commit f0ef89dfbb05292742654135e5ae6e1daa1b5713 Author: root Date: Fri Sep 6 23:53:10 2019 +0800 Init Repo diff --git a/.DS_Store b/.DS_Store new file mode 100755 index 0000000..b677a8e Binary files /dev/null and b/.DS_Store differ diff --git a/._.DS_Store b/._.DS_Store new file mode 100755 index 0000000..9ab07fb Binary files /dev/null and b/._.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..45f54e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +down/ +*.zip +hyhproject/common/conf/database.php diff --git a/.htaccess b/.htaccess new file mode 100755 index 0000000..1f8c5c5 --- /dev/null +++ b/.htaccess @@ -0,0 +1,8 @@ + +Options +FollowSymlinks -Multiviews +RewriteEngine on + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f +RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1] + diff --git a/.user.ini b/.user.ini new file mode 100644 index 0000000..0a4eb8f --- /dev/null +++ b/.user.ini @@ -0,0 +1 @@ +open_basedir=/www/wwwroot/qlg.tsgz.moe/:/tmp/:/proc/ \ No newline at end of file diff --git a/404.html b/404.html new file mode 100755 index 0000000..99ff94f --- /dev/null +++ b/404.html @@ -0,0 +1,26 @@ + + + + + + +404 + + + + +

404,您请求的文件不存在!

+ + diff --git a/addons/.htaccess b/addons/.htaccess new file mode 100755 index 0000000..3e63591 --- /dev/null +++ b/addons/.htaccess @@ -0,0 +1,4 @@ + +order allow,deny +deny from all + \ No newline at end of file diff --git a/addons/cron/Cron.php b/addons/cron/Cron.php new file mode 100755 index 0000000..7bd21c1 --- /dev/null +++ b/addons/cron/Cron.php @@ -0,0 +1,76 @@ + 'Cron', // 插件标识 + 'title' => '计划任务', // 插件名称 + 'description' => '计划任务管理,若用户没有在系统里配置定时任务则建议开启该插件', // 插件简介 + 'status' => 0, // 状态 + 'author' => 'HSF', + 'version' => '1.0.0' + ]; + + + /** + * 插件安装方法 + * @return bool + */ + public function install(){ + $m = new DM(); + $flag = $m->install(); + WSTClearHookCache(); + return $flag; + } + + /** + * 插件卸载方法 + * @return bool + */ + public function uninstall(){ + $m = new DM(); + $flag = $m->uninstall(); + WSTClearHookCache(); + return $flag; + } + + /** + * 插件启用方法 + * @return bool + */ + public function enable(){ + WSTClearHookCache(); + return true; + } + + /** + * 插件禁用方法 + * @return bool + */ + public function disable(){ + WSTClearHookCache(); + return true; + } + + /** + * 插件设置方法 + * @return bool + */ + public function saveConfig(){ + WSTClearHookCache(); + return true; + } + + public function initCronHook($params){ + echo ""; + } +} \ No newline at end of file diff --git a/addons/cron/config.php b/addons/cron/config.php new file mode 100755 index 0000000..062e254 --- /dev/null +++ b/addons/cron/config.php @@ -0,0 +1,5 @@ +fetch("admin/list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + public function toEdit(){ + $m = new M(); + $rs = $m->getById(Input("id/d",0)); + $this->assign("data",$rs); + return $this->fetch("admin/edit"); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 执行计划任务 + */ + public function runCron(){ + $m = new M(); + return $m->runCron(); + } + public function runCrons(){ + $m = new M(); + return $m->runCrons(); + } + + /** + * 停用计划任务 + */ + public function changeEnableStatus(){ + $m = new M(); + return $m->changeEnableStatus(); + } + +} diff --git a/addons/cron/install.sql b/addons/cron/install.sql new file mode 100755 index 0000000..e69de29 diff --git a/addons/cron/model/Crons.php b/addons/cron/model/Crons.php new file mode 100755 index 0000000..683c496 --- /dev/null +++ b/addons/cron/model/Crons.php @@ -0,0 +1,318 @@ +bindHoods("Cron", $hooks); + //管理员后台 + $rs = Db::name('menus')->insert(["parentId"=>2,"menuName"=>"计划任务","menuSort"=>11,"dataFlag"=>1,"isShow"=>1,"menuMark"=>"cron"]); + if($rs!==false){ + $datas = []; + $parentId = Db::name('menus')->getLastInsID(); + $datas[] = ["menuId"=>$parentId,"privilegeCode"=>"CRON_JHRW_00","privilegeName"=>"查看计划任务","isMenuPrivilege"=>1,"privilegeUrl"=>"/addon/cron-cron-index","otherPrivilegeUrl"=>"/addon/cron-cron-pageQuery","dataFlag"=>1,"isEnable"=>1]; + $datas[] = ["menuId"=>$parentId,"privilegeCode"=>"CRON_JHRW_04","privilegeName"=>"操作计划任务","isMenuPrivilege"=>0,"privilegeUrl"=>"/addon/cron-cron-toEdit","otherPrivilegeUrl"=>"/addon/cron-cron-edit,/addon/cron-cron-changeEnableStatus,/addon/cron-cron-runCron","dataFlag"=>1,"isEnable"=>1]; + Db::name('privileges')->insertAll($datas); + } + installSql("cron"); + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + + return false; + } + } + + /** + * 删除菜单 + */ + public function uninstall(){ + Db::startTrans(); + try{ + $hooks = ['initCronHook']; + $this->unbindHoods("Cron", $hooks); + Db::name('menus')->where(["menuMark"=>"cron"])->delete(); + Db::name('privileges')->where(["privilegeCode"=>array("like","CRON_%")])->delete(); + uninstallSql("cron");//传入插件名 + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + return false; + } + } + /** + * 分页 + */ + public function pageQuery(){ + return $this->order('id desc')->paginate(input('limit/d')); + } + /** + * 列表 + */ + public function listQuery(){ + return $this->order('id desc')->select(); + } + public function getById($id){ + $rs = $this->get($id); + if($rs['cronJson']!='')$rs['cronJson'] = unserialize($rs['cronJson']); + return $rs; + } + /** + * 编辑 + */ + public function edit(){ + $data = input('post.'); + $data['cronMinute'] = str_replace(',',',',$data['cronMinute']); + if($data['cronMinute']=='')$data['cronMinute'] = '0'; + Db::startTrans(); + try{ + $corn = $this->get((int)$data['id']); + $corn->cronCycle = (int)$data['cronCycle']; + if(!in_array($corn->cronCycle,[0,1,2]))return WSTReturn('无效的计划时间'); + if($corn->cronCycle==0)$corn->cronDay = $data['cronDay']; + if($corn->cronDay<=0 || $corn->cronDay>=32)return WSTReturn('无效的计划日期'); + if($corn->cronCycle==1)$corn->cronWeek = $data['cronWeek']; + if($corn->cronWeek<0 || $corn->cronWeek>6)return WSTReturn('无效的计划星期'); + $corn->cronHour = $data['cronHour']; + if($corn->cronCycle<0 || $corn->cronCycle>23)return WSTReturn('无效的计划时间'); + $corn->cronMinute = $data['cronMinute']; + $json = unserialize($corn->cronJson); + if(!empty($json)){ + foreach ($json as $key => $v) { + $json[$key]['fieldVal'] = input('post.'.$v['fieldCode']); + } + } + $corn->cronJson = serialize($json); + $corn->isEnable = (int)input('post.isEnable'); + $corn->nextTime = $this->getNextRunTime($corn); + $result = $corn->save(); + if(false !== $result){ + cache('WST_CRONS',null); + Db::commit(); + return WSTReturn("编辑成功", 1); + } + }catch (\Exception $e) { + Db::rollback(); + } + return WSTReturn('编辑失败',-1); + } + /** + * 删除 + */ + public function changeEnableStatus(){ + $id = (int)input('post.id/d'); + $status = ((int)input('post.status/d')==1)?1:0; + Db::startTrans(); + try{ + $result = $this->setField(['isEnable'=>$status,'id'=>$id]); + if(false !== $result){ + cache('WST_CRONS',null); + Db::commit(); + return WSTReturn("操作成功", 1); + } + }catch (\Exception $e) { + Db::rollback(); + } + return WSTReturn('操作失败',-1); + } + + /** + * 执行计划任务 + */ + public function runCron(){ + $id = (int)input('post.id'); + $cron = $this->get($id); + if(!$cron)return WSTReturn('计划任务不存在,跳过此次执行',1); + if($cron->isEnable==0)return WSTReturn('任务执行未开启中,跳过此次执行',1); + if($cron->isRunning==1)return WSTReturn('已有任务执行中,跳过此次执行',1); + $cron->runTime = date('Y-m-d H:i:s'); + $cron->nextTime = $this->getNextRunTime($cron); + Db::startTrans(); + try{ + $cron->isRunning = 1; + $cron->save(); + $domain = request()->root(true); + $domain = $domain."/".$cron->cronUrl; + $data = $this->http($domain); + $data = json_decode($data,true); + $cron->isRunning = 0; + if($data['status']==1){ + $cron->isRunSuccess = 1; + }else{ + $cron->isRunSuccess = 0; + } + $cron->save(); + Db::commit(); + }catch (\Exception $e) { + Db::rollback(); + $cron->isRunning = 0; + $cron->isRunSuccess = 0; + $cron->save(); + return WSTReturn('执行失败'); + } + return WSTReturn('执行成功',1); + } + + public function http($url){ + $ch=curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//设置否输出到页面 + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30 ); //设置连接等待时间 + curl_setopt($ch, CURLOPT_ENCODING, "gzip" ); + $data=curl_exec($ch); + $info = curl_getinfo($ch); + curl_close($ch); + return $data; + } + + /** + * 执行所有定时任务 + */ + public function runCrons(){ + $cons = $this->where('isEnable',1)->select(); + $day = date('d'); + $hour = date('H'); + $minute = date('i'); + $week = date('w'); + foreach($cons as $key =>$cron){ + if($cron->isRunning==1)contnie; + //判断能否执行 + if(strtotime($cron->nextTime)>time())continue; + Db::startTrans(); + try{ + //fopen(time().'_'.rand(0,10000)."_auctionEnd.txt", "w"); + $cron->isRunning = 1; + $cron->runTime = date('Y-m-d H:i:s'); + $cron->nextTime = $this->getNextRunTime($cron); + $cron->save(); + $domain = request()->root(true); + $domain = $domain."/".$cron->cronUrl; + $data = $this->http($domain); + $data = json_decode($data,true); + $cron->isRunning = 0; + if($data['status']==1){ + $cron->isRunSuccess = 1; + }else{ + $cron->isRunSuccess = 0; + } + $cron->save(); + Db::commit(); + }catch (\Exception $e) { + Db::rollback(); + $cron->isRunning = 0; + $cron->isRunSuccess = 0; + $cron->save(); + } + } + echo "done"; + } + + public function getNextRunTime($cron){ + $monthDay = date("t"); + $today = date('j'); + $thisWeek = date('w'); + $thisHour = date('H'); + $thisMinute = date('i'); + $nextDay = date('Y-m-d'); + $nextHour = 0; + $nextMinute = 0; + $isFurther = false;//标记是否要往前进一位 + $tmpMinute = []; + if($cron->cronMinute==-1){ + $nextMinute = date('i',strtotime('+1 Minute')); + if($nextMinute<$thisMinute)$isFurther = true; + $tmpMinute[] = $nextMinute; + }else{ + $tmpMinute = explode(',',$cron->cronMinute); + sort($tmpMinute); + $isFind = false; + foreach($tmpMinute as $key => $v){ + if((int)$v>59)continue; + if($thisMinute<(int)$v){ + $nextMinute = (int)$v; + $isFind = true; + break; + } + } + if(!$isFind){ + $nextMinute = (int)$tmpMinute[0]; + $isFurther = true; + } + } + if($cron->cronHour==-1){ + $nextHour = date("H",time()+($isFurther?3200:0)); + $isFurther = false; + if($nextHour<$thisHour)$isFurther = true; + }else{ + $nextHour = $cron->cronHour; + $isFurther = false; + } + if(time()>strtotime(date('Y-m-d')." ".$nextHour.":".$nextMinute.":00"))$isFurther = true; + if($cron->cronCycle==0){ + if($isFurther){ + $today = date('j',strtotime('+1 day')); + } + if($today<$cron->cronDay){ + $nextDay = date('Y-m-'.$cron->cronDay); + }else{ + $nextDay = date("Y-m",strtotime(" +1 month"))."-".$cron->cronDay; + } + if(date('j',strtotime($nextDay))!=$today){ + if($cron->cronHour==-1){ + $nextHour = 0; + }else{ + $nextHour = $cron->cronHour; + } + if($cron->cronMinute==-1){ + $nextMinute = 0; + }else{ + $nextMinute = (int)$tmpMinute[0]; + } + } + } + if($cron->cronCycle==1){ + if($isFurther){ + $thisWeek = date('w',strtotime('+1 day')); + } + $num = 0; + if($cron->cronWeek>$thisWeek){ + $num = $cron->cronWeek - $thisWeek; + }else{ + $num = $cron->cronWeek - $thisWeek + 7; + } + $nextDay = date("Y-m-d",strtotime("+".$num." day")); + if(date('j',strtotime($nextDay))!=$today){ + if($cron->cronHour==-1){ + $nextHour = 0; + }else{ + $nextHour = $cron->cronHour; + } + if($cron->cronMinute==-1){ + $nextMinute = 0; + }else{ + $nextMinute = (int)$tmpMinute[0]; + } + } + } + if($cron->cronCycle==2){ + if($isFurther){ + $nextDay = date('Y-m-d',strtotime('+1 day')); + }else{ + $nextDay = date('Y-m-d'); + } + } + return date('Y-m-d H:i:s',strtotime($nextDay." ".$nextHour.":".$nextMinute.":00")); + } + +} diff --git a/addons/cron/uninstall.sql b/addons/cron/uninstall.sql new file mode 100755 index 0000000..8a530dd --- /dev/null +++ b/addons/cron/uninstall.sql @@ -0,0 +1 @@ +update hyh_crons set isEnable=0; \ No newline at end of file diff --git a/addons/cron/view/admin/crons.js b/addons/cron/view/admin/crons.js new file mode 100755 index 0000000..f47992e --- /dev/null +++ b/addons/cron/view/admin/crons.js @@ -0,0 +1,113 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'计划任务名称', name:'cronName', width: 80}, + {title:'计划任务描述', name:'cronDesc', width: 150}, + {title:'上次执行时间', name:'runTime', width: 70, renderer: function(val,item,rowIndex){ + return (item['runTime']==0)?'-':item['runTime']; + }}, + {title:'执行状态', name:'isEnable', width: 20, renderer: function(val,item,rowIndex){ + return (item['isRunSuccess']==1)?' 成功':' 失败'; + }}, + {title:'下次执行时间', name:'nextTime', width: 70, renderer: function(val,item,rowIndex){ + return (item['nextTime']==0)?'-':item['nextTime']; + }}, + {title:'作者', name:'auchor', width: 20, renderer: function(val,item,rowIndex){ + return ''+item['author']+''; + }}, + {title:'计划状态', name:'isEnable', width: 20, renderer: function(val,item,rowIndex){ + return (item['isEnable']==1)?' 启用':' 停用'; + }}, + {title:'操作', name:'' ,width:120, align:'center', renderer: function(val,item,rowIndex){ + var h=""; + if(WST.GRANT.CRON_JHRW_04){ + h += "修改 "; + if(item['isEnable']==0){ + h += "启用 "; + }else{ + h += "停用 "; + h += '执行'; + } + + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-115,indexCol: true, cols: cols,method:'POST', + url: WST.AU('cron://cron/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?115:88; + mmg.resize({height:h-diff}) + }}); +} + + +function toEdit(id){ + location.href=WST.AU('cron://cron/toEdit','id='+id); +} +function checkType(v){ + $('.cycle').hide(); + $('.cycle'+v).show(); +} +function run(id){ + var box = WST.confirm({content:'你确定要执行该任务吗?',yes:function(){ + var loading = WST.msg('正在执行计划任务,请稍后...',{icon: 16,time:6000000000}); + $.post(WST.AU('cron://cron/runCron'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) + }}); +} +function edit(id){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.AU('cron://cron/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1},function(){ + location.href=WST.AU('cron://cron/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function changgeEnableStatus(id,type){ + var msg = (type==1)?"您确定要启用该计划任务吗?":"您确定要停用该计划任务吗?" + var box = WST.confirm({content:msg,yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.AU('cron://cron/changeEnableStatus'),{id:id,status:type},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + + + + + \ No newline at end of file diff --git a/addons/cron/view/admin/edit.html b/addons/cron/view/admin/edit.html new file mode 100755 index 0000000..f977151 --- /dev/null +++ b/addons/cron/view/admin/edit.html @@ -0,0 +1,109 @@ +{extend name="../../../hyhproject/admin/view/base" /} +{block name="js"} + +{/block} +{block name="main"} +
+ + + + + + + + + + + + + + {if $data['cronJson']!=''} + {volist name="$data['cronJson']" id='vj'} + + + + + {/volist} + {/if} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
计划任务名称: + {$data['cronName']} +
计划任务描述: + {$data['cronDesc']} +
定时任务网址: + {$data['cronUrl']} +
{$vj['fieldLabel']}: + +
计划时间 + + + +
日期 + +
星期 + +
小时 + +
分钟 + (如多个分钟则以,分隔,-1表示每分钟) +
计划任务状态 + +
+ + +
+
+{/block} + diff --git a/addons/cron/view/admin/list.html b/addons/cron/view/admin/list.html new file mode 100755 index 0000000..3c7a6d0 --- /dev/null +++ b/addons/cron/view/admin/list.html @@ -0,0 +1,23 @@ +{extend name="../../../hyhproject/admin/view/base" /} +{block name="css"} + +{/block} +{block name="js"} + + +{/block} +{block name="main"} +
+
操作说明
+ +
+
+
+
+
+ +{/block} diff --git a/addons/dysms/Dysms.php b/addons/dysms/Dysms.php new file mode 100755 index 0000000..db6d26e --- /dev/null +++ b/addons/dysms/Dysms.php @@ -0,0 +1,177 @@ + 'Dysms', // 插件标识 + + 'title' => '短信接口(阿里云-云通信)', // 插件名称 + + 'description' => '阿里云-云通信短信服务', // 插件简介 + + 'status' => 0, // 状态 + + 'author' => 'HSF', + + 'version' => '1.0.0' + + ]; + + + + + + /** + + * 插件安装方法 + + * @return bool + + */ + + public function install(){ + + $m = new DM(); + + $flag = $m->install(); + + WSTClearHookCache(); + + cache('hooks',null); + + return $flag; + + } + + + + /** + + * 插件卸载方法 + + * @return bool + + */ + + public function uninstall(){ + + $m = new DM(); + + $flag = $m->uninstall(); + + WSTClearHookCache(); + + cache('hooks',null); + + return $flag; + + } + + + + /** + + * 插件启用方法 + + * @return bool + + */ + + public function enable(){ + + WSTClearHookCache(); + + cache('hooks',null); + + return true; + + } + + + + /** + + * 插件禁用方法 + + * @return bool + + */ + + public function disable(){ + + WSTClearHookCache(); + + cache('hooks',null); + + return true; + + } + + + + /** + + * 插件设置方法 + + * @return bool + + */ + + public function saveConfig(){ + + WSTClearHookCache(); + + cache('hooks',null); + + return true; + + } + + + + /** + + * 阿里云-云通信短信服务商 + + * @param string $phoneNumer 手机号码 + + * @param string $content 短信内容 + + */ + + function sendSMS($params){ + + $dm = new DM(); + + $dm->sendSMS($params); + + return true; + + } + + + +} \ No newline at end of file diff --git a/addons/dysms/config.php b/addons/dysms/config.php new file mode 100755 index 0000000..a5f86d2 --- /dev/null +++ b/addons/dysms/config.php @@ -0,0 +1,244 @@ +array( + 'title'=>'【特别提醒】使用之前请先阅读阿里云-云通信短信发送规则', + 'type'=>'hidden', + 'value'=>'' + ), + 'smsKey'=>array( + 'title'=>'Access Key ID【购买短信服务请点击阿里云-云通信短信购买】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'smsPass'=>array( + 'title'=>'Access Key Secret', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'signature'=>array( + 'title'=>'短信签名', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_PUSER_REGISTER_VERFIY'=>array( + 'title'=>'用户通过推荐人注册验证码模板ID【模板参考:您好${name}:您邀约会员注册,邀约码:${code},如非本人或家人邀约,无公害请忽略。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_USER_AUTH_FAMILY_VERFIY'=>array( + 'title'=>'亲人认证验证码模板ID【模板参考:您好,用户${name},申请与您亲人认证,认证码为:${code},请不要把认证码泄露给其他人。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_USER_AUTH_PARTNER_VERFIY'=>array( + 'title'=>'合作人认证验证码模板ID【模板参考:您好,用户${name},申请与您绑定合作人认证,认证码为:${code},请不要把认证码泄露给其他人。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_USER_UPDATE_NOTICE'=>array( + 'title'=>'认证通知模板ID【模板参考:管理员您好:购户${name}申请资格认证,请审核。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_USER_AUTH_NOTICE'=>array( + 'title'=>'实名通知模板ID【您好,您申请实名全亮共会员,验证码${code},如非本人操作,请速与公司联系。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_ADMIN_SHOP_APPLAY_NOTICE'=>array( + 'title'=>'申请商户通知模板ID【管理员您好:购户${name}申请商户请审核。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_ADMIN_GOODS_APPLAY_NOTICE'=>array( + 'title'=>'上传产品通知模板ID【管理员您好:商户${name}上传产品啦,请审核。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_SHOP_ORDER_CONFRIM_NOTICE'=>array( + 'title'=>'成功交易通知模板ID【恭喜您${name}成功交易,请及时处理优惠款,如非本人或家人操作,请速与公司联系。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_DISABLED_USER_REF_NOTICE'=>array( + 'title'=>'禁用推荐人通知模板ID【会员${name}您好:被推荐人${sname}账户已禁用;请您正确引导,该户再次禁用时,您的帐户将被禁用,请速联系。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_ADMIN_SHOP_MONEY_NOTICE'=>array( + 'title'=>'提现通知模板ID【管理员您好:商户${name}申请提现,请处理。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_ADMIN_SET_REPORT_NOTICE'=>array( + 'title'=>'会计操作财务报表通知模板ID【董事长您好:会计${name}需要修改财务报表,日期:${date},${reType}金额:${money}元,核验码${code},请告之。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_FOTGET'=>array( + 'title'=>'忘记密码模板ID【模板参考:您正在重置登录密码,验证码为:${VERFIY_CODE},请及时输入。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + 'PHONE_FOTGET_PAY'=>array( + 'title'=>'忘记操作密码模板ID【模板参考:您正在重置操作密码,验证码为:${VERFIY_CODE},请及时输入。】', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ), + // 'PHONE_PUSER_REGISTER_VERFIY'=>array( + // 'title'=>'模板ID【模板参考:您好:您邀约会员注册,验证码:${code},如非本人或家人邀约,无公害请忽略。】', + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_USER_REGISTER_VERFIY'=>array( + // 'title'=>'用户注册验证码模板ID【模板参考:您的注册验证码为:${VERFIY_CODE},请及时输入。】', + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_BIND'=>array( + // 'title'=>'绑定手机提醒模板ID【模板参考:您的正在操作绑定手机,校验码为:${VERFIY_CODE},请及时输入。】', + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_EDIT'=>array( + // 'title'=>"更改手机提醒模板ID【模板参考:您正在操作修改手机,您的校验码为:${VERFIY_CODE},请及时输入。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_FOTGET'=>array( + // 'title'=>"忘记密码模板ID【模板参考:您正在操作修改手机,您的校验码为:${VERFIY_CODE},请及时输入。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_FOTGET_PAY'=>array( + // 'title'=>"忘记支付密码模板ID【模板参考:您正在重置登录密码,验证码为:${VERFIY_CODE},请及时输入。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_USER_SHOP_OPEN_SUCCESS'=>array( + // 'title'=>"会员开店成功提醒模板ID【模板参考:您申请成为${MALL_NAME}商家的请求已通过。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_SHOP_OPEN_FAIL'=>array( + // 'title'=>"开店失败提醒模板ID【模板参考:您申请成为${MALL_NAME}商家的请求未通过,请登录系统查看详情。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_SHOP_MSG'=>array( + // 'title'=>"商家订单通知模板ID", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'line'=>array( + // 'title'=>' ', + // 'type'=>'hidden', + // 'value'=>'' + // ), + // 'warn_admin'=>array( + // 'title'=>'管理员短信提醒', + // 'type'=>'hidden', + // 'value'=>'' + // ), + // 'PHONE_ADMIN_SUBMIT_ORDER'=>array( + // 'title'=>"管理员-用户下单提醒模板ID【模板参考:有新的订单[${ORDER_NO}],请留意。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_PAY_ORDER'=>array( + // 'title'=>"管理员-支付订单提醒模板ID【模板参考:用户已支付订单[${ORDER_NO}],请留意。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_CANCEL_ORDER'=>array( + // 'title'=>"管理员-取消订单提醒模板ID【模板参考:订单[${ORDER_NO}]已被用户取消。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_REJECT_ORDER'=>array( + // 'title'=>"管理员-拒收订单提醒模板ID【模板参考:订单[${ORDER_NO}]已被用户拒收。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_REFUND_ORDER'=>array( + // 'title'=>"管理员-申请退款提醒模板ID【模板参考:用户申请订单[${ORDER_NO}]退款,请及时处理。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_COMPLAINT_ORDER'=>array( + // 'title'=>"管理员-订单投诉提醒模板ID【模板参考:用户投诉订单[${ORDER_NO}],请及时处理。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ), + // 'PHONE_ADMIN_CASH_DRAWS'=>array( + // 'title'=>"管理员-申请提现提醒模板ID【模板参考:有新的用户申请提现请求,请及时处理。】", + // 'type'=>'text', + // 'value'=>'', + // 'tips'=>'' + // ) + +); diff --git a/addons/dysms/install.sql b/addons/dysms/install.sql new file mode 100755 index 0000000..e69de29 diff --git a/addons/dysms/model/Dysms.php b/addons/dysms/model/Dysms.php new file mode 100755 index 0000000..d215361 --- /dev/null +++ b/addons/dysms/model/Dysms.php @@ -0,0 +1,126 @@ +where('name','Dysms')->field('config')->find(); + $data = json_decode($rs['config'],true); + cache('dysms_sms',$data,31622400); + } + return $data; + } + + public function install(){ + Db::startTrans(); + try{ + $hooks = ['sendSMS']; + $this->bindHoods("Dysms", $hooks); + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + return false; + } + } + public function uninstall(){ + Db::startTrans(); + try{ + $hooks = ['sendSMS']; + $this->unbindHoods("Dysms", $hooks); + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + return false; + } + } + /** + * 发送短信接口 + */ + public function http($params){ + require_once WST_ADDON_PATH.'dysms/sdk/vendor/autoload.php'; + Config::load(); + $smsConf = $this->getConfigs(); + //此处需要替换成自己的AK信息 + $accessKeyId = $smsConf['smsKey'];; + $accessKeySecret = $smsConf['smsPass']; + //短信API产品名(短信产品名固定,无需修改) + $product = "Dysmsapi"; + //短信API产品域名(接口地址固定,无需修改) + $domain = "dysmsapi.aliyuncs.com"; + //暂时不支持多Region(目前仅支持cn-hangzhou请勿修改) + $region = "cn-hangzhou"; + //初始化访问的acsCleint + $profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret); + DefaultProfile::addEndpoint("cn-hangzhou", "cn-hangzhou", $product, $domain); + $acsClient= new DefaultAcsClient($profile); + $request = new SendSmsRequest(); + //必填-短信接收号码。支持以逗号分隔的形式进行批量调用,批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式 + $request->setPhoneNumbers($params['phoneNumber']); + //必填-短信签名 + $request->setSignName($smsConf["signature"]); + //必填-短信模板Code + $request->setTemplateCode($smsConf[$params['params']['tpl']['tplCode']]); + //选填-假如模板中存在变量需要替换则为必填(JSON格式),友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败 + $request->setTemplateParam($params['content']); + //$request->setTemplateParam(json_encode($params['params']['params'])); + // $request->setTemplateParam("{\"orderNo\":\"Tom\", \"orderStatue\":\"123\"}"); + //选填-发送短信流水号 + $request->setOutId($params['timeId']); + //发起访问请求 + //dump($request); + $resp = $acsClient->getAcsResponse($request); + return $resp; + } + + public function sendSMS($params){ + $smsConf = $this->getConfigs(); + $code = []; + $isVerfy = false; + foreach($params['params']['params'] as $key =>$v){ + //$key = str_replace('_','',$key); + if($key=='VERFIY_CODE')$isVerfy = true; + } + foreach($params['params']['params'] as $key =>$v){ + //$key = str_replace('_','',$key); + if($isVerfy && $key=='VERFIY_CODE'){ + $code[] = '"'.$key.'":"'.$v.'"'; + } + } + foreach($params['params']['params'] as $key =>$v){ + //$key = str_replace('_','',$key); + if($isVerfy==false && $key!='VERFIY_CODE'){ + $code[] = '"'.$key.'":"'.$v.'"'; + } + } + $codes = "{".implode(',',$code)."}"; + $params['content'] = $codes; + $timeId = time().rand(100,999); + $params['timeId'] = $timeId; + $code = $this->http($params); + $log = model('common/logSms')->get($params['smsId']); + $log->smsReturnCode = json_encode($code); + $log->smsContent = $codes."||".$params['params']['tpl']['tplCode']."||".$smsConf[$params['params']['tpl']['tplCode']]."||".$timeId; + $log->save(); + try{ + if(strtolower($code->Message)=='ok'){ + $params['status']['msg'] = '短信发送成功!'; + $params['status']['status'] = 1; + } + }catch (\Exception $e) { + $params['status']['msg'] = $code->Message; + $params['status']['status'] = -1; + } + } +} diff --git a/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QueryInterSmsIsoInfoRequest.php b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QueryInterSmsIsoInfoRequest.php new file mode 100755 index 0000000..c9e1bf0 --- /dev/null +++ b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QueryInterSmsIsoInfoRequest.php @@ -0,0 +1,59 @@ +setMethod("POST"); + } + + private $resourceOwnerAccount; + + private $countryName; + + private $resourceOwnerId; + + private $ownerId; + + public function getResourceOwnerAccount() { + return $this->resourceOwnerAccount; + } + + public function setResourceOwnerAccount($resourceOwnerAccount) { + $this->resourceOwnerAccount = $resourceOwnerAccount; + $this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount; + } + + public function getCountryName() { + return $this->countryName; + } + + public function setCountryName($countryName) { + $this->countryName = $countryName; + $this->queryParameters["CountryName"]=$countryName; + } + + public function getResourceOwnerId() { + return $this->resourceOwnerId; + } + + public function setResourceOwnerId($resourceOwnerId) { + $this->resourceOwnerId = $resourceOwnerId; + $this->queryParameters["ResourceOwnerId"]=$resourceOwnerId; + } + + public function getOwnerId() { + return $this->ownerId; + } + + public function setOwnerId($ownerId) { + $this->ownerId = $ownerId; + $this->queryParameters["OwnerId"]=$ownerId; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QuerySendDetailsRequest.php b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QuerySendDetailsRequest.php new file mode 100755 index 0000000..34323fe --- /dev/null +++ b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/QuerySendDetailsRequest.php @@ -0,0 +1,103 @@ +setMethod("POST"); + } + + private $sendDate; + + private $pageSize; + + private $phoneNumber; + + private $resourceOwnerAccount; + + private $currentPage; + + private $bizId; + + private $resourceOwnerId; + + private $ownerId; + + public function getSendDate() { + return $this->sendDate; + } + + public function setSendDate($sendDate) { + $this->sendDate = $sendDate; + $this->queryParameters["SendDate"]=$sendDate; + } + + public function getPageSize() { + return $this->pageSize; + } + + public function setPageSize($pageSize) { + $this->pageSize = $pageSize; + $this->queryParameters["PageSize"]=$pageSize; + } + + public function getPhoneNumber() { + return $this->phoneNumber; + } + + public function setPhoneNumber($phoneNumber) { + $this->phoneNumber = $phoneNumber; + $this->queryParameters["PhoneNumber"]=$phoneNumber; + } + + public function getResourceOwnerAccount() { + return $this->resourceOwnerAccount; + } + + public function setResourceOwnerAccount($resourceOwnerAccount) { + $this->resourceOwnerAccount = $resourceOwnerAccount; + $this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount; + } + + public function getCurrentPage() { + return $this->currentPage; + } + + public function setCurrentPage($currentPage) { + $this->currentPage = $currentPage; + $this->queryParameters["CurrentPage"]=$currentPage; + } + + public function getBizId() { + return $this->bizId; + } + + public function setBizId($bizId) { + $this->bizId = $bizId; + $this->queryParameters["BizId"]=$bizId; + } + + public function getResourceOwnerId() { + return $this->resourceOwnerId; + } + + public function setResourceOwnerId($resourceOwnerId) { + $this->resourceOwnerId = $resourceOwnerId; + $this->queryParameters["ResourceOwnerId"]=$resourceOwnerId; + } + + public function getOwnerId() { + return $this->ownerId; + } + + public function setOwnerId($ownerId) { + $this->ownerId = $ownerId; + $this->queryParameters["OwnerId"]=$ownerId; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendInterSmsRequest.php b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendInterSmsRequest.php new file mode 100755 index 0000000..99b807c --- /dev/null +++ b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendInterSmsRequest.php @@ -0,0 +1,114 @@ +setMethod("POST"); + } + + private $templateCode; + + private $phoneNumbers; + + private $countryCode; + + private $signName; + + private $resourceOwnerAccount; + + private $templateParam; + + private $resourceOwnerId; + + private $ownerId; + + private $outId; + + public function getTemplateCode() { + return $this->templateCode; + } + + public function setTemplateCode($templateCode) { + $this->templateCode = $templateCode; + $this->queryParameters["TemplateCode"]=$templateCode; + } + + public function getPhoneNumbers() { + return $this->phoneNumbers; + } + + public function setPhoneNumbers($phoneNumbers) { + $this->phoneNumbers = $phoneNumbers; + $this->queryParameters["PhoneNumbers"]=$phoneNumbers; + } + + public function getCountryCode() { + return $this->countryCode; + } + + public function setCountryCode($countryCode) { + $this->countryCode = $countryCode; + $this->queryParameters["CountryCode"]=$countryCode; + } + + public function getSignName() { + return $this->signName; + } + + public function setSignName($signName) { + $this->signName = $signName; + $this->queryParameters["SignName"]=$signName; + } + + public function getResourceOwnerAccount() { + return $this->resourceOwnerAccount; + } + + public function setResourceOwnerAccount($resourceOwnerAccount) { + $this->resourceOwnerAccount = $resourceOwnerAccount; + $this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount; + } + + public function getTemplateParam() { + return $this->templateParam; + } + + public function setTemplateParam($templateParam) { + $this->templateParam = $templateParam; + $this->queryParameters["TemplateParam"]=$templateParam; + } + + public function getResourceOwnerId() { + return $this->resourceOwnerId; + } + + public function setResourceOwnerId($resourceOwnerId) { + $this->resourceOwnerId = $resourceOwnerId; + $this->queryParameters["ResourceOwnerId"]=$resourceOwnerId; + } + + public function getOwnerId() { + return $this->ownerId; + } + + public function setOwnerId($ownerId) { + $this->ownerId = $ownerId; + $this->queryParameters["OwnerId"]=$ownerId; + } + + public function getOutId() { + return $this->outId; + } + + public function setOutId($outId) { + $this->outId = $outId; + $this->queryParameters["OutId"]=$outId; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendSmsRequest.php b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendSmsRequest.php new file mode 100755 index 0000000..ceb6401 --- /dev/null +++ b/addons/dysms/sdk/lib/Api/Sms/Request/V20170525/SendSmsRequest.php @@ -0,0 +1,103 @@ +setMethod("POST"); + } + + private $templateCode; + + private $phoneNumbers; + + private $signName; + + private $resourceOwnerAccount; + + private $templateParam; + + private $resourceOwnerId; + + private $ownerId; + + private $outId; + + public function getTemplateCode() { + return $this->templateCode; + } + + public function setTemplateCode($templateCode) { + $this->templateCode = $templateCode; + $this->queryParameters["TemplateCode"]=$templateCode; + } + + public function getPhoneNumbers() { + return $this->phoneNumbers; + } + + public function setPhoneNumbers($phoneNumbers) { + $this->phoneNumbers = $phoneNumbers; + $this->queryParameters["PhoneNumbers"]=$phoneNumbers; + } + + public function getSignName() { + return $this->signName; + } + + public function setSignName($signName) { + $this->signName = $signName; + $this->queryParameters["SignName"]=$signName; + } + + public function getResourceOwnerAccount() { + return $this->resourceOwnerAccount; + } + + public function setResourceOwnerAccount($resourceOwnerAccount) { + $this->resourceOwnerAccount = $resourceOwnerAccount; + $this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount; + } + + public function getTemplateParam() { + return $this->templateParam; + } + + public function setTemplateParam($templateParam) { + $this->templateParam = $templateParam; + $this->queryParameters["TemplateParam"]=$templateParam; + } + + public function getResourceOwnerId() { + return $this->resourceOwnerId; + } + + public function setResourceOwnerId($resourceOwnerId) { + $this->resourceOwnerId = $resourceOwnerId; + $this->queryParameters["ResourceOwnerId"]=$resourceOwnerId; + } + + public function getOwnerId() { + return $this->ownerId; + } + + public function setOwnerId($ownerId) { + $this->ownerId = $ownerId; + $this->queryParameters["OwnerId"]=$ownerId; + } + + public function getOutId() { + return $this->outId; + } + + public function setOutId($outId) { + $this->outId = $outId; + $this->queryParameters["OutId"]=$outId; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/AcsRequest.php b/addons/dysms/sdk/lib/Core/AcsRequest.php new file mode 100755 index 0000000..571f8fd --- /dev/null +++ b/addons/dysms/sdk/lib/Core/AcsRequest.php @@ -0,0 +1,125 @@ +headers["x-sdk-client"] = "php/2.0.0"; + $this->product = $product; + $this->version = $version; + $this->actionName = $actionName; + } + + public abstract function composeUrl($iSigner, $credential, $domain); + + public function getVersion() + { + return $this->version; + } + + public function setVersion($version) + { + $this->version = $version; + } + + public function getProduct() + { + return $this->product; + } + + public function setProduct($product) + { + $this->product = $product; + } + + public function getActionName() + { + return $this->actionName; + } + + public function setActionName($actionName) + { + $this->actionName = $actionName; + } + + public function getAcceptFormat() + { + return $this->acceptFormat; + } + + public function setAcceptFormat($acceptFormat) + { + $this->acceptFormat = $acceptFormat; + } + + public function getQueryParameters() + { + return $this->queryParameters; + } + + public function getHeaders() + { + return $this->headers; + } + + public function getMethod() + { + return $this->method; + } + + public function setMethod($method) + { + $this->method = $method; + } + + public function getProtocol() + { + return $this->protocolType; + } + + public function setProtocol($protocol) + { + $this->protocolType = $protocol; + } + + public function getRegionId() + { + return $this->regionId; + } + public function setRegionId($region) + { + $this->regionId = $region; + } + + public function getContent() + { + return $this->content; + } + + public function setContent($content) + { + $this->content = $content; + } + + + public function addHeader($headerKey, $headerValue) + { + $this->headers[$headerKey] = $headerValue; + } + + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/AcsResponse.php b/addons/dysms/sdk/lib/Core/AcsResponse.php new file mode 100755 index 0000000..57cddf1 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/AcsResponse.php @@ -0,0 +1,29 @@ +code; + } + + public function setCode($code) + { + $this->code = $code; + } + + public function getMessage() + { + return $this->message; + } + + public function setMessage($message) + { + $this->message = $message; + } +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Auth/Credential.php b/addons/dysms/sdk/lib/Core/Auth/Credential.php new file mode 100755 index 0000000..92bf2b2 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Auth/Credential.php @@ -0,0 +1,72 @@ +accessKeyId = $accessKeyId; + $this->accessSecret = $accessSecret; + $this->refreshDate = date($this->dateTimeFormat); + } + + public function isExpired() + { + if($this->expiredDate == null) + { + return false; + } + if(strtotime($this->expiredDate)>date($this->dateTimeFormat)) + { + return false; + } + return true; + } + + public function getRefreshDate() + { + return $this->refreshDate; + } + + public function getExpiredDate() + { + return $this->expiredDate; + } + + public function setExpiredDate($expiredHours) + { + if($expiredHours>0) + { + return $this->expiredDate = date($this->dateTimeFormat, strtotime("+".$expiredHours." hour")); + } + } + + public function getAccessKeyId() + { + return $this->accessKeyId; + } + + public function setAccessKeyId($accessKeyId) + { + $this->accessKeyId = $accessKeyId; + } + + public function getAccessSecret() + { + return $this->accessSecret; + } + + public function setAccessSecret($accessSecret) + { + $this->accessSecret = $accessSecret; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Auth/ISigner.php b/addons/dysms/sdk/lib/Core/Auth/ISigner.php new file mode 100755 index 0000000..c747516 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Auth/ISigner.php @@ -0,0 +1,12 @@ +iClientProfile = $iClientProfile; + $this->__urlTestFlag__ = false; + } + + public function getAcsResponse($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3) + { + $httpResponse = $this->doActionImpl($request, $iSigner, $credential, $autoRetry, $maxRetryNumber); + $respObject = $this->parseAcsResponse($httpResponse->getBody(), $request->getAcceptFormat()); + if(false == $httpResponse->isSuccess()) + { + $this->buildApiException($respObject, $httpResponse->getStatus()); + } + return $respObject; + } + + private function doActionImpl($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3) + { + if(null == $this->iClientProfile && (null == $iSigner || null == $credential + || null == $request->getRegionId() || null == $request->getAcceptFormat())) + { + throw new ClientException("No active profile found.", "SDK.InvalidProfile"); + } + if(null == $iSigner) + { + $iSigner = $this->iClientProfile->getSigner(); + } + if(null == $credential) + { + $credential = $this->iClientProfile->getCredential(); + } + $request = $this->prepareRequest($request); + $domain = EndpointProvider::findProductDomain($request->getRegionId(), $request->getProduct()); + + if(null == $domain) + { + throw new ClientException("Can not find endpoint to access.", "SDK.InvalidRegionId"); + } + $requestUrl = $request->composeUrl($iSigner, $credential, $domain); + + if ($this->__urlTestFlag__) { + throw new ClientException($requestUrl, "URLTestFlagIsSet"); + } + + if(count($request->getDomainParameter())>0){ + $httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getDomainParameter(), $request->getHeaders()); + } else { + $httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(),$request->getContent(), $request->getHeaders()); + } + + $retryTimes = 1; + while (500 <= $httpResponse->getStatus() && $autoRetry && $retryTimes < $maxRetryNumber) { + $requestUrl = $request->composeUrl($iSigner, $credential,$domain); + + if(count($request->getDomainParameter())>0){ + $httpResponse = HttpHelper::curl($requestUrl, $request->getDomainParameter(), $request->getHeaders()); + } else { + $httpResponse = HttpHelper::curl($requestUrl, $request->getMethod(), $request->getContent(), $request->getHeaders()); + } + $retryTimes ++; + } + return $httpResponse; + } + + public function doAction($request, $iSigner = null, $credential = null, $autoRetry = true, $maxRetryNumber = 3) + { + trigger_error("doAction() is deprecated. Please use getAcsResponse() instead.", E_USER_NOTICE); + return $this->doActionImpl($request, $iSigner, $credential, $autoRetry, $maxRetryNumber); + } + + private function prepareRequest($request) + { + if(null == $request->getRegionId()) + { + $request->setRegionId($this->iClientProfile->getRegionId()); + } + if(null == $request->getAcceptFormat()) + { + $request->setAcceptFormat($this->iClientProfile->getFormat()); + } + if(null == $request->getMethod()) + { + $request->setMethod("GET"); + } + return $request; + } + + + private function buildApiException($respObject, $httpStatus) + { + throw new ServerException($respObject->Message, $respObject->Code, $httpStatus, $respObject->RequestId); + } + + private function parseAcsResponse($body, $format) + { + if ("JSON" == $format) + { + $respObject = json_decode($body); + } + else if("XML" == $format) + { + $respObject = @simplexml_load_string($body); + } + else if("RAW" == $format) + { + $respObject = $body; + } + return $respObject; + } +} diff --git a/addons/dysms/sdk/lib/Core/Exception/ClientException.php b/addons/dysms/sdk/lib/Core/Exception/ClientException.php new file mode 100755 index 0000000..537cf30 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Exception/ClientException.php @@ -0,0 +1,50 @@ +errorMessage = $errorMessage; + $this->errorCode = $errorCode; + $this->setErrorType("Client"); + } + + private $errorCode; + private $errorMessage; + private $errorType; + + public function getErrorCode() + { + return $this->errorCode; + } + + public function setErrorCode($errorCode) + { + $this->errorCode = $errorCode; + } + + public function getErrorMessage() + { + return $this->errorMessage; + } + + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; + } + + public function getErrorType() + { + return $this->errorType; + } + + public function setErrorType($errorType) + { + $this->errorType = $errorType; + } + + +} diff --git a/addons/dysms/sdk/lib/Core/Exception/ServerException.php b/addons/dysms/sdk/lib/Core/Exception/ServerException.php new file mode 100755 index 0000000..1fa4d44 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Exception/ServerException.php @@ -0,0 +1,31 @@ +setErrorMessage($errorMessage); + $this->setErrorType("Server"); + $this->httpStatus = $httpStatus; + $this->requestId = $requestId; + } + + public function getHttpStatus() + { + return $this->httpStatus; + } + + public function getRequestId() + { + return $this->requestId; + } + +} diff --git a/addons/dysms/sdk/lib/Core/Http/HttpHelper.php b/addons/dysms/sdk/lib/Core/Http/HttpHelper.php new file mode 100755 index 0000000..adf49dd --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Http/HttpHelper.php @@ -0,0 +1,69 @@ + 5 && strtolower(substr($url,0,5)) == "https" ) { + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + } + if (is_array($headers) && 0 < count($headers)) + { + $httpHeaders =self::getHttpHearders($headers); + curl_setopt($ch,CURLOPT_HTTPHEADER,$httpHeaders); + } + $httpResponse = new HttpResponse(); + $httpResponse->setBody(curl_exec($ch)); + $httpResponse->setStatus(curl_getinfo($ch, CURLINFO_HTTP_CODE)); + if (curl_errno($ch)) + { + throw new ClientException("Server unreachable: Errno: " . curl_errno($ch) . " " . curl_error($ch), "SDK.ServerUnreachable"); + } + curl_close($ch); + return $httpResponse; + } + static function getPostHttpBody($postFildes){ + $content = ""; + foreach ($postFildes as $apiParamKey => $apiParamValue) + { + $content .= "$apiParamKey=" . urlencode($apiParamValue) . "&"; + } + return substr($content, 0, -1); + } + static function getHttpHearders($headers) + { + $httpHeader = array(); + foreach ($headers as $key => $value) + { + array_push($httpHeader, $key.":".$value); + } + return $httpHeader; + } +} diff --git a/addons/dysms/sdk/lib/Core/Http/HttpResponse.php b/addons/dysms/sdk/lib/Core/Http/HttpResponse.php new file mode 100755 index 0000000..df93ec3 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Http/HttpResponse.php @@ -0,0 +1,38 @@ +body; + } + + public function setBody($body) + { + $this->body = $body; + } + + public function getStatus() + { + return $this->status; + } + + public function setStatus($status) + { + $this->status = $status; + } + + public function isSuccess() + { + if(200 <= $this->status && 300 > $this->status) + { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/IAcsClient.php b/addons/dysms/sdk/lib/Core/IAcsClient.php new file mode 100755 index 0000000..b4f548b --- /dev/null +++ b/addons/dysms/sdk/lib/Core/IAcsClient.php @@ -0,0 +1,7 @@ + $endpoint) + { + if($endpoint->getName() == $endpointName) + { + return $endpoint; + } + } + } + + private static function addEndpoint_($endpointName,$regionId, $product, $domain) + { + $regionIds = array($regionId); + $productDomains = array(new ProductDomain($product, $domain)); + $endpoint = new Endpoint($endpointName, $regionIds, $productDomains); + array_push(self::$endpoints, $endpoint); + } + + private static function updateEndpoint($regionId, $product, $domain, $endpoint) + { + $regionIds = $endpoint->getRegionIds(); + if(!in_array($regionId,$regionIds)) + { + array_push($regionIds, $regionId); + $endpoint->setRegionIds($regionIds); + } + + $productDomains = $endpoint->getProductDomains(); + if(null == self::findProductDomain($productDomains, $product, $domain)) + { + array_push($productDomains, new ProductDomain($product, $domain)); + } + $endpoint->setProductDomains($productDomains); + } + + private static function findProductDomain($productDomains, $product, $domain) + { + foreach ($productDomains as $key => $productDomain) + { + if($productDomain->getProductName() == $product && $productDomain->getDomainName() == $domain) + { + return $productDomain; + } + } + return null; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Profile/IClientProfile.php b/addons/dysms/sdk/lib/Core/Profile/IClientProfile.php new file mode 100755 index 0000000..3667018 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Profile/IClientProfile.php @@ -0,0 +1,14 @@ +name = $name; + $this->regionIds = $regionIds; + $this->productDomains = $productDomains; + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getRegionIds() + { + return $this->regionIds; + } + + public function setRegionIds($regionIds) + { + $this->regionIds = $regionIds; + } + + public function getProductDomains() + { + return $this->productDomains; + } + + public function setProductDomains($productDomains) + { + $this->productDomains = $productDomains; + } +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Regions/EndpointConfig.php b/addons/dysms/sdk/lib/Core/Regions/EndpointConfig.php new file mode 100755 index 0000000..55fec72 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Regions/EndpointConfig.php @@ -0,0 +1,63 @@ + $endpoint) + { + if(in_array($regionId, $endpoint->getRegionIds())) + { + return self::findProductDomainByProduct($endpoint->getProductDomains(), $product); + } + } + return null; + } + + private static function findProductDomainByProduct($productDomains, $product) + { + if(null == $productDomains) + { + return null; + } + foreach ($productDomains as $key => $productDomain) + { + if($product == $productDomain->getProductName()) + { + return $productDomain->getDomainName(); + } + } + return null; + } + + + public static function getEndpoints() + { + return self::$endpoints; + } + + public static function setEndpoints($endpoints) + { + self::$endpoints = $endpoints; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Regions/ProductDomain.php b/addons/dysms/sdk/lib/Core/Regions/ProductDomain.php new file mode 100755 index 0000000..b1f94f1 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Regions/ProductDomain.php @@ -0,0 +1,28 @@ +productName = $product; + $this->domainName = $domain; + } + + public function getProductName() { + return $this->productName; + } + public function setProductName($productName) { + $this->productName = $productName; + } + public function getDomainName() { + return $this->domainName; + } + public function setDomainName($domainName) { + $this->domainName = $domainName; + } + +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/Regions/endpoints.xml b/addons/dysms/sdk/lib/Core/Regions/endpoints.xml new file mode 100755 index 0000000..1f0acaa --- /dev/null +++ b/addons/dysms/sdk/lib/Core/Regions/endpoints.xml @@ -0,0 +1,1349 @@ + + + + jp-fudao-1 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + me-east-1 + + Rdsrds.me-east-1.aliyuncs.com + Ecsecs.me-east-1.aliyuncs.com + Vpcvpc.me-east-1.aliyuncs.com + Kmskms.me-east-1.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.me-east-1.aliyuncs.com + + + + us-east-1 + + CScs.aliyuncs.com + Pushcloudpush.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + HPChpc.aliyuncs.com + Locationlocation.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Msgmsg-inner.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Bssbss.aliyuncs.com + Workorderworkorder.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ubsmsubsms.aliyuncs.com + Vpcvpc.aliyuncs.com + Alertalert.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Rdsrds.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + CFcf.aliyuncs.com + Drdsdrds.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Stssts.aliyuncs.com + Dtsdts.aliyuncs.com + Drcdrc.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Alidnsalidns.aliyuncs.com + Onsons.aliyuncs.com + Cdncdn.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + + + + ap-northeast-1 + + Rdsrds.ap-northeast-1.aliyuncs.com + Kmskms.ap-northeast-1.aliyuncs.com + Vpcvpc.ap-northeast-1.aliyuncs.com + Ecsecs.ap-northeast-1.aliyuncs.com + Cmsmetrics.ap-northeast-1.aliyuncs.com + Kvstorer-kvstore.ap-northeast-1.aliyuncs.com + Slbslb.ap-northeast-1.aliyuncs.com + + + + cn-hangzhou-bj-b01 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-hongkong + + Pushcloudpush.aliyuncs.com + COScos.aliyuncs.com + Onsons.aliyuncs.com + Essess.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + CScs.aliyuncs.com + Kmskms.cn-hongkong.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Drcdrc.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Dmdm.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + HPChpc.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Vpcvpc.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Bssbss.aliyuncs.com + Ubsmsubsms.aliyuncs.com + CloudAPIapigateway.cn-hongkong.aliyuncs.com + Stssts.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-hongkong.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Greengreen.aliyuncs.com + Aasaas.aliyuncs.com + Alidnsalidns.aliyuncs.com + Dtsdts.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Rdsrds.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + Ossoss-cn-hongkong.aliyuncs.com + + + + cn-beijing-nu16-b01 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-beijing-am13-c01 + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + in-west-antgroup-1 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-guizhou-gov + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + in-west-antgroup-2 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-qingdao-cm9 + + CScs.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Drdsdrds.aliyuncs.com + HPChpc.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Alertalert.aliyuncs.com + Mscmsc-inner.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ubsmsubsms.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + AMSams.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Bssbss.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-qingdao.aliyuncs.com + CFcf.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Stssts.aliyuncs.com + Dtsdts.aliyuncs.com + Emremr.aliyuncs.com + Drcdrc.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + ROSros.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Rdsrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Cdncdn.aliyuncs.com + + + + tw-snowcloud-kaohsiung + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-shanghai-finance-1 + + Kmskms.cn-shanghai-finance-1.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + Rdsrds.aliyuncs.com + + + + cn-guizhou + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + cn-qingdao-finance + + Ossoss-cn-qdjbp-a.aliyuncs.com + + + + cn-beijing-gov-1 + + Ossoss-cn-haidian-a.aliyuncs.com + Rdsrds.aliyuncs.com + + + + cn-shanghai + + ARMSarms.cn-shanghai.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + HPChpc.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Drcdrc.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Drdsdrds.aliyuncs.com + CScs.aliyuncs.com + Kmskms.cn-shanghai.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Alertalert.aliyuncs.com + Mscmsc-inner.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.cn-shanghai.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + Bssbss.aliyuncs.com + Omsoms.aliyuncs.com + Ubsmsubsms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Apigatewayapigateway.cn-shanghai.aliyuncs.com + CloudAPIapigateway.cn-shanghai.aliyuncs.com + Stssts.aliyuncs.com + Vpcvpc.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-shanghai.aliyuncs.com + Ddsmongodb.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Pushcloudpush.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + Dtsdts.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Jaqjaq.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + jaqjaq.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Rdsrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Essess.aliyuncs.com + Ossoss-cn-shanghai.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + vodvod.cn-shanghai.aliyuncs.com + + + + cn-shenzhen-inner + + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + Onsons.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + HPChpc.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + jaqjaq.aliyuncs.com + Mscmsc-inner.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Bssbss.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + Alertalert.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ubsmsubsms.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + AMSams.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Stssts.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-shenzhen.aliyuncs.com + CFcf.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Greengreen.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + CScs.aliyuncs.com + Drcdrc.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + Dtsdts.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + ROSros.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Rdsrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + + + + cn-fujian + + Ecsecs-cn-hangzhou.aliyuncs.com + Rdsrds.aliyuncs.com + + + + in-mumbai-alipay + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + us-west-1 + + CScs.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Stssts.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + Pushcloudpush.aliyuncs.com + Alidnsalidns.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Bssbss.aliyuncs.com + Mscmsc-inner.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + Alertalert.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Vpcvpc.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Ubsmsubsms.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.us-west-1.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + HPChpc.aliyuncs.com + Drcdrc.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Dtsdts.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + jaqjaq.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Onsons.aliyuncs.com + Ossoss-us-west-1.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + + + + cn-shanghai-inner + + CScs.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.aliyuncs.com + Smssms.aliyuncs.com + Drdsdrds.aliyuncs.com + HPChpc.aliyuncs.com + Locationlocation.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Msgmsg-inner.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + jaqjaq.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + Bssbss.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Alertalert.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Ubsmsubsms.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-shanghai.aliyuncs.com + CFcf.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Stssts.aliyuncs.com + Dtsdts.aliyuncs.com + Drcdrc.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Alidnsalidns.aliyuncs.com + Onsons.aliyuncs.com + Cdncdn.aliyuncs.com + + + + cn-anhui-gov-1 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-hangzhou-finance + + Ossoss-cn-hzjbp-b-console.aliyuncs.com + + + + cn-hangzhou + + ARMSarms.cn-hangzhou.aliyuncs.com + CScs.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Stssts.aliyuncs.com + Smssms.aliyuncs.com + Msgmsg-inner.aliyuncs.com + Jaqjaq.aliyuncs.com + Pushcloudpush.aliyuncs.com + Livelive.aliyuncs.com + Kmskms.cn-hangzhou.aliyuncs.com + Locationlocation.aliyuncs.com + Hpchpc.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Drcdrc.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.cn-hangzhou.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Vpcvpc.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + Domaindomain.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Ubsmsubsms.aliyuncs.com + Apigatewayapigateway.cn-hangzhou.aliyuncs.com + CloudAPIapigateway.cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-hangzhou.aliyuncs.com + Oascn-hangzhou.oas.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Alidnsalidns.aliyuncs.com + HPChpc.aliyuncs.com + Emremr.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + Dtsdts.aliyuncs.com + Bssbss.aliyuncs.com + Otsots-pop.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Rdsrds.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Onsons.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + + + + cn-beijing-inner + + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + HPChpc.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.aliyuncs.com + Smssms.aliyuncs.com + Drdsdrds.aliyuncs.com + CScs.aliyuncs.com + Locationlocation.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Msgmsg-inner.aliyuncs.com + Essess.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Bssbss.aliyuncs.com + Workorderworkorder.aliyuncs.com + Drcdrc.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Dmdm.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + Otsots-pop.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Ubsmsubsms.aliyuncs.com + Stssts.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-beijing.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + CFcf.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Greengreen.aliyuncs.com + Aasaas.aliyuncs.com + Alidnsalidns.aliyuncs.com + Pushcloudpush.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + Dtsdts.aliyuncs.com + Domaindomain.aliyuncs.com + ROSros.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Cdncdn.aliyuncs.com + + + + cn-haidian-cm12-c01 + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + Rdsrds.aliyuncs.com + + + + cn-anhui-gov + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + cn-shenzhen + + ARMSarms.cn-shenzhen.aliyuncs.com + CScs.aliyuncs.com + COScos.aliyuncs.com + Onsons.aliyuncs.com + Essess.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + Pushcloudpush.aliyuncs.com + Kmskms.cn-shenzhen.aliyuncs.com + Locationlocation.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Alertalert.aliyuncs.com + Drcdrc.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Iotiot.aliyuncs.com + HPChpc.aliyuncs.com + Bssbss.aliyuncs.com + Omsoms.aliyuncs.com + Ubsmsubsms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + BatchComputebatchcompute.cn-shenzhen.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Apigatewayapigateway.cn-shenzhen.aliyuncs.com + CloudAPIapigateway.cn-shenzhen.aliyuncs.com + Stssts.aliyuncs.com + Vpcvpc.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-shenzhen.aliyuncs.com + Oascn-shenzhen.oas.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Crmcrm-cn-hangzhou.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + Dtsdts.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + jaqjaq.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Greengreen.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Ossoss-cn-shenzhen.aliyuncs.com + + + + ap-southeast-2 + + Rdsrds.ap-southeast-2.aliyuncs.com + Kmskms.ap-southeast-2.aliyuncs.com + Vpcvpc.ap-southeast-2.aliyuncs.com + Ecsecs.ap-southeast-2.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.ap-southeast-2.aliyuncs.com + + + + cn-qingdao + + CScs.aliyuncs.com + COScos.aliyuncs.com + HPChpc.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.cn-qingdao.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + Dtsdts.aliyuncs.com + Locationlocation.aliyuncs.com + Essess.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + Drcdrc.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.cn-qingdao.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Dmdm.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Iotiot.aliyuncs.com + Bssbss.aliyuncs.com + Omsoms.aliyuncs.com + Ubsmsubsms.cn-qingdao.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + BatchComputebatchcompute.cn-qingdao.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Otsots-pop.aliyuncs.com + PTSpts.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Apigatewayapigateway.cn-qingdao.aliyuncs.com + CloudAPIapigateway.cn-qingdao.aliyuncs.com + Stssts.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-qingdao.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Greengreen.aliyuncs.com + Aasaas.aliyuncs.com + Alidnsalidns.aliyuncs.com + Pushcloudpush.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + Domaindomain.aliyuncs.com + ROSros.aliyuncs.com + jaqjaq.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Ossoss-cn-qingdao.aliyuncs.com + + + + cn-shenzhen-su18-b02 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-shenzhen-su18-b03 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + cn-shenzhen-su18-b01 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + ap-southeast-antgroup-1 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + oss-cn-bjzwy + + Ossoss-cn-bjzwy.aliyuncs.com + + + + cn-henan-am12001 + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + cn-beijing + + ARMSarms.cn-beijing.aliyuncs.com + CScs.aliyuncs.com + COScos.aliyuncs.com + Jaqjaq.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Stssts.aliyuncs.com + Smssms.aliyuncs.com + Msgmsg-inner.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + HPChpc.aliyuncs.com + Oascn-beijing.oas.aliyuncs.com + Locationlocation.aliyuncs.com + Onsons.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Hpchpc.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + jaqjaq.aliyuncs.com + Workorderworkorder.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Bssbss.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + Alertalert.aliyuncs.com + Omsoms.aliyuncs.com + Ubsmsubsms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Apigatewayapigateway.cn-beijing.aliyuncs.com + CloudAPIapigateway.cn-beijing.aliyuncs.com + Kmskms.cn-beijing.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.cn-beijing.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + Dtsdts.aliyuncs.com + Drcdrc.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Ossoss-cn-beijing.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + Rdsrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Alidnsalidns.aliyuncs.com + Greengreen.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Cdncdn.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + vodvod.cn-beijing.aliyuncs.com + + + + cn-hangzhou-d + + CScs.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Emremr.aliyuncs.com + Smssms.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Dtsdts.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Bssbss.aliyuncs.com + Mscmsc-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Alidnsalidns.aliyuncs.com + Iotiot.aliyuncs.com + HPChpc.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Alertalert.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + Otsots-pop.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Ubsmsubsms.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-hangzhou.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + CFcf.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Greengreen.aliyuncs.com + Aasaas.aliyuncs.com + Stssts.aliyuncs.com + Pushcloudpush.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + ROSros.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Drcdrc.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + + + + cn-gansu-am6 + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + Rdsrds.aliyuncs.com + + + + cn-ningxiazhongwei + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + cn-shanghai-et2-b01 + + CScs.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + Onsons.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Jaqjaq.aliyuncs.com + Dtsdts.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Bssbss.aliyuncs.com + Mscmsc-inner.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Dmdm.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + Ubsmsubsms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Ace-opsace-ops.cn-hangzhou.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + AMSams.aliyuncs.com + Otsots-pop.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Rdsrds.aliyuncs.com + Mtsmts.cn-hangzhou.aliyuncs.com + CFcf.aliyuncs.com + Acsacs.aliyun-inc.com + Httpdnshttpdns-api.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Stssts.aliyuncs.com + HPChpc.aliyuncs.com + Emremr.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.aliyuncs.com + Slbslb.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + Domaindomain.aliyuncs.com + ROSros.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Drdsdrds.aliyuncs.com + Vpc-innervpc-inner.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Greengreen.aliyuncs.com + Drcdrc.aliyuncs.com + Ossoss-cn-hangzhou.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + + + + cn-ningxia-am7-c01 + + Ecsecs-cn-hangzhou.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + cn-shenzhen-finance-1 + + Kmskms.cn-shenzhen-finance-1.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + Rdsrds.aliyuncs.com + Vpcvpc.aliyuncs.com + + + + ap-southeast-1 + + CScs.aliyuncs.com + Riskrisk-cn-hangzhou.aliyuncs.com + COScos.aliyuncs.com + Essess.aliyuncs.com + Billingbilling.aliyuncs.com + Dqsdqs.aliyuncs.com + Ddsmongodb.aliyuncs.com + Alidnsalidns.aliyuncs.com + Smssms.aliyuncs.com + Drdsdrds.aliyuncs.com + Dtsdts.aliyuncs.com + Kmskms.ap-southeast-1.aliyuncs.com + Locationlocation.aliyuncs.com + Msgmsg-inner.aliyuncs.com + ChargingServicechargingservice.aliyuncs.com + R-kvstorer-kvstore-cn-hangzhou.aliyuncs.com + Alertalert.aliyuncs.com + Mscmsc-inner.aliyuncs.com + HighDDosyd-highddos-cn-hangzhou.aliyuncs.com + Yundunyundun-cn-hangzhou.aliyuncs.com + Ubsms-innerubsms-inner.aliyuncs.com + Ocsm-kvstore.aliyuncs.com + Dmdm.aliyuncs.com + Greengreen.aliyuncs.com + Commondrivercommon.driver.aliyuncs.com + oceanbaseoceanbase.aliyuncs.com + Workorderworkorder.aliyuncs.com + Yundunhsmyundunhsm.aliyuncs.com + Iotiot.aliyuncs.com + HPChpc.aliyuncs.com + jaqjaq.aliyuncs.com + Omsoms.aliyuncs.com + livelive.aliyuncs.com + Ecsecs-cn-hangzhou.aliyuncs.com + M-kvstorem-kvstore.aliyuncs.com + Vpcvpc.aliyuncs.com + BatchComputebatchCompute.aliyuncs.com + AMSams.aliyuncs.com + ROSros.aliyuncs.com + PTSpts.aliyuncs.com + Qualitycheckqualitycheck.aliyuncs.com + Bssbss.aliyuncs.com + Ubsmsubsms.aliyuncs.com + Apigatewayapigateway.ap-southeast-1.aliyuncs.com + CloudAPIapigateway.ap-southeast-1.aliyuncs.com + Stssts.aliyuncs.com + CmsSiteMonitorsitemonitor.aliyuncs.com + Aceace.cn-hangzhou.aliyuncs.com + Mtsmts.ap-southeast-1.aliyuncs.com + CFcf.aliyuncs.com + Crmcrm-cn-hangzhou.aliyuncs.com + Location-innerlocation-inner.aliyuncs.com + Aasaas.aliyuncs.com + Emremr.aliyuncs.com + Httpdnshttpdns-api.aliyuncs.com + Drcdrc.aliyuncs.com + Pushcloudpush.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.aliyuncs.com + YundunDdosinner-yundun-ddos.cn-hangzhou.aliyuncs.com + Domaindomain.aliyuncs.com + Otsots-pop.aliyuncs.com + Cdncdn.aliyuncs.com + Ramram.aliyuncs.com + Salessales.cn-hangzhou.aliyuncs.com + Rdsrds.aliyuncs.com + OssAdminoss-admin.aliyuncs.com + Onsons.aliyuncs.com + Ossoss-ap-southeast-1.aliyuncs.com + + + + cn-shenzhen-st4-d01 + + Ecsecs-cn-hangzhou.aliyuncs.com + + + + eu-central-1 + + Rdsrds.eu-central-1.aliyuncs.com + Ecsecs.eu-central-1.aliyuncs.com + Vpcvpc.eu-central-1.aliyuncs.com + Kmskms.eu-central-1.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.eu-central-1.aliyuncs.com + + + + cn-zhangjiakou + + Rdsrds.cn-zhangjiakou.aliyuncs.com + Ecsecs.cn-zhangjiakou.aliyuncs.com + Vpcvpc.cn-zhangjiakou.aliyuncs.com + Cmsmetrics.cn-hangzhou.aliyuncs.com + Slbslb.cn-zhangjiakou.aliyuncs.com + + + diff --git a/addons/dysms/sdk/lib/Core/RoaAcsRequest.php b/addons/dysms/sdk/lib/Core/RoaAcsRequest.php new file mode 100755 index 0000000..f0b0337 --- /dev/null +++ b/addons/dysms/sdk/lib/Core/RoaAcsRequest.php @@ -0,0 +1,208 @@ +setVersion($version); + $this->initialize(); + } + + private function initialize() + { + $this->setMethod("RAW"); + } + + public function composeUrl($iSigner, $credential, $domain) + { + $this->prepareHeader($iSigner); + + $signString = $this->getMethod().self::$headerSeparator; + if(isset($this->headers["Accept"])) + { + $signString = $signString.$this->headers["Accept"]; + } + $signString = $signString.self::$headerSeparator; + + if(isset($this->headers["Content-MD5"])) + { + $signString = $signString.$this->headers["Content-MD5"]; + } + $signString = $signString.self::$headerSeparator; + + if(isset($this->headers["Content-Type"])) + { + $signString = $signString.$this->headers["Content-Type"]; + } + $signString = $signString.self::$headerSeparator; + + if(isset($this->headers["Date"])) + { + $signString = $signString.$this->headers["Date"]; + } + $signString = $signString.self::$headerSeparator; + + $uri = $this->replaceOccupiedParameters(); + $signString = $signString.$this->buildCanonicalHeaders(); + $queryString = $this->buildQueryString($uri); + $signString .= $queryString; + $this->headers["Authorization"] = "acs ".$credential->getAccessKeyId().":" + .$iSigner->signString($signString, $credential->getAccessSecret()); + $requestUrl = $this->getProtocol()."://".$domain.$queryString; + return $requestUrl; + } + + private function prepareHeader($iSigner) + { + date_default_timezone_set("GMT"); + $this->headers["Date"] = date($this->dateTimeFormat); + if(null == $this->acceptFormat) + { + $this->acceptFormat = "RAW"; + } + $this->headers["Accept"] = $this->formatToAccept($this->getAcceptFormat()); + $this->headers["x-acs-signature-method"] = $iSigner->getSignatureMethod(); + $this->headers["x-acs-signature-version"] = $iSigner->getSignatureVersion(); + $this->headers["x-acs-region-id"] = $this->regionId; + $content = $this->getDomainParameter(); + if ($content != null) { + $this->headers["Content-MD5"] = base64_encode(md5(json_encode($content),true)); + } + $this->headers["Content-Type"] = "application/octet-stream;charset=utf-8"; + } + + private function replaceOccupiedParameters() + { + $result = $this->uriPattern; + foreach ($this->pathParameters as $pathParameterKey => $apiParameterValue) + { + $target = "[".$pathParameterKey."]"; + $result = str_replace($target,$apiParameterValue,$result); + } + return $result; + } + + private function buildCanonicalHeaders() + { + $sortMap = array(); + foreach ($this->headers as $headerKey => $headerValue) + { + $key = strtolower($headerKey); + if(strpos($key, "x-acs-") === 0) + { + $sortMap[$key] = $headerValue; + } + } + ksort($sortMap); + $headerString = ""; + foreach ($sortMap as $sortMapKey => $sortMapValue) + { + $headerString = $headerString.$sortMapKey.":".$sortMapValue.self::$headerSeparator; + } + return $headerString; + } + + private function splitSubResource($uri) + { + $queIndex = strpos($uri, "?"); + $uriParts = array(); + if(null != $queIndex) + { + array_push($uriParts, substr($uri,0,$queIndex)); + array_push($uriParts, substr($uri,$queIndex+1)); + } + else + { + array_push($uriParts,$uri); + } + return $uriParts; + } + + private function buildQueryString($uri) + { + $uriParts = $this->splitSubResource($uri); + $sortMap = $this->queryParameters; + if(isset($uriParts[1])) + { + $sortMap[$uriParts[1]] = null; + } + $queryString = $uriParts[0]; + if(count($uriParts)) + { + $queryString = $queryString."?"; + } + ksort($sortMap); + foreach ($sortMap as $sortMapKey => $sortMapValue) + { + $queryString = $queryString.$sortMapKey; + if(isset($sortMapValue)) + { + $queryString = $queryString."=".$sortMapValue; + } + $queryString = $queryString.$querySeprator; + } + if(null==count($sortMap)) + { + $queryString = substr($queryString, 0, strlen($queryString)-1); + } + return $queryString; + } + + private function formatToAccept($acceptFormat) + { + if($acceptFormat == "JSON") + { + return "application/json"; + } + elseif ($acceptFormat == "XML") { + return "application/xml"; + } + return "application/octet-stream"; + } + + public function getPathParameters() + { + return $this->pathParameters; + } + + public function putPathParameter($name, $value) + { + $this->pathParameters[$name] = $value; + } + + public function getDomainParameter() + { + return $this->domainParameters; + } + + public function putDomainParameters($name, $value) + { + $this->domainParameters[$name] = $value; + } + + public function getUriPattern() + { + return $this->uriPattern; + } + + public function setUriPattern($uriPattern) + { + return $this->uriPattern = $uriPattern; + } + + public function setVersion($version) + { + $this->version = $version; + $this->headers["x-acs-version"] = $version; + } +} \ No newline at end of file diff --git a/addons/dysms/sdk/lib/Core/RpcAcsRequest.php b/addons/dysms/sdk/lib/Core/RpcAcsRequest.php new file mode 100755 index 0000000..c3315df --- /dev/null +++ b/addons/dysms/sdk/lib/Core/RpcAcsRequest.php @@ -0,0 +1,106 @@ +initialize(); + } + + private function initialize() + { + $this->setMethod("GET"); + $this->setAcceptFormat("JSON"); + } + + + private function prepareValue($value) + { + if (is_bool($value)) { + if ($value) { + return "true"; + } else { + return "false"; + } + } else { + return $value; + } + } + + public function composeUrl($iSigner, $credential, $domain) + { + $apiParams = parent::getQueryParameters(); + foreach ($apiParams as $key => $value) { + $apiParams[$key] = $this->prepareValue($value); + } + $apiParams["RegionId"] = $this->getRegionId(); + $apiParams["AccessKeyId"] = $credential->getAccessKeyId(); + $apiParams["Format"] = $this->getAcceptFormat(); + $apiParams["SignatureMethod"] = $iSigner->getSignatureMethod(); + $apiParams["SignatureVersion"] = $iSigner->getSignatureVersion(); + $apiParams["SignatureNonce"] = uniqid(); + date_default_timezone_set("GMT"); + $apiParams["Timestamp"] = date($this->dateTimeFormat); + $apiParams["Action"] = $this->getActionName(); + $apiParams["Version"] = $this->getVersion(); + $apiParams["Signature"] = $this->computeSignature($apiParams, $credential->getAccessSecret(), $iSigner); + if(parent::getMethod() == "POST") { + + $requestUrl = $this->getProtocol()."://". $domain . "/"; + foreach ($apiParams as $apiParamKey => $apiParamValue) + { + $this->putDomainParameters($apiParamKey,$apiParamValue); + } + return $requestUrl; + } + else { + $requestUrl = $this->getProtocol()."://". $domain . "/?"; + + foreach ($apiParams as $apiParamKey => $apiParamValue) + { + $requestUrl .= "$apiParamKey=" . urlencode($apiParamValue) . "&"; + } + return substr($requestUrl, 0, -1); + } + } + + private function computeSignature($parameters, $accessKeySecret, $iSigner) + { + ksort($parameters); + $canonicalizedQueryString = ''; + foreach($parameters as $key => $value) + { + $canonicalizedQueryString .= '&' . $this->percentEncode($key). '=' . $this->percentEncode($value); + } + $stringToSign = parent::getMethod().'&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1)); + $signature = $iSigner->signString($stringToSign, $accessKeySecret."&"); + + return $signature; + } + + protected function percentEncode($str) + { + $res = urlencode($str); + $res = preg_replace('/\+/', '%20', $res); + $res = preg_replace('/\*/', '%2A', $res); + $res = preg_replace('/%7E/', '~', $res); + return $res; + } + + public function getDomainParameter() + { + return $this->domainParameters; + } + + public function putDomainParameters($name, $value) + { + $this->domainParameters[$name] = $value; + } + +} diff --git a/addons/dysms/sdk/vendor/autoload.php b/addons/dysms/sdk/vendor/autoload.php new file mode 100755 index 0000000..911f28b --- /dev/null +++ b/addons/dysms/sdk/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + foreach ($this->prefixDirsPsr4[$search] as $dir) { + $length = $this->prefixLengthsPsr4[$first][$search]; + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/addons/dysms/sdk/vendor/composer/LICENSE b/addons/dysms/sdk/vendor/composer/LICENSE new file mode 100755 index 0000000..f27399a --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/addons/dysms/sdk/vendor/composer/autoload_classmap.php b/addons/dysms/sdk/vendor/composer/autoload_classmap.php new file mode 100755 index 0000000..bc5155a --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/autoload_classmap.php @@ -0,0 +1,454 @@ + $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', + 'PHPUnit_Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit_Extensions_GroupTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', + 'PHPUnit_Extensions_PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', + 'PHPUnit_Extensions_PhptTestSuite' => $vendorDir . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => $vendorDir . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => $vendorDir . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => $vendorDir . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetError' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => $vendorDir . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Runner_BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => $vendorDir . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_PHP' => $vendorDir . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => $vendorDir . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => $vendorDir . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => $vendorDir . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'PHP_CodeCoverage_Driver' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver.php', + 'PHP_CodeCoverage_Driver_HHVM' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php', + 'PHP_CodeCoverage_Driver_PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php', + 'PHP_CodeCoverage_Driver_Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php', + 'PHP_CodeCoverage_Exception' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception.php', + 'PHP_CodeCoverage_Exception_UnintentionallyCoveredCode' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php', + 'PHP_CodeCoverage_Filter' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Filter.php', + 'PHP_CodeCoverage_Report_Clover' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php', + 'PHP_CodeCoverage_Report_Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php', + 'PHP_CodeCoverage_Report_Factory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php', + 'PHP_CodeCoverage_Report_HTML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php', + 'PHP_CodeCoverage_Report_HTML_Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php', + 'PHP_CodeCoverage_Report_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php', + 'PHP_CodeCoverage_Report_Node_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php', + 'PHP_CodeCoverage_Report_Node_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php', + 'PHP_CodeCoverage_Report_Node_Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php', + 'PHP_CodeCoverage_Report_PHP' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php', + 'PHP_CodeCoverage_Report_Text' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php', + 'PHP_CodeCoverage_Report_XML' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php', + 'PHP_CodeCoverage_Report_XML_Directory' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php', + 'PHP_CodeCoverage_Report_XML_File' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php', + 'PHP_CodeCoverage_Report_XML_File_Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php', + 'PHP_CodeCoverage_Report_XML_File_Method' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php', + 'PHP_CodeCoverage_Report_XML_File_Report' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php', + 'PHP_CodeCoverage_Report_XML_File_Unit' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php', + 'PHP_CodeCoverage_Report_XML_Node' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php', + 'PHP_CodeCoverage_Report_XML_Project' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php', + 'PHP_CodeCoverage_Report_XML_Tests' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php', + 'PHP_CodeCoverage_Report_XML_Totals' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php', + 'PHP_CodeCoverage_Util' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util.php', + 'PHP_CodeCoverage_Util_InvalidArgumentHelper' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage/Util/InvalidArgumentHelper.php', + 'PHP_Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => $vendorDir . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => $vendorDir . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', +); diff --git a/addons/dysms/sdk/vendor/composer/autoload_namespaces.php b/addons/dysms/sdk/vendor/composer/autoload_namespaces.php new file mode 100755 index 0000000..b24b217 --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/autoload_namespaces.php @@ -0,0 +1,10 @@ + array($vendorDir . '/phpspec/prophecy/src'), +); diff --git a/addons/dysms/sdk/vendor/composer/autoload_psr4.php b/addons/dysms/sdk/vendor/composer/autoload_psr4.php new file mode 100755 index 0000000..e2b528c --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/autoload_psr4.php @@ -0,0 +1,15 @@ + array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/type-resolver/src', $vendorDir . '/phpdocumentor/reflection-docblock/src'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'Aliyun\\Test\\' => array($baseDir . '/tests'), + 'Aliyun\\' => array($baseDir . '/lib'), +); diff --git a/addons/dysms/sdk/vendor/composer/autoload_real.php b/addons/dysms/sdk/vendor/composer/autoload_real.php new file mode 100755 index 0000000..c6fc3ca --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/autoload_real.php @@ -0,0 +1,52 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/addons/dysms/sdk/vendor/composer/autoload_static.php b/addons/dysms/sdk/vendor/composer/autoload_static.php new file mode 100755 index 0000000..4f788ca --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/autoload_static.php @@ -0,0 +1,530 @@ + + array ( + 'phpDocumentor\\Reflection\\' => 25, + ), + 'W' => + array ( + 'Webmozart\\Assert\\' => 17, + ), + 'S' => + array ( + 'Symfony\\Component\\Yaml\\' => 23, + ), + 'D' => + array ( + 'Doctrine\\Instantiator\\' => 22, + ), + 'A' => + array ( + 'Aliyun\\Test\\' => 12, + 'Aliyun\\' => 7, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'phpDocumentor\\Reflection\\' => + array ( + 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + 2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', + ), + 'Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'Symfony\\Component\\Yaml\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/yaml', + ), + 'Doctrine\\Instantiator\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', + ), + 'Aliyun\\Test\\' => + array ( + 0 => __DIR__ . '/../..' . '/tests', + ), + 'Aliyun\\' => + array ( + 0 => __DIR__ . '/../..' . '/lib', + ), + ); + + public static $prefixesPsr0 = array ( + 'P' => + array ( + 'Prophecy\\' => + array ( + 0 => __DIR__ . '/..' . '/phpspec/prophecy/src', + ), + ), + ); + + public static $classMap = array ( + 'File_Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', + 'File_Iterator_Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', + 'File_Iterator_Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', + 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/AssertionFailedError.php', + 'PHPUnit\\Framework\\BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/BaseTestListener.php', + 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/Test.php', + 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestCase.php', + 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestListener.php', + 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/ForwardCompatibility/TestSuite.php', + 'PHPUnit_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit_Extensions_GroupTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/GroupTestSuite.php', + 'PHPUnit_Extensions_PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestCase.php', + 'PHPUnit_Extensions_PhptTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/PhptTestSuite.php', + 'PHPUnit_Extensions_RepeatedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/RepeatedTest.php', + 'PHPUnit_Extensions_TestDecorator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TestDecorator.php', + 'PHPUnit_Extensions_TicketListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Extensions/TicketListener.php', + 'PHPUnit_Framework_Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit_Framework_AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/AssertionFailedError.php', + 'PHPUnit_Framework_BaseTestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/BaseTestListener.php', + 'PHPUnit_Framework_CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/CodeCoverageException.php', + 'PHPUnit_Framework_Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint.php', + 'PHPUnit_Framework_Constraint_And' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/And.php', + 'PHPUnit_Framework_Constraint_ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit_Framework_Constraint_ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit_Framework_Constraint_Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit_Framework_Constraint_Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit_Framework_Constraint_ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit_Framework_Constraint_ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit_Framework_Constraint_Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit_Framework_Constraint_Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit_Framework_Constraint_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit_Framework_Constraint_ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit_Framework_Constraint_ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit_Framework_Constraint_ExceptionMessageRegExp' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegExp.php', + 'PHPUnit_Framework_Constraint_FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit_Framework_Constraint_GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit_Framework_Constraint_IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit_Framework_Constraint_IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit_Framework_Constraint_IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit_Framework_Constraint_IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit_Framework_Constraint_IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit_Framework_Constraint_IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit_Framework_Constraint_IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit_Framework_Constraint_IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit_Framework_Constraint_IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit_Framework_Constraint_IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit_Framework_Constraint_JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'PHPUnit_Framework_Constraint_LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit_Framework_Constraint_Not' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Not.php', + 'PHPUnit_Framework_Constraint_ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit_Framework_Constraint_Or' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Or.php', + 'PHPUnit_Framework_Constraint_PCREMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/PCREMatch.php', + 'PHPUnit_Framework_Constraint_SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit_Framework_Constraint_StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit_Framework_Constraint_StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit_Framework_Constraint_StringMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatches.php', + 'PHPUnit_Framework_Constraint_StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit_Framework_Constraint_TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit_Framework_Constraint_TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit_Framework_Constraint_Xor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Xor.php', + 'PHPUnit_Framework_Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error.php', + 'PHPUnit_Framework_Error_Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit_Framework_Error_Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit_Framework_Error_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit_Framework_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception.php', + 'PHPUnit_Framework_ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit_Framework_ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExpectationFailedException.php', + 'PHPUnit_Framework_IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit_Framework_IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit_Framework_IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestError.php', + 'PHPUnit_Framework_InvalidCoversTargetError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetError.php', + 'PHPUnit_Framework_InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidCoversTargetException.php', + 'PHPUnit_Framework_MockObject_BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit_Framework_MockObject_Builder_Identity' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit_Framework_MockObject_Builder_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Builder_Match' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit_Framework_MockObject_Builder_MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Namespace' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Namespace.php', + 'PHPUnit_Framework_MockObject_Builder_ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit_Framework_MockObject_Builder_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit_Framework_MockObject_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit_Framework_MockObject_Generator' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Generator.php', + 'PHPUnit_Framework_MockObject_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation.php', + 'PHPUnit_Framework_MockObject_InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/InvocationMocker.php', + 'PHPUnit_Framework_MockObject_Invocation_Object' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Object.php', + 'PHPUnit_Framework_MockObject_Invocation_Static' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invocation/Static.php', + 'PHPUnit_Framework_MockObject_Invokable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Invokable.php', + 'PHPUnit_Framework_MockObject_Matcher' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/AnyParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'PHPUnit_Framework_MockObject_Matcher_Invocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Invocation.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedCount.php', + 'PHPUnit_Framework_MockObject_Matcher_InvokedRecorder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/InvokedRecorder.php', + 'PHPUnit_Framework_MockObject_Matcher_MethodName' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/MethodName.php', + 'PHPUnit_Framework_MockObject_Matcher_Parameters' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/Parameters.php', + 'PHPUnit_Framework_MockObject_Matcher_StatelessInvocation' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Matcher/StatelessInvocation.php', + 'PHPUnit_Framework_MockObject_MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit_Framework_MockObject_MockObject' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/MockObject.php', + 'PHPUnit_Framework_MockObject_RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit_Framework_MockObject_Stub' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub.php', + 'PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit_Framework_MockObject_Stub_Exception' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit_Framework_MockObject_Stub_MatcherCollection' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/MatcherCollection.php', + 'PHPUnit_Framework_MockObject_Stub_Return' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/Return.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit_Framework_MockObject_Stub_ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit_Framework_MockObject_Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit-mock-objects/src/Framework/MockObject/Verifiable.php', + 'PHPUnit_Framework_OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/OutputError.php', + 'PHPUnit_Framework_RiskyTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTest.php', + 'PHPUnit_Framework_RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/RiskyTestError.php', + 'PHPUnit_Framework_SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit_Framework_SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit_Framework_SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit_Framework_SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestError.php', + 'PHPUnit_Framework_SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestSuiteError.php', + 'PHPUnit_Framework_SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SyntheticError.php', + 'PHPUnit_Framework_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit_Framework_TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit_Framework_TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit_Framework_TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit_Framework_TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit_Framework_TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit_Framework_TestSuite_DataProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite/DataProvider.php', + 'PHPUnit_Framework_UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/UnintentionallyCoveredCodeError.php', + 'PHPUnit_Framework_Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Warning.php', + 'PHPUnit_Runner_BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit_Runner_Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit_Runner_Filter_Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit_Runner_Filter_GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group.php', + 'PHPUnit_Runner_Filter_Group_Exclude' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Exclude.php', + 'PHPUnit_Runner_Filter_Group_Include' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Group/Include.php', + 'PHPUnit_Runner_Filter_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Test.php', + 'PHPUnit_Runner_StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit_Runner_TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit_Runner_Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit_TextUI_Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit_TextUI_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit_TextUI_TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit_Util_Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit_Util_Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit_Util_ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit_Util_Fileloader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Fileloader.php', + 'PHPUnit_Util_Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit_Util_Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit_Util_Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit_Util_GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit_Util_InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidArgumentHelper.php', + 'PHPUnit_Util_Log_JSON' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JSON.php', + 'PHPUnit_Util_Log_JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit_Util_Log_TAP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TAP.php', + 'PHPUnit_Util_PHP' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP.php', + 'PHPUnit_Util_PHP_Default' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Default.php', + 'PHPUnit_Util_PHP_Windows' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/Windows.php', + 'PHPUnit_Util_Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit_Util_Regex' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Regex.php', + 'PHPUnit_Util_String' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/String.php', + 'PHPUnit_Util_Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit_Util_TestDox_NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit_Util_TestDox_ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit_Util_TestDox_ResultPrinter_HTML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/HTML.php', + 'PHPUnit_Util_TestDox_ResultPrinter_Text' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter/Text.php', + 'PHPUnit_Util_TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestSuiteIterator.php', + 'PHPUnit_Util_Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit_Util_XML' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XML.php', + 'PHP_CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'PHP_CodeCoverage_Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Driver.php', + 'PHP_CodeCoverage_Driver_HHVM' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/HHVM.php', + 'PHP_CodeCoverage_Driver_PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/PHPDBG.php', + 'PHP_CodeCoverage_Driver_Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Driver/Xdebug.php', + 'PHP_CodeCoverage_Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Exception.php', + 'PHP_CodeCoverage_Exception_UnintentionallyCoveredCode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Exception/UnintentionallyCoveredCode.php', + 'PHP_CodeCoverage_Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Filter.php', + 'PHP_CodeCoverage_Report_Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Clover.php', + 'PHP_CodeCoverage_Report_Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Crap4j.php', + 'PHP_CodeCoverage_Report_Factory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Factory.php', + 'PHP_CodeCoverage_Report_HTML' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML.php', + 'PHP_CodeCoverage_Report_HTML_Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Dashboard.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/Directory.php', + 'PHP_CodeCoverage_Report_HTML_Renderer_File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/HTML/Renderer/File.php', + 'PHP_CodeCoverage_Report_Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node.php', + 'PHP_CodeCoverage_Report_Node_Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Directory.php', + 'PHP_CodeCoverage_Report_Node_File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/File.php', + 'PHP_CodeCoverage_Report_Node_Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Node/Iterator.php', + 'PHP_CodeCoverage_Report_PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/PHP.php', + 'PHP_CodeCoverage_Report_Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/Text.php', + 'PHP_CodeCoverage_Report_XML' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML.php', + 'PHP_CodeCoverage_Report_XML_Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Directory.php', + 'PHP_CodeCoverage_Report_XML_File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File.php', + 'PHP_CodeCoverage_Report_XML_File_Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Coverage.php', + 'PHP_CodeCoverage_Report_XML_File_Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Method.php', + 'PHP_CodeCoverage_Report_XML_File_Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Report.php', + 'PHP_CodeCoverage_Report_XML_File_Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/File/Unit.php', + 'PHP_CodeCoverage_Report_XML_Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Node.php', + 'PHP_CodeCoverage_Report_XML_Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Project.php', + 'PHP_CodeCoverage_Report_XML_Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Tests.php', + 'PHP_CodeCoverage_Report_XML_Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Report/XML/Totals.php', + 'PHP_CodeCoverage_Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Util.php', + 'PHP_CodeCoverage_Util_InvalidArgumentHelper' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage/Util/InvalidArgumentHelper.php', + 'PHP_Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', + 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ASYNC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AWAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMPILER_HALT_OFFSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENUM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUALS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_JOIN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_CP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LAMBDA_OP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NULLSAFE_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ONUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SHAPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SUPER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TYPELIST_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHERE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_ATTRIBUTE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CATEGORY_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_CHILDREN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_LABEL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_REQUIRED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TAG_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XHP_TEXT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\LCS\\LongestCommonSubsequence' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/LongestCommonSubsequence.php', + 'SebastianBergmann\\Diff\\LCS\\MemoryEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\LCS\\TimeEfficientImplementation' => __DIR__ . '/..' . '/sebastian/diff/src/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$prefixesPsr0; + $loader->classMap = ComposerStaticInitee70723fd3132b6d05f0ff016c58b71b::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/addons/dysms/sdk/vendor/composer/installed.json b/addons/dysms/sdk/vendor/composer/installed.json new file mode 100755 index 0000000..ec0a18c --- /dev/null +++ b/addons/dysms/sdk/vendor/composer/installed.json @@ -0,0 +1,1160 @@ +[ + { + "name": "symfony/yaml", + "version": "v3.3.5", + "version_normalized": "3.3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "1f93a8d19b8241617f5074a123e282575b821df8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/1f93a8d19b8241617f5074a123e282575b821df8", + "reference": "1f93a8d19b8241617f5074a123e282575b821df8", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "require-dev": { + "symfony/console": "~2.8|~3.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "time": "2017-06-15T12:58:50+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com" + }, + { + "name": "sebastian/version", + "version": "1.0.6", + "version_normalized": "1.0.6.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "shasum": "" + }, + "time": "2015-06-21T13:59:46+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2015-10-12T03:26:01+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.5", + "version_normalized": "1.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2016-10-03T07:41:43+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/exporter", + "version": "1.2.2", + "version_normalized": "1.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "time": "2016-06-17T09:04:28+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/environment", + "version": "1.3.8", + "version_normalized": "1.3.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0" + }, + "time": "2016-08-18T05:49:44+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "version_normalized": "1.4.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "time": "2017-05-22T07:24:03+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ] + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "version_normalized": "1.2.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "time": "2017-01-29T09:50:25+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "version_normalized": "1.0.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "time": "2015-06-14T21:17:01+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ] + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21T13:50:34+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.8", + "version_normalized": "2.3.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "suggest": { + "ext-soap": "*" + }, + "time": "2015-10-02T06:51:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ] + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "version_normalized": "1.0.9.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "time": "2017-02-26T11:10:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.2", + "version_normalized": "1.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2016-10-03T07:40:28+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.11", + "version_normalized": "1.4.11.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "time": "2017-02-27T10:12:30+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.2.4", + "version_normalized": "2.2.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "^1.3.2", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "time": "2015-10-06T15:47:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ] + }, + { + "name": "webmozart/assert", + "version": "1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", + "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "time": "2016-11-23T20:04:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "time": "2015-12-27T11:43:31+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ] + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "version_normalized": "0.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "time": "2017-07-14T14:27:02+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.2.0", + "version_normalized": "3.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/46f7e8bb075036c92695b15a1ddb6971c751e585", + "reference": "46f7e8bb075036c92695b15a1ddb6971c751e585", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "phpdocumentor/reflection-common": "^1.0@dev", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "time": "2017-07-15T11:38:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." + }, + { + "name": "phpspec/prophecy", + "version": "v1.7.0", + "version_normalized": "1.7.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" + }, + "time": "2017-03-02T20:05:34+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "phpunit/phpunit", + "version": "4.8.36", + "version_normalized": "4.8.36.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.1|~3.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "time": "2017-06-21T08:07:12+00:00", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ] + } +] diff --git a/addons/dysms/uninstall.sql b/addons/dysms/uninstall.sql new file mode 100755 index 0000000..e69de29 diff --git a/addons/kuaidi/Kuaidi.php b/addons/kuaidi/Kuaidi.php new file mode 100755 index 0000000..9959aee --- /dev/null +++ b/addons/kuaidi/Kuaidi.php @@ -0,0 +1,142 @@ + 'Kuaidi', // 插件标识 + 'title' => '快递100', // 插件名称 + 'description' => '为您更好的跟踪您的订单动态', // 插件简介 + 'status' => 0, // 状态 + 'author' => 'HSF', + 'version' => '1.0.1' + ]; + + + /** + * 插件安装方法 + * @return bool + */ + public function install(){ + $m = new DM(); + $flag = $m->install(); + WSTClearHookCache(); + cache('hooks',null); + return $flag; + } + + /** + * 插件卸载方法 + * @return bool + */ + public function uninstall(){ + $m = new DM(); + $flag = $m->uninstall(); + WSTClearHookCache(); + cache('hooks',null); + return $flag; + } + + /** + * 插件启用方法 + * @return bool + */ + public function enable(){ + WSTClearHookCache(); + cache('hooks',null); + return true; + } + + /** + * 插件禁用方法 + * @return bool + */ + public function disable(){ + WSTClearHookCache(); + cache('hooks',null); + return true; + } + + /** + * 插件设置方法 + * @return bool + */ + public function saveConfig(){ + $m = new DM(); + WSTClearHookCache(); + cache('hooks',null); + return true; + } + /** + * 跳转订单详情【admin】 + */ + public function adminDocumentOrderView($params){ + $m = new DM(); + $rs = $m->getOrderDeliver($params['orderId']); + if($rs["deliverType"]==0 && $rs["orderStatus"]>0){ + $express = $m->getExpress($params['orderId']); + if($express["expressNo"]!=""){ + $rs = $m->getOrderExpress($params['orderId']); + + $expressLogs = json_decode($rs, true); + $this->assign('expressLogs', $expressLogs); + return $this->fetch('view/admin/view'); + } + } + } + + /** + * 跳转订单详情【home】 + */ + public function homeDocumentOrderView($params){ + $m = new DM(); + $rs = $m->getOrderDeliver($params['orderId']); + if($rs["deliverType"]==0 && $rs["orderStatus"]>0){//货到付款的并且是未付款以上状态 + $express = $m->getExpress($params['orderId']);//获取订单号及物流信息 + if($express["expressNo"]!=""){ + $rs = $m->getOrderExpress($params['orderId']);//返回订单信息 + $expressLogs = json_decode($rs, true);//将json转换为数组 + $this->assign('expressLogs', $expressLogs); + return $this->fetch('view/home/view'); + } + + } + } + + public function afterQueryUserOrders($params){ + $m = new DM(); + foreach ($params["page"]["Rows"] as $key => $v){ + $rs = $m->getOrderDeliver($v['orderId']); + if($rs["deliverType"]==0 && $rs["orderStatus"]>0 && $rs["expressNo"]!=""){ + $bnt = ''; + $params["page"]["Rows"][$key]['hook'] = ($v['orderStatus']==1 || $v['orderStatus']==2)?$bnt:""; + }else{ + $params["page"]["Rows"][$key]['hook'] = ""; + } + + } + } + + /** + * 订单列表【mobile】 + */ + public function mobileDocumentOrderList(){ + return $this->fetch('view/mobile/view'); + } + + /** + * 订单列表【wechat】 + */ + public function wechatDocumentOrderList(){ + return $this->fetch('view/wechat/view'); + } + +} \ No newline at end of file diff --git a/addons/kuaidi/config.php b/addons/kuaidi/config.php new file mode 100755 index 0000000..4545008 --- /dev/null +++ b/addons/kuaidi/config.php @@ -0,0 +1,15 @@ +array( + 'title'=>'快递代码是用于物流查询,可点击这里查看,到“首页->基础设置->快递管理”中进行设置', + 'type'=>'hidden', + 'value'=>'' + ), + 'kuaidiKey'=>array( + 'title'=>'快递100授权密匙(Key)    在线申请密匙(Key)', + 'type'=>'text', + 'value'=>'', + 'tips'=>'' + ) +); diff --git a/addons/kuaidi/controller/Kuaidi.php b/addons/kuaidi/controller/Kuaidi.php new file mode 100755 index 0000000..af3e363 --- /dev/null +++ b/addons/kuaidi/controller/Kuaidi.php @@ -0,0 +1,60 @@ +assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wsthomeStyleId')); + } + + /** + * 跳转订单详情【mobile】 + */ + public function checkMobileExpress(){ + $m = new M(); + $rs = $m->getOrderExpress(input("orderId")); + $express = json_decode($rs, true); + $state = isset($express["state"])?$express["state"]:'-1'; + $data = $m->getOrderInfo(); + $data["express"]["stateTxt"] = $this->getExpressState($state); + $express["express"] = $data["express"]; + $express["goodlist"] = $data["goodlist"]; + return $express; + } + + /** + * 跳转订单详情【wechat】 + */ + public function checkWechatExpress(){ + $m = new M(); + $rs = $m->getOrderExpress(input("orderId")); + $express = json_decode($rs, true); + $state = isset($express["state"])?$express["state"]:'-1'; + $data = $m->getOrderInfo(); + $data["express"]["stateTxt"] = $this->getExpressState($state); + $express["express"] = $data["express"]; + $express["goodlist"] = $data["goodlist"]; + return $express; + } + + public function getExpressState($state){ + $stateTxt = ""; + switch ($state) { + case '0':$stateTxt="运输中";break; + case '1':$stateTxt="揽件";break; + case '2':$stateTxt="疑难";break; + case '3':$stateTxt="收件人已签收";break; + case '4':$stateTxt="已退签";break; + case '5':$stateTxt="派件中";break; + case '6':$stateTxt="退回";break; + default:$stateTxt="暂未获取到状态";break; + } + return $stateTxt; + } +} \ No newline at end of file diff --git a/addons/kuaidi/install.sql b/addons/kuaidi/install.sql new file mode 100755 index 0000000..e69de29 diff --git a/addons/kuaidi/model/Kuaidi.php b/addons/kuaidi/model/Kuaidi.php new file mode 100755 index 0000000..a756ef1 --- /dev/null +++ b/addons/kuaidi/model/Kuaidi.php @@ -0,0 +1,148 @@ +bindHoods("Kuaidi", $hooks); + + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + return false; + } + } + + /** + * 解绑勾子 + */ + public function uninstall(){ + Db::startTrans(); + try{ + $hooks = array("adminDocumentOrderView","homeDocumentOrderView","afterQueryUserOrders","mobileDocumentOrderList","wechatDocumentOrderList"); + $this->unbindHoods("Kuaidi", $hooks); + + Db::commit(); + return true; + }catch (\Exception $e) { + Db::rollback(); + return false; + } + } + + public function getExpress($orderId){ + $conf = $this->getConf("Kuaidi"); + $express = Db::name('orders')->where(["orderId"=>$orderId])->field(['expressId','expressNo'])->find(); + return $express; + } + + public function getOrderExpress($orderId){ + $conf = $this->getConf("Kuaidi"); + $express = Db::name('orders')->where(["orderId"=>$orderId])->field(['expressId','expressNo'])->find(); + + if($express["expressId"]>0){ + $expressId = $express["expressId"]; + $row = Db::name('express')->where(["expressId"=>$expressId])->find(); + $typeCom = strtolower($row["expressCode"]); //快递公司 + $typeNu = $express["expressNo"]; //快递单号 + + $appKey= $conf["kuaidiKey"]; + + $expressLogs = null; + $post_data['param'] = json_encode(['com'=>$typeCom,'num'=>$typeNu]); + $key ='jMIRnHZa5264'; + $post_data['customer'] ='466DC9B2C8C2CA140FFB2E6FAFE705DF'; + $post_data['sign']= strtoupper(md5($post_data['param'].$key.$post_data['customer'])); + + + $expressLogs = $this->curl_request('http://poll.kuaidi100.com/poll/query.do',$post_data); + + //$url ='http://api.kuaidi100.com/api?id='.$appKey.'&com='.$typeCom.'&nu='.$typeNu.'&show=0&muti=1&order=asc'; + //$companys = array('ems','shentong','yuantong','shunfeng','yunda','tiantian','zhongtong','zengyisudi'); + // if(in_array($typeCom,$companys)){ + // $url = 'http://www.kuaidi100.com/query?type=' . $typeCom . '&postid=' . $typeNu; + // }else{ + // $url ='http://api.kuaidi100.com/api?id='.$appKey.'&com='.$typeCom.'&nu='.$typeNu.'&show=0&muti=1&order=asc'; + // } + //$expressLogs = $this -> curl($url); + return $expressLogs; + } + + } + //参数1:访问的URL,参数2:post数据(不填则为GET),参数3:提交的$cookies,参数4:是否返回$cookies + function curl_request($url,$post='',$cookie='', $returnCookie=0){ + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($curl, CURLOPT_AUTOREFERER, 1); + curl_setopt($curl, CURLOPT_REFERER, "http://XXX"); + if($post) { + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post)); + } + if($cookie) { + curl_setopt($curl, CURLOPT_COOKIE, $cookie); + } + curl_setopt($curl, CURLOPT_HEADER, $returnCookie); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + $data = curl_exec($curl); + if (curl_errno($curl)) { + return curl_error($curl); + } + curl_close($curl); + if($returnCookie){ + list($header, $body) = explode("\r\n\r\n", $data, 2); + preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches); + $info['cookie'] = substr($matches[1][0], 1); + $info['content'] = $body; + return $info; + }else{ + return $data; + } + } + public function getOrderInfo($orderId = 0){//添加可传订单号方法 mark hsf 20171130 + $data = array(); + if(!$orderId){ + $orderId = input("orderId"); + } + $data["express"] = Db::name('orders o')->join('__EXPRESS__ e', 'o.expressId=e.expressId')->where(["orderId"=>$orderId])->field(['e.expressId','e.expressImg','o.expressNo','e.expressName'])->find(); + $data["express"]['expressImg'] = WSTImg($data["express"]['expressImg'],3); + $data["goodsImg"] = Db::name('orders o')->join('__ORDER_GOODS__ og','o.orderId=og.orderId')->where(["o.orderId"=>$orderId])->value('og.goodsImg');//这个只返回一个数据 + return $data; + } + + public function curl($url) { + $curl = curl_init(); + curl_setopt ($curl, CURLOPT_URL, $url); + curl_setopt ($curl, CURLOPT_HEADER,0); + curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt ($curl, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT']); + curl_setopt ($curl, CURLOPT_TIMEOUT,5); + $content = curl_exec($curl); + curl_close ($curl); + return $content; + } + + + public function getOrderDeliver($orderId){ + $rs = Db::name('orders o')->where(["orderId"=>$orderId])->field("deliverType,orderStatus,expressNo")->find(); + return $rs; + } + + + +} diff --git a/addons/kuaidi/uninstall.sql b/addons/kuaidi/uninstall.sql new file mode 100755 index 0000000..e69de29 diff --git a/addons/kuaidi/view/admin/express.css b/addons/kuaidi/view/admin/express.css new file mode 100755 index 0000000..2bc1081 --- /dev/null +++ b/addons/kuaidi/view/admin/express.css @@ -0,0 +1,2 @@ +#wst-express td,#wst-express th{text-align: left;} +#wst-express .title{font-weight: bold;} \ No newline at end of file diff --git a/addons/kuaidi/view/admin/view.html b/addons/kuaidi/view/admin/view.html new file mode 100755 index 0000000..1767039 --- /dev/null +++ b/addons/kuaidi/view/admin/view.html @@ -0,0 +1,27 @@ + +
+
物流信息
+ + + + + + + {volist name="expressLogs['data']" id="vo"} + + + + + {/volist} + {empty name="$expressLogs['data']"} + + + + {/empty} + + + + + +
时间地点和跟踪进度
{$vo['time']} {:WSTgetWeek($vo['time'])}{$vo['context']}
物流单暂无结果!
物流单暂无结果!
+
\ No newline at end of file diff --git a/addons/kuaidi/view/home/express.css b/addons/kuaidi/view/home/express.css new file mode 100755 index 0000000..2bc1081 --- /dev/null +++ b/addons/kuaidi/view/home/express.css @@ -0,0 +1,2 @@ +#wst-express td,#wst-express th{text-align: left;} +#wst-express .title{font-weight: bold;} \ No newline at end of file diff --git a/addons/kuaidi/view/home/view.html b/addons/kuaidi/view/home/view.html new file mode 100755 index 0000000..423d706 --- /dev/null +++ b/addons/kuaidi/view/home/view.html @@ -0,0 +1,27 @@ + +
+
物流信息
+ + + + + + + {volist name="expressLogs['data']" id="vo"} + + + + + {/volist} + {empty name="$expressLogs['data']"} + + + + {/empty} + + + + + +
时间地点和跟踪进度
{$vo['time']} {:WSTgetWeek($vo['time'])}{$vo['context']}
物流单暂无结果!
物流单暂无结果!
+
\ No newline at end of file diff --git a/addons/kuaidi/view/mobile/express.css b/addons/kuaidi/view/mobile/express.css new file mode 100755 index 0000000..2def527 --- /dev/null +++ b/addons/kuaidi/view/mobile/express.css @@ -0,0 +1,265 @@ + +html * { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.cd-container { + width: 90%; + max-width: 1170px; + margin: 0 auto; +} +.cd-container::after { + content: ''; + display: table; + clear: both; +} + +#cd-timeline { + position: relative; + margin-top: 2em; + margin-bottom: 2em; +} +#cd-timeline::before { + content: ''; + position: absolute; + top: 0; + left: 18px; + height: 100%; + width: 4px; + background: #d7e4ed; +} +@media only screen and (min-width: 1170px) { + #cd-timeline { + margin-top: 3em; + margin-bottom: 3em; + } + #cd-timeline::before { + left: 50%; + margin-left: -2px; + } +} + +.cd-timeline-block { + position: relative; + margin: 1em 0; +} +.cd-timeline-block:after { + content: ""; + display: table; + clear: both; +} +.cd-timeline-block:first-child { + margin-top: 0; +} +.cd-timeline-block:last-child { + margin-bottom: 0; +} +@media only screen and (min-width: 1170px) { + .cd-timeline-block { + margin: 4em 0; + } + .cd-timeline-block:first-child { + margin-top: 0; + } + .cd-timeline-block:last-child { + margin-bottom: 0; + } +} + +.cd-timeline-img { + position: absolute; + top: 2px; + left: 10px; + width: 20px; + height: 20px; + border-radius: 50%; + box-shadow: 0 0 0 4px white, inset 0 2px 0 rgba(0, 0, 0, 0.08), 0 3px 0 4px rgba(0, 0, 0, 0.05); +} +.cd-timeline-img img { + display: block; + width: 24px; + height: 24px; + position: relative; + left: 50%; + top: 50%; + margin-left: -12px; + margin-top: -12px; +} +.curr-picture { + color: #75ce66; + position: absolute; + left: -2px; + top: -2px; +} +.cd-timeline-img.cd-movie { + background: #c03b44; +} +.cd-timeline-img.cd-location { + background: #f0ca45; +} +@media only screen and (min-width: 1170px) { + .cd-timeline-img { + width: 60px; + height: 60px; + left: 50%; + margin-left: -30px; + -webkit-transform: translateZ(0); + -webkit-backface-visibility: hidden; + } + .cssanimations .cd-timeline-img.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-img.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-1 0.6s; + -moz-animation: cd-bounce-1 0.6s; + animation: cd-bounce-1 0.6s; + } +} + +.cd-timeline-content { + position: relative; + margin-left: 50px; + background: white; + border-radius: 0.25em; + padding: 1em; + box-shadow: 0 2px 0 #e0e4e3; +} +.cd-timeline-content:after { + content: ""; + display: table; + clear: both; +} +.cd-timeline-content h2 { + color: #303e49; +} + +.cd-timeline-content .cd-read-more, .cd-timeline-content .cd-date { + display: inline-block; +} +.cd-timeline-content .cd-read-more { + float: right; + padding: .8em 1em; + background: #acb7c0; + color: white; + border-radius: 0.25em; +} +.no-touch .cd-timeline-content .cd-read-more:hover { + background-color: #bac4cb; +} +a.cd-read-more:hover{text-decoration:none; background-color: #424242; } +.cd-timeline-content .cd-date { + float: left; + padding: .8em 0; + opacity: .7; +} +.cd-timeline-content::before { + content: ''; + position: absolute; + top: 16px; + right: 100%; + height: 0; + width: 0; + border: 7px solid transparent; + border-right: 7px solid white; +} +@media only screen and (min-width: 768px) { + .cd-timeline-content h2 { + font-size: 20px; + font-size: 1.25rem; + } + .cd-timeline-content .cd-read-more, .cd-timeline-content .cd-date { + font-size: 14px; + font-size: 0.875rem; + } +} +@media only screen and (min-width: 1170px) { + .cd-timeline-content { + margin-left: 0; + padding: 1.6em; + width: 45%; + } + .cd-timeline-content::before { + top: 24px; + left: 100%; + border-color: transparent; + border-left-color: white; + } + .cd-timeline-content .cd-read-more { + float: left; + } + .cd-timeline-content .cd-date { + position: absolute; + width: 100%; + left: 122%; + top: 6px; + font-size: 16px; + font-size: 1rem; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content::before { + top: 24px; + left: auto; + right: 100%; + border-color: transparent; + border-right-color: white; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date { + left: auto; + right: 122%; + text-align: right; + } + .cssanimations .cd-timeline-content.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-content.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-2 0.6s; + -moz-animation: cd-bounce-2 0.6s; + animation: cd-bounce-2 0.6s; + } +} + +@media only screen and (min-width: 1170px) { + .cssanimations .cd-timeline-block:nth-child(even) .cd-timeline-content.bounce-in { + -webkit-animation: cd-bounce-2-inverse 0.6s; + -moz-animation: cd-bounce-2-inverse 0.6s; + animation: cd-bounce-2-inverse 0.6s; + } +} +.o-Img { + max-width: 60px; + max-height: 60px; + width: 60px; + height: 60px; + margin-top: 5px; + padding-top: 0; +} +.wst-fr-box { + position: fixed; + z-index: 9999; + right: -999px; + bottom: 0px; + width: 100%; + min-height: 40%; + background: #f2f2f2; + font-size: 0.14rem; +} +.d-goodsitme { + background: #fff; + border-bottom: none; + margin-bottom: 5px; + font-size: 0.14rem; +} \ No newline at end of file diff --git a/addons/kuaidi/view/mobile/view.html b/addons/kuaidi/view/mobile/view.html new file mode 100755 index 0000000..ed12d2a --- /dev/null +++ b/addons/kuaidi/view/mobile/view.html @@ -0,0 +1,62 @@ + + + + \ No newline at end of file diff --git a/addons/kuaidi/view/wechat/express.css b/addons/kuaidi/view/wechat/express.css new file mode 100755 index 0000000..2def527 --- /dev/null +++ b/addons/kuaidi/view/wechat/express.css @@ -0,0 +1,265 @@ + +html * { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +*, *:after, *:before { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.cd-container { + width: 90%; + max-width: 1170px; + margin: 0 auto; +} +.cd-container::after { + content: ''; + display: table; + clear: both; +} + +#cd-timeline { + position: relative; + margin-top: 2em; + margin-bottom: 2em; +} +#cd-timeline::before { + content: ''; + position: absolute; + top: 0; + left: 18px; + height: 100%; + width: 4px; + background: #d7e4ed; +} +@media only screen and (min-width: 1170px) { + #cd-timeline { + margin-top: 3em; + margin-bottom: 3em; + } + #cd-timeline::before { + left: 50%; + margin-left: -2px; + } +} + +.cd-timeline-block { + position: relative; + margin: 1em 0; +} +.cd-timeline-block:after { + content: ""; + display: table; + clear: both; +} +.cd-timeline-block:first-child { + margin-top: 0; +} +.cd-timeline-block:last-child { + margin-bottom: 0; +} +@media only screen and (min-width: 1170px) { + .cd-timeline-block { + margin: 4em 0; + } + .cd-timeline-block:first-child { + margin-top: 0; + } + .cd-timeline-block:last-child { + margin-bottom: 0; + } +} + +.cd-timeline-img { + position: absolute; + top: 2px; + left: 10px; + width: 20px; + height: 20px; + border-radius: 50%; + box-shadow: 0 0 0 4px white, inset 0 2px 0 rgba(0, 0, 0, 0.08), 0 3px 0 4px rgba(0, 0, 0, 0.05); +} +.cd-timeline-img img { + display: block; + width: 24px; + height: 24px; + position: relative; + left: 50%; + top: 50%; + margin-left: -12px; + margin-top: -12px; +} +.curr-picture { + color: #75ce66; + position: absolute; + left: -2px; + top: -2px; +} +.cd-timeline-img.cd-movie { + background: #c03b44; +} +.cd-timeline-img.cd-location { + background: #f0ca45; +} +@media only screen and (min-width: 1170px) { + .cd-timeline-img { + width: 60px; + height: 60px; + left: 50%; + margin-left: -30px; + -webkit-transform: translateZ(0); + -webkit-backface-visibility: hidden; + } + .cssanimations .cd-timeline-img.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-img.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-1 0.6s; + -moz-animation: cd-bounce-1 0.6s; + animation: cd-bounce-1 0.6s; + } +} + +.cd-timeline-content { + position: relative; + margin-left: 50px; + background: white; + border-radius: 0.25em; + padding: 1em; + box-shadow: 0 2px 0 #e0e4e3; +} +.cd-timeline-content:after { + content: ""; + display: table; + clear: both; +} +.cd-timeline-content h2 { + color: #303e49; +} + +.cd-timeline-content .cd-read-more, .cd-timeline-content .cd-date { + display: inline-block; +} +.cd-timeline-content .cd-read-more { + float: right; + padding: .8em 1em; + background: #acb7c0; + color: white; + border-radius: 0.25em; +} +.no-touch .cd-timeline-content .cd-read-more:hover { + background-color: #bac4cb; +} +a.cd-read-more:hover{text-decoration:none; background-color: #424242; } +.cd-timeline-content .cd-date { + float: left; + padding: .8em 0; + opacity: .7; +} +.cd-timeline-content::before { + content: ''; + position: absolute; + top: 16px; + right: 100%; + height: 0; + width: 0; + border: 7px solid transparent; + border-right: 7px solid white; +} +@media only screen and (min-width: 768px) { + .cd-timeline-content h2 { + font-size: 20px; + font-size: 1.25rem; + } + .cd-timeline-content .cd-read-more, .cd-timeline-content .cd-date { + font-size: 14px; + font-size: 0.875rem; + } +} +@media only screen and (min-width: 1170px) { + .cd-timeline-content { + margin-left: 0; + padding: 1.6em; + width: 45%; + } + .cd-timeline-content::before { + top: 24px; + left: 100%; + border-color: transparent; + border-left-color: white; + } + .cd-timeline-content .cd-read-more { + float: left; + } + .cd-timeline-content .cd-date { + position: absolute; + width: 100%; + left: 122%; + top: 6px; + font-size: 16px; + font-size: 1rem; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content::before { + top: 24px; + left: auto; + right: 100%; + border-color: transparent; + border-right-color: white; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-read-more { + float: right; + } + .cd-timeline-block:nth-child(even) .cd-timeline-content .cd-date { + left: auto; + right: 122%; + text-align: right; + } + .cssanimations .cd-timeline-content.is-hidden { + visibility: hidden; + } + .cssanimations .cd-timeline-content.bounce-in { + visibility: visible; + -webkit-animation: cd-bounce-2 0.6s; + -moz-animation: cd-bounce-2 0.6s; + animation: cd-bounce-2 0.6s; + } +} + +@media only screen and (min-width: 1170px) { + .cssanimations .cd-timeline-block:nth-child(even) .cd-timeline-content.bounce-in { + -webkit-animation: cd-bounce-2-inverse 0.6s; + -moz-animation: cd-bounce-2-inverse 0.6s; + animation: cd-bounce-2-inverse 0.6s; + } +} +.o-Img { + max-width: 60px; + max-height: 60px; + width: 60px; + height: 60px; + margin-top: 5px; + padding-top: 0; +} +.wst-fr-box { + position: fixed; + z-index: 9999; + right: -999px; + bottom: 0px; + width: 100%; + min-height: 40%; + background: #f2f2f2; + font-size: 0.14rem; +} +.d-goodsitme { + background: #fff; + border-bottom: none; + margin-bottom: 5px; + font-size: 0.14rem; +} \ No newline at end of file diff --git a/addons/kuaidi/view/wechat/view.html b/addons/kuaidi/view/wechat/view.html new file mode 100755 index 0000000..a3ac899 --- /dev/null +++ b/addons/kuaidi/view/wechat/view.html @@ -0,0 +1,62 @@ + + + + \ No newline at end of file diff --git a/admin.php b/admin.php new file mode 100755 index 0000000..a52a7bc --- /dev/null +++ b/admin.php @@ -0,0 +1,5 @@ +connect('127.0.0.1',11211)){ + var_dump( $mem->get('333')); + } + + $a=["2123213","11"]; + list($ip,$port) = $a; + echo $port; \ No newline at end of file diff --git a/extend/.htaccess b/extend/.htaccess new file mode 100755 index 0000000..3e63591 --- /dev/null +++ b/extend/.htaccess @@ -0,0 +1,4 @@ + +order allow,deny +deny from all + \ No newline at end of file diff --git a/extend/alipay/AlipayNotify.php b/extend/alipay/AlipayNotify.php new file mode 100755 index 0000000..e1d3456 --- /dev/null +++ b/extend/alipay/AlipayNotify.php @@ -0,0 +1,153 @@ +alipay_config = $alipay_config; + } + function AlipayNotify($alipay_config) { + $this->__construct ( $alipay_config ); + } + /** + * 针对notify_url验证消息是否是支付宝发出的合法消息 + * @return 验证结果 + */ + function verifyNotify() { + if (empty ( $_POST )) { // 判断POST来的数组是否为空 + return false; + } else { + // 对notify_data解密 + $decrypt_post_para = $_POST; + if ($this->alipay_config ['sign_type'] == '0001') { + $decrypt_post_para ['notify_data'] = rsaDecrypt ( $decrypt_post_para ['notify_data'], $this->alipay_config ['private_key_path'] ); + } + // notify_id从decrypt_post_para中解析出来(也就是说decrypt_post_para中已经包含notify_id的内容) + $doc = new \DOMDocument (); + $doc->loadXML ( $decrypt_post_para ['notify_data'] ); + $notify_id = $doc->getElementsByTagName ( "notify_id" )->item ( 0 )->nodeValue; + + // 获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息) + $responseTxt = 'true'; + if (! empty ( $notify_id )) { + $responseTxt = $this->getResponse ( $notify_id ); + } + // 生成签名结果 + $isSign = $this->getSignVeryfy ( $decrypt_post_para, $_POST ["sign"], false ); + + if (preg_match ( "/true$/i", $responseTxt ) && $isSign) { + return true; + } else { + return false; + } + } + } + + /** + * 针对return_url验证消息是否是支付宝发出的合法消息 + * @return 验证结果 + */ + function verifyReturn() { + if (empty ( $_GET )) { // 判断GET来的数组是否为空 + return false; + } else { + // 生成签名结果 + $isSign = $this->getSignVeryfy ( $_GET, $_GET ["sign"], true ); + if ($isSign) { + return true; + } else { + return false; + } + } + } + + /** + * 解密 + * @param $input_para 要解密数据 + * @return 解密后结果 + */ + function decrypt($prestr) { + return rsaDecrypt ( $prestr, trim ( $this->alipay_config ['private_key_path'] ) ); + } + + /** + * 异步通知时,对参数做固定排序 + * @param $para 排序前的参数组 + * @return 排序后的参数组 + */ + function sortNotifyPara($para) { + $para_sort ['service'] = $para ['service']; + $para_sort ['v'] = $para ['v']; + $para_sort ['sec_id'] = $para ['sec_id']; + $para_sort ['notify_data'] = $para ['notify_data']; + return $para_sort; + } + + /** + * 获取返回时的签名验证结果 + * @param $para_temp 通知返回来的参数数组 + * @param $sign 返回的签名结果 + * @param $isSort 是否对待签名数组排序 + * @return 签名验证结果 + */ + function getSignVeryfy($para_temp, $sign, $isSort) { + // 除去待签名参数数组中的空值和签名参数 + $para = paraFilter ( $para_temp ); + // 对待签名参数数组排序 + if ($isSort) { + $para = argSort ( $para ); + } else { + $para = $this->sortNotifyPara ( $para ); + } + // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 + $prestr = createLinkstring ( $para ); + + $isSgin = false; + switch (strtoupper ( trim ( $this->alipay_config ['sign_type'] ) )) { + case "MD5" : + $isSgin = md5Verify ( $prestr, $sign, $this->alipay_config ['key'] ); + break; + case "RSA" : + $isSgin = rsaVerify ( $prestr, trim ( $this->alipay_config ['ali_public_key_path'] ), $sign ); + break; + case "0001" : + $isSgin = rsaVerify ( $prestr, trim ( $this->alipay_config ['ali_public_key_path'] ), $sign ); + break; + default : + $isSgin = false; + } + + return $isSgin; + } + + /** + * 获取远程服务器ATN结果,验证返回URL + * @param $notify_id 通知校验ID + * @return 服务器ATN结果 验证结果集: + * invalid命令参数不对 出现这个错误,请检测返回处理中partner和key是否为空 + * true 返回正确信息 + * false 请检查防火墙或者是服务器阻止端口问题以及验证时间是否超过一分钟 + */ + function getResponse($notify_id) { + $transport = strtolower ( trim ( $this->alipay_config ['transport'] ) ); + $partner = trim ( $this->alipay_config ['partner'] ); + $veryfy_url = ''; + if ($transport == 'https') { + $veryfy_url = $this->https_verify_url; + } else { + $veryfy_url = $this->http_verify_url; + } + $veryfy_url = $veryfy_url . "partner=" . $partner . "¬ify_id=" . $notify_id; + $responseTxt = getHttpResponseGET ( $veryfy_url, $this->alipay_config ['cacert'] ); + return $responseTxt; + } +} +?> diff --git a/extend/alipay/AlipaySubmit.php b/extend/alipay/AlipaySubmit.php new file mode 100755 index 0000000..93cc1d6 --- /dev/null +++ b/extend/alipay/AlipaySubmit.php @@ -0,0 +1,181 @@ +alipay_config = $alipay_config; + } + function AlipaySubmit($alipay_config) { + $this->__construct($alipay_config); + } + + /** + * 生成签名结果 + * @param $para_sort 已排序要签名的数组 + * return 签名结果字符串 + */ + function buildRequestMysign($para_sort) { + //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 + $prestr = createLinkstring($para_sort); + $mysign = ""; + switch (strtoupper(trim($this->alipay_config['sign_type']))) { + case "MD5" : + $mysign = md5Sign($prestr, $this->alipay_config['key']); + break; + case "RSA" : + $mysign = rsaSign($prestr, $this->alipay_config['private_key_path']); + break; + case "0001" : + $mysign = rsaSign($prestr, $this->alipay_config['private_key_path']); + break; + default : + $mysign = ""; + } + return $mysign; + } + + /** + * 生成要请求给支付宝的参数数组 + * @param $para_temp 请求前的参数数组 + * @return 要请求的参数数组 + */ + function buildRequestPara($para_temp) { + //除去待签名参数数组中的空值和签名参数 + $para_filter = paraFilter($para_temp); + //对待签名参数数组排序 + $para_sort = argSort($para_filter); + //生成签名结果 + $mysign = $this->buildRequestMysign($para_sort); + //签名结果与签名方式加入请求提交参数组中 + $para_sort['sign'] = $mysign; + if($para_sort['service'] != 'alipay.wap.trade.create.direct' && $para_sort['service'] != 'alipay.wap.auth.authAndExecute') { + $para_sort['sign_type'] = strtoupper(trim($this->alipay_config['sign_type'])); + } + return $para_sort; + } + + /** + * 生成要请求给支付宝的参数数组 + * @param $para_temp 请求前的参数数组 + * @return 要请求的参数数组字符串 + */ + function buildRequestParaToString($para_temp) { + //待请求参数数组 + $para = $this->buildRequestPara($para_temp); + //把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码 + $request_data = createLinkstringUrlencode($para); + + return $request_data; + } + + /** + * 建立请求,以表单HTML形式构造(默认) + * @param $para_temp 请求参数数组 + * @param $method 提交方式。两个值可选:post、get + * @param $button_name 确认按钮显示文字 + * @return 提交表单HTML文本 + */ + function buildRequestForm($para_temp, $method, $button_name) { + //待请求参数数组 + $para = $this->buildRequestPara($para_temp); + + $sHtml = "
"; + while (list ($key, $val) = each ($para)) { + $sHtml.= ""; + } + //submit按钮控件请不要含有name属性 + $sHtml = $sHtml."
"; + $sHtml = $sHtml.""; + + return $sHtml; + } + + /** + * 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果 + * @param $para_temp 请求参数数组 + * @return 支付宝处理结果 + */ + function buildRequestHttp($para_temp) { + $sResult = ''; + + //待请求参数数组字符串 + $request_data = $this->buildRequestPara($para_temp); + //远程获取数据 + $sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'],$request_data,trim(strtolower($this->alipay_config['input_charset']))); + return $sResult; + } + + /** + * 建立请求,以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果,带文件上传功能 + * @param $para_temp 请求参数数组 + * @param $file_para_name 文件类型的参数名 + * @param $file_name 文件完整绝对路径 + * @return 支付宝返回处理结果 + */ + function buildRequestHttpInFile($para_temp, $file_para_name, $file_name) { + //待请求参数数组 + $para = $this->buildRequestPara($para_temp); + $para[$file_para_name] = "@".$file_name; + //远程获取数据 + $sResult = getHttpResponsePOST($this->alipay_gateway_new, $this->alipay_config['cacert'],$para,trim(strtolower($this->alipay_config['input_charset']))); + return $sResult; + } + + /** + * 解析远程模拟提交后返回的信息 + * @param $str_text 要解析的字符串 + * @return 解析结果 + */ + function parseResponse($str_text) { + //以“&”字符切割字符串 + $para_split = explode('&',$str_text); + //把切割后的字符串数组变成变量与数值组合的数组 + foreach ($para_split as $item) { + //获得第一个=字符的位置 + $nPos = strpos($item,'='); + //获得字符串长度 + $nLen = strlen($item); + //获得变量名 + $key = substr($item,0,$nPos); + //获得数值 + $value = substr($item,$nPos+1,$nLen-$nPos-1); + //放入数组中 + $para_text[$key] = $value; + } + + if( ! empty ($para_text['res_data'])) { + //解析加密部分字符串 + if($this->alipay_config['sign_type'] == '0001') { + $para_text['res_data'] = rsaDecrypt($para_text['res_data'], $this->alipay_config['private_key_path']); + } + + //token从res_data中解析出来(也就是说res_data中已经包含token的内容) + $doc = new \DOMDocument(); + $doc->loadXML($para_text['res_data']); + $para_text['request_token'] = $doc->getElementsByTagName( "request_token" )->item(0)->nodeValue; + } + return $para_text; + } + + /** + * 用于防钓鱼,调用接口query_timestamp来获取时间戳的处理函数 + * 注意:该功能PHP5环境及以上支持,因此必须服务器、本地电脑中装有支持DOMDocument、SSL的PHP配置环境。建议本地调试时使用PHP开发软件 + * return 时间戳字符串 + */ + function query_timestamp() { + $url = $this->alipay_gateway_new."service=query_timestamp&partner=".trim(strtolower($this->alipay_config['partner']))."&_input_charset=".trim(strtolower($this->alipay_config['input_charset'])); + $encrypt_key = ""; + $doc = new \DOMDocument(); + $doc->load($url); + $itemEncrypt_key = $doc->getElementsByTagName( "encrypt_key" ); + $encrypt_key = $itemEncrypt_key->item(0)->nodeValue; + return $encrypt_key; + } +} +?> \ No newline at end of file diff --git a/extend/alipay/Corefunction.php b/extend/alipay/Corefunction.php new file mode 100755 index 0000000..a93e3ea --- /dev/null +++ b/extend/alipay/Corefunction.php @@ -0,0 +1,176 @@ + \ No newline at end of file diff --git a/extend/alipay/Md5function.php b/extend/alipay/Md5function.php new file mode 100755 index 0000000..5b19e02 --- /dev/null +++ b/extend/alipay/Md5function.php @@ -0,0 +1,32 @@ + \ No newline at end of file diff --git a/extend/alipay/aop/AlipayMobilePublicMultiMediaClient.php b/extend/alipay/aop/AlipayMobilePublicMultiMediaClient.php new file mode 100755 index 0000000..f4ee173 --- /dev/null +++ b/extend/alipay/aop/AlipayMobilePublicMultiMediaClient.php @@ -0,0 +1,231 @@ + serverUrl = $serverUrl; + $this -> appId = $appId; + $this -> privateKey = $partner_private_key; + $this -> format = $format; + $this -> charset = $charset; + } + + /** + * getContents 获取网址内容 + * @param $request + * @return text | bin + */ + public function getContents(){ + //自己的服务器如果没有 curl,可用:fsockopen() 等 + + + //1: + //2: 私钥格式 + $datas = array( + "app_id" => $this -> appId, + "method" => $this -> METHOD_POST, + "sign_type" => $this -> sign_type, + "version" => $this -> apiVersion, + "timestamp" => date('Y-m-d H:i:s') ,//yyyy-MM-dd HH:mm:ss + "biz_content" => '{"mediaId":"'. $this -> media_id .'"}', + "charset" => $this -> charset + ); + + + + //要提交的数据 + $data_sign = $this -> buildGetUrl( $datas ); + + $post_data = $data_sign; + //初始化 curl + $ch = curl_init(); + //设置目标服务器 + curl_setopt($ch, CURLOPT_URL, $this -> serverUrl ); + curl_setopt($ch, CURLOPT_HEADER, TRUE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + //超时时间 + curl_setopt($ch, CURLOPT_TIMEOUT, $this-> timeout); + + if( $this-> METHOD_POST == 'POST'){ + // post数据 + curl_setopt($ch, CURLOPT_POST, 1); + // post的变量 + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + } + + + + + $output = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + echo $output; + + //分离头部 + //list($header, $body) = explode("\r\n\r\n", $output, 2); + $datas = explode("\r\n\r\n", $output, 2); + $header = $datas[0]; + + if( $httpCode == '200'){ + $body = $datas[1]; + }else{ + $body = ''; + + } + + + + + return $this -> execute( $header, $body, $httpCode ); + } + + /** + * + * @param $request + * @return text | bin + */ + public function execute( $header = '', $body = '', $httpCode = '' ){ + $exe = new AlipayMobilePublicMultiMediaExecute( $header, $body, $httpCode ); + return $exe; + } + + public function buildGetUrl( $query = array() ){ + + if( ! is_array( $query ) ){ + //exit; + } + + //排序参数, + $data = $this -> buildQuery( $query ); + + + + // 私钥密码 + $passphrase = ''; + $key_width = 64; + + //私钥 + $privateKey = $this -> privateKey; + $p_key = array(); + //如果私钥是 1行 + if( ! stripos( $privateKey, "\n" ) ){ + $i = 0; + while( $key_str = substr( $privateKey , $i * $key_width , $key_width) ){ + $p_key[] = $key_str; + $i ++ ; + } + }else{ + //echo '一行?'; + } + $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . implode("\n", $p_key) ; + $privateKey = $privateKey ."\n-----END RSA PRIVATE KEY-----"; + +// echo "\n\n私钥:\n"; +// echo( $privateKey ); +// echo "\n\n\n"; + + //私钥 + $private_id = openssl_pkey_get_private( $privateKey , $passphrase); + + + // 签名 + $signature = ''; + + if("RSA2"==$this->sign_type){ + + openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA256 ); + }else{ + + openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA1 ); + } + + openssl_free_key( $private_id ); + + //加密后的内容通常含有特殊字符,需要编码转换下 + $signature = base64_encode($signature); + + $signature = urlencode( $signature ); + + //$signature = 'XjUN6YM1Mc9HXebKMv7GTLy7gmyhktyOgKk2/Jf+cz4DtP6udkzTdpkjW2j/Z4ZSD7xD6CNYI1Spz4yS93HPT0a5X9LgFWYY8SaADqe+ArXg+FBSiTwUz49SE//Xd9+LEiIRsSFkbpkuiGoO6mqJmB7vXjlD5lx6qCM3nb41wb8='; + + $out = $data .'&'. $this -> SIGN .'='. $signature; + +// echo "\n\n 加密后:\n"; +// echo( $out ); +// echo "\n\n\n"; + + return $out ; + } + + /* + * 查询参数排序 a-z + * */ + public function buildQuery( $query ){ + if ( !$query ) { + return null; + } + +//将要 参数 排序 + ksort( $query ); + + //重新组装参数 + $params = array(); + foreach($query as $key => $value){ + $params[] = $key .'='. $value ; + } + $data = implode('&', $params); + + return $data; + + } + + + + + + + + + + + + + + +} diff --git a/extend/alipay/aop/AlipayMobilePublicMultiMediaExecute.php b/extend/alipay/aop/AlipayMobilePublicMultiMediaExecute.php new file mode 100755 index 0000000..d662f3b --- /dev/null +++ b/extend/alipay/aop/AlipayMobilePublicMultiMediaExecute.php @@ -0,0 +1,108 @@ + 'jpg', //+ + "text/plain" => 'text' + ); + + /* + * @$header : 头部 + * */ + function __construct( $header, $body, $httpCode ){ + $this -> code = $httpCode; + $this -> msg = ''; + $this -> params = $header ; + $this -> body = $body; + } + + /** + * + * @return text | bin + */ + public function getCode(){ + return $this -> code ; + } + + /** + * + * @return text | bin + */ + public function getMsg(){ + return $this -> msg ; + } + + /** + * + * @return text | bin + */ + public function getType(){ + $subject = $this -> params ; + $pattern = '/Content\-Type:([^;]+)/'; + preg_match($pattern, $subject, $matches); + if( $matches ){ + $type = $matches[1]; + }else{ + $type = 'application/download'; + } + + return str_replace( ' ', '', $type ); + } + + /** + * + * @return text | bin + */ + public function getContentLength(){ + $subject = $this -> params ; + $pattern = '/Content-Length:\s*([^\n]+)/'; + preg_match($pattern, $subject, $matches); + return (int)( isset($matches[1] ) ? $matches[1] : '' ); + } + + + public function getFileSuffix( $fileType ){ + $type = isset( $this -> fileSuffix[ $fileType ] ) ? $this -> fileSuffix[ $fileType ] : 'text/plain' ; + if( !$type ){ + $type = 'json'; + } + return $type; + } + + + + /** + * + * @return text | bin + */ + public function getBody(){ + //header('Content-type: image/jpeg'); + return $this -> body ; + } + + /** + * 获取参数 + * @return text | bin + */ + public function getParams(){ + return $this -> params ; + } + + +} diff --git a/extend/alipay/aop/AopClient.php b/extend/alipay/aop/AopClient.php new file mode 100755 index 0000000..b4bb0e4 --- /dev/null +++ b/extend/alipay/aop/AopClient.php @@ -0,0 +1,1216 @@ +sign($this->getSignContent($params), $signType); + } + + public function rsaSign($params, $signType = "RSA") { + return $this->sign($this->getSignContent($params), $signType); + } + + public function getSignContent($params) { + ksort($params); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . "$v"; + } else { + $stringToBeSigned .= "&" . "$k" . "=" . "$v"; + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + + //此方法对value做urlencode + public function getSignContentUrlencode($params) { + ksort($params); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . urlencode($v); + } else { + $stringToBeSigned .= "&" . "$k" . "=" . urlencode($v); + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + protected function sign($data, $signType = "RSA") { + if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ + $priKey=$this->rsaPrivateKey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + }else { + $priKey = file_get_contents($this->rsaPrivateKeyFilePath); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if(!$this->checkEmpty($this->rsaPrivateKeyFilePath)){ + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + /** + * RSA单独签名方法,未做字符串处理,字符串处理见getSignContent() + * @param $data 待签名字符串 + * @param $privatekey 商户私钥,根据keyfromfile来判断是读取字符串还是读取文件,false:填写私钥字符串去回车和空格 true:填写私钥文件路径 + * @param $signType 签名方式,RSA:SHA1 RSA2:SHA256 + * @param $keyfromfile 私钥获取方式,读取字符串还是读文件 + * @return string + * @author mengyu.wh + */ + public function alonersaSign($data,$privatekey,$signType = "RSA",$keyfromfile=false) { + + if(!$keyfromfile){ + $priKey=$privatekey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + } + else{ + $priKey = file_get_contents($privatekey); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if($keyfromfile){ + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + + protected function curl($url, $postFields = null) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FAILONERROR, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $postBodyString = ""; + $encodeArray = Array(); + $postMultipart = false; + + + if (is_array($postFields) && 0 < count($postFields)) { + + foreach ($postFields as $k => $v) { + if ("@" != substr($v, 0, 1)) //判断是不是文件上传 + { + + $postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&"; + $encodeArray[$k] = $this->characet($v, $this->postCharset); + } else //文件上传用multipart/form-data,否则用www-form-urlencoded + { + $postMultipart = true; + $encodeArray[$k] = new \CURLFile(substr($v, 1)); + } + + } + unset ($k, $v); + curl_setopt($ch, CURLOPT_POST, true); + if ($postMultipart) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray); + } else { + curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1)); + } + } + + if ($postMultipart) { + + $headers = array('content-type: multipart/form-data;charset=' . $this->postCharset . ';boundary=' . $this->getMillisecond()); + } else { + + $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset); + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + + + + + $reponse = curl_exec($ch); + + if (curl_errno($ch)) { + + throw new Exception(curl_error($ch), 0); + } else { + $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (200 !== $httpStatusCode) { + throw new Exception($reponse, $httpStatusCode); + } + } + + curl_close($ch); + return $reponse; + } + + protected function getMillisecond() { + list($s1, $s2) = explode(' ', microtime()); + return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); + } + + + protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) { + $localIp = isset ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI"; + $logger = new LtLogger; + $logger->conf["log_file"] = rtrim(AOP_SDK_WORK_DIR, '\\/') . '/' . "logs/aop_comm_err_" . $this->appId . "_" . date("Y-m-d") . ".log"; + $logger->conf["separator"] = "^_^"; + $logData = array( + date("Y-m-d H:i:s"), + $apiName, + $this->appId, + $localIp, + PHP_OS, + $this->alipaySdkVersion, + $requestUrl, + $errorCode, + str_replace("\n", "", $responseTxt) + ); + $logger->log($logData); + } + + /** + * 生成用于调用收银台SDK的字符串 + * @param $request SDK接口的请求参数对象 + * @return string + * @author guofa.tgf + */ + public function sdkExecute($request) { + + $this->setupCharsets($request); + + $params['app_id'] = $this->appId; + $params['method'] = $request->getApiMethodName(); + $params['format'] = $this->format; + $params['sign_type'] = $this->signType; + $params['timestamp'] = date("Y-m-d H:i:s"); + $params['alipay_sdk'] = $this->alipaySdkVersion; + $params['charset'] = $this->postCharset; + + $version = $request->getApiVersion(); + $params['version'] = $this->checkEmpty($version) ? $this->apiVersion : $version; + + if ($notify_url = $request->getNotifyUrl()) { + $params['notify_url'] = $notify_url; + } + + $dict = $request->getApiParas(); + $params['biz_content'] = $dict['biz_content']; + + ksort($params); + + $params['sign'] = $this->generateSign($params, $this->signType); + + foreach ($params as &$value) { + $value = $this->characet($value, $params['charset']); + } + + return http_build_query($params); + } + + /* + 页面提交执行方法 + @param:跳转类接口的request; $httpmethod 提交方式。两个值可选:post、get + @return:构建好的、签名后的最终跳转URL(GET)或String形式的form(POST) + auther:笙默 + */ + public function pageExecute($request,$httpmethod = "POST") { + + $this->setupCharsets($request); + + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); + throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); + } + + $iv=null; + + if(!$this->checkEmpty($request->getApiVersion())){ + $iv=$request->getApiVersion(); + }else{ + $iv=$this->apiVersion; + } + + //组装系统参数 + $sysParams["app_id"] = $this->appId; + $sysParams["version"] = $iv; + $sysParams["format"] = $this->format; + $sysParams["sign_type"] = $this->signType; + $sysParams["method"] = $request->getApiMethodName(); + $sysParams["timestamp"] = date("Y-m-d H:i:s"); + $sysParams["alipay_sdk"] = $this->alipaySdkVersion; + $sysParams["terminal_type"] = $request->getTerminalType(); + $sysParams["terminal_info"] = $request->getTerminalInfo(); + $sysParams["prod_code"] = $request->getProdCode(); + $sysParams["notify_url"] = $request->getNotifyUrl(); + $sysParams["return_url"] = $request->getReturnUrl(); + $sysParams["charset"] = $this->postCharset; + + //获取业务参数 + $apiParams = $request->getApiParas(); + + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + $sysParams["encrypt_type"] = $this->encryptType; + + if ($this->checkEmpty($apiParams['biz_content'])) { + + throw new Exception(" api request Fail! The reason : encrypt request is not supperted!"); + } + + if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { + + throw new Exception(" encryptType and encryptKey must not null! "); + } + + if ("AES" != $this->encryptType) { + + throw new Exception("加密类型只支持AES"); + } + + // 执行加密 + $enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey); + $apiParams['biz_content'] = $enCryptContent; + + } + + //print_r($apiParams); + $totalParams = array_merge($apiParams, $sysParams); + + //待签名字符串 + $preSignStr = $this->getSignContent($totalParams); + + //签名 + $totalParams["sign"] = $this->generateSign($totalParams, $this->signType); + + if ("GET" == strtoupper($httpmethod)) { + + //value做urlencode + $preString=$this->getSignContentUrlencode($totalParams); + //拼接GET请求串 + $requestUrl = $this->gatewayUrl."?".$preString; + + return $requestUrl; + } else { + //拼接表单字符串 + return $this->buildRequestForm($totalParams); + } + + + } + + + + /** + * 建立请求,以表单HTML形式构造(默认) + * @param $para_temp 请求参数数组 + * @return 提交表单HTML文本 + */ + protected function buildRequestForm($para_temp) { + + $sHtml = "
"; + while (list ($key, $val) = each ($para_temp)) { + if (false === $this->checkEmpty($val)) { + //$val = $this->characet($val, $this->postCharset); + $val = str_replace("'","'",$val); + //$val = str_replace("\"",""",$val); + $sHtml.= ""; + } + } + + //submit按钮控件请不要含有name属性 + $sHtml = $sHtml."
"; + + $sHtml = $sHtml.""; + + return $sHtml; + } + + + public function execute($request, $authToken = null, $appInfoAuthtoken = null) { + + $this->setupCharsets($request); + + // // 如果两者编码不一致,会出现签名验签或者乱码 + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); + throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); + } + + $iv = null; + + if (!$this->checkEmpty($request->getApiVersion())) { + $iv = $request->getApiVersion(); + } else { + $iv = $this->apiVersion; + } + + + //组装系统参数 + $sysParams["app_id"] = $this->appId; + $sysParams["version"] = $iv; + $sysParams["format"] = $this->format; + $sysParams["sign_type"] = $this->signType; + $sysParams["method"] = $request->getApiMethodName(); + $sysParams["timestamp"] = date("Y-m-d H:i:s"); + $sysParams["auth_token"] = $authToken; + $sysParams["alipay_sdk"] = $this->alipaySdkVersion; + $sysParams["terminal_type"] = $request->getTerminalType(); + $sysParams["terminal_info"] = $request->getTerminalInfo(); + $sysParams["prod_code"] = $request->getProdCode(); + $sysParams["notify_url"] = $request->getNotifyUrl(); + $sysParams["charset"] = $this->postCharset; + $sysParams["app_auth_token"] = $appInfoAuthtoken; + + + //获取业务参数 + $apiParams = $request->getApiParas(); + + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + $sysParams["encrypt_type"] = $this->encryptType; + + if ($this->checkEmpty($apiParams['biz_content'])) { + + throw new Exception(" api request Fail! The reason : encrypt request is not supperted!"); + } + + if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { + + throw new Exception(" encryptType and encryptKey must not null! "); + } + + if ("AES" != $this->encryptType) { + + throw new Exception("加密类型只支持AES"); + } + + // 执行加密 + $enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey); + $apiParams['biz_content'] = $enCryptContent; + + } + + + //签名 + $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType); + + + //系统参数放入GET请求串 + $requestUrl = $this->gatewayUrl . "?"; + foreach ($sysParams as $sysParamKey => $sysParamValue) { + $requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&"; + } + $requestUrl = substr($requestUrl, 0, -1); + + + //发起HTTP请求 + try { + $resp = $this->curl($requestUrl, $apiParams); + } catch (Exception $e) { + + $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage()); + return false; + } + + //解析AOP返回结果 + $respWellFormed = false; + + + // 将返回结果转换本地文件编码 + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + + + + $signData = null; + + if ("json" == $this->format) { + + $respObject = json_decode($r); + if (null !== $respObject) { + $respWellFormed = true; + $signData = $this->parserJSONSignData($request, $resp, $respObject); + } + } else if ("xml" == $this->format) { + + $respObject = @ simplexml_load_string($resp); + if (false !== $respObject) { + $respWellFormed = true; + + $signData = $this->parserXMLSignData($request, $resp); + } + } + + + //返回的HTTP文本不是标准JSON或者XML,记下错误日志 + if (false === $respWellFormed) { + $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_RESPONSE_NOT_WELL_FORMED", $resp); + return false; + } + + // 验签 + $this->checkResponseSign($request, $signData, $resp, $respObject); + + // 解密 + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + if ("json" == $this->format) { + + + $resp = $this->encryptJSONSignSource($request, $resp); + + // 将返回结果转换本地文件编码 + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + $respObject = json_decode($r); + }else{ + + $resp = $this->encryptXMLSignSource($request, $resp); + + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + $respObject = @ simplexml_load_string($r); + + } + } + + return $respObject; + } + + /** + * 转换字符集编码 + * @param $data + * @param $targetCharset + * @return string + */ + function characet($data, $targetCharset) { + + if (!empty($data)) { + $fileType = $this->fileCharset; + if (strcasecmp($fileType, $targetCharset) != 0) { + $data = mb_convert_encoding($data, $targetCharset, $fileType); + // $data = iconv($fileType, $targetCharset.'//IGNORE', $data); + } + } + + + return $data; + } + + public function exec($paramsArray) { + if (!isset ($paramsArray["method"])) { + trigger_error("No api name passed"); + } + $inflector = new LtInflector; + $inflector->conf["separator"] = "."; + $requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request"; + if (!class_exists($requestClassName)) { + trigger_error("No such api: " . $paramsArray["method"]); + } + + $session = isset ($paramsArray["session"]) ? $paramsArray["session"] : null; + + $req = new $requestClassName; + foreach ($paramsArray as $paraKey => $paraValue) { + $inflector->conf["separator"] = "_"; + $setterMethodName = $inflector->camelize($paraKey); + $inflector->conf["separator"] = "."; + $setterMethodName = "set" . $inflector->camelize($setterMethodName); + if (method_exists($req, $setterMethodName)) { + $req->$setterMethodName ($paraValue); + } + } + return $this->execute($req, $session); + } + + /** + * 校验$value是否非空 + * if not set ,return true; + * if is null , return true; + **/ + protected function checkEmpty($value) { + if (!isset($value)) + return true; + if ($value === null) + return true; + if (trim($value) === "") + return true; + + return false; + } + + /** rsaCheckV1 & rsaCheckV2 + * 验证签名 + * 在使用本方法前,必须初始化AopClient且传入公钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') { + $sign = $params['sign']; + $params['sign_type'] = null; + $params['sign'] = null; + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); + } + public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') { + $sign = $params['sign']; + $params['sign'] = null; + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); + } + + function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') { + + if($this->checkEmpty($this->alipayPublicKey)){ + + $pubKey= $this->alipayrsaPublicKey; + $res = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + }else { + //读取公钥文件 + $pubKey = file_get_contents($rsaPublicKeyFilePath); + //转换为openssl格式密钥 + $res = openssl_get_publickey($pubKey); + } + + ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); + + //调用openssl内置方法验签,返回bool值 + + if ("RSA2" == $signType) { + $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); + } else { + $result = (bool)openssl_verify($data, base64_decode($sign), $res); + } + + if(!$this->checkEmpty($this->alipayPublicKey)) { + //释放资源 + openssl_free_key($res); + } + + return $result; + } + +/** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function checkSignAndDecrypt($params, $rsaPublicKeyPem, $rsaPrivateKeyPem, $isCheckSign, $isDecrypt, $signType='RSA') { + $charset = $params['charset']; + $bizContent = $params['biz_content']; + if ($isCheckSign) { + if (!$this->rsaCheckV2($params, $rsaPublicKeyPem, $signType)) { + echo "
checkSign failure
"; + exit; + } + } + if ($isDecrypt) { + return $this->rsaDecrypt($bizContent, $rsaPrivateKeyPem, $charset); + } + + return $bizContent; + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function encryptAndSign($bizContent, $rsaPublicKeyPem, $rsaPrivateKeyPem, $charset, $isEncrypt, $isSign, $signType='RSA') { + // 加密,并签名 + if ($isEncrypt && $isSign) { + $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); + $sign = $this->sign($encrypted, $signType); + $response = "$encryptedRSA$sign$signType"; + return $response; + } + // 加密,不签名 + if ($isEncrypt && (!$isSign)) { + $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); + $response = "$encrypted$signType"; + return $response; + } + // 不加密,但签名 + if ((!$isEncrypt) && $isSign) { + $sign = $this->sign($bizContent, $signType); + $response = "$bizContent$sign$signType"; + return $response; + } + // 不加密,不签名 + $response = "$bizContent"; + return $response; + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaEncrypt($data, $rsaPublicKeyPem, $charset) { + if($this->checkEmpty($this->alipayPublicKey)){ + //读取字符串 + $pubKey= $this->alipayrsaPublicKey; + $res = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + }else { + //读取公钥文件 + $pubKey = file_get_contents($rsaPublicKeyFilePath); + //转换为openssl格式密钥 + $res = openssl_get_publickey($pubKey); + } + + ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); + $blocks = $this->splitCN($data, 0, 30, $charset); + $chrtext  = null; + $encodes  = array(); + foreach ($blocks as $n => $block) { + if (!openssl_public_encrypt($block, $chrtext , $res)) { + echo "
" . openssl_error_string() . "
"; + } + $encodes[] = $chrtext ; + } + $chrtext = implode(",", $encodes); + + return base64_encode($chrtext); + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaDecrypt($data, $rsaPrivateKeyPem, $charset) { + + if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ + //读字符串 + $priKey=$this->rsaPrivateKey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + }else { + $priKey = file_get_contents($this->rsaPrivateKeyFilePath); + $res = openssl_get_privatekey($priKey); + } + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + //转换为openssl格式密钥 + $decodes = explode(',', $data); + $strnull = ""; + $dcyCont = ""; + foreach ($decodes as $n => $decode) { + if (!openssl_private_decrypt($decode, $dcyCont, $res)) { + echo "
" . openssl_error_string() . "
"; + } + $strnull .= $dcyCont; + } + return $strnull; + } + + function splitCN($cont, $n = 0, $subnum, $charset) { + //$len = strlen($cont) / 3; + $arrr = array(); + for ($i = $n; $i < strlen($cont); $i += $subnum) { + $res = $this->subCNchar($cont, $i, $subnum, $charset); + if (!empty ($res)) { + $arrr[] = $res; + } + } + + return $arrr; + } + + function subCNchar($str, $start = 0, $length, $charset = "gbk") { + if (strlen($str) <= $length) { + return $str; + } + $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; + $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; + $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; + preg_match_all($re[$charset], $str, $match); + $slice = join("", array_slice($match[0], $start, $length)); + return $slice; + } + + function parserResponseSubCode($request, $responseContent, $respObject, $format) { + + if ("json" == $format) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + $errorNodeName = $this->ERROR_RESPONSE; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $errorNodeName); + + if ($rootIndex > 0) { + // 内部节点对象 + $rInnerObject = $respObject->$rootNodeName; + } elseif ($errorIndex > 0) { + + $rInnerObject = $respObject->$errorNodeName; + } else { + return null; + } + + // 存在属性则返回对应值 + if (isset($rInnerObject->sub_code)) { + + return $rInnerObject->sub_code; + } else { + + return null; + } + + + } elseif ("xml" == $format) { + + // xml格式sub_code在同一层级 + return $respObject->sub_code; + + } + + + } + + function parserJSONSignData($request, $responseContent, $responseJSON) { + + $signData = new SignData(); + + $signData->sign = $this->parserJSONSign($responseJSON); + $signData->signSourceData = $this->parserJSONSignSource($request, $responseContent); + + + return $signData; + + } + + function parserJSONSignSource($request, $responseContent) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + + + if ($rootIndex > 0) { + + return $this->parserJSONSource($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserJSONSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + function parserJSONSource($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; + $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + $indexLen = $signDataEndIndex - $signDataStartIndex; + if ($indexLen < 0) { + + return null; + } + + return substr($responseContent, $signDataStartIndex, $indexLen); + + } + + function parserJSONSign($responseJSon) { + + return $responseJSon->sign; + } + + function parserXMLSignData($request, $responseContent) { + + + $signData = new SignData(); + + $signData->sign = $this->parserXMLSign($responseContent); + $signData->signSourceData = $this->parserXMLSignSource($request, $responseContent); + + + return $signData; + + + } + + function parserXMLSignSource($request, $responseContent) { + + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + // $this->echoDebug("
rootNodeName:" . $rootNodeName); + // $this->echoDebug("
responseContent:" . $responseContent . ""); + + + if ($rootIndex > 0) { + + return $this->parserXMLSource($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserXMLSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + function parserXMLSource($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; + $signIndex = strpos($responseContent, "<" . $this->SIGN_NODE_NAME . ">"); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + $indexLen = $signDataEndIndex - $signDataStartIndex + 1; + + if ($indexLen < 0) { + return null; + } + + + return substr($responseContent, $signDataStartIndex, $indexLen); + + + } + + function parserXMLSign($responseContent) { + $signNodeName = "<" . $this->SIGN_NODE_NAME . ">"; + $signEndNodeName = "SIGN_NODE_NAME . ">"; + + $indexOfSignNode = strpos($responseContent, $signNodeName); + $indexOfSignEndNode = strpos($responseContent, $signEndNodeName); + + + if ($indexOfSignNode < 0 || $indexOfSignEndNode < 0) { + return null; + } + + $nodeIndex = ($indexOfSignNode + strlen($signNodeName)); + + $indexLen = $indexOfSignEndNode - $nodeIndex; + + if ($indexLen < 0) { + return null; + } + + // 签名 + return substr($responseContent, $nodeIndex, $indexLen); + + } + + /** + * 验签 + * @param $request + * @param $signData + * @param $resp + * @param $respObject + * @throws Exception + */ + public function checkResponseSign($request, $signData, $resp, $respObject) { + + if (!$this->checkEmpty($this->alipayPublicKey) || !$this->checkEmpty($this->alipayrsaPublicKey)) { + + + if ($signData == null || $this->checkEmpty($signData->sign) || $this->checkEmpty($signData->signSourceData)) { + + throw new Exception(" check sign Fail! The reason : signData is Empty"); + } + + + // 获取结果sub_code + $responseSubCode = $this->parserResponseSubCode($request, $resp, $respObject, $this->format); + + + if (!$this->checkEmpty($responseSubCode) || ($this->checkEmpty($responseSubCode) && !$this->checkEmpty($signData->sign))) { + + $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); + + + if (!$checkResult) { + + if (strpos($signData->signSourceData, "\\/") > 0) { + + $signData->signSourceData = str_replace("\\/", "/", $signData->signSourceData); + + $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); + + if (!$checkResult) { + throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); + } + + } else { + + throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); + } + + } + } + + + } + } + + private function setupCharsets($request) { + if ($this->checkEmpty($this->postCharset)) { + $this->postCharset = 'UTF-8'; + } + $str = preg_match('/[\x80-\xff]/', $this->appId) ? $this->appId : print_r($request, true); + $this->fileCharset = mb_detect_encoding($str, "UTF-8, GBK") == 'UTF-8' ? 'UTF-8' : 'GBK'; + } + + // 获取加密内容 + + private function encryptJSONSignSource($request, $responseContent) { + + $parsetItem = $this->parserEncryptJSONSignSource($request, $responseContent); + + $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); + $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); + + $bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey); + return $bodyIndexContent . $bizContent . $bodyEndContent; + + } + + + private function parserEncryptJSONSignSource($request, $responseContent) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + + + if ($rootIndex > 0) { + + return $this->parserEncryptJSONItem($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserEncryptJSONItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + + private function parserEncryptJSONItem($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; + $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + + if ($signDataEndIndex < 0) { + + $signDataEndIndex = strlen($responseContent)-1 ; + } + + $indexLen = $signDataEndIndex - $signDataStartIndex; + + $encContent = substr($responseContent, $signDataStartIndex+1, $indexLen-2); + + + $encryptParseItem = new EncryptParseItem(); + + $encryptParseItem->encryptContent = $encContent; + $encryptParseItem->startIndex = $signDataStartIndex; + $encryptParseItem->endIndex = $signDataEndIndex; + + return $encryptParseItem; + + } + + // 获取加密内容 + + private function encryptXMLSignSource($request, $responseContent) { + + $parsetItem = $this->parserEncryptXMLSignSource($request, $responseContent); + + $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); + $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); + $bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey); + + return $bodyIndexContent . $bizContent . $bodyEndContent; + + } + + private function parserEncryptXMLSignSource($request, $responseContent) { + + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + // $this->echoDebug("
rootNodeName:" . $rootNodeName); + // $this->echoDebug("
responseContent:" . $responseContent . ""); + + + if ($rootIndex > 0) { + + return $this->parserEncryptXMLItem($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserEncryptXMLItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + private function parserEncryptXMLItem($responseContent, $nodeName, $nodeIndex) { + + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; + + $xmlStartNode="<".$this->ENCRYPT_XML_NODE_NAME.">"; + $xmlEndNode="ENCRYPT_XML_NODE_NAME.">"; + + $indexOfXmlNode=strpos($responseContent,$xmlEndNode); + if($indexOfXmlNode<0){ + + $item = new EncryptParseItem(); + $item->encryptContent = null; + $item->startIndex = 0; + $item->endIndex = 0; + return $item; + } + + $startIndex=$signDataStartIndex+strlen($xmlStartNode); + $bizContentLen=$indexOfXmlNode-$startIndex; + $bizContent=substr($responseContent,$startIndex,$bizContentLen); + + $encryptParseItem = new EncryptParseItem(); + $encryptParseItem->encryptContent = $bizContent; + $encryptParseItem->startIndex = $signDataStartIndex; + $encryptParseItem->endIndex = $indexOfXmlNode+strlen($xmlEndNode); + + return $encryptParseItem; + + } + + + function echoDebug($content) { + + if ($this->debugInfo) { + echo "
" . $content; + } + + } + + +} \ No newline at end of file diff --git a/extend/alipay/aop/AopEncrypt.php b/extend/alipay/aop/AopEncrypt.php new file mode 100755 index 0000000..0ec4e5b --- /dev/null +++ b/extend/alipay/aop/AopEncrypt.php @@ -0,0 +1,71 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.advice.accept"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php b/extend/alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php new file mode 100755 index 0000000..ddf4385 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.allclientrate.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAccountExrateRatequeryRequest.php b/extend/alipay/aop/request/AlipayAccountExrateRatequeryRequest.php new file mode 100755 index 0000000..47146c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAccountExrateRatequeryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.ratequery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php b/extend/alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php new file mode 100755 index 0000000..dc2b2e1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.traderequest.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquireCancelRequest.php b/extend/alipay/aop/request/AlipayAcquireCancelRequest.php new file mode 100755 index 0000000..6bb51d1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquireCancelRequest.php @@ -0,0 +1,171 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquireCloseRequest.php b/extend/alipay/aop/request/AlipayAcquireCloseRequest.php new file mode 100755 index 0000000..cbc31e9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquireCloseRequest.php @@ -0,0 +1,152 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.close"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquireCreateandpayRequest.php b/extend/alipay/aop/request/AlipayAcquireCreateandpayRequest.php new file mode 100755 index 0000000..6b0d5fb --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquireCreateandpayRequest.php @@ -0,0 +1,550 @@ +alipayCaRequest = $alipayCaRequest; + $this->apiParas["alipay_ca_request"] = $alipayCaRequest; + } + + public function getAlipayCaRequest() + { + return $this->alipayCaRequest; + } + + public function setBody($body) + { + $this->body = $body; + $this->apiParas["body"] = $body; + } + + public function getBody() + { + return $this->body; + } + + public function setBuyerEmail($buyerEmail) + { + $this->buyerEmail = $buyerEmail; + $this->apiParas["buyer_email"] = $buyerEmail; + } + + public function getBuyerEmail() + { + return $this->buyerEmail; + } + + public function setBuyerId($buyerId) + { + $this->buyerId = $buyerId; + $this->apiParas["buyer_id"] = $buyerId; + } + + public function getBuyerId() + { + return $this->buyerId; + } + + public function setChannelParameters($channelParameters) + { + $this->channelParameters = $channelParameters; + $this->apiParas["channel_parameters"] = $channelParameters; + } + + public function getChannelParameters() + { + return $this->channelParameters; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setDynamicId($dynamicId) + { + $this->dynamicId = $dynamicId; + $this->apiParas["dynamic_id"] = $dynamicId; + } + + public function getDynamicId() + { + return $this->dynamicId; + } + + public function setDynamicIdType($dynamicIdType) + { + $this->dynamicIdType = $dynamicIdType; + $this->apiParas["dynamic_id_type"] = $dynamicIdType; + } + + public function getDynamicIdType() + { + return $this->dynamicIdType; + } + + public function setExtendParams($extendParams) + { + $this->extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setFormatType($formatType) + { + $this->formatType = $formatType; + $this->apiParas["format_type"] = $formatType; + } + + public function getFormatType() + { + return $this->formatType; + } + + public function setGoodsDetail($goodsDetail) + { + $this->goodsDetail = $goodsDetail; + $this->apiParas["goods_detail"] = $goodsDetail; + } + + public function getGoodsDetail() + { + return $this->goodsDetail; + } + + public function setItBPay($itBPay) + { + $this->itBPay = $itBPay; + $this->apiParas["it_b_pay"] = $itBPay; + } + + public function getItBPay() + { + return $this->itBPay; + } + + public function setMcardParameters($mcardParameters) + { + $this->mcardParameters = $mcardParameters; + $this->apiParas["mcard_parameters"] = $mcardParameters; + } + + public function getMcardParameters() + { + return $this->mcardParameters; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPrice($price) + { + $this->price = $price; + $this->apiParas["price"] = $price; + } + + public function getPrice() + { + return $this->price; + } + + public function setQuantity($quantity) + { + $this->quantity = $quantity; + $this->apiParas["quantity"] = $quantity; + } + + public function getQuantity() + { + return $this->quantity; + } + + public function setRefIds($refIds) + { + $this->refIds = $refIds; + $this->apiParas["ref_ids"] = $refIds; + } + + public function getRefIds() + { + return $this->refIds; + } + + public function setRoyaltyParameters($royaltyParameters) + { + $this->royaltyParameters = $royaltyParameters; + $this->apiParas["royalty_parameters"] = $royaltyParameters; + } + + public function getRoyaltyParameters() + { + return $this->royaltyParameters; + } + + public function setRoyaltyType($royaltyType) + { + $this->royaltyType = $royaltyType; + $this->apiParas["royalty_type"] = $royaltyType; + } + + public function getRoyaltyType() + { + return $this->royaltyType; + } + + public function setSellerEmail($sellerEmail) + { + $this->sellerEmail = $sellerEmail; + $this->apiParas["seller_email"] = $sellerEmail; + } + + public function getSellerEmail() + { + return $this->sellerEmail; + } + + public function setSellerId($sellerId) + { + $this->sellerId = $sellerId; + $this->apiParas["seller_id"] = $sellerId; + } + + public function getSellerId() + { + return $this->sellerId; + } + + public function setShowUrl($showUrl) + { + $this->showUrl = $showUrl; + $this->apiParas["show_url"] = $showUrl; + } + + public function getShowUrl() + { + return $this->showUrl; + } + + public function setSubject($subject) + { + $this->subject = $subject; + $this->apiParas["subject"] = $subject; + } + + public function getSubject() + { + return $this->subject; + } + + public function setTotalFee($totalFee) + { + $this->totalFee = $totalFee; + $this->apiParas["total_fee"] = $totalFee; + } + + public function getTotalFee() + { + return $this->totalFee; + } + + public function getApiMethodName() + { + return "alipay.acquire.createandpay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquirePrecreateRequest.php b/extend/alipay/aop/request/AlipayAcquirePrecreateRequest.php new file mode 100755 index 0000000..09ee9de --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquirePrecreateRequest.php @@ -0,0 +1,402 @@ +body = $body; + $this->apiParas["body"] = $body; + } + + public function getBody() + { + return $this->body; + } + + public function setChannelParameters($channelParameters) + { + $this->channelParameters = $channelParameters; + $this->apiParas["channel_parameters"] = $channelParameters; + } + + public function getChannelParameters() + { + return $this->channelParameters; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setExtendParams($extendParams) + { + $this->extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setGoodsDetail($goodsDetail) + { + $this->goodsDetail = $goodsDetail; + $this->apiParas["goods_detail"] = $goodsDetail; + } + + public function getGoodsDetail() + { + return $this->goodsDetail; + } + + public function setItBPay($itBPay) + { + $this->itBPay = $itBPay; + $this->apiParas["it_b_pay"] = $itBPay; + } + + public function getItBPay() + { + return $this->itBPay; + } + + public function setOperatorCode($operatorCode) + { + $this->operatorCode = $operatorCode; + $this->apiParas["operator_code"] = $operatorCode; + } + + public function getOperatorCode() + { + return $this->operatorCode; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPrice($price) + { + $this->price = $price; + $this->apiParas["price"] = $price; + } + + public function getPrice() + { + return $this->price; + } + + public function setQuantity($quantity) + { + $this->quantity = $quantity; + $this->apiParas["quantity"] = $quantity; + } + + public function getQuantity() + { + return $this->quantity; + } + + public function setRoyaltyParameters($royaltyParameters) + { + $this->royaltyParameters = $royaltyParameters; + $this->apiParas["royalty_parameters"] = $royaltyParameters; + } + + public function getRoyaltyParameters() + { + return $this->royaltyParameters; + } + + public function setRoyaltyType($royaltyType) + { + $this->royaltyType = $royaltyType; + $this->apiParas["royalty_type"] = $royaltyType; + } + + public function getRoyaltyType() + { + return $this->royaltyType; + } + + public function setSellerEmail($sellerEmail) + { + $this->sellerEmail = $sellerEmail; + $this->apiParas["seller_email"] = $sellerEmail; + } + + public function getSellerEmail() + { + return $this->sellerEmail; + } + + public function setSellerId($sellerId) + { + $this->sellerId = $sellerId; + $this->apiParas["seller_id"] = $sellerId; + } + + public function getSellerId() + { + return $this->sellerId; + } + + public function setShowUrl($showUrl) + { + $this->showUrl = $showUrl; + $this->apiParas["show_url"] = $showUrl; + } + + public function getShowUrl() + { + return $this->showUrl; + } + + public function setSubject($subject) + { + $this->subject = $subject; + $this->apiParas["subject"] = $subject; + } + + public function getSubject() + { + return $this->subject; + } + + public function setTotalFee($totalFee) + { + $this->totalFee = $totalFee; + $this->apiParas["total_fee"] = $totalFee; + } + + public function getTotalFee() + { + return $this->totalFee; + } + + public function getApiMethodName() + { + return "alipay.acquire.precreate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquireQueryRequest.php b/extend/alipay/aop/request/AlipayAcquireQueryRequest.php new file mode 100755 index 0000000..43cc337 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquireQueryRequest.php @@ -0,0 +1,136 @@ +outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAcquireRefundRequest.php b/extend/alipay/aop/request/AlipayAcquireRefundRequest.php new file mode 100755 index 0000000..77a3947 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAcquireRefundRequest.php @@ -0,0 +1,236 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutRequestNo($outRequestNo) + { + $this->outRequestNo = $outRequestNo; + $this->apiParas["out_request_no"] = $outRequestNo; + } + + public function getOutRequestNo() + { + return $this->outRequestNo; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setRefIds($refIds) + { + $this->refIds = $refIds; + $this->apiParas["ref_ids"] = $refIds; + } + + public function getRefIds() + { + return $this->refIds; + } + + public function setRefundAmount($refundAmount) + { + $this->refundAmount = $refundAmount; + $this->apiParas["refund_amount"] = $refundAmount; + } + + public function getRefundAmount() + { + return $this->refundAmount; + } + + public function setRefundReason($refundReason) + { + $this->refundReason = $refundReason; + $this->apiParas["refund_reason"] = $refundReason; + } + + public function getRefundReason() + { + return $this->refundReason; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAppTokenGetRequest.php b/extend/alipay/aop/request/AlipayAppTokenGetRequest.php new file mode 100755 index 0000000..91724ef --- /dev/null +++ b/extend/alipay/aop/request/AlipayAppTokenGetRequest.php @@ -0,0 +1,118 @@ +secret = $secret; + $this->apiParas["secret"] = $secret; + } + + public function getSecret() + { + return $this->secret; + } + + public function getApiMethodName() + { + return "alipay.app.token.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetAccountBindRequest.php b/extend/alipay/aop/request/AlipayAssetAccountBindRequest.php new file mode 100755 index 0000000..20be1dc --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetAccountBindRequest.php @@ -0,0 +1,170 @@ +bindScene = $bindScene; + $this->apiParas["bind_scene"] = $bindScene; + } + + public function getBindScene() + { + return $this->bindScene; + } + + public function setProviderId($providerId) + { + $this->providerId = $providerId; + $this->apiParas["provider_id"] = $providerId; + } + + public function getProviderId() + { + return $this->providerId; + } + + public function setProviderUserId($providerUserId) + { + $this->providerUserId = $providerUserId; + $this->apiParas["provider_user_id"] = $providerUserId; + } + + public function getProviderUserId() + { + return $this->providerUserId; + } + + public function setProviderUserName($providerUserName) + { + $this->providerUserName = $providerUserName; + $this->apiParas["provider_user_name"] = $providerUserName; + } + + public function getProviderUserName() + { + return $this->providerUserName; + } + + public function getApiMethodName() + { + return "alipay.asset.account.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetAccountGetRequest.php b/extend/alipay/aop/request/AlipayAssetAccountGetRequest.php new file mode 100755 index 0000000..0acef2c --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetAccountGetRequest.php @@ -0,0 +1,135 @@ +providerId = $providerId; + $this->apiParas["provider_id"] = $providerId; + } + + public function getProviderId() + { + return $this->providerId; + } + + public function setProviderUserId($providerUserId) + { + $this->providerUserId = $providerUserId; + $this->apiParas["provider_user_id"] = $providerUserId; + } + + public function getProviderUserId() + { + return $this->providerUserId; + } + + public function getApiMethodName() + { + return "alipay.asset.account.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetAccountUnbindRequest.php b/extend/alipay/aop/request/AlipayAssetAccountUnbindRequest.php new file mode 100755 index 0000000..d35dc00 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetAccountUnbindRequest.php @@ -0,0 +1,134 @@ +providerId = $providerId; + $this->apiParas["provider_id"] = $providerId; + } + + public function getProviderId() + { + return $this->providerId; + } + + public function setProviderUserId($providerUserId) + { + $this->providerUserId = $providerUserId; + $this->apiParas["provider_user_id"] = $providerUserId; + } + + public function getProviderUserId() + { + return $this->providerUserId; + } + + public function getApiMethodName() + { + return "alipay.asset.account.unbind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php b/extend/alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php new file mode 100755 index 0000000..18c4a63 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php b/extend/alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php new file mode 100755 index 0000000..d07b3cd --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetPointOrderCreateRequest.php b/extend/alipay/aop/request/AlipayAssetPointOrderCreateRequest.php new file mode 100755 index 0000000..8c737dd --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetPointOrderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.asset.point.order.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayAssetPointOrderQueryRequest.php b/extend/alipay/aop/request/AlipayAssetPointOrderQueryRequest.php new file mode 100755 index 0000000..014bc92 --- /dev/null +++ b/extend/alipay/aop/request/AlipayAssetPointOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.asset.point.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayBossCsChannelQueryRequest.php b/extend/alipay/aop/request/AlipayBossCsChannelQueryRequest.php new file mode 100755 index 0000000..2f4ec2c --- /dev/null +++ b/extend/alipay/aop/request/AlipayBossCsChannelQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.boss.cs.channel.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php b/extend/alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php new file mode 100755 index 0000000..7a22bca --- /dev/null +++ b/extend/alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php @@ -0,0 +1,118 @@ +productCode = $productCode; + $this->apiParas["product_code"] = $productCode; + } + + public function getProductCode() + { + return $this->productCode; + } + + public function getApiMethodName() + { + return "alipay.boss.prod.arrangement.offline.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php new file mode 100755 index 0000000..efad1c1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php new file mode 100755 index 0000000..73f5043 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php new file mode 100755 index 0000000..d64f385 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php new file mode 100755 index 0000000..560c3dc --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php new file mode 100755 index 0000000..e95bb03 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.function.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php new file mode 100755 index 0000000..60aa1f6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.script.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php new file mode 100755 index 0000000..f76f5ad --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.station.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php new file mode 100755 index 0000000..07b0de2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php new file mode 100755 index 0000000..a489b69 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php new file mode 100755 index 0000000..2a58e80 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php new file mode 100755 index 0000000..46293a7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.generate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php new file mode 100755 index 0000000..9cfe8fe --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php new file mode 100755 index 0000000..5eb4a2e --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php new file mode 100755 index 0000000..7e9d124 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php b/extend/alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php new file mode 100755 index 0000000..e5c50ad --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.data.monitordata.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php b/extend/alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php new file mode 100755 index 0000000..8df3227 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php b/extend/alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php new file mode 100755 index 0000000..63dcf31 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.lottery.present.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php new file mode 100755 index 0000000..3c09f5f --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.lottery.presentlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php new file mode 100755 index 0000000..0af1a4d --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceMedicalInstcardBindRequest.php b/extend/alipay/aop/request/AlipayCommerceMedicalInstcardBindRequest.php new file mode 100755 index 0000000..4f625d3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceMedicalInstcardBindRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.medical.instcard.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php new file mode 100755 index 0000000..bca0c26 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php new file mode 100755 index 0000000..69205d9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.transport.offlinepay.record.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php new file mode 100755 index 0000000..e79389c --- /dev/null +++ b/extend/alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.transport.offlinepay.userblacklist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderCancelRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderCancelRequest.php new file mode 100755 index 0000000..dabd8e5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php new file mode 100755 index 0000000..e3db2ae --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderModifyRequest.php new file mode 100755 index 0000000..8fa97ab --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderQueryRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderQueryRequest.php new file mode 100755 index 0000000..817cd39 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderRefundRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderRefundRequest.php new file mode 100755 index 0000000..d96a8f8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php new file mode 100755 index 0000000..3813240 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.refuse"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php new file mode 100755 index 0000000..f14d4b0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.sp.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiOrderTransferRequest.php b/extend/alipay/aop/request/AlipayDaoweiOrderTransferRequest.php new file mode 100755 index 0000000..96fe8aa --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiOrderTransferRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.transfer"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiServiceModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiServiceModifyRequest.php new file mode 100755 index 0000000..d419812 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiServiceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.service.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php new file mode 100755 index 0000000..ef567df --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.service.price.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiSpModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiSpModifyRequest.php new file mode 100755 index 0000000..9094ca3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiSpModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.sp.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php b/extend/alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php new file mode 100755 index 0000000..d64d7f5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.sp.schedule.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php b/extend/alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php new file mode 100755 index 0000000..bcb8857 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php @@ -0,0 +1,134 @@ +billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillType($billType) + { + $this->billType = $billType; + $this->apiParas["bill_type"] = $billType; + } + + public function getBillType() + { + return $this->billType; + } + + public function getApiMethodName() + { + return "alipay.data.bill.downloadurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php b/extend/alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php new file mode 100755 index 0000000..5111190 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataexchange.sfasdf"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php new file mode 100755 index 0000000..b73d2ba --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.bill.downloadurl.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php new file mode 100755 index 0000000..6d819cd --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.chinaremodel.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php new file mode 100755 index 0000000..83237a7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.code.reco"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php new file mode 100755 index 0000000..fdf6f38 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php new file mode 100755 index 0000000..e35bc75 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.shoppingmallrec.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php new file mode 100755 index 0000000..3694463 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.shoppingmallrec.voucher.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php b/extend/alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php new file mode 100755 index 0000000..eafff18 --- /dev/null +++ b/extend/alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.userlevel.zrank.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillAddRequest.php b/extend/alipay/aop/request/AlipayEbppBillAddRequest.php new file mode 100755 index 0000000..35ddc8b --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillAddRequest.php @@ -0,0 +1,326 @@ +bankBillNo = $bankBillNo; + $this->apiParas["bank_bill_no"] = $bankBillNo; + } + + public function getBankBillNo() + { + return $this->bankBillNo; + } + + public function setBillDate($billDate) + { + $this->billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setMobile($mobile) + { + $this->mobile = $mobile; + $this->apiParas["mobile"] = $mobile; + } + + public function getMobile() + { + return $this->mobile; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setOwnerName($ownerName) + { + $this->ownerName = $ownerName; + $this->apiParas["owner_name"] = $ownerName; + } + + public function getOwnerName() + { + return $this->ownerName; + } + + public function setPayAmount($payAmount) + { + $this->payAmount = $payAmount; + $this->apiParas["pay_amount"] = $payAmount; + } + + public function getPayAmount() + { + return $this->payAmount; + } + + public function setServiceAmount($serviceAmount) + { + $this->serviceAmount = $serviceAmount; + $this->apiParas["service_amount"] = $serviceAmount; + } + + public function getServiceAmount() + { + return $this->serviceAmount; + } + + public function setSubOrderType($subOrderType) + { + $this->subOrderType = $subOrderType; + $this->apiParas["sub_order_type"] = $subOrderType; + } + + public function getSubOrderType() + { + return $this->subOrderType; + } + + public function setTrafficLocation($trafficLocation) + { + $this->trafficLocation = $trafficLocation; + $this->apiParas["traffic_location"] = $trafficLocation; + } + + public function getTrafficLocation() + { + return $this->trafficLocation; + } + + public function setTrafficRegulations($trafficRegulations) + { + $this->trafficRegulations = $trafficRegulations; + $this->apiParas["traffic_regulations"] = $trafficRegulations; + } + + public function getTrafficRegulations() + { + return $this->trafficRegulations; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillBatchPayurlGetRequest.php b/extend/alipay/aop/request/AlipayEbppBillBatchPayurlGetRequest.php new file mode 100755 index 0000000..a400e6a --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillBatchPayurlGetRequest.php @@ -0,0 +1,150 @@ +callbackUrl = $callbackUrl; + $this->apiParas["callback_url"] = $callbackUrl; + } + + public function getCallbackUrl() + { + return $this->callbackUrl; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setPayBillList($payBillList) + { + $this->payBillList = $payBillList; + $this->apiParas["pay_bill_list"] = $payBillList; + } + + public function getPayBillList() + { + return $this->payBillList; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.batch.payurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillGetRequest.php b/extend/alipay/aop/request/AlipayEbppBillGetRequest.php new file mode 100755 index 0000000..a7b64a5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillGetRequest.php @@ -0,0 +1,134 @@ +merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillPayRequest.php b/extend/alipay/aop/request/AlipayEbppBillPayRequest.php new file mode 100755 index 0000000..bb8c365 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillPayRequest.php @@ -0,0 +1,182 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setDispatchClusterTarget($dispatchClusterTarget) + { + $this->dispatchClusterTarget = $dispatchClusterTarget; + $this->apiParas["dispatch_cluster_target"] = $dispatchClusterTarget; + } + + public function getDispatchClusterTarget() + { + return $this->dispatchClusterTarget; + } + + public function setExtend($extend) + { + $this->extend = $extend; + $this->apiParas["extend"] = $extend; + } + + public function getExtend() + { + return $this->extend; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillPayurlGetRequest.php b/extend/alipay/aop/request/AlipayEbppBillPayurlGetRequest.php new file mode 100755 index 0000000..7fd4106 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillPayurlGetRequest.php @@ -0,0 +1,166 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setCallbackUrl($callbackUrl) + { + $this->callbackUrl = $callbackUrl; + $this->apiParas["callback_url"] = $callbackUrl; + } + + public function getCallbackUrl() + { + return $this->callbackUrl; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.payurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppBillSearchRequest.php b/extend/alipay/aop/request/AlipayEbppBillSearchRequest.php new file mode 100755 index 0000000..6ffc3f0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppBillSearchRequest.php @@ -0,0 +1,215 @@ +billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setChargeoffInst($chargeoffInst) + { + $this->chargeoffInst = $chargeoffInst; + $this->apiParas["chargeoff_inst"] = $chargeoffInst; + } + + public function getChargeoffInst() + { + return $this->chargeoffInst; + } + + public function setCompanyId($companyId) + { + $this->companyId = $companyId; + $this->apiParas["company_id"] = $companyId; + } + + public function getCompanyId() + { + return $this->companyId; + } + + public function setExtend($extend) + { + $this->extend = $extend; + $this->apiParas["extend"] = $extend; + } + + public function getExtend() + { + return $this->extend; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setSubOrderType($subOrderType) + { + $this->subOrderType = $subOrderType; + $this->apiParas["sub_order_type"] = $subOrderType; + } + + public function getSubOrderType() + { + return $this->subOrderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php b/extend/alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php new file mode 100755 index 0000000..e9bd700 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.invoice.title.list.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php b/extend/alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php new file mode 100755 index 0000000..d30f54c --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php new file mode 100755 index 0000000..7aeb791 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php @@ -0,0 +1,134 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setOutOrderNo($outOrderNo) + { + $this->outOrderNo = $outOrderNo; + $this->apiParas["out_order_no"] = $outOrderNo; + } + + public function getOutOrderNo() + { + return $this->outOrderNo; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.bill.pay.status"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductPayRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductPayRequest.php new file mode 100755 index 0000000..db57df3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductPayRequest.php @@ -0,0 +1,297 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBillDate($billDate) + { + $this->billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setFineAmount($fineAmount) + { + $this->fineAmount = $fineAmount; + $this->apiParas["fine_amount"] = $fineAmount; + } + + public function getFineAmount() + { + return $this->fineAmount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setOutOrderNo($outOrderNo) + { + $this->outOrderNo = $outOrderNo; + $this->apiParas["out_order_no"] = $outOrderNo; + } + + public function getOutOrderNo() + { + return $this->outOrderNo; + } + + public function setPayAmount($payAmount) + { + $this->payAmount = $payAmount; + $this->apiParas["pay_amount"] = $payAmount; + } + + public function getPayAmount() + { + return $this->payAmount; + } + + public function setPid($pid) + { + $this->pid = $pid; + $this->apiParas["pid"] = $pid; + } + + public function getPid() + { + return $this->pid; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductSignAddRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductSignAddRequest.php new file mode 100755 index 0000000..ff6f2c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductSignAddRequest.php @@ -0,0 +1,372 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setBizType($bizType) + { + $this->bizType = $bizType; + $this->apiParas["biz_type"] = $bizType; + } + + public function getBizType() + { + return $this->bizType; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setDeductType($deductType) + { + $this->deductType = $deductType; + $this->apiParas["deduct_type"] = $deductType; + } + + public function getDeductType() + { + return $this->deductType; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setNotifyConfig($notifyConfig) + { + $this->notifyConfig = $notifyConfig; + $this->apiParas["notify_config"] = $notifyConfig; + } + + public function getNotifyConfig() + { + return $this->notifyConfig; + } + + public function setOutAgreementId($outAgreementId) + { + $this->outAgreementId = $outAgreementId; + $this->apiParas["out_agreement_id"] = $outAgreementId; + } + + public function getOutAgreementId() + { + return $this->outAgreementId; + } + + public function setOwnerName($ownerName) + { + $this->ownerName = $ownerName; + $this->apiParas["owner_name"] = $ownerName; + } + + public function getOwnerName() + { + return $this->ownerName; + } + + public function setPayConfig($payConfig) + { + $this->payConfig = $payConfig; + $this->apiParas["pay_config"] = $payConfig; + } + + public function getPayConfig() + { + return $this->payConfig; + } + + public function setPayPasswordToken($payPasswordToken) + { + $this->payPasswordToken = $payPasswordToken; + $this->apiParas["pay_password_token"] = $payPasswordToken; + } + + public function getPayPasswordToken() + { + return $this->payPasswordToken; + } + + public function setPid($pid) + { + $this->pid = $pid; + $this->apiParas["pid"] = $pid; + } + + public function getPid() + { + return $this->pid; + } + + public function setSignExpireDate($signExpireDate) + { + $this->signExpireDate = $signExpireDate; + $this->apiParas["sign_expire_date"] = $signExpireDate; + } + + public function getSignExpireDate() + { + return $this->signExpireDate; + } + + public function setSubBizType($subBizType) + { + $this->subBizType = $subBizType; + $this->apiParas["sub_biz_type"] = $subBizType; + } + + public function getSubBizType() + { + return $this->subBizType; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php new file mode 100755 index 0000000..5244390 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php @@ -0,0 +1,182 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setPayPasswordToken($payPasswordToken) + { + $this->payPasswordToken = $payPasswordToken; + $this->apiParas["pay_password_token"] = $payPasswordToken; + } + + public function getPayPasswordToken() + { + return $this->payPasswordToken; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php new file mode 100755 index 0000000..771737c --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php b/extend/alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php new file mode 100755 index 0000000..b734839 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.validate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodCreditGetRequest.php b/extend/alipay/aop/request/AlipayEcapiprodCreditGetRequest.php new file mode 100755 index 0000000..239987c --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodCreditGetRequest.php @@ -0,0 +1,182 @@ +creditNo = $creditNo; + $this->apiParas["credit_no"] = $creditNo; + } + + public function getCreditNo() + { + return $this->creditNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.credit.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDataPutRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDataPutRequest.php new file mode 100755 index 0000000..690e1ff --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDataPutRequest.php @@ -0,0 +1,246 @@ +category = $category; + $this->apiParas["category"] = $category; + } + + public function getCategory() + { + return $this->category; + } + + public function setCharSet($charSet) + { + $this->charSet = $charSet; + $this->apiParas["char_set"] = $charSet; + } + + public function getCharSet() + { + return $this->charSet; + } + + public function setCollectingTaskId($collectingTaskId) + { + $this->collectingTaskId = $collectingTaskId; + $this->apiParas["collecting_task_id"] = $collectingTaskId; + } + + public function getCollectingTaskId() + { + return $this->collectingTaskId; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setEntityType($entityType) + { + $this->entityType = $entityType; + $this->apiParas["entity_type"] = $entityType; + } + + public function getEntityType() + { + return $this->entityType; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setJsonData($jsonData) + { + $this->jsonData = $jsonData; + $this->apiParas["json_data"] = $jsonData; + } + + public function getJsonData() + { + return $this->jsonData; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.data.put"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php new file mode 100755 index 0000000..4934936 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php @@ -0,0 +1,182 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.contract.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php new file mode 100755 index 0000000..0e03549 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php @@ -0,0 +1,182 @@ +creditNo = $creditNo; + $this->apiParas["credit_no"] = $creditNo; + } + + public function getCreditNo() + { + return $this->creditNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.drawndnlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php new file mode 100755 index 0000000..dfed150 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.feerecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php new file mode 100755 index 0000000..3e99721 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.lendingrecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php new file mode 100755 index 0000000..1f90098 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php @@ -0,0 +1,182 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.paymentschedule.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php b/extend/alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php new file mode 100755 index 0000000..b5d0c8a --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.repaymentrecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcardEduPublicBindRequest.php b/extend/alipay/aop/request/AlipayEcardEduPublicBindRequest.php new file mode 100755 index 0000000..2361d5a --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcardEduPublicBindRequest.php @@ -0,0 +1,198 @@ +agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setAlipayUserId($alipayUserId) + { + $this->alipayUserId = $alipayUserId; + $this->apiParas["alipay_user_id"] = $alipayUserId; + } + + public function getAlipayUserId() + { + return $this->alipayUserId; + } + + public function setCardName($cardName) + { + $this->cardName = $cardName; + $this->apiParas["card_name"] = $cardName; + } + + public function getCardName() + { + return $this->cardName; + } + + public function setCardNo($cardNo) + { + $this->cardNo = $cardNo; + $this->apiParas["card_no"] = $cardNo; + } + + public function getCardNo() + { + return $this->cardNo; + } + + public function setPublicId($publicId) + { + $this->publicId = $publicId; + $this->apiParas["public_id"] = $publicId; + } + + public function getPublicId() + { + return $this->publicId; + } + + public function getApiMethodName() + { + return "alipay.ecard.edu.public.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php new file mode 100755 index 0000000..d34e083 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.basicservice.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php new file mode 100755 index 0000000..cf8eeef --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.basicservice.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php new file mode 100755 index 0000000..de05617 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.batch.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php new file mode 100755 index 0000000..78c64c0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php new file mode 100755 index 0000000..e7712c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php new file mode 100755 index 0000000..301ff6c --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php new file mode 100755 index 0000000..403b6d6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php new file mode 100755 index 0000000..0b37b74 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php new file mode 100755 index 0000000..c63f0e9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php new file mode 100755 index 0000000..c6ee983 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.details.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php new file mode 100755 index 0000000..c866b26 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php new file mode 100755 index 0000000..9eccc91 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.notice.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php new file mode 100755 index 0000000..fb50ce5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.notice.publish"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php new file mode 100755 index 0000000..1781883 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.repair.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php new file mode 100755 index 0000000..6ace275 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.residentinfo.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php new file mode 100755 index 0000000..6a2a1fe --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.residentinfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php new file mode 100755 index 0000000..f939efb --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php new file mode 100755 index 0000000..1a84501 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php new file mode 100755 index 0000000..601e772 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php new file mode 100755 index 0000000..d38bb79 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.rooominfo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php new file mode 100755 index 0000000..e6e2eef --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.useridentity.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php new file mode 100755 index 0000000..46b5274 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php new file mode 100755 index 0000000..53b3cb9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php new file mode 100755 index 0000000..2dd0460 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php new file mode 100755 index 0000000..a236da0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.schoolinfo.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php new file mode 100755 index 0000000..c982111 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.student.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php b/extend/alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php new file mode 100755 index 0000000..c45e42d --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.student.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php b/extend/alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php new file mode 100755 index 0000000..9d59567 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.carlib.info.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php b/extend/alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php new file mode 100755 index 0000000..e59e273 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.carmodel.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php b/extend/alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php new file mode 100755 index 0000000..38c7707 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.data.external.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php b/extend/alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php new file mode 100755 index 0000000..098ddf7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.data.external.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php b/extend/alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php new file mode 100755 index 0000000..a9e53b4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.dataservice.violationinfo.share"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php new file mode 100755 index 0000000..db27770 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.data.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php new file mode 100755 index 0000000..e3db819 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.order.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php new file mode 100755 index 0000000..7f51ef8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.orderstatus.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php b/extend/alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php new file mode 100755 index 0000000..fedaf47 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.order.status.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php new file mode 100755 index 0000000..b71a477 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.cardbarcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php new file mode 100755 index 0000000..751450d --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.config.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php new file mode 100755 index 0000000..dab75e8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.config.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php new file mode 100755 index 0000000..e73afe3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.enterinfo.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php new file mode 100755 index 0000000..f2a61c9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.exitinfo.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php new file mode 100755 index 0000000..bab3389 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.lotbarcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php new file mode 100755 index 0000000..91ce08d --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.order.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php new file mode 100755 index 0000000..29934cc --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.order.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php new file mode 100755 index 0000000..21e3d4f --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.orderstatus.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php new file mode 100755 index 0000000..f1ae7ee --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.parkinglotinfo.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php new file mode 100755 index 0000000..c2dfd82 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.parkinglotinfo.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php b/extend/alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php new file mode 100755 index 0000000..4e46c8c --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.vehicle.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php b/extend/alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php new file mode 100755 index 0000000..7f0d31f --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.ticket.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php b/extend/alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php new file mode 100755 index 0000000..6006b14 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.ticket.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php b/extend/alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php new file mode 100755 index 0000000..b00aac9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.voucher.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php b/extend/alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php new file mode 100755 index 0000000..0762b72 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.trade.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php b/extend/alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php new file mode 100755 index 0000000..e41a0cf --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.violation.city.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php b/extend/alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php new file mode 100755 index 0000000..a85497f --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.violation.info.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php b/extend/alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php new file mode 100755 index 0000000..3850003 --- /dev/null +++ b/extend/alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.welfare.code.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php b/extend/alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php new file mode 100755 index 0000000..1a8746d --- /dev/null +++ b/extend/alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.currentsign.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php b/extend/alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php new file mode 100755 index 0000000..cbf58f2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.firstfundinpour.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayExscUserFirstsignGetRequest.php b/extend/alipay/aop/request/AlipayExscUserFirstsignGetRequest.php new file mode 100755 index 0000000..8336bb0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayExscUserFirstsignGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.firstsign.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php b/extend/alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php new file mode 100755 index 0000000..bd3c1d2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php @@ -0,0 +1,150 @@ +outProductId = $outProductId; + $this->apiParas["out_product_id"] = $outProductId; + } + + public function getOutProductId() + { + return $this->outProductId; + } + + public function setPublicId($publicId) + { + $this->publicId = $publicId; + $this->apiParas["public_id"] = $publicId; + } + + public function getPublicId() + { + return $this->publicId; + } + + public function setStock($stock) + { + $this->stock = $stock; + $this->apiParas["stock"] = $stock; + } + + public function getStock() + { + return $this->stock; + } + + public function getApiMethodName() + { + return "alipay.flashsales.stock.sync.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundAuthOperationCancelRequest.php b/extend/alipay/aop/request/AlipayFundAuthOperationCancelRequest.php new file mode 100755 index 0000000..c2714a6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundAuthOperationCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.operation.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php b/extend/alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php new file mode 100755 index 0000000..25b2881 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.operation.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php b/extend/alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php new file mode 100755 index 0000000..525e1af --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.freeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php b/extend/alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php new file mode 100755 index 0000000..fc01a04 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.unfreeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php b/extend/alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php new file mode 100755 index 0000000..a9089c5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.voucher.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOperationQueryRequest.php b/extend/alipay/aop/request/AlipayFundCouponOperationQueryRequest.php new file mode 100755 index 0000000..a9c4077 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOperationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.operation.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php b/extend/alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php new file mode 100755 index 0000000..1de5043 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.agreement.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php b/extend/alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php new file mode 100755 index 0000000..d489b81 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.app.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php b/extend/alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php new file mode 100755 index 0000000..1241be8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.disburse"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php b/extend/alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php new file mode 100755 index 0000000..a33327d --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.page.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundCouponOrderRefundRequest.php b/extend/alipay/aop/request/AlipayFundCouponOrderRefundRequest.php new file mode 100755 index 0000000..5cabecb --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundCouponOrderRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundTransOrderQueryRequest.php b/extend/alipay/aop/request/AlipayFundTransOrderQueryRequest.php new file mode 100755 index 0000000..dbdde41 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundTransOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.trans.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayFundTransToaccountTransferRequest.php b/extend/alipay/aop/request/AlipayFundTransToaccountTransferRequest.php new file mode 100755 index 0000000..7380465 --- /dev/null +++ b/extend/alipay/aop/request/AlipayFundTransToaccountTransferRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.trans.toaccount.transfer"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayInsAutoCarSaveRequest.php b/extend/alipay/aop/request/AlipayInsAutoCarSaveRequest.php new file mode 100755 index 0000000..7c38f11 --- /dev/null +++ b/extend/alipay/aop/request/AlipayInsAutoCarSaveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.car.save"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php b/extend/alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php new file mode 100755 index 0000000..eb88981 --- /dev/null +++ b/extend/alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.application.issue.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php b/extend/alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php new file mode 100755 index 0000000..a0a9d3a --- /dev/null +++ b/extend/alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.coupon.receive"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayInsSceneCouponSendRequest.php b/extend/alipay/aop/request/AlipayInsSceneCouponSendRequest.php new file mode 100755 index 0000000..bcadcda --- /dev/null +++ b/extend/alipay/aop/request/AlipayInsSceneCouponSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.coupon.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php new file mode 100755 index 0000000..22f911e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.activity.offline.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php new file mode 100755 index 0000000..71f346d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.activity.offline.trigger"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php new file mode 100755 index 0000000..c11d121 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php new file mode 100755 index 0000000..ef38bf8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php new file mode 100755 index 0000000..e8af57f --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.list.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php new file mode 100755 index 0000000..d9f89ec --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.status.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php new file mode 100755 index 0000000..e9f63a3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.trigger"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php new file mode 100755 index 0000000..42647b4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cert.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php new file mode 100755 index 0000000..7ecac63 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.append"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php new file mode 100755 index 0000000..31ade2a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php new file mode 100755 index 0000000..820ac24 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php new file mode 100755 index 0000000..ee018de --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php new file mode 100755 index 0000000..abaec0c --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php new file mode 100755 index 0000000..2d2aea3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php new file mode 100755 index 0000000..dab6518 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.whitelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php new file mode 100755 index 0000000..a4fc44a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.whitelist.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php new file mode 100755 index 0000000..5fcb065 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php new file mode 100755 index 0000000..7efa6bc --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php new file mode 100755 index 0000000..3f970aa --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampTriggerRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampTriggerRequest.php new file mode 100755 index 0000000..1c10373 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampTriggerRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.trigger"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php new file mode 100755 index 0000000..738e0c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php new file mode 100755 index 0000000..175fa04 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.whitelist.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php new file mode 100755 index 0000000..3f363da --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.prize.amount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php new file mode 100755 index 0000000..ad8d649 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.activateform.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php b/extend/alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php new file mode 100755 index 0000000..df3edd6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.activateurl.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php new file mode 100755 index 0000000..53cec4c --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php b/extend/alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php new file mode 100755 index 0000000..e8dcc40 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php new file mode 100755 index 0000000..1f1d173 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php new file mode 100755 index 0000000..b8a2669 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php b/extend/alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php new file mode 100755 index 0000000..3041763 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.consume.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardDeleteRequest.php b/extend/alipay/aop/request/AlipayMarketingCardDeleteRequest.php new file mode 100755 index 0000000..b36715d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php b/extend/alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php new file mode 100755 index 0000000..352af67 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.formtemplate.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardOpenRequest.php b/extend/alipay/aop/request/AlipayMarketingCardOpenRequest.php new file mode 100755 index 0000000..c76a19f --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardOpenRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.open"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCardQueryRequest.php new file mode 100755 index 0000000..0e3f04f --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php new file mode 100755 index 0000000..3025cde --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php new file mode 100755 index 0000000..4089926 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php new file mode 100755 index 0000000..d1d930e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCardUpdateRequest.php b/extend/alipay/aop/request/AlipayMarketingCardUpdateRequest.php new file mode 100755 index 0000000..25f2151 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCardUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php new file mode 100755 index 0000000..14ae8ce --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashlessvoucher.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php new file mode 100755 index 0000000..d4d7895 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashlessvoucher.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php new file mode 100755 index 0000000..58471c8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashvoucher.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php new file mode 100755 index 0000000..bf9bd37 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashvoucher.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php new file mode 100755 index 0000000..8f6118f --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php new file mode 100755 index 0000000..986737e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php new file mode 100755 index 0000000..2492819 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php new file mode 100755 index 0000000..4b96272 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php new file mode 100755 index 0000000..3981e39 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php new file mode 100755 index 0000000..c2550aa --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.recommend.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php b/extend/alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php new file mode 100755 index 0000000..25ad233 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.exchangevoucher.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php b/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php new file mode 100755 index 0000000..d8b9fc3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.activity.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php new file mode 100755 index 0000000..ec9c0e3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php new file mode 100755 index 0000000..bbcb7a0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.editor.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php new file mode 100755 index 0000000..04f1e56 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.template.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php new file mode 100755 index 0000000..b01e222 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.userule.pid.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php new file mode 100755 index 0000000..ce96ad1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.auth.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php new file mode 100755 index 0000000..51372f2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php new file mode 100755 index 0000000..c5070d8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.list.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherSendRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherSendRequest.php new file mode 100755 index 0000000..9832b6d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php new file mode 100755 index 0000000..8c99d35 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.template.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php new file mode 100755 index 0000000..c475133 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.templatedetail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php b/extend/alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php new file mode 100755 index 0000000..6464d03 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.templatelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMdataTagGetRequest.php b/extend/alipay/aop/request/AlipayMdataTagGetRequest.php new file mode 100755 index 0000000..844de85 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMdataTagGetRequest.php @@ -0,0 +1,134 @@ +requiredTags = $requiredTags; + $this->apiParas["required_tags"] = $requiredTags; + } + + public function getRequiredTags() + { + return $this->requiredTags; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mdata.tag.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMemberCouponQuerylistRequest.php b/extend/alipay/aop/request/AlipayMemberCouponQuerylistRequest.php new file mode 100755 index 0000000..6c779e8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMemberCouponQuerylistRequest.php @@ -0,0 +1,198 @@ +merchantInfo = $merchantInfo; + $this->apiParas["merchant_info"] = $merchantInfo; + } + + public function getMerchantInfo() + { + return $this->merchantInfo; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setUserInfo($userInfo) + { + $this->userInfo = $userInfo; + $this->apiParas["user_info"] = $userInfo; + } + + public function getUserInfo() + { + return $this->userInfo; + } + + public function getApiMethodName() + { + return "alipay.member.coupon.querylist"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php new file mode 100755 index 0000000..dec3068 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php @@ -0,0 +1,182 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setAmount($amount) + { + $this->amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setReceiveUserId($receiveUserId) + { + $this->receiveUserId = $receiveUserId; + $this->apiParas["receive_user_id"] = $receiveUserId; + } + + public function getReceiveUserId() + { + return $this->receiveUserId; + } + + public function setTransferOutOrderNo($transferOutOrderNo) + { + $this->transferOutOrderNo = $transferOutOrderNo; + $this->apiParas["transfer_out_order_no"] = $transferOutOrderNo; + } + + public function getTransferOutOrderNo() + { + return $this->transferOutOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.confirmpayurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php new file mode 100755 index 0000000..3de387c --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php @@ -0,0 +1,182 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setAmount($amount) + { + $this->amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setReceiveUserId($receiveUserId) + { + $this->receiveUserId = $receiveUserId; + $this->apiParas["receive_user_id"] = $receiveUserId; + } + + public function getReceiveUserId() + { + return $this->receiveUserId; + } + + public function setTransferOutOrderNo($transferOutOrderNo) + { + $this->transferOutOrderNo = $transferOutOrderNo; + $this->apiParas["transfer_out_order_no"] = $transferOutOrderNo; + } + + public function getTransferOutOrderNo() + { + return $this->transferOutOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.direct.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderFreezeRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderFreezeRequest.php new file mode 100755 index 0000000..54b7a59 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderFreezeRequest.php @@ -0,0 +1,182 @@ +amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setExpireTime($expireTime) + { + $this->expireTime = $expireTime; + $this->apiParas["expire_time"] = $expireTime; + } + + public function getExpireTime() + { + return $this->expireTime; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setPayConfirm($payConfirm) + { + $this->payConfirm = $payConfirm; + $this->apiParas["pay_confirm"] = $payConfirm; + } + + public function getPayConfirm() + { + return $this->payConfirm; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.freeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php new file mode 100755 index 0000000..8b9a37a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php @@ -0,0 +1,118 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.freezepayurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderGetRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderGetRequest.php new file mode 100755 index 0000000..0dd56f7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderGetRequest.php @@ -0,0 +1,118 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php b/extend/alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php new file mode 100755 index 0000000..387972e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php @@ -0,0 +1,134 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.unfreeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php b/extend/alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php new file mode 100755 index 0000000..4e6d4f1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php b/extend/alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php new file mode 100755 index 0000000..c0b1918 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php b/extend/alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php new file mode 100755 index 0000000..c08ea5b --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php b/extend/alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php new file mode 100755 index 0000000..e04b665 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php b/extend/alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php new file mode 100755 index 0000000..1e7bdf8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.message.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php b/extend/alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php new file mode 100755 index 0000000..dc990cc --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php @@ -0,0 +1,150 @@ +deviceid = $deviceid; + $this->apiParas["deviceid"] = $deviceid; + } + + public function getDeviceid() + { + return $this->deviceid; + } + + public function setSource($source) + { + $this->source = $source; + $this->apiParas["source"] = $source; + } + + public function getSource() + { + return $this->source; + } + + public function setToken($token) + { + $this->token = $token; + $this->apiParas["token"] = $token; + } + + public function getToken() + { + return $this->token; + } + + public function getApiMethodName() + { + return "alipay.mobile.bksigntoken.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileCodeCreateRequest.php b/extend/alipay/aop/request/AlipayMobileCodeCreateRequest.php new file mode 100755 index 0000000..72af74d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileCodeCreateRequest.php @@ -0,0 +1,247 @@ +bizLinkedId = $bizLinkedId; + $this->apiParas["biz_linked_id"] = $bizLinkedId; + } + + public function getBizLinkedId() + { + return $this->bizLinkedId; + } + + public function setBizType($bizType) + { + $this->bizType = $bizType; + $this->apiParas["biz_type"] = $bizType; + } + + public function getBizType() + { + return $this->bizType; + } + + public function setContextStr($contextStr) + { + $this->contextStr = $contextStr; + $this->apiParas["context_str"] = $contextStr; + } + + public function getContextStr() + { + return $this->contextStr; + } + + public function setIsDirect($isDirect) + { + $this->isDirect = $isDirect; + $this->apiParas["is_direct"] = $isDirect; + } + + public function getIsDirect() + { + return $this->isDirect; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setSourceId($sourceId) + { + $this->sourceId = $sourceId; + $this->apiParas["source_id"] = $sourceId; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function setStartDate($startDate) + { + $this->startDate = $startDate; + $this->apiParas["start_date"] = $startDate; + } + + public function getStartDate() + { + return $this->startDate; + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + $this->apiParas["timeout"] = $timeout; + } + + public function getTimeout() + { + return $this->timeout; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mobile.code.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileCodeQueryRequest.php b/extend/alipay/aop/request/AlipayMobileCodeQueryRequest.php new file mode 100755 index 0000000..cf43c88 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileCodeQueryRequest.php @@ -0,0 +1,118 @@ +qrToken = $qrToken; + $this->apiParas["qr_token"] = $qrToken; + } + + public function getQrToken() + { + return $this->qrToken; + } + + public function getApiMethodName() + { + return "alipay.mobile.code.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicAccountAddRequest.php b/extend/alipay/aop/request/AlipayMobilePublicAccountAddRequest.php new file mode 100755 index 0000000..54beb2d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicAccountAddRequest.php @@ -0,0 +1,198 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBindAccountNo($bindAccountNo) + { + $this->bindAccountNo = $bindAccountNo; + $this->apiParas["bind_account_no"] = $bindAccountNo; + } + + public function getBindAccountNo() + { + return $this->bindAccountNo; + } + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function setDisplayName($displayName) + { + $this->displayName = $displayName; + $this->apiParas["display_name"] = $displayName; + } + + public function getDisplayName() + { + return $this->displayName; + } + + public function setFromUserId($fromUserId) + { + $this->fromUserId = $fromUserId; + $this->apiParas["from_user_id"] = $fromUserId; + } + + public function getFromUserId() + { + return $this->fromUserId; + } + + public function setRealName($realName) + { + $this->realName = $realName; + $this->apiParas["real_name"] = $realName; + } + + public function getRealName() + { + return $this->realName; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php b/extend/alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php new file mode 100755 index 0000000..2665830 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php new file mode 100755 index 0000000..78ed91e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicAccountResetRequest.php b/extend/alipay/aop/request/AlipayMobilePublicAccountResetRequest.php new file mode 100755 index 0000000..ae2b5e3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicAccountResetRequest.php @@ -0,0 +1,198 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBindAccountNo($bindAccountNo) + { + $this->bindAccountNo = $bindAccountNo; + $this->apiParas["bind_account_no"] = $bindAccountNo; + } + + public function getBindAccountNo() + { + return $this->bindAccountNo; + } + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function setDisplayName($displayName) + { + $this->displayName = $displayName; + $this->apiParas["display_name"] = $displayName; + } + + public function getDisplayName() + { + return $this->displayName; + } + + public function setFromUserId($fromUserId) + { + $this->fromUserId = $fromUserId; + $this->apiParas["from_user_id"] = $fromUserId; + } + + public function getFromUserId() + { + return $this->fromUserId; + } + + public function setRealName($realName) + { + $this->realName = $realName; + $this->apiParas["real_name"] = $realName; + } + + public function getRealName() + { + return $this->realName; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.reset"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php new file mode 100755 index 0000000..da59f20 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.appinfo.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php b/extend/alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php new file mode 100755 index 0000000..57d51a6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicFollowListRequest.php b/extend/alipay/aop/request/AlipayMobilePublicFollowListRequest.php new file mode 100755 index 0000000..d90ccc8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicFollowListRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.follow.list"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicGisGetRequest.php b/extend/alipay/aop/request/AlipayMobilePublicGisGetRequest.php new file mode 100755 index 0000000..3f8d69d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicGisGetRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.gis.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php b/extend/alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php new file mode 100755 index 0000000..8ec3226 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php @@ -0,0 +1,230 @@ +appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setAuthPic($authPic) + { + $this->authPic = $authPic; + $this->apiParas["auth_pic"] = $authPic; + } + + public function getAuthPic() + { + return $this->authPic; + } + + public function setLicenseUrl($licenseUrl) + { + $this->licenseUrl = $licenseUrl; + $this->apiParas["license_url"] = $licenseUrl; + } + + public function getLicenseUrl() + { + return $this->licenseUrl; + } + + public function setLogoUrl($logoUrl) + { + $this->logoUrl = $logoUrl; + $this->apiParas["logo_url"] = $logoUrl; + } + + public function getLogoUrl() + { + return $this->logoUrl; + } + + public function setPublicGreeting($publicGreeting) + { + $this->publicGreeting = $publicGreeting; + $this->apiParas["public_greeting"] = $publicGreeting; + } + + public function getPublicGreeting() + { + return $this->publicGreeting; + } + + public function setShopPic1($shopPic1) + { + $this->shopPic1 = $shopPic1; + $this->apiParas["shop_pic1"] = $shopPic1; + } + + public function getShopPic1() + { + return $this->shopPic1; + } + + public function setShopPic2($shopPic2) + { + $this->shopPic2 = $shopPic2; + $this->apiParas["shop_pic2"] = $shopPic2; + } + + public function getShopPic2() + { + return $this->shopPic2; + } + + public function setShopPic3($shopPic3) + { + $this->shopPic3 = $shopPic3; + $this->apiParas["shop_pic3"] = $shopPic3; + } + + public function getShopPic3() + { + return $this->shopPic3; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.info.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php new file mode 100755 index 0000000..23ef977 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelAddRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelAddRequest.php new file mode 100755 index 0000000..5789850 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php new file mode 100755 index 0000000..1664bc4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php new file mode 100755 index 0000000..d9af33c --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php new file mode 100755 index 0000000..2b30665 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php new file mode 100755 index 0000000..7ffb360 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php new file mode 100755 index 0000000..a622747 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php new file mode 100755 index 0000000..6086b4d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuAddRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuAddRequest.php new file mode 100755 index 0000000..e7ea16e --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php new file mode 100755 index 0000000..67b81fa --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuGetRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuGetRequest.php new file mode 100755 index 0000000..70500e7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php new file mode 100755 index 0000000..8abaded --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php new file mode 100755 index 0000000..a81a93d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php new file mode 100755 index 0000000..a2d9ded --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php new file mode 100755 index 0000000..6f8a061 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.user.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php new file mode 100755 index 0000000..0ab6477 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php new file mode 100755 index 0000000..289b7a3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.label.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessagePushRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessagePushRequest.php new file mode 100755 index 0000000..d1990c9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessagePushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php new file mode 100755 index 0000000..c4c5f9b --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.single.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php new file mode 100755 index 0000000..4ef7b0d --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.total.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php new file mode 100755 index 0000000..f519a17 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.messagebatch.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php new file mode 100755 index 0000000..c67d9ba --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.messagespecify.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicMockListsmlistApiRequest.php b/extend/alipay/aop/request/AlipayMobilePublicMockListsmlistApiRequest.php new file mode 100755 index 0000000..db209c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicMockListsmlistApiRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.mock.listsmlist.api"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php new file mode 100755 index 0000000..ac3f640 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php b/extend/alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php new file mode 100755 index 0000000..5a969a7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.shortlink.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicStdMockListsmlistApiRequest.php b/extend/alipay/aop/request/AlipayMobilePublicStdMockListsmlistApiRequest.php new file mode 100755 index 0000000..161f590 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicStdMockListsmlistApiRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.std.mock.listsmlist.api"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php new file mode 100755 index 0000000..f8b54d5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php @@ -0,0 +1,118 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php new file mode 100755 index 0000000..666bf5a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php @@ -0,0 +1,118 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php new file mode 100755 index 0000000..b5a5cef --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php @@ -0,0 +1,134 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function setTradeSetting($tradeSetting) + { + $this->tradeSetting = $tradeSetting; + $this->apiParas["trade_setting"] = $tradeSetting; + } + + public function getTradeSetting() + { + return $this->tradeSetting; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php new file mode 100755 index 0000000..b070d24 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php @@ -0,0 +1,134 @@ +template = $template; + $this->apiParas["template"] = $template; + } + + public function getTemplate() + { + return $this->template; + } + + public function setTemplateId($templateId) + { + $this->templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileRecommendGetRequest.php b/extend/alipay/aop/request/AlipayMobileRecommendGetRequest.php new file mode 100755 index 0000000..50af41b --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileRecommendGetRequest.php @@ -0,0 +1,182 @@ +extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setLimit($limit) + { + $this->limit = $limit; + $this->apiParas["limit"] = $limit; + } + + public function getLimit() + { + return $this->limit; + } + + public function setSceneId($sceneId) + { + $this->sceneId = $sceneId; + $this->apiParas["scene_id"] = $sceneId; + } + + public function getSceneId() + { + return $this->sceneId; + } + + public function setStartIdx($startIdx) + { + $this->startIdx = $startIdx; + $this->apiParas["start_idx"] = $startIdx; + } + + public function getStartIdx() + { + return $this->startIdx; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mobile.recommend.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileShakeUserQueryRequest.php b/extend/alipay/aop/request/AlipayMobileShakeUserQueryRequest.php new file mode 100755 index 0000000..46de40a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileShakeUserQueryRequest.php @@ -0,0 +1,137 @@ +dynamicId = $dynamicId; + $this->apiParas["dynamic_id"] = $dynamicId; + } + + public function getDynamicId() + { + return $this->dynamicId; + } + + public function setDynamicIdType($dynamicIdType) + { + $this->dynamicIdType = $dynamicIdType; + $this->apiParas["dynamic_id_type"] = $dynamicIdType; + } + + public function getDynamicIdType() + { + return $this->dynamicIdType; + } + + public function getApiMethodName() + { + return "alipay.mobile.shake.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php b/extend/alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php new file mode 100755 index 0000000..8b874d1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php b/extend/alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php new file mode 100755 index 0000000..3920904 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.express.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php b/extend/alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php new file mode 100755 index 0000000..07a1e60 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.follow.list"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php b/extend/alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php new file mode 100755 index 0000000..7f6ef19 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php b/extend/alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php new file mode 100755 index 0000000..1ac773b --- /dev/null +++ b/extend/alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php b/extend/alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php new file mode 100755 index 0000000..f85a934 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php @@ -0,0 +1,122 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mpointprod.benefit.detail.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php b/extend/alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php new file mode 100755 index 0000000..affaf0a --- /dev/null +++ b/extend/alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.msaas.mediarecog.voice.mediaaudio.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php b/extend/alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php new file mode 100755 index 0000000..7714a43 --- /dev/null +++ b/extend/alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.msaas.promotion.cpainfo.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php new file mode 100755 index 0000000..1386c5c --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.applyorder.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php new file mode 100755 index 0000000..ac460e73 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php new file mode 100755 index 0000000..5f063b3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketItemStateRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketItemStateRequest.php new file mode 100755 index 0000000..36e63ca --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketItemStateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.state"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketLeadsBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketLeadsBatchqueryRequest.php new file mode 100755 index 0000000..7f80932 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketLeadsBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.leads.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketLeadsQrcodeQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketLeadsQrcodeQueryRequest.php new file mode 100755 index 0000000..8a3b447 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketLeadsQrcodeQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.leads.qrcode.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php new file mode 100755 index 0000000..fa0875e --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.mcomment.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php new file mode 100755 index 0000000..22a74d6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.product.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php new file mode 100755 index 0000000..fcf9843 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.product.querydetail"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketReportGetRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketReportGetRequest.php new file mode 100755 index 0000000..745eaa6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketReportGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.report.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php new file mode 100755 index 0000000..9e4c7ed --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.reporterror.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php new file mode 100755 index 0000000..3df228c --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.applyorder.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php new file mode 100755 index 0000000..d426740 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php new file mode 100755 index 0000000..19e190b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.category.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php new file mode 100755 index 0000000..5844e9a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php new file mode 100755 index 0000000..9473eef --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.discount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php new file mode 100755 index 0000000..07ec00b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php new file mode 100755 index 0000000..15a4b39 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php @@ -0,0 +1,134 @@ +isAll = $isAll; + $this->apiParas["is_all"] = $isAll; + } + + public function getIsAll() + { + return $this->isAll; + } + + public function setShopIds($shopIds) + { + $this->shopIds = $shopIds; + $this->apiParas["shop_ids"] = $shopIds; + } + + public function getShopIds() + { + return $this->shopIds; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.public.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php new file mode 100755 index 0000000..05d5a7a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php @@ -0,0 +1,134 @@ +isAll = $isAll; + $this->apiParas["is_all"] = $isAll; + } + + public function getIsAll() + { + return $this->isAll; + } + + public function setShopIds($shopIds) + { + $this->shopIds = $shopIds; + $this->apiParas["shop_ids"] = $shopIds; + } + + public function getShopIds() + { + return $this->shopIds; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.public.unbind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php new file mode 100755 index 0000000..9c34b45 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.querydetail"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php new file mode 100755 index 0000000..2830bb9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.summary.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php new file mode 100755 index 0000000..146e474 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php @@ -0,0 +1,150 @@ +extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setFileContent($fileContent) + { + $this->fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.code.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php new file mode 100755 index 0000000..4f4660b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php new file mode 100755 index 0000000..ff35ccd --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php new file mode 100755 index 0000000..6cc87fe --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php new file mode 100755 index 0000000..1682814 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.status.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php new file mode 100755 index 0000000..c118853 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php b/extend/alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php new file mode 100755 index 0000000..d74b404 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php @@ -0,0 +1,118 @@ +imageIds = $imageIds; + $this->apiParas["image_ids"] = $imageIds; + } + + public function getImageIds() + { + return $this->imageIds; + } + + public function getApiMethodName() + { + return "alipay.offline.material.image.download"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMaterialImageModifyRequest.php b/extend/alipay/aop/request/AlipayOfflineMaterialImageModifyRequest.php new file mode 100755 index 0000000..698b02b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMaterialImageModifyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMaterialImageQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineMaterialImageQueryRequest.php new file mode 100755 index 0000000..5cc5a1f --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMaterialImageQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php b/extend/alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php new file mode 100755 index 0000000..5c7c11b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php @@ -0,0 +1,166 @@ +imageContent = $imageContent; + $this->apiParas["image_content"] = $imageContent; + } + + public function getImageContent() + { + return $this->imageContent; + } + + public function setImageName($imageName) + { + $this->imageName = $imageName; + $this->apiParas["image_name"] = $imageName; + } + + public function getImageName() + { + return $this->imageName; + } + + public function setImagePid($imagePid) + { + $this->imagePid = $imagePid; + $this->apiParas["image_pid"] = $imagePid; + } + + public function getImagePid() + { + return $this->imagePid; + } + + public function setImageType($imageType) + { + $this->imageType = $imageType; + $this->apiParas["image_type"] = $imageType; + } + + public function getImageType() + { + return $this->imageType; + } + + public function getApiMethodName() + { + return "alipay.offline.material.image.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php new file mode 100755 index 0000000..880d396 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.dish.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php new file mode 100755 index 0000000..77a0110 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.equipment.auth.querybypage"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php new file mode 100755 index 0000000..2944073 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.equipment.auth.remove"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php new file mode 100755 index 0000000..3ac0753 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.monitor.log.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php new file mode 100755 index 0000000..9922415 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.shopaction.record"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderStaffUpdateRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderStaffUpdateRequest.php new file mode 100755 index 0000000..1a27010 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderStaffUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.staff.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php b/extend/alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php new file mode 100755 index 0000000..8e52f07 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.useraction.record"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppCodetesttestRequest.php b/extend/alipay/aop/request/AlipayOpenAppCodetesttestRequest.php new file mode 100755 index 0000000..88dcc19 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppCodetesttestRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.codetesttest"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppPackagetestRequest.php b/extend/alipay/aop/request/AlipayOpenAppPackagetestRequest.php new file mode 100755 index 0000000..e2905b2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppPackagetestRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.packagetest"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php b/extend/alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php new file mode 100755 index 0000000..c7f59f9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppXwbtestBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenAppXwbtestBatchqueryRequest.php new file mode 100755 index 0000000..bc3a7de --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppXwbtestBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.xwbtest.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppXwbtestpreCreateRequest.php b/extend/alipay/aop/request/AlipayOpenAppXwbtestpreCreateRequest.php new file mode 100755 index 0000000..297f527 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppXwbtestpreCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.xwbtestpre.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php b/extend/alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php new file mode 100755 index 0000000..400e14d --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.yufanlingsanyaowu.yufalingsanyaowu.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php b/extend/alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php new file mode 100755 index 0000000..449881e --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.industry.platform.create.token"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php b/extend/alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php new file mode 100755 index 0000000..7c9fba6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.token.app.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenAuthTokenAppRequest.php b/extend/alipay/aop/request/AlipayOpenAuthTokenAppRequest.php new file mode 100755 index 0000000..9e768d9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenAuthTokenAppRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.token.app"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php new file mode 100755 index 0000000..6d031e5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php new file mode 100755 index 0000000..c7afd4a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php new file mode 100755 index 0000000..1ac384a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicAccountResetRequest.php b/extend/alipay/aop/request/AlipayOpenPublicAccountResetRequest.php new file mode 100755 index 0000000..da18654 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicAccountResetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.reset"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php new file mode 100755 index 0000000..b567c4f --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php new file mode 100755 index 0000000..6d4b21a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.default.extension.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php new file mode 100755 index 0000000..445ab76 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.follow.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGisQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGisQueryRequest.php new file mode 100755 index 0000000..d32addc --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGisQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.gis.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php new file mode 100755 index 0000000..bd1c0a6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php new file mode 100755 index 0000000..a23ec05 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php new file mode 100755 index 0000000..4a3960a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.crowd.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php new file mode 100755 index 0000000..32bd797 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php new file mode 100755 index 0000000..7a7b459 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php new file mode 100755 index 0000000..8a6f0b5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.info.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php new file mode 100755 index 0000000..73adba0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php new file mode 100755 index 0000000..43ed51b --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php new file mode 100755 index 0000000..d9b8307 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php new file mode 100755 index 0000000..c114c4a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php new file mode 100755 index 0000000..15dea91 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php new file mode 100755 index 0000000..6b9e6d5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php new file mode 100755 index 0000000..df8349e --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php new file mode 100755 index 0000000..9b2282e --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php new file mode 100755 index 0000000..faa8981 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php new file mode 100755 index 0000000..2ef4db8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php @@ -0,0 +1,247 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setCatagoryId($catagoryId) + { + $this->catagoryId = $catagoryId; + $this->apiParas["catagory_id"] = $catagoryId; + } + + public function getCatagoryId() + { + return $this->catagoryId; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setContent($content) + { + $this->content = $content; + $this->apiParas["content"] = $content; + } + + public function getContent() + { + return $this->content; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.account.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php new file mode 100755 index 0000000..ed4600c --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php @@ -0,0 +1,376 @@ +商家经营类目 中的“经营类目编码” + **/ + private $mccCode; + + /** + * 外部入驻申请单据号,由开发者生成,并需保证在开发者端不重复。另,如果代创建被驳回,需更换新的申请号,原申请号不能再次使用 + **/ + private $outBizNo; + + /** + * 自有知识产权证书图片 + **/ + private $ownIntellectualPic; + + /** + * 生活号简介 + **/ + private $publicDesc; + + /** + * 生活号名称 + **/ + private $publicName; + + /** + * 店铺内景图片,个人账户必填 ,企业账户选填 + **/ + private $shopScenePic; + + /** + * 店铺门头照图片,个人账户必填,企业账户选填 + **/ + private $shopSignBoardPic; + + /** + * 企业特殊资质图片,可参考 商家经营类目 中的 “需要的特殊资质证书” + **/ + private $specialLicensePic; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setAccount($account) + { + $this->account = $account; + $this->apiParas["account"] = $account; + } + + public function getAccount() + { + return $this->account; + } + + public function setBackgroundPic($backgroundPic) + { + $this->backgroundPic = $backgroundPic; + $this->apiParas["background_pic"] = $backgroundPic; + } + + public function getBackgroundPic() + { + return $this->backgroundPic; + } + + public function setBusinessLicenseAuthPic($businessLicenseAuthPic) + { + $this->businessLicenseAuthPic = $businessLicenseAuthPic; + $this->apiParas["business_license_auth_pic"] = $businessLicenseAuthPic; + } + + public function getBusinessLicenseAuthPic() + { + return $this->businessLicenseAuthPic; + } + + public function setBusinessLicenseNo($businessLicenseNo) + { + $this->businessLicenseNo = $businessLicenseNo; + $this->apiParas["business_license_no"] = $businessLicenseNo; + } + + public function getBusinessLicenseNo() + { + return $this->businessLicenseNo; + } + + public function setBusinessLicensePic($businessLicensePic) + { + $this->businessLicensePic = $businessLicensePic; + $this->apiParas["business_license_pic"] = $businessLicensePic; + } + + public function getBusinessLicensePic() + { + return $this->businessLicensePic; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactMobile($contactMobile) + { + $this->contactMobile = $contactMobile; + $this->apiParas["contact_mobile"] = $contactMobile; + } + + public function getContactMobile() + { + return $this->contactMobile; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setLogoPic($logoPic) + { + $this->logoPic = $logoPic; + $this->apiParas["logo_pic"] = $logoPic; + } + + public function getLogoPic() + { + return $this->logoPic; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setOutBizNo($outBizNo) + { + $this->outBizNo = $outBizNo; + $this->apiParas["out_biz_no"] = $outBizNo; + } + + public function getOutBizNo() + { + return $this->outBizNo; + } + + public function setOwnIntellectualPic($ownIntellectualPic) + { + $this->ownIntellectualPic = $ownIntellectualPic; + $this->apiParas["own_intellectual_pic"] = $ownIntellectualPic; + } + + public function getOwnIntellectualPic() + { + return $this->ownIntellectualPic; + } + + public function setPublicDesc($publicDesc) + { + $this->publicDesc = $publicDesc; + $this->apiParas["public_desc"] = $publicDesc; + } + + public function getPublicDesc() + { + return $this->publicDesc; + } + + public function setPublicName($publicName) + { + $this->publicName = $publicName; + $this->apiParas["public_name"] = $publicName; + } + + public function getPublicName() + { + return $this->publicName; + } + + public function setShopScenePic($shopScenePic) + { + $this->shopScenePic = $shopScenePic; + $this->apiParas["shop_scene_pic"] = $shopScenePic; + } + + public function getShopScenePic() + { + return $this->shopScenePic; + } + + public function setShopSignBoardPic($shopSignBoardPic) + { + $this->shopSignBoardPic = $shopSignBoardPic; + $this->apiParas["shop_sign_board_pic"] = $shopSignBoardPic; + } + + public function getShopSignBoardPic() + { + return $this->shopSignBoardPic; + } + + public function setSpecialLicensePic($specialLicensePic) + { + $this->specialLicensePic = $specialLicensePic; + $this->apiParas["special_license_pic"] = $specialLicensePic; + } + + public function getSpecialLicensePic() + { + return $this->specialLicensePic; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.agent.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php new file mode 100755 index 0000000..ab6cfc9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.agentcreate.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php new file mode 100755 index 0000000..4469311 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php @@ -0,0 +1,310 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setDescription($description) + { + $this->description = $description; + $this->apiParas["description"] = $description; + } + + public function getDescription() + { + return $this->description; + } + + public function setExtendData($extendData) + { + $this->extendData = $extendData; + $this->apiParas["extend_data"] = $extendData; + } + + public function getExtendData() + { + return $this->extendData; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setPublicBizType($publicBizType) + { + $this->publicBizType = $publicBizType; + $this->apiParas["public_biz_type"] = $publicBizType; + } + + public function getPublicBizType() + { + return $this->publicBizType; + } + + public function setShowStyle($showStyle) + { + $this->showStyle = $showStyle; + $this->apiParas["show_style"] = $showStyle; + } + + public function getShowStyle() + { + return $this->showStyle; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php new file mode 100755 index 0000000..9b45e77 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php new file mode 100755 index 0000000..200d71d --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php new file mode 100755 index 0000000..f46ee38 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php new file mode 100755 index 0000000..09449b4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php new file mode 100755 index 0000000..3fc71b0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php new file mode 100755 index 0000000..9fd56e3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php @@ -0,0 +1,262 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setDescription($description) + { + $this->description = $description; + $this->apiParas["description"] = $description; + } + + public function getDescription() + { + return $this->description; + } + + public function setExtendData($extendData) + { + $this->extendData = $extendData; + $this->apiParas["extend_data"] = $extendData; + } + + public function getExtendData() + { + return $this->extendData; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php new file mode 100755 index 0000000..887dd70 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.msg.recall"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php new file mode 100755 index 0000000..e41265c --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php @@ -0,0 +1,337 @@ +category = $category; + $this->apiParas["category"] = $category; + } + + public function getCategory() + { + return $this->category; + } + + public function setContent($content) + { + $this->content = $content; + $this->apiParas["content"] = $content; + } + + public function getContent() + { + return $this->content; + } + + public function setCover($cover) + { + $this->cover = $cover; + $this->apiParas["cover"] = $cover; + } + + public function getCover() + { + return $this->cover; + } + + public function setDesc($desc) + { + $this->desc = $desc; + $this->apiParas["desc"] = $desc; + } + + public function getDesc() + { + return $this->desc; + } + + public function setMsgType($msgType) + { + $this->msgType = $msgType; + $this->apiParas["msg_type"] = $msgType; + } + + public function getMsgType() + { + return $this->msgType; + } + + public function setSourceExtInfo($sourceExtInfo) + { + $this->sourceExtInfo = $sourceExtInfo; + $this->apiParas["source_ext_info"] = $sourceExtInfo; + } + + public function getSourceExtInfo() + { + return $this->sourceExtInfo; + } + + public function setTitle($title) + { + $this->title = $title; + $this->apiParas["title"] = $title; + } + + public function getTitle() + { + return $this->title; + } + + public function setUniqueMsgId($uniqueMsgId) + { + $this->uniqueMsgId = $uniqueMsgId; + $this->apiParas["unique_msg_id"] = $uniqueMsgId; + } + + public function getUniqueMsgId() + { + return $this->uniqueMsgId; + } + + public function setVideoLength($videoLength) + { + $this->videoLength = $videoLength; + $this->apiParas["video_length"] = $videoLength; + } + + public function getVideoLength() + { + return $this->videoLength; + } + + public function setVideoSamples($videoSamples) + { + $this->videoSamples = $videoSamples; + $this->apiParas["video_samples"] = $videoSamples; + } + + public function getVideoSamples() + { + return $this->videoSamples; + } + + public function setVideoSize($videoSize) + { + $this->videoSize = $videoSize; + $this->apiParas["video_size"] = $videoSize; + } + + public function getVideoSize() + { + return $this->videoSize; + } + + public function setVideoSource($videoSource) + { + $this->videoSource = $videoSource; + $this->apiParas["video_source"] = $videoSource; + } + + public function getVideoSource() + { + return $this->videoSource; + } + + public function setVideoTemporaryUrl($videoTemporaryUrl) + { + $this->videoTemporaryUrl = $videoTemporaryUrl; + $this->apiParas["video_temporary_url"] = $videoTemporaryUrl; + } + + public function getVideoTemporaryUrl() + { + return $this->videoTemporaryUrl; + } + + public function setVideoUrl($videoUrl) + { + $this->videoUrl = $videoUrl; + $this->apiParas["video_url"] = $videoUrl; + } + + public function getVideoUrl() + { + return $this->videoUrl; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.msg.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php new file mode 100755 index 0000000..a5a6db8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.matchuser.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php new file mode 100755 index 0000000..5b36bc7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.matchuser.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php new file mode 100755 index 0000000..7ada742 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php new file mode 100755 index 0000000..b74560c --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.menu.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php new file mode 100755 index 0000000..c09f0de --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.menu.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php new file mode 100755 index 0000000..ab5c002 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php new file mode 100755 index 0000000..4fcab75 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php new file mode 100755 index 0000000..94f0e42 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.group.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php new file mode 100755 index 0000000..2b19d5e --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.label.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php new file mode 100755 index 0000000..fb04467 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.single.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php new file mode 100755 index 0000000..bcf5ca1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.total.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php new file mode 100755 index 0000000..bee43d6 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php new file mode 100755 index 0000000..14afbb8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.menu.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php new file mode 100755 index 0000000..5a88def --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.menu.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php new file mode 100755 index 0000000..0652dfc --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.subscribe.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php new file mode 100755 index 0000000..3d5094d --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php new file mode 100755 index 0000000..f71b701 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php new file mode 100755 index 0000000..28730d4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php new file mode 100755 index 0000000..ccd39bd --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php new file mode 100755 index 0000000..b164c0f --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.menu.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php new file mode 100755 index 0000000..066cd4a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.menu.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php new file mode 100755 index 0000000..731501d --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php b/extend/alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php new file mode 100755 index 0000000..0949868 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.shortlink.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php b/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php new file mode 100755 index 0000000..8e71683 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.template.message.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php b/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php new file mode 100755 index 0000000..84efd92 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.template.message.industry.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php b/extend/alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php new file mode 100755 index 0000000..96750fe --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.third.customer.service"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php new file mode 100755 index 0000000..76b75d3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.commodity.shop.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php new file mode 100755 index 0000000..d78725d --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.commodity.shop.online"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php new file mode 100755 index 0000000..9d416a4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.accept"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php new file mode 100755 index 0000000..3e68c24 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php new file mode 100755 index 0000000..a2ff7b8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.complete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php new file mode 100755 index 0000000..2079676 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php new file mode 100755 index 0000000..df0a336 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php new file mode 100755 index 0000000..d7c0d59 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php b/extend/alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php new file mode 100755 index 0000000..2da669a --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.reject"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOpenWangyanTestDeleteRequest.php b/extend/alipay/aop/request/AlipayOpenWangyanTestDeleteRequest.php new file mode 100755 index 0000000..5c762c3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOpenWangyanTestDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.wangyan.test.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayOperatorMobileBindRequest.php b/extend/alipay/aop/request/AlipayOperatorMobileBindRequest.php new file mode 100755 index 0000000..710d7e9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayOperatorMobileBindRequest.php @@ -0,0 +1,202 @@ +checkSigncard = $checkSigncard; + $this->apiParas["check_signcard"] = $checkSigncard; + } + + public function getCheckSigncard() + { + return $this->checkSigncard; + } + + public function setfReturnUrl($fReturnUrl) + { + $this->fReturnUrl = $fReturnUrl; + $this->apiParas["f_return_url"] = $fReturnUrl; + } + + public function getfReturnUrl() + { + return $this->fReturnUrl; + } + + public function setHasSpi($hasSpi) + { + $this->hasSpi = $hasSpi; + $this->apiParas["has_spi"] = $hasSpi; + } + + public function getHasSpi() + { + return $this->hasSpi; + } + + public function setOperatorName($operatorName) + { + $this->operatorName = $operatorName; + $this->apiParas["operator_name"] = $operatorName; + } + + public function getOperatorName() + { + return $this->operatorName; + } + + public function setProvinceName($provinceName) + { + $this->provinceName = $provinceName; + $this->apiParas["province_name"] = $provinceName; + } + + public function getProvinceName() + { + return $this->provinceName; + } + + public function setsReturnUrl($sReturnUrl) + { + $this->sReturnUrl = $sReturnUrl; + $this->apiParas["s_return_url"] = $sReturnUrl; + } + + public function getsReturnUrl() + { + return $this->sReturnUrl; + } + + public function getApiMethodName() + { + return "alipay.operator.mobile.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassCodeAddRequest.php b/extend/alipay/aop/request/AlipayPassCodeAddRequest.php new file mode 100755 index 0000000..6aef681 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassCodeAddRequest.php @@ -0,0 +1,170 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setRecognitionInfo($recognitionInfo) + { + $this->recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.code.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassCodeVerifyRequest.php b/extend/alipay/aop/request/AlipayPassCodeVerifyRequest.php new file mode 100755 index 0000000..af44151 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassCodeVerifyRequest.php @@ -0,0 +1,170 @@ +extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function getApiMethodName() + { + return "alipay.pass.code.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassFileAddRequest.php b/extend/alipay/aop/request/AlipayPassFileAddRequest.php new file mode 100755 index 0000000..2d1a7f4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassFileAddRequest.php @@ -0,0 +1,153 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setRecognitionInfo($recognitionInfo) + { + $this->recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function getApiMethodName() + { + return "alipay.pass.file.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassInstanceAddRequest.php b/extend/alipay/aop/request/AlipayPassInstanceAddRequest.php new file mode 100755 index 0000000..747a893 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassInstanceAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.instance.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassInstanceUpdateRequest.php b/extend/alipay/aop/request/AlipayPassInstanceUpdateRequest.php new file mode 100755 index 0000000..a99f11c --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassInstanceUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.instance.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassSyncAddRequest.php b/extend/alipay/aop/request/AlipayPassSyncAddRequest.php new file mode 100755 index 0000000..e264983 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassSyncAddRequest.php @@ -0,0 +1,166 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.pass.sync.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassSyncUpdateRequest.php b/extend/alipay/aop/request/AlipayPassSyncUpdateRequest.php new file mode 100755 index 0000000..21ac877 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassSyncUpdateRequest.php @@ -0,0 +1,214 @@ +channelId = $channelId; + $this->apiParas["channel_id"] = $channelId; + } + + public function getChannelId() + { + return $this->channelId; + } + + public function setExtInfo($extInfo) + { + $this->extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setPass($pass) + { + $this->pass = $pass; + $this->apiParas["pass"] = $pass; + } + + public function getPass() + { + return $this->pass; + } + + public function setSerialNumber($serialNumber) + { + $this->serialNumber = $serialNumber; + $this->apiParas["serial_number"] = $serialNumber; + } + + public function getSerialNumber() + { + return $this->serialNumber; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.sync.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTemplateAddRequest.php b/extend/alipay/aop/request/AlipayPassTemplateAddRequest.php new file mode 100755 index 0000000..ef29e0c --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTemplateAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.template.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTemplateUpdateRequest.php b/extend/alipay/aop/request/AlipayPassTemplateUpdateRequest.php new file mode 100755 index 0000000..060af42 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTemplateUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.template.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTplAddRequest.php b/extend/alipay/aop/request/AlipayPassTplAddRequest.php new file mode 100755 index 0000000..e53f024 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTplAddRequest.php @@ -0,0 +1,135 @@ +tplContent = $tplContent; + $this->apiParas["tpl_content"] = $tplContent; + } + + public function getTplContent() + { + return $this->tplContent; + } + + public function setUniqueId($uniqueId) + { + $this->uniqueId = $uniqueId; + $this->apiParas["unique_id"] = $uniqueId; + } + + public function getUniqueId() + { + return $this->uniqueId; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTplContentAddRequest.php b/extend/alipay/aop/request/AlipayPassTplContentAddRequest.php new file mode 100755 index 0000000..1d0bf8f --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTplContentAddRequest.php @@ -0,0 +1,169 @@ +recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function setTplId($tplId) + { + $this->tplId = $tplId; + $this->apiParas["tpl_id"] = $tplId; + } + + public function getTplId() + { + return $this->tplId; + } + + public function setTplParams($tplParams) + { + $this->tplParams = $tplParams; + $this->apiParas["tpl_params"] = $tplParams; + } + + public function getTplParams() + { + return $this->tplParams; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.content.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTplContentUpdateRequest.php b/extend/alipay/aop/request/AlipayPassTplContentUpdateRequest.php new file mode 100755 index 0000000..47c550b --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTplContentUpdateRequest.php @@ -0,0 +1,198 @@ +channelId = $channelId; + $this->apiParas["channel_id"] = $channelId; + } + + public function getChannelId() + { + return $this->channelId; + } + + public function setSerialNumber($serialNumber) + { + $this->serialNumber = $serialNumber; + $this->apiParas["serial_number"] = $serialNumber; + } + + public function getSerialNumber() + { + return $this->serialNumber; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setTplParams($tplParams) + { + $this->tplParams = $tplParams; + $this->apiParas["tpl_params"] = $tplParams; + } + + public function getTplParams() + { + return $this->tplParams; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.content.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassTplUpdateRequest.php b/extend/alipay/aop/request/AlipayPassTplUpdateRequest.php new file mode 100755 index 0000000..12008aa --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassTplUpdateRequest.php @@ -0,0 +1,134 @@ +tplContent = $tplContent; + $this->apiParas["tpl_content"] = $tplContent; + } + + public function getTplContent() + { + return $this->tplContent; + } + + public function setTplId($tplId) + { + $this->tplId = $tplId; + $this->apiParas["tpl_id"] = $tplId; + } + + public function getTplId() + { + return $this->tplId; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPassVerifyQueryRequest.php b/extend/alipay/aop/request/AlipayPassVerifyQueryRequest.php new file mode 100755 index 0000000..64e88eb --- /dev/null +++ b/extend/alipay/aop/request/AlipayPassVerifyQueryRequest.php @@ -0,0 +1,118 @@ +verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function getApiMethodName() + { + return "alipay.pass.verify.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php b/extend/alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php new file mode 100755 index 0000000..c853b28 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.huabei.promo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php b/extend/alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php new file mode 100755 index 0000000..9a0005f --- /dev/null +++ b/extend/alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.loan.apply.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php b/extend/alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php new file mode 100755 index 0000000..14cf2ad --- /dev/null +++ b/extend/alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.loan.refund.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPlatformOpenidGetRequest.php b/extend/alipay/aop/request/AlipayPlatformOpenidGetRequest.php new file mode 100755 index 0000000..d516807 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPlatformOpenidGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.platform.openid.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPlatformUseridGetRequest.php b/extend/alipay/aop/request/AlipayPlatformUseridGetRequest.php new file mode 100755 index 0000000..375c6bc --- /dev/null +++ b/extend/alipay/aop/request/AlipayPlatformUseridGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.platform.userid.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPointBalanceGetRequest.php b/extend/alipay/aop/request/AlipayPointBalanceGetRequest.php new file mode 100755 index 0000000..f52ee38 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPointBalanceGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPointBudgetGetRequest.php b/extend/alipay/aop/request/AlipayPointBudgetGetRequest.php new file mode 100755 index 0000000..9020ebf --- /dev/null +++ b/extend/alipay/aop/request/AlipayPointBudgetGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPointOrderAddRequest.php b/extend/alipay/aop/request/AlipayPointOrderAddRequest.php new file mode 100755 index 0000000..397cb82 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPointOrderAddRequest.php @@ -0,0 +1,198 @@ +memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderTime($orderTime) + { + $this->orderTime = $orderTime; + $this->apiParas["order_time"] = $orderTime; + } + + public function getOrderTime() + { + return $this->orderTime; + } + + public function setPointCount($pointCount) + { + $this->pointCount = $pointCount; + $this->apiParas["point_count"] = $pointCount; + } + + public function getPointCount() + { + return $this->pointCount; + } + + public function setUserSymbol($userSymbol) + { + $this->userSymbol = $userSymbol; + $this->apiParas["user_symbol"] = $userSymbol; + } + + public function getUserSymbol() + { + return $this->userSymbol; + } + + public function setUserSymbolType($userSymbolType) + { + $this->userSymbolType = $userSymbolType; + $this->apiParas["user_symbol_type"] = $userSymbolType; + } + + public function getUserSymbolType() + { + return $this->userSymbolType; + } + + public function getApiMethodName() + { + return "alipay.point.order.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPointOrderGetRequest.php b/extend/alipay/aop/request/AlipayPointOrderGetRequest.php new file mode 100755 index 0000000..3cae954 --- /dev/null +++ b/extend/alipay/aop/request/AlipayPointOrderGetRequest.php @@ -0,0 +1,150 @@ +merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setUserSymbol($userSymbol) + { + $this->userSymbol = $userSymbol; + $this->apiParas["user_symbol"] = $userSymbol; + } + + public function getUserSymbol() + { + return $this->userSymbol; + } + + public function setUserSymbolType($userSymbolType) + { + $this->userSymbolType = $userSymbolType; + $this->apiParas["user_symbol_type"] = $userSymbolType; + } + + public function getUserSymbolType() + { + return $this->userSymbolType; + } + + public function getApiMethodName() + { + return "alipay.point.order.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php b/extend/alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php new file mode 100755 index 0000000..5925ffa --- /dev/null +++ b/extend/alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php @@ -0,0 +1,150 @@ +bizId = $bizId; + $this->apiParas["biz_id"] = $bizId; + } + + public function getBizId() + { + return $this->bizId; + } + + public function setRuleUuid($ruleUuid) + { + $this->ruleUuid = $ruleUuid; + $this->apiParas["rule_uuid"] = $ruleUuid; + } + + public function getRuleUuid() + { + return $this->ruleUuid; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.promorulecenter.rule.analyze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php b/extend/alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php new file mode 100755 index 0000000..35cddcd --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php @@ -0,0 +1,470 @@ +envClientBaseBand = $envClientBaseBand; + $this->apiParas["env_client_base_band"] = $envClientBaseBand; + } + + public function getEnvClientBaseBand() + { + return $this->envClientBaseBand; + } + + public function setEnvClientBaseStation($envClientBaseStation) + { + $this->envClientBaseStation = $envClientBaseStation; + $this->apiParas["env_client_base_station"] = $envClientBaseStation; + } + + public function getEnvClientBaseStation() + { + return $this->envClientBaseStation; + } + + public function setEnvClientCoordinates($envClientCoordinates) + { + $this->envClientCoordinates = $envClientCoordinates; + $this->apiParas["env_client_coordinates"] = $envClientCoordinates; + } + + public function getEnvClientCoordinates() + { + return $this->envClientCoordinates; + } + + public function setEnvClientImei($envClientImei) + { + $this->envClientImei = $envClientImei; + $this->apiParas["env_client_imei"] = $envClientImei; + } + + public function getEnvClientImei() + { + return $this->envClientImei; + } + + public function setEnvClientImsi($envClientImsi) + { + $this->envClientImsi = $envClientImsi; + $this->apiParas["env_client_imsi"] = $envClientImsi; + } + + public function getEnvClientImsi() + { + return $this->envClientImsi; + } + + public function setEnvClientIosUdid($envClientIosUdid) + { + $this->envClientIosUdid = $envClientIosUdid; + $this->apiParas["env_client_ios_udid"] = $envClientIosUdid; + } + + public function getEnvClientIosUdid() + { + return $this->envClientIosUdid; + } + + public function setEnvClientIp($envClientIp) + { + $this->envClientIp = $envClientIp; + $this->apiParas["env_client_ip"] = $envClientIp; + } + + public function getEnvClientIp() + { + return $this->envClientIp; + } + + public function setEnvClientMac($envClientMac) + { + $this->envClientMac = $envClientMac; + $this->apiParas["env_client_mac"] = $envClientMac; + } + + public function getEnvClientMac() + { + return $this->envClientMac; + } + + public function setEnvClientScreen($envClientScreen) + { + $this->envClientScreen = $envClientScreen; + $this->apiParas["env_client_screen"] = $envClientScreen; + } + + public function getEnvClientScreen() + { + return $this->envClientScreen; + } + + public function setEnvClientUuid($envClientUuid) + { + $this->envClientUuid = $envClientUuid; + $this->apiParas["env_client_uuid"] = $envClientUuid; + } + + public function getEnvClientUuid() + { + return $this->envClientUuid; + } + + public function setJsTokenId($jsTokenId) + { + $this->jsTokenId = $jsTokenId; + $this->apiParas["js_token_id"] = $jsTokenId; + } + + public function getJsTokenId() + { + return $this->jsTokenId; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function setUserAccountNo($userAccountNo) + { + $this->userAccountNo = $userAccountNo; + $this->apiParas["user_account_no"] = $userAccountNo; + } + + public function getUserAccountNo() + { + return $this->userAccountNo; + } + + public function setUserBindBankcard($userBindBankcard) + { + $this->userBindBankcard = $userBindBankcard; + $this->apiParas["user_bind_bankcard"] = $userBindBankcard; + } + + public function getUserBindBankcard() + { + return $this->userBindBankcard; + } + + public function setUserBindBankcardType($userBindBankcardType) + { + $this->userBindBankcardType = $userBindBankcardType; + $this->apiParas["user_bind_bankcard_type"] = $userBindBankcardType; + } + + public function getUserBindBankcardType() + { + return $this->userBindBankcardType; + } + + public function setUserBindMobile($userBindMobile) + { + $this->userBindMobile = $userBindMobile; + $this->apiParas["user_bind_mobile"] = $userBindMobile; + } + + public function getUserBindMobile() + { + return $this->userBindMobile; + } + + public function setUserIdentityType($userIdentityType) + { + $this->userIdentityType = $userIdentityType; + $this->apiParas["user_identity_type"] = $userIdentityType; + } + + public function getUserIdentityType() + { + return $this->userIdentityType; + } + + public function setUserRealName($userRealName) + { + $this->userRealName = $userRealName; + $this->apiParas["user_real_name"] = $userRealName; + } + + public function getUserRealName() + { + return $this->userRealName; + } + + public function setUserRegDate($userRegDate) + { + $this->userRegDate = $userRegDate; + $this->apiParas["user_reg_date"] = $userRegDate; + } + + public function getUserRegDate() + { + return $this->userRegDate; + } + + public function setUserRegEmail($userRegEmail) + { + $this->userRegEmail = $userRegEmail; + $this->apiParas["user_reg_email"] = $userRegEmail; + } + + public function getUserRegEmail() + { + return $this->userRegEmail; + } + + public function setUserRegMobile($userRegMobile) + { + $this->userRegMobile = $userRegMobile; + $this->apiParas["user_reg_mobile"] = $userRegMobile; + } + + public function getUserRegMobile() + { + return $this->userRegMobile; + } + + public function setUserrIdentityNo($userrIdentityNo) + { + $this->userrIdentityNo = $userrIdentityNo; + $this->apiParas["userr_identity_no"] = $userrIdentityNo; + } + + public function getUserrIdentityNo() + { + return $this->userrIdentityNo; + } + + public function getApiMethodName() + { + return "alipay.security.info.analysis"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php b/extend/alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php new file mode 100755 index 0000000..1df0f4d --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.alipay.security.prod.test"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php b/extend/alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php new file mode 100755 index 0000000..e75b215 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.amlrisk.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php new file mode 100755 index 0000000..6626644 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.facerepo.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php new file mode 100755 index 0000000..ea64449 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.facerepo.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php new file mode 100755 index 0000000..99469d2 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.apply.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php new file mode 100755 index 0000000..c2b29e5 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php new file mode 100755 index 0000000..dc86d49 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php new file mode 100755 index 0000000..33ef319 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.verify.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php b/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php new file mode 100755 index 0000000..0f25c7b --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php b/extend/alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php new file mode 100755 index 0000000..7b521ed --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php @@ -0,0 +1,134 @@ +bizProduct = $bizProduct; + $this->apiParas["biz_product"] = $bizProduct; + } + + public function getBizProduct() + { + return $this->bizProduct; + } + + public function setFileContent($fileContent) + { + $this->fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.file.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php new file mode 100755 index 0000000..0288cf1 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php new file mode 100755 index 0000000..ce8d159 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php new file mode 100755 index 0000000..15cccab --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityRiskDetectRequest.php b/extend/alipay/aop/request/AlipaySecurityRiskDetectRequest.php new file mode 100755 index 0000000..941f766 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityRiskDetectRequest.php @@ -0,0 +1,998 @@ +buyerAccountNo = $buyerAccountNo; + $this->apiParas["buyer_account_no"] = $buyerAccountNo; + } + + public function getBuyerAccountNo() + { + return $this->buyerAccountNo; + } + + public function setBuyerBindBankcard($buyerBindBankcard) + { + $this->buyerBindBankcard = $buyerBindBankcard; + $this->apiParas["buyer_bind_bankcard"] = $buyerBindBankcard; + } + + public function getBuyerBindBankcard() + { + return $this->buyerBindBankcard; + } + + public function setBuyerBindBankcardType($buyerBindBankcardType) + { + $this->buyerBindBankcardType = $buyerBindBankcardType; + $this->apiParas["buyer_bind_bankcard_type"] = $buyerBindBankcardType; + } + + public function getBuyerBindBankcardType() + { + return $this->buyerBindBankcardType; + } + + public function setBuyerBindMobile($buyerBindMobile) + { + $this->buyerBindMobile = $buyerBindMobile; + $this->apiParas["buyer_bind_mobile"] = $buyerBindMobile; + } + + public function getBuyerBindMobile() + { + return $this->buyerBindMobile; + } + + public function setBuyerGrade($buyerGrade) + { + $this->buyerGrade = $buyerGrade; + $this->apiParas["buyer_grade"] = $buyerGrade; + } + + public function getBuyerGrade() + { + return $this->buyerGrade; + } + + public function setBuyerIdentityNo($buyerIdentityNo) + { + $this->buyerIdentityNo = $buyerIdentityNo; + $this->apiParas["buyer_identity_no"] = $buyerIdentityNo; + } + + public function getBuyerIdentityNo() + { + return $this->buyerIdentityNo; + } + + public function setBuyerIdentityType($buyerIdentityType) + { + $this->buyerIdentityType = $buyerIdentityType; + $this->apiParas["buyer_identity_type"] = $buyerIdentityType; + } + + public function getBuyerIdentityType() + { + return $this->buyerIdentityType; + } + + public function setBuyerRealName($buyerRealName) + { + $this->buyerRealName = $buyerRealName; + $this->apiParas["buyer_real_name"] = $buyerRealName; + } + + public function getBuyerRealName() + { + return $this->buyerRealName; + } + + public function setBuyerRegDate($buyerRegDate) + { + $this->buyerRegDate = $buyerRegDate; + $this->apiParas["buyer_reg_date"] = $buyerRegDate; + } + + public function getBuyerRegDate() + { + return $this->buyerRegDate; + } + + public function setBuyerRegEmail($buyerRegEmail) + { + $this->buyerRegEmail = $buyerRegEmail; + $this->apiParas["buyer_reg_email"] = $buyerRegEmail; + } + + public function getBuyerRegEmail() + { + return $this->buyerRegEmail; + } + + public function setBuyerRegMobile($buyerRegMobile) + { + $this->buyerRegMobile = $buyerRegMobile; + $this->apiParas["buyer_reg_mobile"] = $buyerRegMobile; + } + + public function getBuyerRegMobile() + { + return $this->buyerRegMobile; + } + + public function setBuyerSceneBankcard($buyerSceneBankcard) + { + $this->buyerSceneBankcard = $buyerSceneBankcard; + $this->apiParas["buyer_scene_bankcard"] = $buyerSceneBankcard; + } + + public function getBuyerSceneBankcard() + { + return $this->buyerSceneBankcard; + } + + public function setBuyerSceneBankcardType($buyerSceneBankcardType) + { + $this->buyerSceneBankcardType = $buyerSceneBankcardType; + $this->apiParas["buyer_scene_bankcard_type"] = $buyerSceneBankcardType; + } + + public function getBuyerSceneBankcardType() + { + return $this->buyerSceneBankcardType; + } + + public function setBuyerSceneEmail($buyerSceneEmail) + { + $this->buyerSceneEmail = $buyerSceneEmail; + $this->apiParas["buyer_scene_email"] = $buyerSceneEmail; + } + + public function getBuyerSceneEmail() + { + return $this->buyerSceneEmail; + } + + public function setBuyerSceneMobile($buyerSceneMobile) + { + $this->buyerSceneMobile = $buyerSceneMobile; + $this->apiParas["buyer_scene_mobile"] = $buyerSceneMobile; + } + + public function getBuyerSceneMobile() + { + return $this->buyerSceneMobile; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setEnvClientBaseBand($envClientBaseBand) + { + $this->envClientBaseBand = $envClientBaseBand; + $this->apiParas["env_client_base_band"] = $envClientBaseBand; + } + + public function getEnvClientBaseBand() + { + return $this->envClientBaseBand; + } + + public function setEnvClientBaseStation($envClientBaseStation) + { + $this->envClientBaseStation = $envClientBaseStation; + $this->apiParas["env_client_base_station"] = $envClientBaseStation; + } + + public function getEnvClientBaseStation() + { + return $this->envClientBaseStation; + } + + public function setEnvClientCoordinates($envClientCoordinates) + { + $this->envClientCoordinates = $envClientCoordinates; + $this->apiParas["env_client_coordinates"] = $envClientCoordinates; + } + + public function getEnvClientCoordinates() + { + return $this->envClientCoordinates; + } + + public function setEnvClientImei($envClientImei) + { + $this->envClientImei = $envClientImei; + $this->apiParas["env_client_imei"] = $envClientImei; + } + + public function getEnvClientImei() + { + return $this->envClientImei; + } + + public function setEnvClientImsi($envClientImsi) + { + $this->envClientImsi = $envClientImsi; + $this->apiParas["env_client_imsi"] = $envClientImsi; + } + + public function getEnvClientImsi() + { + return $this->envClientImsi; + } + + public function setEnvClientIosUdid($envClientIosUdid) + { + $this->envClientIosUdid = $envClientIosUdid; + $this->apiParas["env_client_ios_udid"] = $envClientIosUdid; + } + + public function getEnvClientIosUdid() + { + return $this->envClientIosUdid; + } + + public function setEnvClientIp($envClientIp) + { + $this->envClientIp = $envClientIp; + $this->apiParas["env_client_ip"] = $envClientIp; + } + + public function getEnvClientIp() + { + return $this->envClientIp; + } + + public function setEnvClientMac($envClientMac) + { + $this->envClientMac = $envClientMac; + $this->apiParas["env_client_mac"] = $envClientMac; + } + + public function getEnvClientMac() + { + return $this->envClientMac; + } + + public function setEnvClientScreen($envClientScreen) + { + $this->envClientScreen = $envClientScreen; + $this->apiParas["env_client_screen"] = $envClientScreen; + } + + public function getEnvClientScreen() + { + return $this->envClientScreen; + } + + public function setEnvClientUuid($envClientUuid) + { + $this->envClientUuid = $envClientUuid; + $this->apiParas["env_client_uuid"] = $envClientUuid; + } + + public function getEnvClientUuid() + { + return $this->envClientUuid; + } + + public function setItemQuantity($itemQuantity) + { + $this->itemQuantity = $itemQuantity; + $this->apiParas["item_quantity"] = $itemQuantity; + } + + public function getItemQuantity() + { + return $this->itemQuantity; + } + + public function setItemUnitPrice($itemUnitPrice) + { + $this->itemUnitPrice = $itemUnitPrice; + $this->apiParas["item_unit_price"] = $itemUnitPrice; + } + + public function getItemUnitPrice() + { + return $this->itemUnitPrice; + } + + public function setJsTokenId($jsTokenId) + { + $this->jsTokenId = $jsTokenId; + $this->apiParas["js_token_id"] = $jsTokenId; + } + + public function getJsTokenId() + { + return $this->jsTokenId; + } + + public function setOrderAmount($orderAmount) + { + $this->orderAmount = $orderAmount; + $this->apiParas["order_amount"] = $orderAmount; + } + + public function getOrderAmount() + { + return $this->orderAmount; + } + + public function setOrderCategory($orderCategory) + { + $this->orderCategory = $orderCategory; + $this->apiParas["order_category"] = $orderCategory; + } + + public function getOrderCategory() + { + return $this->orderCategory; + } + + public function setOrderCredateTime($orderCredateTime) + { + $this->orderCredateTime = $orderCredateTime; + $this->apiParas["order_credate_time"] = $orderCredateTime; + } + + public function getOrderCredateTime() + { + return $this->orderCredateTime; + } + + public function setOrderItemCity($orderItemCity) + { + $this->orderItemCity = $orderItemCity; + $this->apiParas["order_item_city"] = $orderItemCity; + } + + public function getOrderItemCity() + { + return $this->orderItemCity; + } + + public function setOrderItemName($orderItemName) + { + $this->orderItemName = $orderItemName; + $this->apiParas["order_item_name"] = $orderItemName; + } + + public function getOrderItemName() + { + return $this->orderItemName; + } + + public function setOrderNo($orderNo) + { + $this->orderNo = $orderNo; + $this->apiParas["order_no"] = $orderNo; + } + + public function getOrderNo() + { + return $this->orderNo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setReceiverAddress($receiverAddress) + { + $this->receiverAddress = $receiverAddress; + $this->apiParas["receiver_address"] = $receiverAddress; + } + + public function getReceiverAddress() + { + return $this->receiverAddress; + } + + public function setReceiverCity($receiverCity) + { + $this->receiverCity = $receiverCity; + $this->apiParas["receiver_city"] = $receiverCity; + } + + public function getReceiverCity() + { + return $this->receiverCity; + } + + public function setReceiverDistrict($receiverDistrict) + { + $this->receiverDistrict = $receiverDistrict; + $this->apiParas["receiver_district"] = $receiverDistrict; + } + + public function getReceiverDistrict() + { + return $this->receiverDistrict; + } + + public function setReceiverEmail($receiverEmail) + { + $this->receiverEmail = $receiverEmail; + $this->apiParas["receiver_email"] = $receiverEmail; + } + + public function getReceiverEmail() + { + return $this->receiverEmail; + } + + public function setReceiverMobile($receiverMobile) + { + $this->receiverMobile = $receiverMobile; + $this->apiParas["receiver_mobile"] = $receiverMobile; + } + + public function getReceiverMobile() + { + return $this->receiverMobile; + } + + public function setReceiverName($receiverName) + { + $this->receiverName = $receiverName; + $this->apiParas["receiver_name"] = $receiverName; + } + + public function getReceiverName() + { + return $this->receiverName; + } + + public function setReceiverState($receiverState) + { + $this->receiverState = $receiverState; + $this->apiParas["receiver_state"] = $receiverState; + } + + public function getReceiverState() + { + return $this->receiverState; + } + + public function setReceiverZip($receiverZip) + { + $this->receiverZip = $receiverZip; + $this->apiParas["receiver_zip"] = $receiverZip; + } + + public function getReceiverZip() + { + return $this->receiverZip; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function setSellerAccountNo($sellerAccountNo) + { + $this->sellerAccountNo = $sellerAccountNo; + $this->apiParas["seller_account_no"] = $sellerAccountNo; + } + + public function getSellerAccountNo() + { + return $this->sellerAccountNo; + } + + public function setSellerBindBankcard($sellerBindBankcard) + { + $this->sellerBindBankcard = $sellerBindBankcard; + $this->apiParas["seller_bind_bankcard"] = $sellerBindBankcard; + } + + public function getSellerBindBankcard() + { + return $this->sellerBindBankcard; + } + + public function setSellerBindBankcardType($sellerBindBankcardType) + { + $this->sellerBindBankcardType = $sellerBindBankcardType; + $this->apiParas["seller_bind_bankcard_type"] = $sellerBindBankcardType; + } + + public function getSellerBindBankcardType() + { + return $this->sellerBindBankcardType; + } + + public function setSellerBindMobile($sellerBindMobile) + { + $this->sellerBindMobile = $sellerBindMobile; + $this->apiParas["seller_bind_mobile"] = $sellerBindMobile; + } + + public function getSellerBindMobile() + { + return $this->sellerBindMobile; + } + + public function setSellerIdentityNo($sellerIdentityNo) + { + $this->sellerIdentityNo = $sellerIdentityNo; + $this->apiParas["seller_identity_no"] = $sellerIdentityNo; + } + + public function getSellerIdentityNo() + { + return $this->sellerIdentityNo; + } + + public function setSellerIdentityType($sellerIdentityType) + { + $this->sellerIdentityType = $sellerIdentityType; + $this->apiParas["seller_identity_type"] = $sellerIdentityType; + } + + public function getSellerIdentityType() + { + return $this->sellerIdentityType; + } + + public function setSellerRealName($sellerRealName) + { + $this->sellerRealName = $sellerRealName; + $this->apiParas["seller_real_name"] = $sellerRealName; + } + + public function getSellerRealName() + { + return $this->sellerRealName; + } + + public function setSellerRegDate($sellerRegDate) + { + $this->sellerRegDate = $sellerRegDate; + $this->apiParas["seller_reg_date"] = $sellerRegDate; + } + + public function getSellerRegDate() + { + return $this->sellerRegDate; + } + + public function setSellerRegEmail($sellerRegEmail) + { + $this->sellerRegEmail = $sellerRegEmail; + $this->apiParas["seller_reg_email"] = $sellerRegEmail; + } + + public function getSellerRegEmail() + { + return $this->sellerRegEmail; + } + + public function setSellerRegMoile($sellerRegMoile) + { + $this->sellerRegMoile = $sellerRegMoile; + $this->apiParas["seller_reg_moile"] = $sellerRegMoile; + } + + public function getSellerRegMoile() + { + return $this->sellerRegMoile; + } + + public function setTransportType($transportType) + { + $this->transportType = $transportType; + $this->apiParas["transport_type"] = $transportType; + } + + public function getTransportType() + { + return $this->transportType; + } + + public function getApiMethodName() + { + return "alipay.security.risk.detect"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php b/extend/alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php new file mode 100755 index 0000000..9248c2e --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.risk.hide.deviceid.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php b/extend/alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php new file mode 100755 index 0000000..e470d81 --- /dev/null +++ b/extend/alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.risk.rainscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipaySystemOauthTokenRequest.php b/extend/alipay/aop/request/AlipaySystemOauthTokenRequest.php new file mode 100755 index 0000000..7cb869f --- /dev/null +++ b/extend/alipay/aop/request/AlipaySystemOauthTokenRequest.php @@ -0,0 +1,150 @@ +code = $code; + $this->apiParas["code"] = $code; + } + + public function getCode() + { + return $this->code; + } + + public function setGrantType($grantType) + { + $this->grantType = $grantType; + $this->apiParas["grant_type"] = $grantType; + } + + public function getGrantType() + { + return $this->grantType; + } + + public function setRefreshToken($refreshToken) + { + $this->refreshToken = $refreshToken; + $this->apiParas["refresh_token"] = $refreshToken; + } + + public function getRefreshToken() + { + return $this->refreshToken; + } + + public function getApiMethodName() + { + return "alipay.system.oauth.token"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeAppPayRequest.php b/extend/alipay/aop/request/AlipayTradeAppPayRequest.php new file mode 100755 index 0000000..e4b27fb --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeAppPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.app.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeCancelRequest.php b/extend/alipay/aop/request/AlipayTradeCancelRequest.php new file mode 100755 index 0000000..d130df5 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeCloseRequest.php b/extend/alipay/aop/request/AlipayTradeCloseRequest.php new file mode 100755 index 0000000..d5c356e --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeCloseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.close"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeCreateRequest.php b/extend/alipay/aop/request/AlipayTradeCreateRequest.php new file mode 100755 index 0000000..1213043 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeCustomsDeclareRequest.php b/extend/alipay/aop/request/AlipayTradeCustomsDeclareRequest.php new file mode 100755 index 0000000..8544ba8 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeCustomsDeclareRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.customs.declare"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeCustomsQueryRequest.php b/extend/alipay/aop/request/AlipayTradeCustomsQueryRequest.php new file mode 100755 index 0000000..0a02356 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeCustomsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.customs.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php b/extend/alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php new file mode 100755 index 0000000..b940b90 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.fastpay.refund.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeOrderSettleRequest.php b/extend/alipay/aop/request/AlipayTradeOrderSettleRequest.php new file mode 100755 index 0000000..9f219ff --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeOrderSettleRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.order.settle"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradePagePayRequest.php b/extend/alipay/aop/request/AlipayTradePagePayRequest.php new file mode 100755 index 0000000..3801d1e --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradePagePayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.page.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradePayRequest.php b/extend/alipay/aop/request/AlipayTradePayRequest.php new file mode 100755 index 0000000..37447c2 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradePayRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradePrecreateRequest.php b/extend/alipay/aop/request/AlipayTradePrecreateRequest.php new file mode 100755 index 0000000..f3f15a4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradePrecreateRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.precreate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeQueryRequest.php b/extend/alipay/aop/request/AlipayTradeQueryRequest.php new file mode 100755 index 0000000..6f889e7 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeQueryRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeRefundRequest.php b/extend/alipay/aop/request/AlipayTradeRefundRequest.php new file mode 100755 index 0000000..211027a --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php b/extend/alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php new file mode 100755 index 0000000..77e3fa1 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.vendorpay.devicedata.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTradeWapPayRequest.php b/extend/alipay/aop/request/AlipayTradeWapPayRequest.php new file mode 100755 index 0000000..e830566 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTradeWapPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.wap.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php b/extend/alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php new file mode 100755 index 0000000..2c014d0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php @@ -0,0 +1,301 @@ +amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setExtParam($extParam) + { + $this->extParam = $extParam; + $this->apiParas["ext_param"] = $extParam; + } + + public function getExtParam() + { + return $this->extParam; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setPayeeAccount($payeeAccount) + { + $this->payeeAccount = $payeeAccount; + $this->apiParas["payee_account"] = $payeeAccount; + } + + public function getPayeeAccount() + { + return $this->payeeAccount; + } + + public function setPayeeType($payeeType) + { + $this->payeeType = $payeeType; + $this->apiParas["payee_type"] = $payeeType; + } + + public function getPayeeType() + { + return $this->payeeType; + } + + public function setPayerAccount($payerAccount) + { + $this->payerAccount = $payerAccount; + $this->apiParas["payer_account"] = $payerAccount; + } + + public function getPayerAccount() + { + return $this->payerAccount; + } + + public function setPayerType($payerType) + { + $this->payerType = $payerType; + $this->apiParas["payer_type"] = $payerType; + } + + public function getPayerType() + { + return $this->payerType; + } + + public function setPaymentId($paymentId) + { + $this->paymentId = $paymentId; + $this->apiParas["payment_id"] = $paymentId; + } + + public function getPaymentId() + { + return $this->paymentId; + } + + public function setPaymentSource($paymentSource) + { + $this->paymentSource = $paymentSource; + $this->apiParas["payment_source"] = $paymentSource; + } + + public function getPaymentSource() + { + return $this->paymentSource; + } + + public function setTitle($title) + { + $this->title = $title; + $this->apiParas["title"] = $title; + } + + public function getTitle() + { + return $this->title; + } + + public function getApiMethodName() + { + return "alipay.transfer.thirdparty.bill.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserAuthSendRequest.php b/extend/alipay/aop/request/AlipayTrustUserAuthSendRequest.php new file mode 100755 index 0000000..00a7e85 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserAuthSendRequest.php @@ -0,0 +1,118 @@ +aliTrustUserInfo = $aliTrustUserInfo; + $this->apiParas["ali_trust_user_info"] = $aliTrustUserInfo; + } + + public function getAliTrustUserInfo() + { + return $this->aliTrustUserInfo; + } + + public function getApiMethodName() + { + return "alipay.trust.user.auth.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserReportGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserReportGetRequest.php new file mode 100755 index 0000000..7d75c15 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserReportGetRequest.php @@ -0,0 +1,134 @@ +scene = $scene; + $this->apiParas["scene"] = $scene; + } + + public function getScene() + { + return $this->scene; + } + + public function setType($type) + { + $this->type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.trust.user.report.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserRiskSummaryGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserRiskSummaryGetRequest.php new file mode 100755 index 0000000..e44b083 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserRiskSummaryGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trust.user.risk.summary.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php new file mode 100755 index 0000000..ed475f0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php @@ -0,0 +1,118 @@ +type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.trust.user.riskidentify.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserScoreGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserScoreGetRequest.php new file mode 100755 index 0000000..081fd81 --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserScoreGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserStandardVerifyGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserStandardVerifyGetRequest.php new file mode 100755 index 0000000..5f7547b --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserStandardVerifyGetRequest.php @@ -0,0 +1,118 @@ +aliTrustUserInfo = $aliTrustUserInfo; + $this->apiParas["ali_trust_user_info"] = $aliTrustUserInfo; + } + + public function getAliTrustUserInfo() + { + return $this->aliTrustUserInfo; + } + + public function getApiMethodName() + { + return "alipay.trust.user.standard.verify.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserTokenGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserTokenGetRequest.php new file mode 100755 index 0000000..be8b71c --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserTokenGetRequest.php @@ -0,0 +1,118 @@ +aliTrustUserInfo = $aliTrustUserInfo; + $this->apiParas["ali_trust_user_info"] = $aliTrustUserInfo; + } + + public function getAliTrustUserInfo() + { + return $this->aliTrustUserInfo; + } + + public function getApiMethodName() + { + return "alipay.trust.user.token.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayTrustUserZminfoPairGetRequest.php b/extend/alipay/aop/request/AlipayTrustUserZminfoPairGetRequest.php new file mode 100755 index 0000000..d5845ac --- /dev/null +++ b/extend/alipay/aop/request/AlipayTrustUserZminfoPairGetRequest.php @@ -0,0 +1,150 @@ +applyUserInfo = $applyUserInfo; + $this->apiParas["apply_user_info"] = $applyUserInfo; + } + + public function getApplyUserInfo() + { + return $this->applyUserInfo; + } + + public function setOwnerUserInfo($ownerUserInfo) + { + $this->ownerUserInfo = $ownerUserInfo; + $this->apiParas["owner_user_info"] = $ownerUserInfo; + } + + public function getOwnerUserInfo() + { + return $this->ownerUserInfo; + } + + public function setZmInfoType($zmInfoType) + { + $this->zmInfoType = $zmInfoType; + $this->apiParas["zm_info_type"] = $zmInfoType; + } + + public function getZmInfoType() + { + return $this->zmInfoType; + } + + public function getApiMethodName() + { + return "alipay.trust.user.zminfo.pair.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserAccountFreezeGetRequest.php b/extend/alipay/aop/request/AlipayUserAccountFreezeGetRequest.php new file mode 100755 index 0000000..1f9fdca --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserAccountFreezeGetRequest.php @@ -0,0 +1,118 @@ +freezeType = $freezeType; + $this->apiParas["freeze_type"] = $freezeType; + } + + public function getFreezeType() + { + return $this->freezeType; + } + + public function getApiMethodName() + { + return "alipay.user.account.freeze.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserAccountGetRequest.php b/extend/alipay/aop/request/AlipayUserAccountGetRequest.php new file mode 100755 index 0000000..c94a841 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserAccountGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserAccountSearchRequest.php b/extend/alipay/aop/request/AlipayUserAccountSearchRequest.php new file mode 100755 index 0000000..ad17ba4 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserAccountSearchRequest.php @@ -0,0 +1,198 @@ +endTime = $endTime; + $this->apiParas["end_time"] = $endTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function setFields($fields) + { + $this->fields = $fields; + $this->apiParas["fields"] = $fields; + } + + public function getFields() + { + return $this->fields; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStartTime($startTime) + { + $this->startTime = $startTime; + $this->apiParas["start_time"] = $startTime; + } + + public function getStartTime() + { + return $this->startTime; + } + + public function setType($type) + { + $this->type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.user.account.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php b/extend/alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php new file mode 100755 index 0000000..a62e62f --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.account.userid.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserContractGetRequest.php b/extend/alipay/aop/request/AlipayUserContractGetRequest.php new file mode 100755 index 0000000..9e2d971 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserContractGetRequest.php @@ -0,0 +1,118 @@ +subscriberUserId = $subscriberUserId; + $this->apiParas["subscriber_user_id"] = $subscriberUserId; + } + + public function getSubscriberUserId() + { + return $this->subscriberUserId; + } + + public function getApiMethodName() + { + return "alipay.user.contract.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserFinanceinfoShareRequest.php b/extend/alipay/aop/request/AlipayUserFinanceinfoShareRequest.php new file mode 100755 index 0000000..fc01d82 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserFinanceinfoShareRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.financeinfo.share"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserGetRequest.php b/extend/alipay/aop/request/AlipayUserGetRequest.php new file mode 100755 index 0000000..f75fb66 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserGetRequest.php @@ -0,0 +1,118 @@ +fields = $fields; + $this->apiParas["fields"] = $fields; + } + + public function getFields() + { + return $this->fields; + } + + public function getApiMethodName() + { + return "alipay.user.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserInfoAuthRequest.php b/extend/alipay/aop/request/AlipayUserInfoAuthRequest.php new file mode 100755 index 0000000..eedb338 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserInfoAuthRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.info.auth"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserInfoShareRequest.php b/extend/alipay/aop/request/AlipayUserInfoShareRequest.php new file mode 100755 index 0000000..150a91c --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserInfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserTestRequest.php b/extend/alipay/aop/request/AlipayUserTestRequest.php new file mode 100755 index 0000000..92a8edb --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserTestRequest.php @@ -0,0 +1,118 @@ +userinfo = $userinfo; + $this->apiParas["userinfo"] = $userinfo; + } + + public function getUserinfo() + { + return $this->userinfo; + } + + public function getApiMethodName() + { + return "alipay.user.test"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserTradeSearchRequest.php b/extend/alipay/aop/request/AlipayUserTradeSearchRequest.php new file mode 100755 index 0000000..d1dbd61 --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserTradeSearchRequest.php @@ -0,0 +1,246 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setEndTime($endTime) + { + $this->endTime = $endTime; + $this->apiParas["end_time"] = $endTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderFrom($orderFrom) + { + $this->orderFrom = $orderFrom; + $this->apiParas["order_from"] = $orderFrom; + } + + public function getOrderFrom() + { + return $this->orderFrom; + } + + public function setOrderStatus($orderStatus) + { + $this->orderStatus = $orderStatus; + $this->apiParas["order_status"] = $orderStatus; + } + + public function getOrderStatus() + { + return $this->orderStatus; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStartTime($startTime) + { + $this->startTime = $startTime; + $this->apiParas["start_time"] = $startTime; + } + + public function getStartTime() + { + return $this->startTime; + } + + public function getApiMethodName() + { + return "alipay.user.trade.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayUserUserinfoShareRequest.php b/extend/alipay/aop/request/AlipayUserUserinfoShareRequest.php new file mode 100755 index 0000000..01c6ecb --- /dev/null +++ b/extend/alipay/aop/request/AlipayUserUserinfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php b/extend/alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php new file mode 100755 index 0000000..4cddde9 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.easyservice"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php b/extend/alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php new file mode 100755 index 0000000..5822eb3 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.fcdatalab.zdatamergetask"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdataassetsMetadataRequest.php b/extend/alipay/aop/request/AlipayZdataassetsMetadataRequest.php new file mode 100755 index 0000000..ce293d0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdataassetsMetadataRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.metadata"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php b/extend/alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php new file mode 100755 index 0000000..ff33066 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php @@ -0,0 +1,200 @@ +0,就先判断cache中的数据是否过期,如果没有过期就返回cache中的数据,如果过期再从外部获取数据并刷新cache,然后返回数据。 +单位:秒 + **/ + private $cacheInterval; + + /** + * 通用查询的入参 + **/ + private $queryConditions; + + /** + * 服务名称请与相关开发负责人联系 + **/ + private $serviceName; + + /** + * 访问该服务的业务 + **/ + private $visitBiz; + + /** + * 访问该服务的业务线 + **/ + private $visitBizLine; + + /** + * 访问该服务的部门名称 + **/ + private $visitDomain; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setCacheInterval($cacheInterval) + { + $this->cacheInterval = $cacheInterval; + $this->apiParas["cache_interval"] = $cacheInterval; + } + + public function getCacheInterval() + { + return $this->cacheInterval; + } + + public function setQueryConditions($queryConditions) + { + $this->queryConditions = $queryConditions; + $this->apiParas["query_conditions"] = $queryConditions; + } + + public function getQueryConditions() + { + return $this->queryConditions; + } + + public function setServiceName($serviceName) + { + $this->serviceName = $serviceName; + $this->apiParas["service_name"] = $serviceName; + } + + public function getServiceName() + { + return $this->serviceName; + } + + public function setVisitBiz($visitBiz) + { + $this->visitBiz = $visitBiz; + $this->apiParas["visit_biz"] = $visitBiz; + } + + public function getVisitBiz() + { + return $this->visitBiz; + } + + public function setVisitBizLine($visitBizLine) + { + $this->visitBizLine = $visitBizLine; + $this->apiParas["visit_biz_line"] = $visitBizLine; + } + + public function getVisitBizLine() + { + return $this->visitBizLine; + } + + public function setVisitDomain($visitDomain) + { + $this->visitDomain = $visitDomain; + $this->apiParas["visit_domain"] = $visitDomain; + } + + public function getVisitDomain() + { + return $this->visitDomain; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.common.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php b/extend/alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php new file mode 100755 index 0000000..91d7ebe --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php @@ -0,0 +1,230 @@ +columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileDescription($fileDescription) + { + $this->fileDescription = $fileDescription; + $this->apiParas["file_description"] = $fileDescription; + } + + public function getFileDescription() + { + return $this->fileDescription; + } + + public function setFileDigest($fileDigest) + { + $this->fileDigest = $fileDigest; + $this->apiParas["file_digest"] = $fileDigest; + } + + public function getFileDigest() + { + return $this->fileDigest; + } + + public function setFileType($fileType) + { + $this->fileType = $fileType; + $this->apiParas["file_type"] = $fileType; + } + + public function getFileType() + { + return $this->fileType; + } + + public function setPrimaryKey($primaryKey) + { + $this->primaryKey = $primaryKey; + $this->apiParas["primary_key"] = $primaryKey; + } + + public function getPrimaryKey() + { + return $this->primaryKey; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function setTypeId($typeId) + { + $this->typeId = $typeId; + $this->apiParas["type_id"] = $typeId; + } + + public function getTypeId() + { + return $this->typeId; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.datatransfered.fileupload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php b/extend/alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php new file mode 100755 index 0000000..a756df0 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php @@ -0,0 +1,150 @@ +data = $data; + $this->apiParas["data"] = $data; + } + + public function getData() + { + return $this->data; + } + + public function setIdentity($identity) + { + $this->identity = $identity; + $this->apiParas["identity"] = $identity; + } + + public function getIdentity() + { + return $this->identity; + } + + public function setTypeId($typeId) + { + $this->typeId = $typeId; + $this->apiParas["type_id"] = $typeId; + } + + public function getTypeId() + { + return $this->typeId; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.datatransfered.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php b/extend/alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php new file mode 100755 index 0000000..c838624 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php @@ -0,0 +1,134 @@ +queryCondition = $queryCondition; + $this->apiParas["query_condition"] = $queryCondition; + } + + public function getQueryCondition() + { + return $this->queryCondition; + } + + public function setUniqKey($uniqKey) + { + $this->uniqKey = $uniqKey; + $this->apiParas["uniq_key"] = $uniqKey; + } + + public function getUniqKey() + { + return $this->uniqKey; + } + + public function getApiMethodName() + { + return "alipay.zdataservice.unidata.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AlipayZmscoreZrankGetRequest.php b/extend/alipay/aop/request/AlipayZmscoreZrankGetRequest.php new file mode 100755 index 0000000..ad3a201 --- /dev/null +++ b/extend/alipay/aop/request/AlipayZmscoreZrankGetRequest.php @@ -0,0 +1,118 @@ +userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.zmscore.zrank.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php b/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php new file mode 100755 index 0000000..2478961 --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.contract.facetoface.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php b/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php new file mode 100755 index 0000000..9df9b2b --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.contract.facetoface.sign"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php b/extend/alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php new file mode 100755 index 0000000..d1ef57f --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.enterprise.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandImageUploadRequest.php b/extend/alipay/aop/request/AntMerchantExpandImageUploadRequest.php new file mode 100755 index 0000000..844a155 --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandImageUploadRequest.php @@ -0,0 +1,134 @@ +imageContent = $imageContent; + $this->apiParas["image_content"] = $imageContent; + } + + public function getImageContent() + { + return $this->imageContent; + } + + public function setImageType($imageType) + { + $this->imageType = $imageType; + $this->apiParas["image_type"] = $imageType; + } + + public function getImageType() + { + return $this->imageType; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.image.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php b/extend/alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php new file mode 100755 index 0000000..2152810 --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.mapplyorder.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php b/extend/alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php new file mode 100755 index 0000000..a7e2700 --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.merchant.storelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php b/extend/alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php new file mode 100755 index 0000000..a3b0874 --- /dev/null +++ b/extend/alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.personal.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php b/extend/alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php new file mode 100755 index 0000000..9c28eab --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.catering.tablecode.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCateringTablelistQueryRequest.php b/extend/alipay/aop/request/KoubeiCateringTablelistQueryRequest.php new file mode 100755 index 0000000..859cf1c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCateringTablelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.catering.tablelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiContentCommentDataBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiContentCommentDataBatchqueryRequest.php new file mode 100755 index 0000000..6062995 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiContentCommentDataBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.content.comment.data.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiContentCommentReplyCreateRequest.php b/extend/alipay/aop/request/KoubeiContentCommentReplyCreateRequest.php new file mode 100755 index 0000000..cea730c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiContentCommentReplyCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.content.comment.reply.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php new file mode 100755 index 0000000..0bffab8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php new file mode 100755 index 0000000..ace1245 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php new file mode 100755 index 0000000..45814e2 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php new file mode 100755 index 0000000..dba8bcc --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php new file mode 100755 index 0000000..ff9e66d --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php new file mode 100755 index 0000000..dc9a664 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php new file mode 100755 index 0000000..32f42d9 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiItemBatchqueryRequest.php new file mode 100755 index 0000000..26909c0 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php new file mode 100755 index 0000000..768c845 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.category.children.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemCreateRequest.php b/extend/alipay/aop/request/KoubeiItemCreateRequest.php new file mode 100755 index 0000000..4435d5c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php new file mode 100755 index 0000000..0917000 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php new file mode 100755 index 0000000..c531917 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php new file mode 100755 index 0000000..e486ed2 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.category.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemCreateRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemCreateRequest.php new file mode 100755 index 0000000..f3ebc4d --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php new file mode 100755 index 0000000..e26acb0 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.existed.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemQueryRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemQueryRequest.php new file mode 100755 index 0000000..0457a4f --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemExtitemUpdateRequest.php b/extend/alipay/aop/request/KoubeiItemExtitemUpdateRequest.php new file mode 100755 index 0000000..d6eeed7 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemExtitemUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemModifyRequest.php b/extend/alipay/aop/request/KoubeiItemModifyRequest.php new file mode 100755 index 0000000..285eb2c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiItemStateRequest.php b/extend/alipay/aop/request/KoubeiItemStateRequest.php new file mode 100755 index 0000000..326cfc8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiItemStateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.state"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php new file mode 100755 index 0000000..5a6a3aa --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php new file mode 100755 index 0000000..01825c1 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php new file mode 100755 index 0000000..d92063e --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php new file mode 100755 index 0000000..f0e2487 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php new file mode 100755 index 0000000..ca70492 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php new file mode 100755 index 0000000..087849d --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.asset.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php new file mode 100755 index 0000000..83606d5 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php new file mode 100755 index 0000000..6661036 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.count"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php new file mode 100755 index 0000000..02baa6a --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php new file mode 100755 index 0000000..5944eaf --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php new file mode 100755 index 0000000..81a053e --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php new file mode 100755 index 0000000..95c4686 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php new file mode 100755 index 0000000..3e935b2 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.detail.info.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php new file mode 100755 index 0000000..67d9d75 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.recruit.apply.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php new file mode 100755 index 0000000..99466c8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.recruit.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php new file mode 100755 index 0000000..1bb6142 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php new file mode 100755 index 0000000..0163667 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.user.asset.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php new file mode 100755 index 0000000..58ad65a --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.activity.bill.download"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php new file mode 100755 index 0000000..73ad093 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.activity.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php new file mode 100755 index 0000000..5b413fb --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.alisis.report.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php new file mode 100755 index 0000000..90312f3 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.alisis.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php new file mode 100755 index 0000000..20868f2 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.memberprofile.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php new file mode 100755 index 0000000..fe849a1 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.myddsreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php new file mode 100755 index 0000000..9ca1d59 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.myreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php new file mode 100755 index 0000000..307a418 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php new file mode 100755 index 0000000..30e5c4c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php new file mode 100755 index 0000000..5a5cc6b --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php new file mode 100755 index 0000000..d40e3af --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php new file mode 100755 index 0000000..1393573 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.save"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php new file mode 100755 index 0000000..7980a9a --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.dishdiagnose.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php new file mode 100755 index 0000000..ef95f59 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php new file mode 100755 index 0000000..b95cbc1 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.enterprise.staffinfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php new file mode 100755 index 0000000..1843946 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.indicator.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php new file mode 100755 index 0000000..93a3ccd --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.isv.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php new file mode 100755 index 0000000..b12a5e8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.member.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php new file mode 100755 index 0000000..a5cfe3f --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.message.deliver"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php new file mode 100755 index 0000000..cb2a7b2 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.retail.dm.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php new file mode 100755 index 0000000..9347897 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.smartactivity.config"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php new file mode 100755 index 0000000..46886e5 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.smartactivity.forecast"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php new file mode 100755 index 0000000..dc1756e --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php new file mode 100755 index 0000000..8887c00 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.trade.habbit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php new file mode 100755 index 0000000..6cd6917 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.isv.merchant.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php b/extend/alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php new file mode 100755 index 0000000..9bdbe7e --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.points.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php b/extend/alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php new file mode 100755 index 0000000..9919124 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.points.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php b/extend/alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php new file mode 100755 index 0000000..76c644d --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.prizesend.auth"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php b/extend/alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php new file mode 100755 index 0000000..7dc9629 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php b/extend/alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php new file mode 100755 index 0000000..1fced22 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.member.data.oauth.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiMemberRetailerQueryRequest.php b/extend/alipay/aop/request/KoubeiMemberRetailerQueryRequest.php new file mode 100755 index 0000000..cafb49c --- /dev/null +++ b/extend/alipay/aop/request/KoubeiMemberRetailerQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php b/extend/alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php new file mode 100755 index 0000000..f875fab --- /dev/null +++ b/extend/alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php b/extend/alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php new file mode 100755 index 0000000..3890a4f --- /dev/null +++ b/extend/alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.batch.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php b/extend/alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php new file mode 100755 index 0000000..3d955b8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.checkresult.submit"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php b/extend/alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php new file mode 100755 index 0000000..fb1e6a7 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.item.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php b/extend/alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php new file mode 100755 index 0000000..d246c49 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiRetailShopitemModifyRequest.php b/extend/alipay/aop/request/KoubeiRetailShopitemModifyRequest.php new file mode 100755 index 0000000..9bce978 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiRetailShopitemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiRetailShopitemUploadRequest.php b/extend/alipay/aop/request/KoubeiRetailShopitemUploadRequest.php new file mode 100755 index 0000000..a6f3cc7 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiRetailShopitemUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiTradeItemBuyRequest.php b/extend/alipay/aop/request/KoubeiTradeItemBuyRequest.php new file mode 100755 index 0000000..72de764 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiTradeItemBuyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.item.buy"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiTradeOrderConsultRequest.php b/extend/alipay/aop/request/KoubeiTradeOrderConsultRequest.php new file mode 100755 index 0000000..9a0e2b8 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiTradeOrderConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.order.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiTradeOrderQueryRequest.php b/extend/alipay/aop/request/KoubeiTradeOrderQueryRequest.php new file mode 100755 index 0000000..975c426 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiTradeOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php b/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php new file mode 100755 index 0000000..71da336 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.ticket.ticketcode.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php b/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php new file mode 100755 index 0000000..1589795 --- /dev/null +++ b/extend/alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.ticket.ticketcode.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MonitorHeartbeatSynRequest.php b/extend/alipay/aop/request/MonitorHeartbeatSynRequest.php new file mode 100755 index 0000000..7c735e9 --- /dev/null +++ b/extend/alipay/aop/request/MonitorHeartbeatSynRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "monitor.heartbeat.syn"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php b/extend/alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php new file mode 100755 index 0000000..642510e --- /dev/null +++ b/extend/alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.credit.loanapply.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php b/extend/alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php new file mode 100755 index 0000000..0786b1c --- /dev/null +++ b/extend/alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php b/extend/alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php new file mode 100755 index 0000000..113fd84 --- /dev/null +++ b/extend/alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.capital.purchase"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php b/extend/alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php new file mode 100755 index 0000000..38a6043 --- /dev/null +++ b/extend/alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.capital.ransom"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php b/extend/alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php new file mode 100755 index 0000000..7e5c1c7 --- /dev/null +++ b/extend/alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.price.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php b/extend/alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php new file mode 100755 index 0000000..6fcdf83 --- /dev/null +++ b/extend/alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.trans.history.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php new file mode 100755 index 0000000..e3025df --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.alixiaohao.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php new file mode 100755 index 0000000..7abe91b --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraud.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php new file mode 100755 index 0000000..25079bd --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudintegration.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php new file mode 100755 index 0000000..9937c15 --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php new file mode 100755 index 0000000..880adc5 --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php b/extend/alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php new file mode 100755 index 0000000..266cb7f --- /dev/null +++ b/extend/alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.rainscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php b/extend/alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php new file mode 100755 index 0000000..a2a9702 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.auth.info.authquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php b/extend/alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php new file mode 100755 index 0000000..6feb259 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.antifraud.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php b/extend/alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php new file mode 100755 index 0000000..b59c537 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.score.brief.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCreditScoreGetRequest.php b/extend/alipay/aop/request/ZhimaCreditScoreGetRequest.php new file mode 100755 index 0000000..79d1fd6 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCreditScoreGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.score.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php b/extend/alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php new file mode 100755 index 0000000..f3466a2 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.watchlist.brief.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php b/extend/alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php new file mode 100755 index 0000000..862273f --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.watchlistii.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php b/extend/alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php new file mode 100755 index 0000000..4a4d67d --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.certify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php b/extend/alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php new file mode 100755 index 0000000..8e947dd --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php b/extend/alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php new file mode 100755 index 0000000..3da9e86 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaDataBatchFeedbackRequest.php b/extend/alipay/aop/request/ZhimaDataBatchFeedbackRequest.php new file mode 100755 index 0000000..46b9e01 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaDataBatchFeedbackRequest.php @@ -0,0 +1,230 @@ +bizExtParams = $bizExtParams; + $this->apiParas["biz_ext_params"] = $bizExtParams; + } + + public function getBizExtParams() + { + return $this->bizExtParams; + } + + public function setColumns($columns) + { + $this->columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setFileDescription($fileDescription) + { + $this->fileDescription = $fileDescription; + $this->apiParas["file_description"] = $fileDescription; + } + + public function getFileDescription() + { + return $this->fileDescription; + } + + public function setFileType($fileType) + { + $this->fileType = $fileType; + $this->apiParas["file_type"] = $fileType; + } + + public function getFileType() + { + return $this->fileType; + } + + public function setPrimaryKeyColumns($primaryKeyColumns) + { + $this->primaryKeyColumns = $primaryKeyColumns; + $this->apiParas["primary_key_columns"] = $primaryKeyColumns; + } + + public function getPrimaryKeyColumns() + { + return $this->primaryKeyColumns; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function getApiMethodName() + { + return "zhima.data.batch.feedback"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php b/extend/alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php new file mode 100755 index 0000000..293416c --- /dev/null +++ b/extend/alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.data.feedbackurl.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php b/extend/alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php new file mode 100755 index 0000000..4bd41ff --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.borrow.entity.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php b/extend/alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php new file mode 100755 index 0000000..b0e6ede --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php @@ -0,0 +1,224 @@ +bizExtParams = $bizExtParams; + $this->apiParas["biz_ext_params"] = $bizExtParams; + } + + public function getBizExtParams() + { + return $this->bizExtParams; + } + + public function setColumns($columns) + { + $this->columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setPrimaryKeyColumns($primaryKeyColumns) + { + $this->primaryKeyColumns = $primaryKeyColumns; + $this->apiParas["primary_key_columns"] = $primaryKeyColumns; + } + + public function getPrimaryKeyColumns() + { + return $this->primaryKeyColumns; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function getApiMethodName() + { + return "zhima.merchant.closeloop.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php b/extend/alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php new file mode 100755 index 0000000..1cbec97 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.data.upload.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php b/extend/alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php new file mode 100755 index 0000000..e28835e --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php b/extend/alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php new file mode 100755 index 0000000..eaf1880 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.complete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php b/extend/alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php new file mode 100755 index 0000000..e752a58 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php b/extend/alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php new file mode 100755 index 0000000..7220640 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php b/extend/alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php new file mode 100755 index 0000000..8e4f74b --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php b/extend/alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php new file mode 100755 index 0000000..14605a3 --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.single.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaMerchantTestPracticeRequest.php b/extend/alipay/aop/request/ZhimaMerchantTestPracticeRequest.php new file mode 100755 index 0000000..1de743e --- /dev/null +++ b/extend/alipay/aop/request/ZhimaMerchantTestPracticeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.test.practice"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php b/extend/alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php new file mode 100755 index 0000000..1cb3edd --- /dev/null +++ b/extend/alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.open.app.keyan.lql.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/AopSdk.php b/extend/app_alipay/AopSdk.php new file mode 100755 index 0000000..ff8c2eb --- /dev/null +++ b/extend/app_alipay/AopSdk.php @@ -0,0 +1,43 @@ +option["autoload_dir"] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'aop'; +$lotus->devMode = AOP_SDK_DEV_MODE; +$lotus->defaultStoreDir = AOP_SDK_WORK_DIR; +$lotus->init(); \ No newline at end of file diff --git a/extend/app_alipay/aop/AlipayMobilePublicMultiMediaClient.php b/extend/app_alipay/aop/AlipayMobilePublicMultiMediaClient.php new file mode 100755 index 0000000..f4ee173 --- /dev/null +++ b/extend/app_alipay/aop/AlipayMobilePublicMultiMediaClient.php @@ -0,0 +1,231 @@ + serverUrl = $serverUrl; + $this -> appId = $appId; + $this -> privateKey = $partner_private_key; + $this -> format = $format; + $this -> charset = $charset; + } + + /** + * getContents 获取网址内容 + * @param $request + * @return text | bin + */ + public function getContents(){ + //自己的服务器如果没有 curl,可用:fsockopen() 等 + + + //1: + //2: 私钥格式 + $datas = array( + "app_id" => $this -> appId, + "method" => $this -> METHOD_POST, + "sign_type" => $this -> sign_type, + "version" => $this -> apiVersion, + "timestamp" => date('Y-m-d H:i:s') ,//yyyy-MM-dd HH:mm:ss + "biz_content" => '{"mediaId":"'. $this -> media_id .'"}', + "charset" => $this -> charset + ); + + + + //要提交的数据 + $data_sign = $this -> buildGetUrl( $datas ); + + $post_data = $data_sign; + //初始化 curl + $ch = curl_init(); + //设置目标服务器 + curl_setopt($ch, CURLOPT_URL, $this -> serverUrl ); + curl_setopt($ch, CURLOPT_HEADER, TRUE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + //超时时间 + curl_setopt($ch, CURLOPT_TIMEOUT, $this-> timeout); + + if( $this-> METHOD_POST == 'POST'){ + // post数据 + curl_setopt($ch, CURLOPT_POST, 1); + // post的变量 + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + } + + + + + $output = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + echo $output; + + //分离头部 + //list($header, $body) = explode("\r\n\r\n", $output, 2); + $datas = explode("\r\n\r\n", $output, 2); + $header = $datas[0]; + + if( $httpCode == '200'){ + $body = $datas[1]; + }else{ + $body = ''; + + } + + + + + return $this -> execute( $header, $body, $httpCode ); + } + + /** + * + * @param $request + * @return text | bin + */ + public function execute( $header = '', $body = '', $httpCode = '' ){ + $exe = new AlipayMobilePublicMultiMediaExecute( $header, $body, $httpCode ); + return $exe; + } + + public function buildGetUrl( $query = array() ){ + + if( ! is_array( $query ) ){ + //exit; + } + + //排序参数, + $data = $this -> buildQuery( $query ); + + + + // 私钥密码 + $passphrase = ''; + $key_width = 64; + + //私钥 + $privateKey = $this -> privateKey; + $p_key = array(); + //如果私钥是 1行 + if( ! stripos( $privateKey, "\n" ) ){ + $i = 0; + while( $key_str = substr( $privateKey , $i * $key_width , $key_width) ){ + $p_key[] = $key_str; + $i ++ ; + } + }else{ + //echo '一行?'; + } + $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . implode("\n", $p_key) ; + $privateKey = $privateKey ."\n-----END RSA PRIVATE KEY-----"; + +// echo "\n\n私钥:\n"; +// echo( $privateKey ); +// echo "\n\n\n"; + + //私钥 + $private_id = openssl_pkey_get_private( $privateKey , $passphrase); + + + // 签名 + $signature = ''; + + if("RSA2"==$this->sign_type){ + + openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA256 ); + }else{ + + openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA1 ); + } + + openssl_free_key( $private_id ); + + //加密后的内容通常含有特殊字符,需要编码转换下 + $signature = base64_encode($signature); + + $signature = urlencode( $signature ); + + //$signature = 'XjUN6YM1Mc9HXebKMv7GTLy7gmyhktyOgKk2/Jf+cz4DtP6udkzTdpkjW2j/Z4ZSD7xD6CNYI1Spz4yS93HPT0a5X9LgFWYY8SaADqe+ArXg+FBSiTwUz49SE//Xd9+LEiIRsSFkbpkuiGoO6mqJmB7vXjlD5lx6qCM3nb41wb8='; + + $out = $data .'&'. $this -> SIGN .'='. $signature; + +// echo "\n\n 加密后:\n"; +// echo( $out ); +// echo "\n\n\n"; + + return $out ; + } + + /* + * 查询参数排序 a-z + * */ + public function buildQuery( $query ){ + if ( !$query ) { + return null; + } + +//将要 参数 排序 + ksort( $query ); + + //重新组装参数 + $params = array(); + foreach($query as $key => $value){ + $params[] = $key .'='. $value ; + } + $data = implode('&', $params); + + return $data; + + } + + + + + + + + + + + + + + +} diff --git a/extend/app_alipay/aop/AlipayMobilePublicMultiMediaExecute.php b/extend/app_alipay/aop/AlipayMobilePublicMultiMediaExecute.php new file mode 100755 index 0000000..d662f3b --- /dev/null +++ b/extend/app_alipay/aop/AlipayMobilePublicMultiMediaExecute.php @@ -0,0 +1,108 @@ + 'jpg', //+ + "text/plain" => 'text' + ); + + /* + * @$header : 头部 + * */ + function __construct( $header, $body, $httpCode ){ + $this -> code = $httpCode; + $this -> msg = ''; + $this -> params = $header ; + $this -> body = $body; + } + + /** + * + * @return text | bin + */ + public function getCode(){ + return $this -> code ; + } + + /** + * + * @return text | bin + */ + public function getMsg(){ + return $this -> msg ; + } + + /** + * + * @return text | bin + */ + public function getType(){ + $subject = $this -> params ; + $pattern = '/Content\-Type:([^;]+)/'; + preg_match($pattern, $subject, $matches); + if( $matches ){ + $type = $matches[1]; + }else{ + $type = 'application/download'; + } + + return str_replace( ' ', '', $type ); + } + + /** + * + * @return text | bin + */ + public function getContentLength(){ + $subject = $this -> params ; + $pattern = '/Content-Length:\s*([^\n]+)/'; + preg_match($pattern, $subject, $matches); + return (int)( isset($matches[1] ) ? $matches[1] : '' ); + } + + + public function getFileSuffix( $fileType ){ + $type = isset( $this -> fileSuffix[ $fileType ] ) ? $this -> fileSuffix[ $fileType ] : 'text/plain' ; + if( !$type ){ + $type = 'json'; + } + return $type; + } + + + + /** + * + * @return text | bin + */ + public function getBody(){ + //header('Content-type: image/jpeg'); + return $this -> body ; + } + + /** + * 获取参数 + * @return text | bin + */ + public function getParams(){ + return $this -> params ; + } + + +} diff --git a/extend/app_alipay/aop/AopClient.php b/extend/app_alipay/aop/AopClient.php new file mode 100755 index 0000000..ce0249a --- /dev/null +++ b/extend/app_alipay/aop/AopClient.php @@ -0,0 +1,1215 @@ +sign($this->getSignContent($params), $signType); + } + + public function rsaSign($params, $signType = "RSA") { + return $this->sign($this->getSignContent($params), $signType); + } + + public function getSignContent($params) { + ksort($params); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . "$v"; + } else { + $stringToBeSigned .= "&" . "$k" . "=" . "$v"; + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + + //此方法对value做urlencode + public function getSignContentUrlencode($params) { + ksort($params); + + $stringToBeSigned = ""; + $i = 0; + foreach ($params as $k => $v) { + if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { + + // 转换成目标字符集 + $v = $this->characet($v, $this->postCharset); + + if ($i == 0) { + $stringToBeSigned .= "$k" . "=" . urlencode($v); + } else { + $stringToBeSigned .= "&" . "$k" . "=" . urlencode($v); + } + $i++; + } + } + + unset ($k, $v); + return $stringToBeSigned; + } + + protected function sign($data, $signType = "RSA") { + if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ + $priKey=$this->rsaPrivateKey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + }else { + $priKey = file_get_contents($this->rsaPrivateKeyFilePath); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if(!$this->checkEmpty($this->rsaPrivateKeyFilePath)){ + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + /** + * RSA单独签名方法,未做字符串处理,字符串处理见getSignContent() + * @param $data 待签名字符串 + * @param $privatekey 商户私钥,根据keyfromfile来判断是读取字符串还是读取文件,false:填写私钥字符串去回车和空格 true:填写私钥文件路径 + * @param $signType 签名方式,RSA:SHA1 RSA2:SHA256 + * @param $keyfromfile 私钥获取方式,读取字符串还是读文件 + * @return string + * @author mengyu.wh + */ + public function alonersaSign($data,$privatekey,$signType = "RSA",$keyfromfile=false) { + + if(!$keyfromfile){ + $priKey=$privatekey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + } + else{ + $priKey = file_get_contents($privatekey); + $res = openssl_get_privatekey($priKey); + } + + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + + if ("RSA2" == $signType) { + openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); + } else { + openssl_sign($data, $sign, $res); + } + + if($keyfromfile){ + openssl_free_key($res); + } + $sign = base64_encode($sign); + return $sign; + } + + + protected function curl($url, $postFields = null) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_FAILONERROR, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $postBodyString = ""; + $encodeArray = Array(); + $postMultipart = false; + + + if (is_array($postFields) && 0 < count($postFields)) { + + foreach ($postFields as $k => $v) { + if ("@" != substr($v, 0, 1)) //判断是不是文件上传 + { + + $postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&"; + $encodeArray[$k] = $this->characet($v, $this->postCharset); + } else //文件上传用multipart/form-data,否则用www-form-urlencoded + { + $postMultipart = true; + $encodeArray[$k] = new \CURLFile(substr($v, 1)); + } + + } + unset ($k, $v); + curl_setopt($ch, CURLOPT_POST, true); + if ($postMultipart) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray); + } else { + curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1)); + } + } + + if ($postMultipart) { + + $headers = array('content-type: multipart/form-data;charset=' . $this->postCharset . ';boundary=' . $this->getMillisecond()); + } else { + + $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset); + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + + + + + $reponse = curl_exec($ch); + + if (curl_errno($ch)) { + + throw new Exception(curl_error($ch), 0); + } else { + $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (200 !== $httpStatusCode) { + throw new Exception($reponse, $httpStatusCode); + } + } + + curl_close($ch); + return $reponse; + } + + protected function getMillisecond() { + list($s1, $s2) = explode(' ', microtime()); + return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); + } + + + protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) { + $localIp = isset ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI"; + $logger = new LtLogger; + $logger->conf["log_file"] = rtrim(AOP_SDK_WORK_DIR, '\\/') . '/' . "logs/aop_comm_err_" . $this->appId . "_" . date("Y-m-d") . ".log"; + $logger->conf["separator"] = "^_^"; + $logData = array( + date("Y-m-d H:i:s"), + $apiName, + $this->appId, + $localIp, + PHP_OS, + $this->alipaySdkVersion, + $requestUrl, + $errorCode, + str_replace("\n", "", $responseTxt) + ); + $logger->log($logData); + } + + /** + * 生成用于调用收银台SDK的字符串 + * @param $request SDK接口的请求参数对象 + * @return string + * @author guofa.tgf + */ + public function sdkExecute($request) { + + $this->setupCharsets($request); + + $params['app_id'] = $this->appId; + $params['method'] = $request->getApiMethodName(); + $params['format'] = $this->format; + $params['sign_type'] = $this->signType; + $params['timestamp'] = date("Y-m-d H:i:s"); + $params['alipay_sdk'] = $this->alipaySdkVersion; + $params['charset'] = $this->postCharset; + + $version = $request->getApiVersion(); + $params['version'] = $this->checkEmpty($version) ? $this->apiVersion : $version; + + if ($notify_url = $request->getNotifyUrl()) { + $params['notify_url'] = $notify_url; + } + + $dict = $request->getApiParas(); + $params['biz_content'] = $dict['biz_content']; + + ksort($params); + + $params['sign'] = $this->generateSign($params, $this->signType); + + foreach ($params as &$value) { + $value = $this->characet($value, $params['charset']); + } + + return http_build_query($params); + } + + /* + 页面提交执行方法 + @param:跳转类接口的request; $httpmethod 提交方式。两个值可选:post、get + @return:构建好的、签名后的最终跳转URL(GET)或String形式的form(POST) + auther:笙默 + */ + public function pageExecute($request,$httpmethod = "POST") { + + $this->setupCharsets($request); + + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); + throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); + } + + $iv=null; + + if(!$this->checkEmpty($request->getApiVersion())){ + $iv=$request->getApiVersion(); + }else{ + $iv=$this->apiVersion; + } + + //组装系统参数 + $sysParams["app_id"] = $this->appId; + $sysParams["version"] = $iv; + $sysParams["format"] = $this->format; + $sysParams["sign_type"] = $this->signType; + $sysParams["method"] = $request->getApiMethodName(); + $sysParams["timestamp"] = date("Y-m-d H:i:s"); + $sysParams["alipay_sdk"] = $this->alipaySdkVersion; + $sysParams["terminal_type"] = $request->getTerminalType(); + $sysParams["terminal_info"] = $request->getTerminalInfo(); + $sysParams["prod_code"] = $request->getProdCode(); + $sysParams["notify_url"] = $request->getNotifyUrl(); + $sysParams["return_url"] = $request->getReturnUrl(); + $sysParams["charset"] = $this->postCharset; + + //获取业务参数 + $apiParams = $request->getApiParas(); + + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + $sysParams["encrypt_type"] = $this->encryptType; + + if ($this->checkEmpty($apiParams['biz_content'])) { + + throw new Exception(" api request Fail! The reason : encrypt request is not supperted!"); + } + + if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { + + throw new Exception(" encryptType and encryptKey must not null! "); + } + + if ("AES" != $this->encryptType) { + + throw new Exception("加密类型只支持AES"); + } + + // 执行加密 + $enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey); + $apiParams['biz_content'] = $enCryptContent; + + } + + //print_r($apiParams); + $totalParams = array_merge($apiParams, $sysParams); + + //待签名字符串 + $preSignStr = $this->getSignContent($totalParams); + + //签名 + $totalParams["sign"] = $this->generateSign($totalParams, $this->signType); + + if ("GET" == strtoupper($httpmethod)) { + + //value做urlencode + $preString=$this->getSignContentUrlencode($totalParams); + //拼接GET请求串 + $requestUrl = $this->gatewayUrl."?".$preString; + + return $requestUrl; + } else { + //拼接表单字符串 + return $this->buildRequestForm($totalParams); + } + + + } + + + + /** + * 建立请求,以表单HTML形式构造(默认) + * @param $para_temp 请求参数数组 + * @return 提交表单HTML文本 + */ + protected function buildRequestForm($para_temp) { + + $sHtml = "
"; + while (list ($key, $val) = each ($para_temp)) { + if (false === $this->checkEmpty($val)) { + //$val = $this->characet($val, $this->postCharset); + $val = str_replace("'","'",$val); + //$val = str_replace("\"",""",$val); + $sHtml.= ""; + } + } + + //submit按钮控件请不要含有name属性 + $sHtml = $sHtml."
"; + + $sHtml = $sHtml.""; + + return $sHtml; + } + + + public function execute($request, $authToken = null, $appInfoAuthtoken = null) { + + $this->setupCharsets($request); + + // // 如果两者编码不一致,会出现签名验签或者乱码 + if (strcasecmp($this->fileCharset, $this->postCharset)) { + + // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); + throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); + } + + $iv = null; + + if (!$this->checkEmpty($request->getApiVersion())) { + $iv = $request->getApiVersion(); + } else { + $iv = $this->apiVersion; + } + + + //组装系统参数 + $sysParams["app_id"] = $this->appId; + $sysParams["version"] = $iv; + $sysParams["format"] = $this->format; + $sysParams["sign_type"] = $this->signType; + $sysParams["method"] = $request->getApiMethodName(); + $sysParams["timestamp"] = date("Y-m-d H:i:s"); + $sysParams["auth_token"] = $authToken; + $sysParams["alipay_sdk"] = $this->alipaySdkVersion; + $sysParams["terminal_type"] = $request->getTerminalType(); + $sysParams["terminal_info"] = $request->getTerminalInfo(); + $sysParams["prod_code"] = $request->getProdCode(); + $sysParams["notify_url"] = $request->getNotifyUrl(); + $sysParams["charset"] = $this->postCharset; + $sysParams["app_auth_token"] = $appInfoAuthtoken; + + + //获取业务参数 + $apiParams = $request->getApiParas(); + + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + $sysParams["encrypt_type"] = $this->encryptType; + + if ($this->checkEmpty($apiParams['biz_content'])) { + + throw new Exception(" api request Fail! The reason : encrypt request is not supperted!"); + } + + if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { + + throw new Exception(" encryptType and encryptKey must not null! "); + } + + if ("AES" != $this->encryptType) { + + throw new Exception("加密类型只支持AES"); + } + + // 执行加密 + $enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey); + $apiParams['biz_content'] = $enCryptContent; + + } + + + //签名 + $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType); + + + //系统参数放入GET请求串 + $requestUrl = $this->gatewayUrl . "?"; + foreach ($sysParams as $sysParamKey => $sysParamValue) { + $requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&"; + } + $requestUrl = substr($requestUrl, 0, -1); + + + //发起HTTP请求 + try { + $resp = $this->curl($requestUrl, $apiParams); + } catch (Exception $e) { + + $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage()); + return false; + } + + //解析AOP返回结果 + $respWellFormed = false; + + + // 将返回结果转换本地文件编码 + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + + + + $signData = null; + + if ("json" == $this->format) { + + $respObject = json_decode($r); + if (null !== $respObject) { + $respWellFormed = true; + $signData = $this->parserJSONSignData($request, $resp, $respObject); + } + } else if ("xml" == $this->format) { + + $respObject = @ simplexml_load_string($resp); + if (false !== $respObject) { + $respWellFormed = true; + + $signData = $this->parserXMLSignData($request, $resp); + } + } + + + //返回的HTTP文本不是标准JSON或者XML,记下错误日志 + if (false === $respWellFormed) { + $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_RESPONSE_NOT_WELL_FORMED", $resp); + return false; + } + + // 验签 + $this->checkResponseSign($request, $signData, $resp, $respObject); + + // 解密 + if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ + + if ("json" == $this->format) { + + + $resp = $this->encryptJSONSignSource($request, $resp); + + // 将返回结果转换本地文件编码 + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + $respObject = json_decode($r); + }else{ + + $resp = $this->encryptXMLSignSource($request, $resp); + + $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); + $respObject = @ simplexml_load_string($r); + + } + } + + return $respObject; + } + + /** + * 转换字符集编码 + * @param $data + * @param $targetCharset + * @return string + */ + function characet($data, $targetCharset) { + + if (!empty($data)) { + $fileType = $this->fileCharset; + if (strcasecmp($fileType, $targetCharset) != 0) { + $data = mb_convert_encoding($data, $targetCharset, $fileType); + // $data = iconv($fileType, $targetCharset.'//IGNORE', $data); + } + } + + + return $data; + } + + public function exec($paramsArray) { + if (!isset ($paramsArray["method"])) { + trigger_error("No api name passed"); + } + $inflector = new LtInflector; + $inflector->conf["separator"] = "."; + $requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request"; + if (!class_exists($requestClassName)) { + trigger_error("No such api: " . $paramsArray["method"]); + } + + $session = isset ($paramsArray["session"]) ? $paramsArray["session"] : null; + + $req = new $requestClassName; + foreach ($paramsArray as $paraKey => $paraValue) { + $inflector->conf["separator"] = "_"; + $setterMethodName = $inflector->camelize($paraKey); + $inflector->conf["separator"] = "."; + $setterMethodName = "set" . $inflector->camelize($setterMethodName); + if (method_exists($req, $setterMethodName)) { + $req->$setterMethodName ($paraValue); + } + } + return $this->execute($req, $session); + } + + /** + * 校验$value是否非空 + * if not set ,return true; + * if is null , return true; + **/ + protected function checkEmpty($value) { + if (!isset($value)) + return true; + if ($value === null) + return true; + if (trim($value) === "") + return true; + + return false; + } + + /** rsaCheckV1 & rsaCheckV2 + * 验证签名 + * 在使用本方法前,必须初始化AopClient且传入公钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') { + $sign = $params['sign']; + $params['sign_type'] = null; + $params['sign'] = null; + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); + } + public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') { + $sign = $params['sign']; + $params['sign'] = null; + return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); + } + + function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') { + + if($this->checkEmpty($this->alipayPublicKey)){ + + $pubKey= $this->alipayrsaPublicKey; + $res = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + }else { + //读取公钥文件 + $pubKey = file_get_contents($rsaPublicKeyFilePath); + //转换为openssl格式密钥 + $res = openssl_get_publickey($pubKey); + } + + ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); + + //调用openssl内置方法验签,返回bool值 + + if ("RSA2" == $signType) { + $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); + } else { + $result = (bool)openssl_verify($data, base64_decode($sign), $res); + } + + if(!$this->checkEmpty($this->alipayPublicKey)) { + //释放资源 + openssl_free_key($res); + } + + return $result; + } + +/** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function checkSignAndDecrypt($params, $rsaPublicKeyPem, $rsaPrivateKeyPem, $isCheckSign, $isDecrypt, $signType='RSA') { + $charset = $params['charset']; + $bizContent = $params['biz_content']; + if ($isCheckSign) { + if (!$this->rsaCheckV2($params, $rsaPublicKeyPem, $signType)) { + echo "
checkSign failure
"; + exit; + } + } + if ($isDecrypt) { + return $this->rsaDecrypt($bizContent, $rsaPrivateKeyPem, $charset); + } + + return $bizContent; + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function encryptAndSign($bizContent, $rsaPublicKeyPem, $rsaPrivateKeyPem, $charset, $isEncrypt, $isSign, $signType='RSA') { + // 加密,并签名 + if ($isEncrypt && $isSign) { + $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); + $sign = $this->sign($encrypted, $signType); + $response = "$encryptedRSA$sign$signType"; + return $response; + } + // 加密,不签名 + if ($isEncrypt && (!$isSign)) { + $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); + $response = "$encrypted$signType"; + return $response; + } + // 不加密,但签名 + if ((!$isEncrypt) && $isSign) { + $sign = $this->sign($bizContent, $signType); + $response = "$bizContent$sign$signType"; + return $response; + } + // 不加密,不签名 + $response = "$bizContent"; + return $response; + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaEncrypt($data, $rsaPublicKeyPem, $charset) { + if($this->checkEmpty($this->alipayPublicKey)){ + //读取字符串 + $pubKey= $this->alipayrsaPublicKey; + $res = "-----BEGIN PUBLIC KEY-----\n" . + wordwrap($pubKey, 64, "\n", true) . + "\n-----END PUBLIC KEY-----"; + }else { + //读取公钥文件 + $pubKey = file_get_contents($rsaPublicKeyFilePath); + //转换为openssl格式密钥 + $res = openssl_get_publickey($pubKey); + } + + ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); + $blocks = $this->splitCN($data, 0, 30, $charset); + $chrtext  = null; + $encodes  = array(); + foreach ($blocks as $n => $block) { + if (!openssl_public_encrypt($block, $chrtext , $res)) { + echo "
" . openssl_error_string() . "
"; + } + $encodes[] = $chrtext ; + } + $chrtext = implode(",", $encodes); + + return base64_encode($chrtext); + } + + /** + * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 + * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 + **/ + public function rsaDecrypt($data, $rsaPrivateKeyPem, $charset) { + + if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ + //读字符串 + $priKey=$this->rsaPrivateKey; + $res = "-----BEGIN RSA PRIVATE KEY-----\n" . + wordwrap($priKey, 64, "\n", true) . + "\n-----END RSA PRIVATE KEY-----"; + }else { + $priKey = file_get_contents($this->rsaPrivateKeyFilePath); + $res = openssl_get_privatekey($priKey); + } + ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); + //转换为openssl格式密钥 + $decodes = explode(',', $data); + $strnull = ""; + $dcyCont = ""; + foreach ($decodes as $n => $decode) { + if (!openssl_private_decrypt($decode, $dcyCont, $res)) { + echo "
" . openssl_error_string() . "
"; + } + $strnull .= $dcyCont; + } + return $strnull; + } + + function splitCN($cont, $n = 0, $subnum, $charset) { + //$len = strlen($cont) / 3; + $arrr = array(); + for ($i = $n; $i < strlen($cont); $i += $subnum) { + $res = $this->subCNchar($cont, $i, $subnum, $charset); + if (!empty ($res)) { + $arrr[] = $res; + } + } + + return $arrr; + } + + function subCNchar($str, $start = 0, $length, $charset = "gbk") { + if (strlen($str) <= $length) { + return $str; + } + $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; + $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; + $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; + preg_match_all($re[$charset], $str, $match); + $slice = join("", array_slice($match[0], $start, $length)); + return $slice; + } + + function parserResponseSubCode($request, $responseContent, $respObject, $format) { + + if ("json" == $format) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + $errorNodeName = $this->ERROR_RESPONSE; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $errorNodeName); + + if ($rootIndex > 0) { + // 内部节点对象 + $rInnerObject = $respObject->$rootNodeName; + } elseif ($errorIndex > 0) { + + $rInnerObject = $respObject->$errorNodeName; + } else { + return null; + } + + // 存在属性则返回对应值 + if (isset($rInnerObject->sub_code)) { + + return $rInnerObject->sub_code; + } else { + + return null; + } + + + } elseif ("xml" == $format) { + + // xml格式sub_code在同一层级 + return $respObject->sub_code; + + } + + + } + + function parserJSONSignData($request, $responseContent, $responseJSON) { + + $signData = new SignData(); + + $signData->sign = $this->parserJSONSign($responseJSON); + $signData->signSourceData = $this->parserJSONSignSource($request, $responseContent); + + + return $signData; + + } + + function parserJSONSignSource($request, $responseContent) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + + + if ($rootIndex > 0) { + + return $this->parserJSONSource($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserJSONSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + function parserJSONSource($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; + $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + $indexLen = $signDataEndIndex - $signDataStartIndex; + if ($indexLen < 0) { + + return null; + } + + return substr($responseContent, $signDataStartIndex, $indexLen); + + } + + function parserJSONSign($responseJSon) { + + return $responseJSon->sign; + } + + function parserXMLSignData($request, $responseContent) { + + + $signData = new SignData(); + + $signData->sign = $this->parserXMLSign($responseContent); + $signData->signSourceData = $this->parserXMLSignSource($request, $responseContent); + + + return $signData; + + + } + + function parserXMLSignSource($request, $responseContent) { + + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + // $this->echoDebug("
rootNodeName:" . $rootNodeName); + // $this->echoDebug("
responseContent:" . $responseContent . ""); + + + if ($rootIndex > 0) { + + return $this->parserXMLSource($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserXMLSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + function parserXMLSource($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; + $signIndex = strpos($responseContent, "<" . $this->SIGN_NODE_NAME . ">"); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + $indexLen = $signDataEndIndex - $signDataStartIndex + 1; + + if ($indexLen < 0) { + return null; + } + + + return substr($responseContent, $signDataStartIndex, $indexLen); + + + } + + function parserXMLSign($responseContent) { + $signNodeName = "<" . $this->SIGN_NODE_NAME . ">"; + $signEndNodeName = "SIGN_NODE_NAME . ">"; + + $indexOfSignNode = strpos($responseContent, $signNodeName); + $indexOfSignEndNode = strpos($responseContent, $signEndNodeName); + + + if ($indexOfSignNode < 0 || $indexOfSignEndNode < 0) { + return null; + } + + $nodeIndex = ($indexOfSignNode + strlen($signNodeName)); + + $indexLen = $indexOfSignEndNode - $nodeIndex; + + if ($indexLen < 0) { + return null; + } + + // 签名 + return substr($responseContent, $nodeIndex, $indexLen); + + } + + /** + * 验签 + * @param $request + * @param $signData + * @param $resp + * @param $respObject + * @throws Exception + */ + public function checkResponseSign($request, $signData, $resp, $respObject) { + + if (!$this->checkEmpty($this->alipayPublicKey) || !$this->checkEmpty($this->alipayrsaPublicKey)) { + + + if ($signData == null || $this->checkEmpty($signData->sign) || $this->checkEmpty($signData->signSourceData)) { + + throw new Exception(" check sign Fail! The reason : signData is Empty"); + } + + + // 获取结果sub_code + $responseSubCode = $this->parserResponseSubCode($request, $resp, $respObject, $this->format); + + + if (!$this->checkEmpty($responseSubCode) || ($this->checkEmpty($responseSubCode) && !$this->checkEmpty($signData->sign))) { + + $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); + + + if (!$checkResult) { + + if (strpos($signData->signSourceData, "\\/") > 0) { + + $signData->signSourceData = str_replace("\\/", "/", $signData->signSourceData); + + $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); + + if (!$checkResult) { + throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); + } + + } else { + + throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); + } + + } + } + + + } + } + + private function setupCharsets($request) { + if ($this->checkEmpty($this->postCharset)) { + $this->postCharset = 'UTF-8'; + } + $str = preg_match('/[\x80-\xff]/', $this->appId) ? $this->appId : print_r($request, true); + $this->fileCharset = mb_detect_encoding($str, "UTF-8, GBK") == 'UTF-8' ? 'UTF-8' : 'GBK'; + } + + // 获取加密内容 + + private function encryptJSONSignSource($request, $responseContent) { + + $parsetItem = $this->parserEncryptJSONSignSource($request, $responseContent); + + $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); + $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); + + $bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey); + return $bodyIndexContent . $bizContent . $bodyEndContent; + + } + + + private function parserEncryptJSONSignSource($request, $responseContent) { + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + + + if ($rootIndex > 0) { + + return $this->parserEncryptJSONItem($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserEncryptJSONItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + + private function parserEncryptJSONItem($responseContent, $nodeName, $nodeIndex) { + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; + $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); + // 签名前-逗号 + $signDataEndIndex = $signIndex - 1; + + if ($signDataEndIndex < 0) { + + $signDataEndIndex = strlen($responseContent)-1 ; + } + + $indexLen = $signDataEndIndex - $signDataStartIndex; + + $encContent = substr($responseContent, $signDataStartIndex+1, $indexLen-2); + + + $encryptParseItem = new EncryptParseItem(); + + $encryptParseItem->encryptContent = $encContent; + $encryptParseItem->startIndex = $signDataStartIndex; + $encryptParseItem->endIndex = $signDataEndIndex; + + return $encryptParseItem; + + } + + // 获取加密内容 + + private function encryptXMLSignSource($request, $responseContent) { + + $parsetItem = $this->parserEncryptXMLSignSource($request, $responseContent); + + $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); + $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); + $bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey); + + return $bodyIndexContent . $bizContent . $bodyEndContent; + + } + + private function parserEncryptXMLSignSource($request, $responseContent) { + + + $apiName = $request->getApiMethodName(); + $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; + + + $rootIndex = strpos($responseContent, $rootNodeName); + $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); + // $this->echoDebug("
rootNodeName:" . $rootNodeName); + // $this->echoDebug("
responseContent:" . $responseContent . ""); + + + if ($rootIndex > 0) { + + return $this->parserEncryptXMLItem($responseContent, $rootNodeName, $rootIndex); + } else if ($errorIndex > 0) { + + return $this->parserEncryptXMLItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); + } else { + + return null; + } + + + } + + private function parserEncryptXMLItem($responseContent, $nodeName, $nodeIndex) { + + $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; + + $xmlStartNode="<".$this->ENCRYPT_XML_NODE_NAME.">"; + $xmlEndNode="ENCRYPT_XML_NODE_NAME.">"; + + $indexOfXmlNode=strpos($responseContent,$xmlEndNode); + if($indexOfXmlNode<0){ + + $item = new EncryptParseItem(); + $item->encryptContent = null; + $item->startIndex = 0; + $item->endIndex = 0; + return $item; + } + + $startIndex=$signDataStartIndex+strlen($xmlStartNode); + $bizContentLen=$indexOfXmlNode-$startIndex; + $bizContent=substr($responseContent,$startIndex,$bizContentLen); + + $encryptParseItem = new EncryptParseItem(); + $encryptParseItem->encryptContent = $bizContent; + $encryptParseItem->startIndex = $signDataStartIndex; + $encryptParseItem->endIndex = $indexOfXmlNode+strlen($xmlEndNode); + + return $encryptParseItem; + + } + + + function echoDebug($content) { + + if ($this->debugInfo) { + echo "
" . $content; + } + + } + + +} \ No newline at end of file diff --git a/extend/app_alipay/aop/AopEncrypt.php b/extend/app_alipay/aop/AopEncrypt.php new file mode 100755 index 0000000..0ec4e5b --- /dev/null +++ b/extend/app_alipay/aop/AopEncrypt.php @@ -0,0 +1,71 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.advice.accept"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php b/extend/app_alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php new file mode 100755 index 0000000..ddf4385 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAccountExrateAllclientrateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.allclientrate.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAccountExrateRatequeryRequest.php b/extend/app_alipay/aop/request/AlipayAccountExrateRatequeryRequest.php new file mode 100755 index 0000000..47146c3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAccountExrateRatequeryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.ratequery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php b/extend/app_alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php new file mode 100755 index 0000000..dc2b2e1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAccountExrateTraderequestCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.account.exrate.traderequest.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquireCancelRequest.php b/extend/app_alipay/aop/request/AlipayAcquireCancelRequest.php new file mode 100755 index 0000000..6bb51d1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquireCancelRequest.php @@ -0,0 +1,171 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquireCloseRequest.php b/extend/app_alipay/aop/request/AlipayAcquireCloseRequest.php new file mode 100755 index 0000000..cbc31e9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquireCloseRequest.php @@ -0,0 +1,152 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.close"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquireCreateandpayRequest.php b/extend/app_alipay/aop/request/AlipayAcquireCreateandpayRequest.php new file mode 100755 index 0000000..70e1450 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquireCreateandpayRequest.php @@ -0,0 +1,550 @@ +alipayCaRequest = $alipayCaRequest; + $this->apiParas["alipay_ca_request"] = $alipayCaRequest; + } + + public function getAlipayCaRequest() + { + return $this->alipayCaRequest; + } + + public function setBody($body) + { + $this->body = $body; + $this->apiParas["body"] = $body; + } + + public function getBody() + { + return $this->body; + } + + public function setBuyerEmail($buyerEmail) + { + $this->buyerEmail = $buyerEmail; + $this->apiParas["buyer_email"] = $buyerEmail; + } + + public function getBuyerEmail() + { + return $this->buyerEmail; + } + + public function setBuyerId($buyerId) + { + $this->buyerId = $buyerId; + $this->apiParas["buyer_id"] = $buyerId; + } + + public function getBuyerId() + { + return $this->buyerId; + } + + public function setChannelParameters($channelParameters) + { + $this->channelParameters = $channelParameters; + $this->apiParas["channel_parameters"] = $channelParameters; + } + + public function getChannelParameters() + { + return $this->channelParameters; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setDynamicId($dynamicId) + { + $this->dynamicId = $dynamicId; + $this->apiParas["dynamic_id"] = $dynamicId; + } + + public function getDynamicId() + { + return $this->dynamicId; + } + + public function setDynamicIdType($dynamicIdType) + { + $this->dynamicIdType = $dynamicIdType; + $this->apiParas["dynamic_id_type"] = $dynamicIdType; + } + + public function getDynamicIdType() + { + return $this->dynamicIdType; + } + + public function setExtendParams($extendParams) + { + $this->extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setFormatType($formatType) + { + $this->formatType = $formatType; + $this->apiParas["format_type"] = $formatType; + } + + public function getFormatType() + { + return $this->formatType; + } + + public function setGoodsDetail($goodsDetail) + { + $this->goodsDetail = $goodsDetail; + $this->apiParas["goods_detail"] = $goodsDetail; + } + + public function getGoodsDetail() + { + return $this->goodsDetail; + } + + public function setItBPay($itBPay) + { + $this->itBPay = $itBPay; + $this->apiParas["it_b_pay"] = $itBPay; + } + + public function getItBPay() + { + return $this->itBPay; + } + + public function setMcardParameters($mcardParameters) + { + $this->mcardParameters = $mcardParameters; + $this->apiParas["mcard_parameters"] = $mcardParameters; + } + + public function getMcardParameters() + { + return $this->mcardParameters; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPrice($price) + { + $this->price = $price; + $this->apiParas["price"] = $price; + } + + public function getPrice() + { + return $this->price; + } + + public function setQuantity($quantity) + { + $this->quantity = $quantity; + $this->apiParas["quantity"] = $quantity; + } + + public function getQuantity() + { + return $this->quantity; + } + + public function setRefIds($refIds) + { + $this->refIds = $refIds; + $this->apiParas["ref_ids"] = $refIds; + } + + public function getRefIds() + { + return $this->refIds; + } + + public function setRoyaltyParameters($royaltyParameters) + { + $this->royaltyParameters = $royaltyParameters; + $this->apiParas["royalty_parameters"] = $royaltyParameters; + } + + public function getRoyaltyParameters() + { + return $this->royaltyParameters; + } + + public function setRoyaltyType($royaltyType) + { + $this->royaltyType = $royaltyType; + $this->apiParas["royalty_type"] = $royaltyType; + } + + public function getRoyaltyType() + { + return $this->royaltyType; + } + + public function setSellerEmail($sellerEmail) + { + $this->sellerEmail = $sellerEmail; + $this->apiParas["seller_email"] = $sellerEmail; + } + + public function getSellerEmail() + { + return $this->sellerEmail; + } + + public function setSellerId($sellerId) + { + $this->sellerId = $sellerId; + $this->apiParas["seller_id"] = $sellerId; + } + + public function getSellerId() + { + return $this->sellerId; + } + + public function setShowUrl($showUrl) + { + $this->showUrl = $showUrl; + $this->apiParas["show_url"] = $showUrl; + } + + public function getShowUrl() + { + return $this->showUrl; + } + + public function setSubject($subject) + { + $this->subject = $subject; + $this->apiParas["subject"] = $subject; + } + + public function getSubject() + { + return $this->subject; + } + + public function setTotalFee($totalFee) + { + $this->totalFee = $totalFee; + $this->apiParas["total_fee"] = $totalFee; + } + + public function getTotalFee() + { + return $this->totalFee; + } + + public function getApiMethodName() + { + return "alipay.acquire.createandpay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquirePrecreateRequest.php b/extend/app_alipay/aop/request/AlipayAcquirePrecreateRequest.php new file mode 100755 index 0000000..09ee9de --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquirePrecreateRequest.php @@ -0,0 +1,402 @@ +body = $body; + $this->apiParas["body"] = $body; + } + + public function getBody() + { + return $this->body; + } + + public function setChannelParameters($channelParameters) + { + $this->channelParameters = $channelParameters; + $this->apiParas["channel_parameters"] = $channelParameters; + } + + public function getChannelParameters() + { + return $this->channelParameters; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setExtendParams($extendParams) + { + $this->extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setGoodsDetail($goodsDetail) + { + $this->goodsDetail = $goodsDetail; + $this->apiParas["goods_detail"] = $goodsDetail; + } + + public function getGoodsDetail() + { + return $this->goodsDetail; + } + + public function setItBPay($itBPay) + { + $this->itBPay = $itBPay; + $this->apiParas["it_b_pay"] = $itBPay; + } + + public function getItBPay() + { + return $this->itBPay; + } + + public function setOperatorCode($operatorCode) + { + $this->operatorCode = $operatorCode; + $this->apiParas["operator_code"] = $operatorCode; + } + + public function getOperatorCode() + { + return $this->operatorCode; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPrice($price) + { + $this->price = $price; + $this->apiParas["price"] = $price; + } + + public function getPrice() + { + return $this->price; + } + + public function setQuantity($quantity) + { + $this->quantity = $quantity; + $this->apiParas["quantity"] = $quantity; + } + + public function getQuantity() + { + return $this->quantity; + } + + public function setRoyaltyParameters($royaltyParameters) + { + $this->royaltyParameters = $royaltyParameters; + $this->apiParas["royalty_parameters"] = $royaltyParameters; + } + + public function getRoyaltyParameters() + { + return $this->royaltyParameters; + } + + public function setRoyaltyType($royaltyType) + { + $this->royaltyType = $royaltyType; + $this->apiParas["royalty_type"] = $royaltyType; + } + + public function getRoyaltyType() + { + return $this->royaltyType; + } + + public function setSellerEmail($sellerEmail) + { + $this->sellerEmail = $sellerEmail; + $this->apiParas["seller_email"] = $sellerEmail; + } + + public function getSellerEmail() + { + return $this->sellerEmail; + } + + public function setSellerId($sellerId) + { + $this->sellerId = $sellerId; + $this->apiParas["seller_id"] = $sellerId; + } + + public function getSellerId() + { + return $this->sellerId; + } + + public function setShowUrl($showUrl) + { + $this->showUrl = $showUrl; + $this->apiParas["show_url"] = $showUrl; + } + + public function getShowUrl() + { + return $this->showUrl; + } + + public function setSubject($subject) + { + $this->subject = $subject; + $this->apiParas["subject"] = $subject; + } + + public function getSubject() + { + return $this->subject; + } + + public function setTotalFee($totalFee) + { + $this->totalFee = $totalFee; + $this->apiParas["total_fee"] = $totalFee; + } + + public function getTotalFee() + { + return $this->totalFee; + } + + public function getApiMethodName() + { + return "alipay.acquire.precreate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquireQueryRequest.php b/extend/app_alipay/aop/request/AlipayAcquireQueryRequest.php new file mode 100755 index 0000000..43cc337 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquireQueryRequest.php @@ -0,0 +1,136 @@ +outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAcquireRefundRequest.php b/extend/app_alipay/aop/request/AlipayAcquireRefundRequest.php new file mode 100755 index 0000000..77a3947 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAcquireRefundRequest.php @@ -0,0 +1,236 @@ +operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setOutRequestNo($outRequestNo) + { + $this->outRequestNo = $outRequestNo; + $this->apiParas["out_request_no"] = $outRequestNo; + } + + public function getOutRequestNo() + { + return $this->outRequestNo; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setRefIds($refIds) + { + $this->refIds = $refIds; + $this->apiParas["ref_ids"] = $refIds; + } + + public function getRefIds() + { + return $this->refIds; + } + + public function setRefundAmount($refundAmount) + { + $this->refundAmount = $refundAmount; + $this->apiParas["refund_amount"] = $refundAmount; + } + + public function getRefundAmount() + { + return $this->refundAmount; + } + + public function setRefundReason($refundReason) + { + $this->refundReason = $refundReason; + $this->apiParas["refund_reason"] = $refundReason; + } + + public function getRefundReason() + { + return $this->refundReason; + } + + public function setTradeNo($tradeNo) + { + $this->tradeNo = $tradeNo; + $this->apiParas["trade_no"] = $tradeNo; + } + + public function getTradeNo() + { + return $this->tradeNo; + } + + public function getApiMethodName() + { + return "alipay.acquire.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAppTokenGetRequest.php b/extend/app_alipay/aop/request/AlipayAppTokenGetRequest.php new file mode 100755 index 0000000..91724ef --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAppTokenGetRequest.php @@ -0,0 +1,118 @@ +secret = $secret; + $this->apiParas["secret"] = $secret; + } + + public function getSecret() + { + return $this->secret; + } + + public function getApiMethodName() + { + return "alipay.app.token.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php b/extend/app_alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php new file mode 100755 index 0000000..18c4a63 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAssetPointBalanceQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php b/extend/app_alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php new file mode 100755 index 0000000..d07b3cd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAssetPointBudgetQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAssetPointOrderCreateRequest.php b/extend/app_alipay/aop/request/AlipayAssetPointOrderCreateRequest.php new file mode 100755 index 0000000..8c737dd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAssetPointOrderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.asset.point.order.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayAssetPointOrderQueryRequest.php b/extend/app_alipay/aop/request/AlipayAssetPointOrderQueryRequest.php new file mode 100755 index 0000000..014bc92 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayAssetPointOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.asset.point.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayBossCsChannelQueryRequest.php b/extend/app_alipay/aop/request/AlipayBossCsChannelQueryRequest.php new file mode 100755 index 0000000..2f4ec2c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayBossCsChannelQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.boss.cs.channel.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayBossFncXwbtestRetModifyRequest.php b/extend/app_alipay/aop/request/AlipayBossFncXwbtestRetModifyRequest.php new file mode 100755 index 0000000..a1355c7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayBossFncXwbtestRetModifyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php b/extend/app_alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php new file mode 100755 index 0000000..7a22bca --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayBossProdArrangementOfflineQueryRequest.php @@ -0,0 +1,118 @@ +productCode = $productCode; + $this->apiParas["product_code"] = $productCode; + } + + public function getProductCode() + { + return $this->productCode; + } + + public function getApiMethodName() + { + return "alipay.boss.prod.arrangement.offline.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceAirXfgDsgModifyRequest.php b/extend/app_alipay/aop/request/AlipayCommerceAirXfgDsgModifyRequest.php new file mode 100755 index 0000000..ef1ec59 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceAirXfgDsgModifyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php new file mode 100755 index 0000000..efad1c1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorCityQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php new file mode 100755 index 0000000..73f5043 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php new file mode 100755 index 0000000..d64f385 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php new file mode 100755 index 0000000..560c3dc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorDepositQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.deposit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php new file mode 100755 index 0000000..e95bb03 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorFunctionQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.function.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php new file mode 100755 index 0000000..60aa1f6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorScriptQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.script.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php new file mode 100755 index 0000000..f76f5ad --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorStationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.station.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php new file mode 100755 index 0000000..07b0de2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php new file mode 100755 index 0000000..a489b69 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php new file mode 100755 index 0000000..2a58e80 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php new file mode 100755 index 0000000..46293a7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherGenerateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.generate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php new file mode 100755 index 0000000..9cfe8fe --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php new file mode 100755 index 0000000..5eb4a2e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php new file mode 100755 index 0000000..7e9d124 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceCityfacilitatorVoucherUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.cityfacilitator.voucher.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php b/extend/app_alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php new file mode 100755 index 0000000..1faaf5c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceDataMonitordataSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.data.monitordata.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php b/extend/app_alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php new file mode 100755 index 0000000..8df3227 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceEducateStudentinfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceIotDeviceserviceCancelRequest.php b/extend/app_alipay/aop/request/AlipayCommerceIotDeviceserviceCancelRequest.php new file mode 100755 index 0000000..5c42762 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceIotDeviceserviceCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.iot.deviceservice.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php b/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php new file mode 100755 index 0000000..63dcf31 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.lottery.present.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php new file mode 100755 index 0000000..3c09f5f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceLotteryPresentlistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.lottery.presentlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php new file mode 100755 index 0000000..0af1a4d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceLotteryTypelistQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php new file mode 100755 index 0000000..0c1fb0b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayKeyQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php new file mode 100755 index 0000000..ab97f7d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayRecordVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.transport.offlinepay.record.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php new file mode 100755 index 0000000..de6925a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayCommerceTransportOfflinepayUserblacklistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.commerce.transport.offlinepay.userblacklist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderCancelRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderCancelRequest.php new file mode 100755 index 0000000..dabd8e5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php new file mode 100755 index 0000000..e3db2ae --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderModifyRequest.php new file mode 100755 index 0000000..8fa97ab --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderQueryRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderQueryRequest.php new file mode 100755 index 0000000..817cd39 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderRefundRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderRefundRequest.php new file mode 100755 index 0000000..d96a8f8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php new file mode 100755 index 0000000..3813240 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderRefuseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.refuse"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php new file mode 100755 index 0000000..f14d4b0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderSpModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.sp.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiOrderTransferRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiOrderTransferRequest.php new file mode 100755 index 0000000..96fe8aa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiOrderTransferRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.order.transfer"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiServiceModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiServiceModifyRequest.php new file mode 100755 index 0000000..d419812 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiServiceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.service.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php new file mode 100755 index 0000000..ef567df --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiServicePriceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.service.price.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiSpModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiSpModifyRequest.php new file mode 100755 index 0000000..9094ca3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiSpModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.sp.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php b/extend/app_alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php new file mode 100755 index 0000000..d64d7f5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDaoweiSpScheduleModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.daowei.sp.schedule.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php b/extend/app_alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php new file mode 100755 index 0000000..bcb8857 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataBillDownloadurlGetRequest.php @@ -0,0 +1,134 @@ +billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillType($billType) + { + $this->billType = $billType; + $this->apiParas["bill_type"] = $billType; + } + + public function getBillType() + { + return $this->billType; + } + + public function getApiMethodName() + { + return "alipay.data.bill.downloadurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php b/extend/app_alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php new file mode 100755 index 0000000..5111190 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataexchangeSfasdfRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataexchange.sfasdf"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php new file mode 100755 index 0000000..b73d2ba --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.bill.downloadurl.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php new file mode 100755 index 0000000..6d819cd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceChinaremodelQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.chinaremodel.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php new file mode 100755 index 0000000..83237a7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceCodeRecoRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.code.reco"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php new file mode 100755 index 0000000..fdf6f38 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceSdfsdfRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php new file mode 100755 index 0000000..e35bc75 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.shoppingmallrec.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php new file mode 100755 index 0000000..3694463 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceShoppingmallrecVoucherQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.shoppingmallrec.voucher.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php b/extend/app_alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php new file mode 100755 index 0000000..eafff18 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayDataDataserviceUserlevelZrankGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.data.dataservice.userlevel.zrank.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppBillAddRequest.php b/extend/app_alipay/aop/request/AlipayEbppBillAddRequest.php new file mode 100755 index 0000000..35ddc8b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppBillAddRequest.php @@ -0,0 +1,326 @@ +bankBillNo = $bankBillNo; + $this->apiParas["bank_bill_no"] = $bankBillNo; + } + + public function getBankBillNo() + { + return $this->bankBillNo; + } + + public function setBillDate($billDate) + { + $this->billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setMobile($mobile) + { + $this->mobile = $mobile; + $this->apiParas["mobile"] = $mobile; + } + + public function getMobile() + { + return $this->mobile; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setOwnerName($ownerName) + { + $this->ownerName = $ownerName; + $this->apiParas["owner_name"] = $ownerName; + } + + public function getOwnerName() + { + return $this->ownerName; + } + + public function setPayAmount($payAmount) + { + $this->payAmount = $payAmount; + $this->apiParas["pay_amount"] = $payAmount; + } + + public function getPayAmount() + { + return $this->payAmount; + } + + public function setServiceAmount($serviceAmount) + { + $this->serviceAmount = $serviceAmount; + $this->apiParas["service_amount"] = $serviceAmount; + } + + public function getServiceAmount() + { + return $this->serviceAmount; + } + + public function setSubOrderType($subOrderType) + { + $this->subOrderType = $subOrderType; + $this->apiParas["sub_order_type"] = $subOrderType; + } + + public function getSubOrderType() + { + return $this->subOrderType; + } + + public function setTrafficLocation($trafficLocation) + { + $this->trafficLocation = $trafficLocation; + $this->apiParas["traffic_location"] = $trafficLocation; + } + + public function getTrafficLocation() + { + return $this->trafficLocation; + } + + public function setTrafficRegulations($trafficRegulations) + { + $this->trafficRegulations = $trafficRegulations; + $this->apiParas["traffic_regulations"] = $trafficRegulations; + } + + public function getTrafficRegulations() + { + return $this->trafficRegulations; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppBillGetRequest.php b/extend/app_alipay/aop/request/AlipayEbppBillGetRequest.php new file mode 100755 index 0000000..a7b64a5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppBillGetRequest.php @@ -0,0 +1,134 @@ +merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppBillSearchRequest.php b/extend/app_alipay/aop/request/AlipayEbppBillSearchRequest.php new file mode 100755 index 0000000..6ffc3f0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppBillSearchRequest.php @@ -0,0 +1,215 @@ +billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setChargeoffInst($chargeoffInst) + { + $this->chargeoffInst = $chargeoffInst; + $this->apiParas["chargeoff_inst"] = $chargeoffInst; + } + + public function getChargeoffInst() + { + return $this->chargeoffInst; + } + + public function setCompanyId($companyId) + { + $this->companyId = $companyId; + $this->apiParas["company_id"] = $companyId; + } + + public function getCompanyId() + { + return $this->companyId; + } + + public function setExtend($extend) + { + $this->extend = $extend; + $this->apiParas["extend"] = $extend; + } + + public function getExtend() + { + return $this->extend; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setSubOrderType($subOrderType) + { + $this->subOrderType = $subOrderType; + $this->apiParas["sub_order_type"] = $subOrderType; + } + + public function getSubOrderType() + { + return $this->subOrderType; + } + + public function getApiMethodName() + { + return "alipay.ebpp.bill.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppInvoiceInfoSendRequest.php b/extend/app_alipay/aop/request/AlipayEbppInvoiceInfoSendRequest.php new file mode 100755 index 0000000..457ecfc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppInvoiceInfoSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.invoice.info.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppInvoiceMerchantlistEnterApplyRequest.php b/extend/app_alipay/aop/request/AlipayEbppInvoiceMerchantlistEnterApplyRequest.php new file mode 100755 index 0000000..d9962bf --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppInvoiceMerchantlistEnterApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.invoice.merchantlist.enter.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php b/extend/app_alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php new file mode 100755 index 0000000..e9bd700 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppInvoiceTitleListGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.invoice.title.list.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php b/extend/app_alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php new file mode 100755 index 0000000..d30f54c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppMerchantConfigGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php new file mode 100755 index 0000000..7aeb791 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductBillPayStatusRequest.php @@ -0,0 +1,134 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setOutOrderNo($outOrderNo) + { + $this->outOrderNo = $outOrderNo; + $this->apiParas["out_order_no"] = $outOrderNo; + } + + public function getOutOrderNo() + { + return $this->outOrderNo; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.bill.pay.status"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductPayRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductPayRequest.php new file mode 100755 index 0000000..db57df3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductPayRequest.php @@ -0,0 +1,297 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBillDate($billDate) + { + $this->billDate = $billDate; + $this->apiParas["bill_date"] = $billDate; + } + + public function getBillDate() + { + return $this->billDate; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setFineAmount($fineAmount) + { + $this->fineAmount = $fineAmount; + $this->apiParas["fine_amount"] = $fineAmount; + } + + public function getFineAmount() + { + return $this->fineAmount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setOutOrderNo($outOrderNo) + { + $this->outOrderNo = $outOrderNo; + $this->apiParas["out_order_no"] = $outOrderNo; + } + + public function getOutOrderNo() + { + return $this->outOrderNo; + } + + public function setPayAmount($payAmount) + { + $this->payAmount = $payAmount; + $this->apiParas["pay_amount"] = $payAmount; + } + + public function getPayAmount() + { + return $this->payAmount; + } + + public function setPid($pid) + { + $this->pid = $pid; + $this->apiParas["pid"] = $pid; + } + + public function getPid() + { + return $this->pid; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductSignAddRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductSignAddRequest.php new file mode 100755 index 0000000..c0af4dc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductSignAddRequest.php @@ -0,0 +1,372 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setBillKey($billKey) + { + $this->billKey = $billKey; + $this->apiParas["bill_key"] = $billKey; + } + + public function getBillKey() + { + return $this->billKey; + } + + public function setBizType($bizType) + { + $this->bizType = $bizType; + $this->apiParas["biz_type"] = $bizType; + } + + public function getBizType() + { + return $this->bizType; + } + + public function setChargeInst($chargeInst) + { + $this->chargeInst = $chargeInst; + $this->apiParas["charge_inst"] = $chargeInst; + } + + public function getChargeInst() + { + return $this->chargeInst; + } + + public function setDeductType($deductType) + { + $this->deductType = $deductType; + $this->apiParas["deduct_type"] = $deductType; + } + + public function getDeductType() + { + return $this->deductType; + } + + public function setExtendField($extendField) + { + $this->extendField = $extendField; + $this->apiParas["extend_field"] = $extendField; + } + + public function getExtendField() + { + return $this->extendField; + } + + public function setNotifyConfig($notifyConfig) + { + $this->notifyConfig = $notifyConfig; + $this->apiParas["notify_config"] = $notifyConfig; + } + + public function getNotifyConfig() + { + return $this->notifyConfig; + } + + public function setOutAgreementId($outAgreementId) + { + $this->outAgreementId = $outAgreementId; + $this->apiParas["out_agreement_id"] = $outAgreementId; + } + + public function getOutAgreementId() + { + return $this->outAgreementId; + } + + public function setOwnerName($ownerName) + { + $this->ownerName = $ownerName; + $this->apiParas["owner_name"] = $ownerName; + } + + public function getOwnerName() + { + return $this->ownerName; + } + + public function setPayConfig($payConfig) + { + $this->payConfig = $payConfig; + $this->apiParas["pay_config"] = $payConfig; + } + + public function getPayConfig() + { + return $this->payConfig; + } + + public function setPayPasswordToken($payPasswordToken) + { + $this->payPasswordToken = $payPasswordToken; + $this->apiParas["pay_password_token"] = $payPasswordToken; + } + + public function getPayPasswordToken() + { + return $this->payPasswordToken; + } + + public function setPid($pid) + { + $this->pid = $pid; + $this->apiParas["pid"] = $pid; + } + + public function getPid() + { + return $this->pid; + } + + public function setSignExpireDate($signExpireDate) + { + $this->signExpireDate = $signExpireDate; + $this->apiParas["sign_expire_date"] = $signExpireDate; + } + + public function getSignExpireDate() + { + return $this->signExpireDate; + } + + public function setSubBizType($subBizType) + { + $this->subBizType = $subBizType; + $this->apiParas["sub_biz_type"] = $subBizType; + } + + public function getSubBizType() + { + return $this->subBizType; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php new file mode 100755 index 0000000..5244390 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductSignCancelRequest.php @@ -0,0 +1,182 @@ +agentChannel = $agentChannel; + $this->apiParas["agent_channel"] = $agentChannel; + } + + public function getAgentChannel() + { + return $this->agentChannel; + } + + public function setAgentCode($agentCode) + { + $this->agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setPayPasswordToken($payPasswordToken) + { + $this->payPasswordToken = $payPasswordToken; + $this->apiParas["pay_password_token"] = $payPasswordToken; + } + + public function getPayPasswordToken() + { + return $this->payPasswordToken; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php new file mode 100755 index 0000000..844e4a6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductSignQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php b/extend/app_alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php new file mode 100755 index 0000000..b734839 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEbppPdeductSignValidateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ebpp.pdeduct.sign.validate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodCreditGetRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodCreditGetRequest.php new file mode 100755 index 0000000..239987c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodCreditGetRequest.php @@ -0,0 +1,182 @@ +creditNo = $creditNo; + $this->apiParas["credit_no"] = $creditNo; + } + + public function getCreditNo() + { + return $this->creditNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.credit.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDataPutRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDataPutRequest.php new file mode 100755 index 0000000..690e1ff --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDataPutRequest.php @@ -0,0 +1,246 @@ +category = $category; + $this->apiParas["category"] = $category; + } + + public function getCategory() + { + return $this->category; + } + + public function setCharSet($charSet) + { + $this->charSet = $charSet; + $this->apiParas["char_set"] = $charSet; + } + + public function getCharSet() + { + return $this->charSet; + } + + public function setCollectingTaskId($collectingTaskId) + { + $this->collectingTaskId = $collectingTaskId; + $this->apiParas["collecting_task_id"] = $collectingTaskId; + } + + public function getCollectingTaskId() + { + return $this->collectingTaskId; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setEntityType($entityType) + { + $this->entityType = $entityType; + $this->apiParas["entity_type"] = $entityType; + } + + public function getEntityType() + { + return $this->entityType; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setJsonData($jsonData) + { + $this->jsonData = $jsonData; + $this->apiParas["json_data"] = $jsonData; + } + + public function getJsonData() + { + return $this->jsonData; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.data.put"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php new file mode 100755 index 0000000..4934936 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnContractGetRequest.php @@ -0,0 +1,182 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.contract.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php new file mode 100755 index 0000000..0e03549 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnDrawndnlistQueryRequest.php @@ -0,0 +1,182 @@ +creditNo = $creditNo; + $this->apiParas["credit_no"] = $creditNo; + } + + public function getCreditNo() + { + return $this->creditNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.drawndnlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php new file mode 100755 index 0000000..dfed150 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnFeerecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.feerecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php new file mode 100755 index 0000000..3e99721 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnLendingrecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.lendingrecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php new file mode 100755 index 0000000..1f90098 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnPaymentscheduleGetRequest.php @@ -0,0 +1,182 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.paymentschedule.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php new file mode 100755 index 0000000..b5d0c8a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcapiprodDrawndnRepaymentrecordQueryRequest.php @@ -0,0 +1,214 @@ +drawndnNo = $drawndnNo; + $this->apiParas["drawndn_no"] = $drawndnNo; + } + + public function getDrawndnNo() + { + return $this->drawndnNo; + } + + public function setEnd($end) + { + $this->end = $end; + $this->apiParas["end"] = $end; + } + + public function getEnd() + { + return $this->end; + } + + public function setEntityCode($entityCode) + { + $this->entityCode = $entityCode; + $this->apiParas["entity_code"] = $entityCode; + } + + public function getEntityCode() + { + return $this->entityCode; + } + + public function setEntityName($entityName) + { + $this->entityName = $entityName; + $this->apiParas["entity_name"] = $entityName; + } + + public function getEntityName() + { + return $this->entityName; + } + + public function setIsvCode($isvCode) + { + $this->isvCode = $isvCode; + $this->apiParas["isv_code"] = $isvCode; + } + + public function getIsvCode() + { + return $this->isvCode; + } + + public function setOrgCode($orgCode) + { + $this->orgCode = $orgCode; + $this->apiParas["org_code"] = $orgCode; + } + + public function getOrgCode() + { + return $this->orgCode; + } + + public function setStart($start) + { + $this->start = $start; + $this->apiParas["start"] = $start; + } + + public function getStart() + { + return $this->start; + } + + public function getApiMethodName() + { + return "alipay.ecapiprod.drawndn.repaymentrecord.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcardEduPublicBindRequest.php b/extend/app_alipay/aop/request/AlipayEcardEduPublicBindRequest.php new file mode 100755 index 0000000..2361d5a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcardEduPublicBindRequest.php @@ -0,0 +1,198 @@ +agentCode = $agentCode; + $this->apiParas["agent_code"] = $agentCode; + } + + public function getAgentCode() + { + return $this->agentCode; + } + + public function setAgreementId($agreementId) + { + $this->agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setAlipayUserId($alipayUserId) + { + $this->alipayUserId = $alipayUserId; + $this->apiParas["alipay_user_id"] = $alipayUserId; + } + + public function getAlipayUserId() + { + return $this->alipayUserId; + } + + public function setCardName($cardName) + { + $this->cardName = $cardName; + $this->apiParas["card_name"] = $cardName; + } + + public function getCardName() + { + return $this->cardName; + } + + public function setCardNo($cardNo) + { + $this->cardNo = $cardNo; + $this->apiParas["card_no"] = $cardNo; + } + + public function getCardNo() + { + return $this->cardNo; + } + + public function setPublicId($publicId) + { + $this->publicId = $publicId; + $this->apiParas["public_id"] = $publicId; + } + + public function getPublicId() + { + return $this->publicId; + } + + public function getApiMethodName() + { + return "alipay.ecard.edu.public.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php new file mode 100755 index 0000000..d34e083 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.basicservice.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php new file mode 100755 index 0000000..cf8eeef --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBasicserviceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.basicservice.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php new file mode 100755 index 0000000..de05617 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.batch.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php new file mode 100755 index 0000000..78c64c0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBillBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php new file mode 100755 index 0000000..e7712c3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBillDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php new file mode 100755 index 0000000..301ff6c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBillModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php new file mode 100755 index 0000000..403b6d6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeBillSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.bill.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php new file mode 100755 index 0000000..0b37b74 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php new file mode 100755 index 0000000..c63f0e9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php new file mode 100755 index 0000000..c6ee983 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityDetailsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.details.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php new file mode 100755 index 0000000..c866b26 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeCommunityModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.community.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php new file mode 100755 index 0000000..9eccc91 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeNoticeDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.notice.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php new file mode 100755 index 0000000..fb50ce5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeNoticePublishRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.notice.publish"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifePayResultQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifePayResultQueryRequest.php new file mode 100755 index 0000000..d972ad8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifePayResultQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.pay.result.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php new file mode 100755 index 0000000..1781883 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeRepairStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.repair.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php new file mode 100755 index 0000000..6ace275 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.residentinfo.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php new file mode 100755 index 0000000..6a2a1fe --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeResidentinfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.residentinfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php new file mode 100755 index 0000000..f939efb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php new file mode 100755 index 0000000..1a84501 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php new file mode 100755 index 0000000..601e772 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeRoominfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.roominfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php new file mode 100755 index 0000000..d38bb79 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeRooominfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.rooominfo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php new file mode 100755 index 0000000..e6e2eef --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoCplifeUseridentityStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.cplife.useridentity.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php new file mode 100755 index 0000000..5d09d74 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php new file mode 100755 index 0000000..9d66af7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php new file mode 100755 index 0000000..4bb9db3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtBillingSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.billing.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php new file mode 100755 index 0000000..a236da0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtSchoolinfoModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.schoolinfo.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php new file mode 100755 index 0000000..543bbc1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtStudentModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.student.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php new file mode 100755 index 0000000..c45e42d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoEduKtStudentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.edu.kt.student.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php new file mode 100755 index 0000000..f34a541 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarCarlibInfoPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.carlib.info.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php new file mode 100755 index 0000000..e59e273 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarCarmodelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.carmodel.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php new file mode 100755 index 0000000..38c7707 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.data.external.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php new file mode 100755 index 0000000..098ddf7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarDataExternalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.data.external.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php new file mode 100755 index 0000000..8f65aaa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarDataserviceViolationinfoShareRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.dataservice.violationinfo.share"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php new file mode 100755 index 0000000..e027163 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainDataUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.data.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php new file mode 100755 index 0000000..a602af6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.order.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php new file mode 100755 index 0000000..01394ee --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarMaintainOrderstatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.maintain.orderstatus.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php new file mode 100755 index 0000000..c71cf87 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarOrderStatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.order.status.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php new file mode 100755 index 0000000..b71a477 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingCardbarcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.cardbarcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php new file mode 100755 index 0000000..751450d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.config.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php new file mode 100755 index 0000000..dab75e8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingConfigSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.config.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php new file mode 100755 index 0000000..e73afe3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingEnterinfoSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.enterinfo.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php new file mode 100755 index 0000000..f2a61c9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingExitinfoSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.exitinfo.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php new file mode 100755 index 0000000..bab3389 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingLotbarcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.lotbarcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php new file mode 100755 index 0000000..91ce08d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.order.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php new file mode 100755 index 0000000..29934cc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.order.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php new file mode 100755 index 0000000..21e3d4f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingOrderstatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.orderstatus.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php new file mode 100755 index 0000000..c12e82b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.parkinglotinfo.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php new file mode 100755 index 0000000..a459096 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingParkinglotinfoUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.parkinglotinfo.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php new file mode 100755 index 0000000..4e46c8c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarParkingVehicleQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.parking.vehicle.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php new file mode 100755 index 0000000..b1ff240 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.ticket.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php new file mode 100755 index 0000000..fa29324 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarPromoTicketSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.ticket.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php new file mode 100755 index 0000000..5008445 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarPromoVoucherVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.promo.voucher.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php new file mode 100755 index 0000000..294ebc7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarTradeRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.trade.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php new file mode 100755 index 0000000..a621922 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarViolationCityPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.violation.city.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php b/extend/app_alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php new file mode 100755 index 0000000..6f3eb36 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoMycarViolationInfoPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.mycar.violation.info.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php b/extend/app_alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php new file mode 100755 index 0000000..3850003 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayEcoWelfareCodeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.eco.welfare.code.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php b/extend/app_alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php new file mode 100755 index 0000000..1a8746d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayExscUserCurrentsignGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.currentsign.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php b/extend/app_alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php new file mode 100755 index 0000000..8673a21 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayExscUserFirstfundinpourGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.firstfundinpour.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayExscUserFirstsignGetRequest.php b/extend/app_alipay/aop/request/AlipayExscUserFirstsignGetRequest.php new file mode 100755 index 0000000..8336bb0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayExscUserFirstsignGetRequest.php @@ -0,0 +1,118 @@ +alipayId = $alipayId; + $this->apiParas["alipay_id"] = $alipayId; + } + + public function getAlipayId() + { + return $this->alipayId; + } + + public function getApiMethodName() + { + return "alipay.exsc.user.firstsign.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php b/extend/app_alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php new file mode 100755 index 0000000..bd3c1d2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFlashsalesStockSyncUpdateRequest.php @@ -0,0 +1,150 @@ +outProductId = $outProductId; + $this->apiParas["out_product_id"] = $outProductId; + } + + public function getOutProductId() + { + return $this->outProductId; + } + + public function setPublicId($publicId) + { + $this->publicId = $publicId; + $this->apiParas["public_id"] = $publicId; + } + + public function getPublicId() + { + return $this->publicId; + } + + public function setStock($stock) + { + $this->stock = $stock; + $this->apiParas["stock"] = $stock; + } + + public function getStock() + { + return $this->stock; + } + + public function getApiMethodName() + { + return "alipay.flashsales.stock.sync.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundAuthOperationCancelRequest.php b/extend/app_alipay/aop/request/AlipayFundAuthOperationCancelRequest.php new file mode 100755 index 0000000..ac5ca28 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundAuthOperationCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.operation.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php b/extend/app_alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php new file mode 100755 index 0000000..09d9717 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundAuthOperationDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.operation.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php b/extend/app_alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php new file mode 100755 index 0000000..e64b3ba --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundAuthOrderFreezeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.freeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php b/extend/app_alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php new file mode 100755 index 0000000..35c9deb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundAuthOrderUnfreezeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.unfreeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php b/extend/app_alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php new file mode 100755 index 0000000..8dde24a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundAuthOrderVoucherCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.auth.order.voucher.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOperationQueryRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOperationQueryRequest.php new file mode 100755 index 0000000..d50bdcd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOperationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.operation.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php new file mode 100755 index 0000000..9e74846 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOrderAgreementPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.agreement.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php new file mode 100755 index 0000000..76b0c3b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOrderAppPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.app.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php new file mode 100755 index 0000000..bd4f231 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOrderDisburseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.disburse"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php new file mode 100755 index 0000000..48a3784 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOrderPagePayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.page.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundCouponOrderRefundRequest.php b/extend/app_alipay/aop/request/AlipayFundCouponOrderRefundRequest.php new file mode 100755 index 0000000..3af78c2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundCouponOrderRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.coupon.order.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundTransOrderQueryRequest.php b/extend/app_alipay/aop/request/AlipayFundTransOrderQueryRequest.php new file mode 100755 index 0000000..3bde54f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundTransOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.trans.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayFundTransToaccountTransferRequest.php b/extend/app_alipay/aop/request/AlipayFundTransToaccountTransferRequest.php new file mode 100755 index 0000000..10e57c8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayFundTransToaccountTransferRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.fund.trans.toaccount.transfer"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodCommonConsultRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodCommonConsultRequest.php new file mode 100755 index 0000000..6f08410 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodCommonConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.common.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodEnquriyApplyRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodEnquriyApplyRequest.php new file mode 100755 index 0000000..40fbdc8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodEnquriyApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.enquriy.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyApplyRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyApplyRequest.php new file mode 100755 index 0000000..4051a73 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.policy.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyCancelRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyCancelRequest.php new file mode 100755 index 0000000..527d464 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodPolicyCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.policy.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteApplyRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteApplyRequest.php new file mode 100755 index 0000000..b272273 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.quote.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteQueryRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteQueryRequest.php new file mode 100755 index 0000000..bf057bb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodQuoteQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.quote.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodUserCertifyRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodUserCertifyRequest.php new file mode 100755 index 0000000..0c156ef --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoAutoinsprodUserCertifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.autoinsprod.user.certify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsAutoCarSaveRequest.php b/extend/app_alipay/aop/request/AlipayInsAutoCarSaveRequest.php new file mode 100755 index 0000000..7c38f11 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsAutoCarSaveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.auto.car.save"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsCooperationProductOfflineBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayInsCooperationProductOfflineBatchqueryRequest.php new file mode 100755 index 0000000..5521432 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsCooperationProductOfflineBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.cooperation.product.offline.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsCooperationProductQrcodeApplyRequest.php b/extend/app_alipay/aop/request/AlipayInsCooperationProductQrcodeApplyRequest.php new file mode 100755 index 0000000..a840fe7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsCooperationProductQrcodeApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.cooperation.product.qrcode.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsCooperationRegionQrcodeApplyRequest.php b/extend/app_alipay/aop/request/AlipayInsCooperationRegionQrcodeApplyRequest.php new file mode 100755 index 0000000..2dc8dd9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsCooperationRegionQrcodeApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.cooperation.region.qrcode.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php b/extend/app_alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php new file mode 100755 index 0000000..3b44bc2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsSceneApplicationIssueConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.application.issue.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php b/extend/app_alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php new file mode 100755 index 0000000..a0a9d3a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsSceneCouponReceiveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.coupon.receive"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayInsSceneCouponSendRequest.php b/extend/app_alipay/aop/request/AlipayInsSceneCouponSendRequest.php new file mode 100755 index 0000000..bcadcda --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayInsSceneCouponSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.ins.scene.coupon.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php new file mode 100755 index 0000000..22f911e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.activity.offline.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php new file mode 100755 index 0000000..0d1866d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignActivityOfflineTriggerRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.activity.offline.trigger"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php new file mode 100755 index 0000000..a8845c2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php new file mode 100755 index 0000000..93dbcde --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php new file mode 100755 index 0000000..e8af57f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashListQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.list.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php new file mode 100755 index 0000000..d9f89ec --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashStatusModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.status.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php new file mode 100755 index 0000000..cd18b99 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCashTriggerRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cash.trigger"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php new file mode 100755 index 0000000..42647b4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignCertCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.cert.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php new file mode 100755 index 0000000..e9cdefc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetAppendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.append"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php new file mode 100755 index 0000000..ba77550 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php new file mode 100755 index 0000000..025f7ca --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountBudgetQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.budget.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php new file mode 100755 index 0000000..ee018de --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php new file mode 100755 index 0000000..abaec0c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php new file mode 100755 index 0000000..2d2aea3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php new file mode 100755 index 0000000..dab6518 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.whitelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php new file mode 100755 index 0000000..a4fc44a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDiscountWhitelistUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.discount.whitelist.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php new file mode 100755 index 0000000..5fcb065 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php new file mode 100755 index 0000000..7efa6bc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php new file mode 100755 index 0000000..3f970aa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampStatusUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.status.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php new file mode 100755 index 0000000..738e0c3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php new file mode 100755 index 0000000..175fa04 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignDrawcampWhitelistCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.drawcamp.whitelist.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php new file mode 100755 index 0000000..3f363da --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCampaignPrizeAmountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.campaign.prize.amount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php new file mode 100755 index 0000000..c3196cb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardActivateformQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.activateform.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php new file mode 100755 index 0000000..9d38c15 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardActivateurlApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.activateurl.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php new file mode 100755 index 0000000..53cec4c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php new file mode 100755 index 0000000..e8dcc40 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php new file mode 100755 index 0000000..1f1d173 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php new file mode 100755 index 0000000..b8a2669 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardBenefitQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.benefit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php new file mode 100755 index 0000000..3041763 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardConsumeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.consume.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardDeleteRequest.php new file mode 100755 index 0000000..b36715d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php new file mode 100755 index 0000000..14bf61e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardFormtemplateSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.formtemplate.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardOpenRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardOpenRequest.php new file mode 100755 index 0000000..a17e783 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardOpenRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.open"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardQueryRequest.php new file mode 100755 index 0000000..0e3f04f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php new file mode 100755 index 0000000..6169aea --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php new file mode 100755 index 0000000..04ad847 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php new file mode 100755 index 0000000..3ccde73 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardTemplateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.template.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCardUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCardUpdateRequest.php new file mode 100755 index 0000000..25f2151 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCardUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.card.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php new file mode 100755 index 0000000..679e41e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashlessvoucher.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php new file mode 100755 index 0000000..d4d7895 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCashlessvoucherTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashlessvoucher.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php new file mode 100755 index 0000000..1d233db --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashvoucher.template.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php new file mode 100755 index 0000000..bf9bd37 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCashvoucherTemplateModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cashvoucher.template.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php new file mode 100755 index 0000000..4a9edc6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php new file mode 100755 index 0000000..a39784f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php new file mode 100755 index 0000000..c03280e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php new file mode 100755 index 0000000..4c4120b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php new file mode 100755 index 0000000..3981e39 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpAdvertiseReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.advertise.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php new file mode 100755 index 0000000..c2550aa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingCdpRecommendQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.cdp.recommend.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php b/extend/app_alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php new file mode 100755 index 0000000..25ad233 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingExchangevoucherUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.exchangevoucher.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php new file mode 100755 index 0000000..aec78ee --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.activity.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php new file mode 100755 index 0000000..ec9c0e3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php new file mode 100755 index 0000000..2574798 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieEditorQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.editor.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieMemberCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieMemberCreateRequest.php new file mode 100755 index 0000000..14904c4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieMemberCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.member.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesBatchqueryRequest.php new file mode 100755 index 0000000..718f52d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesConfirmRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesConfirmRequest.php new file mode 100755 index 0000000..3c8e6a3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesCreateRequest.php new file mode 100755 index 0000000..f18c92b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesDeleteRequest.php new file mode 100755 index 0000000..4278451 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesQueryRequest.php new file mode 100755 index 0000000..c42fc9a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesSyncRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesSyncRequest.php new file mode 100755 index 0000000..e57f7bc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSitesSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.sites.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceBatchqueryRequest.php new file mode 100755 index 0000000..95f03cc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.space.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceCreateRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceCreateRequest.php new file mode 100755 index 0000000..947270a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.space.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceQueryRequest.php new file mode 100755 index 0000000..53d091f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieSpaceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.space.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateBatchqueryRequest.php new file mode 100755 index 0000000..eeea447 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.template.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php new file mode 100755 index 0000000..46444c8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.template.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateSendRequest.php b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateSendRequest.php new file mode 100755 index 0000000..c673b5c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingToolFengdieTemplateSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.tool.fengdie.template.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php new file mode 100755 index 0000000..b01e222 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingUserulePidQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.userule.pid.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php new file mode 100755 index 0000000..ce96ad1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherAuthSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.auth.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php new file mode 100755 index 0000000..51372f2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php new file mode 100755 index 0000000..c5070d8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherListQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.list.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherQueryRequest.php new file mode 100755 index 0000000..0d25237 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherSendRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherSendRequest.php new file mode 100755 index 0000000..9832b6d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherStockUseRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherStockUseRequest.php new file mode 100755 index 0000000..9cbb520 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherStockUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.stock.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php new file mode 100755 index 0000000..8c99d35 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplateDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.template.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php new file mode 100755 index 0000000..c475133 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatedetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.templatedetail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php new file mode 100755 index 0000000..6464d03 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMarketingVoucherTemplatelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.marketing.voucher.templatelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMdataTagGetRequest.php b/extend/app_alipay/aop/request/AlipayMdataTagGetRequest.php new file mode 100755 index 0000000..844de85 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMdataTagGetRequest.php @@ -0,0 +1,134 @@ +requiredTags = $requiredTags; + $this->apiParas["required_tags"] = $requiredTags; + } + + public function getRequiredTags() + { + return $this->requiredTags; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mdata.tag.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMemberCouponQuerylistRequest.php b/extend/app_alipay/aop/request/AlipayMemberCouponQuerylistRequest.php new file mode 100755 index 0000000..6c779e8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMemberCouponQuerylistRequest.php @@ -0,0 +1,198 @@ +merchantInfo = $merchantInfo; + $this->apiParas["merchant_info"] = $merchantInfo; + } + + public function getMerchantInfo() + { + return $this->merchantInfo; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setUserInfo($userInfo) + { + $this->userInfo = $userInfo; + $this->apiParas["user_info"] = $userInfo; + } + + public function getUserInfo() + { + return $this->userInfo; + } + + public function getApiMethodName() + { + return "alipay.member.coupon.querylist"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php new file mode 100755 index 0000000..dec3068 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderConfirmpayurlGetRequest.php @@ -0,0 +1,182 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setAmount($amount) + { + $this->amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setReceiveUserId($receiveUserId) + { + $this->receiveUserId = $receiveUserId; + $this->apiParas["receive_user_id"] = $receiveUserId; + } + + public function getReceiveUserId() + { + return $this->receiveUserId; + } + + public function setTransferOutOrderNo($transferOutOrderNo) + { + $this->transferOutOrderNo = $transferOutOrderNo; + $this->apiParas["transfer_out_order_no"] = $transferOutOrderNo; + } + + public function getTransferOutOrderNo() + { + return $this->transferOutOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.confirmpayurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php new file mode 100755 index 0000000..3de387c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderDirectPayRequest.php @@ -0,0 +1,182 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setAmount($amount) + { + $this->amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setReceiveUserId($receiveUserId) + { + $this->receiveUserId = $receiveUserId; + $this->apiParas["receive_user_id"] = $receiveUserId; + } + + public function getReceiveUserId() + { + return $this->receiveUserId; + } + + public function setTransferOutOrderNo($transferOutOrderNo) + { + $this->transferOutOrderNo = $transferOutOrderNo; + $this->apiParas["transfer_out_order_no"] = $transferOutOrderNo; + } + + public function getTransferOutOrderNo() + { + return $this->transferOutOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.direct.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderFreezeRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderFreezeRequest.php new file mode 100755 index 0000000..54b7a59 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderFreezeRequest.php @@ -0,0 +1,182 @@ +amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setExpireTime($expireTime) + { + $this->expireTime = $expireTime; + $this->apiParas["expire_time"] = $expireTime; + } + + public function getExpireTime() + { + return $this->expireTime; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setPayConfirm($payConfirm) + { + $this->payConfirm = $payConfirm; + $this->apiParas["pay_confirm"] = $payConfirm; + } + + public function getPayConfirm() + { + return $this->payConfirm; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.freeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php new file mode 100755 index 0000000..8b9a37a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderFreezepayurlGetRequest.php @@ -0,0 +1,118 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.freezepayurl.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderGetRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderGetRequest.php new file mode 100755 index 0000000..0dd56f7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderGetRequest.php @@ -0,0 +1,118 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php b/extend/app_alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php new file mode 100755 index 0000000..387972e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMicropayOrderUnfreezeRequest.php @@ -0,0 +1,134 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function getApiMethodName() + { + return "alipay.micropay.order.unfreeze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php new file mode 100755 index 0000000..4e6d4f1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php new file mode 100755 index 0000000..c0b1918 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php new file mode 100755 index 0000000..c08ea5b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php new file mode 100755 index 0000000..e04b665 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBeaconDeviceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.device.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php b/extend/app_alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php new file mode 100755 index 0000000..1e7bdf8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBeaconMessageSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.beacon.message.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php b/extend/app_alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php new file mode 100755 index 0000000..dc990cc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileBksigntokenVerifyRequest.php @@ -0,0 +1,150 @@ +deviceid = $deviceid; + $this->apiParas["deviceid"] = $deviceid; + } + + public function getDeviceid() + { + return $this->deviceid; + } + + public function setSource($source) + { + $this->source = $source; + $this->apiParas["source"] = $source; + } + + public function getSource() + { + return $this->source; + } + + public function setToken($token) + { + $this->token = $token; + $this->apiParas["token"] = $token; + } + + public function getToken() + { + return $this->token; + } + + public function getApiMethodName() + { + return "alipay.mobile.bksigntoken.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileCodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayMobileCodeCreateRequest.php new file mode 100755 index 0000000..72af74d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileCodeCreateRequest.php @@ -0,0 +1,247 @@ +bizLinkedId = $bizLinkedId; + $this->apiParas["biz_linked_id"] = $bizLinkedId; + } + + public function getBizLinkedId() + { + return $this->bizLinkedId; + } + + public function setBizType($bizType) + { + $this->bizType = $bizType; + $this->apiParas["biz_type"] = $bizType; + } + + public function getBizType() + { + return $this->bizType; + } + + public function setContextStr($contextStr) + { + $this->contextStr = $contextStr; + $this->apiParas["context_str"] = $contextStr; + } + + public function getContextStr() + { + return $this->contextStr; + } + + public function setIsDirect($isDirect) + { + $this->isDirect = $isDirect; + $this->apiParas["is_direct"] = $isDirect; + } + + public function getIsDirect() + { + return $this->isDirect; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setSourceId($sourceId) + { + $this->sourceId = $sourceId; + $this->apiParas["source_id"] = $sourceId; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function setStartDate($startDate) + { + $this->startDate = $startDate; + $this->apiParas["start_date"] = $startDate; + } + + public function getStartDate() + { + return $this->startDate; + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + $this->apiParas["timeout"] = $timeout; + } + + public function getTimeout() + { + return $this->timeout; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mobile.code.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileCodeQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileCodeQueryRequest.php new file mode 100755 index 0000000..cf43c88 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileCodeQueryRequest.php @@ -0,0 +1,118 @@ +qrToken = $qrToken; + $this->apiParas["qr_token"] = $qrToken; + } + + public function getQrToken() + { + return $this->qrToken; + } + + public function getApiMethodName() + { + return "alipay.mobile.code.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicAccountAddRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicAccountAddRequest.php new file mode 100755 index 0000000..54beb2d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicAccountAddRequest.php @@ -0,0 +1,198 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBindAccountNo($bindAccountNo) + { + $this->bindAccountNo = $bindAccountNo; + $this->apiParas["bind_account_no"] = $bindAccountNo; + } + + public function getBindAccountNo() + { + return $this->bindAccountNo; + } + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function setDisplayName($displayName) + { + $this->displayName = $displayName; + $this->apiParas["display_name"] = $displayName; + } + + public function getDisplayName() + { + return $this->displayName; + } + + public function setFromUserId($fromUserId) + { + $this->fromUserId = $fromUserId; + $this->apiParas["from_user_id"] = $fromUserId; + } + + public function getFromUserId() + { + return $this->fromUserId; + } + + public function setRealName($realName) + { + $this->realName = $realName; + $this->apiParas["real_name"] = $realName; + } + + public function getRealName() + { + return $this->realName; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php new file mode 100755 index 0000000..2665830 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicAccountDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php new file mode 100755 index 0000000..78ed91e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicAccountResetRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicAccountResetRequest.php new file mode 100755 index 0000000..ae2b5e3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicAccountResetRequest.php @@ -0,0 +1,198 @@ +agreementId = $agreementId; + $this->apiParas["agreement_id"] = $agreementId; + } + + public function getAgreementId() + { + return $this->agreementId; + } + + public function setBindAccountNo($bindAccountNo) + { + $this->bindAccountNo = $bindAccountNo; + $this->apiParas["bind_account_no"] = $bindAccountNo; + } + + public function getBindAccountNo() + { + return $this->bindAccountNo; + } + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function setDisplayName($displayName) + { + $this->displayName = $displayName; + $this->apiParas["display_name"] = $displayName; + } + + public function getDisplayName() + { + return $this->displayName; + } + + public function setFromUserId($fromUserId) + { + $this->fromUserId = $fromUserId; + $this->apiParas["from_user_id"] = $fromUserId; + } + + public function getFromUserId() + { + return $this->fromUserId; + } + + public function setRealName($realName) + { + $this->realName = $realName; + $this->apiParas["real_name"] = $realName; + } + + public function getRealName() + { + return $this->realName; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.account.reset"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php new file mode 100755 index 0000000..da59f20 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicAppinfoUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.appinfo.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php new file mode 100755 index 0000000..57d51a6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicContactFollowListRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicFollowListRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicFollowListRequest.php new file mode 100755 index 0000000..d90ccc8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicFollowListRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.follow.list"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicGisGetRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicGisGetRequest.php new file mode 100755 index 0000000..3f8d69d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicGisGetRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.gis.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php new file mode 100755 index 0000000..4029fbd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicInfoModifyRequest.php @@ -0,0 +1,230 @@ +appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setAuthPic($authPic) + { + $this->authPic = $authPic; + $this->apiParas["auth_pic"] = $authPic; + } + + public function getAuthPic() + { + return $this->authPic; + } + + public function setLicenseUrl($licenseUrl) + { + $this->licenseUrl = $licenseUrl; + $this->apiParas["license_url"] = $licenseUrl; + } + + public function getLicenseUrl() + { + return $this->licenseUrl; + } + + public function setLogoUrl($logoUrl) + { + $this->logoUrl = $logoUrl; + $this->apiParas["logo_url"] = $logoUrl; + } + + public function getLogoUrl() + { + return $this->logoUrl; + } + + public function setPublicGreeting($publicGreeting) + { + $this->publicGreeting = $publicGreeting; + $this->apiParas["public_greeting"] = $publicGreeting; + } + + public function getPublicGreeting() + { + return $this->publicGreeting; + } + + public function setShopPic1($shopPic1) + { + $this->shopPic1 = $shopPic1; + $this->apiParas["shop_pic1"] = $shopPic1; + } + + public function getShopPic1() + { + return $this->shopPic1; + } + + public function setShopPic2($shopPic2) + { + $this->shopPic2 = $shopPic2; + $this->apiParas["shop_pic2"] = $shopPic2; + } + + public function getShopPic2() + { + return $this->shopPic2; + } + + public function setShopPic3($shopPic3) + { + $this->shopPic3 = $shopPic3; + $this->apiParas["shop_pic3"] = $shopPic3; + } + + public function getShopPic3() + { + return $this->shopPic3; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.info.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php new file mode 100755 index 0000000..0a7e8c0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicInfoQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelAddRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelAddRequest.php new file mode 100755 index 0000000..5789850 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php new file mode 100755 index 0000000..1664bc4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelDeleteRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php new file mode 100755 index 0000000..d9af33c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelQueryRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php new file mode 100755 index 0000000..2b30665 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUpdateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php new file mode 100755 index 0000000..7ffb360 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php new file mode 100755 index 0000000..a622747 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserDeleteRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php new file mode 100755 index 0000000..6086b4d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicLabelUserQueryRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.label.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuAddRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuAddRequest.php new file mode 100755 index 0000000..e7ea16e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuAddRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php new file mode 100755 index 0000000..67b81fa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuGetRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuGetRequest.php new file mode 100755 index 0000000..70500e7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php new file mode 100755 index 0000000..8abaded --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php new file mode 100755 index 0000000..a81a93d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUpdateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php new file mode 100755 index 0000000..a2d9ded --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php new file mode 100755 index 0000000..6f8a061 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMenuUserUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.menu.user.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php new file mode 100755 index 0000000..0ab6477 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessageCustomSendRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php new file mode 100755 index 0000000..289b7a3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessageLabelSendRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.label.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessagePushRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessagePushRequest.php new file mode 100755 index 0000000..d1990c9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessagePushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php new file mode 100755 index 0000000..c4c5f9b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessageSingleSendRequest.php @@ -0,0 +1,119 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.single.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php new file mode 100755 index 0000000..4ef7b0d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessageTotalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.message.total.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php new file mode 100755 index 0000000..f519a17 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessagebatchPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.messagebatch.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php new file mode 100755 index 0000000..c67d9ba --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicMessagespecifyPushRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.messagespecify.push"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php new file mode 100755 index 0000000..ac3f640 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php new file mode 100755 index 0000000..5a969a7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicShortlinkCreateRequest.php @@ -0,0 +1,118 @@ +详情请见 + **/ + private $bizContent; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBizContent($bizContent) + { + $this->bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.shortlink.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php new file mode 100755 index 0000000..f8b54d5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageDeleteRequest.php @@ -0,0 +1,118 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php new file mode 100755 index 0000000..666bf5a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageGetRequest.php @@ -0,0 +1,118 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php new file mode 100755 index 0000000..b5a5cef --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageModifyRequest.php @@ -0,0 +1,134 @@ +templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function setTradeSetting($tradeSetting) + { + $this->tradeSetting = $tradeSetting; + $this->apiParas["trade_setting"] = $tradeSetting; + } + + public function getTradeSetting() + { + return $this->tradeSetting; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php new file mode 100755 index 0000000..b070d24 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobilePublicTemplateMessageQueryRequest.php @@ -0,0 +1,134 @@ +template = $template; + $this->apiParas["template"] = $template; + } + + public function getTemplate() + { + return $this->template; + } + + public function setTemplateId($templateId) + { + $this->templateId = $templateId; + $this->apiParas["template_id"] = $templateId; + } + + public function getTemplateId() + { + return $this->templateId; + } + + public function getApiMethodName() + { + return "alipay.mobile.public.template.message.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileRecommendGetRequest.php b/extend/app_alipay/aop/request/AlipayMobileRecommendGetRequest.php new file mode 100755 index 0000000..50af41b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileRecommendGetRequest.php @@ -0,0 +1,182 @@ +extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setLimit($limit) + { + $this->limit = $limit; + $this->apiParas["limit"] = $limit; + } + + public function getLimit() + { + return $this->limit; + } + + public function setSceneId($sceneId) + { + $this->sceneId = $sceneId; + $this->apiParas["scene_id"] = $sceneId; + } + + public function getSceneId() + { + return $this->sceneId; + } + + public function setStartIdx($startIdx) + { + $this->startIdx = $startIdx; + $this->apiParas["start_idx"] = $startIdx; + } + + public function getStartIdx() + { + return $this->startIdx; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.mobile.recommend.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileShakeUserQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileShakeUserQueryRequest.php new file mode 100755 index 0000000..7eba0db --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileShakeUserQueryRequest.php @@ -0,0 +1,137 @@ +dynamicId = $dynamicId; + $this->apiParas["dynamic_id"] = $dynamicId; + } + + public function getDynamicId() + { + return $this->dynamicId; + } + + public function setDynamicIdType($dynamicIdType) + { + $this->dynamicIdType = $dynamicIdType; + $this->apiParas["dynamic_id_type"] = $dynamicIdType; + } + + public function getDynamicIdType() + { + return $this->dynamicIdType; + } + + public function getApiMethodName() + { + return "alipay.mobile.shake.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php new file mode 100755 index 0000000..8b874d1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileStdPublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php new file mode 100755 index 0000000..3920904 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileStdPublicExpressUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.express.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php b/extend/app_alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php new file mode 100755 index 0000000..07a1e60 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileStdPublicFollowListRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.follow.list"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php b/extend/app_alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php new file mode 100755 index 0000000..7f6ef19 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileStdPublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php b/extend/app_alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php new file mode 100755 index 0000000..1ac773b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMobileStdPublicMessageCustomSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mobile.std.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php b/extend/app_alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php new file mode 100755 index 0000000..f85a934 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMpointprodBenefitDetailGetRequest.php @@ -0,0 +1,122 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.mpointprod.benefit.detail.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php b/extend/app_alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php new file mode 100755 index 0000000..affaf0a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMsaasMediarecogVoiceMediaaudioUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.msaas.mediarecog.voice.mediaaudio.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php b/extend/app_alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php new file mode 100755 index 0000000..7714a43 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayMsaasPromotionCpainfoCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.msaas.promotion.cpainfo.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php new file mode 100755 index 0000000..1386c5c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketApplyorderBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.applyorder.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php new file mode 100755 index 0000000..ac460e73 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketItemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php new file mode 100755 index 0000000..5f063b3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketItemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketItemStateRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketItemStateRequest.php new file mode 100755 index 0000000..36e63ca --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketItemStateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.item.state"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php new file mode 100755 index 0000000..fa0875e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketMcommentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.mcomment.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php new file mode 100755 index 0000000..22a74d6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketProductBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.product.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php new file mode 100755 index 0000000..fcf9843 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketProductQuerydetailRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.product.querydetail"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php new file mode 100755 index 0000000..9e4c7ed --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketReporterrorCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.reporterror.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php new file mode 100755 index 0000000..3df228c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopApplyorderCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.applyorder.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php new file mode 100755 index 0000000..d426740 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php new file mode 100755 index 0000000..19e190b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopCategoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.category.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php new file mode 100755 index 0000000..5844e9a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php new file mode 100755 index 0000000..2a66f4c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopDiscountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.discount.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php new file mode 100755 index 0000000..07ec00b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php new file mode 100755 index 0000000..15a4b39 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicBindRequest.php @@ -0,0 +1,134 @@ +isAll = $isAll; + $this->apiParas["is_all"] = $isAll; + } + + public function getIsAll() + { + return $this->isAll; + } + + public function setShopIds($shopIds) + { + $this->shopIds = $shopIds; + $this->apiParas["shop_ids"] = $shopIds; + } + + public function getShopIds() + { + return $this->shopIds; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.public.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php new file mode 100755 index 0000000..05d5a7a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopPublicUnbindRequest.php @@ -0,0 +1,134 @@ +isAll = $isAll; + $this->apiParas["is_all"] = $isAll; + } + + public function getIsAll() + { + return $this->isAll; + } + + public function setShopIds($shopIds) + { + $this->shopIds = $shopIds; + $this->apiParas["shop_ids"] = $shopIds; + } + + public function getShopIds() + { + return $this->shopIds; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.public.unbind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php new file mode 100755 index 0000000..9c34b45 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopQuerydetailRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.querydetail"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php new file mode 100755 index 0000000..2830bb9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketShopSummaryBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.market.shop.summary.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php new file mode 100755 index 0000000..146e474 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCodeUploadRequest.php @@ -0,0 +1,150 @@ +extendParams = $extendParams; + $this->apiParas["extend_params"] = $extendParams; + } + + public function getExtendParams() + { + return $this->extendParams; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setFileContent($fileContent) + { + $this->fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.code.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php new file mode 100755 index 0000000..4f4660b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php new file mode 100755 index 0000000..ff35ccd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php new file mode 100755 index 0000000..6cc87fe --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php new file mode 100755 index 0000000..1682814 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherStatusQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.status.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php new file mode 100755 index 0000000..c118853 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMarketingVoucherUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.marketing.voucher.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php new file mode 100755 index 0000000..d74b404 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMaterialImageDownloadRequest.php @@ -0,0 +1,118 @@ +imageIds = $imageIds; + $this->apiParas["image_ids"] = $imageIds; + } + + public function getImageIds() + { + return $this->imageIds; + } + + public function getApiMethodName() + { + return "alipay.offline.material.image.download"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php b/extend/app_alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php new file mode 100755 index 0000000..5c7c11b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineMaterialImageUploadRequest.php @@ -0,0 +1,166 @@ +imageContent = $imageContent; + $this->apiParas["image_content"] = $imageContent; + } + + public function getImageContent() + { + return $this->imageContent; + } + + public function setImageName($imageName) + { + $this->imageName = $imageName; + $this->apiParas["image_name"] = $imageName; + } + + public function getImageName() + { + return $this->imageName; + } + + public function setImagePid($imagePid) + { + $this->imagePid = $imagePid; + $this->apiParas["image_pid"] = $imagePid; + } + + public function getImagePid() + { + return $this->imagePid; + } + + public function setImageType($imageType) + { + $this->imageType = $imageType; + $this->apiParas["image_type"] = $imageType; + } + + public function getImageType() + { + return $this->imageType; + } + + public function getApiMethodName() + { + return "alipay.offline.material.image.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php new file mode 100755 index 0000000..880d396 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderDishQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.dish.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php new file mode 100755 index 0000000..77a0110 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthQuerybypageRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.equipment.auth.querybypage"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php new file mode 100755 index 0000000..2944073 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderEquipmentAuthRemoveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.equipment.auth.remove"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php new file mode 100755 index 0000000..3ac0753 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderMonitorLogSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.monitor.log.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php new file mode 100755 index 0000000..7cad1e3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderShopactionRecordRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.shopaction.record"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php b/extend/app_alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php new file mode 100755 index 0000000..340b0a6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOfflineProviderUseractionRecordRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.offline.provider.useraction.record"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentCancelRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentCancelRequest.php new file mode 100755 index 0000000..42c1c33 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.agent.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentConfirmRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentConfirmRequest.php new file mode 100755 index 0000000..f7443a8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.agent.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentCreateRequest.php new file mode 100755 index 0000000..1e651f8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.agent.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentFacetofaceSignRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentFacetofaceSignRequest.php new file mode 100755 index 0000000..c1f175d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentFacetofaceSignRequest.php @@ -0,0 +1,266 @@ +商家经营类目 中的“经营类目编码” + **/ + private $mccCode; + + /** + * 店铺内景图片,最小50KB,图片格式必须为:png、bmp、gif、jpg、jpeg + **/ + private $shopScenePic; + + /** + * 店铺门头照图片,最小50KB,图片格式必须为:png、bmp、gif、jpg、jpeg + **/ + private $shopSignBoardPic; + + /** + * 企业特殊资质图片,可参考 +商家经营类目 中的“需要的特殊资质证书”,最小50KB,图片格式必须为:png、bmp、gif、jpg、jpeg + **/ + private $specialLicensePic; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setBatchNo($batchNo) + { + $this->batchNo = $batchNo; + $this->apiParas["batch_no"] = $batchNo; + } + + public function getBatchNo() + { + return $this->batchNo; + } + + public function setBusinessLicenseAuthPic($businessLicenseAuthPic) + { + $this->businessLicenseAuthPic = $businessLicenseAuthPic; + $this->apiParas["business_license_auth_pic"] = $businessLicenseAuthPic; + } + + public function getBusinessLicenseAuthPic() + { + return $this->businessLicenseAuthPic; + } + + public function setBusinessLicenseNo($businessLicenseNo) + { + $this->businessLicenseNo = $businessLicenseNo; + $this->apiParas["business_license_no"] = $businessLicenseNo; + } + + public function getBusinessLicenseNo() + { + return $this->businessLicenseNo; + } + + public function setBusinessLicensePic($businessLicensePic) + { + $this->businessLicensePic = $businessLicensePic; + $this->apiParas["business_license_pic"] = $businessLicensePic; + } + + public function getBusinessLicensePic() + { + return $this->businessLicensePic; + } + + public function setDateLimitation($dateLimitation) + { + $this->dateLimitation = $dateLimitation; + $this->apiParas["date_limitation"] = $dateLimitation; + } + + public function getDateLimitation() + { + return $this->dateLimitation; + } + + public function setLongTerm($longTerm) + { + $this->longTerm = $longTerm; + $this->apiParas["long_term"] = $longTerm; + } + + public function getLongTerm() + { + return $this->longTerm; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setShopScenePic($shopScenePic) + { + $this->shopScenePic = $shopScenePic; + $this->apiParas["shop_scene_pic"] = $shopScenePic; + } + + public function getShopScenePic() + { + return $this->shopScenePic; + } + + public function setShopSignBoardPic($shopSignBoardPic) + { + $this->shopSignBoardPic = $shopSignBoardPic; + $this->apiParas["shop_sign_board_pic"] = $shopSignBoardPic; + } + + public function getShopSignBoardPic() + { + return $this->shopSignBoardPic; + } + + public function setSpecialLicensePic($specialLicensePic) + { + $this->specialLicensePic = $specialLicensePic; + $this->apiParas["special_license_pic"] = $specialLicensePic; + } + + public function getSpecialLicensePic() + { + return $this->specialLicensePic; + } + + public function getApiMethodName() + { + return "alipay.open.agent.facetoface.sign"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentMiniCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentMiniCreateRequest.php new file mode 100755 index 0000000..cf188bd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentMiniCreateRequest.php @@ -0,0 +1,249 @@ +appCategoryIds = $appCategoryIds; + $this->apiParas["app_category_ids"] = $appCategoryIds; + } + + public function getAppCategoryIds() + { + return $this->appCategoryIds; + } + + public function setAppDesc($appDesc) + { + $this->appDesc = $appDesc; + $this->apiParas["app_desc"] = $appDesc; + } + + public function getAppDesc() + { + return $this->appDesc; + } + + public function setAppEnglishName($appEnglishName) + { + $this->appEnglishName = $appEnglishName; + $this->apiParas["app_english_name"] = $appEnglishName; + } + + public function getAppEnglishName() + { + return $this->appEnglishName; + } + + public function setAppLogo($appLogo) + { + $this->appLogo = $appLogo; + $this->apiParas["app_logo"] = $appLogo; + } + + public function getAppLogo() + { + return $this->appLogo; + } + + public function setAppName($appName) + { + $this->appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setAppSlogan($appSlogan) + { + $this->appSlogan = $appSlogan; + $this->apiParas["app_slogan"] = $appSlogan; + } + + public function getAppSlogan() + { + return $this->appSlogan; + } + + public function setBatchNo($batchNo) + { + $this->batchNo = $batchNo; + $this->apiParas["batch_no"] = $batchNo; + } + + public function getBatchNo() + { + return $this->batchNo; + } + + public function setServiceEmail($serviceEmail) + { + $this->serviceEmail = $serviceEmail; + $this->apiParas["service_email"] = $serviceEmail; + } + + public function getServiceEmail() + { + return $this->serviceEmail; + } + + public function setServicePhone($servicePhone) + { + $this->servicePhone = $servicePhone; + $this->apiParas["service_phone"] = $servicePhone; + } + + public function getServicePhone() + { + return $this->servicePhone; + } + + public function getApiMethodName() + { + return "alipay.open.agent.mini.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentMobilepaySignRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentMobilepaySignRequest.php new file mode 100755 index 0000000..bdd6142 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentMobilepaySignRequest.php @@ -0,0 +1,266 @@ +商家经营类目 中的“经营类目编码” + **/ + private $mccCode; + + /** + * 企业特殊资质图片,可参考 +商家经营类目 中的“需要的特殊资质证书”,最小50KB,图片格式必须为:png、bmp、gif、jpg、jpeg + **/ + private $specialLicensePic; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setAppDemo($appDemo) + { + $this->appDemo = $appDemo; + $this->apiParas["app_demo"] = $appDemo; + } + + public function getAppDemo() + { + return $this->appDemo; + } + + public function setAppName($appName) + { + $this->appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setBatchNo($batchNo) + { + $this->batchNo = $batchNo; + $this->apiParas["batch_no"] = $batchNo; + } + + public function getBatchNo() + { + return $this->batchNo; + } + + public function setBusinessLicenseAuthPic($businessLicenseAuthPic) + { + $this->businessLicenseAuthPic = $businessLicenseAuthPic; + $this->apiParas["business_license_auth_pic"] = $businessLicenseAuthPic; + } + + public function getBusinessLicenseAuthPic() + { + return $this->businessLicenseAuthPic; + } + + public function setBusinessLicenseNo($businessLicenseNo) + { + $this->businessLicenseNo = $businessLicenseNo; + $this->apiParas["business_license_no"] = $businessLicenseNo; + } + + public function getBusinessLicenseNo() + { + return $this->businessLicenseNo; + } + + public function setBusinessLicensePic($businessLicensePic) + { + $this->businessLicensePic = $businessLicensePic; + $this->apiParas["business_license_pic"] = $businessLicensePic; + } + + public function getBusinessLicensePic() + { + return $this->businessLicensePic; + } + + public function setDateLimitation($dateLimitation) + { + $this->dateLimitation = $dateLimitation; + $this->apiParas["date_limitation"] = $dateLimitation; + } + + public function getDateLimitation() + { + return $this->dateLimitation; + } + + public function setLongTerm($longTerm) + { + $this->longTerm = $longTerm; + $this->apiParas["long_term"] = $longTerm; + } + + public function getLongTerm() + { + return $this->longTerm; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setSpecialLicensePic($specialLicensePic) + { + $this->specialLicensePic = $specialLicensePic; + $this->apiParas["special_license_pic"] = $specialLicensePic; + } + + public function getSpecialLicensePic() + { + return $this->specialLicensePic; + } + + public function getApiMethodName() + { + return "alipay.open.agent.mobilepay.sign"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentOrderQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentOrderQueryRequest.php new file mode 100755 index 0000000..e535a45 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.agent.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAgentZhimabriefSignRequest.php b/extend/app_alipay/aop/request/AlipayOpenAgentZhimabriefSignRequest.php new file mode 100755 index 0000000..4f63458 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAgentZhimabriefSignRequest.php @@ -0,0 +1,426 @@ +商家经营类目 中的“经营类目编码” + **/ + private $mccCode; + + /** + * 异议处理接口人 + **/ + private $ohContact; + + /** + * 用户服务联动机制接口人 + **/ + private $prContact; + + /** + * 企业特殊资质图片,可参考 +商家经营类目 中的“需要的特殊资质证书”,最小50KB,图片格式必须为:png、bmp、gif、jpg、jpeg + **/ + private $specialLicensePic; + + /** + * 使用场景描述,签约芝麻信用产品的用途,可选值:"现金放贷","其他", "消费分期(例如买房、装修等)", "融资租赁", "发放信用卡", "极速返利", "押金减免", "先用后付", "社交场景信用互查", "会员分层信用参考" + **/ + private $usageScene; + + /** + * 接入网址信息(1 app_name、app_demo;2 web_sites;3 alipay_life_name;4 wechat_official_account_name。1、2、3、4至少选择一个填写) + **/ + private $webSites; + + /** + * 微信公众号名称(1 app_name、app_demo;2 web_sites;3 alipay_life_name;4 wechat_official_account_name。1、2、3、4至少选择一个填写) + **/ + private $wechatOfficialAccountName; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setAlipayLifeName($alipayLifeName) + { + $this->alipayLifeName = $alipayLifeName; + $this->apiParas["alipay_life_name"] = $alipayLifeName; + } + + public function getAlipayLifeName() + { + return $this->alipayLifeName; + } + + public function setAppDemo($appDemo) + { + $this->appDemo = $appDemo; + $this->apiParas["app_demo"] = $appDemo; + } + + public function getAppDemo() + { + return $this->appDemo; + } + + public function setAppName($appName) + { + $this->appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setBatchNo($batchNo) + { + $this->batchNo = $batchNo; + $this->apiParas["batch_no"] = $batchNo; + } + + public function getBatchNo() + { + return $this->batchNo; + } + + public function setBusinessLicenseAuthPic($businessLicenseAuthPic) + { + $this->businessLicenseAuthPic = $businessLicenseAuthPic; + $this->apiParas["business_license_auth_pic"] = $businessLicenseAuthPic; + } + + public function getBusinessLicenseAuthPic() + { + return $this->businessLicenseAuthPic; + } + + public function setBusinessLicenseNo($businessLicenseNo) + { + $this->businessLicenseNo = $businessLicenseNo; + $this->apiParas["business_license_no"] = $businessLicenseNo; + } + + public function getBusinessLicenseNo() + { + return $this->businessLicenseNo; + } + + public function setBusinessLicensePic($businessLicensePic) + { + $this->businessLicensePic = $businessLicensePic; + $this->apiParas["business_license_pic"] = $businessLicensePic; + } + + public function getBusinessLicensePic() + { + return $this->businessLicensePic; + } + + public function setCustomUsageScene($customUsageScene) + { + $this->customUsageScene = $customUsageScene; + $this->apiParas["custom_usage_scene"] = $customUsageScene; + } + + public function getCustomUsageScene() + { + return $this->customUsageScene; + } + + public function setDateLimitation($dateLimitation) + { + $this->dateLimitation = $dateLimitation; + $this->apiParas["date_limitation"] = $dateLimitation; + } + + public function getDateLimitation() + { + return $this->dateLimitation; + } + + public function setDrContact($drContact) + { + $this->drContact = $drContact; + $this->apiParas["dr_contact"] = $drContact; + } + + public function getDrContact() + { + return $this->drContact; + } + + public function setEnterpriseAlias($enterpriseAlias) + { + $this->enterpriseAlias = $enterpriseAlias; + $this->apiParas["enterprise_alias"] = $enterpriseAlias; + } + + public function getEnterpriseAlias() + { + return $this->enterpriseAlias; + } + + public function setEnterpriseLogo($enterpriseLogo) + { + $this->enterpriseLogo = $enterpriseLogo; + $this->apiParas["enterprise_logo"] = $enterpriseLogo; + } + + public function getEnterpriseLogo() + { + return $this->enterpriseLogo; + } + + public function setLongTerm($longTerm) + { + $this->longTerm = $longTerm; + $this->apiParas["long_term"] = $longTerm; + } + + public function getLongTerm() + { + return $this->longTerm; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setOhContact($ohContact) + { + $this->ohContact = $ohContact; + $this->apiParas["oh_contact"] = $ohContact; + } + + public function getOhContact() + { + return $this->ohContact; + } + + public function setPrContact($prContact) + { + $this->prContact = $prContact; + $this->apiParas["pr_contact"] = $prContact; + } + + public function getPrContact() + { + return $this->prContact; + } + + public function setSpecialLicensePic($specialLicensePic) + { + $this->specialLicensePic = $specialLicensePic; + $this->apiParas["special_license_pic"] = $specialLicensePic; + } + + public function getSpecialLicensePic() + { + return $this->specialLicensePic; + } + + public function setUsageScene($usageScene) + { + $this->usageScene = $usageScene; + $this->apiParas["usage_scene"] = $usageScene; + } + + public function getUsageScene() + { + return $this->usageScene; + } + + public function setWebSites($webSites) + { + $this->webSites = $webSites; + $this->apiParas["web_sites"] = $webSites; + } + + public function getWebSites() + { + return $this->webSites; + } + + public function setWechatOfficialAccountName($wechatOfficialAccountName) + { + $this->wechatOfficialAccountName = $wechatOfficialAccountName; + $this->apiParas["wechat_official_account_name"] = $wechatOfficialAccountName; + } + + public function getWechatOfficialAccountName() + { + return $this->wechatOfficialAccountName; + } + + public function getApiMethodName() + { + return "alipay.open.agent.zhimabrief.sign"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppCodetesttestRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppCodetesttestRequest.php new file mode 100755 index 0000000..88dcc19 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppCodetesttestRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.codetesttest"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyisiCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyisiCreateRequest.php new file mode 100755 index 0000000..867c062 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyisiCreateRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyiwuBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyiwuBatchqueryRequest.php new file mode 100755 index 0000000..c9bc8b9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppLingjiuyiwuBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppMembersCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppMembersCreateRequest.php new file mode 100755 index 0000000..712ac30 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppMembersCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.members.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppMembersDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppMembersDeleteRequest.php new file mode 100755 index 0000000..e43f723 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppMembersDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.members.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppMembersQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppMembersQueryRequest.php new file mode 100755 index 0000000..beb4866 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppMembersQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.members.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppMiniTemplatemessageSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppMiniTemplatemessageSendRequest.php new file mode 100755 index 0000000..80cbb98 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppMiniTemplatemessageSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.mini.templatemessage.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppNotifyVerifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppNotifyVerifyRequest.php new file mode 100755 index 0000000..70c51c7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppNotifyVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.notify.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php new file mode 100755 index 0000000..3608b22 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppXwbtestabcQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppXwbtestabcQueryRequest.php new file mode 100755 index 0000000..4f33172 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppXwbtestabcQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.xwbtestabc.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppYiyiyiwuQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppYiyiyiwuQueryRequest.php new file mode 100755 index 0000000..f83e317 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppYiyiyiwuQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.yiyiyiwu.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php new file mode 100755 index 0000000..400e14d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAppYufanlingsanyaowuYufalingsanyaowuQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.app.yufanlingsanyaowu.yufalingsanyaowu.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php b/extend/app_alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php new file mode 100755 index 0000000..449881e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAuthIndustryPlatformCreateTokenRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.industry.platform.create.token"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php new file mode 100755 index 0000000..7c9fba6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.token.app.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppRequest.php b/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppRequest.php new file mode 100755 index 0000000..3f67d46 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenAuthTokenAppRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.auth.token.app"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoModifyRequest.php new file mode 100755 index 0000000..3c27016 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoModifyRequest.php @@ -0,0 +1,230 @@ +appCategoryIds = $appCategoryIds; + $this->apiParas["app_category_ids"] = $appCategoryIds; + } + + public function getAppCategoryIds() + { + return $this->appCategoryIds; + } + + public function setAppDesc($appDesc) + { + $this->appDesc = $appDesc; + $this->apiParas["app_desc"] = $appDesc; + } + + public function getAppDesc() + { + return $this->appDesc; + } + + public function setAppEnglishName($appEnglishName) + { + $this->appEnglishName = $appEnglishName; + $this->apiParas["app_english_name"] = $appEnglishName; + } + + public function getAppEnglishName() + { + return $this->appEnglishName; + } + + public function setAppLogo($appLogo) + { + $this->appLogo = $appLogo; + $this->apiParas["app_logo"] = $appLogo; + } + + public function getAppLogo() + { + return $this->appLogo; + } + + public function setAppName($appName) + { + $this->appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setAppSlogan($appSlogan) + { + $this->appSlogan = $appSlogan; + $this->apiParas["app_slogan"] = $appSlogan; + } + + public function getAppSlogan() + { + return $this->appSlogan; + } + + public function setServiceEmail($serviceEmail) + { + $this->serviceEmail = $serviceEmail; + $this->apiParas["service_email"] = $serviceEmail; + } + + public function getServiceEmail() + { + return $this->serviceEmail; + } + + public function setServicePhone($servicePhone) + { + $this->servicePhone = $servicePhone; + $this->apiParas["service_phone"] = $servicePhone; + } + + public function getServicePhone() + { + return $this->servicePhone; + } + + public function getApiMethodName() + { + return "alipay.open.mini.baseinfo.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoQueryRequest.php new file mode 100755 index 0000000..636aded --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniBaseinfoQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCancelRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCancelRequest.php new file mode 100755 index 0000000..2fb6995 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.experience.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCreateRequest.php new file mode 100755 index 0000000..4bf39a9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.experience.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniExperienceQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceQueryRequest.php new file mode 100755 index 0000000..4e133d0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniExperienceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.experience.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainCreateRequest.php new file mode 100755 index 0000000..7338ba9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.safedomain.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainDeleteRequest.php new file mode 100755 index 0000000..a5aefb7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniSafedomainDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.safedomain.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniTemplateUsageQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniTemplateUsageQueryRequest.php new file mode 100755 index 0000000..a2c5685 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniTemplateUsageQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.template.usage.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditApplyRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditApplyRequest.php new file mode 100755 index 0000000..90f9c1c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditApplyRequest.php @@ -0,0 +1,390 @@ +appCategoryIds = $appCategoryIds; + $this->apiParas["app_category_ids"] = $appCategoryIds; + } + + public function getAppCategoryIds() + { + return $this->appCategoryIds; + } + + public function setAppDesc($appDesc) + { + $this->appDesc = $appDesc; + $this->apiParas["app_desc"] = $appDesc; + } + + public function getAppDesc() + { + return $this->appDesc; + } + + public function setAppEnglishName($appEnglishName) + { + $this->appEnglishName = $appEnglishName; + $this->apiParas["app_english_name"] = $appEnglishName; + } + + public function getAppEnglishName() + { + return $this->appEnglishName; + } + + public function setAppLogo($appLogo) + { + $this->appLogo = $appLogo; + $this->apiParas["app_logo"] = $appLogo; + } + + public function getAppLogo() + { + return $this->appLogo; + } + + public function setAppName($appName) + { + $this->appName = $appName; + $this->apiParas["app_name"] = $appName; + } + + public function getAppName() + { + return $this->appName; + } + + public function setAppSlogan($appSlogan) + { + $this->appSlogan = $appSlogan; + $this->apiParas["app_slogan"] = $appSlogan; + } + + public function getAppSlogan() + { + return $this->appSlogan; + } + + public function setAppVersion($appVersion) + { + $this->appVersion = $appVersion; + $this->apiParas["app_version"] = $appVersion; + } + + public function getAppVersion() + { + return $this->appVersion; + } + + public function setFifthScreenShot($fifthScreenShot) + { + $this->fifthScreenShot = $fifthScreenShot; + $this->apiParas["fifth_screen_shot"] = $fifthScreenShot; + } + + public function getFifthScreenShot() + { + return $this->fifthScreenShot; + } + + public function setFirstScreenShot($firstScreenShot) + { + $this->firstScreenShot = $firstScreenShot; + $this->apiParas["first_screen_shot"] = $firstScreenShot; + } + + public function getFirstScreenShot() + { + return $this->firstScreenShot; + } + + public function setFourthScreenShot($fourthScreenShot) + { + $this->fourthScreenShot = $fourthScreenShot; + $this->apiParas["fourth_screen_shot"] = $fourthScreenShot; + } + + public function getFourthScreenShot() + { + return $this->fourthScreenShot; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setRegionType($regionType) + { + $this->regionType = $regionType; + $this->apiParas["region_type"] = $regionType; + } + + public function getRegionType() + { + return $this->regionType; + } + + public function setSecondScreenShot($secondScreenShot) + { + $this->secondScreenShot = $secondScreenShot; + $this->apiParas["second_screen_shot"] = $secondScreenShot; + } + + public function getSecondScreenShot() + { + return $this->secondScreenShot; + } + + public function setServiceEmail($serviceEmail) + { + $this->serviceEmail = $serviceEmail; + $this->apiParas["service_email"] = $serviceEmail; + } + + public function getServiceEmail() + { + return $this->serviceEmail; + } + + public function setServicePhone($servicePhone) + { + $this->servicePhone = $servicePhone; + $this->apiParas["service_phone"] = $servicePhone; + } + + public function getServicePhone() + { + return $this->servicePhone; + } + + public function setServiceRegionInfo($serviceRegionInfo) + { + $this->serviceRegionInfo = $serviceRegionInfo; + $this->apiParas["service_region_info"] = $serviceRegionInfo; + } + + public function getServiceRegionInfo() + { + return $this->serviceRegionInfo; + } + + public function setThirdScreenShot($thirdScreenShot) + { + $this->thirdScreenShot = $thirdScreenShot; + $this->apiParas["third_screen_shot"] = $thirdScreenShot; + } + + public function getThirdScreenShot() + { + return $this->thirdScreenShot; + } + + public function setVersionDesc($versionDesc) + { + $this->versionDesc = $versionDesc; + $this->apiParas["version_desc"] = $versionDesc; + } + + public function getVersionDesc() + { + return $this->versionDesc; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.audit.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditedCancelRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditedCancelRequest.php new file mode 100755 index 0000000..0c97b07 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionAuditedCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.audited.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionBuildQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionBuildQueryRequest.php new file mode 100755 index 0000000..a716819 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionBuildQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.build.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionDeleteRequest.php new file mode 100755 index 0000000..c3c761f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionDetailQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionDetailQueryRequest.php new file mode 100755 index 0000000..2262441 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayCancelRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayCancelRequest.php new file mode 100755 index 0000000..0fc962f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.gray.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayOnlineRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayOnlineRequest.php new file mode 100755 index 0000000..db19be2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionGrayOnlineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.gray.online"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionListQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionListQueryRequest.php new file mode 100755 index 0000000..c17d6d8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionListQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionOfflineRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionOfflineRequest.php new file mode 100755 index 0000000..d3edc6f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionOnlineRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionOnlineRequest.php new file mode 100755 index 0000000..24df80f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionOnlineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.online"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionRollbackRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionRollbackRequest.php new file mode 100755 index 0000000..4d71e74 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionRollbackRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.rollback"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenMiniVersionUploadRequest.php b/extend/app_alipay/aop/request/AlipayOpenMiniVersionUploadRequest.php new file mode 100755 index 0000000..1e69d93 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenMiniVersionUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.mini.version.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php new file mode 100755 index 0000000..6d031e5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAccountCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php new file mode 100755 index 0000000..c7afd4a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAccountDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php new file mode 100755 index 0000000..1ac384a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAccountResetRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAccountResetRequest.php new file mode 100755 index 0000000..da18654 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAccountResetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.account.reset"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAdvertBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertBatchqueryRequest.php new file mode 100755 index 0000000..926c760 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAdvertCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertCreateRequest.php new file mode 100755 index 0000000..0c02d54 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.advert.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAdvertDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertDeleteRequest.php new file mode 100755 index 0000000..70f33f0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.advert.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicAdvertModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertModifyRequest.php new file mode 100755 index 0000000..eade85b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicAdvertModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.advert.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicArticlesummaryDataBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicArticlesummaryDataBatchqueryRequest.php new file mode 100755 index 0000000..e712cb9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicArticlesummaryDataBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.articlesummary.data.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php new file mode 100755 index 0000000..b567c4f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicContactFollowBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php new file mode 100755 index 0000000..6d4b21a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicDefaultExtensionCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.default.extension.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php new file mode 100755 index 0000000..445ab76 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicFollowBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.follow.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGisQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGisQueryRequest.php new file mode 100755 index 0000000..d32addc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGisQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.gis.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php new file mode 100755 index 0000000..bd1c0a6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGroupBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php new file mode 100755 index 0000000..930299d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGroupCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php new file mode 100755 index 0000000..7ec799b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGroupCrowdQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.crowd.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php new file mode 100755 index 0000000..4e647ff --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGroupDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php new file mode 100755 index 0000000..3712ca0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicGroupModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.group.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php new file mode 100755 index 0000000..00d5820 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicInfoModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.info.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php new file mode 100755 index 0000000..509b736 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicInfoQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php new file mode 100755 index 0000000..43ed51b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php new file mode 100755 index 0000000..d9b8307 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php new file mode 100755 index 0000000..c114c4a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php new file mode 100755 index 0000000..15dea91 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php new file mode 100755 index 0000000..6b9e6d5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php new file mode 100755 index 0000000..df8349e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php new file mode 100755 index 0000000..9b2282e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLabelUserQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.label.user.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php new file mode 100755 index 0000000..fe93091 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAboardApplyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php new file mode 100755 index 0000000..2ef4db8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAccountCreateRequest.php @@ -0,0 +1,247 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setCatagoryId($catagoryId) + { + $this->catagoryId = $catagoryId; + $this->apiParas["catagory_id"] = $catagoryId; + } + + public function getCatagoryId() + { + return $this->catagoryId; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setContent($content) + { + $this->content = $content; + $this->apiParas["content"] = $content; + } + + public function getContent() + { + return $this->content; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.account.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php new file mode 100755 index 0000000..629e3e6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentCreateRequest.php @@ -0,0 +1,375 @@ +商家经营类目 中的“经营类目编码” + **/ + private $mccCode; + + /** + * 外部入驻申请单据号,由开发者生成,并需保证在开发者端不重复。另,如果代创建被驳回,需更换新的申请号,原申请号不能再次使用 + **/ + private $outBizNo; + + /** + * 自有知识产权证书图片 + **/ + private $ownIntellectualPic; + + /** + * 生活号简介 + **/ + private $publicDesc; + + /** + * 生活号名称 + **/ + private $publicName; + + /** + * 店铺内景图片,被代创建商户运营主体为个人账户必填,企业账户选填 + **/ + private $shopScenePic; + + /** + * 店铺门头照图片,被代创建商户运营主体为个人账户必填,企业账户选填 + **/ + private $shopSignBoardPic; + + /** + * 企业特殊资质图片,可参考 商家经营类目 中的 “需要的特殊资质证书” + **/ + private $specialLicensePic; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setAccount($account) + { + $this->account = $account; + $this->apiParas["account"] = $account; + } + + public function getAccount() + { + return $this->account; + } + + public function setBackgroundPic($backgroundPic) + { + $this->backgroundPic = $backgroundPic; + $this->apiParas["background_pic"] = $backgroundPic; + } + + public function getBackgroundPic() + { + return $this->backgroundPic; + } + + public function setBusinessLicenseAuthPic($businessLicenseAuthPic) + { + $this->businessLicenseAuthPic = $businessLicenseAuthPic; + $this->apiParas["business_license_auth_pic"] = $businessLicenseAuthPic; + } + + public function getBusinessLicenseAuthPic() + { + return $this->businessLicenseAuthPic; + } + + public function setBusinessLicenseNo($businessLicenseNo) + { + $this->businessLicenseNo = $businessLicenseNo; + $this->apiParas["business_license_no"] = $businessLicenseNo; + } + + public function getBusinessLicenseNo() + { + return $this->businessLicenseNo; + } + + public function setBusinessLicensePic($businessLicensePic) + { + $this->businessLicensePic = $businessLicensePic; + $this->apiParas["business_license_pic"] = $businessLicensePic; + } + + public function getBusinessLicensePic() + { + return $this->businessLicensePic; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactMobile($contactMobile) + { + $this->contactMobile = $contactMobile; + $this->apiParas["contact_mobile"] = $contactMobile; + } + + public function getContactMobile() + { + return $this->contactMobile; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setLogoPic($logoPic) + { + $this->logoPic = $logoPic; + $this->apiParas["logo_pic"] = $logoPic; + } + + public function getLogoPic() + { + return $this->logoPic; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setOutBizNo($outBizNo) + { + $this->outBizNo = $outBizNo; + $this->apiParas["out_biz_no"] = $outBizNo; + } + + public function getOutBizNo() + { + return $this->outBizNo; + } + + public function setOwnIntellectualPic($ownIntellectualPic) + { + $this->ownIntellectualPic = $ownIntellectualPic; + $this->apiParas["own_intellectual_pic"] = $ownIntellectualPic; + } + + public function getOwnIntellectualPic() + { + return $this->ownIntellectualPic; + } + + public function setPublicDesc($publicDesc) + { + $this->publicDesc = $publicDesc; + $this->apiParas["public_desc"] = $publicDesc; + } + + public function getPublicDesc() + { + return $this->publicDesc; + } + + public function setPublicName($publicName) + { + $this->publicName = $publicName; + $this->apiParas["public_name"] = $publicName; + } + + public function getPublicName() + { + return $this->publicName; + } + + public function setShopScenePic($shopScenePic) + { + $this->shopScenePic = $shopScenePic; + $this->apiParas["shop_scene_pic"] = $shopScenePic; + } + + public function getShopScenePic() + { + return $this->shopScenePic; + } + + public function setShopSignBoardPic($shopSignBoardPic) + { + $this->shopSignBoardPic = $shopSignBoardPic; + $this->apiParas["shop_sign_board_pic"] = $shopSignBoardPic; + } + + public function getShopSignBoardPic() + { + return $this->shopSignBoardPic; + } + + public function setSpecialLicensePic($specialLicensePic) + { + $this->specialLicensePic = $specialLicensePic; + $this->apiParas["special_license_pic"] = $specialLicensePic; + } + + public function getSpecialLicensePic() + { + return $this->specialLicensePic; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.agent.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php new file mode 100755 index 0000000..8d6bf5b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeAgentcreateQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.agentcreate.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php new file mode 100755 index 0000000..9f7bd86 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeCreateRequest.php @@ -0,0 +1,310 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setDescription($description) + { + $this->description = $description; + $this->apiParas["description"] = $description; + } + + public function getDescription() + { + return $this->description; + } + + public function setExtendData($extendData) + { + $this->extendData = $extendData; + $this->apiParas["extend_data"] = $extendData; + } + + public function getExtendData() + { + return $this->extendData; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setMccCode($mccCode) + { + $this->mccCode = $mccCode; + $this->apiParas["mcc_code"] = $mccCode; + } + + public function getMccCode() + { + return $this->mccCode; + } + + public function setPublicBizType($publicBizType) + { + $this->publicBizType = $publicBizType; + $this->apiParas["public_biz_type"] = $publicBizType; + } + + public function getPublicBizType() + { + return $this->publicBizType; + } + + public function setShowStyle($showStyle) + { + $this->showStyle = $showStyle; + $this->apiParas["show_style"] = $showStyle; + } + + public function getShowStyle() + { + return $this->showStyle; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php new file mode 100755 index 0000000..5e62a15 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeDebarkApplyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php new file mode 100755 index 0000000..200d71d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php new file mode 100755 index 0000000..f46ee38 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php new file mode 100755 index 0000000..09449b4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php new file mode 100755 index 0000000..3fc71b0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeLabelModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.label.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php new file mode 100755 index 0000000..ab54f8d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeModifyRequest.php @@ -0,0 +1,262 @@ +background = $background; + $this->apiParas["background"] = $background; + } + + public function getBackground() + { + return $this->background; + } + + public function setContactEmail($contactEmail) + { + $this->contactEmail = $contactEmail; + $this->apiParas["contact_email"] = $contactEmail; + } + + public function getContactEmail() + { + return $this->contactEmail; + } + + public function setContactName($contactName) + { + $this->contactName = $contactName; + $this->apiParas["contact_name"] = $contactName; + } + + public function getContactName() + { + return $this->contactName; + } + + public function setContactTel($contactTel) + { + $this->contactTel = $contactTel; + $this->apiParas["contact_tel"] = $contactTel; + } + + public function getContactTel() + { + return $this->contactTel; + } + + public function setCustomerTel($customerTel) + { + $this->customerTel = $customerTel; + $this->apiParas["customer_tel"] = $customerTel; + } + + public function getCustomerTel() + { + return $this->customerTel; + } + + public function setDescription($description) + { + $this->description = $description; + $this->apiParas["description"] = $description; + } + + public function getDescription() + { + return $this->description; + } + + public function setExtendData($extendData) + { + $this->extendData = $extendData; + $this->apiParas["extend_data"] = $extendData; + } + + public function getExtendData() + { + return $this->extendData; + } + + public function setLifeName($lifeName) + { + $this->lifeName = $lifeName; + $this->apiParas["life_name"] = $lifeName; + } + + public function getLifeName() + { + return $this->lifeName; + } + + public function setLogo($logo) + { + $this->logo = $logo; + $this->apiParas["logo"] = $logo; + } + + public function getLogo() + { + return $this->logo; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php new file mode 100755 index 0000000..887dd70 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgRecallRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.msg.recall"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php new file mode 100755 index 0000000..e41265c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicLifeMsgSendRequest.php @@ -0,0 +1,337 @@ +category = $category; + $this->apiParas["category"] = $category; + } + + public function getCategory() + { + return $this->category; + } + + public function setContent($content) + { + $this->content = $content; + $this->apiParas["content"] = $content; + } + + public function getContent() + { + return $this->content; + } + + public function setCover($cover) + { + $this->cover = $cover; + $this->apiParas["cover"] = $cover; + } + + public function getCover() + { + return $this->cover; + } + + public function setDesc($desc) + { + $this->desc = $desc; + $this->apiParas["desc"] = $desc; + } + + public function getDesc() + { + return $this->desc; + } + + public function setMsgType($msgType) + { + $this->msgType = $msgType; + $this->apiParas["msg_type"] = $msgType; + } + + public function getMsgType() + { + return $this->msgType; + } + + public function setSourceExtInfo($sourceExtInfo) + { + $this->sourceExtInfo = $sourceExtInfo; + $this->apiParas["source_ext_info"] = $sourceExtInfo; + } + + public function getSourceExtInfo() + { + return $this->sourceExtInfo; + } + + public function setTitle($title) + { + $this->title = $title; + $this->apiParas["title"] = $title; + } + + public function getTitle() + { + return $this->title; + } + + public function setUniqueMsgId($uniqueMsgId) + { + $this->uniqueMsgId = $uniqueMsgId; + $this->apiParas["unique_msg_id"] = $uniqueMsgId; + } + + public function getUniqueMsgId() + { + return $this->uniqueMsgId; + } + + public function setVideoLength($videoLength) + { + $this->videoLength = $videoLength; + $this->apiParas["video_length"] = $videoLength; + } + + public function getVideoLength() + { + return $this->videoLength; + } + + public function setVideoSamples($videoSamples) + { + $this->videoSamples = $videoSamples; + $this->apiParas["video_samples"] = $videoSamples; + } + + public function getVideoSamples() + { + return $this->videoSamples; + } + + public function setVideoSize($videoSize) + { + $this->videoSize = $videoSize; + $this->apiParas["video_size"] = $videoSize; + } + + public function getVideoSize() + { + return $this->videoSize; + } + + public function setVideoSource($videoSource) + { + $this->videoSource = $videoSource; + $this->apiParas["video_source"] = $videoSource; + } + + public function getVideoSource() + { + return $this->videoSource; + } + + public function setVideoTemporaryUrl($videoTemporaryUrl) + { + $this->videoTemporaryUrl = $videoTemporaryUrl; + $this->apiParas["video_temporary_url"] = $videoTemporaryUrl; + } + + public function getVideoTemporaryUrl() + { + return $this->videoTemporaryUrl; + } + + public function setVideoUrl($videoUrl) + { + $this->videoUrl = $videoUrl; + $this->apiParas["video_url"] = $videoUrl; + } + + public function getVideoUrl() + { + return $this->videoUrl; + } + + public function getApiMethodName() + { + return "alipay.open.public.life.msg.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php new file mode 100755 index 0000000..a5a6db8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.matchuser.label.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php new file mode 100755 index 0000000..5b36bc7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMatchuserLabelDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.matchuser.label.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php new file mode 100755 index 0000000..9076aa4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMenuBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php new file mode 100755 index 0000000..2ac5288 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMenuCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.menu.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMenuDataBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMenuDataBatchqueryRequest.php new file mode 100755 index 0000000..ae972e7 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMenuDataBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.menu.data.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php new file mode 100755 index 0000000..1a8238c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMenuModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.menu.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php new file mode 100755 index 0000000..ab5c002 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMenuQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php new file mode 100755 index 0000000..4fcab75 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageCustomSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.custom.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php new file mode 100755 index 0000000..94f0e42 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageGroupSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.group.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php new file mode 100755 index 0000000..2b19d5e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageLabelSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.label.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageQueryRequest.php new file mode 100755 index 0000000..1570f76 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php new file mode 100755 index 0000000..fb04467 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageSingleSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.single.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php new file mode 100755 index 0000000..bcf5ca1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMessageTotalSendRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.message.total.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php new file mode 100755 index 0000000..bee43d6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicMultimediaDownloadProxyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php new file mode 100755 index 0000000..14afbb8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuOperateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.menu.operate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php new file mode 100755 index 0000000..5a88def --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerMenuQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.menu.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php new file mode 100755 index 0000000..0652dfc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPartnerSubscribeSyncRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.partner.subscribe.sync"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php new file mode 100755 index 0000000..3d5094d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php new file mode 100755 index 0000000..f71b701 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php new file mode 100755 index 0000000..28730d4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php new file mode 100755 index 0000000..ccd39bd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedExtensionSetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.extension.set"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php new file mode 100755 index 0000000..c79dd8c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.menu.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php new file mode 100755 index 0000000..61f213e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicPersonalizedMenuDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.personalized.menu.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php new file mode 100755 index 0000000..731501d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicQrcodeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.qrcode.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicSettingCategoryQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicSettingCategoryQueryRequest.php new file mode 100755 index 0000000..71d1f38 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicSettingCategoryQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php new file mode 100755 index 0000000..0949868 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicShortlinkCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.shortlink.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicSinglearticleDataBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicSinglearticleDataBatchqueryRequest.php new file mode 100755 index 0000000..e695450 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicSinglearticleDataBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.singlearticle.data.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php new file mode 100755 index 0000000..708c9dc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.template.message.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php new file mode 100755 index 0000000..6094c66 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTemplateMessageIndustryModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.template.message.industry.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php new file mode 100755 index 0000000..96750fe --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicThirdCustomerServiceRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.third.customer.service"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTopicBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTopicBatchqueryRequest.php new file mode 100755 index 0000000..e9bcdf4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTopicBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTopicCreateRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTopicCreateRequest.php new file mode 100755 index 0000000..d243493 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTopicCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.topic.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTopicDeleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTopicDeleteRequest.php new file mode 100755 index 0000000..a89f76c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTopicDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.topic.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicTopicModifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicTopicModifyRequest.php new file mode 100755 index 0000000..efb0f73 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicTopicModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.topic.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicUserDataBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicUserDataBatchqueryRequest.php new file mode 100755 index 0000000..fff7f4d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicUserDataBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.user.data.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicUserFollowQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicUserFollowQueryRequest.php new file mode 100755 index 0000000..3aa1d00 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicUserFollowQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.user.follow.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenPublicXwbtestabcdBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenPublicXwbtestabcdBatchqueryRequest.php new file mode 100755 index 0000000..b577a54 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenPublicXwbtestabcdBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.public.xwbtestabcd.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php new file mode 100755 index 0000000..76b75d3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.commodity.shop.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php new file mode 100755 index 0000000..8e7d61f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketCommodityShopOnlineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.commodity.shop.online"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php new file mode 100755 index 0000000..9d416a4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderAcceptRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.accept"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php new file mode 100755 index 0000000..3e68c24 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php new file mode 100755 index 0000000..a2ff7b8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemCompleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.complete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php new file mode 100755 index 0000000..2079676 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderItemConfirmRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.item.confirm"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php new file mode 100755 index 0000000..db89d75 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderNotifyRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php new file mode 100755 index 0000000..3be3286 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php new file mode 100755 index 0000000..2da669a --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOpenServicemarketOrderRejectRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.open.servicemarket.order.reject"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayOperatorMobileBindRequest.php b/extend/app_alipay/aop/request/AlipayOperatorMobileBindRequest.php new file mode 100755 index 0000000..710d7e9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayOperatorMobileBindRequest.php @@ -0,0 +1,202 @@ +checkSigncard = $checkSigncard; + $this->apiParas["check_signcard"] = $checkSigncard; + } + + public function getCheckSigncard() + { + return $this->checkSigncard; + } + + public function setfReturnUrl($fReturnUrl) + { + $this->fReturnUrl = $fReturnUrl; + $this->apiParas["f_return_url"] = $fReturnUrl; + } + + public function getfReturnUrl() + { + return $this->fReturnUrl; + } + + public function setHasSpi($hasSpi) + { + $this->hasSpi = $hasSpi; + $this->apiParas["has_spi"] = $hasSpi; + } + + public function getHasSpi() + { + return $this->hasSpi; + } + + public function setOperatorName($operatorName) + { + $this->operatorName = $operatorName; + $this->apiParas["operator_name"] = $operatorName; + } + + public function getOperatorName() + { + return $this->operatorName; + } + + public function setProvinceName($provinceName) + { + $this->provinceName = $provinceName; + $this->apiParas["province_name"] = $provinceName; + } + + public function getProvinceName() + { + return $this->provinceName; + } + + public function setsReturnUrl($sReturnUrl) + { + $this->sReturnUrl = $sReturnUrl; + $this->apiParas["s_return_url"] = $sReturnUrl; + } + + public function getsReturnUrl() + { + return $this->sReturnUrl; + } + + public function getApiMethodName() + { + return "alipay.operator.mobile.bind"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassCodeAddRequest.php b/extend/app_alipay/aop/request/AlipayPassCodeAddRequest.php new file mode 100755 index 0000000..6aef681 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassCodeAddRequest.php @@ -0,0 +1,170 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setRecognitionInfo($recognitionInfo) + { + $this->recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.code.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassCodeVerifyRequest.php b/extend/app_alipay/aop/request/AlipayPassCodeVerifyRequest.php new file mode 100755 index 0000000..af44151 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassCodeVerifyRequest.php @@ -0,0 +1,170 @@ +extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setOperatorId($operatorId) + { + $this->operatorId = $operatorId; + $this->apiParas["operator_id"] = $operatorId; + } + + public function getOperatorId() + { + return $this->operatorId; + } + + public function setOperatorType($operatorType) + { + $this->operatorType = $operatorType; + $this->apiParas["operator_type"] = $operatorType; + } + + public function getOperatorType() + { + return $this->operatorType; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function getApiMethodName() + { + return "alipay.pass.code.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassFileAddRequest.php b/extend/app_alipay/aop/request/AlipayPassFileAddRequest.php new file mode 100755 index 0000000..ca0f6d4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassFileAddRequest.php @@ -0,0 +1,153 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setRecognitionInfo($recognitionInfo) + { + $this->recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function getApiMethodName() + { + return "alipay.pass.file.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassInstanceAddRequest.php b/extend/app_alipay/aop/request/AlipayPassInstanceAddRequest.php new file mode 100755 index 0000000..10eab63 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassInstanceAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.instance.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassInstanceUpdateRequest.php b/extend/app_alipay/aop/request/AlipayPassInstanceUpdateRequest.php new file mode 100755 index 0000000..4a47872 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassInstanceUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.instance.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassSyncAddRequest.php b/extend/app_alipay/aop/request/AlipayPassSyncAddRequest.php new file mode 100755 index 0000000..e264983 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassSyncAddRequest.php @@ -0,0 +1,166 @@ +fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function setOutTradeNo($outTradeNo) + { + $this->outTradeNo = $outTradeNo; + $this->apiParas["out_trade_no"] = $outTradeNo; + } + + public function getOutTradeNo() + { + return $this->outTradeNo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.pass.sync.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassSyncUpdateRequest.php b/extend/app_alipay/aop/request/AlipayPassSyncUpdateRequest.php new file mode 100755 index 0000000..e717d66 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassSyncUpdateRequest.php @@ -0,0 +1,214 @@ +channelId = $channelId; + $this->apiParas["channel_id"] = $channelId; + } + + public function getChannelId() + { + return $this->channelId; + } + + public function setExtInfo($extInfo) + { + $this->extInfo = $extInfo; + $this->apiParas["ext_info"] = $extInfo; + } + + public function getExtInfo() + { + return $this->extInfo; + } + + public function setPass($pass) + { + $this->pass = $pass; + $this->apiParas["pass"] = $pass; + } + + public function getPass() + { + return $this->pass; + } + + public function setSerialNumber($serialNumber) + { + $this->serialNumber = $serialNumber; + $this->apiParas["serial_number"] = $serialNumber; + } + + public function getSerialNumber() + { + return $this->serialNumber; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.sync.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTemplateAddRequest.php b/extend/app_alipay/aop/request/AlipayPassTemplateAddRequest.php new file mode 100755 index 0000000..ef29e0c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTemplateAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.template.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTemplateUpdateRequest.php b/extend/app_alipay/aop/request/AlipayPassTemplateUpdateRequest.php new file mode 100755 index 0000000..060af42 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTemplateUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pass.template.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTplAddRequest.php b/extend/app_alipay/aop/request/AlipayPassTplAddRequest.php new file mode 100755 index 0000000..e53f024 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTplAddRequest.php @@ -0,0 +1,135 @@ +tplContent = $tplContent; + $this->apiParas["tpl_content"] = $tplContent; + } + + public function getTplContent() + { + return $this->tplContent; + } + + public function setUniqueId($uniqueId) + { + $this->uniqueId = $uniqueId; + $this->apiParas["unique_id"] = $uniqueId; + } + + public function getUniqueId() + { + return $this->uniqueId; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTplContentAddRequest.php b/extend/app_alipay/aop/request/AlipayPassTplContentAddRequest.php new file mode 100755 index 0000000..b418f44 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTplContentAddRequest.php @@ -0,0 +1,169 @@ +recognitionInfo = $recognitionInfo; + $this->apiParas["recognition_info"] = $recognitionInfo; + } + + public function getRecognitionInfo() + { + return $this->recognitionInfo; + } + + public function setRecognitionType($recognitionType) + { + $this->recognitionType = $recognitionType; + $this->apiParas["recognition_type"] = $recognitionType; + } + + public function getRecognitionType() + { + return $this->recognitionType; + } + + public function setTplId($tplId) + { + $this->tplId = $tplId; + $this->apiParas["tpl_id"] = $tplId; + } + + public function getTplId() + { + return $this->tplId; + } + + public function setTplParams($tplParams) + { + $this->tplParams = $tplParams; + $this->apiParas["tpl_params"] = $tplParams; + } + + public function getTplParams() + { + return $this->tplParams; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.content.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTplContentUpdateRequest.php b/extend/app_alipay/aop/request/AlipayPassTplContentUpdateRequest.php new file mode 100755 index 0000000..1368d42 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTplContentUpdateRequest.php @@ -0,0 +1,198 @@ +channelId = $channelId; + $this->apiParas["channel_id"] = $channelId; + } + + public function getChannelId() + { + return $this->channelId; + } + + public function setSerialNumber($serialNumber) + { + $this->serialNumber = $serialNumber; + $this->apiParas["serial_number"] = $serialNumber; + } + + public function getSerialNumber() + { + return $this->serialNumber; + } + + public function setStatus($status) + { + $this->status = $status; + $this->apiParas["status"] = $status; + } + + public function getStatus() + { + return $this->status; + } + + public function setTplParams($tplParams) + { + $this->tplParams = $tplParams; + $this->apiParas["tpl_params"] = $tplParams; + } + + public function getTplParams() + { + return $this->tplParams; + } + + public function setVerifyCode($verifyCode) + { + $this->verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function setVerifyType($verifyType) + { + $this->verifyType = $verifyType; + $this->apiParas["verify_type"] = $verifyType; + } + + public function getVerifyType() + { + return $this->verifyType; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.content.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassTplUpdateRequest.php b/extend/app_alipay/aop/request/AlipayPassTplUpdateRequest.php new file mode 100755 index 0000000..12008aa --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassTplUpdateRequest.php @@ -0,0 +1,134 @@ +tplContent = $tplContent; + $this->apiParas["tpl_content"] = $tplContent; + } + + public function getTplContent() + { + return $this->tplContent; + } + + public function setTplId($tplId) + { + $this->tplId = $tplId; + $this->apiParas["tpl_id"] = $tplId; + } + + public function getTplId() + { + return $this->tplId; + } + + public function getApiMethodName() + { + return "alipay.pass.tpl.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPassVerifyQueryRequest.php b/extend/app_alipay/aop/request/AlipayPassVerifyQueryRequest.php new file mode 100755 index 0000000..64e88eb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPassVerifyQueryRequest.php @@ -0,0 +1,118 @@ +verifyCode = $verifyCode; + $this->apiParas["verify_code"] = $verifyCode; + } + + public function getVerifyCode() + { + return $this->verifyCode; + } + + public function getApiMethodName() + { + return "alipay.pass.verify.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php b/extend/app_alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php new file mode 100755 index 0000000..c853b28 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPcreditHuabeiPromoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.huabei.promo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php b/extend/app_alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php new file mode 100755 index 0000000..9a0005f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPcreditLoanApplyCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.loan.apply.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php b/extend/app_alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php new file mode 100755 index 0000000..14cf2ad --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPcreditLoanRefundCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.pcredit.loan.refund.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPlatformOpenidGetRequest.php b/extend/app_alipay/aop/request/AlipayPlatformOpenidGetRequest.php new file mode 100755 index 0000000..d516807 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPlatformOpenidGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.platform.openid.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPlatformUseridGetRequest.php b/extend/app_alipay/aop/request/AlipayPlatformUseridGetRequest.php new file mode 100755 index 0000000..375c6bc --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPlatformUseridGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.platform.userid.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPointBalanceGetRequest.php b/extend/app_alipay/aop/request/AlipayPointBalanceGetRequest.php new file mode 100755 index 0000000..f52ee38 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPointBalanceGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPointBudgetGetRequest.php b/extend/app_alipay/aop/request/AlipayPointBudgetGetRequest.php new file mode 100755 index 0000000..9020ebf --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPointBudgetGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPointOrderAddRequest.php b/extend/app_alipay/aop/request/AlipayPointOrderAddRequest.php new file mode 100755 index 0000000..397cb82 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPointOrderAddRequest.php @@ -0,0 +1,198 @@ +memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderTime($orderTime) + { + $this->orderTime = $orderTime; + $this->apiParas["order_time"] = $orderTime; + } + + public function getOrderTime() + { + return $this->orderTime; + } + + public function setPointCount($pointCount) + { + $this->pointCount = $pointCount; + $this->apiParas["point_count"] = $pointCount; + } + + public function getPointCount() + { + return $this->pointCount; + } + + public function setUserSymbol($userSymbol) + { + $this->userSymbol = $userSymbol; + $this->apiParas["user_symbol"] = $userSymbol; + } + + public function getUserSymbol() + { + return $this->userSymbol; + } + + public function setUserSymbolType($userSymbolType) + { + $this->userSymbolType = $userSymbolType; + $this->apiParas["user_symbol_type"] = $userSymbolType; + } + + public function getUserSymbolType() + { + return $this->userSymbolType; + } + + public function getApiMethodName() + { + return "alipay.point.order.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPointOrderGetRequest.php b/extend/app_alipay/aop/request/AlipayPointOrderGetRequest.php new file mode 100755 index 0000000..3cae954 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPointOrderGetRequest.php @@ -0,0 +1,150 @@ +merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setUserSymbol($userSymbol) + { + $this->userSymbol = $userSymbol; + $this->apiParas["user_symbol"] = $userSymbol; + } + + public function getUserSymbol() + { + return $this->userSymbol; + } + + public function setUserSymbolType($userSymbolType) + { + $this->userSymbolType = $userSymbolType; + $this->apiParas["user_symbol_type"] = $userSymbolType; + } + + public function getUserSymbolType() + { + return $this->userSymbolType; + } + + public function getApiMethodName() + { + return "alipay.point.order.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php b/extend/app_alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php new file mode 100755 index 0000000..8d5aa8c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayPromorulecenterRuleAnalyzeRequest.php @@ -0,0 +1,150 @@ +bizId = $bizId; + $this->apiParas["biz_id"] = $bizId; + } + + public function getBizId() + { + return $this->bizId; + } + + public function setRuleUuid($ruleUuid) + { + $this->ruleUuid = $ruleUuid; + $this->apiParas["rule_uuid"] = $ruleUuid; + } + + public function getRuleUuid() + { + return $this->ruleUuid; + } + + public function setUserId($userId) + { + $this->userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.promorulecenter.rule.analyze"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php b/extend/app_alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php new file mode 100755 index 0000000..35cddcd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityInfoAnalysisRequest.php @@ -0,0 +1,470 @@ +envClientBaseBand = $envClientBaseBand; + $this->apiParas["env_client_base_band"] = $envClientBaseBand; + } + + public function getEnvClientBaseBand() + { + return $this->envClientBaseBand; + } + + public function setEnvClientBaseStation($envClientBaseStation) + { + $this->envClientBaseStation = $envClientBaseStation; + $this->apiParas["env_client_base_station"] = $envClientBaseStation; + } + + public function getEnvClientBaseStation() + { + return $this->envClientBaseStation; + } + + public function setEnvClientCoordinates($envClientCoordinates) + { + $this->envClientCoordinates = $envClientCoordinates; + $this->apiParas["env_client_coordinates"] = $envClientCoordinates; + } + + public function getEnvClientCoordinates() + { + return $this->envClientCoordinates; + } + + public function setEnvClientImei($envClientImei) + { + $this->envClientImei = $envClientImei; + $this->apiParas["env_client_imei"] = $envClientImei; + } + + public function getEnvClientImei() + { + return $this->envClientImei; + } + + public function setEnvClientImsi($envClientImsi) + { + $this->envClientImsi = $envClientImsi; + $this->apiParas["env_client_imsi"] = $envClientImsi; + } + + public function getEnvClientImsi() + { + return $this->envClientImsi; + } + + public function setEnvClientIosUdid($envClientIosUdid) + { + $this->envClientIosUdid = $envClientIosUdid; + $this->apiParas["env_client_ios_udid"] = $envClientIosUdid; + } + + public function getEnvClientIosUdid() + { + return $this->envClientIosUdid; + } + + public function setEnvClientIp($envClientIp) + { + $this->envClientIp = $envClientIp; + $this->apiParas["env_client_ip"] = $envClientIp; + } + + public function getEnvClientIp() + { + return $this->envClientIp; + } + + public function setEnvClientMac($envClientMac) + { + $this->envClientMac = $envClientMac; + $this->apiParas["env_client_mac"] = $envClientMac; + } + + public function getEnvClientMac() + { + return $this->envClientMac; + } + + public function setEnvClientScreen($envClientScreen) + { + $this->envClientScreen = $envClientScreen; + $this->apiParas["env_client_screen"] = $envClientScreen; + } + + public function getEnvClientScreen() + { + return $this->envClientScreen; + } + + public function setEnvClientUuid($envClientUuid) + { + $this->envClientUuid = $envClientUuid; + $this->apiParas["env_client_uuid"] = $envClientUuid; + } + + public function getEnvClientUuid() + { + return $this->envClientUuid; + } + + public function setJsTokenId($jsTokenId) + { + $this->jsTokenId = $jsTokenId; + $this->apiParas["js_token_id"] = $jsTokenId; + } + + public function getJsTokenId() + { + return $this->jsTokenId; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function setUserAccountNo($userAccountNo) + { + $this->userAccountNo = $userAccountNo; + $this->apiParas["user_account_no"] = $userAccountNo; + } + + public function getUserAccountNo() + { + return $this->userAccountNo; + } + + public function setUserBindBankcard($userBindBankcard) + { + $this->userBindBankcard = $userBindBankcard; + $this->apiParas["user_bind_bankcard"] = $userBindBankcard; + } + + public function getUserBindBankcard() + { + return $this->userBindBankcard; + } + + public function setUserBindBankcardType($userBindBankcardType) + { + $this->userBindBankcardType = $userBindBankcardType; + $this->apiParas["user_bind_bankcard_type"] = $userBindBankcardType; + } + + public function getUserBindBankcardType() + { + return $this->userBindBankcardType; + } + + public function setUserBindMobile($userBindMobile) + { + $this->userBindMobile = $userBindMobile; + $this->apiParas["user_bind_mobile"] = $userBindMobile; + } + + public function getUserBindMobile() + { + return $this->userBindMobile; + } + + public function setUserIdentityType($userIdentityType) + { + $this->userIdentityType = $userIdentityType; + $this->apiParas["user_identity_type"] = $userIdentityType; + } + + public function getUserIdentityType() + { + return $this->userIdentityType; + } + + public function setUserRealName($userRealName) + { + $this->userRealName = $userRealName; + $this->apiParas["user_real_name"] = $userRealName; + } + + public function getUserRealName() + { + return $this->userRealName; + } + + public function setUserRegDate($userRegDate) + { + $this->userRegDate = $userRegDate; + $this->apiParas["user_reg_date"] = $userRegDate; + } + + public function getUserRegDate() + { + return $this->userRegDate; + } + + public function setUserRegEmail($userRegEmail) + { + $this->userRegEmail = $userRegEmail; + $this->apiParas["user_reg_email"] = $userRegEmail; + } + + public function getUserRegEmail() + { + return $this->userRegEmail; + } + + public function setUserRegMobile($userRegMobile) + { + $this->userRegMobile = $userRegMobile; + $this->apiParas["user_reg_mobile"] = $userRegMobile; + } + + public function getUserRegMobile() + { + return $this->userRegMobile; + } + + public function setUserrIdentityNo($userrIdentityNo) + { + $this->userrIdentityNo = $userrIdentityNo; + $this->apiParas["userr_identity_no"] = $userrIdentityNo; + } + + public function getUserrIdentityNo() + { + return $this->userrIdentityNo; + } + + public function getApiMethodName() + { + return "alipay.security.info.analysis"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php new file mode 100755 index 0000000..1df0f4d --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdAlipaySecurityProdTestRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.alipay.security.prod.test"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php new file mode 100755 index 0000000..e75b215 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdAmlriskQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.amlrisk.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php new file mode 100755 index 0000000..6626644 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoAddRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.facerepo.add"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php new file mode 100755 index 0000000..ea64449 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFacerepoSearchRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.facerepo.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php new file mode 100755 index 0000000..99469d2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.apply.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php new file mode 100755 index 0000000..c2b29e5 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php new file mode 100755 index 0000000..dc86d49 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintRiskcontrolQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintRiskcontrolQueryRequest.php new file mode 100755 index 0000000..5503cb6 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintRiskcontrolQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.riskcontrol.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php new file mode 100755 index 0000000..33ef319 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.verify.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php new file mode 100755 index 0000000..0f25c7b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdFingerprintVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.fingerprint.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php new file mode 100755 index 0000000..2a6ede9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureFileUploadRequest.php @@ -0,0 +1,134 @@ +bizProduct = $bizProduct; + $this->apiParas["biz_product"] = $bizProduct; + } + + public function getBizProduct() + { + return $this->bizProduct; + } + + public function setFileContent($fileContent) + { + $this->fileContent = $fileContent; + $this->apiParas["file_content"] = $fileContent; + } + + public function getFileContent() + { + return $this->fileContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.file.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php new file mode 100755 index 0000000..97730db --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php new file mode 100755 index 0000000..fe2133f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php new file mode 100755 index 0000000..33b3896 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdSignatureTaskQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.signature.task.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityProdXwbtestabcAbcQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityProdXwbtestabcAbcQueryRequest.php new file mode 100755 index 0000000..598a033 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityProdXwbtestabcAbcQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.prod.xwbtestabc.abc.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityRiskDetectRequest.php b/extend/app_alipay/aop/request/AlipaySecurityRiskDetectRequest.php new file mode 100755 index 0000000..941f766 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityRiskDetectRequest.php @@ -0,0 +1,998 @@ +buyerAccountNo = $buyerAccountNo; + $this->apiParas["buyer_account_no"] = $buyerAccountNo; + } + + public function getBuyerAccountNo() + { + return $this->buyerAccountNo; + } + + public function setBuyerBindBankcard($buyerBindBankcard) + { + $this->buyerBindBankcard = $buyerBindBankcard; + $this->apiParas["buyer_bind_bankcard"] = $buyerBindBankcard; + } + + public function getBuyerBindBankcard() + { + return $this->buyerBindBankcard; + } + + public function setBuyerBindBankcardType($buyerBindBankcardType) + { + $this->buyerBindBankcardType = $buyerBindBankcardType; + $this->apiParas["buyer_bind_bankcard_type"] = $buyerBindBankcardType; + } + + public function getBuyerBindBankcardType() + { + return $this->buyerBindBankcardType; + } + + public function setBuyerBindMobile($buyerBindMobile) + { + $this->buyerBindMobile = $buyerBindMobile; + $this->apiParas["buyer_bind_mobile"] = $buyerBindMobile; + } + + public function getBuyerBindMobile() + { + return $this->buyerBindMobile; + } + + public function setBuyerGrade($buyerGrade) + { + $this->buyerGrade = $buyerGrade; + $this->apiParas["buyer_grade"] = $buyerGrade; + } + + public function getBuyerGrade() + { + return $this->buyerGrade; + } + + public function setBuyerIdentityNo($buyerIdentityNo) + { + $this->buyerIdentityNo = $buyerIdentityNo; + $this->apiParas["buyer_identity_no"] = $buyerIdentityNo; + } + + public function getBuyerIdentityNo() + { + return $this->buyerIdentityNo; + } + + public function setBuyerIdentityType($buyerIdentityType) + { + $this->buyerIdentityType = $buyerIdentityType; + $this->apiParas["buyer_identity_type"] = $buyerIdentityType; + } + + public function getBuyerIdentityType() + { + return $this->buyerIdentityType; + } + + public function setBuyerRealName($buyerRealName) + { + $this->buyerRealName = $buyerRealName; + $this->apiParas["buyer_real_name"] = $buyerRealName; + } + + public function getBuyerRealName() + { + return $this->buyerRealName; + } + + public function setBuyerRegDate($buyerRegDate) + { + $this->buyerRegDate = $buyerRegDate; + $this->apiParas["buyer_reg_date"] = $buyerRegDate; + } + + public function getBuyerRegDate() + { + return $this->buyerRegDate; + } + + public function setBuyerRegEmail($buyerRegEmail) + { + $this->buyerRegEmail = $buyerRegEmail; + $this->apiParas["buyer_reg_email"] = $buyerRegEmail; + } + + public function getBuyerRegEmail() + { + return $this->buyerRegEmail; + } + + public function setBuyerRegMobile($buyerRegMobile) + { + $this->buyerRegMobile = $buyerRegMobile; + $this->apiParas["buyer_reg_mobile"] = $buyerRegMobile; + } + + public function getBuyerRegMobile() + { + return $this->buyerRegMobile; + } + + public function setBuyerSceneBankcard($buyerSceneBankcard) + { + $this->buyerSceneBankcard = $buyerSceneBankcard; + $this->apiParas["buyer_scene_bankcard"] = $buyerSceneBankcard; + } + + public function getBuyerSceneBankcard() + { + return $this->buyerSceneBankcard; + } + + public function setBuyerSceneBankcardType($buyerSceneBankcardType) + { + $this->buyerSceneBankcardType = $buyerSceneBankcardType; + $this->apiParas["buyer_scene_bankcard_type"] = $buyerSceneBankcardType; + } + + public function getBuyerSceneBankcardType() + { + return $this->buyerSceneBankcardType; + } + + public function setBuyerSceneEmail($buyerSceneEmail) + { + $this->buyerSceneEmail = $buyerSceneEmail; + $this->apiParas["buyer_scene_email"] = $buyerSceneEmail; + } + + public function getBuyerSceneEmail() + { + return $this->buyerSceneEmail; + } + + public function setBuyerSceneMobile($buyerSceneMobile) + { + $this->buyerSceneMobile = $buyerSceneMobile; + $this->apiParas["buyer_scene_mobile"] = $buyerSceneMobile; + } + + public function getBuyerSceneMobile() + { + return $this->buyerSceneMobile; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setEnvClientBaseBand($envClientBaseBand) + { + $this->envClientBaseBand = $envClientBaseBand; + $this->apiParas["env_client_base_band"] = $envClientBaseBand; + } + + public function getEnvClientBaseBand() + { + return $this->envClientBaseBand; + } + + public function setEnvClientBaseStation($envClientBaseStation) + { + $this->envClientBaseStation = $envClientBaseStation; + $this->apiParas["env_client_base_station"] = $envClientBaseStation; + } + + public function getEnvClientBaseStation() + { + return $this->envClientBaseStation; + } + + public function setEnvClientCoordinates($envClientCoordinates) + { + $this->envClientCoordinates = $envClientCoordinates; + $this->apiParas["env_client_coordinates"] = $envClientCoordinates; + } + + public function getEnvClientCoordinates() + { + return $this->envClientCoordinates; + } + + public function setEnvClientImei($envClientImei) + { + $this->envClientImei = $envClientImei; + $this->apiParas["env_client_imei"] = $envClientImei; + } + + public function getEnvClientImei() + { + return $this->envClientImei; + } + + public function setEnvClientImsi($envClientImsi) + { + $this->envClientImsi = $envClientImsi; + $this->apiParas["env_client_imsi"] = $envClientImsi; + } + + public function getEnvClientImsi() + { + return $this->envClientImsi; + } + + public function setEnvClientIosUdid($envClientIosUdid) + { + $this->envClientIosUdid = $envClientIosUdid; + $this->apiParas["env_client_ios_udid"] = $envClientIosUdid; + } + + public function getEnvClientIosUdid() + { + return $this->envClientIosUdid; + } + + public function setEnvClientIp($envClientIp) + { + $this->envClientIp = $envClientIp; + $this->apiParas["env_client_ip"] = $envClientIp; + } + + public function getEnvClientIp() + { + return $this->envClientIp; + } + + public function setEnvClientMac($envClientMac) + { + $this->envClientMac = $envClientMac; + $this->apiParas["env_client_mac"] = $envClientMac; + } + + public function getEnvClientMac() + { + return $this->envClientMac; + } + + public function setEnvClientScreen($envClientScreen) + { + $this->envClientScreen = $envClientScreen; + $this->apiParas["env_client_screen"] = $envClientScreen; + } + + public function getEnvClientScreen() + { + return $this->envClientScreen; + } + + public function setEnvClientUuid($envClientUuid) + { + $this->envClientUuid = $envClientUuid; + $this->apiParas["env_client_uuid"] = $envClientUuid; + } + + public function getEnvClientUuid() + { + return $this->envClientUuid; + } + + public function setItemQuantity($itemQuantity) + { + $this->itemQuantity = $itemQuantity; + $this->apiParas["item_quantity"] = $itemQuantity; + } + + public function getItemQuantity() + { + return $this->itemQuantity; + } + + public function setItemUnitPrice($itemUnitPrice) + { + $this->itemUnitPrice = $itemUnitPrice; + $this->apiParas["item_unit_price"] = $itemUnitPrice; + } + + public function getItemUnitPrice() + { + return $this->itemUnitPrice; + } + + public function setJsTokenId($jsTokenId) + { + $this->jsTokenId = $jsTokenId; + $this->apiParas["js_token_id"] = $jsTokenId; + } + + public function getJsTokenId() + { + return $this->jsTokenId; + } + + public function setOrderAmount($orderAmount) + { + $this->orderAmount = $orderAmount; + $this->apiParas["order_amount"] = $orderAmount; + } + + public function getOrderAmount() + { + return $this->orderAmount; + } + + public function setOrderCategory($orderCategory) + { + $this->orderCategory = $orderCategory; + $this->apiParas["order_category"] = $orderCategory; + } + + public function getOrderCategory() + { + return $this->orderCategory; + } + + public function setOrderCredateTime($orderCredateTime) + { + $this->orderCredateTime = $orderCredateTime; + $this->apiParas["order_credate_time"] = $orderCredateTime; + } + + public function getOrderCredateTime() + { + return $this->orderCredateTime; + } + + public function setOrderItemCity($orderItemCity) + { + $this->orderItemCity = $orderItemCity; + $this->apiParas["order_item_city"] = $orderItemCity; + } + + public function getOrderItemCity() + { + return $this->orderItemCity; + } + + public function setOrderItemName($orderItemName) + { + $this->orderItemName = $orderItemName; + $this->apiParas["order_item_name"] = $orderItemName; + } + + public function getOrderItemName() + { + return $this->orderItemName; + } + + public function setOrderNo($orderNo) + { + $this->orderNo = $orderNo; + $this->apiParas["order_no"] = $orderNo; + } + + public function getOrderNo() + { + return $this->orderNo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setReceiverAddress($receiverAddress) + { + $this->receiverAddress = $receiverAddress; + $this->apiParas["receiver_address"] = $receiverAddress; + } + + public function getReceiverAddress() + { + return $this->receiverAddress; + } + + public function setReceiverCity($receiverCity) + { + $this->receiverCity = $receiverCity; + $this->apiParas["receiver_city"] = $receiverCity; + } + + public function getReceiverCity() + { + return $this->receiverCity; + } + + public function setReceiverDistrict($receiverDistrict) + { + $this->receiverDistrict = $receiverDistrict; + $this->apiParas["receiver_district"] = $receiverDistrict; + } + + public function getReceiverDistrict() + { + return $this->receiverDistrict; + } + + public function setReceiverEmail($receiverEmail) + { + $this->receiverEmail = $receiverEmail; + $this->apiParas["receiver_email"] = $receiverEmail; + } + + public function getReceiverEmail() + { + return $this->receiverEmail; + } + + public function setReceiverMobile($receiverMobile) + { + $this->receiverMobile = $receiverMobile; + $this->apiParas["receiver_mobile"] = $receiverMobile; + } + + public function getReceiverMobile() + { + return $this->receiverMobile; + } + + public function setReceiverName($receiverName) + { + $this->receiverName = $receiverName; + $this->apiParas["receiver_name"] = $receiverName; + } + + public function getReceiverName() + { + return $this->receiverName; + } + + public function setReceiverState($receiverState) + { + $this->receiverState = $receiverState; + $this->apiParas["receiver_state"] = $receiverState; + } + + public function getReceiverState() + { + return $this->receiverState; + } + + public function setReceiverZip($receiverZip) + { + $this->receiverZip = $receiverZip; + $this->apiParas["receiver_zip"] = $receiverZip; + } + + public function getReceiverZip() + { + return $this->receiverZip; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function setSellerAccountNo($sellerAccountNo) + { + $this->sellerAccountNo = $sellerAccountNo; + $this->apiParas["seller_account_no"] = $sellerAccountNo; + } + + public function getSellerAccountNo() + { + return $this->sellerAccountNo; + } + + public function setSellerBindBankcard($sellerBindBankcard) + { + $this->sellerBindBankcard = $sellerBindBankcard; + $this->apiParas["seller_bind_bankcard"] = $sellerBindBankcard; + } + + public function getSellerBindBankcard() + { + return $this->sellerBindBankcard; + } + + public function setSellerBindBankcardType($sellerBindBankcardType) + { + $this->sellerBindBankcardType = $sellerBindBankcardType; + $this->apiParas["seller_bind_bankcard_type"] = $sellerBindBankcardType; + } + + public function getSellerBindBankcardType() + { + return $this->sellerBindBankcardType; + } + + public function setSellerBindMobile($sellerBindMobile) + { + $this->sellerBindMobile = $sellerBindMobile; + $this->apiParas["seller_bind_mobile"] = $sellerBindMobile; + } + + public function getSellerBindMobile() + { + return $this->sellerBindMobile; + } + + public function setSellerIdentityNo($sellerIdentityNo) + { + $this->sellerIdentityNo = $sellerIdentityNo; + $this->apiParas["seller_identity_no"] = $sellerIdentityNo; + } + + public function getSellerIdentityNo() + { + return $this->sellerIdentityNo; + } + + public function setSellerIdentityType($sellerIdentityType) + { + $this->sellerIdentityType = $sellerIdentityType; + $this->apiParas["seller_identity_type"] = $sellerIdentityType; + } + + public function getSellerIdentityType() + { + return $this->sellerIdentityType; + } + + public function setSellerRealName($sellerRealName) + { + $this->sellerRealName = $sellerRealName; + $this->apiParas["seller_real_name"] = $sellerRealName; + } + + public function getSellerRealName() + { + return $this->sellerRealName; + } + + public function setSellerRegDate($sellerRegDate) + { + $this->sellerRegDate = $sellerRegDate; + $this->apiParas["seller_reg_date"] = $sellerRegDate; + } + + public function getSellerRegDate() + { + return $this->sellerRegDate; + } + + public function setSellerRegEmail($sellerRegEmail) + { + $this->sellerRegEmail = $sellerRegEmail; + $this->apiParas["seller_reg_email"] = $sellerRegEmail; + } + + public function getSellerRegEmail() + { + return $this->sellerRegEmail; + } + + public function setSellerRegMoile($sellerRegMoile) + { + $this->sellerRegMoile = $sellerRegMoile; + $this->apiParas["seller_reg_moile"] = $sellerRegMoile; + } + + public function getSellerRegMoile() + { + return $this->sellerRegMoile; + } + + public function setTransportType($transportType) + { + $this->transportType = $transportType; + $this->apiParas["transport_type"] = $transportType; + } + + public function getTransportType() + { + return $this->transportType; + } + + public function getApiMethodName() + { + return "alipay.security.risk.detect"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php new file mode 100755 index 0000000..9248c2e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityRiskHideDeviceidQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.risk.hide.deviceid.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php b/extend/app_alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php new file mode 100755 index 0000000..6ee8950 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySecurityRiskRainscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.security.risk.rainscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipaySystemOauthTokenRequest.php b/extend/app_alipay/aop/request/AlipaySystemOauthTokenRequest.php new file mode 100755 index 0000000..a986f00 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipaySystemOauthTokenRequest.php @@ -0,0 +1,150 @@ +code = $code; + $this->apiParas["code"] = $code; + } + + public function getCode() + { + return $this->code; + } + + public function setGrantType($grantType) + { + $this->grantType = $grantType; + $this->apiParas["grant_type"] = $grantType; + } + + public function getGrantType() + { + return $this->grantType; + } + + public function setRefreshToken($refreshToken) + { + $this->refreshToken = $refreshToken; + $this->apiParas["refresh_token"] = $refreshToken; + } + + public function getRefreshToken() + { + return $this->refreshToken; + } + + public function getApiMethodName() + { + return "alipay.system.oauth.token"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeAppPayRequest.php b/extend/app_alipay/aop/request/AlipayTradeAppPayRequest.php new file mode 100755 index 0000000..dab6d27 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeAppPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.app.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeCancelRequest.php b/extend/app_alipay/aop/request/AlipayTradeCancelRequest.php new file mode 100755 index 0000000..4336747 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeCloseRequest.php b/extend/app_alipay/aop/request/AlipayTradeCloseRequest.php new file mode 100755 index 0000000..dee312e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeCloseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.close"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeCreateRequest.php b/extend/app_alipay/aop/request/AlipayTradeCreateRequest.php new file mode 100755 index 0000000..43d4079 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeCustomsDeclareRequest.php b/extend/app_alipay/aop/request/AlipayTradeCustomsDeclareRequest.php new file mode 100755 index 0000000..8544ba8 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeCustomsDeclareRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.customs.declare"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeCustomsQueryRequest.php b/extend/app_alipay/aop/request/AlipayTradeCustomsQueryRequest.php new file mode 100755 index 0000000..0a02356 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeCustomsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.customs.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php b/extend/app_alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php new file mode 100755 index 0000000..3134623 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeFastpayRefundQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.fastpay.refund.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeOrderSettleRequest.php b/extend/app_alipay/aop/request/AlipayTradeOrderSettleRequest.php new file mode 100755 index 0000000..9f219ff --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeOrderSettleRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.order.settle"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradePagePayRequest.php b/extend/app_alipay/aop/request/AlipayTradePagePayRequest.php new file mode 100755 index 0000000..e58e872 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradePagePayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.page.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradePayRequest.php b/extend/app_alipay/aop/request/AlipayTradePayRequest.php new file mode 100755 index 0000000..b1d4705 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradePayRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradePrecreateRequest.php b/extend/app_alipay/aop/request/AlipayTradePrecreateRequest.php new file mode 100755 index 0000000..d7bcb1e --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradePrecreateRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.precreate"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeQueryRequest.php b/extend/app_alipay/aop/request/AlipayTradeQueryRequest.php new file mode 100755 index 0000000..a17e6ed --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeQueryRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeRefundRequest.php b/extend/app_alipay/aop/request/AlipayTradeRefundRequest.php new file mode 100755 index 0000000..cfd83e2 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeRefundRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.refund"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php b/extend/app_alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php new file mode 100755 index 0000000..77e3fa1 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.vendorpay.devicedata.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTradeWapPayRequest.php b/extend/app_alipay/aop/request/AlipayTradeWapPayRequest.php new file mode 100755 index 0000000..7ef36bd --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTradeWapPayRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.trade.wap.pay"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php b/extend/app_alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php new file mode 100755 index 0000000..2c014d0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTransferThirdpartyBillCreateRequest.php @@ -0,0 +1,301 @@ +amount = $amount; + $this->apiParas["amount"] = $amount; + } + + public function getAmount() + { + return $this->amount; + } + + public function setCurrency($currency) + { + $this->currency = $currency; + $this->apiParas["currency"] = $currency; + } + + public function getCurrency() + { + return $this->currency; + } + + public function setExtParam($extParam) + { + $this->extParam = $extParam; + $this->apiParas["ext_param"] = $extParam; + } + + public function getExtParam() + { + return $this->extParam; + } + + public function setMemo($memo) + { + $this->memo = $memo; + $this->apiParas["memo"] = $memo; + } + + public function getMemo() + { + return $this->memo; + } + + public function setPartnerId($partnerId) + { + $this->partnerId = $partnerId; + $this->apiParas["partner_id"] = $partnerId; + } + + public function getPartnerId() + { + return $this->partnerId; + } + + public function setPayeeAccount($payeeAccount) + { + $this->payeeAccount = $payeeAccount; + $this->apiParas["payee_account"] = $payeeAccount; + } + + public function getPayeeAccount() + { + return $this->payeeAccount; + } + + public function setPayeeType($payeeType) + { + $this->payeeType = $payeeType; + $this->apiParas["payee_type"] = $payeeType; + } + + public function getPayeeType() + { + return $this->payeeType; + } + + public function setPayerAccount($payerAccount) + { + $this->payerAccount = $payerAccount; + $this->apiParas["payer_account"] = $payerAccount; + } + + public function getPayerAccount() + { + return $this->payerAccount; + } + + public function setPayerType($payerType) + { + $this->payerType = $payerType; + $this->apiParas["payer_type"] = $payerType; + } + + public function getPayerType() + { + return $this->payerType; + } + + public function setPaymentId($paymentId) + { + $this->paymentId = $paymentId; + $this->apiParas["payment_id"] = $paymentId; + } + + public function getPaymentId() + { + return $this->paymentId; + } + + public function setPaymentSource($paymentSource) + { + $this->paymentSource = $paymentSource; + $this->apiParas["payment_source"] = $paymentSource; + } + + public function getPaymentSource() + { + return $this->paymentSource; + } + + public function setTitle($title) + { + $this->title = $title; + $this->apiParas["title"] = $title; + } + + public function getTitle() + { + return $this->title; + } + + public function getApiMethodName() + { + return "alipay.transfer.thirdparty.bill.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTrustUserAuthSendRequest.php b/extend/app_alipay/aop/request/AlipayTrustUserAuthSendRequest.php new file mode 100755 index 0000000..00a7e85 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTrustUserAuthSendRequest.php @@ -0,0 +1,118 @@ +aliTrustUserInfo = $aliTrustUserInfo; + $this->apiParas["ali_trust_user_info"] = $aliTrustUserInfo; + } + + public function getAliTrustUserInfo() + { + return $this->aliTrustUserInfo; + } + + public function getApiMethodName() + { + return "alipay.trust.user.auth.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTrustUserReportGetRequest.php b/extend/app_alipay/aop/request/AlipayTrustUserReportGetRequest.php new file mode 100755 index 0000000..7d75c15 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTrustUserReportGetRequest.php @@ -0,0 +1,134 @@ +scene = $scene; + $this->apiParas["scene"] = $scene; + } + + public function getScene() + { + return $this->scene; + } + + public function setType($type) + { + $this->type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.trust.user.report.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php b/extend/app_alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php new file mode 100755 index 0000000..ed475f0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTrustUserRiskidentifyGetRequest.php @@ -0,0 +1,118 @@ +type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.trust.user.riskidentify.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTrustUserScoreGetRequest.php b/extend/app_alipay/aop/request/AlipayTrustUserScoreGetRequest.php new file mode 100755 index 0000000..081fd81 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTrustUserScoreGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayTrustUserTokenGetRequest.php b/extend/app_alipay/aop/request/AlipayTrustUserTokenGetRequest.php new file mode 100755 index 0000000..be8b71c --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayTrustUserTokenGetRequest.php @@ -0,0 +1,118 @@ +aliTrustUserInfo = $aliTrustUserInfo; + $this->apiParas["ali_trust_user_info"] = $aliTrustUserInfo; + } + + public function getAliTrustUserInfo() + { + return $this->aliTrustUserInfo; + } + + public function getApiMethodName() + { + return "alipay.trust.user.token.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserAccountFreezeGetRequest.php b/extend/app_alipay/aop/request/AlipayUserAccountFreezeGetRequest.php new file mode 100755 index 0000000..1f9fdca --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserAccountFreezeGetRequest.php @@ -0,0 +1,118 @@ +freezeType = $freezeType; + $this->apiParas["freeze_type"] = $freezeType; + } + + public function getFreezeType() + { + return $this->freezeType; + } + + public function getApiMethodName() + { + return "alipay.user.account.freeze.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserAccountGetRequest.php b/extend/app_alipay/aop/request/AlipayUserAccountGetRequest.php new file mode 100755 index 0000000..c94a841 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserAccountGetRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserAccountSearchRequest.php b/extend/app_alipay/aop/request/AlipayUserAccountSearchRequest.php new file mode 100755 index 0000000..ad17ba4 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserAccountSearchRequest.php @@ -0,0 +1,198 @@ +endTime = $endTime; + $this->apiParas["end_time"] = $endTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function setFields($fields) + { + $this->fields = $fields; + $this->apiParas["fields"] = $fields; + } + + public function getFields() + { + return $this->fields; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStartTime($startTime) + { + $this->startTime = $startTime; + $this->apiParas["start_time"] = $startTime; + } + + public function getStartTime() + { + return $this->startTime; + } + + public function setType($type) + { + $this->type = $type; + $this->apiParas["type"] = $type; + } + + public function getType() + { + return $this->type; + } + + public function getApiMethodName() + { + return "alipay.user.account.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php b/extend/app_alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php new file mode 100755 index 0000000..a62e62f --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserAccountUseridBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.account.userid.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserAuthZhimaorgIdentityApplyRequest.php b/extend/app_alipay/aop/request/AlipayUserAuthZhimaorgIdentityApplyRequest.php new file mode 100755 index 0000000..23d9243 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserAuthZhimaorgIdentityApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.auth.zhimaorg.identity.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserContractGetRequest.php b/extend/app_alipay/aop/request/AlipayUserContractGetRequest.php new file mode 100755 index 0000000..9e2d971 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserContractGetRequest.php @@ -0,0 +1,118 @@ +subscriberUserId = $subscriberUserId; + $this->apiParas["subscriber_user_id"] = $subscriberUserId; + } + + public function getSubscriberUserId() + { + return $this->subscriberUserId; + } + + public function getApiMethodName() + { + return "alipay.user.contract.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserFinanceinfoShareRequest.php b/extend/app_alipay/aop/request/AlipayUserFinanceinfoShareRequest.php new file mode 100755 index 0000000..fc01d82 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserFinanceinfoShareRequest.php @@ -0,0 +1,119 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.financeinfo.share"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserGetRequest.php b/extend/app_alipay/aop/request/AlipayUserGetRequest.php new file mode 100755 index 0000000..f75fb66 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserGetRequest.php @@ -0,0 +1,118 @@ +fields = $fields; + $this->apiParas["fields"] = $fields; + } + + public function getFields() + { + return $this->fields; + } + + public function getApiMethodName() + { + return "alipay.user.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserInfoAuthRequest.php b/extend/app_alipay/aop/request/AlipayUserInfoAuthRequest.php new file mode 100755 index 0000000..eedb338 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserInfoAuthRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.user.info.auth"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserInfoShareRequest.php b/extend/app_alipay/aop/request/AlipayUserInfoShareRequest.php new file mode 100755 index 0000000..58c7d7b --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserInfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserTestRequest.php b/extend/app_alipay/aop/request/AlipayUserTestRequest.php new file mode 100755 index 0000000..92a8edb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserTestRequest.php @@ -0,0 +1,118 @@ +userinfo = $userinfo; + $this->apiParas["userinfo"] = $userinfo; + } + + public function getUserinfo() + { + return $this->userinfo; + } + + public function getApiMethodName() + { + return "alipay.user.test"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserTradeSearchRequest.php b/extend/app_alipay/aop/request/AlipayUserTradeSearchRequest.php new file mode 100755 index 0000000..d1dbd61 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserTradeSearchRequest.php @@ -0,0 +1,246 @@ +alipayOrderNo = $alipayOrderNo; + $this->apiParas["alipay_order_no"] = $alipayOrderNo; + } + + public function getAlipayOrderNo() + { + return $this->alipayOrderNo; + } + + public function setEndTime($endTime) + { + $this->endTime = $endTime; + $this->apiParas["end_time"] = $endTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function setMerchantOrderNo($merchantOrderNo) + { + $this->merchantOrderNo = $merchantOrderNo; + $this->apiParas["merchant_order_no"] = $merchantOrderNo; + } + + public function getMerchantOrderNo() + { + return $this->merchantOrderNo; + } + + public function setOrderFrom($orderFrom) + { + $this->orderFrom = $orderFrom; + $this->apiParas["order_from"] = $orderFrom; + } + + public function getOrderFrom() + { + return $this->orderFrom; + } + + public function setOrderStatus($orderStatus) + { + $this->orderStatus = $orderStatus; + $this->apiParas["order_status"] = $orderStatus; + } + + public function getOrderStatus() + { + return $this->orderStatus; + } + + public function setOrderType($orderType) + { + $this->orderType = $orderType; + $this->apiParas["order_type"] = $orderType; + } + + public function getOrderType() + { + return $this->orderType; + } + + public function setPageNo($pageNo) + { + $this->pageNo = $pageNo; + $this->apiParas["page_no"] = $pageNo; + } + + public function getPageNo() + { + return $this->pageNo; + } + + public function setPageSize($pageSize) + { + $this->pageSize = $pageSize; + $this->apiParas["page_size"] = $pageSize; + } + + public function getPageSize() + { + return $this->pageSize; + } + + public function setStartTime($startTime) + { + $this->startTime = $startTime; + $this->apiParas["start_time"] = $startTime; + } + + public function getStartTime() + { + return $this->startTime; + } + + public function getApiMethodName() + { + return "alipay.user.trade.search"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayUserUserinfoShareRequest.php b/extend/app_alipay/aop/request/AlipayUserUserinfoShareRequest.php new file mode 100755 index 0000000..01c6ecb --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayUserUserinfoShareRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php b/extend/app_alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php new file mode 100755 index 0000000..4cddde9 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdataassetsEasyserviceRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.easyservice"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php b/extend/app_alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php new file mode 100755 index 0000000..5822eb3 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdataassetsFcdatalabZdatamergetaskRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.fcdatalab.zdatamergetask"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdataassetsMetadataRequest.php b/extend/app_alipay/aop/request/AlipayZdataassetsMetadataRequest.php new file mode 100755 index 0000000..ce293d0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdataassetsMetadataRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "alipay.zdataassets.metadata"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php b/extend/app_alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php new file mode 100755 index 0000000..ff33066 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdatafrontCommonQueryRequest.php @@ -0,0 +1,200 @@ +0,就先判断cache中的数据是否过期,如果没有过期就返回cache中的数据,如果过期再从外部获取数据并刷新cache,然后返回数据。 +单位:秒 + **/ + private $cacheInterval; + + /** + * 通用查询的入参 + **/ + private $queryConditions; + + /** + * 服务名称请与相关开发负责人联系 + **/ + private $serviceName; + + /** + * 访问该服务的业务 + **/ + private $visitBiz; + + /** + * 访问该服务的业务线 + **/ + private $visitBizLine; + + /** + * 访问该服务的部门名称 + **/ + private $visitDomain; + + private $apiParas = array(); + private $terminalType; + private $terminalInfo; + private $prodCode; + private $apiVersion="1.0"; + private $notifyUrl; + private $returnUrl; + private $needEncrypt=false; + + + public function setCacheInterval($cacheInterval) + { + $this->cacheInterval = $cacheInterval; + $this->apiParas["cache_interval"] = $cacheInterval; + } + + public function getCacheInterval() + { + return $this->cacheInterval; + } + + public function setQueryConditions($queryConditions) + { + $this->queryConditions = $queryConditions; + $this->apiParas["query_conditions"] = $queryConditions; + } + + public function getQueryConditions() + { + return $this->queryConditions; + } + + public function setServiceName($serviceName) + { + $this->serviceName = $serviceName; + $this->apiParas["service_name"] = $serviceName; + } + + public function getServiceName() + { + return $this->serviceName; + } + + public function setVisitBiz($visitBiz) + { + $this->visitBiz = $visitBiz; + $this->apiParas["visit_biz"] = $visitBiz; + } + + public function getVisitBiz() + { + return $this->visitBiz; + } + + public function setVisitBizLine($visitBizLine) + { + $this->visitBizLine = $visitBizLine; + $this->apiParas["visit_biz_line"] = $visitBizLine; + } + + public function getVisitBizLine() + { + return $this->visitBizLine; + } + + public function setVisitDomain($visitDomain) + { + $this->visitDomain = $visitDomain; + $this->apiParas["visit_domain"] = $visitDomain; + } + + public function getVisitDomain() + { + return $this->visitDomain; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.common.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php b/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php new file mode 100755 index 0000000..91d7ebe --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedFileuploadRequest.php @@ -0,0 +1,230 @@ +columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileDescription($fileDescription) + { + $this->fileDescription = $fileDescription; + $this->apiParas["file_description"] = $fileDescription; + } + + public function getFileDescription() + { + return $this->fileDescription; + } + + public function setFileDigest($fileDigest) + { + $this->fileDigest = $fileDigest; + $this->apiParas["file_digest"] = $fileDigest; + } + + public function getFileDigest() + { + return $this->fileDigest; + } + + public function setFileType($fileType) + { + $this->fileType = $fileType; + $this->apiParas["file_type"] = $fileType; + } + + public function getFileType() + { + return $this->fileType; + } + + public function setPrimaryKey($primaryKey) + { + $this->primaryKey = $primaryKey; + $this->apiParas["primary_key"] = $primaryKey; + } + + public function getPrimaryKey() + { + return $this->primaryKey; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function setTypeId($typeId) + { + $this->typeId = $typeId; + $this->apiParas["type_id"] = $typeId; + } + + public function getTypeId() + { + return $this->typeId; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.datatransfered.fileupload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php b/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php new file mode 100755 index 0000000..a756df0 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdatafrontDatatransferedSendRequest.php @@ -0,0 +1,150 @@ +data = $data; + $this->apiParas["data"] = $data; + } + + public function getData() + { + return $this->data; + } + + public function setIdentity($identity) + { + $this->identity = $identity; + $this->apiParas["identity"] = $identity; + } + + public function getIdentity() + { + return $this->identity; + } + + public function setTypeId($typeId) + { + $this->typeId = $typeId; + $this->apiParas["type_id"] = $typeId; + } + + public function getTypeId() + { + return $this->typeId; + } + + public function getApiMethodName() + { + return "alipay.zdatafront.datatransfered.send"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php b/extend/app_alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php new file mode 100755 index 0000000..c838624 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZdataserviceUnidataQueryRequest.php @@ -0,0 +1,134 @@ +queryCondition = $queryCondition; + $this->apiParas["query_condition"] = $queryCondition; + } + + public function getQueryCondition() + { + return $this->queryCondition; + } + + public function setUniqKey($uniqKey) + { + $this->uniqKey = $uniqKey; + $this->apiParas["uniq_key"] = $uniqKey; + } + + public function getUniqKey() + { + return $this->uniqKey; + } + + public function getApiMethodName() + { + return "alipay.zdataservice.unidata.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AlipayZmscoreZrankGetRequest.php b/extend/app_alipay/aop/request/AlipayZmscoreZrankGetRequest.php new file mode 100755 index 0000000..ad3a201 --- /dev/null +++ b/extend/app_alipay/aop/request/AlipayZmscoreZrankGetRequest.php @@ -0,0 +1,118 @@ +userId = $userId; + $this->apiParas["user_id"] = $userId; + } + + public function getUserId() + { + return $this->userId; + } + + public function getApiMethodName() + { + return "alipay.zmscore.zrank.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php new file mode 100755 index 0000000..b4f6bd8 --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.contract.facetoface.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php new file mode 100755 index 0000000..034b5a6 --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandContractFacetofaceSignRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.contract.facetoface.sign"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php new file mode 100755 index 0000000..d1ef57f --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandEnterpriseApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.enterprise.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandImageUploadRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandImageUploadRequest.php new file mode 100755 index 0000000..6208575 --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandImageUploadRequest.php @@ -0,0 +1,134 @@ +imageContent = $imageContent; + $this->apiParas["image_content"] = $imageContent; + } + + public function getImageContent() + { + return $this->imageContent; + } + + public function setImageType($imageType) + { + $this->imageType = $imageType; + $this->apiParas["image_type"] = $imageType; + } + + public function getImageType() + { + return $this->imageType; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.image.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php new file mode 100755 index 0000000..2152810 --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandMapplyorderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.mapplyorder.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php new file mode 100755 index 0000000..792402d --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandMerchantStorelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.merchant.storelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php b/extend/app_alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php new file mode 100755 index 0000000..a3b0874 --- /dev/null +++ b/extend/app_alipay/aop/request/AntMerchantExpandPersonalApplyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ant.merchant.expand.personal.apply"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php b/extend/app_alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php new file mode 100755 index 0000000..bafd86a --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCateringTablecodeQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.catering.tablecode.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCateringTablelistQueryRequest.php b/extend/app_alipay/aop/request/KoubeiCateringTablelistQueryRequest.php new file mode 100755 index 0000000..859cf1c --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCateringTablelistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.catering.tablelist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php new file mode 100755 index 0000000..2901de9 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php new file mode 100755 index 0000000..ef62576 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php new file mode 100755 index 0000000..96605cf --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataProviderModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.provider.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php new file mode 100755 index 0000000..ce61c80 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php new file mode 100755 index 0000000..5f7f37f --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php new file mode 100755 index 0000000..7f272df --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php new file mode 100755 index 0000000..0db03a4 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiCraftsmanDataWorkModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.craftsman.data.work.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemBatchqueryRequest.php new file mode 100755 index 0000000..3e72571 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php new file mode 100755 index 0000000..768c845 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemCategoryChildrenBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.category.children.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemCreateRequest.php b/extend/app_alipay/aop/request/KoubeiItemCreateRequest.php new file mode 100755 index 0000000..891722b --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php new file mode 100755 index 0000000..0917000 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php new file mode 100755 index 0000000..c531917 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemBrandQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php new file mode 100755 index 0000000..e486ed2 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemCategoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.category.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemCreateRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemCreateRequest.php new file mode 100755 index 0000000..f3ebc4d --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php new file mode 100755 index 0000000..e26acb0 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemExistedQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.existed.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemQueryRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemQueryRequest.php new file mode 100755 index 0000000..0457a4f --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemExtitemUpdateRequest.php b/extend/app_alipay/aop/request/KoubeiItemExtitemUpdateRequest.php new file mode 100755 index 0000000..d6eeed7 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemExtitemUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.extitem.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemModifyRequest.php b/extend/app_alipay/aop/request/KoubeiItemModifyRequest.php new file mode 100755 index 0000000..066ef64 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiItemStateRequest.php b/extend/app_alipay/aop/request/KoubeiItemStateRequest.php new file mode 100755 index 0000000..326cfc8 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiItemStateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.item.state"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php new file mode 100755 index 0000000..2b73b34 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php new file mode 100755 index 0000000..b680c4a --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php new file mode 100755 index 0000000..0ad276e --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php new file mode 100755 index 0000000..13132ed --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityOfflineRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.offline"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php new file mode 100755 index 0000000..1f6c6c5 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php new file mode 100755 index 0000000..7aba2b7 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignAssetDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.asset.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php new file mode 100755 index 0000000..83606d5 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php new file mode 100755 index 0000000..8cf1ef2 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCountRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.count"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php new file mode 100755 index 0000000..deb22a3 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php new file mode 100755 index 0000000..eb6a587 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php new file mode 100755 index 0000000..840f9bc --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php new file mode 100755 index 0000000..e97cc13 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignCrowdModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.crowd.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php new file mode 100755 index 0000000..967e258 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignDetailInfoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.detail.info.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoBatchqueryRequest.php new file mode 100755 index 0000000..84a2ca5 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoConsultRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoConsultRequest.php new file mode 100755 index 0000000..f7c7ce8 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoCreateRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoCreateRequest.php new file mode 100755 index 0000000..ef17bbe --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoDeleteRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoDeleteRequest.php new file mode 100755 index 0000000..4caa2cb --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoModifyRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoModifyRequest.php new file mode 100755 index 0000000..84c2b10 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoQueryRequest.php new file mode 100755 index 0000000..403beed --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentPromoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.promo.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentShopConsultRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentShopConsultRequest.php new file mode 100755 index 0000000..ec81451 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentShopConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.shop.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentTemplateConsultRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentTemplateConsultRequest.php new file mode 100755 index 0000000..032a85f --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignIntelligentTemplateConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.intelligent.template.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php new file mode 100755 index 0000000..67d9d75 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitApplyQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.recruit.apply.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php new file mode 100755 index 0000000..24516bd --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignRecruitShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.recruit.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php new file mode 100755 index 0000000..1bb6142 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignTagsQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php new file mode 100755 index 0000000..b1e3ee0 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingCampaignUserAssetQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.campaign.user.asset.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php new file mode 100755 index 0000000..4f31b2e --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataActivityBillDownloadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.activity.bill.download"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php new file mode 100755 index 0000000..3fdb44d --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataActivityReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.activity.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php new file mode 100755 index 0000000..5b413fb --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.alisis.report.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php new file mode 100755 index 0000000..90312f3 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataAlisisReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.alisis.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php new file mode 100755 index 0000000..2b91d4a --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMemberprofileQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.memberprofile.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php new file mode 100755 index 0000000..48a55d4 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyddsreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.myddsreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php new file mode 100755 index 0000000..52dead5 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataBizadviserMyreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.bizadviser.myreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php new file mode 100755 index 0000000..307a418 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php new file mode 100755 index 0000000..30e5c4c --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDeleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.delete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php new file mode 100755 index 0000000..5a5cc6b --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php new file mode 100755 index 0000000..d40e3af --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php new file mode 100755 index 0000000..1393573 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataCustomreportSaveRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.customreport.save"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php new file mode 100755 index 0000000..7980a9a --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnoseBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.dishdiagnose.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php new file mode 100755 index 0000000..6f4e2ec --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataDishdiagnosetypeBatchqueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php new file mode 100755 index 0000000..b95cbc1 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataEnterpriseStaffinfoUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.enterprise.staffinfo.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php new file mode 100755 index 0000000..81da6d8 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataIndicatorQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.indicator.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentEffectQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentEffectQueryRequest.php new file mode 100755 index 0000000..07266af --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentEffectQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.intelligent.effect.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentIndicatorQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentIndicatorQueryRequest.php new file mode 100755 index 0000000..2054dd3 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataIntelligentIndicatorQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.intelligent.indicator.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php new file mode 100755 index 0000000..93a3ccd --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataIsvShopQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.isv.shop.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php new file mode 100755 index 0000000..7d36af6 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataMemberReportQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.member.report.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php new file mode 100755 index 0000000..a5cfe3f --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataMessageDeliverRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.message.deliver"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php new file mode 100755 index 0000000..cb2a7b2 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataRetailDmQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.retail.dm.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php new file mode 100755 index 0000000..9347897 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityConfigRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.smartactivity.config"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php new file mode 100755 index 0000000..46886e5 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartactivityForecastRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.smartactivity.forecast"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php new file mode 100755 index 0000000..dc1756e --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataSmartmanagementDiagnoseRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php new file mode 100755 index 0000000..8887c00 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingDataTradeHabbitQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.data.trade.habbit.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php new file mode 100755 index 0000000..6cd6917 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingToolIsvMerchantQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.isv.merchant.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php new file mode 100755 index 0000000..9bdbe7e --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingToolPointsQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.points.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php new file mode 100755 index 0000000..9919124 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingToolPointsUpdateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.points.update"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php b/extend/app_alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php new file mode 100755 index 0000000..76c644d --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMarketingToolPrizesendAuthRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.marketing.tool.prizesend.auth"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php new file mode 100755 index 0000000..7dc9629 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMemberBrandownerNameQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php new file mode 100755 index 0000000..1fced22 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMemberDataOauthQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.member.data.oauth.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiMemberRetailerQueryRequest.php b/extend/app_alipay/aop/request/KoubeiMemberRetailerQueryRequest.php new file mode 100755 index 0000000..cafb49c --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiMemberRetailerQueryRequest.php @@ -0,0 +1,103 @@ +notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php new file mode 100755 index 0000000..f875fab --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptActivityQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.activity.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php new file mode 100755 index 0000000..3890a4f --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptBatchQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.batch.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php new file mode 100755 index 0000000..3d955b8 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptCheckresultSubmitRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.checkresult.submit"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php new file mode 100755 index 0000000..fb1e6a7 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiQualityTestCloudacptItemQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.quality.test.cloudacpt.item.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php b/extend/app_alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php new file mode 100755 index 0000000..d246c49 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiRetailShopitemBatchqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.batchquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiRetailShopitemModifyRequest.php b/extend/app_alipay/aop/request/KoubeiRetailShopitemModifyRequest.php new file mode 100755 index 0000000..9bce978 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiRetailShopitemModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiRetailShopitemUploadRequest.php b/extend/app_alipay/aop/request/KoubeiRetailShopitemUploadRequest.php new file mode 100755 index 0000000..a6f3cc7 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiRetailShopitemUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.retail.shopitem.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiTradeItemBuyRequest.php b/extend/app_alipay/aop/request/KoubeiTradeItemBuyRequest.php new file mode 100755 index 0000000..82e7416 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiTradeItemBuyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.item.buy"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiTradeOrderConsultRequest.php b/extend/app_alipay/aop/request/KoubeiTradeOrderConsultRequest.php new file mode 100755 index 0000000..c99397b --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiTradeOrderConsultRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.order.consult"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiTradeOrderQueryRequest.php b/extend/app_alipay/aop/request/KoubeiTradeOrderQueryRequest.php new file mode 100755 index 0000000..bcfebf8 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiTradeOrderQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.order.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php b/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php new file mode 100755 index 0000000..71da336 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.ticket.ticketcode.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php b/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php new file mode 100755 index 0000000..f1b2795 --- /dev/null +++ b/extend/app_alipay/aop/request/KoubeiTradeTicketTicketcodeUseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "koubei.trade.ticket.ticketcode.use"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MonitorHeartbeatSynRequest.php b/extend/app_alipay/aop/request/MonitorHeartbeatSynRequest.php new file mode 100755 index 0000000..7c735e9 --- /dev/null +++ b/extend/app_alipay/aop/request/MonitorHeartbeatSynRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "monitor.heartbeat.syn"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php b/extend/app_alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php new file mode 100755 index 0000000..642510e --- /dev/null +++ b/extend/app_alipay/aop/request/MybankCreditLoanapplyDataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.credit.loanapply.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php b/extend/app_alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php new file mode 100755 index 0000000..0786b1c --- /dev/null +++ b/extend/app_alipay/aop/request/MybankFinanceYulibaoAccountQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.account.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php b/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php new file mode 100755 index 0000000..113fd84 --- /dev/null +++ b/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalPurchaseRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.capital.purchase"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php b/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php new file mode 100755 index 0000000..38a6043 --- /dev/null +++ b/extend/app_alipay/aop/request/MybankFinanceYulibaoCapitalRansomRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.capital.ransom"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php b/extend/app_alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php new file mode 100755 index 0000000..7e5c1c7 --- /dev/null +++ b/extend/app_alipay/aop/request/MybankFinanceYulibaoPriceQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.price.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php b/extend/app_alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php new file mode 100755 index 0000000..6fcdf83 --- /dev/null +++ b/extend/app_alipay/aop/request/MybankFinanceYulibaoTransHistoryQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "mybank.finance.yulibao.trans.history.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php new file mode 100755 index 0000000..e3025df --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskAlixiaohaoQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.alixiaohao.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php new file mode 100755 index 0000000..46a4246 --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraud.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php new file mode 100755 index 0000000..74830b2 --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudintegrationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudintegration.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php new file mode 100755 index 0000000..c761ff4 --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudlistQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudlist.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php new file mode 100755 index 0000000..cd1db58 --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskAntifraudscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.antifraudscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php b/extend/app_alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php new file mode 100755 index 0000000..16d9b5c --- /dev/null +++ b/extend/app_alipay/aop/request/SsdataDataserviceRiskRainscoreQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "ssdata.dataservice.risk.rainscore.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php b/extend/app_alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php new file mode 100755 index 0000000..13b64cf --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaAuthInfoAuthqueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.auth.info.authquery"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditAntifraudRiskListRequest.php b/extend/app_alipay/aop/request/ZhimaCreditAntifraudRiskListRequest.php new file mode 100755 index 0000000..d1ba9cd --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditAntifraudRiskListRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.antifraud.risk.list"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditAntifraudScoreGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditAntifraudScoreGetRequest.php new file mode 100755 index 0000000..4e6a514 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditAntifraudScoreGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.antifraud.score.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php b/extend/app_alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php new file mode 100755 index 0000000..ae0fd5a --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditAntifraudVerifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.antifraud.verify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditEpInfoGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditEpInfoGetRequest.php new file mode 100755 index 0000000..c552fd2 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditEpInfoGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.ep.info.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitDetailGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitDetailGetRequest.php new file mode 100755 index 0000000..cc0bb61 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitDetailGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.ep.lawsuit.detail.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitRecordGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitRecordGetRequest.php new file mode 100755 index 0000000..b03aaae --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditEpLawsuitRecordGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.ep.lawsuit.record.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditEpScoreGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditEpScoreGetRequest.php new file mode 100755 index 0000000..b257ec9 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditEpScoreGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.ep.score.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitDetailQueryRequest.php b/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitDetailQueryRequest.php new file mode 100755 index 0000000..a56b027 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitDetailQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.pe.lawsuit.detail.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitRecordGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitRecordGetRequest.php new file mode 100755 index 0000000..6e806a4 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditPeLawsuitRecordGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.pe.lawsuit.record.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php new file mode 100755 index 0000000..b59c537 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditScoreBriefGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.score.brief.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditScoreGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditScoreGetRequest.php new file mode 100755 index 0000000..659e5df --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditScoreGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.score.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php new file mode 100755 index 0000000..e90be79 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditWatchlistBriefGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.watchlist.brief.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php b/extend/app_alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php new file mode 100755 index 0000000..be647ef --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCreditWatchlistiiGetRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.credit.watchlistii.get"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php new file mode 100755 index 0000000..0a2fbd1 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerCertificationCertifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.certify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php new file mode 100755 index 0000000..7f7dd2d --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerCertificationInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerCertificationMaterialCertifyRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerCertificationMaterialCertifyRequest.php new file mode 100755 index 0000000..09c2e3d --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerCertificationMaterialCertifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.material.certify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php new file mode 100755 index 0000000..d3f8079 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerCertificationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.certification.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerContractInitializeRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerContractInitializeRequest.php new file mode 100755 index 0000000..d43cd13 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerContractInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.contract.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationCertifyRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationCertifyRequest.php new file mode 100755 index 0000000..ba4db84 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationCertifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.ep.certification.certify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationInitializeRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationInitializeRequest.php new file mode 100755 index 0000000..ad4ff14 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.ep.certification.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationQueryRequest.php b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationQueryRequest.php new file mode 100755 index 0000000..ceb9ba1 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaCustomerEpCertificationQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.customer.ep.certification.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaDataBatchFeedbackRequest.php b/extend/app_alipay/aop/request/ZhimaDataBatchFeedbackRequest.php new file mode 100755 index 0000000..46b9e01 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaDataBatchFeedbackRequest.php @@ -0,0 +1,230 @@ +bizExtParams = $bizExtParams; + $this->apiParas["biz_ext_params"] = $bizExtParams; + } + + public function getBizExtParams() + { + return $this->bizExtParams; + } + + public function setColumns($columns) + { + $this->columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setFileDescription($fileDescription) + { + $this->fileDescription = $fileDescription; + $this->apiParas["file_description"] = $fileDescription; + } + + public function getFileDescription() + { + return $this->fileDescription; + } + + public function setFileType($fileType) + { + $this->fileType = $fileType; + $this->apiParas["file_type"] = $fileType; + } + + public function getFileType() + { + return $this->fileType; + } + + public function setPrimaryKeyColumns($primaryKeyColumns) + { + $this->primaryKeyColumns = $primaryKeyColumns; + $this->apiParas["primary_key_columns"] = $primaryKeyColumns; + } + + public function getPrimaryKeyColumns() + { + return $this->primaryKeyColumns; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function getApiMethodName() + { + return "zhima.data.batch.feedback"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php b/extend/app_alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php new file mode 100755 index 0000000..293416c --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaDataFeedbackurlQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.data.feedbackurl.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php new file mode 100755 index 0000000..aa83d83 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantBorrowEntityUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.borrow.entity.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php new file mode 100755 index 0000000..b0e6ede --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantCloseloopDataUploadRequest.php @@ -0,0 +1,224 @@ +bizExtParams = $bizExtParams; + $this->apiParas["biz_ext_params"] = $bizExtParams; + } + + public function getBizExtParams() + { + return $this->bizExtParams; + } + + public function setColumns($columns) + { + $this->columns = $columns; + $this->apiParas["columns"] = $columns; + } + + public function getColumns() + { + return $this->columns; + } + + public function setFile($file) + { + $this->file = $file; + $this->apiParas["file"] = $file; + } + + public function getFile() + { + return $this->file; + } + + public function setFileCharset($fileCharset) + { + $this->fileCharset = $fileCharset; + $this->apiParas["file_charset"] = $fileCharset; + } + + public function getFileCharset() + { + return $this->fileCharset; + } + + public function setPrimaryKeyColumns($primaryKeyColumns) + { + $this->primaryKeyColumns = $primaryKeyColumns; + $this->apiParas["primary_key_columns"] = $primaryKeyColumns; + } + + public function getPrimaryKeyColumns() + { + return $this->primaryKeyColumns; + } + + public function setRecords($records) + { + $this->records = $records; + $this->apiParas["records"] = $records; + } + + public function getRecords() + { + return $this->records; + } + + public function setSceneCode($sceneCode) + { + $this->sceneCode = $sceneCode; + $this->apiParas["scene_code"] = $sceneCode; + } + + public function getSceneCode() + { + return $this->sceneCode; + } + + public function getApiMethodName() + { + return "zhima.merchant.closeloop.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php new file mode 100755 index 0000000..1cbec97 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantDataUploadInitializeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.data.upload.initialize"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php new file mode 100755 index 0000000..e28835e --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCancelRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.cancel"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php new file mode 100755 index 0000000..0fef438 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCompleteRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.complete"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php new file mode 100755 index 0000000..a64c84e --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php new file mode 100755 index 0000000..1256f89 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentModifyRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.modify"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php new file mode 100755 index 0000000..8e4f74b --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantOrderRentQueryRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.order.rent.query"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php new file mode 100755 index 0000000..14605a3 --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantSingleDataUploadRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.single.data.upload"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaMerchantTestPracticeRequest.php b/extend/app_alipay/aop/request/ZhimaMerchantTestPracticeRequest.php new file mode 100755 index 0000000..1de743e --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaMerchantTestPracticeRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.merchant.test.practice"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php b/extend/app_alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php new file mode 100755 index 0000000..1cb3edd --- /dev/null +++ b/extend/app_alipay/aop/request/ZhimaOpenAppKeyanLqlCreateRequest.php @@ -0,0 +1,118 @@ +bizContent = $bizContent; + $this->apiParas["biz_content"] = $bizContent; + } + + public function getBizContent() + { + return $this->bizContent; + } + + public function getApiMethodName() + { + return "zhima.open.app.keyan.lql.create"; + } + + public function setNotifyUrl($notifyUrl) + { + $this->notifyUrl=$notifyUrl; + } + + public function getNotifyUrl() + { + return $this->notifyUrl; + } + + public function setReturnUrl($returnUrl) + { + $this->returnUrl=$returnUrl; + } + + public function getReturnUrl() + { + return $this->returnUrl; + } + + public function getApiParas() + { + return $this->apiParas; + } + + public function getTerminalType() + { + return $this->terminalType; + } + + public function setTerminalType($terminalType) + { + $this->terminalType = $terminalType; + } + + public function getTerminalInfo() + { + return $this->terminalInfo; + } + + public function setTerminalInfo($terminalInfo) + { + $this->terminalInfo = $terminalInfo; + } + + public function getProdCode() + { + return $this->prodCode; + } + + public function setProdCode($prodCode) + { + $this->prodCode = $prodCode; + } + + public function setApiVersion($apiVersion) + { + $this->apiVersion=$apiVersion; + } + + public function getApiVersion() + { + return $this->apiVersion; + } + + public function setNeedEncrypt($needEncrypt) + { + + $this->needEncrypt=$needEncrypt; + + } + + public function getNeedEncrypt() + { + return $this->needEncrypt; + } + +} diff --git a/extend/app_alipay/aop/test/TestImage.php b/extend/app_alipay/aop/test/TestImage.php new file mode 100755 index 0000000..6c0a0b6 --- /dev/null +++ b/extend/app_alipay/aop/test/TestImage.php @@ -0,0 +1,97 @@ + serverUrl, + $this -> appId, + $this -> partner_private_key, + $this -> format, + $this -> charset + ); + $response = null; + $outputStream = null; + $request = $alipayClient -> getContents() ; + + //200 + //echo( '状态码:'. $request -> getCode() .', '); + //echo '



'; + + $fileType = $request -> getType(); + //echo( '类型:'. $fileType .', '); + if( $fileType == 'text/plain'){ + //出错,返回 json + echo $request -> getBody(); + + }else{ + + $type = $request -> getFileSuffix( $fileType ); + + //echo $this -> getParams(); + //exit(); + + //返回 文件流 + header("Content-type: ". $fileType ); //类型 + + + header("Accept-Ranges: bytes");//告诉客户端浏览器返回的文件大小是按照字节进行计算的 + header("Accept-Length: ". $request -> getContentLength() );//文件大小 + header("Content-Length: ". $request -> getContentLength() );//文件大小 + header('Content-Disposition: attachment; filename="'. time() .'.'. $type .'"'); //文件名 + echo $request -> getBody() ; + exit ( ) ; + } + + //echo( '内容: , '. $request -> getContentLength() ); + + //echo '



'; + //echo '参数:
';
+
+		//echo ($request -> getParams());
+
+		//echo '
' ; + } +} + + + + + +// 测试 +$test1 = new TestImage(); +$test1 -> load(); diff --git a/extend/app_alipay/demo.php b/extend/app_alipay/demo.php new file mode 100755 index 0000000..a07c5d4 --- /dev/null +++ b/extend/app_alipay/demo.php @@ -0,0 +1,49 @@ +gatewayUrl = "https://openapi.alipay.com/gateway.do"; +$aop->appId = "app_id"; +$aop->rsaPrivateKey = '请填写开发者私钥去头去尾去回车,一行字符串'; +$aop->format = "json"; +$aop->charset = "UTF-8"; +$aop->signType = "RSA2"; +$aop->alipayrsaPublicKey = '请填写支付宝公钥,一行字符串'; +//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay +$request = new AlipayTradeAppPayRequest(); +// 异步通知地址 +$notify_url = urlencode('商户外网可以访问的异步地址'); +// 订单标题 +$subject = 'DCloud项目捐赠'; +// 订单详情 +$body = 'DCloud致力于打造HTML5最好的移动开发工具,包括终端的Runtime、云端的服务和IDE,同时提供各项配套的开发者服务。'; +// 订单号,示例代码使用时间值作为唯一的订单ID号 +$out_trade_no = date('YmdHis', time()); +//SDK已经封装掉了公共参数,这里只需要传入业务参数 +$bizcontent = "{\"body\":\"".$body."\"," + . "\"subject\": \"".$subject."\"," + . "\"out_trade_no\": \"".$out_trade_no."\"," + . "\"timeout_express\": \"30m\"," + . "\"total_amount\": \"".$total."\"," + . "\"product_code\":\"QUICK_MSECURITY_PAY\"" + . "}"; +$request->setNotifyUrl($notify_url); +$request->setBizContent($bizcontent); +//这里和普通的接口调用不同,使用的是sdkExecute +$response = $aop->sdkExecute($request); +// 注意:这里不需要使用htmlspecialchars进行转义,直接返回即可 +echo $response; +?> \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Autoloader/Autoloader.php b/extend/app_alipay/lotusphp_runtime/Autoloader/Autoloader.php new file mode 100755 index 0000000..a74ef3f --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Autoloader/Autoloader.php @@ -0,0 +1,306 @@ + true, + + /** + * 要扫描的文件类型 + * + * 若该属性设置为array("php","inc","php3"), + * 则扩展名为"php","inc","php3"的文件会被扫描, + * 其它扩展名的文件会被忽略 + */ + "allow_file_extension" => array("php", "inc"), + + /** + * 不扫描的目录 + * + * 若该属性设置为array(".svn", ".setting"), + * 则所有名为".setting"的目录也会被忽略 + */ + "skip_dir_names" => array(".svn"), + ); + + public $storeHandle; + public $autoloadPath; + protected $functionFileMapping; + protected $fileStore; + + public function init() + { + if (!is_object($this->storeHandle)) + { + $this->storeHandle = new LtStoreMemory; + $this->fileStore = new LtStoreFile; + $this->fileStore->prefix = 'LtAutoloader-token-cache'; + $this->fileStore->useSerialize = true; + $this->fileStore->init(); + } + // Whether scanning directory + if (0 == $this->storeHandle->get(".class_total") && 0 == $this->storeHandle->get(".function_total")) + { + $this->storeHandle->add(".class_total", 0); + $this->storeHandle->add(".function_total", 0); + $this->storeHandle->add(".functions", array(), 0); + $autoloadPath = $this->preparePath($this->autoloadPath); + foreach($autoloadPath as $key => $path) + { + if (is_file($path)) + { + $this->addFileMap($path); + unset($autoloadPath[$key]); + } + } + $this->scanDirs($autoloadPath); + unset($autoloadPath); + } + // Whether loading function files + if ($this->conf["load_function"]) + { + $this->loadFunction(); + } + spl_autoload_register(array($this, "loadClass")); + } + + public function loadFunction() + { + if ($functionFiles = $this->storeHandle->get(".functions")) + { + foreach ($functionFiles as $functionFile) + { + include($functionFile); + } + } + } + + public function loadClass($className) + { + if ($classFile = $this->storeHandle->get(strtolower($className))) + { + include($classFile); + } + } + + protected function convertPath($path) + { + $path = str_replace("\\", "/", $path); + if (!is_readable($path)) + { + trigger_error("Directory is not exists/readable: {$path}"); + return false; + } + $path = rtrim(realpath($path), '\\/'); + if ("WINNT" != PHP_OS && preg_match("/\s/i", $path)) + { + trigger_error("Directory contains space/tab/newline is not supported: {$path}"); + return false; + } + return $path; + } + + /** + * The string or an Multidimensional array into a one-dimensional array + * + * @param array $ or string $var + * @return array one-dimensional array + */ + protected function preparePath($var) + { + $ret = array(); + if (!is_array($var)) + { + $var = array($var); + } + $i = 0; + while (isset($var[$i])) + { + if (!is_array($var[$i]) && $path = $this->convertPath($var[$i])) + { + $ret[] = $path; + } + else + { + foreach($var[$i] as $v) + { + $var[] = $v; + } + } + unset($var[$i]); + $i ++; + } + return $ret; + } + + /** + * Using iterative algorithm scanning subdirectories + * save autoloader filemap + * + * @param array $dirs one-dimensional + * @return + */ + protected function scanDirs($dirs) + { + $i = 0; + while (isset($dirs[$i])) + { + $dir = $dirs[$i]; + $files = scandir($dir); + foreach ($files as $file) + { + if (in_array($file, array(".", "..")) || in_array($file, $this->conf["skip_dir_names"])) + { + continue; + } + $currentFile = $dir . DIRECTORY_SEPARATOR . $file; + if (is_file($currentFile)) + { + $this->addFileMap($currentFile); + } + else if (is_dir($currentFile)) + { + // if $currentFile is a directory, pass through the next loop. + $dirs[] = $currentFile; + } + else + { + trigger_error("$currentFile is not a file or a directory."); + } + } //end foreach + unset($dirs[$i]); + $i ++; + } //end while + } + + protected function parseLibNames($src) + { + $libNames = array(); + $tokens = token_get_all($src); + $level = 0; + $found = false; + $name = ''; + foreach ($tokens as $token) + { + if (is_string($token)) + { + if ('{' == $token) + { + $level ++; + } + else if ('}' == $token) + { + $level --; + } + } + else + { + list($id, $text) = $token; + if (T_CURLY_OPEN == $id || T_DOLLAR_OPEN_CURLY_BRACES == $id) + { + $level ++; + } + if (0 < $level) + { + continue; + } + switch ($id) + { + case T_STRING: + if ($found) + { + $libNames[strtolower($name)][] = $text; + $found = false; + } + break; + case T_CLASS: + case T_INTERFACE: + case T_FUNCTION: + $found = true; + $name = $text; + break; + } + } + } + return $libNames; + } + + protected function addClass($className, $file) + { + $key = strtolower($className); + if ($existedClassFile = $this->storeHandle->get($key)) + { + trigger_error("duplicate class [$className] found in:\n$existedClassFile\n$file\n"); + return false; + } + else + { + $this->storeHandle->add($key, $file); + $this->storeHandle->update(".class_total", $this->storeHandle->get(".class_total") + 1); + return true; + } + } + + protected function addFunction($functionName, $file) + { + $functionName = strtolower($functionName); + if (isset($this->functionFileMapping[$functionName])) + { + $existedFunctionFile = $this->functionFileMapping[$functionName]; + trigger_error("duplicate function [$functionName] found in:\n$existedFunctionFile\n$file\n"); + return false; + } + else + { + $this->functionFileMapping[$functionName] = $file; + $this->storeHandle->update(".functions", array_unique(array_values($this->functionFileMapping))); + $this->storeHandle->update(".function_total", count($this->functionFileMapping)); + return true; + } + } + + protected function addFileMap($file) + { + if (!in_array(pathinfo($file, PATHINFO_EXTENSION), $this->conf["allow_file_extension"])) + { + return false; + } + $libNames = array(); + if ($this->fileStore instanceof LtStore) + { + $cachedFileLastModified = (int) @filemtime($this->fileStore->getFilePath($file)); + if ($cachedFileLastModified < filemtime($file) || !is_array(($libNames = $this->fileStore->get($file)))) + { + $libNames = $this->parseLibNames(trim(file_get_contents($file))); + if (0 < $cachedFileLastModified) + { + $this->fileStore->update($file, $libNames); + } + else + { + $this->fileStore->add($file, $libNames); + } + } + } + else + { + $libNames = $this->parseLibNames(trim(file_get_contents($file))); + } + + foreach ($libNames as $libType => $libArray) + { + $method = "function" == $libType ? "addFunction" : "addClass"; + foreach ($libArray as $libName) + { + $this->$method($libName, $file); + } + } + return true; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapter.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapter.php new file mode 100755 index 0000000..5009b9b --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapter.php @@ -0,0 +1,9 @@ +getRealKey($tableName, $key), $value, $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return apc_delete($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + return apc_fetch($this->getRealKey($tableName, $key)); + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + if ($this->del($key, $tableName, $connectionResource)) + { + return $this->add($key, $value, $ttl, $tableName, $connectionResource); + } + else + { + return false; + } + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterEAccelerator.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterEAccelerator.php new file mode 100755 index 0000000..181de30 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterEAccelerator.php @@ -0,0 +1,49 @@ +getRealKey($tableName, $key), $value, $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return eaccelerator_rm($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + $value = eaccelerator_get($this->getRealKey($tableName, $key)); + if (!empty($value)) + { + return unserialize($value); + } + else + { + return false; + } + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + if ($this->del($key, $tableName, $connectionResource)) + { + return $this->add($key, $value, $ttl, $tableName, $connectionResource); + } + else + { + return false; + } + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterFile.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterFile.php new file mode 100755 index 0000000..c0af63b --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterFile.php @@ -0,0 +1,68 @@ +prefix = 'LtCache-file'; + $fileStore->useSerialize = true; + $fileStore->init(); + return $fileStore; + } + + public function add($key, $value, $ttl = 0, $tableName, $connectionResource) + { + if (0 != $ttl) + { + $ttl += time(); + } + if (true == $connectionResource->add($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value))) + { + return true; + } + else + { + if ($this->get($key,$tableName,$connectionResource)) + { + return false; + } + else + { + $this->del($key,$tableName,$connectionResource); + return $connectionResource->add($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value)); + } + } + } + + public function del($key, $tableName, $connectionResource) + { + return $connectionResource->del($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + $cachedArray = $connectionResource->get($this->getRealKey($tableName, $key)); + if (is_array($cachedArray) && (0 == $cachedArray["ttl"] || $cachedArray["ttl"] > time())) + { + return $cachedArray["value"]; + } + else + { + return false; + } + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + if (0 != $ttl) + { + $ttl += time(); + } + return $connectionResource->update($this->getRealKey($tableName, $key), array("ttl" => $ttl, "value" => $value)); + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcache.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcache.php new file mode 100755 index 0000000..98a7c16 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcache.php @@ -0,0 +1,33 @@ +add($this->getRealKey($tableName, $key), $value, false, $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return $connectionResource->delete($this->getRealKey($tableName, $key), 0); + } + + public function get($key, $tableName, $connectionResource) + { + return $connectionResource->get($this->getRealKey($tableName, $key)); + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + return $connectionResource->replace($this->getRealKey($tableName, $key), $value, false, $ttl); + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcached.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcached.php new file mode 100755 index 0000000..509caff --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterMemcached.php @@ -0,0 +1,35 @@ +addServer($hostConf["host"], $hostConf["port"]); + return $connectionResource; + } + + public function add($key, $value, $ttl=0, $tableName, $connectionResource) + { + return $connectionResource->add($this->getRealKey($tableName, $key), $value, $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return $connectionResource->delete($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + return $connectionResource->get($this->getRealKey($tableName, $key)); + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + return $connectionResource->replace($this->getRealKey($tableName, $key), $value, $ttl); + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterPhps.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterPhps.php new file mode 100755 index 0000000..fb24868 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterPhps.php @@ -0,0 +1,55 @@ +cacheFileRoot = $hostConf['host']; + $fileStore->prefix = 'Ltcache-phps-'; + $fileStore->init(); + return $fileStore; + } + else + { + trigger_error("Must set [host]"); + return false; + } + } + + public function add($key, $value, $ttl = 0, $tableName, $connectionResource) + { + return $connectionResource->add($this->getRealKey($tableName, $key), $this->valueToString($value), $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return $connectionResource->del($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + return $this->stringToValue($connectionResource->get($this->getRealKey($tableName, $key))); + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + return $connectionResource->update($this->getRealKey($tableName, $key), $this->valueToString($value), $ttl); + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } + + protected function valueToString($value) + { + return serialize($value); + } + + protected function stringToValue($str) + { + return unserialize($str); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterXcache.php b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterXcache.php new file mode 100755 index 0000000..25d3bc5 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Adapter/CacheAdapterXcache.php @@ -0,0 +1,43 @@ +getRealKey($tableName, $key), $value, $ttl); + } + + public function del($key, $tableName, $connectionResource) + { + return xcache_unset($this->getRealKey($tableName, $key)); + } + + public function get($key, $tableName, $connectionResource) + { + $key = $this->getRealKey($tableName, $key); + if (xcache_isset($key)) + { + return xcache_get($key); + } + return false; + } + + public function update($key, $value, $ttl = 0, $tableName, $connectionResource) + { + $key = $this->getRealKey($tableName, $key); + if (xcache_isset($key)) + { + return xcache_set($key, $value, $ttl); + } + return false; + } + + protected function getRealKey($tableName, $key) + { + return $tableName . "-" . $key; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Cache/Cache.php b/extend/app_alipay/lotusphp_runtime/Cache/Cache.php new file mode 100755 index 0000000..55a84d3 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/Cache.php @@ -0,0 +1,76 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->ch = new LtCacheHandle; + $this->ch->configHandle = $this->configHandle; + $this->ch->init(); + $this->ch->group = $this->getGroup(); + $this->ch->node = $this->getNode(); + } + + public function getTDG($tableName) + { + $tdg = new LtCacheTableDataGateway; + $tdg->tableName = $tableName; + $tdg->ch = $this->ch; + return $tdg; + } + + public function changeNode($node) + { + $this->node = $node; + $this->dbh->node = $node; + } + + protected function getGroup() + { + if ($this->group) + { + return $this->group; + } + $servers = $this->configHandle->get("cache.servers"); + if (1 == count($servers)) + { + return key($servers); + } + return false; + } + + protected function getNode() + { + if ($this->node) + { + return $this->node; + } + $servers = $this->configHandle->get("cache.servers"); + if (1 == count($servers[$this->getGroup()])) + { + return key($servers[$this->getGroup()]); + } + return false; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/CacheAdapterFactory.php b/extend/app_alipay/lotusphp_runtime/Cache/CacheAdapterFactory.php new file mode 100755 index 0000000..52b625c --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/CacheAdapterFactory.php @@ -0,0 +1,14 @@ + "phps", //apc,xcach,ea; file, phps; memcached + //"prefix" => "" + //"host" => "localhost", //some ip, hostname + //"port" => 3306, + ); + + public function addSingleHost($hostConfig) + { + $this->addHost("group_0", "node_0", "master", $hostConfig); + } + + public function addHost($groupId, $nodeId = "node_0", $role = "master", $hostConfig) + { + if (isset($this->servers[$groupId][$nodeId][$role])) + {//以相同role的第一个host为默认配置 + $ref = $this->servers[$groupId][$nodeId][$role][0]; + } + else if ("slave" == $role && isset($this->servers[$groupId][$nodeId]["master"])) + {//slave host以master的第一个host为默认配置 + $ref = $this->servers[$groupId][$nodeId]["master"][0]; + } + else if (isset($this->servers[$groupId]) && count($this->servers[$groupId])) + {//以本group第一个node的master第一个host为默认配置 + $refNode = key($this->servers[$groupId]); + $ref = $this->servers[$groupId][$refNode]["master"][0]; + } + else + { + if (!isset($hostConfig["adapter"])) + { + trigger_error("No db adapter specified"); + } + $ref = $this->defaultConfig; + } + $conf = array_merge($ref, $hostConfig); + $this->servers[$groupId][$nodeId][$role][] = $conf; + } + + public function getServers() + { + return $this->servers; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/CacheConnectionManager.php b/extend/app_alipay/lotusphp_runtime/Cache/CacheConnectionManager.php new file mode 100755 index 0000000..6c06706 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/CacheConnectionManager.php @@ -0,0 +1,52 @@ +getNewConnection($group, $node, $role)) + { + return array( + "connectionAdapter" => $this->connectionAdapter, + "connectionResource" => $connection + ); + } + else + { + trigger_error("no cache server can be connected"); + return false; + } + } + + protected function getNewConnection($group, $node, $role) + { + $servers = $this->configHandle->get("cache.servers"); + $hostTotal = count($servers[$group][$node][$role]); + $hostIndexArray = array_keys($servers[$group][$node][$role]); + while ($hostTotal) + { + $hashNumber = substr(microtime(),7,1) % $hostTotal; + $hostConfig = $servers[$group][$node][$role][$hostIndexArray[$hashNumber]]; + $cacheFactory = new LtCacheAdapterFactory; + $this->connectionAdapter = $cacheFactory->getConnectionAdapter($hostConfig["adapter"]); + if ($connection = $this->connectionAdapter->connect($hostConfig)) + { + return $connection; + } + else + { + //trigger_error('connection fail', E_USER_WARNING); + //delete the unavailable server + for ($i = $hashNumber; $i < $hostTotal - 1; $i ++) + { + $hostIndexArray[$i] = $hostIndexArray[$i+1]; + } + unset($hostIndexArray[$hostTotal-1]); + $hostTotal --; + }//end else + }//end while + return false; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/CacheHandle.php b/extend/app_alipay/lotusphp_runtime/Cache/CacheHandle.php new file mode 100755 index 0000000..e39faf1 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/CacheHandle.php @@ -0,0 +1,52 @@ +connectionManager = new LtCacheConnectionManager; + $this->connectionManager->configHandle =$this->configHandle; + } + + public function add($key, $value, $ttl = 0, $tableName) + { + $this->initConnection(); + return $this->connectionAdapter->add($key, $value, $ttl, $tableName, $this->connectionResource); + } + + public function del($key, $tableName) + { + $this->initConnection(); + return $this->connectionAdapter->del($key, $tableName, $this->connectionResource); + } + + public function get($key, $tableName) + { + $this->initConnection(); + return $this->connectionAdapter->get($key, $tableName, $this->connectionResource); + } + + public function update($key, $value, $ttl = 0, $tableName) + { + $this->initConnection(); + return $this->connectionAdapter->update($key, $value, $ttl, $tableName, $this->connectionResource); + } + + protected function initConnection() + { + $connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role); + $this->connectionAdapter = $connectionInfo["connectionAdapter"]; + $this->connectionResource = $connectionInfo["connectionResource"]; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cache/QueryEngine/TableDataGateway/CacheTableDataGateway.php b/extend/app_alipay/lotusphp_runtime/Cache/QueryEngine/TableDataGateway/CacheTableDataGateway.php new file mode 100755 index 0000000..63efdb6 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cache/QueryEngine/TableDataGateway/CacheTableDataGateway.php @@ -0,0 +1,27 @@ +ch->add($key, $value, $ttl, $this->tableName); + } + + public function del($key) + { + return $this->ch->del($key, $this->tableName); + } + + public function get($key) + { + return $this->ch->get($key, $this->tableName); + } + + public function update($key, $value, $ttl = 0) + { + return $this->ch->update($key, $value, $ttl, $this->tableName); + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/Captcha.php b/extend/app_alipay/lotusphp_runtime/Captcha/Captcha.php new file mode 100755 index 0000000..bc92158 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Captcha/Captcha.php @@ -0,0 +1,91 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + if (!is_object($this->storeHandle)) + { + $this->storeHandle = new LtStoreFile; + $this->storeHandle->prefix = 'LtCaptcha-seed-'; + $this->storeHandle->init(); + } + } + + public function getImageResource($seed) + { + if (empty($seed)) + { + trigger_error("empty seed"); + return false; + } + if (!is_object($this->imageEngine)) + { + if ($imageEngine = $this->configHandle->get("captcha.image_engine")) + { + if (class_exists($imageEngine)) + { + $this->imageEngine = new $imageEngine; + $this->imageEngine->conf = $this->configHandle->get("captcha.image_engine_conf"); + } + else + { + trigger_error("captcha.image_engine : $imageEngine not exists"); + } + } + else + { + trigger_error("empty captcha.image_engine"); + return false; + } + } + $word = $this->generateRandCaptchaWord($seed); + $this->storeHandle->add($seed, $word); + return $this->imageEngine->drawImage($word); + } + + public function verify($seed, $userInput) + { + if ($word = $this->storeHandle->get($seed)) + { + $this->storeHandle->del($seed); + return $userInput === $word; + } + else + { + return false; + } + } + + protected function generateRandCaptchaWord() + { + $allowChars = $this->configHandle->get("captcha.allow_chars"); + $length = $this->configHandle->get("captcha.length"); + $allowedSymbolsLength = strlen($allowChars) - 1; + $captchaWord = ""; + for ($i = 0; $i < $length; $i ++) + { + $captchaWord .= $allowChars[mt_rand(0, $allowedSymbolsLength)]; + } + return $captchaWord; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/CaptchaImageEngine.php b/extend/app_alipay/lotusphp_runtime/Captcha/CaptchaImageEngine.php new file mode 100755 index 0000000..2990608 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Captcha/CaptchaImageEngine.php @@ -0,0 +1,197 @@ + array('spacing' => -3, 'minSize' => 27, 'maxSize' => 30, 'font' => 'AntykwaBold.ttf'), + 'Candice' => array('spacing' => -1.5, 'minSize' => 28, 'maxSize' => 31, 'font' => 'Candice.ttf'), + 'DingDong' => array('spacing' => -2, 'minSize' => 24, 'maxSize' => 30, 'font' => 'Ding-DongDaddyO.ttf'), + 'Duality' => array('spacing' => -2, 'minSize' => 30, 'maxSize' => 38, 'font' => 'Duality.ttf'), + 'Jura' => array('spacing' => -2, 'minSize' => 28, 'maxSize' => 32, 'font' => 'Jura.ttf'), + 'StayPuft' => array('spacing' => -1.5, 'minSize' => 28, 'maxSize' => 32, 'font' => 'StayPuft.ttf'), + 'Times' => array('spacing' => -2, 'minSize' => 28, 'maxSize' => 34, 'font' => 'TimesNewRomanBold.ttf'), + 'VeraSans' => array('spacing' => -1, 'minSize' => 20, 'maxSize' => 28, 'font' => 'VeraSansBold.ttf'), + ); + + /** + * * Wave configuracion in X and Y axes + */ + protected $Yperiod = 12; + protected $Yamplitude = 14; + protected $Xperiod = 11; + protected $Xamplitude = 5; + + /** + * * GD image + */ + protected $im; + + public function drawImage($text) + { + /** + * * Initialization + */ + $this->ImageAllocate(); + + $fontcfg = $this->fonts[array_rand($this->fonts)]; + $this->WriteText($text, $fontcfg); + + /** + * * Transformations + */ + $this->WaveImage(); + if ($this->conf['blur'] && function_exists('imagefilter')) + { + imagefilter($this->im, IMG_FILTER_GAUSSIAN_BLUR); + } + $this->ReduceImage(); + return $this->im; + } + + /** + * Creates the image resources + */ + protected function ImageAllocate() + { + // Cleanup + if (!empty($this->im)) + { + imagedestroy($this->im); + } + + $this->im = imagecreatetruecolor($this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale']); + // Background color + $this->GdBgColor = imagecolorallocate($this->im, + $this->backgroundColor[0], + $this->backgroundColor[1], + $this->backgroundColor[2] + ); + imagefilledrectangle($this->im, 0, 0, $this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale'], $this->GdBgColor); + // Foreground color + $color = $this->colors[mt_rand(0, sizeof($this->colors)-1)]; + $this->GdFgColor = imagecolorallocate($this->im, $color[0], $color[1], $color[2]); + // Shadow color + if (!empty($this->shadowColor) && is_array($this->shadowColor) && sizeof($this->shadowColor) >= 3) + { + $this->GdShadowColor = imagecolorallocate($this->im, + $this->shadowColor[0], + $this->shadowColor[1], + $this->shadowColor[2] + ); + } + } + + /** + * Text insertion + */ + protected function WriteText($text, $fontcfg = array()) + { + if (empty($fontcfg)) + { + // Select the font configuration + $fontcfg = $this->fonts[array_rand($this->fonts)]; + } + // Full path of font file + $fontfile = dirname(__FILE__) . '/fonts/' . $fontcfg['font']; + + /** + * * Increase font-size for shortest words: 9% for each glyp missing + */ + $lettersMissing = $this->maxWordLength - strlen($text); + $fontSizefactor = 1 + ($lettersMissing * 0.09); + // Text generation (char by char) + $x = 20 * $this->conf['scale']; + $y = round(($this->conf['height'] * 27 / 40) * $this->conf['scale']); + $length = strlen($text); + for ($i = 0; $i < $length; $i++) + { + $degree = rand($this->conf['max_rotation'] * -1, $this->conf['max_rotation']); + $fontsize = rand($fontcfg['minSize'], $fontcfg['maxSize']) * $this->conf['scale'] * $fontSizefactor; + $letter = substr($text, $i, 1); + + if ($this->shadowColor) + { + $coords = imagettftext($this->im, $fontsize, $degree, + $x + $this->conf['scale'], $y + $this->conf['scale'], + $this->GdShadowColor, $fontfile, $letter); + } + $coords = imagettftext($this->im, $fontsize, $degree, + $x, $y, + $this->GdFgColor, $fontfile, $letter); + $x += ($coords[2] - $x) + ($fontcfg['spacing'] * $this->conf['scale']); + } + } + + /** + * Wave filter + */ + protected function WaveImage() + { + // X-axis wave generation + $xp = $this->conf['scale'] * $this->Xperiod * rand(1, 3); + $k = rand(0, 100); + for ($i = 0; $i < ($this->conf['width'] * $this->conf['scale']); $i++) + { + imagecopy($this->im, $this->im, + $i-1, sin($k + $i / $xp) * ($this->conf['scale'] * $this->Xamplitude), + $i, 0, 1, $this->conf['height'] * $this->conf['scale']); + } + // Y-axis wave generation + $k = rand(0, 100); + $yp = $this->conf['scale'] * $this->Yperiod * rand(1, 2); + for ($i = 0; $i < ($this->conf['height'] * $this->conf['scale']); $i++) + { + imagecopy($this->im, $this->im, + sin($k + $i / $yp) * ($this->conf['scale'] * $this->Yamplitude), $i-1, + 0, $i, $this->conf['width'] * $this->conf['scale'], 1); + } + } + + /** + * Reduce the image to the final size + */ + protected function ReduceImage() + { + $imResampled = imagecreatetruecolor($this->conf['width'], $this->conf['height']); + imagecopyresampled($imResampled, $this->im, + 0, 0, 0, 0, + $this->conf['width'], $this->conf['height'], + $this->conf['width'] * $this->conf['scale'], $this->conf['height'] * $this->conf['scale'] + ); + imagedestroy($this->im); + $this->im = $imResampled; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/AntykwaBold.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/AntykwaBold.ttf new file mode 100755 index 0000000..cdeeded Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/AntykwaBold.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Candice.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Candice.ttf new file mode 100755 index 0000000..84439b8 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Candice.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Ding-DongDaddyO.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Ding-DongDaddyO.ttf new file mode 100755 index 0000000..d1dea71 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Ding-DongDaddyO.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Duality.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Duality.ttf new file mode 100755 index 0000000..581d5ce Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Duality.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Jura.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Jura.ttf new file mode 100755 index 0000000..ee0a1c7 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/Jura.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/StayPuft.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/StayPuft.ttf new file mode 100755 index 0000000..09ced57 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/StayPuft.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/TimesNewRomanBold.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/TimesNewRomanBold.ttf new file mode 100755 index 0000000..0fc9d84 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/TimesNewRomanBold.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Captcha/fonts/VeraSansBold.ttf b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/VeraSansBold.ttf new file mode 100755 index 0000000..51d6111 Binary files /dev/null and b/extend/app_alipay/lotusphp_runtime/Captcha/fonts/VeraSansBold.ttf differ diff --git a/extend/app_alipay/lotusphp_runtime/Config.php b/extend/app_alipay/lotusphp_runtime/Config.php new file mode 100755 index 0000000..cce6988 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Config.php @@ -0,0 +1,84 @@ +storeHandle)) + { + $this->storeHandle = new LtStoreMemory; + } + } + + public function init() + { + //don't removeme, I am the placeholder + } + + public function get($key) + { + $storedConfig = $this->storeHandle->get($key); + if ($storedConfig instanceof LtConfigExpression) + { + $str = $storedConfig->__toString(); + if ($storedConfig->autoRetrived) + { + eval("\$value=$str;"); + return $value; + } + else + { + return $str; + } + } + else + { + return $storedConfig; + } + } + + /** + * 警告 + * 这里会包含两个用户定义的配置文件,为了不和配置文件里的变量名发生重名 + * 本方法不定义和使用变量名 + */ + public function loadConfigFile($configFile) + { + if (0 == $this->storeHandle->get(".config_total")) + { + if (null === $configFile || !is_file($configFile)) + { + trigger_error("no config file specified or invalid config file"); + } + $this->conf = include($configFile); + if (!is_array($this->conf)) + { + trigger_error("config file do NOT return array: $configFile"); + } + elseif (!empty($this->conf)) + { + if (0 == $this->storeHandle->get(".config_total")) + { + $this->storeHandle->add(".config_total", 0); + } + $this->addConfig($this->conf); + } + } + } + + public function addConfig($configArray) + { + foreach($configArray as $key => $value) + { + if (!$this->storeHandle->update($key, $value)) + { + if ($this->storeHandle->add($key, $value)) + { + $this->storeHandle->update(".config_total", $this->storeHandle->get(".config_total") + 1, 0); + } + } + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/ConfigExpression.php b/extend/app_alipay/lotusphp_runtime/ConfigExpression.php new file mode 100755 index 0000000..12384fc --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/ConfigExpression.php @@ -0,0 +1,17 @@ +_expression = (string) $string; + $this->autoRetrived = $autoRetrived; + } + + public function __toString() + { + return $this->_expression; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Cookie/Cookie.php b/extend/app_alipay/lotusphp_runtime/Cookie/Cookie.php new file mode 100755 index 0000000..4859e07 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Cookie/Cookie.php @@ -0,0 +1,136 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->secretKey = $this->configHandle->get("cookie.secret_key"); + if(empty($this->secretKey)) + { + trigger_error("cookie.secret_key empty"); + } + } + + /** + * Decrypt the encrypted cookie + * + * @param string $encryptedText + * @return string + */ + protected function decrypt($encryptedText) + { + $key = $this->secretKey; + $cryptText = base64_decode($encryptedText); + $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); + $decryptText = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $cryptText, MCRYPT_MODE_ECB, $iv); + return trim($decryptText); + } + + /** + * Encrypt the cookie + * + * @param string $plainText + * @return string + */ + protected function encrypt($plainText) + { + $key = $this->secretKey; + $ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); + $encryptText = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $plainText, MCRYPT_MODE_ECB, $iv); + return trim(base64_encode($encryptText)); + } + + /** + * Set cookie value to deleted with $name + * + * @param array $args + * @return boolean + */ + public function delCookie($name, $path = '/', $domain = null) + { + if (isset($_COOKIE[$name])) + { + if (is_array($_COOKIE[$name])) + { + foreach($_COOKIE[$name] as $k => $v) + { + setcookie($name . '[' . $k . ']', '', time() - 86400, $path, $domain); + } + } + else + { + setcookie($name, '', time() - 86400, $path, $domain); + } + } + } + + /** + * Get cookie value with $name + * + * @param string $name + * @return mixed + */ + public function getCookie($name) + { + $ret = null; + if (isset($_COOKIE[$name])) + { + if (is_array($_COOKIE[$name])) + { + $ret = array(); + foreach($_COOKIE[$name] as $k => $v) + { + $v = $this->decrypt($v); + $ret[$k] = $v; + } + } + else + { + $ret = $this->decrypt($_COOKIE[$name]); + } + } + return $ret; + } + + /** + * Set cookie + * + * @param array $args + * @return boolean + */ + public function setCookie($name, $value = '', $expire = null, $path = '/', $domain = null, $secure = 0) + { + if (is_array($value)) + { + foreach($value as $k => $v) + { + $v = $this->encrypt($v); + setcookie($name . '[' . $k . ']', $v, $expire, $path, $domain, $secure); + } + } + else + { + $value = $this->encrypt($value); + setcookie($name, $value, $expire, $path, $domain, $secure); + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapter.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapter.php new file mode 100755 index 0000000..4787251 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapter.php @@ -0,0 +1,12 @@ +query($sql); + return $connResource->affected_rows; + } + + public function query($sql, $connResource) + { + $rows = array(); + $result = $connResource->query($sql); + while($row = $result->fetch_assoc()) + { + $rows[] = $row; + } + return $rows; + } + + public function lastInsertId($connResource) + { + return $connResource->insert_id; + } + + public function escape($sql, $connResource) + { + return mysqli_real_escape_string($connResource, $sql); + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPdo.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPdo.php new file mode 100755 index 0000000..78a998f --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPdo.php @@ -0,0 +1,65 @@ + true); + if (isset($connConf['pconnect']) && true == $connConf['pconnect']) + { + $option[PDO::ATTR_PERSISTENT] = true; + } + else + { + $option[PDO::ATTR_PERSISTENT] = false; + } + switch ($connConf['adapter']) + { + case "pdo_mysql": + $dsn = "mysql:host={$connConf['host']};dbname={$connConf['dbname']}"; + break; + case "pdo_sqlite": + $connConf["host"] = rtrim($connConf["host"], '\\/') . DIRECTORY_SEPARATOR; + if (!is_dir($connConf["host"])) + { + if (!@mkdir($connConf["host"], 0777, true)) + { + trigger_error("Can not create {$connConf['host']}"); + } + } + $dsn = "{$connConf['sqlite_version']}:{$connConf['host']}{$connConf['dbname']}"; + break; + case "pdo_pgsql": + $dsn = "pgsql:host={$connConf['host']} port={$connConf['port']} dbname={$connConf['dbname']} user={$connConf['username']} password={$connConf['password']}"; + break; + case "odbc": + $dsn = "odbc:" . $connConf["host"]; + break; + } + return new PDO($dsn, $connConf['username'], $connConf['password'], $option); + } + + public function exec($sql, $connResource) + { + return $connResource->exec($sql); + } + + public function query($sql, $connResource) + { + return $connResource->query($sql)->fetchAll(PDO::FETCH_ASSOC); + } + + /** + * + * @todo pgsql support + */ + public function lastInsertId($connResource) + { + return $connResource->lastInsertId(); + } + + public function escape($sql, $connResource) + { + // quote返回值带最前面和最后面的单引号, 这里去掉, DbHandler中加 + return trim($connResource->quote($sql), "'"); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPgsql.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPgsql.php new file mode 100755 index 0000000..4f06afd --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/ConnectionAdapter/DbConnectionAdapterPgsql.php @@ -0,0 +1,46 @@ +'; + // print_r(debug_backtrace()); + // debug_print_backtrace(); + // echo ''; + // delete from table 结果为0,原因未知。 + // 使用 delete from table where 1 能返回正确结果 + return sqlite_changes($connResource); + } + + public function query($sql, $connResource) + { + $result = sqlite_query($connResource, $sql, SQLITE_ASSOC); + return sqlite_fetch_all($result, SQLITE_ASSOC); + } + + public function lastInsertId($connResource) + { + return sqlite_last_insert_rowid($connResource); + } + + public function escape($sql, $connResource) + { + return sqlite_escape_string($sql); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php new file mode 100755 index 0000000..b596dff --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapter.php @@ -0,0 +1,31 @@ + $value) + { + $fields[$value['Field']]['name'] = $value['Field']; + $fields[$value['Field']]['type'] = $value['Type']; + /* + * not null is NO or empty, null is YES + */ + $fields[$value['Field']]['notnull'] = (bool) ($value['Null'] != 'YES'); + $fields[$value['Field']]['default'] = $value['Default']; + $fields[$value['Field']]['primary'] = (strtolower($value['Key']) == 'pri'); + } + return $fields; + } + public function detectQueryType($sql) + { + if (preg_match("/^\s*SELECT|^\s*EXPLAIN|^\s*SHOW|^\s*DESCRIBE/i", $sql)) + { + $ret = 'SELECT'; + } + else if (preg_match("/^\s*INSERT/i", $sql)) + { + $ret = 'INSERT'; + } + else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql)) + { + $ret = 'CHANGE_ROWS'; + } + else if (preg_match("/^\s*USE|^\s*SET/i", $sql)) + { + $ret = 'SET_SESSION_VAR'; + } + else + { + $ret = 'OTHER'; + } + return $ret; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterPgsql.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterPgsql.php new file mode 100755 index 0000000..4c67445 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterPgsql.php @@ -0,0 +1,81 @@ + 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid + ORDER BY a.attnum"; + } + + public function limit($limit, $offset) + { + return " LIMIT $limit OFFSET $offset"; + } + + public function getSchemas($queryResult) + { + + } + public function getTables($queryResult) + { + + } + public function getFields($queryResult) + { + + } + public function detectQueryType($sql) + { + + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php new file mode 100755 index 0000000..7c560a8 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Adapter/SqlAdapter/DbSqlAdapterSqlite.php @@ -0,0 +1,120 @@ + $value) + { + // 字段名 + $fields[$value['name']]['name'] = $value['name']; + // 字段类型 + $fulltype = $value['type']; + $size = null; + $precision = null; + $scale = null; + + if (preg_match('/^([^\(]+)\(\s*(\d+)\s*,\s*(\d+)\s*\)$/',$fulltype, $matches)) + { + $type = $matches[1]; + $precision = $matches[2]; + $scale = $matches[3]; // aka precision + } + elseif (preg_match('/^([^\(]+)\(\s*(\d+)\s*\)$/',$fulltype, $matches)) + { + $type = $matches[1]; + $size = $matches[2]; + } + else + { + $type = $fulltype; + } + + $fields[$value['name']]['type'] = $type; + /** + * not null is 99, null is 0 + */ + $fields[$value['name']]['notnull'] = (bool) ($value['notnull'] != 0); + $fields[$value['name']]['default'] = $value['dflt_value']; + $fields[$value['name']]['primary'] = (bool) ($value['pk'] == 1 && strtoupper($fulltype) == 'INTEGER'); + } + return $fields; + } + public function detectQueryType($sql) + { + if (preg_match("/^\s*SELECT|^\s*PRAGMA/i", $sql)) + { + $ret = 'SELECT'; + } + else if (preg_match("/^\s*INSERT/i", $sql)) + { + $ret = 'INSERT'; + } + else if (preg_match("/^\s*UPDATE|^\s*DELETE|^\s*REPLACE/i", $sql)) + { + $ret = 'CHANGE_ROWS'; + } + else if (preg_match("/^\s*USE|^\s*SET/i", $sql)) + { + $ret = 'SET_SESSION_VAR'; + } + else + { + $ret = 'OTHER'; + } + return $ret; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/Db.php b/extend/app_alipay/lotusphp_runtime/DB/Db.php new file mode 100755 index 0000000..5f97124 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/Db.php @@ -0,0 +1,91 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->dbh = new LtDbHandle; + $this->dbh->configHandle = $this->configHandle; + $this->dbh->group = $this->getGroup(); + $this->dbh->node = $this->getNode(); + $this->dbh->init(); + } + + public function getDbHandle() + { + return $this->dbh; + } + + public function getTDG($tableName) + { + $tg = new LtDbTableDataGateway; + $tg->configHandle = $this->configHandle; + $tg->tableName = $tableName; + $tg->createdColumn = 'created'; + $tg->modifiedColumn = 'modified'; + $tg->dbh = $this->dbh; + return $tg; + } + + public function getSqlMapClient() + { + $smc = new LtDbSqlMapClient; + $smc->configHandle = $this->configHandle; + $smc->dbh = $this->dbh; + return $smc; + } + + public function changeNode($node) + { + $this->node = $node; + $this->dbh->node = $node; + } + + protected function getGroup() + { + if ($this->group) + { + return $this->group; + } + $servers = $this->configHandle->get("db.servers"); + if (1 == count($servers)) + { + return key($servers); + } + return false; + } + + protected function getNode() + { + if ($this->node) + { + return $this->node; + } + $servers = $this->configHandle->get("db.servers"); + if (1 == count($servers[$this->getGroup()])) + { + return key($servers[$this->getGroup()]); + } + return false; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php b/extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php new file mode 100755 index 0000000..f4a9866 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/DbAdapterFactory.php @@ -0,0 +1,15 @@ + array("connection_adapter" => "", "sql_adapter" => "") + "pgsql" => array("connection_adapter" => "pgsql", "sql_adapter" => "pgsql"), + "pdo_pgsql" => array("connection_adapter" => "pdo", "sql_adapter" => "pgsql"), + "oci" => array("connection_adapter" => "oci", "sql_adapter" => "oracle"), + "pdo_oci" => array("connection_adapter" => "pdo", "sql_adapter" => "oracle"), + "mssql" => array("connection_adapter" => "mssql", "sql_adapter" => "mssql"), + "pdo_dblib" => array("connection_adapter" => "pdo", "sql_adapter" => "mssql"), + "mysql" => array("connection_adapter" => "mysql", "sql_adapter" => "mysql"), + "mysqli" => array("connection_adapter" => "mysqli", "sql_adapter" => "mysql"), + "pdo_mysql" => array("connection_adapter" => "pdo", "sql_adapter" => "mysql"), + "sqlite" => array("connection_adapter" => "sqlite", "sql_adapter" => "sqlite"), + "sqlite3" => array("connection_adapter" => "sqlite3", "sql_adapter" => "sqlite"), + "pdo_sqlite" => array("connection_adapter" => "pdo", "sql_adapter" => "sqlite"), + ); + + protected $defaultConfig = array( + "host" => "localhost", //some ip, hostname + //"port" => 3306, + "username" => "root", + "password" => null, + //"adapter" => "mysql", //mysql,mysqli,pdo_mysql,sqlite,pdo_sqlite + "charset" => "UTF-8", + "pconnect" => true, //true,false + "connection_ttl" => 3600, //any seconds + "dbname" => null, //default dbname + "schema" => null, //default schema + "connection_adapter" => null, + "sql_adapter" => null, + ); + + protected $defaultAdapterConfigs = array( + "pgsql" => array( + "port" => 5432, + ), + "oracle" => array( + "port" => 1521, + ), + "mssql" => array( + "port" => 1433, + ), + "mysql" => array( + "port" => 3306, + "pconnect" => false, + "connection_ttl" => 30, + ), + ); + + public function addSingleHost($hostConfig) + { + $this->addHost("group_0", "node_0", "master", $hostConfig); + } + + public function addHost($groupId, $nodeId = "node_0", $role = "master", $hostConfig) + { + if (isset($this->servers[$groupId][$nodeId][$role])) + {//以相同role的第一个host为默认配置 + $ref = $this->servers[$groupId][$nodeId][$role][0]; + } + else if ("slave" == $role && isset($this->servers[$groupId][$nodeId]["master"])) + {//slave host以master的第一个host为默认配置 + $ref = $this->servers[$groupId][$nodeId]["master"][0]; + } + else if (isset($this->servers[$groupId]) && count($this->servers[$groupId])) + {//以本group第一个node的master第一个host为默认配置 + $refNode = key($this->servers[$groupId]); + $ref = $this->servers[$groupId][$refNode]["master"][0]; + } + else + { + if (!isset($hostConfig["adapter"])) + { + trigger_error("No db adapter specified"); + } + $ref = $this->defaultConfig; + if (isset($this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]])) + { + $ref = array_merge($ref, $this->defaultAdapterConfigs[$this->adapters[$hostConfig["adapter"]]["sql_adapter"]]); + } + } + $conf = array_merge($ref, $hostConfig); + $conf = array_merge($conf, $this->adapters[$conf["adapter"]]); + $conf = $this->convertDbnameToSchema($conf); + $this->servers[$groupId][$nodeId][$role][] = $conf; + } + + public function getServers() + { + return $this->servers; + } + + public function getTables() + { + return $this->tables; + } + + public function buildTablesConfig() + { + + } + + /** + * Convert dbname to schema for: FrontBase, MySQL, mSQL, MS SQL Server, MaxDB, Sybase + * See: http://www.php.net/manual-lookup.php?pattern=_select_db + */ + protected function convertDbnameToSchema($conf) + { + if (preg_match("/fbsql|mysql|msql|mssql|maxdb|sybase/i", $conf["sql_adapter"]) && isset($conf["dbname"])) + { + $conf["schema"] = $conf["dbname"]; + $conf["dbname"] = null; + } + return $conf; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php b/extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php new file mode 100755 index 0000000..bcdd41a --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/DbConnectionManager.php @@ -0,0 +1,117 @@ + connection resource id, + * "expire_time" => expire time, + * "schema" => default schema name, + * "charset" => char set / encoding + * ) + */ + static public $connectionPool; + public $configHandle; + protected $connectionAdapter; + protected $sqlAdapter; + private $servers; + + public function getConnection($group, $node, $role = "master") + { + if(empty($this->servers)) + { + $this->servers = $this->configHandle->get("db.servers"); + } + if (($connection = $this->getNewConnection($group, $node, $role)) ||($connection = $this->getCachedConnection($group, $node, $role))) + { + return array( + "connectionAdapter" => $this->connectionAdapter, + "connectionResource" => $connection + ); + } + else + { + trigger_error("db server can not be connected: group=$group, node=$node, role=$role", E_USER_ERROR); + return false; + } + } + + protected function getConnectionKey($connConf) + { + return $connConf['adapter'] . $connConf['host'] . $connConf['port'] . $connConf['username'] . $connConf['dbname']; + } + + protected function saveConnection($connConf, $connection, $ttl) + { + $connectionInfo = array( + "connection" => $connection, + "expire_time" => time() + $ttl, + "schema" => $connConf["schema"], + "charset" => $connConf["charset"], + ); + self::$connectionPool[$this->getConnectionKey($connConf)] = $connectionInfo; + } + + protected function getCachedConnection($group, $node, $role) + { + foreach($this->servers[$group][$node][$role] as $hostConfig) + { + $key = $this->getConnectionKey($hostConfig); + if(isset(self::$connectionPool[$key]) && time() < self::$connectionPool[$key]['expire_time']) + {//cached connection resource FOUND + $connectionInfo = self::$connectionPool[$key]; + if ($connectionInfo["schema"] != $hostConfig["schema"] || $connectionInfo["charset"] != $hostConfig["charset"]) + {//检查当前schema和charset与用户要操作的目标不一致 + $hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]]; + $dbFactory = new LtDbAdapterFactory; + $this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]); + $this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]); + if ($connectionInfo["schema"] != $hostConfig["schema"]) + { + $this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connectionInfo["connection"]); + } + if ($connectionInfo["charset"] != $hostConfig["charset"]) + { + $this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connectionInfo["connection"]); + } + $this->saveConnection($hostConfig, $connectionInfo["connection"], $hostConfig["connection_ttl"]); + } + return $connectionInfo["connection"]; + } + } + return false; + } + + protected function getNewConnection($group, $node, $role) + { + $hostTotal = count($this->servers[$group][$node][$role]); + $hostIndexArray = array_keys($this->servers[$group][$node][$role]); + while ($hostTotal) + { + $hashNumber = substr(microtime(),7,1) % $hostTotal; + $hostConfig = $this->servers[$group][$node][$role][$hostIndexArray[$hashNumber]]; + $dbFactory = new LtDbAdapterFactory; + $this->connectionAdapter = $dbFactory->getConnectionAdapter($hostConfig["connection_adapter"]); + $this->sqlAdapter = $dbFactory->getSqlAdapter($hostConfig["sql_adapter"]); + if ($connection = $this->connectionAdapter->connect($hostConfig)) + { + $this->connectionAdapter->exec($this->sqlAdapter->setSchema($hostConfig["schema"]), $connection); + $this->connectionAdapter->exec($this->sqlAdapter->setCharset($hostConfig["charset"]), $connection); + $this->saveConnection($hostConfig, $connection, $hostConfig["connection_ttl"]); + return $connection; + } + else + { + //trigger_error('connection fail', E_USER_WARNING); + //delete the unavailable server + for ($i = $hashNumber; $i < $hostTotal - 1; $i ++) + { + $hostIndexArray[$i] = $hostIndexArray[$i+1]; + } + unset($hostIndexArray[$hostTotal-1]); + $hostTotal --; + }//end else + }//end while + return false; + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/DB/DbHandle.php b/extend/app_alipay/lotusphp_runtime/DB/DbHandle.php new file mode 100755 index 0000000..54b4277 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/DbHandle.php @@ -0,0 +1,200 @@ +servers)) + { + $this->servers = $this->configHandle->get("db.servers"); + } + $this->connectionManager = new LtDbConnectionManager; + $this->connectionManager->configHandle = $this->configHandle; + $this->sqlAdapter = $this->getCurrentSqlAdapter(); + $connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role); + $this->connectionAdapter = $connectionInfo["connectionAdapter"]; + $this->connectionResource = $connectionInfo["connectionResource"]; + } + + /** + * Trancaction methods + */ + public function beginTransaction() + { + return $this->connectionAdapter->exec($this->sqlAdapter->beginTransaction(), $this->connectionResource); + } + + public function commit() + { + return $this->connectionAdapter->exec($this->sqlAdapter->commit(), $this->connectionResource); + } + + public function rollBack() + { + return $this->connectionAdapter->exec($this->sqlAdapter->rollBack(), $this->connectionResource); + } + + /** + * Execute an sql query + * + * @param $sql + * @param $bind + * @param $forceUseMaster + * @return false on query failed + * --sql type-- --return value-- + * SELECT, SHOW, DESECRIBE, EXPLAIN rowset or NULL when no record found + * INSERT the ID generated for an AUTO_INCREMENT column + * UPDATE, DELETE, REPLACE affected count + * USE, DROP, ALTER, CREATE, SET etc true + * @notice 每次只能执行一条SQL + * 不要通过此接口执行USE DATABASE, SET NAMES这样的语句 + */ + public function query($sql, $bind = null, $forceUseMaster = false) + { + $sql = trim($sql); + if (empty($sql)) + { + trigger_error('Empty the SQL statement'); + } + $queryType = $this->sqlAdapter->detectQueryType($sql); + switch ($queryType) + { + case "SELECT": + if (!$forceUseMaster && isset($this->servers[$this->group][$this->node]["slave"])) + { + $this->role = "slave"; + } + $queryMethod = "select"; + break; + case "INSERT": + $this->role = "master"; + $queryMethod = "insert"; + break; + case "CHANGE_ROWS": + $this->role = "master"; + $queryMethod = "changeRows"; + break; + case "SET_SESSION_VAR": + $queryMethod = "setSessionVar"; + break; + case "OTHER": + default: + $this->role = "master"; + $queryMethod = "other"; + break; + } + $connectionInfo = $this->connectionManager->getConnection($this->group, $this->node, $this->role); + $this->connectionAdapter = $connectionInfo["connectionAdapter"]; + $this->connectionResource = $connectionInfo["connectionResource"]; + if (is_array($bind) && 0 < count($bind)) + { + $sql = $this->bindParameter($sql, $bind); + } + return $this->$queryMethod($sql, $this->connectionResource); + } + /** + * function posted by renlu + */ + public function escape($str) + { + return $this->connectionAdapter->escape($str, $this->connectionResource); + } + /** + * function posted by renlu + */ + public function insertid() + { + return $this->connectionAdapter->lastInsertId($this->connectionResource); + } + /** + * Generate complete sql from sql template (with placeholder) and parameter + * + * @param $sql + * @param $parameter + * @return string + * @todo 兼容pgsql等其它数据库,pgsql的某些数据类型不接受单引号引起来的值 + */ + public function bindParameter($sql, $parameter) + { + // 注意替换结果尾部加一个空格 + $sql = preg_replace("/:([a-zA-Z0-9_\-\x7f-\xff][a-zA-Z0-9_\-\x7f-\xff]*)\s*([,\)]?)/", "\x01\x02\x03\\1\x01\x02\x03\\2 ", $sql); + foreach($parameter as $key => $value) + { + $find[] = "\x01\x02\x03$key\x01\x02\x03"; + if ($value instanceof LtDbSqlExpression) + { + $replacement[] = $value->__toString(); + } + else + { + $replacement[] = "'" . $this->connectionAdapter->escape($value, $this->connectionResource) . "'"; + } + } + $sql = str_replace($find, $replacement, $sql); + return $sql; + } + + protected function getCurrentSqlAdapter() + { + $factory = new LtDbAdapterFactory; + $host = key($this->servers[$this->group][$this->node][$this->role]); + return $factory->getSqlAdapter($this->servers[$this->group][$this->node][$this->role][$host]["sql_adapter"]); + } + + protected function select($sql, $connResource) + { + $result = $this->connectionAdapter->query($sql, $connResource); + if (empty($result)) + { + return null; + } + else + { + return $result; + } + } + + protected function insert($sql, $connResource) + { + if ($result = $this->connectionAdapter->exec($sql, $connResource)) + { + return $this->connectionAdapter->lastInsertId($connResource); + } + else + { + return $result; + } + } + + protected function changeRows($sql, $connResource) + { + return $this->connectionAdapter->exec($sql, $connResource); + } + + /** + * + * @todo 更新连接缓存 + */ + protected function setSessionVar($sql, $connResource) + { + return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true; + } + + protected function other($sql, $connResource) + { + return false === $this->connectionAdapter->exec($sql, $connResource) ? false : true; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php b/extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php new file mode 100755 index 0000000..e03119e --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/DbSqlExpression.php @@ -0,0 +1,15 @@ +_expression = (string) $string; + } + + public function __toString() + { + return (string) $this->_expression; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/AbstractDbSqlMapFilterObject.php b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/AbstractDbSqlMapFilterObject.php new file mode 100755 index 0000000..cb30d86 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/AbstractDbSqlMapFilterObject.php @@ -0,0 +1,16 @@ +configHandle->get($this->dbh->group . "." . $mapId); + $forceUseMaster = isset($sqlMap["force_use_master"]) ? $sqlMap["force_use_master"] : false; + return $this->dbh->query($sqlMap["sql"], $bind, $forceUseMaster); + } +} + diff --git a/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapResultFactory.php b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapResultFactory.php new file mode 100755 index 0000000..9f9053b --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/SqlMap/DbSqlMapResultFactory.php @@ -0,0 +1,24 @@ +fields)) + { + return true; + } + $servers = $this->configHandle->get('db.servers'); + $group = $this->dbh->group; + $node = $this->dbh->node; + $role = $this->dbh->role; + $table = $this->tableName; + $host = key($servers[$group][$node][$role]); + $key = md5($group . $node . $role . $table . $host . $table); + if (!$value = $this->configHandle->get($key)) + { + $sql = $this->dbh->sqlAdapter->showFields($this->tableName); + $rs = $this->dbh->query($sql); + $this->fields = $this->dbh->sqlAdapter->getFields($rs); + foreach($this->fields as $field) + { + if ($field['primary'] == 1) + { + $this->primaryKey = $field['name']; + break; + } + } + + $value['fields'] = $this->fields; + $value['primaryKey'] = $this->primaryKey; + $this->configHandle->addConfig(array($key => $value)); + } + else + { + $this->fields = $value['fields']; + $this->primaryKey = $value['primaryKey']; + } + } + + /** + * A shortcut to SELECT COUNT(*) FROM table WHERE condition + * + * @param array $args + * @return integer + * @example count(array('expression' => 'id < :id', 'value' => array('id' => 10))); + */ + public function count($args = null) + { + $selectTemplate = 'SELECT COUNT(*) AS total FROM %s%s'; + $where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : ''; + $bind = isset($args['where']['value']) ? $args['where']['value'] : array(); + $join = isset($args['join']) ? ' ' . $args['join'] : ''; + $sql = sprintf($selectTemplate, $this->tableName, $join . $where); + $queryResult = $this->dbh->query($sql, $bind); + return $queryResult[0]['total']; + } + + /** + * Delete a row by primary key + * + * @param string $primaryKeyId + * @return string + * @example delete(10); + */ + public function delete($primaryKeyId) + { + $this->buildFieldList(); + $where['expression'] = $this->primaryKey . '=:' . $this->primaryKey; + $where['value'][$this->primaryKey] = $primaryKeyId; + return $this->deleteRows($where); + } + + /** + * Delete many rows from table + * Please use this method carefully! + * + * @param array $args + * @return integer + * @example deleteRows(array('expression' => "id > :id", 'value' => array('id' => 2))); + */ + public function deleteRows($args = null) + { + $deleteTemplate = 'DELETE FROM %s%s'; + $where = isset($args['expression']) ? ' WHERE ' . $args['expression'] : ''; + $bind = isset($args['value']) ? $args['value'] : array(); + $sql = sprintf($deleteTemplate, $this->tableName, $where); + return $this->dbh->query($sql, $bind); + } + + /** + * Fetch one row from table by primary key + * + * @param string $primaryKeyId + * @param array $args + * @param boolean $useSlave + * @return array + * @example fetch(10) + */ + public function fetch($primaryKeyId, $args = null, $useSlave = true) + { + $this->buildFieldList(); + $fetchRowsArgs['where']['expression'] = $this->tableName . '.' . $this->primaryKey . '=:' . $this->primaryKey; + $fetchRowsArgs['where']['value'][$this->primaryKey] = $primaryKeyId; + $fetchRowsArgs['fields'] = isset($args['fields']) ? $args['fields'] : null; + $fetchRowsArgs['join'] = isset($args['join']) ? $args['join'] : null; + $fetchResult = $this->fetchRows($fetchRowsArgs, $useSlave); + return $fetchResult ? $fetchResult[0] : $fetchResult; + } + + /** + * Fetch many rows from table + * + * @param array $args + * @param boolean $useSlave + * @return array + * @example fetchRows(array('where' => array('expression' => "id > :id", 'value' => array('id' => 2)))); + */ + public function fetchRows($args = null, $useSlave = true) + { + $this->buildFieldList(); + $selectTemplate = 'SELECT %s FROM %s%s'; + $fields = isset($args['fields']) ? $args['fields'] : '*'; + $where = isset($args['where']['expression']) ? ' WHERE ' . $args['where']['expression'] : ''; + $bind = isset($args['where']['value']) ? $args['where']['value'] : array(); + $join = isset($args['join']) ? ' ' . $args['join'] : ''; + $orderby = isset($args['orderby']) ? ' ORDER BY ' . $args['orderby'] : ''; + $groupby = isset($args['groupby']) ? ' GROUP BY ' . $args['groupby'] : ''; + $sql = sprintf($selectTemplate, $fields, $this->tableName, $join . $where . $groupby . $orderby); + if (isset($args['limit'])) + { + $offset = isset($args['offset']) ? $args['offset'] : 0; + $sql = $sql . ' ' . $this->dbh->sqlAdapter->limit($args['limit'], $offset); + } + return $this->dbh->query($sql, $bind); + } + + /** + * Insert one row into table, then return the inserted row's pk + * + * @param array $args + * @return string + * @example insert(array('name' => 'lily', 'age' => '12')); + */ + public function insert($args = null) + { + $this->buildFieldList(); + $insertTemplate = 'INSERT INTO %s (%s) VALUES (%s)'; + $fields = array(); + $placeHolders = array(); + foreach($args as $field => $value) + { + if (isset($this->fields[$field])) + { + $fields[] = $field; + $placeholders[] = ":$field"; + $values[$field] = $value; + } + } + if (isset($this->fields[$this->createdColumn]) && !isset($args[$this->createdColumn])) + { + $fields[] = $this->createdColumn; + $placeholders[] = ':' . $this->createdColumn; + $values[$this->createdColumn] = time(); + } + if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn])) + { + $fields[] = $this->modifiedColumn; + $placeholders[] = ':' . $this->modifiedColumn; + $values[$this->modifiedColumn] = time(); + } + $sql = sprintf($insertTemplate, $this->tableName, implode(",", $fields), implode(",", $placeholders)); + $bind = $values; + $queryResult = $this->dbh->query($sql, $bind); + return isset($args[$this->primaryKey]) ? $args[$this->primaryKey] : $queryResult; + } + + /** + * Update one row by primary key + * + * @param string $primaryKeyId + * @param array $args + * @return integer + * @example update(1, array('name' => 'lily', 'age' => '18')); + */ + public function update($primaryKeyId, $args = null) + { + $this->buildFieldList(); + $where['expression'] = $this->primaryKey . '=:' . $this->primaryKey; + $where['value'][$this->primaryKey] = $primaryKeyId; + return $this->updateRows($where, $args); + } + + /** + * Update manay rows + * Please use this method carefully! + * + * @param array $where + * @param array $args + * @return integer + * @example updateRows(array('expression' => "id > :id", 'value' => array('id' => 2)), array('name' => 'kiwi', 'age' => '1')); + */ + public function updateRows($where, $args = null) + { + $this->buildFieldList(); + $updateTemplate = 'UPDATE %s SET %s%s'; + $fields = array(); + $bindParameters = array(); + $placeholderStyle = isset($where['value']) && array_key_exists(0, $where['value']) ? 'questionMark' : 'named'; + foreach($args as $field => $value) + { + if (isset($this->fields[$field])) + { + if ($args[$field] instanceof DbExpression) + { + $fields[] = "$field=" . $args[$field]->__toString(); + } + else + { + if ('named' == $placeholderStyle) + { + $fields[] = "$field=:$field"; + $bindParameters[$field] = $args[$field]; + } + else + { + $fields[] = "$field=?"; + $bindParameters[] = $args[$field]; + } + } + } + } + if (isset($this->fields[$this->modifiedColumn]) && !isset($args[$this->modifiedColumn])) + { + if ('named' == $placeholderStyle) + { + $fields[] = $this->modifiedColumn . '=:' . $this->modifiedColumn; + $bindParameters[$this->modifiedColumn] = time(); + } + else + { + $fields[] = $this->modifiedColumn . '=?'; + $bindParameters[] = time(); + } + } + $whereCause = isset($where['expression']) ? ' WHERE ' . $where['expression'] : ''; + $bind = isset($where['value']) ? array_merge($bindParameters, $where['value']) : $bindParameters; + $sql = sprintf($updateTemplate, $this->tableName, implode(",", $fields), $whereCause); + return $this->dbh->query($sql, $bind); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/TableDataGateway/DbTableRelation.php b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/TableDataGateway/DbTableRelation.php new file mode 100755 index 0000000..b3d9bbc --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/DB/QueryEngine/TableDataGateway/DbTableRelation.php @@ -0,0 +1 @@ + "_"); + + public function camelize($uncamelized_words) + { + $uncamelized_words = $this->conf["separator"] . str_replace($this->conf["separator"] , " ", strtolower($uncamelized_words)); + return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $this->conf["separator"] ); + } + + public function uncamelize($camelCaps) + { + return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $this->conf["separator"] . "$2", $camelCaps)); + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Logger/Logger.php b/extend/app_alipay/lotusphp_runtime/Logger/Logger.php new file mode 100755 index 0000000..4fc5308 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Logger/Logger.php @@ -0,0 +1,42 @@ + "\t", + "log_file" => "" + ); + + private $fileHandle; + + protected function getFileHandle() + { + if (null === $this->fileHandle) + { + if (empty($this->conf["log_file"])) + { + trigger_error("no log file spcified."); + } + $logDir = dirname($this->conf["log_file"]); + if (!is_dir($logDir)) + { + mkdir($logDir, 0777, true); + } + $this->fileHandle = fopen($this->conf["log_file"], "a"); + } + return $this->fileHandle; + } + + public function log($logData) + { + if ("" == $logData || array() == $logData) + { + return false; + } + if (is_array($logData)) + { + $logData = implode($this->conf["separator"], $logData); + } + $logData = $logData. "\n"; + fwrite($this->getFileHandle(), $logData); + } +} \ No newline at end of file diff --git a/extend/app_alipay/lotusphp_runtime/Lotus.php b/extend/app_alipay/lotusphp_runtime/Lotus.php new file mode 100755 index 0000000..1b3a5fc --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Lotus.php @@ -0,0 +1,157 @@ + + * "app_name" => + * "autoload_dir" => + * ); + */ + public $option; + public $devMode = true; + public $defaultStoreDir; + + protected $proj_dir; + protected $app_dir; + protected $data_dir; + protected $lotusRuntimeDir; + protected $coreCacheHandle; + + public function __construct() + { + $this->lotusRuntimeDir = dirname(__FILE__) . DIRECTORY_SEPARATOR; + } + + public function init() + { + $underMVC = false; + if (isset($this->option["proj_dir"]) && !empty($this->option["proj_dir"])) + { + $this->proj_dir = rtrim($this->option["proj_dir"], '\\/') . '/'; + if (isset($this->option["app_name"]) && !empty($this->option["app_name"])) + { + $this->app_dir = $this->proj_dir . "app/" . $this->option["app_name"] . "/"; + $this->data_dir = $this->proj_dir . "data/" . $this->option["app_name"] . "/"; + $underMVC = true; + } + else + { + trigger_error("Lotus option [app_name] is missing."); + } + } + + /** + * Load core component + */ + require_once $this->lotusRuntimeDir . "Store.php"; + require_once $this->lotusRuntimeDir . "StoreMemory.php"; + require_once $this->lotusRuntimeDir . "StoreFile.php"; + + if ($this->defaultStoreDir) + { + if ($defaultStoreDir = realpath($this->defaultStoreDir)) + { + LtStoreFile::$defaultStoreDir = $defaultStoreDir; + } + else + { + trigger_error("invalid [default store dir]: " . $this->defaultStoreDir); + } + } + if (!$this->devMode) + { + /** + * accelerate LtAutoloader, LtConfig + */ + $this->coreCacheHandle = new LtStoreFile; + $prefix = sprintf("%u", crc32(serialize($this->app_dir))); + $this->coreCacheHandle->prefix = 'Lotus-' . $prefix; + $this->coreCacheHandle->useSerialize = true; + $this->coreCacheHandle->init(); + } + + /** + * Init Autoloader, do this before init all other lotusphp component. + */ + $this->prepareAutoloader(); + + /** + * init Config + */ + $this->prepareConfig(); + + /** + * Run dispatcher when under MVC mode + */ + if ($underMVC) + { + $this->runMVC(); + } + } + + /** + * Autoload all lotus components and user-defined libraries; + */ + protected function prepareAutoloader() + { + require_once $this->lotusRuntimeDir . "Autoloader/Autoloader.php"; + $autoloader = new LtAutoloader; + $autoloader->autoloadPath[] = $this->lotusRuntimeDir; + if (isset($this->option["autoload_dir"])) + { + $autoloader->autoloadPath[] = $this->option["autoload_dir"]; + } + if ($this->proj_dir) + { + is_dir($this->proj_dir . 'lib') && $autoloader->autoloadPath[] = $this->proj_dir . 'lib'; + is_dir($this->app_dir . 'action') && $autoloader->autoloadPath[] = $this->app_dir . 'action'; + is_dir($this->app_dir . 'lib') && $autoloader->autoloadPath[] = $this->app_dir . 'lib'; + } + + if (!$this->devMode) + { + $autoloader->storeHandle = $this->coreCacheHandle; + } + $autoloader->init(); + } + + protected function prepareConfig() + { + $this->configHandle = LtObjectUtil::singleton('LtConfig'); + if (!$this->devMode) + { + $configFile = 'conf/conf.php'; + $this->configHandle->storeHandle = $this->coreCacheHandle; + } + else + { + $configFile = 'conf/conf_dev.php'; + } + $this->configHandle->init(); + if ($this->app_dir && is_file($this->app_dir . $configFile)) + { + $this->configHandle->loadConfigFile($this->app_dir . $configFile); + } + } + + protected function runMVC() + { + $router = LtObjectUtil::singleton('LtRouter'); + $router->init(); + $dispatcher = LtObjectUtil::singleton('LtDispatcher'); + $dispatcher->viewDir = $this->app_dir . 'view/'; + $dispatcher->viewTplDir = $this->data_dir . 'templateView/'; + if (!$this->devMode) + { + $dispatcher->viewTplAutoCompile = false; + } + else + { + $dispatcher->viewTplAutoCompile = true; + } + $dispatcher->dispatchAction($router->module, $router->action); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/MVC/Action.php b/extend/app_alipay/lotusphp_runtime/MVC/Action.php new file mode 100755 index 0000000..aa9405a --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/MVC/Action.php @@ -0,0 +1,236 @@ +constructed = true; + } + + public function executeChain() + { + if (!$this->constructed) + { + //DebugHelper::debug('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR', array('class' => $actionClassName)); + trigger_error('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR'); + } + $this->afterConstruct(); + $validateResult = $this->validateInput(); + if (0 == $validateResult["error_total"]) + { + if ($this->checkPrivilege()) + { + $this->beforeExecute(); + $this->execute(); + } + else + { + $this->code = 403; + $this->message = "Access denied"; + } + } + else + { + $this->code = 407; + $this->message = "Invalid input"; + $this->data['error_messages'] = $validateResult["error_messages"]; + } + $this->writeResponse(); + } + + /** + * Do something after subClass::__construct(). + */ + protected function afterConstruct() + { + + } + + /** + * Validate the data from client + * + * @return array + */ + protected function validateInput() + { + $validateResult = array("error_total" => 0, "error_messages" => array()); + if (!empty($this->dtds) && class_exists('LtValidator')) + { + $validator = new LtValidator; + $validator->init(); + foreach ($this->dtds as $variable => $dtd) + { + $from = isset($dtd->from) ? $dtd->from : 'request'; + + foreach ($dtd->rules as $ruleKey => $ruleValue) + { + if ($ruleValue instanceof ConfigExpression) + { + eval('$_ruleValue = ' . $ruleValue->__toString()); + $dtd->rules[$ruleKey] = $_ruleValue; + } + } + $error_messages = $validator->validate($this->context->$from($variable), $dtd); + if (!empty($error_messages)) + { + $validateResult['error_total'] ++; + $validateResult['error_messages'][$variable] = $error_messages; + } + } + } + return $validateResult; + } + + /** + * Check if current user have privilege to do this + * + * @return boolen + */ + protected function checkPrivilege() + { + $allow = true; + if (!empty($this->roles) && class_exists('LtRbac')) + { + $module = $this->context->uri["module"]; + $action = $this->context->uri["action"]; + $roles = array_merge(array("*"), $this->roles); + $rbac = new LtRbac(); + $rbac->init(); + $allow = $rbac->checkAcl($roles, "$module/$action"); + } + return $allow; + } + + /** + * Do something before subClass::execute(). + */ + protected function beforeExecute() + { + } + + protected function execute() + { + } + + protected function writeResponse() + { + switch ($this->responseType) + { + case 'json': + echo json_encode(array("code" => $this->code, + "message" => $this->message, + "data" => $this->data + )); + exit; // + break; + case 'tpl': + if (null === $this->view) + { + $this->view = new LtTemplateView; + } + $this->view->component = false; // 是否组件 + $this->view->context = $this->context; + $this->view->code = $this->code; + $this->view->message = $this->message; + $this->view->data = $this->data; + $this->view->layoutDir = $this->viewDir . "layout/"; + $this->view->layout = $this->layout; + $this->view->templateDir = $this->viewDir; + $this->view->compiledDir = $this->viewTplDir; + $this->view->autoCompile = $this->viewTplAutoCompile; + if (empty($this->template)) + { + $this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"]; + } + $this->view->template = $this->template; + $this->view->render(); + break; + + case 'html': + case 'wml': + default: + if (null === $this->view) + { + $this->view = new LtView; + } + $this->view->context = $this->context; + $this->view->code = $this->code; + $this->view->message = $this->message; + $this->view->data = $this->data; + $this->view->layoutDir = $this->viewDir . "layout/"; + $this->view->layout = $this->layout; + $this->view->templateDir = $this->viewDir; + if (empty($this->template)) + { + $this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"]; + } + $this->view->template = $this->template; + $this->view->render(); + break; + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/MVC/Component.php b/extend/app_alipay/lotusphp_runtime/MVC/Component.php new file mode 100755 index 0000000..a7b7963 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/MVC/Component.php @@ -0,0 +1,134 @@ +constructed = true; + } + public function executeChain() + { + if (!$this->constructed) + { + //DebugHelper::debug('SUBCLASS_NOT_CALL_PARENT_CONSTRUCTOR', array('class' => $actionClassName)); + } + $this->afterConstruct(); + $this->beforeExecute(); + $this->execute(); + $this->writeResponse(); + } + + protected function afterConstruct() + { + + } + /** + * Do something before subClass::execute(). + */ + protected function beforeExecute() + { + } + + protected function execute() + { + } + + protected function writeResponse() + { + switch ($this->responseType) + { + case 'json': + echo json_encode(array("code" => $this->code, + "message" => $this->message, + "data" => $this->data + )); + exit; + break; + case 'tpl': + if (null === $this->view) + { + $this->view = new LtTemplateView; + } + $this->view->component = true; // 是否组件 + $this->view->context = $this->context; + $this->view->code = $this->code; + $this->view->message = $this->message; + $this->view->data = $this->data; + $this->view->layoutDir = $this->viewDir . "layout/"; + $this->view->layout = $this->layout; + $this->view->templateDir = $this->viewDir . "component/"; + $this->view->compiledDir = $this->viewTplDir . "component/"; + $this->view->autoCompile = $this->viewTplAutoCompile; + if (empty($this->template)) + { + $this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"]; + } + $this->view->template = $this->template; + $this->view->render(); + break; + + case 'html': + case 'wml': + default: + if (null === $this->view) + { + $this->view = new LtView; + } + $this->view->context = $this->context; + $this->view->code = $this->code; + $this->view->message = $this->message; + $this->view->data = $this->data; + $this->view->layoutDir = $this->viewDir . "layout/"; + $this->view->layout = $this->layout; + $this->view->templateDir = $this->viewDir . "component/"; + if (empty($this->template)) + { + $this->template = $this->context->uri["module"] . "-" . $this->context->uri["action"]; + } + $this->view->template = $this->template; + $this->view->render(); + break; + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/MVC/Context.php b/extend/app_alipay/lotusphp_runtime/MVC/Context.php new file mode 100755 index 0000000..179b387 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/MVC/Context.php @@ -0,0 +1,98 @@ + $action)); + trigger_error("{$actionClassName} CLASS NOT FOUND! module={$module} action={$action} classType={$classType}"); + } + else + { + if (!($context instanceof LtContext)) + { + $newContext = new LtContext; + } + else + { + $newContext = clone $context; + } + $newContext->uri['module'] = $module; + $newContext->uri[strtolower($classType)] = $action; + $actionInstance = new $actionClassName(); + $actionInstance->context = $newContext; + $actionInstance->viewDir = $this->viewDir; + $actionInstance->viewTplDir = $this->viewTplDir; // 模板编译目录 + $actionInstance->viewTplAutoCompile = $this->viewTplAutoCompile; + $actionInstance->executeChain(); + $this->data = $actionInstance->data; + } + } + + /** + * Disptach the module/action calling. + * + * @param $module string + * @param $action string + * @return void + * @todo allow one action dispatch another action + */ + public function dispatchAction($module, $action, $context = null) + { + $this->_dispatch($module, $action, $context); + } + + /** + * Disptach the module/component calling. + * + * @param $module string + * @param $component string + * @param $data mixed + * @return void + */ + public function dispatchComponent($module, $component, $context = null) + { + $cloneOfContext = clone $context; + $this->_dispatch($module, $component, $cloneOfContext, "Component"); + } +} diff --git a/extend/app_alipay/lotusphp_runtime/MVC/TemplateView.php b/extend/app_alipay/lotusphp_runtime/MVC/TemplateView.php new file mode 100755 index 0000000..cf97cd7 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/MVC/TemplateView.php @@ -0,0 +1,385 @@ +autoCompile = true; + $this->component = false; + } + + public function render() + { + if (empty($this->compiledDir)) + { + $this->compiledDir = dirname($this->templateDir) . "/viewTpl/"; + } + if (!empty($this->layout)) + { + include $this->template(true); + } + else if ($this->component) + { + return; // 模板内使用{component module action}合并文件 + } + else + { + include $this->template(); + } + } + + /** + * 返回编译后的模板路径, 如果不存在则编译生成并返回路径. + * 如果文件存在且允许自动编译, 则对比模板文件和编译后的文件修改时间 + * 当修改模板后自支重新编译 + * + * @param bool $islayout 是否使用布局 + * @return string 返回编译后的模板路径 + */ + public function template($islayout = false) + { + $this->layoutDir = rtrim($this->layoutDir, '\\/') . '/'; + $this->compiledDir = rtrim($this->compiledDir, '\\/') . '/'; + $this->templateDir = rtrim($this->templateDir, '\\/') . '/'; + + if ($islayout) + { + $tplfile = $this->layoutDir . $this->layout . '.php'; + $objfile = $this->compiledDir . 'layout/' . $this->layout . '@' . $this->template . '.php'; + } + else + { + $tplfile = $this->templateDir . $this->template . '.php'; + $objfile = $this->compiledDir . $this->template . '.php'; + } + if (is_file($objfile)) + { + if ($this->autoCompile) + { + $iscompile = true; + $tpl_include_files = include($objfile); + $last_modified_time = array(); + foreach($tpl_include_files as $f) + { + $last_modified_time[] = filemtime($f); + } + if (filemtime($objfile) == max($last_modified_time)) + { + $iscompile = false; + } + } + else + { + $iscompile = false; + } + } + else + { + // 目标文件不存在,编译模板 + $iscompile = true; + } + if ($iscompile) + { + $this->tpl_include_files[] = $objfile; + $this->tpl_include_files[] = $tplfile; + $dir = pathinfo($objfile, PATHINFO_DIRNAME); + if (!is_dir($dir)) + { + if (!mkdir($dir, 0777, true)) + { + trigger_error("Can not create $dir"); + } + } + $str = file_get_contents($tplfile); + if (!$str) + { + trigger_error('Template file Not found or have no access!', E_USER_ERROR); + } + $str = $this->parse($str); + if ($this->autoCompile) + { + $prefix = "tpl_include_files), true) . ";?>"; + $prefix = preg_replace("/([\r\n])+/", "\r\n", $prefix); + $postfix = "\r\n\r\n"; + } + else + { + $prefix = ''; + $postfix = ''; + } + $str = $prefix . $str . $postfix; + if (!file_put_contents($objfile, $str)) + { + if (file_put_contents($objfile . '.tmp', $str)) + { + copy($objfile . '.tmp', $objfile); // win下不能重命名已经存在的文件 + unlink($objfile . '.tmp'); + } + } + @chmod($objfile,0777); + } + return $objfile; + } + + /** + * 解析{}内字符串,替换php代码 + * + * @param string $str + * @return string + */ + protected function parse($str) + { + $str = $this->removeComments($str); + $str = $this->parseIncludeComponent($str); + // 回车 换行 + $str = str_replace("{CR}", "", $str); + $str = str_replace("{LF}", "", $str); + // if else elseif + $str = preg_replace("/\{if\s+(.+?)\}/", "", $str); + $str = preg_replace("/\{else\}/", "", $str); + $str = preg_replace("/\{elseif\s+(.+?)\}/", "", $str); + $str = preg_replace("/\{\/if\}/", "", $str); + // loop + $str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('')", $str); + $str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('\\3) { ?>')", $str); + $str = preg_replace("/\{\/loop\}/", "", $str); + // url生成 + $str = preg_replace("/\{url\(([^}]+)\)\}/", "generate(\\1);?>", $str); + + // 函数 + $str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\s*\(([^{}]*)\))\}/", "", $str); + $str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "", $str); + // 变量 + /** + * 放弃支持$name.name.name + * $str = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "", $str); + */ + // 其它变量 + $str = preg_replace("/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "", $str); + $str = preg_replace("/\{(\\$[a-zA-Z0-9_\.\[\]\'\"\$\x7f-\xff]+)\}/e", "\$this->addquote('')", $str); + // 类->属性 类->方法 + $str = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff][+\-\>\$\'\"\,\[\]\(\)a-zA-Z0-9_\x7f-\xff]+)\}/es", "\$this->addquote('')", $str); + // 常量 + $str = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/", "", $str); + // 静态变量 + $str = preg_replace("/\{([a-zA-Z0-9_]*::?\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "", $str); + $str = preg_replace("/\{([a-zA-Z0-9_]*::?\\\$[a-zA-Z0-9_\.\[\]\'\"\$\x7f-\xff]+)\}/e", "\$this->addquote('')", $str); + + // 合并相邻php标记 + $str = preg_replace("/\?\>\s*\<\?php[\r\n\t ]*/", "", $str); + /** + * 删除空行 + * Dos和windows采用回车+换行CR/LF表示下一行, + * 而UNIX/Linux采用换行符LF表示下一行, + * 苹果机(MAC OS系统)则采用回车符CR表示下一行. + * CR用符号 '\r'表示, 十进制ASCII代码是13, 十六进制代码为0x0D; + * LF使用'\n'符号表示, ASCII代码是10, 十六制为0x0A. + * 所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示, + * 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示. + * + * 这里统一替换成windows平台回车换行, 第二参数考虑 \\1 保持原有 + */ + $str = preg_replace("/([\r\n])+/", "\r\n", $str); + // 删除第一行 + $str = preg_replace("/^[\r\n]+/", "", $str); + // write + $str = trim($str); + return $str; + } + /** + * 变量加上单引号 + * 如果是数字就不加单引号, 如果已经加上单引号或者双引号保持不变 + */ + protected function addquote($var) + { + preg_match_all("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", $var, $vars); + foreach($vars[1] as $k => $v) + { + if (is_numeric($v)) + { + $var = str_replace($vars[0][$k], "[$v]", $var); + } + else + { + $var = str_replace($vars[0][$k], "['$v']", $var); + } + } + return str_replace("\\\"", "\"", $var); + } + + /** + * 模板中第一行可以写exit函数防止浏览 + * 删除行首尾空白, html javascript css注释 + */ + protected function removeComments($str, $clear = false) + { + $str = str_replace(array('', ''), array('', ''), $str); + // 删除行首尾空白 + $str = preg_replace("/([\r\n]+)[\t ]+/s", "\\1", $str); + $str = preg_replace("/[\t ]+([\r\n]+)/s", "\\1", $str); + // 删除 {} 前后的 html 注释 + $str = preg_replace("/\<\!\-\-\s*\{(.+?)\}\s*\-\-\>/s", "{\\1}", $str); + $str = preg_replace("/\<\!\-\-\s*\-\-\>/s", "", $str); + // 删除 html注释 存在 < { 就不删除 + $str = preg_replace("/\<\!\-\-\s*[^\<\{]*\s*\-\-\>/s", "", $str); + if ($clear) + { + $str = $this->clear($str); + } + return $str; + } + /** + * 清除一部分 style script内的注释 + * 多行注释内部存在 / 字符就不会清除 + */ + protected function clear($str) + { + preg_match_all("|]*>(.*)|Usi", $str, $tvar); + foreach($tvar[0] as $k => $v) + { + // 删除单行注释 + $v = preg_replace("/\/\/\s*[a-zA-Z0-9_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/", "", $v); + // 删除多行注释 + $v = preg_replace("/\/\*[^\/]*\*\//s", "", $v); + $str = str_replace($tvar[0][$k], $v, $str); + } + preg_match_all("|]*>(.*)|Usi", $str, $tvar); + foreach($tvar[0] as $k => $v) + { + // 删除多行注释 + $v = preg_replace("/\/\*[^\/]*\*\//s", "", $v); + $str = str_replace($tvar[0][$k], $v, $str); + } + return $str; + } + /** + * + * @todo 注意相互引用的模板嵌套会导致死循环 + */ + protected function parseIncludeComponent($str) + { + $count_include_component = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar); + $count_include_component += preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar); + unset($tvar); + while ($count_include_component > 0) + { + $str = $this->parseInclude($str); + $str = $this->parseComponent($str); + $count_include_component = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar); + $count_include_component += preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar); + unset($tvar); + } + $str = $this->removeComments($str); + return $str; + } + /** + * 解析多个{include path/file}合并成一个文件 + * + * @example {include 'debug_info'} + * {include 'debug_info.php'} + * {include "debug_info"} + * {include "debug_info.php"} + * {include $this->templateDir . $this->template} + */ + private function parseInclude($str) + { + $countSubTpl = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar); + while ($countSubTpl > 0) + { + foreach($tvar[1] as $k => $subfile) + { + eval("\$subfile = $subfile;"); + if (is_file($subfile)) + { + $findfile = $subfile; + } + else if (is_file($subfile . '.php')) + { + $findfile = $subfile . '.php'; + } + else if (is_file($this->templateDir . $subfile)) + { + $findfile = $this->templateDir . $subfile; + } + else if (is_file($this->templateDir . $subfile . '.php')) + { + $findfile = $this->templateDir . $subfile . '.php'; + } + else + { + $findfile = ''; + } + + if (!empty($findfile)) + { + $subTpl = file_get_contents($findfile); + $this->tpl_include_files[] = $findfile; + } + else + { + // 找不到文件 + $subTpl = 'SubTemplate not found:' . $subfile; + } + $str = str_replace($tvar[0][$k], $subTpl, $str); + } + $countSubTpl = preg_match_all("/\{include\s+(.+)\}/", $str, $tvar); + } + return $str; + } + + /** + * 解析多个{component module action}合并成一个文件 + */ + private function parseComponent($str) + { + $countCom = preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar); + while ($countCom > 0) + { + $i = 0; + while ($i < $countCom) + { + $comfile = $this->templateDir . "component/" . $tvar[1][$i] . '-' . $tvar[2][$i] . '.php'; + if (is_file($comfile)) + { + $subTpl = file_get_contents($comfile); + $this->tpl_include_files[] = $comfile; + } + else + { + $subTpl = 'SubTemplate not found:' . $comfile; + } +//////////////////////////////////////////////////////////////////////////// +$module = $tvar[1][$i]; +$action = $tvar[2][$i]; +$subTpl = "dispatchComponent('$module', '$action', \$this->context); +\$comdata = \$dispatcher->data; +unset(\$dispatcher); +?> +" . $subTpl; +//////////////////////////////////////////////////////////////////////////// + $str = str_replace($tvar[0][$i], $subTpl, $str); + $i++; + } + $countCom = preg_match_all("/\{component\s+([a-zA-Z0-9\.\-_]+)\s+([a-zA-Z0-9\.\-_]+)\}/", $str, $tvar); + } + return $str; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/MVC/View.php b/extend/app_alipay/lotusphp_runtime/MVC/View.php new file mode 100755 index 0000000..84beb4c --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/MVC/View.php @@ -0,0 +1,26 @@ +layout)) + { + include($this->layoutDir . $this->layout . '.php'); + } + else + { + include($this->templateDir . $this->template . '.php'); + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/ObjectUtil/ObjectUtil.php b/extend/app_alipay/lotusphp_runtime/ObjectUtil/ObjectUtil.php new file mode 100755 index 0000000..5f08e8e --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/ObjectUtil/ObjectUtil.php @@ -0,0 +1,33 @@ +init(); + } + self::$instances[$key] = $newInstance; + return $newInstance; + } + else + { + return false; + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Pagination/Pagination.php b/extend/app_alipay/lotusphp_runtime/Pagination/Pagination.php new file mode 100755 index 0000000..3a28cf9 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Pagination/Pagination.php @@ -0,0 +1,226 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->conf = $this->configHandle->get("pagination.pager"); + if (empty($this->conf)) + { + $this->conf['per_page'] = 25; //每个页面中希望展示的项目数量 + $this->conf['num_links_show'] = 9; //数字链接显示数量 + $this->conf['num_point_start_end'] = 2; //“点”前边和后边的链接数量 + $this->conf['show_first'] = true; + $this->conf['show_prev'] = true; + $this->conf['show_next'] = true; + $this->conf['show_last'] = true; + $this->conf['show_goto'] = false; + $this->conf['show_info'] = false; + $this->conf['show_point'] = true; + $this->conf['show_empty_button'] = false; + + $this->conf['first_text'] = 'First'; + $this->conf['prev_text'] = 'Prev'; + $this->conf['next_text'] = 'Next'; + $this->conf['last_text'] = 'Last'; + $this->conf['point_text'] = '...'; + + $this->conf['full_tag_open'] = '
'; + $this->conf['full_tag_close'] = '
'; + $this->conf['num_tag_open'] = ''; + $this->conf['num_tag_close'] = ''; + $this->conf['link_tag_open'] = ''; + $this->conf['link_tag_close'] = ''; + $this->conf['link_tag_cur_open'] = ''; + $this->conf['link_tag_cur_close'] = ''; + $this->conf['button_tag_open'] = ''; + $this->conf['button_tag_close'] = ''; + $this->conf['button_tag_empty_open'] = ''; + $this->conf['button_tag_empty_close'] = ''; + $this->conf['point_tag_open'] = ''; + $this->conf['point_tag_close'] = ''; + } + } + + /** + * + * @param $page int 当前页 + * @param $count int 这个数值是你查询数据库得到的数据总量 + * @param $url string 字串中使用 :page 表示页参数 不在意位置 如/a/:page/c/e + */ + public function pager($page, $count, $url) + { + $per_page = empty($this->conf['per_page']) ? 25 : $this->conf['per_page']; + $pagecount = ceil($count / $per_page); + $pager = $this->renderPager($page, $pagecount, $url); + if ($this->conf['show_goto']) + { + $pager .= $this->renderButton('goto', $page, $pagecount, $url); + } + if ($this->conf['show_info']) + { + $pager .= $this->renderButton('info', $page, $pagecount, $url); + } + return $this->conf['full_tag_open'] . $pager . $this->conf['full_tag_close']; + } + + /** + * + * @param $pagenumber int 当前页 + * @param $pagecount int 总页数 + * @return string + */ + public function renderPager($pagenumber, $pagecount, $baseurl = '?page=:page') + { + $baseurl = urldecode($baseurl); + $pager = $this->conf['num_tag_open']; + + $pager .= $this->renderButton('first', $pagenumber, $pagecount, $baseurl); + $pager .= $this->renderButton('prev', $pagenumber, $pagecount, $baseurl); + + $startPoint = 1; + $endPoint = $this->conf['num_links_show']; + $num_links = ceil($this->conf['num_links_show'] / 2) - 1; + if ($pagenumber > $num_links) + { + $startPoint = $pagenumber - $num_links; + $endPoint = $pagenumber + $num_links; + } + + if ($endPoint > $pagecount) + { + $startPoint = $pagecount + 1 - $this->conf['num_links_show']; + $endPoint = $pagecount; + } + + if ($startPoint < 1) + { + $startPoint = 1; + } + + $currentButton = ''; + if ($this->conf['show_point']) + { + for($page = 1; $page < $startPoint; $page++) + { + $url = str_replace(':page', $page, $baseurl); + if ($page > $this->conf['num_point_start_end']) + { + $currentButton .= $this->conf['point_tag_open'] . $this->conf['point_text'] . $this->conf['point_tag_close']; + break; + } + $currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close']; + } + } + for ($page = $startPoint; $page <= $endPoint; $page++) + { + $url = str_replace(':page', $page, $baseurl); + if ($page == $pagenumber) + { + $currentButton .= $this->conf['link_tag_cur_open'] . $page . $this->conf['link_tag_cur_close']; + } + else + { + $currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close']; + } + } + if ($this->conf['show_point']) + { + $page = $pagecount - $this->conf['num_point_start_end']; + if ($page > $endPoint) + { + $currentButton .= $this->conf['point_tag_open'] . $this->conf['point_text'] . $this->conf['point_tag_close']; + } + + for($page += 1; $page >= $endPoint && $page <= $pagecount; $page++) + { + if ($page == $endPoint) continue; + $url = str_replace(':page', $page, $baseurl); + $currentButton .= str_replace(':url', $url, $this->conf['link_tag_open']) . $page . $this->conf['link_tag_close']; + } + } + $pager .= $currentButton; + $pager .= $this->renderButton('next', $pagenumber, $pagecount, $baseurl); + $pager .= $this->renderButton('last', $pagenumber, $pagecount, $baseurl); + $pager .= $this->conf['num_tag_close']; + + return $pager; + } + + /** + * + * @param $buttonLabel string 显示文字 + * @param $pagenumber int 当前页 + * @param $pagecount int 总页数 + * @return string + */ + public function renderButton($buttonLabel, $pagenumber, $pagecount, $baseurl = '?page=:page') + { + $baseurl = urldecode($baseurl); + $destPage = 1; + if ('goto' == $buttonLabel) + { + $button = "goto "; + return $button; + } + if ('info' == $buttonLabel) + { + $button = " $pagenumber/$pagecount "; + return $button; + } + switch ($buttonLabel) + { + case "first": + $destPage = 1; + $bottenText = $this->conf['first_text']; + break; + case "prev": + $destPage = $pagenumber - 1; + $bottenText = $this->conf['prev_text']; + break; + case "next": + $destPage = $pagenumber + 1; + $bottenText = $this->conf['next_text']; + break; + case "last": + $destPage = $pagecount; + $bottenText = $this->conf['last_text']; + break; + } + $url = str_replace(':page', $destPage, $baseurl); + $button = str_replace(':url', $url, $this->conf['button_tag_open']) . $bottenText . $this->conf['button_tag_close']; + + if ($buttonLabel == "first" || $buttonLabel == "prev") + { + if ($pagenumber <= 1) + { + $button = $this->conf['show_empty_button'] ? $this->conf['button_tag_empty_open'] . $bottenText . $this->conf['button_tag_empty_close'] : ''; + } + } + else + { + if ($pagenumber >= $pagecount) + { + $button = $this->conf['show_empty_button'] ? $this->conf['button_tag_empty_open'] . $bottenText . $this->conf['button_tag_empty_close'] : ''; + } + } + return $button; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/RBAC/Rbac.php b/extend/app_alipay/lotusphp_runtime/RBAC/Rbac.php new file mode 100755 index 0000000..0c09a10 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/RBAC/Rbac.php @@ -0,0 +1,87 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->acl = $this->configHandle->get('rbac.acl'); + } + + public function checkAcl($roles, $resource) + { + $allow = false; + // deny priority + foreach (array("allow", "deny") as $operation) + { + foreach($roles as $role) + { + if (isset($this->acl[$operation][$role])) + { + // everyone * + if (in_array($resource, $this->acl[$operation]['*'])) + { + $allow = "allow" == $operation ? true : false; + break; + } + if (in_array($resource, $this->acl[$operation][$role])) + { + $allow = "allow" == $operation ? true : false; + break; + } + else + { + $res = explode('/', trim($resource, '/')); + for ($i = count($res)-1; $i >= 0; $i--) + { + $res[$i] = '*'; + $tmp = implode('/', $res); + if (in_array($tmp, $this->acl[$operation][$role])) + { + $allow = "allow" == $operation ? true : false; + break; + } + unset($res[$i]); + } + } + } + } + } + return $allow; + } +/* + private function __set($p,$v) + { + $this->$p = $v; + } + + private function __get($p) + { + if(isset($this->$p)) + { + return($this->$p); + } + else + { + return(NULL); + } + } +*/ +} diff --git a/extend/app_alipay/lotusphp_runtime/Router/Router.php b/extend/app_alipay/lotusphp_runtime/Router/Router.php new file mode 100755 index 0000000..096d03c --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Router/Router.php @@ -0,0 +1,194 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil")) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->routingTable = $this->configHandle->get("router.routing_table"); + if (empty($this->routingTable)) + { + $this->routingTable = array('pattern' => ":module/:action/*", + 'default' => array('module' => 'default', 'action' => 'index'), + 'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+', + 'action' => '[a-zA-Z0-9\.\-_]+' + ), + 'varprefix' => ':', + 'delimiter' => '/', + 'postfix' => '', + 'protocol' => 'PATH_INFO', // REWRITE STANDARD + ); + } + + $delimiter = $this->routingTable['delimiter']; + $postfix = $this->routingTable['postfix']; + $protocol = strtoupper($this->routingTable['protocol']); + $module = ''; + $action = ''; + $params = array(); + // HTTP HTTPS + if (isset($_SERVER['SERVER_PROTOCOL'])) + { + if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO'])) + { + // 忽略后缀 + $url = rtrim($_SERVER['PATH_INFO'], "$postfix"); + $url = explode($delimiter, trim($url, "/")); + } + else if (isset($_SERVER['REQUEST_URI'])) + { + if ('REWRITE' == $protocol) + { + if (0 == strcmp($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME'])) + { + $url = array(); + } + else + { + $url = substr($_SERVER['REQUEST_URI'], strlen(pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME))); + $url = rtrim($url, "$postfix"); + $url = explode($delimiter, trim($url, "/")); + } + } + else if ('PATH_INFO' == $protocol) + { + $url = substr($_SERVER['REQUEST_URI'], strlen($_SERVER['SCRIPT_NAME'])); + $url = rtrim($url, "$postfix"); + $url = explode($delimiter, trim($url, "/")); + } + else //STANDARD + { + $url = array(); + foreach($_GET as $v) + { + $url[] = $v; + } + } + } + else + { + $url = array(); + foreach($_GET as $v) + { + $url[] = $v; + } + } + $params = $this->matchingRoutingTable($url); + $module = $params['module']; + $action = $params['action']; + } + else + { + // CLI + $i = 0; + while (isset($_SERVER['argv'][$i]) && isset($_SERVER['argv'][$i + 1])) + { + if (("-m" == $_SERVER['argv'][$i] || "--module" == $_SERVER['argv'][$i])) + { + $module = $_SERVER['argv'][$i + 1]; + } + else if (("-a" == $_SERVER['argv'][$i] || "--action" == $_SERVER['argv'][$i])) + { + $action = $_SERVER['argv'][$i + 1]; + } + else + { + $key = $_SERVER['argv'][$i]; + $params[$key] = $_SERVER['argv'][$i + 1]; + } + $i = $i + 2; + } + } + // 如果$_GET中不存在配置的变量则添加 + foreach($params as $k => $v) + { + !isset($_GET[$k]) && $_GET[$k] = $v; + } + $this->module = $module; + $this->action = $action; + } + + /** + * url 匹配路由表 + * + * @param $ [string|array] $url + * @return + * @todo 修复导致$_GET多出属性的BUG + * @todo 如果是rewrite或者path_info模式,可能需要unset module和action两个$_GET变量 + */ + public function matchingRoutingTable($url) + { + $ret = $this->routingTable['default']; //初始化返回值为路由默认值 + $reqs = $this->routingTable['reqs']; + $delimiter = $this->routingTable['delimiter']; + $varprefix = $this->routingTable['varprefix']; + $postfix = $this->routingTable['postfix']; + $pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter)); + + /** + * 预处理url + */ + if (is_string($url)) + { + $url = rtrim($url, $postfix); //忽略后缀 + $url = explode($delimiter, trim($url, $delimiter)); + } + + foreach($pattern as $k => $v) + { + if ($v[0] == $varprefix) + { + // 变量 + $varname = substr($v, 1); + // 匹配变量 + if (isset($url[$k])) + { + if (isset($reqs[$varname])) + { + $regex = "/^{$reqs[$varname]}\$/i"; + if (preg_match($regex, $url[$k])) + { + $ret[$varname] = $url[$k]; + } + } + } + } + else if ($v[0] == '*') + { + // 通配符 + $pos = $k; + while (isset($url[$pos]) && isset($url[$pos + 1])) + { + $ret[$url[$pos ++]] = urldecode($url[$pos]); + $pos++; + } + } + else + { + // 静态 + } + } + return $ret; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Session/Session.php b/extend/app_alipay/lotusphp_runtime/Session/Session.php new file mode 100755 index 0000000..10e9869 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Session/Session.php @@ -0,0 +1,56 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + if(!$sessionSavePath = $this->configHandle->get("session.save_path")) + { + $sessionSavePath = '/tmp/Lotus/session/'; + } + if (!is_object($this->storeHandle)) + { + ini_set('session.save_handler', 'files'); + if (!is_dir($sessionSavePath)) + { + if (!@mkdir($sessionSavePath, 0777, true)) + { + trigger_error("Can not create $sessionSavePath"); + } + } + session_save_path($sessionSavePath); + } + else + { + $this->storeHandle->conf = $this->configHandle->get("session.conf"); + $this->storeHandle->init(); + session_set_save_handler( + array(&$this->storeHandle, 'open'), + array(&$this->storeHandle, 'close'), + array(&$this->storeHandle, 'read'), + array(&$this->storeHandle, 'write'), + array(&$this->storeHandle, 'destroy'), + array(&$this->storeHandle, 'gc') + ); + } + //session_start(); + //header("Cache-control: private"); // to overcome/fix a bug in IE 6.x + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Session/SessionStore b/extend/app_alipay/lotusphp_runtime/Session/SessionStore new file mode 100755 index 0000000..4c08da2 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Session/SessionStore @@ -0,0 +1,10 @@ +conf['gc_maxlifetime'])) + { + $this->lifeTime = $this->conf['gc_maxlifetime']; + } + else + { + $this->lifeTime = get_cfg_var("session.gc_maxlifetime"); + } + if (isset($this->conf['table_name'])) + { + $this->tableName = $this->conf['table_name']; + } + else + { + $this->tableName = 'lotus_session'; + } + if (isset($this->conf['db_name'])) + { + $this->dbName = $this->conf['db_name']; + } + else + { + $this->dbName = '/tmp/Lotus/session/session_sqlite2.db'; + } + + if (!$this->dbHandle = sqlite_open($this->dbName, 0666)) + { + trigger_error('session sqlite db error'); + return false; + } + return true; + } + + public function open($savePath, $sessName) + { + return true; + } + + public function close() + { + $this->gc($this->lifeTime); + return @sqlite_close($this->dbHandle); + } + + public function read($sessID) + { + $res = sqlite_query("SELECT session_data AS d FROM $this->tableName + WHERE session_id = '$sessID' + AND session_expires > " . time(), $this->dbHandle); + if ($row = sqlite_fetch_array($res, SQLITE_ASSOC)) + { + return $row['d']; + } + else + { + return ""; + } + } + + public function write($sessID, $sessData) + { + $newExp = time() + $this->lifeTime; + $res = sqlite_query("SELECT * FROM $this->tableName + WHERE session_id = '$sessID'", $this->dbHandle); + if (sqlite_num_rows($res)) + { + sqlite_exec("UPDATE $this->tableName + SET session_expires = '$newExp', + session_data = '$sessData' + WHERE session_id = '$sessID'", $this->dbHandle); + if (sqlite_changes($this->dbHandle)) + { + return true; + } + } + else + { + sqlite_exec("INSERT INTO $this->tableName ( + session_id, + session_expires, + session_data) + VALUES( + '$sessID', + '$newExp', + '$sessData')", $this->dbHandle); + if (sqlite_changes($this->dbHandle)) + { + return true; + } + } + return false; + } + + public function destroy($sessID) + { + sqlite_exec("DELETE FROM $this->tableName WHERE session_id = '$sessID'", $this->dbHandle); + if (sqlite_changes($this->dbHandle)) + { + return true; + } + return false; + } + + public function gc($sessMaxLifeTime) + { + sqlite_exec("DELETE FROM $this->tableName WHERE session_expires < " . time(), $this->dbHandle); + return sqlite_changes($this->dbHandle); + } + + public function runOnce() + { + $sql = "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' AND name='" . $this->tableName . "'"; + $res = sqlite_query($sql, $this->dbHandle); + $row = sqlite_fetch_array($res, SQLITE_ASSOC); + if (empty($row)) + { + $sql = "CREATE TABLE $this->tableName ( + [session_id] VARCHAR(255) NOT NULL PRIMARY KEY, + [session_expires] INTEGER DEFAULT '0' NOT NULL, + [session_data] TEXT NULL + )"; + return sqlite_exec($sql, $this->dbHandle); + } + return false; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Store.php b/extend/app_alipay/lotusphp_runtime/Store.php new file mode 100755 index 0000000..e24b4c8 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Store.php @@ -0,0 +1,8 @@ +storeDir) + { + $this->storeDir = self::$defaultStoreDir; + } + $this->storeDir = str_replace('\\', '/', $this->storeDir); + $this->storeDir = rtrim($this->storeDir, '\\/') . '/'; + } + + /** + * 当key存在时: + * 如果没有过期, 不更新值, 返回 false + * 如果已经过期, 更新值, 返回 true + * + * @return bool + */ + public function add($key, $value) + { + $file = $this->getFilePath($key); + $cachePath = pathinfo($file, PATHINFO_DIRNAME); + if (!is_dir($cachePath)) + { + if (!@mkdir($cachePath, 0777, true)) + { + trigger_error("Can not create $cachePath"); + } + } + if (is_file($file)) + { + return false; + } + if ($this->useSerialize) + { + $value = serialize($value); + } + $length = file_put_contents($file, '' . $value); + return $length > 0 ? true : false; + } + + /** + * 删除不存在的key返回false + * + * @return bool + */ + public function del($key) + { + $file = $this->getFilePath($key); + if (!is_file($file)) + { + return false; + } + else + { + return @unlink($file); + } + } + + /** + * 取不存在的key返回false + * 已经过期返回false + * + * @return 成功返回数据,失败返回false + */ + public function get($key) + { + $file = $this->getFilePath($key); + if (!is_file($file)) + { + return false; + } + $str = file_get_contents($file); + $value = substr($str, 13); + if ($this->useSerialize) + { + $value = unserialize($value); + } + return $value; + } + + /** + * key不存在 返回false + * 不管有没有过期,都更新数据 + * + * @return bool + */ + public function update($key, $value) + { + $file = $this->getFilePath($key); + if (!is_file($file)) + { + return false; + } + else + { + if ($this->useSerialize) + { + $value = serialize($value); + } + $length = file_put_contents($file, '' . $value); + return $length > 0 ? true : false; + } + } + + public function getFilePath($key) + { + $token = md5($key); + return $this->storeDir . + $this->prefix . '/' . + substr($token, 0, 2) .'/' . + substr($token, 2, 2) . '/' . + $token . '.php'; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/StoreMemory.php b/extend/app_alipay/lotusphp_runtime/StoreMemory.php new file mode 100755 index 0000000..4e8328a --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/StoreMemory.php @@ -0,0 +1,54 @@ +stack[$key])) + { + return false; + } + else + { + $this->stack[$key] = $value; + return true; + } + } + + public function del($key) + { + if (isset($this->stack[$key])) + { + unset($this->stack[$key]); + return true; + } + else + { + return false; + } + } + + public function get($key) + { + return isset($this->stack[$key]) ? $this->stack[$key] : false; + } + + /** + * key不存在返回false + * + * @return bool + */ + public function update($key, $value) + { + if (!isset($this->stack[$key])) + { + return false; + } + else + { + $this->stack[$key] = $value; + return true; + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Url/Url.php b/extend/app_alipay/lotusphp_runtime/Url/Url.php new file mode 100755 index 0000000..35eae00 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Url/Url.php @@ -0,0 +1,142 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + public function init() + { + $this->routingTable = $this->configHandle->get("router.routing_table"); + if (empty($this->routingTable)) + { + $this->routingTable = array('pattern' => ":module/:action/*", + 'default' => array('module' => 'default', 'action' => 'index'), + 'reqs' => array('module' => '[a-zA-Z0-9\.\-_]+', + 'action' => '[a-zA-Z0-9\.\-_]+' + ), + 'varprefix' => ':', + 'delimiter' => '/', + 'postfix' => '', + 'protocol' => 'PATH_INFO', // REWRITE STANDARD + ); + } + + $protocol = strtoupper($this->routingTable['protocol']); + if ('REWRITE' == $protocol) + { + $this->baseUrl = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME) . '/'; + } + else if ('STANDARD' == $protocol) + { + $this->baseUrl = $_SERVER['PHP_SELF']; + } + else + { + $this->baseUrl = ''; + } + } + + public function generate($module, $action, $args = array()) + { + $args = array_merge(array('module' => $module, 'action' => $action), $args); + $url = ''; + // $url = $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://'; + // $url .= $_SERVER['HTTP_HOST']; + // $url .= $_SERVER['SERVER_PORT'] == '80' ? '' : ':'.$_SERVER['SERVER_PORT']; + $url .= $this->baseUrl; + $url .= $this->reverseMatchingRoutingTable($args); + return $url; + } + + /** + * 将变量反向匹配路由表, 返回匹配后的url + * + * @param array $params + * @return string + */ + public function reverseMatchingRoutingTable($args) + { + $ret = $this->routingTable['pattern']; + $default = $this->routingTable['default']; + $reqs = $this->routingTable['reqs']; + $delimiter = $this->routingTable['delimiter']; + $varprefix = $this->routingTable['varprefix']; + $postfix = $this->routingTable['postfix']; + $protocol = strtoupper($this->routingTable['protocol']); + if ('STANDARD' == $protocol) + { + return '?' . http_build_query($args, '', '&'); + } + $pattern = explode($delimiter, trim($this->routingTable['pattern'], $delimiter)); + + foreach($pattern as $k => $v) + { + if ($v[0] == $varprefix) + { + // 变量 + $varname = substr($v, 1); + // 匹配变量 + if (isset($args[$varname])) + { + $regex = "/^{$reqs[$varname]}\$/i"; + if (preg_match($regex, $args[$varname])) + { + $ret = str_replace($v, $args[$varname], $ret); + unset($args[$varname]); + } + } + else if (isset($default[$varname])) + { + $ret = str_replace($v, $default[$varname], $ret); + } + } + else if ($v[0] == '*') + { + // 通配符 + $tmp = ''; + foreach($args as $key => $value) + { + if (!isset($default[$key])) + { + $tmp .= $key . $delimiter . rawurlencode($value) . $delimiter; + } + } + $tmp = rtrim($tmp, $delimiter); + $ret = str_replace($v, $tmp, $ret); + $ret = rtrim($ret, $delimiter); + } + else + { + // 静态 + } + } + if ('REWRITE' == $protocol) + { + $ret = $ret . $postfix; + } + else if ('PATH_INFO' == $protocol) + { + $ret = $_SERVER['SCRIPT_NAME'] . $delimiter . $ret . $postfix; + } + else + { + $ret = $ret . $postfix; + } + return $ret; + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Validator/Validator.php b/extend/app_alipay/lotusphp_runtime/Validator/Validator.php new file mode 100755 index 0000000..839afe4 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Validator/Validator.php @@ -0,0 +1,174 @@ +configHandle instanceof LtConfig) + { + if (class_exists("LtObjectUtil", false)) + { + $this->configHandle = LtObjectUtil::singleton("LtConfig"); + } + else + { + $this->configHandle = new LtConfig; + } + } + } + + public function init() + { + $this->errorMessages = $this->configHandle->get('validator.error_messages'); + } + + /** + * Validate an element + * + * @param mixed $value + * @param array $dtd + * @return array + */ + public function validate($value, $dtd) + { + $errorMessages = array(); + $label = $dtd->label; + + if (is_array($dtd->rules) && count($dtd->rules)) + { + $messages = isset($dtd->messages) ? $dtd->messages : array(); + foreach ($dtd->rules as $key => $val) + { + // callback_user_function + if ('callback_' == substr($key, 0, 9)) + { + $method = substr($key, 9); + // 定义了过程函数 + if (function_exists($method)) + { + if (!$method($value, $dtd->rules[$key])) + { + if (isset($this->errorMessages[$key])) + { + $messages[$key] = $this->errorMessages[$key]; + } + else + { + $messages[$key] = "validator.error_messages[$key] empty"; + } + $errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]); + } + continue; + } + // 定义了类方法 + $rc = new ReflectionClass($val); + if ($rc->hasMethod($method)) + { + $rcMethod = $rc->getMethod($method); + if ($rcMethod->isStatic()) + { + $ret = $rcMethod->invoke(null, $value, $dtd->rules[$key]); + } + else + { + // 非静态方法需要一个实例 有待考虑单例 + $rcInstance = $rc->newInstance(); + $ret = $rcMethod->invoke($rcInstance, $value, $dtd->rules[$key]); + } + if (!$ret) + { + if (isset($this->errorMessages[$key])) + { + $messages[$key] = $this->errorMessages[$key]; + } + else + { + $messages[$key] = "validator.error_messages[$key] empty"; + } + $errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]); + } + continue; + } + continue; + } + // end callback_user_function + $validateFunction = '_' . $key; + if ((is_bool($dtd->rules[$key]) || 0 < strlen($dtd->rules[$key])) && !$this->$validateFunction($value, $dtd->rules[$key])) + { + if (empty($messages[$key])) + { + if (isset($this->errorMessages[$key])) + { + $messages[$key] = $this->errorMessages[$key]; + } + else + { + $messages[$key] = "validator.error_messages[$key] empty"; + } + } + $errorMessages[$key] = sprintf($messages[$key], $label, $dtd->rules[$key]); + } + } + } + return $errorMessages; + } + + protected function _ban($value, $ruleValue) + { + return !preg_match($ruleValue, $value); + } + + protected function _mask($value, $ruleValue) + { + return preg_match($ruleValue, $value); + } + + protected function _equal_to($value, $ruleValue) + { + return $value === $ruleValue; + } + + protected function _max_length($value, $ruleValue) + { + return mb_strlen($value) <= $ruleValue; + } + + protected function _min_length($value, $ruleValue) + { + return mb_strlen($value) >= $ruleValue; + } + + protected function _max_value($value, $ruleValue) + { + return $value <= $ruleValue; + } + + protected function _min_value($value, $ruleValue) + { + return $value >= $ruleValue; + } + + protected function _min_selected($value, $ruleValue) + { + return count($value) >= $ruleValue; + } + + protected function _max_selected($value, $ruleValue) + { + return count($value) <= $ruleValue; + } + + protected function _required($value, $ruleValue) + { + if (false == $ruleValue) + { + return true; + } + else + { + return is_array($value) && count($value) || strlen($value); + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/Validator/ValidatorDtd.php b/extend/app_alipay/lotusphp_runtime/Validator/ValidatorDtd.php new file mode 100755 index 0000000..1f2f644 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/Validator/ValidatorDtd.php @@ -0,0 +1,23 @@ +label = $label; + foreach($rules as $key => $rule) + { + $this->rules[$key] = $rule; + } + if ($messages) + { + foreach($messages as $key => $message) + { + $this->messages[$key] = $message; + } + } + } +} diff --git a/extend/app_alipay/lotusphp_runtime/XML/Xml.php b/extend/app_alipay/lotusphp_runtime/XML/Xml.php new file mode 100755 index 0000000..ab2a467 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/XML/Xml.php @@ -0,0 +1,304 @@ +mode = $mode; + + $this->encoding = $encoding; + $this->version = $version; + + $this->_getParser($encoding); + } + + public function getArray($xmlString) { + if (READMODE !== $this->mode) { + trigger_error("LtXml is on WRITEMODE, and cannot convert XML string to array."); + return WRONG_MODE; + } + + if (0 === preg_match("/version=[\"|\']([1-9]\d*\.\d*)[\"|\']/", $xmlString, $res)) { + trigger_error("Cannot find the version in this XML document."); + return INTERNAL_ERR; + } + else { + $this->version = $res[1]; + } + + if (0 === preg_match("/encoding=[\"|\'](.*?)[\"|\']/", $xmlString, $res)) { + $this->encoding = "UTF-8"; + } + else { + $this->encoding = strtoupper($res[1]); + } + + $_array = $this->_stringToArray($xmlString); + if (NULL === $_array) { + trigger_error("Fail to get the tag template."); + return INTERNAL_ERR; + } + $currentArray = NULL; + $openingTags = array(); + $array = $this->_getArrayTemplate(); + + foreach ($_array as $tag) { + $tag["tag"] = strtolower($tag["tag"]); + if (isset($tag["type"]) && "close" == $tag["type"] + && isset($tag["tag"]) && ! empty($tag["tag"])) { + if ($openingTags[count($openingTags) - 1]["tag"] == $tag["tag"]) { + unset($openingTags[count($openingTags) - 1]); + } + else { + return -1; + } + } + else if ((isset($tag["type"]) && "complete" == $tag["type"]) + || (isset($tag["type"]) && "open" == $tag["type"]) + && isset($tag["tag"]) && ! empty($tag["tag"])){ + $currentArray = $this->_getArrayTemplate(); + $currentArray["tag"] = $tag["tag"]; + $cdata = $tag["value"]; + $cdata = preg_replace("/^\s*/", "", $cdata); + $cdata = preg_replace("/\s*$/", "", $cdata); + $currentArray["cdata"] = $cdata; + if (isset($tag["attributes"]) && is_array($tag["attributes"])) { + foreach($tag["attributes"] as $k => $v) { + $currentArray["attributes"][strtolower($k)] = $v; + } + } + + if (0 == count($openingTags)) { + $openingTags[] = &$array; + $openingTags[0] = $currentArray; + } + else { + $subCount = count($openingTags[count($openingTags) - 1]["sub"]); + $openingTags[count($openingTags) - 1]["sub"][$subCount] = $currentArray; + $openingTags[count($openingTags)] = &$openingTags[count($openingTags) - 1]["sub"][$subCount]; + } + + if ("complete" == $tag["type"]) { + unset($openingTags[count($openingTags) - 1]); + } + } + else if (isset($tag["type"]) && "cdata" == $tag["type"] + && isset($tag["tag"]) && ! empty($tag["tag"])) { + if ($tag["tag"] == $openingTags[count($openingTags) - 1]["tag"]) { + $cdata = $tag["value"]; + $cdata = preg_replace("/^\s*/", "", $cdata); + $cdata = preg_replace("/\s*$/", "", $cdata); + $openingTags[count($openingTags) - 1]["cdata"] .= $cdata; + } + else { + return -2; + } + } + } + + if (0 < count($openingTags)) { + return -3; + } + + return $array; + } + + public function getString($xmlArray) { + if (WRITEMODE !== $this->mode) { + trigger_error("LtXml is on READMODE, and cannot convert array to string."); + return WRONG_MODE; + } + + $header = "version}\" encoding=\"{$this->encoding}\"". " ?" . ">\n"; + + $xmlString = $header; + + $processingTags = array($xmlArray); + while (! empty($processingTags)) { + if (! isset($processingTags[count($processingTags) -1]["close"])) { + $tagArray = $processingTags[count($processingTags) - 1]; + + if (0 === $this->_isTag($tagArray)) { + trigger_error("The array do not match the format."); + return INTERNAL_ERR; + } + + $processingTags[count($processingTags) -1]["close"] = "YES"; + $tagName = $tagArray["tag"]; + + $tag = "<{$tagName}"; + foreach ($tagArray["attributes"] as $key => $value) { + $tag .= " {$key}=\"{$value}\""; + } + if (! empty($tagArray["sub"]) || ! empty($tagArray["cdata"])) { + $cdata = $this->_convertEntity($tagArray["cdata"]); + $tag .= ">\n{$cdata}\n"; + for ($i=count($tagArray["sub"]) - 1; $i>=0; $i--) { + $subArray = $tagArray["sub"][$i]; + $processingTags[count($processingTags)] = $subArray; + } + } + else { + $processingTags[count($processingTags) - 1]["complete"] = "YES"; + } + } + else { + $tag = (isset($processingTags[count($processingTags) - 1]["complete"])) + ? "/>\n" + : "\n"; + unset($processingTags[count($processingTags) - 1]); + } + + $xmlString .= $tag; + } + $xmlString = preg_replace("/\n\s*/", "\n", $xmlString); + + return $xmlString; + } + + /** + * 生成一个xml节点 + * @param string tag 标签名 + * @param string cdata 数据 + * @param array attr 属性列表 + * @param array sub 子标签列表 + */ + public function createTag($tag, $cdata = "", $attr = array(), $sub = array()) { + $newTag = $this->_getArrayTemplate(); + if (! is_string($tag)) { + trigger_error("Cannot read the tag name."); + return INTERNAL_ERR; + } + + $newTag["tag"] = $tag; + $newTag["cdata"] = $cdata; + $newTag["attributes"] = $attr; + $newTag["sub"] = $sub; + + return $newTag; + } + + /** + * 释放xml_parser + */ + public function free() { + xml_parser_free($this->_handler); + } + + private function _getParser($encoding) { + if (in_array($encoding, $this->_supportedEncoding)) + $this->_handler = xml_parser_create($encoding); + else + $this->_handler = NULL; + } + + private function _stringToArray($xmlString) { + $res = xml_parse_into_struct($this->_handler, $xmlString, $array); + if (1 === $res) + return $array; + else + return NULL; + } + + private function _convertEntity($string) { + $patterns = array("/ "", "attributes" => array(), "sub" => array(), "cdata" => ""); + } + + /** + * 检测传入的参数是否是一个合法的tag数组 + * @return 0 非法 + * @return 1 合法 + */ + private function _isTag($tag) { + if (! is_array($tag)) { + return 0; + } + + if (! isset($tag["tag"]) || ! is_string($tag["tag"]) || empty($tag["tag"])) { + return 0; + } + + if (! isset($tag["attributes"]) || ! is_array($tag["attributes"])) { + return 0; + } + + if (! isset($tag["sub"]) || ! is_array($tag["sub"])) { + return 0; + } + + if (! isset($tag["cdata"]) || ! is_string($tag["cdata"])) { + return 0; + } + + return 1; + } +} + diff --git a/extend/app_alipay/lotusphp_runtime/shortcut.php b/extend/app_alipay/lotusphp_runtime/shortcut.php new file mode 100755 index 0000000..0c5f0d6 --- /dev/null +++ b/extend/app_alipay/lotusphp_runtime/shortcut.php @@ -0,0 +1,5 @@ +appId = "app_id"; ӦAPPID +$aop->rsaPrivateKey = 'д˽Կȥͷȥβȥسһַ'; ӦõRSA2Կ˽Կ +$aop->alipayrsaPublicKey = 'д֧Կһַ'; Ӧõ֧ԿӦRSA2Կɲ鿴 +$notify_url = urlencode('̻Էʵ첽ַ'); ֧صURLַ +index.phpȡҪύtotal(λΪԪ)磺 http://demo.dcloud.net.cn/payment/alipayrsa2/?total=1 ʹDCloud˺ɵĶʾַtotalֵΪҪ֧Ľ \ No newline at end of file diff --git a/extend/image/Image.php b/extend/image/Image.php new file mode 100755 index 0000000..1ceb9ca --- /dev/null +++ b/extend/image/Image.php @@ -0,0 +1,614 @@ + +// +---------------------------------------------------------------------- + +namespace image; + +use image\image\gif\Gif; +use image\image\Exception as ImageException; + +class Image +{ + + /* 缩略图相关常量定义 */ + const THUMB_SCALING = 1; //常量,标识缩略图等比例缩放类型 + const THUMB_FILLED = 2; //常量,标识缩略图缩放后填充类型 + const THUMB_CENTER = 3; //常量,标识缩略图居中裁剪类型 + const THUMB_NORTHWEST = 4; //常量,标识缩略图左上角裁剪类型 + const THUMB_SOUTHEAST = 5; //常量,标识缩略图右下角裁剪类型 + const THUMB_FIXED = 6; //常量,标识缩略图固定尺寸缩放类型 + /* 水印相关常量定义 */ + const WATER_NORTHWEST = 1; //常量,标识左上角水印 + const WATER_NORTH = 2; //常量,标识上居中水印 + const WATER_NORTHEAST = 3; //常量,标识右上角水印 + const WATER_WEST = 4; //常量,标识左居中水印 + const WATER_CENTER = 5; //常量,标识居中水印 + const WATER_EAST = 6; //常量,标识右居中水印 + const WATER_SOUTHWEST = 7; //常量,标识左下角水印 + const WATER_SOUTH = 8; //常量,标识下居中水印 + const WATER_SOUTHEAST = 9; //常量,标识右下角水印 + /* 翻转相关常量定义 */ + const FLIP_X = 1; //X轴翻转 + const FLIP_Y = 2; //Y轴翻转 + + + /** + * 图像资源对象 + * + * @var resource + */ + protected $im; + + /** @var Gif */ + protected $gif; + + /** + * 图像信息,包括 width, height, type, mime, size + * + * @var array + */ + protected $info; + + protected function __construct(\SplFileInfo $file) + { + //获取图像信息 + $info = @getimagesize($file->getPathname()); + + //检测图像合法性 + if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) { + throw new ImageException('Illegal image file'); + } + + //设置图像信息 + $this->info = [ + 'width' => $info[0], + 'height' => $info[1], + 'type' => image_type_to_extension($info[2], false), + 'mime' => $info['mime'], + ]; + + //打开图像 + if ('gif' == $this->info['type']) { + $this->gif = new Gif($file->getPathname()); + $this->im = @imagecreatefromstring($this->gif->image()); + } else { + $fun = "imagecreatefrom{$this->info['type']}"; + $this->im = @$fun($file->getPathname()); + } + + if (empty($this->im)) { + throw new ImageException('Failed to create image resources!'); + } + + } + + /** + * 打开一个图片文件 + * @param \SplFileInfo|string $file + * @return Image + */ + public static function open($file) + { + if (is_string($file)) { + $file = new \SplFileInfo($file); + } + if (!$file->isFile()) { + throw new ImageException('image file not exist'); + } + return new self($file); + } + + /** + * 保存图像 + * @param string $pathname 图像保存路径名称 + * @param null|string $type 图像类型 + * @param int $quality 图像质量 + * @param bool $interlace 是否对JPEG类型图像设置隔行扫描 + * @return $this + */ + public function save($pathname, $type = null, $quality = 80, $interlace = true) + { + //自动获取图像类型 + if (is_null($type)) { + $type = $this->info['type']; + } else { + $type = strtolower($type); + } + //保存图像 + if ('jpeg' == $type || 'jpg' == $type) { + //JPEG图像设置隔行扫描 + imageinterlace($this->im, $interlace); + imagejpeg($this->im, $pathname, $quality); + } elseif ('gif' == $type && !empty($this->gif)) { + $this->gif->save($pathname); + } elseif ('png' == $type) { + //设定保存完整的 alpha 通道信息 + imagesavealpha($this->im, true); + //ImagePNG生成图像的质量范围从0到9的 + imagepng($this->im, $pathname, min((int)($quality / 10), 9)); + } else { + $fun = 'image' . $type; + $fun($this->im, $pathname); + } + + return $this; + } + + /** + * 返回图像宽度 + * @return int 图像宽度 + */ + public function width() + { + return $this->info['width']; + } + + /** + * 返回图像高度 + * @return int 图像高度 + */ + public function height() + { + return $this->info['height']; + } + + /** + * 返回图像类型 + * @return string 图像类型 + */ + public function type() + { + return $this->info['type']; + } + + /** + * 返回图像MIME类型 + * @return string 图像MIME类型 + */ + public function mime() + { + return $this->info['mime']; + } + + /** + * 返回图像尺寸数组 0 - 图像宽度,1 - 图像高度 + * @return array 图像尺寸 + */ + public function size() + { + return [$this->info['width'], $this->info['height']]; + } + + /** + * 旋转图像 + * @param int $degrees 顺时针旋转的度数 + * @return $this + */ + public function rotate($degrees = 90) + { + do { + $img = imagerotate($this->im, -$degrees, imagecolorallocatealpha($this->im, 0, 0, 0, 127)); + imagedestroy($this->im); + $this->im = $img; + } while (!empty($this->gif) && $this->gifNext()); + + $this->info['width'] = imagesx($this->im); + $this->info['height'] = imagesy($this->im); + + return $this; + } + + /** + * 翻转图像 + * @param integer $direction 翻转轴,X或者Y + * @return $this + */ + public function flip($direction = self::FLIP_X) + { + //原图宽度和高度 + $w = $this->info['width']; + $h = $this->info['height']; + + do { + + $img = imagecreatetruecolor($w, $h); + + switch ($direction) { + case self::FLIP_X: + for ($y = 0; $y < $h; $y++) { + imagecopy($img, $this->im, 0, $h - $y - 1, 0, $y, $w, 1); + } + break; + case self::FLIP_Y: + for ($x = 0; $x < $w; $x++) { + imagecopy($img, $this->im, $w - $x - 1, 0, $x, 0, 1, $h); + } + break; + default: + throw new ImageException('不支持的翻转类型'); + } + + imagedestroy($this->im); + $this->im = $img; + + } while (!empty($this->gif) && $this->gifNext()); + + return $this; + } + + /** + * 裁剪图像 + * + * @param integer $w 裁剪区域宽度 + * @param integer $h 裁剪区域高度 + * @param integer $x 裁剪区域x坐标 + * @param integer $y 裁剪区域y坐标 + * @param integer $width 图像保存宽度 + * @param integer $height 图像保存高度 + * + * @return $this + */ + public function crop($w, $h, $x = 0, $y = 0, $width = null, $height = null) + { + //设置保存尺寸 + empty($width) && $width = $w; + empty($height) && $height = $h; + do { + //创建新图像 + $img = imagecreatetruecolor($width, $height); + // 调整默认颜色 + $color = imagecolorallocate($img, 255, 255, 255); + imagefill($img, 0, 0, $color); + //裁剪 + imagecopyresampled($img, $this->im, 0, 0, $x, $y, $width, $height, $w, $h); + imagedestroy($this->im); //销毁原图 + //设置新图像 + $this->im = $img; + } while (!empty($this->gif) && $this->gifNext()); + $this->info['width'] = (int)$width; + $this->info['height'] = (int)$height; + return $this; + } + + /** + * 生成缩略图 + * + * @param integer $width 缩略图最大宽度 + * @param integer $height 缩略图最大高度 + * @param int $type 缩略图裁剪类型 + * + * @return $this + */ + public function thumb($width, $height, $type = self::THUMB_SCALING) + { + //原图宽度和高度 + $w = $this->info['width']; + $h = $this->info['height']; + /* 计算缩略图生成的必要参数 */ + switch ($type) { + /* 等比例缩放 */ + case self::THUMB_SCALING: + //原图尺寸小于缩略图尺寸则不进行缩略 + if ($w < $width && $h < $height) { + return false; + } + //计算缩放比例 + $scale = min($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 + $x = $y = 0; + $width = $w * $scale; + $height = $h * $scale; + break; + /* 居中裁剪 */ + case self::THUMB_CENTER: + //计算缩放比例 + $scale = max($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 + $w = $width / $scale; + $h = $height / $scale; + $x = ($this->info['width'] - $w) / 2; + $y = ($this->info['height'] - $h) / 2; + break; + /* 左上角裁剪 */ + case self::THUMB_NORTHWEST: + //计算缩放比例 + $scale = max($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 + $x = $y = 0; + $w = $width / $scale; + $h = $height / $scale; + break; + /* 右下角裁剪 */ + case self::THUMB_SOUTHEAST: + //计算缩放比例 + $scale = max($width / $w, $height / $h); + //设置缩略图的坐标及宽度和高度 + $w = $width / $scale; + $h = $height / $scale; + $x = $this->info['width'] - $w; + $y = $this->info['height'] - $h; + break; + /* 填充 */ + case self::THUMB_FILLED: + //计算缩放比例 + if ($w < $width && $h < $height) { + $scale = 1; + } else { + $scale = min($width / $w, $height / $h); + } + //设置缩略图的坐标及宽度和高度 + $neww = $w * $scale; + $newh = $h * $scale; + $x = $this->info['width'] - $w; + $y = $this->info['height'] - $h; + $posx = ($width - $w * $scale) / 2; + $posy = ($height - $h * $scale) / 2; + do { + //创建新图像 + $img = imagecreatetruecolor($width, $height); + // 调整默认颜色 + $color = imagecolorallocate($img, 255, 255, 255); + imagefill($img, 0, 0, $color); + //裁剪 + imagecopyresampled($img, $this->im, $posx, $posy, $x, $y, $neww, $newh, $w, $h); + imagedestroy($this->im); //销毁原图 + $this->im = $img; + } while (!empty($this->gif) && $this->gifNext()); + $this->info['width'] = (int)$width; + $this->info['height'] = (int)$height; + return $this; + /* 固定 */ + case self::THUMB_FIXED: + $x = $y = 0; + break; + default: + throw new ImageException('不支持的缩略图裁剪类型'); + } + /* 裁剪图像 */ + $this->crop($w, $h, $x, $y, $width, $height); + return $this; + } + + + /** + * 添加水印 + * + * @param string $source 水印图片路径 + * @param int $locate 水印位置 + * @param int $alpha 透明度 + * @return $this + */ + public function water($source, $locate = self::WATER_SOUTHEAST, $alpha = 100) + { + if (!is_file($source)) { + throw new ImageException('水印图像不存在'); + } + //获取水印图像信息 + $info = getimagesize($source); + if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) { + throw new ImageException('非法水印文件'); + } + //创建水印图像资源 + $fun = 'imagecreatefrom' . image_type_to_extension($info[2], false); + $water = $fun($source); + //设定水印图像的混色模式 + imagealphablending($water, true); + /* 设定水印位置 */ + switch ($locate) { + /* 右下角水印 */ + case self::WATER_SOUTHEAST: + $x = $this->info['width'] - $info[0]; + $y = $this->info['height'] - $info[1]; + break; + /* 左下角水印 */ + case self::WATER_SOUTHWEST: + $x = 0; + $y = $this->info['height'] - $info[1]; + break; + /* 左上角水印 */ + case self::WATER_NORTHWEST: + $x = $y = 0; + break; + /* 右上角水印 */ + case self::WATER_NORTHEAST: + $x = $this->info['width'] - $info[0]; + $y = 0; + break; + /* 居中水印 */ + case self::WATER_CENTER: + $x = ($this->info['width'] - $info[0]) / 2; + $y = ($this->info['height'] - $info[1]) / 2; + break; + /* 下居中水印 */ + case self::WATER_SOUTH: + $x = ($this->info['width'] - $info[0]) / 2; + $y = $this->info['height'] - $info[1]; + break; + /* 右居中水印 */ + case self::WATER_EAST: + $x = $this->info['width'] - $info[0]; + $y = ($this->info['height'] - $info[1]) / 2; + break; + /* 上居中水印 */ + case self::WATER_NORTH: + $x = ($this->info['width'] - $info[0]) / 2; + $y = 0; + break; + /* 左居中水印 */ + case self::WATER_WEST: + $x = 0; + $y = ($this->info['height'] - $info[1]) / 2; + break; + default: + /* 自定义水印坐标 */ + if (is_array($locate)) { + list($x, $y) = $locate; + } else { + throw new ImageException('不支持的水印位置类型'); + } + } + do { + //添加水印 + $src = imagecreatetruecolor($info[0], $info[1]); + // 调整默认颜色 + $color = imagecolorallocate($src, 255, 255, 255); + imagefill($src, 0, 0, $color); + imagecopy($src, $this->im, 0, 0, $x, $y, $info[0], $info[1]); + imagecopy($src, $water, 0, 0, 0, 0, $info[0], $info[1]); + imagecopymerge($this->im, $src, $x, $y, 0, 0, $info[0], $info[1], $alpha); + //销毁零时图片资源 + imagedestroy($src); + } while (!empty($this->gif) && $this->gifNext()); + //销毁水印资源 + imagedestroy($water); + return $this; + } + + /** + * 图像添加文字 + * + * @param string $text 添加的文字 + * @param string $font 字体路径 + * @param integer $size 字号 + * @param string $color 文字颜色 + * @param int $locate 文字写入位置 + * @param integer $offset 文字相对当前位置的偏移量 + * @param integer $angle 文字倾斜角度 + * + * @return $this + * @throws ImageException + */ + public function text($text, $font, $size, $color = '#00000000', + $locate = self::WATER_SOUTHEAST, $offset = 0, $angle = 0) + { + + if (!is_file($font)) { + throw new ImageException("不存在的字体文件:{$font}"); + } + //获取文字信息 + $info = imagettfbbox($size, $angle, $font, $text); + $minx = min($info[0], $info[2], $info[4], $info[6]); + $maxx = max($info[0], $info[2], $info[4], $info[6]); + $miny = min($info[1], $info[3], $info[5], $info[7]); + $maxy = max($info[1], $info[3], $info[5], $info[7]); + /* 计算文字初始坐标和尺寸 */ + $x = $minx; + $y = abs($miny); + $w = $maxx - $minx; + $h = $maxy - $miny; + /* 设定文字位置 */ + switch ($locate) { + /* 右下角文字 */ + case self::WATER_SOUTHEAST: + $x += $this->info['width'] - $w; + $y += $this->info['height'] - $h; + break; + /* 左下角文字 */ + case self::WATER_SOUTHWEST: + $y += $this->info['height'] - $h; + break; + /* 左上角文字 */ + case self::WATER_NORTHWEST: + // 起始坐标即为左上角坐标,无需调整 + break; + /* 右上角文字 */ + case self::WATER_NORTHEAST: + $x += $this->info['width'] - $w; + break; + /* 居中文字 */ + case self::WATER_CENTER: + $x += ($this->info['width'] - $w) / 2; + $y += ($this->info['height'] - $h) / 2; + break; + /* 下居中文字 */ + case self::WATER_SOUTH: + $x += ($this->info['width'] - $w) / 2; + $y += $this->info['height'] - $h; + break; + /* 右居中文字 */ + case self::WATER_EAST: + $x += $this->info['width'] - $w; + $y += ($this->info['height'] - $h) / 2; + break; + /* 上居中文字 */ + case self::WATER_NORTH: + $x += ($this->info['width'] - $w) / 2; + break; + /* 左居中文字 */ + case self::WATER_WEST: + $y += ($this->info['height'] - $h) / 2; + break; + default: + /* 自定义文字坐标 */ + if (is_array($locate)) { + list($posx, $posy) = $locate; + $x += $posx; + $y += $posy; + } else { + throw new ImageException('不支持的文字位置类型'); + } + } + /* 设置偏移量 */ + if (is_array($offset)) { + $offset = array_map('intval', $offset); + list($ox, $oy) = $offset; + } else { + $offset = intval($offset); + $ox = $oy = $offset; + } + /* 设置颜色 */ + if (is_string($color) && 0 === strpos($color, '#')) { + $color = str_split(substr($color, 1), 2); + $color = array_map('hexdec', $color); + if (empty($color[3]) || $color[3] > 127) { + $color[3] = 0; + } + } elseif (!is_array($color)) { + throw new ImageException('错误的颜色值'); + } + do { + /* 写入文字 */ + $col = imagecolorallocatealpha($this->im, $color[0], $color[1], $color[2], $color[3]); + imagettftext($this->im, $size, $angle, $x + $ox, $y + $oy, $col, $font, $text); + } while (!empty($this->gif) && $this->gifNext()); + return $this; + } + + /** + * 切换到GIF的下一帧并保存当前帧 + */ + protected function gifNext() + { + ob_start(); + ob_implicit_flush(0); + imagegif($this->im); + $img = ob_get_clean(); + $this->gif->image($img); + $next = $this->gif->nextImage(); + if ($next) { + imagedestroy($this->im); + $this->im = imagecreatefromstring($next); + return $next; + } else { + imagedestroy($this->im); + $this->im = imagecreatefromstring($this->gif->image()); + return false; + } + } + + /** + * 析构方法,用于销毁图像资源 + */ + public function __destruct() + { + empty($this->im) || imagedestroy($this->im); + } + +} \ No newline at end of file diff --git a/extend/image/image/Exception.php b/extend/image/image/Exception.php new file mode 100755 index 0000000..103fcb1 --- /dev/null +++ b/extend/image/image/Exception.php @@ -0,0 +1,18 @@ + +// +---------------------------------------------------------------------- + +namespace image\image; + + +class Exception extends \RuntimeException +{ + +} \ No newline at end of file diff --git a/extend/image/image/gif/Decoder.php b/extend/image/image/gif/Decoder.php new file mode 100755 index 0000000..5f3b758 --- /dev/null +++ b/extend/image/image/gif/Decoder.php @@ -0,0 +1,207 @@ + +// +---------------------------------------------------------------------- + +namespace image\image\gif; + + +class Decoder +{ + public $GIF_buffer = []; + public $GIF_arrays = []; + public $GIF_delays = []; + public $GIF_stream = ""; + public $GIF_string = ""; + public $GIF_bfseek = 0; + public $GIF_screen = []; + public $GIF_global = []; + public $GIF_sorted; + public $GIF_colorS; + public $GIF_colorC; + public $GIF_colorF; + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFDecoder ( $GIF_pointer ) + :: + */ + public function __construct($GIF_pointer) + { + $this->GIF_stream = $GIF_pointer; + $this->getByte(6); // GIF89a + $this->getByte(7); // Logical Screen Descriptor + $this->GIF_screen = $this->GIF_buffer; + $this->GIF_colorF = $this->GIF_buffer[4] & 0x80 ? 1 : 0; + $this->GIF_sorted = $this->GIF_buffer[4] & 0x08 ? 1 : 0; + $this->GIF_colorC = $this->GIF_buffer[4] & 0x07; + $this->GIF_colorS = 2 << $this->GIF_colorC; + if (1 == $this->GIF_colorF) { + $this->getByte(3 * $this->GIF_colorS); + $this->GIF_global = $this->GIF_buffer; + } + + for ($cycle = 1; $cycle;) { + if ($this->getByte(1)) { + switch ($this->GIF_buffer[0]) { + case 0x21: + $this->readExtensions(); + break; + case 0x2C: + $this->readDescriptor(); + break; + case 0x3B: + $cycle = 0; + break; + } + } else { + $cycle = 0; + } + } + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + public function readExtensions() + { + $this->getByte(1); + for (; ;) { + $this->getByte(1); + if (($u = $this->GIF_buffer[0]) == 0x00) { + break; + } + $this->getByte($u); + /* + * 07.05.2007. + * Implemented a new line for a new function + * to determine the originaly delays between + * frames. + * + */ + if (4 == $u) { + $this->GIF_delays[] = ($this->GIF_buffer[1] | $this->GIF_buffer[2] << 8); + } + } + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFReadExtension ( ) + :: + */ + public function readDescriptor() + { + $this->getByte(9); + $GIF_screen = $this->GIF_buffer; + $GIF_colorF = $this->GIF_buffer[8] & 0x80 ? 1 : 0; + if ($GIF_colorF) { + $GIF_code = $this->GIF_buffer[8] & 0x07; + $GIF_sort = $this->GIF_buffer[8] & 0x20 ? 1 : 0; + } else { + $GIF_code = $this->GIF_colorC; + $GIF_sort = $this->GIF_sorted; + } + $GIF_size = 2 << $GIF_code; + $this->GIF_screen[4] &= 0x70; + $this->GIF_screen[4] |= 0x80; + $this->GIF_screen[4] |= $GIF_code; + if ($GIF_sort) { + $this->GIF_screen[4] |= 0x08; + } + $this->GIF_string = "GIF87a"; + $this->putByte($this->GIF_screen); + if (1 == $GIF_colorF) { + $this->getByte(3 * $GIF_size); + $this->putByte($this->GIF_buffer); + } else { + $this->putByte($this->GIF_global); + } + $this->GIF_string .= chr(0x2C); + $GIF_screen[8] &= 0x40; + $this->putByte($GIF_screen); + $this->getByte(1); + $this->putByte($this->GIF_buffer); + for (; ;) { + $this->getByte(1); + $this->putByte($this->GIF_buffer); + if (($u = $this->GIF_buffer[0]) == 0x00) { + break; + } + $this->getByte($u); + $this->putByte($this->GIF_buffer); + } + $this->GIF_string .= chr(0x3B); + /* + Add frames into $GIF_stream array... + */ + $this->GIF_arrays[] = $this->GIF_string; + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetByte ( $len ) + :: + */ + public function getByte($len) + { + $this->GIF_buffer = []; + for ($i = 0; $i < $len; $i++) { + if ($this->GIF_bfseek > strlen($this->GIF_stream)) { + return 0; + } + $this->GIF_buffer[] = ord($this->GIF_stream{$this->GIF_bfseek++}); + } + return 1; + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFPutByte ( $bytes ) + :: + */ + public function putByte($bytes) + { + for ($i = 0; $i < count($bytes); $i++) { + $this->GIF_string .= chr($bytes[$i]); + } + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: PUBLIC FUNCTIONS + :: + :: + :: GIFGetFrames ( ) + :: + */ + public function getFrames() + { + return ($this->GIF_arrays); + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFGetDelays ( ) + :: + */ + public function getDelays() + { + return ($this->GIF_delays); + } +} \ No newline at end of file diff --git a/extend/image/image/gif/Encoder.php b/extend/image/image/gif/Encoder.php new file mode 100755 index 0000000..20a7e9d --- /dev/null +++ b/extend/image/image/gif/Encoder.php @@ -0,0 +1,222 @@ + +// +---------------------------------------------------------------------- +namespace image\image\gif; + +class Encoder +{ + public $GIF = "GIF89a"; /* GIF header 6 bytes */ + public $VER = "GIFEncoder V2.05"; /* Encoder version */ + public $BUF = []; + public $LOP = 0; + public $DIS = 2; + public $COL = -1; + public $IMG = -1; + public $ERR = [ + 'ERR00' => "Does not supported function for only one image!", + 'ERR01' => "Source is not a GIF image!", + 'ERR02' => "Unintelligible flag ", + 'ERR03' => "Does not make animation from animated GIF source", + ]; + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFEncoder... + :: + */ + public function __construct( + $GIF_src, $GIF_dly, $GIF_lop, $GIF_dis, + $GIF_red, $GIF_grn, $GIF_blu, $GIF_mod + ) + { + if (!is_array($GIF_src)) { + printf("%s: %s", $this->VER, $this->ERR['ERR00']); + exit(0); + } + $this->LOP = ($GIF_lop > -1) ? $GIF_lop : 0; + $this->DIS = ($GIF_dis > -1) ? (($GIF_dis < 3) ? $GIF_dis : 3) : 2; + $this->COL = ($GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1) ? + ($GIF_red | ($GIF_grn << 8) | ($GIF_blu << 16)) : -1; + for ($i = 0; $i < count($GIF_src); $i++) { + if (strtolower($GIF_mod) == "url") { + $this->BUF[] = fread(fopen($GIF_src[$i], "rb"), filesize($GIF_src[$i])); + } else if (strtolower($GIF_mod) == "bin") { + $this->BUF[] = $GIF_src[$i]; + } else { + printf("%s: %s ( %s )!", $this->VER, $this->ERR['ERR02'], $GIF_mod); + exit(0); + } + if (substr($this->BUF[$i], 0, 6) != "GIF87a" && substr($this->BUF[$i], 0, 6) != "GIF89a") { + printf("%s: %d %s", $this->VER, $i, $this->ERR['ERR01']); + exit(0); + } + for ($j = (13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07))), $k = true; $k; $j++) { + switch ($this->BUF[$i]{$j}) { + case "!": + if ((substr($this->BUF[$i], ($j + 3), 8)) == "NETSCAPE") { + printf("%s: %s ( %s source )!", $this->VER, $this->ERR['ERR03'], ($i + 1)); + exit(0); + } + break; + case ";": + $k = false; + break; + } + } + } + $this->addHeader(); + for ($i = 0; $i < count($this->BUF); $i++) { + $this->addFrames($i, $GIF_dly[$i]); + } + $this->addFooter(); + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddHeader... + :: + */ + public function addHeader() + { + if (ord($this->BUF[0]{10}) & 0x80) { + $cmap = 3 * (2 << (ord($this->BUF[0]{10}) & 0x07)); + $this->GIF .= substr($this->BUF[0], 6, 7); + $this->GIF .= substr($this->BUF[0], 13, $cmap); + $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . $this->word($this->LOP) . "\0"; + } + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFrames... + :: + */ + public function addFrames($i, $d) + { + $Locals_img = ''; + $Locals_str = 13 + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07)); + $Locals_end = strlen($this->BUF[$i]) - $Locals_str - 1; + $Locals_tmp = substr($this->BUF[$i], $Locals_str, $Locals_end); + $Global_len = 2 << (ord($this->BUF[0]{10}) & 0x07); + $Locals_len = 2 << (ord($this->BUF[$i]{10}) & 0x07); + $Global_rgb = substr($this->BUF[0], 13, + 3 * (2 << (ord($this->BUF[0]{10}) & 0x07))); + $Locals_rgb = substr($this->BUF[$i], 13, + 3 * (2 << (ord($this->BUF[$i]{10}) & 0x07))); + $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 0) . + chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . "\x0\x0"; + if ($this->COL > -1 && ord($this->BUF[$i]{10}) & 0x80) { + for ($j = 0; $j < (2 << (ord($this->BUF[$i]{10}) & 0x07)); $j++) { + if ( + ord($Locals_rgb{3 * $j + 0}) == (($this->COL >> 16) & 0xFF) && + ord($Locals_rgb{3 * $j + 1}) == (($this->COL >> 8) & 0xFF) && + ord($Locals_rgb{3 * $j + 2}) == (($this->COL >> 0) & 0xFF) + ) { + $Locals_ext = "!\xF9\x04" . chr(($this->DIS << 2) + 1) . + chr(($d >> 0) & 0xFF) . chr(($d >> 8) & 0xFF) . chr($j) . "\x0"; + break; + } + } + } + switch ($Locals_tmp{0}) { + case "!": + /** + * @var string $Locals_img ; + */ + $Locals_img = substr($Locals_tmp, 8, 10); + $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); + break; + case ",": + $Locals_img = substr($Locals_tmp, 0, 10); + $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); + break; + } + if (ord($this->BUF[$i]{10}) & 0x80 && $this->IMG > -1) { + if ($Global_len == $Locals_len) { + if ($this->blockCompare($Global_rgb, $Locals_rgb, $Global_len)) { + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp); + } else { + $byte = ord($Locals_img{9}); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->BUF[0]{10}) & 0x07); + $Locals_img{9} = chr($byte); + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); + } + } else { + $byte = ord($Locals_img{9}); + $byte |= 0x80; + $byte &= 0xF8; + $byte |= (ord($this->BUF[$i]{10}) & 0x07); + $Locals_img{9} = chr($byte); + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp); + } + } else { + $this->GIF .= ($Locals_ext . $Locals_img . $Locals_tmp); + } + $this->IMG = 1; + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFAddFooter... + :: + */ + public function addFooter() + { + $this->GIF .= ";"; + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFBlockCompare... + :: + */ + public function blockCompare($GlobalBlock, $LocalBlock, $Len) + { + for ($i = 0; $i < $Len; $i++) { + if ( + $GlobalBlock{3 * $i + 0} != $LocalBlock{3 * $i + 0} || + $GlobalBlock{3 * $i + 1} != $LocalBlock{3 * $i + 1} || + $GlobalBlock{3 * $i + 2} != $LocalBlock{3 * $i + 2} + ) { + return (0); + } + } + return (1); + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GIFWord... + :: + */ + public function word($int) + { + return (chr($int & 0xFF) . chr(($int >> 8) & 0xFF)); + } + + /* + ::::::::::::::::::::::::::::::::::::::::::::::::::: + :: + :: GetAnimation... + :: + */ + public function getAnimation() + { + return ($this->GIF); + } +} \ No newline at end of file diff --git a/extend/image/image/gif/Gif.php b/extend/image/image/gif/Gif.php new file mode 100755 index 0000000..2fc1d7a --- /dev/null +++ b/extend/image/image/gif/Gif.php @@ -0,0 +1,86 @@ + +// +---------------------------------------------------------------------- +namespace image\image\gif; +class Gif +{ + /** + * GIF帧列表 + * + * @var array + */ + private $frames = []; + /** + * 每帧等待时间列表 + * + * @var array + */ + private $delays = []; + + /** + * 构造方法,用于解码GIF图片 + * + * @param string $src GIF图片数据 + * @param string $mod 图片数据类型 + * @throws \Exception + */ + public function __construct($src = null, $mod = 'url') + { + if (!is_null($src)) { + if ('url' == $mod && is_file($src)) { + $src = file_get_contents($src); + } + /* 解码GIF图片 */ + try { + $de = new Decoder($src); + $this->frames = $de->getFrames(); + $this->delays = $de->getDelays(); + } catch (\Exception $e) { + throw new \Exception("解码GIF图片出错"); + } + } + } + + /** + * 设置或获取当前帧的数据 + * + * @param string $stream 二进制数据流 + * @return mixed 获取到的数据 + */ + public function image($stream = null) + { + if (is_null($stream)) { + $current = current($this->frames); + return false === $current ? reset($this->frames) : $current; + } + $this->frames[key($this->frames)] = $stream; + } + + /** + * 将当前帧移动到下一帧 + * + * @return string 当前帧数据 + */ + public function nextImage() + { + return next($this->frames); + } + + /** + * 编码并保存当前GIF图片 + * + * @param string $pathname 图片名称 + */ + public function save($pathname) + { + $gif = new Encoder($this->frames, $this->delays, 0, 2, 0, 0, 0, 'bin'); + file_put_contents($pathname, $gif->getAnimation()); + } +} \ No newline at end of file diff --git a/extend/org/Base64.php b/extend/org/Base64.php new file mode 100755 index 0000000..1ab0875 --- /dev/null +++ b/extend/org/Base64.php @@ -0,0 +1,78 @@ + +// +---------------------------------------------------------------------- +namespace org; +/** + * Base64 加密实现类 + */ +class Base64 { + + /** + * 加密字符串 + * @param string $str 字符串 + * @param string $key 加密key + * @param integer $expire 有效期(秒) + * @return string + */ + public static function encrypt($data,$key,$expire=0) { + $expire = sprintf('%010d', $expire ? $expire + time():0); + $key = md5($key); + $data = base64_encode($expire.$data); + $char = ""; + $str = ""; + $x=0; + $len = strlen($data); + $l = strlen($key); + for ($i=0;$i< $len;$i++) { + if ($x== $l) $x=0; + $char .=substr($key,$x,1); + $x++; + } + + for ($i=0;$i< $len;$i++) { + $str .=chr(ord(substr($data,$i,1))+(ord(substr($char,$i,1)))%256); + } + return $str; + } + + /** + * 解密字符串 + * @param string $str 字符串 + * @param string $key 加密key + * @return string + */ + public static function decrypt($data,$key) { + $key = md5($key); + $x=0; + $len = strlen($data); + $l = strlen($key); + $char = ""; + $str = ""; + for ($i=0;$i< $len;$i++) { + if ($x== $l) $x=0; + $char .=substr($key,$x,1); + $x++; + } + for ($i=0;$i< $len;$i++) { + if (ord(substr($data,$i,1)) 0 && $expire < time()) { + return ''; + } + $data = substr($data,10); + return $data; + } +} \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel.php b/extend/phpexcel/PHPExcel.php new file mode 100755 index 0000000..bf6f60f --- /dev/null +++ b/extend/phpexcel/PHPExcel.php @@ -0,0 +1,1139 @@ +_hasMacros; + } + + /** + * Define if a workbook has macros + * + * @param true|false + */ + public function setHasMacros($hasMacros=false){ + $this->_hasMacros=(bool)$hasMacros; + } + + /** + * Set the macros code + * + * @param binary string|null + */ + public function setMacrosCode($MacrosCode){ + $this->_macrosCode=$MacrosCode; + $this->setHasMacros(!is_null($MacrosCode)); + } + + /** + * Return the macros code + * + * @return binary|null + */ + public function getMacrosCode(){ + return $this->_macrosCode; + } + + /** + * Set the macros certificate + * + * @param binary|null + */ + public function setMacrosCertificate($Certificate=NULL){ + $this->_macrosCertificate=$Certificate; + } + + /** + * Is the project signed ? + * + * @return true|false + */ + public function hasMacrosCertificate(){ + return !is_null($this->_macrosCertificate); + } + + /** + * Return the macros certificate + * + * @return binary|null + */ + public function getMacrosCertificate(){ + return $this->_macrosCertificate; + } + + /** + * Remove all macros, certificate from spreadsheet + * + * @param none + * @return void + */ + public function discardMacros(){ + $this->_hasMacros=false; + $this->_macrosCode=NULL; + $this->_macrosCertificate=NULL; + } + + /** + * set ribbon XML data + * + */ + public function setRibbonXMLData($Target=NULL, $XMLData=NULL){ + if(!is_null($Target) && !is_null($XMLData)){ + $this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData); + }else{ + $this->_ribbonXMLData=NULL; + } + } + + /** + * retrieve ribbon XML Data + * + * return string|null|array + */ + public function getRibbonXMLData($What='all'){//we need some constants here... + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + $ReturnData=$this->_ribbonXMLData; + break; + case 'target': + case 'data': + if(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){ + $ReturnData=$this->_ribbonXMLData[$What]; + }//else $ReturnData stay at null + break; + }//default: $ReturnData at null + return $ReturnData; + } + + /** + * store binaries ribbon objects (pictures) + * + */ + public function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){ + if(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){ + $this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData); + }else{ + $this->_ribbonBinObjects=NULL; + } + } + /** + * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function) + * + */ + private function _getExtensionOnly($ThePath){ + return pathinfo($ThePath, PATHINFO_EXTENSION); + } + + /** + * retrieve Binaries Ribbon Objects + * + */ + public function getRibbonBinObjects($What='all'){ + $ReturnData=NULL; + $What=strtolower($What); + switch($What){ + case 'all': + return $this->_ribbonBinObjects; + break; + case 'names': + case 'data': + if(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){ + $ReturnData=$this->_ribbonBinObjects[$What]; + } + break; + case 'types': + if(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){ + $tmpTypes=array_keys($this->_ribbonBinObjects['data']); + $ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes)); + }else + $ReturnData=array();//the caller want an array... not null if empty + break; + } + return $ReturnData; + } + + /** + * This workbook have a custom UI ? + * + * @return true|false + */ + public function hasRibbon(){ + return !is_null($this->_ribbonXMLData); + } + + /** + * This workbook have additionnal object for the ribbon ? + * + * @return true|false + */ + public function hasRibbonBinObjects(){ + return !is_null($this->_ribbonBinObjects); + } + + /** + * Check if a sheet with a specified code name already exists + * + * @param string $pSheetCodeName Name of the worksheet to check + * @return boolean + */ + public function sheetCodeNameExists($pSheetCodeName) + { + return ($this->getSheetByCodeName($pSheetCodeName) !== NULL); + } + + /** + * Get sheet by code name. Warning : sheet don't have always a code name ! + * + * @param string $pName Sheet name + * @return PHPExcel_Worksheet + */ + public function getSheetByCodeName($pName = '') + { + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + if ($this->_workSheetCollection[$i]->getCodeName() == $pName) { + return $this->_workSheetCollection[$i]; + } + } + + return null; + } + + /** + * Create a new PHPExcel with one Worksheet + */ + public function __construct() + { + $this->_uniqueID = uniqid(); + $this->_calculationEngine = PHPExcel_Calculation::getInstance($this); + + // Initialise worksheet collection and add one worksheet + $this->_workSheetCollection = array(); + $this->_workSheetCollection[] = new PHPExcel_Worksheet($this); + $this->_activeSheetIndex = 0; + + // Create document properties + $this->_properties = new PHPExcel_DocumentProperties(); + + // Create document security + $this->_security = new PHPExcel_DocumentSecurity(); + + // Set named ranges + $this->_namedRanges = array(); + + // Create the cellXf supervisor + $this->_cellXfSupervisor = new PHPExcel_Style(true); + $this->_cellXfSupervisor->bindParent($this); + + // Create the default style + $this->addCellXf(new PHPExcel_Style); + $this->addCellStyleXf(new PHPExcel_Style); + } + + /** + * Code to execute when this worksheet is unset() + * + */ + public function __destruct() { + PHPExcel_Calculation::unsetInstance($this); + $this->disconnectWorksheets(); + } // function __destruct() + + /** + * Disconnect all worksheets from this PHPExcel workbook object, + * typically so that the PHPExcel object can be unset + * + */ + public function disconnectWorksheets() + { + $worksheet = NULL; + foreach($this->_workSheetCollection as $k => &$worksheet) { + $worksheet->disconnectCells(); + $this->_workSheetCollection[$k] = null; + } + unset($worksheet); + $this->_workSheetCollection = array(); + } + + /** + * Return the calculation engine for this worksheet + * + * @return PHPExcel_Calculation + */ + public function getCalculationEngine() + { + return $this->_calculationEngine; + } // function getCellCacheController() + + /** + * Get properties + * + * @return PHPExcel_DocumentProperties + */ + public function getProperties() + { + return $this->_properties; + } + + /** + * Set properties + * + * @param PHPExcel_DocumentProperties $pValue + */ + public function setProperties(PHPExcel_DocumentProperties $pValue) + { + $this->_properties = $pValue; + } + + /** + * Get security + * + * @return PHPExcel_DocumentSecurity + */ + public function getSecurity() + { + return $this->_security; + } + + /** + * Set security + * + * @param PHPExcel_DocumentSecurity $pValue + */ + public function setSecurity(PHPExcel_DocumentSecurity $pValue) + { + $this->_security = $pValue; + } + + /** + * Get active sheet + * + * @return PHPExcel_Worksheet + */ + public function getActiveSheet() + { + return $this->_workSheetCollection[$this->_activeSheetIndex]; + } + + /** + * Create sheet and add it to this workbook + * + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function createSheet($iSheetIndex = NULL) + { + $newSheet = new PHPExcel_Worksheet($this); + $this->addSheet($newSheet, $iSheetIndex); + return $newSheet; + } + + /** + * Check if a sheet with a specified name already exists + * + * @param string $pSheetName Name of the worksheet to check + * @return boolean + */ + public function sheetNameExists($pSheetName) + { + return ($this->getSheetByName($pSheetName) !== NULL); + } + + /** + * Add sheet + * + * @param PHPExcel_Worksheet $pSheet + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL) + { + if ($this->sheetNameExists($pSheet->getTitle())) { + throw new PHPExcel_Exception( + "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first." + ); + } + + if($iSheetIndex === NULL) { + if ($this->_activeSheetIndex < 0) { + $this->_activeSheetIndex = 0; + } + $this->_workSheetCollection[] = $pSheet; + } else { + // Insert the sheet at the requested index + array_splice( + $this->_workSheetCollection, + $iSheetIndex, + 0, + array($pSheet) + ); + + // Adjust active sheet index if necessary + if ($this->_activeSheetIndex >= $iSheetIndex) { + ++$this->_activeSheetIndex; + } + } + + if ($pSheet->getParent() === null) { + $pSheet->rebindParent($this); + } + + return $pSheet; + } + + /** + * Remove sheet by index + * + * @param int $pIndex Active sheet index + * @throws PHPExcel_Exception + */ + public function removeSheetByIndex($pIndex = 0) + { + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); + } else { + array_splice($this->_workSheetCollection, $pIndex, 1); + } + // Adjust active sheet index if necessary + if (($this->_activeSheetIndex >= $pIndex) && + ($pIndex > count($this->_workSheetCollection) - 1)) { + --$this->_activeSheetIndex; + } + + } + + /** + * Get sheet by index + * + * @param int $pIndex Sheet index + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function getSheet($pIndex = 0) + { + + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." + ); + } else { + return $this->_workSheetCollection[$pIndex]; + } + } + + /** + * Get all sheets + * + * @return PHPExcel_Worksheet[] + */ + public function getAllSheets() + { + return $this->_workSheetCollection; + } + + /** + * Get sheet by name + * + * @param string $pName Sheet name + * @return PHPExcel_Worksheet + */ + public function getSheetByName($pName = '') + { + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + if ($this->_workSheetCollection[$i]->getTitle() === $pName) { + return $this->_workSheetCollection[$i]; + } + } + + return NULL; + } + + /** + * Get index for sheet + * + * @param PHPExcel_Worksheet $pSheet + * @return Sheet index + * @throws PHPExcel_Exception + */ + public function getIndex(PHPExcel_Worksheet $pSheet) + { + foreach ($this->_workSheetCollection as $key => $value) { + if ($value->getHashCode() == $pSheet->getHashCode()) { + return $key; + } + } + + throw new PHPExcel_Exception("Sheet does not exist."); + } + + /** + * Set index for sheet by sheet name. + * + * @param string $sheetName Sheet name to modify index for + * @param int $newIndex New index for the sheet + * @return New sheet index + * @throws PHPExcel_Exception + */ + public function setIndexByName($sheetName, $newIndex) + { + $oldIndex = $this->getIndex($this->getSheetByName($sheetName)); + $pSheet = array_splice( + $this->_workSheetCollection, + $oldIndex, + 1 + ); + array_splice( + $this->_workSheetCollection, + $newIndex, + 0, + $pSheet + ); + return $newIndex; + } + + /** + * Get sheet count + * + * @return int + */ + public function getSheetCount() + { + return count($this->_workSheetCollection); + } + + /** + * Get active sheet index + * + * @return int Active sheet index + */ + public function getActiveSheetIndex() + { + return $this->_activeSheetIndex; + } + + /** + * Set active sheet index + * + * @param int $pIndex Active sheet index + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setActiveSheetIndex($pIndex = 0) + { + $numSheets = count($this->_workSheetCollection); + + if ($pIndex > $numSheets - 1) { + throw new PHPExcel_Exception( + "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." + ); + } else { + $this->_activeSheetIndex = $pIndex; + } + return $this->getActiveSheet(); + } + + /** + * Set active sheet index by name + * + * @param string $pValue Sheet title + * @return PHPExcel_Worksheet + * @throws PHPExcel_Exception + */ + public function setActiveSheetIndexByName($pValue = '') + { + if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) { + $this->setActiveSheetIndex($this->getIndex($worksheet)); + return $worksheet; + } + + throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue); + } + + /** + * Get sheet names + * + * @return string[] + */ + public function getSheetNames() + { + $returnValue = array(); + $worksheetCount = $this->getSheetCount(); + for ($i = 0; $i < $worksheetCount; ++$i) { + $returnValue[] = $this->getSheet($i)->getTitle(); + } + + return $returnValue; + } + + /** + * Add external sheet + * + * @param PHPExcel_Worksheet $pSheet External sheet to add + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) { + if ($this->sheetNameExists($pSheet->getTitle())) { + throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first."); + } + + // count how many cellXfs there are in this workbook currently, we will need this below + $countCellXfs = count($this->_cellXfCollection); + + // copy all the shared cellXfs from the external workbook and append them to the current + foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) { + $this->addCellXf(clone $cellXf); + } + + // move sheet to this workbook + $pSheet->rebindParent($this); + + // update the cellXfs + foreach ($pSheet->getCellCollection(false) as $cellID) { + $cell = $pSheet->getCell($cellID); + $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs ); + } + + return $this->addSheet($pSheet, $iSheetIndex); + } + + /** + * Get named ranges + * + * @return PHPExcel_NamedRange[] + */ + public function getNamedRanges() { + return $this->_namedRanges; + } + + /** + * Add named range + * + * @param PHPExcel_NamedRange $namedRange + * @return PHPExcel + */ + public function addNamedRange(PHPExcel_NamedRange $namedRange) { + if ($namedRange->getScope() == null) { + // global scope + $this->_namedRanges[$namedRange->getName()] = $namedRange; + } else { + // local scope + $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange; + } + return true; + } + + /** + * Get named range + * + * @param string $namedRange + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope + * @return PHPExcel_NamedRange|null + */ + public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) { + $returnValue = null; + + if ($namedRange != '' && ($namedRange !== NULL)) { + // first look for global defined name + if (isset($this->_namedRanges[$namedRange])) { + $returnValue = $this->_namedRanges[$namedRange]; + } + + // then look for local defined name (has priority over global defined name if both names exist) + if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { + $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]; + } + } + + return $returnValue; + } + + /** + * Remove named range + * + * @param string $namedRange + * @param PHPExcel_Worksheet|null $pSheet Scope: use null for global scope. + * @return PHPExcel + */ + public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) { + if ($pSheet === NULL) { + if (isset($this->_namedRanges[$namedRange])) { + unset($this->_namedRanges[$namedRange]); + } + } else { + if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { + unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]); + } + } + return $this; + } + + /** + * Get worksheet iterator + * + * @return PHPExcel_WorksheetIterator + */ + public function getWorksheetIterator() { + return new PHPExcel_WorksheetIterator($this); + } + + /** + * Copy workbook (!= clone!) + * + * @return PHPExcel + */ + public function copy() { + $copied = clone $this; + + $worksheetCount = count($this->_workSheetCollection); + for ($i = 0; $i < $worksheetCount; ++$i) { + $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy(); + $this->_workSheetCollection[$i]->rebindParent($this); + } + + return $copied; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + foreach($this as $key => $val) { + if (is_object($val) || (is_array($val))) { + $this->{$key} = unserialize(serialize($val)); + } + } + } + + /** + * Get the workbook collection of cellXfs + * + * @return PHPExcel_Style[] + */ + public function getCellXfCollection() + { + return $this->_cellXfCollection; + } + + /** + * Get cellXf by index + * + * @param int $pIndex + * @return PHPExcel_Style + */ + public function getCellXfByIndex($pIndex = 0) + { + return $this->_cellXfCollection[$pIndex]; + } + + /** + * Get cellXf by hash code + * + * @param string $pValue + * @return PHPExcel_Style|false + */ + public function getCellXfByHashCode($pValue = '') + { + foreach ($this->_cellXfCollection as $cellXf) { + if ($cellXf->getHashCode() == $pValue) { + return $cellXf; + } + } + return false; + } + + /** + * Check if style exists in style collection + * + * @param PHPExcel_Style $pCellStyle + * @return boolean + */ + public function cellXfExists($pCellStyle = null) + { + return in_array($pCellStyle, $this->_cellXfCollection, true); + } + + /** + * Get default style + * + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getDefaultStyle() + { + if (isset($this->_cellXfCollection[0])) { + return $this->_cellXfCollection[0]; + } + throw new PHPExcel_Exception('No default style found for this workbook'); + } + + /** + * Add a cellXf to the workbook + * + * @param PHPExcel_Style $style + */ + public function addCellXf(PHPExcel_Style $style) + { + $this->_cellXfCollection[] = $style; + $style->setIndex(count($this->_cellXfCollection) - 1); + } + + /** + * Remove cellXf by index. It is ensured that all cells get their xf index updated. + * + * @param int $pIndex Index to cellXf + * @throws PHPExcel_Exception + */ + public function removeCellXfByIndex($pIndex = 0) + { + if ($pIndex > count($this->_cellXfCollection) - 1) { + throw new PHPExcel_Exception("CellXf index is out of bounds."); + } else { + // first remove the cellXf + array_splice($this->_cellXfCollection, $pIndex, 1); + + // then update cellXf indexes for cells + foreach ($this->_workSheetCollection as $worksheet) { + foreach ($worksheet->getCellCollection(false) as $cellID) { + $cell = $worksheet->getCell($cellID); + $xfIndex = $cell->getXfIndex(); + if ($xfIndex > $pIndex ) { + // decrease xf index by 1 + $cell->setXfIndex($xfIndex - 1); + } else if ($xfIndex == $pIndex) { + // set to default xf index 0 + $cell->setXfIndex(0); + } + } + } + } + } + + /** + * Get the cellXf supervisor + * + * @return PHPExcel_Style + */ + public function getCellXfSupervisor() + { + return $this->_cellXfSupervisor; + } + + /** + * Get the workbook collection of cellStyleXfs + * + * @return PHPExcel_Style[] + */ + public function getCellStyleXfCollection() + { + return $this->_cellStyleXfCollection; + } + + /** + * Get cellStyleXf by index + * + * @param int $pIndex + * @return PHPExcel_Style + */ + public function getCellStyleXfByIndex($pIndex = 0) + { + return $this->_cellStyleXfCollection[$pIndex]; + } + + /** + * Get cellStyleXf by hash code + * + * @param string $pValue + * @return PHPExcel_Style|false + */ + public function getCellStyleXfByHashCode($pValue = '') + { + foreach ($this->_cellXfStyleCollection as $cellStyleXf) { + if ($cellStyleXf->getHashCode() == $pValue) { + return $cellStyleXf; + } + } + return false; + } + + /** + * Add a cellStyleXf to the workbook + * + * @param PHPExcel_Style $pStyle + */ + public function addCellStyleXf(PHPExcel_Style $pStyle) + { + $this->_cellStyleXfCollection[] = $pStyle; + $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1); + } + + /** + * Remove cellStyleXf by index + * + * @param int $pIndex + * @throws PHPExcel_Exception + */ + public function removeCellStyleXfByIndex($pIndex = 0) + { + if ($pIndex > count($this->_cellStyleXfCollection) - 1) { + throw new PHPExcel_Exception("CellStyleXf index is out of bounds."); + } else { + array_splice($this->_cellStyleXfCollection, $pIndex, 1); + } + } + + /** + * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells + * and columns in the workbook + */ + public function garbageCollect() + { + // how many references are there to each cellXf ? + $countReferencesCellXf = array(); + foreach ($this->_cellXfCollection as $index => $cellXf) { + $countReferencesCellXf[$index] = 0; + } + + foreach ($this->getWorksheetIterator() as $sheet) { + + // from cells + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + ++$countReferencesCellXf[$cell->getXfIndex()]; + } + + // from row dimensions + foreach ($sheet->getRowDimensions() as $rowDimension) { + if ($rowDimension->getXfIndex() !== null) { + ++$countReferencesCellXf[$rowDimension->getXfIndex()]; + } + } + + // from column dimensions + foreach ($sheet->getColumnDimensions() as $columnDimension) { + ++$countReferencesCellXf[$columnDimension->getXfIndex()]; + } + } + + // remove cellXfs without references and create mapping so we can update xfIndex + // for all cells and columns + $countNeededCellXfs = 0; + foreach ($this->_cellXfCollection as $index => $cellXf) { + if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf + ++$countNeededCellXfs; + } else { + unset($this->_cellXfCollection[$index]); + } + $map[$index] = $countNeededCellXfs - 1; + } + $this->_cellXfCollection = array_values($this->_cellXfCollection); + + // update the index for all cellXfs + foreach ($this->_cellXfCollection as $i => $cellXf) { + $cellXf->setIndex($i); + } + + // make sure there is always at least one cellXf (there should be) + if (empty($this->_cellXfCollection)) { + $this->_cellXfCollection[] = new PHPExcel_Style(); + } + + // update the xfIndex for all cells, row dimensions, column dimensions + foreach ($this->getWorksheetIterator() as $sheet) { + + // for all cells + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + $cell->setXfIndex( $map[$cell->getXfIndex()] ); + } + + // for all row dimensions + foreach ($sheet->getRowDimensions() as $rowDimension) { + if ($rowDimension->getXfIndex() !== null) { + $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] ); + } + } + + // for all column dimensions + foreach ($sheet->getColumnDimensions() as $columnDimension) { + $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] ); + } + + // also do garbage collection for all the sheets + $sheet->garbageCollect(); + } + } + + /** + * Return the unique ID value assigned to this spreadsheet workbook + * + * @return string + */ + public function getID() { + return $this->_uniqueID; + } + +} diff --git a/extend/phpexcel/PHPExcel/Autoloader.php b/extend/phpexcel/PHPExcel/Autoloader.php new file mode 100755 index 0000000..a36dfcc --- /dev/null +++ b/extend/phpexcel/PHPExcel/Autoloader.php @@ -0,0 +1,85 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + if (!apc_store($this->_cachePrefix.$this->_currentObjectID.'.cache',serialize($this->_currentObject),$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in APC'); + } + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @access public + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @access public + * @param string $pCoord Coordinate address of the cell to check + * @return void + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in apc + $success = apc_fetch($this->_cachePrefix.$pCoord.'.cache'); + if ($success === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @access public + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (parent::isDataSet($pCoord)) { + $obj = apc_fetch($this->_cachePrefix.$pCoord.'.cache'); + if ($obj === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @access public + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from APC + apc_delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @access public + * @param PHPExcel_Worksheet $parent The new worksheet + * @throws PHPExcel_Exception + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $obj = apc_fetch($this->_cachePrefix.$cellID.'.cache'); + if ($obj === FALSE) { + // Entry no longer exists in APC, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in APC'); + } + if (!apc_store($newCachePrefix.$cellID.'.cache',$obj,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in APC'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if ($this->_currentObject !== NULL) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the APC cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if ($this->_cachePrefix === NULL) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + apc_delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('apc_store')) { + return FALSE; + } + if (apc_sma_info() === FALSE) { + return FALSE; + } + + return TRUE; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php new file mode 100755 index 0000000..db3a0d8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/CacheBase.php @@ -0,0 +1,347 @@ +_parent = $parent; + } // function __construct() + + + /** + * Return the parent worksheet for this cell collection + * + * @return PHPExcel_Worksheet + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return true; + } + // Check if the requested entry exists in the cache + return isset($this->_cellCache[$pCoord]); + } // function isDataSet() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + $this->_currentCellIsDirty = true; + if (isset($this->_cellCache[$fromAddress])) { + $this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress]; + unset($this->_cellCache[$fromAddress]); + } + + return TRUE; + } // function moveCell() + + + /** + * Add or Update a cell in cache + * + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function updateCacheData(PHPExcel_Cell $cell) { + return $this->addCacheData($cell->getCoordinate(),$cell); + } // function updateCacheData() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = null; + } + + if (is_object($this->_cellCache[$pCoord])) { + $this->_cellCache[$pCoord]->detach(); + unset($this->_cellCache[$pCoord]); + } + $this->_currentCellIsDirty = false; + } // function deleteCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + return array_keys($this->_cellCache); + } // function getCellList() + + + /** + * Sort the list of all cell addresses currently held in cache by row and column + * + * @return void + */ + public function getSortedCellList() { + $sortKeys = array(); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%09d%3s',$row,$column)] = $coord; + } + ksort($sortKeys); + + return array_values($sortKeys); + } // function sortCellList() + + + + /** + * Get highest worksheet column and highest row that have cell records + * + * @return array Highest column name and highest row number + */ + public function getHighestRowAndColumn() + { + // Lookup highest column and highest row + $col = array('A' => '1A'); + $row = array(1); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + $row[$r] = $r; + $col[$c] = strlen($c).$c; + } + if (!empty($row)) { + // Determine highest column and row + $highestRow = max($row); + $highestColumn = substr(max($col),1); + } + + return array( 'row' => $highestRow, + 'column' => $highestColumn + ); + } + + + /** + * Return the cell address of the currently active cell object + * + * @return string + */ + public function getCurrentAddress() + { + return $this->_currentObjectID; + } + + /** + * Return the column address of the currently active cell object + * + * @return string + */ + public function getCurrentColumn() + { + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + return $column; + } + + /** + * Return the row address of the currently active cell object + * + * @return string + */ + public function getCurrentRow() + { + sscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row); + return $row; + } + + /** + * Get highest worksheet column + * + * @param string $row Return the highest column for the specified row, + * or the highest column of any row if no row number is passed + * @return string Highest column name + */ + public function getHighestColumn($row = null) + { + if ($row == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['column']; + } + + $columnList = array(1); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($r != $row) { + continue; + } + $columnList[] = PHPExcel_Cell::columnIndexFromString($c); + } + return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1); + } + + /** + * Get highest worksheet row + * + * @param string $column Return the highest row for the specified column, + * or the highest row of any column if no column letter is passed + * @return int Highest row number + */ + public function getHighestRow($column = null) + { + if ($column == null) { + $colRow = $this->getHighestRowAndColumn(); + return $colRow['row']; + } + + $rowList = array(0); + foreach ($this->getCellList() as $coord) { + sscanf($coord,'%[A-Z]%d', $c, $r); + if ($c != $column) { + continue; + } + $rowList[] = $r; + } + + return max($rowList); + } + + + /** + * Generate a unique ID for cache referencing + * + * @return string Unique Reference + */ + protected function _getUniqueID() { + if (function_exists('posix_getpid')) { + $baseUnique = posix_getpid(); + } else { + $baseUnique = mt_rand(); + } + return uniqid($baseUnique,true); + } + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + $this->_parent = $parent; + if (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) { + $this->_currentObject->attach($this); + } + } // function copyCellCollection() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php new file mode 100755 index 0000000..5e9e382 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/DiscISAM.php @@ -0,0 +1,219 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + fseek($this->_fileHandle,0,SEEK_END); + $offset = ftell($this->_fileHandle); + fwrite($this->_fileHandle, serialize($this->_currentObject)); + $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, + 'sz' => ftell($this->_fileHandle) - $offset + ); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); + $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + // Copy the existing cell cache file + copy ($this->_fileName,$newFileName); + $this->_fileName = $newFileName; + // Open the copied cell cache file + $this->_fileHandle = fopen($this->_fileName,'a+'); + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $this->_cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== NULL)) + ? $arguments['dir'] + : PHPExcel_Shared_File::sys_get_temp_dir(); + + parent::__construct($parent); + if (is_null($this->_fileHandle)) { + $baseUnique = $this->_getUniqueID(); + $this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; + $this->_fileHandle = fopen($this->_fileName,'a+'); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_fileHandle)) { + fclose($this->_fileHandle); + unlink($this->_fileName); + } + $this->_fileHandle = null; + } // function __destruct() + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/ICache.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/ICache.php new file mode 100755 index 0000000..c3f2c14 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/ICache.php @@ -0,0 +1,112 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('igbinary_serialize')) { + return false; + } + + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php new file mode 100755 index 0000000..1becd2b --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/Memcache.php @@ -0,0 +1,312 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $obj = serialize($this->_currentObject); + if (!$this->_memcache->replace($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) { + if (!$this->_memcache->add($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in MemCache'); + } + } + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return void + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in Memcache + $success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache'); + if ($success === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (parent::isDataSet($pCoord)) { + $obj = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache'); + if ($obj === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from Memcache + $this->_memcache->delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache'); + if ($obj === false) { + // Entry no longer exists in Memcache, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in MemCache'); + } + if (!$this->_memcache->add($newCachePrefix.$cellID.'.cache',$obj,NULL,$this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in MemCache'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the Memcache cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost'; + $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if (is_null($this->_cachePrefix)) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + + // Set a new Memcache object and connect to the Memcache server + $this->_memcache = new Memcache(); + if (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { + throw new PHPExcel_Exception('Could not connect to MemCache server at '.$memcacheServer.':'.$memcachePort); + } + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Memcache error handler + * + * @param string $host Memcache server + * @param integer $port Memcache port + * @throws PHPExcel_Exception + */ + public function failureCallback($host, $port) { + throw new PHPExcel_Exception('memcache '.$host.':'.$port.' failed'); + } + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + $this->_memcache->delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('memcache_add')) { + return false; + } + + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/Memory.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/Memory.php new file mode 100755 index 0000000..32b5c5a --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/Memory.php @@ -0,0 +1,125 @@ +_cellCache[$pCoord] = $cell; + + // Set current entry to the new/updated entry + $this->_currentObjectID = $pCoord; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + $this->_currentObjectID = NULL; + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + // Return requested entry + return $this->_cellCache[$pCoord]; + } // function getCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + + $newCollection = array(); + foreach($this->_cellCache as $k => &$cell) { + $newCollection[$k] = clone $cell; + $newCollection[$k]->attach($this); + } + + $this->_cellCache = $newCollection; + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + // Because cells are all stored as intact objects in memory, we need to detach each one from the parent + foreach($this->_cellCache as $k => &$cell) { + $cell->detach(); + $this->_cellCache[$k] = null; + } + unset($cell); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php new file mode 100755 index 0000000..6186be2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/MemoryGZip.php @@ -0,0 +1,137 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject)); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php new file mode 100755 index 0000000..1f2e864 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/MemorySerialized.php @@ -0,0 +1,137 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($this->_cellCache[$pCoord]); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php new file mode 100755 index 0000000..285c7ea --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/PHPTemp.php @@ -0,0 +1,206 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + fseek($this->_fileHandle,0,SEEK_END); + $offset = ftell($this->_fileHandle); + fwrite($this->_fileHandle, serialize($this->_currentObject)); + $this->_cellCache[$this->_currentObjectID] = array('ptr' => $offset, + 'sz' => ftell($this->_fileHandle) - $offset + ); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + if (!isset($this->_cellCache[$pCoord])) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + fseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']); + $this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz'])); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Open a new stream for the cell cache data + $newFileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+'); + // Copy the existing cell cache data to the new stream + fseek($this->_fileHandle,0); + while (!feof($this->_fileHandle)) { + fwrite($newFileHandle,fread($this->_fileHandle, 1024)); + } + $this->_fileHandle = $newFileHandle; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the php://temp file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $this->_memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; + + parent::__construct($parent); + if (is_null($this->_fileHandle)) { + $this->_fileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+'); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_fileHandle)) { + fclose($this->_fileHandle); + } + $this->_fileHandle = null; + } // function __destruct() + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php new file mode 100755 index 0000000..775a9f2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite.php @@ -0,0 +1,306 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + if (!$this->_DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES('".$this->_currentObjectID."','".sqlite_escape_string(serialize($this->_currentObject))."')")) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + $query = "SELECT value FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC); + if ($cellResultSet === false) { + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } elseif ($cellResultSet->numRows() == 0) { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + $cellResult = $cellResultSet->fetchSingle(); + $this->_currentObject = unserialize($cellResult); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Is a value set for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return true; + } + + // Check if the requested entry exists in the cache + $query = "SELECT id FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + $cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC); + if ($cellResultSet === false) { + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } elseif ($cellResultSet->numRows() == 0) { + // Return null if requested entry doesn't exist in cache + return false; + } + return true; + } // function isDataSet() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = null; + } + + // Check if the requested entry exists in the cache + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$pCoord."'"; + if (!$this->_DBHandle->queryExec($query)) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + $this->_currentCellIsDirty = false; + } // function deleteCacheData() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $query = "DELETE FROM kvp_".$this->_TableName." WHERE id='".$toAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $query = "UPDATE kvp_".$this->_TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; + $result = $this->_DBHandle->exec($query); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + $query = "SELECT id FROM kvp_".$this->_TableName; + $cellIdsResult = $this->_DBHandle->unbufferedQuery($query,SQLITE_ASSOC); + if ($cellIdsResult === false) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + $cellKeys = array(); + foreach($cellIdsResult as $row) { + $cellKeys[] = $row['id']; + } + + return $cellKeys; + } // function getCellList() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + // Get a new id for the new table name + $tableName = str_replace('.','_',$this->_getUniqueID()); + if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->_TableName)) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + + // Copy the existing cell cache file + $this->_TableName = $tableName; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + */ + public function __construct(PHPExcel_Worksheet $parent) { + parent::__construct($parent); + if (is_null($this->_DBHandle)) { + $this->_TableName = str_replace('.','_',$this->_getUniqueID()); + $_DBName = ':memory:'; + + $this->_DBHandle = new SQLiteDatabase($_DBName); + if ($this->_DBHandle === false) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + if (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) + throw new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError())); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_DBHandle)) { + $this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName); + } + $this->_DBHandle = null; + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('sqlite_open')) { + return false; + } + + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php new file mode 100755 index 0000000..a2b8526 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/SQLite3.php @@ -0,0 +1,345 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT); + $this->_insertQuery->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB); + $result = $this->_insertQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + $this->_currentCellIsDirty = false; + } + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); + if ($cellResult === FALSE) { + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + if ($cellData === FALSE) { + // Return null if requested entry doesn't exist in cache + return NULL; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + + $this->_currentObject = unserialize($cellData['value']); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Is a value set for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return TRUE; + } + + // Check if the requested entry exists in the cache + $this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $cellResult = $this->_selectQuery->execute(); + if ($cellResult === FALSE) { + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); + + return ($cellData === FALSE) ? FALSE : TRUE; + } // function isDataSet() + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + $this->_currentObject->detach(); + $this->_currentObjectID = $this->_currentObject = NULL; + } + + // Check if the requested entry exists in the cache + $this->_deleteQuery->bindValue('id',$pCoord,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); + if ($result === FALSE) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $this->_currentCellIsDirty = FALSE; + } // function deleteCacheData() + + + /** + * Move a cell object from one address to another + * + * @param string $fromAddress Current address of the cell to move + * @param string $toAddress Destination address of the cell to move + * @return boolean + */ + public function moveCell($fromAddress, $toAddress) { + if ($fromAddress === $this->_currentObjectID) { + $this->_currentObjectID = $toAddress; + } + + $this->_deleteQuery->bindValue('id',$toAddress,SQLITE3_TEXT); + $result = $this->_deleteQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $this->_updateQuery->bindValue('toid',$toAddress,SQLITE3_TEXT); + $this->_updateQuery->bindValue('fromid',$fromAddress,SQLITE3_TEXT); + $result = $this->_updateQuery->execute(); + if ($result === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + return TRUE; + } // function moveCell() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + $query = "SELECT id FROM kvp_".$this->_TableName; + $cellIdsResult = $this->_DBHandle->query($query); + if ($cellIdsResult === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + $cellKeys = array(); + while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) { + $cellKeys[] = $row['id']; + } + + return $cellKeys; + } // function getCellList() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + $this->_currentCellIsDirty; + $this->_storeData(); + + // Get a new id for the new table name + $tableName = str_replace('.','_',$this->_getUniqueID()); + if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) + AS SELECT * FROM kvp_'.$this->_TableName)) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + + // Copy the existing cell cache file + $this->_TableName = $tableName; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + + // Close down the temporary cache file + $this->__destruct(); + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + */ + public function __construct(PHPExcel_Worksheet $parent) { + parent::__construct($parent); + if (is_null($this->_DBHandle)) { + $this->_TableName = str_replace('.','_',$this->_getUniqueID()); + $_DBName = ':memory:'; + + $this->_DBHandle = new SQLite3($_DBName); + if ($this->_DBHandle === false) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + if (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) + throw new PHPExcel_Exception($this->_DBHandle->lastErrorMsg()); + } + + $this->_selectQuery = $this->_DBHandle->prepare("SELECT value FROM kvp_".$this->_TableName." WHERE id = :id"); + $this->_insertQuery = $this->_DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->_TableName." VALUES(:id,:data)"); + $this->_updateQuery = $this->_DBHandle->prepare("UPDATE kvp_".$this->_TableName." SET id=:toId WHERE id=:fromId"); + $this->_deleteQuery = $this->_DBHandle->prepare("DELETE FROM kvp_".$this->_TableName." WHERE id = :id"); + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + if (!is_null($this->_DBHandle)) { + $this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName); + $this->_DBHandle->close(); + } + $this->_DBHandle = null; + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!class_exists('SQLite3',FALSE)) { + return false; + } + + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php b/extend/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php new file mode 100755 index 0000000..f7c55a7 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorage/Wincache.php @@ -0,0 +1,294 @@ +_currentCellIsDirty && !empty($this->_currentObjectID)) { + $this->_currentObject->detach(); + + $obj = serialize($this->_currentObject); + if (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) { + if (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + } + } else { + if (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache'); + } + } + $this->_currentCellIsDirty = false; + } + + $this->_currentObjectID = $this->_currentObject = null; + } // function _storeData() + + + /** + * Add or Update a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to update + * @param PHPExcel_Cell $cell Cell to update + * @return void + * @throws PHPExcel_Exception + */ + public function addCacheData($pCoord, PHPExcel_Cell $cell) { + if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) { + $this->_storeData(); + } + $this->_cellCache[$pCoord] = true; + + $this->_currentObjectID = $pCoord; + $this->_currentObject = $cell; + $this->_currentCellIsDirty = true; + + return $cell; + } // function addCacheData() + + + /** + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? + * + * @param string $pCoord Coordinate address of the cell to check + * @return boolean + */ + public function isDataSet($pCoord) { + // Check if the requested entry is the current object, or exists in the cache + if (parent::isDataSet($pCoord)) { + if ($this->_currentObjectID == $pCoord) { + return true; + } + // Check if the requested entry still exists in cache + $success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache'); + if ($success === false) { + // Entry no longer exists in Wincache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); + } + return true; + } + return false; + } // function isDataSet() + + + /** + * Get cell at a specific coordinate + * + * @param string $pCoord Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found, or null if not found + */ + public function getCacheData($pCoord) { + if ($pCoord === $this->_currentObjectID) { + return $this->_currentObject; + } + $this->_storeData(); + + // Check if the entry that has been requested actually exists + $obj = null; + if (parent::isDataSet($pCoord)) { + $success = false; + $obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success); + if ($success === false) { + // Entry no longer exists in WinCache, so clear it from the cache array + parent::deleteCacheData($pCoord); + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); + } + } else { + // Return null if requested entry doesn't exist in cache + return null; + } + + // Set current entry to the requested entry + $this->_currentObjectID = $pCoord; + $this->_currentObject = unserialize($obj); + // Re-attach this as the cell's parent + $this->_currentObject->attach($this); + + // Return requested entry + return $this->_currentObject; + } // function getCacheData() + + + /** + * Get a list of all cell addresses currently held in cache + * + * @return array of string + */ + public function getCellList() { + if ($this->_currentObjectID !== null) { + $this->_storeData(); + } + + return parent::getCellList(); + } + + + /** + * Delete a cell in cache identified by coordinate address + * + * @param string $pCoord Coordinate address of the cell to delete + * @throws PHPExcel_Exception + */ + public function deleteCacheData($pCoord) { + // Delete the entry from Wincache + wincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache'); + + // Delete the entry from our cell address array + parent::deleteCacheData($pCoord); + } // function deleteCacheData() + + + /** + * Clone the cell collection + * + * @param PHPExcel_Worksheet $parent The new worksheet + * @return void + */ + public function copyCellCollection(PHPExcel_Worksheet $parent) { + parent::copyCellCollection($parent); + // Get a new id for the new file name + $baseUnique = $this->_getUniqueID(); + $newCachePrefix = substr(md5($baseUnique),0,8).'.'; + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + if ($cellID != $this->_currentObjectID) { + $success = false; + $obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success); + if ($success === false) { + // Entry no longer exists in WinCache, so clear it from the cache array + parent::deleteCacheData($cellID); + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache'); + } + if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) { + $this->__destruct(); + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache'); + } + } + } + $this->_cachePrefix = $newCachePrefix; + } // function copyCellCollection() + + + /** + * Clear the cell collection and disconnect from our parent + * + * @return void + */ + public function unsetWorksheetCells() { + if(!is_null($this->_currentObject)) { + $this->_currentObject->detach(); + $this->_currentObject = $this->_currentObjectID = null; + } + + // Flush the WinCache cache + $this->__destruct(); + + $this->_cellCache = array(); + + // detach ourself from the worksheet, so that it can then delete this object successfully + $this->_parent = null; + } // function unsetWorksheetCells() + + + /** + * Initialise this new cell collection + * + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection + * @param array of mixed $arguments Additional initialisation arguments + */ + public function __construct(PHPExcel_Worksheet $parent, $arguments) { + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; + + if (is_null($this->_cachePrefix)) { + $baseUnique = $this->_getUniqueID(); + $this->_cachePrefix = substr(md5($baseUnique),0,8).'.'; + $this->_cacheTime = $cacheTime; + + parent::__construct($parent); + } + } // function __construct() + + + /** + * Destroy this cell collection + */ + public function __destruct() { + $cacheList = $this->getCellList(); + foreach($cacheList as $cellID) { + wincache_ucache_delete($this->_cachePrefix.$cellID.'.cache'); + } + } // function __destruct() + + + /** + * Identify whether the caching method is currently available + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build + * + * @return boolean + */ + public static function cacheMethodIsAvailable() { + if (!function_exists('wincache_ucache_add')) { + return false; + } + + return true; + } + +} diff --git a/extend/phpexcel/PHPExcel/CachedObjectStorageFactory.php b/extend/phpexcel/PHPExcel/CachedObjectStorageFactory.php new file mode 100755 index 0000000..6c3ec15 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CachedObjectStorageFactory.php @@ -0,0 +1,251 @@ + array( + ), + self::cache_in_memory_gzip => array( + ), + self::cache_in_memory_serialized => array( + ), + self::cache_igbinary => array( + ), + self::cache_to_phpTemp => array( 'memoryCacheSize' => '1MB' + ), + self::cache_to_discISAM => array( 'dir' => NULL + ), + self::cache_to_apc => array( 'cacheTime' => 600 + ), + self::cache_to_memcache => array( 'memcacheServer' => 'localhost', + 'memcachePort' => 11211, + 'cacheTime' => 600 + ), + self::cache_to_wincache => array( 'cacheTime' => 600 + ), + self::cache_to_sqlite => array( + ), + self::cache_to_sqlite3 => array( + ), + ); + + + /** + * Arguments for the active cache storage method + * + * @var array of mixed array + */ + private static $_storageMethodParameters = array(); + + + /** + * Return the current cache storage method + * + * @return string|NULL + **/ + public static function getCacheStorageMethod() + { + return self::$_cacheStorageMethod; + } // function getCacheStorageMethod() + + + /** + * Return the current cache storage class + * + * @return PHPExcel_CachedObjectStorage_ICache|NULL + **/ + public static function getCacheStorageClass() + { + return self::$_cacheStorageClass; + } // function getCacheStorageClass() + + + /** + * Return the list of all possible cache storage methods + * + * @return string[] + **/ + public static function getAllCacheStorageMethods() + { + return self::$_storageMethods; + } // function getCacheStorageMethods() + + + /** + * Return the list of all available cache storage methods + * + * @return string[] + **/ + public static function getCacheStorageMethods() + { + $activeMethods = array(); + foreach(self::$_storageMethods as $storageMethod) { + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod; + if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) { + $activeMethods[] = $storageMethod; + } + } + return $activeMethods; + } // function getCacheStorageMethods() + + + /** + * Identify the cache storage method to use + * + * @param string $method Name of the method to use for cell cacheing + * @param array of mixed $arguments Additional arguments to pass to the cell caching class + * when instantiating + * @return boolean + **/ + public static function initialize($method = self::cache_in_memory, $arguments = array()) + { + if (!in_array($method,self::$_storageMethods)) { + return FALSE; + } + + $cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method; + if (!call_user_func(array( $cacheStorageClass, + 'cacheMethodIsAvailable'))) { + return FALSE; + } + + self::$_storageMethodParameters[$method] = self::$_storageMethodDefaultParameters[$method]; + foreach($arguments as $k => $v) { + if (array_key_exists($k, self::$_storageMethodParameters[$method])) { + self::$_storageMethodParameters[$method][$k] = $v; + } + } + + if (self::$_cacheStorageMethod === NULL) { + self::$_cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method; + self::$_cacheStorageMethod = $method; + } + return TRUE; + } // function initialize() + + + /** + * Initialise the cache storage + * + * @param PHPExcel_Worksheet $parent Enable cell caching for this worksheet + * @return PHPExcel_CachedObjectStorage_ICache + **/ + public static function getInstance(PHPExcel_Worksheet $parent) + { + $cacheMethodIsAvailable = TRUE; + if (self::$_cacheStorageMethod === NULL) { + $cacheMethodIsAvailable = self::initialize(); + } + + if ($cacheMethodIsAvailable) { + $instance = new self::$_cacheStorageClass( $parent, + self::$_storageMethodParameters[self::$_cacheStorageMethod] + ); + if ($instance !== NULL) { + return $instance; + } + } + + return FALSE; + } // function getInstance() + + + /** + * Clear the cache storage + * + **/ + public static function finalize() + { + self::$_cacheStorageMethod = NULL; + self::$_cacheStorageClass = NULL; + self::$_storageMethodParameters = array(); + } + +} diff --git a/extend/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php b/extend/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php new file mode 100755 index 0000000..0259193 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CalcEngine/CyclicReferenceStack.php @@ -0,0 +1,98 @@ +_stack); + } + + /** + * Push a new entry onto the stack + * + * @param mixed $value + */ + public function push($value) { + $this->_stack[] = $value; + } // function push() + + /** + * Pop the last entry from the stack + * + * @return mixed + */ + public function pop() { + return array_pop($this->_stack); + } // function pop() + + /** + * Test to see if a specified entry exists on the stack + * + * @param mixed $value The value to test + */ + public function onStack($value) { + return in_array($value, $this->_stack); + } + + /** + * Clear the stack + */ + public function clear() { + $this->_stack = array(); + } // function push() + + /** + * Return an array of all entries on the stack + * + * @return mixed[] + */ + public function showStack() { + return $this->_stack; + } + +} // class PHPExcel_CalcEngine_CyclicReferenceStack diff --git a/extend/phpexcel/PHPExcel/CalcEngine/Logger.php b/extend/phpexcel/PHPExcel/CalcEngine/Logger.php new file mode 100755 index 0000000..2048df3 --- /dev/null +++ b/extend/phpexcel/PHPExcel/CalcEngine/Logger.php @@ -0,0 +1,153 @@ +_cellStack = $stack; + } + + /** + * Enable/Disable Calculation engine logging + * + * @param boolean $pValue + */ + public function setWriteDebugLog($pValue = FALSE) { + $this->_writeDebugLog = $pValue; + } + + /** + * Return whether calculation engine logging is enabled or disabled + * + * @return boolean + */ + public function getWriteDebugLog() { + return $this->_writeDebugLog; + } + + /** + * Enable/Disable echoing of debug log information + * + * @param boolean $pValue + */ + public function setEchoDebugLog($pValue = FALSE) { + $this->_echoDebugLog = $pValue; + } + + /** + * Return whether echoing of debug log information is enabled or disabled + * + * @return boolean + */ + public function getEchoDebugLog() { + return $this->_echoDebugLog; + } + + /** + * Write an entry to the calculation engine debug log + */ + public function writeDebugLog() { + // Only write the debug log if logging is enabled + if ($this->_writeDebugLog) { + $message = implode(func_get_args()); + $cellReference = implode(' -> ', $this->_cellStack->showStack()); + if ($this->_echoDebugLog) { + echo $cellReference, + ($this->_cellStack->count() > 0 ? ' => ' : ''), + $message, + PHP_EOL; + } + $this->_debugLog[] = $cellReference . + ($this->_cellStack->count() > 0 ? ' => ' : '') . + $message; + } + } // function _writeDebug() + + /** + * Clear the calculation engine debug log + */ + public function clearLog() { + $this->_debugLog = array(); + } // function flushLogger() + + /** + * Return the calculation engine debug log + * + * @return string[] + */ + public function getLog() { + return $this->_debugLog; + } // function flushLogger() + +} // class PHPExcel_CalcEngine_Logger + diff --git a/extend/phpexcel/PHPExcel/Calculation.php b/extend/phpexcel/PHPExcel/Calculation.php new file mode 100755 index 0000000..b609b0d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation.php @@ -0,0 +1,3933 @@ +=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d{1,7})'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','((([^\s,!&%^\/\*\+<>=-]*)|(\'[^\']*\')|(\"[^\"]*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } else { + // Cell reference (cell or range of cells, with or without a sheet reference) + define('CALCULATION_REGEXP_CELLREF','(((\w*)|(\'[^\']*\')|(\"[^\"]*\"))!)?\$?([a-z]{1,3})\$?(\d+)'); + // Named Range of cells + define('CALCULATION_REGEXP_NAMEDRANGE','(((\w*)|(\'.*\')|(\".*\"))!)?([_A-Z][_A-Z0-9\.]*)'); + } +} + + +/** + * PHPExcel_Calculation (Multiton) + * + * @category PHPExcel + * @package PHPExcel_Calculation + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Calculation { + + /** Constants */ + /** Regular Expressions */ + // Numeric operand + const CALCULATION_REGEXP_NUMBER = '[-+]?\d*\.?\d+(e[-+]?\d+)?'; + // String operand + const CALCULATION_REGEXP_STRING = '"(?:[^"]|"")*"'; + // Opening bracket + const CALCULATION_REGEXP_OPENBRACE = '\('; + // Function (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it) + const CALCULATION_REGEXP_FUNCTION = '@?([A-Z][A-Z0-9\.]*)[\s]*\('; + // Cell reference (cell or range of cells, with or without a sheet reference) + const CALCULATION_REGEXP_CELLREF = CALCULATION_REGEXP_CELLREF; + // Named Range of cells + const CALCULATION_REGEXP_NAMEDRANGE = CALCULATION_REGEXP_NAMEDRANGE; + // Error + const CALCULATION_REGEXP_ERROR = '\#[A-Z][A-Z0_\/]*[!\?]?'; + + + /** constants */ + const RETURN_ARRAY_AS_ERROR = 'error'; + const RETURN_ARRAY_AS_VALUE = 'value'; + const RETURN_ARRAY_AS_ARRAY = 'array'; + + private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; + + + /** + * Instance of this class + * + * @access private + * @var PHPExcel_Calculation + */ + private static $_instance; + + + /** + * Instance of the workbook this Calculation Engine is using + * + * @access private + * @var PHPExcel + */ + private $_workbook; + + /** + * List of instances of the calculation engine that we've instantiated for individual workbooks + * + * @access private + * @var PHPExcel_Calculation[] + */ + private static $_workbookSets; + + /** + * Calculation cache + * + * @access private + * @var array + */ + private $_calculationCache = array (); + + + /** + * Calculation cache enabled + * + * @access private + * @var boolean + */ + private $_calculationCacheEnabled = TRUE; + + + /** + * List of operators that can be used within formulae + * The true/false value indicates whether it is a binary operator or a unary operator + * + * @access private + * @var array + */ + private static $_operators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '%' => FALSE, '~' => FALSE, + '>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, + '<=' => TRUE, '<>' => TRUE, '|' => TRUE, ':' => TRUE + ); + + + /** + * List of binary operators (those that expect two operands) + * + * @access private + * @var array + */ + private static $_binaryOperators = array('+' => TRUE, '-' => TRUE, '*' => TRUE, '/' => TRUE, + '^' => TRUE, '&' => TRUE, '>' => TRUE, '<' => TRUE, + '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE, + '|' => TRUE, ':' => TRUE + ); + + /** + * The debug log generated by the calculation engine + * + * @access private + * @var PHPExcel_CalcEngine_Logger + * + */ + private $debugLog; + + /** + * Flag to determine how formula errors should be handled + * If true, then a user error will be triggered + * If false, then an exception will be thrown + * + * @access public + * @var boolean + * + */ + public $suppressFormulaErrors = FALSE; + + /** + * Error message for any error that was raised/thrown by the calculation engine + * + * @access public + * @var string + * + */ + public $formulaError = NULL; + + /** + * An array of the nested cell references accessed by the calculation engine, used for the debug log + * + * @access private + * @var array of string + * + */ + private $_cyclicReferenceStack; + + /** + * Current iteration counter for cyclic formulae + * If the value is 0 (or less) then cyclic formulae will throw an exception, + * otherwise they will iterate to the limit defined here before returning a result + * + * @var integer + * + */ + private $_cyclicFormulaCount = 0; + + private $_cyclicFormulaCell = ''; + + /** + * Number of iterations for cyclic formulae + * + * @var integer + * + */ + public $cyclicFormulaCount = 0; + + /** + * Precision used for calculations + * + * @var integer + * + */ + private $_savedPrecision = 14; + + + /** + * The current locale setting + * + * @var string + * + */ + private static $_localeLanguage = 'en_us'; // US English (default locale) + + /** + * List of available locale settings + * Note that this is read for the locale subdirectory only when requested + * + * @var string[] + * + */ + private static $_validLocaleLanguages = array( 'en' // English (default language) + ); + /** + * Locale-specific argument separator for function arguments + * + * @var string + * + */ + private static $_localeArgumentSeparator = ','; + private static $_localeFunctions = array(); + + /** + * Locale-specific translations for Excel constants (True, False and Null) + * + * @var string[] + * + */ + public static $_localeBoolean = array( 'TRUE' => 'TRUE', + 'FALSE' => 'FALSE', + 'NULL' => 'NULL' + ); + + + /** + * Excel constant string translations to their PHP equivalents + * Constant conversion from text name/value to actual (datatyped) value + * + * @var string[] + * + */ + private static $_ExcelConstants = array('TRUE' => TRUE, + 'FALSE' => FALSE, + 'NULL' => NULL + ); + + // PHPExcel functions + private static $_PHPExcelFunctions = array( // PHPExcel functions + 'ABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'abs', + 'argumentCount' => '1' + ), + 'ACCRINT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINT', + 'argumentCount' => '4-7' + ), + 'ACCRINTM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ACCRINTM', + 'argumentCount' => '3-5' + ), + 'ACOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acos', + 'argumentCount' => '1' + ), + 'ACOSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'acosh', + 'argumentCount' => '1' + ), + 'ADDRESS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CELL_ADDRESS', + 'argumentCount' => '2-5' + ), + 'AMORDEGRC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORDEGRC', + 'argumentCount' => '6,7' + ), + 'AMORLINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::AMORLINC', + 'argumentCount' => '6,7' + ), + 'AND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_AND', + 'argumentCount' => '1+' + ), + 'AREAS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ASIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asin', + 'argumentCount' => '1' + ), + 'ASINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'asinh', + 'argumentCount' => '1' + ), + 'ATAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atan', + 'argumentCount' => '1' + ), + 'ATAN2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ATAN2', + 'argumentCount' => '2' + ), + 'ATANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'atanh', + 'argumentCount' => '1' + ), + 'AVEDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVEDEV', + 'argumentCount' => '1+' + ), + 'AVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGE', + 'argumentCount' => '1+' + ), + 'AVERAGEA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEA', + 'argumentCount' => '1+' + ), + 'AVERAGEIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::AVERAGEIF', + 'argumentCount' => '2,3' + ), + 'AVERAGEIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3+' + ), + 'BAHTTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'BESSELI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELI', + 'argumentCount' => '2' + ), + 'BESSELJ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELJ', + 'argumentCount' => '2' + ), + 'BESSELK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELK', + 'argumentCount' => '2' + ), + 'BESSELY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BESSELY', + 'argumentCount' => '2' + ), + 'BETADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETADIST', + 'argumentCount' => '3-5' + ), + 'BETAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BETAINV', + 'argumentCount' => '3-5' + ), + 'BIN2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTODEC', + 'argumentCount' => '1' + ), + 'BIN2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOHEX', + 'argumentCount' => '1,2' + ), + 'BIN2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::BINTOOCT', + 'argumentCount' => '1,2' + ), + 'BINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::BINOMDIST', + 'argumentCount' => '4' + ), + 'CEILING' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::CEILING', + 'argumentCount' => '2' + ), + 'CELL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1,2' + ), + 'CHAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CHARACTER', + 'argumentCount' => '1' + ), + 'CHIDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIDIST', + 'argumentCount' => '2' + ), + 'CHIINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CHIINV', + 'argumentCount' => '2' + ), + 'CHITEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'CHOOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::CHOOSE', + 'argumentCount' => '2+' + ), + 'CLEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE', + 'argumentCount' => '1' + ), + 'CODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::ASCIICODE', + 'argumentCount' => '1' + ), + 'COLUMN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMN', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'COLUMNS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::COLUMNS', + 'argumentCount' => '1' + ), + 'COMBIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::COMBIN', + 'argumentCount' => '2' + ), + 'COMPLEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::COMPLEX', + 'argumentCount' => '2,3' + ), + 'CONCATENATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::CONCATENATE', + 'argumentCount' => '1+' + ), + 'CONFIDENCE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CONFIDENCE', + 'argumentCount' => '3' + ), + 'CONVERT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::CONVERTUOM', + 'argumentCount' => '3' + ), + 'CORREL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'COS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cos', + 'argumentCount' => '1' + ), + 'COSH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'cosh', + 'argumentCount' => '1' + ), + 'COUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNT', + 'argumentCount' => '1+' + ), + 'COUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTA', + 'argumentCount' => '1+' + ), + 'COUNTBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTBLANK', + 'argumentCount' => '1' + ), + 'COUNTIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COUNTIF', + 'argumentCount' => '2' + ), + 'COUNTIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'COUPDAYBS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYBS', + 'argumentCount' => '3,4' + ), + 'COUPDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYS', + 'argumentCount' => '3,4' + ), + 'COUPDAYSNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPDAYSNC', + 'argumentCount' => '3,4' + ), + 'COUPNCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNCD', + 'argumentCount' => '3,4' + ), + 'COUPNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPNUM', + 'argumentCount' => '3,4' + ), + 'COUPPCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::COUPPCD', + 'argumentCount' => '3,4' + ), + 'COVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::COVAR', + 'argumentCount' => '2' + ), + 'CRITBINOM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CRITBINOM', + 'argumentCount' => '3' + ), + 'CUBEKPIMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEMEMBERPROPERTY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBERANKEDMEMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBESETCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUBEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_CUBE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'CUMIPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMIPMT', + 'argumentCount' => '6' + ), + 'CUMPRINC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::CUMPRINC', + 'argumentCount' => '6' + ), + 'DATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATE', + 'argumentCount' => '3' + ), + 'DATEDIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEDIF', + 'argumentCount' => '2,3' + ), + 'DATEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATEVALUE', + 'argumentCount' => '1' + ), + 'DAVERAGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DAVERAGE', + 'argumentCount' => '3' + ), + 'DAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFMONTH', + 'argumentCount' => '1' + ), + 'DAYS360' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYS360', + 'argumentCount' => '2,3' + ), + 'DB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DB', + 'argumentCount' => '4,5' + ), + 'DCOUNT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNT', + 'argumentCount' => '3' + ), + 'DCOUNTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DCOUNTA', + 'argumentCount' => '3' + ), + 'DDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DDB', + 'argumentCount' => '4,5' + ), + 'DEC2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOBIN', + 'argumentCount' => '1,2' + ), + 'DEC2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOHEX', + 'argumentCount' => '1,2' + ), + 'DEC2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DECTOOCT', + 'argumentCount' => '1,2' + ), + 'DEGREES' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'rad2deg', + 'argumentCount' => '1' + ), + 'DELTA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::DELTA', + 'argumentCount' => '1,2' + ), + 'DEVSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::DEVSQ', + 'argumentCount' => '1+' + ), + 'DGET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DGET', + 'argumentCount' => '3' + ), + 'DISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DISC', + 'argumentCount' => '4,5' + ), + 'DMAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMAX', + 'argumentCount' => '3' + ), + 'DMIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DMIN', + 'argumentCount' => '3' + ), + 'DOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::DOLLAR', + 'argumentCount' => '1,2' + ), + 'DOLLARDE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARDE', + 'argumentCount' => '2' + ), + 'DOLLARFR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::DOLLARFR', + 'argumentCount' => '2' + ), + 'DPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DPRODUCT', + 'argumentCount' => '3' + ), + 'DSTDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEV', + 'argumentCount' => '3' + ), + 'DSTDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSTDEVP', + 'argumentCount' => '3' + ), + 'DSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DSUM', + 'argumentCount' => '3' + ), + 'DURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'DVAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVAR', + 'argumentCount' => '3' + ), + 'DVARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATABASE, + 'functionCall' => 'PHPExcel_Calculation_Database::DVARP', + 'argumentCount' => '3' + ), + 'EDATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EDATE', + 'argumentCount' => '2' + ), + 'EFFECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::EFFECT', + 'argumentCount' => '2' + ), + 'EOMONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::EOMONTH', + 'argumentCount' => '2' + ), + 'ERF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERF', + 'argumentCount' => '1,2' + ), + 'ERFC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::ERFC', + 'argumentCount' => '1' + ), + 'ERROR.TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::ERROR_TYPE', + 'argumentCount' => '1' + ), + 'EVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::EVEN', + 'argumentCount' => '1' + ), + 'EXACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'EXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'exp', + 'argumentCount' => '1' + ), + 'EXPONDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::EXPONDIST', + 'argumentCount' => '3' + ), + 'FACT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACT', + 'argumentCount' => '1' + ), + 'FACTDOUBLE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FACTDOUBLE', + 'argumentCount' => '1' + ), + 'FALSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::FALSE', + 'argumentCount' => '0' + ), + 'FDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FIND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHSENSITIVE', + 'argumentCount' => '2,3' + ), + 'FINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3' + ), + 'FISHER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHER', + 'argumentCount' => '1' + ), + 'FISHERINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FISHERINV', + 'argumentCount' => '1' + ), + 'FIXED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::FIXEDFORMAT', + 'argumentCount' => '1-3' + ), + 'FLOOR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::FLOOR', + 'argumentCount' => '2' + ), + 'FORECAST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::FORECAST', + 'argumentCount' => '3' + ), + 'FREQUENCY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'FV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FV', + 'argumentCount' => '3-5' + ), + 'FVSCHEDULE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::FVSCHEDULE', + 'argumentCount' => '2' + ), + 'GAMMADIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMADIST', + 'argumentCount' => '4' + ), + 'GAMMAINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMAINV', + 'argumentCount' => '3' + ), + 'GAMMALN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GAMMALN', + 'argumentCount' => '1' + ), + 'GCD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::GCD', + 'argumentCount' => '1+' + ), + 'GEOMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GEOMEAN', + 'argumentCount' => '1+' + ), + 'GESTEP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::GESTEP', + 'argumentCount' => '1,2' + ), + 'GETPIVOTDATA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'GROWTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::GROWTH', + 'argumentCount' => '1-4' + ), + 'HARMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HARMEAN', + 'argumentCount' => '1+' + ), + 'HEX2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOBIN', + 'argumentCount' => '1,2' + ), + 'HEX2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTODEC', + 'argumentCount' => '1' + ), + 'HEX2OCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::HEXTOOCT', + 'argumentCount' => '1,2' + ), + 'HLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HLOOKUP', + 'argumentCount' => '3,4' + ), + 'HOUR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::HOUROFDAY', + 'argumentCount' => '1' + ), + 'HYPERLINK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::HYPERLINK', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'HYPGEOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::HYPGEOMDIST', + 'argumentCount' => '4' + ), + 'IF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::STATEMENT_IF', + 'argumentCount' => '1-3' + ), + 'IFERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::IFERROR', + 'argumentCount' => '2' + ), + 'IMABS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMABS', + 'argumentCount' => '1' + ), + 'IMAGINARY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMAGINARY', + 'argumentCount' => '1' + ), + 'IMARGUMENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMARGUMENT', + 'argumentCount' => '1' + ), + 'IMCONJUGATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCONJUGATE', + 'argumentCount' => '1' + ), + 'IMCOS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMCOS', + 'argumentCount' => '1' + ), + 'IMDIV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMDIV', + 'argumentCount' => '2' + ), + 'IMEXP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMEXP', + 'argumentCount' => '1' + ), + 'IMLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLN', + 'argumentCount' => '1' + ), + 'IMLOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG10', + 'argumentCount' => '1' + ), + 'IMLOG2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMLOG2', + 'argumentCount' => '1' + ), + 'IMPOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPOWER', + 'argumentCount' => '2' + ), + 'IMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMPRODUCT', + 'argumentCount' => '1+' + ), + 'IMREAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMREAL', + 'argumentCount' => '1' + ), + 'IMSIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSIN', + 'argumentCount' => '1' + ), + 'IMSQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSQRT', + 'argumentCount' => '1' + ), + 'IMSUB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUB', + 'argumentCount' => '2' + ), + 'IMSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::IMSUM', + 'argumentCount' => '1+' + ), + 'INDEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDEX', + 'argumentCount' => '1-4' + ), + 'INDIRECT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::INDIRECT', + 'argumentCount' => '1,2', + 'passCellReference'=> TRUE + ), + 'INFO' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'INT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::INT', + 'argumentCount' => '1' + ), + 'INTERCEPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::INTERCEPT', + 'argumentCount' => '2' + ), + 'INTRATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::INTRATE', + 'argumentCount' => '4,5' + ), + 'IPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IPMT', + 'argumentCount' => '4-6' + ), + 'IRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::IRR', + 'argumentCount' => '1,2' + ), + 'ISBLANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_BLANK', + 'argumentCount' => '1' + ), + 'ISERR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERR', + 'argumentCount' => '1' + ), + 'ISERROR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ERROR', + 'argumentCount' => '1' + ), + 'ISEVEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_EVEN', + 'argumentCount' => '1' + ), + 'ISLOGICAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_LOGICAL', + 'argumentCount' => '1' + ), + 'ISNA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NA', + 'argumentCount' => '1' + ), + 'ISNONTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NONTEXT', + 'argumentCount' => '1' + ), + 'ISNUMBER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_NUMBER', + 'argumentCount' => '1' + ), + 'ISODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_ODD', + 'argumentCount' => '1' + ), + 'ISPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::ISPMT', + 'argumentCount' => '4' + ), + 'ISREF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'ISTEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::IS_TEXT', + 'argumentCount' => '1' + ), + 'JIS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'KURT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::KURT', + 'argumentCount' => '1+' + ), + 'LARGE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LARGE', + 'argumentCount' => '2' + ), + 'LCM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LCM', + 'argumentCount' => '1+' + ), + 'LEFT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEFTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LEFT', + 'argumentCount' => '1,2' + ), + 'LEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LENB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::STRINGLENGTH', + 'argumentCount' => '1' + ), + 'LINEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LINEST', + 'argumentCount' => '1-4' + ), + 'LN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log', + 'argumentCount' => '1' + ), + 'LOG' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::LOG_BASE', + 'argumentCount' => '1,2' + ), + 'LOG10' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'log10', + 'argumentCount' => '1' + ), + 'LOGEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGEST', + 'argumentCount' => '1-4' + ), + 'LOGINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGINV', + 'argumentCount' => '3' + ), + 'LOGNORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::LOGNORMDIST', + 'argumentCount' => '3' + ), + 'LOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::LOOKUP', + 'argumentCount' => '2,3' + ), + 'LOWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::LOWERCASE', + 'argumentCount' => '1' + ), + 'MATCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::MATCH', + 'argumentCount' => '2,3' + ), + 'MAX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAX', + 'argumentCount' => '1+' + ), + 'MAXA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXA', + 'argumentCount' => '1+' + ), + 'MAXIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MAXIF', + 'argumentCount' => '2+' + ), + 'MDETERM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MDETERM', + 'argumentCount' => '1' + ), + 'MDURATION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5,6' + ), + 'MEDIAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MEDIAN', + 'argumentCount' => '1+' + ), + 'MEDIANIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2+' + ), + 'MID' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::MID', + 'argumentCount' => '3' + ), + 'MIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MIN', + 'argumentCount' => '1+' + ), + 'MINA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINA', + 'argumentCount' => '1+' + ), + 'MINIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MINIF', + 'argumentCount' => '2+' + ), + 'MINUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MINUTEOFHOUR', + 'argumentCount' => '1' + ), + 'MINVERSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MINVERSE', + 'argumentCount' => '1' + ), + 'MIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::MIRR', + 'argumentCount' => '3' + ), + 'MMULT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MMULT', + 'argumentCount' => '2' + ), + 'MOD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MOD', + 'argumentCount' => '2' + ), + 'MODE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::MODE', + 'argumentCount' => '1+' + ), + 'MONTH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::MONTHOFYEAR', + 'argumentCount' => '1' + ), + 'MROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MROUND', + 'argumentCount' => '2' + ), + 'MULTINOMIAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::MULTINOMIAL', + 'argumentCount' => '1+' + ), + 'N' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::N', + 'argumentCount' => '1' + ), + 'NA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::NA', + 'argumentCount' => '0' + ), + 'NEGBINOMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NEGBINOMDIST', + 'argumentCount' => '3' + ), + 'NETWORKDAYS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::NETWORKDAYS', + 'argumentCount' => '2+' + ), + 'NOMINAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NOMINAL', + 'argumentCount' => '2' + ), + 'NORMDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMDIST', + 'argumentCount' => '4' + ), + 'NORMINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMINV', + 'argumentCount' => '3' + ), + 'NORMSDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSDIST', + 'argumentCount' => '1' + ), + 'NORMSINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::NORMSINV', + 'argumentCount' => '1' + ), + 'NOT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::NOT', + 'argumentCount' => '1' + ), + 'NOW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATETIMENOW', + 'argumentCount' => '0' + ), + 'NPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPER', + 'argumentCount' => '3-5' + ), + 'NPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::NPV', + 'argumentCount' => '2+' + ), + 'OCT2BIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOBIN', + 'argumentCount' => '1,2' + ), + 'OCT2DEC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTODEC', + 'argumentCount' => '1' + ), + 'OCT2HEX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_ENGINEERING, + 'functionCall' => 'PHPExcel_Calculation_Engineering::OCTTOHEX', + 'argumentCount' => '1,2' + ), + 'ODD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ODD', + 'argumentCount' => '1' + ), + 'ODDFPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDFYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '8,9' + ), + 'ODDLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'ODDLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '7,8' + ), + 'OFFSET' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::OFFSET', + 'argumentCount' => '3,5', + 'passCellReference'=> TRUE, + 'passByReference' => array(TRUE) + ), + 'OR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::LOGICAL_OR', + 'argumentCount' => '1+' + ), + 'PEARSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::CORREL', + 'argumentCount' => '2' + ), + 'PERCENTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTILE', + 'argumentCount' => '2' + ), + 'PERCENTRANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERCENTRANK', + 'argumentCount' => '2,3' + ), + 'PERMUT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::PERMUT', + 'argumentCount' => '2' + ), + 'PHONETIC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'PI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'pi', + 'argumentCount' => '0' + ), + 'PMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PMT', + 'argumentCount' => '3-5' + ), + 'POISSON' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::POISSON', + 'argumentCount' => '3' + ), + 'POWER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::POWER', + 'argumentCount' => '2' + ), + 'PPMT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PPMT', + 'argumentCount' => '4-6' + ), + 'PRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICE', + 'argumentCount' => '6,7' + ), + 'PRICEDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEDISC', + 'argumentCount' => '4,5' + ), + 'PRICEMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PRICEMAT', + 'argumentCount' => '5,6' + ), + 'PROB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '3,4' + ), + 'PRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::PRODUCT', + 'argumentCount' => '1+' + ), + 'PROPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::PROPERCASE', + 'argumentCount' => '1' + ), + 'PV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::PV', + 'argumentCount' => '3-5' + ), + 'QUARTILE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::QUARTILE', + 'argumentCount' => '2' + ), + 'QUOTIENT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::QUOTIENT', + 'argumentCount' => '2' + ), + 'RADIANS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'deg2rad', + 'argumentCount' => '1' + ), + 'RAND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '0' + ), + 'RANDBETWEEN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::RAND', + 'argumentCount' => '2' + ), + 'RANK' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RANK', + 'argumentCount' => '2,3' + ), + 'RATE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RATE', + 'argumentCount' => '3-6' + ), + 'RECEIVED' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::RECEIVED', + 'argumentCount' => '4-5' + ), + 'REPLACE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPLACEB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::REPLACE', + 'argumentCount' => '4' + ), + 'REPT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'str_repeat', + 'argumentCount' => '2' + ), + 'RIGHT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'RIGHTB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RIGHT', + 'argumentCount' => '1,2' + ), + 'ROMAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROMAN', + 'argumentCount' => '1,2' + ), + 'ROUND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'round', + 'argumentCount' => '2' + ), + 'ROUNDDOWN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDDOWN', + 'argumentCount' => '2' + ), + 'ROUNDUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::ROUNDUP', + 'argumentCount' => '2' + ), + 'ROW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROW', + 'argumentCount' => '-1', + 'passByReference' => array(TRUE) + ), + 'ROWS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::ROWS', + 'argumentCount' => '1' + ), + 'RSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::RSQ', + 'argumentCount' => '2' + ), + 'RTD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1+' + ), + 'SEARCH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SEARCHB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE', + 'argumentCount' => '2,3' + ), + 'SECOND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::SECONDOFMINUTE', + 'argumentCount' => '1' + ), + 'SERIESSUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SERIESSUM', + 'argumentCount' => '4' + ), + 'SIGN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SIGN', + 'argumentCount' => '1' + ), + 'SIN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sin', + 'argumentCount' => '1' + ), + 'SINH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sinh', + 'argumentCount' => '1' + ), + 'SKEW' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SKEW', + 'argumentCount' => '1+' + ), + 'SLN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SLN', + 'argumentCount' => '3' + ), + 'SLOPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SLOPE', + 'argumentCount' => '2' + ), + 'SMALL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::SMALL', + 'argumentCount' => '2' + ), + 'SQRT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'sqrt', + 'argumentCount' => '1' + ), + 'SQRTPI' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SQRTPI', + 'argumentCount' => '1' + ), + 'STANDARDIZE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STANDARDIZE', + 'argumentCount' => '3' + ), + 'STDEV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEV', + 'argumentCount' => '1+' + ), + 'STDEVA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVA', + 'argumentCount' => '1+' + ), + 'STDEVP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVP', + 'argumentCount' => '1+' + ), + 'STDEVPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STDEVPA', + 'argumentCount' => '1+' + ), + 'STEYX' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::STEYX', + 'argumentCount' => '2' + ), + 'SUBSTITUTE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::SUBSTITUTE', + 'argumentCount' => '3,4' + ), + 'SUBTOTAL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUBTOTAL', + 'argumentCount' => '2+' + ), + 'SUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUM', + 'argumentCount' => '1+' + ), + 'SUMIF' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMIF', + 'argumentCount' => '2,3' + ), + 'SUMIFS' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '?' + ), + 'SUMPRODUCT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMPRODUCT', + 'argumentCount' => '1+' + ), + 'SUMSQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMSQ', + 'argumentCount' => '1+' + ), + 'SUMX2MY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2MY2', + 'argumentCount' => '2' + ), + 'SUMX2PY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMX2PY2', + 'argumentCount' => '2' + ), + 'SUMXMY2' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::SUMXMY2', + 'argumentCount' => '2' + ), + 'SYD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::SYD', + 'argumentCount' => '4' + ), + 'T' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::RETURNSTRING', + 'argumentCount' => '1' + ), + 'TAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tan', + 'argumentCount' => '1' + ), + 'TANH' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'tanh', + 'argumentCount' => '1' + ), + 'TBILLEQ' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLEQ', + 'argumentCount' => '3' + ), + 'TBILLPRICE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLPRICE', + 'argumentCount' => '3' + ), + 'TBILLYIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::TBILLYIELD', + 'argumentCount' => '3' + ), + 'TDIST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TDIST', + 'argumentCount' => '3' + ), + 'TEXT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TEXTFORMAT', + 'argumentCount' => '2' + ), + 'TIME' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIME', + 'argumentCount' => '3' + ), + 'TIMEVALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::TIMEVALUE', + 'argumentCount' => '1' + ), + 'TINV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TINV', + 'argumentCount' => '2' + ), + 'TODAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DATENOW', + 'argumentCount' => '0' + ), + 'TRANSPOSE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::TRANSPOSE', + 'argumentCount' => '1' + ), + 'TREND' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TREND', + 'argumentCount' => '1-4' + ), + 'TRIM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::TRIMSPACES', + 'argumentCount' => '1' + ), + 'TRIMMEAN' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::TRIMMEAN', + 'argumentCount' => '2' + ), + 'TRUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOGICAL, + 'functionCall' => 'PHPExcel_Calculation_Logical::TRUE', + 'argumentCount' => '0' + ), + 'TRUNC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG, + 'functionCall' => 'PHPExcel_Calculation_MathTrig::TRUNC', + 'argumentCount' => '1,2' + ), + 'TTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '4' + ), + 'TYPE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::TYPE', + 'argumentCount' => '1' + ), + 'UPPER' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_TextData::UPPERCASE', + 'argumentCount' => '1' + ), + 'USDOLLAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '2' + ), + 'VALUE' => array('category' => PHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '1' + ), + 'VAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARFunc', + 'argumentCount' => '1+' + ), + 'VARA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARA', + 'argumentCount' => '1+' + ), + 'VARP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARP', + 'argumentCount' => '1+' + ), + 'VARPA' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::VARPA', + 'argumentCount' => '1+' + ), + 'VDB' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '5-7' + ), + 'VERSION' => array('category' => PHPExcel_Calculation_Function::CATEGORY_INFORMATION, + 'functionCall' => 'PHPExcel_Calculation_Functions::VERSION', + 'argumentCount' => '0' + ), + 'VLOOKUP' => array('category' => PHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => 'PHPExcel_Calculation_LookupRef::VLOOKUP', + 'argumentCount' => '3,4' + ), + 'WEEKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::DAYOFWEEK', + 'argumentCount' => '1,2' + ), + 'WEEKNUM' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WEEKOFYEAR', + 'argumentCount' => '1,2' + ), + 'WEIBULL' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::WEIBULL', + 'argumentCount' => '4' + ), + 'WORKDAY' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::WORKDAY', + 'argumentCount' => '2+' + ), + 'XIRR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XIRR', + 'argumentCount' => '2,3' + ), + 'XNPV' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::XNPV', + 'argumentCount' => '3' + ), + 'YEAR' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEAR', + 'argumentCount' => '1' + ), + 'YEARFRAC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME, + 'functionCall' => 'PHPExcel_Calculation_DateTime::YEARFRAC', + 'argumentCount' => '2,3' + ), + 'YIELD' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Functions::DUMMY', + 'argumentCount' => '6,7' + ), + 'YIELDDISC' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDDISC', + 'argumentCount' => '4,5' + ), + 'YIELDMAT' => array('category' => PHPExcel_Calculation_Function::CATEGORY_FINANCIAL, + 'functionCall' => 'PHPExcel_Calculation_Financial::YIELDMAT', + 'argumentCount' => '5,6' + ), + 'ZTEST' => array('category' => PHPExcel_Calculation_Function::CATEGORY_STATISTICAL, + 'functionCall' => 'PHPExcel_Calculation_Statistical::ZTEST', + 'argumentCount' => '2-3' + ) + ); + + + // Internal functions used for special control purposes + private static $_controlFunctions = array( + 'MKMATRIX' => array('argumentCount' => '*', + 'functionCall' => 'self::_mkMatrix' + ) + ); + + + + + private function __construct(PHPExcel $workbook = NULL) { + $setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16; + $this->_savedPrecision = ini_get('precision'); + if ($this->_savedPrecision < $setPrecision) { + ini_set('precision',$setPrecision); + } + + if ($workbook !== NULL) { + self::$_workbookSets[$workbook->getID()] = $this; + } + + $this->_workbook = $workbook; + $this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack(); + $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack); + } // function __construct() + + + public function __destruct() { + if ($this->_savedPrecision != ini_get('precision')) { + ini_set('precision',$this->_savedPrecision); + } + } + + private static function _loadLocales() { + $localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/'; + foreach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) { + $filename = substr($filename,strlen($localeFileDirectory)+1); + if ($filename != 'en') { + self::$_validLocaleLanguages[] = $filename; + } + } + } + + /** + * Get an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook for working with a PHPExcel object, + * or NULL to create a standalone claculation engine + * @return PHPExcel_Calculation + */ + public static function getInstance(PHPExcel $workbook = NULL) { + if ($workbook !== NULL) { + if (isset(self::$_workbookSets[$workbook->getID()])) { + return self::$_workbookSets[$workbook->getID()]; + } + return new PHPExcel_Calculation($workbook); + } + + if (!isset(self::$_instance) || (self::$_instance === NULL)) { + self::$_instance = new PHPExcel_Calculation(); + } + + return self::$_instance; + } // function getInstance() + + /** + * Unset an instance of this class + * + * @access public + * @param PHPExcel $workbook Injected workbook identifying the instance to unset + */ + public static function unsetInstance(PHPExcel $workbook = NULL) { + if ($workbook !== NULL) { + if (isset(self::$_workbookSets[$workbook->getID()])) { + unset(self::$_workbookSets[$workbook->getID()]); + } + } + } + + /** + * Flush the calculation cache for any existing instance of this class + * but only if a PHPExcel_Calculation instance exists + * + * @access public + * @return null + */ + public function flushInstance() { + $this->clearCalculationCache(); + } // function flushInstance() + + + /** + * Get the debuglog for this claculation engine instance + * + * @access public + * @return PHPExcel_CalcEngine_Logger + */ + public function getDebugLog() { + return $this->_debugLog; + } + + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @access public + * @throws PHPExcel_Calculation_Exception + */ + public final function __clone() { + throw new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!'); + } // function __clone() + + + /** + * Return the locale-specific translation of TRUE + * + * @access public + * @return string locale-specific translation of TRUE + */ + public static function getTRUE() { + return self::$_localeBoolean['TRUE']; + } + + /** + * Return the locale-specific translation of FALSE + * + * @access public + * @return string locale-specific translation of FALSE + */ + public static function getFALSE() { + return self::$_localeBoolean['FALSE']; + } + + /** + * Set the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @param string $returnType Array return type + * @return boolean Success or failure + */ + public static function setArrayReturnType($returnType) { + if (($returnType == self::RETURN_ARRAY_AS_VALUE) || + ($returnType == self::RETURN_ARRAY_AS_ERROR) || + ($returnType == self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnType; + return TRUE; + } + return FALSE; + } // function setArrayReturnType() + + + /** + * Return the Array Return Type (Array or Value of first element in the array) + * + * @access public + * @return string $returnType Array return type + */ + public static function getArrayReturnType() { + return self::$returnArrayAsType; + } // function getArrayReturnType() + + + /** + * Is calculation caching enabled? + * + * @access public + * @return boolean + */ + public function getCalculationCacheEnabled() { + return $this->_calculationCacheEnabled; + } // function getCalculationCacheEnabled() + + /** + * Enable/disable calculation cache + * + * @access public + * @param boolean $pValue + */ + public function setCalculationCacheEnabled($pValue = TRUE) { + $this->_calculationCacheEnabled = $pValue; + $this->clearCalculationCache(); + } // function setCalculationCacheEnabled() + + + /** + * Enable calculation cache + */ + public function enableCalculationCache() { + $this->setCalculationCacheEnabled(TRUE); + } // function enableCalculationCache() + + + /** + * Disable calculation cache + */ + public function disableCalculationCache() { + $this->setCalculationCacheEnabled(FALSE); + } // function disableCalculationCache() + + + /** + * Clear calculation cache + */ + public function clearCalculationCache() { + $this->_calculationCache = array(); + } // function clearCalculationCache() + + /** + * Clear calculation cache for a specified worksheet + * + * @param string $worksheetName + */ + public function clearCalculationCacheForWorksheet($worksheetName) { + if (isset($this->_calculationCache[$worksheetName])) { + unset($this->_calculationCache[$worksheetName]); + } + } // function clearCalculationCacheForWorksheet() + + /** + * Rename calculation cache for a specified worksheet + * + * @param string $fromWorksheetName + * @param string $toWorksheetName + */ + public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) { + if (isset($this->_calculationCache[$fromWorksheetName])) { + $this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName]; + unset($this->_calculationCache[$fromWorksheetName]); + } + } // function renameCalculationCacheForWorksheet() + + + /** + * Get the currently defined locale code + * + * @return string + */ + public function getLocale() { + return self::$_localeLanguage; + } // function getLocale() + + + /** + * Set the locale code + * + * @param string $locale The locale to use for formula translation + * @return boolean + */ + public function setLocale($locale = 'en_us') { + // Identify our locale and language + $language = $locale = strtolower($locale); + if (strpos($locale,'_') !== FALSE) { + list($language) = explode('_',$locale); + } + + if (count(self::$_validLocaleLanguages) == 1) + self::_loadLocales(); + + // Test whether we have any language data for this language (any locale) + if (in_array($language,self::$_validLocaleLanguages)) { + // initialise language/locale settings + self::$_localeFunctions = array(); + self::$_localeArgumentSeparator = ','; + self::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL'); + // Default is English, if user isn't requesting english, then read the necessary data from the locale files + if ($locale != 'en_us') { + // Search for a file with a list of function names for locale + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + // If there isn't a locale specific function file, look for a language specific function file + $functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions'; + if (!file_exists($functionNamesFile)) { + return FALSE; + } + } + // Retrieve the list of locale or language specific function names + $localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeFunctions as $localeFunction) { + list($localeFunction) = explode('##',$localeFunction); // Strip out comments + if (strpos($localeFunction,'=') !== FALSE) { + list($fName,$lfName) = explode('=',$localeFunction); + $fName = trim($fName); + $lfName = trim($lfName); + if ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) { + self::$_localeFunctions[$fName] = $lfName; + } + } + } + // Default the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions + if (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; } + if (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; } + + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config'; + if (!file_exists($configFile)) { + $configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config'; + } + if (file_exists($configFile)) { + $localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($localeSettings as $localeSetting) { + list($localeSetting) = explode('##',$localeSetting); // Strip out comments + if (strpos($localeSetting,'=') !== FALSE) { + list($settingName,$settingValue) = explode('=',$localeSetting); + $settingName = strtoupper(trim($settingName)); + switch ($settingName) { + case 'ARGUMENTSEPARATOR' : + self::$_localeArgumentSeparator = trim($settingValue); + break; + } + } + } + } + } + + self::$functionReplaceFromExcel = self::$functionReplaceToExcel = + self::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL; + self::$_localeLanguage = $locale; + return TRUE; + } + return FALSE; + } // function setLocale() + + + + public static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) { + $strlen = mb_strlen($formula); + for ($i = 0; $i < $strlen; ++$i) { + $chr = mb_substr($formula,$i,1); + switch ($chr) { + case '{' : $inBraces = TRUE; + break; + case '}' : $inBraces = FALSE; + break; + case $fromSeparator : + if (!$inBraces) { + $formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1); + } + } + } + return $formula; + } + + private static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) { + // Convert any Excel function names to the required language + if (self::$_localeLanguage !== 'en_us') { + $inBraces = FALSE; + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $value = preg_replace($from,$to,$value); + $value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $formula = preg_replace($from,$to,$formula); + $formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces); + } + } + + return $formula; + } + + private static $functionReplaceFromExcel = NULL; + private static $functionReplaceToLocale = NULL; + + public function _translateFormulaToLocale($formula) { + if (self::$functionReplaceFromExcel === NULL) { + self::$functionReplaceFromExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelFunctionName).'([\s]*\()/Ui'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromExcel[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + + } + + if (self::$functionReplaceToLocale === NULL) { + self::$functionReplaceToLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2'; + } + foreach(array_values(self::$_localeBoolean) as $localeBoolean) { + self::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator); + } // function _translateFormulaToLocale() + + + private static $functionReplaceFromLocale = NULL; + private static $functionReplaceToExcel = NULL; + + public function _translateFormulaToEnglish($formula) { + if (self::$functionReplaceFromLocale === NULL) { + self::$functionReplaceFromLocale = array(); + foreach(array_values(self::$_localeFunctions) as $localeFunctionName) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($localeFunctionName).'([\s]*\()/Ui'; + } + foreach(array_values(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceFromLocale[] = '/(@?[^\w\.])'.preg_quote($excelBoolean).'([^\w\.])/Ui'; + } + } + + if (self::$functionReplaceToExcel === NULL) { + self::$functionReplaceToExcel = array(); + foreach(array_keys(self::$_localeFunctions) as $excelFunctionName) { + self::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2'; + } + foreach(array_keys(self::$_localeBoolean) as $excelBoolean) { + self::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2'; + } + } + + return self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,','); + } // function _translateFormulaToEnglish() + + + public static function _localeFunc($function) { + if (self::$_localeLanguage !== 'en_us') { + $functionName = trim($function,'('); + if (isset(self::$_localeFunctions[$functionName])) { + $brace = ($functionName != $function); + $function = self::$_localeFunctions[$functionName]; + if ($brace) { $function .= '('; } + } + } + return $function; + } + + + + + /** + * Wrap string values in quotes + * + * @param mixed $value + * @return mixed + */ + public static function _wrapResult($value) { + if (is_string($value)) { + // Error values cannot be "wrapped" + if (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) { + // Return Excel errors "as is" + return $value; + } + // Return strings wrapped in quotes + return '"'.$value.'"'; + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $value; + } // function _wrapResult() + + + /** + * Remove quotes used as a wrapper to identify string values + * + * @param mixed $value + * @return mixed + */ + public static function _unwrapResult($value) { + if (is_string($value)) { + if ((isset($value{0})) && ($value{0} == '"') && (substr($value,-1) == '"')) { + return substr($value,1,-1); + } + // Convert numeric errors to NaN error + } else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $value; + } // function _unwrapResult() + + + + + /** + * Calculate cell value (using formula from a cell ID) + * Retained for backward compatibility + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculate(PHPExcel_Cell $pCell = NULL) { + try { + return $this->calculateCellValue($pCell); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + } // function calculate() + + + /** + * Calculate the value of a cell formula + * + * @access public + * @param PHPExcel_Cell $pCell Cell to calculate + * @param Boolean $resetLog Flag indicating whether the debug log should be reset or not + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) { + if ($pCell === NULL) { + return NULL; + } + + $returnArrayAsType = self::$returnArrayAsType; + if ($resetLog) { + // Initialise the logging settings if requested + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + $this->_cyclicFormulaCount = 1; + + self::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY; + } + + // Execute the calculation for the cell formula + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + if ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { + self::$returnArrayAsType = $returnArrayAsType; + $testResult = PHPExcel_Calculation_Functions::flattenArray($result); + if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) { + return PHPExcel_Calculation_Functions::VALUE(); + } + // If there's only a single cell in the array, then we allow it + if (count($testResult) != 1) { + // If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it + $r = array_keys($result); + $r = array_shift($r); + if (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); } + if (is_array($result[$r])) { + $c = array_keys($result[$r]); + $c = array_shift($c); + if (!is_numeric($c)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + $result = array_shift($testResult); + } + self::$returnArrayAsType = $returnArrayAsType; + + + if ($result === NULL) { + return 0; + } elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $result; + } // function calculateCellValue( + + + /** + * Validate and parse a formula string + * + * @param string $formula Formula to parse + * @return array + * @throws PHPExcel_Calculation_Exception + */ + public function parseFormula($formula) { + // Basic validation that this is indeed a formula + // We return an empty array if not + $formula = trim($formula); + if ((!isset($formula{0})) || ($formula{0} != '=')) return array(); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return array(); + + // Parse the formula and return the token stack + return $this->_parseFormula($formula); + } // function parseFormula() + + + /** + * Calculate the value of a formula + * + * @param string $formula Formula to parse + * @param string $cellID Address of the cell to calculate + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) { + // Initialise the logging settings + $this->formulaError = null; + $this->_debugLog->clearLog(); + $this->_cyclicReferenceStack->clear(); + + // Disable calculation cacheing because it only applies to cell calculations, not straight formulae + // But don't actually flush any cache + $resetCache = $this->getCalculationCacheEnabled(); + $this->_calculationCacheEnabled = FALSE; + // Execute the calculation + try { + $result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell)); + } catch (PHPExcel_Exception $e) { + throw new PHPExcel_Calculation_Exception($e->getMessage()); + } + + // Reset calculation cacheing to its previous state + $this->_calculationCacheEnabled = $resetCache; + + return $result; + } // function calculateFormula() + + + public function getValueFromCache($worksheetName, $cellID, &$cellValue) { + // Is calculation cacheing enabled? + // Is the value present in calculation cache? +//echo 'Test cache for ',$worksheetName,'!',$cellID,PHP_EOL; + $this->_debugLog->writeDebugLog('Testing cache value for cell ', $worksheetName, '!', $cellID); + if (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$worksheetName][$cellID]))) { +//echo 'Retrieve from cache',PHP_EOL; + $this->_debugLog->writeDebugLog('Retrieving value for cell ', $worksheetName, '!', $cellID, ' from cache'); + // Return the cached result + $cellValue = $this->_calculationCache[$worksheetName][$cellID]; + return TRUE; + } + return FALSE; + } + + public function saveValueToCache($worksheetName, $cellID, $cellValue) { + if ($this->_calculationCacheEnabled) { + $this->_calculationCache[$worksheetName][$cellID] = $cellValue; + } + } + + /** + * Parse a cell formula and calculate its value + * + * @param string $formula The formula to parse and calculate + * @param string $cellID The ID (e.g. A3) of the cell that we are calculating + * @param PHPExcel_Cell $pCell Cell to calculate + * @return mixed + * @throws PHPExcel_Calculation_Exception + */ + public function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) { + $cellValue = ''; + + // Basic validation that this is indeed a formula + // We simply return the cell value if not + $formula = trim($formula); + if ($formula{0} != '=') return self::_wrapResult($formula); + $formula = ltrim(substr($formula,1)); + if (!isset($formula{0})) return self::_wrapResult($formula); + + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : "\x00Wrk"; + + if (($cellID !== NULL) && ($this->getValueFromCache($wsTitle, $cellID, $cellValue))) { + return $cellValue; + } + + if (($wsTitle{0} !== "\x00") && ($this->_cyclicReferenceStack->onStack($wsTitle.'!'.$cellID))) { + if ($this->cyclicFormulaCount <= 0) { + return $this->_raiseFormulaError('Cyclic Reference in Formula'); + } elseif (($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) && + ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID)) { + return $cellValue; + } elseif ($this->_cyclicFormulaCell == $wsTitle.'!'.$cellID) { + ++$this->_cyclicFormulaCount; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + } elseif ($this->_cyclicFormulaCell == '') { + $this->_cyclicFormulaCell = $wsTitle.'!'.$cellID; + if ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) { + return $cellValue; + } + } + } + + // Parse the formula onto the token stack and calculate the value + $this->_cyclicReferenceStack->push($wsTitle.'!'.$cellID); + $cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell); + $this->_cyclicReferenceStack->pop(); + + // Save to calculation cache + if ($cellID !== NULL) { + $this->saveValueToCache($wsTitle, $cellID, $cellValue); + } + + // Return the calculated value + return $cellValue; + } // function _calculateFormulaValue() + + + /** + * Ensure that paired matrix operands are both matrices and of the same size + * + * @param mixed &$operand1 First matrix operand + * @param mixed &$operand2 Second matrix operand + * @param integer $resize Flag indicating whether the matrices should be resized to match + * and (if so), whether the smaller dimension should grow or the + * larger should shrink. + * 0 = no resize + * 1 = shrink to fit + * 2 = extend to fit + */ + private static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) { + // Examine each of the two operands, and turn them into an array if they aren't one already + // Note that this function should only be called if one or both of the operand is already an array + if (!is_array($operand1)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2); + $operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1)); + $resize = 0; + } elseif (!is_array($operand2)) { + list($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1); + $operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2)); + $resize = 0; + } + + list($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1); + list($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2); + if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { + $resize = 1; + } + + if ($resize == 2) { + // Given two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger + self::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } elseif ($resize == 1) { + // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller + self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); + } // function _checkMatrixOperands() + + + /** + * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0 + * + * @param mixed &$matrix matrix operand + * @return array An array comprising the number of rows, and number of columns + */ + public static function _getMatrixDimensions(&$matrix) { + $matrixRows = count($matrix); + $matrixColumns = 0; + foreach($matrix as $rowKey => $rowValue) { + $matrixColumns = max(count($rowValue),$matrixColumns); + if (!is_array($rowValue)) { + $matrix[$rowKey] = array($rowValue); + } else { + $matrix[$rowKey] = array_values($rowValue); + } + } + $matrix = array_values($matrix); + return array($matrixRows,$matrixColumns); + } // function _getMatrixDimensions() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Rows < $matrix1Rows) { + for ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) { + unset($matrix1[$i]); + } + } + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + unset($matrix1[$i][$j]); + } + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Rows < $matrix2Rows) { + for ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) { + unset($matrix2[$i]); + } + } + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + unset($matrix2[$i][$j]); + } + } + } + } + } // function _resizeMatricesShrink() + + + /** + * Ensure that paired matrix operands are both matrices of the same size + * + * @param mixed &$matrix1 First matrix operand + * @param mixed &$matrix2 Second matrix operand + * @param integer $matrix1Rows Row size of first matrix operand + * @param integer $matrix1Columns Column size of first matrix operand + * @param integer $matrix2Rows Row size of second matrix operand + * @param integer $matrix2Columns Column size of second matrix operand + */ + private static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) { + if (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) { + if ($matrix2Columns < $matrix1Columns) { + for ($i = 0; $i < $matrix2Rows; ++$i) { + $x = $matrix2[$i][$matrix2Columns-1]; + for ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) { + $matrix2[$i][$j] = $x; + } + } + } + if ($matrix2Rows < $matrix1Rows) { + $x = $matrix2[$matrix2Rows-1]; + for ($i = 0; $i < $matrix1Rows; ++$i) { + $matrix2[$i] = $x; + } + } + } + + if (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) { + if ($matrix1Columns < $matrix2Columns) { + for ($i = 0; $i < $matrix1Rows; ++$i) { + $x = $matrix1[$i][$matrix1Columns-1]; + for ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) { + $matrix1[$i][$j] = $x; + } + } + } + if ($matrix1Rows < $matrix2Rows) { + $x = $matrix1[$matrix1Rows-1]; + for ($i = 0; $i < $matrix2Rows; ++$i) { + $matrix1[$i] = $x; + } + } + } + } // function _resizeMatricesExtend() + + + /** + * Format details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showValue($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if (is_array($value)) { + $returnMatrix = array(); + $pad = $rpad = ', '; + foreach($value as $row) { + if (is_array($row)) { + $returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row)); + $rpad = '; '; + } else { + $returnMatrix[] = $this->_showValue($row); + } + } + return '{ '.implode($rpad,$returnMatrix).' }'; + } elseif(is_string($value) && (trim($value,'"') == $value)) { + return '"'.$value.'"'; + } elseif(is_bool($value)) { + return ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + } + return PHPExcel_Calculation_Functions::flattenSingleValue($value); + } // function _showValue() + + + /** + * Format type and details of an operand for display in the log (based on operand type) + * + * @param mixed $value First matrix operand + * @return mixed + */ + private function _showTypeDetails($value) { + if ($this->_debugLog->getWriteDebugLog()) { + $testArray = PHPExcel_Calculation_Functions::flattenArray($value); + if (count($testArray) == 1) { + $value = array_pop($testArray); + } + + if ($value === NULL) { + return 'a NULL value'; + } elseif (is_float($value)) { + $typeString = 'a floating point number'; + } elseif(is_int($value)) { + $typeString = 'an integer number'; + } elseif(is_bool($value)) { + $typeString = 'a boolean'; + } elseif(is_array($value)) { + $typeString = 'a matrix'; + } else { + if ($value == '') { + return 'an empty string'; + } elseif ($value{0} == '#') { + return 'a '.$value.' error'; + } else { + $typeString = 'a string'; + } + } + return $typeString.' with a value of '.$this->_showValue($value); + } + } // function _showTypeDetails() + + + private static function _convertMatrixReferences($formula) { + static $matrixReplaceFrom = array('{',';','}'); + static $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))'); + + // Convert any Excel matrix references to the MKMATRIX() function + if (strpos($formula,'{') !== FALSE) { + // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + if (strpos($formula,'"') !== FALSE) { + // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded + // the formula + $temp = explode('"',$formula); + // Open and Closed counts used for trapping mismatched braces in the formula + $openCount = $closeCount = 0; + $i = FALSE; + foreach($temp as &$value) { + // Only count/replace in alternating array entries + if ($i = !$i) { + $openCount += substr_count($value,'{'); + $closeCount += substr_count($value,'}'); + $value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value); + } + } + unset($value); + // Then rebuild the formula string + $formula = implode('"',$temp); + } else { + // If there's no quoted strings, then we do a simple count/replace + $openCount = substr_count($formula,'{'); + $closeCount = substr_count($formula,'}'); + $formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula); + } + // Trap for mismatched braces and trigger an appropriate error + if ($openCount < $closeCount) { + if ($openCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '}'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '}' encountered"); + } + } elseif ($openCount > $closeCount) { + if ($closeCount > 0) { + return $this->_raiseFormulaError("Formula Error: Mismatched matrix braces '{'"); + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected '{' encountered"); + } + } + } + + return $formula; + } // function _convertMatrixReferences() + + + private static function _mkMatrix() { + return func_get_args(); + } // function _mkMatrix() + + + // Binary Operators + // These operators always work on two values + // Array key is the operator, the value indicates whether this is a left or right associative operator + private static $_operatorAssociativity = array( + '^' => 0, // Exponentiation + '*' => 0, '/' => 0, // Multiplication and Division + '+' => 0, '-' => 0, // Addition and Subtraction + '&' => 0, // Concatenation + '|' => 0, ':' => 0, // Intersect and Range + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Comparison (Boolean) Operators + // These operators work on two values, but always return a boolean result + private static $_comparisonOperators = array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE); + + // Operator Precedence + // This list includes all valid operators, whether binary (including boolean) or unary (such as %) + // Array key is the operator, the value is its precedence + private static $_operatorPrecedence = array( + ':' => 8, // Range + '|' => 7, // Intersect + '~' => 6, // Negation + '%' => 5, // Percentage + '^' => 4, // Exponentiation + '*' => 3, '/' => 3, // Multiplication and Division + '+' => 2, '-' => 2, // Addition and Subtraction + '&' => 1, // Concatenation + '>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0 // Comparison + ); + + // Convert infix to postfix notation + private function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) { + if (($formula = self::_convertMatrixReferences(trim($formula))) === FALSE) { + return FALSE; + } + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet), + // so we store the parent worksheet so that we can re-attach it when necessary + $pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + + $regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION. + '|'.self::CALCULATION_REGEXP_CELLREF. + '|'.self::CALCULATION_REGEXP_NUMBER. + '|'.self::CALCULATION_REGEXP_STRING. + '|'.self::CALCULATION_REGEXP_OPENBRACE. + '|'.self::CALCULATION_REGEXP_NAMEDRANGE. + '|'.self::CALCULATION_REGEXP_ERROR. + ')/si'; + + // Start with initialisation + $index = 0; + $stack = new PHPExcel_Calculation_Token_Stack; + $output = array(); + $expectingOperator = FALSE; // We use this test in syntax-checking the expression to determine when a + // - is a negation or + is a positive operator rather than an operation + $expectingOperand = FALSE; // We use this test in syntax-checking the expression to determine whether an operand + // should be null in a function call + // The guts of the lexical parser + // Loop through the formula extracting each operator and operand in turn + while(TRUE) { +//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL; + $opCharacter = $formula{$index}; // Get the first character of the value at the current index position +//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL; + if ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) { + $opCharacter .= $formula{++$index}; +//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL; + } + + // Find out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand + $isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match); +//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL; +//var_dump($match); + + if ($opCharacter == '-' && !$expectingOperator) { // Is it a negation instead of a minus? +//echo 'Element is a Negation operator',PHP_EOL; + $stack->push('Unary Operator','~'); // Put a negation on the stack + ++$index; // and drop the negation symbol + } elseif ($opCharacter == '%' && $expectingOperator) { +//echo 'Element is a Percentage operator',PHP_EOL; + $stack->push('Unary Operator','%'); // Put a percentage on the stack + ++$index; + } elseif ($opCharacter == '+' && !$expectingOperator) { // Positive (unary plus rather than binary operator plus) can be discarded? +//echo 'Element is a Positive number, not Plus operator',PHP_EOL; + ++$index; // Drop the redundant plus symbol + } elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) { // We have to explicitly deny a tilde or pipe, because they are legal + return $this->_raiseFormulaError("Formula Error: Illegal character '~'"); // on the stack but not in the input expression + + } elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) { // Are we putting an operator on the stack? +//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator',$opCharacter); // Finally put our current operator onto the stack + ++$index; + $expectingOperator = FALSE; + + } elseif ($opCharacter == ')' && $expectingOperator) { // Are we expecting to close a parenthesis? +//echo 'Element is a Closing bracket',PHP_EOL; + $expectingOperand = FALSE; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace ")"'); + else $output[] = $o2; + } + $d = $stack->last(2); + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) { // Did this parenthesis just close a function? + $functionName = $matches[1]; // Get the function name +//echo 'Closed Function is '.$functionName,PHP_EOL; + $d = $stack->pop(); + $argumentCount = $d['value']; // See how many arguments there were (argument count is the next value stored on the stack) +//if ($argumentCount == 0) { +// echo 'With no arguments',PHP_EOL; +//} elseif ($argumentCount == 1) { +// echo 'With 1 argument',PHP_EOL; +//} else { +// echo 'With '.$argumentCount.' arguments',PHP_EOL; +//} + $output[] = $d; // Dump the argument count on the output + $output[] = $stack->pop(); // Pop the function and push onto the output + if (isset(self::$_controlFunctions[$functionName])) { +//echo 'Built-in function '.$functionName,PHP_EOL; + $expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount']; + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + } elseif (isset(self::$_PHPExcelFunctions[$functionName])) { +//echo 'PHPExcel function '.$functionName,PHP_EOL; + $expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount']; + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + } else { // did we somehow push a non-function on the stack? this should never happen + return $this->_raiseFormulaError("Formula Error: Internal error, non-function on stack"); + } + // Check the argument count + $argumentCountError = FALSE; + if (is_numeric($expectedArgumentCount)) { + if ($expectedArgumentCount < 0) { +//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL; + if ($argumentCount > abs($expectedArgumentCount)) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount); + } + } else { +//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL; + if ($argumentCount != $expectedArgumentCount) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $expectedArgumentCount; + } + } + } elseif ($expectedArgumentCount != '*') { + $isOperandOrFunction = preg_match('/(\d*)([-+,])(\d*)/',$expectedArgumentCount,$argMatch); +//print_r($argMatch); +//echo PHP_EOL; + switch ($argMatch[2]) { + case '+' : + if ($argumentCount < $argMatch[1]) { + $argumentCountError = TRUE; + $expectedArgumentCountString = $argMatch[1].' or more '; + } + break; + case '-' : + if (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3]; + } + break; + case ',' : + if (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) { + $argumentCountError = TRUE; + $expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3]; + } + break; + } + } + if ($argumentCountError) { + return $this->_raiseFormulaError("Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, ".$expectedArgumentCountString." expected"); + } + } + ++$index; + + } elseif ($opCharacter == ',') { // Is this the separator for function arguments? +//echo 'Element is a Function argument separator',PHP_EOL; + while (($o2 = $stack->pop()) && $o2['value'] != '(') { // Pop off the stack back to the last ( + if ($o2 === NULL) return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + else $output[] = $o2; // pop the argument expression stuff and push onto the output + } + // If we've a comma when we're expecting an operand, then what we actually have is a null operand; + // so push a null onto the stack + if (($expectingOperand) || (!$expectingOperator)) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + } + // make sure there was a function + $d = $stack->last(2); + if (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) + return $this->_raiseFormulaError("Formula Error: Unexpected ,"); + $d = $stack->pop(); + $stack->push($d['type'],++$d['value'],$d['reference']); // increment the argument count + $stack->push('Brace', '('); // put the ( back on, we'll need to pop back to it again + $expectingOperator = FALSE; + $expectingOperand = TRUE; + ++$index; + + } elseif ($opCharacter == '(' && !$expectingOperator) { +// echo 'Element is an Opening Bracket
'; + $stack->push('Brace', '('); + ++$index; + + } elseif ($isOperandOrFunction && !$expectingOperator) { // do we now have a function/variable/number? + $expectingOperator = TRUE; + $expectingOperand = FALSE; + $val = $match[1]; + $length = strlen($val); +// echo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function
'; + + if (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) { + $val = preg_replace('/\s/','',$val); +// echo 'Element '.$val.' is a Function
'; + if (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) { // it's a function + $stack->push('Function', strtoupper($val)); + $ax = preg_match('/^\s*(\s*\))/i', substr($formula, $index+$length), $amatch); + if ($ax) { + $stack->push('Operand Count for Function '.strtoupper($val).')', 0); + $expectingOperator = TRUE; + } else { + $stack->push('Operand Count for Function '.strtoupper($val).')', 1); + $expectingOperator = FALSE; + } + $stack->push('Brace', '('); + } else { // it's a var w/ implicit multiplication + $output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL); + } + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) { +// echo 'Element '.$val.' is a Cell reference
'; + // Watch for this case-change when modifying to allow cell references in different worksheets... + // Should only be applied to the actual cell column, not the worksheet name + + // If the last entry on the stack was a : operator, then we have a cell range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + // If we have a worksheet reference, then we're playing with a 3D reference + if ($matches[2] == '') { + // Otherwise, we 'inherit' the worksheet reference from the start cell reference + // The start of the cell range reference should be the last entry in $output + $startCellRef = $output[count($output)-1]['value']; + preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches); + if ($startMatches[2] > '') { + $val = $startMatches[2].'!'.$val; + } + } else { + return $this->_raiseFormulaError("3D Range references are not yet supported"); + } + } + + $output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val); +// $expectingOperator = FALSE; + } else { // it's a variable, constant, string, number or boolean +// echo 'Element is a Variable, Constant, String, Number or Boolean
'; + // If the last entry on the stack was a : operator, then we may have a row or column range reference + $testPrevOp = $stack->last(1); + if ($testPrevOp['value'] == ':') { + $startRowColRef = $output[count($output)-1]['value']; + $rangeWS1 = ''; + if (strpos('!',$startRowColRef) !== FALSE) { + list($rangeWS1,$startRowColRef) = explode('!',$startRowColRef); + } + if ($rangeWS1 != '') $rangeWS1 .= '!'; + $rangeWS2 = $rangeWS1; + if (strpos('!',$val) !== FALSE) { + list($rangeWS2,$val) = explode('!',$val); + } + if ($rangeWS2 != '') $rangeWS2 .= '!'; + if ((is_integer($startRowColRef)) && (ctype_digit($val)) && + ($startRowColRef <= 1048576) && ($val <= 1048576)) { + // Row range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD'; // Max 16,384 columns for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef; + $val = $rangeWS2.$endRowColRef.$val; + } elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) && + (strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) { + // Column range + $endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576; // Max 1,048,576 rows for Excel2007 + $output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1'; + $val = $rangeWS2.$val.$endRowColRef; + } + } + + $localeConstant = FALSE; + if ($opCharacter == '"') { +// echo 'Element is a String
'; + // UnEscape any quotes within the string + $val = self::_wrapResult(str_replace('""','"',self::_unwrapResult($val))); + } elseif (is_numeric($val)) { +// echo 'Element is a Number
'; + if ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) { +// echo 'Casting '.$val.' to float
'; + $val = (float) $val; + } else { +// echo 'Casting '.$val.' to integer
'; + $val = (integer) $val; + } + } elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) { + $excelConstant = trim(strtoupper($val)); +// echo 'Element '.$excelConstant.' is an Excel Constant
'; + $val = self::$_ExcelConstants[$excelConstant]; + } elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) { +// echo 'Element '.$localeConstant.' is an Excel Constant
'; + $val = self::$_ExcelConstants[$localeConstant]; + } + $details = array('type' => 'Value', 'value' => $val, 'reference' => NULL); + if ($localeConstant) { $details['localeValue'] = $localeConstant; } + $output[] = $details; + } + $index += $length; + + } elseif ($opCharacter == '$') { // absolute row or column range + ++$index; + } elseif ($opCharacter == ')') { // miscellaneous error checking + if ($expectingOperand) { + $output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL); + $expectingOperand = FALSE; + $expectingOperator = TRUE; + } else { + return $this->_raiseFormulaError("Formula Error: Unexpected ')'"); + } + } elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) { + return $this->_raiseFormulaError("Formula Error: Unexpected operator '$opCharacter'"); + } else { // I don't even want to know what you did to get here + return $this->_raiseFormulaError("Formula Error: An unexpected error occured"); + } + // Test for end of formula string + if ($index == strlen($formula)) { + // Did we end with an operator?. + // Only valid for the % unary operator + if ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) { + return $this->_raiseFormulaError("Formula Error: Operator '$opCharacter' has no operands"); + } else { + break; + } + } + // Ignore white space + while (($formula{$index} == "\n") || ($formula{$index} == "\r")) { + ++$index; + } + if ($formula{$index} == ' ') { + while ($formula{$index} == ' ') { + ++$index; + } + // If we're expecting an operator, but only have a space between the previous and next operands (and both are + // Cell References) then we have an INTERSECTION operator +// echo 'Possible Intersect Operator
'; + if (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) && + ($output[count($output)-1]['type'] == 'Cell Reference')) { +// echo 'Element is an Intersect Operator
'; + while($stack->count() > 0 && + ($o2 = $stack->last()) && + isset(self::$_operators[$o2['value']]) && + @(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) { + $output[] = $stack->pop(); // Swap operands and higher precedence operators from the stack to the output + } + $stack->push('Binary Operator','|'); // Put an Intersect Operator on the stack + $expectingOperator = FALSE; + } + } + } + + while (($op = $stack->pop()) !== NULL) { // pop everything off the stack and push onto output + if ((is_array($op) && $op['value'] == '(') || ($op === '(')) + return $this->_raiseFormulaError("Formula Error: Expecting ')'"); // if there are any opening braces on the stack, then braces were unbalanced + $output[] = $op; + } + return $output; + } // function _parseFormula() + + + private static function _dataTestReference(&$operandData) + { + $operand = $operandData['value']; + if (($operandData['reference'] === NULL) && (is_array($operand))) { + $rKeys = array_keys($operand); + $rowKey = array_shift($rKeys); + $cKeys = array_keys(array_keys($operand[$rowKey])); + $colKey = array_shift($cKeys); + if (ctype_upper($colKey)) { + $operandData['reference'] = $colKey.$rowKey; + } + } + return $operand; + } + + // evaluate postfix notation + private function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) { + if ($tokens == FALSE) return FALSE; + + // If we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection), + // so we store the parent cell collection so that we can re-attach it when necessary + $pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL; + $pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null; + $stack = new PHPExcel_Calculation_Token_Stack; + + // Loop through each token in turn + foreach ($tokens as $tokenData) { +// print_r($tokenData); +// echo '
'; + $token = $tokenData['value']; +// echo 'Token is '.$token.'
'; + // if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack + if (isset(self::$_binaryOperators[$token])) { +// echo 'Token is a binary operator
'; + // We must have two operands, error if we don't + if (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + if (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + + $operand1 = self::_dataTestReference($operand1Data); + $operand2 = self::_dataTestReference($operand2Data); + + // Log what we're doing + if ($token == ':') { + $this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference'])); + } else { + $this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2)); + } + + // Process the operation in the appropriate manner + switch ($token) { + // Comparison (Boolean) Operators + case '>' : // Greater than + case '<' : // Less than + case '>=' : // Greater than or Equal to + case '<=' : // Less than or Equal to + case '=' : // Equality + case '<>' : // Inequality + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack); + break; + // Binary Operators + case ':' : // Range + $sheet1 = $sheet2 = ''; + if (strpos($operand1Data['reference'],'!') !== FALSE) { + list($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']); + } else { + $sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : ''; + } + if (strpos($operand2Data['reference'],'!') !== FALSE) { + list($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']); + } else { + $sheet2 = $sheet1; + } + if ($sheet1 == $sheet2) { + if ($operand1Data['reference'] === NULL) { + if ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) { + $operand1Data['reference'] = $pCell->getColumn().$operand1Data['value']; + } elseif (trim($operand1Data['reference']) == '') { + $operand1Data['reference'] = $pCell->getCoordinate(); + } else { + $operand1Data['reference'] = $operand1Data['value'].$pCell->getRow(); + } + } + if ($operand2Data['reference'] === NULL) { + if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { + $operand2Data['reference'] = $pCell->getColumn().$operand2Data['value']; + } elseif (trim($operand2Data['reference']) == '') { + $operand2Data['reference'] = $pCell->getCoordinate(); + } else { + $operand2Data['reference'] = $operand2Data['value'].$pCell->getRow(); + } + } + + $oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference'])); + $oCol = $oRow = array(); + foreach($oData as $oDatum) { + $oCR = PHPExcel_Cell::coordinateFromString($oDatum); + $oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1; + $oRow[] = $oCR[1]; + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $stack->push('Cell Reference',$cellValue,$cellRef); + } else { + $stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL); + } + + break; + case '+' : // Addition + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack); + break; + case '-' : // Subtraction + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack); + break; + case '*' : // Multiplication + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack); + break; + case '/' : // Division + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack); + break; + case '^' : // Exponential + $this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack); + break; + case '&' : // Concatenation + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if (is_bool($operand1)) { + $operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if (is_bool($operand2)) { + $operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE']; + } + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices + self::_checkMatrixOperands($operand1,$operand2,2); + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->concat($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + $result = '"'.str_replace('""','"',self::_unwrapResult($operand1,'"').self::_unwrapResult($operand2,'"')).'"'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + break; + case '|' : // Intersect + $rowIntersect = array_intersect_key($operand1,$operand2); + $cellIntersect = $oCol = $oRow = array(); + foreach(array_keys($rowIntersect) as $row) { + $oRow[] = $row; + foreach($rowIntersect[$row] as $col => $data) { + $oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1; + $cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]); + } + } + $cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect)); + $stack->push('Value',$cellIntersect,$cellRef); + break; + } + + // if the token is a unary operator, pop one value off the stack, do the operation, and push it back on + } elseif (($token === '~') || ($token === '%')) { +// echo 'Token is a unary operator
'; + if (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack'); + $arg = $arg['value']; + if ($token === '~') { +// echo 'Token is a negation operator
'; + $this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg)); + $multiplier = -1; + } else { +// echo 'Token is a percentile operator
'; + $this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg)); + $multiplier = 0.01; + } + if (is_array($arg)) { + self::_checkMatrixOperands($arg,$multiplier,2); + try { + $matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg); + $matrixResult = $matrix1->arrayTimesEquals($multiplier); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + $stack->push('Value',$result); + } else { + $this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack); + } + + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) { + $cellRef = NULL; +// echo 'Element '.$token.' is a Cell reference
'; + if (isset($matches[8])) { +// echo 'Reference is a Range of cells
'; + if ($pCell === NULL) { +// We can't access the range, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } + $matches[2] = trim($matches[2],"\"'"); +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet
'; + $this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet'); + if ($pCellParent !== NULL) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } else { +// echo 'Reference is a single Cell
'; + if ($pCell === NULL) { +// We can't access the cell, so return a REF error + $cellValue = PHPExcel_Calculation_Functions::REF(); + } else { + $cellRef = $matches[6].$matches[7]; + if ($matches[2] > '') { + $matches[2] = trim($matches[2],"\"'"); + if ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) { + // It's a Reference to an external workbook (not currently supported) + return $this->_raiseFormulaError('Unable to access External Workbook'); + } +// echo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'
'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]); + if ($pCellParent !== NULL) { + $cellSheet = $this->_workbook->getSheetByName($matches[2]); + if ($cellSheet && $cellSheet->cellExists($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + } else { + return $this->_raiseFormulaError('Unable to access Cell Reference'); + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue)); +// $cellRef = $matches[2].'!'.$cellRef; + } else { +// echo '$cellRef='.$cellRef.' in current worksheet
'; + $this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet'); + if ($pCellParent->isDataSet($cellRef)) { + $cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE); + $pCell->attach($pCellParent); + } else { + $cellValue = NULL; + } + $this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue)); + } + } + } + $stack->push('Value',$cellValue,$cellRef); + + // if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) { +// echo 'Token is a function
'; + $functionName = $matches[1]; + $argCount = $stack->pop(); + $argCount = $argCount['value']; + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's')); + } + if ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) { // function + if (isset(self::$_PHPExcelFunctions[$functionName])) { + $functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']); + } elseif (isset(self::$_controlFunctions[$functionName])) { + $functionCall = self::$_controlFunctions[$functionName]['functionCall']; + $passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']); + $passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']); + } + // get the arguments for this function +// echo 'Function '.$functionName.' expects '.$argCount.' arguments
'; + $args = $argArrayVals = array(); + for ($i = 0; $i < $argCount; ++$i) { + $arg = $stack->pop(); + $a = $argCount - $i - 1; + if (($passByReference) && + (isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) && + (self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) { + if ($arg['reference'] === NULL) { + $args[] = $cellID; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); } + } else { + $args[] = $arg['reference']; + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); } + } + } else { + $args[] = self::_unwrapResult($arg['value']); + if ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); } + } + } + // Reverse the order of the arguments + krsort($args); + if (($passByReference) && ($argCount == 0)) { + $args[] = $cellID; + $argArrayVals[] = $this->_showValue($cellID); + } +// echo 'Arguments are: '; +// print_r($args); +// echo '
'; + if ($functionName != 'MKMATRIX') { + if ($this->_debugLog->getWriteDebugLog()) { + krsort($argArrayVals); + $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )'); + } + } + // Process each argument in turn, building the return value as an array +// if (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) { +// $operand1 = $args[1]; +// $this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1)); +// $result = array(); +// $row = 0; +// foreach($operand1 as $args) { +// if (is_array($args)) { +// foreach($args as $arg) { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )'); +// $r = call_user_func_array($functionCall,$arg); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[$row][] = $r; +// } +// ++$row; +// } else { +// $this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )'); +// $r = call_user_func_array($functionCall,$args); +// $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r)); +// $result[] = $r; +// } +// } +// } else { + // Process the argument with the appropriate function call + if ($passCellReference) { + $args[] = $pCell; + } + if (strpos($functionCall,'::') !== FALSE) { + $result = call_user_func_array(explode('::',$functionCall),$args); + } else { + foreach($args as &$arg) { + $arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg); + } + unset($arg); + $result = call_user_func_array($functionCall,$args); + } +// } + if ($functionName != 'MKMATRIX') { + $this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result)); + } + $stack->push('Value',self::_wrapResult($result)); + } + + } else { + // if the token is a number, boolean, string or an Excel error, push it onto the stack + if (isset(self::$_ExcelConstants[strtoupper($token)])) { + $excelConstant = strtoupper($token); +// echo 'Token is a PHPExcel constant: '.$excelConstant.'
'; + $stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]); + $this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant])); + } elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '"') || ($token{0} == '#')) { +// echo 'Token is a number, boolean, string, null or an Excel error
'; + $stack->push('Value',$token); + // if the token is a named range, push the named range name onto the stack + } elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) { +// echo 'Token is a named range
'; + $namedRange = $matches[6]; +// echo 'Named Range is '.$namedRange.'
'; + $this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange); + $cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE); + $pCell->attach($pCellParent); + $this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue)); + $stack->push('Named Range',$cellValue,$namedRange); + } else { + return $this->_raiseFormulaError("undefined variable '$token'"); + } + } + } + // when we're out of tokens, the stack should have a single element, the final result + if ($stack->count() != 1) return $this->_raiseFormulaError("internal error"); + $output = $stack->pop(); + $output = $output['value']; + +// if ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) { +// return array_shift(PHPExcel_Calculation_Functions::flattenArray($output)); +// } + return $output; + } // function _processTokenStack() + + + private function _validateBinaryOperand($cellID, &$operand, &$stack) { + if (is_array($operand)) { + if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { + do { + $operand = array_pop($operand); + } while (is_array($operand)); + } + } + // Numbers, matrices and booleans can pass straight through, as they're already valid + if (is_string($operand)) { + // We only need special validations for the operand if it is a string + // Start by stripping off the quotation marks we use to identify true excel string values internally + if ($operand > '' && $operand{0} == '"') { $operand = self::_unwrapResult($operand); } + // If the string is a numeric value, we treat it as a numeric, so no further testing + if (!is_numeric($operand)) { + // If not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations + if ($operand > '' && $operand{0} == '#') { + $stack->push('Value', $operand); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand)); + return FALSE; + } elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) { + // If not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations + $stack->push('Value', '#VALUE!'); + $this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!')); + return FALSE; + } + } + } + + // return a true if the value of the operand is one that we can use in normal binary operations + return TRUE; + } // function _validateBinaryOperand() + + + private function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) { + // If we're dealing with matrix operations, we want a matrix result + if ((is_array($operand1)) || (is_array($operand2))) { + $result = array(); + if ((is_array($operand1)) && (!is_array($operand2))) { + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2)); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } elseif ((!is_array($operand1)) && (is_array($operand2))) { + foreach($operand2 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData)); + $this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } else { + if (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); } + foreach($operand1 as $x => $operandData) { + $this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x])); + $this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE); + $r = $stack->pop(); + $result[$x] = $r['value']; + } + } + // Log the result details + $this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Array',$result); + return TRUE; + } + + // Simple validate the two operands if they are string values + if (is_string($operand1) && $operand1 > '' && $operand1{0} == '"') { $operand1 = self::_unwrapResult($operand1); } + if (is_string($operand2) && $operand2 > '' && $operand2{0} == '"') { $operand2 = self::_unwrapResult($operand2); } + + // Use case insensitive comparaison if not OpenOffice mode + if (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) + { + if (is_string($operand1)) { + $operand1 = strtoupper($operand1); + } + + if (is_string($operand2)) { + $operand2 = strtoupper($operand2); + } + } + + $useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE; + + // execute the necessary operation + switch ($operation) { + // Greater than + case '>': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0; + } else { + $result = ($operand1 > $operand2); + } + break; + // Less than + case '<': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0; + } else { + $result = ($operand1 < $operand2); + } + break; + // Equality + case '=': + $result = ($operand1 == $operand2); + break; + // Greater than or equal + case '>=': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0; + } else { + $result = ($operand1 >= $operand2); + } + break; + // Less than or equal + case '<=': + if ($useLowercaseFirstComparison) { + $result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0; + } else { + $result = ($operand1 <= $operand2); + } + break; + // Inequality + case '<>': + $result = ($operand1 != $operand2); + break; + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeBinaryComparisonOperation() + + /** + * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters + * @param string $str1 + * @param string $str2 + * @return integer + */ + private function strcmpLowercaseFirst($str1, $str2) + { + $from = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $to = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $inversedStr1 = strtr($str1, $from, $to); + $inversedStr2 = strtr($str2, $from, $to); + + return strcmp($inversedStr1, $inversedStr2); + } + + private function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) { + // Validate the two operands + if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE; + if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE; + + // If either of the operands is a matrix, we need to treat them both as matrices + // (converting the other operand to a matrix if need be); then perform the required + // matrix operation + if ((is_array($operand1)) || (is_array($operand2))) { + // Ensure that both operands are arrays/matrices of the same size + self::_checkMatrixOperands($operand1, $operand2, 2); + + try { + // Convert operand 1 from a PHP array to a matrix + $matrix = new PHPExcel_Shared_JAMA_Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 + $matrixResult = $matrix->$matrixFunction($operand2); + $result = $matrixResult->getArray(); + } catch (PHPExcel_Exception $ex) { + $this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); + $result = '#VALUE!'; + } + } else { + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) && + ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || + (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) { + $result = PHPExcel_Calculation_Functions::VALUE(); + } else { + // If we're dealing with non-matrix operations, execute the necessary operation + switch ($operation) { + // Addition + case '+': + $result = $operand1 + $operand2; + break; + // Subtraction + case '-': + $result = $operand1 - $operand2; + break; + // Multiplication + case '*': + $result = $operand1 * $operand2; + break; + // Division + case '/': + if ($operand2 == 0) { + // Trap for Divide by Zero error + $stack->push('Value','#DIV/0!'); + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!')); + return FALSE; + } else { + $result = $operand1 / $operand2; + } + break; + // Power + case '^': + $result = pow($operand1, $operand2); + break; + } + } + } + + // Log the result details + $this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result)); + // And push the result onto the stack + $stack->push('Value',$result); + return TRUE; + } // function _executeNumericBinaryOperation() + + + // trigger an error, but nicely, if need be + protected function _raiseFormulaError($errorMessage) { + $this->formulaError = $errorMessage; + $this->_cyclicReferenceStack->clear(); + if (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage); + trigger_error($errorMessage, E_USER_ERROR); + } // function _raiseFormulaError() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @throws PHPExcel_Calculation_Exception + */ + public function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractCellRange('.$pRange.')',PHP_EOL; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Passed sheet name is '.$pSheetName.PHP_EOL; +// echo 'Range reference is '.$pRange.PHP_EOL; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + $pRange = $pSheetName.'!'.$pRange; + if (!isset($aReferences[1])) { + // Single cell in range + sscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + sscanf($reference,'%[A-Z]%d', $currentCol, $currentRow); + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } + } + + // Return + return $returnValue; + } // function extractCellRange() + + + /** + * Extract range values + * + * @param string &$pRange String based range representation + * @param PHPExcel_Worksheet $pSheet Worksheet + * @return mixed Array of values in range if range contains more than one element. Otherwise, a single value is returned. + * @param boolean $resetLog Flag indicating whether calculation log should be reset or not + * @throws PHPExcel_Calculation_Exception + */ + public function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) { + // Return value + $returnValue = array (); + +// echo 'extractNamedRange('.$pRange.')
'; + if ($pSheet !== NULL) { + $pSheetName = $pSheet->getTitle(); +// echo 'Current sheet name is '.$pSheetName.'
'; +// echo 'Range reference is '.$pRange.'
'; + if (strpos ($pRange, '!') !== false) { +// echo '$pRange reference includes sheet reference',PHP_EOL; + list($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true); +// echo 'New sheet name is '.$pSheetName,PHP_EOL; +// echo 'Adjusted Range reference is '.$pRange,PHP_EOL; + $pSheet = $this->_workbook->getSheetByName($pSheetName); + } + + // Named range? + $namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet); + if ($namedRange !== NULL) { + $pSheet = $namedRange->getWorksheet(); +// echo 'Named Range '.$pRange.' ('; + $pRange = $namedRange->getRange(); + $splitRange = PHPExcel_Cell::splitRange($pRange); + // Convert row and column references + if (ctype_alpha($splitRange[0][0])) { + $pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow(); + } elseif(ctype_digit($splitRange[0][0])) { + $pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1]; + } +// echo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'
'; + +// if ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) { +// if (!$namedRange->getLocalOnly()) { +// $pSheet = $namedRange->getWorksheet(); +// } else { +// return $returnValue; +// } +// } + } else { + return PHPExcel_Calculation_Functions::REF(); + } + + // Extract range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); +// var_dump($aReferences); + if (!isset($aReferences[1])) { + // Single cell (or single column or row) in range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]); + $cellValue = NULL; + if ($pSheet->cellExists($aReferences[0])) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } else { + // Extract cell data for all cells in the range + foreach ($aReferences as $reference) { + // Extract range + list($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference); +// echo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'
'; + $cellValue = NULL; + if ($pSheet->cellExists($reference)) { + $returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog); + } else { + $returnValue[$currentRow][$currentCol] = NULL; + } + } + } +// print_r($returnValue); +// echo '
'; + } + + // Return + return $returnValue; + } // function extractNamedRange() + + + /** + * Is a specific function implemented? + * + * @param string $pFunction Function Name + * @return boolean + */ + public function isImplemented($pFunction = '') { + $pFunction = strtoupper ($pFunction); + if (isset(self::$_PHPExcelFunctions[$pFunction])) { + return (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY'); + } else { + return FALSE; + } + } // function isImplemented() + + + /** + * Get a list of all implemented functions as an array of function objects + * + * @return array of PHPExcel_Calculation_Function + */ + public function listFunctions() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'], + $functionName, + $function['functionCall'] + ); + } + } + + // Return + return $returnValue; + } // function listFunctions() + + + /** + * Get a list of all Excel function names + * + * @return array + */ + public function listAllFunctionNames() { + return array_keys(self::$_PHPExcelFunctions); + } // function listAllFunctionNames() + + /** + * Get a list of implemented Excel function names + * + * @return array + */ + public function listFunctionNames() { + // Return value + $returnValue = array(); + // Loop functions + foreach(self::$_PHPExcelFunctions as $functionName => $function) { + if ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') { + $returnValue[] = $functionName; + } + } + + // Return + return $returnValue; + } // function listFunctionNames() + +} // class PHPExcel_Calculation + diff --git a/extend/phpexcel/PHPExcel/Calculation/Database.php b/extend/phpexcel/PHPExcel/Calculation/Database.php new file mode 100755 index 0000000..c3e86d7 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Database.php @@ -0,0 +1,725 @@ + $criteriaName) { + $testCondition = array(); + $testConditionCount = 0; + foreach($criteria as $row => $criterion) { + if ($criterion[$key] > '') { + $testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]); + $testConditionCount++; + } + } + if ($testConditionCount > 1) { + $testConditions[] = 'OR('.implode(',',$testCondition).')'; + $testConditionsCount++; + } elseif($testConditionCount == 1) { + $testConditions[] = $testCondition[0]; + $testConditionsCount++; + } + } + + if ($testConditionsCount > 1) { + $testConditionSet = 'AND('.implode(',',$testConditions).')'; + } elseif($testConditionsCount == 1) { + $testConditionSet = $testConditions[0]; + } + + // Loop through each row of the database + foreach($database as $dataRow => $dataValues) { + // Substitute actual values from the database row for our [:placeholders] + $testConditionList = $testConditionSet; + foreach($criteriaNames as $key => $criteriaName) { + $k = array_search($criteriaName,$fieldNames); + if (isset($dataValues[$k])) { + $dataValue = $dataValues[$k]; + $dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue; + $testConditionList = str_replace('[:'.$criteriaName.']',$dataValue,$testConditionList); + } + } + // evaluate the criteria against the row data + $result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList); + // If the row failed to meet the criteria, remove it from the database + if (!$result) { + unset($database[$dataRow]); + } + } + + return $database; + } + + + /** + * DAVERAGE + * + * Averages the values in a column of a list or database that match conditions you specify. + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DAVERAGE($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::AVERAGE($colData); + } // function DAVERAGE() + + + /** + * DCOUNT + * + * Counts the cells that contain numbers in a column of a list or database that match conditions + * that you specify. + * + * Excel Function: + * DCOUNT(database,[field],criteria) + * + * Excel Function: + * DAVERAGE(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNT counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNT($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNT($colData); + } // function DCOUNT() + + + /** + * DCOUNTA + * + * Counts the nonblank cells in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DCOUNTA(database,[field],criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return integer + * + * @TODO The field argument is optional. If field is omitted, DCOUNTA counts all records in the + * database that match the criteria. + * + */ + public static function DCOUNTA($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::COUNTA($colData); + } // function DCOUNTA() + + + /** + * DGET + * + * Extracts a single value from a column of a list or database that matches conditions that you + * specify. + * + * Excel Function: + * DGET(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return mixed + * + */ + public static function DGET($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + if (count($colData) > 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return $colData[0]; + } // function DGET() + + + /** + * DMAX + * + * Returns the largest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMAX(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMAX($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::MAX($colData); + } // function DMAX() + + + /** + * DMIN + * + * Returns the smallest number in a column of a list or database that matches conditions you that + * specify. + * + * Excel Function: + * DMIN(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DMIN($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::MIN($colData); + } // function DMIN() + + + /** + * DPRODUCT + * + * Multiplies the values in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DPRODUCT(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DPRODUCT($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_MathTrig::PRODUCT($colData); + } // function DPRODUCT() + + + /** + * DSTDEV + * + * Estimates the standard deviation of a population based on a sample by using the numbers in a + * column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEV(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEV($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEV($colData); + } // function DSTDEV() + + + /** + * DSTDEVP + * + * Calculates the standard deviation of a population based on the entire population by using the + * numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSTDEVP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSTDEVP($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::STDEVP($colData); + } // function DSTDEVP() + + + /** + * DSUM + * + * Adds the numbers in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DSUM(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DSUM($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_MathTrig::SUM($colData); + } // function DSUM() + + + /** + * DVAR + * + * Estimates the variance of a population based on a sample by using the numbers in a column + * of a list or database that match conditions that you specify. + * + * Excel Function: + * DVAR(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVAR($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::VARFunc($colData); + } // function DVAR() + + + /** + * DVARP + * + * Calculates the variance of a population based on the entire population by using the numbers + * in a column of a list or database that match conditions that you specify. + * + * Excel Function: + * DVARP(database,field,criteria) + * + * @access public + * @category Database Functions + * @param mixed[] $database The range of cells that makes up the list or database. + * A database is a list of related data in which rows of related + * information are records, and columns of data are fields. The + * first row of the list contains labels for each column. + * @param string|integer $field Indicates which column is used in the function. Enter the + * column label enclosed between double quotation marks, such as + * "Age" or "Yield," or a number (without quotation marks) that + * represents the position of the column within the list: 1 for + * the first column, 2 for the second column, and so on. + * @param mixed[] $criteria The range of cells that contains the conditions you specify. + * You can use any range for the criteria argument, as long as it + * includes at least one column label and at least one cell below + * the column label in which you specify a condition for the + * column. + * @return float + * + */ + public static function DVARP($database,$field,$criteria) { + $field = self::__fieldExtract($database,$field); + if (is_null($field)) { + return NULL; + } + + // reduce the database to a set of rows that match all the criteria + $database = self::__filter($database,$criteria); + // extract an array of values for the requested column + $colData = array(); + foreach($database as $row) { + $colData[] = $row[$field]; + } + + // Return + return PHPExcel_Calculation_Statistical::VARP($colData); + } // function DVARP() + + +} // class PHPExcel_Calculation_Database diff --git a/extend/phpexcel/PHPExcel/Calculation/DateTime.php b/extend/phpexcel/PHPExcel/Calculation/DateTime.php new file mode 100755 index 0000000..debd131 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/DateTime.php @@ -0,0 +1,1475 @@ +format('m'); + $oYear = (int) $PHPDateObject->format('Y'); + + $adjustmentMonthsString = (string) $adjustmentMonths; + if ($adjustmentMonths > 0) { + $adjustmentMonthsString = '+'.$adjustmentMonths; + } + if ($adjustmentMonths != 0) { + $PHPDateObject->modify($adjustmentMonthsString.' months'); + } + $nMonth = (int) $PHPDateObject->format('m'); + $nYear = (int) $PHPDateObject->format('Y'); + + $monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12); + if ($monthDiff != $adjustmentMonths) { + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-'.$adjustDays.' days'; + $PHPDateObject->modify($adjustDaysString); + } + return $PHPDateObject; + } // function _adjustDateByMonths() + + + /** + * DATETIMENOW + * + * Returns the current date and time. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * NOW() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATETIMENOW() { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = False; + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $retValue = (float) PHPExcel_Shared_Date::PHPToExcel(time()); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + $retValue = (integer) time(); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $retValue = new DateTime(); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function DATETIMENOW() + + + /** + * DATENOW + * + * Returns the current date. + * The NOW function is useful when you need to display the current date and time on a worksheet or + * calculate a value based on the current date and time, and have that value updated each time you + * open the worksheet. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * and time format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TODAY() + * + * @access public + * @category Date/Time Functions + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATENOW() { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = False; + $excelDateTime = floor(PHPExcel_Shared_Date::PHPToExcel(time())); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $retValue = (float) $excelDateTime; + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + $retValue = (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateTime); + break; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $retValue = PHPExcel_Shared_Date::ExcelToPHPObject($excelDateTime); + break; + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function DATENOW() + + + /** + * DATE + * + * The DATE function returns a value that represents a particular date. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATE(year,month,day) + * + * PHPExcel is a lot more forgiving than MS Excel when passing non numeric values to this function. + * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, + * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. + * + * @access public + * @category Date/Time Functions + * @param integer $year The value of the year argument can include one to four digits. + * Excel interprets the year argument according to the configured + * date system: 1900 or 1904. + * If year is between 0 (zero) and 1899 (inclusive), Excel adds that + * value to 1900 to calculate the year. For example, DATE(108,1,2) + * returns January 2, 2008 (1900+108). + * If year is between 1900 and 9999 (inclusive), Excel uses that + * value as the year. For example, DATE(2008,1,2) returns January 2, + * 2008. + * If year is less than 0 or is 10000 or greater, Excel returns the + * #NUM! error value. + * @param integer $month A positive or negative integer representing the month of the year + * from 1 to 12 (January to December). + * If month is greater than 12, month adds that number of months to + * the first month in the year specified. For example, DATE(2008,14,2) + * returns the serial number representing February 2, 2009. + * If month is less than 1, month subtracts the magnitude of that + * number of months, plus 1, from the first month in the year + * specified. For example, DATE(2008,-3,2) returns the serial number + * representing September 2, 2007. + * @param integer $day A positive or negative integer representing the day of the month + * from 1 to 31. + * If day is greater than the number of days in the month specified, + * day adds that number of days to the first day in the month. For + * example, DATE(2008,1,35) returns the serial number representing + * February 4, 2008. + * If day is less than 1, day subtracts the magnitude that number of + * days, plus one, from the first day of the month specified. For + * example, DATE(2008,1,-15) returns the serial number representing + * December 16, 2007. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATE($year = 0, $month = 1, $day = 1) { + $year = PHPExcel_Calculation_Functions::flattenSingleValue($year); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + $day = PHPExcel_Calculation_Functions::flattenSingleValue($day); + + if (($month !== NULL) && (!is_numeric($month))) { + $month = PHPExcel_Shared_Date::monthStringToNumber($month); + } + + if (($day !== NULL) && (!is_numeric($day))) { + $day = PHPExcel_Shared_Date::dayStringToNumber($day); + } + + $year = ($year !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($year) : 0; + $month = ($month !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($month) : 0; + $day = ($day !== NULL) ? PHPExcel_Shared_String::testStringAsNumeric($day) : 0; + if ((!is_numeric($year)) || + (!is_numeric($month)) || + (!is_numeric($day))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $year = (integer) $year; + $month = (integer) $month; + $day = (integer) $day; + + $baseYear = PHPExcel_Shared_Date::getExcelCalendar(); + // Validate parameters + if ($year < ($baseYear-1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((($baseYear-1900) != 0) && ($year < $baseYear) && ($year >= 1900)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (($year < $baseYear) && ($year >= ($baseYear-1900))) { + $year += 1900; + } + + if ($month < 1) { + // Handle year/month adjustment if month < 1 + --$month; + $year += ceil($month / 12) - 1; + $month = 13 - abs($month % 12); + } elseif ($month > 12) { + // Handle year/month adjustment if month > 12 + $year += floor($month / 12); + $month = ($month % 12); + } + + // Re-validate the year parameter after adjustments + if (($year < $baseYear) || ($year >= 10000)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day); + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return PHPExcel_Shared_Date::ExcelToPHPObject($excelDateValue); + } + } // function DATE() + + + /** + * TIME + * + * The TIME function returns a value that represents a particular time. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIME(hour,minute,second) + * + * @access public + * @category Date/Time Functions + * @param integer $hour A number from 0 (zero) to 32767 representing the hour. + * Any value greater than 23 will be divided by 24 and the remainder + * will be treated as the hour value. For example, TIME(27,0,0) = + * TIME(3,0,0) = .125 or 3:00 AM. + * @param integer $minute A number from 0 to 32767 representing the minute. + * Any value greater than 59 will be converted to hours and minutes. + * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. + * @param integer $second A number from 0 to 32767 representing the second. + * Any value greater than 59 will be converted to hours, minutes, + * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 + * or 12:33:20 AM + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIME($hour = 0, $minute = 0, $second = 0) { + $hour = PHPExcel_Calculation_Functions::flattenSingleValue($hour); + $minute = PHPExcel_Calculation_Functions::flattenSingleValue($minute); + $second = PHPExcel_Calculation_Functions::flattenSingleValue($second); + + if ($hour == '') { $hour = 0; } + if ($minute == '') { $minute = 0; } + if ($second == '') { $second = 0; } + + if ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $hour = (integer) $hour; + $minute = (integer) $minute; + $second = (integer) $second; + + if ($second < 0) { + $minute += floor($second / 60); + $second = 60 - abs($second % 60); + if ($second == 60) { $second = 0; } + } elseif ($second >= 60) { + $minute += floor($second / 60); + $second = $second % 60; + } + if ($minute < 0) { + $hour += floor($minute / 60); + $minute = 60 - abs($minute % 60); + if ($minute == 60) { $minute = 0; } + } elseif ($minute >= 60) { + $hour += floor($minute / 60); + $minute = $minute % 60; + } + + if ($hour > 23) { + $hour = $hour % 24; + } elseif ($hour < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + $date = 0; + $calendar = PHPExcel_Shared_Date::getExcelCalendar(); + if ($calendar != PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900) { + $date = 1; + } + return (float) PHPExcel_Shared_Date::FormattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::FormattedPHPToExcel(1970, 1, 1, $hour, $minute, $second)); // -2147468400; // -2147472000 + 3600 + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + $dayAdjust = 0; + if ($hour < 0) { + $dayAdjust = floor($hour / 24); + $hour = 24 - abs($hour % 24); + if ($hour == 24) { $hour = 0; } + } elseif ($hour >= 24) { + $dayAdjust = floor($hour / 24); + $hour = $hour % 24; + } + $phpDateObject = new DateTime('1900-01-01 '.$hour.':'.$minute.':'.$second); + if ($dayAdjust != 0) { + $phpDateObject->modify($dayAdjust.' days'); + } + return $phpDateObject; + } + } // function TIME() + + + /** + * DATEVALUE + * + * Returns a value that represents a particular date. + * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * DATEVALUE(dateValue) + * + * @access public + * @category Date/Time Functions + * @param string $dateValue Text that represents a date in a Microsoft Excel date format. + * For example, "1/30/2008" or "30-Jan-2008" are text strings within + * quotation marks that represent dates. Using the default date + * system in Excel for Windows, date_text must represent a date from + * January 1, 1900, to December 31, 9999. Using the default date + * system in Excel for the Macintosh, date_text must represent a date + * from January 1, 1904, to December 31, 9999. DATEVALUE returns the + * #VALUE! error value if date_text is out of this range. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function DATEVALUE($dateValue = 1) { + $dateValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($dateValue),'"'); + // Strip any ordinals because they're allowed in Excel (English only) + $dateValue = preg_replace('/(\d)(st|nd|rd|th)([ -\/])/Ui','$1$3',$dateValue); + // Convert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany) + $dateValue = str_replace(array('/','.','-',' '),array(' ',' ',' ',' '),$dateValue); + + $yearFound = false; + $t1 = explode(' ',$dateValue); + foreach($t1 as &$t) { + if ((is_numeric($t)) && ($t > 31)) { + if ($yearFound) { + return PHPExcel_Calculation_Functions::VALUE(); + } else { + if ($t < 100) { $t += 1900; } + $yearFound = true; + } + } + } + if ((count($t1) == 1) && (strpos($t,':') != false)) { + // We've been fed a time value without any date + return 0.0; + } elseif (count($t1) == 2) { + // We only have two parts of the date: either day/month or month/year + if ($yearFound) { + array_unshift($t1,1); + } else { + array_push($t1,date('Y')); + } + } + unset($t); + $dateValue = implode(' ',$t1); + + $PHPDateArray = date_parse($dateValue); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + $testVal1 = strtok($dateValue,'- '); + if ($testVal1 !== False) { + $testVal2 = strtok('- '); + if ($testVal2 !== False) { + $testVal3 = strtok('- '); + if ($testVal3 === False) { + $testVal3 = strftime('%Y'); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $PHPDateArray = date_parse($testVal1.'-'.$testVal2.'-'.$testVal3); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + $PHPDateArray = date_parse($testVal2.'-'.$testVal1.'-'.$testVal3); + if (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + } + + if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { + // Execute function + if ($PHPDateArray['year'] == '') { $PHPDateArray['year'] = strftime('%Y'); } + if ($PHPDateArray['year'] < 1900) + return PHPExcel_Calculation_Functions::VALUE(); + if ($PHPDateArray['month'] == '') { $PHPDateArray['month'] = strftime('%m'); } + if ($PHPDateArray['day'] == '') { $PHPDateArray['day'] = strftime('%d'); } + $excelDateValue = floor(PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second'])); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return new DateTime($PHPDateArray['year'].'-'.$PHPDateArray['month'].'-'.$PHPDateArray['day'].' 00:00:00'); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DATEVALUE() + + + /** + * TIMEVALUE + * + * Returns a value that represents a particular time. + * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp + * value. + * + * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time + * format of your regional settings. PHPExcel does not change cell formatting in this way. + * + * Excel Function: + * TIMEVALUE(timeValue) + * + * @access public + * @category Date/Time Functions + * @param string $timeValue A text string that represents a time in any one of the Microsoft + * Excel time formats; for example, "6:45 PM" and "18:45" text strings + * within quotation marks that represent time. + * Date information in time_text is ignored. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function TIMEVALUE($timeValue) { + $timeValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($timeValue),'"'); + $timeValue = str_replace(array('/','.'),array('-','-'),$timeValue); + + $PHPDateArray = date_parse($timeValue); + if (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']); + } else { + $excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel(1900,1,1,$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']) - 1; + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $excelDateValue; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) $phpDateValue = PHPExcel_Shared_Date::ExcelToPHP($excelDateValue+25569) - 3600;; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return new DateTime('1900-01-01 '.$PHPDateArray['hour'].':'.$PHPDateArray['minute'].':'.$PHPDateArray['second']); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TIMEVALUE() + + + /** + * DATEDIF + * + * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object + * or a standard date string + * @param string $unit + * @return integer Interval between the dates + */ + public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $unit = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($unit)); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate parameters + if ($startDate >= $endDate) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $difference = $endDate - $startDate; + + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDays = $PHPStartDateObject->format('j'); + $startMonths = $PHPStartDateObject->format('n'); + $startYears = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDays = $PHPEndDateObject->format('j'); + $endMonths = $PHPEndDateObject->format('n'); + $endYears = $PHPEndDateObject->format('Y'); + + $retVal = PHPExcel_Calculation_Functions::NaN(); + switch ($unit) { + case 'D': + $retVal = intval($difference); + break; + case 'M': + $retVal = intval($endMonths - $startMonths) + (intval($endYears - $startYears) * 12); + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'Y': + $retVal = intval($endYears - $startYears); + // We're only interested in full months + if ($endMonths < $startMonths) { + --$retVal; + } elseif (($endMonths == $startMonths) && ($endDays < $startDays)) { + --$retVal; + } + break; + case 'MD': + if ($endDays < $startDays) { + $retVal = $endDays; + $PHPEndDateObject->modify('-'.$endDays.' days'); + $adjustDays = $PHPEndDateObject->format('j'); + if ($adjustDays > $startDays) { + $retVal += ($adjustDays - $startDays); + } + } else { + $retVal = $endDays - $startDays; + } + break; + case 'YM': + $retVal = intval($endMonths - $startMonths); + if ($retVal < 0) $retVal = 12 + $retVal; + // We're only interested in full months + if ($endDays < $startDays) { + --$retVal; + } + break; + case 'YD': + $retVal = intval($difference); + if ($endYears > $startYears) { + while ($endYears > $startYears) { + $PHPEndDateObject->modify('-1 year'); + $endYears = $PHPEndDateObject->format('Y'); + } + $retVal = $PHPEndDateObject->format('z') - $PHPStartDateObject->format('z'); + if ($retVal < 0) { $retVal += 365; } + } + break; + default: + $retVal = PHPExcel_Calculation_Functions::NaN(); + } + return $retVal; + } // function DATEDIF() + + + /** + * DAYS360 + * + * Returns the number of days between two dates based on a 360-day year (twelve 30-day months), + * which is used in some accounting calculations. Use this function to help compute payments if + * your accounting system is based on twelve 30-day months. + * + * Excel Function: + * DAYS360(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method US or European Method + * FALSE or omitted: U.S. (NASD) method. If the starting date is + * the last day of a month, it becomes equal to the 30th of the + * same month. If the ending date is the last day of a month and + * the starting date is earlier than the 30th of a month, the + * ending date becomes equal to the 1st of the next month; + * otherwise the ending date becomes equal to the 30th of the + * same month. + * TRUE: European method. Starting dates and ending dates that + * occur on the 31st of a month become equal to the 30th of the + * same month. + * @return integer Number of days between start date and end date + */ + public static function DAYS360($startDate = 0, $endDate = 0, $method = false) { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_bool($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate); + $startDay = $PHPStartDateObject->format('j'); + $startMonth = $PHPStartDateObject->format('n'); + $startYear = $PHPStartDateObject->format('Y'); + + $PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + $endDay = $PHPEndDateObject->format('j'); + $endMonth = $PHPEndDateObject->format('n'); + $endYear = $PHPEndDateObject->format('Y'); + + return self::_dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method); + } // function DAYS360() + + + /** + * YEARFRAC + * + * Calculates the fraction of the year represented by the number of whole days between two dates + * (the start_date and the end_date). + * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or + * obligations to assign to a specific term. + * + * Excel Function: + * YEARFRAC(startDate,endDate[,method]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $method Method used for the calculation + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float fraction of the year + */ + public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) { + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (is_string($startDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($endDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (((is_numeric($method)) && (!is_string($method))) || ($method == '')) { + switch($method) { + case 0 : + return self::DAYS360($startDate,$endDate) / 360; + case 1 : + $days = self::DATEDIF($startDate,$endDate); + $startYear = self::YEAR($startDate); + $endYear = self::YEAR($endDate); + $years = $endYear - $startYear + 1; + $leapDays = 0; + if ($years == 1) { + if (self::_isLeapYear($endYear)) { + $startMonth = self::MONTHOFYEAR($startDate); + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($startMonth < 3) || + (($endMonth * 100 + $endDay) >= (2 * 100 + 29))) { + $leapDays += 1; + } + } + } else { + for($year = $startYear; $year <= $endYear; ++$year) { + if ($year == $startYear) { + $startMonth = self::MONTHOFYEAR($startDate); + $startDay = self::DAYOFMONTH($startDate); + if ($startMonth < 3) { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } elseif($year == $endYear) { + $endMonth = self::MONTHOFYEAR($endDate); + $endDay = self::DAYOFMONTH($endDate); + if (($endMonth * 100 + $endDay) >= (2 * 100 + 29)) { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } else { + $leapDays += (self::_isLeapYear($year)) ? 1 : 0; + } + } + if ($years == 2) { + if (($leapDays == 0) && (self::_isLeapYear($startYear)) && ($days > 365)) { + $leapDays = 1; + } elseif ($days < 366) { + $years = 1; + } + } + $leapDays /= $years; + } + return $days / (365 + $leapDays); + case 2 : + return self::DATEDIF($startDate,$endDate) / 360; + case 3 : + return self::DATEDIF($startDate,$endDate) / 365; + case 4 : + return self::DAYS360($startDate,$endDate,True) / 360; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YEARFRAC() + + + /** + * NETWORKDAYS + * + * Returns the number of whole working days between start_date and end_date. Working days + * exclude weekends and any dates identified in holidays. + * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days + * worked during a specific term. + * + * Excel Function: + * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return integer Interval between the dates + */ + public static function NETWORKDAYS($startDate,$endDate) { + // Retrieve the mandatory start and end date that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDate = PHPExcel_Calculation_Functions::flattenSingleValue($endDate); + // Flush the mandatory start and end date that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + // Validate the start and end dates + if (is_string($startDate = $sDate = self::_getDateValue($startDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + if (is_string($endDate = $eDate = self::_getDateValue($endDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $endDate = (float) floor($endDate); + + if ($sDate > $eDate) { + $startDate = $eDate; + $endDate = $sDate; + } + + // Execute function + $startDoW = 6 - self::DAYOFWEEK($startDate,2); + if ($startDoW < 0) { $startDoW = 0; } + $endDoW = self::DAYOFWEEK($endDate,2); + if ($endDoW >= 6) { $endDoW = 0; } + + $wholeWeekDays = floor(($endDate - $startDate) / 7) * 5; + $partWeekDays = $endDoW + $startDoW; + if ($partWeekDays > 5) { + $partWeekDays -= 5; + } + + // Test any extra holiday parameters + $holidayCountedArray = array(); + foreach ($dateArgs as $holidayDate) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if ((self::DAYOFWEEK($holidayDate,2) < 6) && (!in_array($holidayDate,$holidayCountedArray))) { + --$partWeekDays; + $holidayCountedArray[] = $holidayDate; + } + } + } + + if ($sDate > $eDate) { + return 0 - ($wholeWeekDays + $partWeekDays); + } + return $wholeWeekDays + $partWeekDays; + } // function NETWORKDAYS() + + + /** + * WORKDAY + * + * Returns the date that is the indicated number of working days before or after a date (the + * starting date). Working days exclude weekends and any dates identified as holidays. + * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected + * delivery times, or the number of days of work performed. + * + * Excel Function: + * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) + * + * @access public + * @category Date/Time Functions + * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param integer $endDays The number of nonweekend and nonholiday days before or after + * startDate. A positive value for days yields a future date; a + * negative value yields a past date. + * @param mixed $holidays,... Optional series of Excel date serial value (float), PHP date + * timestamp (integer), PHP DateTime object, or a standard date + * strings that will be excluded from the working calendar, such + * as state and federal holidays and floating holidays. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function WORKDAY($startDate,$endDays) { + // Retrieve the mandatory start date and days that are referenced in the function definition + $startDate = PHPExcel_Calculation_Functions::flattenSingleValue($startDate); + $endDays = PHPExcel_Calculation_Functions::flattenSingleValue($endDays); + // Flush the mandatory start date and days that are referenced in the function definition, and get the optional days + $dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + array_shift($dateArgs); + array_shift($dateArgs); + + if ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $startDate = (float) floor($startDate); + $endDays = (int) floor($endDays); + // If endDays is 0, we always return startDate + if ($endDays == 0) { return $startDate; } + + $decrementing = ($endDays < 0) ? True : False; + + // Adjust the start date if it falls over a weekend + + $startDoW = self::DAYOFWEEK($startDate,3); + if (self::DAYOFWEEK($startDate,3) >= 5) { + $startDate += ($decrementing) ? -$startDoW + 4: 7 - $startDoW; + ($decrementing) ? $endDays++ : $endDays--; + } + + // Add endDays + $endDate = (float) $startDate + (intval($endDays / 5) * 7) + ($endDays % 5); + + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate,3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; + } + + // Test any extra holiday parameters + if (!empty($dateArgs)) { + $holidayCountedArray = $holidayDates = array(); + foreach ($dateArgs as $holidayDate) { + if (($holidayDate !== NULL) && (trim($holidayDate) > '')) { + if (is_string($holidayDate = self::_getDateValue($holidayDate))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (self::DAYOFWEEK($holidayDate,3) < 5) { + $holidayDates[] = $holidayDate; + } + } + } + if ($decrementing) { + rsort($holidayDates, SORT_NUMERIC); + } else { + sort($holidayDates, SORT_NUMERIC); + } + foreach ($holidayDates as $holidayDate) { + if ($decrementing) { + if (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) { + if (!in_array($holidayDate,$holidayCountedArray)) { + --$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } else { + if (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) { + if (!in_array($holidayDate,$holidayCountedArray)) { + ++$endDate; + $holidayCountedArray[] = $holidayDate; + } + } + } + // Adjust the calculated end date if it falls over a weekend + $endDoW = self::DAYOFWEEK($endDate,3); + if ($endDoW >= 5) { + $endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW; + } + + } + } + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) $endDate; + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP($endDate); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return PHPExcel_Shared_Date::ExcelToPHPObject($endDate); + } + } // function WORKDAY() + + + /** + * DAYOFMONTH + * + * Returns the day of the month, for a specified date. The day is given as an integer + * ranging from 1 to 31. + * + * Excel Function: + * DAY(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Day of the month + */ + public static function DAYOFMONTH($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue == 0.0) { + return 0; + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('j'); + } // function DAYOFMONTH() + + + /** + * DAYOFWEEK + * + * Returns the day of the week for a specified date. The day is given as an integer + * ranging from 0 to 7 (dependent on the requested style). + * + * Excel Function: + * WEEKDAY(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $style A number that determines the type of return value + * 1 or omitted Numbers 1 (Sunday) through 7 (Saturday). + * 2 Numbers 1 (Monday) through 7 (Sunday). + * 3 Numbers 0 (Monday) through 6 (Sunday). + * @return int Day of the week value + */ + public static function DAYOFWEEK($dateValue = 1, $style = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $style = PHPExcel_Calculation_Functions::flattenSingleValue($style); + + if (!is_numeric($style)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($style < 1) || ($style > 3)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $style = floor($style); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $DoW = $PHPDateObject->format('w'); + + $firstDay = 1; + switch ($style) { + case 1: ++$DoW; + break; + case 2: if ($DoW == 0) { $DoW = 7; } + break; + case 3: if ($DoW == 0) { $DoW = 7; } + $firstDay = 0; + --$DoW; + break; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL) { + // Test for Excel's 1900 leap year, and introduce the error as required + if (($PHPDateObject->format('Y') == 1900) && ($PHPDateObject->format('n') <= 2)) { + --$DoW; + if ($DoW < $firstDay) { + $DoW += 7; + } + } + } + + return (int) $DoW; + } // function DAYOFWEEK() + + + /** + * WEEKOFYEAR + * + * Returns the week of the year for a specified date. + * The WEEKNUM function considers the week containing January 1 to be the first week of the year. + * However, there is a European standard that defines the first week as the one with the majority + * of days (four or more) falling in the new year. This means that for years in which there are + * three days or less in the first week of January, the WEEKNUM function returns week numbers + * that are incorrect according to the European standard. + * + * Excel Function: + * WEEKNUM(dateValue[,style]) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param boolean $method Week begins on Sunday or Monday + * 1 or omitted Week begins on Sunday. + * 2 Week begins on Monday. + * @return int Week Number + */ + public static function WEEKOFYEAR($dateValue = 1, $method = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $method = PHPExcel_Calculation_Functions::flattenSingleValue($method); + + if (!is_numeric($method)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif (($method < 1) || ($method > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $method = floor($method); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + $dayOfYear = $PHPDateObject->format('z'); + $dow = $PHPDateObject->format('w'); + $PHPDateObject->modify('-'.$dayOfYear.' days'); + $dow = $PHPDateObject->format('w'); + $daysInFirstWeek = 7 - (($dow + (2 - $method)) % 7); + $dayOfYear -= $daysInFirstWeek; + $weekOfYear = ceil($dayOfYear / 7) + 1; + + return (int) $weekOfYear; + } // function WEEKOFYEAR() + + + /** + * MONTHOFYEAR + * + * Returns the month of a date represented by a serial number. + * The month is given as an integer, ranging from 1 (January) to 12 (December). + * + * Excel Function: + * MONTH(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Month of the year + */ + public static function MONTHOFYEAR($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('n'); + } // function MONTHOFYEAR() + + + /** + * YEAR + * + * Returns the year corresponding to a date. + * The year is returned as an integer in the range 1900-9999. + * + * Excel Function: + * YEAR(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @return int Year + */ + public static function YEAR($dateValue = 1) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Execute function + $PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue); + + return (int) $PHPDateObject->format('Y'); + } // function YEAR() + + + /** + * HOUROFDAY + * + * Returns the hour of a time value. + * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). + * + * Excel Function: + * HOUR(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Hour + */ + public static function HOUROFDAY($timeValue = 0) { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('G',$timeValue); + } // function HOUROFDAY() + + + /** + * MINUTEOFHOUR + * + * Returns the minutes of a time value. + * The minute is given as an integer, ranging from 0 to 59. + * + * Excel Function: + * MINUTE(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Minute + */ + public static function MINUTEOFHOUR($timeValue = 0) { + $timeValue = $timeTester = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('i',$timeValue); + } // function MINUTEOFHOUR() + + + /** + * SECONDOFMINUTE + * + * Returns the seconds of a time value. + * The second is given as an integer in the range 0 (zero) to 59. + * + * Excel Function: + * SECOND(timeValue) + * + * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard time string + * @return int Second + */ + public static function SECONDOFMINUTE($timeValue = 0) { + $timeValue = PHPExcel_Calculation_Functions::flattenSingleValue($timeValue); + + if (!is_numeric($timeValue)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $testVal = strtok($timeValue,'/-: '); + if (strlen($testVal) < strlen($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $timeValue = self::_getTimeValue($timeValue); + if (is_string($timeValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Execute function + if ($timeValue >= 1) { + $timeValue = fmod($timeValue,1); + } elseif ($timeValue < 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue); + + return (int) gmdate('s',$timeValue); + } // function SECONDOFMINUTE() + + + /** + * EDATE + * + * Returns the serial number that represents the date that is the indicated number of months + * before or after a specified date (the start_date). + * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month + * as the date of issue. + * + * Excel Function: + * EDATE(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EDATE($dateValue = 1, $adjustmentMonths = 0) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return $PHPDateObject; + } + } // function EDATE() + + + /** + * EOMONTH + * + * Returns the date value for the last day of the month that is the indicated number of months + * before or after start_date. + * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. + * + * Excel Function: + * EOMONTH(dateValue,adjustmentMonths) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * @param int $adjustmentMonths The number of months before or after start_date. + * A positive value for months yields a future date; + * a negative value yields a past date. + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) { + $dateValue = PHPExcel_Calculation_Functions::flattenSingleValue($dateValue); + $adjustmentMonths = PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths); + + if (!is_numeric($adjustmentMonths)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $adjustmentMonths = floor($adjustmentMonths); + + if (is_string($dateValue = self::_getDateValue($dateValue))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Execute function + $PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths+1); + $adjustDays = (int) $PHPDateObject->format('d'); + $adjustDaysString = '-'.$adjustDays.' days'; + $PHPDateObject->modify($adjustDaysString); + + switch (PHPExcel_Calculation_Functions::getReturnDateType()) { + case PHPExcel_Calculation_Functions::RETURNDATE_EXCEL : + return (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC : + return (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject)); + case PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT : + return $PHPDateObject; + } + } // function EOMONTH() + +} // class PHPExcel_Calculation_DateTime + diff --git a/extend/phpexcel/PHPExcel/Calculation/Engineering.php b/extend/phpexcel/PHPExcel/Calculation/Engineering.php new file mode 100755 index 0000000..7e32aa8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Engineering.php @@ -0,0 +1,2505 @@ + array( 'Group' => 'Mass', 'Unit Name' => 'Gram', 'AllowPrefix' => True ), + 'sg' => array( 'Group' => 'Mass', 'Unit Name' => 'Slug', 'AllowPrefix' => False ), + 'lbm' => array( 'Group' => 'Mass', 'Unit Name' => 'Pound mass (avoirdupois)', 'AllowPrefix' => False ), + 'u' => array( 'Group' => 'Mass', 'Unit Name' => 'U (atomic mass unit)', 'AllowPrefix' => True ), + 'ozm' => array( 'Group' => 'Mass', 'Unit Name' => 'Ounce mass (avoirdupois)', 'AllowPrefix' => False ), + 'm' => array( 'Group' => 'Distance', 'Unit Name' => 'Meter', 'AllowPrefix' => True ), + 'mi' => array( 'Group' => 'Distance', 'Unit Name' => 'Statute mile', 'AllowPrefix' => False ), + 'Nmi' => array( 'Group' => 'Distance', 'Unit Name' => 'Nautical mile', 'AllowPrefix' => False ), + 'in' => array( 'Group' => 'Distance', 'Unit Name' => 'Inch', 'AllowPrefix' => False ), + 'ft' => array( 'Group' => 'Distance', 'Unit Name' => 'Foot', 'AllowPrefix' => False ), + 'yd' => array( 'Group' => 'Distance', 'Unit Name' => 'Yard', 'AllowPrefix' => False ), + 'ang' => array( 'Group' => 'Distance', 'Unit Name' => 'Angstrom', 'AllowPrefix' => True ), + 'Pica' => array( 'Group' => 'Distance', 'Unit Name' => 'Pica (1/72 in)', 'AllowPrefix' => False ), + 'yr' => array( 'Group' => 'Time', 'Unit Name' => 'Year', 'AllowPrefix' => False ), + 'day' => array( 'Group' => 'Time', 'Unit Name' => 'Day', 'AllowPrefix' => False ), + 'hr' => array( 'Group' => 'Time', 'Unit Name' => 'Hour', 'AllowPrefix' => False ), + 'mn' => array( 'Group' => 'Time', 'Unit Name' => 'Minute', 'AllowPrefix' => False ), + 'sec' => array( 'Group' => 'Time', 'Unit Name' => 'Second', 'AllowPrefix' => True ), + 'Pa' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), + 'p' => array( 'Group' => 'Pressure', 'Unit Name' => 'Pascal', 'AllowPrefix' => True ), + 'atm' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), + 'at' => array( 'Group' => 'Pressure', 'Unit Name' => 'Atmosphere', 'AllowPrefix' => True ), + 'mmHg' => array( 'Group' => 'Pressure', 'Unit Name' => 'mm of Mercury', 'AllowPrefix' => True ), + 'N' => array( 'Group' => 'Force', 'Unit Name' => 'Newton', 'AllowPrefix' => True ), + 'dyn' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), + 'dy' => array( 'Group' => 'Force', 'Unit Name' => 'Dyne', 'AllowPrefix' => True ), + 'lbf' => array( 'Group' => 'Force', 'Unit Name' => 'Pound force', 'AllowPrefix' => False ), + 'J' => array( 'Group' => 'Energy', 'Unit Name' => 'Joule', 'AllowPrefix' => True ), + 'e' => array( 'Group' => 'Energy', 'Unit Name' => 'Erg', 'AllowPrefix' => True ), + 'c' => array( 'Group' => 'Energy', 'Unit Name' => 'Thermodynamic calorie', 'AllowPrefix' => True ), + 'cal' => array( 'Group' => 'Energy', 'Unit Name' => 'IT calorie', 'AllowPrefix' => True ), + 'eV' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), + 'ev' => array( 'Group' => 'Energy', 'Unit Name' => 'Electron volt', 'AllowPrefix' => True ), + 'HPh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), + 'hh' => array( 'Group' => 'Energy', 'Unit Name' => 'Horsepower-hour', 'AllowPrefix' => False ), + 'Wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), + 'wh' => array( 'Group' => 'Energy', 'Unit Name' => 'Watt-hour', 'AllowPrefix' => True ), + 'flb' => array( 'Group' => 'Energy', 'Unit Name' => 'Foot-pound', 'AllowPrefix' => False ), + 'BTU' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), + 'btu' => array( 'Group' => 'Energy', 'Unit Name' => 'BTU', 'AllowPrefix' => False ), + 'HP' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), + 'h' => array( 'Group' => 'Power', 'Unit Name' => 'Horsepower', 'AllowPrefix' => False ), + 'W' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), + 'w' => array( 'Group' => 'Power', 'Unit Name' => 'Watt', 'AllowPrefix' => True ), + 'T' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Tesla', 'AllowPrefix' => True ), + 'ga' => array( 'Group' => 'Magnetism', 'Unit Name' => 'Gauss', 'AllowPrefix' => True ), + 'C' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), + 'cel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Celsius', 'AllowPrefix' => False ), + 'F' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), + 'fah' => array( 'Group' => 'Temperature', 'Unit Name' => 'Fahrenheit', 'AllowPrefix' => False ), + 'K' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), + 'kel' => array( 'Group' => 'Temperature', 'Unit Name' => 'Kelvin', 'AllowPrefix' => False ), + 'tsp' => array( 'Group' => 'Liquid', 'Unit Name' => 'Teaspoon', 'AllowPrefix' => False ), + 'tbs' => array( 'Group' => 'Liquid', 'Unit Name' => 'Tablespoon', 'AllowPrefix' => False ), + 'oz' => array( 'Group' => 'Liquid', 'Unit Name' => 'Fluid Ounce', 'AllowPrefix' => False ), + 'cup' => array( 'Group' => 'Liquid', 'Unit Name' => 'Cup', 'AllowPrefix' => False ), + 'pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), + 'us_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.S. Pint', 'AllowPrefix' => False ), + 'uk_pt' => array( 'Group' => 'Liquid', 'Unit Name' => 'U.K. Pint', 'AllowPrefix' => False ), + 'qt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Quart', 'AllowPrefix' => False ), + 'gal' => array( 'Group' => 'Liquid', 'Unit Name' => 'Gallon', 'AllowPrefix' => False ), + 'l' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ), + 'lt' => array( 'Group' => 'Liquid', 'Unit Name' => 'Litre', 'AllowPrefix' => True ) + ); + + /** + * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @var mixed[] + */ + private static $_conversionMultipliers = array( 'Y' => array( 'multiplier' => 1E24, 'name' => 'yotta' ), + 'Z' => array( 'multiplier' => 1E21, 'name' => 'zetta' ), + 'E' => array( 'multiplier' => 1E18, 'name' => 'exa' ), + 'P' => array( 'multiplier' => 1E15, 'name' => 'peta' ), + 'T' => array( 'multiplier' => 1E12, 'name' => 'tera' ), + 'G' => array( 'multiplier' => 1E9, 'name' => 'giga' ), + 'M' => array( 'multiplier' => 1E6, 'name' => 'mega' ), + 'k' => array( 'multiplier' => 1E3, 'name' => 'kilo' ), + 'h' => array( 'multiplier' => 1E2, 'name' => 'hecto' ), + 'e' => array( 'multiplier' => 1E1, 'name' => 'deka' ), + 'd' => array( 'multiplier' => 1E-1, 'name' => 'deci' ), + 'c' => array( 'multiplier' => 1E-2, 'name' => 'centi' ), + 'm' => array( 'multiplier' => 1E-3, 'name' => 'milli' ), + 'u' => array( 'multiplier' => 1E-6, 'name' => 'micro' ), + 'n' => array( 'multiplier' => 1E-9, 'name' => 'nano' ), + 'p' => array( 'multiplier' => 1E-12, 'name' => 'pico' ), + 'f' => array( 'multiplier' => 1E-15, 'name' => 'femto' ), + 'a' => array( 'multiplier' => 1E-18, 'name' => 'atto' ), + 'z' => array( 'multiplier' => 1E-21, 'name' => 'zepto' ), + 'y' => array( 'multiplier' => 1E-24, 'name' => 'yocto' ) + ); + + /** + * Details of the Units of measure conversion factors, organised by group + * + * @var mixed[] + */ + private static $_unitConversions = array( 'Mass' => array( 'g' => array( 'g' => 1.0, + 'sg' => 6.85220500053478E-05, + 'lbm' => 2.20462291469134E-03, + 'u' => 6.02217000000000E+23, + 'ozm' => 3.52739718003627E-02 + ), + 'sg' => array( 'g' => 1.45938424189287E+04, + 'sg' => 1.0, + 'lbm' => 3.21739194101647E+01, + 'u' => 8.78866000000000E+27, + 'ozm' => 5.14782785944229E+02 + ), + 'lbm' => array( 'g' => 4.5359230974881148E+02, + 'sg' => 3.10810749306493E-02, + 'lbm' => 1.0, + 'u' => 2.73161000000000E+26, + 'ozm' => 1.60000023429410E+01 + ), + 'u' => array( 'g' => 1.66053100460465E-24, + 'sg' => 1.13782988532950E-28, + 'lbm' => 3.66084470330684E-27, + 'u' => 1.0, + 'ozm' => 5.85735238300524E-26 + ), + 'ozm' => array( 'g' => 2.83495152079732E+01, + 'sg' => 1.94256689870811E-03, + 'lbm' => 6.24999908478882E-02, + 'u' => 1.70725600000000E+25, + 'ozm' => 1.0 + ) + ), + 'Distance' => array( 'm' => array( 'm' => 1.0, + 'mi' => 6.21371192237334E-04, + 'Nmi' => 5.39956803455724E-04, + 'in' => 3.93700787401575E+01, + 'ft' => 3.28083989501312E+00, + 'yd' => 1.09361329797891E+00, + 'ang' => 1.00000000000000E+10, + 'Pica' => 2.83464566929116E+03 + ), + 'mi' => array( 'm' => 1.60934400000000E+03, + 'mi' => 1.0, + 'Nmi' => 8.68976241900648E-01, + 'in' => 6.33600000000000E+04, + 'ft' => 5.28000000000000E+03, + 'yd' => 1.76000000000000E+03, + 'ang' => 1.60934400000000E+13, + 'Pica' => 4.56191999999971E+06 + ), + 'Nmi' => array( 'm' => 1.85200000000000E+03, + 'mi' => 1.15077944802354E+00, + 'Nmi' => 1.0, + 'in' => 7.29133858267717E+04, + 'ft' => 6.07611548556430E+03, + 'yd' => 2.02537182785694E+03, + 'ang' => 1.85200000000000E+13, + 'Pica' => 5.24976377952723E+06 + ), + 'in' => array( 'm' => 2.54000000000000E-02, + 'mi' => 1.57828282828283E-05, + 'Nmi' => 1.37149028077754E-05, + 'in' => 1.0, + 'ft' => 8.33333333333333E-02, + 'yd' => 2.77777777686643E-02, + 'ang' => 2.54000000000000E+08, + 'Pica' => 7.19999999999955E+01 + ), + 'ft' => array( 'm' => 3.04800000000000E-01, + 'mi' => 1.89393939393939E-04, + 'Nmi' => 1.64578833693305E-04, + 'in' => 1.20000000000000E+01, + 'ft' => 1.0, + 'yd' => 3.33333333223972E-01, + 'ang' => 3.04800000000000E+09, + 'Pica' => 8.63999999999946E+02 + ), + 'yd' => array( 'm' => 9.14400000300000E-01, + 'mi' => 5.68181818368230E-04, + 'Nmi' => 4.93736501241901E-04, + 'in' => 3.60000000118110E+01, + 'ft' => 3.00000000000000E+00, + 'yd' => 1.0, + 'ang' => 9.14400000300000E+09, + 'Pica' => 2.59200000085023E+03 + ), + 'ang' => array( 'm' => 1.00000000000000E-10, + 'mi' => 6.21371192237334E-14, + 'Nmi' => 5.39956803455724E-14, + 'in' => 3.93700787401575E-09, + 'ft' => 3.28083989501312E-10, + 'yd' => 1.09361329797891E-10, + 'ang' => 1.0, + 'Pica' => 2.83464566929116E-07 + ), + 'Pica' => array( 'm' => 3.52777777777800E-04, + 'mi' => 2.19205948372629E-07, + 'Nmi' => 1.90484761219114E-07, + 'in' => 1.38888888888898E-02, + 'ft' => 1.15740740740748E-03, + 'yd' => 3.85802469009251E-04, + 'ang' => 3.52777777777800E+06, + 'Pica' => 1.0 + ) + ), + 'Time' => array( 'yr' => array( 'yr' => 1.0, + 'day' => 365.25, + 'hr' => 8766.0, + 'mn' => 525960.0, + 'sec' => 31557600.0 + ), + 'day' => array( 'yr' => 2.73785078713210E-03, + 'day' => 1.0, + 'hr' => 24.0, + 'mn' => 1440.0, + 'sec' => 86400.0 + ), + 'hr' => array( 'yr' => 1.14077116130504E-04, + 'day' => 4.16666666666667E-02, + 'hr' => 1.0, + 'mn' => 60.0, + 'sec' => 3600.0 + ), + 'mn' => array( 'yr' => 1.90128526884174E-06, + 'day' => 6.94444444444444E-04, + 'hr' => 1.66666666666667E-02, + 'mn' => 1.0, + 'sec' => 60.0 + ), + 'sec' => array( 'yr' => 3.16880878140289E-08, + 'day' => 1.15740740740741E-05, + 'hr' => 2.77777777777778E-04, + 'mn' => 1.66666666666667E-02, + 'sec' => 1.0 + ) + ), + 'Pressure' => array( 'Pa' => array( 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03 + ), + 'p' => array( 'Pa' => 1.0, + 'p' => 1.0, + 'atm' => 9.86923299998193E-06, + 'at' => 9.86923299998193E-06, + 'mmHg' => 7.50061707998627E-03 + ), + 'atm' => array( 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0 + ), + 'at' => array( 'Pa' => 1.01324996583000E+05, + 'p' => 1.01324996583000E+05, + 'atm' => 1.0, + 'at' => 1.0, + 'mmHg' => 760.0 + ), + 'mmHg' => array( 'Pa' => 1.33322363925000E+02, + 'p' => 1.33322363925000E+02, + 'atm' => 1.31578947368421E-03, + 'at' => 1.31578947368421E-03, + 'mmHg' => 1.0 + ) + ), + 'Force' => array( 'N' => array( 'N' => 1.0, + 'dyn' => 1.0E+5, + 'dy' => 1.0E+5, + 'lbf' => 2.24808923655339E-01 + ), + 'dyn' => array( 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06 + ), + 'dy' => array( 'N' => 1.0E-5, + 'dyn' => 1.0, + 'dy' => 1.0, + 'lbf' => 2.24808923655339E-06 + ), + 'lbf' => array( 'N' => 4.448222, + 'dyn' => 4.448222E+5, + 'dy' => 4.448222E+5, + 'lbf' => 1.0 + ) + ), + 'Energy' => array( 'J' => array( 'J' => 1.0, + 'e' => 9.99999519343231E+06, + 'c' => 2.39006249473467E-01, + 'cal' => 2.38846190642017E-01, + 'eV' => 6.24145700000000E+18, + 'ev' => 6.24145700000000E+18, + 'HPh' => 3.72506430801000E-07, + 'hh' => 3.72506430801000E-07, + 'Wh' => 2.77777916238711E-04, + 'wh' => 2.77777916238711E-04, + 'flb' => 2.37304222192651E+01, + 'BTU' => 9.47815067349015E-04, + 'btu' => 9.47815067349015E-04 + ), + 'e' => array( 'J' => 1.00000048065700E-07, + 'e' => 1.0, + 'c' => 2.39006364353494E-08, + 'cal' => 2.38846305445111E-08, + 'eV' => 6.24146000000000E+11, + 'ev' => 6.24146000000000E+11, + 'HPh' => 3.72506609848824E-14, + 'hh' => 3.72506609848824E-14, + 'Wh' => 2.77778049754611E-11, + 'wh' => 2.77778049754611E-11, + 'flb' => 2.37304336254586E-06, + 'BTU' => 9.47815522922962E-11, + 'btu' => 9.47815522922962E-11 + ), + 'c' => array( 'J' => 4.18399101363672E+00, + 'e' => 4.18398900257312E+07, + 'c' => 1.0, + 'cal' => 9.99330315287563E-01, + 'eV' => 2.61142000000000E+19, + 'ev' => 2.61142000000000E+19, + 'HPh' => 1.55856355899327E-06, + 'hh' => 1.55856355899327E-06, + 'Wh' => 1.16222030532950E-03, + 'wh' => 1.16222030532950E-03, + 'flb' => 9.92878733152102E+01, + 'BTU' => 3.96564972437776E-03, + 'btu' => 3.96564972437776E-03 + ), + 'cal' => array( 'J' => 4.18679484613929E+00, + 'e' => 4.18679283372801E+07, + 'c' => 1.00067013349059E+00, + 'cal' => 1.0, + 'eV' => 2.61317000000000E+19, + 'ev' => 2.61317000000000E+19, + 'HPh' => 1.55960800463137E-06, + 'hh' => 1.55960800463137E-06, + 'Wh' => 1.16299914807955E-03, + 'wh' => 1.16299914807955E-03, + 'flb' => 9.93544094443283E+01, + 'BTU' => 3.96830723907002E-03, + 'btu' => 3.96830723907002E-03 + ), + 'eV' => array( 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22 + ), + 'ev' => array( 'J' => 1.60219000146921E-19, + 'e' => 1.60218923136574E-12, + 'c' => 3.82933423195043E-20, + 'cal' => 3.82676978535648E-20, + 'eV' => 1.0, + 'ev' => 1.0, + 'HPh' => 5.96826078912344E-26, + 'hh' => 5.96826078912344E-26, + 'Wh' => 4.45053000026614E-23, + 'wh' => 4.45053000026614E-23, + 'flb' => 3.80206452103492E-18, + 'BTU' => 1.51857982414846E-22, + 'btu' => 1.51857982414846E-22 + ), + 'HPh' => array( 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03 + ), + 'hh' => array( 'J' => 2.68451741316170E+06, + 'e' => 2.68451612283024E+13, + 'c' => 6.41616438565991E+05, + 'cal' => 6.41186757845835E+05, + 'eV' => 1.67553000000000E+25, + 'ev' => 1.67553000000000E+25, + 'HPh' => 1.0, + 'hh' => 1.0, + 'Wh' => 7.45699653134593E+02, + 'wh' => 7.45699653134593E+02, + 'flb' => 6.37047316692964E+07, + 'BTU' => 2.54442605275546E+03, + 'btu' => 2.54442605275546E+03 + ), + 'Wh' => array( 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00 + ), + 'wh' => array( 'J' => 3.59999820554720E+03, + 'e' => 3.59999647518369E+10, + 'c' => 8.60422069219046E+02, + 'cal' => 8.59845857713046E+02, + 'eV' => 2.24692340000000E+22, + 'ev' => 2.24692340000000E+22, + 'HPh' => 1.34102248243839E-03, + 'hh' => 1.34102248243839E-03, + 'Wh' => 1.0, + 'wh' => 1.0, + 'flb' => 8.54294774062316E+04, + 'BTU' => 3.41213254164705E+00, + 'btu' => 3.41213254164705E+00 + ), + 'flb' => array( 'J' => 4.21400003236424E-02, + 'e' => 4.21399800687660E+05, + 'c' => 1.00717234301644E-02, + 'cal' => 1.00649785509554E-02, + 'eV' => 2.63015000000000E+17, + 'ev' => 2.63015000000000E+17, + 'HPh' => 1.56974211145130E-08, + 'hh' => 1.56974211145130E-08, + 'Wh' => 1.17055614802000E-05, + 'wh' => 1.17055614802000E-05, + 'flb' => 1.0, + 'BTU' => 3.99409272448406E-05, + 'btu' => 3.99409272448406E-05 + ), + 'BTU' => array( 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ), + 'btu' => array( 'J' => 1.05505813786749E+03, + 'e' => 1.05505763074665E+10, + 'c' => 2.52165488508168E+02, + 'cal' => 2.51996617135510E+02, + 'eV' => 6.58510000000000E+21, + 'ev' => 6.58510000000000E+21, + 'HPh' => 3.93015941224568E-04, + 'hh' => 3.93015941224568E-04, + 'Wh' => 2.93071851047526E-01, + 'wh' => 2.93071851047526E-01, + 'flb' => 2.50369750774671E+04, + 'BTU' => 1.0, + 'btu' => 1.0, + ) + ), + 'Power' => array( 'HP' => array( 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02 + ), + 'h' => array( 'HP' => 1.0, + 'h' => 1.0, + 'W' => 7.45701000000000E+02, + 'w' => 7.45701000000000E+02 + ), + 'W' => array( 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0 + ), + 'w' => array( 'HP' => 1.34102006031908E-03, + 'h' => 1.34102006031908E-03, + 'W' => 1.0, + 'w' => 1.0 + ) + ), + 'Magnetism' => array( 'T' => array( 'T' => 1.0, + 'ga' => 10000.0 + ), + 'ga' => array( 'T' => 0.0001, + 'ga' => 1.0 + ) + ), + 'Liquid' => array( 'tsp' => array( 'tsp' => 1.0, + 'tbs' => 3.33333333333333E-01, + 'oz' => 1.66666666666667E-01, + 'cup' => 2.08333333333333E-02, + 'pt' => 1.04166666666667E-02, + 'us_pt' => 1.04166666666667E-02, + 'uk_pt' => 8.67558516821960E-03, + 'qt' => 5.20833333333333E-03, + 'gal' => 1.30208333333333E-03, + 'l' => 4.92999408400710E-03, + 'lt' => 4.92999408400710E-03 + ), + 'tbs' => array( 'tsp' => 3.00000000000000E+00, + 'tbs' => 1.0, + 'oz' => 5.00000000000000E-01, + 'cup' => 6.25000000000000E-02, + 'pt' => 3.12500000000000E-02, + 'us_pt' => 3.12500000000000E-02, + 'uk_pt' => 2.60267555046588E-02, + 'qt' => 1.56250000000000E-02, + 'gal' => 3.90625000000000E-03, + 'l' => 1.47899822520213E-02, + 'lt' => 1.47899822520213E-02 + ), + 'oz' => array( 'tsp' => 6.00000000000000E+00, + 'tbs' => 2.00000000000000E+00, + 'oz' => 1.0, + 'cup' => 1.25000000000000E-01, + 'pt' => 6.25000000000000E-02, + 'us_pt' => 6.25000000000000E-02, + 'uk_pt' => 5.20535110093176E-02, + 'qt' => 3.12500000000000E-02, + 'gal' => 7.81250000000000E-03, + 'l' => 2.95799645040426E-02, + 'lt' => 2.95799645040426E-02 + ), + 'cup' => array( 'tsp' => 4.80000000000000E+01, + 'tbs' => 1.60000000000000E+01, + 'oz' => 8.00000000000000E+00, + 'cup' => 1.0, + 'pt' => 5.00000000000000E-01, + 'us_pt' => 5.00000000000000E-01, + 'uk_pt' => 4.16428088074541E-01, + 'qt' => 2.50000000000000E-01, + 'gal' => 6.25000000000000E-02, + 'l' => 2.36639716032341E-01, + 'lt' => 2.36639716032341E-01 + ), + 'pt' => array( 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01 + ), + 'us_pt' => array( 'tsp' => 9.60000000000000E+01, + 'tbs' => 3.20000000000000E+01, + 'oz' => 1.60000000000000E+01, + 'cup' => 2.00000000000000E+00, + 'pt' => 1.0, + 'us_pt' => 1.0, + 'uk_pt' => 8.32856176149081E-01, + 'qt' => 5.00000000000000E-01, + 'gal' => 1.25000000000000E-01, + 'l' => 4.73279432064682E-01, + 'lt' => 4.73279432064682E-01 + ), + 'uk_pt' => array( 'tsp' => 1.15266000000000E+02, + 'tbs' => 3.84220000000000E+01, + 'oz' => 1.92110000000000E+01, + 'cup' => 2.40137500000000E+00, + 'pt' => 1.20068750000000E+00, + 'us_pt' => 1.20068750000000E+00, + 'uk_pt' => 1.0, + 'qt' => 6.00343750000000E-01, + 'gal' => 1.50085937500000E-01, + 'l' => 5.68260698087162E-01, + 'lt' => 5.68260698087162E-01 + ), + 'qt' => array( 'tsp' => 1.92000000000000E+02, + 'tbs' => 6.40000000000000E+01, + 'oz' => 3.20000000000000E+01, + 'cup' => 4.00000000000000E+00, + 'pt' => 2.00000000000000E+00, + 'us_pt' => 2.00000000000000E+00, + 'uk_pt' => 1.66571235229816E+00, + 'qt' => 1.0, + 'gal' => 2.50000000000000E-01, + 'l' => 9.46558864129363E-01, + 'lt' => 9.46558864129363E-01 + ), + 'gal' => array( 'tsp' => 7.68000000000000E+02, + 'tbs' => 2.56000000000000E+02, + 'oz' => 1.28000000000000E+02, + 'cup' => 1.60000000000000E+01, + 'pt' => 8.00000000000000E+00, + 'us_pt' => 8.00000000000000E+00, + 'uk_pt' => 6.66284940919265E+00, + 'qt' => 4.00000000000000E+00, + 'gal' => 1.0, + 'l' => 3.78623545651745E+00, + 'lt' => 3.78623545651745E+00 + ), + 'l' => array( 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0 + ), + 'lt' => array( 'tsp' => 2.02840000000000E+02, + 'tbs' => 6.76133333333333E+01, + 'oz' => 3.38066666666667E+01, + 'cup' => 4.22583333333333E+00, + 'pt' => 2.11291666666667E+00, + 'us_pt' => 2.11291666666667E+00, + 'uk_pt' => 1.75975569552166E+00, + 'qt' => 1.05645833333333E+00, + 'gal' => 2.64114583333333E-01, + 'l' => 1.0, + 'lt' => 1.0 + ) + ) + ); + + + /** + * _parseComplex + * + * Parses a complex number into its real and imaginary parts, and an I or J suffix + * + * @param string $complexNumber The complex number + * @return string[] Indexed on "real", "imaginary" and "suffix" + */ + public static function _parseComplex($complexNumber) { + $workString = (string) $complexNumber; + + $realNumber = $imaginary = 0; + // Extract the suffix, if there is one + $suffix = substr($workString,-1); + if (!is_numeric($suffix)) { + $workString = substr($workString,0,-1); + } else { + $suffix = ''; + } + + // Split the input into its Real and Imaginary components + $leadingSign = 0; + if (strlen($workString) > 0) { + $leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0; + } + $power = ''; + $realNumber = strtok($workString, '+-'); + if (strtoupper(substr($realNumber,-1)) == 'E') { + $power = strtok('+-'); + ++$leadingSign; + } + + $realNumber = substr($workString,0,strlen($realNumber)+strlen($power)+$leadingSign); + + if ($suffix != '') { + $imaginary = substr($workString,strlen($realNumber)); + + if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) { + $imaginary = $realNumber.'1'; + $realNumber = '0'; + } else if ($imaginary == '') { + $imaginary = $realNumber; + $realNumber = '0'; + } elseif (($imaginary == '+') || ($imaginary == '-')) { + $imaginary .= '1'; + } + } + + return array( 'real' => $realNumber, + 'imaginary' => $imaginary, + 'suffix' => $suffix + ); + } // function _parseComplex() + + + /** + * Cleans the leading characters in a complex number string + * + * @param string $complexNumber The complex number to clean + * @return string The "cleaned" complex number + */ + private static function _cleanComplex($complexNumber) { + if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); + if ($complexNumber{0} == '0') $complexNumber = substr($complexNumber,1); + if ($complexNumber{0} == '.') $complexNumber = '0'.$complexNumber; + if ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1); + return $complexNumber; + } + + /** + * Formats a number base string value with leading zeroes + * + * @param string $xVal The "number" to pad + * @param integer $places The length that we want to pad this value + * @return string The padded "number" + */ + private static function _nbrConversionFormat($xVal, $places) { + if (!is_null($places)) { + if (strlen($xVal) <= $places) { + return substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10); + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + return substr($xVal, -10); + } // function _nbrConversionFormat() + + /** + * BESSELI + * + * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated + * for purely imaginary arguments + * + * Excel Function: + * BESSELI(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELI returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. + * If ord is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. + * If $ord < 0, BESSELI returns the #NUM! error value. + * @return float + * + */ + public static function BESSELI($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / 4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_2_PI = 2 * M_PI; + + $fXAbs = abs($x); + $fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELI() + + + /** + * BESSELJ + * + * Returns the Bessel function + * + * Excel Function: + * BESSELJ(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELJ returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. + * If $ord < 0, BESSELJ returns the #NUM! error value. + * @return float + * + */ + public static function BESSELJ($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + $ord = floor($ord); + if ($ord < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $fResult = 0; + if (abs($x) <= 30) { + $fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord); + $ordK = 1; + $fSqrX = ($x * $x) / -4; + do { + $fTerm *= $fSqrX; + $fTerm /= ($ordK * ($ordK + $ord)); + $fResult += $fTerm; + } while ((abs($fTerm) > 1e-12) && (++$ordK < 100)); + } else { + $f_PI_DIV_2 = M_PI / 2; + $f_PI_DIV_4 = M_PI / 4; + + $fXAbs = abs($x); + $fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4); + if (($ord & 1) && ($x < 0)) { + $fResult = -$fResult; + } + } + return (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELJ() + + + private static function _Besselk0($fNum) { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = -log($fNum2) * self::BESSELI($fNum, 0) + + (-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y * + (0.10750e-3 + $y * 0.74e-5)))))); + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y * + (0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3)))))); + } + return $fRet; + } // function _Besselk0() + + + private static function _Besselk1($fNum) { + if ($fNum <= 2) { + $fNum2 = $fNum * 0.5; + $y = ($fNum2 * $fNum2); + $fRet = log($fNum2) * self::BESSELI($fNum, 1) + + (1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y * + (-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum; + } else { + $y = 2 / $fNum; + $fRet = exp(-$fNum) / sqrt($fNum) * + (1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y * + (0.325614e-2 + $y * (-0.68245e-3))))))); + } + return $fRet; + } // function _Besselk1() + + + /** + * BESSELK + * + * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated + * for purely imaginary arguments. + * + * Excel Function: + * BESSELK(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * @return float + * + */ + public static function BESSELK($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0 : return self::_Besselk0($x); + break; + case 1 : return self::_Besselk1($x); + break; + default : $fTox = 2 / $x; + $fBkm = self::_Besselk0($x); + $fBk = self::_Besselk1($x); + for ($n = 1; $n < $ord; ++$n) { + $fBkp = $fBkm + $n * $fTox * $fBk; + $fBkm = $fBk; + $fBk = $fBkp; + } + } + return (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELK() + + + private static function _Bessely0($fNum) { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733)))); + $f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y)))); + $fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum); + } else { + $z = 8.0 / $fNum; + $y = ($z * $z); + $xx = $fNum - 0.785398164; + $f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6))); + $f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7)))); + $fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2); + } + return $fRet; + } // function _Bessely0() + + + private static function _Bessely1($fNum) { + if ($fNum < 8.0) { + $y = ($fNum * $fNum); + $f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y * + (-0.4237922726e7 + $y * 0.8511937935e4))))); + $f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y * + (0.1020426050e6 + $y * (0.3549632885e3 + $y))))); + $fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum); + } else { + $fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491); + } + return $fRet; + } // function _Bessely1() + + + /** + * BESSELY + * + * Returns the Bessel function, which is also called the Weber function or the Neumann function. + * + * Excel Function: + * BESSELY(x,ord) + * + * @access public + * @category Engineering Functions + * @param float $x The value at which to evaluate the function. + * If x is nonnumeric, BESSELK returns the #VALUE! error value. + * @param integer $ord The order of the Bessel function. If n is not an integer, it is truncated. + * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. + * If $ord < 0, BESSELK returns the #NUM! error value. + * + * @return float + */ + public static function BESSELY($x, $ord) { + $x = (is_null($x)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($x); + $ord = (is_null($ord)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($ord); + + if ((is_numeric($x)) && (is_numeric($ord))) { + if (($ord < 0) || ($x == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch(floor($ord)) { + case 0 : return self::_Bessely0($x); + break; + case 1 : return self::_Bessely1($x); + break; + default: $fTox = 2 / $x; + $fBym = self::_Bessely0($x); + $fBy = self::_Bessely1($x); + for ($n = 1; $n < $ord; ++$n) { + $fByp = $n * $fTox * $fBy - $fBym; + $fBym = $fBy; + $fBy = $fByp; + } + } + return (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BESSELY() + + + /** + * BINTODEC + * + * Return a binary value as decimal. + * + * Excel Function: + * BIN2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. + * @return string + */ + public static function BINTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + $x = substr($x,-9); + return '-'.(512-bindec($x)); + } + return bindec($x); + } // function BINTODEC() + + + /** + * BINTOHEX + * + * Return a binary value as hex. + * + * Excel Function: + * BIN2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2HEX uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. + * If places is negative, BIN2HEX returns the #NUM! error value. + * @return string + */ + public static function BINTOHEX($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('F',8).substr(strtoupper(dechex(bindec(substr($x,-9)))),-2); + } + $hexVal = (string) strtoupper(dechex(bindec($x))); + + return self::_nbrConversionFormat($hexVal,$places); + } // function BINTOHEX() + + + /** + * BINTOOCT + * + * Return a binary value as octal. + * + * Excel Function: + * BIN2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The binary number (as a string) that you want to convert. The number + * cannot contain more than 10 characters (10 bits). The most significant + * bit of number is the sign bit. The remaining 9 bits are magnitude bits. + * Negative numbers are represented using two's-complement notation. + * If number is not a valid binary number, or if number contains more than + * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, BIN2OCT uses the + * minimum number of characters necessary. Places is useful for padding the + * return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. + * If places is negative, BIN2OCT returns the #NUM! error value. + * @return string + */ + public static function BINTOOCT($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $x = floor($x); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[01]/',$x,$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (strlen($x) > 10) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (strlen($x) == 10) { + // Two's Complement + return str_repeat('7',7).substr(strtoupper(decoct(bindec(substr($x,-9)))),-3); + } + $octVal = (string) decoct(bindec($x)); + + return self::_nbrConversionFormat($octVal,$places); + } // function BINTOOCT() + + + /** + * DECTOBIN + * + * Return a decimal value as binary. + * + * Excel Function: + * DEC2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * valid place values are ignored and DEC2BIN returns a 10-character + * (10-bit) binary number in which the most significant bit is the sign + * bit. The remaining 9 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error + * value. + * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If DEC2BIN requires more than places characters, it returns the #NUM! + * error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2BIN uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. + * If places is zero or negative, DEC2BIN returns the #NUM! error value. + * @return string + */ + public static function DECTOBIN($x, $places=NULL) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decbin($x); + if (strlen($r) == 32) { + // Two's Complement + $r = substr($r,-10); + } elseif (strlen($r) > 11) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOBIN() + + + /** + * DECTOHEX + * + * Return a decimal value as hex. + * + * Excel Function: + * DEC2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2HEX returns a 10-character (40-bit) + * hexadecimal number in which the most significant bit is the sign + * bit. The remaining 39 bits are magnitude bits. Negative numbers + * are represented using two's-complement notation. + * If number < -549,755,813,888 or if number > 549,755,813,887, + * DEC2HEX returns the #NUM! error value. + * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If DEC2HEX requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2HEX uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. + * If places is zero or negative, DEC2HEX returns the #NUM! error value. + * @return string + */ + public static function DECTOHEX($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = strtoupper(dechex($x)); + if (strlen($r) == 8) { + // Two's Complement + $r = 'FF'.$r; + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOHEX() + + + /** + * DECTOOCT + * + * Return an decimal value as octal. + * + * Excel Function: + * DEC2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The decimal integer you want to convert. If number is negative, + * places is ignored and DEC2OCT returns a 10-character (30-bit) + * octal number in which the most significant bit is the sign bit. + * The remaining 29 bits are magnitude bits. Negative numbers are + * represented using two's-complement notation. + * If number < -536,870,912 or if number > 536,870,911, DEC2OCT + * returns the #NUM! error value. + * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If DEC2OCT requires more than places characters, it returns the + * #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, DEC2OCT uses + * the minimum number of characters necessary. Places is useful for + * padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. + * If places is zero or negative, DEC2OCT returns the #NUM! error value. + * @return string + */ + public static function DECTOOCT($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $x = (int) $x; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) floor($x); + $r = decoct($x); + if (strlen($r) == 11) { + // Two's Complement + $r = substr($r,-10); + } + + return self::_nbrConversionFormat($r,$places); + } // function DECTOOCT() + + + /** + * HEXTOBIN + * + * Return a hex value as binary. + * + * Excel Function: + * HEX2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x the hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit (40th bit from the right). The remaining + * 9 bits are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, HEX2BIN ignores places and returns a + * 10-character binary number. + * If number is negative, it cannot be less than FFFFFFFE00, and + * if number is positive, it cannot be greater than 1FF. + * If number is not a valid hexadecimal number, HEX2BIN returns + * the #NUM! error value. + * If HEX2BIN requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * HEX2BIN uses the minimum number of characters necessary. Places + * is useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. + * If places is negative, HEX2BIN returns the #NUM! error value. + * @return string + */ + public static function HEXTOBIN($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $binVal = decbin(hexdec($x)); + + return substr(self::_nbrConversionFormat($binVal,$places),-10); + } // function HEXTOBIN() + + + /** + * HEXTODEC + * + * Return a hex value as decimal. + * + * Excel Function: + * HEX2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. This number cannot + * contain more than 10 characters (40 bits). The most significant + * bit of number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is not a valid hexadecimal number, HEX2DEC returns the + * #NUM! error value. + * @return string + */ + public static function HEXTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return hexdec($x); + } // function HEXTODEC() + + + /** + * HEXTOOCT + * + * Return a hex value as octal. + * + * Excel Function: + * HEX2OCT(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The hexadecimal number you want to convert. Number cannot + * contain more than 10 characters. The most significant bit of + * number is the sign bit. The remaining 39 bits are magnitude + * bits. Negative numbers are represented using two's-complement + * notation. + * If number is negative, HEX2OCT ignores places and returns a + * 10-character octal number. + * If number is negative, it cannot be less than FFE0000000, and + * if number is positive, it cannot be greater than 1FFFFFFF. + * If number is not a valid hexadecimal number, HEX2OCT returns + * the #NUM! error value. + * If HEX2OCT requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, HEX2OCT + * uses the minimum number of characters necessary. Places is + * useful for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, HEX2OCT returns the #VALUE! error + * value. + * If places is negative, HEX2OCT returns the #NUM! error value. + * @return string + */ + public static function HEXTOOCT($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $octVal = decoct(hexdec($x)); + + return self::_nbrConversionFormat($octVal,$places); + } // function HEXTOOCT() + + + /** + * OCTTOBIN + * + * Return an octal value as binary. + * + * Excel Function: + * OCT2BIN(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not + * contain more than 10 characters. The most significant + * bit of number is the sign bit. The remaining 29 bits + * are magnitude bits. Negative numbers are represented + * using two's-complement notation. + * If number is negative, OCT2BIN ignores places and returns + * a 10-character binary number. + * If number is negative, it cannot be less than 7777777000, + * and if number is positive, it cannot be greater than 777. + * If number is not a valid octal number, OCT2BIN returns + * the #NUM! error value. + * If OCT2BIN requires more than places characters, it + * returns the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, + * OCT2BIN uses the minimum number of characters necessary. + * Places is useful for padding the return value with + * leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2BIN returns the #VALUE! + * error value. + * If places is negative, OCT2BIN returns the #NUM! error + * value. + * @return string + */ + public static function OCTTOBIN($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $r = decbin(octdec($x)); + + return self::_nbrConversionFormat($r,$places); + } // function OCTTOBIN() + + + /** + * OCTTODEC + * + * Return an octal value as decimal. + * + * Excel Function: + * OCT2DEC(x) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is not a valid octal number, OCT2DEC returns the + * #NUM! error value. + * @return string + */ + public static function OCTTODEC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return octdec($x); + } // function OCTTODEC() + + + /** + * OCTTOHEX + * + * Return an octal value as hex. + * + * Excel Function: + * OCT2HEX(x[,places]) + * + * @access public + * @category Engineering Functions + * @param string $x The octal number you want to convert. Number may not contain + * more than 10 octal characters (30 bits). The most significant + * bit of number is the sign bit. The remaining 29 bits are + * magnitude bits. Negative numbers are represented using + * two's-complement notation. + * If number is negative, OCT2HEX ignores places and returns a + * 10-character hexadecimal number. + * If number is not a valid octal number, OCT2HEX returns the + * #NUM! error value. + * If OCT2HEX requires more than places characters, it returns + * the #NUM! error value. + * @param integer $places The number of characters to use. If places is omitted, OCT2HEX + * uses the minimum number of characters necessary. Places is useful + * for padding the return value with leading 0s (zeros). + * If places is not an integer, it is truncated. + * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. + * If places is negative, OCT2HEX returns the #NUM! error value. + * @return string + */ + public static function OCTTOHEX($x, $places=null) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $places = PHPExcel_Calculation_Functions::flattenSingleValue($places); + + if (is_bool($x)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $x = (string) $x; + if (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $hexVal = strtoupper(dechex(octdec($x))); + + return self::_nbrConversionFormat($hexVal,$places); + } // function OCTTOHEX() + + + /** + * COMPLEX + * + * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. + * + * Excel Function: + * COMPLEX(realNumber,imaginary[,places]) + * + * @access public + * @category Engineering Functions + * @param float $realNumber The real coefficient of the complex number. + * @param float $imaginary The imaginary coefficient of the complex number. + * @param string $suffix The suffix for the imaginary component of the complex number. + * If omitted, the suffix is assumed to be "i". + * @return string + */ + public static function COMPLEX($realNumber=0.0, $imaginary=0.0, $suffix='i') { + $realNumber = (is_null($realNumber)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + $imaginary = (is_null($imaginary)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($imaginary); + $suffix = (is_null($suffix)) ? 'i' : PHPExcel_Calculation_Functions::flattenSingleValue($suffix); + + if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && + (($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) { + $realNumber = (float) $realNumber; + $imaginary = (float) $imaginary; + + if ($suffix == '') $suffix = 'i'; + if ($realNumber == 0.0) { + if ($imaginary == 0.0) { + return (string) '0'; + } elseif ($imaginary == 1.0) { + return (string) $suffix; + } elseif ($imaginary == -1.0) { + return (string) '-'.$suffix; + } + return (string) $imaginary.$suffix; + } elseif ($imaginary == 0.0) { + return (string) $realNumber; + } elseif ($imaginary == 1.0) { + return (string) $realNumber.'+'.$suffix; + } elseif ($imaginary == -1.0) { + return (string) $realNumber.'-'.$suffix; + } + if ($imaginary > 0) { $imaginary = (string) '+'.$imaginary; } + return (string) $realNumber.$imaginary.$suffix; + } + + return PHPExcel_Calculation_Functions::VALUE(); + } // function COMPLEX() + + + /** + * IMAGINARY + * + * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMAGINARY(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the imaginary + * coefficient. + * @return float + */ + public static function IMAGINARY($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['imaginary']; + } // function IMAGINARY() + + + /** + * IMREAL + * + * Returns the real coefficient of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMREAL(complexNumber) + * + * @access public + * @category Engineering Functions + * @param string $complexNumber The complex number for which you want the real coefficient. + * @return float + */ + public static function IMREAL($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + return $parsedComplex['real']; + } // function IMREAL() + + + /** + * IMABS + * + * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMABS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the absolute value. + * @return float + */ + public static function IMABS($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + return sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); + } // function IMABS() + + + /** + * IMARGUMENT + * + * Returns the argument theta of a complex number, i.e. the angle in radians from the real + * axis to the representation of the number in polar coordinates. + * + * Excel Function: + * IMARGUMENT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the argument theta. + * @return float + */ + public static function IMARGUMENT($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['real'] == 0.0) { + if ($parsedComplex['imaginary'] == 0.0) { + return 0.0; + } elseif($parsedComplex['imaginary'] < 0.0) { + return M_PI / -2; + } else { + return M_PI / 2; + } + } elseif ($parsedComplex['real'] > 0.0) { + return atan($parsedComplex['imaginary'] / $parsedComplex['real']); + } elseif ($parsedComplex['imaginary'] < 0.0) { + return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real']))); + } else { + return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real'])); + } + } // function IMARGUMENT() + + + /** + * IMCONJUGATE + * + * Returns the complex conjugate of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCONJUGATE(complexNumber) + * + * @param string $complexNumber The complex number for which you want the conjugate. + * @return string + */ + public static function IMCONJUGATE($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return $parsedComplex['real']; + } else { + return self::_cleanComplex( self::COMPLEX( $parsedComplex['real'], + 0 - $parsedComplex['imaginary'], + $parsedComplex['suffix'] + ) + ); + } + } // function IMCONJUGATE() + + + /** + * IMCOS + * + * Returns the cosine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCOS(complexNumber) + * + * @param string $complexNumber The complex number for which you want the cosine. + * @return string|float + */ + public static function IMCOS($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return cos($parsedComplex['real']); + } else { + return self::IMCONJUGATE(self::COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix'])); + } + } // function IMCOS() + + + /** + * IMSIN + * + * Returns the sine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSIN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the sine. + * @return string|float + */ + public static function IMSIN($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if ($parsedComplex['imaginary'] == 0.0) { + return sin($parsedComplex['real']); + } else { + return self::COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']); + } + } // function IMSIN() + + + /** + * IMSQRT + * + * Returns the square root of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSQRT(complexNumber) + * + * @param string $complexNumber The complex number for which you want the square root. + * @return string + */ + public static function IMSQRT($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + $theta = self::IMARGUMENT($complexNumber); + $d1 = cos($theta / 2); + $d2 = sin($theta / 2); + $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($d1 * $r,$d2 * $r); + } else { + return self::COMPLEX($d1 * $r,$d2 * $r,$parsedComplex['suffix']); + } + } // function IMSQRT() + + + /** + * IMLN + * + * Returns the natural logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLN(complexNumber) + * + * @param string $complexNumber The complex number for which you want the natural logarithm. + * @return string + */ + public static function IMLN($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); + $t = self::IMARGUMENT($complexNumber); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($logR,$t); + } else { + return self::COMPLEX($logR,$t,$parsedComplex['suffix']); + } + } // function IMLN() + + + /** + * IMLOG10 + * + * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG10(complexNumber) + * + * @param string $complexNumber The complex number for which you want the common logarithm. + * @return string + */ + public static function IMLOG10($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log10($parsedComplex['real']); + } + + return self::IMPRODUCT(log10(EULER),self::IMLN($complexNumber)); + } // function IMLOG10() + + + /** + * IMLOG2 + * + * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMLOG2(complexNumber) + * + * @param string $complexNumber The complex number for which you want the base-2 logarithm. + * @return string + */ + public static function IMLOG2($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return log($parsedComplex['real'],2); + } + + return self::IMPRODUCT(log(EULER,2),self::IMLN($complexNumber)); + } // function IMLOG2() + + + /** + * IMEXP + * + * Returns the exponential of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMEXP(complexNumber) + * + * @param string $complexNumber The complex number for which you want the exponential. + * @return string + */ + public static function IMEXP($complexNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + + $parsedComplex = self::_parseComplex($complexNumber); + + if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + return '1'; + } + + $e = exp($parsedComplex['real']); + $eX = $e * cos($parsedComplex['imaginary']); + $eY = $e * sin($parsedComplex['imaginary']); + + if ($parsedComplex['suffix'] == '') { + return self::COMPLEX($eX,$eY); + } else { + return self::COMPLEX($eX,$eY,$parsedComplex['suffix']); + } + } // function IMEXP() + + + /** + * IMPOWER + * + * Returns a complex number in x + yi or x + yj text format raised to a power. + * + * Excel Function: + * IMPOWER(complexNumber,realNumber) + * + * @param string $complexNumber The complex number you want to raise to a power. + * @param float $realNumber The power to which you want to raise the complex number. + * @return string + */ + public static function IMPOWER($complexNumber,$realNumber) { + $complexNumber = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber); + $realNumber = PHPExcel_Calculation_Functions::flattenSingleValue($realNumber); + + if (!is_numeric($realNumber)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $parsedComplex = self::_parseComplex($complexNumber); + + $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); + $rPower = pow($r,$realNumber); + $theta = self::IMARGUMENT($complexNumber) * $realNumber; + if ($theta == 0) { + return 1; + } elseif ($parsedComplex['imaginary'] == 0.0) { + return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); + } else { + return self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']); + } + } // function IMPOWER() + + + /** + * IMDIV + * + * Returns the quotient of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMDIV(complexDividend,complexDivisor) + * + * @param string $complexDividend The complex numerator or dividend. + * @param string $complexDivisor The complex denominator or divisor. + * @return string + */ + public static function IMDIV($complexDividend,$complexDivisor) { + $complexDividend = PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend); + $complexDivisor = PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor); + + $parsedComplexDividend = self::_parseComplex($complexDividend); + $parsedComplexDivisor = self::_parseComplex($complexDivisor); + + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && + ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) { + $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix']; + } + + $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']); + $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']); + $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']); + + $r = $d1/$d3; + $i = $d2/$d3; + + if ($i > 0.0) { + return self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']); + } elseif ($i < 0.0) { + return self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']); + } else { + return $r; + } + } // function IMDIV() + + + /** + * IMSUB + * + * Returns the difference of two complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUB(complexNumber1,complexNumber2) + * + * @param string $complexNumber1 The complex number from which to subtract complexNumber2. + * @param string $complexNumber2 The complex number to subtract from complexNumber1. + * @return string + */ + public static function IMSUB($complexNumber1,$complexNumber2) { + $complexNumber1 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1); + $complexNumber2 = PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2); + + $parsedComplex1 = self::_parseComplex($complexNumber1); + $parsedComplex2 = self::_parseComplex($complexNumber2); + + if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && + ($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) { + $parsedComplex1['suffix'] = $parsedComplex2['suffix']; + } + + $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; + $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; + + return self::COMPLEX($d1,$d2,$parsedComplex1['suffix']); + } // function IMSUB() + + + /** + * IMSUM + * + * Returns the sum of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMSUM(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to add + * @return string + */ + public static function IMSUM() { + // Return value + $returnValue = self::_parseComplex('0'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + if ($activeSuffix == '') { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $returnValue['real'] += $parsedComplex['real']; + $returnValue['imaginary'] += $parsedComplex['imaginary']; + } + + if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } // function IMSUM() + + + /** + * IMPRODUCT + * + * Returns the product of two or more complex numbers in x + yi or x + yj text format. + * + * Excel Function: + * IMPRODUCT(complexNumber[,complexNumber[,...]]) + * + * @param string $complexNumber,... Series of complex numbers to multiply + * @return string + */ + public static function IMPRODUCT() { + // Return value + $returnValue = self::_parseComplex('1'); + $activeSuffix = ''; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + $parsedComplex = self::_parseComplex($arg); + + $workValue = $returnValue; + if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { + $activeSuffix = $parsedComplex['suffix']; + } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { + return PHPExcel_Calculation_Functions::NaN(); + } + $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']); + $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']); + } + + if ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; } + return self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix); + } // function IMPRODUCT() + + + /** + * DELTA + * + * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. + * Use this function to filter a set of values. For example, by summing several DELTA + * functions you calculate the count of equal pairs. This function is also known as the + * Kronecker Delta function. + * + * Excel Function: + * DELTA(a[,b]) + * + * @param float $a The first number. + * @param float $b The second number. If omitted, b is assumed to be zero. + * @return int + */ + public static function DELTA($a, $b=0) { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + return (int) ($a == $b); + } // function DELTA() + + + /** + * GESTEP + * + * Excel Function: + * GESTEP(number[,step]) + * + * Returns 1 if number >= step; returns 0 (zero) otherwise + * Use this function to filter a set of values. For example, by summing several GESTEP + * functions you calculate the count of values that exceed a threshold. + * + * @param float $number The value to test against step. + * @param float $step The threshold value. + * If you omit a value for step, GESTEP uses zero. + * @return int + */ + public static function GESTEP($number, $step=0) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $step = PHPExcel_Calculation_Functions::flattenSingleValue($step); + + return (int) ($number >= $step); + } // function GESTEP() + + + // + // Private method to calculate the erf value + // + private static $_two_sqrtpi = 1.128379167095512574; + + public static function _erfVal($x) { + if (abs($x) > 2.2) { + return 1 - self::_erfcVal($x); + } + $sum = $term = $x; + $xsqr = ($x * $x); + $j = 1; + do { + $term *= $xsqr / $j; + $sum -= $term / (2 * $j + 1); + ++$j; + $term *= $xsqr / $j; + $sum += $term / (2 * $j + 1); + ++$j; + if ($sum == 0.0) { + break; + } + } while (abs($term / $sum) > PRECISION); + return self::$_two_sqrtpi * $sum; + } // function _erfVal() + + + /** + * ERF + * + * Returns the error function integrated between the lower and upper bound arguments. + * + * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative ranges. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERF(lower[,upper]) + * + * @param float $lower lower bound for integrating ERF + * @param float $upper upper bound for integrating ERF. + * If omitted, ERF integrates between zero and lower_limit + * @return float + */ + public static function ERF($lower, $upper = NULL) { + $lower = PHPExcel_Calculation_Functions::flattenSingleValue($lower); + $upper = PHPExcel_Calculation_Functions::flattenSingleValue($upper); + + if (is_numeric($lower)) { + if (is_null($upper)) { + return self::_erfVal($lower); + } + if (is_numeric($upper)) { + return self::_erfVal($upper) - self::_erfVal($lower); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ERF() + + + // + // Private method to calculate the erfc value + // + private static $_one_sqrtpi = 0.564189583547756287; + + private static function _erfcVal($x) { + if (abs($x) < 2.2) { + return 1 - self::_erfVal($x); + } + if ($x < 0) { + return 2 - self::ERFC(-$x); + } + $a = $n = 1; + $b = $c = $x; + $d = ($x * $x) + 0.5; + $q1 = $q2 = $b / $d; + $t = 0; + do { + $t = $a * $n + $b * $x; + $a = $b; + $b = $t; + $t = $c * $n + $d * $x; + $c = $d; + $d = $t; + $n += 0.5; + $q1 = $q2; + $q2 = $b / $d; + } while ((abs($q1 - $q2) / $q2) > PRECISION); + return self::$_one_sqrtpi * exp(-$x * $x) * $q2; + } // function _erfcVal() + + + /** + * ERFC + * + * Returns the complementary ERF function integrated between x and infinity + * + * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, + * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was + * improved, so that it can now calculate the function for both positive and negative x values. + * PHPExcel follows Excel 2010 behaviour, and accepts nagative arguments. + * + * Excel Function: + * ERFC(x) + * + * @param float $x The lower bound for integrating ERFC + * @return float + */ + public static function ERFC($x) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + + if (is_numeric($x)) { + return self::_erfcVal($x); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ERFC() + + + /** + * getConversionGroups + * Returns a list of the different conversion groups for UOM conversions + * + * @return array + */ + public static function getConversionGroups() { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit) { + $conversionGroups[] = $conversionUnit['Group']; + } + return array_merge(array_unique($conversionGroups)); + } // function getConversionGroups() + + + /** + * getConversionGroupUnits + * Returns an array of units of measure, for a specified conversion group, or for all groups + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnits($group = NULL) { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = $conversionUnit; + } + } + return $conversionGroups; + } // function getConversionGroupUnits() + + + /** + * getConversionGroupUnitDetails + * + * @param string $group The group whose units of measure you want to retrieve + * @return array + */ + public static function getConversionGroupUnitDetails($group = NULL) { + $conversionGroups = array(); + foreach(self::$_conversionUnits as $conversionUnit => $conversionGroup) { + if ((is_null($group)) || ($conversionGroup['Group'] == $group)) { + $conversionGroups[$conversionGroup['Group']][] = array( 'unit' => $conversionUnit, + 'description' => $conversionGroup['Unit Name'] + ); + } + } + return $conversionGroups; + } // function getConversionGroupUnitDetails() + + + /** + * getConversionMultipliers + * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM() + * + * @return array of mixed + */ + public static function getConversionMultipliers() { + return self::$_conversionMultipliers; + } // function getConversionGroups() + + + /** + * CONVERTUOM + * + * Converts a number from one measurement system to another. + * For example, CONVERT can translate a table of distances in miles to a table of distances + * in kilometers. + * + * Excel Function: + * CONVERT(value,fromUOM,toUOM) + * + * @param float $value The value in fromUOM to convert. + * @param string $fromUOM The units for value. + * @param string $toUOM The units for the result. + * + * @return float + */ + public static function CONVERTUOM($value, $fromUOM, $toUOM) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $fromUOM = PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM); + $toUOM = PHPExcel_Calculation_Functions::flattenSingleValue($toUOM); + + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $fromMultiplier = 1.0; + if (isset(self::$_conversionUnits[$fromUOM])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + $fromMultiplier = substr($fromUOM,0,1); + $fromUOM = substr($fromUOM,1); + if (isset(self::$_conversionMultipliers[$fromMultiplier])) { + $fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) { + $unitGroup1 = self::$_conversionUnits[$fromUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + $value *= $fromMultiplier; + + $toMultiplier = 1.0; + if (isset(self::$_conversionUnits[$toUOM])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + $toMultiplier = substr($toUOM,0,1); + $toUOM = substr($toUOM,1); + if (isset(self::$_conversionMultipliers[$toMultiplier])) { + $toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + if ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) { + $unitGroup2 = self::$_conversionUnits[$toUOM]['Group']; + } else { + return PHPExcel_Calculation_Functions::NA(); + } + } + if ($unitGroup1 != $unitGroup2) { + return PHPExcel_Calculation_Functions::NA(); + } + + if (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) { + // We've already factored $fromMultiplier into the value, so we need + // to reverse it again + return $value / $fromMultiplier; + } elseif ($unitGroup1 == 'Temperature') { + if (($fromUOM == 'F') || ($fromUOM == 'fah')) { + if (($toUOM == 'F') || ($toUOM == 'fah')) { + return $value; + } else { + $value = (($value - 32) / 1.8); + if (($toUOM == 'K') || ($toUOM == 'kel')) { + $value += 273.15; + } + return $value; + } + } elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) && + (($toUOM == 'K') || ($toUOM == 'kel'))) { + return $value; + } elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) && + (($toUOM == 'C') || ($toUOM == 'cel'))) { + return $value; + } + if (($toUOM == 'F') || ($toUOM == 'fah')) { + if (($fromUOM == 'K') || ($fromUOM == 'kel')) { + $value -= 273.15; + } + return ($value * 1.8) + 32; + } + if (($toUOM == 'C') || ($toUOM == 'cel')) { + return $value - 273.15; + } + return $value + 273.15; + } + return ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier; + } // function CONVERTUOM() + +} // class PHPExcel_Calculation_Engineering diff --git a/extend/phpexcel/PHPExcel/Calculation/Exception.php b/extend/phpexcel/PHPExcel/Calculation/Exception.php new file mode 100755 index 0000000..037f788 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/extend/phpexcel/PHPExcel/Calculation/ExceptionHandler.php b/extend/phpexcel/PHPExcel/Calculation/ExceptionHandler.php new file mode 100755 index 0000000..389f647 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/ExceptionHandler.php @@ -0,0 +1,49 @@ +format('d') == $testDate->format('t')); + } // function _lastDayOfMonth() + + + /** + * _firstDayOfMonth + * + * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month + * + * @param DateTime $testDate The date for testing + * @return boolean + */ + private static function _firstDayOfMonth($testDate) + { + return ($testDate->format('d') == 1); + } // function _firstDayOfMonth() + + + private static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next) + { + $months = 12 / $frequency; + + $result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity); + $eom = self::_lastDayOfMonth($result); + + while ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) { + $result->modify('-'.$months.' months'); + } + if ($next) { + $result->modify('+'.$months.' months'); + } + + if ($eom) { + $result->modify('-1 day'); + } + + return PHPExcel_Shared_Date::PHPToExcel($result); + } // function _coupFirstPeriodDate() + + + private static function _validFrequency($frequency) + { + if (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) { + return true; + } + if ((PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) && + (($frequency == 6) || ($frequency == 12))) { + return true; + } + return false; + } // function _validFrequency() + + + /** + * _daysPerYear + * + * Returns the number of days in a specified year, as defined by the "basis" value + * + * @param integer $year The year against which we're testing + * @param integer $basis The type of day count: + * 0 or omitted US (NASD) 360 + * 1 Actual (365 or 366 in a leap year) + * 2 360 + * 3 365 + * 4 European 360 + * @return integer + */ + private static function _daysPerYear($year, $basis=0) + { + switch ($basis) { + case 0 : + case 2 : + case 4 : + $daysPerYear = 360; + break; + case 3 : + $daysPerYear = 365; + break; + case 1 : + $daysPerYear = (PHPExcel_Calculation_DateTime::_isLeapYear($year)) ? 366 : 365; + break; + default : + return PHPExcel_Calculation_Functions::NaN(); + } + return $daysPerYear; + } // function _daysPerYear() + + + private static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0) + { + $pmt = self::PMT($rate, $nper, $pv, $fv, $type); + $capital = $pv; + for ($i = 1; $i<= $per; ++$i) { + $interest = ($type && $i == 1) ? 0 : -$capital * $rate; + $principal = $pmt - $interest; + $capital += $principal; + } + return array($interest, $principal); + } // function _interestAndPrincipal() + + + /** + * ACCRINT + * + * Returns the accrued interest for a security that pays periodic interest. + * + * Excel Function: + * ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed $issue The security's issue date. + * @param mixed $firstinterest The security's first interest date. + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date + * when the security is traded to the buyer. + * @param float $rate The security's annual coupon rate. + * @param float $par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer $frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0) + { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $firstinterest = PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $frequency = (is_null($frequency)) ? 1 : PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINT() + + + /** + * ACCRINTM + * + * Returns the accrued interest for a security that pays interest at maturity. + * + * Excel Function: + * ACCRINTM(issue,settlement,rate[,par[,basis]]) + * + * @access public + * @category Financial Functions + * @param mixed issue The security's issue date. + * @param mixed settlement The security's settlement (or maturity) date. + * @param float rate The security's annual coupon rate. + * @param float par The security's par value. + * If you omit par, ACCRINT uses $1,000. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) { + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $par = (is_null($par)) ? 1000 : PHPExcel_Calculation_Functions::flattenSingleValue($par); + $basis = (is_null($basis)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($rate)) && (is_numeric($par))) { + $rate = (float) $rate; + $par = (float) $par; + if (($rate <= 0) || ($par <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + return $par * $rate * $daysBetweenIssueAndSettlement; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ACCRINTM() + + + /** + * AMORDEGRC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * The function is similar to AMORLINC, except that a depreciation coefficient is applied in + * the calculation depending on the life of the assets. + * This function will return the depreciation until the last period of the life of the assets + * or until the cumulated value of depreciation is greater than the cost of the assets minus + * the salvage value. + * + * Excel Function: + * AMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = floor(PHPExcel_Calculation_Functions::flattenSingleValue($period)); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // The depreciation coefficients are: + // Life of assets (1/rate) Depreciation coefficient + // Less than 3 years 1 + // Between 3 and 4 years 1.5 + // Between 5 and 6 years 2 + // More than 6 years 2.5 + $fUsePer = 1.0 / $rate; + if ($fUsePer < 3.0) { + $amortiseCoeff = 1.0; + } elseif ($fUsePer < 5.0) { + $amortiseCoeff = 1.5; + } elseif ($fUsePer <= 6.0) { + $amortiseCoeff = 2.0; + } else { + $amortiseCoeff = 2.5; + } + + $rate *= $amortiseCoeff; + $fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0); + $cost -= $fNRate; + $fRest = $cost - $salvage; + + for ($n = 0; $n < $period; ++$n) { + $fNRate = round($rate * $cost,0); + $fRest -= $fNRate; + + if ($fRest < 0.0) { + switch ($period - $n) { + case 0 : + case 1 : return round($cost * 0.5, 0); + break; + default : return 0.0; + break; + } + } + $cost -= $fNRate; + } + return $fNRate; + } // function AMORDEGRC() + + + /** + * AMORLINC + * + * Returns the depreciation for each accounting period. + * This function is provided for the French accounting system. If an asset is purchased in + * the middle of the accounting period, the prorated depreciation is taken into account. + * + * Excel Function: + * AMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis]) + * + * @access public + * @category Financial Functions + * @param float cost The cost of the asset. + * @param mixed purchased Date of the purchase of the asset. + * @param mixed firstPeriod Date of the end of the first period. + * @param mixed salvage The salvage value at the end of the life of the asset. + * @param float period The period. + * @param float rate Rate of depreciation. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $purchased = PHPExcel_Calculation_Functions::flattenSingleValue($purchased); + $firstPeriod = PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + $fOneRate = $cost * $rate; + $fCostDelta = $cost - $salvage; + // Note, quirky variation for leap years on the YEARFRAC for this function + $purchasedYear = PHPExcel_Calculation_DateTime::YEAR($purchased); + $yearFrac = PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis); + + if (($basis == 1) && ($yearFrac < 1) && (PHPExcel_Calculation_DateTime::_isLeapYear($purchasedYear))) { + $yearFrac *= 365 / 366; + } + + $f0Rate = $yearFrac * $rate * $cost; + $nNumOfFullPeriods = intval(($cost - $salvage - $f0Rate) / $fOneRate); + + if ($period == 0) { + return $f0Rate; + } elseif ($period <= $nNumOfFullPeriods) { + return $fOneRate; + } elseif ($period == ($nNumOfFullPeriods + 1)) { + return ($fCostDelta - $fOneRate * $nNumOfFullPeriods - $f0Rate); + } else { + return 0.0; + } + } // function AMORLINC() + + + /** + * COUPDAYBS + * + * Returns the number of days from the beginning of the coupon period to the settlement date. + * + * Excel Function: + * COUPDAYBS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + + return PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear; + } // function COUPDAYBS() + + + /** + * COUPDAYS + * + * Returns the number of days in the coupon period that contains the settlement date. + * + * Excel Function: + * COUPDAYS(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + switch ($basis) { + case 3: // Actual/365 + return 365 / $frequency; + case 1: // Actual/actual + if ($frequency == 1) { + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis); + return ($daysPerYear / $frequency); + } else { + $prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + return ($next - $prev); + } + default: // US (NASD) 30/360, Actual/360 or European 30/360 + return 360 / $frequency; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPDAYS() + + + /** + * COUPDAYSNC + * + * Returns the number of days from the settlement date to the next coupon date. + * + * Excel Function: + * COUPDAYSNC(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + $next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + + return PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear; + } // function COUPDAYSNC() + + + /** + * COUPNCD + * + * Returns the next coupon date after the settlement date. + * + * Excel Function: + * COUPNCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPNCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + } // function COUPNCD() + + + /** + * COUPNUM + * + * Returns the number of coupons payable between the settlement date and maturity date, + * rounded up to the nearest whole coupon. + * + * Excel Function: + * COUPNUM(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return integer + */ + public static function COUPNUM($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True); + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365; + + switch ($frequency) { + case 1: // annual payments + return ceil($daysBetweenSettlementAndMaturity / 360); + case 2: // half-yearly + return ceil($daysBetweenSettlementAndMaturity / 180); + case 4: // quarterly + return ceil($daysBetweenSettlementAndMaturity / 90); + case 6: // bimonthly + return ceil($daysBetweenSettlementAndMaturity / 60); + case 12: // monthly + return ceil($daysBetweenSettlementAndMaturity / 30); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COUPNUM() + + + /** + * COUPPCD + * + * Returns the previous coupon date before the settlement date. + * + * Excel Function: + * COUPPCD(settlement,maturity,frequency[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed frequency the number of coupon payments per year. + * Valid frequency values are: + * 1 Annual + * 2 Semi-Annual + * 4 Quarterly + * If working in Gnumeric Mode, the following frequency options are + * also available + * 6 Bimonthly + * 12 Monthly + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, + * depending on the value of the ReturnDateType flag + */ + public static function COUPPCD($settlement, $maturity, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False); + } // function COUPPCD() + + + /** + * CUMIPMT + * + * Returns the cumulative interest paid on a loan between the start and end periods. + * + * Excel Function: + * CUMIPMT(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interest = 0; + for ($per = $start; $per <= $end; ++$per) { + $interest += self::IPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $interest; + } // function CUMIPMT() + + + /** + * CUMPRINC + * + * Returns the cumulative principal paid on a loan between the start and end periods. + * + * Excel Function: + * CUMPRINC(rate,nper,pv,start,end[,type]) + * + * @access public + * @category Financial Functions + * @param float $rate The Interest rate + * @param integer $nper The total number of payment periods + * @param float $pv Present Value + * @param integer $start The first period in the calculation. + * Payment periods are numbered beginning with 1. + * @param integer $end The last period in the calculation. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $start = (int) PHPExcel_Calculation_Functions::flattenSingleValue($start); + $end = (int) PHPExcel_Calculation_Functions::flattenSingleValue($end); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($start < 1 || $start > $end) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $principal = 0; + for ($per = $start; $per <= $end; ++$per) { + $principal += self::PPMT($rate, $per, $nper, $pv, 0, $type); + } + + return $principal; + } // function CUMPRINC() + + + /** + * DB + * + * Returns the depreciation of an asset for a specified period using the + * fixed-declining balance method. + * This form of depreciation is used if you want to get a higher depreciation value + * at the beginning of the depreciation (as opposed to linear depreciation). The + * depreciation value is reduced with every depreciation period by the depreciation + * already deducted from the initial cost. + * + * Excel Function: + * DB(cost,salvage,life,period[,month]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param integer month Number of months in the first year. If month is omitted, + * it defaults to 12. + * @return float + */ + public static function DB($cost, $salvage, $life, $period, $month=12) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $month = PHPExcel_Calculation_Functions::flattenSingleValue($month); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $month = (int) $month; + if ($cost == 0) { + return 0.0; + } elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + if ($per == 1) { + $depreciation = $cost * $fixedDepreciationRate * $month / 12; + } elseif ($per == ($life + 1)) { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate * (12 - $month) / 12; + } else { + $depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate; + } + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DB() + + + /** + * DDB + * + * Returns the depreciation of an asset for a specified period using the + * double-declining balance method or some other method you specify. + * + * Excel Function: + * DDB(cost,salvage,life,period[,factor]) + * + * @access public + * @category Financial Functions + * @param float cost Initial cost of the asset. + * @param float salvage Value at the end of the depreciation. + * (Sometimes called the salvage value of the asset) + * @param integer life Number of periods over which the asset is depreciated. + * (Sometimes called the useful life of the asset) + * @param integer period The period for which you want to calculate the + * depreciation. Period must use the same units as life. + * @param float factor The rate at which the balance declines. + * If factor is omitted, it is assumed to be 2 (the + * double-declining balance method). + * @return float + */ + public static function DDB($cost, $salvage, $life, $period, $factor=2.0) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + $factor = PHPExcel_Calculation_Functions::flattenSingleValue($factor); + + // Validate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) { + $cost = (float) $cost; + $salvage = (float) $salvage; + $life = (int) $life; + $period = (int) $period; + $factor = (float) $factor; + if (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // Set Fixed Depreciation Rate + $fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life)); + $fixedDepreciationRate = round($fixedDepreciationRate, 3); + + // Loop through each period calculating the depreciation + $previousDepreciation = 0; + for ($per = 1; $per <= $period; ++$per) { + $depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) ); + $previousDepreciation += $depreciation; + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + $depreciation = round($depreciation,2); + } + return $depreciation; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DDB() + + + /** + * DISC + * + * Returns the discount rate for a security. + * + * Excel Function: + * DISC(settlement,maturity,price,redemption[,basis]) + * + * @access public + * @category Financial Functions + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue + * date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer price The security's price per $100 face value. + * @param integer redemption The security's redemption value per $100 face value. + * @param integer basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function DISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $price = (float) $price; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function DISC() + + + /** + * DOLLARDE + * + * Converts a dollar price expressed as an integer part and a fraction + * part into a dollar price expressed as a decimal number. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARDE(fractional_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $fractional_dollar Fractional Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARDE($fractional_dollar = Null, $fraction = 0) { + $fractional_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($fractional_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($fractional_dollar); + $cents = fmod($fractional_dollar,1); + $cents /= $fraction; + $cents *= pow(10,ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARDE() + + + /** + * DOLLARFR + * + * Converts a dollar price expressed as a decimal number into a dollar price + * expressed as a fraction. + * Fractional dollar numbers are sometimes used for security prices. + * + * Excel Function: + * DOLLARFR(decimal_dollar,fraction) + * + * @access public + * @category Financial Functions + * @param float $decimal_dollar Decimal Dollar + * @param integer $fraction Fraction + * @return float + */ + public static function DOLLARFR($decimal_dollar = Null, $fraction = 0) { + $decimal_dollar = PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar); + $fraction = (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction); + + // Validate parameters + if (is_null($decimal_dollar) || $fraction < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($fraction == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $dollars = floor($decimal_dollar); + $cents = fmod($decimal_dollar,1); + $cents *= $fraction; + $cents *= pow(10,-ceil(log10($fraction))); + return $dollars + $cents; + } // function DOLLARFR() + + + /** + * EFFECT + * + * Returns the effective interest rate given the nominal rate and the number of + * compounding payments per year. + * + * Excel Function: + * EFFECT(nominal_rate,npery) + * + * @access public + * @category Financial Functions + * @param float $nominal_rate Nominal interest rate + * @param integer $npery Number of compounding payments per year + * @return float + */ + public static function EFFECT($nominal_rate = 0, $npery = 0) { + $nominal_rate = PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($nominal_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return pow((1 + $nominal_rate / $npery), $npery) - 1; + } // function EFFECT() + + + /** + * FV + * + * Returns the Future Value of a cash flow with constant payments and interest rate (annuities). + * + * Excel Function: + * FV(rate,nper,pmt[,pv[,type]]) + * + * @access public + * @category Financial Functions + * @param float $rate The interest rate per period + * @param int $nper Total number of payment periods in an annuity + * @param float $pmt The payment made each period: it cannot change over the + * life of the annuity. Typically, pmt contains principal + * and interest but no other fees or taxes. + * @param float $pv Present Value, or the lump-sum amount that a series of + * future payments is worth right now. + * @param integer $type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @return float + */ + public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate; + } else { + return -$pv - $pmt * $nper; + } + } // function FV() + + + /** + * FVSCHEDULE + * + * Returns the future value of an initial principal after applying a series of compound interest rates. + * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate. + * + * Excel Function: + * FVSCHEDULE(principal,schedule) + * + * @param float $principal The present value. + * @param float[] $schedule An array of interest rates to apply. + * @return float + */ + public static function FVSCHEDULE($principal, $schedule) { + $principal = PHPExcel_Calculation_Functions::flattenSingleValue($principal); + $schedule = PHPExcel_Calculation_Functions::flattenArray($schedule); + + foreach($schedule as $rate) { + $principal *= 1 + $rate; + } + + return $principal; + } // function FVSCHEDULE() + + + /** + * INTRATE + * + * Returns the interest rate for a fully invested security. + * + * Excel Function: + * INTRATE(settlement,maturity,investment,redemption[,basis]) + * + * @param mixed $settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed $maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param integer $investment The amount invested in the security. + * @param integer $redemption The amount to be received at maturity. + * @param integer $basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) { + $investment = (float) $investment; + $redemption = (float) $redemption; + $basis = (int) $basis; + if (($investment <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INTRATE() + + + /** + * IPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * Excel Function: + * IPMT(rate,per,nper,pv[,fv][,type]) + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[0]; + } // function IPMT() + + /** + * IRR + * + * Returns the internal rate of return for a series of cash flows represented by the numbers in values. + * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur + * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received + * for an investment consisting of payments (negative values) and income (positive values) that occur at regular + * periods. + * + * Excel Function: + * IRR(values[,guess]) + * + * @param float[] $values An array or a reference to cells that contain numbers for which you want + * to calculate the internal rate of return. + * Values must contain at least one positive value and one negative value to + * calculate the internal rate of return. + * @param float $guess A number that you guess is close to the result of IRR + * @return float + */ + public static function IRR($values, $guess = 0.1) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::NPV($x1, $values); + $f2 = self::NPV($x2, $values); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values); + } else { + $f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::NPV($x1, $values); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::NPV($x_mid, $values); + if ($f_mid <= 0.0) + $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) + return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function IRR() + + + /** + * ISPMT + * + * Returns the interest payment for an investment based on an interest rate and a constant payment schedule. + * + * Excel Function: + * =ISPMT(interest_rate, period, number_payments, PV) + * + * interest_rate is the interest rate for the investment + * + * period is the period to calculate the interest rate. It must be betweeen 1 and number_payments. + * + * number_payments is the number of payments for the annuity + * + * PV is the loan amount or present value of the payments + */ + public static function ISPMT() { + // Return value + $returnValue = 0; + + // Get the parameters + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $interestRate = array_shift($aArgs); + $period = array_shift($aArgs); + $numberPeriods = array_shift($aArgs); + $principleRemaining = array_shift($aArgs); + + // Calculate + $principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0); + for($i=0; $i <= $period; ++$i) { + $returnValue = $interestRate * $principleRemaining * -1; + $principleRemaining -= $principlePayment; + // principle needs to be 0 after the last payment, don't let floating point screw it up + if($i == $numberPeriods) { + $returnValue = 0; + } + } + return($returnValue); + } // function ISPMT() + + + /** + * MIRR + * + * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both + * the cost of the investment and the interest received on reinvestment of cash. + * + * Excel Function: + * MIRR(values,finance_rate, reinvestment_rate) + * + * @param float[] $values An array or a reference to cells that contain a series of payments and + * income occurring at regular intervals. + * Payments are negative value, income is positive values. + * @param float $finance_rate The interest rate you pay on the money used in the cash flows + * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them + * @return float + */ + public static function MIRR($values, $finance_rate, $reinvestment_rate) { + if (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $finance_rate = PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate); + $reinvestment_rate = PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate); + $n = count($values); + + $rr = 1.0 + $reinvestment_rate; + $fr = 1.0 + $finance_rate; + + $npv_pos = $npv_neg = 0.0; + foreach($values as $i => $v) { + if ($v >= 0) { + $npv_pos += $v / pow($rr, $i); + } else { + $npv_neg += $v / pow($fr, $i); + } + } + + if (($npv_neg == 0) || ($npv_pos == 0) || ($reinvestment_rate <= -1)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $mirr = pow((-$npv_pos * pow($rr, $n)) + / ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0; + + return (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE()); + } // function MIRR() + + + /** + * NOMINAL + * + * Returns the nominal interest rate given the effective rate and the number of compounding payments per year. + * + * @param float $effect_rate Effective interest rate + * @param int $npery Number of compounding payments per year + * @return float + */ + public static function NOMINAL($effect_rate = 0, $npery = 0) { + $effect_rate = PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate); + $npery = (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery); + + // Validate parameters + if ($effect_rate <= 0 || $npery < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + return $npery * (pow($effect_rate + 1, 1 / $npery) - 1); + } // function NOMINAL() + + + /** + * NPER + * + * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate. + * + * @param float $rate Interest rate per period + * @param int $pmt Periodic payment (annuity) + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + if ($pmt == 0 && $pv == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate); + } else { + if ($pmt == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (-$pv -$fv) / $pmt; + } + } // function NPER() + + /** + * NPV + * + * Returns the Net Present Value of a cash flow series given a discount rate. + * + * @return float + */ + public static function NPV() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $rate = array_shift($aArgs); + for ($i = 1; $i <= count($aArgs); ++$i) { + // Is it a numeric value? + if (is_numeric($aArgs[$i - 1])) { + $returnValue += $aArgs[$i - 1] / pow(1 + $rate, $i); + } + } + + // Return + return $returnValue; + } // function NPV() + + /** + * PMT + * + * Returns the constant payment (annuity) for a cash flow with a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate); + } else { + return (-$pv - $fv) / $nper; + } + } // function PMT() + + + /** + * PPMT + * + * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate. + * + * @param float $rate Interest rate per period + * @param int $per Period for which we want to find the interest + * @param int $nper Number of periods + * @param float $pv Present Value + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $per = (int) PHPExcel_Calculation_Functions::flattenSingleValue($per); + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($per <= 0 || $per > $nper) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Calculate + $interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type); + return $interestAndPrincipal[1]; + } // function PPMT() + + + public static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $rate = (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $frequency = (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency); + $basis = (is_null($basis)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + if (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (($settlement > $maturity) || + (!self::_validFrequency($frequency)) || + (($basis < 0) || ($basis > 4))) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $dsc = self::COUPDAYSNC($settlement, $maturity, $frequency, $basis); + $e = self::COUPDAYS($settlement, $maturity, $frequency, $basis); + $n = self::COUPNUM($settlement, $maturity, $frequency, $basis); + $a = self::COUPDAYBS($settlement, $maturity, $frequency, $basis); + + $baseYF = 1.0 + ($yield / $frequency); + $rfp = 100 * ($rate / $frequency); + $de = $dsc / $e; + + $result = $redemption / pow($baseYF, (--$n + $de)); + for($k = 0; $k <= $n; ++$k) { + $result += $rfp / (pow($baseYF, ($k + $de))); + } + $result -= $rfp * ($a / $e); + + return $result; + } // function PRICE() + + + /** + * PRICEDISC + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int discount The security's discount rate. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $redemption = (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) { + if (($discount <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEDISC() + + + /** + * PRICEMAT + * + * Returns the price per $100 face value of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int yield The security's annual yield. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $yield = PHPExcel_Calculation_Functions::flattenSingleValue($yield); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($yield)) { + if (($rate <= 0) || ($yield <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((100 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate * 100)) / + (1 + (($daysBetweenSettlementAndMaturity / $daysPerYear) * $yield)) - + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PRICEMAT() + + + /** + * PV + * + * Returns the Present Value of a cash flow with constant payments and interest rate (annuities). + * + * @param float $rate Interest rate per period + * @param int $nper Number of periods + * @param float $pmt Periodic payment (annuity) + * @param float $fv Future Value + * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period + * @return float + */ + public static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $nper = PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $fv = PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = PHPExcel_Calculation_Functions::flattenSingleValue($type); + + // Validate parameters + if ($type != 0 && $type != 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + + // Calculate + if (!is_null($rate) && $rate != 0) { + return (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper); + } else { + return -$fv - $pmt * $nper; + } + } // function PV() + + + /** + * RATE + * + * Returns the interest rate per period of an annuity. + * RATE is calculated by iteration and can have zero or more solutions. + * If the successive results of RATE do not converge to within 0.0000001 after 20 iterations, + * RATE returns the #NUM! error value. + * + * Excel Function: + * RATE(nper,pmt,pv[,fv[,type[,guess]]]) + * + * @access public + * @category Financial Functions + * @param float nper The total number of payment periods in an annuity. + * @param float pmt The payment made each period and cannot change over the life + * of the annuity. + * Typically, pmt includes principal and interest but no other + * fees or taxes. + * @param float pv The present value - the total amount that a series of future + * payments is worth now. + * @param float fv The future value, or a cash balance you want to attain after + * the last payment is made. If fv is omitted, it is assumed + * to be 0 (the future value of a loan, for example, is 0). + * @param integer type A number 0 or 1 and indicates when payments are due: + * 0 or omitted At the end of the period. + * 1 At the beginning of the period. + * @param float guess Your guess for what the rate will be. + * If you omit guess, it is assumed to be 10 percent. + * @return float + **/ + public static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) { + $nper = (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper); + $pmt = PHPExcel_Calculation_Functions::flattenSingleValue($pmt); + $pv = PHPExcel_Calculation_Functions::flattenSingleValue($pv); + $fv = (is_null($fv)) ? 0.0 : PHPExcel_Calculation_Functions::flattenSingleValue($fv); + $type = (is_null($type)) ? 0 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($type); + $guess = (is_null($guess)) ? 0.1 : PHPExcel_Calculation_Functions::flattenSingleValue($guess); + + $rate = $guess; + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + $y0 = $pv + $pmt * $nper + $fv; + $y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + + // find root by secant method + $i = $x0 = 0.0; + $x1 = $rate; + while ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) { + $rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0); + $x0 = $x1; + $x1 = $rate; + if (($nper * abs($pmt)) > ($pv - $fv)) + $x1 = abs($x1); + + if (abs($rate) < FINANCIAL_PRECISION) { + $y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv; + } else { + $f = exp($nper * log(1 + $rate)); + $y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv; + } + + $y0 = $y1; + $y1 = $y; + ++$i; + } + return $rate; + } // function RATE() + + + /** + * RECEIVED + * + * Returns the price per $100 face value of a discounted security. + * + * @param mixed settlement The security's settlement date. + * The security settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int investment The amount invested in the security. + * @param int discount The security's discount rate. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $investment = (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment); + $discount = (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) { + if (($investment <= 0) || ($discount <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + + return $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function RECEIVED() + + + /** + * SLN + * + * Returns the straight-line depreciation of an asset for one period + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @return float + */ + public static function SLN($cost, $salvage, $life) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) { + if ($life < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($cost - $salvage) / $life; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SLN() + + + /** + * SYD + * + * Returns the sum-of-years' digits depreciation of an asset for a specified period. + * + * @param cost Initial cost of the asset + * @param salvage Value at the end of the depreciation + * @param life Number of periods over which the asset is depreciated + * @param period Period + * @return float + */ + public static function SYD($cost, $salvage, $life, $period) { + $cost = PHPExcel_Calculation_Functions::flattenSingleValue($cost); + $salvage = PHPExcel_Calculation_Functions::flattenSingleValue($salvage); + $life = PHPExcel_Calculation_Functions::flattenSingleValue($life); + $period = PHPExcel_Calculation_Functions::flattenSingleValue($period); + + // Calculate + if ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) { + if (($life < 1) || ($period > $life)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SYD() + + + /** + * TBILLEQ + * + * Returns the bond-equivalent yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLEQ($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + // Use TBILLPRICE for validation + $testValue = self::TBILLPRICE($settlement, $maturity, $discount); + if (is_string($testValue)) { + return $testValue; + } + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity); + } // function TBILLEQ() + + + /** + * TBILLPRICE + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int discount The Treasury bill's discount rate. + * @return float + */ + public static function TBILLPRICE($settlement, $maturity, $discount) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $discount = PHPExcel_Calculation_Functions::flattenSingleValue($discount); + + if (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // Validate + if (is_numeric($discount)) { + if ($discount <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360)); + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return $price; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLPRICE() + + + /** + * TBILLYIELD + * + * Returns the yield for a Treasury bill. + * + * @param mixed settlement The Treasury bill's settlement date. + * The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer. + * @param mixed maturity The Treasury bill's maturity date. + * The maturity date is the date when the Treasury bill expires. + * @param int price The Treasury bill's price per $100 face value. + * @return float + */ + public static function TBILLYIELD($settlement, $maturity, $price) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + + // Validate + if (is_numeric($price)) { + if ($price <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + ++$maturity; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360; + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + } else { + $daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement)); + } + + if ($daysBetweenSettlementAndMaturity > 360) { + return PHPExcel_Calculation_Functions::NaN(); + } + + return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TBILLYIELD() + + + public static function XIRR($values, $dates, $guess = 0.1) { + if ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess); + if (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + + // create an initial range, with a root somewhere between 0 and guess + $x1 = 0.0; + $x2 = $guess; + $f1 = self::XNPV($x1, $values, $dates); + $f2 = self::XNPV($x2, $values, $dates); + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + if (($f1 * $f2) < 0.0) break; + if (abs($f1) < abs($f2)) { + $f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates); + } else { + $f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates); + } + } + if (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE(); + + $f = self::XNPV($x1, $values, $dates); + if ($f < 0.0) { + $rtb = $x1; + $dx = $x2 - $x1; + } else { + $rtb = $x2; + $dx = $x1 - $x2; + } + + for ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) { + $dx *= 0.5; + $x_mid = $rtb + $dx; + $f_mid = self::XNPV($x_mid, $values, $dates); + if ($f_mid <= 0.0) $rtb = $x_mid; + if ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid; + } + return PHPExcel_Calculation_Functions::VALUE(); + } + + + /** + * XNPV + * + * Returns the net present value for a schedule of cash flows that is not necessarily periodic. + * To calculate the net present value for a series of cash flows that is periodic, use the NPV function. + * + * Excel Function: + * =XNPV(rate,values,dates) + * + * @param float $rate The discount rate to apply to the cash flows. + * @param array of float $values A series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value. + * @param array of mixed $dates A schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order. + * @return float + */ + public static function XNPV($rate, $values, $dates) { + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + if (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE(); + if ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE(); + $values = PHPExcel_Calculation_Functions::flattenArray($values); + $dates = PHPExcel_Calculation_Functions::flattenArray($dates); + $valCount = count($values); + if ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN(); + if ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE(); + + $xnpv = 0.0; + for ($i = 0; $i < $valCount; ++$i) { + if (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE(); + $xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365); + } + return (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE(); + } // function XNPV() + + + /** + * YIELDDISC + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param int price The security's price per $100 face value. + * @param int redemption The security's redemption value per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $redemption = PHPExcel_Calculation_Functions::flattenSingleValue($redemption); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($price) && is_numeric($redemption)) { + if (($price <= 0) || ($redemption <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDDISC() + + + /** + * YIELDMAT + * + * Returns the annual yield of a security that pays interest at maturity. + * + * @param mixed settlement The security's settlement date. + * The security's settlement date is the date after the issue date when the security is traded to the buyer. + * @param mixed maturity The security's maturity date. + * The maturity date is the date when the security expires. + * @param mixed issue The security's issue date. + * @param int rate The security's interest rate at date of issue. + * @param int price The security's price per $100 face value. + * @param int basis The type of day count to use. + * 0 or omitted US (NASD) 30/360 + * 1 Actual/actual + * 2 Actual/360 + * 3 Actual/365 + * 4 European 30/360 + * @return float + */ + public static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) { + $settlement = PHPExcel_Calculation_Functions::flattenSingleValue($settlement); + $maturity = PHPExcel_Calculation_Functions::flattenSingleValue($maturity); + $issue = PHPExcel_Calculation_Functions::flattenSingleValue($issue); + $rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate); + $price = PHPExcel_Calculation_Functions::flattenSingleValue($price); + $basis = (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis); + + // Validate + if (is_numeric($rate) && is_numeric($price)) { + if (($rate <= 0) || ($price <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis); + if (!is_numeric($daysPerYear)) { + return $daysPerYear; + } + $daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis); + if (!is_numeric($daysBetweenIssueAndSettlement)) { + // return date error + return $daysBetweenIssueAndSettlement; + } + $daysBetweenIssueAndSettlement *= $daysPerYear; + $daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis); + if (!is_numeric($daysBetweenIssueAndMaturity)) { + // return date error + return $daysBetweenIssueAndMaturity; + } + $daysBetweenIssueAndMaturity *= $daysPerYear; + $daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis); + if (!is_numeric($daysBetweenSettlementAndMaturity)) { + // return date error + return $daysBetweenSettlementAndMaturity; + } + $daysBetweenSettlementAndMaturity *= $daysPerYear; + + return ((1 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate) - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) / + (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) * + ($daysPerYear / $daysBetweenSettlementAndMaturity); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function YIELDMAT() + +} // class PHPExcel_Calculation_Financial diff --git a/extend/phpexcel/PHPExcel/Calculation/FormulaParser.php b/extend/phpexcel/PHPExcel/Calculation/FormulaParser.php new file mode 100755 index 0000000..754a638 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/FormulaParser.php @@ -0,0 +1,614 @@ +<"; + const OPERATORS_POSTFIX = "%"; + + /** + * Formula + * + * @var string + */ + private $_formula; + + /** + * Tokens + * + * @var PHPExcel_Calculation_FormulaToken[] + */ + private $_tokens = array(); + + /** + * Create a new PHPExcel_Calculation_FormulaParser + * + * @param string $pFormula Formula to parse + * @throws PHPExcel_Calculation_Exception + */ + public function __construct($pFormula = '') + { + // Check parameters + if (is_null($pFormula)) { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed: formula"); + } + + // Initialise values + $this->_formula = trim($pFormula); + // Parse! + $this->_parseToTokens(); + } + + /** + * Get Formula + * + * @return string + */ + public function getFormula() { + return $this->_formula; + } + + /** + * Get Token + * + * @param int $pId Token id + * @return string + * @throws PHPExcel_Calculation_Exception + */ + public function getToken($pId = 0) { + if (isset($this->_tokens[$pId])) { + return $this->_tokens[$pId]; + } else { + throw new PHPExcel_Calculation_Exception("Token with id $pId does not exist."); + } + } + + /** + * Get Token count + * + * @return string + */ + public function getTokenCount() { + return count($this->_tokens); + } + + /** + * Get Tokens + * + * @return PHPExcel_Calculation_FormulaToken[] + */ + public function getTokens() { + return $this->_tokens; + } + + /** + * Parse to tokens + */ + private function _parseToTokens() { + // No attempt is made to verify formulas; assumes formulas are derived from Excel, where + // they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions. + + // Check if the formula has a valid starting = + $formulaLength = strlen($this->_formula); + if ($formulaLength < 2 || $this->_formula{0} != '=') return; + + // Helper variables + $tokens1 = $tokens2 = $stack = array(); + $inString = $inPath = $inRange = $inError = false; + $token = $previousToken = $nextToken = null; + + $index = 1; + $value = ''; + + $ERRORS = array("#NULL!", "#DIV/0!", "#VALUE!", "#REF!", "#NAME?", "#NUM!", "#N/A"); + $COMPARATORS_MULTI = array(">=", "<=", "<>"); + + while ($index < $formulaLength) { + // state-dependent character evaluation (order is important) + + // double-quoted strings + // embeds are doubled + // end marks token + if ($inString) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE; + ++$index; + } else { + $inString = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT); + $value = ""; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // single-quoted strings (links) + // embeds are double + // end does not mark a token + if ($inPath) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) { + $value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE; + ++$index; + } else { + $inPath = false; + } + } else { + $value .= $this->_formula{$index}; + } + ++$index; + continue; + } + + // bracked strings (R1C1 range index or linked workbook name) + // no embeds (changed to "()" by Excel) + // end does not mark a token + if ($inRange) { + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) { + $inRange = false; + } + $value .= $this->_formula{$index}; + ++$index; + continue; + } + + // error values + // end marks a token, determined from absolute list of values + if ($inError) { + $value .= $this->_formula{$index}; + ++$index; + if (in_array($value, $ERRORS)) { + $inError = false; + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR); + $value = ""; + } + continue; + } + + // scientific notation check + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) { + if (strlen($value) > 1) { + if (preg_match("/^[1-9]{1}(\.[0-9]+)?E{1}$/", $this->_formula{$index}) != 0) { + $value .= $this->_formula{$index}; + ++$index; + continue; + } + } + } + + // independent character evaluation (order not important) + + // establish state-dependent character evaluations + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) { + if (strlen($value > 0)) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inString = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inPath = true; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) { + $inRange = true; + $value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN; + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + $inError = true; + $value .= PHPExcel_Calculation_FormulaParser::ERROR_START; + ++$index; + continue; + } + + // mark start and end of arrays and array rows + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) { + if (strlen($value) > 0) { // unexpected + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN); + $value = ""; + } + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAY", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + $tokens1[] = $tmp; + + $tmp = new PHPExcel_Calculation_FormulaToken("ARRAYROW", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + + ++$index; + continue; + } + + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // trim white-space + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE); + ++$index; + while (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) { + ++$index; + } + continue; + } + + // multi-character comparators + if (($index + 2) <= $formulaLength) { + if (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + $index += 2; + continue; + } + } + + // standard infix operators + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX); + ++$index; + continue; + } + + // standard postfix operators (only one) + if (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + $tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX); + ++$index; + continue; + } + + // start subexpression or function + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) { + if (strlen($value) > 0) { + $tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + $value = ""; + } else { + $tmp = new PHPExcel_Calculation_FormulaToken("", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START); + $tokens1[] = $tmp; + $stack[] = clone $tmp; + } + ++$index; + continue; + } + + // function, subexpression, or array parameters, or operand unions + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $stack[] = $tmp; + + if ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION); + } else { + $tokens1[] = new PHPExcel_Calculation_FormulaToken(",", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT); + } + ++$index; + continue; + } + + // stop subexpression + if ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) { + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + $value = ""; + } + + $tmp = array_pop($stack); + $tmp->setValue(""); + $tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP); + $tokens1[] = $tmp; + + ++$index; + continue; + } + + // token accumulation + $value .= $this->_formula{$index}; + ++$index; + } + + // dump remaining accumulation + if (strlen($value) > 0) { + $tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND); + } + + // move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections + $tokenCount = count($tokens1); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens1[$i]; + if (isset($tokens1[$i - 1])) { + $previousToken = $tokens1[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens1[$i + 1])) { + $nextToken = $tokens1[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) { + $tokens2[] = $token; + continue; + } + + if (is_null($previousToken)) { + continue; + } + + if (! ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + if (is_null($nextToken)) { + continue; + } + + if (! ( + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + (($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) || + ($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) ) { + continue; + } + + $tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION); + } + + // move tokens to final list, switching infix "-" operators to prefix when appropriate, switching infix "+" operators + // to noop when appropriate, identifying operand and infix-operator subtypes, and pulling "@" from function names + $this->_tokens = array(); + + $tokenCount = count($tokens2); + for ($i = 0; $i < $tokenCount; ++$i) { + $token = $tokens2[$i]; + if (isset($tokens2[$i - 1])) { + $previousToken = $tokens2[$i - 1]; + } else { + $previousToken = null; + } + if (isset($tokens2[$i + 1])) { + $nextToken = $tokens2[$i + 1]; + } else { + $nextToken = null; + } + + if (is_null($token)) { + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "-") { + if ($i == 0) { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + $token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == "+") { + if ($i == 0) { + continue; + } else if ( + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + (($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) || + ($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND) + ) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } else { + continue; + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (strpos("<>=", substr($token->getValue(), 0, 1)) !== false) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else if ($token->getValue() == "&") { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + if (!is_numeric($token->getValue())) { + if (strtoupper($token->getValue()) == "TRUE" || strtoupper($token->getValue() == "FALSE")) { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL); + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE); + } + } else { + $token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER); + } + + $this->_tokens[] = $token; + continue; + } + + if ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) { + if (strlen($token->getValue() > 0)) { + if (substr($token->getValue(), 0, 1) == "@") { + $token->setValue(substr($token->getValue(), 1)); + } + } + } + + $this->_tokens[] = $token; + } + } +} diff --git a/extend/phpexcel/PHPExcel/Calculation/FormulaToken.php b/extend/phpexcel/PHPExcel/Calculation/FormulaToken.php new file mode 100755 index 0000000..fd5e2e5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/FormulaToken.php @@ -0,0 +1,176 @@ +_value = $pValue; + $this->_tokenType = $pTokenType; + $this->_tokenSubType = $pTokenSubType; + } + + /** + * Get Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set Value + * + * @param string $value + */ + public function setValue($value) { + $this->_value = $value; + } + + /** + * Get Token Type (represented by TOKEN_TYPE_*) + * + * @return string + */ + public function getTokenType() { + return $this->_tokenType; + } + + /** + * Set Token Type + * + * @param string $value + */ + public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) { + $this->_tokenType = $value; + } + + /** + * Get Token SubType (represented by TOKEN_SUBTYPE_*) + * + * @return string + */ + public function getTokenSubType() { + return $this->_tokenSubType; + } + + /** + * Set Token SubType + * + * @param string $value + */ + public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) { + $this->_tokenSubType = $value; + } +} diff --git a/extend/phpexcel/PHPExcel/Calculation/Function.php b/extend/phpexcel/PHPExcel/Calculation/Function.php new file mode 100755 index 0000000..7299834 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Function.php @@ -0,0 +1,149 @@ +_category = $pCategory; + $this->_excelName = $pExcelName; + $this->_phpExcelName = $pPHPExcelName; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameters passed."); + } + } + + /** + * Get Category (represented by CATEGORY_*) + * + * @return string + */ + public function getCategory() { + return $this->_category; + } + + /** + * Set Category (represented by CATEGORY_*) + * + * @param string $value + * @throws PHPExcel_Calculation_Exception + */ + public function setCategory($value = null) { + if (!is_null($value)) { + $this->_category = $value; + } else { + throw new PHPExcel_Calculation_Exception("Invalid parameter passed."); + } + } + + /** + * Get Excel name + * + * @return string + */ + public function getExcelName() { + return $this->_excelName; + } + + /** + * Set Excel name + * + * @param string $value + */ + public function setExcelName($value) { + $this->_excelName = $value; + } + + /** + * Get PHPExcel name + * + * @return string + */ + public function getPHPExcelName() { + return $this->_phpExcelName; + } + + /** + * Set PHPExcel name + * + * @param string $value + */ + public function setPHPExcelName($value) { + $this->_phpExcelName = $value; + } +} diff --git a/extend/phpexcel/PHPExcel/Calculation/Functions.php b/extend/phpexcel/PHPExcel/Calculation/Functions.php new file mode 100755 index 0000000..59dd75d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Functions.php @@ -0,0 +1,725 @@ + '#NULL!', + 'divisionbyzero' => '#DIV/0!', + 'value' => '#VALUE!', + 'reference' => '#REF!', + 'name' => '#NAME?', + 'num' => '#NUM!', + 'na' => '#N/A', + 'gettingdata' => '#GETTING_DATA' + ); + + + /** + * Set the Compatibility Mode + * + * @access public + * @category Function Configuration + * @param string $compatibilityMode Compatibility Mode + * Permitted values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + * @return boolean (Success or Failure) + */ + public static function setCompatibilityMode($compatibilityMode) { + if (($compatibilityMode == self::COMPATIBILITY_EXCEL) || + ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) || + ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) { + self::$compatibilityMode = $compatibilityMode; + return True; + } + return False; + } // function setCompatibilityMode() + + + /** + * Return the current Compatibility Mode + * + * @access public + * @category Function Configuration + * @return string Compatibility Mode + * Possible Return values are: + * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel' + * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric' + * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc' + */ + public static function getCompatibilityMode() { + return self::$compatibilityMode; + } // function getCompatibilityMode() + + + /** + * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @param string $returnDateType Return Date Format + * Permitted values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + * @return boolean Success or failure + */ + public static function setReturnDateType($returnDateType) { + if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) || + ($returnDateType == self::RETURNDATE_PHP_OBJECT) || + ($returnDateType == self::RETURNDATE_EXCEL)) { + self::$ReturnDateType = $returnDateType; + return True; + } + return False; + } // function setReturnDateType() + + + /** + * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object) + * + * @access public + * @category Function Configuration + * @return string Return Date Format + * Possible Return values are: + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P' + * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O' + * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E' + */ + public static function getReturnDateType() { + return self::$ReturnDateType; + } // function getReturnDateType() + + + /** + * DUMMY + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DUMMY() { + return '#Not Yet Implemented'; + } // function DUMMY() + + + /** + * DIV0 + * + * @access public + * @category Error Returns + * @return string #Not Yet Implemented + */ + public static function DIV0() { + return self::$_errorCodes['divisionbyzero']; + } // function DIV0() + + + /** + * NA + * + * Excel Function: + * =NA() + * + * Returns the error value #N/A + * #N/A is the error value that means "no value is available." + * + * @access public + * @category Logical Functions + * @return string #N/A! + */ + public static function NA() { + return self::$_errorCodes['na']; + } // function NA() + + + /** + * NaN + * + * Returns the error value #NUM! + * + * @access public + * @category Error Returns + * @return string #NUM! + */ + public static function NaN() { + return self::$_errorCodes['num']; + } // function NaN() + + + /** + * NAME + * + * Returns the error value #NAME? + * + * @access public + * @category Error Returns + * @return string #NAME? + */ + public static function NAME() { + return self::$_errorCodes['name']; + } // function NAME() + + + /** + * REF + * + * Returns the error value #REF! + * + * @access public + * @category Error Returns + * @return string #REF! + */ + public static function REF() { + return self::$_errorCodes['reference']; + } // function REF() + + + /** + * NULL + * + * Returns the error value #NULL! + * + * @access public + * @category Error Returns + * @return string #NULL! + */ + public static function NULL() { + return self::$_errorCodes['null']; + } // function NULL() + + + /** + * VALUE + * + * Returns the error value #VALUE! + * + * @access public + * @category Error Returns + * @return string #VALUE! + */ + public static function VALUE() { + return self::$_errorCodes['value']; + } // function VALUE() + + + public static function isMatrixValue($idx) { + return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0)); + } + + + public static function isValue($idx) { + return (substr_count($idx,'.') == 0); + } + + + public static function isCellValue($idx) { + return (substr_count($idx,'.') > 1); + } + + + public static function _ifCondition($condition) { + $condition = PHPExcel_Calculation_Functions::flattenSingleValue($condition); + if (!isset($condition{0})) + $condition = '=""'; + if (!in_array($condition{0},array('>', '<', '='))) { + if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); } + return '='.$condition; + } else { + preg_match('/([<>=]+)(.*)/',$condition,$matches); + list(,$operator,$operand) = $matches; + + if (!is_numeric($operand)) { + $operand = str_replace('"', '""', $operand); + $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); + } + + return $operator.$operand; + } + } // function _ifCondition() + + + /** + * ERROR_TYPE + * + * @param mixed $value Value to check + * @return boolean + */ + public static function ERROR_TYPE($value = '') { + $value = self::flattenSingleValue($value); + + $i = 1; + foreach(self::$_errorCodes as $errorCode) { + if ($value === $errorCode) { + return $i; + } + ++$i; + } + return self::NA(); + } // function ERROR_TYPE() + + + /** + * IS_BLANK + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_BLANK($value = NULL) { + if (!is_null($value)) { + $value = self::flattenSingleValue($value); + } + + return is_null($value); + } // function IS_BLANK() + + + /** + * IS_ERR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERR($value = '') { + $value = self::flattenSingleValue($value); + + return self::IS_ERROR($value) && (!self::IS_NA($value)); + } // function IS_ERR() + + + /** + * IS_ERROR + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ERROR($value = '') { + $value = self::flattenSingleValue($value); + + if (!is_string($value)) + return false; + return in_array($value, array_values(self::$_errorCodes)); + } // function IS_ERROR() + + + /** + * IS_NA + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NA($value = '') { + $value = self::flattenSingleValue($value); + + return ($value === self::NA()); + } // function IS_NA() + + + /** + * IS_EVEN + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_EVEN($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return ($value % 2 == 0); + } // function IS_EVEN() + + + /** + * IS_ODD + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_ODD($value = NULL) { + $value = self::flattenSingleValue($value); + + if ($value === NULL) + return self::NAME(); + if ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value)))) + return self::VALUE(); + return (abs($value) % 2 == 1); + } // function IS_ODD() + + + /** + * IS_NUMBER + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NUMBER($value = NULL) { + $value = self::flattenSingleValue($value); + + if (is_string($value)) { + return False; + } + return is_numeric($value); + } // function IS_NUMBER() + + + /** + * IS_LOGICAL + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_LOGICAL($value = NULL) { + $value = self::flattenSingleValue($value); + + return is_bool($value); + } // function IS_LOGICAL() + + + /** + * IS_TEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_TEXT($value = NULL) { + $value = self::flattenSingleValue($value); + + return (is_string($value) && !self::IS_ERROR($value)); + } // function IS_TEXT() + + + /** + * IS_NONTEXT + * + * @param mixed $value Value to check + * @return boolean + */ + public static function IS_NONTEXT($value = NULL) { + return !self::IS_TEXT($value); + } // function IS_NONTEXT() + + + /** + * VERSION + * + * @return string Version information + */ + public static function VERSION() { + return 'PHPExcel 1.8.0, 2014-03-02'; + } // function VERSION() + + + /** + * N + * + * Returns a value converted to a number + * + * @param value The value you want converted + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number That number + * A date The serial number of that date + * TRUE 1 + * FALSE 0 + * An error value The error value + * Anything else 0 + */ + public static function N($value = NULL) { + while (is_array($value)) { + $value = array_shift($value); + } + + switch (gettype($value)) { + case 'double' : + case 'float' : + case 'integer' : + return $value; + break; + case 'boolean' : + return (integer) $value; + break; + case 'string' : + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return $value; + } + break; + } + return 0; + } // function N() + + + /** + * TYPE + * + * Returns a number that identifies the type of a value + * + * @param value The value you want tested + * @return number N converts values listed in the following table + * If value is or refers to N returns + * A number 1 + * Text 2 + * Logical Value 4 + * An error value 16 + * Array or Matrix 64 + */ + public static function TYPE($value = NULL) { + $value = self::flattenArrayIndexed($value); + if (is_array($value) && (count($value) > 1)) { + $a = array_keys($value); + $a = array_pop($a); + // Range of cells is an error + if (self::isCellValue($a)) { + return 16; + // Test for Matrix + } elseif (self::isMatrixValue($a)) { + return 64; + } + } elseif(empty($value)) { + // Empty Cell + return 1; + } + $value = self::flattenSingleValue($value); + + if (($value === NULL) || (is_float($value)) || (is_int($value))) { + return 1; + } elseif(is_bool($value)) { + return 4; + } elseif(is_array($value)) { + return 64; + } elseif(is_string($value)) { + // Errors + if ((strlen($value) > 0) && ($value{0} == '#')) { + return 16; + } + return 2; + } + return 0; + } // function TYPE() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArray($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $value) { + if (is_array($value)) { + foreach ($value as $val) { + if (is_array($val)) { + foreach ($val as $v) { + $arrayValues[] = $v; + } + } else { + $arrayValues[] = $val; + } + } + } else { + $arrayValues[] = $value; + } + } + + return $arrayValues; + } // function flattenArray() + + + /** + * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing + * + * @param array $array Array to be flattened + * @return array Flattened array + */ + public static function flattenArrayIndexed($array) { + if (!is_array($array)) { + return (array) $array; + } + + $arrayValues = array(); + foreach ($array as $k1 => $value) { + if (is_array($value)) { + foreach ($value as $k2 => $val) { + if (is_array($val)) { + foreach ($val as $k3 => $v) { + $arrayValues[$k1.'.'.$k2.'.'.$k3] = $v; + } + } else { + $arrayValues[$k1.'.'.$k2] = $val; + } + } + } else { + $arrayValues[$k1] = $value; + } + } + + return $arrayValues; + } // function flattenArrayIndexed() + + + /** + * Convert an array to a single scalar value by extracting the first element + * + * @param mixed $value Array or scalar value + * @return mixed + */ + public static function flattenSingleValue($value = '') { + while (is_array($value)) { + $value = array_pop($value); + } + + return $value; + } // function flattenSingleValue() + +} // class PHPExcel_Calculation_Functions + + +// +// There are a few mathematical functions that aren't available on all versions of PHP for all platforms +// These functions aren't available in Windows implementations of PHP prior to version 5.3.0 +// So we test if they do exist for this version of PHP/operating platform; and if not we create them +// +if (!function_exists('acosh')) { + function acosh($x) { + return 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2)); + } // function acosh() +} + +if (!function_exists('asinh')) { + function asinh($x) { + return log($x + sqrt(1 + $x * $x)); + } // function asinh() +} + +if (!function_exists('atanh')) { + function atanh($x) { + return (log(1 + $x) - log(1 - $x)) / 2; + } // function atanh() +} + + +// +// Strangely, PHP doesn't have a mb_str_replace multibyte function +// As we'll only ever use this function with UTF-8 characters, we can simply "hard-code" the character set +// +if ((!function_exists('mb_str_replace')) && + (function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) { + function mb_str_replace($search, $replace, $subject) { + if(is_array($subject)) { + $ret = array(); + foreach($subject as $key => $val) { + $ret[$key] = mb_str_replace($search, $replace, $val); + } + return $ret; + } + + foreach((array) $search as $key => $s) { + if($s == '') { + continue; + } + $r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : ''); + $pos = mb_strpos($subject, $s, 0, 'UTF-8'); + while($pos !== false) { + $subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8'); + $pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8'); + } + } + return $subject; + } +} diff --git a/extend/phpexcel/PHPExcel/Calculation/Logical.php b/extend/phpexcel/PHPExcel/Calculation/Logical.php new file mode 100755 index 0000000..bb206a1 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Logical.php @@ -0,0 +1,288 @@ + $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue && $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue && ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue && ($arg != 0); + } + } + + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_AND() + + + /** + * LOGICAL_OR + * + * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE. + * + * Excel Function: + * =OR(logical1[,logical2[, ...]]) + * + * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays + * or references that contain logical values. + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $arg,... Data values + * @return boolean The logical OR of the arguments. + */ + public static function LOGICAL_OR() { + // Return value + $returnValue = FALSE; + + // Loop through the arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $argCount = -1; + foreach ($aArgs as $argCount => $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue = $returnValue || $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue = $returnValue || ($arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) { + $arg = TRUE; + } elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) { + $arg = FALSE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $returnValue = $returnValue || ($arg != 0); + } + } + + // Return + if ($argCount < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + return $returnValue; + } // function LOGICAL_OR() + + + /** + * NOT + * + * Returns the boolean inverse of the argument. + * + * Excel Function: + * =NOT(logical) + * + * The argument must evaluate to a logical value such as TRUE or FALSE + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @access public + * @category Logical Functions + * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE + * @return boolean The boolean inverse of the argument. + */ + public static function NOT($logical=FALSE) { + $logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical); + if (is_string($logical)) { + $logical = strtoupper($logical); + if (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) { + return FALSE; + } elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) { + return TRUE; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + + return !$logical; + } // function NOT() + + /** + * STATEMENT_IF + * + * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE. + * + * Excel Function: + * =IF(condition[,returnIfTrue[,returnIfFalse]]) + * + * Condition is any value or expression that can be evaluated to TRUE or FALSE. + * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100, + * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE. + * This argument can use any comparison calculation operator. + * ReturnIfTrue is the value that is returned if condition evaluates to TRUE. + * For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE, + * then the IF function returns the text "Within budget" + * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use + * the logical value TRUE for this argument. + * ReturnIfTrue can be another formula. + * ReturnIfFalse is the value that is returned if condition evaluates to FALSE. + * For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE, + * then the IF function returns the text "Over budget". + * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned. + * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned. + * ReturnIfFalse can be another formula. + * + * @access public + * @category Logical Functions + * @param mixed $condition Condition to evaluate + * @param mixed $returnIfTrue Value to return when condition is true + * @param mixed $returnIfFalse Optional value to return when condition is false + * @return mixed The value of returnIfTrue or returnIfFalse determined by condition + */ + public static function STATEMENT_IF($condition = TRUE, $returnIfTrue = 0, $returnIfFalse = FALSE) { + $condition = (is_null($condition)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition); + $returnIfTrue = (is_null($returnIfTrue)) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue); + $returnIfFalse = (is_null($returnIfFalse)) ? FALSE : PHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse); + + return ($condition) ? $returnIfTrue : $returnIfFalse; + } // function STATEMENT_IF() + + + /** + * IFERROR + * + * Excel Function: + * =IFERROR(testValue,errorpart) + * + * @access public + * @category Logical Functions + * @param mixed $testValue Value to check, is also the value returned when no error + * @param mixed $errorpart Value to return when testValue is an error condition + * @return mixed The value of errorpart or testValue determined by error condition + */ + public static function IFERROR($testValue = '', $errorpart = '') { + $testValue = (is_null($testValue)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + $errorpart = (is_null($errorpart)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($errorpart); + + return self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue); + } // function IFERROR() + +} // class PHPExcel_Calculation_Logical diff --git a/extend/phpexcel/PHPExcel/Calculation/LookupRef.php b/extend/phpexcel/PHPExcel/Calculation/LookupRef.php new file mode 100755 index 0000000..e1285d9 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/LookupRef.php @@ -0,0 +1,881 @@ + '') { + if (strpos($sheetText,' ') !== False) { $sheetText = "'".$sheetText."'"; } + $sheetText .='!'; + } + if ((!is_bool($referenceStyle)) || $referenceStyle) { + $rowRelative = $columnRelative = '$'; + $column = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; } + if (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; } + return $sheetText.$columnRelative.$column.$rowRelative.$row; + } else { + if (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; } + if (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; } + return $sheetText.'R'.$row.'C'.$column; + } + } // function CELL_ADDRESS() + + + /** + * COLUMN + * + * Returns the column number of the given cell reference + * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the COLUMN function appears; otherwise this function returns 0. + * + * Excel Function: + * =COLUMN([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the column numbers + * @return integer or array of integer + */ + public static function COLUMN($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $value) { + $columnKey = preg_replace('/[^a-z]/i','',$columnKey); + return (integer) PHPExcel_Cell::columnIndexFromString($columnKey); + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^a-z]/i','',$startAddress); + $endAddress = preg_replace('/[^a-z]/i','',$endAddress); + $returnValue = array(); + do { + $returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress); + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + $cellAddress = preg_replace('/[^a-z]/i','',$cellAddress); + return (integer) PHPExcel_Cell::columnIndexFromString($cellAddress); + } + } + } // function COLUMN() + + + /** + * COLUMNS + * + * Returns the number of columns in an array or reference. + * + * Excel Function: + * =COLUMNS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns + * @return integer The number of columns in cellAddress + */ + public static function COLUMNS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $x = array_keys($cellAddress); + $x = array_shift($x); + $isMatrix = (is_numeric($x)); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $rows; + } else { + return $columns; + } + } // function COLUMNS() + + + /** + * ROW + * + * Returns the row number of the given cell reference + * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array. + * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the + * reference of the cell in which the ROW function appears; otherwise this function returns 0. + * + * Excel Function: + * =ROW([cellAddress]) + * + * @param cellAddress A reference to a range of cells for which you want the row numbers + * @return integer or array of integer + */ + public static function ROW($cellAddress=Null) { + if (is_null($cellAddress) || trim($cellAddress) === '') { return 0; } + + if (is_array($cellAddress)) { + foreach($cellAddress as $columnKey => $rowValue) { + foreach($rowValue as $rowKey => $cellValue) { + return (integer) preg_replace('/[^0-9]/i','',$rowKey); + } + } + } else { + if (strpos($cellAddress,'!') !== false) { + list($sheet,$cellAddress) = explode('!',$cellAddress); + } + if (strpos($cellAddress,':') !== false) { + list($startAddress,$endAddress) = explode(':',$cellAddress); + $startAddress = preg_replace('/[^0-9]/','',$startAddress); + $endAddress = preg_replace('/[^0-9]/','',$endAddress); + $returnValue = array(); + do { + $returnValue[][] = (integer) $startAddress; + } while ($startAddress++ != $endAddress); + return $returnValue; + } else { + list($cellAddress) = explode(':',$cellAddress); + return (integer) preg_replace('/[^0-9]/','',$cellAddress); + } + } + } // function ROW() + + + /** + * ROWS + * + * Returns the number of rows in an array or reference. + * + * Excel Function: + * =ROWS(cellAddress) + * + * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows + * @return integer The number of rows in cellAddress + */ + public static function ROWS($cellAddress=Null) { + if (is_null($cellAddress) || $cellAddress === '') { + return 1; + } elseif (!is_array($cellAddress)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + $i = array_keys($cellAddress); + $isMatrix = (is_numeric(array_shift($i))); + list($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress); + + if ($isMatrix) { + return $columns; + } else { + return $rows; + } + } // function ROWS() + + + /** + * HYPERLINK + * + * Excel Function: + * =HYPERLINK(linkURL,displayName) + * + * @access public + * @category Logical Functions + * @param string $linkURL Value to check, is also the value returned when no error + * @param string $displayName Value to return when testValue is an error condition + * @param PHPExcel_Cell $pCell The cell to set the hyperlink in + * @return mixed The value of $displayName (or $linkURL if $displayName was blank) + */ + public static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) { + $args = func_get_args(); + $pCell = array_pop($args); + + $linkURL = (is_null($linkURL)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($linkURL); + $displayName = (is_null($displayName)) ? '' : PHPExcel_Calculation_Functions::flattenSingleValue($displayName); + + if ((!is_object($pCell)) || (trim($linkURL) == '')) { + return PHPExcel_Calculation_Functions::REF(); + } + + if ((is_object($displayName)) || trim($displayName) == '') { + $displayName = $linkURL; + } + + $pCell->getHyperlink()->setUrl($linkURL); + + return $displayName; + } // function HYPERLINK() + + + /** + * INDIRECT + * + * Returns the reference specified by a text string. + * References are immediately evaluated to display their contents. + * + * Excel Function: + * =INDIRECT(cellAddress) + * + * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010 + * + * @param cellAddress $cellAddress The cell address of the current cell (containing this formula) + * @param PHPExcel_Cell $pCell The current cell (containing this formula) + * @return mixed The cells referenced by cellAddress + * + * @todo Support for the optional a1 parameter introduced in Excel 2010 + * + */ + public static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) { + $cellAddress = PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress); + if (is_null($cellAddress) || $cellAddress === '') { + return PHPExcel_Calculation_Functions::REF(); + } + + $cellAddress1 = $cellAddress; + $cellAddress2 = NULL; + if (strpos($cellAddress,':') !== false) { + list($cellAddress1,$cellAddress2) = explode(':',$cellAddress); + } + + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) || + ((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) { + if (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) { + return PHPExcel_Calculation_Functions::REF(); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName, $cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE); + } + + if (strpos($cellAddress,'!') !== FALSE) { + list($sheetName,$cellAddress) = explode('!',$cellAddress); + $sheetName = trim($sheetName, "'"); + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE); + } // function INDIRECT() + + + /** + * OFFSET + * + * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells. + * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and + * the number of columns to be returned. + * + * Excel Function: + * =OFFSET(cellAddress, rows, cols, [height], [width]) + * + * @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or + * range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value. + * @param rows The number of rows, up or down, that you want the upper-left cell to refer to. + * Using 5 as the rows argument specifies that the upper-left cell in the reference is + * five rows below reference. Rows can be positive (which means below the starting reference) + * or negative (which means above the starting reference). + * @param cols The number of columns, to the left or right, that you want the upper-left cell of the result + * to refer to. Using 5 as the cols argument specifies that the upper-left cell in the + * reference is five columns to the right of reference. Cols can be positive (which means + * to the right of the starting reference) or negative (which means to the left of the + * starting reference). + * @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number. + * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number. + * @return string A reference to a cell or range of cells + */ + public static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) { + $rows = PHPExcel_Calculation_Functions::flattenSingleValue($rows); + $columns = PHPExcel_Calculation_Functions::flattenSingleValue($columns); + $height = PHPExcel_Calculation_Functions::flattenSingleValue($height); + $width = PHPExcel_Calculation_Functions::flattenSingleValue($width); + if ($cellAddress == Null) { + return 0; + } + + $args = func_get_args(); + $pCell = array_pop($args); + if (!is_object($pCell)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $sheetName = NULL; + if (strpos($cellAddress,"!")) { + list($sheetName,$cellAddress) = explode("!",$cellAddress); + $sheetName = trim($sheetName, "'"); + } + if (strpos($cellAddress,":")) { + list($startCell,$endCell) = explode(":",$cellAddress); + } else { + $startCell = $endCell = $cellAddress; + } + list($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell); + list($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell); + + $startCellRow += $rows; + $startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1; + $startCellColumn += $columns; + + if (($startCellRow <= 0) || ($startCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1; + if (($width != null) && (!is_object($width))) { + $endCellColumn = $startCellColumn + $width - 1; + } else { + $endCellColumn += $columns; + } + $startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn); + + if (($height != null) && (!is_object($height))) { + $endCellRow = $startCellRow + $height - 1; + } else { + $endCellRow += $rows; + } + + if (($endCellRow <= 0) || ($endCellColumn < 0)) { + return PHPExcel_Calculation_Functions::REF(); + } + $endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn); + + $cellAddress = $startCellColumn.$startCellRow; + if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) { + $cellAddress .= ':'.$endCellColumn.$endCellRow; + } + + if ($sheetName !== NULL) { + $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName); + } else { + $pSheet = $pCell->getWorksheet(); + } + + return PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False); + } // function OFFSET() + + + /** + * CHOOSE + * + * Uses lookup_value to return a value from the list of value arguments. + * Use CHOOSE to select one of up to 254 values based on the lookup_value. + * + * Excel Function: + * =CHOOSE(index_num, value1, [value2], ...) + * + * @param index_num Specifies which value argument is selected. + * Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number + * between 1 and 254. + * @param value1... Value1 is required, subsequent values are optional. + * Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on + * index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or + * text. + * @return mixed The selected value + */ + public static function CHOOSE() { + $chooseArgs = func_get_args(); + $chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs)); + $entryCount = count($chooseArgs) - 1; + + if(is_array($chosenEntry)) { + $chosenEntry = array_shift($chosenEntry); + } + if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) { + --$chosenEntry; + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + $chosenEntry = floor($chosenEntry); + if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_array($chooseArgs[$chosenEntry])) { + return PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]); + } else { + return $chooseArgs[$chosenEntry]; + } + } // function CHOOSE() + + + /** + * MATCH + * + * The MATCH function searches for a specified item in a range of cells + * + * Excel Function: + * =MATCH(lookup_value, lookup_array, [match_type]) + * + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param match_type The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered. + * @return integer The relative position of the found item + */ + public static function MATCH($lookup_value, $lookup_array, $match_type=1) { + $lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array); + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $match_type = (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type); + // MATCH is not case sensitive + $lookup_value = strtolower($lookup_value); + + // lookup_value type has to be number, text, or logical values + if ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) { + return PHPExcel_Calculation_Functions::NA(); + } + + // match_type is 0, 1 or -1 + if (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should not be empty + $lookupArraySize = count($lookup_array); + if ($lookupArraySize <= 0) { + return PHPExcel_Calculation_Functions::NA(); + } + + // lookup_array should contain only number, text, or logical values, or empty (null) cells + foreach($lookup_array as $i => $lookupArrayValue) { + // check the type of the value + if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) && + (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) { + return PHPExcel_Calculation_Functions::NA(); + } + // convert strings to lowercase for case-insensitive testing + if (is_string($lookupArrayValue)) { + $lookup_array[$i] = strtolower($lookupArrayValue); + } + if ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) { + $lookup_array = array_slice($lookup_array,0,$i-1); + } + } + + // if match_type is 1 or -1, the list has to be ordered + if ($match_type == 1) { + asort($lookup_array); + $keySet = array_keys($lookup_array); + } elseif($match_type == -1) { + arsort($lookup_array); + $keySet = array_keys($lookup_array); + } + + // ** + // find the match + // ** + // loop on the cells +// var_dump($lookup_array); +// echo '
'; + foreach($lookup_array as $i => $lookupArrayValue) { + if (($match_type == 0) && ($lookupArrayValue == $lookup_value)) { + // exact match + return ++$i; + } elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
'; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
'; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
'; + // if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready smaller than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) { +// echo '$i = '.$i.' => '; +// var_dump($lookupArrayValue); +// echo '
'; +// echo 'Keyset = '; +// var_dump($keySet); +// echo '
'; + $i = array_search($i,$keySet); +// echo '$i='.$i.'
'; + // if match_type is 1 <=> find the largest value that is less than or equal to lookup_value + if ($i < 1){ + // 1st cell was allready bigger than the lookup_value + break; + } else { + // the previous cell was the match + return $keySet[$i-1]+1; + } + } + } + + // unsuccessful in finding a match, return #N/A error value + return PHPExcel_Calculation_Functions::NA(); + } // function MATCH() + + + /** + * INDEX + * + * Uses an index to choose a value from a reference or array + * + * Excel Function: + * =INDEX(range_array, row_num, [column_num]) + * + * @param range_array A range of cells or an array constant + * @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required. + * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required. + * @return mixed the value of a specified cell or array of cells + */ + public static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) { + + if (($rowNum < 0) || ($columnNum < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!is_array($arrayValues)) { + return PHPExcel_Calculation_Functions::REF(); + } + + $rowKeys = array_keys($arrayValues); + $columnKeys = @array_keys($arrayValues[$rowKeys[0]]); + + if ($columnNum > count($columnKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($columnNum == 0) { + if ($rowNum == 0) { + return $arrayValues; + } + $rowNum = $rowKeys[--$rowNum]; + $returnArray = array(); + foreach($arrayValues as $arrayColumn) { + if (is_array($arrayColumn)) { + if (isset($arrayColumn[$rowNum])) { + $returnArray[] = $arrayColumn[$rowNum]; + } else { + return $arrayValues[$rowNum]; + } + } else { + return $arrayValues[$rowNum]; + } + } + return $returnArray; + } + $columnNum = $columnKeys[--$columnNum]; + if ($rowNum > count($rowKeys)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($rowNum == 0) { + return $arrayValues[$columnNum]; + } + $rowNum = $rowKeys[--$rowNum]; + + return $arrayValues[$rowNum][$columnNum]; + } // function INDEX() + + + /** + * TRANSPOSE + * + * @param array $matrixData A matrix of values + * @return array + * + * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix. + */ + public static function TRANSPOSE($matrixData) { + $returnMatrix = array(); + if (!is_array($matrixData)) { $matrixData = array(array($matrixData)); } + + $column = 0; + foreach($matrixData as $matrixRow) { + $row = 0; + foreach($matrixRow as $matrixCell) { + $returnMatrix[$row][$column] = $matrixCell; + ++$row; + } + ++$column; + } + return $returnMatrix; + } // function TRANSPOSE() + + + private static function _vlookupSort($a,$b) { + $f = array_keys($a); + $firstColumn = array_shift($f); + if (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) { + return 0; + } + return (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1; + } // function _vlookupSort() + + + /** + * VLOOKUP + * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $returnColumn = $columnKeys[--$index_number]; + $firstColumn = array_shift($columnKeys); + } + } + + if (!$not_exact_match) { + uasort($lookup_array,array('self','_vlookupSort')); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData[$firstColumn]; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + $result = $lookup_array[$rowNumber][$returnColumn]; + if ((is_numeric($lookup_value) && is_numeric($result)) || + (!is_numeric($lookup_value) && !is_numeric($result))) { + return $result; + } + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function VLOOKUP() + + +/** + * HLOOKUP + * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_array The range of cells being searched + * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1. + * @param not_exact_match Determines if you are looking for an exact match based on lookup_value. + * @return mixed The value of the found cell + */ + public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + $index_number = PHPExcel_Calculation_Functions::flattenSingleValue($index_number); + $not_exact_match = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match); + + // index_number must be greater than or equal to 1 + if ($index_number < 1) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + // index_number must be less than or equal to the number of columns in lookup_array + if ((!is_array($lookup_array)) || (empty($lookup_array))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $f = array_keys($lookup_array); + $firstRow = array_pop($f); + if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) { + return PHPExcel_Calculation_Functions::REF(); + } else { + $columnKeys = array_keys($lookup_array[$firstRow]); + $firstkey = $f[0] - 1; + $returnColumn = $firstkey + $index_number; + $firstColumn = array_shift($f); + } + } + + if (!$not_exact_match) { + $firstRowH = asort($lookup_array[$firstColumn]); + } + + $rowNumber = $rowValue = False; + foreach($lookup_array[$firstColumn] as $rowKey => $rowData) { + if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) || + (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) { + break; + } + $rowNumber = $rowKey; + $rowValue = $rowData; + } + + if ($rowNumber !== false) { + if ((!$not_exact_match) && ($rowValue != $lookup_value)) { + // if an exact match is required, we have what we need to return an appropriate response + return PHPExcel_Calculation_Functions::NA(); + } else { + // otherwise return the appropriate value + $result = $lookup_array[$returnColumn][$rowNumber]; + return $result; + } + } + + return PHPExcel_Calculation_Functions::NA(); + } // function HLOOKUP() + + + /** + * LOOKUP + * The LOOKUP function searches for value either from a one-row or one-column range or from an array. + * @param lookup_value The value that you want to match in lookup_array + * @param lookup_vector The range of cells being searched + * @param result_vector The column from which the matching value must be returned + * @return mixed The value of the found cell + */ + public static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) { + $lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value); + + if (!is_array($lookup_vector)) { + return PHPExcel_Calculation_Functions::NA(); + } + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $l = array_shift($l); + $lookupColumns = count($lookup_vector[$l]); + if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) { + $lookup_vector = self::TRANSPOSE($lookup_vector); + $lookupRows = count($lookup_vector); + $l = array_keys($lookup_vector); + $lookupColumns = count($lookup_vector[array_shift($l)]); + } + + if (is_null($result_vector)) { + $result_vector = $lookup_vector; + } + $resultRows = count($result_vector); + $l = array_keys($result_vector); + $l = array_shift($l); + $resultColumns = count($result_vector[$l]); + if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) { + $result_vector = self::TRANSPOSE($result_vector); + $resultRows = count($result_vector); + $r = array_keys($result_vector); + $resultColumns = count($result_vector[array_shift($r)]); + } + + if ($lookupRows == 2) { + $result_vector = array_pop($lookup_vector); + $lookup_vector = array_shift($lookup_vector); + } + if ($lookupColumns != 2) { + foreach($lookup_vector as &$value) { + if (is_array($value)) { + $k = array_keys($value); + $key1 = $key2 = array_shift($k); + $key2++; + $dataValue1 = $value[$key1]; + } else { + $key1 = 0; + $key2 = 1; + $dataValue1 = $value; + } + $dataValue2 = array_shift($result_vector); + if (is_array($dataValue2)) { + $dataValue2 = array_shift($dataValue2); + } + $value = array($key1 => $dataValue1, $key2 => $dataValue2); + } + unset($value); + } + + return self::VLOOKUP($lookup_value,$lookup_vector,2); + } // function LOOKUP() + +} // class PHPExcel_Calculation_LookupRef diff --git a/extend/phpexcel/PHPExcel/Calculation/MathTrig.php b/extend/phpexcel/PHPExcel/Calculation/MathTrig.php new file mode 100755 index 0000000..1093055 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/MathTrig.php @@ -0,0 +1,1373 @@ + 1; --$i) { + if (($value % $i) == 0) { + $factorArray = array_merge($factorArray,self::_factors($value / $i)); + $factorArray = array_merge($factorArray,self::_factors($i)); + if ($i <= sqrt($value)) { + break; + } + } + } + if (!empty($factorArray)) { + rsort($factorArray); + return $factorArray; + } else { + return array((integer) $value); + } + } // function _factors() + + + private static function _romanCut($num, $n) { + return ($num - ($num % $n ) ) / $n; + } // function _romanCut() + + + /** + * ATAN2 + * + * This function calculates the arc tangent of the two variables x and y. It is similar to + * calculating the arc tangent of y ÷ x, except that the signs of both arguments are used + * to determine the quadrant of the result. + * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a + * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between + * -pi and pi, excluding -pi. + * + * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard + * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function. + * + * Excel Function: + * ATAN2(xCoordinate,yCoordinate) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $xCoordinate The x-coordinate of the point. + * @param float $yCoordinate The y-coordinate of the point. + * @return float The inverse tangent of the specified x- and y-coordinates. + */ + public static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) { + $xCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate); + $yCoordinate = PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate); + + $xCoordinate = ($xCoordinate !== NULL) ? $xCoordinate : 0.0; + $yCoordinate = ($yCoordinate !== NULL) ? $yCoordinate : 0.0; + + if (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) && + ((is_numeric($yCoordinate))) || (is_bool($yCoordinate))) { + $xCoordinate = (float) $xCoordinate; + $yCoordinate = (float) $yCoordinate; + + if (($xCoordinate == 0) && ($yCoordinate == 0)) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + return atan2($yCoordinate, $xCoordinate); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ATAN2() + + + /** + * CEILING + * + * Returns number rounded up, away from zero, to the nearest multiple of significance. + * For example, if you want to avoid using pennies in your prices and your product is + * priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the + * nearest nickel. + * + * Excel Function: + * CEILING(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The number you want to round. + * @param float $significance The multiple to which you want to round. + * @return float Rounded Number + */ + public static function CEILING($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && + (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } + + if ((is_numeric($number)) && (is_numeric($significance))) { + if ($significance == 0.0) { + return 0.0; + } elseif (self::SIGN($number) == self::SIGN($significance)) { + return ceil($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CEILING() + + + /** + * COMBIN + * + * Returns the number of combinations for a given number of items. Use COMBIN to + * determine the total possible number of groups for a given number of items. + * + * Excel Function: + * COMBIN(numObjs,numInSet) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each combination + * @return int Number of combinations + */ + public static function COMBIN($numObjs, $numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($numInSet < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function COMBIN() + + + /** + * EVEN + * + * Returns number rounded up to the nearest even integer. + * You can use this function for processing items that come in twos. For example, + * a packing crate accepts rows of one or two items. The crate is full when + * the number of items, rounded up to the nearest two, matches the crate's + * capacity. + * + * Excel Function: + * EVEN(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @return int Rounded Number + */ + public static function EVEN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = 2 * self::SIGN($number); + return (int) self::CEILING($number,$significance); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EVEN() + + + /** + * FACT + * + * Returns the factorial of a number. + * The factorial of a number is equal to 1*2*3*...* number. + * + * Excel Function: + * FACT(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Factorial + */ + public static function FACT($factVal) { + $factVal = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factVal)) { + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factLoop = floor($factVal); + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if ($factVal > $factLoop) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACT() + + + /** + * FACTDOUBLE + * + * Returns the double factorial of a number. + * + * Excel Function: + * FACTDOUBLE(factVal) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $factVal Factorial Value + * @return int Double Factorial + */ + public static function FACTDOUBLE($factVal) { + $factLoop = PHPExcel_Calculation_Functions::flattenSingleValue($factVal); + + if (is_numeric($factLoop)) { + $factLoop = floor($factLoop); + if ($factVal < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $factorial = 1; + while ($factLoop > 1) { + $factorial *= $factLoop--; + --$factLoop; + } + return $factorial ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FACTDOUBLE() + + + /** + * FLOOR + * + * Rounds number down, toward zero, to the nearest multiple of significance. + * + * Excel Function: + * FLOOR(number[,significance]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to round + * @param float $significance Significance + * @return float Rounded Number + */ + public static function FLOOR($number, $significance = NULL) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $significance = PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + if ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) { + $significance = $number/abs($number); + } + + if ((is_numeric($number)) && (is_numeric($significance))) { + if ((float) $significance == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + if (self::SIGN($number) == self::SIGN($significance)) { + return floor($number / $significance) * $significance; + } else { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FLOOR() + + + /** + * GCD + * + * Returns the greatest common divisor of a series of numbers. + * The greatest common divisor is the largest integer that divides both + * number1 and number2 without a remainder. + * + * Excel Function: + * GCD(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return integer Greatest Common Divisor + */ + public static function GCD() { + $returnValue = 1; + $allValuesFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ($value == 0) { + continue; + } elseif($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors($value); + $myCountedFactors = array_count_values($myFactors); + $allValuesFactors[] = $myCountedFactors; + } + $allValuesCount = count($allValuesFactors); + if ($allValuesCount == 0) { + return 0; + } + + $mergedArray = $allValuesFactors[0]; + for ($i=1;$i < $allValuesCount; ++$i) { + $mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]); + } + $mergedArrayValues = count($mergedArray); + if ($mergedArrayValues == 0) { + return $returnValue; + } elseif ($mergedArrayValues > 1) { + foreach($mergedArray as $mergedKey => $mergedValue) { + foreach($allValuesFactors as $highestPowerTest) { + foreach($highestPowerTest as $testKey => $testValue) { + if (($testKey == $mergedKey) && ($testValue < $mergedValue)) { + $mergedArray[$mergedKey] = $testValue; + $mergedValue = $testValue; + } + } + } + } + + $returnValue = 1; + foreach($mergedArray as $key => $value) { + $returnValue *= pow($key,$value); + } + return $returnValue; + } else { + $keys = array_keys($mergedArray); + $key = $keys[0]; + $value = $mergedArray[$key]; + foreach($allValuesFactors as $testValue) { + foreach($testValue as $mergedKey => $mergedValue) { + if (($mergedKey == $key) && ($mergedValue < $value)) { + $value = $mergedValue; + } + } + } + return pow($key,$value); + } + } // function GCD() + + + /** + * INT + * + * Casts a floating point value to an integer + * + * Excel Function: + * INT(number) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number Number to cast to an integer + * @return integer Integer value + */ + public static function INT($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 0; + } elseif (is_bool($number)) { + return (int) $number; + } + if (is_numeric($number)) { + return (int) floor($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function INT() + + + /** + * LCM + * + * Returns the lowest common multiplier of a series of numbers + * The least common multiple is the smallest positive integer that is a multiple + * of all integer arguments number1, number2, and so on. Use LCM to add fractions + * with different denominators. + * + * Excel Function: + * LCM(number1[,number2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return int Lowest Common Multiplier + */ + public static function LCM() { + $returnValue = 1; + $allPoweredFactors = array(); + // Loop through arguments + foreach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) { + if (!is_numeric($value)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if ($value == 0) { + return 0; + } elseif ($value < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $myFactors = self::_factors(floor($value)); + $myCountedFactors = array_count_values($myFactors); + $myPoweredFactors = array(); + foreach($myCountedFactors as $myCountedFactor => $myCountedPower) { + $myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower); + } + foreach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) { + if (array_key_exists($myPoweredValue,$allPoweredFactors)) { + if ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } else { + $allPoweredFactors[$myPoweredValue] = $myPoweredFactor; + } + } + } + foreach($allPoweredFactors as $allPoweredFactor) { + $returnValue *= (integer) $allPoweredFactor; + } + return $returnValue; + } // function LCM() + + + /** + * LOG_BASE + * + * Returns the logarithm of a number to a specified base. The default base is 10. + * + * Excel Function: + * LOG(number[,base]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param float $number The positive real number for which you want the logarithm + * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10. + * @return float + */ + public static function LOG_BASE($number = NULL, $base = 10) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $base = (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base); + + if ((!is_numeric($base)) || (!is_numeric($number))) + return PHPExcel_Calculation_Functions::VALUE(); + if (($base <= 0) || ($number <= 0)) + return PHPExcel_Calculation_Functions::NaN(); + return log($number, $base); + } // function LOG_BASE() + + + /** + * MDETERM + * + * Returns the matrix determinant of an array. + * + * Excel Function: + * MDETERM(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return float + */ + public static function MDETERM($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->det(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MDETERM() + + + /** + * MINVERSE + * + * Returns the inverse matrix for the matrix stored in an array. + * + * Excel Function: + * MINVERSE(array) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param array $matrixValues A matrix of values + * @return array + */ + public static function MINVERSE($matrixValues) { + $matrixData = array(); + if (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); } + + $row = $maxColumn = 0; + foreach($matrixValues as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $column = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixData[$column][$row] = $matrixCell; + ++$column; + } + if ($column > $maxColumn) { $maxColumn = $column; } + ++$row; + } + if ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); } + + try { + $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData); + return $matrix->inverse()->getArray(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MINVERSE() + + + /** + * MMULT + * + * @param array $matrixData1 A matrix of values + * @param array $matrixData2 A matrix of values + * @return array + */ + public static function MMULT($matrixData1,$matrixData2) { + $matrixAData = $matrixBData = array(); + if (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); } + if (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); } + + $rowA = 0; + foreach($matrixData1 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnA = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixAData[$rowA][$columnA] = $matrixCell; + ++$columnA; + } + ++$rowA; + } + try { + $matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData); + $rowB = 0; + foreach($matrixData2 as $matrixRow) { + if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); } + $columnB = 0; + foreach($matrixRow as $matrixCell) { + if ((is_string($matrixCell)) || ($matrixCell === null)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $matrixBData[$rowB][$columnB] = $matrixCell; + ++$columnB; + } + ++$rowB; + } + $matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData); + + if (($rowA != $columnB) || ($rowB != $columnA)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + return $matrixA->times($matrixB)->getArray(); + } catch (PHPExcel_Exception $ex) { + return PHPExcel_Calculation_Functions::VALUE(); + } + } // function MMULT() + + + /** + * MOD + * + * @param int $a Dividend + * @param int $b Divisor + * @return int Remainder + */ + public static function MOD($a = 1, $b = 1) { + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ($b == 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } elseif (($a < 0.0) && ($b > 0.0)) { + return $b - fmod(abs($a),$b); + } elseif (($a > 0.0) && ($b < 0.0)) { + return $b + fmod($a,abs($b)); + } + + return fmod($a,$b); + } // function MOD() + + + /** + * MROUND + * + * Rounds a number to the nearest multiple of a specified value + * + * @param float $number Number to round + * @param int $multiple Multiple to which you want to round $number + * @return float Rounded Number + */ + public static function MROUND($number,$multiple) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $multiple = PHPExcel_Calculation_Functions::flattenSingleValue($multiple); + + if ((is_numeric($number)) && (is_numeric($multiple))) { + if ($multiple == 0) { + return 0; + } + if ((self::SIGN($number)) == (self::SIGN($multiple))) { + $multiplier = 1 / $multiple; + return round($number * $multiplier) / $multiplier; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function MROUND() + + + /** + * MULTINOMIAL + * + * Returns the ratio of the factorial of a sum of values to the product of factorials. + * + * @param array of mixed Data Series + * @return float + */ + public static function MULTINOMIAL() { + $summer = 0; + $divisor = 1; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if (is_numeric($arg)) { + if ($arg < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + $summer += floor($arg); + $divisor *= self::FACT($arg); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + + // Return + if ($summer > 0) { + $summer = self::FACT($summer); + return $summer / $divisor; + } + return 0; + } // function MULTINOMIAL() + + + /** + * ODD + * + * Returns number rounded up to the nearest odd integer. + * + * @param float $number Number to round + * @return int Rounded Number + */ + public static function ODD($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_null($number)) { + return 1; + } elseif (is_bool($number)) { + $number = (int) $number; + } + + if (is_numeric($number)) { + $significance = self::SIGN($number); + if ($significance == 0) { + return 1; + } + + $result = self::CEILING($number,$significance); + if ($result == self::EVEN($result)) { + $result += $significance; + } + + return (int) $result; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ODD() + + + /** + * POWER + * + * Computes x raised to the power y. + * + * @param float $x + * @param float $y + * @return float + */ + public static function POWER($x = 0, $y = 2) { + $x = PHPExcel_Calculation_Functions::flattenSingleValue($x); + $y = PHPExcel_Calculation_Functions::flattenSingleValue($y); + + // Validate parameters + if ($x == 0.0 && $y == 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } elseif ($x == 0.0 && $y < 0.0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + // Return + $result = pow($x, $y); + return (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN(); + } // function POWER() + + + /** + * PRODUCT + * + * PRODUCT returns the product of all the values and cells referenced in the argument list. + * + * Excel Function: + * PRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function PRODUCT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue *= $arg; + } + } + } + + // Return + if (is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function PRODUCT() + + + /** + * QUOTIENT + * + * QUOTIENT function returns the integer portion of a division. Numerator is the divided number + * and denominator is the divisor. + * + * Excel Function: + * QUOTIENT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function QUOTIENT() { + // Return value + $returnValue = null; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = ($arg == 0) ? 0 : $arg; + } else { + if (($returnValue == 0) || ($arg == 0)) { + $returnValue = 0; + } else { + $returnValue /= $arg; + } + } + } + } + + // Return + return intval($returnValue); + } // function QUOTIENT() + + + /** + * RAND + * + * @param int $min Minimal value + * @param int $max Maximal value + * @return int Random number + */ + public static function RAND($min = 0, $max = 0) { + $min = PHPExcel_Calculation_Functions::flattenSingleValue($min); + $max = PHPExcel_Calculation_Functions::flattenSingleValue($max); + + if ($min == 0 && $max == 0) { + return (rand(0,10000000)) / 10000000; + } else { + return rand($min, $max); + } + } // function RAND() + + + public static function ROMAN($aValue, $style=0) { + $aValue = PHPExcel_Calculation_Functions::flattenSingleValue($aValue); + $style = (is_null($style)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($style); + if ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $aValue = (integer) $aValue; + if ($aValue == 0) { + return ''; + } + + $mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM'); + $cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'); + $tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'); + $ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'); + + $roman = ''; + while ($aValue > 5999) { + $roman .= 'M'; + $aValue -= 1000; + } + $m = self::_romanCut($aValue, 1000); $aValue %= 1000; + $c = self::_romanCut($aValue, 100); $aValue %= 100; + $t = self::_romanCut($aValue, 10); $aValue %= 10; + + return $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue]; + } // function ROMAN() + + + /** + * ROUNDUP + * + * Rounds a number up to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDUP($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return floor($number * $significance) / $significance; + } else { + return ceil($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDUP() + + + /** + * ROUNDDOWN + * + * Rounds a number down to a specified number of decimal places + * + * @param float $number Number to round + * @param int $digits Number of digits to which you want to round $number + * @return float Rounded Number + */ + public static function ROUNDDOWN($number,$digits) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + if ((is_numeric($number)) && (is_numeric($digits))) { + $significance = pow(10,(int) $digits); + if ($number < 0.0) { + return ceil($number * $significance) / $significance; + } else { + return floor($number * $significance) / $significance; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function ROUNDDOWN() + + + /** + * SERIESSUM + * + * Returns the sum of a power series + * + * @param float $x Input value to the power series + * @param float $n Initial power to which you want to raise $x + * @param float $m Step by which to increase $n for each term in the series + * @param array of mixed Data Series + * @return float + */ + public static function SERIESSUM() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $x = array_shift($aArgs); + $n = array_shift($aArgs); + $m = array_shift($aArgs); + + if ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) { + // Calculate + $i = 0; + foreach($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg * pow($x,$n + ($m * $i++)); + } else { + return PHPExcel_Calculation_Functions::VALUE(); + } + } + // Return + return $returnValue; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SERIESSUM() + + + /** + * SIGN + * + * Determines the sign of a number. Returns 1 if the number is positive, zero (0) + * if the number is 0, and -1 if the number is negative. + * + * @param float $number Number to round + * @return int sign value + */ + public static function SIGN($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_bool($number)) + return (int) $number; + if (is_numeric($number)) { + if ($number == 0.0) { + return 0; + } + return $number / abs($number); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SIGN() + + + /** + * SQRTPI + * + * Returns the square root of (number * pi). + * + * @param float $number Number + * @return float Square Root of Number * Pi + */ + public static function SQRTPI($number) { + $number = PHPExcel_Calculation_Functions::flattenSingleValue($number); + + if (is_numeric($number)) { + if ($number < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return sqrt($number * M_PI) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SQRTPI() + + + /** + * SUBTOTAL + * + * Returns a subtotal in a list or database. + * + * @param int the number 1 to 11 that specifies which function to + * use in calculating subtotals within a list. + * @param array of mixed Data Series + * @return float + */ + public static function SUBTOTAL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $subtotal = array_shift($aArgs); + + if ((is_numeric($subtotal)) && (!is_string($subtotal))) { + switch($subtotal) { + case 1 : + return PHPExcel_Calculation_Statistical::AVERAGE($aArgs); + break; + case 2 : + return PHPExcel_Calculation_Statistical::COUNT($aArgs); + break; + case 3 : + return PHPExcel_Calculation_Statistical::COUNTA($aArgs); + break; + case 4 : + return PHPExcel_Calculation_Statistical::MAX($aArgs); + break; + case 5 : + return PHPExcel_Calculation_Statistical::MIN($aArgs); + break; + case 6 : + return self::PRODUCT($aArgs); + break; + case 7 : + return PHPExcel_Calculation_Statistical::STDEV($aArgs); + break; + case 8 : + return PHPExcel_Calculation_Statistical::STDEVP($aArgs); + break; + case 9 : + return self::SUM($aArgs); + break; + case 10 : + return PHPExcel_Calculation_Statistical::VARFunc($aArgs); + break; + case 11 : + return PHPExcel_Calculation_Statistical::VARP($aArgs); + break; + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SUBTOTAL() + + + /** + * SUM + * + * SUM computes the sum of all the values and cells referenced in the argument list. + * + * Excel Function: + * SUM(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUM() { + // Return value + $returnValue = 0; + + // Loop through the arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += $arg; + } + } + + // Return + return $returnValue; + } // function SUM() + + + /** + * SUMIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * SUMIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be summed. + * @return float + */ + public static function SUMIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { + $arg = str_replace('"', '""', $arg); + $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); + } + + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + $returnValue += $sumArgs[$key]; + } + } + + // Return + return $returnValue; + } // function SUMIF() + + + /** + * SUMPRODUCT + * + * Excel Function: + * SUMPRODUCT(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMPRODUCT() { + $arrayList = func_get_args(); + + $wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList)); + $wrkCellCount = count($wrkArray); + + for ($i=0; $i< $wrkCellCount; ++$i) { + if ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) { + $wrkArray[$i] = 0; + } + } + + foreach($arrayList as $matrixData) { + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData); + $count = count($array2); + if ($wrkCellCount != $count) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + foreach ($array2 as $i => $val) { + if ((!is_numeric($val)) || (is_string($val))) { + $val = 0; + } + $wrkArray[$i] *= $val; + } + } + + return array_sum($wrkArray); + } // function SUMPRODUCT() + + + /** + * SUMSQ + * + * SUMSQ returns the sum of the squares of the arguments + * + * Excel Function: + * SUMSQ(value1[,value2[, ...]]) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function SUMSQ() { + // Return value + $returnValue = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += ($arg * $arg); + } + } + + // Return + return $returnValue; + } // function SUMSQ() + + + /** + * SUMX2MY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2MY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2MY2() + + + /** + * SUMX2PY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMX2PY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]); + } + } + + return $result; + } // function SUMX2PY2() + + + /** + * SUMXMY2 + * + * @param mixed[] $matrixData1 Matrix #1 + * @param mixed[] $matrixData2 Matrix #2 + * @return float + */ + public static function SUMXMY2($matrixData1,$matrixData2) { + $array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1); + $array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2); + $count1 = count($array1); + $count2 = count($array2); + if ($count1 < $count2) { + $count = $count1; + } else { + $count = $count2; + } + + $result = 0; + for ($i = 0; $i < $count; ++$i) { + if (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) && + ((is_numeric($array2[$i])) && (!is_string($array2[$i])))) { + $result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]); + } + } + + return $result; + } // function SUMXMY2() + + + /** + * TRUNC + * + * Truncates value to the number of fractional digits by number_digits. + * + * @param float $value + * @param int $digits + * @return float Truncated value + */ + public static function TRUNC($value = 0, $digits = 0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $digits = PHPExcel_Calculation_Functions::flattenSingleValue($digits); + + // Validate parameters + if ((!is_numeric($value)) || (!is_numeric($digits))) + return PHPExcel_Calculation_Functions::VALUE(); + $digits = floor($digits); + + // Truncate + $adjust = pow(10, $digits); + + if (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10)) + return $value; + + return (intval($value * $adjust)) / $adjust; + } // function TRUNC() + +} // class PHPExcel_Calculation_MathTrig diff --git a/extend/phpexcel/PHPExcel/Calculation/Statistical.php b/extend/phpexcel/PHPExcel/Calculation/Statistical.php new file mode 100755 index 0000000..32b9c78 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Statistical.php @@ -0,0 +1,3651 @@ + $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + foreach($array2 as $key => $value) { + if ((is_bool($value)) || (is_string($value)) || (is_null($value))) { + unset($array1[$key]); + unset($array2[$key]); + } + } + $array1 = array_merge($array1); + $array2 = array_merge($array2); + + return True; + } // function _checkTrendArrays() + + + /** + * Beta function. + * + * @author Jaco van Kooten + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + */ + private static function _beta($p, $q) { + if ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) { + return 0.0; + } else { + return exp(self::_logBeta($p, $q)); + } + } // function _beta() + + + /** + * Incomplete beta function + * + * @author Jaco van Kooten + * @author Paul Meagher + * + * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992). + * @param x require 0<=x<=1 + * @param p require p>0 + * @param q require q>0 + * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow + */ + private static function _incompleteBeta($x, $p, $q) { + if ($x <= 0.0) { + return 0.0; + } elseif ($x >= 1.0) { + return 1.0; + } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + return 0.0; + } + $beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x)); + if ($x < ($p + 1.0) / ($p + $q + 2.0)) { + return $beta_gam * self::_betaFraction($x, $p, $q) / $p; + } else { + return 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q); + } + } // function _incompleteBeta() + + + // Function cache for _logBeta function + private static $_logBetaCache_p = 0.0; + private static $_logBetaCache_q = 0.0; + private static $_logBetaCache_result = 0.0; + + /** + * The natural logarithm of the beta function. + * + * @param p require p>0 + * @param q require q>0 + * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow + * @author Jaco van Kooten + */ + private static function _logBeta($p, $q) { + if ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) { + self::$_logBetaCache_p = $p; + self::$_logBetaCache_q = $q; + if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) { + self::$_logBetaCache_result = 0.0; + } else { + self::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q); + } + } + return self::$_logBetaCache_result; + } // function _logBeta() + + + /** + * Evaluates of continued fraction part of incomplete beta function. + * Based on an idea from Numerical Recipes (W.H. Press et al, 1992). + * @author Jaco van Kooten + */ + private static function _betaFraction($x, $p, $q) { + $c = 1.0; + $sum_pq = $p + $q; + $p_plus = $p + 1.0; + $p_minus = $p - 1.0; + $h = 1.0 - $sum_pq * $x / $p_plus; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $frac = $h; + $m = 1; + $delta = 0.0; + while ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) { + $m2 = 2 * $m; + // even index for d + $d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $frac *= $h * $c; + // odd index for d + $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2)); + $h = 1.0 + $d * $h; + if (abs($h) < XMININ) { + $h = XMININ; + } + $h = 1.0 / $h; + $c = 1.0 + $d / $c; + if (abs($c) < XMININ) { + $c = XMININ; + } + $delta = $h * $c; + $frac *= $delta; + ++$m; + } + return $frac; + } // function _betaFraction() + + + /** + * logGamma function + * + * @version 1.1 + * @author Jaco van Kooten + * + * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher. + * + * The natural logarithm of the gamma function.
+ * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz
+ * Applied Mathematics Division
+ * Argonne National Laboratory
+ * Argonne, IL 60439
+ *

+ * References: + *

    + *
  1. W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural + * Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
  2. + *
  3. K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
  4. + *
  5. Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
  6. + *
+ *

+ *

+ * From the original documentation: + *

+ *

+ * This routine calculates the LOG(GAMMA) function for a positive real argument X. + * Computation is based on an algorithm outlined in references 1 and 2. + * The program uses rational functions that theoretically approximate LOG(GAMMA) + * to at least 18 significant decimal digits. The approximation for X > 12 is from + * reference 3, while approximations for X < 12.0 are similar to those in reference + * 1, but are unpublished. The accuracy achieved depends on the arithmetic system, + * the compiler, the intrinsic functions, and proper selection of the + * machine-dependent constants. + *

+ *

+ * Error returns:
+ * The program returns the value XINF for X .LE. 0.0 or when overflow would occur. + * The computation is believed to be free of underflow and overflow. + *

+ * @return MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305 + */ + + // Function cache for logGamma + private static $_logGammaCache_result = 0.0; + private static $_logGammaCache_x = 0.0; + + private static function _logGamma($x) { + // Log Gamma related constants + static $lg_d1 = -0.5772156649015328605195174; + static $lg_d2 = 0.4227843350984671393993777; + static $lg_d4 = 1.791759469228055000094023; + + static $lg_p1 = array( 4.945235359296727046734888, + 201.8112620856775083915565, + 2290.838373831346393026739, + 11319.67205903380828685045, + 28557.24635671635335736389, + 38484.96228443793359990269, + 26377.48787624195437963534, + 7225.813979700288197698961 ); + static $lg_p2 = array( 4.974607845568932035012064, + 542.4138599891070494101986, + 15506.93864978364947665077, + 184793.2904445632425417223, + 1088204.76946882876749847, + 3338152.967987029735917223, + 5106661.678927352456275255, + 3074109.054850539556250927 ); + static $lg_p4 = array( 14745.02166059939948905062, + 2426813.369486704502836312, + 121475557.4045093227939592, + 2663432449.630976949898078, + 29403789566.34553899906876, + 170266573776.5398868392998, + 492612579337.743088758812, + 560625185622.3951465078242 ); + + static $lg_q1 = array( 67.48212550303777196073036, + 1113.332393857199323513008, + 7738.757056935398733233834, + 27639.87074403340708898585, + 54993.10206226157329794414, + 61611.22180066002127833352, + 36351.27591501940507276287, + 8785.536302431013170870835 ); + static $lg_q2 = array( 183.0328399370592604055942, + 7765.049321445005871323047, + 133190.3827966074194402448, + 1136705.821321969608938755, + 5267964.117437946917577538, + 13467014.54311101692290052, + 17827365.30353274213975932, + 9533095.591844353613395747 ); + static $lg_q4 = array( 2690.530175870899333379843, + 639388.5654300092398984238, + 41355999.30241388052042842, + 1120872109.61614794137657, + 14886137286.78813811542398, + 101680358627.2438228077304, + 341747634550.7377132798597, + 446315818741.9713286462081 ); + + static $lg_c = array( -0.001910444077728, + 8.4171387781295e-4, + -5.952379913043012e-4, + 7.93650793500350248e-4, + -0.002777777777777681622553, + 0.08333333333333333331554247, + 0.0057083835261 ); + + // Rough estimate of the fourth root of logGamma_xBig + static $lg_frtbig = 2.25e76; + static $pnt68 = 0.6796875; + + + if ($x == self::$_logGammaCache_x) { + return self::$_logGammaCache_result; + } + $y = $x; + if ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) { + if ($y <= EPS) { + $res = -log(y); + } elseif ($y <= 1.5) { + // --------------------- + // EPS .LT. X .LE. 1.5 + // --------------------- + if ($y < $pnt68) { + $corr = -log($y); + $xm1 = $y; + } else { + $corr = 0.0; + $xm1 = $y - 1.0; + } + if ($y <= 0.5 || $y >= $pnt68) { + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm1 + $lg_p1[$i]; + $xden = $xden * $xm1 + $lg_q1[$i]; + } + $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden)); + } else { + $xm2 = $y - 1.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } + } elseif ($y <= 4.0) { + // --------------------- + // 1.5 .LT. X .LE. 4.0 + // --------------------- + $xm2 = $y - 2.0; + $xden = 1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm2 + $lg_p2[$i]; + $xden = $xden * $xm2 + $lg_q2[$i]; + } + $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden)); + } elseif ($y <= 12.0) { + // ---------------------- + // 4.0 .LT. X .LE. 12.0 + // ---------------------- + $xm4 = $y - 4.0; + $xden = -1.0; + $xnum = 0.0; + for ($i = 0; $i < 8; ++$i) { + $xnum = $xnum * $xm4 + $lg_p4[$i]; + $xden = $xden * $xm4 + $lg_q4[$i]; + } + $res = $lg_d4 + $xm4 * ($xnum / $xden); + } else { + // --------------------------------- + // Evaluate for argument .GE. 12.0 + // --------------------------------- + $res = 0.0; + if ($y <= $lg_frtbig) { + $res = $lg_c[6]; + $ysq = $y * $y; + for ($i = 0; $i < 6; ++$i) + $res = $res / $ysq + $lg_c[$i]; + } + $res /= $y; + $corr = log($y); + $res = $res + log(SQRT2PI) - 0.5 * $corr; + $res += $y * ($corr - 1.0); + } + } else { + // -------------------------- + // Return for bad arguments + // -------------------------- + $res = MAX_VALUE; + } + // ------------------------------ + // Final adjustments and return + // ------------------------------ + self::$_logGammaCache_x = $x; + self::$_logGammaCache_result = $res; + return $res; + } // function _logGamma() + + + // + // Private implementation of the incomplete Gamma function + // + private static function _incompleteGamma($a,$x) { + static $max = 32; + $summer = 0; + for ($n=0; $n<=$max; ++$n) { + $divisor = $a; + for ($i=1; $i<=$n; ++$i) { + $divisor *= ($a + $i); + } + $summer += (pow($x,$n) / $divisor); + } + return pow($x,$a) * exp(0-$x) * $summer; + } // function _incompleteGamma() + + + // + // Private implementation of the Gamma function + // + private static function _gamma($data) { + if ($data == 0.0) return 0; + + static $p0 = 1.000000000190015; + static $p = array ( 1 => 76.18009172947146, + 2 => -86.50532032941677, + 3 => 24.01409824083091, + 4 => -1.231739572450155, + 5 => 1.208650973866179e-3, + 6 => -5.395239384953e-6 + ); + + $y = $x = $data; + $tmp = $x + 5.5; + $tmp -= ($x + 0.5) * log($tmp); + + $summer = $p0; + for ($j=1;$j<=6;++$j) { + $summer += ($p[$j] / ++$y); + } + return exp(0 - $tmp + log(SQRT2PI * $summer / $x)); + } // function _gamma() + + + /*************************************************************************** + * inverse_ncdf.php + * ------------------- + * begin : Friday, January 16, 2004 + * copyright : (C) 2004 Michael Nickerson + * email : nickersonm@yahoo.com + * + ***************************************************************************/ + private static function _inverse_ncdf($p) { + // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to + // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as + // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html + // I have not checked the accuracy of this implementation. Be aware that PHP + // will truncate the coeficcients to 14 digits. + + // You have permission to use and distribute this function freely for + // whatever purpose you want, but please show common courtesy and give credit + // where credit is due. + + // Input paramater is $p - probability - where 0 < p < 1. + + // Coefficients in rational approximations + static $a = array( 1 => -3.969683028665376e+01, + 2 => 2.209460984245205e+02, + 3 => -2.759285104469687e+02, + 4 => 1.383577518672690e+02, + 5 => -3.066479806614716e+01, + 6 => 2.506628277459239e+00 + ); + + static $b = array( 1 => -5.447609879822406e+01, + 2 => 1.615858368580409e+02, + 3 => -1.556989798598866e+02, + 4 => 6.680131188771972e+01, + 5 => -1.328068155288572e+01 + ); + + static $c = array( 1 => -7.784894002430293e-03, + 2 => -3.223964580411365e-01, + 3 => -2.400758277161838e+00, + 4 => -2.549732539343734e+00, + 5 => 4.374664141464968e+00, + 6 => 2.938163982698783e+00 + ); + + static $d = array( 1 => 7.784695709041462e-03, + 2 => 3.224671290700398e-01, + 3 => 2.445134137142996e+00, + 4 => 3.754408661907416e+00 + ); + + // Define lower and upper region break-points. + $p_low = 0.02425; //Use lower region approx. below this + $p_high = 1 - $p_low; //Use upper region approx. above this + + if (0 < $p && $p < $p_low) { + // Rational approximation for lower region. + $q = sqrt(-2 * log($p)); + return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } elseif ($p_low <= $p && $p <= $p_high) { + // Rational approximation for central region. + $q = $p - 0.5; + $r = $q * $q; + return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q / + ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1); + } elseif ($p_high < $p && $p < 1) { + // Rational approximation for upper region. + $q = sqrt(-2 * log(1 - $p)); + return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) / + (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1); + } + // If 0 < p < 1, return a null value + return PHPExcel_Calculation_Functions::NULL(); + } // function _inverse_ncdf() + + + private static function _inverse_ncdf2($prob) { + // Approximation of inverse standard normal CDF developed by + // B. Moro, "The Full Monte," Risk 8(2), Feb 1995, 57-58. + + $a1 = 2.50662823884; + $a2 = -18.61500062529; + $a3 = 41.39119773534; + $a4 = -25.44106049637; + + $b1 = -8.4735109309; + $b2 = 23.08336743743; + $b3 = -21.06224101826; + $b4 = 3.13082909833; + + $c1 = 0.337475482272615; + $c2 = 0.976169019091719; + $c3 = 0.160797971491821; + $c4 = 2.76438810333863E-02; + $c5 = 3.8405729373609E-03; + $c6 = 3.951896511919E-04; + $c7 = 3.21767881768E-05; + $c8 = 2.888167364E-07; + $c9 = 3.960315187E-07; + + $y = $prob - 0.5; + if (abs($y) < 0.42) { + $z = ($y * $y); + $z = $y * ((($a4 * $z + $a3) * $z + $a2) * $z + $a1) / (((($b4 * $z + $b3) * $z + $b2) * $z + $b1) * $z + 1); + } else { + if ($y > 0) { + $z = log(-log(1 - $prob)); + } else { + $z = log(-log($prob)); + } + $z = $c1 + $z * ($c2 + $z * ($c3 + $z * ($c4 + $z * ($c5 + $z * ($c6 + $z * ($c7 + $z * ($c8 + $z * $c9))))))); + if ($y < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf2() + + + private static function _inverse_ncdf3($p) { + // ALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3. + // Produces the normal deviate Z corresponding to a given lower + // tail area of P; Z is accurate to about 1 part in 10**16. + // + // This is a PHP version of the original FORTRAN code that can + // be found at http://lib.stat.cmu.edu/apstat/ + $split1 = 0.425; + $split2 = 5; + $const1 = 0.180625; + $const2 = 1.6; + + // coefficients for p close to 0.5 + $a0 = 3.3871328727963666080; + $a1 = 1.3314166789178437745E+2; + $a2 = 1.9715909503065514427E+3; + $a3 = 1.3731693765509461125E+4; + $a4 = 4.5921953931549871457E+4; + $a5 = 6.7265770927008700853E+4; + $a6 = 3.3430575583588128105E+4; + $a7 = 2.5090809287301226727E+3; + + $b1 = 4.2313330701600911252E+1; + $b2 = 6.8718700749205790830E+2; + $b3 = 5.3941960214247511077E+3; + $b4 = 2.1213794301586595867E+4; + $b5 = 3.9307895800092710610E+4; + $b6 = 2.8729085735721942674E+4; + $b7 = 5.2264952788528545610E+3; + + // coefficients for p not close to 0, 0.5 or 1. + $c0 = 1.42343711074968357734; + $c1 = 4.63033784615654529590; + $c2 = 5.76949722146069140550; + $c3 = 3.64784832476320460504; + $c4 = 1.27045825245236838258; + $c5 = 2.41780725177450611770E-1; + $c6 = 2.27238449892691845833E-2; + $c7 = 7.74545014278341407640E-4; + + $d1 = 2.05319162663775882187; + $d2 = 1.67638483018380384940; + $d3 = 6.89767334985100004550E-1; + $d4 = 1.48103976427480074590E-1; + $d5 = 1.51986665636164571966E-2; + $d6 = 5.47593808499534494600E-4; + $d7 = 1.05075007164441684324E-9; + + // coefficients for p near 0 or 1. + $e0 = 6.65790464350110377720; + $e1 = 5.46378491116411436990; + $e2 = 1.78482653991729133580; + $e3 = 2.96560571828504891230E-1; + $e4 = 2.65321895265761230930E-2; + $e5 = 1.24266094738807843860E-3; + $e6 = 2.71155556874348757815E-5; + $e7 = 2.01033439929228813265E-7; + + $f1 = 5.99832206555887937690E-1; + $f2 = 1.36929880922735805310E-1; + $f3 = 1.48753612908506148525E-2; + $f4 = 7.86869131145613259100E-4; + $f5 = 1.84631831751005468180E-5; + $f6 = 1.42151175831644588870E-7; + $f7 = 2.04426310338993978564E-15; + + $q = $p - 0.5; + + // computation for p close to 0.5 + if (abs($q) <= split1) { + $R = $const1 - $q * $q; + $z = $q * ((((((($a7 * $R + $a6) * $R + $a5) * $R + $a4) * $R + $a3) * $R + $a2) * $R + $a1) * $R + $a0) / + ((((((($b7 * $R + $b6) * $R + $b5) * $R + $b4) * $R + $b3) * $R + $b2) * $R + $b1) * $R + 1); + } else { + if ($q < 0) { + $R = $p; + } else { + $R = 1 - $p; + } + $R = pow(-log($R),2); + + // computation for p not close to 0, 0.5 or 1. + If ($R <= $split2) { + $R = $R - $const2; + $z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) / + ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1); + } else { + // computation for p near 0 or 1. + $R = $R - $split2; + $z = ((((((($e7 * $R + $e6) * $R + $e5) * $R + $e4) * $R + $e3) * $R + $e2) * $R + $e1) * $R + $e0) / + ((((((($f7 * $R + $f6) * $R + $f5) * $R + $f4) * $R + $f3) * $R + $f2) * $R + $f1) * $R + 1); + } + if ($q < 0) { + $z = -$z; + } + } + return $z; + } // function _inverse_ncdf3() + + + /** + * AVEDEV + * + * Returns the average of the absolute deviations of data points from their mean. + * AVEDEV is a measure of the variability in a data set. + * + * Excel Function: + * AVEDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVEDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = abs($arg - $aMean); + } else { + $returnValue += abs($arg - $aMean); + } + ++$aCount; + } + } + + // Return + if ($aCount == 0) { + return PHPExcel_Calculation_Functions::DIV0(); + } + return $returnValue / $aCount; + } + return PHPExcel_Calculation_Functions::NaN(); + } // function AVEDEV() + + + /** + * AVERAGE + * + * Returns the average (arithmetic mean) of the arguments + * + * Excel Function: + * AVERAGE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGE() { + $returnValue = $aCount = 0; + + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGE() + + + /** + * AVERAGEA + * + * Returns the average of its arguments, including numbers, text, and logical values + * + * Excel Function: + * AVERAGEA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function AVERAGEA() { + // Return value + $returnValue = null; + + $aCount = 0; + // Loop through arguments + foreach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = $arg; + } else { + $returnValue += $arg; + } + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEA() + + + /** + * AVERAGEIF + * + * Returns the average value from a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * AVERAGEIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @param mixed[] $averageArgs Data values + * @return float + */ + public static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $averageArgs = PHPExcel_Calculation_Functions::flattenArray($averageArgs); + if (empty($averageArgs)) { + $averageArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + $aCount = 0; + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + return $returnValue / $aCount; + } else { + return PHPExcel_Calculation_Functions::DIV0(); + } + } // function AVERAGEIF() + + + /** + * BETADIST + * + * Returns the beta distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $value -= $rMin; + $value /= ($rMax - $rMin); + return self::_incompleteBeta($value,$alpha,$beta); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETADIST() + + + /** + * BETAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @param float $rMin Minimum value + * @param float $rMax Maximum value + * @param boolean $cumulative + * @return float + * + */ + public static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + $rMin = PHPExcel_Calculation_Functions::flattenSingleValue($rMin); + $rMax = PHPExcel_Calculation_Functions::flattenSingleValue($rMax); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) { + if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($rMin > $rMax) { + $tmp = $rMin; + $rMin = $rMax; + $rMax = $tmp; + } + $a = 0; + $b = 2; + + $i = 0; + while ((($b - $a) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + $guess = ($a + $b) / 2; + $result = self::BETADIST($guess, $alpha, $beta); + if (($result == $probability) || ($result == 0)) { + $b = $a; + } elseif ($result > $probability) { + $b = $guess; + } else { + $a = $guess; + } + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($rMin + $guess * ($rMax - $rMin),12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BETAINV() + + + /** + * BINOMDIST + * + * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with + * a fixed number of tests or trials, when the outcomes of any trial are only success or failure, + * when trials are independent, and when the probability of success is constant throughout the + * experiment. For example, BINOMDIST can calculate the probability that two of the next three + * babies born are male. + * + * @param float $value Number of successes in trials + * @param float $trials Number of trials + * @param float $probability Probability of success on each trial + * @param boolean $cumulative + * @return float + * + * @todo Cumulative distribution function + * + */ + public static function BINOMDIST($value, $trials, $probability, $cumulative) { + $value = floor(PHPExcel_Calculation_Functions::flattenSingleValue($value)); + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) { + if (($value < 0) || ($value > $trials)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= $value; ++$i) { + $summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i); + } + return $summer; + } else { + return PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function BINOMDIST() + + + /** + * CHIDIST + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIDIST($value, $degrees) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($value)) && (is_numeric($degrees))) { + if ($degrees < 1) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($value < 0) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + return 1; + } + return PHPExcel_Calculation_Functions::NaN(); + } + return 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIDIST() + + + /** + * CHIINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function CHIINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::CHIDIST($x, $degrees); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CHIINV() + + + /** + * CONFIDENCE + * + * Returns the confidence interval for a population mean + * + * @param float $alpha + * @param float $stdDev Standard Deviation + * @param float $size + * @return float + * + */ + public static function CONFIDENCE($alpha,$stdDev,$size) { + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + $size = floor(PHPExcel_Calculation_Functions::flattenSingleValue($size)); + + if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) { + if (($alpha <= 0) || ($alpha >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($stdDev <= 0) || ($size < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CONFIDENCE() + + + /** + * CORREL + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function CORREL($yValues,$xValues=null) { + if ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) { + return PHPExcel_Calculation_Functions::VALUE(); + } + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCorrelation(); + } // function CORREL() + + + /** + * COUNT + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNT(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNT() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNT() + + + /** + * COUNTA + * + * Counts the number of cells that are not empty within the list of arguments + * + * Excel Function: + * COUNTA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTA() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric, boolean or string value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTA() + + + /** + * COUNTBLANK + * + * Counts the number of empty cells within the list of arguments + * + * Excel Function: + * COUNTBLANK(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return int + */ + public static function COUNTBLANK() { + // Return value + $returnValue = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a blank cell? + if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) { + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTBLANK() + + + /** + * COUNTIF + * + * Counts the number of cells that contain numbers within the list of arguments + * + * Excel Function: + * COUNTIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be counted. + * @return int + */ + public static function COUNTIF($aArgs,$condition) { + // Return value + $returnValue = 0; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + // Is it a value within our criteria + ++$returnValue; + } + } + + // Return + return $returnValue; + } // function COUNTIF() + + + /** + * COVAR + * + * Returns covariance, the average of the products of deviations for each data point pair. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function COVAR($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getCovariance(); + } // function COVAR() + + + /** + * CRITBINOM + * + * Returns the smallest value for which the cumulative binomial distribution is greater + * than or equal to a criterion value + * + * See http://support.microsoft.com/kb/828117/ for details of the algorithm used + * + * @param float $trials number of Bernoulli trials + * @param float $probability probability of a success on each trial + * @param float $alpha criterion value + * @return int + * + * @todo Warning. This implementation differs from the algorithm detailed on the MS + * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess + * This eliminates a potential endless loop error, but may have an adverse affect on the + * accuracy of the function (although all my tests have so far returned correct results). + * + */ + public static function CRITBINOM($trials, $probability, $alpha) { + $trials = floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + + if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) { + if ($trials < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($alpha < 0) || ($alpha > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($alpha <= 0.5) { + $t = sqrt(log(1 / ($alpha * $alpha))); + $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t)); + } else { + $t = sqrt(log(1 / pow(1 - $alpha,2))); + $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t); + } + $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability))); + if ($Guess < 0) { + $Guess = 0; + } elseif ($Guess > $trials) { + $Guess = $trials; + } + + $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0; + $EssentiallyZero = 10e-12; + + $m = floor($trials * $probability); + ++$TotalUnscaledProbability; + if ($m == $Guess) { ++$UnscaledPGuess; } + if ($m <= $Guess) { ++$UnscaledCumPGuess; } + + $PreviousValue = 1; + $Done = False; + $k = $m + 1; + while ((!$Done) && ($k <= $trials)) { + $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability)); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + ++$k; + } + + $PreviousValue = 1; + $Done = False; + $k = $m - 1; + while ((!$Done) && ($k >= 0)) { + $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability); + $TotalUnscaledProbability += $CurrentValue; + if ($k == $Guess) { $UnscaledPGuess += $CurrentValue; } + if ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; } + if ($CurrentValue <= $EssentiallyZero) { $Done = True; } + $PreviousValue = $CurrentValue; + --$k; + } + + $PGuess = $UnscaledPGuess / $TotalUnscaledProbability; + $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability; + +// $CumPGuessMinus1 = $CumPGuess - $PGuess; + $CumPGuessMinus1 = $CumPGuess - 1; + + while (True) { + if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) { + return $Guess; + } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) { + $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability); + $CumPGuessMinus1 = $CumPGuess; + $CumPGuess = $CumPGuess + $PGuessPlus1; + $PGuess = $PGuessPlus1; + ++$Guess; + } elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) { + $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability; + $CumPGuess = $CumPGuessMinus1; + $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess; + $PGuess = $PGuessMinus1; + --$Guess; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function CRITBINOM() + + + /** + * DEVSQ + * + * Returns the sum of squares of deviations of data points from their sample mean. + * + * Excel Function: + * DEVSQ(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function DEVSQ() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if ($aMean != PHPExcel_Calculation_Functions::DIV0()) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + // Is it a numeric value? + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (is_null($returnValue)) { + return PHPExcel_Calculation_Functions::NaN(); + } else { + return $returnValue; + } + } + return self::NA(); + } // function DEVSQ() + + + /** + * EXPONDIST + * + * Returns the exponential distribution. Use EXPONDIST to model the time between events, + * such as how long an automated bank teller takes to deliver cash. For example, you can + * use EXPONDIST to determine the probability that the process takes at most 1 minute. + * + * @param float $value Value of the function + * @param float $lambda The parameter value + * @param boolean $cumulative + * @return float + */ + public static function EXPONDIST($value, $lambda, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $lambda = PHPExcel_Calculation_Functions::flattenSingleValue($lambda); + $cumulative = PHPExcel_Calculation_Functions::flattenSingleValue($cumulative); + + if ((is_numeric($value)) && (is_numeric($lambda))) { + if (($value < 0) || ($lambda < 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0-$value*$lambda); + } else { + return $lambda * exp(0-$value*$lambda); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function EXPONDIST() + + + /** + * FISHER + * + * Returns the Fisher transformation at x. This transformation produces a function that + * is normally distributed rather than skewed. Use this function to perform hypothesis + * testing on the correlation coefficient. + * + * @param float $value + * @return float + */ + public static function FISHER($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if (($value <= -1) || ($value >= 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return 0.5 * log((1+$value)/(1-$value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHER() + + + /** + * FISHERINV + * + * Returns the inverse of the Fisher transformation. Use this transformation when + * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then + * FISHERINV(y) = x. + * + * @param float $value + * @return float + */ + public static function FISHERINV($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + return (exp(2 * $value) - 1) / (exp(2 * $value) + 1); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function FISHERINV() + + + /** + * FORECAST + * + * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value. + * + * @param float Value of X for which we want to find Y + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function FORECAST($xValue,$yValues,$xValues) { + $xValue = PHPExcel_Calculation_Functions::flattenSingleValue($xValue); + if (!is_numeric($xValue)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getValueOfYForX($xValue); + } // function FORECAST() + + + /** + * GAMMADIST + * + * Returns the gamma distribution. + * + * @param float $value Value at which you want to evaluate the distribution + * @param float $a Parameter to the distribution + * @param float $b Parameter to the distribution + * @param boolean $cumulative + * @return float + * + */ + public static function GAMMADIST($value,$a,$b,$cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $a = PHPExcel_Calculation_Functions::flattenSingleValue($a); + $b = PHPExcel_Calculation_Functions::flattenSingleValue($b); + + if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) { + if (($value < 0) || ($a <= 0) || ($b <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return self::_incompleteGamma($a,$value / $b) / self::_gamma($a); + } else { + return (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMADIST() + + + /** + * GAMMAINV + * + * Returns the inverse of the beta distribution. + * + * @param float $probability Probability at which you want to evaluate the distribution + * @param float $alpha Parameter to the distribution + * @param float $beta Parameter to the distribution + * @return float + * + */ + public static function GAMMAINV($probability,$alpha,$beta) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $xLo = 0; + $xHi = $alpha * $beta * 5; + + $x = $xNew = 1; + $error = $pdf = 0; + $dx = 1024; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $error = self::GAMMADIST($x, $alpha, $beta, True) - $probability; + if ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + $pdf = self::GAMMADIST($x, $alpha, $beta, False); + // Avoid division by zero + if ($pdf != 0.0) { + $dx = $error / $pdf; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return $x; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMAINV() + + + /** + * GAMMALN + * + * Returns the natural logarithm of the gamma function. + * + * @param float $value + * @return float + */ + public static function GAMMALN($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_numeric($value)) { + if ($value <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return log(self::_gamma($value)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function GAMMALN() + + + /** + * GEOMEAN + * + * Returns the geometric mean of an array or range of positive data. For example, you + * can use GEOMEAN to calculate average growth rate given compound interest with + * variable rates. + * + * Excel Function: + * GEOMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function GEOMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs); + if (is_numeric($aMean) && ($aMean > 0)) { + $aCount = self::COUNT($aArgs) ; + if (self::MIN($aArgs) > 0) { + return pow($aMean, (1 / $aCount)); + } + } + return PHPExcel_Calculation_Functions::NaN(); + } // GEOMEAN() + + + /** + * GROWTH + * + * Returns values along a predicted emponential trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitExponential->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue); + } + + return $returnArray; + } // function GROWTH() + + + /** + * HARMEAN + * + * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the + * arithmetic mean of reciprocals. + * + * Excel Function: + * HARMEAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function HARMEAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + if (self::MIN($aArgs) < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + $aCount = 0; + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ($arg <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (is_null($returnValue)) { + $returnValue = (1 / $arg); + } else { + $returnValue += (1 / $arg); + } + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + return 1 / ($returnValue / $aCount); + } else { + return $returnValue; + } + } // function HARMEAN() + + + /** + * HYPGEOMDIST + * + * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of + * sample successes, given the sample size, population successes, and population size. + * + * @param float $sampleSuccesses Number of successes in the sample + * @param float $sampleNumber Size of the sample + * @param float $populationSuccesses Number of successes in the population + * @param float $populationNumber Population size + * @return float + * + */ + public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { + $sampleSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses)); + $sampleNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber)); + $populationSuccesses = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses)); + $populationNumber = floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber)); + + if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) { + if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) * + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) / + PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function HYPGEOMDIST() + + + /** + * INTERCEPT + * + * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function INTERCEPT($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getIntersect(); + } // function INTERCEPT() + + + /** + * KURT + * + * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness + * or flatness of a distribution compared with the normal distribution. Positive + * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a + * relatively flat distribution. + * + * @param array Data Series + * @return float + */ + public static function KURT() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + if ($stdDev > 0) { + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),4) ; + ++$count; + } + } + } + + // Return + if ($count > 3) { + return $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3))); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function KURT() + + + /** + * LARGE + * + * Returns the nth largest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * LARGE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the largest) in the array or range of data to return + * @return float + * + */ + public static function LARGE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + rsort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LARGE() + + + /** + * LINEST + * + * Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) { + $const = (is_null($const)) ? TRUE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? FALSE : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 0; + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitLinear->getSlope(), + $bestFitLinear->getSlopeSE(), + $bestFitLinear->getGoodnessOfFit(), + $bestFitLinear->getF(), + $bestFitLinear->getSSRegression(), + ), + array( $bestFitLinear->getIntersect(), + $bestFitLinear->getIntersectSE(), + $bestFitLinear->getStdevOfResiduals(), + $bestFitLinear->getDFResiduals(), + $bestFitLinear->getSSResiduals() + ) + ); + } else { + return array( $bestFitLinear->getSlope(), + $bestFitLinear->getIntersect() + ); + } + } // function LINEST() + + + /** + * LOGEST + * + * Calculates an exponential curve that best fits the X and Y data series, + * and then returns an array that describes the line. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @param boolean A logical value specifying whether to return additional regression statistics. + * @return array + */ + public static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) { + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + $stats = (is_null($stats)) ? False : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats); + if (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues))); + + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + foreach($yValues as $value) { + if ($value <= 0.0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return 1; + } + + $bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const); + if ($stats) { + return array( array( $bestFitExponential->getSlope(), + $bestFitExponential->getSlopeSE(), + $bestFitExponential->getGoodnessOfFit(), + $bestFitExponential->getF(), + $bestFitExponential->getSSRegression(), + ), + array( $bestFitExponential->getIntersect(), + $bestFitExponential->getIntersectSE(), + $bestFitExponential->getStdevOfResiduals(), + $bestFitExponential->getDFResiduals(), + $bestFitExponential->getSSResiduals() + ) + ); + } else { + return array( $bestFitExponential->getSlope(), + $bestFitExponential->getIntersect() + ); + } + } // function LOGEST() + + + /** + * LOGINV + * + * Returns the inverse of the normal cumulative distribution + * + * @param float $probability + * @param float $mean + * @param float $stdDev + * @return float + * + * @todo Try implementing P J Acklam's refinement algorithm for greater + * accuracy if I can get my head round the mathematics + * (as described at) http://home.online.no/~pjacklam/notes/invnorm/ + */ + public static function LOGINV($probability, $mean, $stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return exp($mean + $stdDev * self::NORMSINV($probability)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGINV() + + + /** + * LOGNORMDIST + * + * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed + * with parameters mean and standard_dev. + * + * @param float $value + * @param float $mean + * @param float $stdDev + * @return float + */ + public static function LOGNORMDIST($value, $mean, $stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($value <= 0) || ($stdDev <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::NORMSDIST((log($value) - $mean) / $stdDev); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function LOGNORMDIST() + + + /** + * MAX + * + * MAX returns the value of the element of the values passed that has the highest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MAX(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAX() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAX() + + + /** + * MAXA + * + * Returns the greatest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MAXA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MAXA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MAXA() + + + /** + * MAXIF + * + * Counts the maximum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MAXIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MAXIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg > $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MAXIF() + + + /** + * MEDIAN + * + * Returns the median of the given numbers. The median is the number in the middle of a set of numbers. + * + * Excel Function: + * MEDIAN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MEDIAN() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NaN(); + + $mArgs = array(); + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs,SORT_NUMERIC); + $mValueCount = $mValueCount / 2; + if ($mValueCount == floor($mValueCount)) { + $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2; + } else { + $mValueCount == floor($mValueCount); + $returnValue = $mArgs[$mValueCount]; + } + } + + // Return + return $returnValue; + } // function MEDIAN() + + + /** + * MIN + * + * MIN returns the value of the element of the values passed that has the smallest value, + * with negative numbers considered smaller than positive numbers. + * + * Excel Function: + * MIN(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MIN() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MIN() + + + /** + * MINA + * + * Returns the smallest value in a list of arguments, including numbers, text, and logical values + * + * Excel Function: + * MINA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MINA() { + // Return value + $returnValue = null; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + if(is_null($returnValue)) { + return 0; + } + return $returnValue; + } // function MINA() + + + /** + * MINIF + * + * Returns the minimum value within a range of cells that contain numbers within the list of arguments + * + * Excel Function: + * MINIF(value1[,value2[, ...]],condition) + * + * @access public + * @category Mathematical and Trigonometric Functions + * @param mixed $arg,... Data values + * @param string $condition The criteria that defines which cells will be checked. + * @return float + */ + public static function MINIF($aArgs,$condition,$sumArgs = array()) { + // Return value + $returnValue = null; + + $aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs); + $sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs); + if (empty($sumArgs)) { + $sumArgs = $aArgs; + } + $condition = PHPExcel_Calculation_Functions::_ifCondition($condition); + // Loop through arguments + foreach ($aArgs as $key => $arg) { + if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); } + $testCondition = '='.$arg.$condition; + if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) { + if ((is_null($returnValue)) || ($arg < $returnValue)) { + $returnValue = $arg; + } + } + } + + // Return + return $returnValue; + } // function MINIF() + + + // + // Special variant of array_count_values that isn't limited to strings and integers, + // but can work with floating point numbers as values + // + private static function _modeCalc($data) { + $frequencyArray = array(); + foreach($data as $datum) { + $found = False; + foreach($frequencyArray as $key => $value) { + if ((string) $value['value'] == (string) $datum) { + ++$frequencyArray[$key]['frequency']; + $found = True; + break; + } + } + if (!$found) { + $frequencyArray[] = array('value' => $datum, + 'frequency' => 1 ); + } + } + + foreach($frequencyArray as $key => $value) { + $frequencyList[$key] = $value['frequency']; + $valueList[$key] = $value['value']; + } + array_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray); + + if ($frequencyArray[0]['frequency'] == 1) { + return PHPExcel_Calculation_Functions::NA(); + } + return $frequencyArray[0]['value']; + } // function _modeCalc() + + + /** + * MODE + * + * Returns the most frequently occurring, or repetitive, value in an array or range of data + * + * Excel Function: + * MODE(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function MODE() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::NA(); + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + + if (!empty($mArgs)) { + return self::_modeCalc($mArgs); + } + + // Return + return $returnValue; + } // function MODE() + + + /** + * NEGBINOMDIST + * + * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that + * there will be number_f failures before the number_s-th success, when the constant + * probability of a success is probability_s. This function is similar to the binomial + * distribution, except that the number of successes is fixed, and the number of trials is + * variable. Like the binomial, trials are assumed to be independent. + * + * @param float $failures Number of Failures + * @param float $successes Threshold number of Successes + * @param float $probability Probability of success on each trial + * @return float + * + */ + public static function NEGBINOMDIST($failures, $successes, $probability) { + $failures = floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures)); + $successes = floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes)); + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + + if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) { + if (($failures < 0) || ($successes < 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) { + if (($failures + $successes - 1) <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + } + return (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NEGBINOMDIST() + + + /** + * NORMDIST + * + * Returns the normal distribution for the specified mean and standard deviation. This + * function has a very wide range of applications in statistics, including hypothesis + * testing. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @param boolean $cumulative + * @return float + * + */ + public static function NORMDIST($value, $mean, $stdDev, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 0.5 * (1 + PHPExcel_Calculation_Engineering::_erfVal(($value - $mean) / ($stdDev * sqrt(2)))); + } else { + return (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev)))); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMDIST() + + + /** + * NORMINV + * + * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. + * + * @param float $value + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float + * + */ + public static function NORMINV($probability,$mean,$stdDev) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if (($probability < 0) || ($probability > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ($stdDev < 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return (self::_inverse_ncdf($probability) * $stdDev) + $mean; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function NORMINV() + + + /** + * NORMSDIST + * + * Returns the standard normal cumulative distribution function. The distribution has + * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a + * table of standard normal curve areas. + * + * @param float $value + * @return float + */ + public static function NORMSDIST($value) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + return self::NORMDIST($value, 0, 1, True); + } // function NORMSDIST() + + + /** + * NORMSINV + * + * Returns the inverse of the standard normal cumulative distribution + * + * @param float $value + * @return float + */ + public static function NORMSINV($value) { + return self::NORMINV($value, 0, 1); + } // function NORMSINV() + + + /** + * PERCENTILE + * + * Returns the nth percentile of values in a range.. + * + * Excel Function: + * PERCENTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $entry Percentile value in the range 0..1, inclusive. + * @return float + */ + public static function PERCENTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $mValueCount = count($mArgs); + if ($mValueCount > 0) { + sort($mArgs); + $count = self::COUNT($mArgs); + $index = $entry * ($count-1); + $iBase = floor($index); + if ($index == $iBase) { + return $mArgs[$index]; + } else { + $iNext = $iBase + 1; + $iProportion = $index - $iBase; + return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERCENTILE() + + + /** + * PERCENTRANK + * + * Returns the rank of a value in a data set as a percentage of the data set. + * + * @param array of number An array of, or a reference to, a list of numbers. + * @param number The number whose rank you want to find. + * @param number The number of significant digits for the returned percentage value. + * @return float + */ + public static function PERCENTRANK($valueSet,$value,$significance=3) { + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $significance = (is_null($significance)) ? 3 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + sort($valueSet,SORT_NUMERIC); + $valueCount = count($valueSet); + if ($valueCount == 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + + $valueAdjustor = $valueCount - 1; + if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) { + return PHPExcel_Calculation_Functions::NA(); + } + + $pos = array_search($value,$valueSet); + if ($pos === False) { + $pos = 0; + $testValue = $valueSet[0]; + while ($testValue < $value) { + $testValue = $valueSet[++$pos]; + } + --$pos; + $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos])); + } + + return round($pos / $valueAdjustor,$significance); + } // function PERCENTRANK() + + + /** + * PERMUT + * + * Returns the number of permutations for a given number of objects that can be + * selected from number objects. A permutation is any set or subset of objects or + * events where internal order is significant. Permutations are different from + * combinations, for which the internal order is not significant. Use this function + * for lottery-style probability calculations. + * + * @param int $numObjs Number of different objects + * @param int $numInSet Number of objects in each permutation + * @return int Number of permutations + */ + public static function PERMUT($numObjs,$numInSet) { + $numObjs = PHPExcel_Calculation_Functions::flattenSingleValue($numObjs); + $numInSet = PHPExcel_Calculation_Functions::flattenSingleValue($numInSet); + + if ((is_numeric($numObjs)) && (is_numeric($numInSet))) { + $numInSet = floor($numInSet); + if ($numObjs < $numInSet) { + return PHPExcel_Calculation_Functions::NaN(); + } + return round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet)); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function PERMUT() + + + /** + * POISSON + * + * Returns the Poisson distribution. A common application of the Poisson distribution + * is predicting the number of events over a specific time, such as the number of + * cars arriving at a toll plaza in 1 minute. + * + * @param float $value + * @param float $mean Mean Value + * @param boolean $cumulative + * @return float + * + */ + public static function POISSON($value, $mean, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + + if ((is_numeric($value)) && (is_numeric($mean))) { + if (($value <= 0) || ($mean <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + $summer = 0; + for ($i = 0; $i <= floor($value); ++$i) { + $summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i); + } + return exp(0-$mean) * $summer; + } else { + return (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function POISSON() + + + /** + * QUARTILE + * + * Returns the quartile of a data set. + * + * Excel Function: + * QUARTILE(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Quartile value in the range 1..3, inclusive. + * @return float + */ + public static function QUARTILE() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = floor(array_pop($aArgs)); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $entry /= 4; + if (($entry < 0) || ($entry > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + return self::PERCENTILE($aArgs,$entry); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function QUARTILE() + + + /** + * RANK + * + * Returns the rank of a number in a list of numbers. + * + * @param number The number whose rank you want to find. + * @param array of number An array of, or a reference to, a list of numbers. + * @param mixed Order to sort the values in the value set + * @return float + */ + public static function RANK($value,$valueSet,$order=0) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet); + $order = (is_null($order)) ? 0 : (integer) PHPExcel_Calculation_Functions::flattenSingleValue($order); + + foreach($valueSet as $key => $valueEntry) { + if (!is_numeric($valueEntry)) { + unset($valueSet[$key]); + } + } + + if ($order == 0) { + rsort($valueSet,SORT_NUMERIC); + } else { + sort($valueSet,SORT_NUMERIC); + } + $pos = array_search($value,$valueSet); + if ($pos === False) { + return PHPExcel_Calculation_Functions::NA(); + } + + return ++$pos; + } // function RANK() + + + /** + * RSQ + * + * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function RSQ($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getGoodnessOfFit(); + } // function RSQ() + + + /** + * SKEW + * + * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry + * of a distribution around its mean. Positive skewness indicates a distribution with an + * asymmetric tail extending toward more positive values. Negative skewness indicates a + * distribution with an asymmetric tail extending toward more negative values. + * + * @param array Data Series + * @return float + */ + public static function SKEW() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $mean = self::AVERAGE($aArgs); + $stdDev = self::STDEV($aArgs); + + $count = $summer = 0; + // Loop through arguments + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summer += pow((($arg - $mean) / $stdDev),3) ; + ++$count; + } + } + } + + // Return + if ($count > 2) { + return $summer * ($count / (($count-1) * ($count-2))); + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function SKEW() + + + /** + * SLOPE + * + * Returns the slope of the linear regression line through data points in known_y's and known_x's. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function SLOPE($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getSlope(); + } // function SLOPE() + + + /** + * SMALL + * + * Returns the nth smallest value in a data set. You can use this function to + * select a value based on its relative standing. + * + * Excel Function: + * SMALL(value1[,value2[, ...]],entry) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param int $entry Position (ordered from the smallest) in the array or range of data to return + * @return float + */ + public static function SMALL() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $entry = array_pop($aArgs); + + if ((is_numeric($entry)) && (!is_string($entry))) { + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $count = self::COUNT($mArgs); + $entry = floor(--$entry); + if (($entry < 0) || ($entry >= $count) || ($count == 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + sort($mArgs); + return $mArgs[$entry]; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SMALL() + + + /** + * STANDARDIZE + * + * Returns a normalized value from a distribution characterized by mean and standard_dev. + * + * @param float $value Value to normalize + * @param float $mean Mean Value + * @param float $stdDev Standard Deviation + * @return float Standardized value + */ + public static function STANDARDIZE($value,$mean,$stdDev) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $mean = PHPExcel_Calculation_Functions::flattenSingleValue($mean); + $stdDev = PHPExcel_Calculation_Functions::flattenSingleValue($stdDev); + + if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) { + if ($stdDev <= 0) { + return PHPExcel_Calculation_Functions::NaN(); + } + return ($value - $mean) / $stdDev ; + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function STANDARDIZE() + + + /** + * STDEV + * + * Estimates standard deviation based on a sample. The standard deviation is a measure of how + * widely values are dispersed from the average value (the mean). + * + * Excel Function: + * STDEV(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEV() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEV() + + + /** + * STDEVA + * + * Estimates standard deviation based on a sample, including numbers, text, and logical values + * + * Excel Function: + * STDEVA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = -1; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVA() + + + /** + * STDEVP + * + * Calculates standard deviation based on the entire population + * + * Excel Function: + * STDEVP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVP() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGE($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + ((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) { + $arg = (integer) $arg; + } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVP() + + + /** + * STDEVPA + * + * Calculates standard deviation based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * STDEVPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function STDEVPA() { + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + + // Return value + $returnValue = null; + + $aMean = self::AVERAGEA($aArgs); + if (!is_null($aMean)) { + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_bool($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + if (is_null($returnValue)) { + $returnValue = pow(($arg - $aMean),2); + } else { + $returnValue += pow(($arg - $aMean),2); + } + ++$aCount; + } + } + } + + // Return + if (($aCount > 0) && ($returnValue >= 0)) { + return sqrt($returnValue / $aCount); + } + } + return PHPExcel_Calculation_Functions::DIV0(); + } // function STDEVPA() + + + /** + * STEYX + * + * Returns the standard error of the predicted y-value for each x in the regression. + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @return float + */ + public static function STEYX($yValues,$xValues) { + if (!self::_checkTrendArrays($yValues,$xValues)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + $yValueCount = count($yValues); + $xValueCount = count($xValues); + + if (($yValueCount == 0) || ($yValueCount != $xValueCount)) { + return PHPExcel_Calculation_Functions::NA(); + } elseif ($yValueCount == 1) { + return PHPExcel_Calculation_Functions::DIV0(); + } + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues); + return $bestFitLinear->getStdevOfResiduals(); + } // function STEYX() + + + /** + * TDIST + * + * Returns the probability of Student's T distribution. + * + * @param float $value Value for the function + * @param float $degrees degrees of freedom + * @param float $tails number of tails (1 or 2) + * @return float + */ + public static function TDIST($value, $degrees, $tails) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + $tails = floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails)); + + if ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) { + if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) { + return PHPExcel_Calculation_Functions::NaN(); + } + // tdist, which finds the probability that corresponds to a given value + // of t with k degrees of freedom. This algorithm is translated from a + // pascal function on p81 of "Statistical Computing in Pascal" by D + // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd: + // London). The above Pascal algorithm is itself a translation of the + // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer + // Laboratory as reported in (among other places) "Applied Statistics + // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis + // Horwood Ltd.; W. Sussex, England). + $tterm = $degrees; + $ttheta = atan2($value,sqrt($tterm)); + $tc = cos($ttheta); + $ts = sin($ttheta); + $tsum = 0; + + if (($degrees % 2) == 1) { + $ti = 3; + $tterm = $tc; + } else { + $ti = 2; + $tterm = 1; + } + + $tsum = $tterm; + while ($ti < $degrees) { + $tterm *= $tc * $tc * ($ti - 1) / $ti; + $tsum += $tterm; + $ti += 2; + } + $tsum *= $ts; + if (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); } + $tValue = 0.5 * (1 + $tsum); + if ($tails == 1) { + return 1 - abs($tValue); + } else { + return 1 - abs((1 - $tValue) - $tValue); + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TDIST() + + + /** + * TINV + * + * Returns the one-tailed probability of the chi-squared distribution. + * + * @param float $probability Probability for the function + * @param float $degrees degrees of freedom + * @return float + */ + public static function TINV($probability, $degrees) { + $probability = PHPExcel_Calculation_Functions::flattenSingleValue($probability); + $degrees = floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees)); + + if ((is_numeric($probability)) && (is_numeric($degrees))) { + $xLo = 100; + $xHi = 0; + + $x = $xNew = 1; + $dx = 1; + $i = 0; + + while ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) { + // Apply Newton-Raphson step + $result = self::TDIST($x, $degrees, 2); + $error = $result - $probability; + if ($error == 0.0) { + $dx = 0; + } elseif ($error < 0.0) { + $xLo = $x; + } else { + $xHi = $x; + } + // Avoid division by zero + if ($result != 0.0) { + $dx = $error / $result; + $xNew = $x - $dx; + } + // If the NR fails to converge (which for example may be the + // case if the initial guess is too rough) we apply a bisection + // step to determine a more narrow interval around the root. + if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) { + $xNew = ($xLo + $xHi) / 2; + $dx = $xNew - $x; + } + $x = $xNew; + } + if ($i == MAX_ITERATIONS) { + return PHPExcel_Calculation_Functions::NA(); + } + return round($x,12); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TINV() + + + /** + * TREND + * + * Returns values along a linear trend + * + * @param array of mixed Data Series Y + * @param array of mixed Data Series X + * @param array of mixed Values of X for which we want to find Y + * @param boolean A logical value specifying whether to force the intersect to equal 0. + * @return array of float + */ + public static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) { + $yValues = PHPExcel_Calculation_Functions::flattenArray($yValues); + $xValues = PHPExcel_Calculation_Functions::flattenArray($xValues); + $newValues = PHPExcel_Calculation_Functions::flattenArray($newValues); + $const = (is_null($const)) ? True : (boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const); + + $bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const); + if (empty($newValues)) { + $newValues = $bestFitLinear->getXValues(); + } + + $returnArray = array(); + foreach($newValues as $xValue) { + $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue); + } + + return $returnArray; + } // function TREND() + + + /** + * TRIMMEAN + * + * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean + * taken by excluding a percentage of data points from the top and bottom tails + * of a data set. + * + * Excel Function: + * TRIMEAN(value1[,value2[, ...]],$discard) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @param float $discard Percentage to discard + * @return float + */ + public static function TRIMMEAN() { + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + + // Calculate + $percent = array_pop($aArgs); + + if ((is_numeric($percent)) && (!is_string($percent))) { + if (($percent < 0) || ($percent > 1)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $mArgs = array(); + foreach ($aArgs as $arg) { + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $mArgs[] = $arg; + } + } + $discard = floor(self::COUNT($mArgs) * $percent / 2); + sort($mArgs); + for ($i=0; $i < $discard; ++$i) { + array_pop($mArgs); + array_shift($mArgs); + } + return self::AVERAGE($mArgs); + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function TRIMMEAN() + + + /** + * VARFunc + * + * Estimates variance based on a sample. + * + * Excel Function: + * VAR(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARFunc() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARFunc() + + + /** + * VARA + * + * Estimates variance based on a sample, including numbers, text, and logical values + * + * Excel Function: + * VARA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 1) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1)); + } + return $returnValue; + } // function VARA() + + + /** + * VARP + * + * Calculates variance based on the entire population + * + * Excel Function: + * VARP(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARP() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + $aCount = 0; + foreach ($aArgs as $arg) { + if (is_bool($arg)) { $arg = (integer) $arg; } + // Is it a numeric value? + if ((is_numeric($arg)) && (!is_string($arg))) { + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARP() + + + /** + * VARPA + * + * Calculates variance based on the entire population, including numbers, text, and logical values + * + * Excel Function: + * VARPA(value1[,value2[, ...]]) + * + * @access public + * @category Statistical Functions + * @param mixed $arg,... Data values + * @return float + */ + public static function VARPA() { + // Return value + $returnValue = PHPExcel_Calculation_Functions::DIV0(); + + $summerA = $summerB = 0; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()); + $aCount = 0; + foreach ($aArgs as $k => $arg) { + if ((is_string($arg)) && + (PHPExcel_Calculation_Functions::isValue($k))) { + return PHPExcel_Calculation_Functions::VALUE(); + } elseif ((is_string($arg)) && + (!PHPExcel_Calculation_Functions::isMatrixValue($k))) { + } else { + // Is it a numeric value? + if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) { + if (is_bool($arg)) { + $arg = (integer) $arg; + } elseif (is_string($arg)) { + $arg = 0; + } + $summerA += ($arg * $arg); + $summerB += $arg; + ++$aCount; + } + } + } + + // Return + if ($aCount > 0) { + $summerA *= $aCount; + $summerB *= $summerB; + $returnValue = ($summerA - $summerB) / ($aCount * $aCount); + } + return $returnValue; + } // function VARPA() + + + /** + * WEIBULL + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $value + * @param float $alpha Alpha Parameter + * @param float $beta Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function WEIBULL($value, $alpha, $beta, $cumulative) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $alpha = PHPExcel_Calculation_Functions::flattenSingleValue($alpha); + $beta = PHPExcel_Calculation_Functions::flattenSingleValue($beta); + + if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) { + if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) { + return PHPExcel_Calculation_Functions::NaN(); + } + if ((is_numeric($cumulative)) || (is_bool($cumulative))) { + if ($cumulative) { + return 1 - exp(0 - pow($value / $beta,$alpha)); + } else { + return ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha)); + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function WEIBULL() + + + /** + * ZTEST + * + * Returns the Weibull distribution. Use this distribution in reliability + * analysis, such as calculating a device's mean time to failure. + * + * @param float $dataSet + * @param float $m0 Alpha Parameter + * @param float $sigma Beta Parameter + * @param boolean $cumulative + * @return float + * + */ + public static function ZTEST($dataSet, $m0, $sigma = NULL) { + $dataSet = PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet); + $m0 = PHPExcel_Calculation_Functions::flattenSingleValue($m0); + $sigma = PHPExcel_Calculation_Functions::flattenSingleValue($sigma); + + if (is_null($sigma)) { + $sigma = self::STDEV($dataSet); + } + $n = count($dataSet); + + return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n))); + } // function ZTEST() + +} // class PHPExcel_Calculation_Statistical diff --git a/extend/phpexcel/PHPExcel/Calculation/TextData.php b/extend/phpexcel/PHPExcel/Calculation/TextData.php new file mode 100755 index 0000000..d1ba272 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/TextData.php @@ -0,0 +1,590 @@ +=0 && ord($c{0}) <= 127) + return ord($c{0}); + if (ord($c{0}) >= 192 && ord($c{0}) <= 223) + return (ord($c{0})-192)*64 + (ord($c{1})-128); + if (ord($c{0}) >= 224 && ord($c{0}) <= 239) + return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128); + if (ord($c{0}) >= 240 && ord($c{0}) <= 247) + return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128); + if (ord($c{0}) >= 248 && ord($c{0}) <= 251) + return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128); + if (ord($c{0}) >= 252 && ord($c{0}) <= 253) + return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128); + if (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error + return PHPExcel_Calculation_Functions::VALUE(); + return 0; + } // function _uniord() + + /** + * CHARACTER + * + * @param string $character Value + * @return int + */ + public static function CHARACTER($character) { + $character = PHPExcel_Calculation_Functions::flattenSingleValue($character); + + if ((!is_numeric($character)) || ($character < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (function_exists('mb_convert_encoding')) { + return mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES'); + } else { + return chr(intval($character)); + } + } + + + /** + * TRIMNONPRINTABLE + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMNONPRINTABLE($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (self::$_invalidChars == Null) { + self::$_invalidChars = range(chr(0),chr(31)); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return str_replace(self::$_invalidChars,'',trim($stringValue,"\x00..\x1F")); + } + return NULL; + } // function TRIMNONPRINTABLE() + + + /** + * TRIMSPACES + * + * @param mixed $stringValue Value to check + * @return string + */ + public static function TRIMSPACES($stringValue = '') { + $stringValue = PHPExcel_Calculation_Functions::flattenSingleValue($stringValue); + + if (is_bool($stringValue)) { + return ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (is_string($stringValue) || is_numeric($stringValue)) { + return trim(preg_replace('/ +/',' ',trim($stringValue,' '))); + } + return NULL; + } // function TRIMSPACES() + + + /** + * ASCIICODE + * + * @param string $characters Value + * @return int + */ + public static function ASCIICODE($characters) { + if (($characters === NULL) || ($characters === '')) + return PHPExcel_Calculation_Functions::VALUE(); + $characters = PHPExcel_Calculation_Functions::flattenSingleValue($characters); + if (is_bool($characters)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $characters = (int) $characters; + } else { + $characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + + $character = $characters; + if ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) { + if (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); } + return self::_uniord($character); + } else { + if (strlen($characters) > 0) { $character = substr($characters, 0, 1); } + return ord($character); + } + } // function ASCIICODE() + + + /** + * CONCATENATE + * + * @return string + */ + public static function CONCATENATE() { + // Return value + $returnValue = ''; + + // Loop through arguments + $aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args()); + foreach ($aArgs as $arg) { + if (is_bool($arg)) { + if (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) { + $arg = (int) $arg; + } else { + $arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + } + $returnValue .= $arg; + } + + // Return + return $returnValue; + } // function CONCATENATE() + + + /** + * DOLLAR + * + * This function converts a number to text using currency format, with the decimals rounded to the specified place. + * The format used is $#,##0.00_);($#,##0.00).. + * + * @param float $value The value to format + * @param int $decimals The number of digits to display to the right of the decimal point. + * If decimals is negative, number is rounded to the left of the decimal point. + * If you omit decimals, it is assumed to be 2 + * @return string + */ + public static function DOLLAR($value = 0, $decimals = 2) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $mask = '$#,##0'; + if ($decimals > 0) { + $mask .= '.' . str_repeat('0',$decimals); + } else { + $round = pow(10,abs($decimals)); + if ($value < 0) { $round = 0-$round; } + $value = PHPExcel_Calculation_MathTrig::MROUND($value, $round); + } + + return PHPExcel_Style_NumberFormat::toFormattedString($value, $mask); + + } // function DOLLAR() + + + /** + * SEARCHSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_strpos')) { + $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8'); + } else { + $pos = strpos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHSENSITIVE() + + + /** + * SEARCHINSENSITIVE + * + * @param string $needle The string to look for + * @param string $haystack The string in which to look + * @param int $offset Offset within $haystack + * @return string + */ + public static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) { + $needle = PHPExcel_Calculation_Functions::flattenSingleValue($needle); + $haystack = PHPExcel_Calculation_Functions::flattenSingleValue($haystack); + $offset = PHPExcel_Calculation_Functions::flattenSingleValue($offset); + + if (!is_bool($needle)) { + if (is_bool($haystack)) { + $haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) { + if (PHPExcel_Shared_String::CountCharacters($needle) == 0) { + return $offset; + } + if (function_exists('mb_stripos')) { + $pos = mb_stripos($haystack, $needle, --$offset,'UTF-8'); + } else { + $pos = stripos($haystack, $needle, --$offset); + } + if ($pos !== false) { + return ++$pos; + } + } + } + return PHPExcel_Calculation_Functions::VALUE(); + } // function SEARCHINSENSITIVE() + + + /** + * FIXEDFORMAT + * + * @param mixed $value Value to check + * @param integer $decimals + * @param boolean $no_commas + * @return boolean + */ + public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $decimals = PHPExcel_Calculation_Functions::flattenSingleValue($decimals); + $no_commas = PHPExcel_Calculation_Functions::flattenSingleValue($no_commas); + + // Validate parameters + if (!is_numeric($value) || !is_numeric($decimals)) { + return PHPExcel_Calculation_Functions::NaN(); + } + $decimals = floor($decimals); + + $valueResult = round($value,$decimals); + if ($decimals < 0) { $decimals = 0; } + if (!$no_commas) { + $valueResult = number_format($valueResult,$decimals); + } + + return (string) $valueResult; + } // function FIXEDFORMAT() + + + /** + * LEFT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function LEFT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, 0, $chars, 'UTF-8'); + } else { + return substr($value, 0, $chars); + } + } // function LEFT() + + + /** + * MID + * + * @param string $value Value + * @param int $start Start character + * @param int $chars Number of characters + * @return string + */ + public static function MID($value = '', $start = 1, $chars = null) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if (($start < 1) || ($chars < 0)) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_substr')) { + return mb_substr($value, --$start, $chars, 'UTF-8'); + } else { + return substr($value, --$start, $chars); + } + } // function MID() + + + /** + * RIGHT + * + * @param string $value Value + * @param int $chars Number of characters + * @return string + */ + public static function RIGHT($value = '', $chars = 1) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + + if ($chars < 0) { + return PHPExcel_Calculation_Functions::VALUE(); + } + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) { + return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8'); + } else { + return substr($value, strlen($value) - $chars); + } + } // function RIGHT() + + + /** + * STRINGLENGTH + * + * @param string $value Value + * @return string + */ + public static function STRINGLENGTH($value = '') { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + + if (is_bool($value)) { + $value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + if (function_exists('mb_strlen')) { + return mb_strlen($value, 'UTF-8'); + } else { + return strlen($value); + } + } // function STRINGLENGTH() + + + /** + * LOWERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function LOWERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToLower($mixedCaseString); + } // function LOWERCASE() + + + /** + * UPPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function UPPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToUpper($mixedCaseString); + } // function UPPERCASE() + + + /** + * PROPERCASE + * + * Converts a string value to upper case. + * + * @param string $mixedCaseString + * @return string + */ + public static function PROPERCASE($mixedCaseString) { + $mixedCaseString = PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString); + + if (is_bool($mixedCaseString)) { + $mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE(); + } + + return PHPExcel_Shared_String::StrToTitle($mixedCaseString); + } // function PROPERCASE() + + + /** + * REPLACE + * + * @param string $oldText String to modify + * @param int $start Start character + * @param int $chars Number of characters + * @param string $newText String to replace in defined position + * @return string + */ + public static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) { + $oldText = PHPExcel_Calculation_Functions::flattenSingleValue($oldText); + $start = PHPExcel_Calculation_Functions::flattenSingleValue($start); + $chars = PHPExcel_Calculation_Functions::flattenSingleValue($chars); + $newText = PHPExcel_Calculation_Functions::flattenSingleValue($newText); + + $left = self::LEFT($oldText,$start-1); + $right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1); + + return $left.$newText.$right; + } // function REPLACE() + + + /** + * SUBSTITUTE + * + * @param string $text Value + * @param string $fromText From Value + * @param string $toText To Value + * @param integer $instance Instance Number + * @return string + */ + public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) { + $text = PHPExcel_Calculation_Functions::flattenSingleValue($text); + $fromText = PHPExcel_Calculation_Functions::flattenSingleValue($fromText); + $toText = PHPExcel_Calculation_Functions::flattenSingleValue($toText); + $instance = floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance)); + + if ($instance == 0) { + if(function_exists('mb_str_replace')) { + return mb_str_replace($fromText,$toText,$text); + } else { + return str_replace($fromText,$toText,$text); + } + } else { + $pos = -1; + while($instance > 0) { + if (function_exists('mb_strpos')) { + $pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8'); + } else { + $pos = strpos($text, $fromText, $pos+1); + } + if ($pos === false) { + break; + } + --$instance; + } + if ($pos !== false) { + if (function_exists('mb_strlen')) { + return self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText); + } else { + return self::REPLACE($text,++$pos,strlen($fromText),$toText); + } + } + } + + return $text; + } // function SUBSTITUTE() + + + /** + * RETURNSTRING + * + * @param mixed $testValue Value to check + * @return boolean + */ + public static function RETURNSTRING($testValue = '') { + $testValue = PHPExcel_Calculation_Functions::flattenSingleValue($testValue); + + if (is_string($testValue)) { + return $testValue; + } + return Null; + } // function RETURNSTRING() + + + /** + * TEXTFORMAT + * + * @param mixed $value Value to check + * @param string $format Format mask to use + * @return boolean + */ + public static function TEXTFORMAT($value,$format) { + $value = PHPExcel_Calculation_Functions::flattenSingleValue($value); + $format = PHPExcel_Calculation_Functions::flattenSingleValue($format); + + if ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) { + $value = PHPExcel_Calculation_DateTime::DATEVALUE($value); + } + + return (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format); + } // function TEXTFORMAT() + +} // class PHPExcel_Calculation_TextData diff --git a/extend/phpexcel/PHPExcel/Calculation/Token/Stack.php b/extend/phpexcel/PHPExcel/Calculation/Token/Stack.php new file mode 100755 index 0000000..821f3bd --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/Token/Stack.php @@ -0,0 +1,115 @@ +_count; + } // function count() + + /** + * Push a new entry onto the stack + * + * @param mixed $type + * @param mixed $value + * @param mixed $reference + */ + public function push($type, $value, $reference = NULL) { + $this->_stack[$this->_count++] = array('type' => $type, + 'value' => $value, + 'reference' => $reference + ); + if ($type == 'Function') { + $localeFunction = PHPExcel_Calculation::_localeFunc($value); + if ($localeFunction != $value) { + $this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction; + } + } + } // function push() + + /** + * Pop the last entry from the stack + * + * @return mixed + */ + public function pop() { + if ($this->_count > 0) { + return $this->_stack[--$this->_count]; + } + return NULL; + } // function pop() + + /** + * Return an entry from the stack without removing it + * + * @param integer $n number indicating how far back in the stack we want to look + * @return mixed + */ + public function last($n = 1) { + if ($this->_count - $n < 0) { + return NULL; + } + return $this->_stack[$this->_count - $n]; + } // function last() + + /** + * Clear the stack + */ + function clear() { + $this->_stack = array(); + $this->_count = 0; + } + +} // class PHPExcel_Calculation_Token_Stack diff --git a/extend/phpexcel/PHPExcel/Calculation/functionlist.txt b/extend/phpexcel/PHPExcel/Calculation/functionlist.txt new file mode 100755 index 0000000..67dbd49 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Calculation/functionlist.txt @@ -0,0 +1,351 @@ +ABS +ACCRINT +ACCRINTM +ACOS +ACOSH +ADDRESS +AMORDEGRC +AMORLINC +AND +AREAS +ASC +ASIN +ASINH +ATAN +ATAN2 +ATANH +AVEDEV +AVERAGE +AVERAGEA +AVERAGEIF +AVERAGEIFS +BAHTTEXT +BESSELI +BESSELJ +BESSELK +BESSELY +BETADIST +BETAINV +BIN2DEC +BIN2HEX +BIN2OCT +BINOMDIST +CEILING +CELL +CHAR +CHIDIST +CHIINV +CHITEST +CHOOSE +CLEAN +CODE +COLUMN +COLUMNS +COMBIN +COMPLEX +CONCATENATE +CONFIDENCE +CONVERT +CORREL +COS +COSH +COUNT +COUNTA +COUNTBLANK +COUNTIF +COUNTIFS +COUPDAYBS +COUPDAYBS +COUPDAYSNC +COUPNCD +COUPNUM +COUPPCD +COVAR +CRITBINOM +CUBEKPIMEMBER +CUBEMEMBER +CUBEMEMBERPROPERTY +CUBERANKEDMEMBER +CUBESET +CUBESETCOUNT +CUBEVALUE +CUMIPMT +CUMPRINC +DATE +DATEDIF +DATEVALUE +DAVERAGE +DAY +DAYS360 +DB +DCOUNT +DCOUNTA +DDB +DEC2BIN +DEC2HEX +DEC2OCT +DEGREES +DELTA +DEVSQ +DGET +DISC +DMAX +DMIN +DOLLAR +DOLLARDE +DOLLARFR +DPRODUCT +DSTDEV +DSTDEVP +DSUM +DURATION +DVAR +DVARP +EDATE +EFFECT +EOMONTH +ERF +ERFC +ERROR.TYPE +EVEN +EXACT +EXP +EXPONDIST +FACT +FACTDOUBLE +FALSE +FDIST +FIND +FINDB +FINV +FISHER +FISHERINV +FIXED +FLOOR +FORECAST +FREQUENCY +FTEST +FV +FVSCHEDULE +GAMAMDIST +GAMMAINV +GAMMALN +GCD +GEOMEAN +GESTEP +GETPIVOTDATA +GROWTH +HARMEAN +HEX2BIN +HEX2OCT +HLOOKUP +HOUR +HYPERLINK +HYPGEOMDIST +IF +IFERROR +IMABS +IMAGINARY +IMARGUMENT +IMCONJUGATE +IMCOS +IMEXP +IMLN +IMLOG10 +IMLOG2 +IMPOWER +IMPRODUCT +IMREAL +IMSIN +IMSQRT +IMSUB +IMSUM +INDEX +INDIRECT +INFO +INT +INTERCEPT +INTRATE +IPMT +IRR +ISBLANK +ISERR +ISERROR +ISEVEN +ISLOGICAL +ISNA +ISNONTEXT +ISNUMBER +ISODD +ISPMT +ISREF +ISTEXT +JIS +KURT +LARGE +LCM +LEFT +LEFTB +LEN +LENB +LINEST +LN +LOG +LOG10 +LOGEST +LOGINV +LOGNORMDIST +LOOKUP +LOWER +MATCH +MAX +MAXA +MDETERM +MDURATION +MEDIAN +MID +MIDB +MIN +MINA +MINUTE +MINVERSE +MIRR +MMULT +MOD +MODE +MONTH +MROUND +MULTINOMIAL +N +NA +NEGBINOMDIST +NETWORKDAYS +NOMINAL +NORMDIST +NORMINV +NORMSDIST +NORMSINV +NOT +NOW +NPER +NPV +OCT2BIN +OCT2DEC +OCT2HEX +ODD +ODDFPRICE +ODDFYIELD +ODDLPRICE +ODDLYIELD +OFFSET +OR +PEARSON +PERCENTILE +PERCENTRANK +PERMUT +PHONETIC +PI +PMT +POISSON +POWER +PPMT +PRICE +PRICEDISC +PRICEMAT +PROB +PRODUCT +PROPER +PV +QUARTILE +QUOTIENT +RADIANS +RAND +RANDBETWEEN +RANK +RATE +RECEIVED +REPLACE +REPLACEB +REPT +RIGHT +RIGHTB +ROMAN +ROUND +ROUNDDOWN +ROUNDUP +ROW +ROWS +RSQ +RTD +SEARCH +SEARCHB +SECOND +SERIESSUM +SIGN +SIN +SINH +SKEW +SLN +SLOPE +SMALL +SQRT +SQRTPI +STANDARDIZE +STDEV +STDEVA +STDEVP +STDEVPA +STEYX +SUBSTITUTE +SUBTOTAL +SUM +SUMIF +SUMIFS +SUMPRODUCT +SUMSQ +SUMX2MY2 +SUMX2PY2 +SUMXMY2 +SYD +T +TAN +TANH +TBILLEQ +TBILLPRICE +TBILLYIELD +TDIST +TEXT +TIME +TIMEVALUE +TINV +TODAY +TRANSPOSE +TREND +TRIM +TRIMMEAN +TRUE +TRUNC +TTEST +TYPE +UPPER +USDOLLAR +VALUE +VAR +VARA +VARP +VARPA +VDB +VERSION +VLOOKUP +WEEKDAY +WEEKNUM +WEIBULL +WORKDAY +XIRR +XNPV +YEAR +YEARFRAC +YIELD +YIELDDISC +YIELDMAT +ZTEST diff --git a/extend/phpexcel/PHPExcel/Cell.php b/extend/phpexcel/PHPExcel/Cell.php new file mode 100755 index 0000000..1788559 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell.php @@ -0,0 +1,990 @@ +_parent->updateCacheData($this); + + return $this; + } + + public function detach() { + $this->_parent = NULL; + } + + public function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) { + + + $this->_parent = $parent; + } + + + /** + * Create a new Cell + * + * @param mixed $pValue + * @param string $pDataType + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Exception + */ + public function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // Initialise cell value + $this->_value = $pValue; + + // Set worksheet cache + $this->_parent = $pSheet->getCellCacheController(); + + // Set datatype? + if ($pDataType !== NULL) { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + $this->_dataType = $pDataType; + } else { + if (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); + } + } + + // set default index to cellXf + $this->_xfIndex = 0; + } + + /** + * Get cell coordinate column + * + * @return string + */ + public function getColumn() + { + return $this->_parent->getCurrentColumn(); + } + + /** + * Get cell coordinate row + * + * @return int + */ + public function getRow() + { + return $this->_parent->getCurrentRow(); + } + + /** + * Get cell coordinate + * + * @return string + */ + public function getCoordinate() + { + return $this->_parent->getCurrentAddress(); + } + + /** + * Get cell value + * + * @return mixed + */ + public function getValue() + { + return $this->_value; + } + + /** + * Get cell value with formatting + * + * @return string + */ + public function getFormattedValue() + { + return (string) PHPExcel_Style_NumberFormat::toFormattedString( + $this->getCalculatedValue(), + $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()) + ->getNumberFormat()->getFormatCode() + ); + } + + /** + * Set cell value + * + * Sets the value for a cell, automatically determining the datatype using the value binder + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValue($pValue = NULL) + { + if (!self::getValueBinder()->bindValue($this, $pValue)) { + throw new PHPExcel_Exception("Value could not be bound to cell."); + } + return $this; + } + + /** + * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder) + * + * @param mixed $pValue Value + * @param string $pDataType Explicit data type + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + // set the value according to data type + switch ($pDataType) { + case PHPExcel_Cell_DataType::TYPE_NULL: + $this->_value = $pValue; + break; + case PHPExcel_Cell_DataType::TYPE_STRING2: + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_INLINE: + $this->_value = PHPExcel_Cell_DataType::checkString($pValue); + break; + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_value = (float)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $this->_value = (string)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_value = (bool)$pValue; + break; + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue); + break; + default: + throw new PHPExcel_Exception('Invalid datatype: ' . $pDataType); + break; + } + + // set the datatype + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } + + /** + * Get calculated cell value + * + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + * + * @param boolean $resetLog Whether the calculation engine logger should be reset or not + * @return mixed + * @throws PHPExcel_Exception + */ + public function getCalculatedValue($resetLog = TRUE) + { +//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL; + if ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) { + try { +//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL; + $result = PHPExcel_Calculation::getInstance( + $this->getWorksheet()->getParent() + )->calculateCellValue($this,$resetLog); +//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL; + // We don't yet handle array returns + if (is_array($result)) { + while (is_array($result)) { + $result = array_pop($result); + } + } + } catch ( PHPExcel_Exception $ex ) { + if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) { +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->_calculatedValue; // Fallback for calculations referencing external files. + } +//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL; + $result = '#N/A'; + throw new PHPExcel_Calculation_Exception( + $this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage() + ); + } + + if ($result === '#Not Yet Implemented') { +//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL; + return $this->_calculatedValue; // Fallback if calculation engine does not support the formula. + } +//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL; + return $result; + } elseif($this->_value instanceof PHPExcel_RichText) { +// echo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'
'; + return $this->_value->getPlainText(); + } +// echo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'
'; + return $this->_value; + } + + /** + * Set old calculated value (cached) + * + * @param mixed $pValue Value + * @return PHPExcel_Cell + */ + public function setCalculatedValue($pValue = NULL) + { + if ($pValue !== NULL) { + $this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue; + } + + return $this->notifyCacheController(); + } + + /** + * Get old calculated value (cached) + * This returns the value last calculated by MS Excel or whichever spreadsheet program was used to + * create the original spreadsheet file. + * Note that this value is not guaranteed to refelect the actual calculated value because it is + * possible that auto-calculation was disabled in the original spreadsheet, and underlying data + * values used by the formula have changed since it was last calculated. + * + * @return mixed + */ + public function getOldCalculatedValue() + { + return $this->_calculatedValue; + } + + /** + * Get cell data type + * + * @return string + */ + public function getDataType() + { + return $this->_dataType; + } + + /** + * Set cell data type + * + * @param string $pDataType + * @return PHPExcel_Cell + */ + public function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING) + { + if ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2) + $pDataType = PHPExcel_Cell_DataType::TYPE_STRING; + + $this->_dataType = $pDataType; + + return $this->notifyCacheController(); + } + + /** + * Identify if the cell contains a formula + * + * @return boolean + */ + public function isFormula() + { + return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA; + } + + /** + * Does this cell contain Data validation rules? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->dataValidationExists($this->getCoordinate()); + } + + /** + * Get Data validation rules + * + * @return PHPExcel_Cell_DataValidation + * @throws PHPExcel_Exception + */ + public function getDataValidation() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getDataValidation($this->getCoordinate()); + } + + /** + * Set Data validation rules + * + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation); + + return $this->notifyCacheController(); + } + + /** + * Does this cell contain a Hyperlink? + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function hasHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); + } + + return $this->getWorksheet()->hyperlinkExists($this->getCoordinate()); + } + + /** + * Get Hyperlink + * + * @return PHPExcel_Cell_Hyperlink + * @throws PHPExcel_Exception + */ + public function getHyperlink() + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); + } + + return $this->getWorksheet()->getHyperlink($this->getCoordinate()); + } + + /** + * Set Hyperlink + * + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Cell + * @throws PHPExcel_Exception + */ + public function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL) + { + if (!isset($this->_parent)) { + throw new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); + } + + $this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink); + + return $this->notifyCacheController(); + } + + /** + * Get parent worksheet + * + * @return PHPExcel_CachedObjectStorage_CacheBase + */ + public function getParent() { + return $this->_parent; + } + + /** + * Get parent worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_parent->getParent(); + } + + /** + * Get cell style + * + * @return PHPExcel_Style + */ + public function getStyle() + { + return $this->getWorksheet()->getParent()->getCellXfByIndex($this->getXfIndex()); + } + + /** + * Re-bind parent + * + * @param PHPExcel_Worksheet $parent + * @return PHPExcel_Cell + */ + public function rebindParent(PHPExcel_Worksheet $parent) { + $this->_parent = $parent->getCellCacheController(); + + return $this->notifyCacheController(); + } + + /** + * Is cell in a specific range? + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return boolean + */ + public function isInRange($pRange = 'A1:A1') + { + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + // Translate properties + $myColumn = self::columnIndexFromString($this->getColumn()); + $myRow = $this->getRow(); + + // Verify if cell is in range + return (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) && + ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow) + ); + } + + /** + * Coordinate from string + * + * @param string $pCoordinateString + * @return array Array containing column and row (indexes 0 and 1) + * @throws PHPExcel_Exception + */ + public static function coordinateFromString($pCoordinateString = 'A1') + { + if (preg_match("/^([$]?[A-Z]{1,3})([$]?\d{1,7})$/", $pCoordinateString, $matches)) { + return array($matches[1],$matches[2]); + } elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } elseif ($pCoordinateString == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string'); + } + + throw new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString); + } + + /** + * Make string row, column or cell coordinate absolute + * + * @param string $pCoordinateString e.g. 'A' or '1' or 'A1' + * Note that this value can be a row or column reference as well as a cell reference + * @return string Absolute coordinate e.g. '$A' or '$1' or '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteReference($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the reference + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + if (ctype_digit($pCoordinateString)) { + return $worksheet . '$' . $pCoordinateString; + } elseif (ctype_alpha($pCoordinateString)) { + return $worksheet . '$' . strtoupper($pCoordinateString); + } + return $worksheet . self::absoluteCoordinate($pCoordinateString); + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Make string coordinate absolute + * + * @param string $pCoordinateString e.g. 'A1' + * @return string Absolute coordinate e.g. '$A$1' + * @throws PHPExcel_Exception + */ + public static function absoluteCoordinate($pCoordinateString = 'A1') + { + if (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) { + // Split out any worksheet name from the coordinate + $worksheet = ''; + $cellAddress = explode('!',$pCoordinateString); + if (count($cellAddress) > 1) { + list($worksheet,$pCoordinateString) = $cellAddress; + } + if ($worksheet > '') $worksheet .= '!'; + + // Create absolute coordinate + list($column, $row) = self::coordinateFromString($pCoordinateString); + $column = ltrim($column,'$'); + $row = ltrim($row,'$'); + return $worksheet . '$' . $column . '$' . $row; + } + + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells'); + } + + /** + * Split range into coordinate strings + * + * @param string $pRange e.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4' + * @return array Array containg one or more arrays containing one or two coordinate strings + * e.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11')) + * or array('B4') + */ + public static function splitRange($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + $exploded = explode(',', $pRange); + $counter = count($exploded); + for ($i = 0; $i < $counter; ++$i) { + $exploded[$i] = explode(':', $exploded[$i]); + } + return $exploded; + } + + /** + * Build range from coordinate strings + * + * @param array $pRange Array containg one or more arrays containing one or two coordinate strings + * @return string String representation of $pRange + * @throws PHPExcel_Exception + */ + public static function buildRange($pRange) + { + // Verify range + if (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) { + throw new PHPExcel_Exception('Range does not contain any information'); + } + + // Build range + $imploded = array(); + $counter = count($pRange); + for ($i = 0; $i < $counter; ++$i) { + $pRange[$i] = implode(':', $pRange[$i]); + } + $imploded = implode(',', $pRange); + + return $imploded; + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column Number, Row Number) + */ + public static function rangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = self::coordinateFromString($rangeA); + $rangeEnd = self::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = self::columnIndexFromString($rangeStart[0]); + $rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]); + + return array($rangeStart, $rangeEnd); + } + + /** + * Calculate range dimension + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range dimension (width, height) + */ + public static function rangeDimension($pRange = 'A1:A1') + { + // Calculate range outer borders + list($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange); + + return array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) ); + } + + /** + * Calculate range boundaries + * + * @param string $pRange Cell range (e.g. A1:A1) + * @return array Range coordinates array(Start Cell, End Cell) + * where Start Cell and End Cell are arrays (Column ID, Row Number) + */ + public static function getRangeBoundaries($pRange = 'A1:A1') + { + // Ensure $pRange is a valid range + if(empty($pRange)) { + $pRange = self::DEFAULT_RANGE; + } + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Extract range + if (strpos($pRange, ':') === FALSE) { + $rangeA = $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + return array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB)); + } + + /** + * Column index from string + * + * @param string $pString + * @return int Column index (base 1 !!!) + */ + public static function columnIndexFromString($pString = 'A') + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (isset($_indexCache[$pString])) + return $_indexCache[$pString]; + + // It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord() + // and make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant + // memory overhead either + static $_columnLookup = array( + 'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13, + 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26, + 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13, + 'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26 + ); + + // We also use the language construct isset() rather than the more costly strlen() function to match the length of $pString + // for improved performance + if (isset($pString{0})) { + if (!isset($pString{1})) { + $_indexCache[$pString] = $_columnLookup[$pString]; + return $_indexCache[$pString]; + } elseif(!isset($pString{2})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}]; + return $_indexCache[$pString]; + } elseif(!isset($pString{3})) { + $_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}]; + return $_indexCache[$pString]; + } + } + throw new PHPExcel_Exception("Column string index can not be " . ((isset($pString{0})) ? "longer than 3 characters" : "empty")); + } + + /** + * String from columnindex + * + * @param int $pColumnIndex Column index (base 0 !!!) + * @return string + */ + public static function stringFromColumnIndex($pColumnIndex = 0) + { + // Using a lookup cache adds a slight memory overhead, but boosts speed + // caching using a static within the method is faster than a class static, + // though it's additional memory overhead + static $_indexCache = array(); + + if (!isset($_indexCache[$pColumnIndex])) { + // Determine column string + if ($pColumnIndex < 26) { + $_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex); + } elseif ($pColumnIndex < 702) { + $_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) . + chr(65 + $pColumnIndex % 26); + } else { + $_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) . + chr(65 + ((($pColumnIndex - 26) % 676) / 26)) . + chr(65 + $pColumnIndex % 26); + } + } + return $_indexCache[$pColumnIndex]; + } + + /** + * Extract all cell references in range + * + * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) + * @return array Array containing single cell references + */ + public static function extractAllCellReferencesInRange($pRange = 'A1') { + // Returnvalue + $returnValue = array(); + + // Explode spaces + $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); + foreach ($cellBlocks as $cellBlock) { + // Single cell? + if (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) { + $returnValue[] = $cellBlock; + continue; + } + + // Range... + $ranges = self::splitRange($cellBlock); + foreach($ranges as $range) { + // Single cell? + if (!isset($range[1])) { + $returnValue[] = $range[0]; + continue; + } + + // Range... + list($rangeStart, $rangeEnd) = $range; + sscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow); + sscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow); + $endCol++; + + // Current data + $currentCol = $startCol; + $currentRow = $startRow; + + // Loop cells + while ($currentCol != $endCol) { + while ($currentRow <= $endRow) { + $returnValue[] = $currentCol.$currentRow; + ++$currentRow; + } + ++$currentCol; + $currentRow = $startRow; + } + } + } + + // Sort the result by column and row + $sortKeys = array(); + foreach (array_unique($returnValue) as $coord) { + sscanf($coord,'%[A-Z]%d', $column, $row); + $sortKeys[sprintf('%3s%09d',$column,$row)] = $coord; + } + ksort($sortKeys); + + // Return value + return array_values($sortKeys); + } + + /** + * Compare 2 cells + * + * @param PHPExcel_Cell $a Cell a + * @param PHPExcel_Cell $b Cell b + * @return int Result of comparison (always -1 or 1, never zero!) + */ + public static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b) + { + if ($a->getRow() < $b->getRow()) { + return -1; + } elseif ($a->getRow() > $b->getRow()) { + return 1; + } elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) { + return -1; + } else { + return 1; + } + } + + /** + * Get value binder to use + * + * @return PHPExcel_Cell_IValueBinder + */ + public static function getValueBinder() { + if (self::$_valueBinder === NULL) { + self::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder(); + } + + return self::$_valueBinder; + } + + /** + * Set value binder to use + * + * @param PHPExcel_Cell_IValueBinder $binder + * @throws PHPExcel_Exception + */ + public static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) { + if ($binder === NULL) { + throw new PHPExcel_Exception("A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly."); + } + + self::$_valueBinder = $binder; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Cell + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + + return $this->notifyCacheController(); + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function setFormulaAttributes($pAttributes) + { + $this->_formulaAttributes = $pAttributes; + return $this; + } + + /** + * @deprecated Since version 1.7.8 for planned changes to cell for array formula handling + */ + public function getFormulaAttributes() + { + return $this->_formulaAttributes; + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() + { + return (string) $this->getValue(); + } + +} + diff --git a/extend/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php b/extend/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php new file mode 100755 index 0000000..00a2b57 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/AdvancedValueBinder.php @@ -0,0 +1,192 @@ +setValueExplicit( TRUE, PHPExcel_Cell_DataType::TYPE_BOOL); + return true; + } elseif($value == PHPExcel_Calculation::getFALSE()) { + $cell->setValueExplicit( FALSE, PHPExcel_Cell_DataType::TYPE_BOOL); + return true; + } + + // Check for number in scientific format + if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) { + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + return true; + } + + // Check for fraction + if (preg_match('/^([+-]?)\s*([0-9]+)\s?\/\s*([0-9]+)$/', $value, $matches)) { + // Convert value to number + $value = $matches[2] / $matches[3]; + if ($matches[1] == '-') $value = 0 - $value; + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( '??/??' ); + return true; + } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\s?\/\s*([0-9]*)$/', $value, $matches)) { + // Convert value to number + $value = $matches[2] + ($matches[3] / $matches[4]); + if ($matches[1] == '-') $value = 0 - $value; + $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( '# ??/??' ); + return true; + } + + // Check for percentage + if (preg_match('/^\-?[0-9]*\.?[0-9]*\s?\%$/', $value)) { + // Convert value to number + $value = (float) str_replace('%', '', $value) / 100; + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 ); + return true; + } + + // Check for currency + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + $decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator(); + $thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator(); + if (preg_match('/^'.preg_quote($currencyCode).' *(\d{1,3}('.preg_quote($thousandsSeparator).'\d{3})*|(\d+))('.preg_quote($decimalSeparator).'\d{2})?$/', $value)) { + // Convert value to number + $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value)); + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( + str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ) + ); + return true; + } elseif (preg_match('/^\$ *(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$/', $value)) { + // Convert value to number + $value = (float) trim(str_replace(array('$',','), '', $value)); + $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE ); + return true; + } + + // Check for time without seconds e.g. '9:45', '09:45' + if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) { + // Convert value to number + list($h, $m) = explode(':', $value); + $days = $h / 24 + $m / 1440; + $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 ); + return true; + } + + // Check for time with seconds '9:45:59', '09:45:59' + if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) { + // Convert value to number + list($h, $m, $s) = explode(':', $value); + $days = $h / 24 + $m / 1440 + $s / 86400; + // Convert value to number + $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 ); + return true; + } + + // Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10' + if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) { + // Convert value to number + $cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC); + // Determine style. Either there is a time part or not. Look for ':' + if (strpos($value, ':') !== false) { + $formatCode = 'yyyy-mm-dd h:mm'; + } else { + $formatCode = 'yyyy-mm-dd'; + } + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getNumberFormat()->setFormatCode($formatCode); + return true; + } + + // Check for newline character "\n" + if (strpos($value, "\n") !== FALSE) { + $value = PHPExcel_Shared_String::SanitizeUTF8($value); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + // Set style + $cell->getWorksheet()->getStyle( $cell->getCoordinate() ) + ->getAlignment()->setWrapText(TRUE); + return true; + } + } + + // Not bound yet? Use parent... + return parent::bindValue($cell, $value); + } +} diff --git a/extend/phpexcel/PHPExcel/Cell/DataType.php b/extend/phpexcel/PHPExcel/Cell/DataType.php new file mode 100755 index 0000000..8576542 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/DataType.php @@ -0,0 +1,122 @@ + 0, + '#DIV/0!' => 1, + '#VALUE!' => 2, + '#REF!' => 3, + '#NAME?' => 4, + '#NUM!' => 5, + '#N/A' => 6 + ); + + /** + * Get list of error codes + * + * @return array + */ + public static function getErrorCodes() { + return self::$_errorCodes; + } + + /** + * DataType for value + * + * @deprecated Replaced by PHPExcel_Cell_IValueBinder infrastructure, will be removed in version 1.8.0 + * @param mixed $pValue + * @return string + */ + public static function dataTypeForValue($pValue = null) { + return PHPExcel_Cell_DefaultValueBinder::dataTypeForValue($pValue); + } + + /** + * Check a string that it satisfies Excel requirements + * + * @param mixed Value to sanitize to an Excel string + * @return mixed Sanitized value + */ + public static function checkString($pValue = null) + { + if ($pValue instanceof PHPExcel_RichText) { + // TODO: Sanitize Rich-Text string (max. character count is 32,767) + return $pValue; + } + + // string must never be longer than 32,767 characters, truncate if necessary + $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 32767); + + // we require that newline is represented as "\n" in core, not as "\r\n" or "\r" + $pValue = str_replace(array("\r\n", "\r"), "\n", $pValue); + + return $pValue; + } + + /** + * Check a value that it is a valid error code + * + * @param mixed Value to sanitize to an Excel error code + * @return string Sanitized value + */ + public static function checkErrorCode($pValue = null) + { + $pValue = (string) $pValue; + + if ( !array_key_exists($pValue, self::$_errorCodes) ) { + $pValue = '#NULL!'; + } + + return $pValue; + } + +} diff --git a/extend/phpexcel/PHPExcel/Cell/DataValidation.php b/extend/phpexcel/PHPExcel/Cell/DataValidation.php new file mode 100755 index 0000000..3174a3f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/DataValidation.php @@ -0,0 +1,472 @@ +_formula1 = ''; + $this->_formula2 = ''; + $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE; + $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; + $this->_operator = ''; + $this->_allowBlank = FALSE; + $this->_showDropDown = FALSE; + $this->_showInputMessage = FALSE; + $this->_showErrorMessage = FALSE; + $this->_errorTitle = ''; + $this->_error = ''; + $this->_promptTitle = ''; + $this->_prompt = ''; + } + + /** + * Get Formula 1 + * + * @return string + */ + public function getFormula1() { + return $this->_formula1; + } + + /** + * Set Formula 1 + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setFormula1($value = '') { + $this->_formula1 = $value; + return $this; + } + + /** + * Get Formula 2 + * + * @return string + */ + public function getFormula2() { + return $this->_formula2; + } + + /** + * Set Formula 2 + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setFormula2($value = '') { + $this->_formula2 = $value; + return $this; + } + + /** + * Get Type + * + * @return string + */ + public function getType() { + return $this->_type; + } + + /** + * Set Type + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) { + $this->_type = $value; + return $this; + } + + /** + * Get Error style + * + * @return string + */ + public function getErrorStyle() { + return $this->_errorStyle; + } + + /** + * Set Error style + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) { + $this->_errorStyle = $value; + return $this; + } + + /** + * Get Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set Operator + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setOperator($value = '') { + $this->_operator = $value; + return $this; + } + + /** + * Get Allow Blank + * + * @return boolean + */ + public function getAllowBlank() { + return $this->_allowBlank; + } + + /** + * Set Allow Blank + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setAllowBlank($value = false) { + $this->_allowBlank = $value; + return $this; + } + + /** + * Get Show DropDown + * + * @return boolean + */ + public function getShowDropDown() { + return $this->_showDropDown; + } + + /** + * Set Show DropDown + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowDropDown($value = false) { + $this->_showDropDown = $value; + return $this; + } + + /** + * Get Show InputMessage + * + * @return boolean + */ + public function getShowInputMessage() { + return $this->_showInputMessage; + } + + /** + * Set Show InputMessage + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowInputMessage($value = false) { + $this->_showInputMessage = $value; + return $this; + } + + /** + * Get Show ErrorMessage + * + * @return boolean + */ + public function getShowErrorMessage() { + return $this->_showErrorMessage; + } + + /** + * Set Show ErrorMessage + * + * @param boolean $value + * @return PHPExcel_Cell_DataValidation + */ + public function setShowErrorMessage($value = false) { + $this->_showErrorMessage = $value; + return $this; + } + + /** + * Get Error title + * + * @return string + */ + public function getErrorTitle() { + return $this->_errorTitle; + } + + /** + * Set Error title + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setErrorTitle($value = '') { + $this->_errorTitle = $value; + return $this; + } + + /** + * Get Error + * + * @return string + */ + public function getError() { + return $this->_error; + } + + /** + * Set Error + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setError($value = '') { + $this->_error = $value; + return $this; + } + + /** + * Get Prompt title + * + * @return string + */ + public function getPromptTitle() { + return $this->_promptTitle; + } + + /** + * Set Prompt title + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setPromptTitle($value = '') { + $this->_promptTitle = $value; + return $this; + } + + /** + * Get Prompt + * + * @return string + */ + public function getPrompt() { + return $this->_prompt; + } + + /** + * Set Prompt + * + * @param string $value + * @return PHPExcel_Cell_DataValidation + */ + public function setPrompt($value = '') { + $this->_prompt = $value; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_formula1 + . $this->_formula2 + . $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE + . $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP + . $this->_operator + . ($this->_allowBlank ? 't' : 'f') + . ($this->_showDropDown ? 't' : 'f') + . ($this->_showInputMessage ? 't' : 'f') + . ($this->_showErrorMessage ? 't' : 'f') + . $this->_errorTitle + . $this->_error + . $this->_promptTitle + . $this->_prompt + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Cell/DefaultValueBinder.php b/extend/phpexcel/PHPExcel/Cell/DefaultValueBinder.php new file mode 100755 index 0000000..f1880fa --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/DefaultValueBinder.php @@ -0,0 +1,106 @@ +setValueExplicit( $value, self::dataTypeForValue($value) ); + + // Done! + return TRUE; + } + + /** + * DataType for value + * + * @param mixed $pValue + * @return string + */ + public static function dataTypeForValue($pValue = null) { + // Match the value against a few data types + if (is_null($pValue)) { + return PHPExcel_Cell_DataType::TYPE_NULL; + + } elseif ($pValue === '') { + return PHPExcel_Cell_DataType::TYPE_STRING; + + } elseif ($pValue instanceof PHPExcel_RichText) { + return PHPExcel_Cell_DataType::TYPE_INLINE; + + } elseif ($pValue{0} === '=' && strlen($pValue) > 1) { + return PHPExcel_Cell_DataType::TYPE_FORMULA; + + } elseif (is_bool($pValue)) { + return PHPExcel_Cell_DataType::TYPE_BOOL; + + } elseif (is_float($pValue) || is_int($pValue)) { + return PHPExcel_Cell_DataType::TYPE_NUMERIC; + + } elseif (preg_match('/^\-?([0-9]+\\.?[0-9]*|[0-9]*\\.?[0-9]+)$/', $pValue)) { + return PHPExcel_Cell_DataType::TYPE_NUMERIC; + + } elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) { + return PHPExcel_Cell_DataType::TYPE_ERROR; + + } else { + return PHPExcel_Cell_DataType::TYPE_STRING; + + } + } +} diff --git a/extend/phpexcel/PHPExcel/Cell/Hyperlink.php b/extend/phpexcel/PHPExcel/Cell/Hyperlink.php new file mode 100755 index 0000000..06edfad --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/Hyperlink.php @@ -0,0 +1,126 @@ +_url = $pUrl; + $this->_tooltip = $pTooltip; + } + + /** + * Get URL + * + * @return string + */ + public function getUrl() { + return $this->_url; + } + + /** + * Set URL + * + * @param string $value + * @return PHPExcel_Cell_Hyperlink + */ + public function setUrl($value = '') { + $this->_url = $value; + return $this; + } + + /** + * Get tooltip + * + * @return string + */ + public function getTooltip() { + return $this->_tooltip; + } + + /** + * Set tooltip + * + * @param string $value + * @return PHPExcel_Cell_Hyperlink + */ + public function setTooltip($value = '') { + $this->_tooltip = $value; + return $this; + } + + /** + * Is this hyperlink internal? (to another worksheet) + * + * @return boolean + */ + public function isInternal() { + return strpos($this->_url, 'sheet://') !== false; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_url + . $this->_tooltip + . __CLASS__ + ); + } +} diff --git a/extend/phpexcel/PHPExcel/Cell/IValueBinder.php b/extend/phpexcel/PHPExcel/Cell/IValueBinder.php new file mode 100755 index 0000000..bc7b468 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Cell/IValueBinder.php @@ -0,0 +1,46 @@ +_name = $name; + $this->_title = $title; + $this->_legend = $legend; + $this->_xAxisLabel = $xAxisLabel; + $this->_yAxisLabel = $yAxisLabel; + $this->_plotArea = $plotArea; + $this->_plotVisibleOnly = $plotVisibleOnly; + $this->_displayBlanksAs = $displayBlanksAs; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Get Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set Worksheet + * + * @param PHPExcel_Worksheet $pValue + * @throws PHPExcel_Chart_Exception + * @return PHPExcel_Chart + */ + public function setWorksheet(PHPExcel_Worksheet $pValue = null) { + $this->_worksheet = $pValue; + + return $this; + } + + /** + * Get Title + * + * @return PHPExcel_Chart_Title + */ + public function getTitle() { + return $this->_title; + } + + /** + * Set Title + * + * @param PHPExcel_Chart_Title $title + * @return PHPExcel_Chart + */ + public function setTitle(PHPExcel_Chart_Title $title) { + $this->_title = $title; + + return $this; + } + + /** + * Get Legend + * + * @return PHPExcel_Chart_Legend + */ + public function getLegend() { + return $this->_legend; + } + + /** + * Set Legend + * + * @param PHPExcel_Chart_Legend $legend + * @return PHPExcel_Chart + */ + public function setLegend(PHPExcel_Chart_Legend $legend) { + $this->_legend = $legend; + + return $this; + } + + /** + * Get X-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getXAxisLabel() { + return $this->_xAxisLabel; + } + + /** + * Set X-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setXAxisLabel(PHPExcel_Chart_Title $label) { + $this->_xAxisLabel = $label; + + return $this; + } + + /** + * Get Y-Axis Label + * + * @return PHPExcel_Chart_Title + */ + public function getYAxisLabel() { + return $this->_yAxisLabel; + } + + /** + * Set Y-Axis Label + * + * @param PHPExcel_Chart_Title $label + * @return PHPExcel_Chart + */ + public function setYAxisLabel(PHPExcel_Chart_Title $label) { + $this->_yAxisLabel = $label; + + return $this; + } + + /** + * Get Plot Area + * + * @return PHPExcel_Chart_PlotArea + */ + public function getPlotArea() { + return $this->_plotArea; + } + + /** + * Get Plot Visible Only + * + * @return boolean + */ + public function getPlotVisibleOnly() { + return $this->_plotVisibleOnly; + } + + /** + * Set Plot Visible Only + * + * @param boolean $plotVisibleOnly + * @return PHPExcel_Chart + */ + public function setPlotVisibleOnly($plotVisibleOnly = true) { + $this->_plotVisibleOnly = $plotVisibleOnly; + + return $this; + } + + /** + * Get Display Blanks as + * + * @return string + */ + public function getDisplayBlanksAs() { + return $this->_displayBlanksAs; + } + + /** + * Set Display Blanks as + * + * @param string $displayBlanksAs + * @return PHPExcel_Chart + */ + public function setDisplayBlanksAs($displayBlanksAs = '0') { + $this->_displayBlanksAs = $displayBlanksAs; + } + + + /** + * Set the Top Left position for the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) { + $this->_topLeftCellRef = $cell; + if (!is_null($xOffset)) + $this->setTopLeftXOffset($xOffset); + if (!is_null($yOffset)) + $this->setTopLeftYOffset($yOffset); + + return $this; + } + + /** + * Get the top left position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getTopLeftPosition() { + return array( 'cell' => $this->_topLeftCellRef, + 'xOffset' => $this->_topLeftXOffset, + 'yOffset' => $this->_topLeftYOffset + ); + } + + /** + * Get the cell address where the top left of the chart is fixed + * + * @return string + */ + public function getTopLeftCell() { + return $this->_topLeftCellRef; + } + + /** + * Set the Top Left cell position for the chart + * + * @param string $cell + * @return PHPExcel_Chart + */ + public function setTopLeftCell($cell) { + $this->_topLeftCellRef = $cell; + + return $this; + } + + /** + * Set the offset position within the Top Left cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setTopLeftOffset($xOffset=null,$yOffset=null) { + if (!is_null($xOffset)) + $this->setTopLeftXOffset($xOffset); + if (!is_null($yOffset)) + $this->setTopLeftYOffset($yOffset); + + return $this; + } + + /** + * Get the offset position within the Top Left cell for the chart + * + * @return integer[] + */ + public function getTopLeftOffset() { + return array( 'X' => $this->_topLeftXOffset, + 'Y' => $this->_topLeftYOffset + ); + } + + public function setTopLeftXOffset($xOffset) { + $this->_topLeftXOffset = $xOffset; + + return $this; + } + + public function getTopLeftXOffset() { + return $this->_topLeftXOffset; + } + + public function setTopLeftYOffset($yOffset) { + $this->_topLeftYOffset = $yOffset; + + return $this; + } + + public function getTopLeftYOffset() { + return $this->_topLeftYOffset; + } + + /** + * Set the Bottom Right position of the chart + * + * @param string $cell + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightPosition($cell, $xOffset=null, $yOffset=null) { + $this->_bottomRightCellRef = $cell; + if (!is_null($xOffset)) + $this->setBottomRightXOffset($xOffset); + if (!is_null($yOffset)) + $this->setBottomRightYOffset($yOffset); + + return $this; + } + + /** + * Get the bottom right position of the chart + * + * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell + */ + public function getBottomRightPosition() { + return array( 'cell' => $this->_bottomRightCellRef, + 'xOffset' => $this->_bottomRightXOffset, + 'yOffset' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightCell($cell) { + $this->_bottomRightCellRef = $cell; + + return $this; + } + + /** + * Get the cell address where the bottom right of the chart is fixed + * + * @return string + */ + public function getBottomRightCell() { + return $this->_bottomRightCellRef; + } + + /** + * Set the offset position within the Bottom Right cell for the chart + * + * @param integer $xOffset + * @param integer $yOffset + * @return PHPExcel_Chart + */ + public function setBottomRightOffset($xOffset=null,$yOffset=null) { + if (!is_null($xOffset)) + $this->setBottomRightXOffset($xOffset); + if (!is_null($yOffset)) + $this->setBottomRightYOffset($yOffset); + + return $this; + } + + /** + * Get the offset position within the Bottom Right cell for the chart + * + * @return integer[] + */ + public function getBottomRightOffset() { + return array( 'X' => $this->_bottomRightXOffset, + 'Y' => $this->_bottomRightYOffset + ); + } + + public function setBottomRightXOffset($xOffset) { + $this->_bottomRightXOffset = $xOffset; + + return $this; + } + + public function getBottomRightXOffset() { + return $this->_bottomRightXOffset; + } + + public function setBottomRightYOffset($yOffset) { + $this->_bottomRightYOffset = $yOffset; + + return $this; + } + + public function getBottomRightYOffset() { + return $this->_bottomRightYOffset; + } + + + public function refresh() { + if ($this->_worksheet !== NULL) { + $this->_plotArea->refresh($this->_worksheet); + } + } + + public function render($outputDestination = null) { + $libraryName = PHPExcel_Settings::getChartRendererName(); + if (is_null($libraryName)) { + return false; + } + // Ensure that data series values are up-to-date before we render + $this->refresh(); + + $libraryPath = PHPExcel_Settings::getChartRendererPath(); + $includePath = str_replace('\\','/',get_include_path()); + $rendererPath = str_replace('\\','/',$libraryPath); + if (strpos($rendererPath,$includePath) === false) { + set_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath); + } + + $rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName; + $renderer = new $rendererName($this); + + if ($outputDestination == 'php://output') { + $outputDestination = null; + } + return $renderer->render($outputDestination); + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/DataSeries.php b/extend/phpexcel/PHPExcel/Chart/DataSeries.php new file mode 100755 index 0000000..f5391aa --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/DataSeries.php @@ -0,0 +1,365 @@ +_plotType = $plotType; + $this->_plotGrouping = $plotGrouping; + $this->_plotOrder = $plotOrder; + $keys = array_keys($plotValues); + $this->_plotValues = $plotValues; + if ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) { + $plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + + $this->_plotLabel = $plotLabel; + if ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) { + $plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues(); + } + $this->_plotCategory = $plotCategory; + $this->_smoothLine = $smoothLine; + $this->_plotStyle = $plotStyle; + } + + /** + * Get Plot Type + * + * @return string + */ + public function getPlotType() { + return $this->_plotType; + } + + /** + * Set Plot Type + * + * @param string $plotType + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotType($plotType = '') { + $this->_plotType = $plotType; + return $this; + } + + /** + * Get Plot Grouping Type + * + * @return string + */ + public function getPlotGrouping() { + return $this->_plotGrouping; + } + + /** + * Set Plot Grouping Type + * + * @param string $groupingType + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotGrouping($groupingType = null) { + $this->_plotGrouping = $groupingType; + return $this; + } + + /** + * Get Plot Direction + * + * @return string + */ + public function getPlotDirection() { + return $this->_plotDirection; + } + + /** + * Set Plot Direction + * + * @param string $plotDirection + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotDirection($plotDirection = null) { + $this->_plotDirection = $plotDirection; + return $this; + } + + /** + * Get Plot Order + * + * @return string + */ + public function getPlotOrder() { + return $this->_plotOrder; + } + + /** + * Get Plot Labels + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabels() { + return $this->_plotLabel; + } + + /** + * Get Plot Label by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotLabelByIndex($index) { + $keys = array_keys($this->_plotLabel); + if (in_array($index,$keys)) { + return $this->_plotLabel[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotLabel[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Categories + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategories() { + return $this->_plotCategory; + } + + /** + * Get Plot Category by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotCategoryByIndex($index) { + $keys = array_keys($this->_plotCategory); + if (in_array($index,$keys)) { + return $this->_plotCategory[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotCategory[$keys[$index]]; + } + return false; + } + + /** + * Get Plot Style + * + * @return string + */ + public function getPlotStyle() { + return $this->_plotStyle; + } + + /** + * Set Plot Style + * + * @param string $plotStyle + * @return PHPExcel_Chart_DataSeries + */ + public function setPlotStyle($plotStyle = null) { + $this->_plotStyle = $plotStyle; + return $this; + } + + /** + * Get Plot Values + * + * @return array of PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValues() { + return $this->_plotValues; + } + + /** + * Get Plot Values by Index + * + * @return PHPExcel_Chart_DataSeriesValues + */ + public function getPlotValuesByIndex($index) { + $keys = array_keys($this->_plotValues); + if (in_array($index,$keys)) { + return $this->_plotValues[$index]; + } elseif(isset($keys[$index])) { + return $this->_plotValues[$keys[$index]]; + } + return false; + } + + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + return count($this->_plotValues); + } + + /** + * Get Smooth Line + * + * @return boolean + */ + public function getSmoothLine() { + return $this->_smoothLine; + } + + /** + * Set Smooth Line + * + * @param boolean $smoothLine + * @return PHPExcel_Chart_DataSeries + */ + public function setSmoothLine($smoothLine = TRUE) { + $this->_smoothLine = $smoothLine; + return $this; + } + + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotValues as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotLabel as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, TRUE); + } + foreach($this->_plotCategory as $plotValues) { + if ($plotValues !== NULL) + $plotValues->refresh($worksheet, FALSE); + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/DataSeriesValues.php b/extend/phpexcel/PHPExcel/Chart/DataSeriesValues.php new file mode 100755 index 0000000..930542b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/DataSeriesValues.php @@ -0,0 +1,327 @@ +setDataType($dataType); + $this->_dataSource = $dataSource; + $this->_formatCode = $formatCode; + $this->_pointCount = $pointCount; + $this->_dataValues = $dataValues; + $this->_marker = $marker; + } + + /** + * Get Series Data Type + * + * @return string + */ + public function getDataType() { + return $this->_dataType; + } + + /** + * Set Series Data Type + * + * @param string $dataType Datatype of this data series + * Typical values are: + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING + * Normally used for axis point values + * PHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER + * Normally used for chart data values + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) { + if (!in_array($dataType, self::$_dataTypeValues)) { + throw new PHPExcel_Chart_Exception('Invalid datatype for chart data series values'); + } + $this->_dataType = $dataType; + + return $this; + } + + /** + * Get Series Data Source (formula) + * + * @return string + */ + public function getDataSource() { + return $this->_dataSource; + } + + /** + * Set Series Data Source (formula) + * + * @param string $dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataSource($dataSource = null, $refreshDataValues = true) { + $this->_dataSource = $dataSource; + + if ($refreshDataValues) { + // TO DO + } + + return $this; + } + + /** + * Get Point Marker + * + * @return string + */ + public function getPointMarker() { + return $this->_marker; + } + + /** + * Set Point Marker + * + * @param string $marker + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setPointMarker($marker = null) { + $this->_marker = $marker; + + return $this; + } + + /** + * Get Series Format Code + * + * @return string + */ + public function getFormatCode() { + return $this->_formatCode; + } + + /** + * Set Series Format Code + * + * @param string $formatCode + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setFormatCode($formatCode = null) { + $this->_formatCode = $formatCode; + + return $this; + } + + /** + * Get Series Point Count + * + * @return integer + */ + public function getPointCount() { + return $this->_pointCount; + } + + /** + * Identify if the Data Series is a multi-level or a simple series + * + * @return boolean + */ + public function isMultiLevelSeries() { + if (count($this->_dataValues) > 0) { + return is_array($this->_dataValues[0]); + } + return null; + } + + /** + * Return the level count of a multi-level Data Series + * + * @return boolean + */ + public function multiLevelCount() { + $levelCount = 0; + foreach($this->_dataValues as $dataValueSet) { + $levelCount = max($levelCount,count($dataValueSet)); + } + return $levelCount; + } + + /** + * Get Series Data Values + * + * @return array of mixed + */ + public function getDataValues() { + return $this->_dataValues; + } + + /** + * Get the first Series Data value + * + * @return mixed + */ + public function getDataValue() { + $count = count($this->_dataValues); + if ($count == 0) { + return null; + } elseif ($count == 1) { + return $this->_dataValues[0]; + } + return $this->_dataValues; + } + + /** + * Set Series Data Values + * + * @param array $dataValues + * @param boolean $refreshDataSource + * TRUE - refresh the value of _dataSource based on the values of $dataValues + * FALSE - don't change the value of _dataSource + * @return PHPExcel_Chart_DataSeriesValues + */ + public function setDataValues($dataValues = array(), $refreshDataSource = TRUE) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues); + $this->_pointCount = count($dataValues); + + if ($refreshDataSource) { + // TO DO + } + + return $this; + } + + private function _stripNulls($var) { + return $var !== NULL; + } + + public function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) { + if ($this->_dataSource !== NULL) { + $calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent()); + $newDataValues = PHPExcel_Calculation::_unwrapResult( + $calcEngine->_calculateFormulaValue( + '='.$this->_dataSource, + NULL, + $worksheet->getCell('A1') + ) + ); + if ($flatten) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + foreach($this->_dataValues as &$dataValue) { + if ((!empty($dataValue)) && ($dataValue[0] == '#')) { + $dataValue = 0.0; + } + } + unset($dataValue); + } else { + $cellRange = explode('!',$this->_dataSource); + if (count($cellRange) > 1) { + list(,$cellRange) = $cellRange; + } + + $dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange)); + if (($dimensions[0] == 1) || ($dimensions[1] == 1)) { + $this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues); + } else { + $newArray = array_values(array_shift($newDataValues)); + foreach($newArray as $i => $newDataSet) { + $newArray[$i] = array($newDataSet); + } + + foreach($newDataValues as $newDataSet) { + $i = 0; + foreach($newDataSet as $newDataVal) { + array_unshift($newArray[$i++],$newDataVal); + } + } + $this->_dataValues = $newArray; + } + } + $this->_pointCount = count($this->_dataValues); + } + + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/Exception.php b/extend/phpexcel/PHPExcel/Chart/Exception.php new file mode 100755 index 0000000..ecf3c43 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/extend/phpexcel/PHPExcel/Chart/Layout.php b/extend/phpexcel/PHPExcel/Chart/Layout.php new file mode 100755 index 0000000..d749dfe --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Layout.php @@ -0,0 +1,445 @@ +_layoutTarget = $layout['layoutTarget']; } + if (isset($layout['xMode'])) { $this->_xMode = $layout['xMode']; } + if (isset($layout['yMode'])) { $this->_yMode = $layout['yMode']; } + if (isset($layout['x'])) { $this->_xPos = (float) $layout['x']; } + if (isset($layout['y'])) { $this->_yPos = (float) $layout['y']; } + if (isset($layout['w'])) { $this->_width = (float) $layout['w']; } + if (isset($layout['h'])) { $this->_height = (float) $layout['h']; } + } + + /** + * Get Layout Target + * + * @return string + */ + public function getLayoutTarget() { + return $this->_layoutTarget; + } + + /** + * Set Layout Target + * + * @param Layout Target $value + * @return PHPExcel_Chart_Layout + */ + public function setLayoutTarget($value) { + $this->_layoutTarget = $value; + return $this; + } + + /** + * Get X-Mode + * + * @return string + */ + public function getXMode() { + return $this->_xMode; + } + + /** + * Set X-Mode + * + * @param X-Mode $value + * @return PHPExcel_Chart_Layout + */ + public function setXMode($value) { + $this->_xMode = $value; + return $this; + } + + /** + * Get Y-Mode + * + * @return string + */ + public function getYMode() { + return $this->_yMode; + } + + /** + * Set Y-Mode + * + * @param Y-Mode $value + * @return PHPExcel_Chart_Layout + */ + public function setYMode($value) { + $this->_yMode = $value; + return $this; + } + + /** + * Get X-Position + * + * @return number + */ + public function getXPosition() { + return $this->_xPos; + } + + /** + * Set X-Position + * + * @param X-Position $value + * @return PHPExcel_Chart_Layout + */ + public function setXPosition($value) { + $this->_xPos = $value; + return $this; + } + + /** + * Get Y-Position + * + * @return number + */ + public function getYPosition() { + return $this->_yPos; + } + + /** + * Set Y-Position + * + * @param Y-Position $value + * @return PHPExcel_Chart_Layout + */ + public function setYPosition($value) { + $this->_yPos = $value; + return $this; + } + + /** + * Get Width + * + * @return number + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param Width $value + * @return PHPExcel_Chart_Layout + */ + public function setWidth($value) { + $this->_width = $value; + return $this; + } + + /** + * Get Height + * + * @return number + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param Height $value + * @return PHPExcel_Chart_Layout + */ + public function setHeight($value) { + $this->_height = $value; + return $this; + } + + + /** + * Get show legend key + * + * @return boolean + */ + public function getShowLegendKey() { + return $this->_showLegendKey; + } + + /** + * Set show legend key + * Specifies that legend keys should be shown in data labels. + * + * @param boolean $value Show legend key + * @return PHPExcel_Chart_Layout + */ + public function setShowLegendKey($value) { + $this->_showLegendKey = $value; + return $this; + } + + /** + * Get show value + * + * @return boolean + */ + public function getShowVal() { + return $this->_showVal; + } + + /** + * Set show val + * Specifies that the value should be shown in data labels. + * + * @param boolean $value Show val + * @return PHPExcel_Chart_Layout + */ + public function setShowVal($value) { + $this->_showVal = $value; + return $this; + } + + /** + * Get show category name + * + * @return boolean + */ + public function getShowCatName() { + return $this->_showCatName; + } + + /** + * Set show cat name + * Specifies that the category name should be shown in data labels. + * + * @param boolean $value Show cat name + * @return PHPExcel_Chart_Layout + */ + public function setShowCatName($value) { + $this->_showCatName = $value; + return $this; + } + + /** + * Get show data series name + * + * @return boolean + */ + public function getShowSerName() { + return $this->_showSerName; + } + + /** + * Set show ser name + * Specifies that the series name should be shown in data labels. + * + * @param boolean $value Show series name + * @return PHPExcel_Chart_Layout + */ + public function setShowSerName($value) { + $this->_showSerName = $value; + return $this; + } + + /** + * Get show percentage + * + * @return boolean + */ + public function getShowPercent() { + return $this->_showPercent; + } + + /** + * Set show percentage + * Specifies that the percentage should be shown in data labels. + * + * @param boolean $value Show percentage + * @return PHPExcel_Chart_Layout + */ + public function setShowPercent($value) { + $this->_showPercent = $value; + return $this; + } + + /** + * Get show bubble size + * + * @return boolean + */ + public function getShowBubbleSize() { + return $this->_showBubbleSize; + } + + /** + * Set show bubble size + * Specifies that the bubble size should be shown in data labels. + * + * @param boolean $value Show bubble size + * @return PHPExcel_Chart_Layout + */ + public function setShowBubbleSize($value) { + $this->_showBubbleSize = $value; + return $this; + } + + /** + * Get show leader lines + * + * @return boolean + */ + public function getShowLeaderLines() { + return $this->_showLeaderLines; + } + + /** + * Set show leader lines + * Specifies that leader lines should be shown in data labels. + * + * @param boolean $value Show leader lines + * @return PHPExcel_Chart_Layout + */ + public function setShowLeaderLines($value) { + $this->_showLeaderLines = $value; + return $this; + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/Legend.php b/extend/phpexcel/PHPExcel/Chart/Legend.php new file mode 100755 index 0000000..4b7c644 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Legend.php @@ -0,0 +1,171 @@ + self::POSITION_BOTTOM, + self::xlLegendPositionCorner => self::POSITION_TOPRIGHT, + self::xlLegendPositionCustom => '??', + self::xlLegendPositionLeft => self::POSITION_LEFT, + self::xlLegendPositionRight => self::POSITION_RIGHT, + self::xlLegendPositionTop => self::POSITION_TOP + ); + + /** + * Legend position + * + * @var string + */ + private $_position = self::POSITION_RIGHT; + + /** + * Allow overlay of other elements? + * + * @var boolean + */ + private $_overlay = TRUE; + + /** + * Legend Layout + * + * @var PHPExcel_Chart_Layout + */ + private $_layout = NULL; + + + /** + * Create a new PHPExcel_Chart_Legend + */ + public function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE) + { + $this->setPosition($position); + $this->_layout = $layout; + $this->setOverlay($overlay); + } + + /** + * Get legend position as an excel string value + * + * @return string + */ + public function getPosition() { + return $this->_position; + } + + /** + * Get legend position using an excel string value + * + * @param string $position + */ + public function setPosition($position = self::POSITION_RIGHT) { + if (!in_array($position,self::$_positionXLref)) { + return false; + } + + $this->_position = $position; + return true; + } + + /** + * Get legend position as an Excel internal numeric value + * + * @return number + */ + public function getPositionXL() { + return array_search($this->_position,self::$_positionXLref); + } + + /** + * Set legend position using an Excel internal numeric value + * + * @param number $positionXL + */ + public function setPositionXL($positionXL = self::xlLegendPositionRight) { + if (!array_key_exists($positionXL,self::$_positionXLref)) { + return false; + } + + $this->_position = self::$_positionXLref[$positionXL]; + return true; + } + + /** + * Get allow overlay of other elements? + * + * @return boolean + */ + public function getOverlay() { + return $this->_overlay; + } + + /** + * Set allow overlay of other elements? + * + * @param boolean $overlay + * @return boolean + */ + public function setOverlay($overlay = FALSE) { + if (!is_bool($overlay)) { + return false; + } + + $this->_overlay = $overlay; + return true; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/PlotArea.php b/extend/phpexcel/PHPExcel/Chart/PlotArea.php new file mode 100755 index 0000000..237d29b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/PlotArea.php @@ -0,0 +1,128 @@ +_layout = $layout; + $this->_plotSeries = $plotSeries; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + + /** + * Get Number of Plot Groups + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroupCount() { + return count($this->_plotSeries); + } + + /** + * Get Number of Plot Series + * + * @return integer + */ + public function getPlotSeriesCount() { + $seriesCount = 0; + foreach($this->_plotSeries as $plot) { + $seriesCount += $plot->getPlotSeriesCount(); + } + return $seriesCount; + } + + /** + * Get Plot Series + * + * @return array of PHPExcel_Chart_DataSeries + */ + public function getPlotGroup() { + return $this->_plotSeries; + } + + /** + * Get Plot Series by Index + * + * @return PHPExcel_Chart_DataSeries + */ + public function getPlotGroupByIndex($index) { + return $this->_plotSeries[$index]; + } + + /** + * Set Plot Series + * + * @param [PHPExcel_Chart_DataSeries] + * @return PHPExcel_Chart_PlotArea + */ + public function setPlotSeries($plotSeries = array()) { + $this->_plotSeries = $plotSeries; + + return $this; + } + + public function refresh(PHPExcel_Worksheet $worksheet) { + foreach($this->_plotSeries as $plotSeries) { + $plotSeries->refresh($worksheet); + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt b/extend/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt new file mode 100755 index 0000000..20a8258 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt @@ -0,0 +1,17 @@ +ChartDirector + http://www.advsofteng.com/cdphp.html + +GraPHPite + http://graphpite.sourceforge.net/ + +JpGraph + http://www.aditus.nu/jpgraph/ + +LibChart + http://naku.dohcrew.com/libchart/pages/introduction/ + +pChart + http://pchart.sourceforge.net/ + +TeeChart + http://www.steema.com/products/teechart/overview.html diff --git a/extend/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php b/extend/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php new file mode 100755 index 0000000..ae88c62 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Renderer/jpgraph.php @@ -0,0 +1,855 @@ + MARK_DIAMOND, + 'square' => MARK_SQUARE, + 'triangle' => MARK_UTRIANGLE, + 'x' => MARK_X, + 'star' => MARK_STAR, + 'dot' => MARK_FILLEDCIRCLE, + 'dash' => MARK_DTRIANGLE, + 'circle' => MARK_CIRCLE, + 'plus' => MARK_CROSS + ); + + + private $_chart = null; + + private $_graph = null; + + private static $_plotColour = 0; + + private static $_plotMark = 0; + + + private function _formatPointMarker($seriesPlot,$markerID) { + $plotMarkKeys = array_keys(self::$_markSet); + if (is_null($markerID)) { + // Use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } elseif ($markerID !== 'none') { + // Use specified plot marker (if it exists) + if (isset(self::$_markSet[$markerID])) { + $seriesPlot->mark->SetType(self::$_markSet[$markerID]); + } else { + // If the specified plot marker doesn't exist, use default plot marker (next marker in the series) + self::$_plotMark %= count(self::$_markSet); + $seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]); + } + } else { + // Hide plot marker + $seriesPlot->mark->Hide(); + } + $seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + + return $seriesPlot; + } // function _formatPointMarker() + + + private function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') { + $datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode(); + if (!is_null($datasetLabelFormatCode)) { + // Retrieve any label formatting code + $datasetLabelFormatCode = stripslashes($datasetLabelFormatCode); + } + + $testCurrentIndex = 0; + foreach($datasetLabels as $i => $datasetLabel) { + if (is_array($datasetLabel)) { + if ($rotation == 'bar') { + $datasetLabels[$i] = implode(" ",$datasetLabel); + } else { + $datasetLabel = array_reverse($datasetLabel); + $datasetLabels[$i] = implode("\n",$datasetLabel); + } + } else { + // Format labels according to any formatting code + if (!is_null($datasetLabelFormatCode)) { + $datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode); + } + } + ++$testCurrentIndex; + } + + return $datasetLabels; + } // function _formatDataSetLabels() + + + private function _percentageSumCalculation($groupID,$seriesCount) { + // Adjust our values to a percentage value across all series in the group + for($i = 0; $i < $seriesCount; ++$i) { + if ($i == 0) { + $sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + } else { + $nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + foreach($nextValues as $k => $value) { + if (isset($sumValues[$k])) { + $sumValues[$k] += $value; + } else { + $sumValues[$k] = $value; + } + } + } + } + + return $sumValues; + } // function _percentageSumCalculation() + + + private function _percentageAdjustValues($dataValues,$sumValues) { + foreach($dataValues as $k => $dataValue) { + $dataValues[$k] = $dataValue / $sumValues[$k] * 100; + } + + return $dataValues; + } // function _percentageAdjustValues() + + + private function _getCaption($captionElement) { + // Read any caption + $caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL; + // Test if we have a title caption to display + if (!is_null($caption)) { + // If we do, it could be a plain string or an array + if (is_array($caption)) { + // Implode an array to a plain string + $caption = implode('',$caption); + } + } + return $caption; + } // function _getCaption() + + + private function _renderTitle() { + $title = $this->_getCaption($this->_chart->getTitle()); + if (!is_null($title)) { + $this->_graph->title->Set($title); + } + } // function _renderTitle() + + + private function _renderLegend() { + $legend = $this->_chart->getLegend(); + if (!is_null($legend)) { + $legendPosition = $legend->getPosition(); + $legendOverlay = $legend->getOverlay(); + switch ($legendPosition) { + case 'r' : + $this->_graph->legend->SetPos(0.01,0.5,'right','center'); // right + $this->_graph->legend->SetColumns(1); + break; + case 'l' : + $this->_graph->legend->SetPos(0.01,0.5,'left','center'); // left + $this->_graph->legend->SetColumns(1); + break; + case 't' : + $this->_graph->legend->SetPos(0.5,0.01,'center','top'); // top + break; + case 'b' : + $this->_graph->legend->SetPos(0.5,0.99,'center','bottom'); // bottom + break; + default : + $this->_graph->legend->SetPos(0.01,0.01,'right','top'); // top-right + $this->_graph->legend->SetColumns(1); + break; + } + } else { + $this->_graph->legend->Hide(); + } + } // function _renderLegend() + + + private function _renderCartesianPlotArea($type='textlin') { + $this->_graph = new Graph(self::$_width,self::$_height); + $this->_graph->SetScale($type); + + $this->_renderTitle(); + + // Rotate for bar rather than column chart + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection(); + $reverse = ($rotation == 'bar') ? true : false; + + $xAxisLabel = $this->_chart->getXAxisLabel(); + if (!is_null($xAxisLabel)) { + $title = $this->_getCaption($xAxisLabel); + if (!is_null($title)) { + $this->_graph->xaxis->SetTitle($title,'center'); + $this->_graph->xaxis->title->SetMargin(35); + if ($reverse) { + $this->_graph->xaxis->title->SetAngle(90); + $this->_graph->xaxis->title->SetMargin(90); + } + } + } + + $yAxisLabel = $this->_chart->getYAxisLabel(); + if (!is_null($yAxisLabel)) { + $title = $this->_getCaption($yAxisLabel); + if (!is_null($title)) { + $this->_graph->yaxis->SetTitle($title,'center'); + if ($reverse) { + $this->_graph->yaxis->title->SetAngle(0); + $this->_graph->yaxis->title->SetMargin(-55); + } + } + } + } // function _renderCartesianPlotArea() + + + private function _renderPiePlotArea($doughnut = False) { + $this->_graph = new PieGraph(self::$_width,self::$_height); + + $this->_renderTitle(); + } // function _renderPiePlotArea() + + + private function _renderRadarPlotArea() { + $this->_graph = new RadarGraph(self::$_width,self::$_height); + $this->_graph->SetScale('lin'); + + $this->_renderTitle(); + } // function _renderRadarPlotArea() + + + private function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + $seriesPlot = new LinePlot($dataValues); + if ($combination) { + $seriesPlot->SetBarCenter(); + } + + if ($filled) { + $seriesPlot->SetFilled(true); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + } else { + // Set the appropriate plot marker + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + + if ($grouping == 'standard') { + $groupPlot = $seriesPlots; + } else { + $groupPlot = new AccLinePlot($seriesPlots); + } + $this->_graph->Add($groupPlot); + } // function _renderPlotLine() + + + private function _renderPlotBar($groupID, $dimensions = '2d') { + $rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection(); + // Rotate for bar rather than column chart + if (($groupID == 0) && ($rotation == 'bar')) { + $this->_graph->Set90AndMargin(); + } + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); + // Rotate for bar rather than column chart + if ($rotation == 'bar') { + $datasetLabels = array_reverse($datasetLabels); + $this->_graph->yaxis->SetPos('max'); + $this->_graph->yaxis->SetLabelAlign('center','top'); + $this->_graph->yaxis->SetLabelSide(SIDE_RIGHT); + } + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + if ($grouping == 'percentStacked') { + $sumValues = $this->_percentageSumCalculation($groupID,$seriesCount); + } + + // Loop through each data series in turn + for($j = 0; $j < $seriesCount; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + if ($grouping == 'percentStacked') { + $dataValues = $this->_percentageAdjustValues($dataValues,$sumValues); + } + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + // Reverse the $dataValues order for bar rather than column chart + if ($rotation == 'bar') { + $dataValues = array_reverse($dataValues); + } + $seriesPlot = new BarPlot($dataValues); + $seriesPlot->SetColor('black'); + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]); + if ($dimensions == '3d') { + $seriesPlot->SetShadow(); + } + if (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) { + $dataLabel = ''; + } else { + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue(); + } + $seriesPlot->SetLegend($dataLabel); + + $seriesPlots[] = $seriesPlot; + } + // Reverse the plot order for bar rather than column chart + if (($rotation == 'bar') && (!($grouping == 'percentStacked'))) { + $seriesPlots = array_reverse($seriesPlots); + } + + if ($grouping == 'clustered') { + $groupPlot = new GroupBarPlot($seriesPlots); + } elseif ($grouping == 'standard') { + $groupPlot = new GroupBarPlot($seriesPlots); + } else { + $groupPlot = new AccBarPlot($seriesPlots); + if ($dimensions == '3d') { + $groupPlot->SetShadow(); + } + } + + $this->_graph->Add($groupPlot); + } // function _renderPlotBar() + + + private function _renderPlotScatter($groupID,$bubble) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + foreach($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + + $seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY); + if ($scatterStyle == 'lineMarker') { + $seriesPlot->SetLinkPoints(); + $seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]); + } elseif ($scatterStyle == 'smoothMarker') { + $spline = new Spline($dataValuesY,$dataValuesX); + list($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20); + $lplot = new LinePlot($splineDataX,$splineDataY); + $lplot->SetColor(self::$_colourSet[self::$_plotColour]); + + $this->_graph->Add($lplot); + } + + if ($bubble) { + $this->_formatPointMarker($seriesPlot,'dot'); + $seriesPlot->mark->SetColor('black'); + $seriesPlot->mark->SetSize($bubbleSize); + } else { + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + $this->_formatPointMarker($seriesPlot,$marker); + } + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotScatter() + + + private function _renderPlotRadar($groupID) { + $radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + $marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); + + $dataValues = array(); + foreach($dataValuesY as $k => $dataValueY) { + $dataValues[$k] = implode(' ',array_reverse($dataValueY)); + } + $tmp = array_shift($dataValues); + $dataValues[] = $tmp; + $tmp = array_shift($dataValuesX); + $dataValuesX[] = $tmp; + + $this->_graph->SetTitles(array_reverse($dataValues)); + + $seriesPlot = new RadarPlot(array_reverse($dataValuesX)); + + $dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if ($radarStyle == 'filled') { + $seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]); + } + $this->_formatPointMarker($seriesPlot,$marker); + $seriesPlot->SetLegend($dataLabel); + + $this->_graph->Add($seriesPlot); + } + } // function _renderPlotRadar() + + + private function _renderPlotContour($groupID) { + $contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + + $dataValues = array(); + // Loop through each data series in turn + for($i = 0; $i < $seriesCount; ++$i) { + $dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); + + $dataValues[$i] = $dataValuesX; + } + $seriesPlot = new ContourPlot($dataValues); + + $this->_graph->Add($seriesPlot); + } // function _renderPlotContour() + + + private function _renderPlotStock($groupID) { + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder(); + + $dataValues = array(); + // Loop through each data series in turn and build the plot arrays + foreach($plotOrder as $i => $v) { + $dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); + foreach($dataValuesX as $j => $dataValueX) { + $dataValues[$plotOrder[$i]][$j] = $dataValueX; + } + } + if(empty($dataValues)) { + return; + } + + $dataValuesPlot = array(); + // Flatten the plot arrays to a single dimensional array to work with jpgraph + for($j = 0; $j < count($dataValues[0]); $j++) { + for($i = 0; $i < $seriesCount; $i++) { + $dataValuesPlot[] = $dataValues[$i][$j]; + } + } + + // Set the x-axis labels + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + $this->_graph->xaxis->SetTickLabels($datasetLabels); + } + + $seriesPlot = new StockPlot($dataValuesPlot); + $seriesPlot->SetWidth(20); + + $this->_graph->Add($seriesPlot); + } // function _renderPlotStock() + + + private function _renderAreaChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,True,False,$dimensions); + } + } // function _renderAreaChart() + + + private function _renderLineChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotLine($i,False,False,$dimensions); + } + } // function _renderLineChart() + + + private function _renderBarChart($groupCount, $dimensions = '2d') { + require_once('jpgraph_bar.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotBar($i,$dimensions); + } + } // function _renderBarChart() + + + private function _renderScatterChart($groupCount) { + require_once('jpgraph_scatter.php'); + require_once('jpgraph_regstat.php'); + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea('linlin'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,false); + } + } // function _renderScatterChart() + + + private function _renderBubbleChart($groupCount) { + require_once('jpgraph_scatter.php'); + + $this->_renderCartesianPlotArea('linlin'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotScatter($i,true); + } + } // function _renderBubbleChart() + + + private function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) { + require_once('jpgraph_pie.php'); + if ($dimensions == '3d') { + require_once('jpgraph_pie3d.php'); + } + + $this->_renderPiePlotArea($doughnut); + + $iLimit = ($multiplePlots) ? $groupCount : 1; + for($groupID = 0; $groupID < $iLimit; ++$groupID) { + $grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); + $exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle(); + if ($groupID == 0) { + $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount()); + if ($labelCount > 0) { + $datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); + $datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount); + } + } + + $seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount(); + $seriesPlots = array(); + // For pie charts, we only display the first series: doughnut charts generally display all series + $jLimit = ($multiplePlots) ? $seriesCount : 1; + // Loop through each data series in turn + for($j = 0; $j < $jLimit; ++$j) { + $dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); + + // Fill in any missing values in the $dataValues array + $testCurrentIndex = 0; + foreach($dataValues as $k => $dataValue) { + while($k != $testCurrentIndex) { + $dataValues[$testCurrentIndex] = null; + ++$testCurrentIndex; + } + ++$testCurrentIndex; + } + + if ($dimensions == '3d') { + $seriesPlot = new PiePlot3D($dataValues); + } else { + if ($doughnut) { + $seriesPlot = new PiePlotC($dataValues); + } else { + $seriesPlot = new PiePlot($dataValues); + } + } + + if ($multiplePlots) { + $seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4)); + } + + if ($doughnut) { + $seriesPlot->SetMidColor('white'); + } + + $seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]); + if (count($datasetLabels) > 0) + $seriesPlot->SetLabels(array_fill(0,count($datasetLabels),'')); + if ($dimensions != '3d') { + $seriesPlot->SetGuideLines(false); + } + if ($j == 0) { + if ($exploded) { + $seriesPlot->ExplodeAll(); + } + $seriesPlot->SetLegends($datasetLabels); + } + + $this->_graph->Add($seriesPlot); + } + } + } // function _renderPieChart() + + + private function _renderRadarChart($groupCount) { + require_once('jpgraph_radar.php'); + + $this->_renderRadarPlotArea(); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotRadar($groupID); + } + } // function _renderRadarChart() + + + private function _renderStockChart($groupCount) { + require_once('jpgraph_stock.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($groupID = 0; $groupID < $groupCount; ++$groupID) { + $this->_renderPlotStock($groupID); + } + } // function _renderStockChart() + + + private function _renderContourChart($groupCount,$dimensions) { + require_once('jpgraph_contour.php'); + + $this->_renderCartesianPlotArea('intint'); + + for($i = 0; $i < $groupCount; ++$i) { + $this->_renderPlotContour($i); + } + } // function _renderContourChart() + + + private function _renderCombinationChart($groupCount,$dimensions,$outputDestination) { + require_once('jpgraph_line.php'); + require_once('jpgraph_bar.php'); + require_once('jpgraph_scatter.php'); + require_once('jpgraph_regstat.php'); + require_once('jpgraph_line.php'); + + $this->_renderCartesianPlotArea(); + + for($i = 0; $i < $groupCount; ++$i) { + $dimensions = null; + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderPlotLine($i,True,True,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderPlotBar($i,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderPlotLine($i,False,True,$dimensions); + break; + case 'scatterChart' : + $this->_renderPlotScatter($i,false); + break; + case 'bubbleChart' : + $this->_renderPlotScatter($i,true); + break; + default : + $this->_graph = null; + return false; + } + } + + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function _renderCombinationChart() + + + public function render($outputDestination) { + self::$_plotColour = 0; + + $groupCount = $this->_chart->getPlotArea()->getPlotGroupCount(); + + $dimensions = null; + if ($groupCount == 1) { + $chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType(); + } else { + $chartTypes = array(); + for($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType(); + } + $chartTypes = array_unique($chartTypes); + if (count($chartTypes) == 1) { + $chartType = array_pop($chartTypes); + } elseif (count($chartTypes) == 0) { + echo 'Chart is not yet implemented
'; + return false; + } else { + return $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination); + } + } + + switch ($chartType) { + case 'area3DChart' : + $dimensions = '3d'; + case 'areaChart' : + $this->_renderAreaChart($groupCount,$dimensions); + break; + case 'bar3DChart' : + $dimensions = '3d'; + case 'barChart' : + $this->_renderBarChart($groupCount,$dimensions); + break; + case 'line3DChart' : + $dimensions = '3d'; + case 'lineChart' : + $this->_renderLineChart($groupCount,$dimensions); + break; + case 'pie3DChart' : + $dimensions = '3d'; + case 'pieChart' : + $this->_renderPieChart($groupCount,$dimensions,False,False); + break; + case 'doughnut3DChart' : + $dimensions = '3d'; + case 'doughnutChart' : + $this->_renderPieChart($groupCount,$dimensions,True,True); + break; + case 'scatterChart' : + $this->_renderScatterChart($groupCount); + break; + case 'bubbleChart' : + $this->_renderBubbleChart($groupCount); + break; + case 'radarChart' : + $this->_renderRadarChart($groupCount); + break; + case 'surface3DChart' : + $dimensions = '3d'; + case 'surfaceChart' : + $this->_renderContourChart($groupCount,$dimensions); + break; + case 'stockChart' : + $this->_renderStockChart($groupCount,$dimensions); + break; + default : + echo $chartType.' is not yet implemented
'; + return false; + } + $this->_renderLegend(); + + $this->_graph->Stroke($outputDestination); + return true; + } // function render() + + + /** + * Create a new PHPExcel_Chart_Renderer_jpgraph + */ + public function __construct(PHPExcel_Chart $chart) + { + $this->_graph = null; + $this->_chart = $chart; + } // function __construct() + +} // PHPExcel_Chart_Renderer_jpgraph diff --git a/extend/phpexcel/PHPExcel/Chart/Title.php b/extend/phpexcel/PHPExcel/Chart/Title.php new file mode 100755 index 0000000..415551b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Chart/Title.php @@ -0,0 +1,92 @@ +_caption = $caption; + $this->_layout = $layout; + } + + /** + * Get caption + * + * @return string + */ + public function getCaption() { + return $this->_caption; + } + + /** + * Set caption + * + * @param string $caption + * @return PHPExcel_Chart_Title + */ + public function setCaption($caption = null) { + $this->_caption = $caption; + + return $this; + } + + /** + * Get Layout + * + * @return PHPExcel_Chart_Layout + */ + public function getLayout() { + return $this->_layout; + } + +} diff --git a/extend/phpexcel/PHPExcel/Comment.php b/extend/phpexcel/PHPExcel/Comment.php new file mode 100755 index 0000000..a2422c6 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Comment.php @@ -0,0 +1,327 @@ +_author = 'Author'; + $this->_text = new PHPExcel_RichText(); + $this->_fillColor = new PHPExcel_Style_Color('FFFFFFE1'); + $this->_alignment = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + } + + /** + * Get Author + * + * @return string + */ + public function getAuthor() { + return $this->_author; + } + + /** + * Set Author + * + * @param string $pValue + * @return PHPExcel_Comment + */ + public function setAuthor($pValue = '') { + $this->_author = $pValue; + return $this; + } + + /** + * Get Rich text comment + * + * @return PHPExcel_RichText + */ + public function getText() { + return $this->_text; + } + + /** + * Set Rich text comment + * + * @param PHPExcel_RichText $pValue + * @return PHPExcel_Comment + */ + public function setText(PHPExcel_RichText $pValue) { + $this->_text = $pValue; + return $this; + } + + /** + * Get comment width (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set comment width (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setWidth($value = '96pt') { + $this->_width = $value; + return $this; + } + + /** + * Get comment height (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set comment height (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setHeight($value = '55.5pt') { + $this->_height = $value; + return $this; + } + + /** + * Get left margin (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getMarginLeft() { + return $this->_marginLeft; + } + + /** + * Set left margin (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setMarginLeft($value = '59.25pt') { + $this->_marginLeft = $value; + return $this; + } + + /** + * Get top margin (CSS style, i.e. XXpx or YYpt) + * + * @return string + */ + public function getMarginTop() { + return $this->_marginTop; + } + + /** + * Set top margin (CSS style, i.e. XXpx or YYpt) + * + * @param string $value + * @return PHPExcel_Comment + */ + public function setMarginTop($value = '1.5pt') { + $this->_marginTop = $value; + return $this; + } + + /** + * Is the comment visible by default? + * + * @return boolean + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set comment default visibility + * + * @param boolean $value + * @return PHPExcel_Comment + */ + public function setVisible($value = false) { + $this->_visible = $value; + return $this; + } + + /** + * Get fill color + * + * @return PHPExcel_Style_Color + */ + public function getFillColor() { + return $this->_fillColor; + } + + /** + * Set Alignment + * + * @param string $pValue + * @return PHPExcel_Comment + */ + public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { + $this->_alignment = $pValue; + return $this; + } + + /** + * Get Alignment + * + * @return string + */ + public function getAlignment() { + return $this->_alignment; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_author + . $this->_text->getHashCode() + . $this->_width + . $this->_height + . $this->_marginLeft + . $this->_marginTop + . ($this->_visible ? 1 : 0) + . $this->_fillColor->getHashCode() + . $this->_alignment + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() { + return $this->_text->getPlainText(); + } + +} diff --git a/extend/phpexcel/PHPExcel/DocumentProperties.php b/extend/phpexcel/PHPExcel/DocumentProperties.php new file mode 100755 index 0000000..2f1fa1e --- /dev/null +++ b/extend/phpexcel/PHPExcel/DocumentProperties.php @@ -0,0 +1,587 @@ +_lastModifiedBy = $this->_creator; + $this->_created = time(); + $this->_modified = time(); + } + + /** + * Get Creator + * + * @return string + */ + public function getCreator() { + return $this->_creator; + } + + /** + * Set Creator + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCreator($pValue = '') { + $this->_creator = $pValue; + return $this; + } + + /** + * Get Last Modified By + * + * @return string + */ + public function getLastModifiedBy() { + return $this->_lastModifiedBy; + } + + /** + * Set Last Modified By + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setLastModifiedBy($pValue = '') { + $this->_lastModifiedBy = $pValue; + return $this; + } + + /** + * Get Created + * + * @return datetime + */ + public function getCreated() { + return $this->_created; + } + + /** + * Set Created + * + * @param datetime $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCreated($pValue = null) { + if ($pValue === NULL) { + $pValue = time(); + } elseif (is_string($pValue)) { + if (is_numeric($pValue)) { + $pValue = intval($pValue); + } else { + $pValue = strtotime($pValue); + } + } + + $this->_created = $pValue; + return $this; + } + + /** + * Get Modified + * + * @return datetime + */ + public function getModified() { + return $this->_modified; + } + + /** + * Set Modified + * + * @param datetime $pValue + * @return PHPExcel_DocumentProperties + */ + public function setModified($pValue = null) { + if ($pValue === NULL) { + $pValue = time(); + } elseif (is_string($pValue)) { + if (is_numeric($pValue)) { + $pValue = intval($pValue); + } else { + $pValue = strtotime($pValue); + } + } + + $this->_modified = $pValue; + return $this; + } + + /** + * Get Title + * + * @return string + */ + public function getTitle() { + return $this->_title; + } + + /** + * Set Title + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setTitle($pValue = '') { + $this->_title = $pValue; + return $this; + } + + /** + * Get Description + * + * @return string + */ + public function getDescription() { + return $this->_description; + } + + /** + * Set Description + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setDescription($pValue = '') { + $this->_description = $pValue; + return $this; + } + + /** + * Get Subject + * + * @return string + */ + public function getSubject() { + return $this->_subject; + } + + /** + * Set Subject + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setSubject($pValue = '') { + $this->_subject = $pValue; + return $this; + } + + /** + * Get Keywords + * + * @return string + */ + public function getKeywords() { + return $this->_keywords; + } + + /** + * Set Keywords + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setKeywords($pValue = '') { + $this->_keywords = $pValue; + return $this; + } + + /** + * Get Category + * + * @return string + */ + public function getCategory() { + return $this->_category; + } + + /** + * Set Category + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCategory($pValue = '') { + $this->_category = $pValue; + return $this; + } + + /** + * Get Company + * + * @return string + */ + public function getCompany() { + return $this->_company; + } + + /** + * Set Company + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setCompany($pValue = '') { + $this->_company = $pValue; + return $this; + } + + /** + * Get Manager + * + * @return string + */ + public function getManager() { + return $this->_manager; + } + + /** + * Set Manager + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setManager($pValue = '') { + $this->_manager = $pValue; + return $this; + } + + /** + * Get a List of Custom Property Names + * + * @return array of string + */ + public function getCustomProperties() { + return array_keys($this->_customProperties); + } + + /** + * Check if a Custom Property is defined + * + * @param string $propertyName + * @return boolean + */ + public function isCustomPropertySet($propertyName) { + return isset($this->_customProperties[$propertyName]); + } + + /** + * Get a Custom Property Value + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyValue($propertyName) { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['value']; + } + + } + + /** + * Get a Custom Property Type + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyType($propertyName) { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['type']; + } + + } + + /** + * Set a Custom Property + * + * @param string $propertyName + * @param mixed $propertyValue + * @param string $propertyType + * 'i' : Integer + * 'f' : Floating Point + * 's' : String + * 'd' : Date/Time + * 'b' : Boolean + * @return PHPExcel_DocumentProperties + */ + public function setCustomProperty($propertyName,$propertyValue='',$propertyType=NULL) { + if (($propertyType === NULL) || (!in_array($propertyType,array(self::PROPERTY_TYPE_INTEGER, + self::PROPERTY_TYPE_FLOAT, + self::PROPERTY_TYPE_STRING, + self::PROPERTY_TYPE_DATE, + self::PROPERTY_TYPE_BOOLEAN)))) { + if ($propertyValue === NULL) { + $propertyType = self::PROPERTY_TYPE_STRING; + } elseif (is_float($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_FLOAT; + } elseif(is_int($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_INTEGER; + } elseif (is_bool($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_BOOLEAN; + } else { + $propertyType = self::PROPERTY_TYPE_STRING; + } + } + + $this->_customProperties[$propertyName] = array('value' => $propertyValue, 'type' => $propertyType); + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + + public static function convertProperty($propertyValue,$propertyType) { + switch ($propertyType) { + case 'empty' : // Empty + return ''; + break; + case 'null' : // Null + return NULL; + break; + case 'i1' : // 1-Byte Signed Integer + case 'i2' : // 2-Byte Signed Integer + case 'i4' : // 4-Byte Signed Integer + case 'i8' : // 8-Byte Signed Integer + case 'int' : // Integer + return (int) $propertyValue; + break; + case 'ui1' : // 1-Byte Unsigned Integer + case 'ui2' : // 2-Byte Unsigned Integer + case 'ui4' : // 4-Byte Unsigned Integer + case 'ui8' : // 8-Byte Unsigned Integer + case 'uint' : // Unsigned Integer + return abs((int) $propertyValue); + break; + case 'r4' : // 4-Byte Real Number + case 'r8' : // 8-Byte Real Number + case 'decimal' : // Decimal + return (float) $propertyValue; + break; + case 'lpstr' : // LPSTR + case 'lpwstr' : // LPWSTR + case 'bstr' : // Basic String + return $propertyValue; + break; + case 'date' : // Date and Time + case 'filetime' : // File Time + return strtotime($propertyValue); + break; + case 'bool' : // Boolean + return ($propertyValue == 'true') ? True : False; + break; + case 'cy' : // Currency + case 'error' : // Error Status Code + case 'vector' : // Vector + case 'array' : // Array + case 'blob' : // Binary Blob + case 'oblob' : // Binary Blob Object + case 'stream' : // Binary Stream + case 'ostream' : // Binary Stream Object + case 'storage' : // Binary Storage + case 'ostorage' : // Binary Storage Object + case 'vstream' : // Binary Versioned Stream + case 'clsid' : // Class ID + case 'cf' : // Clipboard Data + return $propertyValue; + break; + } + return $propertyValue; + } + + public static function convertPropertyType($propertyType) { + switch ($propertyType) { + case 'i1' : // 1-Byte Signed Integer + case 'i2' : // 2-Byte Signed Integer + case 'i4' : // 4-Byte Signed Integer + case 'i8' : // 8-Byte Signed Integer + case 'int' : // Integer + case 'ui1' : // 1-Byte Unsigned Integer + case 'ui2' : // 2-Byte Unsigned Integer + case 'ui4' : // 4-Byte Unsigned Integer + case 'ui8' : // 8-Byte Unsigned Integer + case 'uint' : // Unsigned Integer + return self::PROPERTY_TYPE_INTEGER; + break; + case 'r4' : // 4-Byte Real Number + case 'r8' : // 8-Byte Real Number + case 'decimal' : // Decimal + return self::PROPERTY_TYPE_FLOAT; + break; + case 'empty' : // Empty + case 'null' : // Null + case 'lpstr' : // LPSTR + case 'lpwstr' : // LPWSTR + case 'bstr' : // Basic String + return self::PROPERTY_TYPE_STRING; + break; + case 'date' : // Date and Time + case 'filetime' : // File Time + return self::PROPERTY_TYPE_DATE; + break; + case 'bool' : // Boolean + return self::PROPERTY_TYPE_BOOLEAN; + break; + case 'cy' : // Currency + case 'error' : // Error Status Code + case 'vector' : // Vector + case 'array' : // Array + case 'blob' : // Binary Blob + case 'oblob' : // Binary Blob Object + case 'stream' : // Binary Stream + case 'ostream' : // Binary Stream Object + case 'storage' : // Binary Storage + case 'ostorage' : // Binary Storage Object + case 'vstream' : // Binary Versioned Stream + case 'clsid' : // Class ID + case 'cf' : // Clipboard Data + return self::PROPERTY_TYPE_UNKNOWN; + break; + } + return self::PROPERTY_TYPE_UNKNOWN; + } + +} diff --git a/extend/phpexcel/PHPExcel/DocumentSecurity.php b/extend/phpexcel/PHPExcel/DocumentSecurity.php new file mode 100755 index 0000000..340504e --- /dev/null +++ b/extend/phpexcel/PHPExcel/DocumentSecurity.php @@ -0,0 +1,218 @@ +_lockRevision = false; + $this->_lockStructure = false; + $this->_lockWindows = false; + $this->_revisionsPassword = ''; + $this->_workbookPassword = ''; + } + + /** + * Is some sort of dcument security enabled? + * + * @return boolean + */ + function isSecurityEnabled() { + return $this->_lockRevision || + $this->_lockStructure || + $this->_lockWindows; + } + + /** + * Get LockRevision + * + * @return boolean + */ + function getLockRevision() { + return $this->_lockRevision; + } + + /** + * Set LockRevision + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockRevision($pValue = false) { + $this->_lockRevision = $pValue; + return $this; + } + + /** + * Get LockStructure + * + * @return boolean + */ + function getLockStructure() { + return $this->_lockStructure; + } + + /** + * Set LockStructure + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockStructure($pValue = false) { + $this->_lockStructure = $pValue; + return $this; + } + + /** + * Get LockWindows + * + * @return boolean + */ + function getLockWindows() { + return $this->_lockWindows; + } + + /** + * Set LockWindows + * + * @param boolean $pValue + * @return PHPExcel_DocumentSecurity + */ + function setLockWindows($pValue = false) { + $this->_lockWindows = $pValue; + return $this; + } + + /** + * Get RevisionsPassword (hashed) + * + * @return string + */ + function getRevisionsPassword() { + return $this->_revisionsPassword; + } + + /** + * Set RevisionsPassword + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_DocumentSecurity + */ + function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_revisionsPassword = $pValue; + return $this; + } + + /** + * Get WorkbookPassword (hashed) + * + * @return string + */ + function getWorkbookPassword() { + return $this->_workbookPassword; + } + + /** + * Set WorkbookPassword + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_DocumentSecurity + */ + function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_workbookPassword = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Exception.php b/extend/phpexcel/PHPExcel/Exception.php new file mode 100755 index 0000000..683e909 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Exception.php @@ -0,0 +1,52 @@ +line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/extend/phpexcel/PHPExcel/HashTable.php b/extend/phpexcel/PHPExcel/HashTable.php new file mode 100755 index 0000000..7a9205e --- /dev/null +++ b/extend/phpexcel/PHPExcel/HashTable.php @@ -0,0 +1,202 @@ +addFromSource($pSource); + } + } + + /** + * Add HashTable items from source + * + * @param PHPExcel_IComparable[] $pSource Source array to create HashTable from + * @throws PHPExcel_Exception + */ + public function addFromSource($pSource = null) { + // Check if an array was passed + if ($pSource == null) { + return; + } else if (!is_array($pSource)) { + throw new PHPExcel_Exception('Invalid array parameter passed.'); + } + + foreach ($pSource as $item) { + $this->add($item); + } + } + + /** + * Add HashTable item + * + * @param PHPExcel_IComparable $pSource Item to add + * @throws PHPExcel_Exception + */ + public function add(PHPExcel_IComparable $pSource = null) { + $hash = $pSource->getHashCode(); + if (!isset($this->_items[$hash])) { + $this->_items[$hash] = $pSource; + $this->_keyMap[count($this->_items) - 1] = $hash; + } + } + + /** + * Remove HashTable item + * + * @param PHPExcel_IComparable $pSource Item to remove + * @throws PHPExcel_Exception + */ + public function remove(PHPExcel_IComparable $pSource = null) { + $hash = $pSource->getHashCode(); + if (isset($this->_items[$hash])) { + unset($this->_items[$hash]); + + $deleteKey = -1; + foreach ($this->_keyMap as $key => $value) { + if ($deleteKey >= 0) { + $this->_keyMap[$key - 1] = $value; + } + + if ($value == $hash) { + $deleteKey = $key; + } + } + unset($this->_keyMap[count($this->_keyMap) - 1]); + } + } + + /** + * Clear HashTable + * + */ + public function clear() { + $this->_items = array(); + $this->_keyMap = array(); + } + + /** + * Count + * + * @return int + */ + public function count() { + return count($this->_items); + } + + /** + * Get index for hash code + * + * @param string $pHashCode + * @return int Index + */ + public function getIndexForHashCode($pHashCode = '') { + return array_search($pHashCode, $this->_keyMap); + } + + /** + * Get by index + * + * @param int $pIndex + * @return PHPExcel_IComparable + * + */ + public function getByIndex($pIndex = 0) { + if (isset($this->_keyMap[$pIndex])) { + return $this->getByHashCode( $this->_keyMap[$pIndex] ); + } + + return null; + } + + /** + * Get by hashcode + * + * @param string $pHashCode + * @return PHPExcel_IComparable + * + */ + public function getByHashCode($pHashCode = '') { + if (isset($this->_items[$pHashCode])) { + return $this->_items[$pHashCode]; + } + + return null; + } + + /** + * HashTable to array + * + * @return PHPExcel_IComparable[] + */ + public function toArray() { + return $this->_items; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/IComparable.php b/extend/phpexcel/PHPExcel/IComparable.php new file mode 100755 index 0000000..6b1e18a --- /dev/null +++ b/extend/phpexcel/PHPExcel/IComparable.php @@ -0,0 +1,43 @@ + 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ), + array( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' ) + ); + + /** + * Autoresolve classes + * + * @var array + * @access private + * @static + */ + private static $_autoResolveClasses = array( + 'Excel2007', + 'Excel5', + 'Excel2003XML', + 'OOCalc', + 'SYLK', + 'Gnumeric', + 'HTML', + 'CSV', + ); + + /** + * Private constructor for PHPExcel_IOFactory + */ + private function __construct() { } + + /** + * Get search locations + * + * @static + * @access public + * @return array + */ + public static function getSearchLocations() { + return self::$_searchLocations; + } // function getSearchLocations() + + /** + * Set search locations + * + * @static + * @access public + * @param array $value + * @throws PHPExcel_Reader_Exception + */ + public static function setSearchLocations($value) { + if (is_array($value)) { + self::$_searchLocations = $value; + } else { + throw new PHPExcel_Reader_Exception('Invalid parameter passed.'); + } + } // function setSearchLocations() + + /** + * Add search location + * + * @static + * @access public + * @param string $type Example: IWriter + * @param string $location Example: PHPExcel/Writer/{0}.php + * @param string $classname Example: PHPExcel_Writer_{0} + */ + public static function addSearchLocation($type = '', $location = '', $classname = '') { + self::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname ); + } // function addSearchLocation() + + /** + * Create PHPExcel_Writer_IWriter + * + * @static + * @access public + * @param PHPExcel $phpExcel + * @param string $writerType Example: Excel2007 + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Reader_Exception + */ + public static function createWriter(PHPExcel $phpExcel, $writerType = '') { + // Search type + $searchType = 'IWriter'; + + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $writerType, $searchLocation['class']); + + $instance = new $className($phpExcel); + if ($instance !== NULL) { + return $instance; + } + } + } + + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $writerType"); + } // function createWriter() + + /** + * Create PHPExcel_Reader_IReader + * + * @static + * @access public + * @param string $readerType Example: Excel2007 + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReader($readerType = '') { + // Search type + $searchType = 'IReader'; + + // Include class + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $readerType, $searchLocation['class']); + + $instance = new $className(); + if ($instance !== NULL) { + return $instance; + } + } + } + + // Nothing found... + throw new PHPExcel_Reader_Exception("No $searchType found for type $readerType"); + } // function createReader() + + /** + * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public static function load($pFilename) { + $reader = self::createReaderForFile($pFilename); + return $reader->load($pFilename); + } // function load() + + /** + * Identify file type using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file to identify + * @return string + * @throws PHPExcel_Reader_Exception + */ + public static function identify($pFilename) { + $reader = self::createReaderForFile($pFilename); + $className = get_class($reader); + $classType = explode('_',$className); + unset($reader); + return array_pop($classType); + } // function identify() + + /** + * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution + * + * @static + * @access public + * @param string $pFilename The name of the spreadsheet file + * @return PHPExcel_Reader_IReader + * @throws PHPExcel_Reader_Exception + */ + public static function createReaderForFile($pFilename) { + + // First, lucky guess by inspecting file extension + $pathinfo = pathinfo($pFilename); + + $extensionType = NULL; + if (isset($pathinfo['extension'])) { + switch (strtolower($pathinfo['extension'])) { + case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet + case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded) + case 'xltx': // Excel (OfficeOpenXML) Template + case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded) + $extensionType = 'Excel2007'; + break; + case 'xls': // Excel (BIFF) Spreadsheet + case 'xlt': // Excel (BIFF) Template + $extensionType = 'Excel5'; + break; + case 'ods': // Open/Libre Offic Calc + case 'ots': // Open/Libre Offic Calc Template + $extensionType = 'OOCalc'; + break; + case 'slk': + $extensionType = 'SYLK'; + break; + case 'xml': // Excel 2003 SpreadSheetML + $extensionType = 'Excel2003XML'; + break; + case 'gnumeric': + $extensionType = 'Gnumeric'; + break; + case 'htm': + case 'html': + $extensionType = 'HTML'; + break; + case 'csv': + // Do nothing + // We must not try to use CSV reader since it loads + // all files including Excel files etc. + break; + default: + break; + } + + if ($extensionType !== NULL) { + $reader = self::createReader($extensionType); + // Let's see if we are lucky + if (isset($reader) && $reader->canRead($pFilename)) { + return $reader; + } + } + } + + // If we reach here then "lucky guess" didn't give any result + // Try walking through all the options in self::$_autoResolveClasses + foreach (self::$_autoResolveClasses as $autoResolveClass) { + // Ignore our original guess, we know that won't work + if ($autoResolveClass !== $extensionType) { + $reader = self::createReader($autoResolveClass); + if ($reader->canRead($pFilename)) { + return $reader; + } + } + } + + throw new PHPExcel_Reader_Exception('Unable to identify a reader for this file'); + } // function createReaderForFile() +} diff --git a/extend/phpexcel/PHPExcel/NamedRange.php b/extend/phpexcel/PHPExcel/NamedRange.php new file mode 100755 index 0000000..3ad5caa --- /dev/null +++ b/extend/phpexcel/PHPExcel/NamedRange.php @@ -0,0 +1,246 @@ +_worksheet) + * + * @var bool + */ + private $_localOnly; + + /** + * Scope + * + * @var PHPExcel_Worksheet + */ + private $_scope; + + /** + * Create a new NamedRange + * + * @param string $pName + * @param PHPExcel_Worksheet $pWorksheet + * @param string $pRange + * @param bool $pLocalOnly + * @param PHPExcel_Worksheet|null $pScope Scope. Only applies when $pLocalOnly = true. Null for global scope. + * @throws PHPExcel_Exception + */ + public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null) + { + // Validate data + if (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) { + throw new PHPExcel_Exception('Parameters can not be null.'); + } + + // Set local members + $this->_name = $pName; + $this->_worksheet = $pWorksheet; + $this->_range = $pRange; + $this->_localOnly = $pLocalOnly; + $this->_scope = ($pLocalOnly == true) ? + (($pScope == null) ? $pWorksheet : $pScope) : null; + } + + /** + * Get name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set name + * + * @param string $value + * @return PHPExcel_NamedRange + */ + public function setName($value = null) { + if ($value !== NULL) { + // Old title + $oldTitle = $this->_name; + + // Re-attach + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet); + } + $this->_name = $value; + + if ($this->_worksheet !== NULL) { + $this->_worksheet->getParent()->addNamedRange($this); + } + + // New title + $newTitle = $this->_name; + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle); + } + return $this; + } + + /** + * Get worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set worksheet + * + * @param PHPExcel_Worksheet $value + * @return PHPExcel_NamedRange + */ + public function setWorksheet(PHPExcel_Worksheet $value = null) { + if ($value !== NULL) { + $this->_worksheet = $value; + } + return $this; + } + + /** + * Get range + * + * @return string + */ + public function getRange() { + return $this->_range; + } + + /** + * Set range + * + * @param string $value + * @return PHPExcel_NamedRange + */ + public function setRange($value = null) { + if ($value !== NULL) { + $this->_range = $value; + } + return $this; + } + + /** + * Get localOnly + * + * @return bool + */ + public function getLocalOnly() { + return $this->_localOnly; + } + + /** + * Set localOnly + * + * @param bool $value + * @return PHPExcel_NamedRange + */ + public function setLocalOnly($value = false) { + $this->_localOnly = $value; + $this->_scope = $value ? $this->_worksheet : null; + return $this; + } + + /** + * Get scope + * + * @return PHPExcel_Worksheet|null + */ + public function getScope() { + return $this->_scope; + } + + /** + * Set scope + * + * @param PHPExcel_Worksheet|null $value + * @return PHPExcel_NamedRange + */ + public function setScope(PHPExcel_Worksheet $value = null) { + $this->_scope = $value; + $this->_localOnly = ($value == null) ? false : true; + return $this; + } + + /** + * Resolve a named range to a regular cell range + * + * @param string $pNamedRange Named range + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope + * @return PHPExcel_NamedRange + */ + public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) { + return $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Reader/Abstract.php b/extend/phpexcel/PHPExcel/Reader/Abstract.php new file mode 100755 index 0000000..0d5180c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Abstract.php @@ -0,0 +1,227 @@ +_readDataOnly; + } + + /** + * Set read data only + * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. + * Set to false (the default) to advise the Reader to read both data and formatting for cells. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setReadDataOnly($pValue = FALSE) { + $this->_readDataOnly = $pValue; + return $this; + } + + /** + * Read charts in workbook? + * If this is true, then the Reader will include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * If false (the default) it will ignore any charts defined in the workbook file. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } + + /** + * Set read charts in workbook + * Set to true, to advise the Reader to include any charts that exist in the workbook. + * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. + * Set to false (the default) to discard charts. + * + * @param boolean $pValue + * + * @return PHPExcel_Reader_IReader + */ + public function setIncludeCharts($pValue = FALSE) { + $this->_includeCharts = (boolean) $pValue; + return $this; + } + + /** + * Get which sheets to load + * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null + * indicating that all worksheets in the workbook should be loaded. + * + * @return mixed + */ + public function getLoadSheetsOnly() + { + return $this->_loadSheetsOnly; + } + + /** + * Set which sheets to load + * + * @param mixed $value + * This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. + * If NULL, then it tells the Reader to read all worksheets in the workbook + * + * @return PHPExcel_Reader_IReader + */ + public function setLoadSheetsOnly($value = NULL) + { + $this->_loadSheetsOnly = is_array($value) ? + $value : array($value); + return $this; + } + + /** + * Set all sheets to load + * Tells the Reader to load all worksheets from the workbook. + * + * @return PHPExcel_Reader_IReader + */ + public function setLoadAllSheets() + { + $this->_loadSheetsOnly = NULL; + return $this; + } + + /** + * Read filter + * + * @return PHPExcel_Reader_IReadFilter + */ + public function getReadFilter() { + return $this->_readFilter; + } + + /** + * Set read filter + * + * @param PHPExcel_Reader_IReadFilter $pValue + * @return PHPExcel_Reader_IReader + */ + public function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) { + $this->_readFilter = $pValue; + return $this; + } + + /** + * Open file for reading + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + * @return resource + */ + protected function _openFile($pFilename) + { + // Check if file exists + if (!file_exists($pFilename) || !is_readable($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Open file + $this->_fileHandle = fopen($pFilename, 'r'); + if ($this->_fileHandle === FALSE) { + throw new PHPExcel_Reader_Exception("Could not open file " . $pFilename . " for reading."); + } + } + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + try { + $this->_openFile($pFilename); + } catch (Exception $e) { + return FALSE; + } + + $readable = $this->_isValidFormat(); + fclose ($this->_fileHandle); + return $readable; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/CSV.php b/extend/phpexcel/PHPExcel/Reader/CSV.php new file mode 100755 index 0000000..8bf7b84 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/CSV.php @@ -0,0 +1,415 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a CSV file + * + * @return boolean + */ + protected function _isValidFormat() + { + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'UTF-8') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Move filepointer past any BOM marker + * + */ + protected function _skipBOM() + { + rewind($this->_fileHandle); + + switch ($this->_inputEncoding) { + case 'UTF-8': + fgets($this->_fileHandle, 4) == "\xEF\xBB\xBF" ? + fseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16LE': + fgets($this->_fileHandle, 3) == "\xFF\xFE" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-16BE': + fgets($this->_fileHandle, 3) == "\xFE\xFF" ? + fseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32LE': + fgets($this->_fileHandle, 5) == "\xFF\xFE\x00\x00" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + case 'UTF-32BE': + fgets($this->_fileHandle, 5) == "\x00\x00\xFE\xFF" ? + fseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0); + break; + default: + break; + } + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + $escapeEnclosures = array( "\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure ); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $worksheetInfo[0]['totalRows']++; + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $lineEnding = ini_get('auto_detect_line_endings'); + ini_set('auto_detect_line_endings', true); + + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + + // Skip BOM, if any + $this->_skipBOM(); + + // Create new PHPExcel object + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex); + + $escapeEnclosures = array( "\\" . $this->_enclosure, + $this->_enclosure . $this->_enclosure + ); + + // Set our starting row based on whether we're in contiguous mode or not + $currentRow = 1; + if ($this->_contiguous) { + $currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow; + } + + // Loop through each line of the file in turn + while (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) { + $columnLetter = 'A'; + foreach($rowData as $rowDatum) { + if ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) { + // Unescape enclosures + $rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum); + + // Convert encoding if necessary + if ($this->_inputEncoding !== 'UTF-8') { + $rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding); + } + + // Set cell value + $sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum); + } + ++$columnLetter; + } + ++$currentRow; + } + + // Close file + fclose($fileHandle); + + if ($this->_contiguous) { + $this->_contiguousRow = $currentRow; + } + + ini_set('auto_detect_line_endings', $lineEnding); + + // Return + return $objPHPExcel; + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Reader_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Reader_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = '"'; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get line ending + * + * @return string + */ + public function getLineEnding() { + return $this->_lineEnding; + } + + /** + * Set line ending + * + * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) + * @return PHPExcel_Reader_CSV + */ + public function setLineEnding($pValue = PHP_EOL) { + $this->_lineEnding = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return integer + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param integer $pValue Sheet index + * @return PHPExcel_Reader_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Set Contiguous + * + * @param boolean $contiguous + */ + public function setContiguous($contiguous = FALSE) + { + $this->_contiguous = (bool) $contiguous; + if (!$contiguous) { + $this->_contiguousRow = -1; + } + + return $this; + } + + /** + * Get Contiguous + * + * @return boolean + */ + public function getContiguous() { + return $this->_contiguous; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/DefaultReadFilter.php b/extend/phpexcel/PHPExcel/Reader/DefaultReadFilter.php new file mode 100755 index 0000000..228ed10 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/DefaultReadFilter.php @@ -0,0 +1,58 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + + // Office xmlns:o="urn:schemas-microsoft-com:office:office" + // Excel xmlns:x="urn:schemas-microsoft-com:office:excel" + // XML Spreadsheet xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" + // Spreadsheet component xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" + // XML schema xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" + // XML data type xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" + // MS-persist recordset xmlns:rs="urn:schemas-microsoft-com:rowset" + // Rowset xmlns:z="#RowsetSchema" + // + + $signature = array( + '' + ); + + // Open file + $this->_openFile($pFilename); + $fileHandle = $this->_fileHandle; + + // Read sample data (first 2 KB will do) + $data = fread($fileHandle, 2048); + fclose($fileHandle); + + $valid = true; + foreach($signature as $match) { + // every part of the signature must be present + if (strpos($data, $match) === false) { + $valid = false; + break; + } + } + + // Retrieve charset encoding + if(preg_match('//um',$data,$matches)) { + $this->_charSet = strtoupper($matches[1]); + } +// echo 'Character Set is ',$this->_charSet,'
'; + + return $valid; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $worksheetNames = array(); + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + $worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $worksheetID = 1; + $xml_ss = $xml->children($namespaces['ss']); + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = ''; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + if (isset($worksheet_ss['Name'])) { + $tmpInfo['worksheetName'] = (string) $worksheet_ss['Name']; + } else { + $tmpInfo['worksheetName'] = "Worksheet_{$worksheetID}"; + } + + if (isset($worksheet->Table->Row)) { + $rowIndex = 0; + + foreach($worksheet->Table->Row as $rowData) { + $columnIndex = 0; + $rowHasData = false; + + foreach($rowData->Cell as $cell) { + if (isset($cell->Data)) { + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + $rowHasData = true; + } + + ++$columnIndex; + } + + ++$rowIndex; + + if ($rowHasData) { + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + } + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + ++$worksheetID; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * pixel units to excel width units(units of 1/256th of a character width) + * @param pxs + * @return + */ + private static function _pixel2WidthUnits($pxs) { + $UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219); + + $widthUnits = 256 * ($pxs / 7); + $widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)]; + return $widthUnits; + } + + + /** + * excel width units(units of 1/256th of a character width) to pixel units + * @param widthUnits + * @return + */ + private static function _widthUnits2Pixel($widthUnits) { + $pixels = ($widthUnits / 256) * 7; + $offsetWidthUnits = $widthUnits % 256; + $pixels += round($offsetWidthUnits / (256 / 7)); + return $pixels; + } + + + private static function _hex2str($hex) { + return chr(hexdec($hex[1])); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + $underlineStyles = array ( + PHPExcel_Style_Font::UNDERLINE_NONE, + PHPExcel_Style_Font::UNDERLINE_DOUBLE, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING, + PHPExcel_Style_Font::UNDERLINE_SINGLE, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING + ); + $verticalAlignmentStyles = array ( + PHPExcel_Style_Alignment::VERTICAL_BOTTOM, + PHPExcel_Style_Alignment::VERTICAL_TOP, + PHPExcel_Style_Alignment::VERTICAL_CENTER, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY + ); + $horizontalAlignmentStyles = array ( + PHPExcel_Style_Alignment::HORIZONTAL_GENERAL, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY + ); + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + if (!$this->canRead($pFilename)) { + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + + $xml = simplexml_load_file($pFilename, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespaces = $xml->getNamespaces(true); + + $docProps = $objPHPExcel->getProperties(); + if (isset($xml->DocumentProperties[0])) { + foreach($xml->DocumentProperties[0] as $propertyName => $propertyValue) { + switch ($propertyName) { + case 'Title' : + $docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Subject' : + $docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Author' : + $docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Created' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'LastAuthor' : + $docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'LastSaved' : + $lastSaveDate = strtotime($propertyValue); + $docProps->setModified($lastSaveDate); + break; + case 'Company' : + $docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Category' : + $docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Manager' : + $docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Keywords' : + $docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + case 'Description' : + $docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet)); + break; + } + } + } + if (isset($xml->CustomDocumentProperties)) { + foreach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) { + $propertyAttributes = $propertyValue->attributes($namespaces['dt']); + $propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName); + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN; + switch((string) $propertyAttributes) { + case 'string' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + $propertyValue = trim($propertyValue); + break; + case 'boolean' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + $propertyValue = (bool) $propertyValue; + break; + case 'integer' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER; + $propertyValue = intval($propertyValue); + break; + case 'float' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + $propertyValue = floatval($propertyValue); + break; + case 'dateTime.tz' : + $propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + $propertyValue = strtotime(trim($propertyValue)); + break; + } + $docProps->setCustomProperty($propertyName,$propertyValue,$propertyType); + } + } + + foreach($xml->Styles[0] as $style) { + $style_ss = $style->attributes($namespaces['ss']); + $styleID = (string) $style_ss['ID']; +// echo 'Style ID = '.$styleID.'
'; + if ($styleID == 'Default') { + $this->_styles['Default'] = array(); + } else { + $this->_styles[$styleID] = $this->_styles['Default']; + } + foreach ($style as $styleType => $styleData) { + $styleAttributes = $styleData->attributes($namespaces['ss']); +// echo $styleType.'
'; + switch ($styleType) { + case 'Alignment' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'Vertical' : + if (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue; + } + break; + case 'Horizontal' : + if (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue; + } + break; + case 'WrapText' : + $this->_styles[$styleID]['alignment']['wrap'] = true; + break; + } + } + break; + case 'Borders' : + foreach($styleData->Border as $borderStyle) { + $borderAttributes = $borderStyle->attributes($namespaces['ss']); + $thisBorder = array(); + foreach($borderAttributes as $borderStyleKey => $borderStyleValue) { +// echo $borderStyleKey.' = '.$borderStyleValue.'
'; + switch ($borderStyleKey) { + case 'LineStyle' : + $thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Weight' : +// $thisBorder['style'] = $borderStyleValue; + break; + case 'Position' : + $borderPosition = strtolower($borderStyleValue); + break; + case 'Color' : + $borderColour = substr($borderStyleValue,1); + $thisBorder['color']['rgb'] = $borderColour; + break; + } + } + if (!empty($thisBorder)) { + if (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) { + $this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder; + } + } + } + break; + case 'Font' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = (string) $styleAttributeValue; + switch ($styleAttributeKey) { + case 'FontName' : + $this->_styles[$styleID]['font']['name'] = $styleAttributeValue; + break; + case 'Size' : + $this->_styles[$styleID]['font']['size'] = $styleAttributeValue; + break; + case 'Color' : + $this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1); + break; + case 'Bold' : + $this->_styles[$styleID]['font']['bold'] = true; + break; + case 'Italic' : + $this->_styles[$styleID]['font']['italic'] = true; + break; + case 'Underline' : + if (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) { + $this->_styles[$styleID]['font']['underline'] = $styleAttributeValue; + } + break; + } + } + break; + case 'Interior' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + switch ($styleAttributeKey) { + case 'Color' : + $this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1); + break; + } + } + break; + case 'NumberFormat' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + $styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue); + switch ($styleAttributeValue) { + case 'Short Date' : + $styleAttributeValue = 'dd/mm/yyyy'; + break; + } + if ($styleAttributeValue > '') { + $this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue; + } + } + break; + case 'Protection' : + foreach($styleAttributes as $styleAttributeKey => $styleAttributeValue) { +// echo $styleAttributeKey.' = '.$styleAttributeValue.'
'; + } + break; + } + } +// print_r($this->_styles[$styleID]); +// echo '
'; + } +// echo '
'; + + $worksheetID = 0; + $xml_ss = $xml->children($namespaces['ss']); + + foreach($xml_ss->Worksheet as $worksheet) { + $worksheet_ss = $worksheet->attributes($namespaces['ss']); + + if ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) && + (!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '

Worksheet: ',$worksheet_ss['Name'],'

'; +// + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheet_ss['Name'])) { + $worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply bringing + // the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $columnID = 'A'; + if (isset($worksheet->Table->Column)) { + foreach($worksheet->Table->Column as $columnData) { + $columnData_ss = $columnData->attributes($namespaces['ss']); + if (isset($columnData_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1); + } + if (isset($columnData_ss['Width'])) { + $columnWidth = $columnData_ss['Width']; +// echo 'Setting column width for '.$columnID.' to '.$columnWidth.'
'; + $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4); + } + ++$columnID; + } + } + + $rowID = 1; + if (isset($worksheet->Table->Row)) { + foreach($worksheet->Table->Row as $rowData) { + $rowHasData = false; + $row_ss = $rowData->attributes($namespaces['ss']); + if (isset($row_ss['Index'])) { + $rowID = (integer) $row_ss['Index']; + } +// echo 'Row '.$rowID.'
'; + + $columnID = 'A'; + foreach($rowData->Cell as $cell) { + + $cell_ss = $cell->attributes($namespaces['ss']); + if (isset($cell_ss['Index'])) { + $columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1); + } + $cellRange = $columnID.$rowID; + + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + + if ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) { + $columnTo = $columnID; + if (isset($cell_ss['MergeAcross'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1); + } + $rowTo = $rowID; + if (isset($cell_ss['MergeDown'])) { + $rowTo = $rowTo + $cell_ss['MergeDown']; + } + $cellRange .= ':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + + $cellIsSet = $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cell_ss['Formula'])) { + $cellDataFormula = $cell_ss['Formula']; + // added this as a check for array formulas + if (isset($cell_ss['ArrayRange'])) { + $cellDataCSEFormula = $cell_ss['ArrayRange']; +// echo "found an array formula at ".$columnID.$rowID."
"; + } + $hasCalculatedValue = true; + } + if (isset($cell->Data)) { + $cellValue = $cellData = $cell->Data; + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $cellData_ss = $cellData->attributes($namespaces['ss']); + if (isset($cellData_ss['Type'])) { + $cellDataType = $cellData_ss['Type']; + switch ($cellDataType) { + /* + const TYPE_STRING = 's'; + const TYPE_FORMULA = 'f'; + const TYPE_NUMERIC = 'n'; + const TYPE_BOOL = 'b'; + const TYPE_NULL = 'null'; + const TYPE_INLINE = 'inlineStr'; + const TYPE_ERROR = 'e'; + */ + case 'String' : + $cellValue = self::_convertStringEncoding($cellValue,$this->_charSet); + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case 'Number' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = (float) $cellValue; + if (floor($cellValue) == $cellValue) { + $cellValue = (integer) $cellValue; + } + break; + case 'Boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cellValue = ($cellValue != 0); + break; + case 'DateTime' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue)); + break; + case 'Error' : + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + } + } + + if ($hasCalculatedValue) { +// echo 'FORMULA
'; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + $columnNumber = PHPExcel_Cell::columnIndexFromString($columnID); + if (substr($cellDataFormula,0,3) == 'of:') { + $cellDataFormula = substr($cellDataFormula,3); +// echo 'Before: ',$cellDataFormula,'
'; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + $value = str_replace(array('[.','.',']'),'',$value); + } + } + } else { + // Convert R1C1 style references to A1 style references (but only when not quoted) +// echo 'Before: ',$cellDataFormula,'
'; + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $rowID; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $columnNumber; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'After: ',$cellDataFormula,'
'; + } + +// echo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'
'; +// + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type); + if ($hasCalculatedValue) { +// echo 'Formula result is '.$cellValue.'
'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue); + } + $cellIsSet = $rowHasData = true; + } + + if (isset($cell->Comment)) { +// echo 'comment found
'; + $commentAttributes = $cell->Comment->attributes($namespaces['ss']); + $author = 'unknown'; + if (isset($commentAttributes->Author)) { + $author = (string)$commentAttributes->Author; +// echo 'Author: ',$author,'
'; + } + $node = $cell->Comment->Data->asXML(); +// $annotation = str_replace('html:','',substr($node,49,-10)); +// echo $annotation,'
'; + $annotation = strip_tags($node); +// echo 'Annotation: ',$annotation,'
'; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) + ->setAuthor(self::_convertStringEncoding($author ,$this->_charSet)) + ->setText($this->_parseRichText($annotation) ); + } + + if (($cellIsSet) && (isset($cell_ss['StyleID']))) { + $style = (string) $cell_ss['StyleID']; +// echo 'Cell style for '.$columnID.$rowID.' is '.$style.'
'; + if ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) { +// echo 'Cell '.$columnID.$rowID.'
'; +// print_r($this->_styles[$style]); +// echo '
'; + if (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL); + } + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]); + } + } + ++$columnID; + } + + if ($rowHasData) { + if (isset($row_ss['StyleID'])) { + $rowStyle = $row_ss['StyleID']; + } + if (isset($row_ss['Height'])) { + $rowHeight = $row_ss['Height']; +// echo 'Setting row height to '.$rowHeight.'
'; + $objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight); + } + } + + ++$rowID; + } + } + ++$worksheetID; + } + + // Return + return $objPHPExcel; + } + + + private static function _convertStringEncoding($string,$charset) { + if ($charset != 'UTF-8') { + return PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset); + } + return $string; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText(self::_convertStringEncoding($is,$this->_charSet)); + + return $value; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel2007.php b/extend/phpexcel/PHPExcel/Reader/Excel2007.php new file mode 100755 index 0000000..d8344ac --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel2007.php @@ -0,0 +1,2069 @@ +_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } + + $xl = false; + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($rels !== false) { + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + if (basename($rel["Target"]) == 'workbook.xml') { + $xl = true; + } + break; + + } + } + } + $zip->close(); + } + + return $xl; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader + $rels = simplexml_load_string( + $this->_getFromZipArchive($zip, "_rels/.rels", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $xmlWorkbook = simplexml_load_string( + $this->_getFromZipArchive($zip, "{$rel['Target']}", 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()) + ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + // Check if sheet should be skipped + $worksheetNames[] = (string) $eleSheet["name"]; + } + } + } + } + + $zip->close(); + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + if ($rel["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument") { + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $worksheets = array(); + foreach ($relsWorkbook->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet") { + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + } + } + + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if ($xmlWorkbook->sheets) { + $dir = dirname($rel["Target"]); + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + $tmpInfo = array( + 'worksheetName' => (string) $eleSheet["name"], + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + + $xml = new XMLReader(); + $res = $xml->open('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'."$dir/$fileWorksheet", null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + $currCells = 0; + while ($xml->read()) { + if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) { + $row = $xml->getAttribute('r'); + $tmpInfo['totalRows'] = $row; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + } elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) { + $currCells++; + } + } + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $xml->close(); + + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + + $worksheetInfo[] = $tmpInfo; + } + } + } + } + + $zip->close(); + + return $worksheetInfo; + } + + + private static function _castToBool($c) { +// echo 'Initial Cast to Boolean', PHP_EOL; + $value = isset($c->v) ? (string) $c->v : NULL; + if ($value == '0') { + return FALSE; + } elseif ($value == '1') { + return TRUE; + } else { + return (bool)$c->v; + } + return $value; + } // function _castToBool() + + + private static function _castToError($c) { +// echo 'Initial Cast to Error', PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToError() + + + private static function _castToString($c) { +// echo 'Initial Cast to String, PHP_EOL; + return isset($c->v) ? (string) $c->v : NULL; + } // function _castToString() + + + private function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) { +// echo 'Formula', PHP_EOL; +// echo '$c->f is ', $c->f, PHP_EOL; + $cellDataType = 'f'; + $value = "={$c->f}"; + $calculatedValue = self::$castBaseType($c); + + // Shared formula? + if (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') { +// echo 'SHARED FORMULA', PHP_EOL; + $instance = (string)$c->f['si']; + +// echo 'Instance ID = ', $instance, PHP_EOL; +// +// echo 'Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + if (!isset($sharedFormulas[(string)$c->f['si']])) { +// echo 'SETTING NEW SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $r, PHP_EOL; +// echo 'Formula is ', $value, PHP_EOL; + $sharedFormulas[$instance] = array( 'master' => $r, + 'formula' => $value + ); +// echo 'New Shared Formula Array:', PHP_EOL; +// print_r($sharedFormulas); + } else { +// echo 'GETTING SHARED FORMULA', PHP_EOL; +// echo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL; +// echo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL; + $master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']); + $current = PHPExcel_Cell::coordinateFromString($r); + + $difference = array(0, 0); + $difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]); + $difference[1] = $current[1] - $master[1]; + + $value = $this->_referenceHelper->updateFormulaReferences( $sharedFormulas[$instance]['formula'], + 'A1', + $difference[0], + $difference[1] + ); +// echo 'Adjusted Formula is ', $value, PHP_EOL; + } + } + } + + + public function _getFromZipArchive($archive, $fileName = '') + { + // Root-relative paths + if (strpos($fileName, '//') !== false) + { + $fileName = substr($fileName, strpos($fileName, '//') + 1); + } + $fileName = PHPExcel_Shared_File::realpath($fileName); + + // Apache POI fixes + $contents = $archive->getFromName($fileName); + if ($contents === false) + { + $contents = $archive->getFromName(substr($fileName, 1)); + } + + return $contents; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Initialisations + $excel = new PHPExcel; + $excel->removeSheetByIndex(0); + if (!$this->_readDataOnly) { + $excel->removeCellStyleXfByIndex(0); // remove the default style + $excel->removeCellXfByIndex(0); // remove the default style + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + $zip->open($pFilename); + + // Read the theme first, because we need the colour scheme when reading the styles + $wbRels = simplexml_load_string($this->_getFromZipArchive($zip, "xl/_rels/workbook.xml.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($wbRels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme": + $themeOrderArray = array('lt1','dk1','lt2','dk2'); + $themeOrderAdditional = count($themeOrderArray); + + $xmlTheme = simplexml_load_string($this->_getFromZipArchive($zip, "xl/{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlTheme)) { + $xmlThemeName = $xmlTheme->attributes(); + $xmlTheme = $xmlTheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + $themeName = (string)$xmlThemeName['name']; + + $colourScheme = $xmlTheme->themeElements->clrScheme->attributes(); + $colourSchemeName = (string)$colourScheme['name']; + $colourScheme = $xmlTheme->themeElements->clrScheme->children("http://schemas.openxmlformats.org/drawingml/2006/main"); + + $themeColours = array(); + foreach ($colourScheme as $k => $xmlColour) { + $themePos = array_search($k,$themeOrderArray); + if ($themePos === false) { + $themePos = $themeOrderAdditional++; + } + if (isset($xmlColour->sysClr)) { + $xmlColourData = $xmlColour->sysClr->attributes(); + $themeColours[$themePos] = $xmlColourData['lastClr']; + } elseif (isset($xmlColour->srgbClr)) { + $xmlColourData = $xmlColour->srgbClr->attributes(); + $themeColours[$themePos] = $xmlColourData['val']; + } + } + self::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours); + } + break; + } + } + + $rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); + $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); + $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); + $docProps = $excel->getProperties(); + $docProps->setCreator((string) self::array_item($xmlCore->xpath("dc:creator"))); + $docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath("cp:lastModifiedBy"))); + $docProps->setCreated(strtotime(self::array_item($xmlCore->xpath("dcterms:created")))); //! respect xsi:type + $docProps->setModified(strtotime(self::array_item($xmlCore->xpath("dcterms:modified")))); //! respect xsi:type + $docProps->setTitle((string) self::array_item($xmlCore->xpath("dc:title"))); + $docProps->setDescription((string) self::array_item($xmlCore->xpath("dc:description"))); + $docProps->setSubject((string) self::array_item($xmlCore->xpath("dc:subject"))); + $docProps->setKeywords((string) self::array_item($xmlCore->xpath("cp:keywords"))); + $docProps->setCategory((string) self::array_item($xmlCore->xpath("cp:category"))); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + if (isset($xmlCore->Company)) + $docProps->setCompany((string) $xmlCore->Company); + if (isset($xmlCore->Manager)) + $docProps->setManager((string) $xmlCore->Manager); + } + break; + + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": + $xmlCore = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if (is_object($xmlCore)) { + $docProps = $excel->getProperties(); + foreach ($xmlCore as $xmlProperty) { + $cellDataOfficeAttributes = $xmlProperty->attributes(); + if (isset($cellDataOfficeAttributes['name'])) { + $propertyName = (string) $cellDataOfficeAttributes['name']; + $cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + $attributeType = $cellDataOfficeChildren->getName(); + $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; + $attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType); + $attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType); + $docProps->setCustomProperty($propertyName,$attributeValue,$attributeType); + } + } + } + break; + //Ribbon + case "http://schemas.microsoft.com/office/2006/relationships/ui/extensibility": + $customUI = $rel['Target']; + if(!is_null($customUI)){ + $this->_readRibbon($excel, $customUI, $zip); + } + break; + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $dir = dirname($rel["Target"]); + $relsWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/_rels/" . basename($rel["Target"]) . ".rels"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $relsWorkbook->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + + $sharedStrings = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); + $xmlStrings = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + if (isset($xmlStrings) && isset($xmlStrings->si)) { + foreach ($xmlStrings->si as $val) { + if (isset($val->t)) { + $sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t ); + } elseif (isset($val->r)) { + $sharedStrings[] = $this->_parseRichText($val); + } + } + } + + $worksheets = array(); + $macros = $customUI = NULL; + foreach ($relsWorkbook->Relationship as $ele) { + switch($ele['Type']){ + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet": + $worksheets[(string) $ele["Id"]] = $ele["Target"]; + break; + // a vbaProject ? (: some macros) + case "http://schemas.microsoft.com/office/2006/relationships/vbaProject": + $macros = $ele["Target"]; + break; + } + } + + if(!is_null($macros)){ + $macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin + if($macrosCode !== false){ + $excel->setMacrosCode($macrosCode); + $excel->setHasMacros(true); + //short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir + $Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin'); + if($Certificate !== false) + $excel->setMacrosCertificate($Certificate); + } + } + $styles = array(); + $cellStyles = array(); + $xpath = self::array_item($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); + $xmlStyles = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$xpath[Target]"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $numFmts = null; + if ($xmlStyles && $xmlStyles->numFmts[0]) { + $numFmts = $xmlStyles->numFmts[0]; + } + if (isset($numFmts) && ($numFmts !== NULL)) { + $numFmts->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + } + if (!$this->_readDataOnly && $xmlStyles) { + foreach ($xmlStyles->cellXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + + if ($xf["numFmtId"]) { + if (isset($numFmts)) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } + } + + if ((int)$xf["numFmtId"] < 164) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } + $quotePrefix = false; + if (isset($xf["quotePrefix"])) { + $quotePrefix = (boolean) $xf["quotePrefix"]; + } + //$numFmt = str_replace('mm', 'i', $numFmt); + //$numFmt = str_replace('h', 'H', $numFmt); + + $style = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $styles[] = $style; + + // add style to cellXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $style); + $excel->addCellXf($objStyle); + } + + foreach ($xmlStyles->cellStyleXfs->xf as $xf) { + $numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + if ($numFmts && $xf["numFmtId"]) { + $tmpNumFmt = self::array_item($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]")); + if (isset($tmpNumFmt["formatCode"])) { + $numFmt = (string) $tmpNumFmt["formatCode"]; + } else if ((int)$xf["numFmtId"] < 165) { + $numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf["numFmtId"]); + } + } + + $cellStyle = (object) array( + "numFmt" => $numFmt, + "font" => $xmlStyles->fonts->font[intval($xf["fontId"])], + "fill" => $xmlStyles->fills->fill[intval($xf["fillId"])], + "border" => $xmlStyles->borders->border[intval($xf["borderId"])], + "alignment" => $xf->alignment, + "protection" => $xf->protection, + "quotePrefix" => $quotePrefix, + ); + $cellStyles[] = $cellStyle; + + // add style to cellStyleXf collection + $objStyle = new PHPExcel_Style; + self::_readStyle($objStyle, $cellStyle); + $excel->addCellStyleXf($objStyle); + } + } + + $dxfs = array(); + if (!$this->_readDataOnly && $xmlStyles) { + // Conditional Styles + if ($xmlStyles->dxfs) { + foreach ($xmlStyles->dxfs->dxf as $dxf) { + $style = new PHPExcel_Style(FALSE, TRUE); + self::_readStyle($style, $dxf); + $dxfs[] = $style; + } + } + // Cell Styles + if ($xmlStyles->cellStyles) { + foreach ($xmlStyles->cellStyles->cellStyle as $cellStyle) { + if (intval($cellStyle['builtinId']) == 0) { + if (isset($cellStyles[intval($cellStyle['xfId'])])) { + // Set default style + $style = new PHPExcel_Style; + self::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]); + + // normal style, currently not using it for anything + } + } + } + } + } + + $xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + // Set base date + if ($xmlWorkbook->workbookPr) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (isset($xmlWorkbook->workbookPr['date1904'])) { + if (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + } + + $sheetId = 0; // keep track of new sheet id in final workbook + $oldSheetId = -1; // keep track of old sheet id in final workbook + $countSkippedSheets = 0; // keep track of number of skipped sheets + $mapSheetId = array(); // mapping of sheet ids from old to new + + + $charts = $chartDetails = array(); + + if ($xmlWorkbook->sheets) { + foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { + ++$oldSheetId; + + // Check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet["name"], $this->_loadSheetsOnly)) { + ++$countSkippedSheets; + $mapSheetId[$oldSheetId] = null; + continue; + } + + // Map old sheet id in original workbook to new sheet id. + // They will differ if loadSheetsOnly() is being used + $mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets; + + // Load sheet + $docSheet = $excel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet + // references in formula cells... during the load, all formulae should be correct, + // and we're simply bringing the worksheet name in line with the formula, not the + // reverse + $docSheet->setTitle((string) $eleSheet["name"],false); + $fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + + $sharedFormulas = array(); + + if (isset($eleSheet["state"]) && (string) $eleSheet["state"] != '') { + $docSheet->setSheetState( (string) $eleSheet["state"] ); + } + + if (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) { + if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) { + $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) { + $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) ); + } + + if (isset($xmlSheet->sheetViews->sheetView['view'])) { + $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']); + } + + if (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) { + $docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) { + $docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders'])); + } + + if (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) { + $docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft'])); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane)) { + if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) { + $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] ); + } else { + $xSplit = 0; + $ySplit = 0; + + if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) { + $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']); + } + + if (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) { + $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']); + } + + $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit); + } + } + + if (isset($xmlSheet->sheetViews->sheetView->selection)) { + if (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) { + $sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref']; + $sqref = explode(' ', $sqref); + $sqref = $sqref[0]; + $docSheet->setSelectedCells($sqref); + } + } + + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) { + if (isset($xmlSheet->sheetPr->tabColor['rgb'])) { + $docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] ); + } + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) { + $docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']); + } + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) { + if (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) { + $docSheet->setShowSummaryRight(FALSE); + } else { + $docSheet->setShowSummaryRight(TRUE); + } + + if (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) && + !self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) { + $docSheet->setShowSummaryBelow(FALSE); + } else { + $docSheet->setShowSummaryBelow(TRUE); + } + } + + if (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) { + if (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) && + !self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) { + $docSheet->getPageSetup()->setFitToPage(FALSE); + } else { + $docSheet->getPageSetup()->setFitToPage(TRUE); + } + } + + if (isset($xmlSheet->sheetFormatPr)) { + if (isset($xmlSheet->sheetFormatPr['customHeight']) && + self::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) && + isset($xmlSheet->sheetFormatPr['defaultRowHeight'])) { + $docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] ); + } + if (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) { + $docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] ); + } + if (isset($xmlSheet->sheetFormatPr['zeroHeight']) && + ((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) { + $docSheet->getDefaultRowDimension()->setzeroHeight(true); + } + } + + if (isset($xmlSheet->cols) && !$this->_readDataOnly) { + foreach ($xmlSheet->cols->col as $col) { + for ($i = intval($col["min"]) - 1; $i < intval($col["max"]); ++$i) { + if ($col["style"] && !$this->_readDataOnly) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col["style"])); + } + if (self::boolean($col["bestFit"])) { + //$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE); + } + if (self::boolean($col["hidden"])) { + // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL; + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE); + } + if (self::boolean($col["collapsed"])) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE); + } + if ($col["outlineLevel"] > 0) { + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col["outlineLevel"])); + } + $docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col["width"])); + + if (intval($col["max"]) == 16384) { + break; + } + } + } + } + + if (isset($xmlSheet->printOptions) && !$this->_readDataOnly) { + if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { + $docSheet->setShowGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['gridLines'])) { + $docSheet->setPrintGridlines(TRUE); + } + + if (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) { + $docSheet->getPageSetup()->setHorizontalCentered(TRUE); + } + if (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) { + $docSheet->getPageSetup()->setVerticalCentered(TRUE); + } + } + + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { + foreach ($xmlSheet->sheetData->row as $row) { + if ($row["ht"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setRowHeight(floatval($row["ht"])); + } + if (self::boolean($row["hidden"]) && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setVisible(FALSE); + } + if (self::boolean($row["collapsed"])) { + $docSheet->getRowDimension(intval($row["r"]))->setCollapsed(TRUE); + } + if ($row["outlineLevel"] > 0) { + $docSheet->getRowDimension(intval($row["r"]))->setOutlineLevel(intval($row["outlineLevel"])); + } + if ($row["s"] && !$this->_readDataOnly) { + $docSheet->getRowDimension(intval($row["r"]))->setXfIndex(intval($row["s"])); + } + + foreach ($row->c as $c) { + $r = (string) $c["r"]; + $cellDataType = (string) $c["t"]; + $value = null; + $calculatedValue = null; + + // Read cell? + if ($this->getReadFilter() !== NULL) { + $coordinates = PHPExcel_Cell::coordinateFromString($r); + + if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { + continue; + } + } + + // echo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL; + // print_r($c); + // echo PHP_EOL; + // echo 'Cell Data Type is ', $cellDataType, ': '; + // + // Read cell! + switch ($cellDataType) { + case "s": + // echo 'String', PHP_EOL; + if ((string)$c->v != '') { + $value = $sharedStrings[intval($c->v)]; + + if ($value instanceof PHPExcel_RichText) { + $value = clone $value; + } + } else { + $value = ''; + } + + break; + case "b": + // echo 'Boolean', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToBool($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool'); + if (isset($c->f['t'])) { + $att = array(); + $att = $c->f; + $docSheet->getCell($r)->setFormulaAttributes($att); + } + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + break; + case "inlineStr": + // echo 'Inline String', PHP_EOL; + $value = $this->_parseRichText($c->is); + + break; + case "e": + // echo 'Error', PHP_EOL; + if (!isset($c->f)) { + $value = self::_castToError($c); + } else { + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + + default: + // echo 'Default', PHP_EOL; + if (!isset($c->f)) { + // echo 'Not a Formula', PHP_EOL; + $value = self::_castToString($c); + } else { + // echo 'Treat as Formula', PHP_EOL; + // Formula + $this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString'); + // echo '$calculatedValue = ', $calculatedValue, PHP_EOL; + } + + break; + } + // echo 'Value is ', $value, PHP_EOL; + + // Check for numeric values + if (is_numeric($value) && $cellDataType != 's') { + if ($value == (int)$value) $value = (int)$value; + elseif ($value == (float)$value) $value = (float)$value; + elseif ($value == (double)$value) $value = (double)$value; + } + + // Rich text? + if ($value instanceof PHPExcel_RichText && $this->_readDataOnly) { + $value = $value->getPlainText(); + } + + $cell = $docSheet->getCell($r); + // Assign value + if ($cellDataType != '') { + $cell->setValueExplicit($value, $cellDataType); + } else { + $cell->setValue($value); + } + if ($calculatedValue !== NULL) { + $cell->setCalculatedValue($calculatedValue); + } + + // Style information? + if ($c["s"] && !$this->_readDataOnly) { + // no style index means 0, it seems + $cell->setXfIndex(isset($styles[intval($c["s"])]) ? + intval($c["s"]) : 0); + } + } + } + } + + $conditionals = array(); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) { + foreach ($xmlSheet->conditionalFormatting as $conditional) { + foreach ($conditional->cfRule as $cfRule) { + if ( + ( + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_NONE || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CELLIS || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT || + (string)$cfRule["type"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + ) && isset($dxfs[intval($cfRule["dxfId"])]) + ) { + $conditionals[(string) $conditional["sqref"]][intval($cfRule["priority"])] = $cfRule; + } + } + } + + foreach ($conditionals as $ref => $cfRules) { + ksort($cfRules); + $conditionalStyles = array(); + foreach ($cfRules as $cfRule) { + $objConditional = new PHPExcel_Style_Conditional(); + $objConditional->setConditionType((string)$cfRule["type"]); + $objConditional->setOperatorType((string)$cfRule["operator"]); + + if ((string)$cfRule["text"] != '') { + $objConditional->setText((string)$cfRule["text"]); + } + + if (count($cfRule->formula) > 1) { + foreach ($cfRule->formula as $formula) { + $objConditional->addCondition((string)$formula); + } + } else { + $objConditional->addCondition((string)$cfRule->formula); + } + $objConditional->setStyle(clone $dxfs[intval($cfRule["dxfId"])]); + $conditionalStyles[] = $objConditional; + } + + // Extract all cell references in $ref + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref); + foreach ($aReferences as $reference) { + $docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles); + } + } + } + + $aKeys = array("sheet", "objects", "scenarios", "formatCells", "formatColumns", "formatRows", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "selectLockedCells", "sort", "autoFilter", "pivotTables", "selectUnlockedCells"); + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + foreach ($aKeys as $key) { + $method = "set" . ucfirst($key); + $docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key])); + } + } + + if (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) { + $docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection["password"], TRUE); + if ($xmlSheet->protectedRanges->protectedRange) { + foreach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) { + $docSheet->protectCells((string) $protectedRange["sqref"], (string) $protectedRange["password"], true); + } + } + } + + if ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) { + $autoFilter = $docSheet->getAutoFilter(); + $autoFilter->setRange((string) $xmlSheet->autoFilter["ref"]); + foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) { + $column = $autoFilter->getColumnByOffset((integer) $filterColumn["colId"]); + // Check for standard filters + if ($filterColumn->filters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER); + $filters = $filterColumn->filters; + if ((isset($filters["blank"])) && ($filters["blank"] == 1)) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + '' + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Standard filters are always an OR join, so no join rule needs to be set + // Entries can be either filter elements + foreach ($filters->filter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER); + } + // Or Date Group elements + foreach ($filters->dateGroupItem as $dateGroupItem) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + array( + 'year' => (string) $dateGroupItem["year"], + 'month' => (string) $dateGroupItem["month"], + 'day' => (string) $dateGroupItem["day"], + 'hour' => (string) $dateGroupItem["hour"], + 'minute' => (string) $dateGroupItem["minute"], + 'second' => (string) $dateGroupItem["second"], + ), + (string) $dateGroupItem["dateTimeGrouping"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP); + } + } + // Check for custom filters + if ($filterColumn->customFilters) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER); + $customFilters = $filterColumn->customFilters; + // Custom filters can an AND or an OR join; + // and there should only ever be one or two entries + if ((isset($customFilters["and"])) && ($customFilters["and"] == 1)) { + $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + } + foreach ($customFilters->customFilter as $filterRule) { + $column->createRule()->setRule( + (string) $filterRule["operator"], + (string) $filterRule["val"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); + } + } + // Check for dynamic filters + if ($filterColumn->dynamicFilter) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + // We should only ever have one dynamic filter + foreach ($filterColumn->dynamicFilter as $filterRule) { + $column->createRule()->setRule( + NULL, // Operator is undefined, but always treated as EQUAL + (string) $filterRule["val"], + (string) $filterRule["type"] + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER); + if (isset($filterRule["val"])) { + $column->setAttribute('val',(string) $filterRule["val"]); + } + if (isset($filterRule["maxVal"])) { + $column->setAttribute('maxVal',(string) $filterRule["maxVal"]); + } + } + } + // Check for dynamic filters + if ($filterColumn->top10) { + $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER); + // We should only ever have one top10 filter + foreach ($filterColumn->top10 as $filterRule) { + $column->createRule()->setRule( + (((isset($filterRule["percent"])) && ($filterRule["percent"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE + ), + (string) $filterRule["val"], + (((isset($filterRule["top"])) && ($filterRule["top"] == 1)) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM + ) + ) + ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER); + } + } + } + } + + if ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) { + foreach ($xmlSheet->mergeCells->mergeCell as $mergeCell) { + $mergeRef = (string) $mergeCell["ref"]; + if (strpos($mergeRef,':') !== FALSE) { + $docSheet->mergeCells((string) $mergeCell["ref"]); + } + } + } + + if ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) { + $docPageMargins = $docSheet->getPageMargins(); + $docPageMargins->setLeft(floatval($xmlSheet->pageMargins["left"])); + $docPageMargins->setRight(floatval($xmlSheet->pageMargins["right"])); + $docPageMargins->setTop(floatval($xmlSheet->pageMargins["top"])); + $docPageMargins->setBottom(floatval($xmlSheet->pageMargins["bottom"])); + $docPageMargins->setHeader(floatval($xmlSheet->pageMargins["header"])); + $docPageMargins->setFooter(floatval($xmlSheet->pageMargins["footer"])); + } + + if ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) { + $docPageSetup = $docSheet->getPageSetup(); + + if (isset($xmlSheet->pageSetup["orientation"])) { + $docPageSetup->setOrientation((string) $xmlSheet->pageSetup["orientation"]); + } + if (isset($xmlSheet->pageSetup["paperSize"])) { + $docPageSetup->setPaperSize(intval($xmlSheet->pageSetup["paperSize"])); + } + if (isset($xmlSheet->pageSetup["scale"])) { + $docPageSetup->setScale(intval($xmlSheet->pageSetup["scale"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToHeight"]) && intval($xmlSheet->pageSetup["fitToHeight"]) >= 0) { + $docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup["fitToHeight"]), FALSE); + } + if (isset($xmlSheet->pageSetup["fitToWidth"]) && intval($xmlSheet->pageSetup["fitToWidth"]) >= 0) { + $docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup["fitToWidth"]), FALSE); + } + if (isset($xmlSheet->pageSetup["firstPageNumber"]) && isset($xmlSheet->pageSetup["useFirstPageNumber"]) && + self::boolean((string) $xmlSheet->pageSetup["useFirstPageNumber"])) { + $docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup["firstPageNumber"])); + } + } + + if ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) { + $docHeaderFooter = $docSheet->getHeaderFooter(); + + if (isset($xmlSheet->headerFooter["differentOddEven"]) && + self::boolean((string)$xmlSheet->headerFooter["differentOddEven"])) { + $docHeaderFooter->setDifferentOddEven(TRUE); + } else { + $docHeaderFooter->setDifferentOddEven(FALSE); + } + if (isset($xmlSheet->headerFooter["differentFirst"]) && + self::boolean((string)$xmlSheet->headerFooter["differentFirst"])) { + $docHeaderFooter->setDifferentFirst(TRUE); + } else { + $docHeaderFooter->setDifferentFirst(FALSE); + } + if (isset($xmlSheet->headerFooter["scaleWithDoc"]) && + !self::boolean((string)$xmlSheet->headerFooter["scaleWithDoc"])) { + $docHeaderFooter->setScaleWithDocument(FALSE); + } else { + $docHeaderFooter->setScaleWithDocument(TRUE); + } + if (isset($xmlSheet->headerFooter["alignWithMargins"]) && + !self::boolean((string)$xmlSheet->headerFooter["alignWithMargins"])) { + $docHeaderFooter->setAlignWithMargins(FALSE); + } else { + $docHeaderFooter->setAlignWithMargins(TRUE); + } + + $docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader); + $docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter); + $docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader); + $docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter); + $docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader); + $docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter); + } + + if ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->rowBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak("A$brk[id]", PHPExcel_Worksheet::BREAK_ROW); + } + } + } + if ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) { + foreach ($xmlSheet->colBreaks->brk as $brk) { + if ($brk["man"]) { + $docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk["id"]) . "1", PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + if ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) { + foreach ($xmlSheet->dataValidations->dataValidation as $dataValidation) { + // Uppercase coordinate + $range = strtoupper($dataValidation["sqref"]); + $rangeSet = explode(' ',$range); + foreach($rangeSet as $range) { + $stRange = $docSheet->shrinkRangeToFit($range); + + // Extract all cell references in $range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($aReferences as $reference) { + // Create validation + $docValidation = $docSheet->getCell($reference)->getDataValidation(); + $docValidation->setType((string) $dataValidation["type"]); + $docValidation->setErrorStyle((string) $dataValidation["errorStyle"]); + $docValidation->setOperator((string) $dataValidation["operator"]); + $docValidation->setAllowBlank($dataValidation["allowBlank"] != 0); + $docValidation->setShowDropDown($dataValidation["showDropDown"] == 0); + $docValidation->setShowInputMessage($dataValidation["showInputMessage"] != 0); + $docValidation->setShowErrorMessage($dataValidation["showErrorMessage"] != 0); + $docValidation->setErrorTitle((string) $dataValidation["errorTitle"]); + $docValidation->setError((string) $dataValidation["error"]); + $docValidation->setPromptTitle((string) $dataValidation["promptTitle"]); + $docValidation->setPrompt((string) $dataValidation["prompt"]); + $docValidation->setFormula1((string) $dataValidation->formula1); + $docValidation->setFormula2((string) $dataValidation->formula2); + } + } + } + } + + // Add hyperlinks + $hyperlinks = array(); + if (!$this->_readDataOnly) { + // Locate hyperlink relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") { + $hyperlinks[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through hyperlinks + if ($xmlSheet && $xmlSheet->hyperlinks) { + foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) { + // Link url + $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) { + $cell = $docSheet->getCell( $cellReference ); + if (isset($linkRel['id'])) { + $hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ]; + if (isset($hyperlink['location'])) { + $hyperlinkUrl .= '#' . (string) $hyperlink['location']; + } + $cell->getHyperlink()->setUrl($hyperlinkUrl); + } elseif (isset($hyperlink['location'])) { + $cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] ); + } + + // Tooltip + if (isset($hyperlink['tooltip'])) { + $cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] ); + } + } + } + } + } + + // Add comments + $comments = array(); + $vmlComments = array(); + if (!$this->_readDataOnly) { + // Locate comment relations + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") { + $comments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlComments[(string)$ele["Id"]] = (string)$ele["Target"]; + } + } + } + + // Loop through comments + foreach ($comments as $relName => $relPath) { + // Load comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $commentsFile = simplexml_load_string($this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + + // Utility variables + $authors = array(); + + // Loop through authors + foreach ($commentsFile->authors->author as $author) { + $authors[] = (string)$author; + } + + // Loop through contents + foreach ($commentsFile->commentList->comment as $comment) { + $docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] ); + $docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) ); + } + } + + // Loop through VML comments + foreach ($vmlComments as $relName => $relPath) { + // Load VML comments file + $relPath = PHPExcel_Shared_File::realpath(dirname("$dir/$fileWorksheet") . "/" . $relPath); + $vmlCommentsFile = simplexml_load_string( $this->_getFromZipArchive($zip, $relPath) , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $shapes = $vmlCommentsFile->xpath('//v:shape'); + foreach ($shapes as $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + if (isset($shape['style'])) { + $style = (string)$shape['style']; + $fillColor = strtoupper( substr( (string)$shape['fillcolor'], 1 ) ); + $column = null; + $row = null; + + $clientData = $shape->xpath('.//x:ClientData'); + if (is_array($clientData) && !empty($clientData)) { + $clientData = $clientData[0]; + + if ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) { + $temp = $clientData->xpath('.//x:Row'); + if (is_array($temp)) $row = $temp[0]; + + $temp = $clientData->xpath('.//x:Column'); + if (is_array($temp)) $column = $temp[0]; + } + } + + if (($column !== NULL) && ($row !== NULL)) { + // Set comment properties + $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); + $comment->getFillColor()->setRGB( $fillColor ); + + // Parse style + $styleArray = explode(';', str_replace(' ', '', $style)); + foreach ($styleArray as $stylePair) { + $stylePair = explode(':', $stylePair); + + if ($stylePair[0] == 'margin-left') $comment->setMarginLeft($stylePair[1]); + if ($stylePair[0] == 'margin-top') $comment->setMarginTop($stylePair[1]); + if ($stylePair[0] == 'width') $comment->setWidth($stylePair[1]); + if ($stylePair[0] == 'height') $comment->setHeight($stylePair[1]); + if ($stylePair[0] == 'visibility') $comment->setVisible( $stylePair[1] == 'visible' ); + + } + } + } + } + } + + // Header/footer images + if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) { + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $vmlRelationship = ''; + + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") { + $vmlRelationship = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + + if ($vmlRelationship != '') { + // Fetch linked images + $relsVML = simplexml_load_string($this->_getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels' ), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsVML->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $drawings[(string) $ele["Id"]] = self::dir_add($vmlRelationship, $ele["Target"]); + } + } + + // Fetch VML document + $vmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $vmlRelationship), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + + $hfImages = array(); + + $shapes = $vmlDrawing->xpath('//v:shape'); + foreach ($shapes as $idx => $shape) { + $shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml'); + $imageData = $shape->xpath('//v:imagedata'); + $imageData = $imageData[$idx]; + + $imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office'); + $style = self::toCSSArray( (string)$shape['style'] ); + + $hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing(); + if (isset($imageData['title'])) { + $hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] ); + } + + $hfImages[ (string)$shape['id'] ]->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $drawings[(string)$imageData['relid']], false); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(false); + $hfImages[ (string)$shape['id'] ]->setWidth($style['width']); + $hfImages[ (string)$shape['id'] ]->setHeight($style['height']); + if (isset($style['margin-left'])) { + $hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']); + } + $hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']); + $hfImages[ (string)$shape['id'] ]->setResizeProportional(true); + } + + $docSheet->getHeaderFooter()->setImages($hfImages); + } + } + } + + } + + // TODO: Autoshapes from twoCellAnchors! + if ($zip->locateName(dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels")) { + $relsWorksheet = simplexml_load_string($this->_getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . "/_rels/" . basename($fileWorksheet) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $drawings = array(); + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing") { + $drawings[(string) $ele["Id"]] = self::dir_add("$dir/$fileWorksheet", $ele["Target"]); + } + } + if ($xmlSheet->drawing && !$this->_readDataOnly) { + foreach ($xmlSheet->drawing as $drawing) { + $fileDrawing = $drawings[(string) self::array_item($drawing->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")]; + $relsDrawing = simplexml_load_string($this->_getFromZipArchive($zip, dirname($fileDrawing) . "/_rels/" . basename($fileDrawing) . ".rels") , 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + $images = array(); + + if ($relsDrawing && $relsDrawing->Relationship) { + foreach ($relsDrawing->Relationship as $ele) { + if ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image") { + $images[(string) $ele["Id"]] = self::dir_add($fileDrawing, $ele["Target"]); + } elseif ($ele["Type"] == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart") { + if ($this->_includeCharts) { + $charts[self::dir_add($fileDrawing, $ele["Target"])] = array('id' => (string) $ele["Id"], + 'sheet' => $docSheet->getTitle() + ); + } + } + } + } + $xmlDrawing = simplexml_load_string($this->_getFromZipArchive($zip, $fileDrawing), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"); + + if ($xmlDrawing->oneCellAnchor) { + foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { + if ($oneCellAnchor->pic->blipFill) { + $blip = $oneCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $oneCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy"))); + if ($xfrm) { + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } else { + // ? Can charts be positioned with a oneCellAnchor ? + $coordinates = PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1); + $offsetX = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff); + $offsetY = PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff); + $width = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cx")); + $height = PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), "cy")); + } + } + } + if ($xmlDrawing->twoCellAnchor) { + foreach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) { + if ($twoCellAnchor->pic->blipFill) { + $blip = $twoCellAnchor->pic->blipFill->children("http://schemas.openxmlformats.org/drawingml/2006/main")->blip; + $xfrm = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->xfrm; + $outerShdw = $twoCellAnchor->pic->spPr->children("http://schemas.openxmlformats.org/drawingml/2006/main")->effectLst->outerShdw; + $objDrawing = new PHPExcel_Worksheet_Drawing; + $objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "name")); + $objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), "descr")); + $objDrawing->setPath("zip://".PHPExcel_Shared_File::realpath($pFilename)."#" . $images[(string) self::array_item($blip->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "embed")], false); + $objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1)); + $objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff)); + $objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff)); + $objDrawing->setResizeProportional(false); + + $objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cx"))); + $objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), "cy"))); + + if ($xfrm) { + $objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), "rot"))); + } + if ($outerShdw) { + $shadow = $objDrawing->getShadow(); + $shadow->setVisible(true); + $shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "blurRad"))); + $shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), "dist"))); + $shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), "dir"))); + $shadow->setAlignment((string) self::array_item($outerShdw->attributes(), "algn")); + $shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), "val")); + $shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), "val") / 1000); + } + $objDrawing->setWorksheet($docSheet); + } elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) { + $fromCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1); + $fromOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff); + $fromOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff); + $toCoordinate = PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1); + $toOffsetX = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff); + $toOffsetY = PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff); + $graphic = $twoCellAnchor->graphicFrame->children("http://schemas.openxmlformats.org/drawingml/2006/main")->graphic; + $chartRef = $graphic->graphicData->children("http://schemas.openxmlformats.org/drawingml/2006/chart")->chart; + $thisChart = (string) $chartRef->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + + $chartDetails[$docSheet->getTitle().'!'.$thisChart] = + array( 'fromCoordinate' => $fromCoordinate, + 'fromOffsetX' => $fromOffsetX, + 'fromOffsetY' => $fromOffsetY, + 'toCoordinate' => $toCoordinate, + 'toOffsetX' => $toOffsetX, + 'toOffsetY' => $toOffsetY, + 'worksheetTitle' => $docSheet->getTitle() + ); + } + } + } + + } + } + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) { + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + if ((string)$definedName['hidden'] !== '1') { + $docSheet->getAutoFilter()->setRange($extractedRange); + } + break; + + case '_xlnm.Print_Titles': + // Split $extractedRange + $extractedRange = explode(',', $extractedRange); + + // Set print titles + foreach ($extractedRange as $range) { + $matches = array(); + $range = str_replace('$', '', $range); + + // check for repeating columns, e g. 'A:A' or 'A:D' + if (preg_match('/!?([A-Z]+)\:([A-Z]+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2])); + } + // check for repeating rows, e.g. '1:1' or '1:5' + elseif (preg_match('/!?(\d+)\:(\d+)$/', $range, $matches)) { + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2])); + } + } + break; + + case '_xlnm.Print_Area': + $rangeSets = explode(',', $extractedRange); // FIXME: what if sheetname contains comma? + $newRangeSets = array(); + foreach($rangeSets as $rangeSet) { + $range = explode('!', $rangeSet); // FIXME: what if sheetname contains exclamation mark? + $rangeSet = isset($range[1]) ? $range[1] : $range[0]; + if (strpos($rangeSet, ':') === FALSE) { + $rangeSet = $rangeSet . ':' . $rangeSet; + } + $newRangeSets[] = str_replace('$', '', $rangeSet); + } + $docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets)); + break; + + default: + break; + } + } + } + } + + // Next sheet id + ++$sheetId; + } + + // Loop through definedNames + if ($xmlWorkbook->definedNames) { + foreach ($xmlWorkbook->definedNames->definedName as $definedName) { + // Extract range + $extractedRange = (string)$definedName; + $extractedRange = preg_replace('/\'(\w+)\'\!/', '', $extractedRange); + if (($spos = strpos($extractedRange,'!')) !== false) { + $extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos)); + } else { + $extractedRange = str_replace('$', '', $extractedRange); + } + + // Valid range? + if (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') { + continue; + } + + // Some definedNames are only applicable if we are on the same sheet... + if ((string)$definedName['localSheetId'] != '') { + // Local defined name + // Switch on type + switch ((string)$definedName['name']) { + + case '_xlnm._FilterDatabase': + case '_xlnm.Print_Titles': + case '_xlnm.Print_Area': + break; + + default: + if ($mapSheetId[(integer) $definedName['localSheetId']] !== null) { + $range = explode('!', (string)$definedName); + if (count($range) == 2) { + $range[0] = str_replace("''", "'", $range[0]); + $range[0] = str_replace("'", "", $range[0]); + if ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]); + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) ); + } + } + } + break; + } + } else if (!isset($definedName['localSheetId'])) { + // "Global" definedNames + $locatedSheet = null; + $extractedSheetName = ''; + if (strpos( (string)$definedName, '!' ) !== false) { + // Extract sheet name + $extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true ); + $extractedSheetName = $extractedSheetName[0]; + + // Locate sheet + $locatedSheet = $excel->getSheetByName($extractedSheetName); + + // Modify range + $range = explode('!', $extractedRange); + $extractedRange = isset($range[1]) ? $range[1] : $range[0]; + } + + if ($locatedSheet !== NULL) { + $excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) ); + } + } + } + } + } + + if ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) { + // active sheet index + $activeTab = intval($xmlWorkbook->bookViews->workbookView["activeTab"]); // refers to old sheet index + + // keep active sheet index if sheet is still loaded, else first sheet is set as the active + if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) { + $excel->setActiveSheetIndex($mapSheetId[$activeTab]); + } else { + if ($excel->getSheetCount() == 0) { + $excel->createSheet(); + } + $excel->setActiveSheetIndex(0); + } + } + break; + } + + } + + + if (!$this->_readDataOnly) { + $contentTypes = simplexml_load_string($this->_getFromZipArchive($zip, "[Content_Types].xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + foreach ($contentTypes->Override as $contentType) { + switch ($contentType["ContentType"]) { + case "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": + if ($this->_includeCharts) { + $chartEntryRef = ltrim($contentType['PartName'],'/'); + $chartElements = simplexml_load_string($this->_getFromZipArchive($zip, $chartEntryRef), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml')); + +// echo 'Chart ',$chartEntryRef,'
'; +// var_dump($charts[$chartEntryRef]); +// + if (isset($charts[$chartEntryRef])) { + $chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id']; +// echo 'Position Ref ',$chartPositionRef,'
'; + if (isset($chartDetails[$chartPositionRef])) { +// var_dump($chartDetails[$chartPositionRef]); + + $excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart); + $objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet'])); + $objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'], + $chartDetails[$chartPositionRef]['fromOffsetX'], + $chartDetails[$chartPositionRef]['fromOffsetY'] + ); + $objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'], + $chartDetails[$chartPositionRef]['toOffsetX'], + $chartDetails[$chartPositionRef]['toOffsetY'] + ); + } + } + } + } + } + } + + $zip->close(); + + return $excel; + } + + + private static function _readColor($color, $background=FALSE) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } else if (isset($color["theme"])) { + if (self::$_theme !== NULL) { + $returnColour = self::$_theme->getColourByIndex((int)$color["theme"]); + if (isset($color["tint"])) { + $tintAdjust = (float) $color["tint"]; + $returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust); + } + return 'FF'.$returnColour; + } + } + + if ($background) { + return 'FFFFFFFF'; + } + return 'FF000000'; + } + + + private static function _readStyle($docStyle, $style) { + // format code +// if (isset($style->numFmt)) { +// if (isset($style->numFmt['formatCode'])) { +// $docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']); +// } else { + $docStyle->getNumberFormat()->setFormatCode($style->numFmt); +// } +// } + + // font + if (isset($style->font)) { + $docStyle->getFont()->setName((string) $style->font->name["val"]); + $docStyle->getFont()->setSize((string) $style->font->sz["val"]); + if (isset($style->font->b)) { + $docStyle->getFont()->setBold(!isset($style->font->b["val"]) || self::boolean((string) $style->font->b["val"])); + } + if (isset($style->font->i)) { + $docStyle->getFont()->setItalic(!isset($style->font->i["val"]) || self::boolean((string) $style->font->i["val"])); + } + if (isset($style->font->strike)) { + $docStyle->getFont()->setStrikethrough(!isset($style->font->strike["val"]) || self::boolean((string) $style->font->strike["val"])); + } + $docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color)); + + if (isset($style->font->u) && !isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($style->font->u) && isset($style->font->u["val"])) { + $docStyle->getFont()->setUnderline((string)$style->font->u["val"]); + } + + if (isset($style->font->vertAlign) && isset($style->font->vertAlign["val"])) { + $vertAlign = strtolower((string)$style->font->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $docStyle->getFont()->setSuperScript(true); + } + if ($vertAlign == 'subscript') { + $docStyle->getFont()->setSubScript(true); + } + } + } + + // fill + if (isset($style->fill)) { + if ($style->fill->gradientFill) { + $gradientFill = $style->fill->gradientFill[0]; + if(!empty($gradientFill["type"])) { + $docStyle->getFill()->setFillType((string) $gradientFill["type"]); + } + $docStyle->getFill()->setRotation(floatval($gradientFill["degree"])); + $gradientFill->registerXPathNamespace("sml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=0]"))->color) ); + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath("sml:stop[@position=1]"))->color) ); + } elseif ($style->fill->patternFill) { + $patternType = (string)$style->fill->patternFill["patternType"] != '' ? (string)$style->fill->patternFill["patternType"] : 'solid'; + $docStyle->getFill()->setFillType($patternType); + if ($style->fill->patternFill->fgColor) { + $docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true)); + } else { + $docStyle->getFill()->getStartColor()->setARGB('FF000000'); + } + if ($style->fill->patternFill->bgColor) { + $docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true)); + } + } + } + + // border + if (isset($style->border)) { + $diagonalUp = self::boolean((string) $style->border["diagonalUp"]); + $diagonalDown = self::boolean((string) $style->border["diagonalDown"]); + if (!$diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp && !$diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif (!$diagonalUp && $diagonalDown) { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } else { + $docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + self::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left); + self::_readBorder($docStyle->getBorders()->getRight(), $style->border->right); + self::_readBorder($docStyle->getBorders()->getTop(), $style->border->top); + self::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom); + self::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal); + } + + // alignment + if (isset($style->alignment)) { + $docStyle->getAlignment()->setHorizontal((string) $style->alignment["horizontal"]); + $docStyle->getAlignment()->setVertical((string) $style->alignment["vertical"]); + + $textRotation = 0; + if ((int)$style->alignment["textRotation"] <= 90) { + $textRotation = (int)$style->alignment["textRotation"]; + } else if ((int)$style->alignment["textRotation"] > 90) { + $textRotation = 90 - (int)$style->alignment["textRotation"]; + } + + $docStyle->getAlignment()->setTextRotation(intval($textRotation)); + $docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment["wrapText"])); + $docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment["shrinkToFit"])); + $docStyle->getAlignment()->setIndent( intval((string)$style->alignment["indent"]) > 0 ? intval((string)$style->alignment["indent"]) : 0 ); + } + + // protection + if (isset($style->protection)) { + if (isset($style->protection['locked'])) { + if (self::boolean((string) $style->protection['locked'])) { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + + if (isset($style->protection['hidden'])) { + if (self::boolean((string) $style->protection['hidden'])) { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED); + } else { + $docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + } + } + } + + // top-level style settings + if (isset($style->quotePrefix)) { + $docStyle->setQuotePrefix($style->quotePrefix); + } + } + + + private static function _readBorder($docBorder, $eleBorder) { + if (isset($eleBorder["style"])) { + $docBorder->setBorderStyle((string) $eleBorder["style"]); + } + if (isset($eleBorder->color)) { + $docBorder->getColor()->setARGB(self::_readColor($eleBorder->color)); + } + } + + + private function _parseRichText($is = null) { + $value = new PHPExcel_RichText(); + + if (isset($is->t)) { + $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) ); + } else { + foreach ($is->r as $run) { + if (!isset($run->rPr)) { + $objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + } else { + $objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) ); + + if (isset($run->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $run->rPr->rFont["val"]); + } + + if (isset($run->rPr->sz["val"])) { + $objText->getFont()->setSize((string) $run->rPr->sz["val"]); + } + + if (isset($run->rPr->color)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) ); + } + + if ((isset($run->rPr->b["val"]) && self::boolean((string) $run->rPr->b["val"])) || + (isset($run->rPr->b) && !isset($run->rPr->b["val"]))) { + $objText->getFont()->setBold(TRUE); + } + + if ((isset($run->rPr->i["val"]) && self::boolean((string) $run->rPr->i["val"])) || + (isset($run->rPr->i) && !isset($run->rPr->i["val"]))) { + $objText->getFont()->setItalic(TRUE); + } + + if (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign["val"])) { + $vertAlign = strtolower((string)$run->rPr->vertAlign["val"]); + if ($vertAlign == 'superscript') { + $objText->getFont()->setSuperScript(TRUE); + } + if ($vertAlign == 'subscript') { + $objText->getFont()->setSubScript(TRUE); + } + } + + if (isset($run->rPr->u) && !isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } else if (isset($run->rPr->u) && isset($run->rPr->u["val"])) { + $objText->getFont()->setUnderline((string)$run->rPr->u["val"]); + } + + if ((isset($run->rPr->strike["val"]) && self::boolean((string) $run->rPr->strike["val"])) || + (isset($run->rPr->strike) && !isset($run->rPr->strike["val"]))) { + $objText->getFont()->setStrikethrough(TRUE); + } + } + } + } + + return $value; + } + + private function _readRibbon($excel, $customUITarget, $zip) + { + $baseDir = dirname($customUITarget); + $nameCustomUI = basename($customUITarget); + // get the xml file (ribbon) + $localRibbon = $this->_getFromZipArchive($zip, $customUITarget); + $customUIImagesNames = array(); + $customUIImagesBinaries = array(); + // something like customUI/_rels/customUI.xml.rels + $pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels'; + $dataRels = $this->_getFromZipArchive($zip, $pathRels); + if ($dataRels) { + // exists and not empty if the ribbon have some pictures (other than internal MSO) + $UIRels = simplexml_load_string($dataRels, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($UIRels) { + // we need to save id and target to avoid parsing customUI.xml and "guess" if it's a pseudo callback who load the image + foreach ($UIRels->Relationship as $ele) { + if ($ele["Type"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { + // an image ? + $customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target']; + $customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']); + } + } + } + } + if ($localRibbon) { + $excel->setRibbonXMLData($customUITarget, $localRibbon); + if (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) { + $excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries); + } else { + $excel->setRibbonBinObjects(NULL); + } + } else { + $excel->setRibbonXMLData(NULL); + $excel->setRibbonBinObjects(NULL); + } + } + + private static function array_item($array, $key = 0) { + return (isset($array[$key]) ? $array[$key] : null); + } + + + private static function dir_add($base, $add) { + return preg_replace('~[^/]+/\.\./~', '', dirname($base) . "/$add"); + } + + + private static function toCSSArray($style) { + $style = str_replace(array("\r","\n"), "", $style); + + $temp = explode(';', $style); + $style = array(); + foreach ($temp as $item) { + $item = explode(':', $item); + + if (strpos($item[1], 'px') !== false) { + $item[1] = str_replace('px', '', $item[1]); + } + if (strpos($item[1], 'pt') !== false) { + $item[1] = str_replace('pt', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]); + } + if (strpos($item[1], 'in') !== false) { + $item[1] = str_replace('in', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]); + } + if (strpos($item[1], 'cm') !== false) { + $item[1] = str_replace('cm', '', $item[1]); + $item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]); + } + + $style[$item[0]] = $item[1]; + } + + return $style; + } + + private static function boolean($value = NULL) + { + if (is_object($value)) { + $value = (string) $value; + } + if (is_numeric($value)) { + return (bool) $value; + } + return ($value === 'true' || $value === 'TRUE'); + } +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel2007/Chart.php b/extend/phpexcel/PHPExcel/Reader/Excel2007/Chart.php new file mode 100755 index 0000000..0de88ac --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel2007/Chart.php @@ -0,0 +1,517 @@ +attributes(); + if (isset($attributes[$name])) { + if ($format == 'string') { + return (string) $attributes[$name]; + } elseif ($format == 'integer') { + return (integer) $attributes[$name]; + } elseif ($format == 'boolean') { + return (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true; + } else { + return (float) $attributes[$name]; + } + } + return null; + } // function _getAttribute() + + + private static function _readColor($color,$background=false) { + if (isset($color["rgb"])) { + return (string)$color["rgb"]; + } else if (isset($color["indexed"])) { + return PHPExcel_Style_Color::indexedColor($color["indexed"]-7,$background)->getARGB(); + } + } + + + public static function readChart($chartElements,$chartName) { + $namespacesChartMeta = $chartElements->getNamespaces(true); + $chartElementsC = $chartElements->children($namespacesChartMeta['c']); + + $XaxisLabel = $YaxisLabel = $legend = $title = NULL; + $dispBlanksAs = $plotVisOnly = NULL; + + foreach($chartElementsC as $chartElementKey => $chartElement) { + switch ($chartElementKey) { + case "chart": + foreach($chartElement as $chartDetailsKey => $chartDetails) { + $chartDetailsC = $chartDetails->children($namespacesChartMeta['c']); + switch ($chartDetailsKey) { + case "plotArea": + $plotAreaLayout = $XaxisLable = $YaxisLable = null; + $plotSeries = $plotAttributes = array(); + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "layout": + $plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea'); + break; + case "catAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "dateAx": + if (isset($chartDetail->title)) { + $XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "valAx": + if (isset($chartDetail->title)) { + $YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat'); + } + break; + case "barChart": + case "bar3DChart": + $barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotDirection($barDirection); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "lineChart": + case "line3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "areaChart": + case "area3DChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "doughnutChart": + case "pieChart": + case "pie3DChart": + $explosion = isset($chartDetail->ser->explosion); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($explosion); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "scatterChart": + $scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($scatterStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "bubbleChart": + $bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($bubbleScale); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "radarChart": + $radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($radarStyle); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "surfaceChart": + case "surface3DChart": + $wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean'); + $plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotSer->setPlotStyle($wireFrame); + $plotSeries[] = $plotSer; + $plotAttributes = self::_readChartAttributes($chartDetail); + break; + case "stockChart": + $plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey); + $plotAttributes = self::_readChartAttributes($plotAreaLayout); + break; + } + } + if ($plotAreaLayout == NULL) { + $plotAreaLayout = new PHPExcel_Chart_Layout(); + } + $plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries); + self::_setChartAttributes($plotAreaLayout,$plotAttributes); + break; + case "plotVisOnly": + $plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "dispBlanksAs": + $dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string'); + break; + case "title": + $title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title'); + break; + case "legend": + $legendPos = 'r'; + $legendLayout = null; + $legendOverlay = false; + foreach($chartDetails as $chartDetailKey => $chartDetail) { + switch ($chartDetailKey) { + case "legendPos": + $legendPos = self::_getAttribute($chartDetail, 'val', 'string'); + break; + case "overlay": + $legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean'); + break; + case "layout": + $legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend'); + break; + } + } + $legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay); + break; + } + } + } + } + $chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel); + + return $chart; + } // function readChart() + + + private static function _chartTitle($titleDetails,$namespacesChartMeta,$type) { + $caption = array(); + $titleLayout = null; + foreach($titleDetails as $titleDetailKey => $chartDetail) { + switch ($titleDetailKey) { + case "tx": + $titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']); + foreach($titleDetails as $titleKey => $titleDetail) { + switch ($titleKey) { + case "p": + $titleDetailPart = $titleDetail->children($namespacesChartMeta['a']); + $caption[] = self::_parseRichText($titleDetailPart); + } + } + break; + case "layout": + $titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta); + break; + } + } + + return new PHPExcel_Chart_Title($caption, $titleLayout); + } // function _chartTitle() + + + private static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) { + if (!isset($chartDetail->manualLayout)) { + return null; + } + $details = $chartDetail->manualLayout->children($namespacesChartMeta['c']); + if (is_null($details)) { + return null; + } + $layout = array(); + foreach($details as $detailKey => $detail) { +// echo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL; + $layout[$detailKey] = self::_getAttribute($detail, 'val', 'string'); + } + return new PHPExcel_Chart_Layout($layout); + } // function _chartLayoutDetails() + + + private static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) { + $multiSeriesType = NULL; + $smoothLine = false; + $seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array(); + + $seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']); + foreach($seriesDetailSet as $seriesDetailKey => $seriesDetails) { + switch ($seriesDetailKey) { + case "grouping": + $multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string'); + break; + case "ser": + $marker = NULL; + foreach($seriesDetails as $seriesKey => $seriesDetail) { + switch ($seriesKey) { + case "idx": + $seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer'); + break; + case "order": + $seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer'); + $plotOrder[$seriesIndex] = $seriesOrder; + break; + case "tx": + $seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "marker": + $marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string'); + break; + case "smooth": + $smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean'); + break; + case "cat": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta); + break; + case "val": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "xVal": + $seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + case "yVal": + $seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker); + break; + } + } + } + } + return new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine); + } // function _chartDataSeries() + + + private static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) { + if (isset($seriesDetail->strRef)) { + $seriesSource = (string) $seriesDetail->strRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s'); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->numRef)) { + $seriesSource = (string) $seriesDetail->numRef->f; + $seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c'])); + + return new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlStrRef)) { + $seriesSource = (string) $seriesDetail->multiLvlStrRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } elseif (isset($seriesDetail->multiLvlNumRef)) { + $seriesSource = (string) $seriesDetail->multiLvlNumRef->f; + $seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s'); + $seriesData['pointCount'] = count($seriesData['dataValues']); + + return new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine); + } + return null; + } // function _chartDataSeriesValueSet() + + + private static function _chartDataSeriesValues($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal] = (float) $seriesValue->v; + } + break; + } + } + + if (empty($seriesVal)) { + $seriesVal = NULL; + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValues() + + + private static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') { + $seriesVal = array(); + $formatCode = ''; + $pointCount = 0; + + foreach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) { + foreach($seriesLevel as $seriesValueIdx => $seriesValue) { + switch ($seriesValueIdx) { + case 'ptCount': + $pointCount = self::_getAttribute($seriesValue, 'val', 'integer'); + break; + case 'formatCode': + $formatCode = (string) $seriesValue; + break; + case 'pt': + $pointVal = self::_getAttribute($seriesValue, 'idx', 'integer'); + if ($dataType == 's') { + $seriesVal[$pointVal][] = (string) $seriesValue->v; + } else { + $seriesVal[$pointVal][] = (float) $seriesValue->v; + } + break; + } + } + } + + return array( 'formatCode' => $formatCode, + 'pointCount' => $pointCount, + 'dataValues' => $seriesVal + ); + } // function _chartDataSeriesValuesMultiLevel() + + private static function _parseRichText($titleDetailPart = null) { + $value = new PHPExcel_RichText(); + + foreach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) { + if (isset($titleDetailElement->t)) { + $objText = $value->createTextRun( (string) $titleDetailElement->t ); + } + if (isset($titleDetailElement->rPr)) { + if (isset($titleDetailElement->rPr->rFont["val"])) { + $objText->getFont()->setName((string) $titleDetailElement->rPr->rFont["val"]); + } + + $fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer')); + if (!is_null($fontSize)) { + $objText->getFont()->setSize(floor($fontSize / 100)); + } + + $fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string')); + if (!is_null($fontColor)) { + $objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) ); + } + + $bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean'); + if (!is_null($bold)) { + $objText->getFont()->setBold($bold); + } + + $italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean'); + if (!is_null($italic)) { + $objText->getFont()->setItalic($italic); + } + + $baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer'); + if (!is_null($baseline)) { + if ($baseline > 0) { + $objText->getFont()->setSuperScript(true); + } elseif($baseline < 0) { + $objText->getFont()->setSubScript(true); + } + } + + $underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string')); + if (!is_null($underscore)) { + if ($underscore == 'sng') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + } elseif($underscore == 'dbl') { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + } else { + $objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE); + } + } + + $strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string')); + if (!is_null($strikethrough)) { + if ($strikethrough == 'noStrike') { + $objText->getFont()->setStrikethrough(false); + } else { + $objText->getFont()->setStrikethrough(true); + } + } + } + } + + return $value; + } + + private static function _readChartAttributes($chartDetail) { + $plotAttributes = array(); + if (isset($chartDetail->dLbls)) { + if (isset($chartDetail->dLbls->howLegendKey)) { + $plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showVal)) { + $plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showCatName)) { + $plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showSerName)) { + $plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showPercent)) { + $plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showBubbleSize)) { + $plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string'); + } + if (isset($chartDetail->dLbls->showLeaderLines)) { + $plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string'); + } + } + + return $plotAttributes; + } + + private static function _setChartAttributes($plotArea,$plotAttributes) + { + foreach($plotAttributes as $plotAttributeKey => $plotAttributeValue) { + switch($plotAttributeKey) { + case 'showLegendKey' : + $plotArea->setShowLegendKey($plotAttributeValue); + break; + case 'showVal' : + $plotArea->setShowVal($plotAttributeValue); + break; + case 'showCatName' : + $plotArea->setShowCatName($plotAttributeValue); + break; + case 'showSerName' : + $plotArea->setShowSerName($plotAttributeValue); + break; + case 'showPercent' : + $plotArea->setShowPercent($plotAttributeValue); + break; + case 'showBubbleSize' : + $plotArea->setShowBubbleSize($plotAttributeValue); + break; + case 'showLeaderLines' : + $plotArea->setShowLeaderLines($plotAttributeValue); + break; + } + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel2007/Theme.php b/extend/phpexcel/PHPExcel/Reader/Excel2007/Theme.php new file mode 100755 index 0000000..820fa96 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel2007/Theme.php @@ -0,0 +1,124 @@ +_themeName = $themeName; + $this->_colourSchemeName = $colourSchemeName; + $this->_colourMap = $colourMap; + } + + /** + * Get Theme Name + * + * @return string + */ + public function getThemeName() + { + return $this->_themeName; + } + + /** + * Get colour Scheme Name + * + * @return string + */ + public function getColourSchemeName() { + return $this->_colourSchemeName; + } + + /** + * Get colour Map Value by Position + * + * @return string + */ + public function getColourByIndex($index=0) { + if (isset($this->_colourMap[$index])) { + return $this->_colourMap[$index]; + } + return null; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel5.php b/extend/phpexcel/PHPExcel/Reader/Excel5.php new file mode 100755 index 0000000..b43b315 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel5.php @@ -0,0 +1,7084 @@ +_data + * + * @var int + */ + private $_dataSize; + + /** + * Current position in stream + * + * @var integer + */ + private $_pos; + + /** + * Workbook to be returned by the reader. + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Worksheet that is currently being built by the reader. + * + * @var PHPExcel_Worksheet + */ + private $_phpSheet; + + /** + * BIFF version + * + * @var int + */ + private $_version; + + /** + * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95) + * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE' + * + * @var string + */ + private $_codepage; + + /** + * Shared formats + * + * @var array + */ + private $_formats; + + /** + * Shared fonts + * + * @var array + */ + private $_objFonts; + + /** + * Color palette + * + * @var array + */ + private $_palette; + + /** + * Worksheets + * + * @var array + */ + private $_sheets; + + /** + * External books + * + * @var array + */ + private $_externalBooks; + + /** + * REF structures. Only applies to BIFF8. + * + * @var array + */ + private $_ref; + + /** + * External names + * + * @var array + */ + private $_externalNames; + + /** + * Defined names + * + * @var array + */ + private $_definedname; + + /** + * Shared strings. Only applies to BIFF8. + * + * @var array + */ + private $_sst; + + /** + * Panes are frozen? (in sheet currently being read). See WINDOW2 record. + * + * @var boolean + */ + private $_frozen; + + /** + * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record. + * + * @var boolean + */ + private $_isFitToPages; + + /** + * Objects. One OBJ record contributes with one entry. + * + * @var array + */ + private $_objs; + + /** + * Text Objects. One TXO record corresponds with one entry. + * + * @var array + */ + private $_textObjects; + + /** + * Cell Annotations (BIFF8) + * + * @var array + */ + private $_cellNotes; + + /** + * The combined MSODRAWINGGROUP data + * + * @var string + */ + private $_drawingGroupData; + + /** + * The combined MSODRAWING data (per sheet) + * + * @var string + */ + private $_drawingData; + + /** + * Keep track of XF index + * + * @var int + */ + private $_xfIndex; + + /** + * Mapping of XF index (that is a cell XF) to final index in cellXf collection + * + * @var array + */ + private $_mapCellXfIndex; + + /** + * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection + * + * @var array + */ + private $_mapCellStyleXfIndex; + + /** + * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value. + * + * @var array + */ + private $_sharedFormulas; + + /** + * The shared formula parts in a sheet. One FORMULA record contributes with one value if it + * refers to a shared formula. + * + * @var array + */ + private $_sharedFormulaParts; + + /** + * The type of encryption in use + * + * @var int + */ + private $_encryption = 0; + + /** + * The position in the stream after which contents are encrypted + * + * @var int + */ + private $_encryptionStartPos = false; + + /** + * The current RC4 decryption object + * + * @var PHPExcel_Reader_Excel5_RC4 + */ + private $_rc4Key = null; + + /** + * The position in the stream that the RC4 decryption object was left at + * + * @var int + */ + private $_rc4Pos = 0; + + /** + * The current MD5 context state + * + * @var string + */ + private $_md5Ctxt = null; + + /** + * Create a new PHPExcel_Reader_Excel5 instance + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + try { + // Use ParseXL for the hard work. + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data + $res = $ole->read($pFilename); + return true; + } catch (PHPExcel_Exception $e) { + return false; + } + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetNames = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + foreach ($this->_sheets as $sheet) { + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + $worksheetNames[] = $sheet['name']; + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + // Read the OLE file + $this->_loadOLE($pFilename); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_sheets = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet + // 0x02: Chart + // 0x06: Visual Basic module + continue; + } + + $tmpInfo = array(); + $tmpInfo['worksheetName'] = $sheet['name']; + $tmpInfo['lastColumnLetter'] = 'A'; + $tmpInfo['lastColumnIndex'] = 0; + $tmpInfo['totalRows'] = 0; + $tmpInfo['totalColumns'] = 0; + + $this->_pos = $sheet['offset']; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_RK: + case self::XLS_Type_LABELSST: + case self::XLS_Type_NUMBER: + case self::XLS_Type_FORMULA: + case self::XLS_Type_BOOLERR: + case self::XLS_Type_LABEL: + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $rowIndex = self::_GetInt2d($recordData, 0) + 1; + $columnIndex = self::_GetInt2d($recordData, 2); + + $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex); + $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex); + break; + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; + + $worksheetInfo[] = $tmpInfo; + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Read the OLE file + $this->_loadOLE($pFilename); + + // Initialisations + $this->_phpExcel = new PHPExcel; + $this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet + if (!$this->_readDataOnly) { + $this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style + $this->_phpExcel->removeCellXfByIndex(0); // remove the default style + } + + // Read the summary information stream (containing meta data) + $this->_readSummaryInformation(); + + // Read the Additional document summary information stream (containing application-specific meta data) + $this->_readDocumentSummaryInformation(); + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + // initialize + $this->_pos = 0; + $this->_codepage = 'CP1252'; + $this->_formats = array(); + $this->_objFonts = array(); + $this->_palette = array(); + $this->_sheets = array(); + $this->_externalBooks = array(); + $this->_ref = array(); + $this->_definedname = array(); + $this->_sst = array(); + $this->_drawingGroupData = ''; + $this->_xfIndex = ''; + $this->_mapCellXfIndex = array(); + $this->_mapCellStyleXfIndex = array(); + + // Parse Workbook Global Substream + while ($this->_pos < $this->_dataSize) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_FILEPASS: $this->_readFilepass(); break; + case self::XLS_Type_CODEPAGE: $this->_readCodepage(); break; + case self::XLS_Type_DATEMODE: $this->_readDateMode(); break; + case self::XLS_Type_FONT: $this->_readFont(); break; + case self::XLS_Type_FORMAT: $this->_readFormat(); break; + case self::XLS_Type_XF: $this->_readXf(); break; + case self::XLS_Type_XFEXT: $this->_readXfExt(); break; + case self::XLS_Type_STYLE: $this->_readStyle(); break; + case self::XLS_Type_PALETTE: $this->_readPalette(); break; + case self::XLS_Type_SHEET: $this->_readSheet(); break; + case self::XLS_Type_EXTERNALBOOK: $this->_readExternalBook(); break; + case self::XLS_Type_EXTERNNAME: $this->_readExternName(); break; + case self::XLS_Type_EXTERNSHEET: $this->_readExternSheet(); break; + case self::XLS_Type_DEFINEDNAME: $this->_readDefinedName(); break; + case self::XLS_Type_MSODRAWINGGROUP: $this->_readMsoDrawingGroup(); break; + case self::XLS_Type_SST: $this->_readSst(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + } + + // Resolve indexed colors for font, fill, and border colors + // Cannot be resolved already in XF record, because PALETTE record comes afterwards + if (!$this->_readDataOnly) { + foreach ($this->_objFonts as $objFont) { + if (isset($objFont->colorIndex)) { + $color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version); + $objFont->getColor()->setRGB($color['rgb']); + } + } + + foreach ($this->_phpExcel->getCellXfCollection() as $objStyle) { + // fill start and end color + $fill = $objStyle->getFill(); + + if (isset($fill->startcolorIndex)) { + $startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version); + $fill->getStartColor()->setRGB($startColor['rgb']); + } + + if (isset($fill->endcolorIndex)) { + $endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version); + $fill->getEndColor()->setRGB($endColor['rgb']); + } + + // border colors + $top = $objStyle->getBorders()->getTop(); + $right = $objStyle->getBorders()->getRight(); + $bottom = $objStyle->getBorders()->getBottom(); + $left = $objStyle->getBorders()->getLeft(); + $diagonal = $objStyle->getBorders()->getDiagonal(); + + if (isset($top->colorIndex)) { + $borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version); + $top->getColor()->setRGB($borderTopColor['rgb']); + } + + if (isset($right->colorIndex)) { + $borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version); + $right->getColor()->setRGB($borderRightColor['rgb']); + } + + if (isset($bottom->colorIndex)) { + $borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version); + $bottom->getColor()->setRGB($borderBottomColor['rgb']); + } + + if (isset($left->colorIndex)) { + $borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version); + $left->getColor()->setRGB($borderLeftColor['rgb']); + } + + if (isset($diagonal->colorIndex)) { + $borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version); + $diagonal->getColor()->setRGB($borderDiagonalColor['rgb']); + } + } + } + + // treat MSODRAWINGGROUP records, workbook-level Escher + if (!$this->_readDataOnly && $this->_drawingGroupData) { + $escherWorkbook = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook); + $escherWorkbook = $reader->load($this->_drawingGroupData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingGroupData); + } + + // Parse the individual sheets + foreach ($this->_sheets as $sheet) { + + if ($sheet['sheetType'] != 0x00) { + // 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module + continue; + } + + // check if sheet should be skipped + if (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) { + continue; + } + + // add sheet to PHPExcel object + $this->_phpSheet = $this->_phpExcel->createSheet(); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $this->_phpSheet->setTitle($sheet['name'],false); + $this->_phpSheet->setSheetState($sheet['sheetState']); + + $this->_pos = $sheet['offset']; + + // Initialize isFitToPages. May change after reading SHEETPR record. + $this->_isFitToPages = false; + + // Initialize drawingData + $this->_drawingData = ''; + + // Initialize objs + $this->_objs = array(); + + // Initialize shared formula parts + $this->_sharedFormulaParts = array(); + + // Initialize shared formulas + $this->_sharedFormulas = array(); + + // Initialize text objs + $this->_textObjects = array(); + + // Initialize cell annotations + $this->_cellNotes = array(); + $this->textObjRef = -1; + + while ($this->_pos <= $this->_dataSize - 4) { + $code = self::_GetInt2d($this->_data, $this->_pos); + + switch ($code) { + case self::XLS_Type_BOF: $this->_readBof(); break; + case self::XLS_Type_PRINTGRIDLINES: $this->_readPrintGridlines(); break; + case self::XLS_Type_DEFAULTROWHEIGHT: $this->_readDefaultRowHeight(); break; + case self::XLS_Type_SHEETPR: $this->_readSheetPr(); break; + case self::XLS_Type_HORIZONTALPAGEBREAKS: $this->_readHorizontalPageBreaks(); break; + case self::XLS_Type_VERTICALPAGEBREAKS: $this->_readVerticalPageBreaks(); break; + case self::XLS_Type_HEADER: $this->_readHeader(); break; + case self::XLS_Type_FOOTER: $this->_readFooter(); break; + case self::XLS_Type_HCENTER: $this->_readHcenter(); break; + case self::XLS_Type_VCENTER: $this->_readVcenter(); break; + case self::XLS_Type_LEFTMARGIN: $this->_readLeftMargin(); break; + case self::XLS_Type_RIGHTMARGIN: $this->_readRightMargin(); break; + case self::XLS_Type_TOPMARGIN: $this->_readTopMargin(); break; + case self::XLS_Type_BOTTOMMARGIN: $this->_readBottomMargin(); break; + case self::XLS_Type_PAGESETUP: $this->_readPageSetup(); break; + case self::XLS_Type_PROTECT: $this->_readProtect(); break; + case self::XLS_Type_SCENPROTECT: $this->_readScenProtect(); break; + case self::XLS_Type_OBJECTPROTECT: $this->_readObjectProtect(); break; + case self::XLS_Type_PASSWORD: $this->_readPassword(); break; + case self::XLS_Type_DEFCOLWIDTH: $this->_readDefColWidth(); break; + case self::XLS_Type_COLINFO: $this->_readColInfo(); break; + case self::XLS_Type_DIMENSION: $this->_readDefault(); break; + case self::XLS_Type_ROW: $this->_readRow(); break; + case self::XLS_Type_DBCELL: $this->_readDefault(); break; + case self::XLS_Type_RK: $this->_readRk(); break; + case self::XLS_Type_LABELSST: $this->_readLabelSst(); break; + case self::XLS_Type_MULRK: $this->_readMulRk(); break; + case self::XLS_Type_NUMBER: $this->_readNumber(); break; + case self::XLS_Type_FORMULA: $this->_readFormula(); break; + case self::XLS_Type_SHAREDFMLA: $this->_readSharedFmla(); break; + case self::XLS_Type_BOOLERR: $this->_readBoolErr(); break; + case self::XLS_Type_MULBLANK: $this->_readMulBlank(); break; + case self::XLS_Type_LABEL: $this->_readLabel(); break; + case self::XLS_Type_BLANK: $this->_readBlank(); break; + case self::XLS_Type_MSODRAWING: $this->_readMsoDrawing(); break; + case self::XLS_Type_OBJ: $this->_readObj(); break; + case self::XLS_Type_WINDOW2: $this->_readWindow2(); break; + case self::XLS_Type_PAGELAYOUTVIEW: $this->_readPageLayoutView(); break; + case self::XLS_Type_SCL: $this->_readScl(); break; + case self::XLS_Type_PANE: $this->_readPane(); break; + case self::XLS_Type_SELECTION: $this->_readSelection(); break; + case self::XLS_Type_MERGEDCELLS: $this->_readMergedCells(); break; + case self::XLS_Type_HYPERLINK: $this->_readHyperLink(); break; + case self::XLS_Type_DATAVALIDATIONS: $this->_readDataValidations(); break; + case self::XLS_Type_DATAVALIDATION: $this->_readDataValidation(); break; + case self::XLS_Type_SHEETLAYOUT: $this->_readSheetLayout(); break; + case self::XLS_Type_SHEETPROTECTION: $this->_readSheetProtection(); break; + case self::XLS_Type_RANGEPROTECTION: $this->_readRangeProtection(); break; + case self::XLS_Type_NOTE: $this->_readNote(); break; + //case self::XLS_Type_IMDATA: $this->_readImData(); break; + case self::XLS_Type_TXO: $this->_readTextObject(); break; + case self::XLS_Type_CONTINUE: $this->_readContinue(); break; + case self::XLS_Type_EOF: $this->_readDefault(); break 2; + default: $this->_readDefault(); break; + } + + } + + // treat MSODRAWING records, sheet-level Escher + if (!$this->_readDataOnly && $this->_drawingData) { + $escherWorksheet = new PHPExcel_Shared_Escher(); + $reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet); + $escherWorksheet = $reader->load($this->_drawingData); + + // debug Escher stream + //$debug = new Debug_Escher(new PHPExcel_Shared_Escher()); + //$debug->load($this->_drawingData); + + // get all spContainers in one long array, so they can be mapped to OBJ records + $allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers(); + } + + // treat OBJ records + foreach ($this->_objs as $n => $obj) { +// echo '
Object reference is ',$n,'
'; +// var_dump($obj); +// echo '
'; + + // the first shape container never has a corresponding OBJ record, hence $n + 1 + if (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) { + $spContainer = $allSpContainers[$n + 1]; + + // we skip all spContainers that are a part of a group shape since we cannot yet handle those + if ($spContainer->getNestingLevel() > 1) { + continue; + } + + // calculate the width and height of the shape + list($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates()); + list($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates()); + + $startOffsetX = $spContainer->getStartOffsetX(); + $startOffsetY = $spContainer->getStartOffsetY(); + $endOffsetX = $spContainer->getEndOffsetX(); + $endOffsetY = $spContainer->getEndOffsetY(); + + $width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX); + $height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY); + + // calculate offsetX and offsetY of the shape + $offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024; + $offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256; + + switch ($obj['otObjType']) { + case 0x19: + // Note +// echo 'Cell Annotation Object
'; +// echo 'Object ID is ',$obj['idObjID'],'
'; +// + if (isset($this->_cellNotes[$obj['idObjID']])) { + $cellNote = $this->_cellNotes[$obj['idObjID']]; + + if (isset($this->_textObjects[$obj['idObjID']])) { + $textObject = $this->_textObjects[$obj['idObjID']]; + $this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject; + } + } + break; + + case 0x08: +// echo 'Picture Object
'; + // picture + + // get index to BSE entry (1-based) + $BSEindex = $spContainer->getOPT(0x0104); + $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection(); + $BSE = $BSECollection[$BSEindex - 1]; + $blipType = $BSE->getBlipType(); + + // need check because some blip types are not supported by Escher reader such as EMF + if ($blip = $BSE->getBlip()) { + $ih = imagecreatefromstring($blip->getData()); + $drawing = new PHPExcel_Worksheet_MemoryDrawing(); + $drawing->setImageResource($ih); + + // width, height, offsetX, offsetY + $drawing->setResizeProportional(false); + $drawing->setWidth($width); + $drawing->setHeight($height); + $drawing->setOffsetX($offsetX); + $drawing->setOffsetY($offsetY); + + switch ($blipType) { + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG); + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + $drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG); + $drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG); + break; + } + + $drawing->setWorksheet($this->_phpSheet); + $drawing->setCoordinates($spContainer->getStartCoordinates()); + } + + break; + + default: + // other object type + break; + + } + } + } + + // treat SHAREDFMLA records + if ($this->_version == self::XLS_BIFF8) { + foreach ($this->_sharedFormulaParts as $cell => $baseCell) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($cell); + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) { + $formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell); + $this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + + if (!empty($this->_cellNotes)) { + foreach($this->_cellNotes as $note => $noteDetails) { + if (!isset($noteDetails['objTextData'])) { + if (isset($this->_textObjects[$note])) { + $textObject = $this->_textObjects[$note]; + $noteDetails['objTextData'] = $textObject; + } else { + $noteDetails['objTextData']['text'] = ''; + } + } +// echo 'Cell annotation ',$note,'
'; +// var_dump($noteDetails); +// echo '
'; + $cellAddress = str_replace('$','',$noteDetails['cellRef']); + $this->_phpSheet->getComment( $cellAddress ) + ->setAuthor( $noteDetails['author'] ) + ->setText($this->_parseRichText($noteDetails['objTextData']['text']) ); + } + } + } + + // add the named ranges (defined names) + foreach ($this->_definedname as $definedName) { + if ($definedName['isBuiltInName']) { + switch ($definedName['name']) { + + case pack('C', 0x06): + // print area + // in general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2 + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + $extractedRanges = array(); + foreach ($ranges as $range) { + // $range should look like one of these + // Foo!$C$7:$J$66 + // Bar!$A$1:$IV$2 + + $explodes = explode('!', $range); // FIXME: what if sheetname contains exclamation mark? + $sheetName = trim($explodes[0], "'"); + + if (count($explodes) == 2) { + if (strpos($explodes[1], ':') === FALSE) { + $explodes[1] = $explodes[1] . ':' . $explodes[1]; + } + $extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66 + } + } + if ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) { + $docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2 + } + break; + + case pack('C', 0x07): + // print titles (repeating rows) + // Assuming BIFF8, there are 3 cases + // 1. repeating rows + // formula looks like this: Sheet!$A$1:$IV$2 + // rows 1-2 repeat + // 2. repeating columns + // formula looks like this: Sheet!$A$1:$B$65536 + // columns A-B repeat + // 3. both repeating rows and repeating columns + // formula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2 + + $ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma? + + foreach ($ranges as $range) { + // $range should look like this one of these + // Sheet!$A$1:$B$65536 + // Sheet!$A$1:$IV$2 + + $explodes = explode('!', $range); + + if (count($explodes) == 2) { + if ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) { + + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $coordinateStrings = explode(':', $extractedRange); + if (count($coordinateStrings) == 2) { + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]); + + if ($firstColumn == 'A' and $lastColumn == 'IV') { + // then we have repeating rows + $docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow)); + } elseif ($firstRow == 1 and $lastRow == 65536) { + // then we have repeating columns + $docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn)); + } + } + } + } + } + break; + + } + } else { + // Extract range + $explodes = explode('!', $definedName['formula']); + + if (count($explodes) == 2) { + if (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) || + ($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],"'")))) { + $extractedRange = $explodes[1]; + $extractedRange = str_replace('$', '', $extractedRange); + + $localOnly = ($definedName['scope'] == 0) ? false : true; + + $scope = ($definedName['scope'] == 0) ? + null : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']); + + $this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) ); + } + } else { + // Named Value + // TODO Provide support for named values + } + } + } + + return $this->_phpExcel; + } + + /** + * Read record data from stream, decrypting as required + * + * @param string $data Data stream to read from + * @param int $pos Position to start reading from + * @param int $length Record data length + * + * @return string Record data + */ + private function _readRecordData($data, $pos, $len) + { + $data = substr($data, $pos, $len); + + // File not encrypted, or record before encryption start point + if ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) { + return $data; + } + + $recordData = ''; + if ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) { + + $oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK); + $block = floor($pos / self::REKEY_BLOCK); + $endBlock = floor(($pos + $len) / self::REKEY_BLOCK); + + // Spin an RC4 decryptor to the right spot. If we have a decryptor sitting + // at a point earlier in the current block, re-use it as we can save some time. + if ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) { + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + $step = $pos % self::REKEY_BLOCK; + } else { + $step = $pos - $this->_rc4Pos; + } + $this->_rc4Key->RC4(str_repeat("\0", $step)); + + // Decrypt record data (re-keying at the end of every block) + while ($block != $endBlock) { + $step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK); + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $step)); + $data = substr($data, $step); + $pos += $step; + $len -= $step; + $block++; + $this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt); + } + $recordData .= $this->_rc4Key->RC4(substr($data, 0, $len)); + + // Keep track of the position of this decryptor. + // We'll try and re-use it later if we can to speed things up + $this->_rc4Pos = $pos + $len; + + } elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) { + throw new PHPExcel_Reader_Exception('XOr encryption not supported'); + } + return $recordData; + } + + /** + * Use OLE reader to extract the relevant data streams from the OLE file + * + * @param string $pFilename + */ + private function _loadOLE($pFilename) + { + // OLE reader + $ole = new PHPExcel_Shared_OLERead(); + + // get excel data, + $res = $ole->read($pFilename); + // Get workbook data: workbook stream + sheet streams + $this->_data = $ole->getStream($ole->wrkbook); + + // Get summary information data + $this->_summaryInformation = $ole->getStream($ole->summaryInformation); + + // Get additional document summary information data + $this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation); + + // Get user-defined property data +// $this->_userDefinedProperties = $ole->getUserDefinedProperties(); + } + + + /** + * Read summary information + */ + private function _readSummaryInformation() + { + if (!isset($this->_summaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_summaryInformation, 24); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + // offset: 44; size: 4 + $secOffset = self::_GetInt4d($this->_summaryInformation, 44); + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_summaryInformation, $secOffset); + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4); + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { + + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i)); + + // Use value of property id as appropriate + // offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset); + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Title + $this->_phpExcel->getProperties()->setTitle($value); + break; + + case 0x03: // Subject + $this->_phpExcel->getProperties()->setSubject($value); + break; + + case 0x04: // Author (Creator) + $this->_phpExcel->getProperties()->setCreator($value); + break; + + case 0x05: // Keywords + $this->_phpExcel->getProperties()->setKeywords($value); + break; + + case 0x06: // Comments (Description) + $this->_phpExcel->getProperties()->setDescription($value); + break; + + case 0x07: // Template + // Not supported by PHPExcel + break; + + case 0x08: // Last Saved By (LastModifiedBy) + $this->_phpExcel->getProperties()->setLastModifiedBy($value); + break; + + case 0x09: // Revision + // Not supported by PHPExcel + break; + + case 0x0A: // Total Editing Time + // Not supported by PHPExcel + break; + + case 0x0B: // Last Printed + // Not supported by PHPExcel + break; + + case 0x0C: // Created Date/Time + $this->_phpExcel->getProperties()->setCreated($value); + break; + + case 0x0D: // Modified Date/Time + $this->_phpExcel->getProperties()->setModified($value); + break; + + case 0x0E: // Number of Pages + // Not supported by PHPExcel + break; + + case 0x0F: // Number of Words + // Not supported by PHPExcel + break; + + case 0x10: // Number of Characters + // Not supported by PHPExcel + break; + + case 0x11: // Thumbnail + // Not supported by PHPExcel + break; + + case 0x12: // Name of creating application + // Not supported by PHPExcel + break; + + case 0x13: // Security + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Read additional document summary information + */ + private function _readDocumentSummaryInformation() + { + if (!isset($this->_documentSummaryInformation)) { + return; + } + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + // offset: 2; size: 2; + // offset: 4; size: 2; OS version + // offset: 6; size: 2; OS indicator + // offset: 8; size: 16 + // offset: 24; size: 4; section count + $secCount = self::_GetInt4d($this->_documentSummaryInformation, 24); +// echo '$secCount = ',$secCount,'
'; + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + // offset: 44; size: 4; first section offset + $secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44); +// echo '$secOffset = ',$secOffset,'
'; + + // section header + // offset: $secOffset; size: 4; section length + $secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset); +// echo '$secLength = ',$secLength,'
'; + + // offset: $secOffset+4; size: 4; property count + $countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4); +// echo '$countProperties = ',$countProperties,'
'; + + // initialize code page (used to resolve string values) + $codePage = 'CP1252'; + + // offset: ($secOffset+8); size: var + // loop through property decarations and properties + for ($i = 0; $i < $countProperties; ++$i) { +// echo 'Property ',$i,'
'; + // offset: ($secOffset+8) + (8 * $i); size: 4; property ID + $id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i)); +// echo 'ID is ',$id,'
'; + + // Use value of property id as appropriate + // offset: 60 + 8 * $i; size: 4; offset from beginning of section (48) + $offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i)); + + $type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset); +// echo 'Type is ',$type,', '; + + // initialize property value + $value = null; + + // extract property value based on property type + switch ($type) { + case 0x02: // 2 byte signed integer + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x03: // 4 byte signed integer + $value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + break; + + case 0x0B: // Boolean + $value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = ($value == 0 ? false : true); + break; + + case 0x13: // 4 byte unsigned integer + // not needed yet, fix later if necessary + break; + + case 0x1E: // null-terminated string prepended by dword string length + $byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset); + $value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength); + $value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage); + $value = rtrim($value); + break; + + case 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + // PHP-Time + $value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8)); + break; + + case 0x47: // Clipboard format + // not needed yet, fix later if necessary + break; + } + + switch ($id) { + case 0x01: // Code Page + $codePage = PHPExcel_Shared_CodePage::NumberToName($value); + break; + + case 0x02: // Category + $this->_phpExcel->getProperties()->setCategory($value); + break; + + case 0x03: // Presentation Target + // Not supported by PHPExcel + break; + + case 0x04: // Bytes + // Not supported by PHPExcel + break; + + case 0x05: // Lines + // Not supported by PHPExcel + break; + + case 0x06: // Paragraphs + // Not supported by PHPExcel + break; + + case 0x07: // Slides + // Not supported by PHPExcel + break; + + case 0x08: // Notes + // Not supported by PHPExcel + break; + + case 0x09: // Hidden Slides + // Not supported by PHPExcel + break; + + case 0x0A: // MM Clips + // Not supported by PHPExcel + break; + + case 0x0B: // Scale Crop + // Not supported by PHPExcel + break; + + case 0x0C: // Heading Pairs + // Not supported by PHPExcel + break; + + case 0x0D: // Titles of Parts + // Not supported by PHPExcel + break; + + case 0x0E: // Manager + $this->_phpExcel->getProperties()->setManager($value); + break; + + case 0x0F: // Company + $this->_phpExcel->getProperties()->setCompany($value); + break; + + case 0x10: // Links up-to-date + // Not supported by PHPExcel + break; + + } + } + } + + + /** + * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record. + */ + private function _readDefault() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); +// $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + } + + + /** + * The NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions, + * this record stores a note (cell note). This feature was significantly enhanced in Excel 97. + */ + private function _readNote() + { +// echo 'Read Cell Annotation
'; + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + $cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4)); + if ($this->_version == self::XLS_BIFF8) { + $noteObjID = self::_GetInt2d($recordData, 6); + $noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8)); + $noteAuthor = $noteAuthor['value']; +// echo 'Note Address=',$cellAddress,'
'; +// echo 'Note Object ID=',$noteObjID,'
'; +// echo 'Note Author=',$noteAuthor,'
'; +// + $this->_cellNotes[$noteObjID] = array('cellRef' => $cellAddress, + 'objectID' => $noteObjID, + 'author' => $noteAuthor + ); + } else { + $extension = false; + if ($cellAddress == '$B$65536') { + // If the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation + // note from the previous cell annotation. We're not yet handling this, so annotations longer than the + // max 2048 bytes will probably throw a wobbly. + $row = self::_GetInt2d($recordData, 0); + $extension = true; + $cellAddress = array_pop(array_keys($this->_phpSheet->getComments())); + } +// echo 'Note Address=',$cellAddress,'
'; + + $cellAddress = str_replace('$','',$cellAddress); + $noteLength = self::_GetInt2d($recordData, 4); + $noteText = trim(substr($recordData, 6)); +// echo 'Note Length=',$noteLength,'
'; +// echo 'Note Text=',$noteText,'
'; + + if ($extension) { + // Concatenate this extension with the currently set comment for the cell + $comment = $this->_phpSheet->getComment( $cellAddress ); + $commentText = $comment->getText()->getPlainText(); + $comment->setText($this->_parseRichText($commentText.$noteText) ); + } else { + // Set comment for the cell + $this->_phpSheet->getComment( $cellAddress ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($noteText) ); + } + } + + } + + + /** + * The TEXT Object record contains the text associated with a cell annotation. + */ + private function _readTextObject() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // grbit: 2 bytes; Option Flags + // rot: 2 bytes; rotation + // cchText: 2 bytes; length of the text (in the first continue record) + // cbRuns: 2 bytes; length of the formatting (in the second continue record) + // followed by the continuation records containing the actual text and formatting + $grbitOpts = self::_GetInt2d($recordData, 0); + $rot = self::_GetInt2d($recordData, 2); + $cchText = self::_GetInt2d($recordData, 10); + $cbRuns = self::_GetInt2d($recordData, 12); + $text = $this->_getSplicedRecordData(); + + $this->_textObjects[$this->textObjRef] = array( + 'text' => substr($text["recordData"],$text["spliceOffsets"][0]+1,$cchText), + 'format' => substr($text["recordData"],$text["spliceOffsets"][1],$cbRuns), + 'alignment' => $grbitOpts, + 'rotation' => $rot + ); + +// echo '_readTextObject()
'; +// var_dump($this->_textObjects[$this->textObjRef]); +// echo '
'; + } + + + /** + * Read BOF + */ + private function _readBof() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = substr($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 2; size: 2; type of the following data + $substreamType = self::_GetInt2d($recordData, 2); + + switch ($substreamType) { + case self::XLS_WorkbookGlobals: + $version = self::_GetInt2d($recordData, 0); + if (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) { + throw new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.'); + } + $this->_version = $version; + break; + + case self::XLS_Worksheet: + // do not use this version information for anything + // it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream + break; + + default: + // substream, e.g. chart + // just skip the entire substream + do { + $code = self::_GetInt2d($this->_data, $this->_pos); + $this->_readDefault(); + } while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize); + break; + } + } + + + /** + * FILEPASS + * + * This record is part of the File Protection Block. It + * contains information about the read/write password of the + * file. All record contents following this record will be + * encrypted. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + * + * The decryption functions and objects used from here on in + * are based on the source of Spreadsheet-ParseExcel: + * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/ + */ + private function _readFilepass() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + if ($length != 54) { + throw new PHPExcel_Reader_Exception('Unexpected file pass record length'); + } + + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_verifyPassword( + 'VelvetSweatshop', + substr($recordData, 6, 16), + substr($recordData, 22, 16), + substr($recordData, 38, 16), + $this->_md5Ctxt + )) { + throw new PHPExcel_Reader_Exception('Decryption password incorrect'); + } + + $this->_encryption = self::MS_BIFF_CRYPTO_RC4; + + // Decryption required from the record after next onwards + $this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2); + } + + /** + * Make an RC4 decryptor for the given block + * + * @var int $block Block for which to create decrypto + * @var string $valContext MD5 context state + * + * @return PHPExcel_Reader_Excel5_RC4 + */ + private function _makeKey($block, $valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < 5; $i++) { + $pwarray[$i] = $valContext[$i]; + } + + $pwarray[5] = chr($block & 0xff); + $pwarray[6] = chr(($block >> 8) & 0xff); + $pwarray[7] = chr(($block >> 16) & 0xff); + $pwarray[8] = chr(($block >> 24) & 0xff); + + $pwarray[9] = "\x80"; + $pwarray[56] = "\x48"; + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $s = $md5->getContext(); + return new PHPExcel_Reader_Excel5_RC4($s); + } + + /** + * Verify RC4 file password + * + * @var string $password Password to check + * @var string $docid Document id + * @var string $salt_data Salt data + * @var string $hashedsalt_data Hashed salt data + * @var string &$valContext Set to the MD5 context of the value + * + * @return bool Success + */ + private function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext) + { + $pwarray = str_repeat("\0", 64); + + for ($i = 0; $i < strlen($password); $i++) { + $o = ord(substr($password, $i, 1)); + $pwarray[2 * $i] = chr($o & 0xff); + $pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff); + } + $pwarray[2 * $i] = chr(0x80); + $pwarray[56] = chr(($i << 4) & 0xff); + + $md5 = new PHPExcel_Reader_Excel5_MD5(); + $md5->add($pwarray); + + $mdContext1 = $md5->getContext(); + + $offset = 0; + $keyoffset = 0; + $tocopy = 5; + + $md5->reset(); + + while ($offset != 16) { + if ((64 - $offset) < 5) { + $tocopy = 64 - $offset; + } + + for ($i = 0; $i <= $tocopy; $i++) { + $pwarray[$offset + $i] = $mdContext1[$keyoffset + $i]; + } + + $offset += $tocopy; + + if ($offset == 64) { + $md5->add($pwarray); + $keyoffset = $tocopy; + $tocopy = 5 - $tocopy; + $offset = 0; + continue; + } + + $keyoffset = 0; + $tocopy = 5; + for ($i = 0; $i < 16; $i++) { + $pwarray[$offset + $i] = $docid[$i]; + } + $offset += 16; + } + + $pwarray[16] = "\x80"; + for ($i = 0; $i < 47; $i++) { + $pwarray[17 + $i] = "\0"; + } + $pwarray[56] = "\x80"; + $pwarray[57] = "\x0a"; + + $md5->add($pwarray); + $valContext = $md5->getContext(); + + $key = $this->_makeKey(0, $valContext); + + $salt = $key->RC4($salt_data); + $hashedsalt = $key->RC4($hashedsalt_data); + + $salt .= "\x80" . str_repeat("\0", 47); + $salt[56] = "\x80"; + + $md5->reset(); + $md5->add($salt); + $mdContext2 = $md5->getContext(); + + return $mdContext2 == $hashedsalt; + } + + /** + * CODEPAGE + * + * This record stores the text encoding used to write byte + * strings, stored as MS Windows code page identifier. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readCodepage() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; code page identifier + $codepage = self::_GetInt2d($recordData, 0); + + $this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage); + } + + + /** + * DATEMODE + * + * This record specifies the base date for displaying date + * values. All dates are stored as count of days past this + * base date. In BIFF2-BIFF4 this record is part of the + * Calculation Settings Block. In BIFF5-BIFF8 it is + * stored in the Workbook Globals Substream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDateMode() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900); + if (ord($recordData{0}) == 1) { + PHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904); + } + } + + + /** + * Read a FONT record + */ + private function _readFont() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $objFont = new PHPExcel_Style_Font(); + + // offset: 0; size: 2; height of the font (in twips = 1/20 of a point) + $size = self::_GetInt2d($recordData, 0); + $objFont->setSize($size / 20); + + // offset: 2; size: 2; option flags + // bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8) + // bit: 1; mask 0x0002; italic + $isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1; + if ($isItalic) $objFont->setItalic(true); + + // bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8) + // bit: 3; mask 0x0008; strike + $isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3; + if ($isStrike) $objFont->setStrikethrough(true); + + // offset: 4; size: 2; colour index + $colorIndex = self::_GetInt2d($recordData, 4); + $objFont->colorIndex = $colorIndex; + + // offset: 6; size: 2; font weight + $weight = self::_GetInt2d($recordData, 6); + switch ($weight) { + case 0x02BC: + $objFont->setBold(true); + break; + } + + // offset: 8; size: 2; escapement type + $escapement = self::_GetInt2d($recordData, 8); + switch ($escapement) { + case 0x0001: + $objFont->setSuperScript(true); + break; + case 0x0002: + $objFont->setSubScript(true); + break; + } + + // offset: 10; size: 1; underline type + $underlineType = ord($recordData{10}); + switch ($underlineType) { + case 0x00: + break; // no underline + case 0x01: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE); + break; + case 0x02: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE); + break; + case 0x21: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING); + break; + case 0x22: + $objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING); + break; + } + + // offset: 11; size: 1; font family + // offset: 12; size: 1; character set + // offset: 13; size: 1; not used + // offset: 14; size: var; font name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 14)); + } else { + $string = $this->_readByteStringShort(substr($recordData, 14)); + } + $objFont->setName($string['value']); + + $this->_objFonts[] = $objFont; + } + } + + + /** + * FORMAT + * + * This record contains information about a number format. + * All FORMAT records occur together in a sequential list. + * + * In BIFF2-BIFF4 other records referencing a FORMAT record + * contain a zero-based index into this list. From BIFF5 on + * the FORMAT record contains the index itself that will be + * used by other records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormat() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + $indexCode = self::_GetInt2d($recordData, 0); + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 2)); + } else { + // BIFF7 + $string = $this->_readByteStringShort(substr($recordData, 2)); + } + + $formatString = $string['value']; + $this->_formats[$indexCode] = $formatString; + } + } + + + /** + * XF - Extended Format + * + * This record contains formatting information for cells, rows, columns or styles. + * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF + * and 1 cell XF. + * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF + * and XF record 15 is a cell XF + * We only read the first cell style XF and skip the remaining cell style XF records + * We read all cell XF records. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readXf() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + $objStyle = new PHPExcel_Style(); + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; Index to FONT record + if (self::_GetInt2d($recordData, 0) < 4) { + $fontIndex = self::_GetInt2d($recordData, 0); + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = self::_GetInt2d($recordData, 0) - 1; + } + $objStyle->setFont($this->_objFonts[$fontIndex]); + + // offset: 2; size: 2; Index to FORMAT record + $numberFormatIndex = self::_GetInt2d($recordData, 2); + if (isset($this->_formats[$numberFormatIndex])) { + // then we have user-defined format code + $numberformat = array('code' => $this->_formats[$numberFormatIndex]); + } elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') { + // then we have built-in format code + $numberformat = array('code' => $code); + } else { + // we set the general format code + $numberformat = array('code' => 'General'); + } + $objStyle->getNumberFormat()->setFormatCode($numberformat['code']); + + // offset: 4; size: 2; XF type, cell protection, and parent style XF + // bit 2-0; mask 0x0007; XF_TYPE_PROT + $xfTypeProt = self::_GetInt2d($recordData, 4); + // bit 0; mask 0x01; 1 = cell is locked + $isLocked = (0x01 & $xfTypeProt) >> 0; + $objStyle->getProtection()->setLocked($isLocked ? + PHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 1; mask 0x02; 1 = Formula is hidden + $isHidden = (0x02 & $xfTypeProt) >> 1; + $objStyle->getProtection()->setHidden($isHidden ? + PHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED); + + // bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF + $isCellStyleXf = (0x04 & $xfTypeProt) >> 2; + + // offset: 6; size: 1; Alignment and text break + // bit 2-0, mask 0x07; horizontal alignment + $horAlign = (0x07 & ord($recordData{6})) >> 0; + switch ($horAlign) { + case 0: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL); + break; + case 1: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT); + break; + case 2: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); + break; + case 3: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); + break; + case 4: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL); + break; + case 5: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY); + break; + case 6: + $objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS); + break; + } + // bit 3, mask 0x08; wrap text + $wrapText = (0x08 & ord($recordData{6})) >> 3; + switch ($wrapText) { + case 0: + $objStyle->getAlignment()->setWrapText(false); + break; + case 1: + $objStyle->getAlignment()->setWrapText(true); + break; + } + // bit 6-4, mask 0x70; vertical alignment + $vertAlign = (0x70 & ord($recordData{6})) >> 4; + switch ($vertAlign) { + case 0: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP); + break; + case 1: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER); + break; + case 2: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM); + break; + case 3: + $objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY); + break; + } + + if ($this->_version == self::XLS_BIFF8) { + // offset: 7; size: 1; XF_ROTATION: Text rotation angle + $angle = ord($recordData{7}); + $rotation = 0; + if ($angle <= 90) { + $rotation = $angle; + } else if ($angle <= 180) { + $rotation = 90 - $angle; + } else if ($angle == 255) { + $rotation = -165; + } + $objStyle->getAlignment()->setTextRotation($rotation); + + // offset: 8; size: 1; Indentation, shrink to cell size, and text direction + // bit: 3-0; mask: 0x0F; indent level + $indent = (0x0F & ord($recordData{8})) >> 0; + $objStyle->getAlignment()->setIndent($indent); + + // bit: 4; mask: 0x10; 1 = shrink content to fit into cell + $shrinkToFit = (0x10 & ord($recordData{8})) >> 4; + switch ($shrinkToFit) { + case 0: + $objStyle->getAlignment()->setShrinkToFit(false); + break; + case 1: + $objStyle->getAlignment()->setShrinkToFit(true); + break; + } + + // offset: 9; size: 1; Flags used for attribute groups + + // offset: 10; size: 4; Cell border lines and background area + // bit: 3-0; mask: 0x0000000F; left style + if ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) { + $objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle); + } + // bit: 7-4; mask: 0x000000F0; right style + if ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) { + $objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle); + } + // bit: 11-8; mask: 0x00000F00; top style + if ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) { + $objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle); + } + // bit: 15-12; mask: 0x0000F000; bottom style + if ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) { + $objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle); + } + // bit: 22-16; mask: 0x007F0000; left color + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16; + + // bit: 29-23; mask: 0x3F800000; right color + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23; + + // bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom + $diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ? + true : false; + + // bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right + $diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ? + true : false; + + if ($diagonalUp == false && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE); + } elseif ($diagonalUp == true && $diagonalDown == false) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP); + } elseif ($diagonalUp == false && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN); + } elseif ($diagonalUp == true && $diagonalDown == true) { + $objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH); + } + + // offset: 14; size: 4; + // bit: 6-0; mask: 0x0000007F; top color + $objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0; + + // bit: 13-7; mask: 0x00003F80; bottom color + $objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7; + + // bit: 20-14; mask: 0x001FC000; diagonal color + $objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14; + + // bit: 24-21; mask: 0x01E00000; diagonal style + if ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) { + $objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle); + } + + // bit: 31-26; mask: 0xFC000000 fill pattern + if ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) { + $objStyle->getFill()->setFillType($fillType); + } + // offset: 18; size: 2; pattern and background colour + // bit: 6-0; mask: 0x007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0; + + // bit: 13-7; mask: 0x3F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7; + } else { + // BIFF5 + + // offset: 7; size: 1; Text orientation and flags + $orientationAndFlags = ord($recordData{7}); + + // bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation + $xfOrientation = (0x03 & $orientationAndFlags) >> 0; + switch ($xfOrientation) { + case 0: + $objStyle->getAlignment()->setTextRotation(0); + break; + case 1: + $objStyle->getAlignment()->setTextRotation(-165); + break; + case 2: + $objStyle->getAlignment()->setTextRotation(90); + break; + case 3: + $objStyle->getAlignment()->setTextRotation(-90); + break; + } + + // offset: 8; size: 4; cell border lines and background area + $borderAndBackground = self::_GetInt4d($recordData, 8); + + // bit: 6-0; mask: 0x0000007F; color index for pattern color + $objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0; + + // bit: 13-7; mask: 0x00003F80; color index for pattern background + $objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7; + + // bit: 21-16; mask: 0x003F0000; fill pattern + $objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16)); + + // bit: 24-22; mask: 0x01C00000; bottom line style + $objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22)); + + // bit: 31-25; mask: 0xFE000000; bottom line color + $objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25; + + // offset: 12; size: 4; cell border lines + $borderLines = self::_GetInt4d($recordData, 12); + + // bit: 2-0; mask: 0x00000007; top line style + $objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0)); + + // bit: 5-3; mask: 0x00000038; left line style + $objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3)); + + // bit: 8-6; mask: 0x000001C0; right line style + $objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6)); + + // bit: 15-9; mask: 0x0000FE00; top line color index + $objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9; + + // bit: 22-16; mask: 0x007F0000; left line color index + $objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16; + + // bit: 29-23; mask: 0x3F800000; right line color index + $objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23; + } + + // add cellStyleXf or cellXf and update mapping + if ($isCellStyleXf) { + // we only read one style XF record which is always the first + if ($this->_xfIndex == 0) { + $this->_phpExcel->addCellStyleXf($objStyle); + $this->_mapCellStyleXfIndex[$this->_xfIndex] = 0; + } + } else { + // we read all cell XF records + $this->_phpExcel->addCellXf($objStyle); + $this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1; + } + + // update XF index for when we read next record + ++$this->_xfIndex; + } + } + + + /** + * + */ + private function _readXfExt() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0x087D = repeated header + + // offset: 2; size: 2 + + // offset: 4; size: 8; not used + + // offset: 12; size: 2; record version + + // offset: 14; size: 2; index to XF record which this record modifies + $ixfe = self::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; not used + + // offset: 18; size: 2; number of extension properties that follow + $cexts = self::_GetInt2d($recordData, 18); + + // start reading the actual extension data + $offset = 20; + while ($offset < $length) { + // extension type + $extType = self::_GetInt2d($recordData, $offset); + + // extension length + $cb = self::_GetInt2d($recordData, $offset + 2); + + // extension data + $extData = substr($recordData, $offset + 4, $cb); + + switch ($extType) { + case 4: // fill start color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getStartColor()->setRGB($rgb); + unset($fill->startcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 5: // fill end color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill(); + $fill->getEndColor()->setRGB($rgb); + unset($fill->endcolorIndex); // normal color index does not apply, discard + } + } + break; + + case 7: // border color top + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop(); + $top->getColor()->setRGB($rgb); + unset($top->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 8: // border color bottom + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom(); + $bottom->getColor()->setRGB($rgb); + unset($bottom->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 9: // border color left + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft(); + $left->getColor()->setRGB($rgb); + unset($left->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 10: // border color right + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight(); + $right->getColor()->setRGB($rgb); + unset($right->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 11: // border color diagonal + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal(); + $diagonal->getColor()->setRGB($rgb); + unset($diagonal->colorIndex); // normal color index does not apply, discard + } + } + break; + + case 13: // font color + $xclfType = self::_GetInt2d($extData, 0); // color type + $xclrValue = substr($extData, 4, 4); // color value (value based on color type) + + if ($xclfType == 2) { + $rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2})); + + // modify the relevant style property + if ( isset($this->_mapCellXfIndex[$ixfe]) ) { + $font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont(); + $font->getColor()->setRGB($rgb); + unset($font->colorIndex); // normal color index does not apply, discard + } + } + break; + } + + $offset += $cb; + } + } + + } + + + /** + * Read STYLE record + */ + private function _readStyle() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to XF record and flag for built-in style + $ixfe = self::_GetInt2d($recordData, 0); + + // bit: 11-0; mask 0x0FFF; index to XF record + $xfIndex = (0x0FFF & $ixfe) >> 0; + + // bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style + $isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15); + + if ($isBuiltIn) { + // offset: 2; size: 1; identifier for built-in style + $builtInId = ord($recordData{2}); + + switch ($builtInId) { + case 0x00: + // currently, we are not using this for anything + break; + + default: + break; + } + + } else { + // user-defined; not supported by PHPExcel + } + } + } + + + /** + * Read PALETTE record + */ + private function _readPalette() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; number of following colors + $nm = self::_GetInt2d($recordData, 0); + + // list of RGB colors + for ($i = 0; $i < $nm; ++$i) { + $rgb = substr($recordData, 2 + 4 * $i, 4); + $this->_palette[] = self::_readRGB($rgb); + } + } + } + + + /** + * SHEET + * + * This record is located in the Workbook Globals + * Substream and represents a sheet inside the workbook. + * One SHEET record is written for each sheet. It stores the + * sheet name and a stream offset to the BOF record of the + * respective Sheet Substream within the Workbook Stream. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // offset: 0; size: 4; absolute stream position of the BOF record of the sheet + // NOTE: not encrypted + $rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 4; size: 1; sheet state + switch (ord($recordData{4})) { + case 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + case 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN; break; + case 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break; + default: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE; break; + } + + // offset: 5; size: 1; sheet type + $sheetType = ord($recordData{5}); + + // offset: 6; size: var; sheet name + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } elseif ($this->_version == self::XLS_BIFF7) { + $string = $this->_readByteStringShort(substr($recordData, 6)); + $rec_name = $string['value']; + } + + $this->_sheets[] = array( + 'name' => $rec_name, + 'offset' => $rec_offset, + 'sheetState' => $sheetState, + 'sheetType' => $sheetType, + ); + } + + + /** + * Read EXTERNALBOOK record + */ + private function _readExternalBook() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset within record data + $offset = 0; + + // there are 4 types of records + if (strlen($recordData) > 4) { + // external reference + // offset: 0; size: 2; number of sheet names ($nm) + $nm = self::_GetInt2d($recordData, 0); + $offset += 2; + + // offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length) + $encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2)); + $offset += $encodedUrlString['size']; + + // offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length) + $externalSheetNames = array(); + for ($i = 0; $i < $nm; ++$i) { + $externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset)); + $externalSheetNames[] = $externalSheetNameString['value']; + $offset += $externalSheetNameString['size']; + } + + // store the record data + $this->_externalBooks[] = array( + 'type' => 'external', + 'encodedUrl' => $encodedUrlString['value'], + 'externalSheetNames' => $externalSheetNames, + ); + + } elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) { + // internal reference + // offset: 0; size: 2; number of sheet in this document + // offset: 2; size: 2; 0x01 0x04 + $this->_externalBooks[] = array( + 'type' => 'internal', + ); + } elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) { + // add-in function + // offset: 0; size: 2; 0x0001 + $this->_externalBooks[] = array( + 'type' => 'addInFunction', + ); + } elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) { + // DDE links, OLE links + // offset: 0; size: 2; 0x0000 + // offset: 2; size: var; encoded source document name + $this->_externalBooks[] = array( + 'type' => 'DDEorOLE', + ); + } + } + + + /** + * Read EXTERNNAME record. + */ + private function _readExternName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; options + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; + + // offset: 4; size: 2; not used + + // offset: 6; size: var + $nameString = self::_readUnicodeStringShort(substr($recordData, 6)); + + // offset: var; size: var; formula data + $offset = 6 + $nameString['size']; + $formula = $this->_getFormulaFromStructure(substr($recordData, $offset)); + + $this->_externalNames[] = array( + 'name' => $nameString['value'], + 'formula' => $formula, + ); + } + } + + + /** + * Read EXTERNSHEET record + */ + private function _readExternSheet() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // external sheet references provided for named cells + if ($this->_version == self::XLS_BIFF8) { + // offset: 0; size: 2; number of following ref structures + $nm = self::_GetInt2d($recordData, 0); + for ($i = 0; $i < $nm; ++$i) { + $this->_ref[] = array( + // offset: 2 + 6 * $i; index to EXTERNALBOOK record + 'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i), + // offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record + 'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i), + // offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record + 'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i), + ); + } + } + } + + + /** + * DEFINEDNAME + * + * This record is part of a Link Table. It contains the name + * and the token array of an internal defined name. Token + * arrays of defined names contain tokens with aberrant + * token classes. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readDefinedName() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + // retrieves named cells + + // offset: 0; size: 2; option flags + $opts = self::_GetInt2d($recordData, 0); + + // bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name + $isBuiltInName = (0x0020 & $opts) >> 5; + + // offset: 2; size: 1; keyboard shortcut + + // offset: 3; size: 1; length of the name (character count) + $nlen = ord($recordData{3}); + + // offset: 4; size: 2; size of the formula data (it can happen that this is zero) + // note: there can also be additional data, this is not included in $flen + $flen = self::_GetInt2d($recordData, 4); + + // offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based) + $scope = self::_GetInt2d($recordData, 8); + + // offset: 14; size: var; Name (Unicode string without length field) + $string = self::_readUnicodeString(substr($recordData, 14), $nlen); + + // offset: var; size: $flen; formula data + $offset = 14 + $string['size']; + $formulaStructure = pack('v', $flen) . substr($recordData, $offset); + + try { + $formula = $this->_getFormulaFromStructure($formulaStructure); + } catch (PHPExcel_Exception $e) { + $formula = ''; + } + + $this->_definedname[] = array( + 'isBuiltInName' => $isBuiltInName, + 'name' => $string['value'], + 'formula' => $formula, + 'scope' => $scope, + ); + } + } + + + /** + * Read MSODRAWINGGROUP record + */ + private function _readMsoDrawingGroup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingGroupData .= $recordData; + } + + + /** + * SST - Shared String Table + * + * This record contains a list of all strings used anywhere + * in the workbook. Each string occurs only once. The + * workbook uses indexes into the list to reference the + * strings. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + **/ + private function _readSst() + { + // offset within (spliced) record data + $pos = 0; + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + + $recordData = $splicedRecordData['recordData']; + $spliceOffsets = $splicedRecordData['spliceOffsets']; + + // offset: 0; size: 4; total number of strings in the workbook + $pos += 4; + + // offset: 4; size: 4; number of following strings ($nm) + $nm = self::_GetInt4d($recordData, 4); + $pos += 4; + + // loop through the Unicode strings (16-bit length) + for ($i = 0; $i < $nm; ++$i) { + + // number of characters in the Unicode string + $numChars = self::_GetInt2d($recordData, $pos); + $pos += 2; + + // option flags + $optionFlags = ord($recordData{$pos}); + ++$pos; + + // bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed + $isCompressed = (($optionFlags & 0x01) == 0) ; + + // bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic + $hasAsian = (($optionFlags & 0x04) != 0); + + // bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text + $hasRichText = (($optionFlags & 0x08) != 0); + + if ($hasRichText) { + // number of Rich-Text formatting runs + $formattingRuns = self::_GetInt2d($recordData, $pos); + $pos += 2; + } + + if ($hasAsian) { + // size of Asian phonetic setting + $extendedRunLength = self::_GetInt4d($recordData, $pos); + $pos += 4; + } + + // expected byte length of character array if not split + $len = ($isCompressed) ? $numChars : $numChars * 2; + + // look up limit position + foreach ($spliceOffsets as $spliceOffset) { + // it can happen that the string is empty, therefore we need + // <= and not just < + if ($pos <= $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + if ($pos + $len <= $limitpos) { + // character array is not split between records + + $retstr = substr($recordData, $pos, $len); + $pos += $len; + + } else { + // character array is split between records + + // first part of character array + $retstr = substr($recordData, $pos, $limitpos - $pos); + + $bytesRead = $limitpos - $pos; + + // remaining characters in Unicode string + $charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2)); + + $pos = $limitpos; + + // keep reading the characters + while ($charsLeft > 0) { + + // look up next limit position, in case the string span more than one continue record + foreach ($spliceOffsets as $spliceOffset) { + if ($pos < $spliceOffset) { + $limitpos = $spliceOffset; + break; + } + } + + // repeated option flags + // OpenOffice.org documentation 5.21 + $option = ord($recordData{$pos}); + ++$pos; + + if ($isCompressed && ($option == 0)) { + // 1st fragment compressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len; + $isCompressed = true; + + } elseif (!$isCompressed && ($option != 0)) { + // 1st fragment uncompressed + // this fragment uncompressed + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + + } elseif (!$isCompressed && ($option == 0)) { + // 1st fragment uncompressed + // this fragment compressed + $len = min($charsLeft, $limitpos - $pos); + for ($j = 0; $j < $len; ++$j) { + $retstr .= $recordData{$pos + $j} . chr(0); + } + $charsLeft -= $len; + $isCompressed = false; + + } else { + // 1st fragment compressed + // this fragment uncompressed + $newstr = ''; + for ($j = 0; $j < strlen($retstr); ++$j) { + $newstr .= $retstr[$j] . chr(0); + } + $retstr = $newstr; + $len = min($charsLeft * 2, $limitpos - $pos); + $retstr .= substr($recordData, $pos, $len); + $charsLeft -= $len / 2; + $isCompressed = false; + } + + $pos += $len; + } + } + + // convert to UTF-8 + $retstr = self::_encodeUTF16($retstr, $isCompressed); + + // read additional Rich-Text information, if any + $fmtRuns = array(); + if ($hasRichText) { + // list of formatting runs + for ($j = 0; $j < $formattingRuns; ++$j) { + // first formatted character; zero-based + $charPos = self::_GetInt2d($recordData, $pos + $j * 4); + + // index to font record + $fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4); + + $fmtRuns[] = array( + 'charPos' => $charPos, + 'fontIndex' => $fontIndex, + ); + } + $pos += 4 * $formattingRuns; + } + + // read additional Asian phonetics information, if any + if ($hasAsian) { + // For Asian phonetic settings, we skip the extended string data + $pos += $extendedRunLength; + } + + // store the shared sting + $this->_sst[] = array( + 'value' => $retstr, + 'fmtRuns' => $fmtRuns, + ); + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read PRINTGRIDLINES record + */ + private function _readPrintGridlines() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines + $printGridlines = (bool) self::_GetInt2d($recordData, 0); + $this->_phpSheet->setPrintGridlines($printGridlines); + } + } + + + /** + * Read DEFAULTROWHEIGHT record + */ + private function _readDefaultRowHeight() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + // offset: 2; size: 2; default height for unused rows, (twips 1/20 point) + $height = self::_GetInt2d($recordData, 2); + $this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20); + } + + + /** + * Read SHEETPR record + */ + private function _readSheetPr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2 + + // bit: 6; mask: 0x0040; 0 = outline buttons above outline group + $isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6; + $this->_phpSheet->setShowSummaryBelow($isSummaryBelow); + + // bit: 7; mask: 0x0080; 0 = outline buttons left of outline group + $isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7; + $this->_phpSheet->setShowSummaryRight($isSummaryRight); + + // bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages + // this corresponds to radio button setting in page setup dialog in Excel + $this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8); + } + + + /** + * Read HORIZONTALPAGEBREAKS record + */ + private function _readHorizontalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + + // offset: 0; size: 2; number of the following row index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $r = self::_GetInt2d($recordData, 2 + 6 * $i); + $cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two column indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW); + } + } + } + + + /** + * Read VERTICALPAGEBREAKS record + */ + private function _readVerticalPageBreaks() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + // offset: 0; size: 2; number of the following column index structures + $nm = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 6 * $nm; list of $nm row index structures + for ($i = 0; $i < $nm; ++$i) { + $c = self::_GetInt2d($recordData, 2 + 6 * $i); + $rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2); + $rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4); + + // not sure why two row indexes are necessary? + $this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN); + } + } + } + + + /** + * Read HEADER record + */ + private function _readHeader() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + + $this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']); + } + } + } + + + /** + * Read FOOTER record + */ + private function _readFooter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: var + // realized that $recordData can be empty even when record exists + if ($recordData) { + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + } else { + $string = $this->_readByteStringShort($recordData); + } + $this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']); + $this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']); + } + } + } + + + /** + * Read HCENTER record + */ + private function _readHcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally + $isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered); + } + } + + + /** + * Read VCENTER record + */ + private function _readVcenter() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered + $isVerticalCentered = (bool) self::_GetInt2d($recordData, 0); + + $this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered); + } + } + + + /** + * Read LEFTMARGIN record + */ + private function _readLeftMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData)); + } + } + + + /** + * Read RIGHTMARGIN record + */ + private function _readRightMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData)); + } + } + + + /** + * Read TOPMARGIN record + */ + private function _readTopMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData)); + } + } + + + /** + * Read BOTTOMMARGIN record + */ + private function _readBottomMargin() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8 + $this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData)); + } + } + + + /** + * Read PAGESETUP record + */ + private function _readPageSetup() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; paper size + $paperSize = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; scaling factor + $scale = self::_GetInt2d($recordData, 2); + + // offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed + $fitToWidth = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed + $fitToHeight = self::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; option flags + + // bit: 1; mask: 0x0002; 0=landscape, 1=portrait + $isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1; + + // bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init + // when this bit is set, do not use flags for those properties + $isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2; + + if (!$isNotInit) { + $this->_phpSheet->getPageSetup()->setPaperSize($paperSize); + switch ($isPortrait) { + case 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break; + case 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break; + } + + $this->_phpSheet->getPageSetup()->setScale($scale, false); + $this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages); + $this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false); + $this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false); + } + + // offset: 16; size: 8; header margin (IEEE 754 floating-point value) + $marginHeader = self::_extractNumber(substr($recordData, 16, 8)); + $this->_phpSheet->getPageMargins()->setHeader($marginHeader); + + // offset: 24; size: 8; footer margin (IEEE 754 floating-point value) + $marginFooter = self::_extractNumber(substr($recordData, 24, 8)); + $this->_phpSheet->getPageMargins()->setFooter($marginFooter); + } + } + + + /** + * PROTECT - Sheet protection (BIFF2 through BIFF8) + * if this record is omitted, then it also means no sheet protection + */ + private function _readProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit 0, mask 0x01; 1 = sheet is protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + $this->_phpSheet->getProtection()->setSheet((bool)$bool); + } + + + /** + * SCENPROTECT + */ + private function _readScenProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = scenarios are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setScenarios((bool)$bool); + } + + + /** + * OBJECTPROTECT + */ + private function _readObjectProtect() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; + + // bit: 0, mask 0x01; 1 = objects are protected + $bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0; + + $this->_phpSheet->getProtection()->setObjects((bool)$bool); + } + + + /** + * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8) + */ + private function _readPassword() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; 16-bit hash value of password + $password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password + $this->_phpSheet->getProtection()->setPassword($password, true); + } + } + + + /** + * Read DEFCOLWIDTH record + */ + private function _readDefColWidth() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; default column width + $width = self::_GetInt2d($recordData, 0); + if ($width != 8) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width); + } + } + + + /** + * Read COLINFO record + */ + private function _readColInfo() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index to first column in range + $fc = self::_GetInt2d($recordData, 0); // first column index + + // offset: 2; size: 2; index to last column in range + $lc = self::_GetInt2d($recordData, 2); // first column index + + // offset: 4; size: 2; width of the column in 1/256 of the width of the zero character + $width = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; index to XF record for default column formatting + $xfIndex = self::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; option flags + + // bit: 0; mask: 0x0001; 1= columns are hidden + $isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0; + + // bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline) + $level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8; + + // bit: 12; mask: 0x1000; 1 = collapsed + $isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12; + + // offset: 10; size: 2; not used + + for ($i = $fc; $i <= $lc; ++$i) { + if ($lc == 255 || $lc == 256) { + $this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256); + break; + } + $this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256); + $this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden); + $this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level); + $this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed); + $this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * ROW + * + * This record contains the properties of a single row in a + * sheet. Rows and cells in a sheet are divided into blocks + * of 32 rows. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRow() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; index of this row + $r = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column of the first cell which is described by a cell record + + // offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1 + + // offset: 6; size: 2; + + // bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point + $height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0; + + // bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height + $useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15; + + if (!$useDefaultHeight) { + $this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20); + } + + // offset: 8; size: 2; not used + + // offset: 10; size: 2; not used in BIFF5-BIFF8 + + // offset: 12; size: 4; option flags and default row formatting + + // bit: 2-0: mask: 0x00000007; outline level of the row + $level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0; + $this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level); + + // bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed + $isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4; + $this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed); + + // bit: 5; mask: 0x00000020; 1 = row is hidden + $isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5; + $this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden); + + // bit: 7; mask: 0x00000080; 1 = row has explicit format + $hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7; + + // bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record + $xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16; + + if ($hasExplicitFormat) { + $this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read RK record + * This record represents a cell that contains an RK value + * (encoded integer or floating-point value). If a + * floating-point value cannot be encoded to an RK value, + * a NUMBER record will be written. This record replaces the + * record INTEGER written in BIFF2. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; RK value + $rknum = self::_GetInt4d($recordData, 6); + $numValue = self::_GetIEEE754($rknum); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read LABELSST record + * This record represents a cell that contains a string. It + * replaces the LABEL record and RSTRING record used in + * BIFF2-BIFF5. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabelSst() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 4; index to SST record + $index = self::_GetInt4d($recordData, 6); + + // add cell + if (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) { + // then we should treat as rich text + $richText = new PHPExcel_RichText(); + $charPos = 0; + $sstCount = count($this->_sst[$index]['fmtRuns']); + for ($i = 0; $i <= $sstCount; ++$i) { + if (isset($fmtRuns[$i])) { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos); + $charPos = $fmtRuns[$i]['charPos']; + } else { + $text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value'])); + } + + if (PHPExcel_Shared_String::CountCharacters($text) > 0) { + if ($i == 0) { // first text run, no style + $richText->createText($text); + } else { + $textRun = $richText->createTextRun($text); + if (isset($fmtRuns[$i - 1])) { + if ($fmtRuns[$i - 1]['fontIndex'] < 4) { + $fontIndex = $fmtRuns[$i - 1]['fontIndex']; + } else { + // this has to do with that index 4 is omitted in all BIFF versions for some strange reason + // check the OpenOffice documentation of the FONT record + $fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1; + } + $textRun->setFont(clone $this->_objFonts[$fontIndex]); + } + } + } + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING); + } else { + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING); + } + + if (!$this->_readDataOnly) { + // add style information + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULRK record + * This record represents a cell range containing RK value + * cells. All cells are located in the same row. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulRk() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $colFirst = self::_GetInt2d($recordData, 2); + + // offset: var; size: 2; index to last column + $colLast = self::_GetInt2d($recordData, $length - 2); + $columns = $colLast - $colFirst + 1; + + // offset within record data + $offset = 4; + + for ($i = 0; $i < $columns; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + // offset: var; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, $offset); + + // offset: var; size: 4; RK value + $numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2)); + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + + $offset += 6; + } + } + + + /** + * Read NUMBER record + * This record represents a cell that contains a + * floating-point value. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readNumber() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + $numValue = self::_extractNumber(substr($recordData, 6, 8)); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // add cell value + $cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC); + } + } + + + /** + * Read FORMULA record + perhaps a following STRING record if formula result is a string + * This record contains the token array and the result of a + * formula cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readFormula() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // offset: 20: size: variable; formula structure + $formulaStructure = substr($recordData, 20); + + // offset: 14: size: 2; option flags, recalculate always, recalculate on open etc. + $options = self::_GetInt2d($recordData, 14); + + // bit: 0; mask: 0x0001; 1 = recalculate always + // bit: 1; mask: 0x0002; 1 = calculate on open + // bit: 2; mask: 0x0008; 1 = part of a shared formula + $isPartOfSharedFormula = (bool) (0x0008 & $options); + + // WARNING: + // We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true + // the formula data may be ordinary formula data, therefore we need to check + // explicitly for the tExp token (0x01) + $isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01; + + if ($isPartOfSharedFormula) { + // part of shared formula which means there will be a formula with a tExp token and nothing else + // get the base cell, grab tExp token + $baseRow = self::_GetInt2d($formulaStructure, 3); + $baseCol = self::_GetInt2d($formulaStructure, 5); + $this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1); + } + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + + if ($isPartOfSharedFormula) { + // formula is added to this cell after the sheet has been read + $this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell; + } + + // offset: 16: size: 4; not used + + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 8; result of the formula + if ( (ord($recordData{6}) == 0) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255) ) { + + // String formula. Result follows in appended STRING record + $dataType = PHPExcel_Cell_DataType::TYPE_STRING; + + // read possible SHAREDFMLA record + $code = self::_GetInt2d($this->_data, $this->_pos); + if ($code == self::XLS_Type_SHAREDFMLA) { + $this->_readSharedFmla(); + } + + // read STRING record + $value = $this->_readString(); + + } elseif ((ord($recordData{6}) == 1) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Boolean formula. Result is in +2; 0=false, 1=true + $dataType = PHPExcel_Cell_DataType::TYPE_BOOL; + $value = (bool) ord($recordData{8}); + + } elseif ((ord($recordData{6}) == 2) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Error formula. Error code is in +2 + $dataType = PHPExcel_Cell_DataType::TYPE_ERROR; + $value = self::_mapErrorCode(ord($recordData{8})); + + } elseif ((ord($recordData{6}) == 3) + && (ord($recordData{12}) == 255) + && (ord($recordData{13}) == 255)) { + + // Formula result is a null string + $dataType = PHPExcel_Cell_DataType::TYPE_NULL; + $value = ''; + + } else { + + // forumla result is a number, first 14 bytes like _NUMBER record + $dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $value = self::_extractNumber(substr($recordData, 6, 8)); + + } + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + + // store the formula + if (!$isPartOfSharedFormula) { + // not part of shared formula + // add cell value. If we can read formula, populate with formula, otherwise just used cached value + try { + if ($this->_version != self::XLS_BIFF8) { + throw new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas'); + } + $formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language + $cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + + } catch (PHPExcel_Exception $e) { + $cell->setValueExplicit($value, $dataType); + } + } else { + if ($this->_version == self::XLS_BIFF8) { + // do nothing at this point, formula id added later in the code + } else { + $cell->setValueExplicit($value, $dataType); + } + } + + // store the cached calculated value + $cell->setCalculatedValue($value); + } + } + + + /** + * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader, + * which usually contains relative references. + * These will be used to construct the formula in each shared formula part after the sheet is read. + */ + private function _readSharedFmla() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything + $cellRange = substr($recordData, 0, 6); + $cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax + + // offset: 6, size: 1; not used + + // offset: 7, size: 1; number of existing FORMULA records for this shared formula + $no = ord($recordData{7}); + + // offset: 8, size: var; Binary token array of the shared formula + $formula = substr($recordData, 8); + + // at this point we only store the shared formula for later use + $this->_sharedFormulas[$this->_baseCell] = $formula; + + } + + + /** + * Read a STRING record from current stream position and advance the stream pointer to next record + * This record is used for storing result from FORMULA record when it is a string, and + * it occurs directly after the FORMULA record + * + * @return string The string contents as UTF-8 + */ + private function _readString() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong($recordData); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong($recordData); + $value = $string['value']; + } + + return $value; + } + + + /** + * Read BOOLERR record + * This record represents a Boolean value or error value + * cell. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readBoolErr() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; column index + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; index to XF record + $xfIndex = self::_GetInt2d($recordData, 4); + + // offset: 6; size: 1; the boolean value or error value + $boolErr = ord($recordData{6}); + + // offset: 7; size: 1; 0=boolean; 1=error + $isError = ord($recordData{7}); + + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + switch ($isError) { + case 0: // boolean + $value = (bool) $boolErr; + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL); + break; + + case 1: // error type + $value = self::_mapErrorCode($boolErr); + + // add cell value + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR); + break; + } + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read MULBLANK record + * This record represents a cell range of empty cells. All + * cells are located in the same row + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMulBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first column + $fc = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2 x nc; list of indexes to XF records + // add style information + if (!$this->_readDataOnly) { + for ($i = 0; $i < $length / 2 - 3; ++$i) { + $columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + $xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i); + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + // offset: 6; size 2; index to last column (not needed) + } + + + /** + * Read LABEL record + * This record represents a cell that contains a string. In + * BIFF8 it is usually replaced by the LABELSST record. + * Excel still uses this record, if it copies unformatted + * text cells to the clipboard. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readLabel() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; index to row + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to column + $column = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add cell value + // todo: what if string is very long? continue record + if ($this->_version == self::XLS_BIFF8) { + $string = self::_readUnicodeStringLong(substr($recordData, 6)); + $value = $string['value']; + } else { + $string = $this->_readByteStringLong(substr($recordData, 6)); + $value = $string['value']; + } + $cell = $this->_phpSheet->getCell($columnString . ($row + 1)); + $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING); + + if (!$this->_readDataOnly) { + // add cell style + $cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + } + + + /** + * Read BLANK record + */ + private function _readBlank() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; row index + $row = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; col index + $col = self::_GetInt2d($recordData, 2); + $columnString = PHPExcel_Cell::stringFromColumnIndex($col); + + // Read cell? + if (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) { + // offset: 4; size: 2; XF index + $xfIndex = self::_GetInt2d($recordData, 4); + + // add style information + if (!$this->_readDataOnly) { + $this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]); + } + } + + } + + + /** + * Read MSODRAWING record + */ + private function _readMsoDrawing() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + $this->_drawingData .= $recordData; + } + + + /** + * Read OBJ record + */ + private function _readObj() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) { + return; + } + + // recordData consists of an array of subrecords looking like this: + // ft: 2 bytes; ftCmo type (0x15) + // cb: 2 bytes; size in bytes of ftCmo data + // ot: 2 bytes; Object Type + // id: 2 bytes; Object id number + // grbit: 2 bytes; Option Flags + // data: var; subrecord data + + // for now, we are just interested in the second subrecord containing the object type + $ftCmoType = self::_GetInt2d($recordData, 0); + $cbCmoSize = self::_GetInt2d($recordData, 2); + $otObjType = self::_GetInt2d($recordData, 4); + $idObjID = self::_GetInt2d($recordData, 6); + $grbitOpts = self::_GetInt2d($recordData, 6); + + $this->_objs[] = array( + 'ftCmoType' => $ftCmoType, + 'cbCmoSize' => $cbCmoSize, + 'otObjType' => $otObjType, + 'idObjID' => $idObjID, + 'grbitOpts' => $grbitOpts + ); + $this->textObjRef = $idObjID; + +// echo '_readObj()
'; +// var_dump(end($this->_objs)); +// echo '
'; + } + + + /** + * Read WINDOW2 record + */ + private function _readWindow2() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; option flags + $options = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; index to first visible row + $firstVisibleRow = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; index to first visible colum + $firstVisibleColumn = self::_GetInt2d($recordData, 4); + if ($this->_version === self::XLS_BIFF8) { + // offset: 8; size: 2; not used + // offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%) + // offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%) + // offset: 14; size: 4; not used + $zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10); + if ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60; + $zoomscaleInNormalView = self::_GetInt2d($recordData, 12); + if ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100; + } + + // bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines + $showGridlines = (bool) ((0x0002 & $options) >> 1); + $this->_phpSheet->setShowGridlines($showGridlines); + + // bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers + $showRowColHeaders = (bool) ((0x0004 & $options) >> 2); + $this->_phpSheet->setShowRowColHeaders($showRowColHeaders); + + // bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen + $this->_frozen = (bool) ((0x0008 & $options) >> 3); + + // bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left + $this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6)); + + // bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active + $isActive = (bool) ((0x0400 & $options) >> 10); + if ($isActive) { + $this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet)); + } + + // bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view + $isPageBreakPreview = (bool) ((0x0800 & $options) >> 11); + + //FIXME: set $firstVisibleRow and $firstVisibleColumn + + if ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) { + //NOTE: this setting is inferior to page layout view(Excel2007-) + $view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW : + PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL; + $this->_phpSheet->getSheetView()->setView($view); + if ($this->_version === self::XLS_BIFF8) { + $zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView; + $this->_phpSheet->getSheetView()->setZoomScale($zoomScale); + $this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView); + } + } + } + + /** + * Read PLV Record(Created by Excel2007 or upper) + */ + private function _readPageLayoutView(){ + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + //var_dump(unpack("vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit", $recordData)); + + // offset: 0; size: 2; rt + //->ignore + $rt = self::_GetInt2d($recordData, 0); + // offset: 2; size: 2; grbitfr + //->ignore + $grbitFrt = self::_GetInt2d($recordData, 2); + // offset: 4; size: 8; reserved + //->ignore + + // offset: 12; size 2; zoom scale + $wScalePLV = self::_GetInt2d($recordData, 12); + // offset: 14; size 2; grbit + $grbit = self::_GetInt2d($recordData, 14); + + // decomprise grbit + $fPageLayoutView = $grbit & 0x01; + $fRulerVisible = ($grbit >> 1) & 0x01; //no support + $fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support + + if ($fPageLayoutView === 1) { + $this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT); + $this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT + } + //otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW. + } + + /** + * Read SCL record + */ + private function _readScl() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // offset: 0; size: 2; numerator of the view magnification + $numerator = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; numerator of the view magnification + $denumerator = self::_GetInt2d($recordData, 2); + + // set the zoom scale (in percent) + $this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator); + } + + + /** + * Read PANE record + */ + private function _readPane() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; position of vertical split + $px = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; position of horizontal split + $py = self::_GetInt2d($recordData, 2); + + if ($this->_frozen) { + // frozen panes + $this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1)); + } else { + // unfrozen panes; split windows; not supported by PHPExcel core + } + } + } + + + /** + * Read SELECTION record. There is one such record for each pane in the sheet. + */ + private function _readSelection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 1; pane identifier + $paneId = ord($recordData{0}); + + // offset: 1; size: 2; index to row of the active cell + $r = self::_GetInt2d($recordData, 1); + + // offset: 3; size: 2; index to column of the active cell + $c = self::_GetInt2d($recordData, 3); + + // offset: 5; size: 2; index into the following cell range list to the + // entry that contains the active cell + $index = self::_GetInt2d($recordData, 5); + + // offset: 7; size: var; cell range address list containing all selected cell ranges + $data = substr($recordData, 7); + $cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax + + $selectedCells = $cellRangeAddressList['cellRangeAddresses'][0]; + + // first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!) + if (preg_match('/^([A-Z]+1\:[A-Z]+)16384$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)16384$/', '${1}1048576', $selectedCells); + } + + // first row '1' + last row '65536' indicates that full column is selected + if (preg_match('/^([A-Z]+1\:[A-Z]+)65536$/', $selectedCells)) { + $selectedCells = preg_replace('/^([A-Z]+1\:[A-Z]+)65536$/', '${1}1048576', $selectedCells); + } + + // first column 'A' + last column 'IV' indicates that full row is selected + if (preg_match('/^(A[0-9]+\:)IV([0-9]+)$/', $selectedCells)) { + $selectedCells = preg_replace('/^(A[0-9]+\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells); + } + + $this->_phpSheet->setSelectedCells($selectedCells); + } + } + + + private function _includeCellRangeFiltered($cellRangeAddress) + { + $includeCellRange = true; + if ($this->getReadFilter() !== NULL) { + $includeCellRange = false; + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress); + $rangeBoundaries[1][0]++; + for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) { + for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) { + if ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) { + $includeCellRange = true; + break 2; + } + } + } + } + return $includeCellRange; + } + + + /** + * MERGEDCELLS + * + * This record contains the addresses of merged cell ranges + * in the current sheet. + * + * -- "OpenOffice.org's Documentation of the Microsoft + * Excel File Format" + */ + private function _readMergedCells() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) { + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData); + foreach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) { + if ((strpos($cellRangeAddress,':') !== FALSE) && + ($this->_includeCellRangeFiltered($cellRangeAddress))) { + $this->_phpSheet->mergeCells($cellRangeAddress); + } + } + } + } + + + /** + * Read HYPERLINK record + */ + private function _readHyperLink() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if (!$this->_readDataOnly) { + // offset: 0; size: 8; cell range address of all cells containing this hyperlink + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8); + } catch (PHPExcel_Exception $e) { + return; + } + + // offset: 8, size: 16; GUID of StdLink + + // offset: 24, size: 4; unknown value + + // offset: 28, size: 4; option flags + + // bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL + $isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0; + + // bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL + $isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1; + + // bit: 2 (and 4); mask: 0x00000014; 0 = no description + $hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2; + + // bit: 3; mask: 0x00000008; 0 = no text, 1 = has text + $hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3; + + // bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame + $hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7; + + // bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name) + $isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8; + + // offset within record data + $offset = 32; + + if ($hasDesc) { + // offset: 32; size: var; character count of description text + $dl = self::_GetInt4d($recordData, 32); + // offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated + $desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false); + $offset += 4 + 2 * $dl; + } + if ($hasFrame) { + $fl = self::_GetInt4d($recordData, $offset); + $offset += 4 + 2 * $fl; + } + + // detect type of hyperlink (there are 4 types) + $hyperlinkType = null; + + if ($isUNC) { + $hyperlinkType = 'UNC'; + } else if (!$isFileLinkOrUrl) { + $hyperlinkType = 'workbook'; + } else if (ord($recordData{$offset}) == 0x03) { + $hyperlinkType = 'local'; + } else if (ord($recordData{$offset}) == 0xE0) { + $hyperlinkType = 'URL'; + } + + switch ($hyperlinkType) { + case 'URL': + // section 5.58.2: Hyperlink containing a URL + // e.g. http://example.org/index.php + + // offset: var; size: 16; GUID of URL Moniker + $offset += 16; + // offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word + $us = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated + $url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false); + $url .= $hasText ? '#' : ''; + $offset += $us; + break; + + case 'local': + // section 5.58.3: Hyperlink to local file + // examples: + // mydoc.txt + // ../../somedoc.xls#Sheet!A1 + + // offset: var; size: 16; GUI of File Moniker + $offset += 16; + + // offset: var; size: 2; directory up-level count. + $upLevelCount = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 4; character count of the shortened file path and name, including trailing zero word + $sl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string) + $shortenedFilePath = substr($recordData, $offset, $sl); + $shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true); + $shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero + + $offset += $sl; + + // offset: var; size: 24; unknown sequence + $offset += 24; + + // extended file path + // offset: var; size: 4; size of the following file link field including string lenth mark + $sz = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // only present if $sz > 0 + if ($sz > 0) { + // offset: var; size: 4; size of the character array of the extended file path and name + $xl = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // offset: var; size 2; unknown + $offset += 2; + + // offset: var; size $xl; character array of the extended file path and name. + $extendedFilePath = substr($recordData, $offset, $xl); + $extendedFilePath = self::_encodeUTF16($extendedFilePath, false); + $offset += $xl; + } + + // construct the path + $url = str_repeat('..\\', $upLevelCount); + $url .= ($sz > 0) ? + $extendedFilePath : $shortenedFilePath; // use extended path if available + $url .= $hasText ? '#' : ''; + + break; + + + case 'UNC': + // section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path + // todo: implement + return; + + case 'workbook': + // section 5.58.5: Hyperlink to the Current Workbook + // e.g. Sheet2!B1:C2, stored in text mark field + $url = 'sheet://'; + break; + + default: + return; + + } + + if ($hasText) { + // offset: var; size: 4; character count of text mark including trailing zero word + $tl = self::_GetInt4d($recordData, $offset); + $offset += 4; + // offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated + $text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false); + $url .= $text; + } + + // apply the hyperlink to all the relevant cells + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) { + $this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url); + } + } + } + + + /** + * Read DATAVALIDATIONS record + */ + private function _readDataValidations() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + } + + + /** + * Read DATAVALIDATION record + */ + private function _readDataValidation() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer forward to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 4; Options + $options = self::_GetInt4d($recordData, 0); + + // bit: 0-3; mask: 0x0000000F; type + $type = (0x0000000F & $options) >> 0; + switch ($type) { + case 0x00: $type = PHPExcel_Cell_DataValidation::TYPE_NONE; break; + case 0x01: $type = PHPExcel_Cell_DataValidation::TYPE_WHOLE; break; + case 0x02: $type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL; break; + case 0x03: $type = PHPExcel_Cell_DataValidation::TYPE_LIST; break; + case 0x04: $type = PHPExcel_Cell_DataValidation::TYPE_DATE; break; + case 0x05: $type = PHPExcel_Cell_DataValidation::TYPE_TIME; break; + case 0x06: $type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH; break; + case 0x07: $type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM; break; + } + + // bit: 4-6; mask: 0x00000070; error type + $errorStyle = (0x00000070 & $options) >> 4; + switch ($errorStyle) { + case 0x00: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP; break; + case 0x01: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING; break; + case 0x02: $errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION; break; + } + + // bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list) + // I have only seen cases where this is 1 + $explicitFormula = (0x00000080 & $options) >> 7; + + // bit: 8; mask: 0x00000100; 1= empty cells allowed + $allowBlank = (0x00000100 & $options) >> 8; + + // bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity + $suppressDropDown = (0x00000200 & $options) >> 9; + + // bit: 18; mask: 0x00040000; 1= show prompt box if cell selected + $showInputMessage = (0x00040000 & $options) >> 18; + + // bit: 19; mask: 0x00080000; 1= show error box if invalid values entered + $showErrorMessage = (0x00080000 & $options) >> 19; + + // bit: 20-23; mask: 0x00F00000; condition operator + $operator = (0x00F00000 & $options) >> 20; + switch ($operator) { + case 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN ; break; + case 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN ; break; + case 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL ; break; + case 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL ; break; + case 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN ; break; + case 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN ; break; + case 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL; break; + case 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL ; break; + } + + // offset: 4; size: var; title of the prompt box + $offset = 4; + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $promptTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; title of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $errorTitle = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the prompt box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $prompt = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: var; text of the error box + $string = self::_readUnicodeStringLong(substr($recordData, $offset)); + $error = $string['value'] !== chr(0) ? + $string['value'] : ''; + $offset += $string['size']; + + // offset: var; size: 2; size of the formula data for the first condition + $sz1 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz1; formula data for first condition (without size field) + $formula1 = substr($recordData, $offset, $sz1); + $formula1 = pack('v', $sz1) . $formula1; // prepend the length + try { + $formula1 = $this->_getFormulaFromStructure($formula1); + + // in list type validity, null characters are used as item separators + if ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) { + $formula1 = str_replace(chr(0), ',', $formula1); + } + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz1; + + // offset: var; size: 2; size of the formula data for the first condition + $sz2 = self::_GetInt2d($recordData, $offset); + $offset += 2; + + // offset: var; size: 2; not used + $offset += 2; + + // offset: var; size: $sz2; formula data for second condition (without size field) + $formula2 = substr($recordData, $offset, $sz2); + $formula2 = pack('v', $sz2) . $formula2; // prepend the length + try { + $formula2 = $this->_getFormulaFromStructure($formula2); + } catch (PHPExcel_Exception $e) { + return; + } + $offset += $sz2; + + // offset: var; size: var; cell range address list with + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset)); + $cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses']; + + foreach ($cellRangeAddresses as $cellRange) { + $stRange = $this->_phpSheet->shrinkRangeToFit($cellRange); + $stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange); + foreach ($stRange as $coordinate) { + $objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation(); + $objValidation->setType($type); + $objValidation->setErrorStyle($errorStyle); + $objValidation->setAllowBlank((bool)$allowBlank); + $objValidation->setShowInputMessage((bool)$showInputMessage); + $objValidation->setShowErrorMessage((bool)$showErrorMessage); + $objValidation->setShowDropDown(!$suppressDropDown); + $objValidation->setOperator($operator); + $objValidation->setErrorTitle($errorTitle); + $objValidation->setError($error); + $objValidation->setPromptTitle($promptTitle); + $objValidation->setPrompt($prompt); + $objValidation->setFormula1($formula1); + $objValidation->setFormula2($formula2); + } + } + + } + + + /** + * Read SHEETLAYOUT record. Stores sheet tab color information. + */ + private function _readSheetLayout() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + // offset: 0; size: 2; repeated record identifier 0x0862 + + // offset: 2; size: 10; not used + + // offset: 12; size: 4; size of record data + // Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?) + $sz = self::_GetInt4d($recordData, 12); + + switch ($sz) { + case 0x14: + // offset: 16; size: 2; color index for sheet tab + $colorIndex = self::_GetInt2d($recordData, 16); + $color = self::_readColor($colorIndex,$this->_palette,$this->_version); + $this->_phpSheet->getTabColor()->setRGB($color['rgb']); + break; + + case 0x28: + // TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007 + return; + break; + } + } + } + + + /** + * Read SHEETPROTECTION record (FEATHEADR) + */ + private function _readSheetProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + if ($this->_readDataOnly) { + return; + } + + // offset: 0; size: 2; repeated record header + + // offset: 2; size: 2; FRT cell reference flag (=0 currently) + + // offset: 4; size: 8; Currently not used and set to 0 + + // offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag) + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + return; + } + + // offset: 14; size: 1; =1 since this is a feat header + + // offset: 15; size: 4; size of rgbHdrSData + + // rgbHdrSData, assume "Enhanced Protection" + // offset: 19; size: 2; option flags + $options = self::_GetInt2d($recordData, 19); + + // bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects + $bool = (0x0001 & $options) >> 0; + $this->_phpSheet->getProtection()->setObjects(!$bool); + + // bit: 1; mask 0x0002; edit scenarios + $bool = (0x0002 & $options) >> 1; + $this->_phpSheet->getProtection()->setScenarios(!$bool); + + // bit: 2; mask 0x0004; format cells + $bool = (0x0004 & $options) >> 2; + $this->_phpSheet->getProtection()->setFormatCells(!$bool); + + // bit: 3; mask 0x0008; format columns + $bool = (0x0008 & $options) >> 3; + $this->_phpSheet->getProtection()->setFormatColumns(!$bool); + + // bit: 4; mask 0x0010; format rows + $bool = (0x0010 & $options) >> 4; + $this->_phpSheet->getProtection()->setFormatRows(!$bool); + + // bit: 5; mask 0x0020; insert columns + $bool = (0x0020 & $options) >> 5; + $this->_phpSheet->getProtection()->setInsertColumns(!$bool); + + // bit: 6; mask 0x0040; insert rows + $bool = (0x0040 & $options) >> 6; + $this->_phpSheet->getProtection()->setInsertRows(!$bool); + + // bit: 7; mask 0x0080; insert hyperlinks + $bool = (0x0080 & $options) >> 7; + $this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool); + + // bit: 8; mask 0x0100; delete columns + $bool = (0x0100 & $options) >> 8; + $this->_phpSheet->getProtection()->setDeleteColumns(!$bool); + + // bit: 9; mask 0x0200; delete rows + $bool = (0x0200 & $options) >> 9; + $this->_phpSheet->getProtection()->setDeleteRows(!$bool); + + // bit: 10; mask 0x0400; select locked cells + $bool = (0x0400 & $options) >> 10; + $this->_phpSheet->getProtection()->setSelectLockedCells(!$bool); + + // bit: 11; mask 0x0800; sort cell range + $bool = (0x0800 & $options) >> 11; + $this->_phpSheet->getProtection()->setSort(!$bool); + + // bit: 12; mask 0x1000; auto filter + $bool = (0x1000 & $options) >> 12; + $this->_phpSheet->getProtection()->setAutoFilter(!$bool); + + // bit: 13; mask 0x2000; pivot tables + $bool = (0x2000 & $options) >> 13; + $this->_phpSheet->getProtection()->setPivotTables(!$bool); + + // bit: 14; mask 0x4000; select unlocked cells + $bool = (0x4000 & $options) >> 14; + $this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool); + + // offset: 21; size: 2; not used + } + + + /** + * Read RANGEPROTECTION record + * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification, + * where it is referred to as FEAT record + */ + private function _readRangeProtection() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // move stream pointer to next record + $this->_pos += 4 + $length; + + // local pointer in record data + $offset = 0; + + if (!$this->_readDataOnly) { + $offset += 12; + + // offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag + $isf = self::_GetInt2d($recordData, 12); + if ($isf != 2) { + // we only read FEAT records of type 2 + return; + } + $offset += 2; + + $offset += 5; + + // offset: 19; size: 2; count of ref ranges this feature is on + $cref = self::_GetInt2d($recordData, 19); + $offset += 2; + + $offset += 6; + + // offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record) + $cellRanges = array(); + for ($i = 0; $i < $cref; ++$i) { + try { + $cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8)); + } catch (PHPExcel_Exception $e) { + return; + } + $cellRanges[] = $cellRange; + $offset += 8; + } + + // offset: var; size: var; variable length of feature specific data + $rgbFeat = substr($recordData, $offset); + $offset += 4; + + // offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit) + $wPassword = self::_GetInt4d($recordData, $offset); + $offset += 4; + + // Apply range protection to sheet + if ($cellRanges) { + $this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true); + } + } + } + + + /** + * Read IMDATA record + */ + private function _readImData() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + + // get spliced record data + $splicedRecordData = $this->_getSplicedRecordData(); + $recordData = $splicedRecordData['recordData']; + + // UNDER CONSTRUCTION + + // offset: 0; size: 2; image format + $cf = self::_GetInt2d($recordData, 0); + + // offset: 2; size: 2; environment from which the file was written + $env = self::_GetInt2d($recordData, 2); + + // offset: 4; size: 4; length of the image data + $lcb = self::_GetInt4d($recordData, 4); + + // offset: 8; size: var; image data + $iData = substr($recordData, 8); + + switch ($cf) { + case 0x09: // Windows bitmap format + // BITMAPCOREINFO + // 1. BITMAPCOREHEADER + // offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure + $bcSize = self::_GetInt4d($iData, 0); +// var_dump($bcSize); + + // offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels + $bcWidth = self::_GetInt2d($iData, 4); +// var_dump($bcWidth); + + // offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels. + $bcHeight = self::_GetInt2d($iData, 6); +// var_dump($bcHeight); + $ih = imagecreatetruecolor($bcWidth, $bcHeight); + + // offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1 + + // offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24 + $bcBitCount = self::_GetInt2d($iData, 10); +// var_dump($bcBitCount); + + $rgbString = substr($iData, 12); + $rgbTriples = array(); + while (strlen($rgbString) > 0) { + $rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString); + $rgbString = substr($rgbString, 3); + } + $x = 0; + $y = 0; + foreach ($rgbTriples as $i => $rgbTriple) { + $color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']); + imagesetpixel($ih, $x, $bcHeight - 1 - $y, $color); + $x = ($x + 1) % $bcWidth; + $y = $y + floor(($x + 1) / $bcWidth); + } + //imagepng($ih, 'image.png'); + + $drawing = new PHPExcel_Worksheet_Drawing(); + $drawing->setPath($filename); + $drawing->setWorksheet($this->_phpSheet); + + break; + + case 0x02: // Windows metafile or Macintosh PICT format + case 0x0e: // native format + default; + break; + + } + + // _getSplicedRecordData() takes care of moving current position in data stream + } + + + /** + * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record + * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented. + * In this case, we must treat the CONTINUE record as a MSODRAWING record + */ + private function _readContinue() + { + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + // check if we are reading drawing data + // this is in case a free CONTINUE record occurs in other circumstances we are unaware of + if ($this->_drawingData == '') { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data + if ($length < 4) { + // move stream pointer to next record + $this->_pos += 4 + $length; + + return; + } + + // dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record + // look inside CONTINUE record to see if it looks like a part of an Escher stream + // we know that Escher stream may be split at least at + // 0xF003 MsofbtSpgrContainer + // 0xF004 MsofbtSpContainer + // 0xF00D MsofbtClientTextbox + $validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more + + $splitPoint = self::_GetInt2d($recordData, 2); + if (in_array($splitPoint, $validSplitPoints)) { + // get spliced record data (and move pointer to next record) + $splicedRecordData = $this->_getSplicedRecordData(); + $this->_drawingData .= $splicedRecordData['recordData']; + + return; + } + + // move stream pointer to next record + $this->_pos += 4 + $length; + + } + + + /** + * Reads a record from current position in data stream and continues reading data as long as CONTINUE + * records are found. Splices the record data pieces and returns the combined string as if record data + * is in one piece. + * Moves to next current position in data stream to start of next record different from a CONtINUE record + * + * @return array + */ + private function _getSplicedRecordData() + { + $data = ''; + $spliceOffsets = array(); + + $i = 0; + $spliceOffsets[0] = 0; + + do { + ++$i; + + // offset: 0; size: 2; identifier + $identifier = self::_GetInt2d($this->_data, $this->_pos); + // offset: 2; size: 2; length + $length = self::_GetInt2d($this->_data, $this->_pos + 2); + $data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length); + + $spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length; + + $this->_pos += 4 + $length; + $nextIdentifier = self::_GetInt2d($this->_data, $this->_pos); + } + while ($nextIdentifier == self::XLS_Type_CONTINUE); + + $splicedData = array( + 'recordData' => $data, + 'spliceOffsets' => $spliceOffsets, + ); + + return $splicedData; + + } + + + /** + * Convert formula structure into human readable Excel formula like 'A3+A5*5' + * + * @param string $formulaStructure The complete binary data for the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1') + { + // offset: 0; size: 2; size of the following formula data + $sz = self::_GetInt2d($formulaStructure, 0); + + // offset: 2; size: sz + $formulaData = substr($formulaStructure, 2, $sz); + + // for debug: dump the formula data + //echo ''; + //echo 'size: ' . $sz . "\n"; + //echo 'the entire formula data: '; + //Debug::dump($formulaData); + //echo "\n----\n"; + + // offset: 2 + sz; size: variable (optional) + if (strlen($formulaStructure) > 2 + $sz) { + $additionalData = substr($formulaStructure, 2 + $sz); + + // for debug: dump the additional data + //echo 'the entire additional data: '; + //Debug::dump($additionalData); + //echo "\n----\n"; + + } else { + $additionalData = ''; + } + + return $this->_getFormulaFromData($formulaData, $additionalData, $baseCell); + } + + + /** + * Take formula data and additional data for formula and return human readable formula + * + * @param string $formulaData The binary data for the formula itself + * @param string $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _getFormulaFromData($formulaData, $additionalData = '', $baseCell = 'A1') + { + // start parsing the formula data + $tokens = array(); + + while (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) { + $tokens[] = $token; + $formulaData = substr($formulaData, $token['size']); + + // for debug: dump the token + //var_dump($token); + } + + $formulaString = $this->_createFormulaFromTokens($tokens, $additionalData); + + return $formulaString; + } + + + /** + * Take array of tokens together with additional data for formula and return human readable formula + * + * @param array $tokens + * @param array $additionalData Additional binary data going with the formula + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string Human readable formula + */ + private function _createFormulaFromTokens($tokens, $additionalData) + { + // empty formula? + if (empty($tokens)) { + return ''; + } + + $formulaStrings = array(); + foreach ($tokens as $token) { + // initialize spaces + $space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen + $space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen + $space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis + $space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis + $space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis + $space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis + + switch ($token['name']) { + case 'tAdd': // addition + case 'tConcat': // addition + case 'tDiv': // division + case 'tEQ': // equality + case 'tGE': // greater than or equal + case 'tGT': // greater than + case 'tIsect': // intersection + case 'tLE': // less than or equal + case 'tList': // less than or equal + case 'tLT': // less than + case 'tMul': // multiplication + case 'tNE': // multiplication + case 'tPower': // power + case 'tRange': // range + case 'tSub': // subtraction + $op2 = array_pop($formulaStrings); + $op1 = array_pop($formulaStrings); + $formulaStrings[] = "$op1$space1$space0{$token['data']}$op2"; + unset($space0, $space1); + break; + case 'tUplus': // unary plus + case 'tUminus': // unary minus + $op = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0{$token['data']}$op"; + unset($space0, $space1); + break; + case 'tPercent': // percent sign + $op = array_pop($formulaStrings); + $formulaStrings[] = "$op$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tAttrVolatile': // indicates volatile function + case 'tAttrIf': + case 'tAttrSkip': + case 'tAttrChoose': + // token is only important for Excel formula evaluator + // do nothing + break; + case 'tAttrSpace': // space / carriage return + // space will be used when next token arrives, do not alter formulaString stack + switch ($token['data']['spacetype']) { + case 'type0': + $space0 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type1': + $space1 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type2': + $space2 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type3': + $space3 = str_repeat("\n", $token['data']['spacecount']); + break; + case 'type4': + $space4 = str_repeat(' ', $token['data']['spacecount']); + break; + case 'type5': + $space5 = str_repeat("\n", $token['data']['spacecount']); + break; + } + break; + case 'tAttrSum': // SUM function with one parameter + $op = array_pop($formulaStrings); + $formulaStrings[] = "{$space1}{$space0}SUM($op)"; + unset($space0, $space1); + break; + case 'tFunc': // function with fixed number of arguments + case 'tFuncV': // function with variable number of arguments + if ($token['data']['function'] != '') { + // normal function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args']; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $formulaStrings[] = "$space1$space0{$token['data']['function']}(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } else { + // add-in function + $ops = array(); // array of operators + for ($i = 0; $i < $token['data']['args'] - 1; ++$i) { + $ops[] = array_pop($formulaStrings); + } + $ops = array_reverse($ops); + $function = array_pop($formulaStrings); + $formulaStrings[] = "$space1$space0$function(" . implode(',', $ops) . ")"; + unset($space0, $space1); + } + break; + case 'tParen': // parenthesis + $expression = array_pop($formulaStrings); + $formulaStrings[] = "$space3$space2($expression$space5$space4)"; + unset($space2, $space3, $space4, $space5); + break; + case 'tArray': // array constant + $constantArray = self::_readBIFF8ConstantArray($additionalData); + $formulaStrings[] = $space1 . $space0 . $constantArray['value']; + $additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data + unset($space0, $space1); + break; + case 'tMemArea': + // bite off chunk of additional data + $cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData); + $additionalData = substr($additionalData, $cellRangeAddressList['size']); + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + case 'tArea': // cell range address + case 'tBool': // boolean + case 'tErr': // error code + case 'tInt': // integer + case 'tMemErr': + case 'tMemFunc': + case 'tMissArg': + case 'tName': + case 'tNameX': + case 'tNum': // number + case 'tRef': // single cell reference + case 'tRef3d': // 3d cell reference + case 'tArea3d': // 3d cell range reference + case 'tRefN': + case 'tAreaN': + case 'tStr': // string + $formulaStrings[] = "$space1$space0{$token['data']}"; + unset($space0, $space1); + break; + } + } + $formulaString = $formulaStrings[0]; + + // for debug: dump the human readable formula + //echo '----' . "\n"; + //echo 'Formula: ' . $formulaString; + + return $formulaString; + } + + + /** + * Fetch next token from binary formula data + * + * @param string Formula data + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return array + * @throws PHPExcel_Reader_Exception + */ + private function _getNextToken($formulaData, $baseCell = 'A1') + { + // offset: 0; size: 1; token id + $id = ord($formulaData[0]); // token id + $name = false; // initialize token name + + switch ($id) { + case 0x03: $name = 'tAdd'; $size = 1; $data = '+'; break; + case 0x04: $name = 'tSub'; $size = 1; $data = '-'; break; + case 0x05: $name = 'tMul'; $size = 1; $data = '*'; break; + case 0x06: $name = 'tDiv'; $size = 1; $data = '/'; break; + case 0x07: $name = 'tPower'; $size = 1; $data = '^'; break; + case 0x08: $name = 'tConcat'; $size = 1; $data = '&'; break; + case 0x09: $name = 'tLT'; $size = 1; $data = '<'; break; + case 0x0A: $name = 'tLE'; $size = 1; $data = '<='; break; + case 0x0B: $name = 'tEQ'; $size = 1; $data = '='; break; + case 0x0C: $name = 'tGE'; $size = 1; $data = '>='; break; + case 0x0D: $name = 'tGT'; $size = 1; $data = '>'; break; + case 0x0E: $name = 'tNE'; $size = 1; $data = '<>'; break; + case 0x0F: $name = 'tIsect'; $size = 1; $data = ' '; break; + case 0x10: $name = 'tList'; $size = 1; $data = ','; break; + case 0x11: $name = 'tRange'; $size = 1; $data = ':'; break; + case 0x12: $name = 'tUplus'; $size = 1; $data = '+'; break; + case 0x13: $name = 'tUminus'; $size = 1; $data = '-'; break; + case 0x14: $name = 'tPercent'; $size = 1; $data = '%'; break; + case 0x15: // parenthesis + $name = 'tParen'; + $size = 1; + $data = null; + break; + case 0x16: // missing argument + $name = 'tMissArg'; + $size = 1; + $data = ''; + break; + case 0x17: // string + $name = 'tStr'; + // offset: 1; size: var; Unicode string, 8-bit string length + $string = self::_readUnicodeStringShort(substr($formulaData, 1)); + $size = 1 + $string['size']; + $data = self::_UTF8toExcelDoubleQuoted($string['value']); + break; + case 0x19: // Special attribute + // offset: 1; size: 1; attribute type flags: + switch (ord($formulaData[1])) { + case 0x01: + $name = 'tAttrVolatile'; + $size = 4; + $data = null; + break; + case 0x02: + $name = 'tAttrIf'; + $size = 4; + $data = null; + break; + case 0x04: + $name = 'tAttrChoose'; + // offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1) + $nc = self::_GetInt2d($formulaData, 2); + // offset: 4; size: 2 * $nc + // offset: 4 + 2 * $nc; size: 2 + $size = 2 * $nc + 6; + $data = null; + break; + case 0x08: + $name = 'tAttrSkip'; + $size = 4; + $data = null; + break; + case 0x10: + $name = 'tAttrSum'; + $size = 4; + $data = null; + break; + case 0x40: + case 0x41: + $name = 'tAttrSpace'; + $size = 4; + // offset: 2; size: 2; space type and position + switch (ord($formulaData[2])) { + case 0x00: + $spacetype = 'type0'; + break; + case 0x01: + $spacetype = 'type1'; + break; + case 0x02: + $spacetype = 'type2'; + break; + case 0x03: + $spacetype = 'type3'; + break; + case 0x04: + $spacetype = 'type4'; + break; + case 0x05: + $spacetype = 'type5'; + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token'); + break; + } + // offset: 3; size: 1; number of inserted spaces/carriage returns + $spacecount = ord($formulaData[3]); + + $data = array('spacetype' => $spacetype, 'spacecount' => $spacecount); + break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token'); + break; + } + break; + case 0x1C: // error code + // offset: 1; size: 1; error code + $name = 'tErr'; + $size = 2; + $data = self::_mapErrorCode(ord($formulaData[1])); + break; + case 0x1D: // boolean + // offset: 1; size: 1; 0 = false, 1 = true; + $name = 'tBool'; + $size = 2; + $data = ord($formulaData[1]) ? 'TRUE' : 'FALSE'; + break; + case 0x1E: // integer + // offset: 1; size: 2; unsigned 16-bit integer + $name = 'tInt'; + $size = 3; + $data = self::_GetInt2d($formulaData, 1); + break; + case 0x1F: // number + // offset: 1; size: 8; + $name = 'tNum'; + $size = 9; + $data = self::_extractNumber(substr($formulaData, 1)); + $data = str_replace(',', '.', (string)$data); // in case non-English locale + break; + case 0x20: // array constant + case 0x40: + case 0x60: + // offset: 1; size: 7; not used + $name = 'tArray'; + $size = 8; + $data = null; + break; + case 0x21: // function with fixed number of arguments + case 0x41: + case 0x61: + $name = 'tFunc'; + $size = 3; + // offset: 1; size: 2; index to built-in sheet function + switch (self::_GetInt2d($formulaData, 1)) { + case 2: $function = 'ISNA'; $args = 1; break; + case 3: $function = 'ISERROR'; $args = 1; break; + case 10: $function = 'NA'; $args = 0; break; + case 15: $function = 'SIN'; $args = 1; break; + case 16: $function = 'COS'; $args = 1; break; + case 17: $function = 'TAN'; $args = 1; break; + case 18: $function = 'ATAN'; $args = 1; break; + case 19: $function = 'PI'; $args = 0; break; + case 20: $function = 'SQRT'; $args = 1; break; + case 21: $function = 'EXP'; $args = 1; break; + case 22: $function = 'LN'; $args = 1; break; + case 23: $function = 'LOG10'; $args = 1; break; + case 24: $function = 'ABS'; $args = 1; break; + case 25: $function = 'INT'; $args = 1; break; + case 26: $function = 'SIGN'; $args = 1; break; + case 27: $function = 'ROUND'; $args = 2; break; + case 30: $function = 'REPT'; $args = 2; break; + case 31: $function = 'MID'; $args = 3; break; + case 32: $function = 'LEN'; $args = 1; break; + case 33: $function = 'VALUE'; $args = 1; break; + case 34: $function = 'TRUE'; $args = 0; break; + case 35: $function = 'FALSE'; $args = 0; break; + case 38: $function = 'NOT'; $args = 1; break; + case 39: $function = 'MOD'; $args = 2; break; + case 40: $function = 'DCOUNT'; $args = 3; break; + case 41: $function = 'DSUM'; $args = 3; break; + case 42: $function = 'DAVERAGE'; $args = 3; break; + case 43: $function = 'DMIN'; $args = 3; break; + case 44: $function = 'DMAX'; $args = 3; break; + case 45: $function = 'DSTDEV'; $args = 3; break; + case 48: $function = 'TEXT'; $args = 2; break; + case 61: $function = 'MIRR'; $args = 3; break; + case 63: $function = 'RAND'; $args = 0; break; + case 65: $function = 'DATE'; $args = 3; break; + case 66: $function = 'TIME'; $args = 3; break; + case 67: $function = 'DAY'; $args = 1; break; + case 68: $function = 'MONTH'; $args = 1; break; + case 69: $function = 'YEAR'; $args = 1; break; + case 71: $function = 'HOUR'; $args = 1; break; + case 72: $function = 'MINUTE'; $args = 1; break; + case 73: $function = 'SECOND'; $args = 1; break; + case 74: $function = 'NOW'; $args = 0; break; + case 75: $function = 'AREAS'; $args = 1; break; + case 76: $function = 'ROWS'; $args = 1; break; + case 77: $function = 'COLUMNS'; $args = 1; break; + case 83: $function = 'TRANSPOSE'; $args = 1; break; + case 86: $function = 'TYPE'; $args = 1; break; + case 97: $function = 'ATAN2'; $args = 2; break; + case 98: $function = 'ASIN'; $args = 1; break; + case 99: $function = 'ACOS'; $args = 1; break; + case 105: $function = 'ISREF'; $args = 1; break; + case 111: $function = 'CHAR'; $args = 1; break; + case 112: $function = 'LOWER'; $args = 1; break; + case 113: $function = 'UPPER'; $args = 1; break; + case 114: $function = 'PROPER'; $args = 1; break; + case 117: $function = 'EXACT'; $args = 2; break; + case 118: $function = 'TRIM'; $args = 1; break; + case 119: $function = 'REPLACE'; $args = 4; break; + case 121: $function = 'CODE'; $args = 1; break; + case 126: $function = 'ISERR'; $args = 1; break; + case 127: $function = 'ISTEXT'; $args = 1; break; + case 128: $function = 'ISNUMBER'; $args = 1; break; + case 129: $function = 'ISBLANK'; $args = 1; break; + case 130: $function = 'T'; $args = 1; break; + case 131: $function = 'N'; $args = 1; break; + case 140: $function = 'DATEVALUE'; $args = 1; break; + case 141: $function = 'TIMEVALUE'; $args = 1; break; + case 142: $function = 'SLN'; $args = 3; break; + case 143: $function = 'SYD'; $args = 4; break; + case 162: $function = 'CLEAN'; $args = 1; break; + case 163: $function = 'MDETERM'; $args = 1; break; + case 164: $function = 'MINVERSE'; $args = 1; break; + case 165: $function = 'MMULT'; $args = 2; break; + case 184: $function = 'FACT'; $args = 1; break; + case 189: $function = 'DPRODUCT'; $args = 3; break; + case 190: $function = 'ISNONTEXT'; $args = 1; break; + case 195: $function = 'DSTDEVP'; $args = 3; break; + case 196: $function = 'DVARP'; $args = 3; break; + case 198: $function = 'ISLOGICAL'; $args = 1; break; + case 199: $function = 'DCOUNTA'; $args = 3; break; + case 207: $function = 'REPLACEB'; $args = 4; break; + case 210: $function = 'MIDB'; $args = 3; break; + case 211: $function = 'LENB'; $args = 1; break; + case 212: $function = 'ROUNDUP'; $args = 2; break; + case 213: $function = 'ROUNDDOWN'; $args = 2; break; + case 214: $function = 'ASC'; $args = 1; break; + case 215: $function = 'DBCS'; $args = 1; break; + case 221: $function = 'TODAY'; $args = 0; break; + case 229: $function = 'SINH'; $args = 1; break; + case 230: $function = 'COSH'; $args = 1; break; + case 231: $function = 'TANH'; $args = 1; break; + case 232: $function = 'ASINH'; $args = 1; break; + case 233: $function = 'ACOSH'; $args = 1; break; + case 234: $function = 'ATANH'; $args = 1; break; + case 235: $function = 'DGET'; $args = 3; break; + case 244: $function = 'INFO'; $args = 1; break; + case 252: $function = 'FREQUENCY'; $args = 2; break; + case 261: $function = 'ERROR.TYPE'; $args = 1; break; + case 271: $function = 'GAMMALN'; $args = 1; break; + case 273: $function = 'BINOMDIST'; $args = 4; break; + case 274: $function = 'CHIDIST'; $args = 2; break; + case 275: $function = 'CHIINV'; $args = 2; break; + case 276: $function = 'COMBIN'; $args = 2; break; + case 277: $function = 'CONFIDENCE'; $args = 3; break; + case 278: $function = 'CRITBINOM'; $args = 3; break; + case 279: $function = 'EVEN'; $args = 1; break; + case 280: $function = 'EXPONDIST'; $args = 3; break; + case 281: $function = 'FDIST'; $args = 3; break; + case 282: $function = 'FINV'; $args = 3; break; + case 283: $function = 'FISHER'; $args = 1; break; + case 284: $function = 'FISHERINV'; $args = 1; break; + case 285: $function = 'FLOOR'; $args = 2; break; + case 286: $function = 'GAMMADIST'; $args = 4; break; + case 287: $function = 'GAMMAINV'; $args = 3; break; + case 288: $function = 'CEILING'; $args = 2; break; + case 289: $function = 'HYPGEOMDIST'; $args = 4; break; + case 290: $function = 'LOGNORMDIST'; $args = 3; break; + case 291: $function = 'LOGINV'; $args = 3; break; + case 292: $function = 'NEGBINOMDIST'; $args = 3; break; + case 293: $function = 'NORMDIST'; $args = 4; break; + case 294: $function = 'NORMSDIST'; $args = 1; break; + case 295: $function = 'NORMINV'; $args = 3; break; + case 296: $function = 'NORMSINV'; $args = 1; break; + case 297: $function = 'STANDARDIZE'; $args = 3; break; + case 298: $function = 'ODD'; $args = 1; break; + case 299: $function = 'PERMUT'; $args = 2; break; + case 300: $function = 'POISSON'; $args = 3; break; + case 301: $function = 'TDIST'; $args = 3; break; + case 302: $function = 'WEIBULL'; $args = 4; break; + case 303: $function = 'SUMXMY2'; $args = 2; break; + case 304: $function = 'SUMX2MY2'; $args = 2; break; + case 305: $function = 'SUMX2PY2'; $args = 2; break; + case 306: $function = 'CHITEST'; $args = 2; break; + case 307: $function = 'CORREL'; $args = 2; break; + case 308: $function = 'COVAR'; $args = 2; break; + case 309: $function = 'FORECAST'; $args = 3; break; + case 310: $function = 'FTEST'; $args = 2; break; + case 311: $function = 'INTERCEPT'; $args = 2; break; + case 312: $function = 'PEARSON'; $args = 2; break; + case 313: $function = 'RSQ'; $args = 2; break; + case 314: $function = 'STEYX'; $args = 2; break; + case 315: $function = 'SLOPE'; $args = 2; break; + case 316: $function = 'TTEST'; $args = 4; break; + case 325: $function = 'LARGE'; $args = 2; break; + case 326: $function = 'SMALL'; $args = 2; break; + case 327: $function = 'QUARTILE'; $args = 2; break; + case 328: $function = 'PERCENTILE'; $args = 2; break; + case 331: $function = 'TRIMMEAN'; $args = 2; break; + case 332: $function = 'TINV'; $args = 2; break; + case 337: $function = 'POWER'; $args = 2; break; + case 342: $function = 'RADIANS'; $args = 1; break; + case 343: $function = 'DEGREES'; $args = 1; break; + case 346: $function = 'COUNTIF'; $args = 2; break; + case 347: $function = 'COUNTBLANK'; $args = 1; break; + case 350: $function = 'ISPMT'; $args = 4; break; + case 351: $function = 'DATEDIF'; $args = 3; break; + case 352: $function = 'DATESTRING'; $args = 1; break; + case 353: $function = 'NUMBERSTRING'; $args = 2; break; + case 360: $function = 'PHONETIC'; $args = 1; break; + case 368: $function = 'BAHTTEXT'; $args = 1; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x22: // function with variable number of arguments + case 0x42: + case 0x62: + $name = 'tFuncV'; + $size = 4; + // offset: 1; size: 1; number of arguments + $args = ord($formulaData[1]); + // offset: 2: size: 2; index to built-in sheet function + $index = self::_GetInt2d($formulaData, 2); + switch ($index) { + case 0: $function = 'COUNT'; break; + case 1: $function = 'IF'; break; + case 4: $function = 'SUM'; break; + case 5: $function = 'AVERAGE'; break; + case 6: $function = 'MIN'; break; + case 7: $function = 'MAX'; break; + case 8: $function = 'ROW'; break; + case 9: $function = 'COLUMN'; break; + case 11: $function = 'NPV'; break; + case 12: $function = 'STDEV'; break; + case 13: $function = 'DOLLAR'; break; + case 14: $function = 'FIXED'; break; + case 28: $function = 'LOOKUP'; break; + case 29: $function = 'INDEX'; break; + case 36: $function = 'AND'; break; + case 37: $function = 'OR'; break; + case 46: $function = 'VAR'; break; + case 49: $function = 'LINEST'; break; + case 50: $function = 'TREND'; break; + case 51: $function = 'LOGEST'; break; + case 52: $function = 'GROWTH'; break; + case 56: $function = 'PV'; break; + case 57: $function = 'FV'; break; + case 58: $function = 'NPER'; break; + case 59: $function = 'PMT'; break; + case 60: $function = 'RATE'; break; + case 62: $function = 'IRR'; break; + case 64: $function = 'MATCH'; break; + case 70: $function = 'WEEKDAY'; break; + case 78: $function = 'OFFSET'; break; + case 82: $function = 'SEARCH'; break; + case 100: $function = 'CHOOSE'; break; + case 101: $function = 'HLOOKUP'; break; + case 102: $function = 'VLOOKUP'; break; + case 109: $function = 'LOG'; break; + case 115: $function = 'LEFT'; break; + case 116: $function = 'RIGHT'; break; + case 120: $function = 'SUBSTITUTE'; break; + case 124: $function = 'FIND'; break; + case 125: $function = 'CELL'; break; + case 144: $function = 'DDB'; break; + case 148: $function = 'INDIRECT'; break; + case 167: $function = 'IPMT'; break; + case 168: $function = 'PPMT'; break; + case 169: $function = 'COUNTA'; break; + case 183: $function = 'PRODUCT'; break; + case 193: $function = 'STDEVP'; break; + case 194: $function = 'VARP'; break; + case 197: $function = 'TRUNC'; break; + case 204: $function = 'USDOLLAR'; break; + case 205: $function = 'FINDB'; break; + case 206: $function = 'SEARCHB'; break; + case 208: $function = 'LEFTB'; break; + case 209: $function = 'RIGHTB'; break; + case 216: $function = 'RANK'; break; + case 219: $function = 'ADDRESS'; break; + case 220: $function = 'DAYS360'; break; + case 222: $function = 'VDB'; break; + case 227: $function = 'MEDIAN'; break; + case 228: $function = 'SUMPRODUCT'; break; + case 247: $function = 'DB'; break; + case 255: $function = ''; break; + case 269: $function = 'AVEDEV'; break; + case 270: $function = 'BETADIST'; break; + case 272: $function = 'BETAINV'; break; + case 317: $function = 'PROB'; break; + case 318: $function = 'DEVSQ'; break; + case 319: $function = 'GEOMEAN'; break; + case 320: $function = 'HARMEAN'; break; + case 321: $function = 'SUMSQ'; break; + case 322: $function = 'KURT'; break; + case 323: $function = 'SKEW'; break; + case 324: $function = 'ZTEST'; break; + case 329: $function = 'PERCENTRANK'; break; + case 330: $function = 'MODE'; break; + case 336: $function = 'CONCATENATE'; break; + case 344: $function = 'SUBTOTAL'; break; + case 345: $function = 'SUMIF'; break; + case 354: $function = 'ROMAN'; break; + case 358: $function = 'GETPIVOTDATA'; break; + case 359: $function = 'HYPERLINK'; break; + case 361: $function = 'AVERAGEA'; break; + case 362: $function = 'MAXA'; break; + case 363: $function = 'MINA'; break; + case 364: $function = 'STDEVPA'; break; + case 365: $function = 'VARPA'; break; + case 366: $function = 'STDEVA'; break; + case 367: $function = 'VARA'; break; + default: + throw new PHPExcel_Reader_Exception('Unrecognized function in formula'); + break; + } + $data = array('function' => $function, 'args' => $args); + break; + case 0x23: // index to defined name + case 0x43: + case 0x63: + $name = 'tName'; + $size = 5; + // offset: 1; size: 2; one-based index to definedname record + $definedNameIndex = self::_GetInt2d($formulaData, 1) - 1; + // offset: 2; size: 2; not used + $data = $this->_definedname[$definedNameIndex]['name']; + break; + case 0x24: // single cell reference e.g. A5 + case 0x44: + case 0x64: + $name = 'tRef'; + $size = 5; + $data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4)); + break; + case 0x25: // cell range reference to cells in the same sheet (2d) + case 0x45: + case 0x65: + $name = 'tArea'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8)); + break; + case 0x26: // Constant reference sub-expression + case 0x46: + case 0x66: + $name = 'tMemArea'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x27: // Deleted constant reference sub-expression + case 0x47: + case 0x67: + $name = 'tMemErr'; + // offset: 1; size: 4; not used + // offset: 5; size: 2; size of the following subexpression + $subSize = self::_GetInt2d($formulaData, 5); + $size = 7 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize)); + break; + case 0x29: // Variable reference sub-expression + case 0x49: + case 0x69: + $name = 'tMemFunc'; + // offset: 1; size: 2; size of the following sub-expression + $subSize = self::_GetInt2d($formulaData, 1); + $size = 3 + $subSize; + $data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize)); + break; + + case 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places + case 0x4C: + case 0x6C: + $name = 'tRefN'; + $size = 5; + $data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell); + break; + + case 0x2D: // Relative 2d range reference + case 0x4D: + case 0x6D: + $name = 'tAreaN'; + $size = 9; + $data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell); + break; + + case 0x39: // External name + case 0x59: + case 0x79: + $name = 'tNameX'; + $size = 7; + // offset: 1; size: 2; index to REF entry in EXTERNSHEET record + // offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record + $index = self::_GetInt2d($formulaData, 3); + // assume index is to EXTERNNAME record + $data = $this->_externalNames[$index - 1]['name']; + // offset: 5; size: 2; not used + break; + + case 0x3A: // 3d reference to cell + case 0x5A: + case 0x7A: + $name = 'tRef3d'; + $size = 7; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 4; cell address + $cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4)); + + $data = "$sheetRange!$cellAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + case 0x3B: // 3d reference to cell range + case 0x5B: + case 0x7B: + $name = 'tArea3d'; + $size = 11; + + try { + // offset: 1; size: 2; index to REF entry + $sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1)); + // offset: 3; size: 8; cell address + $cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8)); + + $data = "$sheetRange!$cellRangeAddress"; + } catch (PHPExcel_Exception $e) { + // deleted sheet reference + $data = '#REF!'; + } + + break; + // Unknown cases // don't know how to deal with + default: + throw new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula'); + break; + } + + return array( + 'id' => $id, + 'name' => $name, + 'size' => $size, + 'data' => $data, + ); + } + + + /** + * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2' + * section 3.3.4 + * + * @param string $cellAddressStructure + * @return string + */ + private function _readBIFF8CellAddress($cellAddressStructure) + { + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = '$' . $column; + } + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } + + return $column . $row; + } + + + /** + * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $cellAddressStructure + * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas + * @return string + */ + private function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767)) + $rowIndex = self::_GetInt2d($cellAddressStructure, 0); + $row = self::_GetInt2d($cellAddressStructure, 0) + 1; + + // offset: 2; size: 2; index to column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) { + $column = PHPExcel_Cell::stringFromColumnIndex($colIndex); + $column = '$' . $column; + } else { + $colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256; + $column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) { + $row = '$' . $row; + } else { + $rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536; + $row = $baseRow + $rowIndex; + } + + return $column . $row; + } + + + /** + * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF5CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 1; index to first column + $fc = ord($subData{4}); + + // offset: 5; size: 1; index to last column + $lc = ord($subData{5}); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1' + * always fixed range + * section 2.5.14 + * + * @param string $subData + * @return string + * @throws PHPExcel_Reader_Exception + */ + private function _readBIFF8CellRangeAddressFixed($subData) + { + // offset: 0; size: 2; index to first row + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column + $fc = self::_GetInt2d($subData, 4); + + // offset: 6; size: 2; index to last column + $lc = self::_GetInt2d($subData, 6); + + // check values + if ($fr > $lr || $fc > $lc) { + throw new PHPExcel_Reader_Exception('Not a cell range address'); + } + + // column index to letter + $fc = PHPExcel_Cell::stringFromColumnIndex($fc); + $lc = PHPExcel_Cell::stringFromColumnIndex($lc); + + if ($fr == $lr and $fc == $lc) { + return "$fc$fr"; + } + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6' + * there are flags indicating whether column/row index is relative + * section 3.3.4 + * + * @param string $subData + * @return string + */ + private function _readBIFF8CellRangeAddress($subData) + { + // todo: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767)) + $fr = self::_GetInt2d($subData, 0) + 1; + + // offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767)) + $lr = self::_GetInt2d($subData, 2) + 1; + + // offset: 4; size: 2; index to first column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + $fc = '$' . $fc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + $fr = '$' . $fr; + } + + // offset: 6; size: 2; index to last column or column offset + relative flags + + // bit: 7-0; mask 0x00FF; column index + $lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6)); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + $lc = '$' . $lc; + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + $lr = '$' . $lr; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column + * to indicate offsets from a base cell + * section 3.3.4 + * + * @param string $subData + * @param string $baseCell Base cell + * @return string Cell range address + */ + private function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1') + { + list($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell); + $baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1; + + // TODO: if cell range is just a single cell, should this funciton + // not just return e.g. 'A1' and not 'A1:A1' ? + + // offset: 0; size: 2; first row + $frIndex = self::_GetInt2d($subData, 0); // adjust below + + // offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767) + $lrIndex = self::_GetInt2d($subData, 2); // adjust below + + // offset: 4; size: 2; first column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $fcIndex = 0x00FF & self::_GetInt2d($subData, 4); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 4))) { + // absolute column index + $fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex); + $fc = '$' . $fc; + } else { + // column offset + $fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256; + $fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 4))) { + // absolute row index + $fr = $frIndex + 1; + $fr = '$' . $fr; + } else { + // row offset + $frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536; + $fr = $baseRow + $frIndex; + } + + // offset: 6; size: 2; last column with relative/absolute flags + + // bit: 7-0; mask 0x00FF; column index + $lcIndex = 0x00FF & self::_GetInt2d($subData, 6); + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + + // bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index) + if (!(0x4000 & self::_GetInt2d($subData, 6))) { + // absolute column index + $lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex); + $lc = '$' . $lc; + } else { + // column offset + $lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256; + $lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex); + } + + // bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index) + if (!(0x8000 & self::_GetInt2d($subData, 6))) { + // absolute row index + $lr = $lrIndex + 1; + $lr = '$' . $lr; + } else { + // row offset + $lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536; + $lr = $baseRow + $lrIndex; + } + + return "$fc$fr:$lc$lr"; + } + + + /** + * Read BIFF8 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF8CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8)); + $offset += 8; + } + + return array( + 'size' => 2 + 8 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Read BIFF5 cell range address list + * section 2.5.15 + * + * @param string $subData + * @return array + */ + private function _readBIFF5CellRangeAddressList($subData) + { + $cellRangeAddresses = array(); + + // offset: 0; size: 2; number of the following cell range addresses + $nm = self::_GetInt2d($subData, 0); + + $offset = 2; + // offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses + for ($i = 0; $i < $nm; ++$i) { + $cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6)); + $offset += 6; + } + + return array( + 'size' => 2 + 6 * $nm, + 'cellRangeAddresses' => $cellRangeAddresses, + ); + } + + + /** + * Get a sheet range like Sheet1:Sheet3 from REF index + * Note: If there is only one sheet in the range, one gets e.g Sheet1 + * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets, + * in which case an PHPExcel_Reader_Exception is thrown + * + * @param int $index + * @return string|false + * @throws PHPExcel_Reader_Exception + */ + private function _readSheetRangeByRefIndex($index) + { + if (isset($this->_ref[$index])) { + + $type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type']; + + switch ($type) { + case 'internal': + // check if we have a deleted 3d reference + if ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) { + throw new PHPExcel_Reader_Exception('Deleted sheet reference'); + } + + // we have normal sheet range (collapsed or uncollapsed) + $firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name']; + $lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name']; + + if ($firstSheetName == $lastSheetName) { + // collapsed sheet range + $sheetRange = $firstSheetName; + } else { + $sheetRange = "$firstSheetName:$lastSheetName"; + } + + // escape the single-quotes + $sheetRange = str_replace("'", "''", $sheetRange); + + // if there are special characters, we need to enclose the range in single-quotes + // todo: check if we have identified the whole set of special characters + // it seems that the following characters are not accepted for sheet names + // and we may assume that they are not present: []*/:\? + if (preg_match("/[ !\"@#£$%&{()}<>=+'|^,;-]/", $sheetRange)) { + $sheetRange = "'$sheetRange'"; + } + + return $sheetRange; + break; + + default: + // TODO: external sheet support + throw new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas'); + break; + } + } + return false; + } + + + /** + * read BIFF8 constant value array from array data + * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40} + * section 2.5.8 + * + * @param string $arrayData + * @return array + */ + private static function _readBIFF8ConstantArray($arrayData) + { + // offset: 0; size: 1; number of columns decreased by 1 + $nc = ord($arrayData[0]); + + // offset: 1; size: 2; number of rows decreased by 1 + $nr = self::_GetInt2d($arrayData, 1); + $size = 3; // initialize + $arrayData = substr($arrayData, 3); + + // offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values + $matrixChunks = array(); + for ($r = 1; $r <= $nr + 1; ++$r) { + $items = array(); + for ($c = 1; $c <= $nc + 1; ++$c) { + $constant = self::_readBIFF8Constant($arrayData); + $items[] = $constant['value']; + $arrayData = substr($arrayData, $constant['size']); + $size += $constant['size']; + } + $matrixChunks[] = implode(',', $items); // looks like e.g. '1,"hello"' + } + $matrix = '{' . implode(';', $matrixChunks) . '}'; + + return array( + 'value' => $matrix, + 'size' => $size, + ); + } + + + /** + * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value' + * section 2.5.7 + * returns e.g. array('value' => '5', 'size' => 9) + * + * @param string $valueData + * @return array + */ + private static function _readBIFF8Constant($valueData) + { + // offset: 0; size: 1; identifier for type of constant + $identifier = ord($valueData[0]); + + switch ($identifier) { + case 0x00: // empty constant (what is this?) + $value = ''; + $size = 9; + break; + case 0x01: // number + // offset: 1; size: 8; IEEE 754 floating-point value + $value = self::_extractNumber(substr($valueData, 1, 8)); + $size = 9; + break; + case 0x02: // string value + // offset: 1; size: var; Unicode string, 16-bit string length + $string = self::_readUnicodeStringLong(substr($valueData, 1)); + $value = '"' . $string['value'] . '"'; + $size = 1 + $string['size']; + break; + case 0x04: // boolean + // offset: 1; size: 1; 0 = FALSE, 1 = TRUE + if (ord($valueData[1])) { + $value = 'TRUE'; + } else { + $value = 'FALSE'; + } + $size = 9; + break; + case 0x10: // error code + // offset: 1; size: 1; error code + $value = self::_mapErrorCode(ord($valueData[1])); + $size = 9; + break; + } + return array( + 'value' => $value, + 'size' => $size, + ); + } + + + /** + * Extract RGB color + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4 + * + * @param string $rgb Encoded RGB value (4 bytes) + * @return array + */ + private static function _readRGB($rgb) + { + // offset: 0; size 1; Red component + $r = ord($rgb{0}); + + // offset: 1; size: 1; Green component + $g = ord($rgb{1}); + + // offset: 2; size: 1; Blue component + $b = ord($rgb{2}); + + // HEX notation, e.g. 'FF00FC' + $rgb = sprintf('%02X%02X%02X', $r, $g, $b); + + return array('rgb' => $rgb); + } + + + /** + * Read byte string (8-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringShort($subData) + { + // offset: 0; size: 1; length of the string (character count) + $ln = ord($subData[0]); + + // offset: 1: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 1, $ln)); + + return array( + 'value' => $value, + 'size' => 1 + $ln, // size in bytes of data structure + ); + } + + + /** + * Read byte string (16-bit string length) + * OpenOffice documentation: 2.5.2 + * + * @param string $subData + * @return array + */ + private function _readByteStringLong($subData) + { + // offset: 0; size: 2; length of the string (character count) + $ln = self::_GetInt2d($subData, 0); + + // offset: 2: size: var; character array (8-bit characters) + $value = $this->_decodeCodepage(substr($subData, 2)); + + //return $string; + return array( + 'value' => $value, + 'size' => 2 + $ln, // size in bytes of data structure + ); + } + + + /** + * Extracts an Excel Unicode short string (8-bit string length) + * OpenOffice documentation: 2.5.3 + * function will automatically find out where the Unicode string ends. + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringShort($subData) + { + $value = ''; + + // offset: 0: size: 1; length of the string (character count) + $characterCount = ord($subData[0]); + + $string = self::_readUnicodeString(substr($subData, 1), $characterCount); + + // add 1 for the string length + $string['size'] += 1; + + return $string; + } + + + /** + * Extracts an Excel Unicode long string (16-bit string length) + * OpenOffice documentation: 2.5.3 + * this function is under construction, needs to support rich text, and Asian phonetic settings + * + * @param string $subData + * @return array + */ + private static function _readUnicodeStringLong($subData) + { + $value = ''; + + // offset: 0: size: 2; length of the string (character count) + $characterCount = self::_GetInt2d($subData, 0); + + $string = self::_readUnicodeString(substr($subData, 2), $characterCount); + + // add 2 for the string length + $string['size'] += 2; + + return $string; + } + + + /** + * Read Unicode string with no string length field, but with known character count + * this function is under construction, needs to support rich text, and Asian phonetic settings + * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3 + * + * @param string $subData + * @param int $characterCount + * @return array + */ + private static function _readUnicodeString($subData, $characterCount) + { + $value = ''; + + // offset: 0: size: 1; option flags + + // bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit) + $isCompressed = !((0x01 & ord($subData[0])) >> 0); + + // bit: 2; mask: 0x04; Asian phonetic settings + $hasAsian = (0x04) & ord($subData[0]) >> 2; + + // bit: 3; mask: 0x08; Rich-Text settings + $hasRichText = (0x08) & ord($subData[0]) >> 3; + + // offset: 1: size: var; character array + // this offset assumes richtext and Asian phonetic settings are off which is generally wrong + // needs to be fixed + $value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed); + + return array( + 'value' => $value, + 'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags + ); + } + + + /** + * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas. + * Example: hello"world --> "hello""world" + * + * @param string $value UTF-8 encoded string + * @return string + */ + private static function _UTF8toExcelDoubleQuoted($value) + { + return '"' . str_replace('"', '""', $value) . '"'; + } + + + /** + * Reads first 8 bytes of a string and return IEEE 754 float + * + * @param string $data Binary string that is at least 8 bytes long + * @return float + */ + private static function _extractNumber($data) + { + $rknumhigh = self::_GetInt4d($data, 4); + $rknumlow = self::_GetInt4d($data, 0); + $sign = ($rknumhigh & 0x80000000) >> 31; + $exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023; + $mantissa = (0x100000 | ($rknumhigh & 0x000fffff)); + $mantissalow1 = ($rknumlow & 0x80000000) >> 31; + $mantissalow2 = ($rknumlow & 0x7fffffff); + $value = $mantissa / pow( 2 , (20 - $exp)); + + if ($mantissalow1 != 0) { + $value += 1 / pow (2 , (21 - $exp)); + } + + $value += $mantissalow2 / pow (2 , (52 - $exp)); + if ($sign) { + $value *= -1; + } + + return $value; + } + + + private static function _GetIEEE754($rknum) + { + if (($rknum & 0x02) != 0) { + $value = $rknum >> 2; + } else { + // changes by mmp, info on IEEE754 encoding from + // research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html + // The RK format calls for using only the most significant 30 bits + // of the 64 bit floating point value. The other 34 bits are assumed + // to be 0 so we use the upper 30 bits of $rknum as follows... + $sign = ($rknum & 0x80000000) >> 31; + $exp = ($rknum & 0x7ff00000) >> 20; + $mantissa = (0x100000 | ($rknum & 0x000ffffc)); + $value = $mantissa / pow( 2 , (20- ($exp - 1023))); + if ($sign) { + $value = -1 * $value; + } + //end of changes by mmp + } + if (($rknum & 0x01) != 0) { + $value /= 100; + } + return $value; + } + + + /** + * Get UTF-8 string from (compressed or uncompressed) UTF-16 string + * + * @param string $string + * @param bool $compressed + * @return string + */ + private static function _encodeUTF16($string, $compressed = '') + { + if ($compressed) { + $string = self::_uncompressByteString($string); + } + + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE'); + } + + + /** + * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8. + * + * @param string $string + * @return string + */ + private static function _uncompressByteString($string) + { + $uncompressedString = ''; + $strLen = strlen($string); + for ($i = 0; $i < $strLen; ++$i) { + $uncompressedString .= $string[$i] . "\0"; + } + + return $uncompressedString; + } + + + /** + * Convert string to UTF-8. Only used for BIFF5. + * + * @param string $string + * @return string + */ + private function _decodeCodepage($string) + { + return PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage); + } + + + /** + * Read 16-bit unsigned integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt2d($data, $pos) + { + return ord($data[$pos]) | (ord($data[$pos+1]) << 8); + } + + + /** + * Read 32-bit signed integer + * + * @param string $data + * @param int $pos + * @return int + */ + public static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24; + } + + + /** + * Read color + * + * @param int $color Indexed color + * @param array $palette Color palette + * @return array RGB color value, example: array('rgb' => 'FF0000') + */ + private static function _readColor($color,$palette,$version) + { + if ($color <= 0x07 || $color >= 0x40) { + // special built-in color + return self::_mapBuiltInColor($color); + } elseif (isset($palette) && isset($palette[$color - 8])) { + // palette color, color index 0x08 maps to pallete index 0 + return $palette[$color - 8]; + } else { + // default color table + if ($version == self::XLS_BIFF8) { + return self::_mapColor($color); + } else { + // BIFF5 + return self::_mapColorBIFF5($color); + } + } + + return $color; + } + + + /** + * Map border style + * OpenOffice documentation: 2.5.11 + * + * @param int $index + * @return string + */ + private static function _mapBorderStyle($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Border::BORDER_NONE; + case 0x01: return PHPExcel_Style_Border::BORDER_THIN; + case 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM; + case 0x03: return PHPExcel_Style_Border::BORDER_DASHED; + case 0x04: return PHPExcel_Style_Border::BORDER_DOTTED; + case 0x05: return PHPExcel_Style_Border::BORDER_THICK; + case 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE; + case 0x07: return PHPExcel_Style_Border::BORDER_HAIR; + case 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + case 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT; + case 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + case 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT; + case 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + case 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + default: return PHPExcel_Style_Border::BORDER_NONE; + } + } + + + /** + * Get fill pattern from index + * OpenOffice documentation: 2.5.12 + * + * @param int $index + * @return string + */ + private static function _mapFillPattern($index) + { + switch ($index) { + case 0x00: return PHPExcel_Style_Fill::FILL_NONE; + case 0x01: return PHPExcel_Style_Fill::FILL_SOLID; + case 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + case 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + case 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + case 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + case 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + case 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + case 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + case 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + case 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + case 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + case 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + case 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + case 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + case 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + case 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + case 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + case 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + default: return PHPExcel_Style_Fill::FILL_NONE; + } + } + + + /** + * Map error code, e.g. '#N/A' + * + * @param int $subData + * @return string + */ + private static function _mapErrorCode($subData) + { + switch ($subData) { + case 0x00: return '#NULL!'; break; + case 0x07: return '#DIV/0!'; break; + case 0x0F: return '#VALUE!'; break; + case 0x17: return '#REF!'; break; + case 0x1D: return '#NAME?'; break; + case 0x24: return '#NUM!'; break; + case 0x2A: return '#N/A'; break; + default: return false; + } + } + + + /** + * Map built-in color to RGB value + * + * @param int $color Indexed color + * @return array + */ + private static function _mapBuiltInColor($color) + { + switch ($color) { + case 0x00: return array('rgb' => '000000'); + case 0x01: return array('rgb' => 'FFFFFF'); + case 0x02: return array('rgb' => 'FF0000'); + case 0x03: return array('rgb' => '00FF00'); + case 0x04: return array('rgb' => '0000FF'); + case 0x05: return array('rgb' => 'FFFF00'); + case 0x06: return array('rgb' => 'FF00FF'); + case 0x07: return array('rgb' => '00FFFF'); + case 0x40: return array('rgb' => '000000'); // system window text color + case 0x41: return array('rgb' => 'FFFFFF'); // system window background color + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF5 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColorBIFF5($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '8080FF'); + case 0x19: return array('rgb' => '802060'); + case 0x1A: return array('rgb' => 'FFFFC0'); + case 0x1B: return array('rgb' => 'A0E0F0'); + case 0x1C: return array('rgb' => '600080'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0080C0'); + case 0x1F: return array('rgb' => 'C0C0FF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CFFF'); + case 0x29: return array('rgb' => '69FFFF'); + case 0x2A: return array('rgb' => 'E0FFE0'); + case 0x2B: return array('rgb' => 'FFFF80'); + case 0x2C: return array('rgb' => 'A6CAF0'); + case 0x2D: return array('rgb' => 'DD9CB3'); + case 0x2E: return array('rgb' => 'B38FEE'); + case 0x2F: return array('rgb' => 'E3E3E3'); + case 0x30: return array('rgb' => '2A6FF9'); + case 0x31: return array('rgb' => '3FB8CD'); + case 0x32: return array('rgb' => '488436'); + case 0x33: return array('rgb' => '958C41'); + case 0x34: return array('rgb' => '8E5E42'); + case 0x35: return array('rgb' => 'A0627A'); + case 0x36: return array('rgb' => '624FAC'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '1D2FBE'); + case 0x39: return array('rgb' => '286676'); + case 0x3A: return array('rgb' => '004500'); + case 0x3B: return array('rgb' => '453E01'); + case 0x3C: return array('rgb' => '6A2813'); + case 0x3D: return array('rgb' => '85396A'); + case 0x3E: return array('rgb' => '4A3285'); + case 0x3F: return array('rgb' => '424242'); + default: return array('rgb' => '000000'); + } + } + + + /** + * Map color array from BIFF8 built-in color index + * + * @param int $subData + * @return array + */ + private static function _mapColor($subData) + { + switch ($subData) { + case 0x08: return array('rgb' => '000000'); + case 0x09: return array('rgb' => 'FFFFFF'); + case 0x0A: return array('rgb' => 'FF0000'); + case 0x0B: return array('rgb' => '00FF00'); + case 0x0C: return array('rgb' => '0000FF'); + case 0x0D: return array('rgb' => 'FFFF00'); + case 0x0E: return array('rgb' => 'FF00FF'); + case 0x0F: return array('rgb' => '00FFFF'); + case 0x10: return array('rgb' => '800000'); + case 0x11: return array('rgb' => '008000'); + case 0x12: return array('rgb' => '000080'); + case 0x13: return array('rgb' => '808000'); + case 0x14: return array('rgb' => '800080'); + case 0x15: return array('rgb' => '008080'); + case 0x16: return array('rgb' => 'C0C0C0'); + case 0x17: return array('rgb' => '808080'); + case 0x18: return array('rgb' => '9999FF'); + case 0x19: return array('rgb' => '993366'); + case 0x1A: return array('rgb' => 'FFFFCC'); + case 0x1B: return array('rgb' => 'CCFFFF'); + case 0x1C: return array('rgb' => '660066'); + case 0x1D: return array('rgb' => 'FF8080'); + case 0x1E: return array('rgb' => '0066CC'); + case 0x1F: return array('rgb' => 'CCCCFF'); + case 0x20: return array('rgb' => '000080'); + case 0x21: return array('rgb' => 'FF00FF'); + case 0x22: return array('rgb' => 'FFFF00'); + case 0x23: return array('rgb' => '00FFFF'); + case 0x24: return array('rgb' => '800080'); + case 0x25: return array('rgb' => '800000'); + case 0x26: return array('rgb' => '008080'); + case 0x27: return array('rgb' => '0000FF'); + case 0x28: return array('rgb' => '00CCFF'); + case 0x29: return array('rgb' => 'CCFFFF'); + case 0x2A: return array('rgb' => 'CCFFCC'); + case 0x2B: return array('rgb' => 'FFFF99'); + case 0x2C: return array('rgb' => '99CCFF'); + case 0x2D: return array('rgb' => 'FF99CC'); + case 0x2E: return array('rgb' => 'CC99FF'); + case 0x2F: return array('rgb' => 'FFCC99'); + case 0x30: return array('rgb' => '3366FF'); + case 0x31: return array('rgb' => '33CCCC'); + case 0x32: return array('rgb' => '99CC00'); + case 0x33: return array('rgb' => 'FFCC00'); + case 0x34: return array('rgb' => 'FF9900'); + case 0x35: return array('rgb' => 'FF6600'); + case 0x36: return array('rgb' => '666699'); + case 0x37: return array('rgb' => '969696'); + case 0x38: return array('rgb' => '003366'); + case 0x39: return array('rgb' => '339966'); + case 0x3A: return array('rgb' => '003300'); + case 0x3B: return array('rgb' => '333300'); + case 0x3C: return array('rgb' => '993300'); + case 0x3D: return array('rgb' => '993366'); + case 0x3E: return array('rgb' => '333399'); + case 0x3F: return array('rgb' => '333333'); + default: return array('rgb' => '000000'); + } + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel5/Escher.php b/extend/phpexcel/PHPExcel/Reader/Excel5/Escher.php new file mode 100755 index 0000000..3ed82c6 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel5/Escher.php @@ -0,0 +1,640 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Reader_Excel5_Escher + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_Escher +{ + const DGGCONTAINER = 0xF000; + const BSTORECONTAINER = 0xF001; + const DGCONTAINER = 0xF002; + const SPGRCONTAINER = 0xF003; + const SPCONTAINER = 0xF004; + const DGG = 0xF006; + const BSE = 0xF007; + const DG = 0xF008; + const SPGR = 0xF009; + const SP = 0xF00A; + const OPT = 0xF00B; + const CLIENTTEXTBOX = 0xF00D; + const CLIENTANCHOR = 0xF010; + const CLIENTDATA = 0xF011; + const BLIPJPEG = 0xF01D; + const BLIPPNG = 0xF01E; + const SPLITMENUCOLORS = 0xF11E; + const TERTIARYOPT = 0xF122; + + /** + * Escher stream data (binary) + * + * @var string + */ + private $_data; + + /** + * Size in bytes of the Escher stream data + * + * @var int + */ + private $_dataSize; + + /** + * Current position of stream pointer in Escher stream data + * + * @var int + */ + private $_pos; + + /** + * The object to be returned by the reader. Modified during load. + * + * @var mixed + */ + private $_object; + + /** + * Create a new PHPExcel_Reader_Excel5_Escher instance + * + * @param mixed $object + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Load Escher stream data. May be a partial Escher stream. + * + * @param string $data + */ + public function load($data) + { + $this->_data = $data; + + // total byte size of Excel data (workbook global substream + sheet substreams) + $this->_dataSize = strlen($this->_data); + + $this->_pos = 0; + + // Parse Escher stream + while ($this->_pos < $this->_dataSize) { + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + switch ($fbt) { + case self::DGGCONTAINER: $this->_readDggContainer(); break; + case self::DGG: $this->_readDgg(); break; + case self::BSTORECONTAINER: $this->_readBstoreContainer(); break; + case self::BSE: $this->_readBSE(); break; + case self::BLIPJPEG: $this->_readBlipJPEG(); break; + case self::BLIPPNG: $this->_readBlipPNG(); break; + case self::OPT: $this->_readOPT(); break; + case self::TERTIARYOPT: $this->_readTertiaryOPT(); break; + case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break; + case self::DGCONTAINER: $this->_readDgContainer(); break; + case self::DG: $this->_readDg(); break; + case self::SPGRCONTAINER: $this->_readSpgrContainer(); break; + case self::SPCONTAINER: $this->_readSpContainer(); break; + case self::SPGR: $this->_readSpgr(); break; + case self::SP: $this->_readSp(); break; + case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break; + case self::CLIENTANCHOR: $this->_readClientAnchor(); break; + case self::CLIENTDATA: $this->_readClientData(); break; + default: $this->_readDefault(); break; + } + } + + return $this->_object; + } + + /** + * Read a generic record + */ + private function _readDefault() + { + // offset 0; size: 2; recVer and recInstance + $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos); + + // offset: 2; size: 2: Record Type + $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2); + + // bit: 0-3; mask: 0x000F; recVer + $recVer = (0x000F & $verInstance) >> 0; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DggContainer record (Drawing Group Container) + */ + private function _readDggContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $this->_object->setDggContainer($dggContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer); + $reader->load($recordData); + } + + /** + * Read Dgg record (Drawing Group) + */ + private function _readDgg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read BstoreContainer record (Blip Store Container) + */ + private function _readBstoreContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $this->_object->setBstoreContainer($bstoreContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer); + $reader->load($recordData); + } + + /** + * Read BSE record + */ + private function _readBSE() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // add BSE to BstoreContainer + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $this->_object->addBSE($BSE); + + $BSE->setBLIPType($recInstance); + + // offset: 0; size: 1; btWin32 (MSOBLIPTYPE) + $btWin32 = ord($recordData[0]); + + // offset: 1; size: 1; btWin32 (MSOBLIPTYPE) + $btMacOS = ord($recordData[1]); + + // offset: 2; size: 16; MD4 digest + $rgbUid = substr($recordData, 2, 16); + + // offset: 18; size: 2; tag + $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18); + + // offset: 20; size: 4; size of BLIP in bytes + $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20); + + // offset: 24; size: 4; number of references to this BLIP + $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24); + + // offset: 28; size: 4; MSOFO file offset + $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28); + + // offset: 32; size: 1; unused1 + $unused1 = ord($recordData{32}); + + // offset: 33; size: 1; size of nameData in bytes (including null terminator) + $cbName = ord($recordData{33}); + + // offset: 34; size: 1; unused2 + $unused2 = ord($recordData{34}); + + // offset: 35; size: 1; unused3 + $unused3 = ord($recordData{35}); + + // offset: 36; size: $cbName; nameData + $nameData = substr($recordData, 36, $cbName); + + // offset: 36 + $cbName, size: var; the BLIP data + $blipData = substr($recordData, 36 + $cbName); + + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($BSE); + $reader->load($blipData); + } + + /** + * Read BlipJPEG record. Holds raw JPEG image data + */ + private function _readBlipJPEG() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $pos = 0; + + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; + + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if (in_array($recInstance, array(0x046B, 0x06E3))) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } + + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; + + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); + + $this->_object->setBlip($blip); + } + + /** + * Read BlipPNG record. Holds raw PNG image data + */ + private function _readBlipPNG() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $pos = 0; + + // offset: 0; size: 16; rgbUid1 (MD4 digest of) + $rgbUid1 = substr($recordData, 0, 16); + $pos += 16; + + // offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3 + if ($recInstance == 0x06E1) { + $rgbUid2 = substr($recordData, 16, 16); + $pos += 16; + } + + // offset: var; size: 1; tag + $tag = ord($recordData{$pos}); + $pos += 1; + + // offset: var; size: var; the raw image data + $data = substr($recordData, $pos); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($data); + + $this->_object->setBlip($blip); + } + + /** + * Read OPT record. This record may occur within DggContainer record or SpContainer + */ + private function _readOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + $this->_readOfficeArtRGFOPTE($recordData, $recInstance); + } + + /** + * Read TertiaryOPT record + */ + private function _readTertiaryOPT() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SplitMenuColors record + */ + private function _readSplitMenuColors() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read DgContainer record (Drawing Container) + */ + private function _readDgContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + $this->_object->setDgContainer($dgContainer); + $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Dg record (Drawing) + */ + private function _readDg() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read SpgrContainer record (Shape Group Container) + */ + private function _readSpgrContainer() + { + // context is either context DgContainer or SpgrContainer + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + + if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) { + // DgContainer + $this->_object->setSpgrContainer($spgrContainer); + } else { + // SpgrContainer + $this->_object->addChild($spgrContainer); + } + + $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer); + $escher = $reader->load($recordData); + } + + /** + * Read SpContainer record (Shape Container) + */ + private function _readSpContainer() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // add spContainer to spgrContainer + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $this->_object->addChild($spContainer); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // record is a container, read contents + $reader = new PHPExcel_Reader_Excel5_Escher($spContainer); + $escher = $reader->load($recordData); + } + + /** + * Read Spgr record (Shape Group) + */ + private function _readSpgr() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read Sp record (Shape) + */ + private function _readSp() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientTextbox record + */ + private function _readClientTextbox() + { + // offset: 0; size: 2; recVer and recInstance + + // bit: 4-15; mask: 0xFFF0; recInstance + $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4; + + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet + */ + private function _readClientAnchor() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + + // offset: 2; size: 2; upper-left corner column index (0-based) + $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2); + + // offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width + $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4); + + // offset: 6; size: 2; upper-left corner row index (0-based) + $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6); + + // offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height + $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8); + + // offset: 10; size: 2; bottom-right corner column index (0-based) + $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10); + + // offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width + $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12); + + // offset: 14; size: 2; bottom-right corner row index (0-based) + $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14); + + // offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height + $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16); + + // set the start coordinates + $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1)); + + // set the start offsetX + $this->_object->setStartOffsetX($startOffsetX); + + // set the start offsetY + $this->_object->setStartOffsetY($startOffsetY); + + // set the end coordinates + $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1)); + + // set the end offsetX + $this->_object->setEndOffsetX($endOffsetX); + + // set the end offsetY + $this->_object->setEndOffsetY($endOffsetY); + } + + /** + * Read ClientData record + */ + private function _readClientData() + { + $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4); + $recordData = substr($this->_data, $this->_pos + 8, $length); + + // move stream pointer to next record + $this->_pos += 8 + $length; + } + + /** + * Read OfficeArtRGFOPTE table of property-value pairs + * + * @param string $data Binary data + * @param int $n Number of properties + */ + private function _readOfficeArtRGFOPTE($data, $n) { + + $splicedComplexData = substr($data, 6 * $n); + + // loop through property-value pairs + for ($i = 0; $i < $n; ++$i) { + // read 6 bytes at a time + $fopte = substr($data, 6 * $i, 6); + + // offset: 0; size: 2; opid + $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0); + + // bit: 0-13; mask: 0x3FFF; opid.opid + $opidOpid = (0x3FFF & $opid) >> 0; + + // bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier + $opidFBid = (0x4000 & $opid) >> 14; + + // bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data + $opidFComplex = (0x8000 & $opid) >> 15; + + // offset: 2; size: 4; the value for this property + $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2); + + if ($opidFComplex) { + $complexData = substr($splicedComplexData, 0, $op); + $splicedComplexData = substr($splicedComplexData, $op); + + // we store string value with complex data + $value = $complexData; + } else { + // we store integer value + $value = $op; + } + + $this->_object->setOPT($opidOpid, $value); + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/Excel5/MD5.php b/extend/phpexcel/PHPExcel/Reader/Excel5/MD5.php new file mode 100755 index 0000000..946d5a0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel5/MD5.php @@ -0,0 +1,221 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_Excel5_MD5 + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_MD5 +{ + // Context + private $a; + private $b; + private $c; + private $d; + + + /** + * MD5 stream constructor + */ + public function __construct() + { + $this->reset(); + } + + + /** + * Reset the MD5 stream context + */ + public function reset() + { + $this->a = 0x67452301; + $this->b = 0xEFCDAB89; + $this->c = 0x98BADCFE; + $this->d = 0x10325476; + } + + + /** + * Get MD5 stream context + * + * @return string + */ + public function getContext() + { + $s = ''; + foreach (array('a', 'b', 'c', 'd') as $i) { + $v = $this->{$i}; + $s .= chr($v & 0xff); + $s .= chr(($v >> 8) & 0xff); + $s .= chr(($v >> 16) & 0xff); + $s .= chr(($v >> 24) & 0xff); + } + + return $s; + } + + + /** + * Add data to context + * + * @param string $data Data to add + */ + public function add($data) + { + $words = array_values(unpack('V16', $data)); + + $A = $this->a; + $B = $this->b; + $C = $this->c; + $D = $this->d; + + $F = array('PHPExcel_Reader_Excel5_MD5','F'); + $G = array('PHPExcel_Reader_Excel5_MD5','G'); + $H = array('PHPExcel_Reader_Excel5_MD5','H'); + $I = array('PHPExcel_Reader_Excel5_MD5','I'); + + /* ROUND 1 */ + self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478); + self::step($F, $D, $A, $B, $C, $words[1], 12, 0xe8c7b756); + self::step($F, $C, $D, $A, $B, $words[2], 17, 0x242070db); + self::step($F, $B, $C, $D, $A, $words[3], 22, 0xc1bdceee); + self::step($F, $A, $B, $C, $D, $words[4], 7, 0xf57c0faf); + self::step($F, $D, $A, $B, $C, $words[5], 12, 0x4787c62a); + self::step($F, $C, $D, $A, $B, $words[6], 17, 0xa8304613); + self::step($F, $B, $C, $D, $A, $words[7], 22, 0xfd469501); + self::step($F, $A, $B, $C, $D, $words[8], 7, 0x698098d8); + self::step($F, $D, $A, $B, $C, $words[9], 12, 0x8b44f7af); + self::step($F, $C, $D, $A, $B, $words[10], 17, 0xffff5bb1); + self::step($F, $B, $C, $D, $A, $words[11], 22, 0x895cd7be); + self::step($F, $A, $B, $C, $D, $words[12], 7, 0x6b901122); + self::step($F, $D, $A, $B, $C, $words[13], 12, 0xfd987193); + self::step($F, $C, $D, $A, $B, $words[14], 17, 0xa679438e); + self::step($F, $B, $C, $D, $A, $words[15], 22, 0x49b40821); + + /* ROUND 2 */ + self::step($G, $A, $B, $C, $D, $words[1], 5, 0xf61e2562); + self::step($G, $D, $A, $B, $C, $words[6], 9, 0xc040b340); + self::step($G, $C, $D, $A, $B, $words[11], 14, 0x265e5a51); + self::step($G, $B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa); + self::step($G, $A, $B, $C, $D, $words[5], 5, 0xd62f105d); + self::step($G, $D, $A, $B, $C, $words[10], 9, 0x02441453); + self::step($G, $C, $D, $A, $B, $words[15], 14, 0xd8a1e681); + self::step($G, $B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8); + self::step($G, $A, $B, $C, $D, $words[9], 5, 0x21e1cde6); + self::step($G, $D, $A, $B, $C, $words[14], 9, 0xc33707d6); + self::step($G, $C, $D, $A, $B, $words[3], 14, 0xf4d50d87); + self::step($G, $B, $C, $D, $A, $words[8], 20, 0x455a14ed); + self::step($G, $A, $B, $C, $D, $words[13], 5, 0xa9e3e905); + self::step($G, $D, $A, $B, $C, $words[2], 9, 0xfcefa3f8); + self::step($G, $C, $D, $A, $B, $words[7], 14, 0x676f02d9); + self::step($G, $B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a); + + /* ROUND 3 */ + self::step($H, $A, $B, $C, $D, $words[5], 4, 0xfffa3942); + self::step($H, $D, $A, $B, $C, $words[8], 11, 0x8771f681); + self::step($H, $C, $D, $A, $B, $words[11], 16, 0x6d9d6122); + self::step($H, $B, $C, $D, $A, $words[14], 23, 0xfde5380c); + self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44); + self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); + self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); + self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70); + self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6); + self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa); + self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085); + self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05); + self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039); + self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5); + self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); + self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665); + + /* ROUND 4 */ + self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244); + self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97); + self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7); + self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039); + self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3); + self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); + self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d); + self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1); + self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); + self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); + self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314); + self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1); + self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82); + self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235); + self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); + self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); + + $this->a = ($this->a + $A) & 0xffffffff; + $this->b = ($this->b + $B) & 0xffffffff; + $this->c = ($this->c + $C) & 0xffffffff; + $this->d = ($this->d + $D) & 0xffffffff; + } + + + private static function F($X, $Y, $Z) + { + return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z + } + + + private static function G($X, $Y, $Z) + { + return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z + } + + + private static function H($X, $Y, $Z) + { + return ($X ^ $Y ^ $Z); // X XOR Y XOR Z + } + + + private static function I($X, $Y, $Z) + { + return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z) + } + + + private static function step($func, &$A, $B, $C, $D, $M, $s, $t) + { + $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff; + $A = self::rotate($A, $s); + $A = ($B + $A) & 0xffffffff; + } + + + private static function rotate($decimal, $bits) + { + $binary = str_pad(decbin($decimal), 32, "0", STR_PAD_LEFT); + return bindec(substr($binary, $bits).substr($binary, 0, $bits)); + } +} \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Reader/Excel5/RC4.php b/extend/phpexcel/PHPExcel/Reader/Excel5/RC4.php new file mode 100755 index 0000000..dc6327c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Excel5/RC4.php @@ -0,0 +1,88 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Reader_Excel5_RC4 + * + * @category PHPExcel + * @package PHPExcel_Reader_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Excel5_RC4 +{ + // Context + var $s = array(); + var $i = 0; + var $j = 0; + + /** + * RC4 stream decryption/encryption constrcutor + * + * @param string $key Encryption key/passphrase + */ + public function __construct($key) + { + $len = strlen($key); + + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->s[$this->i] = $this->i; + } + + $this->j = 0; + for ($this->i = 0; $this->i < 256; $this->i++) { + $this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + } + $this->i = $this->j = 0; + } + + /** + * Symmetric decryption/encryption function + * + * @param string $data Data to encrypt/decrypt + * + * @return string + */ + public function RC4($data) + { + $len = strlen($data); + for ($c = 0; $c < $len; $c++) { + $this->i = ($this->i + 1) % 256; + $this->j = ($this->j + $this->s[$this->i]) % 256; + $t = $this->s[$this->i]; + $this->s[$this->i] = $this->s[$this->j]; + $this->s[$this->j] = $t; + + $t = ($this->s[$this->i] + $this->s[$this->j]) % 256; + + $data[$c] = chr(ord($data[$c]) ^ $this->s[$t]); + } + return $data; + } +} diff --git a/extend/phpexcel/PHPExcel/Reader/Exception.php b/extend/phpexcel/PHPExcel/Reader/Exception.php new file mode 100755 index 0000000..f42a1aa --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Exception.php @@ -0,0 +1,52 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_Exception + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Exception extends PHPExcel_Exception { + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/extend/phpexcel/PHPExcel/Reader/Gnumeric.php b/extend/phpexcel/PHPExcel/Reader/Gnumeric.php new file mode 100755 index 0000000..6db7c49 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/Gnumeric.php @@ -0,0 +1,873 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_Gnumeric + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + /** + * Shared Expressions + * + * @var array + */ + private $_expressions = array(); + + private $_referenceHelper = null; + + + /** + * Create a new PHPExcel_Reader_Gnumeric + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + $this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Check if gzlib functions are available + if (!function_exists('gzread')) { + throw new PHPExcel_Reader_Exception("gzlib library is not enabled"); + } + + // Read signature data (first 3 bytes) + $fh = fopen($pFilename, 'r'); + $data = fread($fh, 2); + fclose($fh); + + if ($data != chr(0x1F).chr(0x8B)) { + return false; + } + + return true; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->open( + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetNames = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $worksheetNames[] = (string) $xml->value; + } elseif ($xml->name == 'gnm:Sheets') { + // break out of the loop once we've got our sheet names rather than parse the entire file + break; + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $xml = new XMLReader(); + $xml->open( + 'compress.zlib://'.realpath($pFilename), null, PHPExcel_Settings::getLibXmlLoaderOptions() + ); + $xml->setParserProperty(2,true); + + $worksheetInfo = array(); + while ($xml->read()) { + if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) { + $tmpInfo = array( + 'worksheetName' => '', + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + while ($xml->read()) { + if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['worksheetName'] = (string) $xml->value; + } elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['lastColumnIndex'] = (int) $xml->value; + $tmpInfo['totalColumns'] = (int) $xml->value + 1; + } elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) { + $xml->read(); // Move onto the value node + $tmpInfo['totalRows'] = (int) $xml->value + 1; + break; + } + } + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + + return $worksheetInfo; + } + + + private function _gzfileGetContents($filename) { + $file = @gzopen($filename, 'rb'); + if ($file !== false) { + $data = ''; + while (!gzeof($file)) { + $data .= gzread($file, 1024); + } + gzclose($file); + } + return $data; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + $gFileData = $this->_gzfileGetContents($pFilename); + +// echo '<pre>'; +// echo htmlentities($gFileData,ENT_QUOTES,'UTF-8'); +// echo '</pre><hr />'; +// + $xml = simplexml_load_string($gFileData, 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); + +// var_dump($namespacesMeta); +// + $gnmXML = $xml->children($namespacesMeta['gnm']); + + $docProps = $objPHPExcel->getProperties(); + // Document Properties are held differently, depending on the version of Gnumeric + if (isset($namespacesMeta['office'])) { + $officeXML = $xml->children($namespacesMeta['office']); + $officeDocXML = $officeXML->{'document-meta'}; + $officeDocMetaXML = $officeDocXML->meta; + + foreach($officeDocMetaXML as $officePropertyData) { + + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'subject' : + $docProps->setSubject(trim($propertyValue)); + break; + case 'creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription(trim($propertyValue)); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['meta'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $attributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'keyword' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'initial-creator' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'creation-date' : + $creationDate = strtotime(trim($propertyValue)); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'user-defined' : + list(,$attrName) = explode(':',$attributes['name']); + switch ($attrName) { + case 'publisher' : + $docProps->setCompany(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + } + break; + } + } + } + } elseif (isset($gnmXML->Summary)) { + foreach($gnmXML->Summary->Item as $summaryItem) { + $propertyName = $summaryItem->name; + $propertyValue = $summaryItem->{'val-string'}; + switch ($propertyName) { + case 'title' : + $docProps->setTitle(trim($propertyValue)); + break; + case 'comments' : + $docProps->setDescription(trim($propertyValue)); + break; + case 'keywords' : + $docProps->setKeywords(trim($propertyValue)); + break; + case 'category' : + $docProps->setCategory(trim($propertyValue)); + break; + case 'manager' : + $docProps->setManager(trim($propertyValue)); + break; + case 'author' : + $docProps->setCreator(trim($propertyValue)); + $docProps->setLastModifiedBy(trim($propertyValue)); + break; + case 'company' : + $docProps->setCompany(trim($propertyValue)); + break; + } + } + } + + $worksheetID = 0; + foreach($gnmXML->Sheets->Sheet as $sheet) { + $worksheetName = (string) $sheet->Name; +// echo '<b>Worksheet: ',$worksheetName,'</b><br />'; + if ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) { + continue; + } + + $maxRow = $maxCol = 0; + + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula + // cells... during the load, all formulae should be correct, and we're simply bringing the worksheet + // name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + + if ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) { + if (isset($sheet->PrintInformation->Margins)) { + foreach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) { + $marginAttributes = $margin->attributes(); + $marginSize = 72 / 100; // Default + switch($marginAttributes['PrefUnit']) { + case 'mm' : + $marginSize = intval($marginAttributes['Points']) / 100; + break; + } + switch($key) { + case 'top' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize); + break; + case 'bottom' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize); + break; + case 'left' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize); + break; + case 'right' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize); + break; + case 'header' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize); + break; + case 'footer' : + $objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize); + break; + } + } + } + } + + foreach($sheet->Cells->Cell as $cell) { + $cellAttributes = $cell->attributes(); + $row = (int) $cellAttributes->Row + 1; + $column = (int) $cellAttributes->Col; + + if ($row > $maxRow) $maxRow = $row; + if ($column > $maxCol) $maxCol = $column; + + $column = PHPExcel_Cell::stringFromColumnIndex($column); + + // Read cell? + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { + continue; + } + } + + $ValueType = $cellAttributes->ValueType; + $ExprID = (string) $cellAttributes->ExprID; +// echo 'Cell ',$column,$row,'<br />'; +// echo 'Type is ',$ValueType,'<br />'; +// echo 'Value is ',$cell,'<br />'; + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + if ($ExprID > '') { + if (((string) $cell) > '') { + + $this->_expressions[$ExprID] = array( 'column' => $cellAttributes->Col, + 'row' => $cellAttributes->Row, + 'formula' => (string) $cell + ); +// echo 'NEW EXPRESSION ',$ExprID,'<br />'; + } else { + $expression = $this->_expressions[$ExprID]; + + $cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'], + 'A1', + $cellAttributes->Col - $expression['column'], + $cellAttributes->Row - $expression['row'], + $worksheetName + ); +// echo 'SHARED EXPRESSION ',$ExprID,'<br />'; +// echo 'New Value is ',$cell,'<br />'; + } + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; + } else { + switch($ValueType) { + case '10' : // NULL + $type = PHPExcel_Cell_DataType::TYPE_NULL; + break; + case '20' : // Boolean + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $cell = ($cell == 'TRUE') ? True : False; + break; + case '30' : // Integer + $cell = intval($cell); + case '40' : // Float + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + break; + case '50' : // Error + $type = PHPExcel_Cell_DataType::TYPE_ERROR; + break; + case '60' : // String + $type = PHPExcel_Cell_DataType::TYPE_STRING; + break; + case '70' : // Cell Range + case '80' : // Array + } + } + $objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type); + } + + if ((!$this->_readDataOnly) && (isset($sheet->Objects))) { + foreach($sheet->Objects->children('gnm',TRUE) as $key => $comment) { + $commentAttributes = $comment->attributes(); + // Only comment objects are handled at the moment + if ($commentAttributes->Text) { + $objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound ) + ->setAuthor( (string)$commentAttributes->Author ) + ->setText($this->_parseRichText((string)$commentAttributes->Text) ); + } + } + } +// echo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />'; +// + foreach($sheet->Styles->StyleRegion as $styleRegion) { + $styleAttributes = $styleRegion->attributes(); + if (($styleAttributes['startRow'] <= $maxRow) && + ($styleAttributes['startCol'] <= $maxCol)) { + + $startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']); + $startRow = $styleAttributes['startRow'] + 1; + + $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; + $endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn); + $endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow']; + $endRow += 1; + $cellRange = $startColumn.$startRow.':'.$endColumn.$endRow; +// echo $cellRange,'<br />'; + + $styleAttributes = $styleRegion->Style->attributes(); +// var_dump($styleAttributes); +// echo '<br />'; + + // We still set the number format mask for date/time values, even if _readDataOnly is true + if ((!$this->_readDataOnly) || + (PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) { + $styleArray = array(); + $styleArray['numberformat']['code'] = (string) $styleAttributes['Format']; + // If _readDataOnly is false, we set all formatting information + if (!$this->_readDataOnly) { + switch($styleAttributes['HAlign']) { + case '1' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + break; + case '2' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT; + break; + case '4' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT; + break; + case '8' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER; + break; + case '16' : + case '64' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS; + break; + case '32' : + $styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY; + break; + } + + switch($styleAttributes['VAlign']) { + case '1' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP; + break; + case '2' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + break; + case '4' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER; + break; + case '8' : + $styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY; + break; + } + + $styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False; + $styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False; + $styleArray['alignment']['indent'] = (intval($styleAttributes["Indent"]) > 0) ? $styleAttributes["indent"] : 0; + + $RGB = self::_parseGnumericColour($styleAttributes["Fore"]); + $styleArray['font']['color']['rgb'] = $RGB; + $RGB = self::_parseGnumericColour($styleAttributes["Back"]); + $shade = $styleAttributes["Shade"]; + if (($RGB != '000000') || ($shade != '0')) { + $styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB; + $RGB2 = self::_parseGnumericColour($styleAttributes["PatternColor"]); + $styleArray['fill']['endcolor']['rgb'] = $RGB2; + switch($shade) { + case '1' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID; + break; + case '2' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR; + break; + case '3' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH; + break; + case '4' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN; + break; + case '5' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY; + break; + case '6' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID; + break; + case '7' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL; + break; + case '8' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS; + break; + case '9' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP; + break; + case '10' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL; + break; + case '11' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625; + break; + case '12' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125; + break; + case '13' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN; + break; + case '14' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY; + break; + case '15' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID; + break; + case '16' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL; + break; + case '17' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS; + break; + case '18' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP; + break; + case '19' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL; + break; + case '20' : + $styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY; + break; + } + } + + $fontAttributes = $styleRegion->Style->Font->attributes(); +// var_dump($fontAttributes); +// echo '<br />'; + $styleArray['font']['name'] = (string) $styleRegion->Style->Font; + $styleArray['font']['size'] = intval($fontAttributes['Unit']); + $styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False; + $styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False; + $styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False; + switch($fontAttributes['Underline']) { + case '1' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE; + break; + case '2' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE; + break; + case '3' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING; + break; + case '4' : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING; + break; + default : + $styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE; + break; + } + switch($fontAttributes['Script']) { + case '1' : + $styleArray['font']['superScript'] = True; + break; + case '-1' : + $styleArray['font']['subScript'] = True; + break; + } + + if (isset($styleRegion->Style->StyleBorder)) { + if (isset($styleRegion->Style->StyleBorder->Top)) { + $styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Bottom)) { + $styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Left)) { + $styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes()); + } + if (isset($styleRegion->Style->StyleBorder->Right)) { + $styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes()); + } + if ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH; + } elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP; + } elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) { + $styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes()); + $styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN; + } + } + if (isset($styleRegion->Style->HyperLink)) { + // TO DO + $hyperlink = $styleRegion->Style->HyperLink->attributes(); + } + } +// var_dump($styleArray); +// echo '<br />'; + $objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); + } + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Cols))) { + // Column Widths + $columnAttributes = $sheet->Cols->attributes(); + $defaultWidth = $columnAttributes['DefaultSizePts'] / 5.4; + $c = 0; + foreach($sheet->Cols->ColInfo as $columnOverride) { + $columnAttributes = $columnOverride->attributes(); + $column = $columnAttributes['No']; + $columnWidth = $columnAttributes['Unit'] / 5.4; + $hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false; + $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1; + while ($c < $column) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + while (($c < ($column+$columnCount)) && ($c <= $maxCol)) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false); + } + ++$c; + } + } + while ($c <= $maxCol) { + $objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth); + ++$c; + } + } + + if ((!$this->_readDataOnly) && (isset($sheet->Rows))) { + // Row Heights + $rowAttributes = $sheet->Rows->attributes(); + $defaultHeight = $rowAttributes['DefaultSizePts']; + $r = 0; + + foreach($sheet->Rows->RowInfo as $rowOverride) { + $rowAttributes = $rowOverride->attributes(); + $row = $rowAttributes['No']; + $rowHeight = $rowAttributes['Unit']; + $hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false; + $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1; + while ($r < $row) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + while (($r < ($row+$rowCount)) && ($r < $maxRow)) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight); + if ($hidden) { + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false); + } + } + } + while ($r < $maxRow) { + ++$r; + $objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight); + } + } + + // Handle Merged Cells in this worksheet + if (isset($sheet->MergedRegions)) { + foreach($sheet->MergedRegions->Merge as $mergeCells) { + if (strpos($mergeCells,':') !== FALSE) { + $objPHPExcel->getActiveSheet()->mergeCells($mergeCells); + } + } + } + + $worksheetID++; + } + + // Loop through definedNames (global named ranges) + if (isset($gnmXML->Names)) { + foreach($gnmXML->Names->Name as $namedRange) { + $name = (string) $namedRange->name; + $range = (string) $namedRange->value; + if (stripos($range, '#REF!') !== false) { + continue; + } + + $range = explode('!',$range); + $range[0] = trim($range[0],"'");; + if ($worksheet = $objPHPExcel->getSheetByName($range[0])) { + $extractedRange = str_replace('$', '', $range[1]); + $objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) ); + } + } + } + + + // Return + return $objPHPExcel; + } + + + private static function _parseBorderAttributes($borderAttributes) + { + $styleArray = array(); + + if (isset($borderAttributes["Color"])) { + $RGB = self::_parseGnumericColour($borderAttributes["Color"]); + $styleArray['color']['rgb'] = $RGB; + } + + switch ($borderAttributes["Style"]) { + case '0' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE; + break; + case '1' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case '2' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM; + break; + case '4' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED; + break; + case '5' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK; + break; + case '6' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE; + break; + case '7' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED; + break; + case '9' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT; + break; + case '10' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT; + break; + case '11' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT; + break; + case '12' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '13' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT; + break; + case '3' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT; + break; + case '8' : + $styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED; + break; + } + return $styleArray; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + + + private static function _parseGnumericColour($gnmColour) { + list($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour); + $gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2); + $gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2); + $gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2); + $RGB = $gnmR.$gnmG.$gnmB; +// echo 'Excel Colour: ',$RGB,'<br />'; + return $RGB; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/HTML.php b/extend/phpexcel/PHPExcel/Reader/HTML.php new file mode 100755 index 0000000..1696471 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/HTML.php @@ -0,0 +1,468 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_HTML + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Input encoding + * + * @var string + */ + private $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + private $_formats = array( 'h1' => array( 'font' => array( 'bold' => true, + 'size' => 24, + ), + ), // Bold, 24pt + 'h2' => array( 'font' => array( 'bold' => true, + 'size' => 18, + ), + ), // Bold, 18pt + 'h3' => array( 'font' => array( 'bold' => true, + 'size' => 13.5, + ), + ), // Bold, 13.5pt + 'h4' => array( 'font' => array( 'bold' => true, + 'size' => 12, + ), + ), // Bold, 12pt + 'h5' => array( 'font' => array( 'bold' => true, + 'size' => 10, + ), + ), // Bold, 10pt + 'h6' => array( 'font' => array( 'bold' => true, + 'size' => 7.5, + ), + ), // Bold, 7.5pt + 'a' => array( 'font' => array( 'underline' => true, + 'color' => array( 'argb' => PHPExcel_Style_Color::COLOR_BLUE, + ), + ), + ), // Blue underlined + 'hr' => array( 'borders' => array( 'bottom' => array( 'style' => PHPExcel_Style_Border::BORDER_THIN, + 'color' => array( PHPExcel_Style_Color::COLOR_BLACK, + ), + ), + ), + ), // Bottom border + ); + + + /** + * Create a new PHPExcel_Reader_HTML + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is an HTML file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Reading 2048 bytes should be enough to validate that the format is HTML + $data = fread($this->_fileHandle, 2048); + if ((strpos($data, '<') !== FALSE) && + (strlen($data) !== strlen(strip_tags($data)))) { + return TRUE; + } + + return FALSE; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + // Data Array used for testing only, should write to PHPExcel object on completion of tests + private $_dataArray = array(); + + private $_tableLevel = 0; + private $_nestedColumn = array('A'); + + private function _setTableStartColumn($column) { + if ($this->_tableLevel == 0) + $column = 'A'; + ++$this->_tableLevel; + $this->_nestedColumn[$this->_tableLevel] = $column; + + return $this->_nestedColumn[$this->_tableLevel]; + } + + private function _getTableStartColumn() { + return $this->_nestedColumn[$this->_tableLevel]; + } + + private function _releaseTableStartColumn() { + --$this->_tableLevel; + return array_pop($this->_nestedColumn); + } + + private function _flushCell($sheet,$column,$row,&$cellContent) { + if (is_string($cellContent)) { + // Simple String content + if (trim($cellContent) > '') { + // Only actually write it if there's content in the string +// echo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '<br />'; + // Write to worksheet to be done here... + // ... we return the cell so we can mess about with styles more easily + $cell = $sheet->setCellValue($column.$row,$cellContent,true); + $this->_dataArray[$row][$column] = $cellContent; + } + } else { + // We have a Rich Text run + // TODO + $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent; + } + $cellContent = (string) ''; + } + + private function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent){ + foreach($element->childNodes as $child){ + if ($child instanceof DOMText) { + $domText = preg_replace('/\s+/',' ',trim($child->nodeValue)); + if (is_string($cellContent)) { + // simply append the text if the cell content is a plain text string + $cellContent .= $domText; + } else { + // but if we have a rich text run instead, we need to append it correctly + // TODO + } + } elseif($child instanceof DOMElement) { +// echo '<b>DOM ELEMENT: </b>' , strtoupper($child->nodeName) , '<br />'; + + $attributeArray = array(); + foreach($child->attributes as $attribute) { +// echo '<b>ATTRIBUTE: </b>' , $attribute->name , ' => ' , $attribute->value , '<br />'; + $attributeArray[$attribute->name] = $attribute->value; + } + + switch($child->nodeName) { + case 'meta' : + foreach($attributeArray as $attributeName => $attributeValue) { + switch($attributeName) { + case 'content': + // TODO + // Extract character set, so we can convert to UTF-8 if required + break; + } + } + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + case 'title' : + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + $sheet->setTitle($cellContent); + $cellContent = ''; + break; + case 'span' : + case 'div' : + case 'font' : + case 'i' : + case 'em' : + case 'strong': + case 'b' : +// echo 'STYLING, SPAN OR DIV<br />'; + if ($cellContent > '') + $cellContent .= ' '; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + if ($cellContent > '') + $cellContent .= ' '; +// echo 'END OF STYLING, SPAN OR DIV<br />'; + break; + case 'hr' : + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$row; + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } else { + $cellContent = '----------'; + $this->_flushCell($sheet,$column,$row,$cellContent); + } + ++$row; + case 'br' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; + } else { + // Otherwise flush our existing content and move the row cursor on + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$row; + } +// echo 'HARD LINE BREAK: ' , '<br />'; + break; + case 'a' : +// echo 'START OF HYPERLINK: ' , '<br />'; + foreach($attributeArray as $attributeName => $attributeValue) { + switch($attributeName) { + case 'href': +// echo 'Link to ' , $attributeValue , '<br />'; + $sheet->getCell($column.$row)->getHyperlink()->setUrl($attributeValue); + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } + break; + } + } + $cellContent .= ' '; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF HYPERLINK:' , '<br />'; + break; + case 'h1' : + case 'h2' : + case 'h3' : + case 'h4' : + case 'h5' : + case 'h6' : + case 'ol' : + case 'ul' : + case 'p' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + } else { + if ($cellContent > '') { + $this->_flushCell($sheet,$column,$row,$cellContent); + $row += 2; + } +// echo 'START OF PARAGRAPH: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF PARAGRAPH:' , '<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + + if (isset($this->_formats[$child->nodeName])) { + $sheet->getStyle($column.$row)->applyFromArray($this->_formats[$child->nodeName]); + } + + $row += 2; + $column = 'A'; + } + break; + case 'li' : + if ($this->_tableLevel > 0) { + // If we're inside a table, replace with a \n + $cellContent .= "\n"; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + } else { + if ($cellContent > '') { + $this->_flushCell($sheet,$column,$row,$cellContent); + } + ++$row; +// echo 'LIST ENTRY: ' , '<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF LIST ENTRY:' , '<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + $column = 'A'; + } + break; + case 'table' : + $this->_flushCell($sheet,$column,$row,$cellContent); + $column = $this->_setTableStartColumn($column); +// echo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; + if ($this->_tableLevel > 1) + --$row; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />'; + $column = $this->_releaseTableStartColumn(); + if ($this->_tableLevel > 1) { + ++$column; + } else { + ++$row; + } + break; + case 'thead' : + case 'tbody' : + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + case 'tr' : + ++$row; + $column = $this->_getTableStartColumn(); + $cellContent = ''; +// echo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />'; + break; + case 'th' : + case 'td' : +// echo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />'; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); +// echo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />'; + $this->_flushCell($sheet,$column,$row,$cellContent); + ++$column; + break; + case 'body' : + $row = 1; + $column = 'A'; + $content = ''; + $this->_tableLevel = 0; + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + break; + default: + $this->_processDomElement($child,$sheet,$row,$column,$cellContent); + } + } + } + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file to validate + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid HTML file."); + } + // Close after validating + fclose ($this->_fileHandle); + + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + + // Create a new DOM object + $dom = new domDocument; + // Reload the HTML file into the DOM object + $loaded = $dom->loadHTMLFile($pFilename, PHPExcel_Settings::getLibXmlLoaderOptions()); + if ($loaded === FALSE) { + throw new PHPExcel_Reader_Exception('Failed to load ',$pFilename,' as a DOM Document'); + } + + // Discard white space + $dom->preserveWhiteSpace = false; + + + $row = 0; + $column = 'A'; + $content = ''; + $this->_processDomElement($dom,$objPHPExcel->getActiveSheet(),$row,$column,$content); + +// echo '<hr />'; +// var_dump($this->_dataArray); + + // Return + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_HTML + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/IReadFilter.php b/extend/phpexcel/PHPExcel/Reader/IReadFilter.php new file mode 100755 index 0000000..5a691a5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/IReadFilter.php @@ -0,0 +1,47 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_IReadFilter + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Reader_IReadFilter +{ + /** + * Should this cell be read? + * + * @param $column String column index + * @param $row Row index + * @param $worksheetName Optional worksheet name + * @return boolean + */ + public function readCell($column, $row, $worksheetName = ''); +} diff --git a/extend/phpexcel/PHPExcel/Reader/IReader.php b/extend/phpexcel/PHPExcel/Reader/IReader.php new file mode 100755 index 0000000..6c3e878 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/IReader.php @@ -0,0 +1,53 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Reader_IReader + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Reader_IReader +{ + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + */ + public function canRead($pFilename); + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename); +} diff --git a/extend/phpexcel/PHPExcel/Reader/OOCalc.php b/extend/phpexcel/PHPExcel/Reader/OOCalc.php new file mode 100755 index 0000000..8ad7061 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/OOCalc.php @@ -0,0 +1,707 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_OOCalc + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Formats + * + * @var array + */ + private $_styles = array(); + + + /** + * Create a new PHPExcel_Reader_OOCalc + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + + /** + * Can the current PHPExcel_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPExcel_Reader_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + // Check if zip class exists +// if (!class_exists($zipClass, FALSE)) { +// throw new PHPExcel_Reader_Exception($zipClass . " library is not enabled"); +// } + + $mimeType = 'UNKNOWN'; + // Load file + $zip = new $zipClass; + if ($zip->open($pFilename) === true) { + // check if it is an OOXML archive + $stat = $zip->statName('mimetype'); + if ($stat && ($stat['size'] <= 255)) { + $mimeType = $zip->getFromName($stat['name']); + } elseif($stat = $zip->statName('META-INF/manifest.xml')) { + $xml = simplexml_load_string($zip->getFromName('META-INF/manifest.xml'), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); + if (isset($namespacesContent['manifest'])) { + $manifest = $xml->children($namespacesContent['manifest']); + foreach($manifest as $manifestDataSet) { + $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']); + if ($manifestAttributes->{'full-path'} == '/') { + $mimeType = (string) $manifestAttributes->{'media-type'}; + break; + } + } + } + } + + $zip->close(); + + return ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet'); + } + + return FALSE; + } + + + /** + * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetNames($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $worksheetNames = array(); + + $xml = new XMLReader(); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + // Loop through each table:table node reading the table:name attribute for each worksheet name + do { + $worksheetNames[] = $xml->getAttribute('table:name'); + $xml->next(); + } while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT); + } + } + } + + return $worksheetNames; + } + + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $worksheetInfo = array(); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + + $xml = new XMLReader(); + $res = $xml->open('zip://'.realpath($pFilename).'#content.xml', null, PHPExcel_Settings::getLibXmlLoaderOptions()); + $xml->setParserProperty(2,true); + + // Step into the first level of content of the XML + $xml->read(); + while ($xml->read()) { + // Quickly jump through to the office:body node + while ($xml->name !== 'office:body') { + if ($xml->isEmptyElement) + $xml->read(); + else + $xml->next(); + } + // Now read each node until we find our first table:table node + while ($xml->read()) { + if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) { + $worksheetNames[] = $xml->getAttribute('table:name'); + + $tmpInfo = array( + 'worksheetName' => $xml->getAttribute('table:name'), + 'lastColumnLetter' => 'A', + 'lastColumnIndex' => 0, + 'totalRows' => 0, + 'totalColumns' => 0, + ); + + // Loop through each child node of the table:table element reading + $currCells = 0; + do { + $xml->read(); + if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) { + $rowspan = $xml->getAttribute('table:number-rows-repeated'); + $rowspan = empty($rowspan) ? 1 : $rowspan; + $tmpInfo['totalRows'] += $rowspan; + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $currCells = 0; + // Step into the row + $xml->read(); + do { + if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + if (!$xml->isEmptyElement) { + $currCells++; + $xml->next(); + } else { + $xml->read(); + } + } elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) { + $mergeSize = $xml->getAttribute('table:number-columns-repeated'); + $currCells += $mergeSize; + $xml->read(); + } + } while ($xml->name != 'table:table-row'); + } + } while ($xml->name != 'table:table'); + + $tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells); + $tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1; + $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); + $worksheetInfo[] = $tmpInfo; + } + } + +// foreach($workbookData->table as $worksheetDataSet) { +// $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); +// +// $rowIndex = 0; +// foreach ($worksheetData as $key => $rowData) { +// switch ($key) { +// case 'table-row' : +// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); +// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? +// $rowDataTableAttributes['number-rows-repeated'] : 1; +// $columnIndex = 0; +// +// foreach ($rowData as $key => $cellData) { +// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); +// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? +// $cellDataTableAttributes['number-columns-repeated'] : 1; +// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); +// if (isset($cellDataOfficeAttributes['value-type'])) { +// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1); +// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats); +// } +// $columnIndex += $colRepeats; +// } +// $rowIndex += $rowRepeats; +// break; +// } +// } +// +// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']); +// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1; +// +// } +// } + } + + return $worksheetInfo; + } + + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + + private static function identifyFixedStyleValue($styleList,&$styleAttributeValue) { + $styleAttributeValue = strtolower($styleAttributeValue); + foreach($styleList as $style) { + if ($styleAttributeValue == strtolower($style)) { + $styleAttributeValue = $style; + return true; + } + } + return false; + } + + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Check if file exists + if (!file_exists($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + $timezoneObj = new DateTimeZone('Europe/London'); + $GMT = new DateTimeZone('UTC'); + + $zipClass = PHPExcel_Settings::getZipClass(); + + $zip = new $zipClass; + if (!$zip->open($pFilename)) { + throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file."); + } + +// echo '<h1>Meta Information</h1>'; + $xml = simplexml_load_string($zip->getFromName("meta.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesMeta = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesMeta); +// echo '</pre><hr />'; + + $docProps = $objPHPExcel->getProperties(); + $officeProperty = $xml->children($namespacesMeta['office']); + foreach($officeProperty as $officePropertyData) { + $officePropertyDC = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']); + } + foreach($officePropertyDC as $propertyName => $propertyValue) { + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'title' : + $docProps->setTitle($propertyValue); + break; + case 'subject' : + $docProps->setSubject($propertyValue); + break; + case 'creator' : + $docProps->setCreator($propertyValue); + $docProps->setLastModifiedBy($propertyValue); + break; + case 'date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + $docProps->setModified($creationDate); + break; + case 'description' : + $docProps->setDescription($propertyValue); + break; + } + } + $officePropertyMeta = array(); + if (isset($namespacesMeta['dc'])) { + $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']); + } + foreach($officePropertyMeta as $propertyName => $propertyValue) { + $propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']); + $propertyValue = (string) $propertyValue; + switch ($propertyName) { + case 'initial-creator' : + $docProps->setCreator($propertyValue); + break; + case 'keyword' : + $docProps->setKeywords($propertyValue); + break; + case 'creation-date' : + $creationDate = strtotime($propertyValue); + $docProps->setCreated($creationDate); + break; + case 'user-defined' : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + foreach ($propertyValueAttributes as $key => $value) { + if ($key == 'name') { + $propertyValueName = (string) $value; + } elseif($key == 'value-type') { + switch ($value) { + case 'date' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE; + break; + case 'boolean' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN; + break; + case 'float' : + $propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4'); + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT; + break; + default : + $propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING; + } + } + } + $docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType); + break; + } + } + } + + +// echo '<h1>Workbook Content</h1>'; + $xml = simplexml_load_string($zip->getFromName("content.xml"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); + $namespacesContent = $xml->getNamespaces(true); +// echo '<pre>'; +// print_r($namespacesContent); +// echo '</pre><hr />'; + + $workbook = $xml->children($namespacesContent['office']); + foreach($workbook->body->spreadsheet as $workbookData) { + $workbookData = $workbookData->children($namespacesContent['table']); + $worksheetID = 0; + foreach($workbookData->table as $worksheetDataSet) { + $worksheetData = $worksheetDataSet->children($namespacesContent['table']); +// print_r($worksheetData); +// echo '<br />'; + $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']); +// print_r($worksheetDataAttributes); +// echo '<br />'; + if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) && + (!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) { + continue; + } + +// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>'; + // Create new Worksheet + $objPHPExcel->createSheet(); + $objPHPExcel->setActiveSheetIndex($worksheetID); + if (isset($worksheetDataAttributes['name'])) { + $worksheetName = (string) $worksheetDataAttributes['name']; + // Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in + // formula cells... during the load, all formulae should be correct, and we're simply + // bringing the worksheet name in line with the formula, not the reverse + $objPHPExcel->getActiveSheet()->setTitle($worksheetName,false); + } + + $rowID = 1; + foreach($worksheetData as $key => $rowData) { +// echo '<b>'.$key.'</b><br />'; + switch ($key) { + case 'table-header-rows': + foreach ($rowData as $key=>$cellData) { + $rowData = $cellData; + break; + } + case 'table-row' : + $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']); + $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ? + $rowDataTableAttributes['number-rows-repeated'] : 1; + $columnID = 'A'; + foreach($rowData as $key => $cellData) { + if ($this->getReadFilter() !== NULL) { + if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) { + continue; + } + } + +// echo '<b>'.$columnID.$rowID.'</b><br />'; + $cellDataText = (isset($namespacesContent['text'])) ? + $cellData->children($namespacesContent['text']) : + ''; + $cellDataOffice = $cellData->children($namespacesContent['office']); + $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']); + $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']); + +// echo 'Office Attributes: '; +// print_r($cellDataOfficeAttributes); +// echo '<br />Table Attributes: '; +// print_r($cellDataTableAttributes); +// echo '<br />Cell Data Text'; +// print_r($cellDataText); +// echo '<br />'; +// + $type = $formatting = $hyperlink = null; + $hasCalculatedValue = false; + $cellDataFormula = ''; + if (isset($cellDataTableAttributes['formula'])) { + $cellDataFormula = $cellDataTableAttributes['formula']; + $hasCalculatedValue = true; + } + + if (isset($cellDataOffice->annotation)) { +// echo 'Cell has comment<br />'; + $annotationText = $cellDataOffice->annotation->children($namespacesContent['text']); + $textArray = array(); + foreach($annotationText as $t) { + foreach($t->span as $text) { + $textArray[] = (string)$text; + } + } + $text = implode("\n",$textArray); +// echo $text,'<br />'; + $objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID ) +// ->setAuthor( $author ) + ->setText($this->_parseRichText($text) ); + } + + if (isset($cellDataText->p)) { + // Consolidate if there are multiple p records (maybe with spans as well) + $dataArray = array(); + // Text can have multiple text:p and within those, multiple text:span. + // text:p newlines, but text:span does not. + // Also, here we assume there is no text data is span fields are specified, since + // we have no way of knowing proper positioning anyway. + foreach ($cellDataText->p as $pData) { + if (isset($pData->span)) { + // span sections do not newline, so we just create one large string here + $spanSection = ""; + foreach ($pData->span as $spanData) { + $spanSection .= $spanData; + } + array_push($dataArray, $spanSection); + } else { + array_push($dataArray, $pData); + } + } + $allCellDataText = implode($dataArray, "\n"); + +// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />'; + switch ($cellDataOfficeAttributes['value-type']) { + case 'string' : + $type = PHPExcel_Cell_DataType::TYPE_STRING; + $dataValue = $allCellDataText; + if (isset($dataValue->a)) { + $dataValue = $dataValue->a; + $cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']); + $hyperlink = $cellXLinkAttributes['href']; + } + break; + case 'boolean' : + $type = PHPExcel_Cell_DataType::TYPE_BOOL; + $dataValue = ($allCellDataText == 'TRUE') ? True : False; + break; + case 'percentage' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00; + break; + case 'currency' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + $dataValue = (integer) $dataValue; + } + $formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE; + break; + case 'float' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = (float) $cellDataOfficeAttributes['value']; + if (floor($dataValue) == $dataValue) { + if ($dataValue == (integer) $dataValue) + $dataValue = (integer) $dataValue; + else + $dataValue = (float) $dataValue; + } + break; + case 'date' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT); + $dateObj->setTimeZone($timezoneObj); + list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s')); + $dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second); + if ($dataValue != floor($dataValue)) { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + } else { + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15; + } + break; + case 'time' : + $type = PHPExcel_Cell_DataType::TYPE_NUMERIC; + $dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS')))); + $formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4; + break; + } +// echo 'Data value is '.$dataValue.'<br />'; +// if ($hyperlink !== NULL) { +// echo 'Hyperlink is '.$hyperlink.'<br />'; +// } + } else { + $type = PHPExcel_Cell_DataType::TYPE_NULL; + $dataValue = NULL; + } + + if ($hasCalculatedValue) { + $type = PHPExcel_Cell_DataType::TYPE_FORMULA; +// echo 'Formula: ', $cellDataFormula, PHP_EOL; + $cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1); + $temp = explode('"',$cellDataFormula); + $tKey = false; + foreach($temp as &$value) { + // Only replace in alternate array entries (i.e. non-quoted blocks) + if ($tKey = !$tKey) { + $value = preg_replace('/\[([^\.]+)\.([^\.]+):\.([^\.]+)\]/Ui','$1!$2:$3',$value); // Cell range reference in another sheet + $value = preg_replace('/\[([^\.]+)\.([^\.]+)\]/Ui','$1!$2',$value); // Cell reference in another sheet + $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/Ui','$1:$2',$value); // Cell range reference + $value = preg_replace('/\[\.([^\.]+)\]/Ui','$1',$value); // Simple cell reference + $value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces); + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); +// echo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL; + } + + $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ? + $cellDataTableAttributes['number-columns-repeated'] : 1; + if ($type !== NULL) { + for ($i = 0; $i < $colRepeats; ++$i) { + if ($i > 0) { + ++$columnID; + } + if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) { + for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) { + $rID = $rowID + $rowAdjust; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type); + if ($hasCalculatedValue) { +// echo 'Forumla result is '.$dataValue.'<br />'; + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue); + } + if ($formatting !== NULL) { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting); + } else { + $objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL); + } + if ($hyperlink !== NULL) { + $objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink); + } + } + } + } + } + + // Merged cells + if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) { + if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) { + $columnTo = $columnID; + if (isset($cellDataTableAttributes['number-columns-spanned'])) { + $columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2); + } + $rowTo = $rowID; + if (isset($cellDataTableAttributes['number-rows-spanned'])) { + $rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1; + } + $cellRange = $columnID.$rowID.':'.$columnTo.$rowTo; + $objPHPExcel->getActiveSheet()->mergeCells($cellRange); + } + } + + ++$columnID; + } + $rowID += $rowRepeats; + break; + } + } + ++$worksheetID; + } + } + + // Return + return $objPHPExcel; + } + + + private function _parseRichText($is = '') { + $value = new PHPExcel_RichText(); + + $value->createText($is); + + return $value; + } + +} diff --git a/extend/phpexcel/PHPExcel/Reader/SYLK.php b/extend/phpexcel/PHPExcel/Reader/SYLK.php new file mode 100755 index 0000000..cd87ce5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Reader/SYLK.php @@ -0,0 +1,450 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + +/** + * PHPExcel_Reader_SYLK + * + * @category PHPExcel + * @package PHPExcel_Reader + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader +{ + /** + * Input encoding + * + * @var string + */ + private $_inputEncoding = 'ANSI'; + + /** + * Sheet index to read + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Formats + * + * @var array + */ + private $_formats = array(); + + /** + * Format Count + * + * @var int + */ + private $_format = 0; + + /** + * Create a new PHPExcel_Reader_SYLK + */ + public function __construct() { + $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter(); + } + + /** + * Validate that the current file is a SYLK file + * + * @return boolean + */ + protected function _isValidFormat() + { + // Read sample data (first 2 KB will do) + $data = fread($this->_fileHandle, 2048); + + // Count delimiters in file + $delimiterCount = substr_count($data, ';'); + if ($delimiterCount < 1) { + return FALSE; + } + + // Analyze first line looking for ID; signature + $lines = explode("\n", $data); + if (substr($lines[0],0,4) != 'ID;P') { + return FALSE; + } + + return TRUE; + } + + /** + * Set input encoding + * + * @param string $pValue Input encoding + */ + public function setInputEncoding($pValue = 'ANSI') + { + $this->_inputEncoding = $pValue; + return $this; + } + + /** + * Get input encoding + * + * @return string + */ + public function getInputEncoding() + { + return $this->_inputEncoding; + } + + /** + * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns) + * + * @param string $pFilename + * @throws PHPExcel_Reader_Exception + */ + public function listWorksheetInfo($pFilename) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + $worksheetInfo = array(); + $worksheetInfo[0]['worksheetName'] = 'Worksheet'; + $worksheetInfo[0]['lastColumnLetter'] = 'A'; + $worksheetInfo[0]['lastColumnIndex'] = 0; + $worksheetInfo[0]['totalRows'] = 0; + $worksheetInfo[0]['totalColumns'] = 0; + + // Loop through file + $rowData = array(); + + // loop through one row (line) at a time in the file + $rowIndex = 0; + while (($rowData = fgets($fileHandle)) !== FALSE) { + $columnIndex = 0; + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + if ($dataType == 'C') { + // Read cell value data + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : + $columnIndex = substr($rowDatum,1) - 1; + break; + case 'R' : + case 'Y' : + $rowIndex = substr($rowDatum,1); + break; + } + + $worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex); + $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex); + } + } + } + + $worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']); + $worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1; + + // Close file + fclose($fileHandle); + + return $worksheetInfo; + } + + /** + * Loads PHPExcel from file + * + * @param string $pFilename + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function load($pFilename) + { + // Create new PHPExcel + $objPHPExcel = new PHPExcel(); + + // Load into this instance + return $this->loadIntoExisting($pFilename, $objPHPExcel); + } + + /** + * Loads PHPExcel from file into PHPExcel instance + * + * @param string $pFilename + * @param PHPExcel $objPHPExcel + * @return PHPExcel + * @throws PHPExcel_Reader_Exception + */ + public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel) + { + // Open file + $this->_openFile($pFilename); + if (!$this->_isValidFormat()) { + fclose ($this->_fileHandle); + throw new PHPExcel_Reader_Exception($pFilename . " is an Invalid Spreadsheet file."); + } + $fileHandle = $this->_fileHandle; + rewind($fileHandle); + + // Create new PHPExcel + while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) { + $objPHPExcel->createSheet(); + } + $objPHPExcel->setActiveSheetIndex( $this->_sheetIndex ); + + $fromFormats = array('\-', '\ '); + $toFormats = array('-', ' '); + + // Loop through file + $rowData = array(); + $column = $row = ''; + + // loop through one row (line) at a time in the file + while (($rowData = fgets($fileHandle)) !== FALSE) { + + // convert SYLK encoded $rowData to UTF-8 + $rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData); + + // explode each row at semicolons while taking into account that literal semicolon (;) + // is escaped like this (;;) + $rowData = explode("\t",str_replace('¤',';',str_replace(';',"\t",str_replace(';;','¤',rtrim($rowData))))); + + $dataType = array_shift($rowData); + // Read shared styles + if ($dataType == 'P') { + $formatArray = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'P' : $formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1)); + break; + case 'E' : + case 'F' : $formatArray['font']['name'] = substr($rowDatum,1); + break; + case 'L' : $formatArray['font']['size'] = substr($rowDatum,1); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $formatArray['font']['italic'] = true; + break; + case 'D' : $formatArray['font']['bold'] = true; + break; + case 'T' : $formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + $this->_formats['P'.$this->_format++] = $formatArray; + // Read cell value data + } elseif ($dataType == 'C') { + $hasCalculatedValue = false; + $cellData = $cellDataFormula = ''; + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'K' : $cellData = substr($rowDatum,1); + break; + case 'E' : $cellDataFormula = '='.substr($rowDatum,1); + // Convert R1C1 style references to A1 style references (but only when not quoted) + $temp = explode('"',$cellDataFormula); + $key = false; + foreach($temp as &$value) { + // Only count/replace in alternate array entries + if ($key = !$key) { + preg_match_all('/(R(\[?-?\d*\]?))(C(\[?-?\d*\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE); + // Reverse the matches array, otherwise all our offsets will become incorrect if we modify our way + // through the formula from left to right. Reversing means that we work right to left.through + // the formula + $cellReferences = array_reverse($cellReferences); + // Loop through each R1C1 style reference in turn, converting it to its A1 style equivalent, + // then modify the formula to use that new reference + foreach($cellReferences as $cellReference) { + $rowReference = $cellReference[2][0]; + // Empty R reference is the current row + if ($rowReference == '') $rowReference = $row; + // Bracketed R references are relative to the current row + if ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]'); + $columnReference = $cellReference[4][0]; + // Empty C reference is the current column + if ($columnReference == '') $columnReference = $column; + // Bracketed C references are relative to the current column + if ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]'); + $A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference; + + $value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0])); + } + } + } + unset($value); + // Then rebuild the formula string + $cellDataFormula = implode('"',$temp); + $hasCalculatedValue = true; + break; + } + } + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + + // Set cell value + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData); + if ($hasCalculatedValue) { + $cellData = PHPExcel_Calculation::_unwrapResult($cellData); + $objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData); + } + // Read cell formatting + } elseif ($dataType == 'F') { + $formatStyle = $columnWidth = $styleSettings = ''; + $styleData = array(); + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + case 'P' : $formatStyle = $rowDatum; + break; + case 'W' : list($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1)); + break; + case 'S' : $styleSettings = substr($rowDatum,1); + for ($i=0;$i<strlen($styleSettings);++$i) { + switch ($styleSettings{$i}) { + case 'I' : $styleData['font']['italic'] = true; + break; + case 'D' : $styleData['font']['bold'] = true; + break; + case 'T' : $styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'B' : $styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'L' : $styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + case 'R' : $styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN; + break; + } + } + break; + } + } + if (($formatStyle > '') && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + if (isset($this->_formats[$formatStyle])) { + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]); + } + } + if ((!empty($styleData)) && ($column > '') && ($row > '')) { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1); + $objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData); + } + if ($columnWidth > '') { + if ($startCol == $endCol) { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + } else { + $startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1); + $objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth); + do { + $objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth); + } while ($startCol != $endCol); + } + } + } else { + foreach($rowData as $rowDatum) { + switch($rowDatum{0}) { + case 'C' : + case 'X' : $column = substr($rowDatum,1); + break; + case 'R' : + case 'Y' : $row = substr($rowDatum,1); + break; + } + } + } + } + + // Close file + fclose($fileHandle); + + // Return + return $objPHPExcel; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Reader_SYLK + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + +} diff --git a/extend/phpexcel/PHPExcel/ReferenceHelper.php b/extend/phpexcel/PHPExcel/ReferenceHelper.php new file mode 100755 index 0000000..402f2b4 --- /dev/null +++ b/extend/phpexcel/PHPExcel/ReferenceHelper.php @@ -0,0 +1,922 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_ReferenceHelper (Singleton) + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_ReferenceHelper +{ + /** Constants */ + /** Regular Expressions */ + const REFHELPER_REGEXP_CELLREF = '((\w*|\'[^!]*\')!)?(?<![:a-z\$])(\$?[a-z]{1,3}\$?\d+)(?=[^:!\d\'])'; + const REFHELPER_REGEXP_CELLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}\$?\d+):(\$?[a-z]{1,3}\$?\d+)'; + const REFHELPER_REGEXP_ROWRANGE = '((\w*|\'[^!]*\')!)?(\$?\d+):(\$?\d+)'; + const REFHELPER_REGEXP_COLRANGE = '((\w*|\'[^!]*\')!)?(\$?[a-z]{1,3}):(\$?[a-z]{1,3})'; + + /** + * Instance of this class + * + * @var PHPExcel_ReferenceHelper + */ + private static $_instance; + + /** + * Get an instance of this class + * + * @return PHPExcel_ReferenceHelper + */ + public static function getInstance() { + if (!isset(self::$_instance) || (self::$_instance === NULL)) { + self::$_instance = new PHPExcel_ReferenceHelper(); + } + + return self::$_instance; + } + + /** + * Create a new PHPExcel_ReferenceHelper + */ + protected function __construct() { + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnSort($a, $b) { + return strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two column addresses + * Intended for use as a Callback function for reverse sorting column addresses by column + * + * @param string $a First column to test (e.g. 'AA') + * @param string $b Second column to test (e.g. 'Z') + * @return integer + */ + public static function columnReverseSort($a, $b) { + return 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b); + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? -1 : 1; + } + + /** + * Compare two cell addresses + * Intended for use as a Callback function for sorting cell addresses by column and row + * + * @param string $a First cell to test (e.g. 'AA1') + * @param string $b Second cell to test (e.g. 'Z1') + * @return integer + */ + public static function cellReverseSort($a, $b) { + sscanf($a,'%[A-Z]%d', $ac, $ar); + sscanf($b,'%[A-Z]%d', $bc, $br); + + if ($ar == $br) { + return 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc); + } + return ($ar < $br) ? 1 : -1; + } + + /** + * Test whether a cell address falls within a defined range of cells + * + * @param string $cellAddress Address of the cell we're testing + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @return boolean + */ + private static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) { + list($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress); + $cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn); + // Is cell within the range of rows/columns if we're deleting + if ($pNumRows < 0 && + ($cellRow >= ($beforeRow + $pNumRows)) && + ($cellRow < $beforeRow)) { + return TRUE; + } elseif ($pNumCols < 0 && + ($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) && + ($cellColumnIndex < $beforeColumnIndex)) { + return TRUE; + } + return FALSE; + } + + /** + * Update page breaks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aBreaks = $pSheet->getBreaks(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aBreaks as $key => $value) { + if (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // If we're deleting, then clear any defined breaks that are within the range + // of rows/columns that we're deleting + $pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } else { + // Otherwise update any affected breaks by inserting a new break at the appropriate point + // and removing the old affected break + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setBreak($newReference, $value) + ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE); + } + } + } + } + + /** + * Update cell comments when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aComments = $pSheet->getComments(); + $aNewComments = array(); // the new array of all comments + + foreach ($aComments as $key => &$value) { + // Any comments inside a deleted range will be ignored + if (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) { + // Otherwise build a new array of comments indexed by the adjusted cell reference + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewComments[$newReference] = $value; + } + } + // Replace the comments array with the new set of comments + $pSheet->setComments($aNewComments); + } + + /** + * Update hyperlinks when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aHyperlinkCollection = $pSheet->getHyperlinkCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort')); + + foreach ($aHyperlinkCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setHyperlink( $newReference, $value ); + $pSheet->setHyperlink( $key, null ); + } + } + } + + /** + * Update data validations when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aDataValidationCollection = $pSheet->getDataValidationCollection(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aDataValidationCollection as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->setDataValidation( $newReference, $value ); + $pSheet->setDataValidation( $key, null ); + } + } + } + + /** + * Update merged cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aMergeCells = $pSheet->getMergeCells(); + $aNewMergeCells = array(); // the new array of all merge cells + foreach ($aMergeCells as $key => &$value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + $aNewMergeCells[$newReference] = $newReference; + } + $pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array + } + + /** + * Update protected cells when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aProtectedCells = $pSheet->getProtectedCells(); + ($pNumCols > 0 || $pNumRows > 0) ? + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) : + uksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort')); + foreach ($aProtectedCells as $key => $value) { + $newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows); + if ($key != $newReference) { + $pSheet->protectCells( $newReference, $value, true ); + $pSheet->unprotectCells( $key ); + } + } + } + + /** + * Update column dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true); + if (!empty($aColumnDimensions)) { + foreach ($aColumnDimensions as $objColumnDimension) { + $newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows); + list($newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objColumnDimension->getColumnIndex() != $newReference) { + $objColumnDimension->setColumnIndex($newReference); + } + } + $pSheet->refreshColumnDimensions(); + } + } + + /** + * Update row dimensions when inserting/deleting rows/columns + * + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @param string $pBefore Insert/Delete before this cell address (e.g. 'A1') + * @param integer $beforeColumnIndex Index number of the column we're inserting/deleting before + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $beforeRow Number of the row we're inserting/deleting before + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + */ + protected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows) + { + $aRowDimensions = array_reverse($pSheet->getRowDimensions(), true); + if (!empty($aRowDimensions)) { + foreach ($aRowDimensions as $objRowDimension) { + $newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows); + list(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference); + if ($objRowDimension->getRowIndex() != $newReference) { + $objRowDimension->setRowIndex($newReference); + } + } + $pSheet->refreshRowDimensions(); + + $copyDimension = $pSheet->getRowDimension($beforeRow - 1); + for ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) { + $newDimension = $pSheet->getRowDimension($i); + $newDimension->setRowHeight($copyDimension->getRowHeight()); + $newDimension->setVisible($copyDimension->getVisible()); + $newDimension->setOutlineLevel($copyDimension->getOutlineLevel()); + $newDimension->setCollapsed($copyDimension->getCollapsed()); + } + } + } + + /** + * Insert a new column or row, updating all possible related data + * + * @param string $pBefore Insert before this cell address (e.g. 'A1') + * @param integer $pNumCols Number of columns to insert/delete (negative values indicate deletion) + * @param integer $pNumRows Number of rows to insert/delete (negative values indicate deletion) + * @param PHPExcel_Worksheet $pSheet The worksheet that we're editing + * @throws PHPExcel_Exception + */ + public function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL) + { + $remove = ($pNumCols < 0 || $pNumRows < 0); + $aCellCollection = $pSheet->getCellCollection(); + + // Get coordinates of $pBefore + $beforeColumn = 'A'; + $beforeRow = 1; + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore); + $beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn); + + // Clear cells if we are removing columns or rows + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + // 1. Clear column strips if we are removing columns + if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) { + for ($i = 1; $i <= $highestRow - 1; ++$i) { + for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($j) . $i; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // 2. Clear row strips if we are removing rows + if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) { + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . $j; + $pSheet->removeConditionalStyles($coordinate); + if ($pSheet->cellExists($coordinate)) { + $pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL); + $pSheet->getCell($coordinate)->setXfIndex(0); + } + } + } + } + + // Loop through cells, bottom-up, and change cell coordinates + if($remove) { + // It's faster to reverse and pop than to use unshift, especially with large cell collections + $aCellCollection = array_reverse($aCellCollection); + } + while ($cellID = array_pop($aCellCollection)) { + $cell = $pSheet->getCell($cellID); + $cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn()); + + if ($cellIndex-1 + $pNumCols < 0) { + continue; + } + + // New coordinates + $newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows); + + // Should the cell be updated? Move value and cellXf index from one cell to another. + if (($cellIndex >= $beforeColumnIndex) && + ($cell->getRow() >= $beforeRow)) { + + // Update cell styles + $pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex()); + + // Insert this cell at its new location + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $pSheet->getCell($newCoordinates) + ->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } else { + // Formula should not be adjusted + $pSheet->getCell($newCoordinates)->setValue($cell->getValue()); + } + + // Clear the original cell + $pSheet->getCellCacheController()->deleteCacheData($cellID); + + } else { + /* We don't need to update styles for rows/columns before our insertion position, + but we do still need to adjust any formulae in those cells */ + if ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) { + // Formula should be adjusted + $cell->setValue($this->updateFormulaReferences($cell->getValue(), + $pBefore, $pNumCols, $pNumRows, $pSheet->getTitle())); + } + + } + } + + // Duplicate styles for the newly inserted cells + $highestColumn = $pSheet->getHighestColumn(); + $highestRow = $pSheet->getHighestRow(); + + if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) { + for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i; + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) { + $pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j) . $i, $cloned); + } + } + } + + } + } + + if ($pNumRows > 0 && $beforeRow - 1 > 0) { + for ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) { + + // Style + $coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1); + if ($pSheet->cellExists($coordinate)) { + $xfIndex = $pSheet->getCell($coordinate)->getXfIndex(); + $conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ? + $pSheet->getConditionalStyles($coordinate) : false; + for ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) { + $pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex); + if ($conditionalStyles) { + $cloned = array(); + foreach ($conditionalStyles as $conditionalStyle) { + $cloned[] = clone $conditionalStyle; + } + $pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i) . $j, $cloned); + } + } + } + } + } + + // Update worksheet: column dimensions + $this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: row dimensions + $this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: page breaks + $this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: comments + $this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: hyperlinks + $this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: data validations + $this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: merge cells + $this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: protected cells + $this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows); + + // Update worksheet: autofilter + $autoFilter = $pSheet->getAutoFilter(); + $autoFilterRange = $autoFilter->getRange(); + if (!empty($autoFilterRange)) { + if ($pNumCols != 0) { + $autoFilterColumns = array_keys($autoFilter->getColumns()); + if (count($autoFilterColumns) > 0) { + sscanf($pBefore,'%[A-Z]%d', $column, $row); + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + if ($columnIndex <= $rangeEnd[0]) { + if ($pNumCols < 0) { + // If we're actually deleting any columns that fall within the autofilter range, + // then we delete any rules for those columns + $deleteColumn = $columnIndex + $pNumCols - 1; + $deleteCount = abs($pNumCols); + for ($i = 1; $i <= $deleteCount; ++$i) { + if (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) { + $autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn)); + } + ++$deleteColumn; + } + } + $startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0]; + + // Shuffle columns in autofilter range + if ($pNumCols > 0) { + // For insert, we shuffle from end to beginning to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + + $startColRef = $startCol; + $endColRef = $rangeEnd[0]; + $toColRef = $rangeEnd[0]+$pNumCols; + + do { + $autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1)); + --$endColRef; + --$toColRef; + } while ($startColRef <= $endColRef); + } else { + // For delete, we shuffle from beginning to end to avoid overwriting + $startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1); + $toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1); + $endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]); + do { + $autoFilter->shiftColumn($startColID,$toColID); + ++$startColID; + ++$toColID; + } while ($startColID != $endColID); + } + } + } + } + $pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: freeze pane + if ($pSheet->getFreezePane() != '') { + $pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Page setup + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) ); + } + + // Update worksheet: drawings + $aDrawings = $pSheet->getDrawingCollection(); + foreach ($aDrawings as $objDrawing) { + $newReference = $this->updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows); + if ($objDrawing->getCoordinates() != $newReference) { + $objDrawing->setCoordinates($newReference); + } + } + + // Update workbook: named ranges + if (count($pSheet->getParent()->getNamedRanges()) > 0) { + foreach ($pSheet->getParent()->getNamedRanges() as $namedRange) { + if ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) { + $namedRange->setRange( + $this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows) + ); + } + } + } + + // Garbage collect + $pSheet->garbageCollect(); + } + + /** + * Update references within formulas + * + * @param string $pFormula Formula to update + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @param int $pNumRows Number of rows to insert + * @param string $sheetName Worksheet name/title + * @return string Updated formula + * @throws PHPExcel_Exception + */ + public function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') { + // Update cell references in the formula + $formulaBlocks = explode('"',$pFormula); + $i = false; + foreach($formulaBlocks as &$formulaBlock) { + // Ignore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode) + if ($i = !$i) { + $adjustCount = 0; + $newCellTokens = $cellTokens = array(); + // Search for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2); + $modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = 100000; + $row = 10000000+trim($match[3],'$'); + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<!\d\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + $modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2); + + if ($match[3].':'.$match[4] !== $modified3.':'.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000; + $row = 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?![A-Z])/i'; + ++$adjustCount; + } + } + } + } + // Search for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3].':'.$match[4]; + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + $modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows); + + if ($match[3].$match[4] !== $modified3.$modified4) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3.':'.$modified4; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $column.$row; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z]\$\!)'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + // Search for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5) + $matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER); + + if ($matchCount > 0) { + foreach($matches as $match) { + $fromString = ($match[2] > '') ? $match[2].'!' : ''; + $fromString .= $match[3]; + + $modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows); + if ($match[3] !== $modified3) { + if (($match[2] == '') || (trim($match[2],"'") == $sheetName)) { + $toString = ($match[2] > '') ? $match[2].'!' : ''; + $toString .= $modified3; + list($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]); + // Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more + $column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000; + $row = trim($row,'$') + 10000000; + $cellIndex = $row . $column; + + $newCellTokens[$cellIndex] = preg_quote($toString); + $cellTokens[$cellIndex] = '/(?<![A-Z\$\!])'.preg_quote($fromString).'(?!\d)/i'; + ++$adjustCount; + } + } + } + } + if ($adjustCount > 0) { + if ($pNumCols > 0 || $pNumRows > 0) { + krsort($cellTokens); + krsort($newCellTokens); + } else { + ksort($cellTokens); + ksort($newCellTokens); + } // Update cell references in the formula + $formulaBlock = str_replace('\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock)); + } + } + } + unset($formulaBlock); + + // Then rebuild the formula string + return implode('"',$formulaBlocks); + } + + /** + * Update cell reference + * + * @param string $pCellRange Cell range + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + public function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + // Is it in another worksheet? Will not have to update anything. + if (strpos($pCellRange, "!") !== false) { + return $pCellRange; + // Is it a range or a single cell? + } elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) { + // Single cell + return $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows); + } elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) { + // Range + return $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows); + } else { + // Return original + return $pCellRange; + } + } + + /** + * Update named formulas (i.e. containing worksheet references / named ranges) + * + * @param PHPExcel $pPhpExcel Object to update + * @param string $oldName Old name (name to replace) + * @param string $newName New name + */ + public function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') { + if ($oldName == '') { + return; + } + + foreach ($pPhpExcel->getWorksheetIterator() as $sheet) { + foreach ($sheet->getCellCollection(false) as $cellID) { + $cell = $sheet->getCell($cellID); + if (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) { + $formula = $cell->getValue(); + if (strpos($formula, $oldName) !== false) { + $formula = str_replace("'" . $oldName . "'!", "'" . $newName . "'!", $formula); + $formula = str_replace($oldName . "!", $newName . "!", $formula); + $cell->setValueExplicit($formula, PHPExcel_Cell_DataType::TYPE_FORMULA); + } + } + } + } + } + + /** + * Update cell range + * + * @param string $pCellRange Cell range (e.g. 'B2:D4', 'B:C' or '2:3') + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell range + * @throws PHPExcel_Exception + */ + private function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) { + // Update range + $range = PHPExcel_Cell::splitRange($pCellRange); + $ic = count($range); + for ($i = 0; $i < $ic; ++$i) { + $jc = count($range[$i]); + for ($j = 0; $j < $jc; ++$j) { + if (ctype_alpha($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[0]; + } elseif(ctype_digit($range[$i][$j])) { + $r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows)); + $range[$i][$j] = $r[1]; + } else { + $range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows); + } + } + } + + // Recreate range string + return PHPExcel_Cell::buildRange($range); + } else { + throw new PHPExcel_Exception("Only cell ranges may be passed to this method."); + } + } + + /** + * Update single cell reference + * + * @param string $pCellReference Single cell reference + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to increment + * @param int $pNumRows Number of rows to increment + * @return string Updated cell reference + * @throws PHPExcel_Exception + */ + private function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) { + if (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) { + // Get coordinates of $pBefore + list($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore ); + + // Get coordinates of $pCellReference + list($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference ); + + // Verify which parts should be updated + $updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') && + PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn)); + $updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') && + $newRow >= $beforeRow); + + // Create new column reference + if ($updateColumn) { + $newColumn = PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols ); + } + + // Create new row reference + if ($updateRow) { + $newRow = $newRow + $pNumRows; + } + + // Return new reference + return $newColumn . $newRow; + } else { + throw new PHPExcel_Exception("Only single cell references may be passed to this method."); + } + } + + /** + * __clone implementation. Cloning should not be allowed in a Singleton! + * + * @throws PHPExcel_Exception + */ + public final function __clone() { + throw new PHPExcel_Exception("Cloning a Singleton is not allowed!"); + } +} diff --git a/extend/phpexcel/PHPExcel/RichText.php b/extend/phpexcel/PHPExcel/RichText.php new file mode 100755 index 0000000..2f172a0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/RichText.php @@ -0,0 +1,199 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText implements PHPExcel_IComparable +{ + /** + * Rich text elements + * + * @var PHPExcel_RichText_ITextElement[] + */ + private $_richTextElements; + + /** + * Create a new PHPExcel_RichText instance + * + * @param PHPExcel_Cell $pCell + * @throws PHPExcel_Exception + */ + public function __construct(PHPExcel_Cell $pCell = null) + { + // Initialise variables + $this->_richTextElements = array(); + + // Rich-Text string attached to cell? + if ($pCell !== NULL) { + // Add cell text and style + if ($pCell->getValue() != "") { + $objRun = new PHPExcel_RichText_Run($pCell->getValue()); + $objRun->setFont(clone $pCell->getParent()->getStyle($pCell->getCoordinate())->getFont()); + $this->addText($objRun); + } + + // Set parent value + $pCell->setValueExplicit($this, PHPExcel_Cell_DataType::TYPE_STRING); + } + } + + /** + * Add text + * + * @param PHPExcel_RichText_ITextElement $pText Rich text element + * @throws PHPExcel_Exception + * @return PHPExcel_RichText + */ + public function addText(PHPExcel_RichText_ITextElement $pText = null) + { + $this->_richTextElements[] = $pText; + return $this; + } + + /** + * Create text + * + * @param string $pText Text + * @return PHPExcel_RichText_TextElement + * @throws PHPExcel_Exception + */ + public function createText($pText = '') + { + $objText = new PHPExcel_RichText_TextElement($pText); + $this->addText($objText); + return $objText; + } + + /** + * Create text run + * + * @param string $pText Text + * @return PHPExcel_RichText_Run + * @throws PHPExcel_Exception + */ + public function createTextRun($pText = '') + { + $objText = new PHPExcel_RichText_Run($pText); + $this->addText($objText); + return $objText; + } + + /** + * Get plain text + * + * @return string + */ + public function getPlainText() + { + // Return value + $returnValue = ''; + + // Loop through all PHPExcel_RichText_ITextElement + foreach ($this->_richTextElements as $text) { + $returnValue .= $text->getText(); + } + + // Return + return $returnValue; + } + + /** + * Convert to string + * + * @return string + */ + public function __toString() + { + return $this->getPlainText(); + } + + /** + * Get Rich Text elements + * + * @return PHPExcel_RichText_ITextElement[] + */ + public function getRichTextElements() + { + return $this->_richTextElements; + } + + /** + * Set Rich Text elements + * + * @param PHPExcel_RichText_ITextElement[] $pElements Array of elements + * @throws PHPExcel_Exception + * @return PHPExcel_RichText + */ + public function setRichTextElements($pElements = null) + { + if (is_array($pElements)) { + $this->_richTextElements = $pElements; + } else { + throw new PHPExcel_Exception("Invalid PHPExcel_RichText_ITextElement[] array passed."); + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hashElements = ''; + foreach ($this->_richTextElements as $element) { + $hashElements .= $element->getHashCode(); + } + + return md5( + $hashElements + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() + { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/RichText/ITextElement.php b/extend/phpexcel/PHPExcel/RichText/ITextElement.php new file mode 100755 index 0000000..ec19498 --- /dev/null +++ b/extend/phpexcel/PHPExcel/RichText/ITextElement.php @@ -0,0 +1,64 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_ITextElement + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_RichText_ITextElement +{ + /** + * Get text + * + * @return string Text + */ + public function getText(); + + /** + * Set text + * + * @param $pText string Text + * @return PHPExcel_RichText_ITextElement + */ + public function setText($pText = ''); + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont(); + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode(); +} diff --git a/extend/phpexcel/PHPExcel/RichText/Run.php b/extend/phpexcel/PHPExcel/RichText/Run.php new file mode 100755 index 0000000..71545fc --- /dev/null +++ b/extend/phpexcel/PHPExcel/RichText/Run.php @@ -0,0 +1,102 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_Run + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement +{ + /** + * Font + * + * @var PHPExcel_Style_Font + */ + private $_font; + + /** + * Create a new PHPExcel_RichText_Run instance + * + * @param string $pText Text + */ + public function __construct($pText = '') + { + // Initialise variables + $this->setText($pText); + $this->_font = new PHPExcel_Style_Font(); + } + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() { + return $this->_font; + } + + /** + * Set font + * + * @param PHPExcel_Style_Font $pFont Font + * @throws PHPExcel_Exception + * @return PHPExcel_RichText_ITextElement + */ + public function setFont(PHPExcel_Style_Font $pFont = null) { + $this->_font = $pFont; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->getText() + . $this->_font->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/RichText/TextElement.php b/extend/phpexcel/PHPExcel/RichText/TextElement.php new file mode 100755 index 0000000..3593c6e --- /dev/null +++ b/extend/phpexcel/PHPExcel/RichText/TextElement.php @@ -0,0 +1,108 @@ +<?php +/** + * PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_RichText_TextElement + * + * @category PHPExcel + * @package PHPExcel_RichText + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement +{ + /** + * Text + * + * @var string + */ + private $_text; + + /** + * Create a new PHPExcel_RichText_TextElement instance + * + * @param string $pText Text + */ + public function __construct($pText = '') + { + // Initialise variables + $this->_text = $pText; + } + + /** + * Get text + * + * @return string Text + */ + public function getText() { + return $this->_text; + } + + /** + * Set text + * + * @param $pText string Text + * @return PHPExcel_RichText_ITextElement + */ + public function setText($pText = '') { + $this->_text = $pText; + return $this; + } + + /** + * Get font + * + * @return PHPExcel_Style_Font + */ + public function getFont() { + return null; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_text + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Settings.php b/extend/phpexcel/PHPExcel/Settings.php new file mode 100755 index 0000000..b899613 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Settings.php @@ -0,0 +1,387 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Settings + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + + +class PHPExcel_Settings +{ + /** constants */ + /** Available Zip library classes */ + const PCLZIP = 'PHPExcel_Shared_ZipArchive'; + const ZIPARCHIVE = 'ZipArchive'; + + /** Optional Chart Rendering libraries */ + const CHART_RENDERER_JPGRAPH = 'jpgraph'; + + /** Optional PDF Rendering libraries */ + const PDF_RENDERER_TCPDF = 'tcPDF'; + const PDF_RENDERER_DOMPDF = 'DomPDF'; + const PDF_RENDERER_MPDF = 'mPDF'; + + + private static $_chartRenderers = array( + self::CHART_RENDERER_JPGRAPH, + ); + + private static $_pdfRenderers = array( + self::PDF_RENDERER_TCPDF, + self::PDF_RENDERER_DOMPDF, + self::PDF_RENDERER_MPDF, + ); + + + /** + * Name of the class used for Zip file management + * e.g. + * ZipArchive + * + * @var string + */ + private static $_zipClass = self::ZIPARCHIVE; + + + /** + * Name of the external Library used for rendering charts + * e.g. + * jpgraph + * + * @var string + */ + private static $_chartRendererName = NULL; + + /** + * Directory Path to the external Library used for rendering charts + * + * @var string + */ + private static $_chartRendererPath = NULL; + + + /** + * Name of the external Library used for rendering PDF files + * e.g. + * mPDF + * + * @var string + */ + private static $_pdfRendererName = NULL; + + /** + * Directory Path to the external Library used for rendering PDF files + * + * @var string + */ + private static $_pdfRendererPath = NULL; + + /** + * Default options for libxml loader + * + * @var int + */ + private static $_libXmlLoaderOptions = null; + + /** + * Set the Zip handler Class that PHPExcel should use for Zip file management (PCLZip or ZipArchive) + * + * @param string $zipClass The Zip handler class that PHPExcel should use for Zip file management + * e.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive + * @return boolean Success or failure + */ + public static function setZipClass($zipClass) + { + if (($zipClass === self::PCLZIP) || + ($zipClass === self::ZIPARCHIVE)) { + self::$_zipClass = $zipClass; + return TRUE; + } + return FALSE; + } // function setZipClass() + + + /** + * Return the name of the Zip handler Class that PHPExcel is configured to use (PCLZip or ZipArchive) + * or Zip file management + * + * @return string Name of the Zip handler Class that PHPExcel is configured to use + * for Zip file management + * e.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive + */ + public static function getZipClass() + { + return self::$_zipClass; + } // function getZipClass() + + + /** + * Return the name of the method that is currently configured for cell cacheing + * + * @return string Name of the cacheing method + */ + public static function getCacheStorageMethod() + { + return PHPExcel_CachedObjectStorageFactory::getCacheStorageMethod(); + } // function getCacheStorageMethod() + + + /** + * Return the name of the class that is currently being used for cell cacheing + * + * @return string Name of the class currently being used for cacheing + */ + public static function getCacheStorageClass() + { + return PHPExcel_CachedObjectStorageFactory::getCacheStorageClass(); + } // function getCacheStorageClass() + + + /** + * Set the method that should be used for cell cacheing + * + * @param string $method Name of the cacheing method + * @param array $arguments Optional configuration arguments for the cacheing method + * @return boolean Success or failure + */ + public static function setCacheStorageMethod( + $method = PHPExcel_CachedObjectStorageFactory::cache_in_memory, + $arguments = array() + ) + { + return PHPExcel_CachedObjectStorageFactory::initialize($method, $arguments); + } // function setCacheStorageMethod() + + + /** + * Set the locale code to use for formula translations and any special formatting + * + * @param string $locale The locale code to use (e.g. "fr" or "pt_br" or "en_uk") + * @return boolean Success or failure + */ + public static function setLocale($locale='en_us') + { + return PHPExcel_Calculation::getInstance()->setLocale($locale); + } // function setLocale() + + + /** + * Set details of the external library that PHPExcel should use for rendering charts + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * @param string $libraryBaseDir Directory path to the library's base folder + * + * @return boolean Success or failure + */ + public static function setChartRenderer($libraryName, $libraryBaseDir) + { + if (!self::setChartRendererName($libraryName)) + return FALSE; + return self::setChartRendererPath($libraryBaseDir); + } // function setChartRenderer() + + + /** + * Identify to PHPExcel the external library to use for rendering charts + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + * + * @return boolean Success or failure + */ + public static function setChartRendererName($libraryName) + { + if (!in_array($libraryName,self::$_chartRenderers)) { + return FALSE; + } + + self::$_chartRendererName = $libraryName; + + return TRUE; + } // function setChartRendererName() + + + /** + * Tell PHPExcel where to find the external library to use for rendering charts + * + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure + */ + public static function setChartRendererPath($libraryBaseDir) + { + if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { + return FALSE; + } + self::$_chartRendererPath = $libraryBaseDir; + + return TRUE; + } // function setChartRendererPath() + + + /** + * Return the Chart Rendering Library that PHPExcel is currently configured to use (e.g. jpgraph) + * + * @return string|NULL Internal reference name of the Chart Rendering Library that PHPExcel is + * currently configured to use + * e.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH + */ + public static function getChartRendererName() + { + return self::$_chartRendererName; + } // function getChartRendererName() + + + /** + * Return the directory path to the Chart Rendering Library that PHPExcel is currently configured to use + * + * @return string|NULL Directory Path to the Chart Rendering Library that PHPExcel is + * currently configured to use + */ + public static function getChartRendererPath() + { + return self::$_chartRendererPath; + } // function getChartRendererPath() + + + /** + * Set details of the external library that PHPExcel should use for rendering PDF files + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + * @param string $libraryBaseDir Directory path to the library's base folder + * + * @return boolean Success or failure + */ + public static function setPdfRenderer($libraryName, $libraryBaseDir) + { + if (!self::setPdfRendererName($libraryName)) + return FALSE; + return self::setPdfRendererPath($libraryBaseDir); + } // function setPdfRenderer() + + + /** + * Identify to PHPExcel the external library to use for rendering PDF files + * + * @param string $libraryName Internal reference name of the library + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + * + * @return boolean Success or failure + */ + public static function setPdfRendererName($libraryName) + { + if (!in_array($libraryName,self::$_pdfRenderers)) { + return FALSE; + } + + self::$_pdfRendererName = $libraryName; + + return TRUE; + } // function setPdfRendererName() + + + /** + * Tell PHPExcel where to find the external library to use for rendering PDF files + * + * @param string $libraryBaseDir Directory path to the library's base folder + * @return boolean Success or failure + */ + public static function setPdfRendererPath($libraryBaseDir) + { + if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) { + return FALSE; + } + self::$_pdfRendererPath = $libraryBaseDir; + + return TRUE; + } // function setPdfRendererPath() + + + /** + * Return the PDF Rendering Library that PHPExcel is currently configured to use (e.g. dompdf) + * + * @return string|NULL Internal reference name of the PDF Rendering Library that PHPExcel is + * currently configured to use + * e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF, + * PHPExcel_Settings::PDF_RENDERER_DOMPDF + * or PHPExcel_Settings::PDF_RENDERER_MPDF + */ + public static function getPdfRendererName() + { + return self::$_pdfRendererName; + } // function getPdfRendererName() + + /** + * Return the directory path to the PDF Rendering Library that PHPExcel is currently configured to use + * + * @return string|NULL Directory Path to the PDF Rendering Library that PHPExcel is + * currently configured to use + */ + public static function getPdfRendererPath() + { + return self::$_pdfRendererPath; + } // function getPdfRendererPath() + + /** + * Set default options for libxml loader + * + * @param int $options Default options for libxml loader + */ + public static function setLibXmlLoaderOptions($options = null) + { + if (is_null($options)) { + $options = LIBXML_DTDLOAD | LIBXML_DTDATTR; + } + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + self::$_libXmlLoaderOptions = $options; + } // function setLibXmlLoaderOptions + + /** + * Get default options for libxml loader. + * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly. + * + * @return int Default options for libxml loader + */ + public static function getLibXmlLoaderOptions() + { + if (is_null(self::$_libXmlLoaderOptions)) { + self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR); + } + @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); + return self::$_libXmlLoaderOptions; + } // function getLibXmlLoaderOptions +} diff --git a/extend/phpexcel/PHPExcel/Shared/CodePage.php b/extend/phpexcel/PHPExcel/Shared/CodePage.php new file mode 100755 index 0000000..2807ab3 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/CodePage.php @@ -0,0 +1,102 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_CodePage + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_CodePage +{ + /** + * Convert Microsoft Code Page Identifier to Code Page Name which iconv + * and mbstring understands + * + * @param integer $codePage Microsoft Code Page Indentifier + * @return string Code Page Name + * @throws PHPExcel_Exception + */ + public static function NumberToName($codePage = 1252) + { + switch ($codePage) { + case 367: return 'ASCII'; break; // ASCII + case 437: return 'CP437'; break; // OEM US + case 720: throw new PHPExcel_Exception('Code page 720 not supported.'); + break; // OEM Arabic + case 737: return 'CP737'; break; // OEM Greek + case 775: return 'CP775'; break; // OEM Baltic + case 850: return 'CP850'; break; // OEM Latin I + case 852: return 'CP852'; break; // OEM Latin II (Central European) + case 855: return 'CP855'; break; // OEM Cyrillic + case 857: return 'CP857'; break; // OEM Turkish + case 858: return 'CP858'; break; // OEM Multilingual Latin I with Euro + case 860: return 'CP860'; break; // OEM Portugese + case 861: return 'CP861'; break; // OEM Icelandic + case 862: return 'CP862'; break; // OEM Hebrew + case 863: return 'CP863'; break; // OEM Canadian (French) + case 864: return 'CP864'; break; // OEM Arabic + case 865: return 'CP865'; break; // OEM Nordic + case 866: return 'CP866'; break; // OEM Cyrillic (Russian) + case 869: return 'CP869'; break; // OEM Greek (Modern) + case 874: return 'CP874'; break; // ANSI Thai + case 932: return 'CP932'; break; // ANSI Japanese Shift-JIS + case 936: return 'CP936'; break; // ANSI Chinese Simplified GBK + case 949: return 'CP949'; break; // ANSI Korean (Wansung) + case 950: return 'CP950'; break; // ANSI Chinese Traditional BIG5 + case 1200: return 'UTF-16LE'; break; // UTF-16 (BIFF8) + case 1250: return 'CP1250'; break; // ANSI Latin II (Central European) + case 1251: return 'CP1251'; break; // ANSI Cyrillic + case 0: // CodePage is not always correctly set when the xls file was saved by Apple's Numbers program + case 1252: return 'CP1252'; break; // ANSI Latin I (BIFF4-BIFF7) + case 1253: return 'CP1253'; break; // ANSI Greek + case 1254: return 'CP1254'; break; // ANSI Turkish + case 1255: return 'CP1255'; break; // ANSI Hebrew + case 1256: return 'CP1256'; break; // ANSI Arabic + case 1257: return 'CP1257'; break; // ANSI Baltic + case 1258: return 'CP1258'; break; // ANSI Vietnamese + case 1361: return 'CP1361'; break; // ANSI Korean (Johab) + case 10000: return 'MAC'; break; // Apple Roman + case 10006: return 'MACGREEK'; break; // Macintosh Greek + case 10007: return 'MACCYRILLIC'; break; // Macintosh Cyrillic + case 10008: return 'CP936'; break; // Macintosh - Simplified Chinese (GB 2312) + case 10029: return 'MACCENTRALEUROPE'; break; // Macintosh Central Europe + case 10079: return 'MACICELAND'; break; // Macintosh Icelandic + case 10081: return 'MACTURKISH'; break; // Macintosh Turkish + case 32768: return 'MAC'; break; // Apple Roman + case 32769: throw new PHPExcel_Exception('Code page 32769 not supported.'); + break; // ANSI Latin I (BIFF2-BIFF3) + case 65000: return 'UTF-7'; break; // Unicode (UTF-7) + case 65001: return 'UTF-8'; break; // Unicode (UTF-8) + } + + throw new PHPExcel_Exception('Unknown codepage: ' . $codePage); + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Date.php b/extend/phpexcel/PHPExcel/Shared/Date.php new file mode 100755 index 0000000..7fe4f42 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Date.php @@ -0,0 +1,393 @@ +<?php + +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Date + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Date +{ + /** constants */ + const CALENDAR_WINDOWS_1900 = 1900; // Base date of 1st Jan 1900 = 1.0 + const CALENDAR_MAC_1904 = 1904; // Base date of 2nd Jan 1904 = 1.0 + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_monthNames = array( 'Jan' => 'January', + 'Feb' => 'February', + 'Mar' => 'March', + 'Apr' => 'April', + 'May' => 'May', + 'Jun' => 'June', + 'Jul' => 'July', + 'Aug' => 'August', + 'Sep' => 'September', + 'Oct' => 'October', + 'Nov' => 'November', + 'Dec' => 'December', + ); + + /* + * Names of the months of the year, indexed by shortname + * Planned usage for locale settings + * + * @public + * @var string[] + */ + public static $_numberSuffixes = array( 'st', + 'nd', + 'rd', + 'th', + ); + + /* + * Base calendar year to use for calculations + * + * @private + * @var int + */ + protected static $_excelBaseDate = self::CALENDAR_WINDOWS_1900; + + /** + * Set the Excel calendar (Windows 1900 or Mac 1904) + * + * @param integer $baseDate Excel base date (1900 or 1904) + * @return boolean Success or failure + */ + public static function setExcelCalendar($baseDate) { + if (($baseDate == self::CALENDAR_WINDOWS_1900) || + ($baseDate == self::CALENDAR_MAC_1904)) { + self::$_excelBaseDate = $baseDate; + return TRUE; + } + return FALSE; + } // function setExcelCalendar() + + + /** + * Return the Excel calendar (Windows 1900 or Mac 1904) + * + * @return integer Excel base date (1900 or 1904) + */ + public static function getExcelCalendar() { + return self::$_excelBaseDate; + } // function getExcelCalendar() + + + /** + * Convert a date from Excel to PHP + * + * @param long $dateValue Excel date/time value + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return long PHP serialized date/time + */ + public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + $my_excelBaseDate = 25569; + // Adjust for the spurious 29-Feb-1900 (Day 60) + if ($dateValue < 60) { + --$my_excelBaseDate; + } + } else { + $my_excelBaseDate = 24107; + } + + // Perform conversion + if ($dateValue >= 1) { + $utcDays = $dateValue - $my_excelBaseDate; + $returnValue = round($utcDays * 86400); + if (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) { + $returnValue = (integer) $returnValue; + } + } else { + $hours = round($dateValue * 24); + $mins = round($dateValue * 1440) - round($hours * 60); + $secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60); + $returnValue = (integer) gmmktime($hours, $mins, $secs); + } + + $timezoneAdjustment = ($adjustToTimezone) ? + PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) : + 0; + + // Return + return $returnValue + $timezoneAdjustment; + } // function ExcelToPHP() + + + /** + * Convert a date from Excel to a PHP Date/Time object + * + * @param integer $dateValue Excel date/time value + * @return integer PHP date/time object + */ + public static function ExcelToPHPObject($dateValue = 0) { + $dateTime = self::ExcelToPHP($dateValue); + $days = floor($dateTime / 86400); + $time = round((($dateTime / 86400) - $days) * 86400); + $hours = round($time / 3600); + $minutes = round($time / 60) - ($hours * 60); + $seconds = round($time) - ($hours * 3600) - ($minutes * 60); + + $dateObj = date_create('1-Jan-1970+'.$days.' days'); + $dateObj->setTime($hours,$minutes,$seconds); + + return $dateObj; + } // function ExcelToPHPObject() + + + /** + * Convert a date from PHP to Excel + * + * @param mixed $dateValue PHP serialized date/time or date object + * @param boolean $adjustToTimezone Flag indicating whether $dateValue should be treated as + * a UST timestamp, or adjusted to UST + * @param string $timezone The timezone for finding the adjustment from UST + * @return mixed Excel date/time value + * or boolean FALSE on failure + */ + public static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) { + $saveTimeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $retValue = FALSE; + if ((is_object($dateValue)) && ($dateValue instanceof DateTime)) { + $retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'), + $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s') + ); + } elseif (is_numeric($dateValue)) { + $retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue), + date('H',$dateValue), date('i',$dateValue), date('s',$dateValue) + ); + } + date_default_timezone_set($saveTimeZone); + + return $retValue; + } // function PHPToExcel() + + + /** + * FormattedPHPToExcel + * + * @param long $year + * @param long $month + * @param long $day + * @param long $hours + * @param long $minutes + * @param long $seconds + * @return long Excel date/time value + */ + public static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) { + if (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) { + // + // Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel + // This affects every date following 28th February 1900 + // + $excel1900isLeapYear = TRUE; + if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; } + $my_excelBaseDate = 2415020; + } else { + $my_excelBaseDate = 2416481; + $excel1900isLeapYear = FALSE; + } + + // Julian base date Adjustment + if ($month > 2) { + $month -= 3; + } else { + $month += 9; + --$year; + } + + // Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0) + $century = substr($year,0,2); + $decade = substr($year,2,2); + $excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear; + + $excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400; + + return (float) $excelDate + $excelTime; + } // function FormattedPHPToExcel() + + + /** + * Is a given cell a date/time? + * + * @param PHPExcel_Cell $pCell + * @return boolean + */ + public static function isDateTime(PHPExcel_Cell $pCell) { + return self::isDateTimeFormat( + $pCell->getWorksheet()->getStyle( + $pCell->getCoordinate() + )->getNumberFormat() + ); + } // function isDateTime() + + + /** + * Is a given number format a date/time? + * + * @param PHPExcel_Style_NumberFormat $pFormat + * @return boolean + */ + public static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) { + return self::isDateTimeFormatCode($pFormat->getFormatCode()); + } // function isDateTimeFormat() + + + private static $possibleDateFormatCharacters = 'eymdHs'; + + /** + * Is a given number format code a date/time? + * + * @param string $pFormatCode + * @return boolean + */ + public static function isDateTimeFormatCode($pFormatCode = '') { + if (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL)) + // "General" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check) + return FALSE; + if (preg_match('/[0#]E[+-]0/i', $pFormatCode)) + // Scientific format + return FALSE; + // Switch on formatcode + switch ($pFormatCode) { + // Explicitly defined date formats + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17: + case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22: + return TRUE; + } + + // Typically number, currency or accounting (or occasionally fraction) formats + if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) { + return FALSE; + } + // Try checking for any of the date formatting characters that don't appear within square braces + if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) { + // We might also have a format mask containing quoted strings... + // we don't want to test for any of our characters within the quoted blocks + if (strpos($pFormatCode,'"') !== FALSE) { + $segMatcher = FALSE; + foreach(explode('"',$pFormatCode) as $subVal) { + // Only test in alternate array entries (the non-quoted blocks) + if (($segMatcher = !$segMatcher) && + (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) { + return TRUE; + } + } + return FALSE; + } + return TRUE; + } + + // No date... + return FALSE; + } // function isDateTimeFormatCode() + + + /** + * Convert a date/time string to Excel time + * + * @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10' + * @return float|FALSE Excel date/time serial value + */ + public static function stringToExcel($dateValue = '') { + if (strlen($dateValue) < 2) + return FALSE; + if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue)) + return FALSE; + + $dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue); + + if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } else { + if (strpos($dateValue, ':') !== FALSE) { + $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue); + if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) { + return FALSE; + } + $dateValueNew += $timeValue; + } + return $dateValueNew; + } + + + } + + public static function monthStringToNumber($month) { + $monthIndex = 1; + foreach(self::$_monthNames as $shortMonthName => $longMonthName) { + if (($month === $longMonthName) || ($month === $shortMonthName)) { + return $monthIndex; + } + ++$monthIndex; + } + return $month; + } + + public static function dayStringToNumber($day) { + $strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day)); + if (is_numeric($strippedDayValue)) { + return $strippedDayValue; + } + return $day; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Drawing.php b/extend/phpexcel/PHPExcel/Shared/Drawing.php new file mode 100755 index 0000000..1d7af16 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Drawing.php @@ -0,0 +1,272 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Drawing + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Drawing +{ + /** + * Convert pixels to EMU + * + * @param int $pValue Value in pixels + * @return int Value in EMU + */ + public static function pixelsToEMU($pValue = 0) { + return round($pValue * 9525); + } + + /** + * Convert EMU to pixels + * + * @param int $pValue Value in EMU + * @return int Value in pixels + */ + public static function EMUToPixels($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 9525); + } else { + return 0; + } + } + + /** + * Convert pixels to column width. Exact algorithm not known. + * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875 + * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional. + * + * @param int $pValue Value in pixels + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in cell dimension + */ + public static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']; + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * 11 + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size; + } + + return $colWidth; + } + + /** + * Convert column width from (intrinsic) Excel units to pixels + * + * @param float $pValue Value in cell dimension + * @param PHPExcel_Style_Font $pDefaultFont Default font of the workbook + * @return int Value in pixels + */ + public static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) { + // Font name and size + $name = $pDefaultFont->getName(); + $size = $pDefaultFont->getSize(); + + if (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) { + // Exact width can be determined + $colWidth = $pValue + * PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $colWidth = $pValue * $size + * PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] + / PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11; + } + + // Round pixels to closest integer + $colWidth = (int) round($colWidth); + + return $colWidth; + } + + /** + * Convert pixels to points + * + * @param int $pValue Value in pixels + * @return int Value in points + */ + public static function pixelsToPoints($pValue = 0) { + return $pValue * 0.67777777; + } + + /** + * Convert points to pixels + * + * @param int $pValue Value in points + * @return int Value in pixels + */ + public static function pointsToPixels($pValue = 0) { + if ($pValue != 0) { + return (int) ceil($pValue * 1.333333333); + } else { + return 0; + } + } + + /** + * Convert degrees to angle + * + * @param int $pValue Degrees + * @return int Angle + */ + public static function degreesToAngle($pValue = 0) { + return (int)round($pValue * 60000); + } + + /** + * Convert angle to degrees + * + * @param int $pValue Angle + * @return int Degrees + */ + public static function angleToDegrees($pValue = 0) { + if ($pValue != 0) { + return round($pValue / 60000); + } else { + return 0; + } + } + + /** + * Create a new image from file. By alexander at alexauto dot nl + * + * @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214 + * @param string $filename Path to Windows DIB (BMP) image + * @return resource + */ + public static function imagecreatefrombmp($p_sFile) + { + // Load the image into a string + $file = fopen($p_sFile,"rb"); + $read = fread($file,10); + while(!feof($file)&&($read<>"")) + $read .= fread($file,1024); + + $temp = unpack("H*",$read); + $hex = $temp[1]; + $header = substr($hex,0,108); + + // Process the header + // Structure: http://www.fastgraph.com/help/bmp_header_format.html + if (substr($header,0,4)=="424d") + { + // Cut it in parts of 2 bytes + $header_parts = str_split($header,2); + + // Get the width 4 bytes + $width = hexdec($header_parts[19].$header_parts[18]); + + // Get the height 4 bytes + $height = hexdec($header_parts[23].$header_parts[22]); + + // Unset the header params + unset($header_parts); + } + + // Define starting X and Y + $x = 0; + $y = 1; + + // Create newimage + $image = imagecreatetruecolor($width,$height); + + // Grab the body from the image + $body = substr($hex,108); + + // Calculate if padding at the end-line is needed + // Divided by two to keep overview. + // 1 byte = 2 HEX-chars + $body_size = (strlen($body)/2); + $header_size = ($width*$height); + + // Use end-line padding? Only when needed + $usePadding = ($body_size>($header_size*3)+4); + + // Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption + // Calculate the next DWORD-position in the body + for ($i=0;$i<$body_size;$i+=3) + { + // Calculate line-ending and padding + if ($x>=$width) + { + // If padding needed, ignore image-padding + // Shift i to the ending of the current 32-bit-block + if ($usePadding) + $i += $width%4; + + // Reset horizontal position + $x = 0; + + // Raise the height-position (bottom-up) + $y++; + + // Reached the image-height? Break the for-loop + if ($y>$height) + break; + } + + // Calculation of the RGB-pixel (defined as BGR in image-data) + // Define $i_pos as absolute position in the body + $i_pos = $i*2; + $r = hexdec($body[$i_pos+4].$body[$i_pos+5]); + $g = hexdec($body[$i_pos+2].$body[$i_pos+3]); + $b = hexdec($body[$i_pos].$body[$i_pos+1]); + + // Calculate and draw the pixel + $color = imagecolorallocate($image,$r,$g,$b); + imagesetpixel($image,$x,$height-$y,$color); + + // Raise the horizontal position + $x++; + } + + // Unset the body / free the memory + unset($body); + + // Return image-object + return $image; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher.php b/extend/phpexcel/PHPExcel/Shared/Escher.php new file mode 100755 index 0000000..983cbda --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher.php @@ -0,0 +1,91 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher +{ + /** + * Drawing Group Container + * + * @var PHPExcel_Shared_Escher_DggContainer + */ + private $_dggContainer; + + /** + * Drawing Container + * + * @var PHPExcel_Shared_Escher_DgContainer + */ + private $_dgContainer; + + /** + * Get Drawing Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDggContainer() + { + return $this->_dggContainer; + } + + /** + * Set Drawing Group Container + * + * @param PHPExcel_Shared_Escher_DggContainer $dggContainer + */ + public function setDggContainer($dggContainer) + { + return $this->_dggContainer = $dggContainer; + } + + /** + * Get Drawing Container + * + * @return PHPExcel_Shared_Escher_DgContainer + */ + public function getDgContainer() + { + return $this->_dgContainer; + } + + /** + * Set Drawing Container + * + * @param PHPExcel_Shared_Escher_DgContainer $dgContainer + */ + public function setDgContainer($dgContainer) + { + return $this->_dgContainer = $dgContainer; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer.php b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer.php new file mode 100755 index 0000000..3ec564c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer.php @@ -0,0 +1,83 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer +{ + /** + * Drawing index, 1-based. + * + * @var int + */ + private $_dgId; + + /** + * Last shape index in this drawing + * + * @var int + */ + private $_lastSpId; + + private $_spgrContainer = null; + + public function getDgId() + { + return $this->_dgId; + } + + public function setDgId($value) + { + $this->_dgId = $value; + } + + public function getLastSpId() + { + return $this->_lastSpId; + } + + public function setLastSpId($value) + { + $this->_lastSpId = $value; + } + + public function getSpgrContainer() + { + return $this->_spgrContainer; + } + + public function setSpgrContainer($spgrContainer) + { + return $this->_spgrContainer = $spgrContainer; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php new file mode 100755 index 0000000..651eaf0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php @@ -0,0 +1,109 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer_SpgrContainer +{ + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; + + /** + * Shape Container collection + * + * @var array + */ + private $_children = array(); + + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the parent Shape Group Container if any + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Add a child. This will be either spgrContainer or spContainer + * + * @param mixed $child + */ + public function addChild($child) + { + $this->_children[] = $child; + $child->setParent($this); + } + + /** + * Get collection of Shape Containers + */ + public function getChildren() + { + return $this->_children; + } + + /** + * Recursively get all spContainers within this spgrContainer + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[] + */ + public function getAllSpContainers() + { + $allSpContainers = array(); + + foreach ($this->_children as $child) { + if ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + $allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers()); + } else { + $allSpContainers[] = $child; + } + } + + return $allSpContainers; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php new file mode 100755 index 0000000..dde1154 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php @@ -0,0 +1,395 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer +{ + /** + * Parent Shape Group Container + * + * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + private $_parent; + + /** + * Is this a group shape? + * + * @var boolean + */ + private $_spgr = false; + + /** + * Shape type + * + * @var int + */ + private $_spType; + + /** + * Shape flag + * + * @var int + */ + private $_spFlag; + + /** + * Shape index (usually group shape has index 0, and the rest: 1,2,3...) + * + * @var boolean + */ + private $_spId; + + /** + * Array of options + * + * @var array + */ + private $_OPT; + + /** + * Cell coordinates of upper-left corner of shape, e.g. 'A1' + * + * @var string + */ + private $_startCoordinates; + + /** + * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_startOffsetX; + + /** + * Vertical offset of upper-left corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_startOffsetY; + + /** + * Cell coordinates of bottom-right corner of shape, e.g. 'B2' + * + * @var string + */ + private $_endCoordinates; + + /** + * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width + * + * @var int + */ + private $_endOffsetX; + + /** + * Vertical offset of bottom-right corner of shape measured in 1/256 of row height + * + * @var int + */ + private $_endOffsetY; + + /** + * Set parent Shape Group Container + * + * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the parent Shape Group Container + * + * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Set whether this is a group shape + * + * @param boolean $value + */ + public function setSpgr($value = false) + { + $this->_spgr = $value; + } + + /** + * Get whether this is a group shape + * + * @return boolean + */ + public function getSpgr() + { + return $this->_spgr; + } + + /** + * Set the shape type + * + * @param int $value + */ + public function setSpType($value) + { + $this->_spType = $value; + } + + /** + * Get the shape type + * + * @return int + */ + public function getSpType() + { + return $this->_spType; + } + + /** + * Set the shape flag + * + * @param int $value + */ + public function setSpFlag($value) + { + $this->_spFlag = $value; + } + + /** + * Get the shape flag + * + * @return int + */ + public function getSpFlag() + { + return $this->_spFlag; + } + + /** + * Set the shape index + * + * @param int $value + */ + public function setSpId($value) + { + $this->_spId = $value; + } + + /** + * Get the shape index + * + * @return int + */ + public function getSpId() + { + return $this->_spId; + } + + /** + * Set an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the Shape Group Container + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get the collection of options + * + * @return array + */ + public function getOPTCollection() + { + return $this->_OPT; + } + + /** + * Set cell coordinates of upper-left corner of shape + * + * @param string $value + */ + public function setStartCoordinates($value = 'A1') + { + $this->_startCoordinates = $value; + } + + /** + * Get cell coordinates of upper-left corner of shape + * + * @return string + */ + public function getStartCoordinates() + { + return $this->_startCoordinates; + } + + /** + * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setStartOffsetX($startOffsetX = 0) + { + $this->_startOffsetX = $startOffsetX; + } + + /** + * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getStartOffsetX() + { + return $this->_startOffsetX; + } + + /** + * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @param int $startOffsetY + */ + public function setStartOffsetY($startOffsetY = 0) + { + $this->_startOffsetY = $startOffsetY; + } + + /** + * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getStartOffsetY() + { + return $this->_startOffsetY; + } + + /** + * Set cell coordinates of bottom-right corner of shape + * + * @param string $value + */ + public function setEndCoordinates($value = 'A1') + { + $this->_endCoordinates = $value; + } + + /** + * Get cell coordinates of bottom-right corner of shape + * + * @return string + */ + public function getEndCoordinates() + { + return $this->_endCoordinates; + } + + /** + * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @param int $startOffsetX + */ + public function setEndOffsetX($endOffsetX = 0) + { + $this->_endOffsetX = $endOffsetX; + } + + /** + * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width + * + * @return int + */ + public function getEndOffsetX() + { + return $this->_endOffsetX; + } + + /** + * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @param int $endOffsetY + */ + public function setEndOffsetY($endOffsetY = 0) + { + $this->_endOffsetY = $endOffsetY; + } + + /** + * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height + * + * @return int + */ + public function getEndOffsetY() + { + return $this->_endOffsetY; + } + + /** + * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and + * the dgContainer. A value of 1 = immediately within first spgrContainer + * Higher nesting level occurs if and only if spContainer is part of a shape group + * + * @return int Nesting level + */ + public function getNestingLevel() + { + $nestingLevel = 0; + + $parent = $this->getParent(); + while ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) { + ++$nestingLevel; + $parent = $parent->getParent(); + } + + return $nestingLevel; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer.php b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer.php new file mode 100755 index 0000000..bf5f61f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer.php @@ -0,0 +1,203 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer +{ + /** + * Maximum shape index of all shapes in all drawings increased by one + * + * @var int + */ + private $_spIdMax; + + /** + * Total number of drawings saved + * + * @var int + */ + private $_cDgSaved; + + /** + * Total number of shapes saved (including group shapes) + * + * @var int + */ + private $_cSpSaved; + + /** + * BLIP Store Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_bstoreContainer; + + /** + * Array of options for the drawing group + * + * @var array + */ + private $_OPT = array(); + + /** + * Array of identifier clusters containg information about the maximum shape identifiers + * + * @var array + */ + private $_IDCLs = array(); + + /** + * Get maximum shape index of all shapes in all drawings (plus one) + * + * @return int + */ + public function getSpIdMax() + { + return $this->_spIdMax; + } + + /** + * Set maximum shape index of all shapes in all drawings (plus one) + * + * @param int + */ + public function setSpIdMax($value) + { + $this->_spIdMax = $value; + } + + /** + * Get total number of drawings saved + * + * @return int + */ + public function getCDgSaved() + { + return $this->_cDgSaved; + } + + /** + * Set total number of drawings saved + * + * @param int + */ + public function setCDgSaved($value) + { + $this->_cDgSaved = $value; + } + + /** + * Get total number of shapes saved (including group shapes) + * + * @return int + */ + public function getCSpSaved() + { + return $this->_cSpSaved; + } + + /** + * Set total number of shapes saved (including group shapes) + * + * @param int + */ + public function setCSpSaved($value) + { + $this->_cSpSaved = $value; + } + + /** + * Get BLIP Store Container + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + public function getBstoreContainer() + { + return $this->_bstoreContainer; + } + + /** + * Set BLIP Store Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer + */ + public function setBstoreContainer($bstoreContainer) + { + $this->_bstoreContainer = $bstoreContainer; + } + + /** + * Set an option for the drawing group + * + * @param int $property The number specifies the option + * @param mixed $value + */ + public function setOPT($property, $value) + { + $this->_OPT[$property] = $value; + } + + /** + * Get an option for the drawing group + * + * @param int $property The number specifies the option + * @return mixed + */ + public function getOPT($property) + { + if (isset($this->_OPT[$property])) { + return $this->_OPT[$property]; + } + return null; + } + + /** + * Get identifier clusters + * + * @return array + */ + public function getIDCLs() + { + return $this->_IDCLs; + } + + /** + * Set identifier clusters. array(<drawingId> => <max shape id>, ...) + * + * @param array $pValue + */ + public function setIDCLs($pValue) + { + $this->_IDCLs = $pValue; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php new file mode 100755 index 0000000..d16bfc7 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php @@ -0,0 +1,65 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer +{ + /** + * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture) + * + * @var array + */ + private $_BSECollection = array(); + + /** + * Add a BLIP Store Entry + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE + */ + public function addBSE($BSE) + { + $this->_BSECollection[] = $BSE; + $BSE->setParent($this); + } + + /** + * Get the collection of BLIP Store Entries + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[] + */ + public function getBSECollection() + { + return $this->_BSECollection; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php new file mode 100755 index 0000000..ea3c52a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE +{ + const BLIPTYPE_ERROR = 0x00; + const BLIPTYPE_UNKNOWN = 0x01; + const BLIPTYPE_EMF = 0x02; + const BLIPTYPE_WMF = 0x03; + const BLIPTYPE_PICT = 0x04; + const BLIPTYPE_JPEG = 0x05; + const BLIPTYPE_PNG = 0x06; + const BLIPTYPE_DIB = 0x07; + const BLIPTYPE_TIFF = 0x11; + const BLIPTYPE_CMYKJPEG = 0x12; + + /** + * The parent BLIP Store Entry Container + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer + */ + private $_parent; + + /** + * The BLIP (Big Large Image or Picture) + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + private $_blip; + + /** + * The BLIP type + * + * @var int + */ + private $_blipType; + + /** + * Set parent BLIP Store Entry Container + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get the BLIP + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + */ + public function getBlip() + { + return $this->_blip; + } + + /** + * Set the BLIP + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip + */ + public function setBlip($blip) + { + $this->_blip = $blip; + $blip->setParent($this); + } + + /** + * Get the BLIP type + * + * @return int + */ + public function getBlipType() + { + return $this->_blipType; + } + + /** + * Set the BLIP type + * + * @param int + */ + public function setBlipType($blipType) + { + $this->_blipType = $blipType; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php new file mode 100755 index 0000000..802ce6d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php @@ -0,0 +1,91 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip + * + * @category PHPExcel + * @package PHPExcel_Shared_Escher + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip +{ + /** + * The parent BSE + * + * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE + */ + private $_parent; + + /** + * Raw image data + * + * @var string + */ + private $_data; + + /** + * Get the raw image data + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Set the raw image data + * + * @param string + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Set parent BSE + * + * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function setParent($parent) + { + $this->_parent = $parent; + } + + /** + * Get parent BSE + * + * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent + */ + public function getParent() + { + return $this->_parent; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Excel5.php b/extend/phpexcel/PHPExcel/Shared/Excel5.php new file mode 100755 index 0000000..927dace --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Excel5.php @@ -0,0 +1,317 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_Excel5 + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Excel5 +{ + /** + * Get the width of a column in pixels. We use the relationship y = ceil(7x) where + * x is the width in intrinsic Excel units (measuring width in number of normal characters) + * This holds for Arial 10 + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param string $col The column + * @return integer The width in pixels + */ + public static function sizeCol($sheet, $col = 'A') + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $columnDimensions = $sheet->getColumnDimensions(); + + // first find the true column width in pixels (uncollapsed and unhidden) + if ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) { + + // then we have column dimension with explicit width + $columnDimension = $columnDimensions[$col]; + $width = $columnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) { + + // then we have default column dimension with explicit width + $defaultColumnDimension = $sheet->getDefaultColumnDimension(); + $width = $defaultColumnDimension->getWidth(); + $pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font); + + } else { + + // we don't even have any default column dimension. Width depends on default font + $pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true); + } + + // now find the effective column width in pixels + if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) { + $effectivePixelWidth = 0; + } else { + $effectivePixelWidth = $pixelWidth; + } + + return $effectivePixelWidth; + } + + /** + * Convert the height of a cell from user's units to pixels. By interpolation + * the relationship is: y = 4/3x. If the height hasn't been set by the user we + * use the default value. If the row is hidden we use a value of zero. + * + * @param PHPExcel_Worksheet $sheet The sheet + * @param integer $row The row index (1-based) + * @return integer The width in pixels + */ + public static function sizeRow($sheet, $row = 1) + { + // default font of the workbook + $font = $sheet->getParent()->getDefaultStyle()->getFont(); + + $rowDimensions = $sheet->getRowDimensions(); + + // first find the true row height in pixels (uncollapsed and unhidden) + if ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) { + + // then we have a row dimension + $rowDimension = $rowDimensions[$row]; + $rowHeight = $rowDimension->getRowHeight(); + $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10 + + } else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) { + + // then we have a default row dimension with explicit height + $defaultRowDimension = $sheet->getDefaultRowDimension(); + $rowHeight = $defaultRowDimension->getRowHeight(); + $pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight); + + } else { + + // we don't even have any default row dimension. Height depends on default font + $pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font); + $pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight); + + } + + // now find the effective row height in pixels + if ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) { + $effectivePixelRowHeight = 0; + } else { + $effectivePixelRowHeight = $pixelRowHeight; + } + + return $effectivePixelRowHeight; + } + + /** + * Get the horizontal distance in pixels between two anchors + * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param string $startColumn + * @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width + * @param string $endColumn + * @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width + * @return integer Horizontal measured in pixels + */ + public static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0) + { + $distanceX = 0; + + // add the widths of the spanning columns + $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based + $endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based + for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) { + $distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i)); + } + + // correct for offsetX in startcell + $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024); + + // correct for offsetX in endcell + $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024)); + + return $distanceX; + } + + /** + * Get the vertical distance in pixels between two anchors + * The distanceY is found as sum of all the spanning rows minus two offsets + * + * @param PHPExcel_Worksheet $sheet + * @param integer $startRow (1-based) + * @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height + * @param integer $endRow (1-based) + * @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height + * @return integer Vertical distance measured in pixels + */ + public static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0) + { + $distanceY = 0; + + // add the widths of the spanning rows + for ($row = $startRow; $row <= $endRow; ++$row) { + $distanceY += self::sizeRow($sheet, $row); + } + + // correct for offsetX in startcell + $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256); + + // correct for offsetX in endcell + $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256)); + + return $distanceY; + } + + /** + * Convert 1-cell anchor coordinates to 2-cell anchor coordinates + * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications + * + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * + * @param PHPExcel_Worksheet $sheet + * @param string $coordinates E.g. 'A1' + * @param integer $offsetX Horizontal offset in pixels + * @param integer $offsetY Vertical offset in pixels + * @param integer $width Width in pixels + * @param integer $height Height in pixels + * @return array + */ + public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height) + { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates); + $col_start = PHPExcel_Cell::columnIndexFromString($column) - 1; + $row_start = $row - 1; + + $x1 = $offsetX; + $y1 = $offsetY; + + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= self::sizeRow($sheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= self::sizeRow($sheet, $row_end + 1)) { + $height -= self::sizeRow($sheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero height or width. + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (self::sizeRow($sheet, $row_start + 1) == 0) { + return; + } + if (self::sizeRow($sheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256; + $x2 = ($width + 1) / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object + + $startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1); + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1); + + $twoAnchor = array( + 'startCoordinates' => $startCoordinates, + 'startOffsetX' => $x1, + 'startOffsetY' => $y1, + 'endCoordinates' => $endCoordinates, + 'endOffsetX' => $x2, + 'endOffsetY' => $y2, + ); + + return $twoAnchor; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/File.php b/extend/phpexcel/PHPExcel/Shared/File.php new file mode 100755 index 0000000..70756a0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/File.php @@ -0,0 +1,178 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_File + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_File +{ + /* + * Use Temp or File Upload Temp for temporary files + * + * @protected + * @var boolean + */ + protected static $_useUploadTempDirectory = FALSE; + + + /** + * Set the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @param boolean $useUploadTempDir Use File Upload Temporary directory (true or false) + */ + public static function setUseUploadTempDirectory($useUploadTempDir = FALSE) { + self::$_useUploadTempDirectory = (boolean) $useUploadTempDir; + } // function setUseUploadTempDirectory() + + + /** + * Get the flag indicating whether the File Upload Temp directory should be used for temporary files + * + * @return boolean Use File Upload Temporary directory (true or false) + */ + public static function getUseUploadTempDirectory() { + return self::$_useUploadTempDirectory; + } // function getUseUploadTempDirectory() + + + /** + * Verify if a file exists + * + * @param string $pFilename Filename + * @return bool + */ + public static function file_exists($pFilename) { + // Sick construction, but it seems that + // file_exists returns strange values when + // doing the original file_exists on ZIP archives... + if ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) { + // Open ZIP file and verify if the file exists + $zipFile = substr($pFilename, 6, strpos($pFilename, '#') - 6); + $archiveFile = substr($pFilename, strpos($pFilename, '#') + 1); + + $zip = new ZipArchive(); + if ($zip->open($zipFile) === true) { + $returnValue = ($zip->getFromName($archiveFile) !== false); + $zip->close(); + return $returnValue; + } else { + return false; + } + } else { + // Regular file_exists + return file_exists($pFilename); + } + } + + /** + * Returns canonicalized absolute pathname, also for ZIP archives + * + * @param string $pFilename + * @return string + */ + public static function realpath($pFilename) { + // Returnvalue + $returnValue = ''; + + // Try using realpath() + if (file_exists($pFilename)) { + $returnValue = realpath($pFilename); + } + + // Found something? + if ($returnValue == '' || ($returnValue === NULL)) { + $pathArray = explode('/' , $pFilename); + while(in_array('..', $pathArray) && $pathArray[0] != '..') { + for ($i = 0; $i < count($pathArray); ++$i) { + if ($pathArray[$i] == '..' && $i > 0) { + unset($pathArray[$i]); + unset($pathArray[$i - 1]); + break; + } + } + } + $returnValue = implode('/', $pathArray); + } + + // Return + return $returnValue; + } + + /** + * Get the systems temporary directory. + * + * @return string + */ + public static function sys_get_temp_dir() + { + if (self::$_useUploadTempDirectory) { + // use upload-directory when defined to allow running on environments having very restricted + // open_basedir configs + if (ini_get('upload_tmp_dir') !== FALSE) { + if ($temp = ini_get('upload_tmp_dir')) { + if (file_exists($temp)) + return realpath($temp); + } + } + } + + // sys_get_temp_dir is only available since PHP 5.2.1 + // http://php.net/manual/en/function.sys-get-temp-dir.php#94119 + if ( !function_exists('sys_get_temp_dir')) { + if ($temp = getenv('TMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TEMP') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + if ($temp = getenv('TMPDIR') ) { + if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); } + } + + // trick for creating a file in system's temporary dir + // without knowing the path of the system's temporary dir + $temp = tempnam(__FILE__, ''); + if (file_exists($temp)) { + unlink($temp); + return realpath(dirname($temp)); + } + + return null; + } + + // use ordinary built-in PHP function + // There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only + // be called if we're running 5.2.1 or earlier + return realpath(sys_get_temp_dir()); + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/Font.php b/extend/phpexcel/PHPExcel/Shared/Font.php new file mode 100755 index 0000000..203d4ec --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/Font.php @@ -0,0 +1,775 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Font + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_Font +{ + /* Methods for resolving autosize value */ + const AUTOSIZE_METHOD_APPROX = 'approx'; + const AUTOSIZE_METHOD_EXACT = 'exact'; + + private static $_autoSizeMethods = array( + self::AUTOSIZE_METHOD_APPROX, + self::AUTOSIZE_METHOD_EXACT, + ); + + /** Character set codes used by BIFF5-8 in Font records */ + const CHARSET_ANSI_LATIN = 0x00; + const CHARSET_SYSTEM_DEFAULT = 0x01; + const CHARSET_SYMBOL = 0x02; + const CHARSET_APPLE_ROMAN = 0x4D; + const CHARSET_ANSI_JAPANESE_SHIFTJIS = 0x80; + const CHARSET_ANSI_KOREAN_HANGUL = 0x81; + const CHARSET_ANSI_KOREAN_JOHAB = 0x82; + const CHARSET_ANSI_CHINESE_SIMIPLIFIED = 0x86; // gb2312 + const CHARSET_ANSI_CHINESE_TRADITIONAL = 0x88; // big5 + const CHARSET_ANSI_GREEK = 0xA1; + const CHARSET_ANSI_TURKISH = 0xA2; + const CHARSET_ANSI_VIETNAMESE = 0xA3; + const CHARSET_ANSI_HEBREW = 0xB1; + const CHARSET_ANSI_ARABIC = 0xB2; + const CHARSET_ANSI_BALTIC = 0xBA; + const CHARSET_ANSI_CYRILLIC = 0xCC; + const CHARSET_ANSI_THAI = 0xDD; + const CHARSET_ANSI_LATIN_II = 0xEE; + const CHARSET_OEM_LATIN_I = 0xFF; + + // XXX: Constants created! + /** Font filenames */ + const ARIAL = 'arial.ttf'; + const ARIAL_BOLD = 'arialbd.ttf'; + const ARIAL_ITALIC = 'ariali.ttf'; + const ARIAL_BOLD_ITALIC = 'arialbi.ttf'; + + const CALIBRI = 'CALIBRI.TTF'; + const CALIBRI_BOLD = 'CALIBRIB.TTF'; + const CALIBRI_ITALIC = 'CALIBRII.TTF'; + const CALIBRI_BOLD_ITALIC = 'CALIBRIZ.TTF'; + + const COMIC_SANS_MS = 'comic.ttf'; + const COMIC_SANS_MS_BOLD = 'comicbd.ttf'; + + const COURIER_NEW = 'cour.ttf'; + const COURIER_NEW_BOLD = 'courbd.ttf'; + const COURIER_NEW_ITALIC = 'couri.ttf'; + const COURIER_NEW_BOLD_ITALIC = 'courbi.ttf'; + + const GEORGIA = 'georgia.ttf'; + const GEORGIA_BOLD = 'georgiab.ttf'; + const GEORGIA_ITALIC = 'georgiai.ttf'; + const GEORGIA_BOLD_ITALIC = 'georgiaz.ttf'; + + const IMPACT = 'impact.ttf'; + + const LIBERATION_SANS = 'LiberationSans-Regular.ttf'; + const LIBERATION_SANS_BOLD = 'LiberationSans-Bold.ttf'; + const LIBERATION_SANS_ITALIC = 'LiberationSans-Italic.ttf'; + const LIBERATION_SANS_BOLD_ITALIC = 'LiberationSans-BoldItalic.ttf'; + + const LUCIDA_CONSOLE = 'lucon.ttf'; + const LUCIDA_SANS_UNICODE = 'l_10646.ttf'; + + const MICROSOFT_SANS_SERIF = 'micross.ttf'; + + const PALATINO_LINOTYPE = 'pala.ttf'; + const PALATINO_LINOTYPE_BOLD = 'palab.ttf'; + const PALATINO_LINOTYPE_ITALIC = 'palai.ttf'; + const PALATINO_LINOTYPE_BOLD_ITALIC = 'palabi.ttf'; + + const SYMBOL = 'symbol.ttf'; + + const TAHOMA = 'tahoma.ttf'; + const TAHOMA_BOLD = 'tahomabd.ttf'; + + const TIMES_NEW_ROMAN = 'times.ttf'; + const TIMES_NEW_ROMAN_BOLD = 'timesbd.ttf'; + const TIMES_NEW_ROMAN_ITALIC = 'timesi.ttf'; + const TIMES_NEW_ROMAN_BOLD_ITALIC = 'timesbi.ttf'; + + const TREBUCHET_MS = 'trebuc.ttf'; + const TREBUCHET_MS_BOLD = 'trebucbd.ttf'; + const TREBUCHET_MS_ITALIC = 'trebucit.ttf'; + const TREBUCHET_MS_BOLD_ITALIC = 'trebucbi.ttf'; + + const VERDANA = 'verdana.ttf'; + const VERDANA_BOLD = 'verdanab.ttf'; + const VERDANA_ITALIC = 'verdanai.ttf'; + const VERDANA_BOLD_ITALIC = 'verdanaz.ttf'; + + /** + * AutoSize method + * + * @var string + */ + private static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX; + + /** + * Path to folder containing TrueType font .ttf files + * + * @var string + */ + private static $trueTypeFontPath = null; + + /** + * How wide is a default column for a given default font and size? + * Empirical data found by inspecting real Excel files and reading off the pixel width + * in Microsoft Office Excel 2007. + * + * @var array + */ + public static $defaultColumnWidths = array( + 'Arial' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 64, 'width' => 9.14062500), + 10 => array('px' => 64, 'width' => 9.14062500), + ), + 'Calibri' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 56, 'width' => 9.33203125), + 9 => array('px' => 56, 'width' => 9.33203125), + 10 => array('px' => 64, 'width' => 9.14062500), + 11 => array('px' => 64, 'width' => 9.14062500), + ), + 'Verdana' => array( + 1 => array('px' => 24, 'width' => 12.00000000), + 2 => array('px' => 24, 'width' => 12.00000000), + 3 => array('px' => 32, 'width' => 10.66406250), + 4 => array('px' => 32, 'width' => 10.66406250), + 5 => array('px' => 40, 'width' => 10.00000000), + 6 => array('px' => 48, 'width' => 9.59765625), + 7 => array('px' => 48, 'width' => 9.59765625), + 8 => array('px' => 64, 'width' => 9.14062500), + 9 => array('px' => 72, 'width' => 9.00000000), + 10 => array('px' => 72, 'width' => 9.00000000), + ), + ); + + /** + * Set autoSize method + * + * @param string $pValue + * @return boolean Success or failure + */ + public static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX) + { + if (!in_array($pValue,self::$_autoSizeMethods)) { + return FALSE; + } + + self::$autoSizeMethod = $pValue; + + return TRUE; + } + + /** + * Get autoSize method + * + * @return string + */ + public static function getAutoSizeMethod() + { + return self::$autoSizeMethod; + } + + /** + * Set the path to the folder containing .ttf files. There should be a trailing slash. + * Typical locations on variout some platforms: + * <ul> + * <li>C:/Windows/Fonts/</li> + * <li>/usr/share/fonts/truetype/</li> + * <li>~/.fonts/</li> + * </ul> + * + * @param string $pValue + */ + public static function setTrueTypeFontPath($pValue = '') + { + self::$trueTypeFontPath = $pValue; + } + + /** + * Get the path to the folder containing .ttf files. + * + * @return string + */ + public static function getTrueTypeFontPath() + { + return self::$trueTypeFontPath; + } + + /** + * Calculate an (approximate) OpenXML column width, based on font size and text contained + * + * @param PHPExcel_Style_Font $font Font object + * @param PHPExcel_RichText|string $cellText Text to calculate width + * @param integer $rotation Rotation angle + * @param PHPExcel_Style_Font|NULL $defaultFont Font object + * @return integer Column width + */ + public static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) { + + // If it is rich text, use plain text + if ($cellText instanceof PHPExcel_RichText) { + $cellText = $cellText->getPlainText(); + } + + // Special case if there are one or more newline characters ("\n") + if (strpos($cellText, "\n") !== false) { + $lineTexts = explode("\n", $cellText); + $lineWitdhs = array(); + foreach ($lineTexts as $lineText) { + $lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont); + } + return max($lineWidths); // width of longest line in cell + } + + // Try to get the exact text width in pixels + try { + // If autosize method is set to 'approx', use approximation + if (self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX) { + throw new PHPExcel_Exception('AutoSize method is set to approx'); + } + + // Width of text in pixels excl. padding + $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation); + + // Excel adds some padding, use 1.07 of the width of an 'n' glyph + $columnWidth += ceil(self::getTextWidthPixelsExact('0', $font, 0) * 1.07); // pixels incl. padding + + } catch (PHPExcel_Exception $e) { + // Width of text in pixels excl. padding, approximation + $columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation); + + // Excel adds some padding, just use approx width of 'n' glyph + $columnWidth += self::getTextWidthPixelsApprox('n', $font, 0); + } + + // Convert from pixel width to column width + $columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont); + + // Return + return round($columnWidth, 6); + } + + /** + * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $text + * @param PHPExcel_Style_Font + * @param int $rotation + * @return int + * @throws PHPExcel_Exception + */ + public static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) { + if (!function_exists('imagettfbbox')) { + throw new PHPExcel_Exception('GD library needs to be enabled'); + } + + // font size should really be supplied in pixels in GD2, + // but since GD2 seems to assume 72dpi, pixels and points are the same + $fontFile = self::getTrueTypeFontFileFromFont($font); + $textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text); + + // Get corners positions + $lowerLeftCornerX = $textBox[0]; + $lowerLeftCornerY = $textBox[1]; + $lowerRightCornerX = $textBox[2]; + $lowerRightCornerY = $textBox[3]; + $upperRightCornerX = $textBox[4]; + $upperRightCornerY = $textBox[5]; + $upperLeftCornerX = $textBox[6]; + $upperLeftCornerY = $textBox[7]; + + // Consider the rotation when calculating the width + $textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX); + + return $textWidth; + } + + /** + * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle + * + * @param string $columnText + * @param PHPExcel_Style_Font $font + * @param int $rotation + * @return int Text width in pixels (no padding added) + */ + public static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0) + { + $fontName = $font->getName(); + $fontSize = $font->getSize(); + + // Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size. + switch ($fontName) { + case 'Calibri': + // value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font. + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + + case 'Arial': + // value 7 was found via interpolation by inspecting real Excel files with Arial 10 font. + $columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + case 'Verdana': + // value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font. + $columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size + break; + + default: + // just assume Calibri + $columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText)); + $columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size + break; + } + + // Calculate approximate rotated column width + if ($rotation !== 0) { + if ($rotation == -165) { + // stacked text + $columnWidth = 4; // approximation + } else { + // rotated text + $columnWidth = $columnWidth * cos(deg2rad($rotation)) + + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation + } + } + + // pixel width is an integer + $columnWidth = (int) $columnWidth; + return $columnWidth; + } + + /** + * Calculate an (approximate) pixel size, based on a font points size + * + * @param int $fontSizeInPoints Font size (in points) + * @return int Font size (in pixels) + */ + public static function fontSizeToPixels($fontSizeInPoints = 11) { + return (int) ((4 / 3) * $fontSizeInPoints); + } + + /** + * Calculate an (approximate) pixel size, based on inch size + * + * @param int $sizeInInch Font size (in inch) + * @return int Size (in pixels) + */ + public static function inchSizeToPixels($sizeInInch = 1) { + return ($sizeInInch * 96); + } + + /** + * Calculate an (approximate) pixel size, based on centimeter size + * + * @param int $sizeInCm Font size (in centimeters) + * @return int Size (in pixels) + */ + public static function centimeterSizeToPixels($sizeInCm = 1) { + return ($sizeInCm * 37.795275591); + } + + /** + * Returns the font path given the font + * + * @param PHPExcel_Style_Font + * @return string Path to TrueType font file + */ + public static function getTrueTypeFontFileFromFont($font) { + if (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) { + throw new PHPExcel_Exception('Valid directory to TrueType Font files not specified'); + } + + $name = $font->getName(); + $bold = $font->getBold(); + $italic = $font->getItalic(); + + // Check if we can map font to true type font file + switch ($name) { + case 'Arial': + $fontFile = ( + $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD) + : ($italic ? self::ARIAL_ITALIC : self::ARIAL) + ); + break; + + case 'Calibri': + $fontFile = ( + $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD) + : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI) + ); + break; + + case 'Courier New': + $fontFile = ( + $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD) + : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW) + ); + break; + + case 'Comic Sans MS': + $fontFile = ( + $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS + ); + break; + + case 'Georgia': + $fontFile = ( + $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD) + : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA) + ); + break; + + case 'Impact': + $fontFile = self::IMPACT; + break; + + case 'Liberation Sans': + $fontFile = ( + $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD) + : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS) + ); + break; + + case 'Lucida Console': + $fontFile = self::LUCIDA_CONSOLE; + break; + + case 'Lucida Sans Unicode': + $fontFile = self::LUCIDA_SANS_UNICODE; + break; + + case 'Microsoft Sans Serif': + $fontFile = self::MICROSOFT_SANS_SERIF; + break; + + case 'Palatino Linotype': + $fontFile = ( + $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD) + : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE) + ); + break; + + case 'Symbol': + $fontFile = self::SYMBOL; + break; + + case 'Tahoma': + $fontFile = ( + $bold ? self::TAHOMA_BOLD : self::TAHOMA + ); + break; + + case 'Times New Roman': + $fontFile = ( + $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD) + : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN) + ); + break; + + case 'Trebuchet MS': + $fontFile = ( + $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD) + : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS) + ); + break; + + case 'Verdana': + $fontFile = ( + $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD) + : ($italic ? self::VERDANA_ITALIC : self::VERDANA) + ); + break; + + default: + throw new PHPExcel_Exception('Unknown font name "'. $name .'". Cannot map to TrueType font file'); + break; + } + + $fontFile = self::$trueTypeFontPath . $fontFile; + + // Check if file actually exists + if (!file_exists($fontFile)) { + throw New PHPExcel_Exception('TrueType Font file not found'); + } + + return $fontFile; + } + + /** + * Returns the associated charset for the font name. + * + * @param string $name Font name + * @return int Character set code + */ + public static function getCharsetFromFontName($name) + { + switch ($name) { + // Add more cases. Check FONT records in real Excel files. + case 'EucrosiaUPC': return self::CHARSET_ANSI_THAI; + case 'Wingdings': return self::CHARSET_SYMBOL; + case 'Wingdings 2': return self::CHARSET_SYMBOL; + case 'Wingdings 3': return self::CHARSET_SYMBOL; + default: return self::CHARSET_ANSI_LATIN; + } + } + + /** + * Get the effective column width for columns without a column dimension or column with width -1 + * For example, for Calibri 11 this is 9.140625 (64 px) + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @param boolean $pPixels true = return column width in pixels, false = return in OOXML units + * @return mixed Column width + */ + public static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false) + { + if (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) { + // Exact width can be determined + $columnWidth = $pPixels ? + self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px'] + : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width']; + + } else { + // We don't have data for this particular font and size, use approximation by + // extrapolating from Calibri 11 + $columnWidth = $pPixels ? + self::$defaultColumnWidths['Calibri'][11]['px'] + : self::$defaultColumnWidths['Calibri'][11]['width']; + $columnWidth = $columnWidth * $font->getSize() / 11; + + // Round pixels to closest integer + if ($pPixels) { + $columnWidth = (int) round($columnWidth); + } + } + + return $columnWidth; + } + + /** + * Get the effective row height for rows without a row dimension or rows with height -1 + * For example, for Calibri 11 this is 15 points + * + * @param PHPExcel_Style_Font $font The workbooks default font + * @return float Row height in points + */ + public static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font) + { + switch ($font->getName()) { + case 'Arial': + switch ($font->getSize()) { + case 10: + // inspection of Arial 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Arial 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Arial 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Arial 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Arial 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Arial 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Arial 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Arial 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Arial 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + case 'Calibri': + switch ($font->getSize()) { + case 11: + // inspection of Calibri 11 workbook says 15.00pt ~20px + $rowHeight = 15; + break; + + case 10: + // inspection of Calibri 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Calibri 9 workbook says 12.00pt ~16px + $rowHeight = 12; + break; + + case 8: + // inspection of Calibri 8 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 7: + // inspection of Calibri 7 workbook says 9.00pt ~12px + $rowHeight = 9; + break; + + case 6: + case 5: + // inspection of Calibri 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Calibri 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Calibri 3 workbook says 6.00pt ~8px + $rowHeight = 6.00; + break; + + case 2: + case 1: + // inspection of Calibri 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Calibri 11 workbook as an approximation, extrapolation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + break; + + case 'Verdana': + switch ($font->getSize()) { + case 10: + // inspection of Verdana 10 workbook says 12.75pt ~17px + $rowHeight = 12.75; + break; + + case 9: + // inspection of Verdana 9 workbook says 11.25pt ~15px + $rowHeight = 11.25; + break; + + case 8: + // inspection of Verdana 8 workbook says 10.50pt ~14px + $rowHeight = 10.50; + break; + + case 7: + // inspection of Verdana 7 workbook says 9.00pt ~12px + $rowHeight = 9.00; + break; + + case 6: + case 5: + // inspection of Verdana 5,6 workbook says 8.25pt ~11px + $rowHeight = 8.25; + break; + + case 4: + // inspection of Verdana 4 workbook says 6.75pt ~9px + $rowHeight = 6.75; + break; + + case 3: + // inspection of Verdana 3 workbook says 6.00pt ~8px + $rowHeight = 6; + break; + + case 2: + case 1: + // inspection of Verdana 1,2 workbook says 5.25pt ~7px + $rowHeight = 5.25; + break; + + default: + // use Verdana 10 workbook as an approximation, extrapolation + $rowHeight = 12.75 * $font->getSize() / 10; + break; + } + break; + + default: + // just use Calibri as an approximation + $rowHeight = 15 * $font->getSize() / 11; + break; + } + + return $rowHeight; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT b/extend/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT new file mode 100755 index 0000000..1c18a5d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/CHANGELOG.TXT @@ -0,0 +1,16 @@ +Mar 1, 2005 11:15 AST by PM + ++ For consistency, renamed Math.php to Maths.java, utils to util, + tests to test, docs to doc - + ++ Removed conditional logic from top of Matrix class. + ++ Switched to using hypo function in Maths.php for all php-hypot calls. + NOTE TO SELF: Need to make sure that all decompositions have been + switched over to using the bundled hypo. + +Feb 25, 2005 at 10:00 AST by PM + ++ Recommend using simpler Error.php instead of JAMA_Error.php but + can be persuaded otherwise. + diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php b/extend/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php new file mode 100755 index 0000000..cfbaa53 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/CholeskyDecomposition.php @@ -0,0 +1,149 @@ +<?php +/** + * @package JAMA + * + * Cholesky decomposition class + * + * For a symmetric, positive definite matrix A, the Cholesky decomposition + * is an lower triangular matrix L so that A = L*L'. + * + * If the matrix is not symmetric or positive definite, the constructor + * returns a partial decomposition and sets an internal flag that may + * be queried by the isSPD() method. + * + * @author Paul Meagher + * @author Michael Bommarito + * @version 1.2 + */ +class CholeskyDecomposition { + + /** + * Decomposition storage + * @var array + * @access private + */ + private $L = array(); + + /** + * Matrix row and column dimension + * @var int + * @access private + */ + private $m; + + /** + * Symmetric positive definite flag + * @var boolean + * @access private + */ + private $isspd = true; + + + /** + * CholeskyDecomposition + * + * Class constructor - decomposes symmetric positive definite matrix + * @param mixed Matrix square symmetric positive definite matrix + */ + public function __construct($A = null) { + if ($A instanceof Matrix) { + $this->L = $A->getArray(); + $this->m = $A->getRowDimension(); + + for($i = 0; $i < $this->m; ++$i) { + for($j = $i; $j < $this->m; ++$j) { + for($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) { + $sum -= $this->L[$i][$k] * $this->L[$j][$k]; + } + if ($i == $j) { + if ($sum >= 0) { + $this->L[$i][$i] = sqrt($sum); + } else { + $this->isspd = false; + } + } else { + if ($this->L[$i][$i] != 0) { + $this->L[$j][$i] = $sum / $this->L[$i][$i]; + } + } + } + + for ($k = $i+1; $k < $this->m; ++$k) { + $this->L[$i][$k] = 0.0; + } + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function __construct() + + + /** + * Is the matrix symmetric and positive definite? + * + * @return boolean + */ + public function isSPD() { + return $this->isspd; + } // function isSPD() + + + /** + * getL + * + * Return triangular factor. + * @return Matrix Lower triangular matrix + */ + public function getL() { + return new Matrix($this->L); + } // function getL() + + + /** + * Solve A*X = B + * + * @param $B Row-equal matrix + * @return Matrix L * L' * X = B + */ + public function solve($B = null) { + if ($B instanceof Matrix) { + if ($B->getRowDimension() == $this->m) { + if ($this->isspd) { + $X = $B->getArrayCopy(); + $nx = $B->getColumnDimension(); + + for ($k = 0; $k < $this->m; ++$k) { + for ($i = $k + 1; $i < $this->m; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k]; + } + } + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + } + + for ($k = $this->m - 1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->L[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i]; + } + } + } + + return new Matrix($X, $this->m, $nx); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException)); + } + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } // function solve() + +} // class CholeskyDecomposition diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php b/extend/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php new file mode 100755 index 0000000..2a696d0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php @@ -0,0 +1,862 @@ +<?php +/** + * @package JAMA + * + * Class to obtain eigenvalues and eigenvectors of a real matrix. + * + * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D + * is diagonal and the eigenvector matrix V is orthogonal (i.e. + * A = V.times(D.times(V.transpose())) and V.times(V.transpose()) + * equals the identity matrix). + * + * If A is not symmetric, then the eigenvalue matrix D is block diagonal + * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, + * lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The + * columns of V represent the eigenvectors in the sense that A*V = V*D, + * i.e. A.times(V) equals V.times(D). The matrix V may be badly + * conditioned, or even singular, so the validity of the equation + * A = V*D*inverse(V) depends upon V.cond(). + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class EigenvalueDecomposition { + + /** + * Row and column dimension (square matrix). + * @var int + */ + private $n; + + /** + * Internal symmetry flag. + * @var int + */ + private $issymmetric; + + /** + * Arrays for internal storage of eigenvalues. + * @var array + */ + private $d = array(); + private $e = array(); + + /** + * Array for internal storage of eigenvectors. + * @var array + */ + private $V = array(); + + /** + * Array for internal storage of nonsymmetric Hessenberg form. + * @var array + */ + private $H = array(); + + /** + * Working storage for nonsymmetric algorithm. + * @var array + */ + private $ort; + + /** + * Used for complex scalar division. + * @var float + */ + private $cdivr; + private $cdivi; + + + /** + * Symmetric Householder reduction to tridiagonal form. + * + * @access private + */ + private function tred2 () { + // This is derived from the Algol procedures tred2 by + // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + // Fortran subroutine in EISPACK. + $this->d = $this->V[$this->n-1]; + // Householder reduction to tridiagonal form. + for ($i = $this->n-1; $i > 0; --$i) { + $i_ = $i -1; + // Scale to avoid under/overflow. + $h = $scale = 0.0; + $scale += array_sum(array_map(abs, $this->d)); + if ($scale == 0.0) { + $this->e[$i] = $this->d[$i_]; + $this->d = array_slice($this->V[$i_], 0, $i_); + for ($j = 0; $j < $i; ++$j) { + $this->V[$j][$i] = $this->V[$i][$j] = 0.0; + } + } else { + // Generate Householder vector. + for ($k = 0; $k < $i; ++$k) { + $this->d[$k] /= $scale; + $h += pow($this->d[$k], 2); + } + $f = $this->d[$i_]; + $g = sqrt($h); + if ($f > 0) { + $g = -$g; + } + $this->e[$i] = $scale * $g; + $h = $h - $f * $g; + $this->d[$i_] = $f - $g; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] = 0.0; + } + // Apply similarity transformation to remaining columns. + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $this->V[$j][$i] = $f; + $g = $this->e[$j] + $this->V[$j][$j] * $f; + for ($k = $j+1; $k <= $i_; ++$k) { + $g += $this->V[$k][$j] * $this->d[$k]; + $this->e[$k] += $this->V[$k][$j] * $f; + } + $this->e[$j] = $g; + } + $f = 0.0; + for ($j = 0; $j < $i; ++$j) { + $this->e[$j] /= $h; + $f += $this->e[$j] * $this->d[$j]; + } + $hh = $f / (2 * $h); + for ($j=0; $j < $i; ++$j) { + $this->e[$j] -= $hh * $this->d[$j]; + } + for ($j = 0; $j < $i; ++$j) { + $f = $this->d[$j]; + $g = $this->e[$j]; + for ($k = $j; $k <= $i_; ++$k) { + $this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]); + } + $this->d[$j] = $this->V[$i-1][$j]; + $this->V[$i][$j] = 0.0; + } + } + $this->d[$i] = $h; + } + + // Accumulate transformations. + for ($i = 0; $i < $this->n-1; ++$i) { + $this->V[$this->n-1][$i] = $this->V[$i][$i]; + $this->V[$i][$i] = 1.0; + $h = $this->d[$i+1]; + if ($h != 0.0) { + for ($k = 0; $k <= $i; ++$k) { + $this->d[$k] = $this->V[$k][$i+1] / $h; + } + for ($j = 0; $j <= $i; ++$j) { + $g = 0.0; + for ($k = 0; $k <= $i; ++$k) { + $g += $this->V[$k][$i+1] * $this->V[$k][$j]; + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$j] -= $g * $this->d[$k]; + } + } + } + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$i+1] = 0.0; + } + } + + $this->d = $this->V[$this->n-1]; + $this->V[$this->n-1] = array_fill(0, $j, 0.0); + $this->V[$this->n-1][$this->n-1] = 1.0; + $this->e[0] = 0.0; + } + + + /** + * Symmetric tridiagonal QL algorithm. + * + * This is derived from the Algol procedures tql2, by + * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for + * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function tql2() { + for ($i = 1; $i < $this->n; ++$i) { + $this->e[$i-1] = $this->e[$i]; + } + $this->e[$this->n-1] = 0.0; + $f = 0.0; + $tst1 = 0.0; + $eps = pow(2.0,-52.0); + + for ($l = 0; $l < $this->n; ++$l) { + // Find small subdiagonal element + $tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l])); + $m = $l; + while ($m < $this->n) { + if (abs($this->e[$m]) <= $eps * $tst1) + break; + ++$m; + } + // If m == l, $this->d[l] is an eigenvalue, + // otherwise, iterate. + if ($m > $l) { + $iter = 0; + do { + // Could check iteration count here. + $iter += 1; + // Compute implicit shift + $g = $this->d[$l]; + $p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]); + $r = hypo($p, 1.0); + if ($p < 0) + $r *= -1; + $this->d[$l] = $this->e[$l] / ($p + $r); + $this->d[$l+1] = $this->e[$l] * ($p + $r); + $dl1 = $this->d[$l+1]; + $h = $g - $this->d[$l]; + for ($i = $l + 2; $i < $this->n; ++$i) + $this->d[$i] -= $h; + $f += $h; + // Implicit QL transformation. + $p = $this->d[$m]; + $c = 1.0; + $c2 = $c3 = $c; + $el1 = $this->e[$l + 1]; + $s = $s2 = 0.0; + for ($i = $m-1; $i >= $l; --$i) { + $c3 = $c2; + $c2 = $c; + $s2 = $s; + $g = $c * $this->e[$i]; + $h = $c * $p; + $r = hypo($p, $this->e[$i]); + $this->e[$i+1] = $s * $r; + $s = $this->e[$i] / $r; + $c = $p / $r; + $p = $c * $this->d[$i] - $s * $g; + $this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]); + // Accumulate transformation. + for ($k = 0; $k < $this->n; ++$k) { + $h = $this->V[$k][$i+1]; + $this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h; + $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h; + } + } + $p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1; + $this->e[$l] = $s * $p; + $this->d[$l] = $c * $p; + // Check for convergence. + } while (abs($this->e[$l]) > $eps * $tst1); + } + $this->d[$l] = $this->d[$l] + $f; + $this->e[$l] = 0.0; + } + + // Sort eigenvalues and corresponding vectors. + for ($i = 0; $i < $this->n - 1; ++$i) { + $k = $i; + $p = $this->d[$i]; + for ($j = $i+1; $j < $this->n; ++$j) { + if ($this->d[$j] < $p) { + $k = $j; + $p = $this->d[$j]; + } + } + if ($k != $i) { + $this->d[$k] = $this->d[$i]; + $this->d[$i] = $p; + for ($j = 0; $j < $this->n; ++$j) { + $p = $this->V[$j][$i]; + $this->V[$j][$i] = $this->V[$j][$k]; + $this->V[$j][$k] = $p; + } + } + } + } + + + /** + * Nonsymmetric reduction to Hessenberg form. + * + * This is derived from the Algol procedures orthes and ortran, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutines in EISPACK. + * + * @access private + */ + private function orthes () { + $low = 0; + $high = $this->n-1; + + for ($m = $low+1; $m <= $high-1; ++$m) { + // Scale column. + $scale = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $scale = $scale + abs($this->H[$i][$m-1]); + } + if ($scale != 0.0) { + // Compute Householder transformation. + $h = 0.0; + for ($i = $high; $i >= $m; --$i) { + $this->ort[$i] = $this->H[$i][$m-1] / $scale; + $h += $this->ort[$i] * $this->ort[$i]; + } + $g = sqrt($h); + if ($this->ort[$m] > 0) { + $g *= -1; + } + $h -= $this->ort[$m] * $g; + $this->ort[$m] -= $g; + // Apply Householder similarity transformation + // H = (I -u * u' / h) * H * (I -u * u') / h) + for ($j = $m; $j < $this->n; ++$j) { + $f = 0.0; + for ($i = $high; $i >= $m; --$i) { + $f += $this->ort[$i] * $this->H[$i][$j]; + } + $f /= $h; + for ($i = $m; $i <= $high; ++$i) { + $this->H[$i][$j] -= $f * $this->ort[$i]; + } + } + for ($i = 0; $i <= $high; ++$i) { + $f = 0.0; + for ($j = $high; $j >= $m; --$j) { + $f += $this->ort[$j] * $this->H[$i][$j]; + } + $f = $f / $h; + for ($j = $m; $j <= $high; ++$j) { + $this->H[$i][$j] -= $f * $this->ort[$j]; + } + } + $this->ort[$m] = $scale * $this->ort[$m]; + $this->H[$m][$m-1] = $scale * $g; + } + } + + // Accumulate transformations (Algol's ortran). + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $this->V[$i][$j] = ($i == $j ? 1.0 : 0.0); + } + } + for ($m = $high-1; $m >= $low+1; --$m) { + if ($this->H[$m][$m-1] != 0.0) { + for ($i = $m+1; $i <= $high; ++$i) { + $this->ort[$i] = $this->H[$i][$m-1]; + } + for ($j = $m; $j <= $high; ++$j) { + $g = 0.0; + for ($i = $m; $i <= $high; ++$i) { + $g += $this->ort[$i] * $this->V[$i][$j]; + } + // Double division avoids possible underflow + $g = ($g / $this->ort[$m]) / $this->H[$m][$m-1]; + for ($i = $m; $i <= $high; ++$i) { + $this->V[$i][$j] += $g * $this->ort[$i]; + } + } + } + } + } + + + /** + * Performs complex division. + * + * @access private + */ + private function cdiv($xr, $xi, $yr, $yi) { + if (abs($yr) > abs($yi)) { + $r = $yi / $yr; + $d = $yr + $r * $yi; + $this->cdivr = ($xr + $r * $xi) / $d; + $this->cdivi = ($xi - $r * $xr) / $d; + } else { + $r = $yr / $yi; + $d = $yi + $r * $yr; + $this->cdivr = ($r * $xr + $xi) / $d; + $this->cdivi = ($r * $xi - $xr) / $d; + } + } + + + /** + * Nonsymmetric reduction from Hessenberg to real Schur form. + * + * Code is derived from the Algol procedure hqr2, + * by Martin and Wilkinson, Handbook for Auto. Comp., + * Vol.ii-Linear Algebra, and the corresponding + * Fortran subroutine in EISPACK. + * + * @access private + */ + private function hqr2 () { + // Initialize + $nn = $this->n; + $n = $nn - 1; + $low = 0; + $high = $nn - 1; + $eps = pow(2.0, -52.0); + $exshift = 0.0; + $p = $q = $r = $s = $z = 0; + // Store roots isolated by balanc and compute matrix norm + $norm = 0.0; + + for ($i = 0; $i < $nn; ++$i) { + if (($i < $low) OR ($i > $high)) { + $this->d[$i] = $this->H[$i][$i]; + $this->e[$i] = 0.0; + } + for ($j = max($i-1, 0); $j < $nn; ++$j) { + $norm = $norm + abs($this->H[$i][$j]); + } + } + + // Outer loop over eigenvalue index + $iter = 0; + while ($n >= $low) { + // Look for single small sub-diagonal element + $l = $n; + while ($l > $low) { + $s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]); + if ($s == 0.0) { + $s = $norm; + } + if (abs($this->H[$l][$l-1]) < $eps * $s) { + break; + } + --$l; + } + // Check for convergence + // One root found + if ($l == $n) { + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->d[$n] = $this->H[$n][$n]; + $this->e[$n] = 0.0; + --$n; + $iter = 0; + // Two roots found + } else if ($l == $n-1) { + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + $p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0; + $q = $p * $p + $w; + $z = sqrt(abs($q)); + $this->H[$n][$n] = $this->H[$n][$n] + $exshift; + $this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift; + $x = $this->H[$n][$n]; + // Real pair + if ($q >= 0) { + if ($p >= 0) { + $z = $p + $z; + } else { + $z = $p - $z; + } + $this->d[$n-1] = $x + $z; + $this->d[$n] = $this->d[$n-1]; + if ($z != 0.0) { + $this->d[$n] = $x - $w / $z; + } + $this->e[$n-1] = 0.0; + $this->e[$n] = 0.0; + $x = $this->H[$n][$n-1]; + $s = abs($x) + abs($z); + $p = $x / $s; + $q = $z / $s; + $r = sqrt($p * $p + $q * $q); + $p = $p / $r; + $q = $q / $r; + // Row modification + for ($j = $n-1; $j < $nn; ++$j) { + $z = $this->H[$n-1][$j]; + $this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j]; + $this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z; + } + // Column modification + for ($i = 0; $i <= n; ++$i) { + $z = $this->H[$i][$n-1]; + $this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n]; + $this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $z = $this->V[$i][$n-1]; + $this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n]; + $this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z; + } + // Complex pair + } else { + $this->d[$n-1] = $x + $p; + $this->d[$n] = $x + $p; + $this->e[$n-1] = $z; + $this->e[$n] = -$z; + } + $n = $n - 2; + $iter = 0; + // No convergence yet + } else { + // Form shift + $x = $this->H[$n][$n]; + $y = 0.0; + $w = 0.0; + if ($l < $n) { + $y = $this->H[$n-1][$n-1]; + $w = $this->H[$n][$n-1] * $this->H[$n-1][$n]; + } + // Wilkinson's original ad hoc shift + if ($iter == 10) { + $exshift += $x; + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $x; + } + $s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]); + $x = $y = 0.75 * $s; + $w = -0.4375 * $s * $s; + } + // MATLAB's new ad hoc shift + if ($iter == 30) { + $s = ($y - $x) / 2.0; + $s = $s * $s + $w; + if ($s > 0) { + $s = sqrt($s); + if ($y < $x) { + $s = -$s; + } + $s = $x - $w / (($y - $x) / 2.0 + $s); + for ($i = $low; $i <= $n; ++$i) { + $this->H[$i][$i] -= $s; + } + $exshift += $s; + $x = $y = $w = 0.964; + } + } + // Could check iteration count here. + $iter = $iter + 1; + // Look for two consecutive small sub-diagonal elements + $m = $n - 2; + while ($m >= $l) { + $z = $this->H[$m][$m]; + $r = $x - $z; + $s = $y - $z; + $p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1]; + $q = $this->H[$m+1][$m+1] - $z - $r - $s; + $r = $this->H[$m+2][$m+1]; + $s = abs($p) + abs($q) + abs($r); + $p = $p / $s; + $q = $q / $s; + $r = $r / $s; + if ($m == $l) { + break; + } + if (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) < + $eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) { + break; + } + --$m; + } + for ($i = $m + 2; $i <= $n; ++$i) { + $this->H[$i][$i-2] = 0.0; + if ($i > $m+2) { + $this->H[$i][$i-3] = 0.0; + } + } + // Double QR step involving rows l:n and columns m:n + for ($k = $m; $k <= $n-1; ++$k) { + $notlast = ($k != $n-1); + if ($k != $m) { + $p = $this->H[$k][$k-1]; + $q = $this->H[$k+1][$k-1]; + $r = ($notlast ? $this->H[$k+2][$k-1] : 0.0); + $x = abs($p) + abs($q) + abs($r); + if ($x != 0.0) { + $p = $p / $x; + $q = $q / $x; + $r = $r / $x; + } + } + if ($x == 0.0) { + break; + } + $s = sqrt($p * $p + $q * $q + $r * $r); + if ($p < 0) { + $s = -$s; + } + if ($s != 0) { + if ($k != $m) { + $this->H[$k][$k-1] = -$s * $x; + } elseif ($l != $m) { + $this->H[$k][$k-1] = -$this->H[$k][$k-1]; + } + $p = $p + $s; + $x = $p / $s; + $y = $q / $s; + $z = $r / $s; + $q = $q / $p; + $r = $r / $p; + // Row modification + for ($j = $k; $j < $nn; ++$j) { + $p = $this->H[$k][$j] + $q * $this->H[$k+1][$j]; + if ($notlast) { + $p = $p + $r * $this->H[$k+2][$j]; + $this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z; + } + $this->H[$k][$j] = $this->H[$k][$j] - $p * $x; + $this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y; + } + // Column modification + for ($i = 0; $i <= min($n, $k+3); ++$i) { + $p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->H[$i][$k+2]; + $this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r; + } + $this->H[$i][$k] = $this->H[$i][$k] - $p; + $this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q; + } + // Accumulate transformations + for ($i = $low; $i <= $high; ++$i) { + $p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1]; + if ($notlast) { + $p = $p + $z * $this->V[$i][$k+2]; + $this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r; + } + $this->V[$i][$k] = $this->V[$i][$k] - $p; + $this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q; + } + } // ($s != 0) + } // k loop + } // check convergence + } // while ($n >= $low) + + // Backsubstitute to find vectors of upper triangular form + if ($norm == 0.0) { + return; + } + + for ($n = $nn-1; $n >= 0; --$n) { + $p = $this->d[$n]; + $q = $this->e[$n]; + // Real vector + if ($q == 0) { + $l = $n; + $this->H[$n][$n] = 1.0; + for ($i = $n-1; $i >= 0; --$i) { + $w = $this->H[$i][$i] - $p; + $r = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $r = $r + $this->H[$i][$j] * $this->H[$j][$n]; + } + if ($this->e[$i] < 0.0) { + $z = $w; + $s = $r; + } else { + $l = $i; + if ($this->e[$i] == 0.0) { + if ($w != 0.0) { + $this->H[$i][$n] = -$r / $w; + } else { + $this->H[$i][$n] = -$r / ($eps * $norm); + } + // Solve real equations + } else { + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i]; + $t = ($x * $s - $z * $r) / $q; + $this->H[$i][$n] = $t; + if (abs($x) > abs($z)) { + $this->H[$i+1][$n] = (-$r - $w * $t) / $x; + } else { + $this->H[$i+1][$n] = (-$s - $y * $t) / $z; + } + } + // Overflow control + $t = abs($this->H[$i][$n]); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } + } + // Complex vector + } else if ($q < 0) { + $l = $n-1; + // Last vector component imaginary so matrix is triangular + if (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) { + $this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1]; + $this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1]; + } else { + $this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q); + $this->H[$n-1][$n-1] = $this->cdivr; + $this->H[$n-1][$n] = $this->cdivi; + } + $this->H[$n][$n-1] = 0.0; + $this->H[$n][$n] = 1.0; + for ($i = $n-2; $i >= 0; --$i) { + // double ra,sa,vr,vi; + $ra = 0.0; + $sa = 0.0; + for ($j = $l; $j <= $n; ++$j) { + $ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1]; + $sa = $sa + $this->H[$i][$j] * $this->H[$j][$n]; + } + $w = $this->H[$i][$i] - $p; + if ($this->e[$i] < 0.0) { + $z = $w; + $r = $ra; + $s = $sa; + } else { + $l = $i; + if ($this->e[$i] == 0) { + $this->cdiv(-$ra, -$sa, $w, $q); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + } else { + // Solve complex equations + $x = $this->H[$i][$i+1]; + $y = $this->H[$i+1][$i]; + $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q; + $vi = ($this->d[$i] - $p) * 2.0 * $q; + if ($vr == 0.0 & $vi == 0.0) { + $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z)); + } + $this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi); + $this->H[$i][$n-1] = $this->cdivr; + $this->H[$i][$n] = $this->cdivi; + if (abs($x) > (abs($z) + abs($q))) { + $this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x; + $this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x; + } else { + $this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q); + $this->H[$i+1][$n-1] = $this->cdivr; + $this->H[$i+1][$n] = $this->cdivi; + } + } + // Overflow control + $t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n])); + if (($eps * $t) * $t > 1) { + for ($j = $i; $j <= $n; ++$j) { + $this->H[$j][$n-1] = $this->H[$j][$n-1] / $t; + $this->H[$j][$n] = $this->H[$j][$n] / $t; + } + } + } // end else + } // end for + } // end else for complex case + } // end for + + // Vectors of isolated roots + for ($i = 0; $i < $nn; ++$i) { + if ($i < $low | $i > $high) { + for ($j = $i; $j < $nn; ++$j) { + $this->V[$i][$j] = $this->H[$i][$j]; + } + } + } + + // Back transformation to get eigenvectors of original matrix + for ($j = $nn-1; $j >= $low; --$j) { + for ($i = $low; $i <= $high; ++$i) { + $z = 0.0; + for ($k = $low; $k <= min($j,$high); ++$k) { + $z = $z + $this->V[$i][$k] * $this->H[$k][$j]; + } + $this->V[$i][$j] = $z; + } + } + } // end hqr2 + + + /** + * Constructor: Check for symmetry, then construct the eigenvalue decomposition + * + * @access public + * @param A Square matrix + * @return Structure to access D and V. + */ + public function __construct($Arg) { + $this->A = $Arg->getArray(); + $this->n = $Arg->getColumnDimension(); + + $issymmetric = true; + for ($j = 0; ($j < $this->n) & $issymmetric; ++$j) { + for ($i = 0; ($i < $this->n) & $issymmetric; ++$i) { + $issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]); + } + } + + if ($issymmetric) { + $this->V = $this->A; + // Tridiagonalize. + $this->tred2(); + // Diagonalize. + $this->tql2(); + } else { + $this->H = $this->A; + $this->ort = array(); + // Reduce to Hessenberg form. + $this->orthes(); + // Reduce Hessenberg to real Schur form. + $this->hqr2(); + } + } + + + /** + * Return the eigenvector matrix + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V, $this->n, $this->n); + } + + + /** + * Return the real parts of the eigenvalues + * + * @access public + * @return real(diag(D)) + */ + public function getRealEigenvalues() { + return $this->d; + } + + + /** + * Return the imaginary parts of the eigenvalues + * + * @access public + * @return imag(diag(D)) + */ + public function getImagEigenvalues() { + return $this->e; + } + + + /** + * Return the block diagonal eigenvalue matrix + * + * @access public + * @return D + */ + public function getD() { + for ($i = 0; $i < $this->n; ++$i) { + $D[$i] = array_fill(0, $this->n, 0.0); + $D[$i][$i] = $this->d[$i]; + if ($this->e[$i] == 0) { + continue; + } + $o = ($this->e[$i] > 0) ? $i + 1 : $i - 1; + $D[$i][$o] = $this->e[$i]; + } + return new Matrix($D); + } + +} // class EigenvalueDecomposition diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php b/extend/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php new file mode 100755 index 0000000..08e500c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/LUDecomposition.php @@ -0,0 +1,258 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n + * unit lower triangular matrix L, an n-by-n upper triangular matrix U, + * and a permutation vector piv of length m so that A(piv,:) = L*U. + * If m < n, then L is m-by-m and U is m-by-n. + * + * The LU decompostion with pivoting always exists, even if the matrix is + * singular, so the constructor will never fail. The primary use of the + * LU decomposition is in the solution of square systems of simultaneous + * linear equations. This will fail if isNonsingular() returns false. + * + * @author Paul Meagher + * @author Bartosz Matosiuk + * @author Michael Bommarito + * @version 1.1 + * @license PHP v3.0 + */ +class PHPExcel_Shared_JAMA_LUDecomposition { + + const MatrixSingularException = "Can only perform operation on singular matrix."; + const MatrixSquareException = "Mismatched Row dimension"; + + /** + * Decomposition storage + * @var array + */ + private $LU = array(); + + /** + * Row dimension. + * @var int + */ + private $m; + + /** + * Column dimension. + * @var int + */ + private $n; + + /** + * Pivot sign. + * @var int + */ + private $pivsign; + + /** + * Internal storage of pivot vector. + * @var array + */ + private $piv = array(); + + + /** + * LU Decomposition constructor. + * + * @param $A Rectangular matrix + * @return Structure to access L, U and piv. + */ + public function __construct($A) { + if ($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Use a "left-looking", dot-product, Crout/Doolittle algorithm. + $this->LU = $A->getArray(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + for ($i = 0; $i < $this->m; ++$i) { + $this->piv[$i] = $i; + } + $this->pivsign = 1; + $LUrowi = $LUcolj = array(); + + // Outer loop. + for ($j = 0; $j < $this->n; ++$j) { + // Make a copy of the j-th column to localize references. + for ($i = 0; $i < $this->m; ++$i) { + $LUcolj[$i] = &$this->LU[$i][$j]; + } + // Apply previous transformations. + for ($i = 0; $i < $this->m; ++$i) { + $LUrowi = $this->LU[$i]; + // Most of the time is spent in the following dot product. + $kmax = min($i,$j); + $s = 0.0; + for ($k = 0; $k < $kmax; ++$k) { + $s += $LUrowi[$k] * $LUcolj[$k]; + } + $LUrowi[$j] = $LUcolj[$i] -= $s; + } + // Find pivot and exchange if necessary. + $p = $j; + for ($i = $j+1; $i < $this->m; ++$i) { + if (abs($LUcolj[$i]) > abs($LUcolj[$p])) { + $p = $i; + } + } + if ($p != $j) { + for ($k = 0; $k < $this->n; ++$k) { + $t = $this->LU[$p][$k]; + $this->LU[$p][$k] = $this->LU[$j][$k]; + $this->LU[$j][$k] = $t; + } + $k = $this->piv[$p]; + $this->piv[$p] = $this->piv[$j]; + $this->piv[$j] = $k; + $this->pivsign = $this->pivsign * -1; + } + // Compute multipliers. + if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) { + for ($i = $j+1; $i < $this->m; ++$i) { + $this->LU[$i][$j] /= $this->LU[$j][$j]; + } + } + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() + + + /** + * Get lower triangular factor. + * + * @return array Lower triangular factor + */ + public function getL() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i > $j) { + $L[$i][$j] = $this->LU[$i][$j]; + } elseif ($i == $j) { + $L[$i][$j] = 1.0; + } else { + $L[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($L); + } // function getL() + + + /** + * Get upper triangular factor. + * + * @return array Upper triangular factor + */ + public function getU() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i <= $j) { + $U[$i][$j] = $this->LU[$i][$j]; + } else { + $U[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($U); + } // function getU() + + + /** + * Return pivot permutation vector. + * + * @return array Pivot vector + */ + public function getPivot() { + return $this->piv; + } // function getPivot() + + + /** + * Alias for getPivot + * + * @see getPivot + */ + public function getDoublePivot() { + return $this->getPivot(); + } // function getDoublePivot() + + + /** + * Is the matrix nonsingular? + * + * @return true if U, and hence A, is nonsingular. + */ + public function isNonsingular() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->LU[$j][$j] == 0) { + return false; + } + } + return true; + } // function isNonsingular() + + + /** + * Count determinants + * + * @return array d matrix deterninat + */ + public function det() { + if ($this->m == $this->n) { + $d = $this->pivsign; + for ($j = 0; $j < $this->n; ++$j) { + $d *= $this->LU[$j][$j]; + } + return $d; + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function det() + + + /** + * Solve A*X = B + * + * @param $B A Matrix with as many rows as A and any number of columns. + * @return X so that L*U*X = B(piv,:) + * @PHPExcel_Calculation_Exception IllegalArgumentException Matrix row dimensions must agree. + * @PHPExcel_Calculation_Exception RuntimeException Matrix is singular. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isNonsingular()) { + // Copy right hand side with pivoting + $nx = $B->getColumnDimension(); + $X = $B->getMatrix($this->piv, 0, $nx-1); + // Solve L*Y = B(piv,:) + for ($k = 0; $k < $this->n; ++$k) { + for ($i = $k+1; $i < $this->n; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + // Solve U*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$k][$j] /= $this->LU[$k][$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k]; + } + } + } + return $X; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSingularException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixSquareException); + } + } // function solve() + +} // class PHPExcel_Shared_JAMA_LUDecomposition diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/Matrix.php b/extend/phpexcel/PHPExcel/Shared/JAMA/Matrix.php new file mode 100755 index 0000000..b893a44 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/Matrix.php @@ -0,0 +1,1059 @@ +<?php +/** + * @package JAMA + */ + +/** PHPExcel root directory */ +if (!defined('PHPEXCEL_ROOT')) { + /** + * @ignore + */ + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../'); + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); +} + + +/* + * Matrix class + * + * @author Paul Meagher + * @author Michael Bommarito + * @author Lukasz Karapuda + * @author Bartek Matosiuk + * @version 1.8 + * @license PHP v3.0 + * @see http://math.nist.gov/javanumerics/jama/ + */ +class PHPExcel_Shared_JAMA_Matrix { + + + const PolymorphicArgumentException = "Invalid argument pattern for polymorphic function."; + const ArgumentTypeException = "Invalid argument type."; + const ArgumentBoundsException = "Invalid argument range."; + const MatrixDimensionException = "Matrix dimensions are not equal."; + const ArrayLengthException = "Array length must be a multiple of m."; + + /** + * Matrix storage + * + * @var array + * @access public + */ + public $A = array(); + + /** + * Matrix row dimension + * + * @var int + * @access private + */ + private $m; + + /** + * Matrix column dimension + * + * @var int + * @access private + */ + private $n; + + + /** + * Polymorphic constructor + * + * As PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor. + */ + public function __construct() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //Rectangular matrix - m x n initialized from 2D array + case 'array': + $this->m = count($args[0]); + $this->n = count($args[0][0]); + $this->A = $args[0]; + break; + //Square matrix - n x n + case 'integer': + $this->m = $args[0]; + $this->n = $args[0]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n + case 'integer,integer': + $this->m = $args[0]; + $this->n = $args[1]; + $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0)); + break; + //Rectangular matrix - m x n initialized from packed array + case 'array,integer': + $this->m = $args[1]; + if ($this->m != 0) { + $this->n = count($args[0]) / $this->m; + } else { + $this->n = 0; + } + if (($this->m * $this->n) == count($args[0])) { + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $args[0][$i + $j * $this->m]; + } + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArrayLengthException); + } + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function __construct() + + + /** + * getArray + * + * @return array Matrix array + */ + public function getArray() { + return $this->A; + } // function getArray() + + + /** + * getRowDimension + * + * @return int Row dimension + */ + public function getRowDimension() { + return $this->m; + } // function getRowDimension() + + + /** + * getColumnDimension + * + * @return int Column dimension + */ + public function getColumnDimension() { + return $this->n; + } // function getColumnDimension() + + + /** + * get + * + * Get the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @return mixed Element (int/float/double) + */ + public function get($i = null, $j = null) { + return $this->A[$i][$j]; + } // function get() + + + /** + * getMatrix + * + * Get a submatrix + * @param int $i0 Initial row index + * @param int $iF Final row index + * @param int $j0 Initial column index + * @param int $jF Final column index + * @return Matrix Submatrix + */ + public function getMatrix() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + //A($i0...; $j0...) + case 'integer,integer': + list($i0, $j0) = $args; + if ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $this->m; ++$i) { + for($j = $j0; $j < $this->n; ++$j) { + $R->set($i, $j, $this->A[$i][$j]); + } + } + return $R; + break; + //A($i0...$iF; $j0...$jF) + case 'integer,integer,integer,integer': + list($i0, $iF, $j0, $jF) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1); + for($i = $i0; $i <= $iF; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$i][$j]); + } + } + return $R; + break; + //$R = array of row indices; $C = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //$RL = array of row indices; $CL = array of column indices + case 'array,array': + list($RL, $CL) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]); + } + } + return $R; + break; + //A($i0...$iF); $CL = array of column indices + case 'integer,integer,array': + list($i0, $iF, $CL) = $args; + if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = $i0; $i < $iF; ++$i) { + for($j = 0; $j < $n; ++$j) { + $R->set($i - $i0, $j, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + //$RL = array of row indices + case 'array,integer,integer': + list($RL, $j0, $jF) = $args; + if (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); } + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1); + for($i = 0; $i < $m; ++$i) { + for($j = $j0; $j <= $jF; ++$j) { + $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]); + } + } + return $R; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function getMatrix() + + + /** + * checkMatrixDimensions + * + * Is matrix B the same size? + * @param Matrix $B Matrix B + * @return boolean + */ + public function checkMatrixDimensions($B = null) { + if ($B instanceof PHPExcel_Shared_JAMA_Matrix) { + if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) { + return true; + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixDimensionException); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function checkMatrixDimensions() + + + + /** + * set + * + * Set the i,j-th element of the matrix. + * @param int $i Row position + * @param int $j Column position + * @param mixed $c Int/float/double value + * @return mixed Element (int/float/double) + */ + public function set($i = null, $j = null, $c = null) { + // Optimized set version just has this + $this->A[$i][$j] = $c; + } // function set() + + + /** + * identity + * + * Generate an identity matrix. + * @param int $m Row dimension + * @param int $n Column dimension + * @return Matrix Identity matrix + */ + public function identity($m = null, $n = null) { + return $this->diagonal($m, $n, 1); + } // function identity() + + + /** + * diagonal + * + * Generate a diagonal matrix + * @param int $m Row dimension + * @param int $n Column dimension + * @param mixed $c Diagonal value + * @return Matrix Diagonal matrix + */ + public function diagonal($m = null, $n = null, $c = 1) { + $R = new PHPExcel_Shared_JAMA_Matrix($m, $n); + for($i = 0; $i < $m; ++$i) { + $R->set($i, $i, $c); + } + return $R; + } // function diagonal() + + + /** + * getMatrixByRow + * + * Get a submatrix by row index/range + * @param int $i0 Initial row index + * @param int $iF Final row index + * @return Matrix Submatrix + */ + public function getMatrixByRow($i0 = null, $iF = null) { + if (is_int($i0)) { + if (is_int($iF)) { + return $this->getMatrix($i0, 0, $iF + 1, $this->n); + } else { + return $this->getMatrix($i0, 0, $i0 + 1, $this->n); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByRow() + + + /** + * getMatrixByCol + * + * Get a submatrix by column index/range + * @param int $i0 Initial column index + * @param int $iF Final column index + * @return Matrix Submatrix + */ + public function getMatrixByCol($j0 = null, $jF = null) { + if (is_int($j0)) { + if (is_int($jF)) { + return $this->getMatrix(0, $j0, $this->m, $jF + 1); + } else { + return $this->getMatrix(0, $j0, $this->m, $j0 + 1); + } + } else { + throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); + } + } // function getMatrixByCol() + + + /** + * transpose + * + * Tranpose matrix + * @return Matrix Transposed matrix + */ + public function transpose() { + $R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $R->set($j, $i, $this->A[$i][$j]); + } + } + return $R; + } // function transpose() + + + /** + * trace + * + * Sum of diagonal elements + * @return float Sum of diagonal elements + */ + public function trace() { + $s = 0; + $n = min($this->m, $this->n); + for($i = 0; $i < $n; ++$i) { + $s += $this->A[$i][$i]; + } + return $s; + } // function trace() + + + /** + * uminus + * + * Unary minus matrix -A + * @return Matrix Unary minus matrix + */ + public function uminus() { + } // function uminus() + + + /** + * plus + * + * A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plus() + + + /** + * plusEquals + * + * A = A + B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function plusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] += $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function plusEquals() + + + /** + * minus + * + * A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minus() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minus() + + + /** + * minusEquals + * + * A = A - B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function minusEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] -= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function minusEquals() + + + /** + * arrayTimes + * + * Element-by-element multiplication + * Cij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Cij + */ + public function arrayTimes() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimes() + + + /** + * arrayTimesEquals + * + * Element-by-element multiplication + * Aij = Aij * Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayTimesEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] *= $value; + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayTimesEquals() + + + /** + * arrayRightDivide + * + * Element-by-element right division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayRightDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + if ($value == 0) { + // Trap for Divide by Zero error + $M->set($i, $j, '#DIV/0!'); + } else { + $M->set($i, $j, $this->A[$i][$j] / $value); + } + } else { + $M->set($i, $j, PHPExcel_Calculation_Functions::NaN()); + } + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivide() + + + /** + * arrayRightDivideEquals + * + * Element-by-element right division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayRightDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayRightDivideEquals() + + + /** + * arrayLeftDivide + * + * Element-by-element Left division + * A / B + * @param Matrix $B Matrix B + * @return Matrix Division result + */ + public function arrayLeftDivide() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]); + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivide() + + + /** + * arrayLeftDivideEquals + * + * Element-by-element Left division + * Aij = Aij / Bij + * @param mixed $B Matrix/Array + * @return Matrix Matrix Aij + */ + public function arrayLeftDivideEquals() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j]; + } + } + return $M; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function arrayLeftDivideEquals() + + + /** + * times + * + * Matrix multiplication + * @param mixed $n Matrix/Array/Scalar + * @return Matrix Product + */ + public function times() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($j = 0; $j < $B->n; ++$j) { + for ($k = 0; $k < $this->n; ++$k) { + $Bcolj[$k] = $B->A[$k][$j]; + } + for($i = 0; $i < $this->m; ++$i) { + $Arowi = $this->A[$i]; + $s = 0; + for($k = 0; $k < $this->n; ++$k) { + $s += $Arowi[$k] * $Bcolj[$k]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + break; + case 'array': + $B = new PHPExcel_Shared_JAMA_Matrix($args[0]); + if ($this->n == $B->m) { + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $s = "0"; + for($k = 0; $k < $C->n; ++$k) { + $s += $this->A[$i][$k] * $B->A[$k][$j]; + } + $C->A[$i][$j] = $s; + } + } + return $C; + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch)); + } + return $M; + break; + case 'integer': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + case 'double': + $C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] = $args[0] * $this->A[$i][$j]; + } + } + return $C; + break; + case 'float': + $C = new PHPExcel_Shared_JAMA_Matrix($this->A); + for($i = 0; $i < $C->m; ++$i) { + for($j = 0; $j < $C->n; ++$j) { + $C->A[$i][$j] *= $args[0]; + } + } + return $C; + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function times() + + + /** + * power + * + * A = A ^ B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function power() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + break; + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $validValues = True; + $value = $M->get($i, $j); + if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]); + } + if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) { + $value = trim($value,'"'); + $validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value); + } + if ($validValues) { + $this->A[$i][$j] = pow($this->A[$i][$j],$value); + } else { + $this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN(); + } + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function power() + + + /** + * concat + * + * A = A & B + * @param mixed $B Matrix/Array + * @return Matrix Sum + */ + public function concat() { + if (func_num_args() > 0) { + $args = func_get_args(); + $match = implode(",", array_map('gettype', $args)); + + switch($match) { + case 'object': + if ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); } + case 'array': + $M = new PHPExcel_Shared_JAMA_Matrix($args[0]); + break; + default: + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + break; + } + $this->checkMatrixDimensions($M); + for($i = 0; $i < $this->m; ++$i) { + for($j = 0; $j < $this->n; ++$j) { + $this->A[$i][$j] = trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"'); + } + } + return $this; + } else { + throw new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException); + } + } // function concat() + + + /** + * Solve A*X = B. + * + * @param Matrix $B Right hand side + * @return Matrix ... Solution if A is square, least squares solution otherwise + */ + public function solve($B) { + if ($this->m == $this->n) { + $LU = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $LU->solve($B); + } else { + $QR = new QRDecomposition($this); + return $QR->solve($B); + } + } // function solve() + + + /** + * Matrix inverse or pseudoinverse. + * + * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise. + */ + public function inverse() { + return $this->solve($this->identity($this->m, $this->m)); + } // function inverse() + + + /** + * det + * + * Calculate determinant + * @return float Determinant + */ + public function det() { + $L = new PHPExcel_Shared_JAMA_LUDecomposition($this); + return $L->det(); + } // function det() + + +} // class PHPExcel_Shared_JAMA_Matrix diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php b/extend/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php new file mode 100755 index 0000000..7538462 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/QRDecomposition.php @@ -0,0 +1,234 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n + * orthogonal matrix Q and an n-by-n upper triangular matrix R so that + * A = Q*R. + * + * The QR decompostion always exists, even if the matrix does not have + * full rank, so the constructor will never fail. The primary use of the + * QR decomposition is in the least squares solution of nonsquare systems + * of simultaneous linear equations. This will fail if isFullRank() + * returns false. + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class PHPExcel_Shared_JAMA_QRDecomposition { + + const MatrixRankException = "Can only perform operation on full-rank matrix."; + + /** + * Array for internal storage of decomposition. + * @var array + */ + private $QR = array(); + + /** + * Row dimension. + * @var integer + */ + private $m; + + /** + * Column dimension. + * @var integer + */ + private $n; + + /** + * Array for internal storage of diagonal of R. + * @var array + */ + private $Rdiag = array(); + + + /** + * QR Decomposition computed by Householder reflections. + * + * @param matrix $A Rectangular matrix + * @return Structure to access R and the Householder vectors and compute Q. + */ + public function __construct($A) { + if($A instanceof PHPExcel_Shared_JAMA_Matrix) { + // Initialize. + $this->QR = $A->getArrayCopy(); + $this->m = $A->getRowDimension(); + $this->n = $A->getColumnDimension(); + // Main loop. + for ($k = 0; $k < $this->n; ++$k) { + // Compute 2-norm of k-th column without under/overflow. + $nrm = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $nrm = hypo($nrm, $this->QR[$i][$k]); + } + if ($nrm != 0.0) { + // Form k-th Householder vector. + if ($this->QR[$k][$k] < 0) { + $nrm = -$nrm; + } + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$k] /= $nrm; + } + $this->QR[$k][$k] += 1.0; + // Apply transformation to remaining columns. + for ($j = $k+1; $j < $this->n; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $this->QR[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->QR[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + $this->Rdiag[$k] = -$nrm; + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException); + } + } // function __construct() + + + /** + * Is the matrix full rank? + * + * @return boolean true if R, and hence A, has full rank, else false. + */ + public function isFullRank() { + for ($j = 0; $j < $this->n; ++$j) { + if ($this->Rdiag[$j] == 0) { + return false; + } + } + return true; + } // function isFullRank() + + + /** + * Return the Householder vectors + * + * @return Matrix Lower trapezoidal matrix whose columns define the reflections + */ + public function getH() { + for ($i = 0; $i < $this->m; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i >= $j) { + $H[$i][$j] = $this->QR[$i][$j]; + } else { + $H[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($H); + } // function getH() + + + /** + * Return the upper triangular factor + * + * @return Matrix upper triangular factor + */ + public function getR() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + if ($i < $j) { + $R[$i][$j] = $this->QR[$i][$j]; + } elseif ($i == $j) { + $R[$i][$j] = $this->Rdiag[$i]; + } else { + $R[$i][$j] = 0.0; + } + } + } + return new PHPExcel_Shared_JAMA_Matrix($R); + } // function getR() + + + /** + * Generate and return the (economy-sized) orthogonal factor + * + * @return Matrix orthogonal factor + */ + public function getQ() { + for ($k = $this->n-1; $k >= 0; --$k) { + for ($i = 0; $i < $this->m; ++$i) { + $Q[$i][$k] = 0.0; + } + $Q[$k][$k] = 1.0; + for ($j = $k; $j < $this->n; ++$j) { + if ($this->QR[$k][$k] != 0) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $Q[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $Q[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + } + /* + for($i = 0; $i < count($Q); ++$i) { + for($j = 0; $j < count($Q); ++$j) { + if(! isset($Q[$i][$j]) ) { + $Q[$i][$j] = 0; + } + } + } + */ + return new PHPExcel_Shared_JAMA_Matrix($Q); + } // function getQ() + + + /** + * Least squares solution of A*X = B + * + * @param Matrix $B A Matrix with as many rows as A and any number of columns. + * @return Matrix Matrix that minimizes the two norm of Q*R*X-B. + */ + public function solve($B) { + if ($B->getRowDimension() == $this->m) { + if ($this->isFullRank()) { + // Copy right hand side + $nx = $B->getColumnDimension(); + $X = $B->getArrayCopy(); + // Compute Y = transpose(Q)*B + for ($k = 0; $k < $this->n; ++$k) { + for ($j = 0; $j < $nx; ++$j) { + $s = 0.0; + for ($i = $k; $i < $this->m; ++$i) { + $s += $this->QR[$i][$k] * $X[$i][$j]; + } + $s = -$s/$this->QR[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $X[$i][$j] += $s * $this->QR[$i][$k]; + } + } + } + // Solve R*X = Y; + for ($k = $this->n-1; $k >= 0; --$k) { + for ($j = 0; $j < $nx; ++$j) { + $X[$k][$j] /= $this->Rdiag[$k]; + } + for ($i = 0; $i < $k; ++$i) { + for ($j = 0; $j < $nx; ++$j) { + $X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k]; + } + } + } + $X = new PHPExcel_Shared_JAMA_Matrix($X); + return ($X->getMatrix(0, $this->n-1, 0, $nx)); + } else { + throw new PHPExcel_Calculation_Exception(self::MatrixRankException); + } + } else { + throw new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException); + } + } // function solve() + +} // PHPExcel_Shared_JAMA_class QRDecomposition diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php b/extend/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php new file mode 100755 index 0000000..a4b096c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/SingularValueDecomposition.php @@ -0,0 +1,526 @@ +<?php +/** + * @package JAMA + * + * For an m-by-n matrix A with m >= n, the singular value decomposition is + * an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and + * an n-by-n orthogonal matrix V so that A = U*S*V'. + * + * The singular values, sigma[$k] = S[$k][$k], are ordered so that + * sigma[0] >= sigma[1] >= ... >= sigma[n-1]. + * + * The singular value decompostion always exists, so the constructor will + * never fail. The matrix condition number and the effective numerical + * rank can be computed from this decomposition. + * + * @author Paul Meagher + * @license PHP v3.0 + * @version 1.1 + */ +class SingularValueDecomposition { + + /** + * Internal storage of U. + * @var array + */ + private $U = array(); + + /** + * Internal storage of V. + * @var array + */ + private $V = array(); + + /** + * Internal storage of singular values. + * @var array + */ + private $s = array(); + + /** + * Row dimension. + * @var int + */ + private $m; + + /** + * Column dimension. + * @var int + */ + private $n; + + + /** + * Construct the singular value decomposition + * + * Derived from LINPACK code. + * + * @param $A Rectangular matrix + * @return Structure to access U, S and V. + */ + public function __construct($Arg) { + + // Initialize. + $A = $Arg->getArrayCopy(); + $this->m = $Arg->getRowDimension(); + $this->n = $Arg->getColumnDimension(); + $nu = min($this->m, $this->n); + $e = array(); + $work = array(); + $wantu = true; + $wantv = true; + $nct = min($this->m - 1, $this->n); + $nrt = max(0, min($this->n - 2, $this->m)); + + // Reduce A to bidiagonal form, storing the diagonal elements + // in s and the super-diagonal elements in e. + for ($k = 0; $k < max($nct,$nrt); ++$k) { + + if ($k < $nct) { + // Compute the transformation for the k-th column and + // place the k-th diagonal in s[$k]. + // Compute 2-norm of k-th column without under/overflow. + $this->s[$k] = 0; + for ($i = $k; $i < $this->m; ++$i) { + $this->s[$k] = hypo($this->s[$k], $A[$i][$k]); + } + if ($this->s[$k] != 0.0) { + if ($A[$k][$k] < 0.0) { + $this->s[$k] = -$this->s[$k]; + } + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$k] /= $this->s[$k]; + } + $A[$k][$k] += 1.0; + } + $this->s[$k] = -$this->s[$k]; + } + + for ($j = $k + 1; $j < $this->n; ++$j) { + if (($k < $nct) & ($this->s[$k] != 0.0)) { + // Apply the transformation. + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $A[$i][$k] * $A[$i][$j]; + } + $t = -$t / $A[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $A[$i][$k]; + } + // Place the k-th row of A into e for the + // subsequent calculation of the row transformation. + $e[$j] = $A[$k][$j]; + } + } + + if ($wantu AND ($k < $nct)) { + // Place the transformation in U for subsequent back + // multiplication. + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$k] = $A[$i][$k]; + } + } + + if ($k < $nrt) { + // Compute the k-th row transformation and place the + // k-th super-diagonal in e[$k]. + // Compute 2-norm without under/overflow. + $e[$k] = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$k] = hypo($e[$k], $e[$i]); + } + if ($e[$k] != 0.0) { + if ($e[$k+1] < 0.0) { + $e[$k] = -$e[$k]; + } + for ($i = $k + 1; $i < $this->n; ++$i) { + $e[$i] /= $e[$k]; + } + $e[$k+1] += 1.0; + } + $e[$k] = -$e[$k]; + if (($k+1 < $this->m) AND ($e[$k] != 0.0)) { + // Apply the transformation. + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] = 0.0; + } + for ($j = $k+1; $j < $this->n; ++$j) { + for ($i = $k+1; $i < $this->m; ++$i) { + $work[$i] += $e[$j] * $A[$i][$j]; + } + } + for ($j = $k + 1; $j < $this->n; ++$j) { + $t = -$e[$j] / $e[$k+1]; + for ($i = $k + 1; $i < $this->m; ++$i) { + $A[$i][$j] += $t * $work[$i]; + } + } + } + if ($wantv) { + // Place the transformation in V for subsequent + // back multiplication. + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$k] = $e[$i]; + } + } + } + } + + // Set up the final bidiagonal matrix or order p. + $p = min($this->n, $this->m + 1); + if ($nct < $this->n) { + $this->s[$nct] = $A[$nct][$nct]; + } + if ($this->m < $p) { + $this->s[$p-1] = 0.0; + } + if ($nrt + 1 < $p) { + $e[$nrt] = $A[$nrt][$p-1]; + } + $e[$p-1] = 0.0; + // If required, generate U. + if ($wantu) { + for ($j = $nct; $j < $nu; ++$j) { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$j] = 0.0; + } + $this->U[$j][$j] = 1.0; + } + for ($k = $nct - 1; $k >= 0; --$k) { + if ($this->s[$k] != 0.0) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k; $i < $this->m; ++$i) { + $t += $this->U[$i][$k] * $this->U[$i][$j]; + } + $t = -$t / $this->U[$k][$k]; + for ($i = $k; $i < $this->m; ++$i) { + $this->U[$i][$j] += $t * $this->U[$i][$k]; + } + } + for ($i = $k; $i < $this->m; ++$i ) { + $this->U[$i][$k] = -$this->U[$i][$k]; + } + $this->U[$k][$k] = 1.0 + $this->U[$k][$k]; + for ($i = 0; $i < $k - 1; ++$i) { + $this->U[$i][$k] = 0.0; + } + } else { + for ($i = 0; $i < $this->m; ++$i) { + $this->U[$i][$k] = 0.0; + } + $this->U[$k][$k] = 1.0; + } + } + } + + // If required, generate V. + if ($wantv) { + for ($k = $this->n - 1; $k >= 0; --$k) { + if (($k < $nrt) AND ($e[$k] != 0.0)) { + for ($j = $k + 1; $j < $nu; ++$j) { + $t = 0; + for ($i = $k + 1; $i < $this->n; ++$i) { + $t += $this->V[$i][$k]* $this->V[$i][$j]; + } + $t = -$t / $this->V[$k+1][$k]; + for ($i = $k + 1; $i < $this->n; ++$i) { + $this->V[$i][$j] += $t * $this->V[$i][$k]; + } + } + } + for ($i = 0; $i < $this->n; ++$i) { + $this->V[$i][$k] = 0.0; + } + $this->V[$k][$k] = 1.0; + } + } + + // Main iteration loop for the singular values. + $pp = $p - 1; + $iter = 0; + $eps = pow(2.0, -52.0); + + while ($p > 0) { + // Here is where a test for too many iterations would go. + // This section of the program inspects for negligible + // elements in the s and e arrays. On completion the + // variables kase and k are set as follows: + // kase = 1 if s(p) and e[k-1] are negligible and k<p + // kase = 2 if s(k) is negligible and k<p + // kase = 3 if e[k-1] is negligible, k<p, and + // s(k), ..., s(p) are not negligible (qr step). + // kase = 4 if e(p-1) is negligible (convergence). + for ($k = $p - 2; $k >= -1; --$k) { + if ($k == -1) { + break; + } + if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) { + $e[$k] = 0.0; + break; + } + } + if ($k == $p - 2) { + $kase = 4; + } else { + for ($ks = $p - 1; $ks >= $k; --$ks) { + if ($ks == $k) { + break; + } + $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.); + if (abs($this->s[$ks]) <= $eps * $t) { + $this->s[$ks] = 0.0; + break; + } + } + if ($ks == $k) { + $kase = 3; + } else if ($ks == $p-1) { + $kase = 1; + } else { + $kase = 2; + $k = $ks; + } + } + ++$k; + + // Perform the task indicated by kase. + switch ($kase) { + // Deflate negligible s(p). + case 1: + $f = $e[$p-2]; + $e[$p-2] = 0.0; + for ($j = $p - 2; $j >= $k; --$j) { + $t = hypo($this->s[$j],$f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + if ($j != $k) { + $f = -$sn * $e[$j-1]; + $e[$j-1] = $cs * $e[$j-1]; + } + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1]; + $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1]; + $this->V[$i][$j] = $t; + } + } + } + break; + // Split at negligible s(k). + case 2: + $f = $e[$k-1]; + $e[$k-1] = 0.0; + for ($j = $k; $j < $p; ++$j) { + $t = hypo($this->s[$j], $f); + $cs = $this->s[$j] / $t; + $sn = $f / $t; + $this->s[$j] = $t; + $f = -$sn * $e[$j]; + $e[$j] = $cs * $e[$j]; + if ($wantu) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1]; + $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1]; + $this->U[$i][$j] = $t; + } + } + } + break; + // Perform one qr step. + case 3: + // Calculate the shift. + $scale = max(max(max(max( + abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])), + abs($this->s[$k])), abs($e[$k])); + $sp = $this->s[$p-1] / $scale; + $spm1 = $this->s[$p-2] / $scale; + $epm1 = $e[$p-2] / $scale; + $sk = $this->s[$k] / $scale; + $ek = $e[$k] / $scale; + $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0; + $c = ($sp * $epm1) * ($sp * $epm1); + $shift = 0.0; + if (($b != 0.0) || ($c != 0.0)) { + $shift = sqrt($b * $b + $c); + if ($b < 0.0) { + $shift = -$shift; + } + $shift = $c / ($b + $shift); + } + $f = ($sk + $sp) * ($sk - $sp) + $shift; + $g = $sk * $ek; + // Chase zeros. + for ($j = $k; $j < $p-1; ++$j) { + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + if ($j != $k) { + $e[$j-1] = $t; + } + $f = $cs * $this->s[$j] + $sn * $e[$j]; + $e[$j] = $cs * $e[$j] - $sn * $this->s[$j]; + $g = $sn * $this->s[$j+1]; + $this->s[$j+1] = $cs * $this->s[$j+1]; + if ($wantv) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1]; + $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1]; + $this->V[$i][$j] = $t; + } + } + $t = hypo($f,$g); + $cs = $f/$t; + $sn = $g/$t; + $this->s[$j] = $t; + $f = $cs * $e[$j] + $sn * $this->s[$j+1]; + $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1]; + $g = $sn * $e[$j+1]; + $e[$j+1] = $cs * $e[$j+1]; + if ($wantu && ($j < $this->m - 1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1]; + $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1]; + $this->U[$i][$j] = $t; + } + } + } + $e[$p-2] = $f; + $iter = $iter + 1; + break; + // Convergence. + case 4: + // Make the singular values positive. + if ($this->s[$k] <= 0.0) { + $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0); + if ($wantv) { + for ($i = 0; $i <= $pp; ++$i) { + $this->V[$i][$k] = -$this->V[$i][$k]; + } + } + } + // Order the singular values. + while ($k < $pp) { + if ($this->s[$k] >= $this->s[$k+1]) { + break; + } + $t = $this->s[$k]; + $this->s[$k] = $this->s[$k+1]; + $this->s[$k+1] = $t; + if ($wantv AND ($k < $this->n - 1)) { + for ($i = 0; $i < $this->n; ++$i) { + $t = $this->V[$i][$k+1]; + $this->V[$i][$k+1] = $this->V[$i][$k]; + $this->V[$i][$k] = $t; + } + } + if ($wantu AND ($k < $this->m-1)) { + for ($i = 0; $i < $this->m; ++$i) { + $t = $this->U[$i][$k+1]; + $this->U[$i][$k+1] = $this->U[$i][$k]; + $this->U[$i][$k] = $t; + } + } + ++$k; + } + $iter = 0; + --$p; + break; + } // end switch + } // end while + + } // end constructor + + + /** + * Return the left singular vectors + * + * @access public + * @return U + */ + public function getU() { + return new Matrix($this->U, $this->m, min($this->m + 1, $this->n)); + } + + + /** + * Return the right singular vectors + * + * @access public + * @return V + */ + public function getV() { + return new Matrix($this->V); + } + + + /** + * Return the one-dimensional array of singular values + * + * @access public + * @return diagonal of S. + */ + public function getSingularValues() { + return $this->s; + } + + + /** + * Return the diagonal matrix of singular values + * + * @access public + * @return S + */ + public function getS() { + for ($i = 0; $i < $this->n; ++$i) { + for ($j = 0; $j < $this->n; ++$j) { + $S[$i][$j] = 0.0; + } + $S[$i][$i] = $this->s[$i]; + } + return new Matrix($S); + } + + + /** + * Two norm + * + * @access public + * @return max(S) + */ + public function norm2() { + return $this->s[0]; + } + + + /** + * Two norm condition number + * + * @access public + * @return max(S)/min(S) + */ + public function cond() { + return $this->s[0] / $this->s[min($this->m, $this->n) - 1]; + } + + + /** + * Effective numerical matrix rank + * + * @access public + * @return Number of nonnegligible singular values. + */ + public function rank() { + $eps = pow(2.0, -52.0); + $tol = max($this->m, $this->n) * $this->s[0] * $eps; + $r = 0; + for ($i = 0; $i < count($this->s); ++$i) { + if ($this->s[$i] > $tol) { + ++$r; + } + } + return $r; + } + +} // class SingularValueDecomposition diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php b/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php new file mode 100755 index 0000000..e73252b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Error.php @@ -0,0 +1,82 @@ +<?php +/** + * @package JAMA + * + * Error handling + * @author Michael Bommarito + * @version 01292005 + */ + +//Language constant +define('JAMALANG', 'EN'); + + +//All errors may be defined by the following format: +//define('ExceptionName', N); +//$error['lang'][ExceptionName] = 'Error message'; +$error = array(); + +/* +I've used Babelfish and a little poor knowledge of Romance/Germanic languages for the translations here. +Feel free to correct anything that looks amiss to you. +*/ + +define('PolymorphicArgumentException', -1); +$error['EN'][PolymorphicArgumentException] = "Invalid argument pattern for polymorphic function."; +$error['FR'][PolymorphicArgumentException] = "Modèle inadmissible d'argument pour la fonction polymorphe.". +$error['DE'][PolymorphicArgumentException] = "Unzulässiges Argumentmuster für polymorphe Funktion."; + +define('ArgumentTypeException', -2); +$error['EN'][ArgumentTypeException] = "Invalid argument type."; +$error['FR'][ArgumentTypeException] = "Type inadmissible d'argument."; +$error['DE'][ArgumentTypeException] = "Unzulässige Argumentart."; + +define('ArgumentBoundsException', -3); +$error['EN'][ArgumentBoundsException] = "Invalid argument range."; +$error['FR'][ArgumentBoundsException] = "Gamme inadmissible d'argument."; +$error['DE'][ArgumentBoundsException] = "Unzulässige Argumentstrecke."; + +define('MatrixDimensionException', -4); +$error['EN'][MatrixDimensionException] = "Matrix dimensions are not equal."; +$error['FR'][MatrixDimensionException] = "Les dimensions de Matrix ne sont pas égales."; +$error['DE'][MatrixDimensionException] = "Matrixmaße sind nicht gleich."; + +define('PrecisionLossException', -5); +$error['EN'][PrecisionLossException] = "Significant precision loss detected."; +$error['FR'][PrecisionLossException] = "Perte significative de précision détectée."; +$error['DE'][PrecisionLossException] = "Bedeutender Präzision Verlust ermittelte."; + +define('MatrixSPDException', -6); +$error['EN'][MatrixSPDException] = "Can only perform operation on symmetric positive definite matrix."; +$error['FR'][MatrixSPDException] = "Perte significative de précision détectée."; +$error['DE'][MatrixSPDException] = "Bedeutender Präzision Verlust ermittelte."; + +define('MatrixSingularException', -7); +$error['EN'][MatrixSingularException] = "Can only perform operation on singular matrix."; + +define('MatrixRankException', -8); +$error['EN'][MatrixRankException] = "Can only perform operation on full-rank matrix."; + +define('ArrayLengthException', -9); +$error['EN'][ArrayLengthException] = "Array length must be a multiple of m."; + +define('RowLengthException', -10); +$error['EN'][RowLengthException] = "All rows must have the same length."; + +/** + * Custom error handler + * @param int $num Error number + */ +function JAMAError($errorNumber = null) { + global $error; + + if (isset($errorNumber)) { + if (isset($error[JAMALANG][$errorNumber])) { + return $error[JAMALANG][$errorNumber]; + } else { + return $error['EN'][$errorNumber]; + } + } else { + return ("Invalid argument to JAMAError()"); + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php b/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php new file mode 100755 index 0000000..aa09a8b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/JAMA/utils/Maths.php @@ -0,0 +1,43 @@ +<?php +/** + * @package JAMA + * + * Pythagorean Theorem: + * + * a = 3 + * b = 4 + * r = sqrt(square(a) + square(b)) + * r = 5 + * + * r = sqrt(a^2 + b^2) without under/overflow. + */ +function hypo($a, $b) { + if (abs($a) > abs($b)) { + $r = $b / $a; + $r = abs($a) * sqrt(1 + $r * $r); + } elseif ($b != 0) { + $r = $a / $b; + $r = abs($b) * sqrt(1 + $r * $r); + } else { + $r = 0.0; + } + return $r; +} // function hypo() + + +/** + * Mike Bommarito's version. + * Compute n-dimensional hyotheneuse. + * +function hypot() { + $s = 0; + foreach (func_get_args() as $d) { + if (is_numeric($d)) { + $s += pow($d, 2); + } else { + throw new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException)); + } + } + return sqrt($s); +} +*/ diff --git a/extend/phpexcel/PHPExcel/Shared/OLE.php b/extend/phpexcel/PHPExcel/Shared/OLE.php new file mode 100755 index 0000000..9796282 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLE.php @@ -0,0 +1,531 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: OLE.php,v 1.13 2007/03/07 14:38:25 schmidt Exp $ + + +/** +* Array for storing OLE instances that are accessed from +* OLE_ChainedBlockStream::stream_open(). +* @var array +*/ +$GLOBALS['_OLE_INSTANCES'] = array(); + +/** +* OLE package base class. +* +* @author Xavier Noguer <xnoguer@php.net> +* @author Christian Schmidt <schmidt@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE +{ + const OLE_PPS_TYPE_ROOT = 5; + const OLE_PPS_TYPE_DIR = 1; + const OLE_PPS_TYPE_FILE = 2; + const OLE_DATA_SIZE_SMALL = 0x1000; + const OLE_LONG_INT_SIZE = 4; + const OLE_PPS_SIZE = 0x80; + + /** + * The file handle for reading an OLE container + * @var resource + */ + public $_file_handle; + + /** + * Array of PPS's found on the OLE container + * @var array + */ + public $_list = array(); + + /** + * Root directory of OLE container + * @var OLE_PPS_Root + */ + public $root; + + /** + * Big Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $bbat; + + /** + * Short Block Allocation Table + * @var array (blockId => nextBlockId) + */ + public $sbat; + + /** + * Size of big blocks. This is usually 512. + * @var int number of octets per block. + */ + public $bigBlockSize; + + /** + * Size of small blocks. This is usually 64. + * @var int number of octets per block + */ + public $smallBlockSize; + + /** + * Reads an OLE container from the contents of the file given. + * + * @acces public + * @param string $file + * @return mixed true on success, PEAR_Error on failure + */ + public function read($file) + { + $fh = fopen($file, "r"); + if (!$fh) { + throw new PHPExcel_Reader_Exception("Can't open file $file"); + } + $this->_file_handle = $fh; + + $signature = fread($fh, 8); + if ("\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" != $signature) { + throw new PHPExcel_Reader_Exception("File doesn't seem to be an OLE container."); + } + fseek($fh, 28); + if (fread($fh, 2) != "\xFE\xFF") { + // This shouldn't be a problem in practice + throw new PHPExcel_Reader_Exception("Only Little-Endian encoding is supported."); + } + // Size of blocks and short blocks in bytes + $this->bigBlockSize = pow(2, self::_readInt2($fh)); + $this->smallBlockSize = pow(2, self::_readInt2($fh)); + + // Skip UID, revision number and version number + fseek($fh, 44); + // Number of blocks in Big Block Allocation Table + $bbatBlockCount = self::_readInt4($fh); + + // Root chain 1st block + $directoryFirstBlockId = self::_readInt4($fh); + + // Skip unused bytes + fseek($fh, 56); + // Streams shorter than this are stored using small blocks + $this->bigBlockThreshold = self::_readInt4($fh); + // Block id of first sector in Short Block Allocation Table + $sbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Short Block Allocation Table + $sbbatBlockCount = self::_readInt4($fh); + // Block id of first sector in Master Block Allocation Table + $mbatFirstBlockId = self::_readInt4($fh); + // Number of blocks in Master Block Allocation Table + $mbbatBlockCount = self::_readInt4($fh); + $this->bbat = array(); + + // Remaining 4 * 109 bytes of current block is beginning of Master + // Block Allocation Table + $mbatBlocks = array(); + for ($i = 0; $i < 109; ++$i) { + $mbatBlocks[] = self::_readInt4($fh); + } + + // Read rest of Master Block Allocation Table (if any is left) + $pos = $this->_getBlockOffset($mbatFirstBlockId); + for ($i = 0; $i < $mbbatBlockCount; ++$i) { + fseek($fh, $pos); + for ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) { + $mbatBlocks[] = self::_readInt4($fh); + } + // Last block id in each block points to next block + $pos = $this->_getBlockOffset(self::_readInt4($fh)); + } + + // Read Big Block Allocation Table according to chain specified by + // $mbatBlocks + for ($i = 0; $i < $bbatBlockCount; ++$i) { + $pos = $this->_getBlockOffset($mbatBlocks[$i]); + fseek($fh, $pos); + for ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) { + $this->bbat[] = self::_readInt4($fh); + } + } + + // Read short block allocation table (SBAT) + $this->sbat = array(); + $shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4; + $sbatFh = $this->getStream($sbatFirstBlockId); + for ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) { + $this->sbat[$blockId] = self::_readInt4($sbatFh); + } + fclose($sbatFh); + + $this->_readPpsWks($directoryFirstBlockId); + + return true; + } + + /** + * @param int block id + * @param int byte offset from beginning of file + * @access public + */ + public function _getBlockOffset($blockId) + { + return 512 + $blockId * $this->bigBlockSize; + } + + /** + * Returns a stream for use with fread() etc. External callers should + * use PHPExcel_Shared_OLE_PPS_File::getStream(). + * @param int|PPS block id or PPS + * @return resource read-only stream + */ + public function getStream($blockIdOrPps) + { + static $isRegistered = false; + if (!$isRegistered) { + stream_wrapper_register('ole-chainedblockstream', + 'PHPExcel_Shared_OLE_ChainedBlockStream'); + $isRegistered = true; + } + + // Store current instance in global array, so that it can be accessed + // in OLE_ChainedBlockStream::stream_open(). + // Object is removed from self::$instances in OLE_Stream::close(). + $GLOBALS['_OLE_INSTANCES'][] = $this; + $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES'])); + + $path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId; + if ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) { + $path .= '&blockId=' . $blockIdOrPps->_StartBlock; + $path .= '&size=' . $blockIdOrPps->Size; + } else { + $path .= '&blockId=' . $blockIdOrPps; + } + return fopen($path, 'r'); + } + + /** + * Reads a signed char. + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt1($fh) + { + list(, $tmp) = unpack("c", fread($fh, 1)); + return $tmp; + } + + /** + * Reads an unsigned short (2 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt2($fh) + { + list(, $tmp) = unpack("v", fread($fh, 2)); + return $tmp; + } + + /** + * Reads an unsigned long (4 octets). + * @param resource file handle + * @return int + * @access public + */ + private static function _readInt4($fh) + { + list(, $tmp) = unpack("V", fread($fh, 4)); + return $tmp; + } + + /** + * Gets information about all PPS's on the OLE container from the PPS WK's + * creates an OLE_PPS object for each one. + * + * @access public + * @param integer the block id of the first block + * @return mixed true on success, PEAR_Error on failure + */ + public function _readPpsWks($blockId) + { + $fh = $this->getStream($blockId); + for ($pos = 0; ; $pos += 128) { + fseek($fh, $pos, SEEK_SET); + $nameUtf16 = fread($fh, 64); + $nameLength = self::_readInt2($fh); + $nameUtf16 = substr($nameUtf16, 0, $nameLength - 2); + // Simple conversion from UTF-16LE to ISO-8859-1 + $name = str_replace("\x00", "", $nameUtf16); + $type = self::_readInt1($fh); + switch ($type) { + case self::OLE_PPS_TYPE_ROOT: + $pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array()); + $this->root = $pps; + break; + case self::OLE_PPS_TYPE_DIR: + $pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null, + null, null, null, null, array()); + break; + case self::OLE_PPS_TYPE_FILE: + $pps = new PHPExcel_Shared_OLE_PPS_File($name); + break; + default: + continue; + } + fseek($fh, 1, SEEK_CUR); + $pps->Type = $type; + $pps->Name = $name; + $pps->PrevPps = self::_readInt4($fh); + $pps->NextPps = self::_readInt4($fh); + $pps->DirPps = self::_readInt4($fh); + fseek($fh, 20, SEEK_CUR); + $pps->Time1st = self::OLE2LocalDate(fread($fh, 8)); + $pps->Time2nd = self::OLE2LocalDate(fread($fh, 8)); + $pps->_StartBlock = self::_readInt4($fh); + $pps->Size = self::_readInt4($fh); + $pps->No = count($this->_list); + $this->_list[] = $pps; + + // check if the PPS tree (starting from root) is complete + if (isset($this->root) && + $this->_ppsTreeComplete($this->root->No)) { + + break; + } + } + fclose($fh); + + // Initialize $pps->children on directories + foreach ($this->_list as $pps) { + if ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) { + $nos = array($pps->DirPps); + $pps->children = array(); + while ($nos) { + $no = array_pop($nos); + if ($no != -1) { + $childPps = $this->_list[$no]; + $nos[] = $childPps->PrevPps; + $nos[] = $childPps->NextPps; + $pps->children[] = $childPps; + } + } + } + } + + return true; + } + + /** + * It checks whether the PPS tree is complete (all PPS's read) + * starting with the given PPS (not necessarily root) + * + * @access public + * @param integer $index The index of the PPS from which we are checking + * @return boolean Whether the PPS tree for the given PPS is complete + */ + public function _ppsTreeComplete($index) + { + return isset($this->_list[$index]) && + ($pps = $this->_list[$index]) && + ($pps->PrevPps == -1 || + $this->_ppsTreeComplete($pps->PrevPps)) && + ($pps->NextPps == -1 || + $this->_ppsTreeComplete($pps->NextPps)) && + ($pps->DirPps == -1 || + $this->_ppsTreeComplete($pps->DirPps)); + } + + /** + * Checks whether a PPS is a File PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS + * @return bool true if it's a File PPS, false otherwise + */ + public function isFile($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE); + } + return false; + } + + /** + * Checks whether a PPS is a Root PPS or not. + * If there is no PPS for the index given, it will return false. + * + * @access public + * @param integer $index The index for the PPS. + * @return bool true if it's a Root PPS, false otherwise + */ + public function isRoot($index) + { + if (isset($this->_list[$index])) { + return ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT); + } + return false; + } + + /** + * Gives the total number of PPS's found in the OLE container. + * + * @access public + * @return integer The total number of PPS's found in the OLE container + */ + public function ppsTotal() + { + return count($this->_list); + } + + /** + * Gets data from a PPS + * If there is no PPS for the index given, it will return an empty string. + * + * @access public + * @param integer $index The index for the PPS + * @param integer $position The position from which to start reading + * (relative to the PPS) + * @param integer $length The amount of bytes to read (at most) + * @return string The binary string containing the data requested + * @see OLE_PPS_File::getStream() + */ + public function getData($index, $position, $length) + { + // if position is not valid return empty string + if (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) { + return ''; + } + $fh = $this->getStream($this->_list[$index]); + $data = stream_get_contents($fh, $length, $position); + fclose($fh); + return $data; + } + + /** + * Gets the data length from a PPS + * If there is no PPS for the index given, it will return 0. + * + * @access public + * @param integer $index The index for the PPS + * @return integer The amount of bytes in data the PPS has + */ + public function getDataLength($index) + { + if (isset($this->_list[$index])) { + return $this->_list[$index]->Size; + } + return 0; + } + + /** + * Utility function to transform ASCII text to Unicode + * + * @access public + * @static + * @param string $ascii The ASCII string to transform + * @return string The string in Unicode + */ + public static function Asc2Ucs($ascii) + { + $rawname = ''; + for ($i = 0; $i < strlen($ascii); ++$i) { + $rawname .= $ascii{$i} . "\x00"; + } + return $rawname; + } + + /** + * Utility function + * Returns a string for the OLE container with the date given + * + * @access public + * @static + * @param integer $date A timestamp + * @return string The string for the OLE container + */ + public static function LocalDate2OLE($date = null) + { + if (!isset($date)) { + return "\x00\x00\x00\x00\x00\x00\x00\x00"; + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2, 32); + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + // calculate seconds + $big_date = $days*24*3600 + gmmktime(date("H",$date),date("i",$date),date("s",$date), + date("m",$date),date("d",$date),date("Y",$date)); + // multiply just to make MS happy + $big_date *= 10000000; + + $high_part = floor($big_date / $factor); + // lower 4 bytes + $low_part = floor((($big_date / $factor) - $high_part) * $factor); + + // Make HEX string + $res = ''; + + for ($i = 0; $i < 4; ++$i) { + $hex = $low_part % 0x100; + $res .= pack('c', $hex); + $low_part /= 0x100; + } + for ($i = 0; $i < 4; ++$i) { + $hex = $high_part % 0x100; + $res .= pack('c', $hex); + $high_part /= 0x100; + } + return $res; + } + + /** + * Returns a timestamp from an OLE container's date + * + * @access public + * @static + * @param integer $string A binary string with the encoded date + * @return string The timestamp corresponding to the string + */ + public static function OLE2LocalDate($string) + { + if (strlen($string) != 8) { + return new PEAR_Error("Expecting 8 byte string"); + } + + // factor used for separating numbers into 4 bytes parts + $factor = pow(2,32); + list(, $high_part) = unpack('V', substr($string, 4, 4)); + list(, $low_part) = unpack('V', substr($string, 0, 4)); + + $big_date = ($high_part * $factor) + $low_part; + // translate to seconds + $big_date /= 10000000; + + // days from 1-1-1601 until the beggining of UNIX era + $days = 134774; + + // translate to seconds from beggining of UNIX era + $big_date -= $days * 24 * 3600; + return floor($big_date); + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php b/extend/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php new file mode 100755 index 0000000..3dcd7e1 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLE/ChainedBlockStream.php @@ -0,0 +1,230 @@ +<?php +/** + * PHPExcel + * + * Copyright (C) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_OLE + * @copyright Copyright (c) 2006 - 2007 Christian Schmidt + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +/** + * PHPExcel_Shared_OLE_ChainedBlockStream + * + * Stream wrapper for reading data stored in an OLE file. Implements methods + * for PHP's stream_wrapper_register(). For creating streams using this + * wrapper, use PHPExcel_Shared_OLE_PPS_File::getStream(). + * + * @category PHPExcel + * @package PHPExcel_Shared_OLE + */ +class PHPExcel_Shared_OLE_ChainedBlockStream +{ + /** + * The OLE container of the file that is being read. + * @var OLE + */ + public $ole; + + /** + * Parameters specified by fopen(). + * @var array + */ + public $params; + + /** + * The binary data of the file. + * @var string + */ + public $data; + + /** + * The file pointer. + * @var int byte offset + */ + public $pos; + + /** + * Implements support for fopen(). + * For creating streams using this wrapper, use OLE_PPS_File::getStream(). + * + * @param string $path resource name including scheme, e.g. + * ole-chainedblockstream://oleInstanceId=1 + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success + */ + public function stream_open($path, $mode, $options, &$openedPath) + { + if ($mode != 'r') { + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('Only reading is supported', E_USER_WARNING); + } + return false; + } + + // 25 is length of "ole-chainedblockstream://" + parse_str(substr($path, 25), $this->params); + if (!isset($this->params['oleInstanceId'], + $this->params['blockId'], + $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { + + if ($options & STREAM_REPORT_ERRORS) { + trigger_error('OLE stream not found', E_USER_WARNING); + } + return false; + } + $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; + + $blockId = $this->params['blockId']; + $this->data = ''; + if (isset($this->params['size']) && + $this->params['size'] < $this->ole->bigBlockThreshold && + $blockId != $this->ole->root->_StartBlock) { + + // Block id refers to small blocks + $rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock); + while ($blockId != -2) { + $pos = $rootPos + $blockId * $this->ole->bigBlockSize; + $blockId = $this->ole->sbat[$blockId]; + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + } + } else { + // Block id refers to big blocks + while ($blockId != -2) { + $pos = $this->ole->_getBlockOffset($blockId); + fseek($this->ole->_file_handle, $pos); + $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize); + $blockId = $this->ole->bbat[$blockId]; + } + } + if (isset($this->params['size'])) { + $this->data = substr($this->data, 0, $this->params['size']); + } + + if ($options & STREAM_USE_PATH) { + $openedPath = $path; + } + + return true; + } + + /** + * Implements support for fclose(). + * + */ + public function stream_close() + { + $this->ole = null; + unset($GLOBALS['_OLE_INSTANCES']); + } + + /** + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string + */ + public function stream_read($count) + { + if ($this->stream_eof()) { + return false; + } + $s = substr($this->data, $this->pos, $count); + $this->pos += $count; + return $s; + } + + /** + * Implements support for feof(). + * + * @return bool TRUE if the file pointer is at EOF; otherwise FALSE + */ + public function stream_eof() + { +// As we don't support below 5.2 anymore, this is simply redundancy and overhead +// $eof = $this->pos >= strlen($this->data); +// // Workaround for bug in PHP 5.0.x: http://bugs.php.net/27508 +// if (version_compare(PHP_VERSION, '5.0', '>=') && +// version_compare(PHP_VERSION, '5.1', '<')) { +// $eof = !$eof; +// } +// return $eof; + return $this->pos >= strlen($this->data); + } + + /** + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int + */ + public function stream_tell() + { + return $this->pos; + } + + /** + * Implements support for fseek(). + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool + */ + public function stream_seek($offset, $whence) + { + if ($whence == SEEK_SET && $offset >= 0) { + $this->pos = $offset; + } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) { + $this->pos += $offset; + } elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) { + $this->pos = strlen($this->data) + $offset; + } else { + return false; + } + return true; + } + + /** + * Implements support for fstat(). Currently the only supported field is + * "size". + * @return array + */ + public function stream_stat() + { + return array( + 'size' => strlen($this->data), + ); + } + + // Methods used by stream_wrapper_register() that are not implemented: + // bool stream_flush ( void ) + // int stream_write ( string data ) + // bool rename ( string path_from, string path_to ) + // bool mkdir ( string path, int mode, int options ) + // bool rmdir ( string path, int options ) + // bool dir_opendir ( string path, int options ) + // array url_stat ( string path, int flags ) + // string dir_readdir ( void ) + // bool dir_rewinddir ( void ) + // bool dir_closedir ( void ) +} diff --git a/extend/phpexcel/PHPExcel/Shared/OLE/PPS.php b/extend/phpexcel/PHPExcel/Shared/OLE/PPS.php new file mode 100755 index 0000000..4db0ae4 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLE/PPS.php @@ -0,0 +1,230 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $ + + +/** +* Class for creating PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS +{ + /** + * The PPS index + * @var integer + */ + public $No; + + /** + * The PPS name (in Unicode) + * @var string + */ + public $Name; + + /** + * The PPS type. Dir, Root or File + * @var integer + */ + public $Type; + + /** + * The index of the previous PPS + * @var integer + */ + public $PrevPps; + + /** + * The index of the next PPS + * @var integer + */ + public $NextPps; + + /** + * The index of it's first child if this is a Dir or Root PPS + * @var integer + */ + public $DirPps; + + /** + * A timestamp + * @var integer + */ + public $Time1st; + + /** + * A timestamp + * @var integer + */ + public $Time2nd; + + /** + * Starting block (small or big) for this PPS's data inside the container + * @var integer + */ + public $_StartBlock; + + /** + * The size of the PPS's data (in bytes) + * @var integer + */ + public $Size; + + /** + * The PPS's data (only used if it's not using a temporary file) + * @var string + */ + public $_data; + + /** + * Array of child PPS's (only used by Root and Dir PPS's) + * @var array + */ + public $children = array(); + + /** + * Pointer to OLE container + * @var OLE + */ + public $ole; + + /** + * The constructor + * + * @access public + * @param integer $No The PPS index + * @param string $name The PPS name + * @param integer $type The PPS type. Dir, Root or File + * @param integer $prev The index of the previous PPS + * @param integer $next The index of the next PPS + * @param integer $dir The index of it's first child if this is a Dir or Root PPS + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + * @param string $data The (usually binary) source data of the PPS + * @param array $children Array containing children PPS for this PPS + */ + public function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children) + { + $this->No = $No; + $this->Name = $name; + $this->Type = $type; + $this->PrevPps = $prev; + $this->NextPps = $next; + $this->DirPps = $dir; + $this->Time1st = $time_1st; + $this->Time2nd = $time_2nd; + $this->_data = $data; + $this->children = $children; + if ($data != '') { + $this->Size = strlen($data); + } else { + $this->Size = 0; + } + } + + /** + * Returns the amount of data saved for this PPS + * + * @access public + * @return integer The amount of data (in bytes) + */ + public function _DataLen() + { + if (!isset($this->_data)) { + return 0; + } + //if (isset($this->_PPS_FILE)) { + // fseek($this->_PPS_FILE, 0); + // $stats = fstat($this->_PPS_FILE); + // return $stats[7]; + //} else { + return strlen($this->_data); + //} + } + + /** + * Returns a string with the PPS's WK (What is a WK?) + * + * @access public + * @return string The binary string + */ + public function _getPpsWk() + { + $ret = str_pad($this->Name,64,"\x00"); + + $ret .= pack("v", strlen($this->Name) + 2) // 66 + . pack("c", $this->Type) // 67 + . pack("c", 0x00) //UK // 68 + . pack("V", $this->PrevPps) //Prev // 72 + . pack("V", $this->NextPps) //Next // 76 + . pack("V", $this->DirPps) //Dir // 80 + . "\x00\x09\x02\x00" // 84 + . "\x00\x00\x00\x00" // 88 + . "\xc0\x00\x00\x00" // 92 + . "\x00\x00\x00\x46" // 96 // Seems to be ok only for Root + . "\x00\x00\x00\x00" // 100 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st) // 108 + . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd) // 116 + . pack("V", isset($this->_StartBlock)? + $this->_StartBlock:0) // 120 + . pack("V", $this->Size) // 124 + . pack("V", 0); // 128 + return $ret; + } + + /** + * Updates index and pointers to previous, next and children PPS's for this + * PPS. I don't think it'll work with Dir PPS's. + * + * @access public + * @param array &$raList Reference to the array of PPS's for the whole OLE + * container + * @return integer The index for this PPS + */ + public static function _savePpsSetPnt(&$raList, $to_save, $depth = 0) + { + if ( !is_array($to_save) || (empty($to_save)) ) { + return 0xFFFFFFFF; + } elseif( count($to_save) == 1 ) { + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = 0xFFFFFFFF; + $raList[$cnt]->NextPps = 0xFFFFFFFF; + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + } else { + $iPos = floor(count($to_save) / 2); + $aPrev = array_slice($to_save, 0, $iPos); + $aNext = array_slice($to_save, $iPos + 1); + $cnt = count($raList); + // If the first entry, it's the root... Don't clone it! + $raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos]; + $raList[$cnt]->No = $cnt; + $raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++); + $raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++); + $raList[$cnt]->DirPps = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++); + + } + return $cnt; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/OLE/PPS/File.php b/extend/phpexcel/PHPExcel/Shared/OLE/PPS/File.php new file mode 100755 index 0000000..f061f56 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLE/PPS/File.php @@ -0,0 +1,84 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: File.php,v 1.11 2007/02/13 21:00:42 schmidt Exp $ + + +/** +* Class for creating File PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS + { + /** + * The constructor + * + * @access public + * @param string $name The name of the file (in Unicode) + * @see OLE::Asc2Ucs() + */ + public function __construct($name) + { + parent::__construct( + null, + $name, + PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE, + null, + null, + null, + null, + null, + '', + array()); + } + + /** + * Initialization method. Has to be called right after OLE_PPS_File(). + * + * @access public + * @return mixed true on success + */ + public function init() + { + return true; + } + + /** + * Append data to PPS + * + * @access public + * @param string $data The data to append + */ + public function append($data) + { + $this->_data .= $data; + } + + /** + * Returns a stream for reading this file using fread() etc. + * @return resource a read-only stream + */ + public function getStream() + { + $this->ole->getStream($this); + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php b/extend/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php new file mode 100755 index 0000000..eb929d2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLE/PPS/Root.php @@ -0,0 +1,467 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 4 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2002 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available at through the world-wide-web at | +// | http://www.php.net/license/2_02.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Xavier Noguer <xnoguer@php.net> | +// | Based on OLE::Storage_Lite by Kawai, Takanori | +// +----------------------------------------------------------------------+ +// +// $Id: Root.php,v 1.9 2005/04/23 21:53:49 dufuz Exp $ + + +/** +* Class for creating Root PPS's for OLE containers +* +* @author Xavier Noguer <xnoguer@php.net> +* @category PHPExcel +* @package PHPExcel_Shared_OLE +*/ +class PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS + { + + /** + * Directory for temporary files + * @var string + */ + protected $_tmp_dir = NULL; + + /** + * @param integer $time_1st A timestamp + * @param integer $time_2nd A timestamp + */ + public function __construct($time_1st, $time_2nd, $raChild) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + + parent::__construct( + null, + PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'), + PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT, + null, + null, + null, + $time_1st, + $time_2nd, + null, + $raChild); + } + + /** + * Method for saving the whole OLE container (including files). + * In fact, if called with an empty argument (or '-'), it saves to a + * temporary file and then outputs it's contents to stdout. + * If a resource pointer to a stream created by fopen() is passed + * it will be used, but you have to close such stream by yourself. + * + * @param string|resource $filename The name of the file or stream where to save the OLE container. + * @access public + * @return mixed true on success + */ + public function save($filename) + { + // Initial Setting for saving + $this->_BIG_BLOCK_SIZE = pow(2, + ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE) : 9)); + $this->_SMALL_BLOCK_SIZE= pow(2, + ((isset($this->_SMALL_BLOCK_SIZE))? self::_adjust2($this->_SMALL_BLOCK_SIZE): 6)); + + if (is_resource($filename)) { + $this->_FILEH_ = $filename; + } else if ($filename == '-' || $filename == '') { + if ($this->_tmp_dir === NULL) + $this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tmp_filename = tempnam($this->_tmp_dir, "OLE_PPS_Root"); + $this->_FILEH_ = fopen($this->_tmp_filename,"w+b"); + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't create temporary file."); + } + } else { + $this->_FILEH_ = fopen($filename, "wb"); + } + if ($this->_FILEH_ == false) { + throw new PHPExcel_Writer_Exception("Can't open $filename. It may be in use or protected."); + } + // Make an array of PPS's (for Save) + $aList = array(); + PHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this)); + // calculate values for header + list($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo); + // Save Header + $this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt); + + // Make Small Data string (write SBD) + $this->_data = $this->_makeSmallData($aList); + + // Write BB + $this->_saveBigData($iSBDcnt, $aList); + // Write PPS + $this->_savePps($aList); + // Write Big Block Depot and BDList and Adding Header informations + $this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt); + + if (!is_resource($filename)) { + fclose($this->_FILEH_); + } + + return true; + } + + /** + * Calculate some numbers + * + * @access public + * @param array $raList Reference to an array of PPS's + * @return array The array of numbers + */ + public function _calcSize(&$raList) + { + // Calculate Basic Setting + list($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0); + $iSmallLen = 0; + $iSBcnt = 0; + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + } else { + $iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + } + } + $iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE; + $iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + $iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0); + $iBBcnt += (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) + + (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0)); + $iCnt = count($raList); + $iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + $iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0)); + + return array($iSBDcnt, $iBBcnt, $iPPScnt); + } + + /** + * Helper function for caculating a magic value for block sizes + * + * @access public + * @param integer $i2 The argument + * @see save() + * @return integer + */ + private static function _adjust2($i2) + { + $iWk = log($i2)/log(2); + return ($iWk > floor($iWk))? floor($iWk)+1:$iWk; + } + + /** + * Save OLE header + * + * @access public + * @param integer $iSBDcnt + * @param integer $iBBcnt + * @param integer $iPPScnt + */ + public function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt) + { + $FILE = $this->_FILEH_; + + // Calculate Basic Setting + $iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBBcnt + $iPPScnt + $iSBDcnt; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + + // Calculate BD count + if ($iBdCnt > $i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) { + break; + } + } + } + + // Save Header + fwrite($FILE, + "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("v", 0x3b) + . pack("v", 0x03) + . pack("v", -2) + . pack("v", 9) + . pack("v", 6) + . pack("v", 0) + . "\x00\x00\x00\x00" + . "\x00\x00\x00\x00" + . pack("V", $iBdCnt) + . pack("V", $iBBcnt+$iSBDcnt) //ROOT START + . pack("V", 0) + . pack("V", 0x1000) + . pack("V", $iSBDcnt ? 0 : -2) //Small Block Depot + . pack("V", $iSBDcnt) + ); + // Extra BDList Start, Count + if ($iBdCnt < $i1stBdL) { + fwrite($FILE, + pack("V", -2) // Extra BDList Start + . pack("V", 0) // Extra BDList Count + ); + } else { + fwrite($FILE, pack("V", $iAll+$iBdCnt) . pack("V", $iBdExL)); + } + + // BDList + for ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", $iAll+$i)); + } + if ($i < $i1stBdL) { + $jB = $i1stBdL - $i; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, (pack("V", -1))); + } + } + } + + /** + * Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param integer $iStBlk + * @param array &$raList Reference to array of PPS's + */ + public function _saveBigData($iStBlk, &$raList) + { + $FILE = $this->_FILEH_; + + // cycle through PPS's + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + if ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) { + $raList[$i]->Size = $raList[$i]->_DataLen(); + if (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) || + (($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data))) + { + // Write Data + //if (isset($raList[$i]->_PPS_FILE)) { + // $iLen = 0; + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $iLen += strlen($sBuff); + // fwrite($FILE, $sBuff); + // } + //} else { + fwrite($FILE, $raList[$i]->_data); + //} + + if ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) { + fwrite($FILE, str_repeat("\x00", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE))); + } + // Set For PPS + $raList[$i]->_StartBlock = $iStBlk; + $iStBlk += + (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0)); + } + // Close file for each PPS, and unlink it + //if (isset($raList[$i]->_PPS_FILE)) { + // fclose($raList[$i]->_PPS_FILE); + // $raList[$i]->_PPS_FILE = null; + // unlink($raList[$i]->_tmp_filename); + //} + } + } + } + + /** + * get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) + * + * @access public + * @param array &$raList Reference to array of PPS's + */ + public function _makeSmallData(&$raList) + { + $sRes = ''; + $FILE = $this->_FILEH_; + $iSmBlk = 0; + + $iCount = count($raList); + for ($i = 0; $i < $iCount; ++$i) { + // Make SBD, small data string + if ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) { + if ($raList[$i]->Size <= 0) { + continue; + } + if ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) { + $iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE) + + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0); + // Add to SBD + $jB = $iSmbCnt - 1; + for ($j = 0; $j < $jB; ++$j) { + fwrite($FILE, pack("V", $j+$iSmBlk+1)); + } + fwrite($FILE, pack("V", -2)); + + //// Add to Data String(this will be written for RootEntry) + //if ($raList[$i]->_PPS_FILE) { + // fseek($raList[$i]->_PPS_FILE, 0); // To The Top + // while ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) { + // $sRes .= $sBuff; + // } + //} else { + $sRes .= $raList[$i]->_data; + //} + if ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) { + $sRes .= str_repeat("\x00",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)); + } + // Set for PPS + $raList[$i]->_StartBlock = $iSmBlk; + $iSmBlk += $iSmbCnt; + } + } + } + $iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE); + if ($iSmBlk % $iSbCnt) { + $iB = $iSbCnt - ($iSmBlk % $iSbCnt); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + return $sRes; + } + + /** + * Saves all the PPS's WKs + * + * @access public + * @param array $raList Reference to an array with all PPS's + */ + public function _savePps(&$raList) + { + // Save each PPS WK + $iC = count($raList); + for ($i = 0; $i < $iC; ++$i) { + fwrite($this->_FILEH_, $raList[$i]->_getPpsWk()); + } + // Adjust for Block + $iCnt = count($raList); + $iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE; + if ($iCnt % $iBCnt) { + fwrite($this->_FILEH_, str_repeat("\x00",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE)); + } + } + + /** + * Saving Big Block Depot + * + * @access public + * @param integer $iSbdSize + * @param integer $iBsize + * @param integer $iPpsCnt + */ + public function _saveBbd($iSbdSize, $iBsize, $iPpsCnt) + { + $FILE = $this->_FILEH_; + // Calculate Basic Setting + $iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + $i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE; + + $iBdExL = 0; + $iAll = $iBsize + $iPpsCnt + $iSbdSize; + $iAllW = $iAll; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + // Calculate BD count + if ($iBdCnt >$i1stBdL) { + while (1) { + ++$iBdExL; + ++$iAllW; + $iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0); + $iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0); + if ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) { + break; + } + } + } + + // Making BD + // Set for SBD + if ($iSbdSize > 0) { + for ($i = 0; $i < ($iSbdSize - 1); ++$i) { + fwrite($FILE, pack("V", $i+1)); + } + fwrite($FILE, pack("V", -2)); + } + // Set for B + for ($i = 0; $i < ($iBsize - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+1)); + } + fwrite($FILE, pack("V", -2)); + + // Set for PPS + for ($i = 0; $i < ($iPpsCnt - 1); ++$i) { + fwrite($FILE, pack("V", $i+$iSbdSize+$iBsize+1)); + } + fwrite($FILE, pack("V", -2)); + // Set for BBD itself ( 0xFFFFFFFD : BBD) + for ($i = 0; $i < $iBdCnt; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFD)); + } + // Set for ExtraBDList + for ($i = 0; $i < $iBdExL; ++$i) { + fwrite($FILE, pack("V", 0xFFFFFFFC)); + } + // Adjust for Block + if (($iAllW + $iBdCnt) % $iBbCnt) { + $iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt)); + for ($i = 0; $i < $iBlock; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + // Extra BDList + if ($iBdCnt > $i1stBdL) { + $iN=0; + $iNb=0; + for ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) { + if ($iN >= ($iBbCnt - 1)) { + $iN = 0; + ++$iNb; + fwrite($FILE, pack("V", $iAll+$iBdCnt+$iNb)); + } + fwrite($FILE, pack("V", $iBsize+$iSbdSize+$iPpsCnt+$i)); + } + if (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) { + $iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1)); + for ($i = 0; $i < $iB; ++$i) { + fwrite($FILE, pack("V", -1)); + } + } + fwrite($FILE, pack("V", -2)); + } + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/OLERead.php b/extend/phpexcel/PHPExcel/Shared/OLERead.php new file mode 100755 index 0000000..c4cb7da --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/OLERead.php @@ -0,0 +1,317 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +defined('IDENTIFIER_OLE') || + define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1)); + +class PHPExcel_Shared_OLERead { + private $data = ''; + + // OLE identifier + const IDENTIFIER_OLE = IDENTIFIER_OLE; + + // Size of a sector = 512 bytes + const BIG_BLOCK_SIZE = 0x200; + + // Size of a short sector = 64 bytes + const SMALL_BLOCK_SIZE = 0x40; + + // Size of a directory entry always = 128 bytes + const PROPERTY_STORAGE_BLOCK_SIZE = 0x80; + + // Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams + const SMALL_BLOCK_THRESHOLD = 0x1000; + + // header offsets + const NUM_BIG_BLOCK_DEPOT_BLOCKS_POS = 0x2c; + const ROOT_START_BLOCK_POS = 0x30; + const SMALL_BLOCK_DEPOT_BLOCK_POS = 0x3c; + const EXTENSION_BLOCK_POS = 0x44; + const NUM_EXTENSION_BLOCK_POS = 0x48; + const BIG_BLOCK_DEPOT_BLOCKS_POS = 0x4c; + + // property storage offsets (directory offsets) + const SIZE_OF_NAME_POS = 0x40; + const TYPE_POS = 0x42; + const START_BLOCK_POS = 0x74; + const SIZE_POS = 0x78; + + + + public $wrkbook = null; + public $summaryInformation = null; + public $documentSummaryInformation = null; + + + /** + * Read the file + * + * @param $sFileName string Filename + * @throws PHPExcel_Reader_Exception + */ + public function read($sFileName) + { + // Check if file exists and is readable + if(!is_readable($sFileName)) { + throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable."); + } + + // Get the file identifier + // Don't bother reading the whole file until we know it's a valid OLE file + $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8); + + // Check OLE identifier + if ($this->data != self::IDENTIFIER_OLE) { + throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file'); + } + + // Get the file data + $this->data = file_get_contents($sFileName); + + // Total number of sectors used for the SAT + $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); + + // SecID of the first sector of the directory stream + $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS); + + // SecID of the first sector of the SSAT (or -2 if not extant) + $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS); + + // SecID of the first sector of the MSAT (or -2 if no additional sectors are used) + $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS); + + // Total number of sectors used by MSAT + $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS); + + $bigBlockDepotBlocks = array(); + $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS; + + $bbdBlocks = $this->numBigBlockDepotBlocks; + + if ($this->numExtensionBlocks != 0) { + $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4; + } + + for ($i = 0; $i < $bbdBlocks; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + for ($j = 0; $j < $this->numExtensionBlocks; ++$j) { + $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE; + $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1); + + for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) { + $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos); + $pos += 4; + } + + $bbdBlocks += $blocksToRead; + if ($bbdBlocks < $this->numBigBlockDepotBlocks) { + $this->extensionBlock = self::_GetInt4d($this->data, $pos); + } + } + + $pos = 0; + $this->bigBlockChain = ''; + $bbs = self::BIG_BLOCK_SIZE / 4; + for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) { + $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE; + + $this->bigBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + } + + $pos = 0; + $sbdBlock = $this->sbdStartBlock; + $this->smallBlockChain = ''; + while ($sbdBlock != -2) { + $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE; + + $this->smallBlockChain .= substr($this->data, $pos, 4*$bbs); + $pos += 4*$bbs; + + $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4); + } + + // read the directory stream + $block = $this->rootStartBlock; + $this->entry = $this->_readData($block); + + $this->_readPropertySets(); + } + + /** + * Extract binary stream data + * + * @return string + */ + public function getStream($stream) + { + if ($stream === NULL) { + return null; + } + + $streamData = ''; + + if ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) { + $rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']); + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = $block * self::SMALL_BLOCK_SIZE; + $streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE); + + $block = self::_GetInt4d($this->smallBlockChain, $block*4); + } + + return $streamData; + } else { + $numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE; + if ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) { + ++$numBlocks; + } + + if ($numBlocks == 0) return ''; + + $block = $this->props[$stream]['startBlock']; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + + return $streamData; + } + } + + /** + * Read a standard stream (by joining sectors using information from SAT) + * + * @param int $bl Sector ID where the stream starts + * @return string Data for standard stream + */ + private function _readData($bl) + { + $block = $bl; + $data = ''; + + while ($block != -2) { + $pos = ($block + 1) * self::BIG_BLOCK_SIZE; + $data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE); + $block = self::_GetInt4d($this->bigBlockChain, $block*4); + } + return $data; + } + + /** + * Read entries in the directory stream. + */ + private function _readPropertySets() { + $offset = 0; + + // loop through entires, each entry is 128 bytes + $entryLen = strlen($this->entry); + while ($offset < $entryLen) { + // entry data (128 bytes) + $d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE); + + // size in bytes of name + $nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8); + + // type of entry + $type = ord($d[self::TYPE_POS]); + + // sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook) + // sectorID of first sector of the short-stream container stream, if this entry is root entry + $startBlock = self::_GetInt4d($d, self::START_BLOCK_POS); + + $size = self::_GetInt4d($d, self::SIZE_POS); + + $name = str_replace("\x00", "", substr($d,0,$nameSize)); + + + $this->props[] = array ( + 'name' => $name, + 'type' => $type, + 'startBlock' => $startBlock, + 'size' => $size); + + // tmp helper to simplify checks + $upName = strtoupper($name); + + // Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook) + if (($upName === 'WORKBOOK') || ($upName === 'BOOK')) { + $this->wrkbook = count($this->props) - 1; + } + else if ( $upName === 'ROOT ENTRY' || $upName === 'R') { + // Root entry + $this->rootentry = count($this->props) - 1; + } + + // Summary information + if ($name == chr(5) . 'SummaryInformation') { +// echo 'Summary Information<br />'; + $this->summaryInformation = count($this->props) - 1; + } + + // Additional Document Summary information + if ($name == chr(5) . 'DocumentSummaryInformation') { +// echo 'Document Summary Information<br />'; + $this->documentSummaryInformation = count($this->props) - 1; + } + + $offset += self::PROPERTY_STORAGE_BLOCK_SIZE; + } + + } + + /** + * Read 4 bytes of data at specified position + * + * @param string $data + * @param int $pos + * @return int + */ + private static function _GetInt4d($data, $pos) + { + // FIX: represent numbers correctly on 64-bit system + // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334 + // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems + $_or_24 = ord($data[$pos + 3]); + if ($_or_24 >= 128) { + // negative number + $_ord_24 = -abs((256 - $_or_24) << 24); + } else { + $_ord_24 = ($_or_24 & 127) << 24; + } + return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt b/extend/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt new file mode 100755 index 0000000..cbee875 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/PCLZip/gnu-lgpl.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/extend/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php b/extend/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php new file mode 100755 index 0000000..4bf05a5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/PCLZip/pclzip.lib.php @@ -0,0 +1,5694 @@ +<?php +// -------------------------------------------------------------------------------- +// PhpConcept Library - Zip Module 2.8.2 +// -------------------------------------------------------------------------------- +// License GNU/LGPL - Vincent Blavet - August 2009 +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// +// Presentation : +// PclZip is a PHP library that manage ZIP archives. +// So far tests show that archives generated by PclZip are readable by +// WinZip application and other tools. +// +// Description : +// See readme.txt and http://www.phpconcept.net +// +// Warning : +// This library and the associated files are non commercial, non professional +// work. +// It should not have unexpected results. However if any damage is caused by +// this software the author can not be responsible. +// The use of this software is at the risk of the user. +// +// -------------------------------------------------------------------------------- +// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $ +// -------------------------------------------------------------------------------- + + // ----- Constants + if (!defined('PCLZIP_READ_BLOCK_SIZE')) { + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); + } + + // ----- File list separator + // In version 1.x of PclZip, the separator for file list is a space + // (which is not a very smart choice, specifically for windows paths !). + // A better separator should be a comma (,). This constant gives you the + // abilty to change that. + // However notice that changing this value, may have impact on existing + // scripts, using space separated filenames. + // Recommanded values for compatibility with older versions : + //define( 'PCLZIP_SEPARATOR', ' ' ); + // Recommanded values for smart separation of filenames. + if (!defined('PCLZIP_SEPARATOR')) { + define( 'PCLZIP_SEPARATOR', ',' ); + } + + // ----- Error configuration + // 0 : PclZip Class integrated error handling + // 1 : PclError external library error handling. By enabling this + // you must ensure that you have included PclError library. + // [2,...] : reserved for futur use + if (!defined('PCLZIP_ERROR_EXTERNAL')) { + define( 'PCLZIP_ERROR_EXTERNAL', 0 ); + } + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); + if (!defined('PCLZIP_TEMPORARY_DIR')) { + define( 'PCLZIP_TEMPORARY_DIR', '' ); + } + + // ----- Optional threshold ratio for use of temporary files + // Pclzip sense the size of the file to add/extract and decide to + // use or not temporary file. The algorythm is looking for + // memory_limit of PHP and apply a ratio. + // threshold = memory_limit * ratio. + // Recommended values are under 0.5. Default 0.47. + // Samples : + // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 ); + if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) { + define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 ); + } + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** +// -------------------------------------------------------------------------------- + + // ----- Global variables + $g_pclzip_version = "2.8.2"; + + // ----- Error codes + // -1 : Unable to open file in binary write mode + // -2 : Unable to open file in binary read mode + // -3 : Invalid parameters + // -4 : File does not exist + // -5 : Filename is too long (max. 255) + // -6 : Not a valid zip file + // -7 : Invalid extracted file size + // -8 : Unable to create directory + // -9 : Invalid archive extension + // -10 : Invalid archive format + // -11 : Unable to delete file (unlink) + // -12 : Unable to rename file (rename) + // -13 : Invalid header checksum + // -14 : Invalid archive size + define( 'PCLZIP_ERR_USER_ABORTED', 2 ); + define( 'PCLZIP_ERR_NO_ERROR', 0 ); + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'PCLZIP_ERR_MISSING_FILE', -4 ); + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); + define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + + // ----- Options values + define( 'PCLZIP_OPT_PATH', 77001 ); + define( 'PCLZIP_OPT_ADD_PATH', 77002 ); + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); + define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); + define( 'PCLZIP_OPT_BY_NAME', 77008 ); + define( 'PCLZIP_OPT_BY_INDEX', 77009 ); + define( 'PCLZIP_OPT_BY_EREG', 77010 ); + define( 'PCLZIP_OPT_BY_PREG', 77011 ); + define( 'PCLZIP_OPT_COMMENT', 77012 ); + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); + // Having big trouble with crypt. Need to multiply 2 long int + // which is not correctly supported by PHP ... + //define( 'PCLZIP_OPT_CRYPT', 77018 ); + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 ); + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias + + // ----- File description attributes + define( 'PCLZIP_ATT_FILE_NAME', 79001 ); + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); + define( 'PCLZIP_ATT_FILE_MTIME', 79004 ); + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 ); + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 ); + + // ----- Call backs values + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); + define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); + define( 'PCLZIP_CB_PRE_ADD', 78003 ); + define( 'PCLZIP_CB_POST_ADD', 78004 ); + /* For futur use + define( 'PCLZIP_CB_PRE_LIST', 78005 ); + define( 'PCLZIP_CB_POST_LIST', 78006 ); + define( 'PCLZIP_CB_PRE_DELETE', 78007 ); + define( 'PCLZIP_CB_POST_DELETE', 78008 ); + */ + + // -------------------------------------------------------------------------------- + // Class : PclZip + // Description : + // PclZip is the class that represent a Zip archive. + // The public methods allow the manipulation of the archive. + // Attributes : + // Attributes must not be accessed directly. + // Methods : + // PclZip() : Object creator + // create() : Creates the Zip archive + // listContent() : List the content of the Zip archive + // extract() : Extract the content of the archive + // properties() : List the properties of the archive + // -------------------------------------------------------------------------------- + class PclZip + { + // ----- Filename of the zip file + var $zipname = ''; + + // ----- File descriptor of the zip file + var $zip_fd = 0; + + // ----- Internal error handling + var $error_code = 1; + var $error_string = ''; + + // ----- Current status of the magic_quotes_runtime + // This value store the php configuration for magic_quotes + // The class can then disable the magic_quotes and reset it after + var $magic_quotes_status; + + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { + + // ----- Tests the zlib + if (!function_exists('gzopen')) + { + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } + + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ,PCLZIP_ATT_FILE_MTIME => 'optional' + ,PCLZIP_ATT_FILE_CONTENT => 'optional' + ,PCLZIP_ATT_FILE_COMMENT => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + return 0; + } + + // ----- Return + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exist and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Trace + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional', + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional', + PCLZIP_OPT_TEMP_FILE_ON => 'optional', + PCLZIP_OPT_TEMP_FILE_OFF => 'optional' + )); + if ($v_result != 1) { + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + } + else { + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + return 0; + } + } + } + + // ----- Trace + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Look for default option values + $this->privOptionDefaultThreshold($v_options); + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + return(0); + } + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + return(0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_THRESHOLD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + // ----- Check the value + $v_value = $p_options_list[$i+1]; + if ((!is_integer($v_value)) || ($v_value<0)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + return PclZip::errorCode(); + } + + // ----- Get the value (and convert it in bytes) + $v_result_list[$p_options_list[$i]] = $v_value*1048576; + $i++; + break; + + case PCLZIP_OPT_TEMP_FILE_ON : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_TEMP_FILE_OFF : + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); + return PclZip::errorCode(); + } + // ----- Check for incompatible options + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); + return PclZip::errorCode(); + } + + $v_result_list[$p_options_list[$i]] = true; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); + $i++; + } + else { + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG + // to PCLZIP_OPT_BY_PREG + $p_options_list[$i] = PCLZIP_OPT_BY_PREG; + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + return PclZip::errorCode(); + } + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + return PclZip::errorCode(); + } + } + } + } + + // ----- Look for default values + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { + + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOptionDefaultThreshold() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privOptionDefaultThreshold(&$p_options) + { + $v_result=1; + + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { + return $v_result; + } + + // ----- Get 'memory_limit' configuration value + $v_memory_limit = ini_get('memory_limit'); + $v_memory_limit = trim($v_memory_limit); + $last = strtolower(substr($v_memory_limit, -1)); + + if($last == 'g') + //$v_memory_limit = $v_memory_limit*1024*1024*1024; + $v_memory_limit = $v_memory_limit*1073741824; + if($last == 'm') + //$v_memory_limit = $v_memory_limit*1024*1024; + $v_memory_limit = $v_memory_limit*1048576; + if($last == 'k') + $v_memory_limit = $v_memory_limit*1024; + + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); + + + // ----- Sanity check : No threshold if value lower than 1M + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + break; + + // ----- Look for options that takes a string + case PCLZIP_ATT_FILE_COMMENT : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['comment'] = $v_value; + break; + + case PCLZIP_ATT_FILE_MTIME : + if (!is_integer($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); + return PclZip::errorCode(); + } + + $p_filedescr['mtime'] = $v_value; + break; + + case PCLZIP_ATT_FILE_CONTENT : + $p_filedescr['content'] = $v_value; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // This method look for each item of the list to see if its a file, a folder + // or a string to be added as file. For any other type of files (link, other) + // just ignore the item. + // Then prepare the information that will be stored for that file. + // When its a folder, expand the folder with all the files that are in that + // folder (recursively). + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + + // ----- Look for real file or folder + if (file_exists($v_descr['filename'])) { + if (@is_file($v_descr['filename'])) { + $v_descr['type'] = 'file'; + } + else if (@is_dir($v_descr['filename'])) { + $v_descr['type'] = 'folder'; + } + else if (@is_link($v_descr['filename'])) { + // skip + continue; + } + else { + // skip + continue; + } + } + + // ----- Look for string added as file + else if (isset($v_descr['content'])) { + $v_descr['type'] = 'virtual_file'; + } + + // ----- Missing file + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if (($v_descr['stored_filename'] != $v_descr['filename']) + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + if ($v_descr['stored_filename'] != '') { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + else { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler; + } + } + + $v_dirlist_nb++; + } + + @closedir($v_folder_handler); + } + else { + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + return $v_result; + } + + // ----- Concat the resulting list + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + } + else { + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); + + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + continue; + } + + // ----- Check the filename + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file') + && (!file_exists($p_filedescr_list[$j]['filename']))) { + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); + return PclZip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all path remove option + // or a dir with all its path removed +// if ( (is_file($p_filedescr_list[$j]['filename'])) +// || ( is_dir($p_filedescr_list[$j]['filename']) + if ( ($p_filedescr_list[$j]['type'] == 'file') + || ($p_filedescr_list[$j]['type'] == 'virtual_file') + || ( ($p_filedescr_list[$j]['type'] == 'folder') + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) + ) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + /* TBC : Removed + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + } + */ + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename; + $p_header['stored_filename'] = $p_filedescr['stored_filename']; + $p_header['extra'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for regular file + if ($p_filedescr['type']=='file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for regular folder + else if ($p_filedescr['type']=='folder') { + $p_header['external'] = 0x00000010; + $p_header['mtime'] = filemtime($p_filename); + $p_header['size'] = filesize($p_filename); + } + + // ----- Look for virtual file + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['external'] = 0x00000000; + $p_header['size'] = strlen($p_filedescr['content']); + } + + + // ----- Look for filetime + if (isset($p_filedescr['mtime'])) { + $p_header['mtime'] = $p_filedescr['mtime']; + } + else if ($p_filedescr['type'] == 'virtual_file') { + $p_header['mtime'] = time(); + } + else { + $p_header['mtime'] = filemtime($p_filename); + } + + // ------ Look for file comment + if (isset($p_filedescr['comment'])) { + $p_header['comment_len'] = strlen($p_filedescr['comment']); + $p_header['comment'] = $p_filedescr['comment']; + } + else { + $p_header['comment_len'] = 0; + $p_header['comment'] = ''; + } + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if ($p_filedescr['type'] == 'file') { + // ----- Look for using temporary file to zip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Use "in memory" zip algo + else { + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Close the file + @fclose($v_file); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + + } + + } + + // ----- Look for a virtual file (a file from string) + else if ($p_filedescr['type'] == 'virtual_file') { + + $v_content = $p_filedescr['content']; + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Look for no compression + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + + // ----- Look for normal compression + else { + // ----- Compress the content + $v_content = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content); + $p_header['compression'] = 8; + } + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']); + } + + // ----- Look for a directory + else if ($p_filedescr['type'] == 'folder') { + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) + { + $v_result=PCLZIP_ERR_NO_ERROR; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + return PclZip::errorCode(); + } + + // ----- Creates a compressed temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = filesize($p_filename); + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @gzputs($v_file_compressed, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file); + @gzclose($v_file_compressed); + + // ----- Check the minimum file size + if (filesize($v_gzip_temp_name) < 18) { + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes'); + return PclZip::errorCode(); + } + + // ----- Extract the compressed attributes + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the gzip file header + $v_binary_data = @fread($v_file_compressed, 10); + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data); + + // ----- Check some parameters + $v_data_header['os'] = bin2hex($v_data_header['os']); + + // ----- Read the gzip file footer + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); + $v_binary_data = @fread($v_file_compressed, 8); + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data); + + // ----- Set the attributes + $p_header['compression'] = ord($v_data_header['cm']); + //$p_header['mtime'] = $v_data_header['mtime']; + $p_header['crc'] = $v_data_footer['crc']; + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18; + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + return $v_result; + } + + // ----- Add the compressed data + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) + { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + fseek($v_file_compressed, 10); + $v_size = $p_header['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($v_file_compressed, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close the file + @fclose($v_file_compressed); + + // ----- Unlink the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + // Its when we cahnge just the filename but not the path + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + } + else { + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + } + } + } + + // ----- Remove drive letter if any + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); + + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Go to beginning of Central Dir + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // $p_info['crc'] = CRC of the file content. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + $v_result=1; + + // ----- Get the interesting attributes + $v_temp_path = PclZipUtilPathReduction($p_header['filename']); + $p_info['filename'] = $v_temp_path; + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']); + $p_info['stored_filename'] = $v_temp_path; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + $p_info['crc'] = $p_header['crc']; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + $p_path = substr($p_path, 0, strlen($p_path)-1); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read next Central dir entry + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + $v_extract = true; + } + + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); + + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { + + // ----- Go to the file position + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + $v_string = ''; + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + + $p_entry['status'] = "filtered"; + + return $v_result; + } + + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); + + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); + + return PclZip::errorCode(); + } + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + } + else { + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + return PclZip::errorCode(); + } + } + } + else { + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + return $v_result; + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } + else { + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.'); + return PclZip::errorCode(); + } + + + // ----- Look for using temporary file to unzip + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) { + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); + if ($v_result < PCLZIP_ERR_NO_ERROR) { + return $v_result; + } + } + + // ----- Look for extract in memory + else { + + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + } + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileUsingTempFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileUsingTempFile(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Creates a temporary file + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz'; + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { + fclose($v_file); + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode'); + return PclZip::errorCode(); + } + + + // ----- Write gz file format header + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3)); + @fwrite($v_dest_file, $v_binary_data, 10); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Write gz file format footer + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']); + @fwrite($v_dest_file, $v_binary_data, 8); + + // ----- Close the temporary file + @fclose($v_dest_file); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + $p_entry['status'] = "write_error"; + return $v_result; + } + + // ----- Open the temporary gz file + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) { + @fclose($v_dest_file); + $p_entry['status'] = "read_error"; + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode'); + return PclZip::errorCode(); + } + + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['size']; + while ($v_size != 0) { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($v_src_file, $v_read_size); + //$v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + @fclose($v_dest_file); + @gzclose($v_src_file); + + // ----- Delete the temporary file + @unlink($v_gzip_temp_name); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + // ----- Trace + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) + { + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + return $v_result; + } + + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + } + + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + // if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + } + else { + // TBC : error : can not extract a folder in a string + } + + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Swap the content to header + $v_local_header['content'] = $p_string; + $p_string = ''; + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); + + // ----- Swap back the content to header + $p_string = $v_local_header['content']; + unset($v_local_header['content']); + + // ----- Look for abort result + if ($v_result == 2) { + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + + // ----- Get extra_fields + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + $p_header['compression'] = $v_data['compression']; + $p_header['size'] = $v_data['size']; + $p_header['compressed_size'] = $v_data['compressed_size']; + $p_header['crc'] = $v_data['crc']; + $p_header['flag'] = $v_data['flag']; + $p_header['filename_len'] = $v_data['filename_len']; + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + + // ----- Get extra + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + + // ----- Get comment + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + + // ----- Extract properties + + // ----- Recuperate date in UNIX format + //if ($p_header['mdate'] && $p_header['mtime']) + // TBC : bug : this was ignoring time with 0/0/0 + if (1) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + } + else + { + $p_header['mtime'] = time(); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + } + + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + $p_local_header['size'] = $p_central_header['size']; + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + $p_local_header['crc'] = $p_central_header['crc']; + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + @fseek($this->zip_fd, $v_size); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + @fseek($this->zip_fd, $v_size-22); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + $v_data = @unpack('Vid', $v_binary_data); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + //$v_bytes = ($v_bytes << 8) | Ord($v_byte); + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Extract the values + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + + // ----- Return + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) { + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + } + else + $p_central_dir['comment'] = ''; + + $p_central_dir['entries'] = $v_data['entries']; + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + $p_central_dir['offset'] = $v_data['offset']; + $p_central_dir['size'] = $v_data['size']; + $p_central_dir['disk'] = $v_data['disk']; + $p_central_dir['disk_start'] = $v_data['disk_start']; + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + //} + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + + return $v_result; + } + + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + // ereg() is deprecated with PHP 5.3 + /* + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + */ + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + break; + } + } + } + else { + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) + { + unset($v_header_list[$v_nb_extracted]); + } + else + { + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { + + // ----- Calculate the position of the header + @rewind($this->zip_fd); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + + // ----- Re-Create the Central Dir files header + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + return $v_result; + } + } + } + + // ----- Create the directory + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + return $v_result; + } + + // ----- Go to beginning of File + @rewind($this->zip_fd); + + // ----- Open the archive_to_add file + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); + + // ----- Return + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + return $v_result; + } + + // ----- Go to beginning of File + @rewind($p_archive_to_add->zip_fd); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + return $v_result; + } + + // ----- Open the zip file + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + return $v_result; + } + + // ----- Open the temporary file in write mode + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime(0); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + $v_result = 1; + + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + $v_result = 1; + + if ($p_mode==0) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + $v_result = 0; + } + else if (!@unlink($p_src)) { + $v_result = 0; + } + } + + // ----- Return + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + return $v_key; + } + } + + $v_result = 'Unknown'; + + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // -------------------------------------------------------------------------------- + + +?> diff --git a/extend/phpexcel/PHPExcel/Shared/PCLZip/readme.txt b/extend/phpexcel/PHPExcel/Shared/PCLZip/readme.txt new file mode 100755 index 0000000..6ed8839 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/PCLZip/readme.txt @@ -0,0 +1,421 @@ +// -------------------------------------------------------------------------------- +// PclZip 2.8.2 - readme.txt +// -------------------------------------------------------------------------------- +// License GNU/LGPL - August 2009 +// Vincent Blavet - vincent@phpconcept.net +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $ +// -------------------------------------------------------------------------------- + + + +0 - Sommaire +============ + 1 - Introduction + 2 - What's new + 3 - Corrected bugs + 4 - Known bugs or limitations + 5 - License + 6 - Warning + 7 - Documentation + 8 - Author + 9 - Contribute + +1 - Introduction +================ + + PclZip is a library that allow you to manage a Zip archive. + + Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip + +2 - What's new +============== + + Version 2.8.2 : + - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with + extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string + can also be modified in the post-extract call back. + **Bugs correction : + - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly + - Remove use of eval() and do direct call to callback functions + - Correct support of 64bits systems (Thanks to WordPress team) + + Version 2.8.1 : + - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is + deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will + automatically replace it by PCLZIP_OPT_BY_PREG. + + Version 2.8 : + - Improve extraction of zip archive for large files by using temporary files + This feature is working like the one defined in r2.7. + Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF, + PCLZIP_OPT_TEMP_FILE_THRESHOLD + - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto + sense of temporary file use. + - Bug correction : Reduce filepath in returned file list to remove ennoying + './/' preambule in file path. + + Version 2.7 : + - Improve creation of zip archive for large files : + PclZip will now autosense the configured memory and use temporary files + when large file is suspected. + This feature can also ne triggered by manual options in create() and add() + methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files, + 'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic, + 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size + threshold to use temporary files. + Using "temporary files" rather than "memory" might take more time, but + might give the ability to zip very large files : + Tested on my win laptop with a 88Mo file : + Zip "in-memory" : 18sec (max_execution_time=30, memory_limit=180Mo) + Zip "tmporary-files" : 23sec (max_execution_time=30, memory_limit=30Mo) + - Replace use of mktime() by time() to limit the E_STRICT error messages. + - Bug correction : When adding files with full windows path (drive letter) + PclZip is now working. Before, if the drive letter is not the default + path, PclZip was not able to add the file. + + Version 2.6 : + - Code optimisation + - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to + add a comment for a specific file. (Don't really know if this is usefull) + - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string + as a file. + - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with + a file. + - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted + with current time + - Add CRC value in the informations returned back for each file after an + action. + - Add missing closedir() statement. + - When adding a folder, and removing the path of this folder, files were + incorrectly added with a '/' at the beginning. Which means files are + related to root in unix systems. Corrected. + - Add conditional if before constant definition. This will allow users + to redefine constants without changing the file, and then improve + upgrade of pclzip code for new versions. + + Version 2.5 : + - Introduce the ability to add file/folder with individual properties (file descriptor). + This gives for example the ability to change the filename of a zipped file. + . Able to add files individually + . Able to change full name + . Able to change short name + . Compatible with global options + - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME + - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE + - Add a security control feature. PclZip can extract any file in any folder + of a system. People may use this to upload a zip file and try to override + a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the + ability to forgive any directory transversal behavior. + - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path + - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION + - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend + by current path (getcwd()) + + Version 2.4 : + - Code improvment : try to speed up the code by removing unusefull call to pack() + - Correct bug in delete() : delete() should be called with no argument. This was not + the case in 2.3. This is corrected in 2.4. + - Correct a bug in path_inclusion function. When the path has several '../../', the + result was bad. + - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will + disable it while working and det it back to its original value. + This resolve a lots of bad formated archive errors. + - Bug correction : PclZip now correctly unzip file in some specific situation, + when compressed content has same size as uncompressed content. + - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH', + directories are not any more created. + - Code improvment : correct unclosed opendir(), better handling of . and .. in + loops. + + + Version 2.3 : + - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not + give the same result in PHP4 and PHP5 .... + + Version 2.2 : + - Try development of PCLZIP_OPT_CRYPT ..... + However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers, + the result (greater than a long) is not supported by PHP. Even the use of bcmath + functions does not help. I did not find yet a solution ...; + - Add missing '/' at end of directory entries + - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or + error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION. + - Corrected : Bad "version need to extract" field in local file header + - Add private method privCheckFileHeaders() in order to check local and central + file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives + the ability to have a local file header without size, compressed size and crc filled. + - Add a generic status 'error' for file status + - Add control of compression type. PclZip only support deflate compression method. + Before v2.2, PclZip does not check the compression method used in an archive while + extracting. With v2.2 PclZip returns a new error status for a file using an unsupported + compression method. New status is "unsupported_compression". New error code is + PCLZIP_ERR_UNSUPPORTED_COMPRESSION. + - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files + when errors like 'a folder with same name exists' or 'a newer file exists' or + 'a write protected file' exists, rather than set a status for the concerning file + and resume the extract of the zip. + - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the + replacement of the file, even if a newer version of the file exists. + Note that today if a file with the same name already exists but is older it will be + replaced by the extracted one. + - Improve PclZipUtilOption() + - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central + directory structure is the last data in the archive. Crypt encryption/decryption of + zip archive put trailing 0 bytes after decryption. PclZip is now supporting this. + + Version 2.1 : + - Add the ability to abort the extraction by using a user callback function. + The user can now return the value '2' in its callback which indicates to stop the + extraction. For a pre call-back extract is stopped before the extration of the current + file. For a post call back, the extraction is stopped after. + - Add the ability to extract a file (or several files) directly in the standard output. + This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract(). + - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT, + PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments + in the zip archive. + - When merging two archives, the comments are not any more lost, but merged, with a + blank space separator. + - Corrected bug : Files are not deleted when all files are asked to be deleted. + - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature. + + + Version 2.0 : + ***** Warning : Some new features may break the backward compatibility for your scripts. + Please carefully read the readme file. + - Add the ability to delete by Index, name and regular expression. This feature is + performed by the method delete(), which uses the optional parameters + PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG. + - Add the ability to extract by regular expression. To extract by regexp you must use the method + extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG + (depending if you want to use ereg() or preg_match() syntax) followed by the + regular expression pattern. + - Add the ability to extract by index, directly with the extract() method. This is a + code improvment of the extractByIndex() method. + - Add the ability to extract by name. To extract by name you must use the method + extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to + extract or an array of filenames to extract. To extract all a folder, use the folder + name rather than the filename with a '/' at the end. + - Add the ability to add files without compression. This is done with a new attribute + which is PCLZIP_OPT_NO_COMPRESSION. + - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly + in a string without using any file (or temporary file). + - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string. + The default separator is now a comma (,) and not any more a blank space. + THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with + your script. + - Improve algorythm performance by removing the use of temporary files when adding or + extracting files in an archive. + - Add (correct) detection of empty filename zipping. This can occurs when the removed + path is the same + as a zipped dir. The dir is not zipped (['status'] = filtered), only its content. + - Add better support for windows paths (thanks for help from manus@manusfreedom.com). + - Corrected bug : When the archive file already exists with size=0, the add() method + fails. Corrected in 2.0. + - Remove the use of OS_WINDOWS constant. Use php_uname() function rather. + - Control the order of index ranges in extract by index feature. + - Change the internal management of folders (better handling of internal flag). + + + Version 1.3 : + - Removing the double include check. This is now done by include_once() and require_once() + PHP directives. + - Changing the error handling mecanism : Remove the use of an external error library. + The former PclError...() functions are replaced by internal equivalent methods. + By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library. + Introducing the use of constants for error codes rather than integer values. This will help + in futur improvment. + Introduction of error handling functions like errorCode(), errorName() and errorInfo(). + - Remove the deprecated use of calling function with arguments passed by reference. + - Add the calling of extract(), extractByIndex(), create() and add() functions + with variable options rather than fixed arguments. + - Add the ability to remove all the file path while extracting or adding, + without any need to specify the path to remove. + This is available for extract(), extractByIndex(), create() and add() functionS by using + the new variable options parameters : + - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct. + - Ability to change the mode of a file after the extraction (chmod()). + This is available for extract() and extractByIndex() functionS by using + the new variable options parameters. + - PCLZIP_OPT_SET_CHMOD : by setting the value of this option. + - Ability to definition call-back options. These call-back will be called during the adding, + or the extracting of file (extract(), extractByIndex(), create() and add() functions) : + - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user + can trigerred the change the filename of the extracted file. The user can triggered the + skip of the extraction. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file. + Nothing can be triggered from that point. + - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user + can trigerred the change the stored filename of the added file. The user can triggered the + skip of the add. This is adding a 'skipped' status in the file list result value. + - PCLZIP_CB_POST_ADD : will be called after each add of a file. + Nothing can be triggered from that point. + - Two status are added in the file list returned as function result : skipped & filename_too_long + 'skipped' is used when a call-back function ask for skipping the file. + 'filename_too_long' is used while adding a file with a too long filename to archive (the file is + not added) + - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into + a directory. + - Add a check of the presence of the archive file before some actions (like list, ...) + - Add the initialisation of field "index" in header array. This means that by + default index will be -1 when not explicitly set by the methods. + + Version 1.2 : + - Adding a duplicate function. + - Adding a merge function. The merge function is a "quick merge" function, + it just append the content of an archive at the end of the first one. There + is no check for duplicate files or more recent files. + - Improve the search of the central directory end. + + Version 1.1.2 : + + - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license + (see License section). + - Adding the optional support of a static temporary directory. You will need to configure + the constant PCLZIP_TEMPORARY_DIR if you want to use this feature. + - Improving the rename() function. In some cases rename() does not work (different + Filesystems), so it will be replaced by a copy() + unlink() functions. + + Version 1.1.1 : + + - Maintenance release, no new feature. + + Version 1.1 : + + - New method Add() : adding files in the archive + - New method ExtractByIndex() : partial extract of the archive, files are identified by + their index in the archive + - New method DeleteByIndex() : delete some files/folder entries from the archive, + files are identified by their index in the archive. + - Adding a test of the zlib extension presence. If not present abort the script. + + Version 1.0.1 : + + - No new feature + + +3 - Corrected bugs +================== + + Corrected in Version 2.0 : + - Corrected : During an extraction, if a call-back fucntion is used and try to skip + a file, all the extraction process is stopped. + + Corrected in Version 1.3 : + - Corrected : Support of static synopsis for method extract() is broken. + - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF). + - Corrected : When an extract is done with a remove_path parameter, the entry for + the directory with exactly the same path is not skipped/filtered. + - Corrected : extractByIndex() and deleteByIndex() were not managing index in the + right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This + is due to a sort of the index resulting table that puts 11 before 3-5 (sort on + string and not interger). The sort is temporarilly removed, this means that + you must provide a sorted list of index ranges. + + Corrected in Version 1.2 : + + - Nothing. + + Corrected in Version 1.1.2 : + + - Corrected : Winzip is unable to delete or add new files in a PclZip created archives. + + Corrected in Version 1.1.1 : + + - Corrected : When archived file is not compressed (0% compression), the + extract method fails. + + Corrected in Version 1.1 : + + - Corrected : Adding a complete tree of folder may result in a bad archive + creation. + + Corrected in Version 1.0.1 : + + - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + + +4 - Known bugs or limitations +============================= + + Please publish bugs reports in SourceForge : + http://sourceforge.net/tracker/?group_id=40254&atid=427564 + + In Version 2.x : + - PclZip does only support file uncompressed or compressed with deflate (compression method 8) + - PclZip does not support password protected zip archive + - Some concern were seen when changing mtime of a file while archiving. + Seems to be linked to Daylight Saving Time (PclTest_changing_mtime). + + In Version 1.2 : + + - merge() methods does not check for duplicate files or last date of modifications. + + In Version 1.1 : + + - Limitation : Using 'extract' fields in the file header in the zip archive is not supported. + - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to + add a file in a PclZip created archive. (Corrected in v.1.2) + + In Version 1.0.1 : + + - Adding a complete tree of folder may result in a bad archive + creation. (Corrected in V.1.1). + - Path given to methods must be in the unix format (/) and not the Windows format (\). + Workaround : Use only / directory separators. + - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz + added suffix. Files with these names may already exist and may be overwritten. + Workaround : none. + - PclZip does not check if the zlib extension is present. If it is absent, the zip + file is not created and the lib abort without warning. + Workaround : enable the zlib extension on the php install + + In Version 1.0 : + + - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024). + (Corrected in v.1.0.1) + - Limitation : Multi-disk zip archive are not supported. + + +5 - License +=========== + + Since version 1.1.2, PclZip Library is released under GNU/LGPL license. + This library is free, so you can use it at no cost. + + HOWEVER, if you release a script, an application, a library or any kind of + code using PclZip library (or a part of it), YOU MUST : + - Indicate in the documentation (or a readme file), that your work + uses PclZip Library, and make a reference to the author and the web site + http://www.phpconcept.net + - Gives the ability to the final user to update the PclZip libary. + + I will also appreciate that you send me a mail (vincent@phpconcept.net), just to + be aware that someone is using PclZip. + + For more information about GNU/LGPL license : http://www.gnu.org + +6 - Warning +================= + + This library and the associated files are non commercial, non professional work. + It should not have unexpected results. However if any damage is caused by this software + the author can not be responsible. + The use of this software is at the risk of the user. + +7 - Documentation +================= + PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php + A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/ + +8 - Author +========== + + This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time. + +9 - Contribute +============== + If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net. + If you can help in financing PhpConcept hosting service, please go to + http://www.phpconcept.net/soutien.php diff --git a/extend/phpexcel/PHPExcel/Shared/PasswordHasher.php b/extend/phpexcel/PHPExcel/Shared/PasswordHasher.php new file mode 100755 index 0000000..4f505a2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/PasswordHasher.php @@ -0,0 +1,66 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_PasswordHasher + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_PasswordHasher +{ + /** + * Create a password hash from a given string. + * + * This method is based on the algorithm provided by + * Daniel Rentz of OpenOffice and the PEAR package + * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>. + * + * @param string $pPassword Password to hash + * @return string Hashed password + */ + public static function hashPassword($pPassword = '') { + $password = 0x0000; + $charPos = 1; // char position + + // split the plain text password in its component characters + $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY); + foreach ($chars as $char) { + $value = ord($char) << $charPos++; // shifted ASCII value + $rotated_bits = $value >> 15; // rotated bits beyond bit 15 + $value &= 0x7fff; // first 15 bits + $password ^= ($value | $rotated_bits); + } + + $password ^= strlen($pPassword); + $password ^= 0xCE4B; + + return(strtoupper(dechex($password))); + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/String.php b/extend/phpexcel/PHPExcel/Shared/String.php new file mode 100755 index 0000000..49d217a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/String.php @@ -0,0 +1,776 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_String + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_String +{ + /** Constants */ + /** Regular Expressions */ + // Fraction + const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)'; + + + /** + * Control characters array + * + * @var string[] + */ + private static $_controlCharacters = array(); + + /** + * SYLK Characters array + * + * $var array + */ + private static $_SYLKCharacters = array(); + + /** + * Decimal separator + * + * @var string + */ + private static $_decimalSeparator; + + /** + * Thousands separator + * + * @var string + */ + private static $_thousandsSeparator; + + /** + * Currency code + * + * @var string + */ + private static $_currencyCode; + + /** + * Is mbstring extension avalable? + * + * @var boolean + */ + private static $_isMbstringEnabled; + + /** + * Is iconv extension avalable? + * + * @var boolean + */ + private static $_isIconvEnabled; + + /** + * Build control characters array + */ + private static function _buildControlCharacters() { + for ($i = 0; $i <= 31; ++$i) { + if ($i != 9 && $i != 10 && $i != 13) { + $find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_'; + $replace = chr($i); + self::$_controlCharacters[$find] = $replace; + } + } + } + + /** + * Build SYLK characters array + */ + private static function _buildSYLKCharacters() + { + self::$_SYLKCharacters = array( + "\x1B 0" => chr(0), + "\x1B 1" => chr(1), + "\x1B 2" => chr(2), + "\x1B 3" => chr(3), + "\x1B 4" => chr(4), + "\x1B 5" => chr(5), + "\x1B 6" => chr(6), + "\x1B 7" => chr(7), + "\x1B 8" => chr(8), + "\x1B 9" => chr(9), + "\x1B :" => chr(10), + "\x1B ;" => chr(11), + "\x1B <" => chr(12), + "\x1B :" => chr(13), + "\x1B >" => chr(14), + "\x1B ?" => chr(15), + "\x1B!0" => chr(16), + "\x1B!1" => chr(17), + "\x1B!2" => chr(18), + "\x1B!3" => chr(19), + "\x1B!4" => chr(20), + "\x1B!5" => chr(21), + "\x1B!6" => chr(22), + "\x1B!7" => chr(23), + "\x1B!8" => chr(24), + "\x1B!9" => chr(25), + "\x1B!:" => chr(26), + "\x1B!;" => chr(27), + "\x1B!<" => chr(28), + "\x1B!=" => chr(29), + "\x1B!>" => chr(30), + "\x1B!?" => chr(31), + "\x1B'?" => chr(127), + "\x1B(0" => '€', // 128 in CP1252 + "\x1B(2" => '‚', // 130 in CP1252 + "\x1B(3" => 'ƒ', // 131 in CP1252 + "\x1B(4" => '„', // 132 in CP1252 + "\x1B(5" => '…', // 133 in CP1252 + "\x1B(6" => '†', // 134 in CP1252 + "\x1B(7" => '‡', // 135 in CP1252 + "\x1B(8" => 'ˆ', // 136 in CP1252 + "\x1B(9" => '‰', // 137 in CP1252 + "\x1B(:" => 'Š', // 138 in CP1252 + "\x1B(;" => '‹', // 139 in CP1252 + "\x1BNj" => 'Œ', // 140 in CP1252 + "\x1B(>" => 'Ž', // 142 in CP1252 + "\x1B)1" => '‘', // 145 in CP1252 + "\x1B)2" => '’', // 146 in CP1252 + "\x1B)3" => '“', // 147 in CP1252 + "\x1B)4" => '”', // 148 in CP1252 + "\x1B)5" => '•', // 149 in CP1252 + "\x1B)6" => '–', // 150 in CP1252 + "\x1B)7" => '—', // 151 in CP1252 + "\x1B)8" => '˜', // 152 in CP1252 + "\x1B)9" => '™', // 153 in CP1252 + "\x1B):" => 'š', // 154 in CP1252 + "\x1B);" => '›', // 155 in CP1252 + "\x1BNz" => 'œ', // 156 in CP1252 + "\x1B)>" => 'ž', // 158 in CP1252 + "\x1B)?" => 'Ÿ', // 159 in CP1252 + "\x1B*0" => ' ', // 160 in CP1252 + "\x1BN!" => '¡', // 161 in CP1252 + "\x1BN\"" => '¢', // 162 in CP1252 + "\x1BN#" => '£', // 163 in CP1252 + "\x1BN(" => '¤', // 164 in CP1252 + "\x1BN%" => '¥', // 165 in CP1252 + "\x1B*6" => '¦', // 166 in CP1252 + "\x1BN'" => '§', // 167 in CP1252 + "\x1BNH " => '¨', // 168 in CP1252 + "\x1BNS" => '©', // 169 in CP1252 + "\x1BNc" => 'ª', // 170 in CP1252 + "\x1BN+" => '«', // 171 in CP1252 + "\x1B*<" => '¬', // 172 in CP1252 + "\x1B*=" => '­', // 173 in CP1252 + "\x1BNR" => '®', // 174 in CP1252 + "\x1B*?" => '¯', // 175 in CP1252 + "\x1BN0" => '°', // 176 in CP1252 + "\x1BN1" => '±', // 177 in CP1252 + "\x1BN2" => '²', // 178 in CP1252 + "\x1BN3" => '³', // 179 in CP1252 + "\x1BNB " => '´', // 180 in CP1252 + "\x1BN5" => 'µ', // 181 in CP1252 + "\x1BN6" => '¶', // 182 in CP1252 + "\x1BN7" => '·', // 183 in CP1252 + "\x1B+8" => '¸', // 184 in CP1252 + "\x1BNQ" => '¹', // 185 in CP1252 + "\x1BNk" => 'º', // 186 in CP1252 + "\x1BN;" => '»', // 187 in CP1252 + "\x1BN<" => '¼', // 188 in CP1252 + "\x1BN=" => '½', // 189 in CP1252 + "\x1BN>" => '¾', // 190 in CP1252 + "\x1BN?" => '¿', // 191 in CP1252 + "\x1BNAA" => 'À', // 192 in CP1252 + "\x1BNBA" => 'Á', // 193 in CP1252 + "\x1BNCA" => 'Â', // 194 in CP1252 + "\x1BNDA" => 'Ã', // 195 in CP1252 + "\x1BNHA" => 'Ä', // 196 in CP1252 + "\x1BNJA" => 'Å', // 197 in CP1252 + "\x1BNa" => 'Æ', // 198 in CP1252 + "\x1BNKC" => 'Ç', // 199 in CP1252 + "\x1BNAE" => 'È', // 200 in CP1252 + "\x1BNBE" => 'É', // 201 in CP1252 + "\x1BNCE" => 'Ê', // 202 in CP1252 + "\x1BNHE" => 'Ë', // 203 in CP1252 + "\x1BNAI" => 'Ì', // 204 in CP1252 + "\x1BNBI" => 'Í', // 205 in CP1252 + "\x1BNCI" => 'Î', // 206 in CP1252 + "\x1BNHI" => 'Ï', // 207 in CP1252 + "\x1BNb" => 'Ð', // 208 in CP1252 + "\x1BNDN" => 'Ñ', // 209 in CP1252 + "\x1BNAO" => 'Ò', // 210 in CP1252 + "\x1BNBO" => 'Ó', // 211 in CP1252 + "\x1BNCO" => 'Ô', // 212 in CP1252 + "\x1BNDO" => 'Õ', // 213 in CP1252 + "\x1BNHO" => 'Ö', // 214 in CP1252 + "\x1B-7" => '×', // 215 in CP1252 + "\x1BNi" => 'Ø', // 216 in CP1252 + "\x1BNAU" => 'Ù', // 217 in CP1252 + "\x1BNBU" => 'Ú', // 218 in CP1252 + "\x1BNCU" => 'Û', // 219 in CP1252 + "\x1BNHU" => 'Ü', // 220 in CP1252 + "\x1B-=" => 'Ý', // 221 in CP1252 + "\x1BNl" => 'Þ', // 222 in CP1252 + "\x1BN{" => 'ß', // 223 in CP1252 + "\x1BNAa" => 'à', // 224 in CP1252 + "\x1BNBa" => 'á', // 225 in CP1252 + "\x1BNCa" => 'â', // 226 in CP1252 + "\x1BNDa" => 'ã', // 227 in CP1252 + "\x1BNHa" => 'ä', // 228 in CP1252 + "\x1BNJa" => 'å', // 229 in CP1252 + "\x1BNq" => 'æ', // 230 in CP1252 + "\x1BNKc" => 'ç', // 231 in CP1252 + "\x1BNAe" => 'è', // 232 in CP1252 + "\x1BNBe" => 'é', // 233 in CP1252 + "\x1BNCe" => 'ê', // 234 in CP1252 + "\x1BNHe" => 'ë', // 235 in CP1252 + "\x1BNAi" => 'ì', // 236 in CP1252 + "\x1BNBi" => 'í', // 237 in CP1252 + "\x1BNCi" => 'î', // 238 in CP1252 + "\x1BNHi" => 'ï', // 239 in CP1252 + "\x1BNs" => 'ð', // 240 in CP1252 + "\x1BNDn" => 'ñ', // 241 in CP1252 + "\x1BNAo" => 'ò', // 242 in CP1252 + "\x1BNBo" => 'ó', // 243 in CP1252 + "\x1BNCo" => 'ô', // 244 in CP1252 + "\x1BNDo" => 'õ', // 245 in CP1252 + "\x1BNHo" => 'ö', // 246 in CP1252 + "\x1B/7" => '÷', // 247 in CP1252 + "\x1BNy" => 'ø', // 248 in CP1252 + "\x1BNAu" => 'ù', // 249 in CP1252 + "\x1BNBu" => 'ú', // 250 in CP1252 + "\x1BNCu" => 'û', // 251 in CP1252 + "\x1BNHu" => 'ü', // 252 in CP1252 + "\x1B/=" => 'ý', // 253 in CP1252 + "\x1BN|" => 'þ', // 254 in CP1252 + "\x1BNHy" => 'ÿ', // 255 in CP1252 + ); + } + + /** + * Get whether mbstring extension is available + * + * @return boolean + */ + public static function getIsMbstringEnabled() + { + if (isset(self::$_isMbstringEnabled)) { + return self::$_isMbstringEnabled; + } + + self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? + true : false; + + return self::$_isMbstringEnabled; + } + + /** + * Get whether iconv extension is available + * + * @return boolean + */ + public static function getIsIconvEnabled() + { + if (isset(self::$_isIconvEnabled)) { + return self::$_isIconvEnabled; + } + + // Fail if iconv doesn't exist + if (!function_exists('iconv')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false, + if (!@iconv('UTF-8', 'UTF-16LE', 'x')) { + self::$_isIconvEnabled = false; + return false; + } + + // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0 + // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773) + if (!@iconv_substr('A', 0, 1, 'UTF-8')) { + self::$_isIconvEnabled = false; + return false; + } + + // CUSTOM: IBM AIX iconv() does not work + if ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX') + && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) + && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) ) + { + self::$_isIconvEnabled = false; + return false; + } + + // If we reach here no problems were detected with iconv + self::$_isIconvEnabled = true; + return true; + } + + public static function buildCharacterSets() { + if(empty(self::$_controlCharacters)) { + self::_buildControlCharacters(); + } + if(empty(self::$_SYLKCharacters)) { + self::_buildSYLKCharacters(); + } + } + + /** + * Convert from OpenXML escaped control character to PHP control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to unescape + * @return string + */ + public static function ControlCharacterOOXML2PHP($value = '') { + return str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value ); + } + + /** + * Convert from PHP control character to OpenXML escaped control character + * + * Excel 2007 team: + * ---------------- + * That's correct, control characters are stored directly in the shared-strings table. + * We do encode characters that cannot be represented in XML using the following escape sequence: + * _xHHHH_ where H represents a hexadecimal character in the character's value... + * So you could end up with something like _x0008_ in a string (either in a cell value (<v>) + * element or in the shared string <t> element. + * + * @param string $value Value to escape + * @return string + */ + public static function ControlCharacterPHP2OOXML($value = '') { + return str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value ); + } + + /** + * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters. + * + * @param string $value + * @return string + */ + public static function SanitizeUTF8($value) + { + if (self::getIsIconvEnabled()) { + $value = @iconv('UTF-8', 'UTF-8', $value); + return $value; + } + + if (self::getIsMbstringEnabled()) { + $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8'); + return $value; + } + + // else, no conversion + return $value; + } + + /** + * Check if a string contains UTF8 data + * + * @param string $value + * @return boolean + */ + public static function IsUTF8($value = '') { + return $string === '' || preg_match('/^./su', $string) === 1; + } + + /** + * Formats a numeric value as a string for output in various output writers forcing + * point as decimal separator in case locale is other than English. + * + * @param mixed $value + * @return string + */ + public static function FormatNumber($value) { + if (is_float($value)) { + return str_replace(',', '.', $value); + } + return (string) $value; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @param mixed[] $arrcRuns Details of rich text runs in $value + * @return string + */ + public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array()) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + // option flags + if(empty($arrcRuns)){ + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + $data = pack('CC', $ln, $opt); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + } + else { + $data = pack('vC', $ln, 0x09); + $data .= pack('v', count($arrcRuns)); + // characters + $data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + foreach ($arrcRuns as $cRun){ + $data .= pack('v', $cRun['strlen']); + $data .= pack('v', $cRun['fontidx']); + } + } + return $data; + } + + /** + * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) + * Writes the string using uncompressed notation, no rich text, no Asian phonetics + * If mbstring extension is not available, ASCII is assumed, and compressed notation is used + * although this will give wrong results for non-ASCII strings + * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 + * + * @param string $value UTF-8 encoded string + * @return string + */ + public static function UTF8toBIFF8UnicodeLong($value) + { + // character count + $ln = self::CountCharacters($value, 'UTF-8'); + + // option flags + $opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ? + 0x0001 : 0x0000; + + // characters + $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); + + $data = pack('vC', $ln, $opt) . $chars; + return $data; + } + + /** + * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $to Encoding to convert to, e.g. 'UTF-8' + * @param string $from Encoding to convert from, e.g. 'UTF-16LE' + * @return string + */ + public static function ConvertEncoding($value, $to, $from) + { + if (self::getIsIconvEnabled()) { + return iconv($from, $to, $value); + } + + if (self::getIsMbstringEnabled()) { + return mb_convert_encoding($value, $to, $from); + } + + if($from == 'UTF-16LE'){ + return self::utf16_decode($value, false); + }else if($from == 'UTF-16BE'){ + return self::utf16_decode($value); + } + // else, no conversion + return $value; + } + + /** + * Decode UTF-16 encoded strings. + * + * Can handle both BOM'ed data and un-BOM'ed data. + * Assumes Big-Endian byte order if no BOM is available. + * This function was taken from http://php.net/manual/en/function.utf8-decode.php + * and $bom_be parameter added. + * + * @param string $str UTF-16 encoded data to decode. + * @return string UTF-8 / ISO encoded data. + * @access public + * @version 0.2 / 2010-05-13 + * @author Rasmus Andersson {@link http://rasmusandersson.se/} + * @author vadik56 + */ + public static function utf16_decode($str, $bom_be = TRUE) { + if( strlen($str) < 2 ) return $str; + $c0 = ord($str{0}); + $c1 = ord($str{1}); + if( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); } + elseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; } + $len = strlen($str); + $newstr = ''; + for($i=0;$i<$len;$i+=2) { + if( $bom_be ) { $val = ord($str{$i}) << 4; $val += ord($str{$i+1}); } + else { $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); } + $newstr .= ($val == 0x228) ? "\n" : chr($val); + } + return $newstr; + } + + /** + * Get character count. First try mbstring, then iconv, finally strlen + * + * @param string $value + * @param string $enc Encoding + * @return int Character count + */ + public static function CountCharacters($value, $enc = 'UTF-8') + { + if (self::getIsMbstringEnabled()) { + return mb_strlen($value, $enc); + } + + if (self::getIsIconvEnabled()) { + return iconv_strlen($value, $enc); + } + + // else strlen + return strlen($value); + } + + /** + * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen + * + * @param string $pValue UTF-8 encoded string + * @param int $pStart Start offset + * @param int $pLength Maximum number of characters in substring + * @return string + */ + public static function Substring($pValue = '', $pStart = 0, $pLength = 0) + { + if (self::getIsMbstringEnabled()) { + return mb_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + if (self::getIsIconvEnabled()) { + return iconv_substr($pValue, $pStart, $pLength, 'UTF-8'); + } + + // else substr + return substr($pValue, $pStart, $pLength); + } + + /** + * Convert a UTF-8 encoded string to upper case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToUpper($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_UPPER, "UTF-8"); + } + return strtoupper($pValue); + } + + /** + * Convert a UTF-8 encoded string to lower case + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToLower($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_LOWER, "UTF-8"); + } + return strtolower($pValue); + } + + /** + * Convert a UTF-8 encoded string to title/proper case + * (uppercase every first character in each word, lower case all other characters) + * + * @param string $pValue UTF-8 encoded string + * @return string + */ + public static function StrToTitle($pValue = '') + { + if (function_exists('mb_convert_case')) { + return mb_convert_case($pValue, MB_CASE_TITLE, "UTF-8"); + } + return ucwords($pValue); + } + + /** + * Identify whether a string contains a fractional numeric value, + * and convert it to a numeric if it is + * + * @param string &$operand string value to test + * @return boolean + */ + public static function convertToNumberIfFraction(&$operand) { + if (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) { + $sign = ($match[1] == '-') ? '-' : '+'; + $fractionFormula = '='.$sign.$match[2].$sign.$match[3]; + $operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + return true; + } + return false; + } // function convertToNumberIfFraction() + + /** + * Get the decimal separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getDecimalSeparator() + { + if (!isset(self::$_decimalSeparator)) { + $localeconv = localeconv(); + self::$_decimalSeparator = ($localeconv['decimal_point'] != '') + ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point']; + + if (self::$_decimalSeparator == '') { + // Default to . + self::$_decimalSeparator = '.'; + } + } + return self::$_decimalSeparator; + } + + /** + * Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for decimal separator + */ + public static function setDecimalSeparator($pValue = '.') + { + self::$_decimalSeparator = $pValue; + } + + /** + * Get the thousands separator. If it has not yet been set explicitly, try to obtain number + * formatting information from locale. + * + * @return string + */ + public static function getThousandsSeparator() + { + if (!isset(self::$_thousandsSeparator)) { + $localeconv = localeconv(); + self::$_thousandsSeparator = ($localeconv['thousands_sep'] != '') + ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep']; + + if (self::$_thousandsSeparator == '') { + // Default to . + self::$_thousandsSeparator = ','; + } + } + return self::$_thousandsSeparator; + } + + /** + * Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for thousands separator + */ + public static function setThousandsSeparator($pValue = ',') + { + self::$_thousandsSeparator = $pValue; + } + + /** + * Get the currency code. If it has not yet been set explicitly, try to obtain the + * symbol information from locale. + * + * @return string + */ + public static function getCurrencyCode() + { + if (!isset(self::$_currencyCode)) { + $localeconv = localeconv(); + self::$_currencyCode = ($localeconv['currency_symbol'] != '') + ? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol']; + + if (self::$_currencyCode == '') { + // Default to $ + self::$_currencyCode = '$'; + } + } + return self::$_currencyCode; + } + + /** + * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString() + * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF + * + * @param string $pValue Character for currency code + */ + public static function setCurrencyCode($pValue = '$') + { + self::$_currencyCode = $pValue; + } + + /** + * Convert SYLK encoded string to UTF-8 + * + * @param string $pValue + * @return string UTF-8 encoded string + */ + public static function SYLKtoUTF8($pValue = '') + { + // If there is no escape character in the string there is nothing to do + if (strpos($pValue, '') === false) { + return $pValue; + } + + foreach (self::$_SYLKCharacters as $k => $v) { + $pValue = str_replace($k, $v, $pValue); + } + + return $pValue; + } + + /** + * Retrieve any leading numeric part of a string, or return the full string if no leading numeric + * (handles basic integer or float, but not exponent or non decimal) + * + * @param string $value + * @return mixed string or only the leading numeric part of the string + */ + public static function testStringAsNumeric($value) + { + if (is_numeric($value)) + return $value; + $v = floatval($value); + return (is_numeric(substr($value,0,strlen($v)))) ? $v : $value; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/TimeZone.php b/extend/phpexcel/PHPExcel/Shared/TimeZone.php new file mode 100755 index 0000000..d5fa2ad --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/TimeZone.php @@ -0,0 +1,140 @@ +<?php + +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_TimeZone + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_TimeZone +{ + /* + * Default Timezone used for date/time conversions + * + * @private + * @var string + */ + protected static $_timezone = 'UTC'; + + /** + * Validate a Timezone name + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function _validateTimeZone($timezone) { + if (in_array($timezone, DateTimeZone::listIdentifiers())) { + return TRUE; + } + return FALSE; + } + + /** + * Set the Default Timezone used for date/time conversions + * + * @param string $timezone Time zone (e.g. 'Europe/London') + * @return boolean Success or failure + */ + public static function setTimeZone($timezone) { + if (self::_validateTimezone($timezone)) { + self::$_timezone = $timezone; + return TRUE; + } + return FALSE; + } // function setTimezone() + + + /** + * Return the Default Timezone used for date/time conversions + * + * @return string Timezone (e.g. 'Europe/London') + */ + public static function getTimeZone() { + return self::$_timezone; + } // function getTimezone() + + + /** + * Return the Timezone transition for the specified timezone and timestamp + * + * @param DateTimeZone $objTimezone The timezone for finding the transitions + * @param integer $timestamp PHP date/time value for finding the current transition + * @return array The current transition details + */ + private static function _getTimezoneTransitions($objTimezone, $timestamp) { + $allTransitions = $objTimezone->getTransitions(); + $transitions = array(); + foreach($allTransitions as $key => $transition) { + if ($transition['ts'] > $timestamp) { + $transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition; + break; + } + if (empty($transitions)) { + $transitions[] = end($allTransitions); + } + } + + return $transitions; + } + + /** + * Return the Timezone offset used for date/time conversions to/from UST + * This requires both the timezone and the calculated date/time to allow for local DST + * + * @param string $timezone The timezone for finding the adjustment to UST + * @param integer $timestamp PHP date/time value + * @return integer Number of seconds for timezone adjustment + * @throws PHPExcel_Exception + */ + public static function getTimeZoneAdjustment($timezone, $timestamp) { + if ($timezone !== NULL) { + if (!self::_validateTimezone($timezone)) { + throw new PHPExcel_Exception("Invalid timezone " . $timezone); + } + } else { + $timezone = self::$_timezone; + } + + if ($timezone == 'UST') { + return 0; + } + + $objTimezone = new DateTimeZone($timezone); + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + $transitions = $objTimezone->getTransitions($timestamp,$timestamp); + } else { + $transitions = self::_getTimezoneTransitions($objTimezone, $timestamp); + } + + return (count($transitions) > 0) ? $transitions[0]['offset'] : 0; + } + +} diff --git a/extend/phpexcel/PHPExcel/Shared/XMLWriter.php b/extend/phpexcel/PHPExcel/Shared/XMLWriter.php new file mode 100755 index 0000000..0b0b553 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/XMLWriter.php @@ -0,0 +1,127 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +if (!defined('DATE_W3C')) { + define('DATE_W3C', 'Y-m-d\TH:i:sP'); +} + +if (!defined('DEBUGMODE_ENABLED')) { + define('DEBUGMODE_ENABLED', false); +} + + +/** + * PHPExcel_Shared_XMLWriter + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_XMLWriter extends XMLWriter { + /** Temporary storage method */ + const STORAGE_MEMORY = 1; + const STORAGE_DISK = 2; + + /** + * Temporary filename + * + * @var string + */ + private $_tempFileName = ''; + + /** + * Create a new PHPExcel_Shared_XMLWriter instance + * + * @param int $pTemporaryStorage Temporary storage location + * @param string $pTemporaryStorageFolder Temporary storage folder + */ + public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) { + // Open temporary storage + if ($pTemporaryStorage == self::STORAGE_MEMORY) { + $this->openMemory(); + } else { + // Create temporary filename + if ($pTemporaryStorageFolder === NULL) + $pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir(); + $this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml'); + + // Open storage + if ($this->openUri($this->_tempFileName) === false) { + // Fallback to memory... + $this->openMemory(); + } + } + + // Set default values + if (DEBUGMODE_ENABLED) { + $this->setIndent(true); + } + } + + /** + * Destructor + */ + public function __destruct() { + // Unlink temporary files + if ($this->_tempFileName != '') { + @unlink($this->_tempFileName); + } + } + + /** + * Get written data + * + * @return $data + */ + public function getData() { + if ($this->_tempFileName == '') { + return $this->outputMemory(true); + } else { + $this->flush(); + return file_get_contents($this->_tempFileName); + } + } + + /** + * Fallback method for writeRaw, introduced in PHP 5.2 + * + * @param string $text + * @return string + */ + public function writeRawData($text) + { + if (is_array($text)) { + $text = implode("\n",$text); + } + + if (method_exists($this, 'writeRaw')) { + return $this->writeRaw(htmlspecialchars($text)); + } + + return $this->text($text); + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/ZipArchive.php b/extend/phpexcel/PHPExcel/Shared/ZipArchive.php new file mode 100755 index 0000000..ab551af --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/ZipArchive.php @@ -0,0 +1,175 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_ZipArchive + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +if (!defined('PCLZIP_TEMPORARY_DIR')) { + define('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir()); +} +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php'; + + +/** + * PHPExcel_Shared_ZipArchive + * + * @category PHPExcel + * @package PHPExcel_Shared_ZipArchive + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_ZipArchive +{ + + /** constants */ + const OVERWRITE = 'OVERWRITE'; + const CREATE = 'CREATE'; + + + /** + * Temporary storage directory + * + * @var string + */ + private $_tempDir; + + /** + * Zip Archive Stream Handle + * + * @var string + */ + private $_zip; + + + /** + * Open a new zip archive + * + * @param string $fileName Filename for the zip archive + * @return boolean + */ + public function open($fileName) + { + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + + $this->_zip = new PclZip($fileName); + + return true; + } + + + /** + * Close this zip archive + * + */ + public function close() + { + } + + + /** + * Add a new file to the zip archive from a string of raw data. + * + * @param string $localname Directory/Name of the file to add to the zip archive + * @param string $contents String of data to add to the zip archive + */ + public function addFromString($localname, $contents) + { + $filenameParts = pathinfo($localname); + + $handle = fopen($this->_tempDir.'/'.$filenameParts["basename"], "wb"); + fwrite($handle, $contents); + fclose($handle); + + $res = $this->_zip->add($this->_tempDir.'/'.$filenameParts["basename"], + PCLZIP_OPT_REMOVE_PATH, $this->_tempDir, + PCLZIP_OPT_ADD_PATH, $filenameParts["dirname"] + ); + if ($res == 0) { + throw new PHPExcel_Writer_Exception("Error zipping files : " . $this->_zip->errorInfo(true)); + } + + unlink($this->_tempDir.'/'.$filenameParts["basename"]); + } + + /** + * Find if given fileName exist in archive (Emulate ZipArchive locateName()) + * + * @param string $fileName Filename for the file in zip archive + * @return boolean + */ + public function locateName($fileName) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + return ($list_index > -1); + } + + /** + * Extract file from archive by given fileName (Emulate ZipArchive getFromName()) + * + * @param string $fileName Filename for the file in zip archive + * @return string $contents File string contents + */ + public function getFromName($fileName) + { + $list = $this->_zip->listContent(); + $listCount = count($list); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + + $extracted = ""; + if ($list_index != -1) { + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } else { + $filename = substr($fileName, 1); + $list_index = -1; + for ($i = 0; $i < $listCount; ++$i) { + if (strtolower($list[$i]["filename"]) == strtolower($fileName) || + strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) { + $list_index = $i; + break; + } + } + $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING); + } + if ((is_array($extracted)) && ($extracted != 0)) { + $contents = $extracted[0]["content"]; + } + + return $contents; + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php b/extend/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php new file mode 100755 index 0000000..696072b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/ZipStreamWrapper.php @@ -0,0 +1,201 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_ZipStreamWrapper + * + * @category PHPExcel + * @package PHPExcel_Shared + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Shared_ZipStreamWrapper { + /** + * Internal ZipAcrhive + * + * @var ZipAcrhive + */ + private $_archive; + + /** + * Filename in ZipAcrhive + * + * @var string + */ + private $_fileNameInArchive = ''; + + /** + * Position in file + * + * @var int + */ + private $_position = 0; + + /** + * Data + * + * @var mixed + */ + private $_data = ''; + + /** + * Register wrapper + */ + public static function register() { + @stream_wrapper_unregister("zip"); + @stream_wrapper_register("zip", __CLASS__); + } + + /** + * Implements support for fopen(). + * + * @param string $path resource name including scheme, e.g. + * @param string $mode only "r" is supported + * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH + * @param string &$openedPath absolute path of the opened stream (out parameter) + * @return bool true on success + */ + public function stream_open($path, $mode, $options, &$opened_path) { + // Check for mode + if ($mode{0} != 'r') { + throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.'); + } + + $pos = strrpos($path, '#'); + $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://') + $url['fragment'] = substr($path, $pos + 1); + + // Open archive + $this->_archive = new ZipArchive(); + $this->_archive->open($url['host']); + + $this->_fileNameInArchive = $url['fragment']; + $this->_position = 0; + $this->_data = $this->_archive->getFromName( $this->_fileNameInArchive ); + + return true; + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function statName() { + return $this->_fileNameInArchive; + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function url_stat() { + return $this->statName( $this->_fileNameInArchive ); + } + + /** + * Implements support for fstat(). + * + * @return boolean + */ + public function stream_stat() { + return $this->_archive->statName( $this->_fileNameInArchive ); + } + + /** + * Implements support for fread(), fgets() etc. + * + * @param int $count maximum number of bytes to read + * @return string + */ + function stream_read($count) { + $ret = substr($this->_data, $this->_position, $count); + $this->_position += strlen($ret); + return $ret; + } + + /** + * Returns the position of the file pointer, i.e. its offset into the file + * stream. Implements support for ftell(). + * + * @return int + */ + public function stream_tell() { + return $this->_position; + } + + /** + * EOF stream + * + * @return bool + */ + public function stream_eof() { + return $this->_position >= strlen($this->_data); + } + + /** + * Seek stream + * + * @param int $offset byte offset + * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END + * @return bool + */ + public function stream_seek($offset, $whence) { + switch ($whence) { + case SEEK_SET: + if ($offset < strlen($this->_data) && $offset >= 0) { + $this->_position = $offset; + return true; + } else { + return false; + } + break; + + case SEEK_CUR: + if ($offset >= 0) { + $this->_position += $offset; + return true; + } else { + return false; + } + break; + + case SEEK_END: + if (strlen($this->_data) + $offset >= 0) { + $this->_position = strlen($this->_data) + $offset; + return true; + } else { + return false; + } + break; + + default: + return false; + } + } +} diff --git a/extend/phpexcel/PHPExcel/Shared/trend/bestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/bestFitClass.php new file mode 100755 index 0000000..088ce06 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/bestFitClass.php @@ -0,0 +1,432 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Best_Fit +{ + /** + * Indicator flag for a calculation error + * + * @var boolean + **/ + protected $_error = False; + + /** + * Algorithm type to use for best-fit + * + * @var string + **/ + protected $_bestFitType = 'undetermined'; + + /** + * Number of entries in the sets of x- and y-value arrays + * + * @var int + **/ + protected $_valueCount = 0; + + /** + * X-value dataseries of values + * + * @var float[] + **/ + protected $_xValues = array(); + + /** + * Y-value dataseries of values + * + * @var float[] + **/ + protected $_yValues = array(); + + /** + * Flag indicating whether values should be adjusted to Y=0 + * + * @var boolean + **/ + protected $_adjustToZero = False; + + /** + * Y-value series of best-fit values + * + * @var float[] + **/ + protected $_yBestFitValues = array(); + + protected $_goodnessOfFit = 1; + + protected $_stdevOfResiduals = 0; + + protected $_covariance = 0; + + protected $_correlation = 0; + + protected $_SSRegression = 0; + + protected $_SSResiduals = 0; + + protected $_DFResiduals = 0; + + protected $_F = 0; + + protected $_slope = 0; + + protected $_slopeSE = 0; + + protected $_intersect = 0; + + protected $_intersectSE = 0; + + protected $_Xoffset = 0; + + protected $_Yoffset = 0; + + + public function getError() { + return $this->_error; + } // function getBestFitType() + + + public function getBestFitType() { + return $this->_bestFitType; + } // function getBestFitType() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + */ + public function getValueOfYForX($xValue) { + return False; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + */ + public function getValueOfXForY($yValue) { + return False; + } // function getValueOfXForY() + + + /** + * Return the original set of X-Values + * + * @return float[] X-Values + */ + public function getXValues() { + return $this->_xValues; + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getEquation($dp=0) { + return False; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlope($dp=0) { + if ($dp != 0) { + return round($this->_slope,$dp); + } + return $this->_slope; + } // function getSlope() + + + /** + * Return the standard error of the Slope + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getSlopeSE($dp=0) { + if ($dp != 0) { + return round($this->_slopeSE,$dp); + } + return $this->_slopeSE; + } // function getSlopeSE() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round($this->_intersect,$dp); + } + return $this->_intersect; + } // function getIntersect() + + + /** + * Return the standard error of the Intersect + * + * @param int $dp Number of places of decimal precision to display + * @return string + */ + public function getIntersectSE($dp=0) { + if ($dp != 0) { + return round($this->_intersectSE,$dp); + } + return $this->_intersectSE; + } // function getIntersectSE() + + + /** + * Return the goodness of fit for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getGoodnessOfFit($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit,$dp); + } + return $this->_goodnessOfFit; + } // function getGoodnessOfFit() + + + public function getGoodnessOfFitPercent($dp=0) { + if ($dp != 0) { + return round($this->_goodnessOfFit * 100,$dp); + } + return $this->_goodnessOfFit * 100; + } // function getGoodnessOfFitPercent() + + + /** + * Return the standard deviation of the residuals for this regression + * + * @param int $dp Number of places of decimal precision to return + * @return float + */ + public function getStdevOfResiduals($dp=0) { + if ($dp != 0) { + return round($this->_stdevOfResiduals,$dp); + } + return $this->_stdevOfResiduals; + } // function getStdevOfResiduals() + + + public function getSSRegression($dp=0) { + if ($dp != 0) { + return round($this->_SSRegression,$dp); + } + return $this->_SSRegression; + } // function getSSRegression() + + + public function getSSResiduals($dp=0) { + if ($dp != 0) { + return round($this->_SSResiduals,$dp); + } + return $this->_SSResiduals; + } // function getSSResiduals() + + + public function getDFResiduals($dp=0) { + if ($dp != 0) { + return round($this->_DFResiduals,$dp); + } + return $this->_DFResiduals; + } // function getDFResiduals() + + + public function getF($dp=0) { + if ($dp != 0) { + return round($this->_F,$dp); + } + return $this->_F; + } // function getF() + + + public function getCovariance($dp=0) { + if ($dp != 0) { + return round($this->_covariance,$dp); + } + return $this->_covariance; + } // function getCovariance() + + + public function getCorrelation($dp=0) { + if ($dp != 0) { + return round($this->_correlation,$dp); + } + return $this->_correlation; + } // function getCorrelation() + + + public function getYBestFitValues() { + return $this->_yBestFitValues; + } // function getYBestFitValues() + + + protected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) { + $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; + foreach($this->_xValues as $xKey => $xValue) { + $bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + + $SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY); + if ($const) { + $SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY); + } else { + $SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey]; + } + $SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY); + if ($const) { + $SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX); + } else { + $SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey]; + } + } + + $this->_SSResiduals = $SSres; + $this->_DFResiduals = $this->_valueCount - 1 - $const; + + if ($this->_DFResiduals == 0.0) { + $this->_stdevOfResiduals = 0.0; + } else { + $this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals); + } + if (($SStot == 0.0) || ($SSres == $SStot)) { + $this->_goodnessOfFit = 1; + } else { + $this->_goodnessOfFit = 1 - ($SSres / $SStot); + } + + $this->_SSRegression = $this->_goodnessOfFit * $SStot; + $this->_covariance = $SScov / $this->_valueCount; + $this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2))); + $this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex); + $this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2)); + if ($this->_SSResiduals != 0.0) { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals); + } + } else { + if ($this->_DFResiduals == 0.0) { + $this->_F = 0.0; + } else { + $this->_F = $this->_SSRegression / $this->_DFResiduals; + } + } + } // function _calculateGoodnessOfFit() + + + protected function _leastSquareFit($yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $meanX = $x_sum / $this->_valueCount; + $meanY = $y_sum / $this->_valueCount; + $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + + if ($const) { + $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY); + $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX); + } else { + $mBase += $xValues[$i] * $yValues[$i]; + $mDivisor += $xValues[$i] * $xValues[$i]; + } + } + + // calculate slope +// $this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum)); + $this->_slope = $mBase / $mDivisor; + + // calculate intersect +// $this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount; + if ($const) { + $this->_intersect = $meanY - ($this->_slope * $meanX); + } else { + $this->_intersect = 0; + } + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const); + } // function _leastSquareFit() + + + /** + * Define the regression + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + // Calculate number of points + $nY = count($yValues); + $nX = count($xValues); + + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + $this->_error = True; + return False; + } + + $this->_valueCount = $nY; + $this->_xValues = $xValues; + $this->_yValues = $yValues; + } // function __construct() + +} // class bestFit diff --git a/extend/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php new file mode 100755 index 0000000..44c7aee --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/exponentialBestFitClass.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Exponential_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'exponential'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset)); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * '.$slope.'^X'; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + return round(exp($this->_slope),$dp); + } + return exp($this->_slope); + } // function getSlope() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _exponential_regression($yValues, $xValues, $const) { + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _exponential_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_exponential_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class exponentialBestFit \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php new file mode 100755 index 0000000..00da841 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/linearBestFitClass.php @@ -0,0 +1,111 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Linear_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'linear'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * $xValue; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * X'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _linear_regression($yValues, $xValues, $const) { + $this->_leastSquareFit($yValues, $xValues,$const); + } // function _linear_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_linear_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class linearBestFit \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php new file mode 100755 index 0000000..ac9c1e2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/logarithmicBestFitClass.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'); + + +/** + * PHPExcel_Logarithmic_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'logarithmic'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return exp(($yValue - $this->getIntersect()) / $this->getSlope()); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' + '.$slope.' * log(X)'; + } // function getEquation() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _logarithmic_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _logarithmic_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_logarithmic_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class logarithmicBestFit \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php new file mode 100755 index 0000000..a507975 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/polynomialBestFitClass.php @@ -0,0 +1,224 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; + + +/** + * PHPExcel_Polynomial_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'polynomial'; + + /** + * Polynomial order + * + * @protected + * @var int + **/ + protected $_order = 0; + + + /** + * Return the order of this polynomial + * + * @return int + **/ + public function getOrder() { + return $this->_order; + } // function getOrder() + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + $retVal = $this->getIntersect(); + $slope = $this->getSlope(); + foreach($slope as $key => $value) { + if ($value != 0.0) { + $retVal += $value * pow($xValue, $key + 1); + } + } + return $retVal; + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return ($yValue - $this->getIntersect()) / $this->getSlope(); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + $equation = 'Y = '.$intersect; + foreach($slope as $key => $value) { + if ($value != 0.0) { + $equation .= ' + '.$value.' * X'; + if ($key > 0) { + $equation .= '^'.($key + 1); + } + } + } + return $equation; + } // function getEquation() + + + /** + * Return the Slope of the line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getSlope($dp=0) { + if ($dp != 0) { + $coefficients = array(); + foreach($this->_slope as $coefficient) { + $coefficients[] = round($coefficient,$dp); + } + return $coefficients; + } + return $this->_slope; + } // function getSlope() + + + public function getCoefficients($dp=0) { + return array_merge(array($this->getIntersect($dp)),$this->getSlope($dp)); + } // function getCoefficients() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _polynomial_regression($order, $yValues, $xValues, $const) { + // calculate sums + $x_sum = array_sum($xValues); + $y_sum = array_sum($yValues); + $xx_sum = $xy_sum = 0; + for($i = 0; $i < $this->_valueCount; ++$i) { + $xy_sum += $xValues[$i] * $yValues[$i]; + $xx_sum += $xValues[$i] * $xValues[$i]; + $yy_sum += $yValues[$i] * $yValues[$i]; + } + /* + * This routine uses logic from the PHP port of polyfit version 0.1 + * written by Michael Bommarito and Paul Meagher + * + * The function fits a polynomial function of order $order through + * a series of x-y data points using least squares. + * + */ + for ($i = 0; $i < $this->_valueCount; ++$i) { + for ($j = 0; $j <= $order; ++$j) { + $A[$i][$j] = pow($xValues[$i], $j); + } + } + for ($i=0; $i < $this->_valueCount; ++$i) { + $B[$i] = array($yValues[$i]); + } + $matrixA = new Matrix($A); + $matrixB = new Matrix($B); + $C = $matrixA->solve($matrixB); + + $coefficients = array(); + for($i = 0; $i < $C->m; ++$i) { + $r = $C->get($i, 0); + if (abs($r) <= pow(10, -9)) { + $r = 0; + } + $coefficients[] = $r; + } + + $this->_intersect = array_shift($coefficients); + $this->_slope = $coefficients; + + $this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum); + foreach($this->_xValues as $xKey => $xValue) { + $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); + } + } // function _polynomial_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param int $order Order of Polynomial for this regression + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($order, $yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + if ($order < $this->_valueCount) { + $this->_bestFitType .= '_'.$order; + $this->_order = $order; + $this->_polynomial_regression($order, $yValues, $xValues, $const); + if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { + $this->_error = True; + } + } else { + $this->_error = True; + } + } + } // function __construct() + +} // class polynomialBestFit \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php b/extend/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php new file mode 100755 index 0000000..158e0c4 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/powerBestFitClass.php @@ -0,0 +1,142 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; + + +/** + * PHPExcel_Power_Best_Fit + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit +{ + /** + * Algorithm type to use for best-fit + * (Name of this trend class) + * + * @var string + **/ + protected $_bestFitType = 'power'; + + + /** + * Return the Y-Value for a specified value of X + * + * @param float $xValue X-Value + * @return float Y-Value + **/ + public function getValueOfYForX($xValue) { + return $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope()); + } // function getValueOfYForX() + + + /** + * Return the X-Value for a specified value of Y + * + * @param float $yValue Y-Value + * @return float X-Value + **/ + public function getValueOfXForY($yValue) { + return pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope())); + } // function getValueOfXForY() + + + /** + * Return the Equation of the best-fit line + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getEquation($dp=0) { + $slope = $this->getSlope($dp); + $intersect = $this->getIntersect($dp); + + return 'Y = '.$intersect.' * X^'.$slope; + } // function getEquation() + + + /** + * Return the Value of X where it intersects Y = 0 + * + * @param int $dp Number of places of decimal precision to display + * @return string + **/ + public function getIntersect($dp=0) { + if ($dp != 0) { + return round(exp($this->_intersect),$dp); + } + return exp($this->_intersect); + } // function getIntersect() + + + /** + * Execute the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + private function _power_regression($yValues, $xValues, $const) { + foreach($xValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + foreach($yValues as &$value) { + if ($value < 0.0) { + $value = 0 - log(abs($value)); + } elseif ($value > 0.0) { + $value = log($value); + } + } + unset($value); + + $this->_leastSquareFit($yValues, $xValues, $const); + } // function _power_regression() + + + /** + * Define the regression and calculate the goodness of fit for a set of X and Y data values + * + * @param float[] $yValues The set of Y-values for this regression + * @param float[] $xValues The set of X-values for this regression + * @param boolean $const + */ + function __construct($yValues, $xValues=array(), $const=True) { + if (parent::__construct($yValues, $xValues) !== False) { + $this->_power_regression($yValues, $xValues, $const); + } + } // function __construct() + +} // class powerBestFit \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Shared/trend/trendClass.php b/extend/phpexcel/PHPExcel/Shared/trend/trendClass.php new file mode 100755 index 0000000..d891a7d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Shared/trend/trendClass.php @@ -0,0 +1,156 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php'; +require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php'; + + +/** + * PHPExcel_trendClass + * + * @category PHPExcel + * @package PHPExcel_Shared_Trend + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class trendClass +{ + const TREND_LINEAR = 'Linear'; + const TREND_LOGARITHMIC = 'Logarithmic'; + const TREND_EXPONENTIAL = 'Exponential'; + const TREND_POWER = 'Power'; + const TREND_POLYNOMIAL_2 = 'Polynomial_2'; + const TREND_POLYNOMIAL_3 = 'Polynomial_3'; + const TREND_POLYNOMIAL_4 = 'Polynomial_4'; + const TREND_POLYNOMIAL_5 = 'Polynomial_5'; + const TREND_POLYNOMIAL_6 = 'Polynomial_6'; + const TREND_BEST_FIT = 'Bestfit'; + const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; + + /** + * Names of the best-fit trend analysis methods + * + * @var string[] + **/ + private static $_trendTypes = array( self::TREND_LINEAR, + self::TREND_LOGARITHMIC, + self::TREND_EXPONENTIAL, + self::TREND_POWER + ); + /** + * Names of the best-fit trend polynomial orders + * + * @var string[] + **/ + private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2, + self::TREND_POLYNOMIAL_3, + self::TREND_POLYNOMIAL_4, + self::TREND_POLYNOMIAL_5, + self::TREND_POLYNOMIAL_6 + ); + + /** + * Cached results for each method when trying to identify which provides the best fit + * + * @var PHPExcel_Best_Fit[] + **/ + private static $_trendCache = array(); + + + public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) { + // Calculate number of points in each dataset + $nY = count($yValues); + $nX = count($xValues); + + // Define X Values if necessary + if ($nX == 0) { + $xValues = range(1,$nY); + $nX = $nY; + } elseif ($nY != $nX) { + // Ensure both arrays of points are the same size + trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR); + } + + $key = md5($trendType.$const.serialize($yValues).serialize($xValues)); + // Determine which trend method has been requested + switch ($trendType) { + // Instantiate and return the class for the requested trend method + case self::TREND_LINEAR : + case self::TREND_LOGARITHMIC : + case self::TREND_EXPONENTIAL : + case self::TREND_POWER : + if (!isset(self::$_trendCache[$key])) { + $className = 'PHPExcel_'.$trendType.'_Best_Fit'; + self::$_trendCache[$key] = new $className($yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_POLYNOMIAL_2 : + case self::TREND_POLYNOMIAL_3 : + case self::TREND_POLYNOMIAL_4 : + case self::TREND_POLYNOMIAL_5 : + case self::TREND_POLYNOMIAL_6 : + if (!isset(self::$_trendCache[$key])) { + $order = substr($trendType,-1); + self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + } + return self::$_trendCache[$key]; + break; + case self::TREND_BEST_FIT : + case self::TREND_BEST_FIT_NO_POLY : + // If the request is to determine the best fit regression, then we test each trend line in turn + // Start by generating an instance of each available trend method + foreach(self::$_trendTypes as $trendMethod) { + $className = 'PHPExcel_'.$trendMethod.'BestFit'; + $bestFit[$trendMethod] = new $className($yValues,$xValues,$const); + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + if ($trendType != self::TREND_BEST_FIT_NO_POLY) { + foreach(self::$_trendTypePolyOrders as $trendMethod) { + $order = substr($trendMethod,-1); + $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const); + if ($bestFit[$trendMethod]->getError()) { + unset($bestFit[$trendMethod]); + } else { + $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); + } + } + } + // Determine which of our trend lines is the best fit, and then we return the instance of that trend class + arsort($bestFitValue); + $bestFitType = key($bestFitValue); + return $bestFit[$bestFitType]; + break; + default : + return false; + } + } // function calculate() + +} // class trendClass \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Style.php b/extend/phpexcel/PHPExcel/Style.php new file mode 100755 index 0000000..715ae11 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style.php @@ -0,0 +1,668 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /** + * Font + * + * @var PHPExcel_Style_Font + */ + protected $_font; + + /** + * Fill + * + * @var PHPExcel_Style_Fill + */ + protected $_fill; + + /** + * Borders + * + * @var PHPExcel_Style_Borders + */ + protected $_borders; + + /** + * Alignment + * + * @var PHPExcel_Style_Alignment + */ + protected $_alignment; + + /** + * Number Format + * + * @var PHPExcel_Style_NumberFormat + */ + protected $_numberFormat; + + /** + * Conditional styles + * + * @var PHPExcel_Style_Conditional[] + */ + protected $_conditionalStyles; + + /** + * Protection + * + * @var PHPExcel_Style_Protection + */ + protected $_protection; + + /** + * Index of style in collection. Only used for real style. + * + * @var int + */ + protected $_index; + + /** + * Use Quote Prefix when displaying in cell editor. Only used for real style. + * + * @var boolean + */ + protected $_quotePrefix = false; + + /** + * Create a new PHPExcel_Style + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = false, $isConditional = false) + { + // Supervisor? + $this->_isSupervisor = $isSupervisor; + + // Initialise values + $this->_conditionalStyles = array(); + $this->_font = new PHPExcel_Style_Font($isSupervisor, $isConditional); + $this->_fill = new PHPExcel_Style_Fill($isSupervisor, $isConditional); + $this->_borders = new PHPExcel_Style_Borders($isSupervisor, $isConditional); + $this->_alignment = new PHPExcel_Style_Alignment($isSupervisor, $isConditional); + $this->_numberFormat = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional); + $this->_protection = new PHPExcel_Style_Protection($isSupervisor, $isConditional); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_font->bindParent($this); + $this->_fill->bindParent($this); + $this->_borders->bindParent($this); + $this->_alignment->bindParent($this); + $this->_numberFormat->bindParent($this); + $this->_protection->bindParent($this); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style + */ + public function getSharedComponent() + { + $activeSheet = $this->getActiveSheet(); + $selectedCell = $this->getActiveCell(); // e.g. 'A1' + + if ($activeSheet->cellExists($selectedCell)) { + $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex(); + } else { + $xfIndex = 0; + } + + return $this->_parent->getCellXfByIndex($xfIndex); + } + + /** + * Get parent. Only used for style supervisor + * + * @return PHPExcel + */ + public function getParent() + { + return $this->_parent; + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('quotePrefix' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray( + * array( + * 'font' => array( + * 'name' => 'Arial', + * 'bold' => true, + * 'italic' => false, + * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE, + * 'strike' => false, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'borders' => array( + * 'bottom' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'top' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ), + * 'quotePrefix' => true + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @param boolean $pAdvanced Advanced mode for setting borders. + * @throws PHPExcel_Exception + * @return PHPExcel_Style + */ + public function applyFromArray($pStyles = null, $pAdvanced = true) + { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + + $pRange = $this->getSelectedCells(); + + // Uppercase coordinate + $pRange = strtoupper($pRange); + + // Is it a cell range or a single cell? + if (strpos($pRange, ':') === false) { + $rangeA = $pRange; + $rangeB = $pRange; + } else { + list($rangeA, $rangeB) = explode(':', $pRange); + } + + // Calculate range outer borders + $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA); + $rangeEnd = PHPExcel_Cell::coordinateFromString($rangeB); + + // Translate column into index + $rangeStart[0] = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1; + $rangeEnd[0] = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1; + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // ADVANCED MODE: + + if ($pAdvanced && isset($pStyles['borders'])) { + + // 'allborders' is a shorthand property for 'outline' and 'inside' and + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['allborders'])) { + foreach (array('outline', 'inside') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['allborders']; + } + } + unset($pStyles['borders']['allborders']); // not needed any more + } + + // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left' + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['outline'])) { + foreach (array('top', 'right', 'bottom', 'left') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['outline']; + } + } + unset($pStyles['borders']['outline']); // not needed any more + } + + // 'inside' is a shorthand property for 'vertical' and 'horizontal' + // it applies to components that have not been set explicitly + if (isset($pStyles['borders']['inside'])) { + foreach (array('vertical', 'horizontal') as $component) { + if (!isset($pStyles['borders'][$component])) { + $pStyles['borders'][$component] = $pStyles['borders']['inside']; + } + } + unset($pStyles['borders']['inside']); // not needed any more + } + + // width and height characteristics of selection, 1, 2, or 3 (for 3 or more) + $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3); + $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3); + + // loop through up to 3 x 3 = 9 regions + for ($x = 1; $x <= $xMax; ++$x) { + // start column index for region + $colStart = ($x == 3) ? + PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]) + : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1); + + // end column index for region + $colEnd = ($x == 1) ? + PHPExcel_Cell::stringFromColumnIndex($rangeStart[0]) + : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x); + + for ($y = 1; $y <= $yMax; ++$y) { + + // which edges are touching the region + $edges = array(); + + // are we at left edge + if ($x == 1) { + $edges[] = 'left'; + } + + // are we at right edge + if ($x == $xMax) { + $edges[] = 'right'; + } + + // are we at top edge? + if ($y == 1) { + $edges[] = 'top'; + } + + // are we at bottom edge? + if ($y == $yMax) { + $edges[] = 'bottom'; + } + + // start row index for region + $rowStart = ($y == 3) ? + $rangeEnd[1] : $rangeStart[1] + $y - 1; + + // end row index for region + $rowEnd = ($y == 1) ? + $rangeStart[1] : $rangeEnd[1] - $yMax + $y; + + // build range for region + $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd; + + // retrieve relevant style array for region + $regionStyles = $pStyles; + unset($regionStyles['borders']['inside']); + + // what are the inner edges of the region when looking at the selection + $innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges ); + + // inner edges that are not touching the region should take the 'inside' border properties if they have been set + foreach ($innerEdges as $innerEdge) { + switch ($innerEdge) { + case 'top': + case 'bottom': + // should pick up 'horizontal' border property if set + if (isset($pStyles['borders']['horizontal'])) { + $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal']; + } else { + unset($regionStyles['borders'][$innerEdge]); + } + break; + case 'left': + case 'right': + // should pick up 'vertical' border property if set + if (isset($pStyles['borders']['vertical'])) { + $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical']; + } else { + unset($regionStyles['borders'][$innerEdge]); + } + break; + } + } + + // apply region style to region by calling applyFromArray() in simple mode + $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false); + } + } + return $this; + } + + // SIMPLE MODE: + + // Selection type, inspect + if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) { + $selectionType = 'COLUMN'; + } else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) { + $selectionType = 'ROW'; + } else { + $selectionType = 'CELL'; + } + + // First loop through columns, rows, or cells to find out which styles are affected by this operation + switch ($selectionType) { + case 'COLUMN': + $oldXfIndexes = array(); + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true; + } + break; + + case 'ROW': + $oldXfIndexes = array(); + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) { + $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style + } else { + $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true; + } + } + break; + + case 'CELL': + $oldXfIndexes = array(); + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true; + } + } + break; + } + + // clone each of the affected styles, apply the style array, and add the new styles to the workbook + $workbook = $this->getActiveSheet()->getParent(); + foreach ($oldXfIndexes as $oldXfIndex => $dummy) { + $style = $workbook->getCellXfByIndex($oldXfIndex); + $newStyle = clone $style; + $newStyle->applyFromArray($pStyles); + + if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) { + // there is already such cell Xf in our collection + $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex(); + } else { + // we don't have such a cell Xf, need to add + $workbook->addCellXf($newStyle); + $newXfIndexes[$oldXfIndex] = $newStyle->getIndex(); + } + } + + // Loop through columns, rows, or cells again and update the XF index + switch ($selectionType) { + case 'COLUMN': + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col); + $oldXfIndex = $columnDimension->getXfIndex(); + $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]); + } + break; + + case 'ROW': + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $rowDimension = $this->getActiveSheet()->getRowDimension($row); + $oldXfIndex = $rowDimension->getXfIndex() === null ? + 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style + $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]); + } + break; + + case 'CELL': + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row); + $oldXfIndex = $cell->getXfIndex(); + $cell->setXfIndex($newXfIndexes[$oldXfIndex]); + } + } + break; + } + + } else { + // not a supervisor, just apply the style array directly on style object + if (array_key_exists('fill', $pStyles)) { + $this->getFill()->applyFromArray($pStyles['fill']); + } + if (array_key_exists('font', $pStyles)) { + $this->getFont()->applyFromArray($pStyles['font']); + } + if (array_key_exists('borders', $pStyles)) { + $this->getBorders()->applyFromArray($pStyles['borders']); + } + if (array_key_exists('alignment', $pStyles)) { + $this->getAlignment()->applyFromArray($pStyles['alignment']); + } + if (array_key_exists('numberformat', $pStyles)) { + $this->getNumberFormat()->applyFromArray($pStyles['numberformat']); + } + if (array_key_exists('protection', $pStyles)) { + $this->getProtection()->applyFromArray($pStyles['protection']); + } + if (array_key_exists('quotePrefix', $pStyles)) { + $this->_quotePrefix = $pStyles['quotePrefix']; + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Fill + * + * @return PHPExcel_Style_Fill + */ + public function getFill() + { + return $this->_fill; + } + + /** + * Get Font + * + * @return PHPExcel_Style_Font + */ + public function getFont() + { + return $this->_font; + } + + /** + * Set font + * + * @param PHPExcel_Style_Font $font + * @return PHPExcel_Style + */ + public function setFont(PHPExcel_Style_Font $font) + { + $this->_font = $font; + return $this; + } + + /** + * Get Borders + * + * @return PHPExcel_Style_Borders + */ + public function getBorders() + { + return $this->_borders; + } + + /** + * Get Alignment + * + * @return PHPExcel_Style_Alignment + */ + public function getAlignment() + { + return $this->_alignment; + } + + /** + * Get Number Format + * + * @return PHPExcel_Style_NumberFormat + */ + public function getNumberFormat() + { + return $this->_numberFormat; + } + + /** + * Get Conditional Styles. Only used on supervisor. + * + * @return PHPExcel_Style_Conditional[] + */ + public function getConditionalStyles() + { + return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell()); + } + + /** + * Set Conditional Styles. Only used on supervisor. + * + * @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles + * @return PHPExcel_Style + */ + public function setConditionalStyles($pValue = null) + { + if (is_array($pValue)) { + $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue); + } + return $this; + } + + /** + * Get Protection + * + * @return PHPExcel_Style_Protection + */ + public function getProtection() + { + return $this->_protection; + } + + /** + * Get quote prefix + * + * @return boolean + */ + public function getQuotePrefix() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getQuotePrefix(); + } + return $this->_quotePrefix; + } + + /** + * Set quote prefix + * + * @param boolean $pValue + */ + public function setQuotePrefix($pValue) + { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = array('quotePrefix' => $pValue); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_quotePrefix = (boolean) $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + $hashConditionals = ''; + foreach ($this->_conditionalStyles as $conditional) { + $hashConditionals .= $conditional->getHashCode(); + } + + return md5( + $this->_fill->getHashCode() + . $this->_font->getHashCode() + . $this->_borders->getHashCode() + . $this->_alignment->getHashCode() + . $this->_numberFormat->getHashCode() + . $hashConditionals + . $this->_protection->getHashCode() + . ($this->_quotePrefix ? 't' : 'f') + . __CLASS__ + ); + } + + /** + * Get own index in style collection + * + * @return int + */ + public function getIndex() + { + return $this->_index; + } + + /** + * Set own index in style collection + * + * @param int $pValue + */ + public function setIndex($pValue) + { + $this->_index = $pValue; + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Alignment.php b/extend/phpexcel/PHPExcel/Style/Alignment.php new file mode 100755 index 0000000..0d9e076 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Alignment.php @@ -0,0 +1,412 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Alignment + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Horizontal alignment styles */ + const HORIZONTAL_GENERAL = 'general'; + const HORIZONTAL_LEFT = 'left'; + const HORIZONTAL_RIGHT = 'right'; + const HORIZONTAL_CENTER = 'center'; + const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; + const HORIZONTAL_JUSTIFY = 'justify'; + const HORIZONTAL_FILL = 'fill'; + const HORIZONTAL_DISTRIBUTED = 'distributed'; // Excel2007 only + + /* Vertical alignment styles */ + const VERTICAL_BOTTOM = 'bottom'; + const VERTICAL_TOP = 'top'; + const VERTICAL_CENTER = 'center'; + const VERTICAL_JUSTIFY = 'justify'; + const VERTICAL_DISTRIBUTED = 'distributed'; // Excel2007 only + + /** + * Horizontal + * + * @var string + */ + protected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + + /** + * Vertical + * + * @var string + */ + protected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + + /** + * Text rotation + * + * @var int + */ + protected $_textRotation = 0; + + /** + * Wrap text + * + * @var boolean + */ + protected $_wrapText = FALSE; + + /** + * Shrink to fit + * + * @var boolean + */ + protected $_shrinkToFit = FALSE; + + /** + * Indent - only possible with horizontal alignment left and right + * + * @var int + */ + protected $_indent = 0; + + /** + * Create a new PHPExcel_Style_Alignment + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + if ($isConditional) { + $this->_horizontal = NULL; + $this->_vertical = NULL; + $this->_textRotation = NULL; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Alignment + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getAlignment(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('alignment' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray( + * array( + * 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER, + * 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER, + * 'rotation' => 0, + * 'wrap' => TRUE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Alignment + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells()) + ->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['horizontal'])) { + $this->setHorizontal($pStyles['horizontal']); + } + if (isset($pStyles['vertical'])) { + $this->setVertical($pStyles['vertical']); + } + if (isset($pStyles['rotation'])) { + $this->setTextRotation($pStyles['rotation']); + } + if (isset($pStyles['wrap'])) { + $this->setWrapText($pStyles['wrap']); + } + if (isset($pStyles['shrinkToFit'])) { + $this->setShrinkToFit($pStyles['shrinkToFit']); + } + if (isset($pStyles['indent'])) { + $this->setIndent($pStyles['indent']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Horizontal + * + * @return string + */ + public function getHorizontal() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHorizontal(); + } + return $this->_horizontal; + } + + /** + * Set Horizontal + * + * @param string $pValue + * @return PHPExcel_Style_Alignment + */ + public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; + } + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('horizontal' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } + else { + $this->_horizontal = $pValue; + } + return $this; + } + + /** + * Get Vertical + * + * @return string + */ + public function getVertical() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getVertical(); + } + return $this->_vertical; + } + + /** + * Set Vertical + * + * @param string $pValue + * @return PHPExcel_Style_Alignment + */ + public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; + } + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('vertical' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_vertical = $pValue; + } + return $this; + } + + /** + * Get TextRotation + * + * @return int + */ + public function getTextRotation() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getTextRotation(); + } + return $this->_textRotation; + } + + /** + * Set TextRotation + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Alignment + */ + public function setTextRotation($pValue = 0) { + // Excel2007 value 255 => PHPExcel value -165 + if ($pValue == 255) { + $pValue = -165; + } + + // Set rotation + if ( ($pValue >= -90 && $pValue <= 90) || $pValue == -165 ) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('rotation' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_textRotation = $pValue; + } + } else { + throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90."); + } + + return $this; + } + + /** + * Get Wrap Text + * + * @return boolean + */ + public function getWrapText() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getWrapText(); + } + return $this->_wrapText; + } + + /** + * Set Wrap Text + * + * @param boolean $pValue + * @return PHPExcel_Style_Alignment + */ + public function setWrapText($pValue = FALSE) { + if ($pValue == '') { + $pValue = FALSE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('wrap' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_wrapText = $pValue; + } + return $this; + } + + /** + * Get Shrink to fit + * + * @return boolean + */ + public function getShrinkToFit() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getShrinkToFit(); + } + return $this->_shrinkToFit; + } + + /** + * Set Shrink to fit + * + * @param boolean $pValue + * @return PHPExcel_Style_Alignment + */ + public function setShrinkToFit($pValue = FALSE) { + if ($pValue == '') { + $pValue = FALSE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_shrinkToFit = $pValue; + } + return $this; + } + + /** + * Get indent + * + * @return int + */ + public function getIndent() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getIndent(); + } + return $this->_indent; + } + + /** + * Set indent + * + * @param int $pValue + * @return PHPExcel_Style_Alignment + */ + public function setIndent($pValue = 0) { + if ($pValue > 0) { + if ($this->getHorizontal() != self::HORIZONTAL_GENERAL && + $this->getHorizontal() != self::HORIZONTAL_LEFT && + $this->getHorizontal() != self::HORIZONTAL_RIGHT) { + $pValue = 0; // indent not supported + } + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('indent' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_indent = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_horizontal + . $this->_vertical + . $this->_textRotation + . ($this->_wrapText ? 't' : 'f') + . ($this->_shrinkToFit ? 't' : 'f') + . $this->_indent + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Border.php b/extend/phpexcel/PHPExcel/Style/Border.php new file mode 100755 index 0000000..3b7eba9 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Border.php @@ -0,0 +1,294 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Border + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Border style */ + const BORDER_NONE = 'none'; + const BORDER_DASHDOT = 'dashDot'; + const BORDER_DASHDOTDOT = 'dashDotDot'; + const BORDER_DASHED = 'dashed'; + const BORDER_DOTTED = 'dotted'; + const BORDER_DOUBLE = 'double'; + const BORDER_HAIR = 'hair'; + const BORDER_MEDIUM = 'medium'; + const BORDER_MEDIUMDASHDOT = 'mediumDashDot'; + const BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot'; + const BORDER_MEDIUMDASHED = 'mediumDashed'; + const BORDER_SLANTDASHDOT = 'slantDashDot'; + const BORDER_THICK = 'thick'; + const BORDER_THIN = 'thin'; + + /** + * Border style + * + * @var string + */ + protected $_borderStyle = PHPExcel_Style_Border::BORDER_NONE; + + /** + * Border color + * + * @var PHPExcel_Style_Color + */ + protected $_color; + + /** + * Parent property name + * + * @var string + */ + protected $_parentPropertyName; + + /** + * Create a new PHPExcel_Style_Border + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_color->bindParent($this, '_color'); + } + } + + /** + * Bind parent. Only used for supervisor + * + * @param PHPExcel_Style_Borders $parent + * @param string $parentPropertyName + * @return PHPExcel_Style_Border + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + $this->_parentPropertyName = $parentPropertyName; + return $this; + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getSharedComponent() + { + switch ($this->_parentPropertyName) { + case '_allBorders': + case '_horizontal': + case '_inside': + case '_outline': + case '_vertical': + throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.'); + break; + case '_bottom': + return $this->_parent->getSharedComponent()->getBottom(); break; + case '_diagonal': + return $this->_parent->getSharedComponent()->getDiagonal(); break; + case '_left': + return $this->_parent->getSharedComponent()->getLeft(); break; + case '_right': + return $this->_parent->getSharedComponent()->getRight(); break; + case '_top': + return $this->_parent->getSharedComponent()->getTop(); break; + + } + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + switch ($this->_parentPropertyName) { + case '_allBorders': + $key = 'allborders'; break; + case '_bottom': + $key = 'bottom'; break; + case '_diagonal': + $key = 'diagonal'; break; + case '_horizontal': + $key = 'horizontal'; break; + case '_inside': + $key = 'inside'; break; + case '_left': + $key = 'left'; break; + case '_outline': + $key = 'outline'; break; + case '_right': + $key = 'right'; break; + case '_top': + $key = 'top'; break; + case '_vertical': + $key = 'vertical'; break; + } + return $this->_parent->getStyleArray(array($key => $array)); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray( + * array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Border + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['style'])) { + $this->setBorderStyle($pStyles['style']); + } + if (isset($pStyles['color'])) { + $this->getColor()->applyFromArray($pStyles['color']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Border style + * + * @return string + */ + public function getBorderStyle() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBorderStyle(); + } + return $this->_borderStyle; + } + + /** + * Set Border style + * + * @param string|boolean $pValue + * When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE + * and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM + * @return PHPExcel_Style_Border + */ + public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE) { + + if (empty($pValue)) { + $pValue = PHPExcel_Style_Border::BORDER_NONE; + } elseif(is_bool($pValue) && $pValue) { + $pValue = PHPExcel_Style_Border::BORDER_MEDIUM; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('style' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_borderStyle = $pValue; + } + return $this; + } + + /** + * Get Border Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Border Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Border + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_color = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_borderStyle + . $this->_color->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Borders.php b/extend/phpexcel/PHPExcel/Style/Borders.php new file mode 100755 index 0000000..b90838a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Borders.php @@ -0,0 +1,424 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Borders + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Diagonal directions */ + const DIAGONAL_NONE = 0; + const DIAGONAL_UP = 1; + const DIAGONAL_DOWN = 2; + const DIAGONAL_BOTH = 3; + + /** + * Left + * + * @var PHPExcel_Style_Border + */ + protected $_left; + + /** + * Right + * + * @var PHPExcel_Style_Border + */ + protected $_right; + + /** + * Top + * + * @var PHPExcel_Style_Border + */ + protected $_top; + + /** + * Bottom + * + * @var PHPExcel_Style_Border + */ + protected $_bottom; + + /** + * Diagonal + * + * @var PHPExcel_Style_Border + */ + protected $_diagonal; + + /** + * DiagonalDirection + * + * @var int + */ + protected $_diagonalDirection; + + /** + * All borders psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_allBorders; + + /** + * Outline psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_outline; + + /** + * Inside psedo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_inside; + + /** + * Vertical pseudo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_vertical; + + /** + * Horizontal pseudo-border. Only applies to supervisor. + * + * @var PHPExcel_Style_Border + */ + protected $_horizontal; + + /** + * Create a new PHPExcel_Style_Borders + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + $this->_left = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_right = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_top = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_bottom = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_diagonal = new PHPExcel_Style_Border($isSupervisor, $isConditional); + $this->_diagonalDirection = PHPExcel_Style_Borders::DIAGONAL_NONE; + + // Specially for supervisor + if ($isSupervisor) { + // Initialize pseudo-borders + $this->_allBorders = new PHPExcel_Style_Border(TRUE); + $this->_outline = new PHPExcel_Style_Border(TRUE); + $this->_inside = new PHPExcel_Style_Border(TRUE); + $this->_vertical = new PHPExcel_Style_Border(TRUE); + $this->_horizontal = new PHPExcel_Style_Border(TRUE); + + // bind parent if we are a supervisor + $this->_left->bindParent($this, '_left'); + $this->_right->bindParent($this, '_right'); + $this->_top->bindParent($this, '_top'); + $this->_bottom->bindParent($this, '_bottom'); + $this->_diagonal->bindParent($this, '_diagonal'); + $this->_allBorders->bindParent($this, '_allBorders'); + $this->_outline->bindParent($this, '_outline'); + $this->_inside->bindParent($this, '_inside'); + $this->_vertical->bindParent($this, '_vertical'); + $this->_horizontal->bindParent($this, '_horizontal'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Borders + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getBorders(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('borders' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( + * array( + * 'bottom' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ), + * 'top' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ) + * ); + * </code> + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( + * array( + * 'allborders' => array( + * 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Borders + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('left', $pStyles)) { + $this->getLeft()->applyFromArray($pStyles['left']); + } + if (array_key_exists('right', $pStyles)) { + $this->getRight()->applyFromArray($pStyles['right']); + } + if (array_key_exists('top', $pStyles)) { + $this->getTop()->applyFromArray($pStyles['top']); + } + if (array_key_exists('bottom', $pStyles)) { + $this->getBottom()->applyFromArray($pStyles['bottom']); + } + if (array_key_exists('diagonal', $pStyles)) { + $this->getDiagonal()->applyFromArray($pStyles['diagonal']); + } + if (array_key_exists('diagonaldirection', $pStyles)) { + $this->setDiagonalDirection($pStyles['diagonaldirection']); + } + if (array_key_exists('allborders', $pStyles)) { + $this->getLeft()->applyFromArray($pStyles['allborders']); + $this->getRight()->applyFromArray($pStyles['allborders']); + $this->getTop()->applyFromArray($pStyles['allborders']); + $this->getBottom()->applyFromArray($pStyles['allborders']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Left + * + * @return PHPExcel_Style_Border + */ + public function getLeft() { + return $this->_left; + } + + /** + * Get Right + * + * @return PHPExcel_Style_Border + */ + public function getRight() { + return $this->_right; + } + + /** + * Get Top + * + * @return PHPExcel_Style_Border + */ + public function getTop() { + return $this->_top; + } + + /** + * Get Bottom + * + * @return PHPExcel_Style_Border + */ + public function getBottom() { + return $this->_bottom; + } + + /** + * Get Diagonal + * + * @return PHPExcel_Style_Border + */ + public function getDiagonal() { + return $this->_diagonal; + } + + /** + * Get AllBorders (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getAllBorders() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_allBorders; + } + + /** + * Get Outline (pseudo-border). Only applies to supervisor. + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function getOutline() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_outline; + } + + /** + * Get Inside (pseudo-border). Only applies to supervisor. + * + * @return boolean + * @throws PHPExcel_Exception + */ + public function getInside() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_inside; + } + + /** + * Get Vertical (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getVertical() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_vertical; + } + + /** + * Get Horizontal (pseudo-border). Only applies to supervisor. + * + * @return PHPExcel_Style_Border + * @throws PHPExcel_Exception + */ + public function getHorizontal() { + if (!$this->_isSupervisor) { + throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); + } + return $this->_horizontal; + } + + /** + * Get DiagonalDirection + * + * @return int + */ + public function getDiagonalDirection() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getDiagonalDirection(); + } + return $this->_diagonalDirection; + } + + /** + * Set DiagonalDirection + * + * @param int $pValue + * @return PHPExcel_Style_Borders + */ + public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Borders::DIAGONAL_NONE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_diagonalDirection = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashcode(); + } + return md5( + $this->getLeft()->getHashCode() + . $this->getRight()->getHashCode() + . $this->getTop()->getHashCode() + . $this->getBottom()->getHashCode() + . $this->getDiagonal()->getHashCode() + . $this->getDiagonalDirection() + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Color.php b/extend/phpexcel/PHPExcel/Style/Color.php new file mode 100755 index 0000000..4d34504 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Color.php @@ -0,0 +1,429 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Color + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Colors */ + const COLOR_BLACK = 'FF000000'; + const COLOR_WHITE = 'FFFFFFFF'; + const COLOR_RED = 'FFFF0000'; + const COLOR_DARKRED = 'FF800000'; + const COLOR_BLUE = 'FF0000FF'; + const COLOR_DARKBLUE = 'FF000080'; + const COLOR_GREEN = 'FF00FF00'; + const COLOR_DARKGREEN = 'FF008000'; + const COLOR_YELLOW = 'FFFFFF00'; + const COLOR_DARKYELLOW = 'FF808000'; + + /** + * Indexed colors array + * + * @var array + */ + protected static $_indexedColors; + + /** + * ARGB - Alpha RGB + * + * @var string + */ + protected $_argb = NULL; + + /** + * Parent property name + * + * @var string + */ + protected $_parentPropertyName; + + + /** + * Create a new PHPExcel_Style_Color + * + * @param string $pARGB ARGB value for the colour + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($pARGB = PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if (!$isConditional) { + $this->_argb = $pARGB; + } + } + + /** + * Bind parent. Only used for supervisor + * + * @param mixed $parent + * @param string $parentPropertyName + * @return PHPExcel_Style_Color + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + $this->_parentPropertyName = $parentPropertyName; + return $this; + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Color + */ + public function getSharedComponent() + { + switch ($this->_parentPropertyName) { + case '_endColor': + return $this->_parent->getSharedComponent()->getEndColor(); break; + case '_color': + return $this->_parent->getSharedComponent()->getColor(); break; + case '_startColor': + return $this->_parent->getSharedComponent()->getStartColor(); break; + } + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + switch ($this->_parentPropertyName) { + case '_endColor': + $key = 'endcolor'; + break; + case '_color': + $key = 'color'; + break; + case '_startColor': + $key = 'startcolor'; + break; + + } + return $this->_parent->getStyleArray(array($key => $array)); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Color + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('rgb', $pStyles)) { + $this->setRGB($pStyles['rgb']); + } + if (array_key_exists('argb', $pStyles)) { + $this->setARGB($pStyles['argb']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get ARGB + * + * @return string + */ + public function getARGB() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getARGB(); + } + return $this->_argb; + } + + /** + * Set ARGB + * + * @param string $pValue + * @return PHPExcel_Style_Color + */ + public function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK) { + if ($pValue == '') { + $pValue = PHPExcel_Style_Color::COLOR_BLACK; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('argb' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_argb = $pValue; + } + return $this; + } + + /** + * Get RGB + * + * @return string + */ + public function getRGB() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getRGB(); + } + return substr($this->_argb, 2); + } + + /** + * Set RGB + * + * @param string $pValue RGB value + * @return PHPExcel_Style_Color + */ + public function setRGB($pValue = '000000') { + if ($pValue == '') { + $pValue = '000000'; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_argb = 'FF' . $pValue; + } + return $this; + } + + /** + * Get a specified colour component of an RGB value + * + * @private + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param int $offset Position within the RGB value to extract + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The extracted colour component + */ + private static function _getColourComponent($RGB,$offset,$hex=TRUE) { + $colour = substr($RGB, $offset, 2); + if (!$hex) + $colour = hexdec($colour); + return $colour; + } + + /** + * Get the red colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The red colour component + */ + public static function getRed($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 6, $hex); + } + + /** + * Get the green colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The green colour component + */ + public static function getGreen($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 4, $hex); + } + + /** + * Get the blue colour component of an RGB value + * + * @param string $RGB The colour as an RGB value (e.g. FF00CCCC or CCDDEE + * @param boolean $hex Flag indicating whether the component should be returned as a hex or a + * decimal value + * @return string The blue colour component + */ + public static function getBlue($RGB,$hex=TRUE) { + return self::_getColourComponent($RGB, strlen($RGB) - 2, $hex); + } + + /** + * Adjust the brightness of a color + * + * @param string $hex The colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) + * @param float $adjustPercentage The percentage by which to adjust the colour as a float from -1 to 1 + * @return string The adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE) + */ + public static function changeBrightness($hex, $adjustPercentage) { + $rgba = (strlen($hex) == 8); + + $red = self::getRed($hex, FALSE); + $green = self::getGreen($hex, FALSE); + $blue = self::getBlue($hex, FALSE); + if ($adjustPercentage > 0) { + $red += (255 - $red) * $adjustPercentage; + $green += (255 - $green) * $adjustPercentage; + $blue += (255 - $blue) * $adjustPercentage; + } else { + $red += $red * $adjustPercentage; + $green += $green * $adjustPercentage; + $blue += $blue * $adjustPercentage; + } + + if ($red < 0) $red = 0; + elseif ($red > 255) $red = 255; + if ($green < 0) $green = 0; + elseif ($green > 255) $green = 255; + if ($blue < 0) $blue = 0; + elseif ($blue > 255) $blue = 255; + + $rgb = strtoupper( str_pad(dechex($red), 2, '0', 0) . + str_pad(dechex($green), 2, '0', 0) . + str_pad(dechex($blue), 2, '0', 0) + ); + return (($rgba) ? 'FF' : '') . $rgb; + } + + /** + * Get indexed color + * + * @param int $pIndex Index entry point into the colour array + * @param boolean $background Flag to indicate whether default background or foreground colour + * should be returned if the indexed colour doesn't exist + * @return PHPExcel_Style_Color + */ + public static function indexedColor($pIndex, $background=FALSE) { + // Clean parameter + $pIndex = intval($pIndex); + + // Indexed colors + if (is_null(self::$_indexedColors)) { + self::$_indexedColors = array( + 1 => 'FF000000', // System Colour #1 - Black + 2 => 'FFFFFFFF', // System Colour #2 - White + 3 => 'FFFF0000', // System Colour #3 - Red + 4 => 'FF00FF00', // System Colour #4 - Green + 5 => 'FF0000FF', // System Colour #5 - Blue + 6 => 'FFFFFF00', // System Colour #6 - Yellow + 7 => 'FFFF00FF', // System Colour #7- Magenta + 8 => 'FF00FFFF', // System Colour #8- Cyan + 9 => 'FF800000', // Standard Colour #9 + 10 => 'FF008000', // Standard Colour #10 + 11 => 'FF000080', // Standard Colour #11 + 12 => 'FF808000', // Standard Colour #12 + 13 => 'FF800080', // Standard Colour #13 + 14 => 'FF008080', // Standard Colour #14 + 15 => 'FFC0C0C0', // Standard Colour #15 + 16 => 'FF808080', // Standard Colour #16 + 17 => 'FF9999FF', // Chart Fill Colour #17 + 18 => 'FF993366', // Chart Fill Colour #18 + 19 => 'FFFFFFCC', // Chart Fill Colour #19 + 20 => 'FFCCFFFF', // Chart Fill Colour #20 + 21 => 'FF660066', // Chart Fill Colour #21 + 22 => 'FFFF8080', // Chart Fill Colour #22 + 23 => 'FF0066CC', // Chart Fill Colour #23 + 24 => 'FFCCCCFF', // Chart Fill Colour #24 + 25 => 'FF000080', // Chart Line Colour #25 + 26 => 'FFFF00FF', // Chart Line Colour #26 + 27 => 'FFFFFF00', // Chart Line Colour #27 + 28 => 'FF00FFFF', // Chart Line Colour #28 + 29 => 'FF800080', // Chart Line Colour #29 + 30 => 'FF800000', // Chart Line Colour #30 + 31 => 'FF008080', // Chart Line Colour #31 + 32 => 'FF0000FF', // Chart Line Colour #32 + 33 => 'FF00CCFF', // Standard Colour #33 + 34 => 'FFCCFFFF', // Standard Colour #34 + 35 => 'FFCCFFCC', // Standard Colour #35 + 36 => 'FFFFFF99', // Standard Colour #36 + 37 => 'FF99CCFF', // Standard Colour #37 + 38 => 'FFFF99CC', // Standard Colour #38 + 39 => 'FFCC99FF', // Standard Colour #39 + 40 => 'FFFFCC99', // Standard Colour #40 + 41 => 'FF3366FF', // Standard Colour #41 + 42 => 'FF33CCCC', // Standard Colour #42 + 43 => 'FF99CC00', // Standard Colour #43 + 44 => 'FFFFCC00', // Standard Colour #44 + 45 => 'FFFF9900', // Standard Colour #45 + 46 => 'FFFF6600', // Standard Colour #46 + 47 => 'FF666699', // Standard Colour #47 + 48 => 'FF969696', // Standard Colour #48 + 49 => 'FF003366', // Standard Colour #49 + 50 => 'FF339966', // Standard Colour #50 + 51 => 'FF003300', // Standard Colour #51 + 52 => 'FF333300', // Standard Colour #52 + 53 => 'FF993300', // Standard Colour #53 + 54 => 'FF993366', // Standard Colour #54 + 55 => 'FF333399', // Standard Colour #55 + 56 => 'FF333333' // Standard Colour #56 + ); + } + + if (array_key_exists($pIndex, self::$_indexedColors)) { + return new PHPExcel_Style_Color(self::$_indexedColors[$pIndex]); + } + + if ($background) { + return new PHPExcel_Style_Color('FFFFFFFF'); + } + return new PHPExcel_Style_Color('FF000000'); + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_argb + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Conditional.php b/extend/phpexcel/PHPExcel/Style/Conditional.php new file mode 100755 index 0000000..ffd7a9f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Conditional.php @@ -0,0 +1,277 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Conditional + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Conditional implements PHPExcel_IComparable +{ + /* Condition types */ + const CONDITION_NONE = 'none'; + const CONDITION_CELLIS = 'cellIs'; + const CONDITION_CONTAINSTEXT = 'containsText'; + const CONDITION_EXPRESSION = 'expression'; + + /* Operator types */ + const OPERATOR_NONE = ''; + const OPERATOR_BEGINSWITH = 'beginsWith'; + const OPERATOR_ENDSWITH = 'endsWith'; + const OPERATOR_EQUAL = 'equal'; + const OPERATOR_GREATERTHAN = 'greaterThan'; + const OPERATOR_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const OPERATOR_LESSTHAN = 'lessThan'; + const OPERATOR_LESSTHANOREQUAL = 'lessThanOrEqual'; + const OPERATOR_NOTEQUAL = 'notEqual'; + const OPERATOR_CONTAINSTEXT = 'containsText'; + const OPERATOR_NOTCONTAINS = 'notContains'; + const OPERATOR_BETWEEN = 'between'; + + /** + * Condition type + * + * @var int + */ + private $_conditionType; + + /** + * Operator type + * + * @var int + */ + private $_operatorType; + + /** + * Text + * + * @var string + */ + private $_text; + + /** + * Condition + * + * @var string[] + */ + private $_condition = array(); + + /** + * Style + * + * @var PHPExcel_Style + */ + private $_style; + + /** + * Create a new PHPExcel_Style_Conditional + */ + public function __construct() + { + // Initialise values + $this->_conditionType = PHPExcel_Style_Conditional::CONDITION_NONE; + $this->_operatorType = PHPExcel_Style_Conditional::OPERATOR_NONE; + $this->_text = null; + $this->_condition = array(); + $this->_style = new PHPExcel_Style(FALSE, TRUE); + } + + /** + * Get Condition type + * + * @return string + */ + public function getConditionType() { + return $this->_conditionType; + } + + /** + * Set Condition type + * + * @param string $pValue PHPExcel_Style_Conditional condition type + * @return PHPExcel_Style_Conditional + */ + public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE) { + $this->_conditionType = $pValue; + return $this; + } + + /** + * Get Operator type + * + * @return string + */ + public function getOperatorType() { + return $this->_operatorType; + } + + /** + * Set Operator type + * + * @param string $pValue PHPExcel_Style_Conditional operator type + * @return PHPExcel_Style_Conditional + */ + public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE) { + $this->_operatorType = $pValue; + return $this; + } + + /** + * Get text + * + * @return string + */ + public function getText() { + return $this->_text; + } + + /** + * Set text + * + * @param string $value + * @return PHPExcel_Style_Conditional + */ + public function setText($value = null) { + $this->_text = $value; + return $this; + } + + /** + * Get Condition + * + * @deprecated Deprecated, use getConditions instead + * @return string + */ + public function getCondition() { + if (isset($this->_condition[0])) { + return $this->_condition[0]; + } + + return ''; + } + + /** + * Set Condition + * + * @deprecated Deprecated, use setConditions instead + * @param string $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function setCondition($pValue = '') { + if (!is_array($pValue)) + $pValue = array($pValue); + + return $this->setConditions($pValue); + } + + /** + * Get Conditions + * + * @return string[] + */ + public function getConditions() { + return $this->_condition; + } + + /** + * Set Conditions + * + * @param string[] $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function setConditions($pValue) { + if (!is_array($pValue)) + $pValue = array($pValue); + + $this->_condition = $pValue; + return $this; + } + + /** + * Add Condition + * + * @param string $pValue Condition + * @return PHPExcel_Style_Conditional + */ + public function addCondition($pValue = '') { + $this->_condition[] = $pValue; + return $this; + } + + /** + * Get Style + * + * @return PHPExcel_Style + */ + public function getStyle() { + return $this->_style; + } + + /** + * Set Style + * + * @param PHPExcel_Style $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Conditional + */ + public function setStyle(PHPExcel_Style $pValue = null) { + $this->_style = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_conditionType + . $this->_operatorType + . implode(';', $this->_condition) + . $this->_style->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Style/Fill.php b/extend/phpexcel/PHPExcel/Style/Fill.php new file mode 100755 index 0000000..1b4d0ad --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Fill.php @@ -0,0 +1,321 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Fill + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Fill types */ + const FILL_NONE = 'none'; + const FILL_SOLID = 'solid'; + const FILL_GRADIENT_LINEAR = 'linear'; + const FILL_GRADIENT_PATH = 'path'; + const FILL_PATTERN_DARKDOWN = 'darkDown'; + const FILL_PATTERN_DARKGRAY = 'darkGray'; + const FILL_PATTERN_DARKGRID = 'darkGrid'; + const FILL_PATTERN_DARKHORIZONTAL = 'darkHorizontal'; + const FILL_PATTERN_DARKTRELLIS = 'darkTrellis'; + const FILL_PATTERN_DARKUP = 'darkUp'; + const FILL_PATTERN_DARKVERTICAL = 'darkVertical'; + const FILL_PATTERN_GRAY0625 = 'gray0625'; + const FILL_PATTERN_GRAY125 = 'gray125'; + const FILL_PATTERN_LIGHTDOWN = 'lightDown'; + const FILL_PATTERN_LIGHTGRAY = 'lightGray'; + const FILL_PATTERN_LIGHTGRID = 'lightGrid'; + const FILL_PATTERN_LIGHTHORIZONTAL = 'lightHorizontal'; + const FILL_PATTERN_LIGHTTRELLIS = 'lightTrellis'; + const FILL_PATTERN_LIGHTUP = 'lightUp'; + const FILL_PATTERN_LIGHTVERTICAL = 'lightVertical'; + const FILL_PATTERN_MEDIUMGRAY = 'mediumGray'; + + /** + * Fill type + * + * @var string + */ + protected $_fillType = PHPExcel_Style_Fill::FILL_NONE; + + /** + * Rotation + * + * @var double + */ + protected $_rotation = 0; + + /** + * Start color + * + * @var PHPExcel_Style_Color + */ + protected $_startColor; + + /** + * End color + * + * @var PHPExcel_Style_Color + */ + protected $_endColor; + + /** + * Create a new PHPExcel_Style_Fill + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if ($isConditional) { + $this->_fillType = NULL; + } + $this->_startColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional); + $this->_endColor = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional); + + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_startColor->bindParent($this, '_startColor'); + $this->_endColor->bindParent($this, '_endColor'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Fill + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getFill(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('fill' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray( + * array( + * 'type' => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR, + * 'rotation' => 0, + * 'startcolor' => array( + * 'rgb' => '000000' + * ), + * 'endcolor' => array( + * 'argb' => 'FFFFFFFF' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('type', $pStyles)) { + $this->setFillType($pStyles['type']); + } + if (array_key_exists('rotation', $pStyles)) { + $this->setRotation($pStyles['rotation']); + } + if (array_key_exists('startcolor', $pStyles)) { + $this->getStartColor()->applyFromArray($pStyles['startcolor']); + } + if (array_key_exists('endcolor', $pStyles)) { + $this->getEndColor()->applyFromArray($pStyles['endcolor']); + } + if (array_key_exists('color', $pStyles)) { + $this->getStartColor()->applyFromArray($pStyles['color']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Fill Type + * + * @return string + */ + public function getFillType() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getFillType(); + } + return $this->_fillType; + } + + /** + * Set Fill Type + * + * @param string $pValue PHPExcel_Style_Fill fill type + * @return PHPExcel_Style_Fill + */ + public function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('type' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_fillType = $pValue; + } + return $this; + } + + /** + * Get Rotation + * + * @return double + */ + public function getRotation() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getRotation(); + } + return $this->_rotation; + } + + /** + * Set Rotation + * + * @param double $pValue + * @return PHPExcel_Style_Fill + */ + public function setRotation($pValue = 0) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('rotation' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_rotation = $pValue; + } + return $this; + } + + /** + * Get Start Color + * + * @return PHPExcel_Style_Color + */ + public function getStartColor() { + return $this->_startColor; + } + + /** + * Set Start Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function setStartColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_startColor = $color; + } + return $this; + } + + /** + * Get End Color + * + * @return PHPExcel_Style_Color + */ + public function getEndColor() { + return $this->_endColor; + } + + /** + * Set End Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Fill + */ + public function setEndColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_endColor = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->getFillType() + . $this->getRotation() + . $this->getStartColor()->getHashCode() + . $this->getEndColor()->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Font.php b/extend/phpexcel/PHPExcel/Style/Font.php new file mode 100755 index 0000000..e89488c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Font.php @@ -0,0 +1,532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Font + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Underline types */ + const UNDERLINE_NONE = 'none'; + const UNDERLINE_DOUBLE = 'double'; + const UNDERLINE_DOUBLEACCOUNTING = 'doubleAccounting'; + const UNDERLINE_SINGLE = 'single'; + const UNDERLINE_SINGLEACCOUNTING = 'singleAccounting'; + + /** + * Font Name + * + * @var string + */ + protected $_name = 'Calibri'; + + /** + * Font Size + * + * @var float + */ + protected $_size = 11; + + /** + * Bold + * + * @var boolean + */ + protected $_bold = FALSE; + + /** + * Italic + * + * @var boolean + */ + protected $_italic = FALSE; + + /** + * Superscript + * + * @var boolean + */ + protected $_superScript = FALSE; + + /** + * Subscript + * + * @var boolean + */ + protected $_subScript = FALSE; + + /** + * Underline + * + * @var string + */ + protected $_underline = self::UNDERLINE_NONE; + + /** + * Strikethrough + * + * @var boolean + */ + protected $_strikethrough = FALSE; + + /** + * Foreground color + * + * @var PHPExcel_Style_Color + */ + protected $_color; + + /** + * Create a new PHPExcel_Style_Font + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if ($isConditional) { + $this->_name = NULL; + $this->_size = NULL; + $this->_bold = NULL; + $this->_italic = NULL; + $this->_superScript = NULL; + $this->_subScript = NULL; + $this->_underline = NULL; + $this->_strikethrough = NULL; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional); + } else { + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor); + } + // bind parent if we are a supervisor + if ($isSupervisor) { + $this->_color->bindParent($this, '_color'); + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Font + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getFont(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('font' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray( + * array( + * 'name' => 'Arial', + * 'bold' => TRUE, + * 'italic' => FALSE, + * 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE, + * 'strike' => FALSE, + * 'color' => array( + * 'rgb' => '808080' + * ) + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Font + */ + public function applyFromArray($pStyles = null) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('name', $pStyles)) { + $this->setName($pStyles['name']); + } + if (array_key_exists('bold', $pStyles)) { + $this->setBold($pStyles['bold']); + } + if (array_key_exists('italic', $pStyles)) { + $this->setItalic($pStyles['italic']); + } + if (array_key_exists('superScript', $pStyles)) { + $this->setSuperScript($pStyles['superScript']); + } + if (array_key_exists('subScript', $pStyles)) { + $this->setSubScript($pStyles['subScript']); + } + if (array_key_exists('underline', $pStyles)) { + $this->setUnderline($pStyles['underline']); + } + if (array_key_exists('strike', $pStyles)) { + $this->setStrikethrough($pStyles['strike']); + } + if (array_key_exists('color', $pStyles)) { + $this->getColor()->applyFromArray($pStyles['color']); + } + if (array_key_exists('size', $pStyles)) { + $this->setSize($pStyles['size']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getName(); + } + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Style_Font + */ + public function setName($pValue = 'Calibri') { + if ($pValue == '') { + $pValue = 'Calibri'; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('name' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_name = $pValue; + } + return $this; + } + + /** + * Get Size + * + * @return double + */ + public function getSize() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSize(); + } + return $this->_size; + } + + /** + * Set Size + * + * @param double $pValue + * @return PHPExcel_Style_Font + */ + public function setSize($pValue = 10) { + if ($pValue == '') { + $pValue = 10; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('size' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_size = $pValue; + } + return $this; + } + + /** + * Get Bold + * + * @return boolean + */ + public function getBold() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBold(); + } + return $this->_bold; + } + + /** + * Set Bold + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setBold($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('bold' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_bold = $pValue; + } + return $this; + } + + /** + * Get Italic + * + * @return boolean + */ + public function getItalic() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getItalic(); + } + return $this->_italic; + } + + /** + * Set Italic + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setItalic($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('italic' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_italic = $pValue; + } + return $this; + } + + /** + * Get SuperScript + * + * @return boolean + */ + public function getSuperScript() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSuperScript(); + } + return $this->_superScript; + } + + /** + * Set SuperScript + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setSuperScript($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('superScript' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_superScript = $pValue; + $this->_subScript = !$pValue; + } + return $this; + } + + /** + * Get SubScript + * + * @return boolean + */ + public function getSubScript() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getSubScript(); + } + return $this->_subScript; + } + + /** + * Set SubScript + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setSubScript($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('subScript' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_subScript = $pValue; + $this->_superScript = !$pValue; + } + return $this; + } + + /** + * Get Underline + * + * @return string + */ + public function getUnderline() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getUnderline(); + } + return $this->_underline; + } + + /** + * Set Underline + * + * @param string|boolean $pValue PHPExcel_Style_Font underline type + * If a boolean is passed, then TRUE equates to UNDERLINE_SINGLE, + * false equates to UNDERLINE_NONE + * @return PHPExcel_Style_Font + */ + public function setUnderline($pValue = self::UNDERLINE_NONE) { + if (is_bool($pValue)) { + $pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE; + } elseif ($pValue == '') { + $pValue = self::UNDERLINE_NONE; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('underline' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_underline = $pValue; + } + return $this; + } + + /** + * Get Strikethrough + * + * @return boolean + */ + public function getStrikethrough() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getStrikethrough(); + } + return $this->_strikethrough; + } + + /** + * Set Strikethrough + * + * @param boolean $pValue + * @return PHPExcel_Style_Font + */ + public function setStrikethrough($pValue = false) { + if ($pValue == '') { + $pValue = false; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('strike' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_strikethrough = $pValue; + } + return $this; + } + + /** + * Get Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Font + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + // make sure parameter is a real color and not a supervisor + $color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; + + if ($this->_isSupervisor) { + $styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB())); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_color = $color; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_name + . $this->_size + . ($this->_bold ? 't' : 'f') + . ($this->_italic ? 't' : 'f') + . ($this->_superScript ? 't' : 'f') + . ($this->_subScript ? 't' : 'f') + . $this->_underline + . ($this->_strikethrough ? 't' : 'f') + . $this->_color->getHashCode() + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/NumberFormat.php b/extend/phpexcel/PHPExcel/Style/NumberFormat.php new file mode 100755 index 0000000..e8a978f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/NumberFormat.php @@ -0,0 +1,711 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_NumberFormat + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /* Pre-defined formats */ + const FORMAT_GENERAL = 'General'; + + const FORMAT_TEXT = '@'; + + const FORMAT_NUMBER = '0'; + const FORMAT_NUMBER_00 = '0.00'; + const FORMAT_NUMBER_COMMA_SEPARATED1 = '#,##0.00'; + const FORMAT_NUMBER_COMMA_SEPARATED2 = '#,##0.00_-'; + + const FORMAT_PERCENTAGE = '0%'; + const FORMAT_PERCENTAGE_00 = '0.00%'; + + const FORMAT_DATE_YYYYMMDD2 = 'yyyy-mm-dd'; + const FORMAT_DATE_YYYYMMDD = 'yy-mm-dd'; + const FORMAT_DATE_DDMMYYYY = 'dd/mm/yy'; + const FORMAT_DATE_DMYSLASH = 'd/m/y'; + const FORMAT_DATE_DMYMINUS = 'd-m-y'; + const FORMAT_DATE_DMMINUS = 'd-m'; + const FORMAT_DATE_MYMINUS = 'm-y'; + const FORMAT_DATE_XLSX14 = 'mm-dd-yy'; + const FORMAT_DATE_XLSX15 = 'd-mmm-yy'; + const FORMAT_DATE_XLSX16 = 'd-mmm'; + const FORMAT_DATE_XLSX17 = 'mmm-yy'; + const FORMAT_DATE_XLSX22 = 'm/d/yy h:mm'; + const FORMAT_DATE_DATETIME = 'd/m/y h:mm'; + const FORMAT_DATE_TIME1 = 'h:mm AM/PM'; + const FORMAT_DATE_TIME2 = 'h:mm:ss AM/PM'; + const FORMAT_DATE_TIME3 = 'h:mm'; + const FORMAT_DATE_TIME4 = 'h:mm:ss'; + const FORMAT_DATE_TIME5 = 'mm:ss'; + const FORMAT_DATE_TIME6 = 'h:mm:ss'; + const FORMAT_DATE_TIME7 = 'i:s.S'; + const FORMAT_DATE_TIME8 = 'h:mm:ss;@'; + const FORMAT_DATE_YYYYMMDDSLASH = 'yy/mm/dd;@'; + + const FORMAT_CURRENCY_USD_SIMPLE = '"$"#,##0.00_-'; + const FORMAT_CURRENCY_USD = '$#,##0_-'; + const FORMAT_CURRENCY_EUR_SIMPLE = '[$EUR ]#,##0.00_-'; + + /** + * Excel built-in number formats + * + * @var array + */ + protected static $_builtInFormats; + + /** + * Excel built-in number formats (flipped, for faster lookups) + * + * @var array + */ + protected static $_flippedBuiltInFormats; + + /** + * Format Code + * + * @var string + */ + protected $_formatCode = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + + /** + * Built-in format Code + * + * @var string + */ + protected $_builtInFormatCode = 0; + + /** + * Create a new PHPExcel_Style_NumberFormat + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + if ($isConditional) { + $this->_formatCode = NULL; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_NumberFormat + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getNumberFormat(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('numberformat' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray( + * array( + * 'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_NumberFormat + */ + public function applyFromArray($pStyles = null) + { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (array_key_exists('code', $pStyles)) { + $this->setFormatCode($pStyles['code']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get Format Code + * + * @return string + */ + public function getFormatCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getFormatCode(); + } + if ($this->_builtInFormatCode !== false) + { + return self::builtInFormatCode($this->_builtInFormatCode); + } + return $this->_formatCode; + } + + /** + * Set Format Code + * + * @param string $pValue + * @return PHPExcel_Style_NumberFormat + */ + public function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL) + { + if ($pValue == '') { + $pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + } + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('code' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_formatCode = $pValue; + $this->_builtInFormatCode = self::builtInFormatCodeIndex($pValue); + } + return $this; + } + + /** + * Get Built-In Format Code + * + * @return int + */ + public function getBuiltInFormatCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getBuiltInFormatCode(); + } + return $this->_builtInFormatCode; + } + + /** + * Set Built-In Format Code + * + * @param int $pValue + * @return PHPExcel_Style_NumberFormat + */ + public function setBuiltInFormatCode($pValue = 0) + { + + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue))); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_builtInFormatCode = $pValue; + $this->_formatCode = self::builtInFormatCode($pValue); + } + return $this; + } + + /** + * Fill built-in format codes + */ + private static function fillBuiltInFormatCodes() + { + // Built-in format codes + if (is_null(self::$_builtInFormats)) { + self::$_builtInFormats = array(); + + // General + self::$_builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL; + self::$_builtInFormats[1] = '0'; + self::$_builtInFormats[2] = '0.00'; + self::$_builtInFormats[3] = '#,##0'; + self::$_builtInFormats[4] = '#,##0.00'; + + self::$_builtInFormats[9] = '0%'; + self::$_builtInFormats[10] = '0.00%'; + self::$_builtInFormats[11] = '0.00E+00'; + self::$_builtInFormats[12] = '# ?/?'; + self::$_builtInFormats[13] = '# ??/??'; + self::$_builtInFormats[14] = 'mm-dd-yy'; + self::$_builtInFormats[15] = 'd-mmm-yy'; + self::$_builtInFormats[16] = 'd-mmm'; + self::$_builtInFormats[17] = 'mmm-yy'; + self::$_builtInFormats[18] = 'h:mm AM/PM'; + self::$_builtInFormats[19] = 'h:mm:ss AM/PM'; + self::$_builtInFormats[20] = 'h:mm'; + self::$_builtInFormats[21] = 'h:mm:ss'; + self::$_builtInFormats[22] = 'm/d/yy h:mm'; + + self::$_builtInFormats[37] = '#,##0 ;(#,##0)'; + self::$_builtInFormats[38] = '#,##0 ;[Red](#,##0)'; + self::$_builtInFormats[39] = '#,##0.00;(#,##0.00)'; + self::$_builtInFormats[40] = '#,##0.00;[Red](#,##0.00)'; + + self::$_builtInFormats[44] = '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)'; + self::$_builtInFormats[45] = 'mm:ss'; + self::$_builtInFormats[46] = '[h]:mm:ss'; + self::$_builtInFormats[47] = 'mmss.0'; + self::$_builtInFormats[48] = '##0.0E+0'; + self::$_builtInFormats[49] = '@'; + + // CHT + self::$_builtInFormats[27] = '[$-404]e/m/d'; + self::$_builtInFormats[30] = 'm/d/yy'; + self::$_builtInFormats[36] = '[$-404]e/m/d'; + self::$_builtInFormats[50] = '[$-404]e/m/d'; + self::$_builtInFormats[57] = '[$-404]e/m/d'; + + // THA + self::$_builtInFormats[59] = 't0'; + self::$_builtInFormats[60] = 't0.00'; + self::$_builtInFormats[61] = 't#,##0'; + self::$_builtInFormats[62] = 't#,##0.00'; + self::$_builtInFormats[67] = 't0%'; + self::$_builtInFormats[68] = 't0.00%'; + self::$_builtInFormats[69] = 't# ?/?'; + self::$_builtInFormats[70] = 't# ??/??'; + + // Flip array (for faster lookups) + self::$_flippedBuiltInFormats = array_flip(self::$_builtInFormats); + } + } + + /** + * Get built-in format code + * + * @param int $pIndex + * @return string + */ + public static function builtInFormatCode($pIndex) + { + // Clean parameter + $pIndex = intval($pIndex); + + // Ensure built-in format codes are available + self::fillBuiltInFormatCodes(); + + // Lookup format code + if (isset(self::$_builtInFormats[$pIndex])) { + return self::$_builtInFormats[$pIndex]; + } + + return ''; + } + + /** + * Get built-in format code index + * + * @param string $formatCode + * @return int|boolean + */ + public static function builtInFormatCodeIndex($formatCode) + { + // Ensure built-in format codes are available + self::fillBuiltInFormatCodes(); + + // Lookup format code + if (isset(self::$_flippedBuiltInFormats[$formatCode])) { + return self::$_flippedBuiltInFormats[$formatCode]; + } + + return false; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() + { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_formatCode + . $this->_builtInFormatCode + . __CLASS__ + ); + } + + /** + * Search/replace values to convert Excel date/time format masks to PHP format masks + * + * @var array + */ + private static $_dateFormatReplacements = array( + // first remove escapes related to non-format characters + '\\' => '', + // 12-hour suffix + 'am/pm' => 'A', + // 4-digit year + 'e' => 'Y', + 'yyyy' => 'Y', + // 2-digit year + 'yy' => 'y', + // first letter of month - no php equivalent + 'mmmmm' => 'M', + // full month name + 'mmmm' => 'F', + // short month name + 'mmm' => 'M', + // mm is minutes if time, but can also be month w/leading zero + // so we try to identify times be the inclusion of a : separator in the mask + // It isn't perfect, but the best way I know how + ':mm' => ':i', + 'mm:' => 'i:', + // month leading zero + 'mm' => 'm', + // month no leading zero + 'm' => 'n', + // full day of week name + 'dddd' => 'l', + // short day of week name + 'ddd' => 'D', + // days leading zero + 'dd' => 'd', + // days no leading zero + 'd' => 'j', + // seconds + 'ss' => 's', + // fractional seconds - no php equivalent + '.s' => '' + ); + /** + * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock) + * + * @var array + */ + private static $_dateFormatReplacements24 = array( + 'hh' => 'H', + 'h' => 'G' + ); + /** + * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock) + * + * @var array + */ + private static $_dateFormatReplacements12 = array( + 'hh' => 'h', + 'h' => 'g' + ); + + private static function _formatAsDate(&$value, &$format) + { + // dvc: convert Excel formats to PHP date formats + + // strip off first part containing e.g. [$-F800] or [$USD-409] + // general syntax: [$<Currency string>-<language info>] + // language info is in hexadecimal + $format = preg_replace('/^(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format); + + // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case + $format = strtolower($format); + + $format = strtr($format,self::$_dateFormatReplacements); + if (!strpos($format,'A')) { // 24-hour time format + $format = strtr($format,self::$_dateFormatReplacements24); + } else { // 12-hour time format + $format = strtr($format,self::$_dateFormatReplacements12); + } + + $dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value); + $value = $dateObj->format($format); + } + + private static function _formatAsPercentage(&$value, &$format) + { + if ($format === self::FORMAT_PERCENTAGE) { + $value = round( (100 * $value), 0) . '%'; + } else { + if (preg_match('/\.[#0]+/i', $format, $m)) { + $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1); + $format = str_replace($m[0], $s, $format); + } + if (preg_match('/^[#0]+/', $format, $m)) { + $format = str_replace($m[0], strlen($m[0]), $format); + } + $format = '%' . str_replace('%', 'f%%', $format); + + $value = sprintf($format, 100 * $value); + } + } + + private static function _formatAsFraction(&$value, &$format) + { + $sign = ($value < 0) ? '-' : ''; + + $integerPart = floor(abs($value)); + $decimalPart = trim(fmod(abs($value),1),'0.'); + $decimalLength = strlen($decimalPart); + $decimalDivisor = pow(10,$decimalLength); + + $GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor); + + $adjustedDecimalPart = $decimalPart/$GCD; + $adjustedDecimalDivisor = $decimalDivisor/$GCD; + + if ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) { + if ($integerPart == 0) { + $integerPart = ''; + } + $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor"; + } else { + $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor; + $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor"; + } + } + + private static function _complexNumberFormatMask($number, $mask) { + if (strpos($mask,'.') !== false) { + $numbers = explode('.', $number . '.0'); + $masks = explode('.', $mask . '.0'); + $result1 = self::_complexNumberFormatMask($numbers[0], $masks[0]); + $result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]))); + return $result1 . '.' . $result2; + } + + $r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE); + if ($r > 1) { + $result = array_reverse($result[0]); + + foreach($result as $block) { + $divisor = 1 . $block[0]; + $size = strlen($block[0]); + $offset = $block[1]; + + $blockValue = sprintf( + '%0' . $size . 'd', + fmod($number, $divisor) + ); + $number = floor($number / $divisor); + $mask = substr_replace($mask,$blockValue, $offset, $size); + } + if ($number > 0) { + $mask = substr_replace($mask, $number, $offset, 0); + } + $result = $mask; + } else { + $result = $number; + } + + return $result; + } + + /** + * Convert a value in a pre-defined format to a PHP string + * + * @param mixed $value Value to format + * @param string $format Format code + * @param array $callBack Callback function for additional formatting of string + * @return string Formatted string + */ + public static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null) + { + // For now we do not treat strings although section 4 of a format code affects strings + if (!is_numeric($value)) return $value; + + // For 'General' format code, we just pass the value although this is not entirely the way Excel does it, + // it seems to round numbers to a total of 10 digits. + if (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) { + return $value; + } + + // Get the sections, there can be up to four sections + $sections = explode(';', $format); + + // Fetch the relevant section depending on whether number is positive, negative, or zero? + // Text not supported yet. + // Here is how the sections apply to various values in Excel: + // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT] + // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE] + // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO] + // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT] + switch (count($sections)) { + case 1: + $format = $sections[0]; + break; + + case 2: + $format = ($value >= 0) ? $sections[0] : $sections[1]; + $value = abs($value); // Use the absolute value + break; + + case 3: + $format = ($value > 0) ? + $sections[0] : ( ($value < 0) ? + $sections[1] : $sections[2]); + $value = abs($value); // Use the absolute value + break; + + case 4: + $format = ($value > 0) ? + $sections[0] : ( ($value < 0) ? + $sections[1] : $sections[2]); + $value = abs($value); // Use the absolute value + break; + + default: + // something is wrong, just use first section + $format = $sections[0]; + break; + } + + // Save format with color information for later use below + $formatColor = $format; + + // Strip color information + $color_regex = '/^\\[[a-zA-Z]+\\]/'; + $format = preg_replace($color_regex, '', $format); + + // Let's begin inspecting the format and converting the value to a formatted string + if (preg_match('/^(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy]/i', $format)) { // datetime format + self::_formatAsDate($value, $format); + } else if (preg_match('/%$/', $format)) { // % number format + self::_formatAsPercentage($value, $format); + } else { + if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) { + $value = 'EUR ' . sprintf('%1.2f', $value); + } else { + // In Excel formats, "_" is used to add spacing, which we can't do in HTML + $format = preg_replace('/_./', '', $format); + + // Some non-number characters are escaped with \, which we don't need + $format = preg_replace("/\\\\/", '', $format); + + // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols + $format = str_replace(array('"','*'), '', $format); + + // Find out if we need thousands separator + // This is indicated by a comma enclosed by a digit placeholder: + // #,# or 0,0 + $useThousands = preg_match('/(#,#|0,0)/', $format); + if ($useThousands) { + $format = preg_replace('/0,0/', '00', $format); + $format = preg_replace('/#,#/', '##', $format); + } + + // Scale thousands, millions,... + // This is indicated by a number of commas after a digit placeholder: + // #, or 0.0,, + $scale = 1; // same as no scale + $matches = array(); + if (preg_match('/(#|0)(,+)/', $format, $matches)) { + $scale = pow(1000, strlen($matches[2])); + + // strip the commas + $format = preg_replace('/0,+/', '0', $format); + $format = preg_replace('/#,+/', '#', $format); + } + + if (preg_match('/#?.*\?\/\?/', $format, $m)) { + //echo 'Format mask is fractional '.$format.' <br />'; + if ($value != (int)$value) { + self::_formatAsFraction($value, $format); + } + + } else { + // Handle the number itself + + // scale number + $value = $value / $scale; + + // Strip # + $format = preg_replace('/\\#/', '0', $format); + + $n = "/\[[^\]]+\]/"; + $m = preg_replace($n, '', $format); + $number_regex = "/(0+)(\.?)(0*)/"; + if (preg_match($number_regex, $m, $matches)) { + $left = $matches[1]; + $dec = $matches[2]; + $right = $matches[3]; + + // minimun width of formatted number (including dot) + $minWidth = strlen($left) + strlen($dec) + strlen($right); + if ($useThousands) { + $value = number_format( + $value + , strlen($right) + , PHPExcel_Shared_String::getDecimalSeparator() + , PHPExcel_Shared_String::getThousandsSeparator() + ); + $value = preg_replace($number_regex, $value, $format); + } else { + if (preg_match('/[0#]E[+-]0/i', $format)) { + // Scientific format + $value = sprintf('%5.2E', $value); + } elseif (preg_match('/0([^\d\.]+)0/', $format)) { + $value = self::_complexNumberFormatMask($value, $format); + } else { + $sprintf_pattern = "%0$minWidth." . strlen($right) . "f"; + $value = sprintf($sprintf_pattern, $value); + $value = preg_replace($number_regex, $value, $format); + } + } + } + } + if (preg_match('/\[\$(.*)\]/u', $format, $m)) { + // Currency or Accounting + $currencyFormat = $m[0]; + $currencyCode = $m[1]; + list($currencyCode) = explode('-',$currencyCode); + if ($currencyCode == '') { + $currencyCode = PHPExcel_Shared_String::getCurrencyCode(); + } + $value = preg_replace('/\[\$([^\]]*)\]/u',$currencyCode,$value); + } + } + } + + // Additional formatting provided by callback function + if ($callBack !== null) { + list($writerInstance, $function) = $callBack; + $value = $writerInstance->$function($value, $formatColor); + } + + return $value; + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Protection.php b/extend/phpexcel/PHPExcel/Style/Protection.php new file mode 100755 index 0000000..8dc1f31 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Protection.php @@ -0,0 +1,207 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.4.5, 2007-08-23 + */ + + +/** + * PHPExcel_Style_Protection + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable +{ + /** Protection styles */ + const PROTECTION_INHERIT = 'inherit'; + const PROTECTION_PROTECTED = 'protected'; + const PROTECTION_UNPROTECTED = 'unprotected'; + + /** + * Locked + * + * @var string + */ + protected $_locked; + + /** + * Hidden + * + * @var string + */ + protected $_hidden; + + /** + * Create a new PHPExcel_Style_Protection + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + * @param boolean $isConditional Flag indicating if this is a conditional style or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE, $isConditional = FALSE) + { + // Supervisor? + parent::__construct($isSupervisor); + + // Initialise values + if (!$isConditional) { + $this->_locked = self::PROTECTION_INHERIT; + $this->_hidden = self::PROTECTION_INHERIT; + } + } + + /** + * Get the shared style component for the currently active cell in currently active sheet. + * Only used for style supervisor + * + * @return PHPExcel_Style_Protection + */ + public function getSharedComponent() + { + return $this->_parent->getSharedComponent()->getProtection(); + } + + /** + * Build style array from subcomponents + * + * @param array $array + * @return array + */ + public function getStyleArray($array) + { + return array('protection' => $array); + } + + /** + * Apply styles from array + * + * <code> + * $objPHPExcel->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray( + * array( + * 'locked' => TRUE, + * 'hidden' => FALSE + * ) + * ); + * </code> + * + * @param array $pStyles Array containing style information + * @throws PHPExcel_Exception + * @return PHPExcel_Style_Protection + */ + public function applyFromArray($pStyles = NULL) { + if (is_array($pStyles)) { + if ($this->_isSupervisor) { + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); + } else { + if (isset($pStyles['locked'])) { + $this->setLocked($pStyles['locked']); + } + if (isset($pStyles['hidden'])) { + $this->setHidden($pStyles['hidden']); + } + } + } else { + throw new PHPExcel_Exception("Invalid style array passed."); + } + return $this; + } + + /** + * Get locked + * + * @return string + */ + public function getLocked() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getLocked(); + } + return $this->_locked; + } + + /** + * Set locked + * + * @param string $pValue + * @return PHPExcel_Style_Protection + */ + public function setLocked($pValue = self::PROTECTION_INHERIT) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('locked' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_locked = $pValue; + } + return $this; + } + + /** + * Get hidden + * + * @return string + */ + public function getHidden() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHidden(); + } + return $this->_hidden; + } + + /** + * Set hidden + * + * @param string $pValue + * @return PHPExcel_Style_Protection + */ + public function setHidden($pValue = self::PROTECTION_INHERIT) { + if ($this->_isSupervisor) { + $styleArray = $this->getStyleArray(array('hidden' => $pValue)); + $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); + } else { + $this->_hidden = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_isSupervisor) { + return $this->getSharedComponent()->getHashCode(); + } + return md5( + $this->_locked + . $this->_hidden + . __CLASS__ + ); + } + +} diff --git a/extend/phpexcel/PHPExcel/Style/Supervisor.php b/extend/phpexcel/PHPExcel/Style/Supervisor.php new file mode 100755 index 0000000..c2ce9c0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Style/Supervisor.php @@ -0,0 +1,132 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Style_Supervisor + * + * @category PHPExcel + * @package PHPExcel_Style + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Style_Supervisor +{ + /** + * Supervisor? + * + * @var boolean + */ + protected $_isSupervisor; + + /** + * Parent. Only used for supervisor + * + * @var PHPExcel_Style + */ + protected $_parent; + + /** + * Create a new PHPExcel_Style_Alignment + * + * @param boolean $isSupervisor Flag indicating if this is a supervisor or not + * Leave this value at default unless you understand exactly what + * its ramifications are + */ + public function __construct($isSupervisor = FALSE) + { + // Supervisor? + $this->_isSupervisor = $isSupervisor; + } + + /** + * Bind parent. Only used for supervisor + * + * @param PHPExcel $parent + * @return PHPExcel_Style_Supervisor + */ + public function bindParent($parent, $parentPropertyName=NULL) + { + $this->_parent = $parent; + return $this; + } + + /** + * Is this a supervisor or a cell style component? + * + * @return boolean + */ + public function getIsSupervisor() + { + return $this->_isSupervisor; + } + + /** + * Get the currently active sheet. Only used for supervisor + * + * @return PHPExcel_Worksheet + */ + public function getActiveSheet() + { + return $this->_parent->getActiveSheet(); + } + + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getSelectedCells() + { + return $this->getActiveSheet()->getSelectedCells(); + } + + /** + * Get the currently active cell coordinate in currently active sheet. + * Only used for supervisor + * + * @return string E.g. 'A1' + */ + public function getActiveCell() + { + return $this->getActiveSheet()->getActiveCell(); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if ((is_object($value)) && ($key != '_parent')) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet.php b/extend/phpexcel/PHPExcel/Worksheet.php new file mode 100755 index 0000000..682ad98 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet.php @@ -0,0 +1,2909 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet implements PHPExcel_IComparable +{ + /* Break types */ + const BREAK_NONE = 0; + const BREAK_ROW = 1; + const BREAK_COLUMN = 2; + + /* Sheet state */ + const SHEETSTATE_VISIBLE = 'visible'; + const SHEETSTATE_HIDDEN = 'hidden'; + const SHEETSTATE_VERYHIDDEN = 'veryHidden'; + + /** + * Invalid characters in sheet title + * + * @var array + */ + private static $_invalidCharacters = array('*', ':', '/', '\\', '?', '[', ']'); + + /** + * Parent spreadsheet + * + * @var PHPExcel + */ + private $_parent; + + /** + * Cacheable collection of cells + * + * @var PHPExcel_CachedObjectStorage_xxx + */ + private $_cellCollection = null; + + /** + * Collection of row dimensions + * + * @var PHPExcel_Worksheet_RowDimension[] + */ + private $_rowDimensions = array(); + + /** + * Default row dimension + * + * @var PHPExcel_Worksheet_RowDimension + */ + private $_defaultRowDimension = null; + + /** + * Collection of column dimensions + * + * @var PHPExcel_Worksheet_ColumnDimension[] + */ + private $_columnDimensions = array(); + + /** + * Default column dimension + * + * @var PHPExcel_Worksheet_ColumnDimension + */ + private $_defaultColumnDimension = null; + + /** + * Collection of drawings + * + * @var PHPExcel_Worksheet_BaseDrawing[] + */ + private $_drawingCollection = null; + + /** + * Collection of Chart objects + * + * @var PHPExcel_Chart[] + */ + private $_chartCollection = array(); + + /** + * Worksheet title + * + * @var string + */ + private $_title; + + /** + * Sheet state + * + * @var string + */ + private $_sheetState; + + /** + * Page setup + * + * @var PHPExcel_Worksheet_PageSetup + */ + private $_pageSetup; + + /** + * Page margins + * + * @var PHPExcel_Worksheet_PageMargins + */ + private $_pageMargins; + + /** + * Page header/footer + * + * @var PHPExcel_Worksheet_HeaderFooter + */ + private $_headerFooter; + + /** + * Sheet view + * + * @var PHPExcel_Worksheet_SheetView + */ + private $_sheetView; + + /** + * Protection + * + * @var PHPExcel_Worksheet_Protection + */ + private $_protection; + + /** + * Collection of styles + * + * @var PHPExcel_Style[] + */ + private $_styles = array(); + + /** + * Conditional styles. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_conditionalStylesCollection = array(); + + /** + * Is the current cell collection sorted already? + * + * @var boolean + */ + private $_cellCollectionIsSorted = false; + + /** + * Collection of breaks + * + * @var array + */ + private $_breaks = array(); + + /** + * Collection of merged cell ranges + * + * @var array + */ + private $_mergeCells = array(); + + /** + * Collection of protected cell ranges + * + * @var array + */ + private $_protectedCells = array(); + + /** + * Autofilter Range and selection + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_autoFilter = NULL; + + /** + * Freeze pane + * + * @var string + */ + private $_freezePane = ''; + + /** + * Show gridlines? + * + * @var boolean + */ + private $_showGridlines = true; + + /** + * Print gridlines? + * + * @var boolean + */ + private $_printGridlines = false; + + /** + * Show row and column headers? + * + * @var boolean + */ + private $_showRowColHeaders = true; + + /** + * Show summary below? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryBelow = true; + + /** + * Show summary right? (Row/Column outline) + * + * @var boolean + */ + private $_showSummaryRight = true; + + /** + * Collection of comments + * + * @var PHPExcel_Comment[] + */ + private $_comments = array(); + + /** + * Active cell. (Only one!) + * + * @var string + */ + private $_activeCell = 'A1'; + + /** + * Selected cells + * + * @var string + */ + private $_selectedCells = 'A1'; + + /** + * Cached highest column + * + * @var string + */ + private $_cachedHighestColumn = 'A'; + + /** + * Cached highest row + * + * @var int + */ + private $_cachedHighestRow = 1; + + /** + * Right-to-left? + * + * @var boolean + */ + private $_rightToLeft = false; + + /** + * Hyperlinks. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_hyperlinkCollection = array(); + + /** + * Data validation objects. Indexed by cell coordinate, e.g. 'A1' + * + * @var array + */ + private $_dataValidationCollection = array(); + + /** + * Tab color + * + * @var PHPExcel_Style_Color + */ + private $_tabColor; + + /** + * Dirty flag + * + * @var boolean + */ + private $_dirty = true; + + /** + * Hash + * + * @var string + */ + private $_hash = null; + + /** + * CodeName + * + * @var string + */ + private $_codeName = null; + + /** + * Create a new worksheet + * + * @param PHPExcel $pParent + * @param string $pTitle + */ + public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet') + { + // Set parent and title + $this->_parent = $pParent; + $this->setTitle($pTitle, FALSE); + // setTitle can change $pTitle + $this->setCodeName($this->getTitle()); + $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE); + + $this->_cellCollection = PHPExcel_CachedObjectStorageFactory::getInstance($this); + + // Set page setup + $this->_pageSetup = new PHPExcel_Worksheet_PageSetup(); + + // Set page margins + $this->_pageMargins = new PHPExcel_Worksheet_PageMargins(); + + // Set page header/footer + $this->_headerFooter = new PHPExcel_Worksheet_HeaderFooter(); + + // Set sheet view + $this->_sheetView = new PHPExcel_Worksheet_SheetView(); + + // Drawing collection + $this->_drawingCollection = new ArrayObject(); + + // Chart collection + $this->_chartCollection = new ArrayObject(); + + // Protection + $this->_protection = new PHPExcel_Worksheet_Protection(); + + // Default row dimension + $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL); + + // Default column dimension + $this->_defaultColumnDimension = new PHPExcel_Worksheet_ColumnDimension(NULL); + + $this->_autoFilter = new PHPExcel_Worksheet_AutoFilter(NULL, $this); + } + + + /** + * Disconnect all cells from this PHPExcel_Worksheet object, + * typically so that the worksheet object can be unset + * + */ + public function disconnectCells() { + if ( $this->_cellCollection !== NULL){ + $this->_cellCollection->unsetWorksheetCells(); + $this->_cellCollection = NULL; + } + // detach ourself from the workbook, so that it can then delete this worksheet successfully + $this->_parent = null; + } + + /** + * Code to execute when this worksheet is unset() + * + */ + function __destruct() { + PHPExcel_Calculation::getInstance($this->_parent) + ->clearCalculationCacheForWorksheet($this->_title); + + $this->disconnectCells(); + } + + /** + * Return the cache controller for the cell collection + * + * @return PHPExcel_CachedObjectStorage_xxx + */ + public function getCellCacheController() { + return $this->_cellCollection; + } // function getCellCacheController() + + + /** + * Get array of invalid characters for sheet title + * + * @return array + */ + public static function getInvalidCharacters() + { + return self::$_invalidCharacters; + } + + /** + * Check sheet code name for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws Exception + */ + private static function _checkSheetCodeName($pValue) + { + $CharCount = PHPExcel_Shared_String::CountCharacters($pValue); + if ($CharCount == 0) { + throw new PHPExcel_Exception('Sheet code name cannot be empty.'); + } + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] and first and last characters cannot be a "'" + if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || + (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\'') || + (PHPExcel_Shared_String::Substring($pValue,0,1)=='\'')) { + throw new PHPExcel_Exception('Invalid character found in sheet code name'); + } + + // Maximum 31 characters allowed for sheet title + if ($CharCount > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.'); + } + + return $pValue; + } + + /** + * Check sheet title for valid Excel syntax + * + * @param string $pValue The string to check + * @return string The valid string + * @throws PHPExcel_Exception + */ + private static function _checkSheetTitle($pValue) + { + // Some of the printable ASCII characters are invalid: * : / \ ? [ ] + if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) { + throw new PHPExcel_Exception('Invalid character found in sheet title'); + } + + // Maximum 31 characters allowed for sheet title + if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) { + throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.'); + } + + return $pValue; + } + + /** + * Get collection of cells + * + * @param boolean $pSorted Also sort the cell collection? + * @return PHPExcel_Cell[] + */ + public function getCellCollection($pSorted = true) + { + if ($pSorted) { + // Re-order cell collection + return $this->sortCellCollection(); + } + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getCellList(); + } + return array(); + } + + /** + * Sort collection of cells + * + * @return PHPExcel_Worksheet + */ + public function sortCellCollection() + { + if ($this->_cellCollection !== NULL) { + return $this->_cellCollection->getSortedCellList(); + } + return array(); + } + + /** + * Get collection of row dimensions + * + * @return PHPExcel_Worksheet_RowDimension[] + */ + public function getRowDimensions() + { + return $this->_rowDimensions; + } + + /** + * Get default row dimension + * + * @return PHPExcel_Worksheet_RowDimension + */ + public function getDefaultRowDimension() + { + return $this->_defaultRowDimension; + } + + /** + * Get collection of column dimensions + * + * @return PHPExcel_Worksheet_ColumnDimension[] + */ + public function getColumnDimensions() + { + return $this->_columnDimensions; + } + + /** + * Get default column dimension + * + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getDefaultColumnDimension() + { + return $this->_defaultColumnDimension; + } + + /** + * Get collection of drawings + * + * @return PHPExcel_Worksheet_BaseDrawing[] + */ + public function getDrawingCollection() + { + return $this->_drawingCollection; + } + + /** + * Get collection of charts + * + * @return PHPExcel_Chart[] + */ + public function getChartCollection() + { + return $this->_chartCollection; + } + + /** + * Add chart + * + * @param PHPExcel_Chart $pChart + * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last) + * @return PHPExcel_Chart + */ + public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null) + { + $pChart->setWorksheet($this); + if (is_null($iChartIndex)) { + $this->_chartCollection[] = $pChart; + } else { + // Insert the chart at the requested index + array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart)); + } + + return $pChart; + } + + /** + * Return the count of charts on this worksheet + * + * @return int The number of charts + */ + public function getChartCount() + { + return count($this->_chartCollection); + } + + /** + * Get a chart by its index position + * + * @param string $index Chart index position + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByIndex($index = null) + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + if (is_null($index)) { + $index = --$chartCount; + } + if (!isset($this->_chartCollection[$index])) { + return false; + } + + return $this->_chartCollection[$index]; + } + + /** + * Return an array of the names of charts on this worksheet + * + * @return string[] The names of charts + * @throws PHPExcel_Exception + */ + public function getChartNames() + { + $chartNames = array(); + foreach($this->_chartCollection as $chart) { + $chartNames[] = $chart->getName(); + } + return $chartNames; + } + + /** + * Get a chart by name + * + * @param string $chartName Chart name + * @return false|PHPExcel_Chart + * @throws PHPExcel_Exception + */ + public function getChartByName($chartName = '') + { + $chartCount = count($this->_chartCollection); + if ($chartCount == 0) { + return false; + } + foreach($this->_chartCollection as $index => $chart) { + if ($chart->getName() == $chartName) { + return $this->_chartCollection[$index]; + } + } + return false; + } + + /** + * Refresh column dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshColumnDimensions() + { + $currentColumnDimensions = $this->getColumnDimensions(); + $newColumnDimensions = array(); + + foreach ($currentColumnDimensions as $objColumnDimension) { + $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension; + } + + $this->_columnDimensions = $newColumnDimensions; + + return $this; + } + + /** + * Refresh row dimensions + * + * @return PHPExcel_Worksheet + */ + public function refreshRowDimensions() + { + $currentRowDimensions = $this->getRowDimensions(); + $newRowDimensions = array(); + + foreach ($currentRowDimensions as $objRowDimension) { + $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension; + } + + $this->_rowDimensions = $newRowDimensions; + + return $this; + } + + /** + * Calculate worksheet dimension + * + * @return string String containing the dimension of this worksheet + */ + public function calculateWorksheetDimension() + { + // Return + return 'A1' . ':' . $this->getHighestColumn() . $this->getHighestRow(); + } + + /** + * Calculate worksheet data dimension + * + * @return string String containing the dimension of this worksheet that actually contain data + */ + public function calculateWorksheetDataDimension() + { + // Return + return 'A1' . ':' . $this->getHighestDataColumn() . $this->getHighestDataRow(); + } + + /** + * Calculate widths for auto-size columns + * + * @param boolean $calculateMergeCells Calculate merge cell width + * @return PHPExcel_Worksheet; + */ + public function calculateColumnWidths($calculateMergeCells = false) + { + // initialize $autoSizes array + $autoSizes = array(); + foreach ($this->getColumnDimensions() as $colDimension) { + if ($colDimension->getAutoSize()) { + $autoSizes[$colDimension->getColumnIndex()] = -1; + } + } + + // There is only something to do if there are some auto-size columns + if (!empty($autoSizes)) { + + // build list of cells references that participate in a merge + $isMergeCell = array(); + foreach ($this->getMergeCells() as $cells) { + foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) { + $isMergeCell[$cellReference] = true; + } + } + + // loop through all cells in the worksheet + foreach ($this->getCellCollection(false) as $cellID) { + $cell = $this->getCell($cellID); + if (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) { + // Determine width if cell does not participate in a merge + if (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) { + // Calculated value + // To formatted string + $cellValue = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode() + ); + + $autoSizes[$this->_cellCollection->getCurrentColumn()] = max( + (float) $autoSizes[$this->_cellCollection->getCurrentColumn()], + (float)PHPExcel_Shared_Font::calculateColumnWidth( + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(), + $cellValue, + $this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(), + $this->getDefaultStyle()->getFont() + ) + ); + } + } + } + + // adjust column widths + foreach ($autoSizes as $columnIndex => $width) { + if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth(); + $this->getColumnDimension($columnIndex)->setWidth($width); + } + } + + return $this; + } + + /** + * Get parent + * + * @return PHPExcel + */ + public function getParent() { + return $this->_parent; + } + + /** + * Re-bind parent + * + * @param PHPExcel $parent + * @return PHPExcel_Worksheet + */ + public function rebindParent(PHPExcel $parent) { + if ($this->_parent !== null) { + $namedRanges = $this->_parent->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $parent->addNamedRange($namedRange); + } + + $this->_parent->removeSheetByIndex( + $this->_parent->getIndex($this) + ); + } + $this->_parent = $parent; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Set title + * + * @param string $pValue String containing the dimension of this worksheet + * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should + * be updated to reflect the new sheet name. + * This should be left as the default true, unless you are + * certain that no formula cells on any worksheet contain + * references to this worksheet + * @return PHPExcel_Worksheet + */ + public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true) + { + // Is this a 'rename' or not? + if ($this->getTitle() == $pValue) { + return $this; + } + + // Syntax check + self::_checkSheetTitle($pValue); + + // Old title + $oldTitle = $this->getTitle(); + + if ($this->_parent) { + // Is there already such sheet name? + if ($this->_parent->sheetNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->_parent->sheetNameExists($pValue . ' ' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $altTitle = $pValue . ' ' . $i; + return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + // Set title + $this->_title = $pValue; + $this->_dirty = true; + + if ($this->_parent) { + // New title + $newTitle = $this->getTitle(); + PHPExcel_Calculation::getInstance($this->_parent) + ->renameCalculationCacheForWorksheet($oldTitle, $newTitle); + if ($updateFormulaCellReferences) + PHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle); + } + + return $this; + } + + /** + * Get sheet state + * + * @return string Sheet state (visible, hidden, veryHidden) + */ + public function getSheetState() { + return $this->_sheetState; + } + + /** + * Set sheet state + * + * @param string $value Sheet state (visible, hidden, veryHidden) + * @return PHPExcel_Worksheet + */ + public function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) { + $this->_sheetState = $value; + return $this; + } + + /** + * Get page setup + * + * @return PHPExcel_Worksheet_PageSetup + */ + public function getPageSetup() + { + return $this->_pageSetup; + } + + /** + * Set page setup + * + * @param PHPExcel_Worksheet_PageSetup $pValue + * @return PHPExcel_Worksheet + */ + public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue) + { + $this->_pageSetup = $pValue; + return $this; + } + + /** + * Get page margins + * + * @return PHPExcel_Worksheet_PageMargins + */ + public function getPageMargins() + { + return $this->_pageMargins; + } + + /** + * Set page margins + * + * @param PHPExcel_Worksheet_PageMargins $pValue + * @return PHPExcel_Worksheet + */ + public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue) + { + $this->_pageMargins = $pValue; + return $this; + } + + /** + * Get page header/footer + * + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function getHeaderFooter() + { + return $this->_headerFooter; + } + + /** + * Set page header/footer + * + * @param PHPExcel_Worksheet_HeaderFooter $pValue + * @return PHPExcel_Worksheet + */ + public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue) + { + $this->_headerFooter = $pValue; + return $this; + } + + /** + * Get sheet view + * + * @return PHPExcel_Worksheet_SheetView + */ + public function getSheetView() + { + return $this->_sheetView; + } + + /** + * Set sheet view + * + * @param PHPExcel_Worksheet_SheetView $pValue + * @return PHPExcel_Worksheet + */ + public function setSheetView(PHPExcel_Worksheet_SheetView $pValue) + { + $this->_sheetView = $pValue; + return $this; + } + + /** + * Get Protection + * + * @return PHPExcel_Worksheet_Protection + */ + public function getProtection() + { + return $this->_protection; + } + + /** + * Set Protection + * + * @param PHPExcel_Worksheet_Protection $pValue + * @return PHPExcel_Worksheet + */ + public function setProtection(PHPExcel_Worksheet_Protection $pValue) + { + $this->_protection = $pValue; + $this->_dirty = true; + + return $this; + } + + /** + * Get highest worksheet column + * + * @param string $row Return the data highest column for the specified row, + * or the highest column of any row if no row number is passed + * @return string Highest column name + */ + public function getHighestColumn($row = null) + { + if ($row == null) { + return $this->_cachedHighestColumn; + } + return $this->getHighestDataColumn($row); + } + + /** + * Get highest worksheet column that contains data + * + * @param string $row Return the highest data column for the specified row, + * or the highest data column of any row if no row number is passed + * @return string Highest column name that contains data + */ + public function getHighestDataColumn($row = null) + { + return $this->_cellCollection->getHighestColumn($row); + } + + /** + * Get highest worksheet row + * + * @param string $column Return the highest data row for the specified column, + * or the highest row of any column if no column letter is passed + * @return int Highest row number + */ + public function getHighestRow($column = null) + { + if ($column == null) { + return $this->_cachedHighestRow; + } + return $this->getHighestDataRow($column); + } + + /** + * Get highest worksheet row that contains data + * + * @param string $column Return the highest data row for the specified column, + * or the highest data row of any column if no column letter is passed + * @return string Highest row number that contains data + */ + public function getHighestDataRow($column = null) + { + return $this->_cellCollection->getHighestRow($column); + } + + /** + * Get highest worksheet column and highest row that have cell records + * + * @return array Highest column name and highest row number + */ + public function getHighestRowAndColumn() + { + return $this->_cellCollection->getHighestRowAndColumn(); + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false) + { + $cell = $this->getCell($pCoordinate)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell (A = 0) + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false) + { + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value + * + * @param string $pCoordinate Coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + // Set value + $cell = $this->getCell($pCoordinate)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Set a cell value by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @param mixed $pValue Value of the cell + * @param string $pDataType Explicit data type + * @param bool $returnCell Return the worksheet (false, default) or the cell (true) + * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified + */ + public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false) + { + $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType); + return ($returnCell) ? $cell : $this; + } + + /** + * Get cell at a specific coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Cell Cell that was found + */ + public function getCell($pCoordinate = 'A1') + { + // Check cell collection + if ($this->_cellCollection->isDataSet($pCoordinate)) { + return $this->_cellCollection->getCacheData($pCoordinate); + } + + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + return $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]); + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + return $namedRange->getWorksheet()->getCell($pCoordinate); + } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate, '$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } + + // Create new cell object + return $this->_createNewCell($pCoordinate); + } + + /** + * Get cell at a specific coordinate by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return PHPExcel_Cell Cell that was found + */ + public function getCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn); + $coordinate = $columnLetter . $pRow; + + if ($this->_cellCollection->isDataSet($coordinate)) { + return $this->_cellCollection->getCacheData($coordinate); + } + + return $this->_createNewCell($coordinate); + } + + /** + * Create a new cell at the specified coordinate + * + * @param string $pCoordinate Coordinate of the cell + * @return PHPExcel_Cell Cell that was created + */ + private function _createNewCell($pCoordinate) + { + $cell = $this->_cellCollection->addCacheData( + $pCoordinate, + new PHPExcel_Cell( + NULL, + PHPExcel_Cell_DataType::TYPE_NULL, + $this + ) + ); + $this->_cellCollectionIsSorted = false; + + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0])) + $this->_cachedHighestColumn = $aCoordinates[0]; + $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]); + + // Cell needs appropriate xfIndex from dimensions records + // but don't create dimension records if they don't already exist + $rowDimension = $this->getRowDimension($aCoordinates[1], FALSE); + $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE); + + if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) { + // then there is a row dimension with explicit style, assign it to the cell + $cell->setXfIndex($rowDimension->getXfIndex()); + } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) { + // then there is a column dimension, assign it to the cell + $cell->setXfIndex($columnDimension->getXfIndex()); + } + + return $cell; + } + + /** + * Does the cell at a specific coordinate exist? + * + * @param string $pCoordinate Coordinate of the cell + * @throws PHPExcel_Exception + * @return boolean + */ + public function cellExists($pCoordinate = 'A1') + { + // Worksheet reference? + if (strpos($pCoordinate, '!') !== false) { + $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true); + return $this->_parent->getSheetByName($worksheetReference[0])->cellExists($worksheetReference[1]); + } + + // Named range? + if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) && + (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) { + $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this); + if ($namedRange !== NULL) { + $pCoordinate = $namedRange->getRange(); + if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) { + if (!$namedRange->getLocalOnly()) { + return $namedRange->getWorksheet()->cellExists($pCoordinate); + } else { + throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle()); + } + } + } + else { return false; } + } + + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.'); + } elseif (strpos($pCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } else { + // Coordinates + $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate); + + // Cell exists? + return $this->_cellCollection->isDataSet($pCoordinate); + } + } + + /** + * Cell at a specific coordinate by using numeric cell coordinates exists? + * + * @param string $pColumn Numeric column coordinate of the cell + * @param string $pRow Numeric row coordinate of the cell + * @return boolean + */ + public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get row dimension at a specific row + * + * @param int $pRow Numeric index of the row + * @return PHPExcel_Worksheet_RowDimension + */ + public function getRowDimension($pRow = 1, $create = TRUE) + { + // Found + $found = null; + + // Get row dimension + if (!isset($this->_rowDimensions[$pRow])) { + if (!$create) + return NULL; + $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow); + + $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow); + } + return $this->_rowDimensions[$pRow]; + } + + /** + * Get column dimension at a specific column + * + * @param string $pColumn String index of the column + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimension($pColumn = 'A', $create = TRUE) + { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + + // Fetch dimensions + if (!isset($this->_columnDimensions[$pColumn])) { + if (!$create) + return NULL; + $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn); + + if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn)) + $this->_cachedHighestColumn = $pColumn; + } + return $this->_columnDimensions[$pColumn]; + } + + /** + * Get column dimension at a specific column by using numeric cell coordinates + * + * @param string $pColumn Numeric column coordinate of the cell + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function getColumnDimensionByColumn($pColumn = 0) + { + return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn)); + } + + /** + * Get styles + * + * @return PHPExcel_Style[] + */ + public function getStyles() + { + return $this->_styles; + } + + /** + * Get default style of workbook. + * + * @deprecated + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getDefaultStyle() + { + return $this->_parent->getDefaultStyle(); + } + + /** + * Set default style - should only be used by PHPExcel_IReader implementations! + * + * @deprecated + * @param PHPExcel_Style $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setDefaultStyle(PHPExcel_Style $pValue) + { + $this->_parent->getDefaultStyle()->applyFromArray(array( + 'font' => array( + 'name' => $pValue->getFont()->getName(), + 'size' => $pValue->getFont()->getSize(), + ), + )); + return $this; + } + + /** + * Get style for cell + * + * @param string $pCellCoordinate Cell coordinate to get style for + * @return PHPExcel_Style + * @throws PHPExcel_Exception + */ + public function getStyle($pCellCoordinate = 'A1') + { + // set this sheet as active + $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this)); + + // set cell coordinate as active + $this->setSelectedCells($pCellCoordinate); + + return $this->_parent->getCellXfSupervisor(); + } + + /** + * Get conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Style_Conditional[] + */ + public function getConditionalStyles($pCoordinate = 'A1') + { + if (!isset($this->_conditionalStylesCollection[$pCoordinate])) { + $this->_conditionalStylesCollection[$pCoordinate] = array(); + } + return $this->_conditionalStylesCollection[$pCoordinate]; + } + + /** + * Do conditional styles exist for this cell? + * + * @param string $pCoordinate + * @return boolean + */ + public function conditionalStylesExists($pCoordinate = 'A1') + { + if (isset($this->_conditionalStylesCollection[$pCoordinate])) { + return true; + } + return false; + } + + /** + * Removes conditional styles for a cell + * + * @param string $pCoordinate + * @return PHPExcel_Worksheet + */ + public function removeConditionalStyles($pCoordinate = 'A1') + { + unset($this->_conditionalStylesCollection[$pCoordinate]); + return $this; + } + + /** + * Get collection of conditional styles + * + * @return array + */ + public function getConditionalStylesCollection() + { + return $this->_conditionalStylesCollection; + } + + /** + * Set conditional styles + * + * @param $pCoordinate string E.g. 'A1' + * @param $pValue PHPExcel_Style_Conditional[] + * @return PHPExcel_Worksheet + */ + public function setConditionalStyles($pCoordinate = 'A1', $pValue) + { + $this->_conditionalStylesCollection[$pCoordinate] = $pValue; + return $this; + } + + /** + * Get style for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Style + */ + public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Set shared cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @deprecated + * @param PHPExcel_Style $pSharedCellStyle Cell style to share + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '') + { + $this->duplicateStyle($pSharedCellStyle, $pRange); + return $this; + } + + /** + * Duplicate cell style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param PHPExcel_Style $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '') + { + // make sure we have a real style and not supervisor + $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle; + + // Add the style to the workbook if necessary + $workbook = $this->_parent; + if ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) { + // there is already such cell Xf in our collection + $xfIndex = $existingStyle->getIndex(); + } else { + // we don't have such a cell Xf, need to add + $workbook->addCellXf($pCellStyle); + $xfIndex = $pCellStyle->getIndex(); + } + + // Calculate range outer borders + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex); + } + } + + return $this; + } + + /** + * Duplicate conditional style to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range! + * + * @param array of PHPExcel_Style_Conditional $pCellStyle Cell style to duplicate + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '') + { + foreach($pCellStyle as $cellStyle) { + if (!($cellStyle instanceof PHPExcel_Style_Conditional)) { + throw new PHPExcel_Exception('Style is not a conditional style'); + } + } + + // Calculate range outer borders + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange); + + // Make sure we can loop upwards on rows and columns + if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) { + $tmp = $rangeStart; + $rangeStart = $rangeEnd; + $rangeEnd = $tmp; + } + + // Loop through cells and apply styles + for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) { + for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) { + $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row, $pCellStyle); + } + } + + return $this; + } + + /** + * Duplicate cell style array to a range of cells + * + * Please note that this will overwrite existing cell styles for cells in range, + * if they are in the styles array. For example, if you decide to set a range of + * cells to font bold, only include font bold in the styles array. + * + * @deprecated + * @param array $pStyles Array containing style information + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param boolean $pAdvanced Advanced mode for setting borders. + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true) + { + $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced); + return $this; + } + + /** + * Set break on a cell + * + * @param string $pCell Cell coordinate (e.g. A1) + * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + // Uppercase coordinate + $pCell = strtoupper($pCell); + + if ($pCell != '') { + if ($pBreak == PHPExcel_Worksheet::BREAK_NONE) { + if (isset($this->_breaks[$pCell])) { + unset($this->_breaks[$pCell]); + } + } else { + $this->_breaks[$pCell] = $pBreak; + } + } else { + throw new PHPExcel_Exception('No cell coordinate specified.'); + } + + return $this; + } + + /** + * Set break on a cell by using numeric cell coordinates + * + * @param integer $pColumn Numeric column coordinate of the cell + * @param integer $pRow Numeric row coordinate of the cell + * @param integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*) + * @return PHPExcel_Worksheet + */ + public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE) + { + return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak); + } + + /** + * Get breaks + * + * @return array[] + */ + public function getBreaks() + { + return $this->_breaks; + } + + /** + * Set merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (strpos($pRange,':') !== false) { + $this->_mergeCells[$pRange] = $pRange; + + // make sure cells are created + + // get the cells in the range + $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange); + + // create upper left cell if it does not already exist + $upperLeft = $aReferences[0]; + if (!$this->cellExists($upperLeft)) { + $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } + + // create or blank out the rest of the cells in the range + $count = count($aReferences); + for ($i = 1; $i < $count; $i++) { + $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL); + } + + } else { + throw new PHPExcel_Exception('Merge must be set on a range of cells.'); + } + + return $this; + } + + /** + * Set merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->mergeCells($cellRange); + } + + /** + * Remove merge on a cell range + * + * @param string $pRange Cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCells($pRange = 'A1:A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (strpos($pRange,':') !== false) { + if (isset($this->_mergeCells[$pRange])) { + unset($this->_mergeCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.'); + } + } else { + throw new PHPExcel_Exception('Merge can only be removed from a range of cells.'); + } + + return $this; + } + + /** + * Remove merge on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unmergeCells($cellRange); + } + + /** + * Get merge cells array. + * + * @return array[] + */ + public function getMergeCells() + { + return $this->_mergeCells; + } + + /** + * Set merge cells array for the entire sheet. Use instead mergeCells() to merge + * a single cell range. + * + * @param array + */ + public function setMergeCells($pValue = array()) + { + $this->_mergeCells = $pValue; + + return $this; + } + + /** + * Set protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false) + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (!$pAlreadyHashed) { + $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword); + } + $this->_protectedCells[$pRange] = $pPassword; + + return $this; + } + + /** + * Set protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed); + } + + /** + * Remove protection on a cell range + * + * @param string $pRange Cell (e.g. A1) or cell range (e.g. A1:E1) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCells($pRange = 'A1') + { + // Uppercase coordinate + $pRange = strtoupper($pRange); + + if (isset($this->_protectedCells[$pRange])) { + unset($this->_protectedCells[$pRange]); + } else { + throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.'); + } + return $this; + } + + /** + * Remove protection on a cell range by using numeric cell coordinates + * + * @param int $pColumn1 Numeric column coordinate of the first cell + * @param int $pRow1 Numeric row coordinate of the first cell + * @param int $pColumn2 Numeric column coordinate of the last cell + * @param int $pRow2 Numeric row coordinate of the last cell + * @param string $pPassword Password to unlock the protection + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false) + { + $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2; + return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed); + } + + /** + * Get protected cells + * + * @return array[] + */ + public function getProtectedCells() + { + return $this->_protectedCells; + } + + /** + * Get Autofilter + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getAutoFilter() + { + return $this->_autoFilter; + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter|string $pValue + * A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilter($pValue) + { + if (is_string($pValue)) { + $this->_autoFilter->setRange($pValue); + } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) { + $this->_autoFilter = $pValue; + } + return $this; + } + + /** + * Set Autofilter Range by using numeric cell coordinates + * + * @param integer $pColumn1 Numeric column coordinate of the first cell + * @param integer $pRow1 Numeric row coordinate of the first cell + * @param integer $pColumn2 Numeric column coordinate of the second cell + * @param integer $pRow2 Numeric row coordinate of the second cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1) + { + return $this->setAutoFilter( + PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 + . ':' . + PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2 + ); + } + + /** + * Remove autofilter + * + * @return PHPExcel_Worksheet + */ + public function removeAutoFilter() + { + $this->_autoFilter->setRange(NULL); + return $this; + } + + /** + * Get Freeze Pane + * + * @return string + */ + public function getFreezePane() + { + return $this->_freezePane; + } + + /** + * Freeze Pane + * + * @param string $pCell Cell (i.e. A2) + * Examples: + * A2 will freeze the rows above cell A2 (i.e row 1) + * B1 will freeze the columns to the left of cell B1 (i.e column A) + * B2 will freeze the rows above and to the left of cell A2 + * (i.e row 1 and column A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePane($pCell = '') + { + // Uppercase coordinate + $pCell = strtoupper($pCell); + + if (strpos($pCell,':') === false && strpos($pCell,',') === false) { + $this->_freezePane = $pCell; + } else { + throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.'); + } + return $this; + } + + /** + * Freeze Pane by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Unfreeze Pane + * + * @return PHPExcel_Worksheet + */ + public function unfreezePane() + { + return $this->freezePane(''); + } + + /** + * Insert a new row, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumRows Number of rows to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) { + if ($pBefore >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows can only be inserted before at least row 1."); + } + return $this; + } + + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) { + if (!is_numeric($pBefore)) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } + + /** + * Insert a new column, updating all possible related data + * + * @param int $pBefore Insert before this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to insert + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) { + if ($pBefore >= 0) { + return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns can only be inserted before at least column A (0)."); + } + } + + /** + * Delete a row, updating all possible related data + * + * @param int $pRow Remove starting with this one + * @param int $pNumRows Number of rows to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeRow($pRow = 1, $pNumRows = 1) { + if ($pRow >= 1) { + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this); + } else { + throw new PHPExcel_Exception("Rows to be deleted should at least start from row 1."); + } + return $this; + } + + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumn($pColumn = 'A', $pNumCols = 1) { + if (!is_numeric($pColumn)) { + $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols); + $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance(); + $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this); + } else { + throw new PHPExcel_Exception("Column references should not be numeric."); + } + return $this; + } + + /** + * Remove a column, updating all possible related data + * + * @param int $pColumn Remove starting with this one (numeric column coordinate of the cell) + * @param int $pNumCols Number of columns to remove + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) { + if ($pColumn >= 0) { + return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols); + } else { + throw new PHPExcel_Exception("Columns to be deleted should at least start from column 0"); + } + } + + /** + * Show gridlines? + * + * @return boolean + */ + public function getShowGridlines() { + return $this->_showGridlines; + } + + /** + * Set show gridlines + * + * @param boolean $pValue Show gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowGridlines($pValue = false) { + $this->_showGridlines = $pValue; + return $this; + } + + /** + * Print gridlines? + * + * @return boolean + */ + public function getPrintGridlines() { + return $this->_printGridlines; + } + + /** + * Set print gridlines + * + * @param boolean $pValue Print gridlines (true/false) + * @return PHPExcel_Worksheet + */ + public function setPrintGridlines($pValue = false) { + $this->_printGridlines = $pValue; + return $this; + } + + /** + * Show row and column headers? + * + * @return boolean + */ + public function getShowRowColHeaders() { + return $this->_showRowColHeaders; + } + + /** + * Set show row and column headers + * + * @param boolean $pValue Show row and column headers (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowRowColHeaders($pValue = false) { + $this->_showRowColHeaders = $pValue; + return $this; + } + + /** + * Show summary below? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryBelow() { + return $this->_showSummaryBelow; + } + + /** + * Set show summary below + * + * @param boolean $pValue Show summary below (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryBelow($pValue = true) { + $this->_showSummaryBelow = $pValue; + return $this; + } + + /** + * Show summary right? (Row/Column outlining) + * + * @return boolean + */ + public function getShowSummaryRight() { + return $this->_showSummaryRight; + } + + /** + * Set show summary right + * + * @param boolean $pValue Show summary right (true/false) + * @return PHPExcel_Worksheet + */ + public function setShowSummaryRight($pValue = true) { + $this->_showSummaryRight = $pValue; + return $this; + } + + /** + * Get comments + * + * @return PHPExcel_Comment[] + */ + public function getComments() + { + return $this->_comments; + } + + /** + * Set comments array for the entire sheet. + * + * @param array of PHPExcel_Comment + * @return PHPExcel_Worksheet + */ + public function setComments($pValue = array()) + { + $this->_comments = $pValue; + + return $this; + } + + /** + * Get comment for cell + * + * @param string $pCellCoordinate Cell coordinate to get comment for + * @return PHPExcel_Comment + * @throws PHPExcel_Exception + */ + public function getComment($pCellCoordinate = 'A1') + { + // Uppercase coordinate + $pCellCoordinate = strtoupper($pCellCoordinate); + + if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) { + throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.'); + } else if (strpos($pCellCoordinate,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate string must not be absolute.'); + } else if ($pCellCoordinate == '') { + throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.'); + } else { + // Check if we already have a comment for this cell. + // If not, create a new comment. + if (isset($this->_comments[$pCellCoordinate])) { + return $this->_comments[$pCellCoordinate]; + } else { + $newComment = new PHPExcel_Comment(); + $this->_comments[$pCellCoordinate] = $newComment; + return $newComment; + } + } + } + + /** + * Get comment for cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @return PHPExcel_Comment + */ + public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get selected cell + * + * @deprecated + * @return string + */ + public function getSelectedCell() + { + return $this->getSelectedCells(); + } + + /** + * Get active cell + * + * @return string Example: 'A1' + */ + public function getActiveCell() + { + return $this->_activeCell; + } + + /** + * Get selected cells + * + * @return string + */ + public function getSelectedCells() + { + return $this->_selectedCells; + } + + /** + * Selected cell + * + * @param string $pCoordinate Cell (i.e. A1) + * @return PHPExcel_Worksheet + */ + public function setSelectedCell($pCoordinate = 'A1') + { + return $this->setSelectedCells($pCoordinate); + } + + /** + * Select a range of cells. + * + * @param string $pCoordinate Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6' + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCells($pCoordinate = 'A1') + { + // Uppercase coordinate + $pCoordinate = strtoupper($pCoordinate); + + // Convert 'A' to 'A:A' + $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate); + + // Convert '1' to '1:1' + $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate); + + // Convert 'A:C' to 'A1:C1048576' + $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate); + + // Convert '1:3' to 'A1:XFD3' + $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate); + + if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) { + list($first, ) = PHPExcel_Cell::splitRange($pCoordinate); + $this->_activeCell = $first[0]; + } else { + $this->_activeCell = $pCoordinate; + } + $this->_selectedCells = $pCoordinate; + return $this; + } + + /** + * Selected cell by using numeric cell coordinates + * + * @param int $pColumn Numeric column coordinate of the cell + * @param int $pRow Numeric row coordinate of the cell + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1) + { + return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow); + } + + /** + * Get right-to-left + * + * @return boolean + */ + public function getRightToLeft() { + return $this->_rightToLeft; + } + + /** + * Set right-to-left + * + * @param boolean $value Right-to-left true/false + * @return PHPExcel_Worksheet + */ + public function setRightToLeft($value = false) { + $this->_rightToLeft = $value; + return $this; + } + + /** + * Fill worksheet from values in array + * + * @param array $source Source array + * @param mixed $nullValue Value in source array that stands for blank cell + * @param string $startCell Insert array starting from this cell address as the top left coordinate + * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet + */ + public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) { + if (is_array($source)) { + // Convert a 1-D array to 2-D (for ease of looping) + if (!is_array(end($source))) { + $source = array($source); + } + + // start coordinate + list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell); + + // Loop through $source + foreach ($source as $rowData) { + $currentColumn = $startColumn; + foreach($rowData as $cellValue) { + if ($strictNullComparison) { + if ($cellValue !== $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } else { + if ($cellValue != $nullValue) { + // Set cell value + $this->getCell($currentColumn . $startRow)->setValue($cellValue); + } + } + ++$currentColumn; + } + ++$startRow; + } + } else { + throw new PHPExcel_Exception("Parameter \$source should be an array."); + } + return $this; + } + + /** + * Create array from a range of cells + * + * @param string $pRange Range of cells (i.e. "A1:B10"), or just one cell (i.e. "A1") + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ + public function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + // Returnvalue + $returnValue = array(); + // Identify the range that we need to extract from the worksheet + list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange); + $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1); + $minRow = $rangeStart[1]; + $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1); + $maxRow = $rangeEnd[1]; + + $maxCol++; + // Loop through rows + $r = -1; + for ($row = $minRow; $row <= $maxRow; ++$row) { + $rRef = ($returnCellRef) ? $row : ++$r; + $c = -1; + // Loop through columns in the current row + for ($col = $minCol; $col != $maxCol; ++$col) { + $cRef = ($returnCellRef) ? $col : ++$c; + // Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen + // so we test and retrieve directly against _cellCollection + if ($this->_cellCollection->isDataSet($col.$row)) { + // Cell exists + $cell = $this->_cellCollection->getCacheData($col.$row); + if ($cell->getValue() !== null) { + if ($cell->getValue() instanceof PHPExcel_RichText) { + $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText(); + } else { + if ($calculateFormulas) { + $returnValue[$rRef][$cRef] = $cell->getCalculatedValue(); + } else { + $returnValue[$rRef][$cRef] = $cell->getValue(); + } + } + + if ($formatData) { + $style = $this->_parent->getCellXfByIndex($cell->getXfIndex()); + $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString( + $returnValue[$rRef][$cRef], + ($style && $style->getNumberFormat()) ? + $style->getNumberFormat()->getFormatCode() : + PHPExcel_Style_NumberFormat::FORMAT_GENERAL + ); + } + } else { + // Cell holds a NULL + $returnValue[$rRef][$cRef] = $nullValue; + } + } else { + // Cell doesn't exist + $returnValue[$rRef][$cRef] = $nullValue; + } + } + } + + // Return + return $returnValue; + } + + + /** + * Create array from a range of cells + * + * @param string $pNamedRange Name of the Named Range + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + * @throws PHPExcel_Exception + */ + public function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this); + if ($namedRange !== NULL) { + $pWorkSheet = $namedRange->getWorksheet(); + $pCellRange = $namedRange->getRange(); + + return $pWorkSheet->rangeToArray( $pCellRange, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); + } + + throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.'); + } + + + /** + * Create array from worksheet + * + * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist + * @param boolean $calculateFormulas Should formulas be calculated? + * @param boolean $formatData Should formatting be applied to cell values? + * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero + * True - Return rows and columns indexed by their actual row and column IDs + * @return array + */ + public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + // Garbage collect... + $this->garbageCollect(); + + // Identify the range that we need to extract from the worksheet + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + // Return + return $this->rangeToArray( 'A1:'.$maxCol.$maxRow, + $nullValue, $calculateFormulas, $formatData, $returnCellRef); + } + + /** + * Get row iterator + * + * @param integer $startRow The row number at which to start iterating + * @return PHPExcel_Worksheet_RowIterator + */ + public function getRowIterator($startRow = 1) { + return new PHPExcel_Worksheet_RowIterator($this,$startRow); + } + + /** + * Run PHPExcel garabage collector. + * + * @return PHPExcel_Worksheet + */ + public function garbageCollect() { + // Flush cache + $this->_cellCollection->getCacheData('A1'); + // Build a reference table from images +// $imageCoordinates = array(); +// $iterator = $this->getDrawingCollection()->getIterator(); +// while ($iterator->valid()) { +// $imageCoordinates[$iterator->current()->getCoordinates()] = true; +// +// $iterator->next(); +// } +// + // Lookup highest column and highest row if cells are cleaned + $colRow = $this->_cellCollection->getHighestRowAndColumn(); + $highestRow = $colRow['row']; + $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']); + + // Loop through column dimensions + foreach ($this->_columnDimensions as $dimension) { + $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex())); + } + + // Loop through row dimensions + foreach ($this->_rowDimensions as $dimension) { + $highestRow = max($highestRow,$dimension->getRowIndex()); + } + + // Cache values + if ($highestColumn < 0) { + $this->_cachedHighestColumn = 'A'; + } else { + $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn); + } + $this->_cachedHighestRow = $highestRow; + + // Return + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + if ($this->_dirty) { + $this->_hash = md5( $this->_title . + $this->_autoFilter . + ($this->_protection->isProtectionEnabled() ? 't' : 'f') . + __CLASS__ + ); + $this->_dirty = false; + } + return $this->_hash; + } + + /** + * Extract worksheet title from range. + * + * Example: extractSheetTitle("testSheet!A1") ==> 'A1' + * Example: extractSheetTitle("'testSheet 1'!A1", true) ==> array('testSheet 1', 'A1'); + * + * @param string $pRange Range to extract title from + * @param bool $returnRange Return range? (see example) + * @return mixed + */ + public static function extractSheetTitle($pRange, $returnRange = false) { + // Sheet title included? + if (($sep = strpos($pRange, '!')) === false) { + return ''; + } + + if ($returnRange) { + return array( trim(substr($pRange, 0, $sep),"'"), + substr($pRange, $sep + 1) + ); + } + + return substr($pRange, $sep + 1); + } + + /** + * Get hyperlink + * + * @param string $pCellCoordinate Cell coordinate to get hyperlink for + */ + public function getHyperlink($pCellCoordinate = 'A1') + { + // return hyperlink if we already have one + if (isset($this->_hyperlinkCollection[$pCellCoordinate])) { + return $this->_hyperlinkCollection[$pCellCoordinate]; + } + + // else create hyperlink + $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink(); + return $this->_hyperlinkCollection[$pCellCoordinate]; + } + + /** + * Set hyperlnk + * + * @param string $pCellCoordinate Cell coordinate to insert hyperlink + * @param PHPExcel_Cell_Hyperlink $pHyperlink + * @return PHPExcel_Worksheet + */ + public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null) + { + if ($pHyperlink === null) { + unset($this->_hyperlinkCollection[$pCellCoordinate]); + } else { + $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink; + } + return $this; + } + + /** + * Hyperlink at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function hyperlinkExists($pCoordinate = 'A1') + { + return isset($this->_hyperlinkCollection[$pCoordinate]); + } + + /** + * Get collection of hyperlinks + * + * @return PHPExcel_Cell_Hyperlink[] + */ + public function getHyperlinkCollection() + { + return $this->_hyperlinkCollection; + } + + /** + * Get data validation + * + * @param string $pCellCoordinate Cell coordinate to get data validation for + */ + public function getDataValidation($pCellCoordinate = 'A1') + { + // return data validation if we already have one + if (isset($this->_dataValidationCollection[$pCellCoordinate])) { + return $this->_dataValidationCollection[$pCellCoordinate]; + } + + // else create data validation + $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation(); + return $this->_dataValidationCollection[$pCellCoordinate]; + } + + /** + * Set data validation + * + * @param string $pCellCoordinate Cell coordinate to insert data validation + * @param PHPExcel_Cell_DataValidation $pDataValidation + * @return PHPExcel_Worksheet + */ + public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null) + { + if ($pDataValidation === null) { + unset($this->_dataValidationCollection[$pCellCoordinate]); + } else { + $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation; + } + return $this; + } + + /** + * Data validation at a specific coordinate exists? + * + * @param string $pCoordinate + * @return boolean + */ + public function dataValidationExists($pCoordinate = 'A1') + { + return isset($this->_dataValidationCollection[$pCoordinate]); + } + + /** + * Get collection of data validations + * + * @return PHPExcel_Cell_DataValidation[] + */ + public function getDataValidationCollection() + { + return $this->_dataValidationCollection; + } + + /** + * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet + * + * @param string $range + * @return string Adjusted range value + */ + public function shrinkRangeToFit($range) { + $maxCol = $this->getHighestColumn(); + $maxRow = $this->getHighestRow(); + $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol); + + $rangeBlocks = explode(' ',$range); + foreach ($rangeBlocks as &$rangeSet) { + $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet); + + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; } + if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); } + if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; } + $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1]; + } + unset($rangeSet); + $stRange = implode(' ',$rangeBlocks); + + return $stRange; + } + + /** + * Get tab color + * + * @return PHPExcel_Style_Color + */ + public function getTabColor() + { + if ($this->_tabColor === NULL) + $this->_tabColor = new PHPExcel_Style_Color(); + + return $this->_tabColor; + } + + /** + * Reset tab color + * + * @return PHPExcel_Worksheet + */ + public function resetTabColor() + { + $this->_tabColor = null; + unset($this->_tabColor); + + return $this; + } + + /** + * Tab color set? + * + * @return boolean + */ + public function isTabColorSet() + { + return ($this->_tabColor !== NULL); + } + + /** + * Copy worksheet (!= clone!) + * + * @return PHPExcel_Worksheet + */ + public function copy() { + $copied = clone $this; + + return $copied; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + foreach ($this as $key => $val) { + if ($key == '_parent') { + continue; + } + + if (is_object($val) || (is_array($val))) { + if ($key == '_cellCollection') { + $newCollection = clone $this->_cellCollection; + $newCollection->copyCellCollection($this); + $this->_cellCollection = $newCollection; + } elseif ($key == '_drawingCollection') { + $newCollection = clone $this->_drawingCollection; + $this->_drawingCollection = $newCollection; + } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) { + $newAutoFilter = clone $this->_autoFilter; + $this->_autoFilter = $newAutoFilter; + $this->_autoFilter->setParent($this); + } else { + $this->{$key} = unserialize(serialize($val)); + } + } + } + } +/** + * Define the code name of the sheet + * + * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore) + * @return objWorksheet + * @throws PHPExcel_Exception + */ + public function setCodeName($pValue=null){ + // Is this a 'rename' or not? + if ($this->getCodeName() == $pValue) { + return $this; + } + $pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same + // Syntax check + // throw an exception if not valid + self::_checkSheetCodeName($pValue); + + // We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_' + + if ($this->getParent()) { + // Is there already such sheet name? + if ($this->getParent()->sheetCodeNameExists($pValue)) { + // Use name, but append with lowest possible integer + + if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,29); + } + $i = 1; + while ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) { + ++$i; + if ($i == 10) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,28); + } + } elseif ($i == 100) { + if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) { + $pValue = PHPExcel_Shared_String::Substring($pValue,0,27); + } + } + } + + $pValue = $pValue . '_' . $i;// ok, we have a valid name + //codeName is'nt used in formula : no need to call for an update + //return $this->setTitle($altTitle,$updateFormulaCellReferences); + } + } + + $this->_codeName=$pValue; + return $this; + } + /** + * Return the code name of the sheet + * + * @return null|string + */ + public function getCodeName(){ + return $this->_codeName; + } + /** + * Sheet has a code name ? + * @return boolean + */ + public function hasCodeName(){ + return !(is_null($this->_codeName)); + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/AutoFilter.php b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter.php new file mode 100755 index 0000000..03055e1 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter.php @@ -0,0 +1,858 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter +{ + /** + * Autofilter Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_workSheet = NULL; + + + /** + * Autofilter Range + * + * @var string + */ + private $_range = ''; + + + /** + * Autofilter Column Ruleset + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column + */ + private $_columns = array(); + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter + * + * @param string $pRange Cell range (i.e. A1:E10) + * @param PHPExcel_Worksheet $pSheet + */ + public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) + { + $this->_range = $pRange; + $this->_workSheet = $pSheet; + } + + /** + * Get AutoFilter Parent Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getParent() { + return $this->_workSheet; + } + + /** + * Set AutoFilter Parent Worksheet + * + * @param PHPExcel_Worksheet $pSheet + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setParent(PHPExcel_Worksheet $pSheet = NULL) { + $this->_workSheet = $pSheet; + + return $this; + } + + /** + * Get AutoFilter Range + * + * @return string + */ + public function getRange() { + return $this->_range; + } + + /** + * Set AutoFilter Range + * + * @param string $pRange Cell range (i.e. A1:E10) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setRange($pRange = '') { + // Uppercase coordinate + $cellAddress = explode('!',strtoupper($pRange)); + if (count($cellAddress) > 1) { + list($worksheet,$pRange) = $cellAddress; + } + + if (strpos($pRange,':') !== FALSE) { + $this->_range = $pRange; + } elseif(empty($pRange)) { + $this->_range = ''; + } else { + throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); + } + + if (empty($pRange)) { + // Discard all column rules + $this->_columns = array(); + } else { + // Discard any column rules that are no longer valid within this range + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + foreach($this->_columns as $key => $value) { + $colIndex = PHPExcel_Cell::columnIndexFromString($key); + if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { + unset($this->_columns[$key]); + } + } + } + + return $this; + } + + /** + * Get all AutoFilter Columns + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumns() { + return $this->_columns; + } + + /** + * Validate that the specified column is in the AutoFilter range + * + * @param string $column Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The column offset within the autofilter range + */ + public function testColumnInRange($column) { + if (empty($this->_range)) { + throw new PHPExcel_Exception("No autofilter range is defined."); + } + + $columnIndex = PHPExcel_Cell::columnIndexFromString($column); + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { + throw new PHPExcel_Exception("Column is outside of current autofilter range."); + } + + return $columnIndex - $rangeStart[0]; + } + + /** + * Get a specified AutoFilter Column Offset within the defined AutoFilter range + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return integer The offset of the specified column within the autofilter range + */ + public function getColumnOffset($pColumn) { + return $this->testColumnInRange($pColumn); + } + + /** + * Get a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (!isset($this->_columns[$pColumn])) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } + + return $this->_columns[$pColumn]; + } + + /** + * Get a specified AutoFilter Column by it's offset + * + * @param integer $pColumnOffset Column offset within range (starting from 0) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getColumnByOffset($pColumnOffset = 0) { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + $pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); + + return $this->getColumn($pColumn); + } + + /** + * Set AutoFilter + * + * @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn + * A simple string containing a Column ID like 'A' is permitted + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function setColumn($pColumn) + { + if ((is_string($pColumn)) && (!empty($pColumn))) { + $column = $pColumn; + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $column = $pColumn->getColumnIndex(); + } else { + throw new PHPExcel_Exception("Column is not within the autofilter range."); + } + $this->testColumnInRange($column); + + if (is_string($pColumn)) { + $this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); + } elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { + $pColumn->setParent($this); + $this->_columns[$column] = $pColumn; + } + ksort($this->_columns); + + return $this; + } + + /** + * Clear a specified AutoFilter Column + * + * @param string $pColumn Column name (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function clearColumn($pColumn) { + $this->testColumnInRange($pColumn); + + if (isset($this->_columns[$pColumn])) { + unset($this->_columns[$pColumn]); + } + + return $this; + } + + /** + * Shift an AutoFilter Column Rule to a different column + * + * Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range. + * Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value. + * Use with caution. + * + * @param string $fromColumn Column name (e.g. A) + * @param string $toColumn Column name (e.g. B) + * @return PHPExcel_Worksheet_AutoFilter + */ + public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { + $fromColumn = strtoupper($fromColumn); + $toColumn = strtoupper($toColumn); + + if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { + $this->_columns[$fromColumn]->setParent(); + $this->_columns[$fromColumn]->setColumnIndex($toColumn); + $this->_columns[$toColumn] = $this->_columns[$fromColumn]; + $this->_columns[$toColumn]->setParent($this); + unset($this->_columns[$fromColumn]); + + ksort($this->_columns); + } + + return $this; + } + + + /** + * Test if cell value is in the defined set of values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInSimpleDataSet($cellValue,$dataSet) + { + $dataSetValues = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + return in_array($cellValue,$dataSetValues); + } + + /** + * Test if cell value is in the defined set of Excel date values + * + * @param mixed $cellValue + * @param mixed[] $dataSet + * @return boolean + */ + private static function _filterTestInDateGroupSet($cellValue,$dataSet) + { + $dateSet = $dataSet['filterValues']; + $blanks = $dataSet['blanks']; + if (($cellValue == '') || ($cellValue === NULL)) { + return $blanks; + } + + if (is_numeric($cellValue)) { + $dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); + if ($cellValue < 1) { + // Just the time part + $dtVal = date('His',$dateValue); + $dateSet = $dateSet['time']; + } elseif($cellValue == floor($cellValue)) { + // Just the date part + $dtVal = date('Ymd',$dateValue); + $dateSet = $dateSet['date']; + } else { + // date and time parts + $dtVal = date('YmdHis',$dateValue); + $dateSet = $dateSet['dateTime']; + } + foreach($dateSet as $dateValue) { + // Use of substr to extract value at the appropriate group level + if (substr($dtVal,0,strlen($dateValue)) == $dateValue) + return TRUE; + } + } + + return FALSE; + } + + /** + * Test if cell value is within a set of values defined by a ruleset + * + * @param mixed $cellValue + * @param mixed[] $ruleSet + * @return boolean + */ + private static function _filterTestInCustomDataSet($cellValue, $ruleSet) + { + $dataSet = $ruleSet['filterRules']; + $join = $ruleSet['join']; + $customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; + + if (!$customRuleForBlanks) { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + } + $returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); + foreach($dataSet as $rule) { + if (is_numeric($rule['value'])) { + // Numeric values are tested using the appropriate operator + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = ($cellValue == $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = ($cellValue != $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : + $retVal = ($cellValue > $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : + $retVal = ($cellValue >= $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : + $retVal = ($cellValue < $rule['value']); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : + $retVal = ($cellValue <= $rule['value']); + break; + } + } elseif($rule['value'] == '') { + switch ($rule['operator']) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : + $retVal = (($cellValue == '') || ($cellValue === NULL)); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : + $retVal = (($cellValue != '') && ($cellValue !== NULL)); + break; + default : + $retVal = TRUE; + break; + } + } else { + // String values are always tested for equality, factoring in for wildcards (hence a regexp test) + $retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); + } + // If there are multiple conditions, then we need to test both using the appropriate join operator + switch ($join) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : + $returnVal = $returnVal || $retVal; + // Break as soon as we have a TRUE match for OR joins, + // to avoid unnecessary additional code execution + if ($returnVal) + return $returnVal; + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : + $returnVal = $returnVal && $retVal; + break; + } + } + + return $returnVal; + } + + /** + * Test if cell date value is matches a set of values defined by a set of months + * + * @param mixed $cellValue + * @param mixed[] $monthSet + * @return boolean + */ + private static function _filterTestInPeriodDateSet($cellValue, $monthSet) + { + // Blank cells are always ignored, so return a FALSE + if (($cellValue == '') || ($cellValue === NULL)) { + return FALSE; + } + + if (is_numeric($cellValue)) { + $dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); + if (in_array($dateValue,$monthSet)) { + return TRUE; + } + } + + return FALSE; + } + + /** + * Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching + * + * @var array + */ + private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); + private static $_toReplace = array('.*', '.', '~', '\*', '\?'); + + + /** + * Convert a dynamic rule daterange to a custom filter range expression for ease of calculation + * + * @param string $dynamicRuleType + * @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn + * @return mixed[] + */ + private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) + { + $rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); + $val = $maxVal = NULL; + + $ruleValues = array(); + $baseDate = PHPExcel_Calculation_DateTime::DATENOW(); + // Calculate start/end dates for the required date range based on current date + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $baseDate = strtotime('-7 days',$baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + $baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + $baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + $baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + } + + switch ($dynamicRuleType) { + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : + $maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : + $thisMonth = date('m',$baseDate); + $thisQuarter = floor(--$thisMonth / 3); + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : + $maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); + ++$maxVal; + $val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : + $dayOfWeek = date('w',$baseDate); + $val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; + $maxVal = $val + 7; + break; + } + + switch ($dynamicRuleType) { + // Adjust Today dates for Yesterday and Tomorrow + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : + --$maxVal; + --$val; + break; + case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : + ++$maxVal; + ++$val; + break; + } + + // Set the filter column rule attributes ready for writing + $filterColumn->setAttributes(array( 'val' => $val, + 'maxVal' => $maxVal + ) + ); + + // Set the rules for identifying rows for hide/show + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + 'value' => $val + ); + $ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, + 'value' => $maxVal + ); + PHPExcel_Calculation_Functions::setReturnDateType($rDateType); + + return array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND + ) + ); + } + + private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { + $range = $columnID.$startRow.':'.$columnID.$endRow; + $dataValues = PHPExcel_Calculation_Functions::flattenArray( + $this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) + ); + + $dataValues = array_filter($dataValues); + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { + rsort($dataValues); + } else { + sort($dataValues); + } + + return array_pop(array_slice($dataValues,0,$ruleValue)); + } + + /** + * Apply the AutoFilter rules to the AutoFilter Range + * + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter + */ + public function showHideRows() + { + list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); + + // The heading row should always be visible +// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; + $this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); + + $columnFilterTests = array(); + foreach($this->_columns as $columnID => $filterColumn) { + $rules = $filterColumn->getRules(); + switch ($filterColumn->getFilterType()) { + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValues[] = $rule->getValue(); + } + // Test if we want to include blanks in our filter criteria + $blanks = FALSE; + $ruleDataSet = array_filter($ruleValues); + if (count($ruleValues) != count($ruleDataSet)) + $blanks = TRUE; + if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { + // Filter on absolute values + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInSimpleDataSet', + 'arguments' => array( 'filterValues' => $ruleDataSet, + 'blanks' => $blanks + ) + ); + } else { + // Filter on date group values + $arguments = array(); + foreach($ruleDataSet as $ruleValue) { + $date = $time = ''; + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) + $date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) + $date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); + if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && + ($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) + $time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); + $dateTime = $date . $time; + $arguments['date'][] = $date; + $arguments['time'][] = $time; + $arguments['dateTime'][] = $dateTime; + } + // Remove empty elements + $arguments['date'] = array_filter($arguments['date']); + $arguments['time'] = array_filter($arguments['time']); + $arguments['dateTime'] = array_filter($arguments['dateTime']); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInDateGroupSet', + 'arguments' => array( 'filterValues' => $arguments, + 'blanks' => $blanks + ) + ); + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : + $customRuleForBlanks = FALSE; + $ruleValues = array(); + // Build a list of the filter value selections + foreach($rules as $rule) { + $ruleType = $rule->getRuleType(); + $ruleValue = $rule->getValue(); + if (!is_numeric($ruleValue)) { + // Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards + $ruleValue = preg_quote($ruleValue); + $ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); + if (trim($ruleValue) == '') { + $customRuleForBlanks = TRUE; + $ruleValue = trim($ruleValue); + } + } + $ruleValues[] = array( 'operator' => $rule->getOperator(), + 'value' => $ruleValue + ); + } + $join = $filterColumn->getJoin(); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => $join, + 'customRuleForBlanks' => $customRuleForBlanks + ) + ); + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : + $ruleValues = array(); + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $dynamicRuleType = $rule->getGrouping(); + if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || + ($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) { + // Number (Average) based + // Calculate the average + $averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; + $average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); + // Set above/below rule based on greaterThan or LessTan + $operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $average + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + } else { + // Date based + if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { + // Month or Quarter + sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); + if ($periodType == 'M') { + $ruleValues = array($period); + } else { + --$period; + $periodEnd = (1+$period)*3; + $periodStart = 1+$period*3; + $ruleValues = range($periodStart,periodEnd); + } + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInPeriodDateSet', + 'arguments' => $ruleValues + ); + $filterColumn->setAttributes(array()); + } else { + // Date Range + $columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); + break; + } + } + } + break; + case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : + $ruleValues = array(); + $dataRowCount = $rangeEnd[1] - $rangeStart[1]; + foreach($rules as $rule) { + // We should only ever have one Dynamic Filter Rule anyway + $toptenRuleType = $rule->getGrouping(); + $ruleValue = $rule->getValue(); + $ruleOperator = $rule->getOperator(); + } + if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { + $ruleValue = floor($ruleValue * ($dataRowCount / 100)); + } + if ($ruleValue < 1) $ruleValue = 1; + if ($ruleValue > 500) $ruleValue = 500; + + $maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); + + $operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) + ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL + : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; + $ruleValues[] = array( 'operator' => $operator, + 'value' => $maxVal + ); + $columnFilterTests[$columnID] = array( + 'method' => '_filterTestInCustomDataSet', + 'arguments' => array( 'filterRules' => $ruleValues, + 'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR + ) + ); + $filterColumn->setAttributes( + array('maxVal' => $maxVal) + ); + break; + } + } + +// echo 'Column Filter Test CRITERIA',PHP_EOL; +// var_dump($columnFilterTests); +// + // Execute the column tests for each row in the autoFilter range to determine show/hide, + for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { +// echo 'Testing Row = ',$row,PHP_EOL; + $result = TRUE; + foreach($columnFilterTests as $columnID => $columnFilterTest) { +// echo 'Testing cell ',$columnID.$row,PHP_EOL; + $cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); +// echo 'Value is ',$cellValue,PHP_EOL; + // Execute the filter test + $result = $result && + call_user_func_array( + array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), + array( + $cellValue, + $columnFilterTest['arguments'] + ) + ); +// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; + // If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests + if (!$result) + break; + } + // Set show/hide for the row based on the result of the autoFilter result +// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; + $this->_workSheet->getRowDimension($row)->setVisible($result); + } + + return $this; + } + + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_workSheet') { + // Detach from worksheet + $this->{$key} = NULL; + } else { + $this->{$key} = clone $value; + } + } elseif ((is_array($value)) && ($key == '_columns')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->{$key} = array(); + foreach ($value as $k => $v) { + $this->{$key}[$k] = clone $v; + // attach the new cloned Column to this new cloned Autofilter object + $this->{$key}[$k]->setParent($this); + } + } else { + $this->{$key} = $value; + } + } + } + + /** + * toString method replicates previous behavior by returning the range if object is + * referenced as a property of its parent. + */ + public function __toString() { + return (string) $this->_range; + } + +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php new file mode 100755 index 0000000..12043d5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column.php @@ -0,0 +1,394 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter_Column + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter_Column +{ + const AUTOFILTER_FILTERTYPE_FILTER = 'filters'; + const AUTOFILTER_FILTERTYPE_CUSTOMFILTER = 'customFilters'; + // Supports no more than 2 rules, with an And/Or join criteria + // if more than 1 rule is defined + const AUTOFILTER_FILTERTYPE_DYNAMICFILTER = 'dynamicFilter'; + // Even though the filter rule is constant, the filtered data can vary + // e.g. filtered by date = TODAY + const AUTOFILTER_FILTERTYPE_TOPTENFILTER = 'top10'; + + /** + * Types of autofilter rules + * + * @var string[] + */ + private static $_filterTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_FILTERTYPE_FILTER, + self::AUTOFILTER_FILTERTYPE_CUSTOMFILTER, + self::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, + self::AUTOFILTER_FILTERTYPE_TOPTENFILTER, + ); + + /* Multiple Rule Connections */ + const AUTOFILTER_COLUMN_JOIN_AND = 'and'; + const AUTOFILTER_COLUMN_JOIN_OR = 'or'; + + /** + * Join options for autofilter rules + * + * @var string[] + */ + private static $_ruleJoins = array( + self::AUTOFILTER_COLUMN_JOIN_AND, + self::AUTOFILTER_COLUMN_JOIN_OR, + ); + + /** + * Autofilter + * + * @var PHPExcel_Worksheet_AutoFilter + */ + private $_parent = NULL; + + + /** + * Autofilter Column Index + * + * @var string + */ + private $_columnIndex = ''; + + + /** + * Autofilter Column Filter Type + * + * @var string + */ + private $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER; + + + /** + * Autofilter Multiple Rules And/Or + * + * @var string + */ + private $_join = self::AUTOFILTER_COLUMN_JOIN_OR; + + + /** + * Autofilter Column Rules + * + * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + private $_ruleset = array(); + + + /** + * Autofilter Column Dynamic Attributes + * + * @var array of mixed + */ + private $_attributes = array(); + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column + * + * @param string $pColumn Column (e.g. A) + * @param PHPExcel_Worksheet_AutoFilter $pParent Autofilter for this column + */ + public function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL) + { + $this->_columnIndex = $pColumn; + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Column Index + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set AutoFilter Column Index + * + * @param string $pColumn Column (e.g. A) + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setColumnIndex($pColumn) { + // Uppercase coordinate + $pColumn = strtoupper($pColumn); + if ($this->_parent !== NULL) { + $this->_parent->testColumnInRange($pColumn); + } + + $this->_columnIndex = $pColumn; + + return $this; + } + + /** + * Get this Column's AutoFilter Parent + * + * @return PHPExcel_Worksheet_AutoFilter + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Column's AutoFilter Parent + * + * @param PHPExcel_Worksheet_AutoFilter + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Get AutoFilter Type + * + * @return string + */ + public function getFilterType() { + return $this->_filterType; + } + + /** + * Set AutoFilter Type + * + * @param string $pFilterType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) { + if (!in_array($pFilterType,self::$_filterTypes)) { + throw new PHPExcel_Exception('Invalid filter type for column AutoFilter.'); + } + + $this->_filterType = $pFilterType; + + return $this; + } + + /** + * Get AutoFilter Multiple Rules And/Or Join + * + * @return string + */ + public function getJoin() { + return $this->_join; + } + + /** + * Set AutoFilter Multiple Rules And/Or + * + * @param string $pJoin And/Or + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) { + // Lowercase And/Or + $pJoin = strtolower($pJoin); + if (!in_array($pJoin,self::$_ruleJoins)) { + throw new PHPExcel_Exception('Invalid rule connection for column AutoFilter.'); + } + + $this->_join = $pJoin; + + return $this; + } + + /** + * Set AutoFilter Attributes + * + * @param string[] $pAttributes + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttributes($pAttributes = array()) { + $this->_attributes = $pAttributes; + + return $this; + } + + /** + * Set An AutoFilter Attribute + * + * @param string $pName Attribute Name + * @param string $pValue Attribute Value + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setAttribute($pName, $pValue) { + $this->_attributes[$pName] = $pValue; + + return $this; + } + + /** + * Get AutoFilter Column Attributes + * + * @return string + */ + public function getAttributes() { + return $this->_attributes; + } + + /** + * Get specific AutoFilter Column Attribute + * + * @param string $pName Attribute Name + * @return string + */ + public function getAttribute($pName) { + if (isset($this->_attributes[$pName])) + return $this->_attributes[$pName]; + return NULL; + } + + /** + * Get all AutoFilter Column Rules + * + * @throws PHPExcel_Exception + * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRules() { + return $this->_ruleset; + } + + /** + * Get a specified AutoFilter Column Rule + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function getRule($pIndex) { + if (!isset($this->_ruleset[$pIndex])) { + $this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + } + return $this->_ruleset[$pIndex]; + } + + /** + * Create a new AutoFilter Column Rule in the ruleset + * + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function createRule() { + $this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this); + + return end($this->_ruleset); + } + + /** + * Add a new AutoFilter Column Rule to the ruleset + * + * @param PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule + * @param boolean $returnRule Flag indicating whether the rule object or the column object should be returned + * @return PHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) { + $pRule->setParent($this); + $this->_ruleset[] = $pRule; + + return ($returnRule) ? $pRule : $this; + } + + /** + * Delete a specified AutoFilter Column Rule + * If the number of rules is reduced to 1, then we reset And/Or logic to Or + * + * @param integer $pIndex Rule index in the ruleset array + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function deleteRule($pIndex) { + if (isset($this->_ruleset[$pIndex])) { + unset($this->_ruleset[$pIndex]); + // If we've just deleted down to a single rule, then reset And/Or joining to Or + if (count($this->_ruleset) <= 1) { + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + } + } + + return $this; + } + + /** + * Delete all AutoFilter Column Rules + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function clearRules() { + $this->_ruleset = array(); + $this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR); + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } elseif ((is_array($value)) && ($key == '_ruleset')) { + // The columns array of PHPExcel_Worksheet_AutoFilter objects + $this->$key = array(); + foreach ($value as $k => $v) { + $this->$key[$k] = clone $v; + // attach the new cloned Rule to this new cloned Autofilter Cloned object + $this->$key[$k]->setParent($this); + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php new file mode 100755 index 0000000..ae33683 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/AutoFilter/Column/Rule.php @@ -0,0 +1,464 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_AutoFilter_Column_Rule +{ + const AUTOFILTER_RULETYPE_FILTER = 'filter'; + const AUTOFILTER_RULETYPE_DATEGROUP = 'dateGroupItem'; + const AUTOFILTER_RULETYPE_CUSTOMFILTER = 'customFilter'; + const AUTOFILTER_RULETYPE_DYNAMICFILTER = 'dynamicFilter'; + const AUTOFILTER_RULETYPE_TOPTENFILTER = 'top10Filter'; + + private static $_ruleTypes = array( + // Currently we're not handling + // colorFilter + // extLst + // iconFilter + self::AUTOFILTER_RULETYPE_FILTER, + self::AUTOFILTER_RULETYPE_DATEGROUP, + self::AUTOFILTER_RULETYPE_CUSTOMFILTER, + self::AUTOFILTER_RULETYPE_DYNAMICFILTER, + self::AUTOFILTER_RULETYPE_TOPTENFILTER, + ); + + const AUTOFILTER_RULETYPE_DATEGROUP_YEAR = 'year'; + const AUTOFILTER_RULETYPE_DATEGROUP_MONTH = 'month'; + const AUTOFILTER_RULETYPE_DATEGROUP_DAY = 'day'; + const AUTOFILTER_RULETYPE_DATEGROUP_HOUR = 'hour'; + const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE = 'minute'; + const AUTOFILTER_RULETYPE_DATEGROUP_SECOND = 'second'; + + private static $_dateTimeGroups = array( + self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH, + self::AUTOFILTER_RULETYPE_DATEGROUP_DAY, + self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR, + self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE, + self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND, + ); + + const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY = 'yesterday'; + const AUTOFILTER_RULETYPE_DYNAMIC_TODAY = 'today'; + const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW = 'tomorrow'; + const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE = 'yearToDate'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR = 'thisYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER = 'thisQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH = 'thisMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK = 'thisWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR = 'lastYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER = 'lastQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH = 'lastMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK = 'lastWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR = 'nextYear'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER = 'nextQuarter'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH = 'nextMonth'; + const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK = 'nextWeek'; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1 = 'M1'; + const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2 = 'M2'; + const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3 = 'M3'; + const AUTOFILTER_RULETYPE_DYNAMIC_MARCH = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4 = 'M4'; + const AUTOFILTER_RULETYPE_DYNAMIC_APRIL = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5 = 'M5'; + const AUTOFILTER_RULETYPE_DYNAMIC_MAY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6 = 'M6'; + const AUTOFILTER_RULETYPE_DYNAMIC_JUNE = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7 = 'M7'; + const AUTOFILTER_RULETYPE_DYNAMIC_JULY = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8 = 'M8'; + const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9 = 'M9'; + const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10 = 'M10'; + const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11 = 'M11'; + const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11; + const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12 = 'M12'; + const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER = self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1 = 'Q1'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2 = 'Q2'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3 = 'Q3'; + const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4 = 'Q4'; + const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE = 'aboveAverage'; + const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE = 'belowAverage'; + + private static $_dynamicTypes = array( + self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY, + self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW, + self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH, + self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11, + self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3, + self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4, + self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE, + self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE, + ); + + /* + * The only valid filter rule operators for filter and customFilter types are: + * <xsd:enumeration value="equal"/> + * <xsd:enumeration value="lessThan"/> + * <xsd:enumeration value="lessThanOrEqual"/> + * <xsd:enumeration value="notEqual"/> + * <xsd:enumeration value="greaterThanOrEqual"/> + * <xsd:enumeration value="greaterThan"/> + */ + const AUTOFILTER_COLUMN_RULE_EQUAL = 'equal'; + const AUTOFILTER_COLUMN_RULE_NOTEQUAL = 'notEqual'; + const AUTOFILTER_COLUMN_RULE_GREATERTHAN = 'greaterThan'; + const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL = 'greaterThanOrEqual'; + const AUTOFILTER_COLUMN_RULE_LESSTHAN = 'lessThan'; + const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL = 'lessThanOrEqual'; + + private static $_operators = array( + self::AUTOFILTER_COLUMN_RULE_EQUAL, + self::AUTOFILTER_COLUMN_RULE_NOTEQUAL, + self::AUTOFILTER_COLUMN_RULE_GREATERTHAN, + self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, + self::AUTOFILTER_COLUMN_RULE_LESSTHAN, + self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE = 'byValue'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT = 'byPercent'; + + private static $_topTenValue = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT, + ); + + const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP = 'top'; + const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM = 'bottom'; + + private static $_topTenType = array( + self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP, + self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM, + ); + + + /* Rule Operators (Numeric, Boolean etc) */ +// const AUTOFILTER_COLUMN_RULE_BETWEEN = 'between'; // greaterThanOrEqual 1 && lessThanOrEqual 2 + /* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_TOPTEN = 'topTen'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT = 'topTenPercent'; // greaterThan calculated value +// const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE = 'aboveAverage'; // Value is calculated as the average +// const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE = 'belowAverage'; // Value is calculated as the average + /* Rule Operators (String) which are set as wild-carded values */ +// const AUTOFILTER_COLUMN_RULE_BEGINSWITH = 'beginsWith'; // A* +// const AUTOFILTER_COLUMN_RULE_ENDSWITH = 'endsWith'; // *Z +// const AUTOFILTER_COLUMN_RULE_CONTAINS = 'contains'; // *B* +// const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN = 'notEqual'; // notEqual *B* + /* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */ +// const AUTOFILTER_COLUMN_RULE_BEFORE = 'lessThan'; +// const AUTOFILTER_COLUMN_RULE_AFTER = 'greaterThan'; +// const AUTOFILTER_COLUMN_RULE_YESTERDAY = 'yesterday'; +// const AUTOFILTER_COLUMN_RULE_TODAY = 'today'; +// const AUTOFILTER_COLUMN_RULE_TOMORROW = 'tomorrow'; +// const AUTOFILTER_COLUMN_RULE_LASTWEEK = 'lastWeek'; +// const AUTOFILTER_COLUMN_RULE_THISWEEK = 'thisWeek'; +// const AUTOFILTER_COLUMN_RULE_NEXTWEEK = 'nextWeek'; +// const AUTOFILTER_COLUMN_RULE_LASTMONTH = 'lastMonth'; +// const AUTOFILTER_COLUMN_RULE_THISMONTH = 'thisMonth'; +// const AUTOFILTER_COLUMN_RULE_NEXTMONTH = 'nextMonth'; +// const AUTOFILTER_COLUMN_RULE_LASTQUARTER = 'lastQuarter'; +// const AUTOFILTER_COLUMN_RULE_THISQUARTER = 'thisQuarter'; +// const AUTOFILTER_COLUMN_RULE_NEXTQUARTER = 'nextQuarter'; +// const AUTOFILTER_COLUMN_RULE_LASTYEAR = 'lastYear'; +// const AUTOFILTER_COLUMN_RULE_THISYEAR = 'thisYear'; +// const AUTOFILTER_COLUMN_RULE_NEXTYEAR = 'nextYear'; +// const AUTOFILTER_COLUMN_RULE_YEARTODATE = 'yearToDate'; // <dynamicFilter val="40909" type="yearToDate" maxVal="41113"/> +// const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH = 'allDatesInMonth'; // <dynamicFilter type="M2"/> for Month/February +// const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER = 'allDatesInQuarter'; // <dynamicFilter type="Q2"/> for Quarter 2 + + /** + * Autofilter Column + * + * @var PHPExcel_Worksheet_AutoFilter_Column + */ + private $_parent = NULL; + + + /** + * Autofilter Rule Type + * + * @var string + */ + private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER; + + + /** + * Autofilter Rule Value + * + * @var string + */ + private $_value = ''; + + /** + * Autofilter Rule Operator + * + * @var string + */ + private $_operator = ''; + + /** + * DateTimeGrouping Group Value + * + * @var string + */ + private $_grouping = ''; + + + /** + * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule + * + * @param PHPExcel_Worksheet_AutoFilter_Column $pParent + */ + public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) + { + $this->_parent = $pParent; + } + + /** + * Get AutoFilter Rule Type + * + * @return string + */ + public function getRuleType() { + return $this->_ruleType; + } + + /** + * Set AutoFilter Rule Type + * + * @param string $pRuleType + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) { + if (!in_array($pRuleType,self::$_ruleTypes)) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_ruleType = $pRuleType; + + return $this; + } + + /** + * Get AutoFilter Rule Value + * + * @return string + */ + public function getValue() { + return $this->_value; + } + + /** + * Set AutoFilter Rule Value + * + * @param string|string[] $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setValue($pValue = '') { + if (is_array($pValue)) { + $grouping = -1; + foreach($pValue as $key => $value) { + // Validate array entries + if (!in_array($key,self::$_dateTimeGroups)) { + // Remove any invalid entries from the value array + unset($pValue[$key]); + } else { + // Work out what the dateTime grouping will be + $grouping = max($grouping,array_search($key,self::$_dateTimeGroups)); + } + } + if (count($pValue) == 0) { + throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.'); + } + // Set the dateTime grouping that we've anticipated + $this->setGrouping(self::$_dateTimeGroups[$grouping]); + } + $this->_value = $pValue; + + return $this; + } + + /** + * Get AutoFilter Rule Operator + * + * @return string + */ + public function getOperator() { + return $this->_operator; + } + + /** + * Set AutoFilter Rule Operator + * + * @param string $pOperator + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) { + if (empty($pOperator)) + $pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL; + if ((!in_array($pOperator,self::$_operators)) && + (!in_array($pOperator,self::$_topTenValue))) { + throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.'); + } + $this->_operator = $pOperator; + + return $this; + } + + /** + * Get AutoFilter Rule Grouping + * + * @return string + */ + public function getGrouping() { + return $this->_grouping; + } + + /** + * Set AutoFilter Rule Grouping + * + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setGrouping($pGrouping = NULL) { + if (($pGrouping !== NULL) && + (!in_array($pGrouping,self::$_dateTimeGroups)) && + (!in_array($pGrouping,self::$_dynamicTypes)) && + (!in_array($pGrouping,self::$_topTenType))) { + throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.'); + } + + $this->_grouping = $pGrouping; + + return $this; + } + + /** + * Set AutoFilter Rule + * + * @param string $pOperator + * @param string|string[] $pValue + * @param string $pGrouping + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) { + $this->setOperator($pOperator); + $this->setValue($pValue); + // Only set grouping if it's been passed in as a user-supplied argument, + // otherwise we're calculating it when we setValue() and don't want to overwrite that + // If the user supplies an argumnet for grouping, then on their own head be it + if ($pGrouping !== NULL) + $this->setGrouping($pGrouping); + + return $this; + } + + /** + * Get this Rule's AutoFilter Column Parent + * + * @return PHPExcel_Worksheet_AutoFilter_Column + */ + public function getParent() { + return $this->_parent; + } + + /** + * Set this Rule's AutoFilter Column Parent + * + * @param PHPExcel_Worksheet_AutoFilter_Column + * @return PHPExcel_Worksheet_AutoFilter_Column_Rule + */ + public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) { + $this->_parent = $pParent; + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + if ($key == '_parent') { + // Detach from autofilter column parent + $this->$key = NULL; + } else { + $this->$key = clone $value; + } + } else { + $this->$key = $value; + } + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/BaseDrawing.php b/extend/phpexcel/PHPExcel/Worksheet/BaseDrawing.php new file mode 100755 index 0000000..4db0f88 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/BaseDrawing.php @@ -0,0 +1,485 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_BaseDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /** + * Image counter + * + * @var int + */ + private static $_imageCounter = 0; + + /** + * Image index + * + * @var int + */ + private $_imageIndex = 0; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Description + * + * @var string + */ + protected $_description; + + /** + * Worksheet + * + * @var PHPExcel_Worksheet + */ + protected $_worksheet; + + /** + * Coordinates + * + * @var string + */ + protected $_coordinates; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; + + /** + * Rotation + * + * @var int + */ + protected $_rotation; + + /** + * Shadow + * + * @var PHPExcel_Worksheet_Drawing_Shadow + */ + protected $_shadow; + + /** + * Create a new PHPExcel_Worksheet_BaseDrawing + */ + public function __construct() + { + // Initialise values + $this->_name = ''; + $this->_description = ''; + $this->_worksheet = null; + $this->_coordinates = 'A1'; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; + $this->_rotation = 0; + $this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); + + // Set image index + self::$_imageCounter++; + $this->_imageIndex = self::$_imageCounter; + } + + /** + * Get image index + * + * @return int + */ + public function getImageIndex() { + return $this->_imageIndex; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setName($pValue = '') { + $this->_name = $pValue; + return $this; + } + + /** + * Get Description + * + * @return string + */ + public function getDescription() { + return $this->_description; + } + + /** + * Set Description + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setDescription($pValue = '') { + $this->_description = $pValue; + return $this; + } + + /** + * Get Worksheet + * + * @return PHPExcel_Worksheet + */ + public function getWorksheet() { + return $this->_worksheet; + } + + /** + * Set Worksheet + * + * @param PHPExcel_Worksheet $pValue + * @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { + if (is_null($this->_worksheet)) { + // Add drawing to PHPExcel_Worksheet + $this->_worksheet = $pValue; + $this->_worksheet->getCell($this->_coordinates); + $this->_worksheet->getDrawingCollection()->append($this); + } else { + if ($pOverrideOld) { + // Remove drawing from old PHPExcel_Worksheet + $iterator = $this->_worksheet->getDrawingCollection()->getIterator(); + + while ($iterator->valid()) { + if ($iterator->current()->getHashCode() == $this->getHashCode()) { + $this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); + $this->_worksheet = null; + break; + } + } + + // Set new PHPExcel_Worksheet + $this->setWorksheet($pValue); + } else { + throw new PHPExcel_Exception("A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet."); + } + } + return $this; + } + + /** + * Get Coordinates + * + * @return string + */ + public function getCoordinates() { + return $this->_coordinates; + } + + /** + * Set Coordinates + * + * @param string $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setCoordinates($pValue = 'A1') { + $this->_coordinates = $pValue; + return $this; + } + + /** + * Get OffsetX + * + * @return int + */ + public function getOffsetX() { + return $this->_offsetX; + } + + /** + * Set OffsetX + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setOffsetX($pValue = 0) { + $this->_offsetX = $pValue; + return $this; + } + + /** + * Get OffsetY + * + * @return int + */ + public function getOffsetY() { + return $this->_offsetY; + } + + /** + * Set OffsetY + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setOffsetY($pValue = 0) { + $this->_offsetY = $pValue; + return $this; + } + + /** + * Get Width + * + * @return int + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWidth($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_height / $this->_width; + $this->_height = round($ratio * $pValue); + } + + // Set width + $this->_width = $pValue; + + return $this; + } + + /** + * Get Height + * + * @return int + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setHeight($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_width = round($ratio * $pValue); + } + + // Set height + $this->_height = $pValue; + + return $this; + } + + /** + * Set width and height with proportional resize + * Example: + * <code> + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * </code> + * + * @author Vincent@luo MSN:kele_100@hotmail.com + * @param int $width + * @param int $height + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / $this->_width; + $yratio = $height / $this->_height; + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } + return $this; + } + + /** + * Get ResizeProportional + * + * @return boolean + */ + public function getResizeProportional() { + return $this->_resizeProportional; + } + + /** + * Set ResizeProportional + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setResizeProportional($pValue = true) { + $this->_resizeProportional = $pValue; + return $this; + } + + /** + * Get Rotation + * + * @return int + */ + public function getRotation() { + return $this->_rotation; + } + + /** + * Set Rotation + * + * @param int $pValue + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setRotation($pValue = 0) { + $this->_rotation = $pValue; + return $this; + } + + /** + * Get Shadow + * + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function getShadow() { + return $this->_shadow; + } + + /** + * Set Shadow + * + * @param PHPExcel_Worksheet_Drawing_Shadow $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_BaseDrawing + */ + public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { + $this->_shadow = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_name + . $this->_description + . $this->_worksheet->getHashCode() + . $this->_coordinates + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . $this->_rotation + . $this->_shadow->getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/CellIterator.php b/extend/phpexcel/PHPExcel/Worksheet/CellIterator.php new file mode 100755 index 0000000..4b96816 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/CellIterator.php @@ -0,0 +1,161 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_CellIterator + * + * Used to iterate rows in a PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_CellIterator implements Iterator +{ + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $_subject; + + /** + * Row index + * + * @var int + */ + private $_rowIndex; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 0; + + /** + * Loop only existing cells + * + * @var boolean + */ + private $_onlyExistingCells = true; + + /** + * Create a new cell iterator + * + * @param PHPExcel_Worksheet $subject + * @param int $rowIndex + */ + public function __construct(PHPExcel_Worksheet $subject = null, $rowIndex = 1) { + // Set subject and row index + $this->_subject = $subject; + $this->_rowIndex = $rowIndex; + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * Rewind iterator + */ + public function rewind() { + $this->_position = 0; + } + + /** + * Current PHPExcel_Cell + * + * @return PHPExcel_Cell + */ + public function current() { + return $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex); + } + + /** + * Current key + * + * @return int + */ + public function key() { + return $this->_position; + } + + /** + * Next value + */ + public function next() { + ++$this->_position; + } + + /** + * Are there any more PHPExcel_Cell instances available? + * + * @return boolean + */ + public function valid() { + // columnIndexFromString() returns an index based at one, + // treat it as a count when comparing it to the base zero + // position. + $columnCount = PHPExcel_Cell::columnIndexFromString($this->_subject->getHighestColumn()); + + if ($this->_onlyExistingCells) { + // If we aren't looking at an existing cell, either + // because the first column doesn't exist or next() has + // been called onto a nonexistent cell, then loop until we + // find one, or pass the last column. + while ($this->_position < $columnCount && + !$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) { + ++$this->_position; + } + } + + return $this->_position < $columnCount; + } + + /** + * Get loop only existing cells + * + * @return boolean + */ + public function getIterateOnlyExistingCells() { + return $this->_onlyExistingCells; + } + + /** + * Set the iterator to loop only existing cells + * + * @param boolean $value + */ + public function setIterateOnlyExistingCells($value = true) { + $this->_onlyExistingCells = $value; + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/ColumnDimension.php b/extend/phpexcel/PHPExcel/Worksheet/ColumnDimension.php new file mode 100755 index 0000000..79db1c5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/ColumnDimension.php @@ -0,0 +1,266 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_ColumnDimension + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_ColumnDimension +{ + /** + * Column index + * + * @var int + */ + private $_columnIndex; + + /** + * Column width + * + * When this is set to a negative value, the column width should be ignored by IWriter + * + * @var double + */ + private $_width = -1; + + /** + * Auto size? + * + * @var bool + */ + private $_autoSize = false; + + /** + * Visible? + * + * @var bool + */ + private $_visible = true; + + /** + * Outline level + * + * @var int + */ + private $_outlineLevel = 0; + + /** + * Collapsed + * + * @var bool + */ + private $_collapsed = false; + + /** + * Index to cellXf + * + * @var int + */ + private $_xfIndex; + + /** + * Create a new PHPExcel_Worksheet_ColumnDimension + * + * @param string $pIndex Character column index + */ + public function __construct($pIndex = 'A') + { + // Initialise values + $this->_columnIndex = $pIndex; + + // set default index to cellXf + $this->_xfIndex = 0; + } + + /** + * Get ColumnIndex + * + * @return string + */ + public function getColumnIndex() { + return $this->_columnIndex; + } + + /** + * Set ColumnIndex + * + * @param string $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setColumnIndex($pValue) { + $this->_columnIndex = $pValue; + return $this; + } + + /** + * Get Width + * + * @return double + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param double $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setWidth($pValue = -1) { + $this->_width = $pValue; + return $this; + } + + /** + * Get Auto Size + * + * @return bool + */ + public function getAutoSize() { + return $this->_autoSize; + } + + /** + * Set Auto Size + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setAutoSize($pValue = false) { + $this->_autoSize = $pValue; + return $this; + } + + /** + * Get Visible + * + * @return bool + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setVisible($pValue = true) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Outline Level + * + * @return int + */ + public function getOutlineLevel() { + return $this->_outlineLevel; + } + + /** + * Set Outline Level + * + * Value must be between 0 and 7 + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setOutlineLevel($pValue) { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } + + $this->_outlineLevel = $pValue; + return $this; + } + + /** + * Get Collapsed + * + * @return bool + */ + public function getCollapsed() { + return $this->_collapsed; + } + + /** + * Set Collapsed + * + * @param bool $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setCollapsed($pValue = true) { + $this->_collapsed = $pValue; + return $this; + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_ColumnDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/Drawing.php b/extend/phpexcel/PHPExcel/Worksheet/Drawing.php new file mode 100755 index 0000000..56f0cfd --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/Drawing.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Drawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Create a new PHPExcel_Worksheet_Drawing + */ + public function __construct() + { + // Initialise values + $this->_path = ''; + + // Initialize parent + parent::__construct(); + } + + /** + * Get Filename + * + * @return string + */ + public function getFilename() { + return basename($this->_path); + } + + /** + * Get indexed filename (using image index) + * + * @return string + */ + public function getIndexedFilename() { + $fileName = $this->getFilename(); + $fileName = str_replace(' ', '_', $fileName); + return str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension(); + } + + /** + * Get Extension + * + * @return string + */ + public function getExtension() { + $exploded = explode(".", basename($this->_path)); + return $exploded[count($exploded) - 1]; + } + + /** + * Get Path + * + * @return string + */ + public function getPath() { + return $this->_path; + } + + /** + * Set Path + * + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_Drawing + */ + public function setPath($pValue = '', $pVerifyFile = true) { + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; + + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . parent::getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php b/extend/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php new file mode 100755 index 0000000..5df4489 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/Drawing/Shadow.php @@ -0,0 +1,288 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Drawing_Shadow + * + * @category PHPExcel + * @package PHPExcel_Worksheet_Drawing + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable +{ + /* Shadow alignment */ + const SHADOW_BOTTOM = 'b'; + const SHADOW_BOTTOM_LEFT = 'bl'; + const SHADOW_BOTTOM_RIGHT = 'br'; + const SHADOW_CENTER = 'ctr'; + const SHADOW_LEFT = 'l'; + const SHADOW_TOP = 't'; + const SHADOW_TOP_LEFT = 'tl'; + const SHADOW_TOP_RIGHT = 'tr'; + + /** + * Visible + * + * @var boolean + */ + private $_visible; + + /** + * Blur radius + * + * Defaults to 6 + * + * @var int + */ + private $_blurRadius; + + /** + * Shadow distance + * + * Defaults to 2 + * + * @var int + */ + private $_distance; + + /** + * Shadow direction (in degrees) + * + * @var int + */ + private $_direction; + + /** + * Shadow alignment + * + * @var int + */ + private $_alignment; + + /** + * Color + * + * @var PHPExcel_Style_Color + */ + private $_color; + + /** + * Alpha + * + * @var int + */ + private $_alpha; + + /** + * Create a new PHPExcel_Worksheet_Drawing_Shadow + */ + public function __construct() + { + // Initialise values + $this->_visible = false; + $this->_blurRadius = 6; + $this->_distance = 2; + $this->_direction = 0; + $this->_alignment = PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT; + $this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK); + $this->_alpha = 50; + } + + /** + * Get Visible + * + * @return boolean + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setVisible($pValue = false) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Blur radius + * + * @return int + */ + public function getBlurRadius() { + return $this->_blurRadius; + } + + /** + * Set Blur radius + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setBlurRadius($pValue = 6) { + $this->_blurRadius = $pValue; + return $this; + } + + /** + * Get Shadow distance + * + * @return int + */ + public function getDistance() { + return $this->_distance; + } + + /** + * Set Shadow distance + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setDistance($pValue = 2) { + $this->_distance = $pValue; + return $this; + } + + /** + * Get Shadow direction (in degrees) + * + * @return int + */ + public function getDirection() { + return $this->_direction; + } + + /** + * Set Shadow direction (in degrees) + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setDirection($pValue = 0) { + $this->_direction = $pValue; + return $this; + } + + /** + * Get Shadow alignment + * + * @return int + */ + public function getAlignment() { + return $this->_alignment; + } + + /** + * Set Shadow alignment + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setAlignment($pValue = 0) { + $this->_alignment = $pValue; + return $this; + } + + /** + * Get Color + * + * @return PHPExcel_Style_Color + */ + public function getColor() { + return $this->_color; + } + + /** + * Set Color + * + * @param PHPExcel_Style_Color $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setColor(PHPExcel_Style_Color $pValue = null) { + $this->_color = $pValue; + return $this; + } + + /** + * Get Alpha + * + * @return int + */ + public function getAlpha() { + return $this->_alpha; + } + + /** + * Set Alpha + * + * @param int $pValue + * @return PHPExcel_Worksheet_Drawing_Shadow + */ + public function setAlpha($pValue = 0) { + $this->_alpha = $pValue; + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + ($this->_visible ? 't' : 'f') + . $this->_blurRadius + . $this->_distance + . $this->_direction + . $this->_alignment + . $this->_color->getHashCode() + . $this->_alpha + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/HeaderFooter.php b/extend/phpexcel/PHPExcel/Worksheet/HeaderFooter.php new file mode 100755 index 0000000..82d7faf --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/HeaderFooter.php @@ -0,0 +1,465 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_HeaderFooter + * + * <code> + * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970: + * + * There are a number of formatting codes that can be written inline with the actual header / footer text, which + * affect the formatting in the header or footer. + * + * Example: This example shows the text "Center Bold Header" on the first line (center section), and the date on + * the second line (center section). + * &CCenter &"-,Bold"Bold&"-,Regular"Header_x000A_&D + * + * General Rules: + * There is no required order in which these codes must appear. + * + * The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again: + * - strikethrough + * - superscript + * - subscript + * Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored, + * while the first is ON. + * &L - code for "left section" (there are three header / footer locations, "left", "center", and "right"). When + * two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the + * order of appearance, and placed into the left section. + * &P - code for "current page #" + * &N - code for "total pages" + * &font size - code for "text font size", where font size is a font size in points. + * &K - code for "text font color" + * RGB Color is specified as RRGGBB + * Theme Color is specifed as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade + * value, NN is the tint/shade value. + * &S - code for "text strikethrough" on / off + * &X - code for "text super script" on / off + * &Y - code for "text subscript" on / off + * &C - code for "center section". When two or more occurrences of this section marker exist, the contents + * from all markers are concatenated, in the order of appearance, and placed into the center section. + * + * &D - code for "date" + * &T - code for "time" + * &G - code for "picture as background" + * &U - code for "text single underline" + * &E - code for "double underline" + * &R - code for "right section". When two or more occurrences of this section marker exist, the contents + * from all markers are concatenated, in the order of appearance, and placed into the right section. + * &Z - code for "this workbook's file path" + * &F - code for "this workbook's file name" + * &A - code for "sheet tab name" + * &+ - code for add to page #. + * &- - code for subtract from page #. + * &"font name,font type" - code for "text font name" and "text font type", where font name and font type + * are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font + * name, it means "none specified". Both of font name and font type can be localized values. + * &"-,Bold" - code for "bold font style" + * &B - also means "bold font style". + * &"-,Regular" - code for "regular font style" + * &"-,Italic" - code for "italic font style" + * &I - also means "italic font style" + * &"-,Bold Italic" code for "bold italic font style" + * &O - code for "outline style" + * &H - code for "shadow style" + * </code> + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_HeaderFooter +{ + /* Header/footer image location */ + const IMAGE_HEADER_LEFT = 'LH'; + const IMAGE_HEADER_CENTER = 'CH'; + const IMAGE_HEADER_RIGHT = 'RH'; + const IMAGE_FOOTER_LEFT = 'LF'; + const IMAGE_FOOTER_CENTER = 'CF'; + const IMAGE_FOOTER_RIGHT = 'RF'; + + /** + * OddHeader + * + * @var string + */ + private $_oddHeader = ''; + + /** + * OddFooter + * + * @var string + */ + private $_oddFooter = ''; + + /** + * EvenHeader + * + * @var string + */ + private $_evenHeader = ''; + + /** + * EvenFooter + * + * @var string + */ + private $_evenFooter = ''; + + /** + * FirstHeader + * + * @var string + */ + private $_firstHeader = ''; + + /** + * FirstFooter + * + * @var string + */ + private $_firstFooter = ''; + + /** + * Different header for Odd/Even, defaults to false + * + * @var boolean + */ + private $_differentOddEven = false; + + /** + * Different header for first page, defaults to false + * + * @var boolean + */ + private $_differentFirst = false; + + /** + * Scale with document, defaults to true + * + * @var boolean + */ + private $_scaleWithDocument = true; + + /** + * Align with margins, defaults to true + * + * @var boolean + */ + private $_alignWithMargins = true; + + /** + * Header/footer images + * + * @var PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + private $_headerFooterImages = array(); + + /** + * Create a new PHPExcel_Worksheet_HeaderFooter + */ + public function __construct() + { + } + + /** + * Get OddHeader + * + * @return string + */ + public function getOddHeader() { + return $this->_oddHeader; + } + + /** + * Set OddHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setOddHeader($pValue) { + $this->_oddHeader = $pValue; + return $this; + } + + /** + * Get OddFooter + * + * @return string + */ + public function getOddFooter() { + return $this->_oddFooter; + } + + /** + * Set OddFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setOddFooter($pValue) { + $this->_oddFooter = $pValue; + return $this; + } + + /** + * Get EvenHeader + * + * @return string + */ + public function getEvenHeader() { + return $this->_evenHeader; + } + + /** + * Set EvenHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setEvenHeader($pValue) { + $this->_evenHeader = $pValue; + return $this; + } + + /** + * Get EvenFooter + * + * @return string + */ + public function getEvenFooter() { + return $this->_evenFooter; + } + + /** + * Set EvenFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setEvenFooter($pValue) { + $this->_evenFooter = $pValue; + return $this; + } + + /** + * Get FirstHeader + * + * @return string + */ + public function getFirstHeader() { + return $this->_firstHeader; + } + + /** + * Set FirstHeader + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstHeader($pValue) { + $this->_firstHeader = $pValue; + return $this; + } + + /** + * Get FirstFooter + * + * @return string + */ + public function getFirstFooter() { + return $this->_firstFooter; + } + + /** + * Set FirstFooter + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstFooter($pValue) { + $this->_firstFooter = $pValue; + return $this; + } + + /** + * Get DifferentOddEven + * + * @return boolean + */ + public function getDifferentOddEven() { + return $this->_differentOddEven; + } + + /** + * Set DifferentOddEven + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setDifferentOddEven($pValue = false) { + $this->_differentOddEven = $pValue; + return $this; + } + + /** + * Get DifferentFirst + * + * @return boolean + */ + public function getDifferentFirst() { + return $this->_differentFirst; + } + + /** + * Set DifferentFirst + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setDifferentFirst($pValue = false) { + $this->_differentFirst = $pValue; + return $this; + } + + /** + * Get ScaleWithDocument + * + * @return boolean + */ + public function getScaleWithDocument() { + return $this->_scaleWithDocument; + } + + /** + * Set ScaleWithDocument + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setScaleWithDocument($pValue = true) { + $this->_scaleWithDocument = $pValue; + return $this; + } + + /** + * Get AlignWithMargins + * + * @return boolean + */ + public function getAlignWithMargins() { + return $this->_alignWithMargins; + } + + /** + * Set AlignWithMargins + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setAlignWithMargins($pValue = true) { + $this->_alignWithMargins = $pValue; + return $this; + } + + /** + * Add header/footer image + * + * @param PHPExcel_Worksheet_HeaderFooterDrawing $image + * @param string $location + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) { + $this->_headerFooterImages[$location] = $image; + return $this; + } + + /** + * Remove header/footer image + * + * @param string $location + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function removeImage($location = self::IMAGE_HEADER_LEFT) { + if (isset($this->_headerFooterImages[$location])) { + unset($this->_headerFooterImages[$location]); + } + return $this; + } + + /** + * Set header/footer images + * + * @param PHPExcel_Worksheet_HeaderFooterDrawing[] $images + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setImages($images) { + if (!is_array($images)) { + throw new PHPExcel_Exception('Invalid parameter!'); + } + + $this->_headerFooterImages = $images; + return $this; + } + + /** + * Get header/footer images + * + * @return PHPExcel_Worksheet_HeaderFooterDrawing[] + */ + public function getImages() { + // Sort array + $images = array(); + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) $images[self::IMAGE_HEADER_LEFT] = $this->_headerFooterImages[self::IMAGE_HEADER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) $images[self::IMAGE_HEADER_CENTER] = $this->_headerFooterImages[self::IMAGE_HEADER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) $images[self::IMAGE_HEADER_RIGHT] = $this->_headerFooterImages[self::IMAGE_HEADER_RIGHT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) $images[self::IMAGE_FOOTER_LEFT] = $this->_headerFooterImages[self::IMAGE_FOOTER_LEFT]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) $images[self::IMAGE_FOOTER_CENTER] = $this->_headerFooterImages[self::IMAGE_FOOTER_CENTER]; + if (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) $images[self::IMAGE_FOOTER_RIGHT] = $this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT]; + $this->_headerFooterImages = $images; + + return $this->_headerFooterImages; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php b/extend/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php new file mode 100755 index 0000000..1c6f4e1 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/HeaderFooterDrawing.php @@ -0,0 +1,350 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_HeaderFooterDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable +{ + /** + * Path + * + * @var string + */ + private $_path; + + /** + * Name + * + * @var string + */ + protected $_name; + + /** + * Offset X + * + * @var int + */ + protected $_offsetX; + + /** + * Offset Y + * + * @var int + */ + protected $_offsetY; + + /** + * Width + * + * @var int + */ + protected $_width; + + /** + * Height + * + * @var int + */ + protected $_height; + + /** + * Proportional resize + * + * @var boolean + */ + protected $_resizeProportional; + + /** + * Create a new PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function __construct() + { + // Initialise values + $this->_path = ''; + $this->_name = ''; + $this->_offsetX = 0; + $this->_offsetY = 0; + $this->_width = 0; + $this->_height = 0; + $this->_resizeProportional = true; + } + + /** + * Get Name + * + * @return string + */ + public function getName() { + return $this->_name; + } + + /** + * Set Name + * + * @param string $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setName($pValue = '') { + $this->_name = $pValue; + return $this; + } + + /** + * Get OffsetX + * + * @return int + */ + public function getOffsetX() { + return $this->_offsetX; + } + + /** + * Set OffsetX + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setOffsetX($pValue = 0) { + $this->_offsetX = $pValue; + return $this; + } + + /** + * Get OffsetY + * + * @return int + */ + public function getOffsetY() { + return $this->_offsetY; + } + + /** + * Set OffsetY + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setOffsetY($pValue = 0) { + $this->_offsetY = $pValue; + return $this; + } + + /** + * Get Width + * + * @return int + */ + public function getWidth() { + return $this->_width; + } + + /** + * Set Width + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setWidth($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_height = round($ratio * $pValue); + } + + // Set width + $this->_width = $pValue; + + return $this; + } + + /** + * Get Height + * + * @return int + */ + public function getHeight() { + return $this->_height; + } + + /** + * Set Height + * + * @param int $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setHeight($pValue = 0) { + // Resize proportional? + if ($this->_resizeProportional && $pValue != 0) { + $ratio = $this->_width / $this->_height; + $this->_width = round($ratio * $pValue); + } + + // Set height + $this->_height = $pValue; + + return $this; + } + + /** + * Set width and height with proportional resize + * Example: + * <code> + * $objDrawing->setResizeProportional(true); + * $objDrawing->setWidthAndHeight(160,120); + * </code> + * + * @author Vincent@luo MSN:kele_100@hotmail.com + * @param int $width + * @param int $height + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setWidthAndHeight($width = 0, $height = 0) { + $xratio = $width / $this->_width; + $yratio = $height / $this->_height; + if ($this->_resizeProportional && !($width == 0 || $height == 0)) { + if (($xratio * $this->_height) < $height) { + $this->_height = ceil($xratio * $this->_height); + $this->_width = $width; + } else { + $this->_width = ceil($yratio * $this->_width); + $this->_height = $height; + } + } + return $this; + } + + /** + * Get ResizeProportional + * + * @return boolean + */ + public function getResizeProportional() { + return $this->_resizeProportional; + } + + /** + * Set ResizeProportional + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setResizeProportional($pValue = true) { + $this->_resizeProportional = $pValue; + return $this; + } + + /** + * Get Filename + * + * @return string + */ + public function getFilename() { + return basename($this->_path); + } + + /** + * Get Extension + * + * @return string + */ + public function getExtension() { + $parts = explode(".", basename($this->_path)); + return end($parts); + } + + /** + * Get Path + * + * @return string + */ + public function getPath() { + return $this->_path; + } + + /** + * Set Path + * + * @param string $pValue File path + * @param boolean $pVerifyFile Verify file + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_HeaderFooterDrawing + */ + public function setPath($pValue = '', $pVerifyFile = true) { + if ($pVerifyFile) { + if (file_exists($pValue)) { + $this->_path = $pValue; + + if ($this->_width == 0 && $this->_height == 0) { + // Get width/height + list($this->_width, $this->_height) = getimagesize($pValue); + } + } else { + throw new PHPExcel_Exception("File $pValue not found!"); + } + } else { + $this->_path = $pValue; + } + return $this; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_path + . $this->_name + . $this->_offsetX + . $this->_offsetY + . $this->_width + . $this->_height + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php b/extend/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php new file mode 100755 index 0000000..93266d2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/MemoryDrawing.php @@ -0,0 +1,200 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_MemoryDrawing + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable +{ + /* Rendering functions */ + const RENDERING_DEFAULT = 'imagepng'; + const RENDERING_PNG = 'imagepng'; + const RENDERING_GIF = 'imagegif'; + const RENDERING_JPEG = 'imagejpeg'; + + /* MIME types */ + const MIMETYPE_DEFAULT = 'image/png'; + const MIMETYPE_PNG = 'image/png'; + const MIMETYPE_GIF = 'image/gif'; + const MIMETYPE_JPEG = 'image/jpeg'; + + /** + * Image resource + * + * @var resource + */ + private $_imageResource; + + /** + * Rendering function + * + * @var string + */ + private $_renderingFunction; + + /** + * Mime type + * + * @var string + */ + private $_mimeType; + + /** + * Unique name + * + * @var string + */ + private $_uniqueName; + + /** + * Create a new PHPExcel_Worksheet_MemoryDrawing + */ + public function __construct() + { + // Initialise values + $this->_imageResource = null; + $this->_renderingFunction = self::RENDERING_DEFAULT; + $this->_mimeType = self::MIMETYPE_DEFAULT; + $this->_uniqueName = md5(rand(0, 9999). time() . rand(0, 9999)); + + // Initialize parent + parent::__construct(); + } + + /** + * Get image resource + * + * @return resource + */ + public function getImageResource() { + return $this->_imageResource; + } + + /** + * Set image resource + * + * @param $value resource + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setImageResource($value = null) { + $this->_imageResource = $value; + + if (!is_null($this->_imageResource)) { + // Get width/height + $this->_width = imagesx($this->_imageResource); + $this->_height = imagesy($this->_imageResource); + } + return $this; + } + + /** + * Get rendering function + * + * @return string + */ + public function getRenderingFunction() { + return $this->_renderingFunction; + } + + /** + * Set rendering function + * + * @param string $value + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) { + $this->_renderingFunction = $value; + return $this; + } + + /** + * Get mime type + * + * @return string + */ + public function getMimeType() { + return $this->_mimeType; + } + + /** + * Set mime type + * + * @param string $value + * @return PHPExcel_Worksheet_MemoryDrawing + */ + public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) { + $this->_mimeType = $value; + return $this; + } + + /** + * Get indexed filename (using image index) + * + * @return string + */ + public function getIndexedFilename() { + $extension = strtolower($this->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; + + return $this->_uniqueName . $this->getImageIndex() . '.' . $extension; + } + + /** + * Get hash code + * + * @return string Hash code + */ + public function getHashCode() { + return md5( + $this->_renderingFunction + . $this->_mimeType + . $this->_uniqueName + . parent::getHashCode() + . __CLASS__ + ); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/PageMargins.php b/extend/phpexcel/PHPExcel/Worksheet/PageMargins.php new file mode 100755 index 0000000..671711f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/PageMargins.php @@ -0,0 +1,220 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_PageMargins + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_PageMargins +{ + /** + * Left + * + * @var double + */ + private $_left = 0.7; + + /** + * Right + * + * @var double + */ + private $_right = 0.7; + + /** + * Top + * + * @var double + */ + private $_top = 0.75; + + /** + * Bottom + * + * @var double + */ + private $_bottom = 0.75; + + /** + * Header + * + * @var double + */ + private $_header = 0.3; + + /** + * Footer + * + * @var double + */ + private $_footer = 0.3; + + /** + * Create a new PHPExcel_Worksheet_PageMargins + */ + public function __construct() + { + } + + /** + * Get Left + * + * @return double + */ + public function getLeft() { + return $this->_left; + } + + /** + * Set Left + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setLeft($pValue) { + $this->_left = $pValue; + return $this; + } + + /** + * Get Right + * + * @return double + */ + public function getRight() { + return $this->_right; + } + + /** + * Set Right + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setRight($pValue) { + $this->_right = $pValue; + return $this; + } + + /** + * Get Top + * + * @return double + */ + public function getTop() { + return $this->_top; + } + + /** + * Set Top + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setTop($pValue) { + $this->_top = $pValue; + return $this; + } + + /** + * Get Bottom + * + * @return double + */ + public function getBottom() { + return $this->_bottom; + } + + /** + * Set Bottom + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setBottom($pValue) { + $this->_bottom = $pValue; + return $this; + } + + /** + * Get Header + * + * @return double + */ + public function getHeader() { + return $this->_header; + } + + /** + * Set Header + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setHeader($pValue) { + $this->_header = $pValue; + return $this; + } + + /** + * Get Footer + * + * @return double + */ + public function getFooter() { + return $this->_footer; + } + + /** + * Set Footer + * + * @param double $pValue + * @return PHPExcel_Worksheet_PageMargins + */ + public function setFooter($pValue) { + $this->_footer = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/PageSetup.php b/extend/phpexcel/PHPExcel/Worksheet/PageSetup.php new file mode 100755 index 0000000..9512dbe --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/PageSetup.php @@ -0,0 +1,798 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_PageSetup + * + * <code> + * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988: + * + * 1 = Letter paper (8.5 in. by 11 in.) + * 2 = Letter small paper (8.5 in. by 11 in.) + * 3 = Tabloid paper (11 in. by 17 in.) + * 4 = Ledger paper (17 in. by 11 in.) + * 5 = Legal paper (8.5 in. by 14 in.) + * 6 = Statement paper (5.5 in. by 8.5 in.) + * 7 = Executive paper (7.25 in. by 10.5 in.) + * 8 = A3 paper (297 mm by 420 mm) + * 9 = A4 paper (210 mm by 297 mm) + * 10 = A4 small paper (210 mm by 297 mm) + * 11 = A5 paper (148 mm by 210 mm) + * 12 = B4 paper (250 mm by 353 mm) + * 13 = B5 paper (176 mm by 250 mm) + * 14 = Folio paper (8.5 in. by 13 in.) + * 15 = Quarto paper (215 mm by 275 mm) + * 16 = Standard paper (10 in. by 14 in.) + * 17 = Standard paper (11 in. by 17 in.) + * 18 = Note paper (8.5 in. by 11 in.) + * 19 = #9 envelope (3.875 in. by 8.875 in.) + * 20 = #10 envelope (4.125 in. by 9.5 in.) + * 21 = #11 envelope (4.5 in. by 10.375 in.) + * 22 = #12 envelope (4.75 in. by 11 in.) + * 23 = #14 envelope (5 in. by 11.5 in.) + * 24 = C paper (17 in. by 22 in.) + * 25 = D paper (22 in. by 34 in.) + * 26 = E paper (34 in. by 44 in.) + * 27 = DL envelope (110 mm by 220 mm) + * 28 = C5 envelope (162 mm by 229 mm) + * 29 = C3 envelope (324 mm by 458 mm) + * 30 = C4 envelope (229 mm by 324 mm) + * 31 = C6 envelope (114 mm by 162 mm) + * 32 = C65 envelope (114 mm by 229 mm) + * 33 = B4 envelope (250 mm by 353 mm) + * 34 = B5 envelope (176 mm by 250 mm) + * 35 = B6 envelope (176 mm by 125 mm) + * 36 = Italy envelope (110 mm by 230 mm) + * 37 = Monarch envelope (3.875 in. by 7.5 in.). + * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.) + * 39 = US standard fanfold (14.875 in. by 11 in.) + * 40 = German standard fanfold (8.5 in. by 12 in.) + * 41 = German legal fanfold (8.5 in. by 13 in.) + * 42 = ISO B4 (250 mm by 353 mm) + * 43 = Japanese double postcard (200 mm by 148 mm) + * 44 = Standard paper (9 in. by 11 in.) + * 45 = Standard paper (10 in. by 11 in.) + * 46 = Standard paper (15 in. by 11 in.) + * 47 = Invite envelope (220 mm by 220 mm) + * 50 = Letter extra paper (9.275 in. by 12 in.) + * 51 = Legal extra paper (9.275 in. by 15 in.) + * 52 = Tabloid extra paper (11.69 in. by 18 in.) + * 53 = A4 extra paper (236 mm by 322 mm) + * 54 = Letter transverse paper (8.275 in. by 11 in.) + * 55 = A4 transverse paper (210 mm by 297 mm) + * 56 = Letter extra transverse paper (9.275 in. by 12 in.) + * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm) + * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm) + * 59 = Letter plus paper (8.5 in. by 12.69 in.) + * 60 = A4 plus paper (210 mm by 330 mm) + * 61 = A5 transverse paper (148 mm by 210 mm) + * 62 = JIS B5 transverse paper (182 mm by 257 mm) + * 63 = A3 extra paper (322 mm by 445 mm) + * 64 = A5 extra paper (174 mm by 235 mm) + * 65 = ISO B5 extra paper (201 mm by 276 mm) + * 66 = A2 paper (420 mm by 594 mm) + * 67 = A3 transverse paper (297 mm by 420 mm) + * 68 = A3 extra transverse paper (322 mm by 445 mm) + * </code> + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_PageSetup +{ + /* Paper size */ + const PAPERSIZE_LETTER = 1; + const PAPERSIZE_LETTER_SMALL = 2; + const PAPERSIZE_TABLOID = 3; + const PAPERSIZE_LEDGER = 4; + const PAPERSIZE_LEGAL = 5; + const PAPERSIZE_STATEMENT = 6; + const PAPERSIZE_EXECUTIVE = 7; + const PAPERSIZE_A3 = 8; + const PAPERSIZE_A4 = 9; + const PAPERSIZE_A4_SMALL = 10; + const PAPERSIZE_A5 = 11; + const PAPERSIZE_B4 = 12; + const PAPERSIZE_B5 = 13; + const PAPERSIZE_FOLIO = 14; + const PAPERSIZE_QUARTO = 15; + const PAPERSIZE_STANDARD_1 = 16; + const PAPERSIZE_STANDARD_2 = 17; + const PAPERSIZE_NOTE = 18; + const PAPERSIZE_NO9_ENVELOPE = 19; + const PAPERSIZE_NO10_ENVELOPE = 20; + const PAPERSIZE_NO11_ENVELOPE = 21; + const PAPERSIZE_NO12_ENVELOPE = 22; + const PAPERSIZE_NO14_ENVELOPE = 23; + const PAPERSIZE_C = 24; + const PAPERSIZE_D = 25; + const PAPERSIZE_E = 26; + const PAPERSIZE_DL_ENVELOPE = 27; + const PAPERSIZE_C5_ENVELOPE = 28; + const PAPERSIZE_C3_ENVELOPE = 29; + const PAPERSIZE_C4_ENVELOPE = 30; + const PAPERSIZE_C6_ENVELOPE = 31; + const PAPERSIZE_C65_ENVELOPE = 32; + const PAPERSIZE_B4_ENVELOPE = 33; + const PAPERSIZE_B5_ENVELOPE = 34; + const PAPERSIZE_B6_ENVELOPE = 35; + const PAPERSIZE_ITALY_ENVELOPE = 36; + const PAPERSIZE_MONARCH_ENVELOPE = 37; + const PAPERSIZE_6_3_4_ENVELOPE = 38; + const PAPERSIZE_US_STANDARD_FANFOLD = 39; + const PAPERSIZE_GERMAN_STANDARD_FANFOLD = 40; + const PAPERSIZE_GERMAN_LEGAL_FANFOLD = 41; + const PAPERSIZE_ISO_B4 = 42; + const PAPERSIZE_JAPANESE_DOUBLE_POSTCARD = 43; + const PAPERSIZE_STANDARD_PAPER_1 = 44; + const PAPERSIZE_STANDARD_PAPER_2 = 45; + const PAPERSIZE_STANDARD_PAPER_3 = 46; + const PAPERSIZE_INVITE_ENVELOPE = 47; + const PAPERSIZE_LETTER_EXTRA_PAPER = 48; + const PAPERSIZE_LEGAL_EXTRA_PAPER = 49; + const PAPERSIZE_TABLOID_EXTRA_PAPER = 50; + const PAPERSIZE_A4_EXTRA_PAPER = 51; + const PAPERSIZE_LETTER_TRANSVERSE_PAPER = 52; + const PAPERSIZE_A4_TRANSVERSE_PAPER = 53; + const PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER = 54; + const PAPERSIZE_SUPERA_SUPERA_A4_PAPER = 55; + const PAPERSIZE_SUPERB_SUPERB_A3_PAPER = 56; + const PAPERSIZE_LETTER_PLUS_PAPER = 57; + const PAPERSIZE_A4_PLUS_PAPER = 58; + const PAPERSIZE_A5_TRANSVERSE_PAPER = 59; + const PAPERSIZE_JIS_B5_TRANSVERSE_PAPER = 60; + const PAPERSIZE_A3_EXTRA_PAPER = 61; + const PAPERSIZE_A5_EXTRA_PAPER = 62; + const PAPERSIZE_ISO_B5_EXTRA_PAPER = 63; + const PAPERSIZE_A2_PAPER = 64; + const PAPERSIZE_A3_TRANSVERSE_PAPER = 65; + const PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER = 66; + + /* Page orientation */ + const ORIENTATION_DEFAULT = 'default'; + const ORIENTATION_LANDSCAPE = 'landscape'; + const ORIENTATION_PORTRAIT = 'portrait'; + + /* Print Range Set Method */ + const SETPRINTRANGE_OVERWRITE = 'O'; + const SETPRINTRANGE_INSERT = 'I'; + + + /** + * Paper size + * + * @var int + */ + private $_paperSize = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER; + + /** + * Orientation + * + * @var string + */ + private $_orientation = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT; + + /** + * Scale (Print Scale) + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @var int? + */ + private $_scale = 100; + + /** + * Fit To Page + * Whether scale or fitToWith / fitToHeight applies + * + * @var boolean + */ + private $_fitToPage = FALSE; + + /** + * Fit To Height + * Number of vertical pages to fit on + * + * @var int? + */ + private $_fitToHeight = 1; + + /** + * Fit To Width + * Number of horizontal pages to fit on + * + * @var int? + */ + private $_fitToWidth = 1; + + /** + * Columns to repeat at left + * + * @var array Containing start column and end column, empty array if option unset + */ + private $_columnsToRepeatAtLeft = array('', ''); + + /** + * Rows to repeat at top + * + * @var array Containing start row number and end row number, empty array if option unset + */ + private $_rowsToRepeatAtTop = array(0, 0); + + /** + * Center page horizontally + * + * @var boolean + */ + private $_horizontalCentered = FALSE; + + /** + * Center page vertically + * + * @var boolean + */ + private $_verticalCentered = FALSE; + + /** + * Print area + * + * @var string + */ + private $_printArea = NULL; + + /** + * First page number + * + * @var int + */ + private $_firstPageNumber = NULL; + + /** + * Create a new PHPExcel_Worksheet_PageSetup + */ + public function __construct() + { + } + + /** + * Get Paper Size + * + * @return int + */ + public function getPaperSize() { + return $this->_paperSize; + } + + /** + * Set Paper Size + * + * @param int $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) { + $this->_paperSize = $pValue; + return $this; + } + + /** + * Get Orientation + * + * @return string + */ + public function getOrientation() { + return $this->_orientation; + } + + /** + * Set Orientation + * + * @param string $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) { + $this->_orientation = $pValue; + return $this; + } + + /** + * Get Scale + * + * @return int? + */ + public function getScale() { + return $this->_scale; + } + + /** + * Set Scale + * + * Print scaling. Valid values range from 10 to 400 + * This setting is overridden when fitToWidth and/or fitToHeight are in use + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so scaling applies rather than fitToHeight / fitToWidth + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setScale($pValue = 100, $pUpdate = true) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 0, where 0 results in 100 + if (($pValue >= 0) || is_null($pValue)) { + $this->_scale = $pValue; + if ($pUpdate) { + $this->_fitToPage = false; + } + } else { + throw new PHPExcel_Exception("Scale must not be negative"); + } + return $this; + } + + /** + * Get Fit To Page + * + * @return boolean + */ + public function getFitToPage() { + return $this->_fitToPage; + } + + /** + * Set Fit To Page + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToPage($pValue = TRUE) { + $this->_fitToPage = $pValue; + return $this; + } + + /** + * Get Fit To Height + * + * @return int? + */ + public function getFitToHeight() { + return $this->_fitToHeight; + } + + /** + * Set Fit To Height + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToHeight($pValue = 1, $pUpdate = TRUE) { + $this->_fitToHeight = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Get Fit To Width + * + * @return int? + */ + public function getFitToWidth() { + return $this->_fitToWidth; + } + + /** + * Set Fit To Width + * + * @param int? $pValue + * @param boolean $pUpdate Update fitToPage so it applies rather than scaling + * @return PHPExcel_Worksheet_PageSetup + */ + public function setFitToWidth($pValue = 1, $pUpdate = TRUE) { + $this->_fitToWidth = $pValue; + if ($pUpdate) { + $this->_fitToPage = TRUE; + } + return $this; + } + + /** + * Is Columns to repeat at left set? + * + * @return boolean + */ + public function isColumnsToRepeatAtLeftSet() { + if (is_array($this->_columnsToRepeatAtLeft)) { + if ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') { + return true; + } + } + + return false; + } + + /** + * Get Columns to repeat at left + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getColumnsToRepeatAtLeft() { + return $this->_columnsToRepeatAtLeft; + } + + /** + * Set Columns to repeat at left + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeft($pValue = null) { + if (is_array($pValue)) { + $this->_columnsToRepeatAtLeft = $pValue; + } + return $this; + } + + /** + * Set Columns to repeat at left by start and end + * + * @param string $pStart + * @param string $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') { + $this->_columnsToRepeatAtLeft = array($pStart, $pEnd); + return $this; + } + + /** + * Is Rows to repeat at top set? + * + * @return boolean + */ + public function isRowsToRepeatAtTopSet() { + if (is_array($this->_rowsToRepeatAtTop)) { + if ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) { + return true; + } + } + + return false; + } + + /** + * Get Rows to repeat at top + * + * @return array Containing start column and end column, empty array if option unset + */ + public function getRowsToRepeatAtTop() { + return $this->_rowsToRepeatAtTop; + } + + /** + * Set Rows to repeat at top + * + * @param array $pValue Containing start column and end column, empty array if option unset + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTop($pValue = null) { + if (is_array($pValue)) { + $this->_rowsToRepeatAtTop = $pValue; + } + return $this; + } + + /** + * Set Rows to repeat at top by start and end + * + * @param int $pStart + * @param int $pEnd + * @return PHPExcel_Worksheet_PageSetup + */ + public function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) { + $this->_rowsToRepeatAtTop = array($pStart, $pEnd); + return $this; + } + + /** + * Get center page horizontally + * + * @return bool + */ + public function getHorizontalCentered() { + return $this->_horizontalCentered; + } + + /** + * Set center page horizontally + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setHorizontalCentered($value = false) { + $this->_horizontalCentered = $value; + return $this; + } + + /** + * Get center page vertically + * + * @return bool + */ + public function getVerticalCentered() { + return $this->_verticalCentered; + } + + /** + * Set center page vertically + * + * @param bool $value + * @return PHPExcel_Worksheet_PageSetup + */ + public function setVerticalCentered($value = false) { + $this->_verticalCentered = $value; + return $this; + } + + /** + * Get print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or a index value of 0, will return all ranges as a comma-separated string + * Otherwise, the specific range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @throws PHPExcel_Exception + * @return string + */ + public function getPrintArea($index = 0) { + if ($index == 0) { + return $this->_printArea; + } + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + return $printAreas[$index-1]; + } + throw new PHPExcel_Exception("Requested Print Area does not exist"); + } + + /** + * Is print area set? + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will identify whether any print range is set + * Otherwise, existence of the range identified by the value of $index will be returned + * Print areas are numbered from 1 + * @return boolean + */ + public function isPrintAreaSet($index = 0) { + if ($index == 0) { + return !is_null($this->_printArea); + } + $printAreas = explode(',',$this->_printArea); + return isset($printAreas[$index-1]); + } + + /** + * Clear a print area + * + * @param int $index Identifier for a specific print area range if several ranges have been set + * Default behaviour, or an index value of 0, will clear all print ranges that are set + * Otherwise, the range identified by the value of $index will be removed from the series + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + */ + public function clearPrintArea($index = 0) { + if ($index == 0) { + $this->_printArea = NULL; + } else { + $printAreas = explode(',',$this->_printArea); + if (isset($printAreas[$index-1])) { + unset($printAreas[$index-1]); + $this->_printArea = implode(',',$printAreas); + } + } + + return $this; + } + + /** + * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20' + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) { + if (strpos($value,'!') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not specify a worksheet.'); + } elseif (strpos($value,':') === false) { + throw new PHPExcel_Exception('Cell coordinate must be a range of cells.'); + } elseif (strpos($value,'$') !== false) { + throw new PHPExcel_Exception('Cell coordinate must not be absolute.'); + } + $value = strtoupper($value); + + if ($method == self::SETPRINTRANGE_OVERWRITE) { + if ($index == 0) { + $this->_printArea = $value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = count($printAreas) - abs($index) + 1; + } + if (($index <= 0) || ($index > count($printAreas))) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas[$index-1] = $value; + $this->_printArea = implode(',',$printAreas); + } + } elseif($method == self::SETPRINTRANGE_INSERT) { + if ($index == 0) { + $this->_printArea .= ($this->_printArea == '') ? $value : ','.$value; + } else { + $printAreas = explode(',',$this->_printArea); + if($index < 0) { + $index = abs($index) - 1; + } + if ($index > count($printAreas)) { + throw new PHPExcel_Exception('Invalid index for setting print range.'); + } + $printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index)); + $this->_printArea = implode(',',$printAreas); + } + } else { + throw new PHPExcel_Exception('Invalid method for setting print range.'); + } + + return $this; + } + + /** + * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas + * + * @param string $value + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function addPrintArea($value, $index = -1) { + return $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Set print area + * + * @param int $column1 Column 1 + * @param int $row1 Row 1 + * @param int $column2 Column 2 + * @param int $row2 Row 2 + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * When the method is "O"verwrite, then a positive integer index will overwrite that indexed + * entry in the print areas list; a negative index value will identify which entry to + * overwrite working bacward through the print area to the list, with the last entry as -1. + * Specifying an index value of 0, will overwrite <b>all</b> existing print ranges. + * When the method is "I"nsert, then a positive index will insert after that indexed entry in + * the print areas list, while a negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @param string $method Determines the method used when setting multiple print areas + * Default behaviour, or the "O" method, overwrites existing print area + * The "I" method, inserts the new print area before any specified index, or at the end of the list + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) + { + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method); + } + + /** + * Add a new print area to the list of print areas + * + * @param int $column1 Start Column for the print area + * @param int $row1 Start Row for the print area + * @param int $column2 End Column for the print area + * @param int $row2 End Row for the print area + * @param int $index Identifier for a specific print area range allowing several ranges to be set + * A positive index will insert after that indexed entry in the print areas list, while a + * negative index will insert before the indexed entry. + * Specifying an index value of 0, will always append the new print range at the end of the + * list. + * Print areas are numbered from 1 + * @return PHPExcel_Worksheet_PageSetup + * @throws PHPExcel_Exception + */ + public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1) + { + return $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT); + } + + /** + * Get first page number + * + * @return int + */ + public function getFirstPageNumber() { + return $this->_firstPageNumber; + } + + /** + * Set first page number + * + * @param int $value + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function setFirstPageNumber($value = null) { + $this->_firstPageNumber = $value; + return $this; + } + + /** + * Reset first page number + * + * @return PHPExcel_Worksheet_HeaderFooter + */ + public function resetFirstPageNumber() { + return $this->setFirstPageNumber(null); + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/Protection.php b/extend/phpexcel/PHPExcel/Worksheet/Protection.php new file mode 100755 index 0000000..f41dd53 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/Protection.php @@ -0,0 +1,545 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Protection + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Protection +{ + /** + * Sheet + * + * @var boolean + */ + private $_sheet = false; + + /** + * Objects + * + * @var boolean + */ + private $_objects = false; + + /** + * Scenarios + * + * @var boolean + */ + private $_scenarios = false; + + /** + * Format cells + * + * @var boolean + */ + private $_formatCells = false; + + /** + * Format columns + * + * @var boolean + */ + private $_formatColumns = false; + + /** + * Format rows + * + * @var boolean + */ + private $_formatRows = false; + + /** + * Insert columns + * + * @var boolean + */ + private $_insertColumns = false; + + /** + * Insert rows + * + * @var boolean + */ + private $_insertRows = false; + + /** + * Insert hyperlinks + * + * @var boolean + */ + private $_insertHyperlinks = false; + + /** + * Delete columns + * + * @var boolean + */ + private $_deleteColumns = false; + + /** + * Delete rows + * + * @var boolean + */ + private $_deleteRows = false; + + /** + * Select locked cells + * + * @var boolean + */ + private $_selectLockedCells = false; + + /** + * Sort + * + * @var boolean + */ + private $_sort = false; + + /** + * AutoFilter + * + * @var boolean + */ + private $_autoFilter = false; + + /** + * Pivot tables + * + * @var boolean + */ + private $_pivotTables = false; + + /** + * Select unlocked cells + * + * @var boolean + */ + private $_selectUnlockedCells = false; + + /** + * Password + * + * @var string + */ + private $_password = ''; + + /** + * Create a new PHPExcel_Worksheet_Protection + */ + public function __construct() + { + } + + /** + * Is some sort of protection enabled? + * + * @return boolean + */ + function isProtectionEnabled() { + return $this->_sheet || + $this->_objects || + $this->_scenarios || + $this->_formatCells || + $this->_formatColumns || + $this->_formatRows || + $this->_insertColumns || + $this->_insertRows || + $this->_insertHyperlinks || + $this->_deleteColumns || + $this->_deleteRows || + $this->_selectLockedCells || + $this->_sort || + $this->_autoFilter || + $this->_pivotTables || + $this->_selectUnlockedCells; + } + + /** + * Get Sheet + * + * @return boolean + */ + function getSheet() { + return $this->_sheet; + } + + /** + * Set Sheet + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSheet($pValue = false) { + $this->_sheet = $pValue; + return $this; + } + + /** + * Get Objects + * + * @return boolean + */ + function getObjects() { + return $this->_objects; + } + + /** + * Set Objects + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setObjects($pValue = false) { + $this->_objects = $pValue; + return $this; + } + + /** + * Get Scenarios + * + * @return boolean + */ + function getScenarios() { + return $this->_scenarios; + } + + /** + * Set Scenarios + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setScenarios($pValue = false) { + $this->_scenarios = $pValue; + return $this; + } + + /** + * Get FormatCells + * + * @return boolean + */ + function getFormatCells() { + return $this->_formatCells; + } + + /** + * Set FormatCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatCells($pValue = false) { + $this->_formatCells = $pValue; + return $this; + } + + /** + * Get FormatColumns + * + * @return boolean + */ + function getFormatColumns() { + return $this->_formatColumns; + } + + /** + * Set FormatColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatColumns($pValue = false) { + $this->_formatColumns = $pValue; + return $this; + } + + /** + * Get FormatRows + * + * @return boolean + */ + function getFormatRows() { + return $this->_formatRows; + } + + /** + * Set FormatRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setFormatRows($pValue = false) { + $this->_formatRows = $pValue; + return $this; + } + + /** + * Get InsertColumns + * + * @return boolean + */ + function getInsertColumns() { + return $this->_insertColumns; + } + + /** + * Set InsertColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertColumns($pValue = false) { + $this->_insertColumns = $pValue; + return $this; + } + + /** + * Get InsertRows + * + * @return boolean + */ + function getInsertRows() { + return $this->_insertRows; + } + + /** + * Set InsertRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertRows($pValue = false) { + $this->_insertRows = $pValue; + return $this; + } + + /** + * Get InsertHyperlinks + * + * @return boolean + */ + function getInsertHyperlinks() { + return $this->_insertHyperlinks; + } + + /** + * Set InsertHyperlinks + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setInsertHyperlinks($pValue = false) { + $this->_insertHyperlinks = $pValue; + return $this; + } + + /** + * Get DeleteColumns + * + * @return boolean + */ + function getDeleteColumns() { + return $this->_deleteColumns; + } + + /** + * Set DeleteColumns + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setDeleteColumns($pValue = false) { + $this->_deleteColumns = $pValue; + return $this; + } + + /** + * Get DeleteRows + * + * @return boolean + */ + function getDeleteRows() { + return $this->_deleteRows; + } + + /** + * Set DeleteRows + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setDeleteRows($pValue = false) { + $this->_deleteRows = $pValue; + return $this; + } + + /** + * Get SelectLockedCells + * + * @return boolean + */ + function getSelectLockedCells() { + return $this->_selectLockedCells; + } + + /** + * Set SelectLockedCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSelectLockedCells($pValue = false) { + $this->_selectLockedCells = $pValue; + return $this; + } + + /** + * Get Sort + * + * @return boolean + */ + function getSort() { + return $this->_sort; + } + + /** + * Set Sort + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSort($pValue = false) { + $this->_sort = $pValue; + return $this; + } + + /** + * Get AutoFilter + * + * @return boolean + */ + function getAutoFilter() { + return $this->_autoFilter; + } + + /** + * Set AutoFilter + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setAutoFilter($pValue = false) { + $this->_autoFilter = $pValue; + return $this; + } + + /** + * Get PivotTables + * + * @return boolean + */ + function getPivotTables() { + return $this->_pivotTables; + } + + /** + * Set PivotTables + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setPivotTables($pValue = false) { + $this->_pivotTables = $pValue; + return $this; + } + + /** + * Get SelectUnlockedCells + * + * @return boolean + */ + function getSelectUnlockedCells() { + return $this->_selectUnlockedCells; + } + + /** + * Set SelectUnlockedCells + * + * @param boolean $pValue + * @return PHPExcel_Worksheet_Protection + */ + function setSelectUnlockedCells($pValue = false) { + $this->_selectUnlockedCells = $pValue; + return $this; + } + + /** + * Get Password (hashed) + * + * @return string + */ + function getPassword() { + return $this->_password; + } + + /** + * Set Password + * + * @param string $pValue + * @param boolean $pAlreadyHashed If the password has already been hashed, set this to true + * @return PHPExcel_Worksheet_Protection + */ + function setPassword($pValue = '', $pAlreadyHashed = false) { + if (!$pAlreadyHashed) { + $pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue); + } + $this->_password = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/Row.php b/extend/phpexcel/PHPExcel/Worksheet/Row.php new file mode 100755 index 0000000..2e9bd13 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/Row.php @@ -0,0 +1,90 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_Row + * + * Represents a row in PHPExcel_Worksheet, used by PHPExcel_Worksheet_RowIterator + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_Row +{ + /** + * PHPExcel_Worksheet + * + * @var PHPExcel_Worksheet + */ + private $_parent; + + /** + * Row index + * + * @var int + */ + private $_rowIndex = 0; + + /** + * Create a new row + * + * @param PHPExcel_Worksheet $parent + * @param int $rowIndex + */ + public function __construct(PHPExcel_Worksheet $parent = null, $rowIndex = 1) { + // Set parent and row index + $this->_parent = $parent; + $this->_rowIndex = $rowIndex; + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_parent); + } + + /** + * Get row index + * + * @return int + */ + public function getRowIndex() { + return $this->_rowIndex; + } + + /** + * Get cell iterator + * + * @return PHPExcel_Worksheet_CellIterator + */ + public function getCellIterator() { + return new PHPExcel_Worksheet_CellIterator($this->_parent, $this->_rowIndex); + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/RowDimension.php b/extend/phpexcel/PHPExcel/Worksheet/RowDimension.php new file mode 100755 index 0000000..69b7ba8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/RowDimension.php @@ -0,0 +1,265 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_RowDimension + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_RowDimension +{ + /** + * Row index + * + * @var int + */ + private $_rowIndex; + + /** + * Row height (in pt) + * + * When this is set to a negative value, the row height should be ignored by IWriter + * + * @var double + */ + private $_rowHeight = -1; + + /** + * ZeroHeight for Row? + * + * @var bool + */ + private $_zeroHeight = false; + + /** + * Visible? + * + * @var bool + */ + private $_visible = true; + + /** + * Outline level + * + * @var int + */ + private $_outlineLevel = 0; + + /** + * Collapsed + * + * @var bool + */ + private $_collapsed = false; + + /** + * Index to cellXf. Null value means row has no explicit cellXf format. + * + * @var int|null + */ + private $_xfIndex; + + /** + * Create a new PHPExcel_Worksheet_RowDimension + * + * @param int $pIndex Numeric row index + */ + public function __construct($pIndex = 0) + { + // Initialise values + $this->_rowIndex = $pIndex; + + // set row dimension as unformatted by default + $this->_xfIndex = null; + } + + /** + * Get Row Index + * + * @return int + */ + public function getRowIndex() { + return $this->_rowIndex; + } + + /** + * Set Row Index + * + * @param int $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setRowIndex($pValue) { + $this->_rowIndex = $pValue; + return $this; + } + + /** + * Get Row Height + * + * @return double + */ + public function getRowHeight() { + return $this->_rowHeight; + } + + /** + * Set Row Height + * + * @param double $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setRowHeight($pValue = -1) { + $this->_rowHeight = $pValue; + return $this; + } + + /** + * Get ZeroHeight + * + * @return bool + */ + public function getzeroHeight() { + return $this->_zeroHeight; + } + + /** + * Set ZeroHeight + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setzeroHeight($pValue = false) { + $this->_zeroHeight = $pValue; + return $this; + } + + /** + * Get Visible + * + * @return bool + */ + public function getVisible() { + return $this->_visible; + } + + /** + * Set Visible + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setVisible($pValue = true) { + $this->_visible = $pValue; + return $this; + } + + /** + * Get Outline Level + * + * @return int + */ + public function getOutlineLevel() { + return $this->_outlineLevel; + } + + /** + * Set Outline Level + * + * Value must be between 0 and 7 + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_RowDimension + */ + public function setOutlineLevel($pValue) { + if ($pValue < 0 || $pValue > 7) { + throw new PHPExcel_Exception("Outline level must range between 0 and 7."); + } + + $this->_outlineLevel = $pValue; + return $this; + } + + /** + * Get Collapsed + * + * @return bool + */ + public function getCollapsed() { + return $this->_collapsed; + } + + /** + * Set Collapsed + * + * @param bool $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setCollapsed($pValue = true) { + $this->_collapsed = $pValue; + return $this; + } + + /** + * Get index to cellXf + * + * @return int + */ + public function getXfIndex() + { + return $this->_xfIndex; + } + + /** + * Set index to cellXf + * + * @param int $pValue + * @return PHPExcel_Worksheet_RowDimension + */ + public function setXfIndex($pValue = 0) + { + $this->_xfIndex = $pValue; + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/RowIterator.php b/extend/phpexcel/PHPExcel/Worksheet/RowIterator.php new file mode 100755 index 0000000..f2d962f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/RowIterator.php @@ -0,0 +1,148 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_RowIterator + * + * Used to iterate rows in a PHPExcel_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_RowIterator implements Iterator +{ + /** + * PHPExcel_Worksheet to iterate + * + * @var PHPExcel_Worksheet + */ + private $_subject; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 1; + + /** + * Start position + * + * @var int + */ + private $_startRow = 1; + + + /** + * Create a new row iterator + * + * @param PHPExcel_Worksheet $subject The worksheet to iterate over + * @param integer $startRow The row number at which to start iterating + */ + public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1) { + // Set subject + $this->_subject = $subject; + $this->resetStart($startRow); + } + + /** + * Destructor + */ + public function __destruct() { + unset($this->_subject); + } + + /** + * (Re)Set the start row and the current row pointer + * + * @param integer $startRow The row number at which to start iterating + */ + public function resetStart($startRow = 1) { + $this->_startRow = $startRow; + $this->seek($startRow); + } + + /** + * Set the row pointer to the selected row + * + * @param integer $row The row number to set the current pointer at + */ + public function seek($row = 1) { + $this->_position = $row; + } + + /** + * Rewind the iterator to the starting row + */ + public function rewind() { + $this->_position = $this->_startRow; + } + + /** + * Return the current row in this worksheet + * + * @return PHPExcel_Worksheet_Row + */ + public function current() { + return new PHPExcel_Worksheet_Row($this->_subject, $this->_position); + } + + /** + * Return the current iterator key + * + * @return int + */ + public function key() { + return $this->_position; + } + + /** + * Set the iterator to its next value + */ + public function next() { + ++$this->_position; + } + + /** + * Set the iterator to its previous value + */ + public function prev() { + if ($this->_position > 1) + --$this->_position; + } + + /** + * Indicate if more rows exist in the worksheet + * + * @return boolean + */ + public function valid() { + return $this->_position <= $this->_subject->getHighestRow(); + } +} diff --git a/extend/phpexcel/PHPExcel/Worksheet/SheetView.php b/extend/phpexcel/PHPExcel/Worksheet/SheetView.php new file mode 100755 index 0000000..05fbf28 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Worksheet/SheetView.php @@ -0,0 +1,188 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Worksheet_SheetView + * + * @category PHPExcel + * @package PHPExcel_Worksheet + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Worksheet_SheetView +{ + + /* Sheet View types */ + const SHEETVIEW_NORMAL = 'normal'; + const SHEETVIEW_PAGE_LAYOUT = 'pageLayout'; + const SHEETVIEW_PAGE_BREAK_PREVIEW = 'pageBreakPreview'; + + private static $_sheetViewTypes = array( + self::SHEETVIEW_NORMAL, + self::SHEETVIEW_PAGE_LAYOUT, + self::SHEETVIEW_PAGE_BREAK_PREVIEW, + ); + + /** + * ZoomScale + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScale = 100; + + /** + * ZoomScaleNormal + * + * Valid values range from 10 to 400. + * + * @var int + */ + private $_zoomScaleNormal = 100; + + /** + * View + * + * Valid values range from 10 to 400. + * + * @var string + */ + private $_sheetviewType = self::SHEETVIEW_NORMAL; + + /** + * Create a new PHPExcel_Worksheet_SheetView + */ + public function __construct() + { + } + + /** + * Get ZoomScale + * + * @return int + */ + public function getZoomScale() { + return $this->_zoomScale; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScale($pValue = 100) { + // Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface, + // but it is apparently still able to handle any scale >= 1 + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScale = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get ZoomScaleNormal + * + * @return int + */ + public function getZoomScaleNormal() { + return $this->_zoomScaleNormal; + } + + /** + * Set ZoomScale + * + * Valid values range from 10 to 400. + * + * @param int $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setZoomScaleNormal($pValue = 100) { + if (($pValue >= 1) || is_null($pValue)) { + $this->_zoomScaleNormal = $pValue; + } else { + throw new PHPExcel_Exception("Scale must be greater than or equal to 1."); + } + return $this; + } + + /** + * Get View + * + * @return string + */ + public function getView() { + return $this->_sheetviewType; + } + + /** + * Set View + * + * Valid values are + * 'normal' self::SHEETVIEW_NORMAL + * 'pageLayout' self::SHEETVIEW_PAGE_LAYOUT + * 'pageBreakPreview' self::SHEETVIEW_PAGE_BREAK_PREVIEW + * + * @param string $pValue + * @throws PHPExcel_Exception + * @return PHPExcel_Worksheet_SheetView + */ + public function setView($pValue = NULL) { + // MS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview' + // via the user interface + if ($pValue === NULL) + $pValue = self::SHEETVIEW_NORMAL; + if (in_array($pValue, self::$_sheetViewTypes)) { + $this->_sheetviewType = $pValue; + } else { + throw new PHPExcel_Exception("Invalid sheetview layout type."); + } + + return $this; + } + + /** + * Implement PHP __clone to create a deep clone, not just a shallow copy. + */ + public function __clone() { + $vars = get_object_vars($this); + foreach ($vars as $key => $value) { + if (is_object($value)) { + $this->$key = clone $value; + } else { + $this->$key = $value; + } + } + } +} diff --git a/extend/phpexcel/PHPExcel/WorksheetIterator.php b/extend/phpexcel/PHPExcel/WorksheetIterator.php new file mode 100755 index 0000000..624b49b --- /dev/null +++ b/extend/phpexcel/PHPExcel/WorksheetIterator.php @@ -0,0 +1,118 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_WorksheetIterator + * + * Used to iterate worksheets in PHPExcel + * + * @category PHPExcel + * @package PHPExcel + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_WorksheetIterator implements Iterator +{ + /** + * Spreadsheet to iterate + * + * @var PHPExcel + */ + private $_subject; + + /** + * Current iterator position + * + * @var int + */ + private $_position = 0; + + /** + * Create a new worksheet iterator + * + * @param PHPExcel $subject + */ + public function __construct(PHPExcel $subject = null) + { + // Set subject + $this->_subject = $subject; + } + + /** + * Destructor + */ + public function __destruct() + { + unset($this->_subject); + } + + /** + * Rewind iterator + */ + public function rewind() + { + $this->_position = 0; + } + + /** + * Current PHPExcel_Worksheet + * + * @return PHPExcel_Worksheet + */ + public function current() + { + return $this->_subject->getSheet($this->_position); + } + + /** + * Current key + * + * @return int + */ + public function key() + { + return $this->_position; + } + + /** + * Next value + */ + public function next() + { + ++$this->_position; + } + + /** + * More PHPExcel_Worksheet instances available? + * + * @return boolean + */ + public function valid() + { + return $this->_position < $this->_subject->getSheetCount(); + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Abstract.php b/extend/phpexcel/PHPExcel/Writer/Abstract.php new file mode 100755 index 0000000..7e09ef8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Abstract.php @@ -0,0 +1,158 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Abstract + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * Write charts that are defined in the workbook? + * Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object; + * + * @var boolean + */ + protected $_includeCharts = FALSE; + + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * @var boolean + */ + protected $_preCalculateFormulas = TRUE; + + /** + * Use disk caching where possible? + * + * @var boolean + */ + protected $_useDiskCaching = FALSE; + + /** + * Disk caching directory + * + * @var string + */ + protected $_diskCachingDirectory = './'; + + /** + * Write charts in workbook? + * If this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object. + * If false (the default) it will ignore any charts defined in the PHPExcel object. + * + * @return boolean + */ + public function getIncludeCharts() { + return $this->_includeCharts; + } + + /** + * Set write charts in workbook + * Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. + * Set to false (the default) to ignore charts. + * + * @param boolean $pValue + * @return PHPExcel_Writer_IWriter + */ + public function setIncludeCharts($pValue = FALSE) { + $this->_includeCharts = (boolean) $pValue; + return $this; + } + + /** + * Get Pre-Calculate Formulas flag + * If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, + * so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet + * viewer when opening the file + * If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower + * when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself + * + * @return boolean + */ + public function getPreCalculateFormulas() { + return $this->_preCalculateFormulas; + } + + /** + * Set Pre-Calculate Formulas + * Set to true (the default) to advise the Writer to calculate all formulae on save + * Set to false to prevent precalculation of formulae on save. + * + * @param boolean $pValue Pre-Calculate Formulas? + * @return PHPExcel_Writer_IWriter + */ + public function setPreCalculateFormulas($pValue = TRUE) { + $this->_preCalculateFormulas = (boolean) $pValue; + return $this; + } + + /** + * Get use disk caching where possible? + * + * @return boolean + */ + public function getUseDiskCaching() { + return $this->_useDiskCaching; + } + + /** + * Set use disk caching where possible? + * + * @param boolean $pValue + * @param string $pDirectory Disk caching directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel2007 + */ + public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { + $this->_useDiskCaching = $pValue; + + if ($pDirectory !== NULL) { + if (is_dir($pDirectory)) { + $this->_diskCachingDirectory = $pDirectory; + } else { + throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); + } + } + return $this; + } + + /** + * Get disk caching directory + * + * @return string + */ + public function getDiskCachingDirectory() { + return $this->_diskCachingDirectory; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/CSV.php b/extend/phpexcel/PHPExcel/Writer/CSV.php new file mode 100755 index 0000000..521874f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/CSV.php @@ -0,0 +1,310 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_CSV + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_CSV + * + * @category PHPExcel + * @package PHPExcel_Writer_CSV + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Delimiter + * + * @var string + */ + private $_delimiter = ','; + + /** + * Enclosure + * + * @var string + */ + private $_enclosure = '"'; + + /** + * Line ending + * + * @var string + */ + private $_lineEnding = PHP_EOL; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Whether to write a BOM (for UTF8). + * + * @var boolean + */ + private $_useBOM = false; + + /** + * Whether to write a fully Excel compatible CSV file. + * + * @var boolean + */ + private $_excelCompatibility = false; + + /** + * Create a new PHPExcel_Writer_CSV + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + // Fetch sheet + $sheet = $this->_phpExcel->getSheet($this->_sheetIndex); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + if ($this->_excelCompatibility) { + fwrite($fileHandle, "\xEF\xBB\xBF"); // Enforce UTF-8 BOM Header + $this->setEnclosure('"'); // Set enclosure to " + $this->setDelimiter(";"); // Set delimiter to a semi-colon + $this->setLineEnding("\r\n"); + fwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding); + } elseif ($this->_useBOM) { + // Write the UTF-8 BOM code if required + fwrite($fileHandle, "\xEF\xBB\xBF"); + } + + // Identify the range that we need to extract from the worksheet + $maxCol = $sheet->getHighestDataColumn(); + $maxRow = $sheet->getHighestDataRow(); + + // Write rows to file + for($row = 1; $row <= $maxRow; ++$row) { + // Convert the row to an array... + $cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas); + // ... and write to the file + $this->_writeLine($fileHandle, $cellsArray[0]); + } + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Get delimiter + * + * @return string + */ + public function getDelimiter() { + return $this->_delimiter; + } + + /** + * Set delimiter + * + * @param string $pValue Delimiter, defaults to , + * @return PHPExcel_Writer_CSV + */ + public function setDelimiter($pValue = ',') { + $this->_delimiter = $pValue; + return $this; + } + + /** + * Get enclosure + * + * @return string + */ + public function getEnclosure() { + return $this->_enclosure; + } + + /** + * Set enclosure + * + * @param string $pValue Enclosure, defaults to " + * @return PHPExcel_Writer_CSV + */ + public function setEnclosure($pValue = '"') { + if ($pValue == '') { + $pValue = null; + } + $this->_enclosure = $pValue; + return $this; + } + + /** + * Get line ending + * + * @return string + */ + public function getLineEnding() { + return $this->_lineEnding; + } + + /** + * Set line ending + * + * @param string $pValue Line ending, defaults to OS line ending (PHP_EOL) + * @return PHPExcel_Writer_CSV + */ + public function setLineEnding($pValue = PHP_EOL) { + $this->_lineEnding = $pValue; + return $this; + } + + /** + * Get whether BOM should be used + * + * @return boolean + */ + public function getUseBOM() { + return $this->_useBOM; + } + + /** + * Set whether BOM should be used + * + * @param boolean $pValue Use UTF-8 byte-order mark? Defaults to false + * @return PHPExcel_Writer_CSV + */ + public function setUseBOM($pValue = false) { + $this->_useBOM = $pValue; + return $this; + } + + /** + * Get whether the file should be saved with full Excel Compatibility + * + * @return boolean + */ + public function getExcelCompatibility() { + return $this->_excelCompatibility; + } + + /** + * Set whether the file should be saved with full Excel Compatibility + * + * @param boolean $pValue Set the file to be written as a fully Excel compatible csv file + * Note that this overrides other settings such as useBOM, enclosure and delimiter + * @return PHPExcel_Writer_CSV + */ + public function setExcelCompatibility($pValue = false) { + $this->_excelCompatibility = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_CSV + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Write line to CSV file + * + * @param mixed $pFileHandle PHP filehandle + * @param array $pValues Array containing values in a row + * @throws PHPExcel_Writer_Exception + */ + private function _writeLine($pFileHandle = null, $pValues = null) { + if (is_array($pValues)) { + // No leading delimiter + $writeDelimiter = false; + + // Build the line + $line = ''; + + foreach ($pValues as $element) { + // Escape enclosures + $element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element); + + // Add delimiter + if ($writeDelimiter) { + $line .= $this->_delimiter; + } else { + $writeDelimiter = true; + } + + // Add enclosed string + $line .= $this->_enclosure . $element . $this->_enclosure; + } + + // Add line ending + $line .= $this->_lineEnding; + + // Write to file + fwrite($pFileHandle, $line); + } else { + throw new PHPExcel_Writer_Exception("Invalid data row passed to CSV writer."); + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007.php b/extend/phpexcel/PHPExcel/Writer/Excel2007.php new file mode 100755 index 0000000..a8f7593 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007.php @@ -0,0 +1,532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007 + * + * @category PHPExcel + * @package PHPExcel_Writer_2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * Pre-calculate formulas + * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are + * immediately available to MS Excel or other office spreadsheet viewer when opening the file + * + * Overrides the default TRUE for this specific writer for performance reasons + * + * @var boolean + */ + protected $_preCalculateFormulas = FALSE; + + /** + * Office2003 compatibility + * + * @var boolean + */ + private $_office2003compatibility = false; + + /** + * Private writer parts + * + * @var PHPExcel_Writer_Excel2007_WriterPart[] + */ + private $_writerParts = array(); + + /** + * Private PHPExcel + * + * @var PHPExcel + */ + private $_spreadSheet; + + /** + * Private string table + * + * @var string[] + */ + private $_stringTable = array(); + + /** + * Private unique PHPExcel_Style_Conditional HashTable + * + * @var PHPExcel_HashTable + */ + private $_stylesConditionalHashTable; + + /** + * Private unique PHPExcel_Style HashTable + * + * @var PHPExcel_HashTable + */ + private $_styleHashTable; + + /** + * Private unique PHPExcel_Style_Fill HashTable + * + * @var PHPExcel_HashTable + */ + private $_fillHashTable; + + /** + * Private unique PHPExcel_Style_Font HashTable + * + * @var PHPExcel_HashTable + */ + private $_fontHashTable; + + /** + * Private unique PHPExcel_Style_Borders HashTable + * + * @var PHPExcel_HashTable + */ + private $_bordersHashTable ; + + /** + * Private unique PHPExcel_Style_NumberFormat HashTable + * + * @var PHPExcel_HashTable + */ + private $_numFmtHashTable; + + /** + * Private unique PHPExcel_Worksheet_BaseDrawing HashTable + * + * @var PHPExcel_HashTable + */ + private $_drawingHashTable; + + /** + * Create a new PHPExcel_Writer_Excel2007 + * + * @param PHPExcel $pPHPExcel + */ + public function __construct(PHPExcel $pPHPExcel = null) + { + // Assign PHPExcel + $this->setPHPExcel($pPHPExcel); + + $writerPartsArray = array( 'stringtable' => 'PHPExcel_Writer_Excel2007_StringTable', + 'contenttypes' => 'PHPExcel_Writer_Excel2007_ContentTypes', + 'docprops' => 'PHPExcel_Writer_Excel2007_DocProps', + 'rels' => 'PHPExcel_Writer_Excel2007_Rels', + 'theme' => 'PHPExcel_Writer_Excel2007_Theme', + 'style' => 'PHPExcel_Writer_Excel2007_Style', + 'workbook' => 'PHPExcel_Writer_Excel2007_Workbook', + 'worksheet' => 'PHPExcel_Writer_Excel2007_Worksheet', + 'drawing' => 'PHPExcel_Writer_Excel2007_Drawing', + 'comments' => 'PHPExcel_Writer_Excel2007_Comments', + 'chart' => 'PHPExcel_Writer_Excel2007_Chart', + 'relsvba' => 'PHPExcel_Writer_Excel2007_RelsVBA', + 'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon' + ); + + // Initialise writer parts + // and Assign their parent IWriters + foreach ($writerPartsArray as $writer => $class) { + $this->_writerParts[$writer] = new $class($this); + } + + $hashTablesArray = array( '_stylesConditionalHashTable', '_fillHashTable', '_fontHashTable', + '_bordersHashTable', '_numFmtHashTable', '_drawingHashTable', + '_styleHashTable' + ); + + // Set HashTable variables + foreach ($hashTablesArray as $tableName) { + $this->$tableName = new PHPExcel_HashTable(); + } + } + + /** + * Get writer part + * + * @param string $pPartName Writer part name + * @return PHPExcel_Writer_Excel2007_WriterPart + */ + public function getWriterPart($pPartName = '') { + if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { + return $this->_writerParts[strtolower($pPartName)]; + } else { + return null; + } + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) + { + if ($this->_spreadSheet !== NULL) { + // garbage collect + $this->_spreadSheet->garbageCollect(); + + // If $pFilename is php://output or php://stdout, make it a temporary file... + $originalFilename = $pFilename; + if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') { + $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp'); + if ($pFilename == '') { + $pFilename = $originalFilename; + } + } + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // Create string lookup table + $this->_stringTable = array(); + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable); + } + + // Create styles dictionaries + $this->_styleHashTable->addFromSource( $this->getWriterPart('Style')->allStyles($this->_spreadSheet) ); + $this->_stylesConditionalHashTable->addFromSource( $this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) ); + $this->_fillHashTable->addFromSource( $this->getWriterPart('Style')->allFills($this->_spreadSheet) ); + $this->_fontHashTable->addFromSource( $this->getWriterPart('Style')->allFonts($this->_spreadSheet) ); + $this->_bordersHashTable->addFromSource( $this->getWriterPart('Style')->allBorders($this->_spreadSheet) ); + $this->_numFmtHashTable->addFromSource( $this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) ); + + // Create drawing dictionary + $this->_drawingHashTable->addFromSource( $this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) ); + + // Create new ZIP file and open it for writing + $zipClass = PHPExcel_Settings::getZipClass(); + $objZip = new $zipClass(); + + // Retrieve OVERWRITE and CREATE constants from the instantiated zip class + // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP + $ro = new ReflectionObject($objZip); + $zipOverWrite = $ro->getConstant('OVERWRITE'); + $zipCreate = $ro->getConstant('CREATE'); + + if (file_exists($pFilename)) { + unlink($pFilename); + } + // Try opening the ZIP file + if ($objZip->open($pFilename, $zipOverWrite) !== true) { + if ($objZip->open($pFilename, $zipCreate) !== true) { + throw new PHPExcel_Writer_Exception("Could not open " . $pFilename . " for writing."); + } + } + + // Add [Content_Types].xml to ZIP file + $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts)); + + //if hasMacros, add the vbaProject.bin file, Certificate file(if exists) + if($this->_spreadSheet->hasMacros()){ + $macrosCode=$this->_spreadSheet->getMacrosCode(); + if(!is_null($macrosCode)){// we have the code ? + $objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin + if($this->_spreadSheet->hasMacrosCertificate()){//signed macros ? + // Yes : add the certificate file and the related rels file + $objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate()); + $objZip->addFromString('xl/_rels/vbaProject.bin.rels', + $this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet)); + } + } + } + //a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels) + if($this->_spreadSheet->hasRibbon()){ + $tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target'); + $objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data')); + if($this->_spreadSheet->hasRibbonBinObjects()){ + $tmpRootPath=dirname($tmpRibbonTarget).'/'; + $ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write + foreach($ribbonBinObjects as $aPath=>$aContent){ + $objZip->addFromString($tmpRootPath.$aPath, $aContent); + } + //the rels for files + $objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels', + $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet)); + } + } + + // Add relationships to ZIP file + $objZip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet)); + $objZip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet)); + + // Add document properties to ZIP file + $objZip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet)); + $objZip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet)); + $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet); + if ($customPropertiesPart !== NULL) { + $objZip->addFromString('docProps/custom.xml', $customPropertiesPart); + } + + // Add theme to ZIP file + $objZip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->_spreadSheet)); + + // Add string table to ZIP file + $objZip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->_stringTable)); + + // Add styles to ZIP file + $objZip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->_spreadSheet)); + + // Add workbook to ZIP file + $objZip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas)); + + $chartCount = 0; + // Add worksheets + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + $objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts)); + if ($this->_includeCharts) { + $charts = $this->_spreadSheet->getSheet($i)->getChartCollection(); + if (count($charts) > 0) { + foreach($charts as $chart) { + $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart)); + $chartCount++; + } + } + } + } + + $chartRef1 = $chartRef2 = 0; + // Add worksheet relationships (drawings, ...) + for ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) { + + // Add relationships + $objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts)); + + $drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + if ($this->_includeCharts) { + $chartCount = $this->_spreadSheet->getSheet($i)->getChartCount(); + } + + // Add drawing and image relationship parts + if (($drawingCount > 0) || ($chartCount > 0)) { + // Drawing relationships + $objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts)); + + // Drawings + $objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts)); + } + + // Add comment relationship parts + if (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) { + // VML Comments + $objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i))); + + // Comments + $objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i))); + } + + // Add header/footer relationship parts + if (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { + // VML Drawings + $objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i))); + + // VML Drawing relationships + $objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i))); + + // Media + foreach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) { + $objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath())); + } + } + } + + // Add media + for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { + if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $imageContents = null; + $imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath(); + if (strpos($imagePath, 'zip://') !== false) { + $imagePath = substr($imagePath, 6); + $imagePathSplitted = explode('#', $imagePath); + + $imageZip = new ZipArchive(); + $imageZip->open($imagePathSplitted[0]); + $imageContents = $imageZip->getFromName($imagePathSplitted[1]); + $imageZip->close(); + unset($imageZip); + } else { + $imageContents = file_get_contents($imagePath); + } + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + ob_start(); + call_user_func( + $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), + $this->getDrawingHashTable()->getByIndex($i)->getImageResource() + ); + $imageContents = ob_get_contents(); + ob_end_clean(); + + $objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); + } + } + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog); + + // Close file + if ($objZip->close() === false) { + throw new PHPExcel_Writer_Exception("Could not close zip file $pFilename."); + } + + // If a temporary file was used, copy it to the correct file stream + if ($originalFilename != $pFilename) { + if (copy($pFilename, $originalFilename) === false) { + throw new PHPExcel_Writer_Exception("Could not copy temporary zip file $pFilename to $originalFilename."); + } + @unlink($pFilename); + } + } else { + throw new PHPExcel_Writer_Exception("PHPExcel object unassigned."); + } + } + + /** + * Get PHPExcel object + * + * @return PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function getPHPExcel() { + if ($this->_spreadSheet !== null) { + return $this->_spreadSheet; + } else { + throw new PHPExcel_Writer_Exception("No PHPExcel assigned."); + } + } + + /** + * Set PHPExcel object + * + * @param PHPExcel $pPHPExcel PHPExcel object + * @throws PHPExcel_Writer_Exception + * @return PHPExcel_Writer_Excel2007 + */ + public function setPHPExcel(PHPExcel $pPHPExcel = null) { + $this->_spreadSheet = $pPHPExcel; + return $this; + } + + /** + * Get string table + * + * @return string[] + */ + public function getStringTable() { + return $this->_stringTable; + } + + /** + * Get PHPExcel_Style HashTable + * + * @return PHPExcel_HashTable + */ + public function getStyleHashTable() { + return $this->_styleHashTable; + } + + /** + * Get PHPExcel_Style_Conditional HashTable + * + * @return PHPExcel_HashTable + */ + public function getStylesConditionalHashTable() { + return $this->_stylesConditionalHashTable; + } + + /** + * Get PHPExcel_Style_Fill HashTable + * + * @return PHPExcel_HashTable + */ + public function getFillHashTable() { + return $this->_fillHashTable; + } + + /** + * Get PHPExcel_Style_Font HashTable + * + * @return PHPExcel_HashTable + */ + public function getFontHashTable() { + return $this->_fontHashTable; + } + + /** + * Get PHPExcel_Style_Borders HashTable + * + * @return PHPExcel_HashTable + */ + public function getBordersHashTable() { + return $this->_bordersHashTable; + } + + /** + * Get PHPExcel_Style_NumberFormat HashTable + * + * @return PHPExcel_HashTable + */ + public function getNumFmtHashTable() { + return $this->_numFmtHashTable; + } + + /** + * Get PHPExcel_Worksheet_BaseDrawing HashTable + * + * @return PHPExcel_HashTable + */ + public function getDrawingHashTable() { + return $this->_drawingHashTable; + } + + /** + * Get Office2003 compatibility + * + * @return boolean + */ + public function getOffice2003Compatibility() { + return $this->_office2003compatibility; + } + + /** + * Set Office2003 compatibility + * + * @param boolean $pValue Office2003 compatibility? + * @return PHPExcel_Writer_Excel2007 + */ + public function setOffice2003Compatibility($pValue = false) { + $this->_office2003compatibility = $pValue; + return $this; + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Chart.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Chart.php new file mode 100755 index 0000000..526daa9 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Chart.php @@ -0,0 +1,1203 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Chart + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Chart extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write charts to XML format + * + * @param PHPExcel_Chart $pChart + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeChart(PHPExcel_Chart $pChart = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + // Ensure that data series values are up-to-date before we save + $pChart->refresh(); + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // c:chartSpace + $objWriter->startElement('c:chartSpace'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + $objWriter->startElement('c:date1904'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + $objWriter->startElement('c:lang'); + $objWriter->writeAttribute('val', "en-GB"); + $objWriter->endElement(); + $objWriter->startElement('c:roundedCorners'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writeAlternateContent($objWriter); + + $objWriter->startElement('c:chart'); + + $this->_writeTitle($pChart->getTitle(), $objWriter); + + $objWriter->startElement('c:autoTitleDeleted'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $this->_writePlotArea($pChart->getPlotArea(), + $pChart->getXAxisLabel(), + $pChart->getYAxisLabel(), + $objWriter, + $pChart->getWorksheet() + ); + + $this->_writeLegend($pChart->getLegend(), $objWriter); + + + $objWriter->startElement('c:plotVisOnly'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:dispBlanksAs'); + $objWriter->writeAttribute('val', "gap"); + $objWriter->endElement(); + + $objWriter->startElement('c:showDLblsOverMax'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + $this->_writePrintSettings($objWriter); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Chart Title + * + * @param PHPExcel_Chart_Title $title + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeTitle(PHPExcel_Chart_Title $title = null, $objWriter) + { + if (is_null($title)) { + return; + } + + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + + $caption = $title->getCaption(); + if ((is_array($caption)) && (count($caption) > 0)) + $caption = $caption[0]; + $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a'); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $title->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Legend + * + * @param PHPExcel_Chart_Legend $legend + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegend(PHPExcel_Chart_Legend $legend = null, $objWriter) + { + if (is_null($legend)) { + return; + } + + $objWriter->startElement('c:legend'); + + $objWriter->startElement('c:legendPos'); + $objWriter->writeAttribute('val', $legend->getPosition()); + $objWriter->endElement(); + + $layout = $legend->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0'); + $objWriter->endElement(); + + $objWriter->startElement('c:txPr'); + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:pPr'); + $objWriter->writeAttribute('rtl', 0); + + $objWriter->startElement('a:defRPr'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:endParaRPr'); + $objWriter->writeAttribute('lang', "en-US"); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Chart Plot Area + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param PHPExcel_Chart_Title $yAxisLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea, + PHPExcel_Chart_Title $xAxisLabel = NULL, + PHPExcel_Chart_Title $yAxisLabel = NULL, + $objWriter, + PHPExcel_Worksheet $pSheet) + { + if (is_null($plotArea)) { + return; + } + + $id1 = $id2 = 0; + $this->_seriesIndex = 0; + $objWriter->startElement('c:plotArea'); + + $layout = $plotArea->getLayout(); + + $this->_writeLayout($layout, $objWriter); + + $chartTypes = self::_getChartType($plotArea); + $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE; + $plotGroupingType = ''; + foreach($chartTypes as $chartType) { + $objWriter->startElement('c:'.$chartType); + + $groupCount = $plotArea->getPlotGroupCount(); + for($i = 0; $i < $groupCount; ++$i) { + $plotGroup = $plotArea->getPlotGroupByIndex($i); + $groupType = $plotGroup->getPlotType(); + if ($groupType == $chartType) { + + $plotStyle = $plotGroup->getPlotStyle(); + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) { + $objWriter->startElement('c:radarStyle'); + $objWriter->writeAttribute('val', $plotStyle ); + $objWriter->endElement(); + } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) { + $objWriter->startElement('c:scatterStyle'); + $objWriter->writeAttribute('val', $plotStyle ); + $objWriter->endElement(); + } + + $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet); + } + } + + $this->_writeDataLbls($objWriter, $layout); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + // Line only, Line3D can't be smoothed + + $objWriter->startElement('c:smooth'); + $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine() ); + $objWriter->endElement(); + } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + + $objWriter->startElement('c:gapWidth'); + $objWriter->writeAttribute('val', 150 ); + $objWriter->endElement(); + + if ($plotGroupingType == 'percentStacked' || + $plotGroupingType == 'stacked') { + + $objWriter->startElement('c:overlap'); + $objWriter->writeAttribute('val', 100 ); + $objWriter->endElement(); + } + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + + $objWriter->startElement('c:bubbleScale'); + $objWriter->writeAttribute('val', 25 ); + $objWriter->endElement(); + + $objWriter->startElement('c:showNegBubbles'); + $objWriter->writeAttribute('val', 0 ); + $objWriter->endElement(); + } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + + $objWriter->startElement('c:hiLowLines'); + $objWriter->endElement(); + + $objWriter->startElement( 'c:upDownBars' ); + + $objWriter->startElement( 'c:gapWidth' ); + $objWriter->writeAttribute('val', 300); + $objWriter->endElement(); + + $objWriter->startElement( 'c:upBars' ); + $objWriter->endElement(); + + $objWriter->startElement( 'c:downBars' ); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // Generate 2 unique numbers to use for axId values +// $id1 = $id2 = rand(10000000,99999999); +// do { +// $id2 = rand(10000000,99999999); +// } while ($id1 == $id2); + $id1 = '75091328'; + $id2 = '75089408'; + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1 ); + $objWriter->endElement(); + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2 ); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:firstSliceAng'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) { + + $objWriter->startElement('c:holeSize'); + $objWriter->writeAttribute('val', 50); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeValAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); + } else { + $this->_writeCatAx($objWriter,$plotArea,$xAxisLabel,$chartType,$id1,$id2,$catIsMultiLevelSeries); + } + + $this->_writeValAx($objWriter,$plotArea,$yAxisLabel,$chartType,$id1,$id2,$valIsMultiLevelSeries); + } + + $objWriter->endElement(); + } + + /** + * Write Data Labels + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_Layout $chartLayout Chart layout + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataLbls($objWriter, $chartLayout) + { + $objWriter->startElement('c:dLbls'); + + $objWriter->startElement('c:showLegendKey'); + $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey(); + $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1) ); + $objWriter->endElement(); + + + $objWriter->startElement('c:showVal'); + $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal(); + $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showCatName'); + $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName(); + $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showSerName'); + $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName(); + $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showPercent'); + $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent(); + $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showBubbleSize'); + $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize(); + $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->startElement('c:showLeaderLines'); + $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines(); + $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1) ); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Category Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $xAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * @throws PHPExcel_Writer_Exception + */ + private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) + { + $objWriter->startElement('c:catAx'); + + if ($id1 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id1); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', "minMax"); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "b"); + $objWriter->endElement(); + + if (!is_null($xAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $xAxisLabel->getCaption(); + if (is_array($caption)) + $caption = $caption[0]; + $objWriter->startElement('a:t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $layout = $xAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', "General"); + $objWriter->writeAttribute('sourceLinked', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', "out"); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', "none"); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', "nextTo"); + $objWriter->endElement(); + + if ($id2 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', "autoZero"); + $objWriter->endElement(); + } + + $objWriter->startElement('c:auto'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:lblAlgn'); + $objWriter->writeAttribute('val', "ctr"); + $objWriter->endElement(); + + $objWriter->startElement('c:lblOffset'); + $objWriter->writeAttribute('val', 100); + $objWriter->endElement(); + + if ($isMultiLevelSeries) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + $objWriter->endElement(); + + } + + + /** + * Write Value Axis + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart_PlotArea $plotArea + * @param PHPExcel_Chart_Title $yAxisLabel + * @param string $groupType Chart type + * @param string $id1 + * @param string $id2 + * @param boolean $isMultiLevelSeries + * @throws PHPExcel_Writer_Exception + */ + private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries) + { + $objWriter->startElement('c:valAx'); + + if ($id2 > 0) { + $objWriter->startElement('c:axId'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + } + + $objWriter->startElement('c:scaling'); + $objWriter->startElement('c:orientation'); + $objWriter->writeAttribute('val', "minMax"); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:delete'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:axPos'); + $objWriter->writeAttribute('val', "l"); + $objWriter->endElement(); + + $objWriter->startElement('c:majorGridlines'); + $objWriter->endElement(); + + if (!is_null($yAxisLabel)) { + $objWriter->startElement('c:title'); + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:rich'); + + $objWriter->startElement('a:bodyPr'); + $objWriter->endElement(); + + $objWriter->startElement('a:lstStyle'); + $objWriter->endElement(); + + $objWriter->startElement('a:p'); + $objWriter->startElement('a:r'); + + $caption = $yAxisLabel->getCaption(); + if (is_array($caption)) + $caption = $caption[0]; + $objWriter->startElement('a:t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $caption )); + $objWriter->endElement(); + + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $layout = $yAxisLabel->getLayout(); + $this->_writeLayout($layout, $objWriter); + } + + $objWriter->startElement('c:overlay'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + $objWriter->startElement('c:numFmt'); + $objWriter->writeAttribute('formatCode', "General"); + $objWriter->writeAttribute('sourceLinked', 1); + $objWriter->endElement(); + + $objWriter->startElement('c:majorTickMark'); + $objWriter->writeAttribute('val', "out"); + $objWriter->endElement(); + + $objWriter->startElement('c:minorTickMark'); + $objWriter->writeAttribute('val', "none"); + $objWriter->endElement(); + + $objWriter->startElement('c:tickLblPos'); + $objWriter->writeAttribute('val', "nextTo"); + $objWriter->endElement(); + + if ($id1 > 0) { + $objWriter->startElement('c:crossAx'); + $objWriter->writeAttribute('val', $id2); + $objWriter->endElement(); + + $objWriter->startElement('c:crosses'); + $objWriter->writeAttribute('val', "autoZero"); + $objWriter->endElement(); + + $objWriter->startElement('c:crossBetween'); + $objWriter->writeAttribute('val', "midCat"); + $objWriter->endElement(); + } + + if ($isMultiLevelSeries) { + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $objWriter->startElement('c:noMultiLvlLbl'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + $objWriter->endElement(); + + } + + + /** + * Get the data series type(s) for a chart plot series + * + * @param PHPExcel_Chart_PlotArea $plotArea + * @return string|array + * @throws PHPExcel_Writer_Exception + */ + private static function _getChartType($plotArea) + { + $groupCount = $plotArea->getPlotGroupCount(); + + if ($groupCount == 1) { + $chartType = array($plotArea->getPlotGroupByIndex(0)->getPlotType()); + } else { + $chartTypes = array(); + for($i = 0; $i < $groupCount; ++$i) { + $chartTypes[] = $plotArea->getPlotGroupByIndex($i)->getPlotType(); + } + $chartType = array_unique($chartTypes); + if (count($chartTypes) == 0) { + throw new PHPExcel_Writer_Exception('Chart is not yet implemented'); + } + } + + return $chartType; + } + + /** + * Write Plot Group (series of related plots) + * + * @param PHPExcel_Chart_DataSeries $plotGroup + * @param string $groupType Type of plot for dataseries + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean &$catIsMultiLevelSeries Is category a multi-series category + * @param boolean &$valIsMultiLevelSeries Is value set a multi-series set + * @param string &$plotGroupingType Type of grouping for multi-series values + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotGroup( $plotGroup, + $groupType, + $objWriter, + &$catIsMultiLevelSeries, + &$valIsMultiLevelSeries, + &$plotGroupingType, + PHPExcel_Worksheet $pSheet + ) + { + if (is_null($plotGroup)) { + return; + } + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)) { + $objWriter->startElement('c:barDir'); + $objWriter->writeAttribute('val', $plotGroup->getPlotDirection()); + $objWriter->endElement(); + } + + if (!is_null($plotGroup->getPlotGrouping())) { + $plotGroupingType = $plotGroup->getPlotGrouping(); + $objWriter->startElement('c:grouping'); + $objWriter->writeAttribute('val', $plotGroupingType); + $objWriter->endElement(); + } + + // Get these details before the loop, because we can use the count to check for varyColors + $plotSeriesOrder = $plotGroup->getPlotOrder(); + $plotSeriesCount = count($plotSeriesOrder); + + if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) && + ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + + if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) { + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) || + ($plotSeriesCount > 1)) { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 1); + $objWriter->endElement(); + } else { + $objWriter->startElement('c:varyColors'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + } + } + + foreach($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) { + $objWriter->startElement('c:ser'); + + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx); + $objWriter->endElement(); + + $objWriter->startElement('c:order'); + $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef); + $objWriter->endElement(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + $objWriter->startElement('c:dPt'); + $objWriter->startElement('c:idx'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:solidFill'); + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FF9900'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Labels + $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef); + if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) { + $objWriter->startElement('c:tx'); + $objWriter->startElement('c:strRef'); + $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter); + $objWriter->endElement(); + $objWriter->endElement(); + } + + // Formatting for the points + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)) { + $objWriter->startElement('c:spPr'); + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', 12700); + if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) { + $objWriter->startElement('a:noFill'); + $objWriter->endElement(); + } + $objWriter->endElement(); + $objWriter->endElement(); + } + + $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef); + if ($plotSeriesValues) { + $plotSeriesMarker = $plotSeriesValues->getPointMarker(); + if ($plotSeriesMarker) { + $objWriter->startElement('c:marker'); + $objWriter->startElement('c:symbol'); + $objWriter->writeAttribute('val', $plotSeriesMarker); + $objWriter->endElement(); + + if ($plotSeriesMarker !== 'none') { + $objWriter->startElement('c:size'); + $objWriter->writeAttribute('val', 3); + $objWriter->endElement(); + } + $objWriter->endElement(); + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)) { + + $objWriter->startElement('c:invertIfNegative'); + $objWriter->writeAttribute('val', 0); + $objWriter->endElement(); + } + + // Category Labels + $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef); + if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) { + $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries(); + + if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) || + ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if (!is_null($plotGroup->getPlotStyle())) { + $plotStyle = $plotGroup->getPlotStyle(); + if ($plotStyle) { + $objWriter->startElement('c:explosion'); + $objWriter->writeAttribute('val', 25); + $objWriter->endElement(); + } + } + } + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:xVal'); + } else { + $objWriter->startElement('c:cat'); + } + + $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet); + $objWriter->endElement(); + } + + // Values + if ($plotSeriesValues) { + $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries(); + + if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) || + ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)) { + $objWriter->startElement('c:yVal'); + } else { + $objWriter->startElement('c:val'); + } + + $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet); + $objWriter->endElement(); + } + + if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) { + $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet); + } + + $objWriter->endElement(); + + } + + $this->_seriesIndex += $plotSeriesIdx + 1; + } + + /** + * Write Plot Series Label + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesLabel + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) + { + if (is_null($plotSeriesLabel)) { + return; + } + + $objWriter->startElement('c:f'); + $objWriter->writeRawData($plotSeriesLabel->getDataSource()); + $objWriter->endElement(); + + $objWriter->startElement('c:strCache'); + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount() ); + $objWriter->endElement(); + + foreach($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotLabelKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotLabelValue ); + $objWriter->endElement(); + $objWriter->endElement(); + } + $objWriter->endElement(); + + } + + /** + * Write Plot Series Values + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $groupType Type of plot for dataseries + * @param string $dataType Datatype of series values + * @param PHPExcel_Worksheet $pSheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePlotSeriesValues( $plotSeriesValues, + $objWriter, + $groupType, + $dataType='str', + PHPExcel_Worksheet $pSheet + ) + { + if (is_null($plotSeriesValues)) { + return; + } + + if ($plotSeriesValues->isMultiLevelSeries()) { + $levelCount = $plotSeriesValues->multiLevelCount(); + + $objWriter->startElement('c:multiLvlStrRef'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); + $objWriter->endElement(); + + $objWriter->startElement('c:multiLvlStrCache'); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + for ($level = 0; $level < $levelCount; ++$level) { + $objWriter->startElement('c:lvl'); + + foreach($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) { + if (isset($plotSeriesValue[$level])) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotSeriesValue[$level] ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } else { + $objWriter->startElement('c:'.$dataType.'Ref'); + + $objWriter->startElement('c:f'); + $objWriter->writeRawData( $plotSeriesValues->getDataSource() ); + $objWriter->endElement(); + + $objWriter->startElement('c:'.$dataType.'Cache'); + + if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) && + ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)) { + + if (($plotSeriesValues->getFormatCode() !== NULL) && + ($plotSeriesValues->getFormatCode() !== '')) { + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData( $plotSeriesValues->getFormatCode() ); + $objWriter->endElement(); + } + } + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + + $objWriter->startElement('c:v'); + $objWriter->writeRawData( $plotSeriesValue ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Bubble Chart Details + * + * @param PHPExcel_Chart_DataSeriesValues $plotSeriesValues + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) + { + if (is_null($plotSeriesValues)) { + return; + } + + $objWriter->startElement('c:bubbleSize'); + $objWriter->startElement('c:numLit'); + + $objWriter->startElement('c:formatCode'); + $objWriter->writeRawData( 'General' ); + $objWriter->endElement(); + + $objWriter->startElement('c:ptCount'); + $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount() ); + $objWriter->endElement(); + + $dataValues = $plotSeriesValues->getDataValues(); + if (!empty($dataValues)) { + if (is_array($dataValues)) { + foreach($dataValues as $plotSeriesKey => $plotSeriesValue) { + $objWriter->startElement('c:pt'); + $objWriter->writeAttribute('idx', $plotSeriesKey ); + $objWriter->startElement('c:v'); + $objWriter->writeRawData( 1 ); + $objWriter->endElement(); + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('c:bubble3D'); + $objWriter->writeAttribute('val', 0 ); + $objWriter->endElement(); + } + + /** + * Write Layout + * + * @param PHPExcel_Chart_Layout $layout + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) + { + $objWriter->startElement('c:layout'); + + if (!is_null($layout)) { + $objWriter->startElement('c:manualLayout'); + + $layoutTarget = $layout->getLayoutTarget(); + if (!is_null($layoutTarget)) { + $objWriter->startElement('c:layoutTarget'); + $objWriter->writeAttribute('val', $layoutTarget); + $objWriter->endElement(); + } + + $xMode = $layout->getXMode(); + if (!is_null($xMode)) { + $objWriter->startElement('c:xMode'); + $objWriter->writeAttribute('val', $xMode); + $objWriter->endElement(); + } + + $yMode = $layout->getYMode(); + if (!is_null($yMode)) { + $objWriter->startElement('c:yMode'); + $objWriter->writeAttribute('val', $yMode); + $objWriter->endElement(); + } + + $x = $layout->getXPosition(); + if (!is_null($x)) { + $objWriter->startElement('c:x'); + $objWriter->writeAttribute('val', $x); + $objWriter->endElement(); + } + + $y = $layout->getYPosition(); + if (!is_null($y)) { + $objWriter->startElement('c:y'); + $objWriter->writeAttribute('val', $y); + $objWriter->endElement(); + } + + $w = $layout->getWidth(); + if (!is_null($w)) { + $objWriter->startElement('c:w'); + $objWriter->writeAttribute('val', $w); + $objWriter->endElement(); + } + + $h = $layout->getHeight(); + if (!is_null($h)) { + $objWriter->startElement('c:h'); + $objWriter->writeAttribute('val', $h); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Alternate Content block + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeAlternateContent($objWriter) + { + $objWriter->startElement('mc:AlternateContent'); + $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006'); + + $objWriter->startElement('mc:Choice'); + $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart'); + $objWriter->writeAttribute('Requires', 'c14'); + + $objWriter->startElement('c14:style'); + $objWriter->writeAttribute('val', '102'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('mc:Fallback'); + $objWriter->startElement('c:style'); + $objWriter->writeAttribute('val', '2'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Printer Settings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintSettings($objWriter) + { + $objWriter->startElement('c:printSettings'); + + $objWriter->startElement('c:headerFooter'); + $objWriter->endElement(); + + $objWriter->startElement('c:pageMargins'); + $objWriter->writeAttribute('footer', 0.3); + $objWriter->writeAttribute('header', 0.3); + $objWriter->writeAttribute('r', 0.7); + $objWriter->writeAttribute('l', 0.7); + $objWriter->writeAttribute('t', 0.75); + $objWriter->writeAttribute('b', 0.75); + $objWriter->endElement(); + + $objWriter->startElement('c:pageSetup'); + $objWriter->writeAttribute('orientation', "portrait"); + $objWriter->endElement(); + + $objWriter->endElement(); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Comments.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Comments.php new file mode 100755 index 0000000..436219c --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Comments.php @@ -0,0 +1,268 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Comments + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // Authors cache + $authors = array(); + $authorId = 0; + foreach ($comments as $comment) { + if (!isset($authors[$comment->getAuthor()])) { + $authors[$comment->getAuthor()] = $authorId++; + } + } + + // comments + $objWriter->startElement('comments'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // Loop through authors + $objWriter->startElement('authors'); + foreach ($authors as $author => $index) { + $objWriter->writeElement('author', $author); + } + $objWriter->endElement(); + + // Loop through comments + $objWriter->startElement('commentList'); + foreach ($comments as $key => $value) { + $this->_writeComment($objWriter, $key, $value, $authors); + } + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @param array $pAuthors Array of authors + * @throws PHPExcel_Writer_Exception + */ + public function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null) + { + // comment + $objWriter->startElement('comment'); + $objWriter->writeAttribute('ref', $pCellReference); + $objWriter->writeAttribute('authorId', $pAuthors[$pComment->getAuthor()]); + + // text + $objWriter->startElement('text'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write VML comments to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Comments cache + $comments = $pWorksheet->getComments(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t202'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '202'); + $objWriter->writeAttribute('path', 'm,l,21600r21600,l21600,xe'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through comments + foreach ($comments as $key => $value) { + $this->_writeVMLComment($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pCellReference Cell reference + * @param PHPExcel_Comment $pComment Comment + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null) + { + // Metadata + list($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference); + $column = PHPExcel_Cell::columnIndexFromString($column); + $id = 1024 + $column + $row; + $id = substr($id, 0, 4); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t202'); + $objWriter->writeAttribute('style', 'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden')); + $objWriter->writeAttribute('fillcolor', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->writeAttribute('o:insetmode', 'auto'); + + // v:fill + $objWriter->startElement('v:fill'); + $objWriter->writeAttribute('color2', '#' . $pComment->getFillColor()->getRGB()); + $objWriter->endElement(); + + // v:shadow + $objWriter->startElement('v:shadow'); + $objWriter->writeAttribute('on', 't'); + $objWriter->writeAttribute('color', 'black'); + $objWriter->writeAttribute('obscured', 't'); + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:connecttype', 'none'); + $objWriter->endElement(); + + // v:textbox + $objWriter->startElement('v:textbox'); + $objWriter->writeAttribute('style', 'mso-direction-alt:auto'); + + // div + $objWriter->startElement('div'); + $objWriter->writeAttribute('style', 'text-align:left'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // x:ClientData + $objWriter->startElement('x:ClientData'); + $objWriter->writeAttribute('ObjectType', 'Note'); + + // x:MoveWithCells + $objWriter->writeElement('x:MoveWithCells', ''); + + // x:SizeWithCells + $objWriter->writeElement('x:SizeWithCells', ''); + + // x:Anchor + //$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18'); + + // x:AutoFill + $objWriter->writeElement('x:AutoFill', 'False'); + + // x:Row + $objWriter->writeElement('x:Row', ($row - 1)); + + // x:Column + $objWriter->writeElement('x:Column', ($column - 1)); + + $objWriter->endElement(); + + $objWriter->endElement(); + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php new file mode 100755 index 0000000..3c17a16 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/ContentTypes.php @@ -0,0 +1,287 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_ContentTypes + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write content types to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Types + $objWriter->startElement('Types'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types'); + + // Theme + $this->_writeOverrideContentType( + $objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' + ); + + // Styles + $this->_writeOverrideContentType( + $objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml' + ); + + // Rels + $this->_writeDefaultContentType( + $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' + ); + + // XML + $this->_writeDefaultContentType( + $objWriter, 'xml', 'application/xml' + ); + + // VML + $this->_writeDefaultContentType( + $objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing' + ); + + // Workbook + if($pPHPExcel->hasMacros()){ //Macros in workbook ? + // Yes : not standard content but "macroEnabled" + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml' + ); + //... and define a new type for the VBA project + $this->_writeDefaultContentType( + $objWriter, 'bin', 'application/vnd.ms-office.vbaProject' + ); + if($pPHPExcel->hasMacrosCertificate()){// signed macros ? + // Yes : add needed information + $this->_writeOverrideContentType( + $objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature' + ); + } + }else{// no macros in workbook, so standard type + $this->_writeOverrideContentType( + $objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml' + ); + } + + // DocProps + $this->_writeOverrideContentType( + $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' + ); + + $this->_writeOverrideContentType( + $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' + ); + + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + $this->_writeOverrideContentType( + $objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + ); + } + + // Worksheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeOverrideContentType( + $objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' + ); + } + + // Shared strings + $this->_writeOverrideContentType( + $objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml' + ); + + // Add worksheet relationship content types + $chart = 1; + for ($i = 0; $i < $sheetCount; ++$i) { + $drawings = $pPHPExcel->getSheet($i)->getDrawingCollection(); + $drawingCount = count($drawings); + $chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0; + + // We need a drawing relationship for the worksheet if we have either drawings or charts + if (($drawingCount > 0) || ($chartCount > 0)) { + $this->_writeOverrideContentType( + $objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml' + ); + } + + // If we have charts, then we need a chart relationship for every individual chart + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeOverrideContentType( + $objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' + ); + } + } + } + + // Comments + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet($i)->getComments()) > 0) { + $this->_writeOverrideContentType( + $objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml' + ); + } + } + + // Add media content-types + $aMediaContentTypes = array(); + $mediaCount = $this->getParentWriter()->getDrawingHashTable()->count(); + for ($i = 0; $i < $mediaCount; ++$i) { + $extension = ''; + $mimeType = ''; + + if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); + $mimeType = $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() ); + } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) { + $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); + $extension = explode('/', $extension); + $extension = $extension[1]; + + $mimeType = $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType(); + } + + if (!isset( $aMediaContentTypes[$extension]) ) { + $aMediaContentTypes[$extension] = $mimeType; + + $this->_writeDefaultContentType( + $objWriter, $extension, $mimeType + ); + } + } + if($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ? + //we need to write "Extension" but not already write for media content + $tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes)); + foreach($tabRibbonTypes as $aRibbonType){ + $mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor + $this->_writeDefaultContentType( + $objWriter, $aRibbonType, $mimeType + ); + } + } + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + if (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) { + foreach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) { + if (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) { + $aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() ); + + $this->_writeDefaultContentType( + $objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())] + ); + } + } + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Get image mime type + * + * @param string $pFile Filename + * @return string Mime Type + * @throws PHPExcel_Writer_Exception + */ + private function _getImageMimeType($pFile = '') + { + if (PHPExcel_Shared_File::file_exists($pFile)) { + $image = getimagesize($pFile); + return image_type_to_mime_type($image[2]); + } else { + throw new PHPExcel_Writer_Exception("File $pFile does not exist"); + } + } + + /** + * Write Default content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Default'); + $objWriter->writeAttribute('Extension', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pPartname Part name + * @param string $pContentType Content type + * @throws PHPExcel_Writer_Exception + */ + private function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '') + { + if ($pPartname != '' && $pContentType != '') { + // Write content type + $objWriter->startElement('Override'); + $objWriter->writeAttribute('PartName', $pPartname); + $objWriter->writeAttribute('ContentType', $pContentType); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php new file mode 100755 index 0000000..cfc3089 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/DocProps.php @@ -0,0 +1,272 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_DocProps + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart +{ +/** + * Write docProps/app.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsApp(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Properties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + // Application + $objWriter->writeElement('Application', 'Microsoft Excel'); + + // DocSecurity + $objWriter->writeElement('DocSecurity', '0'); + + // ScaleCrop + $objWriter->writeElement('ScaleCrop', 'false'); + + // HeadingPairs + $objWriter->startElement('HeadingPairs'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', '2'); + $objWriter->writeAttribute('baseType', 'variant'); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:lpstr', 'Worksheets'); + $objWriter->endElement(); + + // Variant + $objWriter->startElement('vt:variant'); + $objWriter->writeElement('vt:i4', $pPHPExcel->getSheetCount()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // TitlesOfParts + $objWriter->startElement('TitlesOfParts'); + + // Vector + $objWriter->startElement('vt:vector'); + $objWriter->writeAttribute('size', $pPHPExcel->getSheetCount()); + $objWriter->writeAttribute('baseType', 'lpstr'); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle()); + } + + $objWriter->endElement(); + + $objWriter->endElement(); + + // Company + $objWriter->writeElement('Company', $pPHPExcel->getProperties()->getCompany()); + + // Company + $objWriter->writeElement('Manager', $pPHPExcel->getProperties()->getManager()); + + // LinksUpToDate + $objWriter->writeElement('LinksUpToDate', 'false'); + + // SharedDoc + $objWriter->writeElement('SharedDoc', 'false'); + + // HyperlinksChanged + $objWriter->writeElement('HyperlinksChanged', 'false'); + + // AppVersion + $objWriter->writeElement('AppVersion', '12.0000'); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/core.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCore(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('cp:coreProperties'); + $objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties'); + $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/'); + $objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/'); + $objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/'); + $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + + // dc:creator + $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator()); + + // cp:lastModifiedBy + $objWriter->writeElement('cp:lastModifiedBy', $pPHPExcel->getProperties()->getLastModifiedBy()); + + // dcterms:created + $objWriter->startElement('dcterms:created'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getCreated())); + $objWriter->endElement(); + + // dcterms:modified + $objWriter->startElement('dcterms:modified'); + $objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF'); + $objWriter->writeRawData(date(DATE_W3C, $pPHPExcel->getProperties()->getModified())); + $objWriter->endElement(); + + // dc:title + $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle()); + + // dc:description + $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription()); + + // dc:subject + $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject()); + + // cp:keywords + $objWriter->writeElement('cp:keywords', $pPHPExcel->getProperties()->getKeywords()); + + // cp:category + $objWriter->writeElement('cp:category', $pPHPExcel->getProperties()->getCategory()); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write docProps/custom.xml to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDocPropsCustom(PHPExcel $pPHPExcel = null) + { + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (empty($customPropertyList)) { + return; + } + + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // cp:coreProperties + $objWriter->startElement('Properties'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'); + $objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes'); + + + foreach($customPropertyList as $key => $customProperty) { + $propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty); + $propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty); + + $objWriter->startElement('property'); + $objWriter->writeAttribute('fmtid', '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}'); + $objWriter->writeAttribute('pid', $key+2); + $objWriter->writeAttribute('name', $customProperty); + + switch($propertyType) { + case 'i' : + $objWriter->writeElement('vt:i4', $propertyValue); + break; + case 'f' : + $objWriter->writeElement('vt:r8', $propertyValue); + break; + case 'b' : + $objWriter->writeElement('vt:bool', ($propertyValue) ? 'true' : 'false'); + break; + case 'd' : + $objWriter->startElement('vt:filetime'); + $objWriter->writeRawData(date(DATE_W3C, $propertyValue)); + $objWriter->endElement(); + break; + default : + $objWriter->writeElement('vt:lpwstr', $propertyValue); + break; + } + + $objWriter->endElement(); + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php new file mode 100755 index 0000000..3c52723 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Drawing.php @@ -0,0 +1,598 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Drawing + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write drawings to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // xdr:wsDr + $objWriter->startElement('xdr:wsDr'); + $objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + + // Loop through images and write drawings + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $this->_writeDrawing($objWriter, $iterator->current(), $i); + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + $chartCount = $pWorksheet->getChartCount(); + // Loop through charts and write the chart position + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i); + } + } + } + + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Chart $pChart + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1) + { + $tl = $pChart->getTopLeftPosition(); + $tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']); + $br = $pChart->getBottomRightPosition(); + $br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']); + + $objWriter->startElement('xdr:twoCellAnchor'); + + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset'])); + $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset'])); + $objWriter->endElement(); + $objWriter->startElement('xdr:to'); + $objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset'])); + $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset'])); + $objWriter->endElement(); + + $objWriter->startElement('xdr:graphicFrame'); + $objWriter->writeAttribute('macro', ''); + $objWriter->startElement('xdr:nvGraphicFramePr'); + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('name', 'Chart '.$pRelationId); + $objWriter->writeAttribute('id', 1025 * $pRelationId); + $objWriter->endElement(); + $objWriter->startElement('xdr:cNvGraphicFramePr'); + $objWriter->startElement('a:graphicFrameLocks'); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:xfrm'); + $objWriter->startElement('a:off'); + $objWriter->writeAttribute('x', '0'); + $objWriter->writeAttribute('y', '0'); + $objWriter->endElement(); + $objWriter->startElement('a:ext'); + $objWriter->writeAttribute('cx', '0'); + $objWriter->writeAttribute('cy', '0'); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('a:graphic'); + $objWriter->startElement('a:graphicData'); + $objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->startElement('c:chart'); + $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:id', 'rId'.$pRelationId); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + $objWriter->endElement(); + + $objWriter->startElement('xdr:clientData'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write drawings to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet_BaseDrawing $pDrawing + * @param int $pRelationId + * @throws PHPExcel_Writer_Exception + */ + public function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1) + { + if ($pRelationId >= 0) { + // xdr:oneCellAnchor + $objWriter->startElement('xdr:oneCellAnchor'); + // Image location + $aCoordinates = PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates()); + $aCoordinates[0] = PHPExcel_Cell::columnIndexFromString($aCoordinates[0]); + + // xdr:from + $objWriter->startElement('xdr:from'); + $objWriter->writeElement('xdr:col', $aCoordinates[0] - 1); + $objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX())); + $objWriter->writeElement('xdr:row', $aCoordinates[1] - 1); + $objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY())); + $objWriter->endElement(); + + // xdr:ext + $objWriter->startElement('xdr:ext'); + $objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth())); + $objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight())); + $objWriter->endElement(); + + // xdr:pic + $objWriter->startElement('xdr:pic'); + + // xdr:nvPicPr + $objWriter->startElement('xdr:nvPicPr'); + + // xdr:cNvPr + $objWriter->startElement('xdr:cNvPr'); + $objWriter->writeAttribute('id', $pRelationId); + $objWriter->writeAttribute('name', $pDrawing->getName()); + $objWriter->writeAttribute('descr', $pDrawing->getDescription()); + $objWriter->endElement(); + + // xdr:cNvPicPr + $objWriter->startElement('xdr:cNvPicPr'); + + // a:picLocks + $objWriter->startElement('a:picLocks'); + $objWriter->writeAttribute('noChangeAspect', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:blipFill + $objWriter->startElement('xdr:blipFill'); + + // a:blip + $objWriter->startElement('a:blip'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:embed', 'rId' . $pRelationId); + $objWriter->endElement(); + + // a:stretch + $objWriter->startElement('a:stretch'); + $objWriter->writeElement('a:fillRect', null); + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:spPr + $objWriter->startElement('xdr:spPr'); + + // a:xfrm + $objWriter->startElement('a:xfrm'); + $objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation())); + $objWriter->endElement(); + + // a:prstGeom + $objWriter->startElement('a:prstGeom'); + $objWriter->writeAttribute('prst', 'rect'); + + // a:avLst + $objWriter->writeElement('a:avLst', null); + + $objWriter->endElement(); + +// // a:solidFill +// $objWriter->startElement('a:solidFill'); + +// // a:srgbClr +// $objWriter->startElement('a:srgbClr'); +// $objWriter->writeAttribute('val', 'FFFFFF'); + +///* SHADE +// // a:shade +// $objWriter->startElement('a:shade'); +// $objWriter->writeAttribute('val', '85000'); +// $objWriter->endElement(); +//*/ + +// $objWriter->endElement(); + +// $objWriter->endElement(); +/* + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '88900'); + $objWriter->writeAttribute('cap', 'sq'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:miter + $objWriter->startElement('a:miter'); + $objWriter->writeAttribute('lim', '800000'); + $objWriter->endElement(); + + $objWriter->endElement(); +*/ + + if ($pDrawing->getShadow()->getVisible()) { + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius())); + $objWriter->writeAttribute('dist', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance())); + $objWriter->writeAttribute('dir', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection())); + $objWriter->writeAttribute('algn', $pDrawing->getShadow()->getAlignment()); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getColor()->getRGB()); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', $pDrawing->getShadow()->getAlpha() * 1000); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } +/* + + // a:scene3d + $objWriter->startElement('a:scene3d'); + + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + $objWriter->endElement(); + + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'twoPt'); + $objWriter->writeAttribute('dir', 't'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); +*/ +/* + // a:sp3d + $objWriter->startElement('a:sp3d'); + + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('h', '19050'); + $objWriter->endElement(); + + // a:contourClr + $objWriter->startElement('a:contourClr'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); +*/ + $objWriter->endElement(); + + $objWriter->endElement(); + + // xdr:clientData + $objWriter->writeElement('xdr:clientData', null); + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write VML header/footer images to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Header/footer images + $images = $pWorksheet->getHeaderFooter()->getImages(); + + // xml + $objWriter->startElement('xml'); + $objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml'); + $objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office'); + $objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel'); + + // o:shapelayout + $objWriter->startElement('o:shapelayout'); + $objWriter->writeAttribute('v:ext', 'edit'); + + // o:idmap + $objWriter->startElement('o:idmap'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('data', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:shapetype + $objWriter->startElement('v:shapetype'); + $objWriter->writeAttribute('id', '_x0000_t75'); + $objWriter->writeAttribute('coordsize', '21600,21600'); + $objWriter->writeAttribute('o:spt', '75'); + $objWriter->writeAttribute('o:preferrelative', 't'); + $objWriter->writeAttribute('path', 'm@4@5l@4@11@9@11@9@5xe'); + $objWriter->writeAttribute('filled', 'f'); + $objWriter->writeAttribute('stroked', 'f'); + + // v:stroke + $objWriter->startElement('v:stroke'); + $objWriter->writeAttribute('joinstyle', 'miter'); + $objWriter->endElement(); + + // v:formulas + $objWriter->startElement('v:formulas'); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'if lineDrawn pixelLineWidth 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 1 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum 0 0 @1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @2 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @3 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @0 0 1'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @6 1 2'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelWidth'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @8 21600 0'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'prod @7 21600 pixelHeight'); + $objWriter->endElement(); + + // v:f + $objWriter->startElement('v:f'); + $objWriter->writeAttribute('eqn', 'sum @10 21600 0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // v:path + $objWriter->startElement('v:path'); + $objWriter->writeAttribute('o:extrusionok', 'f'); + $objWriter->writeAttribute('gradientshapeok', 't'); + $objWriter->writeAttribute('o:connecttype', 'rect'); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('aspectratio', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Loop through images + foreach ($images as $key => $value) { + $this->_writeVMLHeaderFooterImage($objWriter, $key, $value); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write VML comment to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pReference Reference + * @param PHPExcel_Worksheet_HeaderFooterDrawing $pImage Image + * @throws PHPExcel_Writer_Exception + */ + public function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null) + { + // Calculate object id + preg_match('{(\d+)}', md5($pReference), $m); + $id = 1500 + (substr($m[1], 0, 2) * 1); + + // Calculate offset + $width = $pImage->getWidth(); + $height = $pImage->getHeight(); + $marginLeft = $pImage->getOffsetX(); + $marginTop = $pImage->getOffsetY(); + + // v:shape + $objWriter->startElement('v:shape'); + $objWriter->writeAttribute('id', $pReference); + $objWriter->writeAttribute('o:spid', '_x0000_s' . $id); + $objWriter->writeAttribute('type', '#_x0000_t75'); + $objWriter->writeAttribute('style', "position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1"); + + // v:imagedata + $objWriter->startElement('v:imagedata'); + $objWriter->writeAttribute('o:relid', 'rId' . $pReference); + $objWriter->writeAttribute('o:title', $pImage->getName()); + $objWriter->endElement(); + + // o:lock + $objWriter->startElement('o:lock'); + $objWriter->writeAttribute('v:ext', 'edit'); + $objWriter->writeAttribute('rotation', 't'); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + + /** + * Get an array of all drawings + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Worksheet_Drawing[] All drawings in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allDrawings(PHPExcel $pPHPExcel = null) + { + // Get an array of all drawings + $aDrawings = array(); + + // Loop through PHPExcel + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // Loop through images and add to array + $iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + $aDrawings[] = $iterator->current(); + + $iterator->next(); + } + } + + return $aDrawings; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Rels.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Rels.php new file mode 100755 index 0000000..0bdb667 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Rels.php @@ -0,0 +1,437 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Rels + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + $customPropertyList = $pPHPExcel->getProperties()->getCustomProperties(); + if (!empty($customPropertyList)) { + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 4, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties', + 'docProps/custom.xml' + ); + + } + + // Relationship docProps/app.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties', + 'docProps/app.xml' + ); + + // Relationship docProps/core.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties', + 'docProps/core.xml' + ); + + // Relationship xl/workbook.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument', + 'xl/workbook.xml' + ); + // a custom UI in workbook ? + if($pPHPExcel->hasRibbon()){ + $this->_writeRelationShip( + $objWriter, + 5, + 'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility', + $pPHPExcel->getRibbonXMLData('target') + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write workbook relationships to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbookRelationships(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Relationship styles.xml + $this->_writeRelationship( + $objWriter, + 1, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles', + 'styles.xml' + ); + + // Relationship theme/theme1.xml + $this->_writeRelationship( + $objWriter, + 2, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme', + 'theme/theme1.xml' + ); + + // Relationship sharedStrings.xml + $this->_writeRelationship( + $objWriter, + 3, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings', + 'sharedStrings.xml' + ); + + // Relationships with sheets + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + $this->_writeRelationship( + $objWriter, + ($i + 1 + 3), + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet', + 'worksheets/sheet' . ($i + 1) . '.xml' + ); + } + // Relationships for vbaProject if needed + // id : just after the last sheet + if($pPHPExcel->hasMacros()){ + $this->_writeRelationShip( + $objWriter, + ($i + 1 + 3), + 'http://schemas.microsoft.com/office/2006/relationships/vbaProject', + 'vbaProject.bin' + ); + ++$i;//increment i if needed for an another relation + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write worksheet relationships to XML format + * + * Numbering is as follows: + * rId1 - Drawings + * rId_hyperlink_x - Hyperlinks + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int $pWorksheetId + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Write drawing relationships? + $d = 0; + if ($includeCharts) { + $charts = $pWorksheet->getChartCollection(); + } else { + $charts = array(); + } + if (($pWorksheet->getDrawingCollection()->count() > 0) || + (count($charts) > 0)) { + $this->_writeRelationship( + $objWriter, + ++$d, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', + '../drawings/drawing' . $pWorksheetId . '.xml' + ); + } + + // Write chart relationships? +// $chartCount = 0; +// $charts = $pWorksheet->getChartCollection(); +// echo 'Chart Rels: ' , count($charts) , '<br />'; +// if (count($charts) > 0) { +// foreach($charts as $chart) { +// $this->_writeRelationship( +// $objWriter, +// ++$d, +// 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', +// '../charts/chart' . ++$chartCount . '.xml' +// ); +// } +// } +// + // Write hyperlink relationships? + $i = 1; + foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) { + if (!$hyperlink->isInternal()) { + $this->_writeRelationship( + $objWriter, + '_hyperlink_' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', + $hyperlink->getUrl(), + 'External' + ); + + ++$i; + } + } + + // Write comments relationship? + $i = 1; + if (count($pWorksheet->getComments()) > 0) { + $this->_writeRelationship( + $objWriter, + '_comments_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawing' . $pWorksheetId . '.vml' + ); + + $this->_writeRelationship( + $objWriter, + '_comments' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', + '../comments' . $pWorksheetId . '.xml' + ); + } + + // Write header/footer relationship? + $i = 1; + if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) { + $this->_writeRelationship( + $objWriter, + '_headerfooter_vml' . $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', + '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml' + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @param int &$chartRef Chart ID + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + $i = 1; + $iterator = $pWorksheet->getDrawingCollection()->getIterator(); + while ($iterator->valid()) { + if ($iterator->current() instanceof PHPExcel_Worksheet_Drawing + || $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + ); + } + + $iterator->next(); + ++$i; + } + + if ($includeCharts) { + // Loop through charts and write relationships + $chartCount = $pWorksheet->getChartCount(); + if ($chartCount > 0) { + for ($c = 0; $c < $chartCount; ++$c) { + $this->_writeRelationship( + $objWriter, + $i++, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', + '../charts/chart' . ++$chartRef . '.xml' + ); + } + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write header/footer drawing relationships to XML format + * + * @param PHPExcel_Worksheet $pWorksheet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Loop through images and write relationships + foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) { + // Write relationship for image drawing + $this->_writeRelationship( + $objWriter, + $key, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', + '../media/' . $value->getIndexedFilename() + ); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Override content type + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param int $pId Relationship ID. rId will be prepended! + * @param string $pType Relationship type + * @param string $pTarget Relationship target + * @param string $pTargetMode Relationship target mode + * @throws PHPExcel_Writer_Exception + */ + private function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') + { + if ($pType != '' && $pTarget != '') { + // Write relationship + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId' . $pId); + $objWriter->writeAttribute('Type', $pType); + $objWriter->writeAttribute('Target', $pTarget); + + if ($pTargetMode != '') { + $objWriter->writeAttribute('TargetMode', $pTargetMode); + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php new file mode 100755 index 0000000..f924a1d --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsRibbon.php @@ -0,0 +1,77 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_RelsRibbon + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships for additional objects of custom UI (ribbon) + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeRibbonRelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $localRels=$pPHPExcel->getRibbonBinObjects('names'); + if(is_array($localRels)){ + foreach($localRels as $aId=>$aTarget){ + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', $aId); + $objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'); + $objWriter->writeAttribute('Target', $aTarget); + $objWriter->endElement();//Relationship + } + } + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php new file mode 100755 index 0000000..aecb0b8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/RelsVBA.php @@ -0,0 +1,72 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_RelsVBA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write relationships for a signed VBA Project + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeVBARelationships(PHPExcel $pPHPExcel = null){ + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', 'rId1'); + $objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature'); + $objWriter->writeAttribute('Target', 'vbaProjectSignature.bin'); + $objWriter->endElement();//Relationship + $objWriter->endElement();//Relationships + + // Return + return $objWriter->getData(); + + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php new file mode 100755 index 0000000..0e8a259 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/StringTable.php @@ -0,0 +1,319 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_StringTable + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Create worksheet stringtable + * + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pExistingTable Existing table to eventually merge with + * @return string[] String table for worksheet + * @throws PHPExcel_Writer_Exception + */ + public function createStringTable($pSheet = null, $pExistingTable = null) + { + if ($pSheet !== NULL) { + // Create string lookup table + $aStringTable = array(); + $cellCollection = null; + $aFlippedStringTable = null; // For faster lookup + + // Is an existing table given? + if (($pExistingTable !== NULL) && is_array($pExistingTable)) { + $aStringTable = $pExistingTable; + } + + // Fill index array + $aFlippedStringTable = $this->flipStringTable($aStringTable); + + // Loop through cells + foreach ($pSheet->getCellCollection() as $cellID) { + $cell = $pSheet->getCell($cellID); + $cellValue = $cell->getValue(); + if (!is_object($cellValue) && + ($cellValue !== NULL) && + $cellValue !== '' && + !isset($aFlippedStringTable[$cellValue]) && + ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue] = true; + } elseif ($cellValue instanceof PHPExcel_RichText && + ($cellValue !== NULL) && + !isset($aFlippedStringTable[$cellValue->getHashCode()])) { + $aStringTable[] = $cellValue; + $aFlippedStringTable[$cellValue->getHashCode()] = true; + } + } + + // Return + return $aStringTable; + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write string table to XML format + * + * @param string[] $pStringTable + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStringTable($pStringTable = null) + { + if ($pStringTable !== NULL) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // String table + $objWriter->startElement('sst'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('uniqueCount', count($pStringTable)); + + // Loop through string table + foreach ($pStringTable as $textElement) { + $objWriter->startElement('si'); + + if (! $textElement instanceof PHPExcel_RichText) { + $textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement ); + $objWriter->startElement('t'); + if ($textToWrite !== trim($textToWrite)) { + $objWriter->writeAttribute('xml:space', 'preserve'); + } + $objWriter->writeRawData($textToWrite); + $objWriter->endElement(); + } else if ($textElement instanceof PHPExcel_RichText) { + $this->writeRichText($objWriter, $textElement); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid string table array passed."); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_RichText $pRichText Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL) + { + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + if ($element instanceof PHPExcel_RichText_Run) { + // rPr + $objWriter->startElement($prefix.'rPr'); + + // rFont + $objWriter->startElement($prefix.'rFont'); + $objWriter->writeAttribute('val', $element->getFont()->getName()); + $objWriter->endElement(); + + // Bold + $objWriter->startElement($prefix.'b'); + $objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false')); + $objWriter->endElement(); + + // Italic + $objWriter->startElement($prefix.'i'); + $objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false')); + $objWriter->endElement(); + + // Superscript / subscript + if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { + $objWriter->startElement($prefix.'vertAlign'); + if ($element->getFont()->getSuperScript()) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($element->getFont()->getSubScript()) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Strikethrough + $objWriter->startElement($prefix.'strike'); + $objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false')); + $objWriter->endElement(); + + // Color + $objWriter->startElement($prefix.'color'); + $objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB()); + $objWriter->endElement(); + + // Size + $objWriter->startElement($prefix.'sz'); + $objWriter->writeAttribute('val', $element->getFont()->getSize()); + $objWriter->endElement(); + + // Underline + $objWriter->startElement($prefix.'u'); + $objWriter->writeAttribute('val', $element->getFont()->getUnderline()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + // t + $objWriter->startElement($prefix.'t'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write Rich Text + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string|PHPExcel_RichText $pRichText text string or Rich text + * @param string $prefix Optional Namespace prefix + * @throws PHPExcel_Writer_Exception + */ + public function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL) + { + if (!$pRichText instanceof PHPExcel_RichText) { + $textRun = $pRichText; + $pRichText = new PHPExcel_RichText(); + $pRichText->createTextRun($textRun); + } + + if ($prefix !== NULL) + $prefix .= ':'; + // Loop through rich text elements + $elements = $pRichText->getRichTextElements(); + foreach ($elements as $element) { + // r + $objWriter->startElement($prefix.'r'); + + // rPr + $objWriter->startElement($prefix.'rPr'); + + // Bold + $objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0)); + // Italic + $objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0)); + // Underline + $underlineType = $element->getFont()->getUnderline(); + switch($underlineType) { + case 'single' : + $underlineType = 'sng'; + break; + case 'double' : + $underlineType = 'dbl'; + break; + } + $objWriter->writeAttribute('u', $underlineType); + // Strikethrough + $objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike')); + + // rFont + $objWriter->startElement($prefix.'latin'); + $objWriter->writeAttribute('typeface', $element->getFont()->getName()); + $objWriter->endElement(); + + // Superscript / subscript +// if ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) { +// $objWriter->startElement($prefix.'vertAlign'); +// if ($element->getFont()->getSuperScript()) { +// $objWriter->writeAttribute('val', 'superscript'); +// } else if ($element->getFont()->getSubScript()) { +// $objWriter->writeAttribute('val', 'subscript'); +// } +// $objWriter->endElement(); +// } +// + $objWriter->endElement(); + + // t + $objWriter->startElement($prefix.'t'); +// $objWriter->writeAttribute('xml:space', 'preserve'); // Excel2010 accepts, Excel2007 complains + $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() )); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Flip string table (for index searching) + * + * @param array $stringTable Stringtable + * @return array + */ + public function flipStringTable($stringTable = array()) { + // Return value + $returnValue = array(); + + // Loop through stringtable and add flipped items to $returnValue + foreach ($stringTable as $key => $value) { + if (! $value instanceof PHPExcel_RichText) { + $returnValue[$value] = $key; + } else if ($value instanceof PHPExcel_RichText) { + $returnValue[$value->getHashCode()] = $key; + } + } + + // Return + return $returnValue; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Style.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Style.php new file mode 100755 index 0000000..849ad12 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Style.php @@ -0,0 +1,704 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Style + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write styles to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeStyles(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // styleSheet + $objWriter->startElement('styleSheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + // numFmts + $objWriter->startElement('numFmts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count()); + + // numFmt + for ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) { + $this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i); + } + + $objWriter->endElement(); + + // fonts + $objWriter->startElement('fonts'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count()); + + // font + for ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) { + $this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // fills + $objWriter->startElement('fills'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count()); + + // fill + for ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) { + $this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // borders + $objWriter->startElement('borders'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count()); + + // border + for ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) { + $this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i)); + } + + $objWriter->endElement(); + + // cellStyleXfs + $objWriter->startElement('cellStyleXfs'); + $objWriter->writeAttribute('count', 1); + + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('numFmtId', 0); + $objWriter->writeAttribute('fontId', 0); + $objWriter->writeAttribute('fillId', 0); + $objWriter->writeAttribute('borderId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // cellXfs + $objWriter->startElement('cellXfs'); + $objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection())); + + // xf + foreach ($pPHPExcel->getCellXfCollection() as $cellXf) { + $this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel); + } + + $objWriter->endElement(); + + // cellStyles + $objWriter->startElement('cellStyles'); + $objWriter->writeAttribute('count', 1); + + // cellStyle + $objWriter->startElement('cellStyle'); + $objWriter->writeAttribute('name', 'Normal'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('builtinId', 0); + $objWriter->endElement(); + + $objWriter->endElement(); + + // dxfs + $objWriter->startElement('dxfs'); + $objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count()); + + // dxf + for ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) { + $this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle()); + } + + $objWriter->endElement(); + + // tableStyles + $objWriter->startElement('tableStyles'); + $objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9'); + $objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // Check if this is a pattern type or gradient type + if ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR || + $pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) { + // Gradient fill + $this->_writeGradientFill($objWriter, $pFill); + } elseif($pFill->getFillType() !== NULL) { + // Pattern fill + $this->_writePatternFill($objWriter, $pFill); + } + } + + /** + * Write Gradient Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // gradientFill + $objWriter->startElement('gradientFill'); + $objWriter->writeAttribute('type', $pFill->getFillType()); + $objWriter->writeAttribute('degree', $pFill->getRotation()); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '0'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + // stop + $objWriter->startElement('stop'); + $objWriter->writeAttribute('position', '1'); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Pattern Fill + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Fill $pFill Fill style + * @throws PHPExcel_Writer_Exception + */ + private function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null) + { + // fill + $objWriter->startElement('fill'); + + // patternFill + $objWriter->startElement('patternFill'); + $objWriter->writeAttribute('patternType', $pFill->getFillType()); + + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // fgColor + if ($pFill->getStartColor()->getARGB()) { + $objWriter->startElement('fgColor'); + $objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB()); + $objWriter->endElement(); + } + } + if ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) { + // bgColor + if ($pFill->getEndColor()->getARGB()) { + $objWriter->startElement('bgColor'); + $objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB()); + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write Font + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Font $pFont Font style + * @throws PHPExcel_Writer_Exception + */ + private function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null) + { + // font + $objWriter->startElement('font'); + // Weird! The order of these elements actually makes a difference when opening Excel2007 + // files in Excel2003 with the compatibility pack. It's not documented behaviour, + // and makes for a real WTF! + + // Bold. We explicitly write this element also when false (like MS Office Excel 2007 does + // for conditional formatting). Otherwise it will apparently not be picked up in conditional + // formatting style dialog + if ($pFont->getBold() !== NULL) { + $objWriter->startElement('b'); + $objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0'); + $objWriter->endElement(); + } + + // Italic + if ($pFont->getItalic() !== NULL) { + $objWriter->startElement('i'); + $objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0'); + $objWriter->endElement(); + } + + // Strikethrough + if ($pFont->getStrikethrough() !== NULL) { + $objWriter->startElement('strike'); + $objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0'); + $objWriter->endElement(); + } + + // Underline + if ($pFont->getUnderline() !== NULL) { + $objWriter->startElement('u'); + $objWriter->writeAttribute('val', $pFont->getUnderline()); + $objWriter->endElement(); + } + + // Superscript / subscript + if ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) { + $objWriter->startElement('vertAlign'); + if ($pFont->getSuperScript() === TRUE) { + $objWriter->writeAttribute('val', 'superscript'); + } else if ($pFont->getSubScript() === TRUE) { + $objWriter->writeAttribute('val', 'subscript'); + } + $objWriter->endElement(); + } + + // Size + if ($pFont->getSize() !== NULL) { + $objWriter->startElement('sz'); + $objWriter->writeAttribute('val', $pFont->getSize()); + $objWriter->endElement(); + } + + // Foreground color + if ($pFont->getColor()->getARGB() !== NULL) { + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB()); + $objWriter->endElement(); + } + + // Name + if ($pFont->getName() !== NULL) { + $objWriter->startElement('name'); + $objWriter->writeAttribute('val', $pFont->getName()); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Border + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_Borders $pBorders Borders style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null) + { + // Write border + $objWriter->startElement('border'); + // Diagonal? + switch ($pBorders->getDiagonalDirection()) { + case PHPExcel_Style_Borders::DIAGONAL_UP: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'false'); + break; + case PHPExcel_Style_Borders::DIAGONAL_DOWN: + $objWriter->writeAttribute('diagonalUp', 'false'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + case PHPExcel_Style_Borders::DIAGONAL_BOTH: + $objWriter->writeAttribute('diagonalUp', 'true'); + $objWriter->writeAttribute('diagonalDown', 'true'); + break; + } + + // BorderPr + $this->_writeBorderPr($objWriter, 'left', $pBorders->getLeft()); + $this->_writeBorderPr($objWriter, 'right', $pBorders->getRight()); + $this->_writeBorderPr($objWriter, 'top', $pBorders->getTop()); + $this->_writeBorderPr($objWriter, 'bottom', $pBorders->getBottom()); + $this->_writeBorderPr($objWriter, 'diagonal', $pBorders->getDiagonal()); + $objWriter->endElement(); + } + + /** + * Write Cell Style Xf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @param PHPExcel $pPHPExcel Workbook + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null) + { + // xf + $objWriter->startElement('xf'); + $objWriter->writeAttribute('xfId', 0); + $objWriter->writeAttribute('fontId', (int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode())); + if ($pStyle->getQuotePrefix()) { + $objWriter->writeAttribute('quotePrefix', 1); + } + + if ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) { + $objWriter->writeAttribute('numFmtId', (int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164) ); + } else { + $objWriter->writeAttribute('numFmtId', (int)$pStyle->getNumberFormat()->getBuiltInFormatCode()); + } + + $objWriter->writeAttribute('fillId', (int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode())); + $objWriter->writeAttribute('borderId', (int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode())); + + // Apply styles? + $objWriter->writeAttribute('applyFont', ($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyFill', ($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyBorder', ($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0'); + $objWriter->writeAttribute('applyAlignment', ($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('applyProtection', 'true'); + } + + // alignment + $objWriter->startElement('alignment'); + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + + $objWriter->writeAttribute('wrapText', ($pStyle->getAlignment()->getWrapText() ? 'true' : 'false')); + $objWriter->writeAttribute('shrinkToFit', ($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false')); + + if ($pStyle->getAlignment()->getIndent() > 0) { + $objWriter->writeAttribute('indent', $pStyle->getAlignment()->getIndent()); + } + $objWriter->endElement(); + + // protection + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Cell Style Dxf + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style $pStyle Style + * @throws PHPExcel_Writer_Exception + */ + private function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null) + { + // dxf + $objWriter->startElement('dxf'); + + // font + $this->_writeFont($objWriter, $pStyle->getFont()); + + // numFmt + $this->_writeNumFmt($objWriter, $pStyle->getNumberFormat()); + + // fill + $this->_writeFill($objWriter, $pStyle->getFill()); + + // alignment + $objWriter->startElement('alignment'); + if ($pStyle->getAlignment()->getHorizontal() !== NULL) { + $objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal()); + } + if ($pStyle->getAlignment()->getVertical() !== NULL) { + $objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical()); + } + + if ($pStyle->getAlignment()->getTextRotation() !== NULL) { + $textRotation = 0; + if ($pStyle->getAlignment()->getTextRotation() >= 0) { + $textRotation = $pStyle->getAlignment()->getTextRotation(); + } else if ($pStyle->getAlignment()->getTextRotation() < 0) { + $textRotation = 90 - $pStyle->getAlignment()->getTextRotation(); + } + $objWriter->writeAttribute('textRotation', $textRotation); + } + $objWriter->endElement(); + + // border + $this->_writeBorder($objWriter, $pStyle->getBorders()); + + // protection + if (($pStyle->getProtection()->getLocked() !== NULL) || + ($pStyle->getProtection()->getHidden() !== NULL)) { + if ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT || + $pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) { + $objWriter->startElement('protection'); + if (($pStyle->getProtection()->getLocked() !== NULL) && + ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + if (($pStyle->getProtection()->getHidden() !== NULL) && + ($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) { + $objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false')); + } + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } + + /** + * Write BorderPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pName Element name + * @param PHPExcel_Style_Border $pBorder Border style + * @throws PHPExcel_Writer_Exception + */ + private function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null) + { + // Write BorderPr + if ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) { + $objWriter->startElement($pName); + $objWriter->writeAttribute('style', $pBorder->getBorderStyle()); + + // color + $objWriter->startElement('color'); + $objWriter->writeAttribute('rgb', $pBorder->getColor()->getARGB()); + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + + /** + * Write NumberFormat + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Style_NumberFormat $pNumberFormat Number Format + * @param int $pId Number Format identifier + * @throws PHPExcel_Writer_Exception + */ + private function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0) + { + // Translate formatcode + $formatCode = $pNumberFormat->getFormatCode(); + + // numFmt + if ($formatCode !== NULL) { + $objWriter->startElement('numFmt'); + $objWriter->writeAttribute('numFmtId', ($pId + 164)); + $objWriter->writeAttribute('formatCode', $formatCode); + $objWriter->endElement(); + } + } + + /** + * Get an array of all styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style[] All styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allStyles(PHPExcel $pPHPExcel = null) + { + $aStyles = $pPHPExcel->getCellXfCollection(); + + return $aStyles; + } + + /** + * Get an array of all conditional styles + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Conditional[] All conditional styles in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allConditionalStyles(PHPExcel $pPHPExcel = null) + { + // Get an array of all styles + $aStyles = array(); + + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + foreach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) { + foreach ($conditionalStyles as $conditionalStyle) { + $aStyles[] = $conditionalStyle; + } + } + } + + return $aStyles; + } + + /** + * Get an array of all fills + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Fill[] All fills in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFills(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fills + $aFills = array(); + + // Two first fills are predefined + $fill0 = new PHPExcel_Style_Fill(); + $fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE); + $aFills[] = $fill0; + + $fill1 = new PHPExcel_Style_Fill(); + $fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125); + $aFills[] = $fill1; + // The remaining fills + $aStyles = $this->allStyles($pPHPExcel); + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFill()->getHashCode(), $aFills)) { + $aFills[ $style->getFill()->getHashCode() ] = $style->getFill(); + } + } + + return $aFills; + } + + /** + * Get an array of all fonts + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Font[] All fonts in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allFonts(PHPExcel $pPHPExcel = null) + { + // Get an array of unique fonts + $aFonts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) { + $aFonts[ $style->getFont()->getHashCode() ] = $style->getFont(); + } + } + + return $aFonts; + } + + /** + * Get an array of all borders + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_Borders[] All borders in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allBorders(PHPExcel $pPHPExcel = null) + { + // Get an array of unique borders + $aBorders = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) { + $aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders(); + } + } + + return $aBorders; + } + + /** + * Get an array of all number formats + * + * @param PHPExcel $pPHPExcel + * @return PHPExcel_Style_NumberFormat[] All number formats in PHPExcel + * @throws PHPExcel_Writer_Exception + */ + public function allNumberFormats(PHPExcel $pPHPExcel = null) + { + // Get an array of unique number formats + $aNumFmts = array(); + $aStyles = $this->allStyles($pPHPExcel); + + foreach ($aStyles as $style) { + if ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) { + $aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat(); + } + } + + return $aNumFmts; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Theme.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Theme.php new file mode 100755 index 0000000..064c3ed --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Theme.php @@ -0,0 +1,871 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Theme + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Map of Major fonts to write + * @static array of string + * + */ + private static $_majorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Times New Roman', + 'Hebr' => 'Times New Roman', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'MoolBoran', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Times New Roman', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of Minor fonts to write + * @static array of string + * + */ + private static $_minorFonts = array( + 'Jpan' => 'MS Pゴシック', + 'Hang' => '맑은 고딕', + 'Hans' => '宋体', + 'Hant' => '新細明體', + 'Arab' => 'Arial', + 'Hebr' => 'Arial', + 'Thai' => 'Tahoma', + 'Ethi' => 'Nyala', + 'Beng' => 'Vrinda', + 'Gujr' => 'Shruti', + 'Khmr' => 'DaunPenh', + 'Knda' => 'Tunga', + 'Guru' => 'Raavi', + 'Cans' => 'Euphemia', + 'Cher' => 'Plantagenet Cherokee', + 'Yiii' => 'Microsoft Yi Baiti', + 'Tibt' => 'Microsoft Himalaya', + 'Thaa' => 'MV Boli', + 'Deva' => 'Mangal', + 'Telu' => 'Gautami', + 'Taml' => 'Latha', + 'Syrc' => 'Estrangelo Edessa', + 'Orya' => 'Kalinga', + 'Mlym' => 'Kartika', + 'Laoo' => 'DokChampa', + 'Sinh' => 'Iskoola Pota', + 'Mong' => 'Mongolian Baiti', + 'Viet' => 'Arial', + 'Uigh' => 'Microsoft Uighur', + 'Geor' => 'Sylfaen', + ); + + /** + * Map of core colours + * @static array of string + * + */ + private static $_colourScheme = array( + 'dk2' => '1F497D', + 'lt2' => 'EEECE1', + 'accent1' => '4F81BD', + 'accent2' => 'C0504D', + 'accent3' => '9BBB59', + 'accent4' => '8064A2', + 'accent5' => '4BACC6', + 'accent6' => 'F79646', + 'hlink' => '0000FF', + 'folHlink' => '800080', + ); + + /** + * Write theme to XML format + * + * @param PHPExcel $pPHPExcel + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeTheme(PHPExcel $pPHPExcel = null) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // a:theme + $objWriter->startElement('a:theme'); + $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main'); + $objWriter->writeAttribute('name', 'Office Theme'); + + // a:themeElements + $objWriter->startElement('a:themeElements'); + + // a:clrScheme + $objWriter->startElement('a:clrScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:dk1 + $objWriter->startElement('a:dk1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'windowText'); + $objWriter->writeAttribute('lastClr', '000000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lt1 + $objWriter->startElement('a:lt1'); + + // a:sysClr + $objWriter->startElement('a:sysClr'); + $objWriter->writeAttribute('val', 'window'); + $objWriter->writeAttribute('lastClr', 'FFFFFF'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:dk2 + $this->_writeColourScheme($objWriter); + + $objWriter->endElement(); + + // a:fontScheme + $objWriter->startElement('a:fontScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:majorFont + $objWriter->startElement('a:majorFont'); + $this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts); + $objWriter->endElement(); + + // a:minorFont + $objWriter->startElement('a:minorFont'); + $this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:fmtScheme + $objWriter->startElement('a:fmtScheme'); + $objWriter->writeAttribute('name', 'Office'); + + // a:fillStyleLst + $objWriter->startElement('a:fillStyleLst'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '50000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '35000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '37000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '15000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '1'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '51000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '80000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '93000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '130000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '94000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '135000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lin + $objWriter->startElement('a:lin'); + $objWriter->writeAttribute('ang', '16200000'); + $objWriter->writeAttribute('scaled', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lnStyleLst + $objWriter->startElement('a:lnStyleLst'); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '9525'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '95000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '105000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '25400'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:ln + $objWriter->startElement('a:ln'); + $objWriter->writeAttribute('w', '38100'); + $objWriter->writeAttribute('cap', 'flat'); + $objWriter->writeAttribute('cmpd', 'sng'); + $objWriter->writeAttribute('algn', 'ctr'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:prstDash + $objWriter->startElement('a:prstDash'); + $objWriter->writeAttribute('val', 'solid'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + + + // a:effectStyleLst + $objWriter->startElement('a:effectStyleLst'); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '20000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '38000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:effectStyle + $objWriter->startElement('a:effectStyle'); + + // a:effectLst + $objWriter->startElement('a:effectLst'); + + // a:outerShdw + $objWriter->startElement('a:outerShdw'); + $objWriter->writeAttribute('blurRad', '40000'); + $objWriter->writeAttribute('dist', '23000'); + $objWriter->writeAttribute('dir', '5400000'); + $objWriter->writeAttribute('rotWithShape', '0'); + + // a:srgbClr + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', '000000'); + + // a:alpha + $objWriter->startElement('a:alpha'); + $objWriter->writeAttribute('val', '35000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:scene3d + $objWriter->startElement('a:scene3d'); + + // a:camera + $objWriter->startElement('a:camera'); + $objWriter->writeAttribute('prst', 'orthographicFront'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '0'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:lightRig + $objWriter->startElement('a:lightRig'); + $objWriter->writeAttribute('rig', 'threePt'); + $objWriter->writeAttribute('dir', 't'); + + // a:rot + $objWriter->startElement('a:rot'); + $objWriter->writeAttribute('lat', '0'); + $objWriter->writeAttribute('lon', '0'); + $objWriter->writeAttribute('rev', '1200000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:sp3d + $objWriter->startElement('a:sp3d'); + + // a:bevelT + $objWriter->startElement('a:bevelT'); + $objWriter->writeAttribute('w', '63500'); + $objWriter->writeAttribute('h', '25400'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:bgFillStyleLst + $objWriter->startElement('a:bgFillStyleLst'); + + // a:solidFill + $objWriter->startElement('a:solidFill'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '40000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '40000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '45000'); + $objWriter->endElement(); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '99000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '350000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '20000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '255000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '-80000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '180000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gradFill + $objWriter->startElement('a:gradFill'); + $objWriter->writeAttribute('rotWithShape', '1'); + + // a:gsLst + $objWriter->startElement('a:gsLst'); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '0'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:tint + $objWriter->startElement('a:tint'); + $objWriter->writeAttribute('val', '80000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '300000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:gs + $objWriter->startElement('a:gs'); + $objWriter->writeAttribute('pos', '100000'); + + // a:schemeClr + $objWriter->startElement('a:schemeClr'); + $objWriter->writeAttribute('val', 'phClr'); + + // a:shade + $objWriter->startElement('a:shade'); + $objWriter->writeAttribute('val', '30000'); + $objWriter->endElement(); + + // a:satMod + $objWriter->startElement('a:satMod'); + $objWriter->writeAttribute('val', '200000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:path + $objWriter->startElement('a:path'); + $objWriter->writeAttribute('path', 'circle'); + + // a:fillToRect + $objWriter->startElement('a:fillToRect'); + $objWriter->writeAttribute('l', '50000'); + $objWriter->writeAttribute('t', '50000'); + $objWriter->writeAttribute('r', '50000'); + $objWriter->writeAttribute('b', '50000'); + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + $objWriter->endElement(); + + // a:objectDefaults + $objWriter->writeElement('a:objectDefaults', null); + + // a:extraClrSchemeLst + $objWriter->writeElement('a:extraClrSchemeLst', null); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write fonts to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @param string $latinFont + * @param array of string $fontSet + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeFonts($objWriter, $latinFont, $fontSet) + { + // a:latin + $objWriter->startElement('a:latin'); + $objWriter->writeAttribute('typeface', $latinFont); + $objWriter->endElement(); + + // a:ea + $objWriter->startElement('a:ea'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + // a:cs + $objWriter->startElement('a:cs'); + $objWriter->writeAttribute('typeface', ''); + $objWriter->endElement(); + + foreach($fontSet as $fontScript => $typeface) { + $objWriter->startElement('a:font'); + $objWriter->writeAttribute('script', $fontScript); + $objWriter->writeAttribute('typeface', $typeface); + $objWriter->endElement(); + } + + } + + /** + * Write colour scheme to XML format + * + * @param PHPExcel_Shared_XMLWriter $objWriter + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + private function _writeColourScheme($objWriter) + { + foreach(self::$_colourScheme as $colourName => $colourValue) { + $objWriter->startElement('a:'.$colourName); + + $objWriter->startElement('a:srgbClr'); + $objWriter->writeAttribute('val', $colourValue); + $objWriter->endElement(); + + $objWriter->endElement(); + } + + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php new file mode 100755 index 0000000..d1fe666 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Workbook.php @@ -0,0 +1,456 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Workbook + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write workbook to XML format + * + * @param PHPExcel $pPHPExcel + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE) + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // workbook + $objWriter->startElement('workbook'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // fileVersion + $this->_writeFileVersion($objWriter); + + // workbookPr + $this->_writeWorkbookPr($objWriter); + + // workbookProtection + $this->_writeWorkbookProtection($objWriter, $pPHPExcel); + + // bookViews + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + $this->_writeBookViews($objWriter, $pPHPExcel); + } + + // sheets + $this->_writeSheets($objWriter, $pPHPExcel); + + // definedNames + $this->_writeDefinedNames($objWriter, $pPHPExcel); + + // calcPr + $this->_writeCalcPr($objWriter,$recalcRequired); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + /** + * Write file version + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('fileVersion'); + $objWriter->writeAttribute('appName', 'xl'); + $objWriter->writeAttribute('lastEdited', '4'); + $objWriter->writeAttribute('lowestEdited', '4'); + $objWriter->writeAttribute('rupBuild', '4505'); + $objWriter->endElement(); + } + + /** + * Write WorkbookPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null) + { + $objWriter->startElement('workbookPr'); + + if (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) { + $objWriter->writeAttribute('date1904', '1'); + } + + $objWriter->writeAttribute('codeName', 'ThisWorkbook'); + + $objWriter->endElement(); + } + + /** + * Write BookViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // bookViews + $objWriter->startElement('bookViews'); + + // workbookView + $objWriter->startElement('workbookView'); + + $objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex()); + $objWriter->writeAttribute('autoFilterDateGrouping', '1'); + $objWriter->writeAttribute('firstSheet', '0'); + $objWriter->writeAttribute('minimized', '0'); + $objWriter->writeAttribute('showHorizontalScroll', '1'); + $objWriter->writeAttribute('showSheetTabs', '1'); + $objWriter->writeAttribute('showVerticalScroll', '1'); + $objWriter->writeAttribute('tabRatio', '600'); + $objWriter->writeAttribute('visibility', 'visible'); + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write WorkbookProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + if ($pPHPExcel->getSecurity()->isSecurityEnabled()) { + $objWriter->startElement('workbookProtection'); + $objWriter->writeAttribute('lockRevision', ($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false')); + $objWriter->writeAttribute('lockStructure', ($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false')); + $objWriter->writeAttribute('lockWindows', ($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false')); + + if ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') { + $objWriter->writeAttribute('revisionsPassword', $pPHPExcel->getSecurity()->getRevisionsPassword()); + } + + if ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') { + $objWriter->writeAttribute('workbookPassword', $pPHPExcel->getSecurity()->getWorkbookPassword()); + } + + $objWriter->endElement(); + } + } + + /** + * Write calcPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param boolean $recalcRequired Indicate whether formulas should be recalculated before writing + * @throws PHPExcel_Writer_Exception + */ + private function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE) + { + $objWriter->startElement('calcPr'); + + // Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc + // If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit + // because the file has changed + $objWriter->writeAttribute('calcId', '999999'); + $objWriter->writeAttribute('calcMode', 'auto'); + // fullCalcOnLoad isn't needed if we've recalculating for the save + $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); + $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); + + $objWriter->endElement(); + } + + /** + * Write sheets + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write sheets + $objWriter->startElement('sheets'); + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // sheet + $this->_writeSheet( + $objWriter, + $pPHPExcel->getSheet($i)->getTitle(), + ($i + 1), + ($i + 1 + 3), + $pPHPExcel->getSheet($i)->getSheetState() + ); + } + + $objWriter->endElement(); + } + + /** + * Write sheet + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param string $pSheetname Sheet name + * @param int $pSheetId Sheet id + * @param int $pRelId Relationship ID + * @param string $sheetState Sheet state (visible, hidden, veryHidden) + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible') + { + if ($pSheetname != '') { + // Write sheet + $objWriter->startElement('sheet'); + $objWriter->writeAttribute('name', $pSheetname); + $objWriter->writeAttribute('sheetId', $pSheetId); + if ($sheetState != 'visible' && $sheetState != '') { + $objWriter->writeAttribute('state', $sheetState); + } + $objWriter->writeAttribute('r:id', 'rId' . $pRelId); + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Defined Names + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null) + { + // Write defined names + $objWriter->startElement('definedNames'); + + // Named ranges + if (count($pPHPExcel->getNamedRanges()) > 0) { + // Named ranges + $this->_writeNamedRanges($objWriter, $pPHPExcel); + } + + // Other defined names + $sheetCount = $pPHPExcel->getSheetCount(); + for ($i = 0; $i < $sheetCount; ++$i) { + // definedName for autoFilter + $this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Titles + $this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i); + + // definedName for Print_Area + $this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i); + } + + $objWriter->endElement(); + } + + /** + * Write named ranges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel $pPHPExcel + * @throws PHPExcel_Writer_Exception + */ + private function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel) + { + // Loop named ranges + $namedRanges = $pPHPExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + $this->_writeDefinedNameForNamedRange($objWriter, $namedRange); + } + } + + /** + * Write Defined Name for named range + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_NamedRange $pNamedRange + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange) + { + // definedName for named range + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', $pNamedRange->getName()); + if ($pNamedRange->getLocalOnly()) { + $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope())); + } + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($pNamedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); + + $objWriter->writeRawData($range); + + $objWriter->endElement(); + } + + /** + * Write Defined Name for autoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for autoFilter + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm._FilterDatabase'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + $objWriter->writeAttribute('hidden', '1'); + + // Create absolute coordinate and write as raw text + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref so we can make the cell ref absolute + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + + $range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]); + $range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]); + $range = implode(':', $range); + + $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintTitles + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Titles'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Columns to repeat + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + // Rows to repeat + if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) { + $settingString .= ','; + } + + $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop(); + + $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1]; + } + + $objWriter->writeRawData($settingString); + + $objWriter->endElement(); + } + } + + /** + * Write Defined Name for PrintTitles + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet + * @param int $pSheetId + * @throws PHPExcel_Writer_Exception + */ + private function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0) + { + // definedName for PrintArea + if ($pSheet->getPageSetup()->isPrintAreaSet()) { + $objWriter->startElement('definedName'); + $objWriter->writeAttribute('name', '_xlnm.Print_Area'); + $objWriter->writeAttribute('localSheetId', $pSheetId); + + // Setting string + $settingString = ''; + + // Print area + $printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea()); + + $chunks = array(); + foreach ($printArea as $printAreaRect) { + $printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]); + $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect); + } + + $objWriter->writeRawData(implode(',', $chunks)); + + $objWriter->endElement(); + } + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php new file mode 100755 index 0000000..7d93f5a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/Worksheet.php @@ -0,0 +1,1220 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Write worksheet to XML format + * + * @param PHPExcel_Worksheet $pSheet + * @param string[] $pStringTable + * @param boolean $includeCharts Flag indicating if we should write charts + * @return string XML Output + * @throws PHPExcel_Writer_Exception + */ + public function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE) + { + if (!is_null($pSheet)) { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0','UTF-8','yes'); + + // Worksheet + $objWriter->startElement('worksheet'); + $objWriter->writeAttribute('xml:space', 'preserve'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + + // sheetPr + $this->_writeSheetPr($objWriter, $pSheet); + + // Dimension + $this->_writeDimension($objWriter, $pSheet); + + // sheetViews + $this->_writeSheetViews($objWriter, $pSheet); + + // sheetFormatPr + $this->_writeSheetFormatPr($objWriter, $pSheet); + + // cols + $this->_writeCols($objWriter, $pSheet); + + // sheetData + $this->_writeSheetData($objWriter, $pSheet, $pStringTable); + + // sheetProtection + $this->_writeSheetProtection($objWriter, $pSheet); + + // protectedRanges + $this->_writeProtectedRanges($objWriter, $pSheet); + + // autoFilter + $this->_writeAutoFilter($objWriter, $pSheet); + + // mergeCells + $this->_writeMergeCells($objWriter, $pSheet); + + // conditionalFormatting + $this->_writeConditionalFormatting($objWriter, $pSheet); + + // dataValidations + $this->_writeDataValidations($objWriter, $pSheet); + + // hyperlinks + $this->_writeHyperlinks($objWriter, $pSheet); + + // Print options + $this->_writePrintOptions($objWriter, $pSheet); + + // Page margins + $this->_writePageMargins($objWriter, $pSheet); + + // Page setup + $this->_writePageSetup($objWriter, $pSheet); + + // Header / footer + $this->_writeHeaderFooter($objWriter, $pSheet); + + // Breaks + $this->_writeBreaks($objWriter, $pSheet); + + // Drawings and/or Charts + $this->_writeDrawings($objWriter, $pSheet, $includeCharts); + + // LegacyDrawing + $this->_writeLegacyDrawing($objWriter, $pSheet); + + // LegacyDrawingHF + $this->_writeLegacyDrawingHF($objWriter, $pSheet); + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } else { + throw new PHPExcel_Writer_Exception("Invalid PHPExcel_Worksheet object passed."); + } + } + + /** + * Write SheetPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetPr + $objWriter->startElement('sheetPr'); + //$objWriter->writeAttribute('codeName', $pSheet->getTitle()); + if($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet + if($pSheet->hasCodeName()==false){ + $pSheet->setCodeName($pSheet->getTitle()); + } + $objWriter->writeAttribute('codeName', $pSheet->getCodeName()); + } + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + $objWriter->writeAttribute('filterMode', 1); + $pSheet->getAutoFilter()->showHideRows(); + } + + // tabColor + if ($pSheet->isTabColorSet()) { + $objWriter->startElement('tabColor'); + $objWriter->writeAttribute('rgb', $pSheet->getTabColor()->getARGB()); + $objWriter->endElement(); + } + + // outlinePr + $objWriter->startElement('outlinePr'); + $objWriter->writeAttribute('summaryBelow', ($pSheet->getShowSummaryBelow() ? '1' : '0')); + $objWriter->writeAttribute('summaryRight', ($pSheet->getShowSummaryRight() ? '1' : '0')); + $objWriter->endElement(); + + // pageSetUpPr + if ($pSheet->getPageSetup()->getFitToPage()) { + $objWriter->startElement('pageSetUpPr'); + $objWriter->writeAttribute('fitToPage', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + /** + * Write Dimension + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // dimension + $objWriter->startElement('dimension'); + $objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension()); + $objWriter->endElement(); + } + + /** + * Write SheetViews + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL) + { + // sheetViews + $objWriter->startElement('sheetViews'); + + // Sheet selected? + $sheetSelected = false; + if ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex()) + $sheetSelected = true; + + + // sheetView + $objWriter->startElement('sheetView'); + $objWriter->writeAttribute('tabSelected', $sheetSelected ? '1' : '0'); + $objWriter->writeAttribute('workbookViewId', '0'); + + // Zoom scales + if ($pSheet->getSheetView()->getZoomScale() != 100) { + $objWriter->writeAttribute('zoomScale', $pSheet->getSheetView()->getZoomScale()); + } + if ($pSheet->getSheetView()->getZoomScaleNormal() != 100) { + $objWriter->writeAttribute('zoomScaleNormal', $pSheet->getSheetView()->getZoomScaleNormal()); + } + + // View Layout Type + if ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) { + $objWriter->writeAttribute('view', $pSheet->getSheetView()->getView()); + } + + // Gridlines + if ($pSheet->getShowGridlines()) { + $objWriter->writeAttribute('showGridLines', 'true'); + } else { + $objWriter->writeAttribute('showGridLines', 'false'); + } + + // Row and column headers + if ($pSheet->getShowRowColHeaders()) { + $objWriter->writeAttribute('showRowColHeaders', '1'); + } else { + $objWriter->writeAttribute('showRowColHeaders', '0'); + } + + // Right-to-left + if ($pSheet->getRightToLeft()) { + $objWriter->writeAttribute('rightToLeft', 'true'); + } + + $activeCell = $pSheet->getActiveCell(); + + // Pane + $pane = ''; + $topLeftCell = $pSheet->getFreezePane(); + if (($topLeftCell != '') && ($topLeftCell != 'A1')) { + $activeCell = $topLeftCell; + // Calculate freeze coordinates + $xSplit = $ySplit = 0; + + list($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell); + $xSplit = PHPExcel_Cell::columnIndexFromString($xSplit); + + // pane + $pane = 'topRight'; + $objWriter->startElement('pane'); + if ($xSplit > 1) + $objWriter->writeAttribute('xSplit', $xSplit - 1); + if ($ySplit > 1) { + $objWriter->writeAttribute('ySplit', $ySplit - 1); + $pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft'; + } + $objWriter->writeAttribute('topLeftCell', $topLeftCell); + $objWriter->writeAttribute('activePane', $pane); + $objWriter->writeAttribute('state', 'frozen'); + $objWriter->endElement(); + + if (($xSplit > 1) && ($ySplit > 1)) { + // Write additional selections if more than two panes (ie both an X and a Y split) + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'topRight'); $objWriter->endElement(); + $objWriter->startElement('selection'); $objWriter->writeAttribute('pane', 'bottomLeft'); $objWriter->endElement(); + } + } + + // Selection +// if ($pane != '') { + // Only need to write selection element if we have a split pane + // We cheat a little by over-riding the active cell selection, setting it to the split cell + $objWriter->startElement('selection'); + if ($pane != '') { + $objWriter->writeAttribute('pane', $pane); + } + $objWriter->writeAttribute('activeCell', $activeCell); + $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->endElement(); +// } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + + /** + * Write SheetFormatPr + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetFormatPr + $objWriter->startElement('sheetFormatPr'); + + // Default row height + if ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', 'true'); + $objWriter->writeAttribute('defaultRowHeight', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight())); + } else { + $objWriter->writeAttribute('defaultRowHeight', '14.4'); + } + + // Set Zero Height row + if ((string)$pSheet->getDefaultRowDimension()->getzeroHeight() == '1' || + strtolower((string)$pSheet->getDefaultRowDimension()->getzeroHeight()) == 'true' ) { + $objWriter->writeAttribute('zeroHeight', '1'); + } + + // Default column width + if ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) { + $objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth())); + } + + // Outline level - row + $outlineLevelRow = 0; + foreach ($pSheet->getRowDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelRow) { + $outlineLevelRow = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelRow', (int)$outlineLevelRow); + + // Outline level - column + $outlineLevelCol = 0; + foreach ($pSheet->getColumnDimensions() as $dimension) { + if ($dimension->getOutlineLevel() > $outlineLevelCol) { + $outlineLevelCol = $dimension->getOutlineLevel(); + } + } + $objWriter->writeAttribute('outlineLevelCol', (int)$outlineLevelCol); + + $objWriter->endElement(); + } + + /** + * Write Cols + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // cols + if (count($pSheet->getColumnDimensions()) > 0) { + $objWriter->startElement('cols'); + + $pSheet->calculateColumnWidths(); + + // Loop through column dimensions + foreach ($pSheet->getColumnDimensions() as $colDimension) { + // col + $objWriter->startElement('col'); + $objWriter->writeAttribute('min', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + $objWriter->writeAttribute('max', PHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex())); + + if ($colDimension->getWidth() < 0) { + // No width set, apply default of 10 + $objWriter->writeAttribute('width', '9.10'); + } else { + // Width set + $objWriter->writeAttribute('width', PHPExcel_Shared_String::FormatNumber($colDimension->getWidth())); + } + + // Column visibility + if ($colDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Auto size? + if ($colDimension->getAutoSize()) { + $objWriter->writeAttribute('bestFit', 'true'); + } + + // Custom width? + if ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) { + $objWriter->writeAttribute('customWidth', 'true'); + } + + // Collapsed + if ($colDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($colDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $colDimension->getOutlineLevel()); + } + + // Style + $objWriter->writeAttribute('style', $colDimension->getXfIndex()); + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetProtection + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // sheetProtection + $objWriter->startElement('sheetProtection'); + + if ($pSheet->getProtection()->getPassword() != '') { + $objWriter->writeAttribute('password', $pSheet->getProtection()->getPassword()); + } + + $objWriter->writeAttribute('sheet', ($pSheet->getProtection()->getSheet() ? 'true' : 'false')); + $objWriter->writeAttribute('objects', ($pSheet->getProtection()->getObjects() ? 'true' : 'false')); + $objWriter->writeAttribute('scenarios', ($pSheet->getProtection()->getScenarios() ? 'true' : 'false')); + $objWriter->writeAttribute('formatCells', ($pSheet->getProtection()->getFormatCells() ? 'true' : 'false')); + $objWriter->writeAttribute('formatColumns', ($pSheet->getProtection()->getFormatColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('formatRows', ($pSheet->getProtection()->getFormatRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertColumns', ($pSheet->getProtection()->getInsertColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('insertRows', ($pSheet->getProtection()->getInsertRows() ? 'true' : 'false')); + $objWriter->writeAttribute('insertHyperlinks', ($pSheet->getProtection()->getInsertHyperlinks() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteColumns', ($pSheet->getProtection()->getDeleteColumns() ? 'true' : 'false')); + $objWriter->writeAttribute('deleteRows', ($pSheet->getProtection()->getDeleteRows() ? 'true' : 'false')); + $objWriter->writeAttribute('selectLockedCells', ($pSheet->getProtection()->getSelectLockedCells() ? 'true' : 'false')); + $objWriter->writeAttribute('sort', ($pSheet->getProtection()->getSort() ? 'true' : 'false')); + $objWriter->writeAttribute('autoFilter', ($pSheet->getProtection()->getAutoFilter() ? 'true' : 'false')); + $objWriter->writeAttribute('pivotTables', ($pSheet->getProtection()->getPivotTables() ? 'true' : 'false')); + $objWriter->writeAttribute('selectUnlockedCells', ($pSheet->getProtection()->getSelectUnlockedCells() ? 'true' : 'false')); + $objWriter->endElement(); + } + + /** + * Write ConditionalFormatting + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Conditional id + $id = 1; + + // Loop through styles in the current worksheet + foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + // WHY was this again? + // if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') { + // continue; + // } + if ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) { + // conditionalFormatting + $objWriter->startElement('conditionalFormatting'); + $objWriter->writeAttribute('sqref', $cellCoordinate); + + // cfRule + $objWriter->startElement('cfRule'); + $objWriter->writeAttribute('type', $conditional->getConditionType()); + $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() )); + $objWriter->writeAttribute('priority', $id++); + + if (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || + $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT) + && $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) { + $objWriter->writeAttribute('operator', $conditional->getOperatorType()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeAttribute('text', $conditional->getText()); + } + + if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'NOT(ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . ')))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')="' . $conditional->getText() . '"'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + && $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS + && !is_null($conditional->getText())) { + $objWriter->writeElement('formula', 'ISERROR(SEARCH("' . $conditional->getText() . '",' . $cellCoordinate . '))'); + } else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) { + foreach ($conditional->getConditions() as $formula) { + // Formula + $objWriter->writeElement('formula', $formula); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + } + + /** + * Write DataValidations + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Datavalidation collection + $dataValidationCollection = $pSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + $objWriter->startElement('dataValidations'); + $objWriter->writeAttribute('count', count($dataValidationCollection)); + + foreach ($dataValidationCollection as $coordinate => $dv) { + $objWriter->startElement('dataValidation'); + + if ($dv->getType() != '') { + $objWriter->writeAttribute('type', $dv->getType()); + } + + if ($dv->getErrorStyle() != '') { + $objWriter->writeAttribute('errorStyle', $dv->getErrorStyle()); + } + + if ($dv->getOperator() != '') { + $objWriter->writeAttribute('operator', $dv->getOperator()); + } + + $objWriter->writeAttribute('allowBlank', ($dv->getAllowBlank() ? '1' : '0')); + $objWriter->writeAttribute('showDropDown', (!$dv->getShowDropDown() ? '1' : '0')); + $objWriter->writeAttribute('showInputMessage', ($dv->getShowInputMessage() ? '1' : '0')); + $objWriter->writeAttribute('showErrorMessage', ($dv->getShowErrorMessage() ? '1' : '0')); + + if ($dv->getErrorTitle() !== '') { + $objWriter->writeAttribute('errorTitle', $dv->getErrorTitle()); + } + if ($dv->getError() !== '') { + $objWriter->writeAttribute('error', $dv->getError()); + } + if ($dv->getPromptTitle() !== '') { + $objWriter->writeAttribute('promptTitle', $dv->getPromptTitle()); + } + if ($dv->getPrompt() !== '') { + $objWriter->writeAttribute('prompt', $dv->getPrompt()); + } + + $objWriter->writeAttribute('sqref', $coordinate); + + if ($dv->getFormula1() !== '') { + $objWriter->writeElement('formula1', $dv->getFormula1()); + } + if ($dv->getFormula2() !== '') { + $objWriter->writeElement('formula2', $dv->getFormula2()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write Hyperlinks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Hyperlink collection + $hyperlinkCollection = $pSheet->getHyperlinkCollection(); + + // Relation ID + $relationId = 1; + + // Write hyperlinks? + if (!empty($hyperlinkCollection)) { + $objWriter->startElement('hyperlinks'); + + foreach ($hyperlinkCollection as $coordinate => $hyperlink) { + $objWriter->startElement('hyperlink'); + + $objWriter->writeAttribute('ref', $coordinate); + if (!$hyperlink->isInternal()) { + $objWriter->writeAttribute('r:id', 'rId_hyperlink_' . $relationId); + ++$relationId; + } else { + $objWriter->writeAttribute('location', str_replace('sheet://', '', $hyperlink->getUrl())); + } + + if ($hyperlink->getTooltip() != '') { + $objWriter->writeAttribute('tooltip', $hyperlink->getTooltip()); + } + + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write ProtectedRanges + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getProtectedCells()) > 0) { + // protectedRanges + $objWriter->startElement('protectedRanges'); + + // Loop protectedRanges + foreach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) { + // protectedRange + $objWriter->startElement('protectedRange'); + $objWriter->writeAttribute('name', 'p' . md5($protectedCell)); + $objWriter->writeAttribute('sqref', $protectedCell); + if (!empty($passwordHash)) { + $objWriter->writeAttribute('password', $passwordHash); + } + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write MergeCells + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + if (count($pSheet->getMergeCells()) > 0) { + // mergeCells + $objWriter->startElement('mergeCells'); + + // Loop mergeCells + foreach ($pSheet->getMergeCells() as $mergeCell) { + // mergeCell + $objWriter->startElement('mergeCell'); + $objWriter->writeAttribute('ref', $mergeCell); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write PrintOptions + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // printOptions + $objWriter->startElement('printOptions'); + + $objWriter->writeAttribute('gridLines', ($pSheet->getPrintGridlines() ? 'true': 'false')); + $objWriter->writeAttribute('gridLinesSet', 'true'); + + if ($pSheet->getPageSetup()->getHorizontalCentered()) { + $objWriter->writeAttribute('horizontalCentered', 'true'); + } + + if ($pSheet->getPageSetup()->getVerticalCentered()) { + $objWriter->writeAttribute('verticalCentered', 'true'); + } + + $objWriter->endElement(); + } + + /** + * Write PageMargins + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageMargins + $objWriter->startElement('pageMargins'); + $objWriter->writeAttribute('left', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft())); + $objWriter->writeAttribute('right', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight())); + $objWriter->writeAttribute('top', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop())); + $objWriter->writeAttribute('bottom', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom())); + $objWriter->writeAttribute('header', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader())); + $objWriter->writeAttribute('footer', PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter())); + $objWriter->endElement(); + } + + /** + * Write AutoFilter + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + $autoFilterRange = $pSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // autoFilter + $objWriter->startElement('autoFilter'); + + // Strip any worksheet reference from the filter coordinates + $range = PHPExcel_Cell::splitRange($autoFilterRange); + $range = $range[0]; + // Strip any worksheet ref + if (strpos($range[0],'!') !== false) { + list($ws,$range[0]) = explode('!',$range[0]); + } + $range = implode(':', $range); + + $objWriter->writeAttribute('ref', str_replace('$','',$range)); + + $columns = $pSheet->getAutoFilter()->getColumns(); + if (count($columns > 0)) { + foreach($columns as $columnID => $column) { + $rules = $column->getRules(); + if (count($rules > 0)) { + $objWriter->startElement('filterColumn'); + $objWriter->writeAttribute('colId', $pSheet->getAutoFilter()->getColumnOffset($columnID)); + + $objWriter->startElement( $column->getFilterType()); + if ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) { + $objWriter->writeAttribute('and', 1); + } + + foreach ($rules as $rule) { + if (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) && + ($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) && + ($rule->getValue() === '')) { + // Filter rule for Blanks + $objWriter->writeAttribute('blank', 1); + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) { + // Dynamic Filter Rule + $objWriter->writeAttribute('type', $rule->getGrouping()); + $val = $column->getAttribute('val'); + if ($val !== NULL) { + $objWriter->writeAttribute('val', $val); + } + $maxVal = $column->getAttribute('maxVal'); + if ($maxVal !== NULL) { + $objWriter->writeAttribute('maxVal', $maxVal); + } + } elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) { + // Top 10 Filter Rule + $objWriter->writeAttribute('val', $rule->getValue()); + $objWriter->writeAttribute('percent', (($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0')); + $objWriter->writeAttribute('top', (($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0')); + } else { + // Filter, DateGroupItem or CustomFilter + $objWriter->startElement($rule->getRuleType()); + + if ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) { + $objWriter->writeAttribute('operator', $rule->getOperator()); + } + if ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) { + // Date Group filters + foreach($rule->getValue() as $key => $value) { + if ($value > '') $objWriter->writeAttribute($key, $value); + } + $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping()); + } else { + $objWriter->writeAttribute('val', $rule->getValue()); + } + + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + + $objWriter->endElement(); + } + } + } + + $objWriter->endElement(); + } + } + + /** + * Write PageSetup + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // pageSetup + $objWriter->startElement('pageSetup'); + $objWriter->writeAttribute('paperSize', $pSheet->getPageSetup()->getPaperSize()); + $objWriter->writeAttribute('orientation', $pSheet->getPageSetup()->getOrientation()); + + if (!is_null($pSheet->getPageSetup()->getScale())) { + $objWriter->writeAttribute('scale', $pSheet->getPageSetup()->getScale()); + } + if (!is_null($pSheet->getPageSetup()->getFitToHeight())) { + $objWriter->writeAttribute('fitToHeight', $pSheet->getPageSetup()->getFitToHeight()); + } else { + $objWriter->writeAttribute('fitToHeight', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFitToWidth())) { + $objWriter->writeAttribute('fitToWidth', $pSheet->getPageSetup()->getFitToWidth()); + } else { + $objWriter->writeAttribute('fitToWidth', '0'); + } + if (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) { + $objWriter->writeAttribute('firstPageNumber', $pSheet->getPageSetup()->getFirstPageNumber()); + $objWriter->writeAttribute('useFirstPageNumber', '1'); + } + + $objWriter->endElement(); + } + + /** + * Write Header / Footer + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // headerFooter + $objWriter->startElement('headerFooter'); + $objWriter->writeAttribute('differentOddEven', ($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false')); + $objWriter->writeAttribute('differentFirst', ($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false')); + $objWriter->writeAttribute('scaleWithDoc', ($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false')); + $objWriter->writeAttribute('alignWithMargins', ($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false')); + + $objWriter->writeElement('oddHeader', $pSheet->getHeaderFooter()->getOddHeader()); + $objWriter->writeElement('oddFooter', $pSheet->getHeaderFooter()->getOddFooter()); + $objWriter->writeElement('evenHeader', $pSheet->getHeaderFooter()->getEvenHeader()); + $objWriter->writeElement('evenFooter', $pSheet->getHeaderFooter()->getEvenFooter()); + $objWriter->writeElement('firstHeader', $pSheet->getHeaderFooter()->getFirstHeader()); + $objWriter->writeElement('firstFooter', $pSheet->getHeaderFooter()->getFirstFooter()); + $objWriter->endElement(); + } + + /** + * Write Breaks + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // Get row and column breaks + $aRowBreaks = array(); + $aColumnBreaks = array(); + foreach ($pSheet->getBreaks() as $cell => $breakType) { + if ($breakType == PHPExcel_Worksheet::BREAK_ROW) { + $aRowBreaks[] = $cell; + } else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) { + $aColumnBreaks[] = $cell; + } + } + + // rowBreaks + if (!empty($aRowBreaks)) { + $objWriter->startElement('rowBreaks'); + $objWriter->writeAttribute('count', count($aRowBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aRowBreaks)); + + foreach ($aRowBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', $coords[1]); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + + // Second, write column breaks + if (!empty($aColumnBreaks)) { + $objWriter->startElement('colBreaks'); + $objWriter->writeAttribute('count', count($aColumnBreaks)); + $objWriter->writeAttribute('manualBreakCount', count($aColumnBreaks)); + + foreach ($aColumnBreaks as $cell) { + $coords = PHPExcel_Cell::coordinateFromString($cell); + + $objWriter->startElement('brk'); + $objWriter->writeAttribute('id', PHPExcel_Cell::columnIndexFromString($coords[0]) - 1); + $objWriter->writeAttribute('man', '1'); + $objWriter->endElement(); + } + + $objWriter->endElement(); + } + } + + /** + * Write SheetData + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param string[] $pStringTable String table + * @throws PHPExcel_Writer_Exception + */ + private function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null) + { + if (is_array($pStringTable)) { + // Flipped stringtable, for faster index searching + $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable); + + // sheetData + $objWriter->startElement('sheetData'); + + // Get column count + $colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()); + + // Highest row number + $highestRow = $pSheet->getHighestRow(); + + // Loop through cells + $cellsByRow = array(); + foreach ($pSheet->getCellCollection() as $cellID) { + $cellAddress = PHPExcel_Cell::coordinateFromString($cellID); + $cellsByRow[$cellAddress[1]][] = $cellID; + } + + $currentRow = 0; + while($currentRow++ < $highestRow) { + // Get row dimension + $rowDimension = $pSheet->getRowDimension($currentRow); + + // Write current row? + $writeCurrentRow = isset($cellsByRow[$currentRow]) || + $rowDimension->getRowHeight() >= 0 || + $rowDimension->getVisible() == false || + $rowDimension->getCollapsed() == true || + $rowDimension->getOutlineLevel() > 0 || + $rowDimension->getXfIndex() !== null; + + if ($writeCurrentRow) { + // Start a new row + $objWriter->startElement('row'); + $objWriter->writeAttribute('r', $currentRow); + $objWriter->writeAttribute('spans', '1:' . $colCount); + + // Row dimensions + if ($rowDimension->getRowHeight() >= 0) { + $objWriter->writeAttribute('customHeight', '1'); + $objWriter->writeAttribute('ht', PHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight())); + } + + // Row visibility + if ($rowDimension->getVisible() == false) { + $objWriter->writeAttribute('hidden', 'true'); + } + + // Collapsed + if ($rowDimension->getCollapsed() == true) { + $objWriter->writeAttribute('collapsed', 'true'); + } + + // Outline level + if ($rowDimension->getOutlineLevel() > 0) { + $objWriter->writeAttribute('outlineLevel', $rowDimension->getOutlineLevel()); + } + + // Style + if ($rowDimension->getXfIndex() !== null) { + $objWriter->writeAttribute('s', $rowDimension->getXfIndex()); + $objWriter->writeAttribute('customFormat', '1'); + } + + // Write cells + if (isset($cellsByRow[$currentRow])) { + foreach($cellsByRow[$currentRow] as $cellAddress) { + // Write cell + $this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable); + } + } + + // End row + $objWriter->endElement(); + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Cell + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param PHPExcel_Cell $pCellAddress Cell Address + * @param string[] $pStringTable String table + * @param string[] $pFlippedStringTable String table (flipped), for faster index searching + * @throws PHPExcel_Writer_Exception + */ + private function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null) + { + if (is_array($pStringTable) && is_array($pFlippedStringTable)) { + // Cell + $pCell = $pSheet->getCell($pCellAddress); + $objWriter->startElement('c'); + $objWriter->writeAttribute('r', $pCellAddress); + + // Sheet styles + if ($pCell->getXfIndex() != '') { + $objWriter->writeAttribute('s', $pCell->getXfIndex()); + } + + // If cell value is supplied, write cell value + $cellValue = $pCell->getValue(); + if (is_object($cellValue) || $cellValue !== '') { + // Map type + $mappedType = $pCell->getDataType(); + + // Write data type depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + case 's': // String + case 'b': // Boolean + $objWriter->writeAttribute('t', $mappedType); + break; + case 'f': // Formula + $calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ? + $pCell->getCalculatedValue() : + $cellValue; + if (is_string($calculatedValue)) { + $objWriter->writeAttribute('t', 'str'); + } + break; + case 'e': // Error + $objWriter->writeAttribute('t', $mappedType); + } + + // Write data depending on its type + switch (strtolower($mappedType)) { + case 'inlinestr': // Inline string + if (! $cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) ); + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->startElement('is'); + $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue); + $objWriter->endElement(); + } + + break; + case 's': // String + if (! $cellValue instanceof PHPExcel_RichText) { + if (isset($pFlippedStringTable[$cellValue])) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue]); + } + } else if ($cellValue instanceof PHPExcel_RichText) { + $objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]); + } + + break; + case 'f': // Formula + $attributes = $pCell->getFormulaAttributes(); + if($attributes['t'] == 'array') { + $objWriter->startElement('f'); + $objWriter->writeAttribute('t', 'array'); + $objWriter->writeAttribute('ref', $pCellAddress); + $objWriter->writeAttribute('aca', '1'); + $objWriter->writeAttribute('ca', '1'); + $objWriter->text(substr($cellValue, 1)); + $objWriter->endElement(); + } else { + $objWriter->writeElement('f', substr($cellValue, 1)); + } + if ($this->getParentWriter()->getOffice2003Compatibility() === false) { + if ($this->getParentWriter()->getPreCalculateFormulas()) { +// $calculatedValue = $pCell->getCalculatedValue(); + if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') { + $objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue)); + } else { + $objWriter->writeElement('v', '0'); + } + } else { + $objWriter->writeElement('v', '0'); + } + } + break; + case 'n': // Numeric + // force point as decimal separator in case current locale uses comma + $objWriter->writeElement('v', str_replace(',', '.', $cellValue)); + break; + case 'b': // Boolean + $objWriter->writeElement('v', ($cellValue ? '1' : '0')); + break; + case 'e': // Error + if (substr($cellValue, 0, 1) == '=') { + $objWriter->writeElement('f', substr($cellValue, 1)); + $objWriter->writeElement('v', substr($cellValue, 1)); + } else { + $objWriter->writeElement('v', $cellValue); + } + + break; + } + } + + $objWriter->endElement(); + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Write Drawings + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @param boolean $includeCharts Flag indicating if we should include drawing details for charts + * @throws PHPExcel_Writer_Exception + */ + private function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE) + { + $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; + // If sheet contains drawings, add the relationships + if (($pSheet->getDrawingCollection()->count() > 0) || + ($chartCount > 0)) { + $objWriter->startElement('drawing'); + $objWriter->writeAttribute('r:id', 'rId1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawing + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains comments, add the relationships + if (count($pSheet->getComments()) > 0) { + $objWriter->startElement('legacyDrawing'); + $objWriter->writeAttribute('r:id', 'rId_comments_vml1'); + $objWriter->endElement(); + } + } + + /** + * Write LegacyDrawingHF + * + * @param PHPExcel_Shared_XMLWriter $objWriter XML Writer + * @param PHPExcel_Worksheet $pSheet Worksheet + * @throws PHPExcel_Writer_Exception + */ + private function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null) + { + // If sheet contains images, add the relationships + if (count($pSheet->getHeaderFooter()->getImages()) > 0) { + $objWriter->startElement('legacyDrawingHF'); + $objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1'); + $objWriter->endElement(); + } + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php b/extend/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php new file mode 100755 index 0000000..982117b --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel2007/WriterPart.php @@ -0,0 +1,81 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel2007_WriterPart + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel2007 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_Excel2007_WriterPart +{ + /** + * Parent IWriter object + * + * @var PHPExcel_Writer_IWriter + */ + private $_parentWriter; + + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) { + $this->_parentWriter = $pWriter; + } + + /** + * Get parent IWriter object + * + * @return PHPExcel_Writer_IWriter + * @throws PHPExcel_Writer_Exception + */ + public function getParentWriter() { + if (!is_null($this->_parentWriter)) { + return $this->_parentWriter; + } else { + throw new PHPExcel_Writer_Exception("No parent PHPExcel_Writer_IWriter assigned."); + } + } + + /** + * Set parent IWriter object + * + * @param PHPExcel_Writer_IWriter $pWriter + * @throws PHPExcel_Writer_Exception + */ + public function __construct(PHPExcel_Writer_IWriter $pWriter = null) { + if (!is_null($pWriter)) { + $this->_parentWriter = $pWriter; + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5.php b/extend/phpexcel/PHPExcel/Writer/Excel5.php new file mode 100755 index 0000000..3f816fa --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5.php @@ -0,0 +1,935 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel5 + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter +{ + /** + * PHPExcel object + * + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total = 0; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique = 0; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table = array(); + + /** + * Color cache. Mapping between RGB value and color index. + * + * @var array + */ + private $_colors; + + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Identifier clusters for drawings. Used in MSODRAWINGGROUP record. + * + * @var array + */ + private $_IDCLs; + + /** + * Basic OLE object summary information + * + * @var array + */ + private $_summaryInformation; + + /** + * Extended OLE object document summary information + * + * @var array + */ + private $_documentSummaryInformation; + + /** + * Create a new PHPExcel_Writer_Excel5 + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + + $this->_parser = new PHPExcel_Writer_Excel5_Parser(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType(); + PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL); + + // initialize colors array + $this->_colors = array(); + + // Initialise workbook writer + $this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel, + $this->_str_total, $this->_str_unique, $this->_str_table, + $this->_colors, $this->_parser); + + // Initialise worksheet writers + $countSheets = $this->_phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique, + $this->_str_table, $this->_colors, + $this->_parser, + $this->_preCalculateFormulas, + $this->_phpExcel->getSheet($i)); + } + + // build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook. + $this->_buildWorksheetEschers(); + $this->_buildWorkbookEscher(); + + // add 15 identical cell style Xfs + // for now, we use the first cellXf instead of cellStyleXf + $cellXfCollection = $this->_phpExcel->getCellXfCollection(); + for ($i = 0; $i < 15; ++$i) { + $this->_writerWorkbook->addXfWriter($cellXfCollection[0], true); + } + + // add all the cell Xfs + foreach ($this->_phpExcel->getCellXfCollection() as $style) { + $this->_writerWorkbook->addXfWriter($style, false); + } + + // add fonts from rich text eleemnts + for ($i = 0; $i < $countSheets; ++$i) { + foreach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) { + $cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID); + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + if ($element instanceof PHPExcel_RichText_Run) { + $font = $element->getFont(); + $this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font); + } + } + } + } + } + + // initialize OLE file + $workbookStreamName = 'Workbook'; + $OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName)); + + // Write the worksheet streams before the global workbook stream, + // because the byte sizes of these are needed in the global workbook stream + $worksheetSizes = array(); + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writerWorksheets[$i]->close(); + $worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize; + } + + // add binary data for global workbook stream + $OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes)); + + // add binary data for sheet streams + for ($i = 0; $i < $countSheets; ++$i) { + $OLE->append($this->_writerWorksheets[$i]->getData()); + } + + $this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation(); + // initialize OLE Document Summary Information + if(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){ + $OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation')); + $OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation); + } + + $this->_summaryInformation = $this->_writeSummaryInformation(); + // initialize OLE Summary Information + if(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){ + $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation')); + $OLE_SummaryInformation->append($this->_summaryInformation); + } + + // define OLE Parts + $arrRootData = array($OLE); + // initialize OLE Properties file + if(isset($OLE_SummaryInformation)){ + $arrRootData[] = $OLE_SummaryInformation; + } + // initialize OLE Extended Properties file + if(isset($OLE_DocumentSummaryInformation)){ + $arrRootData[] = $OLE_DocumentSummaryInformation; + } + + $root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData); + // save the OLE file + $res = $root->save($pFilename); + + PHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Set temporary storage directory + * + * @deprecated + * @param string $pValue Temporary storage directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_Excel5 + */ + public function setTempDir($pValue = '') { + return $this; + } + + /** + * Build the Worksheet Escher objects + * + */ + private function _buildWorksheetEschers() + { + // 1-based index to BstoreContainer + $blipIndex = 0; + $lastReducedSpId = 0; + $lastSpId = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + // sheet index + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + $escher = null; + + // check if there are any shapes for this sheet + $filterRange = $sheet->getAutoFilter()->getRange(); + if (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) { + continue; + } + + // create intermediate Escher object + $escher = new PHPExcel_Shared_Escher(); + + // dgContainer + $dgContainer = new PHPExcel_Shared_Escher_DgContainer(); + + // set the drawing index (we use sheet index + 1) + $dgId = $sheet->getParent()->getIndex($sheet) + 1; + $dgContainer->setDgId($dgId); + $escher->setDgContainer($dgContainer); + + // spgrContainer + $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer(); + $dgContainer->setSpgrContainer($spgrContainer); + + // add one shape which is the group shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + $spContainer->setSpgr(true); + $spContainer->setSpType(0); + $spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10); + $spgrContainer->addChild($spContainer); + + // add the shapes + + $countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$blipIndex; + + ++$countShapes[$sheetIndex]; + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + + // set the shape type + $spContainer->setSpType(0x004B); + // set the shape flag + $spContainer->setSpFlag(0x02); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + // set the BLIP index + $spContainer->setOPT(0x4104, $blipIndex); + + // set coordinates and offsets, client anchor + $coordinates = $drawing->getCoordinates(); + $offsetX = $drawing->getOffsetX(); + $offsetY = $drawing->getOffsetY(); + $width = $drawing->getWidth(); + $height = $drawing->getHeight(); + + $twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height); + + $spContainer->setStartCoordinates($twoAnchor['startCoordinates']); + $spContainer->setStartOffsetX($twoAnchor['startOffsetX']); + $spContainer->setStartOffsetY($twoAnchor['startOffsetY']); + $spContainer->setEndCoordinates($twoAnchor['endCoordinates']); + $spContainer->setEndOffsetX($twoAnchor['endOffsetX']); + $spContainer->setEndOffsetY($twoAnchor['endOffsetY']); + + $spgrContainer->addChild($spContainer); + } + + // AutoFilters + if(!empty($filterRange)){ + $rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange); + $iNumColStart = $rangeBounds[0][0]; + $iNumColEnd = $rangeBounds[1][0]; + + $iInc = $iNumColStart; + while($iInc <= $iNumColEnd){ + ++$countShapes[$sheetIndex]; + + // create an Drawing Object for the dropdown + $oDrawing = new PHPExcel_Worksheet_BaseDrawing(); + // get the coordinates of drawing + $cDrawing = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1]; + $oDrawing->setCoordinates($cDrawing); + $oDrawing->setWorksheet($sheet); + + // add the shape + $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer(); + // set the shape type + $spContainer->setSpType(0x00C9); + // set the shape flag + $spContainer->setSpFlag(0x01); + + // set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index) + $reducedSpId = $countShapes[$sheetIndex]; + $spId = $reducedSpId + | ($sheet->getParent()->getIndex($sheet) + 1) << 10; + $spContainer->setSpId($spId); + + // keep track of last reducedSpId + $lastReducedSpId = $reducedSpId; + + // keep track of last spId + $lastSpId = $spId; + + $spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping + $spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape + $spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest + $spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash + $spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint + + // set coordinates and offsets, client anchor + $endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1)); + $endCoordinates .= $rangeBounds[0][1] + 1; + + $spContainer->setStartCoordinates($cDrawing); + $spContainer->setStartOffsetX(0); + $spContainer->setStartOffsetY(0); + $spContainer->setEndCoordinates($endCoordinates); + $spContainer->setEndOffsetX(0); + $spContainer->setEndOffsetY(0); + + $spgrContainer->addChild($spContainer); + $iInc++; + } + } + + // identifier clusters, used for workbook Escher object + $this->_IDCLs[$dgId] = $lastReducedSpId; + + // set last shape index + $dgContainer->setLastSpId($lastSpId); + + // set the Escher object + $this->_writerWorksheets[$sheetIndex]->setEscher($escher); + } + } + + /** + * Build the Escher object corresponding to the MSODRAWINGGROUP record + */ + private function _buildWorkbookEscher() + { + $escher = null; + + // any drawings in this workbook? + $found = false; + foreach ($this->_phpExcel->getAllSheets() as $sheet) { + if (count($sheet->getDrawingCollection()) > 0) { + $found = true; + break; + } + } + + // nothing to do if there are no drawings + if (!$found) { + return; + } + + // if we reach here, then there are drawings in the workbook + $escher = new PHPExcel_Shared_Escher(); + + // dggContainer + $dggContainer = new PHPExcel_Shared_Escher_DggContainer(); + $escher->setDggContainer($dggContainer); + + // set IDCLs (identifier clusters) + $dggContainer->setIDCLs($this->_IDCLs); + + // this loop is for determining maximum shape identifier of all drawing + $spIdMax = 0; + $totalCountShapes = 0; + $countDrawings = 0; + + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + $sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet + + if (count($sheet->getDrawingCollection()) > 0) { + ++$countDrawings; + + foreach ($sheet->getDrawingCollection() as $drawing) { + ++$sheetCountShapes; + ++$totalCountShapes; + + $spId = $sheetCountShapes + | ($this->_phpExcel->getIndex($sheet) + 1) << 10; + $spIdMax = max($spId, $spIdMax); + } + } + } + + $dggContainer->setSpIdMax($spIdMax + 1); + $dggContainer->setCDgSaved($countDrawings); + $dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing + + // bstoreContainer + $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer(); + $dggContainer->setBstoreContainer($bstoreContainer); + + // the BSE's (all the images) + foreach ($this->_phpExcel->getAllsheets() as $sheet) { + foreach ($sheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + + $filename = $drawing->getPath(); + + list($imagesx, $imagesy, $imageFormat) = getimagesize($filename); + + switch ($imageFormat) { + + case 1: // GIF, not supported by BIFF8, we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(imagecreatefromgif($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + case 2: // JPEG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $blipData = file_get_contents($filename); + break; + + case 3: // PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $blipData = file_get_contents($filename); + break; + + case 6: // Windows DIB (BMP), we convert to PNG + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + ob_start(); + imagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename)); + $blipData = ob_get_contents(); + ob_end_clean(); + break; + + default: continue 2; + + } + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + + } else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) { + + switch ($drawing->getRenderingFunction()) { + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG; + $renderingFunction = 'imagejpeg'; + break; + + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG: + case PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT: + $blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG; + $renderingFunction = 'imagepng'; + break; + + } + + ob_start(); + call_user_func($renderingFunction, $drawing->getImageResource()); + $blipData = ob_get_contents(); + ob_end_clean(); + + $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip(); + $blip->setData($blipData); + + $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE(); + $BSE->setBlipType($blipType); + $BSE->setBlip($blip); + + $bstoreContainer->addBSE($BSE); + } + } + } + + // Set the Escher object + $this->_writerWorkbook->setEscher($escher); + } + + /** + * Build the OLE Part for DocumentSummary Information + * @return string + */ + private function _writeDocumentSummaryInformation(){ + + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae + $data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // GKPIDDSI_CODEPAGE: CodePage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); + $dataSection_NumProps++; + + // GKPIDDSI_CATEGORY : Category + if($this->_phpExcel->getProperties()->getCategory()){ + $dataProp = $this->_phpExcel->getProperties()->getCategory(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // GKPIDDSI_VERSION :Version of the application that wrote the property storage + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), + 'data' => array('pack' => 'V', 'data' => 0x000C0000)); + $dataSection_NumProps++; + // GKPIDDSI_SCALE : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_SHAREDOC : FALSE + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + // GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x0B), + 'data' => array('data' => false)); + $dataSection_NumProps++; + + // GKPIDDSI_DOCSPARTS + // MS-OSHARED p75 (2.3.3.2.2.1) + // Structure is VtVecUnalignedLpstrValue (2.3.3.1.9) + // cElements + $dataProp = pack('v', 0x0001); + $dataProp .= pack('v', 0x0000); + // array of UnalignedLpstr + // cch + $dataProp .= pack('v', 0x000A); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Worksheet'.chr(0); + + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x101E), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // GKPIDDSI_HEADINGPAIR + // VtVecHeadingPairValue + // cElements + $dataProp = pack('v', 0x0002); + $dataProp .= pack('v', 0x0000); + // Array of vtHeadingPair + // vtUnalignedString - headingString + // stringType + $dataProp .= pack('v', 0x001E); + // padding + $dataProp .= pack('v', 0x0000); + // UnalignedLpstr + // cch + $dataProp .= pack('v', 0x0013); + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= 'Feuilles de calcul'; + // vtUnalignedString - headingParts + // wType : 0x0003 = 32 bit signed integer + $dataProp .= pack('v', 0x0300); + // padding + $dataProp .= pack('v', 0x0000); + // value + $dataProp .= pack('v', 0x0100); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); + $dataProp .= pack('v', 0x0000); + + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x100C), + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x0B){ // Boolean + if($dataProp['data']['data'] == false){ + $dataSection_Content .= pack('V', 0x0000); + } else { + $dataSection_Content .= pack('V', 0x0001); + } + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + $dataProp['data']['length']; + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } + + /** + * Build the OLE Part for Summary Information + * @return string + */ + private function _writeSummaryInformation(){ + // offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark) + $data = pack('v', 0xFFFE); + // offset: 2; size: 2; + $data .= pack('v', 0x0000); + // offset: 4; size: 2; OS version + $data .= pack('v', 0x0106); + // offset: 6; size: 2; OS indicator + $data .= pack('v', 0x0002); + // offset: 8; size: 16 + $data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00); + // offset: 24; size: 4; section count + $data .= pack('V', 0x0001); + + // offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9 + $data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3); + // offset: 44; size: 4; offset of the start + $data .= pack('V', 0x30); + + // SECTION + $dataSection = array(); + $dataSection_NumProps = 0; + $dataSection_Summary = ''; + $dataSection_Content = ''; + + // CodePage : CP-1252 + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer + 'data' => array('data' => 1252)); + $dataSection_NumProps++; + + // Title + if($this->_phpExcel->getProperties()->getTitle()){ + $dataProp = $this->_phpExcel->getProperties()->getTitle(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Subject + if($this->_phpExcel->getProperties()->getSubject()){ + $dataProp = $this->_phpExcel->getProperties()->getSubject(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Author (Creator) + if($this->_phpExcel->getProperties()->getCreator()){ + $dataProp = $this->_phpExcel->getProperties()->getCreator(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Keywords + if($this->_phpExcel->getProperties()->getKeywords()){ + $dataProp = $this->_phpExcel->getProperties()->getKeywords(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Comments (Description) + if($this->_phpExcel->getProperties()->getDescription()){ + $dataProp = $this->_phpExcel->getProperties()->getDescription(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Last Saved By (LastModifiedBy) + if($this->_phpExcel->getProperties()->getLastModifiedBy()){ + $dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length + 'data' => array('data' => $dataProp, 'length' => strlen($dataProp))); + $dataSection_NumProps++; + } + // Created Date/Time + if($this->_phpExcel->getProperties()->getCreated()){ + $dataProp = $this->_phpExcel->getProperties()->getCreated(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Modified Date/Time + if($this->_phpExcel->getProperties()->getModified()){ + $dataProp = $this->_phpExcel->getProperties()->getModified(); + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + 'data' => array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp))); + $dataSection_NumProps++; + } + // Security + $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13), + 'offset' => array('pack' => 'V'), + 'type' => array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer + 'data' => array('data' => 0x00)); + $dataSection_NumProps++; + + + // 4 Section Length + // 4 Property count + // 8 * $dataSection_NumProps (8 = ID (4) + OffSet(4)) + $dataSection_Content_Offset = 8 + $dataSection_NumProps * 8; + foreach ($dataSection as $dataProp){ + // Summary + $dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']); + // Offset + $dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset); + // DataType + $dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']); + // Data + if($dataProp['type']['data'] == 0x02){ // 2 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer + $dataSection_Content .= pack('V', $dataProp['data']['data']); + + $dataSection_Content_Offset += 4 + 4; + } + elseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length + // Null-terminated string + $dataProp['data']['data'] .= chr(0); + $dataProp['data']['length'] += 1; + // Complete the string with null string for being a %4 + $dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4)); + $dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT); + + $dataSection_Content .= pack('V', $dataProp['data']['length']); + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']); + } + elseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601) + $dataSection_Content .= $dataProp['data']['data']; + + $dataSection_Content_Offset += 4 + 8; + } + else { + // Data Type Not Used at the moment + } + } + // Now $dataSection_Content_Offset contains the size of the content + + // section header + // offset: $secOffset; size: 4; section length + // + x Size of the content (summary + content) + $data .= pack('V', $dataSection_Content_Offset); + // offset: $secOffset+4; size: 4; property count + $data .= pack('V', $dataSection_NumProps); + // Section Summary + $data .= $dataSection_Summary; + // Section Content + $data .= $dataSection_Content; + + return $data; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php b/extend/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php new file mode 100755 index 0000000..b3e48bc --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/BIFFwriter.php @@ -0,0 +1,255 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_BIFFwriter (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_BIFFwriter + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * The byte order of this architecture. 0 => little endian, 1 => big endian + * @var integer + */ + private static $_byte_order; + + /** + * The string containing the data of the BIFF stream + * @var string + */ + public $_data; + + /** + * The size of the data in bytes. Should be the same as strlen($this->_data) + * @var integer + */ + public $_datasize; + + /** + * The maximum length for a BIFF record (excluding record header and length field). See _addContinue() + * @var integer + * @see _addContinue() + */ + public $_limit = 8224; + + /** + * Constructor + */ + public function __construct() + { + $this->_data = ''; + $this->_datasize = 0; +// $this->_limit = 8224; + } + + /** + * Determine the byte order and store it as class data to avoid + * recalculating it for each call to new(). + * + * @return int + */ + public static function getByteOrder() + { + if (!isset(self::$_byte_order)) { + // Check if "pack" gives the required IEEE 64bit float + $teststr = pack("d", 1.2345); + $number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); + if ($number == $teststr) { + $byte_order = 0; // Little Endian + } elseif ($number == strrev($teststr)){ + $byte_order = 1; // Big Endian + } else { + // Give up. I'll fix this in a later version. + throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); + } + self::$_byte_order = $byte_order; + } + + return self::$_byte_order; + } + + /** + * General storage function + * + * @param string $data binary data to append + * @access private + */ + function _append($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_data .= $data; + $this->_datasize += strlen($data); + } + + /** + * General storage function like _append, but returns string instead of modifying $this->_data + * + * @param string $data binary data to write + * @return string + */ + public function writeData($data) + { + if (strlen($data) - 4 > $this->_limit) { + $data = $this->_addContinue($data); + } + $this->_datasize += strlen($data); + + return $data; + } + + /** + * Writes Excel BOF record to indicate the beginning of a stream or + * sub-stream in the BIFF file. + * + * @param integer $type Type of BIFF file to write: 0x0005 Workbook, + * 0x0010 Worksheet. + * @access private + */ + function _storeBof($type) + { + $record = 0x0809; // Record identifier (BIFF5-BIFF8) + $length = 0x0010; + + // by inspection of real files, MS Office Excel 2007 writes the following + $unknown = pack("VV", 0x000100D1, 0x00000406); + + $build = 0x0DBB; // Excel 97 + $year = 0x07CC; // Excel 97 + + $version = 0x0600; // BIFF8 + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $version, $type, $build, $year); + $this->_append($header . $data . $unknown); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + function _storeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $this->_append($header); + } + + /** + * Writes Excel EOF record to indicate the end of a BIFF stream. + * + * @access private + */ + public function writeEof() + { + $record = 0x000A; // Record identifier + $length = 0x0000; // Number of bytes to follow + $header = pack("vv", $record, $length); + return $this->writeData($header); + } + + /** + * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In + * Excel 97 the limit is 8228 bytes. Records that are longer than these limits + * must be split up into CONTINUE blocks. + * + * This function takes a long BIFF record and inserts CONTINUE records as + * necessary. + * + * @param string $data The original binary data to be written + * @return string A very convenient string of continue blocks + * @access private + */ + function _addContinue($data) + { + $limit = $this->_limit; + $record = 0x003C; // Record identifier + + // The first 2080/8224 bytes remain intact. However, we have to change + // the length field of the record. + $tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); + + $header = pack("vv", $record, $limit); // Headers for continue records + + // Retrieve chunks of 2080/8224 bytes +4 for the header. + $data_length = strlen($data); + for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { + $tmp .= $header; + $tmp .= substr($data, $i, $limit); + } + + // Retrieve the last chunk of data + $header = pack("vv", $record, strlen($data) - $i); + $tmp .= $header; + $tmp .= substr($data, $i, strlen($data) - $i); + + return $tmp; + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Escher.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Escher.php new file mode 100755 index 0000000..7e9b73a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Escher.php @@ -0,0 +1,537 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Shared_Escher_DggContainer_BstoreContainer + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Escher +{ + /** + * The object we are writing + */ + private $_object; + + /** + * The written binary data + */ + private $_data; + + /** + * Shape offsets. Positions in binary stream where a new shape record begins + * + * @var array + */ + private $_spOffsets; + + /** + * Shape types. + * + * @var array + */ + private $_spTypes; + + /** + * Constructor + * + * @param mixed + */ + public function __construct($object) + { + $this->_object = $object; + } + + /** + * Process the object to be written + */ + public function close() + { + // initialize + $this->_data = ''; + + switch (get_class($this->_object)) { + + case 'PHPExcel_Shared_Escher': + if ($dggContainer = $this->_object->getDggContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer); + $this->_data = $writer->close(); + } else if ($dgContainer = $this->_object->getDgContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer); + $this->_data = $writer->close(); + $this->_spOffsets = $writer->getSpOffsets(); + $this->_spTypes = $writer->getSpTypes(); + } + break; + + case 'PHPExcel_Shared_Escher_DggContainer': + // this is a container record + + // initialize + $innerData = ''; + + // write the dgg + $recVer = 0x0; + $recInstance = 0x0000; + $recType = 0xF006; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + // dgg data + $dggData = + pack('VVVV' + , $this->_object->getSpIdMax() // maximum shape identifier increased by one + , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one + , $this->_object->getCSpSaved() + , $this->_object->getCDgSaved() // count total number of drawings saved + ); + + // add file identifier clusters (one per drawing) + $IDCLs = $this->_object->getIDCLs(); + + foreach ($IDCLs as $dgId => $maxReducedSpId) { + $dggData .= pack('VV', $dgId, $maxReducedSpId + 1); + } + + $header = pack('vvV', $recVerInstance, $recType, strlen($dggData)); + $innerData .= $header . $dggData; + + // write the bstoreContainer + if ($bstoreContainer = $this->_object->getBstoreContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer); + $innerData .= $writer->close(); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF000; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer': + // this is a container record + + // initialize + $innerData = ''; + + // treat the inner data + if ($BSECollection = $this->_object->getBSECollection()) { + foreach ($BSECollection as $BSE) { + $writer = new PHPExcel_Writer_Excel5_Escher($BSE); + $innerData .= $writer->close(); + } + } + + // write the record + $recVer = 0xF; + $recInstance = count($this->_object->getBSECollection()); + $recType = 0xF001; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE': + // this is a semi-container record + + // initialize + $innerData = ''; + + // here we treat the inner data + if ($blip = $this->_object->getBlip()) { + $writer = new PHPExcel_Writer_Excel5_Escher($blip); + $innerData .= $writer->close(); + } + + // initialize + $data = ''; + + $btWin32 = $this->_object->getBlipType(); + $btMacOS = $this->_object->getBlipType(); + $data .= pack('CC', $btWin32, $btMacOS); + + $rgbUid = pack('VVVV', 0,0,0,0); // todo + $data .= $rgbUid; + + $tag = 0; + $size = strlen($innerData); + $cRef = 1; + $foDelay = 0; //todo + $unused1 = 0x0; + $cbName = 0x0; + $unused2 = 0x0; + $unused3 = 0x0; + $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3); + + $data .= $innerData; + + // write the record + $recVer = 0x2; + $recInstance = $this->_object->getBlipType(); + $recType = 0xF007; + $length = strlen($data); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $data; + break; + + case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip': + // this is an atom record + + // write the record + switch ($this->_object->getParent()->getBlipType()) { + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG: + // initialize + $innerData = ''; + + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; + + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); + + $innerData .= $this->_object->getData(); + + $recVer = 0x0; + $recInstance = 0x46A; + $recType = 0xF01D; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $innerData; + break; + + case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG: + // initialize + $innerData = ''; + + $rgbUid1 = pack('VVVV', 0,0,0,0); // todo + $innerData .= $rgbUid1; + + $tag = 0xFF; // todo + $innerData .= pack('C', $tag); + + $innerData .= $this->_object->getData(); + + $recVer = 0x0; + $recInstance = 0x6E0; + $recType = 0xF01E; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header; + + $this->_data .= $innerData; + break; + + } + break; + + case 'PHPExcel_Shared_Escher_DgContainer': + // this is a container record + + // initialize + $innerData = ''; + + // write the dg + $recVer = 0x0; + $recInstance = $this->_object->getDgId(); + $recType = 0xF008; + $length = 8; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + // number of shapes in this drawing (including group shape) + $countShapes = count($this->_object->getSpgrContainer()->getChildren()); + $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId()); + //$innerData .= $header . pack('VV', 0, 0); + + // write the spgrContainer + if ($spgrContainer = $this->_object->getSpgrContainer()) { + $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer); + $innerData .= $writer->close(); + + // get the shape offsets relative to the spgrContainer record + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + + // save the shape offsets relative to dgContainer + foreach ($spOffsets as & $spOffset) { + $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes) + } + + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF002; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + break; + + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer': + // this is a container record + + // initialize + $innerData = ''; + + // initialize spape offsets + $totalSize = 8; + $spOffsets = array(); + $spTypes = array(); + + // treat the inner data + foreach ($this->_object->getChildren() as $spContainer) { + $writer = new PHPExcel_Writer_Excel5_Escher($spContainer); + $spData = $writer->close(); + $innerData .= $spData; + + // save the shape offsets (where new shape records begin) + $totalSize += strlen($spData); + $spOffsets[] = $totalSize; + + $spTypes = array_merge($spTypes, $writer->getSpTypes()); + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF003; + $length = strlen($innerData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $innerData; + $this->_spOffsets = $spOffsets; + $this->_spTypes = $spTypes; + break; + + case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer': + // initialize + $data = ''; + + // build the data + + // write group shape record, if necessary? + if ($this->_object->getSpgr()) { + $recVer = 0x1; + $recInstance = 0x0000; + $recType = 0xF009; + $length = 0x00000010; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $data .= $header . pack('VVVV', 0,0,0,0); + } + $this->_spTypes[] = ($this->_object->getSpType()); + + // write the shape record + $recVer = 0x2; + $recInstance = $this->_object->getSpType(); // shape type + $recType = 0xF00A; + $length = 0x00000008; + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00); + + + // the options + if ($this->_object->getOPTCollection()) { + $optData = ''; + + $recVer = 0x3; + $recInstance = count($this->_object->getOPTCollection()); + $recType = 0xF00B; + foreach ($this->_object->getOPTCollection() as $property => $value) { + $optData .= pack('vV', $property, $value); + } + $length = strlen($optData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $optData; + } + + // the client anchor + if ($this->_object->getStartCoordinates()) { + $clientAnchorData = ''; + + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF010; + + // start coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates()); + $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r1 = $row - 1; + + // start offsetX + $startOffsetX = $this->_object->getStartOffsetX(); + + // start offsetY + $startOffsetY = $this->_object->getStartOffsetY(); + + // end coordinates + list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates()); + $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1; + $r2 = $row - 1; + + // end offsetX + $endOffsetX = $this->_object->getEndOffsetX(); + + // end offsetY + $endOffsetY = $this->_object->getEndOffsetY(); + + $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(), + $c1, $startOffsetX, $r1, $startOffsetY, + $c2, $endOffsetX, $r2, $endOffsetY); + + $length = strlen($clientAnchorData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientAnchorData; + } + + // the client data, just empty for now + if (!$this->_object->getSpgr()) { + $clientDataData = ''; + + $recVer = 0x0; + $recInstance = 0x0; + $recType = 0xF011; + + $length = strlen($clientDataData); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + $data .= $header . $clientDataData; + } + + // write the record + $recVer = 0xF; + $recInstance = 0x0000; + $recType = 0xF004; + $length = strlen($data); + + $recVerInstance = $recVer; + $recVerInstance |= $recInstance << 4; + + $header = pack('vvV', $recVerInstance, $recType, $length); + + $this->_data = $header . $data; + break; + + } + + return $this->_data; + } + + /** + * Gets the shape offsets + * + * @return array + */ + public function getSpOffsets() + { + return $this->_spOffsets; + } + + /** + * Gets the shape types + * + * @return array + */ + public function getSpTypes() + { + return $this->_spTypes; + } + + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Font.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Font.php new file mode 100755 index 0000000..f2dbab2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Font.php @@ -0,0 +1,165 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Excel5_Font + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Font +{ + /** + * Color index + * + * @var int + */ + private $_colorIndex; + + /** + * Font + * + * @var PHPExcel_Style_Font + */ + private $_font; + + /** + * Constructor + * + * @param PHPExcel_Style_Font $font + */ + public function __construct(PHPExcel_Style_Font $font = null) + { + $this->_colorIndex = 0x7FFF; + $this->_font = $font; + } + + /** + * Set the color index + * + * @param int $colorIndex + */ + public function setColorIndex($colorIndex) + { + $this->_colorIndex = $colorIndex; + } + + /** + * Get font record data + * + * @return string + */ + public function writeFont() + { + $font_outline = 0; + $font_shadow = 0; + + $icv = $this->_colorIndex; // Index to color palette + if ($this->_font->getSuperScript()) { + $sss = 1; + } else if ($this->_font->getSubScript()) { + $sss = 2; + } else { + $sss = 0; + } + $bFamily = 0; // Font family + $bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set + + $record = 0x31; // Record identifier + $reserved = 0x00; // Reserved + $grbit = 0x00; // Font attributes + if ($this->_font->getItalic()) { + $grbit |= 0x02; + } + if ($this->_font->getStrikethrough()) { + $grbit |= 0x08; + } + if ($font_outline) { + $grbit |= 0x10; + } + if ($font_shadow) { + $grbit |= 0x20; + } + + $data = pack("vvvvvCCCC", + $this->_font->getSize() * 20, // Fontsize (in twips) + $grbit, + $icv, // Colour + self::_mapBold($this->_font->getBold()), // Font weight + $sss, // Superscript/Subscript + self::_mapUnderline($this->_font->getUnderline()), + $bFamily, + $bCharSet, + $reserved + ); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName()); + + $length = strlen($data); + $header = pack("vv", $record, $length); + + return($header . $data); + } + + /** + * Map to BIFF5-BIFF8 codes for bold + * + * @param boolean $bold + * @return int + */ + private static function _mapBold($bold) { + if ($bold) { + return 0x2BC; // 700 = Bold font weight + } + return 0x190; // 400 = Normal font weight + } + + /** + * Map of BIFF2-BIFF8 codes for underline styles + * @static array of int + * + */ + private static $_mapUnderline = array( PHPExcel_Style_Font::UNDERLINE_NONE => 0x00, + PHPExcel_Style_Font::UNDERLINE_SINGLE => 0x01, + PHPExcel_Style_Font::UNDERLINE_DOUBLE => 0x02, + PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING => 0x21, + PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING => 0x22, + ); + /** + * Map underline + * + * @param string + * @return int + */ + private static function _mapUnderline($underline) { + if (isset(self::$_mapUnderline[$underline])) + return self::$_mapUnderline[$underline]; + return 0x00; + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Parser.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Parser.php new file mode 100755 index 0000000..04e674a --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Parser.php @@ -0,0 +1,1582 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Parser (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// * Class for parsing Excel formulas +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Parser + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Parser +{ + /** Constants */ + // Sheet title in unquoted form + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] + // Moreover, there are valid sheet title characters that cannot occur in unquoted form (there may be more?) + // +-% '^&<>=,;#()"{} + const REGEX_SHEET_TITLE_UNQUOTED = '[^\*\:\/\\\\\?\[\]\+\-\% \\\'\^\&\<\>\=\,\;\#\(\)\"\{\}]+'; + + // Sheet title in quoted form (without surrounding quotes) + // Invalid sheet title characters cannot occur in the sheet title: + // *:/\?[] (usual invalid sheet title characters) + // Single quote is represented as a pair '' + const REGEX_SHEET_TITLE_QUOTED = '(([^\*\:\/\\\\\?\[\]\\\'])+|(\\\'\\\')+)+'; + + /** + * The index of the character we are currently looking at + * @var integer + */ + public $_current_char; + + /** + * The token we are working on. + * @var string + */ + public $_current_token; + + /** + * The formula to parse + * @var string + */ + public $_formula; + + /** + * The character ahead of the current char + * @var string + */ + public $_lookahead; + + /** + * The parse tree to be generated + * @var string + */ + public $_parse_tree; + + /** + * Array of external sheets + * @var array + */ + public $_ext_sheets; + + /** + * Array of sheet references in the form of REF structures + * @var array + */ + public $_references; + + /** + * The class constructor + * + */ + public function __construct() + { + $this->_current_char = 0; + $this->_current_token = ''; // The token we are working on. + $this->_formula = ''; // The formula to parse. + $this->_lookahead = ''; // The character ahead of the current char. + $this->_parse_tree = ''; // The parse tree to be generated. + $this->_initializeHashes(); // Initialize the hashes: ptg's and function's ptg's + $this->_ext_sheets = array(); + $this->_references = array(); + } + + /** + * Initialize the ptg and function hashes. + * + * @access private + */ + function _initializeHashes() + { + // The Excel ptg indices + $this->ptg = array( + 'ptgExp' => 0x01, + 'ptgTbl' => 0x02, + 'ptgAdd' => 0x03, + 'ptgSub' => 0x04, + 'ptgMul' => 0x05, + 'ptgDiv' => 0x06, + 'ptgPower' => 0x07, + 'ptgConcat' => 0x08, + 'ptgLT' => 0x09, + 'ptgLE' => 0x0A, + 'ptgEQ' => 0x0B, + 'ptgGE' => 0x0C, + 'ptgGT' => 0x0D, + 'ptgNE' => 0x0E, + 'ptgIsect' => 0x0F, + 'ptgUnion' => 0x10, + 'ptgRange' => 0x11, + 'ptgUplus' => 0x12, + 'ptgUminus' => 0x13, + 'ptgPercent' => 0x14, + 'ptgParen' => 0x15, + 'ptgMissArg' => 0x16, + 'ptgStr' => 0x17, + 'ptgAttr' => 0x19, + 'ptgSheet' => 0x1A, + 'ptgEndSheet' => 0x1B, + 'ptgErr' => 0x1C, + 'ptgBool' => 0x1D, + 'ptgInt' => 0x1E, + 'ptgNum' => 0x1F, + 'ptgArray' => 0x20, + 'ptgFunc' => 0x21, + 'ptgFuncVar' => 0x22, + 'ptgName' => 0x23, + 'ptgRef' => 0x24, + 'ptgArea' => 0x25, + 'ptgMemArea' => 0x26, + 'ptgMemErr' => 0x27, + 'ptgMemNoMem' => 0x28, + 'ptgMemFunc' => 0x29, + 'ptgRefErr' => 0x2A, + 'ptgAreaErr' => 0x2B, + 'ptgRefN' => 0x2C, + 'ptgAreaN' => 0x2D, + 'ptgMemAreaN' => 0x2E, + 'ptgMemNoMemN' => 0x2F, + 'ptgNameX' => 0x39, + 'ptgRef3d' => 0x3A, + 'ptgArea3d' => 0x3B, + 'ptgRefErr3d' => 0x3C, + 'ptgAreaErr3d' => 0x3D, + 'ptgArrayV' => 0x40, + 'ptgFuncV' => 0x41, + 'ptgFuncVarV' => 0x42, + 'ptgNameV' => 0x43, + 'ptgRefV' => 0x44, + 'ptgAreaV' => 0x45, + 'ptgMemAreaV' => 0x46, + 'ptgMemErrV' => 0x47, + 'ptgMemNoMemV' => 0x48, + 'ptgMemFuncV' => 0x49, + 'ptgRefErrV' => 0x4A, + 'ptgAreaErrV' => 0x4B, + 'ptgRefNV' => 0x4C, + 'ptgAreaNV' => 0x4D, + 'ptgMemAreaNV' => 0x4E, + 'ptgMemNoMemN' => 0x4F, + 'ptgFuncCEV' => 0x58, + 'ptgNameXV' => 0x59, + 'ptgRef3dV' => 0x5A, + 'ptgArea3dV' => 0x5B, + 'ptgRefErr3dV' => 0x5C, + 'ptgAreaErr3d' => 0x5D, + 'ptgArrayA' => 0x60, + 'ptgFuncA' => 0x61, + 'ptgFuncVarA' => 0x62, + 'ptgNameA' => 0x63, + 'ptgRefA' => 0x64, + 'ptgAreaA' => 0x65, + 'ptgMemAreaA' => 0x66, + 'ptgMemErrA' => 0x67, + 'ptgMemNoMemA' => 0x68, + 'ptgMemFuncA' => 0x69, + 'ptgRefErrA' => 0x6A, + 'ptgAreaErrA' => 0x6B, + 'ptgRefNA' => 0x6C, + 'ptgAreaNA' => 0x6D, + 'ptgMemAreaNA' => 0x6E, + 'ptgMemNoMemN' => 0x6F, + 'ptgFuncCEA' => 0x78, + 'ptgNameXA' => 0x79, + 'ptgRef3dA' => 0x7A, + 'ptgArea3dA' => 0x7B, + 'ptgRefErr3dA' => 0x7C, + 'ptgAreaErr3d' => 0x7D + ); + + // Thanks to Michael Meeks and Gnumeric for the initial arg values. + // + // The following hash was generated by "function_locale.pl" in the distro. + // Refer to function_locale.pl for non-English function names. + // + // The array elements are as follow: + // ptg: The Excel function ptg code. + // args: The number of arguments that the function takes: + // >=0 is a fixed number of arguments. + // -1 is a variable number of arguments. + // class: The reference, value or array class of the function args. + // vol: The function is volatile. + // + $this->_functions = array( + // function ptg args class vol + 'COUNT' => array( 0, -1, 0, 0 ), + 'IF' => array( 1, -1, 1, 0 ), + 'ISNA' => array( 2, 1, 1, 0 ), + 'ISERROR' => array( 3, 1, 1, 0 ), + 'SUM' => array( 4, -1, 0, 0 ), + 'AVERAGE' => array( 5, -1, 0, 0 ), + 'MIN' => array( 6, -1, 0, 0 ), + 'MAX' => array( 7, -1, 0, 0 ), + 'ROW' => array( 8, -1, 0, 0 ), + 'COLUMN' => array( 9, -1, 0, 0 ), + 'NA' => array( 10, 0, 0, 0 ), + 'NPV' => array( 11, -1, 1, 0 ), + 'STDEV' => array( 12, -1, 0, 0 ), + 'DOLLAR' => array( 13, -1, 1, 0 ), + 'FIXED' => array( 14, -1, 1, 0 ), + 'SIN' => array( 15, 1, 1, 0 ), + 'COS' => array( 16, 1, 1, 0 ), + 'TAN' => array( 17, 1, 1, 0 ), + 'ATAN' => array( 18, 1, 1, 0 ), + 'PI' => array( 19, 0, 1, 0 ), + 'SQRT' => array( 20, 1, 1, 0 ), + 'EXP' => array( 21, 1, 1, 0 ), + 'LN' => array( 22, 1, 1, 0 ), + 'LOG10' => array( 23, 1, 1, 0 ), + 'ABS' => array( 24, 1, 1, 0 ), + 'INT' => array( 25, 1, 1, 0 ), + 'SIGN' => array( 26, 1, 1, 0 ), + 'ROUND' => array( 27, 2, 1, 0 ), + 'LOOKUP' => array( 28, -1, 0, 0 ), + 'INDEX' => array( 29, -1, 0, 1 ), + 'REPT' => array( 30, 2, 1, 0 ), + 'MID' => array( 31, 3, 1, 0 ), + 'LEN' => array( 32, 1, 1, 0 ), + 'VALUE' => array( 33, 1, 1, 0 ), + 'TRUE' => array( 34, 0, 1, 0 ), + 'FALSE' => array( 35, 0, 1, 0 ), + 'AND' => array( 36, -1, 0, 0 ), + 'OR' => array( 37, -1, 0, 0 ), + 'NOT' => array( 38, 1, 1, 0 ), + 'MOD' => array( 39, 2, 1, 0 ), + 'DCOUNT' => array( 40, 3, 0, 0 ), + 'DSUM' => array( 41, 3, 0, 0 ), + 'DAVERAGE' => array( 42, 3, 0, 0 ), + 'DMIN' => array( 43, 3, 0, 0 ), + 'DMAX' => array( 44, 3, 0, 0 ), + 'DSTDEV' => array( 45, 3, 0, 0 ), + 'VAR' => array( 46, -1, 0, 0 ), + 'DVAR' => array( 47, 3, 0, 0 ), + 'TEXT' => array( 48, 2, 1, 0 ), + 'LINEST' => array( 49, -1, 0, 0 ), + 'TREND' => array( 50, -1, 0, 0 ), + 'LOGEST' => array( 51, -1, 0, 0 ), + 'GROWTH' => array( 52, -1, 0, 0 ), + 'PV' => array( 56, -1, 1, 0 ), + 'FV' => array( 57, -1, 1, 0 ), + 'NPER' => array( 58, -1, 1, 0 ), + 'PMT' => array( 59, -1, 1, 0 ), + 'RATE' => array( 60, -1, 1, 0 ), + 'MIRR' => array( 61, 3, 0, 0 ), + 'IRR' => array( 62, -1, 0, 0 ), + 'RAND' => array( 63, 0, 1, 1 ), + 'MATCH' => array( 64, -1, 0, 0 ), + 'DATE' => array( 65, 3, 1, 0 ), + 'TIME' => array( 66, 3, 1, 0 ), + 'DAY' => array( 67, 1, 1, 0 ), + 'MONTH' => array( 68, 1, 1, 0 ), + 'YEAR' => array( 69, 1, 1, 0 ), + 'WEEKDAY' => array( 70, -1, 1, 0 ), + 'HOUR' => array( 71, 1, 1, 0 ), + 'MINUTE' => array( 72, 1, 1, 0 ), + 'SECOND' => array( 73, 1, 1, 0 ), + 'NOW' => array( 74, 0, 1, 1 ), + 'AREAS' => array( 75, 1, 0, 1 ), + 'ROWS' => array( 76, 1, 0, 1 ), + 'COLUMNS' => array( 77, 1, 0, 1 ), + 'OFFSET' => array( 78, -1, 0, 1 ), + 'SEARCH' => array( 82, -1, 1, 0 ), + 'TRANSPOSE' => array( 83, 1, 1, 0 ), + 'TYPE' => array( 86, 1, 1, 0 ), + 'ATAN2' => array( 97, 2, 1, 0 ), + 'ASIN' => array( 98, 1, 1, 0 ), + 'ACOS' => array( 99, 1, 1, 0 ), + 'CHOOSE' => array( 100, -1, 1, 0 ), + 'HLOOKUP' => array( 101, -1, 0, 0 ), + 'VLOOKUP' => array( 102, -1, 0, 0 ), + 'ISREF' => array( 105, 1, 0, 0 ), + 'LOG' => array( 109, -1, 1, 0 ), + 'CHAR' => array( 111, 1, 1, 0 ), + 'LOWER' => array( 112, 1, 1, 0 ), + 'UPPER' => array( 113, 1, 1, 0 ), + 'PROPER' => array( 114, 1, 1, 0 ), + 'LEFT' => array( 115, -1, 1, 0 ), + 'RIGHT' => array( 116, -1, 1, 0 ), + 'EXACT' => array( 117, 2, 1, 0 ), + 'TRIM' => array( 118, 1, 1, 0 ), + 'REPLACE' => array( 119, 4, 1, 0 ), + 'SUBSTITUTE' => array( 120, -1, 1, 0 ), + 'CODE' => array( 121, 1, 1, 0 ), + 'FIND' => array( 124, -1, 1, 0 ), + 'CELL' => array( 125, -1, 0, 1 ), + 'ISERR' => array( 126, 1, 1, 0 ), + 'ISTEXT' => array( 127, 1, 1, 0 ), + 'ISNUMBER' => array( 128, 1, 1, 0 ), + 'ISBLANK' => array( 129, 1, 1, 0 ), + 'T' => array( 130, 1, 0, 0 ), + 'N' => array( 131, 1, 0, 0 ), + 'DATEVALUE' => array( 140, 1, 1, 0 ), + 'TIMEVALUE' => array( 141, 1, 1, 0 ), + 'SLN' => array( 142, 3, 1, 0 ), + 'SYD' => array( 143, 4, 1, 0 ), + 'DDB' => array( 144, -1, 1, 0 ), + 'INDIRECT' => array( 148, -1, 1, 1 ), + 'CALL' => array( 150, -1, 1, 0 ), + 'CLEAN' => array( 162, 1, 1, 0 ), + 'MDETERM' => array( 163, 1, 2, 0 ), + 'MINVERSE' => array( 164, 1, 2, 0 ), + 'MMULT' => array( 165, 2, 2, 0 ), + 'IPMT' => array( 167, -1, 1, 0 ), + 'PPMT' => array( 168, -1, 1, 0 ), + 'COUNTA' => array( 169, -1, 0, 0 ), + 'PRODUCT' => array( 183, -1, 0, 0 ), + 'FACT' => array( 184, 1, 1, 0 ), + 'DPRODUCT' => array( 189, 3, 0, 0 ), + 'ISNONTEXT' => array( 190, 1, 1, 0 ), + 'STDEVP' => array( 193, -1, 0, 0 ), + 'VARP' => array( 194, -1, 0, 0 ), + 'DSTDEVP' => array( 195, 3, 0, 0 ), + 'DVARP' => array( 196, 3, 0, 0 ), + 'TRUNC' => array( 197, -1, 1, 0 ), + 'ISLOGICAL' => array( 198, 1, 1, 0 ), + 'DCOUNTA' => array( 199, 3, 0, 0 ), + 'USDOLLAR' => array( 204, -1, 1, 0 ), + 'FINDB' => array( 205, -1, 1, 0 ), + 'SEARCHB' => array( 206, -1, 1, 0 ), + 'REPLACEB' => array( 207, 4, 1, 0 ), + 'LEFTB' => array( 208, -1, 1, 0 ), + 'RIGHTB' => array( 209, -1, 1, 0 ), + 'MIDB' => array( 210, 3, 1, 0 ), + 'LENB' => array( 211, 1, 1, 0 ), + 'ROUNDUP' => array( 212, 2, 1, 0 ), + 'ROUNDDOWN' => array( 213, 2, 1, 0 ), + 'ASC' => array( 214, 1, 1, 0 ), + 'DBCS' => array( 215, 1, 1, 0 ), + 'RANK' => array( 216, -1, 0, 0 ), + 'ADDRESS' => array( 219, -1, 1, 0 ), + 'DAYS360' => array( 220, -1, 1, 0 ), + 'TODAY' => array( 221, 0, 1, 1 ), + 'VDB' => array( 222, -1, 1, 0 ), + 'MEDIAN' => array( 227, -1, 0, 0 ), + 'SUMPRODUCT' => array( 228, -1, 2, 0 ), + 'SINH' => array( 229, 1, 1, 0 ), + 'COSH' => array( 230, 1, 1, 0 ), + 'TANH' => array( 231, 1, 1, 0 ), + 'ASINH' => array( 232, 1, 1, 0 ), + 'ACOSH' => array( 233, 1, 1, 0 ), + 'ATANH' => array( 234, 1, 1, 0 ), + 'DGET' => array( 235, 3, 0, 0 ), + 'INFO' => array( 244, 1, 1, 1 ), + 'DB' => array( 247, -1, 1, 0 ), + 'FREQUENCY' => array( 252, 2, 0, 0 ), + 'ERROR.TYPE' => array( 261, 1, 1, 0 ), + 'REGISTER.ID' => array( 267, -1, 1, 0 ), + 'AVEDEV' => array( 269, -1, 0, 0 ), + 'BETADIST' => array( 270, -1, 1, 0 ), + 'GAMMALN' => array( 271, 1, 1, 0 ), + 'BETAINV' => array( 272, -1, 1, 0 ), + 'BINOMDIST' => array( 273, 4, 1, 0 ), + 'CHIDIST' => array( 274, 2, 1, 0 ), + 'CHIINV' => array( 275, 2, 1, 0 ), + 'COMBIN' => array( 276, 2, 1, 0 ), + 'CONFIDENCE' => array( 277, 3, 1, 0 ), + 'CRITBINOM' => array( 278, 3, 1, 0 ), + 'EVEN' => array( 279, 1, 1, 0 ), + 'EXPONDIST' => array( 280, 3, 1, 0 ), + 'FDIST' => array( 281, 3, 1, 0 ), + 'FINV' => array( 282, 3, 1, 0 ), + 'FISHER' => array( 283, 1, 1, 0 ), + 'FISHERINV' => array( 284, 1, 1, 0 ), + 'FLOOR' => array( 285, 2, 1, 0 ), + 'GAMMADIST' => array( 286, 4, 1, 0 ), + 'GAMMAINV' => array( 287, 3, 1, 0 ), + 'CEILING' => array( 288, 2, 1, 0 ), + 'HYPGEOMDIST' => array( 289, 4, 1, 0 ), + 'LOGNORMDIST' => array( 290, 3, 1, 0 ), + 'LOGINV' => array( 291, 3, 1, 0 ), + 'NEGBINOMDIST' => array( 292, 3, 1, 0 ), + 'NORMDIST' => array( 293, 4, 1, 0 ), + 'NORMSDIST' => array( 294, 1, 1, 0 ), + 'NORMINV' => array( 295, 3, 1, 0 ), + 'NORMSINV' => array( 296, 1, 1, 0 ), + 'STANDARDIZE' => array( 297, 3, 1, 0 ), + 'ODD' => array( 298, 1, 1, 0 ), + 'PERMUT' => array( 299, 2, 1, 0 ), + 'POISSON' => array( 300, 3, 1, 0 ), + 'TDIST' => array( 301, 3, 1, 0 ), + 'WEIBULL' => array( 302, 4, 1, 0 ), + 'SUMXMY2' => array( 303, 2, 2, 0 ), + 'SUMX2MY2' => array( 304, 2, 2, 0 ), + 'SUMX2PY2' => array( 305, 2, 2, 0 ), + 'CHITEST' => array( 306, 2, 2, 0 ), + 'CORREL' => array( 307, 2, 2, 0 ), + 'COVAR' => array( 308, 2, 2, 0 ), + 'FORECAST' => array( 309, 3, 2, 0 ), + 'FTEST' => array( 310, 2, 2, 0 ), + 'INTERCEPT' => array( 311, 2, 2, 0 ), + 'PEARSON' => array( 312, 2, 2, 0 ), + 'RSQ' => array( 313, 2, 2, 0 ), + 'STEYX' => array( 314, 2, 2, 0 ), + 'SLOPE' => array( 315, 2, 2, 0 ), + 'TTEST' => array( 316, 4, 2, 0 ), + 'PROB' => array( 317, -1, 2, 0 ), + 'DEVSQ' => array( 318, -1, 0, 0 ), + 'GEOMEAN' => array( 319, -1, 0, 0 ), + 'HARMEAN' => array( 320, -1, 0, 0 ), + 'SUMSQ' => array( 321, -1, 0, 0 ), + 'KURT' => array( 322, -1, 0, 0 ), + 'SKEW' => array( 323, -1, 0, 0 ), + 'ZTEST' => array( 324, -1, 0, 0 ), + 'LARGE' => array( 325, 2, 0, 0 ), + 'SMALL' => array( 326, 2, 0, 0 ), + 'QUARTILE' => array( 327, 2, 0, 0 ), + 'PERCENTILE' => array( 328, 2, 0, 0 ), + 'PERCENTRANK' => array( 329, -1, 0, 0 ), + 'MODE' => array( 330, -1, 2, 0 ), + 'TRIMMEAN' => array( 331, 2, 0, 0 ), + 'TINV' => array( 332, 2, 1, 0 ), + 'CONCATENATE' => array( 336, -1, 1, 0 ), + 'POWER' => array( 337, 2, 1, 0 ), + 'RADIANS' => array( 342, 1, 1, 0 ), + 'DEGREES' => array( 343, 1, 1, 0 ), + 'SUBTOTAL' => array( 344, -1, 0, 0 ), + 'SUMIF' => array( 345, -1, 0, 0 ), + 'COUNTIF' => array( 346, 2, 0, 0 ), + 'COUNTBLANK' => array( 347, 1, 0, 0 ), + 'ISPMT' => array( 350, 4, 1, 0 ), + 'DATEDIF' => array( 351, 3, 1, 0 ), + 'DATESTRING' => array( 352, 1, 1, 0 ), + 'NUMBERSTRING' => array( 353, 2, 1, 0 ), + 'ROMAN' => array( 354, -1, 1, 0 ), + 'GETPIVOTDATA' => array( 358, -1, 0, 0 ), + 'HYPERLINK' => array( 359, -1, 1, 0 ), + 'PHONETIC' => array( 360, 1, 0, 0 ), + 'AVERAGEA' => array( 361, -1, 0, 0 ), + 'MAXA' => array( 362, -1, 0, 0 ), + 'MINA' => array( 363, -1, 0, 0 ), + 'STDEVPA' => array( 364, -1, 0, 0 ), + 'VARPA' => array( 365, -1, 0, 0 ), + 'STDEVA' => array( 366, -1, 0, 0 ), + 'VARA' => array( 367, -1, 0, 0 ), + 'BAHTTEXT' => array( 368, 1, 0, 0 ), + ); + } + + /** + * Convert a token to the proper ptg value. + * + * @access private + * @param mixed $token The token to convert. + * @return mixed the converted token on success + */ + function _convert($token) + { + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $token)) { + return $this->_convertString($token); + + } elseif (is_numeric($token)) { + return $this->_convertNumber($token); + + // match references like A1 or $A$1 + } elseif (preg_match('/^\$?([A-Ia-i]?[A-Za-z])\$?(\d+)$/',$token)) { + return $this->_convertRef2d($token); + + // match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?(\d+)$/u",$token)) { + return $this->_convertRef3d($token); + + // match ranges like A1:B2 or $A$1:$B$2 + } elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)\:(\$)?[A-Ia-i]?[A-Za-z](\$)?(\d+)$/', $token)) { + return $this->_convertRange2d($token); + + // match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + } elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + } elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)\:\\$?([A-Ia-i]?[A-Za-z])?\\$?(\d+)$/u",$token)) { + return $this->_convertRange3d($token); + + // operators (including parentheses) + } elseif (isset($this->ptg[$token])) { + return pack("C", $this->ptg[$token]); + + // match error codes + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') { + return $this->_convertError($token); + + // commented so argument number can be processed correctly. See toReversePolish(). + /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/",$token)) + { + return($this->_convertFunction($token,$this->_func_args)); + }*/ + + // if it's an argument, ignore the token (the argument remains) + } elseif ($token == 'arg') { + return ''; + } + + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown token $token"); + } + + /** + * Convert a number token to ptgInt or ptgNum + * + * @access private + * @param mixed $num an integer or double for conversion to its ptg value + */ + function _convertNumber($num) + { + // Integer in the range 0..2**16-1 + if ((preg_match("/^\d+$/", $num)) and ($num <= 65535)) { + return pack("Cv", $this->ptg['ptgInt'], $num); + } else { // A float + if (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian + $num = strrev($num); + } + return pack("Cd", $this->ptg['ptgNum'], $num); + } + } + + /** + * Convert a string token to ptgStr + * + * @access private + * @param string $string A string for conversion to its ptg value. + * @return mixed the converted token on success + */ + function _convertString($string) + { + // chop away beggining and ending quotes + $string = substr($string, 1, strlen($string) - 2); + if (strlen($string) > 255) { + throw new PHPExcel_Writer_Exception("String is too long"); + } + + return pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string); + } + + /** + * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of + * args that it takes. + * + * @access private + * @param string $token The name of the function for convertion to ptg value. + * @param integer $num_args The number of arguments the function receives. + * @return string The packed ptg for the function + */ + function _convertFunction($token, $num_args) + { + $args = $this->_functions[$token][1]; +// $volatile = $this->_functions[$token][3]; + + // Fixed number of args eg. TIME($i,$j,$k). + if ($args >= 0) { + return pack("Cv", $this->ptg['ptgFuncV'], $this->_functions[$token][0]); + } + // Variable number of args eg. SUM($i,$j,$k, ..). + if ($args == -1) { + return pack("CCv", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]); + } + } + + /** + * Convert an Excel range such as A1:D4 to a ptgRefV. + * + * @access private + * @param string $range An Excel range in the A1:A2 + * @param int $class + */ + function _convertRange2d($range, $class=0) + { + + // TODO: possible class value 0,1,2 check Formula.pm + // Split the range into 2 cell refs + if (preg_match('/^(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)\:(\$)?([A-Ia-i]?[A-Za-z])(\$)?(\d+)$/', $range)) { + list($cell1, $cell2) = explode(':', $range); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown range separator"); + } + + // Convert the cell references + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + + // The ptg value depends on the class of the ptg. + if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea']); + } elseif ($class == 1) { + $ptgArea = pack("C", $this->ptg['ptgAreaV']); + } elseif ($class == 2) { + $ptgArea = pack("C", $this->ptg['ptgAreaA']); + } else { + // TODO: use real error codes + throw new PHPExcel_Writer_Exception("Unknown class $class"); + } + return $ptgArea . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to + * a ptgArea3d. + * + * @access private + * @param string $token An Excel range in the Sheet1!A1:A2 format. + * @return mixed The packed ptgArea3d token on success. + */ + function _convertRange3d($token) + { +// $class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B) + + // Split the ref at the ! symbol + list($ext_ref, $range) = explode('!', $token); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Split the range into 2 cell refs + list($cell1, $cell2) = explode(':', $range); + + // Convert the cell references + if (preg_match("/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\d+)$/", $cell1)) { + list($row1, $col1) = $this->_cellToPackedRowcol($cell1); + list($row2, $col2) = $this->_cellToPackedRowcol($cell2); + } else { // It's a rows range (like 26:27) + list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2); + } + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { + $ptgArea = pack("C", $this->ptg['ptgArea3d']); +// } elseif ($class == 1) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dV']); +// } elseif ($class == 2) { +// $ptgArea = pack("C", $this->ptg['ptgArea3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2; + } + + /** + * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV. + * + * @access private + * @param string $cell An Excel cell reference + * @return string The cell in packed() format with the corresponding ptg + */ + function _convertRef2d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Convert the cell reference + $cell_array = $this->_cellToPackedRowcol($cell); + list($row, $col) = $cell_array; + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRefV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRefA']); +// } else { +// // TODO: use real error codes +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + return $ptgRef.$row.$col; + } + + /** + * Convert an Excel 3d reference such as "Sheet1!A1" or "Sheet1:Sheet2!A1" to a + * ptgRef3d. + * + * @access private + * @param string $cell An Excel cell reference + * @return mixed The packed ptgRef3d token on success. + */ + function _convertRef3d($cell) + { +// $class = 2; // as far as I know, this is magick. + + // Split the ref at the ! symbol + list($ext_ref, $cell) = explode('!', $cell); + + // Convert the external reference part (different for BIFF8) + $ext_ref = $this->_getRefIndex($ext_ref); + + // Convert the cell reference part + list($row, $col) = $this->_cellToPackedRowcol($cell); + + // The ptg value depends on the class of the ptg. +// if ($class == 0) { +// $ptgRef = pack("C", $this->ptg['ptgRef3d']); +// } elseif ($class == 1) { +// $ptgRef = pack("C", $this->ptg['ptgRef3dV']); +// } elseif ($class == 2) { + $ptgRef = pack("C", $this->ptg['ptgRef3dA']); +// } else { +// throw new PHPExcel_Writer_Exception("Unknown class $class"); +// } + + return $ptgRef . $ext_ref. $row . $col; + } + + /** + * Convert an error code to a ptgErr + * + * @access private + * @param string $errorCode The error code for conversion to its ptg value + * @return string The error code ptgErr + */ + function _convertError($errorCode) + { + switch ($errorCode) { + case '#NULL!': return pack("C", 0x00); + case '#DIV/0!': return pack("C", 0x07); + case '#VALUE!': return pack("C", 0x0F); + case '#REF!': return pack("C", 0x17); + case '#NAME?': return pack("C", 0x1D); + case '#NUM!': return pack("C", 0x24); + case '#N/A': return pack("C", 0x2A); + } + return pack("C", 0xFF); + } + + /** + * Convert the sheet name part of an external reference, for example "Sheet1" or + * "Sheet1:Sheet2", to a packed structure. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return string The reference index in packed() format + */ + function _packExtRef($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // References are stored relative to 0xFFFF. + $offset = -1 - $sheet1; + + return pack('vdvv', $offset, 0x00, $sheet1, $sheet2); + } + + /** + * Look up the REF index that corresponds to an external sheet name + * (or range). If it doesn't exist yet add it to the workbook's references + * array. It assumes all sheet names given must exist. + * + * @access private + * @param string $ext_ref The name of the external reference + * @return mixed The reference index in packed() format on success + */ + function _getRefIndex($ext_ref) + { + $ext_ref = preg_replace("/^'/", '', $ext_ref); // Remove leading ' if any. + $ext_ref = preg_replace("/'$/", '', $ext_ref); // Remove trailing ' if any. + $ext_ref = str_replace('\'\'', '\'', $ext_ref); // Replace escaped '' with ' + + // Check if there is a sheet range eg., Sheet1:Sheet2. + if (preg_match("/:/", $ext_ref)) { + list($sheet_name1, $sheet_name2) = explode(':', $ext_ref); + + $sheet1 = $this->_getSheetIndex($sheet_name1); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name1 in formula"); + } + $sheet2 = $this->_getSheetIndex($sheet_name2); + if ($sheet2 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $sheet_name2 in formula"); + } + + // Reverse max and min sheet numbers if necessary + if ($sheet1 > $sheet2) { + list($sheet1, $sheet2) = array($sheet2, $sheet1); + } + } else { // Single sheet name only. + $sheet1 = $this->_getSheetIndex($ext_ref); + if ($sheet1 == -1) { + throw new PHPExcel_Writer_Exception("Unknown sheet name $ext_ref in formula"); + } + $sheet2 = $sheet1; + } + + // assume all references belong to this document + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $sheet1, $sheet2); + $total_references = count($this->_references); + $index = -1; + for ($i = 0; $i < $total_references; ++$i) { + if ($ref == $this->_references[$i]) { + $index = $i; + break; + } + } + // if REF was not found add it to references array + if ($index == -1) { + $this->_references[$total_references] = $ref; + $index = $total_references; + } + + return pack('v', $index); + } + + /** + * Look up the index that corresponds to an external sheet name. The hash of + * sheet names is updated by the addworksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access private + * @param string $sheet_name Sheet name + * @return integer The sheet index, -1 if the sheet was not found + */ + function _getSheetIndex($sheet_name) + { + if (!isset($this->_ext_sheets[$sheet_name])) { + return -1; + } else { + return $this->_ext_sheets[$sheet_name]; + } + } + + /** + * This method is used to update the array of sheet names. It is + * called by the addWorksheet() method of the + * PHPExcel_Writer_Excel5_Workbook class. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet() + * @param string $name The name of the worksheet being added + * @param integer $index The index of the worksheet being added + */ + function setExtSheet($name, $index) + { + $this->_ext_sheets[$name] = $index; + } + + /** + * pack() row and column into the required 3 or 4 byte format. + * + * @access private + * @param string $cell The Excel cell reference to be packed + * @return array Array containing the row and column in packed() format + */ + function _cellToPackedRowcol($cell) + { + $cell = strtoupper($cell); + list($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell); + if ($col >= 256) { + throw new PHPExcel_Writer_Exception("Column in: $cell greater than 255"); + } + if ($row >= 65536) { + throw new PHPExcel_Writer_Exception("Row in: $cell greater than 65536 "); + } + + // Set the high bits to indicate if row or col are relative. + $col |= $col_rel << 14; + $col |= $row_rel << 15; + $col = pack('v', $col); + + $row = pack('v', $row); + + return array($row, $col); + } + + /** + * pack() row range into the required 3 or 4 byte format. + * Just using maximum col/rows, which is probably not the correct solution + * + * @access private + * @param string $range The Excel range to be packed + * @return array Array containing (row1,col1,row2,col2) in packed() format + */ + function _rangeToPackedRange($range) + { + preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match); + // return absolute rows if there is a $ in the ref + $row1_rel = empty($match[1]) ? 1 : 0; + $row1 = $match[2]; + $row2_rel = empty($match[3]) ? 1 : 0; + $row2 = $match[4]; + // Convert 1-index to zero-index + --$row1; + --$row2; + // Trick poor inocent Excel + $col1 = 0; + $col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!) + + // FIXME: this changes for BIFF8 + if (($row1 >= 65536) or ($row2 >= 65536)) { + throw new PHPExcel_Writer_Exception("Row in: $range greater than 65536 "); + } + + // Set the high bits to indicate if rows are relative. + $col1 |= $row1_rel << 15; + $col2 |= $row2_rel << 15; + $col1 = pack('v', $col1); + $col2 = pack('v', $col2); + + $row1 = pack('v', $row1); + $row2 = pack('v', $row2); + + return array($row1, $col1, $row2, $col2); + } + + /** + * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero + * indexed row and column number. Also returns two (0,1) values to indicate + * whether the row or column are relative references. + * + * @access private + * @param string $cell The Excel cell reference in A1 format. + * @return array + */ + function _cellToRowcol($cell) + { + preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match); + // return absolute column if there is a $ in the ref + $col_rel = empty($match[1]) ? 1 : 0; + $col_ref = $match[2]; + $row_rel = empty($match[3]) ? 1 : 0; + $row = $match[4]; + + // Convert base26 column string to a number. + $expn = strlen($col_ref) - 1; + $col = 0; + $col_ref_length = strlen($col_ref); + for ($i = 0; $i < $col_ref_length; ++$i) { + $col += (ord($col_ref{$i}) - 64) * pow(26, $expn); + --$expn; + } + + // Convert 1-index to zero-index + --$row; + --$col; + + return array($row, $col, $row_rel, $col_rel); + } + + /** + * Advance to the next valid token. + * + * @access private + */ + function _advance() + { + $i = $this->_current_char; + $formula_length = strlen($this->_formula); + // eat up white spaces + if ($i < $formula_length) { + while ($this->_formula{$i} == " ") { + ++$i; + } + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } + $token = ''; + } + + while ($i < $formula_length) { + $token .= $this->_formula{$i}; + + if ($i < ($formula_length - 1)) { + $this->_lookahead = $this->_formula{$i+1}; + } else { + $this->_lookahead = ''; + } + + if ($this->_match($token) != '') { + //if ($i < strlen($this->_formula) - 1) { + // $this->_lookahead = $this->_formula{$i+1}; + //} + $this->_current_char = $i + 1; + $this->_current_token = $token; + return 1; + } + + if ($i < ($formula_length - 2)) { + $this->_lookahead = $this->_formula{$i+2}; + } else { // if we run out of characters _lookahead becomes empty + $this->_lookahead = ''; + } + ++$i; + } + //die("Lexical error ".$this->_current_char); + } + + /** + * Checks if it's a valid token. + * + * @access private + * @param mixed $token The token to check. + * @return mixed The checked token or false on failure + */ + function _match($token) + { + switch($token) { + case "+": + case "-": + case "*": + case "/": + case "(": + case ")": + case ",": + case ";": + case ">=": + case "<=": + case "=": + case "<>": + case "^": + case "&": + case "%": + return $token; + break; + case ">": + if ($this->_lookahead == '=') { // it's a GE token + break; + } + return $token; + break; + case "<": + // it's a LE or a NE token + if (($this->_lookahead == '=') or ($this->_lookahead == '>')) { + break; + } + return $token; + break; + default: + // if it's a reference A1 or $A$1 or $A1 or A$1 + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.') and + ($this->_lookahead != '!')) + { + return $token; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead) and + ($this->_lookahead != ':') and ($this->_lookahead != '.')) + { + return $token; + } + // if it's a range A1:A2 or $A$1:$A$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/', $token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2 + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2 + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$token) and + !preg_match("/[0-9]/",$this->_lookahead)) + { + return $token; + } + // If it's a number (check that it's not a sheet name or range) + elseif (is_numeric($token) and + (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and + ($this->_lookahead != '!') and ($this->_lookahead != ':')) + { + return $token; + } + // If it's a string (of maximum 255 characters) + elseif (preg_match("/\"([^\"]|\"\"){0,255}\"/",$token) and $this->_lookahead != '"' and (substr_count($token, '"')%2 == 0)) + { + return $token; + } + // If it's an error code + elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $token) or $token == '#N/A') + { + return $token; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$token) and ($this->_lookahead == "(")) + { + return $token; + } + // It's an argument of some description (e.g. a named range), + // precise nature yet to be determined + elseif(substr($token,-1) == ')') { + return $token; + } + return ''; + } + } + + /** + * The parsing method. It parses a formula. + * + * @access public + * @param string $formula The formula to parse, without the initial equal + * sign (=). + * @return mixed true on success + */ + function parse($formula) + { + $this->_current_char = 0; + $this->_formula = $formula; + $this->_lookahead = isset($formula{1}) ? $formula{1} : ''; + $this->_advance(); + $this->_parse_tree = $this->_condition(); + return true; + } + + /** + * It parses a condition. It assumes the following rule: + * Cond -> Expr [(">" | "<") Expr] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _condition() + { + $result = $this->_expression(); + if ($this->_current_token == "<") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLT', $result, $result2); + } elseif ($this->_current_token == ">") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGT', $result, $result2); + } elseif ($this->_current_token == "<=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgLE', $result, $result2); + } elseif ($this->_current_token == ">=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgGE', $result, $result2); + } elseif ($this->_current_token == "=") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgEQ', $result, $result2); + } elseif ($this->_current_token == "<>") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgNE', $result, $result2); + } elseif ($this->_current_token == "&") { + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgConcat', $result, $result2); + } + return $result; + } + + /** + * It parses a expression. It assumes the following rule: + * Expr -> Term [("+" | "-") Term] + * -> "string" + * -> "-" Term : Negative value + * -> "+" Term : Positive value + * -> Error code + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _expression() + { + // If it's a string return a string node + if (preg_match("/\"([^\"]|\"\"){0,255}\"/", $this->_current_token)) { + $tmp = str_replace('""', '"', $this->_current_token); + if (($tmp == '"') || ($tmp == '')) $tmp = '""'; // Trap for "" that has been used for an empty string + $result = $this->_createTree($tmp, '', ''); + $this->_advance(); + return $result; + // If it's an error code + } elseif (preg_match("/^#[A-Z0\/]{3,5}[!?]{1}$/", $this->_current_token) or $this->_current_token == '#N/A'){ + $result = $this->_createTree($this->_current_token, 'ptgErr', ''); + $this->_advance(); + return $result; + // If it's a negative value + } elseif ($this->_current_token == "-") { + // catch "-" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUminus', $result2, ''); + return $result; + // If it's a positive value + } elseif ($this->_current_token == "+") { + // catch "+" Term + $this->_advance(); + $result2 = $this->_expression(); + $result = $this->_createTree('ptgUplus', $result2, ''); + return $result; + } + $result = $this->_term(); + while (($this->_current_token == "+") or + ($this->_current_token == "-") or + ($this->_current_token == "^")) { + /**/ + if ($this->_current_token == "+") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgAdd', $result, $result2); + } elseif ($this->_current_token == "-") { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgSub', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_term(); + $result = $this->_createTree('ptgPower', $result, $result2); + } + } + return $result; + } + + /** + * This function just introduces a ptgParen element in the tree, so that Excel + * doesn't get confused when working with a parenthesized formula afterwards. + * + * @access private + * @see _fact() + * @return array The parsed ptg'd tree + */ + function _parenthesizedExpression() + { + $result = $this->_createTree('ptgParen', $this->_expression(), ''); + return $result; + } + + /** + * It parses a term. It assumes the following rule: + * Term -> Fact [("*" | "/") Fact] + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _term() + { + $result = $this->_fact(); + while (($this->_current_token == "*") or + ($this->_current_token == "/")) { + /**/ + if ($this->_current_token == "*") { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgMul', $result, $result2); + } else { + $this->_advance(); + $result2 = $this->_fact(); + $result = $this->_createTree('ptgDiv', $result, $result2); + } + } + return $result; + } + + /** + * It parses a factor. It assumes the following rule: + * Fact -> ( Expr ) + * | CellRef + * | CellRange + * | Number + * | Function + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _fact() + { + if ($this->_current_token == "(") { + $this->_advance(); // eat the "(" + $result = $this->_parenthesizedExpression(); + if ($this->_current_token != ")") { + throw new PHPExcel_Writer_Exception("')' token expected."); + } + $this->_advance(); // eat the ")" + return $result; + } + // if it's a reference + if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/u",$this->_current_token)) + { + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // if it's a range A1:B2 or $A$1:$B$2 + elseif (preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token) or + preg_match('/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/',$this->_current_token)) + { + // must be an error? + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2) + elseif (preg_match("/^" . self::REGEX_SHEET_TITLE_UNQUOTED . "(\:" . self::REGEX_SHEET_TITLE_UNQUOTED . ")?\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2) + elseif (preg_match("/^'" . self::REGEX_SHEET_TITLE_QUOTED . "(\:" . self::REGEX_SHEET_TITLE_QUOTED . ")?'\!\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+:\\$?([A-Ia-i]?[A-Za-z])?\\$?[0-9]+$/u",$this->_current_token)) + { + // must be an error? + //$result = $this->_current_token; + $result = $this->_createTree($this->_current_token, '', ''); + $this->_advance(); + return $result; + } + // If it's a number or a percent + elseif (is_numeric($this->_current_token)) + { + if($this->_lookahead == '%'){ + $result = $this->_createTree('ptgPercent', $this->_current_token, ''); + } else { + $result = $this->_createTree($this->_current_token, '', ''); + } + $this->_advance(); + return $result; + } + // if it's a function call + elseif (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/i",$this->_current_token)) + { + $result = $this->_func(); + return $result; + } + throw new PHPExcel_Writer_Exception("Syntax error: ".$this->_current_token. + ", lookahead: ".$this->_lookahead. + ", current char: ".$this->_current_char); + } + + /** + * It parses a function call. It assumes the following rule: + * Func -> ( Expr [,Expr]* ) + * + * @access private + * @return mixed The parsed ptg'd tree on success + */ + function _func() + { + $num_args = 0; // number of arguments received + $function = strtoupper($this->_current_token); + $result = ''; // initialize result + $this->_advance(); + $this->_advance(); // eat the "(" + while ($this->_current_token != ')') { + /**/ + if ($num_args > 0) { + if ($this->_current_token == "," or + $this->_current_token == ";") + { + $this->_advance(); // eat the "," or ";" + } else { + throw new PHPExcel_Writer_Exception("Syntax error: comma expected in ". + "function $function, arg #{$num_args}"); + } + $result2 = $this->_condition(); + $result = $this->_createTree('arg', $result, $result2); + } else { // first argument + $result2 = $this->_condition(); + $result = $this->_createTree('arg', '', $result2); + } + ++$num_args; + } + if (!isset($this->_functions[$function])) { + throw new PHPExcel_Writer_Exception("Function $function() doesn't exist"); + } + $args = $this->_functions[$function][1]; + // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid. + if (($args >= 0) and ($args != $num_args)) { + throw new PHPExcel_Writer_Exception("Incorrect number of arguments in function $function() "); + } + + $result = $this->_createTree($function, $result, $num_args); + $this->_advance(); // eat the ")" + return $result; + } + + /** + * Creates a tree. In fact an array which may have one or two arrays (sub-trees) + * as elements. + * + * @access private + * @param mixed $value The value of this node. + * @param mixed $left The left array (sub-tree) or a final node. + * @param mixed $right The right array (sub-tree) or a final node. + * @return array A tree + */ + function _createTree($value, $left, $right) + { + return array('value' => $value, 'left' => $left, 'right' => $right); + } + + /** + * Builds a string containing the tree in reverse polish notation (What you + * would use in a HP calculator stack). + * The following tree: + * + * + + * / \ + * 2 3 + * + * produces: "23+" + * + * The following tree: + * + * + + * / \ + * 3 * + * / \ + * 6 A1 + * + * produces: "36A1*+" + * + * In fact all operands, functions, references, etc... are written as ptg's + * + * @access public + * @param array $tree The optional tree to convert. + * @return string The tree in reverse polish notation + */ + function toReversePolish($tree = array()) + { + $polish = ""; // the string we are going to return + if (empty($tree)) { // If it's the first call use _parse_tree + $tree = $this->_parse_tree; + } + + if (is_array($tree['left'])) { + $converted_tree = $this->toReversePolish($tree['left']); + $polish .= $converted_tree; + } elseif ($tree['left'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['left']); + $polish .= $converted_tree; + } + if (is_array($tree['right'])) { + $converted_tree = $this->toReversePolish($tree['right']); + $polish .= $converted_tree; + } elseif ($tree['right'] != '') { // It's a final node + $converted_tree = $this->_convert($tree['right']); + $polish .= $converted_tree; + } + // if it's a function convert it here (so we can set it's arguments) + if (preg_match("/^[A-Z0-9\xc0-\xdc\.]+$/",$tree['value']) and + !preg_match('/^([A-Ia-i]?[A-Za-z])(\d+)$/',$tree['value']) and + !preg_match("/^[A-Ia-i]?[A-Za-z](\d+)\.\.[A-Ia-i]?[A-Za-z](\d+)$/",$tree['value']) and + !is_numeric($tree['value']) and + !isset($this->ptg[$tree['value']])) + { + // left subtree for a function is always an array. + if ($tree['left'] != '') { + $left_tree = $this->toReversePolish($tree['left']); + } else { + $left_tree = ''; + } + // add it's left subtree and return. + return $left_tree.$this->_convertFunction($tree['value'], $tree['right']); + } else { + $converted_tree = $this->_convert($tree['value']); + } + $polish .= $converted_tree; + return $polish; + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Workbook.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Workbook.php new file mode 100755 index 0000000..e14bcba --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Workbook.php @@ -0,0 +1,1450 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Workbook (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Workbook + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * The BIFF file size for the workbook. + * @var integer + * @see _calcSheetOffsets() + */ + public $_biffsize; + + /** + * XF Writers + * @var PHPExcel_Writer_Excel5_Xf[] + */ + private $_xfWriters = array(); + + /** + * Array containing the colour palette + * @var array + */ + public $_palette; + + /** + * The codepage indicates the text encoding used for strings + * @var integer + */ + public $_codepage; + + /** + * The country code used for localization + * @var integer + */ + public $_country_code; + + /** + * Workbook + * @var PHPExcel + */ + private $_phpExcel; + + /** + * Fonts writers + * + * @var PHPExcel_Writer_Excel5_Font[] + */ + private $_fontWriters = array(); + + /** + * Added fonts. Maps from font's hash => index in workbook + * + * @var array + */ + private $_addedFonts = array(); + + /** + * Shared number formats + * + * @var array + */ + private $_numberFormats = array(); + + /** + * Added number formats. Maps from numberFormat's hash => index in workbook + * + * @var array + */ + private $_addedNumberFormats = array(); + + /** + * Sizes of the binary worksheet streams + * + * @var array + */ + private $_worksheetSizes = array(); + + /** + * Offsets of the binary worksheet streams relative to the start of the global workbook stream + * + * @var array + */ + private $_worksheetOffsets = array(); + + /** + * Total number of shared strings in workbook + * + * @var int + */ + private $_str_total; + + /** + * Number of unique shared strings in workbook + * + * @var int + */ + private $_str_unique; + + /** + * Array of unique shared strings in workbook + * + * @var array + */ + private $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Escher object corresponding to MSODRAWINGGROUP + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + + /** + * Class constructor + * + * @param PHPExcel $phpExcel The Workbook + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + */ + public function __construct(PHPExcel $phpExcel = null, + &$str_total, &$str_unique, &$str_table, &$colors, + $parser ) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + $this->_parser = $parser; + $this->_biffsize = 0; + $this->_palette = array(); + $this->_country_code = -1; + + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_setPaletteXl97(); + + $this->_phpExcel = $phpExcel; + + // set BIFFwriter limit for CONTINUE records + // $this->_limit = 8224; + $this->_codepage = 0x04B0; + + // Add empty sheets and Build color cache + $countSheets = $phpExcel->getSheetCount(); + for ($i = 0; $i < $countSheets; ++$i) { + $phpSheet = $phpExcel->getSheet($i); + + $this->_parser->setExtSheet($phpSheet->getTitle(), $i); // Register worksheet name with parser + + $supbook_index = 0x00; + $ref = pack('vvv', $supbook_index, $i, $i); + $this->_parser->_references[] = $ref; // Register reference with parser + + // Sheet tab colors? + if ($phpSheet->isTabColorSet()) { + $this->_addColor($phpSheet->getTabColor()->getRGB()); + } + } + + } + + /** + * Add a new XF writer + * + * @param PHPExcel_Style + * @param boolean Is it a style XF? + * @return int Index to XF record + */ + public function addXfWriter($style, $isStyleXf = false) + { + $xfWriter = new PHPExcel_Writer_Excel5_Xf($style); + $xfWriter->setIsStyleXf($isStyleXf); + + // Add the font if not already added + $fontIndex = $this->_addFont($style->getFont()); + + // Assign the font index to the xf record + $xfWriter->setFontIndex($fontIndex); + + // Background colors, best to treat these after the font so black will come after white in custom palette + $xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB())); + $xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB())); + $xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB())); + $xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB())); + $xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB())); + $xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB())); + $xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB())); + + // Add the number format if it is not a built-in one and not already added + if ($style->getNumberFormat()->getBuiltInFormatCode() === false) { + $numberFormatHashCode = $style->getNumberFormat()->getHashCode(); + + if (isset($this->_addedNumberFormats[$numberFormatHashCode])) { + $numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode]; + } else { + $numberFormatIndex = 164 + count($this->_numberFormats); + $this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat(); + $this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex; + } + } else { + $numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode(); + } + + // Assign the number format index to xf record + $xfWriter->setNumberFormatIndex($numberFormatIndex); + + $this->_xfWriters[] = $xfWriter; + + $xfIndex = count($this->_xfWriters) - 1; + return $xfIndex; + } + + /** + * Add a font to added fonts + * + * @param PHPExcel_Style_Font $font + * @return int Index to FONT record + */ + public function _addFont(PHPExcel_Style_Font $font) + { + $fontHashCode = $font->getHashCode(); + if(isset($this->_addedFonts[$fontHashCode])){ + $fontIndex = $this->_addedFonts[$fontHashCode]; + } else { + $countFonts = count($this->_fontWriters); + $fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1; + + $fontWriter = new PHPExcel_Writer_Excel5_Font($font); + $fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB())); + $this->_fontWriters[] = $fontWriter; + + $this->_addedFonts[$fontHashCode] = $fontIndex; + } + return $fontIndex; + } + + /** + * Alter color palette adding a custom color + * + * @param string $rgb E.g. 'FF00AA' + * @return int Color index + */ + private function _addColor($rgb) { + if (!isset($this->_colors[$rgb])) { + if (count($this->_colors) < 57) { + // then we add a custom color altering the palette + $colorIndex = 8 + count($this->_colors); + $this->_palette[$colorIndex] = + array( + hexdec(substr($rgb, 0, 2)), + hexdec(substr($rgb, 2, 2)), + hexdec(substr($rgb, 4)), + 0 + ); + $this->_colors[$rgb] = $colorIndex; + } else { + // no room for more custom colors, just map to black + $colorIndex = 0; + } + } else { + // fetch already added custom color + $colorIndex = $this->_colors[$rgb]; + } + + return $colorIndex; + } + + /** + * Sets the colour palette to the Excel 97+ default. + * + * @access private + */ + function _setPaletteXl97() + { + $this->_palette = array( + 0x08 => array(0x00, 0x00, 0x00, 0x00), + 0x09 => array(0xff, 0xff, 0xff, 0x00), + 0x0A => array(0xff, 0x00, 0x00, 0x00), + 0x0B => array(0x00, 0xff, 0x00, 0x00), + 0x0C => array(0x00, 0x00, 0xff, 0x00), + 0x0D => array(0xff, 0xff, 0x00, 0x00), + 0x0E => array(0xff, 0x00, 0xff, 0x00), + 0x0F => array(0x00, 0xff, 0xff, 0x00), + 0x10 => array(0x80, 0x00, 0x00, 0x00), + 0x11 => array(0x00, 0x80, 0x00, 0x00), + 0x12 => array(0x00, 0x00, 0x80, 0x00), + 0x13 => array(0x80, 0x80, 0x00, 0x00), + 0x14 => array(0x80, 0x00, 0x80, 0x00), + 0x15 => array(0x00, 0x80, 0x80, 0x00), + 0x16 => array(0xc0, 0xc0, 0xc0, 0x00), + 0x17 => array(0x80, 0x80, 0x80, 0x00), + 0x18 => array(0x99, 0x99, 0xff, 0x00), + 0x19 => array(0x99, 0x33, 0x66, 0x00), + 0x1A => array(0xff, 0xff, 0xcc, 0x00), + 0x1B => array(0xcc, 0xff, 0xff, 0x00), + 0x1C => array(0x66, 0x00, 0x66, 0x00), + 0x1D => array(0xff, 0x80, 0x80, 0x00), + 0x1E => array(0x00, 0x66, 0xcc, 0x00), + 0x1F => array(0xcc, 0xcc, 0xff, 0x00), + 0x20 => array(0x00, 0x00, 0x80, 0x00), + 0x21 => array(0xff, 0x00, 0xff, 0x00), + 0x22 => array(0xff, 0xff, 0x00, 0x00), + 0x23 => array(0x00, 0xff, 0xff, 0x00), + 0x24 => array(0x80, 0x00, 0x80, 0x00), + 0x25 => array(0x80, 0x00, 0x00, 0x00), + 0x26 => array(0x00, 0x80, 0x80, 0x00), + 0x27 => array(0x00, 0x00, 0xff, 0x00), + 0x28 => array(0x00, 0xcc, 0xff, 0x00), + 0x29 => array(0xcc, 0xff, 0xff, 0x00), + 0x2A => array(0xcc, 0xff, 0xcc, 0x00), + 0x2B => array(0xff, 0xff, 0x99, 0x00), + 0x2C => array(0x99, 0xcc, 0xff, 0x00), + 0x2D => array(0xff, 0x99, 0xcc, 0x00), + 0x2E => array(0xcc, 0x99, 0xff, 0x00), + 0x2F => array(0xff, 0xcc, 0x99, 0x00), + 0x30 => array(0x33, 0x66, 0xff, 0x00), + 0x31 => array(0x33, 0xcc, 0xcc, 0x00), + 0x32 => array(0x99, 0xcc, 0x00, 0x00), + 0x33 => array(0xff, 0xcc, 0x00, 0x00), + 0x34 => array(0xff, 0x99, 0x00, 0x00), + 0x35 => array(0xff, 0x66, 0x00, 0x00), + 0x36 => array(0x66, 0x66, 0x99, 0x00), + 0x37 => array(0x96, 0x96, 0x96, 0x00), + 0x38 => array(0x00, 0x33, 0x66, 0x00), + 0x39 => array(0x33, 0x99, 0x66, 0x00), + 0x3A => array(0x00, 0x33, 0x00, 0x00), + 0x3B => array(0x33, 0x33, 0x00, 0x00), + 0x3C => array(0x99, 0x33, 0x00, 0x00), + 0x3D => array(0x99, 0x33, 0x66, 0x00), + 0x3E => array(0x33, 0x33, 0x99, 0x00), + 0x3F => array(0x33, 0x33, 0x33, 0x00), + ); + } + + /** + * Assemble worksheets into a workbook and send the BIFF data to an OLE + * storage. + * + * @param array $pWorksheetSizes The sizes in bytes of the binary worksheet streams + * @return string Binary data for workbook stream + */ + public function writeWorkbook($pWorksheetSizes = null) + { + $this->_worksheetSizes = $pWorksheetSizes; + + // Calculate the number of selected worksheet tabs and call the finalization + // methods for each worksheet + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Add part 1 of the Workbook globals, what goes before the SHEET records + $this->_storeBof(0x0005); + $this->_writeCodepage(); + $this->_writeWindow1(); + + $this->_writeDatemode(); + $this->_writeAllFonts(); + $this->_writeAllNumFormats(); + $this->_writeAllXfs(); + $this->_writeAllStyles(); + $this->_writePalette(); + + // Prepare part 3 of the workbook global stream, what goes after the SHEET records + $part3 = ''; + if ($this->_country_code != -1) { + $part3 .= $this->_writeCountry(); + } + $part3 .= $this->_writeRecalcId(); + + $part3 .= $this->_writeSupbookInternal(); + /* TODO: store external SUPBOOK records and XCT and CRN records + in case of external references for BIFF8 */ + $part3 .= $this->_writeExternsheetBiff8(); + $part3 .= $this->_writeAllDefinedNamesBiff8(); + $part3 .= $this->_writeMsoDrawingGroup(); + $part3 .= $this->_writeSharedStringsTable(); + + $part3 .= $this->writeEof(); + + // Add part 2 of the Workbook globals, the SHEET records + $this->_calcSheetOffsets(); + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]); + } + + // Add part 3 of the Workbook globals + $this->_data .= $part3; + + return $this->_data; + } + + /** + * Calculate offsets for Worksheet BOF records. + * + * @access private + */ + function _calcSheetOffsets() + { + $boundsheet_length = 10; // fixed length for a BOUNDSHEET record + + // size of Workbook globals part 1 + 3 + $offset = $this->_datasize; + + // add size of Workbook globals part 2, the length of the SHEET records + $total_worksheets = count($this->_phpExcel->getAllSheets()); + foreach ($this->_phpExcel->getWorksheetIterator() as $sheet) { + $offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle())); + } + + // add the sizes of each of the Sheet substreams, respectively + for ($i = 0; $i < $total_worksheets; ++$i) { + $this->_worksheetOffsets[$i] = $offset; + $offset += $this->_worksheetSizes[$i]; + } + $this->_biffsize = $offset; + } + + /** + * Store the Excel FONT records. + */ + private function _writeAllFonts() + { + foreach ($this->_fontWriters as $fontWriter) { + $this->_append($fontWriter->writeFont()); + } + } + + /** + * Store user defined numerical formats i.e. FORMAT records + */ + private function _writeAllNumFormats() + { + foreach ($this->_numberFormats as $numberFormatIndex => $numberFormat) { + $this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex); + } + } + + /** + * Write all XF records. + */ + private function _writeAllXfs() + { + foreach ($this->_xfWriters as $xfWriter) { + $this->_append($xfWriter->writeXf()); + } + } + + /** + * Write all STYLE records. + */ + private function _writeAllStyles() + { + $this->_writeStyle(); + } + + /** + * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for + * the NAME records. + */ + private function _writeExterns() + { + $countSheets = $this->_phpExcel->getSheetCount(); + // Create EXTERNCOUNT with number of worksheets + $this->_writeExterncount($countSheets); + + // Create EXTERNSHEET for each worksheet + for ($i = 0; $i < $countSheets; ++$i) { + $this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle()); + } + } + + /** + * Write the NAME record to define the print area and the repeat rows and cols. + */ + private function _writeNames() + { + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // Create the print area NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // Write a Name record if the print area has been defined + if ($sheetSetup->isPrintAreaSet()) { + // Print area + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $printArea = $printArea[0]; + $printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]); + $printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]); + + $print_rowmin = $printArea[0][1] - 1; + $print_rowmax = $printArea[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1; + + $this->_writeNameShort( + $i, // sheet index + 0x06, // NAME type + $print_rowmin, + $print_rowmax, + $print_colmin, + $print_colmax + ); + } + } + + // Create the print title NAME records + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + $this->_writeNameLong( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + $this->_writeNameShort( + $i, // sheet index + 0x07, // NAME type + $rowmin, + $rowmax, + $colmin, + $colmax + ); + } + } + } + + /** + * Writes all the DEFINEDNAME records (BIFF8). + * So far this is only used for repeating rows/columns (print titles) and print areas + */ + private function _writeAllDefinedNamesBiff8() + { + $chunk = ''; + + // Named ranges + if (count($this->_phpExcel->getNamedRanges()) > 0) { + // Loop named ranges + $namedRanges = $this->_phpExcel->getNamedRanges(); + foreach ($namedRanges as $namedRange) { + + // Create absolute coordinate + $range = PHPExcel_Cell::splitRange($namedRange->getRange()); + for ($i = 0; $i < count($range); $i++) { + $range[$i][0] = '\'' . str_replace("'", "''", $namedRange->getWorksheet()->getTitle()) . '\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]); + if (isset($range[$i][1])) { + $range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]); + } + } + $range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2 + + // parse formula + try { + $error = $this->_parser->parse($range); + $formulaData = $this->_parser->toReversePolish(); + + // make sure tRef3d is of type tRef3dR (0x3A) + if (isset($formulaData{0}) and ($formulaData{0} == "\x7A" or $formulaData{0} == "\x5A")) { + $formulaData = "\x3A" . substr($formulaData, 1); + } + + if ($namedRange->getLocalOnly()) { + // local scope + $scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1; + } else { + // global scope + $scope = 0; + } + $chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false)); + + } catch(PHPExcel_Exception $e) { + // do nothing + } + } + } + + // total number of sheets + $total_worksheets = $this->_phpExcel->getSheetCount(); + + // write the print titles (repeating rows, columns), if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + // simultaneous repeatColumns repeatRows + if ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + + // construct formula data manually + $formulaData = pack('Cv', 0x29, 0x17); // tMemFunc + $formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d + $formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d + $formulaData .= pack('C', 0x10); // tList + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + + // (exclusive) either repeatColumns or repeatRows + } else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) { + + // Columns to repeat + if ($sheetSetup->isColumnsToRepeatAtLeftSet()) { + $repeat = $sheetSetup->getColumnsToRepeatAtLeft(); + $colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1; + $colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1; + } else { + $colmin = 0; + $colmax = 255; + } + // Rows to repeat + if ($sheetSetup->isRowsToRepeatAtTopSet()) { + $repeat = $sheetSetup->getRowsToRepeatAtTop(); + $rowmin = $repeat[0] - 1; + $rowmax = $repeat[1] - 1; + } else { + $rowmin = 0; + $rowmax = 65535; + } + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax); + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true)); + } + } + + // write the print areas, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup(); + if ($sheetSetup->isPrintAreaSet()) { + // Print area, e.g. A3:J6,H1:X20 + $printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea()); + $countPrintArea = count($printArea); + + $formulaData = ''; + for ($j = 0; $j < $countPrintArea; ++$j) { + $printAreaRect = $printArea[$j]; // e.g. A3:J6 + $printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]); + $printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]); + + $print_rowmin = $printAreaRect[0][1] - 1; + $print_rowmax = $printAreaRect[1][1] - 1; + $print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1; + $print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1; + + // construct formula data manually because parser does not recognize absolute 3d cell references + $formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax); + + if ($j > 0) { + $formulaData .= pack('C', 0x10); // list operator token ',' + } + } + + // store the DEFINEDNAME record + $chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true)); + } + } + + // write autofilters, if any + for ($i = 0; $i < $total_worksheets; ++$i) { + $sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter(); + $autoFilterRange = $sheetAutoFilter->getRange(); + if(!empty($autoFilterRange)) { + $rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange); + + //Autofilter built in name + $name = pack('C', 0x0D); + + $chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true)); + } + } + + return $chunk; + } + + /** + * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data + * + * @param string $name The name in UTF-8 + * @param string $formulaData The binary formula data + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param boolean $isBuiltIn Built-in name? + * @return string Complete binary record data + */ + private function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false) + { + $record = 0x0018; + + // option flags + $options = $isBuiltIn ? 0x20 : 0x00; + + // length of the name, character count + $nlen = PHPExcel_Shared_String::CountCharacters($name); + + // name with stripped length field + $name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2); + + // size of the formula (in bytes) + $sz = strlen($formulaData); + + // combine the parts + $data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0) + . $name . $formulaData; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Write a short NAME record + * + * @param string $name + * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global + * @param integer[][] $rangeBounds range boundaries + * @param boolean $isHidden + * @return string Complete binary record data + * */ + private function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){ + $record = 0x0018; + + // option flags + $options = ($isHidden ? 0x21 : 0x00); + + $extra = pack('Cvvvvv', + 0x3B, + $sheetIndex - 1, + $rangeBounds[0][1] - 1, + $rangeBounds[1][1] - 1, + $rangeBounds[0][0] - 1, + $rangeBounds[1][0] - 1); + + // size of the formula (in bytes) + $sz = strlen($extra); + + // combine the parts + $data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0) + . $name . $extra; + $length = strlen($data); + + $header = pack('vv', $record, $length); + + return $header . $data; + } + + /** + * Stores the CODEPAGE biff record. + */ + private function _writeCodepage() + { + $record = 0x0042; // Record identifier + $length = 0x0002; // Number of bytes to follow + $cv = $this->_codepage; // The code page + + $header = pack('vv', $record, $length); + $data = pack('v', $cv); + + $this->_append($header . $data); + } + + /** + * Write Excel BIFF WINDOW1 record. + */ + private function _writeWindow1() + { + $record = 0x003D; // Record identifier + $length = 0x0012; // Number of bytes to follow + + $xWn = 0x0000; // Horizontal position of window + $yWn = 0x0000; // Vertical position of window + $dxWn = 0x25BC; // Width of window + $dyWn = 0x1572; // Height of window + + $grbit = 0x0038; // Option flags + + // not supported by PHPExcel, so there is only one selected sheet, the active + $ctabsel = 1; // Number of workbook tabs selected + + $wTabRatio = 0x0258; // Tab to scrollbar ratio + + // not supported by PHPExcel, set to 0 + $itabFirst = 0; // 1st displayed worksheet + $itabCur = $this->_phpExcel->getActiveSheetIndex(); // Active worksheet + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvvv", $xWn, $yWn, $dxWn, $dyWn, + $grbit, + $itabCur, $itabFirst, + $ctabsel, $wTabRatio); + $this->_append($header . $data); + } + + /** + * Writes Excel BIFF BOUNDSHEET record. + * + * @param PHPExcel_Worksheet $sheet Worksheet name + * @param integer $offset Location of worksheet BOF + */ + private function _writeBoundsheet($sheet, $offset) + { + $sheetname = $sheet->getTitle(); + $record = 0x0085; // Record identifier + + // sheet state + switch ($sheet->getSheetState()) { + case PHPExcel_Worksheet::SHEETSTATE_VISIBLE: $ss = 0x00; break; + case PHPExcel_Worksheet::SHEETSTATE_HIDDEN: $ss = 0x01; break; + case PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN: $ss = 0x02; break; + default: $ss = 0x00; break; + } + + // sheet type + $st = 0x00; + + $grbit = 0x0000; // Visibility and sheet type + + $data = pack("VCC", $offset, $ss, $st); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname); + + $length = strlen($data); + $header = pack("vv", $record, $length); + $this->_append($header . $data); + } + + /** + * Write Internal SUPBOOK record + */ + private function _writeSupbookInternal() + { + $record = 0x01AE; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpExcel->getSheetCount(), 0x0401); + return $this->writeData($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. + * + */ + private function _writeExternsheetBiff8() + { + $total_references = count($this->_parser->_references); + $record = 0x0017; // Record identifier + $length = 2 + 6 * $total_references; // Number of bytes to follow + + $supbook_index = 0; // FIXME: only using internal SUPBOOK record + $header = pack("vv", $record, $length); + $data = pack('v', $total_references); + for ($i = 0; $i < $total_references; ++$i) { + $data .= $this->_parser->_references[$i]; + } + return $this->writeData($header . $data); + } + + /** + * Write Excel BIFF STYLE records. + */ + private function _writeStyle() + { + $record = 0x0293; // Record identifier + $length = 0x0004; // Bytes to follow + + $ixfe = 0x8000; // Index to cell style XF + $BuiltIn = 0x00; // Built-in style + $iLevel = 0xff; // Outline style level + + $header = pack("vv", $record, $length); + $data = pack("vCC", $ixfe, $BuiltIn, $iLevel); + $this->_append($header . $data); + } + + /** + * Writes Excel FORMAT record for non "built-in" numerical formats. + * + * @param string $format Custom format string + * @param integer $ifmt Format index code + */ + private function _writeNumFormat($format, $ifmt) + { + $record = 0x041E; // Record identifier + + $numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format); + $length = 2 + strlen($numberFormatString); // Number of bytes to follow + + + $header = pack("vv", $record, $length); + $data = pack("v", $ifmt) . $numberFormatString; + $this->_append($header . $data); + } + + /** + * Write DATEMODE record to indicate the date system in use (1904 or 1900). + */ + private function _writeDatemode() + { + $record = 0x0022; // Record identifier + $length = 0x0002; // Bytes to follow + + $f1904 = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ? + 1 : 0; // Flag for 1904 date system + + $header = pack("vv", $record, $length); + $data = pack("v", $f1904); + $this->_append($header . $data); + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in the workbook. + * + * Excel only stores references to external sheets that are used in NAME. + * The workbook NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param integer $cxals Number of external references + */ + private function _writeExterncount($cxals) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cxals); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. NAME record is required to define the print area and the repeat + * rows and columns. + * + * A similar method is used in Worksheet.php for a slightly different purpose. + * + * @param string $sheetname Worksheet name + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + $length = 0x02 + strlen($sheetname); // Number of bytes to follow + + $cch = strlen($sheetname); // Length of sheet name + $rgch = 0x03; // Filename encoding + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Store the NAME record in the short format that is used for storing the print + * area, repeat rows only and repeat columns only. + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x0024; // Number of bytes to follow + + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x0015; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8005; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + $this->_append($header . $data); + } + + /** + * Store the NAME record in the long format that is used for storing the repeat + * rows and columns when both are specified. This shares a lot of code with + * _writeNameShort() but we use a separate method to keep the code clean. + * Code abstraction for reuse can be carried too far, and I should know. ;-) + * + * @param integer $index Sheet index + * @param integer $type Built-in name type + * @param integer $rowmin Start row + * @param integer $rowmax End row + * @param integer $colmin Start colum + * @param integer $colmax End column + */ + private function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax) + { + $record = 0x0018; // Record identifier + $length = 0x003d; // Number of bytes to follow + $grbit = 0x0020; // Option flags + $chKey = 0x00; // Keyboard shortcut + $cch = 0x01; // Length of text name + $cce = 0x002e; // Length of text definition + $ixals = $index + 1; // Sheet index + $itab = $ixals; // Equal to ixals + $cchCustMenu = 0x00; // Length of cust menu text + $cchDescription = 0x00; // Length of description text + $cchHelptopic = 0x00; // Length of help topic text + $cchStatustext = 0x00; // Length of status bar text + $rgch = $type; // Built-in name type + + $unknown01 = 0x29; + $unknown02 = 0x002b; + $unknown03 = 0x3b; + $unknown04 = 0xffff-$index; + $unknown05 = 0x0000; + $unknown06 = 0x0000; + $unknown07 = 0x1087; + $unknown08 = 0x8008; + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $data .= pack("C", $chKey); + $data .= pack("C", $cch); + $data .= pack("v", $cce); + $data .= pack("v", $ixals); + $data .= pack("v", $itab); + $data .= pack("C", $cchCustMenu); + $data .= pack("C", $cchDescription); + $data .= pack("C", $cchHelptopic); + $data .= pack("C", $cchStatustext); + $data .= pack("C", $rgch); + $data .= pack("C", $unknown01); + $data .= pack("v", $unknown02); + // Column definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", 0x0000); + $data .= pack("v", 0x3fff); + $data .= pack("C", $colmin); + $data .= pack("C", $colmax); + // Row definition + $data .= pack("C", $unknown03); + $data .= pack("v", $unknown04); + $data .= pack("v", $unknown05); + $data .= pack("v", $unknown06); + $data .= pack("v", $unknown07); + $data .= pack("v", $unknown08); + $data .= pack("v", $index); + $data .= pack("v", $index); + $data .= pack("v", $rowmin); + $data .= pack("v", $rowmax); + $data .= pack("C", 0x00); + $data .= pack("C", 0xff); + // End of data + $data .= pack("C", 0x10); + $this->_append($header . $data); + } + + /** + * Stores the COUNTRY record for localization + * + * @return string + */ + private function _writeCountry() + { + $record = 0x008C; // Record identifier + $length = 4; // Number of bytes to follow + + $header = pack('vv', $record, $length); + /* using the same country code always for simplicity */ + $data = pack('vv', $this->_country_code, $this->_country_code); + //$this->_append($header . $data); + return $this->writeData($header . $data); + } + + /** + * Write the RECALCID record + * + * @return string + */ + private function _writeRecalcId() + { + $record = 0x01C1; // Record identifier + $length = 8; // Number of bytes to follow + + $header = pack('vv', $record, $length); + + // by inspection of real Excel files, MS Office Excel 2007 writes this + $data = pack('VV', 0x000001C1, 0x00001E667); + + return $this->writeData($header . $data); + } + + /** + * Stores the PALETTE biff record. + */ + private function _writePalette() + { + $aref = $this->_palette; + + $record = 0x0092; // Record identifier + $length = 2 + 4 * count($aref); // Number of bytes to follow + $ccv = count($aref); // Number of RGB values to follow + $data = ''; // The RGB data + + // Pack the RGB data + foreach ($aref as $color) { + foreach ($color as $byte) { + $data .= pack("C",$byte); + } + } + + $header = pack("vvv", $record, $length, $ccv); + $this->_append($header . $data); + } + + /** + * Handling of the SST continue blocks is complicated by the need to include an + * additional continuation byte depending on whether the string is split between + * blocks or whether it starts at the beginning of the block. (There are also + * additional complications that will arise later when/if Rich Strings are + * supported). + * + * The Excel documentation says that the SST record should be followed by an + * EXTSST record. The EXTSST record is a hash table that is used to optimise + * access to SST. However, despite the documentation it doesn't seem to be + * required so we will ignore it. + * + * @return string Binary data + */ + private function _writeSharedStringsTable() + { + // maximum size of record data (excluding record header) + $continue_limit = 8224; + + // initialize array of record data blocks + $recordDatas = array(); + + // start SST record data block with total number of strings, total number of unique strings + $recordData = pack("VV", $this->_str_total, $this->_str_unique); + + // loop through all (unique) strings in shared strings table + foreach (array_keys($this->_str_table) as $string) { + + // here $string is a BIFF8 encoded string + + // length = character count + $headerinfo = unpack("vlength/Cencoding", $string); + + // currently, this is always 1 = uncompressed + $encoding = $headerinfo["encoding"]; + + // initialize finished writing current $string + $finished = false; + + while ($finished === false) { + + // normally, there will be only one cycle, but if string cannot immediately be written as is + // there will be need for more than one cylcle, if string longer than one record data block, there + // may be need for even more cycles + + if (strlen($recordData) + strlen($string) <= $continue_limit) { + // then we can write the string (or remainder of string) without any problems + $recordData .= $string; + + if (strlen($recordData) + strlen($string) == $continue_limit) { + // we close the record data block, and initialize a new one + $recordDatas[] = $recordData; + $recordData = ''; + } + + // we are finished writing this string + $finished = true; + } else { + // special treatment writing the string (or remainder of the string) + // If the string is very long it may need to be written in more than one CONTINUE record. + + // check how many bytes more there is room for in the current record + $space_remaining = $continue_limit - strlen($recordData); + + // minimum space needed + // uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character + // compressed: 2 byte string length length field + 1 byte option flags + 1 byte character + $min_space_needed = ($encoding == 1) ? 5 : 4; + + // We have two cases + // 1. space remaining is less than minimum space needed + // here we must waste the space remaining and move to next record data block + // 2. space remaining is greater than or equal to minimum space needed + // here we write as much as we can in the current block, then move to next record data block + + // 1. space remaining is less than minimum space needed + if ($space_remaining < $min_space_needed) { + // we close the block, store the block data + $recordDatas[] = $recordData; + + // and start new record data block where we start writing the string + $recordData = ''; + + // 2. space remaining is greater than or equal to minimum space needed + } else { + // initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below + $effective_space_remaining = $space_remaining; + + // for uncompressed strings, sometimes effective space remaining is reduced by 1 + if ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) { + --$effective_space_remaining; + } + + // one block fininshed, store the block data + $recordData .= substr($string, 0, $effective_space_remaining); + + $string = substr($string, $effective_space_remaining); // for next cycle in while loop + $recordDatas[] = $recordData; + + // start new record data block with the repeated option flags + $recordData = pack('C', $encoding); + } + } + } + } + + // Store the last record data block unless it is empty + // if there was no need for any continue records, this will be the for SST record data block itself + if (strlen($recordData) > 0) { + $recordDatas[] = $recordData; + } + + // combine into one chunk with all the blocks SST, CONTINUE,... + $chunk = ''; + foreach ($recordDatas as $i => $recordData) { + // first block should have the SST record header, remaing should have CONTINUE header + $record = ($i == 0) ? 0x00FC : 0x003C; + + $header = pack("vv", $record, strlen($recordData)); + $data = $header . $recordData; + + $chunk .= $this->writeData($data); + } + + return $chunk; + } + + /** + * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records. + */ + private function _writeMsoDrawingGroup() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + + $record = 0x00EB; + $length = strlen($data); + $header = pack("vv", $record, $length); + + return $this->writeData($header . $data); + + } else { + return ''; + } + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php new file mode 100755 index 0000000..55da26f --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Worksheet.php @@ -0,0 +1,3681 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Worksheet (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Worksheet + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter +{ + /** + * Formula parser + * + * @var PHPExcel_Writer_Excel5_Parser + */ + private $_parser; + + /** + * Maximum number of characters for a string (LABEL record in BIFF5) + * @var integer + */ + public $_xls_strmax; + + /** + * Array containing format information for columns + * @var array + */ + public $_colinfo; + + /** + * Array containing the selected area for the worksheet + * @var array + */ + public $_selection; + + /** + * The active pane for the worksheet + * @var integer + */ + public $_active_pane; + + /** + * Whether to use outline. + * @var integer + */ + public $_outline_on; + + /** + * Auto outline styles. + * @var bool + */ + public $_outline_style; + + /** + * Whether to have outline summary below. + * @var bool + */ + public $_outline_below; + + /** + * Whether to have outline summary at the right. + * @var bool + */ + public $_outline_right; + + /** + * Reference to the total number of strings in the workbook + * @var integer + */ + public $_str_total; + + /** + * Reference to the number of unique strings in the workbook + * @var integer + */ + public $_str_unique; + + /** + * Reference to the array containing all the unique strings in the workbook + * @var array + */ + public $_str_table; + + /** + * Color cache + */ + private $_colors; + + /** + * Index of first used row (at least 0) + * @var int + */ + private $_firstRowIndex; + + /** + * Index of last used row. (no used rows means -1) + * @var int + */ + private $_lastRowIndex; + + /** + * Index of first used column (at least 0) + * @var int + */ + private $_firstColumnIndex; + + /** + * Index of last used column (no used columns means -1) + * @var int + */ + private $_lastColumnIndex; + + /** + * Sheet object + * @var PHPExcel_Worksheet + */ + public $_phpSheet; + + /** + * Count cell style Xfs + * + * @var int + */ + private $_countCellStyleXfs; + + /** + * Escher object corresponding to MSODRAWING + * + * @var PHPExcel_Shared_Escher + */ + private $_escher; + + /** + * Array of font hashes associated to FONT records index + * + * @var array + */ + public $_fntHashIndex; + + /** + * Constructor + * + * @param int &$str_total Total number of strings + * @param int &$str_unique Total number of unique strings + * @param array &$str_table String Table + * @param array &$colors Colour Table + * @param mixed $parser The formula parser created for the Workbook + * @param boolean $preCalculateFormulas Flag indicating whether formulas should be calculated or just written + * @param string $phpSheet The worksheet to write + * @param PHPExcel_Worksheet $phpSheet + */ + public function __construct(&$str_total, &$str_unique, &$str_table, &$colors, + $parser, $preCalculateFormulas, $phpSheet) + { + // It needs to call its parent's constructor explicitly + parent::__construct(); + + // change BIFFwriter limit for CONTINUE records +// $this->_limit = 8224; + + + $this->_preCalculateFormulas = $preCalculateFormulas; + $this->_str_total = &$str_total; + $this->_str_unique = &$str_unique; + $this->_str_table = &$str_table; + $this->_colors = &$colors; + $this->_parser = $parser; + + $this->_phpSheet = $phpSheet; + + //$this->ext_sheets = array(); + //$this->offset = 0; + $this->_xls_strmax = 255; + $this->_colinfo = array(); + $this->_selection = array(0,0,0,0); + $this->_active_pane = 3; + + $this->_print_headers = 0; + + $this->_outline_style = 0; + $this->_outline_below = 1; + $this->_outline_right = 1; + $this->_outline_on = 1; + + $this->_fntHashIndex = array(); + + // calculate values for DIMENSIONS record + $minR = 1; + $minC = 'A'; + + $maxR = $this->_phpSheet->getHighestRow(); + $maxC = $this->_phpSheet->getHighestColumn(); + + // Determine lowest and highest column and row +// $this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR; + $this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ; + + $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString($minC); + $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString($maxC); + +// if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; + if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; + + $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); + } + + /** + * Add data to the beginning of the workbook (note the reverse order) + * and to the end of the workbook. + * + * @access public + * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook() + */ + function close() + { + $_phpSheet = $this->_phpSheet; + + $num_sheets = $_phpSheet->getParent()->getSheetCount(); + + // Write BOF record + $this->_storeBof(0x0010); + + // Write PRINTHEADERS + $this->_writePrintHeaders(); + + // Write PRINTGRIDLINES + $this->_writePrintGridlines(); + + // Write GRIDSET + $this->_writeGridset(); + + // Calculate column widths + $_phpSheet->calculateColumnWidths(); + + // Column dimensions + if (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) { + $defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont()); + } + + $columnDimensions = $_phpSheet->getColumnDimensions(); + $maxCol = $this->_lastColumnIndex -1; + for ($i = 0; $i <= $maxCol; ++$i) { + $hidden = 0; + $level = 0; + $xfIndex = 15; // there are 15 cell style Xfs + + $width = $defaultWidth; + + $columnLetter = PHPExcel_Cell::stringFromColumnIndex($i); + if (isset($columnDimensions[$columnLetter])) { + $columnDimension = $columnDimensions[$columnLetter]; + if ($columnDimension->getWidth() >= 0) { + $width = $columnDimension->getWidth(); + } + $hidden = $columnDimension->getVisible() ? 0 : 1; + $level = $columnDimension->getOutlineLevel(); + $xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs + } + + // Components of _colinfo: + // $firstcol first column on the range + // $lastcol last column on the range + // $width width to set + // $xfIndex The optional cell style Xf index to apply to the columns + // $hidden The optional hidden atribute + // $level The optional outline level + $this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level); + } + + // Write GUTS + $this->_writeGuts(); + + // Write DEFAULTROWHEIGHT + $this->_writeDefaultRowHeight(); + + // Write WSBOOL + $this->_writeWsbool(); + + // Write horizontal and vertical page breaks + $this->_writeBreaks(); + + // Write page header + $this->_writeHeader(); + + // Write page footer + $this->_writeFooter(); + + // Write page horizontal centering + $this->_writeHcenter(); + + // Write page vertical centering + $this->_writeVcenter(); + + // Write left margin + $this->_writeMarginLeft(); + + // Write right margin + $this->_writeMarginRight(); + + // Write top margin + $this->_writeMarginTop(); + + // Write bottom margin + $this->_writeMarginBottom(); + + // Write page setup + $this->_writeSetup(); + + // Write sheet protection + $this->_writeProtect(); + + // Write SCENPROTECT + $this->_writeScenProtect(); + + // Write OBJECTPROTECT + $this->_writeObjectProtect(); + + // Write sheet password + $this->_writePassword(); + + // Write DEFCOLWIDTH record + $this->_writeDefcol(); + + // Write the COLINFO records if they exist + if (!empty($this->_colinfo)) { + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $this->_writeColinfo($this->_colinfo[$i]); + } + } + $autoFilterRange = $_phpSheet->getAutoFilter()->getRange(); + if (!empty($autoFilterRange)) { + // Write AUTOFILTERINFO + $this->_writeAutoFilterInfo(); + } + + // Write sheet dimensions + $this->_writeDimensions(); + + // Row dimensions + foreach ($_phpSheet->getRowDimensions() as $rowDimension) { + $xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs + $this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() ); + } + + // Write Cells + foreach ($_phpSheet->getCellCollection() as $cellID) { + $cell = $_phpSheet->getCell($cellID); + $row = $cell->getRow() - 1; + $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1; + + // Don't break Excel! +// if ($row + 1 > 65536 or $column + 1 > 256) { + if ($row > 65535 || $column > 255) { + break; + } + + // Write cell value + $xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs + + $cVal = $cell->getValue(); + if ($cVal instanceof PHPExcel_RichText) { + // $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex); + $arrcRun = array(); + $str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8'); + $str_pos = 0; + $elements = $cVal->getRichTextElements(); + foreach ($elements as $element) { + // FONT Index + if ($element instanceof PHPExcel_RichText_Run) { + $str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()]; + } + else { + $str_fontidx = 0; + } + $arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx); + // Position FROM + $str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8'); + } + $this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun); + } else { + switch ($cell->getDatatype()) { + case PHPExcel_Cell_DataType::TYPE_STRING: + case PHPExcel_Cell_DataType::TYPE_NULL: + if ($cVal === '' || $cVal === null) { + $this->_writeBlank($row, $column, $xfIndex); + } else { + $this->_writeString($row, $column, $cVal, $xfIndex); + } + break; + + case PHPExcel_Cell_DataType::TYPE_NUMERIC: + $this->_writeNumber($row, $column, $cVal, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_FORMULA: + $calculatedValue = $this->_preCalculateFormulas ? + $cell->getCalculatedValue() : null; + $this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue); + break; + + case PHPExcel_Cell_DataType::TYPE_BOOL: + $this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex); + break; + + case PHPExcel_Cell_DataType::TYPE_ERROR: + $this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex); + break; + + } + } + } + + // Append + $this->_writeMsoDrawing(); + + // Write WINDOW2 record + $this->_writeWindow2(); + + // Write PLV record + $this->_writePageLayoutView(); + + // Write ZOOM record + $this->_writeZoom(); + if ($_phpSheet->getFreezePane()) { + $this->_writePanes(); + } + + // Write SELECTION record + $this->_writeSelection(); + + // Write MergedCellsTable Record + $this->_writeMergedCells(); + + // Hyperlinks + foreach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate); + + $url = $hyperlink->getUrl(); + + if ( strpos($url, 'sheet://') !== false ) { + // internal to current workbook + $url = str_replace('sheet://', 'internal:', $url); + + } else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) { + // URL + // $url = $url; + + } else { + // external (local file) + $url = 'external:' . $url; + } + + $this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url); + } + + $this->_writeDataValidity(); + $this->_writeSheetLayout(); + + // Write SHEETPROTECTION record + $this->_writeSheetProtection(); + $this->_writeRangeProtection(); + + $arrConditionalStyles = $_phpSheet->getConditionalStylesCollection(); + if(!empty($arrConditionalStyles)){ + $arrConditional = array(); + // @todo CFRule & CFHeader + // Write CFHEADER record + $this->_writeCFHeader(); + // Write ConditionalFormattingTable records + foreach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + // Write CFRULE record + $this->_writeCFRule($conditional); + } + } + } + } + } + + $this->_storeEof(); + } + + /** + * Write a cell range address in BIFF8 + * always fixed range + * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format + * + * @param string $range E.g. 'A1' or 'A1:B6' + * @return string Binary data + */ + private function _writeBIFF8CellRangeAddressFixed($range = 'A1') + { + $explodes = explode(':', $range); + + // extract first cell, e.g. 'A1' + $firstCell = $explodes[0]; + + // extract last cell, e.g. 'B6' + if (count($explodes) == 1) { + $lastCell = $firstCell; + } else { + $lastCell = $explodes[1]; + } + + $firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1) + $lastCellCoordinates = PHPExcel_Cell::coordinateFromString($lastCell); // e.g. array(1, 6) + + return(pack('vvvv', + $firstCellCoordinates[1] - 1, + $lastCellCoordinates[1] - 1, + PHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1, + PHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1 + )); + } + + /** + * Retrieves data from memory in one chunk, or from disk in $buffer + * sized chunks. + * + * @return string The data + */ + function getData() + { + $buffer = 4096; + + // Return data stored in memory + if (isset($this->_data)) { + $tmp = $this->_data; + unset($this->_data); + return $tmp; + } + // No data to return + return false; + } + + /** + * Set the option to print the row and column headers on the printed page. + * + * @access public + * @param integer $print Whether to print the headers or not. Defaults to 1 (print). + */ + function printRowColHeaders($print = 1) + { + $this->_print_headers = $print; + } + + /** + * This method sets the properties for outlining and grouping. The defaults + * correspond to Excel's defaults. + * + * @param bool $visible + * @param bool $symbols_below + * @param bool $symbols_right + * @param bool $auto_style + */ + function setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false) + { + $this->_outline_on = $visible; + $this->_outline_below = $symbols_below; + $this->_outline_right = $symbols_right; + $this->_outline_style = $auto_style; + + // Ensure this is a boolean vale for Window2 + if ($this->_outline_on) { + $this->_outline_on = 1; + } + } + + /** + * Write a double to the specified row and column (zero indexed). + * An integer can be written as a double. Excel will display an + * integer. $format is optional. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param float $num The number to write + * @param mixed $xfIndex The optional XF format + * @return integer + */ + private function _writeNumber($row, $col, $num, $xfIndex) + { + $record = 0x0203; // Record identifier + $length = 0x000E; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $xl_double = pack("d", $num); + if (self::getByteOrder()) { // if it's Big Endian + $xl_double = strrev($xl_double); + } + + $this->_append($header.$data.$xl_double); + return(0); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param int $xfIndex Index to XF record + */ + private function _writeString($row, $col, $str, $xfIndex) + { + $this->_writeLabelSst($row, $col, $str, $xfIndex); + } + + /** + * Write a LABELSST record or a LABEL record. Which one depends on BIFF version + * It differs from _writeString by the writing of rich text strings. + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param string $str The string + * @param mixed $xfIndex The XF format index for the cell + * @param array $arrcRun Index to Font record and characters beginning + */ + private function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){ + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Write a string to the specified row and column (zero indexed). + * NOTE: there is an Excel 5 defined limit of 255 characters. + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabel($row, $col, $str, $xfIndex) + { + $strlen = strlen($str); + $record = 0x0204; // Record identifier + $length = 0x0008 + $strlen; // Bytes to follow + + $str_error = 0; + + if ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars + $str = substr($str, 0, $this->_xls_strmax); + $length = 0x0008 + $this->_xls_strmax; + $strlen = $this->_xls_strmax; + $str_error = -3; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row, $col, $xfIndex, $strlen); + $this->_append($header . $data . $str); + return($str_error); + } + + /** + * Write a string to the specified row and column (zero indexed). + * This is the BIFF8 version (no 255 chars limit). + * $format is optional. + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @access public + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $str The string to write + * @param mixed $xfIndex The XF format index for the cell + * @return integer + */ + private function _writeLabelSst($row, $col, $str, $xfIndex) + { + $record = 0x00FD; // Record identifier + $length = 0x000A; // Bytes to follow + + $str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str); + + /* check if string is already present */ + if (!isset($this->_str_table[$str])) { + $this->_str_table[$str] = $this->_str_unique++; + } + $this->_str_total++; + + $header = pack('vv', $record, $length); + $data = pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]); + $this->_append($header.$data); + } + + /** + * Writes a note associated with the cell given by the row and column. + * NOTE records don't have a length limit. + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $note The note to write + */ + private function _writeNote($row, $col, $note) + { + $note_length = strlen($note); + $record = 0x001C; // Record identifier + $max_length = 2048; // Maximun length for a NOTE record + + // Length for this record is no more than 2048 + 6 + $length = 0x0006 + min($note_length, 2048); + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $note_length); + $this->_append($header . $data . substr($note, 0, 2048)); + + for ($i = $max_length; $i < $note_length; $i += $max_length) { + $chunk = substr($note, $i, $max_length); + $length = 0x0006 + strlen($chunk); + $header = pack("vv", $record, $length); + $data = pack("vvv", -1, 0, strlen($chunk)); + $this->_append($header.$data.$chunk); + } + return(0); + } + + /** + * Write a blank cell to the specified row and column (zero indexed). + * A blank cell is used to specify formatting without adding a string + * or a number. + * + * A blank cell without a format serves no purpose. Therefore, we don't write + * a BLANK record unless a format is specified. + * + * Returns 0 : normal termination (including no format) + * -1 : insufficient number of arguments + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param mixed $xfIndex The XF format index + */ + function _writeBlank($row, $col, $xfIndex) + { + $record = 0x0201; // Record identifier + $length = 0x0006; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vvv", $row, $col, $xfIndex); + $this->_append($header . $data); + return 0; + } + + /** + * Write a boolean or an error type to the specified row and column (zero indexed) + * + * @param int $row Row index (0-based) + * @param int $col Column index (0-based) + * @param int $value + * @param boolean $isError Error or Boolean? + * @param int $xfIndex + */ + private function _writeBoolErr($row, $col, $value, $isError, $xfIndex) + { + $record = 0x0205; + $length = 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvCC", $row, $col, $xfIndex, $value, $isError); + $this->_append($header . $data); + return 0; + } + + /** + * Write a formula to the specified row and column (zero indexed). + * The textual representation of the formula is passed to the parser in + * Parser.php which returns a packed binary string. + * + * Returns 0 : normal termination + * -1 : formula errors (bad formula) + * -2 : row or column out of range + * + * @param integer $row Zero indexed row + * @param integer $col Zero indexed column + * @param string $formula The formula text string + * @param mixed $xfIndex The XF format index + * @param mixed $calculatedValue Calculated value + * @return integer + */ + private function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue) + { + $record = 0x0006; // Record identifier + + // Initialize possible additional value for STRING record that should be written after the FORMULA record? + $stringValue = null; + + // calculated value + if (isset($calculatedValue)) { + // Since we can't yet get the data type of the calculated value, + // we use best effort to determine data type + if (is_bool($calculatedValue)) { + // Boolean value + $num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF); + } elseif (is_int($calculatedValue) || is_float($calculatedValue)) { + // Numeric value + $num = pack('d', $calculatedValue); + } elseif (is_string($calculatedValue)) { + if (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) { + // Error value + $num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF); + } elseif ($calculatedValue === '') { + // Empty string (and BIFF8) + $num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } else { + // Non-empty string value (or empty string BIFF5) + $stringValue = $calculatedValue; + $num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF); + } + } else { + // We are really not supposed to reach here + $num = pack('d', 0x00); + } + } else { + $num = pack('d', 0x00); + } + + $grbit = 0x03; // Option flags + $unknown = 0x0000; // Must be zero + + // Strip the '=' or '@' sign at the beginning of the formula string + if ($formula{0} == '=') { + $formula = substr($formula,1); + } else { + // Error handling + $this->_writeString($row, $col, 'Unrecognised character for formula'); + return -1; + } + + // Parse the formula using the parser in Parser.php + try { + $error = $this->_parser->parse($formula); + $formula = $this->_parser->toReversePolish(); + + $formlen = strlen($formula); // Length of the binary string + $length = 0x16 + $formlen; // Length of the record data + + $header = pack("vv", $record, $length); + + $data = pack("vvv", $row, $col, $xfIndex) + . $num + . pack("vVv", $grbit, $unknown, $formlen); + $this->_append($header . $data . $formula); + + // Append also a STRING record if necessary + if ($stringValue !== null) { + $this->_writeStringRecord($stringValue); + } + + return 0; + + } catch (PHPExcel_Exception $e) { + // do nothing + } + + } + + /** + * Write a STRING record. This + * + * @param string $stringValue + */ + private function _writeStringRecord($stringValue) + { + $record = 0x0207; // Record identifier + $data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue); + + $length = strlen($data); + $header = pack('vv', $record, $length); + + $this->_append($header . $data); + } + + /** + * Write a hyperlink. + * This is comprised of two elements: the visible label and + * the invisible link. The visible label is the same as the link unless an + * alternative string is specified. The label is written using the + * _writeString() method. Therefore the 255 characters string limit applies. + * $string and $format are optional. + * + * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external + * directory url. + * + * Returns 0 : normal termination + * -2 : row or column out of range + * -3 : long string truncated to 255 chars + * + * @param integer $row Row + * @param integer $col Column + * @param string $url URL string + * @return integer + */ + private function _writeUrl($row, $col, $url) + { + // Add start row and col to arg list + return($this->_writeUrlRange($row, $col, $row, $col, $url)); + } + + /** + * This is the more general form of _writeUrl(). It allows a hyperlink to be + * written to a range of cells. This function also decides the type of hyperlink + * to be written. These are either, Web (http, ftp, mailto), Internal + * (Sheet1!A1) or external ('c:\temp\foo.xls#Sheet1!A1'). + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlRange($row1, $col1, $row2, $col2, $url) + { + // Check for internal/external sheet links or default to web link + if (preg_match('[^internal:]', $url)) { + return($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url)); + } + if (preg_match('[^external:]', $url)) { + return($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url)); + } + return($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url)); + } + + /** + * Used to write http, ftp and mailto hyperlinks. + * The link type ($options) is 0x03 is the same as absolute dir ref without + * sheet. However it is differentiated by the $unknown2 data stream. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlWeb($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + $unknown2 = pack("H*", "E0C9EA79F9BACE118C8200AA004BA90B"); + + // Pack the option flags + $options = pack("V", 0x03); + + // Convert URL to a null terminated wchar string + $url = join("\0", preg_split("''", $url, -1, PREG_SPLIT_NO_EMPTY)); + $url = $url . "\0\0\0"; + + // Pack the length of the URL + $url_len = pack("V", strlen($url)); + + // Calculate the data length + $length = 0x34 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $unknown2 . $url_len . $url); + return 0; + } + + /** + * Used to write internal reference hyperlinks such as "Sheet1!A1". + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlInternal($row1, $col1, $row2, $col2, $url) + { + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type + $url = preg_replace('/^internal:/', '', $url); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*", "D0C9EA79F9BACE118C8200AA004BA90B02000000"); + + // Pack the option flags + $options = pack("V", 0x08); + + // Convert the URL type and to a null terminated wchar string + $url .= "\0"; + + // character count + $url_len = PHPExcel_Shared_String::CountCharacters($url); + $url_len = pack('V', $url_len); + + $url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8'); + + // Calculate the data length + $length = 0x24 + strlen($url); + + // Pack the header data + $header = pack("vv", $record, $length); + $data = pack("vvvv", $row1, $row2, $col1, $col2); + + // Write the packed data + $this->_append($header . $data . + $unknown1 . $options . + $url_len . $url); + return 0; + } + + /** + * Write links to external directory names such as 'c:\foo.xls', + * c:\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'. + * + * Note: Excel writes some relative links with the $dir_long string. We ignore + * these cases for the sake of simpler code. + * + * @access private + * @see _writeUrl() + * @param integer $row1 Start row + * @param integer $col1 Start column + * @param integer $row2 End row + * @param integer $col2 End column + * @param string $url URL string + * @return integer + */ + function _writeUrlExternal($row1, $col1, $row2, $col2, $url) + { + // Network drives are different. We will handle them separately + // MS/Novell network drives and shares start with \\ + if (preg_match('[^external:\\\\]', $url)) { + return; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format)); + } + + $record = 0x01B8; // Record identifier + $length = 0x00000; // Bytes to follow + + // Strip URL type and change Unix dir separator to Dos style (if needed) + // + $url = preg_replace('/^external:/', '', $url); + $url = preg_replace('/\//', "\\", $url); + + // Determine if the link is relative or absolute: + // relative if link contains no dir separator, "somefile.xls" + // relative if link starts with up-dir, "..\..\somefile.xls" + // otherwise, absolute + + $absolute = 0x00; // relative path + if ( preg_match('/^[A-Z]:/', $url) ) { + $absolute = 0x02; // absolute path on Windows, e.g. C:\... + } + $link_type = 0x01 | $absolute; + + // Determine if the link contains a sheet reference and change some of the + // parameters accordingly. + // Split the dir name and sheet name (if it exists) + $dir_long = $url; + if (preg_match("/\#/", $url)) { + $link_type |= 0x08; + } + + + // Pack the link type + $link_type = pack("V", $link_type); + + // Calculate the up-level dir count e.g.. (..\..\..\ == 3) + $up_count = preg_match_all("/\.\.\\\/", $dir_long, $useless); + $up_count = pack("v", $up_count); + + // Store the short dos dir name (null terminated) + $dir_short = preg_replace("/\.\.\\\/", '', $dir_long) . "\0"; + + // Store the long dir name as a wchar string (non-null terminated) + $dir_long = $dir_long . "\0"; + + // Pack the lengths of the dir strings + $dir_short_len = pack("V", strlen($dir_short) ); + $dir_long_len = pack("V", strlen($dir_long) ); + $stream_len = pack("V", 0);//strlen($dir_long) + 0x06); + + // Pack the undocumented parts of the hyperlink stream + $unknown1 = pack("H*",'D0C9EA79F9BACE118C8200AA004BA90B02000000' ); + $unknown2 = pack("H*",'0303000000000000C000000000000046' ); + $unknown3 = pack("H*",'FFFFADDE000000000000000000000000000000000000000'); + $unknown4 = pack("v", 0x03 ); + + // Pack the main data stream + $data = pack("vvvv", $row1, $row2, $col1, $col2) . + $unknown1 . + $link_type . + $unknown2 . + $up_count . + $dir_short_len. + $dir_short . + $unknown3 . + $stream_len ;/*. + $dir_long_len . + $unknown4 . + $dir_long . + $sheet_len . + $sheet ;*/ + + // Pack the header data + $length = strlen($data); + $header = pack("vv", $record, $length); + + // Write the packed data + $this->_append($header. $data); + return 0; + } + + /** + * This method is used to set the height and format for a row. + * + * @param integer $row The row to set + * @param integer $height Height we are giving to the row. + * Use null to set XF without setting height + * @param integer $xfIndex The optional cell style Xf index to apply to the columns + * @param bool $hidden The optional hidden attribute + * @param integer $level The optional outline level for row, in range [0,7] + */ + private function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0) + { + $record = 0x0208; // Record identifier + $length = 0x0010; // Number of bytes to follow + + $colMic = 0x0000; // First defined column + $colMac = 0x0000; // Last defined column + $irwMac = 0x0000; // Used by Excel to optimise loading + $reserved = 0x0000; // Reserved + $grbit = 0x0000; // Option flags + $ixfe = $xfIndex; + + if ( $height < 0 ){ + $height = null; + } + + // Use _writeRow($row, null, $XF) to set XF format without setting height + if ($height != null) { + $miyRw = $height * 20; // row height + } else { + $miyRw = 0xff; // default row height is 256 + } + + // Set the options flags. fUnsynced is used to show that the font and row + // heights are not compatible. This is usually the case for WriteExcel. + // The collapsed flag 0x10 doesn't seem to be used to indicate that a row + // is collapsed. Instead it is used to indicate that the previous row is + // collapsed. The zero height flag, 0x20, is used to collapse a row. + + $grbit |= $level; + if ($hidden) { + $grbit |= 0x0020; + } + if ($height !== null) { + $grbit |= 0x0040; // fUnsynced + } + if ($xfIndex !== 0xF) { + $grbit |= 0x0080; + } + $grbit |= 0x0100; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvvvv", $row, $colMic, $colMac, $miyRw, + $irwMac,$reserved, $grbit, $ixfe); + $this->_append($header.$data); + } + + /** + * Writes Excel DIMENSIONS to define the area in which there is data. + */ + private function _writeDimensions() + { + $record = 0x0200; // Record identifier + + $length = 0x000E; + $data = pack('VVvvv' + , $this->_firstRowIndex + , $this->_lastRowIndex + 1 + , $this->_firstColumnIndex + , $this->_lastColumnIndex + 1 + , 0x0000 // reserved + ); + + $header = pack("vv", $record, $length); + $this->_append($header.$data); + } + + /** + * Write BIFF record Window2. + */ + private function _writeWindow2() + { + $record = 0x023E; // Record identifier + $length = 0x0012; + + $grbit = 0x00B6; // Option flags + $rwTop = 0x0000; // Top row visible in window + $colLeft = 0x0000; // Leftmost column visible in window + + + // The options flags that comprise $grbit + $fDspFmla = 0; // 0 - bit + $fDspGrid = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1 + $fDspRwCol = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2 + $fFrozen = $this->_phpSheet->getFreezePane() ? 1 : 0; // 3 + $fDspZeros = 1; // 4 + $fDefaultHdr = 1; // 5 + $fArabic = $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6 + $fDspGuts = $this->_outline_on; // 7 + $fFrozenNoSplit = 0; // 0 - bit + // no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet + $fSelected = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0; + $fPaged = 1; // 2 + $fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW; + + $grbit = $fDspFmla; + $grbit |= $fDspGrid << 1; + $grbit |= $fDspRwCol << 2; + $grbit |= $fFrozen << 3; + $grbit |= $fDspZeros << 4; + $grbit |= $fDefaultHdr << 5; + $grbit |= $fArabic << 6; + $grbit |= $fDspGuts << 7; + $grbit |= $fFrozenNoSplit << 8; + $grbit |= $fSelected << 9; + $grbit |= $fPaged << 10; + $grbit |= $fPageBreakPreview << 11; + + $header = pack("vv", $record, $length); + $data = pack("vvv", $grbit, $rwTop, $colLeft); + + // FIXME !!! + $rgbHdr = 0x0040; // Row/column heading and gridline color index + $zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000); + $zoom_factor_normal = $this->_phpSheet->getSheetView()->getZoomScaleNormal(); + + $data .= pack("vvvvV", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000); + + $this->_append($header.$data); + } + + /** + * Write BIFF record DEFAULTROWHEIGHT. + */ + private function _writeDefaultRowHeight() + { + $defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight(); + + if ($defaultRowHeight < 0) { + return; + } + + // convert to twips + $defaultRowHeight = (int) 20 * $defaultRowHeight; + + $record = 0x0225; // Record identifier + $length = 0x0004; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", 1, $defaultRowHeight); + $this->_append($header . $data); + } + + /** + * Write BIFF record DEFCOLWIDTH if COLINFO records are in use. + */ + private function _writeDefcol() + { + $defaultColWidth = 8; + + $record = 0x0055; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $defaultColWidth); + $this->_append($header . $data); + } + + /** + * Write BIFF record COLINFO to define column widths + * + * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C + * length record. + * + * @param array $col_array This is the only parameter received and is composed of the following: + * 0 => First formatted column, + * 1 => Last formatted column, + * 2 => Col width (8.43 is Excel default), + * 3 => The optional XF format of the column, + * 4 => Option flags. + * 5 => Optional outline level + */ + private function _writeColinfo($col_array) + { + if (isset($col_array[0])) { + $colFirst = $col_array[0]; + } + if (isset($col_array[1])) { + $colLast = $col_array[1]; + } + if (isset($col_array[2])) { + $coldx = $col_array[2]; + } else { + $coldx = 8.43; + } + if (isset($col_array[3])) { + $xfIndex = $col_array[3]; + } else { + $xfIndex = 15; + } + if (isset($col_array[4])) { + $grbit = $col_array[4]; + } else { + $grbit = 0; + } + if (isset($col_array[5])) { + $level = $col_array[5]; + } else { + $level = 0; + } + $record = 0x007D; // Record identifier + $length = 0x000C; // Number of bytes to follow + + $coldx *= 256; // Convert to units of 1/256 of a char + + $ixfe = $xfIndex; + $reserved = 0x0000; // Reserved + + $level = max(0, min($level, 7)); + $grbit |= $level << 8; + + $header = pack("vv", $record, $length); + $data = pack("vvvvvv", $colFirst, $colLast, $coldx, + $ixfe, $grbit, $reserved); + $this->_append($header.$data); + } + + /** + * Write BIFF record SELECTION. + */ + private function _writeSelection() + { + // look up the selected cell range + $selectedCells = $this->_phpSheet->getSelectedCells(); + $selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells()); + $selectedCells = $selectedCells[0]; + if (count($selectedCells) == 2) { + list($first, $last) = $selectedCells; + } else { + $first = $selectedCells[0]; + $last = $selectedCells[0]; + } + + list($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first); + $colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index + --$rwFirst; // base 0 row index + + list($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last); + $colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index + --$rwLast; // base 0 row index + + // make sure we are not out of bounds + $colFirst = min($colFirst, 255); + $colLast = min($colLast, 255); + + $rwFirst = min($rwFirst, 65535); + $rwLast = min($rwLast, 65535); + + $record = 0x001D; // Record identifier + $length = 0x000F; // Number of bytes to follow + + $pnn = $this->_active_pane; // Pane position + $rwAct = $rwFirst; // Active row + $colAct = $colFirst; // Active column + $irefAct = 0; // Active cell ref + $cref = 1; // Number of refs + + if (!isset($rwLast)) { + $rwLast = $rwFirst; // Last row in reference + } + if (!isset($colLast)) { + $colLast = $colFirst; // Last col in reference + } + + // Swap last row/col for first row/col as necessary + if ($rwFirst > $rwLast) { + list($rwFirst, $rwLast) = array($rwLast, $rwFirst); + } + + if ($colFirst > $colLast) { + list($colFirst, $colLast) = array($colLast, $colFirst); + } + + $header = pack("vv", $record, $length); + $data = pack("CvvvvvvCC", $pnn, $rwAct, $colAct, + $irefAct, $cref, + $rwFirst, $rwLast, + $colFirst, $colLast); + $this->_append($header . $data); + } + + /** + * Store the MERGEDCELLS records for all ranges of merged cells + */ + private function _writeMergedCells() + { + $mergeCells = $this->_phpSheet->getMergeCells(); + $countMergeCells = count($mergeCells); + + if ($countMergeCells == 0) { + return; + } + + // maximum allowed number of merged cells per record + $maxCountMergeCellsPerRecord = 1027; + + // record identifier + $record = 0x00E5; + + // counter for total number of merged cells treated so far by the writer + $i = 0; + + // counter for number of merged cells written in record currently being written + $j = 0; + + // initialize record data + $recordData = ''; + + // loop through the merged cells + foreach ($mergeCells as $mergeCell) { + ++$i; + ++$j; + + // extract the row and column indexes + $range = PHPExcel_Cell::splitRange($mergeCell); + list($first, $last) = $range[0]; + list($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first); + list($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last); + + $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1); + + // flush record if we have reached limit for number of merged cells, or reached final merged cell + if ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) { + $recordData = pack('v', $j) . $recordData; + $length = strlen($recordData); + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + + // initialize for next record, if any + $recordData = ''; + $j = 0; + } + } + } + + /** + * Write SHEETLAYOUT record + */ + private function _writeSheetLayout() + { + if (!$this->_phpSheet->isTabColorSet()) { + return; + } + + $recordData = pack( + 'vvVVVvv' + , 0x0862 + , 0x0000 // unused + , 0x00000000 // unused + , 0x00000000 // unused + , 0x00000014 // size of record data + , $this->_colors[$this->_phpSheet->getTabColor()->getRGB()] // color index + , 0x0000 // unused + ); + + $length = strlen($recordData); + + $record = 0x0862; // Record identifier + $header = pack('vv', $record, $length); + $this->_append($header . $recordData); + } + + /** + * Write SHEETPROTECTION + */ + private function _writeSheetProtection() + { + // record identifier + $record = 0x0867; + + // prepare options + $options = (int) !$this->_phpSheet->getProtection()->getObjects() + | (int) !$this->_phpSheet->getProtection()->getScenarios() << 1 + | (int) !$this->_phpSheet->getProtection()->getFormatCells() << 2 + | (int) !$this->_phpSheet->getProtection()->getFormatColumns() << 3 + | (int) !$this->_phpSheet->getProtection()->getFormatRows() << 4 + | (int) !$this->_phpSheet->getProtection()->getInsertColumns() << 5 + | (int) !$this->_phpSheet->getProtection()->getInsertRows() << 6 + | (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks() << 7 + | (int) !$this->_phpSheet->getProtection()->getDeleteColumns() << 8 + | (int) !$this->_phpSheet->getProtection()->getDeleteRows() << 9 + | (int) !$this->_phpSheet->getProtection()->getSelectLockedCells() << 10 + | (int) !$this->_phpSheet->getProtection()->getSort() << 11 + | (int) !$this->_phpSheet->getProtection()->getAutoFilter() << 12 + | (int) !$this->_phpSheet->getProtection()->getPivotTables() << 13 + | (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ; + + // record data + $recordData = pack( + 'vVVCVVvv' + , 0x0867 // repeated record identifier + , 0x0000 // not used + , 0x0000 // not used + , 0x00 // not used + , 0x01000200 // unknown data + , 0xFFFFFFFF // unknown data + , $options // options + , 0x0000 // not used + ); + + $length = strlen($recordData); + $header = pack('vv', $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Write BIFF record RANGEPROTECTION + * + * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records + * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records + */ + private function _writeRangeProtection() + { + foreach ($this->_phpSheet->getProtectedCells() as $range => $password) { + // number of ranges, e.g. 'A1:B3 C20:D25' + $cellRanges = explode(' ', $range); + $cref = count($cellRanges); + + $recordData = pack( + 'vvVVvCVvVv', + 0x0868, + 0x00, + 0x0000, + 0x0000, + 0x02, + 0x0, + 0x0000, + $cref, + 0x0000, + 0x00 + ); + + foreach ($cellRanges as $cellRange) { + $recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange); + } + + // the rgbFeat structure + $recordData .= pack( + 'VV', + 0x0000, + hexdec($password) + ); + + $recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData)); + + $length = strlen($recordData); + + $record = 0x0868; // Record identifier + $header = pack("vv", $record, $length); + $this->_append($header . $recordData); + } + } + + /** + * Write BIFF record EXTERNCOUNT to indicate the number of external sheet + * references in a worksheet. + * + * Excel only stores references to external sheets that are used in formulas. + * For simplicity we store references to all the sheets in the workbook + * regardless of whether they are used or not. This reduces the overall + * complexity and eliminates the need for a two way dialogue between the formula + * parser the worksheet objects. + * + * @param integer $count The number of external sheet references in this worksheet + */ + private function _writeExterncount($count) + { + $record = 0x0016; // Record identifier + $length = 0x0002; // Number of bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $count); + $this->_append($header . $data); + } + + /** + * Writes the Excel BIFF EXTERNSHEET record. These references are used by + * formulas. A formula references a sheet name via an index. Since we store a + * reference to all of the external worksheets the EXTERNSHEET index is the same + * as the worksheet index. + * + * @param string $sheetname The name of a external worksheet + */ + private function _writeExternsheet($sheetname) + { + $record = 0x0017; // Record identifier + + // References to the current sheet are encoded differently to references to + // external sheets. + // + if ($this->_phpSheet->getTitle() == $sheetname) { + $sheetname = ''; + $length = 0x02; // The following 2 bytes + $cch = 1; // The following byte + $rgch = 0x02; // Self reference + } else { + $length = 0x02 + strlen($sheetname); + $cch = strlen($sheetname); + $rgch = 0x03; // Reference to a sheet in the current workbook + } + + $header = pack("vv", $record, $length); + $data = pack("CC", $cch, $rgch); + $this->_append($header . $data . $sheetname); + } + + /** + * Writes the Excel BIFF PANE record. + * The panes can either be frozen or thawed (unfrozen). + * Frozen panes are specified in terms of an integer number of rows and columns. + * Thawed panes are specified in terms of Excel's units for rows and columns. + */ + private function _writePanes() + { + $panes = array(); + if ($freezePane = $this->_phpSheet->getFreezePane()) { + list($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane); + $panes[0] = $row - 1; + $panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1; + } else { + // thaw panes + return; + } + + $y = isset($panes[0]) ? $panes[0] : null; + $x = isset($panes[1]) ? $panes[1] : null; + $rwTop = isset($panes[2]) ? $panes[2] : null; + $colLeft = isset($panes[3]) ? $panes[3] : null; + if (count($panes) > 4) { // if Active pane was received + $pnnAct = $panes[4]; + } else { + $pnnAct = null; + } + $record = 0x0041; // Record identifier + $length = 0x000A; // Number of bytes to follow + + // Code specific to frozen or thawed panes. + if ($this->_phpSheet->getFreezePane()) { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = $y; + } + if (!isset($colLeft)) { + $colLeft = $x; + } + } else { + // Set default values for $rwTop and $colLeft + if (!isset($rwTop)) { + $rwTop = 0; + } + if (!isset($colLeft)) { + $colLeft = 0; + } + + // Convert Excel's row and column units to the internal units. + // The default row height is 12.75 + // The default column width is 8.43 + // The following slope and intersection values were interpolated. + // + $y = 20*$y + 255; + $x = 113.879*$x + 390; + } + + + // Determine which pane should be active. There is also the undocumented + // option to override this should it be necessary: may be removed later. + // + if (!isset($pnnAct)) { + if ($x != 0 && $y != 0) { + $pnnAct = 0; // Bottom right + } + if ($x != 0 && $y == 0) { + $pnnAct = 1; // Top right + } + if ($x == 0 && $y != 0) { + $pnnAct = 2; // Bottom left + } + if ($x == 0 && $y == 0) { + $pnnAct = 3; // Top left + } + } + + $this->_active_pane = $pnnAct; // Used in _writeSelection + + $header = pack("vv", $record, $length); + $data = pack("vvvvv", $x, $y, $rwTop, $colLeft, $pnnAct); + $this->_append($header . $data); + } + + /** + * Store the page setup SETUP BIFF record. + */ + private function _writeSetup() + { + $record = 0x00A1; // Record identifier + $length = 0x0022; // Number of bytes to follow + + $iPaperSize = $this->_phpSheet->getPageSetup()->getPaperSize(); // Paper size + + $iScale = $this->_phpSheet->getPageSetup()->getScale() ? + $this->_phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor + + $iPageStart = 0x01; // Starting page number + $iFitWidth = (int) $this->_phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide + $iFitHeight = (int) $this->_phpSheet->getPageSetup()->getFitToHeight(); // Fit to number of pages high + $grbit = 0x00; // Option flags + $iRes = 0x0258; // Print resolution + $iVRes = 0x0258; // Vertical print resolution + + $numHdr = $this->_phpSheet->getPageMargins()->getHeader(); // Header Margin + + $numFtr = $this->_phpSheet->getPageMargins()->getFooter(); // Footer Margin + $iCopies = 0x01; // Number of copies + + $fLeftToRight = 0x0; // Print over then down + + // Page orientation + $fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ? + 0x0 : 0x1; + + $fNoPls = 0x0; // Setup not read from printer + $fNoColor = 0x0; // Print black and white + $fDraft = 0x0; // Print draft quality + $fNotes = 0x0; // Print notes + $fNoOrient = 0x0; // Orientation not set + $fUsePage = 0x0; // Use custom starting page + + $grbit = $fLeftToRight; + $grbit |= $fLandscape << 1; + $grbit |= $fNoPls << 2; + $grbit |= $fNoColor << 3; + $grbit |= $fDraft << 4; + $grbit |= $fNotes << 5; + $grbit |= $fNoOrient << 6; + $grbit |= $fUsePage << 7; + + $numHdr = pack("d", $numHdr); + $numFtr = pack("d", $numFtr); + if (self::getByteOrder()) { // if it's Big Endian + $numHdr = strrev($numHdr); + $numFtr = strrev($numFtr); + } + + $header = pack("vv", $record, $length); + $data1 = pack("vvvvvvvv", $iPaperSize, + $iScale, + $iPageStart, + $iFitWidth, + $iFitHeight, + $grbit, + $iRes, + $iVRes); + $data2 = $numHdr.$numFtr; + $data3 = pack("v", $iCopies); + $this->_append($header . $data1 . $data2 . $data3); + } + + /** + * Store the header caption BIFF record. + */ + private function _writeHeader() + { + $record = 0x0014; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddHeader(); // header string + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the footer caption BIFF record. + */ + private function _writeFooter() + { + $record = 0x0015; // Record identifier + + /* removing for now + // need to fix character count (multibyte!) + if (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) { + $str = $this->_phpSheet->getHeaderFooter()->getOddFooter(); + } else { + $str = ''; + } + */ + + $recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter()); + $length = strlen($recordData); + + $header = pack("vv", $record, $length); + + $this->_append($header . $recordData); + } + + /** + * Store the horizontal centering HCENTER BIFF record. + * + * @access private + */ + private function _writeHcenter() + { + $record = 0x0083; // Record identifier + $length = 0x0002; // Bytes to follow + + $fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fHCenter); + + $this->_append($header.$data); + } + + /** + * Store the vertical centering VCENTER BIFF record. + */ + private function _writeVcenter() + { + $record = 0x0084; // Record identifier + $length = 0x0002; // Bytes to follow + + $fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0; // Horizontal centering + + $header = pack("vv", $record, $length); + $data = pack("v", $fVCenter); + $this->_append($header . $data); + } + + /** + * Store the LEFTMARGIN BIFF record. + */ + private function _writeMarginLeft() + { + $record = 0x0026; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getLeft(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the RIGHTMARGIN BIFF record. + */ + private function _writeMarginRight() + { + $record = 0x0027; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getRight(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the TOPMARGIN BIFF record. + */ + private function _writeMarginTop() + { + $record = 0x0028; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getTop(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Store the BOTTOMMARGIN BIFF record. + */ + private function _writeMarginBottom() + { + $record = 0x0029; // Record identifier + $length = 0x0008; // Bytes to follow + + $margin = $this->_phpSheet->getPageMargins()->getBottom(); // Margin in inches + + $header = pack("vv", $record, $length); + $data = pack("d", $margin); + if (self::getByteOrder()) { // if it's Big Endian + $data = strrev($data); + } + + $this->_append($header . $data); + } + + /** + * Write the PRINTHEADERS BIFF record. + */ + private function _writePrintHeaders() + { + $record = 0x002a; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintRwCol = $this->_print_headers; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintRwCol); + $this->_append($header . $data); + } + + /** + * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the + * GRIDSET record. + */ + private function _writePrintGridlines() + { + $record = 0x002b; // Record identifier + $length = 0x0002; // Bytes to follow + + $fPrintGrid = $this->_phpSheet->getPrintGridlines() ? 1 : 0; // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fPrintGrid); + $this->_append($header . $data); + } + + /** + * Write the GRIDSET BIFF record. Must be used in conjunction with the + * PRINTGRIDLINES record. + */ + private function _writeGridset() + { + $record = 0x0082; // Record identifier + $length = 0x0002; // Bytes to follow + + $fGridSet = !$this->_phpSheet->getPrintGridlines(); // Boolean flag + + $header = pack("vv", $record, $length); + $data = pack("v", $fGridSet); + $this->_append($header . $data); + } + + /** + * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet. + */ + private function _writeAutoFilterInfo(){ + $record = 0x009D; // Record identifier + $length = 0x0002; // Bytes to follow + + $rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange()); + $iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0]; + + $header = pack("vv", $record, $length); + $data = pack("v", $iNumFilters); + $this->_append($header . $data); + } + + /** + * Write the GUTS BIFF record. This is used to configure the gutter margins + * where Excel outline symbols are displayed. The visibility of the gutters is + * controlled by a flag in WSBOOL. + * + * @see _writeWsbool() + */ + private function _writeGuts() + { + $record = 0x0080; // Record identifier + $length = 0x0008; // Bytes to follow + + $dxRwGut = 0x0000; // Size of row gutter + $dxColGut = 0x0000; // Size of col gutter + + // determine maximum row outline level + $maxRowOutlineLevel = 0; + foreach ($this->_phpSheet->getRowDimensions() as $rowDimension) { + $maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel()); + } + + $col_level = 0; + + // Calculate the maximum column outline level. The equivalent calculation + // for the row outline level is carried out in _writeRow(). + $colcount = count($this->_colinfo); + for ($i = 0; $i < $colcount; ++$i) { + $col_level = max($this->_colinfo[$i][5], $col_level); + } + + // Set the limits for the outline levels (0 <= x <= 7). + $col_level = max(0, min($col_level, 7)); + + // The displayed level is one greater than the max outline levels + if ($maxRowOutlineLevel) { + ++$maxRowOutlineLevel; + } + if ($col_level) { + ++$col_level; + } + + $header = pack("vv", $record, $length); + $data = pack("vvvv", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level); + + $this->_append($header.$data); + } + + /** + * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction + * with the SETUP record. + */ + private function _writeWsbool() + { + $record = 0x0081; // Record identifier + $length = 0x0002; // Bytes to follow + $grbit = 0x0000; + + // The only option that is of interest is the flag for fit to page. So we + // set all the options in one go. + // + // Set the option flags + $grbit |= 0x0001; // Auto page breaks visible + if ($this->_outline_style) { + $grbit |= 0x0020; // Auto outline styles + } + if ($this->_phpSheet->getShowSummaryBelow()) { + $grbit |= 0x0040; // Outline summary below + } + if ($this->_phpSheet->getShowSummaryRight()) { + $grbit |= 0x0080; // Outline summary right + } + if ($this->_phpSheet->getPageSetup()->getFitToPage()) { + $grbit |= 0x0100; // Page setup fit to page + } + if ($this->_outline_on) { + $grbit |= 0x0400; // Outline symbols displayed + } + + $header = pack("vv", $record, $length); + $data = pack("v", $grbit); + $this->_append($header . $data); + } + + /** + * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records. + */ + private function _writeBreaks() + { + // initialize + $vbreaks = array(); + $hbreaks = array(); + + foreach ($this->_phpSheet->getBreaks() as $cell => $breakType) { + // Fetch coordinates + $coordinates = PHPExcel_Cell::coordinateFromString($cell); + + // Decide what to do by the type of break + switch ($breakType) { + case PHPExcel_Worksheet::BREAK_COLUMN: + // Add to list of vertical breaks + $vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1; + break; + + case PHPExcel_Worksheet::BREAK_ROW: + // Add to list of horizontal breaks + $hbreaks[] = $coordinates[1]; + break; + + case PHPExcel_Worksheet::BREAK_NONE: + default: + // Nothing to do + break; + } + } + + //horizontal page breaks + if (!empty($hbreaks)) { + + // Sort and filter array of page breaks + sort($hbreaks, SORT_NUMERIC); + if ($hbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($hbreaks); + } + + $record = 0x001b; // Record identifier + $cbrk = count($hbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($hbreaks as $hbreak) { + $data .= pack("vvv", $hbreak, 0x0000, 0x00ff); + } + + $this->_append($header . $data); + } + + // vertical page breaks + if (!empty($vbreaks)) { + + // 1000 vertical pagebreaks appears to be an internal Excel 5 limit. + // It is slightly higher in Excel 97/200, approx. 1026 + $vbreaks = array_slice($vbreaks, 0, 1000); + + // Sort and filter array of page breaks + sort($vbreaks, SORT_NUMERIC); + if ($vbreaks[0] == 0) { // don't use first break if it's 0 + array_shift($vbreaks); + } + + $record = 0x001a; // Record identifier + $cbrk = count($vbreaks); // Number of page breaks + $length = 2 + 6 * $cbrk; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("v", $cbrk); + + // Append each page break + foreach ($vbreaks as $vbreak) { + $data .= pack("vvv", $vbreak, 0x0000, 0xffff); + } + + $this->_append($header . $data); + } + } + + /** + * Set the Biff PROTECT record to indicate that the worksheet is protected. + */ + private function _writeProtect() + { + // Exit unless sheet protection has been specified + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + $record = 0x0012; // Record identifier + $length = 0x0002; // Bytes to follow + + $fLock = 1; // Worksheet is protected + + $header = pack("vv", $record, $length); + $data = pack("v", $fLock); + + $this->_append($header.$data); + } + + /** + * Write SCENPROTECT + */ + private function _writeScenProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if scenarios are not protected + if (!$this->_phpSheet->getProtection()->getScenarios()) { + return; + } + + $record = 0x00DD; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write OBJECTPROTECT + */ + private function _writeObjectProtect() + { + // Exit if sheet protection is not active + if (!$this->_phpSheet->getProtection()->getSheet()) { + return; + } + + // Exit if objects are not protected + if (!$this->_phpSheet->getProtection()->getObjects()) { + return; + } + + $record = 0x0063; // Record identifier + $length = 0x0002; // Bytes to follow + + $header = pack('vv', $record, $length); + $data = pack('v', 1); + + $this->_append($header . $data); + } + + /** + * Write the worksheet PASSWORD record. + */ + private function _writePassword() + { + // Exit unless sheet protection and password have been specified + if (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) { + return; + } + + $record = 0x0013; // Record identifier + $length = 0x0002; // Bytes to follow + + $wPassword = hexdec($this->_phpSheet->getProtection()->getPassword()); // Encoded password + + $header = pack("vv", $record, $length); + $data = pack("v", $wPassword); + + $this->_append($header . $data); + } + + /** + * Insert a 24bit bitmap image in a worksheet. + * + * @access public + * @param integer $row The row we are going to insert the bitmap into + * @param integer $col The column we are going to insert the bitmap into + * @param mixed $bitmap The bitmap filename or GD-image resource + * @param integer $x The horizontal position (offset) of the image inside the cell. + * @param integer $y The vertical position (offset) of the image inside the cell. + * @param float $scale_x The horizontal scale + * @param float $scale_y The vertical scale + */ + function insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1) + { + $bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap)); + list($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap); + + // Scale the frame of the image. + $width *= $scale_x; + $height *= $scale_y; + + // Calculate the vertices of the image and write the OBJ record + $this->_positionImage($col, $row, $x, $y, $width, $height); + + // Write the IMDATA record to store the bitmap data + $record = 0x007f; + $length = 8 + $size; + $cf = 0x09; + $env = 0x01; + $lcb = $size; + + $header = pack("vvvvV", $record, $length, $cf, $env, $lcb); + $this->_append($header.$data); + } + + /** + * Calculate the vertices that define the position of the image as required by + * the OBJ record. + * + * +------------+------------+ + * | A | B | + * +-----+------------+------------+ + * | |(x1,y1) | | + * | 1 |(A1)._______|______ | + * | | | | | + * | | | | | + * +-----+----| BITMAP |-----+ + * | | | | | + * | 2 | |______________. | + * | | | (B2)| + * | | | (x2,y2)| + * +---- +------------+------------+ + * + * Example of a bitmap that covers some of the area from cell A1 to cell B2. + * + * Based on the width and height of the bitmap we need to calculate 8 vars: + * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2. + * The width and height of the cells are also variable and have to be taken into + * account. + * The values of $col_start and $row_start are passed in from the calling + * function. The values of $col_end and $row_end are calculated by subtracting + * the width and height of the bitmap from the width and height of the + * underlying cells. + * The vertices are expressed as a percentage of the underlying cell width as + * follows (rhs values are in pixels): + * + * x1 = X / W *1024 + * y1 = Y / H *256 + * x2 = (X-1) / W *1024 + * y2 = (Y-1) / H *256 + * + * Where: X is distance from the left side of the underlying cell + * Y is distance from the top of the underlying cell + * W is the width of the cell + * H is the height of the cell + * The SDK incorrectly states that the height should be expressed as a + * percentage of 1024. + * + * @access private + * @param integer $col_start Col containing upper left corner of object + * @param integer $row_start Row containing top left corner of object + * @param integer $x1 Distance to left side of object + * @param integer $y1 Distance to top of object + * @param integer $width Width of image frame + * @param integer $height Height of image frame + */ + function _positionImage($col_start, $row_start, $x1, $y1, $width, $height) + { + // Initialise end cell to the same as the start cell + $col_end = $col_start; // Col containing lower right corner of object + $row_end = $row_start; // Row containing bottom right corner of object + + // Zero the specified offset if greater than the cell dimensions + if ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) { + $x1 = 0; + } + if ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) { + $y1 = 0; + } + + $width = $width + $x1 -1; + $height = $height + $y1 -1; + + // Subtract the underlying cell widths to find the end cell of the image + while ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) { + $width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)); + ++$col_end; + } + + // Subtract the underlying cell heights to find the end cell of the image + while ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) { + $height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1); + ++$row_end; + } + + // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell + // with zero eight or width. + // + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) { + return; + } + if (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) == 0) { + return; + } + + // Convert the pixel values to the percentage value expected by Excel + $x1 = $x1 / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) * 1024; + $y1 = $y1 / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) * 256; + $x2 = $width / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object + $y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1) * 256; // Distance to bottom of object + + $this->_writeObjPicture($col_start, $x1, + $row_start, $y1, + $col_end, $x2, + $row_end, $y2); + } + + /** + * Store the OBJ record that precedes an IMDATA record. This could be generalise + * to support other Excel objects. + * + * @param integer $colL Column containing upper left corner of object + * @param integer $dxL Distance from left side of cell + * @param integer $rwT Row containing top left corner of object + * @param integer $dyT Distance from top of cell + * @param integer $colR Column containing lower right corner of object + * @param integer $dxR Distance from right of cell + * @param integer $rwB Row containing bottom right corner of object + * @param integer $dyB Distance from bottom of cell + */ + private function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB) + { + $record = 0x005d; // Record identifier + $length = 0x003c; // Bytes to follow + + $cObj = 0x0001; // Count of objects in file (set to 1) + $OT = 0x0008; // Object type. 8 = Picture + $id = 0x0001; // Object ID + $grbit = 0x0614; // Option flags + + $cbMacro = 0x0000; // Length of FMLA structure + $Reserved1 = 0x0000; // Reserved + $Reserved2 = 0x0000; // Reserved + + $icvBack = 0x09; // Background colour + $icvFore = 0x09; // Foreground colour + $fls = 0x00; // Fill pattern + $fAuto = 0x00; // Automatic fill + $icv = 0x08; // Line colour + $lns = 0xff; // Line style + $lnw = 0x01; // Line weight + $fAutoB = 0x00; // Automatic border + $frs = 0x0000; // Frame style + $cf = 0x0009; // Image format, 9 = bitmap + $Reserved3 = 0x0000; // Reserved + $cbPictFmla = 0x0000; // Length of FMLA structure + $Reserved4 = 0x0000; // Reserved + $grbit2 = 0x0001; // Option flags + $Reserved5 = 0x0000; // Reserved + + + $header = pack("vv", $record, $length); + $data = pack("V", $cObj); + $data .= pack("v", $OT); + $data .= pack("v", $id); + $data .= pack("v", $grbit); + $data .= pack("v", $colL); + $data .= pack("v", $dxL); + $data .= pack("v", $rwT); + $data .= pack("v", $dyT); + $data .= pack("v", $colR); + $data .= pack("v", $dxR); + $data .= pack("v", $rwB); + $data .= pack("v", $dyB); + $data .= pack("v", $cbMacro); + $data .= pack("V", $Reserved1); + $data .= pack("v", $Reserved2); + $data .= pack("C", $icvBack); + $data .= pack("C", $icvFore); + $data .= pack("C", $fls); + $data .= pack("C", $fAuto); + $data .= pack("C", $icv); + $data .= pack("C", $lns); + $data .= pack("C", $lnw); + $data .= pack("C", $fAutoB); + $data .= pack("v", $frs); + $data .= pack("V", $cf); + $data .= pack("v", $Reserved3); + $data .= pack("v", $cbPictFmla); + $data .= pack("v", $Reserved4); + $data .= pack("v", $grbit2); + $data .= pack("V", $Reserved5); + + $this->_append($header . $data); + } + + /** + * Convert a GD-image into the internal format. + * + * @access private + * @param resource $image The image to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmapGd($image) { + $width = imagesx($image); + $height = imagesy($image); + + $data = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + for ($j=$height; $j--; ) { + for ($i=0; $i < $width; ++$i) { + $color = imagecolorsforindex($image, imagecolorat($image, $i, $j)); + foreach (array("red", "green", "blue") as $key) { + $color[$key] = $color[$key] + round((255 - $color[$key]) * $color["alpha"] / 127); + } + $data .= chr($color["blue"]) . chr($color["green"]) . chr($color["red"]); + } + if (3*$width % 4) { + $data .= str_repeat("\x00", 4 - 3*$width % 4); + } + } + + return array($width, $height, strlen($data), $data); + } + + /** + * Convert a 24 bit bitmap into the modified internal format used by Windows. + * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the + * MSDN library. + * + * @access private + * @param string $bitmap The bitmap to process + * @return array Array with data and properties of the bitmap + */ + function _processBitmap($bitmap) + { + // Open file. + $bmp_fd = @fopen($bitmap,"rb"); + if (!$bmp_fd) { + throw new PHPExcel_Writer_Exception("Couldn't import $bitmap"); + } + + // Slurp the file into a string. + $data = fread($bmp_fd, filesize($bitmap)); + + // Check that the file is big enough to be a bitmap. + if (strlen($data) <= 0x36) { + throw new PHPExcel_Writer_Exception("$bitmap doesn't contain enough data.\n"); + } + + // The first 2 bytes are used to identify the bitmap. + $identity = unpack("A2ident", $data); + if ($identity['ident'] != "BM") { + throw new PHPExcel_Writer_Exception("$bitmap doesn't appear to be a valid bitmap image.\n"); + } + + // Remove bitmap data: ID. + $data = substr($data, 2); + + // Read and remove the bitmap size. This is more reliable than reading + // the data size at offset 0x22. + // + $size_array = unpack("Vsa", substr($data, 0, 4)); + $size = $size_array['sa']; + $data = substr($data, 4); + $size -= 0x36; // Subtract size of bitmap header. + $size += 0x0C; // Add size of BIFF header. + + // Remove bitmap data: reserved, offset, header length. + $data = substr($data, 12); + + // Read and remove the bitmap width and height. Verify the sizes. + $width_and_height = unpack("V2", substr($data, 0, 8)); + $width = $width_and_height[1]; + $height = $width_and_height[2]; + $data = substr($data, 8); + if ($width > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image width supported is 65k.\n"); + } + if ($height > 0xFFFF) { + throw new PHPExcel_Writer_Exception("$bitmap: largest image height supported is 65k.\n"); + } + + // Read and remove the bitmap planes and bpp data. Verify them. + $planes_and_bitcount = unpack("v2", substr($data, 0, 4)); + $data = substr($data, 4); + if ($planes_and_bitcount[2] != 24) { // Bitcount + throw new PHPExcel_Writer_Exception("$bitmap isn't a 24bit true color bitmap.\n"); + } + if ($planes_and_bitcount[1] != 1) { + throw new PHPExcel_Writer_Exception("$bitmap: only 1 plane supported in bitmap image.\n"); + } + + // Read and remove the bitmap compression. Verify compression. + $compression = unpack("Vcomp", substr($data, 0, 4)); + $data = substr($data, 4); + + //$compression = 0; + if ($compression['comp'] != 0) { + throw new PHPExcel_Writer_Exception("$bitmap: compression not supported in bitmap image.\n"); + } + + // Remove bitmap data: data size, hres, vres, colours, imp. colours. + $data = substr($data, 20); + + // Add the BITMAPCOREHEADER data + $header = pack("Vvvvv", 0x000c, $width, $height, 0x01, 0x18); + $data = $header . $data; + + return (array($width, $height, $size, $data)); + } + + /** + * Store the window zoom factor. This should be a reduced fraction but for + * simplicity we will store all fractions with a numerator of 100. + */ + private function _writeZoom() + { + // If scale is 100 we don't need to write a record + if ($this->_phpSheet->getSheetView()->getZoomScale() == 100) { + return; + } + + $record = 0x00A0; // Record identifier + $length = 0x0004; // Bytes to follow + + $header = pack("vv", $record, $length); + $data = pack("vv", $this->_phpSheet->getSheetView()->getZoomScale(), 100); + $this->_append($header . $data); + } + + /** + * Get Escher object + * + * @return PHPExcel_Shared_Escher + */ + public function getEscher() + { + return $this->_escher; + } + + /** + * Set Escher object + * + * @param PHPExcel_Shared_Escher $pValue + */ + public function setEscher(PHPExcel_Shared_Escher $pValue = null) + { + $this->_escher = $pValue; + } + + /** + * Write MSODRAWING record + */ + private function _writeMsoDrawing() + { + // write the Escher stream if necessary + if (isset($this->_escher)) { + $writer = new PHPExcel_Writer_Excel5_Escher($this->_escher); + $data = $writer->close(); + $spOffsets = $writer->getSpOffsets(); + $spTypes = $writer->getSpTypes(); + // write the neccesary MSODRAWING, OBJ records + + // split the Escher stream + $spOffsets[0] = 0; + $nm = count($spOffsets) - 1; // number of shapes excluding first shape + for ($i = 1; $i <= $nm; ++$i) { + // MSODRAWING record + $record = 0x00EC; // Record identifier + + // chunk of Escher stream for one shape + $dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]); + + $length = strlen($dataChunk); + $header = pack("vv", $record, $length); + + $this->_append($header . $dataChunk); + + // OBJ record + $record = 0x005D; // record identifier + $objData = ''; + + // ftCmo + if($spTypes[$i] == 0x00C9){ + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0014 // object type, 0x0014 = filter + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x2101 // option flags, 0x2001 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + + // Add ftSbs Scroll bar subobject + $objData .= pack('vv', 0x00C, 0x0014); + $objData .= pack('H*', '0000000000000000640001000A00000010000100'); + // Add ftLbsData (List box data) subobject + $objData .= pack('vv', 0x0013, 0x1FEE); + $objData .= pack('H*', '00000000010001030000020008005700'); + } + else { + // Add ftCmo (common object data) subobject + $objData .= + pack('vvvvvVVV' + , 0x0015 // 0x0015 = ftCmo + , 0x0012 // length of ftCmo data + , 0x0008 // object type, 0x0008 = picture + , $i // object id number, Excel seems to use 1-based index, local for the sheet + , 0x6011 // option flags, 0x6011 is what OpenOffice.org uses + , 0 // reserved + , 0 // reserved + , 0 // reserved + ); + } + + // ftEnd + $objData .= + pack('vv' + , 0x0000 // 0x0000 = ftEnd + , 0x0000 // length of ftEnd data + ); + + $length = strlen($objData); + $header = pack('vv', $record, $length); + $this->_append($header . $objData); + } + } + } + + /** + * Store the DATAVALIDATIONS and DATAVALIDATION records. + */ + private function _writeDataValidity() + { + // Datavalidation collection + $dataValidationCollection = $this->_phpSheet->getDataValidationCollection(); + + // Write data validations? + if (!empty($dataValidationCollection)) { + + // DATAVALIDATIONS record + $record = 0x01B2; // Record identifier + $length = 0x0012; // Bytes to follow + + $grbit = 0x0000; // Prompt box at cell, no cached validity data at DV records + $horPos = 0x00000000; // Horizontal position of prompt box, if fixed position + $verPos = 0x00000000; // Vertical position of prompt box, if fixed position + $objId = 0xFFFFFFFF; // Object identifier of drop down arrow object, or -1 if not visible + + $header = pack('vv', $record, $length); + $data = pack('vVVVV', $grbit, $horPos, $verPos, $objId, + count($dataValidationCollection)); + $this->_append($header.$data); + + // DATAVALIDATION records + $record = 0x01BE; // Record identifier + + foreach ($dataValidationCollection as $cellCoordinate => $dataValidation) { + // initialize record data + $data = ''; + + // options + $options = 0x00000000; + + // data type + $type = $dataValidation->getType(); + switch ($type) { + case PHPExcel_Cell_DataValidation::TYPE_NONE: $type = 0x00; break; + case PHPExcel_Cell_DataValidation::TYPE_WHOLE: $type = 0x01; break; + case PHPExcel_Cell_DataValidation::TYPE_DECIMAL: $type = 0x02; break; + case PHPExcel_Cell_DataValidation::TYPE_LIST: $type = 0x03; break; + case PHPExcel_Cell_DataValidation::TYPE_DATE: $type = 0x04; break; + case PHPExcel_Cell_DataValidation::TYPE_TIME: $type = 0x05; break; + case PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH: $type = 0x06; break; + case PHPExcel_Cell_DataValidation::TYPE_CUSTOM: $type = 0x07; break; + } + $options |= $type << 0; + + // error style + $errorStyle = $dataValidation->getType(); + switch ($errorStyle) { + case PHPExcel_Cell_DataValidation::STYLE_STOP: $errorStyle = 0x00; break; + case PHPExcel_Cell_DataValidation::STYLE_WARNING: $errorStyle = 0x01; break; + case PHPExcel_Cell_DataValidation::STYLE_INFORMATION: $errorStyle = 0x02; break; + } + $options |= $errorStyle << 4; + + // explicit formula? + if ($type == 0x03 && preg_match('/^\".*\"$/', $dataValidation->getFormula1())) { + $options |= 0x01 << 7; + } + + // empty cells allowed + $options |= $dataValidation->getAllowBlank() << 8; + + // show drop down + $options |= (!$dataValidation->getShowDropDown()) << 9; + + // show input message + $options |= $dataValidation->getShowInputMessage() << 18; + + // show error message + $options |= $dataValidation->getShowErrorMessage() << 19; + + // condition operator + $operator = $dataValidation->getOperator(); + switch ($operator) { + case PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05 ; break; + case PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06; break; + case PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07 ; break; + } + $options |= $operator << 20; + + $data = pack('V', $options); + + // prompt title + $promptTitle = $dataValidation->getPromptTitle() !== '' ? + $dataValidation->getPromptTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle); + + // error title + $errorTitle = $dataValidation->getErrorTitle() !== '' ? + $dataValidation->getErrorTitle() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle); + + // prompt text + $prompt = $dataValidation->getPrompt() !== '' ? + $dataValidation->getPrompt() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt); + + // error text + $error = $dataValidation->getError() !== '' ? + $dataValidation->getError() : chr(0); + $data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error); + + // formula 1 + try { + $formula1 = $dataValidation->getFormula1(); + if ($type == 0x03) { // list type + $formula1 = str_replace(',', chr(0), $formula1); + } + $this->_parser->parse($formula1); + $formula1 = $this->_parser->toReversePolish(); + $sz1 = strlen($formula1); + + } catch(PHPExcel_Exception $e) { + $sz1 = 0; + $formula1 = ''; + } + $data .= pack('vv', $sz1, 0x0000); + $data .= $formula1; + + // formula 2 + try { + $formula2 = $dataValidation->getFormula2(); + if ($formula2 === '') { + throw new PHPExcel_Writer_Exception('No formula2'); + } + $this->_parser->parse($formula2); + $formula2 = $this->_parser->toReversePolish(); + $sz2 = strlen($formula2); + + } catch(PHPExcel_Exception $e) { + $sz2 = 0; + $formula2 = ''; + } + $data .= pack('vv', $sz2, 0x0000); + $data .= $formula2; + + // cell range address list + $data .= pack('v', 0x0001); + $data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate); + + $length = strlen($data); + $header = pack("vv", $record, $length); + + $this->_append($header . $data); + } + } + } + + /** + * Map Error code + * + * @param string $errorCode + * @return int + */ + private static function _mapErrorCode($errorCode) { + switch ($errorCode) { + case '#NULL!': return 0x00; + case '#DIV/0!': return 0x07; + case '#VALUE!': return 0x0F; + case '#REF!': return 0x17; + case '#NAME?': return 0x1D; + case '#NUM!': return 0x24; + case '#N/A': return 0x2A; + } + + return 0; + } + + /** + * Write PLV Record + */ + private function _writePageLayoutView(){ + $record = 0x088B; // Record identifier + $length = 0x0010; // Bytes to follow + + $rt = 0x088B; // 2 + $grbitFrt = 0x0000; // 2 + $reserved = 0x0000000000000000; // 8 + $wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2 + + // The options flags that comprise $grbit + if($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){ + $fPageLayoutView = 1; + } else { + $fPageLayoutView = 0; + } + $fRulerVisible = 0; + $fWhitespaceHidden = 0; + + $grbit = $fPageLayoutView; // 2 + $grbit |= $fRulerVisible << 1; + $grbit |= $fWhitespaceHidden << 3; + + $header = pack("vv", $record, $length); + $data = pack("vvVVvv", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit); + $this->_append($header . $data); + } + + /** + * Write CFRule Record + * @param PHPExcel_Style_Conditional $conditional + */ + private function _writeCFRule(PHPExcel_Style_Conditional $conditional){ + $record = 0x01B1; // Record identifier + + // $type : Type of the CF + // $operatorType : Comparison operator + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){ + $type = 0x02; + $operatorType = 0x00; + } else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + $type = 0x01; + + switch ($conditional->getOperatorType()){ + case PHPExcel_Style_Conditional::OPERATOR_NONE: + $operatorType = 0x00; + break; + case PHPExcel_Style_Conditional::OPERATOR_EQUAL: + $operatorType = 0x03; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN: + $operatorType = 0x05; + break; + case PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL: + $operatorType = 0x07; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHAN: + $operatorType = 0x06; + break; + case PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL: + $operatorType = 0x08; + break; + case PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL: + $operatorType = 0x04; + break; + case PHPExcel_Style_Conditional::OPERATOR_BETWEEN: + $operatorType = 0x01; + break; + // not OPERATOR_NOTBETWEEN 0x02 + } + } + + // $szValue1 : size of the formula data for first value or formula + // $szValue2 : size of the formula data for second value or formula + $arrConditions = $conditional->getConditions(); + $numConditions = sizeof($arrConditions); + if($numConditions == 1){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = 0x0000; + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = null; + } else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){ + $szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000); + $szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000); + $operand1 = pack('Cv', 0x1E, $arrConditions[0]); + $operand2 = pack('Cv', 0x1E, $arrConditions[1]); + } else { + $szValue1 = 0x0000; + $szValue2 = 0x0000; + $operand1 = null; + $operand2 = null; + } + + // $flags : Option flags + // Alignment + $bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0); + $bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0); + $bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0); + $bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0); + $bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0); + $bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0); + if($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){ + $bFormatAlign = 1; + } else { + $bFormatAlign = 0; + } + // Protection + $bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0); + $bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0); + if($bProtLocked == 0 || $bProtHidden == 0){ + $bFormatProt = 1; + } else { + $bFormatProt = 0; + } + // Border + $bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + $bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK + && $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0); + if($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){ + $bFormatBorder = 1; + } else { + $bFormatBorder = 0; + } + // Pattern + $bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1); + $bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1); + $bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1); + if($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){ + $bFormatFill = 1; + } else { + $bFormatFill = 0; + } + // Font + if($conditional->getStyle()->getFont()->getName() != null + || $conditional->getStyle()->getFont()->getSize() != null + || $conditional->getStyle()->getFont()->getBold() != null + || $conditional->getStyle()->getFont()->getItalic() != null + || $conditional->getStyle()->getFont()->getSuperScript() != null + || $conditional->getStyle()->getFont()->getSubScript() != null + || $conditional->getStyle()->getFont()->getUnderline() != null + || $conditional->getStyle()->getFont()->getStrikethrough() != null + || $conditional->getStyle()->getFont()->getColor()->getARGB() != null){ + $bFormatFont = 1; + } else { + $bFormatFont = 0; + } + // Alignment + $flags = 0; + $flags |= (1 == $bAlignHz ? 0x00000001 : 0); + $flags |= (1 == $bAlignVt ? 0x00000002 : 0); + $flags |= (1 == $bAlignWrapTx ? 0x00000004 : 0); + $flags |= (1 == $bTxRotation ? 0x00000008 : 0); + // Justify last line flag + $flags |= (1 == 1 ? 0x00000010 : 0); + $flags |= (1 == $bIndent ? 0x00000020 : 0); + $flags |= (1 == $bShrinkToFit ? 0x00000040 : 0); + // Default + $flags |= (1 == 1 ? 0x00000080 : 0); + // Protection + $flags |= (1 == $bProtLocked ? 0x00000100 : 0); + $flags |= (1 == $bProtHidden ? 0x00000200 : 0); + // Border + $flags |= (1 == $bBorderLeft ? 0x00000400 : 0); + $flags |= (1 == $bBorderRight ? 0x00000800 : 0); + $flags |= (1 == $bBorderTop ? 0x00001000 : 0); + $flags |= (1 == $bBorderBottom ? 0x00002000 : 0); + $flags |= (1 == 1 ? 0x00004000 : 0); // Top left to Bottom right border + $flags |= (1 == 1 ? 0x00008000 : 0); // Bottom left to Top right border + // Pattern + $flags |= (1 == $bFillStyle ? 0x00010000 : 0); + $flags |= (1 == $bFillColor ? 0x00020000 : 0); + $flags |= (1 == $bFillColorBg ? 0x00040000 : 0); + $flags |= (1 == 1 ? 0x00380000 : 0); + // Font + $flags |= (1 == $bFormatFont ? 0x04000000 : 0); + // Alignment : + $flags |= (1 == $bFormatAlign ? 0x08000000 : 0); + // Border + $flags |= (1 == $bFormatBorder ? 0x10000000 : 0); + // Pattern + $flags |= (1 == $bFormatFill ? 0x20000000 : 0); + // Protection + $flags |= (1 == $bFormatProt ? 0x40000000 : 0); + // Text direction + $flags |= (1 == 0 ? 0x80000000 : 0); + + // Data Blocks + if($bFormatFont == 1){ + // Font Name + if($conditional->getStyle()->getFont()->getName() == null){ + $dataBlockFont = pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + $dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000); + } else { + $dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName()); + } + // Font Size + if($conditional->getStyle()->getFont()->getSize() == null){ + $dataBlockFont .= pack('V', 20 * 11); + } else { + $dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize()); + } + // Font Options + $dataBlockFont .= pack('V', 0); + // Font weight + if($conditional->getStyle()->getFont()->getBold() == true){ + $dataBlockFont .= pack('v', 0x02BC); + } else { + $dataBlockFont .= pack('v', 0x0190); + } + // Escapement type + if($conditional->getStyle()->getFont()->getSubScript() == true){ + $dataBlockFont .= pack('v', 0x02); + $fontEscapement = 0; + } else if($conditional->getStyle()->getFont()->getSuperScript() == true){ + $dataBlockFont .= pack('v', 0x01); + $fontEscapement = 0; + } else { + $dataBlockFont .= pack('v', 0x00); + $fontEscapement = 1; + } + // Underline type + switch ($conditional->getStyle()->getFont()->getUnderline()){ + case PHPExcel_Style_Font::UNDERLINE_NONE : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLE : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLE : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break; + case PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break; + default : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break; + } + // Not used (3) + $dataBlockFont .= pack('vC', 0x0000, 0x00); + // Font color index + switch ($conditional->getStyle()->getFont()->getColor()->getRGB()) { + case '000000': $colorIdx = 0x08; break; + case 'FFFFFF': $colorIdx = 0x09; break; + case 'FF0000': $colorIdx = 0x0A; break; + case '00FF00': $colorIdx = 0x0B; break; + case '0000FF': $colorIdx = 0x0C; break; + case 'FFFF00': $colorIdx = 0x0D; break; + case 'FF00FF': $colorIdx = 0x0E; break; + case '00FFFF': $colorIdx = 0x0F; break; + case '800000': $colorIdx = 0x10; break; + case '008000': $colorIdx = 0x11; break; + case '000080': $colorIdx = 0x12; break; + case '808000': $colorIdx = 0x13; break; + case '800080': $colorIdx = 0x14; break; + case '008080': $colorIdx = 0x15; break; + case 'C0C0C0': $colorIdx = 0x16; break; + case '808080': $colorIdx = 0x17; break; + case '9999FF': $colorIdx = 0x18; break; + case '993366': $colorIdx = 0x19; break; + case 'FFFFCC': $colorIdx = 0x1A; break; + case 'CCFFFF': $colorIdx = 0x1B; break; + case '660066': $colorIdx = 0x1C; break; + case 'FF8080': $colorIdx = 0x1D; break; + case '0066CC': $colorIdx = 0x1E; break; + case 'CCCCFF': $colorIdx = 0x1F; break; + case '000080': $colorIdx = 0x20; break; + case 'FF00FF': $colorIdx = 0x21; break; + case 'FFFF00': $colorIdx = 0x22; break; + case '00FFFF': $colorIdx = 0x23; break; + case '800080': $colorIdx = 0x24; break; + case '800000': $colorIdx = 0x25; break; + case '008080': $colorIdx = 0x26; break; + case '0000FF': $colorIdx = 0x27; break; + case '00CCFF': $colorIdx = 0x28; break; + case 'CCFFFF': $colorIdx = 0x29; break; + case 'CCFFCC': $colorIdx = 0x2A; break; + case 'FFFF99': $colorIdx = 0x2B; break; + case '99CCFF': $colorIdx = 0x2C; break; + case 'FF99CC': $colorIdx = 0x2D; break; + case 'CC99FF': $colorIdx = 0x2E; break; + case 'FFCC99': $colorIdx = 0x2F; break; + case '3366FF': $colorIdx = 0x30; break; + case '33CCCC': $colorIdx = 0x31; break; + case '99CC00': $colorIdx = 0x32; break; + case 'FFCC00': $colorIdx = 0x33; break; + case 'FF9900': $colorIdx = 0x34; break; + case 'FF6600': $colorIdx = 0x35; break; + case '666699': $colorIdx = 0x36; break; + case '969696': $colorIdx = 0x37; break; + case '003366': $colorIdx = 0x38; break; + case '339966': $colorIdx = 0x39; break; + case '003300': $colorIdx = 0x3A; break; + case '333300': $colorIdx = 0x3B; break; + case '993300': $colorIdx = 0x3C; break; + case '993366': $colorIdx = 0x3D; break; + case '333399': $colorIdx = 0x3E; break; + case '333333': $colorIdx = 0x3F; break; + default: $colorIdx = 0x00; break; + } + $dataBlockFont .= pack('V', $colorIdx); + // Not used (4) + $dataBlockFont .= pack('V', 0x00000000); + // Options flags for modified font attributes + $optionsFlags = 0; + $optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0); + $optionsFlags |= (1 == $optionsFlagsBold ? 0x00000002 : 0); + $optionsFlags |= (1 == 1 ? 0x00000008 : 0); + $optionsFlags |= (1 == 1 ? 0x00000010 : 0); + $optionsFlags |= (1 == 0 ? 0x00000020 : 0); + $optionsFlags |= (1 == 1 ? 0x00000080 : 0); + $dataBlockFont .= pack('V', $optionsFlags); + // Escapement type + $dataBlockFont .= pack('V', $fontEscapement); + // Underline type + $dataBlockFont .= pack('V', $fontUnderline); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Always + $dataBlockFont .= pack('V', 0x00000000); + // Not used (8) + $dataBlockFont .= pack('VV', 0x00000000, 0x00000000); + // Always + $dataBlockFont .= pack('v', 0x0001); + } + if($bFormatAlign == 1){ + $blockAlign = 0; + // Alignment and text break + switch ($conditional->getStyle()->getAlignment()->getHorizontal()){ + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL : $blockAlign = 0; break; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT : $blockAlign = 1; break; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT : $blockAlign = 3; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER : $blockAlign = 2; break; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS : $blockAlign = 6; break; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY : $blockAlign = 5; break; + } + if($conditional->getStyle()->getAlignment()->getWrapText() == true){ + $blockAlign |= 1 << 3; + } else { + $blockAlign |= 0 << 3; + } + switch ($conditional->getStyle()->getAlignment()->getVertical()){ + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM : $blockAlign = 2 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_TOP : $blockAlign = 0 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_CENTER : $blockAlign = 1 << 4; break; + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY : $blockAlign = 3 << 4; break; + } + $blockAlign |= 0 << 7; + + // Text rotation angle + $blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation(); + + // Indentation + $blockIndent = $conditional->getStyle()->getAlignment()->getIndent(); + if($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){ + $blockIndent |= 1 << 4; + } else { + $blockIndent |= 0 << 4; + } + $blockIndent |= 0 << 6; + + // Relative indentation + $blockIndentRelative = 255; + + $dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000); + } + if($bFormatBorder == 1){ + $blockLineStyle = 0; + switch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D; break; + } + switch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 4; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 4; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 4; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 4; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 4; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 4; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 4; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 4; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 4; break; + } + switch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 8; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 8; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 8; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 8; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 8; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 8; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 8; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 8; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 8; break; + } + switch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockLineStyle |= 0x00 << 12; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockLineStyle |= 0x01 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockLineStyle |= 0x02 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockLineStyle |= 0x03 << 12; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockLineStyle |= 0x04 << 12; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockLineStyle |= 0x05 << 12; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockLineStyle |= 0x06 << 12; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockLineStyle |= 0x07 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockLineStyle |= 0x08 << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockLineStyle |= 0x09 << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockLineStyle |= 0x0A << 12; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockLineStyle |= 0x0B << 12; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockLineStyle |= 0x0C << 12; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockLineStyle |= 0x0D << 12; break; + } + //@todo _writeCFRule() => $blockLineStyle => Index Color for left line + //@todo _writeCFRule() => $blockLineStyle => Index Color for right line + //@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off + //@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off + $blockColor = 0; + //@todo _writeCFRule() => $blockColor => Index Color for top line + //@todo _writeCFRule() => $blockColor => Index Color for bottom line + //@todo _writeCFRule() => $blockColor => Index Color for diagonal line + switch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){ + case PHPExcel_Style_Border::BORDER_NONE : $blockColor |= 0x00 << 21; break; + case PHPExcel_Style_Border::BORDER_THIN : $blockColor |= 0x01 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUM : $blockColor |= 0x02 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHED : $blockColor |= 0x03 << 21; break; + case PHPExcel_Style_Border::BORDER_DOTTED : $blockColor |= 0x04 << 21; break; + case PHPExcel_Style_Border::BORDER_THICK : $blockColor |= 0x05 << 21; break; + case PHPExcel_Style_Border::BORDER_DOUBLE : $blockColor |= 0x06 << 21; break; + case PHPExcel_Style_Border::BORDER_HAIR : $blockColor |= 0x07 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED : $blockColor |= 0x08 << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOT : $blockColor |= 0x09 << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT : $blockColor |= 0x0A << 21; break; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT : $blockColor |= 0x0B << 21; break; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT : $blockColor |= 0x0C << 21; break; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT : $blockColor |= 0x0D << 21; break; + } + $dataBlockBorder = pack('vv', $blockLineStyle, $blockColor); + } + if($bFormatFill == 1){ + // Fill Patern Style + $blockFillPatternStyle = 0; + switch ($conditional->getStyle()->getFill()->getFillType()){ + case PHPExcel_Style_Fill::FILL_NONE : $blockFillPatternStyle = 0x00; break; + case PHPExcel_Style_Fill::FILL_SOLID : $blockFillPatternStyle = 0x01; break; + case PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY : $blockFillPatternStyle = 0x02; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY : $blockFillPatternStyle = 0x03; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY : $blockFillPatternStyle = 0x04; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL : $blockFillPatternStyle = 0x05; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL : $blockFillPatternStyle = 0x06; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN : $blockFillPatternStyle = 0x07; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKUP : $blockFillPatternStyle = 0x08; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID : $blockFillPatternStyle = 0x09; break; + case PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS : $blockFillPatternStyle = 0x0A; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL : $blockFillPatternStyle = 0x0B; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL : $blockFillPatternStyle = 0x0C; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN : $blockFillPatternStyle = 0x0D; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP : $blockFillPatternStyle = 0x0E; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID : $blockFillPatternStyle = 0x0F; break; + case PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS : $blockFillPatternStyle = 0x10; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 : $blockFillPatternStyle = 0x11; break; + case PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 : $blockFillPatternStyle = 0x12; break; + case PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + case PHPExcel_Style_Fill::FILL_GRADIENT_PATH : $blockFillPatternStyle = 0x00; break; // does not exist in BIFF8 + default : $blockFillPatternStyle = 0x00; break; + } + // Color + switch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) { + case '000000': $colorIdxBg = 0x08; break; + case 'FFFFFF': $colorIdxBg = 0x09; break; + case 'FF0000': $colorIdxBg = 0x0A; break; + case '00FF00': $colorIdxBg = 0x0B; break; + case '0000FF': $colorIdxBg = 0x0C; break; + case 'FFFF00': $colorIdxBg = 0x0D; break; + case 'FF00FF': $colorIdxBg = 0x0E; break; + case '00FFFF': $colorIdxBg = 0x0F; break; + case '800000': $colorIdxBg = 0x10; break; + case '008000': $colorIdxBg = 0x11; break; + case '000080': $colorIdxBg = 0x12; break; + case '808000': $colorIdxBg = 0x13; break; + case '800080': $colorIdxBg = 0x14; break; + case '008080': $colorIdxBg = 0x15; break; + case 'C0C0C0': $colorIdxBg = 0x16; break; + case '808080': $colorIdxBg = 0x17; break; + case '9999FF': $colorIdxBg = 0x18; break; + case '993366': $colorIdxBg = 0x19; break; + case 'FFFFCC': $colorIdxBg = 0x1A; break; + case 'CCFFFF': $colorIdxBg = 0x1B; break; + case '660066': $colorIdxBg = 0x1C; break; + case 'FF8080': $colorIdxBg = 0x1D; break; + case '0066CC': $colorIdxBg = 0x1E; break; + case 'CCCCFF': $colorIdxBg = 0x1F; break; + case '000080': $colorIdxBg = 0x20; break; + case 'FF00FF': $colorIdxBg = 0x21; break; + case 'FFFF00': $colorIdxBg = 0x22; break; + case '00FFFF': $colorIdxBg = 0x23; break; + case '800080': $colorIdxBg = 0x24; break; + case '800000': $colorIdxBg = 0x25; break; + case '008080': $colorIdxBg = 0x26; break; + case '0000FF': $colorIdxBg = 0x27; break; + case '00CCFF': $colorIdxBg = 0x28; break; + case 'CCFFFF': $colorIdxBg = 0x29; break; + case 'CCFFCC': $colorIdxBg = 0x2A; break; + case 'FFFF99': $colorIdxBg = 0x2B; break; + case '99CCFF': $colorIdxBg = 0x2C; break; + case 'FF99CC': $colorIdxBg = 0x2D; break; + case 'CC99FF': $colorIdxBg = 0x2E; break; + case 'FFCC99': $colorIdxBg = 0x2F; break; + case '3366FF': $colorIdxBg = 0x30; break; + case '33CCCC': $colorIdxBg = 0x31; break; + case '99CC00': $colorIdxBg = 0x32; break; + case 'FFCC00': $colorIdxBg = 0x33; break; + case 'FF9900': $colorIdxBg = 0x34; break; + case 'FF6600': $colorIdxBg = 0x35; break; + case '666699': $colorIdxBg = 0x36; break; + case '969696': $colorIdxBg = 0x37; break; + case '003366': $colorIdxBg = 0x38; break; + case '339966': $colorIdxBg = 0x39; break; + case '003300': $colorIdxBg = 0x3A; break; + case '333300': $colorIdxBg = 0x3B; break; + case '993300': $colorIdxBg = 0x3C; break; + case '993366': $colorIdxBg = 0x3D; break; + case '333399': $colorIdxBg = 0x3E; break; + case '333333': $colorIdxBg = 0x3F; break; + default: $colorIdxBg = 0x41; break; + } + // Fg Color + switch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) { + case '000000': $colorIdxFg = 0x08; break; + case 'FFFFFF': $colorIdxFg = 0x09; break; + case 'FF0000': $colorIdxFg = 0x0A; break; + case '00FF00': $colorIdxFg = 0x0B; break; + case '0000FF': $colorIdxFg = 0x0C; break; + case 'FFFF00': $colorIdxFg = 0x0D; break; + case 'FF00FF': $colorIdxFg = 0x0E; break; + case '00FFFF': $colorIdxFg = 0x0F; break; + case '800000': $colorIdxFg = 0x10; break; + case '008000': $colorIdxFg = 0x11; break; + case '000080': $colorIdxFg = 0x12; break; + case '808000': $colorIdxFg = 0x13; break; + case '800080': $colorIdxFg = 0x14; break; + case '008080': $colorIdxFg = 0x15; break; + case 'C0C0C0': $colorIdxFg = 0x16; break; + case '808080': $colorIdxFg = 0x17; break; + case '9999FF': $colorIdxFg = 0x18; break; + case '993366': $colorIdxFg = 0x19; break; + case 'FFFFCC': $colorIdxFg = 0x1A; break; + case 'CCFFFF': $colorIdxFg = 0x1B; break; + case '660066': $colorIdxFg = 0x1C; break; + case 'FF8080': $colorIdxFg = 0x1D; break; + case '0066CC': $colorIdxFg = 0x1E; break; + case 'CCCCFF': $colorIdxFg = 0x1F; break; + case '000080': $colorIdxFg = 0x20; break; + case 'FF00FF': $colorIdxFg = 0x21; break; + case 'FFFF00': $colorIdxFg = 0x22; break; + case '00FFFF': $colorIdxFg = 0x23; break; + case '800080': $colorIdxFg = 0x24; break; + case '800000': $colorIdxFg = 0x25; break; + case '008080': $colorIdxFg = 0x26; break; + case '0000FF': $colorIdxFg = 0x27; break; + case '00CCFF': $colorIdxFg = 0x28; break; + case 'CCFFFF': $colorIdxFg = 0x29; break; + case 'CCFFCC': $colorIdxFg = 0x2A; break; + case 'FFFF99': $colorIdxFg = 0x2B; break; + case '99CCFF': $colorIdxFg = 0x2C; break; + case 'FF99CC': $colorIdxFg = 0x2D; break; + case 'CC99FF': $colorIdxFg = 0x2E; break; + case 'FFCC99': $colorIdxFg = 0x2F; break; + case '3366FF': $colorIdxFg = 0x30; break; + case '33CCCC': $colorIdxFg = 0x31; break; + case '99CC00': $colorIdxFg = 0x32; break; + case 'FFCC00': $colorIdxFg = 0x33; break; + case 'FF9900': $colorIdxFg = 0x34; break; + case 'FF6600': $colorIdxFg = 0x35; break; + case '666699': $colorIdxFg = 0x36; break; + case '969696': $colorIdxFg = 0x37; break; + case '003366': $colorIdxFg = 0x38; break; + case '339966': $colorIdxFg = 0x39; break; + case '003300': $colorIdxFg = 0x3A; break; + case '333300': $colorIdxFg = 0x3B; break; + case '993300': $colorIdxFg = 0x3C; break; + case '993366': $colorIdxFg = 0x3D; break; + case '333399': $colorIdxFg = 0x3E; break; + case '333333': $colorIdxFg = 0x3F; break; + default: $colorIdxFg = 0x40; break; + } + $dataBlockFill = pack('v', $blockFillPatternStyle); + $dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7)); + } + if($bFormatProt == 1){ + $dataBlockProtection = 0; + if($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1; + } + if($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){ + $dataBlockProtection = 1 << 1; + } + } + + $data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000); + if($bFormatFont == 1){ // Block Formatting : OK + $data .= $dataBlockFont; + } + if($bFormatAlign == 1){ + $data .= $dataBlockAlign; + } + if($bFormatBorder == 1){ + $data .= $dataBlockBorder; + } + if($bFormatFill == 1){ // Block Formatting : OK + $data .= $dataBlockFill; + } + if($bFormatProt == 1){ + $data .= $dataBlockProtection; + } + if(!is_null($operand1)){ + $data .= $operand1; + } + if(!is_null($operand2)){ + $data .= $operand2; + } + $header = pack('vv', $record, strlen($data)); + $this->_append($header . $data); + } + + /** + * Write CFHeader record + */ + private function _writeCFHeader(){ + $record = 0x01B0; // Record identifier + $length = 0x0016; // Bytes to follow + + $numColumnMin = null; + $numColumnMax = null; + $numRowMin = null; + $numRowMax = null; + $arrConditional = array(); + foreach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) { + foreach ($conditionalStyles as $conditional) { + if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION + || $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){ + if(!in_array($conditional->getHashCode(), $arrConditional)){ + $arrConditional[] = $conditional->getHashCode(); + } + // Cells + $arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate); + if(!is_numeric($arrCoord[0])){ + $arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]); + } + if(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){ + $numColumnMin = $arrCoord[0]; + } + if(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){ + $numColumnMax = $arrCoord[0]; + } + if(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){ + $numRowMin = $arrCoord[1]; + } + if(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){ + $numRowMax = $arrCoord[1]; + } + } + } + } + $needRedraw = 1; + $cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1); + + $header = pack('vv', $record, $length); + $data = pack('vv', count($arrConditional), $needRedraw); + $data .= $cellRange; + $data .= pack('v', 0x0001); + $data .= $cellRange; + $this->_append($header . $data); + } +} \ No newline at end of file diff --git a/extend/phpexcel/PHPExcel/Writer/Excel5/Xf.php b/extend/phpexcel/PHPExcel/Writer/Excel5/Xf.php new file mode 100755 index 0000000..f803f68 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Excel5/Xf.php @@ -0,0 +1,547 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + +// Original file header of PEAR::Spreadsheet_Excel_Writer_Format (used as the base for this class): +// ----------------------------------------------------------------------------------------- +// /* +// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> +// * +// * The majority of this is _NOT_ my code. I simply ported it from the +// * PERL Spreadsheet::WriteExcel module. +// * +// * The author of the Spreadsheet::WriteExcel module is John McNamara +// * <jmcnamara@cpan.org> +// * +// * I _DO_ maintain this code, and John McNamara has nothing to do with the +// * porting of this code to PHP. Any questions directly related to this +// * class library should be directed to me. +// * +// * License Information: +// * +// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets +// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com +// * +// * This library is free software; you can redistribute it and/or +// * modify it under the terms of the GNU Lesser General Public +// * License as published by the Free Software Foundation; either +// * version 2.1 of the License, or (at your option) any later version. +// * +// * This library is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// * Lesser General Public License for more details. +// * +// * You should have received a copy of the GNU Lesser General Public +// * License along with this library; if not, write to the Free Software +// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// */ + + +/** + * PHPExcel_Writer_Excel5_Xf + * + * @category PHPExcel + * @package PHPExcel_Writer_Excel5 + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Excel5_Xf +{ + /** + * Style XF or a cell XF ? + * + * @var boolean + */ + private $_isStyleXf; + + /** + * Index to the FONT record. Index 4 does not exist + * @var integer + */ + private $_fontIndex; + + /** + * An index (2 bytes) to a FORMAT record (number format). + * @var integer + */ + public $_numberFormatIndex; + + /** + * 1 bit, apparently not used. + * @var integer + */ + public $_text_justlast; + + /** + * The cell's foreground color. + * @var integer + */ + public $_fg_color; + + /** + * The cell's background color. + * @var integer + */ + public $_bg_color; + + /** + * Color of the bottom border of the cell. + * @var integer + */ + public $_bottom_color; + + /** + * Color of the top border of the cell. + * @var integer + */ + public $_top_color; + + /** + * Color of the left border of the cell. + * @var integer + */ + public $_left_color; + + /** + * Color of the right border of the cell. + * @var integer + */ + public $_right_color; + + /** + * Constructor + * + * @access public + * @param PHPExcel_Style The XF format + */ + public function __construct(PHPExcel_Style $style = null) + { + $this->_isStyleXf = false; + $this->_fontIndex = 0; + + $this->_numberFormatIndex = 0; + + $this->_text_justlast = 0; + + $this->_fg_color = 0x40; + $this->_bg_color = 0x41; + + $this->_diag = 0; + + $this->_bottom_color = 0x40; + $this->_top_color = 0x40; + $this->_left_color = 0x40; + $this->_right_color = 0x40; + $this->_diag_color = 0x40; + $this->_style = $style; + + } + + + /** + * Generate an Excel BIFF XF record (style or cell). + * + * @return string The XF record + */ + function writeXf() + { + // Set the type of the XF record and some of the attributes. + if ($this->_isStyleXf) { + $style = 0xFFF5; + } else { + $style = self::_mapLocked($this->_style->getProtection()->getLocked()); + $style |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1; + } + + // Flags to indicate if attributes have been set. + $atr_num = ($this->_numberFormatIndex != 0)?1:0; + $atr_fnt = ($this->_fontIndex != 0)?1:0; + $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0; + $atr_bdr = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) || + self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0; + $atr_pat = (($this->_fg_color != 0x40) || + ($this->_bg_color != 0x41) || + self::_mapFillType($this->_style->getFill()->getFillType()))?1:0; + $atr_prot = self::_mapLocked($this->_style->getProtection()->getLocked()) + | self::_mapHidden($this->_style->getProtection()->getHidden()); + + // Zero the default border colour if the border has not been set. + if (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) { + $this->_bottom_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) { + $this->_top_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) { + $this->_right_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) { + $this->_left_color = 0; + } + if (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) { + $this->_diag_color = 0; + } + + $record = 0x00E0; // Record identifier + $length = 0x0014; // Number of bytes to follow + + $ifnt = $this->_fontIndex; // Index to FONT record + $ifmt = $this->_numberFormatIndex; // Index to FORMAT record + + $align = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment + $align |= (int) $this->_style->getAlignment()->getWrapText() << 3; + $align |= self::_mapVAlign($this->_style->getAlignment()->getVertical()) << 4; + $align |= $this->_text_justlast << 7; + + $used_attrib = $atr_num << 2; + $used_attrib |= $atr_fnt << 3; + $used_attrib |= $atr_alc << 4; + $used_attrib |= $atr_bdr << 5; + $used_attrib |= $atr_pat << 6; + $used_attrib |= $atr_prot << 7; + + $icv = $this->_fg_color; // fg and bg pattern colors + $icv |= $this->_bg_color << 7; + + $border1 = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8; + $border1 |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12; + $border1 |= $this->_left_color << 16; + $border1 |= $this->_right_color << 23; + + $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection(); + $diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN; + $diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH + || $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP; + $border1 |= $diag_tl_to_rb << 30; + $border1 |= $diag_tr_to_lb << 31; + + $border2 = $this->_top_color; // Border color + $border2 |= $this->_bottom_color << 7; + $border2 |= $this->_diag_color << 14; + $border2 |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21; + $border2 |= self::_mapFillType($this->_style->getFill()->getFillType()) << 26; + + $header = pack("vv", $record, $length); + + //BIFF8 options: identation, shrinkToFit and text direction + $biff8_options = $this->_style->getAlignment()->getIndent(); + $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4; + + $data = pack("vvvC", $ifnt, $ifmt, $style, $align); + $data .= pack("CCC" + , self::_mapTextRotation($this->_style->getAlignment()->getTextRotation()) + , $biff8_options + , $used_attrib + ); + $data .= pack("VVv", $border1, $border2, $icv); + + return($header . $data); + } + + /** + * Is this a style XF ? + * + * @param boolean $value + */ + public function setIsStyleXf($value) + { + $this->_isStyleXf = $value; + } + + /** + * Sets the cell's bottom border color + * + * @access public + * @param int $colorIndex Color index + */ + function setBottomColor($colorIndex) + { + $this->_bottom_color = $colorIndex; + } + + /** + * Sets the cell's top border color + * + * @access public + * @param int $colorIndex Color index + */ + function setTopColor($colorIndex) + { + $this->_top_color = $colorIndex; + } + + /** + * Sets the cell's left border color + * + * @access public + * @param int $colorIndex Color index + */ + function setLeftColor($colorIndex) + { + $this->_left_color = $colorIndex; + } + + /** + * Sets the cell's right border color + * + * @access public + * @param int $colorIndex Color index + */ + function setRightColor($colorIndex) + { + $this->_right_color = $colorIndex; + } + + /** + * Sets the cell's diagonal border color + * + * @access public + * @param int $colorIndex Color index + */ + function setDiagColor($colorIndex) + { + $this->_diag_color = $colorIndex; + } + + + /** + * Sets the cell's foreground color + * + * @access public + * @param int $colorIndex Color index + */ + function setFgColor($colorIndex) + { + $this->_fg_color = $colorIndex; + } + + /** + * Sets the cell's background color + * + * @access public + * @param int $colorIndex Color index + */ + function setBgColor($colorIndex) + { + $this->_bg_color = $colorIndex; + } + + /** + * Sets the index to the number format record + * It can be date, time, currency, etc... + * + * @access public + * @param integer $numberFormatIndex Index to format record + */ + function setNumberFormatIndex($numberFormatIndex) + { + $this->_numberFormatIndex = $numberFormatIndex; + } + + /** + * Set the font index. + * + * @param int $value Font index, note that value 4 does not exist + */ + public function setFontIndex($value) + { + $this->_fontIndex = $value; + } + + /** + * Map of BIFF2-BIFF8 codes for border styles + * @static array of int + * + */ + private static $_mapBorderStyle = array ( PHPExcel_Style_Border::BORDER_NONE => 0x00, + PHPExcel_Style_Border::BORDER_THIN => 0x01, + PHPExcel_Style_Border::BORDER_MEDIUM => 0x02, + PHPExcel_Style_Border::BORDER_DASHED => 0x03, + PHPExcel_Style_Border::BORDER_DOTTED => 0x04, + PHPExcel_Style_Border::BORDER_THICK => 0x05, + PHPExcel_Style_Border::BORDER_DOUBLE => 0x06, + PHPExcel_Style_Border::BORDER_HAIR => 0x07, + PHPExcel_Style_Border::BORDER_MEDIUMDASHED => 0x08, + PHPExcel_Style_Border::BORDER_DASHDOT => 0x09, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT => 0x0A, + PHPExcel_Style_Border::BORDER_DASHDOTDOT => 0x0B, + PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT => 0x0C, + PHPExcel_Style_Border::BORDER_SLANTDASHDOT => 0x0D, + ); + + /** + * Map border style + * + * @param string $borderStyle + * @return int + */ + private static function _mapBorderStyle($borderStyle) { + if (isset(self::$_mapBorderStyle[$borderStyle])) + return self::$_mapBorderStyle[$borderStyle]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for fill types + * @static array of int + * + */ + private static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE => 0x00, + PHPExcel_Style_Fill::FILL_SOLID => 0x01, + PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY => 0x02, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY => 0x03, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY => 0x04, + PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05, + PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL => 0x06, + PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN => 0x07, + PHPExcel_Style_Fill::FILL_PATTERN_DARKUP => 0x08, + PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID => 0x09, + PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS => 0x0A, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN => 0x0D, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP => 0x0E, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID => 0x0F, + PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY125 => 0x11, + PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625 => 0x12, + PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8 + PHPExcel_Style_Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8 + ); + /** + * Map fill type + * + * @param string $fillType + * @return int + */ + private static function _mapFillType($fillType) { + if (isset(self::$_mapFillType[$fillType])) + return self::$_mapFillType[$fillType]; + return 0x00; + } + + /** + * Map of BIFF2-BIFF8 codes for horizontal alignment + * @static array of int + * + */ + private static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL => 0, + PHPExcel_Style_Alignment::HORIZONTAL_LEFT => 1, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER => 2, + PHPExcel_Style_Alignment::HORIZONTAL_RIGHT => 3, + PHPExcel_Style_Alignment::HORIZONTAL_FILL => 4, + PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY => 5, + PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6, + ); + /** + * Map to BIFF2-BIFF8 codes for horizontal alignment + * + * @param string $hAlign + * @return int + */ + private function _mapHAlign($hAlign) + { + if (isset(self::$_mapHAlign[$hAlign])) + return self::$_mapHAlign[$hAlign]; + return 0; + } + + /** + * Map of BIFF2-BIFF8 codes for vertical alignment + * @static array of int + * + */ + private static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP => 0, + PHPExcel_Style_Alignment::VERTICAL_CENTER => 1, + PHPExcel_Style_Alignment::VERTICAL_BOTTOM => 2, + PHPExcel_Style_Alignment::VERTICAL_JUSTIFY => 3, + ); + /** + * Map to BIFF2-BIFF8 codes for vertical alignment + * + * @param string $vAlign + * @return int + */ + private static function _mapVAlign($vAlign) { + if (isset(self::$_mapVAlign[$vAlign])) + return self::$_mapVAlign[$vAlign]; + return 2; + } + + /** + * Map to BIFF8 codes for text rotation angle + * + * @param int $textRotation + * @return int + */ + private static function _mapTextRotation($textRotation) { + if ($textRotation >= 0) { + return $textRotation; + } + if ($textRotation == -165) { + return 255; + } + if ($textRotation < 0) { + return 90 - $textRotation; + } + } + + /** + * Map locked + * + * @param string + * @return int + */ + private static function _mapLocked($locked) { + switch ($locked) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 1; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 1; + } + } + + /** + * Map hidden + * + * @param string + * @return int + */ + private static function _mapHidden($hidden) { + switch ($hidden) { + case PHPExcel_Style_Protection::PROTECTION_INHERIT: return 0; + case PHPExcel_Style_Protection::PROTECTION_PROTECTED: return 1; + case PHPExcel_Style_Protection::PROTECTION_UNPROTECTED: return 0; + default: return 0; + } + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/Exception.php b/extend/phpexcel/PHPExcel/Writer/Exception.php new file mode 100755 index 0000000..e8fe9be --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/Exception.php @@ -0,0 +1,52 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_Exception + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_Exception extends PHPExcel_Exception { + /** + * Error handler callback + * + * @param mixed $code + * @param mixed $string + * @param mixed $file + * @param mixed $line + * @param mixed $context + */ + public static function errorHandlerCallback($code, $string, $file, $line, $context) { + $e = new self($string, $code); + $e->line = $line; + $e->file = $file; + throw $e; + } +} diff --git a/extend/phpexcel/PHPExcel/Writer/HTML.php b/extend/phpexcel/PHPExcel/Writer/HTML.php new file mode 100755 index 0000000..0f2cc08 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/HTML.php @@ -0,0 +1,1532 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_HTML + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_HTML + * + * @category PHPExcel + * @package PHPExcel_Writer_HTML + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter { + /** + * PHPExcel object + * + * @var PHPExcel + */ + protected $_phpExcel; + + /** + * Sheet index to write + * + * @var int + */ + private $_sheetIndex = 0; + + /** + * Images root + * + * @var string + */ + private $_imagesRoot = '.'; + + /** + * embed images, or link to images + * + * @var boolean + */ + private $_embedImages = FALSE; + + /** + * Use inline CSS? + * + * @var boolean + */ + private $_useInlineCss = false; + + /** + * Array of CSS styles + * + * @var array + */ + private $_cssStyles = null; + + /** + * Array of column widths in points + * + * @var array + */ + private $_columnWidths = null; + + /** + * Default font + * + * @var PHPExcel_Style_Font + */ + private $_defaultFont; + + /** + * Flag whether spans have been calculated + * + * @var boolean + */ + private $_spansAreCalculated = false; + + /** + * Excel cells that should not be written as HTML cells + * + * @var array + */ + private $_isSpannedCell = array(); + + /** + * Excel cells that are upper-left corner in a cell merge + * + * @var array + */ + private $_isBaseCell = array(); + + /** + * Excel rows that should not be written as HTML rows + * + * @var array + */ + private $_isSpannedRow = array(); + + /** + * Is the current writer creating PDF? + * + * @var boolean + */ + protected $_isPdf = false; + + /** + * Generate the Navigation block + * + * @var boolean + */ + private $_generateSheetNavigationBlock = true; + + /** + * Create a new PHPExcel_Writer_HTML + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) { + $this->_phpExcel = $phpExcel; + $this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont(); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = null) { + // garbage collect + $this->_phpExcel->garbageCollect(); + + $saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog(); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE); + $saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Build CSS + $this->buildCSS(!$this->_useInlineCss); + + // Open file + $fileHandle = fopen($pFilename, 'wb+'); + if ($fileHandle === false) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + // Write headers + fwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss)); + + // Write navigation (tabs) + if ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) { + fwrite($fileHandle, $this->generateNavigation()); + } + + // Write data + fwrite($fileHandle, $this->generateSheetData()); + + // Write footer + fwrite($fileHandle, $this->generateHTMLFooter()); + + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($saveArrayReturnType); + PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog); + } + + /** + * Map VAlign + * + * @param string $vAlign Vertical alignment + * @return string + */ + private function _mapVAlign($vAlign) { + switch ($vAlign) { + case PHPExcel_Style_Alignment::VERTICAL_BOTTOM: return 'bottom'; + case PHPExcel_Style_Alignment::VERTICAL_TOP: return 'top'; + case PHPExcel_Style_Alignment::VERTICAL_CENTER: + case PHPExcel_Style_Alignment::VERTICAL_JUSTIFY: return 'middle'; + default: return 'baseline'; + } + } + + /** + * Map HAlign + * + * @param string $hAlign Horizontal alignment + * @return string|false + */ + private function _mapHAlign($hAlign) { + switch ($hAlign) { + case PHPExcel_Style_Alignment::HORIZONTAL_GENERAL: return false; + case PHPExcel_Style_Alignment::HORIZONTAL_LEFT: return 'left'; + case PHPExcel_Style_Alignment::HORIZONTAL_RIGHT: return 'right'; + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER: + case PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS: return 'center'; + case PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY: return 'justify'; + default: return false; + } + } + + /** + * Map border style + * + * @param int $borderStyle Sheet index + * @return string + */ + private function _mapBorderStyle($borderStyle) { + switch ($borderStyle) { + case PHPExcel_Style_Border::BORDER_NONE: return 'none'; + case PHPExcel_Style_Border::BORDER_DASHDOT: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DASHDOTDOT: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DASHED: return '1px dashed'; + case PHPExcel_Style_Border::BORDER_DOTTED: return '1px dotted'; + case PHPExcel_Style_Border::BORDER_DOUBLE: return '3px double'; + case PHPExcel_Style_Border::BORDER_HAIR: return '1px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUM: return '2px solid'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT: return '2px dotted'; + case PHPExcel_Style_Border::BORDER_MEDIUMDASHED: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_SLANTDASHDOT: return '2px dashed'; + case PHPExcel_Style_Border::BORDER_THICK: return '3px solid'; + case PHPExcel_Style_Border::BORDER_THIN: return '1px solid'; + default: return '1px solid'; // map others to thin + } + } + + /** + * Get sheet index + * + * @return int + */ + public function getSheetIndex() { + return $this->_sheetIndex; + } + + /** + * Set sheet index + * + * @param int $pValue Sheet index + * @return PHPExcel_Writer_HTML + */ + public function setSheetIndex($pValue = 0) { + $this->_sheetIndex = $pValue; + return $this; + } + + /** + * Get sheet index + * + * @return boolean + */ + public function getGenerateSheetNavigationBlock() { + return $this->_generateSheetNavigationBlock; + } + + /** + * Set sheet index + * + * @param boolean $pValue Flag indicating whether the sheet navigation block should be generated or not + * @return PHPExcel_Writer_HTML + */ + public function setGenerateSheetNavigationBlock($pValue = true) { + $this->_generateSheetNavigationBlock = (bool) $pValue; + return $this; + } + + /** + * Write all sheets (resets sheetIndex to NULL) + */ + public function writeAllSheets() { + $this->_sheetIndex = null; + return $this; + } + + /** + * Generate HTML header + * + * @param boolean $pIncludeStyles Include styles? + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateHTMLHeader($pIncludeStyles = false) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Construct HTML + $properties = $this->_phpExcel->getProperties(); + $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' . PHP_EOL; + $html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL; + $html .= '<html>' . PHP_EOL; + $html .= ' <head>' . PHP_EOL; + $html .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL; + + if ($properties->getCreator() > '') + $html .= ' <meta name="author" content="' . htmlspecialchars($properties->getCreator()) . '" />' . PHP_EOL; + if ($properties->getTitle() > '') + $html .= ' <meta name="title" content="' . htmlspecialchars($properties->getTitle()) . '" />' . PHP_EOL; + if ($properties->getDescription() > '') + $html .= ' <meta name="description" content="' . htmlspecialchars($properties->getDescription()) . '" />' . PHP_EOL; + if ($properties->getSubject() > '') + $html .= ' <meta name="subject" content="' . htmlspecialchars($properties->getSubject()) . '" />' . PHP_EOL; + if ($properties->getKeywords() > '') + $html .= ' <meta name="keywords" content="' . htmlspecialchars($properties->getKeywords()) . '" />' . PHP_EOL; + if ($properties->getCategory() > '') + $html .= ' <meta name="category" content="' . htmlspecialchars($properties->getCategory()) . '" />' . PHP_EOL; + if ($properties->getCompany() > '') + $html .= ' <meta name="company" content="' . htmlspecialchars($properties->getCompany()) . '" />' . PHP_EOL; + if ($properties->getManager() > '') + $html .= ' <meta name="manager" content="' . htmlspecialchars($properties->getManager()) . '" />' . PHP_EOL; + + if ($pIncludeStyles) { + $html .= $this->generateStyles(true); + } + + $html .= ' </head>' . PHP_EOL; + $html .= '' . PHP_EOL; + $html .= ' <body>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate sheet data + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateSheetData() { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Ensure that Spans have been calculated? + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Loop all sheets + $sheetId = 0; + foreach ($sheets as $sheet) { + // Write table header + $html .= $this->_generateTableHeader($sheet); + + // Get worksheet dimension + $dimension = explode(':', $sheet->calculateWorksheetDimension()); + $dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]); + $dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1; + $dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]); + $dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1; + + // row min,max + $rowMin = $dimension[0][1]; + $rowMax = $dimension[1][1]; + + // calculate start of <tbody>, <thead> + $tbodyStart = $rowMin; + $theadStart = $theadEnd = 0; // default: no <thead> no </thead> + if ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) { + $rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop(); + + // we can only support repeating rows that start at top row + if ($rowsToRepeatAtTop[0] == 1) { + $theadStart = $rowsToRepeatAtTop[0]; + $theadEnd = $rowsToRepeatAtTop[1]; + $tbodyStart = $rowsToRepeatAtTop[1] + 1; + } + } + + // Loop through cells + $row = $rowMin-1; + while($row++ < $rowMax) { + // <thead> ? + if ($row == $theadStart) { + $html .= ' <thead>' . PHP_EOL; + } + + // <tbody> ? + if ($row == $tbodyStart) { + $html .= ' <tbody>' . PHP_EOL; + } + + // Write row if there are HTML table cells in it + if ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) { + // Start a new rowData + $rowData = array(); + // Loop through columns + $column = $dimension[0][0] - 1; + while($column++ < $dimension[1][0]) { + // Cell exists? + if ($sheet->cellExistsByColumnAndRow($column, $row)) { + $rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row; + } else { + $rowData[$column] = ''; + } + } + $html .= $this->_generateRow($sheet, $rowData, $row - 1); + } + + // </thead> ? + if ($row == $theadEnd) { + $html .= ' </thead>' . PHP_EOL; + } + } + $html .= $this->_extendRowsForChartsAndImages($sheet, $row); + + // Close table body. + $html .= ' </tbody>' . PHP_EOL; + + // Write table footer + $html .= $this->_generateTableFooter(); + + // Writing PDF? + if ($this->_isPdf) { + if (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) { + $html .= '<div style="page-break-before:always" />'; + } + } + + // Next sheet + ++$sheetId; + } + + // Return + return $html; + } + + /** + * Generate sheet tabs + * + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateNavigation() + { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Construct HTML + $html = ''; + + // Only if there are more than 1 sheets + if (count($sheets) > 1) { + // Loop all sheets + $sheetId = 0; + + $html .= '<ul class="navigation">' . PHP_EOL; + + foreach ($sheets as $sheet) { + $html .= ' <li class="sheet' . $sheetId . '"><a href="#sheet' . $sheetId . '">' . $sheet->getTitle() . '</a></li>' . PHP_EOL; + ++$sheetId; + } + + $html .= '</ul>' . PHP_EOL; + } + + return $html; + } + + private function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) { + $rowMax = $row; + $colMax = 'A'; + if ($this->_includeCharts) { + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']); + $chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]); + if ($chartTL[1] > $rowMax) { + $rowMax = $chartTL[1]; + if ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $chartTL[0]; + } + } + } + } + } + + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates()); + $imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]); + if ($imageTL[1] > $rowMax) { + $rowMax = $imageTL[1]; + if ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) { + $colMax = $imageTL[0]; + } + } + } + } + $html = ''; + $colMax++; + while ($row < $rowMax) { + $html .= '<tr>'; + for ($col = 'A'; $col != $colMax; ++$col) { + $html .= '<td>'; + $html .= $this->_writeImageInCell($pSheet, $col.$row); + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $col.$row); + } + $html .= '</td>'; + } + ++$row; + $html .= '</tr>'; + } + return $html; + } + + + /** + * Generate image tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write images + foreach ($pSheet->getDrawingCollection() as $drawing) { + if ($drawing instanceof PHPExcel_Worksheet_Drawing) { + if ($drawing->getCoordinates() == $coordinates) { + $filename = $drawing->getPath(); + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.') { + $filename = substr($filename, 1); + } + + // Prepend images root + $filename = $this->getImagesRoot() . $filename; + + // Strip off eventual '.' + if (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') { + $filename = substr($filename, 1); + } + + // Convert UTF8 data to PCDATA + $filename = htmlspecialchars($filename); + + $html .= PHP_EOL; + if ((!$this->_embedImages) || ($this->_isPdf)) { + $imageData = $filename; + } else { + $imageDetails = getimagesize($filename); + if ($fp = fopen($filename,"rb", 0)) { + $picture = fread($fp,filesize($filename)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + } else { + $imageData = $filename; + } + } + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . + $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . + $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;" src="' . + $imageData . '" border="0" />'; + $html .= '</div>'; + } + } + } + + // Return + return $html; + } + + /** + * Generate chart tag in cell + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param string $coordinates Cell coordinates + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) { + // Construct HTML + $html = ''; + + // Write charts + foreach ($pSheet->getChartCollection() as $chart) { + if ($chart instanceof PHPExcel_Chart) { + $chartCoordinates = $chart->getTopLeftPosition(); + if ($chartCoordinates['cell'] == $coordinates) { + $chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png'; + if (!$chart->render($chartFileName)) { + return; + } + + $html .= PHP_EOL; + $imageDetails = getimagesize($chartFileName); + if ($fp = fopen($chartFileName,"rb", 0)) { + $picture = fread($fp,filesize($chartFileName)); + fclose($fp); + // base64 encode the binary data, then break it + // into chunks according to RFC 2045 semantics + $base64 = chunk_split(base64_encode($picture)); + $imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64; + + $html .= '<div style="position: relative;">'; + $html .= '<img style="position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;" src="' . $imageData . '" border="0" />' . PHP_EOL; + $html .= '</div>'; + + unlink($chartFileName); + } + } + } + } + + // Return + return $html; + } + + /** + * Generate CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML tags? (<style> and </style>) + * @return string + * @throws PHPExcel_Writer_Exception + */ + public function generateStyles($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Build CSS + $css = $this->buildCSS($generateSurroundingHTML); + + // Construct HTML + $html = ''; + + // Start styles + if ($generateSurroundingHTML) { + $html .= ' <style type="text/css">' . PHP_EOL; + $html .= ' html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL; + } + + // Write all other styles + foreach ($css as $styleName => $styleDefinition) { + if ($styleName != 'html') { + $html .= ' ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL; + } + } + + // End styles + if ($generateSurroundingHTML) { + $html .= ' </style>' . PHP_EOL; + } + + // Return + return $html; + } + + /** + * Build CSS styles + * + * @param boolean $generateSurroundingHTML Generate surrounding HTML style? (html { }) + * @return array + * @throws PHPExcel_Writer_Exception + */ + public function buildCSS($generateSurroundingHTML = true) { + // PHPExcel object known? + if (is_null($this->_phpExcel)) { + throw new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.'); + } + + // Cached? + if (!is_null($this->_cssStyles)) { + return $this->_cssStyles; + } + + // Ensure that spans have been calculated + if (!$this->_spansAreCalculated) { + $this->_calculateSpans(); + } + + // Construct CSS + $css = array(); + + // Start styles + if ($generateSurroundingHTML) { + // html { } + $css['html']['font-family'] = 'Calibri, Arial, Helvetica, sans-serif'; + $css['html']['font-size'] = '11pt'; + $css['html']['background-color'] = 'white'; + } + + + // table { } + $css['table']['border-collapse'] = 'collapse'; + if (!$this->_isPdf) { + $css['table']['page-break-after'] = 'always'; + } + + // .gridlines td { } + $css['.gridlines td']['border'] = '1px dotted black'; + + // .b {} + $css['.b']['text-align'] = 'center'; // BOOL + + // .e {} + $css['.e']['text-align'] = 'center'; // ERROR + + // .f {} + $css['.f']['text-align'] = 'right'; // FORMULA + + // .inlineStr {} + $css['.inlineStr']['text-align'] = 'left'; // INLINE + + // .n {} + $css['.n']['text-align'] = 'right'; // NUMERIC + + // .s {} + $css['.s']['text-align'] = 'left'; // STRING + + // Calculate cell style hashes + foreach ($this->_phpExcel->getCellXfCollection() as $index => $style) { + $css['td.style' . $index] = $this->_createCSSStyle( $style ); + } + + // Fetch sheets + $sheets = array(); + if (is_null($this->_sheetIndex)) { + $sheets = $this->_phpExcel->getAllSheets(); + } else { + $sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex); + } + + // Build styles per sheet + foreach ($sheets as $sheet) { + // Calculate hash code + $sheetIndex = $sheet->getParent()->getIndex($sheet); + + // Build styles + // Calculate column widths + $sheet->calculateColumnWidths(); + + // col elements, initialize + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1; + $column = -1; + while($column++ < $highestColumnIndex) { + $this->_columnWidths[$sheetIndex][$column] = 42; // approximation + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt'; + } + + // col elements, loop through columnDimensions and set width + foreach ($sheet->getColumnDimensions() as $columnDimension) { + if (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) { + $width = PHPExcel_Shared_Drawing::pixelsToPoints($width); + $column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1; + $this->_columnWidths[$sheetIndex][$column] = $width; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt'; + + if ($columnDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse'; + $css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7 + } + } + } + + // Default row height + $rowDimension = $sheet->getDefaultRowDimension(); + + // table.sheetN tr { } + $css['table.sheet' . $sheetIndex . ' tr'] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr']['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden'; + } + + // Calculate row heights + foreach ($sheet->getRowDimensions() as $rowDimension) { + $row = $rowDimension->getRowIndex() - 1; + + // table.sheetN tr.rowYYYYYY { } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array(); + + if ($rowDimension->getRowHeight() == -1) { + $pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont()); + } else { + $pt_height = $rowDimension->getRowHeight(); + } + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt'; + if ($rowDimension->getVisible() === false) { + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none'; + $css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden'; + } + } + } + + // Cache + if (is_null($this->_cssStyles)) { + $this->_cssStyles = $css; + } + + // Return + return $css; + } + + /** + * Create CSS style + * + * @param PHPExcel_Style $pStyle PHPExcel_Style + * @return array + */ + private function _createCSSStyle(PHPExcel_Style $pStyle) { + // Construct CSS + $css = ''; + + // Create CSS + $css = array_merge( + $this->_createCSSStyleAlignment($pStyle->getAlignment()) + , $this->_createCSSStyleBorders($pStyle->getBorders()) + , $this->_createCSSStyleFont($pStyle->getFont()) + , $this->_createCSSStyleFill($pStyle->getFill()) + ); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Alignment) + * + * @param PHPExcel_Style_Alignment $pStyle PHPExcel_Style_Alignment + * @return array + */ + private function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical()); + if ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) { + $css['text-align'] = $textAlign; + if(in_array($textAlign,array('left','right'))) + $css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px'; + } + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Font) + * + * @param PHPExcel_Style_Font $pStyle PHPExcel_Style_Font + * @return array + */ + private function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + if ($pStyle->getBold()) { + $css['font-weight'] = 'bold'; + } + if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) { + $css['text-decoration'] = 'underline line-through'; + } else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) { + $css['text-decoration'] = 'underline'; + } else if ($pStyle->getStrikethrough()) { + $css['text-decoration'] = 'line-through'; + } + if ($pStyle->getItalic()) { + $css['font-style'] = 'italic'; + } + + $css['color'] = '#' . $pStyle->getColor()->getRGB(); + $css['font-family'] = '\'' . $pStyle->getName() . '\''; + $css['font-size'] = $pStyle->getSize() . 'pt'; + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Borders) + * + * @param PHPExcel_Style_Borders $pStyle PHPExcel_Style_Borders + * @return array + */ + private function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) { + // Construct CSS + $css = array(); + + // Create CSS + $css['border-bottom'] = $this->_createCSSStyleBorder($pStyle->getBottom()); + $css['border-top'] = $this->_createCSSStyleBorder($pStyle->getTop()); + $css['border-left'] = $this->_createCSSStyleBorder($pStyle->getLeft()); + $css['border-right'] = $this->_createCSSStyleBorder($pStyle->getRight()); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Border) + * + * @param PHPExcel_Style_Border $pStyle PHPExcel_Style_Border + * @return string + */ + private function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) { + // Create CSS +// $css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB(); + // Create CSS - add !important to non-none border styles for merged cells + $borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle()); + $css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); + + // Return + return $css; + } + + /** + * Create CSS style (PHPExcel_Style_Fill) + * + * @param PHPExcel_Style_Fill $pStyle PHPExcel_Style_Fill + * @return array + */ + private function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) { + // Construct HTML + $css = array(); + + // Create CSS + $value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ? + 'white' : '#' . $pStyle->getStartColor()->getRGB(); + $css['background-color'] = $value; + + // Return + return $css; + } + + /** + * Generate HTML footer + */ + public function generateHTMLFooter() { + // Construct HTML + $html = ''; + $html .= ' </body>' . PHP_EOL; + $html .= '</html>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate table header + * + * @param PHPExcel_Worksheet $pSheet The worksheet for the table we are writing + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableHeader($pSheet) { + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // Construct HTML + $html = ''; + $html .= $this->_setMargins($pSheet); + + if (!$this->_useInlineCss) { + $gridlines = $pSheet->getShowGridlines() ? ' gridlines' : ''; + $html .= ' <table border="0" cellpadding="0" cellspacing="0" id="sheet' . $sheetIndex . '" class="sheet' . $sheetIndex . $gridlines . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table']) ? + $this->_assembleCSS($this->_cssStyles['table']) : ''; + + if ($this->_isPdf && $pSheet->getShowGridlines()) { + $html .= ' <table border="1" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="1" style="' . $style . '">' . PHP_EOL; + } else { + $html .= ' <table border="0" cellpadding="1" id="sheet' . $sheetIndex . '" cellspacing="0" style="' . $style . '">' . PHP_EOL; + } + } + + // Write <col> elements + $highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1; + $i = -1; + while($i++ < $highestColumnIndex) { + if (!$this->_isPdf) { + if (!$this->_useInlineCss) { + $html .= ' <col class="col' . $i . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ? + $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : ''; + $html .= ' <col style="' . $style . '">' . PHP_EOL; + } + } + } + + // Return + return $html; + } + + /** + * Generate table footer + * + * @throws PHPExcel_Writer_Exception + */ + private function _generateTableFooter() { + // Construct HTML + $html = ''; + $html .= ' </table>' . PHP_EOL; + + // Return + return $html; + } + + /** + * Generate row + * + * @param PHPExcel_Worksheet $pSheet PHPExcel_Worksheet + * @param array $pValues Array containing cells in a row + * @param int $pRow Row number (0-based) + * @return string + * @throws PHPExcel_Writer_Exception + */ + private function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0) { + if (is_array($pValues)) { + // Construct HTML + $html = ''; + + // Sheet index + $sheetIndex = $pSheet->getParent()->getIndex($pSheet); + + // DomPDF and breaks + if ($this->_isPdf && count($pSheet->getBreaks()) > 0) { + $breaks = $pSheet->getBreaks(); + + // check if a break is needed before this row + if (isset($breaks['A' . $pRow])) { + // close table: </table> + $html .= $this->_generateTableFooter(); + + // insert page break + $html .= '<div style="page-break-before:always" />'; + + // open table again: <table> + <col> etc. + $html .= $this->_generateTableHeader($pSheet); + } + } + + // Write row start + if (!$this->_useInlineCss) { + $html .= ' <tr class="row' . $pRow . '">' . PHP_EOL; + } else { + $style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) + ? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : ''; + + $html .= ' <tr style="' . $style . '">' . PHP_EOL; + } + + // Write cells + $colNum = 0; + foreach ($pValues as $cellAddress) { + $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : ''; + $coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1); + if (!$this->_useInlineCss) { + $cssClass = ''; + $cssClass = 'column' . $colNum; + } else { + $cssClass = array(); + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) { + $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum]; + } + } + $colSpan = 1; + $rowSpan = 1; + + // initialize + $cellData = '&nbsp;'; + + // PHPExcel_Cell + if ($cell instanceof PHPExcel_Cell) { + $cellData = ''; + if (is_null($cell->getParent())) { + $cell->attach($pSheet); + } + // Value + if ($cell->getValue() instanceof PHPExcel_RichText) { + // Loop through rich text elements + $elements = $cell->getValue()->getRichTextElements(); + foreach ($elements as $element) { + // Rich text start? + if ($element instanceof PHPExcel_RichText_Run) { + $cellData .= '<span style="' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '">'; + + if ($element->getFont()->getSuperScript()) { + $cellData .= '<sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '<sub>'; + } + } + + // Convert UTF8 data to PCDATA + $cellText = $element->getText(); + $cellData .= htmlspecialchars($cellText); + + if ($element instanceof PHPExcel_RichText_Run) { + if ($element->getFont()->getSuperScript()) { + $cellData .= '</sup>'; + } else if ($element->getFont()->getSubScript()) { + $cellData .= '</sub>'; + } + + $cellData .= '</span>'; + } + } + } else { + if ($this->_preCalculateFormulas) { + $cellData = PHPExcel_Style_NumberFormat::toFormattedString( + $cell->getCalculatedValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } else { + $cellData = PHPExcel_Style_NumberFormat::ToFormattedString( + $cell->getValue(), + $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(), + array($this, 'formatColor') + ); + } + $cellData = htmlspecialchars($cellData); + if ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) { + $cellData = '<sup>'.$cellData.'</sup>'; + } elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) { + $cellData = '<sub>'.$cellData.'</sub>'; + } + } + + // Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp; + // Example: " Hello\n to the world" is converted to "&nbsp;&nbsp;Hello\n&nbsp;to the world" + $cellData = preg_replace("/(?m)(?:^|\\G) /", '&nbsp;', $cellData); + + // convert newline "\n" to '<br>' + $cellData = nl2br($cellData); + + // Extend CSS class? + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $cell->getXfIndex(); + $cssClass .= ' ' . $cell->getDataType(); + } else { + if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) { + $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]); + } + + // General horizontal alignment: Actual horizontal alignment depends on dataType + $sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() ); + if ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL + && isset($this->_cssStyles['.' . $cell->getDataType()]['text-align'])) + { + $cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align']; + } + } + } + + // Hyperlink? + if ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) { + $cellData = '<a href="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '" title="' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '">' . $cellData . '</a>'; + } + + // Should the cell be written or is it swallowed by a rowspan or colspan? + $writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]) + && $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] ); + + // Colspan and Rowspan + $colspan = 1; + $rowspan = 1; + if (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) { + $spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum]; + $rowSpan = $spans['rowspan']; + $colSpan = $spans['colspan']; + + // Also apply style from last cell in merge to fix borders - + // relies on !important for non-none border declarations in _createCSSStyleBorder + $endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan); + if (!$this->_useInlineCss) { + $cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex(); + } + } + + // Write + if ($writeCell) { + // Column start + $html .= ' <td'; + if (!$this->_useInlineCss) { + $html .= ' class="' . $cssClass . '"'; + } else { + //** Necessary redundant code for the sake of PHPExcel_Writer_PDF ** + // We must explicitly write the width of the <td> element because TCPDF + // does not recognize e.g. <col style="width:42pt"> + $width = 0; + $i = $colNum - 1; + $e = $colNum + $colSpan - 1; + while($i++ < $e) { + if (isset($this->_columnWidths[$sheetIndex][$i])) { + $width += $this->_columnWidths[$sheetIndex][$i]; + } + } + $cssClass['width'] = $width . 'pt'; + + // We must also explicitly write the height of the <td> element because TCPDF + // does not recognize e.g. <tr style="height:50pt"> + if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) { + $height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height']; + $cssClass['height'] = $height; + } + //** end of redundant code ** + + $html .= ' style="' . $this->_assembleCSS($cssClass) . '"'; + } + if ($colSpan > 1) { + $html .= ' colspan="' . $colSpan . '"'; + } + if ($rowSpan > 1) { + $html .= ' rowspan="' . $rowSpan . '"'; + } + $html .= '>'; + + // Image? + $html .= $this->_writeImageInCell($pSheet, $coordinate); + + // Chart? + if ($this->_includeCharts) { + $html .= $this->_writeChartInCell($pSheet, $coordinate); + } + + // Cell data + $html .= $cellData; + + // Column end + $html .= '</td>' . PHP_EOL; + } + + // Next column + ++$colNum; + } + + // Write row end + $html .= ' </tr>' . PHP_EOL; + + // Return + return $html; + } else { + throw new PHPExcel_Writer_Exception("Invalid parameters passed."); + } + } + + /** + * Takes array where of CSS properties / values and converts to CSS string + * + * @param array + * @return string + */ + private function _assembleCSS($pValue = array()) + { + $pairs = array(); + foreach ($pValue as $property => $value) { + $pairs[] = $property . ':' . $value; + } + $string = implode('; ', $pairs); + + return $string; + } + + /** + * Get images root + * + * @return string + */ + public function getImagesRoot() { + return $this->_imagesRoot; + } + + /** + * Set images root + * + * @param string $pValue + * @return PHPExcel_Writer_HTML + */ + public function setImagesRoot($pValue = '.') { + $this->_imagesRoot = $pValue; + return $this; + } + + /** + * Get embed images + * + * @return boolean + */ + public function getEmbedImages() { + return $this->_embedImages; + } + + /** + * Set embed images + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setEmbedImages($pValue = '.') { + $this->_embedImages = $pValue; + return $this; + } + + /** + * Get use inline CSS? + * + * @return boolean + */ + public function getUseInlineCss() { + return $this->_useInlineCss; + } + + /** + * Set use inline CSS? + * + * @param boolean $pValue + * @return PHPExcel_Writer_HTML + */ + public function setUseInlineCss($pValue = false) { + $this->_useInlineCss = $pValue; + return $this; + } + + /** + * Add color to formatted string as inline style + * + * @param string $pValue Plain formatted value without color + * @param string $pFormat Format code + * @return string + */ + public function formatColor($pValue, $pFormat) + { + // Color information, e.g. [Red] is always at the beginning + $color = null; // initialize + $matches = array(); + + $color_regex = '/^\\[[a-zA-Z]+\\]/'; + if (preg_match($color_regex, $pFormat, $matches)) { + $color = str_replace('[', '', $matches[0]); + $color = str_replace(']', '', $color); + $color = strtolower($color); + } + + // convert to PCDATA + $value = htmlspecialchars($pValue); + + // color span tag + if ($color !== null) { + $value = '<span style="color:' . $color . '">' . $value . '</span>'; + } + + return $value; + } + + /** + * Calculate information about HTML colspan and rowspan which is not always the same as Excel's + */ + private function _calculateSpans() + { + // Identify all cells that should be omitted in HTML due to cell merge. + // In HTML only the upper-left cell should be written and it should have + // appropriate rowspan / colspan attribute + $sheetIndexes = $this->_sheetIndex !== null ? + array($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1); + + foreach ($sheetIndexes as $sheetIndex) { + $sheet = $this->_phpExcel->getSheet($sheetIndex); + + $candidateSpannedRow = array(); + + // loop through all Excel merged cells + foreach ($sheet->getMergeCells() as $cells) { + list($cells, ) = PHPExcel_Cell::splitRange($cells); + $first = $cells[0]; + $last = $cells[1]; + + list($fc, $fr) = PHPExcel_Cell::coordinateFromString($first); + $fc = PHPExcel_Cell::columnIndexFromString($fc) - 1; + + list($lc, $lr) = PHPExcel_Cell::coordinateFromString($last); + $lc = PHPExcel_Cell::columnIndexFromString($lc) - 1; + + // loop through the individual cells in the individual merge + $r = $fr - 1; + while($r++ < $lr) { + // also, flag this row as a HTML row that is candidate to be omitted + $candidateSpannedRow[$r] = $r; + + $c = $fc - 1; + while($c++ < $lc) { + if ( !($c == $fc && $r == $fr) ) { + // not the upper-left cell (should not be written in HTML) + $this->_isSpannedCell[$sheetIndex][$r][$c] = array( + 'baseCell' => array($fr, $fc), + ); + } else { + // upper-left is the base cell that should hold the colspan/rowspan attribute + $this->_isBaseCell[$sheetIndex][$r][$c] = array( + 'xlrowspan' => $lr - $fr + 1, // Excel rowspan + 'rowspan' => $lr - $fr + 1, // HTML rowspan, value may change + 'xlcolspan' => $lc - $fc + 1, // Excel colspan + 'colspan' => $lc - $fc + 1, // HTML colspan, value may change + ); + } + } + } + } + + // Identify which rows should be omitted in HTML. These are the rows where all the cells + // participate in a merge and the where base cells are somewhere above. + $countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()); + foreach ($candidateSpannedRow as $rowIndex) { + if (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) { + if (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) { + $this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex; + }; + } + } + + // For each of the omitted rows we found above, the affected rowspans should be subtracted by 1 + if ( isset($this->_isSpannedRow[$sheetIndex]) ) { + foreach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) { + $adjustedBaseCells = array(); + $c = -1; + $e = $countColumns - 1; + while($c++ < $e) { + $baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell']; + + if ( !in_array($baseCell, $adjustedBaseCells) ) { + // subtract rowspan by 1 + --$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan']; + $adjustedBaseCells[] = $baseCell; + } + } + } + } + + // TODO: Same for columns + } + + // We have calculated the spans + $this->_spansAreCalculated = true; + } + + private function _setMargins(PHPExcel_Worksheet $pSheet) { + $htmlPage = '@page { '; + $htmlBody = 'body { '; + + $left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; '; + $htmlPage .= 'left-margin: ' . $left; + $htmlBody .= 'left-margin: ' . $left; + $right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; '; + $htmlPage .= 'right-margin: ' . $right; + $htmlBody .= 'right-margin: ' . $right; + $top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; '; + $htmlPage .= 'top-margin: ' . $top; + $htmlBody .= 'top-margin: ' . $top; + $bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; '; + $htmlPage .= 'bottom-margin: ' . $bottom; + $htmlBody .= 'bottom-margin: ' . $bottom; + + $htmlPage .= "}\n"; + $htmlBody .= "}\n"; + + return "<style>\n" . $htmlPage . $htmlBody . "</style>\n"; + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/IWriter.php b/extend/phpexcel/PHPExcel/Writer/IWriter.php new file mode 100755 index 0000000..6974c93 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/IWriter.php @@ -0,0 +1,46 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_IWriter + * + * @category PHPExcel + * @package PHPExcel_Writer + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +interface PHPExcel_Writer_IWriter +{ + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL); + +} diff --git a/extend/phpexcel/PHPExcel/Writer/PDF.php b/extend/phpexcel/PHPExcel/Writer/PDF.php new file mode 100755 index 0000000..65fb50e --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/PDF.php @@ -0,0 +1,90 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_PDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF +{ + + /** + * The wrapper for the requested PDF rendering engine + * + * @var PHPExcel_Writer_PDF_Core + */ + private $_renderer = NULL; + + /** + * Instantiate a new renderer of the configured type within this container class + * + * @param PHPExcel $phpExcel PHPExcel object + * @throws PHPExcel_Writer_Exception when PDF library is not configured + */ + public function __construct(PHPExcel $phpExcel) + { + $pdfLibraryName = PHPExcel_Settings::getPdfRendererName(); + if (is_null($pdfLibraryName)) { + throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); + } + + $pdfLibraryPath = PHPExcel_Settings::getPdfRendererPath(); + if (is_null($pdfLibraryName)) { + throw new PHPExcel_Writer_Exception("PDF Rendering library path has not been defined."); + } + $includePath = str_replace('\\', '/', get_include_path()); + $rendererPath = str_replace('\\', '/', $pdfLibraryPath); + if (strpos($rendererPath, $includePath) === false) { + set_include_path(get_include_path() . PATH_SEPARATOR . $pdfLibraryPath); + } + + $rendererName = 'PHPExcel_Writer_PDF_' . $pdfLibraryName; + $this->_renderer = new $rendererName($phpExcel); + } + + + /** + * Magic method to handle direct calls to the configured PDF renderer wrapper class. + * + * @param string $name Renderer library method name + * @param mixed[] $arguments Array of arguments to pass to the renderer method + * @return mixed Returned data from the PDF renderer wrapper method + */ + public function __call($name, $arguments) + { + if ($this->_renderer === NULL) { + throw new PHPExcel_Writer_Exception("PDF Rendering library has not been defined."); + } + + return call_user_func_array(array($this->_renderer, $name), $arguments); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/PDF/Core.php b/extend/phpexcel/PHPExcel/Writer/PDF/Core.php new file mode 100755 index 0000000..3b281f4 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/PDF/Core.php @@ -0,0 +1,364 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** + * PHPExcel_Writer_PDF_Core + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +abstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML +{ + /** + * Temporary storage directory + * + * @var string + */ + protected $_tempDir = ''; + + /** + * Font + * + * @var string + */ + protected $_font = 'freesans'; + + /** + * Orientation (Over-ride) + * + * @var string + */ + protected $_orientation = NULL; + + /** + * Paper size (Over-ride) + * + * @var int + */ + protected $_paperSize = NULL; + + + /** + * Temporary storage for Save Array Return type + * + * @var string + */ + private $_saveArrayReturnType; + + /** + * Paper Sizes xRef List + * + * @var array + */ + protected static $_paperSizes = array( + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_SMALL + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID + => array(792.00, 1224.00), // (11 in. by 17 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEDGER + => array(1224.00, 792.00), // (17 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL + => 'LEGAL', // (8.5 in. by 14 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STATEMENT + => array(396.00, 612.00), // (5.5 in. by 8.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_EXECUTIVE + => 'EXECUTIVE', // (7.25 in. by 10.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3 + => 'A3', // (297 mm by 420 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4 + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_SMALL + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5 + => 'A5', // (148 mm by 210 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4 + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5 + => 'B5', // (176 mm by 250 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_FOLIO + => 'FOLIO', // (8.5 in. by 13 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_QUARTO + => array(609.45, 779.53), // (215 mm by 275 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_1 + => array(720.00, 1008.00), // (10 in. by 14 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_2 + => array(792.00, 1224.00), // (11 in. by 17 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NOTE + => 'LETTER', // (8.5 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO9_ENVELOPE + => array(279.00, 639.00), // (3.875 in. by 8.875 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO10_ENVELOPE + => array(297.00, 684.00), // (4.125 in. by 9.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO11_ENVELOPE + => array(324.00, 747.00), // (4.5 in. by 10.375 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO12_ENVELOPE + => array(342.00, 792.00), // (4.75 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO14_ENVELOPE + => array(360.00, 828.00), // (5 in. by 11.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C + => array(1224.00, 1584.00), // (17 in. by 22 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_D + => array(1584.00, 2448.00), // (22 in. by 34 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_E + => array(2448.00, 3168.00), // (34 in. by 44 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_DL_ENVELOPE + => array(311.81, 623.62), // (110 mm by 220 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C5_ENVELOPE + => 'C5', // (162 mm by 229 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C3_ENVELOPE + => 'C3', // (324 mm by 458 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C4_ENVELOPE + => 'C4', // (229 mm by 324 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C6_ENVELOPE + => 'C6', // (114 mm by 162 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_C65_ENVELOPE + => array(323.15, 649.13), // (114 mm by 229 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4_ENVELOPE + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5_ENVELOPE + => 'B5', // (176 mm by 250 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_B6_ENVELOPE + => array(498.90, 354.33), // (176 mm by 125 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ITALY_ENVELOPE + => array(311.81, 651.97), // (110 mm by 230 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_MONARCH_ENVELOPE + => array(279.00, 540.00), // (3.875 in. by 7.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_6_3_4_ENVELOPE + => array(261.00, 468.00), // (3.625 in. by 6.5 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_US_STANDARD_FANFOLD + => array(1071.00, 792.00), // (14.875 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_STANDARD_FANFOLD + => array(612.00, 864.00), // (8.5 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_LEGAL_FANFOLD + => 'FOLIO', // (8.5 in. by 13 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B4 + => 'B4', // (250 mm by 353 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_JAPANESE_DOUBLE_POSTCARD + => array(566.93, 419.53), // (200 mm by 148 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_1 + => array(648.00, 792.00), // (9 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_2 + => array(720.00, 792.00), // (10 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_3 + => array(1080.00, 792.00), // (15 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_INVITE_ENVELOPE + => array(623.62, 623.62), // (220 mm by 220 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_PAPER + => array(667.80, 864.00), // (9.275 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL_EXTRA_PAPER + => array(667.80, 1080.00), // (9.275 in. by 15 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID_EXTRA_PAPER + => array(841.68, 1296.00), // (11.69 in. by 18 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_EXTRA_PAPER + => array(668.98, 912.76), // (236 mm by 322 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_TRANSVERSE_PAPER + => array(595.80, 792.00), // (8.275 in. by 11 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_TRANSVERSE_PAPER + => 'A4', // (210 mm by 297 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER + => array(667.80, 864.00), // (9.275 in. by 12 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERA_SUPERA_A4_PAPER + => array(643.46, 1009.13), // (227 mm by 356 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERB_SUPERB_A3_PAPER + => array(864.57, 1380.47), // (305 mm by 487 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_PLUS_PAPER + => array(612.00, 913.68), // (8.5 in. by 12.69 in.) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_PLUS_PAPER + => array(595.28, 935.43), // (210 mm by 330 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_TRANSVERSE_PAPER + => 'A5', // (148 mm by 210 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_JIS_B5_TRANSVERSE_PAPER + => array(515.91, 728.50), // (182 mm by 257 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_PAPER + => array(912.76, 1261.42), // (322 mm by 445 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_EXTRA_PAPER + => array(493.23, 666.14), // (174 mm by 235 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B5_EXTRA_PAPER + => array(569.76, 782.36), // (201 mm by 276 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A2_PAPER + => 'A2', // (420 mm by 594 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_TRANSVERSE_PAPER + => 'A3', // (297 mm by 420 mm) + PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER + => array(912.76, 1261.42) // (322 mm by 445 mm) + ); + + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + $this->setUseInlineCss(TRUE); + $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir(); + } + + /** + * Get Font + * + * @return string + */ + public function getFont() + { + return $this->_font; + } + + /** + * Set font. Examples: + * 'arialunicid0-chinese-simplified' + * 'arialunicid0-chinese-traditional' + * 'arialunicid0-korean' + * 'arialunicid0-japanese' + * + * @param string $fontName + */ + public function setFont($fontName) + { + $this->_font = $fontName; + return $this; + } + + /** + * Get Paper Size + * + * @return int + */ + public function getPaperSize() + { + return $this->_paperSize; + } + + /** + * Set Paper Size + * + * @param string $pValue Paper size + * @return PHPExcel_Writer_PDF + */ + public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) + { + $this->_paperSize = $pValue; + return $this; + } + + /** + * Get Orientation + * + * @return string + */ + public function getOrientation() + { + return $this->_orientation; + } + + /** + * Set Orientation + * + * @param string $pValue Page orientation + * @return PHPExcel_Writer_PDF + */ + public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + { + $this->_orientation = $pValue; + return $this; + } + + /** + * Get temporary storage directory + * + * @return string + */ + public function getTempDir() + { + return $this->_tempDir; + } + + /** + * Set temporary storage directory + * + * @param string $pValue Temporary storage directory + * @throws PHPExcel_Writer_Exception when directory does not exist + * @return PHPExcel_Writer_PDF + */ + public function setTempDir($pValue = '') + { + if (is_dir($pValue)) { + $this->_tempDir = $pValue; + } else { + throw new PHPExcel_Writer_Exception("Directory does not exist: $pValue"); + } + return $this; + } + + /** + * Save PHPExcel to PDF file, pre-save + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + protected function prepareForSave($pFilename = NULL) + { + // garbage collect + $this->_phpExcel->garbageCollect(); + + $this->_saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType(); + PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE); + + // Open file + $fileHandle = fopen($pFilename, 'w'); + if ($fileHandle === FALSE) { + throw new PHPExcel_Writer_Exception("Could not open file $pFilename for writing."); + } + + // Set PDF + $this->_isPdf = TRUE; + // Build CSS + $this->buildCSS(TRUE); + + return $fileHandle; + } + + /** + * Save PHPExcel to PDF file, post-save + * + * @param resource $fileHandle + * @throws PHPExcel_Writer_Exception + */ + protected function restoreStateAfterSave($fileHandle) + { + // Close file + fclose($fileHandle); + + PHPExcel_Calculation::setArrayReturnType($this->_saveArrayReturnType); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/PDF/DomPDF.php b/extend/phpexcel/PHPExcel/Writer/PDF/DomPDF.php new file mode 100755 index 0000000..111dd36 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/PDF/DomPDF.php @@ -0,0 +1,120 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require DomPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/dompdf_config.inc.php'; +if (file_exists($pdfRendererClassFile)) { + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_DomPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT + : $this->getOrientation(); + } + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + $orientation = ($orientation == 'L') ? 'landscape' : 'portrait'; + + // Create PDF + $pdf = new DOMPDF(); + $pdf->set_paper(strtolower($paperSize), $orientation); + + $pdf->load_html( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + $pdf->render(); + + // Write to file + fwrite($fileHandle, $pdf->output()); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/PDF/mPDF.php b/extend/phpexcel/PHPExcel/Writer/PDF/mPDF.php new file mode 100755 index 0000000..8e274f4 --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/PDF/mPDF.php @@ -0,0 +1,130 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require mPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/mpdf.php'; +if (file_exists($pdfRendererClassFile)) { + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_mPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + $this->setOrientation($orientation); + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) + ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT + : $this->getOrientation(); + } + $orientation = strtoupper($orientation); + + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + // Create PDF + $pdf = new mpdf(); + $ortmp = $orientation; + $pdf->_setPageSize(strtoupper($paperSize), $ortmp); + $pdf->DefOrientation = $orientation; + $pdf->AddPage($orientation); + + // Document info + $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + + $pdf->WriteHTML( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + + // Write to file + fwrite($fileHandle, $pdf->Output('', 'S')); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/extend/phpexcel/PHPExcel/Writer/PDF/tcPDF.php b/extend/phpexcel/PHPExcel/Writer/PDF/tcPDF.php new file mode 100755 index 0000000..c3809ec --- /dev/null +++ b/extend/phpexcel/PHPExcel/Writer/PDF/tcPDF.php @@ -0,0 +1,136 @@ +<?php +/** + * PHPExcel + * + * Copyright (c) 2006 - 2014 PHPExcel + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL + * @version 1.8.0, 2014-03-02 + */ + + +/** Require tcPDF library */ +$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/tcpdf.php'; +if (file_exists($pdfRendererClassFile)) { + $k_path_url = PHPExcel_Settings::getPdfRendererPath(); + require_once $pdfRendererClassFile; +} else { + throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library'); +} + +/** + * PHPExcel_Writer_PDF_tcPDF + * + * @category PHPExcel + * @package PHPExcel_Writer_PDF + * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel) + */ +class PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter +{ + /** + * Create a new PHPExcel_Writer_PDF + * + * @param PHPExcel $phpExcel PHPExcel object + */ + public function __construct(PHPExcel $phpExcel) + { + parent::__construct($phpExcel); + } + + /** + * Save PHPExcel to file + * + * @param string $pFilename Name of the file to save as + * @throws PHPExcel_Writer_Exception + */ + public function save($pFilename = NULL) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (is_null($this->getSheetIndex())) { + $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins(); + } else { + $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins(); + } + + // Override Page Orientation + if (!is_null($this->getOrientation())) { + $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) + ? 'L' + : 'P'; + } + // Override Paper Size + if (!is_null($this->getPaperSize())) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$_paperSizes[$printPaperSize])) { + $paperSize = self::$_paperSizes[$printPaperSize]; + } + + + // Create PDF + $pdf = new TCPDF($orientation, 'pt', $paperSize); + $pdf->setFontSubsetting(FALSE); + // Set margins, converting inches to points (using 72 dpi) + $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72); + $pdf->SetAutoPageBreak(TRUE, $printMargins->getBottom() * 72); + + $pdf->setPrintHeader(FALSE); + $pdf->setPrintFooter(FALSE); + + $pdf->AddPage(); + + // Set the appropriate font + $pdf->SetFont($this->getFont()); + $pdf->writeHTML( + $this->generateHTMLHeader(FALSE) . + $this->generateSheetData() . + $this->generateHTMLFooter() + ); + + // Document info + $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle()); + $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator()); + $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject()); + $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords()); + $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator()); + + // Write to file + fwrite($fileHandle, $pdf->output($pFilename, 'S')); + + parent::restoreStateAfterSave($fileHandle); + } + +} diff --git a/extend/phpexcel/PHPExcel/locale/bg/config b/extend/phpexcel/PHPExcel/locale/bg/config new file mode 100755 index 0000000..d7ecb2b --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/bg/config @@ -0,0 +1,49 @@ +## +## PHPExcel +## + +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = лв + + +## +## Excel Error Codes (For future use) + +## +NULL = #ПРАЗНО! +DIV0 = #ДЕЛ/0! +VALUE = #СТОЙНОСТ! +REF = #РЕФ! +NAME = #ИМЕ? +NUM = #ЧИСЛО! +NA = #Н/Д diff --git a/extend/phpexcel/PHPExcel/locale/cs/config b/extend/phpexcel/PHPExcel/locale/cs/config new file mode 100755 index 0000000..af4589b --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/cs/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = Kč + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #HODNOTA! +REF = #REF! +NAME = #NÁZEV? +NUM = #NUM! +NA = #N/A diff --git a/extend/phpexcel/PHPExcel/locale/cs/functions b/extend/phpexcel/PHPExcel/locale/cs/functions new file mode 100755 index 0000000..f324759 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/cs/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funkce doplňků a automatizace +## +GETPIVOTDATA = ZÍSKATKONTDATA ## Vrátí data uložená v kontingenční tabulce. Pomocí funkce ZÍSKATKONTDATA můžete načíst souhrnná data z kontingenční tabulky, pokud jsou tato data v kontingenční sestavě zobrazena. + + +## +## Cube functions Funkce pro práci s krychlemi +## +CUBEKPIMEMBER = CUBEKPIMEMBER ## Vrátí název, vlastnost a velikost klíčového ukazatele výkonu (KUV) a zobrazí v buňce název a vlastnost. Klíčový ukazatel výkonu je kvantifikovatelná veličina, například hrubý měsíční zisk nebo čtvrtletní obrat na zaměstnance, která se používá pro sledování výkonnosti organizace. +CUBEMEMBER = CUBEMEMBER ## Vrátí člen nebo n-tici v hierarchii krychle. Slouží k ověření, zda v krychli existuje člen nebo n-tice. +CUBEMEMBERPROPERTY = CUBEMEMBERPROPERTY ## Vrátí hodnotu vlastnosti člena v krychli. Slouží k ověření, zda v krychli existuje člen s daným názvem, a k vrácení konkrétní vlastnosti tohoto člena. +CUBERANKEDMEMBER = CUBERANKEDMEMBER ## Vrátí n-tý nebo pořadový člen sady. Použijte ji pro vrácení jednoho nebo více prvků sady, například obchodníka s nejvyšším obratem nebo deseti nejlepších studentů. +CUBESET = CUBESET ## Definuje vypočtenou sadu členů nebo n-tic odesláním výrazu sady do krychle na serveru, který vytvoří sadu a potom ji vrátí do aplikace Microsoft Office Excel. +CUBESETCOUNT = CUBESETCOUNT ## Vrátí počet položek v množině +CUBEVALUE = CUBEVALUE ## Vrátí úhrnnou hodnotu z krychle. + + +## +## Database functions Funkce databáze +## +DAVERAGE = DPRŮMĚR ## Vrátí průměr vybraných položek databáze. +DCOUNT = DPOČET ## Spočítá buňky databáze obsahující čísla. +DCOUNTA = DPOČET2 ## Spočítá buňky databáze, které nejsou prázdné. +DGET = DZÍSKAT ## Extrahuje z databáze jeden záznam splňující zadaná kritéria. +DMAX = DMAX ## Vrátí maximální hodnotu z vybraných položek databáze. +DMIN = DMIN ## Vrátí minimální hodnotu z vybraných položek databáze. +DPRODUCT = DSOUČIN ## Vynásobí hodnoty určitého pole záznamů v databázi, které splňují daná kritéria. +DSTDEV = DSMODCH.VÝBĚR ## Odhadne směrodatnou odchylku výběru vybraných položek databáze. +DSTDEVP = DSMODCH ## Vypočte směrodatnou odchylku základního souboru vybraných položek databáze. +DSUM = DSUMA ## Sečte čísla ve sloupcovém poli záznamů databáze, která splňují daná kritéria. +DVAR = DVAR.VÝBĚR ## Odhadne rozptyl výběru vybraných položek databáze. +DVARP = DVAR ## Vypočte rozptyl základního souboru vybraných položek databáze. + + +## +## Date and time functions Funkce data a času +## +DATE = DATUM ## Vrátí pořadové číslo určitého data. +DATEVALUE = DATUMHODN ## Převede datum ve formě textu na pořadové číslo. +DAY = DEN ## Převede pořadové číslo na den v měsíci. +DAYS360 = ROK360 ## Vrátí počet dní mezi dvěma daty na základě roku s 360 dny. +EDATE = EDATE ## Vrátí pořadové číslo data, které označuje určený počet měsíců před nebo po počátečním datu. +EOMONTH = EOMONTH ## Vrátí pořadové číslo posledního dne měsíce před nebo po zadaném počtu měsíců. +HOUR = HODINA ## Převede pořadové číslo na hodinu. +MINUTE = MINUTA ## Převede pořadové číslo na minutu. +MONTH = MĚSÍC ## Převede pořadové číslo na měsíc. +NETWORKDAYS = NETWORKDAYS ## Vrátí počet celých pracovních dní mezi dvěma daty. +NOW = NYNÍ ## Vrátí pořadové číslo aktuálního data a času. +SECOND = SEKUNDA ## Převede pořadové číslo na sekundu. +TIME = ČAS ## Vrátí pořadové číslo určitého času. +TIMEVALUE = ČASHODN ## Převede čas ve formě textu na pořadové číslo. +TODAY = DNES ## Vrátí pořadové číslo dnešního data. +WEEKDAY = DENTÝDNE ## Převede pořadové číslo na den v týdnu. +WEEKNUM = WEEKNUM ## Převede pořadové číslo na číslo představující číselnou pozici týdne v roce. +WORKDAY = WORKDAY ## Vrátí pořadové číslo data před nebo po zadaném počtu pracovních dní. +YEAR = ROK ## Převede pořadové číslo na rok. +YEARFRAC = YEARFRAC ## Vrátí část roku vyjádřenou zlomkem a představující počet celých dní mezi počátečním a koncovým datem. + + +## +## Engineering functions Inženýrské funkce (Technické funkce) +## +BESSELI = BESSELI ## Vrátí modifikovanou Besselovu funkci In(x). +BESSELJ = BESSELJ ## Vrátí modifikovanou Besselovu funkci Jn(x). +BESSELK = BESSELK ## Vrátí modifikovanou Besselovu funkci Kn(x). +BESSELY = BESSELY ## Vrátí Besselovu funkci Yn(x). +BIN2DEC = BIN2DEC ## Převede binární číslo na desítkové. +BIN2HEX = BIN2HEX ## Převede binární číslo na šestnáctkové. +BIN2OCT = BIN2OCT ## Převede binární číslo na osmičkové. +COMPLEX = COMPLEX ## Převede reálnou a imaginární část na komplexní číslo. +CONVERT = CONVERT ## Převede číslo do jiného jednotkového měrného systému. +DEC2BIN = DEC2BIN ## Převede desítkového čísla na dvojkové +DEC2HEX = DEC2HEX ## Převede desítkové číslo na šestnáctkové. +DEC2OCT = DEC2OCT ## Převede desítkové číslo na osmičkové. +DELTA = DELTA ## Testuje rovnost dvou hodnot. +ERF = ERF ## Vrátí chybovou funkci. +ERFC = ERFC ## Vrátí doplňkovou chybovou funkci. +GESTEP = GESTEP ## Testuje, zda je číslo větší než mezní hodnota. +HEX2BIN = HEX2BIN ## Převede šestnáctkové číslo na binární. +HEX2DEC = HEX2DEC ## Převede šestnáctkové číslo na desítkové. +HEX2OCT = HEX2OCT ## Převede šestnáctkové číslo na osmičkové. +IMABS = IMABS ## Vrátí absolutní hodnotu (modul) komplexního čísla. +IMAGINARY = IMAGINARY ## Vrátí imaginární část komplexního čísla. +IMARGUMENT = IMARGUMENT ## Vrátí argument théta, úhel vyjádřený v radiánech. +IMCONJUGATE = IMCONJUGATE ## Vrátí komplexně sdružené číslo ke komplexnímu číslu. +IMCOS = IMCOS ## Vrátí kosinus komplexního čísla. +IMDIV = IMDIV ## Vrátí podíl dvou komplexních čísel. +IMEXP = IMEXP ## Vrátí exponenciální tvar komplexního čísla. +IMLN = IMLN ## Vrátí přirozený logaritmus komplexního čísla. +IMLOG10 = IMLOG10 ## Vrátí dekadický logaritmus komplexního čísla. +IMLOG2 = IMLOG2 ## Vrátí logaritmus komplexního čísla při základu 2. +IMPOWER = IMPOWER ## Vrátí komplexní číslo umocněné na celé číslo. +IMPRODUCT = IMPRODUCT ## Vrátí součin komplexních čísel. +IMREAL = IMREAL ## Vrátí reálnou část komplexního čísla. +IMSIN = IMSIN ## Vrátí sinus komplexního čísla. +IMSQRT = IMSQRT ## Vrátí druhou odmocninu komplexního čísla. +IMSUB = IMSUB ## Vrátí rozdíl mezi dvěma komplexními čísly. +IMSUM = IMSUM ## Vrátí součet dvou komplexních čísel. +OCT2BIN = OCT2BIN ## Převede osmičkové číslo na binární. +OCT2DEC = OCT2DEC ## Převede osmičkové číslo na desítkové. +OCT2HEX = OCT2HEX ## Převede osmičkové číslo na šestnáctkové. + + +## +## Financial functions Finanční funkce +## +ACCRINT = ACCRINT ## Vrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen v pravidelných termínech. +ACCRINTM = ACCRINTM ## Vrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen k datu splatnosti. +AMORDEGRC = AMORDEGRC ## Vrátí lineární amortizaci v každém účetním období pomocí koeficientu amortizace. +AMORLINC = AMORLINC ## Vrátí lineární amortizaci v každém účetním období. +COUPDAYBS = COUPDAYBS ## Vrátí počet dnů od začátku období placení kupónů do data splatnosti. +COUPDAYS = COUPDAYS ## Vrátí počet dnů v období placení kupónů, které obsahuje den zúčtování. +COUPDAYSNC = COUPDAYSNC ## Vrátí počet dnů od data zúčtování do následujícího data placení kupónu. +COUPNCD = COUPNCD ## Vrátí následující datum placení kupónu po datu zúčtování. +COUPNUM = COUPNUM ## Vrátí počet kupónů splatných mezi datem zúčtování a datem splatnosti. +COUPPCD = COUPPCD ## Vrátí předchozí datum placení kupónu před datem zúčtování. +CUMIPMT = CUMIPMT ## Vrátí kumulativní úrok splacený mezi dvěma obdobími. +CUMPRINC = CUMPRINC ## Vrátí kumulativní jistinu splacenou mezi dvěma obdobími půjčky. +DB = ODPIS.ZRYCH ## Vrátí odpis aktiva za určité období pomocí degresivní metody odpisu s pevným zůstatkem. +DDB = ODPIS.ZRYCH2 ## Vrátí odpis aktiva za určité období pomocí dvojité degresivní metody odpisu nebo jiné metody, kterou zadáte. +DISC = DISC ## Vrátí diskontní sazbu cenného papíru. +DOLLARDE = DOLLARDE ## Převede částku v korunách vyjádřenou zlomkem na částku v korunách vyjádřenou desetinným číslem. +DOLLARFR = DOLLARFR ## Převede částku v korunách vyjádřenou desetinným číslem na částku v korunách vyjádřenou zlomkem. +DURATION = DURATION ## Vrátí roční dobu cenného papíru s pravidelnými úrokovými sazbami. +EFFECT = EFFECT ## Vrátí efektivní roční úrokovou sazbu. +FV = BUDHODNOTA ## Vrátí budoucí hodnotu investice. +FVSCHEDULE = FVSCHEDULE ## Vrátí budoucí hodnotu počáteční jistiny po použití série sazeb složitého úroku. +INTRATE = INTRATE ## Vrátí úrokovou sazbu plně investovaného cenného papíru. +IPMT = PLATBA.ÚROK ## Vrátí výšku úroku investice za dané období. +IRR = MÍRA.VÝNOSNOSTI ## Vrátí vnitřní výnosové procento série peněžních toků. +ISPMT = ISPMT ## Vypočte výši úroku z investice zaplaceného během určitého období. +MDURATION = MDURATION ## Vrátí Macauleyho modifikovanou dobu cenného papíru o nominální hodnotě 100 Kč. +MIRR = MOD.MÍRA.VÝNOSNOSTI ## Vrátí vnitřní sazbu výnosu, přičemž kladné a záporné hodnoty peněžních prostředků jsou financovány podle různých sazeb. +NOMINAL = NOMINAL ## Vrátí nominální roční úrokovou sazbu. +NPER = POČET.OBDOBÍ ## Vrátí počet období pro investici. +NPV = ČISTÁ.SOUČHODNOTA ## Vrátí čistou současnou hodnotu investice vypočítanou na základě série pravidelných peněžních toků a diskontní sazby. +ODDFPRICE = ODDFPRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným prvním obdobím. +ODDFYIELD = ODDFYIELD ## Vrátí výnos cenného papíru s odlišným prvním obdobím. +ODDLPRICE = ODDLPRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným posledním obdobím. +ODDLYIELD = ODDLYIELD ## Vrátí výnos cenného papíru s odlišným posledním obdobím. +PMT = PLATBA ## Vrátí hodnotu pravidelné splátky anuity. +PPMT = PLATBA.ZÁKLAD ## Vrátí hodnotu splátky jistiny pro zadanou investici za dané období. +PRICE = PRICE ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen v pravidelných termínech. +PRICEDISC = PRICEDISC ## Vrátí cenu diskontního cenného papíru o nominální hodnotě 100 Kč. +PRICEMAT = PRICEMAT ## Vrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen k datu splatnosti. +PV = SOUČHODNOTA ## Vrátí současnou hodnotu investice. +RATE = ÚROKOVÁ.MÍRA ## Vrátí úrokovou sazbu vztaženou na období anuity. +RECEIVED = RECEIVED ## Vrátí částku obdrženou k datu splatnosti plně investovaného cenného papíru. +SLN = ODPIS.LIN ## Vrátí přímé odpisy aktiva pro jedno období. +SYD = ODPIS.NELIN ## Vrátí směrné číslo ročních odpisů aktiva pro zadané období. +TBILLEQ = TBILLEQ ## Vrátí výnos směnky státní pokladny ekvivalentní výnosu obligace. +TBILLPRICE = TBILLPRICE ## Vrátí cenu směnky státní pokladny o nominální hodnotě 100 Kč. +TBILLYIELD = TBILLYIELD ## Vrátí výnos směnky státní pokladny. +VDB = ODPIS.ZA.INT ## Vrátí odpis aktiva pro určité období nebo část období pomocí degresivní metody odpisu. +XIRR = XIRR ## Vrátí vnitřní výnosnost pro harmonogram peněžních toků, který nemusí být nutně periodický. +XNPV = XNPV ## Vrátí čistou současnou hodnotu pro harmonogram peněžních toků, který nemusí být nutně periodický. +YIELD = YIELD ## Vrátí výnos cenného papíru, ze kterého je úrok placen v pravidelných termínech. +YIELDDISC = YIELDDISC ## Vrátí roční výnos diskontního cenného papíru, například směnky státní pokladny. +YIELDMAT = YIELDMAT ## Vrátí roční výnos cenného papíru, ze kterého je úrok placen k datu splatnosti. + + +## +## Information functions Informační funkce +## +CELL = POLÍČKO ## Vrátí informace o formátování, umístění nebo obsahu buňky. +ERROR.TYPE = CHYBA.TYP ## Vrátí číslo odpovídající typu chyby. +INFO = O.PROSTŘEDÍ ## Vrátí informace o aktuálním pracovním prostředí. +ISBLANK = JE.PRÁZDNÉ ## Vrátí hodnotu PRAVDA, pokud se argument hodnota odkazuje na prázdnou buňku. +ISERR = JE.CHYBA ## Vrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota (kromě #N/A). +ISERROR = JE.CHYBHODN ## Vrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota. +ISEVEN = ISEVEN ## Vrátí hodnotu PRAVDA, pokud je číslo sudé. +ISLOGICAL = JE.LOGHODN ## Vrátí hodnotu PRAVDA, pokud je argument hodnota logická hodnota. +ISNA = JE.NEDEF ## Vrátí hodnotu PRAVDA, pokud je argument hodnota chybová hodnota #N/A. +ISNONTEXT = JE.NETEXT ## Vrátí hodnotu PRAVDA, pokud argument hodnota není text. +ISNUMBER = JE.ČÍSLO ## Vrátí hodnotu PRAVDA, pokud je argument hodnota číslo. +ISODD = ISODD ## Vrátí hodnotu PRAVDA, pokud je číslo liché. +ISREF = JE.ODKAZ ## Vrátí hodnotu PRAVDA, pokud je argument hodnota odkaz. +ISTEXT = JE.TEXT ## Vrátí hodnotu PRAVDA, pokud je argument hodnota text. +N = N ## Vrátí hodnotu převedenou na číslo. +NA = NEDEF ## Vrátí chybovou hodnotu #N/A. +TYPE = TYP ## Vrátí číslo označující datový typ hodnoty. + + +## +## Logical functions Logické funkce +## +AND = A ## Vrátí hodnotu PRAVDA, mají-li všechny argumenty hodnotu PRAVDA. +FALSE = NEPRAVDA ## Vrátí logickou hodnotu NEPRAVDA. +IF = KDYŽ ## Určí, který logický test má proběhnout. +IFERROR = IFERROR ## Pokud je vzorec vyhodnocen jako chyba, vrátí zadanou hodnotu. V opačném případě vrátí výsledek vzorce. +NOT = NE ## Provede logickou negaci argumentu funkce. +OR = NEBO ## Vrátí hodnotu PRAVDA, je-li alespoň jeden argument roven hodnotě PRAVDA. +TRUE = PRAVDA ## Vrátí logickou hodnotu PRAVDA. + + +## +## Lookup and reference functions Vyhledávací funkce +## +ADDRESS = ODKAZ ## Vrátí textový odkaz na jednu buňku listu. +AREAS = POČET.BLOKŮ ## Vrátí počet oblastí v odkazu. +CHOOSE = ZVOLIT ## Zvolí hodnotu ze seznamu hodnot. +COLUMN = SLOUPEC ## Vrátí číslo sloupce odkazu. +COLUMNS = SLOUPCE ## Vrátí počet sloupců v odkazu. +HLOOKUP = VVYHLEDAT ## Prohledá horní řádek matice a vrátí hodnotu určené buňky. +HYPERLINK = HYPERTEXTOVÝ.ODKAZ ## Vytvoří zástupce nebo odkaz, který otevře dokument uložený na síťovém serveru, v síti intranet nebo Internet. +INDEX = INDEX ## Pomocí rejstříku zvolí hodnotu z odkazu nebo matice. +INDIRECT = NEPŘÍMÝ.ODKAZ ## Vrátí odkaz určený textovou hodnotou. +LOOKUP = VYHLEDAT ## Vyhledá hodnoty ve vektoru nebo matici. +MATCH = POZVYHLEDAT ## Vyhledá hodnoty v odkazu nebo matici. +OFFSET = POSUN ## Vrátí posun odkazu od zadaného odkazu. +ROW = ŘÁDEK ## Vrátí číslo řádku odkazu. +ROWS = ŘÁDKY ## Vrátí počet řádků v odkazu. +RTD = RTD ## Načte data reálného času z programu, který podporuje automatizaci modelu COM (Automatizace: Způsob práce s objekty určité aplikace z jiné aplikace nebo nástroje pro vývoj. Automatizace (dříve nazývaná automatizace OLE) je počítačovým standardem a je funkcí modelu COM (Component Object Model).). +TRANSPOSE = TRANSPOZICE ## Vrátí transponovanou matici. +VLOOKUP = SVYHLEDAT ## Prohledá první sloupec matice, přesune kurzor v řádku a vrátí hodnotu buňky. + + +## +## Math and trigonometry functions Matematické a trigonometrické funkce +## +ABS = ABS ## Vrátí absolutní hodnotu čísla. +ACOS = ARCCOS ## Vrátí arkuskosinus čísla. +ACOSH = ARCCOSH ## Vrátí hyperbolický arkuskosinus čísla. +ASIN = ARCSIN ## Vrátí arkussinus čísla. +ASINH = ARCSINH ## Vrátí hyperbolický arkussinus čísla. +ATAN = ARCTG ## Vrátí arkustangens čísla. +ATAN2 = ARCTG2 ## Vrátí arkustangens x-ové a y-ové souřadnice. +ATANH = ARCTGH ## Vrátí hyperbolický arkustangens čísla. +CEILING = ZAOKR.NAHORU ## Zaokrouhlí číslo na nejbližší celé číslo nebo na nejbližší násobek zadané hodnoty. +COMBIN = KOMBINACE ## Vrátí počet kombinací pro daný počet položek. +COS = COS ## Vrátí kosinus čísla. +COSH = COSH ## Vrátí hyperbolický kosinus čísla. +DEGREES = DEGREES ## Převede radiány na stupně. +EVEN = ZAOKROUHLIT.NA.SUDÉ ## Zaokrouhlí číslo nahoru na nejbližší celé sudé číslo. +EXP = EXP ## Vrátí základ přirozeného logaritmu e umocněný na zadané číslo. +FACT = FAKTORIÁL ## Vrátí faktoriál čísla. +FACTDOUBLE = FACTDOUBLE ## Vrátí dvojitý faktoriál čísla. +FLOOR = ZAOKR.DOLŮ ## Zaokrouhlí číslo dolů, směrem k nule. +GCD = GCD ## Vrátí největší společný dělitel. +INT = CELÁ.ČÁST ## Zaokrouhlí číslo dolů na nejbližší celé číslo. +LCM = LCM ## Vrátí nejmenší společný násobek. +LN = LN ## Vrátí přirozený logaritmus čísla. +LOG = LOGZ ## Vrátí logaritmus čísla při zadaném základu. +LOG10 = LOG ## Vrátí dekadický logaritmus čísla. +MDETERM = DETERMINANT ## Vrátí determinant matice. +MINVERSE = INVERZE ## Vrátí inverzní matici. +MMULT = SOUČIN.MATIC ## Vrátí součin dvou matic. +MOD = MOD ## Vrátí zbytek po dělení. +MROUND = MROUND ## Vrátí číslo zaokrouhlené na požadovaný násobek. +MULTINOMIAL = MULTINOMIAL ## Vrátí mnohočlen z množiny čísel. +ODD = ZAOKROUHLIT.NA.LICHÉ ## Zaokrouhlí číslo nahoru na nejbližší celé liché číslo. +PI = PI ## Vrátí hodnotu čísla pí. +POWER = POWER ## Umocní číslo na zadanou mocninu. +PRODUCT = SOUČIN ## Vynásobí argumenty funkce. +QUOTIENT = QUOTIENT ## Vrátí celou část dělení. +RADIANS = RADIANS ## Převede stupně na radiány. +RAND = NÁHČÍSLO ## Vrátí náhodné číslo mezi 0 a 1. +RANDBETWEEN = RANDBETWEEN ## Vrátí náhodné číslo mezi zadanými čísly. +ROMAN = ROMAN ## Převede arabskou číslici na římskou ve formátu textu. +ROUND = ZAOKROUHLIT ## Zaokrouhlí číslo na zadaný počet číslic. +ROUNDDOWN = ROUNDDOWN ## Zaokrouhlí číslo dolů, směrem k nule. +ROUNDUP = ROUNDUP ## Zaokrouhlí číslo nahoru, směrem od nuly. +SERIESSUM = SERIESSUM ## Vrátí součet mocninné řady určené podle vzorce. +SIGN = SIGN ## Vrátí znaménko čísla. +SIN = SIN ## Vrátí sinus daného úhlu. +SINH = SINH ## Vrátí hyperbolický sinus čísla. +SQRT = ODMOCNINA ## Vrátí kladnou druhou odmocninu. +SQRTPI = SQRTPI ## Vrátí druhou odmocninu výrazu (číslo * pí). +SUBTOTAL = SUBTOTAL ## Vrátí souhrn v seznamu nebo databázi. +SUM = SUMA ## Sečte argumenty funkce. +SUMIF = SUMIF ## Sečte buňky vybrané podle zadaných kritérií. +SUMIFS = SUMIFS ## Sečte buňky určené více zadanými podmínkami. +SUMPRODUCT = SOUČIN.SKALÁRNÍ ## Vrátí součet součinů odpovídajících prvků matic. +SUMSQ = SUMA.ČTVERCŮ ## Vrátí součet čtverců argumentů. +SUMX2MY2 = SUMX2MY2 ## Vrátí součet rozdílu čtverců odpovídajících hodnot ve dvou maticích. +SUMX2PY2 = SUMX2PY2 ## Vrátí součet součtu čtverců odpovídajících hodnot ve dvou maticích. +SUMXMY2 = SUMXMY2 ## Vrátí součet čtverců rozdílů odpovídajících hodnot ve dvou maticích. +TAN = TGTG ## Vrátí tangens čísla. +TANH = TGH ## Vrátí hyperbolický tangens čísla. +TRUNC = USEKNOUT ## Zkrátí číslo na celé číslo. + + +## +## Statistical functions Statistické funkce +## +AVEDEV = PRŮMODCHYLKA ## Vrátí průměrnou hodnotu absolutních odchylek datových bodů od jejich střední hodnoty. +AVERAGE = PRŮMĚR ## Vrátí průměrnou hodnotu argumentů. +AVERAGEA = AVERAGEA ## Vrátí průměrnou hodnotu argumentů včetně čísel, textu a logických hodnot. +AVERAGEIF = AVERAGEIF ## Vrátí průměrnou hodnotu (aritmetický průměr) všech buněk v oblasti, které vyhovují příslušné podmínce. +AVERAGEIFS = AVERAGEIFS ## Vrátí průměrnou hodnotu (aritmetický průměr) všech buněk vyhovujících několika podmínkám. +BETADIST = BETADIST ## Vrátí hodnotu součtového rozdělení beta. +BETAINV = BETAINV ## Vrátí inverzní hodnotu součtového rozdělení pro zadané rozdělení beta. +BINOMDIST = BINOMDIST ## Vrátí hodnotu binomického rozdělení pravděpodobnosti jednotlivých veličin. +CHIDIST = CHIDIST ## Vrátí jednostrannou pravděpodobnost rozdělení chí-kvadrát. +CHIINV = CHIINV ## Vrátí hodnotu funkce inverzní k distribuční funkci jednostranné pravděpodobnosti rozdělení chí-kvadrát. +CHITEST = CHITEST ## Vrátí test nezávislosti. +CONFIDENCE = CONFIDENCE ## Vrátí interval spolehlivosti pro střední hodnotu základního souboru. +CORREL = CORREL ## Vrátí korelační koeficient mezi dvěma množinami dat. +COUNT = POČET ## Vrátí počet čísel v seznamu argumentů. +COUNTA = POČET2 ## Vrátí počet hodnot v seznamu argumentů. +COUNTBLANK = COUNTBLANK ## Spočítá počet prázdných buněk v oblasti. +COUNTIF = COUNTIF ## Spočítá buňky v oblasti, které odpovídají zadaným kritériím. +COUNTIFS = COUNTIFS ## Spočítá buňky v oblasti, které odpovídají více kritériím. +COVAR = COVAR ## Vrátí hodnotu kovariance, průměrnou hodnotu součinů párových odchylek +CRITBINOM = CRITBINOM ## Vrátí nejmenší hodnotu, pro kterou má součtové binomické rozdělení hodnotu větší nebo rovnu hodnotě kritéria. +DEVSQ = DEVSQ ## Vrátí součet čtverců odchylek. +EXPONDIST = EXPONDIST ## Vrátí hodnotu exponenciálního rozdělení. +FDIST = FDIST ## Vrátí hodnotu rozdělení pravděpodobnosti F. +FINV = FINV ## Vrátí hodnotu inverzní funkce k distribuční funkci rozdělení F. +FISHER = FISHER ## Vrátí hodnotu Fisherovy transformace. +FISHERINV = FISHERINV ## Vrátí hodnotu inverzní funkce k Fisherově transformaci. +FORECAST = FORECAST ## Vrátí hodnotu lineárního trendu. +FREQUENCY = ČETNOSTI ## Vrátí četnost rozdělení jako svislou matici. +FTEST = FTEST ## Vrátí výsledek F-testu. +GAMMADIST = GAMMADIST ## Vrátí hodnotu rozdělení gama. +GAMMAINV = GAMMAINV ## Vrátí hodnotu inverzní funkce k distribuční funkci součtového rozdělení gama. +GAMMALN = GAMMALN ## Vrátí přirozený logaritmus funkce gama, Γ(x). +GEOMEAN = GEOMEAN ## Vrátí geometrický průměr. +GROWTH = LOGLINTREND ## Vrátí hodnoty exponenciálního trendu. +HARMEAN = HARMEAN ## Vrátí harmonický průměr. +HYPGEOMDIST = HYPGEOMDIST ## Vrátí hodnotu hypergeometrického rozdělení. +INTERCEPT = INTERCEPT ## Vrátí úsek lineární regresní čáry. +KURT = KURT ## Vrátí hodnotu excesu množiny dat. +LARGE = LARGE ## Vrátí k-tou největší hodnotu množiny dat. +LINEST = LINREGRESE ## Vrátí parametry lineárního trendu. +LOGEST = LOGLINREGRESE ## Vrátí parametry exponenciálního trendu. +LOGINV = LOGINV ## Vrátí inverzní funkci k distribuční funkci logaritmicko-normálního rozdělení. +LOGNORMDIST = LOGNORMDIST ## Vrátí hodnotu součtového logaritmicko-normálního rozdělení. +MAX = MAX ## Vrátí maximální hodnotu seznamu argumentů. +MAXA = MAXA ## Vrátí maximální hodnotu seznamu argumentů včetně čísel, textu a logických hodnot. +MEDIAN = MEDIAN ## Vrátí střední hodnotu zadaných čísel. +MIN = MIN ## Vrátí minimální hodnotu seznamu argumentů. +MINA = MINA ## Vrátí nejmenší hodnotu v seznamu argumentů včetně čísel, textu a logických hodnot. +MODE = MODE ## Vrátí hodnotu, která se v množině dat vyskytuje nejčastěji. +NEGBINOMDIST = NEGBINOMDIST ## Vrátí hodnotu negativního binomického rozdělení. +NORMDIST = NORMDIST ## Vrátí hodnotu normálního součtového rozdělení. +NORMINV = NORMINV ## Vrátí inverzní funkci k funkci normálního součtového rozdělení. +NORMSDIST = NORMSDIST ## Vrátí hodnotu standardního normálního součtového rozdělení. +NORMSINV = NORMSINV ## Vrátí inverzní funkci k funkci standardního normálního součtového rozdělení. +PEARSON = PEARSON ## Vrátí Pearsonův výsledný momentový korelační koeficient. +PERCENTILE = PERCENTIL ## Vrátí hodnotu k-tého percentilu hodnot v oblasti. +PERCENTRANK = PERCENTRANK ## Vrátí pořadí hodnoty v množině dat vyjádřené procentuální částí množiny dat. +PERMUT = PERMUTACE ## Vrátí počet permutací pro zadaný počet objektů. +POISSON = POISSON ## Vrátí hodnotu distribuční funkce Poissonova rozdělení. +PROB = PROB ## Vrátí pravděpodobnost výskytu hodnot v oblasti mezi dvěma mezními hodnotami. +QUARTILE = QUARTIL ## Vrátí hodnotu kvartilu množiny dat. +RANK = RANK ## Vrátí pořadí čísla v seznamu čísel. +RSQ = RKQ ## Vrátí druhou mocninu Pearsonova výsledného momentového korelačního koeficientu. +SKEW = SKEW ## Vrátí zešikmení rozdělení. +SLOPE = SLOPE ## Vrátí směrnici lineární regresní čáry. +SMALL = SMALL ## Vrátí k-tou nejmenší hodnotu množiny dat. +STANDARDIZE = STANDARDIZE ## Vrátí normalizovanou hodnotu. +STDEV = SMODCH.VÝBĚR ## Vypočte směrodatnou odchylku výběru. +STDEVA = STDEVA ## Vypočte směrodatnou odchylku výběru včetně čísel, textu a logických hodnot. +STDEVP = SMODCH ## Vypočte směrodatnou odchylku základního souboru. +STDEVPA = STDEVPA ## Vypočte směrodatnou odchylku základního souboru včetně čísel, textu a logických hodnot. +STEYX = STEYX ## Vrátí standardní chybu předpovězené hodnoty y pro každou hodnotu x v regresi. +TDIST = TDIST ## Vrátí hodnotu Studentova t-rozdělení. +TINV = TINV ## Vrátí inverzní funkci k distribuční funkci Studentova t-rozdělení. +TREND = LINTREND ## Vrátí hodnoty lineárního trendu. +TRIMMEAN = TRIMMEAN ## Vrátí střední hodnotu vnitřní části množiny dat. +TTEST = TTEST ## Vrátí pravděpodobnost spojenou se Studentovým t-testem. +VAR = VAR.VÝBĚR ## Vypočte rozptyl výběru. +VARA = VARA ## Vypočte rozptyl výběru včetně čísel, textu a logických hodnot. +VARP = VAR ## Vypočte rozptyl základního souboru. +VARPA = VARPA ## Vypočte rozptyl základního souboru včetně čísel, textu a logických hodnot. +WEIBULL = WEIBULL ## Vrátí hodnotu Weibullova rozdělení. +ZTEST = ZTEST ## Vrátí jednostrannou P-hodnotu z-testu. + + +## +## Text functions Textové funkce +## +ASC = ASC ## Změní znaky s plnou šířkou (dvoubajtové)v řetězci znaků na znaky s poloviční šířkou (jednobajtové). +BAHTTEXT = BAHTTEXT ## Převede číslo na text ve formátu, měny ß (baht). +CHAR = ZNAK ## Vrátí znak určený číslem kódu. +CLEAN = VYČISTIT ## Odebere z textu všechny netisknutelné znaky. +CODE = KÓD ## Vrátí číselný kód prvního znaku zadaného textového řetězce. +CONCATENATE = CONCATENATE ## Spojí několik textových položek do jedné. +DOLLAR = KČ ## Převede číslo na text ve formátu měny Kč (česká koruna). +EXACT = STEJNÉ ## Zkontroluje, zda jsou dvě textové hodnoty shodné. +FIND = NAJÍT ## Nalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena). +FINDB = FINDB ## Nalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena). +FIXED = ZAOKROUHLIT.NA.TEXT ## Zformátuje číslo jako text s pevným počtem desetinných míst. +JIS = JIS ## Změní znaky s poloviční šířkou (jednobajtové) v řetězci znaků na znaky s plnou šířkou (dvoubajtové). +LEFT = ZLEVA ## Vrátí první znaky textové hodnoty umístěné nejvíce vlevo. +LEFTB = LEFTB ## Vrátí první znaky textové hodnoty umístěné nejvíce vlevo. +LEN = DÉLKA ## Vrátí počet znaků textového řetězce. +LENB = LENB ## Vrátí počet znaků textového řetězce. +LOWER = MALÁ ## Převede text na malá písmena. +MID = ČÁST ## Vrátí určitý počet znaků textového řetězce počínaje zadaným místem. +MIDB = MIDB ## Vrátí určitý počet znaků textového řetězce počínaje zadaným místem. +PHONETIC = ZVUKOVÉ ## Extrahuje fonetické znaky (furigana) z textového řetězce. +PROPER = VELKÁ2 ## Převede první písmeno každého slova textové hodnoty na velké. +REPLACE = NAHRADIT ## Nahradí znaky uvnitř textu. +REPLACEB = NAHRADITB ## Nahradí znaky uvnitř textu. +REPT = OPAKOVAT ## Zopakuje text podle zadaného počtu opakování. +RIGHT = ZPRAVA ## Vrátí první znaky textové hodnoty umístěné nejvíce vpravo. +RIGHTB = RIGHTB ## Vrátí první znaky textové hodnoty umístěné nejvíce vpravo. +SEARCH = HLEDAT ## Nalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována). +SEARCHB = SEARCHB ## Nalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována). +SUBSTITUTE = DOSADIT ## V textovém řetězci nahradí starý text novým. +T = T ## Převede argumenty na text. +TEXT = HODNOTA.NA.TEXT ## Zformátuje číslo a převede ho na text. +TRIM = PROČISTIT ## Odstraní z textu mezery. +UPPER = VELKÁ ## Převede text na velká písmena. +VALUE = HODNOTA ## Převede textový argument na číslo. diff --git a/extend/phpexcel/PHPExcel/locale/da/config b/extend/phpexcel/PHPExcel/locale/da/config new file mode 100755 index 0000000..1ddecb9 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/da/config @@ -0,0 +1,48 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + + +## +## Excel Error Codes (For future use) +## +NULL = #NUL! +DIV0 = #DIVISION/0! +VALUE = #VÆRDI! +REF = #REFERENCE! +NAME = #NAVN? +NUM = #NUM! +NA = #I/T diff --git a/extend/phpexcel/PHPExcel/locale/da/functions b/extend/phpexcel/PHPExcel/locale/da/functions new file mode 100755 index 0000000..102d578 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/da/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Tilføjelsesprogram- og automatiseringsfunktioner +## +GETPIVOTDATA = HENTPIVOTDATA ## Returnerer data, der er lagret i en pivottabelrapport + + +## +## Cube functions Kubefunktioner +## +CUBEKPIMEMBER = KUBE.KPI.MEDLEM ## Returnerer navn, egenskab og mål for en KPI-indikator og viser navnet og egenskaben i cellen. En KPI-indikator er en målbar størrelse, f.eks. bruttooverskud pr. måned eller personaleudskiftning pr. kvartal, der bruges til at overvåge en organisations præstationer. +CUBEMEMBER = KUBE.MEDLEM ## Returnerer et medlem eller en tupel fra kubehierarkiet. Bruges til at validere, om et medlem eller en tupel findes i kuben. +CUBEMEMBERPROPERTY = KUBEMEDLEM.EGENSKAB ## Returnerer værdien af en egenskab for et medlem i kuben. Bruges til at validere, om et medlemsnavn findes i kuben, og returnere den angivne egenskab for medlemmet. +CUBERANKEDMEMBER = KUBEMEDLEM.RANG ## Returnerer det n'te eller rangordnede medlem i et sæt. Bruges til at returnere et eller flere elementer i et sæt, f.eks. topsælgere eller de 10 bedste elever. +CUBESET = KUBESÆT ## Definerer et beregnet sæt medlemmer eller tupler ved at sende et sætudtryk til kuben på serveren, som opretter sættet og returnerer det til Microsoft Office Excel. +CUBESETCOUNT = KUBESÆT.TÆL ## Returnerer antallet af elementer i et sæt. +CUBEVALUE = KUBEVÆRDI ## Returnerer en sammenlagt (aggregeret) værdi fra en kube. + + +## +## Database functions Databasefunktioner +## +DAVERAGE = DMIDDEL ## Returnerer gennemsnittet af markerede databaseposter +DCOUNT = DTÆL ## Tæller de celler, der indeholder tal, i en database +DCOUNTA = DTÆLV ## Tæller udfyldte celler i en database +DGET = DHENT ## Uddrager en enkelt post, der opfylder de angivne kriterier, fra en database +DMAX = DMAKS ## Returnerer den største værdi blandt markerede databaseposter +DMIN = DMIN ## Returnerer den mindste værdi blandt markerede databaseposter +DPRODUCT = DPRODUKT ## Ganger værdierne i et bestemt felt med poster, der opfylder kriterierne i en database +DSTDEV = DSTDAFV ## Beregner et skøn over standardafvigelsen baseret på en stikprøve af markerede databaseposter +DSTDEVP = DSTDAFVP ## Beregner standardafvigelsen baseret på hele populationen af markerede databaseposter +DSUM = DSUM ## Sammenlægger de tal i feltkolonnen i databasen, der opfylder kriterierne +DVAR = DVARIANS ## Beregner varians baseret på en stikprøve af markerede databaseposter +DVARP = DVARIANSP ## Beregner varians baseret på hele populationen af markerede databaseposter + + +## +## Date and time functions Dato- og klokkeslætsfunktioner +## +DATE = DATO ## Returnerer serienummeret for en bestemt dato +DATEVALUE = DATOVÆRDI ## Konverterer en dato i form af tekst til et serienummer +DAY = DAG ## Konverterer et serienummer til en dag i måneden +DAYS360 = DAGE360 ## Beregner antallet af dage mellem to datoer på grundlag af et år med 360 dage +EDATE = EDATO ## Returnerer serienummeret for den dato, der ligger det angivne antal måneder før eller efter startdatoen +EOMONTH = SLUT.PÅ.MÅNED ## Returnerer serienummeret på den sidste dag i måneden før eller efter et angivet antal måneder +HOUR = TIME ## Konverterer et serienummer til en time +MINUTE = MINUT ## Konverterer et serienummer til et minut +MONTH = MÅNED ## Konverterer et serienummer til en måned +NETWORKDAYS = ANTAL.ARBEJDSDAGE ## Returnerer antallet af hele arbejdsdage mellem to datoer +NOW = NU ## Returnerer serienummeret for den aktuelle dato eller det aktuelle klokkeslæt +SECOND = SEKUND ## Konverterer et serienummer til et sekund +TIME = KLOKKESLÆT ## Returnerer serienummeret for et bestemt klokkeslæt +TIMEVALUE = TIDSVÆRDI ## Konverterer et klokkeslæt i form af tekst til et serienummer +TODAY = IDAG ## Returnerer serienummeret for dags dato +WEEKDAY = UGEDAG ## Konverterer et serienummer til en ugedag +WEEKNUM = UGE.NR ## Konverterer et serienummer til et tal, der angiver ugenummeret i året +WORKDAY = ARBEJDSDAG ## Returnerer serienummeret for dagen før eller efter det angivne antal arbejdsdage +YEAR = ÅR ## Konverterer et serienummer til et år +YEARFRAC = ÅR.BRØK ## Returnerer årsbrøken, der repræsenterer antallet af hele dage mellem startdato og slutdato + + +## +## Engineering functions Tekniske funktioner +## +BESSELI = BESSELI ## Returnerer den modificerede Bessel-funktion In(x) +BESSELJ = BESSELJ ## Returnerer Bessel-funktionen Jn(x) +BESSELK = BESSELK ## Returnerer den modificerede Bessel-funktion Kn(x) +BESSELY = BESSELY ## Returnerer Bessel-funktionen Yn(x) +BIN2DEC = BIN.TIL.DEC ## Konverterer et binært tal til et decimaltal +BIN2HEX = BIN.TIL.HEX ## Konverterer et binært tal til et heksadecimalt tal +BIN2OCT = BIN.TIL.OKT ## Konverterer et binært tal til et oktaltal. +COMPLEX = KOMPLEKS ## Konverterer reelle og imaginære koefficienter til et komplekst tal +CONVERT = KONVERTER ## Konverterer et tal fra én måleenhed til en anden +DEC2BIN = DEC.TIL.BIN ## Konverterer et decimaltal til et binært tal +DEC2HEX = DEC.TIL.HEX ## Konverterer et decimaltal til et heksadecimalt tal +DEC2OCT = DEC.TIL.OKT ## Konverterer et decimaltal til et oktaltal +DELTA = DELTA ## Tester, om to værdier er ens +ERF = FEJLFUNK ## Returner fejlfunktionen +ERFC = FEJLFUNK.KOMP ## Returnerer den komplementære fejlfunktion +GESTEP = GETRIN ## Tester, om et tal er større end en grænseværdi +HEX2BIN = HEX.TIL.BIN ## Konverterer et heksadecimalt tal til et binært tal +HEX2DEC = HEX.TIL.DEC ## Konverterer et decimaltal til et heksadecimalt tal +HEX2OCT = HEX.TIL.OKT ## Konverterer et heksadecimalt tal til et oktaltal +IMABS = IMAGABS ## Returnerer den absolutte værdi (modulus) for et komplekst tal +IMAGINARY = IMAGINÆR ## Returnerer den imaginære koefficient for et komplekst tal +IMARGUMENT = IMAGARGUMENT ## Returnerer argumentet theta, en vinkel udtrykt i radianer +IMCONJUGATE = IMAGKONJUGERE ## Returnerer den komplekse konjugation af et komplekst tal +IMCOS = IMAGCOS ## Returnerer et komplekst tals cosinus +IMDIV = IMAGDIV ## Returnerer kvotienten for to komplekse tal +IMEXP = IMAGEKSP ## Returnerer et komplekst tals eksponentialfunktion +IMLN = IMAGLN ## Returnerer et komplekst tals naturlige logaritme +IMLOG10 = IMAGLOG10 ## Returnerer et komplekst tals sædvanlige logaritme (titalslogaritme) +IMLOG2 = IMAGLOG2 ## Returnerer et komplekst tals sædvanlige logaritme (totalslogaritme) +IMPOWER = IMAGPOTENS ## Returnerer et komplekst tal opløftet i en heltalspotens +IMPRODUCT = IMAGPRODUKT ## Returnerer produktet af komplekse tal +IMREAL = IMAGREELT ## Returnerer den reelle koefficient for et komplekst tal +IMSIN = IMAGSIN ## Returnerer et komplekst tals sinus +IMSQRT = IMAGKVROD ## Returnerer et komplekst tals kvadratrod +IMSUB = IMAGSUB ## Returnerer forskellen mellem to komplekse tal +IMSUM = IMAGSUM ## Returnerer summen af komplekse tal +OCT2BIN = OKT.TIL.BIN ## Konverterer et oktaltal til et binært tal +OCT2DEC = OKT.TIL.DEC ## Konverterer et oktaltal til et decimaltal +OCT2HEX = OKT.TIL.HEX ## Konverterer et oktaltal til et heksadecimalt tal + + +## +## Financial functions Finansielle funktioner +## +ACCRINT = PÅLØBRENTE ## Returnerer den påløbne rente for et værdipapir med periodiske renteudbetalinger +ACCRINTM = PÅLØBRENTE.UDLØB ## Returnerer den påløbne rente for et værdipapir, hvor renteudbetalingen finder sted ved papirets udløb +AMORDEGRC = AMORDEGRC ## Returnerer afskrivningsbeløbet for hver regnskabsperiode ved hjælp af en afskrivningskoefficient +AMORLINC = AMORLINC ## Returnerer afskrivningsbeløbet for hver regnskabsperiode +COUPDAYBS = KUPONDAGE.SA ## Returnerer antallet af dage fra starten af kuponperioden til afregningsdatoen +COUPDAYS = KUPONDAGE.A ## Returnerer antallet af dage fra begyndelsen af kuponperioden til afregningsdatoen +COUPDAYSNC = KUPONDAGE.ANK ## Returnerer antallet af dage i den kuponperiode, der indeholder afregningsdatoen +COUPNCD = KUPONDAG.NÆSTE ## Returnerer den næste kupondato efter afregningsdatoen +COUPNUM = KUPONBETALINGER ## Returnerer antallet af kuponudbetalinger mellem afregnings- og udløbsdatoen +COUPPCD = KUPONDAG.FORRIGE ## Returnerer den forrige kupondato før afregningsdatoen +CUMIPMT = AKKUM.RENTE ## Returnerer den akkumulerede rente, der betales på et lån mellem to perioder +CUMPRINC = AKKUM.HOVEDSTOL ## Returnerer den akkumulerede nedbringelse af hovedstol mellem to perioder +DB = DB ## Returnerer afskrivningen på et aktiv i en angivet periode ved anvendelse af saldometoden +DDB = DSA ## Returnerer afskrivningsbeløbet for et aktiv over en bestemt periode ved anvendelse af dobbeltsaldometoden eller en anden afskrivningsmetode, som du angiver +DISC = DISKONTO ## Returnerer et værdipapirs diskonto +DOLLARDE = KR.DECIMAL ## Konverterer en kronepris udtrykt som brøk til en kronepris udtrykt som decimaltal +DOLLARFR = KR.BRØK ## Konverterer en kronepris udtrykt som decimaltal til en kronepris udtrykt som brøk +DURATION = VARIGHED ## Returnerer den årlige løbetid for et værdipapir med periodiske renteudbetalinger +EFFECT = EFFEKTIV.RENTE ## Returnerer den årlige effektive rente +FV = FV ## Returnerer fremtidsværdien af en investering +FVSCHEDULE = FVTABEL ## Returnerer den fremtidige værdi af en hovedstol, når der er tilskrevet rente og rentes rente efter forskellige rentesatser +INTRATE = RENTEFOD ## Returnerer renten på et fuldt ud investeret værdipapir +IPMT = R.YDELSE ## Returnerer renten fra en investering for en given periode +IRR = IA ## Returnerer den interne rente for en række pengestrømme +ISPMT = ISPMT ## Beregner den betalte rente i løbet af en bestemt investeringsperiode +MDURATION = MVARIGHED ## Returnerer Macauleys modificerede løbetid for et værdipapir med en formodet pari på kr. 100 +MIRR = MIA ## Returnerer den interne forrentning, hvor positive og negative pengestrømme finansieres til forskellig rente +NOMINAL = NOMINEL ## Returnerer den årlige nominelle rente +NPER = NPER ## Returnerer antallet af perioder for en investering +NPV = NUTIDSVÆRDI ## Returnerer nettonutidsværdien for en investering baseret på en række periodiske pengestrømme og en diskonteringssats +ODDFPRICE = ULIGE.KURS.PÅLYDENDE ## Returnerer kursen pr. kr. 100 nominel værdi for et værdipapir med en ulige (kort eller lang) første periode +ODDFYIELD = ULIGE.FØRSTE.AFKAST ## Returnerer afkastet for et værdipapir med ulige første periode +ODDLPRICE = ULIGE.SIDSTE.KURS ## Returnerer kursen pr. kr. 100 nominel værdi for et værdipapir med ulige sidste periode +ODDLYIELD = ULIGE.SIDSTE.AFKAST ## Returnerer afkastet for et værdipapir med ulige sidste periode +PMT = YDELSE ## Returnerer renten fra en investering for en given periode +PPMT = H.YDELSE ## Returnerer ydelsen på hovedstolen for en investering i en given periode +PRICE = KURS ## Returnerer kursen pr. kr 100 nominel værdi for et værdipapir med periodiske renteudbetalinger +PRICEDISC = KURS.DISKONTO ## Returnerer kursen pr. kr 100 nominel værdi for et diskonteret værdipapir +PRICEMAT = KURS.UDLØB ## Returnerer kursen pr. kr 100 nominel værdi for et værdipapir, hvor renten udbetales ved papirets udløb +PV = NV ## Returnerer den nuværende værdi af en investering +RATE = RENTE ## Returnerer renten i hver periode for en annuitet +RECEIVED = MODTAGET.VED.UDLØB ## Returnerer det beløb, der modtages ved udløbet af et fuldt ud investeret værdipapir +SLN = LA ## Returnerer den lineære afskrivning for et aktiv i en enkelt periode +SYD = ÅRSAFSKRIVNING ## Returnerer den årlige afskrivning på et aktiv i en bestemt periode +TBILLEQ = STATSOBLIGATION ## Returnerer det obligationsækvivalente afkast for en statsobligation +TBILLPRICE = STATSOBLIGATION.KURS ## Returnerer kursen pr. kr 100 nominel værdi for en statsobligation +TBILLYIELD = STATSOBLIGATION.AFKAST ## Returnerer en afkastet på en statsobligation +VDB = VSA ## Returnerer afskrivningen på et aktiv i en angivet periode, herunder delperioder, ved brug af dobbeltsaldometoden +XIRR = INTERN.RENTE ## Returnerer den interne rente for en plan over pengestrømme, der ikke behøver at være periodiske +XNPV = NETTO.NUTIDSVÆRDI ## Returnerer nutidsværdien for en plan over pengestrømme, der ikke behøver at være periodiske +YIELD = AFKAST ## Returnerer afkastet for et værdipapir med periodiske renteudbetalinger +YIELDDISC = AFKAST.DISKONTO ## Returnerer det årlige afkast for et diskonteret værdipapir, f.eks. en statsobligation +YIELDMAT = AFKAST.UDLØBSDATO ## Returnerer det årlige afkast for et værdipapir, hvor renten udbetales ved papirets udløb + + +## +## Information functions Informationsfunktioner +## +CELL = CELLE ## Returnerer oplysninger om formatering, placering eller indhold af en celle +ERROR.TYPE = FEJLTYPE ## Returnerer et tal, der svarer til en fejltype +INFO = INFO ## Returnerer oplysninger om det aktuelle operativmiljø +ISBLANK = ER.TOM ## Returnerer SAND, hvis værdien er tom +ISERR = ER.FJL ## Returnerer SAND, hvis værdien er en fejlværdi undtagen #I/T +ISERROR = ER.FEJL ## Returnerer SAND, hvis værdien er en fejlværdi +ISEVEN = ER.LIGE ## Returnerer SAND, hvis tallet er lige +ISLOGICAL = ER.LOGISK ## Returnerer SAND, hvis værdien er en logisk værdi +ISNA = ER.IKKE.TILGÆNGELIG ## Returnerer SAND, hvis værdien er fejlværdien #I/T +ISNONTEXT = ER.IKKE.TEKST ## Returnerer SAND, hvis værdien ikke er tekst +ISNUMBER = ER.TAL ## Returnerer SAND, hvis værdien er et tal +ISODD = ER.ULIGE ## Returnerer SAND, hvis tallet er ulige +ISREF = ER.REFERENCE ## Returnerer SAND, hvis værdien er en reference +ISTEXT = ER.TEKST ## Returnerer SAND, hvis værdien er tekst +N = TAL ## Returnerer en værdi konverteret til et tal +NA = IKKE.TILGÆNGELIG ## Returnerer fejlværdien #I/T +TYPE = VÆRDITYPE ## Returnerer et tal, der angiver datatypen for en værdi + + +## +## Logical functions Logiske funktioner +## +AND = OG ## Returnerer SAND, hvis alle argumenterne er sande +FALSE = FALSK ## Returnerer den logiske værdi FALSK +IF = HVIS ## Angiver en logisk test, der skal udføres +IFERROR = HVIS.FEJL ## Returnerer en værdi, du angiver, hvis en formel evauleres som en fejl. Returnerer i modsat fald resultatet af formlen +NOT = IKKE ## Vender argumentets logik om +OR = ELLER ## Returneret værdien SAND, hvis mindst ét argument er sandt +TRUE = SAND ## Returnerer den logiske værdi SAND + + +## +## Lookup and reference functions Opslags- og referencefunktioner +## +ADDRESS = ADRESSE ## Returnerer en reference som tekst til en enkelt celle i et regneark +AREAS = OMRÅDER ## Returnerer antallet af områder i en reference +CHOOSE = VÆLG ## Vælger en værdi på en liste med værdier +COLUMN = KOLONNE ## Returnerer kolonnenummeret i en reference +COLUMNS = KOLONNER ## Returnerer antallet af kolonner i en reference +HLOOKUP = VOPSLAG ## Søger i den øverste række af en matrix og returnerer værdien af den angivne celle +HYPERLINK = HYPERLINK ## Opretter en genvej kaldet et hyperlink, der åbner et dokument, som er lagret på en netværksserver, på et intranet eller på internettet +INDEX = INDEKS ## Anvender et indeks til at vælge en værdi fra en reference eller en matrix +INDIRECT = INDIREKTE ## Returnerer en reference, der er angivet af en tekstværdi +LOOKUP = SLÅ.OP ## Søger værdier i en vektor eller en matrix +MATCH = SAMMENLIGN ## Søger værdier i en reference eller en matrix +OFFSET = FORSKYDNING ## Returnerer en reference forskudt i forhold til en given reference +ROW = RÆKKE ## Returnerer rækkenummeret for en reference +ROWS = RÆKKER ## Returnerer antallet af rækker i en reference +RTD = RTD ## Henter realtidsdata fra et program, der understøtter COM-automatisering (Automation: En metode til at arbejde med objekter fra et andet program eller udviklingsværktøj. Automation, som tidligere blev kaldt OLE Automation, er en industristandard og en funktion i COM (Component Object Model).) +TRANSPOSE = TRANSPONER ## Returnerer en transponeret matrix +VLOOKUP = LOPSLAG ## Søger i øverste række af en matrix og flytter på tværs af rækken for at returnere en celleværdi + + +## +## Math and trigonometry functions Matematiske og trigonometriske funktioner +## +ABS = ABS ## Returnerer den absolutte værdi af et tal +ACOS = ARCCOS ## Returnerer et tals arcus cosinus +ACOSH = ARCCOSH ## Returnerer den inverse hyperbolske cosinus af tal +ASIN = ARCSIN ## Returnerer et tals arcus sinus +ASINH = ARCSINH ## Returnerer den inverse hyperbolske sinus for tal +ATAN = ARCTAN ## Returnerer et tals arcus tangens +ATAN2 = ARCTAN2 ## Returnerer de angivne x- og y-koordinaters arcus tangens +ATANH = ARCTANH ## Returnerer et tals inverse hyperbolske tangens +CEILING = AFRUND.LOFT ## Afrunder et tal til nærmeste heltal eller til nærmeste multiplum af betydning +COMBIN = KOMBIN ## Returnerer antallet af kombinationer for et givet antal objekter +COS = COS ## Returnerer et tals cosinus +COSH = COSH ## Returnerer den inverse hyperbolske cosinus af et tal +DEGREES = GRADER ## Konverterer radianer til grader +EVEN = LIGE ## Runder et tal op til nærmeste lige heltal +EXP = EKSP ## Returnerer e opløftet til en potens af et angivet tal +FACT = FAKULTET ## Returnerer et tals fakultet +FACTDOUBLE = DOBBELT.FAKULTET ## Returnerer et tals dobbelte fakultet +FLOOR = AFRUND.GULV ## Runder et tal ned mod nul +GCD = STØRSTE.FÆLLES.DIVISOR ## Returnerer den største fælles divisor +INT = HELTAL ## Nedrunder et tal til det nærmeste heltal +LCM = MINDSTE.FÆLLES.MULTIPLUM ## Returnerer det mindste fælles multiplum +LN = LN ## Returnerer et tals naturlige logaritme +LOG = LOG ## Returnerer logaritmen for et tal på grundlag af et angivet grundtal +LOG10 = LOG10 ## Returnerer titalslogaritmen af et tal +MDETERM = MDETERM ## Returnerer determinanten for en matrix +MINVERSE = MINVERT ## Returnerer den inverse matrix for en matrix +MMULT = MPRODUKT ## Returnerer matrixproduktet af to matrixer +MOD = REST ## Returnerer restværdien fra division +MROUND = MAFRUND ## Returnerer et tal afrundet til det ønskede multiplum +MULTINOMIAL = MULTINOMIAL ## Returnerer et multinomialt talsæt +ODD = ULIGE ## Runder et tal op til nærmeste ulige heltal +PI = PI ## Returnerer værdien af pi +POWER = POTENS ## Returnerer resultatet af et tal opløftet til en potens +PRODUCT = PRODUKT ## Multiplicerer argumenterne +QUOTIENT = KVOTIENT ## Returnerer heltalsdelen ved division +RADIANS = RADIANER ## Konverterer grader til radianer +RAND = SLUMP ## Returnerer et tilfældigt tal mellem 0 og 1 +RANDBETWEEN = SLUMP.MELLEM ## Returnerer et tilfældigt tal mellem de tal, der angives +ROMAN = ROMERTAL ## Konverterer et arabertal til romertal som tekst +ROUND = AFRUND ## Afrunder et tal til et angivet antal decimaler +ROUNDDOWN = RUND.NED ## Runder et tal ned mod nul +ROUNDUP = RUND.OP ## Runder et tal op, væk fra 0 (nul) +SERIESSUM = SERIESUM ## Returnerer summen af en potensserie baseret på en formel +SIGN = FORTEGN ## Returnerer et tals fortegn +SIN = SIN ## Returnerer en given vinkels sinusværdi +SINH = SINH ## Returnerer den hyperbolske sinus af et tal +SQRT = KVROD ## Returnerer en positiv kvadratrod +SQRTPI = KVRODPI ## Returnerer kvadratroden af (tal * pi;) +SUBTOTAL = SUBTOTAL ## Returnerer en subtotal på en liste eller i en database +SUM = SUM ## Lægger argumenterne sammen +SUMIF = SUM.HVIS ## Lægger de celler sammen, der er specificeret af et givet kriterium. +SUMIFS = SUM.HVISER ## Lægger de celler i et område sammen, der opfylder flere kriterier. +SUMPRODUCT = SUMPRODUKT ## Returnerer summen af produkter af ens matrixkomponenter +SUMSQ = SUMKV ## Returnerer summen af argumenternes kvadrater +SUMX2MY2 = SUMX2MY2 ## Returnerer summen af differensen mellem kvadrater af ens værdier i to matrixer +SUMX2PY2 = SUMX2PY2 ## Returnerer summen af summen af kvadrater af tilsvarende værdier i to matrixer +SUMXMY2 = SUMXMY2 ## Returnerer summen af kvadrater af differenser mellem ens værdier i to matrixer +TAN = TAN ## Returnerer et tals tangens +TANH = TANH ## Returnerer et tals hyperbolske tangens +TRUNC = AFKORT ## Afkorter et tal til et heltal + + +## +## Statistical functions Statistiske funktioner +## +AVEDEV = MAD ## Returnerer den gennemsnitlige numeriske afvigelse fra stikprøvens middelværdi +AVERAGE = MIDDEL ## Returnerer middelværdien af argumenterne +AVERAGEA = MIDDELV ## Returnerer middelværdien af argumenterne og medtager tal, tekst og logiske værdier +AVERAGEIF = MIDDEL.HVIS ## Returnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder et givet kriterium, i et område +AVERAGEIFS = MIDDEL.HVISER ## Returnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder flere kriterier. +BETADIST = BETAFORDELING ## Returnerer den kumulative betafordelingsfunktion +BETAINV = BETAINV ## Returnerer den inverse kumulative fordelingsfunktion for en angivet betafordeling +BINOMDIST = BINOMIALFORDELING ## Returnerer punktsandsynligheden for binomialfordelingen +CHIDIST = CHIFORDELING ## Returnerer fraktilsandsynligheden for en chi2-fordeling +CHIINV = CHIINV ## Returnerer den inverse fraktilsandsynlighed for en chi2-fordeling +CHITEST = CHITEST ## Foretager en test for uafhængighed +CONFIDENCE = KONFIDENSINTERVAL ## Returnerer et konfidensinterval for en population +CORREL = KORRELATION ## Returnerer korrelationskoefficienten mellem to datasæt +COUNT = TÆL ## Tæller antallet af tal på en liste med argumenter +COUNTA = TÆLV ## Tæller antallet af værdier på en liste med argumenter +COUNTBLANK = ANTAL.BLANKE ## Tæller antallet af tomme celler i et område +COUNTIF = TÆLHVIS ## Tæller antallet af celler, som opfylder de givne kriterier, i et område +COUNTIFS = TÆL.HVISER ## Tæller antallet af de celler, som opfylder flere kriterier, i et område +COVAR = KOVARIANS ## Beregner kovariansen mellem to stokastiske variabler +CRITBINOM = KRITBINOM ## Returnerer den mindste værdi for x, for hvilken det gælder, at fordelingsfunktionen er mindre end eller lig med kriterieværdien. +DEVSQ = SAK ## Returnerer summen af de kvadrerede afvigelser fra middelværdien +EXPONDIST = EKSPFORDELING ## Returnerer eksponentialfordelingen +FDIST = FFORDELING ## Returnerer fraktilsandsynligheden for F-fordelingen +FINV = FINV ## Returnerer den inverse fraktilsandsynlighed for F-fordelingen +FISHER = FISHER ## Returnerer Fisher-transformationen +FISHERINV = FISHERINV ## Returnerer den inverse Fisher-transformation +FORECAST = PROGNOSE ## Returnerer en prognoseværdi baseret på lineær tendens +FREQUENCY = FREKVENS ## Returnerer en frekvensfordeling i en søjlevektor +FTEST = FTEST ## Returnerer resultatet af en F-test til sammenligning af varians +GAMMADIST = GAMMAFORDELING ## Returnerer fordelingsfunktionen for gammafordelingen +GAMMAINV = GAMMAINV ## Returnerer den inverse fordelingsfunktion for gammafordelingen +GAMMALN = GAMMALN ## Returnerer den naturlige logaritme til gammafordelingen, G(x) +GEOMEAN = GEOMIDDELVÆRDI ## Returnerer det geometriske gennemsnit +GROWTH = FORØGELSE ## Returnerer værdier langs en eksponentiel tendens +HARMEAN = HARMIDDELVÆRDI ## Returnerer det harmoniske gennemsnit +HYPGEOMDIST = HYPGEOFORDELING ## Returnerer punktsandsynligheden i en hypergeometrisk fordeling +INTERCEPT = SKÆRING ## Returnerer afskæringsværdien på y-aksen i en lineær regression +KURT = TOPSTEJL ## Returnerer kurtosisværdien for en stokastisk variabel +LARGE = STOR ## Returnerer den k'te største værdi i et datasæt +LINEST = LINREGR ## Returnerer parameterestimaterne for en lineær tendens +LOGEST = LOGREGR ## Returnerer parameterestimaterne for en eksponentiel tendens +LOGINV = LOGINV ## Returnerer den inverse fordelingsfunktion for lognormalfordelingen +LOGNORMDIST = LOGNORMFORDELING ## Returnerer fordelingsfunktionen for lognormalfordelingen +MAX = MAKS ## Returnerer den maksimale værdi på en liste med argumenter. +MAXA = MAKSV ## Returnerer den maksimale værdi på en liste med argumenter og medtager tal, tekst og logiske værdier +MEDIAN = MEDIAN ## Returnerer medianen for de angivne tal +MIN = MIN ## Returnerer den mindste værdi på en liste med argumenter. +MINA = MINV ## Returnerer den mindste værdi på en liste med argumenter og medtager tal, tekst og logiske værdier +MODE = HYPPIGST ## Returnerer den hyppigste værdi i et datasæt +NEGBINOMDIST = NEGBINOMFORDELING ## Returnerer den negative binomialfordeling +NORMDIST = NORMFORDELING ## Returnerer fordelingsfunktionen for normalfordelingen +NORMINV = NORMINV ## Returnerer den inverse fordelingsfunktion for normalfordelingen +NORMSDIST = STANDARDNORMFORDELING ## Returnerer fordelingsfunktionen for standardnormalfordelingen +NORMSINV = STANDARDNORMINV ## Returnerer den inverse fordelingsfunktion for standardnormalfordelingen +PEARSON = PEARSON ## Returnerer Pearsons korrelationskoefficient +PERCENTILE = FRAKTIL ## Returnerer den k'te fraktil for datasættet +PERCENTRANK = PROCENTPLADS ## Returnerer den procentuelle rang for en given værdi i et datasæt +PERMUT = PERMUT ## Returnerer antallet af permutationer for et givet sæt objekter +POISSON = POISSON ## Returnerer fordelingsfunktionen for en Poisson-fordeling +PROB = SANDSYNLIGHED ## Returnerer intervalsandsynligheden +QUARTILE = KVARTIL ## Returnerer kvartilen i et givet datasæt +RANK = PLADS ## Returnerer rangen for et tal på en liste med tal +RSQ = FORKLARINGSGRAD ## Returnerer R2-værdien fra en simpel lineær regression +SKEW = SKÆVHED ## Returnerer skævheden for en stokastisk variabel +SLOPE = HÆLDNING ## Returnerer estimatet på hældningen fra en simpel lineær regression +SMALL = MINDSTE ## Returnerer den k'te mindste værdi i datasættet +STANDARDIZE = STANDARDISER ## Returnerer en standardiseret værdi +STDEV = STDAFV ## Estimerer standardafvigelsen på basis af en stikprøve +STDEVA = STDAFVV ## Beregner standardafvigelsen på basis af en prøve og medtager tal, tekst og logiske værdier +STDEVP = STDAFVP ## Beregner standardafvigelsen på basis af en hel population +STDEVPA = STDAFVPV ## Beregner standardafvigelsen på basis af en hel population og medtager tal, tekst og logiske værdier +STEYX = STFYX ## Returnerer standardafvigelsen for de estimerede y-værdier i den simple lineære regression +TDIST = TFORDELING ## Returnerer fordelingsfunktionen for Student's t-fordeling +TINV = TINV ## Returnerer den inverse fordelingsfunktion for Student's t-fordeling +TREND = TENDENS ## Returnerer værdi under antagelse af en lineær tendens +TRIMMEAN = TRIMMIDDELVÆRDI ## Returnerer den trimmede middelværdi for datasættet +TTEST = TTEST ## Returnerer den sandsynlighed, der er forbundet med Student's t-test +VAR = VARIANS ## Beregner variansen på basis af en prøve +VARA = VARIANSV ## Beregner variansen på basis af en prøve og medtager tal, tekst og logiske værdier +VARP = VARIANSP ## Beregner variansen på basis af hele populationen +VARPA = VARIANSPV ## Beregner variansen på basis af hele populationen og medtager tal, tekst og logiske værdier +WEIBULL = WEIBULL ## Returnerer fordelingsfunktionen for Weibull-fordelingen +ZTEST = ZTEST ## Returnerer sandsynlighedsværdien ved en en-sidet z-test + + +## +## Text functions Tekstfunktioner +## +ASC = ASC ## Ændrer engelske tegn i fuld bredde (dobbelt-byte) eller katakana i en tegnstreng til tegn i halv bredde (enkelt-byte) +BAHTTEXT = BAHTTEKST ## Konverterer et tal til tekst ved hjælp af valutaformatet ß (baht) +CHAR = TEGN ## Returnerer det tegn, der svarer til kodenummeret +CLEAN = RENS ## Fjerner alle tegn, der ikke kan udskrives, fra tekst +CODE = KODE ## Returnerer en numerisk kode for det første tegn i en tekststreng +CONCATENATE = SAMMENKÆDNING ## Sammenkæder adskillige tekstelementer til ét tekstelement +DOLLAR = KR ## Konverterer et tal til tekst ved hjælp af valutaformatet kr. (kroner) +EXACT = EKSAKT ## Kontrollerer, om to tekstværdier er identiske +FIND = FIND ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver) +FINDB = FINDB ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver) +FIXED = FAST ## Formaterer et tal som tekst med et fast antal decimaler +JIS = JIS ## Ændrer engelske tegn i halv bredde (enkelt-byte) eller katakana i en tegnstreng til tegn i fuld bredde (dobbelt-byte) +LEFT = VENSTRE ## Returnerer tegnet længst til venstre i en tekstværdi +LEFTB = VENSTREB ## Returnerer tegnet længst til venstre i en tekstværdi +LEN = LÆNGDE ## Returnerer antallet af tegn i en tekststreng +LENB = LÆNGDEB ## Returnerer antallet af tegn i en tekststreng +LOWER = SMÅ.BOGSTAVER ## Konverterer tekst til små bogstaver +MID = MIDT ## Returnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition +MIDB = MIDTB ## Returnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition +PHONETIC = FONETISK ## Uddrager de fonetiske (furigana) tegn fra en tekststreng +PROPER = STORT.FORBOGSTAV ## Konverterer første bogstav i hvert ord i teksten til stort bogstav +REPLACE = ERSTAT ## Erstatter tegn i tekst +REPLACEB = ERSTATB ## Erstatter tegn i tekst +REPT = GENTAG ## Gentager tekst et givet antal gange +RIGHT = HØJRE ## Returnerer tegnet længste til højre i en tekstværdi +RIGHTB = HØJREB ## Returnerer tegnet længste til højre i en tekstværdi +SEARCH = SØG ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver) +SEARCHB = SØGB ## Søger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver) +SUBSTITUTE = UDSKIFT ## Udskifter gammel tekst med ny tekst i en tekststreng +T = T ## Konverterer argumenterne til tekst +TEXT = TEKST ## Formaterer et tal og konverterer det til tekst +TRIM = FJERN.OVERFLØDIGE.BLANKE ## Fjerner mellemrum fra tekst +UPPER = STORE.BOGSTAVER ## Konverterer tekst til store bogstaver +VALUE = VÆRDI ## Konverterer et tekstargument til et tal diff --git a/extend/phpexcel/PHPExcel/locale/de/config b/extend/phpexcel/PHPExcel/locale/de/config new file mode 100755 index 0000000..c997275 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/de/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #WERT! +REF = #BEZUG! +NAME = #NAME? +NUM = #ZAHL! +NA = #NV diff --git a/extend/phpexcel/PHPExcel/locale/de/functions b/extend/phpexcel/PHPExcel/locale/de/functions new file mode 100755 index 0000000..8ce08de --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/de/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Add-In- und Automatisierungsfunktionen +## +GETPIVOTDATA = PIVOTDATENZUORDNEN ## In einem PivotTable-Bericht gespeicherte Daten werden zurückgegeben. + + +## +## Cube functions Cubefunktionen +## +CUBEKPIMEMBER = CUBEKPIELEMENT ## Gibt Name, Eigenschaft und Measure eines Key Performance Indicators (KPI) zurück und zeigt den Namen und die Eigenschaft in der Zelle an. Ein KPI ist ein quantifizierbares Maß, wie z. B. der monatliche Bruttogewinn oder die vierteljährliche Mitarbeiterfluktuation, mit dessen Hilfe das Leistungsverhalten eines Unternehmens überwacht werden kann. +CUBEMEMBER = CUBEELEMENT ## Gibt ein Element oder ein Tuple in einer Cubehierarchie zurück. Wird verwendet, um zu überprüfen, ob das Element oder Tuple im Cube vorhanden ist. +CUBEMEMBERPROPERTY = CUBEELEMENTEIGENSCHAFT ## Gibt den Wert einer Elementeigenschaft im Cube zurück. Wird verwendet, um zu überprüfen, ob ein Elementname im Cube vorhanden ist, und um die für dieses Element angegebene Eigenschaft zurückzugeben. +CUBERANKEDMEMBER = CUBERANGELEMENT ## Gibt das n-te oder n-rangige Element in einer Menge zurück. Wird verwendet, um mindestens ein Element in einer Menge zurückzugeben, wie z. B. bester Vertriebsmitarbeiter oder 10 beste Kursteilnehmer. +CUBESET = CUBEMENGE ## Definiert eine berechnete Menge Elemente oder Tuples durch Senden eines Mengenausdrucks an den Cube auf dem Server, der die Menge erstellt und an Microsoft Office Excel zurückgibt. +CUBESETCOUNT = CUBEMENGENANZAHL ## Gibt die Anzahl der Elemente in einer Menge zurück. +CUBEVALUE = CUBEWERT ## Gibt einen Aggregatwert aus einem Cube zurück. + + +## +## Database functions Datenbankfunktionen +## +DAVERAGE = DBMITTELWERT ## Gibt den Mittelwert der ausgewählten Datenbankeinträge zurück +DCOUNT = DBANZAHL ## Zählt die Zellen mit Zahlen in einer Datenbank +DCOUNTA = DBANZAHL2 ## Zählt nicht leere Zellen in einer Datenbank +DGET = DBAUSZUG ## Extrahiert aus einer Datenbank einen einzelnen Datensatz, der den angegebenen Kriterien entspricht +DMAX = DBMAX ## Gibt den größten Wert aus ausgewählten Datenbankeinträgen zurück +DMIN = DBMIN ## Gibt den kleinsten Wert aus ausgewählten Datenbankeinträgen zurück +DPRODUCT = DBPRODUKT ## Multipliziert die Werte in einem bestimmten Feld mit Datensätzen, die den Kriterien in einer Datenbank entsprechen +DSTDEV = DBSTDABW ## Schätzt die Standardabweichung auf der Grundlage einer Stichprobe aus ausgewählten Datenbankeinträgen +DSTDEVP = DBSTDABWN ## Berechnet die Standardabweichung auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge +DSUM = DBSUMME ## Addiert die Zahlen in der Feldspalte mit Datensätzen in der Datenbank, die den Kriterien entsprechen +DVAR = DBVARIANZ ## Schätzt die Varianz auf der Grundlage ausgewählter Datenbankeinträge +DVARP = DBVARIANZEN ## Berechnet die Varianz auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge + + +## +## Date and time functions Datums- und Zeitfunktionen +## +DATE = DATUM ## Gibt die fortlaufende Zahl eines bestimmten Datums zurück +DATEVALUE = DATWERT ## Wandelt ein Datum in Form von Text in eine fortlaufende Zahl um +DAY = TAG ## Wandelt eine fortlaufende Zahl in den Tag des Monats um +DAYS360 = TAGE360 ## Berechnet die Anzahl der Tage zwischen zwei Datumsangaben ausgehend von einem Jahr, das 360 Tage hat +EDATE = EDATUM ## Gibt die fortlaufende Zahl des Datums zurück, bei dem es sich um die angegebene Anzahl von Monaten vor oder nach dem Anfangstermin handelt +EOMONTH = MONATSENDE ## Gibt die fortlaufende Zahl des letzten Tags des Monats vor oder nach einer festgelegten Anzahl von Monaten zurück +HOUR = STUNDE ## Wandelt eine fortlaufende Zahl in eine Stunde um +MINUTE = MINUTE ## Wandelt eine fortlaufende Zahl in eine Minute um +MONTH = MONAT ## Wandelt eine fortlaufende Zahl in einen Monat um +NETWORKDAYS = NETTOARBEITSTAGE ## Gibt die Anzahl von ganzen Arbeitstagen zwischen zwei Datumswerten zurück +NOW = JETZT ## Gibt die fortlaufende Zahl des aktuellen Datums und der aktuellen Uhrzeit zurück +SECOND = SEKUNDE ## Wandelt eine fortlaufende Zahl in eine Sekunde um +TIME = ZEIT ## Gibt die fortlaufende Zahl einer bestimmten Uhrzeit zurück +TIMEVALUE = ZEITWERT ## Wandelt eine Uhrzeit in Form von Text in eine fortlaufende Zahl um +TODAY = HEUTE ## Gibt die fortlaufende Zahl des heutigen Datums zurück +WEEKDAY = WOCHENTAG ## Wandelt eine fortlaufende Zahl in den Wochentag um +WEEKNUM = KALENDERWOCHE ## Wandelt eine fortlaufende Zahl in eine Zahl um, die angibt, in welche Woche eines Jahres das angegebene Datum fällt +WORKDAY = ARBEITSTAG ## Gibt die fortlaufende Zahl des Datums vor oder nach einer bestimmten Anzahl von Arbeitstagen zurück +YEAR = JAHR ## Wandelt eine fortlaufende Zahl in ein Jahr um +YEARFRAC = BRTEILJAHRE ## Gibt die Anzahl der ganzen Tage zwischen Ausgangsdatum und Enddatum in Bruchteilen von Jahren zurück + + +## +## Engineering functions Konstruktionsfunktionen +## +BESSELI = BESSELI ## Gibt die geänderte Besselfunktion In(x) zurück +BESSELJ = BESSELJ ## Gibt die Besselfunktion Jn(x) zurück +BESSELK = BESSELK ## Gibt die geänderte Besselfunktion Kn(x) zurück +BESSELY = BESSELY ## Gibt die Besselfunktion Yn(x) zurück +BIN2DEC = BININDEZ ## Wandelt eine binäre Zahl (Dualzahl) in eine dezimale Zahl um +BIN2HEX = BININHEX ## Wandelt eine binäre Zahl (Dualzahl) in eine hexadezimale Zahl um +BIN2OCT = BININOKT ## Wandelt eine binäre Zahl (Dualzahl) in eine oktale Zahl um +COMPLEX = KOMPLEXE ## Wandelt den Real- und Imaginärteil in eine komplexe Zahl um +CONVERT = UMWANDELN ## Wandelt eine Zahl von einem Maßsystem in ein anderes um +DEC2BIN = DEZINBIN ## Wandelt eine dezimale Zahl in eine binäre Zahl (Dualzahl) um +DEC2HEX = DEZINHEX ## Wandelt eine dezimale Zahl in eine hexadezimale Zahl um +DEC2OCT = DEZINOKT ## Wandelt eine dezimale Zahl in eine oktale Zahl um +DELTA = DELTA ## Überprüft, ob zwei Werte gleich sind +ERF = GAUSSFEHLER ## Gibt die Gauss'sche Fehlerfunktion zurück +ERFC = GAUSSFKOMPL ## Gibt das Komplement zur Gauss'schen Fehlerfunktion zurück +GESTEP = GGANZZAHL ## Überprüft, ob eine Zahl größer als ein gegebener Schwellenwert ist +HEX2BIN = HEXINBIN ## Wandelt eine hexadezimale Zahl in eine Binärzahl um +HEX2DEC = HEXINDEZ ## Wandelt eine hexadezimale Zahl in eine dezimale Zahl um +HEX2OCT = HEXINOKT ## Wandelt eine hexadezimale Zahl in eine Oktalzahl um +IMABS = IMABS ## Gibt den Absolutbetrag (Modulo) einer komplexen Zahl zurück +IMAGINARY = IMAGINÄRTEIL ## Gibt den Imaginärteil einer komplexen Zahl zurück +IMARGUMENT = IMARGUMENT ## Gibt das Argument Theta zurück, einen Winkel, der als Bogenmaß ausgedrückt wird +IMCONJUGATE = IMKONJUGIERTE ## Gibt die konjugierte komplexe Zahl zu einer komplexen Zahl zurück +IMCOS = IMCOS ## Gibt den Kosinus einer komplexen Zahl zurück +IMDIV = IMDIV ## Gibt den Quotienten zweier komplexer Zahlen zurück +IMEXP = IMEXP ## Gibt die algebraische Form einer in exponentieller Schreibweise vorliegenden komplexen Zahl zurück +IMLN = IMLN ## Gibt den natürlichen Logarithmus einer komplexen Zahl zurück +IMLOG10 = IMLOG10 ## Gibt den Logarithmus einer komplexen Zahl zur Basis 10 zurück +IMLOG2 = IMLOG2 ## Gibt den Logarithmus einer komplexen Zahl zur Basis 2 zurück +IMPOWER = IMAPOTENZ ## Potenziert eine komplexe Zahl mit einer ganzen Zahl +IMPRODUCT = IMPRODUKT ## Gibt das Produkt von komplexen Zahlen zurück +IMREAL = IMREALTEIL ## Gibt den Realteil einer komplexen Zahl zurück +IMSIN = IMSIN ## Gibt den Sinus einer komplexen Zahl zurück +IMSQRT = IMWURZEL ## Gibt die Quadratwurzel einer komplexen Zahl zurück +IMSUB = IMSUB ## Gibt die Differenz zwischen zwei komplexen Zahlen zurück +IMSUM = IMSUMME ## Gibt die Summe von komplexen Zahlen zurück +OCT2BIN = OKTINBIN ## Wandelt eine oktale Zahl in eine binäre Zahl (Dualzahl) um +OCT2DEC = OKTINDEZ ## Wandelt eine oktale Zahl in eine dezimale Zahl um +OCT2HEX = OKTINHEX ## Wandelt eine oktale Zahl in eine hexadezimale Zahl um + + +## +## Financial functions Finanzmathematische Funktionen +## +ACCRINT = AUFGELZINS ## Gibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers mit periodischen Zinszahlungen zurück +ACCRINTM = AUFGELZINSF ## Gibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers zurück, die bei Fälligkeit ausgezahlt werden +AMORDEGRC = AMORDEGRK ## Gibt die Abschreibung für die einzelnen Abschreibungszeiträume mithilfe eines Abschreibungskoeffizienten zurück +AMORLINC = AMORLINEARK ## Gibt die Abschreibung für die einzelnen Abschreibungszeiträume zurück +COUPDAYBS = ZINSTERMTAGVA ## Gibt die Anzahl der Tage vom Anfang des Zinstermins bis zum Abrechnungstermin zurück +COUPDAYS = ZINSTERMTAGE ## Gibt die Anzahl der Tage der Zinsperiode zurück, die den Abrechnungstermin einschließt +COUPDAYSNC = ZINSTERMTAGNZ ## Gibt die Anzahl der Tage vom Abrechnungstermin bis zum nächsten Zinstermin zurück +COUPNCD = ZINSTERMNZ ## Gibt das Datum des ersten Zinstermins nach dem Abrechnungstermin zurück +COUPNUM = ZINSTERMZAHL ## Gibt die Anzahl der Zinstermine zwischen Abrechnungs- und Fälligkeitsdatum zurück +COUPPCD = ZINSTERMVZ ## Gibt das Datum des letzten Zinstermins vor dem Abrechnungstermin zurück +CUMIPMT = KUMZINSZ ## Berechnet die kumulierten Zinsen, die zwischen zwei Perioden zu zahlen sind +CUMPRINC = KUMKAPITAL ## Berechnet die aufgelaufene Tilgung eines Darlehens, die zwischen zwei Perioden zu zahlen ist +DB = GDA2 ## Gibt die geometrisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück +DDB = GDA ## Gibt die Abschreibung eines Anlageguts für einen angegebenen Zeitraum unter Verwendung der degressiven Doppelraten-Abschreibung oder eines anderen von Ihnen angegebenen Abschreibungsverfahrens zurück +DISC = DISAGIO ## Gibt den in Prozent ausgedrückten Abzinsungssatz eines Wertpapiers zurück +DOLLARDE = NOTIERUNGDEZ ## Wandelt eine Notierung, die als Dezimalbruch ausgedrückt wurde, in eine Dezimalzahl um +DOLLARFR = NOTIERUNGBRU ## Wandelt eine Notierung, die als Dezimalzahl ausgedrückt wurde, in einen Dezimalbruch um +DURATION = DURATION ## Gibt die jährliche Duration eines Wertpapiers mit periodischen Zinszahlungen zurück +EFFECT = EFFEKTIV ## Gibt die jährliche Effektivverzinsung zurück +FV = ZW ## Gibt den zukünftigen Wert (Endwert) einer Investition zurück +FVSCHEDULE = ZW2 ## Gibt den aufgezinsten Wert des Anfangskapitals für eine Reihe periodisch unterschiedlicher Zinssätze zurück +INTRATE = ZINSSATZ ## Gibt den Zinssatz eines voll investierten Wertpapiers zurück +IPMT = ZINSZ ## Gibt die Zinszahlung einer Investition für die angegebene Periode zurück +IRR = IKV ## Gibt den internen Zinsfuß einer Investition ohne Finanzierungskosten oder Reinvestitionsgewinne zurück +ISPMT = ISPMT ## Berechnet die während eines bestimmten Zeitraums für eine Investition gezahlten Zinsen +MDURATION = MDURATION ## Gibt die geänderte Dauer für ein Wertpapier mit einem angenommenen Nennwert von 100 € zurück +MIRR = QIKV ## Gibt den internen Zinsfuß zurück, wobei positive und negative Zahlungen zu unterschiedlichen Sätzen finanziert werden +NOMINAL = NOMINAL ## Gibt die jährliche Nominalverzinsung zurück +NPER = ZZR ## Gibt die Anzahl der Zahlungsperioden einer Investition zurück +NPV = NBW ## Gibt den Nettobarwert einer Investition auf Basis periodisch anfallender Zahlungen und eines Abzinsungsfaktors zurück +ODDFPRICE = UNREGER.KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück +ODDFYIELD = UNREGER.REND ## Gibt die Rendite eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück +ODDLPRICE = UNREGLE.KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück +ODDLYIELD = UNREGLE.REND ## Gibt die Rendite eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück +PMT = RMZ ## Gibt die periodische Zahlung für eine Annuität zurück +PPMT = KAPZ ## Gibt die Kapitalrückzahlung einer Investition für eine angegebene Periode zurück +PRICE = KURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das periodisch Zinsen auszahlt +PRICEDISC = KURSDISAGIO ## Gibt den Kurs pro 100 € Nennwert eines unverzinslichen Wertpapiers zurück +PRICEMAT = KURSFÄLLIG ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt +PV = BW ## Gibt den Barwert einer Investition zurück +RATE = ZINS ## Gibt den Zinssatz pro Zeitraum einer Annuität zurück +RECEIVED = AUSZAHLUNG ## Gibt den Auszahlungsbetrag eines voll investierten Wertpapiers am Fälligkeitstermin zurück +SLN = LIA ## Gibt die lineare Abschreibung eines Wirtschaftsguts pro Periode zurück +SYD = DIA ## Gibt die arithmetisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück +TBILLEQ = TBILLÄQUIV ## Gibt die Rendite für ein Wertpapier zurück +TBILLPRICE = TBILLKURS ## Gibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück +TBILLYIELD = TBILLRENDITE ## Gibt die Rendite für ein Wertpapier zurück +VDB = VDB ## Gibt die degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode oder Teilperiode zurück +XIRR = XINTZINSFUSS ## Gibt den internen Zinsfuß einer Reihe nicht periodisch anfallender Zahlungen zurück +XNPV = XKAPITALWERT ## Gibt den Nettobarwert (Kapitalwert) einer Reihe nicht periodisch anfallender Zahlungen zurück +YIELD = RENDITE ## Gibt die Rendite eines Wertpapiers zurück, das periodisch Zinsen auszahlt +YIELDDISC = RENDITEDIS ## Gibt die jährliche Rendite eines unverzinslichen Wertpapiers zurück +YIELDMAT = RENDITEFÄLL ## Gibt die jährliche Rendite eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt + + +## +## Information functions Informationsfunktionen +## +CELL = ZELLE ## Gibt Informationen zu Formatierung, Position oder Inhalt einer Zelle zurück +ERROR.TYPE = FEHLER.TYP ## Gibt eine Zahl zurück, die einem Fehlertyp entspricht +INFO = INFO ## Gibt Informationen zur aktuellen Betriebssystemumgebung zurück +ISBLANK = ISTLEER ## Gibt WAHR zurück, wenn der Wert leer ist +ISERR = ISTFEHL ## Gibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert außer #N/V ist +ISERROR = ISTFEHLER ## Gibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert ist +ISEVEN = ISTGERADE ## Gibt WAHR zurück, wenn es sich um eine gerade Zahl handelt +ISLOGICAL = ISTLOG ## Gibt WAHR zurück, wenn der Wert ein Wahrheitswert ist +ISNA = ISTNV ## Gibt WAHR zurück, wenn der Wert der Fehlerwert #N/V ist +ISNONTEXT = ISTKTEXT ## Gibt WAHR zurück, wenn der Wert ein Element ist, das keinen Text enthält +ISNUMBER = ISTZAHL ## Gibt WAHR zurück, wenn der Wert eine Zahl ist +ISODD = ISTUNGERADE ## Gibt WAHR zurück, wenn es sich um eine ungerade Zahl handelt +ISREF = ISTBEZUG ## Gibt WAHR zurück, wenn der Wert ein Bezug ist +ISTEXT = ISTTEXT ## Gibt WAHR zurück, wenn der Wert ein Element ist, das Text enthält +N = N ## Gibt den in eine Zahl umgewandelten Wert zurück +NA = NV ## Gibt den Fehlerwert #NV zurück +TYPE = TYP ## Gibt eine Zahl zurück, die den Datentyp des angegebenen Werts anzeigt + + +## +## Logical functions Logische Funktionen +## +AND = UND ## Gibt WAHR zurück, wenn alle zugehörigen Argumente WAHR sind +FALSE = FALSCH ## Gibt den Wahrheitswert FALSCH zurück +IF = WENN ## Gibt einen logischen Test zum Ausführen an +IFERROR = WENNFEHLER ## Gibt einen von Ihnen festgelegten Wert zurück, wenn die Auswertung der Formel zu einem Fehler führt; andernfalls wird das Ergebnis der Formel zurückgegeben +NOT = NICHT ## Kehrt den Wahrheitswert der zugehörigen Argumente um +OR = ODER ## Gibt WAHR zurück, wenn ein Argument WAHR ist +TRUE = WAHR ## Gibt den Wahrheitswert WAHR zurück + + +## +## Lookup and reference functions Nachschlage- und Verweisfunktionen +## +ADDRESS = ADRESSE ## Gibt einen Bezug auf eine einzelne Zelle in einem Tabellenblatt als Text zurück +AREAS = BEREICHE ## Gibt die Anzahl der innerhalb eines Bezugs aufgeführten Bereiche zurück +CHOOSE = WAHL ## Wählt einen Wert aus eine Liste mit Werten aus +COLUMN = SPALTE ## Gibt die Spaltennummer eines Bezugs zurück +COLUMNS = SPALTEN ## Gibt die Anzahl der Spalten in einem Bezug zurück +HLOOKUP = HVERWEIS ## Sucht in der obersten Zeile einer Matrix und gibt den Wert der angegebenen Zelle zurück +HYPERLINK = HYPERLINK ## Erstellt eine Verknüpfung, über die ein auf einem Netzwerkserver, in einem Intranet oder im Internet gespeichertes Dokument geöffnet wird +INDEX = INDEX ## Verwendet einen Index, um einen Wert aus einem Bezug oder einer Matrix auszuwählen +INDIRECT = INDIREKT ## Gibt einen Bezug zurück, der von einem Textwert angegeben wird +LOOKUP = LOOKUP ## Sucht Werte in einem Vektor oder einer Matrix +MATCH = VERGLEICH ## Sucht Werte in einem Bezug oder einer Matrix +OFFSET = BEREICH.VERSCHIEBEN ## Gibt einen Bezugoffset aus einem gegebenen Bezug zurück +ROW = ZEILE ## Gibt die Zeilennummer eines Bezugs zurück +ROWS = ZEILEN ## Gibt die Anzahl der Zeilen in einem Bezug zurück +RTD = RTD ## Ruft Echtzeitdaten von einem Programm ab, das die COM-Automatisierung (Automatisierung: Ein Verfahren, bei dem aus einer Anwendung oder einem Entwicklungstool heraus mit den Objekten einer anderen Anwendung gearbeitet wird. Die früher als OLE-Automatisierung bezeichnete Automatisierung ist ein Industriestandard und eine Funktion von COM (Component Object Model).) unterstützt +TRANSPOSE = MTRANS ## Gibt die transponierte Matrix einer Matrix zurück +VLOOKUP = SVERWEIS ## Sucht in der ersten Spalte einer Matrix und arbeitet sich durch die Zeile, um den Wert einer Zelle zurückzugeben + + +## +## Math and trigonometry functions Mathematische und trigonometrische Funktionen +## +ABS = ABS ## Gibt den Absolutwert einer Zahl zurück +ACOS = ARCCOS ## Gibt den Arkuskosinus einer Zahl zurück +ACOSH = ARCCOSHYP ## Gibt den umgekehrten hyperbolischen Kosinus einer Zahl zurück +ASIN = ARCSIN ## Gibt den Arkussinus einer Zahl zurück +ASINH = ARCSINHYP ## Gibt den umgekehrten hyperbolischen Sinus einer Zahl zurück +ATAN = ARCTAN ## Gibt den Arkustangens einer Zahl zurück +ATAN2 = ARCTAN2 ## Gibt den Arkustangens einer x- und einer y-Koordinate zurück +ATANH = ARCTANHYP ## Gibt den umgekehrten hyperbolischen Tangens einer Zahl zurück +CEILING = OBERGRENZE ## Rundet eine Zahl auf die nächste ganze Zahl oder das nächste Vielfache von Schritt +COMBIN = KOMBINATIONEN ## Gibt die Anzahl der Kombinationen für eine bestimmte Anzahl von Objekten zurück +COS = COS ## Gibt den Kosinus einer Zahl zurück +COSH = COSHYP ## Gibt den hyperbolischen Kosinus einer Zahl zurück +DEGREES = GRAD ## Wandelt Bogenmaß (Radiant) in Grad um +EVEN = GERADE ## Rundet eine Zahl auf die nächste gerade ganze Zahl auf +EXP = EXP ## Potenziert die Basis e mit der als Argument angegebenen Zahl +FACT = FAKULTÄT ## Gibt die Fakultät einer Zahl zurück +FACTDOUBLE = ZWEIFAKULTÄT ## Gibt die Fakultät zu Zahl mit Schrittlänge 2 zurück +FLOOR = UNTERGRENZE ## Rundet die Zahl auf Anzahl_Stellen ab +GCD = GGT ## Gibt den größten gemeinsamen Teiler zurück +INT = GANZZAHL ## Rundet eine Zahl auf die nächstkleinere ganze Zahl ab +LCM = KGV ## Gibt das kleinste gemeinsame Vielfache zurück +LN = LN ## Gibt den natürlichen Logarithmus einer Zahl zurück +LOG = LOG ## Gibt den Logarithmus einer Zahl zu der angegebenen Basis zurück +LOG10 = LOG10 ## Gibt den Logarithmus einer Zahl zur Basis 10 zurück +MDETERM = MDET ## Gibt die Determinante einer Matrix zurück +MINVERSE = MINV ## Gibt die inverse Matrix einer Matrix zurück +MMULT = MMULT ## Gibt das Produkt zweier Matrizen zurück +MOD = REST ## Gibt den Rest einer Division zurück +MROUND = VRUNDEN ## Gibt eine auf das gewünschte Vielfache gerundete Zahl zurück +MULTINOMIAL = POLYNOMIAL ## Gibt den Polynomialkoeffizienten einer Gruppe von Zahlen zurück +ODD = UNGERADE ## Rundet eine Zahl auf die nächste ungerade ganze Zahl auf +PI = PI ## Gibt den Wert Pi zurück +POWER = POTENZ ## Gibt als Ergebnis eine potenzierte Zahl zurück +PRODUCT = PRODUKT ## Multipliziert die zugehörigen Argumente +QUOTIENT = QUOTIENT ## Gibt den ganzzahligen Anteil einer Division zurück +RADIANS = BOGENMASS ## Wandelt Grad in Bogenmaß (Radiant) um +RAND = ZUFALLSZAHL ## Gibt eine Zufallszahl zwischen 0 und 1 zurück +RANDBETWEEN = ZUFALLSBEREICH ## Gibt eine Zufallszahl aus dem festgelegten Bereich zurück +ROMAN = RÖMISCH ## Wandelt eine arabische Zahl in eine römische Zahl als Text um +ROUND = RUNDEN ## Rundet eine Zahl auf eine bestimmte Anzahl von Dezimalstellen +ROUNDDOWN = ABRUNDEN ## Rundet die Zahl auf Anzahl_Stellen ab +ROUNDUP = AUFRUNDEN ## Rundet die Zahl auf Anzahl_Stellen auf +SERIESSUM = POTENZREIHE ## Gibt die Summe von Potenzen (zur Berechnung von Potenzreihen und dichotomen Wahrscheinlichkeiten) zurück +SIGN = VORZEICHEN ## Gibt das Vorzeichen einer Zahl zurück +SIN = SIN ## Gibt den Sinus einer Zahl zurück +SINH = SINHYP ## Gibt den hyperbolischen Sinus einer Zahl zurück +SQRT = WURZEL ## Gibt die Quadratwurzel einer Zahl zurück +SQRTPI = WURZELPI ## Gibt die Wurzel aus der mit Pi (pi) multiplizierten Zahl zurück +SUBTOTAL = TEILERGEBNIS ## Gibt ein Teilergebnis in einer Liste oder Datenbank zurück +SUM = SUMME ## Addiert die zugehörigen Argumente +SUMIF = SUMMEWENN ## Addiert Zahlen, die mit den Suchkriterien übereinstimmen +SUMIFS = SUMMEWENNS ## Die Zellen, die mehrere Kriterien erfüllen, werden in einem Bereich hinzugefügt +SUMPRODUCT = SUMMENPRODUKT ## Gibt die Summe der Produkte zusammengehöriger Matrixkomponenten zurück +SUMSQ = QUADRATESUMME ## Gibt die Summe der quadrierten Argumente zurück +SUMX2MY2 = SUMMEX2MY2 ## Gibt die Summe der Differenzen der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück +SUMX2PY2 = SUMMEX2PY2 ## Gibt die Summe der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück +SUMXMY2 = SUMMEXMY2 ## Gibt die Summe der quadrierten Differenzen für zusammengehörige Komponenten zweier Matrizen zurück +TAN = TAN ## Gibt den Tangens einer Zahl zurück +TANH = TANHYP ## Gibt den hyperbolischen Tangens einer Zahl zurück +TRUNC = KÜRZEN ## Schneidet die Kommastellen einer Zahl ab und gibt als Ergebnis eine ganze Zahl zurück + + +## +## Statistical functions Statistische Funktionen +## +AVEDEV = MITTELABW ## Gibt die durchschnittliche absolute Abweichung einer Reihe von Merkmalsausprägungen und ihrem Mittelwert zurück +AVERAGE = MITTELWERT ## Gibt den Mittelwert der zugehörigen Argumente zurück +AVERAGEA = MITTELWERTA ## Gibt den Mittelwert der zugehörigen Argumente, die Zahlen, Text und Wahrheitswerte enthalten, zurück +AVERAGEIF = MITTELWERTWENN ## Der Durchschnittswert (arithmetisches Mittel) für alle Zellen in einem Bereich, die einem angegebenen Kriterium entsprechen, wird zurückgegeben +AVERAGEIFS = MITTELWERTWENNS ## Gibt den Durchschnittswert (arithmetisches Mittel) aller Zellen zurück, die mehreren Kriterien entsprechen +BETADIST = BETAVERT ## Gibt die Werte der kumulierten Betaverteilungsfunktion zurück +BETAINV = BETAINV ## Gibt das Quantil der angegebenen Betaverteilung zurück +BINOMDIST = BINOMVERT ## Gibt Wahrscheinlichkeiten einer binomialverteilten Zufallsvariablen zurück +CHIDIST = CHIVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer Chi-Quadrat-verteilten Zufallsgröße zurück +CHIINV = CHIINV ## Gibt Quantile der Verteilungsfunktion (1-Alpha) der Chi-Quadrat-Verteilung zurück +CHITEST = CHITEST ## Gibt die Teststatistik eines Unabhängigkeitstests zurück +CONFIDENCE = KONFIDENZ ## Ermöglicht die Berechnung des 1-Alpha Konfidenzintervalls für den Erwartungswert einer Zufallsvariablen +CORREL = KORREL ## Gibt den Korrelationskoeffizienten zweier Reihen von Merkmalsausprägungen zurück +COUNT = ANZAHL ## Gibt die Anzahl der Zahlen in der Liste mit Argumenten an +COUNTA = ANZAHL2 ## Gibt die Anzahl der Werte in der Liste mit Argumenten an +COUNTBLANK = ANZAHLLEEREZELLEN ## Gibt die Anzahl der leeren Zellen in einem Bereich an +COUNTIF = ZÄHLENWENN ## Gibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit den Suchkriterien übereinstimmen +COUNTIFS = ZÄHLENWENNS ## Gibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit mehreren Suchkriterien übereinstimmen +COVAR = KOVAR ## Gibt die Kovarianz zurück, den Mittelwert der für alle Datenpunktpaare gebildeten Produkte der Abweichungen +CRITBINOM = KRITBINOM ## Gibt den kleinsten Wert zurück, für den die kumulierten Wahrscheinlichkeiten der Binomialverteilung kleiner oder gleich einer Grenzwahrscheinlichkeit sind +DEVSQ = SUMQUADABW ## Gibt die Summe der quadrierten Abweichungen der Datenpunkte von ihrem Stichprobenmittelwert zurück +EXPONDIST = EXPONVERT ## Gibt Wahrscheinlichkeiten einer exponential verteilten Zufallsvariablen zurück +FDIST = FVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer F-verteilten Zufallsvariablen zurück +FINV = FINV ## Gibt Quantile der F-Verteilung zurück +FISHER = FISHER ## Gibt die Fisher-Transformation zurück +FISHERINV = FISHERINV ## Gibt die Umkehrung der Fisher-Transformation zurück +FORECAST = PROGNOSE ## Gibt einen Wert zurück, der sich aus einem linearen Trend ergibt +FREQUENCY = HÄUFIGKEIT ## Gibt eine Häufigkeitsverteilung als vertikale Matrix zurück +FTEST = FTEST ## Gibt die Teststatistik eines F-Tests zurück +GAMMADIST = GAMMAVERT ## Gibt Wahrscheinlichkeiten einer gammaverteilten Zufallsvariablen zurück +GAMMAINV = GAMMAINV ## Gibt Quantile der Gammaverteilung zurück +GAMMALN = GAMMALN ## Gibt den natürlichen Logarithmus der Gammafunktion zurück, Γ(x) +GEOMEAN = GEOMITTEL ## Gibt das geometrische Mittel zurück +GROWTH = VARIATION ## Gibt Werte zurück, die sich aus einem exponentiellen Trend ergeben +HARMEAN = HARMITTEL ## Gibt das harmonische Mittel zurück +HYPGEOMDIST = HYPGEOMVERT ## Gibt Wahrscheinlichkeiten einer hypergeometrisch-verteilten Zufallsvariablen zurück +INTERCEPT = ACHSENABSCHNITT ## Gibt den Schnittpunkt der Regressionsgeraden zurück +KURT = KURT ## Gibt die Kurtosis (Exzess) einer Datengruppe zurück +LARGE = KGRÖSSTE ## Gibt den k-größten Wert einer Datengruppe zurück +LINEST = RGP ## Gibt die Parameter eines linearen Trends zurück +LOGEST = RKP ## Gibt die Parameter eines exponentiellen Trends zurück +LOGINV = LOGINV ## Gibt Quantile der Lognormalverteilung zurück +LOGNORMDIST = LOGNORMVERT ## Gibt Werte der Verteilungsfunktion einer lognormalverteilten Zufallsvariablen zurück +MAX = MAX ## Gibt den Maximalwert einer Liste mit Argumenten zurück +MAXA = MAXA ## Gibt den Maximalwert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten +MEDIAN = MEDIAN ## Gibt den Median der angegebenen Zahlen zurück +MIN = MIN ## Gibt den Minimalwert einer Liste mit Argumenten zurück +MINA = MINA ## Gibt den kleinsten Wert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten +MODE = MODALWERT ## Gibt den am häufigsten vorkommenden Wert in einer Datengruppe zurück +NEGBINOMDIST = NEGBINOMVERT ## Gibt Wahrscheinlichkeiten einer negativen, binominal verteilten Zufallsvariablen zurück +NORMDIST = NORMVERT ## Gibt Wahrscheinlichkeiten einer normal verteilten Zufallsvariablen zurück +NORMINV = NORMINV ## Gibt Quantile der Normalverteilung zurück +NORMSDIST = STANDNORMVERT ## Gibt Werte der Verteilungsfunktion einer standardnormalverteilten Zufallsvariablen zurück +NORMSINV = STANDNORMINV ## Gibt Quantile der Standardnormalverteilung zurück +PEARSON = PEARSON ## Gibt den Pearsonschen Korrelationskoeffizienten zurück +PERCENTILE = QUANTIL ## Gibt das Alpha-Quantil einer Gruppe von Daten zurück +PERCENTRANK = QUANTILSRANG ## Gibt den prozentualen Rang (Alpha) eines Werts in einer Datengruppe zurück +PERMUT = VARIATIONEN ## Gibt die Anzahl der Möglichkeiten zurück, um k Elemente aus einer Menge von n Elementen ohne Zurücklegen zu ziehen +POISSON = POISSON ## Gibt Wahrscheinlichkeiten einer poissonverteilten Zufallsvariablen zurück +PROB = WAHRSCHBEREICH ## Gibt die Wahrscheinlichkeit für ein von zwei Werten eingeschlossenes Intervall zurück +QUARTILE = QUARTILE ## Gibt die Quartile der Datengruppe zurück +RANK = RANG ## Gibt den Rang zurück, den eine Zahl innerhalb einer Liste von Zahlen einnimmt +RSQ = BESTIMMTHEITSMASS ## Gibt das Quadrat des Pearsonschen Korrelationskoeffizienten zurück +SKEW = SCHIEFE ## Gibt die Schiefe einer Verteilung zurück +SLOPE = STEIGUNG ## Gibt die Steigung der Regressionsgeraden zurück +SMALL = KKLEINSTE ## Gibt den k-kleinsten Wert einer Datengruppe zurück +STANDARDIZE = STANDARDISIERUNG ## Gibt den standardisierten Wert zurück +STDEV = STABW ## Schätzt die Standardabweichung ausgehend von einer Stichprobe +STDEVA = STABWA ## Schätzt die Standardabweichung ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält +STDEVP = STABWN ## Berechnet die Standardabweichung ausgehend von der Grundgesamtheit +STDEVPA = STABWNA ## Berechnet die Standardabweichung ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält +STEYX = STFEHLERYX ## Gibt den Standardfehler der geschätzten y-Werte für alle x-Werte der Regression zurück +TDIST = TVERT ## Gibt Werte der Verteilungsfunktion (1-Alpha) einer (Student) t-verteilten Zufallsvariablen zurück +TINV = TINV ## Gibt Quantile der t-Verteilung zurück +TREND = TREND ## Gibt Werte zurück, die sich aus einem linearen Trend ergeben +TRIMMEAN = GESTUTZTMITTEL ## Gibt den Mittelwert einer Datengruppe zurück, ohne die Randwerte zu berücksichtigen +TTEST = TTEST ## Gibt die Teststatistik eines Student'schen t-Tests zurück +VAR = VARIANZ ## Schätzt die Varianz ausgehend von einer Stichprobe +VARA = VARIANZA ## Schätzt die Varianz ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält +VARP = VARIANZEN ## Berechnet die Varianz ausgehend von der Grundgesamtheit +VARPA = VARIANZENA ## Berechnet die Varianz ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält +WEIBULL = WEIBULL ## Gibt Wahrscheinlichkeiten einer weibullverteilten Zufallsvariablen zurück +ZTEST = GTEST ## Gibt den einseitigen Wahrscheinlichkeitswert für einen Gausstest (Normalverteilung) zurück + + +## +## Text functions Textfunktionen +## +ASC = ASC ## Konvertiert DB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in SB-Text +BAHTTEXT = BAHTTEXT ## Wandelt eine Zahl in Text im Währungsformat ß (Baht) um +CHAR = ZEICHEN ## Gibt das der Codezahl entsprechende Zeichen zurück +CLEAN = SÄUBERN ## Löscht alle nicht druckbaren Zeichen aus einem Text +CODE = CODE ## Gibt die Codezahl des ersten Zeichens in einem Text zurück +CONCATENATE = VERKETTEN ## Verknüpft mehrere Textelemente zu einem Textelement +DOLLAR = DM ## Wandelt eine Zahl in Text im Währungsformat € (Euro) um +EXACT = IDENTISCH ## Prüft, ob zwei Textwerte identisch sind +FIND = FINDEN ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden) +FINDB = FINDENB ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden) +FIXED = FEST ## Formatiert eine Zahl als Text mit einer festen Anzahl von Dezimalstellen +JIS = JIS ## Konvertiert SB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in DB-Text +LEFT = LINKS ## Gibt die Zeichen ganz links in einem Textwert zurück +LEFTB = LINKSB ## Gibt die Zeichen ganz links in einem Textwert zurück +LEN = LÄNGE ## Gibt die Anzahl der Zeichen in einer Zeichenfolge zurück +LENB = LÄNGEB ## Gibt die Anzahl der Zeichen in einer Zeichenfolge zurück +LOWER = KLEIN ## Wandelt Text in Kleinbuchstaben um +MID = TEIL ## Gibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück +MIDB = TEILB ## Gibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück +PHONETIC = PHONETIC ## Extrahiert die phonetischen (Furigana-)Zeichen aus einer Textzeichenfolge +PROPER = GROSS2 ## Wandelt den ersten Buchstaben aller Wörter eines Textwerts in Großbuchstaben um +REPLACE = ERSETZEN ## Ersetzt Zeichen in Text +REPLACEB = ERSETZENB ## Ersetzt Zeichen in Text +REPT = WIEDERHOLEN ## Wiederholt einen Text so oft wie angegeben +RIGHT = RECHTS ## Gibt die Zeichen ganz rechts in einem Textwert zurück +RIGHTB = RECHTSB ## Gibt die Zeichen ganz rechts in einem Textwert zurück +SEARCH = SUCHEN ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden) +SEARCHB = SUCHENB ## Sucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden) +SUBSTITUTE = WECHSELN ## Ersetzt in einer Zeichenfolge neuen Text gegen alten +T = T ## Wandelt die zugehörigen Argumente in Text um +TEXT = TEXT ## Formatiert eine Zahl und wandelt sie in Text um +TRIM = GLÄTTEN ## Entfernt Leerzeichen aus Text +UPPER = GROSS ## Wandelt Text in Großbuchstaben um +VALUE = WERT ## Wandelt ein Textargument in eine Zahl um diff --git a/extend/phpexcel/PHPExcel/locale/en/uk/config b/extend/phpexcel/PHPExcel/locale/en/uk/config new file mode 100755 index 0000000..dfcc63b --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/en/uk/config @@ -0,0 +1,32 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +## +## (For future use) +## +currencySymbol = £ diff --git a/extend/phpexcel/PHPExcel/locale/es/config b/extend/phpexcel/PHPExcel/locale/es/config new file mode 100755 index 0000000..0b11eb7 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/es/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = $ ## I'm surprised that the Excel Documentation suggests $ rather than € + + +## +## Excel Error Codes (For future use) +## +NULL = #¡NULO! +DIV0 = #¡DIV/0! +VALUE = #¡VALOR! +REF = #¡REF! +NAME = #¿NOMBRE? +NUM = #¡NÚM! +NA = #N/A diff --git a/extend/phpexcel/PHPExcel/locale/es/functions b/extend/phpexcel/PHPExcel/locale/es/functions new file mode 100755 index 0000000..f6e6fd2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/es/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funciones de complementos y automatización +## +GETPIVOTDATA = IMPORTARDATOSDINAMICOS ## Devuelve los datos almacenados en un informe de tabla dinámica. + + +## +## Cube functions Funciones de cubo +## +CUBEKPIMEMBER = MIEMBROKPICUBO ## Devuelve un nombre, propiedad y medida de indicador de rendimiento clave (KPI) y muestra el nombre y la propiedad en la celda. Un KPI es una medida cuantificable, como los beneficios brutos mensuales o la facturación trimestral por empleado, que se usa para supervisar el rendimiento de una organización. +CUBEMEMBER = MIEMBROCUBO ## Devuelve un miembro o tupla en una jerarquía de cubo. Se usa para validar la existencia del miembro o la tupla en el cubo. +CUBEMEMBERPROPERTY = PROPIEDADMIEMBROCUBO ## Devuelve el valor de una propiedad de miembro del cubo Se usa para validar la existencia de un nombre de miembro en el cubo y para devolver la propiedad especificada para este miembro. +CUBERANKEDMEMBER = MIEMBRORANGOCUBO ## Devuelve el miembro n, o clasificado, de un conjunto. Se usa para devolver uno o más elementos de un conjunto, por ejemplo, el representante con mejores ventas o los diez mejores alumnos. +CUBESET = CONJUNTOCUBO ## Define un conjunto calculado de miembros o tuplas mediante el envío de una expresión de conjunto al cubo en el servidor, lo que crea el conjunto y, después, devuelve dicho conjunto a Microsoft Office Excel. +CUBESETCOUNT = RECUENTOCONJUNTOCUBO ## Devuelve el número de elementos de un conjunto. +CUBEVALUE = VALORCUBO ## Devuelve un valor agregado de un cubo. + + +## +## Database functions Funciones de base de datos +## +DAVERAGE = BDPROMEDIO ## Devuelve el promedio de las entradas seleccionadas en la base de datos. +DCOUNT = BDCONTAR ## Cuenta el número de celdas que contienen números en una base de datos. +DCOUNTA = BDCONTARA ## Cuenta el número de celdas no vacías en una base de datos. +DGET = BDEXTRAER ## Extrae de una base de datos un único registro que cumple los criterios especificados. +DMAX = BDMAX ## Devuelve el valor máximo de las entradas seleccionadas de la base de datos. +DMIN = BDMIN ## Devuelve el valor mínimo de las entradas seleccionadas de la base de datos. +DPRODUCT = BDPRODUCTO ## Multiplica los valores de un campo concreto de registros de una base de datos que cumplen los criterios especificados. +DSTDEV = BDDESVEST ## Calcula la desviación estándar a partir de una muestra de entradas seleccionadas en la base de datos. +DSTDEVP = BDDESVESTP ## Calcula la desviación estándar en función de la población total de las entradas seleccionadas de la base de datos. +DSUM = BDSUMA ## Suma los números de la columna de campo de los registros de la base de datos que cumplen los criterios. +DVAR = BDVAR ## Calcula la varianza a partir de una muestra de entradas seleccionadas de la base de datos. +DVARP = BDVARP ## Calcula la varianza a partir de la población total de entradas seleccionadas de la base de datos. + + +## +## Date and time functions Funciones de fecha y hora +## +DATE = FECHA ## Devuelve el número de serie correspondiente a una fecha determinada. +DATEVALUE = FECHANUMERO ## Convierte una fecha con formato de texto en un valor de número de serie. +DAY = DIA ## Convierte un número de serie en un valor de día del mes. +DAYS360 = DIAS360 ## Calcula el número de días entre dos fechas a partir de un año de 360 días. +EDATE = FECHA.MES ## Devuelve el número de serie de la fecha equivalente al número indicado de meses anteriores o posteriores a la fecha inicial. +EOMONTH = FIN.MES ## Devuelve el número de serie correspondiente al último día del mes anterior o posterior a un número de meses especificado. +HOUR = HORA ## Convierte un número de serie en un valor de hora. +MINUTE = MINUTO ## Convierte un número de serie en un valor de minuto. +MONTH = MES ## Convierte un número de serie en un valor de mes. +NETWORKDAYS = DIAS.LAB ## Devuelve el número de todos los días laborables existentes entre dos fechas. +NOW = AHORA ## Devuelve el número de serie correspondiente a la fecha y hora actuales. +SECOND = SEGUNDO ## Convierte un número de serie en un valor de segundo. +TIME = HORA ## Devuelve el número de serie correspondiente a una hora determinada. +TIMEVALUE = HORANUMERO ## Convierte una hora con formato de texto en un valor de número de serie. +TODAY = HOY ## Devuelve el número de serie correspondiente al día actual. +WEEKDAY = DIASEM ## Convierte un número de serie en un valor de día de la semana. +WEEKNUM = NUM.DE.SEMANA ## Convierte un número de serie en un número que representa el lugar numérico correspondiente a una semana de un año. +WORKDAY = DIA.LAB ## Devuelve el número de serie de la fecha que tiene lugar antes o después de un número determinado de días laborables. +YEAR = AÑO ## Convierte un número de serie en un valor de año. +YEARFRAC = FRAC.AÑO ## Devuelve la fracción de año que representa el número total de días existentes entre el valor de fecha_inicial y el de fecha_final. + + +## +## Engineering functions Funciones de ingeniería +## +BESSELI = BESSELI ## Devuelve la función Bessel In(x) modificada. +BESSELJ = BESSELJ ## Devuelve la función Bessel Jn(x). +BESSELK = BESSELK ## Devuelve la función Bessel Kn(x) modificada. +BESSELY = BESSELY ## Devuelve la función Bessel Yn(x). +BIN2DEC = BIN.A.DEC ## Convierte un número binario en decimal. +BIN2HEX = BIN.A.HEX ## Convierte un número binario en hexadecimal. +BIN2OCT = BIN.A.OCT ## Convierte un número binario en octal. +COMPLEX = COMPLEJO ## Convierte coeficientes reales e imaginarios en un número complejo. +CONVERT = CONVERTIR ## Convierte un número de un sistema de medida a otro. +DEC2BIN = DEC.A.BIN ## Convierte un número decimal en binario. +DEC2HEX = DEC.A.HEX ## Convierte un número decimal en hexadecimal. +DEC2OCT = DEC.A.OCT ## Convierte un número decimal en octal. +DELTA = DELTA ## Comprueba si dos valores son iguales. +ERF = FUN.ERROR ## Devuelve la función de error. +ERFC = FUN.ERROR.COMPL ## Devuelve la función de error complementario. +GESTEP = MAYOR.O.IGUAL ## Comprueba si un número es mayor que un valor de umbral. +HEX2BIN = HEX.A.BIN ## Convierte un número hexadecimal en binario. +HEX2DEC = HEX.A.DEC ## Convierte un número hexadecimal en decimal. +HEX2OCT = HEX.A.OCT ## Convierte un número hexadecimal en octal. +IMABS = IM.ABS ## Devuelve el valor absoluto (módulo) de un número complejo. +IMAGINARY = IMAGINARIO ## Devuelve el coeficiente imaginario de un número complejo. +IMARGUMENT = IM.ANGULO ## Devuelve el argumento theta, un ángulo expresado en radianes. +IMCONJUGATE = IM.CONJUGADA ## Devuelve la conjugada compleja de un número complejo. +IMCOS = IM.COS ## Devuelve el coseno de un número complejo. +IMDIV = IM.DIV ## Devuelve el cociente de dos números complejos. +IMEXP = IM.EXP ## Devuelve el valor exponencial de un número complejo. +IMLN = IM.LN ## Devuelve el logaritmo natural (neperiano) de un número complejo. +IMLOG10 = IM.LOG10 ## Devuelve el logaritmo en base 10 de un número complejo. +IMLOG2 = IM.LOG2 ## Devuelve el logaritmo en base 2 de un número complejo. +IMPOWER = IM.POT ## Devuelve un número complejo elevado a una potencia entera. +IMPRODUCT = IM.PRODUCT ## Devuelve el producto de números complejos. +IMREAL = IM.REAL ## Devuelve el coeficiente real de un número complejo. +IMSIN = IM.SENO ## Devuelve el seno de un número complejo. +IMSQRT = IM.RAIZ2 ## Devuelve la raíz cuadrada de un número complejo. +IMSUB = IM.SUSTR ## Devuelve la diferencia entre dos números complejos. +IMSUM = IM.SUM ## Devuelve la suma de números complejos. +OCT2BIN = OCT.A.BIN ## Convierte un número octal en binario. +OCT2DEC = OCT.A.DEC ## Convierte un número octal en decimal. +OCT2HEX = OCT.A.HEX ## Convierte un número octal en hexadecimal. + + +## +## Financial functions Funciones financieras +## +ACCRINT = INT.ACUM ## Devuelve el interés acumulado de un valor bursátil con pagos de interés periódicos. +ACCRINTM = INT.ACUM.V ## Devuelve el interés acumulado de un valor bursátil con pagos de interés al vencimiento. +AMORDEGRC = AMORTIZ.PROGRE ## Devuelve la amortización de cada período contable mediante el uso de un coeficiente de amortización. +AMORLINC = AMORTIZ.LIN ## Devuelve la amortización de cada uno de los períodos contables. +COUPDAYBS = CUPON.DIAS.L1 ## Devuelve el número de días desde el principio del período de un cupón hasta la fecha de liquidación. +COUPDAYS = CUPON.DIAS ## Devuelve el número de días del período (entre dos cupones) donde se encuentra la fecha de liquidación. +COUPDAYSNC = CUPON.DIAS.L2 ## Devuelve el número de días desde la fecha de liquidación hasta la fecha del próximo cupón. +COUPNCD = CUPON.FECHA.L2 ## Devuelve la fecha del próximo cupón después de la fecha de liquidación. +COUPNUM = CUPON.NUM ## Devuelve el número de pagos de cupón entre la fecha de liquidación y la fecha de vencimiento. +COUPPCD = CUPON.FECHA.L1 ## Devuelve la fecha de cupón anterior a la fecha de liquidación. +CUMIPMT = PAGO.INT.ENTRE ## Devuelve el interés acumulado pagado entre dos períodos. +CUMPRINC = PAGO.PRINC.ENTRE ## Devuelve el capital acumulado pagado de un préstamo entre dos períodos. +DB = DB ## Devuelve la amortización de un bien durante un período específico a través del método de amortización de saldo fijo. +DDB = DDB ## Devuelve la amortización de un bien durante un período específico a través del método de amortización por doble disminución de saldo u otro método que se especifique. +DISC = TASA.DESC ## Devuelve la tasa de descuento de un valor bursátil. +DOLLARDE = MONEDA.DEC ## Convierte una cotización de un valor bursátil expresada en forma fraccionaria en una cotización de un valor bursátil expresada en forma decimal. +DOLLARFR = MONEDA.FRAC ## Convierte una cotización de un valor bursátil expresada en forma decimal en una cotización de un valor bursátil expresada en forma fraccionaria. +DURATION = DURACION ## Devuelve la duración anual de un valor bursátil con pagos de interés periódico. +EFFECT = INT.EFECTIVO ## Devuelve la tasa de interés anual efectiva. +FV = VF ## Devuelve el valor futuro de una inversión. +FVSCHEDULE = VF.PLAN ## Devuelve el valor futuro de un capital inicial después de aplicar una serie de tasas de interés compuesto. +INTRATE = TASA.INT ## Devuelve la tasa de interés para la inversión total de un valor bursátil. +IPMT = PAGOINT ## Devuelve el pago de intereses de una inversión durante un período determinado. +IRR = TIR ## Devuelve la tasa interna de retorno para una serie de flujos de efectivo periódicos. +ISPMT = INT.PAGO.DIR ## Calcula el interés pagado durante un período específico de una inversión. +MDURATION = DURACION.MODIF ## Devuelve la duración de Macauley modificada de un valor bursátil con un valor nominal supuesto de 100 $. +MIRR = TIRM ## Devuelve la tasa interna de retorno donde se financian flujos de efectivo positivos y negativos a tasas diferentes. +NOMINAL = TASA.NOMINAL ## Devuelve la tasa nominal de interés anual. +NPER = NPER ## Devuelve el número de períodos de una inversión. +NPV = VNA ## Devuelve el valor neto actual de una inversión en función de una serie de flujos periódicos de efectivo y una tasa de descuento. +ODDFPRICE = PRECIO.PER.IRREGULAR.1 ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con un primer período impar. +ODDFYIELD = RENDTO.PER.IRREGULAR.1 ## Devuelve el rendimiento de un valor bursátil con un primer período impar. +ODDLPRICE = PRECIO.PER.IRREGULAR.2 ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con un último período impar. +ODDLYIELD = RENDTO.PER.IRREGULAR.2 ## Devuelve el rendimiento de un valor bursátil con un último período impar. +PMT = PAGO ## Devuelve el pago periódico de una anualidad. +PPMT = PAGOPRIN ## Devuelve el pago de capital de una inversión durante un período determinado. +PRICE = PRECIO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga una tasa de interés periódico. +PRICEDISC = PRECIO.DESCUENTO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil con descuento. +PRICEMAT = PRECIO.VENCIMIENTO ## Devuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga interés a su vencimiento. +PV = VALACT ## Devuelve el valor actual de una inversión. +RATE = TASA ## Devuelve la tasa de interés por período de una anualidad. +RECEIVED = CANTIDAD.RECIBIDA ## Devuelve la cantidad recibida al vencimiento de un valor bursátil completamente invertido. +SLN = SLN ## Devuelve la amortización por método directo de un bien en un período dado. +SYD = SYD ## Devuelve la amortización por suma de dígitos de los años de un bien durante un período especificado. +TBILLEQ = LETRA.DE.TES.EQV.A.BONO ## Devuelve el rendimiento de un bono equivalente a una letra del Tesoro (de EE.UU.) +TBILLPRICE = LETRA.DE.TES.PRECIO ## Devuelve el precio por un valor nominal de 100 $ de una letra del Tesoro (de EE.UU.) +TBILLYIELD = LETRA.DE.TES.RENDTO ## Devuelve el rendimiento de una letra del Tesoro (de EE.UU.) +VDB = DVS ## Devuelve la amortización de un bien durante un período específico o parcial a través del método de cálculo del saldo en disminución. +XIRR = TIR.NO.PER ## Devuelve la tasa interna de retorno para un flujo de efectivo que no es necesariamente periódico. +XNPV = VNA.NO.PER ## Devuelve el valor neto actual para un flujo de efectivo que no es necesariamente periódico. +YIELD = RENDTO ## Devuelve el rendimiento de un valor bursátil que paga intereses periódicos. +YIELDDISC = RENDTO.DESC ## Devuelve el rendimiento anual de un valor bursátil con descuento; por ejemplo, una letra del Tesoro (de EE.UU.) +YIELDMAT = RENDTO.VENCTO ## Devuelve el rendimiento anual de un valor bursátil que paga intereses al vencimiento. + + +## +## Information functions Funciones de información +## +CELL = CELDA ## Devuelve información acerca del formato, la ubicación o el contenido de una celda. +ERROR.TYPE = TIPO.DE.ERROR ## Devuelve un número que corresponde a un tipo de error. +INFO = INFO ## Devuelve información acerca del entorno operativo en uso. +ISBLANK = ESBLANCO ## Devuelve VERDADERO si el valor está en blanco. +ISERR = ESERR ## Devuelve VERDADERO si el valor es cualquier valor de error excepto #N/A. +ISERROR = ESERROR ## Devuelve VERDADERO si el valor es cualquier valor de error. +ISEVEN = ES.PAR ## Devuelve VERDADERO si el número es par. +ISLOGICAL = ESLOGICO ## Devuelve VERDADERO si el valor es un valor lógico. +ISNA = ESNOD ## Devuelve VERDADERO si el valor es el valor de error #N/A. +ISNONTEXT = ESNOTEXTO ## Devuelve VERDADERO si el valor no es texto. +ISNUMBER = ESNUMERO ## Devuelve VERDADERO si el valor es un número. +ISODD = ES.IMPAR ## Devuelve VERDADERO si el número es impar. +ISREF = ESREF ## Devuelve VERDADERO si el valor es una referencia. +ISTEXT = ESTEXTO ## Devuelve VERDADERO si el valor es texto. +N = N ## Devuelve un valor convertido en un número. +NA = ND ## Devuelve el valor de error #N/A. +TYPE = TIPO ## Devuelve un número que indica el tipo de datos de un valor. + + +## +## Logical functions Funciones lógicas +## +AND = Y ## Devuelve VERDADERO si todos sus argumentos son VERDADERO. +FALSE = FALSO ## Devuelve el valor lógico FALSO. +IF = SI ## Especifica una prueba lógica que realizar. +IFERROR = SI.ERROR ## Devuelve un valor que se especifica si una fórmula lo evalúa como un error; de lo contrario, devuelve el resultado de la fórmula. +NOT = NO ## Invierte el valor lógico del argumento. +OR = O ## Devuelve VERDADERO si cualquier argumento es VERDADERO. +TRUE = VERDADERO ## Devuelve el valor lógico VERDADERO. + + +## +## Lookup and reference functions Funciones de búsqueda y referencia +## +ADDRESS = DIRECCION ## Devuelve una referencia como texto a una sola celda de una hoja de cálculo. +AREAS = AREAS ## Devuelve el número de áreas de una referencia. +CHOOSE = ELEGIR ## Elige un valor de una lista de valores. +COLUMN = COLUMNA ## Devuelve el número de columna de una referencia. +COLUMNS = COLUMNAS ## Devuelve el número de columnas de una referencia. +HLOOKUP = BUSCARH ## Busca en la fila superior de una matriz y devuelve el valor de la celda indicada. +HYPERLINK = HIPERVINCULO ## Crea un acceso directo o un salto que abre un documento almacenado en un servidor de red, en una intranet o en Internet. +INDEX = INDICE ## Usa un índice para elegir un valor de una referencia o matriz. +INDIRECT = INDIRECTO ## Devuelve una referencia indicada por un valor de texto. +LOOKUP = BUSCAR ## Busca valores de un vector o una matriz. +MATCH = COINCIDIR ## Busca valores de una referencia o matriz. +OFFSET = DESREF ## Devuelve un desplazamiento de referencia respecto a una referencia dada. +ROW = FILA ## Devuelve el número de fila de una referencia. +ROWS = FILAS ## Devuelve el número de filas de una referencia. +RTD = RDTR ## Recupera datos en tiempo real desde un programa compatible con la automatización COM (automatización: modo de trabajar con los objetos de una aplicación desde otra aplicación o herramienta de entorno. La automatización, antes denominada automatización OLE, es un estándar de la industria y una función del Modelo de objetos componentes (COM).). +TRANSPOSE = TRANSPONER ## Devuelve la transposición de una matriz. +VLOOKUP = BUSCARV ## Busca en la primera columna de una matriz y se mueve en horizontal por la fila para devolver el valor de una celda. + + +## +## Math and trigonometry functions Funciones matemáticas y trigonométricas +## +ABS = ABS ## Devuelve el valor absoluto de un número. +ACOS = ACOS ## Devuelve el arcocoseno de un número. +ACOSH = ACOSH ## Devuelve el coseno hiperbólico inverso de un número. +ASIN = ASENO ## Devuelve el arcoseno de un número. +ASINH = ASENOH ## Devuelve el seno hiperbólico inverso de un número. +ATAN = ATAN ## Devuelve la arcotangente de un número. +ATAN2 = ATAN2 ## Devuelve la arcotangente de las coordenadas "x" e "y". +ATANH = ATANH ## Devuelve la tangente hiperbólica inversa de un número. +CEILING = MULTIPLO.SUPERIOR ## Redondea un número al entero más próximo o al múltiplo significativo más cercano. +COMBIN = COMBINAT ## Devuelve el número de combinaciones para un número determinado de objetos. +COS = COS ## Devuelve el coseno de un número. +COSH = COSH ## Devuelve el coseno hiperbólico de un número. +DEGREES = GRADOS ## Convierte radianes en grados. +EVEN = REDONDEA.PAR ## Redondea un número hasta el entero par más próximo. +EXP = EXP ## Devuelve e elevado a la potencia de un número dado. +FACT = FACT ## Devuelve el factorial de un número. +FACTDOUBLE = FACT.DOBLE ## Devuelve el factorial doble de un número. +FLOOR = MULTIPLO.INFERIOR ## Redondea un número hacia abajo, en dirección hacia cero. +GCD = M.C.D ## Devuelve el máximo común divisor. +INT = ENTERO ## Redondea un número hacia abajo hasta el entero más próximo. +LCM = M.C.M ## Devuelve el mínimo común múltiplo. +LN = LN ## Devuelve el logaritmo natural (neperiano) de un número. +LOG = LOG ## Devuelve el logaritmo de un número en una base especificada. +LOG10 = LOG10 ## Devuelve el logaritmo en base 10 de un número. +MDETERM = MDETERM ## Devuelve la determinante matricial de una matriz. +MINVERSE = MINVERSA ## Devuelve la matriz inversa de una matriz. +MMULT = MMULT ## Devuelve el producto de matriz de dos matrices. +MOD = RESIDUO ## Devuelve el resto de la división. +MROUND = REDOND.MULT ## Devuelve un número redondeado al múltiplo deseado. +MULTINOMIAL = MULTINOMIAL ## Devuelve el polinomio de un conjunto de números. +ODD = REDONDEA.IMPAR ## Redondea un número hacia arriba hasta el entero impar más próximo. +PI = PI ## Devuelve el valor de pi. +POWER = POTENCIA ## Devuelve el resultado de elevar un número a una potencia. +PRODUCT = PRODUCTO ## Multiplica sus argumentos. +QUOTIENT = COCIENTE ## Devuelve la parte entera de una división. +RADIANS = RADIANES ## Convierte grados en radianes. +RAND = ALEATORIO ## Devuelve un número aleatorio entre 0 y 1. +RANDBETWEEN = ALEATORIO.ENTRE ## Devuelve un número aleatorio entre los números que especifique. +ROMAN = NUMERO.ROMANO ## Convierte un número arábigo en número romano, con formato de texto. +ROUND = REDONDEAR ## Redondea un número al número de decimales especificado. +ROUNDDOWN = REDONDEAR.MENOS ## Redondea un número hacia abajo, en dirección hacia cero. +ROUNDUP = REDONDEAR.MAS ## Redondea un número hacia arriba, en dirección contraria a cero. +SERIESSUM = SUMA.SERIES ## Devuelve la suma de una serie de potencias en función de la fórmula. +SIGN = SIGNO ## Devuelve el signo de un número. +SIN = SENO ## Devuelve el seno de un ángulo determinado. +SINH = SENOH ## Devuelve el seno hiperbólico de un número. +SQRT = RAIZ ## Devuelve la raíz cuadrada positiva de un número. +SQRTPI = RAIZ2PI ## Devuelve la raíz cuadrada de un número multiplicado por PI (número * pi). +SUBTOTAL = SUBTOTALES ## Devuelve un subtotal en una lista o base de datos. +SUM = SUMA ## Suma sus argumentos. +SUMIF = SUMAR.SI ## Suma las celdas especificadas que cumplen unos criterios determinados. +SUMIFS = SUMAR.SI.CONJUNTO ## Suma las celdas de un rango que cumplen varios criterios. +SUMPRODUCT = SUMAPRODUCTO ## Devuelve la suma de los productos de los correspondientes componentes de matriz. +SUMSQ = SUMA.CUADRADOS ## Devuelve la suma de los cuadrados de los argumentos. +SUMX2MY2 = SUMAX2MENOSY2 ## Devuelve la suma de la diferencia de los cuadrados de los valores correspondientes de dos matrices. +SUMX2PY2 = SUMAX2MASY2 ## Devuelve la suma de la suma de los cuadrados de los valores correspondientes de dos matrices. +SUMXMY2 = SUMAXMENOSY2 ## Devuelve la suma de los cuadrados de las diferencias de los valores correspondientes de dos matrices. +TAN = TAN ## Devuelve la tangente de un número. +TANH = TANH ## Devuelve la tangente hiperbólica de un número. +TRUNC = TRUNCAR ## Trunca un número a un entero. + + +## +## Statistical functions Funciones estadísticas +## +AVEDEV = DESVPROM ## Devuelve el promedio de las desviaciones absolutas de la media de los puntos de datos. +AVERAGE = PROMEDIO ## Devuelve el promedio de sus argumentos. +AVERAGEA = PROMEDIOA ## Devuelve el promedio de sus argumentos, incluidos números, texto y valores lógicos. +AVERAGEIF = PROMEDIO.SI ## Devuelve el promedio (media aritmética) de todas las celdas de un rango que cumplen unos criterios determinados. +AVERAGEIFS = PROMEDIO.SI.CONJUNTO ## Devuelve el promedio (media aritmética) de todas las celdas que cumplen múltiples criterios. +BETADIST = DISTR.BETA ## Devuelve la función de distribución beta acumulativa. +BETAINV = DISTR.BETA.INV ## Devuelve la función inversa de la función de distribución acumulativa de una distribución beta especificada. +BINOMDIST = DISTR.BINOM ## Devuelve la probabilidad de una variable aleatoria discreta siguiendo una distribución binomial. +CHIDIST = DISTR.CHI ## Devuelve la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola. +CHIINV = PRUEBA.CHI.INV ## Devuelve la función inversa de la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola. +CHITEST = PRUEBA.CHI ## Devuelve la prueba de independencia. +CONFIDENCE = INTERVALO.CONFIANZA ## Devuelve el intervalo de confianza de la media de una población. +CORREL = COEF.DE.CORREL ## Devuelve el coeficiente de correlación entre dos conjuntos de datos. +COUNT = CONTAR ## Cuenta cuántos números hay en la lista de argumentos. +COUNTA = CONTARA ## Cuenta cuántos valores hay en la lista de argumentos. +COUNTBLANK = CONTAR.BLANCO ## Cuenta el número de celdas en blanco de un rango. +COUNTIF = CONTAR.SI ## Cuenta el número de celdas, dentro del rango, que cumplen el criterio especificado. +COUNTIFS = CONTAR.SI.CONJUNTO ## Cuenta el número de celdas, dentro del rango, que cumplen varios criterios. +COVAR = COVAR ## Devuelve la covarianza, que es el promedio de los productos de las desviaciones para cada pareja de puntos de datos. +CRITBINOM = BINOM.CRIT ## Devuelve el menor valor cuya distribución binomial acumulativa es menor o igual a un valor de criterio. +DEVSQ = DESVIA2 ## Devuelve la suma de los cuadrados de las desviaciones. +EXPONDIST = DISTR.EXP ## Devuelve la distribución exponencial. +FDIST = DISTR.F ## Devuelve la distribución de probabilidad F. +FINV = DISTR.F.INV ## Devuelve la función inversa de la distribución de probabilidad F. +FISHER = FISHER ## Devuelve la transformación Fisher. +FISHERINV = PRUEBA.FISHER.INV ## Devuelve la función inversa de la transformación Fisher. +FORECAST = PRONOSTICO ## Devuelve un valor en una tendencia lineal. +FREQUENCY = FRECUENCIA ## Devuelve una distribución de frecuencia como una matriz vertical. +FTEST = PRUEBA.F ## Devuelve el resultado de una prueba F. +GAMMADIST = DISTR.GAMMA ## Devuelve la distribución gamma. +GAMMAINV = DISTR.GAMMA.INV ## Devuelve la función inversa de la distribución gamma acumulativa. +GAMMALN = GAMMA.LN ## Devuelve el logaritmo natural de la función gamma, G(x). +GEOMEAN = MEDIA.GEOM ## Devuelve la media geométrica. +GROWTH = CRECIMIENTO ## Devuelve valores en una tendencia exponencial. +HARMEAN = MEDIA.ARMO ## Devuelve la media armónica. +HYPGEOMDIST = DISTR.HIPERGEOM ## Devuelve la distribución hipergeométrica. +INTERCEPT = INTERSECCION.EJE ## Devuelve la intersección de la línea de regresión lineal. +KURT = CURTOSIS ## Devuelve la curtosis de un conjunto de datos. +LARGE = K.ESIMO.MAYOR ## Devuelve el k-ésimo mayor valor de un conjunto de datos. +LINEST = ESTIMACION.LINEAL ## Devuelve los parámetros de una tendencia lineal. +LOGEST = ESTIMACION.LOGARITMICA ## Devuelve los parámetros de una tendencia exponencial. +LOGINV = DISTR.LOG.INV ## Devuelve la función inversa de la distribución logarítmico-normal. +LOGNORMDIST = DISTR.LOG.NORM ## Devuelve la distribución logarítmico-normal acumulativa. +MAX = MAX ## Devuelve el valor máximo de una lista de argumentos. +MAXA = MAXA ## Devuelve el valor máximo de una lista de argumentos, incluidos números, texto y valores lógicos. +MEDIAN = MEDIANA ## Devuelve la mediana de los números dados. +MIN = MIN ## Devuelve el valor mínimo de una lista de argumentos. +MINA = MINA ## Devuelve el valor mínimo de una lista de argumentos, incluidos números, texto y valores lógicos. +MODE = MODA ## Devuelve el valor más común de un conjunto de datos. +NEGBINOMDIST = NEGBINOMDIST ## Devuelve la distribución binomial negativa. +NORMDIST = DISTR.NORM ## Devuelve la distribución normal acumulativa. +NORMINV = DISTR.NORM.INV ## Devuelve la función inversa de la distribución normal acumulativa. +NORMSDIST = DISTR.NORM.ESTAND ## Devuelve la distribución normal estándar acumulativa. +NORMSINV = DISTR.NORM.ESTAND.INV ## Devuelve la función inversa de la distribución normal estándar acumulativa. +PEARSON = PEARSON ## Devuelve el coeficiente de momento de correlación de producto Pearson. +PERCENTILE = PERCENTIL ## Devuelve el k-ésimo percentil de los valores de un rango. +PERCENTRANK = RANGO.PERCENTIL ## Devuelve el rango porcentual de un valor de un conjunto de datos. +PERMUT = PERMUTACIONES ## Devuelve el número de permutaciones de un número determinado de objetos. +POISSON = POISSON ## Devuelve la distribución de Poisson. +PROB = PROBABILIDAD ## Devuelve la probabilidad de que los valores de un rango se encuentren entre dos límites. +QUARTILE = CUARTIL ## Devuelve el cuartil de un conjunto de datos. +RANK = JERARQUIA ## Devuelve la jerarquía de un número en una lista de números. +RSQ = COEFICIENTE.R2 ## Devuelve el cuadrado del coeficiente de momento de correlación de producto Pearson. +SKEW = COEFICIENTE.ASIMETRIA ## Devuelve la asimetría de una distribución. +SLOPE = PENDIENTE ## Devuelve la pendiente de la línea de regresión lineal. +SMALL = K.ESIMO.MENOR ## Devuelve el k-ésimo menor valor de un conjunto de datos. +STANDARDIZE = NORMALIZACION ## Devuelve un valor normalizado. +STDEV = DESVEST ## Calcula la desviación estándar a partir de una muestra. +STDEVA = DESVESTA ## Calcula la desviación estándar a partir de una muestra, incluidos números, texto y valores lógicos. +STDEVP = DESVESTP ## Calcula la desviación estándar en función de toda la población. +STDEVPA = DESVESTPA ## Calcula la desviación estándar en función de toda la población, incluidos números, texto y valores lógicos. +STEYX = ERROR.TIPICO.XY ## Devuelve el error estándar del valor de "y" previsto para cada "x" de la regresión. +TDIST = DISTR.T ## Devuelve la distribución de t de Student. +TINV = DISTR.T.INV ## Devuelve la función inversa de la distribución de t de Student. +TREND = TENDENCIA ## Devuelve valores en una tendencia lineal. +TRIMMEAN = MEDIA.ACOTADA ## Devuelve la media del interior de un conjunto de datos. +TTEST = PRUEBA.T ## Devuelve la probabilidad asociada a una prueba t de Student. +VAR = VAR ## Calcula la varianza en función de una muestra. +VARA = VARA ## Calcula la varianza en función de una muestra, incluidos números, texto y valores lógicos. +VARP = VARP ## Calcula la varianza en función de toda la población. +VARPA = VARPA ## Calcula la varianza en función de toda la población, incluidos números, texto y valores lógicos. +WEIBULL = DIST.WEIBULL ## Devuelve la distribución de Weibull. +ZTEST = PRUEBA.Z ## Devuelve el valor de una probabilidad de una cola de una prueba z. + + +## +## Text functions Funciones de texto +## +ASC = ASC ## Convierte las letras inglesas o katakana de ancho completo (de dos bytes) dentro de una cadena de caracteres en caracteres de ancho medio (de un byte). +BAHTTEXT = TEXTOBAHT ## Convierte un número en texto, con el formato de moneda ß (Baht). +CHAR = CARACTER ## Devuelve el carácter especificado por el número de código. +CLEAN = LIMPIAR ## Quita del texto todos los caracteres no imprimibles. +CODE = CODIGO ## Devuelve un código numérico del primer carácter de una cadena de texto. +CONCATENATE = CONCATENAR ## Concatena varios elementos de texto en uno solo. +DOLLAR = MONEDA ## Convierte un número en texto, con el formato de moneda $ (dólar). +EXACT = IGUAL ## Comprueba si dos valores de texto son idénticos. +FIND = ENCONTRAR ## Busca un valor de texto dentro de otro (distingue mayúsculas de minúsculas). +FINDB = ENCONTRARB ## Busca un valor de texto dentro de otro (distingue mayúsculas de minúsculas). +FIXED = DECIMAL ## Da formato a un número como texto con un número fijo de decimales. +JIS = JIS ## Convierte las letras inglesas o katakana de ancho medio (de un byte) dentro de una cadena de caracteres en caracteres de ancho completo (de dos bytes). +LEFT = IZQUIERDA ## Devuelve los caracteres del lado izquierdo de un valor de texto. +LEFTB = IZQUIERDAB ## Devuelve los caracteres del lado izquierdo de un valor de texto. +LEN = LARGO ## Devuelve el número de caracteres de una cadena de texto. +LENB = LARGOB ## Devuelve el número de caracteres de una cadena de texto. +LOWER = MINUSC ## Pone el texto en minúsculas. +MID = EXTRAE ## Devuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique. +MIDB = EXTRAEB ## Devuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique. +PHONETIC = FONETICO ## Extrae los caracteres fonéticos (furigana) de una cadena de texto. +PROPER = NOMPROPIO ## Pone en mayúscula la primera letra de cada palabra de un valor de texto. +REPLACE = REEMPLAZAR ## Reemplaza caracteres de texto. +REPLACEB = REEMPLAZARB ## Reemplaza caracteres de texto. +REPT = REPETIR ## Repite el texto un número determinado de veces. +RIGHT = DERECHA ## Devuelve los caracteres del lado derecho de un valor de texto. +RIGHTB = DERECHAB ## Devuelve los caracteres del lado derecho de un valor de texto. +SEARCH = HALLAR ## Busca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas). +SEARCHB = HALLARB ## Busca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas). +SUBSTITUTE = SUSTITUIR ## Sustituye texto nuevo por texto antiguo en una cadena de texto. +T = T ## Convierte sus argumentos a texto. +TEXT = TEXTO ## Da formato a un número y lo convierte en texto. +TRIM = ESPACIOS ## Quita los espacios del texto. +UPPER = MAYUSC ## Pone el texto en mayúsculas. +VALUE = VALOR ## Convierte un argumento de texto en un número. diff --git a/extend/phpexcel/PHPExcel/locale/fi/config b/extend/phpexcel/PHPExcel/locale/fi/config new file mode 100755 index 0000000..380f397 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/fi/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = $ # Symbol not known, should it be a € (Euro)? + + +## +## Excel Error Codes (For future use) +## +NULL = #TYHJÄ! +DIV0 = #JAKO/0! +VALUE = #ARVO! +REF = #VIITTAUS! +NAME = #NIMI? +NUM = #LUKU! +NA = #PUUTTUU diff --git a/extend/phpexcel/PHPExcel/locale/fi/functions b/extend/phpexcel/PHPExcel/locale/fi/functions new file mode 100755 index 0000000..bf60bec --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/fi/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Apuohjelma- ja automaatiofunktiot +## +GETPIVOTDATA = NOUDA.PIVOT.TIEDOT ## Palauttaa pivot-taulukkoraporttiin tallennettuja tietoja. + + +## +## Cube functions Kuutiofunktiot +## +CUBEKPIMEMBER = KUUTIOKPIJÄSEN ## Palauttaa suorituskykyilmaisimen (KPI) nimen, ominaisuuden sekä mitan ja näyttää nimen sekä ominaisuuden solussa. KPI on mitattavissa oleva suure, kuten kuukauden bruttotuotto tai vuosineljänneksen työntekijäkohtainen liikevaihto, joiden avulla tarkkaillaan organisaation suorituskykyä. +CUBEMEMBER = KUUTIONJÄSEN ## Palauttaa kuutiohierarkian jäsenen tai monikon. Tällä funktiolla voit tarkistaa, että jäsen tai monikko on olemassa kuutiossa. +CUBEMEMBERPROPERTY = KUUTIONJÄSENENOMINAISUUS ## Palauttaa kuution jäsenominaisuuden arvon. Tällä funktiolla voit tarkistaa, että nimi on olemassa kuutiossa, ja palauttaa tämän jäsenen määritetyn ominaisuuden. +CUBERANKEDMEMBER = KUUTIONLUOKITELTUJÄSEN ## Palauttaa joukon n:nnen jäsenen. Tällä funktiolla voit palauttaa joukosta elementtejä, kuten parhaan myyjän tai 10 parasta opiskelijaa. +CUBESET = KUUTIOJOUKKO ## Määrittää lasketun jäsen- tai monikkojoukon lähettämällä joukon lausekkeita palvelimessa olevalle kuutiolle. Palvelin luo joukon ja palauttaa sen Microsoft Office Excelille. +CUBESETCOUNT = KUUTIOJOUKKOJENMÄÄRÄ ## Palauttaa joukon kohteiden määrän. +CUBEVALUE = KUUTIONARVO ## Palauttaa koostetun arvon kuutiosta. + + +## +## Database functions Tietokantafunktiot +## +DAVERAGE = TKESKIARVO ## Palauttaa valittujen tietokantamerkintöjen keskiarvon. +DCOUNT = TLASKE ## Laskee tietokannan lukuja sisältävien solujen määrän. +DCOUNTA = TLASKEA ## Laskee tietokannan tietoja sisältävien solujen määrän. +DGET = TNOUDA ## Hakee määritettyjä ehtoja vastaavan tietueen tietokannasta. +DMAX = TMAKS ## Palauttaa suurimman arvon tietokannasta valittujen arvojen joukosta. +DMIN = TMIN ## Palauttaa pienimmän arvon tietokannasta valittujen arvojen joukosta. +DPRODUCT = TTULO ## Kertoo määritetyn ehdon täyttävien tietokannan tietueiden tietyssä kentässä olevat arvot. +DSTDEV = TKESKIHAJONTA ## Laskee keskihajonnan tietokannasta valituista arvoista muodostuvan otoksen perusteella. +DSTDEVP = TKESKIHAJONTAP ## Laskee keskihajonnan tietokannasta valittujen arvojen koko populaation perusteella. +DSUM = TSUMMA ## Lisää luvut määritetyn ehdon täyttävien tietokannan tietueiden kenttäsarakkeeseen. +DVAR = TVARIANSSI ## Laskee varianssin tietokannasta valittujen arvojen otoksen perusteella. +DVARP = TVARIANSSIP ## Laskee varianssin tietokannasta valittujen arvojen koko populaation perusteella. + + +## +## Date and time functions Päivämäärä- ja aikafunktiot +## +DATE = PÄIVÄYS ## Palauttaa annetun päivämäärän järjestysluvun. +DATEVALUE = PÄIVÄYSARVO ## Muuntaa tekstimuodossa olevan päivämäärän järjestysluvuksi. +DAY = PÄIVÄ ## Muuntaa järjestysluvun kuukauden päiväksi. +DAYS360 = PÄIVÄT360 ## Laskee kahden päivämäärän välisten päivien määrän käyttäen perustana 360-päiväistä vuotta. +EDATE = PÄIVÄ.KUUKAUSI ## Palauttaa järjestyslukuna päivämäärän, joka poikkeaa aloituspäivän päivämäärästä annetun kuukausimäärän verran joko eteen- tai taaksepäin. +EOMONTH = KUUKAUSI.LOPPU ## Palauttaa järjestyslukuna sen kuukauden viimeisen päivämäärän, joka poikkeaa annetun kuukausimäärän verran eteen- tai taaksepäin. +HOUR = TUNNIT ## Muuntaa järjestysluvun tunneiksi. +MINUTE = MINUUTIT ## Muuntaa järjestysluvun minuuteiksi. +MONTH = KUUKAUSI ## Muuntaa järjestysluvun kuukausiksi. +NETWORKDAYS = TYÖPÄIVÄT ## Palauttaa kahden päivämäärän välissä olevien täysien työpäivien määrän. +NOW = NYT ## Palauttaa kuluvan päivämäärän ja ajan järjestysnumeron. +SECOND = SEKUNNIT ## Muuntaa järjestysluvun sekunneiksi. +TIME = AIKA ## Palauttaa annetun kellonajan järjestysluvun. +TIMEVALUE = AIKA_ARVO ## Muuntaa tekstimuodossa olevan kellonajan järjestysluvuksi. +TODAY = TÄMÄ.PÄIVÄ ## Palauttaa kuluvan päivän päivämäärän järjestysluvun. +WEEKDAY = VIIKONPÄIVÄ ## Muuntaa järjestysluvun viikonpäiväksi. +WEEKNUM = VIIKKO.NRO ## Muuntaa järjestysluvun luvuksi, joka ilmaisee viikon järjestysluvun vuoden alusta laskettuna. +WORKDAY = TYÖPÄIVÄ ## Palauttaa järjestysluvun päivämäärälle, joka sijaitsee annettujen työpäivien verran eteen tai taaksepäin. +YEAR = VUOSI ## Muuntaa järjestysluvun vuosiksi. +YEARFRAC = VUOSI.OSA ## Palauttaa määritettyjen päivämäärien (aloituspäivä ja lopetuspäivä) välisen osan vuodesta. + + +## +## Engineering functions Tekniset funktiot +## +BESSELI = BESSELI ## Palauttaa muunnetun Bessel-funktion In(x). +BESSELJ = BESSELJ ## Palauttaa Bessel-funktion Jn(x). +BESSELK = BESSELK ## Palauttaa muunnetun Bessel-funktion Kn(x). +BESSELY = BESSELY ## Palauttaa Bessel-funktion Yn(x). +BIN2DEC = BINDES ## Muuntaa binaariluvun desimaaliluvuksi. +BIN2HEX = BINHEKSA ## Muuntaa binaariluvun heksadesimaaliluvuksi. +BIN2OCT = BINOKT ## Muuntaa binaariluvun oktaaliluvuksi. +COMPLEX = KOMPLEKSI ## Muuntaa reaali- ja imaginaariosien kertoimet kompleksiluvuksi. +CONVERT = MUUNNA ## Muuntaa luvun toisen mittajärjestelmän mukaiseksi. +DEC2BIN = DESBIN ## Muuntaa desimaaliluvun binaariluvuksi. +DEC2HEX = DESHEKSA ## Muuntaa kymmenjärjestelmän luvun heksadesimaaliluvuksi. +DEC2OCT = DESOKT ## Muuntaa kymmenjärjestelmän luvun oktaaliluvuksi. +DELTA = SAMA.ARVO ## Tarkistaa, ovatko kaksi arvoa yhtä suuria. +ERF = VIRHEFUNKTIO ## Palauttaa virhefunktion. +ERFC = VIRHEFUNKTIO.KOMPLEMENTTI ## Palauttaa komplementtivirhefunktion. +GESTEP = RAJA ## Testaa, onko luku suurempi kuin kynnysarvo. +HEX2BIN = HEKSABIN ## Muuntaa heksadesimaaliluvun binaariluvuksi. +HEX2DEC = HEKSADES ## Muuntaa heksadesimaaliluvun desimaaliluvuksi. +HEX2OCT = HEKSAOKT ## Muuntaa heksadesimaaliluvun oktaaliluvuksi. +IMABS = KOMPLEKSI.ITSEISARVO ## Palauttaa kompleksiluvun itseisarvon (moduluksen). +IMAGINARY = KOMPLEKSI.IMAG ## Palauttaa kompleksiluvun imaginaariosan kertoimen. +IMARGUMENT = KOMPLEKSI.ARG ## Palauttaa theeta-argumentin, joka on radiaaneina annettu kulma. +IMCONJUGATE = KOMPLEKSI.KONJ ## Palauttaa kompleksiluvun konjugaattiluvun. +IMCOS = KOMPLEKSI.COS ## Palauttaa kompleksiluvun kosinin. +IMDIV = KOMPLEKSI.OSAM ## Palauttaa kahden kompleksiluvun osamäärän. +IMEXP = KOMPLEKSI.EKSP ## Palauttaa kompleksiluvun eksponentin. +IMLN = KOMPLEKSI.LN ## Palauttaa kompleksiluvun luonnollisen logaritmin. +IMLOG10 = KOMPLEKSI.LOG10 ## Palauttaa kompleksiluvun kymmenkantaisen logaritmin. +IMLOG2 = KOMPLEKSI.LOG2 ## Palauttaa kompleksiluvun kaksikantaisen logaritmin. +IMPOWER = KOMPLEKSI.POT ## Palauttaa kokonaislukupotenssiin korotetun kompleksiluvun. +IMPRODUCT = KOMPLEKSI.TULO ## Palauttaa kompleksilukujen tulon. +IMREAL = KOMPLEKSI.REAALI ## Palauttaa kompleksiluvun reaaliosan kertoimen. +IMSIN = KOMPLEKSI.SIN ## Palauttaa kompleksiluvun sinin. +IMSQRT = KOMPLEKSI.NELIÖJ ## Palauttaa kompleksiluvun neliöjuuren. +IMSUB = KOMPLEKSI.EROTUS ## Palauttaa kahden kompleksiluvun erotuksen. +IMSUM = KOMPLEKSI.SUM ## Palauttaa kompleksilukujen summan. +OCT2BIN = OKTBIN ## Muuntaa oktaaliluvun binaariluvuksi. +OCT2DEC = OKTDES ## Muuntaa oktaaliluvun desimaaliluvuksi. +OCT2HEX = OKTHEKSA ## Muuntaa oktaaliluvun heksadesimaaliluvuksi. + + +## +## Financial functions Rahoitusfunktiot +## +ACCRINT = KERTYNYT.KORKO ## Laskee arvopaperille kertyneen koron, kun korko kertyy säännöllisin väliajoin. +ACCRINTM = KERTYNYT.KORKO.LOPUSSA ## Laskee arvopaperille kertyneen koron, kun korko maksetaan eräpäivänä. +AMORDEGRC = AMORDEGRC ## Laskee kunkin laskentakauden poiston poistokerrointa käyttämällä. +AMORLINC = AMORLINC ## Palauttaa kunkin laskentakauden poiston. +COUPDAYBS = KORKOPÄIVÄT.ALUSTA ## Palauttaa koronmaksukauden aloituspäivän ja tilityspäivän välisen ajanjakson päivien määrän. +COUPDAYS = KORKOPÄIVÄT ## Palauttaa päivien määrän koronmaksukaudelta, johon tilityspäivä kuuluu. +COUPDAYSNC = KORKOPÄIVÄT.SEURAAVA ## Palauttaa tilityspäivän ja seuraavan koronmaksupäivän välisen ajanjakson päivien määrän. +COUPNCD = KORKOMAKSU.SEURAAVA ## Palauttaa tilityspäivän jälkeisen seuraavan koronmaksupäivän. +COUPNUM = KORKOPÄIVÄJAKSOT ## Palauttaa arvopaperin ostopäivän ja erääntymispäivän välisten koronmaksupäivien määrän. +COUPPCD = KORKOPÄIVÄ.EDELLINEN ## Palauttaa tilityspäivää edeltävän koronmaksupäivän. +CUMIPMT = MAKSETTU.KORKO ## Palauttaa kahden jakson välisenä aikana kertyneen koron. +CUMPRINC = MAKSETTU.LYHENNYS ## Palauttaa lainalle kahden jakson välisenä aikana kertyneen lyhennyksen. +DB = DB ## Palauttaa kauden kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan. +DDB = DDB ## Palauttaa kauden kirjanpidollisen poiston amerikkalaisen DDB-menetelmän (Double-Declining Balance) tai jonkin muun määrittämäsi menetelmän mukaan. +DISC = DISKONTTOKORKO ## Palauttaa arvopaperin diskonttokoron. +DOLLARDE = VALUUTTA.DES ## Muuntaa murtolukuna ilmoitetun valuuttamäärän desimaaliluvuksi. +DOLLARFR = VALUUTTA.MURTO ## Muuntaa desimaalilukuna ilmaistun valuuttamäärän murtoluvuksi. +DURATION = KESTO ## Palauttaa keston arvopaperille, jonka koronmaksu tapahtuu säännöllisesti. +EFFECT = KORKO.EFEKT ## Palauttaa todellisen vuosikoron. +FV = TULEVA.ARVO ## Palauttaa sijoituksen tulevan arvon. +FVSCHEDULE = TULEVA.ARVO.ERIKORKO ## Palauttaa pääoman tulevan arvon, kun pääomalle on kertynyt korkoa vaihtelevasti. +INTRATE = KORKO.ARVOPAPERI ## Palauttaa arvopaperin korkokannan täysin sijoitetulle arvopaperille. +IPMT = IPMT ## Laskee sijoitukselle tai lainalle tiettynä ajanjaksona kertyvän koron. +IRR = SISÄINEN.KORKO ## Laskee sisäisen korkokannan kassavirrasta muodostuvalle sarjalle. +ISPMT = ONMAKSU ## Laskee sijoituksen maksetun koron tietyllä jaksolla. +MDURATION = KESTO.MUUNN ## Palauttaa muunnetun Macauley-keston arvopaperille, jonka oletettu nimellisarvo on 100 euroa. +MIRR = MSISÄINEN ## Palauttaa sisäisen korkokannan, kun positiivisten ja negatiivisten kassavirtojen rahoituskorko on erilainen. +NOMINAL = KORKO.VUOSI ## Palauttaa vuosittaisen nimelliskoron. +NPER = NJAKSO ## Palauttaa sijoituksen jaksojen määrän. +NPV = NNA ## Palauttaa sijoituksen nykyarvon toistuvista kassavirroista muodostuvan sarjan ja diskonttokoron perusteella. +ODDFPRICE = PARITON.ENS.NIMELLISARVO ## Palauttaa arvopaperin hinnan tilanteessa, jossa ensimmäinen jakso on pariton. +ODDFYIELD = PARITON.ENS.TUOTTO ## Palauttaa arvopaperin tuoton tilanteessa, jossa ensimmäinen jakso on pariton. +ODDLPRICE = PARITON.VIIM.NIMELLISARVO ## Palauttaa arvopaperin hinnan tilanteessa, jossa viimeinen jakso on pariton. +ODDLYIELD = PARITON.VIIM.TUOTTO ## Palauttaa arvopaperin tuoton tilanteessa, jossa viimeinen jakso on pariton. +PMT = MAKSU ## Palauttaa annuiteetin kausittaisen maksuerän. +PPMT = PPMT ## Laskee sijoitukselle tai lainalle tiettynä ajanjaksona maksettavan lyhennyksen. +PRICE = HINTA ## Palauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan säännöllisin väliajoin. +PRICEDISC = HINTA.DISK ## Palauttaa diskontatun arvopaperin hinnan 100 euron nimellisarvoa kohden. +PRICEMAT = HINTA.LUNASTUS ## Palauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan erääntymispäivänä. +PV = NA ## Palauttaa sijoituksen nykyarvon. +RATE = KORKO ## Palauttaa annuiteetin kausittaisen korkokannan. +RECEIVED = SAATU.HINTA ## Palauttaa arvopaperin tuoton erääntymispäivänä kokonaan maksetulle sijoitukselle. +SLN = STP ## Palauttaa sijoituksen tasapoiston yhdeltä jaksolta. +SYD = VUOSIPOISTO ## Palauttaa sijoituksen vuosipoiston annettuna kautena amerikkalaisen SYD-menetelmän (Sum-of-Year's Digits) avulla. +TBILLEQ = OBLIG.TUOTTOPROS ## Palauttaa valtion obligaation tuoton vastaavana joukkovelkakirjan tuottona. +TBILLPRICE = OBLIG.HINTA ## Palauttaa obligaation hinnan 100 euron nimellisarvoa kohden. +TBILLYIELD = OBLIG.TUOTTO ## Palauttaa obligaation tuoton. +VDB = VDB ## Palauttaa annetun kauden tai kauden osan kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan. +XIRR = SISÄINEN.KORKO.JAKSOTON ## Palauttaa sisäisen korkokannan kassavirtojen sarjoille, jotka eivät välttämättä ole säännöllisiä. +XNPV = NNA.JAKSOTON ## Palauttaa nettonykyarvon kassavirtasarjalle, joka ei välttämättä ole kausittainen. +YIELD = TUOTTO ## Palauttaa tuoton arvopaperille, jonka korko maksetaan säännöllisin väliajoin. +YIELDDISC = TUOTTO.DISK ## Palauttaa diskontatun arvopaperin, kuten obligaation, vuosittaisen tuoton. +YIELDMAT = TUOTTO.ERÄP ## Palauttaa erääntymispäivänään korkoa tuottavan arvopaperin vuosittaisen tuoton. + + +## +## Information functions Erikoisfunktiot +## +CELL = SOLU ## Palauttaa tietoja solun muotoilusta, sijainnista ja sisällöstä. +ERROR.TYPE = VIRHEEN.LAJI ## Palauttaa virhetyyppiä vastaavan luvun. +INFO = KUVAUS ## Palauttaa tietoja nykyisestä käyttöympäristöstä. +ISBLANK = ONTYHJÄ ## Palauttaa arvon TOSI, jos arvo on tyhjä. +ISERR = ONVIRH ## Palauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo paitsi arvo #PUUTTUU!. +ISERROR = ONVIRHE ## Palauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo. +ISEVEN = ONPARILLINEN ## Palauttaa arvon TOSI, jos arvo on parillinen. +ISLOGICAL = ONTOTUUS ## Palauttaa arvon TOSI, jos arvo on mikä tahansa looginen arvo. +ISNA = ONPUUTTUU ## Palauttaa arvon TOSI, jos virhearvo on #PUUTTUU!. +ISNONTEXT = ONEI_TEKSTI ## Palauttaa arvon TOSI, jos arvo ei ole teksti. +ISNUMBER = ONLUKU ## Palauttaa arvon TOSI, jos arvo on luku. +ISODD = ONPARITON ## Palauttaa arvon TOSI, jos arvo on pariton. +ISREF = ONVIITT ## Palauttaa arvon TOSI, jos arvo on viittaus. +ISTEXT = ONTEKSTI ## Palauttaa arvon TOSI, jos arvo on teksti. +N = N ## Palauttaa arvon luvuksi muunnettuna. +NA = PUUTTUU ## Palauttaa virhearvon #PUUTTUU!. +TYPE = TYYPPI ## Palauttaa luvun, joka ilmaisee arvon tietotyypin. + + +## +## Logical functions Loogiset funktiot +## +AND = JA ## Palauttaa arvon TOSI, jos kaikkien argumenttien arvo on TOSI. +FALSE = EPÄTOSI ## Palauttaa totuusarvon EPÄTOSI. +IF = JOS ## Määrittää suoritettavan loogisen testin. +IFERROR = JOSVIRHE ## Palauttaa määrittämäsi arvon, jos kaavan tulos on virhe; muussa tapauksessa palauttaa kaavan tuloksen. +NOT = EI ## Kääntää argumentin loogisen arvon. +OR = TAI ## Palauttaa arvon TOSI, jos minkä tahansa argumentin arvo on TOSI. +TRUE = TOSI ## Palauttaa totuusarvon TOSI. + + +## +## Lookup and reference functions Haku- ja viitefunktiot +## +ADDRESS = OSOITE ## Palauttaa laskentataulukon soluun osoittavan viittauksen tekstinä. +AREAS = ALUEET ## Palauttaa viittauksessa olevien alueiden määrän. +CHOOSE = VALITSE.INDEKSI ## Valitsee arvon arvoluettelosta. +COLUMN = SARAKE ## Palauttaa viittauksen sarakenumeron. +COLUMNS = SARAKKEET ## Palauttaa viittauksessa olevien sarakkeiden määrän. +HLOOKUP = VHAKU ## Suorittaa haun matriisin ylimmältä riviltä ja palauttaa määritetyn solun arvon. +HYPERLINK = HYPERLINKKI ## Luo pikakuvakkeen tai tekstin, joka avaa verkkopalvelimeen, intranetiin tai Internetiin tallennetun tiedoston. +INDEX = INDEKSI ## Valitsee arvon viittauksesta tai matriisista indeksin mukaan. +INDIRECT = EPÄSUORA ## Palauttaa tekstiarvona ilmaistun viittauksen. +LOOKUP = HAKU ## Etsii arvoja vektorista tai matriisista. +MATCH = VASTINE ## Etsii arvoja viittauksesta tai matriisista. +OFFSET = SIIRTYMÄ ## Palauttaa annetun viittauksen siirtymän. +ROW = RIVI ## Palauttaa viittauksen rivinumeron. +ROWS = RIVIT ## Palauttaa viittauksessa olevien rivien määrän. +RTD = RTD ## Noutaa COM-automaatiota (automaatio: Tapa käsitellä sovelluksen objekteja toisesta sovelluksesta tai kehitystyökalusta. Automaatio, jota aiemmin kutsuttiin OLE-automaatioksi, on teollisuusstandardi ja COM-mallin (Component Object Model) ominaisuus.) tukevasta ohjelmasta reaaliaikaisia tietoja. +TRANSPOSE = TRANSPONOI ## Palauttaa matriisin käänteismatriisin. +VLOOKUP = PHAKU ## Suorittaa haun matriisin ensimmäisestä sarakkeesta ja palauttaa rivillä olevan solun arvon. + + +## +## Math and trigonometry functions Matemaattiset ja trigonometriset funktiot +## +ABS = ITSEISARVO ## Palauttaa luvun itseisarvon. +ACOS = ACOS ## Palauttaa luvun arkuskosinin. +ACOSH = ACOSH ## Palauttaa luvun käänteisen hyperbolisen kosinin. +ASIN = ASIN ## Palauttaa luvun arkussinin. +ASINH = ASINH ## Palauttaa luvun käänteisen hyperbolisen sinin. +ATAN = ATAN ## Palauttaa luvun arkustangentin. +ATAN2 = ATAN2 ## Palauttaa arkustangentin x- ja y-koordinaatin perusteella. +ATANH = ATANH ## Palauttaa luvun käänteisen hyperbolisen tangentin. +CEILING = PYÖRISTÄ.KERR.YLÖS ## Pyöristää luvun lähimpään kokonaislukuun tai tarkkuusargumentin lähimpään kerrannaiseen. +COMBIN = KOMBINAATIO ## Palauttaa mahdollisten kombinaatioiden määrän annetulle objektien määrälle. +COS = COS ## Palauttaa luvun kosinin. +COSH = COSH ## Palauttaa luvun hyperbolisen kosinin. +DEGREES = ASTEET ## Muuntaa radiaanit asteiksi. +EVEN = PARILLINEN ## Pyöristää luvun ylöspäin lähimpään parilliseen kokonaislukuun. +EXP = EKSPONENTTI ## Palauttaa e:n korotettuna annetun luvun osoittamaan potenssiin. +FACT = KERTOMA ## Palauttaa luvun kertoman. +FACTDOUBLE = KERTOMA.OSA ## Palauttaa luvun osakertoman. +FLOOR = PYÖRISTÄ.KERR.ALAS ## Pyöristää luvun alaspäin (nollaa kohti). +GCD = SUURIN.YHT.TEKIJÄ ## Palauttaa suurimman yhteisen tekijän. +INT = KOKONAISLUKU ## Pyöristää luvun alaspäin lähimpään kokonaislukuun. +LCM = PIENIN.YHT.JAETTAVA ## Palauttaa pienimmän yhteisen tekijän. +LN = LUONNLOG ## Palauttaa luvun luonnollisen logaritmin. +LOG = LOG ## Laskee luvun logaritmin käyttämällä annettua kantalukua. +LOG10 = LOG10 ## Palauttaa luvun kymmenkantaisen logaritmin. +MDETERM = MDETERM ## Palauttaa matriisin matriisideterminantin. +MINVERSE = MKÄÄNTEINEN ## Palauttaa matriisin käänteismatriisin. +MMULT = MKERRO ## Palauttaa kahden matriisin tulon. +MOD = JAKOJ ## Palauttaa jakolaskun jäännöksen. +MROUND = PYÖRISTÄ.KERR ## Palauttaa luvun pyöristettynä annetun luvun kerrannaiseen. +MULTINOMIAL = MULTINOMI ## Palauttaa lukujoukon multinomin. +ODD = PARITON ## Pyöristää luvun ylöspäin lähimpään parittomaan kokonaislukuun. +PI = PII ## Palauttaa piin arvon. +POWER = POTENSSI ## Palauttaa luvun korotettuna haluttuun potenssiin. +PRODUCT = TULO ## Kertoo annetut argumentit. +QUOTIENT = OSAMÄÄRÄ ## Palauttaa osamäärän kokonaislukuosan. +RADIANS = RADIAANIT ## Muuntaa asteet radiaaneiksi. +RAND = SATUNNAISLUKU ## Palauttaa satunnaisluvun väliltä 0–1. +RANDBETWEEN = SATUNNAISLUKU.VÄLILTÄ ## Palauttaa satunnaisluvun määritettyjen lukujen väliltä. +ROMAN = ROMAN ## Muuntaa arabialaisen numeron tekstimuotoiseksi roomalaiseksi numeroksi. +ROUND = PYÖRISTÄ ## Pyöristää luvun annettuun määrään desimaaleja. +ROUNDDOWN = PYÖRISTÄ.DES.ALAS ## Pyöristää luvun alaspäin (nollaa kohti). +ROUNDUP = PYÖRISTÄ.DES.YLÖS ## Pyöristää luvun ylöspäin (poispäin nollasta). +SERIESSUM = SARJA.SUMMA ## Palauttaa kaavaan perustuvan potenssisarjan arvon. +SIGN = ETUMERKKI ## Palauttaa luvun etumerkin. +SIN = SIN ## Palauttaa annetun kulman sinin. +SINH = SINH ## Palauttaa luvun hyperbolisen sinin. +SQRT = NELIÖJUURI ## Palauttaa positiivisen neliöjuuren. +SQRTPI = NELIÖJUURI.PII ## Palauttaa tulon (luku * pii) neliöjuuren. +SUBTOTAL = VÄLISUMMA ## Palauttaa luettelon tai tietokannan välisumman. +SUM = SUMMA ## Laskee yhteen annetut argumentit. +SUMIF = SUMMA.JOS ## Laskee ehdot täyttävien solujen summan. +SUMIFS = SUMMA.JOS.JOUKKO ## Laskee yhteen solualueen useita ehtoja vastaavat solut. +SUMPRODUCT = TULOJEN.SUMMA ## Palauttaa matriisin toisiaan vastaavien osien tulojen summan. +SUMSQ = NELIÖSUMMA ## Palauttaa argumenttien neliöiden summan. +SUMX2MY2 = NELIÖSUMMIEN.EROTUS ## Palauttaa kahden matriisin toisiaan vastaavien arvojen laskettujen neliösummien erotuksen. +SUMX2PY2 = NELIÖSUMMIEN.SUMMA ## Palauttaa kahden matriisin toisiaan vastaavien arvojen neliösummien summan. +SUMXMY2 = EROTUSTEN.NELIÖSUMMA ## Palauttaa kahden matriisin toisiaan vastaavien arvojen erotusten neliösumman. +TAN = TAN ## Palauttaa luvun tangentin. +TANH = TANH ## Palauttaa luvun hyperbolisen tangentin. +TRUNC = KATKAISE ## Katkaisee luvun kokonaisluvuksi. + + +## +## Statistical functions Tilastolliset funktiot +## +AVEDEV = KESKIPOIKKEAMA ## Palauttaa hajontojen itseisarvojen keskiarvon. +AVERAGE = KESKIARVO ## Palauttaa argumenttien keskiarvon. +AVERAGEA = KESKIARVOA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, keskiarvon. +AVERAGEIF = KESKIARVO.JOS ## Palauttaa alueen niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka täyttävät annetut ehdot. +AVERAGEIFS = KESKIARVO.JOS.JOUKKO ## Palauttaa niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka vastaavat useita ehtoja. +BETADIST = BEETAJAKAUMA ## Palauttaa kumulatiivisen beetajakaumafunktion arvon. +BETAINV = BEETAJAKAUMA.KÄÄNT ## Palauttaa määritetyn beetajakauman käänteisen kumulatiivisen jakaumafunktion arvon. +BINOMDIST = BINOMIJAKAUMA ## Palauttaa yksittäisen termin binomijakaumatodennäköisyyden. +CHIDIST = CHIJAKAUMA ## Palauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden. +CHIINV = CHIJAKAUMA.KÄÄNT ## Palauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden käänteisarvon. +CHITEST = CHITESTI ## Palauttaa riippumattomuustestin tuloksen. +CONFIDENCE = LUOTTAMUSVÄLI ## Palauttaa luottamusvälin populaation keskiarvolle. +CORREL = KORRELAATIO ## Palauttaa kahden arvojoukon korrelaatiokertoimen. +COUNT = LASKE ## Laskee argumenttiluettelossa olevien lukujen määrän. +COUNTA = LASKE.A ## Laskee argumenttiluettelossa olevien arvojen määrän. +COUNTBLANK = LASKE.TYHJÄT ## Laskee alueella olevien tyhjien solujen määrän. +COUNTIF = LASKE.JOS ## Laskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa annettuja ehtoja. +COUNTIFS = LASKE.JOS.JOUKKO ## Laskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa useita ehtoja. +COVAR = KOVARIANSSI ## Palauttaa kovarianssin, joka on keskiarvo havaintoaineiston kunkin pisteparin poikkeamien tuloista. +CRITBINOM = BINOMIJAKAUMA.KRIT ## Palauttaa pienimmän arvon, jossa binomijakauman kertymäfunktion arvo on pienempi tai yhtä suuri kuin vertailuarvo. +DEVSQ = OIKAISTU.NELIÖSUMMA ## Palauttaa keskipoikkeamien neliösumman. +EXPONDIST = EKSPONENTIAALIJAKAUMA ## Palauttaa eksponentiaalijakauman. +FDIST = FJAKAUMA ## Palauttaa F-todennäköisyysjakauman. +FINV = FJAKAUMA.KÄÄNT ## Palauttaa F-todennäköisyysjakauman käänteisfunktion. +FISHER = FISHER ## Palauttaa Fisher-muunnoksen. +FISHERINV = FISHER.KÄÄNT ## Palauttaa käänteisen Fisher-muunnoksen. +FORECAST = ENNUSTE ## Palauttaa lineaarisen trendin arvon. +FREQUENCY = TAAJUUS ## Palauttaa frekvenssijakautuman pystysuuntaisena matriisina. +FTEST = FTESTI ## Palauttaa F-testin tuloksen. +GAMMADIST = GAMMAJAKAUMA ## Palauttaa gammajakauman. +GAMMAINV = GAMMAJAKAUMA.KÄÄNT ## Palauttaa käänteisen gammajakauman kertymäfunktion. +GAMMALN = GAMMALN ## Palauttaa gammafunktion luonnollisen logaritmin G(x). +GEOMEAN = KESKIARVO.GEOM ## Palauttaa geometrisen keskiarvon. +GROWTH = KASVU ## Palauttaa eksponentiaalisen trendin arvon. +HARMEAN = KESKIARVO.HARM ## Palauttaa harmonisen keskiarvon. +HYPGEOMDIST = HYPERGEOM.JAKAUMA ## Palauttaa hypergeometrisen jakauman. +INTERCEPT = LEIKKAUSPISTE ## Palauttaa lineaarisen regressiosuoran leikkauspisteen. +KURT = KURT ## Palauttaa tietoalueen vinous-arvon eli huipukkuuden. +LARGE = SUURI ## Palauttaa tietojoukon k:nneksi suurimman arvon. +LINEST = LINREGR ## Palauttaa lineaarisen trendin parametrit. +LOGEST = LOGREGR ## Palauttaa eksponentiaalisen trendin parametrit. +LOGINV = LOGNORM.JAKAUMA.KÄÄNT ## Palauttaa lognormeeratun jakauman käänteisfunktion. +LOGNORMDIST = LOGNORM.JAKAUMA ## Palauttaa lognormaalisen jakauman kertymäfunktion. +MAX = MAKS ## Palauttaa suurimman arvon argumenttiluettelosta. +MAXA = MAKSA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, suurimman arvon. +MEDIAN = MEDIAANI ## Palauttaa annettujen lukujen mediaanin. +MIN = MIN ## Palauttaa pienimmän arvon argumenttiluettelosta. +MINA = MINA ## Palauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, pienimmän arvon. +MODE = MOODI ## Palauttaa tietojoukossa useimmin esiintyvän arvon. +NEGBINOMDIST = BINOMIJAKAUMA.NEG ## Palauttaa negatiivisen binomijakauman. +NORMDIST = NORM.JAKAUMA ## Palauttaa normaalijakauman kertymäfunktion. +NORMINV = NORM.JAKAUMA.KÄÄNT ## Palauttaa käänteisen normaalijakauman kertymäfunktion. +NORMSDIST = NORM.JAKAUMA.NORMIT ## Palauttaa normitetun normaalijakauman kertymäfunktion. +NORMSINV = NORM.JAKAUMA.NORMIT.KÄÄNT ## Palauttaa normitetun normaalijakauman kertymäfunktion käänteisarvon. +PEARSON = PEARSON ## Palauttaa Pearsonin tulomomenttikorrelaatiokertoimen. +PERCENTILE = PROSENTTIPISTE ## Palauttaa alueen arvojen k:nnen prosenttipisteen. +PERCENTRANK = PROSENTTIJÄRJESTYS ## Palauttaa tietojoukon arvon prosentuaalisen järjestysluvun. +PERMUT = PERMUTAATIO ## Palauttaa mahdollisten permutaatioiden määrän annetulle objektien määrälle. +POISSON = POISSON ## Palauttaa Poissonin todennäköisyysjakauman. +PROB = TODENNÄKÖISYYS ## Palauttaa todennäköisyyden sille, että arvot ovat tietyltä väliltä. +QUARTILE = NELJÄNNES ## Palauttaa tietoalueen neljänneksen. +RANK = ARVON.MUKAAN ## Palauttaa luvun paikan lukuarvoluettelossa. +RSQ = PEARSON.NELIÖ ## Palauttaa Pearsonin tulomomenttikorrelaatiokertoimen neliön. +SKEW = JAKAUMAN.VINOUS ## Palauttaa jakauman vinouden. +SLOPE = KULMAKERROIN ## Palauttaa lineaarisen regressiosuoran kulmakertoimen. +SMALL = PIENI ## Palauttaa tietojoukon k:nneksi pienimmän arvon. +STANDARDIZE = NORMITA ## Palauttaa normitetun arvon. +STDEV = KESKIHAJONTA ## Laskee populaation keskihajonnan otoksen perusteella. +STDEVA = KESKIHAJONTAA ## Laskee populaation keskihajonnan otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot. +STDEVP = KESKIHAJONTAP ## Laskee normaalijakautuman koko populaation perusteella. +STDEVPA = KESKIHAJONTAPA ## Laskee populaation keskihajonnan koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot. +STEYX = KESKIVIRHE ## Palauttaa regression kutakin x-arvoa vastaavan ennustetun y-arvon keskivirheen. +TDIST = TJAKAUMA ## Palauttaa t-jakautuman. +TINV = TJAKAUMA.KÄÄNT ## Palauttaa käänteisen t-jakauman. +TREND = SUUNTAUS ## Palauttaa lineaarisen trendin arvoja. +TRIMMEAN = KESKIARVO.TASATTU ## Palauttaa tietojoukon tasatun keskiarvon. +TTEST = TTESTI ## Palauttaa t-testiin liittyvän todennäköisyyden. +VAR = VAR ## Arvioi populaation varianssia otoksen perusteella. +VARA = VARA ## Laskee populaation varianssin otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot. +VARP = VARP ## Laskee varianssin koko populaation perusteella. +VARPA = VARPA ## Laskee populaation varianssin koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot. +WEIBULL = WEIBULL ## Palauttaa Weibullin jakauman. +ZTEST = ZTESTI ## Palauttaa z-testin yksisuuntaisen todennäköisyysarvon. + + +## +## Text functions Tekstifunktiot +## +ASC = ASC ## Muuntaa merkkijonossa olevat englanninkieliset DBCS- tai katakana-merkit SBCS-merkeiksi. +BAHTTEXT = BAHTTEKSTI ## Muuntaa luvun tekstiksi ß (baht) -valuuttamuotoa käyttämällä. +CHAR = MERKKI ## Palauttaa koodin lukua vastaavan merkin. +CLEAN = SIIVOA ## Poistaa tekstistä kaikki tulostumattomat merkit. +CODE = KOODI ## Palauttaa tekstimerkkijonon ensimmäisen merkin numerokoodin. +CONCATENATE = KETJUTA ## Yhdistää useat merkkijonot yhdeksi merkkijonoksi. +DOLLAR = VALUUTTA ## Muuntaa luvun tekstiksi $ (dollari) -valuuttamuotoa käyttämällä. +EXACT = VERTAA ## Tarkistaa, ovatko kaksi tekstiarvoa samanlaiset. +FIND = ETSI ## Etsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet). +FINDB = ETSIB ## Etsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet). +FIXED = KIINTEÄ ## Muotoilee luvun tekstiksi, jossa on kiinteä määrä desimaaleja. +JIS = JIS ## Muuntaa merkkijonossa olevat englanninkieliset SBCS- tai katakana-merkit DBCS-merkeiksi. +LEFT = VASEN ## Palauttaa tekstiarvon vasemmanpuoliset merkit. +LEFTB = VASENB ## Palauttaa tekstiarvon vasemmanpuoliset merkit. +LEN = PITUUS ## Palauttaa tekstimerkkijonon merkkien määrän. +LENB = PITUUSB ## Palauttaa tekstimerkkijonon merkkien määrän. +LOWER = PIENET ## Muuntaa tekstin pieniksi kirjaimiksi. +MID = POIMI.TEKSTI ## Palauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta. +MIDB = POIMI.TEKSTIB ## Palauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta. +PHONETIC = FONEETTINEN ## Hakee foneettiset (furigana) merkit merkkijonosta. +PROPER = ERISNIMI ## Muuttaa merkkijonon kunkin sanan ensimmäisen kirjaimen isoksi. +REPLACE = KORVAA ## Korvaa tekstissä olevat merkit. +REPLACEB = KORVAAB ## Korvaa tekstissä olevat merkit. +REPT = TOISTA ## Toistaa tekstin annetun määrän kertoja. +RIGHT = OIKEA ## Palauttaa tekstiarvon oikeanpuoliset merkit. +RIGHTB = OIKEAB ## Palauttaa tekstiarvon oikeanpuoliset merkit. +SEARCH = KÄY.LÄPI ## Etsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi). +SEARCHB = KÄY.LÄPIB ## Etsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi). +SUBSTITUTE = VAIHDA ## Korvaa merkkijonossa olevan tekstin toisella. +T = T ## Muuntaa argumentit tekstiksi. +TEXT = TEKSTI ## Muotoilee luvun ja muuntaa sen tekstiksi. +TRIM = POISTA.VÄLIT ## Poistaa välilyönnit tekstistä. +UPPER = ISOT ## Muuntaa tekstin isoiksi kirjaimiksi. +VALUE = ARVO ## Muuntaa tekstiargumentin luvuksi. diff --git a/extend/phpexcel/PHPExcel/locale/fr/config b/extend/phpexcel/PHPExcel/locale/fr/config new file mode 100755 index 0000000..368b3c3 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/fr/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NUL! +DIV0 = #DIV/0! +VALUE = #VALEUR! +REF = #REF! +NAME = #NOM? +NUM = #NOMBRE! +NA = #N/A diff --git a/extend/phpexcel/PHPExcel/locale/fr/functions b/extend/phpexcel/PHPExcel/locale/fr/functions new file mode 100755 index 0000000..e85dba5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/fr/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Fonctions de complément et d’automatisation +## +GETPIVOTDATA = LIREDONNEESTABCROISDYNAMIQUE ## Renvoie les données stockées dans un rapport de tableau croisé dynamique. + + +## +## Cube functions Fonctions Cube +## +CUBEKPIMEMBER = MEMBREKPICUBE ## Renvoie un nom, une propriété et une mesure d’indicateur de performance clé et affiche le nom et la propriété dans la cellule. Un indicateur de performance clé est une mesure quantifiable, telle que la marge bénéficiaire brute mensuelle ou la rotation trimestrielle du personnel, utilisée pour évaluer les performances d’une entreprise. +CUBEMEMBER = MEMBRECUBE ## Renvoie un membre ou un uplet dans une hiérarchie de cubes. Utilisez cette fonction pour valider l’existence du membre ou de l’uplet dans le cube. +CUBEMEMBERPROPERTY = PROPRIETEMEMBRECUBE ## Renvoie la valeur d’une propriété de membre du cube. Utilisez cette fonction pour valider l’existence d’un nom de membre dans le cube et pour renvoyer la propriété spécifiée pour ce membre. +CUBERANKEDMEMBER = RANGMEMBRECUBE ## Renvoie le nième membre ou le membre placé à un certain rang dans un ensemble. Utilisez cette fonction pour renvoyer un ou plusieurs éléments d’un ensemble, tels que les meilleurs vendeurs ou les 10 meilleurs étudiants. +CUBESET = JEUCUBE ## Définit un ensemble calculé de membres ou d’uplets en envoyant une expression définie au cube sur le serveur qui crée l’ensemble et le renvoie à Microsoft Office Excel. +CUBESETCOUNT = NBJEUCUBE ## Renvoie le nombre d’éléments dans un jeu. +CUBEVALUE = VALEURCUBE ## Renvoie une valeur d’agrégation issue d’un cube. + + +## +## Database functions Fonctions de base de données +## +DAVERAGE = BDMOYENNE ## Renvoie la moyenne des entrées de base de données sélectionnées. +DCOUNT = BCOMPTE ## Compte le nombre de cellules d’une base de données qui contiennent des nombres. +DCOUNTA = BDNBVAL ## Compte les cellules non vides d’une base de données. +DGET = BDLIRE ## Extrait d’une base de données un enregistrement unique répondant aux critères spécifiés. +DMAX = BDMAX ## Renvoie la valeur maximale des entrées de base de données sélectionnées. +DMIN = BDMIN ## Renvoie la valeur minimale des entrées de base de données sélectionnées. +DPRODUCT = BDPRODUIT ## Multiplie les valeurs d’un champ particulier des enregistrements d’une base de données, qui répondent aux critères spécifiés. +DSTDEV = BDECARTYPE ## Calcule l’écart type pour un échantillon d’entrées de base de données sélectionnées. +DSTDEVP = BDECARTYPEP ## Calcule l’écart type pour l’ensemble d’une population d’entrées de base de données sélectionnées. +DSUM = BDSOMME ## Ajoute les nombres dans la colonne de champ des enregistrements de la base de données, qui répondent aux critères. +DVAR = BDVAR ## Calcule la variance pour un échantillon d’entrées de base de données sélectionnées. +DVARP = BDVARP ## Calcule la variance pour l’ensemble d’une population d’entrées de base de données sélectionnées. + + +## +## Date and time functions Fonctions de date et d’heure +## +DATE = DATE ## Renvoie le numéro de série d’une date précise. +DATEVALUE = DATEVAL ## Convertit une date représentée sous forme de texte en numéro de série. +DAY = JOUR ## Convertit un numéro de série en jour du mois. +DAYS360 = JOURS360 ## Calcule le nombre de jours qui séparent deux dates sur la base d’une année de 360 jours. +EDATE = MOIS.DECALER ## Renvoie le numéro séquentiel de la date qui représente une date spécifiée (l’argument date_départ), corrigée en plus ou en moins du nombre de mois indiqué. +EOMONTH = FIN.MOIS ## Renvoie le numéro séquentiel de la date du dernier jour du mois précédant ou suivant la date_départ du nombre de mois indiqué. +HOUR = HEURE ## Convertit un numéro de série en heure. +MINUTE = MINUTE ## Convertit un numéro de série en minute. +MONTH = MOIS ## Convertit un numéro de série en mois. +NETWORKDAYS = NB.JOURS.OUVRES ## Renvoie le nombre de jours ouvrés entiers compris entre deux dates. +NOW = MAINTENANT ## Renvoie le numéro de série de la date et de l’heure du jour. +SECOND = SECONDE ## Convertit un numéro de série en seconde. +TIME = TEMPS ## Renvoie le numéro de série d’une heure précise. +TIMEVALUE = TEMPSVAL ## Convertit une date représentée sous forme de texte en numéro de série. +TODAY = AUJOURDHUI ## Renvoie le numéro de série de la date du jour. +WEEKDAY = JOURSEM ## Convertit un numéro de série en jour de la semaine. +WEEKNUM = NO.SEMAINE ## Convertit un numéro de série en un numéro représentant l’ordre de la semaine dans l’année. +WORKDAY = SERIE.JOUR.OUVRE ## Renvoie le numéro de série de la date avant ou après le nombre de jours ouvrés spécifiés. +YEAR = ANNEE ## Convertit un numéro de série en année. +YEARFRAC = FRACTION.ANNEE ## Renvoie la fraction de l’année représentant le nombre de jours entre la date de début et la date de fin. + + +## +## Engineering functions Fonctions d’ingénierie +## +BESSELI = BESSELI ## Renvoie la fonction Bessel modifiée In(x). +BESSELJ = BESSELJ ## Renvoie la fonction Bessel Jn(x). +BESSELK = BESSELK ## Renvoie la fonction Bessel modifiée Kn(x). +BESSELY = BESSELY ## Renvoie la fonction Bessel Yn(x). +BIN2DEC = BINDEC ## Convertit un nombre binaire en nombre décimal. +BIN2HEX = BINHEX ## Convertit un nombre binaire en nombre hexadécimal. +BIN2OCT = BINOCT ## Convertit un nombre binaire en nombre octal. +COMPLEX = COMPLEXE ## Convertit des coefficients réel et imaginaire en un nombre complexe. +CONVERT = CONVERT ## Convertit un nombre d’une unité de mesure à une autre. +DEC2BIN = DECBIN ## Convertit un nombre décimal en nombre binaire. +DEC2HEX = DECHEX ## Convertit un nombre décimal en nombre hexadécimal. +DEC2OCT = DECOCT ## Convertit un nombre décimal en nombre octal. +DELTA = DELTA ## Teste l’égalité de deux nombres. +ERF = ERF ## Renvoie la valeur de la fonction d’erreur. +ERFC = ERFC ## Renvoie la valeur de la fonction d’erreur complémentaire. +GESTEP = SUP.SEUIL ## Teste si un nombre est supérieur à une valeur de seuil. +HEX2BIN = HEXBIN ## Convertit un nombre hexadécimal en nombre binaire. +HEX2DEC = HEXDEC ## Convertit un nombre hexadécimal en nombre décimal. +HEX2OCT = HEXOCT ## Convertit un nombre hexadécimal en nombre octal. +IMABS = COMPLEXE.MODULE ## Renvoie la valeur absolue (module) d’un nombre complexe. +IMAGINARY = COMPLEXE.IMAGINAIRE ## Renvoie le coefficient imaginaire d’un nombre complexe. +IMARGUMENT = COMPLEXE.ARGUMENT ## Renvoie l’argument thêta, un angle exprimé en radians. +IMCONJUGATE = COMPLEXE.CONJUGUE ## Renvoie le nombre complexe conjugué d’un nombre complexe. +IMCOS = IMCOS ## Renvoie le cosinus d’un nombre complexe. +IMDIV = COMPLEXE.DIV ## Renvoie le quotient de deux nombres complexes. +IMEXP = COMPLEXE.EXP ## Renvoie la fonction exponentielle d’un nombre complexe. +IMLN = COMPLEXE.LN ## Renvoie le logarithme népérien d’un nombre complexe. +IMLOG10 = COMPLEXE.LOG10 ## Calcule le logarithme en base 10 d’un nombre complexe. +IMLOG2 = COMPLEXE.LOG2 ## Calcule le logarithme en base 2 d’un nombre complexe. +IMPOWER = COMPLEXE.PUISSANCE ## Renvoie un nombre complexe élevé à une puissance entière. +IMPRODUCT = COMPLEXE.PRODUIT ## Renvoie le produit de plusieurs nombres complexes. +IMREAL = COMPLEXE.REEL ## Renvoie le coefficient réel d’un nombre complexe. +IMSIN = COMPLEXE.SIN ## Renvoie le sinus d’un nombre complexe. +IMSQRT = COMPLEXE.RACINE ## Renvoie la racine carrée d’un nombre complexe. +IMSUB = COMPLEXE.DIFFERENCE ## Renvoie la différence entre deux nombres complexes. +IMSUM = COMPLEXE.SOMME ## Renvoie la somme de plusieurs nombres complexes. +OCT2BIN = OCTBIN ## Convertit un nombre octal en nombre binaire. +OCT2DEC = OCTDEC ## Convertit un nombre octal en nombre décimal. +OCT2HEX = OCTHEX ## Convertit un nombre octal en nombre hexadécimal. + + +## +## Financial functions Fonctions financières +## +ACCRINT = INTERET.ACC ## Renvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu périodiquement. +ACCRINTM = INTERET.ACC.MAT ## Renvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu à l’échéance. +AMORDEGRC = AMORDEGRC ## Renvoie l’amortissement correspondant à chaque période comptable en utilisant un coefficient d’amortissement. +AMORLINC = AMORLINC ## Renvoie l’amortissement d’un bien à la fin d’une période fiscale donnée. +COUPDAYBS = NB.JOURS.COUPON.PREC ## Renvoie le nombre de jours entre le début de la période de coupon et la date de liquidation. +COUPDAYS = NB.JOURS.COUPONS ## Renvoie le nombre de jours pour la période du coupon contenant la date de liquidation. +COUPDAYSNC = NB.JOURS.COUPON.SUIV ## Renvoie le nombre de jours entre la date de liquidation et la date du coupon suivant la date de liquidation. +COUPNCD = DATE.COUPON.SUIV ## Renvoie la première date de coupon ultérieure à la date de règlement. +COUPNUM = NB.COUPONS ## Renvoie le nombre de coupons dus entre la date de règlement et la date d’échéance. +COUPPCD = DATE.COUPON.PREC ## Renvoie la date de coupon précédant la date de règlement. +CUMIPMT = CUMUL.INTER ## Renvoie l’intérêt cumulé payé sur un emprunt entre deux périodes. +CUMPRINC = CUMUL.PRINCPER ## Renvoie le montant cumulé des remboursements du capital d’un emprunt effectués entre deux périodes. +DB = DB ## Renvoie l’amortissement d’un bien pour une période spécifiée en utilisant la méthode de l’amortissement dégressif à taux fixe. +DDB = DDB ## Renvoie l’amortissement d’un bien pour toute période spécifiée, en utilisant la méthode de l’amortissement dégressif à taux double ou selon un coefficient à spécifier. +DISC = TAUX.ESCOMPTE ## Calcule le taux d’escompte d’une transaction. +DOLLARDE = PRIX.DEC ## Convertit un prix en euros, exprimé sous forme de fraction, en un prix en euros exprimé sous forme de nombre décimal. +DOLLARFR = PRIX.FRAC ## Convertit un prix en euros, exprimé sous forme de nombre décimal, en un prix en euros exprimé sous forme de fraction. +DURATION = DUREE ## Renvoie la durée, en années, d’un titre dont l’intérêt est perçu périodiquement. +EFFECT = TAUX.EFFECTIF ## Renvoie le taux d’intérêt annuel effectif. +FV = VC ## Renvoie la valeur future d’un investissement. +FVSCHEDULE = VC.PAIEMENTS ## Calcule la valeur future d’un investissement en appliquant une série de taux d’intérêt composites. +INTRATE = TAUX.INTERET ## Affiche le taux d’intérêt d’un titre totalement investi. +IPMT = INTPER ## Calcule le montant des intérêts d’un investissement pour une période donnée. +IRR = TRI ## Calcule le taux de rentabilité interne d’un investissement pour une succession de trésoreries. +ISPMT = ISPMT ## Calcule le montant des intérêts d’un investissement pour une période donnée. +MDURATION = DUREE.MODIFIEE ## Renvoie la durée de Macauley modifiée pour un titre ayant une valeur nominale hypothétique de 100_euros. +MIRR = TRIM ## Calcule le taux de rentabilité interne lorsque les paiements positifs et négatifs sont financés à des taux différents. +NOMINAL = TAUX.NOMINAL ## Calcule le taux d’intérêt nominal annuel. +NPER = NPM ## Renvoie le nombre de versements nécessaires pour rembourser un emprunt. +NPV = VAN ## Calcule la valeur actuelle nette d’un investissement basé sur une série de décaissements et un taux d’escompte. +ODDFPRICE = PRIX.PCOUPON.IRREG ## Renvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière. +ODDFYIELD = REND.PCOUPON.IRREG ## Renvoie le taux de rendement d’un titre dont la première période de coupon est irrégulière. +ODDLPRICE = PRIX.DCOUPON.IRREG ## Renvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière. +ODDLYIELD = REND.DCOUPON.IRREG ## Renvoie le taux de rendement d’un titre dont la dernière période de coupon est irrégulière. +PMT = VPM ## Calcule le paiement périodique d’un investissement donné. +PPMT = PRINCPER ## Calcule, pour une période donnée, la part de remboursement du principal d’un investissement. +PRICE = PRIX.TITRE ## Renvoie le prix d’un titre rapportant des intérêts périodiques, pour une valeur nominale de 100 euros. +PRICEDISC = VALEUR.ENCAISSEMENT ## Renvoie la valeur d’encaissement d’un escompte commercial, pour une valeur nominale de 100 euros. +PRICEMAT = PRIX.TITRE.ECHEANCE ## Renvoie le prix d’un titre dont la valeur nominale est 100 euros et qui rapporte des intérêts à l’échéance. +PV = PV ## Calcule la valeur actuelle d’un investissement. +RATE = TAUX ## Calcule le taux d’intérêt par période pour une annuité. +RECEIVED = VALEUR.NOMINALE ## Renvoie la valeur nominale à échéance d’un effet de commerce. +SLN = AMORLIN ## Calcule l’amortissement linéaire d’un bien pour une période donnée. +SYD = SYD ## Calcule l’amortissement d’un bien pour une période donnée sur la base de la méthode américaine Sum-of-Years Digits (amortissement dégressif à taux décroissant appliqué à une valeur constante). +TBILLEQ = TAUX.ESCOMPTE.R ## Renvoie le taux d’escompte rationnel d’un bon du Trésor. +TBILLPRICE = PRIX.BON.TRESOR ## Renvoie le prix d’un bon du Trésor d’une valeur nominale de 100 euros. +TBILLYIELD = RENDEMENT.BON.TRESOR ## Calcule le taux de rendement d’un bon du Trésor. +VDB = VDB ## Renvoie l’amortissement d’un bien pour une période spécifiée ou partielle en utilisant une méthode de l’amortissement dégressif à taux fixe. +XIRR = TRI.PAIEMENTS ## Calcule le taux de rentabilité interne d’un ensemble de paiements non périodiques. +XNPV = VAN.PAIEMENTS ## Renvoie la valeur actuelle nette d’un ensemble de paiements non périodiques. +YIELD = RENDEMENT.TITRE ## Calcule le rendement d’un titre rapportant des intérêts périodiquement. +YIELDDISC = RENDEMENT.SIMPLE ## Calcule le taux de rendement d’un emprunt à intérêt simple (par exemple, un bon du Trésor). +YIELDMAT = RENDEMENT.TITRE.ECHEANCE ## Renvoie le rendement annuel d’un titre qui rapporte des intérêts à l’échéance. + + +## +## Information functions Fonctions d’information +## +CELL = CELLULE ## Renvoie des informations sur la mise en forme, l’emplacement et le contenu d’une cellule. +ERROR.TYPE = TYPE.ERREUR ## Renvoie un nombre correspondant à un type d’erreur. +INFO = INFORMATIONS ## Renvoie des informations sur l’environnement d’exploitation actuel. +ISBLANK = ESTVIDE ## Renvoie VRAI si l’argument valeur est vide. +ISERR = ESTERR ## Renvoie VRAI si l’argument valeur fait référence à une valeur d’erreur, sauf #N/A. +ISERROR = ESTERREUR ## Renvoie VRAI si l’argument valeur fait référence à une valeur d’erreur. +ISEVEN = EST.PAIR ## Renvoie VRAI si le chiffre est pair. +ISLOGICAL = ESTLOGIQUE ## Renvoie VRAI si l’argument valeur fait référence à une valeur logique. +ISNA = ESTNA ## Renvoie VRAI si l’argument valeur fait référence à la valeur d’erreur #N/A. +ISNONTEXT = ESTNONTEXTE ## Renvoie VRAI si l’argument valeur ne se présente pas sous forme de texte. +ISNUMBER = ESTNUM ## Renvoie VRAI si l’argument valeur représente un nombre. +ISODD = EST.IMPAIR ## Renvoie VRAI si le chiffre est impair. +ISREF = ESTREF ## Renvoie VRAI si l’argument valeur est une référence. +ISTEXT = ESTTEXTE ## Renvoie VRAI si l’argument valeur se présente sous forme de texte. +N = N ## Renvoie une valeur convertie en nombre. +NA = NA ## Renvoie la valeur d’erreur #N/A. +TYPE = TYPE ## Renvoie un nombre indiquant le type de données d’une valeur. + + +## +## Logical functions Fonctions logiques +## +AND = ET ## Renvoie VRAI si tous ses arguments sont VRAI. +FALSE = FAUX ## Renvoie la valeur logique FAUX. +IF = SI ## Spécifie un test logique à effectuer. +IFERROR = SIERREUR ## Renvoie une valeur que vous spécifiez si une formule génère une erreur ; sinon, elle renvoie le résultat de la formule. +NOT = NON ## Inverse la logique de cet argument. +OR = OU ## Renvoie VRAI si un des arguments est VRAI. +TRUE = VRAI ## Renvoie la valeur logique VRAI. + + +## +## Lookup and reference functions Fonctions de recherche et de référence +## +ADDRESS = ADRESSE ## Renvoie une référence sous forme de texte à une seule cellule d’une feuille de calcul. +AREAS = ZONES ## Renvoie le nombre de zones dans une référence. +CHOOSE = CHOISIR ## Choisit une valeur dans une liste. +COLUMN = COLONNE ## Renvoie le numéro de colonne d’une référence. +COLUMNS = COLONNES ## Renvoie le nombre de colonnes dans une référence. +HLOOKUP = RECHERCHEH ## Effectue une recherche dans la première ligne d’une matrice et renvoie la valeur de la cellule indiquée. +HYPERLINK = LIEN_HYPERTEXTE ## Crée un raccourci ou un renvoi qui ouvre un document stocké sur un serveur réseau, sur un réseau Intranet ou sur Internet. +INDEX = INDEX ## Utilise un index pour choisir une valeur provenant d’une référence ou d’une matrice. +INDIRECT = INDIRECT ## Renvoie une référence indiquée par une valeur de texte. +LOOKUP = RECHERCHE ## Recherche des valeurs dans un vecteur ou une matrice. +MATCH = EQUIV ## Recherche des valeurs dans une référence ou une matrice. +OFFSET = DECALER ## Renvoie une référence décalée par rapport à une référence donnée. +ROW = LIGNE ## Renvoie le numéro de ligne d’une référence. +ROWS = LIGNES ## Renvoie le nombre de lignes dans une référence. +RTD = RTD ## Extrait les données en temps réel à partir d’un programme prenant en charge l’automation COM (Automation : utilisation des objets d'une application à partir d'une autre application ou d'un autre outil de développement. Autrefois appelée OLE Automation, Automation est une norme industrielle et une fonctionnalité du modèle d'objet COM (Component Object Model).). +TRANSPOSE = TRANSPOSE ## Renvoie la transposition d’une matrice. +VLOOKUP = RECHERCHEV ## Effectue une recherche dans la première colonne d’une matrice et se déplace sur la ligne pour renvoyer la valeur d’une cellule. + + +## +## Math and trigonometry functions Fonctions mathématiques et trigonométriques +## +ABS = ABS ## Renvoie la valeur absolue d’un nombre. +ACOS = ACOS ## Renvoie l’arccosinus d’un nombre. +ACOSH = ACOSH ## Renvoie le cosinus hyperbolique inverse d’un nombre. +ASIN = ASIN ## Renvoie l’arcsinus d’un nombre. +ASINH = ASINH ## Renvoie le sinus hyperbolique inverse d’un nombre. +ATAN = ATAN ## Renvoie l’arctangente d’un nombre. +ATAN2 = ATAN2 ## Renvoie l’arctangente des coordonnées x et y. +ATANH = ATANH ## Renvoie la tangente hyperbolique inverse d’un nombre. +CEILING = PLAFOND ## Arrondit un nombre au nombre entier le plus proche ou au multiple le plus proche de l’argument précision en s’éloignant de zéro. +COMBIN = COMBIN ## Renvoie le nombre de combinaisons que l’on peut former avec un nombre donné d’objets. +COS = COS ## Renvoie le cosinus d’un nombre. +COSH = COSH ## Renvoie le cosinus hyperbolique d’un nombre. +DEGREES = DEGRES ## Convertit des radians en degrés. +EVEN = PAIR ## Arrondit un nombre au nombre entier pair le plus proche en s’éloignant de zéro. +EXP = EXP ## Renvoie e élevé à la puissance d’un nombre donné. +FACT = FACT ## Renvoie la factorielle d’un nombre. +FACTDOUBLE = FACTDOUBLE ## Renvoie la factorielle double d’un nombre. +FLOOR = PLANCHER ## Arrondit un nombre en tendant vers 0 (zéro). +GCD = PGCD ## Renvoie le plus grand commun diviseur. +INT = ENT ## Arrondit un nombre à l’entier immédiatement inférieur. +LCM = PPCM ## Renvoie le plus petit commun multiple. +LN = LN ## Renvoie le logarithme népérien d’un nombre. +LOG = LOG ## Renvoie le logarithme d’un nombre dans la base spécifiée. +LOG10 = LOG10 ## Calcule le logarithme en base 10 d’un nombre. +MDETERM = DETERMAT ## Renvoie le déterminant d’une matrice. +MINVERSE = INVERSEMAT ## Renvoie la matrice inverse d’une matrice. +MMULT = PRODUITMAT ## Renvoie le produit de deux matrices. +MOD = MOD ## Renvoie le reste d’une division. +MROUND = ARRONDI.AU.MULTIPLE ## Donne l’arrondi d’un nombre au multiple spécifié. +MULTINOMIAL = MULTINOMIALE ## Calcule la multinomiale d’un ensemble de nombres. +ODD = IMPAIR ## Renvoie le nombre, arrondi à la valeur du nombre entier impair le plus proche en s’éloignant de zéro. +PI = PI ## Renvoie la valeur de pi. +POWER = PUISSANCE ## Renvoie la valeur du nombre élevé à une puissance. +PRODUCT = PRODUIT ## Multiplie ses arguments. +QUOTIENT = QUOTIENT ## Renvoie la partie entière du résultat d’une division. +RADIANS = RADIANS ## Convertit des degrés en radians. +RAND = ALEA ## Renvoie un nombre aléatoire compris entre 0 et 1. +RANDBETWEEN = ALEA.ENTRE.BORNES ## Renvoie un nombre aléatoire entre les nombres que vous spécifiez. +ROMAN = ROMAIN ## Convertit des chiffres arabes en chiffres romains, sous forme de texte. +ROUND = ARRONDI ## Arrondit un nombre au nombre de chiffres indiqué. +ROUNDDOWN = ARRONDI.INF ## Arrondit un nombre en tendant vers 0 (zéro). +ROUNDUP = ARRONDI.SUP ## Arrondit un nombre à l’entier supérieur, en s’éloignant de zéro. +SERIESSUM = SOMME.SERIES ## Renvoie la somme d’une série géométrique en s’appuyant sur la formule suivante : +SIGN = SIGNE ## Renvoie le signe d’un nombre. +SIN = SIN ## Renvoie le sinus d’un angle donné. +SINH = SINH ## Renvoie le sinus hyperbolique d’un nombre. +SQRT = RACINE ## Renvoie la racine carrée d’un nombre. +SQRTPI = RACINE.PI ## Renvoie la racine carrée de (nombre * pi). +SUBTOTAL = SOUS.TOTAL ## Renvoie un sous-total dans une liste ou une base de données. +SUM = SOMME ## Calcule la somme de ses arguments. +SUMIF = SOMME.SI ## Additionne les cellules spécifiées si elles répondent à un critère donné. +SUMIFS = SOMME.SI.ENS ## Ajoute les cellules d’une plage qui répondent à plusieurs critères. +SUMPRODUCT = SOMMEPROD ## Multiplie les valeurs correspondantes des matrices spécifiées et calcule la somme de ces produits. +SUMSQ = SOMME.CARRES ## Renvoie la somme des carrés des arguments. +SUMX2MY2 = SOMME.X2MY2 ## Renvoie la somme de la différence des carrés des valeurs correspondantes de deux matrices. +SUMX2PY2 = SOMME.X2PY2 ## Renvoie la somme de la somme des carrés des valeurs correspondantes de deux matrices. +SUMXMY2 = SOMME.XMY2 ## Renvoie la somme des carrés des différences entre les valeurs correspondantes de deux matrices. +TAN = TAN ## Renvoie la tangente d’un nombre. +TANH = TANH ## Renvoie la tangente hyperbolique d’un nombre. +TRUNC = TRONQUE ## Renvoie la partie entière d’un nombre. + + +## +## Statistical functions Fonctions statistiques +## +AVEDEV = ECART.MOYEN ## Renvoie la moyenne des écarts absolus observés dans la moyenne des points de données. +AVERAGE = MOYENNE ## Renvoie la moyenne de ses arguments. +AVERAGEA = AVERAGEA ## Renvoie la moyenne de ses arguments, nombres, texte et valeurs logiques inclus. +AVERAGEIF = MOYENNE.SI ## Renvoie la moyenne (arithmétique) de toutes les cellules d’une plage qui répondent à des critères donnés. +AVERAGEIFS = MOYENNE.SI.ENS ## Renvoie la moyenne (arithmétique) de toutes les cellules qui répondent à plusieurs critères. +BETADIST = LOI.BETA ## Renvoie la fonction de distribution cumulée. +BETAINV = BETA.INVERSE ## Renvoie l’inverse de la fonction de distribution cumulée pour une distribution bêta spécifiée. +BINOMDIST = LOI.BINOMIALE ## Renvoie la probabilité d’une variable aléatoire discrète suivant la loi binomiale. +CHIDIST = LOI.KHIDEUX ## Renvoie la probabilité unilatérale de la distribution khi-deux. +CHIINV = KHIDEUX.INVERSE ## Renvoie l’inverse de la probabilité unilatérale de la distribution khi-deux. +CHITEST = TEST.KHIDEUX ## Renvoie le test d’indépendance. +CONFIDENCE = INTERVALLE.CONFIANCE ## Renvoie l’intervalle de confiance pour une moyenne de population. +CORREL = COEFFICIENT.CORRELATION ## Renvoie le coefficient de corrélation entre deux séries de données. +COUNT = NB ## Détermine les nombres compris dans la liste des arguments. +COUNTA = NBVAL ## Détermine le nombre de valeurs comprises dans la liste des arguments. +COUNTBLANK = NB.VIDE ## Compte le nombre de cellules vides dans une plage. +COUNTIF = NB.SI ## Compte le nombre de cellules qui répondent à un critère donné dans une plage. +COUNTIFS = NB.SI.ENS ## Compte le nombre de cellules à l’intérieur d’une plage qui répondent à plusieurs critères. +COVAR = COVARIANCE ## Renvoie la covariance, moyenne des produits des écarts pour chaque série d’observations. +CRITBINOM = CRITERE.LOI.BINOMIALE ## Renvoie la plus petite valeur pour laquelle la distribution binomiale cumulée est inférieure ou égale à une valeur de critère. +DEVSQ = SOMME.CARRES.ECARTS ## Renvoie la somme des carrés des écarts. +EXPONDIST = LOI.EXPONENTIELLE ## Renvoie la distribution exponentielle. +FDIST = LOI.F ## Renvoie la distribution de probabilité F. +FINV = INVERSE.LOI.F ## Renvoie l’inverse de la distribution de probabilité F. +FISHER = FISHER ## Renvoie la transformation de Fisher. +FISHERINV = FISHER.INVERSE ## Renvoie l’inverse de la transformation de Fisher. +FORECAST = PREVISION ## Calcule une valeur par rapport à une tendance linéaire. +FREQUENCY = FREQUENCE ## Calcule la fréquence d’apparition des valeurs dans une plage de valeurs, puis renvoie des nombres sous forme de matrice verticale. +FTEST = TEST.F ## Renvoie le résultat d’un test F. +GAMMADIST = LOI.GAMMA ## Renvoie la probabilité d’une variable aléatoire suivant une loi Gamma. +GAMMAINV = LOI.GAMMA.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi Gamma. +GAMMALN = LNGAMMA ## Renvoie le logarithme népérien de la fonction Gamma, G(x) +GEOMEAN = MOYENNE.GEOMETRIQUE ## Renvoie la moyenne géométrique. +GROWTH = CROISSANCE ## Calcule des valeurs par rapport à une tendance exponentielle. +HARMEAN = MOYENNE.HARMONIQUE ## Renvoie la moyenne harmonique. +HYPGEOMDIST = LOI.HYPERGEOMETRIQUE ## Renvoie la probabilité d’une variable aléatoire discrète suivant une loi hypergéométrique. +INTERCEPT = ORDONNEE.ORIGINE ## Renvoie l’ordonnée à l’origine d’une droite de régression linéaire. +KURT = KURTOSIS ## Renvoie le kurtosis d’une série de données. +LARGE = GRANDE.VALEUR ## Renvoie la k-ième plus grande valeur d’une série de données. +LINEST = DROITEREG ## Renvoie les paramètres d’une tendance linéaire. +LOGEST = LOGREG ## Renvoie les paramètres d’une tendance exponentielle. +LOGINV = LOI.LOGNORMALE.INVERSE ## Renvoie l’inverse de la probabilité pour une variable aléatoire suivant la loi lognormale. +LOGNORMDIST = LOI.LOGNORMALE ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi lognormale. +MAX = MAX ## Renvoie la valeur maximale contenue dans une liste d’arguments. +MAXA = MAXA ## Renvoie la valeur maximale d’une liste d’arguments, nombres, texte et valeurs logiques inclus. +MEDIAN = MEDIANE ## Renvoie la valeur médiane des nombres donnés. +MIN = MIN ## Renvoie la valeur minimale contenue dans une liste d’arguments. +MINA = MINA ## Renvoie la plus petite valeur d’une liste d’arguments, nombres, texte et valeurs logiques inclus. +MODE = MODE ## Renvoie la valeur la plus courante d’une série de données. +NEGBINOMDIST = LOI.BINOMIALE.NEG ## Renvoie la probabilité d’une variable aléatoire discrète suivant une loi binomiale négative. +NORMDIST = LOI.NORMALE ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi normale. +NORMINV = LOI.NORMALE.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi normale standard. +NORMSDIST = LOI.NORMALE.STANDARD ## Renvoie la probabilité d’une variable aléatoire continue suivant une loi normale standard. +NORMSINV = LOI.NORMALE.STANDARD.INVERSE ## Renvoie l’inverse de la distribution cumulée normale standard. +PEARSON = PEARSON ## Renvoie le coefficient de corrélation d’échantillonnage de Pearson. +PERCENTILE = CENTILE ## Renvoie le k-ième centile des valeurs d’une plage. +PERCENTRANK = RANG.POURCENTAGE ## Renvoie le rang en pourcentage d’une valeur d’une série de données. +PERMUT = PERMUTATION ## Renvoie le nombre de permutations pour un nombre donné d’objets. +POISSON = LOI.POISSON ## Renvoie la probabilité d’une variable aléatoire suivant une loi de Poisson. +PROB = PROBABILITE ## Renvoie la probabilité que des valeurs d’une plage soient comprises entre deux limites. +QUARTILE = QUARTILE ## Renvoie le quartile d’une série de données. +RANK = RANG ## Renvoie le rang d’un nombre contenu dans une liste. +RSQ = COEFFICIENT.DETERMINATION ## Renvoie la valeur du coefficient de détermination R^2 d’une régression linéaire. +SKEW = COEFFICIENT.ASYMETRIE ## Renvoie l’asymétrie d’une distribution. +SLOPE = PENTE ## Renvoie la pente d’une droite de régression linéaire. +SMALL = PETITE.VALEUR ## Renvoie la k-ième plus petite valeur d’une série de données. +STANDARDIZE = CENTREE.REDUITE ## Renvoie une valeur centrée réduite. +STDEV = ECARTYPE ## Évalue l’écart type d’une population en se basant sur un échantillon de cette population. +STDEVA = STDEVA ## Évalue l’écart type d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques inclus. +STDEVP = ECARTYPEP ## Calcule l’écart type d’une population à partir de la population entière. +STDEVPA = STDEVPA ## Calcule l’écart type d’une population à partir de l’ensemble de la population, nombres, texte et valeurs logiques inclus. +STEYX = ERREUR.TYPE.XY ## Renvoie l’erreur type de la valeur y prévue pour chaque x de la régression. +TDIST = LOI.STUDENT ## Renvoie la probabilité d’une variable aléatoire suivant une loi T de Student. +TINV = LOI.STUDENT.INVERSE ## Renvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi T de Student. +TREND = TENDANCE ## Renvoie des valeurs par rapport à une tendance linéaire. +TRIMMEAN = MOYENNE.REDUITE ## Renvoie la moyenne de l’intérieur d’une série de données. +TTEST = TEST.STUDENT ## Renvoie la probabilité associée à un test T de Student. +VAR = VAR ## Calcule la variance sur la base d’un échantillon. +VARA = VARA ## Estime la variance d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques incluses. +VARP = VAR.P ## Calcule la variance sur la base de l’ensemble de la population. +VARPA = VARPA ## Calcule la variance d’une population en se basant sur la population entière, nombres, texte et valeurs logiques inclus. +WEIBULL = LOI.WEIBULL ## Renvoie la probabilité d’une variable aléatoire suivant une loi de Weibull. +ZTEST = TEST.Z ## Renvoie la valeur de probabilité unilatérale d’un test z. + + +## +## Text functions Fonctions de texte +## +ASC = ASC ## Change les caractères anglais ou katakana à pleine chasse (codés sur deux octets) à l’intérieur d’une chaîne de caractères en caractères à demi-chasse (codés sur un octet). +BAHTTEXT = BAHTTEXT ## Convertit un nombre en texte en utilisant le format monétaire ß (baht). +CHAR = CAR ## Renvoie le caractère spécifié par le code numérique. +CLEAN = EPURAGE ## Supprime tous les caractères de contrôle du texte. +CODE = CODE ## Renvoie le numéro de code du premier caractère du texte. +CONCATENATE = CONCATENER ## Assemble plusieurs éléments textuels de façon à n’en former qu’un seul. +DOLLAR = EURO ## Convertit un nombre en texte en utilisant le format monétaire € (euro). +EXACT = EXACT ## Vérifie si deux valeurs de texte sont identiques. +FIND = TROUVE ## Trouve un valeur textuelle dans une autre, en respectant la casse. +FINDB = TROUVERB ## Trouve un valeur textuelle dans une autre, en respectant la casse. +FIXED = CTXT ## Convertit un nombre au format texte avec un nombre de décimales spécifié. +JIS = JIS ## Change les caractères anglais ou katakana à demi-chasse (codés sur un octet) à l’intérieur d’une chaîne de caractères en caractères à à pleine chasse (codés sur deux octets). +LEFT = GAUCHE ## Renvoie des caractères situés à l’extrême gauche d’une chaîne de caractères. +LEFTB = GAUCHEB ## Renvoie des caractères situés à l’extrême gauche d’une chaîne de caractères. +LEN = NBCAR ## Renvoie le nombre de caractères contenus dans une chaîne de texte. +LENB = LENB ## Renvoie le nombre de caractères contenus dans une chaîne de texte. +LOWER = MINUSCULE ## Convertit le texte en minuscules. +MID = STXT ## Renvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez. +MIDB = STXTB ## Renvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez. +PHONETIC = PHONETIQUE ## Extrait les caractères phonétiques (furigana) d’une chaîne de texte. +PROPER = NOMPROPRE ## Met en majuscules la première lettre de chaque mot dans une chaîne textuelle. +REPLACE = REMPLACER ## Remplace des caractères dans un texte. +REPLACEB = REMPLACERB ## Remplace des caractères dans un texte. +REPT = REPT ## Répète un texte un certain nombre de fois. +RIGHT = DROITE ## Renvoie des caractères situés à l’extrême droite d’une chaîne de caractères. +RIGHTB = DROITEB ## Renvoie des caractères situés à l’extrême droite d’une chaîne de caractères. +SEARCH = CHERCHE ## Trouve un texte dans un autre texte (sans respecter la casse). +SEARCHB = CHERCHERB ## Trouve un texte dans un autre texte (sans respecter la casse). +SUBSTITUTE = SUBSTITUE ## Remplace l’ancien texte d’une chaîne de caractères par un nouveau. +T = T ## Convertit ses arguments en texte. +TEXT = TEXTE ## Convertit un nombre au format texte. +TRIM = SUPPRESPACE ## Supprime les espaces du texte. +UPPER = MAJUSCULE ## Convertit le texte en majuscules. +VALUE = CNUM ## Convertit un argument textuel en nombre diff --git a/extend/phpexcel/PHPExcel/locale/hu/config b/extend/phpexcel/PHPExcel/locale/hu/config new file mode 100755 index 0000000..e04151c --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/hu/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = Ft + + +## +## Excel Error Codes (For future use) +## +NULL = #NULLA! +DIV0 = #ZÉRÓOSZTÓ! +VALUE = #ÉRTÉK! +REF = #HIV! +NAME = #NÉV? +NUM = #SZÁM! +NA = #HIÁNYZIK diff --git a/extend/phpexcel/PHPExcel/locale/hu/functions b/extend/phpexcel/PHPExcel/locale/hu/functions new file mode 100755 index 0000000..77cae92 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/hu/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Bővítmények és automatizálási függvények +## +GETPIVOTDATA = KIMUTATÁSADATOT.VESZ ## A kimutatásokban tárolt adatok visszaadására használható. + + +## +## Cube functions Kockafüggvények +## +CUBEKPIMEMBER = KOCKA.FŐTELJMUT ## Egy fő teljesítménymutató (KPI) nevét, tulajdonságát és mértékegységét adja eredményül, a nevet és a tulajdonságot megjeleníti a cellában. A KPI-k számszerűsíthető mérési lehetőséget jelentenek – ilyen mutató például a havi bruttó nyereség vagy az egy alkalmazottra jutó negyedéves forgalom –, egy szervezet teljesítményének nyomonkövetésére használhatók. +CUBEMEMBER = KOCKA.TAG ## Kockahierachia tagját vagy rekordját adja eredményül. Ellenőrizhető vele, hogy szerepel-e a kockában az adott tag vagy rekord. +CUBEMEMBERPROPERTY = KOCKA.TAG.TUL ## A kocka egyik tagtulajdonságának értékét adja eredményül. Használatával ellenőrizhető, hogy szerepel-e egy tagnév a kockában, eredménye pedig az erre a tagra vonatkozó, megadott tulajdonság. +CUBERANKEDMEMBER = KOCKA.HALM.ELEM ## Egy halmaz rangsor szerinti n-edik tagját adja eredményül. Használatával egy halmaz egy vagy több elemét kaphatja meg, például a legnagyobb teljesítményű üzletkötőt vagy a 10 legjobb tanulót. +CUBESET = KOCKA.HALM ## Számított tagok vagy rekordok halmazát adja eredményül, ehhez egy beállított kifejezést elküld a kiszolgálón található kockának, majd ezt a halmazt adja vissza a Microsoft Office Excel alkalmazásnak. +CUBESETCOUNT = KOCKA.HALM.DB ## Egy halmaz elemszámát adja eredményül. +CUBEVALUE = KOCKA.ÉRTÉK ## Kockából összesített értéket ad eredményül. + + +## +## Database functions Adatbázis-kezelő függvények +## +DAVERAGE = AB.ÁTLAG ## A kijelölt adatbáziselemek átlagát számítja ki. +DCOUNT = AB.DARAB ## Megszámolja, hogy az adatbázisban hány cella tartalmaz számokat. +DCOUNTA = AB.DARAB2 ## Megszámolja az adatbázisban lévő nem üres cellákat. +DGET = AB.MEZŐ ## Egy adatbázisból egyetlen olyan rekordot ad vissza, amely megfelel a megadott feltételeknek. +DMAX = AB.MAX ## A kiválasztott adatbáziselemek közül a legnagyobb értéket adja eredményül. +DMIN = AB.MIN ## A kijelölt adatbáziselemek közül a legkisebb értéket adja eredményül. +DPRODUCT = AB.SZORZAT ## Az adatbázis megadott feltételeknek eleget tevő rekordjaira összeszorozza a megadott mezőben található számértékeket, és eredményül ezt a szorzatot adja. +DSTDEV = AB.SZÓRÁS ## A kijelölt adatbáziselemek egy mintája alapján megbecsüli a szórást. +DSTDEVP = AB.SZÓRÁS2 ## A kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórást. +DSUM = AB.SZUM ## Összeadja a feltételnek megfelelő adatbázisrekordok mezőoszlopában a számokat. +DVAR = AB.VAR ## A kijelölt adatbáziselemek mintája alapján becslést ad a szórásnégyzetre. +DVARP = AB.VAR2 ## A kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórásnégyzetet. + + +## +## Date and time functions Dátumfüggvények +## +DATE = DÁTUM ## Adott dátum dátumértékét adja eredményül. +DATEVALUE = DÁTUMÉRTÉK ## Szövegként megadott dátumot dátumértékké alakít át. +DAY = NAP ## Dátumértéket a hónap egy napjává (0-31) alakít. +DAYS360 = NAP360 ## Két dátum közé eső napok számát számítja ki a 360 napos év alapján. +EDATE = EDATE ## Adott dátumnál adott számú hónappal korábbi vagy későbbi dátum dátumértékét adja eredményül. +EOMONTH = EOMONTH ## Adott dátumnál adott számú hónappal korábbi vagy későbbi hónap utolsó napjának dátumértékét adja eredményül. +HOUR = ÓRA ## Időértéket órákká alakít. +MINUTE = PERC ## Időértéket percekké alakít. +MONTH = HÓNAP ## Időértéket hónapokká alakít. +NETWORKDAYS = NETWORKDAYS ## Két dátum között a teljes munkanapok számát adja meg. +NOW = MOST ## A napi dátum dátumértékét és a pontos idő időértékét adja eredményül. +SECOND = MPERC ## Időértéket másodpercekké alakít át. +TIME = IDŐ ## Adott időpont időértékét adja meg. +TIMEVALUE = IDŐÉRTÉK ## Szövegként megadott időpontot időértékké alakít át. +TODAY = MA ## A napi dátum dátumértékét adja eredményül. +WEEKDAY = HÉT.NAPJA ## Dátumértéket a hét napjává alakítja át. +WEEKNUM = WEEKNUM ## Visszatérési értéke egy szám, amely azt mutatja meg, hogy a megadott dátum az év hányadik hetére esik. +WORKDAY = WORKDAY ## Adott dátumnál adott munkanappal korábbi vagy későbbi dátum dátumértékét adja eredményül. +YEAR = ÉV ## Sorszámot évvé alakít át. +YEARFRAC = YEARFRAC ## Az adott dátumok közötti teljes napok számát törtévként adja meg. + + +## +## Engineering functions Mérnöki függvények +## +BESSELI = BESSELI ## Az In(x) módosított Bessel-függvény értékét adja eredményül. +BESSELJ = BESSELJ ## A Jn(x) Bessel-függvény értékét adja eredményül. +BESSELK = BESSELK ## A Kn(x) módosított Bessel-függvény értékét adja eredményül. +BESSELY = BESSELY ## Az Yn(x) módosított Bessel-függvény értékét adja eredményül. +BIN2DEC = BIN2DEC ## Bináris számot decimálissá alakít át. +BIN2HEX = BIN2HEX ## Bináris számot hexadecimálissá alakít át. +BIN2OCT = BIN2OCT ## Bináris számot oktálissá alakít át. +COMPLEX = COMPLEX ## Valós és képzetes részből komplex számot képez. +CONVERT = CONVERT ## Mértékegységeket vált át. +DEC2BIN = DEC2BIN ## Decimális számot binárissá alakít át. +DEC2HEX = DEC2HEX ## Decimális számot hexadecimálissá alakít át. +DEC2OCT = DEC2OCT ## Decimális számot oktálissá alakít át. +DELTA = DELTA ## Azt vizsgálja, hogy két érték egyenlő-e. +ERF = ERF ## A hibafüggvény értékét adja eredményül. +ERFC = ERFC ## A kiegészített hibafüggvény értékét adja eredményül. +GESTEP = GESTEP ## Azt vizsgálja, hogy egy szám nagyobb-e adott küszöbértéknél. +HEX2BIN = HEX2BIN ## Hexadecimális számot binárissá alakít át. +HEX2DEC = HEX2DEC ## Hexadecimális számot decimálissá alakít át. +HEX2OCT = HEX2OCT ## Hexadecimális számot oktálissá alakít át. +IMABS = IMABS ## Komplex szám abszolút értékét (modulusát) adja eredményül. +IMAGINARY = IMAGINARY ## Komplex szám képzetes részét adja eredményül. +IMARGUMENT = IMARGUMENT ## A komplex szám radiánban kifejezett théta argumentumát adja eredményül. +IMCONJUGATE = IMCONJUGATE ## Komplex szám komplex konjugáltját adja eredményül. +IMCOS = IMCOS ## Komplex szám koszinuszát adja eredményül. +IMDIV = IMDIV ## Két komplex szám hányadosát adja eredményül. +IMEXP = IMEXP ## Az e szám komplex kitevőjű hatványát adja eredményül. +IMLN = IMLN ## Komplex szám természetes logaritmusát adja eredményül. +IMLOG10 = IMLOG10 ## Komplex szám tízes alapú logaritmusát adja eredményül. +IMLOG2 = IMLOG2 ## Komplex szám kettes alapú logaritmusát adja eredményül. +IMPOWER = IMPOWER ## Komplex szám hatványát adja eredményül. +IMPRODUCT = IMPRODUCT ## Komplex számok szorzatát adja eredményül. +IMREAL = IMREAL ## Komplex szám valós részét adja eredményül. +IMSIN = IMSIN ## Komplex szám szinuszát adja eredményül. +IMSQRT = IMSQRT ## Komplex szám négyzetgyökét adja eredményül. +IMSUB = IMSUB ## Két komplex szám különbségét adja eredményül. +IMSUM = IMSUM ## Komplex számok összegét adja eredményül. +OCT2BIN = OCT2BIN ## Oktális számot binárissá alakít át. +OCT2DEC = OCT2DEC ## Oktális számot decimálissá alakít át. +OCT2HEX = OCT2HEX ## Oktális számot hexadecimálissá alakít át. + + +## +## Financial functions Pénzügyi függvények +## +ACCRINT = ACCRINT ## Periodikusan kamatozó értékpapír felszaporodott kamatát adja eredményül. +ACCRINTM = ACCRINTM ## Lejáratkor kamatozó értékpapír felszaporodott kamatát adja eredményül. +AMORDEGRC = AMORDEGRC ## Állóeszköz lineáris értékcsökkenését adja meg az egyes könyvelési időszakokra vonatkozóan. +AMORLINC = AMORLINC ## Az egyes könyvelési időszakokban az értékcsökkenést adja meg. +COUPDAYBS = COUPDAYBS ## A szelvényidőszak kezdetétől a kifizetés időpontjáig eltelt napokat adja vissza. +COUPDAYS = COUPDAYS ## A kifizetés időpontját magában foglaló szelvényperiódus hosszát adja meg napokban. +COUPDAYSNC = COUPDAYSNC ## A kifizetés időpontja és a legközelebbi szelvénydátum közötti napok számát adja meg. +COUPNCD = COUPNCD ## A kifizetést követő legelső szelvénydátumot adja eredményül. +COUPNUM = COUPNUM ## A kifizetés és a lejárat időpontja között kifizetendő szelvények számát adja eredményül. +COUPPCD = COUPPCD ## A kifizetés előtti utolsó szelvénydátumot adja eredményül. +CUMIPMT = CUMIPMT ## Két fizetési időszak között kifizetett kamat halmozott értékét adja eredményül. +CUMPRINC = CUMPRINC ## Két fizetési időszak között kifizetett részletek halmozott (kamatot nem tartalmazó) értékét adja eredményül. +DB = KCS2 ## Eszköz adott időszak alatti értékcsökkenését számítja ki a lineáris leírási modell alkalmazásával. +DDB = KCSA ## Eszköz értékcsökkenését számítja ki adott időszakra vonatkozóan a progresszív vagy egyéb megadott leírási modell alkalmazásával. +DISC = DISC ## Értékpapír leszámítolási kamatlábát adja eredményül. +DOLLARDE = DOLLARDE ## Egy közönséges törtként megadott számot tizedes törtté alakít át. +DOLLARFR = DOLLARFR ## Tizedes törtként megadott számot közönséges törtté alakít át. +DURATION = DURATION ## Periodikus kamatfizetésű értékpapír éves kamatérzékenységét adja eredményül. +EFFECT = EFFECT ## Az éves tényleges kamatláb értékét adja eredményül. +FV = JBÉ ## Befektetés jövőbeli értékét számítja ki. +FVSCHEDULE = FVSCHEDULE ## A kezdőtőke adott kamatlábak szerint megnövelt jövőbeli értékét adja eredményül. +INTRATE = INTRATE ## A lejáratig teljesen lekötött értékpapír kamatrátáját adja eredményül. +IPMT = RRÉSZLET ## Hiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra. +IRR = BMR ## A befektetés belső megtérülési rátáját számítja ki pénzáramláshoz. +ISPMT = LRÉSZLETKAMAT ## A befektetés adott időszakára fizetett kamatot számítja ki. +MDURATION = MDURATION ## Egy 100 Ft névértékű értékpapír Macauley-féle módosított kamatérzékenységét adja eredményül. +MIRR = MEGTÉRÜLÉS ## A befektetés belső megtérülési rátáját számítja ki a költségek és a bevételek különböző kamatlába mellett. +NOMINAL = NOMINAL ## Az éves névleges kamatláb értékét adja eredményül. +NPER = PER.SZÁM ## A törlesztési időszakok számát adja meg. +NPV = NMÉ ## Befektetéshez kapcsolódó pénzáramlás nettó jelenértékét számítja ki ismert pénzáramlás és kamatláb mellett. +ODDFPRICE = ODDFPRICE ## Egy 100 Ft névértékű, a futamidő elején töredék-időszakos értékpapír árát adja eredményül. +ODDFYIELD = ODDFYIELD ## A futamidő elején töredék-időszakos értékpapír hozamát adja eredményül. +ODDLPRICE = ODDLPRICE ## Egy 100 Ft névértékű, a futamidő végén töredék-időszakos értékpapír árát adja eredményül. +ODDLYIELD = ODDLYIELD ## A futamidő végén töredék-időszakos értékpapír hozamát adja eredményül. +PMT = RÉSZLET ## A törlesztési időszakra vonatkozó törlesztési összeget számítja ki. +PPMT = PRÉSZLET ## Hiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra. +PRICE = PRICE ## Egy 100 Ft névértékű, periodikusan kamatozó értékpapír árát adja eredményül. +PRICEDISC = PRICEDISC ## Egy 100 Ft névértékű leszámítolt értékpapír árát adja eredményül. +PRICEMAT = PRICEMAT ## Egy 100 Ft névértékű, a lejáratkor kamatozó értékpapír árát adja eredményül. +PV = MÉ ## Befektetés jelenlegi értékét számítja ki. +RATE = RÁTA ## Egy törlesztési időszakban az egy időszakra eső kamatláb nagyságát számítja ki. +RECEIVED = RECEIVED ## A lejáratig teljesen lekötött értékpapír lejáratakor kapott összegét adja eredményül. +SLN = LCSA ## Tárgyi eszköz egy időszakra eső amortizációját adja meg bruttó érték szerinti lineáris leírási kulcsot alkalmazva. +SYD = SYD ## Tárgyi eszköz értékcsökkenését számítja ki adott időszakra az évek számjegyösszegével dolgozó módszer alapján. +TBILLEQ = TBILLEQ ## Kincstárjegy kötvény-egyenértékű hozamát adja eredményül. +TBILLPRICE = TBILLPRICE ## Egy 100 Ft névértékű kincstárjegy árát adja eredményül. +TBILLYIELD = TBILLYIELD ## Kincstárjegy hozamát adja eredményül. +VDB = ÉCSRI ## Tárgyi eszköz amortizációját számítja ki megadott vagy részidőszakra a csökkenő egyenleg módszerének alkalmazásával. +XIRR = XIRR ## Ütemezett készpénzforgalom (cash flow) belső megtérülési kamatrátáját adja eredményül. +XNPV = XNPV ## Ütemezett készpénzforgalom (cash flow) nettó jelenlegi értékét adja eredményül. +YIELD = YIELD ## Periodikusan kamatozó értékpapír hozamát adja eredményül. +YIELDDISC = YIELDDISC ## Leszámítolt értékpapír (például kincstárjegy) éves hozamát adja eredményül. +YIELDMAT = YIELDMAT ## Lejáratkor kamatozó értékpapír éves hozamát adja eredményül. + + +## +## Information functions Információs függvények +## +CELL = CELLA ## Egy cella formátumára, elhelyezkedésére vagy tartalmára vonatkozó adatokat ad eredményül. +ERROR.TYPE = HIBA.TÍPUS ## Egy hibatípushoz tartozó számot ad eredményül. +INFO = INFÓ ## A rendszer- és munkakörnyezet pillanatnyi állapotáról ad felvilágosítást. +ISBLANK = ÜRES ## Eredménye IGAZ, ha az érték üres. +ISERR = HIBA ## Eredménye IGAZ, ha az érték valamelyik hibaérték a #HIÁNYZIK kivételével. +ISERROR = HIBÁS ## Eredménye IGAZ, ha az érték valamelyik hibaérték. +ISEVEN = ISEVEN ## Eredménye IGAZ, ha argumentuma páros szám. +ISLOGICAL = LOGIKAI ## Eredménye IGAZ, ha az érték logikai érték. +ISNA = NINCS ## Eredménye IGAZ, ha az érték a #HIÁNYZIK hibaérték. +ISNONTEXT = NEM.SZÖVEG ## Eredménye IGAZ, ha az érték nem szöveg. +ISNUMBER = SZÁM ## Eredménye IGAZ, ha az érték szám. +ISODD = ISODD ## Eredménye IGAZ, ha argumentuma páratlan szám. +ISREF = HIVATKOZÁS ## Eredménye IGAZ, ha az érték hivatkozás. +ISTEXT = SZÖVEG.E ## Eredménye IGAZ, ha az érték szöveg. +N = N ## Argumentumának értékét számmá alakítja. +NA = HIÁNYZIK ## Eredménye a #HIÁNYZIK hibaérték. +TYPE = TÍPUS ## Érték adattípusának azonosítószámát adja eredményül. + + +## +## Logical functions Logikai függvények +## +AND = ÉS ## Eredménye IGAZ, ha minden argumentuma IGAZ. +FALSE = HAMIS ## A HAMIS logikai értéket adja eredményül. +IF = HA ## Logikai vizsgálatot hajt végre. +IFERROR = HAHIBA ## A megadott értéket adja vissza, ha egy képlet hibához vezet; más esetben a képlet értékét adja eredményül. +NOT = NEM ## Argumentuma értékének ellentettjét adja eredményül. +OR = VAGY ## Eredménye IGAZ, ha bármely argumentuma IGAZ. +TRUE = IGAZ ## Az IGAZ logikai értéket adja eredményül. + + +## +## Lookup and reference functions Keresési és hivatkozási függvények +## +ADDRESS = CÍM ## A munkalap egy cellájára való hivatkozást adja szövegként eredményül. +AREAS = TERÜLET ## Hivatkozásban a területek számát adja eredményül. +CHOOSE = VÁLASZT ## Értékek listájából választ ki egy elemet. +COLUMN = OSZLOP ## Egy hivatkozás oszlopszámát adja eredményül. +COLUMNS = OSZLOPOK ## A hivatkozásban található oszlopok számát adja eredményül. +HLOOKUP = VKERES ## A megadott tömb felső sorában adott értékű elemet keres, és a megtalált elem oszlopából adott sorban elhelyezkedő értékkel tér vissza. +HYPERLINK = HIPERHIVATKOZÁS ## Hálózati kiszolgálón, intraneten vagy az interneten tárolt dokumentumot megnyitó parancsikont vagy hivatkozást hoz létre. +INDEX = INDEX ## Tömb- vagy hivatkozás indexszel megadott értékét adja vissza. +INDIRECT = INDIREKT ## Szöveg megadott hivatkozást ad eredményül. +LOOKUP = KERES ## Vektorban vagy tömbben keres meg értékeket. +MATCH = HOL.VAN ## Hivatkozásban vagy tömbben értékeket keres. +OFFSET = OFSZET ## Hivatkozás egy másik hivatkozástól számított távolságát adja meg. +ROW = SOR ## Egy hivatkozás sorának számát adja meg. +ROWS = SOROK ## Egy hivatkozás sorainak számát adja meg. +RTD = RTD ## Valós idejű adatokat keres vissza a COM automatizmust (automatizálás: Egy alkalmazás objektumaival való munka másik alkalmazásból vagy fejlesztőeszközből. A korábban OLE automatizmusnak nevezett automatizálás iparági szabvány, a Component Object Model (COM) szolgáltatása.) támogató programból. +TRANSPOSE = TRANSZPONÁLÁS ## Egy tömb transzponáltját adja eredményül. +VLOOKUP = FKERES ## A megadott tömb bal szélső oszlopában megkeres egy értéket, majd annak sora és a megadott oszlop metszéspontjában levő értéked adja eredményül. + + +## +## Math and trigonometry functions Matematikai és trigonometrikus függvények +## +ABS = ABS ## Egy szám abszolút értékét adja eredményül. +ACOS = ARCCOS ## Egy szám arkusz koszinuszát számítja ki. +ACOSH = ACOSH ## Egy szám inverz koszinusz hiperbolikuszát számítja ki. +ASIN = ARCSIN ## Egy szám arkusz szinuszát számítja ki. +ASINH = ASINH ## Egy szám inverz szinusz hiperbolikuszát számítja ki. +ATAN = ARCTAN ## Egy szám arkusz tangensét számítja ki. +ATAN2 = ARCTAN2 ## X és y koordináták alapján számítja ki az arkusz tangens értéket. +ATANH = ATANH ## A szám inverz tangens hiperbolikuszát számítja ki. +CEILING = PLAFON ## Egy számot a legközelebbi egészre vagy a pontosságként megadott érték legközelebb eső többszörösére kerekít. +COMBIN = KOMBINÁCIÓK ## Adott számú objektum összes lehetséges kombinációinak számát számítja ki. +COS = COS ## Egy szám koszinuszát számítja ki. +COSH = COSH ## Egy szám koszinusz hiperbolikuszát számítja ki. +DEGREES = FOK ## Radiánt fokká alakít át. +EVEN = PÁROS ## Egy számot a legközelebbi páros egész számra kerekít. +EXP = KITEVŐ ## Az e adott kitevőjű hatványát adja eredményül. +FACT = FAKT ## Egy szám faktoriálisát számítja ki. +FACTDOUBLE = FACTDOUBLE ## Egy szám dupla faktoriálisát adja eredményül. +FLOOR = PADLÓ ## Egy számot lefelé, a nulla felé kerekít. +GCD = GCD ## A legnagyobb közös osztót adja eredményül. +INT = INT ## Egy számot lefelé kerekít a legközelebbi egészre. +LCM = LCM ## A legkisebb közös többszöröst adja eredményül. +LN = LN ## Egy szám természetes logaritmusát számítja ki. +LOG = LOG ## Egy szám adott alapú logaritmusát számítja ki. +LOG10 = LOG10 ## Egy szám 10-es alapú logaritmusát számítja ki. +MDETERM = MDETERM ## Egy tömb mátrix-determinánsát számítja ki. +MINVERSE = INVERZ.MÁTRIX ## Egy tömb mátrix inverzét adja eredményül. +MMULT = MSZORZAT ## Két tömb mátrix-szorzatát adja meg. +MOD = MARADÉK ## Egy szám osztási maradékát adja eredményül. +MROUND = MROUND ## A kívánt többszörösére kerekített értéket ad eredményül. +MULTINOMIAL = MULTINOMIAL ## Számhalmaz multinomiálisát adja eredményül. +ODD = PÁRATLAN ## Egy számot a legközelebbi páratlan számra kerekít. +PI = PI ## A pi matematikai állandót adja vissza. +POWER = HATVÁNY ## Egy szám adott kitevőjű hatványát számítja ki. +PRODUCT = SZORZAT ## Argumentumai szorzatát számítja ki. +QUOTIENT = QUOTIENT ## Egy hányados egész részét adja eredményül. +RADIANS = RADIÁN ## Fokot radiánná alakít át. +RAND = VÉL ## Egy 0 és 1 közötti véletlen számot ad eredményül. +RANDBETWEEN = RANDBETWEEN ## Megadott számok közé eső véletlen számot állít elő. +ROMAN = RÓMAI ## Egy számot római számokkal kifejezve szövegként ad eredményül. +ROUND = KEREKÍTÉS ## Egy számot adott számú számjegyre kerekít. +ROUNDDOWN = KEREKÍTÉS.LE ## Egy számot lefelé, a nulla felé kerekít. +ROUNDUP = KEREKÍTÉS.FEL ## Egy számot felfelé, a nullától távolabbra kerekít. +SERIESSUM = SERIESSUM ## Hatványsor összegét adja eredményül. +SIGN = ELŐJEL ## Egy szám előjelét adja meg. +SIN = SIN ## Egy szög szinuszát számítja ki. +SINH = SINH ## Egy szám szinusz hiperbolikuszát számítja ki. +SQRT = GYÖK ## Egy szám pozitív négyzetgyökét számítja ki. +SQRTPI = SQRTPI ## A (szám*pi) négyzetgyökét adja eredményül. +SUBTOTAL = RÉSZÖSSZEG ## Lista vagy adatbázis részösszegét adja eredményül. +SUM = SZUM ## Összeadja az argumentumlistájában lévő számokat. +SUMIF = SZUMHA ## A megadott feltételeknek eleget tevő cellákban található értékeket adja össze. +SUMIFS = SZUMHATÖBB ## Több megadott feltételnek eleget tévő tartománycellák összegét adja eredményül. +SUMPRODUCT = SZORZATÖSSZEG ## A megfelelő tömbelemek szorzatának összegét számítja ki. +SUMSQ = NÉGYZETÖSSZEG ## Argumentumai négyzetének összegét számítja ki. +SUMX2MY2 = SZUMX2BŐLY2 ## Két tömb megfelelő elemei négyzetének különbségét összegzi. +SUMX2PY2 = SZUMX2MEGY2 ## Két tömb megfelelő elemei négyzetének összegét összegzi. +SUMXMY2 = SZUMXBŐLY2 ## Két tömb megfelelő elemei különbségének négyzetösszegét számítja ki. +TAN = TAN ## Egy szám tangensét számítja ki. +TANH = TANH ## Egy szám tangens hiperbolikuszát számítja ki. +TRUNC = CSONK ## Egy számot egésszé csonkít. + + +## +## Statistical functions Statisztikai függvények +## +AVEDEV = ÁTL.ELTÉRÉS ## Az adatpontoknak átlaguktól való átlagos abszolút eltérését számítja ki. +AVERAGE = ÁTLAG ## Argumentumai átlagát számítja ki. +AVERAGEA = ÁTLAGA ## Argumentumai átlagát számítja ki (beleértve a számokat, szöveget és logikai értékeket). +AVERAGEIF = ÁTLAGHA ## A megadott feltételnek eleget tévő tartomány celláinak átlagát (számtani közepét) adja eredményül. +AVERAGEIFS = ÁTLAGHATÖBB ## A megadott feltételeknek eleget tévő cellák átlagát (számtani közepét) adja eredményül. +BETADIST = BÉTA.ELOSZLÁS ## A béta-eloszlás függvényt számítja ki. +BETAINV = INVERZ.BÉTA ## Adott béta-eloszláshoz kiszámítja a béta eloszlásfüggvény inverzét. +BINOMDIST = BINOM.ELOSZLÁS ## A diszkrét binomiális eloszlás valószínűségértékét számítja ki. +CHIDIST = KHI.ELOSZLÁS ## A khi-négyzet-eloszlás egyszélű valószínűségértékét számítja ki. +CHIINV = INVERZ.KHI ## A khi-négyzet-eloszlás egyszélű valószínűségértékének inverzét számítja ki. +CHITEST = KHI.PRÓBA ## Függetlenségvizsgálatot hajt végre. +CONFIDENCE = MEGBÍZHATÓSÁG ## Egy statisztikai sokaság várható értékének megbízhatósági intervallumát adja eredményül. +CORREL = KORREL ## Két adathalmaz korrelációs együtthatóját számítja ki. +COUNT = DARAB ## Megszámolja, hogy argumentumlistájában hány szám található. +COUNTA = DARAB2 ## Megszámolja, hogy argumentumlistájában hány érték található. +COUNTBLANK = DARABÜRES ## Egy tartományban összeszámolja az üres cellákat. +COUNTIF = DARABTELI ## Egy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek a megadott feltételnek. +COUNTIFS = DARABHATÖBB ## Egy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek több feltételnek. +COVAR = KOVAR ## A kovarianciát, azaz a páronkénti eltérések szorzatának átlagát számítja ki. +CRITBINOM = KRITBINOM ## Azt a legkisebb számot adja eredményül, amelyre a binomiális eloszlásfüggvény értéke nem kisebb egy adott határértéknél. +DEVSQ = SQ ## Az átlagtól való eltérések négyzetének összegét számítja ki. +EXPONDIST = EXP.ELOSZLÁS ## Az exponenciális eloszlás értékét számítja ki. +FDIST = F.ELOSZLÁS ## Az F-eloszlás értékét számítja ki. +FINV = INVERZ.F ## Az F-eloszlás inverzének értékét számítja ki. +FISHER = FISHER ## Fisher-transzformációt hajt végre. +FISHERINV = INVERZ.FISHER ## A Fisher-transzformáció inverzét hajtja végre. +FORECAST = ELŐREJELZÉS ## Az ismert értékek alapján lineáris regresszióval becsült értéket ad eredményül. +FREQUENCY = GYAKORISÁG ## A gyakorisági vagy empirikus eloszlás értékét függőleges tömbként adja eredményül. +FTEST = F.PRÓBA ## Az F-próba értékét adja eredményül. +GAMMADIST = GAMMA.ELOSZLÁS ## A gamma-eloszlás értékét számítja ki. +GAMMAINV = INVERZ.GAMMA ## A gamma-eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +GAMMALN = GAMMALN ## A gamma-függvény természetes logaritmusát számítja ki. +GEOMEAN = MÉRTANI.KÖZÉP ## Argumentumai mértani középértékét számítja ki. +GROWTH = NÖV ## Exponenciális regresszió alapján ad becslést. +HARMEAN = HARM.KÖZÉP ## Argumentumai harmonikus átlagát számítja ki. +HYPGEOMDIST = HIPERGEOM.ELOSZLÁS ## A hipergeometriai eloszlás értékét számítja ki. +INTERCEPT = METSZ ## A regressziós egyenes y tengellyel való metszéspontját határozza meg. +KURT = CSÚCSOSSÁG ## Egy adathalmaz csúcsosságát számítja ki. +LARGE = NAGY ## Egy adathalmaz k-adik legnagyobb elemét adja eredményül. +LINEST = LIN.ILL ## A legkisebb négyzetek módszerével az adatokra illesztett egyenes paramétereit határozza meg. +LOGEST = LOG.ILL ## Az adatokra illesztett exponenciális görbe paramétereit határozza meg. +LOGINV = INVERZ.LOG.ELOSZLÁS ## A lognormális eloszlás inverzét számítja ki. +LOGNORMDIST = LOG.ELOSZLÁS ## A lognormális eloszlásfüggvény értékét számítja ki. +MAX = MAX ## Az argumentumai között szereplő legnagyobb számot adja meg. +MAXA = MAX2 ## Az argumentumai között szereplő legnagyobb számot adja meg (beleértve a számokat, szöveget és logikai értékeket). +MEDIAN = MEDIÁN ## Adott számhalmaz mediánját számítja ki. +MIN = MIN ## Az argumentumai között szereplő legkisebb számot adja meg. +MINA = MIN2 ## Az argumentumai között szereplő legkisebb számot adja meg, beleértve a számokat, szöveget és logikai értékeket. +MODE = MÓDUSZ ## Egy adathalmazból kiválasztja a leggyakrabban előforduló számot. +NEGBINOMDIST = NEGBINOM.ELOSZL ## A negatív binomiális eloszlás értékét számítja ki. +NORMDIST = NORM.ELOSZL ## A normális eloszlás értékét számítja ki. +NORMINV = INVERZ.NORM ## A normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +NORMSDIST = STNORMELOSZL ## A standard normális eloszlás eloszlásfüggvényének értékét számítja ki. +NORMSINV = INVERZ.STNORM ## A standard normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki. +PEARSON = PEARSON ## A Pearson-féle korrelációs együtthatót számítja ki. +PERCENTILE = PERCENTILIS ## Egy tartományban található értékek k-adik percentilisét, azaz százalékosztályát adja eredményül. +PERCENTRANK = SZÁZALÉKRANG ## Egy értéknek egy adathalmazon belül vett százalékos rangját (elhelyezkedését) számítja ki. +PERMUT = VARIÁCIÓK ## Adott számú objektum k-ad osztályú ismétlés nélküli variációinak számát számítja ki. +POISSON = POISSON ## A Poisson-eloszlás értékét számítja ki. +PROB = VALÓSZÍNŰSÉG ## Annak valószínűségét számítja ki, hogy adott értékek két határérték közé esnek. +QUARTILE = KVARTILIS ## Egy adathalmaz kvartilisét (negyedszintjét) számítja ki. +RANK = SORSZÁM ## Kiszámítja, hogy egy szám hányadik egy számsorozatban. +RSQ = RNÉGYZET ## Kiszámítja a Pearson-féle szorzatmomentum korrelációs együtthatójának négyzetét. +SKEW = FERDESÉG ## Egy eloszlás ferdeségét határozza meg. +SLOPE = MEREDEKSÉG ## Egy lineáris regressziós egyenes meredekségét számítja ki. +SMALL = KICSI ## Egy adathalmaz k-adik legkisebb elemét adja meg. +STANDARDIZE = NORMALIZÁLÁS ## Normalizált értéket ad eredményül. +STDEV = SZÓRÁS ## Egy statisztikai sokaság mintájából kiszámítja annak szórását. +STDEVA = SZÓRÁSA ## Egy statisztikai sokaság mintájából kiszámítja annak szórását (beleértve a számokat, szöveget és logikai értékeket). +STDEVP = SZÓRÁSP ## Egy statisztikai sokaság egészéből kiszámítja annak szórását. +STDEVPA = SZÓRÁSPA ## Egy statisztikai sokaság egészéből kiszámítja annak szórását (beleértve számokat, szöveget és logikai értékeket). +STEYX = STHIBAYX ## Egy regresszió esetén az egyes x-értékek alapján meghatározott y-értékek standard hibáját számítja ki. +TDIST = T.ELOSZLÁS ## A Student-féle t-eloszlás értékét számítja ki. +TINV = INVERZ.T ## A Student-féle t-eloszlás inverzét számítja ki. +TREND = TREND ## Lineáris trend értékeit számítja ki. +TRIMMEAN = RÉSZÁTLAG ## Egy adathalmaz középső részének átlagát számítja ki. +TTEST = T.PRÓBA ## A Student-féle t-próbához tartozó valószínűséget számítja ki. +VAR = VAR ## Minta alapján becslést ad a varianciára. +VARA = VARA ## Minta alapján becslést ad a varianciára (beleértve számokat, szöveget és logikai értékeket). +VARP = VARP ## Egy statisztikai sokaság varianciáját számítja ki. +VARPA = VARPA ## Egy statisztikai sokaság varianciáját számítja ki (beleértve számokat, szöveget és logikai értékeket). +WEIBULL = WEIBULL ## A Weibull-féle eloszlás értékét számítja ki. +ZTEST = Z.PRÓBA ## Az egyszélű z-próbával kapott valószínűségértéket számítja ki. + + +## +## Text functions Szövegműveletekhez használható függvények +## +ASC = ASC ## Szöveg teljes szélességű (kétbájtos) latin és katakana karaktereit félszélességű (egybájtos) karakterekké alakítja. +BAHTTEXT = BAHTSZÖVEG ## Számot szöveggé alakít a ß (baht) pénznemformátum használatával. +CHAR = KARAKTER ## A kódszámmal meghatározott karaktert adja eredményül. +CLEAN = TISZTÍT ## A szövegből eltávolítja az összes nem nyomtatható karaktert. +CODE = KÓD ## Karaktersorozat első karakterének numerikus kódját adja eredményül. +CONCATENATE = ÖSSZEFŰZ ## Több szövegelemet egyetlen szöveges elemmé fűz össze. +DOLLAR = FORINT ## Számot pénznem formátumú szöveggé alakít át. +EXACT = AZONOS ## Megvizsgálja, hogy két érték azonos-e. +FIND = SZÖVEG.TALÁL ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével). +FINDB = SZÖVEG.TALÁL2 ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével). +FIXED = FIX ## Számot szöveges formátumúra alakít adott számú tizedesjegyre kerekítve. +JIS = JIS ## A félszélességű (egybájtos) latin és a katakana karaktereket teljes szélességű (kétbájtos) karakterekké alakítja. +LEFT = BAL ## Szöveg bal szélső karaktereit adja eredményül. +LEFTB = BAL2 ## Szöveg bal szélső karaktereit adja eredményül. +LEN = HOSSZ ## Szöveg karakterekben mért hosszát adja eredményül. +LENB = HOSSZ2 ## Szöveg karakterekben mért hosszát adja eredményül. +LOWER = KISBETŰ ## Szöveget kisbetűssé alakít át. +MID = KÖZÉP ## A szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként. +MIDB = KÖZÉP2 ## A szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként. +PHONETIC = PHONETIC ## Szöveg furigana (fonetikus) karaktereit adja vissza. +PROPER = TNÉV ## Szöveg minden szavának kezdőbetűjét nagybetűsre cseréli. +REPLACE = CSERE ## A szövegen belül karaktereket cserél. +REPLACEB = CSERE2 ## A szövegen belül karaktereket cserél. +REPT = SOKSZOR ## Megadott számú alkalommal megismétel egy szövegrészt. +RIGHT = JOBB ## Szövegrész jobb szélső karaktereit adja eredményül. +RIGHTB = JOBB2 ## Szövegrész jobb szélső karaktereit adja eredményül. +SEARCH = SZÖVEG.KERES ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget). +SEARCHB = SZÖVEG.KERES2 ## Karaktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget). +SUBSTITUTE = HELYETTE ## Szövegben adott karaktereket másikra cserél. +T = T ## Argumentumát szöveggé alakítja át. +TEXT = SZÖVEG ## Számértéket alakít át adott számformátumú szöveggé. +TRIM = TRIM ## A szövegből eltávolítja a szóközöket. +UPPER = NAGYBETŰS ## Szöveget nagybetűssé alakít át. +VALUE = ÉRTÉK ## Szöveget számmá alakít át. diff --git a/extend/phpexcel/PHPExcel/locale/it/config b/extend/phpexcel/PHPExcel/locale/it/config new file mode 100755 index 0000000..94499fe --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/it/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULLO! +DIV0 = #DIV/0! +VALUE = #VALORE! +REF = #RIF! +NAME = #NOME? +NUM = #NUM! +NA = #N/D diff --git a/extend/phpexcel/PHPExcel/locale/it/functions b/extend/phpexcel/PHPExcel/locale/it/functions new file mode 100755 index 0000000..033b969 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/it/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funzioni di automazione e dei componenti aggiuntivi +## +GETPIVOTDATA = INFO.DATI.TAB.PIVOT ## Restituisce i dati memorizzati in un rapporto di tabella pivot + + +## +## Cube functions Funzioni cubo +## +CUBEKPIMEMBER = MEMBRO.KPI.CUBO ## Restituisce il nome, la proprietà e la misura di un indicatore di prestazioni chiave (KPI) e visualizza il nome e la proprietà nella cella. Un KPI è una misura quantificabile, ad esempio l'utile lordo mensile o il fatturato trimestrale dei dipendenti, utilizzata per il monitoraggio delle prestazioni di un'organizzazione. +CUBEMEMBER = MEMBRO.CUBO ## Restituisce un membro o una tupla in una gerarchia di cubi. Consente di verificare l'esistenza del membro o della tupla nel cubo. +CUBEMEMBERPROPERTY = PROPRIETÀ.MEMBRO.CUBO ## Restituisce il valore di una proprietà di un membro del cubo. Consente di verificare l'esistenza di un nome di membro all'interno del cubo e di restituire la proprietà specificata per tale membro. +CUBERANKEDMEMBER = MEMBRO.CUBO.CON.RANGO ## Restituisce l'n-esimo membro o il membro ordinato di un insieme. Consente di restituire uno o più elementi in un insieme, ad esempio l'agente di vendita migliore o i primi 10 studenti. +CUBESET = SET.CUBO ## Definisce un insieme di tuple o membri calcolati mediante l'invio di un'espressione di insieme al cubo sul server. In questo modo l'insieme viene creato e restituito a Microsoft Office Excel. +CUBESETCOUNT = CONTA.SET.CUBO ## Restituisce il numero di elementi di un insieme. +CUBEVALUE = VALORE.CUBO ## Restituisce un valore aggregato da un cubo. + + +## +## Database functions Funzioni di database +## +DAVERAGE = DB.MEDIA ## Restituisce la media di voci del database selezionate +DCOUNT = DB.CONTA.NUMERI ## Conta le celle di un database contenenti numeri +DCOUNTA = DB.CONTA.VALORI ## Conta le celle non vuote in un database +DGET = DB.VALORI ## Estrae da un database un singolo record che soddisfa i criteri specificati +DMAX = DB.MAX ## Restituisce il valore massimo dalle voci selezionate in un database +DMIN = DB.MIN ## Restituisce il valore minimo dalle voci di un database selezionate +DPRODUCT = DB.PRODOTTO ## Moltiplica i valori in un determinato campo di record che soddisfano i criteri del database +DSTDEV = DB.DEV.ST ## Restituisce una stima della deviazione standard sulla base di un campione di voci di un database selezionate +DSTDEVP = DB.DEV.ST.POP ## Calcola la deviazione standard sulla base di tutte le voci di un database selezionate +DSUM = DB.SOMMA ## Aggiunge i numeri nel campo colonna di record del database che soddisfa determinati criteri +DVAR = DB.VAR ## Restituisce una stima della varianza sulla base di un campione da voci di un database selezionate +DVARP = DB.VAR.POP ## Calcola la varianza sulla base di tutte le voci di un database selezionate + + +## +## Date and time functions Funzioni data e ora +## +DATE = DATA ## Restituisce il numero seriale di una determinata data +DATEVALUE = DATA.VALORE ## Converte una data sotto forma di testo in un numero seriale +DAY = GIORNO ## Converte un numero seriale in un giorno del mese +DAYS360 = GIORNO360 ## Calcola il numero di giorni compreso tra due date basandosi su un anno di 360 giorni +EDATE = DATA.MESE ## Restituisce il numero seriale della data che rappresenta il numero di mesi prima o dopo la data di inizio +EOMONTH = FINE.MESE ## Restituisce il numero seriale dell'ultimo giorno del mese, prima o dopo un determinato numero di mesi +HOUR = ORA ## Converte un numero seriale in un'ora +MINUTE = MINUTO ## Converte un numero seriale in un minuto +MONTH = MESE ## Converte un numero seriale in un mese +NETWORKDAYS = GIORNI.LAVORATIVI.TOT ## Restituisce il numero di tutti i giorni lavorativi compresi fra due date +NOW = ADESSO ## Restituisce il numero seriale della data e dell'ora corrente +SECOND = SECONDO ## Converte un numero seriale in un secondo +TIME = ORARIO ## Restituisce il numero seriale di una determinata ora +TIMEVALUE = ORARIO.VALORE ## Converte un orario in forma di testo in un numero seriale +TODAY = OGGI ## Restituisce il numero seriale relativo alla data odierna +WEEKDAY = GIORNO.SETTIMANA ## Converte un numero seriale in un giorno della settimana +WEEKNUM = NUM.SETTIMANA ## Converte un numero seriale in un numero che rappresenta la posizione numerica di una settimana nell'anno +WORKDAY = GIORNO.LAVORATIVO ## Restituisce il numero della data prima o dopo un determinato numero di giorni lavorativi +YEAR = ANNO ## Converte un numero seriale in un anno +YEARFRAC = FRAZIONE.ANNO ## Restituisce la frazione dell'anno che rappresenta il numero dei giorni compresi tra una data_ iniziale e una data_finale + + +## +## Engineering functions Funzioni ingegneristiche +## +BESSELI = BESSEL.I ## Restituisce la funzione di Bessel modificata In(x) +BESSELJ = BESSEL.J ## Restituisce la funzione di Bessel Jn(x) +BESSELK = BESSEL.K ## Restituisce la funzione di Bessel modificata Kn(x) +BESSELY = BESSEL.Y ## Restituisce la funzione di Bessel Yn(x) +BIN2DEC = BINARIO.DECIMALE ## Converte un numero binario in decimale +BIN2HEX = BINARIO.HEX ## Converte un numero binario in esadecimale +BIN2OCT = BINARIO.OCT ## Converte un numero binario in ottale +COMPLEX = COMPLESSO ## Converte i coefficienti reali e immaginari in numeri complessi +CONVERT = CONVERTI ## Converte un numero da un sistema di misura in un altro +DEC2BIN = DECIMALE.BINARIO ## Converte un numero decimale in binario +DEC2HEX = DECIMALE.HEX ## Converte un numero decimale in esadecimale +DEC2OCT = DECIMALE.OCT ## Converte un numero decimale in ottale +DELTA = DELTA ## Verifica se due valori sono uguali +ERF = FUNZ.ERRORE ## Restituisce la funzione di errore +ERFC = FUNZ.ERRORE.COMP ## Restituisce la funzione di errore complementare +GESTEP = SOGLIA ## Verifica se un numero è maggiore del valore di soglia +HEX2BIN = HEX.BINARIO ## Converte un numero esadecimale in binario +HEX2DEC = HEX.DECIMALE ## Converte un numero esadecimale in decimale +HEX2OCT = HEX.OCT ## Converte un numero esadecimale in ottale +IMABS = COMP.MODULO ## Restituisce il valore assoluto (modulo) di un numero complesso +IMAGINARY = COMP.IMMAGINARIO ## Restituisce il coefficiente immaginario di un numero complesso +IMARGUMENT = COMP.ARGOMENTO ## Restituisce l'argomento theta, un angolo espresso in radianti +IMCONJUGATE = COMP.CONIUGATO ## Restituisce il complesso coniugato del numero complesso +IMCOS = COMP.COS ## Restituisce il coseno di un numero complesso +IMDIV = COMP.DIV ## Restituisce il quoziente di due numeri complessi +IMEXP = COMP.EXP ## Restituisce il valore esponenziale di un numero complesso +IMLN = COMP.LN ## Restituisce il logaritmo naturale di un numero complesso +IMLOG10 = COMP.LOG10 ## Restituisce il logaritmo in base 10 di un numero complesso +IMLOG2 = COMP.LOG2 ## Restituisce un logaritmo in base 2 di un numero complesso +IMPOWER = COMP.POTENZA ## Restituisce il numero complesso elevato a una potenza intera +IMPRODUCT = COMP.PRODOTTO ## Restituisce il prodotto di numeri complessi compresi tra 2 e 29 +IMREAL = COMP.PARTE.REALE ## Restituisce il coefficiente reale di un numero complesso +IMSIN = COMP.SEN ## Restituisce il seno di un numero complesso +IMSQRT = COMP.RADQ ## Restituisce la radice quadrata di un numero complesso +IMSUB = COMP.DIFF ## Restituisce la differenza fra due numeri complessi +IMSUM = COMP.SOMMA ## Restituisce la somma di numeri complessi +OCT2BIN = OCT.BINARIO ## Converte un numero ottale in binario +OCT2DEC = OCT.DECIMALE ## Converte un numero ottale in decimale +OCT2HEX = OCT.HEX ## Converte un numero ottale in esadecimale + + +## +## Financial functions Funzioni finanziarie +## +ACCRINT = INT.MATURATO.PER ## Restituisce l'interesse maturato di un titolo che paga interessi periodici +ACCRINTM = INT.MATURATO.SCAD ## Restituisce l'interesse maturato di un titolo che paga interessi alla scadenza +AMORDEGRC = AMMORT.DEGR ## Restituisce l'ammortamento per ogni periodo contabile utilizzando un coefficiente di ammortamento +AMORLINC = AMMORT.PER ## Restituisce l'ammortamento per ogni periodo contabile +COUPDAYBS = GIORNI.CED.INIZ.LIQ ## Restituisce il numero dei giorni che vanno dall'inizio del periodo di durata della cedola alla data di liquidazione +COUPDAYS = GIORNI.CED ## Restituisce il numero dei giorni relativi al periodo della cedola che contiene la data di liquidazione +COUPDAYSNC = GIORNI.CED.NUOVA ## Restituisce il numero di giorni che vanno dalla data di liquidazione alla data della cedola successiva +COUPNCD = DATA.CED.SUCC ## Restituisce un numero che rappresenta la data della cedola successiva alla data di liquidazione +COUPNUM = NUM.CED ## Restituisce il numero di cedole pagabili fra la data di liquidazione e la data di scadenza +COUPPCD = DATA.CED.PREC ## Restituisce un numero che rappresenta la data della cedola precedente alla data di liquidazione +CUMIPMT = INT.CUMUL ## Restituisce l'interesse cumulativo pagato fra due periodi +CUMPRINC = CAP.CUM ## Restituisce il capitale cumulativo pagato per estinguere un debito fra due periodi +DB = DB ## Restituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a quote fisse decrescenti +DDB = AMMORT ## Restituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a doppie quote decrescenti o altri metodi specificati +DISC = TASSO.SCONTO ## Restituisce il tasso di sconto per un titolo +DOLLARDE = VALUTA.DEC ## Converte un prezzo valuta, espresso come frazione, in prezzo valuta, espresso come numero decimale +DOLLARFR = VALUTA.FRAZ ## Converte un prezzo valuta, espresso come numero decimale, in prezzo valuta, espresso come frazione +DURATION = DURATA ## Restituisce la durata annuale di un titolo con i pagamenti di interesse periodico +EFFECT = EFFETTIVO ## Restituisce l'effettivo tasso di interesse annuo +FV = VAL.FUT ## Restituisce il valore futuro di un investimento +FVSCHEDULE = VAL.FUT.CAPITALE ## Restituisce il valore futuro di un capitale iniziale dopo aver applicato una serie di tassi di interesse composti +INTRATE = TASSO.INT ## Restituisce il tasso di interesse per un titolo interamente investito +IPMT = INTERESSI ## Restituisce il valore degli interessi per un investimento relativo a un periodo specifico +IRR = TIR.COST ## Restituisce il tasso di rendimento interno per una serie di flussi di cassa +ISPMT = INTERESSE.RATA ## Calcola l'interesse di un investimento pagato durante un periodo specifico +MDURATION = DURATA.M ## Restituisce la durata Macauley modificata per un titolo con un valore presunto di € 100 +MIRR = TIR.VAR ## Restituisce il tasso di rendimento interno in cui i flussi di cassa positivi e negativi sono finanziati a tassi differenti +NOMINAL = NOMINALE ## Restituisce il tasso di interesse nominale annuale +NPER = NUM.RATE ## Restituisce un numero di periodi relativi a un investimento +NPV = VAN ## Restituisce il valore attuale netto di un investimento basato su una serie di flussi di cassa periodici e sul tasso di sconto +ODDFPRICE = PREZZO.PRIMO.IRR ## Restituisce il prezzo di un titolo dal valore nominale di € 100 avente il primo periodo di durata irregolare +ODDFYIELD = REND.PRIMO.IRR ## Restituisce il rendimento di un titolo avente il primo periodo di durata irregolare +ODDLPRICE = PREZZO.ULTIMO.IRR ## Restituisce il prezzo di un titolo dal valore nominale di € 100 avente l'ultimo periodo di durata irregolare +ODDLYIELD = REND.ULTIMO.IRR ## Restituisce il rendimento di un titolo avente l'ultimo periodo di durata irregolare +PMT = RATA ## Restituisce il pagamento periodico di una rendita annua +PPMT = P.RATA ## Restituisce il pagamento sul capitale di un investimento per un dato periodo +PRICE = PREZZO ## Restituisce il prezzo di un titolo dal valore nominale di € 100 che paga interessi periodici +PRICEDISC = PREZZO.SCONT ## Restituisce il prezzo di un titolo scontato dal valore nominale di € 100 +PRICEMAT = PREZZO.SCAD ## Restituisce il prezzo di un titolo dal valore nominale di € 100 che paga gli interessi alla scadenza +PV = VA ## Restituisce il valore attuale di un investimento +RATE = TASSO ## Restituisce il tasso di interesse per un periodo di un'annualità +RECEIVED = RICEV.SCAD ## Restituisce l'ammontare ricevuto alla scadenza di un titolo interamente investito +SLN = AMMORT.COST ## Restituisce l'ammortamento a quote costanti di un bene per un singolo periodo +SYD = AMMORT.ANNUO ## Restituisce l'ammortamento a somma degli anni di un bene per un periodo specificato +TBILLEQ = BOT.EQUIV ## Restituisce il rendimento equivalente ad un'obbligazione per un Buono ordinario del Tesoro +TBILLPRICE = BOT.PREZZO ## Restituisce il prezzo di un Buono del Tesoro dal valore nominale di € 100 +TBILLYIELD = BOT.REND ## Restituisce il rendimento di un Buono del Tesoro +VDB = AMMORT.VAR ## Restituisce l'ammortamento di un bene per un periodo specificato o parziale utilizzando il metodo a doppie quote proporzionali ai valori residui +XIRR = TIR.X ## Restituisce il tasso di rendimento interno di un impiego di flussi di cassa +XNPV = VAN.X ## Restituisce il valore attuale netto di un impiego di flussi di cassa non necessariamente periodici +YIELD = REND ## Restituisce il rendimento di un titolo che frutta interessi periodici +YIELDDISC = REND.TITOLI.SCONT ## Restituisce il rendimento annuale di un titolo scontato, ad esempio un Buono del Tesoro +YIELDMAT = REND.SCAD ## Restituisce il rendimento annuo di un titolo che paga interessi alla scadenza + + +## +## Information functions Funzioni relative alle informazioni +## +CELL = CELLA ## Restituisce le informazioni sulla formattazione, la posizione o i contenuti di una cella +ERROR.TYPE = ERRORE.TIPO ## Restituisce un numero che corrisponde a un tipo di errore +INFO = INFO ## Restituisce le informazioni sull'ambiente operativo corrente +ISBLANK = VAL.VUOTO ## Restituisce VERO se il valore è vuoto +ISERR = VAL.ERR ## Restituisce VERO se il valore è un valore di errore qualsiasi tranne #N/D +ISERROR = VAL.ERRORE ## Restituisce VERO se il valore è un valore di errore qualsiasi +ISEVEN = VAL.PARI ## Restituisce VERO se il numero è pari +ISLOGICAL = VAL.LOGICO ## Restituisce VERO se il valore è un valore logico +ISNA = VAL.NON.DISP ## Restituisce VERO se il valore è un valore di errore #N/D +ISNONTEXT = VAL.NON.TESTO ## Restituisce VERO se il valore non è in formato testo +ISNUMBER = VAL.NUMERO ## Restituisce VERO se il valore è un numero +ISODD = VAL.DISPARI ## Restituisce VERO se il numero è dispari +ISREF = VAL.RIF ## Restituisce VERO se il valore è un riferimento +ISTEXT = VAL.TESTO ## Restituisce VERO se il valore è in formato testo +N = NUM ## Restituisce un valore convertito in numero +NA = NON.DISP ## Restituisce il valore di errore #N/D +TYPE = TIPO ## Restituisce un numero che indica il tipo di dati relativi a un valore + + +## +## Logical functions Funzioni logiche +## +AND = E ## Restituisce VERO se tutti gli argomenti sono VERO +FALSE = FALSO ## Restituisce il valore logico FALSO +IF = SE ## Specifica un test logico da eseguire +IFERROR = SE.ERRORE ## Restituisce un valore specificato se una formula fornisce un errore come risultato; in caso contrario, restituisce il risultato della formula +NOT = NON ## Inverte la logica degli argomenti +OR = O ## Restituisce VERO se un argomento qualsiasi è VERO +TRUE = VERO ## Restituisce il valore logico VERO + + +## +## Lookup and reference functions Funzioni di ricerca e di riferimento +## +ADDRESS = INDIRIZZO ## Restituisce un riferimento come testo in una singola cella di un foglio di lavoro +AREAS = AREE ## Restituisce il numero di aree in un riferimento +CHOOSE = SCEGLI ## Sceglie un valore da un elenco di valori +COLUMN = RIF.COLONNA ## Restituisce il numero di colonna di un riferimento +COLUMNS = COLONNE ## Restituisce il numero di colonne in un riferimento +HLOOKUP = CERCA.ORIZZ ## Effettua una ricerca nella riga superiore di una matrice e restituisce il valore della cella specificata +HYPERLINK = COLLEG.IPERTESTUALE ## Crea un collegamento che apre un documento memorizzato in un server di rete, una rete Intranet o Internet +INDEX = INDICE ## Utilizza un indice per scegliere un valore da un riferimento o da una matrice +INDIRECT = INDIRETTO ## Restituisce un riferimento specificato da un valore testo +LOOKUP = CERCA ## Ricerca i valori in un vettore o in una matrice +MATCH = CONFRONTA ## Ricerca i valori in un riferimento o in una matrice +OFFSET = SCARTO ## Restituisce uno scarto di riferimento da un riferimento dato +ROW = RIF.RIGA ## Restituisce il numero di riga di un riferimento +ROWS = RIGHE ## Restituisce il numero delle righe in un riferimento +RTD = DATITEMPOREALE ## Recupera dati in tempo reale da un programma che supporta l'automazione COM (automazione: Metodo per utilizzare gli oggetti di un'applicazione da un'altra applicazione o da un altro strumento di sviluppo. Precedentemente nota come automazione OLE, l'automazione è uno standard del settore e una caratteristica del modello COM (Component Object Model).) +TRANSPOSE = MATR.TRASPOSTA ## Restituisce la trasposizione di una matrice +VLOOKUP = CERCA.VERT ## Effettua una ricerca nella prima colonna di una matrice e si sposta attraverso la riga per restituire il valore di una cella + + +## +## Math and trigonometry functions Funzioni matematiche e trigonometriche +## +ABS = ASS ## Restituisce il valore assoluto di un numero. +ACOS = ARCCOS ## Restituisce l'arcocoseno di un numero +ACOSH = ARCCOSH ## Restituisce l'inverso del coseno iperbolico di un numero +ASIN = ARCSEN ## Restituisce l'arcoseno di un numero +ASINH = ARCSENH ## Restituisce l'inverso del seno iperbolico di un numero +ATAN = ARCTAN ## Restituisce l'arcotangente di un numero +ATAN2 = ARCTAN.2 ## Restituisce l'arcotangente delle coordinate x e y specificate +ATANH = ARCTANH ## Restituisce l'inverso della tangente iperbolica di un numero +CEILING = ARROTONDA.ECCESSO ## Arrotonda un numero per eccesso all'intero più vicino o al multiplo più vicino a peso +COMBIN = COMBINAZIONE ## Restituisce il numero di combinazioni possibili per un numero assegnato di elementi +COS = COS ## Restituisce il coseno dell'angolo specificato +COSH = COSH ## Restituisce il coseno iperbolico di un numero +DEGREES = GRADI ## Converte i radianti in gradi +EVEN = PARI ## Arrotonda il valore assoluto di un numero per eccesso al più vicino intero pari +EXP = ESP ## Restituisce il numero e elevato alla potenza di num +FACT = FATTORIALE ## Restituisce il fattoriale di un numero +FACTDOUBLE = FATT.DOPPIO ## Restituisce il fattoriale doppio di un numero +FLOOR = ARROTONDA.DIFETTO ## Arrotonda un numero per difetto al multiplo più vicino a zero +GCD = MCD ## Restituisce il massimo comune divisore +INT = INT ## Arrotonda un numero per difetto al numero intero più vicino +LCM = MCM ## Restituisce il minimo comune multiplo +LN = LN ## Restituisce il logaritmo naturale di un numero +LOG = LOG ## Restituisce il logaritmo di un numero in una specificata base +LOG10 = LOG10 ## Restituisce il logaritmo in base 10 di un numero +MDETERM = MATR.DETERM ## Restituisce il determinante di una matrice +MINVERSE = MATR.INVERSA ## Restituisce l'inverso di una matrice +MMULT = MATR.PRODOTTO ## Restituisce il prodotto di due matrici +MOD = RESTO ## Restituisce il resto della divisione +MROUND = ARROTONDA.MULTIPLO ## Restituisce un numero arrotondato al multiplo desiderato +MULTINOMIAL = MULTINOMIALE ## Restituisce il multinomiale di un insieme di numeri +ODD = DISPARI ## Arrotonda un numero per eccesso al più vicino intero dispari +PI = PI.GRECO ## Restituisce il valore di pi greco +POWER = POTENZA ## Restituisce il risultato di un numero elevato a potenza +PRODUCT = PRODOTTO ## Moltiplica i suoi argomenti +QUOTIENT = QUOZIENTE ## Restituisce la parte intera di una divisione +RADIANS = RADIANTI ## Converte i gradi in radianti +RAND = CASUALE ## Restituisce un numero casuale compreso tra 0 e 1 +RANDBETWEEN = CASUALE.TRA ## Restituisce un numero casuale compreso tra i numeri specificati +ROMAN = ROMANO ## Restituisce il numero come numero romano sotto forma di testo +ROUND = ARROTONDA ## Arrotonda il numero al numero di cifre specificato +ROUNDDOWN = ARROTONDA.PER.DIF ## Arrotonda il valore assoluto di un numero per difetto +ROUNDUP = ARROTONDA.PER.ECC ## Arrotonda il valore assoluto di un numero per eccesso +SERIESSUM = SOMMA.SERIE ## Restituisce la somma di una serie di potenze in base alla formula +SIGN = SEGNO ## Restituisce il segno di un numero +SIN = SEN ## Restituisce il seno di un dato angolo +SINH = SENH ## Restituisce il seno iperbolico di un numero +SQRT = RADQ ## Restituisce una radice quadrata +SQRTPI = RADQ.PI.GRECO ## Restituisce la radice quadrata di un numero (numero * pi greco) +SUBTOTAL = SUBTOTALE ## Restituisce un subtotale in un elenco o in un database +SUM = SOMMA ## Somma i suoi argomenti +SUMIF = SOMMA.SE ## Somma le celle specificate da un dato criterio +SUMIFS = SOMMA.PIÙ.SE ## Somma le celle in un intervallo che soddisfano più criteri +SUMPRODUCT = MATR.SOMMA.PRODOTTO ## Restituisce la somma dei prodotti dei componenti corrispondenti della matrice +SUMSQ = SOMMA.Q ## Restituisce la somma dei quadrati degli argomenti +SUMX2MY2 = SOMMA.DIFF.Q ## Restituisce la somma della differenza dei quadrati dei corrispondenti elementi in due matrici +SUMX2PY2 = SOMMA.SOMMA.Q ## Restituisce la somma della somma dei quadrati dei corrispondenti elementi in due matrici +SUMXMY2 = SOMMA.Q.DIFF ## Restituisce la somma dei quadrati delle differenze dei corrispondenti elementi in due matrici +TAN = TAN ## Restituisce la tangente di un numero +TANH = TANH ## Restituisce la tangente iperbolica di un numero +TRUNC = TRONCA ## Tronca la parte decimale di un numero + + +## +## Statistical functions Funzioni statistiche +## +AVEDEV = MEDIA.DEV ## Restituisce la media delle deviazioni assolute delle coordinate rispetto alla loro media +AVERAGE = MEDIA ## Restituisce la media degli argomenti +AVERAGEA = MEDIA.VALORI ## Restituisce la media degli argomenti, inclusi i numeri, il testo e i valori logici +AVERAGEIF = MEDIA.SE ## Restituisce la media aritmetica di tutte le celle in un intervallo che soddisfano un determinato criterio +AVERAGEIFS = MEDIA.PIÙ.SE ## Restituisce la media aritmetica di tutte le celle che soddisfano più criteri +BETADIST = DISTRIB.BETA ## Restituisce la funzione di distribuzione cumulativa beta +BETAINV = INV.BETA ## Restituisce l'inverso della funzione di distribuzione cumulativa per una distribuzione beta specificata +BINOMDIST = DISTRIB.BINOM ## Restituisce la distribuzione binomiale per il termine individuale +CHIDIST = DISTRIB.CHI ## Restituisce la probabilità a una coda per la distribuzione del chi quadrato +CHIINV = INV.CHI ## Restituisce l'inverso della probabilità ad una coda per la distribuzione del chi quadrato +CHITEST = TEST.CHI ## Restituisce il test per l'indipendenza +CONFIDENCE = CONFIDENZA ## Restituisce l'intervallo di confidenza per una popolazione +CORREL = CORRELAZIONE ## Restituisce il coefficiente di correlazione tra due insiemi di dati +COUNT = CONTA.NUMERI ## Conta la quantità di numeri nell'elenco di argomenti +COUNTA = CONTA.VALORI ## Conta il numero di valori nell'elenco di argomenti +COUNTBLANK = CONTA.VUOTE ## Conta il numero di celle vuote all'interno di un intervallo +COUNTIF = CONTA.SE ## Conta il numero di celle all'interno di un intervallo che soddisfa i criteri specificati +COUNTIFS = CONTA.PIÙ.SE ## Conta il numero di celle in un intervallo che soddisfano più criteri. +COVAR = COVARIANZA ## Calcola la covarianza, la media dei prodotti delle deviazioni accoppiate +CRITBINOM = CRIT.BINOM ## Restituisce il più piccolo valore per il quale la distribuzione cumulativa binomiale risulta maggiore o uguale ad un valore di criterio +DEVSQ = DEV.Q ## Restituisce la somma dei quadrati delle deviazioni +EXPONDIST = DISTRIB.EXP ## Restituisce la distribuzione esponenziale +FDIST = DISTRIB.F ## Restituisce la distribuzione di probabilità F +FINV = INV.F ## Restituisce l'inverso della distribuzione della probabilità F +FISHER = FISHER ## Restituisce la trasformazione di Fisher +FISHERINV = INV.FISHER ## Restituisce l'inverso della trasformazione di Fisher +FORECAST = PREVISIONE ## Restituisce i valori lungo una tendenza lineare +FREQUENCY = FREQUENZA ## Restituisce la distribuzione di frequenza come matrice verticale +FTEST = TEST.F ## Restituisce il risultato di un test F +GAMMADIST = DISTRIB.GAMMA ## Restituisce la distribuzione gamma +GAMMAINV = INV.GAMMA ## Restituisce l'inverso della distribuzione cumulativa gamma +GAMMALN = LN.GAMMA ## Restituisce il logaritmo naturale della funzione gamma, G(x) +GEOMEAN = MEDIA.GEOMETRICA ## Restituisce la media geometrica +GROWTH = CRESCITA ## Restituisce i valori lungo una linea di tendenza esponenziale +HARMEAN = MEDIA.ARMONICA ## Restituisce la media armonica +HYPGEOMDIST = DISTRIB.IPERGEOM ## Restituisce la distribuzione ipergeometrica +INTERCEPT = INTERCETTA ## Restituisce l'intercetta della retta di regressione lineare +KURT = CURTOSI ## Restituisce la curtosi di un insieme di dati +LARGE = GRANDE ## Restituisce il k-esimo valore più grande in un insieme di dati +LINEST = REGR.LIN ## Restituisce i parametri di una tendenza lineare +LOGEST = REGR.LOG ## Restituisce i parametri di una linea di tendenza esponenziale +LOGINV = INV.LOGNORM ## Restituisce l'inverso di una distribuzione lognormale +LOGNORMDIST = DISTRIB.LOGNORM ## Restituisce la distribuzione lognormale cumulativa +MAX = MAX ## Restituisce il valore massimo in un elenco di argomenti +MAXA = MAX.VALORI ## Restituisce il valore massimo in un elenco di argomenti, inclusi i numeri, il testo e i valori logici +MEDIAN = MEDIANA ## Restituisce la mediana dei numeri specificati +MIN = MIN ## Restituisce il valore minimo in un elenco di argomenti +MINA = MIN.VALORI ## Restituisce il più piccolo valore in un elenco di argomenti, inclusi i numeri, il testo e i valori logici +MODE = MODA ## Restituisce il valore più comune in un insieme di dati +NEGBINOMDIST = DISTRIB.BINOM.NEG ## Restituisce la distribuzione binomiale negativa +NORMDIST = DISTRIB.NORM ## Restituisce la distribuzione cumulativa normale +NORMINV = INV.NORM ## Restituisce l'inverso della distribuzione cumulativa normale standard +NORMSDIST = DISTRIB.NORM.ST ## Restituisce la distribuzione cumulativa normale standard +NORMSINV = INV.NORM.ST ## Restituisce l'inverso della distribuzione cumulativa normale +PEARSON = PEARSON ## Restituisce il coefficiente del momento di correlazione di Pearson +PERCENTILE = PERCENTILE ## Restituisce il k-esimo dato percentile di valori in un intervallo +PERCENTRANK = PERCENT.RANGO ## Restituisce il rango di un valore in un insieme di dati come percentuale +PERMUT = PERMUTAZIONE ## Restituisce il numero delle permutazioni per un determinato numero di oggetti +POISSON = POISSON ## Restituisce la distribuzione di Poisson +PROB = PROBABILITÀ ## Calcola la probabilità che dei valori in un intervallo siano compresi tra due limiti +QUARTILE = QUARTILE ## Restituisce il quartile di un insieme di dati +RANK = RANGO ## Restituisce il rango di un numero in un elenco di numeri +RSQ = RQ ## Restituisce la radice quadrata del coefficiente di momento di correlazione di Pearson +SKEW = ASIMMETRIA ## Restituisce il grado di asimmetria di una distribuzione +SLOPE = PENDENZA ## Restituisce la pendenza di una retta di regressione lineare +SMALL = PICCOLO ## Restituisce il k-esimo valore più piccolo in un insieme di dati +STANDARDIZE = NORMALIZZA ## Restituisce un valore normalizzato +STDEV = DEV.ST ## Restituisce una stima della deviazione standard sulla base di un campione +STDEVA = DEV.ST.VALORI ## Restituisce una stima della deviazione standard sulla base di un campione, inclusi i numeri, il testo e i valori logici +STDEVP = DEV.ST.POP ## Calcola la deviazione standard sulla base di un'intera popolazione +STDEVPA = DEV.ST.POP.VALORI ## Calcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici +STEYX = ERR.STD.YX ## Restituisce l'errore standard del valore previsto per y per ogni valore x nella regressione +TDIST = DISTRIB.T ## Restituisce la distribuzione t di Student +TINV = INV.T ## Restituisce l'inversa della distribuzione t di Student +TREND = TENDENZA ## Restituisce i valori lungo una linea di tendenza lineare +TRIMMEAN = MEDIA.TRONCATA ## Restituisce la media della parte interna di un insieme di dati +TTEST = TEST.T ## Restituisce la probabilità associata ad un test t di Student +VAR = VAR ## Stima la varianza sulla base di un campione +VARA = VAR.VALORI ## Stima la varianza sulla base di un campione, inclusi i numeri, il testo e i valori logici +VARP = VAR.POP ## Calcola la varianza sulla base dell'intera popolazione +VARPA = VAR.POP.VALORI ## Calcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici +WEIBULL = WEIBULL ## Restituisce la distribuzione di Weibull +ZTEST = TEST.Z ## Restituisce il valore di probabilità a una coda per un test z + + +## +## Text functions Funzioni di testo +## +ASC = ASC ## Modifica le lettere inglesi o il katakana a doppio byte all'interno di una stringa di caratteri in caratteri a singolo byte +BAHTTEXT = BAHTTESTO ## Converte un numero in testo, utilizzando il formato valuta ß (baht) +CHAR = CODICE.CARATT ## Restituisce il carattere specificato dal numero di codice +CLEAN = LIBERA ## Elimina dal testo tutti i caratteri che non è possibile stampare +CODE = CODICE ## Restituisce il codice numerico del primo carattere di una stringa di testo +CONCATENATE = CONCATENA ## Unisce diversi elementi di testo in un unico elemento di testo +DOLLAR = VALUTA ## Converte un numero in testo, utilizzando il formato valuta € (euro) +EXACT = IDENTICO ## Verifica se due valori di testo sono uguali +FIND = TROVA ## Rileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole) +FINDB = TROVA.B ## Rileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole) +FIXED = FISSO ## Formatta un numero come testo con un numero fisso di decimali +JIS = ORDINAMENTO.JIS ## Modifica le lettere inglesi o i caratteri katakana a byte singolo all'interno di una stringa di caratteri in caratteri a byte doppio. +LEFT = SINISTRA ## Restituisce il carattere più a sinistra di un valore di testo +LEFTB = SINISTRA.B ## Restituisce il carattere più a sinistra di un valore di testo +LEN = LUNGHEZZA ## Restituisce il numero di caratteri di una stringa di testo +LENB = LUNB ## Restituisce il numero di caratteri di una stringa di testo +LOWER = MINUSC ## Converte il testo in lettere minuscole +MID = MEDIA ## Restituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata +MIDB = MEDIA.B ## Restituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata +PHONETIC = FURIGANA ## Estrae i caratteri fonetici (furigana) da una stringa di testo. +PROPER = MAIUSC.INIZ ## Converte in maiuscolo la prima lettera di ogni parola di un valore di testo +REPLACE = RIMPIAZZA ## Sostituisce i caratteri all'interno di un testo +REPLACEB = SOSTITUISCI.B ## Sostituisce i caratteri all'interno di un testo +REPT = RIPETI ## Ripete un testo per un dato numero di volte +RIGHT = DESTRA ## Restituisce il carattere più a destra di un valore di testo +RIGHTB = DESTRA.B ## Restituisce il carattere più a destra di un valore di testo +SEARCH = RICERCA ## Rileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole) +SEARCHB = CERCA.B ## Rileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole) +SUBSTITUTE = SOSTITUISCI ## Sostituisce il nuovo testo al testo contenuto in una stringa +T = T ## Converte gli argomenti in testo +TEXT = TESTO ## Formatta un numero e lo converte in testo +TRIM = ANNULLA.SPAZI ## Elimina gli spazi dal testo +UPPER = MAIUSC ## Converte il testo in lettere maiuscole +VALUE = VALORE ## Converte un argomento di testo in numero diff --git a/extend/phpexcel/PHPExcel/locale/nl/config b/extend/phpexcel/PHPExcel/locale/nl/config new file mode 100755 index 0000000..00c1b0f --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/nl/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #LEEG! +DIV0 = #DEEL/0! +VALUE = #WAARDE! +REF = #VERW! +NAME = #NAAM? +NUM = #GETAL! +NA = #N/B diff --git a/extend/phpexcel/PHPExcel/locale/nl/functions b/extend/phpexcel/PHPExcel/locale/nl/functions new file mode 100755 index 0000000..6380008 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/nl/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Automatiseringsfuncties en functies in invoegtoepassingen +## +GETPIVOTDATA = DRAAITABEL.OPHALEN ## Geeft gegevens uit een draaitabelrapport als resultaat + + +## +## Cube functions Kubusfuncties +## +CUBEKPIMEMBER = KUBUSKPILID ## Retourneert de naam, eigenschap en waarde van een KPI (prestatie-indicator) en geeft de naam en de eigenschap in de cel weer. Een KPI is een meetbare waarde, zoals de maandelijkse brutowinst of de omzet per kwartaal per werknemer, die wordt gebruikt om de prestaties van een organisatie te bewaken +CUBEMEMBER = KUBUSLID ## Retourneert een lid of tupel in een kubushiërarchie. Wordt gebruikt om te controleren of het lid of de tupel in de kubus aanwezig is +CUBEMEMBERPROPERTY = KUBUSLIDEIGENSCHAP ## Retourneert de waarde van een lideigenschap in de kubus. Wordt gebruikt om te controleren of de lidnaam in de kubus bestaat en retourneert de opgegeven eigenschap voor dit lid +CUBERANKEDMEMBER = KUBUSGERANGCHIKTLID ## Retourneert het zoveelste, gerangschikte lid in een set. Wordt gebruikt om een of meer elementen in een set te retourneren, zoals de tien beste verkopers of de tien beste studenten +CUBESET = KUBUSSET ## Definieert een berekende set leden of tupels door een ingestelde expressie naar de kubus op de server te sturen, alwaar de set wordt gemaakt en vervolgens wordt geretourneerd naar Microsoft Office Excel +CUBESETCOUNT = KUBUSSETAANTAL ## Retourneert het aantal onderdelen in een set +CUBEVALUE = KUBUSWAARDE ## Retourneert een samengestelde waarde van een kubus + + +## +## Database functions Databasefuncties +## +DAVERAGE = DBGEMIDDELDE ## Berekent de gemiddelde waarde in geselecteerde databasegegevens +DCOUNT = DBAANTAL ## Telt de cellen met getallen in een database +DCOUNTA = DBAANTALC ## Telt de niet-lege cellen in een database +DGET = DBLEZEN ## Retourneert één record dat voldoet aan de opgegeven criteria uit een database +DMAX = DBMAX ## Retourneert de maximumwaarde in de geselecteerde databasegegevens +DMIN = DBMIN ## Retourneert de minimumwaarde in de geselecteerde databasegegevens +DPRODUCT = DBPRODUCT ## Vermenigvuldigt de waarden in een bepaald veld van de records die voldoen aan de criteria in een database +DSTDEV = DBSTDEV ## Maakt een schatting van de standaarddeviatie op basis van een steekproef uit geselecteerde databasegegevens +DSTDEVP = DBSTDEVP ## Berekent de standaarddeviatie op basis van de volledige populatie van geselecteerde databasegegevens +DSUM = DBSOM ## Telt de getallen uit een kolom records in de database op die voldoen aan de criteria +DVAR = DBVAR ## Maakt een schatting van de variantie op basis van een steekproef uit geselecteerde databasegegevens +DVARP = DBVARP ## Berekent de variantie op basis van de volledige populatie van geselecteerde databasegegevens + + +## +## Date and time functions Datum- en tijdfuncties +## +DATE = DATUM ## Geeft als resultaat het seriële getal van een opgegeven datum +DATEVALUE = DATUMWAARDE ## Converteert een datum in de vorm van tekst naar een serieel getal +DAY = DAG ## Converteert een serieel getal naar een dag van de maand +DAYS360 = DAGEN360 ## Berekent het aantal dagen tussen twee datums op basis van een jaar met 360 dagen +EDATE = ZELFDE.DAG ## Geeft als resultaat het seriële getal van een datum die het opgegeven aantal maanden voor of na de begindatum ligt +EOMONTH = LAATSTE.DAG ## Geeft als resultaat het seriële getal van de laatste dag van de maand voor of na het opgegeven aantal maanden +HOUR = UUR ## Converteert een serieel getal naar uren +MINUTE = MINUUT ## Converteert een serieel naar getal minuten +MONTH = MAAND ## Converteert een serieel getal naar een maand +NETWORKDAYS = NETTO.WERKDAGEN ## Geeft als resultaat het aantal hele werkdagen tussen twee datums +NOW = NU ## Geeft als resultaat het seriële getal van de huidige datum en tijd +SECOND = SECONDE ## Converteert een serieel getal naar seconden +TIME = TIJD ## Geeft als resultaat het seriële getal van een bepaald tijdstip +TIMEVALUE = TIJDWAARDE ## Converteert de tijd in de vorm van tekst naar een serieel getal +TODAY = VANDAAG ## Geeft als resultaat het seriële getal van de huidige datum +WEEKDAY = WEEKDAG ## Converteert een serieel getal naar een weekdag +WEEKNUM = WEEKNUMMER ## Converteert een serieel getal naar een weeknummer +WORKDAY = WERKDAG ## Geeft als resultaat het seriële getal van de datum voor of na een bepaald aantal werkdagen +YEAR = JAAR ## Converteert een serieel getal naar een jaar +YEARFRAC = JAAR.DEEL ## Geeft als resultaat het gedeelte van het jaar, uitgedrukt in het aantal hele dagen tussen begindatum en einddatum + + +## +## Engineering functions Technische functies +## +BESSELI = BESSEL.Y ## Geeft als resultaat de gewijzigde Bessel-functie In(x) +BESSELJ = BESSEL.J ## Geeft als resultaat de Bessel-functie Jn(x) +BESSELK = BESSEL.K ## Geeft als resultaat de gewijzigde Bessel-functie Kn(x) +BESSELY = BESSEL.Y ## Geeft als resultaat de gewijzigde Bessel-functie Yn(x) +BIN2DEC = BIN.N.DEC ## Converteert een binair getal naar een decimaal getal +BIN2HEX = BIN.N.HEX ## Converteert een binair getal naar een hexadecimaal getal +BIN2OCT = BIN.N.OCT ## Converteert een binair getal naar een octaal getal +COMPLEX = COMPLEX ## Converteert reële en imaginaire coëfficiënten naar een complex getal +CONVERT = CONVERTEREN ## Converteert een getal in de ene maateenheid naar een getal in een andere maateenheid +DEC2BIN = DEC.N.BIN ## Converteert een decimaal getal naar een binair getal +DEC2HEX = DEC.N.HEX ## Converteert een decimaal getal naar een hexadecimaal getal +DEC2OCT = DEC.N.OCT ## Converteert een decimaal getal naar een octaal getal +DELTA = DELTA ## Test of twee waarden gelijk zijn +ERF = FOUTFUNCTIE ## Geeft als resultaat de foutfunctie +ERFC = FOUT.COMPLEMENT ## Geeft als resultaat de complementaire foutfunctie +GESTEP = GROTER.DAN ## Test of een getal groter is dan de drempelwaarde +HEX2BIN = HEX.N.BIN ## Converteert een hexadecimaal getal naar een binair getal +HEX2DEC = HEX.N.DEC ## Converteert een hexadecimaal getal naar een decimaal getal +HEX2OCT = HEX.N.OCT ## Converteert een hexadecimaal getal naar een octaal getal +IMABS = C.ABS ## Geeft als resultaat de absolute waarde (modulus) van een complex getal +IMAGINARY = C.IM.DEEL ## Geeft als resultaat de imaginaire coëfficiënt van een complex getal +IMARGUMENT = C.ARGUMENT ## Geeft als resultaat het argument thèta, een hoek uitgedrukt in radialen +IMCONJUGATE = C.TOEGEVOEGD ## Geeft als resultaat het complexe toegevoegde getal van een complex getal +IMCOS = C.COS ## Geeft als resultaat de cosinus van een complex getal +IMDIV = C.QUOTIENT ## Geeft als resultaat het quotiënt van twee complexe getallen +IMEXP = C.EXP ## Geeft als resultaat de exponent van een complex getal +IMLN = C.LN ## Geeft als resultaat de natuurlijke logaritme van een complex getal +IMLOG10 = C.LOG10 ## Geeft als resultaat de logaritme met grondtal 10 van een complex getal +IMLOG2 = C.LOG2 ## Geeft als resultaat de logaritme met grondtal 2 van een complex getal +IMPOWER = C.MACHT ## Geeft als resultaat een complex getal dat is verheven tot de macht van een geheel getal +IMPRODUCT = C.PRODUCT ## Geeft als resultaat het product van complexe getallen +IMREAL = C.REEEL.DEEL ## Geeft als resultaat de reële coëfficiënt van een complex getal +IMSIN = C.SIN ## Geeft als resultaat de sinus van een complex getal +IMSQRT = C.WORTEL ## Geeft als resultaat de vierkantswortel van een complex getal +IMSUB = C.VERSCHIL ## Geeft als resultaat het verschil tussen twee complexe getallen +IMSUM = C.SOM ## Geeft als resultaat de som van complexe getallen +OCT2BIN = OCT.N.BIN ## Converteert een octaal getal naar een binair getal +OCT2DEC = OCT.N.DEC ## Converteert een octaal getal naar een decimaal getal +OCT2HEX = OCT.N.HEX ## Converteert een octaal getal naar een hexadecimaal getal + + +## +## Financial functions Financiële functies +## +ACCRINT = SAMENG.RENTE ## Berekent de opgelopen rente voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +ACCRINTM = SAMENG.RENTE.V ## Berekent de opgelopen rente voor een waardepapier waarvan de rente op de vervaldatum wordt uitgekeerd +AMORDEGRC = AMORDEGRC ## Geeft als resultaat de afschrijving voor elke boekingsperiode door een afschrijvingscoëfficiënt toe te passen +AMORLINC = AMORLINC ## Berekent de afschrijving voor elke boekingsperiode +COUPDAYBS = COUP.DAGEN.BB ## Berekent het aantal dagen vanaf het begin van de coupontermijn tot de stortingsdatum +COUPDAYS = COUP.DAGEN ## Geeft als resultaat het aantal dagen in de coupontermijn waarin de stortingsdatum valt +COUPDAYSNC = COUP.DAGEN.VV ## Geeft als resultaat het aantal dagen vanaf de stortingsdatum tot de volgende couponvervaldatum +COUPNCD = COUP.DATUM.NB ## Geeft als resultaat de volgende coupondatum na de stortingsdatum +COUPNUM = COUP.AANTAL ## Geeft als resultaat het aantal coupons dat nog moet worden uitbetaald tussen de stortingsdatum en de vervaldatum +COUPPCD = COUP.DATUM.VB ## Geeft als resultaat de vorige couponvervaldatum vóór de stortingsdatum +CUMIPMT = CUM.RENTE ## Geeft als resultaat de cumulatieve rente die tussen twee termijnen is uitgekeerd +CUMPRINC = CUM.HOOFDSOM ## Geeft als resultaat de cumulatieve hoofdsom van een lening die tussen twee termijnen is terugbetaald +DB = DB ## Geeft als resultaat de afschrijving van activa voor een bepaalde periode met behulp van de 'fixed declining balance'-methode +DDB = DDB ## Geeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'double declining balance'-methode of een andere methode die u opgeeft +DISC = DISCONTO ## Geeft als resultaat het discontopercentage voor een waardepapier +DOLLARDE = EURO.DE ## Converteert een prijs in euro's, uitgedrukt in een breuk, naar een prijs in euro's, uitgedrukt in een decimaal getal +DOLLARFR = EURO.BR ## Converteert een prijs in euro's, uitgedrukt in een decimaal getal, naar een prijs in euro's, uitgedrukt in een breuk +DURATION = DUUR ## Geeft als resultaat de gewogen gemiddelde looptijd voor een waardepapier met periodieke rentebetalingen +EFFECT = EFFECT.RENTE ## Geeft als resultaat het effectieve jaarlijkse rentepercentage +FV = TW ## Geeft als resultaat de toekomstige waarde van een investering +FVSCHEDULE = TOEK.WAARDE2 ## Geeft als resultaat de toekomstige waarde van een bepaalde hoofdsom na het toepassen van een reeks samengestelde rentepercentages +INTRATE = RENTEPERCENTAGE ## Geeft als resultaat het rentepercentage voor een volgestort waardepapier +IPMT = IBET ## Geeft als resultaat de te betalen rente voor een investering over een bepaalde termijn +IRR = IR ## Geeft als resultaat de interne rentabiliteit voor een reeks cashflows +ISPMT = ISBET ## Geeft als resultaat de rente die is betaald tijdens een bepaalde termijn van een investering +MDURATION = AANG.DUUR ## Geeft als resultaat de aangepaste Macauley-looptijd voor een waardepapier, aangenomen dat de nominale waarde € 100 bedraagt +MIRR = GIR ## Geeft als resultaat de interne rentabiliteit voor een serie cashflows, waarbij voor betalingen een ander rentepercentage geldt dan voor inkomsten +NOMINAL = NOMINALE.RENTE ## Geeft als resultaat het nominale jaarlijkse rentepercentage +NPER = NPER ## Geeft als resultaat het aantal termijnen van een investering +NPV = NHW ## Geeft als resultaat de netto huidige waarde van een investering op basis van een reeks periodieke cashflows en een discontopercentage +ODDFPRICE = AFW.ET.PRIJS ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende eerste termijn +ODDFYIELD = AFW.ET.REND ## Geeft als resultaat het rendement voor een waardepapier met een afwijkende eerste termijn +ODDLPRICE = AFW.LT.PRIJS ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende laatste termijn +ODDLYIELD = AFW.LT.REND ## Geeft als resultaat het rendement voor een waardepapier met een afwijkende laatste termijn +PMT = BET ## Geeft als resultaat de periodieke betaling voor een annuïteit +PPMT = PBET ## Geeft als resultaat de afbetaling op de hoofdsom voor een bepaalde termijn +PRICE = PRIJS.NOM ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +PRICEDISC = PRIJS.DISCONTO ## Geeft als resultaat de prijs per € 100 nominale waarde voor een verdisconteerd waardepapier +PRICEMAT = PRIJS.VERVALDAG ## Geeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum +PV = HW ## Geeft als resultaat de huidige waarde van een investering +RATE = RENTE ## Geeft als resultaat het periodieke rentepercentage voor een annuïteit +RECEIVED = OPBRENGST ## Geeft als resultaat het bedrag dat op de vervaldatum wordt uitgekeerd voor een volgestort waardepapier +SLN = LIN.AFSCHR ## Geeft als resultaat de lineaire afschrijving van activa over één termijn +SYD = SYD ## Geeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'Sum-Of-Years-Digits'-methode +TBILLEQ = SCHATK.OBL ## Geeft als resultaat het rendement op schatkistpapier, dat op dezelfde manier wordt berekend als het rendement op obligaties +TBILLPRICE = SCHATK.PRIJS ## Bepaalt de prijs per € 100 nominale waarde voor schatkistpapier +TBILLYIELD = SCHATK.REND ## Berekent het rendement voor schatkistpapier +VDB = VDB ## Geeft als resultaat de afschrijving van activa over een gehele of gedeeltelijke termijn met behulp van de 'declining balance'-methode +XIRR = IR.SCHEMA ## Berekent de interne rentabiliteit voor een betalingsschema van cashflows +XNPV = NHW2 ## Berekent de huidige nettowaarde voor een betalingsschema van cashflows +YIELD = RENDEMENT ## Geeft als resultaat het rendement voor een waardepapier waarvan de rente periodiek wordt uitgekeerd +YIELDDISC = REND.DISCONTO ## Geeft als resultaat het jaarlijkse rendement voor een verdisconteerd waardepapier, bijvoorbeeld schatkistpapier +YIELDMAT = REND.VERVAL ## Geeft als resultaat het jaarlijkse rendement voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum + + +## +## Information functions Informatiefuncties +## +CELL = CEL ## Geeft als resultaat informatie over de opmaak, locatie of inhoud van een cel +ERROR.TYPE = TYPE.FOUT ## Geeft als resultaat een getal dat overeenkomt met een van de foutwaarden van Microsoft Excel +INFO = INFO ## Geeft als resultaat informatie over de huidige besturingsomgeving +ISBLANK = ISLEEG ## Geeft als resultaat WAAR als de waarde leeg is +ISERR = ISFOUT2 ## Geeft als resultaat WAAR als de waarde een foutwaarde is, met uitzondering van #N/B +ISERROR = ISFOUT ## Geeft als resultaat WAAR als de waarde een foutwaarde is +ISEVEN = IS.EVEN ## Geeft als resultaat WAAR als het getal even is +ISLOGICAL = ISLOGISCH ## Geeft als resultaat WAAR als de waarde een logische waarde is +ISNA = ISNB ## Geeft als resultaat WAAR als de waarde de foutwaarde #N/B is +ISNONTEXT = ISGEENTEKST ## Geeft als resultaat WAAR als de waarde geen tekst is +ISNUMBER = ISGETAL ## Geeft als resultaat WAAR als de waarde een getal is +ISODD = IS.ONEVEN ## Geeft als resultaat WAAR als het getal oneven is +ISREF = ISVERWIJZING ## Geeft als resultaat WAAR als de waarde een verwijzing is +ISTEXT = ISTEKST ## Geeft als resultaat WAAR als de waarde tekst is +N = N ## Geeft als resultaat een waarde die is geconverteerd naar een getal +NA = NB ## Geeft als resultaat de foutwaarde #N/B +TYPE = TYPE ## Geeft als resultaat een getal dat het gegevenstype van een waarde aangeeft + + +## +## Logical functions Logische functies +## +AND = EN ## Geeft als resultaat WAAR als alle argumenten WAAR zijn +FALSE = ONWAAR ## Geeft als resultaat de logische waarde ONWAAR +IF = ALS ## Geeft een logische test aan +IFERROR = ALS.FOUT ## Retourneert een waarde die u opgeeft als een formule een fout oplevert, anders wordt het resultaat van de formule geretourneerd +NOT = NIET ## Keert de logische waarde van het argument om +OR = OF ## Geeft als resultaat WAAR als minimaal een van de argumenten WAAR is +TRUE = WAAR ## Geeft als resultaat de logische waarde WAAR + + +## +## Lookup and reference functions Zoek- en verwijzingsfuncties +## +ADDRESS = ADRES ## Geeft als resultaat een verwijzing, in de vorm van tekst, naar één bepaalde cel in een werkblad +AREAS = BEREIKEN ## Geeft als resultaat het aantal bereiken in een verwijzing +CHOOSE = KIEZEN ## Kiest een waarde uit een lijst met waarden +COLUMN = KOLOM ## Geeft als resultaat het kolomnummer van een verwijzing +COLUMNS = KOLOMMEN ## Geeft als resultaat het aantal kolommen in een verwijzing +HLOOKUP = HORIZ.ZOEKEN ## Zoekt in de bovenste rij van een matrix naar een bepaalde waarde en geeft als resultaat de gevonden waarde in de opgegeven cel +HYPERLINK = HYPERLINK ## Maakt een snelkoppeling of een sprong waarmee een document wordt geopend dat is opgeslagen op een netwerkserver, een intranet of op internet +INDEX = INDEX ## Kiest met een index een waarde uit een verwijzing of een matrix +INDIRECT = INDIRECT ## Geeft als resultaat een verwijzing die wordt aangegeven met een tekstwaarde +LOOKUP = ZOEKEN ## Zoekt naar bepaalde waarden in een vector of een matrix +MATCH = VERGELIJKEN ## Zoekt naar bepaalde waarden in een verwijzing of een matrix +OFFSET = VERSCHUIVING ## Geeft als resultaat een nieuwe verwijzing die is verschoven ten opzichte van een bepaalde verwijzing +ROW = RIJ ## Geeft als resultaat het rijnummer van een verwijzing +ROWS = RIJEN ## Geeft als resultaat het aantal rijen in een verwijzing +RTD = RTG ## Haalt realtimegegevens op uit een programma dat COM-automatisering (automatisering: een methode waarmee de ene toepassing objecten van een andere toepassing of ontwikkelprogramma kan besturen. Automatisering werd vroeger OLE-automatisering genoemd. Automatisering is een industrienorm die deel uitmaakt van het Component Object Model (COM).) ondersteunt +TRANSPOSE = TRANSPONEREN ## Geeft als resultaat de getransponeerde van een matrix +VLOOKUP = VERT.ZOEKEN ## Zoekt in de meest linkse kolom van een matrix naar een bepaalde waarde en geeft als resultaat de waarde in de opgegeven cel + + +## +## Math and trigonometry functions Wiskundige en trigonometrische functies +## +ABS = ABS ## Geeft als resultaat de absolute waarde van een getal +ACOS = BOOGCOS ## Geeft als resultaat de boogcosinus van een getal +ACOSH = BOOGCOSH ## Geeft als resultaat de inverse cosinus hyperbolicus van een getal +ASIN = BOOGSIN ## Geeft als resultaat de boogsinus van een getal +ASINH = BOOGSINH ## Geeft als resultaat de inverse sinus hyperbolicus van een getal +ATAN = BOOGTAN ## Geeft als resultaat de boogtangens van een getal +ATAN2 = BOOGTAN2 ## Geeft als resultaat de boogtangens van de x- en y-coördinaten +ATANH = BOOGTANH ## Geeft als resultaat de inverse tangens hyperbolicus van een getal +CEILING = AFRONDEN.BOVEN ## Rondt de absolute waarde van een getal naar boven af op het dichtstbijzijnde gehele getal of het dichtstbijzijnde significante veelvoud +COMBIN = COMBINATIES ## Geeft als resultaat het aantal combinaties voor een bepaald aantal objecten +COS = COS ## Geeft als resultaat de cosinus van een getal +COSH = COSH ## Geeft als resultaat de cosinus hyperbolicus van een getal +DEGREES = GRADEN ## Converteert radialen naar graden +EVEN = EVEN ## Rondt het getal af op het dichtstbijzijnde gehele even getal +EXP = EXP ## Verheft e tot de macht van een bepaald getal +FACT = FACULTEIT ## Geeft als resultaat de faculteit van een getal +FACTDOUBLE = DUBBELE.FACULTEIT ## Geeft als resultaat de dubbele faculteit van een getal +FLOOR = AFRONDEN.BENEDEN ## Rondt de absolute waarde van een getal naar beneden af +GCD = GGD ## Geeft als resultaat de grootste gemene deler +INT = INTEGER ## Rondt een getal naar beneden af op het dichtstbijzijnde gehele getal +LCM = KGV ## Geeft als resultaat het kleinste gemene veelvoud +LN = LN ## Geeft als resultaat de natuurlijke logaritme van een getal +LOG = LOG ## Geeft als resultaat de logaritme met het opgegeven grondtal van een getal +LOG10 = LOG10 ## Geeft als resultaat de logaritme met grondtal 10 van een getal +MDETERM = DETERMINANTMAT ## Geeft als resultaat de determinant van een matrix +MINVERSE = INVERSEMAT ## Geeft als resultaat de inverse van een matrix +MMULT = PRODUCTMAT ## Geeft als resultaat het product van twee matrices +MOD = REST ## Geeft als resultaat het restgetal van een deling +MROUND = AFRONDEN.N.VEELVOUD ## Geeft als resultaat een getal afgerond op het gewenste veelvoud +MULTINOMIAL = MULTINOMIAAL ## Geeft als resultaat de multinomiaalcoëfficiënt van een reeks getallen +ODD = ONEVEN ## Rondt de absolute waarde van het getal naar boven af op het dichtstbijzijnde gehele oneven getal +PI = PI ## Geeft als resultaat de waarde van pi +POWER = MACHT ## Verheft een getal tot een macht +PRODUCT = PRODUCT ## Vermenigvuldigt de argumenten met elkaar +QUOTIENT = QUOTIENT ## Geeft als resultaat de uitkomst van een deling als geheel getal +RADIANS = RADIALEN ## Converteert graden naar radialen +RAND = ASELECT ## Geeft als resultaat een willekeurig getal tussen 0 en 1 +RANDBETWEEN = ASELECTTUSSEN ## Geeft een willekeurig getal tussen de getallen die u hebt opgegeven +ROMAN = ROMEINS ## Converteert een Arabisch getal naar een Romeins getal en geeft het resultaat weer in de vorm van tekst +ROUND = AFRONDEN ## Rondt een getal af op het opgegeven aantal decimalen +ROUNDDOWN = AFRONDEN.NAAR.BENEDEN ## Rondt de absolute waarde van een getal naar beneden af +ROUNDUP = AFRONDEN.NAAR.BOVEN ## Rondt de absolute waarde van een getal naar boven af +SERIESSUM = SOM.MACHTREEKS ## Geeft als resultaat de som van een machtreeks die is gebaseerd op de formule +SIGN = POS.NEG ## Geeft als resultaat het teken van een getal +SIN = SIN ## Geeft als resultaat de sinus van de opgegeven hoek +SINH = SINH ## Geeft als resultaat de sinus hyperbolicus van een getal +SQRT = WORTEL ## Geeft als resultaat de positieve vierkantswortel van een getal +SQRTPI = WORTEL.PI ## Geeft als resultaat de vierkantswortel van (getal * pi) +SUBTOTAL = SUBTOTAAL ## Geeft als resultaat een subtotaal voor een bereik +SUM = SOM ## Telt de argumenten op +SUMIF = SOM.ALS ## Telt de getallen bij elkaar op die voldoen aan een bepaald criterium +SUMIFS = SOMMEN.ALS ## Telt de cellen in een bereik op die aan meerdere criteria voldoen +SUMPRODUCT = SOMPRODUCT ## Geeft als resultaat de som van de producten van de corresponderende matrixelementen +SUMSQ = KWADRATENSOM ## Geeft als resultaat de som van de kwadraten van de argumenten +SUMX2MY2 = SOM.X2MINY2 ## Geeft als resultaat de som van het verschil tussen de kwadraten van corresponderende waarden in twee matrices +SUMX2PY2 = SOM.X2PLUSY2 ## Geeft als resultaat de som van de kwadratensom van corresponderende waarden in twee matrices +SUMXMY2 = SOM.XMINY.2 ## Geeft als resultaat de som van de kwadraten van de verschillen tussen de corresponderende waarden in twee matrices +TAN = TAN ## Geeft als resultaat de tangens van een getal +TANH = TANH ## Geeft als resultaat de tangens hyperbolicus van een getal +TRUNC = GEHEEL ## Kapt een getal af tot een geheel getal + + +## +## Statistical functions Statistische functies +## +AVEDEV = GEM.DEVIATIE ## Geeft als resultaat het gemiddelde van de absolute deviaties van gegevenspunten ten opzichte van hun gemiddelde waarde +AVERAGE = GEMIDDELDE ## Geeft als resultaat het gemiddelde van de argumenten +AVERAGEA = GEMIDDELDEA ## Geeft als resultaat het gemiddelde van de argumenten, inclusief getallen, tekst en logische waarden +AVERAGEIF = GEMIDDELDE.ALS ## Geeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen in een bereik die voldoen aan de opgegeven criteria +AVERAGEIFS = GEMIDDELDEN.ALS ## Geeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen die aan meerdere criteria voldoen +BETADIST = BETA.VERD ## Geeft als resultaat de cumulatieve bèta-verdelingsfunctie +BETAINV = BETA.INV ## Geeft als resultaat de inverse van de cumulatieve verdelingsfunctie voor een gegeven bèta-verdeling +BINOMDIST = BINOMIALE.VERD ## Geeft als resultaat de binomiale verdeling +CHIDIST = CHI.KWADRAAT ## Geeft als resultaat de eenzijdige kans van de chi-kwadraatverdeling +CHIINV = CHI.KWADRAAT.INV ## Geeft als resultaat de inverse van een eenzijdige kans van de chi-kwadraatverdeling +CHITEST = CHI.TOETS ## Geeft als resultaat de onafhankelijkheidstoets +CONFIDENCE = BETROUWBAARHEID ## Geeft als resultaat het betrouwbaarheidsinterval van een gemiddelde waarde voor de elementen van een populatie +CORREL = CORRELATIE ## Geeft als resultaat de correlatiecoëfficiënt van twee gegevensverzamelingen +COUNT = AANTAL ## Telt het aantal getallen in de argumentenlijst +COUNTA = AANTALARG ## Telt het aantal waarden in de argumentenlijst +COUNTBLANK = AANTAL.LEGE.CELLEN ## Telt het aantal lege cellen in een bereik +COUNTIF = AANTAL.ALS ## Telt in een bereik het aantal cellen die voldoen aan een bepaald criterium +COUNTIFS = AANTALLEN.ALS ## Telt in een bereik het aantal cellen die voldoen aan meerdere criteria +COVAR = COVARIANTIE ## Geeft als resultaat de covariantie, het gemiddelde van de producten van de gepaarde deviaties +CRITBINOM = CRIT.BINOM ## Geeft als resultaat de kleinste waarde waarvoor de binomiale verdeling kleiner is dan of gelijk is aan het criterium +DEVSQ = DEV.KWAD ## Geeft als resultaat de som van de deviaties in het kwadraat +EXPONDIST = EXPON.VERD ## Geeft als resultaat de exponentiële verdeling +FDIST = F.VERDELING ## Geeft als resultaat de F-verdeling +FINV = F.INVERSE ## Geeft als resultaat de inverse van de F-verdeling +FISHER = FISHER ## Geeft als resultaat de Fisher-transformatie +FISHERINV = FISHER.INV ## Geeft als resultaat de inverse van de Fisher-transformatie +FORECAST = VOORSPELLEN ## Geeft als resultaat een waarde op basis van een lineaire trend +FREQUENCY = FREQUENTIE ## Geeft als resultaat een frequentieverdeling in de vorm van een verticale matrix +FTEST = F.TOETS ## Geeft als resultaat een F-toets +GAMMADIST = GAMMA.VERD ## Geeft als resultaat de gamma-verdeling +GAMMAINV = GAMMA.INV ## Geeft als resultaat de inverse van de cumulatieve gamma-verdeling +GAMMALN = GAMMA.LN ## Geeft als resultaat de natuurlijke logaritme van de gamma-functie, G(x) +GEOMEAN = MEETK.GEM ## Geeft als resultaat het meetkundige gemiddelde +GROWTH = GROEI ## Geeft als resultaat de waarden voor een exponentiële trend +HARMEAN = HARM.GEM ## Geeft als resultaat het harmonische gemiddelde +HYPGEOMDIST = HYPERGEO.VERD ## Geeft als resultaat de hypergeometrische verdeling +INTERCEPT = SNIJPUNT ## Geeft als resultaat het snijpunt van de lineaire regressielijn met de y-as +KURT = KURTOSIS ## Geeft als resultaat de kurtosis van een gegevensverzameling +LARGE = GROOTSTE ## Geeft als resultaat de op k-1 na grootste waarde in een gegevensverzameling +LINEST = LIJNSCH ## Geeft als resultaat de parameters van een lineaire trend +LOGEST = LOGSCH ## Geeft als resultaat de parameters van een exponentiële trend +LOGINV = LOG.NORM.INV ## Geeft als resultaat de inverse van de logaritmische normale verdeling +LOGNORMDIST = LOG.NORM.VERD ## Geeft als resultaat de cumulatieve logaritmische normale verdeling +MAX = MAX ## Geeft als resultaat de maximumwaarde in een lijst met argumenten +MAXA = MAXA ## Geeft als resultaat de maximumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden +MEDIAN = MEDIAAN ## Geeft als resultaat de mediaan van de opgegeven getallen +MIN = MIN ## Geeft als resultaat de minimumwaarde in een lijst met argumenten +MINA = MINA ## Geeft als resultaat de minimumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden +MODE = MODUS ## Geeft als resultaat de meest voorkomende waarde in een gegevensverzameling +NEGBINOMDIST = NEG.BINOM.VERD ## Geeft als resultaat de negatieve binomiaalverdeling +NORMDIST = NORM.VERD ## Geeft als resultaat de cumulatieve normale verdeling +NORMINV = NORM.INV ## Geeft als resultaat de inverse van de cumulatieve standaardnormale verdeling +NORMSDIST = STAND.NORM.VERD ## Geeft als resultaat de cumulatieve standaardnormale verdeling +NORMSINV = STAND.NORM.INV ## Geeft als resultaat de inverse van de cumulatieve normale verdeling +PEARSON = PEARSON ## Geeft als resultaat de correlatiecoëfficiënt van Pearson +PERCENTILE = PERCENTIEL ## Geeft als resultaat het k-de percentiel van waarden in een bereik +PERCENTRANK = PERCENT.RANG ## Geeft als resultaat de positie, in procenten uitgedrukt, van een waarde in de rangorde van een gegevensverzameling +PERMUT = PERMUTATIES ## Geeft als resultaat het aantal permutaties voor een gegeven aantal objecten +POISSON = POISSON ## Geeft als resultaat de Poisson-verdeling +PROB = KANS ## Geeft als resultaat de kans dat waarden zich tussen twee grenzen bevinden +QUARTILE = KWARTIEL ## Geeft als resultaat het kwartiel van een gegevensverzameling +RANK = RANG ## Geeft als resultaat het rangnummer van een getal in een lijst getallen +RSQ = R.KWADRAAT ## Geeft als resultaat het kwadraat van de Pearson-correlatiecoëfficiënt +SKEW = SCHEEFHEID ## Geeft als resultaat de mate van asymmetrie van een verdeling +SLOPE = RICHTING ## Geeft als resultaat de richtingscoëfficiënt van een lineaire regressielijn +SMALL = KLEINSTE ## Geeft als resultaat de op k-1 na kleinste waarde in een gegevensverzameling +STANDARDIZE = NORMALISEREN ## Geeft als resultaat een genormaliseerde waarde +STDEV = STDEV ## Maakt een schatting van de standaarddeviatie op basis van een steekproef +STDEVA = STDEVA ## Maakt een schatting van de standaarddeviatie op basis van een steekproef, inclusief getallen, tekst en logische waarden +STDEVP = STDEVP ## Berekent de standaarddeviatie op basis van de volledige populatie +STDEVPA = STDEVPA ## Berekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden +STEYX = STAND.FOUT.YX ## Geeft als resultaat de standaardfout in de voorspelde y-waarde voor elke x in een regressie +TDIST = T.VERD ## Geeft als resultaat de Student T-verdeling +TINV = T.INV ## Geeft als resultaat de inverse van de Student T-verdeling +TREND = TREND ## Geeft als resultaat de waarden voor een lineaire trend +TRIMMEAN = GETRIMD.GEM ## Geeft als resultaat het gemiddelde van waarden in een gegevensverzameling +TTEST = T.TOETS ## Geeft als resultaat de kans met behulp van de Student T-toets +VAR = VAR ## Maakt een schatting van de variantie op basis van een steekproef +VARA = VARA ## Maakt een schatting van de variantie op basis van een steekproef, inclusief getallen, tekst en logische waarden +VARP = VARP ## Berekent de variantie op basis van de volledige populatie +VARPA = VARPA ## Berekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden +WEIBULL = WEIBULL ## Geeft als resultaat de Weibull-verdeling +ZTEST = Z.TOETS ## Geeft als resultaat de eenzijdige kanswaarde van een Z-toets + + +## +## Text functions Tekstfuncties +## +ASC = ASC ## Wijzigt Nederlandse letters of katakanatekens over de volle breedte (dubbel-bytetekens) binnen een tekenreeks in tekens over de halve breedte (enkel-bytetekens) +BAHTTEXT = BAHT.TEKST ## Converteert een getal naar tekst met de valutanotatie ß (baht) +CHAR = TEKEN ## Geeft als resultaat het teken dat hoort bij de opgegeven code +CLEAN = WISSEN.CONTROL ## Verwijdert alle niet-afdrukbare tekens uit een tekst +CODE = CODE ## Geeft als resultaat de numerieke code voor het eerste teken in een tekenreeks +CONCATENATE = TEKST.SAMENVOEGEN ## Voegt verschillende tekstfragmenten samen tot één tekstfragment +DOLLAR = EURO ## Converteert een getal naar tekst met de valutanotatie € (euro) +EXACT = GELIJK ## Controleert of twee tekenreeksen identiek zijn +FIND = VIND.ALLES ## Zoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +FINDB = VIND.ALLES.B ## Zoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +FIXED = VAST ## Maakt een getal als tekst met een vast aantal decimalen op +JIS = JIS ## Wijzigt Nederlandse letters of katakanatekens over de halve breedte (enkel-bytetekens) binnen een tekenreeks in tekens over de volle breedte (dubbel-bytetekens) +LEFT = LINKS ## Geeft als resultaat de meest linkse tekens in een tekenreeks +LEFTB = LINKSB ## Geeft als resultaat de meest linkse tekens in een tekenreeks +LEN = LENGTE ## Geeft als resultaat het aantal tekens in een tekenreeks +LENB = LENGTEB ## Geeft als resultaat het aantal tekens in een tekenreeks +LOWER = KLEINE.LETTERS ## Zet tekst om in kleine letters +MID = MIDDEN ## Geeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft +MIDB = DEELB ## Geeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft +PHONETIC = FONETISCH ## Haalt de fonetische tekens (furigana) uit een tekenreeks op +PROPER = BEGINLETTERS ## Zet de eerste letter van elk woord in een tekst om in een hoofdletter +REPLACE = VERVANG ## Vervangt tekens binnen een tekst +REPLACEB = VERVANGENB ## Vervangt tekens binnen een tekst +REPT = HERHALING ## Herhaalt een tekst een aantal malen +RIGHT = RECHTS ## Geeft als resultaat de meest rechtse tekens in een tekenreeks +RIGHTB = RECHTSB ## Geeft als resultaat de meest rechtse tekens in een tekenreeks +SEARCH = VIND.SPEC ## Zoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +SEARCHB = VIND.SPEC.B ## Zoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters) +SUBSTITUTE = SUBSTITUEREN ## Vervangt oude tekst door nieuwe tekst in een tekenreeks +T = T ## Converteert de argumenten naar tekst +TEXT = TEKST ## Maakt een getal op en converteert het getal naar tekst +TRIM = SPATIES.WISSEN ## Verwijdert de spaties uit een tekst +UPPER = HOOFDLETTERS ## Zet tekst om in hoofdletters +VALUE = WAARDE ## Converteert tekst naar een getal diff --git a/extend/phpexcel/PHPExcel/locale/no/config b/extend/phpexcel/PHPExcel/locale/no/config new file mode 100755 index 0000000..5bf96a1 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/no/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + +## +## Excel Error Codes (For future use) +## +NULL = #NULL! +DIV0 = #DIV/0! +VALUE = #VERDI! +REF = #REF! +NAME = #NAVN? +NUM = #NUM! +NA = #I/T diff --git a/extend/phpexcel/PHPExcel/locale/no/functions b/extend/phpexcel/PHPExcel/locale/no/functions new file mode 100755 index 0000000..917c7f7 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/no/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funksjonene Tillegg og Automatisering +## +GETPIVOTDATA = HENTPIVOTDATA ## Returnerer data som er lagret i en pivottabellrapport + + +## +## Cube functions Kubefunksjoner +## +CUBEKPIMEMBER = KUBEKPIMEDLEM ## Returnerer navnet, egenskapen og målet for en viktig ytelsesindikator (KPI), og viser navnet og egenskapen i cellen. En KPI er en målbar enhet, for eksempel månedlig bruttoinntjening eller kvartalsvis inntjening per ansatt, og brukes til å overvåke ytelsen i en organisasjon. +CUBEMEMBER = KUBEMEDLEM ## Returnerer et medlem eller en tuppel i et kubehierarki. Brukes til å validere at medlemmet eller tuppelen finnes i kuben. +CUBEMEMBERPROPERTY = KUBEMEDLEMEGENSKAP ## Returnerer verdien til en medlemsegenskap i kuben. Brukes til å validere at et medlemsnavn finnes i kuben, og til å returnere den angitte egenskapen for dette medlemmet. +CUBERANKEDMEMBER = KUBERANGERTMEDLEM ## Returnerer det n-te, eller rangerte, medlemmet i et sett. Brukes til å returnere ett eller flere elementer i et sett, for eksempel de 10 beste studentene. +CUBESET = KUBESETT ## Definerer et beregnet sett av medlemmer eller tuppeler ved å sende et settuttrykk til kuben på serveren, noe som oppretter settet og deretter returnerer dette settet til Microsoft Office Excel. +CUBESETCOUNT = KUBESETTANTALL ## Returnerer antallet elementer i et sett. +CUBEVALUE = KUBEVERDI ## Returnerer en aggregert verdi fra en kube. + + +## +## Database functions Databasefunksjoner +## +DAVERAGE = DGJENNOMSNITT ## Returnerer gjennomsnittet av merkede databaseposter +DCOUNT = DANTALL ## Teller celler som inneholder tall i en database +DCOUNTA = DANTALLA ## Teller celler som ikke er tomme i en database +DGET = DHENT ## Trekker ut fra en database en post som oppfyller angitte vilkår +DMAX = DMAKS ## Returnerer maksimumsverdien fra merkede databaseposter +DMIN = DMIN ## Returnerer minimumsverdien fra merkede databaseposter +DPRODUCT = DPRODUKT ## Multipliserer verdiene i et bestemt felt med poster som oppfyller vilkårene i en database +DSTDEV = DSTDAV ## Estimerer standardavviket basert på et utvalg av merkede databaseposter +DSTDEVP = DSTAVP ## Beregner standardavviket basert på at merkede databaseposter utgjør hele populasjonen +DSUM = DSUMMER ## Legger til tallene i feltkolonnen med poster, i databasen som oppfyller vilkårene +DVAR = DVARIANS ## Estimerer variansen basert på et utvalg av merkede databaseposter +DVARP = DVARIANSP ## Beregner variansen basert på at merkede databaseposter utgjør hele populasjonen + + +## +## Date and time functions Dato- og tidsfunksjoner +## +DATE = DATO ## Returnerer serienummeret som svarer til en bestemt dato +DATEVALUE = DATOVERDI ## Konverterer en dato med tekstformat til et serienummer +DAY = DAG ## Konverterer et serienummer til en dag i måneden +DAYS360 = DAGER360 ## Beregner antall dager mellom to datoer basert på et år med 360 dager +EDATE = DAG.ETTER ## Returnerer serienummeret som svarer til datoen som er det indikerte antall måneder før eller etter startdatoen +EOMONTH = MÅNEDSSLUTT ## Returnerer serienummeret som svarer til siste dag i måneden, før eller etter et angitt antall måneder +HOUR = TIME ## Konverterer et serienummer til en time +MINUTE = MINUTT ## Konverterer et serienummer til et minutt +MONTH = MÅNED ## Konverterer et serienummer til en måned +NETWORKDAYS = NETT.ARBEIDSDAGER ## Returnerer antall hele arbeidsdager mellom to datoer +NOW = NÅ ## Returnerer serienummeret som svarer til gjeldende dato og klokkeslett +SECOND = SEKUND ## Konverterer et serienummer til et sekund +TIME = TID ## Returnerer serienummeret som svarer til et bestemt klokkeslett +TIMEVALUE = TIDSVERDI ## Konverterer et klokkeslett i tekstformat til et serienummer +TODAY = IDAG ## Returnerer serienummeret som svarer til dagens dato +WEEKDAY = UKEDAG ## Konverterer et serienummer til en ukedag +WEEKNUM = UKENR ## Konverterer et serienummer til et tall som representerer hvilket nummer uken har i et år +WORKDAY = ARBEIDSDAG ## Returnerer serienummeret som svarer til datoen før eller etter et angitt antall arbeidsdager +YEAR = ÅR ## Konverterer et serienummer til et år +YEARFRAC = ÅRDEL ## Returnerer brøkdelen for året, som svarer til antall hele dager mellom startdato og sluttdato + + +## +## Engineering functions Tekniske funksjoner +## +BESSELI = BESSELI ## Returnerer den endrede Bessel-funksjonen In(x) +BESSELJ = BESSELJ ## Returnerer Bessel-funksjonen Jn(x) +BESSELK = BESSELK ## Returnerer den endrede Bessel-funksjonen Kn(x) +BESSELY = BESSELY ## Returnerer Bessel-funksjonen Yn(x) +BIN2DEC = BINTILDES ## Konverterer et binært tall til et desimaltall +BIN2HEX = BINTILHEKS ## Konverterer et binært tall til et heksadesimaltall +BIN2OCT = BINTILOKT ## Konverterer et binært tall til et oktaltall +COMPLEX = KOMPLEKS ## Konverterer reelle og imaginære koeffisienter til et komplekst tall +CONVERT = KONVERTER ## Konverterer et tall fra ett målsystem til et annet +DEC2BIN = DESTILBIN ## Konverterer et desimaltall til et binærtall +DEC2HEX = DESTILHEKS ## Konverterer et heltall i 10-tallsystemet til et heksadesimalt tall +DEC2OCT = DESTILOKT ## Konverterer et heltall i 10-tallsystemet til et oktaltall +DELTA = DELTA ## Undersøker om to verdier er like +ERF = FEILF ## Returnerer feilfunksjonen +ERFC = FEILFK ## Returnerer den komplementære feilfunksjonen +GESTEP = GRENSEVERDI ## Tester om et tall er større enn en terskelverdi +HEX2BIN = HEKSTILBIN ## Konverterer et heksadesimaltall til et binært tall +HEX2DEC = HEKSTILDES ## Konverterer et heksadesimalt tall til et heltall i 10-tallsystemet +HEX2OCT = HEKSTILOKT ## Konverterer et heksadesimalt tall til et oktaltall +IMABS = IMABS ## Returnerer absoluttverdien (koeffisienten) til et komplekst tall +IMAGINARY = IMAGINÆR ## Returnerer den imaginære koeffisienten til et komplekst tall +IMARGUMENT = IMARGUMENT ## Returnerer argumentet theta, som er en vinkel uttrykt i radianer +IMCONJUGATE = IMKONJUGERT ## Returnerer den komplekse konjugaten til et komplekst tall +IMCOS = IMCOS ## Returnerer cosinus til et komplekst tall +IMDIV = IMDIV ## Returnerer kvotienten til to komplekse tall +IMEXP = IMEKSP ## Returnerer eksponenten til et komplekst tall +IMLN = IMLN ## Returnerer den naturlige logaritmen for et komplekst tall +IMLOG10 = IMLOG10 ## Returnerer logaritmen med grunntall 10 for et komplekst tall +IMLOG2 = IMLOG2 ## Returnerer logaritmen med grunntall 2 for et komplekst tall +IMPOWER = IMOPPHØY ## Returnerer et komplekst tall opphøyd til en heltallspotens +IMPRODUCT = IMPRODUKT ## Returnerer produktet av komplekse tall +IMREAL = IMREELL ## Returnerer den reelle koeffisienten til et komplekst tall +IMSIN = IMSIN ## Returnerer sinus til et komplekst tall +IMSQRT = IMROT ## Returnerer kvadratroten av et komplekst tall +IMSUB = IMSUB ## Returnerer differansen mellom to komplekse tall +IMSUM = IMSUMMER ## Returnerer summen av komplekse tall +OCT2BIN = OKTTILBIN ## Konverterer et oktaltall til et binært tall +OCT2DEC = OKTTILDES ## Konverterer et oktaltall til et desimaltall +OCT2HEX = OKTTILHEKS ## Konverterer et oktaltall til et heksadesimaltall + + +## +## Financial functions Økonomiske funksjoner +## +ACCRINT = PÅLØPT.PERIODISK.RENTE ## Returnerer påløpte renter for et verdipapir som betaler periodisk rente +ACCRINTM = PÅLØPT.FORFALLSRENTE ## Returnerer den påløpte renten for et verdipapir som betaler rente ved forfall +AMORDEGRC = AMORDEGRC ## Returnerer avskrivningen for hver regnskapsperiode ved hjelp av en avskrivingskoeffisient +AMORLINC = AMORLINC ## Returnerer avskrivingen for hver regnskapsperiode +COUPDAYBS = OBLIG.DAGER.FF ## Returnerer antall dager fra begynnelsen av den rentebærende perioden til innløsningsdatoen +COUPDAYS = OBLIG.DAGER ## Returnerer antall dager i den rentebærende perioden som inneholder innløsningsdatoen +COUPDAYSNC = OBLIG.DAGER.NF ## Returnerer antall dager fra betalingsdato til neste renteinnbetalingsdato +COUPNCD = OBLIG.DAGER.EF ## Returnerer obligasjonsdatoen som kommer etter oppgjørsdatoen +COUPNUM = OBLIG.ANTALL ## Returnerer antall obligasjoner som skal betales mellom oppgjørsdatoen og forfallsdatoen +COUPPCD = OBLIG.DAG.FORRIGE ## Returnerer obligasjonsdatoen som kommer før oppgjørsdatoen +CUMIPMT = SAMLET.RENTE ## Returnerer den kumulative renten som er betalt mellom to perioder +CUMPRINC = SAMLET.HOVEDSTOL ## Returnerer den kumulative hovedstolen som er betalt for et lån mellom to perioder +DB = DAVSKR ## Returnerer avskrivningen for et aktivum i en angitt periode, foretatt med fast degressiv avskrivning +DDB = DEGRAVS ## Returnerer avskrivningen for et aktivum for en gitt periode, ved hjelp av dobbel degressiv avskrivning eller en metode som du selv angir +DISC = DISKONTERT ## Returnerer diskonteringsraten for et verdipapir +DOLLARDE = DOLLARDE ## Konverterer en valutapris uttrykt som en brøk, til en valutapris uttrykt som et desimaltall +DOLLARFR = DOLLARBR ## Konverterer en valutapris uttrykt som et desimaltall, til en valutapris uttrykt som en brøk +DURATION = VARIGHET ## Returnerer årlig varighet for et verdipapir med renter som betales periodisk +EFFECT = EFFEKTIV.RENTE ## Returnerer den effektive årlige rentesatsen +FV = SLUTTVERDI ## Returnerer fremtidig verdi for en investering +FVSCHEDULE = SVPLAN ## Returnerer den fremtidige verdien av en inngående hovedstol etter å ha anvendt en serie med sammensatte rentesatser +INTRATE = RENTESATS ## Returnerer rentefoten av et fullfinansiert verdipapir +IPMT = RAVDRAG ## Returnerer betalte renter på en investering for en gitt periode +IRR = IR ## Returnerer internrenten for en serie kontantstrømmer +ISPMT = ER.AVDRAG ## Beregner renten som er betalt for en investering i løpet av en bestemt periode +MDURATION = MVARIGHET ## Returnerer Macauleys modifiserte varighet for et verdipapir med en antatt pålydende verdi på kr 100,00 +MIRR = MODIR ## Returnerer internrenten der positive og negative kontantstrømmer finansieres med forskjellige satser +NOMINAL = NOMINELL ## Returnerer årlig nominell rentesats +NPER = PERIODER ## Returnerer antall perioder for en investering +NPV = NNV ## Returnerer netto nåverdi for en investering, basert på en serie periodiske kontantstrømmer og en rentesats +ODDFPRICE = AVVIKFP.PRIS ## Returnerer pris pålydende kr 100 for et verdipapir med en odde første periode +ODDFYIELD = AVVIKFP.AVKASTNING ## Returnerer avkastingen for et verdipapir med en odde første periode +ODDLPRICE = AVVIKSP.PRIS ## Returnerer pris pålydende kr 100 for et verdipapir med en odde siste periode +ODDLYIELD = AVVIKSP.AVKASTNING ## Returnerer avkastingen for et verdipapir med en odde siste periode +PMT = AVDRAG ## Returnerer periodisk betaling for en annuitet +PPMT = AMORT ## Returnerer betalingen på hovedstolen for en investering i en gitt periode +PRICE = PRIS ## Returnerer prisen per pålydende kr 100 for et verdipapir som gir periodisk avkastning +PRICEDISC = PRIS.DISKONTERT ## Returnerer prisen per pålydende kr 100 for et diskontert verdipapir +PRICEMAT = PRIS.FORFALL ## Returnerer prisen per pålydende kr 100 av et verdipapir som betaler rente ved forfall +PV = NÅVERDI ## Returnerer nåverdien av en investering +RATE = RENTE ## Returnerer rentesatsen per periode for en annuitet +RECEIVED = MOTTATT.AVKAST ## Returnerer summen som mottas ved forfallsdato for et fullinvestert verdipapir +SLN = LINAVS ## Returnerer den lineære avskrivningen for et aktivum i én periode +SYD = ÅRSAVS ## Returnerer årsavskrivningen for et aktivum i en angitt periode +TBILLEQ = TBILLEKV ## Returnerer den obligasjonsekvivalente avkastningen for en statsobligasjon +TBILLPRICE = TBILLPRIS ## Returnerer prisen per pålydende kr 100 for en statsobligasjon +TBILLYIELD = TBILLAVKASTNING ## Returnerer avkastningen til en statsobligasjon +VDB = VERDIAVS ## Returnerer avskrivningen for et aktivum i en angitt periode eller delperiode, ved hjelp av degressiv avskrivning +XIRR = XIR ## Returnerer internrenten for en serie kontantstrømmer som ikke nødvendigvis er periodiske +XNPV = XNNV ## Returnerer netto nåverdi for en serie kontantstrømmer som ikke nødvendigvis er periodiske +YIELD = AVKAST ## Returnerer avkastningen på et verdipapir som betaler periodisk rente +YIELDDISC = AVKAST.DISKONTERT ## Returnerer årlig avkastning for et diskontert verdipapir, for eksempel en statskasseveksel +YIELDMAT = AVKAST.FORFALL ## Returnerer den årlige avkastningen for et verdipapir som betaler rente ved forfallsdato + + +## +## Information functions Informasjonsfunksjoner +## +CELL = CELLE ## Returnerer informasjon om formatering, plassering eller innholdet til en celle +ERROR.TYPE = FEIL.TYPE ## Returnerer et tall som svarer til en feiltype +INFO = INFO ## Returnerer informasjon om gjeldende operativmiljø +ISBLANK = ERTOM ## Returnerer SANN hvis verdien er tom +ISERR = ERFEIL ## Returnerer SANN hvis verdien er en hvilken som helst annen feilverdi enn #I/T +ISERROR = ERFEIL ## Returnerer SANN hvis verdien er en hvilken som helst feilverdi +ISEVEN = ERPARTALL ## Returnerer SANN hvis tallet er et partall +ISLOGICAL = ERLOGISK ## Returnerer SANN hvis verdien er en logisk verdi +ISNA = ERIT ## Returnerer SANN hvis verdien er feilverdien #I/T +ISNONTEXT = ERIKKETEKST ## Returnerer SANN hvis verdien ikke er tekst +ISNUMBER = ERTALL ## Returnerer SANN hvis verdien er et tall +ISODD = ERODDETALL ## Returnerer SANN hvis tallet er et oddetall +ISREF = ERREF ## Returnerer SANN hvis verdien er en referanse +ISTEXT = ERTEKST ## Returnerer SANN hvis verdien er tekst +N = N ## Returnerer en verdi som er konvertert til et tall +NA = IT ## Returnerer feilverdien #I/T +TYPE = VERDITYPE ## Returnerer et tall som indikerer datatypen til en verdi + + +## +## Logical functions Logiske funksjoner +## +AND = OG ## Returnerer SANN hvis alle argumentene er lik SANN +FALSE = USANN ## Returnerer den logiske verdien USANN +IF = HVIS ## Angir en logisk test som skal utføres +IFERROR = HVISFEIL ## Returnerer en verdi du angir hvis en formel evaluerer til en feil. Ellers returnerer den resultatet av formelen. +NOT = IKKE ## Reverserer logikken til argumentet +OR = ELLER ## Returnerer SANN hvis ett eller flere argumenter er lik SANN +TRUE = SANN ## Returnerer den logiske verdien SANN + + +## +## Lookup and reference functions Oppslag- og referansefunksjoner +## +ADDRESS = ADRESSE ## Returnerer en referanse som tekst til en enkelt celle i et regneark +AREAS = OMRÅDER ## Returnerer antall områder i en referanse +CHOOSE = VELG ## Velger en verdi fra en liste med verdier +COLUMN = KOLONNE ## Returnerer kolonnenummeret for en referanse +COLUMNS = KOLONNER ## Returnerer antall kolonner i en referanse +HLOOKUP = FINN.KOLONNE ## Leter i den øverste raden i en matrise og returnerer verdien for den angitte cellen +HYPERLINK = HYPERKOBLING ## Oppretter en snarvei eller et hopp som åpner et dokument som er lagret på en nettverksserver, et intranett eller Internett +INDEX = INDEKS ## Bruker en indeks til å velge en verdi fra en referanse eller matrise +INDIRECT = INDIREKTE ## Returnerer en referanse angitt av en tekstverdi +LOOKUP = SLÅ.OPP ## Slår opp verdier i en vektor eller matrise +MATCH = SAMMENLIGNE ## Slår opp verdier i en referanse eller matrise +OFFSET = FORSKYVNING ## Returnerer en referanseforskyvning fra en gitt referanse +ROW = RAD ## Returnerer radnummeret for en referanse +ROWS = RADER ## Returnerer antall rader i en referanse +RTD = RTD ## Henter sanntidsdata fra et program som støtter COM-automatisering (automatisering: En måte å arbeide på med programobjekter fra et annet program- eller utviklingsverktøy. Tidligere kalt OLE-automatisering. Automatisering er en bransjestandard og en funksjon i Component Object Model (COM).) +TRANSPOSE = TRANSPONER ## Returnerer transponeringen av en matrise +VLOOKUP = FINN.RAD ## Leter i den første kolonnen i en matrise og flytter bortover raden for å returnere verdien til en celle + + +## +## Math and trigonometry functions Matematikk- og trigonometrifunksjoner +## +ABS = ABS ## Returnerer absoluttverdien til et tall +ACOS = ARCCOS ## Returnerer arcus cosinus til et tall +ACOSH = ARCCOSH ## Returnerer den inverse hyperbolske cosinus til et tall +ASIN = ARCSIN ## Returnerer arcus sinus til et tall +ASINH = ARCSINH ## Returnerer den inverse hyperbolske sinus til et tall +ATAN = ARCTAN ## Returnerer arcus tangens til et tall +ATAN2 = ARCTAN2 ## Returnerer arcus tangens fra x- og y-koordinater +ATANH = ARCTANH ## Returnerer den inverse hyperbolske tangens til et tall +CEILING = AVRUND.GJELDENDE.MULTIPLUM ## Runder av et tall til nærmeste heltall eller til nærmeste signifikante multiplum +COMBIN = KOMBINASJON ## Returnerer antall kombinasjoner for ett gitt antall objekter +COS = COS ## Returnerer cosinus til et tall +COSH = COSH ## Returnerer den hyperbolske cosinus til et tall +DEGREES = GRADER ## Konverterer radianer til grader +EVEN = AVRUND.TIL.PARTALL ## Runder av et tall oppover til nærmeste heltall som er et partall +EXP = EKSP ## Returnerer e opphøyd i en angitt potens +FACT = FAKULTET ## Returnerer fakultet til et tall +FACTDOUBLE = DOBBELFAKT ## Returnerer et talls doble fakultet +FLOOR = AVRUND.GJELDENDE.MULTIPLUM.NED ## Avrunder et tall nedover, mot null +GCD = SFF ## Returnerer høyeste felles divisor +INT = HELTALL ## Avrunder et tall nedover til nærmeste heltall +LCM = MFM ## Returnerer minste felles multiplum +LN = LN ## Returnerer den naturlige logaritmen til et tall +LOG = LOG ## Returnerer logaritmen for et tall til et angitt grunntall +LOG10 = LOG10 ## Returnerer logaritmen med grunntall 10 for et tall +MDETERM = MDETERM ## Returnerer matrisedeterminanten til en matrise +MINVERSE = MINVERS ## Returnerer den inverse matrisen til en matrise +MMULT = MMULT ## Returnerer matriseproduktet av to matriser +MOD = REST ## Returnerer resten fra en divisjon +MROUND = MRUND ## Returnerer et tall avrundet til det ønskede multiplum +MULTINOMIAL = MULTINOMINELL ## Returnerer det multinominelle for et sett med tall +ODD = AVRUND.TIL.ODDETALL ## Runder av et tall oppover til nærmeste heltall som er et oddetall +PI = PI ## Returnerer verdien av pi +POWER = OPPHØYD.I ## Returnerer resultatet av et tall opphøyd i en potens +PRODUCT = PRODUKT ## Multipliserer argumentene +QUOTIENT = KVOTIENT ## Returnerer heltallsdelen av en divisjon +RADIANS = RADIANER ## Konverterer grader til radianer +RAND = TILFELDIG ## Returnerer et tilfeldig tall mellom 0 og 1 +RANDBETWEEN = TILFELDIGMELLOM ## Returnerer et tilfeldig tall innenfor et angitt område +ROMAN = ROMERTALL ## Konverterer vanlige tall til romertall, som tekst +ROUND = AVRUND ## Avrunder et tall til et angitt antall sifre +ROUNDDOWN = AVRUND.NED ## Avrunder et tall nedover, mot null +ROUNDUP = AVRUND.OPP ## Runder av et tall oppover, bort fra null +SERIESSUM = SUMMER.REKKE ## Returnerer summen av en geometrisk rekke, basert på formelen +SIGN = FORTEGN ## Returnerer fortegnet for et tall +SIN = SIN ## Returnerer sinus til en gitt vinkel +SINH = SINH ## Returnerer den hyperbolske sinus til et tall +SQRT = ROT ## Returnerer en positiv kvadratrot +SQRTPI = ROTPI ## Returnerer kvadratroten av (tall * pi) +SUBTOTAL = DELSUM ## Returnerer en delsum i en liste eller database +SUM = SUMMER ## Legger sammen argumentene +SUMIF = SUMMERHVIS ## Legger sammen cellene angitt ved et gitt vilkår +SUMIFS = SUMMER.HVIS.SETT ## Legger sammen cellene i et område som oppfyller flere vilkår +SUMPRODUCT = SUMMERPRODUKT ## Returnerer summen av produktene av tilsvarende matrisekomponenter +SUMSQ = SUMMERKVADRAT ## Returnerer kvadratsummen av argumentene +SUMX2MY2 = SUMMERX2MY2 ## Returnerer summen av differansen av kvadratene for tilsvarende verdier i to matriser +SUMX2PY2 = SUMMERX2PY2 ## Returnerer summen av kvadratsummene for tilsvarende verdier i to matriser +SUMXMY2 = SUMMERXMY2 ## Returnerer summen av kvadratene av differansen for tilsvarende verdier i to matriser +TAN = TAN ## Returnerer tangens for et tall +TANH = TANH ## Returnerer den hyperbolske tangens for et tall +TRUNC = AVKORT ## Korter av et tall til et heltall + + +## +## Statistical functions Statistiske funksjoner +## +AVEDEV = GJENNOMSNITTSAVVIK ## Returnerer datapunktenes gjennomsnittlige absoluttavvik fra middelverdien +AVERAGE = GJENNOMSNITT ## Returnerer gjennomsnittet for argumentene +AVERAGEA = GJENNOMSNITTA ## Returnerer gjennomsnittet for argumentene, inkludert tall, tekst og logiske verdier +AVERAGEIF = GJENNOMSNITTHVIS ## Returnerer gjennomsnittet (aritmetisk gjennomsnitt) av alle cellene i et område som oppfyller et bestemt vilkår +AVERAGEIFS = GJENNOMSNITT.HVIS.SETT ## Returnerer gjennomsnittet (aritmetisk middelverdi) av alle celler som oppfyller flere vilkår. +BETADIST = BETA.FORDELING ## Returnerer den kumulative betafordelingsfunksjonen +BETAINV = INVERS.BETA.FORDELING ## Returnerer den inverse verdien til fordelingsfunksjonen for en angitt betafordeling +BINOMDIST = BINOM.FORDELING ## Returnerer den individuelle binomiske sannsynlighetsfordelingen +CHIDIST = KJI.FORDELING ## Returnerer den ensidige sannsynligheten for en kjikvadrert fordeling +CHIINV = INVERS.KJI.FORDELING ## Returnerer den inverse av den ensidige sannsynligheten for den kjikvadrerte fordelingen +CHITEST = KJI.TEST ## Utfører testen for uavhengighet +CONFIDENCE = KONFIDENS ## Returnerer konfidensintervallet til gjennomsnittet for en populasjon +CORREL = KORRELASJON ## Returnerer korrelasjonskoeffisienten mellom to datasett +COUNT = ANTALL ## Teller hvor mange tall som er i argumentlisten +COUNTA = ANTALLA ## Teller hvor mange verdier som er i argumentlisten +COUNTBLANK = TELLBLANKE ## Teller antall tomme celler i et område. +COUNTIF = ANTALL.HVIS ## Teller antall celler i et område som oppfyller gitte vilkår +COUNTIFS = ANTALL.HVIS.SETT ## Teller antallet ikke-tomme celler i et område som oppfyller flere vilkår +COVAR = KOVARIANS ## Returnerer kovariansen, gjennomsnittet av produktene av parvise avvik +CRITBINOM = GRENSE.BINOM ## Returnerer den minste verdien der den kumulative binomiske fordelingen er mindre enn eller lik en vilkårsverdi +DEVSQ = AVVIK.KVADRERT ## Returnerer summen av kvadrerte avvik +EXPONDIST = EKSP.FORDELING ## Returnerer eksponentialfordelingen +FDIST = FFORDELING ## Returnerer F-sannsynlighetsfordelingen +FINV = FFORDELING.INVERS ## Returnerer den inverse av den sannsynlige F-fordelingen +FISHER = FISHER ## Returnerer Fisher-transformasjonen +FISHERINV = FISHERINV ## Returnerer den inverse av Fisher-transformasjonen +FORECAST = PROGNOSE ## Returnerer en verdi langs en lineær trend +FREQUENCY = FREKVENS ## Returnerer en frekvensdistribusjon som en loddrett matrise +FTEST = FTEST ## Returnerer resultatet av en F-test +GAMMADIST = GAMMAFORDELING ## Returnerer gammafordelingen +GAMMAINV = GAMMAINV ## Returnerer den inverse av den gammakumulative fordelingen +GAMMALN = GAMMALN ## Returnerer den naturlige logaritmen til gammafunksjonen G(x) +GEOMEAN = GJENNOMSNITT.GEOMETRISK ## Returnerer den geometriske middelverdien +GROWTH = VEKST ## Returnerer verdier langs en eksponentiell trend +HARMEAN = GJENNOMSNITT.HARMONISK ## Returnerer den harmoniske middelverdien +HYPGEOMDIST = HYPGEOM.FORDELING ## Returnerer den hypergeometriske fordelingen +INTERCEPT = SKJÆRINGSPUNKT ## Returnerer skjæringspunktet til den lineære regresjonslinjen +KURT = KURT ## Returnerer kurtosen til et datasett +LARGE = N.STØRST ## Returnerer den n-te største verdien i et datasett +LINEST = RETTLINJE ## Returnerer parameterne til en lineær trend +LOGEST = KURVE ## Returnerer parameterne til en eksponentiell trend +LOGINV = LOGINV ## Returnerer den inverse lognormale fordelingen +LOGNORMDIST = LOGNORMFORD ## Returnerer den kumulative lognormale fordelingen +MAX = STØRST ## Returnerer maksimumsverdien i en argumentliste +MAXA = MAKSA ## Returnerer maksimumsverdien i en argumentliste, inkludert tall, tekst og logiske verdier +MEDIAN = MEDIAN ## Returnerer medianen til tallene som er gitt +MIN = MIN ## Returnerer minimumsverdien i en argumentliste +MINA = MINA ## Returnerer den minste verdien i en argumentliste, inkludert tall, tekst og logiske verdier +MODE = MODUS ## Returnerer den vanligste verdien i et datasett +NEGBINOMDIST = NEGBINOM.FORDELING ## Returnerer den negative binomiske fordelingen +NORMDIST = NORMALFORDELING ## Returnerer den kumulative normalfordelingen +NORMINV = NORMINV ## Returnerer den inverse kumulative normalfordelingen +NORMSDIST = NORMSFORDELING ## Returnerer standard kumulativ normalfordeling +NORMSINV = NORMSINV ## Returnerer den inverse av den den kumulative standard normalfordelingen +PEARSON = PEARSON ## Returnerer produktmomentkorrelasjonskoeffisienten, Pearson +PERCENTILE = PERSENTIL ## Returnerer den n-te persentil av verdiene i et område +PERCENTRANK = PROSENTDEL ## Returnerer prosentrangeringen av en verdi i et datasett +PERMUT = PERMUTER ## Returnerer antall permutasjoner for et gitt antall objekter +POISSON = POISSON ## Returnerer Poissons sannsynlighetsfordeling +PROB = SANNSYNLIG ## Returnerer sannsynligheten for at verdier i et område ligger mellom to grenser +QUARTILE = KVARTIL ## Returnerer kvartilen til et datasett +RANK = RANG ## Returnerer rangeringen av et tall, eller plassen tallet har i en rekke +RSQ = RKVADRAT ## Returnerer kvadratet av produktmomentkorrelasjonskoeffisienten (Pearsons r) +SKEW = SKJEVFORDELING ## Returnerer skjevheten i en fordeling +SLOPE = STIGNINGSTALL ## Returnerer stigningtallet for den lineære regresjonslinjen +SMALL = N.MINST ## Returnerer den n-te minste verdien i et datasett +STANDARDIZE = NORMALISER ## Returnerer en normalisert verdi +STDEV = STDAV ## Estimere standardavvik på grunnlag av et utvalg +STDEVA = STDAVVIKA ## Estimerer standardavvik basert på et utvalg, inkludert tall, tekst og logiske verdier +STDEVP = STDAVP ## Beregner standardavvik basert på hele populasjonen +STDEVPA = STDAVVIKPA ## Beregner standardavvik basert på hele populasjonen, inkludert tall, tekst og logiske verdier +STEYX = STANDARDFEIL ## Returnerer standardfeilen for den predikerte y-verdien for hver x i regresjonen +TDIST = TFORDELING ## Returnerer en Student t-fordeling +TINV = TINV ## Returnerer den inverse Student t-fordelingen +TREND = TREND ## Returnerer verdier langs en lineær trend +TRIMMEAN = TRIMMET.GJENNOMSNITT ## Returnerer den interne middelverdien til et datasett +TTEST = TTEST ## Returnerer sannsynligheten assosiert med en Student t-test +VAR = VARIANS ## Estimerer varians basert på et utvalg +VARA = VARIANSA ## Estimerer varians basert på et utvalg, inkludert tall, tekst og logiske verdier +VARP = VARIANSP ## Beregner varians basert på hele populasjonen +VARPA = VARIANSPA ## Beregner varians basert på hele populasjonen, inkludert tall, tekst og logiske verdier +WEIBULL = WEIBULL.FORDELING ## Returnerer Weibull-fordelingen +ZTEST = ZTEST ## Returnerer den ensidige sannsynlighetsverdien for en z-test + + +## +## Text functions Tekstfunksjoner +## +ASC = STIGENDE ## Endrer fullbreddes (dobbeltbyte) engelske bokstaver eller katakana i en tegnstreng, til halvbreddes (enkeltbyte) tegn +BAHTTEXT = BAHTTEKST ## Konverterer et tall til tekst, og bruker valutaformatet ß (baht) +CHAR = TEGNKODE ## Returnerer tegnet som svarer til kodenummeret +CLEAN = RENSK ## Fjerner alle tegn som ikke kan skrives ut, fra teksten +CODE = KODE ## Returnerer en numerisk kode for det første tegnet i en tekststreng +CONCATENATE = KJEDE.SAMMEN ## Slår sammen flere tekstelementer til ett tekstelement +DOLLAR = VALUTA ## Konverterer et tall til tekst, og bruker valutaformatet $ (dollar) +EXACT = EKSAKT ## Kontrollerer om to tekstverdier er like +FIND = FINN ## Finner en tekstverdi inne i en annen (skiller mellom store og små bokstaver) +FINDB = FINNB ## Finner en tekstverdi inne i en annen (skiller mellom store og små bokstaver) +FIXED = FASTSATT ## Formaterer et tall som tekst med et bestemt antall desimaler +JIS = JIS ## Endrer halvbreddes (enkeltbyte) engelske bokstaver eller katakana i en tegnstreng, til fullbreddes (dobbeltbyte) tegn +LEFT = VENSTRE ## Returnerer tegnene lengst til venstre i en tekstverdi +LEFTB = VENSTREB ## Returnerer tegnene lengst til venstre i en tekstverdi +LEN = LENGDE ## Returnerer antall tegn i en tekststreng +LENB = LENGDEB ## Returnerer antall tegn i en tekststreng +LOWER = SMÅ ## Konverterer tekst til små bokstaver +MID = DELTEKST ## Returnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir +MIDB = DELTEKSTB ## Returnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir +PHONETIC = FURIGANA ## Trekker ut fonetiske tegn (furigana) fra en tekststreng +PROPER = STOR.FORBOKSTAV ## Gir den første bokstaven i hvert ord i en tekstverdi stor forbokstav +REPLACE = ERSTATT ## Erstatter tegn i en tekst +REPLACEB = ERSTATTB ## Erstatter tegn i en tekst +REPT = GJENTA ## Gjentar tekst et gitt antall ganger +RIGHT = HØYRE ## Returnerer tegnene lengst til høyre i en tekstverdi +RIGHTB = HØYREB ## Returnerer tegnene lengst til høyre i en tekstverdi +SEARCH = SØK ## Finner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver) +SEARCHB = SØKB ## Finner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver) +SUBSTITUTE = BYTT.UT ## Bytter ut gammel tekst med ny tekst i en tekststreng +T = T ## Konverterer argumentene til tekst +TEXT = TEKST ## Formaterer et tall og konverterer det til tekst +TRIM = TRIMME ## Fjerner mellomrom fra tekst +UPPER = STORE ## Konverterer tekst til store bokstaver +VALUE = VERDI ## Konverterer et tekstargument til et tall diff --git a/extend/phpexcel/PHPExcel/locale/pl/config b/extend/phpexcel/PHPExcel/locale/pl/config new file mode 100755 index 0000000..5061311 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pl/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = zł + + +## +## Excel Error Codes (For future use) +## +NULL = #ZERO! +DIV0 = #DZIEL/0! +VALUE = #ARG! +REF = #ADR! +NAME = #NAZWA? +NUM = #LICZBA! +NA = #N/D! diff --git a/extend/phpexcel/PHPExcel/locale/pl/functions b/extend/phpexcel/PHPExcel/locale/pl/functions new file mode 100755 index 0000000..14499c0 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pl/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Funkcje dodatków i automatyzacji +## +GETPIVOTDATA = WEŹDANETABELI ## Zwraca dane przechowywane w raporcie tabeli przestawnej. + + +## +## Cube functions Funkcje modułów +## +CUBEKPIMEMBER = ELEMENT.KPI.MODUŁU ## Zwraca nazwę, właściwość i miarę kluczowego wskaźnika wydajności (KPI) oraz wyświetla nazwę i właściwość w komórce. Wskaźnik KPI jest miarą ilościową, taką jak miesięczny zysk brutto lub kwartalna fluktuacja pracowników, używaną do monitorowania wydajności organizacji. +CUBEMEMBER = ELEMENT.MODUŁU ## Zwraca element lub krotkę z hierarchii modułu. Służy do sprawdzania, czy element lub krotka istnieje w module. +CUBEMEMBERPROPERTY = WŁAŚCIWOŚĆ.ELEMENTU.MODUŁU ## Zwraca wartość właściwości elementu w module. Służy do sprawdzania, czy nazwa elementu istnieje w module, i zwracania określonej właściwości dla tego elementu. +CUBERANKEDMEMBER = USZEREGOWANY.ELEMENT.MODUŁU ## Zwraca n-ty (albo uszeregowany) element zestawu. Służy do zwracania elementu lub elementów zestawu, na przykład najlepszego sprzedawcy lub 10 najlepszych studentów. +CUBESET = ZESTAW.MODUŁÓW ## Definiuje obliczony zestaw elementów lub krotek, wysyłając wyrażenie zestawu do serwera modułu, który tworzy zestaw i zwraca go do programu Microsoft Office Excel. +CUBESETCOUNT = LICZNIK.MODUŁÓW.ZESTAWU ## Zwraca liczbę elementów zestawu. +CUBEVALUE = WARTOŚĆ.MODUŁU ## Zwraca zagregowaną wartość z modułu. + + +## +## Database functions Funkcje baz danych +## +DAVERAGE = BD.ŚREDNIA ## Zwraca wartość średniej wybranych wpisów bazy danych. +DCOUNT = BD.ILE.REKORDÓW ## Zlicza komórki zawierające liczby w bazie danych. +DCOUNTA = BD.ILE.REKORDÓW.A ## Zlicza niepuste komórki w bazie danych. +DGET = BD.POLE ## Wyodrębnia z bazy danych jeden rekord spełniający określone kryteria. +DMAX = BD.MAX ## Zwraca wartość maksymalną z wybranych wpisów bazy danych. +DMIN = BD.MIN ## Zwraca wartość minimalną z wybranych wpisów bazy danych. +DPRODUCT = BD.ILOCZYN ## Mnoży wartości w konkretnym, spełniającym kryteria polu rekordów bazy danych. +DSTDEV = BD.ODCH.STANDARD ## Szacuje odchylenie standardowe na podstawie próbki z wybranych wpisów bazy danych. +DSTDEVP = BD.ODCH.STANDARD.POPUL ## Oblicza odchylenie standardowe na podstawie całej populacji wybranych wpisów bazy danych. +DSUM = BD.SUMA ## Dodaje liczby w kolumnie pól rekordów bazy danych, które spełniają kryteria. +DVAR = BD.WARIANCJA ## Szacuje wariancję na podstawie próbki z wybranych wpisów bazy danych. +DVARP = BD.WARIANCJA.POPUL ## Oblicza wariancję na podstawie całej populacji wybranych wpisów bazy danych. + + +## +## Date and time functions Funkcje dat, godzin i czasu +## +DATE = DATA ## Zwraca liczbę seryjną dla wybranej daty. +DATEVALUE = DATA.WARTOŚĆ ## Konwertuje datę w formie tekstu na liczbę seryjną. +DAY = DZIEŃ ## Konwertuje liczbę seryjną na dzień miesiąca. +DAYS360 = DNI.360 ## Oblicza liczbę dni między dwiema datami na podstawie roku 360-dniowego. +EDATE = UPŁDNI ## Zwraca liczbę seryjną daty jako wskazaną liczbę miesięcy przed określoną datą początkową lub po niej. +EOMONTH = EOMONTH ## Zwraca liczbę seryjną ostatniego dnia miesiąca przed określoną liczbą miesięcy lub po niej. +HOUR = GODZINA ## Konwertuje liczbę seryjną na godzinę. +MINUTE = MINUTA ## Konwertuje liczbę seryjną na minutę. +MONTH = MIESIĄC ## Konwertuje liczbę seryjną na miesiąc. +NETWORKDAYS = NETWORKDAYS ## Zwraca liczbę pełnych dni roboczych między dwiema datami. +NOW = TERAZ ## Zwraca liczbę seryjną bieżącej daty i godziny. +SECOND = SEKUNDA ## Konwertuje liczbę seryjną na sekundę. +TIME = CZAS ## Zwraca liczbę seryjną określonego czasu. +TIMEVALUE = CZAS.WARTOŚĆ ## Konwertuje czas w formie tekstu na liczbę seryjną. +TODAY = DZIŚ ## Zwraca liczbę seryjną dla daty bieżącej. +WEEKDAY = DZIEŃ.TYG ## Konwertuje liczbę seryjną na dzień tygodnia. +WEEKNUM = WEEKNUM ## Konwertuje liczbę seryjną na liczbę reprezentującą numer tygodnia w roku. +WORKDAY = WORKDAY ## Zwraca liczbę seryjną dla daty przed określoną liczbą dni roboczych lub po niej. +YEAR = ROK ## Konwertuje liczbę seryjną na rok. +YEARFRAC = YEARFRAC ## Zwraca część roku reprezentowaną przez pełną liczbę dni między datą początkową a datą końcową. + + +## +## Engineering functions Funkcje inżynierskie +## +BESSELI = BESSELI ## Zwraca wartość zmodyfikowanej funkcji Bessela In(x). +BESSELJ = BESSELJ ## Zwraca wartość funkcji Bessela Jn(x). +BESSELK = BESSELK ## Zwraca wartość zmodyfikowanej funkcji Bessela Kn(x). +BESSELY = BESSELY ## Zwraca wartość funkcji Bessela Yn(x). +BIN2DEC = BIN2DEC ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci dziesiętnej. +BIN2HEX = BIN2HEX ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci szesnastkowej. +BIN2OCT = BIN2OCT ## Konwertuje liczbę w postaci dwójkowej na liczbę w postaci ósemkowej. +COMPLEX = COMPLEX ## Konwertuje część rzeczywistą i urojoną na liczbę zespoloną. +CONVERT = CONVERT ## Konwertuje liczbę z jednego systemu miar na inny. +DEC2BIN = DEC2BIN ## Konwertuje liczbę w postaci dziesiętnej na postać dwójkową. +DEC2HEX = DEC2HEX ## Konwertuje liczbę w postaci dziesiętnej na liczbę w postaci szesnastkowej. +DEC2OCT = DEC2OCT ## Konwertuje liczbę w postaci dziesiętnej na liczbę w postaci ósemkowej. +DELTA = DELTA ## Sprawdza, czy dwie wartości są równe. +ERF = ERF ## Zwraca wartość funkcji błędu. +ERFC = ERFC ## Zwraca wartość komplementarnej funkcji błędu. +GESTEP = GESTEP ## Sprawdza, czy liczba jest większa niż wartość progowa. +HEX2BIN = HEX2BIN ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci dwójkowej. +HEX2DEC = HEX2DEC ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci dziesiętnej. +HEX2OCT = HEX2OCT ## Konwertuje liczbę w postaci szesnastkowej na liczbę w postaci ósemkowej. +IMABS = IMABS ## Zwraca wartość bezwzględną (moduł) liczby zespolonej. +IMAGINARY = IMAGINARY ## Zwraca wartość części urojonej liczby zespolonej. +IMARGUMENT = IMARGUMENT ## Zwraca wartość argumentu liczby zespolonej, przy czym kąt wyrażony jest w radianach. +IMCONJUGATE = IMCONJUGATE ## Zwraca wartość liczby sprzężonej danej liczby zespolonej. +IMCOS = IMCOS ## Zwraca wartość cosinusa liczby zespolonej. +IMDIV = IMDIV ## Zwraca wartość ilorazu dwóch liczb zespolonych. +IMEXP = IMEXP ## Zwraca postać wykładniczą liczby zespolonej. +IMLN = IMLN ## Zwraca wartość logarytmu naturalnego liczby zespolonej. +IMLOG10 = IMLOG10 ## Zwraca wartość logarytmu dziesiętnego liczby zespolonej. +IMLOG2 = IMLOG2 ## Zwraca wartość logarytmu liczby zespolonej przy podstawie 2. +IMPOWER = IMPOWER ## Zwraca wartość liczby zespolonej podniesionej do potęgi całkowitej. +IMPRODUCT = IMPRODUCT ## Zwraca wartość iloczynu liczb zespolonych. +IMREAL = IMREAL ## Zwraca wartość części rzeczywistej liczby zespolonej. +IMSIN = IMSIN ## Zwraca wartość sinusa liczby zespolonej. +IMSQRT = IMSQRT ## Zwraca wartość pierwiastka kwadratowego z liczby zespolonej. +IMSUB = IMSUB ## Zwraca wartość różnicy dwóch liczb zespolonych. +IMSUM = IMSUM ## Zwraca wartość sumy liczb zespolonych. +OCT2BIN = OCT2BIN ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci dwójkowej. +OCT2DEC = OCT2DEC ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci dziesiętnej. +OCT2HEX = OCT2HEX ## Konwertuje liczbę w postaci ósemkowej na liczbę w postaci szesnastkowej. + + +## +## Financial functions Funkcje finansowe +## +ACCRINT = ACCRINT ## Zwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem okresowym. +ACCRINTM = ACCRINTM ## Zwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem w terminie wykupu. +AMORDEGRC = AMORDEGRC ## Zwraca amortyzację dla każdego okresu rozliczeniowego z wykorzystaniem współczynnika amortyzacji. +AMORLINC = AMORLINC ## Zwraca amortyzację dla każdego okresu rozliczeniowego. +COUPDAYBS = COUPDAYBS ## Zwraca liczbę dni od początku okresu dywidendy do dnia rozliczeniowego. +COUPDAYS = COUPDAYS ## Zwraca liczbę dni w okresie dywidendy, z uwzględnieniem dnia rozliczeniowego. +COUPDAYSNC = COUPDAYSNC ## Zwraca liczbę dni od dnia rozliczeniowego do daty następnego dnia dywidendy. +COUPNCD = COUPNCD ## Zwraca dzień następnej dywidendy po dniu rozliczeniowym. +COUPNUM = COUPNUM ## Zwraca liczbę dywidend płatnych między dniem rozliczeniowym a dniem wykupu. +COUPPCD = COUPPCD ## Zwraca dzień poprzedniej dywidendy przed dniem rozliczeniowym. +CUMIPMT = CUMIPMT ## Zwraca wartość procentu składanego płatnego między dwoma okresami. +CUMPRINC = CUMPRINC ## Zwraca wartość kapitału skumulowanego spłaty pożyczki między dwoma okresami. +DB = DB ## Zwraca amortyzację środka trwałego w danym okresie metodą degresywną z zastosowaniem stałej bazowej. +DDB = DDB ## Zwraca amortyzację środka trwałego za podany okres metodą degresywną z zastosowaniem podwójnej bazowej lub metodą określoną przez użytkownika. +DISC = DISC ## Zwraca wartość stopy dyskontowej papieru wartościowego. +DOLLARDE = DOLLARDE ## Konwertuje cenę w postaci ułamkowej na cenę wyrażoną w postaci dziesiętnej. +DOLLARFR = DOLLARFR ## Konwertuje cenę wyrażoną w postaci dziesiętnej na cenę wyrażoną w postaci ułamkowej. +DURATION = DURATION ## Zwraca wartość rocznego przychodu z papieru wartościowego o okresowych wypłatach oprocentowania. +EFFECT = EFFECT ## Zwraca wartość efektywnej rocznej stopy procentowej. +FV = FV ## Zwraca przyszłą wartość lokaty. +FVSCHEDULE = FVSCHEDULE ## Zwraca przyszłą wartość kapitału początkowego wraz z szeregiem procentów składanych. +INTRATE = INTRATE ## Zwraca wartość stopy procentowej papieru wartościowego całkowicie ulokowanego. +IPMT = IPMT ## Zwraca wysokość spłaty oprocentowania lokaty za dany okres. +IRR = IRR ## Zwraca wartość wewnętrznej stopy zwrotu dla serii przepływów gotówkowych. +ISPMT = ISPMT ## Oblicza wysokość spłaty oprocentowania za dany okres lokaty. +MDURATION = MDURATION ## Zwraca wartość zmodyfikowanego okresu Macauleya dla papieru wartościowego o założonej wartości nominalnej 100 zł. +MIRR = MIRR ## Zwraca wartość wewnętrznej stopy zwrotu dla przypadku, gdy dodatnie i ujemne przepływy gotówkowe mają różne stopy. +NOMINAL = NOMINAL ## Zwraca wysokość nominalnej rocznej stopy procentowej. +NPER = NPER ## Zwraca liczbę okresów dla lokaty. +NPV = NPV ## Zwraca wartość bieżącą netto lokaty na podstawie szeregu okresowych przepływów gotówkowych i stopy dyskontowej. +ODDFPRICE = ODDFPRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym pierwszym okresem. +ODDFYIELD = ODDFYIELD ## Zwraca rentowność papieru wartościowego z nietypowym pierwszym okresem. +ODDLPRICE = ODDLPRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym ostatnim okresem. +ODDLYIELD = ODDLYIELD ## Zwraca rentowność papieru wartościowego z nietypowym ostatnim okresem. +PMT = PMT ## Zwraca wartość okresowej płatności raty rocznej. +PPMT = PPMT ## Zwraca wysokość spłaty kapitału w przypadku lokaty dla danego okresu. +PRICE = PRICE ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem okresowym. +PRICEDISC = PRICEDISC ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego zdyskontowanego. +PRICEMAT = PRICEMAT ## Zwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem w terminie wykupu. +PV = PV ## Zwraca wartość bieżącą lokaty. +RATE = RATE ## Zwraca wysokość stopy procentowej w okresie raty rocznej. +RECEIVED = RECEIVED ## Zwraca wartość kapitału otrzymanego przy wykupie papieru wartościowego całkowicie ulokowanego. +SLN = SLN ## Zwraca amortyzację środka trwałego za jeden okres metodą liniową. +SYD = SYD ## Zwraca amortyzację środka trwałego za dany okres metodą sumy cyfr lat amortyzacji. +TBILLEQ = TBILLEQ ## Zwraca rentowność ekwiwalentu obligacji dla bonu skarbowego. +TBILLPRICE = TBILLPRICE ## Zwraca cenę za 100 zł wartości nominalnej bonu skarbowego. +TBILLYIELD = TBILLYIELD ## Zwraca rentowność bonu skarbowego. +VDB = VDB ## Oblicza amortyzację środka trwałego w danym okresie lub jego części metodą degresywną. +XIRR = XIRR ## Zwraca wartość wewnętrznej stopy zwrotu dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych. +XNPV = XNPV ## Zwraca wartość bieżącą netto dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych. +YIELD = YIELD ## Zwraca rentowność papieru wartościowego z oprocentowaniem okresowym. +YIELDDISC = YIELDDISC ## Zwraca roczną rentowność zdyskontowanego papieru wartościowego, na przykład bonu skarbowego. +YIELDMAT = YIELDMAT ## Zwraca roczną rentowność papieru wartościowego oprocentowanego przy wykupie. + + +## +## Information functions Funkcje informacyjne +## +CELL = KOMÓRKA ## Zwraca informacje o formacie, położeniu lub zawartości komórki. +ERROR.TYPE = NR.BŁĘDU ## Zwraca liczbę odpowiadającą typowi błędu. +INFO = INFO ## Zwraca informację o aktualnym środowisku pracy. +ISBLANK = CZY.PUSTA ## Zwraca wartość PRAWDA, jeśli wartość jest pusta. +ISERR = CZY.BŁ ## Zwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu, z wyjątkiem #N/D!. +ISERROR = CZY.BŁĄD ## Zwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu. +ISEVEN = ISEVEN ## Zwraca wartość PRAWDA, jeśli liczba jest parzysta. +ISLOGICAL = CZY.LOGICZNA ## Zwraca wartość PRAWDA, jeśli wartość jest wartością logiczną. +ISNA = CZY.BRAK ## Zwraca wartość PRAWDA, jeśli wartość jest wartością błędu #N/D!. +ISNONTEXT = CZY.NIE.TEKST ## Zwraca wartość PRAWDA, jeśli wartość nie jest tekstem. +ISNUMBER = CZY.LICZBA ## Zwraca wartość PRAWDA, jeśli wartość jest liczbą. +ISODD = ISODD ## Zwraca wartość PRAWDA, jeśli liczba jest nieparzysta. +ISREF = CZY.ADR ## Zwraca wartość PRAWDA, jeśli wartość jest odwołaniem. +ISTEXT = CZY.TEKST ## Zwraca wartość PRAWDA, jeśli wartość jest tekstem. +N = L ## Zwraca wartość przekonwertowaną na postać liczbową. +NA = BRAK ## Zwraca wartość błędu #N/D!. +TYPE = TYP ## Zwraca liczbę wskazującą typ danych wartości. + + +## +## Logical functions Funkcje logiczne +## +AND = ORAZ ## Zwraca wartość PRAWDA, jeśli wszystkie argumenty mają wartość PRAWDA. +FALSE = FAŁSZ ## Zwraca wartość logiczną FAŁSZ. +IF = JEŻELI ## Określa warunek logiczny do sprawdzenia. +IFERROR = JEŻELI.BŁĄD ## Zwraca określoną wartość, jeśli wynikiem obliczenia formuły jest błąd; w przeciwnym przypadku zwraca wynik formuły. +NOT = NIE ## Odwraca wartość logiczną argumentu. +OR = LUB ## Zwraca wartość PRAWDA, jeśli co najmniej jeden z argumentów ma wartość PRAWDA. +TRUE = PRAWDA ## Zwraca wartość logiczną PRAWDA. + + +## +## Lookup and reference functions Funkcje wyszukiwania i odwołań +## +ADDRESS = ADRES ## Zwraca odwołanie do jednej komórki w arkuszu jako wartość tekstową. +AREAS = OBSZARY ## Zwraca liczbę obszarów występujących w odwołaniu. +CHOOSE = WYBIERZ ## Wybiera wartość z listy wartości. +COLUMN = NR.KOLUMNY ## Zwraca numer kolumny z odwołania. +COLUMNS = LICZBA.KOLUMN ## Zwraca liczbę kolumn dla danego odwołania. +HLOOKUP = WYSZUKAJ.POZIOMO ## Przegląda górny wiersz tablicy i zwraca wartość wskazanej komórki. +HYPERLINK = HIPERŁĄCZE ## Tworzy skrót lub skok, który pozwala otwierać dokument przechowywany na serwerze sieciowym, w sieci intranet lub w Internecie. +INDEX = INDEKS ## Używa indeksu do wybierania wartości z odwołania lub tablicy. +INDIRECT = ADR.POŚR ## Zwraca odwołanie określone przez wartość tekstową. +LOOKUP = WYSZUKAJ ## Wyszukuje wartości w wektorze lub tablicy. +MATCH = PODAJ.POZYCJĘ ## Wyszukuje wartości w odwołaniu lub w tablicy. +OFFSET = PRZESUNIĘCIE ## Zwraca adres przesunięty od danego odwołania. +ROW = WIERSZ ## Zwraca numer wiersza odwołania. +ROWS = ILE.WIERSZY ## Zwraca liczbę wierszy dla danego odwołania. +RTD = RTD ## Pobiera dane w czasie rzeczywistym z programu obsługującego automatyzację COM (Automatyzacja: Sposób pracy z obiektami aplikacji pochodzącymi z innej aplikacji lub narzędzia projektowania. Nazywana wcześniej Automatyzacją OLE, Automatyzacja jest standardem przemysłowym i funkcją obiektowego modelu składników (COM, Component Object Model).). +TRANSPOSE = TRANSPONUJ ## Zwraca transponowaną tablicę. +VLOOKUP = WYSZUKAJ.PIONOWO ## Przeszukuje pierwszą kolumnę tablicy i przechodzi wzdłuż wiersza, aby zwrócić wartość komórki. + + +## +## Math and trigonometry functions Funkcje matematyczne i trygonometryczne +## +ABS = MODUŁ.LICZBY ## Zwraca wartość absolutną liczby. +ACOS = ACOS ## Zwraca arcus cosinus liczby. +ACOSH = ACOSH ## Zwraca arcus cosinus hiperboliczny liczby. +ASIN = ASIN ## Zwraca arcus sinus liczby. +ASINH = ASINH ## Zwraca arcus sinus hiperboliczny liczby. +ATAN = ATAN ## Zwraca arcus tangens liczby. +ATAN2 = ATAN2 ## Zwraca arcus tangens liczby na podstawie współrzędnych x i y. +ATANH = ATANH ## Zwraca arcus tangens hiperboliczny liczby. +CEILING = ZAOKR.W.GÓRĘ ## Zaokrągla liczbę do najbliższej liczby całkowitej lub do najbliższej wielokrotności dokładności. +COMBIN = KOMBINACJE ## Zwraca liczbę kombinacji dla danej liczby obiektów. +COS = COS ## Zwraca cosinus liczby. +COSH = COSH ## Zwraca cosinus hiperboliczny liczby. +DEGREES = STOPNIE ## Konwertuje radiany na stopnie. +EVEN = ZAOKR.DO.PARZ ## Zaokrągla liczbę w górę do najbliższej liczby parzystej. +EXP = EXP ## Zwraca wartość liczby e podniesionej do potęgi określonej przez podaną liczbę. +FACT = SILNIA ## Zwraca silnię liczby. +FACTDOUBLE = FACTDOUBLE ## Zwraca podwójną silnię liczby. +FLOOR = ZAOKR.W.DÓŁ ## Zaokrągla liczbę w dół, w kierunku zera. +GCD = GCD ## Zwraca największy wspólny dzielnik. +INT = ZAOKR.DO.CAŁK ## Zaokrągla liczbę w dół do najbliższej liczby całkowitej. +LCM = LCM ## Zwraca najmniejszą wspólną wielokrotność. +LN = LN ## Zwraca logarytm naturalny podanej liczby. +LOG = LOG ## Zwraca logarytm danej liczby przy zadanej podstawie. +LOG10 = LOG10 ## Zwraca logarytm dziesiętny liczby. +MDETERM = WYZNACZNIK.MACIERZY ## Zwraca wyznacznik macierzy tablicy. +MINVERSE = MACIERZ.ODW ## Zwraca odwrotność macierzy tablicy. +MMULT = MACIERZ.ILOCZYN ## Zwraca iloczyn macierzy dwóch tablic. +MOD = MOD ## Zwraca resztę z dzielenia. +MROUND = MROUND ## Zwraca liczbę zaokrągloną do żądanej wielokrotności. +MULTINOMIAL = MULTINOMIAL ## Zwraca wielomian dla zbioru liczb. +ODD = ZAOKR.DO.NPARZ ## Zaokrągla liczbę w górę do najbliższej liczby nieparzystej. +PI = PI ## Zwraca wartość liczby Pi. +POWER = POTĘGA ## Zwraca liczbę podniesioną do potęgi. +PRODUCT = ILOCZYN ## Mnoży argumenty. +QUOTIENT = QUOTIENT ## Zwraca iloraz (całkowity). +RADIANS = RADIANY ## Konwertuje stopnie na radiany. +RAND = LOS ## Zwraca liczbę pseudolosową z zakresu od 0 do 1. +RANDBETWEEN = RANDBETWEEN ## Zwraca liczbę pseudolosową z zakresu określonego przez podane argumenty. +ROMAN = RZYMSKIE ## Konwertuje liczbę arabską na rzymską jako tekst. +ROUND = ZAOKR ## Zaokrągla liczbę do określonej liczby cyfr. +ROUNDDOWN = ZAOKR.DÓŁ ## Zaokrągla liczbę w dół, w kierunku zera. +ROUNDUP = ZAOKR.GÓRA ## Zaokrągla liczbę w górę, w kierunku od zera. +SERIESSUM = SERIESSUM ## Zwraca sumę szeregu potęgowego na podstawie wzoru. +SIGN = ZNAK.LICZBY ## Zwraca znak liczby. +SIN = SIN ## Zwraca sinus danego kąta. +SINH = SINH ## Zwraca sinus hiperboliczny liczby. +SQRT = PIERWIASTEK ## Zwraca dodatni pierwiastek kwadratowy. +SQRTPI = SQRTPI ## Zwraca pierwiastek kwadratowy iloczynu (liczba * Pi). +SUBTOTAL = SUMY.POŚREDNIE ## Zwraca sumę częściową listy lub bazy danych. +SUM = SUMA ## Dodaje argumenty. +SUMIF = SUMA.JEŻELI ## Dodaje komórki określone przez podane kryterium. +SUMIFS = SUMA.WARUNKÓW ## Dodaje komórki w zakresie, które spełniają wiele kryteriów. +SUMPRODUCT = SUMA.ILOCZYNÓW ## Zwraca sumę iloczynów odpowiednich elementów tablicy. +SUMSQ = SUMA.KWADRATÓW ## Zwraca sumę kwadratów argumentów. +SUMX2MY2 = SUMA.X2.M.Y2 ## Zwraca sumę różnic kwadratów odpowiednich wartości w dwóch tablicach. +SUMX2PY2 = SUMA.X2.P.Y2 ## Zwraca sumę sum kwadratów odpowiednich wartości w dwóch tablicach. +SUMXMY2 = SUMA.XMY.2 ## Zwraca sumę kwadratów różnic odpowiednich wartości w dwóch tablicach. +TAN = TAN ## Zwraca tangens liczby. +TANH = TANH ## Zwraca tangens hiperboliczny liczby. +TRUNC = LICZBA.CAŁK ## Przycina liczbę do wartości całkowitej. + + +## +## Statistical functions Funkcje statystyczne +## +AVEDEV = ODCH.ŚREDNIE ## Zwraca średnią wartość odchyleń absolutnych punktów danych od ich wartości średniej. +AVERAGE = ŚREDNIA ## Zwraca wartość średnią argumentów. +AVERAGEA = ŚREDNIA.A ## Zwraca wartość średnią argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +AVERAGEIF = ŚREDNIA.JEŻELI ## Zwraca średnią (średnią arytmetyczną) wszystkich komórek w zakresie, które spełniają podane kryteria. +AVERAGEIFS = ŚREDNIA.WARUNKÓW ## Zwraca średnią (średnią arytmetyczną) wszystkich komórek, które spełniają jedno lub więcej kryteriów. +BETADIST = ROZKŁAD.BETA ## Zwraca skumulowaną funkcję gęstości prawdopodobieństwa beta. +BETAINV = ROZKŁAD.BETA.ODW ## Zwraca odwrotność skumulowanej funkcji gęstości prawdopodobieństwa beta. +BINOMDIST = ROZKŁAD.DWUM ## Zwraca pojedynczy składnik dwumianowego rozkładu prawdopodobieństwa. +CHIDIST = ROZKŁAD.CHI ## Zwraca wartość jednostronnego prawdopodobieństwa rozkładu chi-kwadrat. +CHIINV = ROZKŁAD.CHI.ODW ## Zwraca odwrotność wartości jednostronnego prawdopodobieństwa rozkładu chi-kwadrat. +CHITEST = TEST.CHI ## Zwraca test niezależności. +CONFIDENCE = UFNOŚĆ ## Zwraca interwał ufności dla średniej populacji. +CORREL = WSP.KORELACJI ## Zwraca współczynnik korelacji dwóch zbiorów danych. +COUNT = ILE.LICZB ## Zlicza liczby znajdujące się na liście argumentów. +COUNTA = ILE.NIEPUSTYCH ## Zlicza wartości znajdujące się na liście argumentów. +COUNTBLANK = LICZ.PUSTE ## Zwraca liczbę pustych komórek w pewnym zakresie. +COUNTIF = LICZ.JEŻELI ## Zlicza komórki wewnątrz zakresu, które spełniają podane kryteria. +COUNTIFS = LICZ.WARUNKI ## Zlicza komórki wewnątrz zakresu, które spełniają wiele kryteriów. +COVAR = KOWARIANCJA ## Zwraca kowariancję, czyli średnią wartość iloczynów odpowiednich odchyleń. +CRITBINOM = PRÓG.ROZKŁAD.DWUM ## Zwraca najmniejszą wartość, dla której skumulowany rozkład dwumianowy jest mniejszy niż wartość kryterium lub równy jej. +DEVSQ = ODCH.KWADRATOWE ## Zwraca sumę kwadratów odchyleń. +EXPONDIST = ROZKŁAD.EXP ## Zwraca rozkład wykładniczy. +FDIST = ROZKŁAD.F ## Zwraca rozkład prawdopodobieństwa F. +FINV = ROZKŁAD.F.ODW ## Zwraca odwrotność rozkładu prawdopodobieństwa F. +FISHER = ROZKŁAD.FISHER ## Zwraca transformację Fishera. +FISHERINV = ROZKŁAD.FISHER.ODW ## Zwraca odwrotność transformacji Fishera. +FORECAST = REGLINX ## Zwraca wartość trendu liniowego. +FREQUENCY = CZĘSTOŚĆ ## Zwraca rozkład częstotliwości jako tablicę pionową. +FTEST = TEST.F ## Zwraca wynik testu F. +GAMMADIST = ROZKŁAD.GAMMA ## Zwraca rozkład gamma. +GAMMAINV = ROZKŁAD.GAMMA.ODW ## Zwraca odwrotność skumulowanego rozkładu gamma. +GAMMALN = ROZKŁAD.LIN.GAMMA ## Zwraca logarytm naturalny funkcji gamma, Γ(x). +GEOMEAN = ŚREDNIA.GEOMETRYCZNA ## Zwraca średnią geometryczną. +GROWTH = REGEXPW ## Zwraca wartości trendu wykładniczego. +HARMEAN = ŚREDNIA.HARMONICZNA ## Zwraca średnią harmoniczną. +HYPGEOMDIST = ROZKŁAD.HIPERGEOM ## Zwraca rozkład hipergeometryczny. +INTERCEPT = ODCIĘTA ## Zwraca punkt przecięcia osi pionowej z linią regresji liniowej. +KURT = KURTOZA ## Zwraca kurtozę zbioru danych. +LARGE = MAX.K ## Zwraca k-tą największą wartość ze zbioru danych. +LINEST = REGLINP ## Zwraca parametry trendu liniowego. +LOGEST = REGEXPP ## Zwraca parametry trendu wykładniczego. +LOGINV = ROZKŁAD.LOG.ODW ## Zwraca odwrotność rozkładu logarytmu naturalnego. +LOGNORMDIST = ROZKŁAD.LOG ## Zwraca skumulowany rozkład logarytmu naturalnego. +MAX = MAX ## Zwraca maksymalną wartość listy argumentów. +MAXA = MAX.A ## Zwraca maksymalną wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +MEDIAN = MEDIANA ## Zwraca medianę podanych liczb. +MIN = MIN ## Zwraca minimalną wartość listy argumentów. +MINA = MIN.A ## Zwraca najmniejszą wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych. +MODE = WYST.NAJCZĘŚCIEJ ## Zwraca wartość najczęściej występującą w zbiorze danych. +NEGBINOMDIST = ROZKŁAD.DWUM.PRZEC ## Zwraca ujemny rozkład dwumianowy. +NORMDIST = ROZKŁAD.NORMALNY ## Zwraca rozkład normalny skumulowany. +NORMINV = ROZKŁAD.NORMALNY.ODW ## Zwraca odwrotność rozkładu normalnego skumulowanego. +NORMSDIST = ROZKŁAD.NORMALNY.S ## Zwraca standardowy rozkład normalny skumulowany. +NORMSINV = ROZKŁAD.NORMALNY.S.ODW ## Zwraca odwrotność standardowego rozkładu normalnego skumulowanego. +PEARSON = PEARSON ## Zwraca współczynnik korelacji momentu iloczynu Pearsona. +PERCENTILE = PERCENTYL ## Wyznacza k-ty percentyl wartości w zakresie. +PERCENTRANK = PROCENT.POZYCJA ## Zwraca procentową pozycję wartości w zbiorze danych. +PERMUT = PERMUTACJE ## Zwraca liczbę permutacji dla danej liczby obiektów. +POISSON = ROZKŁAD.POISSON ## Zwraca rozkład Poissona. +PROB = PRAWDPD ## Zwraca prawdopodobieństwo, że wartości w zakresie leżą pomiędzy dwiema granicami. +QUARTILE = KWARTYL ## Wyznacza kwartyl zbioru danych. +RANK = POZYCJA ## Zwraca pozycję liczby na liście liczb. +RSQ = R.KWADRAT ## Zwraca kwadrat współczynnika korelacji momentu iloczynu Pearsona. +SKEW = SKOŚNOŚĆ ## Zwraca skośność rozkładu. +SLOPE = NACHYLENIE ## Zwraca nachylenie linii regresji liniowej. +SMALL = MIN.K ## Zwraca k-tą najmniejszą wartość ze zbioru danych. +STANDARDIZE = NORMALIZUJ ## Zwraca wartość znormalizowaną. +STDEV = ODCH.STANDARDOWE ## Szacuje odchylenie standardowe na podstawie próbki. +STDEVA = ODCH.STANDARDOWE.A ## Szacuje odchylenie standardowe na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych. +STDEVP = ODCH.STANDARD.POPUL ## Oblicza odchylenie standardowe na podstawie całej populacji. +STDEVPA = ODCH.STANDARD.POPUL.A ## Oblicza odchylenie standardowe na podstawie całej populacji, z uwzględnieniem liczb, teksów i wartości logicznych. +STEYX = REGBŁSTD ## Zwraca błąd standardowy przewidzianej wartości y dla każdej wartości x w regresji. +TDIST = ROZKŁAD.T ## Zwraca rozkład t-Studenta. +TINV = ROZKŁAD.T.ODW ## Zwraca odwrotność rozkładu t-Studenta. +TREND = REGLINW ## Zwraca wartości trendu liniowego. +TRIMMEAN = ŚREDNIA.WEWN ## Zwraca średnią wartość dla wnętrza zbioru danych. +TTEST = TEST.T ## Zwraca prawdopodobieństwo związane z testem t-Studenta. +VAR = WARIANCJA ## Szacuje wariancję na podstawie próbki. +VARA = WARIANCJA.A ## Szacuje wariancję na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych. +VARP = WARIANCJA.POPUL ## Oblicza wariancję na podstawie całej populacji. +VARPA = WARIANCJA.POPUL.A ## Oblicza wariancję na podstawie całej populacji, z uwzględnieniem liczb, tekstów i wartości logicznych. +WEIBULL = ROZKŁAD.WEIBULL ## Zwraca rozkład Weibulla. +ZTEST = TEST.Z ## Zwraca wartość jednostronnego prawdopodobieństwa testu z. + + +## +## Text functions Funkcje tekstowe +## +ASC = ASC ## Zamienia litery angielskie lub katakana o pełnej szerokości (dwubajtowe) w ciągu znaków na znaki o szerokości połówkowej (jednobajtowe). +BAHTTEXT = BAHTTEXT ## Konwertuje liczbę na tekst, stosując format walutowy ß (baht). +CHAR = ZNAK ## Zwraca znak o podanym numerze kodu. +CLEAN = OCZYŚĆ ## Usuwa z tekstu wszystkie znaki, które nie mogą być drukowane. +CODE = KOD ## Zwraca kod numeryczny pierwszego znaku w ciągu tekstowym. +CONCATENATE = ZŁĄCZ.TEKSTY ## Łączy kilka oddzielnych tekstów w jeden tekst. +DOLLAR = KWOTA ## Konwertuje liczbę na tekst, stosując format walutowy $ (dolar). +EXACT = PORÓWNAJ ## Sprawdza identyczność dwóch wartości tekstowych. +FIND = ZNAJDŹ ## Znajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter). +FINDB = ZNAJDŹB ## Znajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter). +FIXED = ZAOKR.DO.TEKST ## Formatuje liczbę jako tekst przy stałej liczbie miejsc dziesiętnych. +JIS = JIS ## Zmienia litery angielskie lub katakana o szerokości połówkowej (jednobajtowe) w ciągu znaków na znaki o pełnej szerokości (dwubajtowe). +LEFT = LEWY ## Zwraca skrajne lewe znaki z wartości tekstowej. +LEFTB = LEWYB ## Zwraca skrajne lewe znaki z wartości tekstowej. +LEN = DŁ ## Zwraca liczbę znaków ciągu tekstowego. +LENB = DŁ.B ## Zwraca liczbę znaków ciągu tekstowego. +LOWER = LITERY.MAŁE ## Konwertuje wielkie litery tekstu na małe litery. +MID = FRAGMENT.TEKSTU ## Zwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji. +MIDB = FRAGMENT.TEKSTU.B ## Zwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji. +PHONETIC = PHONETIC ## Wybiera znaki fonetyczne (furigana) z ciągu tekstowego. +PROPER = Z.WIELKIEJ.LITERY ## Zastępuje pierwszą literę każdego wyrazu tekstu wielką literą. +REPLACE = ZASTĄP ## Zastępuje znaki w tekście. +REPLACEB = ZASTĄP.B ## Zastępuje znaki w tekście. +REPT = POWT ## Powiela tekst daną liczbę razy. +RIGHT = PRAWY ## Zwraca skrajne prawe znaki z wartości tekstowej. +RIGHTB = PRAWYB ## Zwraca skrajne prawe znaki z wartości tekstowej. +SEARCH = SZUKAJ.TEKST ## Wyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter). +SEARCHB = SZUKAJ.TEKST.B ## Wyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter). +SUBSTITUTE = PODSTAW ## Podstawia nowy tekst w miejsce poprzedniego tekstu w ciągu tekstowym. +T = T ## Konwertuje argumenty na tekst. +TEXT = TEKST ## Formatuje liczbę i konwertuje ją na tekst. +TRIM = USUŃ.ZBĘDNE.ODSTĘPY ## Usuwa spacje z tekstu. +UPPER = LITERY.WIELKIE ## Konwertuje znaki tekstu na wielkie litery. +VALUE = WARTOŚĆ ## Konwertuje argument tekstowy na liczbę. diff --git a/extend/phpexcel/PHPExcel/locale/pt/br/config b/extend/phpexcel/PHPExcel/locale/pt/br/config new file mode 100755 index 0000000..b4bf704 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pt/br/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = R$ + + +## +## Excel Error Codes (For future use) +## +NULL = #NULO! +DIV0 = #DIV/0! +VALUE = #VALOR! +REF = #REF! +NAME = #NOME? +NUM = #NÚM! +NA = #N/D diff --git a/extend/phpexcel/PHPExcel/locale/pt/br/functions b/extend/phpexcel/PHPExcel/locale/pt/br/functions new file mode 100755 index 0000000..f3ba3a3 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pt/br/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Funções Suplemento e Automação +## +GETPIVOTDATA = INFODADOSTABELADINÂMICA ## Retorna os dados armazenados em um relatório de tabela dinâmica + + +## +## Cube functions Funções de Cubo +## +CUBEKPIMEMBER = MEMBROKPICUBO ## Retorna o nome de um KPI (indicador de desempenho-chave), uma propriedade e uma medida e exibe o nome e a propriedade na célula. Um KPI é uma medida quantificável, como o lucro bruto mensal ou a rotatividade trimestral dos funcionários, usada para monitorar o desempenho de uma organização. +CUBEMEMBER = MEMBROCUBO ## Retorna um membro ou tupla em uma hierarquia de cubo. Use para validar se o membro ou tupla existe no cubo. +CUBEMEMBERPROPERTY = PROPRIEDADEMEMBROCUBO ## Retorna o valor da propriedade de um membro no cubo. Usada para validar a existência do nome do membro no cubo e para retornar a propriedade especificada para esse membro. +CUBERANKEDMEMBER = MEMBROCLASSIFICADOCUBO ## Retorna o enésimo membro, ou o membro ordenado, em um conjunto. Use para retornar um ou mais elementos em um conjunto, assim como o melhor vendedor ou os dez melhores alunos. +CUBESET = CONJUNTOCUBO ## Define um conjunto calculado de membros ou tuplas enviando uma expressão do conjunto para o cubo no servidor, que cria o conjunto e o retorna para o Microsoft Office Excel. +CUBESETCOUNT = CONTAGEMCONJUNTOCUBO ## Retorna o número de itens em um conjunto. +CUBEVALUE = VALORCUBO ## Retorna um valor agregado de um cubo. + + +## +## Database functions Funções de banco de dados +## +DAVERAGE = BDMÉDIA ## Retorna a média das entradas selecionadas de um banco de dados +DCOUNT = BDCONTAR ## Conta as células que contêm números em um banco de dados +DCOUNTA = BDCONTARA ## Conta células não vazias em um banco de dados +DGET = BDEXTRAIR ## Extrai de um banco de dados um único registro que corresponde a um critério específico +DMAX = BDMÁX ## Retorna o valor máximo de entradas selecionadas de um banco de dados +DMIN = BDMÍN ## Retorna o valor mínimo de entradas selecionadas de um banco de dados +DPRODUCT = BDMULTIPL ## Multiplica os valores em um campo específico de registros que correspondem ao critério em um banco de dados +DSTDEV = BDEST ## Estima o desvio padrão com base em uma amostra de entradas selecionadas de um banco de dados +DSTDEVP = BDDESVPA ## Calcula o desvio padrão com base na população inteira de entradas selecionadas de um banco de dados +DSUM = BDSOMA ## Adiciona os números à coluna de campos de registros do banco de dados que correspondem ao critério +DVAR = BDVAREST ## Estima a variância com base em uma amostra de entradas selecionadas de um banco de dados +DVARP = BDVARP ## Calcula a variância com base na população inteira de entradas selecionadas de um banco de dados + + +## +## Date and time functions Funções de data e hora +## +DATE = DATA ## Retorna o número de série de uma data específica +DATEVALUE = DATA.VALOR ## Converte uma data na forma de texto para um número de série +DAY = DIA ## Converte um número de série em um dia do mês +DAYS360 = DIAS360 ## Calcula o número de dias entre duas datas com base em um ano de 360 dias +EDATE = DATAM ## Retorna o número de série da data que é o número indicado de meses antes ou depois da data inicial +EOMONTH = FIMMÊS ## Retorna o número de série do último dia do mês antes ou depois de um número especificado de meses +HOUR = HORA ## Converte um número de série em uma hora +MINUTE = MINUTO ## Converte um número de série em um minuto +MONTH = MÊS ## Converte um número de série em um mês +NETWORKDAYS = DIATRABALHOTOTAL ## Retorna o número de dias úteis inteiros entre duas datas +NOW = AGORA ## Retorna o número de série seqüencial da data e hora atuais +SECOND = SEGUNDO ## Converte um número de série em um segundo +TIME = HORA ## Retorna o número de série de uma hora específica +TIMEVALUE = VALOR.TEMPO ## Converte um horário na forma de texto para um número de série +TODAY = HOJE ## Retorna o número de série da data de hoje +WEEKDAY = DIA.DA.SEMANA ## Converte um número de série em um dia da semana +WEEKNUM = NÚMSEMANA ## Converte um número de série em um número que representa onde a semana cai numericamente em um ano +WORKDAY = DIATRABALHO ## Retorna o número de série da data antes ou depois de um número específico de dias úteis +YEAR = ANO ## Converte um número de série em um ano +YEARFRAC = FRAÇÃOANO ## Retorna a fração do ano que representa o número de dias entre data_inicial e data_final + + +## +## Engineering functions Funções de engenharia +## +BESSELI = BESSELI ## Retorna a função de Bessel In(x) modificada +BESSELJ = BESSELJ ## Retorna a função de Bessel Jn(x) +BESSELK = BESSELK ## Retorna a função de Bessel Kn(x) modificada +BESSELY = BESSELY ## Retorna a função de Bessel Yn(x) +BIN2DEC = BIN2DEC ## Converte um número binário em decimal +BIN2HEX = BIN2HEX ## Converte um número binário em hexadecimal +BIN2OCT = BIN2OCT ## Converte um número binário em octal +COMPLEX = COMPLEX ## Converte coeficientes reais e imaginários e um número complexo +CONVERT = CONVERTER ## Converte um número de um sistema de medida para outro +DEC2BIN = DECABIN ## Converte um número decimal em binário +DEC2HEX = DECAHEX ## Converte um número decimal em hexadecimal +DEC2OCT = DECAOCT ## Converte um número decimal em octal +DELTA = DELTA ## Testa se dois valores são iguais +ERF = FUNERRO ## Retorna a função de erro +ERFC = FUNERROCOMPL ## Retorna a função de erro complementar +GESTEP = DEGRAU ## Testa se um número é maior do que um valor limite +HEX2BIN = HEXABIN ## Converte um número hexadecimal em binário +HEX2DEC = HEXADEC ## Converte um número hexadecimal em decimal +HEX2OCT = HEXAOCT ## Converte um número hexadecimal em octal +IMABS = IMABS ## Retorna o valor absoluto (módulo) de um número complexo +IMAGINARY = IMAGINÁRIO ## Retorna o coeficiente imaginário de um número complexo +IMARGUMENT = IMARG ## Retorna o argumento teta, um ângulo expresso em radianos +IMCONJUGATE = IMCONJ ## Retorna o conjugado complexo de um número complexo +IMCOS = IMCOS ## Retorna o cosseno de um número complexo +IMDIV = IMDIV ## Retorna o quociente de dois números complexos +IMEXP = IMEXP ## Retorna o exponencial de um número complexo +IMLN = IMLN ## Retorna o logaritmo natural de um número complexo +IMLOG10 = IMLOG10 ## Retorna o logaritmo de base 10 de um número complexo +IMLOG2 = IMLOG2 ## Retorna o logaritmo de base 2 de um número complexo +IMPOWER = IMPOT ## Retorna um número complexo elevado a uma potência inteira +IMPRODUCT = IMPROD ## Retorna o produto de números complexos +IMREAL = IMREAL ## Retorna o coeficiente real de um número complexo +IMSIN = IMSENO ## Retorna o seno de um número complexo +IMSQRT = IMRAIZ ## Retorna a raiz quadrada de um número complexo +IMSUB = IMSUBTR ## Retorna a diferença entre dois números complexos +IMSUM = IMSOMA ## Retorna a soma de números complexos +OCT2BIN = OCTABIN ## Converte um número octal em binário +OCT2DEC = OCTADEC ## Converte um número octal em decimal +OCT2HEX = OCTAHEX ## Converte um número octal em hexadecimal + + +## +## Financial functions Funções financeiras +## +ACCRINT = JUROSACUM ## Retorna a taxa de juros acumulados de um título que paga uma taxa periódica de juros +ACCRINTM = JUROSACUMV ## Retorna os juros acumulados de um título que paga juros no vencimento +AMORDEGRC = AMORDEGRC ## Retorna a depreciação para cada período contábil usando o coeficiente de depreciação +AMORLINC = AMORLINC ## Retorna a depreciação para cada período contábil +COUPDAYBS = CUPDIASINLIQ ## Retorna o número de dias do início do período de cupom até a data de liquidação +COUPDAYS = CUPDIAS ## Retorna o número de dias no período de cupom que contém a data de quitação +COUPDAYSNC = CUPDIASPRÓX ## Retorna o número de dias da data de liquidação até a data do próximo cupom +COUPNCD = CUPDATAPRÓX ## Retorna a próxima data de cupom após a data de quitação +COUPNUM = CUPNÚM ## Retorna o número de cupons pagáveis entre as datas de quitação e vencimento +COUPPCD = CUPDATAANT ## Retorna a data de cupom anterior à data de quitação +CUMIPMT = PGTOJURACUM ## Retorna os juros acumulados pagos entre dois períodos +CUMPRINC = PGTOCAPACUM ## Retorna o capital acumulado pago sobre um empréstimo entre dois períodos +DB = BD ## Retorna a depreciação de um ativo para um período especificado, usando o método de balanço de declínio fixo +DDB = BDD ## Retorna a depreciação de um ativo com relação a um período especificado usando o método de saldos decrescentes duplos ou qualquer outro método especificado por você +DISC = DESC ## Retorna a taxa de desconto de um título +DOLLARDE = MOEDADEC ## Converte um preço em formato de moeda, na forma fracionária, em um preço na forma decimal +DOLLARFR = MOEDAFRA ## Converte um preço, apresentado na forma decimal, em um preço apresentado na forma fracionária +DURATION = DURAÇÃO ## Retorna a duração anual de um título com pagamentos de juros periódicos +EFFECT = EFETIVA ## Retorna a taxa de juros anual efetiva +FV = VF ## Retorna o valor futuro de um investimento +FVSCHEDULE = VFPLANO ## Retorna o valor futuro de um capital inicial após a aplicação de uma série de taxas de juros compostas +INTRATE = TAXAJUROS ## Retorna a taxa de juros de um título totalmente investido +IPMT = IPGTO ## Retorna o pagamento de juros para um investimento em um determinado período +IRR = TIR ## Retorna a taxa interna de retorno de uma série de fluxos de caixa +ISPMT = ÉPGTO ## Calcula os juros pagos durante um período específico de um investimento +MDURATION = MDURAÇÃO ## Retorna a duração de Macauley modificada para um título com um valor de paridade equivalente a R$ 100 +MIRR = MTIR ## Calcula a taxa interna de retorno em que fluxos de caixa positivos e negativos são financiados com diferentes taxas +NOMINAL = NOMINAL ## Retorna a taxa de juros nominal anual +NPER = NPER ## Retorna o número de períodos de um investimento +NPV = VPL ## Retorna o valor líquido atual de um investimento com base em uma série de fluxos de caixa periódicos e em uma taxa de desconto +ODDFPRICE = PREÇOPRIMINC ## Retorna o preço por R$ 100 de valor nominal de um título com um primeiro período indefinido +ODDFYIELD = LUCROPRIMINC ## Retorna o rendimento de um título com um primeiro período indefinido +ODDLPRICE = PREÇOÚLTINC ## Retorna o preço por R$ 100 de valor nominal de um título com um último período de cupom indefinido +ODDLYIELD = LUCROÚLTINC ## Retorna o rendimento de um título com um último período indefinido +PMT = PGTO ## Retorna o pagamento periódico de uma anuidade +PPMT = PPGTO ## Retorna o pagamento de capital para determinado período de investimento +PRICE = PREÇO ## Retorna a preço por R$ 100,00 de valor nominal de um título que paga juros periódicos +PRICEDISC = PREÇODESC ## Retorna o preço por R$ 100,00 de valor nominal de um título descontado +PRICEMAT = PREÇOVENC ## Retorna o preço por R$ 100,00 de valor nominal de um título que paga juros no vencimento +PV = VP ## Retorna o valor presente de um investimento +RATE = TAXA ## Retorna a taxa de juros por período de uma anuidade +RECEIVED = RECEBER ## Retorna a quantia recebida no vencimento de um título totalmente investido +SLN = DPD ## Retorna a depreciação em linha reta de um ativo durante um período +SYD = SDA ## Retorna a depreciação dos dígitos da soma dos anos de um ativo para um período especificado +TBILLEQ = OTN ## Retorna o rendimento de um título equivalente a uma obrigação do Tesouro +TBILLPRICE = OTNVALOR ## Retorna o preço por R$ 100,00 de valor nominal de uma obrigação do Tesouro +TBILLYIELD = OTNLUCRO ## Retorna o rendimento de uma obrigação do Tesouro +VDB = BDV ## Retorna a depreciação de um ativo para um período especificado ou parcial usando um método de balanço declinante +XIRR = XTIR ## Fornece a taxa interna de retorno para um programa de fluxos de caixa que não é necessariamente periódico +XNPV = XVPL ## Retorna o valor presente líquido de um programa de fluxos de caixa que não é necessariamente periódico +YIELD = LUCRO ## Retorna o lucro de um título que paga juros periódicos +YIELDDISC = LUCRODESC ## Retorna o rendimento anual de um título descontado. Por exemplo, uma obrigação do Tesouro +YIELDMAT = LUCROVENC ## Retorna o lucro anual de um título que paga juros no vencimento + + +## +## Information functions Funções de informação +## +CELL = CÉL ## Retorna informações sobre formatação, localização ou conteúdo de uma célula +ERROR.TYPE = TIPO.ERRO ## Retorna um número correspondente a um tipo de erro +INFO = INFORMAÇÃO ## Retorna informações sobre o ambiente operacional atual +ISBLANK = ÉCÉL.VAZIA ## Retorna VERDADEIRO se o valor for vazio +ISERR = ÉERRO ## Retorna VERDADEIRO se o valor for um valor de erro diferente de #N/D +ISERROR = ÉERROS ## Retorna VERDADEIRO se o valor for um valor de erro +ISEVEN = ÉPAR ## Retorna VERDADEIRO se o número for par +ISLOGICAL = ÉLÓGICO ## Retorna VERDADEIRO se o valor for um valor lógico +ISNA = É.NÃO.DISP ## Retorna VERDADEIRO se o valor for o valor de erro #N/D +ISNONTEXT = É.NÃO.TEXTO ## Retorna VERDADEIRO se o valor for diferente de texto +ISNUMBER = ÉNÚM ## Retorna VERDADEIRO se o valor for um número +ISODD = ÉIMPAR ## Retorna VERDADEIRO se o número for ímpar +ISREF = ÉREF ## Retorna VERDADEIRO se o valor for uma referência +ISTEXT = ÉTEXTO ## Retorna VERDADEIRO se o valor for texto +N = N ## Retorna um valor convertido em um número +NA = NÃO.DISP ## Retorna o valor de erro #N/D +TYPE = TIPO ## Retorna um número indicando o tipo de dados de um valor + + +## +## Logical functions Funções lógicas +## +AND = E ## Retorna VERDADEIRO se todos os seus argumentos forem VERDADEIROS +FALSE = FALSO ## Retorna o valor lógico FALSO +IF = SE ## Especifica um teste lógico a ser executado +IFERROR = SEERRO ## Retornará um valor que você especifica se uma fórmula for avaliada para um erro; do contrário, retornará o resultado da fórmula +NOT = NÃO ## Inverte o valor lógico do argumento +OR = OU ## Retorna VERDADEIRO se um dos argumentos for VERDADEIRO +TRUE = VERDADEIRO ## Retorna o valor lógico VERDADEIRO + + +## +## Lookup and reference functions Funções de pesquisa e referência +## +ADDRESS = ENDEREÇO ## Retorna uma referência como texto para uma única célula em uma planilha +AREAS = ÁREAS ## Retorna o número de áreas em uma referência +CHOOSE = ESCOLHER ## Escolhe um valor a partir de uma lista de valores +COLUMN = COL ## Retorna o número da coluna de uma referência +COLUMNS = COLS ## Retorna o número de colunas em uma referência +HLOOKUP = PROCH ## Procura na linha superior de uma matriz e retorna o valor da célula especificada +HYPERLINK = HYPERLINK ## Cria um atalho ou salto que abre um documento armazenado em um servidor de rede, uma intranet ou na Internet +INDEX = ÍNDICE ## Usa um índice para escolher um valor de uma referência ou matriz +INDIRECT = INDIRETO ## Retorna uma referência indicada por um valor de texto +LOOKUP = PROC ## Procura valores em um vetor ou em uma matriz +MATCH = CORRESP ## Procura valores em uma referência ou em uma matriz +OFFSET = DESLOC ## Retorna um deslocamento de referência com base em uma determinada referência +ROW = LIN ## Retorna o número da linha de uma referência +ROWS = LINS ## Retorna o número de linhas em uma referência +RTD = RTD ## Recupera dados em tempo real de um programa que ofereça suporte a automação COM (automação: uma forma de trabalhar com objetos de um aplicativo a partir de outro aplicativo ou ferramenta de desenvolvimento. Chamada inicialmente de automação OLE, a automação é um padrão industrial e um recurso do modelo de objeto componente (COM).) +TRANSPOSE = TRANSPOR ## Retorna a transposição de uma matriz +VLOOKUP = PROCV ## Procura na primeira coluna de uma matriz e move ao longo da linha para retornar o valor de uma célula + + +## +## Math and trigonometry functions Funções matemáticas e trigonométricas +## +ABS = ABS ## Retorna o valor absoluto de um número +ACOS = ACOS ## Retorna o arco cosseno de um número +ACOSH = ACOSH ## Retorna o cosseno hiperbólico inverso de um número +ASIN = ASEN ## Retorna o arco seno de um número +ASINH = ASENH ## Retorna o seno hiperbólico inverso de um número +ATAN = ATAN ## Retorna o arco tangente de um número +ATAN2 = ATAN2 ## Retorna o arco tangente das coordenadas x e y especificadas +ATANH = ATANH ## Retorna a tangente hiperbólica inversa de um número +CEILING = TETO ## Arredonda um número para o inteiro mais próximo ou para o múltiplo mais próximo de significância +COMBIN = COMBIN ## Retorna o número de combinações de um determinado número de objetos +COS = COS ## Retorna o cosseno de um número +COSH = COSH ## Retorna o cosseno hiperbólico de um número +DEGREES = GRAUS ## Converte radianos em graus +EVEN = PAR ## Arredonda um número para cima até o inteiro par mais próximo +EXP = EXP ## Retorna e elevado à potência de um número especificado +FACT = FATORIAL ## Retorna o fatorial de um número +FACTDOUBLE = FATDUPLO ## Retorna o fatorial duplo de um número +FLOOR = ARREDMULTB ## Arredonda um número para baixo até zero +GCD = MDC ## Retorna o máximo divisor comum +INT = INT ## Arredonda um número para baixo até o número inteiro mais próximo +LCM = MMC ## Retorna o mínimo múltiplo comum +LN = LN ## Retorna o logaritmo natural de um número +LOG = LOG ## Retorna o logaritmo de um número de uma base especificada +LOG10 = LOG10 ## Retorna o logaritmo de base 10 de um número +MDETERM = MATRIZ.DETERM ## Retorna o determinante de uma matriz de uma variável do tipo matriz +MINVERSE = MATRIZ.INVERSO ## Retorna a matriz inversa de uma matriz +MMULT = MATRIZ.MULT ## Retorna o produto de duas matrizes +MOD = RESTO ## Retorna o resto da divisão +MROUND = MARRED ## Retorna um número arredondado ao múltiplo desejado +MULTINOMIAL = MULTINOMIAL ## Retorna o multinomial de um conjunto de números +ODD = ÍMPAR ## Arredonda um número para cima até o inteiro ímpar mais próximo +PI = PI ## Retorna o valor de Pi +POWER = POTÊNCIA ## Fornece o resultado de um número elevado a uma potência +PRODUCT = MULT ## Multiplica seus argumentos +QUOTIENT = QUOCIENTE ## Retorna a parte inteira de uma divisão +RADIANS = RADIANOS ## Converte graus em radianos +RAND = ALEATÓRIO ## Retorna um número aleatório entre 0 e 1 +RANDBETWEEN = ALEATÓRIOENTRE ## Retorna um número aleatório entre os números especificados +ROMAN = ROMANO ## Converte um algarismo arábico em romano, como texto +ROUND = ARRED ## Arredonda um número até uma quantidade especificada de dígitos +ROUNDDOWN = ARREDONDAR.PARA.BAIXO ## Arredonda um número para baixo até zero +ROUNDUP = ARREDONDAR.PARA.CIMA ## Arredonda um número para cima, afastando-o de zero +SERIESSUM = SOMASEQÜÊNCIA ## Retorna a soma de uma série polinomial baseada na fórmula +SIGN = SINAL ## Retorna o sinal de um número +SIN = SEN ## Retorna o seno de um ângulo dado +SINH = SENH ## Retorna o seno hiperbólico de um número +SQRT = RAIZ ## Retorna uma raiz quadrada positiva +SQRTPI = RAIZPI ## Retorna a raiz quadrada de (núm* pi) +SUBTOTAL = SUBTOTAL ## Retorna um subtotal em uma lista ou em um banco de dados +SUM = SOMA ## Soma seus argumentos +SUMIF = SOMASE ## Adiciona as células especificadas por um determinado critério +SUMIFS = SOMASE ## Adiciona as células em um intervalo que atende a vários critérios +SUMPRODUCT = SOMARPRODUTO ## Retorna a soma dos produtos de componentes correspondentes de matrizes +SUMSQ = SOMAQUAD ## Retorna a soma dos quadrados dos argumentos +SUMX2MY2 = SOMAX2DY2 ## Retorna a soma da diferença dos quadrados dos valores correspondentes em duas matrizes +SUMX2PY2 = SOMAX2SY2 ## Retorna a soma da soma dos quadrados dos valores correspondentes em duas matrizes +SUMXMY2 = SOMAXMY2 ## Retorna a soma dos quadrados das diferenças dos valores correspondentes em duas matrizes +TAN = TAN ## Retorna a tangente de um número +TANH = TANH ## Retorna a tangente hiperbólica de um número +TRUNC = TRUNCAR ## Trunca um número para um inteiro + + +## +## Statistical functions Funções estatísticas +## +AVEDEV = DESV.MÉDIO ## Retorna a média aritmética dos desvios médios dos pontos de dados a partir de sua média +AVERAGE = MÉDIA ## Retorna a média dos argumentos +AVERAGEA = MÉDIAA ## Retorna a média dos argumentos, inclusive números, texto e valores lógicos +AVERAGEIF = MÉDIASE ## Retorna a média (média aritmética) de todas as células em um intervalo que atendem a um determinado critério +AVERAGEIFS = MÉDIASES ## Retorna a média (média aritmética) de todas as células que atendem a múltiplos critérios. +BETADIST = DISTBETA ## Retorna a função de distribuição cumulativa beta +BETAINV = BETA.ACUM.INV ## Retorna o inverso da função de distribuição cumulativa para uma distribuição beta especificada +BINOMDIST = DISTRBINOM ## Retorna a probabilidade de distribuição binomial do termo individual +CHIDIST = DIST.QUI ## Retorna a probabilidade unicaudal da distribuição qui-quadrada +CHIINV = INV.QUI ## Retorna o inverso da probabilidade uni-caudal da distribuição qui-quadrada +CHITEST = TESTE.QUI ## Retorna o teste para independência +CONFIDENCE = INT.CONFIANÇA ## Retorna o intervalo de confiança para uma média da população +CORREL = CORREL ## Retorna o coeficiente de correlação entre dois conjuntos de dados +COUNT = CONT.NÚM ## Calcula quantos números há na lista de argumentos +COUNTA = CONT.VALORES ## Calcula quantos valores há na lista de argumentos +COUNTBLANK = CONTAR.VAZIO ## Conta o número de células vazias no intervalo especificado +COUNTIF = CONT.SE ## Calcula o número de células não vazias em um intervalo que corresponde a determinados critérios +COUNTIFS = CONT.SES ## Conta o número de células dentro de um intervalo que atende a múltiplos critérios +COVAR = COVAR ## Retorna a covariância, a média dos produtos dos desvios pares +CRITBINOM = CRIT.BINOM ## Retorna o menor valor para o qual a distribuição binomial cumulativa é menor ou igual ao valor padrão +DEVSQ = DESVQ ## Retorna a soma dos quadrados dos desvios +EXPONDIST = DISTEXPON ## Retorna a distribuição exponencial +FDIST = DISTF ## Retorna a distribuição de probabilidade F +FINV = INVF ## Retorna o inverso da distribuição de probabilidades F +FISHER = FISHER ## Retorna a transformação Fisher +FISHERINV = FISHERINV ## Retorna o inverso da transformação Fisher +FORECAST = PREVISÃO ## Retorna um valor ao longo de uma linha reta +FREQUENCY = FREQÜÊNCIA ## Retorna uma distribuição de freqüência como uma matriz vertical +FTEST = TESTEF ## Retorna o resultado de um teste F +GAMMADIST = DISTGAMA ## Retorna a distribuição gama +GAMMAINV = INVGAMA ## Retorna o inverso da distribuição cumulativa gama +GAMMALN = LNGAMA ## Retorna o logaritmo natural da função gama, G(x) +GEOMEAN = MÉDIA.GEOMÉTRICA ## Retorna a média geométrica +GROWTH = CRESCIMENTO ## Retorna valores ao longo de uma tendência exponencial +HARMEAN = MÉDIA.HARMÔNICA ## Retorna a média harmônica +HYPGEOMDIST = DIST.HIPERGEOM ## Retorna a distribuição hipergeométrica +INTERCEPT = INTERCEPÇÃO ## Retorna a intercepção da linha de regressão linear +KURT = CURT ## Retorna a curtose de um conjunto de dados +LARGE = MAIOR ## Retorna o maior valor k-ésimo de um conjunto de dados +LINEST = PROJ.LIN ## Retorna os parâmetros de uma tendência linear +LOGEST = PROJ.LOG ## Retorna os parâmetros de uma tendência exponencial +LOGINV = INVLOG ## Retorna o inverso da distribuição lognormal +LOGNORMDIST = DIST.LOGNORMAL ## Retorna a distribuição lognormal cumulativa +MAX = MÁXIMO ## Retorna o valor máximo em uma lista de argumentos +MAXA = MÁXIMOA ## Retorna o maior valor em uma lista de argumentos, inclusive números, texto e valores lógicos +MEDIAN = MED ## Retorna a mediana dos números indicados +MIN = MÍNIMO ## Retorna o valor mínimo em uma lista de argumentos +MINA = MÍNIMOA ## Retorna o menor valor em uma lista de argumentos, inclusive números, texto e valores lógicos +MODE = MODO ## Retorna o valor mais comum em um conjunto de dados +NEGBINOMDIST = DIST.BIN.NEG ## Retorna a distribuição binomial negativa +NORMDIST = DIST.NORM ## Retorna a distribuição cumulativa normal +NORMINV = INV.NORM ## Retorna o inverso da distribuição cumulativa normal +NORMSDIST = DIST.NORMP ## Retorna a distribuição cumulativa normal padrão +NORMSINV = INV.NORMP ## Retorna o inverso da distribuição cumulativa normal padrão +PEARSON = PEARSON ## Retorna o coeficiente de correlação do momento do produto Pearson +PERCENTILE = PERCENTIL ## Retorna o k-ésimo percentil de valores em um intervalo +PERCENTRANK = ORDEM.PORCENTUAL ## Retorna a ordem percentual de um valor em um conjunto de dados +PERMUT = PERMUT ## Retorna o número de permutações de um determinado número de objetos +POISSON = POISSON ## Retorna a distribuição Poisson +PROB = PROB ## Retorna a probabilidade de valores em um intervalo estarem entre dois limites +QUARTILE = QUARTIL ## Retorna o quartil do conjunto de dados +RANK = ORDEM ## Retorna a posição de um número em uma lista de números +RSQ = RQUAD ## Retorna o quadrado do coeficiente de correlação do momento do produto de Pearson +SKEW = DISTORÇÃO ## Retorna a distorção de uma distribuição +SLOPE = INCLINAÇÃO ## Retorna a inclinação da linha de regressão linear +SMALL = MENOR ## Retorna o menor valor k-ésimo do conjunto de dados +STANDARDIZE = PADRONIZAR ## Retorna um valor normalizado +STDEV = DESVPAD ## Estima o desvio padrão com base em uma amostra +STDEVA = DESVPADA ## Estima o desvio padrão com base em uma amostra, inclusive números, texto e valores lógicos +STDEVP = DESVPADP ## Calcula o desvio padrão com base na população total +STDEVPA = DESVPADPA ## Calcula o desvio padrão com base na população total, inclusive números, texto e valores lógicos +STEYX = EPADYX ## Retorna o erro padrão do valor-y previsto para cada x da regressão +TDIST = DISTT ## Retorna a distribuição t de Student +TINV = INVT ## Retorna o inverso da distribuição t de Student +TREND = TENDÊNCIA ## Retorna valores ao longo de uma tendência linear +TRIMMEAN = MÉDIA.INTERNA ## Retorna a média do interior de um conjunto de dados +TTEST = TESTET ## Retorna a probabilidade associada ao teste t de Student +VAR = VAR ## Estima a variância com base em uma amostra +VARA = VARA ## Estima a variância com base em uma amostra, inclusive números, texto e valores lógicos +VARP = VARP ## Calcula a variância com base na população inteira +VARPA = VARPA ## Calcula a variância com base na população total, inclusive números, texto e valores lógicos +WEIBULL = WEIBULL ## Retorna a distribuição Weibull +ZTEST = TESTEZ ## Retorna o valor de probabilidade uni-caudal de um teste-z + + +## +## Text functions Funções de texto +## +ASC = ASC ## Altera letras do inglês ou katakana de largura total (bytes duplos) dentro de uma seqüência de caracteres para caracteres de meia largura (byte único) +BAHTTEXT = BAHTTEXT ## Converte um número em um texto, usando o formato de moeda ß (baht) +CHAR = CARACT ## Retorna o caractere especificado pelo número de código +CLEAN = TIRAR ## Remove todos os caracteres do texto que não podem ser impressos +CODE = CÓDIGO ## Retorna um código numérico para o primeiro caractere de uma seqüência de caracteres de texto +CONCATENATE = CONCATENAR ## Agrupa vários itens de texto em um único item de texto +DOLLAR = MOEDA ## Converte um número em texto, usando o formato de moeda $ (dólar) +EXACT = EXATO ## Verifica se dois valores de texto são idênticos +FIND = PROCURAR ## Procura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas) +FINDB = PROCURARB ## Procura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas) +FIXED = DEF.NÚM.DEC ## Formata um número como texto com um número fixo de decimais +JIS = JIS ## Altera letras do inglês ou katakana de meia largura (byte único) dentro de uma seqüência de caracteres para caracteres de largura total (bytes duplos) +LEFT = ESQUERDA ## Retorna os caracteres mais à esquerda de um valor de texto +LEFTB = ESQUERDAB ## Retorna os caracteres mais à esquerda de um valor de texto +LEN = NÚM.CARACT ## Retorna o número de caracteres em uma seqüência de texto +LENB = NÚM.CARACTB ## Retorna o número de caracteres em uma seqüência de texto +LOWER = MINÚSCULA ## Converte texto para minúsculas +MID = EXT.TEXTO ## Retorna um número específico de caracteres de uma seqüência de texto começando na posição especificada +MIDB = EXT.TEXTOB ## Retorna um número específico de caracteres de uma seqüência de texto começando na posição especificada +PHONETIC = FONÉTICA ## Extrai os caracteres fonéticos (furigana) de uma seqüência de caracteres de texto +PROPER = PRI.MAIÚSCULA ## Coloca a primeira letra de cada palavra em maiúscula em um valor de texto +REPLACE = MUDAR ## Muda os caracteres dentro do texto +REPLACEB = MUDARB ## Muda os caracteres dentro do texto +REPT = REPT ## Repete o texto um determinado número de vezes +RIGHT = DIREITA ## Retorna os caracteres mais à direita de um valor de texto +RIGHTB = DIREITAB ## Retorna os caracteres mais à direita de um valor de texto +SEARCH = LOCALIZAR ## Localiza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas) +SEARCHB = LOCALIZARB ## Localiza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas) +SUBSTITUTE = SUBSTITUIR ## Substitui um novo texto por um texto antigo em uma seqüência de texto +T = T ## Converte os argumentos em texto +TEXT = TEXTO ## Formata um número e o converte em texto +TRIM = ARRUMAR ## Remove espaços do texto +UPPER = MAIÚSCULA ## Converte o texto em maiúsculas +VALUE = VALOR ## Converte um argumento de texto em um número diff --git a/extend/phpexcel/PHPExcel/locale/pt/config b/extend/phpexcel/PHPExcel/locale/pt/config new file mode 100755 index 0000000..60b422b --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pt/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = € + + +## +## Excel Error Codes (For future use) +## +NULL = #NULO! +DIV0 = #DIV/0! +VALUE = #VALOR! +REF = #REF! +NAME = #NOME? +NUM = #NÚM! +NA = #N/D diff --git a/extend/phpexcel/PHPExcel/locale/pt/functions b/extend/phpexcel/PHPExcel/locale/pt/functions new file mode 100755 index 0000000..7fe9e3b --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/pt/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Funções de Suplemento e Automatização +## +GETPIVOTDATA = OBTERDADOSDIN ## Devolve dados armazenados num relatório de Tabela Dinâmica + + +## +## Cube functions Funções de cubo +## +CUBEKPIMEMBER = MEMBROKPICUBO ## Devolve o nome, propriedade e medição de um KPI (key performance indicator) e apresenta o nome e a propriedade na célula. Um KPI é uma medida quantificável, como, por exemplo, o lucro mensal bruto ou a rotatividade trimestral de pessoal, utilizada para monitorizar o desempenho de uma organização. +CUBEMEMBER = MEMBROCUBO ## Devolve um membro ou cadeia de identificação numa hierarquia de cubo. Utilizada para validar a existência do membro ou cadeia de identificação no cubo. +CUBEMEMBERPROPERTY = PROPRIEDADEMEMBROCUBO ## Devolve o valor de uma propriedade de membro no cubo. Utilizada para validar a existência de um nome de membro no cubo e para devolver a propriedade especificada para esse membro. +CUBERANKEDMEMBER = MEMBROCLASSIFICADOCUBO ## Devolve o enésimo ou a classificação mais alta num conjunto. Utilizada para devolver um ou mais elementos num conjunto, tal como o melhor vendedor ou os 10 melhores alunos. +CUBESET = CONJUNTOCUBO ## Define um conjunto calculado de membros ou cadeias de identificação enviando uma expressão de conjunto para o cubo no servidor, que cria o conjunto e, em seguida, devolve o conjunto ao Microsoft Office Excel. +CUBESETCOUNT = CONTARCONJUNTOCUBO ## Devolve o número de itens num conjunto. +CUBEVALUE = VALORCUBO ## Devolve um valor agregado do cubo. + + +## +## Database functions Funções de base de dados +## +DAVERAGE = BDMÉDIA ## Devolve a média das entradas da base de dados seleccionadas +DCOUNT = BDCONTAR ## Conta as células que contêm números numa base de dados +DCOUNTA = BDCONTAR.VAL ## Conta as células que não estejam em branco numa base de dados +DGET = BDOBTER ## Extrai de uma base de dados um único registo que corresponde aos critérios especificados +DMAX = BDMÁX ## Devolve o valor máximo das entradas da base de dados seleccionadas +DMIN = BDMÍN ## Devolve o valor mínimo das entradas da base de dados seleccionadas +DPRODUCT = BDMULTIPL ## Multiplica os valores de um determinado campo de registos que correspondem aos critérios numa base de dados +DSTDEV = BDDESVPAD ## Calcula o desvio-padrão com base numa amostra de entradas da base de dados seleccionadas +DSTDEVP = BDDESVPADP ## Calcula o desvio-padrão com base na população total das entradas da base de dados seleccionadas +DSUM = BDSOMA ## Adiciona os números na coluna de campo dos registos de base de dados que correspondem aos critérios +DVAR = BDVAR ## Calcula a variância com base numa amostra das entradas de base de dados seleccionadas +DVARP = BDVARP ## Calcula a variância com base na população total das entradas de base de dados seleccionadas + + +## +## Date and time functions Funções de data e hora +## +DATE = DATA ## Devolve o número de série de uma determinada data +DATEVALUE = DATA.VALOR ## Converte uma data em forma de texto num número de série +DAY = DIA ## Converte um número de série num dia do mês +DAYS360 = DIAS360 ## Calcula o número de dias entre duas datas com base num ano com 360 dias +EDATE = DATAM ## Devolve um número de série de data que corresponde ao número de meses indicado antes ou depois da data de início +EOMONTH = FIMMÊS ## Devolve o número de série do último dia do mês antes ou depois de um número de meses especificado +HOUR = HORA ## Converte um número de série numa hora +MINUTE = MINUTO ## Converte um número de série num minuto +MONTH = MÊS ## Converte um número de série num mês +NETWORKDAYS = DIATRABALHOTOTAL ## Devolve o número total de dias úteis entre duas datas +NOW = AGORA ## Devolve o número de série da data e hora actuais +SECOND = SEGUNDO ## Converte um número de série num segundo +TIME = TEMPO ## Devolve o número de série de um determinado tempo +TIMEVALUE = VALOR.TEMPO ## Converte um tempo em forma de texto num número de série +TODAY = HOJE ## Devolve o número de série da data actual +WEEKDAY = DIA.SEMANA ## Converte um número de série num dia da semana +WEEKNUM = NÚMSEMANA ## Converte um número de série num número que representa o número da semana num determinado ano +WORKDAY = DIA.TRABALHO ## Devolve o número de série da data antes ou depois de um número de dias úteis especificado +YEAR = ANO ## Converte um número de série num ano +YEARFRAC = FRACÇÃOANO ## Devolve a fracção de ano que representa o número de dias inteiros entre a data_de_início e a data_de_fim + + +## +## Engineering functions Funções de engenharia +## +BESSELI = BESSELI ## Devolve a função de Bessel modificada In(x) +BESSELJ = BESSELJ ## Devolve a função de Bessel Jn(x) +BESSELK = BESSELK ## Devolve a função de Bessel modificada Kn(x) +BESSELY = BESSELY ## Devolve a função de Bessel Yn(x) +BIN2DEC = BINADEC ## Converte um número binário em decimal +BIN2HEX = BINAHEX ## Converte um número binário em hexadecimal +BIN2OCT = BINAOCT ## Converte um número binário em octal +COMPLEX = COMPLEXO ## Converte coeficientes reais e imaginários num número complexo +CONVERT = CONVERTER ## Converte um número de um sistema de medida noutro +DEC2BIN = DECABIN ## Converte um número decimal em binário +DEC2HEX = DECAHEX ## Converte um número decimal em hexadecimal +DEC2OCT = DECAOCT ## Converte um número decimal em octal +DELTA = DELTA ## Testa se dois valores são iguais +ERF = FUNCERRO ## Devolve a função de erro +ERFC = FUNCERROCOMPL ## Devolve a função de erro complementar +GESTEP = DEGRAU ## Testa se um número é maior do que um valor limite +HEX2BIN = HEXABIN ## Converte um número hexadecimal em binário +HEX2DEC = HEXADEC ## Converte um número hexadecimal em decimal +HEX2OCT = HEXAOCT ## Converte um número hexadecimal em octal +IMABS = IMABS ## Devolve o valor absoluto (módulo) de um número complexo +IMAGINARY = IMAGINÁRIO ## Devolve o coeficiente imaginário de um número complexo +IMARGUMENT = IMARG ## Devolve o argumento Teta, um ângulo expresso em radianos +IMCONJUGATE = IMCONJ ## Devolve o conjugado complexo de um número complexo +IMCOS = IMCOS ## Devolve o co-seno de um número complexo +IMDIV = IMDIV ## Devolve o quociente de dois números complexos +IMEXP = IMEXP ## Devolve o exponencial de um número complexo +IMLN = IMLN ## Devolve o logaritmo natural de um número complexo +IMLOG10 = IMLOG10 ## Devolve o logaritmo de base 10 de um número complexo +IMLOG2 = IMLOG2 ## Devolve o logaritmo de base 2 de um número complexo +IMPOWER = IMPOT ## Devolve um número complexo elevado a uma potência inteira +IMPRODUCT = IMPROD ## Devolve o produto de números complexos +IMREAL = IMREAL ## Devolve o coeficiente real de um número complexo +IMSIN = IMSENO ## Devolve o seno de um número complexo +IMSQRT = IMRAIZ ## Devolve a raiz quadrada de um número complexo +IMSUB = IMSUBTR ## Devolve a diferença entre dois números complexos +IMSUM = IMSOMA ## Devolve a soma de números complexos +OCT2BIN = OCTABIN ## Converte um número octal em binário +OCT2DEC = OCTADEC ## Converte um número octal em decimal +OCT2HEX = OCTAHEX ## Converte um número octal em hexadecimal + + +## +## Financial functions Funções financeiras +## +ACCRINT = JUROSACUM ## Devolve os juros acumulados de um título que paga juros periódicos +ACCRINTM = JUROSACUMV ## Devolve os juros acumulados de um título que paga juros no vencimento +AMORDEGRC = AMORDEGRC ## Devolve a depreciação correspondente a cada período contabilístico utilizando um coeficiente de depreciação +AMORLINC = AMORLINC ## Devolve a depreciação correspondente a cada período contabilístico +COUPDAYBS = CUPDIASINLIQ ## Devolve o número de dias entre o início do período do cupão e a data de regularização +COUPDAYS = CUPDIAS ## Devolve o número de dias no período do cupão que contém a data de regularização +COUPDAYSNC = CUPDIASPRÓX ## Devolve o número de dias entre a data de regularização e a data do cupão seguinte +COUPNCD = CUPDATAPRÓX ## Devolve a data do cupão seguinte após a data de regularização +COUPNUM = CUPNÚM ## Devolve o número de cupões a serem pagos entre a data de regularização e a data de vencimento +COUPPCD = CUPDATAANT ## Devolve a data do cupão anterior antes da data de regularização +CUMIPMT = PGTOJURACUM ## Devolve os juros cumulativos pagos entre dois períodos +CUMPRINC = PGTOCAPACUM ## Devolve o capital cumulativo pago a título de empréstimo entre dois períodos +DB = BD ## Devolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas fixas +DDB = BDD ## Devolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas duplas ou qualquer outro método especificado +DISC = DESC ## Devolve a taxa de desconto de um título +DOLLARDE = MOEDADEC ## Converte um preço em unidade monetária, expresso como uma fracção, num preço em unidade monetária, expresso como um número decimal +DOLLARFR = MOEDAFRA ## Converte um preço em unidade monetária, expresso como um número decimal, num preço em unidade monetária, expresso como uma fracção +DURATION = DURAÇÃO ## Devolve a duração anual de um título com pagamentos de juros periódicos +EFFECT = EFECTIVA ## Devolve a taxa de juros anual efectiva +FV = VF ## Devolve o valor futuro de um investimento +FVSCHEDULE = VFPLANO ## Devolve o valor futuro de um capital inicial após a aplicação de uma série de taxas de juro compostas +INTRATE = TAXAJUROS ## Devolve a taxa de juros de um título investido na totalidade +IPMT = IPGTO ## Devolve o pagamento dos juros de um investimento durante um determinado período +IRR = TIR ## Devolve a taxa de rentabilidade interna para uma série de fluxos monetários +ISPMT = É.PGTO ## Calcula os juros pagos durante um período específico de um investimento +MDURATION = MDURAÇÃO ## Devolve a duração modificada de Macauley de um título com um valor de paridade equivalente a € 100 +MIRR = MTIR ## Devolve a taxa interna de rentabilidade em que os fluxos monetários positivos e negativos são financiados com taxas diferentes +NOMINAL = NOMINAL ## Devolve a taxa de juros nominal anual +NPER = NPER ## Devolve o número de períodos de um investimento +NPV = VAL ## Devolve o valor actual líquido de um investimento com base numa série de fluxos monetários periódicos e numa taxa de desconto +ODDFPRICE = PREÇOPRIMINC ## Devolve o preço por € 100 do valor nominal de um título com um período inicial incompleto +ODDFYIELD = LUCROPRIMINC ## Devolve o lucro de um título com um período inicial incompleto +ODDLPRICE = PREÇOÚLTINC ## Devolve o preço por € 100 do valor nominal de um título com um período final incompleto +ODDLYIELD = LUCROÚLTINC ## Devolve o lucro de um título com um período final incompleto +PMT = PGTO ## Devolve o pagamento periódico de uma anuidade +PPMT = PPGTO ## Devolve o pagamento sobre o capital de um investimento num determinado período +PRICE = PREÇO ## Devolve o preço por € 100 do valor nominal de um título que paga juros periódicos +PRICEDISC = PREÇODESC ## Devolve o preço por € 100 do valor nominal de um título descontado +PRICEMAT = PREÇOVENC ## Devolve o preço por € 100 do valor nominal de um título que paga juros no vencimento +PV = VA ## Devolve o valor actual de um investimento +RATE = TAXA ## Devolve a taxa de juros por período de uma anuidade +RECEIVED = RECEBER ## Devolve o montante recebido no vencimento de um título investido na totalidade +SLN = AMORT ## Devolve uma depreciação linear de um activo durante um período +SYD = AMORTD ## Devolve a depreciação por algarismos da soma dos anos de um activo durante um período especificado +TBILLEQ = OTN ## Devolve o lucro de um título equivalente a uma Obrigação do Tesouro +TBILLPRICE = OTNVALOR ## Devolve o preço por € 100 de valor nominal de uma Obrigação do Tesouro +TBILLYIELD = OTNLUCRO ## Devolve o lucro de uma Obrigação do Tesouro +VDB = BDV ## Devolve a depreciação de um activo relativo a um período específico ou parcial utilizando um método de quotas degressivas +XIRR = XTIR ## Devolve a taxa interna de rentabilidade de um plano de fluxos monetários que não seja necessariamente periódica +XNPV = XVAL ## Devolve o valor actual líquido de um plano de fluxos monetários que não seja necessariamente periódico +YIELD = LUCRO ## Devolve o lucro de um título que paga juros periódicos +YIELDDISC = LUCRODESC ## Devolve o lucro anual de um título emitido abaixo do valor nominal, por exemplo, uma Obrigação do Tesouro +YIELDMAT = LUCROVENC ## Devolve o lucro anual de um título que paga juros na data de vencimento + + +## +## Information functions Funções de informação +## +CELL = CÉL ## Devolve informações sobre a formatação, localização ou conteúdo de uma célula +ERROR.TYPE = TIPO.ERRO ## Devolve um número correspondente a um tipo de erro +INFO = INFORMAÇÃO ## Devolve informações sobre o ambiente de funcionamento actual +ISBLANK = É.CÉL.VAZIA ## Devolve VERDADEIRO se o valor estiver em branco +ISERR = É.ERROS ## Devolve VERDADEIRO se o valor for um valor de erro diferente de #N/D +ISERROR = É.ERRO ## Devolve VERDADEIRO se o valor for um valor de erro +ISEVEN = ÉPAR ## Devolve VERDADEIRO se o número for par +ISLOGICAL = É.LÓGICO ## Devolve VERDADEIRO se o valor for lógico +ISNA = É.NÃO.DISP ## Devolve VERDADEIRO se o valor for o valor de erro #N/D +ISNONTEXT = É.NÃO.TEXTO ## Devolve VERDADEIRO se o valor não for texto +ISNUMBER = É.NÚM ## Devolve VERDADEIRO se o valor for um número +ISODD = ÉÍMPAR ## Devolve VERDADEIRO se o número for ímpar +ISREF = É.REF ## Devolve VERDADEIRO se o valor for uma referência +ISTEXT = É.TEXTO ## Devolve VERDADEIRO se o valor for texto +N = N ## Devolve um valor convertido num número +NA = NÃO.DISP ## Devolve o valor de erro #N/D +TYPE = TIPO ## Devolve um número que indica o tipo de dados de um valor + + +## +## Logical functions Funções lógicas +## +AND = E ## Devolve VERDADEIRO se todos os respectivos argumentos corresponderem a VERDADEIRO +FALSE = FALSO ## Devolve o valor lógico FALSO +IF = SE ## Especifica um teste lógico a ser executado +IFERROR = SE.ERRO ## Devolve um valor definido pelo utilizador se ocorrer um erro na fórmula, e devolve o resultado da fórmula se não ocorrer nenhum erro +NOT = NÃO ## Inverte a lógica do respectivo argumento +OR = OU ## Devolve VERDADEIRO se qualquer argumento for VERDADEIRO +TRUE = VERDADEIRO ## Devolve o valor lógico VERDADEIRO + + +## +## Lookup and reference functions Funções de pesquisa e referência +## +ADDRESS = ENDEREÇO ## Devolve uma referência a uma única célula numa folha de cálculo como texto +AREAS = ÁREAS ## Devolve o número de áreas numa referência +CHOOSE = SELECCIONAR ## Selecciona um valor a partir de uma lista de valores +COLUMN = COL ## Devolve o número da coluna de uma referência +COLUMNS = COLS ## Devolve o número de colunas numa referência +HLOOKUP = PROCH ## Procura na linha superior de uma matriz e devolve o valor da célula indicada +HYPERLINK = HIPERLIGAÇÃO ## Cria um atalho ou hiperligação que abre um documento armazenado num servidor de rede, numa intranet ou na Internet +INDEX = ÍNDICE ## Utiliza um índice para escolher um valor de uma referência ou de uma matriz +INDIRECT = INDIRECTO ## Devolve uma referência indicada por um valor de texto +LOOKUP = PROC ## Procura valores num vector ou numa matriz +MATCH = CORRESP ## Procura valores numa referência ou numa matriz +OFFSET = DESLOCAMENTO ## Devolve o deslocamento de referência de uma determinada referência +ROW = LIN ## Devolve o número da linha de uma referência +ROWS = LINS ## Devolve o número de linhas numa referência +RTD = RTD ## Obtém dados em tempo real a partir de um programa que suporte automatização COM (automatização: modo de trabalhar com objectos de uma aplicação a partir de outra aplicação ou ferramenta de desenvolvimento. Anteriormente conhecida como automatização OLE, a automatização é uma norma da indústria de software e uma funcionalidade COM (Component Object Model).) +TRANSPOSE = TRANSPOR ## Devolve a transposição de uma matriz +VLOOKUP = PROCV ## Procura na primeira coluna de uma matriz e percorre a linha para devolver o valor de uma célula + + +## +## Math and trigonometry functions Funções matemáticas e trigonométricas +## +ABS = ABS ## Devolve o valor absoluto de um número +ACOS = ACOS ## Devolve o arco de co-seno de um número +ACOSH = ACOSH ## Devolve o co-seno hiperbólico inverso de um número +ASIN = ASEN ## Devolve o arco de seno de um número +ASINH = ASENH ## Devolve o seno hiperbólico inverso de um número +ATAN = ATAN ## Devolve o arco de tangente de um número +ATAN2 = ATAN2 ## Devolve o arco de tangente das coordenadas x e y +ATANH = ATANH ## Devolve a tangente hiperbólica inversa de um número +CEILING = ARRED.EXCESSO ## Arredonda um número para o número inteiro mais próximo ou para o múltiplo de significância mais próximo +COMBIN = COMBIN ## Devolve o número de combinações de um determinado número de objectos +COS = COS ## Devolve o co-seno de um número +COSH = COSH ## Devolve o co-seno hiperbólico de um número +DEGREES = GRAUS ## Converte radianos em graus +EVEN = PAR ## Arredonda um número por excesso para o número inteiro mais próximo +EXP = EXP ## Devolve e elevado à potência de um determinado número +FACT = FACTORIAL ## Devolve o factorial de um número +FACTDOUBLE = FACTDUPLO ## Devolve o factorial duplo de um número +FLOOR = ARRED.DEFEITO ## Arredonda um número por defeito até zero +GCD = MDC ## Devolve o maior divisor comum +INT = INT ## Arredonda um número por defeito para o número inteiro mais próximo +LCM = MMC ## Devolve o mínimo múltiplo comum +LN = LN ## Devolve o logaritmo natural de um número +LOG = LOG ## Devolve o logaritmo de um número com uma base especificada +LOG10 = LOG10 ## Devolve o logaritmo de base 10 de um número +MDETERM = MATRIZ.DETERM ## Devolve o determinante matricial de uma matriz +MINVERSE = MATRIZ.INVERSA ## Devolve o inverso matricial de uma matriz +MMULT = MATRIZ.MULT ## Devolve o produto matricial de duas matrizes +MOD = RESTO ## Devolve o resto da divisão +MROUND = MARRED ## Devolve um número arredondado para o múltiplo pretendido +MULTINOMIAL = POLINOMIAL ## Devolve o polinomial de um conjunto de números +ODD = ÍMPAR ## Arredonda por excesso um número para o número inteiro ímpar mais próximo +PI = PI ## Devolve o valor de pi +POWER = POTÊNCIA ## Devolve o resultado de um número elevado a uma potência +PRODUCT = PRODUTO ## Multiplica os respectivos argumentos +QUOTIENT = QUOCIENTE ## Devolve a parte inteira de uma divisão +RADIANS = RADIANOS ## Converte graus em radianos +RAND = ALEATÓRIO ## Devolve um número aleatório entre 0 e 1 +RANDBETWEEN = ALEATÓRIOENTRE ## Devolve um número aleatório entre os números especificados +ROMAN = ROMANO ## Converte um número árabe em romano, como texto +ROUND = ARRED ## Arredonda um número para um número de dígitos especificado +ROUNDDOWN = ARRED.PARA.BAIXO ## Arredonda um número por defeito até zero +ROUNDUP = ARRED.PARA.CIMA ## Arredonda um número por excesso, afastando-o de zero +SERIESSUM = SOMASÉRIE ## Devolve a soma de uma série de potências baseada na fórmula +SIGN = SINAL ## Devolve o sinal de um número +SIN = SEN ## Devolve o seno de um determinado ângulo +SINH = SENH ## Devolve o seno hiperbólico de um número +SQRT = RAIZQ ## Devolve uma raiz quadrada positiva +SQRTPI = RAIZPI ## Devolve a raiz quadrada de (núm * pi) +SUBTOTAL = SUBTOTAL ## Devolve um subtotal numa lista ou base de dados +SUM = SOMA ## Adiciona os respectivos argumentos +SUMIF = SOMA.SE ## Adiciona as células especificadas por um determinado critério +SUMIFS = SOMA.SE.S ## Adiciona as células num intervalo que cumpre vários critérios +SUMPRODUCT = SOMARPRODUTO ## Devolve a soma dos produtos de componentes de matrizes correspondentes +SUMSQ = SOMARQUAD ## Devolve a soma dos quadrados dos argumentos +SUMX2MY2 = SOMAX2DY2 ## Devolve a soma da diferença dos quadrados dos valores correspondentes em duas matrizes +SUMX2PY2 = SOMAX2SY2 ## Devolve a soma da soma dos quadrados dos valores correspondentes em duas matrizes +SUMXMY2 = SOMAXMY2 ## Devolve a soma dos quadrados da diferença dos valores correspondentes em duas matrizes +TAN = TAN ## Devolve a tangente de um número +TANH = TANH ## Devolve a tangente hiperbólica de um número +TRUNC = TRUNCAR ## Trunca um número para um número inteiro + + +## +## Statistical functions Funções estatísticas +## +AVEDEV = DESV.MÉDIO ## Devolve a média aritmética dos desvios absolutos à média dos pontos de dados +AVERAGE = MÉDIA ## Devolve a média dos respectivos argumentos +AVERAGEA = MÉDIAA ## Devolve uma média dos respectivos argumentos, incluindo números, texto e valores lógicos +AVERAGEIF = MÉDIA.SE ## Devolve a média aritmética de todas as células num intervalo que cumprem determinado critério +AVERAGEIFS = MÉDIA.SE.S ## Devolve a média aritmética de todas as células que cumprem múltiplos critérios +BETADIST = DISTBETA ## Devolve a função de distribuição cumulativa beta +BETAINV = BETA.ACUM.INV ## Devolve o inverso da função de distribuição cumulativa relativamente a uma distribuição beta específica +BINOMDIST = DISTRBINOM ## Devolve a probabilidade de distribuição binomial de termo individual +CHIDIST = DIST.CHI ## Devolve a probabilidade unicaudal da distribuição qui-quadrada +CHIINV = INV.CHI ## Devolve o inverso da probabilidade unicaudal da distribuição qui-quadrada +CHITEST = TESTE.CHI ## Devolve o teste para independência +CONFIDENCE = INT.CONFIANÇA ## Devolve o intervalo de confiança correspondente a uma média de população +CORREL = CORREL ## Devolve o coeficiente de correlação entre dois conjuntos de dados +COUNT = CONTAR ## Conta os números que existem na lista de argumentos +COUNTA = CONTAR.VAL ## Conta os valores que existem na lista de argumentos +COUNTBLANK = CONTAR.VAZIO ## Conta o número de células em branco num intervalo +COUNTIF = CONTAR.SE ## Calcula o número de células num intervalo que corresponde aos critérios determinados +COUNTIFS = CONTAR.SE.S ## Conta o número de células num intervalo que cumprem múltiplos critérios +COVAR = COVAR ## Devolve a covariância, que é a média dos produtos de desvios de pares +CRITBINOM = CRIT.BINOM ## Devolve o menor valor em que a distribuição binomial cumulativa é inferior ou igual a um valor de critério +DEVSQ = DESVQ ## Devolve a soma dos quadrados dos desvios +EXPONDIST = DISTEXPON ## Devolve a distribuição exponencial +FDIST = DISTF ## Devolve a distribuição da probabilidade F +FINV = INVF ## Devolve o inverso da distribuição da probabilidade F +FISHER = FISHER ## Devolve a transformação Fisher +FISHERINV = FISHERINV ## Devolve o inverso da transformação Fisher +FORECAST = PREVISÃO ## Devolve um valor ao longo de uma tendência linear +FREQUENCY = FREQUÊNCIA ## Devolve uma distribuição de frequência como uma matriz vertical +FTEST = TESTEF ## Devolve o resultado de um teste F +GAMMADIST = DISTGAMA ## Devolve a distribuição gama +GAMMAINV = INVGAMA ## Devolve o inverso da distribuição gama cumulativa +GAMMALN = LNGAMA ## Devolve o logaritmo natural da função gama, Γ(x) +GEOMEAN = MÉDIA.GEOMÉTRICA ## Devolve a média geométrica +GROWTH = CRESCIMENTO ## Devolve valores ao longo de uma tendência exponencial +HARMEAN = MÉDIA.HARMÓNICA ## Devolve a média harmónica +HYPGEOMDIST = DIST.HIPERGEOM ## Devolve a distribuição hipergeométrica +INTERCEPT = INTERCEPTAR ## Devolve a intercepção da linha de regressão linear +KURT = CURT ## Devolve a curtose de um conjunto de dados +LARGE = MAIOR ## Devolve o maior valor k-ésimo de um conjunto de dados +LINEST = PROJ.LIN ## Devolve os parâmetros de uma tendência linear +LOGEST = PROJ.LOG ## Devolve os parâmetros de uma tendência exponencial +LOGINV = INVLOG ## Devolve o inverso da distribuição normal logarítmica +LOGNORMDIST = DIST.NORMALLOG ## Devolve a distribuição normal logarítmica cumulativa +MAX = MÁXIMO ## Devolve o valor máximo numa lista de argumentos +MAXA = MÁXIMOA ## Devolve o valor máximo numa lista de argumentos, incluindo números, texto e valores lógicos +MEDIAN = MED ## Devolve a mediana dos números indicados +MIN = MÍNIMO ## Devolve o valor mínimo numa lista de argumentos +MINA = MÍNIMOA ## Devolve o valor mínimo numa lista de argumentos, incluindo números, texto e valores lógicos +MODE = MODA ## Devolve o valor mais comum num conjunto de dados +NEGBINOMDIST = DIST.BIN.NEG ## Devolve a distribuição binominal negativa +NORMDIST = DIST.NORM ## Devolve a distribuição cumulativa normal +NORMINV = INV.NORM ## Devolve o inverso da distribuição cumulativa normal +NORMSDIST = DIST.NORMP ## Devolve a distribuição cumulativa normal padrão +NORMSINV = INV.NORMP ## Devolve o inverso da distribuição cumulativa normal padrão +PEARSON = PEARSON ## Devolve o coeficiente de correlação momento/produto de Pearson +PERCENTILE = PERCENTIL ## Devolve o k-ésimo percentil de valores num intervalo +PERCENTRANK = ORDEM.PERCENTUAL ## Devolve a ordem percentual de um valor num conjunto de dados +PERMUT = PERMUTAR ## Devolve o número de permutações de um determinado número de objectos +POISSON = POISSON ## Devolve a distribuição de Poisson +PROB = PROB ## Devolve a probabilidade dos valores num intervalo se encontrarem entre dois limites +QUARTILE = QUARTIL ## Devolve o quartil de um conjunto de dados +RANK = ORDEM ## Devolve a ordem de um número numa lista numérica +RSQ = RQUAD ## Devolve o quadrado do coeficiente de correlação momento/produto de Pearson +SKEW = DISTORÇÃO ## Devolve a distorção de uma distribuição +SLOPE = DECLIVE ## Devolve o declive da linha de regressão linear +SMALL = MENOR ## Devolve o menor valor de k-ésimo de um conjunto de dados +STANDARDIZE = NORMALIZAR ## Devolve um valor normalizado +STDEV = DESVPAD ## Calcula o desvio-padrão com base numa amostra +STDEVA = DESVPADA ## Calcula o desvio-padrão com base numa amostra, incluindo números, texto e valores lógicos +STDEVP = DESVPADP ## Calcula o desvio-padrão com base na população total +STDEVPA = DESVPADPA ## Calcula o desvio-padrão com base na população total, incluindo números, texto e valores lógicos +STEYX = EPADYX ## Devolve o erro-padrão do valor de y previsto para cada x na regressão +TDIST = DISTT ## Devolve a distribuição t de Student +TINV = INVT ## Devolve o inverso da distribuição t de Student +TREND = TENDÊNCIA ## Devolve valores ao longo de uma tendência linear +TRIMMEAN = MÉDIA.INTERNA ## Devolve a média do interior de um conjunto de dados +TTEST = TESTET ## Devolve a probabilidade associada ao teste t de Student +VAR = VAR ## Calcula a variância com base numa amostra +VARA = VARA ## Calcula a variância com base numa amostra, incluindo números, texto e valores lógicos +VARP = VARP ## Calcula a variância com base na população total +VARPA = VARPA ## Calcula a variância com base na população total, incluindo números, texto e valores lógicos +WEIBULL = WEIBULL ## Devolve a distribuição Weibull +ZTEST = TESTEZ ## Devolve o valor de probabilidade unicaudal de um teste-z + + +## +## Text functions Funções de texto +## +ASC = ASC ## Altera letras ou katakana de largura total (byte duplo) numa cadeia de caracteres para caracteres de largura média (byte único) +BAHTTEXT = TEXTO.BAHT ## Converte um número em texto, utilizando o formato monetário ß (baht) +CHAR = CARÁCT ## Devolve o carácter especificado pelo número de código +CLEAN = LIMPAR ## Remove do texto todos os caracteres não imprimíveis +CODE = CÓDIGO ## Devolve um código numérico correspondente ao primeiro carácter numa cadeia de texto +CONCATENATE = CONCATENAR ## Agrupa vários itens de texto num único item de texto +DOLLAR = MOEDA ## Converte um número em texto, utilizando o formato monetário € (Euro) +EXACT = EXACTO ## Verifica se dois valores de texto são idênticos +FIND = LOCALIZAR ## Localiza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas) +FINDB = LOCALIZARB ## Localiza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas) +FIXED = FIXA ## Formata um número como texto com um número fixo de decimais +JIS = JIS ## Altera letras ou katakana de largura média (byte único) numa cadeia de caracteres para caracteres de largura total (byte duplo) +LEFT = ESQUERDA ## Devolve os caracteres mais à esquerda de um valor de texto +LEFTB = ESQUERDAB ## Devolve os caracteres mais à esquerda de um valor de texto +LEN = NÚM.CARACT ## Devolve o número de caracteres de uma cadeia de texto +LENB = NÚM.CARACTB ## Devolve o número de caracteres de uma cadeia de texto +LOWER = MINÚSCULAS ## Converte o texto em minúsculas +MID = SEG.TEXTO ## Devolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada +MIDB = SEG.TEXTOB ## Devolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada +PHONETIC = FONÉTICA ## Retira os caracteres fonéticos (furigana) de uma cadeia de texto +PROPER = INICIAL.MAIÚSCULA ## Coloca em maiúsculas a primeira letra de cada palavra de um valor de texto +REPLACE = SUBSTITUIR ## Substitui caracteres no texto +REPLACEB = SUBSTITUIRB ## Substitui caracteres no texto +REPT = REPETIR ## Repete texto um determinado número de vezes +RIGHT = DIREITA ## Devolve os caracteres mais à direita de um valor de texto +RIGHTB = DIREITAB ## Devolve os caracteres mais à direita de um valor de texto +SEARCH = PROCURAR ## Localiza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas) +SEARCHB = PROCURARB ## Localiza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas) +SUBSTITUTE = SUBST ## Substitui texto novo por texto antigo numa cadeia de texto +T = T ## Converte os respectivos argumentos em texto +TEXT = TEXTO ## Formata um número e converte-o em texto +TRIM = COMPACTAR ## Remove espaços do texto +UPPER = MAIÚSCULAS ## Converte texto em maiúsculas +VALUE = VALOR ## Converte um argumento de texto num número diff --git a/extend/phpexcel/PHPExcel/locale/ru/config b/extend/phpexcel/PHPExcel/locale/ru/config new file mode 100755 index 0000000..6f6ace2 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/ru/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = р + + +## +## Excel Error Codes (For future use) +## +NULL = #ПУСТО! +DIV0 = #ДЕЛ/0! +VALUE = #ЗНАЧ! +REF = #ССЫЛ! +NAME = #ИМЯ? +NUM = #ЧИСЛО! +NA = #Н/Д diff --git a/extend/phpexcel/PHPExcel/locale/ru/functions b/extend/phpexcel/PHPExcel/locale/ru/functions new file mode 100755 index 0000000..bd63686 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/ru/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from information provided by web-junior (http://www.web-junior.net/) +## +## + + +## +## Add-in and Automation functions Функции надстроек и автоматизации +## +GETPIVOTDATA = ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ ## Возвращает данные, хранящиеся в отчете сводной таблицы. + + +## +## Cube functions Функции Куб +## +CUBEKPIMEMBER = КУБЭЛЕМЕНТКИП ## Возвращает свойство ключевого индикатора производительности «(КИП)» и отображает имя «КИП» в ячейке. «КИП» представляет собой количественную величину, такую как ежемесячная валовая прибыль или ежеквартальная текучесть кадров, используемой для контроля эффективности работы организации. +CUBEMEMBER = КУБЭЛЕМЕНТ ## Возвращает элемент или кортеж из куба. Используется для проверки существования элемента или кортежа в кубе. +CUBEMEMBERPROPERTY = КУБСВОЙСТВОЭЛЕМЕНТА ## Возвращает значение свойства элемента из куба. Используется для проверки существования имени элемента в кубе и возвращает указанное свойство для этого элемента. +CUBERANKEDMEMBER = КУБПОРЭЛЕМЕНТ ## Возвращает n-ый или ранжированный элемент в множество. Используется для возвращения одного или нескольких элементов в множество, например, лучшего продавца или 10 лучших студентов. +CUBESET = КУБМНОЖ ## Определяет вычислительное множество элементов или кортежей, отправляя на сервер выражение, которое создает множество, а затем возвращает его в Microsoft Office Excel. +CUBESETCOUNT = КУБЧИСЛОЭЛМНОЖ ## Возвращает число элементов множества. +CUBEVALUE = КУБЗНАЧЕНИЕ ## Возвращает обобщенное значение из куба. + + +## +## Database functions Функции для работы с базами данных +## +DAVERAGE = ДСРЗНАЧ ## Возвращает среднее значение выбранных записей базы данных. +DCOUNT = БСЧЁТ ## Подсчитывает количество числовых ячеек в базе данных. +DCOUNTA = БСЧЁТА ## Подсчитывает количество непустых ячеек в базе данных. +DGET = БИЗВЛЕЧЬ ## Извлекает из базы данных одну запись, удовлетворяющую заданному условию. +DMAX = ДМАКС ## Возвращает максимальное значение среди выделенных записей базы данных. +DMIN = ДМИН ## Возвращает минимальное значение среди выделенных записей базы данных. +DPRODUCT = БДПРОИЗВЕД ## Перемножает значения определенного поля в записях базы данных, удовлетворяющих условию. +DSTDEV = ДСТАНДОТКЛ ## Оценивает стандартное отклонение по выборке для выделенных записей базы данных. +DSTDEVP = ДСТАНДОТКЛП ## Вычисляет стандартное отклонение по генеральной совокупности для выделенных записей базы данных +DSUM = БДСУММ ## Суммирует числа в поле для записей базы данных, удовлетворяющих условию. +DVAR = БДДИСП ## Оценивает дисперсию по выборке из выделенных записей базы данных +DVARP = БДДИСПП ## Вычисляет дисперсию по генеральной совокупности для выделенных записей базы данных + + +## +## Date and time functions Функции даты и времени +## +DATE = ДАТА ## Возвращает заданную дату в числовом формате. +DATEVALUE = ДАТАЗНАЧ ## Преобразует дату из текстового формата в числовой формат. +DAY = ДЕНЬ ## Преобразует дату в числовом формате в день месяца. +DAYS360 = ДНЕЙ360 ## Вычисляет количество дней между двумя датами на основе 360-дневного года. +EDATE = ДАТАМЕС ## Возвращает дату в числовом формате, отстоящую на заданное число месяцев вперед или назад от начальной даты. +EOMONTH = КОНМЕСЯЦА ## Возвращает дату в числовом формате для последнего дня месяца, отстоящего вперед или назад на заданное число месяцев. +HOUR = ЧАС ## Преобразует дату в числовом формате в часы. +MINUTE = МИНУТЫ ## Преобразует дату в числовом формате в минуты. +MONTH = МЕСЯЦ ## Преобразует дату в числовом формате в месяцы. +NETWORKDAYS = ЧИСТРАБДНИ ## Возвращает количество рабочих дней между двумя датами. +NOW = ТДАТА ## Возвращает текущую дату и время в числовом формате. +SECOND = СЕКУНДЫ ## Преобразует дату в числовом формате в секунды. +TIME = ВРЕМЯ ## Возвращает заданное время в числовом формате. +TIMEVALUE = ВРЕМЗНАЧ ## Преобразует время из текстового формата в числовой формат. +TODAY = СЕГОДНЯ ## Возвращает текущую дату в числовом формате. +WEEKDAY = ДЕНЬНЕД ## Преобразует дату в числовом формате в день недели. +WEEKNUM = НОМНЕДЕЛИ ## Преобразует числовое представление в число, которое указывает, на какую неделю года приходится указанная дата. +WORKDAY = РАБДЕНЬ ## Возвращает дату в числовом формате, отстоящую вперед или назад на заданное количество рабочих дней. +YEAR = ГОД ## Преобразует дату в числовом формате в год. +YEARFRAC = ДОЛЯГОДА ## Возвращает долю года, которую составляет количество дней между начальной и конечной датами. + + +## +## Engineering functions Инженерные функции +## +BESSELI = БЕССЕЛЬ.I ## Возвращает модифицированную функцию Бесселя In(x). +BESSELJ = БЕССЕЛЬ.J ## Возвращает функцию Бесселя Jn(x). +BESSELK = БЕССЕЛЬ.K ## Возвращает модифицированную функцию Бесселя Kn(x). +BESSELY = БЕССЕЛЬ.Y ## Возвращает функцию Бесселя Yn(x). +BIN2DEC = ДВ.В.ДЕС ## Преобразует двоичное число в десятичное. +BIN2HEX = ДВ.В.ШЕСТН ## Преобразует двоичное число в шестнадцатеричное. +BIN2OCT = ДВ.В.ВОСЬМ ## Преобразует двоичное число в восьмеричное. +COMPLEX = КОМПЛЕКСН ## Преобразует коэффициенты при вещественной и мнимой частях комплексного числа в комплексное число. +CONVERT = ПРЕОБР ## Преобразует число из одной системы единиц измерения в другую. +DEC2BIN = ДЕС.В.ДВ ## Преобразует десятичное число в двоичное. +DEC2HEX = ДЕС.В.ШЕСТН ## Преобразует десятичное число в шестнадцатеричное. +DEC2OCT = ДЕС.В.ВОСЬМ ## Преобразует десятичное число в восьмеричное. +DELTA = ДЕЛЬТА ## Проверяет равенство двух значений. +ERF = ФОШ ## Возвращает функцию ошибки. +ERFC = ДФОШ ## Возвращает дополнительную функцию ошибки. +GESTEP = ПОРОГ ## Проверяет, не превышает ли данное число порогового значения. +HEX2BIN = ШЕСТН.В.ДВ ## Преобразует шестнадцатеричное число в двоичное. +HEX2DEC = ШЕСТН.В.ДЕС ## Преобразует шестнадцатеричное число в десятичное. +HEX2OCT = ШЕСТН.В.ВОСЬМ ## Преобразует шестнадцатеричное число в восьмеричное. +IMABS = МНИМ.ABS ## Возвращает абсолютную величину (модуль) комплексного числа. +IMAGINARY = МНИМ.ЧАСТЬ ## Возвращает коэффициент при мнимой части комплексного числа. +IMARGUMENT = МНИМ.АРГУМЕНТ ## Возвращает значение аргумента комплексного числа (тета) — угол, выраженный в радианах. +IMCONJUGATE = МНИМ.СОПРЯЖ ## Возвращает комплексно-сопряженное комплексное число. +IMCOS = МНИМ.COS ## Возвращает косинус комплексного числа. +IMDIV = МНИМ.ДЕЛ ## Возвращает частное от деления двух комплексных чисел. +IMEXP = МНИМ.EXP ## Возвращает экспоненту комплексного числа. +IMLN = МНИМ.LN ## Возвращает натуральный логарифм комплексного числа. +IMLOG10 = МНИМ.LOG10 ## Возвращает обычный (десятичный) логарифм комплексного числа. +IMLOG2 = МНИМ.LOG2 ## Возвращает двоичный логарифм комплексного числа. +IMPOWER = МНИМ.СТЕПЕНЬ ## Возвращает комплексное число, возведенное в целую степень. +IMPRODUCT = МНИМ.ПРОИЗВЕД ## Возвращает произведение от 2 до 29 комплексных чисел. +IMREAL = МНИМ.ВЕЩ ## Возвращает коэффициент при вещественной части комплексного числа. +IMSIN = МНИМ.SIN ## Возвращает синус комплексного числа. +IMSQRT = МНИМ.КОРЕНЬ ## Возвращает значение квадратного корня из комплексного числа. +IMSUB = МНИМ.РАЗН ## Возвращает разность двух комплексных чисел. +IMSUM = МНИМ.СУММ ## Возвращает сумму комплексных чисел. +OCT2BIN = ВОСЬМ.В.ДВ ## Преобразует восьмеричное число в двоичное. +OCT2DEC = ВОСЬМ.В.ДЕС ## Преобразует восьмеричное число в десятичное. +OCT2HEX = ВОСЬМ.В.ШЕСТН ## Преобразует восьмеричное число в шестнадцатеричное. + + +## +## Financial functions Финансовые функции +## +ACCRINT = НАКОПДОХОД ## Возвращает накопленный процент по ценным бумагам с периодической выплатой процентов. +ACCRINTM = НАКОПДОХОДПОГАШ ## Возвращает накопленный процент по ценным бумагам, проценты по которым выплачиваются в срок погашения. +AMORDEGRC = АМОРУМ ## Возвращает величину амортизации для каждого периода, используя коэффициент амортизации. +AMORLINC = АМОРУВ ## Возвращает величину амортизации для каждого периода. +COUPDAYBS = ДНЕЙКУПОНДО ## Возвращает количество дней от начала действия купона до даты соглашения. +COUPDAYS = ДНЕЙКУПОН ## Возвращает число дней в периоде купона, содержащем дату соглашения. +COUPDAYSNC = ДНЕЙКУПОНПОСЛЕ ## Возвращает число дней от даты соглашения до срока следующего купона. +COUPNCD = ДАТАКУПОНПОСЛЕ ## Возвращает следующую дату купона после даты соглашения. +COUPNUM = ЧИСЛКУПОН ## Возвращает количество купонов, которые могут быть оплачены между датой соглашения и сроком вступления в силу. +COUPPCD = ДАТАКУПОНДО ## Возвращает предыдущую дату купона перед датой соглашения. +CUMIPMT = ОБЩПЛАТ ## Возвращает общую выплату, произведенную между двумя периодическими выплатами. +CUMPRINC = ОБЩДОХОД ## Возвращает общую выплату по займу между двумя периодами. +DB = ФУО ## Возвращает величину амортизации актива для заданного периода, рассчитанную методом фиксированного уменьшения остатка. +DDB = ДДОБ ## Возвращает величину амортизации актива за данный период, используя метод двойного уменьшения остатка или иной явно указанный метод. +DISC = СКИДКА ## Возвращает норму скидки для ценных бумаг. +DOLLARDE = РУБЛЬ.ДЕС ## Преобразует цену в рублях, выраженную в виде дроби, в цену в рублях, выраженную десятичным числом. +DOLLARFR = РУБЛЬ.ДРОБЬ ## Преобразует цену в рублях, выраженную десятичным числом, в цену в рублях, выраженную в виде дроби. +DURATION = ДЛИТ ## Возвращает ежегодную продолжительность действия ценных бумаг с периодическими выплатами по процентам. +EFFECT = ЭФФЕКТ ## Возвращает действующие ежегодные процентные ставки. +FV = БС ## Возвращает будущую стоимость инвестиции. +FVSCHEDULE = БЗРАСПИС ## Возвращает будущую стоимость первоначальной основной суммы после начисления ряда сложных процентов. +INTRATE = ИНОРМА ## Возвращает процентную ставку для полностью инвестированных ценных бумаг. +IPMT = ПРПЛТ ## Возвращает величину выплаты прибыли на вложения за данный период. +IRR = ВСД ## Возвращает внутреннюю ставку доходности для ряда потоков денежных средств. +ISPMT = ПРОЦПЛАТ ## Вычисляет выплаты за указанный период инвестиции. +MDURATION = МДЛИТ ## Возвращает модифицированную длительность Маколея для ценных бумаг с предполагаемой номинальной стоимостью 100 рублей. +MIRR = МВСД ## Возвращает внутреннюю ставку доходности, при которой положительные и отрицательные денежные потоки имеют разные значения ставки. +NOMINAL = НОМИНАЛ ## Возвращает номинальную годовую процентную ставку. +NPER = КПЕР ## Возвращает общее количество периодов выплаты для данного вклада. +NPV = ЧПС ## Возвращает чистую приведенную стоимость инвестиции, основанной на серии периодических денежных потоков и ставке дисконтирования. +ODDFPRICE = ЦЕНАПЕРВНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным первым периодом. +ODDFYIELD = ДОХОДПЕРВНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным первым периодом. +ODDLPRICE = ЦЕНАПОСЛНЕРЕГ ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным последним периодом. +ODDLYIELD = ДОХОДПОСЛНЕРЕГ ## Возвращает доход по ценным бумагам с нерегулярным последним периодом. +PMT = ПЛТ ## Возвращает величину выплаты за один период аннуитета. +PPMT = ОСПЛТ ## Возвращает величину выплат в погашение основной суммы по инвестиции за заданный период. +PRICE = ЦЕНА ## Возвращает цену за 100 рублей нарицательной стоимости ценных бумаг, по которым производится периодическая выплата процентов. +PRICEDISC = ЦЕНАСКИДКА ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, на которые сделана скидка. +PRICEMAT = ЦЕНАПОГАШ ## Возвращает цену за 100 рублей номинальной стоимости ценных бумаг, проценты по которым выплачиваются в срок погашения. +PV = ПС ## Возвращает приведенную (к текущему моменту) стоимость инвестиции. +RATE = СТАВКА ## Возвращает процентную ставку по аннуитету за один период. +RECEIVED = ПОЛУЧЕНО ## Возвращает сумму, полученную к сроку погашения полностью обеспеченных ценных бумаг. +SLN = АПЛ ## Возвращает величину линейной амортизации актива за один период. +SYD = АСЧ ## Возвращает величину амортизации актива за данный период, рассчитанную методом суммы годовых чисел. +TBILLEQ = РАВНОКЧЕК ## Возвращает эквивалентный облигации доход по казначейскому чеку. +TBILLPRICE = ЦЕНАКЧЕК ## Возвращает цену за 100 рублей нарицательной стоимости для казначейского чека. +TBILLYIELD = ДОХОДКЧЕК ## Возвращает доход по казначейскому чеку. +VDB = ПУО ## Возвращает величину амортизации актива для указанного или частичного периода при использовании метода сокращающегося баланса. +XIRR = ЧИСТВНДОХ ## Возвращает внутреннюю ставку доходности для графика денежных потоков, которые не обязательно носят периодический характер. +XNPV = ЧИСТНЗ ## Возвращает чистую приведенную стоимость для денежных потоков, которые не обязательно являются периодическими. +YIELD = ДОХОД ## Возвращает доход от ценных бумаг, по которым производятся периодические выплаты процентов. +YIELDDISC = ДОХОДСКИДКА ## Возвращает годовой доход по ценным бумагам, на которые сделана скидка (пример — казначейские чеки). +YIELDMAT = ДОХОДПОГАШ ## Возвращает годовой доход от ценных бумаг, проценты по которым выплачиваются в срок погашения. + + +## +## Information functions Информационные функции +## +CELL = ЯЧЕЙКА ## Возвращает информацию о формате, расположении или содержимом ячейки. +ERROR.TYPE = ТИП.ОШИБКИ ## Возвращает числовой код, соответствующий типу ошибки. +INFO = ИНФОРМ ## Возвращает информацию о текущей операционной среде. +ISBLANK = ЕПУСТО ## Возвращает значение ИСТИНА, если аргумент является ссылкой на пустую ячейку. +ISERR = ЕОШ ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки, кроме #Н/Д. +ISERROR = ЕОШИБКА ## Возвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки. +ISEVEN = ЕЧЁТН ## Возвращает значение ИСТИНА, если значение аргумента является четным числом. +ISLOGICAL = ЕЛОГИЧ ## Возвращает значение ИСТИНА, если аргумент ссылается на логическое значение. +ISNA = ЕНД ## Возвращает значение ИСТИНА, если аргумент ссылается на значение ошибки #Н/Д. +ISNONTEXT = ЕНЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента не является текстом. +ISNUMBER = ЕЧИСЛО ## Возвращает значение ИСТИНА, если аргумент ссылается на число. +ISODD = ЕНЕЧЁТ ## Возвращает значение ИСТИНА, если значение аргумента является нечетным числом. +ISREF = ЕССЫЛКА ## Возвращает значение ИСТИНА, если значение аргумента является ссылкой. +ISTEXT = ЕТЕКСТ ## Возвращает значение ИСТИНА, если значение аргумента является текстом. +N = Ч ## Возвращает значение, преобразованное в число. +NA = НД ## Возвращает значение ошибки #Н/Д. +TYPE = ТИП ## Возвращает число, обозначающее тип данных значения. + + +## +## Logical functions Логические функции +## +AND = И ## Renvoie VRAI si tous ses arguments sont VRAI. +FALSE = ЛОЖЬ ## Возвращает логическое значение ЛОЖЬ. +IF = ЕСЛИ ## Выполняет проверку условия. +IFERROR = ЕСЛИОШИБКА ## Возвращает введённое значение, если вычисление по формуле вызывает ошибку; в противном случае функция возвращает результат вычисления. +NOT = НЕ ## Меняет логическое значение своего аргумента на противоположное. +OR = ИЛИ ## Возвращает значение ИСТИНА, если хотя бы один аргумент имеет значение ИСТИНА. +TRUE = ИСТИНА ## Возвращает логическое значение ИСТИНА. + + +## +## Lookup and reference functions Функции ссылки и поиска +## +ADDRESS = АДРЕС ## Возвращает ссылку на отдельную ячейку листа в виде текста. +AREAS = ОБЛАСТИ ## Возвращает количество областей в ссылке. +CHOOSE = ВЫБОР ## Выбирает значение из списка значений по индексу. +COLUMN = СТОЛБЕЦ ## Возвращает номер столбца, на который указывает ссылка. +COLUMNS = ЧИСЛСТОЛБ ## Возвращает количество столбцов в ссылке. +HLOOKUP = ГПР ## Ищет в первой строке массива и возвращает значение отмеченной ячейки +HYPERLINK = ГИПЕРССЫЛКА ## Создает ссылку, открывающую документ, который находится на сервере сети, в интрасети или в Интернете. +INDEX = ИНДЕКС ## Использует индекс для выбора значения из ссылки или массива. +INDIRECT = ДВССЫЛ ## Возвращает ссылку, заданную текстовым значением. +LOOKUP = ПРОСМОТР ## Ищет значения в векторе или массиве. +MATCH = ПОИСКПОЗ ## Ищет значения в ссылке или массиве. +OFFSET = СМЕЩ ## Возвращает смещение ссылки относительно заданной ссылки. +ROW = СТРОКА ## Возвращает номер строки, определяемой ссылкой. +ROWS = ЧСТРОК ## Возвращает количество строк в ссылке. +RTD = ДРВ ## Извлекает данные реального времени из программ, поддерживающих автоматизацию COM (Программирование объектов. Стандартное средство для работы с объектами некоторого приложения из другого приложения или средства разработки. Программирование объектов (ранее называемое программированием OLE) является функцией модели COM (Component Object Model, модель компонентных объектов).). +TRANSPOSE = ТРАНСП ## Возвращает транспонированный массив. +VLOOKUP = ВПР ## Ищет значение в первом столбце массива и возвращает значение из ячейки в найденной строке и указанном столбце. + + +## +## Math and trigonometry functions Математические и тригонометрические функции +## +ABS = ABS ## Возвращает модуль (абсолютную величину) числа. +ACOS = ACOS ## Возвращает арккосинус числа. +ACOSH = ACOSH ## Возвращает гиперболический арккосинус числа. +ASIN = ASIN ## Возвращает арксинус числа. +ASINH = ASINH ## Возвращает гиперболический арксинус числа. +ATAN = ATAN ## Возвращает арктангенс числа. +ATAN2 = ATAN2 ## Возвращает арктангенс для заданных координат x и y. +ATANH = ATANH ## Возвращает гиперболический арктангенс числа. +CEILING = ОКРВВЕРХ ## Округляет число до ближайшего целого или до ближайшего кратного указанному значению. +COMBIN = ЧИСЛКОМБ ## Возвращает количество комбинаций для заданного числа объектов. +COS = COS ## Возвращает косинус числа. +COSH = COSH ## Возвращает гиперболический косинус числа. +DEGREES = ГРАДУСЫ ## Преобразует радианы в градусы. +EVEN = ЧЁТН ## Округляет число до ближайшего четного целого. +EXP = EXP ## Возвращает число e, возведенное в указанную степень. +FACT = ФАКТР ## Возвращает факториал числа. +FACTDOUBLE = ДВФАКТР ## Возвращает двойной факториал числа. +FLOOR = ОКРВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. +GCD = НОД ## Возвращает наибольший общий делитель. +INT = ЦЕЛОЕ ## Округляет число до ближайшего меньшего целого. +LCM = НОК ## Возвращает наименьшее общее кратное. +LN = LN ## Возвращает натуральный логарифм числа. +LOG = LOG ## Возвращает логарифм числа по заданному основанию. +LOG10 = LOG10 ## Возвращает десятичный логарифм числа. +MDETERM = МОПРЕД ## Возвращает определитель матрицы массива. +MINVERSE = МОБР ## Возвращает обратную матрицу массива. +MMULT = МУМНОЖ ## Возвращает произведение матриц двух массивов. +MOD = ОСТАТ ## Возвращает остаток от деления. +MROUND = ОКРУГЛТ ## Возвращает число, округленное с требуемой точностью. +MULTINOMIAL = МУЛЬТИНОМ ## Возвращает мультиномиальный коэффициент множества чисел. +ODD = НЕЧЁТ ## Округляет число до ближайшего нечетного целого. +PI = ПИ ## Возвращает число пи. +POWER = СТЕПЕНЬ ## Возвращает результат возведения числа в степень. +PRODUCT = ПРОИЗВЕД ## Возвращает произведение аргументов. +QUOTIENT = ЧАСТНОЕ ## Возвращает целую часть частного при делении. +RADIANS = РАДИАНЫ ## Преобразует градусы в радианы. +RAND = СЛЧИС ## Возвращает случайное число в интервале от 0 до 1. +RANDBETWEEN = СЛУЧМЕЖДУ ## Возвращает случайное число в интервале между двумя заданными числами. +ROMAN = РИМСКОЕ ## Преобразует арабские цифры в римские в виде текста. +ROUND = ОКРУГЛ ## Округляет число до указанного количества десятичных разрядов. +ROUNDDOWN = ОКРУГЛВНИЗ ## Округляет число до ближайшего меньшего по модулю значения. +ROUNDUP = ОКРУГЛВВЕРХ ## Округляет число до ближайшего большего по модулю значения. +SERIESSUM = РЯД.СУММ ## Возвращает сумму степенного ряда, вычисленную по формуле. +SIGN = ЗНАК ## Возвращает знак числа. +SIN = SIN ## Возвращает синус заданного угла. +SINH = SINH ## Возвращает гиперболический синус числа. +SQRT = КОРЕНЬ ## Возвращает положительное значение квадратного корня. +SQRTPI = КОРЕНЬПИ ## Возвращает квадратный корень из значения выражения (число * ПИ). +SUBTOTAL = ПРОМЕЖУТОЧНЫЕ.ИТОГИ ## Возвращает промежуточный итог в списке или базе данных. +SUM = СУММ ## Суммирует аргументы. +SUMIF = СУММЕСЛИ ## Суммирует ячейки, удовлетворяющие заданному условию. +SUMIFS = СУММЕСЛИМН ## Суммирует диапазон ячеек, удовлетворяющих нескольким условиям. +SUMPRODUCT = СУММПРОИЗВ ## Возвращает сумму произведений соответствующих элементов массивов. +SUMSQ = СУММКВ ## Возвращает сумму квадратов аргументов. +SUMX2MY2 = СУММРАЗНКВ ## Возвращает сумму разностей квадратов соответствующих значений в двух массивах. +SUMX2PY2 = СУММСУММКВ ## Возвращает сумму сумм квадратов соответствующих элементов двух массивов. +SUMXMY2 = СУММКВРАЗН ## Возвращает сумму квадратов разностей соответствующих значений в двух массивах. +TAN = TAN ## Возвращает тангенс числа. +TANH = TANH ## Возвращает гиперболический тангенс числа. +TRUNC = ОТБР ## Отбрасывает дробную часть числа. + + +## +## Statistical functions Статистические функции +## +AVEDEV = СРОТКЛ ## Возвращает среднее арифметическое абсолютных значений отклонений точек данных от среднего. +AVERAGE = СРЗНАЧ ## Возвращает среднее арифметическое аргументов. +AVERAGEA = СРЗНАЧА ## Возвращает среднее арифметическое аргументов, включая числа, текст и логические значения. +AVERAGEIF = СРЗНАЧЕСЛИ ## Возвращает среднее значение (среднее арифметическое) всех ячеек в диапазоне, которые удовлетворяют данному условию. +AVERAGEIFS = СРЗНАЧЕСЛИМН ## Возвращает среднее значение (среднее арифметическое) всех ячеек, которые удовлетворяют нескольким условиям. +BETADIST = БЕТАРАСП ## Возвращает интегральную функцию бета-распределения. +BETAINV = БЕТАОБР ## Возвращает обратную интегральную функцию указанного бета-распределения. +BINOMDIST = БИНОМРАСП ## Возвращает отдельное значение биномиального распределения. +CHIDIST = ХИ2РАСП ## Возвращает одностороннюю вероятность распределения хи-квадрат. +CHIINV = ХИ2ОБР ## Возвращает обратное значение односторонней вероятности распределения хи-квадрат. +CHITEST = ХИ2ТЕСТ ## Возвращает тест на независимость. +CONFIDENCE = ДОВЕРИТ ## Возвращает доверительный интервал для среднего значения по генеральной совокупности. +CORREL = КОРРЕЛ ## Возвращает коэффициент корреляции между двумя множествами данных. +COUNT = СЧЁТ ## Подсчитывает количество чисел в списке аргументов. +COUNTA = СЧЁТЗ ## Подсчитывает количество значений в списке аргументов. +COUNTBLANK = СЧИТАТЬПУСТОТЫ ## Подсчитывает количество пустых ячеек в диапазоне +COUNTIF = СЧЁТЕСЛИ ## Подсчитывает количество ячеек в диапазоне, удовлетворяющих заданному условию +COUNTIFS = СЧЁТЕСЛИМН ## Подсчитывает количество ячеек внутри диапазона, удовлетворяющих нескольким условиям. +COVAR = КОВАР ## Возвращает ковариацию, среднее произведений парных отклонений +CRITBINOM = КРИТБИНОМ ## Возвращает наименьшее значение, для которого интегральное биномиальное распределение меньше или равно заданному критерию. +DEVSQ = КВАДРОТКЛ ## Возвращает сумму квадратов отклонений. +EXPONDIST = ЭКСПРАСП ## Возвращает экспоненциальное распределение. +FDIST = FРАСП ## Возвращает F-распределение вероятности. +FINV = FРАСПОБР ## Возвращает обратное значение для F-распределения вероятности. +FISHER = ФИШЕР ## Возвращает преобразование Фишера. +FISHERINV = ФИШЕРОБР ## Возвращает обратное преобразование Фишера. +FORECAST = ПРЕДСКАЗ ## Возвращает значение линейного тренда. +FREQUENCY = ЧАСТОТА ## Возвращает распределение частот в виде вертикального массива. +FTEST = ФТЕСТ ## Возвращает результат F-теста. +GAMMADIST = ГАММАРАСП ## Возвращает гамма-распределение. +GAMMAINV = ГАММАОБР ## Возвращает обратное гамма-распределение. +GAMMALN = ГАММАНЛОГ ## Возвращает натуральный логарифм гамма функции, Γ(x). +GEOMEAN = СРГЕОМ ## Возвращает среднее геометрическое. +GROWTH = РОСТ ## Возвращает значения в соответствии с экспоненциальным трендом. +HARMEAN = СРГАРМ ## Возвращает среднее гармоническое. +HYPGEOMDIST = ГИПЕРГЕОМЕТ ## Возвращает гипергеометрическое распределение. +INTERCEPT = ОТРЕЗОК ## Возвращает отрезок, отсекаемый на оси линией линейной регрессии. +KURT = ЭКСЦЕСС ## Возвращает эксцесс множества данных. +LARGE = НАИБОЛЬШИЙ ## Возвращает k-ое наибольшее значение в множестве данных. +LINEST = ЛИНЕЙН ## Возвращает параметры линейного тренда. +LOGEST = ЛГРФПРИБЛ ## Возвращает параметры экспоненциального тренда. +LOGINV = ЛОГНОРМОБР ## Возвращает обратное логарифмическое нормальное распределение. +LOGNORMDIST = ЛОГНОРМРАСП ## Возвращает интегральное логарифмическое нормальное распределение. +MAX = МАКС ## Возвращает наибольшее значение в списке аргументов. +MAXA = МАКСА ## Возвращает наибольшее значение в списке аргументов, включая числа, текст и логические значения. +MEDIAN = МЕДИАНА ## Возвращает медиану заданных чисел. +MIN = МИН ## Возвращает наименьшее значение в списке аргументов. +MINA = МИНА ## Возвращает наименьшее значение в списке аргументов, включая числа, текст и логические значения. +MODE = МОДА ## Возвращает значение моды множества данных. +NEGBINOMDIST = ОТРБИНОМРАСП ## Возвращает отрицательное биномиальное распределение. +NORMDIST = НОРМРАСП ## Возвращает нормальную функцию распределения. +NORMINV = НОРМОБР ## Возвращает обратное нормальное распределение. +NORMSDIST = НОРМСТРАСП ## Возвращает стандартное нормальное интегральное распределение. +NORMSINV = НОРМСТОБР ## Возвращает обратное значение стандартного нормального распределения. +PEARSON = ПИРСОН ## Возвращает коэффициент корреляции Пирсона. +PERCENTILE = ПЕРСЕНТИЛЬ ## Возвращает k-ую персентиль для значений диапазона. +PERCENTRANK = ПРОЦЕНТРАНГ ## Возвращает процентную норму значения в множестве данных. +PERMUT = ПЕРЕСТ ## Возвращает количество перестановок для заданного числа объектов. +POISSON = ПУАССОН ## Возвращает распределение Пуассона. +PROB = ВЕРОЯТНОСТЬ ## Возвращает вероятность того, что значение из диапазона находится внутри заданных пределов. +QUARTILE = КВАРТИЛЬ ## Возвращает квартиль множества данных. +RANK = РАНГ ## Возвращает ранг числа в списке чисел. +RSQ = КВПИРСОН ## Возвращает квадрат коэффициента корреляции Пирсона. +SKEW = СКОС ## Возвращает асимметрию распределения. +SLOPE = НАКЛОН ## Возвращает наклон линии линейной регрессии. +SMALL = НАИМЕНЬШИЙ ## Возвращает k-ое наименьшее значение в множестве данных. +STANDARDIZE = НОРМАЛИЗАЦИЯ ## Возвращает нормализованное значение. +STDEV = СТАНДОТКЛОН ## Оценивает стандартное отклонение по выборке. +STDEVA = СТАНДОТКЛОНА ## Оценивает стандартное отклонение по выборке, включая числа, текст и логические значения. +STDEVP = СТАНДОТКЛОНП ## Вычисляет стандартное отклонение по генеральной совокупности. +STDEVPA = СТАНДОТКЛОНПА ## Вычисляет стандартное отклонение по генеральной совокупности, включая числа, текст и логические значения. +STEYX = СТОШYX ## Возвращает стандартную ошибку предсказанных значений y для каждого значения x в регрессии. +TDIST = СТЬЮДРАСП ## Возвращает t-распределение Стьюдента. +TINV = СТЬЮДРАСПОБР ## Возвращает обратное t-распределение Стьюдента. +TREND = ТЕНДЕНЦИЯ ## Возвращает значения в соответствии с линейным трендом. +TRIMMEAN = УРЕЗСРЕДНЕЕ ## Возвращает среднее внутренности множества данных. +TTEST = ТТЕСТ ## Возвращает вероятность, соответствующую критерию Стьюдента. +VAR = ДИСП ## Оценивает дисперсию по выборке. +VARA = ДИСПА ## Оценивает дисперсию по выборке, включая числа, текст и логические значения. +VARP = ДИСПР ## Вычисляет дисперсию для генеральной совокупности. +VARPA = ДИСПРА ## Вычисляет дисперсию для генеральной совокупности, включая числа, текст и логические значения. +WEIBULL = ВЕЙБУЛЛ ## Возвращает распределение Вейбулла. +ZTEST = ZТЕСТ ## Возвращает двустороннее P-значение z-теста. + + +## +## Text functions Текстовые функции +## +ASC = ASC ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полноширинные (двухбайтовые) знаки в полуширинные (однобайтовые). +BAHTTEXT = БАТТЕКСТ ## Преобразует число в текст, используя денежный формат ß (БАТ). +CHAR = СИМВОЛ ## Возвращает знак с заданным кодом. +CLEAN = ПЕЧСИМВ ## Удаляет все непечатаемые знаки из текста. +CODE = КОДСИМВ ## Возвращает числовой код первого знака в текстовой строке. +CONCATENATE = СЦЕПИТЬ ## Объединяет несколько текстовых элементов в один. +DOLLAR = РУБЛЬ ## Преобразует число в текст, используя денежный формат. +EXACT = СОВПАД ## Проверяет идентичность двух текстовых значений. +FIND = НАЙТИ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). +FINDB = НАЙТИБ ## Ищет вхождения одного текстового значения в другом (с учетом регистра). +FIXED = ФИКСИРОВАННЫЙ ## Форматирует число и преобразует его в текст с заданным числом десятичных знаков. +JIS = JIS ## Для языков с двухбайтовыми наборами знаков (например, катакана) преобразует полуширинные (однобайтовые) знаки в текстовой строке в полноширинные (двухбайтовые). +LEFT = ЛЕВСИМВ ## Возвращает крайние слева знаки текстового значения. +LEFTB = ЛЕВБ ## Возвращает крайние слева знаки текстового значения. +LEN = ДЛСТР ## Возвращает количество знаков в текстовой строке. +LENB = ДЛИНБ ## Возвращает количество знаков в текстовой строке. +LOWER = СТРОЧН ## Преобразует все буквы текста в строчные. +MID = ПСТР ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. +MIDB = ПСТРБ ## Возвращает заданное число знаков из строки текста, начиная с указанной позиции. +PHONETIC = PHONETIC ## Извлекает фонетические (фуригана) знаки из текстовой строки. +PROPER = ПРОПНАЧ ## Преобразует первую букву в каждом слове текста в прописную. +REPLACE = ЗАМЕНИТЬ ## Заменяет знаки в тексте. +REPLACEB = ЗАМЕНИТЬБ ## Заменяет знаки в тексте. +REPT = ПОВТОР ## Повторяет текст заданное число раз. +RIGHT = ПРАВСИМВ ## Возвращает крайние справа знаки текстовой строки. +RIGHTB = ПРАВБ ## Возвращает крайние справа знаки текстовой строки. +SEARCH = ПОИСК ## Ищет вхождения одного текстового значения в другом (без учета регистра). +SEARCHB = ПОИСКБ ## Ищет вхождения одного текстового значения в другом (без учета регистра). +SUBSTITUTE = ПОДСТАВИТЬ ## Заменяет в текстовой строке старый текст новым. +T = Т ## Преобразует аргументы в текст. +TEXT = ТЕКСТ ## Форматирует число и преобразует его в текст. +TRIM = СЖПРОБЕЛЫ ## Удаляет из текста пробелы. +UPPER = ПРОПИСН ## Преобразует все буквы текста в прописные. +VALUE = ЗНАЧЕН ## Преобразует текстовый аргумент в число. diff --git a/extend/phpexcel/PHPExcel/locale/sv/config b/extend/phpexcel/PHPExcel/locale/sv/config new file mode 100755 index 0000000..5d1a9a9 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/sv/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = kr + + +## +## Excel Error Codes (For future use) +## +NULL = #Skärning! +DIV0 = #Division/0! +VALUE = #Värdefel! +REF = #Referens! +NAME = #Namn? +NUM = #Ogiltigt! +NA = #Saknas! diff --git a/extend/phpexcel/PHPExcel/locale/sv/functions b/extend/phpexcel/PHPExcel/locale/sv/functions new file mode 100755 index 0000000..9af37d8 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/sv/functions @@ -0,0 +1,408 @@ +## +## Add-in and Automation functions Tilläggs- och automatiseringsfunktioner +## +GETPIVOTDATA = HÄMTA.PIVOTDATA ## Returnerar data som lagrats i en pivottabellrapport + + +## +## Cube functions Kubfunktioner +## +CUBEKPIMEMBER = KUBKPIMEDLEM ## Returnerar namn, egenskap och mått för en KPI och visar namnet och egenskapen i cellen. En KPI, eller prestandaindikator, är ett kvantifierbart mått, t.ex. månatlig bruttovinst eller personalomsättning per kvartal, som används för att analysera ett företags resultat. +CUBEMEMBER = KUBMEDLEM ## Returnerar en medlem eller ett par i en kubhierarki. Används för att verifiera att medlemmen eller paret finns i kuben. +CUBEMEMBERPROPERTY = KUBMEDLEMSEGENSKAP ## Returnerar värdet för en medlemsegenskap i kuben. Används för att verifiera att ett medlemsnamn finns i kuben, samt för att returnera den angivna egenskapen för medlemmen. +CUBERANKEDMEMBER = KUBRANGORDNADMEDLEM ## Returnerar den n:te, eller rangordnade, medlemmen i en uppsättning. Används för att returnera ett eller flera element i en uppsättning, till exempelvis den bästa försäljaren eller de tio bästa eleverna. +CUBESET = KUBINSTÄLLNING ## Definierar en beräknad uppsättning medlemmar eller par genom att skicka ett bestämt uttryck till kuben på servern, som skapar uppsättningen och sedan returnerar den till Microsoft Office Excel. +CUBESETCOUNT = KUBINSTÄLLNINGANTAL ## Returnerar antalet objekt i en uppsättning. +CUBEVALUE = KUBVÄRDE ## Returnerar ett mängdvärde från en kub. + + +## +## Database functions Databasfunktioner +## +DAVERAGE = DMEDEL ## Returnerar medelvärdet av databasposterna +DCOUNT = DANTAL ## Räknar antalet celler som innehåller tal i en databas +DCOUNTA = DANTALV ## Räknar ifyllda celler i en databas +DGET = DHÄMTA ## Hämtar en enstaka post från en databas som uppfyller de angivna villkoren +DMAX = DMAX ## Returnerar det största värdet från databasposterna +DMIN = DMIN ## Returnerar det minsta värdet från databasposterna +DPRODUCT = DPRODUKT ## Multiplicerar värdena i ett visst fält i poster som uppfyller villkoret +DSTDEV = DSTDAV ## Uppskattar standardavvikelsen baserat på ett urval av databasposterna +DSTDEVP = DSTDAVP ## Beräknar standardavvikelsen utifrån hela populationen av valda databasposter +DSUM = DSUMMA ## Summerar talen i kolumnfält i databasposter som uppfyller villkoret +DVAR = DVARIANS ## Uppskattar variansen baserat på ett urval av databasposterna +DVARP = DVARIANSP ## Beräknar variansen utifrån hela populationen av valda databasposter + + +## +## Date and time functions Tid- och datumfunktioner +## +DATE = DATUM ## Returnerar ett serienummer för ett visst datum +DATEVALUE = DATUMVÄRDE ## Konverterar ett datum i textformat till ett serienummer +DAY = DAG ## Konverterar ett serienummer till dag i månaden +DAYS360 = DAGAR360 ## Beräknar antalet dagar mellan två datum baserat på ett 360-dagarsår +EDATE = EDATUM ## Returnerar serienumret för ett datum som infaller ett visst antal månader före eller efter startdatumet +EOMONTH = SLUTMÅNAD ## Returnerar serienumret för sista dagen i månaden ett visst antal månader tidigare eller senare +HOUR = TIMME ## Konverterar ett serienummer till en timme +MINUTE = MINUT ## Konverterar ett serienummer till en minut +MONTH = MÅNAD ## Konverterar ett serienummer till en månad +NETWORKDAYS = NETTOARBETSDAGAR ## Returnerar antalet hela arbetsdagar mellan två datum +NOW = NU ## Returnerar serienumret för dagens datum och aktuell tid +SECOND = SEKUND ## Konverterar ett serienummer till en sekund +TIME = KLOCKSLAG ## Returnerar serienumret för en viss tid +TIMEVALUE = TIDVÄRDE ## Konverterar en tid i textformat till ett serienummer +TODAY = IDAG ## Returnerar serienumret för dagens datum +WEEKDAY = VECKODAG ## Konverterar ett serienummer till en dag i veckan +WEEKNUM = VECKONR ## Konverterar ett serienummer till ett veckonummer +WORKDAY = ARBETSDAGAR ## Returnerar serienumret för ett datum ett visst antal arbetsdagar tidigare eller senare +YEAR = ÅR ## Konverterar ett serienummer till ett år +YEARFRAC = ÅRDEL ## Returnerar en del av ett år som representerar antalet hela dagar mellan start- och slutdatum + + +## +## Engineering functions Tekniska funktioner +## +BESSELI = BESSELI ## Returnerar den modifierade Bessel-funktionen In(x) +BESSELJ = BESSELJ ## Returnerar Bessel-funktionen Jn(x) +BESSELK = BESSELK ## Returnerar den modifierade Bessel-funktionen Kn(x) +BESSELY = BESSELY ## Returnerar Bessel-funktionen Yn(x) +BIN2DEC = BIN.TILL.DEC ## Omvandlar ett binärt tal till decimalt +BIN2HEX = BIN.TILL.HEX ## Omvandlar ett binärt tal till hexadecimalt +BIN2OCT = BIN.TILL.OKT ## Omvandlar ett binärt tal till oktalt +COMPLEX = KOMPLEX ## Omvandlar reella och imaginära koefficienter till ett komplext tal +CONVERT = KONVERTERA ## Omvandlar ett tal från ett måttsystem till ett annat +DEC2BIN = DEC.TILL.BIN ## Omvandlar ett decimalt tal till binärt +DEC2HEX = DEC.TILL.HEX ## Omvandlar ett decimalt tal till hexadecimalt +DEC2OCT = DEC.TILL.OKT ## Omvandlar ett decimalt tal till oktalt +DELTA = DELTA ## Testar om två värden är lika +ERF = FELF ## Returnerar felfunktionen +ERFC = FELFK ## Returnerar den komplementära felfunktionen +GESTEP = SLSTEG ## Testar om ett tal är större än ett tröskelvärde +HEX2BIN = HEX.TILL.BIN ## Omvandlar ett hexadecimalt tal till binärt +HEX2DEC = HEX.TILL.DEC ## Omvandlar ett hexadecimalt tal till decimalt +HEX2OCT = HEX.TILL.OKT ## Omvandlar ett hexadecimalt tal till oktalt +IMABS = IMABS ## Returnerar absolutvärdet (modulus) för ett komplext tal +IMAGINARY = IMAGINÄR ## Returnerar den imaginära koefficienten för ett komplext tal +IMARGUMENT = IMARGUMENT ## Returnerar det komplexa talets argument, en vinkel uttryckt i radianer +IMCONJUGATE = IMKONJUGAT ## Returnerar det komplexa talets konjugat +IMCOS = IMCOS ## Returnerar cosinus för ett komplext tal +IMDIV = IMDIV ## Returnerar kvoten för två komplexa tal +IMEXP = IMEUPPHÖJT ## Returnerar exponenten för ett komplext tal +IMLN = IMLN ## Returnerar den naturliga logaritmen för ett komplext tal +IMLOG10 = IMLOG10 ## Returnerar 10-logaritmen för ett komplext tal +IMLOG2 = IMLOG2 ## Returnerar 2-logaritmen för ett komplext tal +IMPOWER = IMUPPHÖJT ## Returnerar ett komplext tal upphöjt till en exponent +IMPRODUCT = IMPRODUKT ## Returnerar produkten av komplexa tal +IMREAL = IMREAL ## Returnerar den reella koefficienten för ett komplext tal +IMSIN = IMSIN ## Returnerar sinus för ett komplext tal +IMSQRT = IMROT ## Returnerar kvadratroten av ett komplext tal +IMSUB = IMDIFF ## Returnerar differensen mellan två komplexa tal +IMSUM = IMSUM ## Returnerar summan av komplexa tal +OCT2BIN = OKT.TILL.BIN ## Omvandlar ett oktalt tal till binärt +OCT2DEC = OKT.TILL.DEC ## Omvandlar ett oktalt tal till decimalt +OCT2HEX = OKT.TILL.HEX ## Omvandlar ett oktalt tal till hexadecimalt + + +## +## Financial functions Finansiella funktioner +## +ACCRINT = UPPLRÄNTA ## Returnerar den upplupna räntan för värdepapper med periodisk ränta +ACCRINTM = UPPLOBLRÄNTA ## Returnerar den upplupna räntan för ett värdepapper som ger avkastning på förfallodagen +AMORDEGRC = AMORDEGRC ## Returnerar avskrivningen för varje redovisningsperiod med hjälp av en avskrivningskoefficient +AMORLINC = AMORLINC ## Returnerar avskrivningen för varje redovisningsperiod +COUPDAYBS = KUPDAGBB ## Returnerar antal dagar från början av kupongperioden till likviddagen +COUPDAYS = KUPDAGARS ## Returnerar antalet dagar i kupongperioden som innehåller betalningsdatumet +COUPDAYSNC = KUPDAGNK ## Returnerar antalet dagar från betalningsdatumet till nästa kupongdatum +COUPNCD = KUPNKD ## Returnerar nästa kupongdatum efter likviddagen +COUPNUM = KUPANT ## Returnerar kuponger som förfaller till betalning mellan likviddagen och förfallodagen +COUPPCD = KUPFKD ## Returnerar föregående kupongdatum före likviddagen +CUMIPMT = KUMRÄNTA ## Returnerar den ackumulerade räntan som betalats mellan två perioder +CUMPRINC = KUMPRIS ## Returnerar det ackumulerade kapitalbeloppet som betalats på ett lån mellan två perioder +DB = DB ## Returnerar avskrivningen för en tillgång under en angiven tid enligt metoden för fast degressiv avskrivning +DDB = DEGAVSKR ## Returnerar en tillgångs värdeminskning under en viss period med hjälp av dubbel degressiv avskrivning eller någon annan metod som du anger +DISC = DISK ## Returnerar diskonteringsräntan för ett värdepapper +DOLLARDE = DECTAL ## Omvandlar ett pris uttryckt som ett bråk till ett decimaltal +DOLLARFR = BRÅK ## Omvandlar ett pris i kronor uttryckt som ett decimaltal till ett bråk +DURATION = LÖPTID ## Returnerar den årliga löptiden för en säkerhet med periodiska räntebetalningar +EFFECT = EFFRÄNTA ## Returnerar den årliga effektiva räntesatsen +FV = SLUTVÄRDE ## Returnerar det framtida värdet på en investering +FVSCHEDULE = FÖRRÄNTNING ## Returnerar det framtida värdet av ett begynnelsekapital beräknat på olika räntenivåer +INTRATE = ÅRSRÄNTA ## Returnerar räntesatsen för ett betalt värdepapper +IPMT = RBETALNING ## Returnerar räntedelen av en betalning för en given period +IRR = IR ## Returnerar internräntan för en serie betalningar +ISPMT = RALÅN ## Beräknar räntan som har betalats under en specifik betalningsperiod +MDURATION = MLÖPTID ## Returnerar den modifierade Macauley-löptiden för ett värdepapper med det antagna nominella värdet 100 kr +MIRR = MODIR ## Returnerar internräntan där positiva och negativa betalningar finansieras med olika räntor +NOMINAL = NOMRÄNTA ## Returnerar den årliga nominella räntesatsen +NPER = PERIODER ## Returnerar antalet perioder för en investering +NPV = NETNUVÄRDE ## Returnerar nuvärdet av en serie periodiska betalningar vid en given diskonteringsränta +ODDFPRICE = UDDAFPRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper med en udda första period +ODDFYIELD = UDDAFAVKASTNING ## Returnerar avkastningen för en säkerhet med en udda första period +ODDLPRICE = UDDASPRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper med en udda sista period +ODDLYIELD = UDDASAVKASTNING ## Returnerar avkastningen för en säkerhet med en udda sista period +PMT = BETALNING ## Returnerar den periodiska betalningen för en annuitet +PPMT = AMORT ## Returnerar amorteringsdelen av en annuitetsbetalning för en given period +PRICE = PRIS ## Returnerar priset per 100 kr nominellt värde för ett värdepapper som ger periodisk ränta +PRICEDISC = PRISDISK ## Returnerar priset per 100 kr nominellt värde för ett diskonterat värdepapper +PRICEMAT = PRISFÖRF ## Returnerar priset per 100 kr nominellt värde för ett värdepapper som ger ränta på förfallodagen +PV = PV ## Returnerar nuvärdet av en serie lika stora periodiska betalningar +RATE = RÄNTA ## Returnerar räntesatsen per period i en annuitet +RECEIVED = BELOPP ## Returnerar beloppet som utdelas på förfallodagen för ett betalat värdepapper +SLN = LINAVSKR ## Returnerar den linjära avskrivningen för en tillgång under en period +SYD = ÅRSAVSKR ## Returnerar den årliga avskrivningssumman för en tillgång under en angiven period +TBILLEQ = SSVXEKV ## Returnerar avkastningen motsvarande en obligation för en statsskuldväxel +TBILLPRICE = SSVXPRIS ## Returnerar priset per 100 kr nominellt värde för en statsskuldväxel +TBILLYIELD = SSVXRÄNTA ## Returnerar avkastningen för en statsskuldväxel +VDB = VDEGRAVSKR ## Returnerar avskrivningen för en tillgång under en angiven period (med degressiv avskrivning) +XIRR = XIRR ## Returnerar internräntan för en serie betalningar som inte nödvändigtvis är periodiska +XNPV = XNUVÄRDE ## Returnerar det nuvarande nettovärdet för en serie betalningar som inte nödvändigtvis är periodiska +YIELD = NOMAVK ## Returnerar avkastningen för ett värdepapper som ger periodisk ränta +YIELDDISC = NOMAVKDISK ## Returnerar den årliga avkastningen för diskonterade värdepapper, exempelvis en statsskuldväxel +YIELDMAT = NOMAVKFÖRF ## Returnerar den årliga avkastningen för ett värdepapper som ger ränta på förfallodagen + + +## +## Information functions Informationsfunktioner +## +CELL = CELL ## Returnerar information om formatering, plats och innehåll i en cell +ERROR.TYPE = FEL.TYP ## Returnerar ett tal som motsvarar ett felvärde +INFO = INFO ## Returnerar information om operativsystemet +ISBLANK = ÄRREF ## Returnerar SANT om värdet är tomt +ISERR = Ä ## Returnerar SANT om värdet är ett felvärde annat än #SAKNAS! +ISERROR = ÄRFEL ## Returnerar SANT om värdet är ett felvärde +ISEVEN = ÄRJÄMN ## Returnerar SANT om talet är jämnt +ISLOGICAL = ÄREJTEXT ## Returnerar SANT om värdet är ett logiskt värde +ISNA = ÄRLOGISK ## Returnerar SANT om värdet är felvärdet #SAKNAS! +ISNONTEXT = ÄRSAKNAD ## Returnerar SANT om värdet inte är text +ISNUMBER = ÄRTAL ## Returnerar SANT om värdet är ett tal +ISODD = ÄRUDDA ## Returnerar SANT om talet är udda +ISREF = ÄRTOM ## Returnerar SANT om värdet är en referens +ISTEXT = ÄRTEXT ## Returnerar SANT om värdet är text +N = N ## Returnerar ett värde omvandlat till ett tal +NA = SAKNAS ## Returnerar felvärdet #SAKNAS! +TYPE = VÄRDETYP ## Returnerar ett tal som anger värdets datatyp + + +## +## Logical functions Logiska funktioner +## +AND = OCH ## Returnerar SANT om alla argument är sanna +FALSE = FALSKT ## Returnerar det logiska värdet FALSKT +IF = OM ## Anger vilket logiskt test som ska utföras +IFERROR = OMFEL ## Returnerar ett värde som du anger om en formel utvärderar till ett fel; annars returneras resultatet av formeln +NOT = ICKE ## Inverterar logiken för argumenten +OR = ELLER ## Returnerar SANT om något argument är SANT +TRUE = SANT ## Returnerar det logiska värdet SANT + + +## +## Lookup and reference functions Sök- och referensfunktioner +## +ADDRESS = ADRESS ## Returnerar en referens som text till en enstaka cell i ett kalkylblad +AREAS = OMRÅDEN ## Returnerar antalet områden i en referens +CHOOSE = VÄLJ ## Väljer ett värde i en lista över värden +COLUMN = KOLUMN ## Returnerar kolumnnumret för en referens +COLUMNS = KOLUMNER ## Returnerar antalet kolumner i en referens +HLOOKUP = LETAKOLUMN ## Söker i den översta raden i en matris och returnerar värdet för angiven cell +HYPERLINK = HYPERLÄNK ## Skapar en genväg eller ett hopp till ett dokument i nätverket, i ett intranät eller på Internet +INDEX = INDEX ## Använder ett index för ett välja ett värde i en referens eller matris +INDIRECT = INDIREKT ## Returnerar en referens som anges av ett textvärde +LOOKUP = LETAUPP ## Letar upp värden i en vektor eller matris +MATCH = PASSA ## Letar upp värden i en referens eller matris +OFFSET = FÖRSKJUTNING ## Returnerar en referens förskjuten i förhållande till en given referens +ROW = RAD ## Returnerar radnumret för en referens +ROWS = RADER ## Returnerar antalet rader i en referens +RTD = RTD ## Hämtar realtidsdata från ett program som stöder COM-automation (Automation: Ett sätt att arbeta med ett programs objekt från ett annat program eller utvecklingsverktyg. Detta kallades tidigare för OLE Automation, och är en branschstandard och ingår i Component Object Model (COM).) +TRANSPOSE = TRANSPONERA ## Transponerar en matris +VLOOKUP = LETARAD ## Letar i den första kolumnen i en matris och flyttar över raden för att returnera värdet för en cell + + +## +## Math and trigonometry functions Matematiska och trigonometriska funktioner +## +ABS = ABS ## Returnerar absolutvärdet av ett tal +ACOS = ARCCOS ## Returnerar arcus cosinus för ett tal +ACOSH = ARCCOSH ## Returnerar inverterad hyperbolisk cosinus för ett tal +ASIN = ARCSIN ## Returnerar arcus cosinus för ett tal +ASINH = ARCSINH ## Returnerar hyperbolisk arcus sinus för ett tal +ATAN = ARCTAN ## Returnerar arcus tangens för ett tal +ATAN2 = ARCTAN2 ## Returnerar arcus tangens för en x- och en y- koordinat +ATANH = ARCTANH ## Returnerar hyperbolisk arcus tangens för ett tal +CEILING = RUNDA.UPP ## Avrundar ett tal till närmaste heltal eller närmaste signifikanta multipel +COMBIN = KOMBIN ## Returnerar antalet kombinationer för ett givet antal objekt +COS = COS ## Returnerar cosinus för ett tal +COSH = COSH ## Returnerar hyperboliskt cosinus för ett tal +DEGREES = GRADER ## Omvandlar radianer till grader +EVEN = JÄMN ## Avrundar ett tal uppåt till närmaste heltal +EXP = EXP ## Returnerar e upphöjt till ett givet tal +FACT = FAKULTET ## Returnerar fakulteten för ett tal +FACTDOUBLE = DUBBELFAKULTET ## Returnerar dubbelfakulteten för ett tal +FLOOR = RUNDA.NED ## Avrundar ett tal nedåt mot noll +GCD = SGD ## Returnerar den största gemensamma nämnaren +INT = HELTAL ## Avrundar ett tal nedåt till närmaste heltal +LCM = MGM ## Returnerar den minsta gemensamma multipeln +LN = LN ## Returnerar den naturliga logaritmen för ett tal +LOG = LOG ## Returnerar logaritmen för ett tal för en given bas +LOG10 = LOG10 ## Returnerar 10-logaritmen för ett tal +MDETERM = MDETERM ## Returnerar matrisen som är avgörandet av en matris +MINVERSE = MINVERT ## Returnerar matrisinversen av en matris +MMULT = MMULT ## Returnerar matrisprodukten av två matriser +MOD = REST ## Returnerar resten vid en division +MROUND = MAVRUNDA ## Returnerar ett tal avrundat till en given multipel +MULTINOMIAL = MULTINOMIAL ## Returnerar multinomialen för en uppsättning tal +ODD = UDDA ## Avrundar ett tal uppåt till närmaste udda heltal +PI = PI ## Returnerar värdet pi +POWER = UPPHÖJT.TILL ## Returnerar resultatet av ett tal upphöjt till en exponent +PRODUCT = PRODUKT ## Multiplicerar argumenten +QUOTIENT = KVOT ## Returnerar heltalsdelen av en division +RADIANS = RADIANER ## Omvandlar grader till radianer +RAND = SLUMP ## Returnerar ett slumptal mellan 0 och 1 +RANDBETWEEN = SLUMP.MELLAN ## Returnerar ett slumptal mellan de tal som du anger +ROMAN = ROMERSK ## Omvandlar vanliga (arabiska) siffror till romerska som text +ROUND = AVRUNDA ## Avrundar ett tal till ett angivet antal siffror +ROUNDDOWN = AVRUNDA.NEDÅT ## Avrundar ett tal nedåt mot noll +ROUNDUP = AVRUNDA.UPPÅT ## Avrundar ett tal uppåt, från noll +SERIESSUM = SERIESUMMA ## Returnerar summan av en potensserie baserat på formeln +SIGN = TECKEN ## Returnerar tecknet för ett tal +SIN = SIN ## Returnerar sinus för en given vinkel +SINH = SINH ## Returnerar hyperbolisk sinus för ett tal +SQRT = ROT ## Returnerar den positiva kvadratroten +SQRTPI = ROTPI ## Returnerar kvadratroten för (tal * pi) +SUBTOTAL = DELSUMMA ## Returnerar en delsumma i en lista eller databas +SUM = SUMMA ## Summerar argumenten +SUMIF = SUMMA.OM ## Summerar celler enligt ett angivet villkor +SUMIFS = SUMMA.OMF ## Lägger till cellerna i ett område som uppfyller flera kriterier +SUMPRODUCT = PRODUKTSUMMA ## Returnerar summan av produkterna i motsvarande matriskomponenter +SUMSQ = KVADRATSUMMA ## Returnerar summan av argumentens kvadrater +SUMX2MY2 = SUMMAX2MY2 ## Returnerar summan av differensen mellan kvadraterna för motsvarande värden i två matriser +SUMX2PY2 = SUMMAX2PY2 ## Returnerar summan av summan av kvadraterna av motsvarande värden i två matriser +SUMXMY2 = SUMMAXMY2 ## Returnerar summan av kvadraten av skillnaden mellan motsvarande värden i två matriser +TAN = TAN ## Returnerar tangens för ett tal +TANH = TANH ## Returnerar hyperbolisk tangens för ett tal +TRUNC = AVKORTA ## Avkortar ett tal till ett heltal + + +## +## Statistical functions Statistiska funktioner +## +AVEDEV = MEDELAVV ## Returnerar medelvärdet för datapunkters absoluta avvikelse från deras medelvärde +AVERAGE = MEDEL ## Returnerar medelvärdet av argumenten +AVERAGEA = AVERAGEA ## Returnerar medelvärdet av argumenten, inklusive tal, text och logiska värden +AVERAGEIF = MEDELOM ## Returnerar medelvärdet (aritmetiskt medelvärde) för alla celler i ett område som uppfyller ett givet kriterium +AVERAGEIFS = MEDELOMF ## Returnerar medelvärdet (det aritmetiska medelvärdet) för alla celler som uppfyller flera villkor. +BETADIST = BETAFÖRD ## Returnerar den kumulativa betafördelningsfunktionen +BETAINV = BETAINV ## Returnerar inversen till den kumulativa fördelningsfunktionen för en viss betafördelning +BINOMDIST = BINOMFÖRD ## Returnerar den individuella binomialfördelningen +CHIDIST = CHI2FÖRD ## Returnerar den ensidiga sannolikheten av c2-fördelningen +CHIINV = CHI2INV ## Returnerar inversen av chi2-fördelningen +CHITEST = CHI2TEST ## Returnerar oberoendetesten +CONFIDENCE = KONFIDENS ## Returnerar konfidensintervallet för en populations medelvärde +CORREL = KORREL ## Returnerar korrelationskoefficienten mellan två datamängder +COUNT = ANTAL ## Räknar hur många tal som finns bland argumenten +COUNTA = ANTALV ## Räknar hur många värden som finns bland argumenten +COUNTBLANK = ANTAL.TOMMA ## Räknar antalet tomma celler i ett område +COUNTIF = ANTAL.OM ## Räknar antalet celler i ett område som uppfyller angivna villkor. +COUNTIFS = ANTAL.OMF ## Räknar antalet celler i ett område som uppfyller flera villkor. +COVAR = KOVAR ## Returnerar kovariansen, d.v.s. medelvärdet av produkterna för parade avvikelser +CRITBINOM = KRITBINOM ## Returnerar det minsta värdet för vilket den kumulativa binomialfördelningen är mindre än eller lika med ett villkorsvärde +DEVSQ = KVADAVV ## Returnerar summan av kvadrater på avvikelser +EXPONDIST = EXPONFÖRD ## Returnerar exponentialfördelningen +FDIST = FFÖRD ## Returnerar F-sannolikhetsfördelningen +FINV = FINV ## Returnerar inversen till F-sannolikhetsfördelningen +FISHER = FISHER ## Returnerar Fisher-transformationen +FISHERINV = FISHERINV ## Returnerar inversen till Fisher-transformationen +FORECAST = PREDIKTION ## Returnerar ett värde längs en linjär trendlinje +FREQUENCY = FREKVENS ## Returnerar en frekvensfördelning som en lodrät matris +FTEST = FTEST ## Returnerar resultatet av en F-test +GAMMADIST = GAMMAFÖRD ## Returnerar gammafördelningen +GAMMAINV = GAMMAINV ## Returnerar inversen till den kumulativa gammafördelningen +GAMMALN = GAMMALN ## Returnerar den naturliga logaritmen för gammafunktionen, G(x) +GEOMEAN = GEOMEDEL ## Returnerar det geometriska medelvärdet +GROWTH = EXPTREND ## Returnerar värden längs en exponentiell trend +HARMEAN = HARMMEDEL ## Returnerar det harmoniska medelvärdet +HYPGEOMDIST = HYPGEOMFÖRD ## Returnerar den hypergeometriska fördelningen +INTERCEPT = SKÄRNINGSPUNKT ## Returnerar skärningspunkten för en linjär regressionslinje +KURT = TOPPIGHET ## Returnerar toppigheten av en mängd data +LARGE = STÖRSTA ## Returnerar det n:te största värdet i en mängd data +LINEST = REGR ## Returnerar parametrar till en linjär trendlinje +LOGEST = EXPREGR ## Returnerar parametrarna i en exponentiell trend +LOGINV = LOGINV ## Returnerar inversen till den lognormala fördelningen +LOGNORMDIST = LOGNORMFÖRD ## Returnerar den kumulativa lognormala fördelningen +MAX = MAX ## Returnerar det största värdet i en lista av argument +MAXA = MAXA ## Returnerar det största värdet i en lista av argument, inklusive tal, text och logiska värden +MEDIAN = MEDIAN ## Returnerar medianen för angivna tal +MIN = MIN ## Returnerar det minsta värdet i en lista med argument +MINA = MINA ## Returnerar det minsta värdet i en lista över argument, inklusive tal, text och logiska värden +MODE = TYPVÄRDE ## Returnerar det vanligaste värdet i en datamängd +NEGBINOMDIST = NEGBINOMFÖRD ## Returnerar den negativa binomialfördelningen +NORMDIST = NORMFÖRD ## Returnerar den kumulativa normalfördelningen +NORMINV = NORMINV ## Returnerar inversen till den kumulativa normalfördelningen +NORMSDIST = NORMSFÖRD ## Returnerar den kumulativa standardnormalfördelningen +NORMSINV = NORMSINV ## Returnerar inversen till den kumulativa standardnormalfördelningen +PEARSON = PEARSON ## Returnerar korrelationskoefficienten till Pearsons momentprodukt +PERCENTILE = PERCENTIL ## Returnerar den n:te percentilen av värden i ett område +PERCENTRANK = PROCENTRANG ## Returnerar procentrangen för ett värde i en datamängd +PERMUT = PERMUT ## Returnerar antal permutationer för ett givet antal objekt +POISSON = POISSON ## Returnerar Poisson-fördelningen +PROB = SANNOLIKHET ## Returnerar sannolikheten att värden i ett område ligger mellan två gränser +QUARTILE = KVARTIL ## Returnerar kvartilen av en mängd data +RANK = RANG ## Returnerar rangordningen för ett tal i en lista med tal +RSQ = RKV ## Returnerar kvadraten av Pearsons produktmomentkorrelationskoefficient +SKEW = SNEDHET ## Returnerar snedheten för en fördelning +SLOPE = LUTNING ## Returnerar lutningen på en linjär regressionslinje +SMALL = MINSTA ## Returnerar det n:te minsta värdet i en mängd data +STANDARDIZE = STANDARDISERA ## Returnerar ett normaliserat värde +STDEV = STDAV ## Uppskattar standardavvikelsen baserat på ett urval +STDEVA = STDEVA ## Uppskattar standardavvikelsen baserat på ett urval, inklusive tal, text och logiska värden +STDEVP = STDAVP ## Beräknar standardavvikelsen baserat på hela populationen +STDEVPA = STDEVPA ## Beräknar standardavvikelsen baserat på hela populationen, inklusive tal, text och logiska värden +STEYX = STDFELYX ## Returnerar standardfelet för ett förutspått y-värde för varje x-värde i regressionen +TDIST = TFÖRD ## Returnerar Students t-fördelning +TINV = TINV ## Returnerar inversen till Students t-fördelning +TREND = TREND ## Returnerar värden längs en linjär trend +TRIMMEAN = TRIMMEDEL ## Returnerar medelvärdet av mittpunkterna i en datamängd +TTEST = TTEST ## Returnerar sannolikheten beräknad ur Students t-test +VAR = VARIANS ## Uppskattar variansen baserat på ett urval +VARA = VARA ## Uppskattar variansen baserat på ett urval, inklusive tal, text och logiska värden +VARP = VARIANSP ## Beräknar variansen baserat på hela populationen +VARPA = VARPA ## Beräknar variansen baserat på hela populationen, inklusive tal, text och logiska värden +WEIBULL = WEIBULL ## Returnerar Weibull-fördelningen +ZTEST = ZTEST ## Returnerar det ensidiga sannolikhetsvärdet av ett z-test + + +## +## Text functions Textfunktioner +## +ASC = ASC ## Ändrar helbredds (dubbel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med halvt breddsteg (enkel byte) +BAHTTEXT = BAHTTEXT ## Omvandlar ett tal till text med valutaformatet ß (baht) +CHAR = TECKENKOD ## Returnerar tecknet som anges av kod +CLEAN = STÄDA ## Tar bort alla icke utskrivbara tecken i en text +CODE = KOD ## Returnerar en numerisk kod för det första tecknet i en textsträng +CONCATENATE = SAMMANFOGA ## Sammanfogar flera textdelar till en textsträng +DOLLAR = VALUTA ## Omvandlar ett tal till text med valutaformat +EXACT = EXAKT ## Kontrollerar om två textvärden är identiska +FIND = HITTA ## Hittar en text i en annan (skiljer på gemener och versaler) +FINDB = HITTAB ## Hittar en text i en annan (skiljer på gemener och versaler) +FIXED = FASTTAL ## Formaterar ett tal som text med ett fast antal decimaler +JIS = JIS ## Ändrar halvbredds (enkel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med helt breddsteg (dubbel byte) +LEFT = VÄNSTER ## Returnerar tecken längst till vänster i en sträng +LEFTB = VÄNSTERB ## Returnerar tecken längst till vänster i en sträng +LEN = LÄNGD ## Returnerar antalet tecken i en textsträng +LENB = LÄNGDB ## Returnerar antalet tecken i en textsträng +LOWER = GEMENER ## Omvandlar text till gemener +MID = EXTEXT ## Returnerar angivet antal tecken från en text med början vid den position som du anger +MIDB = EXTEXTB ## Returnerar angivet antal tecken från en text med början vid den position som du anger +PHONETIC = PHONETIC ## Returnerar de fonetiska (furigana) tecknen i en textsträng +PROPER = INITIAL ## Ändrar första bokstaven i varje ord i ett textvärde till versal +REPLACE = ERSÄTT ## Ersätter tecken i text +REPLACEB = ERSÄTTB ## Ersätter tecken i text +REPT = REP ## Upprepar en text ett bestämt antal gånger +RIGHT = HÖGER ## Returnerar tecken längst till höger i en sträng +RIGHTB = HÖGERB ## Returnerar tecken längst till höger i en sträng +SEARCH = SÖK ## Hittar ett textvärde i ett annat (skiljer inte på gemener och versaler) +SEARCHB = SÖKB ## Hittar ett textvärde i ett annat (skiljer inte på gemener och versaler) +SUBSTITUTE = BYT.UT ## Ersätter gammal text med ny text i en textsträng +T = T ## Omvandlar argumenten till text +TEXT = TEXT ## Formaterar ett tal och omvandlar det till text +TRIM = RENSA ## Tar bort blanksteg från text +UPPER = VERSALER ## Omvandlar text till versaler +VALUE = TEXTNUM ## Omvandlar ett textargument till ett tal diff --git a/extend/phpexcel/PHPExcel/locale/tr/config b/extend/phpexcel/PHPExcel/locale/tr/config new file mode 100755 index 0000000..de69cf5 --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/tr/config @@ -0,0 +1,47 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Settings +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## + + +ArgumentSeparator = ; + + +## +## (For future use) +## +currencySymbol = YTL + + +## +## Excel Error Codes (For future use) +## +NULL = #BOŞ! +DIV0 = #SAYI/0! +VALUE = #DEĞER! +REF = #BAŞV! +NAME = #AD? +NUM = #SAYI! +NA = #YOK diff --git a/extend/phpexcel/PHPExcel/locale/tr/functions b/extend/phpexcel/PHPExcel/locale/tr/functions new file mode 100755 index 0000000..c327bca --- /dev/null +++ b/extend/phpexcel/PHPExcel/locale/tr/functions @@ -0,0 +1,438 @@ +## +## PHPExcel +## +## Copyright (c) 2006 - 2013 PHPExcel +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +## +## @category PHPExcel +## @package PHPExcel_Calculation +## @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) +## @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL +## @version 1.8.0, 2014-03-02 +## +## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/ +## +## + + +## +## Add-in and Automation functions Eklenti ve Otomasyon fonksiyonları +## +GETPIVOTDATA = ÖZETVERİAL ## Bir Özet Tablo raporunda saklanan verileri verir. + + +## +## Cube functions Küp işlevleri +## +CUBEKPIMEMBER = KÜPKPIÜYE ## Kilit performans göstergesi (KPI-Key Performance Indicator) adını, özelliğini ve ölçüsünü verir ve hücredeki ad ve özelliği gösterir. KPI, bir kurumun performansını izlemek için kullanılan aylık brüt kâr ya da üç aylık çalışan giriş çıkışları gibi ölçülebilen bir birimdir. +CUBEMEMBER = KÜPÜYE ## Bir küp hiyerarşisinde bir üyeyi veya kaydı verir. Üye veya kaydın küpte varolduğunu doğrulamak için kullanılır. +CUBEMEMBERPROPERTY = KÜPÜYEÖZELLİĞİ ## Bir küpte bir üyenin özelliğinin değerini verir. Küp içinde üye adının varlığını doğrulamak ve bu üyenin belli özelliklerini getirmek için kullanılır. +CUBERANKEDMEMBER = KÜPÜYESIRASI ## Bir küme içindeki üyenin derecesini veya kaçıncı olduğunu verir. En iyi satış elemanı, veya en iyi on öğrenci gibi bir kümedeki bir veya daha fazla öğeyi getirmek için kullanılır. +CUBESET = KÜPKÜME ## Kümeyi oluşturan ve ardından bu kümeyi Microsoft Office Excel'e getiren sunucudaki küpe küme ifadelerini göndererek hesaplanan üye veya kayıt kümesini tanımlar. +CUBESETCOUNT = KÜPKÜMESAY ## Bir kümedeki öğelerin sayısını getirir. +CUBEVALUE = KÜPDEĞER ## Bir küpten toplam değeri getirir. + + +## +## Database functions Veritabanı işlevleri +## +DAVERAGE = VSEÇORT ## Seçili veritabanı girdilerinin ortalamasını verir. +DCOUNT = VSEÇSAY ## Veritabanında sayı içeren hücre sayısını hesaplar. +DCOUNTA = VSEÇSAYDOLU ## Veritabanındaki boş olmayan hücreleri sayar. +DGET = VAL ## Veritabanından, belirtilen ölçütlerle eşleşen tek bir rapor çıkarır. +DMAX = VSEÇMAK ## Seçili veritabanı girişlerinin en yüksek değerini verir. +DMIN = VSEÇMİN ## Seçili veritabanı girişlerinin en düşük değerini verir. +DPRODUCT = VSEÇÇARP ## Kayıtların belli bir alanında bulunan, bir veritabanındaki ölçütlerle eşleşen değerleri çarpar. +DSTDEV = VSEÇSTDSAPMA ## Seçili veritabanı girişlerinden oluşan bir örneğe dayanarak, standart sapmayı tahmin eder. +DSTDEVP = VSEÇSTDSAPMAS ## Standart sapmayı, seçili veritabanı girişlerinin tüm popülasyonunu esas alarak hesaplar. +DSUM = VSEÇTOPLA ## Kayıtların alan sütununda bulunan, ölçütle eşleşen sayıları toplar. +DVAR = VSEÇVAR ## Seçili veritabanı girişlerinden oluşan bir örneği esas alarak farkı tahmin eder. +DVARP = VSEÇVARS ## Seçili veritabanı girişlerinin tüm popülasyonunu esas alarak farkı hesaplar. + + +## +## Date and time functions Tarih ve saat işlevleri +## +DATE = TARİH ## Belirli bir tarihin seri numarasını verir. +DATEVALUE = TARİHSAYISI ## Metin biçimindeki bir tarihi seri numarasına dönüştürür. +DAY = GÜN ## Seri numarasını, ayın bir gününe dönüştürür. +DAYS360 = GÜN360 ## İki tarih arasındaki gün sayısını, 360 günlük yılı esas alarak hesaplar. +EDATE = SERİTARİH ## Başlangıç tarihinden itibaren, belirtilen ay sayısından önce veya sonraki tarihin seri numarasını verir. +EOMONTH = SERİAY ## Belirtilen sayıda ay önce veya sonraki ayın son gününün seri numarasını verir. +HOUR = SAAT ## Bir seri numarasını saate dönüştürür. +MINUTE = DAKİKA ## Bir seri numarasını dakikaya dönüştürür. +MONTH = AY ## Bir seri numarasını aya dönüştürür. +NETWORKDAYS = TAMİŞGÜNÜ ## İki tarih arasındaki tam çalışma günlerinin sayısını verir. +NOW = ŞİMDİ ## Geçerli tarihin ve saatin seri numarasını verir. +SECOND = SANİYE ## Bir seri numarasını saniyeye dönüştürür. +TIME = ZAMAN ## Belirli bir zamanın seri numarasını verir. +TIMEVALUE = ZAMANSAYISI ## Metin biçimindeki zamanı seri numarasına dönüştürür. +TODAY = BUGÜN ## Bugünün tarihini seri numarasına dönüştürür. +WEEKDAY = HAFTANINGÜNÜ ## Bir seri numarasını, haftanın gününe dönüştürür. +WEEKNUM = HAFTASAY ## Dizisel değerini, haftanın yıl içinde bulunduğu konumu sayısal olarak gösteren sayıya dönüştürür. +WORKDAY = İŞGÜNÜ ## Belirtilen sayıda çalışma günü öncesinin ya da sonrasının tarihinin seri numarasını verir. +YEAR = YIL ## Bir seri numarasını yıla dönüştürür. +YEARFRAC = YILORAN ## Başlangıç_tarihi ve bitiş_tarihi arasındaki tam günleri gösteren yıl kesrini verir. + + +## +## Engineering functions Mühendislik işlevleri +## +BESSELI = BESSELI ## Değiştirilmiş Bessel fonksiyonu In(x)'i verir. +BESSELJ = BESSELJ ## Bessel fonksiyonu Jn(x)'i verir. +BESSELK = BESSELK ## Değiştirilmiş Bessel fonksiyonu Kn(x)'i verir. +BESSELY = BESSELY ## Bessel fonksiyonu Yn(x)'i verir. +BIN2DEC = BIN2DEC ## İkili bir sayıyı, ondalık sayıya dönüştürür. +BIN2HEX = BIN2HEX ## İkili bir sayıyı, onaltılıya dönüştürür. +BIN2OCT = BIN2OCT ## İkili bir sayıyı, sekizliye dönüştürür. +COMPLEX = KARMAŞIK ## Gerçek ve sanal katsayıları, karmaşık sayıya dönüştürür. +CONVERT = ÇEVİR ## Bir sayıyı, bir ölçüm sisteminden bir başka ölçüm sistemine dönüştürür. +DEC2BIN = DEC2BIN ## Ondalık bir sayıyı, ikiliye dönüştürür. +DEC2HEX = DEC2HEX ## Ondalık bir sayıyı, onaltılıya dönüştürür. +DEC2OCT = DEC2OCT ## Ondalık bir sayıyı sekizliğe dönüştürür. +DELTA = DELTA ## İki değerin eşit olup olmadığını sınar. +ERF = HATAİŞLEV ## Hata işlevini verir. +ERFC = TÜMHATAİŞLEV ## Tümleyici hata işlevini verir. +GESTEP = BESINIR ## Bir sayının eşik değerinden büyük olup olmadığını sınar. +HEX2BIN = HEX2BIN ## Onaltılı bir sayıyı ikiliye dönüştürür. +HEX2DEC = HEX2DEC ## Onaltılı bir sayıyı ondalığa dönüştürür. +HEX2OCT = HEX2OCT ## Onaltılı bir sayıyı sekizliğe dönüştürür. +IMABS = SANMUTLAK ## Karmaşık bir sayının mutlak değerini (modül) verir. +IMAGINARY = SANAL ## Karmaşık bir sayının sanal katsayısını verir. +IMARGUMENT = SANBAĞ_DEĞİŞKEN ## Radyanlarla belirtilen bir açı olan teta bağımsız değişkenini verir. +IMCONJUGATE = SANEŞLENEK ## Karmaşık bir sayının karmaşık eşleniğini verir. +IMCOS = SANCOS ## Karmaşık bir sayının kosinüsünü verir. +IMDIV = SANBÖL ## İki karmaşık sayının bölümünü verir. +IMEXP = SANÜS ## Karmaşık bir sayının üssünü verir. +IMLN = SANLN ## Karmaşık bir sayının doğal logaritmasını verir. +IMLOG10 = SANLOG10 ## Karmaşık bir sayının, 10 tabanında logaritmasını verir. +IMLOG2 = SANLOG2 ## Karmaşık bir sayının 2 tabanında logaritmasını verir. +IMPOWER = SANÜSSÜ ## Karmaşık bir sayıyı, bir tamsayı üssüne yükseltilmiş olarak verir. +IMPRODUCT = SANÇARP ## Karmaşık sayıların çarpımını verir. +IMREAL = SANGERÇEK ## Karmaşık bir sayının, gerçek katsayısını verir. +IMSIN = SANSIN ## Karmaşık bir sayının sinüsünü verir. +IMSQRT = SANKAREKÖK ## Karmaşık bir sayının karekökünü verir. +IMSUB = SANÇIKAR ## İki karmaşık sayının farkını verir. +IMSUM = SANTOPLA ## Karmaşık sayıların toplamını verir. +OCT2BIN = OCT2BIN ## Sekizli bir sayıyı ikiliye dönüştürür. +OCT2DEC = OCT2DEC ## Sekizli bir sayıyı ondalığa dönüştürür. +OCT2HEX = OCT2HEX ## Sekizli bir sayıyı onaltılıya dönüştürür. + + +## +## Financial functions Finansal fonksiyonlar +## +ACCRINT = GERÇEKFAİZ ## Dönemsel faiz ödeyen hisse senedine ilişkin tahakkuk eden faizi getirir. +ACCRINTM = GERÇEKFAİZV ## Vadesinde ödeme yapan bir tahvilin tahakkuk etmiş faizini verir. +AMORDEGRC = AMORDEGRC ## Yıpranma katsayısı kullanarak her hesap döneminin değer kaybını verir. +AMORLINC = AMORLINC ## Her hesap dönemi içindeki yıpranmayı verir. +COUPDAYBS = KUPONGÜNBD ## Kupon süresinin başlangıcından alış tarihine kadar olan süredeki gün sayısını verir. +COUPDAYS = KUPONGÜN ## Kupon süresindeki, gün sayısını, alış tarihini de içermek üzere, verir. +COUPDAYSNC = KUPONGÜNDSK ## Alış tarihinden bir sonraki kupon tarihine kadar olan gün sayısını verir. +COUPNCD = KUPONGÜNSKT ## Alış tarihinden bir sonraki kupon tarihini verir. +COUPNUM = KUPONSAYI ## Alış tarihiyle vade tarihi arasında ödenecek kuponların sayısını verir. +COUPPCD = KUPONGÜNÖKT ## Alış tarihinden bir önceki kupon tarihini verir. +CUMIPMT = AİÇVERİMORANI ## İki dönem arasında ödenen kümülatif faizi verir. +CUMPRINC = ANA_PARA_ÖDEMESİ ## İki dönem arasında bir borç üzerine ödenen birikimli temeli verir. +DB = AZALANBAKİYE ## Bir malın belirtilen bir süre içindeki yıpranmasını, sabit azalan bakiye yöntemini kullanarak verir. +DDB = ÇİFTAZALANBAKİYE ## Bir malın belirtilen bir süre içindeki yıpranmasını, çift azalan bakiye yöntemi ya da sizin belirttiğiniz başka bir yöntemi kullanarak verir. +DISC = İNDİRİM ## Bir tahvilin indirim oranını verir. +DOLLARDE = LİRAON ## Kesir olarak tanımlanmış lira fiyatını, ondalık sayı olarak tanımlanmış lira fiyatına dönüştürür. +DOLLARFR = LİRAKES ## Ondalık sayı olarak tanımlanmış lira fiyatını, kesir olarak tanımlanmış lira fiyatına dönüştürür. +DURATION = SÜRE ## Belli aralıklarla faiz ödemesi yapan bir tahvilin yıllık süresini verir. +EFFECT = ETKİN ## Efektif yıllık faiz oranını verir. +FV = ANBD ## Bir yatırımın gelecekteki değerini verir. +FVSCHEDULE = GDPROGRAM ## Bir seri birleşik faiz oranı uyguladıktan sonra, bir başlangıçtaki anaparanın gelecekteki değerini verir. +INTRATE = FAİZORANI ## Tam olarak yatırım yapılmış bir tahvilin faiz oranını verir. +IPMT = FAİZTUTARI ## Bir yatırımın verilen bir süre için faiz ödemesini verir. +IRR = İÇ_VERİM_ORANI ## Bir para akışı serisi için, iç verim oranını verir. +ISPMT = ISPMT ## Yatırımın belirli bir dönemi boyunca ödenen faizi hesaplar. +MDURATION = MSÜRE ## Varsayılan par değeri 10.000.000 lira olan bir tahvil için Macauley değiştirilmiş süreyi verir. +MIRR = D_İÇ_VERİM_ORANI ## Pozitif ve negatif para akışlarının farklı oranlarda finanse edildiği durumlarda, iç verim oranını verir. +NOMINAL = NOMİNAL ## Yıllık nominal faiz oranını verir. +NPER = DÖNEM_SAYISI ## Bir yatırımın dönem sayısını verir. +NPV = NBD ## Bir yatırımın bugünkü net değerini, bir dönemsel para akışları serisine ve bir indirim oranına bağlı olarak verir. +ODDFPRICE = TEKYDEĞER ## Tek bir ilk dönemi olan bir tahvilin değerini, her 100.000.000 lirada bir verir. +ODDFYIELD = TEKYÖDEME ## Tek bir ilk dönemi olan bir tahvilin ödemesini verir. +ODDLPRICE = TEKSDEĞER ## Tek bir son dönemi olan bir tahvilin fiyatını her 10.000.000 lirada bir verir. +ODDLYIELD = TEKSÖDEME ## Tek bir son dönemi olan bir tahvilin ödemesini verir. +PMT = DEVRESEL_ÖDEME ## Bir yıllık dönemsel ödemeyi verir. +PPMT = ANA_PARA_ÖDEMESİ ## Verilen bir süre için, bir yatırımın anaparasına dayanan ödemeyi verir. +PRICE = DEĞER ## Dönemsel faiz ödeyen bir tahvilin fiyatını 10.000.00 liralık değer başına verir. +PRICEDISC = DEĞERİND ## İndirimli bir tahvilin fiyatını 10.000.000 liralık nominal değer başına verir. +PRICEMAT = DEĞERVADE ## Faizini vade sonunda ödeyen bir tahvilin fiyatını 10.000.000 nominal değer başına verir. +PV = BD ## Bir yatırımın bugünkü değerini verir. +RATE = FAİZ_ORANI ## Bir yıllık dönem başına düşen faiz oranını verir. +RECEIVED = GETİRİ ## Tam olarak yatırılmış bir tahvilin vadesinin bitiminde alınan miktarı verir. +SLN = DA ## Bir malın bir dönem içindeki doğrusal yıpranmasını verir. +SYD = YAT ## Bir malın belirli bir dönem için olan amortismanını verir. +TBILLEQ = HTAHEŞ ## Bir Hazine bonosunun bono eşdeğeri ödemesini verir. +TBILLPRICE = HTAHDEĞER ## Bir Hazine bonosunun değerini, 10.000.000 liralık nominal değer başına verir. +TBILLYIELD = HTAHÖDEME ## Bir Hazine bonosunun ödemesini verir. +VDB = DAB ## Bir malın amortismanını, belirlenmiş ya da kısmi bir dönem için, bir azalan bakiye yöntemi kullanarak verir. +XIRR = AİÇVERİMORANI ## Dönemsel olması gerekmeyen bir para akışları programı için, iç verim oranını verir. +XNPV = ANBD ## Dönemsel olması gerekmeyen bir para akışları programı için, bugünkü net değeri verir. +YIELD = ÖDEME ## Belirli aralıklarla faiz ödeyen bir tahvilin ödemesini verir. +YIELDDISC = ÖDEMEİND ## İndirimli bir tahvilin yıllık ödemesini verir; örneğin, bir Hazine bonosunun. +YIELDMAT = ÖDEMEVADE ## Vadesinin bitiminde faiz ödeyen bir tahvilin yıllık ödemesini verir. + + +## +## Information functions Bilgi fonksiyonları +## +CELL = HÜCRE ## Bir hücrenin biçimlendirmesi, konumu ya da içeriği hakkında bilgi verir. +ERROR.TYPE = HATA.TİPİ ## Bir hata türüne ilişkin sayıları verir. +INFO = BİLGİ ## Geçerli işletim ortamı hakkında bilgi verir. +ISBLANK = EBOŞSA ## Değer boşsa, DOĞRU verir. +ISERR = EHATA ## Değer, #YOK dışındaki bir hata değeriyse, DOĞRU verir. +ISERROR = EHATALIYSA ## Değer, herhangi bir hata değeriyse, DOĞRU verir. +ISEVEN = ÇİFTTİR ## Sayı çiftse, DOĞRU verir. +ISLOGICAL = EMANTIKSALSA ## Değer, mantıksal bir değerse, DOĞRU verir. +ISNA = EYOKSA ## Değer, #YOK hata değeriyse, DOĞRU verir. +ISNONTEXT = EMETİNDEĞİLSE ## Değer, metin değilse, DOĞRU verir. +ISNUMBER = ESAYIYSA ## Değer, bir sayıysa, DOĞRU verir. +ISODD = TEKTİR ## Sayı tekse, DOĞRU verir. +ISREF = EREFSE ## Değer bir başvuruysa, DOĞRU verir. +ISTEXT = EMETİNSE ## Değer bir metinse DOĞRU verir. +N = N ## Sayıya dönüştürülmüş bir değer verir. +NA = YOKSAY ## #YOK hata değerini verir. +TYPE = TİP ## Bir değerin veri türünü belirten bir sayı verir. + + +## +## Logical functions Mantıksal fonksiyonlar +## +AND = VE ## Bütün bağımsız değişkenleri DOĞRU ise, DOĞRU verir. +FALSE = YANLIŞ ## YANLIŞ mantıksal değerini verir. +IF = EĞER ## Gerçekleştirilecek bir mantıksal sınama belirtir. +IFERROR = EĞERHATA ## Formül hatalıysa belirttiğiniz değeri verir; bunun dışındaki durumlarda formülün sonucunu verir. +NOT = DEĞİL ## Bağımsız değişkeninin mantığını tersine çevirir. +OR = YADA ## Bağımsız değişkenlerden herhangi birisi DOĞRU ise, DOĞRU verir. +TRUE = DOĞRU ## DOĞRU mantıksal değerini verir. + + +## +## Lookup and reference functions Arama ve Başvuru fonksiyonları +## +ADDRESS = ADRES ## Bir başvuruyu, çalışma sayfasındaki tek bir hücreye metin olarak verir. +AREAS = ALANSAY ## Renvoie le nombre de zones dans une référence. +CHOOSE = ELEMAN ## Değerler listesinden bir değer seçer. +COLUMN = SÜTUN ## Bir başvurunun sütun sayısını verir. +COLUMNS = SÜTUNSAY ## Bir başvurudaki sütunların sayısını verir. +HLOOKUP = YATAYARA ## Bir dizinin en üst satırına bakar ve belirtilen hücrenin değerini verir. +HYPERLINK = KÖPRÜ ## Bir ağ sunucusunda, bir intranette ya da Internet'te depolanan bir belgeyi açan bir kısayol ya da atlama oluşturur. +INDEX = İNDİS ## Başvurudan veya diziden bir değer seçmek için, bir dizin kullanır. +INDIRECT = DOLAYLI ## Metin değeriyle belirtilen bir başvuru verir. +LOOKUP = ARA ## Bir vektördeki veya dizideki değerleri arar. +MATCH = KAÇINCI ## Bir başvurudaki veya dizideki değerleri arar. +OFFSET = KAYDIR ## Verilen bir başvurudan, bir başvuru kaydırmayı verir. +ROW = SATIR ## Bir başvurunun satır sayısını verir. +ROWS = SATIRSAY ## Bir başvurudaki satırların sayısını verir. +RTD = RTD ## COM otomasyonunu destekleyen programdan gerçek zaman verileri alır. +TRANSPOSE = DEVRİK_DÖNÜŞÜM ## Bir dizinin devrik dönüşümünü verir. +VLOOKUP = DÜŞEYARA ## Bir dizinin ilk sütununa bakar ve bir hücrenin değerini vermek için satır boyunca hareket eder. + + +## +## Math and trigonometry functions Matematik ve trigonometri fonksiyonları +## +ABS = MUTLAK ## Bir sayının mutlak değerini verir. +ACOS = ACOS ## Bir sayının ark kosinüsünü verir. +ACOSH = ACOSH ## Bir sayının ters hiperbolik kosinüsünü verir. +ASIN = ASİN ## Bir sayının ark sinüsünü verir. +ASINH = ASİNH ## Bir sayının ters hiperbolik sinüsünü verir. +ATAN = ATAN ## Bir sayının ark tanjantını verir. +ATAN2 = ATAN2 ## Ark tanjantı, x- ve y- koordinatlarından verir. +ATANH = ATANH ## Bir sayının ters hiperbolik tanjantını verir. +CEILING = TAVANAYUVARLA ## Bir sayıyı, en yakın tamsayıya ya da en yakın katına yuvarlar. +COMBIN = KOMBİNASYON ## Verilen sayıda öğenin kombinasyon sayısını verir. +COS = COS ## Bir sayının kosinüsünü verir. +COSH = COSH ## Bir sayının hiperbolik kosinüsünü verir. +DEGREES = DERECE ## Radyanları dereceye dönüştürür. +EVEN = ÇİFT ## Bir sayıyı, en yakın daha büyük çift tamsayıya yuvarlar. +EXP = ÜS ## e'yi, verilen bir sayının üssüne yükseltilmiş olarak verir. +FACT = ÇARPINIM ## Bir sayının faktörünü verir. +FACTDOUBLE = ÇİFTFAKTÖR ## Bir sayının çift çarpınımını verir. +FLOOR = TABANAYUVARLA ## Bir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar. +GCD = OBEB ## En büyük ortak böleni verir. +INT = TAMSAYI ## Bir sayıyı aşağıya doğru en yakın tamsayıya yuvarlar. +LCM = OKEK ## En küçük ortak katı verir. +LN = LN ## Bir sayının doğal logaritmasını verir. +LOG = LOG ## Bir sayının, belirtilen bir tabandaki logaritmasını verir. +LOG10 = LOG10 ## Bir sayının 10 tabanında logaritmasını verir. +MDETERM = DETERMİNANT ## Bir dizinin dizey determinantını verir. +MINVERSE = DİZEY_TERS ## Bir dizinin dizey tersini verir. +MMULT = DÇARP ## İki dizinin dizey çarpımını verir. +MOD = MODÜLO ## Bölmeden kalanı verir. +MROUND = KYUVARLA ## İstenen kata yuvarlanmış bir sayı verir. +MULTINOMIAL = ÇOKTERİMLİ ## Bir sayılar kümesinin çok terimlisini verir. +ODD = TEK ## Bir sayıyı en yakın daha büyük tek sayıya yuvarlar. +PI = Pİ ## Pi değerini verir. +POWER = KUVVET ## Bir üsse yükseltilmiş sayının sonucunu verir. +PRODUCT = ÇARPIM ## Bağımsız değişkenlerini çarpar. +QUOTIENT = BÖLÜM ## Bir bölme işleminin tamsayı kısmını verir. +RADIANS = RADYAN ## Dereceleri radyanlara dönüştürür. +RAND = S_SAYI_ÜRET ## 0 ile 1 arasında rastgele bir sayı verir. +RANDBETWEEN = RASTGELEARALIK ## Belirttiğiniz sayılar arasında rastgele bir sayı verir. +ROMAN = ROMEN ## Bir normal rakamı, metin olarak, romen rakamına çevirir. +ROUND = YUVARLA ## Bir sayıyı, belirtilen basamak sayısına yuvarlar. +ROUNDDOWN = AŞAĞIYUVARLA ## Bir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar. +ROUNDUP = YUKARIYUVARLA ## Bir sayıyı daha büyük sayıya, sıfırdan ıraksayarak yuvarlar. +SERIESSUM = SERİTOPLA ## Bir üs serisinin toplamını, formüle bağlı olarak verir. +SIGN = İŞARET ## Bir sayının işaretini verir. +SIN = SİN ## Verilen bir açının sinüsünü verir. +SINH = SİNH ## Bir sayının hiperbolik sinüsünü verir. +SQRT = KAREKÖK ## Pozitif bir karekök verir. +SQRTPI = KAREKÖKPİ ## (* Pi sayısının) kare kökünü verir. +SUBTOTAL = ALTTOPLAM ## Bir listedeki ya da veritabanındaki bir alt toplamı verir. +SUM = TOPLA ## Bağımsız değişkenlerini toplar. +SUMIF = ETOPLA ## Verilen ölçütle belirlenen hücreleri toplar. +SUMIFS = SUMIFS ## Bir aralıktaki, birden fazla ölçüte uyan hücreleri ekler. +SUMPRODUCT = TOPLA.ÇARPIM ## İlişkili dizi bileşenlerinin çarpımlarının toplamını verir. +SUMSQ = TOPKARE ## Bağımsız değişkenlerin karelerinin toplamını verir. +SUMX2MY2 = TOPX2EY2 ## İki dizideki ilişkili değerlerin farkının toplamını verir. +SUMX2PY2 = TOPX2AY2 ## İki dizideki ilişkili değerlerin karelerinin toplamının toplamını verir. +SUMXMY2 = TOPXEY2 ## İki dizideki ilişkili değerlerin farklarının karelerinin toplamını verir. +TAN = TAN ## Bir sayının tanjantını verir. +TANH = TANH ## Bir sayının hiperbolik tanjantını verir. +TRUNC = NSAT ## Bir sayının, tamsayı durumuna gelecek şekilde, fazlalıklarını atar. + + +## +## Statistical functions İstatistiksel fonksiyonlar +## +AVEDEV = ORTSAP ## Veri noktalarının ortalamalarından mutlak sapmalarının ortalamasını verir. +AVERAGE = ORTALAMA ## Bağımsız değişkenlerinin ortalamasını verir. +AVERAGEA = ORTALAMAA ## Bağımsız değişkenlerinin, sayılar, metin ve mantıksal değerleri içermek üzere ortalamasını verir. +AVERAGEIF = EĞERORTALAMA ## Verili ölçütü karşılayan bir aralıktaki bütün hücrelerin ortalamasını (aritmetik ortalama) hesaplar. +AVERAGEIFS = EĞERLERORTALAMA ## Birden çok ölçüte uyan tüm hücrelerin ortalamasını (aritmetik ortalama) hesaplar. +BETADIST = BETADAĞ ## Beta birikimli dağılım fonksiyonunu verir. +BETAINV = BETATERS ## Belirli bir beta dağılımı için birikimli dağılım fonksiyonunun tersini verir. +BINOMDIST = BİNOMDAĞ ## Tek terimli binom dağılımı olasılığını verir. +CHIDIST = KİKAREDAĞ ## Kikare dağılımın tek kuyruklu olasılığını verir. +CHIINV = KİKARETERS ## Kikare dağılımın kuyruklu olasılığının tersini verir. +CHITEST = KİKARETEST ## Bağımsızlık sınamalarını verir. +CONFIDENCE = GÜVENİRLİK ## Bir popülasyon ortalaması için güvenirlik aralığını verir. +CORREL = KORELASYON ## İki veri kümesi arasındaki bağlantı katsayısını verir. +COUNT = BAĞ_DEĞ_SAY ## Bağımsız değişkenler listesinde kaç tane sayı bulunduğunu sayar. +COUNTA = BAĞ_DEĞ_DOLU_SAY ## Bağımsız değişkenler listesinde kaç tane değer bulunduğunu sayar. +COUNTBLANK = BOŞLUKSAY ## Aralıktaki boş hücre sayısını hesaplar. +COUNTIF = EĞERSAY ## Verilen ölçütlere uyan bir aralık içindeki hücreleri sayar. +COUNTIFS = ÇOKEĞERSAY ## Birden çok ölçüte uyan bir aralık içindeki hücreleri sayar. +COVAR = KOVARYANS ## Eşleştirilmiş sapmaların ortalaması olan kovaryansı verir. +CRITBINOM = KRİTİKBİNOM ## Birikimli binom dağılımının bir ölçüt değerinden küçük veya ölçüt değerine eşit olduğu en küçük değeri verir. +DEVSQ = SAPKARE ## Sapmaların karelerinin toplamını verir. +EXPONDIST = ÜSTELDAĞ ## Üstel dağılımı verir. +FDIST = FDAĞ ## F olasılık dağılımını verir. +FINV = FTERS ## F olasılık dağılımının tersini verir. +FISHER = FISHER ## Fisher dönüşümünü verir. +FISHERINV = FISHERTERS ## Fisher dönüşümünün tersini verir. +FORECAST = TAHMİN ## Bir doğrusal eğilim boyunca bir değer verir. +FREQUENCY = SIKLIK ## Bir sıklık dağılımını, dikey bir dizi olarak verir. +FTEST = FTEST ## Bir F-test'in sonucunu verir. +GAMMADIST = GAMADAĞ ## Gama dağılımını verir. +GAMMAINV = GAMATERS ## Gama kümülatif dağılımının tersini verir. +GAMMALN = GAMALN ## Gama fonksiyonunun (?(x)) doğal logaritmasını verir. +GEOMEAN = GEOORT ## Geometrik ortayı verir. +GROWTH = BÜYÜME ## Üstel bir eğilim boyunca değerler verir. +HARMEAN = HARORT ## Harmonik ortayı verir. +HYPGEOMDIST = HİPERGEOMDAĞ ## Hipergeometrik dağılımı verir. +INTERCEPT = KESMENOKTASI ## Doğrusal çakıştırma çizgisinin kesişme noktasını verir. +KURT = BASIKLIK ## Bir veri kümesinin basıklığını verir. +LARGE = BÜYÜK ## Bir veri kümesinde k. en büyük değeri verir. +LINEST = DOT ## Doğrusal bir eğilimin parametrelerini verir. +LOGEST = LOT ## Üstel bir eğilimin parametrelerini verir. +LOGINV = LOGTERS ## Bir lognormal dağılımının tersini verir. +LOGNORMDIST = LOGNORMDAĞ ## Birikimli lognormal dağılımını verir. +MAX = MAK ## Bir bağımsız değişkenler listesindeki en büyük değeri verir. +MAXA = MAKA ## Bir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri içermek üzere, en büyük değeri verir. +MEDIAN = ORTANCA ## Belirtilen sayıların orta değerini verir. +MIN = MİN ## Bir bağımsız değişkenler listesindeki en küçük değeri verir. +MINA = MİNA ## Bir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri de içermek üzere, en küçük değeri verir. +MODE = ENÇOK_OLAN ## Bir veri kümesindeki en sık rastlanan değeri verir. +NEGBINOMDIST = NEGBİNOMDAĞ ## Negatif binom dağılımını verir. +NORMDIST = NORMDAĞ ## Normal birikimli dağılımı verir. +NORMINV = NORMTERS ## Normal kümülatif dağılımın tersini verir. +NORMSDIST = NORMSDAĞ ## Standart normal birikimli dağılımı verir. +NORMSINV = NORMSTERS ## Standart normal birikimli dağılımın tersini verir. +PEARSON = PEARSON ## Pearson çarpım moment korelasyon katsayısını verir. +PERCENTILE = YÜZDEBİRLİK ## Bir aralık içerisinde bulunan değerlerin k. frekans toplamını verir. +PERCENTRANK = YÜZDERANK ## Bir veri kümesindeki bir değerin yüzde mertebesini verir. +PERMUT = PERMÜTASYON ## Verilen sayıda nesne için permütasyon sayısını verir. +POISSON = POISSON ## Poisson dağılımını verir. +PROB = OLASILIK ## Bir aralıktaki değerlerin iki sınır arasında olması olasılığını verir. +QUARTILE = DÖRTTEBİRLİK ## Bir veri kümesinin dörtte birliğini verir. +RANK = RANK ## Bir sayılar listesinde bir sayının mertebesini verir. +RSQ = RKARE ## Pearson çarpım moment korelasyon katsayısının karesini verir. +SKEW = ÇARPIKLIK ## Bir dağılımın çarpıklığını verir. +SLOPE = EĞİM ## Doğrusal çakışma çizgisinin eğimini verir. +SMALL = KÜÇÜK ## Bir veri kümesinde k. en küçük değeri verir. +STANDARDIZE = STANDARTLAŞTIRMA ## Normalleştirilmiş bir değer verir. +STDEV = STDSAPMA ## Bir örneğe dayanarak standart sapmayı tahmin eder. +STDEVA = STDSAPMAA ## Standart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder. +STDEVP = STDSAPMAS ## Standart sapmayı, tüm popülasyona bağlı olarak hesaplar. +STDEVPA = STDSAPMASA ## Standart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar. +STEYX = STHYX ## Regresyondaki her x için tahmini y değerinin standart hatasını verir. +TDIST = TDAĞ ## T-dağılımını verir. +TINV = TTERS ## T-dağılımının tersini verir. +TREND = EĞİLİM ## Doğrusal bir eğilim boyunca değerler verir. +TRIMMEAN = KIRPORTALAMA ## Bir veri kümesinin içinin ortalamasını verir. +TTEST = TTEST ## T-test'le ilişkilendirilmiş olasılığı verir. +VAR = VAR ## Varyansı, bir örneğe bağlı olarak tahmin eder. +VARA = VARA ## Varyansı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder. +VARP = VARS ## Varyansı, tüm popülasyona dayanarak hesaplar. +VARPA = VARSA ## Varyansı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar. +WEIBULL = WEIBULL ## Weibull dağılımını hesaplar. +ZTEST = ZTEST ## Z-testinin tek kuyruklu olasılık değerini hesaplar. + + +## +## Text functions Metin fonksiyonları +## +ASC = ASC ## Bir karakter dizesindeki çift enli (iki bayt) İngilizce harfleri veya katakanayı yarım enli (tek bayt) karakterlerle değiştirir. +BAHTTEXT = BAHTTEXT ## Sayıyı, ß (baht) para birimi biçimini kullanarak metne dönüştürür. +CHAR = DAMGA ## Kod sayısıyla belirtilen karakteri verir. +CLEAN = TEMİZ ## Metindeki bütün yazdırılamaz karakterleri kaldırır. +CODE = KOD ## Bir metin dizesindeki ilk karakter için sayısal bir kod verir. +CONCATENATE = BİRLEŞTİR ## Pek çok metin öğesini bir metin öğesi olarak birleştirir. +DOLLAR = LİRA ## Bir sayıyı YTL (yeni Türk lirası) para birimi biçimini kullanarak metne dönüştürür. +EXACT = ÖZDEŞ ## İki metin değerinin özdeş olup olmadığını anlamak için, değerleri denetler. +FIND = BUL ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır). +FINDB = BULB ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır). +FIXED = SAYIDÜZENLE ## Bir sayıyı, sabit sayıda ondalıkla, metin olarak biçimlendirir. +JIS = JIS ## Bir karakter dizesindeki tek enli (tek bayt) İngilizce harfleri veya katakanayı çift enli (iki bayt) karakterlerle değiştirir. +LEFT = SOL ## Bir metin değerinden en soldaki karakterleri verir. +LEFTB = SOLB ## Bir metin değerinden en soldaki karakterleri verir. +LEN = UZUNLUK ## Bir metin dizesindeki karakter sayısını verir. +LENB = UZUNLUKB ## Bir metin dizesindeki karakter sayısını verir. +LOWER = KÜÇÜKHARF ## Metni küçük harfe çevirir. +MID = ORTA ## Bir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir. +MIDB = ORTAB ## Bir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir. +PHONETIC = SES ## Metin dizesinden ses (furigana) karakterlerini ayıklar. +PROPER = YAZIM.DÜZENİ ## Bir metin değerinin her bir sözcüğünün ilk harfini büyük harfe çevirir. +REPLACE = DEĞİŞTİR ## Metnin içindeki karakterleri değiştirir. +REPLACEB = DEĞİŞTİRB ## Metnin içindeki karakterleri değiştirir. +REPT = YİNELE ## Metni belirtilen sayıda yineler. +RIGHT = SAĞ ## Bir metin değerinden en sağdaki karakterleri verir. +RIGHTB = SAĞB ## Bir metin değerinden en sağdaki karakterleri verir. +SEARCH = BUL ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir). +SEARCHB = BULB ## Bir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir). +SUBSTITUTE = YERİNEKOY ## Bir metin dizesinde, eski metnin yerine yeni metin koyar. +T = M ## Bağımsız değerlerini metne dönüştürür. +TEXT = METNEÇEVİR ## Bir sayıyı biçimlendirir ve metne dönüştürür. +TRIM = KIRP ## Metindeki boşlukları kaldırır. +UPPER = BÜYÜKHARF ## Metni büyük harfe çevirir. +VALUE = SAYIYAÇEVİR ## Bir metin bağımsız değişkenini sayıya dönüştürür. diff --git a/extend/phpmailer/SMTP.php b/extend/phpmailer/SMTP.php new file mode 100755 index 0000000..b882e66 --- /dev/null +++ b/extend/phpmailer/SMTP.php @@ -0,0 +1,1155 @@ +<?php +/** + * PHPMailer RFC821 SMTP email transport class. + * PHP Version 5 + * @package PHPMailer + * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project + * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> + * @author Jim Jagielski (jimjag) <jimjag@gmail.com> + * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> + * @author Brent R. Matzelle (original founder) + * @copyright 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailer RFC821 SMTP email transport class. + * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. + * @package PHPMailer + * @author Chris Ryan + * @author Marcus Bointon <phpmailer@synchromedia.co.uk> + */ +namespace phpmailer; + + +class SMTP +{ + /** + * The PHPMailer SMTP version number. + * @type string + */ + const VERSION = '5.2.10'; + + /** + * SMTP line break constant. + * @type string + */ + const CRLF = "\r\n"; + + /** + * The SMTP port to use if one is not specified. + * @type integer + */ + const DEFAULT_SMTP_PORT = 25; + + /** + * The maximum line length allowed by RFC 2822 section 2.1.1 + * @type integer + */ + const MAX_LINE_LENGTH = 998; + + /** + * Debug level for no output + */ + const DEBUG_OFF = 0; + + /** + * Debug level to show client -> server messages + */ + const DEBUG_CLIENT = 1; + + /** + * Debug level to show client -> server and server -> client messages + */ + const DEBUG_SERVER = 2; + + /** + * Debug level to show connection status, client -> server and server -> client messages + */ + const DEBUG_CONNECTION = 3; + + /** + * Debug level to show all messages + */ + const DEBUG_LOWLEVEL = 4; + + /** + * The PHPMailer SMTP Version number. + * @type string + * @deprecated Use the `VERSION` constant instead + * @see SMTP::VERSION + */ + public $Version = '5.2.10'; + + /** + * SMTP server port number. + * @type integer + * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead + * @see SMTP::DEFAULT_SMTP_PORT + */ + public $SMTP_PORT = 25; + + /** + * SMTP reply line ending. + * @type string + * @deprecated Use the `CRLF` constant instead + * @see SMTP::CRLF + */ + public $CRLF = "\r\n"; + + /** + * Debug output level. + * Options: + * * self::DEBUG_OFF (`0`) No debug output, default + * * self::DEBUG_CLIENT (`1`) Client commands + * * self::DEBUG_SERVER (`2`) Client commands and server responses + * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status + * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages + * @type integer + */ + public $do_debug = self::DEBUG_OFF; + + /** + * How to handle debug output. + * Options: + * * `echo` Output plain-text as-is, appropriate for CLI + * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output + * * `error_log` Output to error log as configured in php.ini + * + * Alternatively, you can provide a callable expecting two params: a message string and the debug level: + * <code> + * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; + * </code> + * @type string|callable + */ + public $Debugoutput = 'echo'; + + /** + * Whether to use VERP. + * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @link http://www.postfix.org/VERP_README.html Info on VERP + * @type boolean + */ + public $do_verp = false; + + /** + * The timeout value for connection, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. + * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2 + * @type integer + */ + public $Timeout = 300; + + /** + * How long to wait for commands to complete, in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * @type integer + */ + public $Timelimit = 300; + + /** + * The socket for the server connection. + * @type resource + */ + protected $smtp_conn; + + /** + * Error information, if any, for the last SMTP command. + * @type array + */ + protected $error = array( + 'error' => '', + 'detail' => '', + 'smtp_code' => '', + 'smtp_code_ex' => '' + ); + + /** + * The reply the server sent to us for HELO. + * If null, no HELO string has yet been received. + * @type string|null + */ + protected $helo_rply = null; + + /** + * The set of SMTP extensions sent in reply to EHLO command. + * Indexes of the array are extension names. + * Value at index 'HELO' or 'EHLO' (according to command that was sent) + * represents the server name. In case of HELO it is the only element of the array. + * Other values can be boolean TRUE or an array containing extension options. + * If null, no HELO/EHLO string has yet been received. + * @type array|null + */ + protected $server_caps = null; + + /** + * The most recent reply received from the server. + * @type string + */ + protected $last_reply = ''; + + /** + * Output debugging info via a user-selected method. + * @see SMTP::$Debugoutput + * @see SMTP::$do_debug + * @param string $str Debug string to output + * @param integer $level The debug level of this message; see DEBUG_* constants + * @return void + */ + protected function edebug($str, $level = 0) + { + if ($level > $this->do_debug) { + return; + } + //Avoid clash with built-in function names + if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { + call_user_func($this->Debugoutput, $str, $this->do_debug); + return; + } + switch ($this->Debugoutput) { + case 'error_log': + //Don't output, just log + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking, HTML-safe output + echo htmlentities( + preg_replace('/[\r\n]+/', '', $str), + ENT_QUOTES, + 'UTF-8' + ) + . "<br>\n"; + break; + case 'echo': + default: + //Normalize line breaks + $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str); + echo gmdate('Y-m-d H:i:s') . "\t" . str_replace( + "\n", + "\n \t ", + trim($str) + )."\n"; + } + } + + /** + * Connect to an SMTP server. + * @param string $host SMTP server IP or host name + * @param integer $port The port number to connect to + * @param integer $timeout How long to wait for the connection to open + * @param array $options An array of options for stream_context_create() + * @access public + * @return boolean + */ + public function connect($host, $port = null, $timeout = 30, $options = array()) + { + static $streamok; + //This is enabled by default since 5.0.0 but some providers disable it + //Check this once and cache the result + if (is_null($streamok)) { + $streamok = function_exists('stream_socket_client'); + } + // Clear errors to avoid confusion + $this->setError(''); + // Make sure we are __not__ connected + if ($this->connected()) { + // Already connected, generate error + $this->setError('Already connected to a server'); + return false; + } + if (empty($port)) { + $port = self::DEFAULT_SMTP_PORT; + } + // Connect to the SMTP server + $this->edebug( + "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true), + self::DEBUG_CONNECTION + ); + $errno = 0; + $errstr = ''; + if ($streamok) { + $socket_context = stream_context_create($options); + //Suppress errors; connection failures are handled at a higher level + $this->smtp_conn = @stream_socket_client( + $host . ":" . $port, + $errno, + $errstr, + $timeout, + STREAM_CLIENT_CONNECT, + $socket_context + ); + } else { + //Fall back to fsockopen which should work in more places, but is missing some features + $this->edebug( + "Connection: stream_socket_client not available, falling back to fsockopen", + self::DEBUG_CONNECTION + ); + $this->smtp_conn = fsockopen( + $host, + $port, + $errno, + $errstr, + $timeout + ); + } + // Verify we connected properly + if (!is_resource($this->smtp_conn)) { + $this->setError( + 'Failed to connect to server', + $errno, + $errstr + ); + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] + . ": $errstr ($errno)", + self::DEBUG_CLIENT + ); + return false; + } + $this->edebug('Connection: opened', self::DEBUG_CONNECTION); + // SMTP server can take longer to respond, give longer timeout for first read + // Windows does not have support for this timeout function + if (substr(PHP_OS, 0, 3) != 'WIN') { + $max = ini_get('max_execution_time'); + // Don't bother if unlimited + if ($max != 0 && $timeout > $max) { + @set_time_limit($timeout); + } + stream_set_timeout($this->smtp_conn, $timeout, 0); + } + // Get any announcement + $announce = $this->get_lines(); + $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); + return true; + } + + /** + * Initiate a TLS (encrypted) session. + * @access public + * @return boolean + */ + public function startTLS() + { + if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { + return false; + } + // Begin encrypted connection + if (!stream_socket_enable_crypto( + $this->smtp_conn, + true, + STREAM_CRYPTO_METHOD_TLS_CLIENT + )) { + return false; + } + return true; + } + + /** + * Perform SMTP authentication. + * Must be run after hello(). + * @see hello() + * @param string $username The user name + * @param string $password The password + * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5) + * @param string $realm The auth realm for NTLM + * @param string $workstation The auth workstation for NTLM + * @access public + * @return boolean True if successfully authenticated. + */ + public function authenticate( + $username, + $password, + $authtype = null, + $realm = '', + $workstation = '' + ) { + if (!$this->server_caps) { + $this->setError('Authentication is not allowed before HELO/EHLO'); + return false; + } + + if (array_key_exists('EHLO', $this->server_caps)) { + // SMTP extensions are available. Let's try to find a proper authentication method + + if (!array_key_exists('AUTH', $this->server_caps)) { + $this->setError('Authentication is not allowed at this stage'); + // 'at this stage' means that auth may be allowed after the stage changes + // e.g. after STARTTLS + return false; + } + + self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL); + self::edebug( + 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), + self::DEBUG_LOWLEVEL + ); + + if (empty($authtype)) { + foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN') as $method) { + if (in_array($method, $this->server_caps['AUTH'])) { + $authtype = $method; + break; + } + } + if (empty($authtype)) { + $this->setError('No supported authentication methods found'); + return false; + } + self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL); + } + + if (!in_array($authtype, $this->server_caps['AUTH'])) { + $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); + return false; + } + } elseif (empty($authtype)) { + $authtype = 'LOGIN'; + } + switch ($authtype) { + case 'PLAIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { + return false; + } + // Send encoded username and password + if (!$this->sendCommand( + 'User & Password', + base64_encode("\0" . $username . "\0" . $password), + 235 + ) + ) { + return false; + } + break; + case 'LOGIN': + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { + return false; + } + if (!$this->sendCommand("Username", base64_encode($username), 334)) { + return false; + } + if (!$this->sendCommand("Password", base64_encode($password), 235)) { + return false; + } + break; + case 'NTLM': + /* + * ntlm_sasl_client.php + * Bundled with Permission + * + * How to telnet in windows: + * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx + * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication + */ + require_once 'extras/ntlm_sasl_client.php'; + $temp = new stdClass; + $ntlm_client = new ntlm_sasl_client_class; + //Check that functions are available + if (!$ntlm_client->Initialize($temp)) { + $this->setError($temp->error); + $this->edebug( + 'You need to enable some modules in your php.ini file: ' + . $this->error['error'], + self::DEBUG_CLIENT + ); + return false; + } + //msg1 + $msg1 = $ntlm_client->TypeMsg1($realm, $workstation); //msg1 + + if (!$this->sendCommand( + 'AUTH NTLM', + 'AUTH NTLM ' . base64_encode($msg1), + 334 + ) + ) { + return false; + } + //Though 0 based, there is a white space after the 3 digit number + //msg2 + $challenge = substr($this->last_reply, 3); + $challenge = base64_decode($challenge); + $ntlm_res = $ntlm_client->NTLMResponse( + substr($challenge, 24, 8), + $password + ); + //msg3 + $msg3 = $ntlm_client->TypeMsg3( + $ntlm_res, + $username, + $realm, + $workstation + ); + // send encoded username + return $this->sendCommand('Username', base64_encode($msg3), 235); + case 'CRAM-MD5': + // Start authentication + if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { + return false; + } + // Get the challenge + $challenge = base64_decode(substr($this->last_reply, 4)); + + // Build the response + $response = $username . ' ' . $this->hmac($challenge, $password); + + // send encoded credentials + return $this->sendCommand('Username', base64_encode($response), 235); + default: + $this->setError("Authentication method \"$authtype\" is not supported"); + return false; + } + return true; + } + + /** + * Calculate an MD5 HMAC hash. + * Works like hash_hmac('md5', $data, $key) + * in case that function is not available + * @param string $data The data to hash + * @param string $key The key to hash with + * @access protected + * @return string + */ + protected function hmac($data, $key) + { + if (function_exists('hash_hmac')) { + return hash_hmac('md5', $data, $key); + } + + // The following borrowed from + // http://php.net/manual/en/function.mhash.php#27225 + + // RFC 2104 HMAC implementation for php. + // Creates an md5 HMAC. + // Eliminates the need to install mhash to compute a HMAC + // by Lance Rushing + + $bytelen = 64; // byte length for md5 + if (strlen($key) > $bytelen) { + $key = pack('H*', md5($key)); + } + $key = str_pad($key, $bytelen, chr(0x00)); + $ipad = str_pad('', $bytelen, chr(0x36)); + $opad = str_pad('', $bytelen, chr(0x5c)); + $k_ipad = $key ^ $ipad; + $k_opad = $key ^ $opad; + + return md5($k_opad . pack('H*', md5($k_ipad . $data))); + } + + /** + * Check connection state. + * @access public + * @return boolean True if connected. + */ + public function connected() + { + if (is_resource($this->smtp_conn)) { + $sock_status = stream_get_meta_data($this->smtp_conn); + if ($sock_status['eof']) { + // The socket is valid but we are not connected + $this->edebug( + 'SMTP NOTICE: EOF caught while checking if connected', + self::DEBUG_CLIENT + ); + $this->close(); + return false; + } + return true; // everything looks good + } + return false; + } + + /** + * Close the socket and clean up the state of the class. + * Don't use this function without first trying to use QUIT. + * @see quit() + * @access public + * @return void + */ + public function close() + { + $this->setError(''); + $this->server_caps = null; + $this->helo_rply = null; + if (is_resource($this->smtp_conn)) { + // close the connection and cleanup + fclose($this->smtp_conn); + $this->smtp_conn = null; //Makes for cleaner serialization + $this->edebug('Connection: closed', self::DEBUG_CONNECTION); + } + } + + /** + * Send an SMTP DATA command. + * Issues a data command and sends the msg_data to the server, + * finializing the mail transaction. $msg_data is the message + * that is to be send with the headers. Each header needs to be + * on a single line followed by a <CRLF> with the message headers + * and the message body being separated by and additional <CRLF>. + * Implements rfc 821: DATA <CRLF> + * @param string $msg_data Message data to send + * @access public + * @return boolean + */ + public function data($msg_data) + { + //This will use the standard timelimit + if (!$this->sendCommand('DATA', 'DATA', 354)) { + return false; + } + + /* The server is ready to accept data! + * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) + * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into + * smaller lines to fit within the limit. + * We will also look for lines that start with a '.' and prepend an additional '.'. + * NOTE: this does not count towards line-length limit. + */ + + // Normalize line breaks before exploding + $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data)); + + /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field + * of the first line (':' separated) does not contain a space then it _should_ be a header and we will + * process all lines before a blank line as headers. + */ + + $field = substr($lines[0], 0, strpos($lines[0], ':')); + $in_headers = false; + if (!empty($field) && strpos($field, ' ') === false) { + $in_headers = true; + } + + foreach ($lines as $line) { + $lines_out = array(); + if ($in_headers and $line == '') { + $in_headers = false; + } + //Break this line up into several smaller lines if it's too long + //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len), + while (isset($line[self::MAX_LINE_LENGTH])) { + //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on + //so as to avoid breaking in the middle of a word + $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); + //Deliberately matches both false and 0 + if (!$pos) { + //No nice break found, add a hard break + $pos = self::MAX_LINE_LENGTH - 1; + $lines_out[] = substr($line, 0, $pos); + $line = substr($line, $pos); + } else { + //Break at the found point + $lines_out[] = substr($line, 0, $pos); + //Move along by the amount we dealt with + $line = substr($line, $pos + 1); + } + //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1 + if ($in_headers) { + $line = "\t" . $line; + } + } + $lines_out[] = $line; + + //Send the lines to the server + foreach ($lines_out as $line_out) { + //RFC2821 section 4.5.2 + if (!empty($line_out) and $line_out[0] == '.') { + $line_out = '.' . $line_out; + } + $this->client_send($line_out . self::CRLF); + } + } + + //Message data has been sent, complete the command + //Increase timelimit for end of DATA command + $savetimelimit = $this->Timelimit; + $this->Timelimit = $this->Timelimit * 2; + $result = $this->sendCommand('DATA END', '.', 250); + //Restore timelimit + $this->Timelimit = $savetimelimit; + return $result; + } + + /** + * Send an SMTP HELO or EHLO command. + * Used to identify the sending server to the receiving server. + * This makes sure that client and server are in a known state. + * Implements RFC 821: HELO <SP> <domain> <CRLF> + * and RFC 2821 EHLO. + * @param string $host The host name or IP to connect to + * @access public + * @return boolean + */ + public function hello($host = '') + { + //Try extended hello first (RFC 2821) + return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host)); + } + + /** + * Send an SMTP HELO or EHLO command. + * Low-level implementation used by hello() + * @see hello() + * @param string $hello The HELO string + * @param string $host The hostname to say we are + * @access protected + * @return boolean + */ + protected function sendHello($hello, $host) + { + $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); + $this->helo_rply = $this->last_reply; + if ($noerror) { + $this->parseHelloFields($hello); + } else { + $this->server_caps = null; + } + return $noerror; + } + + /** + * Parse a reply to HELO/EHLO command to discover server extensions. + * In case of HELO, the only parameter that can be discovered is a server name. + * @access protected + * @param string $type - 'HELO' or 'EHLO' + */ + protected function parseHelloFields($type) + { + $this->server_caps = array(); + $lines = explode("\n", $this->last_reply); + foreach ($lines as $n => $s) { + $s = trim(substr($s, 4)); + if (!$s) { + continue; + } + $fields = explode(' ', $s); + if (!empty($fields)) { + if (!$n) { + $name = $type; + $fields = $fields[0]; + } else { + $name = array_shift($fields); + if ($name == 'SIZE') { + $fields = ($fields) ? $fields[0] : 0; + } + } + $this->server_caps[$name] = ($fields ? $fields : true); + } + } + } + + /** + * Send an SMTP MAIL command. + * Starts a mail transaction from the email address specified in + * $from. Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. + * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> + * @param string $from Source address of this message + * @access public + * @return boolean + */ + public function mail($from) + { + $useVerp = ($this->do_verp ? ' XVERP' : ''); + return $this->sendCommand( + 'MAIL FROM', + 'MAIL FROM:<' . $from . '>' . $useVerp, + 250 + ); + } + + /** + * Send an SMTP QUIT command. + * Closes the socket if there is no error or the $close_on_error argument is true. + * Implements from rfc 821: QUIT <CRLF> + * @param boolean $close_on_error Should the connection close if an error occurs? + * @access public + * @return boolean + */ + public function quit($close_on_error = true) + { + $noerror = $this->sendCommand('QUIT', 'QUIT', 221); + $err = $this->error; //Save any error + if ($noerror or $close_on_error) { + $this->close(); + $this->error = $err; //Restore any error from the quit command + } + return $noerror; + } + + /** + * Send an SMTP RCPT command. + * Sets the TO argument to $toaddr. + * Returns true if the recipient was accepted false if it was rejected. + * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> + * @param string $toaddr The address the message is being sent to + * @access public + * @return boolean + */ + public function recipient($toaddr) + { + return $this->sendCommand( + 'RCPT TO', + 'RCPT TO:<' . $toaddr . '>', + array(250, 251) + ); + } + + /** + * Send an SMTP RSET command. + * Abort any transaction that is currently in progress. + * Implements rfc 821: RSET <CRLF> + * @access public + * @return boolean True on success. + */ + public function reset() + { + return $this->sendCommand('RSET', 'RSET', 250); + } + + /** + * Send a command to an SMTP server and check its return code. + * @param string $command The command name - not sent to the server + * @param string $commandstring The actual command to send + * @param integer|array $expect One or more expected integer success codes + * @access protected + * @return boolean True on success. + */ + protected function sendCommand($command, $commandstring, $expect) + { + if (!$this->connected()) { + $this->setError("Called $command without being connected"); + return false; + } + $this->client_send($commandstring . self::CRLF); + + $this->last_reply = $this->get_lines(); + // Fetch SMTP code and possible error code explanation + $matches = array(); + if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) { + $code = $matches[1]; + $code_ex = (count($matches) > 2 ? $matches[2] : null); + // Cut off error code from each response line + $detail = preg_replace( + "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m", + '', + $this->last_reply + ); + } else { + // Fall back to simple parsing if regex fails + $code = substr($this->last_reply, 0, 3); + $code_ex = null; + $detail = substr($this->last_reply, 4); + } + + $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); + + if (!in_array($code, (array)$expect)) { + $this->setError( + "$command command failed", + $detail, + $code, + $code_ex + ); + $this->edebug( + 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, + self::DEBUG_CLIENT + ); + return false; + } + + $this->setError(''); + return true; + } + + /** + * Send an SMTP SAML command. + * Starts a mail transaction from the email address specified in $from. + * Returns true if successful or false otherwise. If True + * the mail transaction is started and then one or more recipient + * commands may be called followed by a data command. This command + * will send the message to the users terminal if they are logged + * in and send them an email. + * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> + * @param string $from The address the message is from + * @access public + * @return boolean + */ + public function sendAndMail($from) + { + return $this->sendCommand('SAML', "SAML FROM:$from", 250); + } + + /** + * Send an SMTP VRFY command. + * @param string $name The name to verify + * @access public + * @return boolean + */ + public function verify($name) + { + return $this->sendCommand('VRFY', "VRFY $name", array(250, 251)); + } + + /** + * Send an SMTP NOOP command. + * Used to keep keep-alives alive, doesn't actually do anything + * @access public + * @return boolean + */ + public function noop() + { + return $this->sendCommand('NOOP', 'NOOP', 250); + } + + /** + * Send an SMTP TURN command. + * This is an optional command for SMTP that this class does not support. + * This method is here to make the RFC821 Definition complete for this class + * and _may_ be implemented in future + * Implements from rfc 821: TURN <CRLF> + * @access public + * @return boolean + */ + public function turn() + { + $this->setError('The SMTP TURN command is not implemented'); + $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); + return false; + } + + /** + * Send raw data to the server. + * @param string $data The data to send + * @access public + * @return integer|boolean The number of bytes sent to the server or false on error + */ + public function client_send($data) + { + $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT); + return fwrite($this->smtp_conn, $data); + } + + /** + * Get the latest error. + * @access public + * @return array + */ + public function getError() + { + return $this->error; + } + + /** + * Get SMTP extensions available on the server + * @access public + * @return array|null + */ + public function getServerExtList() + { + return $this->server_caps; + } + + /** + * A multipurpose method + * The method works in three ways, dependent on argument value and current state + * 1. HELO/EHLO was not sent - returns null and set up $this->error + * 2. HELO was sent + * $name = 'HELO': returns server name + * $name = 'EHLO': returns boolean false + * $name = any string: returns null and set up $this->error + * 3. EHLO was sent + * $name = 'HELO'|'EHLO': returns server name + * $name = any string: if extension $name exists, returns boolean True + * or its options. Otherwise returns boolean False + * In other words, one can use this method to detect 3 conditions: + * - null returned: handshake was not or we don't know about ext (refer to $this->error) + * - false returned: the requested feature exactly not exists + * - positive value returned: the requested feature exists + * @param string $name Name of SMTP extension or 'HELO'|'EHLO' + * @return mixed + */ + public function getServerExt($name) + { + if (!$this->server_caps) { + $this->setError('No HELO/EHLO was sent'); + return null; + } + + // the tight logic knot ;) + if (!array_key_exists($name, $this->server_caps)) { + if ($name == 'HELO') { + return $this->server_caps['EHLO']; + } + if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) { + return false; + } + $this->setError('HELO handshake was used. Client knows nothing about server extensions'); + return null; + } + + return $this->server_caps[$name]; + } + + /** + * Get the last reply from the server. + * @access public + * @return string + */ + public function getLastReply() + { + return $this->last_reply; + } + + /** + * Read the SMTP server's response. + * Either before eof or socket timeout occurs on the operation. + * With SMTP we can tell if we have more lines to read if the + * 4th character is '-' symbol. If it is a space then we don't + * need to read anything else. + * @access protected + * @return string + */ + protected function get_lines() + { + // If the connection is bad, give up straight away + if (!is_resource($this->smtp_conn)) { + return ''; + } + $data = ''; + $endtime = 0; + stream_set_timeout($this->smtp_conn, $this->Timeout); + if ($this->Timelimit > 0) { + $endtime = time() + $this->Timelimit; + } + while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { + $str = @fgets($this->smtp_conn, 515); + $this->edebug("SMTP -> get_lines(): \$data was \"$data\"", self::DEBUG_LOWLEVEL); + $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL); + $data .= $str; + $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL); + // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen + if ((isset($str[3]) and $str[3] == ' ')) { + break; + } + // Timed-out? Log and break + $info = stream_get_meta_data($this->smtp_conn); + if ($info['timed_out']) { + $this->edebug( + 'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', + self::DEBUG_LOWLEVEL + ); + break; + } + // Now check if reads took too long + if ($endtime and time() > $endtime) { + $this->edebug( + 'SMTP -> get_lines(): timelimit reached ('. + $this->Timelimit . ' sec)', + self::DEBUG_LOWLEVEL + ); + break; + } + } + return $data; + } + + /** + * Enable or disable VERP address generation. + * @param boolean $enabled + */ + public function setVerp($enabled = false) + { + $this->do_verp = $enabled; + } + + /** + * Get VERP address generation mode. + * @return boolean + */ + public function getVerp() + { + return $this->do_verp; + } + + /** + * Set error messages and codes. + * @param string $message The error message + * @param string $detail Further detail on the error + * @param string $smtp_code An associated SMTP error code + * @param string $smtp_code_ex Extended SMTP code + */ + protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') + { + $this->error = array( + 'error' => $message, + 'detail' => $detail, + 'smtp_code' => $smtp_code, + 'smtp_code_ex' => $smtp_code_ex + ); + } + + /** + * Set debug output method. + * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it. + */ + public function setDebugOutput($method = 'echo') + { + $this->Debugoutput = $method; + } + + /** + * Get debug output method. + * @return string + */ + public function getDebugOutput() + { + return $this->Debugoutput; + } + + /** + * Set debug output level. + * @param integer $level + */ + public function setDebugLevel($level = 0) + { + $this->do_debug = $level; + } + + /** + * Get debug output level. + * @return integer + */ + public function getDebugLevel() + { + return $this->do_debug; + } + + /** + * Set SMTP timeout. + * @param integer $timeout + */ + public function setTimeout($timeout = 0) + { + $this->Timeout = $timeout; + } + + /** + * Get SMTP timeout. + * @return integer + */ + public function getTimeout() + { + return $this->Timeout; + } +} diff --git a/extend/phpmailer/phpmailer.lang-zh_cn.php b/extend/phpmailer/phpmailer.lang-zh_cn.php new file mode 100755 index 0000000..1586dba --- /dev/null +++ b/extend/phpmailer/phpmailer.lang-zh_cn.php @@ -0,0 +1,27 @@ +<?php +/** + * Simplified Chinese PHPMailer language file: refer to English translation for definitive list + * @package PHPMailer + * @author liqwei <liqwei@liqwei.com> + * @author young <masxy@foxmail.com> + */ + +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; +$PHPMAILER_LANG['empty_message'] = '邮件正文为空。'; +$PHPMAILER_LANG['encoding'] = '未知编码: '; +$PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['file_access'] = '无法访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; +$PHPMAILER_LANG['from_failed'] = '发送地址错误:'; +$PHPMAILER_LANG['instantiate'] = '未知函数调用。'; +$PHPMAILER_LANG['invalid_address'] = '发送失败,电子邮箱地址是无效的。'; +$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; +$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; +$PHPMAILER_LANG['signing'] = '登录失败:'; +$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP服务器连接失败。'; +$PHPMAILER_LANG['smtp_error'] = 'SMTP服务器出错: '; +$PHPMAILER_LANG['variable_set'] = '无法设置或重置变量:'; +//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; diff --git a/extend/phpmailer/phpmailer.php b/extend/phpmailer/phpmailer.php new file mode 100755 index 0000000..ad454c5 --- /dev/null +++ b/extend/phpmailer/phpmailer.php @@ -0,0 +1,3625 @@ +<?php +/** + * PHPMailer - PHP email creation and transport class. + * PHP Version 5 + * @package PHPMailer + * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project + * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> + * @author Jim Jagielski (jimjag) <jimjag@gmail.com> + * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> + * @author Brent R. Matzelle (original founder) + * @copyright 2012 - 2014 Marcus Bointon + * @copyright 2010 - 2012 Jim Jagielski + * @copyright 2004 - 2009 Andy Prevost + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @note This program is distributed in the hope that it will be useful - WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +/** + * PHPMailer - PHP email creation and transport class. + * @package PHPMailer + * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> + * @author Jim Jagielski (jimjag) <jimjag@gmail.com> + * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> + * @author Brent R. Matzelle (original founder) + */ +namespace phpmailer; + + +class PHPMailer +{ + /** + * The PHPMailer Version number. + * @type string + */ + public $Version = '5.2.10'; + + /** + * Email priority. + * Options: 1 = High, 3 = Normal, 5 = low. + * @type integer + */ + public $Priority = 3; + + /** + * The character set of the message. + * @type string + */ + public $CharSet = 'iso-8859-1'; + + /** + * The MIME Content-type of the message. + * @type string + */ + public $ContentType = 'text/plain'; + + /** + * The message encoding. + * Options: "8bit", "7bit", "binary", "base64", and "quoted-printable". + * @type string + */ + public $Encoding = '8bit'; + + /** + * Holds the most recent mailer error message. + * @type string + */ + public $ErrorInfo = ''; + + /** + * The From email address for the message. + * @type string + */ + public $From = 'root@localhost'; + + /** + * The From name of the message. + * @type string + */ + public $FromName = 'Root User'; + + /** + * The Sender email (Return-Path) of the message. + * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode. + * @type string + */ + public $Sender = ''; + + /** + * The Return-Path of the message. + * If empty, it will be set to either From or Sender. + * @type string + * @deprecated Email senders should never set a return-path header; + * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything. + * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference + */ + public $ReturnPath = ''; + + /** + * The Subject of the message. + * @type string + */ + public $Subject = ''; + + /** + * An HTML or plain text message body. + * If HTML then call isHTML(true). + * @type string + */ + public $Body = ''; + + /** + * The plain-text message body. + * This body can be read by mail clients that do not have HTML email + * capability such as mutt & Eudora. + * Clients that can read HTML will view the normal Body. + * @type string + */ + public $AltBody = ''; + + /** + * An iCal message part body. + * Only supported in simple alt or alt_inline message types + * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator + * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ + * @link http://kigkonsult.se/iCalcreator/ + * @type string + */ + public $Ical = ''; + + /** + * The complete compiled MIME message body. + * @access protected + * @type string + */ + protected $MIMEBody = ''; + + /** + * The complete compiled MIME message headers. + * @type string + * @access protected + */ + protected $MIMEHeader = ''; + + /** + * Extra headers that createHeader() doesn't fold in. + * @type string + * @access protected + */ + protected $mailHeader = ''; + + /** + * Word-wrap the message body to this number of chars. + * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance. + * @type integer + */ + public $WordWrap = 0; + + /** + * Which method to use to send mail. + * Options: "mail", "sendmail", or "smtp". + * @type string + */ + public $Mailer = 'mail'; + + /** + * The path to the sendmail program. + * @type string + */ + public $Sendmail = '/usr/sbin/sendmail'; + + /** + * Whether mail() uses a fully sendmail-compatible MTA. + * One which supports sendmail's "-oi -f" options. + * @type boolean + */ + public $UseSendmailOptions = true; + + /** + * Path to PHPMailer plugins. + * Useful if the SMTP class is not in the PHP include path. + * @type string + * @deprecated Should not be needed now there is an autoloader. + */ + public $PluginDir = ''; + + /** + * The email address that a reading confirmation should be sent to. + * @type string + */ + public $ConfirmReadingTo = ''; + + /** + * The hostname to use in Message-Id and Received headers + * and as default HELO string. + * If empty, the value returned + * by SERVER_NAME is used or 'localhost.localdomain'. + * @type string + */ + public $Hostname = ''; + + /** + * An ID to be used in the Message-Id header. + * If empty, a unique id will be generated. + * @type string + */ + public $MessageID = ''; + + /** + * The message Date to be used in the Date header. + * If empty, the current date will be added. + * @type string + */ + public $MessageDate = ''; + + /** + * SMTP hosts. + * Either a single hostname or multiple semicolon-delimited hostnames. + * You can also specify a different port + * for each host by using this format: [hostname:port] + * (e.g. "smtp1.example.com:25;smtp2.example.com"). + * You can also specify encryption type, for example: + * (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). + * Hosts will be tried in order. + * @type string + */ + public $Host = 'localhost'; + + /** + * The default SMTP server port. + * @type integer + * @TODO Why is this needed when the SMTP class takes care of it? + */ + public $Port = 25; + + /** + * The SMTP HELO of the message. + * Default is $Hostname. + * @type string + * @see PHPMailer::$Hostname + */ + public $Helo = ''; + + /** + * What kind of encryption to use on the SMTP connection. + * Options: '', 'ssl' or 'tls' + * @type string + */ + public $SMTPSecure = ''; + + /** + * Whether to enable TLS encryption automatically if a server supports it, + * even if `SMTPSecure` is not set to 'tls'. + * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid. + * @type boolean + */ + public $SMTPAutoTLS = true; + + /** + * Whether to use SMTP authentication. + * Uses the Username and Password properties. + * @type boolean + * @see PHPMailer::$Username + * @see PHPMailer::$Password + */ + public $SMTPAuth = false; + + /** + * Options array passed to stream_context_create when connecting via SMTP. + * @type array + */ + public $SMTPOptions = array(); + + /** + * SMTP username. + * @type string + */ + public $Username = ''; + + /** + * SMTP password. + * @type string + */ + public $Password = ''; + + /** + * SMTP auth type. + * Options are LOGIN (default), PLAIN, NTLM, CRAM-MD5 + * @type string + */ + public $AuthType = ''; + + /** + * SMTP realm. + * Used for NTLM auth + * @type string + */ + public $Realm = ''; + + /** + * SMTP workstation. + * Used for NTLM auth + * @type string + */ + public $Workstation = ''; + + /** + * The SMTP server timeout in seconds. + * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 + * @type integer + */ + public $Timeout = 300; + + /** + * SMTP class debug output mode. + * Debug output level. + * Options: + * * `0` No output + * * `1` Commands + * * `2` Data and commands + * * `3` As 2 plus connection status + * * `4` Low-level data output + * @type integer + * @see SMTP::$do_debug + */ + public $SMTPDebug = 0; + + /** + * How to handle debug output. + * Options: + * * `echo` Output plain-text as-is, appropriate for CLI + * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output + * * `error_log` Output to error log as configured in php.ini + * + * Alternatively, you can provide a callable expecting two params: a message string and the debug level: + * <code> + * $mail->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; + * </code> + * @type string|callable + * @see SMTP::$Debugoutput + */ + public $Debugoutput = 'echo'; + + /** + * Whether to keep SMTP connection open after each message. + * If this is set to true then to close the connection + * requires an explicit call to smtpClose(). + * @type boolean + */ + public $SMTPKeepAlive = false; + + /** + * Whether to split multiple to addresses into multiple messages + * or send them all in one message. + * @type boolean + */ + public $SingleTo = false; + + /** + * Storage for addresses when SingleTo is enabled. + * @type array + * @TODO This should really not be public + */ + public $SingleToArray = array(); + + /** + * Whether to generate VERP addresses on send. + * Only applicable when sending via SMTP. + * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path + * @link http://www.postfix.org/VERP_README.html Postfix VERP info + * @type boolean + */ + public $do_verp = false; + + /** + * Whether to allow sending messages with an empty body. + * @type boolean + */ + public $AllowEmpty = false; + + /** + * The default line ending. + * @note The default remains "\n". We force CRLF where we know + * it must be used via self::CRLF. + * @type string + */ + public $LE = "\n"; + + /** + * DKIM selector. + * @type string + */ + public $DKIM_selector = ''; + + /** + * DKIM Identity. + * Usually the email address used as the source of the email + * @type string + */ + public $DKIM_identity = ''; + + /** + * DKIM passphrase. + * Used if your key is encrypted. + * @type string + */ + public $DKIM_passphrase = ''; + + /** + * DKIM signing domain name. + * @example 'example.com' + * @type string + */ + public $DKIM_domain = ''; + + /** + * DKIM private key file path. + * @type string + */ + public $DKIM_private = ''; + + /** + * Callback Action function name. + * + * The function that handles the result of the send email action. + * It is called out by send() for each email sent. + * + * Value can be any php callable: http://www.php.net/is_callable + * + * Parameters: + * boolean $result result of the send action + * string $to email address of the recipient + * string $cc cc email addresses + * string $bcc bcc email addresses + * string $subject the subject + * string $body the email body + * string $from email address of sender + * @type string + */ + public $action_function = ''; + + /** + * What to put in the X-Mailer header. + * Options: An empty string for PHPMailer default, whitespace for none, or a string to use + * @type string + */ + public $XMailer = ''; + + /** + * An instance of the SMTP sender class. + * @type SMTP + * @access protected + */ + protected $smtp = null; + + /** + * The array of 'to' addresses. + * @type array + * @access protected + */ + protected $to = array(); + + /** + * The array of 'cc' addresses. + * @type array + * @access protected + */ + protected $cc = array(); + + /** + * The array of 'bcc' addresses. + * @type array + * @access protected + */ + protected $bcc = array(); + + /** + * The array of reply-to names and addresses. + * @type array + * @access protected + */ + protected $ReplyTo = array(); + + /** + * An array of all kinds of addresses. + * Includes all of $to, $cc, $bcc + * @type array + * @access protected + */ + protected $all_recipients = array(); + + /** + * The array of attachments. + * @type array + * @access protected + */ + protected $attachment = array(); + + /** + * The array of custom headers. + * @type array + * @access protected + */ + protected $CustomHeader = array(); + + /** + * The most recent Message-ID (including angular brackets). + * @type string + * @access protected + */ + protected $lastMessageID = ''; + + /** + * The message's MIME type. + * @type string + * @access protected + */ + protected $message_type = ''; + + /** + * The array of MIME boundary strings. + * @type array + * @access protected + */ + protected $boundary = array(); + + /** + * The array of available languages. + * @type array + * @access protected + */ + protected $language = array(); + + /** + * The number of errors encountered. + * @type integer + * @access protected + */ + protected $error_count = 0; + + /** + * The S/MIME certificate file path. + * @type string + * @access protected + */ + protected $sign_cert_file = ''; + + /** + * The S/MIME key file path. + * @type string + * @access protected + */ + protected $sign_key_file = ''; + + /** + * The optional S/MIME extra certificates ("CA Chain") file path. + * @type string + * @access protected + */ + protected $sign_extracerts_file = ''; + + /** + * The S/MIME password for the key. + * Used only if the key is encrypted. + * @type string + * @access protected + */ + protected $sign_key_pass = ''; + + /** + * Whether to throw exceptions for errors. + * @type boolean + * @access protected + */ + protected $exceptions = false; + + /** + * Unique ID used for message ID and boundaries. + * @type string + * @access protected + */ + protected $uniqueid = ''; + + /** + * Error severity: message only, continue processing. + */ + const STOP_MESSAGE = 0; + + /** + * Error severity: message, likely ok to continue processing. + */ + const STOP_CONTINUE = 1; + + /** + * Error severity: message, plus full stop, critical error reached. + */ + const STOP_CRITICAL = 2; + + /** + * SMTP RFC standard line ending. + */ + const CRLF = "\r\n"; + + /** + * The maximum line length allowed by RFC 2822 section 2.1.1 + * @type integer + */ + const MAX_LINE_LENGTH = 998; + + /** + * Constructor. + * @param boolean $exceptions Should we throw external exceptions? + */ + public function __construct($exceptions = false) + { + $this->exceptions = (boolean)$exceptions; + } + + /** + * Destructor. + */ + public function __destruct() + { + //Close any open SMTP connection nicely + if ($this->Mailer == 'smtp') { + $this->smtpClose(); + } + } + + /** + * Call mail() in a safe_mode-aware fashion. + * Also, unless sendmail_path points to sendmail (or something that + * claims to be sendmail), don't pass params (not a perfect fix, + * but it will do) + * @param string $to To + * @param string $subject Subject + * @param string $body Message Body + * @param string $header Additional Header(s) + * @param string $params Params + * @access private + * @return boolean + */ + private function mailPassthru($to, $subject, $body, $header, $params) + { + //Check overloading of mail function to avoid double-encoding + if (ini_get('mbstring.func_overload') & 1) { + $subject = $this->secureHeader($subject); + } else { + $subject = $this->encodeHeader($this->secureHeader($subject)); + } + if (ini_get('safe_mode') || !($this->UseSendmailOptions)) { + $result = @mail($to, $subject, $body, $header); + } else { + $result = @mail($to, $subject, $body, $header, $params); + } + return $result; + } + + /** + * Output debugging info via user-defined method. + * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug). + * @see PHPMailer::$Debugoutput + * @see PHPMailer::$SMTPDebug + * @param string $str + */ + protected function edebug($str) + { + if ($this->SMTPDebug <= 0) { + return; + } + //Avoid clash with built-in function names + if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { + call_user_func($this->Debugoutput, $str, $this->SMTPDebug); + return; + } + switch ($this->Debugoutput) { + case 'error_log': + //Don't output, just log + error_log($str); + break; + case 'html': + //Cleans up output a bit for a better looking, HTML-safe output + echo htmlentities( + preg_replace('/[\r\n]+/', '', $str), + ENT_QUOTES, + 'UTF-8' + ) + . "<br>\n"; + break; + case 'echo': + default: + //Normalize line breaks + $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str); + echo gmdate('Y-m-d H:i:s') . "\t" . str_replace( + "\n", + "\n \t ", + trim($str) + ) . "\n"; + } + } + + /** + * Sets message type to HTML or plain. + * @param boolean $isHtml True for HTML mode. + * @return void + */ + public function isHTML($isHtml = true) + { + if ($isHtml) { + $this->ContentType = 'text/html'; + } else { + $this->ContentType = 'text/plain'; + } + } + + /** + * Send messages using SMTP. + * @return void + */ + public function isSMTP() + { + $this->Mailer = 'smtp'; + } + + /** + * Send messages using PHP's mail() function. + * @return void + */ + public function isMail() + { + $this->Mailer = 'mail'; + } + + /** + * Send messages using $Sendmail. + * @return void + */ + public function isSendmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (!stristr($ini_sendmail_path, 'sendmail')) { + $this->Sendmail = '/usr/sbin/sendmail'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'sendmail'; + } + + /** + * Send messages using qmail. + * @return void + */ + public function isQmail() + { + $ini_sendmail_path = ini_get('sendmail_path'); + + if (!stristr($ini_sendmail_path, 'qmail')) { + $this->Sendmail = '/var/qmail/bin/qmail-inject'; + } else { + $this->Sendmail = $ini_sendmail_path; + } + $this->Mailer = 'qmail'; + } + + /** + * Add a "To" address. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function addAddress($address, $name = '') + { + return $this->addAnAddress('to', $address, $name); + } + + /** + * Add a "CC" address. + * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function addCC($address, $name = '') + { + return $this->addAnAddress('cc', $address, $name); + } + + /** + * Add a "BCC" address. + * @note: This function works with the SMTP mailer on win32, not with the "mail" mailer. + * @param string $address + * @param string $name + * @return boolean true on success, false if address already used + */ + public function addBCC($address, $name = '') + { + return $this->addAnAddress('bcc', $address, $name); + } + + /** + * Add a "Reply-to" address. + * @param string $address + * @param string $name + * @return boolean + */ + public function addReplyTo($address, $name = '') + { + return $this->addAnAddress('Reply-To', $address, $name); + } + + /** + * Add an address to one of the recipient arrays. + * Addresses that have been added already return false, but do not throw exceptions + * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo' + * @param string $address The email address to send to + * @param string $name + * @throws phpmailerException + * @return boolean true on success, false if address already used or invalid in some way + * @access protected + */ + protected function addAnAddress($kind, $address, $name = '') + { + if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) { + $this->setError($this->lang('Invalid recipient array') . ': ' . $kind); + $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind); + if ($this->exceptions) { + throw new phpmailerException('Invalid recipient array: ' . $kind); + } + return false; + } + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!$this->validateAddress($address)) { + $this->setError($this->lang('invalid_address') . ': ' . $address); + $this->edebug($this->lang('invalid_address') . ': ' . $address); + if ($this->exceptions) { + throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + } + return false; + } + if ($kind != 'Reply-To') { + if (!isset($this->all_recipients[strtolower($address)])) { + array_push($this->$kind, array($address, $name)); + $this->all_recipients[strtolower($address)] = true; + return true; + } + } else { + if (!array_key_exists(strtolower($address), $this->ReplyTo)) { + $this->ReplyTo[strtolower($address)] = array($address, $name); + return true; + } + } + return false; + } + + /** + * Set the From and FromName properties. + * @param string $address + * @param string $name + * @param boolean $auto Whether to also set the Sender address, defaults to true + * @throws phpmailerException + * @return boolean + */ + public function setFrom($address, $name = '', $auto = true) + { + $address = trim($address); + $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim + if (!$this->validateAddress($address)) { + $this->setError($this->lang('invalid_address') . ': ' . $address); + $this->edebug($this->lang('invalid_address') . ': ' . $address); + if ($this->exceptions) { + throw new phpmailerException($this->lang('invalid_address') . ': ' . $address); + } + return false; + } + $this->From = $address; + $this->FromName = $name; + if ($auto) { + if (empty($this->Sender)) { + $this->Sender = $address; + } + } + return true; + } + + /** + * Return the Message-ID header of the last email. + * Technically this is the value from the last time the headers were created, + * but it's also the message ID of the last sent message except in + * pathological cases. + * @return string + */ + public function getLastMessageID() + { + return $this->lastMessageID; + } + + /** + * Check that a string looks like an email address. + * @param string $address The email address to check + * @param string $patternselect A selector for the validation pattern to use : + * * `auto` Pick strictest one automatically; + * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14; + * * `pcre` Use old PCRE implementation; + * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; same as pcre8 but does not allow 'dotless' domains; + * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. + * * `noregex` Don't use a regex: super fast, really dumb. + * @return boolean + * @static + * @access public + */ + public static function validateAddress($address, $patternselect = 'auto') + { + if (!$patternselect or $patternselect == 'auto') { + //Check this constant first so it works when extension_loaded() is disabled by safe mode + //Constant was added in PHP 5.2.4 + if (defined('PCRE_VERSION')) { + //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2 + if (version_compare(PCRE_VERSION, '8.0.3') >= 0) { + $patternselect = 'pcre8'; + } else { + $patternselect = 'pcre'; + } + } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) { + //Fall back to older PCRE + $patternselect = 'pcre'; + } else { + //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension + if (version_compare(PHP_VERSION, '5.2.0') >= 0) { + $patternselect = 'php'; + } else { + $patternselect = 'noregex'; + } + } + } + switch ($patternselect) { + case 'pcre8': + /** + * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains. + * @link http://squiloople.com/2009/12/20/email-address-validation/ + * @copyright 2009-2010 Michael Rushton + * Feel free to use and redistribute this code. But please keep this copyright notice. + */ + return (boolean)preg_match( + '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . + '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . + '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . + '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . + '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . + '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . + '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . + '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . + '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', + $address + ); + case 'pcre': + //An older regex that doesn't need a recent PCRE + return (boolean)preg_match( + '/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' . + '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' . + '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' . + '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' . + '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' . + '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' . + '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' . + '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' . + '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' . + '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD', + $address + ); + case 'html5': + /** + * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements. + * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email) + */ + return (boolean)preg_match( + '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . + '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', + $address + ); + case 'noregex': + //No PCRE! Do something _very_ approximate! + //Check the address is 3 chars or longer and contains an @ that's not the first or last char + return (strlen($address) >= 3 + and strpos($address, '@') >= 1 + and strpos($address, '@') != strlen($address) - 1); + case 'php': + default: + return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL); + } + } + + /** + * Create a message and send it. + * Uses the sending method specified by $Mailer. + * @throws phpmailerException + * @return boolean false on error - See the ErrorInfo property for details of the error. + */ + public function send() + { + try { + if (!$this->preSend()) { + return false; + } + return $this->postSend(); + } catch (phpmailerException $exc) { + $this->mailHeader = ''; + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + } + + /** + * Prepare a message for sending. + * @throws phpmailerException + * @return boolean + */ + public function preSend() + { + try { + $this->mailHeader = ''; + if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { + throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL); + } + + // Set whether the message is multipart/alternative + if (!empty($this->AltBody)) { + $this->ContentType = 'multipart/alternative'; + } + + $this->error_count = 0; // Reset errors + $this->setMessageType(); + // Refuse to send an empty message unless we are specifically allowing it + if (!$this->AllowEmpty and empty($this->Body)) { + throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL); + } + + // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding) + $this->MIMEHeader = ''; + $this->MIMEBody = $this->createBody(); + // createBody may have added some headers, so retain them + $tempheaders = $this->MIMEHeader; + $this->MIMEHeader = $this->createHeader(); + $this->MIMEHeader .= $tempheaders; + + // To capture the complete message when using mail(), create + // an extra header list which createHeader() doesn't fold in + if ($this->Mailer == 'mail') { + if (count($this->to) > 0) { + $this->mailHeader .= $this->addrAppend('To', $this->to); + } else { + $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + $this->mailHeader .= $this->headerLine( + 'Subject', + $this->encodeHeader($this->secureHeader(trim($this->Subject))) + ); + } + + // Sign with DKIM if enabled + if (!empty($this->DKIM_domain) + && !empty($this->DKIM_private) + && !empty($this->DKIM_selector) + && file_exists($this->DKIM_private)) { + $header_dkim = $this->DKIM_Add( + $this->MIMEHeader . $this->mailHeader, + $this->encodeHeader($this->secureHeader($this->Subject)), + $this->MIMEBody + ); + $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . + str_replace("\r\n", "\n", $header_dkim) . self::CRLF; + } + return true; + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + } + + /** + * Actually send a message. + * Send the email via the selected mechanism + * @throws phpmailerException + * @return boolean + */ + public function postSend() + { + try { + // Choose the mailer and send through it + switch ($this->Mailer) { + case 'sendmail': + case 'qmail': + return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody); + case 'smtp': + return $this->smtpSend($this->MIMEHeader, $this->MIMEBody); + case 'mail': + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + default: + $sendMethod = $this->Mailer.'Send'; + if (method_exists($this, $sendMethod)) { + return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody); + } + + return $this->mailSend($this->MIMEHeader, $this->MIMEBody); + } + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + } + return false; + } + + /** + * Send mail using the $Sendmail program. + * @param string $header The message headers + * @param string $body The message body + * @see PHPMailer::$Sendmail + * @throws phpmailerException + * @access protected + * @return boolean + */ + protected function sendmailSend($header, $body) + { + if ($this->Sender != '') { + if ($this->Mailer == 'qmail') { + $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + } else { + $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); + } + } else { + if ($this->Mailer == 'qmail') { + $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail)); + } else { + $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail)); + } + } + if ($this->SingleTo) { + foreach ($this->SingleToArray as $toAddr) { + if (!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, 'To: ' . $toAddr . "\n"); + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + $this->doCallback( + ($result == 0), + array($toAddr), + $this->cc, + $this->bcc, + $this->Subject, + $body, + $this->From + ); + if ($result != 0) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + } else { + if (!@$mail = popen($sendmail, 'w')) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + $this->doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + if ($result != 0) { + throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL); + } + } + return true; + } + + /** + * Send mail using the PHP mail() function. + * @param string $header The message headers + * @param string $body The message body + * @link http://www.php.net/manual/en/book.mail.php + * @throws phpmailerException + * @access protected + * @return boolean + */ + protected function mailSend($header, $body) + { + $toArr = array(); + foreach ($this->to as $toaddr) { + $toArr[] = $this->addrFormat($toaddr); + } + $to = implode(', ', $toArr); + + if (empty($this->Sender)) { + $params = ' '; + } else { + $params = sprintf('-f%s', $this->Sender); + } + if ($this->Sender != '' and !ini_get('safe_mode')) { + $old_from = ini_get('sendmail_from'); + ini_set('sendmail_from', $this->Sender); + } + $result = false; + if ($this->SingleTo && count($toArr) > 1) { + foreach ($toArr as $toAddr) { + $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); + $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From); + } + } else { + $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params); + $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From); + } + if (isset($old_from)) { + ini_set('sendmail_from', $old_from); + } + if (!$result) { + throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL); + } + return true; + } + + /** + * Get an instance to use for SMTP operations. + * Override this function to load your own SMTP implementation + * @return SMTP + */ + public function getSMTPInstance() + { + if (!is_object($this->smtp)) { + $this->smtp = new SMTP; + } + return $this->smtp; + } + + /** + * Send mail via SMTP. + * Returns false if there is a bad MAIL FROM, RCPT, or DATA input. + * Uses the PHPMailerSMTP class by default. + * @see PHPMailer::getSMTPInstance() to use a different class. + * @param string $header The message headers + * @param string $body The message body + * @throws phpmailerException + * @uses SMTP + * @access protected + * @return boolean + */ + protected function smtpSend($header, $body) + { + $bad_rcpt = array(); + if (!$this->smtpConnect($this->SMTPOptions)) { + throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); + } + if ('' == $this->Sender) { + $smtp_from = $this->From; + } else { + $smtp_from = $this->Sender; + } + if (!$this->smtp->mail($smtp_from)) { + $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); + throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL); + } + + // Attempt to send to all recipients + foreach (array($this->to, $this->cc, $this->bcc) as $togroup) { + foreach ($togroup as $to) { + if (!$this->smtp->recipient($to[0])) { + $error = $this->smtp->getError(); + $bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']); + $isSent = false; + } else { + $isSent = true; + } + $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From); + } + } + + // Only send the DATA command if we have viable recipients + if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) { + throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL); + } + if ($this->SMTPKeepAlive) { + $this->smtp->reset(); + } else { + $this->smtp->quit(); + $this->smtp->close(); + } + //Create error message for any bad addresses + if (count($bad_rcpt) > 0) { + $errstr = ''; + foreach ($bad_rcpt as $bad) { + $errstr .= $bad['to'] . ': ' . $bad['error']; + } + throw new phpmailerException( + $this->lang('recipients_failed') . $errstr, + self::STOP_CONTINUE + ); + } + return true; + } + + /** + * Initiate a connection to an SMTP server. + * Returns false if the operation failed. + * @param array $options An array of options compatible with stream_context_create() + * @uses SMTP + * @access public + * @throws phpmailerException + * @return boolean + */ + public function smtpConnect($options = array()) + { + if (is_null($this->smtp)) { + $this->smtp = $this->getSMTPInstance(); + } + + // Already connected? + if ($this->smtp->connected()) { + return true; + } + + $this->smtp->setTimeout($this->Timeout); + $this->smtp->setDebugLevel($this->SMTPDebug); + $this->smtp->setDebugOutput($this->Debugoutput); + $this->smtp->setVerp($this->do_verp); + $hosts = explode(';', $this->Host); + $lastexception = null; + + foreach ($hosts as $hostentry) { + $hostinfo = array(); + if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) { + // Not a valid host entry + continue; + } + // $hostinfo[2]: optional ssl or tls prefix + // $hostinfo[3]: the hostname + // $hostinfo[4]: optional port number + // The host string prefix can temporarily override the current setting for SMTPSecure + // If it's not specified, the default value is used + $prefix = ''; + $secure = $this->SMTPSecure; + $tls = ($this->SMTPSecure == 'tls'); + if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) { + $prefix = 'ssl://'; + $tls = false; // Can't have SSL and TLS at the same time + $secure = 'ssl'; + } elseif ($hostinfo[2] == 'tls') { + $tls = true; + // tls doesn't use a prefix + $secure = 'tls'; + } + //Do we need the OpenSSL extension? + $sslext = defined('OPENSSL_ALGO_SHA1'); + if ('tls' === $secure or 'ssl' === $secure) { + //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled + if (!$sslext) { + throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL); + } + } + $host = $hostinfo[3]; + $port = $this->Port; + $tport = (integer)$hostinfo[4]; + if ($tport > 0 and $tport < 65536) { + $port = $tport; + } + if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) { + try { + if ($this->Helo) { + $hello = $this->Helo; + } else { + $hello = $this->serverHostname(); + } + $this->smtp->hello($hello); + //Automatically enable TLS encryption if: + // * it's not disabled + // * we have openssl extension + // * we are not already using SSL + // * the server offers STARTTLS + if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) { + $tls = true; + } + if ($tls) { + if (!$this->smtp->startTLS()) { + throw new phpmailerException($this->lang('connect_host')); + } + // We must resend HELO after tls negotiation + $this->smtp->hello($hello); + } + if ($this->SMTPAuth) { + if (!$this->smtp->authenticate( + $this->Username, + $this->Password, + $this->AuthType, + $this->Realm, + $this->Workstation + ) + ) { + throw new phpmailerException($this->lang('authenticate')); + } + } + return true; + } catch (phpmailerException $exc) { + $lastexception = $exc; + $this->edebug($exc->getMessage()); + // We must have connected, but then failed TLS or Auth, so close connection nicely + $this->smtp->quit(); + } + } + } + // If we get here, all connection attempts have failed, so close connection hard + $this->smtp->close(); + // As we've caught all exceptions, just report whatever the last one was + if ($this->exceptions and !is_null($lastexception)) { + throw $lastexception; + } + return false; + } + + /** + * Close the active SMTP session if one exists. + * @return void + */ + public function smtpClose() + { + if ($this->smtp !== null) { + if ($this->smtp->connected()) { + $this->smtp->quit(); + $this->smtp->close(); + } + } + } + + /** + * Set the language for error messages. + * Returns false if it cannot load the language file. + * The default language is English. + * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") + * @param string $lang_path Path to the language file directory, with trailing separator (slash) + * @return boolean + * @access public + */ + public function setLanguage($langcode = 'en', $lang_path = '') + { + // Define full set of translatable strings in English + $PHPMAILER_LANG = array( + 'authenticate' => 'SMTP Error: Could not authenticate.', + 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', + 'data_not_accepted' => 'SMTP Error: data not accepted.', + 'empty_message' => 'Message body empty', + 'encoding' => 'Unknown encoding: ', + 'execute' => 'Could not execute: ', + 'file_access' => 'Could not access file: ', + 'file_open' => 'File Error: Could not open file: ', + 'from_failed' => 'The following From address failed: ', + 'instantiate' => 'Could not instantiate mail function.', + 'invalid_address' => 'Invalid address', + 'mailer_not_supported' => ' mailer is not supported.', + 'provide_address' => 'You must provide at least one recipient email address.', + 'recipients_failed' => 'SMTP Error: The following recipients failed: ', + 'signing' => 'Signing Error: ', + 'smtp_connect_failed' => 'SMTP connect() failed.', + 'smtp_error' => 'SMTP server error: ', + 'variable_set' => 'Cannot set or reset variable: ', + 'extension_missing' => 'Extension missing: ' + ); + if (empty($lang_path)) { + // Calculate an absolute path so it can work if CWD is not here + $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR; + } + $foundlang = true; + $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; + // There is no English translation file + if ($langcode != 'en') { + // Make sure language file path is readable + if (!is_readable($lang_file)) { + $foundlang = false; + } else { + // Overwrite language-specific strings. + // This way we'll never have missing translation keys. + $foundlang = include $lang_file; + } + } + $this->language = $PHPMAILER_LANG; + return (boolean)$foundlang; // Returns false if language not found + } + + /** + * Get the array of strings for the current language. + * @return array + */ + public function getTranslations() + { + return $this->language; + } + + /** + * Create recipient headers. + * @access public + * @param string $type + * @param array $addr An array of recipient, + * where each recipient is a 2-element indexed array with element 0 containing an address + * and element 1 containing a name, like: + * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User')) + * @return string + */ + public function addrAppend($type, $addr) + { + $addresses = array(); + foreach ($addr as $address) { + $addresses[] = $this->addrFormat($address); + } + return $type . ': ' . implode(', ', $addresses) . $this->LE; + } + + /** + * Format an address for use in a message header. + * @access public + * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name + * like array('joe@example.com', 'Joe User') + * @return string + */ + public function addrFormat($addr) + { + if (empty($addr[1])) { // No name provided + return $this->secureHeader($addr[0]); + } else { + return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader( + $addr[0] + ) . '>'; + } + } + + /** + * Word-wrap message. + * For use with mailers that do not automatically perform wrapping + * and for quoted-printable encoded messages. + * Original written by philippe. + * @param string $message The message to wrap + * @param integer $length The line length to wrap to + * @param boolean $qp_mode Whether to run in Quoted-Printable mode + * @access public + * @return string + */ + public function wrapText($message, $length, $qp_mode = false) + { + if ($qp_mode) { + $soft_break = sprintf(' =%s', $this->LE); + } else { + $soft_break = $this->LE; + } + // If utf-8 encoding is used, we will need to make sure we don't + // split multibyte characters when we wrap + $is_utf8 = (strtolower($this->CharSet) == 'utf-8'); + $lelen = strlen($this->LE); + $crlflen = strlen(self::CRLF); + + $message = $this->fixEOL($message); + //Remove a trailing line break + if (substr($message, -$lelen) == $this->LE) { + $message = substr($message, 0, -$lelen); + } + + //Split message into lines + $lines = explode($this->LE, $message); + //Message will be rebuilt in here + $message = ''; + foreach ($lines as $line) { + $words = explode(' ', $line); + $buf = ''; + $firstword = true; + foreach ($words as $word) { + if ($qp_mode and (strlen($word) > $length)) { + $space_left = $length - strlen($buf) - $crlflen; + if (!$firstword) { + if ($space_left > 20) { + $len = $space_left; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == '=') { + $len--; + } elseif (substr($word, $len - 2, 1) == '=') { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + $buf .= ' ' . $part; + $message .= $buf . sprintf('=%s', self::CRLF); + } else { + $message .= $buf . $soft_break; + } + $buf = ''; + } + while (strlen($word) > 0) { + if ($length <= 0) { + break; + } + $len = $length; + if ($is_utf8) { + $len = $this->utf8CharBoundary($word, $len); + } elseif (substr($word, $len - 1, 1) == '=') { + $len--; + } elseif (substr($word, $len - 2, 1) == '=') { + $len -= 2; + } + $part = substr($word, 0, $len); + $word = substr($word, $len); + + if (strlen($word) > 0) { + $message .= $part . sprintf('=%s', self::CRLF); + } else { + $buf = $part; + } + } + } else { + $buf_o = $buf; + if (!$firstword) { + $buf .= ' '; + } + $buf .= $word; + + if (strlen($buf) > $length and $buf_o != '') { + $message .= $buf_o . $soft_break; + $buf = $word; + } + } + $firstword = false; + } + $message .= $buf . self::CRLF; + } + + return $message; + } + + /** + * Find the last character boundary prior to $maxLength in a utf-8 + * quoted-printable encoded string. + * Original written by Colin Brown. + * @access public + * @param string $encodedText utf-8 QP text + * @param integer $maxLength Find the last character boundary prior to this length + * @return integer + */ + public function utf8CharBoundary($encodedText, $maxLength) + { + $foundSplitPos = false; + $lookBack = 3; + while (!$foundSplitPos) { + $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack); + $encodedCharPos = strpos($lastChunk, '='); + if (false !== $encodedCharPos) { + // Found start of encoded character byte within $lookBack block. + // Check the encoded byte value (the 2 chars after the '=') + $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2); + $dec = hexdec($hex); + if ($dec < 128) { + // Single byte character. + // If the encoded char was found at pos 0, it will fit + // otherwise reduce maxLength to start of the encoded char + if ($encodedCharPos > 0) { + $maxLength = $maxLength - ($lookBack - $encodedCharPos); + } + $foundSplitPos = true; + } elseif ($dec >= 192) { + // First byte of a multi byte character + // Reduce maxLength to split at start of character + $maxLength = $maxLength - ($lookBack - $encodedCharPos); + $foundSplitPos = true; + } elseif ($dec < 192) { + // Middle byte of a multi byte character, look further back + $lookBack += 3; + } + } else { + // No encoded character found + $foundSplitPos = true; + } + } + return $maxLength; + } + + /** + * Apply word wrapping to the message body. + * Wraps the message body to the number of chars set in the WordWrap property. + * You should only do this to plain-text bodies as wrapping HTML tags may break them. + * This is called automatically by createBody(), so you don't need to call it yourself. + * @access public + * @return void + */ + public function setWordWrap() + { + if ($this->WordWrap < 1) { + return; + } + + switch ($this->message_type) { + case 'alt': + case 'alt_inline': + case 'alt_attach': + case 'alt_inline_attach': + $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap); + break; + default: + $this->Body = $this->wrapText($this->Body, $this->WordWrap); + break; + } + } + + /** + * Assemble message headers. + * @access public + * @return string The assembled headers + */ + public function createHeader() + { + $result = ''; + + if ($this->MessageDate == '') { + $this->MessageDate = self::rfcDate(); + } + $result .= $this->headerLine('Date', $this->MessageDate); + + + // To be created automatically by mail() + if ($this->SingleTo) { + if ($this->Mailer != 'mail') { + foreach ($this->to as $toaddr) { + $this->SingleToArray[] = $this->addrFormat($toaddr); + } + } + } else { + if (count($this->to) > 0) { + if ($this->Mailer != 'mail') { + $result .= $this->addrAppend('To', $this->to); + } + } elseif (count($this->cc) == 0) { + $result .= $this->headerLine('To', 'undisclosed-recipients:;'); + } + } + + $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName))); + + // sendmail and mail() extract Cc from the header before sending + if (count($this->cc) > 0) { + $result .= $this->addrAppend('Cc', $this->cc); + } + + // sendmail and mail() extract Bcc from the header before sending + if (( + $this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail' + ) + and count($this->bcc) > 0 + ) { + $result .= $this->addrAppend('Bcc', $this->bcc); + } + + if (count($this->ReplyTo) > 0) { + $result .= $this->addrAppend('Reply-To', $this->ReplyTo); + } + + // mail() sets the subject itself + if ($this->Mailer != 'mail') { + $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); + } + + if ($this->MessageID != '') { + $this->lastMessageID = $this->MessageID; + } else { + $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->ServerHostname()); + } + $result .= $this->headerLine('Message-ID', $this->lastMessageID); + $result .= $this->headerLine('X-Priority', $this->Priority); + if ($this->XMailer == '') { + $result .= $this->headerLine( + 'X-Mailer', + 'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer/)' + ); + } else { + $myXmailer = trim($this->XMailer); + if ($myXmailer) { + $result .= $this->headerLine('X-Mailer', $myXmailer); + } + } + + if ($this->ConfirmReadingTo != '') { + $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); + } + + // Add custom headers + foreach ($this->CustomHeader as $header) { + $result .= $this->headerLine( + trim($header[0]), + $this->encodeHeader(trim($header[1])) + ); + } + if (!$this->sign_key_file) { + $result .= $this->headerLine('MIME-Version', '1.0'); + $result .= $this->getMailMIME(); + } + + return $result; + } + + /** + * Get the message MIME type headers. + * @access public + * @return string + */ + public function getMailMIME() + { + $result = ''; + $ismultipart = true; + switch ($this->message_type) { + case 'inline': + $result .= $this->headerLine('Content-Type', 'multipart/related;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + case 'attach': + case 'inline_attach': + case 'alt_attach': + case 'alt_inline_attach': + $result .= $this->headerLine('Content-Type', 'multipart/mixed;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + case 'alt': + case 'alt_inline': + $result .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"'); + break; + default: + // Catches case 'plain': and case '': + $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet); + $ismultipart = false; + break; + } + // RFC1341 part 5 says 7bit is assumed if not specified + if ($this->Encoding != '7bit') { + // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE + if ($ismultipart) { + if ($this->Encoding == '8bit') { + $result .= $this->headerLine('Content-Transfer-Encoding', '8bit'); + } + // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible + } else { + $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding); + } + } + + if ($this->Mailer != 'mail') { + $result .= $this->LE; + } + + return $result; + } + + /** + * Returns the whole MIME message. + * Includes complete headers and body. + * Only valid post preSend(). + * @see PHPMailer::preSend() + * @access public + * @return string + */ + public function getSentMIMEMessage() + { + return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; + } + + /** + * Assemble the message body. + * Returns an empty string on failure. + * @access public + * @throws phpmailerException + * @return string The assembled message body + */ + public function createBody() + { + $body = ''; + //Create unique IDs and preset boundaries + $this->uniqueid = md5(uniqid(time())); + $this->boundary[1] = 'b1_' . $this->uniqueid; + $this->boundary[2] = 'b2_' . $this->uniqueid; + $this->boundary[3] = 'b3_' . $this->uniqueid; + + if ($this->sign_key_file) { + $body .= $this->getMailMIME() . $this->LE; + } + + $this->setWordWrap(); + + $bodyEncoding = $this->Encoding; + $bodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? + if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) { + $bodyEncoding = '7bit'; + $bodyCharSet = 'us-ascii'; + } + //If lines are too long, and we're not already using an encoding that will shorten them, + //change to quoted-printable transfer encoding + if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) { + $this->Encoding = 'quoted-printable'; + $bodyEncoding = 'quoted-printable'; + } + + $altBodyEncoding = $this->Encoding; + $altBodyCharSet = $this->CharSet; + //Can we do a 7-bit downgrade? + if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) { + $altBodyEncoding = '7bit'; + $altBodyCharSet = 'us-ascii'; + } + //If lines are too long, change to quoted-printable transfer encoding + if (self::hasLineLongerThanMax($this->AltBody)) { + $altBodyEncoding = 'quoted-printable'; + } + //Use this as a preamble in all multipart message types + $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE; + switch ($this->message_type) { + case 'inline': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[1]); + break; + case 'attach': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'inline_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + if (!empty($this->Ical)) { + $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', ''); + $body .= $this->encodeString($this->Ical, $this->Encoding); + $body .= $this->LE . $this->LE; + } + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_inline': + $body .= $mimepre; + $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[2]); + $body .= $this->LE; + $body .= $this->endBoundary($this->boundary[1]); + break; + case 'alt_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->endBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + case 'alt_inline_attach': + $body .= $mimepre; + $body .= $this->textLine('--' . $this->boundary[1]); + $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); + $body .= $this->encodeString($this->AltBody, $altBodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->textLine('--' . $this->boundary[2]); + $body .= $this->headerLine('Content-Type', 'multipart/related;'); + $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"'); + $body .= $this->LE; + $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding); + $body .= $this->encodeString($this->Body, $bodyEncoding); + $body .= $this->LE . $this->LE; + $body .= $this->attachAll('inline', $this->boundary[3]); + $body .= $this->LE; + $body .= $this->endBoundary($this->boundary[2]); + $body .= $this->LE; + $body .= $this->attachAll('attachment', $this->boundary[1]); + break; + default: + // catch case 'plain' and case '' + $body .= $this->encodeString($this->Body, $bodyEncoding); + break; + } + + if ($this->isError()) { + $body = ''; + } elseif ($this->sign_key_file) { + try { + if (!defined('PKCS7_TEXT')) { + throw new phpmailerException($this->lang('extension_missing') . 'openssl'); + } + // @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1 + $file = tempnam(sys_get_temp_dir(), 'mail'); + if (false === file_put_contents($file, $body)) { + throw new phpmailerException($this->lang('signing') . ' Could not write temp file'); + } + $signed = tempnam(sys_get_temp_dir(), 'signed'); + //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197 + if (empty($this->sign_extracerts_file)) { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), + null + ); + } else { + $sign = @openssl_pkcs7_sign( + $file, + $signed, + 'file://' . realpath($this->sign_cert_file), + array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), + null, + PKCS7_DETACHED, + $this->sign_extracerts_file + ); + } + if ($sign) { + @unlink($file); + $body = file_get_contents($signed); + @unlink($signed); + //The message returned by openssl contains both headers and body, so need to split them up + $parts = explode("\n\n", $body, 2); + $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE; + $body = $parts[1]; + } else { + @unlink($file); + @unlink($signed); + throw new phpmailerException($this->lang('signing') . openssl_error_string()); + } + } catch (phpmailerException $exc) { + $body = ''; + if ($this->exceptions) { + throw $exc; + } + } + } + return $body; + } + + /** + * Return the start of a message boundary. + * @access protected + * @param string $boundary + * @param string $charSet + * @param string $contentType + * @param string $encoding + * @return string + */ + protected function getBoundary($boundary, $charSet, $contentType, $encoding) + { + $result = ''; + if ($charSet == '') { + $charSet = $this->CharSet; + } + if ($contentType == '') { + $contentType = $this->ContentType; + } + if ($encoding == '') { + $encoding = $this->Encoding; + } + $result .= $this->textLine('--' . $boundary); + $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet); + $result .= $this->LE; + // RFC1341 part 5 says 7bit is assumed if not specified + if ($encoding != '7bit') { + $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); + } + $result .= $this->LE; + + return $result; + } + + /** + * Return the end of a message boundary. + * @access protected + * @param string $boundary + * @return string + */ + protected function endBoundary($boundary) + { + return $this->LE . '--' . $boundary . '--' . $this->LE; + } + + /** + * Set the message type. + * PHPMailer only supports some preset message types, + * not arbitrary MIME structures. + * @access protected + * @return void + */ + protected function setMessageType() + { + $type = array(); + if ($this->alternativeExists()) { + $type[] = 'alt'; + } + if ($this->inlineImageExists()) { + $type[] = 'inline'; + } + if ($this->attachmentExists()) { + $type[] = 'attach'; + } + $this->message_type = implode('_', $type); + if ($this->message_type == '') { + $this->message_type = 'plain'; + } + } + + /** + * Format a header line. + * @access public + * @param string $name + * @param string $value + * @return string + */ + public function headerLine($name, $value) + { + return $name . ': ' . $value . $this->LE; + } + + /** + * Return a formatted mail line. + * @access public + * @param string $value + * @return string + */ + public function textLine($value) + { + return $value . $this->LE; + } + + /** + * Add an attachment from a path on the filesystem. + * Returns false if the file could not be found or read. + * @param string $path Path to the attachment. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @param string $disposition Disposition to use + * @throws phpmailerException + * @return boolean + */ + public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment') + { + try { + if (!@is_file($path)) { + throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE); + } + + // If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($path); + } + + $filename = basename($path); + if ($name == '') { + $name = $filename; + } + + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => 0 + ); + + } catch (phpmailerException $exc) { + $this->setError($exc->getMessage()); + $this->edebug($exc->getMessage()); + if ($this->exceptions) { + throw $exc; + } + return false; + } + return true; + } + + /** + * Return the array of attachments. + * @return array + */ + public function getAttachments() + { + return $this->attachment; + } + + /** + * Attach all file, string, and binary attachments to the message. + * Returns an empty string on failure. + * @access protected + * @param string $disposition_type + * @param string $boundary + * @return string + */ + protected function attachAll($disposition_type, $boundary) + { + // Return text of body + $mime = array(); + $cidUniq = array(); + $incl = array(); + + // Add all attachments + foreach ($this->attachment as $attachment) { + // Check if it is a valid disposition_filter + if ($attachment[6] == $disposition_type) { + // Check for string attachment + $string = ''; + $path = ''; + $bString = $attachment[5]; + if ($bString) { + $string = $attachment[0]; + } else { + $path = $attachment[0]; + } + + $inclhash = md5(serialize($attachment)); + if (in_array($inclhash, $incl)) { + continue; + } + $incl[] = $inclhash; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; + if ($disposition == 'inline' && isset($cidUniq[$cid])) { + continue; + } + $cidUniq[$cid] = true; + + $mime[] = sprintf('--%s%s', $boundary, $this->LE); + $mime[] = sprintf( + 'Content-Type: %s; name="%s"%s', + $type, + $this->encodeHeader($this->secureHeader($name)), + $this->LE + ); + // RFC1341 part 5 says 7bit is assumed if not specified + if ($encoding != '7bit') { + $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE); + } + + if ($disposition == 'inline') { + $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE); + } + + // If a filename contains any of these chars, it should be quoted, + // but not otherwise: RFC2183 & RFC2045 5.1 + // Fixes a warning in IETF's msglint MIME checker + // Allow for bypassing the Content-Disposition header totally + if (!(empty($disposition))) { + $encoded_name = $this->encodeHeader($this->secureHeader($name)); + if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) { + $mime[] = sprintf( + 'Content-Disposition: %s; filename="%s"%s', + $disposition, + $encoded_name, + $this->LE . $this->LE + ); + } else { + $mime[] = sprintf( + 'Content-Disposition: %s; filename=%s%s', + $disposition, + $encoded_name, + $this->LE . $this->LE + ); + } + } else { + $mime[] = $this->LE; + } + + // Encode as string attachment + if ($bString) { + $mime[] = $this->encodeString($string, $encoding); + if ($this->isError()) { + return ''; + } + $mime[] = $this->LE . $this->LE; + } else { + $mime[] = $this->encodeFile($path, $encoding); + if ($this->isError()) { + return ''; + } + $mime[] = $this->LE . $this->LE; + } + } + } + + $mime[] = sprintf('--%s--%s', $boundary, $this->LE); + + return implode('', $mime); + } + + /** + * Encode a file attachment in requested format. + * Returns an empty string on failure. + * @param string $path The full path to the file + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @throws phpmailerException + * @see EncodeFile(encodeFile + * @access protected + * @return string + */ + protected function encodeFile($path, $encoding = 'base64') + { + try { + if (!is_readable($path)) { + throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE); + } + $magic_quotes = get_magic_quotes_runtime(); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime(false); + } else { + //Doesn't exist in PHP 5.4, but we don't need to check because + //get_magic_quotes_runtime always returns false in 5.4+ + //so it will never get here + ini_set('magic_quotes_runtime', false); + } + } + $file_buffer = file_get_contents($path); + $file_buffer = $this->encodeString($file_buffer, $encoding); + if ($magic_quotes) { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + set_magic_quotes_runtime($magic_quotes); + } else { + ini_set('magic_quotes_runtime', $magic_quotes); + } + } + return $file_buffer; + } catch (Exception $exc) { + $this->setError($exc->getMessage()); + return ''; + } + } + + /** + * Encode a string in requested format. + * Returns an empty string on failure. + * @param string $str The text to encode + * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable' + * @access public + * @return string + */ + public function encodeString($str, $encoding = 'base64') + { + $encoded = ''; + switch (strtolower($encoding)) { + case 'base64': + $encoded = chunk_split(base64_encode($str), 76, $this->LE); + break; + case '7bit': + case '8bit': + $encoded = $this->fixEOL($str); + // Make sure it ends with a line break + if (substr($encoded, -(strlen($this->LE))) != $this->LE) { + $encoded .= $this->LE; + } + break; + case 'binary': + $encoded = $str; + break; + case 'quoted-printable': + $encoded = $this->encodeQP($str); + break; + default: + $this->setError($this->lang('encoding') . $encoding); + break; + } + return $encoded; + } + + /** + * Encode a header string optimally. + * Picks shortest of Q, B, quoted-printable or none. + * @access public + * @param string $str + * @param string $position + * @return string + */ + public function encodeHeader($str, $position = 'text') + { + $matchcount = 0; + switch (strtolower($position)) { + case 'phrase': + if (!preg_match('/[\200-\377]/', $str)) { + // Can't use addslashes as we don't know the value of magic_quotes_sybase + $encoded = addcslashes($str, "\0..\37\177\\\""); + if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) { + return ($encoded); + } else { + return ("\"$encoded\""); + } + } + $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches); + break; + /** @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + $matchcount = preg_match_all('/[()"]/', $str, $matches); + // Intentional fall-through + case 'text': + default: + $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches); + break; + } + + //There are no chars that need encoding + if ($matchcount == 0) { + return ($str); + } + + $maxlen = 75 - 7 - strlen($this->CharSet); + // Try to select the encoding which should produce the shortest output + if ($matchcount > strlen($str) / 3) { + // More than a third of the content will need encoding, so B encoding will be most efficient + $encoding = 'B'; + if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) { + // Use a custom function which correctly encodes and wraps long + // multibyte strings without breaking lines within a character + $encoded = $this->base64EncodeWrapMB($str, "\n"); + } else { + $encoded = base64_encode($str); + $maxlen -= $maxlen % 4; + $encoded = trim(chunk_split($encoded, $maxlen, "\n")); + } + } else { + $encoding = 'Q'; + $encoded = $this->encodeQ($str, $position); + $encoded = $this->wrapText($encoded, $maxlen, true); + $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded)); + } + + $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded); + $encoded = trim(str_replace("\n", $this->LE, $encoded)); + + return $encoded; + } + + /** + * Check if a string contains multi-byte characters. + * @access public + * @param string $str multi-byte text to wrap encode + * @return boolean + */ + public function hasMultiBytes($str) + { + if (function_exists('mb_strlen')) { + return (strlen($str) > mb_strlen($str, $this->CharSet)); + } else { // Assume no multibytes (we can't handle without mbstring functions anyway) + return false; + } + } + + /** + * Does a string contain any 8-bit chars (in any charset)? + * @param string $text + * @return boolean + */ + public function has8bitChars($text) + { + return (boolean)preg_match('/[\x80-\xFF]/', $text); + } + + /** + * Encode and wrap long multibyte strings for mail headers + * without breaking lines within a character. + * Adapted from a function by paravoid + * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 + * @access public + * @param string $str multi-byte text to wrap encode + * @param string $linebreak string to use as linefeed/end-of-line + * @return string + */ + public function base64EncodeWrapMB($str, $linebreak = null) + { + $start = '=?' . $this->CharSet . '?B?'; + $end = '?='; + $encoded = ''; + if ($linebreak === null) { + $linebreak = $this->LE; + } + + $mb_length = mb_strlen($str, $this->CharSet); + // Each line must have length <= 75, including $start and $end + $length = 75 - strlen($start) - strlen($end); + // Average multi-byte ratio + $ratio = $mb_length / strlen($str); + // Base64 has a 4:3 ratio + $avgLength = floor($length * $ratio * .75); + + for ($i = 0; $i < $mb_length; $i += $offset) { + $lookBack = 0; + do { + $offset = $avgLength - $lookBack; + $chunk = mb_substr($str, $i, $offset, $this->CharSet); + $chunk = base64_encode($chunk); + $lookBack++; + } while (strlen($chunk) > $length); + $encoded .= $chunk . $linebreak; + } + + // Chomp the last linefeed + $encoded = substr($encoded, 0, -strlen($linebreak)); + return $encoded; + } + + /** + * Encode a string in quoted-printable format. + * According to RFC2045 section 6.7. + * @access public + * @param string $string The text to encode + * @param integer $line_max Number of chars allowed on a line before wrapping + * @return string + * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment + */ + public function encodeQP($string, $line_max = 76) + { + // Use native function if it's available (>= PHP5.3) + if (function_exists('quoted_printable_encode')) { + return $this->fixEOL(quoted_printable_encode($string)); + } + // Fall back to a pure PHP implementation + $string = str_replace( + array('%20', '%0D%0A.', '%0D%0A', '%'), + array(' ', "\r\n=2E", "\r\n", '='), + rawurlencode($string) + ); + $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string); + return $this->fixEOL($string); + } + + /** + * Backward compatibility wrapper for an old QP encoding function that was removed. + * @see PHPMailer::encodeQP() + * @access public + * @param string $string + * @param integer $line_max + * @param boolean $space_conv + * @return string + * @deprecated Use encodeQP instead. + */ + public function encodeQPphp( + $string, + $line_max = 76, + /** @noinspection PhpUnusedParameterInspection */ $space_conv = false + ) { + return $this->encodeQP($string, $line_max); + } + + /** + * Encode a string using Q encoding. + * @link http://tools.ietf.org/html/rfc2047 + * @param string $str the text to encode + * @param string $position Where the text is going to be used, see the RFC for what that means + * @access public + * @return string + */ + public function encodeQ($str, $position = 'text') + { + // There should not be any EOL in the string + $pattern = ''; + $encoded = str_replace(array("\r", "\n"), '', $str); + switch (strtolower($position)) { + case 'phrase': + // RFC 2047 section 5.3 + $pattern = '^A-Za-z0-9!*+\/ -'; + break; + /** @noinspection PhpMissingBreakStatementInspection */ + case 'comment': + // RFC 2047 section 5.2 + $pattern = '\(\)"'; + // intentional fall-through + // for this reason we build the $pattern without including delimiters and [] + case 'text': + default: + // RFC 2047 section 5.1 + // Replace every high ascii, control, =, ? and _ characters + $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; + break; + } + $matches = array(); + if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { + // If the string contains an '=', make sure it's the first thing we replace + // so as to avoid double-encoding + $eqkey = array_search('=', $matches[0]); + if (false !== $eqkey) { + unset($matches[0][$eqkey]); + array_unshift($matches[0], '='); + } + foreach (array_unique($matches[0]) as $char) { + $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); + } + } + // Replace every spaces to _ (more readable than =20) + return str_replace(' ', '_', $encoded); + } + + + /** + * Add a string or binary attachment (non-filesystem). + * This method can be used to attach ascii or binary data, + * such as a BLOB record from a database. + * @param string $string String attachment data. + * @param string $filename Name of the attachment. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File extension (MIME) type. + * @param string $disposition Disposition to use + * @return void + */ + public function addStringAttachment( + $string, + $filename, + $encoding = 'base64', + $type = '', + $disposition = 'attachment' + ) { + // If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($filename); + } + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => basename($filename), + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => 0 + ); + } + + /** + * Add an embedded (inline) attachment from a file. + * This can include images, sounds, and just about any other document type. + * These differ from 'regular' attachments in that they are intended to be + * displayed inline with the message, not just attached for download. + * This is used in HTML messages that embed the images + * the HTML refers to using the $cid value. + * @param string $path Path to the attachment. + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML. + * @param string $name Overrides the attachment name. + * @param string $encoding File encoding (see $Encoding). + * @param string $type File MIME type. + * @param string $disposition Disposition to use + * @return boolean True on successfully adding an attachment + */ + public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') + { + if (!@is_file($path)) { + $this->setError($this->lang('file_access') . $path); + return false; + } + + // If a MIME type is not specified, try to work it out from the file name + if ($type == '') { + $type = self::filenameToType($path); + } + + $filename = basename($path); + if ($name == '') { + $name = $filename; + } + + // Append to $attachment array + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => $disposition, + 7 => $cid + ); + return true; + } + + /** + * Add an embedded stringified attachment. + * This can include images, sounds, and just about any other document type. + * Be sure to set the $type to an image type for images: + * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'. + * @param string $string The attachment binary data. + * @param string $cid Content ID of the attachment; Use this to reference + * the content when using an embedded image in HTML. + * @param string $name + * @param string $encoding File encoding (see $Encoding). + * @param string $type MIME type. + * @param string $disposition Disposition to use + * @return boolean True on successfully adding an attachment + */ + public function addStringEmbeddedImage( + $string, + $cid, + $name = '', + $encoding = 'base64', + $type = '', + $disposition = 'inline' + ) { + // If a MIME type is not specified, try to work it out from the name + if ($type == '') { + $type = self::filenameToType($name); + } + + // Append to $attachment array + $this->attachment[] = array( + 0 => $string, + 1 => $name, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => $disposition, + 7 => $cid + ); + return true; + } + + /** + * Check if an inline attachment is present. + * @access public + * @return boolean + */ + public function inlineImageExists() + { + foreach ($this->attachment as $attachment) { + if ($attachment[6] == 'inline') { + return true; + } + } + return false; + } + + /** + * Check if an attachment (non-inline) is present. + * @return boolean + */ + public function attachmentExists() + { + foreach ($this->attachment as $attachment) { + if ($attachment[6] == 'attachment') { + return true; + } + } + return false; + } + + /** + * Check if this message has an alternative body set. + * @return boolean + */ + public function alternativeExists() + { + return !empty($this->AltBody); + } + + /** + * Clear all To recipients. + * @return void + */ + public function clearAddresses() + { + foreach ($this->to as $to) { + unset($this->all_recipients[strtolower($to[0])]); + } + $this->to = array(); + } + + /** + * Clear all CC recipients. + * @return void + */ + public function clearCCs() + { + foreach ($this->cc as $cc) { + unset($this->all_recipients[strtolower($cc[0])]); + } + $this->cc = array(); + } + + /** + * Clear all BCC recipients. + * @return void + */ + public function clearBCCs() + { + foreach ($this->bcc as $bcc) { + unset($this->all_recipients[strtolower($bcc[0])]); + } + $this->bcc = array(); + } + + /** + * Clear all ReplyTo recipients. + * @return void + */ + public function clearReplyTos() + { + $this->ReplyTo = array(); + } + + /** + * Clear all recipient types. + * @return void + */ + public function clearAllRecipients() + { + $this->to = array(); + $this->cc = array(); + $this->bcc = array(); + $this->all_recipients = array(); + } + + /** + * Clear all filesystem, string, and binary attachments. + * @return void + */ + public function clearAttachments() + { + $this->attachment = array(); + } + + /** + * Clear all custom headers. + * @return void + */ + public function clearCustomHeaders() + { + $this->CustomHeader = array(); + } + + /** + * Add an error message to the error container. + * @access protected + * @param string $msg + * @return void + */ + protected function setError($msg) + { + $this->error_count++; + if ($this->Mailer == 'smtp' and !is_null($this->smtp)) { + $lasterror = $this->smtp->getError(); + if (!empty($lasterror['error'])) { + $msg .= $this->lang('smtp_error') . $lasterror['error']; + if (!empty($lasterror['detail'])) { + $msg .= ' Detail: '. $lasterror['detail']; + } + if (!empty($lasterror['smtp_code'])) { + $msg .= ' SMTP code: ' . $lasterror['smtp_code']; + } + if (!empty($lasterror['smtp_code_ex'])) { + $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex']; + } + } + } + $this->ErrorInfo = $msg; + } + + /** + * Return an RFC 822 formatted date. + * @access public + * @return string + * @static + */ + public static function rfcDate() + { + // Set the time zone to whatever the default is to avoid 500 errors + // Will default to UTC if it's not set properly in php.ini + date_default_timezone_set(@date_default_timezone_get()); + return date('D, j M Y H:i:s O'); + } + + /** + * Get the server hostname. + * Returns 'localhost.localdomain' if unknown. + * @access protected + * @return string + */ + protected function serverHostname() + { + $result = 'localhost.localdomain'; + if (!empty($this->Hostname)) { + $result = $this->Hostname; + } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + $result = $_SERVER['SERVER_NAME']; + } elseif (function_exists('gethostname') && gethostname() !== false) { + $result = gethostname(); + } elseif (php_uname('n') !== false) { + $result = php_uname('n'); + } + return $result; + } + + /** + * Get an error message in the current language. + * @access protected + * @param string $key + * @return string + */ + protected function lang($key) + { + if (count($this->language) < 1) { + $this->setLanguage('en'); // set the default language + } + + if (array_key_exists($key, $this->language)) { + if ($key == 'smtp_connect_failed') { + //Include a link to troubleshooting docs on SMTP connection failure + //this is by far the biggest cause of support questions + //but it's usually not PHPMailer's fault. + return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting'; + } + return $this->language[$key]; + } else { + //Return the key as a fallback + return $key; + } + } + + /** + * Check if an error occurred. + * @access public + * @return boolean True if an error did occur. + */ + public function isError() + { + return ($this->error_count > 0); + } + + /** + * Ensure consistent line endings in a string. + * Changes every end of line from CRLF, CR or LF to $this->LE. + * @access public + * @param string $str String to fixEOL + * @return string + */ + public function fixEOL($str) + { + // Normalise to \n + $nstr = str_replace(array("\r\n", "\r"), "\n", $str); + // Now convert LE as needed + if ($this->LE !== "\n") { + $nstr = str_replace("\n", $this->LE, $nstr); + } + return $nstr; + } + + /** + * Add a custom header. + * $name value can be overloaded to contain + * both header name and value (name:value) + * @access public + * @param string $name Custom header name + * @param string $value Header value + * @return void + */ + public function addCustomHeader($name, $value = null) + { + if ($value === null) { + // Value passed in as name:value + $this->CustomHeader[] = explode(':', $name, 2); + } else { + $this->CustomHeader[] = array($name, $value); + } + } + + /** + * Returns all custom headers + * + * @return array + */ + public function getCustomHeaders() + { + return $this->CustomHeader; + } + + /** + * Create a message from an HTML string. + * Automatically makes modifications for inline images and backgrounds + * and creates a plain-text version by converting the HTML. + * Overwrites any existing values in $this->Body and $this->AltBody + * @access public + * @param string $message HTML message string + * @param string $basedir baseline directory for path + * @param boolean|callable $advanced Whether to use the internal HTML to text converter + * or your own custom converter @see html2text() + * @return string $message + */ + public function msgHTML($message, $basedir = '', $advanced = false) + { + preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images); + if (isset($images[2])) { + foreach ($images[2] as $imgindex => $url) { + // Convert data URIs into embedded images + if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) { + $data = substr($url, strpos($url, ',')); + if ($match[2]) { + $data = base64_decode($data); + } else { + $data = rawurldecode($data); + } + $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 + if ($this->addStringEmbeddedImage($data, $cid, '', 'base64', $match[1])) { + $message = str_replace( + $images[0][$imgindex], + $images[1][$imgindex] . '="cid:' . $cid . '"', + $message + ); + } + } elseif (!preg_match('#^[A-z]+://#', $url)) { + // Do not change urls for absolute images (thanks to corvuscorax) + $filename = basename($url); + $directory = dirname($url); + if ($directory == '.') { + $directory = ''; + } + $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2 + if (strlen($basedir) > 1 && substr($basedir, -1) != '/') { + $basedir .= '/'; + } + if (strlen($directory) > 1 && substr($directory, -1) != '/') { + $directory .= '/'; + } + if ($this->addEmbeddedImage( + $basedir . $directory . $filename, + $cid, + $filename, + 'base64', + self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION)) + ) + ) { + $message = preg_replace( + '/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', + $images[1][$imgindex] . '="cid:' . $cid . '"', + $message + ); + } + } + } + } + $this->isHTML(true); + // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better + $this->Body = $this->normalizeBreaks($message); + $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); + if (empty($this->AltBody)) { + $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . + self::CRLF . self::CRLF; + } + return $this->Body; + } + + /** + * Convert an HTML string into plain text. + * This is used by msgHTML(). + * Note - older versions of this function used a bundled advanced converter + * which was been removed for license reasons in #232 + * Example usage: + * <code> + * // Use default conversion + * $plain = $mail->html2text($html); + * // Use your own custom converter + * $plain = $mail->html2text($html, function($html) { + * $converter = new MyHtml2text($html); + * return $converter->get_text(); + * }); + * </code> + * @param string $html The HTML text to convert + * @param boolean|callable $advanced Any boolean value to use the internal converter, + * or provide your own callable for custom conversion. + * @return string + */ + public function html2text($html, $advanced = false) + { + if (is_callable($advanced)) { + return call_user_func($advanced, $html); + } + return html_entity_decode( + trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), + ENT_QUOTES, + $this->CharSet + ); + } + + /** + * Get the MIME type for a file extension. + * @param string $ext File extension + * @access public + * @return string MIME type of file. + * @static + */ + public static function _mime_types($ext = '') + { + $mimes = array( + 'xl' => 'application/excel', + 'js' => 'application/javascript', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'bin' => 'application/macbinary', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'class' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php3' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mpga' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'eml' => 'message/rfc822', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'log' => 'text/plain', + 'text' => 'text/plain', + 'txt' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'vcf' => 'text/vcard', + 'vcard' => 'text/vcard', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mov' => 'video/quicktime', + 'qt' => 'video/quicktime', + 'rv' => 'video/vnd.rn-realvideo', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie' + ); + if (array_key_exists(strtolower($ext), $mimes)) { + return $mimes[strtolower($ext)]; + } + return 'application/octet-stream'; + } + + /** + * Map a file name to a MIME type. + * Defaults to 'application/octet-stream', i.e.. arbitrary binary data. + * @param string $filename A file name or full path, does not need to exist as a file + * @return string + * @static + */ + public static function filenameToType($filename) + { + // In case the path is a URL, strip any query string before getting extension + $qpos = strpos($filename, '?'); + if (false !== $qpos) { + $filename = substr($filename, 0, $qpos); + } + $pathinfo = self::mb_pathinfo($filename); + return self::_mime_types($pathinfo['extension']); + } + + /** + * Multi-byte-safe pathinfo replacement. + * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe. + * Works similarly to the one in PHP >= 5.2.0 + * @link http://www.php.net/manual/en/function.pathinfo.php#107461 + * @param string $path A filename or path, does not need to exist as a file + * @param integer|string $options Either a PATHINFO_* constant, + * or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2 + * @return string|array + * @static + */ + public static function mb_pathinfo($path, $options = null) + { + $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => ''); + $pathinfo = array(); + if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) { + if (array_key_exists(1, $pathinfo)) { + $ret['dirname'] = $pathinfo[1]; + } + if (array_key_exists(2, $pathinfo)) { + $ret['basename'] = $pathinfo[2]; + } + if (array_key_exists(5, $pathinfo)) { + $ret['extension'] = $pathinfo[5]; + } + if (array_key_exists(3, $pathinfo)) { + $ret['filename'] = $pathinfo[3]; + } + } + switch ($options) { + case PATHINFO_DIRNAME: + case 'dirname': + return $ret['dirname']; + case PATHINFO_BASENAME: + case 'basename': + return $ret['basename']; + case PATHINFO_EXTENSION: + case 'extension': + return $ret['extension']; + case PATHINFO_FILENAME: + case 'filename': + return $ret['filename']; + default: + return $ret; + } + } + + /** + * Set or reset instance properties. + * You should avoid this function - it's more verbose, less efficient, more error-prone and + * harder to debug than setting properties directly. + * Usage Example: + * `$mail->set('SMTPSecure', 'tls');` + * is the same as: + * `$mail->SMTPSecure = 'tls';` + * @access public + * @param string $name The property name to set + * @param mixed $value The value to set the property to + * @return boolean + * @TODO Should this not be using the __set() magic function? + */ + public function set($name, $value = '') + { + if (property_exists($this, $name)) { + $this->$name = $value; + return true; + } else { + $this->setError($this->lang('variable_set') . $name); + return false; + } + } + + /** + * Strip newlines to prevent header injection. + * @access public + * @param string $str + * @return string + */ + public function secureHeader($str) + { + return trim(str_replace(array("\r", "\n"), '', $str)); + } + + /** + * Normalize line breaks in a string. + * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. + * Defaults to CRLF (for message bodies) and preserves consecutive breaks. + * @param string $text + * @param string $breaktype What kind of line break to use, defaults to CRLF + * @return string + * @access public + * @static + */ + public static function normalizeBreaks($text, $breaktype = "\r\n") + { + return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text); + } + + + /** + * Set the public and private key files and password for S/MIME signing. + * @access public + * @param string $cert_filename + * @param string $key_filename + * @param string $key_pass Password for private key + * @param string $extracerts_filename Optional path to chain certificate + */ + public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '') + { + $this->sign_cert_file = $cert_filename; + $this->sign_key_file = $key_filename; + $this->sign_key_pass = $key_pass; + $this->sign_extracerts_file = $extracerts_filename; + } + + /** + * Quoted-Printable-encode a DKIM header. + * @access public + * @param string $txt + * @return string + */ + public function DKIM_QP($txt) + { + $line = ''; + for ($i = 0; $i < strlen($txt); $i++) { + $ord = ord($txt[$i]); + if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) { + $line .= $txt[$i]; + } else { + $line .= '=' . sprintf('%02X', $ord); + } + } + return $line; + } + + /** + * Generate a DKIM signature. + * @access public + * @param string $signHeader + * @throws phpmailerException + * @return string + */ + public function DKIM_Sign($signHeader) + { + if (!defined('PKCS7_TEXT')) { + if ($this->exceptions) { + throw new phpmailerException($this->lang('extension_missing') . 'openssl'); + } + return ''; + } + $privKeyStr = file_get_contents($this->DKIM_private); + if ($this->DKIM_passphrase != '') { + $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); + } else { + $privKey = $privKeyStr; + } + if (openssl_sign($signHeader, $signature, $privKey)) { + return base64_encode($signature); + } + return ''; + } + + /** + * Generate a DKIM canonicalization header. + * @access public + * @param string $signHeader Header + * @return string + */ + public function DKIM_HeaderC($signHeader) + { + $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader); + $lines = explode("\r\n", $signHeader); + foreach ($lines as $key => $line) { + list($heading, $value) = explode(':', $line, 2); + $heading = strtolower($heading); + $value = preg_replace('/\s+/', ' ', $value); // Compress useless spaces + $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value + } + $signHeader = implode("\r\n", $lines); + return $signHeader; + } + + /** + * Generate a DKIM canonicalization body. + * @access public + * @param string $body Message Body + * @return string + */ + public function DKIM_BodyC($body) + { + if ($body == '') { + return "\r\n"; + } + // stabilize line endings + $body = str_replace("\r\n", "\n", $body); + $body = str_replace("\n", "\r\n", $body); + // END stabilize line endings + while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") { + $body = substr($body, 0, strlen($body) - 2); + } + return $body; + } + + /** + * Create the DKIM header and body in a new message header. + * @access public + * @param string $headers_line Header lines + * @param string $subject Subject + * @param string $body Body + * @return string + */ + public function DKIM_Add($headers_line, $subject, $body) + { + $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms + $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body + $DKIMquery = 'dns/txt'; // Query method + $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) + $subject_header = "Subject: $subject"; + $headers = explode($this->LE, $headers_line); + $from_header = ''; + $to_header = ''; + $current = ''; + foreach ($headers as $header) { + if (strpos($header, 'From:') === 0) { + $from_header = $header; + $current = 'from_header'; + } elseif (strpos($header, 'To:') === 0) { + $to_header = $header; + $current = 'to_header'; + } else { + if (!empty($$current) && strpos($header, ' =?') === 0) { + $$current .= $header; + } else { + $current = ''; + } + } + } + $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); + $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); + $subject = str_replace( + '|', + '=7C', + $this->DKIM_QP($subject_header) + ); // Copied header fields (dkim-quoted-printable) + $body = $this->DKIM_BodyC($body); + $DKIMlen = strlen($body); // Length of body + $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1 hash of body + if ('' == $this->DKIM_identity) { + $ident = ''; + } else { + $ident = ' i=' . $this->DKIM_identity . ';'; + } + $dkimhdrs = 'DKIM-Signature: v=1; a=' . + $DKIMsignatureType . '; q=' . + $DKIMquery . '; l=' . + $DKIMlen . '; s=' . + $this->DKIM_selector . + ";\r\n" . + "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" . + "\th=From:To:Subject;\r\n" . + "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" . + "\tz=$from\r\n" . + "\t|$to\r\n" . + "\t|$subject;\r\n" . + "\tbh=" . $DKIMb64 . ";\r\n" . + "\tb="; + $toSign = $this->DKIM_HeaderC( + $from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs + ); + $signed = $this->DKIM_Sign($toSign); + return $dkimhdrs . $signed . "\r\n"; + } + + /** + * Detect if a string contains a line longer than the maximum line length allowed. + * @param string $str + * @return boolean + * @static + */ + public static function hasLineLongerThanMax($str) + { + //+2 to include CRLF line break for a 1000 total + return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str); + } + + /** + * Allows for public read access to 'to' property. + * @access public + * @return array + */ + public function getToAddresses() + { + return $this->to; + } + + /** + * Allows for public read access to 'cc' property. + * @access public + * @return array + */ + public function getCcAddresses() + { + return $this->cc; + } + + /** + * Allows for public read access to 'bcc' property. + * @access public + * @return array + */ + public function getBccAddresses() + { + return $this->bcc; + } + + /** + * Allows for public read access to 'ReplyTo' property. + * @access public + * @return array + */ + public function getReplyToAddresses() + { + return $this->ReplyTo; + } + + /** + * Allows for public read access to 'all_recipients' property. + * @access public + * @return array + */ + public function getAllRecipientAddresses() + { + return $this->all_recipients; + } + + /** + * Perform a callback. + * @param boolean $isSent + * @param array $to + * @param array $cc + * @param array $bcc + * @param string $subject + * @param string $body + * @param string $from + */ + protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from) + { + if (!empty($this->action_function) && is_callable($this->action_function)) { + $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from); + call_user_func_array($this->action_function, $params); + } + } +} + +/** + * PHPMailer exception handler + * @package PHPMailer + */ +class phpmailerException extends \think\Exception +{ + /** + * Prettify error message output + * @return string + */ + public function errorMessage() + { + $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n"; + return $errorMsg; + } +} diff --git a/extend/unionpay/sdk/SDKConfig.php b/extend/unionpay/sdk/SDKConfig.php new file mode 100755 index 0000000..02d9a93 --- /dev/null +++ b/extend/unionpay/sdk/SDKConfig.php @@ -0,0 +1,87 @@ +<?php +include_once 'log.class.php'; +include_once 'common.php'; + +class SDKConfig { + + static public $frontTransUrl; + static public $backTransUrl; + static public $singleQueryUrl; + static public $batchTransUrl; + static public $fileTransUrl; + static public $appTransUrl; + static public $cardTransUrl; + static public $jfFrontTransUrl; + static public $jfBackTransUrl; + static public $jfSingleQueryUrl; + static public $jfCardTransUrl; + static public $jfAppTransUrl; + + static public $qrcBackTransUrl; + static public $qrcB2cIssBackTransUrl; + static public $qrcB2cMerBackTransUrl; + + static public $signMethod; + static public $version; + static public $ifValidateCNName; + static public $ifValidateRemoteCert; + + static public $signCertPath; + static public $signCertPwd; + static public $validateCertDir; + static public $encryptCertPath; + static public $rootCertPath; + static public $middleCertPath; + static public $frontUrl; + static public $backUrl; + static public $secureKey; + static public $logFilePath; + static public $logLevel; + + function __construct($config = array()){ + + self::$frontTransUrl = "https://gateway.test.95516.com/gateway/api/frontTransReq.do"; + self::$backTransUrl = "https://gateway.test.95516.com/gateway/api/backTransReq.do"; + self::$singleQueryUrl = "https://gateway.test.95516.com/gateway/api/queryTrans.do"; + self::$batchTransUrl = "https://gateway.test.95516.com/gateway/api/batchTrans.do"; + self::$fileTransUrl = "https://filedownload.test.95516.com/"; + self::$appTransUrl = "https://gateway.test.95516.com/gateway/api/appTransReq.do"; + self::$cardTransUrl = "https://gateway.test.95516.com/gateway/api/cardTransReq.do"; + + self::$jfFrontTransUrl = "https://gateway.test.95516.com/jiaofei/api/frontTransReq.do"; + self::$jfBackTransUrl = "https://gateway.test.95516.com/jiaofei/api/backTransReq.do"; + self::$jfSingleQueryUrl = "https://gateway.test.95516.com/jiaofei/api/queryTrans.do"; + self::$jfCardTransUrl = "https://gateway.test.95516.com/jiaofei/api/cardTransReq.do"; + self::$jfAppTransUrl = "https://gateway.test.95516.com/jiaofei/api/appTransReq.do"; + + self::$qrcBackTransUrl = null; + self::$qrcB2cIssBackTransUrl = null; + self::$qrcB2cMerBackTransUrl = null; + + + self::$version = "5.1.0"; + self::$ifValidateCNName = "false"; // 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。; + self::$ifValidateRemoteCert = "false";//是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。 + + self::$signCertPath = WSTRootPath()."/extend/unionpay/certs/acp_test_sign.pfx"; + + + self::$validateCertDir = null; + self::$encryptCertPath = WSTRootPath()."/extend/unionpay/certs/acp_test_enc.cer"; + self::$rootCertPath = WSTRootPath()."/extend/unionpay/certs/acp_test_root.cer"; + self::$middleCertPath = WSTRootPath()."/extend/unionpay/certs/acp_test_middle.cer"; + + self::$frontUrl = $config["frontUrl"]; + self::$backUrl = $config["backUrl"];; + self::$signCertPwd = $config["signCertPwd"]; + self::$signMethod = $config["signMethod"]; + + self::$secureKey = null; + self::$logFilePath = WSTRootPath()."/extend/unionpay/logs/"; + self::$logLevel = 1; + + } + +} + + diff --git a/extend/unionpay/sdk/acp_sdk.ini b/extend/unionpay/sdk/acp_sdk.ini new file mode 100755 index 0000000..0cffb1e --- /dev/null +++ b/extend/unionpay/sdk/acp_sdk.ini @@ -0,0 +1,74 @@ +;;;;;;;;;;;;;;SDK配置文件(证书方式签名);;;;;;;;;;;;;;;; +; 说明: +; 1. 使用时请删除后缀的“.证书”,并将此文件复制到根文件夹下替换原来的acp_sdk.ini。 +; 2. 具体配置项请根据注释修改。 +; 3. sdk默认读取的配置文件路径为sdk文件夹的acp_sdk.ini文件,如果需修改路径,请自行到sdk/SDKConfig.php中修改。 +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[acpsdk] +;;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址);;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;交易请求地址 +acpsdk.frontTransUrl= +acpsdk.backTransUrl= +acpsdk.singleQueryUrl= +acpsdk.batchTransUrl= +acpsdk.fileTransUrl= +acpsdk.appTransUrl= +acpsdk.cardTransUrl= + +;以下缴费产品使用,其余产品用不到 +acpsdk.jfFrontTransUrl= +acpsdk.jfBackTransUrl= +acpsdk.jfSingleQueryUrl= +acpsdk.jfCardTransUrl= +acpsdk.jfAppTransUrl= + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; 报文版本号,固定5.1.0,请勿改动 +acpsdk.version=5.1.0 + +; 签名方式,证书方式固定01,请勿改动 +acpsdk.signMethod=01 + +; 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。 +acpsdk.ifValidateCNName=false + +; 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。 +acpsdk.ifValidateRemoteCert=false + +;前台通知地址,填写后台接收银联前台通知的地址 +acpsdk.backUrl=http://222.222.222.222:8080/upacp_demo_b2c/demo/api_01_gateway/BackReceive.php + +;后台通知地址,填写后台接收银联后台通知的地址,必须外网能访问 +acpsdk.frontUrl=http://localhost:8086/upacp_demo_b2c/demo/api_01_gateway/FrontReceive.php + +;;;;;;;;;;;;;;;;;;;;;;;;;入网测试环境签名证书配置 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 多证书的情况证书路径为代码指定,可不对此块做配置。 +; 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。 +; 测试环境证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹。生产环境证书由业务部门邮件发送。 +; windows样例: +acpsdk.signCert.path=E:/AppServ/wamp/www/upacp_demo_b2c/certs/acp_test_sign.pfx +; linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明) +;acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp700000000000001.pfx + +; 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败 +acpsdk.signCert.pwd=000000 + +;;;;;;;;;;;;;;;;;;;;;;;;;;加密证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用) +acpsdk.encryptCert.path=E:/AppServ/wamp/www/upacp_demo_b2c/certs/acp_test_enc.cer + +;;;;;;;;;;;;;;;;;;;;;;;;;;验签证书配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 验签中级证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹) +acpsdk.middleCert.path=D:/certs/acp_test_middle.cer +; 验签根证书(证书位于assets/测试环境证书/文件夹下,请复制到d:/certs文件夹) +acpsdk.rootCert.path=E:/AppServ/wamp/www/upacp_demo_b2c/certs/acp_test_root.cer + +;;;;;;;;;;;;;;;;;;;;;;;;;;日志配置;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 日志打印路径,linux注意要有写权限 +acpsdk.log.file.path=D:/logs/ +; 日志级别,debug级别会打印密钥,生产请用info或以上级别 +acpsdk.log.level=DEBUG diff --git a/extend/unionpay/sdk/acp_service.php b/extend/unionpay/sdk/acp_service.php new file mode 100755 index 0000000..89d43ec --- /dev/null +++ b/extend/unionpay/sdk/acp_service.php @@ -0,0 +1,523 @@ +<?php + +header ( 'Content-type:text/html;charset=utf-8' ); +include_once 'log.class.php'; +include_once 'SDKConfig.php'; +include_once 'common.php'; +include_once 'cert_util.php'; + +class AcpService { + + /** + * + * 更新证书 + * + * Enter description here ... + */ + public static function updateEncryptCert(&$params) + { + $logger = LogUtil::getLogger(); + // 取得证书 + $strCert = $params['encryptPubKeyCert']; + $certType = $params['certType']; + openssl_x509_read($strCert); + $certInfo = openssl_x509_parse($strCert); + if($certType === "01"){ + $logger->LogInfo ('原证书certId:'.CertUtil::getEncryptCertId().',新证书certId:'.$certInfo['serialNumber']); + // 更新敏感信息加密公钥 + if (CertUtil::getEncryptCertId() != $certInfo['serialNumber']) { + $newFileName = getBackupFileName(SDKConfig::$encryptCertPath); + // 将原证书备份重命名 + if(!copy(SDKConfig::$encryptCertPath, $newFileName)){ + $logger->LogError ('原证书备份失败'); + return -1; + } + // 更新证书 + if(!file_put_contents(SDKConfig::$encryptCertPath, $strCert)){ + $logger->LogError ('更新证书失败'); + return -1; + } + $logger->LogInfo ('证书更新成功'); + return 1; + } else { + $logger->LogInfo ('证书无需更新'); + return 0; + } + } else if($certType === "02"){ + return 0; + } else { + $logger->LogError ('unknown cerType: '. $certType); + return -1; + } + } + + /** + * 签名 + * @param req 请求要素 + * @param resp 应答要素 + * @return 是否成功 + */ + static function sign(&$params) { + if($params['signMethod']=='01') { + return AcpService::signByCertInfo($params, SDKConfig::$signCertPath, SDKConfig::$signCertPwd); + } else { + return AcpService::signBySecureKey($params, SDKConfig::$secureKey); + } + } + + static function signByCertInfo(&$params, $cert_path, $cert_pwd) { + + $logger = LogUtil::getLogger(); + $logger->LogInfo ( '=====签名报文开始======' ); + if(isset($params['signature'])){ + unset($params['signature']); + } + + $result = false; + + if($params['signMethod']=='01') { + //证书ID + $params ['certId'] = CertUtil::getSignCertIdFromPfx($cert_path, $cert_pwd); + $private_key = CertUtil::getSignKeyFromPfx( $cert_path, $cert_pwd ); + // 转换成key=val&串 + $params_str = createLinkString ( $params, true, false ); + $logger->LogInfo ( "签名key=val&...串 >" . $params_str ); + if($params['version']=='5.0.0'){ + $params_sha1x16 = sha1 ( $params_str, FALSE ); + $logger->LogInfo ( "摘要sha1x16 >" . $params_sha1x16 ); + // 签名 + $result = openssl_sign ( $params_sha1x16, $signature, $private_key, OPENSSL_ALGO_SHA1); + + if ($result) { + $signature_base64 = base64_encode ( $signature ); + $logger->LogInfo ( "签名串为 >" . $signature_base64 ); + $params ['signature'] = $signature_base64; + } else { + $logger->LogInfo ( ">>>>>签名失败<<<<<<<" ); + } + } else if($params['version']=='5.1.0'){ + //sha256签名摘要 + $params_sha256x16 = hash( 'sha256',$params_str); + $logger->LogInfo ( "摘要sha256x16 >" . $params_sha256x16 ); + // 签名 + $result = openssl_sign ( $params_sha256x16, $signature, $private_key, 'sha256'); + if ($result) { + $signature_base64 = base64_encode ( $signature ); + $logger->LogInfo ( "签名串为 >" . $signature_base64 ); + $params ['signature'] = $signature_base64; + } else { + $logger->LogInfo ( ">>>>>签名失败<<<<<<<" ); + } + } else { + $logger->LogError ( "wrong version: " + $params['version'] ); + $result = false; + } + } else { + $logger->LogError ( "signMethod不正确"); + $result = false; + } + $logger->LogInfo ( '=====签名报文结束======' ); + return $result; + } + + static function signBySecureKey(&$params, $secureKey) { + + $logger = LogUtil::getLogger(); + $logger->LogInfo ( '=====签名报文开始======' ); + + if($params['signMethod']=='11') { + // 转换成key=val&串 + $params_str = createLinkString ( $params, true, false ); + $logger->LogInfo ( "签名key=val&...串 >" . $params_str ); + $params_before_sha256 = hash('sha256', $secureKey); + $params_before_sha256 = $params_str.'&'.$params_before_sha256; + $logger->LogDebug( "before final sha256: " . $params_before_sha256); + $params_after_sha256 = hash('sha256',$params_before_sha256); + $logger->LogInfo ( "签名串为 >" . $params_after_sha256 ); + $params ['signature'] = $params_after_sha256; + $result = true; + } else if($params['signMethod']=='12') { + //TODO SM3 + $logger->LogError ( "signMethod=12未实现"); + $result = false; + } else { + $logger->LogError ( "signMethod不正确"); + $result = false; + } + $logger->LogInfo ( '=====签名报文结束======' ); + return $result; + } + + /** + * 验签 + * @param $params 应答数组 + * @return 是否成功 + */ + static function validate($params) { + + $logger = LogUtil::getLogger(); + + $isSuccess = false; + + if($params['signMethod']=='01') + { + $signature_str = $params ['signature']; + unset ( $params ['signature'] ); + $params_str = createLinkString ( $params, true, false ); + $logger->LogInfo ( '报文去[signature] key=val&串>' . $params_str ); + $logger->LogInfo ( '签名原文>' . $signature_str ); + if($params['version']=='5.0.0'){ + + // 公钥 + $public_key = CertUtil::getVerifyCertByCertId ( $params ['certId'] ); + $signature = base64_decode ( $signature_str ); + $params_sha1x16 = sha1 ( $params_str, FALSE ); + $logger->LogInfo ( 'sha1>' . $params_sha1x16 ); + $isSuccess = openssl_verify ( $params_sha1x16, $signature, $public_key, OPENSSL_ALGO_SHA1 ); + $logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' ); + + } else if($params['version']=='5.1.0'){ + + $strCert = $params['signPubKeyCert']; + $strCert = CertUtil::verifyAndGetVerifyCert($strCert); + if($strCert == null){ + $logger->LogError ("validate cert err: " + $params["signPubKeyCert"]); + $isSuccess = false; + } else { + $params_sha256x16 = hash('sha256', $params_str); + $logger->LogInfo ( 'sha256>' . $params_sha256x16 ); + $signature = base64_decode ( $signature_str ); + $isSuccess = openssl_verify ( $params_sha256x16, $signature,$strCert, "sha256" ); + $logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' ); + } + + } else { + $logger->LogError ( "wrong version: " + $params['version'] ); + $isSuccess = false; + } + } else { + $isSuccess = AcpService::validateBySecureKey($params, SDKConfig::$secureKey); + } + return $isSuccess; + } + + static function validateBySecureKey($params, $secureKey) { + + $logger = LogUtil::getLogger(); + $isSuccess = false; + + $signature_str = $params ['signature']; + unset ( $params ['signature'] ); + $params_str = createLinkString ( $params, true, false ); + $logger->LogInfo ( '报文去[signature] key=val&串>' . $params_str ); + $logger->LogInfo ( '签名原文>' . $signature_str ); + + if($params['signMethod']=='11') { + + $params_before_sha256 = hash('sha256', $secureKey); + $params_before_sha256 = $params_str.'&'.$params_before_sha256; + $params_after_sha256 = hash('sha256',$params_before_sha256); + $isSuccess = $params_after_sha256 == $signature_str; + $logger->LogInfo ( $isSuccess ? '验签成功' : '验签失败' ); + } else if($params['signMethod']=='12') { + //TODO SM3 + $logger->LogError ( "sm3没实现"); + $isSuccess = false; + } else { + $logger->LogError ( "signMethod不正确"); + $isSuccess = false; + } + + return $isSuccess; + + } + + /** + * @deprecated 5.1.0开发包已删除此方法,请直接参考5.1.0开发包中的VerifyAppData.php验签。 + * 对控件支付成功返回的结果信息中data域进行验签 + * @param $jsonData json格式数据,例如:{"sign" : "J6rPLClQ64szrdXCOtV1ccOMzUmpiOKllp9cseBuRqJ71pBKPPkZ1FallzW18gyP7CvKh1RxfNNJ66AyXNMFJi1OSOsteAAFjF5GZp0Xsfm3LeHaN3j/N7p86k3B1GrSPvSnSw1LqnYuIBmebBkC1OD0Qi7qaYUJosyA1E8Ld8oGRZT5RR2gLGBoiAVraDiz9sci5zwQcLtmfpT5KFk/eTy4+W9SsC0M/2sVj43R9ePENlEvF8UpmZBqakyg5FO8+JMBz3kZ4fwnutI5pWPdYIWdVrloBpOa+N4pzhVRKD4eWJ0CoiD+joMS7+C0aPIEymYFLBNYQCjM0KV7N726LA==", "data" : "pay_result=success&tn=201602141008032671528&cert_id=68759585097"} + * @return 是否成功 + */ + static function validateAppResponse($jsonData) { + + $data = json_decode($jsonData); + $sign = $data->sign; + $data = $data->data; + $dataMap = parseQString($data); + $public_key = CertUtil::getVerifyCertByCertId( $dataMap ['cert_id'] ); + $signature = base64_decode ( $sign ); + $params_sha1x16 = sha1 ( $data, FALSE ); + $isSuccess = openssl_verify ( $params_sha1x16, $signature,$public_key, OPENSSL_ALGO_SHA1 ); + return $isSuccess; + } + + /** + * 后台交易 HttpClient通信 + * + * @param unknown_type $params + * @param unknown_type $url + * @return mixed + */ + static function post($params, $url) { + $logger = LogUtil::getLogger(); + + $opts = createLinkString ( $params, false, true ); + $logger->LogInfo ( "后台请求地址为>" . $url ); + $logger->LogInfo ( "后台请求报文为>" . $opts ); + + $ch = curl_init (); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_POST, 1 ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); // 不验证证书 + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false ); // 不验证HOST + curl_setopt ( $ch, CURLOPT_SSLVERSION, 1 ); // http://php.net/manual/en/function.curl-setopt.php页面搜CURL_SSLVERSION_TLSv1 + curl_setopt ( $ch, CURLOPT_HTTPHEADER, array ( + 'Content-type:application/x-www-form-urlencoded;charset=UTF-8' + ) ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $opts ); + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); + $html = curl_exec ( $ch ); + $logger->LogInfo ( "后台返回结果为>" . $html ); + + if(curl_errno($ch)){ + $errmsg = curl_error($ch); + curl_close ( $ch ); + $logger->LogInfo ( "请求失败,报错信息>" . $errmsg ); + return null; + } + if( curl_getinfo($ch, CURLINFO_HTTP_CODE) != "200"){ + $errmsg = "http状态=" . curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close ( $ch ); + $logger->LogInfo ( "请求失败,报错信息>" . $errmsg ); + return null; + } + curl_close ( $ch ); + $result_arr = convertStringToArray ( $html ); + return $result_arr; + } + + /** + * 后台交易 HttpClient通信 + * + * @param unknown_type $params + * @param unknown_type $url + * @return mixed + */ + static function get($params, $url) { + + $logger = LogUtil::getLogger(); + + $opts = createLinkString ( $params, false, true ); + $logger->LogDebug( "后台请求地址为>" . $url ); //get的日志太多而且没啥用,设debug级别 + $logger->LogDebug ( "后台请求报文为>" . $opts ); + + $ch = curl_init (); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false ); // 不验证证书 + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, false ); // 不验证HOST + curl_setopt ( $ch, CURLOPT_SSLVERSION, 1 ); // http://php.net/manual/en/function.curl-setopt.php页面搜CURL_SSLVERSION_TLSv1 + curl_setopt ( $ch, CURLOPT_HTTPHEADER, array ( + 'Content-type:application/x-www-form-urlencoded;charset=UTF-8' + ) ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $opts ); + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); + $html = curl_exec ( $ch ); + $logger->LogInfo ( "后台返回结果为>" . $html ); + if(curl_errno($ch)){ + $errmsg = curl_error($ch); + curl_close ( $ch ); + $logger->LogDebug ( "请求失败,报错信息>" . $errmsg ); + return null; + } + if( curl_getinfo($ch, CURLINFO_HTTP_CODE) != "200"){ + $errmsg = "http状态=" . curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close ( $ch ); + $logger->LogDebug ( "请求失败,报错信息>" . $errmsg ); + return null; + } + curl_close ( $ch ); + return $html; + } + + static function createAutoFormHtml($params, $reqUrl) { + // <body onload="javascript:document.pay_form.submit();"> + $encodeType = isset ( $params ['encoding'] ) ? $params ['encoding'] : 'UTF-8'; + $html = <<<eot +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset={$encodeType}" /> +</head> +<body onload="javascript:document.pay_form.submit();"> + <form id="pay_form" name="pay_form" action="{$reqUrl}" method="post"> + +eot; + foreach ( $params as $key => $value ) { + $html .= " <input type=\"hidden\" name=\"{$key}\" id=\"{$key}\" value=\"{$value}\" />\n"; + } + $html .= <<<eot + <!-- <input type="submit" type="hidden">--> + </form> +</body> +</html> +eot; + $logger = LogUtil::getLogger(); + $logger->LogInfo ( "自动跳转html>" . $html ); + return $html; + } + + + + static function getCustomerInfo($customerInfo) { + if($customerInfo == null || count($customerInfo) == 0 ) + return ""; + return base64_encode ( "{" . createLinkString ( $customerInfo, false, false ) . "}" ); + } + + /** + * map转换string,按新规范加密 + * + * @param + * $customerInfo + */ + static function getCustomerInfoWithEncrypt($customerInfo) { + if($customerInfo == null || count($customerInfo) == 0 ) + return ""; + $encryptedInfo = array(); + foreach ( $customerInfo as $key => $value ) { + if ($key == 'phoneNo' || $key == 'cvn2' || $key == 'expired' ) { + //if ($key == 'phoneNo' || $key == 'cvn2' || $key == 'expired' || $key == 'certifTp' || $key == 'certifId') { + $encryptedInfo [$key] = $customerInfo [$key]; + unset ( $customerInfo [$key] ); + } + } + if( count ($encryptedInfo) > 0 ){ + $encryptedInfo = createLinkString ( $encryptedInfo, false, false ); + $encryptedInfo = AcpService::encryptData ( $encryptedInfo, SDKConfig::$encryptCertPath ); + $customerInfo ['encryptedInfo'] = $encryptedInfo; + } + return base64_encode ( "{" . createLinkString ( $customerInfo, false, false ) . "}" ); + } + + + /** + * 解析customerInfo。 + * 为方便处理,encryptedInfo下面的信息也均转换为customerInfo子域一样方式处理, + * @param unknown $customerInfostr + * @return array形式ParseCustomerInfo + */ + static function parseCustomerInfo($customerInfostr) { + $customerInfostr = base64_decode($customerInfostr); + $customerInfostr = substr($customerInfostr, 1, strlen($customerInfostr) - 2); + $customerInfo = parseQString($customerInfostr); + if(array_key_exists("encryptedInfo", $customerInfo)) { + $encryptedInfoStr = $customerInfo["encryptedInfo"]; + unset ( $customerInfo ["encryptedInfo"] ); + $encryptedInfoStr = AcpService::decryptData($encryptedInfoStr); + $encryptedInfo = parseQString($encryptedInfoStr); + foreach ($encryptedInfo as $key => $value){ + $customerInfo[$key] = $value; + } + } + return $customerInfo; + } + + static function getEncryptCertId() { + $cert_path=SDKConfig::$encryptCertPath; + return CertUtil::getEncryptCertId($cert_path); + } + + /** + * 加密数据 + * @param string $data数据 + * @param string $cert_path 证书配置路径 + * @return unknown + */ + static function encryptData($data, $cert_path=null) { + if( $cert_path == null ) { + $cert_path = SDKConfig::$encryptCertPath; + } + $public_key = CertUtil::getEncryptKey( $cert_path ); + openssl_public_encrypt ( $data, $crypted, $public_key ); + return base64_encode ( $crypted ); + } + + /** + * 解密数据 + * @param string $data数据 + * @param string $cert_path 证书配置路径 + * @return unknown + */ + static function decryptData($data, $cert_path=null, $cert_pwd=null) { + + if( $cert_path == null ) { + $cert_path = SDKConfig::$signCertPath; + $cert_pwd = SDKConfig::$signCertPwd; + } + + $data = base64_decode ( $data ); + $private_key = CertUtil::getSignKeyFromPfx ( $cert_path, $cert_pwd); + openssl_private_decrypt ( $data, $crypted, $private_key ); + return $crypted; + } + + + /** + * 处理报文中的文件 + * + * @param unknown_type $params + */ + static function deCodeFileContent($params, $fileDirectory) { + $logger = LogUtil::getLogger(); + if (isset ( $params ['fileContent'] )) { + $logger->LogInfo ( "---------处理后台报文返回的文件---------" ); + $fileContent = $params ['fileContent']; + + if (empty ( $fileContent )) { + $logger->LogInfo ( '文件内容为空' ); + return false; + } else { + // 文件内容 解压缩 + $content = gzuncompress ( base64_decode ( $fileContent ) ); + $filePath = null; + if (empty ( $params ['fileName'] )) { + $logger->LogInfo ( "文件名为空" ); + $filePath = $fileDirectory . $params ['merId'] . '_' . $params ['batchNo'] . '_' . $params ['txnTime'] . '.txt'; + } else { + $filePath = $fileDirectory . $params ['fileName']; + } + $handle = fopen ( $filePath, "w+" ); + if (! is_writable ( $filePath )) { + $logger->LogInfo ( "文件:" . $filePath . "不可写,请检查!" ); + return false; + } else { + file_put_contents ( $filePath, $content ); + $logger->LogInfo ( "文件位置 >:" . $filePath ); + } + fclose ( $handle ); + } + return true; + } else { + return false; + } + } + + + static function enCodeFileContent($path){ + + $file_content_base64 = ''; + if(!file_exists($path)){ + echo '文件没找到'; + return false; + } + + $file_content = file_get_contents ( $path ); + //UTF8 去掉文本中的 bom头 + $BOM = chr(239).chr(187).chr(191); + $file_content = str_replace($BOM,'',$file_content); + $file_content_deflate = gzcompress ( $file_content ); + $file_content_base64 = base64_encode ( $file_content_deflate ); + return $file_content_base64; + } + +} + diff --git a/extend/unionpay/sdk/cert_util.php b/extend/unionpay/sdk/cert_util.php new file mode 100755 index 0000000..4a4c65b --- /dev/null +++ b/extend/unionpay/sdk/cert_util.php @@ -0,0 +1,410 @@ +<?php + +include_once 'acp_service.php'; + +const COMPANY = "中国银联股份有限公司"; +class Cert +{ + public $cert; + public $certId; + public $key; +} + + +// 内存泄漏问题说明: +// openssl_x509_parse疑似有内存泄漏,暂不清楚原因,可能和php、openssl版本有关,估计有bug。 +// windows下试过php5.4+openssl0.9.8,php7.0+openssl1.0.2都有这问题。mac下试过也有问题。 +// 不过至今没人来反馈过这个问题,所以不一定真有泄漏?或者因为增长量不大所以一般都不会遇到问题? +// 也有别人汇报过bug:https://bugs.php.net/bug.php?id=71519 +// +// 替代解决方案: +// 方案1. 所有调用openssl_x509_parse的地方都是为了获取证书序列号,可以尝试把证书序列号+证书/key以别的方式保存, +// 从其他地方(比如数据库)读序列号,而不直接从证书文件里读序列号。 +// 方案2. 代码改成执行脚本的方式执行,这样执行完一次保证能释放掉所有内存。 +// 方案3. 改用下面的CertSerialUtil取序列号, +// 此方法仅用了几个测试和生产的证书做过测试,不保证没bug,所以默认注释掉了。如发现有bug或者可优化的地方可自行修改代码。 +// 注意用了bcmath的方法,*nix下编译时需要 --enable-bcmath。http://php.net/manual/zh/bc.installation.php + + +class CertUtil{ + + private static $signCerts = array(); + private static $encryptCerts = array(); + private static $verifyCerts = array(); + private static $verifyCerts510 = array(); + + private static function initSignCert($certPath, $certPwd){ + $logger = LogUtil::getLogger(); + $logger->LogInfo("读取签名证书……"); + + $pkcs12certdata = file_get_contents ( $certPath ); + if($pkcs12certdata === false ){ + $logger->LogInfo($certPath . "file_get_contents fail。"); + return; + } + + if(openssl_pkcs12_read ( $pkcs12certdata, $certs, $certPwd ) == FALSE ){ + $logger->LogInfo($certPath . ", pwd[" . $certPwd . "] openssl_pkcs12_read fail。"); + return; + } + + $cert = new Cert(); + $x509data = $certs ['cert']; + + if(!openssl_x509_read ( $x509data )){ + $logger->LogInfo($certPath . " openssl_x509_read fail。"); + } + $certdata = openssl_x509_parse ( $x509data ); + $cert->certId = $certdata ['serialNumber']; + +// $certId = CertSerialUtil::getSerial($x509data, $errMsg); +// if($certId === false){ +// $logger->LogInfo("签名证书读取序列号失败:" . $errMsg); +// return; +// } +// $cert->certId = $certId; + + $cert->key = $certs ['pkey']; + $cert->cert = $x509data; + + $logger->LogInfo("签名证书读取成功,序列号:" . $cert->certId); + CertUtil::$signCerts[$certPath] = $cert; + } + + public static function getSignKeyFromPfx($certPath=null, $certPwd=null) + { + if( $certPath == null ) { + $certPath = SDKConfig::$signCertPath; + $certPwd = SDKConfig::$signCertPwd; + } + + if (!array_key_exists($certPath, CertUtil::$signCerts)) { + self::initSignCert($certPath, $certPwd); + } + return CertUtil::$signCerts[$certPath] -> key; + } + + public static function getSignCertIdFromPfx($certPath=null, $certPwd=null) + { + + if( $certPath == null ) { + $certPath = SDKConfig::$signCertPath; + $certPwd = SDKConfig::$signCertPwd; + } + + if (!array_key_exists($certPath, CertUtil::$signCerts)) { + self::initSignCert($certPath, $certPwd); + } + return CertUtil::$signCerts[$certPath] -> certId; + } + + private static function initEncryptCert($cert_path) + { + $logger = LogUtil::getLogger(); + $logger->LogInfo("读取加密证书……"); + + $x509data = file_get_contents ( $cert_path ); + if($x509data === false ){ + $logger->LogInfo($cert_path . " file_get_contents fail。"); + return; + } + + if(!openssl_x509_read ( $x509data )){ + $logger->LogInfo($cert_path . " openssl_x509_read fail。"); + return; + } + + $cert = new Cert(); + $certdata = openssl_x509_parse ( $x509data ); + $cert->certId = $certdata ['serialNumber']; + +// $certId = CertSerialUtil::getSerial($x509data, $errMsg); +// if($certId === false){ +// $logger->LogInfo("签名证书读取序列号失败:" . $errMsg); +// return; +// } +// $cert->certId = $certId; + + $cert->key = $x509data; + CertUtil::$encryptCerts[$cert_path] = $cert; + $logger->LogInfo("加密证书读取成功,序列号:" . $cert->certId); + } + + public static function verifyAndGetVerifyCert($certBase64String){ + + $logger = LogUtil::getLogger(); + + if (array_key_exists($certBase64String, CertUtil::$verifyCerts510)){ + return CertUtil::$verifyCerts510[$certBase64String]; + } + + if (SDKConfig::$middleCertPath === null || SDKConfig::$rootCertPath === null){ + $logger->LogError("rootCertPath or middleCertPath is none, exit initRootCert"); + return null; + } + openssl_x509_read($certBase64String); + $certInfo = openssl_x509_parse($certBase64String); + + $cn = CertUtil::getIdentitiesFromCertficate($certInfo); + if(strtolower(SDKConfig::$ifValidateCNName) == "true"){ + if (COMPANY != $cn){ + $logger->LogInfo("cer owner is not CUP:" . $cn); + return null; + } + } else if (COMPANY != $cn && "00040000:SIGN" != $cn){ + $logger->LogInfo("cer owner is not CUP:" . $cn); + return null; + } + + $from = date_create ( '@' . $certInfo ['validFrom_time_t'] ); + $to = date_create ( '@' . $certInfo ['validTo_time_t'] ); + $now = date_create ( date ( 'Ymd' ) ); + $interval1 = $from->diff ( $now ); + $interval2 = $now->diff ( $to ); + if ($interval1->invert || $interval2->invert) { + $logger->LogInfo("signPubKeyCert has expired"); + return null; + } + + $result = openssl_x509_checkpurpose($certBase64String, X509_PURPOSE_ANY, array(SDKConfig::$rootCertPath, SDKConfig::$middleCertPath)); + if($result === FALSE){ + $logger->LogInfo("validate signPubKeyCert by rootCert failed"); + return null; + } else if($result === TRUE){ + CertUtil::$verifyCerts510[$certBase64String] = $certBase64String; + return CertUtil::$verifyCerts510[$certBase64String]; + } else { + $logger->LogInfo("validate signPubKeyCert by rootCert failed with error"); + return null; + } + } + + public static function getIdentitiesFromCertficate($certInfo){ + + $cn = $certInfo['subject']; + $cn = $cn['CN']; + $company = explode('@',$cn); + + if(count($company) < 3) { + return null; + } + return $company[2]; + } + + public static function getEncryptCertId($cert_path=null){ + if( $cert_path == null ) { + $cert_path = SDKConfig::$encryptCertPath; + } + if(!array_key_exists($cert_path, CertUtil::$encryptCerts)){ + self::initEncryptCert($cert_path); + } + if(array_key_exists($cert_path, CertUtil::$encryptCerts)){ + return CertUtil::$encryptCerts[$cert_path] -> certId; + } + return false; + } + + public static function getEncryptKey($cert_path=null){ + if( $cert_path == null ) { + $cert_path = SDKConfig::$encryptCertPath; + } + if(!array_key_exists($cert_path, CertUtil::$encryptCerts)){ + self::initEncryptCert($cert_path); + } + if(array_key_exists($cert_path, CertUtil::$encryptCerts)){ + return CertUtil::$encryptCerts[$cert_path] -> key; + } + return false; + } + + private static function initVerifyCerts($cert_dir=null) { + + if( $cert_dir == null ) { + $cert_dir = SDKConfig::$validateCertDir; + } + + $logger = LogUtil::getLogger(); + $logger->LogInfo ( '验证签名证书目录 :>' . $cert_dir ); + $handle = opendir ( $cert_dir ); + if (!$handle) { + $logger->LogInfo ( '证书目录 ' . $cert_dir . '不正确' ); + return; + } + + while ($file = readdir($handle)) { + clearstatcache(); + $filePath = $cert_dir . '/' . $file; + if (is_file($filePath)) { + if (pathinfo($file, PATHINFO_EXTENSION) == 'cer') { + + $x509data = file_get_contents($filePath); + if($x509data === false ){ + $logger->LogInfo($filePath . " file_get_contents fail。"); + continue; + } + if(!openssl_x509_read($x509data)){ + $logger->LogInfo($certPath . " openssl_x509_read fail。"); + continue; + } + + $cert = new Cert(); + $certdata = openssl_x509_parse($x509data); + $cert->certId = $certdata ['serialNumber']; + +// $certId = CertSerialUtil::getSerial($x509data, $errMsg); +// if($certId === false){ +// $logger->LogInfo("签名证书读取序列号失败:" . $errMsg); +// return; +// } +// $cert->certId = $certId; + + $cert->key = $x509data; + CertUtil::$verifyCerts[$cert->certId] = $cert; + $logger->LogInfo($filePath . "读取成功,序列号:" . $cert->certId); + } + } + } + closedir ( $handle ); + } + + public static function getVerifyCertByCertId($certId){ + $logger = LogUtil::getLogger(); + if(count(CertUtil::$verifyCerts) == 0){ + self::initVerifyCerts(); + } + if(count(CertUtil::$verifyCerts) == 0){ + $logger->LogInfo("未读取到任何证书……"); + return null; + } + if(array_key_exists($certId, CertUtil::$verifyCerts)){ + return CertUtil::$verifyCerts[$certId]->key; + } else { + $logger->LogInfo("未匹配到序列号为[" . certId . "]的证书"); + return null; + } + } + + public static function test() { + + $x509data = file_get_contents ( "d:/certs/acp_test_enc.cer" ); +// $resource = openssl_x509_read ( $x509data ); + // $certdata = openssl_x509_parse ( $resource ); //<=这句尼玛内存泄漏啊根本释放不掉啊啊啊啊啊啊啊 + // echo $certdata ['serialNumber']; //<=就是需要这个数据啦 + // echo $x509data; + // unset($certdata); //<=没有什么用 + // openssl_x509_free($resource); //<=没有什么用x2 + echo CertSerialUtil::getSerial ( $x509data, $errMsg ) . "\n"; + } +} + + + +// class CertSerialUtil { + +// private static function bytesToInteger($bytes) { +// $val = 0; +// for($i = 0; $i < count ( $bytes ); $i ++) { +// // $val += (($bytes [$i] & 0xff) << (8 * (count ( $bytes ) - 1 - $i))); +// $val += $bytes [$i] * pow(256, count ( $bytes ) - 1 - $i); +// // echo $val . "<br>\n"; +// } +// return $val; +// } + +// private static function bytesToBigInteger($bytes) { +// $val = 0; +// for($i = 0; $i < count ( $bytes ); $i ++) { +// $val = bcadd($val, bcmul($bytes [$i], bcpow(256, count ( $bytes ) - 1 - $i))); +// // echo $val . "<br>\n"; +// } +// return $val; +// } + +// private static function toStr($bytes) { +// $str = ''; +// foreach($bytes as $ch) { +// $str .= chr($ch); +// } +// return $str; +// } + +// public static function getSerial($fileData, &$errMsg) { + +// // $fileData = str_replace('\n','',$fileData); +// // $fileData = str_replace('\r','',$fileData); + +// $start = "-----BEGIN CERTIFICATE-----"; +// $end = "-----END CERTIFICATE-----"; +// $data = trim ( $fileData ); +// if (substr ( $data, 0, strlen ( $start ) ) != $start || +// substr ( $data, strlen ( $data ) - strlen ( $end ) ) != $end) { +// // echo $fileData; +// $errMsg = "error pem data"; +// return false; +// } + +// $data = substr ( $data, strlen ( $start ), strlen ( $data ) - strlen ( $end ) - strlen ( $start ) ); +// $bindata = base64_decode ( $data ); +// $bindata = unpack ( 'C*', $bindata ); + +// $byte = array_shift ( $bindata ); +// if ($byte != 0x30) { +// $errMsg = "1st tag " . $byte . " is not 30"; +// return false; +// } + +// $length = CertSerialUtil::readLength ( $bindata ); +// $byte = array_shift ( $bindata ); +// if ($byte != 0x30) { +// $errMsg = "2nd tag " . $byte . " is not 30"; +// return false; +// } + +// $length = CertSerialUtil::readLength ( $bindata ); +// $byte = array_shift ( $bindata ); +// // echo $byte . "<br>\n"; +// if ($byte == 0xa0) { //version tag. +// $length = CertSerialUtil::readLength ( $bindata ); +// CertSerialUtil::readData ( $bindata, $length ); +// $byte = array_shift ( $bindata ); +// } + +// // echo $byte . "<br>\n"; +// if ($byte != 0x02) { //x509v1 has no version tag, x509v3 has. +// $errMsg = "4th/3rd tag " . $byte . " is not 02"; +// return false; +// } +// $length = CertSerialUtil::readLength ( $bindata ); +// $serial = CertSerialUtil::readData ( $bindata, $length ); +// // echo bin2hex(CertSerialUtil::toStr( $serial )); +// return CertSerialUtil::bytesToBigInteger($serial); +// } + +// private static function readLength(&$bindata) { +// $byte = array_shift ( $bindata ); +// if ($byte < 0x80) { +// $length = $byte; +// } else { +// $lenOfLength = $byte - 0x80; +// for($i = 0; $i < $lenOfLength; $i ++) { +// $lenBytes [] = array_shift ( $bindata ); +// } +// $length = CertSerialUtil::bytesToInteger ( $lenBytes ); +// } +// return $length; +// } + +// private static function readData(&$bindata, $length) { +// $data = array (); +// for($i = 0; $i < $length; $i ++) { +// $data [] = array_shift ( $bindata ); +// } +// return $data; +// } +// } + + + + + + \ No newline at end of file diff --git a/extend/unionpay/sdk/common.php b/extend/unionpay/sdk/common.php new file mode 100755 index 0000000..2742cde --- /dev/null +++ b/extend/unionpay/sdk/common.php @@ -0,0 +1,195 @@ +<?php +include_once 'log.class.php'; +include_once 'SDKConfig.php'; +header ( 'Content-type:text/html;charset=utf-8' ); + +class LogUtil +{ + private static $_logger = null; + public static function getLogger() + { + if (LogUtil::$_logger == null ) { + $l = SDKConfig::$logLevel; + if("INFO" == strtoupper($l)) + $level = PhpLog::INFO; + else if("DEBUG" == strtoupper($l)) + $level = PhpLog::DEBUG; + else if("ERROR" == strtoupper($l)) + $level = PhpLog::ERROR; + else if("WARN" == strtoupper($l)) + $level = PhpLog::WARN; + else if("FATAL" == strtoupper($l)) + $level = PhpLog::FATAL; + else + $level = PhpLog::OFF; + LogUtil::$_logger = new PhpLog ( SDKConfig::$logFilePath, "PRC", $level ); + } + return self::$_logger; + } +} + +/** + * key1=value1&key2=value2转array + * @param $str key1=value1&key2=value2的字符串 + * @param $$needUrlDecode 是否需要解url编码,默认不需要 + */ +function parseQString($str, $needUrlDecode=false){ + $result = array(); + $len = strlen($str); + $temp = ""; + $curChar = ""; + $key = ""; + $isKey = true; + $isOpen = false; + $openName = "\0"; + + for($i=0; $i<$len; $i++){ + $curChar = $str[$i]; + if($isOpen){ + if( $curChar == $openName){ + $isOpen = false; + } + $temp .= $curChar; + } elseif ($curChar == "{"){ + $isOpen = true; + $openName = "}"; + $temp .= $curChar; + } elseif ($curChar == "["){ + $isOpen = true; + $openName = "]"; + $temp .= $curChar; + } elseif ($isKey && $curChar == "="){ + $key = $temp; + $temp = ""; + $isKey = false; + } elseif ( $curChar == "&" && !$isOpen){ + putKeyValueToDictionary($temp, $isKey, $key, $result, $needUrlDecode); + $temp = ""; + $isKey = true; + } else { + $temp .= $curChar; + } + } + putKeyValueToDictionary($temp, $isKey, $key, $result, $needUrlDecode); + return $result; +} + + +function putKeyValueToDictionary($temp, $isKey, $key, &$result, $needUrlDecode) { + if ($isKey) { + $key = $temp; + if (strlen ( $key ) == 0) { + return false; + } + $result [$key] = ""; + } else { + if (strlen ( $key ) == 0) { + return false; + } + if ($needUrlDecode) + $result [$key] = urldecode ( $temp ); + else + $result [$key] = $temp; + } +} + +/** + * 取得备份文件名 + * + * Enter description here ... + * @param $path + */ +function getBackupFileName($path){ + $i = strrpos($path, "."); + $leftFileName = substr($path, 0, $i); + $rightFileName = substr($path, $i + 1); + $newFileName = $leftFileName . '_backup.' . $rightFileName; + return $newFileName; +} + +/** + * 字符串转换为 数组 + * + * @param unknown_type $str + * @return multitype:unknown + */ +function convertStringToArray($str) { + return parseQString($str); +} + +/** + * 压缩文件 对应java deflate + * + * @param unknown_type $params + */ +function deflate_file(&$params) { + $logger = LogUtil::getLogger(); + foreach ( $_FILES as $file ) { + $logger->LogInfo ( "---------处理文件---------" ); + if (file_exists ( $file ['tmp_name'] )) { + $params ['fileName'] = $file ['name']; + + $file_content = file_get_contents ( $file ['tmp_name'] ); + $file_content_deflate = gzcompress ( $file_content ); + + $params ['fileContent'] = base64_encode ( $file_content_deflate ); + $logger->LogInfo ( "压缩后文件内容为>" . base64_encode ( $file_content_deflate ) ); + } else { + $logger->LogInfo ( ">>>>文件上传失败<<<<<" ); + } + } +} + + +/** + * 讲数组转换为string + * + * @param $para 数组 + * @param $sort 是否需要排序 + * @param $encode 是否需要URL编码 + * @return string + */ +function createLinkString($para, $sort, $encode) { + if($para == NULL || !is_array($para)) + return ""; + + $linkString = ""; + if ($sort) { + $para = argSort ( $para ); + } + while ( list ( $key, $value ) = each ( $para ) ) { + if ($encode) { + $value = urlencode ( $value ); + } + $linkString .= $key . "=" . $value . "&"; + } + // 去掉最后一个&字符 + $linkString = substr ( $linkString, 0, count ( $linkString ) - 2 ); + + return $linkString; +} + +/** + * 对数组排序 + * + * @param $para 排序前的数组 + * return 排序后的数组 + */ +function argSort($para) { + ksort ( $para ); + reset ( $para ); + return $para; +} + + +function getProjName(){ + $dir = str_replace("\\","/", dirname(__FILE__)); + $rootDir = str_replace("\\", "/", $_SERVER ['DOCUMENT_ROOT']); + if($rootDir[strlen($rootDir) - 1] != "/") $rootDir = $rootDir . "/"; + $index = strlen($rootDir); + $dir = substr($dir, $index); + $index = strpos($dir, "/"); + $projName = substr($dir, 0, $index); + return $projName; +} + diff --git a/extend/unionpay/sdk/log.class.php b/extend/unionpay/sdk/log.class.php new file mode 100755 index 0000000..e160740 --- /dev/null +++ b/extend/unionpay/sdk/log.class.php @@ -0,0 +1,286 @@ +<?php +class PhpLog { + const DEBUG = 1;// Most Verbose + const INFO = 2;// ... + const WARN = 3;// ... + const ERROR = 4;// ... + const FATAL = 5;// Least Verbose + const OFF = 6;// Nothing at all. + + const LOG_OPEN = 1; + const OPEN_FAILED = 2; + const LOG_CLOSED = 3; + + /* Public members: Not so much of an example of encapsulation, but that's okay. */ + public $Log_Status = PhpLog::LOG_CLOSED; + public $DateFormat= "Y-m-d G:i:s"; + public $MessageQueue; + + private $filename; + private $log_file; + private $priority = PhpLog::INFO; + + private $file_handle; + + /** + * AUTHOR: gu_yongkang + * DATA: 20110322 + * Enter description here ... + * @param $filepath + * 文件存储的路径 + * @param $timezone + * 时间格式,此处设置为"PRC"(中国) + * @param $priority + * 设置运行级别 + */ + + public function __construct( $filepath, $timezone, $priority ) + { + if ( $priority == PhpLog::OFF ) return; + + $this->filename = date('Y-m-d', time()) . '.log'; //默认为以时间+.log的文件文件 + $this->log_file = $this->createPath($filepath, $this->filename); + $this->MessageQueue = array(); + $this->priority = $priority; + date_default_timezone_set($timezone); + + if ( !file_exists($filepath) ) //判断文件路径是否存在 + { + if(!empty($filepath)) //判断路径是否为空 + { + if(!($this->_createDir($filepath))) + { + $this->Log_Status = PhpLog::OPEN_FAILED; + $this->MessageQueue[] = "Create file failed."; + return; + } + if ( !is_writable($this->log_file) ) + { + $this->Log_Status = PhpLog::OPEN_FAILED; + $this->MessageQueue[] = "The file exists, but could not be opened for writing. Check that appropriate permissions have been set."; + return; + } + } + } + + if ( $this->file_handle = fopen( $this->log_file , "a+" ) ) + { + $this->Log_Status = PhpLog::LOG_OPEN; + $this->MessageQueue[] = "The log file was opened successfully."; + } + else + { + $this->Log_Status = PhpLog::OPEN_FAILED; + $this->MessageQueue[] = "The file could not be opened. Check permissions."; + } + return; + } + + public function __destruct() + { + if ( $this->file_handle ) + fclose( $this->file_handle ); + } + + /** + *作用:创建目录 + *输入:要创建的目录 + *输出:true | false + */ + private function _createDir($dir) + { + // return is_dir($dir) or (self::_createDir(dirname($dir)) and mkdir($dir, 0777)); + return false; + } + + /** + *作用:构建路径 + *输入:文件的路径,要写入的文件名 + *输出:构建好的路径字串 + */ + private function createPath($dir, $filename) + { + if (empty($dir)) + { + return $filename; + } + else + { + return $dir . "/" . $filename; + } + } + + public function LogInfo($line) + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + $this->Log( $line, PhpLog::INFO, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + } + + public function LogDebug($line) + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + $this->Log( $line, PhpLog::DEBUG, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + } + + public function LogWarn($line) + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + $this->Log( $line, PhpLog::WARN, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + } + + public function LogError($line) + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + $this->Log( $line, PhpLog::ERROR, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + } + + public function LogFatal($line) + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + $this->Log( $line, PhpLog::FATAL, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + } + + /** + * Author : gu_yongkang + * Enter description here ... + * @param unknown_type $line + * content 内容 + * @param unknown_type $priority + * 打印级别 + * @param unknown_type $sFile + * 调用打印日志的文件名 + * @param unknown_type $iLine + * 打印文件的位置(行数) + */ + public function Log($line, $priority, $sFile, $iLine) + { + if ($iLine > 0) + { + //$line = iconv('GBK', 'UTF-8', $line); + if ( $this->priority <= $priority ) + { + $status = $this->getTimeLine( $priority, $sFile, $iLine); + $this->WriteFreeFormLine ( "$status $line \n" ); + } + } + else + { + /** + * AUTHOR : gu_yongkang + * 增加打印函数和文件名的功能 + */ + $sAarray = array(); + $sAarray = debug_backtrace(); + $sGetFilePath = $sAarray[0]["file"]; + $sGetFileLine = $sAarray[0]["line"]; + if ( $this->priority <= $priority ) + { + $status = $this->getTimeLine( $priority, $sGetFilePath, $sGetFileLine); + unset($sAarray); + unset($sGetFilePath); + unset($sGetFileLine); + $this->WriteFreeFormLine ( "$status $line \n" ); + } + } + } + // 支持输入多个参数 + public function WriteFreeFormLine( $line ) + { + if ( $this->Log_Status == PhpLog::LOG_OPEN && $this->priority != PhpLog::OFF ) + { + if (fwrite( $this->file_handle , $line ) === false) + { + $this->MessageQueue[] = "The file could not be written to. Check that appropriate permissions have been set."; + } + } + } + private function getRemoteIP() + { + foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) + { + if (array_key_exists($key, $_SERVER) === true) + { + foreach (explode(',', $_SERVER[$key]) as $ip) + { + $ip = trim($ip); + if (!empty($ip)) + { + return $ip; + } + } + } + } + return "_NO_IP"; + } + + private function getTimeLine( $level, $FilePath, $FileLine) + { + $time = date( $this->DateFormat ); + $ip = $this->getRemoteIP(); + switch( $level ) + { + case PhpLog::INFO: + return "$time, " . "INFO, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + case PhpLog::WARN: + return "$time, " . "WARN, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + case PhpLog::DEBUG: + return "$time, " . "DEBUG, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + case PhpLog::ERROR: + return "$time, " . "ERROR, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + case PhpLog::FATAL: + return "$time, " . "FATAL, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + default: + return "$time, " . "LOG, " . "$ip, " . "File[ $FilePath ], " . "Line[$FileLine]" . "------"; + } + } + } diff --git a/extend/verify/Verify.php b/extend/verify/Verify.php new file mode 100755 index 0000000..11393e7 --- /dev/null +++ b/extend/verify/Verify.php @@ -0,0 +1,297 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn> +// +---------------------------------------------------------------------- + +namespace verify; + +class Verify { + protected $config = array( + 'seKey' => 'wstmart.com', // 验证码加密密钥 + 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY', // 验证码字符集合 + 'expire' => 1800, // 验证码过期时间(s) + 'useZh' => false, // 使用中文验证码 + 'zhSet' => '们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借', // 中文验证码字符串 + 'useImgBg' => false, // 使用背景图片 + 'fontSize' => 25, // 验证码字体大小(px) + 'useCurve' => false, // 是否画混淆曲线 + 'useNoise' => true, // 是否添加杂点 + 'imageH' => 0, // 验证码图片高度 + 'imageW' => 0, // 验证码图片宽度 + 'length' => 5, // 验证码位数 + 'fontttf' => '4.ttf', // 验证码字体,不设置随机获取 + 'bg' => array(243, 251, 254), // 背景颜色 + 'reset' => true, // 验证成功后是否重置 + ); + + private $_image = NULL; // 验证码图片实例 + private $_color = NULL; // 验证码字体颜色 + + /** + * 架构方法 设置参数 + * @access public + * @param array $config 配置参数 + */ + public function __construct($config=array()){ + $this->config = array_merge($this->config, $config); + } + + /** + * 使用 $this->name 获取配置 + * @access public + * @param string $name 配置名称 + * @return multitype 配置值 + */ + public function __get($name) { + return $this->config[$name]; + } + + /** + * 设置验证码配置 + * @access public + * @param string $name 配置名称 + * @param string $value 配置值 + * @return void + */ + public function __set($name,$value){ + if(isset($this->config[$name])) { + $this->config[$name] = $value; + } + } + + /** + * 检查配置 + * @access public + * @param string $name 配置名称 + * @return bool + */ + public function __isset($name){ + return isset($this->config[$name]); + } + + /** + * 验证验证码是否正确 + * @access public + * @param string $code 用户验证码 + * @param string $id 验证码标识 + * @return bool 用户验证码是否正确 + */ + public function check($code, $id = '') { + $key = $this->authcode($this->seKey).$id; + // 验证码不能为空 + $secode = session($key); + + if(empty($code) || empty($secode)) { + return false; + } + + // session 过期 + if(time() - $secode['verify_time'] > $this->expire) { + session($key, null); + return false; + } + if($this->authcode(strtoupper($code)) == $secode['verify_code']) { + $this->reset && session($key, null); + return true; + } + + return false; + } + + /** + * 输出验证码并把验证码的值保存的session中 + * 验证码保存到session的格式为: array('verify_code' => '验证码值', 'verify_time' => '验证码创建时间'); + * @access public + * @param string $id 要生成验证码的标识 + * @return void + */ + public function entry($id = '') { + // 图片宽(px) + $this->imageW || $this->imageW = $this->length*$this->fontSize*1.5 + $this->length*$this->fontSize/2; + // 图片高(px) + $this->imageH || $this->imageH = $this->fontSize * 2.5; + // 建立一幅 $this->imageW x $this->imageH 的图像 + $this->_image = imagecreate($this->imageW, $this->imageH); + // 设置背景 + imagecolorallocate($this->_image, $this->bg[0], $this->bg[1], $this->bg[2]); + + // 验证码字体随机颜色 + $this->_color = imagecolorallocate($this->_image, mt_rand(1,150), mt_rand(1,150), mt_rand(1,150)); + // 验证码使用随机字体 + $ttfPath = dirname(__FILE__) . '/verify/' . ($this->useZh ? 'zhttfs' : 'ttfs') . '/'; + + if(empty($this->fontttf)){ + $dir = dir($ttfPath); + $ttfs = array(); + while (false !== ($file = $dir->read())) { + if($file[0] != '.' && substr($file, -4) == '.ttf') { + $ttfs[] = $file; + } + } + $dir->close(); + $this->fontttf = $ttfs[array_rand($ttfs)]; + } + $this->fontttf = $ttfPath . $this->fontttf; + + if($this->useImgBg) { + $this->_background(); + } + + if ($this->useNoise) { + // 绘杂点 + $this->_writeNoise(); + } + if ($this->useCurve) { + // 绘干扰线 + $this->_writeCurve(); + } + + // 绘验证码 + $code = array(); // 验证码 + $codeNX = 0; // 验证码第N个字符的左边距 + if($this->useZh){ // 中文验证码 + for ($i = 0; $i<$this->length; $i++) { + $code[$i] = iconv_substr($this->zhSet,floor(mt_rand(0,mb_strlen($this->zhSet,'utf-8')-1)),1,'utf-8'); + imagettftext($this->_image, $this->fontSize, mt_rand(-40, 40), $this->fontSize*($i+1)*1.5, $this->fontSize + mt_rand(10, 20), $this->_color, $this->fontttf, $code[$i]); + } + }else{ + for ($i = 0; $i<$this->length; $i++) { + $code[$i] = $this->codeSet[mt_rand(0, strlen($this->codeSet)-1)]; + $codeNX += mt_rand($this->fontSize*1.2, $this->fontSize*1.6); + imagettftext($this->_image, $this->fontSize, 0, $codeNX, $this->fontSize*1.6, $this->_color, $this->fontttf, $code[$i]); + } + } + + // 保存验证码 + $key = $this->authcode($this->seKey); + $code = $this->authcode(strtoupper(implode('', $code))); + $secode = array(); + $secode['verify_code'] = $code; // 把校验码保存到session + $secode['verify_time'] = time(); // 验证码创建时间 + + $sessionId = input("sessionId"); + if($sessionId)session_id($sessionId); + session($key.$id, $secode); + + header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate'); + header('Cache-Control: post-check=0, pre-check=0', false); + header('Pragma: no-cache'); + header("content-type: image/png"); + + // 输出图像 + imagepng($this->_image); + imagedestroy($this->_image); + } + + /** + * 画一条由两条连在一起构成的随机正弦函数曲线作干扰线(你可以改成更帅的曲线函数) + * + * 高中的数学公式咋都忘了涅,写出来 + * 正弦型函数解析式:y=Asin(ωx+φ)+b + * 各常数值对函数图像的影响: + * A:决定峰值(即纵向拉伸压缩的倍数) + * b:表示波形在Y轴的位置关系或纵向移动距离(上加下减) + * φ:决定波形与X轴位置关系或横向移动距离(左加右减) + * ω:决定周期(最小正周期T=2π/∣ω∣) + * + */ + private function _writeCurve() { + $px = $py = 0; + + // 曲线前部分 + $A = mt_rand(1, $this->imageH/2); // 振幅 + $b = mt_rand(-$this->imageH/4, $this->imageH/4); // Y轴方向偏移量 + $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 + $T = mt_rand($this->imageH, $this->imageW*2); // 周期 + $w = (2* M_PI)/$T; + + $px1 = 0; // 曲线横坐标起始位置 + $px2 = mt_rand($this->imageW/2, $this->imageW * 0.8); // 曲线横坐标结束位置 + + for ($px=$px1; $px<=$px2; $px = $px + 1) { + if ($w!=0) { + $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b + $i = (int) ($this->fontSize/5); + while ($i > 0) { + imagesetpixel($this->_image, $px + $i , $py + $i, $this->_color); // 这里(while)循环画像素点比imagettftext和imagestring用字体大小一次画出(不用这while循环)性能要好很多 + $i--; + } + } + } + + // 曲线后部分 + $A = mt_rand(1, $this->imageH/2); // 振幅 + $f = mt_rand(-$this->imageH/4, $this->imageH/4); // X轴方向偏移量 + $T = mt_rand($this->imageH, $this->imageW*2); // 周期 + $w = (2* M_PI)/$T; + $b = $py - $A * sin($w*$px + $f) - $this->imageH/2; + $px1 = $px2; + $px2 = $this->imageW; + + for ($px=$px1; $px<=$px2; $px=$px+ 1) { + if ($w!=0) { + $py = $A * sin($w*$px + $f)+ $b + $this->imageH/2; // y = Asin(ωx+φ) + b + $i = (int) ($this->fontSize/5); + while ($i > 0) { + imagesetpixel($this->_image, $px + $i, $py + $i, $this->_color); + $i--; + } + } + } + } + + /** + * 画杂点 + * 往图片上写不同颜色的字母或数字 + */ + private function _writeNoise() { + $codeSet = '2345678abcdefhijkmnpqrstuvwxyz'; + for($i = 0; $i < 10; $i++){ + //杂点颜色 + $noiseColor = imagecolorallocate($this->_image, mt_rand(150,225), mt_rand(150,225), mt_rand(150,225)); + for($j = 0; $j < 5; $j++) { + // 绘杂点 + imagestring($this->_image, 5, mt_rand(-10, $this->imageW), mt_rand(-10, $this->imageH), $codeSet[mt_rand(0, 29)], $noiseColor); + } + } + } + + /** + * 绘制背景图片 + * 注:如果验证码输出图片比较大,将占用比较多的系统资源 + */ + private function _background() { + $path = dirname(__FILE__).'/verify/bgs/'; + $dir = dir($path); + + $bgs = array(); + while (false !== ($file = $dir->read())) { + if($file[0] != '.' && substr($file, -4) == '.jpg') { + $bgs[] = $path . $file; + } + } + $dir->close(); + + $gb = $bgs[array_rand($bgs)]; + + list($width, $height) = @getimagesize($gb); + // Resample + $bgImage = @imagecreatefromjpeg($gb); + @imagecopyresampled($this->_image, $bgImage, 0, 0, 0, 0, $this->imageW, $this->imageH, $width, $height); + @imagedestroy($bgImage); + } + + /* 加密验证码 */ + private function authcode($str){ + $key = substr(md5($this->seKey), 5, 8); + $str = substr(md5($str), 8, 10); + return md5($key . $str); + } + +} diff --git a/extend/verify/verify/bgs/1.jpg b/extend/verify/verify/bgs/1.jpg new file mode 100755 index 0000000..d417136 Binary files /dev/null and b/extend/verify/verify/bgs/1.jpg differ diff --git a/extend/verify/verify/bgs/2.jpg b/extend/verify/verify/bgs/2.jpg new file mode 100755 index 0000000..56640bd Binary files /dev/null and b/extend/verify/verify/bgs/2.jpg differ diff --git a/extend/verify/verify/bgs/3.jpg b/extend/verify/verify/bgs/3.jpg new file mode 100755 index 0000000..83e5bd9 Binary files /dev/null and b/extend/verify/verify/bgs/3.jpg differ diff --git a/extend/verify/verify/bgs/4.jpg b/extend/verify/verify/bgs/4.jpg new file mode 100755 index 0000000..97a3721 Binary files /dev/null and b/extend/verify/verify/bgs/4.jpg differ diff --git a/extend/verify/verify/bgs/5.jpg b/extend/verify/verify/bgs/5.jpg new file mode 100755 index 0000000..220a17a Binary files /dev/null and b/extend/verify/verify/bgs/5.jpg differ diff --git a/extend/verify/verify/bgs/6.jpg b/extend/verify/verify/bgs/6.jpg new file mode 100755 index 0000000..be53ea0 Binary files /dev/null and b/extend/verify/verify/bgs/6.jpg differ diff --git a/extend/verify/verify/bgs/7.jpg b/extend/verify/verify/bgs/7.jpg new file mode 100755 index 0000000..fbf537f Binary files /dev/null and b/extend/verify/verify/bgs/7.jpg differ diff --git a/extend/verify/verify/bgs/8.jpg b/extend/verify/verify/bgs/8.jpg new file mode 100755 index 0000000..e10cf28 Binary files /dev/null and b/extend/verify/verify/bgs/8.jpg differ diff --git a/extend/verify/verify/ttfs/1.ttf b/extend/verify/verify/ttfs/1.ttf new file mode 100755 index 0000000..d4ee155 Binary files /dev/null and b/extend/verify/verify/ttfs/1.ttf differ diff --git a/extend/verify/verify/ttfs/2.ttf b/extend/verify/verify/ttfs/2.ttf new file mode 100755 index 0000000..3a452b6 Binary files /dev/null and b/extend/verify/verify/ttfs/2.ttf differ diff --git a/extend/verify/verify/ttfs/3.ttf b/extend/verify/verify/ttfs/3.ttf new file mode 100755 index 0000000..d07a4d9 Binary files /dev/null and b/extend/verify/verify/ttfs/3.ttf differ diff --git a/extend/verify/verify/ttfs/4.ttf b/extend/verify/verify/ttfs/4.ttf new file mode 100755 index 0000000..54a14ed Binary files /dev/null and b/extend/verify/verify/ttfs/4.ttf differ diff --git a/extend/verify/verify/ttfs/5.ttf b/extend/verify/verify/ttfs/5.ttf new file mode 100755 index 0000000..d672876 Binary files /dev/null and b/extend/verify/verify/ttfs/5.ttf differ diff --git a/extend/verify/verify/ttfs/6.ttf b/extend/verify/verify/ttfs/6.ttf new file mode 100755 index 0000000..7f183e2 Binary files /dev/null and b/extend/verify/verify/ttfs/6.ttf differ diff --git a/extend/wechat/WSTWechat.php b/extend/wechat/WSTWechat.php new file mode 100755 index 0000000..0738828 --- /dev/null +++ b/extend/wechat/WSTWechat.php @@ -0,0 +1,359 @@ +<?php +/** + * ============================================================================ + * 微信接口类 + */ +namespace wechat; +use think\Db; +use think\Cache; + +class WSTWechat{ + public $appId; + public $secret; + private $tokenId; + private $error; + private $tpl = [ + 'text' => "<xml> + <ToUserName><![CDATA[%s]]></ToUserName> + <FromUserName><![CDATA[%s]]></FromUserName> + <CreateTime>%s</CreateTime> + <MsgType><![CDATA[text]]></MsgType> + <Content><![CDATA[%s]]></Content> + <FuncFlag>0</FuncFlag> + </xml>", + 'image' => " <xml> + <ToUserName><![CDATA[%s]]></ToUserName> + <FromUserName><![CDATA[%s]]></FromUserName> + <CreateTime>%s</CreateTime> + <MsgType><![CDATA[image]]></MsgType> + <PicUrl><![CDATA[this is a url]]></PicUrl> + <MediaId><![CDATA[media_id]]></MediaId> + <MsgId>1234567890123456</MsgId> + </xml>", + 'news' => '<xml> + <ToUserName><![CDATA[%s]]></ToUserName> + <FromUserName><![CDATA[%s]]></FromUserName> + <CreateTime>%s</CreateTime> + <MsgType><![CDATA[news]]></MsgType> + <ArticleCount>%s</ArticleCount> + <Articles> + %s + </Articles> + </xml> ', + 'content' => '<item> + <Title><![CDATA[%s]]></Title> + <Description><![CDATA[%s]]></Description> + <PicUrl><![CDATA[%s]]></PicUrl> + <Url><![CDATA[%s]]></Url> + </item>', + ]; + + /** + * 初始微信配置信息 + */ + public function __construct($appId, $secret) { + $this->appId = $appId; + $this->secret = $secret; + $this->getToken(); + } + /** + * http访问 + * @param $url 访问网址 + */ + private function http($url,$data = null){ + $curl = curl_init(); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_TIMEOUT, 500); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_URL, $url); + if($data){ + curl_setopt($curl,CURLOPT_POST,1); + curl_setopt($curl,CURLOPT_POSTFIELDS,$data);//如果要处理的数据,请在处理后再传进来 ,例如http_build_query这里不要加 + } + $res = curl_exec($curl); + if(!$res){ + $error = curl_errno($curl); + echo $error; + } + curl_close($curl); + return $res; + } + + /** + * 获取访问令牌 + */ + public function getToken(){ + $access_token = cache('access_token'); + if($access_token!=false) { //已缓存,直接使用 + $this->tokenId = $access_token; + return $this->tokenId; + } else { //获取access_token + $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appId.'&secret='.$this->secret; + $data = $this->http($url); + $data = json_decode($data, true); + if($data['access_token']!=''){ + Cache::set('access_token',$data['access_token'],600); + $this->tokenId = $data['access_token']; + return $this->tokenId; + }else{ + $this->error = $data; + } + return false; + } + } + + /** + * 获取openid和access_token/微信端 + */ + public function getUserInfo($code){ + $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->appId.'&secret='.$this->secret.'&code='.$code.'&grant_type=authorization_code'; + $data = $this->http($url); + return json_decode($data, true); + } + + /** + * 获取用户详细信息/微信端 + */ + public function UserInfo($wdata){ + $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$wdata['access_token'].'&openid='.$wdata['openid'].'&lang=zh_CN'; + $data = $this->http($url); + return json_decode($data, true); + } + + /** + * 创建自定义菜单 + */ + public function wxMenuCreate($wdata){ + $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$this->getToken(); + $data = $this->http($url,$wdata); + return json_decode($data, true); + } + + /** + * 获取自定义菜单 + */ + public function wxMenuGet(){ + $url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=".$this->getToken(); + $data = $this->http($url); + return json_decode($data, true); + } + + /** + * 获取用户基本信息/后台 + */ + public function wxUserInfo($openid){ + $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$this->getToken().'&openid='.$openid.'&lang=zh_CN'; + $data = $this->http($url); + return json_decode($data, true); + } + + /** + * 获取用户列表 + */ + public function wxUserGet($nextOpenid=''){ + $url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.$this->getToken().'&next_openid='.$nextOpenid; + $data = $this->http($url); + return json_decode($data, true); + } + + /** + * 设置备注名 + */ + public function wxUpdateremark($wdata){ + $url = 'https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token='.$this->getToken(); + $data = $this->http($url,$wdata); + return json_decode($data, true); + } + + /** + * 发送模板消息 + */ + public function sendTemplateMessage($data){ + $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$this->getToken(); + return $this->http($url,$data); + //return json_decode($rdata, true); + } + + // 响应用户操作 + public function responseMsg() + { + //get post data, May be due to the different environments + $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; + + $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); + //判断用户发送的什么类型的消息 + switch($postObj->MsgType) + { + case 'event': + $this->_doEvent($postObj); + break; + case 'text': + $this->_doText($postObj); + break; + case 'image': + $this->_doImage($postObj); + break; + case 'voice': + $this->_doVoice($postObj); + break; + case 'video': + $this->_doVideo($postObj); + break; + case 'location': + $this->_doLocation($postObj); + break; + case 'shortvideo': + $this->_doShortVideo($postObj); + break; + case 'link': + $this->_doLink($postObj); + break; + default:exit; + } + } + /*************** 被动回复消息 ****************/ + + public function _doText($postObj) + { + $time = time(); + $msgType = "text"; + $keyword = trim($postObj->Content);// 用户发送过来的关键字 + $keyword = "$keyword"; + $m = Db::name('wx_passive_replys'); + + $msgType = $m->where(['keyword'=>$keyword])->value('msgType'); + + if($msgType=='text'){ + $contentStr = $m->where(['keyword'=>$keyword])->value('content'); + $resultStr = sprintf($this->tpl['text'], $postObj->FromUserName, $postObj->ToUserName, $time, $contentStr); + echo $resultStr; + }elseif($msgType=='news'){ + // 图文消息最多发送10条 + $news = $m->field('title,description,picurl,url')->where(['keyword'=>$keyword])->limit(10)->select(); + $count = count($news); + $newC=''; + for($i=0;$i<$count;++$i){ + $newC .= sprintf($this->tpl['content'], $news[$i]['title'], $news[$i]['description'], $news[$i]['picurl'], $news[$i]['url']); + } + //将内容输出到新闻模板 + $news = sprintf($this->tpl['news'], $postObj->FromUserName, $postObj->ToUserName, $time, $count, $newC); + echo $news; + } + exit; + } + /********************** 模板消息相关 ************************/ + // 查询模板列表 + public function getTemplates(){ + $url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=".$this->getToken(); + return $this->http($url); + } + // 发送模板消息 + public function sendTemplate(){ + $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$this->getToken(); + // 没有 "url":"http://weixin.wstmart.net", 则发送出去的模板消息详情 + $data = '{ + "touser":"oCRQgwemDVQvHuAVgCBCjQjvRo3I", + "template_id":"8tsGZ3xPapfft_llrPgsy6CKe_iK6oMQ9LeO-uoR2D0", + "data":{ + "first": { + "value":"您收到了一条新的订单", + "color":"#173177" + }, + "keynote1":{ + "value":"这个是订单时间", + "color":"#173177" + }, + "keynote2": { + "value":"这个是订单类型", + "color":"#173177" + }, + "keynote3": { + "value":"客户信息", + "color":"#173177" + }, + "keynote4": { + "value":"测试一下", + "color":"#173177" + }, + "keynote5": { + "value":"测试一下2", + "color":"#173177" + }, + "remark":{ + "value":"订单备注。", + "color":"#173177" + } + } + }'; + return $this->http($url,$data); + } + + + + + /******************************************************************* + * + * JS SDK相关接口 + * + ******************************************************************/ + /** + * 获取随机字符加数值 + * @param len 需要返回的字符串长度 + */ + public function getRadomStr($len = 16){ + $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + $str = ""; + for ($i = 0; $i < $len; $i++) { + $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); + } + return $str; + } + /** + * + */ + /** + * 获取jsapi_ticket + */ + public function getJsApiTicket(){ + $tokenId = $this->getToken(); + $url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$tokenId.'&type=jsapi'; + $data = $this->http($url); + return json_decode($data, true); + } + /** + * 获取签名 + * @param url 调用的网址 + * @return array('status'=>-1/1) + */ + public function getJsSignature($url){ + //如果jsapi_ticket过期的话就重新获取,否则就继续用原来的 + $jsapi_ticket = cache('jsapi_ticket_'.md5($url)); + if($jsapi_ticket){ + return $jsapi_ticket; + }else{ + $ticket = $this->getJsApiTicket(); + if($ticket['errcode']==0){ + $data = array(); + $data['status'] = 1; + $data['noncestr'] = $this->getRadomStr(); + $data['timestamp'] = time(); + $data['jsapi_ticket'] = $ticket['ticket']; + $data['signature'] = sha1('jsapi_ticket='.$ticket['ticket'].'&noncestr='.$data['noncestr'].'&timestamp='.$data['timestamp'].'&url='.$url); + cache('jsapi_ticket_'.md5($url),$data,600); + return $data; + }else{ + $this->error = $ticket; + } + return array('status'=>-1,'errcode'=>$ticket['errcode'],'errmsg'=>$ticket['errmsg']); + } + } + + /** + * 记录出错日志 + * @return array + */ + public function getError(){ + return $this->error; + } +} \ No newline at end of file diff --git a/extend/wxpay/WxException.php b/extend/wxpay/WxException.php new file mode 100755 index 0000000..2d1cc2d --- /dev/null +++ b/extend/wxpay/WxException.php @@ -0,0 +1,9 @@ +<?php + +class WxException extends Exception { + public function errorMessage() { + return $this->getMessage (); + } +} + +?> \ No newline at end of file diff --git a/extend/wxpay/WxJsApiPay.php b/extend/wxpay/WxJsApiPay.php new file mode 100755 index 0000000..a4e1258 --- /dev/null +++ b/extend/wxpay/WxJsApiPay.php @@ -0,0 +1,572 @@ +<?php +/** + * 微信支付 + */ + +include_once ("WxException.php"); +include_once ("WxPayConf.php"); + +/** + * 所有接口的基类 + */ + +class CommonUtil { + function __construct() { + } + function trimString($value) { + $ret = null; + if (null != $value) { + $ret = $value; + if (strlen ( $ret ) == 0) { + $ret = null; + } + } + return $ret; + } + + /** + * 产生随机字符串,不长于32位 + */ + public function createNoncestr($length = 32) { + $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + $str = ""; + for($i = 0; $i < $length; $i ++) { + $str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 ); + } + return $str; + } + + /** + * 格式化参数,签名过程需要使用 + */ + function formatBizQueryParaMap($paraMap, $urlencode) { + $buff = ""; + ksort ( $paraMap ); + foreach ( $paraMap as $k => $v ) { + if ($urlencode) { + $v = urlencode ( $v ); + } + $buff .= $k . "=" . $v . "&"; + } + $reqPar; + if (strlen ( $buff ) > 0) { + $reqPar = substr ( $buff, 0, strlen ( $buff ) - 1 ); + } + return $reqPar; + } + + /** + * 生成签名 + */ + public function getSign($Obj) { + foreach ( $Obj as $k => $v ) { + $Parameters [$k] = $v; + } + // 签名步骤一:按字典序排序参数 + ksort ( $Parameters ); + $String = $this->formatBizQueryParaMap ( $Parameters, false ); + // 签名步骤二:在string后加入KEY + $String = $String . "&key=" . WxPayConf::$KEY; + // 签名步骤三:MD5加密 + $String = md5 ( $String ); + // 签名步骤四:所有字符转为大写 + $result_ = strtoupper ( $String ); + return $result_; + } + + /** + * array转xml + */ + function arrayToXml($arr) { + $xml = "<xml>"; + foreach ( $arr as $key => $val ) { + if (is_numeric ( $val )) { + $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; + } else + $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; + } + $xml .= "</xml>"; + return $xml; + } + + /** + * 将xml转为array + */ + public function xmlToArray($xml) { + // 将XML转为array + libxml_disable_entity_loader(true); + libxml_use_internal_errors(); + $array_data = json_decode ( json_encode ( simplexml_load_string ( $xml, 'SimpleXMLElement', LIBXML_NOCDATA ) ), true ); + return $array_data; + } + + /** + * 以post方式提交xml到对应的接口url + */ + public function postXmlCurl($xml, $url, $second = 30) { + // 初始化curl + $ch = curl_init (); + // 设置超时 + curl_setopt ( $ch, CURLOPT_TIMEOUT, $second ); + // 这里设置代理,如果有的话 + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); + // 设置header + curl_setopt ( $ch, CURLOPT_HEADER, FALSE ); + // 要求结果为字符串且输出到屏幕上 + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE ); + // post提交方式 + curl_setopt ( $ch, CURLOPT_POST, TRUE ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml ); + // 运行curl + $data = curl_exec ( $ch ); + // 返回结果 + if ($data) { + curl_close ( $ch ); + return $data; + } else { + $error = curl_errno ( $ch ); + echo "curl出错,错误码:$error" . "<br>"; + echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>"; + curl_close ( $ch ); + return false; + } + } + + /** + * 使用证书,以post方式提交xml到对应的接口url + */ + function postXmlSSLCurl($xml, $url, $second = 30) { + $ch = curl_init (); + // 超时时间 + curl_setopt ( $ch, CURLOPT_TIMEOUT, $second ); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); + // 设置header + curl_setopt ( $ch, CURLOPT_HEADER, FALSE ); + // 要求结果为字符串且输出到屏幕上 + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE ); + // 设置证书 + + curl_setopt ( $ch, CURLOPT_SSLCERT, WxPayConf::$SSLCERT_PATH ); + curl_setopt ( $ch, CURLOPT_SSLKEY, WxPayConf::$SSLKEY_PATH ); + curl_setopt ( $ch, CURLOPT_CAINFO, WxPayConf::$SSLCA_PATH ); // CA根证书(用来验证的网站证书是否是CA颁布) + + // post提交方式 + curl_setopt ( $ch, CURLOPT_POST, true ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml ); + $data = curl_exec ( $ch ); + // 返回结果 + if ($data) { + //curl_close ( $ch ); + return $data; + } else { + $error = curl_errno ( $ch ); + echo "curl出错,错误码:$error" . "<br>"; + echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>"; + curl_close ( $ch ); + return false; + } + } + + /** + * 打印数组 + */ + function printErr($wording = '', $err = '') { + print_r ( '<pre>' ); + echo $wording . "</br>"; + var_dump ( $err ); + print_r ( '</pre>' ); + } +} + +/** + * 请求型接口的基类 + */ +class WxpayClient extends CommonUtil { + var $parameters; // 请求参数,类型为关联数组 + public $response; // 微信返回的响应 + public $result; // 返回参数,类型为关联数组 + var $url; // 接口链接 + var $curl_timeout; // curl超时时间 + + /** + * 设置请求参数 + */ + function setParameter($parameter, $parameterValue) { + $this->parameters [$this->trimString ( $parameter )] = $this->trimString ( $parameterValue ); + } + + /** + * 设置标配的请求参数,生成签名,生成接口参数xml + */ + function createXml() { + $this->parameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->parameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $this->parameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->parameters ["sign"] = $this->getSign ( $this->parameters ); // 签名 + print_r ( $this->parameters ); + return $this->arrayToXml ( $this->parameters ); + } + + /** + * post请求xml + */ + function postXml() { + $xml = $this->createXml (); + $this->response = $this->postXmlCurl ( $xml, $this->url, $this->curl_timeout ); + return $this->response; + } + + /** + * 使用证书post请求xml + */ + function postXmlSSL() { + $xml = $this->createXml (); + $this->response = $this->postXmlSSLCurl ( $xml, $this->url, $this->curl_timeout ); + return $this->response; + } + + /** + * 获取结果,默认不使用证书 + */ + function getResult() { + $this->postXml (); + $this->result = $this->xmlToArray ( $this->response ); + return $this->result; + } +} + +/** + * 统一支付接口类 + */ +class UnifiedOrder extends WxpayClient { + function __construct() { + // 设置接口链接 + $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; + // 设置curl超时时间 + $this->curl_timeout = WxPayConf::$CURL_TIMEOUT; + } + + /** + * 生成接口参数xml + */ + function createXml() { + try { + // 检测必填参数 + if ($this->parameters ["out_trade_no"] == null) { + throw new WxException ( "缺少统一支付接口必填参数out_trade_no!" . "<br>" ); + } elseif ($this->parameters ["body"] == null) { + throw new WxException ( "缺少统一支付接口必填参数body!" . "<br>" ); + } elseif ($this->parameters ["total_fee"] == null) { + throw new WxException ( "缺少统一支付接口必填参数total_fee!" . "<br>" ); + } elseif ($this->parameters ["notify_url"] == null) { + throw new WxException ( "缺少统一支付接口必填参数notify_url!" . "<br>" ); + } elseif ($this->parameters ["trade_type"] == null) { + throw new WxException ( "缺少统一支付接口必填参数trade_type!" . "<br>" ); + } elseif ($this->parameters ["trade_type"] == "JSAPI" && $this->parameters ["openid"] == NULL) { + throw new WxException ( "统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!" . "<br>" ); + } + $this->parameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->parameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $this->parameters ["spbill_create_ip"] = $_SERVER ['REMOTE_ADDR']; // 终端ip + $this->parameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->parameters ["sign"] = $this->getSign ( $this->parameters ); // 签名 + return $this->arrayToXml ( $this->parameters ); + } catch ( WxException $e ) { + die ( $e->errorMessage () ); + } + } + + + + /** + * 设置jsapi的参数 + */ + public function getParameters($obj) { + $appObj ["appid"] = WxPayConf::$APPID; + $appObj ["partnerid"] = WxPayConf::$MCHID; // 商户号 + $appObj ["prepayid"] = $obj["prepayid"]; + $appObj ["package"] = "Sign=WXPay"; + $appObj ["noncestr"] = $this->createNoncestr (); + $timeStamp = time (); + $appObj ["timestamp"] = (string)$timeStamp; + $appObj ["sign"] = $this->getSign ( $appObj ); + return $appObj; + } + + /** + * 获取prepay_id + */ + function getPrepayId() { + $this->postXml (); + $this->result = $this->xmlToArray ( $this->response ); + + $prepay_id = $this->result ["prepay_id"]; + + return $prepay_id; + } +} + +/** + * 订单查询接口 + */ +class OrderQuery extends WxpayClient { + function __construct() { + // 设置接口链接 + $this->url = "https://api.mch.weixin.qq.com/pay/orderquery"; + // 设置curl超时时间 + $this->curl_timeout = WxPayConf::$CURL_TIMEOUT; + } + + /** + * 生成接口参数xml + */ + function createXml() { + try { + // 检测必填参数 + if ($this->parameters ["out_trade_no"] == null && $this->parameters ["transaction_id"] == null) { + throw new WxException ( "订单查询接口中,out_trade_no、transaction_id至少填一个!" . "<br>" ); + } + $this->parameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->parameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $this->parameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->parameters ["sign"] = $this->getSign ( $this->parameters ); // 签名 + return $this->arrayToXml ( $this->parameters ); + } catch ( WxException $e ) { + die ( $e->errorMessage () ); + } + } +} + + + + +/** + * 响应型接口基类 + */ +class WxpayServer extends CommonUtil { + public $data; // 接收到的数据,类型为关联数组 + var $returnParameters; // 返回参数,类型为关联数组 + + /** + * 将微信的请求xml转换成关联数组,以方便数据处理 + */ + function saveData($xml) { + $this->data = $this->xmlToArray ( $xml ); + } + function checkSign() { + $tmpData = $this->data; + unset ( $tmpData ['sign'] ); + $sign = $this->getSign ( $tmpData ); // 本地签名 + if ($this->data ['sign'] == $sign) { + return TRUE; + } + return FALSE; + } + + /** + * 获取微信的请求数据 + */ + function getData() { + return $this->data; + } + + /** + * 设置返回微信的xml数据 + */ + function setReturnParameter($parameter, $parameterValue) { + $this->returnParameters [$this->trimString ( $parameter )] = $this->trimString ( $parameterValue ); + } + + /** + * 生成接口参数xml + */ + function createXml() { + return $this->arrayToXml ( $this->returnParameters ); + } + + /** + * 将xml数据返回微信 + */ + function returnXml() { + $returnXml = $this->createXml (); + return $returnXml; + } +} + +/** + * 通用通知接口 + */ +class Notify extends WxpayServer { +} + + +/** + * 请求商家获取商品信息接口 + */ +class NativeCall extends WxpayServer { + /** + * 生成接口参数xml + */ + function createXml() { + if ($this->returnParameters ["return_code"] == "SUCCESS") { + $this->returnParameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->returnParameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $this->returnParameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->returnParameters ["sign"] = $this->getSign ( $this->returnParameters ); // 签名 + } + return $this->arrayToXml ( $this->returnParameters ); + } + + /** + * 获取product_id + */ + function getProductId() { + $product_id = $this->data ["product_id"]; + return $product_id; + } +} + +/** + * 静态链接二维码 + */ +class NativeLink extends CommonUtil { + var $parameters; // 静态链接参数 + var $url; // 静态链接 + function __construct() { + } + + /** + * 设置参数 + */ + function setParameter($parameter, $parameterValue) { + $this->parameters [$this->trimString ( $parameter )] = $this->trimString ( $parameterValue ); + } + + /** + * 生成Native支付链接二维码 + */ + function createLink() { + try { + if ($this->parameters ["product_id"] == null) { + throw new WxException ( "缺少Native支付二维码链接必填参数product_id!" . "<br>" ); + } + $this->parameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->parameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $time_stamp = time (); + $this->parameters ["time_stamp"] = "$time_stamp"; // 时间戳 + $this->parameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->parameters ["sign"] = $this->getSign ( $this->parameters ); // 签名 + $bizString = $this->formatBizQueryParaMap ( $this->parameters, false ); + $this->url = "weixin://wxpay/bizpayurl?" . $bizString; + } catch ( WxException $e ) { + die ( $e->errorMessage () ); + } + } + + /** + * 返回链接 + */ + function getUrl() { + $this->createLink (); + return $this->url; + } +} + +/** + * JSAPI支付——H5网页端调起支付接口 + */ +class JsApi extends CommonUtil { + var $code; // code码,用以获取openid + var $openid; // 用户的openid + var $parameters; // jsapi参数,格式为json + var $prepay_id; // 使用统一支付接口得到的预支付id + var $curl_timeout; // curl超时时间 + function __construct() { + // 设置curl超时时间 + $this->curl_timeout = WxPayConf::$CURL_TIMEOUT; + } + + /** + * 生成可以获得code的url + */ + function createOauthUrlForCode($redirectUrl) { + $urlObj ["appid"] = WxPayConf::$APPID; + $urlObj ["redirect_uri"] = "$redirectUrl"; + $urlObj ["response_type"] = "code"; + $urlObj ["scope"] = "snsapi_base"; + $urlObj ["state"] = "STATE" . "#wechat_redirect"; + $bizString = $this->formatBizQueryParaMap ( $urlObj, false ); + return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString; + } + + /** + * 生成可以获得openid的url + */ + function createOauthUrlForOpenid() { + $urlObj ["appid"] = WxPayConf::$APPID; + $urlObj ["secret"] = WxPayConf::$APPSECRET; + $urlObj ["code"] = $this->code; + $urlObj ["grant_type"] = "authorization_code"; + $bizString = $this->formatBizQueryParaMap ( $urlObj, false ); + return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString; + } + + /** + * 通过curl向微信提交code,以获取openid + */ + function getOpenid() { + $url = $this->createOauthUrlForOpenid (); + // 初始化curl + $ch = curl_init (); + // 设置超时 + curl_setopt ( $ch, CURLOPT_TIMEOUT, $this->curl_timeout ); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); + curl_setopt ( $ch, CURLOPT_HEADER, FALSE ); + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE ); + // 运行curl,结果以jason形式返回 + $res = curl_exec ( $ch ); + curl_close ( $ch ); + // 取出openid + $data = json_decode ( $res, true ); + $this->openid = $data ['openid']; + return $this->openid; + } + + /** + * 设置prepay_id + */ + function setPrepayId($prepayId) { + $this->prepay_id = $prepayId; + } + + /** + * 设置code + */ + function setCode($code_) { + $this->code = $code_; + } + + /** + * 设置jsapi的参数 + */ + public function getParameters() { + $jsApiObj ["appId"] = WxPayConf::$APPID; + $timeStamp = time (); + $jsApiObj ["timeStamp"] = (string)$timeStamp; + $jsApiObj ["nonceStr"] = $this->createNoncestr (); + $jsApiObj ["package"] = "prepay_id=$this->prepay_id"; + $jsApiObj ["signType"] = "MD5"; + $jsApiObj ["paySign"] = $this->getSign ( $jsApiObj ); + $this->parameters = json_encode ( $jsApiObj ); + + return $this->parameters; + } +} + +?> diff --git a/extend/wxpay/WxPayBase.php b/extend/wxpay/WxPayBase.php new file mode 100755 index 0000000..4b4afc6 --- /dev/null +++ b/extend/wxpay/WxPayBase.php @@ -0,0 +1,159 @@ +<?php +include_once ("WxException.php"); +/** + * 所有接口的基类 + */ +class WxPayBase { + function __construct() { + } + function trimString($value) { + $ret = null; + if (null != $value) { + $ret = $value; + if (strlen ( $ret ) == 0) { + $ret = null; + } + } + return $ret; + } + + /** + * 作用:产生随机字符串,不长于32位 + */ + public function createNoncestr($length = 32) { + $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + $str = ""; + for($i = 0; $i < $length; $i ++) { + $str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 ); + } + return $str; + } + + /** + * 作用:格式化参数,签名过程需要使用 + */ + function formatBizQueryParaMap($paraMap, $urlencode) { + $buff = ""; + ksort ( $paraMap ); + foreach ( $paraMap as $k => $v ) { + if ($urlencode) { + $v = urlencode ( $v ); + } + // $buff .= strtolower($k) . "=" . $v . "&"; + $buff .= $k . "=" . $v . "&"; + } + $reqPar; + if (strlen ( $buff ) > 0) { + $reqPar = substr ( $buff, 0, strlen ( $buff ) - 1 ); + } + return $reqPar; + } + + /** + * 作用:生成签名 + */ + public function getSign($Obj) { + foreach ( $Obj as $k => $v ) { + $Parameters [$k] = $v; + } + // 签名步骤一:按字典序排序参数 + ksort ( $Parameters ); + $String = $this->formatBizQueryParaMap ( $Parameters, false ); + // 签名步骤二:在string后加入KEY + $String = $String . "&key=" . WxPayConf::$KEY; + // 签名步骤三:MD5加密 + $String = md5 ( $String ); + // 签名步骤四:所有字符转为大写 + $result_ = strtoupper ( $String ); + return $result_; + } + + /** + * 作用:array转xml + */ + function arrayToXml($arr) { + $xml = "<xml>"; + foreach ( $arr as $key => $val ) { + if (is_numeric ( $val )) { + $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; + } else + $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; + } + $xml .= "</xml>"; + return $xml; + } + + /** + * 作用:将xml转为array + */ + public function xmlToArray($xml) { + // 将XML转为array + libxml_disable_entity_loader(true); + libxml_use_internal_errors(); + $array_data = json_decode ( json_encode ( simplexml_load_string ( $xml, 'SimpleXMLElement', LIBXML_NOCDATA ) ), true ); + return $array_data; + } + + /** + * 作用:以post方式提交xml到对应的接口url + */ + public function postXmlCurl($xml, $url, $second = 30) { + // 初始化curl + $ch = curl_init (); + // 设置超时 + curl_setopt ( $ch, CURLOPT_TIMEOUT, $second ); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); + // 设置header + curl_setopt ( $ch, CURLOPT_HEADER, FALSE ); + // 要求结果为字符串且输出到屏幕上 + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE ); + // post提交方式 + curl_setopt ( $ch, CURLOPT_POST, TRUE ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml ); + // 运行curl + $data = curl_exec ( $ch ); + curl_close ( $ch ); + // 返回结果 + if ($data) { + //curl_close ( $ch ); + return $data; + } else { + $error = curl_errno ( $ch ); + curl_close ( $ch ); + throw new WxException("curl出错,错误码:$error"); + } + } + + /** + * 作用:使用证书,以post方式提交xml到对应的接口url + */ + function postXmlSSLCurl($xml, $url, $second = 30) { + $ch = curl_init (); + // 超时时间 + curl_setopt ( $ch, CURLOPT_TIMEOUT, $second ); + curl_setopt ( $ch, CURLOPT_URL, $url ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); + curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); + // 设置header + curl_setopt ( $ch, CURLOPT_HEADER, FALSE ); + // 要求结果为字符串且输出到屏幕上 + curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE ); + // post提交方式 + curl_setopt ( $ch, CURLOPT_POST, true ); + curl_setopt ( $ch, CURLOPT_POSTFIELDS, $xml ); + $data = curl_exec ( $ch ); + // 返回结果 + if ($data) { + return $data; + } else { + $error = curl_errno ( $ch ); + curl_close ( $ch ); + throw new WxException("curl出错,错误码:$error"); + } + } + +} + +?> diff --git a/extend/wxpay/WxPayConf.php b/extend/wxpay/WxPayConf.php new file mode 100755 index 0000000..e4d0246 --- /dev/null +++ b/extend/wxpay/WxPayConf.php @@ -0,0 +1,31 @@ +<?php + +/** + * 配置账号信息 + */ + +class WxPayConf { + + static public $APPID; + static public $APPSECRET; + static public $MCHID; + static public $KEY; + static public $CURL_TIMEOUT; + + static public $NOTIFY_URL; + static public $RETURN_URL; + // =======【基本信息设置】===================================== + public function __construct($wxpayconfig = array()) { + + self::$APPID = $wxpayconfig['appid']; + self::$APPSECRET = $wxpayconfig['appsecret']; + self::$MCHID = $wxpayconfig['mchid']; + self::$KEY = $wxpayconfig['key']; + self::$CURL_TIMEOUT = $wxpayconfig['curl_timeout']; + self::$NOTIFY_URL = $wxpayconfig['notifyurl']; + self::$RETURN_URL = $wxpayconfig['returnurl']; + + } +} + +?> \ No newline at end of file diff --git a/extend/wxpay/WxQrcodePay.php b/extend/wxpay/WxQrcodePay.php new file mode 100755 index 0000000..9e539e4 --- /dev/null +++ b/extend/wxpay/WxQrcodePay.php @@ -0,0 +1,127 @@ +<?php + +/** + * 扫码支付接口类 + */ + +include_once ("WxPayBase.php"); + + +class WxQrcodePay extends WxPayBase { + public $parameters; // 请求参数,类型为关联数组 + public $response; // 微信返回的响应 + public $result; // 返回参数,类型为关联数组 + public $url; // 接口链接 + public $curl_timeout; // curl超时时间 + public $data; // 接收到的数据,类型为关联数组 + public $returnParameters; // 返回参数,类型为关联数组 + + function __construct() { + // 设置接口链接 + $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; + // 设置curl超时时间 + $this->curl_timeout = WxPayConf::$CURL_TIMEOUT; + } + + /** + * 作用:设置请求参数 + */ + function setParameter($parameter, $parameterValue) { + $this->parameters [$this->trimString ( $parameter )] = $this->trimString ( $parameterValue ); + } + + /** + * 作用:设置标配的请求参数,生成签名,生成接口参数xml + */ + function getXml() { + $this->parameters ["appid"] = WxPayConf::$APPID; // 公众账号ID + $this->parameters ["mch_id"] = WxPayConf::$MCHID; // 商户号 + $this->parameters ["nonce_str"] = $this->createNoncestr (); // 随机字符串 + $this->parameters ["sign"] = $this->getSign ( $this->parameters ); // 签名 + + return $this->arrayToXml ( $this->parameters ); + } + + /** + * 作用:post请求xml + */ + function postXml() { + $xml = $this->getXml (); + + $this->response = $this->postXmlCurl ( $xml, $this->url, $this->curl_timeout ); + + return $this->response; + } + + /** + * 作用:使用证书post请求xml + */ + function postXmlSSL() { + $xml = $this->getXml (); + $this->response = $this->postXmlSSLCurl ( $xml, $this->url, $this->curl_timeout ); + return $this->response; + } + + /** + * 作用:获取结果,默认不使用证书 + */ + function getResult() { + + $this->postXml (); + + $this->result = $this->xmlToArray ( $this->response ); + return $this->result; + } + + /** + * 将微信的请求xml转换成关联数组,以方便数据处理 + */ + function saveData($xml) { + $this->data = $this->xmlToArray ( $xml ); + } + + /** + * 检测微信签名 + * @return boolean + */ + function checkSign() { + $tmpData = $this->data; + unset ( $tmpData ['sign'] ); + $sign = $this->getSign ( $tmpData ); // 本地签名 + if ($this->data ['sign'] == $sign) { + return TRUE; + } + return FALSE; + } + + /** + * 获取微信的请求数据 + */ + function getData() { + return $this->data; + } + + /** + * 设置返回微信的xml数据 + */ + function setReturnParameter($parameter, $parameterValue) { + $this->returnParameters [$this->trimString ( $parameter )] = $this->trimString ( $parameterValue ); + } + + /** + * 生成接口参数xml + */ + function createXml() { + return $this->arrayToXml ( $this->returnParameters ); + } + + /** + * 将xml数据返回微信 + */ + function returnXml() { + $returnXml = $this->createXml (); + return $returnXml; + } +} + +?> diff --git a/get_startup.php b/get_startup.php new file mode 100755 index 0000000..6789441 --- /dev/null +++ b/get_startup.php @@ -0,0 +1,5 @@ +<?php + $data['show']=0; + $data['img'][0] = ['src'=>'http://img.juzi199.com/static/app2/img/startup_1.jpg','href'=>'']; + $data['img'][1] = ['src'=>'http://img.juzi199.com/static/app2/img/startup_1.jpg','href'=>'']; + exit(json_encode($data)); \ No newline at end of file diff --git a/get_version.php b/get_version.php new file mode 100755 index 0000000..8c09ad9 --- /dev/null +++ b/get_version.php @@ -0,0 +1,20 @@ +<?php + $data['version'] = 39; + $data['ios_must_update'] = 0; //是否强制更新,0不强制,1强制 + + if(time()>1539532800){ + $data['apk_version'] = '2.0.0'; + $data['must_update'] = 1; //是否强制更新,0不强制,1强制 + }else{ + $data['apk_version'] = '1.0.9'; + $data['must_update'] = 0; //是否强制更新,0不强制,1强制 + } + + $data['apk_down_url'] = 'http://juzi199.com/down/juzi_2_0_0.apk'; + //$data['ios_version'] = '1.0.0'; + $data['ios_appid'] = '1355322179'; + $data['update_url'] = 'https://itunes.apple.com/cn/lookup?id='.$data['ios_appid']; + $data['ios_down_url'] = 'https://itunes.apple.com/cn/app/san-gu-hui/id'.$data['ios_appid'].'?mt=8'; + $data['cssUrl'] = 'http://www.heyuanhui.cn/static/app/css/'; + $data['jsUrl'] = 'http://www.heyuanhui.cn/static/app/js/'; + exit(json_encode($data)); \ No newline at end of file diff --git a/get_version_new.php b/get_version_new.php new file mode 100755 index 0000000..60af100 --- /dev/null +++ b/get_version_new.php @@ -0,0 +1,13 @@ +<?php + $data['version'] = 16; + $data['ios_must_update'] = 0; //是否强制更新,0不强制,1强制 + $data['must_update'] = 0; //是否强制更新,0不强制,1强制 + $data['apk_version'] = '2.1.7'; + $data['apk_down_url'] = 'http://t.ect99.com/down/qlg_2_1_7.zip'; + //$data['ios_version'] = '1.0.0'; + $data['ios_appid'] = '1355322179'; + $data['update_url'] = 'https://itunes.apple.com/cn/lookup?id='.$data['ios_appid']; + $data['ios_down_url'] = 'https://itunes.apple.com/cn/app/san-gu-hui/id'.$data['ios_appid'].'?mt=8'; + $data['cssUrl'] = 'http://t.ect99.com/static/app2/css/'; + $data['jsUrl'] = 'http://t.ect99.com/static/app2/js/'; + exit(json_encode($data)); \ No newline at end of file diff --git a/hyhproject/.DS_Store b/hyhproject/.DS_Store new file mode 100755 index 0000000..171c24e Binary files /dev/null and b/hyhproject/.DS_Store differ diff --git a/hyhproject/._.DS_Store b/hyhproject/._.DS_Store new file mode 100755 index 0000000..5bd99f6 Binary files /dev/null and b/hyhproject/._.DS_Store differ diff --git a/hyhproject/.htaccess b/hyhproject/.htaccess new file mode 100755 index 0000000..3e63591 --- /dev/null +++ b/hyhproject/.htaccess @@ -0,0 +1,4 @@ +<FilesMatch (.*)\.(html|php)$> +order allow,deny +deny from all +</FilesMatch> \ No newline at end of file diff --git a/hyhproject/admin/.DS_Store b/hyhproject/admin/.DS_Store new file mode 100755 index 0000000..b17ab86 Binary files /dev/null and b/hyhproject/admin/.DS_Store differ diff --git a/hyhproject/admin/._.DS_Store b/hyhproject/admin/._.DS_Store new file mode 100755 index 0000000..90aeffc Binary files /dev/null and b/hyhproject/admin/._.DS_Store differ diff --git a/hyhproject/admin/behavior/InitConfig.php b/hyhproject/admin/behavior/InitConfig.php new file mode 100755 index 0000000..eb2d00d --- /dev/null +++ b/hyhproject/admin/behavior/InitConfig.php @@ -0,0 +1,12 @@ +<?php +namespace wstmart\admin\behavior; +/** + * ============================================================================ + * 初始化基础数据 + */ +class InitConfig +{ + public function run(&$params){ + WSTConf('listenUrl',WSTVisitPrivilege()); + } +} \ No newline at end of file diff --git a/hyhproject/admin/behavior/ListenLoginStatus.php b/hyhproject/admin/behavior/ListenLoginStatus.php new file mode 100755 index 0000000..d7a0026 --- /dev/null +++ b/hyhproject/admin/behavior/ListenLoginStatus.php @@ -0,0 +1,37 @@ +<?php +namespace wstmart\admin\behavior; +/** + * ============================================================================ + * 检测用户有没有登录 + */ +class ListenLoginStatus +{ + public function run(&$params){ + $STAFF = session('WST_STAFF'); + $allowUrl = ['admin/index/login', + 'admin/index/checklogin', + 'admin/index/logout', + 'admin/index/logout', + 'admin/index/getverify', + 'admin/cronjobs/autocancelnopay', + 'admin/cronjobs/autoappraise', + 'admin/cronjobs/autoreceive', + 'admin/cronjobs/autosendmsg' + ]; + $request = request(); + $visit = strtolower($request->module()."/".$request->controller()."/".$request->action()); + if(empty($STAFF) && !in_array($visit,$allowUrl)){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您还没有登录,请先登录']); + }else{ + if('quanlianggongmall' == input('key')){ + header("Location:".url('admin/index/login?key=quanlianggongmall')); + }else{ + echo 'hello'; + } + + } + exit(); + } + } +} \ No newline at end of file diff --git a/hyhproject/admin/behavior/ListenOperate.php b/hyhproject/admin/behavior/ListenOperate.php new file mode 100755 index 0000000..8ddf8e5 --- /dev/null +++ b/hyhproject/admin/behavior/ListenOperate.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\admin\behavior; +/** + * ============================================================================ + * 记录用户的访问日志 + */ +class ListenOperate +{ + public function run(&$params){ + $urls = WSTConf('listenUrl'); + $request = request(); + $visit = strtolower($request->module()."/".$request->controller()."/".$request->action()); + if(array_key_exists($visit,$urls)&& $visit!='admin/logoperates/pagequery'){ + $privilege = current($urls[$visit]); + $data = []; + $data['menuId'] = $privilege['menuId']; + $data['operateUrl'] = $_SERVER['REQUEST_URI']; + $data['operateDesc'] = $privilege['name']; + $data['content'] = !empty($_REQUEST)?json_encode($_REQUEST):''; + $data['operateIP'] = $request->ip(); + model('admin/LogOperates')->add($data); + } + } +} \ No newline at end of file diff --git a/hyhproject/admin/behavior/ListenPrivilege.php b/hyhproject/admin/behavior/ListenPrivilege.php new file mode 100755 index 0000000..250449b --- /dev/null +++ b/hyhproject/admin/behavior/ListenPrivilege.php @@ -0,0 +1,33 @@ +<?php +namespace wstmart\admin\behavior; +/** + * ============================================================================ + * 检测有没有访问权限 + */ +class ListenPrivilege +{ + public function run(&$params){ + $privileges = session('WST_STAFF.privileges'); + $staffId = (int)session('WST_STAFF.staffId'); + if($staffId!=1){ + $urls = WSTConf('listenUrl'); + $request = request(); + $visit = strtolower($request->module()."/".$request->controller()."/".$request->action()); + if(array_key_exists($visit,$urls) && !$this->checkUserCode($urls[$visit],$privileges)){ + if($request->isAjax()){ + echo json_encode(['status'=>-998,'msg'=>'对不起,您没有操作权限,请与管理员联系']); + }else{ + header("Content-type: text/html; charset=utf-8"); + echo "对不起,您没有操作权限,请与管理员联系"; + } + exit(); + } + } + } + private function checkUserCode($urlCodes,$userCodes){ + foreach ($urlCodes as $key => $value) { + if(in_array($key,$userCodes))return true; + } + return false; + } +} \ No newline at end of file diff --git a/hyhproject/admin/common/function.php b/hyhproject/admin/common/function.php new file mode 100755 index 0000000..01490cb --- /dev/null +++ b/hyhproject/admin/common/function.php @@ -0,0 +1,58 @@ +<?php +use think\Db; +/** + * ============================================================================ + */ +/** + * 加载系统访问路径 + */ +function WSTVisitPrivilege(){ + $listenUrl = cache('WST_LISTEN_URL'); + if(!$listenUrl){ + $list = model('admin/Privileges')->getAllPrivileges(); + $listenUrl = []; + foreach ($list as $v){ + if($v['privilegeUrl']=='')continue; + $listenUrl[strtolower($v['privilegeUrl'])][$v['privilegeCode']] = ['code'=>$v['privilegeCode'], + 'url'=>strtolower($v['privilegeUrl']), + 'name'=>$v['privilegeName'], + 'isParent'=>true, + 'menuId'=>$v['menuId'] + ]; + if(strpos($v['otherPrivilegeUrl'],'/')!==false){ + $t = explode(',',$v['otherPrivilegeUrl']); + foreach ($t as $vv){ + if(strpos($vv,'/')!==false){ + $listenUrl[strtolower($vv)][$v['privilegeCode']] = ['code'=>$v['privilegeCode'], + 'url'=>strtolower($vv), + 'name'=>$v['privilegeName'], + 'isParent'=>false, + 'menuId'=>$v['menuId'] + ]; + } + } + } + } + cache('WST_LISTEN_URL',$listenUrl); + } + return $listenUrl; +} + +/** + * 判断有没有权限 + * @param $code 权限代码 + * @param $type 返回的类型 true-boolean false-string + */ +function WSTGrant($code){ + $STAFF = session("WST_STAFF"); + if(in_array($code,$STAFF['privileges']))return true; + return false; +} + +/** + * 微信配置 + */ +function WXAdmin(){ + $wechat = new \wechat\WSTWechat(WSTConf('CONF.wxAppId'),WSTConf('CONF.wxAppKey')); + return $wechat; +} diff --git a/hyhproject/admin/conf/config.php b/hyhproject/admin/conf/config.php new file mode 100755 index 0000000..b4e508d --- /dev/null +++ b/hyhproject/admin/conf/config.php @@ -0,0 +1,17 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- +return [ + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ] +]; diff --git a/hyhproject/admin/controller/.DS_Store b/hyhproject/admin/controller/.DS_Store new file mode 100755 index 0000000..0d98001 Binary files /dev/null and b/hyhproject/admin/controller/.DS_Store differ diff --git a/hyhproject/admin/controller/._.DS_Store b/hyhproject/admin/controller/._.DS_Store new file mode 100755 index 0000000..b83effd Binary files /dev/null and b/hyhproject/admin/controller/._.DS_Store differ diff --git a/hyhproject/admin/controller/Accreds.php b/hyhproject/admin/controller/Accreds.php new file mode 100755 index 0000000..a565560 --- /dev/null +++ b/hyhproject/admin/controller/Accreds.php @@ -0,0 +1,50 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Accreds as M; +/** + * ============================================================================ + * 商家认证控制器 + */ +class Accreds extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Addons.php b/hyhproject/admin/controller/Addons.php new file mode 100755 index 0000000..3dbd653 --- /dev/null +++ b/hyhproject/admin/controller/Addons.php @@ -0,0 +1,181 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Addons as M; +/** + * ============================================================================ + * 插件控制器 + */ +class Addons extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 设置插件页面 + */ + public function toEdit(){ + $m = new M(); + $addon = $m->getById(); + if(!$addon) $this->error('插件未安装'); + $addon_class = get_addon_class($addon['name']); + if(!class_exists($addon_class)){ + trace("插件{$addon['name']}无法实例化,",'ADDONS','ERR'); + } + $data = new $addon_class; + $addon['addons_path'] = $data->addons_path; + $this->meta_title = '设置插件-'.$data->info['title']; + $db_config = $addon['config']; + $addon['config'] = include $data->config_file; + + if($db_config){ + $db_config = json_decode($db_config, true); + foreach ($addon['config'] as $key => $value) { + if($value['type'] != 'group'){ + $addon['config'][$key]['value'] = isset($db_config[$key])?$db_config[$key]:""; + }else{ + foreach ($value['options'] as $gourp => $options) { + foreach ($options['options'] as $gkey => $value) { + $addon['config'][$key]['options'][$gourp]['options'][$gkey]['value'] = $db_config[$gkey]; + } + } + } + } + } + $this->assign('data',$addon); + $this->assign('addonId',(int)input("id")); + return $this->fetch("config"); + } + + /** + * 保存插件设置 + */ + public function saveConfig(){ + $m = new M(); + $m->saveConfig(); + + $addon = $m->getById(); + $addonName = $addon["name"]; + $class = get_addon_class($addonName); + if(!class_exists($class)){ + return WSTReturn("插件不存在",-1); + } + $addons = new $class; + $addons->saveConfig(); + + return $this->fetch("list"); + } + + /** + * 卸载插件 + */ + public function install(){ + $m = new M(); + $addon = $m->getById(); + $addonName = $addon["name"]; + $class = get_addon_class($addonName); + if(!class_exists($class)){ + return WSTReturn("插件不存在",-1); + } + $addons = new $class; + $flag = $addons->install(); + if(!$flag){ + return WSTReturn("安装失败",-1); + }else{ + return $m->editStatus(1); + } + } + + /** + * 卸载插件 + */ + public function uninstall(){ + $m = new M(); + $addon = $m->getById(); + $addonName = $addon["name"]; + $class = get_addon_class($addonName); + if(!class_exists($class)){ + return WSTReturn("插件不存在",-1); + } + $addons = new $class; + $flag = $addons->uninstall(); + if(!$flag){ + return WSTReturn("卸载失败",-1); + }else{ + return $m->del(); + } + + } + + /** + * 启用插件 + */ + public function enable(){ + $m = new M(); + $addon = $m->getById(); + $addonName = $addon["name"]; + $class = get_addon_class($addonName); + if(!class_exists($class)){ + return WSTReturn("插件不存在",-1); + } + $addons = new $class; + $flag = $addons->enable(); + if(!$flag){ + return WSTReturn("启用失败",-1); + }else{ + return $m->editStatus(1); + } + + } + + /** + * 禁用插件 + */ + public function disable(){ + + $m = new M(); + $addon = $m->getById(); + $addonName = $addon["name"]; + $class = get_addon_class($addonName); + if(!class_exists($class)){ + return WSTReturn("插件不存在",-1); + } + $addons = new $class; + $flag = $addons->disable(); + if(!$flag){ + return WSTReturn("禁用失败",-1); + }else{ + return $m->editStatus(2); + } + + } +} diff --git a/hyhproject/admin/controller/Adgoods.php b/hyhproject/admin/controller/Adgoods.php new file mode 100755 index 0000000..8c04f32 --- /dev/null +++ b/hyhproject/admin/controller/Adgoods.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Adgoods as M; +/** + * ============================================================================ + * 广告控制器 + */ +class Adgoods extends Base{ + + public function index(){ + $result=db('ads')->field('adName,adId')->order('adId desc')->select(); + return $this->fetch("list",['result'=>$result]); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $data = $m->getById(Input("id/d",0)); + if($data) $data['adName']=db('ads')->where('adId',$data['adId'])->value('adName'); + $result=db('ads')->field('adName,adId')->order('adId desc')->select(); + return $this->fetch("edit",['data'=>$data,'result'=>$result]); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 修改广告排序 + */ + public function changeSort(){ + $m = new M(); + return $m->changeSort(); + } + + +} diff --git a/hyhproject/admin/controller/Adpositions.php b/hyhproject/admin/controller/Adpositions.php new file mode 100755 index 0000000..710ad3d --- /dev/null +++ b/hyhproject/admin/controller/Adpositions.php @@ -0,0 +1,63 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\AdPositions as M; +/** + * ============================================================================ + * 广告位置控制器 + */ +class Adpositions extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $assign = ['data'=>$m->getById(Input("get.id/d",0))]; + return $this->fetch("edit",$assign); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 获取位置信息(用于广告) + */ + public function getPositon(){ + $m = new M(); + return $m->getPositon((int)input('post.positionType/d')); + } +} diff --git a/hyhproject/admin/controller/Ads.php b/hyhproject/admin/controller/Ads.php new file mode 100755 index 0000000..0dcfc50 --- /dev/null +++ b/hyhproject/admin/controller/Ads.php @@ -0,0 +1,65 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Ads as M; +/** + * ============================================================================ + * 广告控制器 + */ +class Ads extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $data = $m->getById(Input("id/d",0)); + return $this->fetch("edit",['data'=>$data]); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 修改广告排序 + */ + public function changeSort(){ + $m = new M(); + return $m->changeSort(); + } + + +} diff --git a/hyhproject/admin/controller/Areas.php b/hyhproject/admin/controller/Areas.php new file mode 100755 index 0000000..31fa7f8 --- /dev/null +++ b/hyhproject/admin/controller/Areas.php @@ -0,0 +1,92 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Areas as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Areas extends Base{ + + public function index(){ + $m = new M(); + $pArea=array('areaId'=>0,'parentId'=>0); + $parentId = Input("get.parentId/d",0); + if($parentId>0){ + $pArea = $m->getFieldsById($parentId,['areaName,areaId,parentId']); + } + $this->assign("pArea",$pArea); + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + + /** + * 设置是否显示/隐藏 + */ + public function editiIsShow(){ + $m = new M(); + $rs = $m->editiIsShow(); + return $rs; + } + + /** + * 获取地区 + */ + public function get(){ + $m = new M(); + $rs = $m->getById((int)Input("post.id")); + return $rs; + } + + /** + * 排序字母 + */ + public function letterObtain(){ + $m = new M(); + $rs = $m->letterObtain(); + return $rs; + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $list = $m->listQuery(Input("post.parentId/d",0)); + return WSTReturn("", 1,$list); + } +} diff --git a/hyhproject/admin/controller/Articlecats.php b/hyhproject/admin/controller/Articlecats.php new file mode 100755 index 0000000..724e2bc --- /dev/null +++ b/hyhproject/admin/controller/Articlecats.php @@ -0,0 +1,96 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\ArticleCats as M; +/** + * ============================================================================ + * 文章分类控制器 + */ +class ArticleCats extends Base{ + + public function index(){ + $m = new M(); + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return $rs; + } + /** + * 获取列表 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(input('parentId/d',0)); + return $rs; + } + /** + * 设置是否显示/隐藏 + */ + public function editiIsShow(){ + $m = new M(); + $rs = $m->editiIsShow(); + return $rs; + } + + /** + * 获取文章分类 + */ + public function get(){ + $m = new M(); + $rs = $m->getById((int)Input("post.id")); + return $rs; + } + + /** + * 获取文章分类列表 + */ + public function listQuery2(){ + $m = new M(); + $rs = $m->listQuery2(); + if((int)input('id')==0 && (int)input('hasRoot')==1){ + $rs = ['id'=>0,'name'=>'全部','pId'=>0,'isParent'=>true,'children'=>$rs,'open'=>true]; + } + return $rs; + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + + /** + * 修改分类名称 + */ + public function editName(){ + $m = new M(); + $rs = $m->editName(); + return $rs; + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } +} diff --git a/hyhproject/admin/controller/Articles.php b/hyhproject/admin/controller/Articles.php new file mode 100755 index 0000000..09cf708 --- /dev/null +++ b/hyhproject/admin/controller/Articles.php @@ -0,0 +1,94 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Articles as M; +/** + * ============================================================================ + * 文章控制器 + */ +class Articles extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + + /** + * 获取文章 + */ + public function get(){ + $m = new M(); + $rs = $m->get(Input("post.id/d",0)); + return $rs; + } + + /** + * 设置是否显示/隐藏 + */ + public function editiIsShow(){ + $m = new M(); + $rs = $m->editiIsShow(); + return $rs; + } + + /** + * 跳去新增/编辑页面 + */ + public function toEdit(){ + $id = Input("get.id/d",0); + $m = new M(); + if($id>0){ + $object = $m->getById($id); + }else{ + $object = $m->getEModel('articles'); + $object['catName'] = ''; + } + $this->assign('object',$object); + $this->assign('articlecatList',model('Article_Cats')->listQuery(0)); + return $this->fetch("edit"); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + /** + * 批量删除 + */ + public function delByBatch(){ + $m = new M(); + $rs = $m->delByBatch(); + return $rs; + } +} diff --git a/hyhproject/admin/controller/Attributes.php b/hyhproject/admin/controller/Attributes.php new file mode 100755 index 0000000..304c49f --- /dev/null +++ b/hyhproject/admin/controller/Attributes.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Attributes as M; +/** + * ============================================================================ + * 属性控制器 + */ +class Attributes extends Base{ + + public function index(){ + $this->assign('catId', input("catId/d")); + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + + /** + * 获取分页 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + return $rs; + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + //获取该记录信息 + $this->assign('data', $this->get()); + $m = new M(); + $this->assign('catId', input("catId/d",0)); + return $this->fetch("edit"); + } + /** + * 获取数据 + */ + public function get(){ + $m = new M(); + $rs = $m->getById(input("attrId/d")); + return $rs; + } + /** + * 显示隐藏 + */ + public function setToggle(){ + $m = new M(); + $rs = $m->setToggle(); + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + +} diff --git a/hyhproject/admin/controller/Banks.php b/hyhproject/admin/controller/Banks.php new file mode 100755 index 0000000..3b5fad6 --- /dev/null +++ b/hyhproject/admin/controller/Banks.php @@ -0,0 +1,56 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Banks as M; +/** + * ============================================================================ + * 银行控制器 + */ +class Banks extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + $rs = $m->getById(Input("id/d",0)); + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + /** + * 修改 + */ + public function edit(){ + + $m = new M(); + $rs = $m->edit(); + return $rs; + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + +} diff --git a/hyhproject/admin/controller/Base.php b/hyhproject/admin/controller/Base.php new file mode 100755 index 0000000..3ac2221 --- /dev/null +++ b/hyhproject/admin/controller/Base.php @@ -0,0 +1,33 @@ +<?php +namespace wstmart\admin\controller; +/** + * ============================================================================ + * 基础控制器 + */ +use think\Controller; +class Base extends Controller { + public function __construct(){ + parent::__construct(); + $this->assign("v",WSTConf('CONF.wstVersion')); + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []) + { + $replace['__ADMIN__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/admin/view'; + return $this->view->fetch($template, $vars, $replace, $config); + } + + public function getVerify(){ + WSTVerify(); + } + + public function uploadPic(){ + return WSTUploadPic(1); + } + + /** + * 编辑器上传文件 + */ + public function editorUpload(){ + return WSTEditUpload(1); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Brands.php b/hyhproject/admin/controller/Brands.php new file mode 100755 index 0000000..d32346c --- /dev/null +++ b/hyhproject/admin/controller/Brands.php @@ -0,0 +1,86 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Brands as M; +/** + * ============================================================================ + * 品牌控制器 + */ +class Brands extends Base{ + + public function index(){ + $g = model('GoodsCats'); + $this->assign('gcatList',$g->listQuery(0)); + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + + /** + * 获取品牌 + */ + public function get(){ + $m = new M(); + $rs = $m->get((int)Input("post.id")); + return $rs; + } + + /** + * 跳去新增/编辑页面 + */ + public function toEdit(){ + $id = Input("get.id/d",0); + $m = new M(); + if($id>0){ + $object = $m->getById($id); + }else{ + $object = $m->getEModel('brands'); + } + $this->assign('object',$object); + $this->assign('gcatList',model('GoodsCats')->listQuery(0)); + return $this->fetch("edit"); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + /** + * 修改品牌排序 + */ + public function changeSort(){ + $m = new M(); + return $m->changeSort(); + } + +} diff --git a/hyhproject/admin/controller/Carts.php b/hyhproject/admin/controller/Carts.php new file mode 100755 index 0000000..01b57fa --- /dev/null +++ b/hyhproject/admin/controller/Carts.php @@ -0,0 +1,30 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Carts as M; +/** + * ============================================================================ + * 基础控业务处理 + */ +use think\Db; +class Carts extends Base{ + //购物车列表 + public function cart(){ + $m = new M(); + return $this->fetch('carts'); + } + //获取分页 + public function cartsByPage(){ + $m=new M(); + $result=$m->cartsByPage(); + $result['status'] = 1; + return WSTGrid($result); + } + /** + * 导出购物车数据 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Cashdraws.php b/hyhproject/admin/controller/Cashdraws.php new file mode 100755 index 0000000..61ab41c --- /dev/null +++ b/hyhproject/admin/controller/Cashdraws.php @@ -0,0 +1,198 @@ +<?php + +namespace wstmart\admin\controller; + +use wstmart\admin\model\CashDraws as M; + +/** + + * ============================================================================ + + * 提现控制器 + + */ + +class Cashdraws extends Base{ + + + + public function index(){ + + return $this->fetch("list"); + + } + + + + /** + + * 获取分页 + + */ + + public function pageQuery(){ + + $m = new M(); + + return WSTGrid($m->pageQuery()); + + } + + + + /** + + * 跳去编辑页面 + + */ + + public function toHandle(){ + + //获取该记录信息 + + $m = new M(); + + $this->assign('object', $m->getById()); + + return $this->fetch("edit"); + + } + /** + * 查看报表 + * @return [type] [description] + */ + public function viewReport(){ + + $m = new M(); + $date = input('get.searchDate'); + if(!$date){ + $date = date('Y-m-d'); + } + $orders = $m->viewReport($date); + $this->assign("searchDate",$date); + $this->assign('orders',$orders); + return $this->fetch("view_report"); + } + /** + * 修改报表信息 + */ + public function setReport(){ + $data['money'] =(int) session('reData.money');//充值/扣除数量 + $mobileCode =(int)input('mobileCode');//验证码 + if($data['money'] <= 0){ + exit(jsonReturn('请求超时请重试!')); + } + if(session('reData.reCode') != $mobileCode){ + exit(jsonReturn('验证码错误')); + } + $reDate = session('reData.reDate');//充值/扣除日期 + $reType =(int) session('reData.reType');//1充值2扣除 + if($reType == 1){ + $reTypeName = '充值'; + }else{ + $data['money']*=-1; + $reTypeName = '扣除'; + } + $data['adminId'] = session('WST_STAFF.staffId'); + $data['logContent'] = session('WST_STAFF.staffName').$reTypeName; + $data['setTime'] = strtotime($reDate); + $data['createTime'] = time(); + $m = Model('common/Table'); + $m->setTable('log_day_money'); + if(false !== $m->insertInfo($data)){ + session('reData',null); + exit(jsonReturn('操作成功',1)); + } + exit(jsonReturn('操作失败')); + } + /** + * 获取操作验证码 + */ + public function getMobileCode(){ + $mobile = getAdminPhone(); + //董事长您好:会计${name}需要修改财务报表,日期:${date},${reType}金额:${money}元,核验码${code},请告之。 + $data = input('post.'); + $model_logsms = model('common/LogSms'); + $phoneVerify = rand(1000,9999); + $name = session('WST_STAFF.staffName'); + $date = $data['reDate']; + if($data['reType'] == 1){ + $reTypeName = '充值'; + }else{ + $reTypeName = '扣除'; + } + $money = $data['money']; + $data['reCode'] = $phoneVerify; + $tpl = WSTMsgTemplates('PHONE_ADMIN_SET_REPORT_NOTICE'); + $rv['status'] = -1; + $rv['msg'] = '发送失败'; + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$name,'date'=>$date,'reType'=>$reTypeName,'money'=>$money,'code'=>$phoneVerify]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$mobile,$params,'PHONE_ADMIN_SET_REPORT_NOTICE',$phoneVerify); + } + if(1 == $rv['status']){ + session('reData',$data); + } + exit(json_encode($rv)); + } + /** + + * 修改 + + */ + + public function handle(){ + + $drawsStatus = (int)input('cashSatus',-1); + + $m = new M(); + + if($drawsStatus==1){ + + return $m->handle(); + + }else{ + + return $m->handleFail(); + + } + + } + + + + /** + + * 查看提现内容 + + */ + + public function toView(){ + + $m = new M(); + + $this->assign('object', $m->getById()); + + return $this->fetch("view"); + + } + + /** + + * 导出 + + */ + + public function toExport(){ + + $m = new M(); + + $rs = $m->toExport(); + + $this->assign('rs',$rs); + + } + +} + diff --git a/hyhproject/admin/controller/Chargeitems.php b/hyhproject/admin/controller/Chargeitems.php new file mode 100755 index 0000000..304d5e6 --- /dev/null +++ b/hyhproject/admin/controller/Chargeitems.php @@ -0,0 +1,57 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\ChargeItems as M; +/** + * ============================================================================ + * 充值项控制器 + */ +class Chargeitems extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $assign = ['data'=>$m->getById(Input("get.id/d",0))]; + return $this->fetch("edit",$assign); + } + /** + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + +} diff --git a/hyhproject/admin/controller/Cronjobs.php b/hyhproject/admin/controller/Cronjobs.php new file mode 100755 index 0000000..d9cdb2c --- /dev/null +++ b/hyhproject/admin/controller/Cronjobs.php @@ -0,0 +1,42 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\CronJobs as M; +/** + * ============================================================================ + * 定时任务控制器 + */ +class Cronjobs extends Base{ + /** + * 取消未付款订单 + */ + public function autoCancelNoPay(){ + $m = new M(); + $rs = $m->autoCancelNoPay(); + return json($rs); + } + /** + * 自动好评 + */ + public function autoAppraise(){ + $m = new M(); + $rs = $m->autoAppraise(); + return json($rs); + } + /** + * 自动确认收货 + */ + public function autoReceive(){ + $m = new M(); + $rs = $m->autoReceive(); + return json($rs); + } + + /** + * 发送队列消息 + */ + public function autoSendMsg(){ + $m = new M(); + $rs = $m->autoSendMsg(); + return json($rs); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Datacats.php b/hyhproject/admin/controller/Datacats.php new file mode 100755 index 0000000..a47743c --- /dev/null +++ b/hyhproject/admin/controller/Datacats.php @@ -0,0 +1,44 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\DataCats as M; +/** + * ============================================================================ + * 系统数据分类控制器 + */ +class Datacats extends Base{ + /** + * 根据 + */ + public function listQuery(){ + $m = new M(); + return $m->listQuery((int)Input("post.id",-1)); + } + /** + * 根据catId获取数据分类 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("post.id")); + } + /** + * 新增数据分类 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑数据分类 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除数据分类 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Datas.php b/hyhproject/admin/controller/Datas.php new file mode 100755 index 0000000..b7cd496 --- /dev/null +++ b/hyhproject/admin/controller/Datas.php @@ -0,0 +1,55 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Datas as M; +/** + * ============================================================================ + * 系统数据控制器 + */ +class Datas extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 根据catId获取子数据 + */ + public function childQuery(){ + $m = new M(); + return WSTGrid($m->childQuery()); + } + /** + * 获取菜单列表 + */ + public function listQuery(){ + $m = new M(); + return $m->dataQuery((int)Input("post.id",-1)); + } + /** + * 获取菜单 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("post.id")); + } + /** + * 新增菜单 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Ectday.php b/hyhproject/admin/controller/Ectday.php new file mode 100755 index 0000000..f3a5854 --- /dev/null +++ b/hyhproject/admin/controller/Ectday.php @@ -0,0 +1,37 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\EctDay as M; +/** + * ============================================================================ + * 提现控制器 + */ +class Ectday extends Base{ + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 导出 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } + //获取查看页面 + public function ectPage(){ + $m=new M(); + $result=$m->ectTarget(); + $this->assign('result',$result); + return $this->fetch('ectpage'); + + } +} diff --git a/hyhproject/admin/controller/Ectdeal.php b/hyhproject/admin/controller/Ectdeal.php new file mode 100755 index 0000000..2f97d1d --- /dev/null +++ b/hyhproject/admin/controller/Ectdeal.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\EctDeal as M; +/** + * ============================================================================ + * 提现控制器 + */ +class Ectdeal extends Base{ + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $result=$m->pageQuery(); + return WSTGrid($result); + } +} diff --git a/hyhproject/admin/controller/Ecttarget.php b/hyhproject/admin/controller/Ecttarget.php new file mode 100755 index 0000000..5066bc2 --- /dev/null +++ b/hyhproject/admin/controller/Ecttarget.php @@ -0,0 +1,50 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\EctTarget as M; +/** + * ============================================================================ + * 提现控制器 + */ +class Ecttarget extends Base{ + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 导出 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } + //获取记录信息 + public function toHandle(){ + $m=new M(); + $result=$m->toHandle(); + $this->assign('object',$result); + return $this->fetch('ecttarget'); + } + //进行审核操作 + public function ectTarget(){ + $m=new M(); + $result=$m->ectTarget(); + exit(json_encode($result)); + } + //获取查看页面 + public function ectPage(){ + $m=new M(); + $result=$m->ectTarget(); + $this->assign('result',$result); + return $this->fetch('ectpage'); + + } +} diff --git a/hyhproject/admin/controller/Express.php b/hyhproject/admin/controller/Express.php new file mode 100755 index 0000000..8a64ce6 --- /dev/null +++ b/hyhproject/admin/controller/Express.php @@ -0,0 +1,56 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Express as M; +/** + * ============================================================================ + * 快递控制器 + */ +class Express extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + $rs = $m->getById(Input("id/d",0)); + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + /** + * 修改 + */ + public function edit(){ + + $m = new M(); + $rs = $m->edit(); + return $rs; + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + +} diff --git a/hyhproject/admin/controller/Friendlinks.php b/hyhproject/admin/controller/Friendlinks.php new file mode 100755 index 0000000..b5d0636 --- /dev/null +++ b/hyhproject/admin/controller/Friendlinks.php @@ -0,0 +1,59 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Friendlinks as M; +/** + * ============================================================================ + * 友情链接控制器 + */ +class Friendlinks extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $rs = $m->getById((int)Input("post.id")); + $this->assign("object",$rs); + return $this->fetch("edit"); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Goods.php b/hyhproject/admin/controller/Goods.php new file mode 100755 index 0000000..0a1fa7c --- /dev/null +++ b/hyhproject/admin/controller/Goods.php @@ -0,0 +1,132 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Goods as M; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + /** + * 查看上架商品列表 + */ + public function index(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch('list_sale'); + } + /** + * 批量删除商品 + */ + public function batchDel(){ + $m = new M(); + return $m->batchDel(); + } + + /** + * 设置违规商品 + */ + public function illegal(){ + $m = new M(); + return $m->illegal(); + } + /** + * 批量设置违规商品 + */ + public function batchIllegal(){ + $m = new M(); + return $m->batchIllegal(); + } + /** + * 通过商品审核 + */ + public function allow(){ + $m = new M(); + return $m->allow(); + } + /** + * 批量通过商品审核 + */ + public function batchAllow(){ + $m = new M(); + return $m->batchAllow(); + } + /** + * 获取上架商品列表 + */ + public function saleByPage(){ + $m = new M(); + $rs = $m->saleByPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + /** + * 已下架的商品 + */ + public function shelves(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch('goods/list_shelves'); + } + /** + * 获取已下架的商品 + */ + public function shelvesByPage(){ + $m = new M(); + $rs = $m->shelvesByPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + /** + * 审核中的商品 + */ + public function auditIndex(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch('goods/list_audit'); + } + /** + * 获取审核中的商品 + */ + public function auditByPage(){ + $m = new M(); + $rs = $m->auditByPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + /** + * 审核中的商品 + */ + public function illegalIndex(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch('list_illegal'); + } + /** + * 获取违规商品列表 + */ + public function illegalByPage(){ + $m = new M(); + $rs = $m->illegalByPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + + /** + * 删除商品 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 导出购物车数据 + */ + public function toExportSale(){ + $m = new M(); + $rs = $m->toExportSale(); + $this->assign('rs',$rs); + } + /** + * 商品ECT支付状态 + */ + public function goodsEct(){ + $m = new M(); + return $m->goodsEct(); + } +} diff --git a/hyhproject/admin/controller/Goodsappraises.php b/hyhproject/admin/controller/Goodsappraises.php new file mode 100755 index 0000000..554a36b --- /dev/null +++ b/hyhproject/admin/controller/Goodsappraises.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\GoodsAppraises as M; +/** + * ============================================================================ + * 商品评价控制器 + */ +class Goodsappraises extends Base{ + + public function index(){ + //获取地区 + $area1 = model('areas')->listQuery(0); + return $this->fetch("list",['area1'=>$area1,]); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $data = $m->getById(input("get.id/d",0)); + if($data['images']!='') + $data['images'] = explode(',',$data['images']); + $assign = ['data'=>$data]; + return $this->fetch("edit",$assign); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Goodscats.php b/hyhproject/admin/controller/Goodscats.php new file mode 100755 index 0000000..b656799 --- /dev/null +++ b/hyhproject/admin/controller/Goodscats.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class GoodsCats extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 获取列表 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(input('parentId/d',0)); + return WSTReturn("", 1,$rs); + } + /** + * 获取商品分类 + */ + public function get(){ + $m = new M(); + return $m->get((int)Input("post.id")); + } + + /** + * 设置是否自营显示/隐藏 + */ + public function editiIsSelfShow(){ + $m = new M(); + return $m->editiIsSelfShow(); + } + /** + * 设置是否推荐/不推荐 + */ + public function editiIsFloor(){ + $m = new M(); + return $m->editiIsFloor(); + } + + /** + * 设置是否显示/隐藏 + */ + public function editiIsShow(){ + $m = new M(); + return $m->editiIsShow(); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 编辑分类名 + */ + public function editName(){ + $m = new M(); + return $m->editName(); + } + /** + * 编辑分类排序 + */ + public function editOrder(){ + $m = new M(); + return $m->editOrder(); + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Goodsclassify.php b/hyhproject/admin/controller/Goodsclassify.php new file mode 100755 index 0000000..8828860 --- /dev/null +++ b/hyhproject/admin/controller/Goodsclassify.php @@ -0,0 +1,203 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\GoodsClassify as M; +/** + * ============================================================================ + * 商品控制器 + */ +class Goodsclassify extends Base{ + /*查看商品总分类*/ + public function index(){ + return $this->fetch('list'); + } + /**获取商品总分类分页*/ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTGrid($rs); + } + /**获取总分类数据*/ + public function get(){ + $m = new M(); + $rs = $m->getById(input("goodsclassifyId/d")); + return $rs; + } + //添加商品总分类 + public function add(){ + $m=new M(); + $rs=$m->add(); + return $rs; + } + //修改商品总分类 + public function edit(){ + $m=new M(); + $rs=$m->edit(); + return $rs; + } + /** + * 获取商品分类数据 + */ + public function gets(){ + $m = new M(); + $rs = $m->getByIds(input("goodsclassifyId/d")); + return $rs; + } + //获取商品分类详情 + public function catdetail(){ + $m=new M(); + $row= $m->catdetail(); + $id=input('goodsclassifyId'); + $this->assign("id",$id); + return $this->fetch('catdetail'); + } + //获取商品分类分页 + public function catdetailPage(){ + $m = new M(); + $rs = $m->catdetailPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + /**删除商品总分类下的商品分类*/ + public function catdel(){ + $m = new M(); + return $m->catdel(); + } + //获取商品详情 + public function detail(){ + $m=new M(); + $row= $m->detail(); + $id=input('catId'); + $this->assign("id",$id); + return $this->fetch('detail'); + } + //获取商品详情页面 + public function detailByPage(){ + $m = new M(); + $rs = $m->detailByPage(); + $rs['status'] = 1; + return WSTGrid($rs); + } + /**删除商品总分类*/ + public function del(){ + $m = new M(); + return $m->del(); + } + /*添加商品分类*/ + public function add_cat(){ + $m = new M(); + return $m->add_cat(); + } + //获取设置活动页页面 + public function setdetail(){ + $id=input('goodsclassifyId'); + $result=db('goods_classify')->where('goodsclassifyId',$id)->value('goodsclassifyName'); + $this->assign(["id"=>$id,'result'=>$result]); + $classify=db('recom_classify')->where('classifyId',$id)->field('recomId,recomName')->select(); + $this->assign('classify',$classify); + return $this->fetch('setdetail'); + } + //获取商品详情页面 + public function setdetailPage(){ + $m = new M(); + $rs = $m->setdetailPage(); + return WSTGrid($rs); + } + //更改活动商品的排序号 + public function changeSet(){ + $m = new M(); + $rs = $m->changeSet(); + return $rs; + } + //获取设置活动页页面 + public function recom(){ + $id=input('goodsclassifyId'); + $result=db('goods_classify')->where('goodsclassifyId',$id)->value('goodsclassifyName'); + $this->assign(["id"=>$id,'result'=>$result]); + $classify=db('recom_classify')->where('classifyId',$id)->field('recomId,recomName')->select(); + $this->assign('classify',$classify); + return $this->fetch('recom'); + } + //更改活动商品的排序号 + public function changeRecom(){ + $m = new M(); + $rs = $m->changeRecom(); + return $rs; + } + //删除推荐商品 + public function recomActiveDel(){ + $m = new M(); + return $m->recomActiveDel(); + } + /**获取总分类数据*/ + public function getrecomActive(){ + $m = new M(); + $rs = $m->getrecomActiveId(input("recomActiveId/d")); + return $rs; + } + //添加商品总分类 + public function addrecomActive(){ + $m=new M(); + $rs=$m->addrecomActive(); + return $rs; + } + //获取商品详情页面 + public function recomPage(){ + $m = new M(); + $rs = $m->recomPage(); + return WSTGrid($rs); + } + /*查看活动页的活动分类*/ + public function cats(){ + $this->assign('classifyId',input('classifyId')); + $classify=db('goods_classify')->where('goodsclassifyId',input('classifyId'))->value('goodsclassifyName'); + $this->assign('classify',$classify); + return $this->fetch('cats'); + } + //查看活动页的活动详情 + public function catsPage(){ + $m = new M(); + $rs = $m->catsPage(); + return WSTGrid($rs); + } + /** + * 获取活动数据 + */ + public function getCats(){ + $m = new M(); + $rs = $m->getCatsId(input("recomId/d")); + return $rs; + } + /*添加分类活动分类*/ + public function addCats(){ + $m = new M(); + return $m->addCats(); + } + /*更改分类活动分类*/ + public function editCats(){ + $m = new M(); + return $m->editCats(); + } + //删除活动页活动分类 + public function catsDel(){ + $m = new M(); + return $m->catsDel(); + } + /** + * 获取活动商品详情 + */ + public function getGoods(){ + $m = new M(); + $rs = $m->getGoodsId(input("id/d")); + return $rs; + } + /*添加分类活动分类*/ + public function addGoods(){ + $m = new M(); + return $m->addGoods(); + } + //删除活动商品 + public function goodsDel(){ + $m = new M(); + return $m->goodsDel(); + } +} diff --git a/hyhproject/admin/controller/Goodsconsult.php b/hyhproject/admin/controller/Goodsconsult.php new file mode 100755 index 0000000..69dba95 --- /dev/null +++ b/hyhproject/admin/controller/Goodsconsult.php @@ -0,0 +1,44 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\GoodsConsult as M; +/** + * ============================================================================ + * 商品咨询控制器 + */ +class GoodsConsult extends Base{ + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $data = $m->getById(input("get.id/d",0)); + $assign = ['data'=>$data]; + return $this->fetch("edit",$assign); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Homemenus.php b/hyhproject/admin/controller/Homemenus.php new file mode 100755 index 0000000..e82b93e --- /dev/null +++ b/hyhproject/admin/controller/Homemenus.php @@ -0,0 +1,65 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\HomeMenus as M; +/** + * ============================================================================ + * 前台菜单控制器 + */ +class Homemenus extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取菜单列表 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 获取菜单 + */ + public function get(){ + $m = new M(); + return $m->getById((int)input("post.menuId")); + } + /** + * 新增菜单 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + /** + * 显示隐藏 + */ + public function setToggle(){ + $m = new M(); + return $m->setToggle(); + } + + /** + * 修改排序 + */ + public function changeSort(){ + $m = new M(); + return $m->changeSort(); + } +} diff --git a/hyhproject/admin/controller/Hooks.php b/hyhproject/admin/controller/Hooks.php new file mode 100755 index 0000000..fef9496 --- /dev/null +++ b/hyhproject/admin/controller/Hooks.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Hooks as M; +/** + * ============================================================================ + * 广告控制器 + */ +class Hooks extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + +} diff --git a/hyhproject/admin/controller/Images.php b/hyhproject/admin/controller/Images.php new file mode 100755 index 0000000..fcdb1c9 --- /dev/null +++ b/hyhproject/admin/controller/Images.php @@ -0,0 +1,102 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Images as M; +/** + * ============================================================================ + * 图片空间控制器 + */ +class Images extends Base{ + /** + * 进入主页面 + */ + public function index(){ + return $this->fetch(); + } + /** + * 获取概况 + * 后台商城消息 编辑器中的图片只记录上传图片容量 删除相关数据时无法标记图片为已删除状态 + */ + public function summary(){ + $m = new M(); + $data = $m->summary(); + return WSTReturn("", 1,$data); + } + /** + * 进入列表页面 + */ + public function lists(){ + $datas = model('Datas')->listQuery(3); + $this->assign('datas',$datas); + $this->assign('keyword',input('get.keyword')); + return $this->fetch('list'); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 检测图片信息 + */ + // public function checkImages(){ + // $imgPath = input('get.imgPath'); + // $m = WSTConf('CONF.wstMobileImgSuffix'); + // $imgPath = str_replace($m.'.','.',$imgPath); + // $imgPath = str_replace($m.'_thumb.','.',$imgPath); + // $imgPath = str_replace('_thumb.','.',$imgPath); + // $imgPath_thumb = str_replace('.','_thumb.',$imgPath); + // $mimg = ''; + // $mimg_thumb = ''; + // if($m!=''){ + // $mimg = str_replace('.',$m.'.',$imgPath); + // $mimg_thumb = str_replace('.',$m.'_thumb.',$imgPath); + // } + // $data['imgpath']=$imgPath; + // $data['img']=file_exists(WSTRootPath()."/".$imgPath)?true:false; + // $data['thumb']=file_exists(WSTRootPath()."/".$imgPath_thumb)?true:false; + // $data['thumbpath']=$imgPath_thumb; + // $data['mimg']=file_exists(WSTRootPath()."/".$mimg)?true:false; + // $data['mimgpath']=$mimg; + // $data['mthumb']=file_exists(WSTRootPath()."/".$mimg_thumb)?true:false; + // $data['mthumbpath']=$mimg_thumb; + // return $this->fetch('view',$data); + // } + /** + * 检测图片信息 mark 20180609 + */ + public function checkImages(){ + $imgPath = input('get.imgPath'); + $m = WSTConf('CONF.wstMobileImgSuffix'); + $imgPath = str_replace($m.'.','.',$imgPath); + $imgPath = str_replace($m.'_thumb.','.',$imgPath); + $imgPath = str_replace('_thumb.','.',$imgPath); + $imgPath_thumb = str_replace('.','_thumb.',$imgPath); + $mimg = ''; + $mimg_thumb = ''; + if($m!=''){ + $mimg = str_replace('.',$m.'.',$imgPath); + $mimg_thumb = str_replace('.',$m.'_thumb.',$imgPath); + } + $data['imgpath']=$imgPath; + $data['img']=file_exists(WSTRootPath()."/".$imgPath)?true:false; + //添加判断oss上是否存在 mark 2010608 by zl + $data['img_oss']=file_exists_oss($imgPath)?true:false; + + $data['thumb']=file_exists(WSTRootPath()."/".$imgPath_thumb)?true:false; + $data['thumbpath']=$imgPath_thumb; + $data['mimg']=file_exists(WSTRootPath()."/".$mimg)?true:false; + $data['mimgpath']=$mimg; + $data['mthumb']=file_exists(WSTRootPath()."/".$mimg_thumb)?true:false; + $data['mthumbpath']=$mimg_thumb; + return $this->fetch('view',$data); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Index.php b/hyhproject/admin/controller/Index.php new file mode 100755 index 0000000..6e4da58 --- /dev/null +++ b/hyhproject/admin/controller/Index.php @@ -0,0 +1,98 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Staffs; +use wstmart\admin\model\Menus; +use wstmart\admin\model\Index as M; +/** + * ============================================================================ + * 首页控制器 + */ +class Index extends Base{ + /** + * 跳去登录页 + */ + public function login(){ + if('quanlianggongmall' == input('key')){ + model('CronJobs')->autoByAdmin(); + return $this->fetch("/login"); + }else{ + echo 'hello'; + } + } + + public function index(){ + $m = new Menus(); + $ms = $m->getMenus(); + // dump($ms);die; + $this->assign("sysMenus",$ms); + return $this->fetch("/index"); + } + + /** + * 登录验证 + */ + public function checkLogin(){ + $m = new Staffs(); + return $m->checkLogin(); + } + + /** + * 退出系统 + */ + public function logout(){ + session('WST_STAFF',null); + return WSTReturn("退出成功,正在跳转页面", 1); + } + + /** + * 系统预览 + */ + public function main(){ + $m = new M(); + $rs = $m->summary(); + $this->assign("object",$rs); + return $this->fetch("/main"); + } + + /** + * 获取用户权限 + */ + public function getGrants(){ + $rs = session('WST_STAFF'); + if(empty($rs))return WSTReturn("您未登录,请先登录系统",-1); + $rs = $rs['privileges']; + $grants = []; + foreach ($rs as $v){ + $grants[$v] = true; + } + return WSTReturn("权限加载成功",1, $grants); + } + /** + * 清除缓存 + */ + public function clearcache(){ + WSTClearAllCache(); + return WSTReturn("清除成功!", 1); + } + + /** + * 获取最新版本提示 + */ + public function getVersion(){ + return []; + } + + /** + * 输入授权码 + */ + public function enterLicense(){ + return $this->fetch("/enter_license"); + } + /** + * 验证授权码 + */ + public function verifyLicense(){ + + } + +} diff --git a/hyhproject/admin/controller/Informs.php b/hyhproject/admin/controller/Informs.php new file mode 100755 index 0000000..14d74bc --- /dev/null +++ b/hyhproject/admin/controller/Informs.php @@ -0,0 +1,51 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Informs as M; +/** + * ============================================================================ + * 订单投诉控制器 + */ +class Informs extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 查看举报信息 + */ + public function view(){ + $m = model('informs'); + if((int)Input('cid')>0){ + $data = $m->getDetail(); + $this->assign('data',$data); + } + return $this->fetch('view'); + } + /** + * 跳去处理页面 + */ + public function toHandle(){ + $m = model('informs'); + if(Input('cid')>0){ + $data = $m->getDetail(); + $this->assign('data',$data); + } + return $this->fetch("handle"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 举报记录 + */ + public function finalHandle(){ + return model('Informs')->finalHandle(); + } + + +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Logmoneys.php b/hyhproject/admin/controller/Logmoneys.php new file mode 100755 index 0000000..f6d0699 --- /dev/null +++ b/hyhproject/admin/controller/Logmoneys.php @@ -0,0 +1,41 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\LogMoneys as M; +/** + * ============================================================================ + * 资金流水日志控制器 + */ +class Logmoneys extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取用户分页 + */ + public function pageQueryByUser(){ + $m = new M(); + return WSTGrid($m->pageQueryByUser()); + } + /** + * 获取商分页 + */ + public function pageQueryByShop(){ + $m = new M(); + return WSTGrid($m->pageQueryByShop()); + } + /** + * 获取指定记录 + */ + public function tologmoneys(){ + $m = new M(); + $object = $m->getUserInfoByType(); + $this->assign("object",$object); + return $this->fetch("list_log"); + } + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } +} diff --git a/hyhproject/admin/controller/Logoperates.php b/hyhproject/admin/controller/Logoperates.php new file mode 100755 index 0000000..640d78c --- /dev/null +++ b/hyhproject/admin/controller/Logoperates.php @@ -0,0 +1,28 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\LogOperates as M; +/** + * ============================================================================ + * 操作日志控制器 + */ +class Logoperates extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 获取指定记录 + */ + public function get(){ + $m = new M(); + return $m->getById(input('id/d',0)); + } +} diff --git a/hyhproject/admin/controller/Logsms.php b/hyhproject/admin/controller/Logsms.php new file mode 100755 index 0000000..7b0eafd --- /dev/null +++ b/hyhproject/admin/controller/Logsms.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\LogSms as M; +/** + * ============================================================================ + * 登录日志控制器 + */ +class Logsms extends Base{ + + public function index(){ + + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Logstafflogins.php b/hyhproject/admin/controller/Logstafflogins.php new file mode 100755 index 0000000..df10a36 --- /dev/null +++ b/hyhproject/admin/controller/Logstafflogins.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\LogStaffLogins as M; +/** + * ============================================================================ + * 登录日志控制器 + */ +class Logstafflogins extends Base{ + + public function index(){ + + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } +} diff --git a/hyhproject/admin/controller/Member.php b/hyhproject/admin/controller/Member.php new file mode 100755 index 0000000..e24c970 --- /dev/null +++ b/hyhproject/admin/controller/Member.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Member as M; + +class Member extends Base{ + public function index(){ + return $this->fetch('member'); + } + //分页获取 + public function memberByPage(){ + $m=new M(); + return WSTGrid($m->memberByPage()); + } + /** + * 导出订单 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Menus.php b/hyhproject/admin/controller/Menus.php new file mode 100755 index 0000000..8477020 --- /dev/null +++ b/hyhproject/admin/controller/Menus.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Menus as M; +/** + * ============================================================================ + * 菜单控制器 + */ +class Menus extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取菜单列表 + */ + public function listQuery(){ + $m = new M(); + return $m->listQuery((int)Input("post.id",-1)); + } + /** + * 获取菜单 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("post.id")); + } + /** + * 新增菜单 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Messages.php b/hyhproject/admin/controller/Messages.php new file mode 100755 index 0000000..fde0ed9 --- /dev/null +++ b/hyhproject/admin/controller/Messages.php @@ -0,0 +1,78 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Messages as M; +/** + * ============================================================================ + * 商城消息控制器 + */ +class Messages extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 查找用户 + */ + public function userQuery(){ + $m = model('users'); + return $m->getByName(input('post.loginName')); + } + /** + * 发送消息 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 查看完整消息 + */ + public function showFullMsg(){ + $m = new M(); + $rs = $m->getById(Input("id/d",0)); + return $this->fetch('msg', ['data'=>$rs]); + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/hyhproject/admin/controller/Mobilebtns.php b/hyhproject/admin/controller/Mobilebtns.php new file mode 100755 index 0000000..0ca1cd2 --- /dev/null +++ b/hyhproject/admin/controller/Mobilebtns.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\MobileBtns as M; +/** + * ============================================================================ + * 移动端按钮管理控制器 + */ +class Mobilebtns extends Base{ + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Navs.php b/hyhproject/admin/controller/Navs.php new file mode 100755 index 0000000..88fde9d --- /dev/null +++ b/hyhproject/admin/controller/Navs.php @@ -0,0 +1,69 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Navs as M; +/** + * ============================================================================ + * 导航控制器 + */ +class Navs extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + //获取省级信息 + $this->assign('area1',model('areas')->listQuery(0)); + $m = new M(); + $rs = $m->getById((int)Input("get.id")); + $this->assign("data",$rs); + return $this->fetch("edit"); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("id")); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 显示隐藏 + */ + public function editiIsShow(){ + $m = new M(); + return $m->editiIsShow(); + } + + +} diff --git a/hyhproject/admin/controller/Ordercomplains.php b/hyhproject/admin/controller/Ordercomplains.php new file mode 100755 index 0000000..92718ac --- /dev/null +++ b/hyhproject/admin/controller/Ordercomplains.php @@ -0,0 +1,120 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\OrderComplains as M; +/** + * ============================================================================ + * 订单投诉控制器 + */ +class OrderComplains extends Base{ + + public function index(){ + $areaList = model('areas')->listQuery(0); + $this->assign("areaList",$areaList); + return $this->fetch("list"); + } + /** + * 查看投诉信息 + */ + public function view(){ + $m = model('OrderComplains'); + if((int)Input('cid')>0){ + $data = $m->getDetail(); + $this->assign('order',$data); + $rs = model('orders')->getByView($data['orderId']); + $this->assign('object',$rs); + } + return $this->fetch('view'); + } + /** + * 跳去处理页面 + */ + public function toHandle(){ + $m = model('OrderComplains'); + if(Input('cid')>0){ + $data = $m->getDetail(); + $this->assign('order',$data); + $rs = model('orders')->getByView($data['orderId']); + $this->assign('object',$rs); + } + return $this->fetch("handle"); + } + /** + * 转交给应诉人回应 + */ + public function deliverRespond(){ + return model('OrderComplains')->deliverRespond(); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 仲裁投诉记录 + */ + public function finalHandle(){ + return model('OrderComplains')->finalHandle(); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(Input("id/d",0)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Orderrefunds.php b/hyhproject/admin/controller/Orderrefunds.php new file mode 100755 index 0000000..1cf3f7b --- /dev/null +++ b/hyhproject/admin/controller/Orderrefunds.php @@ -0,0 +1,46 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\OrderRefunds as M; +/** + * ============================================================================ + * 退款订单控制器 + */ +class Orderrefunds extends Base{ + /** + * 退款列表 + */ + public function refund(){ + $areaList = model('areas')->listQuery(0); + $this->assign("areaList",$areaList); + return $this->fetch("list"); + } + public function refundPageQuery(){ + $m = new M(); + return WSTGrid($m->refundPageQuery()); + } + /** + * 跳去退款界面 + */ + public function toRefund(){ + $m = new M(); + $object = $m->getInfoByRefund(); + $this->assign("object",$object); + return $this->fetch("box_refund"); + } + /** + * 退款 + */ + public function orderRefund(){ + $m = new M(); + return $m->orderRefund(); + } + + /** + * 导出订单 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} diff --git a/hyhproject/admin/controller/Orders.php b/hyhproject/admin/controller/Orders.php new file mode 100755 index 0000000..d5141f1 --- /dev/null +++ b/hyhproject/admin/controller/Orders.php @@ -0,0 +1,95 @@ +<?php + +namespace wstmart\admin\controller; + +use wstmart\admin\model\Orders as M; + +/** + + * ============================================================================ + + * 订单控制器 + + */ + +class Orders extends Base{ + + /** + + * 订单列表 + + */ + + public function index(){ + + $areaList = model('areas')->listQuery(0); + + $this->assign("areaList",$areaList); + + $this->assign("userId",(int)input('userId')); + + return $this->fetch("list"); + + } + + /** + + * 获取分页 + + */ + + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery((int)input('orderStatus',10000))); + } + //凭证列表 + public function certificate(){ + return $this->fetch("certificate_list"); + } + //获取凭证列表 + public function getCertificate(){ + $m = new M(); + return WSTGrid($m->getCertificate()); + } + //凭证设置 + public function certificateSet(){ + $m = new M(); + exit(json_encode($m->certificateSet())); + } + + /** + + * 获取订单详情 + + */ + + public function view(){ + + $m = new M(); + + $rs = $m->getByView(Input("id/d",0)); + + $this->assign("object",$rs); + + return $this->fetch("view"); + + } + + /** + + * 导出订单 + + */ + + public function toExport(){ + + $m = new M(); + + $rs = $m->toExport(); + + $this->assign('rs',$rs); + + } + +} + diff --git a/hyhproject/admin/controller/Payments.php b/hyhproject/admin/controller/Payments.php new file mode 100755 index 0000000..c514f37 --- /dev/null +++ b/hyhproject/admin/controller/Payments.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Payments as M; +/** + * ============================================================================ + * 支付控制器 + */ +class Payments extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $rs = $m->getById((int)Input("get.id")); + $payConfig = json_decode($rs['payConfig']); + //判断是否为空 + if(!empty($payConfig)){ + foreach($payConfig as $k=>$v) + $rs[$k]=$v; + } + $this->assign("object",$rs); + return $this->fetch("pay_".input('get.payCode')); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("id")); + } + + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + //商家选择支付方式 + public function pay(){ + $m=new M(); + return $m->pay(); + } + +} diff --git a/hyhproject/admin/controller/Platform.php b/hyhproject/admin/controller/Platform.php new file mode 100755 index 0000000..46f8fb3 --- /dev/null +++ b/hyhproject/admin/controller/Platform.php @@ -0,0 +1,213 @@ +<?php + +namespace wstmart\admin\controller; + +use wstmart\admin\model\Platform as M; + +/** + + * ============================================================================ + + * 基础控业务处理 + + */ + + +class Platform extends Base{ + + //列表 + + public function index(){ + + $where=[]; + + $map=[]; + + $page_map=[]; + + //接受时间 + + if (Request()->isPost()) { + + $start_date=input('start'); + + $end_date=input('end'); + + $start=strtotime($start_date); + + $end=strtotime($end_date); + + if($start && $end){ + + $where['createTime'] =array('between',[$start,$end]); + + $map['createTime'] =array('between',[$start_date,$end_date]); + + $page_map['create_time']=array('between',[$start,$end]); + + }elseif($start){ + + $where['createTime'] =array('egt',$start); + + $map['createTime'] =array('egt',$start_date); + + $page_map['create_time']=array('egt',$start); + + }elseif($end){ + + $where['createTime'] =array('elt',$end); + + $page_map['create_time']=array('elt',$end); + + $map['createTime'] =array('egt',$end_date); + + } + + } + + //判断时间周期内的注册数量 + + $where['loginSrc']=0; + + $result['pcNum'] = db('login_src')->where($where)->count(); + + $where['loginSrc']=1; + + $result['webappNum'] = db('login_src')->where($where)->count(); + + $where['loginSrc']=2 ; + + $result['appNum'] = db('login_src')->where($where)->count(); + + //查询出所有新注册用户 + + unset($where['loginSrc']); + + //dump($ids); + + //下过单的用户 + + if(Request()->isAjax()){ + + $userIds=db('login_src')->where($where)->field('userId')->select(); + + $ids=[]; + + foreach ($userIds as &$value) { + + $ids[]=$value['userId']; + + } + + $map['userId']=array('in',$ids); + + $page_map['userId']=array('in',$ids); + + } + + $map['isPay']=1; + + $result['validUser']=db('orders')->where($map)->group('userId')->count('userId'); + + //总单数 + + $orderNum=db('orders')->where($map)->count('orderId'); + + //总浏览 + + $viewNum=db('page_view')->where($page_map)->count('id'); + + // dump($orderNum); + + // dump($viewNum); + + //转换率 + + if($orderNum==0 || $viewNum==0){ + + $result['orderRade']="0".'%'; + + }else{ + + $result['orderRade']=(round($orderNum/$viewNum,2)*100).'%'; + + } + + //dump($result); + + if (Request()->isAjax()) { + + exit(jsonReturn('',1,$result)); + + } + + $this->assign('object',$result); + + //dump($result); + + return $this->fetch('platform'); + + } + + // //获取分页 + + // public function platformByPage(){ + + // $m=new M(); + + // $result=$m->platformByPage(); + + // $result['status'] = 1; + + // return WSTGrid($result); + + // } + //查看券值记录 + + public function viewData(){ + if(Request()->isAjax()){ + $dataType = input('post.dataType'); + $start_date = input('start'); + $end_date = input('end'); + $start = strtotime($start_date); + $end = strtotime($end_date); + $m = Model('common/Table'); + $m->setTable('user_vouchers_notice'); + $result['num'] = 0; + $where = []; + $map = []; + if($start && $end){ + $where['createTime'] =array('between',[$start,$end]); + $map['createTime'] =array('between',[$start_date,$end_date]); + }elseif($start){ + $where['createTime'] =array('egt',$start); + $map['createTime'] =array('egt',$start_date); + }elseif($end){ + $where['createTime'] =array('elt',$end); + $map['createTime'] =array('egt',$end_date); + } + switch ($dataType) { + case 1://预获产品券 + $result['num'] = $m->getSum(array_merge($where,['moneyType'=>1]),'expectedProductNum'); + $result['num'] -= $m->getSum(array_merge($where,['moneyType'=>0]),'expectedProductNum'); + break; + case 2://预获优惠券 + $result['num'] = $m->getSum(array_merge($where,['moneyType'=>1]),'expectedCouponsNum'); + $result['num'] -= $m->getSum(array_merge($where,['moneyType'=>0]),'expectedCouponsNum'); + break; + case 3://产品券 + case 4://优惠券 + case 5://旺旺券 + $dataType-=2; + $m->setTable('log_moneys'); + $result['num'] = $m->getSum(array_merge($map,['dataFlag'=>1,'moneyType'=>1,'moneyName'=>$dataType]),'money'); + $result['num'] -= $m->getSum(array_merge($map,['dataFlag'=>1,'moneyType'=>0,'moneyName'=>$dataType]),'money'); + break; + default: + break; + } + exit(jsonReturn('',1,$result)); + } + return $this->fetch('view_data'); + } +} \ No newline at end of file diff --git a/hyhproject/admin/controller/Privileges.php b/hyhproject/admin/controller/Privileges.php new file mode 100755 index 0000000..a27ac54 --- /dev/null +++ b/hyhproject/admin/controller/Privileges.php @@ -0,0 +1,58 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Privileges as M; +/** + * ============================================================================ + * 权限控制器 + */ +class privileges extends Base{ + /** + * 获取权限列表 + */ + public function listQuery(){ + $m = new M(); + return WSTGrid($m->listQuery((int)Input("id"))); + } + /** + * 获取权限 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("id")); + } + /** + * 新增权限 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑权限 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除权限 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 检测权限代码是否存在 + */ + public function checkPrivilegeCode(){ + $m = new M(); + return $m->checkPrivilegeCode(); + } + /** + * 获取角色的权限 + */ + public function listQueryByRole(){ + $m = new M(); + return $m->listQueryByRole((int)Input("id")); + } +} diff --git a/hyhproject/admin/controller/Recommends.php b/hyhproject/admin/controller/Recommends.php new file mode 100755 index 0000000..f18008f --- /dev/null +++ b/hyhproject/admin/controller/Recommends.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Recommends as M; +/** + * ============================================================================ + * 推荐管理控制器 + */ +class Recommends extends Base{ + /** + * 查看商品推荐 + */ + public function goods(){ + return $this->fetch('goods'); + } + /** + * 查询商品 + */ + public function searchGoods(){ + $rs = model('Goods')->searchQuery(); + return WSTReturn("", 1,$rs); + } + /** + * 推荐商品 + */ + public function editGoods(){ + $m = new M(); + return $m->editGoods(); + } + /** + * 获取已选择商品 + */ + public function listQueryByGoods(){ + $m = new M(); + $rs= $m->listQueryByGoods(); + return WSTReturn("", 1,$rs); + } + + /** + * 查看店铺推荐 + */ + public function shops(){ + return $this->fetch('shops'); + } + /** + * 查询店铺 + */ + public function searchShops(){ + $rs = model('Shops')->searchQuery(); + return WSTReturn("", 1,$rs); + } + /** + * 推荐店铺 + */ + public function editShops(){ + $m = new M(); + return $m->editShops(); + } + /** + * 获取已选择店铺 + */ + public function listQueryByShops(){ + $m = new M(); + $rs= $m->listQueryByShops(); + return WSTReturn("", 1,$rs); + } + + + /** + * 查看品牌推荐 + */ + public function brands(){ + return $this->fetch('brands'); + } + /** + * 查询品牌 + */ + public function searchBrands(){ + $rs = model('Brands')->searchBrands(); + return WSTReturn("", 1,$rs); + } + /** + * 推荐品牌 + */ + public function editBrands(){ + $m = new M(); + $rs= $m->editBrands(); + return $rs; + } + /** + * 获取已选择品牌 + */ + public function listQueryByBrands(){ + $m = new M(); + $rs= $m->listQueryByBrands(); + return WSTReturn("", 1,$rs); + } +} diff --git a/hyhproject/admin/controller/Reports.php b/hyhproject/admin/controller/Reports.php new file mode 100755 index 0000000..8360142 --- /dev/null +++ b/hyhproject/admin/controller/Reports.php @@ -0,0 +1,159 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Reports as M; +/** + * ============================================================================ + * 报表控制器 + */ +class Reports extends Base{ + /** + * 商品销售排行 + */ + public function toTopSaleGoods(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/top_sale_goods"); + } + /** + * 获取商品排行数据 + */ + public function topSaleGoodsByPage(){ + $m = new M(); + return WSTGrid($m->topSaleGoodsByPage()); + } + /** + * 店铺销售排行 + */ + public function toTopShopSales(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/top_sale_shop"); + } + /** + * 获取店铺排行数据 + */ + public function topShopSalesByPage(){ + $m = new M(); + return WSTGrid($m->topShopSalesByPage()); + } + /** + * 获取销售额 + */ + public function toStatSales(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/stat_sales"); + } + public function statSales(){ + $m = new M(); + return $m->statSales(); + } + /** + * 获取订单统计 + */ + public function toStatOrders(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/stat_orders"); + } + /* + * + */ + public function getOrders(){ + $m = new M(); + return $m->getOrders(); + } + public function statOrders(){ + $m = new M(); + return $m->statOrders(); + } + + + /** + * 获取每日新增用户 + */ + public function toStatNewUser(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/stat_new_user"); + } + public function statNewUser(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where='dataFlag=1 AND userStatus=1 AND userType=0'; + $totalNum=db('users')->where($where)->count('userId'); + if($start!='' && $end!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where.=' AND createTime BETWEEN "'.$start.'" AND "'.$end.'"'; + }else if($start!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $where.= ' AND createTime>="'.$start.'"'; + }else if($end!=''){ + $end = date('Y-m-d 00:00:00',strtotime(input('endDate'))); + $where.= ' AND createTime<="'.$end.'"'; + } + $aa=array('dsad'); + $groupNum=db('users')->where($where)->count('userId'); + $groupRate=$groupNum/$totalNum; + $m = new M(); + $a= $m->statNewUser(); + $a['groupNum']=$groupNum; + $a['groupRate']=$groupRate; + $this->assign('a',$a); +return $a; + } + /* + * 首页获取新增用户 + */ + public function getNewUser(){ + $m = new M(); + $data = cache('userNumData'); + if(empty($data)){ + $rdata = $m->statNewUser(); + cache('userNumData',$rdata,7200); + }else{ + $rdata = cache('userNumData'); + } + return $rdata; + } + /** + * 会员登录统计 + */ + public function toStatUserLogin(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch("/reports/stat_user_login"); + } + public function statUserLogin(){ + $m = new M(); + return $m->statUserLogin(); + } + /** + * 导出商品销售订单 + */ + public function toExportGoods(){ + $m = new M(); + $rs = $m->toExportGoods(); + $this->assign('rs',$rs); + } + /** + * 导出商家销售订单 + */ + public function toExportShop(){ + $m = new M(); + $rs = $m->toExportShop(); + $this->assign('rs',$rs); + } + // 店铺商品销售统计 + public function detail(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch('detail'); + } + public function detailByPage(){ + $m=new M(); + $result=$m->detailByPage(); + return $result; + } +} diff --git a/hyhproject/admin/controller/Roles.php b/hyhproject/admin/controller/Roles.php new file mode 100755 index 0000000..a1e1c85 --- /dev/null +++ b/hyhproject/admin/controller/Roles.php @@ -0,0 +1,60 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Roles as M; +/** + * ============================================================================ + * 角色控制器 + */ +class Roles extends Base{ + + public function index(){ + + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 获取菜单 + */ + public function get(){ + + $m = new M(); + return $m->get((int)Input("post.id")); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $rs = $m->getById((int)Input("get.id")); + $this->assign("object",$rs); + return $this->fetch("edit"); + } + /** + * 新增菜单 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Settlements.php b/hyhproject/admin/controller/Settlements.php new file mode 100755 index 0000000..4d984cc --- /dev/null +++ b/hyhproject/admin/controller/Settlements.php @@ -0,0 +1,102 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Settlements as M; +/** + * ============================================================================ + * 结算控制器 + */ +class Settlements extends Base{ + public function index(){ + return $this->fetch('list'); + } + + /** + * 获取列表 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去结算页面 + */ + public function toHandle(){ + $m = new M(); + $object = $m->getById(); + $this->assign("object",$object); + return $this->fetch('edit'); + } + + /** + * 处理订单 + */ + public function handle(){ + $m = new M(); + return $m->handle(); + } + /** + * 跳去结算详情 + */ + public function toView(){ + $m = new M(); + $object = $m->getById(); + $this->assign("object",$object); + return $this->fetch('view'); + } + + /** + * 获取订单商品 + */ + public function pageGoodsQuery(){ + $m = new M(); + return WSTGrid($m->pageGoodsQuery()); + } + + /************************************************* + * 以下是平台主动生成结算单 + ************************************************/ + /** + * 进入平台结算野蛮 + */ + public function toShopIndex(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch('list_shop'); + } + + /** + * 获取待结算的商家列表 + */ + public function pageShopQuery(){ + $m = new M(); + return WSTGrid($m->pageShopQuery()); + } + /** + * 进入订单列表页面 + */ + public function toOrders(){ + $this->assign("id",(int)input('id')); + return $this->fetch('list_order'); + } + /** + * 获取商家的待结算订单列表 + */ + public function pageShopOrderQuery(){ + $m = new M(); + return WSTGrid($m->pageShopOrderQuery()); + } + /** + * 生成结算单 + */ + public function generateSettleByShop(){ + $m = new M(); + return $m->generateSettleByShop(); + } + /** + * 导出 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} diff --git a/hyhproject/admin/controller/Shops.php b/hyhproject/admin/controller/Shops.php new file mode 100755 index 0000000..d5c040f --- /dev/null +++ b/hyhproject/admin/controller/Shops.php @@ -0,0 +1,294 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Shops as M; +use wstmart\common\model\Table as TM; +/** + * ============================================================================ + * 店铺控制器 + */ +class Shops extends Base{ + public function index(){ + $this->assign("areaList",model('areas')->listQuery(0)); + $this->assign("catList",model('GoodsCats')->listQuery(0)); + return $this->fetch("list"); + + } + + public function stopIndex(){ + $this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch("list_stop"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 停用店铺列表 + */ + public function pageStopQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery(-1)); + } + // 商家登录 + public function detail(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch('detail'); + } + public function detailByPage(){ + $m=new M(); + $result=$m->detailByPage(); + return WSTGrid($result); + } + /** + * 获取菜单 + */ + public function get(){ + $m = new M(); + return $m->get((int)Input("post.id")); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $id = (int)Input("get.id"); + if($id>0){ + $object = $m->getById((int)Input("get.id")); + $object['auxiliary']=db('shop_auxiliary')->where('shopId',$object['shopId'])->select(); + $data['object']=$object; + }else{ + $object = $m->getEModel('shops'); + $object['catshops'] = []; + $object['accreds'] = []; + $object['loginName'] = ''; + $data['object']=$object; + } + $data['goodsCatList'] = model('goodsCats')->listQuery(0); + $data['accredList'] = model('accreds')->listQuery(0); + $data['bankList'] = model('banks')->listQuery(); + $data['areaList'] = model('areas')->listQuery(0); + if($id>0){ + return $this->fetch("edit",$data); + }else{ + return $this->fetch("add",$data); + } + } + + /** + * 新增菜单 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + /** + * 检测店铺编号是否存在 + */ + public function checkShopSn(){ + $m = new M(); + $isChk = $m->checkShopSn(input('post.shopSn'),input('shopId/d')); + if(!$isChk){ + return ['ok'=>'该店铺编号可用']; + }else{ + return ['error'=>'对不起,该店铺编号已存在']; + } + } + + /** + * 自营店铺后台 + */ + public function inself(){ + $staffId=session("WST_STAFF"); + if(!empty($staffId)){ + $id=1; + $s = new M(); + $r = $s->selfLogin($id); + if($r['status']==1){ + header("Location: ".Url('home/shops/index')); + exit(); + } + } + header("Location: ".Url('home/shops/selfShop')); + exit(); + } + + /** + * 跳去店铺申请列表 + */ + public function apply(){ + $this->assign("areaList",model('Position')->listQuery()); + //$this->assign("areaList",model('areas')->listQuery(0)); + return $this->fetch("list_apply"); + } + /** + * 获取分页 + */ + public function pageQueryByApply(){ + $m = new M(); + return WSTGrid($m->pageQueryByApply()); + } + /** + * 获取店铺申请列表 + */ + public function shopApplyList(){ + $m = new M(); + return WSTGrid($m->shopApplyList()); + } + + /** + * 去处理开店申请 + */ + public function applyEdit(){ + $data = []; + $id = input('get.id/d'); + // dump($id); + $m = new TM(); + $m->setTable('shops'); + $data['object'] = $m->getInfo(['shopId'=>$id],'*'); + $data['object']['applyTime'] = date('Y-m-d H:i:s',$data['object']['createTime']); + //改成用户表 + $m->setTable('users'); + $data['object']['user'] = $m->getInfo(['userId'=>$data['object']['userId']],'loginName,trueName'); + $areas=['province','city','county','town','village']; + $data['object']['area'] = ''; + foreach ($areas as $v) { + $m->setTable('position_'.$v); + $data['object']['area'] .=$m->getField([$v.'_id'=>$data['object'][$v.'Id']],$v.'_name').'-'; + } + + + // //改成省表 + // $m->setTable('position_province'); + // $data['object']['area'] = $m->getField(['province_id'=>$data['object']['provinceId']],'province_name'); + // //改成市表 + // $m->setTable('position_city'); + // $data['object']['area'] .='-'.$m->getField(['city_id'=>$data['object']['cityId']],'city_name'); + // //改成区表 + // $m->setTable('position_county'); + // $data['object']['area'] .='-'.$m->getField(['county_id'=>$data['object']['countyId']],'county_name'); + // //改成乡镇表 + // $m->setTable('position_town'); + // $data['object']['area'] .='-'.$m->getField(['town_id'=>$data['object']['townId']],'town_name'); + // //改成村表 + // $m->setTable('position_village'); + // $data['object']['area'] .='-'.$m->getField(['village_id'=>$data['object']['villageId']],'village_name'); + // dump($data);die; + return $this->fetch("apply_edit",$data); + } + /** + * 去处理开店申请 + */ + public function toHandleApply(){ + $data = []; + $data['shoplicense']=db('shop_license') + ->where('shopId',(int)input("get.id")) + ->find(); + $data['cashDeposit'] = db('shops_deposit')->where('shopId',(int)input("get.id"))->find(); + $data['object'] = model('shops')->getShopApply((int)input("get.id")); + $data['goodsCatList'] = model('goodsCats')->listQuery(0); + $data['accredList'] = model('accreds')->listQuery(0); + $data['bankList'] = model('banks')->listQuery(); + $data['areaList'] = model('areas')->listQuery(0); + return $this->fetch("edit_apply",$data); + } + + public function delApply(){ + $m = new M(); + return $m->delApply(); + } + + /** + * 开店申请处理 + */ + public function handleApply(){ + $m = new M(); + return $m->handleApply(); + } + /** + * 导出订单 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } + /** + * 导出商家登录订单 + */ + public function toExports(){ + $m = new M(); + $rs = $m->toExports(); + $this->assign('rs',$rs); + } + + /** + * 管理质保金页面 + */ + public function toDeposit(){ + $m = new M(); + return $this->fetch('deposit'); + } + /** + * 质保金充值或扣除 + */ + public function topDeposit(){ + $m = new M(); + $result = $m->topDeposit(); + exit(json_encode($result)); + } + + /** + * 获取店铺名称 + */ + public function upShopName(){ + $m = new M(); + $res = $m->upShopName(); + // dump($res);die; + exit(json_encode($res)); + } + + /** + * 修改佣金扣点 + */ + public function commission(){ + $m = new M(); + $obj = $m->commission((int)Input("post.shopId")); + exit(json_encode($obj)); + } + + /** + * 设置店铺佣金扣点,业务员提成 + */ + public function upCommission(){ + $m = new M(); + $result = $m->upCommission(); + exit(json_encode($result)); + } + /** + * 查询业务员信息 + */ + public function staffs(){ + $m = new M(); + $data = $m->staffs(); + exit(json_encode($data)); + } +} diff --git a/hyhproject/admin/controller/Speccats.php b/hyhproject/admin/controller/Speccats.php new file mode 100755 index 0000000..4f19b09 --- /dev/null +++ b/hyhproject/admin/controller/Speccats.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\SpecCats as M; +/** + * ============================================================================ + * 规格类别控制器 + */ +class Speccats extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 跳去编辑页面 + */ + public function toEdit(){ + //获取该记录信息 + $this->assign('data', $this->get()); + return $this->fetch("edit"); + } + /** + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById(input("catId/d")); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 显示隐藏 + */ + public function setToggle(){ + $m = new M(); + return $m->setToggle(); + } + + public function checkCatName(){ + $m = new M(); + $rs = $m->checkCatName(); + if($rs["status"]==1){ + return array("ok"=>""); + }else{ + return array("error"=>$rs["msg"]); + } + } + +} diff --git a/hyhproject/admin/controller/Staffs.php b/hyhproject/admin/controller/Staffs.php new file mode 100755 index 0000000..0611523 --- /dev/null +++ b/hyhproject/admin/controller/Staffs.php @@ -0,0 +1,92 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Staffs as M; +use wstmart\admin\model\Roles as R; +/** + * ============================================================================ + * 职员控制器 + */ +class Staffs extends Base{ + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 获取 + */ + public function get(){ + $m = new M(); + return $m->get((int)Input("post.id")); + } + /** + * 跳去新增界面 + */ + public function toAdd(){ + $id = (int)Input("get.id",0); + $m = new M(); + $this->assign("object",['staffId'=>0,'workStatus'=>1,'staffStatus'=>1]); + $m = new R(); + $this->assign("roles",$m->listQuery()); + return $this->fetch("add"); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $id = (int)Input("get.id",0); + $m = new M(); + $rs = $m->getById($id); + $this->assign("object",$rs); + $m = new R(); + $this->assign("roles",$m->listQuery()); + return $this->fetch("edit"); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑菜单 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除菜单 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 检测账号是否重复 + */ + public function checkLoginKey(){ + $m = new M(); + return $m->checkLoginKey(input('post.key')); + } + /** + * 编辑自己密码 + */ + public function editMyPass(){ + $m = new M(); + return $m->editMyPass((int)session('WST_STAFF.staffId')); + } + /** + * 编辑职员密码 + */ + public function editPass(){ + $m = new M(); + return $m->editPass((int)input('post.staffId')); + } +} diff --git a/hyhproject/admin/controller/Styles.php b/hyhproject/admin/controller/Styles.php new file mode 100755 index 0000000..24e239f --- /dev/null +++ b/hyhproject/admin/controller/Styles.php @@ -0,0 +1,33 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Styles as M; +/** + * ============================================================================ + * 风格配置控制器 + */ +class Styles extends Base{ + + public function index(){ + $m = new M(); + $rs = $m->getCats(); + $m->initStyles(); + $this->assign('cats',$rs); + return $this->fetch(); + } + /** + * 获取风格列表 + */ + public function listQueryBySys(){ + $m = new M(); + $rs = $m->listQuery(); + return WSTReturn('',1,$rs); + } + + /** + * 保存 + */ + public function changeStyle(){ + $m = new M(); + return $m->changeStyle(); + } +} diff --git a/hyhproject/admin/controller/Sysconfigs.php b/hyhproject/admin/controller/Sysconfigs.php new file mode 100755 index 0000000..d941d6f --- /dev/null +++ b/hyhproject/admin/controller/Sysconfigs.php @@ -0,0 +1,30 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\SysConfigs as M; +/** + * ============================================================================ + * 商城配置控制器 + */ +class Sysconfigs extends Base{ + + public function index(){ + $m = new M(); + $object = $m->getSysConfigs(); + $this->assign("object",$object); + $list = model('admin/staffs')->listQuery(); + $this->assign("list",$list); + $tm = Model('common/Table'); + $tm->setTable('data_configs'); + $dataConfigs = $tm->getList([],'*'); + $this->assign("dataConfigs",$dataConfigs); + return $this->fetch("edit"); + } + + /** + * 保存 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } +} diff --git a/hyhproject/admin/controller/Templatemsgs.php b/hyhproject/admin/controller/Templatemsgs.php new file mode 100755 index 0000000..7b8fed5 --- /dev/null +++ b/hyhproject/admin/controller/Templatemsgs.php @@ -0,0 +1,95 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\TemplateMsgs as M; +/** + * ============================================================================ + * 消息模板控制器 + */ +class Templatemsgs extends Base{ + + public function index(){ + $this->assign('src',(int)input('src')); + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageMsgQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery(0,'TEMPLATE_SYS')); + } + /** + * 设置是否显示/隐藏 + */ + public function editiIsShow(){ + $m = new M(); + $rs = $m->editiIsShow(); + return $rs; + } + /** + * 跳转去新增页面 + */ + public function toEditMsg(){ + $id = (int)input('id'); + $m = new M(); + if($id>0){ + $data = $m->getById($id); + }else{ + $data = $m->getEModel('template_msgs'); + } + $this->assign('object',$data); + return $this->fetch("edit_msg"); + } + /** + * 跳转去新增页面 + */ + public function toEditEmail(){ + $id = (int)input('id'); + $m = new M(); + if($id>0){ + $data = $m->getById($id); + }else{ + $data = $m->getEModel('template_email'); + } + $this->assign('object',$data); + return $this->fetch("edit_email"); + } + /** + * 跳转去新增页面 + */ + public function toEditSMS(){ + $id = (int)input('id'); + $m = new M(); + if($id>0){ + $data = $m->getById($id); + }else{ + $data = $m->getEModel('template_sms'); + } + $this->assign('object',$data); + return $this->fetch("edit_sms"); + } + + /** + * 发送消息 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 获取分页 + */ + public function pageEmailQuery(){ + $m = new M(); + return WSTGrid($m->pageEmailQuery()); + } + /** + * 获取分页 + */ + public function pageSMSQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery(2,'TEMPLATE_SMS')); + } + +} diff --git a/hyhproject/admin/controller/Userranks.php b/hyhproject/admin/controller/Userranks.php new file mode 100755 index 0000000..3de7b48 --- /dev/null +++ b/hyhproject/admin/controller/Userranks.php @@ -0,0 +1,59 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\UserRanks as M; +/** + * ============================================================================ + * 会员等级控制器 + */ +class Userranks extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $assign = ['data'=>$this->get(), + 'object'=>$m->getById((int)Input("post.id"))]; + return $this->fetch("edit",$assign); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("id")); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + + +} diff --git a/hyhproject/admin/controller/Users.php b/hyhproject/admin/controller/Users.php new file mode 100755 index 0000000..3fc9c72 --- /dev/null +++ b/hyhproject/admin/controller/Users.php @@ -0,0 +1,253 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Users as M; +/** + * ============================================================================ + * 会员控制器 + */ +class Users extends Base{ + /** + * 个体认证审核 + */ + public function personalReview(){ + return $this->fetch("personal_review_list"); + } + /** + * 个体认证审核列表 + */ + public function getPersonalReview(){ + $m = new M(); + return WSTGrid($m->getReview(1)); + } + + /** + * 个体认证操作 + */ + public function personalAction(){ + $m = new M(); + return $m->authAction(1); + } + /** + * 个体认证审核 + */ + public function companyReview(){ + return $this->fetch("company_review_list"); + } + /** + * 个体认证审核列表 + */ + public function getCompanyReview(){ + $m = new M(); + return WSTGrid($m->getReview(2)); + } + + /** + * 个体认证操作 + */ + public function companyAction(){ + $m = new M(); + return $m->authAction(2); + } + /** + * 获取亲人认证/报备列表 + */ + public function authFamilyList(){ + $m = Model('AuthFamily'); + if(1 == (int)input( 'post.isPersonal')){//亲人认证 + $m->setTable('auth_family_personal'); + } + $where['userId'] = (int)input( 'post.userId'); + $data = $m->getList($where,'*'); + return WSTReturn('',1,$data); + } + /** + * 获取亲人认证/报备列表 + */ + public function familyList(){ + $m = Model('AuthFamily'); + if(1 == (int)input( 'post.isPersonal')){//亲人认证 + $m->setTable('auth_family_personal'); + } + $where['userId'] = (int)input( 'post.userId'); + $data = $m->getList($where,'*'); + return WSTReturn('',1,$data); + } + /** + * 获取合作人列表 + */ + public function authCompanyList(){ + $m = Model('Table'); + $m->setTable('auth_company_partner'); + $where['userId'] = (int)input( 'post.userId'); + $where['dataFlag'] = 1; + $data = $m->getList($where,'*'); + return WSTReturn('',1,$data); + } + /** + * 获取银行卡 + */ + public function authCompanyBank(){ + $m = Model('CompanyBank'); + $where['userId'] = (int)input( 'post.userId'); + $data = $m->getList($where,'*'); + return WSTReturn('',1,$data); + } + public function index(){ + return $this->fetch("list"); + } + /** + * 申请列表 + */ + public function userUpdateList(){ + return $this->fetch("update_list"); + } + /** + * 获取申请列表 + */ + public function getUserUpdateList(){ + $m = new M(); + $data = $m->getUserUpdateList(); + return WSTGrid($data); + } + /** + * 申请升级操作 + */ + public function setUserUpdate(){ + $m = new M(); + $data = $m->setUserUpdate(); + exit(json_encode($data)); + } + /** + * 查看会员定返数据 + */ + public function viewUserDayData(){ + return $this->fetch("user_day_list"); + } + /** + * 获取申请列表 + */ + public function getViewUserDayData(){ + $m = new M(); + $data = $m->getViewUserDayData(); + return WSTGrid($data); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + /** + * 跳去编辑页面 + */ + public function toEdit(){ + $m = new M(); + $data = $this->get(); + $assign = ['data'=>$data]; + return $this->fetch("edit",$assign); + } + /** + * 跳去充值页面 + */ + public function toRecharge(){ + $m = new M(); + $data = $this->get(); + $assign = ['data'=>$data]; + return $this->fetch("recharge",$assign); + } + /* + * 获取数据 + */ + public function get(){ + $m = new M(); + return $m->getById((int)Input("id")); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 充值 + */ + public function recharge(){ + $m = new M(); + return $m->recharge(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + public function getUserByKey(){ + $m = new M(); + return $m->getUserByKey(); + } + /********************************************************************************************** + * 账号管理 * + **********************************************************************************************/ + /** + * 账号管理页面 + */ + public function accountIndex(){ + return $this->fetch("account_list"); + } + /** + * 判断账号是否存在 + */ + public function checkLoginKey(){ + $rs = WSTCheckLoginKey(Input('post.loginName'),Input('post.userId/d',0)); + if($rs['status']==1){ + return ['ok'=>$rs['msg']]; + }else{ + return ['error'=>$rs['msg']]; + } + } + /** + * 是否启用 + */ + public function changeUserStatus($id, $status){ + $m = new M(); + return $m->changeUserStatus($id, $status); + } + public function editAccount(){ + $m = new M(); + return $m->edit(); + } + /** + * 获取所有用户id + */ + public function getAllUserId() + { + $m = new M(); + return $m->getAllUserId(); + } + /** + * 重置支付密码 + */ + public function resetPayPwd(){ + $m = new M(); + return $m->resetPayPwd(); + } + /** + * 导出订单 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} diff --git a/hyhproject/admin/controller/Userscores.php b/hyhproject/admin/controller/Userscores.php new file mode 100755 index 0000000..714f2ab --- /dev/null +++ b/hyhproject/admin/controller/Userscores.php @@ -0,0 +1,42 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\UserScores as M; +/** + * ============================================================================ + * 积分日志控制器 + */ +class Userscores extends Base{ + + public function toUserScores(){ + $m = new M(); + $object = $m->getUserInfo(); + $this->assign("object",$object); + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery()); + } + + /** + * 跳去新增界面 + */ + public function toAdd(){ + $m = new M(); + $object = $m->getUserInfo(); + $this->assign("object",$object); + return $this->fetch("box"); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->addByAdmin(); + } +} diff --git a/hyhproject/admin/controller/Wsysconfigs.php b/hyhproject/admin/controller/Wsysconfigs.php new file mode 100755 index 0000000..fba630e --- /dev/null +++ b/hyhproject/admin/controller/Wsysconfigs.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\SysConfigs as M; +/** + * ============================================================================ + * 微信配置控制器 + */ +class Wsysconfigs extends Base{ + + public function index(){ + $m = new M(); + $object = $m->getSysConfigs(); + $this->assign("object",$object); + return $this->fetch("edit"); + } + + /** + * 保存 + */ + public function edit(){ + $m = new M(); + return $m->edit(1); + } +} diff --git a/hyhproject/admin/controller/Wxmenus.php b/hyhproject/admin/controller/Wxmenus.php new file mode 100755 index 0000000..9a8791e --- /dev/null +++ b/hyhproject/admin/controller/Wxmenus.php @@ -0,0 +1,87 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Wxmenus as M; +/** + * ============================================================================ + * 微信自定义列表控制器 + */ +class Wxmenus extends Base{ + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 获取列表 + */ + public function listQuery(){ + $m = new M(); + return $m->listQuery(); + } + + /** + * 与微信菜单同步 + */ + public function synchroWx(){ + $m = new M(); + return $m->synchroWx(); + } + + /** + * 同步到微信菜单 + */ + public function synchroAd(){ + $m = new M(); + return $m->synchroAd(); + } + + /** + * 跳去新增/编辑页面 + */ + public function toEdit(){ + $menuId = Input("get.menuId/d",0); + $parentId = Input("get.parentId/d",0); + $m = new M(); + if($menuId>0){ + $object = $m->getById($menuId); + }else{ + $object = $m->getEModel('wx_menus'); + } + $this->assign('menuId',$menuId); + $this->assign('parentId',$parentId); + $this->assign('object',$object); + return $this->fetch("edit"); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Wxpassivereplys.php b/hyhproject/admin/controller/Wxpassivereplys.php new file mode 100755 index 0000000..24d0f49 --- /dev/null +++ b/hyhproject/admin/controller/Wxpassivereplys.php @@ -0,0 +1,85 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\WxPassiveReplys as M; +/** + * ============================================================================ + * 微信被动回复管理控制器 + */ +class Wxpassivereplys extends Base{ + // 文本消息列表 + public function text(){ + return $this->fetch("text"); + } + /** + * 获取文本消息分页 + */ + public function textPageQuery(){ + $m = new M(); + return WSTGrid($m->textPageQuery()); + } + /** + * 跳去文本消息新增/编辑页面 + */ + public function textEdit(){ + $id = Input("get.id/d",0); + $m = new M(); + $data = $m->getById($id); + $this->assign('data',$data); + return $this->fetch("text_edit"); + } + + + + // 图文消息列表 + public function news(){ + return $this->fetch("news"); + } + /** + * 获取图文消息分页 + */ + public function newsPageQuery(){ + $m = new M(); + return $m->newsPageQuery(); + } + /** + * 跳去图文消息新增/编辑页面 + */ + public function newsEdit(){ + $id = Input("get.id/d",0); + $m = new M(); + $data = $m->getById($id); + $this->assign('data',$data); + return $this->fetch("news_edit"); + } + + + + + // + public function sendNews(){ + $wx = WXAdmin(); + $wx->_doText(); + } + + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/admin/controller/Wxtemplatemsgs.php b/hyhproject/admin/controller/Wxtemplatemsgs.php new file mode 100755 index 0000000..35a0f13 --- /dev/null +++ b/hyhproject/admin/controller/Wxtemplatemsgs.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\TemplateMsgs as M; +/** + * ============================================================================ + * 微信消息模板控制器 + */ +class Wxtemplatemsgs extends Base{ + + public function index(){ + return $this->fetch("list"); + } + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return WSTGrid($m->pageQuery(3,'TEMPLATE_WX')); + } + /** + * 跳转去新增页面 + */ + public function toEdit(){ + $id = (int)input('id'); + $m = new M(); + if($id>0){ + $data = $m->getById($id); + }else{ + $data = $m->getEModel('template_msgs'); + } + $this->assign('object',$data); + return $this->fetch("edit"); + } + + /** + * 发送消息 + */ + public function edit(){ + return model('WxTemplateParams')->edit(); + } + + /** + * 获取参数列表 + */ + public function listQuery(){ + return model('WxTemplateParams')->listQuery((int)input('post.parentId')); + } + +} diff --git a/hyhproject/admin/controller/Wxusers.php b/hyhproject/admin/controller/Wxusers.php new file mode 100755 index 0000000..c22dbdc --- /dev/null +++ b/hyhproject/admin/controller/Wxusers.php @@ -0,0 +1,53 @@ +<?php +namespace wstmart\admin\controller; +use wstmart\admin\model\Wxusers as M; +/** + * ============================================================================ + * 微信用户控制器 + */ +class Wxusers extends Base{ + public function recodeUnionId(){ + $m = new M(); + return json_encode($m->recodeUnionId()); + } + + public function index(){ + return $this->fetch("list"); + } + + /** + * 获取分页 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 与微信用户管理同步 + */ + public function synchroWx(){ + $m = new M(); + return $m->synchroWx(); + } + public function wxLoad(){ + $m = new M(); + return $m->wxLoad(); + } + + /** + * 获取指定对象 + */ + public function getById(){ + $m = new M(); + return $m->getById((int)input('id')); + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } +} diff --git a/hyhproject/admin/model/Accreds.php b/hyhproject/admin/model/Accreds.php new file mode 100755 index 0000000..d37943d --- /dev/null +++ b/hyhproject/admin/model/Accreds.php @@ -0,0 +1,172 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 商家认证业务处理 + + */ + +class Accreds extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + return $this->where('dataFlag',1)->field(true)->order('accredId desc')->paginate(input('limit/d')); + + } + + /** + + * 列表 + + */ + + public function listQuery(){ + + return $this->where('dataFlag',1)->field(true)->select(); + + } + + public function getById($id){ + + return $this->get(['accredId'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + WSTUnset($data,'accredId'); + + Db::startTrans(); + + try{ + + $result = $this->validate('Accreds.add')->allowField(true)->save($data); + + if(false !==$result){ + + $id = $this->accredId; + + //启用上传图片 + + WSTUseImages(1, $id, $data['accredImg']); + + if(false !== $result){ + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $data = input('post.'); + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, (int)$data['accredId'], $data['accredImg'], 'accreds', 'accredImg'); + + $result = $this->validate('Accreds.edit')->allowField(true)->save($data,['accredId'=>(int)$data['accredId']]); + + if(false !== $result){ + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d'); + + Db::startTrans(); + + try{ + + $result = $this->setField(['dataFlag'=>-1,'accredId'=>$id]); + + WSTUnuseImage('accreds','accredImg',$id); + + if(false !== $result){ + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('删除失败',-1); + + } + + + +} + diff --git a/hyhproject/admin/model/AdPositions.php b/hyhproject/admin/model/AdPositions.php new file mode 100755 index 0000000..547fba0 --- /dev/null +++ b/hyhproject/admin/model/AdPositions.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 广告位置业务处理 + */ +class AdPositions extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $positionType = (int)input('positionType'); + $key = input('key'); + $where = []; + $where['dataFlag'] = 1; + if($positionType>0)$where['positionType'] = $positionType; + if($key !='')$where['positionCode'] = ['like','%'.$key.'%']; + return $this->where($where)->field(true)->order('apSort asc,positionId desc')->paginate(input('limit/d')); + } + public function getById($id){ + return $this->get(['positionId'=>$id,'dataFlag'=>1]); + } + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + WSTUnset($data,'positionId'); + $result = $this->validate('AdPositions.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $Id = (int)input('post.positionId'); + $result = $this->validate('AdPositions.edit')->allowField(true)->save(input('post.'),['positionId'=>$Id]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = (int)input('post.id/d'); + $result = $this->setField(['positionId'=>$id,'dataFlag'=>-1]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取广告位置 + */ + public function getPositon($typeId){ + return $this->where(['positionType'=>$typeId,'dataFlag'=>1])->order('apSort asc,positionId asc')->select(); + } + +} diff --git a/hyhproject/admin/model/Addons.php b/hyhproject/admin/model/Addons.php new file mode 100755 index 0000000..9badbaf --- /dev/null +++ b/hyhproject/admin/model/Addons.php @@ -0,0 +1,139 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 插件业务处理 + */ +class Addons extends Base{ + + /** + * 获取插件列表 + * @param string $addon_dir + */ + public function pageQuery($addon_dir = ''){ + if(!$addon_dir) + $addon_dir = WST_ADDON_PATH; + $dirs = array_map('basename',glob($addon_dir.'*', GLOB_ONLYDIR)); + if($dirs === FALSE || !file_exists($addon_dir)){ + $this->error = '插件目录不可读或者不存在'; + return FALSE; + } + $addons = array(); + $where['dataFlag'] = 1; + $where['name'] = array('not in',$dirs); + $this->where($where)->delete(); + + $names = $this->column("name"); + $names = array_map('strtolower', $names); + $list = array(); + foreach ($dirs as $value) { + if(!in_array($value,$names)){ + $class = get_addon_class($value); + if(!class_exists($class)){ // 实例化插件失败忽略执行 + \Think\Log::record('插件'.$value.'的入口文件不存在!'); + continue; + } + $obj = new $class; + $data = $obj->info; + $config = $obj->getConfig(); + $data["isConfig"] = count($config)?1:0; + $data["createTime"] = date("Y-m-d H:i:s"); + $data["updateTime"] = date("Y-m-d H:i:s"); + $data["dataFlag"] = 1; + $list[] = $data; + } + } + $this->saveAll($list); + $keyWords = input("keyWords"); + $parentId = input('get.parentId/d',0); + $sort = input('sort'); + $where = array(); + $where["dataFlag"] = 1; + $where["name|title"] = array("like","%$keyWords%"); + $order = 'addonId desc'; + if($sort){ + $sort = str_replace('.',' ',$sort); + $order = $sort; + } + $page = $this->where($where)->order($order)->paginate(input('post.limit/d'))->toArray(); + if(count($page['Rows'])>0){ + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['statusName'] = WSTLangAddonStatus($v['status']); + $page['Rows'][$key]['hasConf'] = ($v['isConfig']!='')?1:0; + } + } + cache('WST_ADDONS_MAPS',null); + return $page; + + } + + /** + * 保存插件设置 + */ + public function saveConfig(){ + $id = input("id/d",0); + $config = isset($_POST['config'])?$_POST['config']:array(); + $data["config"] = json_encode($config); + $data["updateTime"] = date('Y-m-d H:i:s'); + $flag = $this->save($data,['addonId'=>$id]); + if($flag !== false){ + return WSTReturn("保存成功", 1); + }else{ + return WSTReturn('保存失败',-1); + } + } + + /** + * 获取指定记录 + */ + public function getById(){ + $id = input("id/d",0); + return $this->get(['addonId'=>$id,'dataFlag'=>1])->toArray(); + } + + /** + * 新增 + */ + public function add(){ + + return WSTReturn("新增成功", 1); + } + + /** + * 编辑 + */ + public function edit(){ + return WSTReturn("编辑成功", 1); + } + + /** + * 删除 + */ + public function del(){ + $id = (int)input('post.id/d'); + $result = $this->where(["addonId"=>$id,'dataFlag'=>1])->delete(); + if($result!==false){ + cache('WST_ADDONS_MAPS',null); + return WSTReturn("卸载成功", 1); + } + return WSTReturn('卸载失败',-1); + } + + /** + * 修改插件状态 + */ + public function editStatus($status){ + $id = (int)input('post.id/d'); + $data = array(); + $data["status"] = $status; + $data["updateTime"] = date('Y-m-d H:i:s'); + $result = $this->save($data,['addonId'=>$id]); + if($result!==false){ + return WSTReturn("操作成功", 1); + } + return WSTReturn('操作失败',-1); + } + + +} diff --git a/hyhproject/admin/model/Adgoods.php b/hyhproject/admin/model/Adgoods.php new file mode 100755 index 0000000..4c7c69f --- /dev/null +++ b/hyhproject/admin/model/Adgoods.php @@ -0,0 +1,224 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 广告业务处理 + + */ + +class adgoods extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $where = []; + + $apId = (int)input('adId'); + + if($apId>0)$where['a.adId'] = $apId; + + return Db::name('adgoods')->alias('a') + + ->join('ads ap','a.adId=ap.adId','left') + + ->join('goods g','g.goodsId=a.goodsId') + + ->field('a.adId,adName,g.goodsId,goodsName,a.startDate,a.endDate,adGoodsImg,a.adGoodsStatus,a.adGoodsId') + + ->where($where)->order('a.adId desc') + + ->order('a.goodsId','asc') + + ->paginate(input('limit/d')); + + } + + public function getById($id){ + + $result= $this->get(['adGoodsId'=>$id]); + + //$result['adName']=db('ads')->where('adId',$result['adId'])->value('adName'); + + return $result; + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['createTime'] = time(); + + WSTUnset($data,'adGoodsId'); + + Db::startTrans(); + + try{ + + $goods=db('goods')->where(['goodsId'=>$data['goodsId'],'dataFlag'=>1,'isSale'=>1,'goodsStatus'=>1])->find(); + + if(!$goods) return WSTReturn('无此商品,请重新选择商品'); + + $result = $this->validate('adgoods.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + $id = $this->adId; + + //启用上传图片 + + WSTUseImages(1, $id, $data['adGoodsImg']); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $data = input('post.'); + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + //WSTUseImages(1, (int)$data['adId'], $data['adFile'], 'ads-pic', 'adFile'); + + $result = $this->validate('adgoods.edit')->allowField(true)->save($data,['adGoodsId'=>(int)$data['adGoodsId']]); + + if(false !== $result){ + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d'); + + Db::startTrans(); + + try{ + + $result = $this->where(['adGoodsId'=>$id])->delete(); + + WSTUnuseImage('adgoods','adGoodsImg',$id); + + if($result){ + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + /** + + * 修改广告排序 + + */ + + public function changeSort(){ + + $id = (int)input('id'); + + $adSort = (int)input('adSort'); + + $result = $this->setField(['adId'=>$id,'adSort'=>$adSort]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/Ads.php b/hyhproject/admin/model/Ads.php new file mode 100755 index 0000000..751b193 --- /dev/null +++ b/hyhproject/admin/model/Ads.php @@ -0,0 +1,228 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 广告业务处理 + + */ + +class ads extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $where = []; + + $where['a.dataFlag'] = 1; + + $pt = (int)input('positionType'); + + $apId = (int)input('adPositionId'); + + if($pt>0)$where['a.positionType'] = $pt; + + if($apId!=0)$where['a.adPositionId'] = $apId; + + + + + + return Db::name('ads')->alias('a') + + ->join('ad_positions ap','a.positionType=ap.positionType AND a.adPositionId=ap.positionId AND ap.dataFlag=1','left') + + ->field('adId,adName,adPositionId,adURL,adStartDate,adEndDate,adPositionId,adFile,adClickNum,ap.positionName,a.adSort') + + ->where($where)->order('adId desc') + + ->order('adSort','asc') + + ->paginate(input('limit/d')); + + } + + public function getById($id){ + + return $this->get(['adId'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + $data['adSort'] = (int)$data['adSort']; + + WSTUnset($data,'adId'); + + Db::startTrans(); + + try{ + + $result = $this->validate('ads.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + $id = $this->adId; + + //启用上传图片 + + WSTUseImages(1, $id, $data['adFile']); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $data = input('post.'); + + $data['adSort'] = (int)$data['adSort']; + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, (int)$data['adId'], $data['adFile'], 'ads-pic', 'adFile'); + + $result = $this->validate('ads.edit')->allowField(true)->save($data,['adId'=>(int)$data['adId']]); + + if(false !== $result){ + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d'); + + Db::startTrans(); + + try{ + + $result = $this->setField(['adId'=>$id,'dataFlag'=>-1]); + + WSTUnuseImage('ads','adFile',$id); + + if(false !== $result){ + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + /** + + * 修改广告排序 + + */ + + public function changeSort(){ + + $id = (int)input('id'); + + $adSort = (int)input('adSort'); + + $result = $this->setField(['adId'=>$id,'adSort'=>$adSort]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/Alipays.php b/hyhproject/admin/model/Alipays.php new file mode 100755 index 0000000..4a71e9f --- /dev/null +++ b/hyhproject/admin/model/Alipays.php @@ -0,0 +1,69 @@ +<?php +namespace wstmart\admin\model; +use think\Loader; +use think\Db; +use Env; +use wstmart\common\model\Payments as M; +/** + * ============================================================================ + * 阿里支付控制器 + */ +class Alipays extends Base{ + + /** + * 退款 + */ + public function orderRefund($refund,$order){ + + $content = input('post.content'); + $refundId = (int)input('post.id'); + $request_no = $order['orderNo'].$order['userId']; + $backMoney = $refund["backMoney"]; + $tradeNo = $order['tradeNo']; + $refund_reason = "订单【".$order['orderNo']."】退款"; + + require Env::get('root_path') . 'extend/alipay/aop/AopClient.php'; + require Env::get('root_path') . 'extend/alipay/aop/request/AlipayTradeRefundRequest.php'; + $m = new M(); + $payment = $m->getPayment("alipays"); + $aop = new \AopClient (); + $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do'; + $aop->appId = $payment["appId"]; + $aop->rsaPrivateKey = $payment["rsaPrivateKey"]; + $aop->alipayrsaPublicKey=$payment["alipayrsaPublicKey"]; + $aop->apiVersion = '1.0'; + $aop->signType = 'RSA2'; + $aop->postCharset='UTF-8'; + $aop->format='json'; + $request = new \AlipayTradeRefundRequest (); + + $request->setBizContent("{" . + "\"trade_no\":\"$tradeNo\"," . + "\"refund_amount\":\"$backMoney\"," . + "\"refund_reason\":\"$refund_reason\"," . + "\"out_request_no\":\"$request_no\"" . + " }"); + + $result = $aop->execute ( $request); + + $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; + $resultCode = $result->$responseNode->code; + if(!empty($resultCode) && $resultCode == 10000){ + if($result->$responseNode->fund_change=="Y"){ + $obj = array(); + $obj['refundTradeNo'] = $request_no;//退款单号 + $obj['content'] = $content; + $obj['refundId'] = $refundId; + $rs = model('admin/OrderRefunds')->complateOrderRefund($obj); + if($rs['status']==1){ + return WSTReturn("退款成功",1); + }else{ + return WSTReturn("退款失败",1); + } + } + } else { + $msg = $result->$responseNode->sub_msg; + return WSTReturn($msg,-1); + } + } +} diff --git a/hyhproject/admin/model/Areas.php b/hyhproject/admin/model/Areas.php new file mode 100755 index 0000000..db37f8c --- /dev/null +++ b/hyhproject/admin/model/Areas.php @@ -0,0 +1,169 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 地区业务处理 + */ +class Areas extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $parentId = input('get.parentId/d',0); + return $this->where(['dataFlag'=>1,'parentId'=>$parentId])->order('areaId desc')->paginate(input('post.limit/d')); + } + + /** + * 获取指定对象 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'areaId'=>$id]); + } + + /** + * 获取地区 + */ + public function getFieldsById($id,$fileds){ + return $this->where(['dataFlag'=>1,'areaId'=>$id])->field($fileds)->find(); + } + + /** + * 显示是否显示/隐藏 + */ + public function editiIsShow(){ + //获取子集 + $ids = array(); + $ids[] = input('post.id/d',0); + $ids = $this->getChild($ids,$ids); + $isShow = input('post.isShow/d',0)?0:1; + $result = $this->where("areaId in(".implode(',',$ids).")")->update(['isShow' => $isShow]); + if(false !== $result){ + return WSTReturn("操作成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 迭代获取下级 + */ + public function getChild($ids = array(),$pids = array()){ + $result = $this->where("dataFlag=1 and parentId in(".implode(',',$pids).")")->select(); + if(count($result)>0){ + $cids = array(); + foreach ($result as $key =>$v){ + $cids[] = $v['areaId']; + } + $ids = array_merge($ids,$cids); + return $this->getChild($ids,$cids); + }else{ + return $ids; + } + } + + /** + * 根据子分类获取其父级分类 + */ + public function getParentIs($id,$data = array()){ + $data[] = $id; + $parentId = $this->where('areaId',$id)->value('parentId'); + if($parentId==0){ + krsort($data); + return $data; + }else{ + return $this->getParentIs($parentId, $data); + } + } + + /** + * 获取自己以及父级的地区名称 + */ + public function getParentNames($id,$data = array()){ + $areas = $this->where('areaId',$id)->field('parentId,areaName')->find(); + $data[] = $areas['areaName']; + if((int)$areas['parentId']==0){ + krsort($data); + return $data; + }else{ + return $this->getParentNames((int)$areas['parentId'], $data); + } + } + + + /** + * 排序字母 + */ + public function letterObtain(){ + $areaName = input('code'); + if($areaName =='')return WSTReturn("", 1); + $areaName = WSTGetFirstCharter($areaName); + if($areaName){ + return WSTReturn($areaName, 1); + }else{ + return WSTReturn("", 1); + } + } + + /** + * 新增 + */ + public function add(){ + $areaType = 0; + $parentId = input('post.parentId/d',0); + if($parentId>0){ + $prs = $this->getFieldsById($parentId,['areaType']); + $areaType = $prs['areaType']+1; + } + $data = input('post.'); + WSTUnset($data,'areaId,dataFlag'); + $data['areaType'] = $areaType; + $data['createTime'] = date('Y-m-d H:i:s'); + $result = $this->validate('Areas.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 编辑 + */ + public function edit(){ + $areaId = input('post.areaId/d'); + $result = $this->validate('Areas.edit')->allowField(['areaName','isShow','areaSort','areaKey'])->save(input('post.'),['areaId'=>$areaId]); + $ids = array(); + $ids[] = $areaId; + $ids = $this->getChild($ids,$ids); + $this->where("areaId in(".implode(',',$ids).")")->update(['isShow' => input('post.')['isShow']]); + if(false !== $result){ + return WSTReturn("修改成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 删除 + */ + public function del(){ + $ids = array(); + $ids[] = input('post.id/d'); + $ids = $this->getChild($ids,$ids); + $data = []; + $data['dataFlag'] = -1; + $result = $this->where("areaId in(".implode(',',$ids).")")->update($data); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 获取地区列表 + */ + public function listQuery($parentId){ + return $this->where(['dataFlag'=>1,'parentId'=>$parentId,'isShow'=>1])->field('areaId,areaName,parentId')->order('areaSort desc')->select(); + } +} \ No newline at end of file diff --git a/hyhproject/admin/model/ArticleCats.php b/hyhproject/admin/model/ArticleCats.php new file mode 100755 index 0000000..d3cfa65 --- /dev/null +++ b/hyhproject/admin/model/ArticleCats.php @@ -0,0 +1,337 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 文章分类业务处理 + + */ + +use think\Db; + +class ArticleCats extends Base{ + + /** + + * 获取树形分类 + + */ + + public function pageQuery(){ + + $parentId = input('catId/d',0); + + $data = $this->where(['dataFlag'=>1,'parentId'=>$parentId])->order('catId desc')->paginate(1000)->toArray(); + + return $data; + + } + + /** + + * 获取列表 + + */ + + public function listQuery($parentId){ + + $rs = $this->where(['dataFlag'=>1,'parentId'=>$parentId])->order('catSort asc,catName asc')->select(); + + if(count($rs)>0){ + + foreach ($rs as $key => $v){ + + $rs[$key]['childrenurl'] = url('admin/articlecats/listQuery',array('parentId'=>$v['catId'])); + + $rs[$key]['children'] = []; + + $rs[$key]['isextend'] = false; + + } + + } + + return $rs; + + } + + /** + + * 获取指定对象 + + */ + + public function getById($id){ + + return $this->get(['dataFlag'=>1,'catId'=>$id]); + + } + + + + /** + + * 获取文章分类列表 + + */ + + public function listQuery2(){ + + $id = (int)input('id'); + + return $this->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>$id])->field('catId as id,catName as name,parentId as pId, 1 as isParent')->order('catSort desc')->select(); + + } + + /** + + * 修改分类名称 + + */ + + public function editName(){ + + if(input('catName')=='')return WSTReturn("操作失败,商品分类名称不能为空"); + + $id = (int)input('id'); + + $result = $this->where("catId = ".$id)->update(['catName' => input('catName')]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + + + } + + + + /** + + * 显示是否显示/隐藏 + + */ + + public function editiIsShow(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + $isShow = input('post.isShow/d')?1:0; + + $result = $this->where("catId in(".implode(',',$ids).")")->update(['isShow' => $isShow]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 迭代获取下级 + + * 获取一个分类下的所有子级分类id + + */ + + public function getChild($pid=1){ + + $data = $this->where("dataFlag=1")->select(); + + //获取该分类id下的所有子级分类id + + $ids = $this->_getChild($data, $pid, true);//每次调用都清空一次数组 + + //把自己也放进来 + + array_unshift($ids, $pid); + + return $ids; + + } + + public function _getChild($data, $pid, $isClear=false){ + + static $ids = array(); + + if($isClear)//是否清空数组 + + $ids = array(); + + foreach($data as $k=>$v) + + { + + if($v['parentId']==$pid && $v['dataFlag']==1) + + { + + $ids[] = $v['catId'];//将找到的下级分类id放入静态数组 + + //再找下当前id是否还存在下级id + + $this->_getChild($data, $v['catId']); + + } + + } + + return $ids; + + } + + + + /** + + * 新增 + + */ + + public function add(){ + + $parentId = input('post.parentId/d'); + + $data = input('post.'); + + WSTUnset($data,'catId,catType,dataFlag'); + + $data['parentId'] = $parentId; + + $data['createTime'] = date('Y-m-d H:i:s'); + + $result = $this->validate('ArticleCats.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 编辑 + + */ + + public function edit(){ + + $catId = input('post.id/d'); + + $result = $this->validate('ArticleCats.edit')->allowField(['catName','isShow','catSort'])->save(input('post.'),['catId'=>$catId]); + + $ids = array(); + + $ids = $this->getChild($catId); + + $this->where("catId in(".implode(',',$ids).")")->update(['isShow' => input('post.')['isShow']]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("修改成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 删除 + + */ + + public function del(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + $data = []; + + $data['dataFlag'] = -1; + + $rs = $this->getById($id); + + if($rs['catType']==1){ + + return WSTReturn("不能删除该分类", -1); + + }else{ + + Db::startTrans(); + + try{ + + $result = $this->where("catId in(".implode(',',$ids).")")->update($data); + + if(false !==$result){ + + WSTClearAllCache(); + + Db::name('articles')->where(['catId'=>['in',$ids]])->update(['dataFlag'=>-1]); + + } + + Db::commit(); + + return WSTReturn("删除成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/Articles.php b/hyhproject/admin/model/Articles.php new file mode 100755 index 0000000..9f9737b --- /dev/null +++ b/hyhproject/admin/model/Articles.php @@ -0,0 +1,349 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 文章业务处理 + + */ + +class Articles extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $key = input('key'); + + $catId = (int)input('catId'); + + $sort = input('sort'); + + $catIds = []; + + if($catId>0){ + + $catIds = model('ArticleCats')->getChild($catId); + + } + + $where = []; + + $where['a.dataFlag'] = 1; + + if(count($catIds)>0)$where['a.catId'] = ['in',$catIds]; + + if($key!='')$where['a.articleTitle'] = ['like','%'.$key.'%']; + + $order = 'a.articleId desc'; + + if($sort){ + + $sort = str_replace('.',' ',$sort); + + $order = $sort; + + } + + $page = Db::name('articles')->alias('a') + + ->join('__ARTICLE_CATS__ ac','a.catId= ac.catId','left') + + ->join('__STAFFS__ s','a.staffId= s.staffId','left') + + ->where($where) + + ->field('a.articleId,a.catId,a.articleTitle,a.isShow,a.articleContent,a.articleKey,a.createTime,ac.catName,s.staffName') + + ->order($order) + + ->paginate(input('post.limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + + foreach ($page['Rows'] as $key => $v){ + + $page['Rows'][$key]['articleContent'] = strip_tags(htmlspecialchars_decode($v['articleContent'])); + + } + + } + + return $page; + + } + + + + /** + + * 显示是否显示/隐藏 + + */ + + public function editiIsShow(){ + + $id = input('post.id/d'); + + $isShow = (input('post.isShow/d')==1)?1:0; + + $result = $this->where(['articleId'=>$id])->update(['isShow' => $isShow]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 获取指定对象 + + */ + + public function getById($id){ + + $single = $this->where(['articleId'=>$id,'dataFlag'=>1])->find(); + + $singlec = Db::name('article_cats')->where(['catId'=>$single['catId'],'dataFlag'=>1])->field('catName')->find(); + + $single['catName']=$singlec['catName']; + + $single['articleContent'] = htmlspecialchars_decode($single['articleContent']); + + return $single; + + } + + + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + WSTUnset($data,'articleId,dataFlag'); + + $data["staffId"] = (int)session('WST_STAFF.staffId'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + Db::startTrans(); + + try{ + + $result = $this->validate('Articles.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + // 预览图 + + WSTUseImages(1, $this->articleId, $data['coverImg']); + + //文章描述图片 + + WSTEditorImageRocord(1, $this->articleId, '',$data['articleContent']); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 编辑 + + */ + + public function edit(){ + + $articleId = input('post.id/d'); + + $data = input('post.'); + + WSTUnset($data,'articleId,dataFlag,createTime'); + + $data["staffId"] = (int)session('WST_STAFF.staffId'); + + Db::startTrans(); + + try{ + + // 预览图 + + WSTUseImages(0, $articleId, $data['coverImg'],'articles','coverImg'); + + //文章描述图片 + + $oldArticleContent = $this->where('articleId',$articleId)->value('articleContent');// 旧描述 + + WSTEditorImageRocord(1, $articleId, $oldArticleContent,$data['articleContent']); + + $result = $this->validate('Articles.edit')->allowField(true)->save($data,['articleId'=>$articleId]); + + if(false !== $result){ + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("修改成功", 1); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.id/d'); + + $data = []; + + $data['dataFlag'] = -1; + + Db::startTrans(); + + try{ + + $result = $this->where(['articleId'=>$id])->update($data); + + if(false !== $result){ + + WSTClearAllCache(); + + // 预览图 + + WSTUnuseImage('articles','coverImg',$id); + + //文章描述图片 + + $oldArticleContent = $this->where('articleId',$id)->value('articleContent');// 旧描述 + + WSTEditorImageRocord(1, $id, $oldArticleContent,''); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + /** + + * 批量删除 + + */ + + public function delByBatch(){ + + $ids = input('post.ids'); + + $data = []; + + $data['dataFlag'] = -1; + + Db::startTrans(); + + try{ + + $result = $this->where(['articleId'=>['in',$ids]])->update($data); + + if(false !== $result){ + + $oldArticleContent = $this->field('articleId,articleContent')->where(['articleId'=>['in',$ids]])->select();// 旧描述 + + foreach($oldArticleContent as $k=>$v){ + + // 预览图 + + WSTUnuseImage('articles','coverImg',$v['articleId']); + + //文章描述图片 + + WSTEditorImageRocord(1, $v['articleId'], $v['articleContent'],''); + + } + + WSTClearAllCache(); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/Attributes.php b/hyhproject/admin/model/Attributes.php new file mode 100755 index 0000000..ab908b6 --- /dev/null +++ b/hyhproject/admin/model/Attributes.php @@ -0,0 +1,132 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 规格业务处理 + */ +class Attributes extends Base{ + + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + WSTUnset($data, 'attrId,dataFlag'); + $data['createTime'] = date('Y-m-d H:i:s'); + $data['attrVal'] = str_replace(',',',',$data['attrVal']); + $data["dataFlag"] = 1; + $data["attrSort"] = (int)$data["attrSort"]; + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + krsort($goodsCats); + if(!empty($goodsCats))$data['goodsCatPath'] = implode('_',$goodsCats)."_"; + $result = $this->validate('Attributes.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $attrId = input('post.attrId/d'); + $data = input('post.'); + $data["attrSort"] = (int)$data["attrSort"]; + WSTUnset($data, 'attrId,dataFlag,createTime'); + $data['attrVal'] = str_replace(',',',',$data['attrVal']); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + krsort($goodsCats); + if(!empty($goodsCats))$data['goodsCatPath'] = implode('_',$goodsCats)."_"; + $result = $this->validate('Attributes.edit')->allowField(true)->save($data,['attrId'=>$attrId]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $attrId = input('post.attrId/d'); + $data["dataFlag"] = -1; + $result = $this->save($data,['attrId'=>$attrId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * + * 根据ID获取 + */ + public function getById($attrId){ + $obj = null; + if($attrId>0){ + $obj = $this->get(['attrId'=>$attrId,'dataFlag'=>1]); + }else{ + $obj = self::getEModel("attributes"); + } + return $obj; + } + + /** + * 显示隐藏 + */ + public function setToggle(){ + $attrId = input('post.attrId/d'); + $isShow = input('post.isShow/d'); + $result = $this->where(['attrId'=>$attrId,"dataFlag"=>1])->setField("isShow", $isShow); + if(false !== $result){ + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 分页 + */ + public function pageQuery(){ + $keyName = input('keyName'); + $goodsCatPath = input('goodsCatPath'); + $dbo = $this->field(true); + $map = array(); + $map['dataFlag'] = 1; + if($keyName!="")$map['attrName'] = ["like","%".$keyName."%"]; + if($goodsCatPath!='')$map['goodsCatPath'] = ["like",$goodsCatPath."_%"]; + $page = $dbo->field(true)->where($map)->paginate(input('limit/d'))->toArray(); + if(count($page['Rows'])>0){ + $keyCats = model('GoodsCats')->listKeyAll(); + foreach ($page['Rows'] as $key => $v){ + $goodsCatPath = $page['Rows'][$key]['goodsCatPath']; + $page['Rows'][$key]['goodsCatNames'] = self::getGoodsCatNames($goodsCatPath,$keyCats); + $page['Rows'][$key]['children'] = []; + $page['Rows'][$key]['isextend'] = false; + } + } + return $page; + } + + public function getGoodsCatNames($goodsCatPath, $keyCats){ + $catIds = explode("_",$goodsCatPath); + $catNames = array(); + for($i=0,$k=count($catIds);$i<$k;$i++){ + if($catIds[$i]=='')continue; + if(isset($keyCats[$catIds[$i]]))$catNames[] = $keyCats[$catIds[$i]]; + } + return implode("→",$catNames); + } + + /** + * 列表 + */ + public function listQuery(){ + $catId = input("post.catId/d"); + $rs = $this->field("attrId id, attrId, catId, attrName name, '' goodsCatNames")->where(["dataFlag"=>1,"catId"=>$catId])->sort('attrSort asc,attrId asc')->select(); + return $rs; + } +} diff --git a/hyhproject/admin/model/Banks.php b/hyhproject/admin/model/Banks.php new file mode 100755 index 0000000..59ff7ca --- /dev/null +++ b/hyhproject/admin/model/Banks.php @@ -0,0 +1,67 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 银行业务处理 + */ +class Banks extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + return $this->where('dataFlag',1)->field('bankId,bankName')->order('bankId desc')->paginate(input('limit/d')); + } + public function getById($id){ + return $this->get(['bankId'=>$id,'dataFlag'=>1]); + } + /** + * 列表 + */ + public function listQuery(){ + return $this->where('dataFlag',1)->field('bankId,bankName')->select(); + } + /** + * 新增 + */ + public function add(){ + $data = ['bankName'=>input('post.bankName'), + 'createTime'=>date('Y-m-d H:i:s'),]; + $result = $this->validate('Banks.add')->allowField(['bankName','createTime'])->save($data); + if(false !== $result){ + cache('WST_BANKS',null); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $bankId = input('post.bankId/d',0); + $result = $this->validate('Banks.edit')->allowField(['bankName'])->save(['bankName'=>input('post.bankName')],['bankId'=>$bankId]); + + if(false !== $result){ + cache('WST_BANKS',null); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d',0); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['bankId'=>$id]); + if(false !== $result){ + cache('WST_BANKS',null); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/Base.php b/hyhproject/admin/model/Base.php new file mode 100755 index 0000000..9ac7ab9 --- /dev/null +++ b/hyhproject/admin/model/Base.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 基础控业务处理 + */ +use think\Model; +use think\Db; +class Base extends Model { + /** + * 获取空模型 + */ + public function getEModel($tables){ + $rs = Db::query('show columns FROM `'.config('database.prefix').$tables."`"); + $obj = []; + if($rs){ + foreach($rs as $key => $v) { + $obj[$v['Field']] = $v['Default']; + if($v['Key'] == 'PRI')$obj[$v['Field']] = 0; + } + } + return $obj; + } +} \ No newline at end of file diff --git a/hyhproject/admin/model/Brands.php b/hyhproject/admin/model/Brands.php new file mode 100755 index 0000000..c8ccdb5 --- /dev/null +++ b/hyhproject/admin/model/Brands.php @@ -0,0 +1,407 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 品牌业务处理 + + */ + +class Brands extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $key = input('key'); + + $id = input('id/d'); + + $where = []; + + $where['b.dataFlag'] = 1; + + if($key!='')$where['b.brandName'] = ['like','%'.$key.'%']; + + if($id>0)$where['gcb.catId'] = $id; + + $total = Db::name('brands')->alias('b'); + + if($id>0){ + + $total->join('__CAT_BRANDS__ gcb','b.brandId = gcb.brandId','left'); + + } + + $page = $total->where($where) + + ->join('shops s','s.shopId=b.shopId','left') + + ->join('cat_brands cb','cb.brandId=b.brandId','left') + + ->join('goods_cats gc','gc.catId=cb.catId','left') + + ->where('b.dataFlag=1 and s.dataFlag=1 and s.shopStatus=1') + + ->field('b.brandId,b.brandName,b.brandImg,b.brandDesc,b.sortNo,s.shopName,gc.catName') + + ->order('b.brandId', 'desc') + + ->group('b.brandId') + + ->paginate(input('post.limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + + foreach ($page['Rows'] as $key => $v){ + + $page['Rows'][$key]['brandDesc'] = strip_tags(htmlspecialchars_decode($v['brandDesc'])); + + } + + } + + return $page; + + } + + + + /** + + * 获取指定对象 + + */ + + public function getById($id){ + + $result = $this->where(['brandId'=>$id])->find(); + + //获取关联的分类 + + $result['catIds'] = Db::name('cat_brands')->where(['brandId'=>$id])->column('catId'); + + return $result; + + } + + + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $shop=db('shops')->where(['shopId'=>$data['shopId'],'dataFlag'=>1,'shopStatus'=>1])->find(); + + if(!$shop) return WSTReturn('无效的店铺,请重新输入'); + + WSTUnset($data,'brandId,dataFlag'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + $idsStr = explode(',',$data['catId']); + + if($idsStr!=''){ + + foreach ($idsStr as $v){ + + if((int)$v>0)$ids[] = (int)$v; + + } + + } + + Db::startTrans(); + + try{ + + $result = $this->validate('Brands.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + //启用上传图片 + + WSTUseImages(1, $this->brandId, $data['brandImg']); + + //商品描述图片 + + WSTEditorImageRocord(1, $this->brandId, '',$data['brandDesc']); + + foreach ($ids as $key =>$v){ + + $d = array(); + + $d['catId'] = $v; + + $d['brandId'] = $this->brandId; + + Db::name('cat_brands')->insert($d); + + } + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + + + /** + + * 编辑 + + */ + + public function edit(){ + + $brandId = input('post.id/d'); + + $data = input('post.'); + + $idsStr = explode(',',$data['catId']); + + if($idsStr!=''){ + + foreach ($idsStr as $v){ + + if((int)$v>0)$ids[] = (int)$v; + + } + + } + + $filter = array(); + + //获取品牌的关联分类 + + $catBrands = Db::name('cat_brands')->where(['brandId'=>$brandId])->select(); + + foreach ($catBrands as $key =>$v){ + + if(!in_array($v['catId'],$ids))$filter[] = $v['catId']; + + } + + Db::startTrans(); + + try{ + + WSTUseImages(1, $brandId, $data['brandImg'], 'brands', 'brandImg'); + + // 品牌描述图片 + + $desc = $this->where('brandId',$brandId)->value('brandDesc'); + + WSTEditorImageRocord(1, $brandId, $desc, $data['brandDesc']); + + $result = $this->validate('Brands.edit')->allowField(['brandName','brandImg','brandDesc','sortNo','shopId'])->save(input('post.'),['brandId'=>$brandId]);//添加shopId mark cheng 20180207 + + if(false !== $result){ + + WSTClearAllCache(); + + foreach ($catBrands as $key =>$v){ + + Db::name('cat_brands')->where('brandId',$brandId)->delete(); + + } + + foreach ($ids as $key =>$v){ + + $d = array(); + + $d['catId'] = $v; + + $d['brandId'] = $brandId; + + Db::name('cat_brands')->insert($d); + + } + + Db::commit(); + + return WSTReturn("修改成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('修改失败',-1); + + } + + + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.id/d'); + + $data = []; + + $data['dataFlag'] = -1; + + Db::startTrans(); + + try{ + + $result = $this->where(['brandId'=>$id])->update($data); + + WSTUnuseImage('brands','brandImg',$id); + + // 品牌描述图片 + + $desc = $this->where('brandId',$id)->value('brandDesc'); + + WSTEditorImageRocord(1, $id, $desc,''); + + if(false !== $result){ + + WSTClearAllCache(); + + //删除推荐品牌 + + Db::name('recommends')->where(['dataSrc'=>2,'dataId'=>$id])->delete(); + + //删除品牌和分类的关系 + + Db::name('cat_brands')->where(['brandId'=>$id])->delete(); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('删除失败',-1); + + } + + + + /** + + * 获取品牌 + + */ + + public function searchBrands(){ + + $goodsCatatId = (int)input('post.goodsCatId'); + + if($goodsCatatId<=0)return []; + + $key = input('post.key'); + + $where = []; + + $where['dataFlag'] = 1; + + $where['catId'] = $goodsCatatId; + + if($key!='')$where['brandName'] = ['like','%'.$key.'%']; + + return $this->alias('s')->join('__CAT_BRANDS__ cb','s.brandId=cb.brandId','inner') + + ->where($where)->field('brandName,s.brandId')->select(); + + } + + /** + + * 排序字母 + + */ + + public function letterObtain(){ + + $areaName = input('code'); + + if($areaName =='')return WSTReturn("", 1); + + $areaName = WSTGetFirstCharter($areaName); + + if($areaName){ + + return WSTReturn($areaName, 1); + + }else{ + + return WSTReturn("", 1); + + } + + } + + + + /** + + * 修改品牌排序 + + */ + + public function changeSort(){ + + $id = (int)input('id'); + + $sortNo = (int)input('sortNo'); + + $result = $this->setField(['brandId'=>$id,'sortNo'=>$sortNo]); + + if(false !== $result){ + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/Carts.php b/hyhproject/admin/model/Carts.php new file mode 100755 index 0000000..64ce4b8 --- /dev/null +++ b/hyhproject/admin/model/Carts.php @@ -0,0 +1,158 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 商品类 + */ +class Carts extends Base{ + /** + * 购物车列表 + */ + public function cartsByPage(){ + $shopName=input('shopName'); + $loginName=input('loginName'); + $goodsName=input('goodsName'); + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + if($shopName!="")$where['shopName']=['like',"%$shopName%"]; + if($loginName!="")$where['loginName']=['like',"%$loginName%"]; + if($goodsName!="")$where['goodsName']=['like',"%$goodsName%"]; + $result=$this->alias('c') + ->join('__USERS__ u','u.userId=c.userId','left') + ->join('__GOODS__ g','g.goodsId=c.goodsId','left') + ->join('__SHOPS__ s','s.shopId=g.shopId','left') + ->where($where) + ->field('u.loginName,shopPrice,sum(cartNum)cartNum,goodsName,shopName,goodsImg,goodsCatIdPath,g.goodsId') + ->order('cartNum desc') + ->group('u.userId,g.goodsId') + ->paginate(input('limit/d'))->toArray(); + $keyCats = model('GoodsCats')->listKeyAll(); + foreach ($result['Rows'] as $key => $v){ + $result['Rows'][$key]['totalPrice']=$v['cartNum']*$v['shopPrice']; + $result['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + return $result; + } + public function getGoodsCatNames($goodsCatPath, $keyCats){ + $catIds = explode("_",$goodsCatPath); + $catNames = array(); + for($i=0,$k=count($catIds);$i<$k;$i++){ + if($catIds[$i]=='')continue; + if(isset($keyCats[$catIds[$i]]))$catNames[] = $keyCats[$catIds[$i]]; + } + return implode("→",$catNames); + } + //导出数据 + public function toExport(){ + $name='购物车数据'; + $shopName=input('shopName'); + $loginName=input('loginName'); + $goodsName=input('goodsName'); + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + if($shopName!="")$where['shopName']=['like',"%$shopName%"]; + if($loginName!="")$where['loginName']=['like',"%$loginName%"]; + if($goodsName!="")$where['goodsName']=['like',"%$goodsName%"]; + $page=$this->alias('c') + ->join('__USERS__ u','u.userId=c.userId','left') + ->join('__GOODS__ g','g.goodsId=c.goodsId','left') + ->join('__SHOPS__ s','s.shopId=g.shopId','left') + ->where($where) + ->field('u.loginName,shopPrice,sum(cartNum)cartNum,goodsName,shopName,goodsImg,goodsCatIdPath,g.goodsId') + ->order('cartNum desc') + ->group('u.userId,g.goodsId') + ->select(); + // dump($page); + $keyCats = model('GoodsCats')->listKeyAll(); + foreach ($page as $key => $v){ + $page[$key]['totalPrice']=$v['cartNum']*$v['shopPrice']; + $page[$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(55); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(40); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '用户名称') + ->setCellValue('B1', '商品名称') + ->setCellValue('C1', '购物车数量') + ->setCellValue('D1', '单品价格') + ->setCellValue('E1', '总价') + ->setCellValue('F1', '所属店铺') + ->setCellValue('G1', '所属分类'); + $objPHPExcel->getActiveSheet()->getStyle('A1:G1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['loginName']) + ->setCellValue('B'.$i, $page[$row]['goodsName']) + ->setCellValue('C'.$i, $page[$row]['cartNum']) + ->setCellValue('D'.$i, $page[$row]['shopPrice']) + ->setCellValue('E'.$i, $page[$row]['totalPrice']) + ->setCellValue('F'.$i, $page[$row]['shopName']) + ->setCellValue('G'.$i, $page[$row]['goodsCatName']); + + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/CashDraws.php b/hyhproject/admin/model/CashDraws.php new file mode 100755 index 0000000..82747f8 --- /dev/null +++ b/hyhproject/admin/model/CashDraws.php @@ -0,0 +1,771 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +use think\Loader; + +/** + + * ============================================================================ + + * 提现分类业务处理 + + */ + +class CashDraws extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $targetType = input('targetType',-1); + + $cashNo = input('cashNo'); + + $cashSatus = input('cashSatus',-1); + + $where = []; + + if(in_array($targetType,[0,1]))$where['targetType'] = $targetType; + + if(in_array($cashSatus,[0,1]))$where['cashSatus'] = $cashSatus; + + if($cashNo!='')$where['cashNo'] = ['like','%'.$cashNo.'%']; + + + + $sort = input('sort'); + + $order = []; + + if($sort!=''){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + if($sortArr[0]=='cashNo'){ + + $order = $sortArr[0].'+0 '.$sortArr[1]; + + } + + } + + //mark by cheng 只显示超过一天的提现数据 + + //$page = $this->where($where)->whereTime('createTime','<=', date('Y-m-d'))->order($order)->order('createTime desc')->paginate(input('limit/d'))->toArray(); + $page = $this->where($where)->order($order)->order('createTime desc')->paginate(input('limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + + $userIds = []; + + $shopIds = []; + + foreach ($page['Rows'] as $key => $v) { + + if($v['targetType']==0)$userIds[] = $v['targetId']; + + if($v['targetType']==1)$shopIds[] = $v['targetId']; + + } + + $userMap = []; + + if(count($userIds)>0){ + + $user = Db::name('users')->where(['userId'=>['in',$userIds]])->field('userId,loginName,userName')->select(); + + foreach ($user as $key => $v) { + + $userMap["0_".$v['userId']] = $v; + + } + + } + + if(count($shopIds)>0){ + + $user = Db::name('shops')->alias('s') + + ->join('__USERS__ u','u.userId=s.userId') + + ->where(['shopId'=>['in',$shopIds]]) + + ->field('s.shopId,u.loginName,s.shopName as userName') + + ->select(); + + foreach ($user as $key => $v) { + + $userMap["1_".$v['shopId']] = $v; + + } + + } + + foreach ($page['Rows'] as $key => $v) { + + $page['Rows'][$key]['loginName'] = $userMap[$v['targetType']."_".$v['targetId']]['loginName']; + + $page['Rows'][$key]['userName'] = $userMap[$v['targetType']."_".$v['targetId']]['userName']; + + } + + } + + return $page; + + } + /** + * 查看报表 + * @return [type] [description] + */ + public function viewReport($date,$isSave=0){ + + $orders['list'] = Db::name('orders') + ->where('orderStatus=2 AND dataFlag=1') + ->whereTime('receiveTime',[$date,date('Y-m-d',strtotime('+1 day',strtotime($date)))]) + ->field('orderId,shopId,userId,productTaxFee,productHandlingFee,couponsHandlingFee,couponsTaxFee,realTotalMoney,receiveTime,payable') + ->select(); + //dump(Db::getlastsql()); + $discountMoney = 0; + $m = Model('common/Table'); + $orders['allPaySum']=0;//消费总额 + $orders['coupousEarningsSum'] = 0;//优惠款总收益 + $orders['hasVouchersEearningsSum'] = 0;//已获券总收益 + $orders['taxFeeSum'] = 0;//税费总收益 + $orders['collectionPaySum']=0;//公司需付商家,即商家已获旺旺券总额 + $orders['collectionGatheringSum']=0;//商家需付公司总额 + $orders['collection']=[]; + $orders['yesterdayMoney']=0; + $orders['todayMoney']=0; + $m->setTable('log_day_money'); + $orders['yesterdayMoney'] = $m->getSum('setTime < '.strtotime($date),'money'); + foreach ($orders['list'] as &$v) { + $orders['allPaySum'] += $v['realTotalMoney']; + $m->setTable('order_goods'); + $orderGoodsList = $m->getList(['orderId'=>$v['orderId']],'goodsPrice,goodsNum,freight,discountRate'); + $discountMoney = 0;//优惠款 + foreach ($orderGoodsList as &$val) { + $discountMoney += ($val['goodsPrice']*$val['goodsNum'] + $val['freight']) * ($val['discountRate']*0.01);//优惠款 + } + $v['discountMoney'] = $discountMoney; + $v['coupousEarnings'] = $discountMoney * 0.1;//优惠款收益 + $orders['coupousEarningsSum']+=$v['coupousEarnings']; + + $v['hasVouchersEearnings'] = $v['productHandlingFee'] + $v['couponsHandlingFee'];//已获券收益 + $orders['hasVouchersEearningsSum']+=$v['hasVouchersEearnings']; + + $v['taxFee'] = $v['productTaxFee']+$v['couponsTaxFee'];//税费 + $orders['taxFeeSum']+=$v['taxFee']; + + $m->setTable('shops'); + $shopUserId = $m->getField(['shopId'=>$v['shopId']],'userId'); + $m->setTable('users'); + $v['loginName'] = $m->getField(['userId'=>$v['userId']],'loginName'); + $v['shopLoginName'] = $m->getField(['userId'=>$shopUserId],'loginName'); + if(!isset($orders['collection'][$shopUserId]['gathering'])) $orders['collection'][$shopUserId]['gathering']=0; + if(!isset($orders['collection'][$shopUserId]['pay'])) $orders['collection'][$shopUserId]['pay']=0; + $orders['collection'][$shopUserId]['shopLoginName'] = $v['shopLoginName']; + + if($v['payable']>0){ + //公司需付商家,即提现 + $orders['collection'][$shopUserId]['pay']+=$v['payable'];//代付款 + $orders['collectionPaySum'] += $v['payable']; + }else{ + //商家需付公司 + $orders['collection'][$shopUserId]['gathering'] += abs($v['payable']);//代收款 + $orders['collectionGatheringSum'] += abs($v['payable']); + } + } + $allMoney = $orders['collectionGatheringSum']-($orders['coupousEarningsSum']+$orders['hasVouchersEearningsSum']+$orders['taxFeeSum']+$orders['collectionPaySum']); + $orders['todayMoney'] = $orders['yesterdayMoney'] + $allMoney; + if(1 == $isSave && $allMoney != 0){ + $data['money'] = $allMoney;//充值/扣除数量 + if($allMoney >= 0 ){ + $reTypeName = '充值'; + }else{ + $reTypeName = '扣除'; + } + $data['adminId'] = 0; + $data['logContent'] = '系统'.$reTypeName; + $data['setTime'] = time(); + $data['createTime'] = time(); + $m->setTable('log_day_money'); + $m->insertInfo($data); + echo $allMoney; + return true; + } + //$orders['collection'] = Db::name('orders')->where(); + return $orders; + } + /** + + * 获取提现详情 + + */ + + public function getById(){ + + $id = (int)input('id'); + + $rs = $this->get($id); + + $user = []; + + if($rs['targetType']==1){ + + $user = Db::name('shops')->alias('s') + + ->join('__USERS__ u','u.userId=s.userId') + + ->where('shopId',$rs['targetId']) + + ->field('s.shopId,u.loginName,s.shopName as userName') + + ->find(); + + + + }else{ + + $user = Db::name('users')->where('userId',$rs['targetId'])->field('userId,loginName,userName')->find(); + + } + + $rs['userName'] = $user['userName']; + + $rs['loginName'] = $user['loginName']; + + return $rs; + + } + + + + /** + + * 处理提现成功 + + */ + + public function handle(){ + + $id = (int)input('cashId'); + + $cash = $this->get($id); + + if(empty($cash))return WSTReturn('无效的提现申请记录'); + + Db::startTrans(); + + try{ + + + + if($cash->targetType==0){ + + $user = model('users')->get($cash->targetId); + + // if($user->lockMoney<$cash->money)return WSTReturn('操作失败,被冻结的金额小于提现金额'); + + // $user->lockMoney = $user->lockMoney-$cash->money; + + // $user->save(); + + $targetId = $user->userId; + + }else{ + + $shop = model('shops')->get($cash->targetId); + + // if($shop->lockMoney<$cash->money)return WSTReturn('操作失败,被冻结的金额小于提现金额'); + + // $shop->lockMoney = $shop->lockMoney-$cash->money; + + // $shop->save(); + + $targetId = $shop->userId; + + } + + $cash->cashSatus = 1; + + $cash->cashRemarks = input('cashRemarks'); + + $result = $cash->save(); + + + + if(false != $result){ + + //创建一条流水记录 + + $lm = []; + + $lm['targetType'] = $cash->targetType; + + $lm['targetId'] = $targetId; + + $lm['dataId'] = $id; + + $lm['dataSrc'] = 3; + + $lm['remark'] = '提现申请单【'.$cash->cashNo.'】申请提现¥'.$cash->money.'。'.(($cash->cashRemarks!='')?"【操作备注】:".$cash->cashRemarks:''); + + $lm['moneyType'] = 0; + + $lm['money'] = $cash->money; + + $lm['payType'] = 0; + + $lm['createTime'] = date('Y-m-d H:i:s'); + + model('LogMoneys')->insert($lm); + + //发送信息信息 + + $tpl = WSTMsgTemplates('CASH_DRAW_SUCCESS'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + $find = ['${CASH_NO}']; + + $replace = [$cash->cashNo]; + + WSTSendMsg($targetId,str_replace($find,$replace,$tpl['tplContent']),['from'=>5,'dataId'=>$id]); + + } + + //微信消息 + + if((int)WSTConf('CONF.wxenabled')==1){ + + $params = []; + + $params['CASH_NO'] = $cash->cashNo; + + $params['MONEY'] = $cash->money; + + $params['CASH_TYPE'] = '银行提现'; + + $params['CASH_TIME'] = $cash['createTime']; + + $params['CASH_RESULT'] = "审核通过。【备注:".((input('cashRemarks')=='')?"无":input('cashRemarks'))."】"; + + $params['EXAMINE_TIME'] = date('Y-m-d H:i:s'); + + WSTWxMessage(['CODE'=>'WX_CASH_DRAW_SUCCESS','userId'=>$targetId,'params'=>$params]); + + } + + Db::commit(); + + return WSTReturn('操作成功!',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('操作失败!',-1); + + } + + + + /** + + * 处理提现失败 + + */ + + public function handleFail(){ + + $id = (int)input('cashId'); + + $cash = $this->get($id); + + if(empty($cash))return WSTReturn('无效的提现申请记录'); + + if(input('cashRemarks')=='')return WSTReturn('请输入提现失败原因'); + + Db::startTrans(); + + try{ + + + + if($cash->targetType==0){ + + $user = model('users')->get($cash->targetId); + + if($user->lockMoney<$cash->money)return WSTReturn('操作失败,无效的冻结的金额'); + + $user->userMoney = $user->userMoney + $cash->money; + + $user->lockMoney = $user->lockMoney-$cash->money; + + $user->save(); + + $targetId = $user->userId; + + }else{ + + $shop = model('shops')->get($cash->targetId); + + if($shop->lockMoney<$cash->money)return WSTReturn('操作失败,无效的冻结的金额'); + + $shop->shopMoney = $shop->shopMoney + $cash->money; + + $shop->lockMoney = $shop->lockMoney-$cash->money; + + $shop->save(); + + $targetId = $shop->userId; + + } + + $cash->cashSatus = -1; + + $cash->cashRemarks = input('cashRemarks'); + + $result = $cash->save(); + + + + if(false != $result){ + + //发送信息信息 + + $tpl = WSTMsgTemplates('CASH_DRAW_FAIL'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + $find = ['${CASH_NO}','${CASH_RESULT}']; + + $replace = [$cash->cashNo,input('cashRemarks')]; + + WSTSendMsg($targetId,str_replace($find,$replace,$tpl['tplContent']),['from'=>5,'dataId'=>$id]); + + } + + //微信消息 + + if((int)WSTConf('CONF.wxenabled')==1){ + + $params = []; + + $params['CASH_NO'] = $cash->cashNo; + + $params['MONEY'] = $cash->money; + + $params['CASH_TYPE'] = '银行提现'; + + $params['CASH_TIME'] = $cash['createTime']; + + $params['CASH_RESULT'] = "审核不通过。【备注:".((input('cashRemarks')=='')?"无":input('cashRemarks'))."】"; + + $params['EXAMINE_TIME'] = date('Y-m-d H:i:s'); + + WSTWxMessage(['CODE'=>'WX_CASH_DRAW_FAIL','userId'=>$targetId,'params'=>$params]); + + } + + Db::commit(); + + return WSTReturn('操作成功!',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('操作失败!',-1); + + } + + /** + + * 导出提现申请 + + */ + + public function toExport(){ + + $name='提现申请表'; + + $targetType = input('targetType',-1); + + $cashNo = input('cashNo'); + + $cashSatus = input('cashSatus',-1); + + $where = []; + + if(in_array($targetType,[0,1]))$where['targetType'] = $targetType; + + if(in_array($cashSatus,[0,1]))$where['cashSatus'] = $cashSatus; + + if($cashNo!='')$where['cashNo'] = ['like','%'.$cashNo.'%']; + + // 排序 + + $sort = input('sort'); + + $order = []; + + if($sort!=''){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + if($sortArr[0]=='cashNo'){ + + $order = $sortArr[0].'+0 '.$sortArr[1]; + + } + + } + + $page = $this->where($where)->order($order)->order('createTime desc')->select(); + + if(count($page)>0){ + + $userIds = []; + + $shopIds = []; + + foreach ($page as $key => $v) { + + if($v['targetType']==0)$userIds[] = $v['targetId']; + + if($v['targetType']==1)$shopIds[] = $v['targetId']; + + } + + $userMap = []; + + if(count($userIds)>0){ + + $user = Db::name('users')->where(['userId'=>['in',$userIds]])->field('userId,loginName,userName')->select(); + + foreach ($user as $key => $v) { + + $userMap["0_".$v['userId']] = $v; + + } + + } + + if(count($shopIds)>0){ + + $user = Db::name('shops')->alias('s') + + ->join('__USERS__ u','u.userId=s.userId') + + ->where(['shopId'=>['in',$shopIds]]) + + ->field('s.shopId,u.loginName,s.shopName as userName') + + ->select(); + + foreach ($user as $key => $v) { + + $userMap["1_".$v['shopId']] = $v; + + } + + } + + foreach ($page as $key => $v) { + + $page[$key]['userType'] = ($v['targetType']==1)?"【商家】":"【会员】"; + + $page[$key]['loginName'] = $userMap[$v['targetType']."_".$v['targetId']]['loginName']; + + $page[$key]['userName'] = $userMap[$v['targetType']."_".$v['targetId']]['userName']; + + $page[$key]['cashSatus'] = ($page[$key]['cashSatus']==1)?'提现成功':(($page[$key]['cashSatus']==-1)?'提现失败':'待处理'); + + } + + } + + + + + + Loader::import('phpexcel.PHPExcel.IOFactory'); + + $objPHPExcel = new \PHPExcel(); + + // 设置excel文档的属性 + + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + + ->setLastModifiedBy("WSTMart")//最后修改人 + + ->setTitle($name)//标题 + + ->setSubject($name)//题目 + + ->setDescription($name)//描述 + + ->setKeywords("提现")//关键字 + + ->setCategory("Test result file");//种类 + + + + // 开始操作excel表 + + $objPHPExcel->setActiveSheetIndex(0); + + // 设置工作薄名称 + + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + + // 设置默认字体和大小 + + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + + $styleArray = array( + + 'font' => array( + + 'bold' => true, + + 'color'=>array( + + 'argb' => 'ffffffff', + + ) + + ), + + 'borders' => array ( + + 'outline' => array ( + + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + + ) + + ) + + ); + + //设置宽 + + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + + + + + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->getStartColor()->setARGB('333399'); + + + + $objPHPExcel->getActiveSheet()->setCellValue('A1', '提现单号') + + ->setCellValue('B1', '会员类型')->setCellValue('C1', '会员名称') + + ->setCellValue('D1', '提现银行')->setCellValue('E1', '银行卡号') + + ->setCellValue('F1', '持卡人')->setCellValue('G1', '提现金额') + + ->setCellValue('H1', '提现时间')->setCellValue('I1', '状态'); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->applyFromArray($styleArray); + + + + for ($row = 0; $row < count($page); $row++){ + + $i = $row+2; + + $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $page[$row]['cashNo']) + + ->setCellValue('B'.$i, $page[$row]['userType'])->setCellValue('C'.$i, $page[$row]['userName'].'('.$page[$row]['loginName'].')' ) + + ->setCellValue('D'.$i, $page[$row]['accTargetName'])->setCellValue('E'.$i, $page[$row]['accNo']) + + ->setCellValue('F'.$i, $page[$row]['accUser'])->setCellValue('G'.$i, '¥'.$page[$row]['money']) + + ->setCellValue('H'.$i, $page[$row]['createTime'])->setCellValue('I'.$i, $page[$row]['cashSatus']); + + } + + + + //输出EXCEL格式 + + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + + // 从浏览器直接输出$filename + + header('Content-Type:application/csv;charset=UTF-8'); + + header("Pragma: public"); + + header("Expires: 0"); + + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + + header("Content-Type:application/force-download"); + + header("Content-Type:application/vnd.ms-excel;"); + + header("Content-Type:application/octet-stream"); + + header("Content-Type:application/download"); + + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + + header("Content-Transfer-Encoding:binary"); + + $objWriter->save('php://output'); + + } + +} + diff --git a/hyhproject/admin/model/ChargeItems.php b/hyhproject/admin/model/ChargeItems.php new file mode 100755 index 0000000..e31d730 --- /dev/null +++ b/hyhproject/admin/model/ChargeItems.php @@ -0,0 +1,60 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 充值项业务处理 + */ +class ChargeItems extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $where = []; + $where['dataFlag'] = 1; + return $this->where($where)->field(true)->order('itemSort asc,id asc')->paginate(input('limit/d')); + } + public function getById($id){ + return $this->get(['id'=>$id,'dataFlag'=>1]); + } + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + $data["createTime"] = date("Y-m-d H:i:s"); + WSTUnset($data,'positionId'); + $result = $this->validate('ChargeItems.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $Id = (int)input('post.id'); + $result = $this->validate('ChargeItems.edit')->allowField(true)->save(input('post.'),['id'=>$Id]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = (int)input('post.id/d'); + $result = $this->setField(['id'=>$id,'dataFlag'=>-1]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + +} diff --git a/hyhproject/admin/model/CronJobs.php b/hyhproject/admin/model/CronJobs.php new file mode 100755 index 0000000..2c60123 --- /dev/null +++ b/hyhproject/admin/model/CronJobs.php @@ -0,0 +1,1368 @@ +<?php + + + +namespace wstmart\admin\model; + + + +use think\Db; + + + +/** + + + + * ============================================================================ + + + + * 定时业务处理 + + + + */ + + + +class CronJobs extends Base{ + + + + /** + + + + * 管理员登录触发动作 + + + + */ + + + + public function autoByAdmin(){ + + + + $this->autoCancelNoPay(); + + + + $this->autoReceive(); + + + + $this->autoAppraise(); + + + + $this->autoSendMsg(); + + + + } + + + + /** + + + + * 取消未支付订单 + + + + */ + + + + public function autoCancelNoPay(){ + + + + $autoCancelNoPayDays = (int)WSTConf('CONF.autoCancelNoPayDays'); + + + $autoCancelNoPayDays = ($autoCancelNoPayDays>0)?$autoCancelNoPayDays:6; + + + + $lastDay = date("Y-m-d H:i:s",strtotime("-".$autoCancelNoPayDays." hours")); + + + + $orders = Db::name('orders')->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left')->where("o.createTime<'".$lastDay."' and o.orderStatus=-2 and o.dataFlag=1 and o.payType=1 and o.isPay=0")->field("o.orderId,o.orderNo,o.userId,o.shopId,o.useScore,s.userId shopUserId,orderCode")->select(); + + + + if(!empty($orders)){ + + + + $prefix = config('database.prefix'); + + + + $orderIds = []; + + + + foreach ($orders as $okey => $order){ + + + + $orderIds[] = $order['orderId']; + + + + } + + + + Db::startTrans(); + + + + try{ + + + + //提前锁定订单 + + + + Db::name('orders')->where(['orderId'=>['in',$orderIds]])->update(['orderStatus'=>-1]); + + + + foreach ($orders as $okey => $order){ + + + + $shopId = $order['shopId']; + + + + //未付款状态则直接退回积分 + + + + if($order['useScore']>0){ + + + + $score = []; + + + + $score['userId'] = $order['userId']; + + + + $score['score'] = $order['useScore']; + + + + $score['dataSrc'] = 1; + + + + $score['dataId'] = $order['orderId']; + + + + $score['dataRemarks'] = "取消交易订单【".$order['orderNo']."】,退回积分".$order['useScore']."个"; + + + + $score['scoreType'] = 1; + + + + model('common/UserScores')->add($score); + + + + } + + + + $goods = Db::name('order_goods')->alias('og')->join('__GOODS__ g','og.goodsId=g.goodsId','inner') + + + + ->where('orderId',$order['orderId'])->field('og.*,g.isSpec')->select(); + + + + foreach ($goods as $k => $v){ + + + + //处理虚拟产品 + + + + if($v['goodsType']==1){ + + + + $extraJson = json_decode($v['extraJson'],true); + + + + foreach ($extraJson as $ecard) { + + + + Db::name('goods_virtuals')->where('id',$ecard['cardId'])->update(['orderId'=>0,'orderNo'=>'','isUse'=>0]); + + + + } + + + + $counts = Db::name('goods_virtuals')->where(['dataFlag'=>1,'goodsId'=>$v['goodsId'],'isUse'=>0])->count(); + + + + Db::name('goods')->where('goodsId',$v['goodsId'])->update(['goodsStock'=>$counts]); + + + + }else{ + + + + //只有正常下单的才会修改库存的,其他的任何插件都不会修改库存 + + + + if($order['orderCode'] == 'order'){ + + + + //修改库存 + + + + if($v['isSpec']>0){ + + + + Db::name('goods_specs')->where('id',$v['goodsSpecId'])->setInc('specStock',$v['goodsNum']); + + + + } + + + + Db::name('goods')->where('goodsId',$v['goodsId'])->setInc('goodsStock',$v['goodsNum']); + + + + //Db::name('goods')->where('goodsId',$v['goodsId'])->setDec('saleNum',$v['goodsNum']);//减少销量 mark 20180412 + + + + + + + + } + + + + } + + + + } + + + + //新增订单日志 + + + + $logOrder = []; + + + + $logOrder['orderId'] = $order['orderId']; + + + + $logOrder['orderStatus'] = -1; + + + + $logOrder['logContent'] = "订单长时间未支付,系统自动取消订单"; + + + + $logOrder['logUserId'] = $order['userId']; + + + + $logOrder['logType'] = 0; + + + + $logOrder['logTime'] = date('Y-m-d H:i:s'); + + + + Db::name('log_orders')->insert($logOrder); + + + + //发送消息 + + + + $tpl = WSTMsgTemplates('ORDER_USER_PAY_TIMEOUT'); + + + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + + + $find = ['${ORDER_NO}']; + + + + $replace = [$order['orderNo']]; + + + + //发送一条用户信息 + + + + WSTSendMsg($order['userId'],str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order['orderId']]); + + + + } + + + + $tpl = WSTMsgTemplates('ORDER_SHOP_PAY_TIMEOUT'); + + + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + + + $find = ['${ORDER_NO}']; + + + + $replace = [$order['orderNo']]; + + + + //发送一条商家信息 + + + + + + + + $msg = array(); + + + + $msg["shopId"] = $shopId; + + + + $msg["tplCode"] = $tpl["tplCode"]; + + + + $msg["msgType"] = 1; + + + + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + + + + $msg["msgJson"] = ['from'=>1,'dataId'=>$order['orderId']]; + + + + model("common/MessageQueues")->add($msg); + + + + } + + + + //微信消息 + + + + if((int)WSTConf('CONF.wxenabled')==1){ + + + + $params = []; + + + + $params['ORDER_NO'] = $order['orderNo']; + + + + WSTWxMessage(['CODE'=>'WX_ORDER_USER_PAY_TIMEOUT','userId'=>$order['userId'],'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + + + + + + + + $msg = array(); + + + + $tplCode = "WX_ORDER_SHOP_PAY_TIMEOUT"; + + + + $msg["shopId"] = $shopId; + + + + $msg["tplCode"] = $tplCode; + + + + $msg["msgType"] = 4; + + + + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/index',['type'=>'abnormal'],true,true),'params'=>$params] ; + + + + $msg["msgJson"] = ""; + + + + model("common/MessageQueues")->add($msg); + + + + } + + + + } + + + + + + + + Db::commit(); + + + + return WSTReturn('操作成功',1); + + + + }catch (\Exception $e) { + + + + Db::rollback();errLog($e); + + + + return WSTReturn('操作失败',-1); + + + + } + + + + } + + + + return WSTReturn('操作成功',1); + + + + } + + + + /** + + + + * 自动好评 + + + + */ + + + + public function autoAppraise(){ + + + + $autoAppraiseDays = (int)WSTConf('CONF.autoAppraiseDays'); + + + + $autoAppraiseDays = ($autoAppraiseDays>0)?$autoAppraiseDays:7;//避免有些客户没有设置值 + + + + $lastDay = date("Y-m-d 00:00:00",strtotime("-".$autoAppraiseDays." days")); + + + + $rs = model('orders')->where("receiveTime<'".$lastDay."' and orderStatus=2 and dataFlag=1 and isAppraise=0")->field("orderId,userId,orderScore,shopId,orderNo")->select(); + + + + if(!empty($rs)){ + + + + $prefix = config('database.prefix'); + + + + $orderIds = []; + + + + foreach ($rs as $okey => $order){ + + + + $orderIds[] = $order->orderId; + + + + } + + + + Db::startTrans(); + + + + try{ + + + + //提前锁定订单 + + + + Db::name('orders')->where(['orderId'=>['in',$orderIds]])->update(['isAppraise'=>1,'isClosed'=>1]); + + + + foreach ($rs as $okey => $order){; + + + + //获取订单相关的商品 + + + + $ordergoods = Db::name('order_goods')->where('orderId',$order->orderId)->field('goodsId,orderId,goodsSpecId')->select(); + + + + foreach($ordergoods as $goods){ + + + + //增加订单评价 + + + + $data = []; + + + + $data['userId'] = $order->userId; + + + + $data['goodsSpecId'] = (int)$goods['goodsSpecId']; + + + + $data['goodsId'] = $goods['goodsId']; + + + + $data['shopId'] = $order->shopId; + + + + $data['orderId'] = $goods['orderId']; + + + + $data['goodsScore'] = 5; + + + + $data['serviceScore'] = 5; + + + + $data['timeScore']= 5; + + + + $data['content'] = '自动好评'; + + + + $data['createTime'] = date('Y-m-d H:i:s'); + + + + Db::name('goods_appraises')->insert($data); + + + + } + + + + //增加商品评分 + + + + $updateSql = "update ".$prefix."goods_scores set + + + + totalScore=totalScore+15, + + + + goodsScore=goodsScore+5, + + + + serviceScore=serviceScore+5, + + + + timeScore=timeScore+5, + + + + totalUsers=totalUsers+1,goodsUsers=goodsUsers+1,serviceUsers=serviceUsers+1,timeUsers=timeUsers+1 + + + + where goodsId=".$goods['goodsId']; + + + + Db::execute($updateSql); + + + + //增加商品评价数 + + + + Db::name('goods')->where('goodsId',$goods['goodsId'])->setInc('appraiseNum'); + + + + //增加店铺评分 + + + + $updateSql = "update ".$prefix."shop_scores set + + + + totalScore=totalScore+15, + + + + goodsScore=goodsScore+5, + + + + serviceScore=serviceScore+5, + + + + timeScore=timeScore+5, + + + + totalUsers=totalUsers+1,goodsUsers=goodsUsers+1,serviceUsers=serviceUsers+1,timeUsers=timeUsers+1 + + + + where shopId=".$order->shopId; + + + + Db::execute($updateSql); + + + + // 查询该订单是否已经完成评价,修改orders表中的isAppraise + + + + $ogRs = Db::name('order_goods')->alias('og') + + + + ->join('__GOODS_APPRAISES__ ga','og.orderId=ga.orderId and og.goodsId=ga.goodsId and og.goodsSpecId=ga.goodsSpecId','left') + + + + ->where('og.orderId',$order->orderId)->field('og.id,ga.id gid')->select(); + + + + $isFinish = true; + + + + foreach ($ogRs as $vkey => $v){ + + + + if($v['id']>0 && $v['gid']==''){ + + + + $isFinish = false; + + + + break; + + + + } + + + + } + + + + //订单商品全部评价完则修改订单状态 + + + + if($isFinish){ + + + + if(WSTConf("CONF.isAppraisesScore")==1){ + + + + $appraisesScore = (int)WSTConf('CONF.appraisesScore'); + + + + if($appraisesScore>0){ + + + + //给用户增加积分 + + + + $score = []; + + + + $score['userId'] = $order->userId; + + + + $score['score'] = $appraisesScore; + + + + $score['dataSrc'] = 1; + + + + $score['dataId'] = $order->orderId; + + + + $score['dataRemarks'] = "评价订单【".$order->orderNo."】获得积分".$appraisesScore."个"; + + + + $score['scoreType'] = 1; + + + + $score['createTime'] = date('Y-m-d H:i:s'); + + + + Db::name('user_scores')->insert($score); + + + + // 增加用户积分 + + + + model('Users')->where("userId=".$order->userId)->update([ + + + + 'userScore'=>['exp','userScore+'.$appraisesScore], + + + + 'userTotalScore'=>['exp','userTotalScore+'.$appraisesScore] + + + + ]); + + + + } + + + + } + + + + } + + + + } + + + + Db::commit(); + + + + return WSTReturn('操作成功',1); + + + + }catch (\Exception $e) { + + + + Db::rollback();errLog($e); + + + + return WSTReturn('操作失败',-1); + + + + } + + + + } + + + + return WSTReturn('操作成功',1); + + + + } + + + + /** + + + + * 自动确认收货 + + + + */ + + + + public function autoReceive(){ + + + + $autoReceiveDays = (int)WSTConf('CONF.autoReceiveDays'); + + + + $autoReceiveDays = ($autoReceiveDays>0)?$autoReceiveDays:10;//避免有些客户没有设置值 + + + + $lastDay = date("Y-m-d 00:00:00",strtotime("-".$autoReceiveDays." days")); + + + + $rs= model('orders')->where("deliveryTime<'".$lastDay."' and orderStatus=1 and dataFlag=1")->field("orderId,orderNo,shopId,userId,shopId,orderScore,commissionFee")->select(); + + + + //dump($rs); + + + + //循环是否有延时收获的 + + + + $now_time = time(); + + + + foreach($rs as $key=>$v){ + + + + $delay_time = Db::name('order_delay')->where(['orderId'=>$v['orderId']])->value('delayTime'); + + + + if($now_time < $delay_time){ + + + + unset($rs[$key]); + + + + } + + + + } + + + + if(!empty($rs)){ + + + + $prefix = config('database.prefix'); + + + + Db::startTrans(); + + + + try{ + + + + foreach ($rs as $key => $order){ + + + + //结束订单状态 + + + + $order->receiveTime = date('Y-m-d 00:00:00'); + + + + $order->orderStatus = 2; + + + + $rsStatus = $order->save(); + + + + if(false !== $rsStatus){ + + + + hook('afterUserReceive',['orderId'=>$order->orderId]); + + + + + + + + if(WSTConf('CONF.statementType')==1){ + + + + //修改商家未计算订单数 + + + + $upSql = 'update '.$prefix.'shops set noSettledOrderNum=noSettledOrderNum+1,noSettledOrderFee=noSettledOrderFee-'.$order->commissionFee.' where shopId='.$order->shopId; + + + + Db::execute($upSql); + + + + }else{ + + + + //即时结算 + + + + model('common/Settlements')->speedySettlement($order->orderId); + + + + } + + + + + + + + //新增订单日志 + + + + $logOrder = []; + + + + $logOrder['orderId'] = $order->orderId; + + + + $logOrder['orderStatus'] = 2; + + + + $logOrder['logContent'] = "系统自动确认收货"; + + + + $logOrder['logUserId'] = $order->userId; + + + + $logOrder['logType'] = 0; + + + + $logOrder['logTime'] = date('Y-m-d H:i:s'); + + + + Db::name('log_orders')->insert($logOrder); + + + + + + + + //发送一条商家信息 + + + + $tpl = WSTMsgTemplates('ORDER_ATUO_RECEIVE'); + + + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + + + $find = ['${ORDER_NO}']; + + + + $replace = [$order['orderNo']]; + + + + $msg = array(); + + + + $msg["shopId"] = $order->shopId; + + + + $msg["tplCode"] = $tpl["tplCode"]; + + + + $msg["msgType"] = 1; + + + + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + + + + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + + + + model("common/MessageQueues")->add($msg); + + + + } + + + + //给用户增加积分 + + + + if(WSTConf("CONF.isOrderScore")==1){ + + + + $score = []; + + + + $score['userId'] = $order->userId; + + + + $score['score'] = $order->orderScore; + + + + $score['dataSrc'] = 1; + + + + $score['dataId'] = $order->orderId; + + + + $score['dataRemarks'] = "交易订单【".$order->orderNo."】获得积分".$order->orderScore."个"; + + + + $score['scoreType'] = 1; + + + + $score['createTime'] = date('Y-m-d H:i:s'); + + + + model('UserScores')->save($score); + + + + // 增加用户积分 + + + + model('Users')->where("userId=".$order->userId)->setInc('userScore',$order->orderScore); + + + + // 用户总积分 + + + + model('Users')->where("userId=".$order->userId)->setInc('userTotalScore',$order->orderScore); + + + + } + + + + } + + + + } + + + + Db::commit(); + + + + return WSTReturn('操作成功',1); + + + + }catch (\Exception $e) { + + + + Db::rollback();errLog($e); + + + + return WSTReturn('操作失败',-1); + + + + } + + + + } + + + + //echo 1; + + + + return WSTReturn('操作成功',1); + + + + } + + + + + + + + public function autoSendMsg(){ + + + + $now = date("Y-m-d H:i:s"); + + + + $list = Db::name("message_queues")->where(["sendStatus"=>0])->limit(500)->select(); + + + + foreach ($list as $key => $msg) { + + + + Db::startTrans(); + + + + try{ + + + + $msgParams = json_decode($msg["paramJson"],true); + + + + if($msg["msgType"]==2){//短信消息 + + + + //门店暂无 + + + + }else if($msg["msgType"]==3){//邮件消息 + + + + //门店暂无 + + + + }else if($msg["msgType"]==4){//微信消息 + + + + WSTWxMessage($msgParams); + + + + } + + + + Db::name("message_queues")->where(["id"=>$msg["id"]])->update(["sendStatus"=>1,"sendTime"=>$now]); + + + + Db::commit(); + + + + }catch (\Exception $e) { + + + + Db::rollback();errLog($e); + + + + return WSTReturn('操作失败',-1); + + + + } + + + + } + + + + return WSTReturn('操作成功',1); + + + + } + + + +} diff --git a/hyhproject/admin/model/DataCats.php b/hyhproject/admin/model/DataCats.php new file mode 100755 index 0000000..da4a4ae --- /dev/null +++ b/hyhproject/admin/model/DataCats.php @@ -0,0 +1,166 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 系统数据分类业务处理 + + */ + +use think\Db; + +class DataCats extends Base{ + + protected $insert = ['dataFlag'=>1]; + + /** + + * 获取数据分类列表 + + */ + + public function listQuery($catId = -1){ + + if($catId==-1)return ['id'=>0,'name'=>'系统数据','isParent'=>true,'open'=>true]; + + $rs = Db::name('data_cats')->where(['dataFlag'=>1])->field('catId id,catName name')->select(); + + return $rs; + + } + + /** + + * 获取数据分类 + + */ + + public function getById($id){ + + return $this->get(['dataFlag'=>1,'catId'=>$id]); + + } + + + + /** + + * 新增数据分类 + + */ + + public function add(){ + + // 验证数据代码 + + $catCode = input('catCode'); + + $hasCode = $this->where(['catCode'=>$catCode,'dataFlag'=>1])->find(); + + if(!empty($hasCode))return WSTReturn('数据分类代码已存在'); + + // 执行新增 + + $result = $this->validate('DataCats.add')->save(input('post.')); + + if(false !== $result){ + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + /** + + * 编辑数据分类 + + */ + + public function edit(){ + + $id = input('post.catId/d'); + + + + // 验证数据代码 + + $catCode = input('catCode'); + + $hasCode = $this->where(['catCode'=>$catCode,'dataFlag'=>1,'catId'=>['<>',$id]])->find(); + + if(!empty($hasCode))return WSTReturn('数据分类代码已存在'); + + + + + + $result = $this->validate('DataCats.edit')->allowField(['catName','catCode'])->save(input('post.'),['catId'=>$id]); + + if(false !== $result){ + + return WSTReturn("编辑成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + /** + + * 删除数据分类 + + */ + + public function del(){ + + $id = input('post.id/d'); + + $data = []; + + $data['dataFlag'] = -1; + + Db::startTrans(); + + try{ + + $result = $this->update($data,['catId'=>$id]);// 删除该数据分类 + + if(false !== $result){ + + // 删除该数据分类下所有子数据 + + Db::name('datas')->where(['catId'=>$id])->setField('dataFlag',-1); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn("删除失败",-1); + + } + + + + } + + + +} + diff --git a/hyhproject/admin/model/Datas.php b/hyhproject/admin/model/Datas.php new file mode 100755 index 0000000..ca79d85 --- /dev/null +++ b/hyhproject/admin/model/Datas.php @@ -0,0 +1,79 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 经营范围业务处理 + */ +use think\Db; +class Datas extends Base{ + protected $insert = ['dataFlag'=>1]; + /** + * 获取指定分类的列表 + */ + public function listQuery($catId){ + return Db::name('datas')->where('catId',$catId)->field('dataName,dataVal')->select(); + } + /** + * 根据catId获取子数据 + */ + public function childQuery(){ + $catId = (int)input('post.id'); + return $this->where(['dataFlag'=>1,'catId'=>$catId])->paginate(input('limit/d')); + } + /** + * 获取菜单列表 + */ + public function dataQuery($catId = -1){ + if($catId==-1)return ['id'=>0,'name'=>'系统数据','isParent'=>true,'open'=>true]; + $rs = Db::name('data_cats')->where(['dataFlag'=>1])->field('catId id,catName name')->select(); + return $rs; + } + /** + * 获取菜单 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'id'=>$id]); + } + + /** + * 新增菜单 + */ + public function add(){ + $result = $this->validate('Datas.add')->save(input('post.')); + if(false !== $result){ + cache('WST_DATAS',null); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑菜单 + */ + public function edit(){ + $id = input('post.id/d'); + $result = $this->validate('Datas.edit')->allowField(['dataName','dataVal','dataSort'])->save(input('post.'),['id'=>$id]); + if(false !== $result){ + cache('WST_DATAS',null); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除菜单 + */ + public function del(){ + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>$id]); + if(false !== $result){ + cache('WST_DATAS',null); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/EctDay.php b/hyhproject/admin/model/EctDay.php new file mode 100755 index 0000000..487ee33 --- /dev/null +++ b/hyhproject/admin/model/EctDay.php @@ -0,0 +1,163 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 提现分类业务处理 + */ +class EctDay extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $loginName = input('loginName'); + $where = []; + if($loginName!='')$where['b.loginName'] = ['like','%'.$loginName.'%']; + if($startDate && $endDate){ + $where['a.giveTime'] =['between',[strtotime($startDate.' 00:00:00'),strtotime($endDate.' 23:59:59')]]; + }elseif($startDate){ + $where['a.giveTime'] = [">=",strtotime($startDate)]; + }elseif($endDate){ + $where['a.giveTime'] = ["<=",strtotime($endDate)]; + } + //mark by cheng 只显示超过一天的提现数据 + $page = Db::name('user_everyday_ect_log')->alias('a') + ->join('users b','b.userId=a.userId','left') + ->where($where) + ->order('a.giveTime desc') + ->field('a.ectNum,giveTime,b.loginName') + ->paginate(input('limit/d'))->toArray(); + return $page; + } + /** + * 获取提现详情 + */ + public function getById(){ + $id = (int)input('id'); + $rs = $this->get($id); + $user = []; + if($rs['targetType']==1){ + $user = Db::name('shops')->alias('s') + ->join('__USERS__ u','u.userId=s.userId') + ->where('shopId',$rs['targetId']) + ->field('s.shopId,u.loginName,s.shopName as userName') + ->find(); + + }else{ + $user = Db::name('users')->where('userId',$rs['targetId'])->field('userId,loginName,userName')->find(); + } + $rs['userName'] = $user['userName']; + $rs['loginName'] = $user['loginName']; + return $rs; + } + /** + * 导出提现申请 + */ + public function toExport(){ + $name='ECT提现管理表'; + $startDate = input('startDate'); + $endDate = input('endDate'); + $ectNo = input('ectNo'); + $where = []; + if($ectNo!='')$where['ectNum'] = ['like','%'.$ectNo.'%']; + if($startDate && $endDate){ + $where['a.giveTime'] =['between',[strtotime($startDate.' 00:00:00'),strtotime($endDate.' 23:59:59')]]; + }elseif($startDate){ + $where['a.giveTime'] = [">=",strtotime($startDate)]; + }elseif($endDate){ + $where['a.giveTime'] = ["<=",strtotime($endDate)]; + } + //mark by cheng 只显示超过一天的提现数据 + $page = Db::name('user_ect_cash_log')->alias('a') + ->join('users b','b.userId=a.userId','left') + ->where($where) + ->order('a.giveTime desc') + ->field('a.giveTime,ectNum,b.loginName') + ->select(); + + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + ->setLastModifiedBy("WSTMart")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("提现")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet()->setCellValue('A1', 'ECT交易ID') + ->setCellValue('B1', '会员名称') + ->setCellValue('C1', 'ECT发送方') + ->setCellValue('D1', 'ECT接收方') + ->setCellValue('E1', '备注') + ->setCellValue('F1', 'ECT提现数量') + ->setCellValue('G1', '创建时间'); + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $page[$row]['transactionId']) + ->setCellValue('B'.$i, $page[$row]['loginName']) + ->setCellValue('C'.$i, $page[$row]['fromAccount']) + ->setCellValue('D'.$i, $page[$row]['toAccount']) + ->setCellValue('E'.$i, $page[$row]['dataRemarks']) + ->setCellValue('F'.$i, $page[$row]['ectNum']) + ->setCellValue('G'.$i, $page[$row]['createTime']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/EctDeal.php b/hyhproject/admin/model/EctDeal.php new file mode 100755 index 0000000..1a8e638 --- /dev/null +++ b/hyhproject/admin/model/EctDeal.php @@ -0,0 +1,71 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 提现分类业务处理 + */ +class EctDeal extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $loginName = trim(input('loginName')); + $where = []; + + if($loginName!=''){ + $userInfo = getUserByName($loginName); + if(!$userInfo) return []; + $where['b.userId'] = $userInfo['userId']; + } + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + if($sortArr[0]=='ectNo'){ + $order = $sortArr[0].'+0 '.$sortArr[1]; + } + }else{ + $order = ('ectId DESC'); + } + if($startDate!='' && $endDate!=''){ + $startDate=strtotime($startDate.' 00:00:00'); + $endDate=strtotime($endDate.' 23:59:59'); + $where['a.createTime'] = ['between',[$startDate,$endDate]]; + }else if($startDate!=''){ + $startDate=strtotime($startDate.' 00:00:00'); + $where['a.createTime'] = ['>=',$startDate]; + }else if($endDate!=''){ + $endDate=strtotime($endDate.' 23:59:59'); + $where['a.createTime'] = ['<=',$endDate]; + } + $page = Db::name('user_ect_log')->alias('a')->join('users b','b.userId=a.userId','inner') + ->where($where) + ->order($order) + ->field('a.ectId,dataSrc,dataRemarks,a.createTime,ectNum,b.loginName,a.userId') + ->paginate(input('limit/d'))->toArray(); + if($loginName!=''){ + foreach ($page['Rows'] as $key => $value) { + $page['Rows'][$key]['sumEct']=db('user_ect_log')->where(['userId'=>$value['userId'],'dataSrc'=>12])->sum('ectNum'); + $page['Rows'][$key]['sumCashEct']=db('user_ect_cash_log')->where(['userId'=>$value['userId'],'status'=>1])->sum('ectNum'); + $page['Rows'][$key]['sumCashChong']=db('user_ect_log')->where(['userId'=>$value['userId'],'dataSrc'=>14])->sum('ectNum'); + } + } + if(count($page['Rows'])>0){ + $userIds = []; + $shopIds = []; + $userMap = []; + if(count($userIds)>0){ + $user = Db::name('users')->where(['userId'=>['in',$userIds]])->field('userId,loginName,userName')->select(); + foreach ($user as $key => $v) { + $userMap["0_".$v['userId']] = $v; + } + } + } + return $page; + } +} diff --git a/hyhproject/admin/model/EctTarget.php b/hyhproject/admin/model/EctTarget.php new file mode 100755 index 0000000..17c51fe --- /dev/null +++ b/hyhproject/admin/model/EctTarget.php @@ -0,0 +1,400 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +use think\Loader; + +/** + + * ============================================================================ + + * 提现分类业务处理 + + */ + +class EctTarget extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $startDate = input('startDate'); + + $endDate = input('endDate'); + + $ectNo = input('ectNo'); + + $loginName = input('loginName'); + + $where = []; + + if($ectNo!='')$where['ectNum'] = ['like','%'.$ectNo.'%']; + + if($loginName!='')$where['b.loginName'] = ['like','%'.$loginName.'%']; + + if($startDate && $endDate){ + + $where['a.createTime'] =['between',[strtotime($startDate.' 00:00:00'),strtotime($endDate.' 23:59:59')]]; + + }elseif($startDate){ + + $where['a.createTime'] = [">=",strtotime($startDate)]; + + }elseif($endDate){ + + $where['a.createTime'] = ["<=",strtotime($endDate)]; + + } + + //mark by cheng 只显示超过一天的提现数据 + + $page = Db::name('user_ect_cash_log')->alias('a') + + ->join('users b','b.userId=a.userId','left') + + ->where($where) + + ->order('a.status asc,a.id desc') + + ->field('a.transactionId,fromAccount,toAccount,dataRemarks,a.createTime,ectNum,b.loginName,a.userId,a.status,a.id') + + ->paginate(input('limit/d'))->toArray(); + + if($loginName!=''){ + + foreach ($page['Rows'] as $key => $value) { + + $page['Rows'][$key]['sumEct']=db('user_ect_cash_log')->where(['userId'=>$value['userId'],'status'=>1])->sum('ectNum'); + + } + + } + + return $page; + + } + + //根据ID获取提现详情 + + public function toHandle(){ + + $id=input('id'); + + $result=Db::name('user_ect_cash_log')->alias('a') + + ->join('users b','b.userId=a.userId','left') + + ->where('id',$id) + + ->order('a.createTime desc') + + ->field('a.transactionId,fromAccount,toAccount,dataRemarks,a.createTime,ectNum,b.loginName,a.userId,a.status,a.id') + + ->find(); + + return $result; + + } + + //对审核结果进行操作 + + public function ectTarget(){ + + $id=input('id'); + + $status=input('status'); + + Db::startTrans(); + + try{ + + $result = db('user_ect_cash_log')->where('id',$id)->update(['status'=>$status]); + + if(false !== $result){ + + Db::commit(); + + //标记删除购物车 + + return WSTReturn("修改成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('修改失败',-1); + + } + + /** + + * 获取提现详情 + + */ + + public function getById(){ + + $id = (int)input('id'); + + $rs = $this->get($id); + + $user = []; + + if($rs['targetType']==1){ + + $user = Db::name('shops')->alias('s') + + ->join('__USERS__ u','u.userId=s.userId') + + ->where('shopId',$rs['targetId']) + + ->field('s.shopId,u.loginName,s.shopName as userName') + + ->find(); + + + + }else{ + + $user = Db::name('users')->where('userId',$rs['targetId'])->field('userId,loginName,userName')->find(); + + } + + $rs['userName'] = $user['userName']; + + $rs['loginName'] = $user['loginName']; + + return $rs; + + } + + /** + + * 导出提现申请 + + */ + + public function toExport(){ + + $name='ECT提现管理表'; + + $startDate = input('startDate'); + + $endDate = input('endDate'); + + $ectNo = input('ectNo'); + + $loginName = input('loginName'); + + $where = []; + + if($ectNo!='')$where['ectNum'] = ['like','%'.$ectNo.'%']; + + if($loginName!='')$where['b.loginName'] = ['like','%'.$loginName.'%']; + + if($startDate && $endDate){ + + $where['a.createTime'] =['between',[strtotime($startDate.' 00:00:00'),strtotime($endDate.' 23:59:59')]]; + + }elseif($startDate){ + + $where['a.createTime'] = [">=",strtotime($startDate)]; + + }elseif($endDate){ + + $where['a.createTime'] = ["<=",strtotime($endDate)]; + + } + + //mark by cheng 只显示超过一天的提现数据 + + $page = Db::name('user_ect_cash_log')->alias('a') + + ->join('users b','b.userId=a.userId','left') + + ->where($where) + + ->order('a.createTime desc') + + ->field('a.transactionId,fromAccount,toAccount,dataRemarks,a.createTime,from_unixtime(a.createTime) dateTime, ectNum,b.loginName,a.status') + + ->select(); + + + + Loader::import('phpexcel.PHPExcel.IOFactory'); + + $objPHPExcel = new \PHPExcel(); + + // 设置excel文档的属性 + + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + + ->setLastModifiedBy("WSTMart")//最后修改人 + + ->setTitle($name)//标题 + + ->setSubject($name)//题目 + + ->setDescription($name)//描述 + + ->setKeywords("提现")//关键字 + + ->setCategory("Test result file");//种类 + + + + // 开始操作excel表 + + $objPHPExcel->setActiveSheetIndex(0); + + // 设置工作薄名称 + + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + + // 设置默认字体和大小 + + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + + $styleArray = array( + + 'font' => array( + + 'bold' => true, + + 'color'=>array( + + 'argb' => 'ffffffff', + + ) + + ), + + 'borders' => array ( + + 'outline' => array ( + + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + + ) + + ) + + ); + + //设置宽 + + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(30); + + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->getFill()->getStartColor()->setARGB('333399'); + + + + $objPHPExcel->getActiveSheet()->setCellValue('A1', 'ECT交易ID') + + ->setCellValue('B1', '会员名称') + + ->setCellValue('C1', 'ECT发送方') + + ->setCellValue('D1', 'ECT接收方') + + ->setCellValue('E1', '备注') + + ->setCellValue('F1', 'ECT提现数量') + + ->setCellValue('G1', '创建时间') + + ->setCellValue('H1', '状态(0.未审核1.同意2.拒绝)'); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->applyFromArray($styleArray); + + + + for ($row = 0; $row < count($page); $row++){ + + $i = $row+2; + + $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $page[$row]['transactionId']) + + ->setCellValue('B'.$i, $page[$row]['loginName']) + + ->setCellValue('C'.$i, $page[$row]['fromAccount']) + + ->setCellValue('D'.$i, $page[$row]['toAccount']) + + ->setCellValue('E'.$i, $page[$row]['dataRemarks']) + + ->setCellValue('F'.$i, $page[$row]['ectNum']) + + ->setCellValue('G'.$i, $page[$row]['dateTime']) + + ->setCellValue('H'.$i, $page[$row]['status']); + + } + + + + //输出EXCEL格式 + + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + + // 从浏览器直接输出$filename + + header('Content-Type:application/csv;charset=UTF-8'); + + header("Pragma: public"); + + header("Expires: 0"); + + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + + header("Content-Type:application/force-download"); + + header("Content-Type:application/vnd.ms-excel;"); + + header("Content-Type:application/octet-stream"); + + header("Content-Type:application/download"); + + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + + header("Content-Transfer-Encoding:binary"); + + $objWriter->save('php://output'); + + } + +} + diff --git a/hyhproject/admin/model/Express.php b/hyhproject/admin/model/Express.php new file mode 100755 index 0000000..0432f46 --- /dev/null +++ b/hyhproject/admin/model/Express.php @@ -0,0 +1,150 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 快递业务处理 + + */ + +class Express extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + return $this->where('dataFlag',1)->field('expressId,expressName,expressCode,expressImg')->order('expressId desc')->paginate(input('limit/d')); + + } + + public function getById($id){ + + return $this->get(['expressId'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + // $data = ['expressName'=>input('post.expressName'),'expressCode'=>input('post.expressCode')]; + + $data = input('post.'); + + WSTUnset($data,'expressId'); + + Db::startTrans(); + + try{ + + $result = $this->validate('Express.add')->allowField(true)->save($data); + + if (false !==$result){ + + $id = $this->expressId; + + //启用文件上传 + + WSTUseImages(1,$id,$data['expressImg']); + + if(false !==$result){ + + Db::commit(); + + return WSTReturn("新增成功",1); + + } + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $data = input('post.'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, (int)$data['expressId'], $data['expressImg'], 'express', 'expressImg'); + + $result = $this->validate('Express.edit')->allowField(true)->save($data,['expressId'=>(int)$data['expressId']]); + + if(false !== $result){ + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d',0); + + $data = []; + + $data['dataFlag'] = -1; + + $result = $this->update($data,['expressId'=>$id]); + + if(false !== $result){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/Friendlinks.php b/hyhproject/admin/model/Friendlinks.php new file mode 100755 index 0000000..1780f23 --- /dev/null +++ b/hyhproject/admin/model/Friendlinks.php @@ -0,0 +1,172 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 友情链接业务处理 + + */ + +use think\Db; + +class friendlinks extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + return $this->where('dataFlag',1)->field('friendlinkId,friendlinkName,friendlinkIco,friendlinkSort,friendlinkUrl')->order('friendlinkId desc')->paginate(input('limit/d')); + + } + + public function getById($id){ + + return $this->get(['friendlinkId'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + $data['friendlinkSort'] = (int)$data['friendlinkSort']; + + WSTUnset($data,'friendlinkId'); + + Db::startTrans(); + + try{ + + $result = $this->validate('friendlinks.add')->allowField(true)->save($data); + + $id = $this->friendlinkId; + + if(false !== $result){ + + cache('TAG_FRIENDLINK',null); + + //启用上传图片 + + WSTUseImages(1, $id, $data['friendlinkIco']); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $id = (int)input('post.friendlinkId'); + + $data = input('post.'); + + $data['friendlinkSort'] = (int)$data['friendlinkSort']; + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, $id, $data['friendlinkIco'], 'friendlinks', 'friendlinkIco'); + + $result = $this->validate('friendlinks.edit')->allowField(true)->save($data,['friendlinkId'=>$id]); + + if(false !== $result){ + + cache('TAG_FRIENDLINK',null); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.id/d'); + + Db::startTrans(); + + try{ + + $data = []; + + $data['dataFlag'] = -1; + + $result = $this->update($data,['friendlinkId'=>$id]); + + if(false !== $result){ + + cache('TAG_FRIENDLINK',null); + + WSTUnuseImage('friendlinks','friendlinkIco',$id); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/Goods.php b/hyhproject/admin/model/Goods.php new file mode 100755 index 0000000..a6b806a --- /dev/null +++ b/hyhproject/admin/model/Goods.php @@ -0,0 +1,627 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends Base{ + /** + * 上架商品列表 + */ + public function saleByPage(){ + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + $areaIdPath = input('areaIdPath'); + $goodsCatIdPath = input('goodsCatIdPath'); + $goodsName = input('goodsName'); + $shopName = input('shopName'); + $startDate = input('startDate'); + $endDate = input('endDate'); + if($startDate!='' && $endDate!=''){ + $where['saleTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['saleTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['saleTime'] = ['<=',$endDate.' 23:59:59']; + } + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($goodsCatIdPath !='')$where['goodsCatIdPath'] = ['like',$goodsCatIdPath."%"]; + if($goodsName != '')$where['goodsName|goodsSn'] = ['like',"%$goodsName%"]; + if($shopName != '')$where['shopName|shopSn'] = ['like',"%$shopName%"]; + // 排序 + $sort = input('sort'); + $order = 'saleTime desc'; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $keyCats = model('GoodsCats')->listKeyAll(); + $rs = $this->alias('g') + ->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->where($where) + ->field('g.goodsId,g.goodsName,g.goodsSn,g.saleNum,g.shopPrice,g.discountRate,g.shopId,goodsImg,s.shopName,s.phone,goodsCatIdPath,g.createTime,g.saleTime,g.isSale') + ->order($order) + ->paginate(input('limit/d'))->toArray(); + + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + $rs['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + // dump($rs);die; + return $rs; + } + /** + * 下架商品列表 + */ + public function shelvesByPage(){ + $where = []; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 0; + $areaIdPath = input('areaIdPath'); + $goodsCatIdPath = input('goodsCatIdPath'); + $goodsName = input('goodsName'); + $shopName = input('shopName'); + $startDate = input('startDate'); + $endDate = input('endDate'); + if($startDate!='' && $endDate!=''){ + $where['saleTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['saleTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['saleTime'] = ['<=',$endDate.' 23:59:59']; + } + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($goodsCatIdPath !='')$where['goodsCatIdPath'] = ['like',$goodsCatIdPath."%"]; + if($goodsName != '')$where['goodsName|goodsSn'] = ['like',"%$goodsName%"]; + if($shopName != '')$where['shopName|shopSn'] = ['like',"%$shopName%"]; + // 排序 + $sort = input('sort'); + $order = 'saleTime desc'; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $keyCats = model('GoodsCats')->listKeyAll(); + $rs = $this->alias('g') + ->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->where($where) + ->field('goodsId,goodsName,goodsSn,saleNum,shopPrice,g.shopId,goodsImg,s.shopName,goodsCatIdPath,g.createTime,saleTime,isSale') + ->order($order) + ->paginate(input('limit/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + $rs['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + return $rs; + } + public function getGoodsCatNames($goodsCatPath, $keyCats){ + $catIds = explode("_",$goodsCatPath); + $catNames = array(); + for($i=0,$k=count($catIds);$i<$k;$i++){ + if($catIds[$i]=='')continue; + if(isset($keyCats[$catIds[$i]]))$catNames[] = $keyCats[$catIds[$i]]; + } + return implode("→",$catNames); + } + /** + * 审核中的商品 + */ + public function auditByPage(){ + $where['goodsStatus'] = 0; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $areaIdPath = input('areaIdPath'); + $goodsCatIdPath = input('goodsCatIdPath'); + $goodsName = input('goodsName'); + $shopName = input('shopName'); + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($goodsCatIdPath !='')$where['goodsCatIdPath'] = ['like',$goodsCatIdPath."%"]; + if($goodsName != '')$where['goodsName|goodsSn'] = ['like',"%$goodsName%"]; + if($shopName != '')$where['shopName|shopSn'] = ['like',"%$shopName%"]; + // 排序 + $sort = input('sort'); + $order = 'saleTime desc'; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $keyCats = model('GoodsCats')->listKeyAll(); + $rs = $this->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->where($where) + ->field('g.goodsId,g.discountRate,g.goodsName,g.goodsSn,g.saleNum,g.shopPrice,g.goodsImg,s.shopName,s.shopId,s.phone,goodsCatIdPath') + ->order($order) + ->paginate(input('limit/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + $rs['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + return $rs; + } + /** + * 违规的商品 + */ + public function illegalByPage(){ + $where['goodsStatus'] = -1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $areaIdPath = input('areaIdPath'); + $goodsCatIdPath = input('goodsCatIdPath'); + $goodsName = input('goodsName'); + $shopName = input('shopName'); + $startDate = input('startDate'); + $endDate = input('endDate'); + if($startDate!='' && $endDate!=''){ + $where['saleTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['saleTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['saleTime'] = ['<=',$endDate.' 23:59:59']; + } + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($goodsCatIdPath !='')$where['goodsCatIdPath'] = ['like',$goodsCatIdPath."%"]; + if($goodsName != '')$where['goodsName|goodsSn'] = ['like',"%$goodsName%"]; + if($shopName != '')$where['shopName|shopSn'] = ['like',"%$shopName%"]; + // 排序 + $sort = input('sort'); + $order = 'saleTime desc'; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $keyCats = model('GoodsCats')->listKeyAll(); + $rs = $this->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->where($where) + ->field('goodsId,goodsName,goodsSn,goodsImg,s.shopName,s.shopId,illegalRemarks,goodsCatIdPath') + ->order($order) + ->paginate(input('limit/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + $rs['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + return $rs; + } + + /** + * 删除商品 + */ + public function del(){ + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $data['isSale'] = 0; + Db::startTrans(); + try{ + $result = $this->update($data,['goodsId'=>$id]); + if(false !== $result){ + hook('afterChangeGoodsStatus',['goodsId'=>$id]); + Db::name('carts')->where('goodsId',$id)->delete(); + WSTUnuseImage('goods','goodsImg',$id); + WSTUnuseImage('goods','gallery',$id); + Db::commit(); + //标记删除购物车 + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + /** + * 批量删除商品 + */ + public function batchDel(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('post.ids/a'); + Db::startTrans(); + try{ + $rs = $this->where(['goodsId'=>['in',$ids], + 'shopId'=>$shopId])->setField(['dataFlag'=>-1,'isSale'=>0]); + if(false !== $rs){ + Db::name('carts')->where(['goodsId'=>['in',$ids]])->delete(); + //标记删除购物车 + foreach ($ids as $v){ + WSTUnuseImage('goods','goodsImg',(int)$v); + WSTUnuseImage('goods','gallery',(int)$v); + hook('afterChangeGoodsStatus',['goodsId'=>$v]); + } + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + + /** + * 设置商品违规状态 + */ + public function illegal($goodsId=0,$from=0){ + $illegalRemarks = input('post.illegalRemarks'); + $id = ($goodsId==0)?(int)input('post.id'):$goodsId; + if($illegalRemarks==''){ + return WSTReturn("请输入原因"); + }else if($from == 1){ + $id = ($goodsId==0)?(int)input('post.id'):$goodsId; + $illegalRemarks = '该商品因被用户举报,现已下架'; + } + //判断商品状态 + $rs = $this->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId','left')->where('goodsId',$id) + ->field('s.userId,g.goodsName,g.goodsSn,g.goodsStatus,g.goodsId,g.shopId')->find(); + if((int)$rs['goodsId']==0)return WSTReturn("无效的商品"); + if((int)$rs['goodsStatus']<0)return WSTReturn("操作失败,商品状态已发生改变,请刷新后再尝试"); + Db::startTrans(); + try{ + $res = $this->where('goodsId',$id)->setField(['goodsStatus'=>-1,'illegalRemarks'=>$illegalRemarks]); + if($res!==false){ + + Db::name('carts')->where(['goodsId'=>$id])->delete(); + //发送一条商家信息 + $shopId = $rs["shopId"]; + $tpl = WSTMsgTemplates('GOODS_REJECT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${GOODS}','${GOODS_SN}','${TIME}','${REASON}']; + $replace = [$rs['goodsName'],$rs['goodsSn'],date('Y-m-d H:i:s'),$illegalRemarks]; + + $msg = array(); + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>2,'dataId'=>$id]; + model("common/MessageQueues")->add($msg); + } + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['GOODS'] = $rs['goodsName']; + $params['GOODS_SN'] = $rs['goodsSn']; + $params['TIME'] = date('Y-m-d H:i:s'); + $params['REASON'] = $illegalRemarks; + + $msg = array(); + $tplCode = "WX_GOODS_REJECT"; + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'params'=>$params] ; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + hook('afterChangeGoodsStatus',['goodsId'=>$id]); + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + /** + * 批量商品审核不通过 + */ + public function batchIllegal(){ + $ids = input('ids'); + if(empty($ids))return WSTReturn('请选择商品'); + $ids = explode(',' , $ids); + foreach($ids as $k=>$v){ + $rs = $this->illegal($v); + } + return WSTReturn('操作成功',1); + + } + /** + * 通过商品审核通过 + */ + public function allow($goodsId=0){ + $id = ($goodsId==0)?(int)input('post.id'):$goodsId; + //判断商品状态 + $rs = $this->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId','left')->where('goodsId',$id) + ->field('s.userId,g.goodsName,g.goodsSn,g.goodsStatus,g.goodsId,g.shopId')->find(); + if((int)$rs['goodsId']==0)return WSTReturn("无效的商品"); + if((int)$rs['goodsStatus']==1)return WSTReturn("操作失败,商品状态已发生改变,请刷新后再尝试"); + Db::startTrans(); + try{ + $res = $this->setField(['goodsId'=>$id,'goodsStatus'=>1]); + if($res!==false){ + //发送一条商家信息 + $shopId = $rs["shopId"]; + $tpl = WSTMsgTemplates('GOODS_ALLOW'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${GOODS}','${GOODS_SN}','${TIME}']; + $replace = [$rs['goodsName'],$rs['goodsSn'],date('Y-m-d H:i:s')]; + + $msg = array(); + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + $msg["msgJson"] = ['from'=>2,'dataId'=>$id]; + model("common/MessageQueues")->add($msg); + } + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['GOODS'] = $rs['goodsName']; + $params['GOODS_SN'] = $rs['goodsSn']; + $params['TIME'] = date('Y-m-d H:i:s'); + + $msg = array(); + $tplCode = "WX_GOODS_ALLOW"; + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'params'=>$params] ; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + hook('afterChangeGoodsStatus',['goodsId'=>$id]); + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + /** + * 批量商品审核 + */ + public function batchAllow(){ + $ids = input('ids'); + if(empty($ids))return WSTReturn('请选择商品'); + $ids = explode(',' , $ids); + $count = 0;// 记录上架不成功的商品数 + foreach($ids as $k=>$v){ + $rs = $this->allow($v); + if($rs['status']==-1){ + ++$count; + } + } + if($count==0)return WSTReturn('操作成功',1); + $msg = "成功上架".(count($ids)-$count)."件商品,其中{$count}件商品上架失败."; + return WSTReturn($msg,1); + + } + + + /** + * 查询商品 + */ + public function searchQuery(){ + $goodsCatatId = (int)input('post.goodsCatId'); + if($goodsCatatId<=0)return []; + $goodsCatIds = WSTGoodsCatPath($goodsCatatId); + $key = input('post.key'); + $where = []; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + $where['g.goodsStatus'] = 1; + $where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + if($key!='')$where['goodsName|shopName'] = ['like','%'.$key.'%']; + return $this->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId','inner') + ->where($where)->field('g.goodsName,s.shopName,g.goodsId')->limit(50)->select(); + } + + /** + * 根据下架指定店铺下的所有商品 + */ + public function unsaleByshopId($shopId){ + //下架商品 + $data = []; + $data['isSale'] = 0; + $goodsIds = []; + $goods = $this->where(['shopId'=>$shopId,'isSale'=>1])->field('goodsId')->select(); + if(!empty($goods)){ + foreach ($goods as $key => $v) { + $goodsIds[] = $v['goodsId']; + } + } + $result = $this->where(['shopId'=>$shopId])->update($data); + if(false !== $result){ + //删除推荐商品,删除购物车里的商品 + if(count($goodsIds)>0){ + //执行钩子事件 + foreach ($goodsIds as $key => $v) { + hook('afterChangeGoodsStatus',['goodsId'=>$v]); + } + Db::name('recommends')->where(['dataSrc'=>0,'dataId'=>['in',$goodsIds]])->delete(); + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + } + Db::commit(); + return WSTReturn('操作成功',1); + } + return WSTReturn('删除失败',-1); + } + + /** + * 根据下架指定店铺下的所有商品 + */ + public function delByshopId($shopId){ + //下架商品 + $data = []; + $data['isSale'] = 0; + $data['dataFlag'] = -1; + $goodsIds = []; + $goods = $this->where(['shopId'=>$shopId])->field('goodsId')->select(); + if(!empty($goods)){ + foreach ($goods as $key => $v) { + $goodsIds[] = $v['goodsId']; + } + } + $result = $this->where(['shopId'=>$shopId])->update($data); + if(false !== $result){ + //删除推荐商品,删除购物车里的商品 + if(count($goodsIds)>0){ + //执行钩子事件 + foreach ($goodsIds as $key => $v) { + hook('afterChangeGoodsStatus',['goodsId'=>$v]); + } + Db::name('recommends')->where(['dataSrc'=>0,'dataId'=>['in',$goodsIds]])->delete(); + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + } + Db::commit(); + return WSTReturn('操作成功',1); + } + return WSTReturn('删除失败',-1); + } + + /** + * 商品ECT支付状态 + */ + public function goodsEct(){ + $goodsId = input('post.id/d'); + $pay = Db::name('goods_pay')->where(['goodsId'=>$goodsId])->select();//查询支付方式表是否已有该商品 + if($pay){ + return WSTReturn('此商品已添加ECT支付'); + } + $arr =[]; + $arr['goodsId'] = $goodsId; + $arr['ectPay'] = 1; + // dump($arr);die; + $result = Db::name('goods_pay')->insert($arr); + if($result){ + return WSTReturn('添加成功',1); + }else{ + return WSTReturn('添加失败'); + } + } + + //上架商品导出 + public function toExportSale(){ + $name="上架商品列表"; + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + $areaIdPath = input('areaIdPath'); + $goodsCatIdPath = input('goodsCatIdPath'); + $goodsName = input('goodsName'); + $shopName = input('shopName'); + $startDate = input('startDate'); + $endDate = input('endDate'); + if($startDate!='' && $endDate!=''){ + $where['saleTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['saleTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['saleTime'] = ['<=',$endDate.' 23:59:59']; + } + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($goodsCatIdPath !='')$where['goodsCatIdPath'] = ['like',$goodsCatIdPath."%"]; + if($goodsName != '')$where['goodsName|goodsSn'] = ['like',"%$goodsName%"]; + if($shopName != '')$where['shopName|shopSn'] = ['like',"%$shopName%"]; + // 排序 + $sort = input('sort'); + $order = 'saleTime desc'; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $keyCats = model('GoodsCats')->listKeyAll(); + $page = $this->alias('g') + ->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->where($where) + ->field('goodsId,goodsName,goodsSn,saleNum,shopPrice,g.shopId,goodsImg,s.shopName,goodsCatIdPath,g.createTime,saleTime,isSale') + ->order($order) + ->select(); + foreach ($page as $key => $v){ + $page[$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + $page[$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(40); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '商品ID') + ->setCellValue('B1', '商品名称') + ->setCellValue('C1', '商品编号') + ->setCellValue('D1', '价格') + ->setCellValue('E1', '所属店铺') + ->setCellValue('F1', '申请上架时间') + ->setCellValue('G1', '审核通过时间') + ->setCellValue('H1', '所属分类') + ->setCellValue('I1', '销量') + ->setCellValue('J1', '状态'); + $objPHPExcel->getActiveSheet()->getStyle('A1:J1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['goodsId']) + ->setCellValue('B'.$i, $page[$row]['goodsName']) + ->setCellValue('C'.$i, chunk_split($page[$row]['goodsSn'])) + ->setCellValue('D'.$i, $page[$row]['shopPrice']) + ->setCellValue('E'.$i, $page[$row]['shopName']) + ->setCellValue('F'.$i, $page[$row]['saleTime']) + ->setCellValue('G'.$i, $page[$row]['createTime']) + ->setCellValue('H'.$i, $page[$row]['goodsCatName']) + ->setCellValue('I'.$i, $page[$row]['saleNum']) + ->setCellValue('J'.$i, $page[$row]['isSale']); + + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/GoodsAppraises.php b/hyhproject/admin/model/GoodsAppraises.php new file mode 100755 index 0000000..72e18ae --- /dev/null +++ b/hyhproject/admin/model/GoodsAppraises.php @@ -0,0 +1,286 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 商品评价业务处理 + + */ + +class GoodsAppraises extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $where = 'p.shopId=g.shopId and gp.goodsId=g.goodsId and o.orderId=gp.orderId and gp.dataFlag=1'; + + $shopName = input('shopName'); + + $goodsName = input('goodsName'); + + + + $areaId1 = (int)input('areaId1'); + + if($areaId1>0){ + + $where.=" and p.areaIdPath like '".$areaId1."%'"; + + + + $areaId2 = (int)input("areaId1_".$areaId1); + + if($areaId2>0) + + $where.=" and p.areaIdPath like '".$areaId1."_".$areaId2."%'"; + + + + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + + if($areaId3>0) + + $where.=" and p.areaId = $areaId3"; + + } + + + + + + if($shopName!='') + + $where.=" and (p.shopName like '%".$shopName."%' or p.shopSn like '%".$shopName."%')"; + + if($goodsName!='') + + $where.=" and (g.goodsName like '%".$goodsName."%' or g.goodsSn like '%".$goodsName."%')"; + + $sort = input('sort'); + + $order = []; + + if($sort!=''){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + } + + $rs = $this->alias('gp')->field('gp.*,g.goodsName,g.goodsImg,o.orderNo,u.loginName') + + ->join('__GOODS__ g ','gp.goodsId=g.goodsId','left') + + ->join('__ORDERS__ o','gp.orderId=o.orderId','left') + + ->join('__USERS__ u','u.userId=gp.userId','left') + + ->join('__SHOPS__ p','p.shopId=gp.shopId','left') + + ->where($where) + + ->order($order) + + ->order('id desc') + + ->paginate(input('limit/d'))->toArray(); + + return $rs; + + } + + public function getById($id){ + + return $this->alias('gp')->field('gp.*,o.orderNo,u.loginName,g.goodsName,g.goodsImg') + + ->join('__GOODS__ g ','gp.goodsId=g.goodsId','left') + + ->join('__ORDERS__ o','gp.orderId=o.orderId','left') + + ->join('__USERS__ u','u.userId=gp.userId','left') + + ->where('gp.id',$id)->find(); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $Id = input('post.id/d',0); + + $data = input('post.'); + + $data['isShow'] = ((int)$data['isShow']==1)?1:0; + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + $result = $this->validate('GoodsAppraises.edit')->allowField(true)->save($data,['id'=>$Id]); + + if(false !== $result){ + + $goodsAppraises = $this->get($Id); + + $this->statGoodsAppraises($goodsAppraises->goodsId,$goodsAppraises->shopId); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + print_r($e); + + Db::rollback();errLog($e); + + } + + return WSTReturn("编辑失败"); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.id/d',0); + + Db::startTrans(); + + try{ + + $goodsAppraises = $this->get($id); + + $goodsAppraises->dataFlag = -1; + + $result = $goodsAppraises->save(); + + if(false !== $result){ + + $this->statGoodsAppraises($goodsAppraises->goodsId,$goodsAppraises->shopId); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn("删除失败"); + + } + + + + /** + + * 重新统计商品 + + */ + + public function statGoodsAppraises($goodsId,$shopId){ + + $rs = Db::name('goods_appraises')->where(['goodsId'=>$goodsId,'isShow'=>1,'dataFlag'=>1]) + + ->field('count(userId) userNum,sum(goodsScore) goodsScore,sum(serviceScore) serviceScore, sum(timeScore) timeScore') + + ->find(); + + $data = []; + + //商品评价数 + + Db::name('goods')->where('goodsId',$goodsId)->update(['appraiseNum'=>$rs['userNum']]); + + //商品评价统计 + + $data['totalScore'] = (int)$rs['goodsScore']+$rs['serviceScore']+$rs['timeScore']; + + $data['totalUsers'] = (int)$rs['userNum']; + + $data['goodsScore'] = (int)$rs['goodsScore']; + + $data['goodsUsers'] = (int)$rs['userNum']; + + $data['serviceScore'] = (int)$rs['serviceScore']; + + $data['serviceUsers'] = (int)$rs['userNum']; + + $data['timeScore'] = (int)$rs['serviceScore']; + + $data['timeUsers'] = (int)$rs['userNum']; + + Db::name('goods_scores')->where('goodsId',$goodsId)->update($data); + + //商家评价 + + $rs = Db::name('goods_appraises')->where(['shopId'=>$shopId,'isShow'=>1,'dataFlag'=>1]) + + ->field('count(userId) userNum,sum(goodsScore) goodsScore,sum(serviceScore) serviceScore, sum(timeScore) timeScore') + + ->find(); + + $data['totalScore'] = $rs['goodsScore']+$rs['serviceScore']+$rs['timeScore']; + + $data['totalUsers'] = $rs['userNum']; + + $data['goodsScore'] = $rs['goodsScore']; + + $data['goodsUsers'] = $rs['userNum']; + + $data['serviceScore'] = $rs['serviceScore']; + + $data['serviceUsers'] = $rs['userNum']; + + $data['timeScore'] = $rs['serviceScore']; + + $data['timeUsers'] = $rs['userNum']; + + Db::name('shop_scores')->where('shopId',$shopId)->update($data); + + + + } + + + +} + diff --git a/hyhproject/admin/model/GoodsCats.php b/hyhproject/admin/model/GoodsCats.php new file mode 100755 index 0000000..60283e0 --- /dev/null +++ b/hyhproject/admin/model/GoodsCats.php @@ -0,0 +1,619 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 商品分类业务处理 + + */ + +use think\Db; + +class GoodsCats extends Base{ + + /** + + * 获取树形分类 + + */ + + public function pageQuery(){ + + return $this->where(['dataFlag'=>1,'parentId'=>input('catId/d',0)])->order('catSort asc,catId desc')->paginate(1000)->toArray(); + + } + + /** + + * 获取列表 + + */ + + public function listQuery($parentId){ + + return $this->where(['dataFlag'=>1,'parentId'=>$parentId])->order('catSort asc,catName asc')->select(); + + } + + + + /** + + *获取商品分类名值对 + + */ + + public function listKeyAll(){ + + $rs = $this->field("catId,catName")->where(['dataFlag'=>1])->order('catSort asc,catName asc')->select(); + + $data = array(); + + foreach ($rs as $key => $cat) { + + $data[$cat["catId"]] = $cat["catName"]; + + } + + return $data; + + } + + + + /** + + * 获取树形分类 + + */ + + public function getTree($data, $parentId=0){ + + $arr = array(); + + foreach($data as $k=>$v) + + { + + if($v['parentId']==$parentId && $v['dataFlag']==1) + + { + + //再查找该分类下是否还有子分类 + + $v['child'] = $this->getTree($data, $v['catId']); + + //统计child + + $v['childNum'] = count($v['child']); + + //将找到的分类放回该数组中 + + $arr[]=$v; + + } + + } + + return $arr; + + } + + + + /** + + * 迭代获取下级 + + * 获取一个分类下的所有子级分类id + + */ + + public function getChild($pid){ + + $data = $this->where("dataFlag=1")->select(); + + //获取该分类id下的所有子级分类id + + $ids = $this->_getChild($data, $pid, true);//每次调用都清空一次数组 + + //把自己也放进来 + + array_unshift($ids, $pid); + + return $ids; + + } + + + + public function _getChild($data, $pid, $isClear=false){ + + static $ids = array(); + + if($isClear)//是否清空数组 + + $ids = array(); + + foreach($data as $k=>$v) + + { + + if($v['parentId']==$pid && $v['dataFlag']==1) + + { + + $ids[] = $v['catId'];//将找到的下级分类id放入静态数组 + + //再找下当前id是否还存在下级id + + $this->_getChild($data, $v['catId']); + + } + + } + + return $ids; + + } + + + + /** + + * 获取指定对象 + + */ + + public function getGoodscats($id){ + + return $this->where(['catId'=>$id])->find(); + + } + + + + /** + + * 显示是否推荐/不推荐 + + */ + + public function editiIsFloor(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + $isFloor = input('post.isFloor/d')?1:0; + + $result = $this->where("catId in(".implode(',',$ids).")")->update(['isFloor' => $isFloor]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 修改分类名称 + + */ + + public function editName(){ + + $catName = input('catName'); + + if($catName=='')return WSTReturn("操作失败,商品分类名称不能为空"); + + if(mb_strlen($catName)>20)return WSTReturn('商品分类名称不能超过20个字'.mb_strlen($catName)); + + $id = (int)input('id'); + + $result = $this->where("catId = ".$id)->update(['catName' => $catName]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + + + } + + /** + + * 修改分类排序 + + */ + + public function editOrder(){ + + $id = (int)input('id'); + + $result = $this->where("catId = ".$id)->update(['catSort' => (int)input('catSort')]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + + + } + + /** + + * 显示是否自营显示/隐藏 + + */ + + public function editiIsSelfShow(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + $isSelfShow = input('post.isSelfShow/d')?1:0; + + Db::startTrans(); + + try{ + + $result = $this->where("catId in(".implode(',',$ids).")")->update(['isSelfShow' => $isSelfShow]); + + if(false !== $result){ + + if($isSelfShow==0){ + + //删除购物车里的相关商 + + $goods = Db::name('goods g')->join('shops s','s.shopId=g.shopId')->where(["goodsCatId"=>['in',$ids],'isSale'=>1,'shopStatus'=>1,'s.isSelf'=>1])->field('goodsId')->select(); + + if(count($goods)>0){ + + $goodsIds = []; + + foreach ($goods as $key =>$v){ + + $goodsIds[] = $v['goodsId']; + + } + + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + + } + + //把相关的商品下架了 + + Db::name('goods g')->join('shops s','s.shopId=g.shopId')->where("goodsCatId in(".implode(',',$ids).") and s.isSelf=1")->update(['g.isSale' => 0]); + + + + WSTClearAllCache(); + + } + + } + + Db::commit(); + + return WSTReturn("操作成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + } + + /** + + * 显示是否显示/隐藏 + + */ + + public function editiIsShow(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + $isShow = input('post.isShow/d')?1:0; + + Db::startTrans(); + + try{ + + $result = $this->where("catId in(".implode(',',$ids).")")->update(['isShow' => $isShow]); + + if(false !== $result){ + + if($isShow==0){ + + //删除购物车里的相关商品 + + $goods = Db::name('goods g')->join('shops s','s.shopId=g.shopId')->where(["goodsCatId"=>['in',$ids],'isSale'=>1,'s.isSelf'=>0])->field('goodsId')->select(); + + if(count($goods)>0){ + + $goodsIds = []; + + foreach ($goods as $key =>$v){ + + $goodsIds[] = $v['goodsId']; + + } + + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + + } + + //把相关的商品下架了 + + Db::name('goods g')->join('shops s','s.shopId=g.shopId')->where("goodsCatId in(".implode(',',$ids).") and s.isSelf=0")->update(['g.isSale' => 0]); + + WSTClearAllCache(); + + } + + } + + Db::commit(); + + return WSTReturn("操作成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + + + } + + + + /** + + * 新增 + + */ + + public function add(){ + + $parentId = input('post.parentId/d'); + + $data = input('post.'); + + WSTUnset($data,'catId,dataFlag'); + + $data['parentId'] = $parentId; + + $data['createTime'] = date('Y-m-d H:i:s'); + + $result = $this->validate('GoodsCats.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 编辑 + + */ + + public function edit(){ + + $catId = input('post.id/d'); + + $data = input('post.'); + + WSTUnset($data,'catId,dataFlag,createTime'); + + $result = $this->validate('GoodsCats.edit')->allowField(true)->save($data,['catId'=>$catId]); + + $ids = array(); + + $ids = $this->getChild($catId); + + $this->where("catId in(".implode(',',$ids).")")->update(['isShow' => (int)$data['isShow'],'isFloor'=> $data['isFloor'],'commissionRate'=>(float)$data['commissionRate'],'payDeposit'=>(float)$data['payDeposit']]); + + if(false !== $result){ + + if($data['isShow']==0){ + + //删除购物车里的相关商品 + + $goods = Db::name('goods')->where(["goodsCatId"=>['in',$ids],'isSale'=>1])->field('goodsId')->select(); + + if(count($goods)>0){ + + $goodsIds = []; + + foreach ($goods as $key =>$v){ + + $goodsIds[] = $v['goodsId']; + + } + + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + + } + + //把相关的商品下架了 + + Db::name('goods')->where("goodsCatId in(".implode(',',$ids).")")->update(['isSale' => 0]); + + WSTClearAllCache(); + + } + + return WSTReturn("修改成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 删除 + + */ + + public function del(){ + + $ids = array(); + + $id = input('post.id/d'); + + $ids = $this->getChild($id); + + Db::startTrans(); + + try{ + + $data = []; + + $data['dataFlag'] = -1; + + $result = $this->where(['catId'=>['in',$ids]])->update($data); + + if(false !== $result){ + + //删除购物车里的相关商品 + + $goods = Db::name('goods')->where(["goodsCatId"=>['in',$ids],'isSale'=>1])->field('goodsId')->select(); + + if(count($goods)>0){ + + $goodsIds = []; + + foreach ($goods as $key =>$v){ + + $goodsIds[] = $v['goodsId']; + + } + + Db::name('carts')->where(['goodsId'=>['in',$goodsIds]])->delete(); + + } + + //删除商品属性 + + Db::name('attributes')->where("goodsCatId in(".implode(',',$ids).")")->update(['dataFlag'=>-1]); + + //删除商品规格 + + Db::name('spec_cats')->where("goodsCatId in(".implode(',',$ids).")")->update(['dataFlag'=>-1]); + + //把相关的商品下架了 + + Db::name('goods')->where("goodsCatId in(".implode(',',$ids).")")->update(['isSale' => 0]); + + WSTClearAllCache(); + + } + + Db::commit(); + + return WSTReturn("删除成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + + + /** + + * 根据子分类获取其父级分类 + + */ + + public function getParentIs($id,$data = array()){ + + $data[] = $id; + + $parentId = $this->where('catId',$id)->value('parentId'); + + if($parentId==0){ + + krsort($data); + + return $data; + + }else{ + + return $this->getParentIs($parentId, $data); + + } + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/GoodsClassify.php b/hyhproject/admin/model/GoodsClassify.php new file mode 100755 index 0000000..deba37b --- /dev/null +++ b/hyhproject/admin/model/GoodsClassify.php @@ -0,0 +1,877 @@ +<?php + +namespace wstmart\admin\model; + +use think\Validate; + +/** + + * ============================================================================ + + * 商品分类业务处理 + + */ + +use think\Db; + +class GoodsClassify extends Base{ + + /** + + * 获取树形分类 + + */ + + public function pageQuery(){ + + return Db::name('goods_classify')->order('orderby desc')->paginate(15)->toArray(); + + } + + + +/** + + * 获取指定对象 + + */ + + public function getById($goodsclassifyId){ + + $obj = null; + + if($goodsclassifyId>0){ + + $obj = Db::name('goods_classify')->where(['goodsclassifyId'=>$goodsclassifyId])->find(); + + }else{ + + $obj = self::getEModel("goods_classify"); + + } + + return $obj; + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['create_time'] = date('Y-m-d H:i:s'); + + $validate = Validate::make([ + + 'goodsclassifyName' => 'require', + + ]); + + $msg = [ + + 'goodsclassifyName.require' => '商品总名称不能为空', + + ]; + + + + $info = [ + + 'goodsclassifyName' => $data['goodsclassifyName'], + + ]; + + if (!$validate->check($info)) { + + return WSTReturn ($validate->getError()); + + } + + $find=$this->where('goodsclassifyName',$data['goodsclassifyName'])->find(); + + if($find) return WSTReturn('此总分类名称已存在'); + + $result = $this->allowField(true)->save($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 编辑 + + */ + + public function edit(){ + + $goodsclassifyId = input('post.goodsclassifyId/d'); + + $data = input('post.'); + + $result=$this->allowField(true)->save($data,['goodsclassifyId'=>$goodsclassifyId]); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.goodsclassifyId/d'); + + $see=db('cat_classify')->where('classifyId',$id)->find(); + + $recom=db('recom_classify')->where('classifyId',$id)->find(); + + if($see!==NUll) return WSTReturn ('商品有子分类,不能删除'); + + if($recom) return WSTReturn ('此商品分类有活动,不能删除'); + + $result=$this->where('goodsclassifyId',$id)->delete(); + + if($result!=false){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn('删除失败',-1); + + } + + } + + + + /** + + * 获取指定对象 + + */ + + public function getByIds($catId){ + + $obj = null; + + if($catId>0){ + + $obj = Db::name('cat_classify')->where(['catId'=>$catId])->find(); + + }else{ + + $obj = self::getEModel("cat_classify"); + + } + + return $obj; + + } + + // 添加商品分类 + + public function add_cat(){ + + $data=input('post.'); + + $result = db('cat_classify')->insert($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn("新增失败",-1); + + } + + } + + //获取商品分类 + + public function catdetail(){ + + $id=input('goodsclassifyId'); + + $result=db('cat_classify')->where('classifyId',$id)->field('catId')->select(); + + return $result; + + } + + //获取商品分类列表 + + public function catdetailPage(){ + + $id=input('classifyId'); + + $pagesize = input('limit/d'); + + $result=db('cat_classify')->alias('a') + + ->join('goods_cats g','g.catId=a.catId','left') + + ->where('classifyId',$id)->field('g.catName,createTime,a.catId') + + ->paginate($pagesize)->toArray(); + + return $result; + + } + + /** + + * 删除商品分类 + + */ + + public function catdel(){ + + $catId = input('catId'); + + $classifyId = input('classifyId'); + + $result=db('cat_classify')->where(['catId'=>$catId,'classifyId'=>$classifyId])->delete(); + + if($result!=false){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn('删除失败',-1); + + } + + } + + /* + + 详情 + + */ + + public function detail(){ + + $id=input('catId'); + + $result=db('cat_classify')->where('catId',$id)->field('catId')->select(); + + return $result; + + } + + //详情分页 + + public function detailByPage(){ + + $catId=input('catId'); + + $pagesize = input('limit/d'); + + $get_child=$this->getChild('',$catId); + + $goods_result=db('goods')->alias('a')->join('shops s','s.shopId=a.shopId','left') + + ->whereIn('goodsCatId',$get_child)->order('saleNum desc') + + ->where(['isSale'=>1,'a.dataFlag'=>1,'a.goodsStatus'=>1,'isHot'=>1]) + + ->field('goodsId,goodsName,goodsImg,shopPrice,saleNum,goodsSn,s.shopName,a.shopId,goodsCatIdPath') + + ->paginate($pagesize)->toArray(); + + $keyCats = model('GoodsCats')->listKeyAll(); + + foreach ($goods_result['Rows'] as $key => $v){ + + $goods_result['Rows'][$key]['verfiycode'] = WSTShopEncrypt($v['shopId']); + + $goods_result['Rows'][$key]['goodsCatName'] = self::getGoodsCatNames($v['goodsCatIdPath'],$keyCats); + + } + + return $goods_result; + + } + + + + public function getGoodsCatNames($goodsCatPath, $keyCats){ + + $catIds = explode("_",$goodsCatPath); + + $catNames = array(); + + for($i=0,$k=count($catIds);$i<$k;$i++){ + + if($catIds[$i]=='')continue; + + if(isset($keyCats[$catIds[$i]]))$catNames[] = $keyCats[$catIds[$i]]; + + } + + return implode("→",$catNames); + + } + + /** + + * 迭代获取下级 + + * 获取一个分类下的所有子级分类id + + */ + + public function getChild($data,$pid){ + + $childId = db('goods_cats')->where("dataFlag=1")->where('parentId',$pid)->field('catId,parentId')->select(); + + //获取该分类id下的所有子级分类id + + foreach($childId as $key=>$value){ + + $child[]=$value['catId']; + + } + + static $ids = array(); + + foreach($childId as $k=>$v){ + + //dump($childId); + + $ids[] = $v['catId'];//将找到的下级分类id放入静态数组 + + //再找下当前id是否还存在下级id + + $this->getChild($childId, $v['catId']); + + } + + return $ids; + + } + + //活动详情分页 + + public function setdetailPage(){ + + $recomId=input('recomId'); + + $goodsId=input('goodsId'); + + $where=[]; + + //dump($recomId); + + if($recomId)$where['rg.recomId'] = $recomId; + + if($goodsId)$where['rg.goodsId'] = ['like','%'.$goodsId.'%']; + + $classifyId=input('classifyId'); + + $pagesize = input('limit/d'); + + $goods_result=db('recom_classify')->alias('rc') + + ->join('recom_goods rg','rg.recomId =rc.recomId','left') + + ->join('goods a','a.goodsId=rg.goodsId','left') + + ->where(['isSale'=>1,'a.dataFlag'=>1,'a.goodsStatus'=>1,'rc.classifyId'=>$classifyId])->where($where) + + ->field('recomGoodsId,a.goodsId,a.goodsName,goodsImg,rc.recomId,rc.recomName,rg.goodsOrder,from_unixtime(rg.createTime)createTime,a.shopPrice') + + ->order('goodsOrder desc') + + ->paginate($pagesize)->toArray(); + + return $goods_result; + + } + + //更改活动商品的排序号 + + public function changeSet(){ + + $id=(int)input('id'); + + $goodsOrder=(int)input('goodsOrder'); + + $result=db('recom_goods')->where('recomGoodsId',$id)->update(['goodsOrder'=>$goodsOrder]); + + if($result!==false){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn("新增失败",-1); + + } + + } + + //活动详情分页 + + public function recomPage(){ + + $classifyId=input('classifyId'); + + $goodsId=(int)input('goodsId'); + + $where=[]; + + if($goodsId)$where['ra.goodsId'] = ['like','%'.$goodsId.'%']; + + $pagesize = input('limit/d'); + + $goods_result=db('recom_active')->alias('ra') + + ->join('goods a','a.goodsId=ra.goodsId','left') + + ->where(['isSale'=>1,'a.dataFlag'=>1,'a.goodsStatus'=>1,'ra.classifyId'=>$classifyId])->where($where) + + ->field('recomActiveId,a.goodsId,a.goodsName,goodsImg,ra.goodsOrder,from_unixtime(ra.createTime)createTime,a.shopPrice') + + ->order('goodsOrder desc') + + ->paginate($pagesize)->toArray(); + + return $goods_result; + + } + + //更改活动商品的排序号 + + public function changeRecom(){ + + $id=(int)input('id'); + + $goodsOrder=(int)input('goodsOrder'); + + $result=db('recom_active')->where('recomActiveId',$id)->update(['goodsOrder'=>$goodsOrder]); + + if($result!==false){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn("新增失败",-1); + + } + + } + + //删除推荐商品 + + public function recomActiveDel(){ + + $recomGoodsId=input('recomActiveId'); + + $result=db('recom_active')->where('recomActiveId',$recomGoodsId)->delete(); + + if($result!=false){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn('删除失败',-1); + + } + + } + + /** + + * 获取指定对象 + + */ + + public function getrecomActiveId($recomActiveId){ + + $obj = null; + + if($recomActiveId>0){ + + $obj = Db::name('recom_active')->where(['recomActiveId'=>$recomActiveId])->find(); + + }else{ + + $obj = self::getEModel("recom_active"); + + } + + return $obj; + + } + + /** + + * 新增 + + */ + + public function addrecomActive(){ + + Db::startTrans(); + + try{ + + $data=input('post.'); + + $data['createTime']=time(); + + $goodsId = trim(input('goodsId')); + + $product_id = explode(',',$goodsId); + + $arr=[]; + + foreach ($product_id as $k=>$value) { + + $goods=db('goods')->where('goodsId',$value)->where('dataFlag=1 and isSale=1 and goodsStatus=1')->find(); + + if(!$goods) return WSTReturn('无效商品 '.$value); + + $arr[$k]['goodsId'] = $value; + + $arr[$k]['classifyId'] = $data['classifyId']; + + $arr[$k]['createTime'] = $data['createTime']; + + if($arr[$k]['goodsId']=="," || $arr[$k]['goodsId']==""){ + + unset($arr[$k]); + + } + + $find=db('recom_active')->where(['goodsId'=>$arr[$k]['goodsId']])->find(); + + if($find) return WSTReturn('此商品已存在 '.$arr[$k]['goodsId']); + + } + + $result=Db::name('recom_active')->insertAll($arr); + + Db::commit(); + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + + + } + + catch(\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn("添加失败",-1); + + } + + //查看活动页活动分类 + + public function catsPage(){ + + $classifyId=input('classifyId'); + + $goods_result=db('recom_classify')->alias('rc') + + ->join('goods_classify gc','gc.goodsclassifyId=rc.classifyId','left') + + ->where('classifyId',$classifyId) + + ->field('recomId,recomName,classifyId,goodsclassifyName,recomOrder,from_unixtime(startTime) startTime,from_unixtime(endTime)endTime') + + ->order('recomOrder desc') + + ->paginate()->toArray(); + + return $goods_result; + + } + + + + /** + + * 获取指定对象 + + */ + + public function getCatsId($recomId){ + + $obj = null; + + if($recomId>0){ + + $obj = Db::name('recom_classify')->where(['recomId'=>$recomId])->find(); + + $obj['startTime']=date('Y-m-d H:i:s',$obj['startTime']); + + $obj['endTime']=date('Y-m-d H:i:s',$obj['endTime']); + + }else{ + + $obj = self::getEModel("recom_classify"); + + } + + return $obj; + + } + + // 添加商品活动分类 + + public function addCats(){ + + $data=input('post.'); + + $data['startTime']=strtotime(input('startTime')); + + $data['endTime']=strtotime(input('endTime')); + + $find=db('recom_classify')->where('recomName',$data['recomName'])->find(); + + if($find) return WSTReturn('此分类名称已存在'); + + $result = db('recom_classify')->insert($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("新增成功", 1); + + }else{ + + return WSTReturn("新增失败",-1); + + } + + } + + // 修改商品活动分类 + + public function editCats(){ + + $data=input('post.'); + + $data['startTime']=strtotime(input('startTime')); + + $data['endTime']=strtotime(input('endTime')); + + $result = db('recom_classify')->where('recomId',$data['recomId'])->update($data); + + if(false !== $result){ + + WSTClearAllCache(); + + return WSTReturn("操作成功", 1); + + }else{ + + return WSTReturn("操作失败",-1); + + } + + } + + //删除分类活动 + + public function catsDel(){ + + $recomId=input('recomId'); + + $m=input('m'); + + Db::startTrans(); + + try{ + + if($m==2){ + + db('recom_goods')->where('recomId',$recomId)->delete(); + + db('recom_classify')->where('recomId',$recomId)->delete(); + + }else{ + + $find_goods=db('recom_goods')->where('recomId',$recomId)->find(); + + if($find_goods) return WSTReturn('此分类有活动商品',2); + + db('recom_classify')->where('recomId',$recomId)->delete(); + + } + + Db::commit(); + + return WSTReturn("操作成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + /** + + * 获取指定对象 + + */ + + public function getGoodsId($recomId){ + + $obj = null; + + if($recomId>0){ + + $obj = Db::name('recom_goods')->where(['id'=>$recomId])->find(); + + }else{ + + $obj = self::getEModel("recom_goods"); + + } + + return $obj; + + } + + // 添加活动商品 + + public function addGoods(){ + + Db::startTrans(); + + try{ + + $data=input('post.'); + + $data['createTime']=time(); + + $goodsId = trim(input('goodsId')); + + $product_id = explode(',',$goodsId); + + $arr=[]; + + foreach ($product_id as $k=>$value) { + + $goods=db('goods')->where('goodsId',$value)->where('dataFlag=1 and isSale=1 and goodsStatus=1')->find(); + + if(!$goods) return WSTReturn('无效商品 '.$value); + + $arr[$k]['goodsId'] = $value; + + $arr[$k]['recomId'] = $data['recomId']; + + $arr[$k]['createTime'] = $data['createTime']; + + if($arr[$k]['goodsId']=="," || $arr[$k]['goodsId']==""){ + + unset($arr[$k]); + + } + + $find=db('recom_goods')->where(['goodsId'=>$arr[$k]['goodsId'],'recomId'=>$arr[$k]['recomId']])->find(); + + if($find) return WSTReturn('此商品已存在 '.$arr[$k]['goodsId']); + + } + + $result=Db::name('recom_goods')->insertAll($arr); + + Db::commit(); + + WSTClearAllCache(); + + return WSTReturn("添加成功", 1); + + } + + catch(\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn("添加失败",-1); + + } + + //删除分类活动商品 + + public function goodsDel(){ + + $recomGoodsId=input('recomGoodsId'); + + $result=db('recom_goods')->where('recomGoodsId',$recomGoodsId)->delete(); + + if($result!=false){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn('删除失败',-1); + + } + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/GoodsConsult.php b/hyhproject/admin/model/GoodsConsult.php new file mode 100755 index 0000000..d17868d --- /dev/null +++ b/hyhproject/admin/model/GoodsConsult.php @@ -0,0 +1,72 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 商品咨询业务处理 + */ +class GoodsConsult extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $type = (int)input('type'); + $consultKey = input('consultKey'); + $where = []; + $where['gc.dataFlag'] = 1; + // 筛选类别 + if($type>0){$where['gc.consultType'] = $type;} + // 关键字搜索 + if($consultKey!=''){$where['gc.consultContent'] = ['like',"%$consultKey%"];} + $rs = $this->alias('gc') + ->join('__GOODS__ g','g.goodsId=gc.goodsId') + ->join('__USERS__ u','u.userId=gc.userId','left') + ->field('gc.*,u.loginName,g.goodsId,g.goodsImg,g.goodsName') + ->where($where) + ->order('gc.createTime desc') + ->paginate(input('limit/d'))->toArray(); + if(!empty($rs['Rows'])){ + foreach($rs['Rows'] as $k=>&$v){ + // 解义 + $v['consultContent'] = htmlspecialchars_decode($v['consultContent']); + } + } + return $rs; + } + public function getById($id){ + return $this->alias('gc') + ->join('__GOODS__ g','gc.goodsId=g.goodsId') + ->join('__USERS__ u','gc.userId=u.userId','left') + ->field('gc.*,g.goodsImg,g.goodsId,g.goodsName,u.loginName') + ->where(['id'=>$id]) + ->find(); + } + /** + * 编辑 + */ + public function edit(){ + $Id = input('post.id/d',0); + $data = input('post.'); + WSTUnset($data,'createTime'); + $result = $this->validate('GoodsConsult.edit')->allowField(true)->save($data,['id'=>$Id]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d',0); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>$id]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/HomeMenus.php b/hyhproject/admin/model/HomeMenus.php new file mode 100755 index 0000000..0edf29a --- /dev/null +++ b/hyhproject/admin/model/HomeMenus.php @@ -0,0 +1,154 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 前台菜单业务处理 + */ +class HomeMenus extends Base{ + protected $insert = ['dataFlag'=>1]; + + /** + * 获取菜单 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'menuId'=>$id]); + } + + /** + * 新增菜单 + */ + public function add(){ + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + $data["dataFlag"] = 1; + $result = $this->validate('HomeMenus.add')->allowField(true)->save($data); + if(false !== $result){ + cache('WST_HOME_MENUS',null); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑菜单 + */ + public function edit(){ + $menuId = input('post.menuId/d',0); + $result = $this->validate('HomeMenus.edit')->allowField(['menuName','menuSort','menuType','isShow','menuUrl','menuOtherUrl'])->save(input('post.'),['menuId'=>$menuId]); + if(false !== $result){ + cache('WST_HOME_MENUS',null); + $parentId = input('post.parentId'); + if($parentId==0){ + // 获取其子集id + $ids = $this->getChildId($menuId); + $menuType = input('post.menuType/d'); + $result = $this->where(['menuId'=>['in',$ids],"dataFlag"=>1])->setField("menuType", $menuType); + } + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除菜单 + */ + public function del(){ + $menuId = input('post.menuId/d',0); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['menuId'=>$menuId]); + $this->update($data,['parentId'=>$menuId]); + if(false !== $result){ + cache('WST_HOME_MENUS',null); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 分页 + */ + public function pageQuery(){ + $where = []; + $menuType = (int)input('menuType',-1); + if($menuType!=-1)$where['a.menuType'] = $menuType; + $where['a.parentId'] = (int)input('menuId',0); + $where['a.dataFlag'] = 1; + $rs = $this->alias('a')->join('__HOME_MENUS__ b','a.parentId = b.menuId','left') + ->field("a.menuId,a.menuType, a.parentId, a.menuName, a.menuUrl, a.menuOtherUrl, a.isShow, a.menuSort, b.menuName parentName") + ->where($where) + ->order('a.menuSort asc') + ->paginate(1000); + return $rs; + } + + /** + * 显示隐藏 + */ + public function setToggle(){ + $menuId = input('post.menuId',0); + // 获取其子集id + $ids = $this->getChildId($menuId); + $isShow = input('post.isShow/d'); + $result = $this->where(['menuId'=>['in',$ids],"dataFlag"=>1])->setField("isShow", $isShow); + if(false !== $result){ + cache('WST_HOME_MENUS',null); + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取子集id + */ + private function getChildId($mId){ + $data = $this->field('menuId,parentId')->where('dataFlag=1')->select(); + $ids = $this->_getChildId($data,$mId,true); + $ids[]=(int)$mId; + return $ids; + } + private function _getChildId($data,$pId,$isClear=false){ + static $ids = []; + if($isClear)$ids=[]; + foreach($data as $k=>$v){ + if($v['parentId']==$pId){ + $ids[] = $v['menuId']; + $this->_getChildId($data,$v['menuId']); + } + } + return $ids; + } + + + /** + * 获取菜单列表 + */ + public function getMenus($parentId = -1){ + $rs = $this->where(['parentId'=>$parentId,'dataFlag'=>1])->field('menuId, parentId, menuName, menuUrl,menuOtherUrl')->order('menuSort', 'asc')->select(); + if(count($rs)>0){ + foreach ($rs as $key =>$v){ + $children = self::getMenus($rs[$key]['menuId']); + if(!empty($children)){ + $rs[$key]["children"] = $children; + } + } + }; + return $rs; + } + + /** + * 修改排序 + */ + public function changeSort(){ + $id = (int)input('id'); + $menuSort = (int)input('menuSort'); + $rs = $this->where('menuId',$id)->setField('menuSort',$menuSort); + if($rs!==false){ + cache('WST_HOME_MENUS',null); + return WSTReturn('修改成功',1); + } + return WSTReturn('修改失败',-1); + } +} diff --git a/hyhproject/admin/model/Hooks.php b/hyhproject/admin/model/Hooks.php new file mode 100755 index 0000000..f448db0 --- /dev/null +++ b/hyhproject/admin/model/Hooks.php @@ -0,0 +1,43 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 钩子业务处理 + */ +class Hooks extends Base{ + + /** + * 获取插件列表 + * @param string $addon_dir + */ + public function pageQuery(){ + + $keyWords = input("keyWords"); + $parentId = input('parentId/d',0); + $where = array(); + $where["name"] = array("like","%$keyWords%"); + $page = $this->where($where)->order('`name` asc')->paginate(input('post.limit/d'))->toArray(); + + return $page; + + } + + /** + * 保存插件设置 + */ + public function saveConfig(){ + $id = input("id/d",0); + $config = $_POST['config']; + $flag = $this->where(["addonId"=>$id])->setField('config',json_encode($config)); + if($flag !== false){ + return WSTReturn("保存成功", 1); + }else{ + return WSTReturn('保存失败',-1); + } + } + + + + +} diff --git a/hyhproject/admin/model/Images.php b/hyhproject/admin/model/Images.php new file mode 100755 index 0000000..767f80b --- /dev/null +++ b/hyhproject/admin/model/Images.php @@ -0,0 +1,228 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 图片空间业务处理 + + */ + +use wstmart\common\model\Aliyunoss; + +use think\Db; + +class Images extends Base{ + + /** + + * 获取图片空间概况 + + */ + + public function summary(){ + + $rs = Db::name('images')->where(['dataFlag'=>1])->field('fromTable,isUse,sum(imgSize) imgSize')->group('fromTable,isUse') + + ->order('fromTable asc')->select(); + + //获取目录名称 + + $rs2 = Db::name('datas')->where(['catId'=>3])->field('dataName,dataVal')->select(); + + $imagesMap = []; + + foreach ($rs2 as $key =>$v){ + + $imagesMap[$v['dataVal']] = $v['dataName']; + + } + + $images = []; + + foreach ($rs as $key =>$v){ + + if(!isset($images[$v['fromTable']]))$images[$v['fromTable']] = ['directory'=>'','data'=>['0'=>0,'1'=>0]]; + + if(isset($imagesMap[$v['fromTable']]))$images[$v['fromTable']]['directory'] = $imagesMap[$v['fromTable']]; + + $images[$v['fromTable']]['data'][$v['isUse']] = round($v['imgSize']/1024/1024,2); + + } + + $maxSize = 0; + + foreach ($images as $key =>$v){ + + $size = (float)$v['data']['0']+(float)$v['data']['1']; + + if($maxSize<$size)$maxSize = $size; + + } + + $images['_WSTSummary_'] = $maxSize; + + return $images; + + } + + /** + + * 获取记录 + + */ + + public function pageQuery(){ + + $key = input('keyword'); + + $isUse = (int)input('isUse'); + + $where = ['fromTable'=>$key,'a.dataFlag'=>1]; + + if($isUse !=-1)$where['isUse'] = $isUse; + + $page = $this->alias('a')->join('__USERS__ u','a.ownId=u.userId and fromType=0','left') + + ->join('__SHOPS__ s','s.userId=u.userId','left') + + ->join('__STAFFS__ sf','sf.staffId=a.ownId','left') + + ->where($where)->field('a.imgId,u.loginName,u.userType,fromType,sf.loginName loginName2,s.shopName,imgPath,imgSize,isUse,a.createTime') + + ->order('a.imgId desc')->paginate(input('post.limit/d'))->toArray(); + + foreach ($page['Rows'] as $key => $v){ + + if($v['fromType']==1){ + + $page['Rows'][$key]['loginName'] = $v['loginName2']; + + } + + $page['Rows'][$key]['imgSize'] = round($v['imgSize']/1024/1024,2); + + unset($page['Rows'][$key]['loginName2']); + + } + + return $page; + + } + + /** + + * 删除图片 + + */ + + public function del(){ + + $id = (int)input('id'); + + $image = $this->where('imgId',$id)->find(); + + $rs = $this->where('imgId',$id)->update(['dataFlag'=>-1]); + + if(false !== $rs){ + + $m = WSTConf('CONF.wstMobileImgSuffix'); + + $timgPath = str_replace('.','_thumb.',$image['imgPath']); + + $mimgPath = str_replace('.',$m.'.',$image['imgPath']); + + $mtimgPath = str_replace('.',$m.'_thumb.',$image['imgPath']); + + + + if(file_exists(WSTRootPath()."/".$image['imgPath']))unlink(WSTRootPath()."/".$image['imgPath']); + + if(file_exists(WSTRootPath()."/".$timgPath))unlink(WSTRootPath()."/".$timgPath); + + if(file_exists(WSTRootPath()."/".$mimgPath))unlink(WSTRootPath()."/".$mimgPath); + + if(file_exists(WSTRootPath()."/".$mtimgPath))unlink(WSTRootPath()."/".$mtimgPath); + + //添加删除oss上的图片 mark 20180608 + + $imgurl = getImgUrl().$image['imgPath']; + + if(file_exists_oss($image['imgPath']))model('Aliyunoss')->del($image['imgPath']); + + return WSTReturn("删除成功", 1); + + } + + return WSTReturn("删除失败"); + + } + + //添加判断文件是否存在 mark 20180608 by zl + + // public function file_exists_oss($object){ + + // $imgurl = getImgUrl().$object; + + // $ch = curl_init(); + + // $timeout = 10; + + // curl_setopt ($ch, CURLOPT_URL, $imgurl); + + // curl_setopt($ch, CURLOPT_HEADER, 1); + + // curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); + + // curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + + + + // $contents = curl_exec($ch); + + // if (preg_match("/404/", $contents)){ + + // return false; + + // }else{ + + // return true; + + // } + + + + // //说是在windows下可以,LINUX下无论图片在不在都返加TRUE + + // // if(file_get_contents($imgurl,0,null,0,1)){ + + // // return true; + + // // }else{ + + // // return false; + + // // } + + + + // // if(@fopen( $imgurl, 'r' )){ + + // // return true; + + // // }else{ + + // // return false; + + // // } + + + + + + // } + +} + diff --git a/hyhproject/admin/model/Index.php b/hyhproject/admin/model/Index.php new file mode 100755 index 0000000..a0bf733 --- /dev/null +++ b/hyhproject/admin/model/Index.php @@ -0,0 +1,109 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 系统业务处理 + */ +class Index extends Base{ + /** + * 获取基础统计信息 + */ + public function summary(){ + $data = []; + $m = Model('common/Table'); + + $m->setTable('sys_summary'); + $toPayInfo = $m->getInfo(['id'=>1],'toPayFast,toPaySlow'); + $data['qlg']['fastPay'] = $toPayInfo['toPayFast']; + $data['qlg']['slowPay'] = $toPayInfo['toPaySlow']; + //预代付值 + $m->setTable('user_vouchers_summary'); + $data['qlg']['vouchersSummarySum'] = $m->getSum(['isDisabled'=>0],'expectedProductNum+expectedCouponsNum'); + //个体认证数 + $m->setTable('users'); + $data['qlg']['personalCount'] = $m->getCount(['authType'=>1]); + //合作认证数 + $data['qlg']['companyCount'] = $m->getCount(['authType'=>2]); + //合作商数 + $m->setTable('user_update'); + $data['qlg']['updateCount'] = $m->getCount(['status'=>1]); + //已上线店铺数 + $m->setTable('shops'); + $data['qlg']['shopCount'] = $m->getCount(['status'=>1,'dataFlag'=>1]); + //已消费用户数 + $data['qlg']['payCount'] = Db::name('orders')->where(['orderStatus'=>['BETWEEN','0,2']])->group('userId')->count(); + //已完成订单总额 + $m->setTable('orders'); + //$data['qlg']['orderSum'] = $m->getSum(['orderStatus'=>['BETWEEN','0,2']],'realTotalMoney'); + $data['qlg']['orderSum'] = $m->getSum(['orderStatus'=>2],'realTotalMoney'); + //个体待审核 + $m->setTable('auth_personal'); + $data['qlg']['personalWaitCount'] = $m->getCount(['status'=>0]); + //合作待审核 + $m->setTable('auth_company'); + $data['qlg']['companyWaitCount'] = $m->getCount(['status'=>0]); + //合作商待审核 + $m->setTable('user_update'); + $data['qlg']['updateWaitCount'] = $m->getCount(['status'=>0]); + //产品券抵现 + $m->setTable('orders'); + $data['qlg']['productSum'] = $m->getSum(['orderStatus'=>['BETWEEN','0,2']],'productNum-productHandlingFee-productTaxFee'); + //优惠券抵现 + $data['qlg']['couponsSum'] = $m->getSum(['orderStatus'=>['BETWEEN','0,2']],'couponsNum-couponsHandlingFee-couponsTaxFee'); + //旺旺券抵现 + $data['qlg']['wangSum'] = $m->getSum(['orderStatus'=>['BETWEEN','0,2']],'wangNum'); + + //今日统计 + $data['tody'] = ['userType0'=>0,'userType1'=>0]; + $rs = Db::name('users')->where(['createTime'=>['like',date('Y-m-d').'%'],'dataFlag'=>1])->group('userType')->field('userType,count(userId) counts')->select(); + $tmp = []; + if(!empty($rs)){ + foreach ($rs as $key => $v){ + $tmp[$v['userType']] = $v['counts']; + } + } + if(isset($tmp['0']))$data['tody']['userType0'] = $tmp['0']; + if(isset($tmp['1']))$data['tody']['userType1'] = $tmp['1']; + $data['tody']['shopApplys'] = Db::name('shops')->whereTime('createTime','today')->where(['dataFlag'=>1,'status'=>0])->count(); + $data['tody']['compalins'] = Db::name('order_complains')->where(['complainTime'=>['like',date('Y-m-d').'%']])->count(); + $data['tody']['saleGoods'] = Db::name('goods')->where(['dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1,'createTime'=>['like',date('Y-m-d').'%']])->count(); + $data['tody']['auditGoods'] = Db::name('goods')->where(['dataFlag'=>1,'goodsStatus'=>0,'isSale'=>1,'createTime'=>['like',date('Y-m-d').'%']])->count(); + $data['tody']['order'] = Db::name('orders')->where(['dataFlag'=>1,'createTime'=>['like',date('Y-m-d').'%']])->count(); + //商城统计 + $data['mall'] = ['userType0'=>1,'userType1'=>0]; + $rs = Db::name('users')->where(['dataFlag'=>1])->group('userType')->field('userType,count(userId) counts')->select(); + $tmp = []; + if(!empty($rs)){ + foreach ($rs as $key => $v){ + $tmp[$v['userType']] = $v['counts']; + } + } + if(isset($tmp['0']))$data['mall']['userType0'] = $tmp['0']; + if(isset($tmp['1']))$data['mall']['userType1'] = $tmp['1']; + $data['mall']['saleGoods'] = Db::name('goods')->where(['dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1])->count(); + $data['mall']['auditGoods'] = Db::name('goods')->where(['dataFlag'=>1,'goodsStatus'=>0,'isSale'=>1])->count(); + $data['mall']['order'] = Db::name('orders')->where(['dataFlag'=>1])->count(); + $data['mall']['brands'] = Db::name('brands')->where(['dataFlag'=>1])->count(); + $data['mall']['appraise'] = Db::name('goods_appraises')->where(['dataFlag'=>1])->count(); + $rs = Db::query('select VERSION() as sqlversion'); + $data['MySQL_Version'] = $rs[0]['sqlversion']; + $data['time']['startDate'] = date('Y-m-d',strtotime("-1month")); + $data['time']['endDate'] = date('Y-m-d'); + return $data; + } + + /** + * 保存授权码 + */ + public function saveLicense(){ + $data = []; + $data['fieldValue'] = input('license'); + $result = model('SysConfigs')->where('fieldCode','mallLicense')->update($data); + if(false !== $result){ + cache('WST_CONF',null); + return WSTReturn("操作成功",1); + } + return WSTReturn("操作失败"); + } +} \ No newline at end of file diff --git a/hyhproject/admin/model/Informs.php b/hyhproject/admin/model/Informs.php new file mode 100755 index 0000000..9f83f55 --- /dev/null +++ b/hyhproject/admin/model/Informs.php @@ -0,0 +1,270 @@ +<?php + +namespace wstmart\admin\model; + +use wstmart\admin\model\Goods as M; + +use think\Db; + +/** + + * ============================================================================ + + * 订单投诉业务处理 + + */ + +class Informs extends Base{ + + /** + + * 获取举报列表 + + */ + + public function pageQuery(){ + + $informStatus = (int)Input('informStatus',-1); + + if($informStatus>-1)$where['o.informStatus']=$informStatus; + + $where['o.dataFlag']=1; + + $order = []; + + $rs = Db::name('informs')->alias('o') + + ->field('o.*,s.shopId,s.shopName,u.userName,u.loginName,oc.goodsImg,oc.goodsId,oc.goodsName') + + ->join('__SHOPS__ s','o.shopId=s.shopId','inner','left') + + ->join('__USERS__ u','o.informTargetId=u.userId','inner') + + ->join('__GOODS__ oc','oc.goodsId=o.goodId','inner') + + ->where($where) + + ->order('informId desc') + + ->paginate() + + ->toArray(); + + $reason = WSTDatas('INFORMS_TYPE'); + + for($i=1;$i<=count($reason);$i++){ + + for($j=0;$j<count($rs['Rows']);$j++) + + if($rs['Rows'][$j]['informType'] == $i){ + + $rs['Rows'][$j]['informType'] = $reason[$i]['dataName']; + + } + + } + + return $rs; + + } + + + + /** + + * 获取举报信息 + + */ + + public function getDetail(){ + + $informId = (int)Input('cid'); + + $data = $this->alias('oc') + + ->join('__SHOPS__ s','oc.shopId=s.shopId','inner','left') + + ->join('__USERS__ u','oc.informTargetId=u.userId','inner') + + ->where("oc.informId=$informId") + + ->find(); + + if($data){ + + if($data['informAnnex']!='')$data['informAnnex'] = explode(',',$data['informAnnex']); + + $data['userName'] = ($data['userName']=='')?$data['loginName']:$data['userName']; + + + + } + + return $data; + + } + + + + + + + + /** + + * 处理 + + */ + + public function finalHandle(){ + + $rd = array('status'=>-1,'msg'=>'无效的举报信息'); + + $informId = (int)Input('cid'); + + $finalResult = Input('finalResult'); + + $informStatus = Input('informStatus'); + + if($informId==0){ + + return WSTReturn('无效的举报信息',-1); + + } + + //判断是否已经处理过了 + + $rs = Db::name('informs')->alias('oc') + + ->field('oc.informTargetId,oc.informStatus,oc.goodId,oc.shopId,oc.informTargetId') + + ->where("oc.informId=$informId") + + ->find(); + + if($informStatus == 3){ + + try{ + + $data['isInform'] = 0; + + $ers = Db::name('informs')->where('informTargetId='.$rs['informTargetId'])->delete(); + + $res = Db::name('users')->where('userId='.$rs['informTargetId'])->update($data); + + if($ers!==false){ + + //发站内用户信息提醒 + + WSTSendMsg($rs['informTargetId'],"由于您被检验出恶意举报,您所有未处理举报商品已被取消并且已被禁止举报!",['from'=>3,'dataId'=>$informId]); + + Db::commit(); + + return WSTReturn('操作成功',2); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + } + + if($rs['informStatus']!=1 && $rs['informStatus']!=2){ + + if($informStatus == 2){ + + $m = new M(); + + $m->illegal($rs['goodId'],1); + + } + + $data = array(); + + $data['finalHandleStaffId'] = session('WST_STAFF.staffId'); + + $data['informStatus'] = $informStatus; + + $data['respondContent'] = Input('finalResult'); + + $data['finalHandleTime'] = date('Y-m-d H:i:s'); + + Db::startTrans(); + + try{ + + $ers = Db::name('informs')->where('informId='.$informId)->update($data); + + if($ers!==false){ + + //发站内商家信息提醒 + + $shopId = $rs["shopId"]; + + $tpl = WSTMsgTemplates('SHOP_GOODS_INFORM'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + $goodId = $rs['goodId']; + + $goods = Db::name("goods")->where(["goodsId"=>$goodId])->field("goodsName")->find(); + + $find = ['${GOODS}']; + + $replace = [$goods['goodsName']]; + + + + $msg = array(); + + $msg["shopId"] = $shopId; + + $msg["tplCode"] = $tpl["tplCode"]; + + $msg["msgType"] = 1; + + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + + $msg["msgJson"] = ['from'=>3,'dataId'=>$informId]; + + model("common/MessageQueues")->add($msg); + + } + + + + //发站内用户信息提醒 + + WSTSendMsg($rs['informTargetId'],"您举报的商品已有回复,请查看违规举报详情。",['from'=>3,'dataId'=>$informId]); + + Db::commit(); + + return WSTReturn('操作成功',1); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + }else{ + + return WSTReturn('操作失败,该举报状态已发生改变,请刷新后重试!',-1); + + } + + + + } + +} + diff --git a/hyhproject/admin/model/LogMoneys.php b/hyhproject/admin/model/LogMoneys.php new file mode 100755 index 0000000..04dd168 --- /dev/null +++ b/hyhproject/admin/model/LogMoneys.php @@ -0,0 +1,108 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 资金流水日志业务处理 + */ +class LogMoneys extends Base{ + /** + * 用户资金列表 + */ + public function pageQueryByUser(){ + $key = input('key'); + $where = []; + // 排序 + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order[$sortArr[0]] = $sortArr[1]; + } + $where['dataFlag'] = 1; + $where['loginName'] = ['like','%'.$key.'%']; + return model('users')->where($where)->field('loginName,userId,userName,userMoney,lockMoney')->order($order)->paginate(input('limit/d')); + } + /** + * 商家资金列表 + */ + public function pageQueryByShop(){ + $key = input('key'); + $where = []; + $where['u.dataFlag'] = 1; + $where['s.dataFlag'] = 1; + $where['loginName'] = ['like','%'.$key.'%']; + return Db::name('shops')->alias('s')->join('__USERS__ u','s.userId=u.userId','inner')->where($where)->field('loginName,shopId,shopName,shopMoney,s.lockMoney')->paginate(input('limit/d')); + } + + /** + * 获取用户信息 + */ + public function getUserInfoByType(){ + $type = (int)input('type',0); + $id = (int)input('id'); + $data = []; + if($type==1){ + $data = Db::name('shops')->alias('s')->join('__USERS__ u','s.userId=u.userId','inner')->where('shopId',$id)->field('shopId as userId,shopName as userName,loginName,1 as userType')->find(); + }else{ + $data = model('users')->where('userId',$id)->field('loginName,userId,userName,0 as userType')->find(); + } + return $data; + } + + /** + * 分页 + */ + public function pageQuery(){ + $userType = input('type'); + $userId = input('id'); + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = []; + if($startDate!='')$where['createTime'] = ['>=',$startDate." 00:00:00"]; + if($endDate!='')$where[' createTime'] = ['<=',$endDate." 23:59:59"]; + $where['targetType'] = $userType; + $where['targetId'] = $userId; + $page = $this->where($where)->order('id', 'desc')->paginate(input('limit/d'))->toArray(); + if(count($page['Rows'])>0){ + foreach ($page['Rows'] as $key => $v) { + $page['Rows'][$key]['dataSrc'] = WSTLangMoneySrc($v['dataSrc']); + } + } + return $page; + } + + /** + * 新增记录 + */ + public function add($log){ + $log['createTime'] = date('Y-m-d H:i:s'); + $this->create($log); + //dump($log); + if($log['moneyType']==1){ + if($log['targetType']==1){ + if($log['payType']==='ect'){ + ectLog($log['targetId'],$log['money'],12,'结算',['userECT'=>['exp','userECT+'.$log['money']]],1); + }else { + Db::name('shops')->where(["shopId" => $log['targetId']])->setInc('shopMoney', $log['money']); + } + }else{ + if($log['payType']==='ect'){ + ectLog($log['targetId'],$log['money'],13,'退款',['userECT'=>['exp','userECT+'.$log['money']]],1); + }else{ + Db::name('users')->where(["userId"=>$log['targetId']])->setInc('userMoney',$log['money']); + } + } + }else{ + if($log['targetType']==1){ + Db::name('shops')->where(["shopId"=>$log['targetId']])->setDec('shopMoney',$log['money']); + }else{ + if($log['payType']==='ect'){ + ectLog($log['targetId'],$log['money'],11,'购物',['userECT'=>['exp','userECT-'.$log['money']]],2); + }else{ + Db::name('users')->where(["userId"=>$log['targetId']])->setDec('userMoney',$log['money']); + } + } + } + } +} diff --git a/hyhproject/admin/model/LogOperates.php b/hyhproject/admin/model/LogOperates.php new file mode 100755 index 0000000..0189a11 --- /dev/null +++ b/hyhproject/admin/model/LogOperates.php @@ -0,0 +1,51 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 操作日志业务处理 + */ +class LogOperates extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = []; + if($startDate!='')$where['l.operateTime'] = ['>=',$startDate." 00:00:00"]; + if($endDate!='')$where[' l.operateTime'] = ['<=',$endDate." 23:59:59"]; + return $mrs = Db::name('log_operates')->alias('l')->join('__STAFFS__ s',' l.staffId=s.staffId','left') + ->join('__MENUS__ m',' l.menuId=m.menuId','left') + ->where($where) + ->field('l.*,s.staffName,m.menuName') + ->order('l.operateId', 'desc')->paginate(input('limit/d')); + + } + + /** + * 新增操作权限 + */ + public function add($param){ + $data = []; + $data['staffId'] = (int)session('WST_STAFF.staffId'); + $data['operateTime'] = date('Y-m-d H:i:s'); + $data['menuId'] = $param['menuId']; + $data['operateDesc'] = $param['operateDesc']; + $data['content'] = $param['content']; + $data['operateUrl'] = $param['operateUrl']; + $data['operateIP'] = $param['operateIP']; + $this->create($data); + } + + /** + * 获取指定的操作记录 + */ + public function getById($id){ + $rs = $this->get($id); + if(!empty($rs)){ + return WSTReturn('', 1,$rs); + } + return WSTReturn('对不起,没有找到该记录', -1); + } +} diff --git a/hyhproject/admin/model/LogSms.php b/hyhproject/admin/model/LogSms.php new file mode 100755 index 0000000..67e9ac8 --- /dev/null +++ b/hyhproject/admin/model/LogSms.php @@ -0,0 +1,41 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 短信日志类 + */ +class LogSms extends Base{ + + /** + * 写入并发送短讯记录 + */ + public function sendSMS($smsSrc,$userId,$phoneNumber,$params,$smsFunc){ + if((int)WSTConf('CONF.smsOpen')==0)return WSTReturn('未开启短信接口'); + $data = []; + $data['smsSrc'] = $smsSrc; + $data['smsUserId'] = $userId; + $data['smsPhoneNumber'] = $phoneNumber; + $data['smsContent'] = 'N/A'; + $data['smsReturnCode'] = ''; + $data['smsFunc'] = $smsFunc; + $data['smsIP'] = request()->ip(); + $data['createTime'] = date('Y-m-d H:i:s'); + $this->data($data)->save(); + $rdata = ['msg'=>'短信发送失败!','status'=>-1]; + hook('sendSMS',['phoneNumber'=>$phoneNumber,"params"=>$params,'smsId'=>$this->smsId,'status'=>&$rdata]); + return $rdata; + } + + public function pageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = []; + if($startDate!='')$where['l.createTime'] = ['>=',$startDate." 00:00:00"]; + if($endDate!='')$where[' l.createTime'] = ['<=',$endDate." 23:59:59"]; + return $mrs = Db::name('log_sms')->alias('l')->join('__STAFFS__ s',' l.smsUserId=s.staffId','left') + ->where($where) + ->field('l.*,s.staffName') + ->order('l.smsId', 'desc')->paginate(input('limit/d')); + } +} diff --git a/hyhproject/admin/model/LogStaffLogins.php b/hyhproject/admin/model/LogStaffLogins.php new file mode 100755 index 0000000..89e132e --- /dev/null +++ b/hyhproject/admin/model/LogStaffLogins.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 登录日志业务处理 + */ +class LogStaffLogins extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = []; + if($startDate!='')$where['l.loginTime'] = ['>=',$startDate." 00:00:00"]; + if($endDate!='')$where[' l.loginTime'] = ['<=',$endDate." 23:59:59"]; + return $mrs = Db::name('log_staff_logins')->alias('l')->join('__STAFFS__ s',' l.staffId=s.staffId','left') + ->where($where) + ->field('l.*,s.staffName') + ->order('l.loginId', 'desc')->paginate(input('limit/d')); + + } +} diff --git a/hyhproject/admin/model/Member.php b/hyhproject/admin/model/Member.php new file mode 100755 index 0000000..44d44eb --- /dev/null +++ b/hyhproject/admin/model/Member.php @@ -0,0 +1,150 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +use think\Validate; +class Member extends Base{ + public function memberByPage(){ + $where='u.userStatus=1 AND u.dataFlag=1 AND u.userType=0'; + $start=input('startDate'); + $end=input('endDate'); + $loginName=input('loginName'); + $userPhone=input('userPhone'); + //dump($nonlogTime); + if($loginName!='')$where.= ' AND u.loginName LIKE "%'.$loginName.'%"'; + if($userPhone!='')$where.= ' AND u.userPhone LIKE "%'.$userPhone.'%"'; + if($start!='' && $end!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where.=' AND con.loginTime BETWEEN "'.$start.'" AND "'.$end.'"'; + }else if($start!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $where.= ' AND con.loginTime>="'.$start.'"'; + }else if($end!=''){ + $end = date('Y-m-d 00:00:00',strtotime(input('endDate'))); + $where.= ' AND con.loginTime<="'.$end.'"'; + } + $result=Db::table('__USERS__')->alias('u') + ->join('(select l.*,count(l.userId) logNum from __LOG_USER_LOGINS__ l group by l.userId ) con','con.userId=u.userId','left') + ->join('__ORDERS__ o','u.userId=o.userId','left') + ->where($where) + ->field('u.loginName,trueName,u.userPhone,lastTime,u.createTime,con.logNum,count(o.userId) orderNum') + ->order('loginTime desc') + ->group('u.userId,trueName') + ->paginate(input('limit/d'))->toArray(); + //dump(db::getlastsql()); + //dump($result); + return $result; + } + public function toExport(){ + $name="活跃用户数据列表"; + $where='u.userStatus=1 AND u.dataFlag=1 AND u.userType=0'; + $start=input('startDate'); + $end=input('endDate'); + $loginName=input('loginName'); + $userPhone=input('userPhone'); + //dump($nonlogTime); + if($loginName!='')$where.= ' AND u.loginName LIKE "%'.$loginName.'%"'; + if($userPhone!='')$where.= ' AND u.userPhone LIKE "%'.$userPhone.'%"'; + if($start!='' && $end!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + }else if($start!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + }else if($end!=''){ + $end = date('Y-m-d 00:00:00',strtotime(input('endDate'))); + }else{ + $end = date('Y-m-d 23:59:59',strtotime("now")); + } + $where.=' AND con.loginTime BETWEEN "'.$start.'" AND "'.$end.'"'; + + $page=Db::table('__USERS__')->alias('u') + ->join('(select l.*,count(l.userId) logNum from __LOG_USER_LOGINS__ l group by l.userId ) con','con.userId=u.userId','left') + ->join('__ORDERS__ o','u.userId=o.userId','left') + ->where($where) + ->field('u.loginName,trueName,u.userPhone,lastTime,u.createTime,con.logNum,count(o.userId) orderNum') + ->order('loginTime desc') + ->group('u.userId') + ->select(); + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '登录账号') + ->setCellValue('B1', '真实姓名') + ->setCellValue('C1', '联系方式') + ->setCellValue('D1', '最后登录时间') + ->setCellValue('E1', '登陆次数') + ->setCellValue('F1', '订单数量') + ->setCellValue('G1', '创建时间'); + $objPHPExcel->getActiveSheet()->getStyle('A1:G1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['loginName']) + ->setCellValue('B'.$i, $page[$row]['trueName']) + ->setCellValue('C'.$i, $page[$row]['userPhone']) + ->setCellValue('D'.$i, $page[$row]['lastTime']) + ->setCellValue('E'.$i, $page[$row]['logNum']) + ->setCellValue('F'.$i, $page[$row]['orderNum']) + ->setCellValue('G'.$i, $page[$row]['createTime']); + + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} \ No newline at end of file diff --git a/hyhproject/admin/model/Menus.php b/hyhproject/admin/model/Menus.php new file mode 100755 index 0000000..13c8762 --- /dev/null +++ b/hyhproject/admin/model/Menus.php @@ -0,0 +1,107 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 菜单业务处理 + */ +class Menus extends Base{ + protected $insert = ['dataFlag'=>1]; + /** + * 获取菜单列表 + */ + public function listQuery($parentId = -1){ + if($parentId==-1)return ['id'=>0,'name'=>WSTConf('CONF.mallName'),'isParent'=>true,'open'=>true]; + $rs = $this->where(['parentId'=>$parentId,'dataFlag'=>1])->field('menuId id,menuName name')->order('menuSort', 'asc')->select(); + if(count($rs)>0){ + foreach ($rs as $key =>$v){ + $rs[$key]['isParent'] = true; + } + }; + return $rs; + } + /** + * 获取菜单 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'menuId'=>$id]); + } + + /** + * 新增菜单 + */ + public function add(){ + $data = input('post.'); + WSTUnset($data,'menuId'); + $result = $this->validate('Menus.add')->save($data); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑菜单 + */ + public function edit(){ + $menuId = input('post.menuId/d'); + $result = $this->validate('Menus.edit')->allowField(['menuName','menuIcon','menuSort'])->save(input('post.'),['menuId'=>$menuId]); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除菜单 + */ + public function del(){ + $menuId = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['menuId'=>$menuId]); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + public function getChildMenus($parentId,$data){ + $rdata = []; + foreach($data as $v){ + if($v['parentId']==$parentId){ + $v['child'] = $this->getChildMenus($v['menuId'],$data); + $rdata[] = $v; + } + } + return $rdata; + } + /** + * 获取用户菜单 + */ + public function getMenus(){ + //用户权限判断 + $STAFF = session('WST_STAFF'); + $datas = []; + $dbo = $this->alias('m')->join('__PRIVILEGES__ p','m.menuId= p.menuId and isMenuPrivilege=1 and p.dataFlag=1','left') + ->where(['m.dataFlag'=>1]); + if((int)$STAFF['staffId']!=1){ + $dbo->where(['m.menuId'=>['in',$STAFF['menuIds']]]); + } + $menus = $dbo->field('m.menuId,m.menuName,privilegeUrl,m.parentId,m.menuIcon') + ->order('menuSort', 'asc') + ->select(); + if(!empty($menus)){ + foreach($menus as $key =>$v0){ + if($v0['parentId']==0){ + $v0['child'] = $this->getChildMenus($v0['menuId'],$menus); + $datas[] = $v0; + } + } + } + return $datas; + } +} diff --git a/hyhproject/admin/model/Messages.php b/hyhproject/admin/model/Messages.php new file mode 100755 index 0000000..78b1e71 --- /dev/null +++ b/hyhproject/admin/model/Messages.php @@ -0,0 +1,206 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 商城消息业务处理 + + */ + +class Messages extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $where = []; + + $where['m.dataFlag'] = 1; + + $msgType = (int)input('msgType'); + + if($msgType >= 0)$where['msgType'] = $msgType; + + $msgContent = input('msgContent'); + + if(!empty($msgContent))$where['msgContent']=['like',"%$msgContent%"]; + + $rs = $this->alias('m') + + ->field('m.*,u.loginName,s.shopName,st.loginName stName') + + ->join('__USERS__ u','m.receiveUserId=u.userId','left') + + ->join('__SHOPS__ s','m.receiveUserId=s.shopId','left') + + ->join('__STAFFS__ st','m.sendUserId=st.staffId','left') + + ->order('id desc') + + ->where($where) + + ->paginate(input('limit/d'))->toArray(); + + foreach ($rs['Rows'] as $key => $v){ + + $rs['Rows'][$key]['msgContent'] = WSTMSubstr(strip_tags($v['msgContent']),0,140); + + } + + return $rs; + + } + + public function getById($id){ + + return $this->get(['id'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + // 图片记录 + + // $rule = '/src="\/(upload.*?)"/'; + + // preg_match_all($rule,$data['msgContent'],$result); + + // mark 20180608 by zl + + $rule = '/src=".*?\/(upload.*?)"/'; + + preg_match_all($rule,htmlspecialchars_decode($data['msgContent']),$result); + + // 获取src数组 + + $imgs = $result[1]; + + $data['createTime'] = date('Y-m-d H:i:s'); + + $data['sendUserId'] = session('WST_STAFF.staffId'); + + //判断发送对象 + + if($data['sendType']=='theUser'){ + + $ids = explode(',',$data['htarget']); + + } + + elseif($data['sendType']=='shop'){ + + //获取所有店铺的id + + $ids = model('Shops')->getAllShopId(); + + }elseif($data['sendType']=='users'){ + + //获取所有用户id + + $ids = model('users')->getAllUserId(); + + } + + WSTUnset($data,'id,sendType,htarget');//删除多余字段 + + $list = []; + + //去重 + + array_unique($ids); + + foreach($ids as $v) + + { + + $data['receiveUserId'] = $v; + + $data['msgType'] = 0;//后台手工发送消息 + + $list[] = $data; + + } + + + + Db::startTrans(); + + try{ + + $result = $this->allowField(true)->saveAll($list); + + $id = $result[0]['id'];//新增的第一条消息id + + if(false !== $result){ + + //启用上传图片 + + WSTUseImages(1, $id, $imgs); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = input('post.id/d'); + + $data = []; + + $data['dataFlag'] = -1; + + $result = $this->update($data,['id'=>$id]); + + if(false !== $result){ + + return WSTReturn("删除成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/MobileBtns.php b/hyhproject/admin/model/MobileBtns.php new file mode 100755 index 0000000..c8fd3b5 --- /dev/null +++ b/hyhproject/admin/model/MobileBtns.php @@ -0,0 +1,194 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 商家认证业务处理 + + */ + +class MobileBtns extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $btnSrc = (int)input('btnSrc1',-1); + + $btnName = input('btnName1'); + + $where = []; + + if($btnSrc>-1){ + + $where['btnSrc'] = $btnSrc; + + } + + if($btnName!=''){ + + $where['btnName'] = ['like',"%$btnName%"]; + + } + + return $this->field(true) + + ->where($where) + + ->order('btnSrc asc,btnSort asc') + + ->paginate(input('limit/d')); + + } + + public function getById($id){ + + return $this->get(['id'=>$id]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['btnSort'] = (int)$data['btnSort']; + + WSTUnset($data,'id'); + + Db::startTrans(); + + try{ + + $result = $this->validate('MobileBtns.add')->allowField(true)->save($data); + + if(false !==$result){ + + cache('WST_MOBILE_BTN',null); + + $id = $this->id; + + //启用上传图片 + + WSTUseImages(1, $id, $data['btnImg']); + + if(false !== $result){ + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('新增失败',-1); + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $data = input('post.'); + + $data['btnSort'] = (int)$data['btnSort']; + + WSTUnset($data,'createTime'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, (int)$data['id'], $data['btnImg'], 'mobile_btns', 'btnImg'); + + $result = $this->validate('MobileBtns.edit')->allowField(true)->save($data,['id'=>(int)$data['id']]); + + if(false !== $result){ + + cache('WST_MOBILE_BTN',null); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('编辑失败',-1); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d'); + + Db::startTrans(); + + try{ + + WSTUnuseImage('mobile_btns','btnImg',$id); + + $result = $this->where(['id'=>$id])->delete(); + + if(false !== $result){ + + cache('WST_MOBILE_BTN',null); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + echo $e->getMessage(); + + Db::rollback();errLog($e); + + } + + return WSTReturn('删除失败',-1); + + } + + + +} + diff --git a/hyhproject/admin/model/Navs.php b/hyhproject/admin/model/Navs.php new file mode 100755 index 0000000..14ff597 --- /dev/null +++ b/hyhproject/admin/model/Navs.php @@ -0,0 +1,79 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 导航管理业务处理 + */ +class Navs extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + return $this->field(true)->order('id desc')->paginate(input('limit/d')); + } + public function getById($id){ + return $this->get($id); + } + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + WSTUnset($data,'id'); + $result = $this->validate('navs.add')->allowField(true)->save($data); + if(false !== $result){ + cache('WST_NAVS',null); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $Id = input('post.id/d',0); + //获取数据 + $data = input('post.'); + WSTUnset($data,'createTime'); + $result = $this->validate('navs.edit')->allowField(true)->save($data,['id'=>$Id]); + if(false !== $result){ + cache('WST_NAVS',null); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d'); + $result = $this->destroy($id); + if(false !== $result){ + cache('WST_NAVS',null); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 设置显示隐藏 + */ + public function editiIsShow(){ + $id = input('post.id/d',0); + $field = input('post.field'); + $val = input('post.val/d',0); + if(!in_array($field,['isShow','isOpen']))return WSTReturn("非法的操作内容",-1); + $result = Db::name('navs')->where(['id'=>['eq',$id]])->setField($field, $val); + if(false !== $result){ + cache('WST_NAVS',null); + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/OrderComplains.php b/hyhproject/admin/model/OrderComplains.php new file mode 100755 index 0000000..4dbdb45 --- /dev/null +++ b/hyhproject/admin/model/OrderComplains.php @@ -0,0 +1,416 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 订单投诉业务处理 + + */ + +class OrderComplains extends Base{ + + /** + + * 获取订单投诉列表 + + */ + + public function pageQuery(){ + + $startDate = input('startDate'); + + $endDate = input('endDate'); + + $shopName = Input('shopName'); + + $orderNo = Input('orderNo'); + + $complainStatus = (int)Input('complainStatus',-1); + + // 搜素条件 + + $areaId1 = (int)input('areaId1'); + + if($areaId1>0){ + + $where['s.areaIdPath'] = ['like',"$areaId1%"]; + + $areaId2 = (int)input("areaId1_".$areaId1); + + if($areaId2>0)$where['s.areaIdPath'] = ['like',$areaId1."_"."$areaId2%"]; + + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + + if($areaId3>0)$where['s.areaId'] = $areaId3; + + } + + if($startDate!='' && $endDate!=''){ + + $where['oc.complainTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + + }else if($startDate!=''){ + + $where['oc.complainTime'] = ['>=',$startDate.' 00:00:00']; + + }else if($endDate!=''){ + + $where['oc.complainTime'] = ['<=',$endDate.' 23:59:59']; + + } + + + + + + if($complainStatus>-1)$where['oc.complainStatus']=$complainStatus; + + if($orderNo!='')$where['o.orderNo']=['like',"%$orderNo%"]; + + $where['o.dataFlag']=1; + + $sort = input('sort'); + + $order = []; + + if($sort!=''){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + } + + $rs = Db::name('orders')->alias('o') + + ->field('oc.complainId,o.orderId,o.orderNo,o.orderSrc,s.shopName,u.userName,u.loginName,oc.complainTime,oc.complainStatus,oc.complainType,o.orderCode') + + ->join('__SHOPS__ s','o.shopId=s.shopId','inner','left') + + ->join('__USERS__ u','o.userId=u.userId','inner') + + ->join('__ORDER_COMPLAINS__ oc','oc.orderId=o.orderId','inner') + + ->where($where) + + ->order($order) + + ->order('complainId desc') + + ->paginate() + + ->toArray(); + + if(count($rs['Rows'])>0){ + + foreach ($rs['Rows'] as $key => $v){ + + $rs['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + + } + + } + + + + return $rs; + + } + + + + /** + + * 获取订单详细信息 + + */ + + public function getDetail(){ + + $complainId = (int)Input('cid'); + + $data = $this->alias('oc') + + ->field('oc.*,u.userName,u.loginName') + + ->join('__USERS__ u','oc.complainTargetId=u.userId','inner') + + ->where("oc.complainId=$complainId") + + ->find(); + + if($data){ + + if($data['complainAnnex']!='')$data['complainAnnex'] = explode(',',$data['complainAnnex']); + + if($data['respondAnnex']!='')$data['respondAnnex'] = explode(',',$data['respondAnnex']); + + $data['userName'] = ($data['userName']=='')?$data['loginName']:$data['userName']; + + $rs = Db::name('orders')->alias('o') + + ->field('o.orderStatus,o.areaId,o.userAddress,o.orderNo,o.userName,s.shopName,o.userAddress') + + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + + ->where(['o.dataFlag'=>1, + + 'o.orderId'=>$data['orderId']]) + + ->find(); + + //获取日志信息 + + $rs['log'] = Db::name('log_orders')->alias('lo') + + ->field('lo.*,u.loginName,u.userType,s.shopName') + + ->join('__USERS__ u','lo.logUserId=u.userId','left') + + ->join('__SHOPS__ s','u.userType=1 and s.userId=u.userId','left') + + ->where(['orderId'=>$data['orderId']]) + + ->select(); + + //获取相关商品 + + $rs['goodslist'] = Db::name('order_goods')->where(['orderId'=>$data['orderId']])->select(); + + $data['order'] = $rs; + + } + + return $data; + + } + + + + /** + + * 转交给应诉人应诉 + + */ + + public function deliverRespond(){ + + $id = (int)Input('id'); + + if($id==0){ + + return WSTReturn('无效的投诉信息',-1); + + } + + //判断是否已经处理过了 + + $rs = $this->alias('oc') + + ->field('oc.complainStatus,oc.respondTargetId,o.orderNo,s.userId,o.shopId') + + ->join('__ORDERS__ o','oc.orderId=o.orderId','inner') + + ->join('__SHOPS__ s','o.shopId = s.shopId','left') + + ->where("complainId=$id") + + ->find(); + + if($rs['complainStatus']==0){ + + $data = array(); + + $data['needRespond'] = 1; + + $data['complainStatus'] = 1; + + $data['deliverRespondTime'] = date('Y-m-d H:i:s'); + + Db::startTrans(); + + try{ + + $ers = $this->where('complainId='.$id)->update($data); + + if($ers!==false){ + + //发站内信息提醒 + + $tpl = WSTMsgTemplates('ORDER_NEW_COMPLAIN'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + $find = ['${ORDER_NO}']; + + $replace = [$rs['orderNo']]; + + $msg = array(); + + $msg["shopId"] = $rs["shopId"]; + + $msg["tplCode"] = $tpl["tplCode"]; + + $msg["msgType"] = 1; + + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + + $msg["msgJson"] = ['from'=>3,'dataId'=>$id]; + + model("common/MessageQueues")->add($msg); + + } + + Db::commit(); + + return WSTReturn('操作成功',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + }else{ + + return WSTReturn('操作失败,该投诉状态已发生改变,请刷新后重试!',-1); + + } + + return $rd; + + } + + + + /** + + * 仲裁 + + */ + + public function finalHandle(){ + + $rd = array('status'=>-1,'msg'=>'无效的投诉信息'); + + $complainId = (int)Input('cid'); + + if($complainId==0){ + + return WSTReturn('无效的投诉信息',-1); + + } + + //判断是否已经处理过了 + + $rs = $this->alias('oc') + + ->field('oc.complainStatus,s.userId shopUserId,o.shopId,o.userId,o.orderNo,o.orderId,oc.needRespond') + + ->join('__ORDERS__ o','oc.orderId=o.orderId','inner') + + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + + ->where("complainId=$complainId") + + ->find(); + + if($rs['complainStatus']!=4){ + + $data = array(); + + $data['finalHandleStaffId'] = session('WST_STAFF.staffId'); + + $data['complainStatus'] = 4; + + $data['finalResult'] = Input('finalResult'); + + $data['finalResultTime'] = date('Y-m-d H:i:s'); + + Db::startTrans(); + + try{ + + $ers = $this->where('complainId='.$complainId)->update($data); + + if($ers!==false){ + + //需要卖家回应的话则给卖家也一条消息 + + + + + + $tpl = WSTMsgTemplates('ORDER_HANDLED_COMPLAIN'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + //发站内商家信息提醒 + + $find = ['${ORDER_NO}']; + + $replace = [$rs['orderNo']]; + + $content = str_replace($find,$replace,$tpl['tplContent']) ; + + if($rs['needRespond']==1){ + + $msg = array(); + + $msg["shopId"] = $rs["shopId"]; + + $msg["tplCode"] = $tpl["tplCode"]; + + $msg["msgType"] = 1; + + $msg["content"] = $content ; + + $msg["msgJson"] = ['from'=>3,'dataId'=>$complainId]; + + model("common/MessageQueues")->add($msg); + + } + + //发站内用户信息提醒 + + WSTSendMsg($rs['userId'],$content,['from'=>3,'dataId'=>$complainId]); + + } + + + + Db::commit(); + + return WSTReturn('操作成功',1); + + } + + }catch(\Exception $e){ + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + }else{ + + return WSTReturn('操作失败,该投诉状态已发生改变,请刷新后重试!',-1); + + } + + + + } + +} + diff --git a/hyhproject/admin/model/OrderRefunds.php b/hyhproject/admin/model/OrderRefunds.php new file mode 100755 index 0000000..926af78 --- /dev/null +++ b/hyhproject/admin/model/OrderRefunds.php @@ -0,0 +1,723 @@ +<?php +namespace wstmart\admin\model; +use think\Loader; +use think\Db; +use Env; +/** + * ============================================================================ + * 退款订单业务处理类 + */ +class OrderRefunds extends Base{ + + /** + * 获取用户退款订单列表 + */ + public function refundPageQuery(){ + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = ['o.dataFlag'=>1]; + $where['orderStatus'] = ['in',[-1,-3]]; + $orderNo = input('orderNo'); + $shopName = input('shopName'); + $deliverType = (int)input('deliverType',-1); + $areaId1 = (int)input('areaId1'); + if($areaId1>0){ + $where['s.areaIdPath'] = ['like',"$areaId1%"]; + $areaId2 = (int)input("areaId1_".$areaId1); + if($areaId2>0)$where['s.areaIdPath'] = ['like',$areaId1."_"."$areaId2%"]; + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + if($areaId3>0)$where['s.areaId'] = $areaId3; + } + $isRefund = (int)input('isRefund',-1); + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + + if($deliverType!=-1)$where['o.deliverType'] = $deliverType; + if($isRefund!=-1)$where['o.isRefund'] = $isRefund; + + if($startDate!='' && $endDate!=''){ + $where['orf.createTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['orf.createTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['orf.createTime'] = ['<=',$endDate.' 23:59:59']; + } + // 排序 + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order[$sortArr[0]] = $sortArr[1]; + } + $page = Db::name('orders')->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__USERS__ u','o.userId=u.userId','left') + ->join('__ORDER_REFUNDS__ orf ','o.orderId=orf.orderId and refundStatus in (0,1,2)') + ->where($where) + ->field('orf.id refundId,o.orderId,o.orderNo,s.shopName,s.shopId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney,refundStatus, + o.orderStatus,u.loginName,o.deliverType,payType,payFrom,o.orderStatus,orderSrc,orf.backMoney,orf.backProductNum,orf.backCouponsNum,orf.backWangNum,orf.refundRemark,isRefund,orf.createTime,o.orderCode,o.useScore') + ->order($order) + ->order('orf.createTime', 'desc') + ->paginate(input('limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['payType'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + $page['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + } + } + return $page; + } + /** + * 获取退款资料 + */ + public function getInfoByRefund(){ + return $this->alias('orf')->join('__ORDERS__ o','orf.orderId=o.orderId')->where(['orf.id'=>(int)input('get.id'),'isRefund'=>0,'orderStatus'=>['in',[-1,-3]],'refundStatus'=>['in',[0,1]]]) + ->field('orf.id refundId,orderNo,o.orderId,goodsMoney,refundReson,refundOtherReson,totalMoney,realTotalMoney,deliverMoney,payType,payFrom,backMoney,o.useScore,o.scoreMoney,tradeNo,orf.backProductNum,orf.backCouponsNum,orf.backWangNum,o.productNum,o.couponsNum,o.wangNum,o.moneyNum') + ->find(); + } + /** + * 退款 + */ + public function orderRefund(){ + $id = (int)input('post.id'); + if($id==0)return WSTReturn("操作失败!"); + $refund = $this->get($id); + //if(empty($refund) || $refund->refundStatus!=1)return WSTReturn("该退款订单不存在或已退款!"); + if(empty($refund))return WSTReturn("该退款订单不存在或已退款!"); + $order = model('orders')->get($refund->orderId); +// dump($order->payFrom); + if($order->payType==1 && $order->payFrom=='wallets'){ + return $this->saveOrderRefund($refund,$order); + } + if($order->payType==1 && $order->payFrom=='ect'){ + return $this->ectOrderRefund($refund,$order); + } + if($order->payType==1 && $order->payFrom=='qlgpay'){ + return $this->qlgOrderRefund($refund,$order); + } + $content = input('post.content'); + $refundId = (int)input('post.id'); + $request_no = $order['orderNo'].$order['userId']; + $backMoney = $refund["backMoney"]; + $tradeNo = $order['tradeNo']; + $refund_reason = "订单【".$order['orderNo']."】退款"; + Loader::import('alipay.aop.AopClient', EXTEND_PATH,'.php'); + Loader::import('alipay.aop.request.AlipayTradeRefundRequest', EXTEND_PATH,'.php'); + // require Env::get('root_path') . 'extend/alipay/aop/AopClient.php'; + // require Env::get('root_path') . 'extend/alipay/aop/request/AlipayTradeRefundRequest.php'; + $payment = model('common/payments')->getPayment("app_alipays"); + //dump($payment); + $aop = new \AopClient (); + $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do'; + $aop->appId = $payment["appId"]; + $aop->rsaPrivateKey = $payment["rsaPrivateKey"]; + $aop->alipayrsaPublicKey=$payment["alipayrsaPublicKey"]; + $aop->apiVersion = '1.0'; + $aop->signType = 'RSA2'; + $aop->postCharset='UTF-8'; + $aop->format='json'; + $request = new \AlipayTradeRefundRequest (); + + $request->setBizContent("{" . + "\"trade_no\":\"$tradeNo\"," . + "\"refund_amount\":\"$backMoney\"," . + "\"refund_reason\":\"$refund_reason\"," . + "\"out_request_no\":\"$request_no\"" . + " }"); + + $result = $aop->execute ( $request); + $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response"; + $resultCode = $result->$responseNode->code; + if(!empty($resultCode) && $resultCode == 10000){ + if($result->$responseNode->fund_change=="Y"){ + $obj = array(); + $obj['refundTradeNo'] = $request_no;//退款单号 + $obj['content'] = $content; + $obj['refundId'] = $refundId; + $rs = $this->complateOrderRefund($obj); + if($rs['status']==1){ + return WSTReturn("退款成功",1); + }else{ + return WSTReturn("退款失败",1); + } + } + } else { + $msg = $result->$responseNode->sub_msg; + //dump($msg); + return WSTReturn($msg,-1); + } + + } + public function complateOrderRefund($obj){ + Db::startTrans(); + try{ + $content = $obj['content']; + $refundTradeNo = $obj['refundTradeNo']; + $refundId = $obj['refundId']; + $refund = $this->get($refundId); + $order = model('orders')->get($refund->orderId); + if(!(in_array($order->orderStatus,[-1,-3]) && $order->isRefund==0 && ($order->isPay==1 || ($order->payType==0 && $order->useScore>0))))return WSTReturn("无效的退款订单!"); + //修改退款单信息 + $refund->refundRemark = $content; + $refund->refundTime = date('Y-m-d H:i:s'); + $refund->refundStatus = 2; + $refund->refundTradeNo = $refundTradeNo; + $refund->save(); + //修改订单状态 + $order->isRefund = 1; + $order->save(); + + if($order->useScore>0){ + $score = []; + $score['userId'] = $order->userId; + $score['score'] = $order->useScore; + $score['dataSrc'] = 4; + $score['dataId'] = $refund['id']; + $score['dataRemarks'] = "返还订单【".$order->orderNo."】积分".$order->useScore."个"; + $score['scoreType'] = 1; + model('common/UserScores')->add($score); + } + + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_REFUND_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REMARK}']; + $replace = [$order->orderNo,$content]; + WSTSendMsg($order->userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order->orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxMessage(['CODE'=>'WX_ORDER_REFUND_SUCCESS','userId'=>$order->userId,'params'=>$params]); + } + //如果有钱剩下,那么就退回到商家钱包 + $shopMoneys = $order->realTotalMoney-$refund->backMoney; + if($shopMoneys>0){ + //创建商家资金流水 + $lm = []; + $lm['targetType'] = 1; + $lm['targetId'] = $order->shopId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '订单【'.$order->orderNo.'】退款,返回商家金额¥'.$shopMoneys."。"; + $lm['moneyType'] = 1; + $lm['money'] = $shopMoneys; + $lm['payType'] = 0; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->add($lm); + //发送商家信息 + $tpl = WSTMsgTemplates('ORDER_SHOP_REFUND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${MONEY}']; + $replace = [$order->orderNo,$shopMoneys]; + + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['SHOP_MONEY'] = $shopMoneys; + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + + $msg = array(); + $tplCode = "WX_ORDER_SHOP_REFUND"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>'WX_ORDER_SHOP_REFUND','params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + } + Db::commit(); + return WSTReturn("退款成功",1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn("退款失败,请刷新后再重试"); + } + + public function saveOrderRefund($refund,$order){ + $content = input('post.content'); + $lockCashMoney = $order["lockCashMoney"]; + if(!(in_array($order->orderStatus,[-1,-3]) && $order->isRefund==0 && ($order->isPay==1 || ($order->payType==0 && $order->useScore>0))))return WSTReturn("无效的退款订单!"); + Db::startTrans(); + try{ + //修改退款单信息 + $refund->refundRemark = $content; + $refund->refundTime = date('Y-m-d H:i:s'); + $refund->refundStatus = 2; + $refund->save(); + //修改订单状态 + $order->isRefund = 1; + $order->save(); + //创建用户资金流水记录 + if($refund->backMoney>0){ + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $order->userId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '订单【'.$order->orderNo.'】退款¥'.$refund->backMoney."。".(($content!='')?"【退款备注】:".$content:''); + $lm['moneyType'] = 1; + $lm['money'] = $refund->backMoney; + $lm['payType'] = 0; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('common/LogMoneys')->add($lm); + //修改用户充值金额 + model('users')->where(["userId"=>$order->userId])->setInc("rechargeMoney",($lockCashMoney>$refund->backMoney)?$refund->backMoney:$lockCashMoney); + } + + if($order->useScore>0) { + $score = []; + $score['userId'] = $order->userId; + $score['score'] = $order->useScore; + $score['dataSrc'] = 4; + $score['dataId'] = $refund['id']; + $score['dataRemarks'] = "返还订单【" . $order->orderNo . "】积分" . $order->useScore . "个"; + $score['scoreType'] = 1; + model('common/UserScores')->add($score); + } + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_REFUND_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REMARK}']; + $replace = [$order->orderNo,$content]; + WSTSendMsg($order->userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order->orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxMessage(['CODE'=>'WX_ORDER_REFUND_SUCCESS','userId'=>$order->userId,'params'=>$params]); + } + //如果有钱剩下,那么就退回到商家钱包 + $shopMoneys = $order->realTotalMoney-$refund->backMoney; + if($shopMoneys>0){ + //创建商家资金流水 + $lm = []; + $lm['targetType'] = 1; + $lm['targetId'] = $order->shopId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '订单【'.$order->orderNo.'】退款,返回商家金额¥'.$shopMoneys."。"; + $lm['moneyType'] = 1; + $lm['money'] = $shopMoneys; + $lm['payType'] = 0; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->add($lm); + //dump($lm); + //发送商家信息 + $tpl = WSTMsgTemplates('ORDER_SHOP_REFUND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${MONEY}']; + $replace = [$order->orderNo,$shopMoneys]; + + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['SHOP_MONEY'] = $shopMoneys; + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + + $msg = array(); + $tplCode = "WX_ORDER_SHOP_REFUND"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>'WX_ORDER_SHOP_REFUND','params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + } +// die; + Db::commit(); + return WSTReturn("退款成功",1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn("退款失败,请刷新后再重试"); + } + public function qlgOrderRefund($refund,$order){ + $content = input('post.content'); + //dump($refund); + if(!(in_array($order->orderStatus,[-1,-3]) && $order->isRefund==0 && ($order->isPay==1 || ($order->payType==0 && $order->useScore>0))))return WSTReturn("无效的退款订单!"); + + Db::startTrans(); + try{ + //修改退款单信息 + $refund->refundRemark = $content; + $refund->refundTime = date('Y-m-d H:i:s'); + $refund->refundStatus = 2; + //修改订单状态 + $order->isRefund = 1; + $order->save(); + $userId = $order->userId; + //创建用户资金流水记录 + $um = Db::name('users'); + $lmm = Db::name('log_moneys'); + $nowTime = time(); + //记录各个券支出 + //产品券 + if($refund->backProductNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款¥'.$refund->backProductNum,1,$refund->backProductNum,'qlgpay',1); + } + //优惠券 + if($refund->backCouponsNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款¥'.$refund->backCouponsNum,1,$refund->backCouponsNum,'qlgpay',2); + } + //旺旺券 + if($refund->backWangNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款¥'.$refund->backWangNum,1,$refund->backWangNum,'qlgpay',3); + } + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_REFUND_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REMARK}']; + $replace = [$order->orderNo,$content]; + WSTSendMsg($order->userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order->orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxMessage(['CODE'=>'WX_ORDER_REFUND_SUCCESS','userId'=>$order->userId,'params'=>$params]); + } + //如果有钱剩下,那么就退回到商家钱包 + $userId=Db::name('shops')->where('shopId',$order->shopId)->value('userId'); + $backShopNum = round($order->productNum - $refund->backProductNum,2); + if($backShopNum > 0){ + Model('common/LogMoneys')->addMoneyLog(1,$order->shopId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款剩余收入¥'.$backShopNum,1,$backShopNum,'qlgpay',1); + } + $backShopNum = round($order->couponsNum - $refund->backCouponsNum,2); + if($backShopNum > 0){ + Model('common/LogMoneys')->addMoneyLog(1,$order->shopId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款剩余收入¥'.$backShopNum,1,$backShopNum,'qlgpay',2); + } + $backShopNum = round($order->wangNum - $refund->backWangNum,2); + if($backShopNum > 0){ + Model('common/LogMoneys')->addMoneyLog(1,$order->shopId,$order->orderId,1,'交易订单【'.$order->orderNo.'】退款剩余收入¥'.$backShopNum,1,$backShopNum,'qlgpay',3); + } + Db::commit(); + return WSTReturn("退款成功",1); + }catch (\Exception $e) { + dump($e); + Db::rollback();errLog($e); + } + return WSTReturn("退款失败,请刷新后再重试"); + } + public function ectOrderRefund($refund,$order){ + $content = input('post.content'); + $lockCashMoney = $order["lockCashMoney"]; + //dump($refund); + if(!(in_array($order->orderStatus,[-1,-3]) && $order->isRefund==0 && ($order->isPay==1 || ($order->payType==0 && $order->useScore>0))))return WSTReturn("无效的退款订单!"); + + Db::startTrans(); + try{ + //修改退款单信息 + $refund->refundRemark = $content; + $refund->refundTime = date('Y-m-d H:i:s'); + $refund->refundStatus = 2; + //修改订单状态 + $order->isRefund = 1; + $order->save(); + //创建用户资金流水记录 + $ectInfo=db('orders_ect')->where('orderId',$order['orderId'])->field('ectPrice,orderEctNum')->find(); + //获取退还给用户的ECT数量 + $ectNum=round(($refund->backMoney/$ectInfo['ectPrice']),2); + if($ectNum>0){ + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $order->userId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '订单【'.$order->orderNo.'】退ECT数量'.$ectNum."。".(($content!='')?"【退款备注】:".$content:''); + $lm['moneyType'] = 1; + $lm['money'] = $ectNum; + $lm['payType'] = "ect"; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('common/LogMoneys')->add($lm); + } + if($order->useScore>0){ + $score = []; + $score['userId'] = $order->userId; + $score['score'] = $order->useScore; + $score['dataSrc'] = 4; + $score['dataId'] = $refund['id']; + $score['dataRemarks'] = "返还订单【".$order->orderNo."】积分".$order->useScore."个"; + $score['scoreType'] = 1; + model('common/UserScores')->add($score); + } + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_REFUND_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REMARK}']; + $replace = [$order->orderNo,$content]; + WSTSendMsg($order->userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order->orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxMessage(['CODE'=>'WX_ORDER_REFUND_SUCCESS','userId'=>$order->userId,'params'=>$params]); + } + //如果有钱剩下,那么就退回到商家钱包,先获取总的ECT数量 + + $backShopEctNum=round(($ectInfo['orderEctNum']-$ectNum),2); + if($backShopEctNum>0){ + //创建商家资金流水 + $userId=db('shops')->where('shopId',$order['shopId'])->value('userId'); + $l = []; + $l['targetType'] = 1; + $l['targetId'] = $userId; + $l['dataId'] = $order->orderId; + $l['dataSrc'] = 1; + $l['remark'] = '订单【'.$order->orderNo.'】退款,返回商家ect数量:'.$backShopEctNum."。"; + $l['moneyType'] = 1; + $l['money'] = $backShopEctNum; + $l['payType'] = "ect"; + $l['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->add($l); + //dump(Db::getlastsql());die; + //发送商家信息 + $tpl = WSTMsgTemplates('ORDER_SHOP_REFUND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${MONEY}']; + $replace = [$order->orderNo,$backShopEctNum]; + + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$refund->refundReson); + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['REASON'] = $reasonData['dataName'].(($refund->refundReson==10000)?" - ".$refund->refundOtherReson:""); + $params['SHOP_MONEY'] = $backShopEctNum; + $params['MONEY'] = $refund->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + + $msg = array(); + $tplCode = "WX_ORDER_SHOP_REFUND"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>'WX_ORDER_SHOP_REFUND','params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + } + Db::commit(); + return WSTReturn("退款成功",1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn("退款失败,请刷新后再重试"); + } + + /** + * 导出订单 + */ + public function toExport(){ + $name='退款订单表'; + $startDate = input('startDate'); + $endDate = input('endDate'); + $where = ['o.dataFlag'=>1]; + $where['orderStatus'] = ['in',[-1,-3]]; + $orderNo = input('orderNo'); + $shopName = input('shopName'); + $deliverType = (int)input('deliverType',-1); + $areaId1 = (int)input('areaId1'); + if($startDate!='' && $endDate!=''){ + $where['orf.createTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['orf.createTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['orf.createTime'] = ['<=',$endDate.' 23:59:59']; + } + $isRefund = (int)input('isRefund',-1); + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + if($deliverType!=-1)$where['o.deliverType'] = $deliverType; + if($isRefund!=-1)$where['o.isRefund'] = $isRefund; + + if($areaId1>0){ + $where['s.areaIdPath'] = ['like',"$areaId1%"]; + $areaId2 = (int)input("areaId1_".$areaId1); + if($areaId2>0)$where['s.areaIdPath'] = ['like',$areaId1."_"."$areaId2%"]; + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + if($areaId3>0)$where['s.areaId'] = $areaId3; + } + $isRefund = (int)input('isRefund',-1); + + // 排序 + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order[$sortArr[0]] = $sortArr[1]; + } + $page = Db::name('orders')->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__USERS__ u','o.userId=u.userId','left') + ->join('__ORDER_REFUNDS__ orf ','o.orderId=orf.orderId and refundStatus in (1,2)') + ->where($where) + ->field('orf.id refundId,o.orderId,o.orderNo,s.shopName,s.shopId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney, + o.orderStatus,u.loginName,o.deliverType,payType,o.payFrom,o.orderStatus,orderSrc,orf.backMoney,orf.refundRemark,isRefund,orf.createTime,o.orderCode,o.useScore') + ->order($order) + ->order('orf.createTime', 'desc') + ->select(); + if(count($page)>0){ + foreach ($page as &$v){ + $v['payType'] = WSTLangPayType($v['payType']); + $v['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $v['status'] = WSTLangOrderStatus($v['orderStatus']); + $v['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + } + } + + unset($v); + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("退款订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(35); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12); + $objPHPExcel->getActiveSheet()->getStyle('A1:T1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:T1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '订单编号') + ->setCellValue('B1', '申请人') + ->setCellValue('C1', '店铺名称') + ->setCellValue('D1', '订单来源') + ->setCellValue('E1', '配送方式') + ->setCellValue('F1', '支付方式') + ->setCellValue('G1', '实收金额') + ->setCellValue('H1', '申请退款金额') + ->setCellValue('I1', '申请时间') + ->setCellValue('J1', '退款状态') + ->setCellValue('K1', '退款备注'); + $objPHPExcel->getActiveSheet()->getStyle('A1:R1')->applyFromArray($styleArray); + $reRefundInfo=['0'=>'未退款','1'=>'已退款']; + for ($row = 0; $row < count($page); $row++){ + if($page[$row]['payFrom'] =='ect'){ + $page[$row]['payFrom'] = 'ECT'; + }else if($page[$row]['payFrom'] =='wallets'){ + $page[$row]['payFrom'] = '余额'; + }else if($page[$row]['payFrom'] =='app_alipays' || $page[$row]['payFrom'] =='alipays'){ + $page[$row]['payFrom'] = '支付宝'; + }else if($page[$row]['payFrom'] =='weixinpays'){ + $page[$row]['payFrom'] = '微信'; + }else if($page[$row]['payFrom'] =='cod'){ + $page[$row]['payFrom'] = '货到付款'; + } + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['orderNo']) + ->setCellValue('B'.$i, $page[$row]['loginName']) + ->setCellValue('C'.$i, $page[$row]['shopName']) + ->setCellValue('D'.$i, $page[$row]['orderCodeTitle']) + ->setCellValue('E'.$i, $page[$row]['deliverType']) + ->setCellValue('F'.$i, $page[$row]['payFrom']) + ->setCellValue('G'.$i, $page[$row]['realTotalMoney']) + ->setCellValue('H'.$i, $page[$row]['backMoney']) + ->setCellValue('I'.$i, $page[$row]['createTime']) + ->setCellValue('J'.$i, $reRefundInfo[$page[$row]['isRefund']]) + ->setCellValue('K'.$i, $page[$row]['refundRemark']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/Orders.php b/hyhproject/admin/model/Orders.php new file mode 100755 index 0000000..cd75905 --- /dev/null +++ b/hyhproject/admin/model/Orders.php @@ -0,0 +1,478 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 订单业务处理类 + */ +class Orders extends Base{ + /** + * 获取用户订单列表 + */ + public function pageQuery($orderStatus = 10000,$isAppraise = -1){ + $where = ['o.dataFlag'=>1]; + if($orderStatus!=10000){ + $where['orderStatus'] = $orderStatus; + } + $startDate = input('startDate'); + $endDate = input('endDate'); + $orderNo = input('orderNo'); + $shopName = input('shopName'); + $userPhone = input('userPhone'); + $userId = (int)input('userId'); + $payType = (int)input('payType',-1); + $deliverType = (int)input('deliverType',-1); + $sort = input('sort'); + $investmentStaff =htmlspecialchars(input('investmentStaff')); // mark + if($isAppraise!=-1)$where['isAppraise'] = $isAppraise; + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + if($userPhone!='')$where['o.userPhone'] = ['like','%'.$userPhone.'%']; + if($userId>0)$where['o.userId'] = $userId; + + if($startDate!='' && $endDate!=''){ + $where['o.createTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['o.createTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['o.createTime'] = ['<=',$endDate.' 23:59:59']; + } + $areaId1 = (int)input('areaId1'); + + if($areaId1>0){ + $where['s.areaIdPath'] = ['like',"$areaId1%"]; + $areaId2 = (int)input("areaId1_".$areaId1); + if($areaId2>0)$where['s.areaIdPath'] = ['like',$areaId1."_"."$areaId2%"]; + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + if($areaId3>0)$where['s.areaId'] = $areaId3; + } + + if($deliverType!=-1)$where['o.deliverType'] = $deliverType; + if($payType!=-1)$where['o.payType'] = $payType; + $order = 'o.createTime desc'; + if($sort){ + $sort = str_replace('.',' ',$sort); + $order = $sort; + } + //mark + if($investmentStaff !=""){ + $where['se.investmentStaff'] = ['like',"%".$investmentStaff."%"]; + $where['orderStatus'] = 2; + } + // $page = $this->alias('o')->join('__USERS__ u','o.userId=u.userId','left')->join('__SHOPS__ s','o.shopId=s.shopId','left')->where($where) + // ->field('o.orderId,o.orderNo,u.loginName,s.shopName,s.shopId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney, + // o.orderStatus,o.userName,o.deliverType,payType,payFrom,o.orderStatus,orderSrc,o.createTime,o.orderCode') + // ->order($order) + // ->paginate(input('limit/d'))->toArray(); + //添加对接人员查询 mark 20180514 + $page = $this->alias('o')->join('__USERS__ u','o.userId=u.userId','left')->join('__SHOPS__ s','o.shopId=s.shopId','left')->join('__SHOP_EXTRAS__ se','o.shopId=se.shopId','left')->where($where) + ->field('o.orderId,o.orderNo,u.loginName,s.shopName,s.shopId,s.userId shopUserId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney, + o.orderStatus,o.userName,o.payable,o.deliverType,o.productNum,o.couponsNum,o.wangNum,o.moneyNum,o.productHandlingFee,o.productTaxFee,o.couponsHandlingFee,o.couponsTaxFee,payType,payFrom,o.orderStatus,orderSrc,o.createTime,o.orderCode,se.investmentStaff') + ->order($order) + ->paginate(input('limit/d'))->toArray(); + if(count($page['Rows'])>0){ + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['loginName'] = "【".$v['loginName']."】"; + $page['Rows'][$key]['userName'] = $v['userName']; + $shopUserInfo = getUserInfo(['userId'=>$v['shopUserId']],'loginName'); + $page['Rows'][$key]['shopLoginName'] = "【".$shopUserInfo['loginName']."】"; + $page['Rows'][$key]['payType'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + $page['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + } + } + return $page; + } + /** + * 获取凭证 + * @return [type] [description] + */ + public function getCertificate(){ + $certificateStatus = (int)input('post.certificateStatus'); + $shopName = input('post.shopName'); + $data = []; + $m = Db::name('orders'); + $tm = Model('common/Table'); + $tm->setTable('shops'); + // $certificateStatus = 2; + if($certificateStatus <=1){//未上传和不需上传的订单 + $where = ['certificateStatus'=>$certificateStatus,'orderStatus'=>2,'dataFlag'=>1]; + if($shopName){ + $shopIds = $tm->getColumn(['shopName'=>['LIKE','%'.$shopName.'%']],'shopId'); + $where = array_merge($where,['shopId'=>['IN',$shopIds]]); + } + $data = $m->where($where)->group('shopId')->field('shopId,sum(payable) payNum')->paginate(input('limit/d'))->toArray(); + foreach ($data['Rows'] as &$v) { + $v['status'] = $certificateStatus; + $v['list'] = $m->where($where)->where(['shopId'=>$v['shopId']])->field('orderId,orderNo,payable')->select(); + } + }else{ + $where = ['status'=>$certificateStatus]; + if($shopName){ + $shopIds = $tm->getColumn(['shopName'=>['LIKE','%'.$shopName.'%']],'shopId'); + $where = array_merge($where,['shopId'=>['IN',$shopIds]]); + } + $data = Db::name('order_shop_certificate')->where($where)->field('*')->paginate(input('limit/d'))->toArray(); + foreach ($data['Rows'] as &$v) { + $v['payNum'] = $m->where(['orderId'=>['IN',$v['orderIds']]])->sum('payable'); + $v['list'] = $m->where(['orderId'=>['IN',$v['orderIds']]])->field('orderId,orderNo,payable')->select(); + } + } + foreach ($data['Rows'] as &$val) { + $val['shop'] = $tm->getInfo(['shopId'=>$val['shopId']],'shopName,phone'); + } + return $data; + } + //凭证设置 + public function certificateSet(){ + $id = input('post.id'); + $status = input('post.status') + 2; + $data['status'] = $status; + $data['reasonsForRefusal'] = (string)input('post.reasonsForRefusal'); + $m = Model('common/Table'); + $m->setTable('order_shop_certificate'); + $orderIds = $m->getField(['id'=>$id],'orderIds'); + Db::startTrans(); + try{ + $m->setTable('order_shop_certificate'); + if(false !== $m->updateInfo(['id'=>$id],$data)){ + $m->setTable('orders'); + $m->updateInfo(['orderId'=>['IN',$orderIds]],['certificateStatus'=>$status]); + } + Db::commit(); + return WSTReturn("操作成功",1); + }catch (\Exception $e) { + + Db::rollback();errLog($e); + } + return WSTReturn("操作失败"); + } + /** + * 获取用户退款订单列表 + */ + public function refundPageQuery(){ + $where = ['o.dataFlag'=>1]; + $where['orderStatus'] = ['in',[-1,-4]]; + $where['o.payType'] = 1; + $orderNo = input('orderNo'); + $shopName = input('shopName'); + $deliverType = (int)input('deliverType',-1); + $areaId1 = (int)input('areaId1'); + $areaId2 = (int)input('areaId2'); + $areaId3 = (int)input('areaId3'); + $isRefund = (int)input('isRefund',-1); + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + if($areaId1>0)$where['s.areaId1'] = $areaId1; + if($areaId2>0)$where['s.areaId2'] = $areaId2; + if($areaId3>0)$where['s.areaId3'] = $areaId3; + if($deliverType!=-1)$where['o.deliverType'] = $deliverType; + if($isRefund!=-1)$where['o.isRefund'] = $isRefund; + $page = $this->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__ORDER_REFUNDS__ orf ','o.orderId=orf.orderId','left') + ->where($where) + ->field('o.orderId,o.orderNo,s.shopName,s.shopId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney, + o.orderStatus,o.userName,o.deliverType,payType,payFrom,o.orderStatus,orderSrc,orf.refundRemark,isRefund,o.createTime') + ->order('o.createTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])>0){ + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['payType'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + return $page; + } + /** + * 获取退款资料 + */ + public function getInfoByRefund(){ + return $this->where(['orderId'=>(int)input('get.id'),'isRefund'=>0,'orderStatus'=>['in',[-1,-4]]]) + ->field('orderNo,orderId,goodsMoney,totalMoney,realTotalMoney,deliverMoney,payType,payFrom,tradeNo') + ->find(); + } + /** + * 退款 + */ + public function orderRefund(){ + $id = (int)input('post.id'); + $content = input('post.content'); + if($id==0)return WSTReturn("操作失败!"); + $order = $this->where(['orderId'=>(int)input('post.id'),'payType'=>1,'isRefund'=>0,'orderStatus'=>['in',[-1,-4]]]) + ->field('userId,orderNo,orderId,goodsMoney,totalMoney,realTotalMoney,deliverMoney,payType,payFrom,tradeNo') + ->find(); + if(empty($order))return WSTReturn("该订单不存在或已退款!"); + Db::startTrans(); + try{ + $order->isRefund = 1; + $order->save(); + //修改用户账户金额 + Db::name('users')->where('userId',$order->userId)->setInc('userMoney',$order->realTotalMoney); + //创建资金流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $order->userId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '订单【'.$order->orderNo.'】退款¥'.$order->realTotalMoney."。".(($content!='')?"【退款备注】:".$content:''); + $lm['moneyType'] = 1; + $lm['money'] = $order->realTotalMoney; + $lm['payType'] = 0; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->save($lm); + //创建退款记录 + $data = []; + $data['orderId'] = $id; + $data['refundRemark'] = $content; + $data['refundTime'] = date('Y-m-d H:i:s'); + $rs = Db::name('order_refunds')->insert($data); + if(false !== $rs){ + //发送一条用户信息 + WSTSendMsg($order['userId'],"您的退款订单【".$order['orderNo']."】已处理,请留意账户到账情况。".(($content!='')?"【退款备注:".$content."】":""),['from'=>1,'dataId'=>$id]); + Db::commit(); + return WSTReturn("操作成功",1); + } + }catch (\Exception $e) { + + Db::rollback();errLog($e); + } + return WSTReturn("操作失败,请刷新后再重试"); + } + + + /** + * 获取订单详情 + */ + public function getByView($orderId){ + $orders = $this->alias('o')->join('__EXPRESS__ e','o.expressId=e.expressId','left') + ->join('__ORDER_REFUNDS__ orf ','o.orderId=orf.orderId','left') + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__USERS__ u','o.userId=u.userId','left') + ->where('o.dataFlag=1 and o.orderId='.$orderId) + ->field('o.*,e.expressName,u.loginName,s.shopName,s.shopQQ,s.shopWangWang,orf.refundRemark,orf.refundTime,orf.backProductNum,orf.backCouponsNum,orf.backWangNum')->find(); + if(empty($orders))return WSTReturn("无效的订单信息"); + //获取订单信息 + $orders['log'] = Db::name('log_orders')->where('orderId',$orderId)->order('logId asc')->select(); + //获取订单商品 + $orders['goods'] = Db::name('order_goods')->where('orderId',$orderId)->order('id asc')->select(); + $orders['userCertificate'] = Db::name('order_certificate')->where(['orderId'=>$orderId,'isShop'=>0])->order('id desc')->select(); + //$orders['shopCertificate'] = Db::name('order_certificate')->where(['orderId'=>$orderId,'isShop'=>1])->order('id desc')->select(); + return $orders; + } + + /** + * 导出订单 + */ + public function toExport(){ + $name='订单表'; + $where = ['o.dataFlag'=>1]; + $orderStatus = (int)input('orderStatus',0); + if($orderStatus==0){ + $name='待发货订单表'; + }else if($orderStatus==-2){ + $name='待付款订单表'; + }else if($orderStatus==1){ + $name='配送中订单表'; + }else if($orderStatus==10000){ + $name='订单列表'; + }else if($orderStatus==-1){ + $name='取消订单表'; + }else if($orderStatus==-3){ + $name='拒收订单表'; + }else if($orderStatus==2){ + $name='已收货订单表'; + } + if($orderStatus!=10000){ + $where['o.orderStatus'] = $orderStatus; + } + $startDate = input('startDate'); + $endDate = input('endDate'); + $orderNo = input('orderNo'); + $shopName = input('shopName'); + $userPhone = input('userPhone'); + $userId = (int)input('userId'); + $payType = (int)input('payType',-1); + $deliverType = (int)input('deliverType',-1); + if($startDate!='' && $endDate!=''){ + $where['o.createTime'] = ['between',[$startDate.' 00:00:00',$endDate.' 23:59:59']]; + }else if($startDate!=''){ + $where['o.createTime'] = ['>=',$startDate.' 00:00:00']; + }else if($endDate!=''){ + $where['o.createTime'] = ['<=',$endDate.' 23:59:59']; + } + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + if($userPhone!='')$where['o.userPhone'] = ['like','%'.$userPhone.'%']; + if($userId>0){ + $where['o.userId'] = $userId; + $user = Db::name('users')->where('userId',$userId)->field('userName')->find(); + $name = $user['userName'].'的订单表'; + } + $areaId1 = (int)input('areaId1'); + if($areaId1>0){ + $where['s.areaIdPath'] = ['like',"$areaId1%"]; + $areaId2 = (int)input("areaId1_".$areaId1); + if($areaId2>0)$where['s.areaIdPath'] = ['like',$areaId1."_"."$areaId2%"]; + $areaId3 = (int)input("areaId1_".$areaId1."_".$areaId2); + if($areaId3>0)$where['s.areaId'] = $areaId3; + } + + if($deliverType!=-1)$where['o.deliverType'] = $deliverType; + if($payType!=-1)$where['o.payType'] = $payType; + $page = $this->alias('o')->where($where) + ->join('__USERS__ u','o.userId=u.userId','left') + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__LOG_ORDERS__ lo','lo.orderId=o.orderId and lo.orderStatus in (-1,-3) ','left') + ->field('o.orderId,o.orderNo,u.loginName,s.shopName,s.shopId,s.shopQQ,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney,o.deliverMoney,lo.logContent,o.orderStatus,o.userName,o.userAddress,o.userPhone,o.orderRemarks,o.invoiceClient,o.receiveTime, + o.deliveryTime,o.deliverType,o.productNum,o.couponsNum,o.wangNum,o.moneyNum,o.productHandlingFee,o.productTaxFee,o.couponsHandlingFee,o.couponsTaxFee,payType,payFrom,o.orderStatus,orderSrc,o.commissionFee,o.createTime') + ->order('o.createTime desc') + ->select(); + if(count($page)>0){ + foreach ($page as $key => $v){ + $page[$key]['userName'] = "【".$v['loginName']."】".$v['userName']; + $page[$key]['payTypeName'] = WSTLangPayType($v['payType']); + $page[$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page[$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(35); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(16); + $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(16); + $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(26); + $objPHPExcel->getActiveSheet()->getColumnDimension('T')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('U')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('V')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('W')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('X')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('Y')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('Z')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:W1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:W1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '订单编号') + ->setCellValue('B1', '订单状态') + ->setCellValue('C1', '店铺名称') + ->setCellValue('D1', '收货人') + ->setCellValue('E1', '收货地址') + ->setCellValue('F1', '联系方式') + ->setCellValue('G1', '支付方式') + ->setCellValue('H1', '配送方式') + ->setCellValue('I1', '买家留言') + ->setCellValue('J1', '发票信息') + ->setCellValue('K1', '订单总金额') + ->setCellValue('L1', '现金额') + ->setCellValue('M1', '旺旺券') + ->setCellValue('N1', '产品券') + ->setCellValue('O1', '产品券税') + ->setCellValue('P1', '产品券手续费') + ->setCellValue('Q1', '优惠券') + ->setCellValue('R1', '优惠券税') + ->setCellValue('S1', '优惠券手续费') + ->setCellValue('T1', '运费') + ->setCellValue('U1', '实付金额') + ->setCellValue('V1', '支付方式') + ->setCellValue('W1', '下单时间') + ->setCellValue('X1', '发货时间') + ->setCellValue('Y1', '收货时间') + ->setCellValue('Z1', '取消/拒收原因'); + $objPHPExcel->getActiveSheet()->getStyle('A1:U1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['orderNo']) + ->setCellValue('B'.$i, $page[$row]['status']) + ->setCellValue('C'.$i, $page[$row]['shopName']) + ->setCellValue('D'.$i, $page[$row]['userName']) + ->setCellValue('E'.$i, $page[$row]['userAddress']) + ->setCellValue('F'.$i, $page[$row]['userPhone']) + ->setCellValue('G'.$i, $page[$row]['payTypeName']) + ->setCellValue('H'.$i, $page[$row]['deliverType']) + ->setCellValue('I'.$i, $page[$row]['orderRemarks']) + ->setCellValue('J'.$i, $page[$row]['invoiceClient']) + ->setCellValue('K'.$i, $page[$row]['totalMoney']) + ->setCellValue('L'.$i, $page[$row]['moneyNum']) + ->setCellValue('M'.$i, $page[$row]['wangNum']) + ->setCellValue('N'.$i, $page[$row]['productNum']) + ->setCellValue('O'.$i, $page[$row]['productTaxFee']) + ->setCellValue('P'.$i, $page[$row]['productHandlingFee']) + ->setCellValue('Q'.$i, $page[$row]['couponsNum']) + ->setCellValue('R'.$i, $page[$row]['couponsTaxFee']) + ->setCellValue('S'.$i, $page[$row]['couponsHandlingFee']) + ->setCellValue('T'.$i, $page[$row]['deliverMoney']) + ->setCellValue('U'.$i, $page[$row]['realTotalMoney']) + ->setCellValue('V'.$i, $page[$row]['payFrom']) + ->setCellValue('W'.$i, $page[$row]['createTime']) + ->setCellValue('X'.$i, $page[$row]['deliveryTime']) + ->setCellValue('Y'.$i, $page[$row]['receiveTime']) + ->setCellValue('Z'.$i, $page[$row]['logContent']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/Payments.php b/hyhproject/admin/model/Payments.php new file mode 100755 index 0000000..ec89338 --- /dev/null +++ b/hyhproject/admin/model/Payments.php @@ -0,0 +1,74 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 支付管理业务处理 + */ +class Payments extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + return $this->field(true)->order('id desc')->paginate(input('limit/d')); + } + public function getById($id){ + return $this->get(['id'=>$id]); + } + + /** + * 编辑 + */ + public function edit(){ + $Id = input('post.id/d',0); + //获取数据 + $data = input('post.'); + $data["payConfig"] = isset($data['payConfig'])?json_encode($data['payConfig']):""; + $data['enabled']=1; + $result = $this->validate('payments.edit')->allowField(true)->save($data,['id'=>$Id]); + if(false !== $result){ + cache('WST_PAY_SRC',null); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d',0); + $data = []; + $data['enabled'] = 0; + $result = $this->update($data,['id'=>$id]); + if(false !== $result){ + cache('WST_PAY_SRC',null); + return WSTReturn("卸载成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + //商家应用ect支付 + public function pay(){ + $data=[]; + $data['shopId']=input('id'); + $data['paymentsId']=6; + $data['status']=input('status'); + //dump($data['shopId']); + $row=db('shop_pay')->where('shopId',$data['shopId'])->find(); + if(!$row){ + $data['status']=1; + db('shop_pay')->insert($data); + return WSTReturn("编辑成功", 1); + } + if($data['status']==1){ + db('shop_pay')->where(['shopId'=>$data['shopId'],'paymentsId'=>$data['paymentsId']]) + ->update(['status'=>0]); + return WSTReturn("编辑成功", 1); + } + if($data['status']==0){ + db('shop_pay')->where(['shopId'=>$data['shopId'],'paymentsId'=>$data['paymentsId']]) + ->update(['status'=>1]); + return WSTReturn("编辑成功", 1); + } + } +} diff --git a/hyhproject/admin/model/Privileges.php b/hyhproject/admin/model/Privileges.php new file mode 100755 index 0000000..49fe266 --- /dev/null +++ b/hyhproject/admin/model/Privileges.php @@ -0,0 +1,116 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 权限业务处理 + */ +class Privileges extends Base{ + /** + * 加载指定菜单的权限 + */ + public function listQuery($parentId){ + $rs = $this->where(['menuId'=>$parentId,'dataFlag'=>1])->order('privilegeId', 'asc')->select(); + return ['Rows'=>$rs,'Total'=>count($rs)]; + } + /** + * 获取指定权限 + */ + public function getById($id){ + return $this->get(['privilegeId'=>$id,'dataFlag'=>1]); + } + + /** + * 新增 + */ + public function add(){ + $result = $this->validate('Privileges.add')->allowField(true)->save(input('post.')); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $id = input('post.id/d'); + $result = $this->validate('Privileges.edit')->allowField(true)->save(input('post.'),['privilegeId'=>$id]); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d'); + $result = $this->where(['privilegeId'=>$id])->delete(); + if(false !== $result){ + WSTClearAllCache(); + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 检测权限代码是否存在 + */ + public function checkPrivilegeCode(){ + $privilegeId = input('privilegeId/d',0); + $code = input('code'); + if($code=='')return WSTReturn("", 1); + $where = []; + $where["privilegeCode"] = $code; + $where["dataFlag"] = 1; + if($privilegeId>0){ + $where["privilegeId"] = ["<>",$privilegeId]; + } + $rs = $this->where($where)->Count(); + if($rs==0)return WSTReturn("", 1); + return WSTReturn("该权限代码已存在!", -1); + } + + /** + * 加载权限并且标用户的权限 + */ + public function listQueryByRole($id){ + $mrs = Db::name('menus')->alias('m')->join('__PRIVILEGES__ p','m.menuId= p.menuId and isMenuPrivilege=1 and p.dataFlag=1','left') + ->where(['parentId'=>$id,'m.dataFlag'=>1]) + ->field('m.menuId id,m.menuName name,p.privilegeCode,1 as isParent') + ->order('menuSort', 'asc') + ->select(); + $prs = $this->where(['dataFlag'=>1,'menuId'=>$id])->field('privilegeId id,privilegeName name,privilegeCode,0 as isParent')->select(); + if($mrs){ + if($prs){ + foreach ($prs as $v){ + array_unshift($mrs,$v); + } + } + }else{ + if($prs)$mrs = $prs; + } + if(!$mrs)return []; + foreach ($mrs as $key =>$v){ + if($v['isParent']==1){ + $mrs[$key]['isParent'] = true; + $mrs[$key]['open'] = true; + }else{ + $mrs[$key]['id'] = 'p'.$v['id']; + } + } + return $mrs; + } + /** + * 加载全部权限 + */ + public function getAllPrivileges(){ + return $this->where(['dataFlag'=>1])->field('menuId,privilegeName,privilegeCode,privilegeUrl,otherPrivilegeUrl')->select(); + } +} diff --git a/hyhproject/admin/model/Recommends.php b/hyhproject/admin/model/Recommends.php new file mode 100755 index 0000000..bbb547c --- /dev/null +++ b/hyhproject/admin/model/Recommends.php @@ -0,0 +1,340 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 推荐业务处理 + + */ + +use think\Db; + +class Recommends extends Base{ + + /** + + * 获取已推荐商品 + + */ + + public function listQueryByGoods(){ + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $rs = $this->alias('r')->join('__GOODS__ g','r.dataId=g.goodsId','inner') + + ->join('__SHOPS__ s','s.shopId=g.shopId','inner') + + ->where(['dataSrc'=>0,'dataType'=>$dataType,'r.goodsCatId'=>$goodsCatId]) + + ->field('dataId,goodsName,shopName,dataSort,isSale,g.dataFlag,goodsStatus')->order('dataSort asc')->select(); + + $data = []; + + foreach ($rs as $key => $v){ + + if($v['isSale']!=1 || $v['dataFlag']!=1 || $v['goodsStatus']!=1)$v['invalid'] = true; + + $data[] = $v; + + } + + return $data; + + } + + /** + + * 推荐商品 + + */ + + public function editGoods(){ + + $ids = input('post.ids'); + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $ids = explode(',',$ids); + + Db::startTrans(); + + try{ + + $this->where(['dataSrc'=>0,'dataType'=>$dataType,'goodsCatId'=>$goodsCatId])->delete(); + + if(!empty($ids)){ + + //查看商品是否有效 + + $rs = Db::name('goods')->where(['goodsStatus'=>1,'dataFlag'=>1,'goodsId'=>['in',$ids]])->field('goodsId')->select(); + + if(!empty($rs)){ + + $data = []; + + foreach ($rs as $key => $v){ + + $tmp = []; + + $tmp['goodsCatId'] = $goodsCatId; + + $tmp['dataSrc'] = 0; + + $tmp['dataType'] = $dataType; + + $tmp['dataId'] = $v['goodsId']; + + $tmp['dataSort'] = (int)input('post.ipt'.$v['goodsId']); + + $data[] = $tmp; + + } + + $this->saveAll($data); + + } + + WSTClearAllCache(); + + } + + Db::commit(); + + return WSTReturn("提交成功", 1); + + }catch(\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('提交失败',-1); + + } + + } + + + + + + /** + + * 获取已推荐店铺 + + */ + + public function listQueryByShops(){ + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $rs = $this->alias('r')->join('__SHOPS__ s','r.dataId=s.shopId','inner') + + ->where(['dataSrc'=>1,'dataType'=>$dataType,'r.goodsCatId'=>$goodsCatId]) + + ->field('dataId,shopSn,shopName,dataSort,shopStatus,dataFlag')->order('dataSort asc')->select(); + + $data = []; + + foreach ($rs as $key => $v){ + + if($v['dataFlag']!=1 || $v['shopStatus']!=1)$v['invalid'] = true; + + $data[] = $v; + + } + + return $data; + + } + + /** + + * 推荐店铺 + + */ + + public function editShops(){ + + $ids = input('post.ids'); + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $ids = explode(',',$ids); + + Db::startTrans(); + + try{ + + $this->where(['dataSrc'=>1,'dataType'=>$dataType,'goodsCatId'=>$goodsCatId])->delete(); + + if(!empty($ids)){ + + //查看商品是否有效 + + $rs = Db::name('shops')->where(['shopStatus'=>1,'dataFlag'=>1,'shopId'=>['in',$ids]])->field('shopId')->select(); + + if(!empty($rs)){ + + $data = []; + + foreach ($rs as $key => $v){ + + $tmp = []; + + $tmp['goodsCatId'] = $goodsCatId; + + $tmp['dataSrc'] = 1; + + $tmp['dataType'] = $dataType; + + $tmp['dataId'] = $v['shopId']; + + $tmp['dataSort'] = (int)input('post.ipt'.$v['shopId']); + + $data[] = $tmp; + + } + + $this->saveAll($data); + + } + + WSTClearAllCache(); + + } + + Db::commit(); + + return WSTReturn("提交成功", 1); + + }catch(\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('提交失败',-1); + + } + + } + + + + + + /** + + * 获取已推荐品牌 + + */ + + public function listQueryByBrands(){ + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $rs = $this->alias('r')->join('__BRANDS__ s','r.dataId=s.brandId','inner') + + ->where(['dataSrc'=>2,'dataType'=>$dataType,'r.goodsCatId'=>$goodsCatId]) + + ->field('dataId,brandName,dataSort,dataFlag')->order('dataSort asc')->select(); + + $data = []; + + foreach ($rs as $key => $v){ + + if($v['dataFlag']!=1)$v['invalid'] = true; + + $data[] = $v; + + } + + return $data; + + } + + /** + + * 推荐品牌 + + */ + + public function editBrands(){ + + $ids = input('post.ids'); + + $dataType = (int)input('post.dataType'); + + $goodsCatId = (int)input('post.goodsCatId'); + + $ids = explode(',',$ids); + + Db::startTrans(); + + try{ + + $this->where(['dataSrc'=>2,'dataType'=>$dataType,'goodsCatId'=>$goodsCatId])->delete(); + + if(!empty($ids)){ + + //查看商品是否有效 + + $rs = Db::name('brands')->where(['dataFlag'=>1,'brandId'=>['in',$ids]])->field('brandId')->select(); + + if(!empty($rs)){ + + $data = []; + + foreach ($rs as $key => $v){ + + $tmp = []; + + $tmp['goodsCatId'] = $goodsCatId; + + $tmp['dataSrc'] = 2; + + $tmp['dataType'] = $dataType; + + $tmp['dataId'] = $v['brandId']; + + $tmp['dataSort'] = (int)input('post.ipt'.$v['brandId']); + + $data[] = $tmp; + + } + + $this->saveAll($data); + + } + + WSTClearAllCache(); + + } + + Db::commit(); + + return WSTReturn("提交成功", 1); + + }catch(\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('提交失败',-1); + + } + + } + +} + diff --git a/hyhproject/admin/model/Reports.php b/hyhproject/admin/model/Reports.php new file mode 100755 index 0000000..1a09435 --- /dev/null +++ b/hyhproject/admin/model/Reports.php @@ -0,0 +1,497 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 报表业务处理 + */ +class Reports extends Base{ + /** + * 获取商品销售统计 + */ + public function topSaleGoodsByPage(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $startTime = strtotime(input('startDate')); + $endTime =strtotime(input('endDate')); + $goodsCatIdPath = input('goodsCatIdPath'); + $shopName = input('post.shopName'); + $goodsName = input('post.goodsName'); + $where='(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1'; + if($shopName)$where.=' AND shopName like "%'.$shopName.'%"'; + if($goodsName)$where.=' AND g.goodsName like "%'.$goodsName.'%"'; + if($goodsCatIdPath !='')$where.=' AND g.goodsCatIdPath like "%'.$goodsCatIdPath.'%"'; + $rs= Db::field('og.goodsId,g.goodsName,goodsSn,s.shopId,shopName,sum(og.goodsNum) goodsNum,og.goodsImg,count(og.goodsId)orderNum,pageNum,goodsCatIdPath') + ->name('order_goods')->alias('og') + ->join('(select p.*,count(p.goodsId) pageNum from __PAGE_VIEW__ p group by p.goodsId ) con','con.goodsId=og.goodsId','left') + ->join('__ORDERS__ o','og.orderId=o.orderId','left') + ->join('__GOODS__ g','og.goodsId=g.goodsId','left') + ->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->order('goodsNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where($where) + ->group('og.goodsId,g.goodsName,goodsSn,s.shopId,shopName,og.goodsImg') + ->paginate(input('limit/d'))->toArray(); + return $rs; + } + /** + * 获取店铺销售统计 + */ + public function topShopSalesByPage(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $shopName = input('shopName'); + $where='(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1'; + if($shopName)$where.=' AND shopName like "%'.$shopName.'%"'; + $rs = Db::field('s.shopId,s.shopImg,s.shopName,sum(o.totalMoney) totalMoney,count(o.shopId) orderNum,s.userId') + ->name('shops')->alias('s') + ->join('__ORDERS__ o','s.shopId=o.shopId') + ->order('totalMoney desc,orderNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where($where) + ->group('o.shopId') + ->paginate(input('limit/d'))->toArray(); + foreach($rs['Rows'] as $k=>$v){ + $onLineArr = Db::name('orders') + ->whereTime('createTime','between',[$start,$end]) + ->field('sum(totalMoney) totalMoney,sum(realTotalMoney) realTotalMoney') + ->where('payType=1 and isPay=1 and dataFlag=1 and orderStatus=2') + ->where(['shopId'=>$v['shopId']]) + ->find(); + $rs['Rows'][$k]['onLinePayMoney'] = (float)$onLineArr['totalMoney'];// 在线支付总金额 + $rs['Rows'][$k]['onLinePayTrueMoney'] = (float)$onLineArr['realTotalMoney'];// 在线支付实际金额 + $rs['Rows'][$k]['offLinePayMoney'] = (float)Db::name('orders') + ->whereTime('createTime','between',[$start,$end]) + ->where('payType=0 and dataFlag=1 and orderStatus=2') + ->where(['shopId'=>$v['shopId']]) + ->value('sum(totalMoney)');;// 货到付款金额 + $rs['Rows'][$k]['ectNum']=db('user_ect_log')->where(['userId'=>$v['userId'],'ectType'=>12])->value('sum(ectNum)ectNum'); + } + return $rs; + + } + + /** + * 获取销售额 + */ + public function statSales(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $payType = (int)input('payType',-1); + $rs = Db::field('left(createTime,10) createTime,orderSrc,sum(totalMoney) totalMoney')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('((payType=0 or (payType=1 and isPay=1)) and dataFlag=1) '.(in_array($payType,[0,1])?" and payType=".$payType:'')) + ->order('createTime asc') + ->group('left(createTime,10),orderSrc')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $payTypes = [0,1,2,3,4]; + $tmp = []; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['orderSrc']."_".$v['createTime']] = $v['totalMoney']; + } + $rdata['map'] = ['p0'=>0,'p1'=>0,'p2'=>0,'p3'=>0,'p4'=>0]; + foreach($days as $v){ + $total = 0; + foreach($payTypes as $p){ + $pv = isset($tmp[$p."_".$v])?$tmp[$p."_".$v]:0; + $rdata['p'.$p][] = (float)$pv; + $total = $total + (float)$pv; + $rdata['map']['p'.$p] = $rdata['map']['p'.$p] + (float)$pv; + } + $rdata['total'][] = $total; + } + $rdata['days'] = $days; + } + return WSTReturn('',1,$rdata); + } + + /** + * 获取订单统计 + */ + public function statOrders(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $payType = (int)input('payType',-1); + $rs = Db::field('left(createTime,10) createTime,orderSrc,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('((payType=0 or (payType=1 and isPay=1)) and dataFlag=1) '.(in_array($payType,[0,1])?" and payType=".$payType:'')) + ->order('createTime asc') + ->group('left(createTime,10),orderSrc')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $payTypes = [0,1,2,3,4]; + $tmp = []; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['orderSrc']."_".$v['createTime']] = $v['orderNum']; + } + $rdata['map'] = ['p0'=>0,'p1'=>0,'p2'=>0,'p3'=>0,'p4'=>0]; + foreach($days as $v){ + $total = 0; + foreach($payTypes as $p){ + $pv = isset($tmp[$p."_".$v])?$tmp[$p."_".$v]:0; + $rdata['p'.$p][] = (float)$pv; + $total = $total + (float)$pv; + $rdata['map']['p'.$p] = $rdata['map']['p'.$p] + (float)$pv; + } + $rdata['total'][] = $total; + } + $rdata['days'] = $days; + } + return WSTReturn('',1,$rdata); + } + /*首页获取订单数量*/ + public function getOrders(){ + $data = cache('orderData'); + if(empty($data)){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $payType = -1; + $rs = Db::field('left(createTime,10) createTime,orderSrc,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('((payType=0 or (payType=1 and isPay=1)) and dataFlag=1) '.(in_array($payType,[0,1])?" and payType=".$payType:'')) + ->order('createTime asc') + ->group('left(createTime,10),orderSrc')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + $payTypes = [0,1,2,3,4]; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['orderSrc']."_".$v['createTime']] = $v['orderNum']; + } + foreach($days as $v){ + $total = 0; + foreach($payTypes as $p){ + $pv = isset($tmp[$p."_".$v])?$tmp[$p."_".$v]:0; + $total = $total + (float)$pv; + } + $rdata['total'][] = $total; + } + $rdata['days'] = $days; + cache('orderData',$rdata,7200); + } + }else{ + $rdata = cache('orderData'); + } + return WSTReturn('',1,$rdata); + } + /** + * 获取新增用户 + */ + public function statNewUser(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $urs = Db::field('left(createTime,10) createTime,count(userId) userNum') + ->name('users') + ->whereTime('createTime','between',[$start,$end]) + ->where(['dataFlag'=>1,'userType'=>0]) + ->order('createTime asc') + ->group('left(createTime,10)') + ->select(); + $srs = Db::field('left(createTime,10) createTime,count(shopId) userNum') + ->name('shops') + ->whereTime('createTime','between',[$start,$end]) + ->where(['dataFlag'=>1]) + ->order('createTime asc') + ->group('left(createTime,10)') + ->select(); + $rdata = []; + $days = []; + $tmp = []; + if(count($urs)>0){ + foreach($urs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp["0_".$v['createTime']] = $v['userNum']; + } + } + if(count($srs)>0){ + foreach($srs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp["1_".$v['createTime']] = $v['userNum']; + } + } + sort($days); + foreach($days as $v){ + $rdata['u0'][] = isset($tmp['0_'.$v])?$tmp['0_'.$v]:0; + $rdata['u1'][] = isset($tmp['1_'.$v])?$tmp['1_'.$v]:0; + } + $rdata['days'] = $days; + return WSTReturn('',1,$rdata); + } + /** + * 会员登录统计 + */ + public function statUserLogin(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $prefix = config('database.prefix'); + $sql ='select createTime,userType,count(userId) userNum from ( + SELECT left(loginTime,10) createTime,`userType`,u.userId + FROM `'.$prefix.'users` `u` INNER JOIN `'.$prefix.'log_user_logins` `lg` ON `u`.`userId`=`lg`.`userId` + WHERE `loginTime` BETWEEN "'.$start.'" AND "'.$end.'" AND ( dataFlag=1 ) + GROUP BY left(loginTime,10),userType,lg.userId + ) a GROUP BY createTime, userType ORDER BY createTime asc '; + $rs = Db::query($sql); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['userType']."_".$v['createTime']] = $v['userNum']; + } + foreach($days as $v){ + $rdata['u0'][] = isset($tmp['0_'.$v])?$tmp['0_'.$v]:0; + $rdata['u1'][] = isset($tmp['1_'.$v])?$tmp['1_'.$v]:0; + } + $rdata['days'] = $days; + } + return WSTReturn('',1,$rdata); + } + /** + * 导出商品销售订单 + */ + public function toExportGoods(){ + $name='商品销售统计表'; + $start = input('startDate'); + $end = input('endDate'); + $where=[]; + $shopName = input('shopName'); + $goodsName = input('goodsName'); + $goodsCatIdPath = input('goodsCatIdPath'); + if($goodsCatIdPath !='')$where['g.goodsCatIdPath'] = ['like','%'.$goodsCatIdPath.'%']; + if($shopName!='')$where['shopName'] = ['like','%'.$shopName.'%']; + if($goodsName!='')$where['g.goodsName'] = ['like','%'.$goodsName.'%']; + if($start!='' && $end!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where['o.createTime'] = ['between',[$start.' 00:00:00',$end.' 23:59:59']]; + }else if($start!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $where['o.createTime'] = ['>=',$start.' 00:00:00']; + }else if($end!=''){ + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where['o.createTime'] = ['<=',$end.' 23:59:59']; + } + $page=Db::field('og.goodsId,g.goodsName,goodsSn,s.shopId,shopName,sum(og.goodsNum) goodsNum,og.goodsImg,count(og.goodsId)orderNum,pageNum') + ->name('order_goods')->alias('og') + ->join('(select p.*,count(p.goodsId) pageNum from __PAGE_VIEW__ p group by p.goodsId ) con','con.goodsId=og.goodsId','left') + ->join('__ORDERS__ o','og.orderId=o.orderId','left') + ->join('__GOODS__ g','og.goodsId=g.goodsId','left') + ->join('__SHOPS__ s','g.shopId=s.shopId','left') + ->order('goodsNum desc') + ->where($where) + ->where('(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1') + ->group('og.goodsId,g.goodsName,goodsSn,s.shopId,shopName,og.goodsImg') + ->select(); + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '商品ID') + ->setCellValue('B1', '商品编号') + ->setCellValue('C1', '商品名称') + ->setCellValue('D1', '商品销量') + ->setCellValue('E1', '所属店铺') + ->setCellValue('F1', '订单总数') + ->setCellValue('G1', '浏览总数'); + $objPHPExcel->getActiveSheet()->getStyle('A1:G1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['goodsId']) + ->setCellValue('B'.$i, chunk_split($page[$row]['goodsSn'])) + ->setCellValue('C'.$i, $page[$row]['goodsName']) + ->setCellValue('D'.$i, $page[$row]['goodsNum']) + ->setCellValue('E'.$i, $page[$row]['shopName']) + ->setCellValue('F'.$i, $page[$row]['orderNum']) + ->setCellValue('G'.$i, $page[$row]['pageNum']); + + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } + /** + * 导出商品销售订单 + */ + public function toExportShop(){ + $name='店铺销售统计表'; + $start = input('startDate'); + $end = input('endDate'); + $shopName = input('shopName'); + $wh='(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1'; + if($shopName)$wh.=' AND shopName like "%'.$shopName.'%"'; + $where=[]; + if($start!='' && $end!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where['o.createTime'] = ['between',[$start.' 00:00:00',$end.' 23:59:59']]; + }else if($start!=''){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $where['o.createTime'] = ['>=',$start.' 00:00:00']; + }else if($end!=''){ + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $where['o.createTime'] = ['<=',$end.' 23:59:59']; + } + $page=Db::field('s.shopId,s.shopImg,s.shopName,sum(o.totalMoney) totalMoney,count(o.orderId) orderNum') + ->name('shops')->alias('s') + ->join('__ORDERS__ o','s.shopId=o.shopId') + ->order('totalMoney desc,orderNum desc') + ->where($where) + ->where($wh) + ->group('o.shopId') + ->select(); + + foreach($page as $k=>$v){ + $onLineArr = Db::name('orders')->alias('o') + ->where($where) + ->field('sum(totalMoney) totalMoney,sum(realTotalMoney) realTotalMoney') + ->where('payType=1 and isPay=1 and dataFlag=1 and orderStatus=2') + ->where(['shopId'=>$v['shopId']]) + ->find(); + $page[$k]['onLinePayMoney'] = (float)$onLineArr['totalMoney'];// 在线支付总金额 + $page[$k]['onLinePayTrueMoney'] = (float)$onLineArr['realTotalMoney'];// 在线支付实际金额 + $page[$k]['offLinePayMoney'] = (float)Db::name('orders')->alias('o') + ->where($where) + ->where('payType=0 and dataFlag=1 and orderStatus=2') + ->where(['shopId'=>$v['shopId']]) + ->value('sum(totalMoney)');;// 货到付款金额 + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:H1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '店铺名称') + ->setCellValue('B1', '订单总金额') + ->setCellValue('C1', '订单总数') + ->setCellValue('D1', '在线支付总金额') + ->setCellValue('E1', '在线支付实际金额') + ->setCellValue('F1', '货到付款金额'); + $objPHPExcel->getActiveSheet()->getStyle('A1:E1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['shopName']) + ->setCellValue('B'.$i, $page[$row]['totalMoney']) + ->setCellValue('C'.$i, $page[$row]['orderNum']) + ->setCellValue('D'.$i, $page[$row]['onLinePayMoney']) + ->setCellValue('E'.$i, $page[$row]['onLinePayTrueMoney']) + ->setCellValue('F'.$i, $page[$row]['offLinePayMoney']); + + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} \ No newline at end of file diff --git a/hyhproject/admin/model/Roles.php b/hyhproject/admin/model/Roles.php new file mode 100755 index 0000000..b02be51 --- /dev/null +++ b/hyhproject/admin/model/Roles.php @@ -0,0 +1,75 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 角色志业务处理 + */ +class Roles extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + return $this->where('dataFlag',1)->field('roleId,roleName,roleDesc')->paginate(input('limit/d')); + } + /** + * 列表 + */ + public function listQuery(){ + return $this->where('dataFlag',1)->field('roleId,roleName')->select(); + } + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['roleId'=>$id]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 获取角色权限 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'roleId'=>$id]); + } + + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + $result = $this->validate('Roles.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $id = input('post.roleId/d'); + $result = $this->validate('Roles.edit')->allowField(true)->save(input('post.'),['roleId'=>$id]); + if(false !== $result){ + $staffRoleId = (int)session('WST_STAFF.staffRoleId'); + if($id==$staffRoleId){ + $STAFF = session('WST_STAFF'); + $STAFF['privileges'] = explode(',',input('post.privileges')); + $STAFF['roleName'] = Input('post.roleName'); + session('WST_STAFF',$STAFF); + } + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/Settlements.php b/hyhproject/admin/model/Settlements.php new file mode 100755 index 0000000..3b06055 --- /dev/null +++ b/hyhproject/admin/model/Settlements.php @@ -0,0 +1,795 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +use think\Loader; + +/** + + * ============================================================================ + + * 结算业务处理 + + */ + +class Settlements extends Base{ + + /** + + * 获取结算列表 + + */ + + public function pageQuery(){ + + $settlementNo = input('settlementNo'); + + $shopName = input('shopName'); + + $settlementStatus = (int)input('settlementStatus',-1); + + $sort = input('sort'); + + $where = []; + + if($settlementNo!='')$where['settlementNo'] = ['like','%'.$settlementNo.'%']; + + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + + if($settlementStatus>=0)$where['settlementStatus'] = $settlementStatus; + + $order = 'st.settlementId desc'; + + if($sort){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + if($sortArr[0]=='settlementNo'){ + + $order = $sortArr[0].'+0 '.$sortArr[1]; + + } + + } + + $result=Db::name('settlements')->alias('st') + + ->join('__SHOPS__ s','s.shopId=st.shopId','left') + + ->join('__ORDERS__ o','o.settlementId=st.settlementId','left') + + ->join('__SHOPS_DEPOSIT_DETAIL__ sd','sd.orderId=o.orderId','left') + + ->join('__PAYMENTS__ p','p.payCode=o.payFrom','left') + + ->where($where)->field('s.shopName,settlementNo,sd.cashDeposit,st.settlementId,st.settlementMoney,st.commissionFee,st.backMoney,st.settlementStatus,st.settlementTime,st.createTime,payFrom,payName')->order($order) + + ->paginate(input('limit/d'))->toArray(); + + return $result; + + } + + + + /** + + * 获取结算订单详情 + + */ + + public function getById(){ + + $settlementId = (int)input('id'); + + $object = Db::name('settlements')->alias('st')->where('settlementId',$settlementId)->join('__SHOPS__ s','s.shopId=st.shopId','left')->field('s.shopName,st.*')->find(); + + // dump($object);die; + + + + if(!empty($object)){ + + $object['list'] = Db::name('orders')->alias('o')->join('__SHOPS_DEPOSIT_DETAIL__ sd','o.orderId=sd.orderId','left')->where(['o.settlementId'=>$settlementId]) + + ->field('sd.cashDeposit,o.orderId,orderNo,o.payType,goodsMoney,deliverMoney,realTotalMoney,totalMoney,commissionFee,scoreMoney,createTime') + + ->order('payType desc,orderId desc')->select(); + + } + + // dump($object);die; + + return $object; + + } + + /** + + * 处理订单 + + */ + + public function handle(){ + + $id = (int)input('settlementId'); + + $remarks = input('remarks'); + + Db::startTrans(); + + try{ + + $object = $this->get($id); + + $object->settlementStatus = 1; + + $object->settlementTime = date('Y-m-d H:i:s'); + + if($remarks!='')$object->remarks = $remarks; + + $rs = $object->save(); + + if(false !== $rs){ + + $shop = model('Shops')->get($object->shopId); + + WSTSendMsg($shop['userId'],"您的结算申请【".$object->settlementNo."】已处理,请留意到账户息哦~",['from'=>4,'dataId'=>$id]); + + $shop->shopMoney = $shop->shopMoney+$object->backMoney; + + $shop->paymentMoney = $shop->paymentMoney + $object->commissionFee; + + $shop->save(); + + $lmarr = []; + + //增加资金变动信息 + + if($object->settlementMoney>0){ + + $lm = []; + + $lm['targetType'] = 1; + + $lm['targetId'] = $object->shopId; + + $lm['dataId'] = $id; + + $lm['dataSrc'] = 2; + + $lm['remark'] = '结算订单申请【'.$object->settlementNo.'】收入订单金额¥'.$object->settlementMoney; + + $lm['moneyType'] = 1; + + $lm['money'] = $object->settlementMoney; + + $lm['payType'] = 0; + + $lm['createTime'] = date('Y-m-d H:i:s'); + + $lmarr[] = $lm; + + } + + if($object->commissionFee>0){ + + //要对有积分支付的佣金记录进行处理 + + $commissionFee = $object->commissionFee; + + //如果backMoney小于0则说明平台收到的钱不足以支付佣金,这个backMoney已经减去了积分支付,所以直接显示backMoney为应付的佣金就好 + + if($object->backMoney<0){ + + $commissionFee = $object->backMoney; + + } + + $lm = []; + + $lm['targetType'] = 1; + + $lm['targetId'] = $object->shopId; + + $lm['dataId'] = $id; + + $lm['dataSrc'] = 2; + + $lm['remark'] = '结算订单申请【'.$object->settlementNo.'】支出订单佣金¥'.$commissionFee."。".(($object->remarks!='')?"【操作备注】:".$object->remarks:''); + + $lm['moneyType'] = 0; + + $lm['money'] = $commissionFee; + + $lm['payType'] = 0; + + $lm['createTime'] = date('Y-m-d H:i:s'); + + $lmarr[] = $lm; + + } + + if(count($lmarr)>0)model('LogMoneys')->saveAll($lmarr); + + Db::commit(); + + return WSTReturn('操作成功!',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('操作失败!',-1); + + } + + + + /** + + * 获取订单商品 + + */ + + public function pageGoodsQuery(){ + + $id = (int)input('id'); + + return Db::name('orders')->alias('o')->join('__ORDER_GOODS__ og','o.orderId=og.orderId')->where('o.settlementId',$id) + + ->field('orderNo,og.goodsPrice,og.goodsName,og.goodsSpecNames,og.goodsNum,og.commissionRate')->order('o.payType desc,o.orderId desc')->paginate(input('limit/d'))->toArray(); + + } + + + + /** + + * 获取待结算商家 + + */ + + public function pageShopQuery(){ + + $areaIdPath = input('areaIdPath'); + + $shopName = input('shopName'); + + $where = []; + + if($shopName!='')$where['s.shopName|s.shopSn'] = ['like','%'.$shopName.'%']; + + if($areaIdPath !='')$where['s.areaIdPath'] = ['like',$areaIdPath."%"]; + + $where['s.dataFlag'] = 1; + + $where['s.noSettledOrderNum'] = ['>',0]; + + return Db::table('__SHOPS__')->alias('s')->join('__AREAS__ a2','s.areaId=a2.areaId') + + ->where($where) + + ->field('shopId,shopSn,shopName,a2.areaName,shopkeeper,telephone,abs(noSettledOrderFee) noSettledOrderFee,noSettledOrderNum') + + ->order('noSettledOrderFee desc')->paginate(input('limit/d')); + + + + } + + + + /** + + * 获取商家未结算的订单 + + */ + + public function pageShopOrderQuery(){ + + $orderNo = input('orderNo'); + + $payType = (int)input('payType',-1); + + $where = []; + + $where['settlementId'] = 0; + + $where['orderStatus'] = 2; + + $where['shopId'] = (int)input('id'); + + $where['dataFlag'] = 1; + + if($orderNo!='')$where['orderNo'] = ['like','%'.$orderNo.'%']; + + if(in_array($payType,[0,1]))$where['payType'] = $payType; + + $page = Db::name('orders')->where($where) + + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,realTotalMoney,totalMoney,commissionFee,createTime') + + ->order('payType desc,orderId desc')->paginate(input('limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + + foreach ($page['Rows'] as $key => $v) { + + $page['Rows'][$key]['payTypeName'] = WSTLangPayType($v['payType']); + + } + + } + + return $page; + + } + + + + /** + + * 生成结算单 + + */ + + public function generateSettleByShop(){ + + $shopId = (int)input('id'); + + $where = []; + + $where['shopId'] = $shopId; + + $where['dataFlag'] = 1; + + $where['orderStatus'] = 2; + + $where['settlementId'] = 0; + + $orders = Db::name('orders')->where($where)->field('orderId,payType,realTotalMoney,scoreMoney,commissionFee')->select(); + + if(empty($orders))return WSTReturn('没有需要结算的订单,请刷新后再核对!'); + + $settlementMoney = 0; + + $commissionFee = 0; //平台要收的佣金 + + $ids = []; + + foreach ($orders as $key => $v) { + + $ids[] = $v['orderId']; + + if($v['payType']==1){ + + $settlementMoney += $v['realTotalMoney']+$v['scoreMoney']; + + }else{ + + $settlementMoney += $v['scoreMoney']; + + } + + $commissionFee += abs($v['commissionFee']); + + } + + $backMoney = $settlementMoney-$commissionFee; + + $shops = model('shops')->get($shopId); + + if(empty($shops))WSTReturn('无效的店铺结算账号!'); + + Db::startTrans(); + + try{ + + $data = []; + + $data['settlementType'] = 0; + + $data['shopId'] = $shopId; + + $data['settlementMoney'] = $settlementMoney; + + $data['commissionFee'] = $commissionFee; + + $data['backMoney'] = $settlementMoney-$commissionFee; + + $data['settlementStatus'] = 1; + + $data['settlementTime'] = date('Y-m-d H:i:s'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + $data['settlementNo'] = ''; + + $result = $this->save($data); + + if(false !== $result){ + + $this->settlementNo = $this->settlementId.(fmod($this->settlementId,7)); + + $this->save(); + + //修改商家订单情况 + + Db::name('orders')->where(['orderId'=>['in',$ids]])->update(['settlementId'=>$this->settlementId]); + + $shops->shopMoney = $shops->shopMoney + $backMoney; + + $shops->noSettledOrderNum = 0; + + $shops->noSettledOrderFee = 0; + + $shops->paymentMoney = 0; + + //修改商家充值金额 + + $lockCashMoney = (($shops->rechargeMoney - $commissionFee)>=0)?($shops->rechargeMoney - $commissionFee):0; + + $shops->rechargeMoney = $lockCashMoney; + + $shops->save(); + + + + //发消息 + + $tpl = WSTMsgTemplates('SHOP_SETTLEMENT'); + + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + + $find = ['${SETTLEMENT_NO}']; + + $replace = [$this->settlementNo]; + + + + $msg = array(); + + $msg["shopId"] = $shopId; + + $msg["tplCode"] = $tpl["tplCode"]; + + $msg["msgType"] = 1; + + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']) ; + + $msg["msgJson"] = ['from'=>4,'dataId'=>$this->settlementId]; + + model("common/MessageQueues")->add($msg); + + } + + //增加资金变动信息 + + $lmarr = []; + + if($settlementMoney>0){ + + $lm = []; + + $lm['targetType'] = 1; + + $lm['targetId'] = $shopId; + + $lm['dataId'] = $this->settlementId; + + $lm['dataSrc'] = 2; + + $lm['remark'] = '结算订单申请【'.$this->settlementNo.'】收入订单金额¥'.$settlementMoney."。"; + + $lm['moneyType'] = 1; + + $lm['money'] = $settlementMoney; + + $lm['payType'] = 0; + + $lm['createTime'] = date('Y-m-d H:i:s'); + + $lmarr[] = $lm; + + } + + if($commissionFee>0){ + + $lm = []; + + $lm['targetType'] = 1; + + $lm['targetId'] = $shopId; + + $lm['dataId'] = $this->settlementId; + + $lm['dataSrc'] = 2; + + $lm['remark'] = '结算订单申请【'.$this->settlementNo.'】收取订单佣金¥'.$commissionFee."。"; + + $lm['moneyType'] = 0; + + $lm['money'] = $commissionFee; + + $lm['payType'] = 0; + + $lm['createTime'] = date('Y-m-d H:i:s'); + + $lmarr[] = $lm; + + } + + if(count($lmarr)>0)model('LogMoneys')->saveAll($lmarr); + + Db::commit(); + + return WSTReturn('生成结算单成功',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + return WSTReturn('生成结算单失败',-1); + + } + + /** + + * 导出 + + */ + + public function toExport(){ + + $name='结算申请表'; + + $settlementNo = input('settlementNo'); + + $shopName = input('shopName'); + + $settlementStatus = (int)input('settlementStatus',-1); + + $sort = input('sort'); + + $where = []; + + if($settlementNo!='')$where['settlementNo'] = ['like','%'.$settlementNo.'%']; + + if($shopName!='')$where['shopName|shopSn'] = ['like','%'.$shopName.'%']; + + if($settlementStatus>=0)$where['settlementStatus'] = $settlementStatus; + + $order = 'st.settlementId desc'; + + if($sort){ + + $sortArr = explode('.',$sort); + + $order = $sortArr[0].' '.$sortArr[1]; + + if($sortArr[0]=='settlementNo'){ + + $order = $sortArr[0].'+0 '.$sortArr[1]; + + } + + } + + $page=Db::name('settlements')->alias('st') + + ->join('__SHOPS__ s','s.shopId=st.shopId','left') + + ->join('__ORDERS__ o','o.settlementId=st.settlementId','left') + + ->join('__SHOPS_DEPOSIT_DETAIL__ sd','sd.orderId=o.orderId','left') + + ->join('__PAYMENTS__ p','p.payCode=o.payFrom','left') + + ->where($where)->field('s.shopName,settlementNo,sd.cashDeposit,st.settlementId,st.settlementMoney,st.commissionFee,st.backMoney,st.settlementStatus,st.settlementTime,st.createTime,payFrom,payName')->order($order) + + ->select(); + + foreach($page as &$v){ + + $order_list=db('orders')->where('settlementId',$v['settlementId'])->field('orderNo,realTotalMoney,scoreMoney')->select(); + + $v['order_number']=''; + + if(count($order_list)>0){ + + foreach($order_list as $val){ + + $v['order_number']=$v['order_number'].$val['orderNo'].',';// + + } + + //.$order_list['realTotalMoney'].$order_list['scoreMoney']; + + } + + } + + Loader::import('phpexcel.PHPExcel.IOFactory'); + + $objPHPExcel = new \PHPExcel(); + + // 设置excel文档的属性 + + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + + ->setLastModifiedBy("WSTMart")//最后修改人 + + ->setTitle($name)//标题 + + ->setSubject($name)//题目 + + ->setDescription($name)//描述 + + ->setKeywords("结算")//关键字 + + ->setCategory("Test result file");//种类 + + + + // 开始操作excel表 + + $objPHPExcel->setActiveSheetIndex(0); + + // 设置工作薄名称 + + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + + // 设置默认字体和大小 + + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + + $styleArray = array( + + 'font' => array( + + 'bold' => true, + + 'color'=>array( + + 'argb' => 'ffffffff', + + ) + + ), + + 'borders' => array ( + + 'outline' => array ( + + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + + ) + + ) + + ); + + //设置宽 + + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + + $objPHPExcel->getActiveSheet()->getStyle('A1:K1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + + $objPHPExcel->getActiveSheet()->getStyle('A1:K1')->getFill()->getStartColor()->setARGB('333399'); + + + + $objPHPExcel->getActiveSheet()->setCellValue('A1', '结算单号') + + ->setCellValue('B1', '申请店铺')->setCellValue('C1', '结算金额') + + ->setCellValue('D1', '结算佣金')->setCellValue('E1', '扣除质保金')->setCellValue('F1', '返还金额') + + ->setCellValue('G1', '申请时间')->setCellValue('H1', '状态') + + ->setCellValue('I1', '订单单号')->setCellValue('J1', '支付方式'); + + $objPHPExcel->getActiveSheet()->getStyle('A1:I1')->applyFromArray($styleArray); + + + + for ($row = 0; $row < count($page); $row++){ + + $i = $row+2; + + $objPHPExcel->getActiveSheet() + + ->setCellValue('A'.$i, $page[$row]['settlementNo']) + + ->setCellValue('B'.$i, $page[$row]['shopName']) + + ->setCellValue('C'.$i, '¥'.$page[$row]['settlementMoney']) + + ->setCellValue('D'.$i, '¥'.$page[$row]['commissionFee']) + + ->setCellValue('E'.$i, '¥'.(float)$page[$row]['cashDeposit']) + + ->setCellValue('F'.$i, '¥'.$page[$row]['backMoney']) + + ->setCellValue('G'.$i, $page[$row]['createTime']) + + ->setCellValue('H'.$i, $page[$row]['settlementStatus']==1?'已结算':'未结算') + + ->setCellValue('I'.$i, $page[$row]['order_number']) + + ->setCellValue('J'.$i, $page[$row]['payName']); + + + + } + + + + //输出EXCEL格式 + + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + + // 从浏览器直接输出$filename + + header('Content-Type:application/csv;charset=UTF-8'); + + header("Pragma: public"); + + header("Expires: 0"); + + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + + header("Content-Type:application/force-download"); + + header("Content-Type:application/vnd.ms-excel;"); + + header("Content-Type:application/octet-stream"); + + header("Content-Type:application/download"); + + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + + header("Content-Transfer-Encoding:binary"); + + $objWriter->save('php://output'); + + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/Shops.php b/hyhproject/admin/model/Shops.php new file mode 100755 index 0000000..9dfab12 --- /dev/null +++ b/hyhproject/admin/model/Shops.php @@ -0,0 +1,1367 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +use think\Validate; +/** + * ============================================================================ + * 店铺业务处理 + */ +class Shops extends Base{ + /** + * 分页 + */ + public function pageQuery($shopStatus=1){ + $areaIdPath = input('areaIdPath'); + $shopName = input('shopName'); + $telephone = input('userPhone'); + $catId =(int)input('cat'); + $isInvestment = (int)input('isInvestment/d',-1); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.applyStatus'] = 2; + $where['s.shopStatus'] = $shopStatus; + if($catId!="0"){ + $where['c.catId'] = $catId; + } + if(in_array($isInvestment,[0,1]))$where['ss.isInvestment'] = $isInvestment; + if($shopName!='')$where['shopName'] = ['like','%'.$shopName.'%']; + if($telephone!='')$where['telephone'] = ['like','%'.$telephone.'%']; + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($catId !='')$where['catId'] = ['like',$catId."%"]; + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $result=Db::table('__SHOPS__')->alias('s') + ->join('__AREAS__ a2','s.areaId=a2.areaId','left') + ->join('__USERS__ u','u.userId=s.userId','left') + ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','left') + ->join('__CAT_SHOPS__ c','c.shopId=s.shopId','left') + ->join('__SHOP_PAY__ sp','sp.shopId=s.shopId','left') + ->join('__SHOP_COMMISSION__ sc','sc.shopId=s.shopId','left') + ->where($where) + ->field('u.loginName,s.shopId,shopSn,shopName,a2.areaName,shopkeeper,telephone,shopAddress,shopCompany,shopAtive,shopStatus,s.applyTime,s.createTime,sp.status,sc.commission') + ->order('createTime desc')->group('s.shopId') + ->paginate(input('limit/d'))->toArray(); + foreach ($result['Rows'] as &$value) { + $catName=db('cat_shops')->alias('a')->join('goods_cats g','g.catId=a.catId') + ->where('shopId',$value['shopId'])->field('catName')->select(); + $value['catName']=""; + if(count($catName)>1){ + foreach ($catName as &$v) { + $value['catName']=$value['catName'].$v['catName'].','; + } + } + $goodsNum=db('goods')->alias('g')->where(['shopId'=>$value['shopId'],'isSale'=>1,'dataFlag'=>1])->field('count(goodsId)goodsNum')->select(); + $value['goodsNum']=""; + foreach ($goodsNum as &$v) { + $value['goodsNum']=$value['goodsNum'].$v['goodsNum']; + } + } + return $result; + } + /** + * 分页>where('a.orgin_id=b.id AND a.orgin_id=c.orgin_id AND b.status='.$status.' AND a.task_name like %'.$serch_val.'%') + */ + public function pageQueryByApply(){ + $areaIdPath = input('areaIdPath'); + //$catId = input('cat/d'); + $shopName = input('shopName'); + $investmentStaff = input('investmentStaff');// mark hsf 20180112 + $isInvestment = (int)input('isInvestment/d',-1); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.applyStatus'] = ['in',[-1,1,2]];// mark hsf 20180112 + if(in_array($isInvestment,[0,1]))$where['ss.isInvestment'] = $isInvestment; + if($shopName!='')$where['shopName'] = ['like','%'.$shopName.'%']; + if($investmentStaff!='')$where['ss.investmentStaff'] = ['like','%'.$investmentStaff.'%'];// mark hsf 20180112 + //if($catId !='')$where['catId'] = ['like',$catId."%"]; + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + return Db::table('__SHOPS__')->alias('s')->join('__AREAS__ a2','s.areaId=a2.areaId','left') + ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','left') + ->join('__USERS__ u','u.userId=s.userId','left') + //->join('__CAT_SHOPS__ c','c.shopId=s.shopId','left') + ->where($where) + ->field('u.loginName,s.shopId,applyLinkMan,applyLinkTel,investmentStaff,isInvestment,shopName,a2.areaName,shopAddress,shopCompany,applyTime,applyStatus') + ->order('s.applyStatus=1 DESC,s.applyStatus ASC,s.shopId desc')->paginate(input('limit/d'));// mark hsf 20180112 + } + /** + * 开店申请列表 + */ + public function shopApplyList(){ + //$areaIdPath = input('areaIdPath'); + $shopName = input('shopName'); + $where = []; + $where['s.dataFlag'] = 1; + if($shopName!='')$where['shopName'] = ['like','%'.$shopName.'%']; + //if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + return Db::name('shops')->alias('s') + ->join('__USERS__ u','u.userId=s.userId','left') + ->where($where) + ->field('u.loginName,u.trueName,s.*,from_unixtime(s.createTime) applyTime') + ->order('s.status ASC,s.createTime ASC')->paginate(input('limit/d'));// mark hsf 20180112 + // return Db::table('__SHOPS__')->alias('s')->join('__AREAS__ a2','s.areaId=a2.areaId','left') + // ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','left') + // ->join('__USERS__ u','u.userId=s.userId','left') + // //->join('__CAT_SHOPS__ c','c.shopId=s.shopId','left') + // ->where($where) + // ->field('u.loginName,s.shopId,applyLinkMan,applyLinkTel,investmentStaff,isInvestment,shopName,a2.areaName,shopAddress,shopCompany,applyTime,applyStatus') + // ->order('s.applyStatus=1 DESC,s.applyStatus ASC,s.shopId desc')->paginate(input('limit/d'));// mark hsf 20180112 + } + + /** + * 为店铺添加质保金 + */ + public function topDeposit(){ + Db::startTrans(); + try{ + $shopId = input('shopId'); + $applyStatus = (int)input('applyStatus'); + $cashDeposit = input('addDeposit');//充值质保金金额 + $offDeposit = input('offDeposit');//扣除质保金金额 + $offCause = input('offCause');//扣除质保金原因 + // echo $offCause;die; + // echo $applyStatus;die; + if($applyStatus == 1){ + $deposit_info = Db::name('shops_deposit')->where('shopId',$shopId)->field('shopId,payDeposit,cashDeposit')->find(); + // dump($deposit_info);die; + $data_deposit['cashDeposit'] = $deposit_info['cashDeposit'] + $cashDeposit; + // echo $data_deposit['cashDeposit'];die; + + if($deposit_info['payDeposit'] < $data_deposit['cashDeposit']){ + return WSTReturn("质保金大于店铺应交剩余金额",2); + }elseif($deposit_info['payDeposit'] == $data_deposit['cashDeposit']){ + $data_deposit['isFinish'] = 1; + $data_deposit['completeTime'] = time(); + } + + $res = Db::name('shops_deposit')->where('shopId',$shopId)->update($data_deposit);//商户充值质保金 + //添加到质保金变动记录表 + $detail = []; + $detail['shopId'] = $shopId; + $detail['cashDeposit'] = $cashDeposit; + $detail['payType'] = 3; + $detail['payTime'] = time(); + Db::name('shops_deposit_detail')->insert($detail); + }else{ + + $deposit_info = Db::name('shops_deposit')->where('shopId',$shopId)->field('shopId,payDeposit,cashDeposit')->find(); + $data_deposit['cashDeposit'] = $deposit_info['cashDeposit'] - $offDeposit; + $data_deposit['isFinish'] = 2; + Db::name('shops_deposit')->where('shopId',$shopId)->update($data_deposit);//扣除商户质保金 + //添加到质保金变动记录表 + $detail = []; + $detail['shopId'] = $shopId; + $detail['cashDeposit'] = $offDeposit; + $detail['payType'] = 4; + $detail['payTime'] = time(); + Db::name('shops_deposit_detail')->insert($detail); + //为商户发送扣除质保金提醒 + $userId = Db::name('shops')->where('shopId',$shopId)->field('userId')->find(); + // dump($userId);die; + $messages = []; + $messages['msgType'] = 1; + $messages['sendUserId'] = 1; + $messages['receiveUserId'] = $userId['userId']; + $messages['msgContent'] = $offCause; + $messages['msgStatus'] = 0; + $messages['msgJson'] = '{"from":0,"dataId":"0"}'; + $messages['dataFlag'] = 1; + $messages['from'] = 0; + $messages['createTime'] = date('Y-m-d',time()); + Db::name('messages')->insert($messages); + } + Db::commit(); + return WSTReturn('操作成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',2); + } + } + + /** + * 删除 + */ + public function del(){ + $id = input('post.id/d'); + if($id==1)return WSTReturn('无法删除自营店铺'); + Db::startTrans(); + try{ + $shop = $this->get($id); + $shop->dataFlag = -1; + $result = $shop->save(); + WSTUnuseImage('shops','shopImg',$id); + // 店铺申请表的图片标记为删除 + $imgArr = model('shopExtras')->field('legalCertificateImg,businessLicenceImg,bankAccountPermitImg,organizationCodeImg,taxRegistrationCertificateImg,taxpayerQualificationImg')->where(['shopId'=>$id])->find(); + WSTUnuseImage($imgArr->getData()); + if(false !== $result){ + //删除推荐店铺 + Db::name('recommends')->where(['dataSrc'=>1,'dataId'=>$id])->delete(); + //删除店铺与商品分类的关系 + Db::name('cat_shops')->where(['shopId'=>$id])->delete(); + //删除用户店铺身份 + Db::name('users')->where(['userId'=>$shop->userId])->update(['dataFlag'=>-1]); + //下架及下架商品 + model('goods')->delByshopId($id); + //删除店铺钩子事件 + hook('afterChangeShopStatus',['shopId'=>$id]); + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + /** + * 根据根据userId删除店铺 + */ + public function delByUserId($userId){ + if($userId==1)return WSTReturn('无法删除自营店铺'); + $shop = $this->where('userId',$userId)->find(); + if(!$shop)return; + $shop->dataFlag = -1; + $result = $shop->save(); + WSTUnuseImage('shops','shopImg',$shop->shopId); + if(false !== $result){ + //删除推荐店铺 + Db::name('recommends')->where(['dataSrc'=>1,'dataId'=>$shop->shopId])->delete(); + //删除店铺与商品分类的关系 + Db::name('cat_shops')->where(['shopId'=>$shop->shopId])->delete(); + //下架及删除商品 + model('goods')->delByshopId($shop->shopId); + //删除店铺钩子事件 + hook('afterChangeShopStatus',['shopId'=>$shop->shopId]); + return WSTReturn("删除成功", 1); + } + return WSTReturn('删除失败',-1); + } + /** + * 获取商家入驻资料 + */ + public function getShopApply($id){ + $shop = $this->alias('s')->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','inner') + ->join('__USERS__ u','u.userId=s.userId','inner') + ->where('s.shopId',$id) + ->find() + ->toArray(); + //获取经营范围 + $goodscats = Db::name('cat_shops')->where('shopId',$id)->select(); + $shop['catshops'] = []; + foreach ($goodscats as $v){ + $shop['catshops'][$v['catId']] = true; + } + $shop['auxiliary']=db('shop_auxiliary')->where('shopId',$shop['shopId'])->select(); + $shop['taxRegistrationCertificateImgVO'] = ($shop['taxRegistrationCertificateImg']!='')?explode(',',$shop['taxRegistrationCertificateImg']):[]; + return $shop; + } + /** + * 获取店铺信息 + */ + public function getById($id){ + $shop = $this->alias('s')->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','inner') + ->where('s.shopId',$id) + ->find() + ->toArray(); + //获取经营范围 + $goodscats = Db::name('cat_shops')->where('shopId',$id)->select(); + $shop['catshops'] = []; + foreach ($goodscats as $v){ + $shop['catshops'][$v['catId']] = true; + } + //获取认证类型 + $shopAccreds = Db::name('shop_accreds')->where('shopId',$id)->select(); + $shop['accreds'] = []; + foreach ($shopAccreds as $v){ + $shop['accreds'][$v['accredId']] = true; + } + $shop['taxRegistrationCertificateImgVO'] = ($shop['taxRegistrationCertificateImg']!='')?explode(',',$shop['taxRegistrationCertificateImg']):[]; + return $shop; + } + /** + * 生成店铺编号 + * @param $key 编号前缀,要控制不要超过int总长度,最好是一两个字母 + */ + public function getShopSn($key = ''){ + $rs = $this->Max("REPLACE(shopSn,'S','')+''"); + if($rs==''){ + return $key.'000000001'; + }else{ + for($i=0;$i<1000;$i++){ + $num = (int)str_replace($key,'',$rs); + $shopSn = $key.sprintf("%09d",($num+1)); + $ischeck = $this->checkShopSn($shopSn); + if(!$ischeck)return $shopSn; + } + return '';//一直都检测到那就不要强行添加了 + } + } + + /** + * 检测店铺编号是否存在 + */ + public function checkShopSn($shopSn,$shopId=0){ + $dbo = $this->where(['shopSn'=>$shopSn,'dataFlag'=>1]); + if($shopId>0)$dbo->where('shopId','<>',$shopId); + $num = $dbo->Count(); + if($num==0)return false; + return true; + } + + /** + * 处理申请 + */ + public function handleApply(){ + $data = input('post.'); + $shopId=$data['shopId']; + Db::startTrans(); + try{ + $shops = $this->get($shopId); + if($data['status']==1){ + //建立店铺配置信息 + $sc = []; + $sc['shopId'] = $shopId; + if(!Db::name('ShopConfigs')->where($sc)->value('shopId')){ + Db::name('ShopConfigs')->insert($sc); + } + if(!Db::name('shop_users')->where($sc)->value('shopId')){ + $su = []; + $su["shopId"] = $shopId; + $su["userId"] = $shops->userId; + $su["roleId"] = 0; + Db::name('shop_users')->insert($su); + } + if(!Db::name('shop_scores')->where($sc)->value('shopId')){ + //建立店铺评分记录 + $ss = []; + $ss['shopId'] = $shopId; + Db::name('shop_scores')->insert($ss); + } + + Db::name('shops')->where(['shopId'=>$shopId])->update(['status'=>1]); + if($shops->status!=$data['status']){ + $userInfo = getUserInfo(['userId'=>$shops->userId],'userLevel,userType'); + if($userInfo['userLevel'] == 0 || $userInfo['userType'] == 0){ + $user_data['userLevel'] = empty($userInfo['userLevel']) ? 1 : $userInfo['userLevel']; + $user_data['userType'] = empty($userInfo['userType']) ? 1 : $userInfo['userType']; + Db::name('users')->where(['userId'=>$shops->userId])->update($user_data); + } + //发送开店成功短信 + $tpl = WSTMsgTemplates('PHONE_USER_SHOP_OPEN_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['phone']!=''){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'LOGIN_NAME'=>$data['userName']]]; + $rv = model('admin/LogSms')->sendSMS(0,$shops->userId,$data['phone'],$params,'handleApply'); + } + } + //店铺申请成功之后钩子 mark 20180530 by zll + //hook('afterShopHandleApply',['userId'=>$shops->userId]); + }else{ + if($shops->status!=$data['status']){ + //发送开店失败短信 + $tpl = WSTMsgTemplates('PHONE_SHOP_OPEN_FAIL'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['phone']!=''){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'REASON'=>$data['applyDesc']]]; + $rv = model('admin/LogSms')->sendSMS(0,$shops->userId,$data['phone'],$params,'handleApply'); + } + } + } + $this->allowField(true)->save($data,['shopId'=>$shopId]); + Db::commit(); + // //店铺申请成功之后钩子 mark 20180530 by zll + // hook('afterShopHandleApply',['userId'=>$shops->userId,'applyStatus'=>$data['applyStatus']]); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + //return WSTReturn($e->getMessage()); + return WSTReturn('操作失败',-1); + //echo $e->getMessage(); + } + } + public function handleApplyTest(){ + $shopId = input('post.shopId/d',0); + $shops = $this->get($shopId); + $shopAds=input('shopAds'); + $auxiliary=explode(',',$shopAds); + if(empty($shops))return WSTReturn('删除失败,该入驻申请不存在'); + if($shops->applyStatus==2)return WSTReturn('该入驻申请已通过',1); + $validate = Loader::validate('Shops'); + if(!$validate->check(Input('post.')))return WSTReturn($validate->getError()); + + //判断经营范围 + $goodsCatIds = input('post.goodsCatIds'); + $accredIds = input('post.accredIds'); + if($goodsCatIds=='')return WSTReturn('请选择经营范围'); + $data = input('post.'); + $data['createTime']=date('Y-m-d'); + $data['applyStatus'] = ($data['applyStatus']==2)?2:-1; + if($data['applyStatus']!=2 && $data['applyDesc']==''){ + return WSTReturn('请输入审核不通过原因'); + } + if($data['applyStatus']==2 && $data['cashDeposit'] ==''){ + return WSTReturn('请输入实缴保证金'); + } + if($data['applyStatus']==2 && !is_numeric($data['cashDeposit'])){ + return WSTReturn('实缴保证金请输入数字'); + } + $shopLicense=input('shopLicense'); + if((strpos($data['goodsCatIds'],'393')!==false)||$data['goodsCatIds']=='393'){ + if($shopLicense==""){ + return WSTReturn('食品许可证不能为空'); + } + }else{ + $data['shopLicense']=''; + } + + // $goodsCatIds = $data['goodsCatIds']; + if($data['payDeposit'] !=''){ + if(!is_numeric($data['payDeposit'])){ + return WSTReturn('应缴保证金请输入数字'); + } + $payDeposit['payDeposit'] = $data['payDeposit']; + }else{ + $payDeposit = Db::name('goods_cats')->where('catId',$goodsCatIds)->field('payDeposit')->find(); + } + // dump($payDeposit);die; + $cashDeposit = $data['cashDeposit']; + $isFinish = ''; + $completeTime = ''; + if($payDeposit['payDeposit'] > $cashDeposit){ + $isFinish = 2; + $completeTime = ''; + }elseif($payDeposit['payDeposit'] <= $cashDeposit){ + $isFinish = 1; + $completeTime = time(); + }//elseif($payDeposit['payDeposit'] < $cashDeposit){ + //return WSTReturn('通过保证金大于经营类目质保金,请重新输入'); + //} + // echo $isFinish;die; + Db::startTrans(); + try{ + //保存店铺基础信息 + $auxiliary_data=[]; + $shopAuxiliary = Db::name('shop_auxiliary')->where('shopId='.$shopId)->find(); + WSTUseImages(0, $shopAuxiliary['id'], $auxiliary,'shopauxiliary'); + Db::name('shop_auxiliary')->where('shopId='.$shopId)->delete(); + foreach($auxiliary as $k=>$v){ + $auxiliary_data[$k]['shopId']=$shopId; + $auxiliary_data[$k]['auxiliaryImg']=$v; + } + //dump($shopAuxiliary);die; + Db::name('shop_auxiliary')->insertAll($auxiliary_data); + $areaIds = model('Areas')->getParentIs($data['areaId']); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + $areaIds = model('Areas')->getParentIs($data['bankAreaId']); + if(!empty($areaIds))$data['bankAreaIdPath'] = implode('_',$areaIds)."_"; + WSTUnset($data,'id,shopId,userId,dataFlag,goodsCatIds,accredIds,isSelf'); + if($data['applyStatus']==2 && $data['shopSn']=='')$data['shopSn'] = $this->getShopSn('S'); + $row=db('shop_license')->where('shopId',$shopId)->update(['shopLicense'=>$shopLicense]); + //启用上传图片 + WSTUseImages(1, $shopId, $data['shopImg'],'shops','shopImg'); + //WSTUseImages(1, $shopId, $shopLicense,'shops','shopLicense'); + $this->allowField(true)->save($data,['shopId'=>$shopId,'dataFlag'=>1,'shopStatus'=>1]); + //更改用户身份 + if($data['applyStatus']==2){ + Db::name('users')->where('userId',$shops->userId)->update(['userType'=>1]); + } + //保存店铺其他信息 + $areaIds = model('Areas')->getParentIs($data['businessAreaPath0']); + if(!empty($areaIds))$data['businessAreaPath0'] = implode('_',$areaIds)."_"; + //if($data['establishmentDate']=='')unset($data['establishmentDate']); + //if($data['businessEndDate']=='')unset($data['businessEndDate']); + //if($data['businessStartDate']=='')unset($data['businessStartDate']); + //if($data['legalCertificateStartDate']=='')unset($data['legalCertificateStartDate']); + //if($data['legalCertificateEndDate']=='')unset($data['legalCertificateEndDate']); + //if($data['organizationCodeStartDate']=='')unset($data['organizationCodeStartDate']); + //if($data['organizationCodeEndDate']=='')unset($data['organizationCodeEndDate']); + //$data['registeredCapital'] = (float)$data['registeredCapital']; + + $seModel = model('ShopExtras'); + $Id = $seModel->where(['shopId'=>$shopId])->value('id'); + /* + legalCertificateImg + businessLicenceImg + bankAccountPermitImg + organizationCodeImg + taxRegistrationCertificateImg + taxpayerQualificationImg + */ + // 启用上传图片[extras表] + WSTUseImages(1, $Id, $data['legalCertificateImg'], 'shop_extras', 'legalCertificateImg'); + WSTUseImages(1, $Id, $data['businessLicenceImg'], 'shop_extras', 'businessLicenceImg'); + WSTUseImages(1, $Id, $data['bankAccountPermitImg'], 'shop_extras', 'bankAccountPermitImg'); + //WSTUseImages(1, $Id, $data['organizationCodeImg'], 'shop_extras', 'organizationCodeImg'); + //WSTUseImages(1, $Id, $data['taxRegistrationCertificateImg'], 'shop_extras', 'taxRegistrationCertificateImg'); + //WSTUseImages(1, $Id, $data['taxpayerQualificationImg'], 'shop_extras', 'taxpayerQualificationImg'); + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + + + //经营范围 + Db::name('cat_shops')->where('shopId','=',$shopId)->delete(); + $goodsCats = explode(',',$goodsCatIds); + foreach ($goodsCats as $key =>$v){ + if((int)$v>0){ + Db::name('cat_shops')->insert(['shopId'=>$shopId,'catId'=>$v]); + } + } + //认证类型 + Db::name('shop_accreds')->where('shopId','=',$shopId)->delete(); + if($accredIds!=''){ + $accreds = explode(',',$accredIds); + foreach ($accreds as $key =>$v){ + if((int)$v>0){ + Db::name('shop_accreds')->insert(['shopId'=>$shopId,'accredId'=>$v]); + } + } + } + if($data['applyStatus']==2){ + //建立店铺配置信息 + $sc = []; + $sc['shopId'] = $shopId; + Db::name('ShopConfigs')->insert($sc); + $su = []; + $su["shopId"] = $shopId; + $su["userId"] = $shops->userId; + $su["roleId"] = 0; + Db::name('shop_users')->insert($su); + //建立店铺评分记录 + $ss = []; + $ss['shopId'] = $shopId; + Db::name('shop_scores')->insert($ss); + //店铺申请通过添加质保金 + $deposit = []; + $deposit['shopId'] = $shopId; + $deposit['cashDeposit'] = $cashDeposit; + $deposit['passTime'] = time(); + $deposit['payDeposit'] = $payDeposit['payDeposit']; + $deposit['isFinish'] = $isFinish; + $deposit['completeTime'] = $completeTime; + // dump($deposit);die; + Db::name('shops_deposit')->insert($deposit); + //加入商家质保金缴纳记录表 + $detail = []; + $detail['shopId'] = $shopId; + $detail['cashDeposit'] = $cashDeposit; + $detail['payType'] = 1; + $detail['payTime'] = time(); + Db::name('shops_deposit_detail')->insert($detail); + //店铺申请成功之后钩子 mark 20180530 by zll + hook('afterShopHandleApply',['userId'=>$shops->userId]); + } + if($shops->applyStatus!=$data['applyStatus'])$this->sendMessages($shopId,$shops->userId,$data,'handleApply'); + Db::commit(); + // //店铺申请成功之后钩子 mark 20180530 by zll + // hook('afterShopHandleApply',['userId'=>$shops->userId,'applyStatus'=>$data['applyStatus']]); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + //return WSTReturn($e->getMessage()); + return WSTReturn('操作失败',-1); + //echo $e->getMessage(); + } + } + + /** + * 发送信息 + */ + public function sendMessages($shopId,$userId,$data,$method){ + $user = model('users')->get($userId); + $shops = model('shops')->get($shopId); + if((int)$data['applyStatus']==2){ + //如果存在手机则发送手机号码提示 + $tpl = WSTMsgTemplates('PHONE_USER_SHOP_OPEN_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['applyLinkTel']!=''){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'LOGIN_NAME'=>$user->loginName]]; + $rv = model('admin/LogSms')->sendSMS(0,$userId,$data['applyLinkTel'],$params,$method); + } + //发送邮件 + /* + $tpl = WSTMsgTemplates('EMAIL_USER_SHOP_OPEN_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['applyLinkEmail']){ + $find = ['${LOGIN_NAME}','${MALL_NAME}']; + $replace = [$user->loginName,WSTConf("CONF.mallName")]; + $sendRs = WSTSendMail($data['applyLinkEmail'],'申请入驻审核通过',str_replace($find,$replace,$tpl['content'])); + } + 关闭发送邮件 20180203 make cheng */ + // 会员发送一条商城消息 + $tpl = WSTMsgTemplates('SHOP_OPEN_SUCCESS'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${MALL_NAME}']; + $replace = [$user->loginName,WSTConf("CONF.mallName")]; + WSTSendMsg($userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>0,'dataId'=>$shopId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['SHOP_NAME'] = $shops['shopName']; + $params['APPLY_TIME'] = $shops['applyTime']; + $params['NOW_TIME'] = date('Y-m-d H:i:s'); + $params['REASON'] = "申请入驻成功"; + WSTWxMessage(['CODE'=>'WX_SHOP_OPEN_SUCCESS','userId'=>$userId,'params'=>$params]); + } + }else{ + //如果存在手机则发送手机号码提示 + $tpl = WSTMsgTemplates('PHONE_SHOP_OPEN_FAIL'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['applyLinkTel']!=''){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'REASON'=>$data['applyDesc']]]; + $rv = model('admin/LogSms')->sendSMS(0,$userId,$data['applyLinkTel'],$params,$method); + } + //发送邮件 + // $tpl = WSTMsgTemplates('EMAIL_SHOP_OPEN_FAIL'); + // if( $tpl['tplContent']!='' && $tpl['status']=='1' && $data['applyLinkEmail']){ + // $find = ['${LOGIN_NAME}','${MALL_NAME}','${REASON}']; + // $replace = [$user->loginName,WSTConf("CONF.mallName"),$data['applyDesc']]; + // $sendRs = WSTSendMail($data['applyLinkEmail'],'申请入驻失败',str_replace($find,$replace,$tpl['content'])); + // } + // 会员发送一条商城消息 + $tpl = WSTMsgTemplates('SHOP_OPEN_FAIL'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${MALL_NAME}','${REASON}']; + $replace = [$user->loginName,WSTConf("CONF.mallName"),$data['applyDesc']]; + WSTSendMsg($userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>0,'dataId'=>$shopId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['SHOP_NAME'] = $shops['shopName']; + $params['APPLY_TIME'] = $shops['applyTime']; + $params['NOW_TIME'] = date('Y-m-d H:i:s'); + $params['REASON'] = $data['applyDesc']; + WSTWxMessage(['CODE'=>'WX_SHOP_OPEN_FAIL','userId'=>$userId,'params'=>$params]); + } + } + } + /** + * 删除申请 + */ + public function delApply(){ + $id = input('post.id/d'); + $shop = $this->get($id); + if($shop->applyStatus==2)return WSTReturn('通过申请的店铺不允许删除'); + Db::startTrans(); + try{ + //删除店铺信息 + Db::name('cat_shops')->where(['shopId'=>$id])->delete(); + Db::name('shop_extras')->where(['shopId'=>$id])->delete(); + Db::name('shops')->where(['shopId'=>$id])->delete(); + WSTUnuseImage('shops','shopImg',$id); + Db::commit(); + return WSTReturn("删除成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + /** + * 新增 + */ + public function add(){ + $validate = Loader::validate('Shops'); + if(!$validate->check(Input('post.')))return WSTReturn($validate->getError()); + //判断经营范围 + $goodsCatIds = Input('post.goodsCatIds'); + $accredIds = Input('post.accredIds'); + if($goodsCatIds=='')return WSTReturn('请选择经营范围'); + Db::startTrans(); + try{ + $userId = 0; + $isNewUser = (int)input('post.isNew/d'); + if($isNewUser==1){ + //创建用户账号 + $user = []; + $user['loginName'] = input('post.loginName'); + $user['loginPwd'] = input('post.loginPwd'); + $ck = WSTCheckLoginKey($user['loginName']); + if($ck['status']!=1)return $ck; + if($user['loginPwd']=='')$user['loginPwd'] = '88888888'; + $loginPwd = $user['loginPwd']; + $user["loginSecret"] = rand(1000,9999); + $user['loginPwd'] = md5($user['loginPwd'].$user['loginSecret']); + $user["userType"] = 1; + $user['createTime'] = date('Y-m-d H:i:s'); + model('users')->save($user); + $userId = model('users')->userId; + }else{ + $userId = (int)input('post.shopUserId/d'); + //检查用户是否可用 + $shopUser = model('users')->where(['userId'=>$userId,'dataFlag'=>1])->find(); + if(empty($shopUser))return WSTReturn('无效的账号信息'); + $tmpShop = $this->where(['dataFlag'=>1,'userId'=>$userId])->find(); + if(!empty($tmpShop))return WSTReturn('所关联账号已有店铺信息'); + $shopUser->userType = 1; + $shopUser->save(); + } + if($userId>0){ + //创建商家基础信息 + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + $areaIds = model('Areas')->getParentIs($data['areaId']); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + $areaIds = model('Areas')->getParentIs($data['bankAreaId']); + if(!empty($areaIds))$data['bankAreaIdPath'] = implode('_',$areaIds)."_"; + WSTUnset($data,'id,shopId,dataFlag,isSelf'); + if($data['shopSn']=='')$data['shopSn'] = $this->getShopSn('S'); + $data['userId'] = $userId; + $data['applyStatus'] = 2; + $this->allowField(true)->save($data); + $shopId = $this->shopId; + //启用上传图片 + WSTUseImages(1, $shopId, $data['shopImg']); + //保存店铺其他信息 + $areaIds = model('Areas')->getParentIs($data['businessAreaPath0']); + if(!empty($areaIds))$data['businessAreaPath'] = implode('_',$areaIds)."_"; + //if($data['establishmentDate']=='')unset($data['establishmentDate']); + //if($data['businessEndDate']=='')unset($data['businessEndDate']); + //if($data['businessStartDate']=='')unset($data['businessStartDate']); + //if($data['legalCertificateStartDate']=='')unset($data['legalCertificateStartDate']); + //if($data['legalCertificateEndDate']=='')unset($data['legalCertificateEndDate']); + //if($data['organizationCodeStartDate']=='')unset($data['organizationCodeStartDate']); + // if($data['organizationCodeEndDate']=='')unset($data['organizationCodeEndDate']); + //$data['registeredCapital'] = (float)$data['registeredCapital']; + $data['shopId'] = $shopId; + + $seModel = model('ShopExtras'); + $seModel->allowField(true)->save($data); + $Id = $seModel->where(['shopId'=>$shopId])->value('id'); + // 判断是否有上传图片资料,启用上传图片[extras表] + WSTUseImages(1, $Id, $data['legalCertificateImg'], 'shop_extras'); + WSTUseImages(1, $Id, $data['businessLicenceImg'], 'shop_extras'); + WSTUseImages(1, $Id, $data['bankAccountPermitImg'], 'shop_extras'); + //WSTUseImages(1, $Id, $data['organizationCodeImg'], 'shop_extras'); + // WSTUseImages(1, $Id, $data['taxRegistrationCertificateImg'], 'shop_extras'); + // WSTUseImages(1, $Id, $data['taxpayerQualificationImg'], 'shop_extras'); + //建立店铺配置信息 + $sc = []; + $sc['shopId'] = $shopId; + Db::name('ShopConfigs')->insert($sc); + $su = []; + $su["shopId"] = $shopId; + $su["userId"] = $userId; + $su["roleId"] = 0; + Db::name('shop_users')->insert($su); + //建立店铺评分记录 + $ss = []; + $ss['shopId'] = $shopId; + Db::name('shop_scores')->insert($ss); + //经营范围 + $goodsCats = explode(',',$goodsCatIds); + foreach ($goodsCats as $v){ + if((int)$v>0)Db::name('cat_shops')->insert(['shopId'=>$shopId,'catId'=>$v]); + } + //认证类型 + if($accredIds!=''){ + $accreds = explode(',',$accredIds); + foreach ($accreds as $v){ + if((int)$v>0)Db::name('shop_accreds')->insert(['shopId'=>$shopId,'accredId'=>$v]); + } + } + $data['applyStatus'] = 2; + $data['applyDesc'] = ''; + $this->sendMessages($shopId,$userId,$data,'add'); + } + Db::commit(); + return WSTReturn("新增成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败',-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $shopId = input('post.shopId/d',0); + $shops = $this->get($shopId); + $shopAds=input('shopAds'); + $auxiliary=explode(',',$shopAds); + if(empty($shops) || $shops->dataFlag!=1)return WSTReturn('店铺不存在'); + $validate = Loader::validate('Shops'); + if(!$validate->check(Input('post.')))return WSTReturn($validate->getError()); + //判断经营范围 + $goodsCatIds = input('post.goodsCatIds'); + $accredIds = input('post.accredIds'); + if($goodsCatIds=='')return WSTReturn('请选择经营范围'); + Db::startTrans(); + try{ + $data = input('post.'); + $auxiliary_data=[]; + $shopAuxiliary = Db::name('shop_auxiliary')->where('shopId='.$shopId)->find(); + WSTUseImages(0, $shopAuxiliary['id'], $auxiliary,'shopauxiliary'); + Db::name('shop_auxiliary')->where('shopId='.$shopId)->delete(); + foreach($auxiliary as $k=>$v){ + $auxiliary_data[$k]['shopId']=$shopId; + $auxiliary_data[$k]['auxiliaryImg']=$v; + } + Db::name('shop_auxiliary')->insertAll($auxiliary_data); + //保存店铺基础信息 + $areaIds = model('Areas')->getParentIs($data['areaId']); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + $areaIds = model('Areas')->getParentIs($data['bankAreaId']); + if(!empty($areaIds))$data['bankAreaIdPath'] = implode('_',$areaIds)."_"; + WSTUnset($data,'id,shopId,userId,dataFlag,goodsCatIds,accredIds,isSelf,applyStatus,applyDesc'); + //启用上传图片 + WSTUseImages(1, $shopId, $data['shopImg'],'shops','shopImg'); + $this->allowField(true)->save($data,['shopId'=>$shopId,'dataFlag'=>1]); + //保存店铺其他信息 + $areaIds = model('Areas')->getParentIs($data['businessAreaPath0']); + if(!empty($areaIds))$data['businessAreaPath'] = implode('_',$areaIds)."_"; + //if($data['establishmentDate']=='')unset($data['establishmentDate']); + //if($data['businessEndDate']=='')unset($data['businessEndDate']); + //if($data['businessStartDate']=='')unset($data['businessStartDate']); + //if($data['legalCertificateStartDate']=='')unset($data['legalCertificateStartDate']); + //if($data['legalCertificateEndDate']=='')unset($data['legalCertificateEndDate']); + //if($data['organizationCodeStartDate']=='')unset($data['organizationCodeStartDate']); + //if($data['organizationCodeEndDate']=='')unset($data['organizationCodeEndDate']); + //$data['registeredCapital'] = (float)$data['registeredCapital']; + $seModel = model('ShopExtras'); + $Id = $seModel->where(['shopId'=>$shopId])->value('id'); + // 启用上传图片[extras表] + WSTUseImages(1, $Id, $data['legalCertificateImg'], 'shop_extras','legalCertificateImg'); + WSTUseImages(1, $Id, $data['businessLicenceImg'], 'shop_extras','businessLicenceImg'); + WSTUseImages(1, $Id, $data['bankAccountPermitImg'], 'shop_extras','bankAccountPermitImg'); + //WSTUseImages(1, $Id, $data['organizationCodeImg'], 'shop_extras','organizationCodeImg'); + //WSTUseImages(1, $Id, $data['taxRegistrationCertificateImg'], 'shop_extras','taxRegistrationCertificateImg'); + // WSTUseImages(1, $Id, $data['taxpayerQualificationImg'], 'shop_extras','taxpayerQualificationImg'); + + + + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + + + + + //经营范围 + Db::name('cat_shops')->where('shopId','=',$shopId)->delete(); + $goodsCats = explode(',',$goodsCatIds); + foreach ($goodsCats as $key =>$v){ + if((int)$v>0){ + Db::name('cat_shops')->insert(['shopId'=>$shopId,'catId'=>$v]); + } + } + //认证类型 + Db::name('shop_accreds')->where('shopId','=',$shopId)->delete(); + if($accredIds!=''){ + $accreds = explode(',',$accredIds); + foreach ($accreds as $key =>$v){ + if((int)$v>0){ + Db::name('shop_accreds')->insert(['shopId'=>$shopId,'accredId'=>$v]); + } + } + } + if((int)input('shopStatus')!=1){ + //店铺状态不正常就停用所有的商品 + model('goods')->unsaleByshopId($shopId); + } + //删除店铺钩子事件 + hook('afterChangeShopStatus',['shopId'=>$shopId]); + Db::commit(); + return WSTReturn("编辑成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('编辑失败',-1); + } + } + /** + * 获取所有店铺id + */ + public function getAllShopId(){ + return $this->where(['dataFlag'=>1,'shopStatus'=>1])->column('shopId'); + } + + /** + * 根据店铺ID获取店铺名称 + */ + public function upShopName(){ + $shopId = input('shopId/d'); + // $shopId = 1; + $res = Db::name('shops')->where('shopId',$shopId)->field('shopId,shopName')->find(); + // dump($res);die; + return $res; + } + + /** + * 搜索经验范围的店铺 + */ + public function searchQuery(){ + $goodsCatatId = (int)input('post.goodsCatId'); + if($goodsCatatId<=0)return []; + $key = input('post.key'); + $where = []; + $where['dataFlag'] = 1; + $where['shopStatus'] = 1; + $where['catId'] = $goodsCatatId; + if($key!='')$where['shopName|shopSn'] = ['like','%'.$key.'%']; + return $this->alias('s')->join('__CAT_SHOPS__ cs','s.shopId=cs.shopId','inner') + ->where($where)->field('shopName,s.shopId,shopSn')->select(); + } + + /** + * 自营自动登录 + */ + public function selfLogin($id){ + $shopId = $id; + $userid = $this->where(["dataFlag"=>1, "status"=>1,"shopId"=>$shopId])->field('userId')->find(); + if(!empty($userid['userId'])){ + $userId = $userid['userId']; + //获取用户信息 + $u = new Users(); + $rs = $u->getById($userId); + //获取用户等级 + $rrs = WSTUserRank($rs['userTotalScore']); + $rs['rankId'] = $rrs['rankId']; + $rs['rankName'] = $rrs['rankName']; + $rs['userrankImg'] = $rrs['userrankImg']; + $ip = request()->ip(); + $u->where(["userId"=>$userId])->update(["lastTime"=>date('Y-m-d H:i:s'),"lastIP"=>$ip]); + //加载店铺信息 + $shops= new Shops(); + $shop = $shops->where(["userId"=>$userId,"dataFlag" =>1])->find(); + if(!empty($shop))$rs = array_merge($shop->toArray(),$rs->toArray()); + //记录登录日志 + $data = array(); + $data["userId"] = $userId; + $data["loginTime"] = date('Y-m-d H:i:s'); + $data["loginIp"] = $ip; + Db::name('log_user_logins')->insert($data); + if($rs['userPhoto']=='')$rs['userPhoto'] = WSTConf('CONF.userLogo'); + session('WST_USER',$rs); + return WSTReturn("","1"); + } + return WSTReturn("",-1); + } + + /** + * 查询店铺佣金扣点 + */ + public function commission($shopId){ + $obj = Db::name('shops')->alias('s') + ->join('__SHOP_COMMISSION__ sc','sc.shopId=s.shopId','left')->where('s.shopId',$shopId)->field('s.shopId,sc.commission,sc.userId,sc.userName,sc.usersPhone,sc.deductMoney')->find(); + // dump($obj);die; + return $obj; + } + /** + * 设置店铺佣金扣点 + */ + public function upCommission(){ + $data['shopId'] = input('shopId/d'); + $data['commission'] = input('commission'); + $data['userName'] = input('userName'); + //$data['userId'] = input('userId/d'); + $data['usersPhone'] = input('usersPhone'); + $user = Db::name('users')->where(['loginName|userPhone'=>$data['usersPhone']])->field('userId')->find(); + if(!$user){ + return WSTReturn('该职员不存在',-1);die; + } + $data['userId'] = $user['userId']; + $com = Db::name('shop_commission')->where('shopId',$data['shopId'])->find(); + if($com){ + $result = Db::name('shop_commission')->where('shopId',$data['shopId'])->update(['commission'=>$data['commission'],'usersPhone'=>$data['usersPhone'],'userName'=>$data['userName'],'userId'=>$data['userId']]); + }else{ + $result = Db::name('shop_commission')->insert($data); + } + if($result){ + return WSTReturn("操作成功",1); + }else{ + return WSTReturn("操作失败",-1); + } + } + + /** + * 查询业务员信息 + */ + public function staffs(){ + $userName = input('userName'); + $data = Db::name('users')->where(['loginName'=>$userName,'userStatus'=>1,'dataFlag'=>1])->field('userPhone,userId')->find(); + if($data){ + return $data; + }else{ + return WSTReturn('该职员不存在',-1); + } + } + + + /** + * 导出订单 + */ + public function toExport($shopStatus=1){ + $name="店铺列表"; + $areaIdPath = input('areaIdPath'); + $shopName = input('shopName'); + $telephone = input('userPhone'); + $catId =(int)input('cat'); + $isInvestment = (int)input('isInvestment/d',-1); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.applyStatus'] = 2; + $where['s.shopStatus'] = $shopStatus; + if($catId!="0"){ + $where['c.catId'] = $catId; + } + if(in_array($isInvestment,[0,1]))$where['ss.isInvestment'] = $isInvestment; + if($shopName!='')$where['shopName'] = ['like','%'.$shopName.'%']; + if($telephone!='')$where['telephone'] = ['like','%'.$telephone.'%']; + if($areaIdPath !='')$where['areaIdPath'] = ['like',$areaIdPath."%"]; + if($catId !='')$where['catId'] = ['like',$catId."%"]; + $sort = input('sort'); + $order = []; + if($sort!=''){ + $sortArr = explode('.',$sort); + $order = $sortArr[0].' '.$sortArr[1]; + } + $list=Db::table('__SHOPS__')->alias('s') + ->join('__AREAS__ a2','s.areaId=a2.areaId','left') + ->join('__USERS__ u','u.userId=s.userId','left') + ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','left') + ->join('__CAT_SHOPS__ c','c.shopId=s.shopId','left') + ->join('__SHOP_PAY__ sp','sp.shopId=s.shopId','left') + ->where($where) + ->field('u.loginName,s.shopId,shopSn,shopName,a2.areaName,shopkeeper,telephone,shopAddress,shopCompany,shopAtive,shopStatus,s.applyTime,s.createTime,sp.status') + ->order('createTime desc')->group('s.shopId') + ->select(); + foreach ($list as &$value) { + $catName=db('cat_shops')->alias('a')->join('goods_cats g','g.catId=a.catId') + ->where('shopId',$value['shopId'])->field('catName')->select(); + $value['catName']=""; + if(count($catName)>1){ + foreach ($catName as &$v) { + $value['catName']=$value['catName'].$v['catName'].','; + } + } + $goodsNum=db('goods')->alias('g')->where(['shopId'=>$value['shopId'],'isSale'=>1,'dataFlag'=>1])->field('count(goodsId)goodsNum')->select(); + $value['goodsNum']=""; + foreach ($goodsNum as &$v) { + $value['goodsNum']=$value['goodsNum'].$v['goodsNum']; + } + } + //dump($list);die; + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + // $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + // ->setLastModifiedBy("heyuanhui")//最后修改人 + // ->setTitle($name)//标题 + // ->setSubject($name)//题目 + // ->setDescription($name)//描述 + // ->setKeywords("订单")//关键字 + // ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(12); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '用户名称') + ->setCellValue('B1', '店铺ID') + ->setCellValue('C1', '店铺编号') + ->setCellValue('D1', '店铺名称') + ->setCellValue('E1', '地区名称') + ->setCellValue('F1', '店主名称') + ->setCellValue('G1', '店主联系电话') + ->setCellValue('H1', '店铺地址') + ->setCellValue('I1', '公司名称') + ->setCellValue('J1', '门店状态') + ->setCellValue('K1', '门店状态') + ->setCellValue('L1', '商品数量') + ->setCellValue('M1', '申请时间') + ->setCellValue('N1', '通过时间') + ->setCellValue('O1', '经营类目'); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->applyFromArray($styleArray); + for ($row = 0; $row < count($list); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $list[$row]['loginName']) + ->setCellValue('B'.$i, $list[$row]['shopId']) + ->setCellValue('C'.$i, $list[$row]['shopSn']) + ->setCellValue('D'.$i, $list[$row]['shopName']) + ->setCellValue('E'.$i, $list[$row]['areaName']) + ->setCellValue('F'.$i, $list[$row]['shopkeeper']) + ->setCellValue('G'.$i, $list[$row]['telephone']) + ->setCellValue('H'.$i, $list[$row]['shopAddress']) + ->setCellValue('I'.$i, $list[$row]['shopCompany']) + ->setCellValue('J'.$i, $list[$row]['shopAtive']) + ->setCellValue('K'.$i, $list[$row]['shopStatus']) + ->setCellValue('L'.$i, $list[$row]['goodsNum']) + ->setCellValue('M'.$i, $list[$row]['applyTime']) + ->setCellValue('N'.$i, $list[$row]['createTime']) + ->setCellValue('O'.$i, $list[$row]['catName']); + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } + //商家登录 + public function detailByPage(){ + $where='s.shopStatus=1 AND s.dataFlag=1'; + $start=input('startDate'); + $end=input('endDate'); + $nonTime=input('nonTime'); + if($nonTime){ + $nonlogTime=date('Y-m-d H:i:s',strtotime('-'.$nonTime.'day')); + $where.=' AND l.nonlogTime<"'.$nonlogTime.'"'; + } + //dump($nonlogTime); + // if($start!='' && $end!=''){ + // $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + // $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + // $where.=' AND lo.loginTime BETWEEN "'.$start.'" AND "'.$end.'"'; + // }else if($start!=''){ + // $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + // $where.= ' AND lo.loginTime>="'.$start.'"'; + // }else if($end!=''){ + // $end = date('Y-m-d 00:00:00',strtotime(input('endDate'))); + // $where.= ' AND lo.loginTime<="'.$end.'"'; + // } + // $result=Db::query('SELECT + // s.userId,s.shopName,l.loginNum,b.goodsNum + // FROM + // '.config('database.prefix').'shops s + // LEFT JOIN + // (SELECT COUNT(*) loginNum,userId FROM '.config('database.prefix').'log_user_logins a GROUP BY a.userId) l on l.userId=s.userId + // LEFT JOIN + // (SELECT COUNT(*) goodsNum,shopId FROM '.config('database.prefix').'goods g GROUP BY g.shopId) b on b.shopId=s.shopId + + // '); + $result=Db::table('__SHOPS__')->alias('s') + //->join('__LOG_USER_LOGINS__ a','s.userId=a.userId','left') + ->join('(SELECT COUNT(*) loginNum,userId,loginTime,MAX(loginTime) nonlogTime FROM __LOG_USER_LOGINS__ a GROUP BY a.userId) l','s.userId=l.userId','left') + ->join('(SELECT COUNT(*) goodsNum,shopId,isSale FROM __GOODS__ g WHERE g.isSale=1 GROUP BY g.shopId) go','s.shopId=go.shopId','left') + ->join('__LOG_USER_LOGINS__ lo','s.userId=lo.userId','left') + // ->join('(SELECT COUNT(*) orderNum,shopId,orderStatus FROM __ORDERS__ o GROUP BY o.shopId) oo','s.shopId=oo.shopId','left') + // ->join('(SELECT COUNT(*) orderNums,shopId,orderStatus FROM __ORDERS__ o2 GROUP BY o2.orderStatus) od','s.shopId=od.shopId','left') + //->whereTime('l.loginTime','between',[$start,$end]) + ->where($where) + ->field('s.shopName,l.loginNum,go.goodsNum,s.shopId,s.shopCompany,shopkeeper,telephone,applyTime,nonlogTime') + ->order('l.loginNum desc') + ->group('s.shopId') + ->paginate(input('limit/d'))->toArray(); + //dump(db::getlastsql()); + //dump($result); + foreach ($result['Rows'] as &$value) { + if($end=='')$end = date('Y-m-d 23:59:59',strtotime("now")); + if($start=='')$start = date('Y-m-d 23:59:59',strtotime("0")); + $value['nonTime']=sprintf("%.0f",(strtotime(date('Y-m-d H:i:s'))-strtotime($value['nonlogTime']))/86400); + $value['successOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>2,'dataFlag'=>1])->count('shopId'); + $value['cancelOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>-1,'dataFlag'=>1])->count('shopId'); + $value['nonpayOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>-2,'dataFlag'=>1])->count('shopId'); + $value['deliveredOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>1,'dataFlag'=>1])->count('shopId'); + } + // $result=Db::table('__SHOPS__')->alias('s') + // ->join('__LOG_USER_LOGINS__ a','s.userId=a.userId','left') + // ->join('__GOODS__ go','s.shopId=go.shopId','left') + // ->where($where) + // ->field('a.userId,shopName,count(a.userId)logNum,count(go.shopId)goodsNum') + // ->order('logNum desc')->group('a.userId,go.shopId,s.shopId,s.userId,a.userId') + // ->paginate(input('limit/d'))->toArray(); + + return $result; + } + /** + * 导出商家登录活跃数据订单 + */ + public function toExports(){ + $name="商家活跃信息列表"; + $start=input('startDate'); + $end=input('endDate'); + $nonTime=input('nonTime'); + $where='s.shopStatus=1 AND s.dataFlag=1'; + if($nonTime){ + $nonlogTime=date('Y-m-d H:i:s',strtotime('-'.$nonTime.'day')); + $where.=' AND l.nonlogTime<"'.$nonlogTime.'"'; + } + // if($start!='' && $end!=''){ + // $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + // $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + // $where.=' AND lo.loginTime BETWEEN "'.$start.'" AND "'.$end.'"'; + // }else if($start!=''){ + // $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + // $where.= ' AND lo.loginTime>="'.$start.'"'; + // }else if($end!=''){ + // $end = date('Y-m-d 00:00:00',strtotime(input('endDate'))); + // $where.= ' AND lo.loginTime<="'.$end.'"'; + // } + $list=Db::query('SELECT + s.shopId,s.shopName,l.loginNum,b.goodsNum,l.nonlogTime,s.shopCompany,s.applyTime,s.shopkeeper,s.telephone + FROM + '.config('database.prefix').'shops s + LEFT JOIN + (SELECT COUNT(*) loginNum,userId,MAX(loginTime) nonlogTime FROM '.config('database.prefix').'log_user_logins a GROUP BY a.userId) l on l.userId=s.userId + LEFT JOIN + (SELECT COUNT(*) goodsNum,shopId FROM '.config('database.prefix').'goods g WHERE g.isSale=1 GROUP BY g.shopId) b on b.shopId=s.shopId + LEFT JOIN + (SELECT userId,loginTime FROM '.config('database.prefix').'log_user_logins)lo on lo.userId=s.userId + WHERE '.$where.' + GROUP BY s.shopId + ORDER BY l.loginNum DESC'); + foreach ($list as &$value) { + if($end=='')$end = date('Y-m-d 23:59:59',strtotime("now")); + if($start=='')$start = date('Y-m-d 23:59:59',strtotime("0")); + $value['nonTime']=sprintf("%.0f",(strtotime(date('Y-m-d H:i:s'))-strtotime($value['nonlogTime']))/86400); + $value['successOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>2,'dataFlag'=>1])->count('shopId'); + $value['cancelOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>-1,'dataFlag'=>1])->count('shopId'); + $value['nonpayOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>-2,'dataFlag'=>1])->count('shopId'); + $value['deliveredOrder']=db('orders')->whereTime('createTime','between',[$start,$end]) + ->where(['shopId'=>$value['shopId'],'orderStatus'=>1,'dataFlag'=>1])->count('shopId'); + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + // $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + // ->setLastModifiedBy("heyuanhui")//最后修改人 + // ->setTitle($name)//标题 + // ->setSubject($name)//题目 + // ->setDescription($name)//描述 + // ->setKeywords("订单")//关键字 + // ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(12); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '店铺名称') + ->setCellValue('B1', '公司名称') + ->setCellValue('C1', '注册时间') + ->setCellValue('D1', '联系人姓名') + ->setCellValue('E1', '联系人电话') + ->setCellValue('F1', '未登录天数') + ->setCellValue('G1', '登录频次') + ->setCellValue('H1', '商品数量') + ->setCellValue('I1', '已成功订单') + ->setCellValue('J1', '已取消订单') + ->setCellValue('K1', '未付款订单') + ->setCellValue('L1', '已发货订单'); + + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->applyFromArray($styleArray); + for ($row = 0; $row < count($list); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $list[$row]['shopName']) + ->setCellValue('B'.$i, $list[$row]['shopCompany']) + ->setCellValue('C'.$i, $list[$row]['applyTime']) + ->setCellValue('D'.$i, $list[$row]['shopkeeper']) + ->setCellValue('E'.$i, $list[$row]['telephone']) + ->setCellValue('F'.$i, $list[$row]['nonTime']) + ->setCellValue('G'.$i, $list[$row]['loginNum']) + ->setCellValue('H'.$i, $list[$row]['goodsNum']) + ->setCellValue('I'.$i, $list[$row]['successOrder']) + ->setCellValue('J'.$i, $list[$row]['cancelOrder']) + ->setCellValue('K'.$i, $list[$row]['nonpayOrder']) + ->setCellValue('L'.$i, $list[$row]['deliveredOrder']); + } + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } + +} \ No newline at end of file diff --git a/hyhproject/admin/model/SpecCats.php b/hyhproject/admin/model/SpecCats.php new file mode 100755 index 0000000..471e092 --- /dev/null +++ b/hyhproject/admin/model/SpecCats.php @@ -0,0 +1,139 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 规格分类业务处理 + */ +class SpecCats extends Base{ + + /** + * 新增 + */ + public function add(){ + $isExistAllowImg = false; + $msg = ''; + $data = input('post.'); + if($data['isAllowImg']==1){ + if($this->checkExistAllowImg((int)$data['goodsCatId'],0)){ + return WSTReturn("同一分类下已存在允许上传图片规格类型,请先修改之后再新增"); + } + } + $data['createTime'] = date('Y-m-d H:i:s'); + $data["dataFlag"] = 1; + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + if(!empty($goodsCats))$data['goodsCatPath'] = implode('_',$goodsCats)."_"; + $result = $this->validate('SpecCats.add')->allowField(['catName','isShow','isAllowImg','goodsCatPath','goodsCatId','dataFlag','createTime'])->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 检测是否存在统一分类下的上传图片分类 + */ + public function checkExistAllowImg($goodsCatId,$catId){ + $dbo = $this->where(['goodsCatId'=>$goodsCatId,'dataFlag'=>1,'isAllowImg'=>1]); + if($catId>0)$dbo->where('catId','<>',$catId); + $rs = $dbo->count(); + if($rs>0)return true; + return false; + } + /** + * 编辑 + */ + public function edit(){ + $catId = input('post.catId/d'); + $data = input('post.'); + if($data['isAllowImg']==1){ + if($this->checkExistAllowImg((int)$data['goodsCatId'],$catId)){ + return WSTReturn("同一分类下已存在允许上传图片规格类型,请先修改之后再保存"); + } + } + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + if(!empty($goodsCats))$data['goodsCatPath'] = implode('_',$goodsCats)."_"; + $result = $this->validate('SpecCats.edit')->allowField(['catName','goodsCatPath','goodsCatId','isShow','isAllowImg'])->save($data,['catId'=>$catId,"dataFlag"=>1]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del(){ + $catId = input('post.catId/d'); + $data["dataFlag"] = -1; + $result = $this->save($data,['catId'=>$catId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 显示隐藏 + */ + public function setToggle(){ + $catId = input('post.catId/d'); + $isShow = input('post.isShow/d'); + $result = $this->where(['catId'=>$catId,"dataFlag"=>1])->setField("isShow", $isShow); + if(false !== $result){ + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * + * 根据ID获取 + */ + public function getById($catId){ + $obj = null; + if($catId>0){ + $obj = $this->get(['catId'=>$catId,"dataFlag"=>1]); + }else{ + $obj = self::getEModel("spec_cats"); + } + return $obj; + } + + + /** + * 分页 + */ + public function pageQuery(){ + $keyName = input('keyName'); + $goodsCatPath = input('goodsCatPath'); + $dbo = $this->field(true); + $map = array(); + $map['dataFlag'] = 1; + if($keyName!="")$map['catName'] = ["like","%".$keyName."%"]; + if($goodsCatPath!='')$map['goodsCatPath'] = ["like",$goodsCatPath."_%"]; + $dbo = $dbo->field("catName name, catId id, isShow ,isAllowImg")->where($map); + $page = $dbo->order('catSort asc,catId asc')->paginate(input('limit/d'))->toArray(); + if(count($page['Rows'])>0){ + $keyCats = model('GoodsCats')->listKeyAll(); + foreach ($page['Rows'] as $key => $v){ + $goodsCatPath = $page['Rows'][$key]['goodsCatPath']; + $page['Rows'][$key]['goodsCatNames'] = self::getGoodsCatNames($goodsCatPath,$keyCats); + $page['Rows'][$key]['children'] = []; + $page['Rows'][$key]['isextend'] = false; + } + } + return $page; + } + + public function getGoodsCatNames($goodsCatPath, $keyCats){ + $catIds = explode("_",$goodsCatPath); + $catNames = array(); + for($i=0,$k=count($catIds);$i<$k;$i++){ + if($catIds[$i]=='')continue; + if(isset($keyCats[$catIds[$i]]))$catNames[] = $keyCats[$catIds[$i]]; + } + return implode("→",$catNames); + } +} diff --git a/hyhproject/admin/model/Staffs.php b/hyhproject/admin/model/Staffs.php new file mode 100755 index 0000000..a8e8f50 --- /dev/null +++ b/hyhproject/admin/model/Staffs.php @@ -0,0 +1,416 @@ +<?php + +namespace wstmart\admin\model; + +use wstmart\admin\model\Roles; + +use wstmart\admin\model\LogStaffLogins; + +use think\Db; + +/** + + * ============================================================================ + + * 职员业务处理 + + */ + +class Staffs extends Base{ + + + + /** + + * 判断用户登录帐号密码 + + */ + + public function checkLogin(){ + + $loginName = input("post.loginName"); + + $loginPwd = input("post.loginPwd"); + + $code = input("post.verifyCode"); + + if(!WSTVerifyCheck($code)){ + + return WSTReturn('验证码错误!'); + + } + + $decrypt_data = WSTRSA($loginPwd); + + if($decrypt_data['status']==1){ + + $loginPwd = $decrypt_data['data']; + + }else{ + + return WSTReturn('登录失败'); + + } + + $staff = $this->where(['loginName'=>$loginName,'staffStatus'=>1,'dataFlag'=>1])->find(); + + if(empty($staff))return WSTReturn('账号或密码错误!'); + + if($staff['loginPwd']==md5($loginPwd.$staff['secretKey'])){ + + $staff->lastTime = date('Y-m-d H:i:s'); + + $staff->lastIP = request()->ip(); + + $staff->save(); + + //记录登录日志 + + LogStaffLogins::create([ + + 'staffId'=>$staff['staffId'], + + 'loginTime'=> date('Y-m-d H:i:s'), + + 'loginIp'=>request()->ip() + + ]); + + //获取角色权限 + + $role = Roles::get(['dataFlag'=>1,'roleId'=>$staff['staffRoleId']]); + + $staff['roleName'] = $role['roleName']; + + if($staff['staffId']==1){ + + $staff['privileges'] = Db::name('privileges')->where(['dataFlag'=>1])->column('privilegeCode'); + + $staff['menuIds'] = Db::name('menus')->where('dataFlag',1)->column('menuId'); + + }else{ + + $staff['privileges'] = explode(',',$role['privileges']); + + $staff['menuIds'] = []; + + //获取管理员拥有的菜单 + + if(!empty($staff['privileges'])){ + + $menus = Db::name('menus')->alias('m')->join('__PRIVILEGES__ p','m.menuId=p.menuId and p.dataFlag=1','inner') + + ->where(['p.privilegeCode'=>['in',$staff['privileges']]])->field('m.menuId')->select(); + + $menuIds = []; + + if(!empty($menus)){ + + foreach ($menus as $key => $v){ + + $menuIds[] = $v['menuId']; + + } + + $staff['menuIds'] = $menuIds; + + } + + } + + } + + session("WST_STAFF",$staff); + + return WSTReturn("",1,$staff); + + } + + return WSTReturn('账号或密码错误!'); + + } + + + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $key = input('key'); + + $where = []; + + $where['s.dataFlag'] = 1; + + if($key!='')$where['loginName|staffName|staffNo'] = ['like','%'.$key.'%']; + + return Db::name('staffs')->alias('s')->join('__ROLES__ r','s.staffRoleId=r.roleId and r.dataFlag=1','left') + + ->where($where)->field('staffId,staffName,loginName,workStatus,staffNo,lastTime,lastIP,roleName') + + ->order('staffId', 'desc')->paginate(input('limit/d')); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $staffId = (int)session('WST_STAFF.staffId'); + + $id = (int)input('post.id/d'); + + if($staffId==$id)return WSTReturn('不允许删除自己',-1); + + if($id==1)return WSTReturn('不允许删除最高管理员',-1); + + $data = []; + + $data['dataFlag'] = -1; + + Db::startTrans(); + + try{ + + $result = $this->update($data,['staffId'=>$id]); + + if(false !== $result){ + + WSTUnuseImage('staffs','staffPhoto',$id); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('删除失败',-1); + + } + + } + + + + /** + + * 获取角色权限 + + */ + + public function getById($id){ + + return $this->get(['dataFlag'=>1,'staffId'=>$id]); + + } + + + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['secretKey'] = rand(1000,9999); + + $data["loginPwd"] = md5(input("post.loginPwd").$data["secretKey"]); + + $data["staffFlag"] = 1; + + $data["createTime"] = date('Y-m-d H:i:s'); + + Db::startTrans(); + + try{ + + $result = $this->validate('Staffs.add')->allowField(true)->save($data); + + if(false !== $result){ + + WSTUseImages(1, $this->staffId,$data['staffPhoto']); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('新增失败',-1); + + } + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $id = input('post.staffId/d'); + + $data = input('post.'); + + WSTUnset($data, 'staffId,loginPwd,secretKey,dataFlag,createTime,lastTime,lastIP'); + + Db::startTrans(); + + try{ + + WSTUseImages(1, $id,$data['staffPhoto'],'staffs','staffPhoto'); + + $result = $this->validate('Staffs.edit')->allowField(true)->save($data,['staffId'=>$id]); + + if(false !== $result){ + + Db::commit(); + + if(session('WST_STAFF.staffId')==$id){ + + session('WST_STAFF.staffPhoto',$data['staffPhoto']); + + session('WST_STAFF.staffName',$data['staffName']); + + } + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('编辑失败',-1); + + } + + } + + + + /** + + * 检测账号是否重复 + + */ + + public function checkLoginKey($key){ + + $rs = $this->where(['loginName'=>$key,'dataFlag'=>1])->count(); + + return ($rs==0)?WSTReturn('该账号可用', 1):WSTReturn("对不起,该账号已存在"); + + } + + /** + + * 修改自己密码 + + */ + + public function editMyPass($staffId){ + + if(input("post.newPass")=='')WSTReturn("密码不能为空"); + + $staff = $this->where('staffId',$staffId)->field('secretKey,loginPwd')->find(); + + if(empty($staff))return WSTReturn("修改失败"); + + $srcPass = md5(input("post.srcPass").$staff["secretKey"]); + + if($srcPass!=$staff['loginPwd'])return WSTReturn("原密码错误"); + + $staff->loginPwd = md5(input("post.newPass").$staff["secretKey"]); + + $result = $staff->save(); + + if(false !== $result){ + + return WSTReturn("修改成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + /** + + * 修改职员密码 + + */ + + public function editPass($staffId){ + + if(input("post.newPass")=='')WSTReturn("密码不能为空"); + + $staff = $this->where('staffId',$staffId)->field('secretKey')->find(); + + if(empty($staff))return WSTReturn("修改失败"); + + $staff->loginPwd = md5(input("post.newPass").$staff["secretKey"]); + + $result = $staff->save(); + + if(false !== $result){ + + return WSTReturn("修改成功", 1); + + }else{ + + return WSTReturn($this->getError(),-1); + + } + + } + + + + /** + + * 获取所有的职员列表 + + */ + + public function listQuery(){ + + $where = []; + + $where['dataFlag'] = 1; + + $where['staffStatus'] = 1; + + return Db::name('staffs')->where($where)->field('staffId,staffName') + + ->order('staffName', 'asc')->select(); + + } + +} + diff --git a/hyhproject/admin/model/Styles.php b/hyhproject/admin/model/Styles.php new file mode 100755 index 0000000..6d1662e --- /dev/null +++ b/hyhproject/admin/model/Styles.php @@ -0,0 +1,250 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 商城配置业务处理 + + */ + +use think\Db; + +class Styles extends Base{ + + /** + + * 获取分类 + + */ + + public function getCats(){ + + return $this->distinct(true)->field('styleSys')->select(); + + } + + /** + + * 获取风格列表 + + */ + + public function listQuery(){ + + $styleSys = input('styleSys'); + + $rs = $this->where('styleSys',$styleSys)->select(); + + return ['sys'=>$styleSys,'list'=>$rs]; + + } + + /** + + * 初始化风格列表 + + */ + + public function initStyles(){ + + $styles = $this->field('styleSys,stylePath,id')->select(); + + $sys = []; + + foreach ($styles as $key => $v) { + + $sys[$v['styleSys']][$v['stylePath']] = 1; + + //删除不存在的风格记录 + + if(!is_dir(WSTRootPath(). DS .'hyhproject'. DS .$v['styleSys']. DS .'view'. DS.$v['stylePath'])){ + + $this->where('id',$v['id'])->delete(); + + } + + } + + Db::startTrans(); + + try{ + + //添加不存在的风格目录 + + $prefix = config('database.prefix'); + + foreach ($sys as $key => $v) { + + $dirs = array_map('basename',glob(WSTRootPath(). DS .'hyhproject'.DS.$key.DS.'view'.DS.'*', GLOB_ONLYDIR)); + + foreach ($dirs as $dkey => $dv) { + + if(!isset($v[$dv])){ + + $sqlPath = WSTRootPath(). DS .'hyhproject'. DS .$key. DS .'view'. DS .$dv. DS.'sql'.DS.'install.sql';// sql路径 + + $hasFile = file_exists($sqlPath); + + if(!$hasFile)continue; + + $sql = file_get_contents($sqlPath); + + $this->excute($sql,$prefix); + + } + + } + + } + + Db::commit(); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + + } + + + + /** + + * 编辑 + + */ + + public function changeStyle(){ + + $id = (int)input('post.id'); + + $object = $this->get($id); + + // styleSys stylePath + + + + $sqlPath = WSTRootPath(). DS .'hyhproject'. DS .$object['styleSys']. DS .'view'. DS .$object['stylePath']. DS.'sql'.DS.'style.sql';// sql路径 + + $hasFile = file_exists($sqlPath); + + if(!$hasFile)return WSTReturn('风格sql文件不存在,请联系管理员'); + + $sql = file_get_contents($sqlPath); + + + + $positionArr = ['home'=>1,'wechat'=>2,'mobile'=>3]; + + if(!isset($positionArr[$object['styleSys']]))return WSTReturn('风格目录出错,请联系管理员'); + + $positionType = $positionArr[$object['styleSys']];// 1:PC版 2:微信 3:手机版 + + + + Db::startTrans(); + + try{ + + $prefix = config('database.prefix'); + + /* 删除与风格无关广告 */ + + $delAds = "delete from `".$prefix."ads` where positionType='".$positionType."';"; + + // 若为pc版,则保留商家入驻广告位置 + + if($positionType==1){ + + // 获取当前商家入驻广告位置的主键id + + $positionId = Db::name('ad_positions')->where(['positionCode'=>'ads-shop-apply'])->value('positionId'); + + $delAds = "delete from `".$prefix."ads` where positionType='".$positionType."' and adPositionId!=$positionId;"; + + } + + Db::execute($delAds); + + + + /* 删除无关广告位 */ + + $delAdPosition = "delete from `".$prefix."ad_positions` where positionType='".$positionType."';"; + + // 若为pc版,则保留商家入驻广告 + + if($positionType==1){ + + $delAdPosition = "delete from `".$prefix."ad_positions` where positionType='".$positionType."' and positionCode not in ('ads-shop-apply');"; + + } + + Db::execute($delAdPosition); + + $flag = $this->excute($sql,$prefix); + + if($flag===false)throw new \Exception("风格sql执行出错", 1); + + + + + + $rs = $this->where('styleSys',$object['styleSys'])->update(['isUse'=>0]); + + if(false !== $rs){ + + $object->isUse = 1; + + $object->save(); + + cache('WST_CONF',null); + + Db::commit(); + + return WSTReturn('操作成功',1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn("操作失败"); + + } + + } + + + + /** + + * 执行sql + + */ + + private function excute($sql,$db_prefix=''){ + + if(!isset($sql) || empty($sql)) return; + + $sql = str_replace("\r", " ", str_replace('`wst_', '`'.$db_prefix, $sql));// 替换表前缀 + + $ret = array(); + + foreach(explode(";\n", trim($sql)) as $query) { + + Db::execute(trim($query)); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/SysConfigs.php b/hyhproject/admin/model/SysConfigs.php new file mode 100755 index 0000000..ed24732 --- /dev/null +++ b/hyhproject/admin/model/SysConfigs.php @@ -0,0 +1,134 @@ +<?php + +namespace wstmart\admin\model; + +/** + + * ============================================================================ + + * 商城配置业务处理 + + */ + +use think\Db; + +class SysConfigs extends Base{ + + /** + + * 获取商城配置 + + */ + + public function getSysConfigs(){ + + $rs = $this->field('fieldCode,fieldValue')->select(); + + $rv = []; + + $split = [ + + 'submitOrderTipUsers','payOrderTipUsers','cancelOrderTipUsers','rejectOrderTipUsers','refundOrderTipUsers','complaintOrderTipUsers','cashDrawsTipUsers' + + ]; + + foreach ($rs as $v){ + + if(in_array($v['fieldCode'],$split)){ + + $rv[$v['fieldCode']] = ($v['fieldValue']=='')?[]:explode(',',$v['fieldValue']); + + }else{ + + $rv[$v['fieldCode']] = $v['fieldValue']; + + } + + } + + $signScore = explode(",",$rv['signScore']); + + for($i=0;$i<31;++$i){ + + $rv['signScore'.$i] = ($signScore[0]==0)?0:$signScore[$i]; + + } + + return $rv; + + } + + + + + + /** + + * 编辑 + + */ + + public function edit($fieldType = 0){ + if(1 == input('isDataConfigs')){ + $data = input('post.'); + unset($data['isDataConfigs']); + $m = Model('Table'); + $m->setTable('data_configs'); + Db::startTrans(); + try{ + foreach ($data as $k=>$v) { + $m->updateInfo(['configId'=>$k],['fieldValue'=>$v]); + } + Db::commit(); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + }else{ + $list = $this->where('fieldType',$fieldType)->field('configId,fieldCode,fieldValue')->select(); + Db::startTrans(); + + try{ + + foreach ($list as $key =>$v){ + + $code = trim($v['fieldCode']); + + if(in_array($code,['wstVersion','wstMd5','wstMobileImgSuffix','mallLicense']))continue; + + $val = Input('post.'.trim($v['fieldCode'])); + + //启用图片 + + if(substr($val,0,7)=='upload/' && strpos($val,'.')!==false){ + + WSTUseImages(1, $v['configId'],$val, 'sys_configs','fieldValue'); + + } + + $this->update(['fieldValue'=>$val],['fieldCode'=>$code]); + + } + + Db::commit(); + + cache('WST_CONF',null); + + return WSTReturn("操作成功", 1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + } + } + + + return WSTReturn("操作失败", 1); + + } + + + +} + diff --git a/hyhproject/admin/model/TemplateMsgs.php b/hyhproject/admin/model/TemplateMsgs.php new file mode 100755 index 0000000..e47f65e --- /dev/null +++ b/hyhproject/admin/model/TemplateMsgs.php @@ -0,0 +1,73 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 消息模板业务处理 + */ +class TemplateMsgs extends Base{ + /** + * 分页 + */ + public function pageQuery($tplType,$dataType){ + //dump($tplType); + $page = $this->where(['dataFlag'=>1,'tplType'=>$tplType])->paginate(input('limit/d'))->toArray(); + //dump($page); + if(count($page['Rows'])>0){ + foreach($page['Rows'] as $key =>$data){ + $d = WSTDatas($dataType,$data['tplCode']); + $page['Rows'][$key]['tplCode'] = $d[$data['tplCode']]['dataName']; + } + } + return $page; + } + /** + * 显示是否显示/隐藏 + */ + public function editiIsShow(){ + //获取子集 + $id = input('post.id/d'); + $status = input('post.status/d',0)?0:1; + $result = $this->where('id',$id)->update(['status' => $status]); + if(false !== $result){ + cache('WST_MSG_TEMPLATES',null); + return WSTReturn("操作成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + public function pageEmailQuery(){ + $page = $this->where(['dataFlag'=>1,'tplType'=>1])->paginate(input('limit/d'))->toArray(); + if(count($page['Rows'])>0){ + foreach($page['Rows'] as $key =>$data){ + $d = WSTDatas('TEMPLATE_EMAIL',$data['tplCode']); + $page['Rows'][$key]['tplCode'] = $d[$data['tplCode']]['dataName']; + $page['Rows'][$key]['tplContent'] = strip_tags(htmlspecialchars_decode($data['tplContent'])); + } + } + return $page; + } + /** + * 获取角色权限 + */ + public function getById($id){ + return $this->get(['dataFlag'=>1,'id'=>$id]); + } + /** + * 编辑 + */ + public function edit(){ + $id = (int)input('post.id/d'); + $tplCode = input('post.tplCode'); + $data = []; + $data['tplContent'] = input('post.tplContent'); + $data['status'] = input('post.seoMallSwitch'); + $result = $this->save($data,['id'=>$id,'tplCode'=>$tplCode]); + if(false !== $result){ + cache('WST_MSG_TEMPLATES',null); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/UserRanks.php b/hyhproject/admin/model/UserRanks.php new file mode 100755 index 0000000..bb26b37 --- /dev/null +++ b/hyhproject/admin/model/UserRanks.php @@ -0,0 +1,176 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 会员等级业务处理 + + */ + +class UserRanks extends Base{ + + /** + + * 分页 + + */ + + public function pageQuery(){ + + return $this->where('dataFlag',1)->field(true)->order('rankId desc')->paginate(input('limit/d')); + + } + + public function getById($id){ + + return $this->get(['rankId'=>$id,'dataFlag'=>1]); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $data = input('post.'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + $data['startScore'] = (int) $data['startScore']; + + $data['endScore'] = (int) $data['endScore']; + + WSTUnset($data,'rankId'); + + Db::startTrans(); + + try{ + + $result = $this->validate('UserRanks.add')->allowField(true)->save($data); + + $id = $this->rankId; + + //启用上传图片 + + WSTUseImages(1, $id, $data['userrankImg']); + + if(false !== $result){ + + cache('WST_USER_RANK',null); + + Db::commit(); + + return WSTReturn("新增成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('新增失败',-1); + + } + + } + + /** + + * 编辑 + + */ + + public function edit(){ + + $Id = (int)input('post.rankId'); + + $data = input('post.'); + + $data['startScore'] = (int) $data['startScore']; + + $data['endScore'] = (int) $data['endScore']; + + Db::startTrans(); + + try{ + + WSTUseImages(1, $Id, $data['userrankImg'], 'user_ranks', 'userrankImg'); + + WSTUnset($data,'createTime'); + + $result = $this->validate('UserRanks.edit')->allowField(true)->save($data,['rankId'=>$Id]); + + if(false !== $result){ + + cache('WST_USER_RANK',null); + + Db::commit(); + + return WSTReturn("编辑成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('编辑失败',-1); + + } + + } + + /** + + * 删除 + + */ + + public function del(){ + + $id = (int)input('post.id/d'); + + Db::startTrans(); + + try{ + + $data = []; + + $data['dataFlag'] = -1; + + $result = $this->update($data,['rankId'=>$id]); + + if(false !== $result){ + + WSTUnuseImage('user_ranks','userrankImg',$id); + + cache('WST_USER_RANK',null); + + Db::commit(); + + return WSTReturn("删除成功", 1); + + } + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('编辑失败',-1); + + } + + } + + + +} + diff --git a/hyhproject/admin/model/UserScores.php b/hyhproject/admin/model/UserScores.php new file mode 100755 index 0000000..4978978 --- /dev/null +++ b/hyhproject/admin/model/UserScores.php @@ -0,0 +1,148 @@ +<?php + +namespace wstmart\admin\model; + +use think\Db; + +/** + + * ============================================================================ + + * 积分流水日志业务处理 + + */ + +class UserScores extends Base{ + + + + /** + + * 获取用户信息 + + */ + + public function getUserInfo(){ + + $id = (int)input('id'); + + return model('users')->where('userId',$id)->field('loginName,userId,userName')->find(); + + } + + + + /** + + * 分页 + + */ + + public function pageQuery(){ + + $userId = input('id'); + + $startDate = input('startDate'); + + $endDate = input('endDate'); + + $where = []; + + if($startDate!='')$where['createTime'] = ['>=',$startDate." 00:00:00"]; + + if($endDate!='')$where[' createTime'] = ['<=',$endDate." 23:59:59"]; + + $where['userId'] = $userId; + + $page = $this->where($where)->order('scoreId', 'desc')->paginate(input('limit/d'))->toArray(); + + if(count($page['Rows'])>0){ + + foreach ($page['Rows'] as $key => $v) { + + $page['Rows'][$key]['dataSrc'] = WSTLangScore($v['dataSrc']); + + } + + } + + return $page; + + } + + + + /** + + * 新增记录 + + */ + + public function addByAdmin(){ + + $data = []; + + $data['userId'] = (int)input('userId'); + + $data['score'] = (int)input('score'); + + $data['dataSrc'] = 10001; + + $data['dataId'] = 0; + + $data['scoreType'] = (int)input('scoreType'); + + $data['dataRemarks'] = input('dataRemarks'); + + $data['createTime'] = date('Y-m-d H:i:s'); + + //判断用户身份 + + $user = model('users')->where(['userId'=>$data['userId'],'dataFlag'=>1])->find(); + + if(empty($user))return WSTReturn('无效的会员'); + + if(!in_array($data['scoreType'],[0,1]))return WSTReturn('无效的调节类型'); + + if($data['score']<=0)return WSTReturn('调节积分必须大于0'); + + Db::startTrans(); + + try{ + + $result = $this->insert($data); + + if(false !== $result){ + + if($data['scoreType']==1){ + + $user->userScore = $user->userScore+$data['score']; + + $user->userTotalScore = $user->userTotalScore+$data['score']; + + }else{ + + $user->userScore = $user->userScore-$data['score']; + + } + + $user->save(); + + } + + Db::commit(); + + return WSTReturn('操作成功',1); + + }catch (\Exception $e) { + + Db::rollback();errLog($e); + + return WSTReturn('操作失败',-1); + + } + + } + +} + diff --git a/hyhproject/admin/model/Users.php b/hyhproject/admin/model/Users.php new file mode 100755 index 0000000..ad7e398 --- /dev/null +++ b/hyhproject/admin/model/Users.php @@ -0,0 +1,587 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 会员业务处理 + */ +class Users extends Base{ + /** + * 个体认证审核列表 + * @param int $isPersonal 是否是个体认证 + * @return array + * @throws \think\exception\DbException + */ + public function getReview($isPersonal=1){ + + if(1 == $isPersonal){ + $m = Db::name('auth_personal a'); + }else{ + $m = Db::name('auth_company a'); + } + $where=[]; + $loginName = input('post.loginName'); + if($loginName) $where['u.loginName|u.userPhone'] = $loginName; + $rs = $m->join('__USERS__ u','a.userId=u.userId') + ->where($where) + ->field('u.loginName,u.userPhone,a.*') + ->order('status ASC,createTime ASC') + ->paginate(input('limit/d')) + ->toArray(); + return $rs; + } + /**个体认证操作 + * @param int $isPersonal 是否是个体认证 + * @return array + * @throws \think\Exception + * @throws \think\exception\PDOException + */ + public function authAction($isPersonal=1){ + $data = input('post.'); + $id = $data['id']; + if(1 == $data['status']){ + unset($data['reasonsForRefusal']); + } + $field = '*'; + $user_data = []; + if(1 == $isPersonal){ + $field = 'userId,householdName trueName,userPhone'; + $user_data['authType'] = 1; + $m = Db::name('auth_personal a'); + }else{ + $user_data['authType'] = 2; + $field = 'userId,trueName,userPhone'; + $m = Db::name('auth_company a'); + } + $where['id'] = $id; + $authInfo = $m->where($where)->field($field)->find(); + if(!$authInfo){ + return WSTReturn('认证不存在'); + }else{ + if(1 == $data['status']) { + $user_data['userPhone'] = $authInfo['userPhone']; + $user_data['trueName'] = $authInfo['trueName']; + $user_data['userName'] = $authInfo['trueName']; + }else{ + $user_data['authType'] = 0; + } + Db::name('users')->where(['userId' => $authInfo['userId']])->update($user_data); + } + $data['updateTime'] = time(); + $rs = $m->where($where)->update($data); + if(false !== $rs){ + + return WSTReturn('操作成功',1); + } + return WSTReturn('操作失败,请重试',-1); + } + /** + * 获取申请列表 + */ + public function getUserUpdateList(){ + $where=[]; + $loginName = input('post.loginName'); + if($loginName) $where['u.loginName|u.userPhone'] = $loginName; + $rs = Db::name('user_update d') + ->join('__USERS__ u','d.userId=u.userId') + ->join('__SHOPS__ s','d.shopId=s.shopId') + ->where($where) + ->field('u.loginName,u.userPhone,u.trueName,s.userName,s.phone,s.shopName,s.provinceId,s.cityId,s.countyId,s.townId,s.villageId,d.userId,d.shopId,d.id,d.applyLevel,d.confirmImg,d.shopImg,d.status,d.reasonsForRefusal,d.createTime,d.updateTime') + ->order('status ASC,createTime ASC') + ->paginate(input('limit/d')) + ->toArray(); + $m = Model('common/Position'); + foreach ($rs['Rows'] as &$v) { + $m->initData(1); + $v['province'] = $m->getAreaName($v['provinceId']); + + $m->initData(2); + $v['city'] = $m->getAreaName($v['cityId']); + + $m->initData(3); + $v['county'] = $m->getAreaName($v['countyId']); + + $m->initData(4); + $v['town'] = $m->getAreaName($v['townId']); + + $m->initData(5); + $v['village'] = $m->getAreaName($v['villageId']); + } + return $rs; + } + /** + * 申请操作 + */ + public function setUserUpdate(){ + + $data = input('post.'); + $id = $data['id']; + $applyInfo = Db::name('user_update')->where(['id'=>$id])->field('userId,shopId,applyLevel')->find(); + if(!$applyInfo){ + return WSTReturn('此数据不存在'); + } + $applyLevel = $applyInfo['applyLevel']; + if(!in_array($applyLevel,[2,3,4])) return WSTReturn('请正确输入等级!'); + if(1 == $data['status']){ + unset($data['reasonsForRefusal']); + //店铺位置信息 + $shopInfo = Model('common/shops')->getFieldsById($applyInfo['shopId'],'provinceId,cityId,countyId,townId,villageId'); + $shopInfo = $shopInfo->toArray(); + //检查是否已有代理 + $applyArea=''; + switch ($applyLevel) { + case 2: + $applyArea = 'countyId'; + break; + case 3: + $applyArea = 'townId'; + break; + case 4: + $applyArea = 'villageId'; + break; + } + if(Db::name('user_update')->where(['status'=>1,'applyLevel'=>$applyLevel,$applyArea=>$shopInfo[$applyArea]])->value('id')){ + return WSTReturn('当前区域代理已存在'); + } + $data = array_merge($data,$shopInfo); + } + Db::startTrans(); + try{ + $data['updateTime'] = time(); + if(1 == $data['status']){ + //升级会员等级,没啥用了,留着吧 + $userInfo = getUserInfo(['userId'=>$applyInfo['userId']],'userLevel'); + if($applyLevel > $userInfo['userLevel']){ + Db::name('users')->where(['userId'=>$applyInfo['userId']])->update(['userLevel'=>$applyLevel]); + } + } + if(false !== Db::name('user_update')->where(['id'=>$id])->update($data)){ + Db::commit(); + return WSTReturn('操作成功',1); + } + + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + + } + /** + * 分页 + */ + public function pageQuery(){ + /******************** 查询 ************************/ + $where = []; + $where['u.dataFlag'] = 1; + $lName = input('loginName1'); + $phone = input('loginPhone'); + $email = input('loginEmail'); + $uType = input('userType'); + $uStatus = input('userStatus1'); + $sort = input('sort'); + if(!empty($lName)) + $where['loginName|s.shopName'] = ['like',"%$lName%"]; + if(!empty($phone)) + $where['userPhone'] = ['like',"%$phone%"]; + if(!empty($email)) + $where['userEmail'] = ['like',"%$email%"]; + if(is_numeric($uType)) + $where['userType'] = ['=',"$uType"]; + if(is_numeric($uStatus)) + $where['userStatus'] = ['=',"$uStatus"]; + $order = 'u.userId desc'; + if($sort){ + //$sort = str_replace('.',' ',$sort); + //$order = $sort; + } + /********************* 取数据 *************************/ + $rs = $this->alias('u')->join('__SHOPS__ s','u.userId=s.userId and s.dataFlag=1','left')->join('__USER_TREES__ t','u.userId=t.uid','left')->where($where) + ->field(['u.userId','u.regConfirmImg','loginName','u.userName','userType','userPhone','userEmail','userECT','userScore','u.createTime','u.productNum','u.couponsNum','u.wangNum','userStatus','lastTime','s.shopId','userMoney','u.lockMoney','t.pid']) + ->order($order) + ->group('u.userId') + ->paginate(input('limit/d')) + ->toArray(); + $m = Model('Table'); + foreach ($rs['Rows'] as &$v) { + if($v['pid']){ + $m->setTable('users'); + $v['pName'] = $m->getField(['userId'=>$v['pid']],'loginName'); + }else{ + $v['pName'] = ''; + } + $m->setTable('user_vouchers_summary'); + $sInfo = $m->getInfo(['userId'=>$v['userId']],'expectedProductNum,expectedCouponsNum'); + $v['expectedProductNum'] = (float)$sInfo['expectedProductNum']; + $v['expectedCouponsNum'] = (float)$sInfo['expectedCouponsNum']; + $r = WSTUserRank($v['userScore']); + $v['rank'] = $r['rankName']; + } + return $rs; + } + public function getById($id){ + return $this->get(['userId'=>$id]); + } + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + $data["loginSecret"] = rand(1000,9999); + $data['loginPwd'] = md5($data['loginPwd'].$data['loginSecret']); + WSTUnset($data,'userId,userType,userScore,userTotalScore,lastIP,lastTime,userMoney,lockMoney,dataFlag,rechargeMoney'); + Db::startTrans(); + try{ + $result = $this->validate('Users.add')->allowField(true)->save($data); + $id = $this->userId; + if(false !== $result){ + hook("adminAfterAddUser",["userId"=>$id]); + WSTUseImages(1, $id, $data['userPhoto']); + Db::commit(); + return WSTReturn("新增成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败',-1); + } + } + /** + * 编辑 + */ + public function edit(){ + $Id = (int)input('post.userId'); + $data = input('post.'); + $u = $this->where('userId',$Id)->field('loginSecret')->find(); + if(empty($u))return WSTReturn('无效的用户'); + //判断是否需要修改密码 + if(empty($data['loginPwd'])){ + unset($data['loginPwd']); + }else{ + //修改联盟登录密码 + $password = $data['loginPwd']; + $data['loginPwd'] = md5($data['loginPwd'].$u['loginSecret']); + } + Db::startTrans(); + try{ + if(isset($data['userPhoto'])){ + WSTUseImages(1, $Id, $data['userPhoto'], 'users', 'userPhoto'); + } + + WSTUnset($data,'loginName,createTime,userId,userType,userScore,userTotalScore,lastIP,lastTime,userMoney,lockMoney,dataFlag,rechargeMoney'); + $result = $this->allowField(true)->save($data,['userId'=>$Id]); + if(false !== $result){ + // 同步修改联盟密码 + // if(!empty($password)){ + // Db::table('rd_users')->where(['shop_id'=>$Id])->setField('password',md5($password)); + // } + hook("adminAfterEditUser",["userId"=>$Id]); + Db::commit(); + return WSTReturn("编辑成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('编辑失败',-1); + } + } + /** + * 查看会员定返数据 + */ + public function viewUserDayData(){ + + } + /** + * 充值 + */ + public function recharge(){ + $userId = (int)input('post.userId'); + $loginName = input('post.loginName'); + $rechargeCurrency = input('post.rechargeCurrency');//充值币种,1为ECT + $rechargeType = (int)input('post.rechargeType');//1充值0扣除 + $rechargeNum = (float)input('post.rechargeNum'); + if($rechargeNum <=0){ + return WSTReturn('请正确输入充值数量!'); + } + $rechargeNames = ['0'=>'扣除','1'=>'充值']; + if(!$rechargeCurrency) return WSTReturn('请正确输入币种!'); + if(!$userId) $userId = $this->where('loginName',$loginName)->value('userId'); + if(!$userId) return WSTReturn('未找到此会员'); + Db::startTrans(); + try{ + switch ($rechargeCurrency) { + case 1://预获产品券 + Model('common/UserVouchers')->insertVouchersNotice($userId,0,$rechargeNum,0,'系统'.$rechargeNames[$rechargeType],$rechargeType); + break; + case 2://预获优惠券 + Model('common/UserVouchers')->insertVouchersNotice($userId,0,0,$rechargeNum,'系统'.$rechargeNames[$rechargeType],$rechargeType); + break; + case 3://产品券 + case 4://优惠券 + case 5://旺旺券 + $rechargeCurrency-=2; + Model('common/LogMoneys')->addMoneyLog(0,$userId,0,2,'系统'.$rechargeNames[$rechargeType],$rechargeType,$rechargeNum,'system',$rechargeCurrency); + break; + default: + break; + } + Db::commit(); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + // if($userId){ + // $u = $this->where('userId',$userId)->field('userId,loginSecret,userECT')->find(); + // }else{ + // $u = $this->where('loginName',$loginName)->field('userId,loginSecret,userECT')->find(); + // } + + // if(empty($u))return WSTReturn('无效的用户'); + // $userId = $u['userId']; + // if($rechargeType == 2){//扣除 + // if($rechargeCurrency == 1){ + // if($u['userECT'] < $rechargeNum ){ + // return WSTReturn('余额不足以扣除!当前余额:'.$u['userECT']); + // } + // } + // } + // Db::startTrans(); + // try{ + // if($rechargeCurrency == 1){//ECT + // if($rechargeType == 1){//充值 + // ectLog($userId,$rechargeNum,10,'',['userECT'=>['exp','userECT+'.$rechargeNum]],1); + // }else{ + // ectLog($userId,$rechargeNum,10,'',['userECT'=>['exp','userECT-'.$rechargeNum]],2); + // } + // } + // Db::commit(); + // return WSTReturn("操作成功", 1); + // }catch (\Exception $e) { + // Db::rollback();errLog($e); + // return WSTReturn('操作失败',-1); + // } + } + /** + * 删除 + */ + public function del(){ + $id = (int)input('post.id'); + if($id==1){ + return WSTReturn('无法删除自营店铺账号',-1); + } + Db::startTrans(); + try{ + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['userId'=>$id]); + if(false !== $result){ + //删除店铺信息 + model('shops')->delByUserId($id); + hook("adminAfterDelUser",["userId"=>$id]); + WSTUnuseImage('users','userPhoto',$id); + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('删除失败',-1); + } + } + /** + * 是否启用 + */ + public function changeUserStatus($id, $status){ + Db::startTrans(); + try{ + + $this->update(['userStatus'=>(int)$status],['userId'=>(int)$id]); + if(0 == $status){ + $lockTime =(int)input('post.lockTime'); + $lockReason =input('post.lockReason'); + Db::name('user_lock')->insert(['userId'=>$id,'lockTime'=>$lockTime,'lockReason'=>$lockReason,'createTime'=>time()]); + $this->update(['userStatus'=>(int)$status],['userId'=>(int)$id]); + } + + Db::commit(); + return WSTReturn("操作成功",1); + }catch (\Exception $e) { + //dump($e); + Db::rollback();errLog($e); + } + return WSTReturn("操作失败,请刷新后再重试"); + } + /** + * 根据用户名查找用户 + */ + public function getByName($name){ + return $this->field(['userId','loginName'])->where(['loginName'=>['like',"%$name%"]])->select(); + } + /** + * 获取所有用户id + */ + public function getAllUserId() + { + return $this->where('dataFlag',1)->column('userId'); + } + /** + * 重置支付密码 + */ + public function resetPayPwd(){ + $Id = (int)input('post.userId'); + $loginSecret = $this->where('userId',$Id)->value('loginSecret'); + // 重置支付密码为6个6 + $payPwd = md5('666666'.$loginSecret); + $result = $this->where('userId',$Id)->setField('payPwd',$payPwd); + if(false !== $result){ + return WSTReturn("重置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 根据用户账号查找用户信息 + */ + public function getUserByKey(){ + $key = input('key'); + $user = $this->where(['loginName|userPhone|userEmail'=>['=',$key],'dataFlag'=>1])->find(); + if(empty($user))return WSTReturn('找不到用户',-1); + $shop = model('shops')->where(['userId'=>$user->userId,'dataFlag'=>1])->find(); + if(!empty($shop))return WSTReturn('该用户已存在关联的店铺信息',-1); + return WSTReturn('',1,['loginName'=>$user->loginName,'userId'=>$user->userId]); + } + /** + * 导出订单 --林莉 + */ + public function toExport(){ + $name="会员管理表"; + $where = []; + $where['u.dataFlag'] = 1; + $lName = input('loginName1'); + $phone = input('loginPhone'); + $email = input('loginEmail'); + $uType = input('userType'); + $uStatus = input('userStatus1'); + $sort = input('sort'); + if(!empty($lName)) + $where['loginName|s.shopName'] = ['like',"%$lName%"]; + if(!empty($phone)) + $where['userPhone'] = ['like',"%$phone%"]; + if(!empty($email)) + $where['userEmail'] = ['like',"%$email%"]; + if(is_numeric($uType)) + $where['userType'] = ['=',"$uType"]; + if(is_numeric($uStatus)) + $where['userStatus'] = ['=',"$uStatus"]; + $order = 'u.userId desc'; + /********************* 取数据 *************************/ + $page = db('users')->alias('u')->join('__SHOPS__ s','u.userId=s.userId and s.dataFlag=1','left')->where($where) + ->field(['u.userId','loginName','userName','userType','userPhone','userEmail','userECT','userScore','u.createTime','userStatus','lastTime','s.shopId','userMoney','u.lockMoney']) + ->order($order) + ->select(); + foreach ($page as $key => $v) { + $r = WSTUserRank($v['userScore']); + $page[$key]['rank'] = $r['rankName']; + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("heyuanhui")//创建人 + ->setLastModifiedBy("heyuanhui")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("会员")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(15); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(8); + $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(35); + $objPHPExcel->getActiveSheet()->getColumnDimension('T')->setWidth(25); + $objPHPExcel->getActiveSheet()->getStyle('A1:T1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:T1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet() + ->setCellValue('A1', '账号') + ->setCellValue('B1', '用户名') + ->setCellValue('C1', '手机号码') + ->setCellValue('D1', '电子邮箱') + ->setCellValue('E1', '可用金额') + ->setCellValue('F1', '冻结金额') + ->setCellValue('G1', '积分') + ->setCellValue('H1', 'ECT') + ->setCellValue('I1', '等级') + ->setCellValue('J1', '注册时间') + ->setCellValue('K1', '状态'); + $objPHPExcel->getActiveSheet()->getStyle('A1:R1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['loginName']) + ->setCellValue('B'.$i, $page[$row]['userName']) + ->setCellValue('C'.$i, $page[$row]['userPhone']) + ->setCellValue('D'.$i, $page[$row]['userEmail']) + ->setCellValue('E'.$i, $page[$row]['userMoney']) + ->setCellValue('F'.$i, $page[$row]['lockMoney']) + ->setCellValue('G'.$i, $page[$row]['userScore']) + ->setCellValue('H'.$i, $page[$row]['userECT']) + ->setCellValue('I'.$i, $page[$row]['rank']) + ->setCellValue('J'.$i, $page[$row]['createTime']) + ->setCellValue('K'.$i, $page[$row]['userStatus']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} diff --git a/hyhproject/admin/model/Weixinpays.php b/hyhproject/admin/model/Weixinpays.php new file mode 100755 index 0000000..c5bb078 --- /dev/null +++ b/hyhproject/admin/model/Weixinpays.php @@ -0,0 +1,113 @@ +<?php +namespace wstmart\admin\model; +use think\Loader; +use think\Db; +use Env; +use wstmart\common\model\Payments as M; +use wstmart\common\model\LogPayParams as PM; +/** + * ============================================================================ + * 微信支付业务处理 + */ +class Weixinpays extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function initialize() { + header ("Content-type: text/html; charset=utf-8"); + require Env::get('root_path') . 'extend/wxpay/WxPayConf.php'; + require Env::get('root_path') . 'extend/wxpay/WxJsApiPay.php'; + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + + $this->wxpayConfig['apiclient_cert'] = WSTRootPath().'/extend/wxpay/cert/apiclient_cert.pem'; // 商户支付证书 + $this->wxpayConfig['apiclient_key'] = WSTRootPath().'/extend/wxpay/cert/apiclient_key.pem'; // 商户支付证书 + + $this->wxpayConfig['curl_timeout'] = 30; + $this->wxpayConfig['notifyurl'] = url("admin/orderrefunds/wxrefundnodify","",true,true); + $this->wxpayConfig['returnurl'] = ""; + // 初始化WxPayConf + new \WxPayConf($this->wxpayConfig); + } + + /** + * 退款 + */ + public function orderRefund($refund,$order){ + + $content = input('post.content'); + $refundId = (int)input('post.id'); + + $wxrefund = new \Refund(); + $refund_no = $order['orderNo'].$order['userId']; + $wxrefund->setParameter("transaction_id",$order['tradeNo']);//微信订单号 + $wxrefund->setParameter("out_refund_no",$refund_no);//商户退款单号 + $wxrefund->setParameter("total_fee",$order['totalPayFee']);//订单金额 + $wxrefund->setParameter("refund_fee",$refund["backMoney"]*100);//退款金额 + $wxrefund->setParameter("refund_fee_type","CNY");//货币种类 + $wxrefund->setParameter("refund_desc","订单【".$order['orderNo']."】退款");//退款原因 + $wxrefund->setParameter("notify_url",$this->wxpayConfig['notifyurl']);//退款原因 + + $payParams = []; + $payParams["userId"] = (int)$order['userId']; + $payParams["refundId"] = $refundId; + $payParams["isBatch"] = (int)$order['isBatch']; + $payParams["content"] = $content; + $pdata = array(); + $pdata["userId"] = $order['userId']; + $pdata["transId"] = $refund_no; + $pdata["paramsVa"] = json_encode($payParams); + $pdata["payFrom"] = 'weixinpays'; + $m = new PM(); + $m->addPayLog($pdata); + $rs = $wxrefund->getResult(); + if($rs["result_code"]=="SUCCESS"){ + return WSTReturn("退款成功",1); + }else{ + return WSTReturn($rs['err_code_des'],-1); + } + } + + /** + * 异步通知 + */ + public function notify(){ + // 使用通用通知接口 + $notify = new \Notify(); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $notify->saveData ( $xml ); + if ($notify->data ["return_code"] == "SUCCESS"){ + $order = $notify->getData (); + $req_info = $order["req_info"]; + + $reqinfo = $notify->decryptReqinfo($req_info);//解密退款加密信息 + $transId = $reqinfo["out_refund_no"]; + $m = new PM(); + $payParams = $m->getPayLog(["transId"=>$transId]); + $content = $payParams['content']; + $refundId = $payParams['refundId']; + + $obj = array(); + $obj['refundTradeNo'] = $reqinfo["refund_id"];//微信退款单号 + $obj['content'] = $content; + $obj['refundId'] = $refundId; + $rs = model('admin/OrderRefunds')->complateOrderRefund($obj); + if($rs['status']==1){ + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + } + + +} diff --git a/hyhproject/admin/model/WeixinpaysApp.php b/hyhproject/admin/model/WeixinpaysApp.php new file mode 100755 index 0000000..e04d7de --- /dev/null +++ b/hyhproject/admin/model/WeixinpaysApp.php @@ -0,0 +1,113 @@ +<?php +namespace wstmart\admin\model; +use think\Loader; +use think\Db; +use Env; +use wstmart\common\model\Payments as M; +use wstmart\common\model\LogPayParams as PM; +/** + * ============================================================================ + * 微信支付业务处理 + */ +class WeixinpaysApp extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function initialize() { + header ("Content-type: text/html; charset=utf-8"); + require Env::get('root_path') . 'extend/wxpay/WxPayConf.php'; + require Env::get('root_path') . 'extend/wxpay/WxJsApiPay.php'; + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("app_weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + + $this->wxpayConfig['apiclient_cert'] = WSTRootPath().'/extend/wxpay/cert2/apiclient_cert.pem'; // 商户支付证书 + $this->wxpayConfig['apiclient_key'] = WSTRootPath().'/extend/wxpay/cert2/apiclient_key.pem'; // 商户支付证书 + + $this->wxpayConfig['curl_timeout'] = 30; + $this->wxpayConfig['notifyurl'] = url("admin/orderrefunds/wxapprefundnodify","",true,true); + $this->wxpayConfig['returnurl'] = ""; + // 初始化WxPayConf + new \WxPayConf($this->wxpayConfig); + } + + /** + * 退款 + */ + public function orderRefund($refund,$order){ + + $content = input('post.content'); + $refundId = (int)input('post.id'); + + $wxrefund = new \Refund(); + $refund_no = $order['orderNo'].$order['userId']; + $wxrefund->setParameter("transaction_id",$order['tradeNo']);//微信订单号 + $wxrefund->setParameter("out_refund_no",$refund_no);//商户退款单号 + $wxrefund->setParameter("total_fee",$order['totalPayFee']);//订单金额 + $wxrefund->setParameter("refund_fee",$refund["backMoney"]*100);//退款金额 + $wxrefund->setParameter("refund_fee_type","CNY");//货币种类 + $wxrefund->setParameter("refund_desc","订单【".$order['orderNo']."】退款");//退款原因 + $wxrefund->setParameter("notify_url",$this->wxpayConfig['notifyurl']);//退款原因 + + $payParams = []; + $payParams["userId"] = (int)$order['userId']; + $payParams["refundId"] = $refundId; + $payParams["isBatch"] = (int)$order['isBatch']; + $payParams["content"] = $content; + $pdata = array(); + $pdata["userId"] = $order['userId']; + $pdata["transId"] = $refund_no; + $pdata["paramsVa"] = json_encode($payParams); + $pdata["payFrom"] = 'app_weixinpays'; + $m = new PM(); + $m->addPayLog($pdata); + $rs = $wxrefund->getResult(); + if($rs["result_code"]=="SUCCESS"){ + return WSTReturn("退款成功",1); + }else{ + return WSTReturn($rs['err_code_des'],-1); + } + } + + /** + * 异步通知 + */ + public function notify(){ + // 使用通用通知接口 + $notify = new \Notify(); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $notify->saveData ( $xml ); + if ($notify->data ["return_code"] == "SUCCESS"){ + $order = $notify->getData (); + $req_info = $order["req_info"]; + + $reqinfo = $notify->decryptReqinfo($req_info);//解密退款加密信息 + $transId = $reqinfo["out_refund_no"]; + $m = new PM(); + $payParams = $m->getPayLog(["transId"=>$transId]); + $content = $payParams['content']; + $refundId = $payParams['refundId']; + + $obj = array(); + $obj['refundTradeNo'] = $reqinfo["refund_id"];//微信退款单号 + $obj['content'] = $content; + $obj['refundId'] = $refundId; + $rs = model('admin/OrderRefunds')->complateOrderRefund($obj); + if($rs['status']==1){ + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + } + + +} diff --git a/hyhproject/admin/model/WxPassiveReplys.php b/hyhproject/admin/model/WxPassiveReplys.php new file mode 100755 index 0000000..684b712 --- /dev/null +++ b/hyhproject/admin/model/WxPassiveReplys.php @@ -0,0 +1,70 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 微信被动回复业务处理 + */ +class WxPassiveReplys extends Base{ + /** + * 文本消息分页 + */ + public function textPageQuery(){ + return $this->where(['dataFlag'=>1,'msgType'=>'text'])->field(true)->order('id desc')->paginate(input('limit/d')); + } + /** + * 图文消息分页 + */ + public function newsPageQuery(){ + $rs = $this->where(['dataFlag'=>1,'msgType'=>'news'])->field(true)->order('id desc')->paginate(input('limit/d')); + return WSTReturn('',1,$rs); + } + + public function getById($id){ + return $this->get(['id'=>$id,'dataFlag'=>1]); + } + + + + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + $data['createTime'] = date('Y-m-d H:i:s'); + WSTUnset($data,'id'); + + $result = $this->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + } + return WSTReturn($this->getError(), -1); + + } + /** + * 编辑 + */ + public function edit(){ + $Id = (int)input('post.id'); + $data = input('post.'); + WSTUnset($data,'createTime'); + $result = $this->allowField(true)->save($data,['id'=>$Id]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + } + return WSTReturn('编辑失败',-1); + } + /** + * 删除 + */ + public function del(){ + $id = (int)input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>$id]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + } + return WSTReturn('编辑失败',-1); + } +} diff --git a/hyhproject/admin/model/WxTemplateParams.php b/hyhproject/admin/model/WxTemplateParams.php new file mode 100755 index 0000000..386a653 --- /dev/null +++ b/hyhproject/admin/model/WxTemplateParams.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\admin\model; +/** + * ============================================================================ + * 微信消息参数模板业务处理 + */ +class WxTemplateParams extends Base{ + /** + * 分页 + */ + public function listQuery($parentId){ + $rs = $this->where('parentId',$parentId)->select(); + return WSTReturn('',1,$rs); + } + /** + * 编辑 + */ + public function edit(){ + $id = (int)input('post.id/d'); + $tplCode = input('post.tplCode'); + $data = []; + $data['tplContent'] = input('post.tplContent'); + $data['tplExternaId'] = input('post.tplExternaId'); + $data['status'] = input('post.seoMallSwitch'); + $result = model('admin/TemplateMsgs')->save($data,['id'=>$id,'tplCode'=>$tplCode]); + if(false !== $result){ + cache('WST_MSG_TEMPLATES',null); + $this->where('parentId',$id)->delete(); + $num = (int)input('num'); + if($num>0){ + $tdata = []; + for($i=0;$i<=$num;$i++){ + $code = input('code_'.$i); + if($code=='')continue; + $data = []; + $data['parentId'] = $id; + $data['fieldCode'] = $code; + $data['fieldVal'] = input('val_'.$i); + $tdata[] = $data; + } + if(count($tdata)>0)$this->saveAll($tdata); + } + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + +} diff --git a/hyhproject/admin/model/Wxmenus.php b/hyhproject/admin/model/Wxmenus.php new file mode 100755 index 0000000..65decc8 --- /dev/null +++ b/hyhproject/admin/model/Wxmenus.php @@ -0,0 +1,216 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 微信菜单业务处理 + */ +class WxMenus extends Base{ + /** + * 获取树形分类 + */ + public function pageQuery(){ + $list = $this->where(['dataFlag'=>1,'parentId'=>input('menuId/d',0)])->order('menuSort asc,menuId desc')->paginate(input('post.limit/d'))->toArray(); + foreach($list['Rows'] as $key=>$v){ + $list['Rows'][$key]['menuUrl'] = htmlspecialchars_decode($v['menuUrl']); + } + return $list; + } + + /** + * 获取列表 + */ + public function listQuery(){ + $listMenu = $this->where(['dataFlag'=>1,'parentId'=>0])->field('menuId,menuName')->order('menuSort asc')->select(); + for ($i = 0; $i < count($listMenu); $i++) { + $parentId = $listMenu[$i]["menuId"]; + $listSon = $this->where(['dataFlag'=>1,'parentId'=>$parentId])->field('menuId,menuName')->order('menuSort asc')->select(); + $listMenu[$i]['listSon'] = $listSon; + } + return $listMenu; + } + + /** + * 获取指定对象 + */ + public function getById($id){ + $data = $this->where(['menuId'=>$id])->find(); + $data['menuUrl'] = htmlspecialchars_decode($data['menuUrl']); + return $data; + } + + /** + * 与微信菜单同步 + */ + public function synchroWx(){ + $this->where('menuId>0')->delete(); + $wx = WXAdmin(); + $data = $wx->wxMenuGet(); + if(isset($data['errcode'])){ + if($data['errcode']!=0)return WSTReturn('与微信同步失败,请清除缓存重试'); + } + if($data){ + $data = $data['menu']['button']; + $type = array('click'=>1,'view'=>2,'scancode_push'=>3,'scancode_waitmsg'=>4,'pic_sysphoto'=>5,'pic_photo_or_album'=>6,'pic_weixin'=>7,'location_select'=>8,'media_id'=>9,'view_limited'=>10); + $dataList = []; + foreach( $data as $key=>$v){ + $data = []; + $data['menuName'] = $v['name']; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['menuType'] = (isset($v['type']))?$type[$v['type']]:''; + $data['menuKey'] = (isset($v['key']))?$v['key']:''; + $data['menuSort'] = $key; + $data['menuUrl'] = ''; + $rs = $this->insert($data,false,true); + if($v['sub_button']){ + foreach($v['sub_button'] as $keys=>$vs){ + $datas = []; + $datas['menuName'] = $vs['name']; + $datas['parentId'] = $rs; + $datas['menuSort'] = $keys; + $datas['createTime'] = date('Y-m-d H:i:s'); + $datas['menuType'] = (isset($vs['type']))?$type[$vs['type']]:''; + $datas['menuKey'] = (isset($vs['key']))?$vs['key']:''; + $datas['menuUrl'] = (isset($vs['url']))?$vs['url']:''; + $dataList[] = $datas; + } + } + } + $this->insertAll($dataList); + return WSTReturn("与微信同步成功", 1); + } + } + + /** + * 同步到微信菜单 + */ + public function synchroAd(){ + $rs = Db::name('wx_menus')->where('dataFlag=1')->order('menuSort asc')->select(); + $arr = $this->makeNewArr($rs,0); + header('content-type:text/html;charset=utf-8'); + $arr = json_encode($arr,JSON_UNESCAPED_UNICODE); + $wx = WXAdmin(); + $data = $wx->wxMenuCreate($arr); + if($data['errcode']==0){ + return WSTReturn('菜单同步成功',1); + } + return WSTReturn('菜单同步失败,请清除缓存重试'); + } + function makeNewArr($data,$pId){ + $type = array(1=>'click',2=>'view',3=>'scancode_push',4=>'scancode_waitmsg',5=>'pic_sysphoto',6=>'pic_photo_or_album',7=>'pic_weixin',8=>'location_select',9=>'media_id',10=>'view_limited'); + $c=0; + $newArr = []; + foreach($data as $k=>$v){ + if($v['parentId']==$pId){ + $sub_button = $this->makeNewArr($data,$v['menuId']); + if($pId==0){ + $arr = ['name'=>$v['menuName']]; + if(!empty($sub_button)){ + $arr['sub_button'] = $sub_button; + }else{ + $arr['key']=$v['menuKey']; + $arr['type']=$type[$v['menuType']]; + if($v['menuUrl']!='') + $arr['url']= htmlspecialchars_decode($v['menuUrl']); + } + $newArr['button'][] = $arr; + }else{ + $newArr[$c]['name'] = $v['menuName']; + $newArr[$c]['key'] = $v['menuKey']; + $newArr[$c]['type'] =$type[$v['menuType']]; + if($v['menuUrl']!='') + $newArr[$c]['url'] = htmlspecialchars_decode($v['menuUrl']); + ++$c; + } + } + } + return $newArr; + } + + /** + * 查询菜单个数 + */ + function menuNum($parentId){ + $rs = $this->where(['parentId'=>$parentId,'dataFlag'=>1])->field('menuId')->select(); + return count($rs); + } + + /** + * 新增 + */ + public function add(){ + $data = input('post.'); + if($data['content']==0){ + $data['menuType'] = 2; + } + WSTUnset($data,'menuId,dataFlag,content'); + if(!$data['menuName'])return WSTReturn("请输入菜单名称"); + $num = $this->menuNum($data['parentId']); + if($data['parentId']==0){ + if($num>=3)return WSTReturn("一级菜单数,个数应为1~3个 "); + }else{ + if($num>=5)return WSTReturn("二级菜单数,个数应为1~5个 "); + } + $data['parentId'] = $data['parentId']; + $data['createTime'] = date('Y-m-d H:i:s'); + $result = $this->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 编辑 + */ + public function edit(){ + $menuId = input('post.menuId/d'); + $data = input('post.'); + if($data['content']==0){ + $data['menuType'] = 2; + } + WSTUnset($data,'menuId,dataFlag,createTime,content'); + if(!$data['menuName'])return WSTReturn("请输入菜单名称"); + $result = $this->allowField(true)->save($data,['menuId'=>$menuId]); + if(false !== $result){ + return WSTReturn("修改成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 删除 + */ + public function del(){ + $ids = array(); + $ids[] = input('post.id/d'); + $ids = $this->getChild($ids,$ids); + $data = []; + $data['dataFlag'] = -1; + $result = $this->where("menuId in(".implode(',',$ids).")")->update($data); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 迭代获取下级 + */ + public function getChild($ids = array(),$pids = array()){ + $result = $this->where("dataFlag=1 and parentId in(".implode(',',$pids).")")->field('menuId')->select(); + if(count($result)>0){ + $cids = array(); + foreach ($result as $key =>$v){ + $cids[] = $v['menuId']; + } + $ids = array_merge($ids,$cids); + return $this->getChild($ids,$cids); + }else{ + return $ids; + } + } +} diff --git a/hyhproject/admin/model/Wxusers.php b/hyhproject/admin/model/Wxusers.php new file mode 100755 index 0000000..21f7306 --- /dev/null +++ b/hyhproject/admin/model/Wxusers.php @@ -0,0 +1,115 @@ +<?php +namespace wstmart\admin\model; +use think\Db; +/** + * ============================================================================ + * 微信用户业务处理 + */ +class WxUsers extends Base{ + /** + * 分页 + */ + public function pageQuery(){ + $key = input('get.key'); + $where = []; + if($key!='')$where['userName'] = ['like','%'.$key.'%']; + return $this->where($where)->order('subscribeTime desc,userId desc')->paginate(input('post.limit/d'))->toArray(); + } + + /** + * 获取指定对象 + */ + public function getById($id){ + return $this->where(['userId'=>$id])->find(); + } + + /** + * 与微信用户管理同步 + */ + public function synchroWx(){ + $this->where('userId>0')->delete(); + $wx = WXAdmin(); + $data = $wx->wxUserGet(); + if(isset($data['errcode'])){ + if($data['errcode']!=0)return WSTReturn('与微信同步失败,请清除缓存重试'); + } + if(isset($data['data']) && count($data['data']['openid'])>0){ + $dataList = []; + foreach($data['data']['openid'] as $key=>$v){ + $datas = []; + $datas['openId'] = $v; + $datas['userFill'] = -1; + $dataList[] = $datas; + } + $this->insertAll($dataList); + return WSTReturn("共".$data['total']."个用户需同步", 1,$dataList); + } + } + + public function wxLoad(){ + $openId = input('post.id'); + $wx = WXAdmin(); + $userInfo = $wx->wxUserInfo($openId); + if(isset($userInfo['errcode'])){ + if($userInfo['errcode']!=0)return WSTReturn('与微信同步失败,请清除缓存重试'); + } + $data = []; + $data['userName'] = $userInfo['nickname']; + $data['userSex'] = $userInfo['sex']; + $data['userAreas'] = $userInfo['country'].$userInfo['province'].$userInfo['city']; + $data['userPhoto'] = $userInfo['headimgurl']; + $data['userRemark'] = $userInfo['remark']; + $data['subscribeTime'] = date('Y-m-d H:i:s',$userInfo['subscribe_time']); + $data['groupId'] = $userInfo['groupid']; + $data['openId'] = $userInfo['openid']; + $data['userFill'] = 1; + $result = $this->update($data,['openId'=>$openId,'userFill'=>-1]); + if(false !== $result){ + return WSTReturn("", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 编辑 + */ + public function edit(){ + $userId = input('post.id/d'); + $data = input('post.'); + WSTUnset($data,'userId,userName,userSex,userAreas,userPhoto,subscribeTime,groupId,openId'); + $result = $this->allowField(true)->save($data,['userId'=>$userId]); + if(false !== $result){ + $info = $this->getById($userId); + $wdata = []; + $wdata["openid"] = $info["openId"]; + $wdata["remark"] = $info["userRemark"]; + $wdata = json_encode($wdata,JSON_UNESCAPED_UNICODE); + $wx = WXAdmin(); + $data = $wx->wxUpdateremark($wdata); + return WSTReturn("修改成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 写入unionId + */ + public function recodeUnionId(){ + $m = new \wstmart\common\model\Users; + // 取出已关联微信的账号 + $rs = $m->field('userId,wxOpenId')->where(['wxOpenId'=>['<>','']])->where("isNull(wxUnionId)")->select(); + if(empty($rs))return WSTReturn('无需写入unionId'); + // 写入UnionId + $wx = WXAdmin(); + $update = []; + foreach($rs as $k=>$v){ + $data = $wx->wxUserInfo($v['wxOpenId']); + $item = ['userId'=>$v['userId'],'wxUnionId'=>$data['unionid']]; + array_push($update, $item); + } + $flag = $m->saveAll($update); + if($flag!==false)return WSTReturn('unionId写入完成',1); + return WSTReturn($this->getError(),-1); + } +} diff --git a/hyhproject/admin/validate/Accreds.php b/hyhproject/admin/validate/Accreds.php new file mode 100755 index 0000000..23b2446 --- /dev/null +++ b/hyhproject/admin/validate/Accreds.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 认证商家验证器 + */ +class Accreds extends Validate{ + protected $rule = [ + ['accredName' ,'require|max:30','请输入认证名称|认证名称不能超过30个字符'], + ['accredImg' ,'require','请上传图标'] + ]; + + protected $scene = [ + 'add' => ['accredName','accredImg'], + 'edit' => ['accredName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/AdPositions.php b/hyhproject/admin/validate/AdPositions.php new file mode 100755 index 0000000..8e7da7b --- /dev/null +++ b/hyhproject/admin/validate/AdPositions.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 广告位置验证器 + */ +class AdPositions extends Validate{ + protected $rule = [ + ['positionName' ,'require|max:60','请输入位置名称|位置名称不能超过30个字符'], + ['positionCode' ,'require|max:60','请输入位置代码|位置代码不能超过20个字符'], + ['positionType' ,'require','请选择位置类型'], + ['positionWidth' ,'require|number','请输入建议宽度|建议宽度只能为数字'], + ['positionHeight' ,'require|number','请输入建议高度|建议高度只能为数字'], + ['apSort' ,'number','排序号只能为数字'], + ]; + + protected $scene = [ + 'add' => ['positionName','positionCode','positionType','positionWidth','positionHeight','apSort'], + 'edit' => ['positionName','positionCode','positionType','positionWidth','positionHeight','apSort'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Adgoods.php b/hyhproject/admin/validate/Adgoods.php new file mode 100755 index 0000000..09e15c3 --- /dev/null +++ b/hyhproject/admin/validate/Adgoods.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 广告验证器 + */ +class Adgoods extends Validate{ + protected $rule = [ + ['adId' ,'require|max:30','请输入广告名称|广告名称不能超过10个字符'], + ['adGoodsImg' ,'require','请上传广告图片'], + ['goodsId' ,'require','请上传广告商品'], + ['startDate' , 'require', '请输入广告开始时间' ], + ['endDate' , 'require', '请输入广告结束时间'], + ]; + + protected $scene = [ + 'add' => ['adName','adURL','startDate','endDate'], + 'edit' => ['adName','adURL','startDate','endDate'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Ads.php b/hyhproject/admin/validate/Ads.php new file mode 100755 index 0000000..2b0b023 --- /dev/null +++ b/hyhproject/admin/validate/Ads.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 广告验证器 + */ +class Ads extends Validate{ + protected $rule = [ + ['adName' ,'require|max:60','请输入广告标题|广告标题不能超过30个字'], + ['adFile' ,'require','请上传广告图片'], + ['adStartDate' , 'require', '请输入广告开始时间' ], + ['adEndDate' , 'require', '请输入广告结束时间'], + ]; + + protected $scene = [ + 'add' => ['adName','adURL','adStartDate','adEndDate'], + 'edit' => ['adName','adURL','adStartDate','adEndDate'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Areas.php b/hyhproject/admin/validate/Areas.php new file mode 100755 index 0000000..c8fe1dd --- /dev/null +++ b/hyhproject/admin/validate/Areas.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class Areas extends Validate{ + protected $rule = [ + ['areaName' ,'require|max:30','请输入地区名称|地区名称不能超过10个字符'], + ['areaKey' ,'require|max:2','请输入排序字母|排序字母不能超过1个字符'], + ['areaSort' ,'require|max:16','请输入排序号|排序号不能超过8个字符'], + ]; + + protected $scene = [ + 'add' => ['areaName','areaKey','areaSort'], + 'edit' => ['areaName','areaKey','areaSort'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/ArticleCats.php b/hyhproject/admin/validate/ArticleCats.php new file mode 100755 index 0000000..5e26b95 --- /dev/null +++ b/hyhproject/admin/validate/ArticleCats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class ArticleCats extends Validate{ + protected $rule = [ + ['catName' ,'require|max:30','请输入文章分类名称|文章分类名称不能超过10个字符'], + ['catSort' ,'require|max:16','请输入排序号|排序号不能超过8个字符'], + ]; + + protected $scene = [ + 'add' => ['catName','catSort'], + 'edit' => ['catName','catSort'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Articles.php b/hyhproject/admin/validate/Articles.php new file mode 100755 index 0000000..f355fc7 --- /dev/null +++ b/hyhproject/admin/validate/Articles.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class Articles extends Validate{ + protected $rule = [ + ['articleTitle' ,'require|max:150','请输入文章标题|文章标题不能超过50个字符'], + ['articleKey' ,'require|max:300','请输入关键字|关键字不能超过100个字符'], + ['articleContent' ,'require','请输入文章内容'] + ]; + + protected $scene = [ + 'add' => ['articleTitle','articleKey','articleContent'], + 'edit' => ['articleTitle','articleKey','articleContent'] + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Attributes.php b/hyhproject/admin/validate/Attributes.php new file mode 100755 index 0000000..7735520 --- /dev/null +++ b/hyhproject/admin/validate/Attributes.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 属性验证器 + */ +class Attributes extends Validate{ + protected $rule = [ + ['attrName', 'require|max:60', '请输入属性名称|属性名称不能超过20个字符'], + ['attrType','in:0,1,2','请选择属性类型'], + ['attrVal','checkattrVal:1','请输入发票说明'], + ['isShow','in:0,1','请选择是否显示'] + ]; + protected $scene = [ + 'add'=>['attrName'], + 'edit'=>['attrName'], + ]; + protected function checkattrVal(){ + if(input('post.attrType/d')!=0 && input('post.attrVal')=='')return '请输入属性选项'; + return true; + } + +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Banks.php b/hyhproject/admin/validate/Banks.php new file mode 100755 index 0000000..7efa6e4 --- /dev/null +++ b/hyhproject/admin/validate/Banks.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 银行验证器 + */ +class Banks extends Validate{ + protected $rule = [ + ['bankName' ,'require|max:30','请输入银行名称|银行名称不能超过10个字符'], + ]; + + protected $scene = [ + 'add' => ['bankName'], + 'edit' => ['bankName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Brands.php b/hyhproject/admin/validate/Brands.php new file mode 100755 index 0000000..71e5057 --- /dev/null +++ b/hyhproject/admin/validate/Brands.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class Brands extends Validate{ + protected $rule = [ + ['brandName' ,'require|max:100','请输入品牌名称|品牌名称不能超过50个字符'], + ['brandImg' ,'require','请上传品牌图标'], + ['brandDesc' ,'require','请输入品牌介绍'] + ]; + + protected $scene = [ + 'add' => ['brandName','brandImg','brandDesc'], + 'edit' => ['brandName','brandImg','brandDesc'] + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/ChargeItems.php b/hyhproject/admin/validate/ChargeItems.php new file mode 100755 index 0000000..fddbb95 --- /dev/null +++ b/hyhproject/admin/validate/ChargeItems.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 广告位置验证器 + */ +class ChargeItems extends Validate{ + protected $rule = [ + ['chargeMoney' ,'require|egt:1','请输入充值金额|充值金额必须大于0'], + ['giveMoney' ,'require|egt:0','请输入赠送金额|赠送金额必须不小于0'], + ]; + + protected $scene = [ + 'add' => ['chargeMoney','giveMoney'], + 'edit' => ['chargeMoney','positionCode'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/DataCats.php b/hyhproject/admin/validate/DataCats.php new file mode 100755 index 0000000..d5966bc --- /dev/null +++ b/hyhproject/admin/validate/DataCats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 数据分类验证器 + */ +class DataCats extends Validate{ + protected $rule = [ + ['catName' ,'require','请输入数据分类名称'], + ['catCode' ,'require','请输入数据代码'] + ]; + + protected $scene = [ + 'add' => ['catName','catCode'], + 'edit' => ['catName','catCode'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Datas.php b/hyhproject/admin/validate/Datas.php new file mode 100755 index 0000000..54748bf --- /dev/null +++ b/hyhproject/admin/validate/Datas.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 数据验证器 + */ +class Datas extends Validate{ + protected $rule = [ + ['dataName' ,'require','请输入数据名称'], + ['dataVal' ,'require','请输入数据值'] + ]; + + protected $scene = [ + 'add' => ['dataName','dataVal'], + 'edit' => ['dataName','dataVal'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Express.php b/hyhproject/admin/validate/Express.php new file mode 100755 index 0000000..24343f6 --- /dev/null +++ b/hyhproject/admin/validate/Express.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 快递验证器 + */ +class express extends Validate{ + protected $rule = [ + ['expressName' ,'require|max:30','请输入快递名称|快递名称不能超过10个字符'] + ]; + + protected $scene = [ + 'add' => ['expressName'], + 'edit' => ['expressName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Friendlinks.php b/hyhproject/admin/validate/Friendlinks.php new file mode 100755 index 0000000..b898bbf --- /dev/null +++ b/hyhproject/admin/validate/Friendlinks.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class Friendlinks extends Validate{ + protected $rule = [ + ['friendlinkName' ,'require|max:90','请输入网站名称|网站名称不能超过30个字符'], + ['friendlinkUrl' ,'require','请输入网址'] + ]; + + protected $scene = [ + 'add' => ['friendlinkName'], + 'edit' => ['friendlinkName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/GoodsAppraises.php b/hyhproject/admin/validate/GoodsAppraises.php new file mode 100755 index 0000000..3a4321a --- /dev/null +++ b/hyhproject/admin/validate/GoodsAppraises.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class GoodsAppraises extends Validate{ + protected $rule = [ + ['goodsScore','number|gt:0','评分只能是数字|评分必须大于0'], + ['timeScore','number|gt:0','评分只能是数字|评分必须大于0'], + ['serviceScore','number|gt:0','评分只能是数字|评分必须大于0'], + ['content','length:3,50','评价内容3-50个字'], + ]; + + protected $scene = [ + 'edit'=>['isShow','goodsScore','timeScore','serviceScore','content'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/GoodsCats.php b/hyhproject/admin/validate/GoodsCats.php new file mode 100755 index 0000000..d1161b2 --- /dev/null +++ b/hyhproject/admin/validate/GoodsCats.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class GoodsCats extends Validate{ + protected $rule = [ + ['catName' ,'require|max:30','请输入商品分类名称|商品分类名称不能超过10个字符'], + ['commissionRate' ,'require','请输入分类佣金'], + ['catSort' ,'require|max:16','请输入排序号|排序号不能超过8个字符'], + ]; + + protected $scene = [ + 'add' => ['catName','commissionRate','catSort'], + 'edit' => ['catName','commissionRate','catSort'] + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/GoodsConsult.php b/hyhproject/admin/validate/GoodsConsult.php new file mode 100755 index 0000000..a94ae0b --- /dev/null +++ b/hyhproject/admin/validate/GoodsConsult.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class GoodsConsult extends Validate{ + protected $rule = [ + ['isShow','require|in:0,1','状态不能为空|状态必须为0或1'], + ['consultContent' ,'require|length:3,600','请输入咨询内容|咨询内容应为3-200个字'], + ['reply' ,'require|length:3,600','请输入回复内容|回复内容应为3-200个字'] + ]; + + protected $scene = [ + 'edit'=>['isShow','consultContent','reply'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/HomeMenus.php b/hyhproject/admin/validate/HomeMenus.php new file mode 100755 index 0000000..b2b36e7 --- /dev/null +++ b/hyhproject/admin/validate/HomeMenus.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 菜单验证器 + */ +class HomeMenus extends Validate{ + protected $rule = [ + ['menuName' ,'require|max:30','请输入菜单名称|菜单名称不能超过10个字符'], + ['parentId' ,'number','无效的父级菜单'], + ['menuType' ,'require','请输入菜单类型'], + ['menuUrl' ,'require','请输入菜单Url'], + ['isShow' ,'require','请选择是否显示'] + ]; + + protected $scene = [ + 'add' => ['menuName','parentId','menuType','menuUrl','isShow'], + 'edit' => ['menuName','menuType','menuUrl','isShow'] + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Menus.php b/hyhproject/admin/validate/Menus.php new file mode 100755 index 0000000..091e84a --- /dev/null +++ b/hyhproject/admin/validate/Menus.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 菜单验证器 + */ +class Menus extends Validate{ + protected $rule = [ + ['menuName' ,'require|max:30','请输入菜单名称|菜单名称不能超过10个字符'], + ['parentId' ,'number','无效的父级菜单'] + ]; + + protected $scene = [ + 'add' => ['menuName','parentId'], + 'edit' => ['menuName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/MobileBtns.php b/hyhproject/admin/validate/MobileBtns.php new file mode 100755 index 0000000..f660ab1 --- /dev/null +++ b/hyhproject/admin/validate/MobileBtns.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 移动版按钮验证器 + */ +class MobileBtns extends Validate{ + protected $rule = [ + ['btnName' ,'require','请输入按钮名称'], + ['btnUrl' ,'require','请输入按钮名称'], + ['btnImg' ,'require','请上传图标'] + ]; + + protected $scene = [ + 'add' => ['btnName','btnImg','btnUrl'], + 'edit' => ['btnName','btnUrl'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Navs.php b/hyhproject/admin/validate/Navs.php new file mode 100755 index 0000000..a90d018 --- /dev/null +++ b/hyhproject/admin/validate/Navs.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 导航验证器 + */ +class Navs extends Validate{ + protected $rule = [ + ['navTitle|max:30', 'require', '请输入导航名称|导航名称不能超过10个字符'], + ['navUrl','require', '请输入导航链接'], + ['navSort','integer', '排序号只能为整数'], + ]; + protected $scene = [ + 'add'=>['navTitle','navUrl','navSort'], + 'edit'=>['navTitle','navUrl','navSort'], + ]; + +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Payments.php b/hyhproject/admin/validate/Payments.php new file mode 100755 index 0000000..eb410a0 --- /dev/null +++ b/hyhproject/admin/validate/Payments.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 支付验证器 + */ +class Payments extends Validate{ + protected $rule = [ + ['payName','require','支付名称不能为空'], + ['payDesc','require','支付描述不能为空'], + ['payOrder','require','排序号不能为空'], + ]; + protected $scene = [ + 'edit'=>['payName','payDesc','payOrder'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Privileges.php b/hyhproject/admin/validate/Privileges.php new file mode 100755 index 0000000..ba8027a --- /dev/null +++ b/hyhproject/admin/validate/Privileges.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 权限验证器 + */ +class Privileges extends Validate{ + protected $rule = [ + ['privilegeName' ,'require|max:60','请输入权限名称|权限名称不能超过20个字符'], + ['privilegeCode' ,'require|max:30','请输入权限代码|权限代码不能超过10个字符'], + ['menuId' ,'number','无效的权限菜单'] + ]; + + protected $scene = [ + 'add' => ['privilegeName','privilegeCode','menuId'], + 'edit' => ['privilegeName','privilegeCode'], + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Roles.php b/hyhproject/admin/validate/Roles.php new file mode 100755 index 0000000..7d4a05d --- /dev/null +++ b/hyhproject/admin/validate/Roles.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 角色验证器 + */ +class Roles extends Validate{ + protected $rule = [ + ['roleName' ,'require|max:30','请输入角色名称|角色名称不能超过10个字符'] + ]; + + protected $scene = [ + 'add' => ['menuName'], + 'edit' => ['menuName'] + ]; +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Shops.php b/hyhproject/admin/validate/Shops.php new file mode 100755 index 0000000..9ecbc9e --- /dev/null +++ b/hyhproject/admin/validate/Shops.php @@ -0,0 +1,60 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 店铺验证器 + */ +class Shops extends Validate{ + protected $rule = [ + ['shopSn','checkShopSn:1','请输入店铺编号|店铺编号不能超过20个字符'], + ['shopName' ,'require|max:40','请输入店铺名称|店铺名称不能超过20个字符'], + ['shopCompany' ,'require|max:300','请输入公司名称|公司名称不能超过100个字符'], + ['shopTel' ,'require|max:40','请输入公司联系电话|公司联系电话不能超过20个字符'], + ['shopkeeper' ,'require|max:100','请输入公司紧急联系人|公司紧急联系人不能超过50个字符'], + ['telephone' ,'require|max:40','请输入公司紧急联系人手机|公司紧急联系人手机不能超过20个字符'], + ['isSelf' ,'in:0,1','无效的自营店类型'], + ['shopImg' ,'require','请上传店铺图标'], + ['areaId' ,'require','请选择公司所在区域'], + ['shopAddress' ,'require','请输入公司详细地址'], + ['isInvoice' ,'in:0,1','无效的发票类型'], + ['invoiceRemarks','checkInvoiceRemark:1','请输入发票说明'], + ['shopAtive' ,'in:0,1','无效的营业状态'], + ['bankUserName' ,'require|max:100','请输入银行开户名|银行开户名称长度不能能超过50个字符'], + ['bankNo' ,'require','请输入对公结算银行账号'], + ['bankId' ,'require','请选择结算银行'], + // ['bankAreaId' ,'require','请选择开户所地区'], + ['shopStatus' ,'in:-1,1','无效的店铺状态'], + ['statusDesc' ,'checkStatusDesc:1','请输入店铺停止原因'] + ]; + + protected $scene = [ + 'add' => ['shopSn','shopName','shopCompany','shopkeeper','telephone','shopCompany','shopTel','isSelf','shopImg', + 'areaId','shopAddress','isInvoice','shopAtive','bankId','bankAreaId','bankNo','bankUserName','shopAtive'], + 'edit' => ['shopSn','shopName','shopCompany','shopkeeper','telephone','shopCompany','shopTel','isSelf','shopImg', + 'areaId','shopAddress','isInvoice','shopAtive','bankId','bankAreaId','bankNo','bankUserName','shopAtive'] + ]; + + protected function checkShopSn($value){ + $shopId = Input('post.shopId/d',0); + $key = Input('post.shopSn'); + if($shopId>0){ + if($key=='')return '请输入店铺编号'; + $isChk = model('Shops')->checkShopSn($key,$shopId); + if($isChk)return '对不起,该店铺编号已存在'; + } + return true; + } + + protected function checkInvoiceRemark($value){ + $isInvoice = Input('post.isInvoice/d',0); + $key = Input('post.invoiceRemarks'); + return ($isInvoice==1 && $key=='')?'请输入发票说明':true; + } + + protected function checkStatusDesc($value){ + $shopStatus = Input('post.shopStatus/d',0); + $key = Input('post.statusDesc'); + return ($shopStatus==-1 && $key=='')?'请输入店铺停止原因':true; + } +} \ No newline at end of file diff --git a/hyhproject/admin/validate/SpecCats.php b/hyhproject/admin/validate/SpecCats.php new file mode 100755 index 0000000..bacb880 --- /dev/null +++ b/hyhproject/admin/validate/SpecCats.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 规格类型验证器 + */ +class SpecCats extends Validate{ + protected $rule = [ + ['catName|max:30', 'require', '请输入规格名称|规格名称不能超过10个字符'], + ['goodsCatId','require|gt:0', '请选择所属商品分类'], + ['isAllowImg','number|in:0,1', '请选择是否显示允许上传图片'], + ['isShow','require|in:0,1', '请选择是否显示'] + ]; + protected $scene = [ + 'add'=>['catName','goodsCatId','isAllowImg','isShow'], + 'edit'=>['catName','goodsCatId','isAllowImg','isShow'] + ]; + +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Staffs.php b/hyhproject/admin/validate/Staffs.php new file mode 100755 index 0000000..abb177e --- /dev/null +++ b/hyhproject/admin/validate/Staffs.php @@ -0,0 +1,30 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +use think\Db; +/** + * ============================================================================ + * 职员验证器 + */ +class Staffs extends Validate{ + protected $rule = [ + ['loginName' ,'require|max:20|checkLoginName:1','请输入登录账号|登录账号不能超过20个字符'], + ['loginPwd' ,'require|min:6','请输入登录密码|登录密码不能少于6个字符'], + ['staffName' ,'require|max:60','请输入职员名称|职员名称不能超过20个字符'], + ['workStatus','require|in:0,1','请选择工作状态|无效的工作状态值'], + ['staffStatus','require|in:0,1','请选择账号状态|无效的账号状态值'] + ]; + + protected $scene = [ + 'add' => ['loginName','loginPwd','staffName','workStatus','staffStatus'], + 'edit' => ['staffName','workStatus','staffStatus'] + ]; + + protected function checkLoginName($value){ + $where = []; + $where['dataFlag'] = 1; + $where['loginName'] = $value; + $rs = Db::name('staffs')->where($where)->count(); + return ($rs==0)?true:'该登录账号已存在'; + } +} \ No newline at end of file diff --git a/hyhproject/admin/validate/UserRanks.php b/hyhproject/admin/validate/UserRanks.php new file mode 100755 index 0000000..0625262 --- /dev/null +++ b/hyhproject/admin/validate/UserRanks.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +/** + * ============================================================================ + * 会员级别验证器 + */ +class UserRanks extends Validate{ + protected $rule = [ + ['rankName' ,'require|max:30','请输入会员等级名称|会员等级名称不能超过10个字符'], + ]; + + protected $scene = [ + 'add' => ['rankName'], + 'edit' => ['rankName'], + ]; + + +} \ No newline at end of file diff --git a/hyhproject/admin/validate/Users.php b/hyhproject/admin/validate/Users.php new file mode 100755 index 0000000..16af728 --- /dev/null +++ b/hyhproject/admin/validate/Users.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\admin\validate; +use think\Validate; +use think\Db; +/** + * ============================================================================ + * 会员验证器 + */ +class Users extends Validate{ + protected $rule = [ + ['loginName' ,'require|max:30|checkLoginName:1','请输入账号|账号不能超过10个字符'], + ]; + + protected $scene = [ + 'add' => ['loginName'], + ]; + + protected function checkLoginName($value){ + $where = []; + $where['dataFlag'] = 1; + $where['loginName'] = $value; + if((int)input('userId')>0){ + $where['userId'] = ['<>',(int)input('post.userId')]; + } + $rs = Db::name('users')->where($where)->count(); + return ($rs==0)?true:'该登录账号已存在'; + } + +} \ No newline at end of file diff --git a/hyhproject/admin/view/accreds/accreds.js b/hyhproject/admin/view/accreds/accreds.js new file mode 100755 index 0000000..32e30e8 --- /dev/null +++ b/hyhproject/admin/view/accreds/accreds.js @@ -0,0 +1,156 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'图标', name:'accredImg' ,width:50, align:'center', renderer: function(val,item,rowIndex){ + return '<img src="'+WST.conf.IMGURL+'/'+item['accredImg']+'" height="28px" />'; + }}, + {title:'认证名称', name:'accredName' ,width:125}, + {title:'创建时间', name:'createTime' ,width:75,}, + {title:'操作', name:'' ,width:60, align:'center', renderer: function(val,item,rowIndex){ + var h=""; + if(WST.GRANT.RZGL_02)h += "<a class='btn btn-blue' href='javascript:getForEdit(" + item['accredId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.RZGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['accredId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/Accreds/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/accreds/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.accredId){ + WST.setValues(json); + //显示原来的图片 + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.accredImg+'" height="70px" />'); + $('#isImg').val('ok'); + toEdit(json.accredId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + if(!isInitUpload){ + initUpload(); + } + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#accredBox'),area: ['450px', '280px'],btn: ['确定','取消'],yes:function(){ + $('#accredForm').submit(); + },cancel:function(){ + //重置表单 + $('#accredForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#accredImg').val(''); + + },end:function(){ + $('#accredBox').hide(); + //重置表单 + $('#accredForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#accredImg').val(''); + + }}); + $('#accredForm').validator({ + fields: { + accredName: { + rule:"required;", + msg:{required:"请输入认证名称"}, + tip:"请输入认证名称", + ok:"", + }, + accredImg: { + rule:"required;", + msg:{required:"请上传图标"}, + tip:"请上传图标", + ok:"", + }, + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.accredId = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/accreds/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#accredForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#accredImg').val(''); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} +var isInitUpload = false; +function initUpload(){ + isInitUpload = true; + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'accreds'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#accredImg').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} + + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Accreds/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/accreds/list.html b/hyhproject/admin/view/accreds/list.html new file mode 100755 index 0000000..45efdbd --- /dev/null +++ b/hyhproject/admin/view/accreds/list.html @@ -0,0 +1,50 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/accreds/accreds.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} +{block name="main"} +{if WSTGrant('RZGL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:toEdit(0)"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> + +<div id='accredBox' style='display:none'> + <form id='accredForm' method="post" autocomplete="off"> + + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>认证名称<font color='red'>*</font>:</th> + <td><input type='text' id='accredName' name="accredName" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th>图标:</th> + <td> + <div id='adFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='accredImg' name="accredImg" class="ipt" /> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:70px;" id="preview"></div></td> + </tr> + </table> + + </form> + + </div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/addons/addons.js b/hyhproject/admin/view/addons/addons.js new file mode 100755 index 0000000..656a7de --- /dev/null +++ b/hyhproject/admin/view/addons/addons.js @@ -0,0 +1,110 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'名称', name:'title', width: 50,sortable:true}, + {title:'标识', name:'name', width: 10,sortable:true}, + {title:'描述', name:'description', width: 220,sortable:true}, + {title:'状态', name:'status', width: 10,sortable:true, renderer: function(val,item,rowIndex){ + if(item['status']==0){ + return "<span class='statu-wait'><i class='fa fa-ban'></i> "+item.statusName+"</span>"; + }else if(item['status']==2){ + return "<span class='statu-no'><i class='fa fa-ban'></i> "+item.statusName+"</span>"; + }else{ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> "+item.statusName+"</span>"; + } + }}, + {title:'作者', name:'author', width: 10,sortable:true}, + {title:'版本', name:'version', width: 5,sortable:true}, + {title:'操作', name:'' ,width:100, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.CJGL_01 && item['status']>0 && item['isConfig']==1)h += "<a class='btn btn-blue' href='"+WST.U('admin/Addons/toEdit','id='+item['addonId'])+"'><i class='fa fa-gear'></i>设置</a> "; + if(WST.GRANT.CJGL_02 && item['status']==0)h += "<a class='btn btn-blue' href='javascript:install(" + item['addonId'] + ")'><i class='fa fa-gear'></i>安装</a> "; + if(WST.GRANT.CJGL_03 && item['status']>0)h += "<a class='btn btn-red' href='javascript:uninstall(" + item['addonId'] + ")'><i class='fa fa-trash-o'></i>卸载</a> "; + if(WST.GRANT.CJGL_04 && item['status']==2)h += "<a class='btn btn-blue' href='javascript:enable(" + item['addonId'] + ")'><i class='fa fa-check'></i>启用</a> "; + if(WST.GRANT.CJGL_05 && item['status']==1)h += "<a class='btn btn-red' href='javascript:disable(" + item['addonId'] + ")'><i class='fa fa-ban'></i>禁用</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/addons/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'status',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +//安装 +function install(id){ + var loading = WST.msg('正在安装,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/addons/install'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("安装成功,请刷页面",{icon:1}); + layer.close(loading); + addonsQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +//卸载 +function uninstall(id){ + var box = WST.confirm({content:"您确定要卸载吗?",yes:function(){ + var loading = WST.msg('正在卸载,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/addons/uninstall'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("卸载成功,请刷页面",{icon:1}); + layer.close(box); + addonsQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +//禁用 +function enable(id){ + var loading = WST.msg('正在启用,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/addons/enable'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("启用成功",{icon:1}); + layer.close(loading); + addonsQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +//启用 +function disable(id){ + var loading = WST.msg('正在禁用,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/addons/disable'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("禁用成功",{icon:1}); + layer.close(loading); + addonsQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +//查询 +function addonsQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} + diff --git a/hyhproject/admin/view/addons/config.html b/hyhproject/admin/view/addons/config.html new file mode 100755 index 0000000..262e238 --- /dev/null +++ b/hyhproject/admin/view/addons/config.html @@ -0,0 +1,168 @@ +{extend name="base" /} +{block name="main"} + <div > + <form action="{:url('saveConfig')}" method="post" style="line-height: 30px;margin:10px;" autocomplete="off"> + <div class="main-title cf"> + <div class="addoncfg-title">插件配置 [ {$data.title} ]</div> + </div> + {foreach name="data['config']" item="form" key="o_key"} + <div class="form-item cf"> + {present name="form.title"} + <label class="item-label"> + <span style="font-weight: bold;">{$form.title|default=''}</span> + + </label> + {/present} + {switch name="form.type"} + {case value="tips"} + <div> + {$form.value} + </div> + {/case} + {case value="text"} + <div> + <input type="text" name="config[{$o_key}]" class="text input-large" value="{$form.value}" style="width:400px;"><?php if(isset($form['tips'])){ ?><span>{$form.tips}</span><?php } ?> + </div> + {/case} + {case value="password"} + <div> + <input type="password" name="config[{$o_key}]" class="text input-large" value="{$form.value}"> + </div> + {/case} + {case value="hidden"} + <input type="hidden" name="config[{$o_key}]" value="{$form.value}"> + {/case} + {case value="radio"} + <div class="layui-form"> + {foreach name="form.options" item="opt" key="opt_k"} + <label class="radio"> + <input type="radio" name="config[{$o_key}]" value="{$opt_k}" {eq name="form.value" value="$opt_k"} checked{/eq} title="{$opt}"> + </label> + {/foreach} + </div> + {/case} + {case value="checkbox"} + <div> + {foreach name="form.options" item="opt" key="opt_k"} + <label class="checkbox"> + {php} + is_null($form["value"]) && $form["value"] = array(); + {/php} + <input type="checkbox" name="config[{$o_key}][]" value="{$opt_k}" {in name="opt_k" value="$form.value"}checked{/in}>{$opt} + </label> + {/foreach} + </div> + {/case} + {case value="select"} + <div> + <select name="config[{$o_key}]"> + {foreach name="form.options" item="opt" key="opt_k"} + <option value="{$opt_k}" {eq name="form.value" value="$opt_k"} selected{/eq}>{$opt}</option> + {/foreach} + </select> + </div> + {/case} + {case value="textarea"} + <div> + <label class="textarea input-large"> + <textarea name="config[{$o_key}]" style="width:500px;height:200px;">{$form.value}</textarea> + </label> + </div> + {/case} + + {case value="group"} + <ul class="tab-nav nav"> + {volist name="form.options" id="li"} + <li data-tab="tab{$i}" {eq name="i" value="1"}class="current" {/eq} ><a href="javascript:void(0);">{$li.title}</a></li> + {/volist} + <div style="clear: both;"></div> + </ul> + <div class="tab-content"> + {volist name="form.options" id="tab"} + <div id="tab{$i}" class="tab-pane {eq name="i" value="1"}in{/eq} tab{$i}"> + {foreach name="tab['options']" item="tab_form" key="o_tab_key"} + <label class="item-label"> + <span style="font-weight: bold;">{$tab_form.title|default=''}</span> + {present name="tab_form.tip"} + <span class="check-tips">{$tab_form.tip}</span> + {/present} + </label> + <div> + {switch name="tab_form.type"} + {case value="tips"} + <div> + {$form.value} + </div> + {/case} + {case value="text"} + <input type="text" name="config[{$o_tab_key}]" class="text input-large" value="{$tab_form.value}" style="width:400px;"> + {/case} + {case value="password"} + <input type="password" name="config[{$o_tab_key}]" class="text input-large" value="{$tab_form.value}"> + {/case} + {case value="hidden"} + <input type="hidden" name="config[{$o_tab_key}]" value="{$tab_form.value}"> + {/case} + {case value="radio"} + {foreach name="tab_form.options" item="opt" key="opt_k"} + <label class="layui-form radio"> + <input type="radio" name="config[{$o_tab_key}]" value="{$opt_k}" {eq name="tab_form.value" value="$opt_k"} checked{/eq} title="{$opt}"> + </label> + {/foreach} + {/case} + {case value="checkbox"} + {foreach name="tab_form.options" item="opt" key="opt_k"} + <label class="checkbox"> + {php} + is_null($tab_form["value"]) && $tab_form["value"] = array(); + {/php} + <input type="checkbox" name="config[{$o_tab_key}][]" value="{$opt_k}" {in name="opt_k" value="$tab_form.value"} checked{/in}>{$opt} + </label> + {/foreach} + {/case} + {case value="select"} + <select name="config[{$o_tab_key}]"> + {foreach name="tab_form.options" item="opt" key="opt_k"} + <option value="{$opt_k}" {eq name="tab_form.value" value="$opt_k"} selected{/eq}>{$opt}</option> + {/foreach} + </select> + {/case} + {case value="textarea"} + <label> + <textarea name="config[{$o_tab_key}]">{$tab_form.value}</textarea> + </label> + {/case} + + {/switch} + </div> + {/foreach} + </div> + {/volist} + </div> + {/case} + {/switch} + </div> + {/foreach} + <div class="form-item cf wst-bottombar" style='padding-left:130px;padding-top:10px'> + <input type="hidden" name="id" value="{$addonId}" readonly/> + <button type="submit" class="btn submit-btn ajax-post btn-primary btn-mright" ><i class="fa fa-check"></i>确 定</button>&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick="location.href='{:url("admin/addons/index")}'"><i class="fa fa-angle-double-left"></i>返回</button> + </div> + </form> + </div> +{/block} + +{block name="js"} +<script type="text/javascript" charset="utf-8"> + +$(function(){ + $(".tab-nav li").click(function(){ + var self = $(this), target = self.data("tab"); + self.addClass("current").siblings(".current").removeClass("current"); + //window.location.hash = "#" + target.substr(3); + $(".tab-pane.in").removeClass("in"); + $("." + target).addClass("in"); + }).filter("[data-tab=tab" + window.location.hash.substr(1) + "]").click(); +}) +</script> +{/block} diff --git a/hyhproject/admin/view/addons/list.html b/hyhproject/admin/view/addons/list.html new file mode 100755 index 0000000..a9e8fb2 --- /dev/null +++ b/hyhproject/admin/view/addons/list.html @@ -0,0 +1,27 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/addons/addons.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div id="query" style="float:left;"> + <input type="text" name="keyWords" placeholder="插件名称、标识" id="keyWords" class="j-ipt query"> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:addonsQuery()"><i class="fa fa-search"></i>查询</button> + <span style="color:red;font-weight:bold;">&nbsp;&nbsp;安装插件后,进入“设置”,填写配置信息,然后点击保存!</span> + </div> + + <div style="clear:both"></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/adgoods/admgrs.js b/hyhproject/admin/view/adgoods/admgrs.js new file mode 100755 index 0000000..bdebf3c --- /dev/null +++ b/hyhproject/admin/view/adgoods/admgrs.js @@ -0,0 +1,184 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'图标', name:'' ,width:50, align:'center', renderer: function(val,item,rowIndex){ + var adGoodsImg = item['adGoodsImg'].split(','); + return'<img src="'+WST.conf.IMGURL+'/'+adGoodsImg[0]+'" height="28px" width="100"/>'; + }}, + {title:'广告名称', name:'adName' ,width:80}, + {title:'商品名称', name:'goodsName' ,width:130}, + {title:'商品种类', name:'adGoodsStatus' ,width:30,renderer: function(val,item,rowIndex){ + if(item['adGoodsStatus']==1){return "精选"} + if(item['adGoodsStatus']==2){return "推荐"} + if(item['adGoodsStatus']==3){return "热卖"} + }}, + {title:'广告开始日期', name:'startDate' ,width:50}, + {title:'广告结束日期', name:'endDate' ,width:50}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.GGGL_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+item['adGoodsId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.GGGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['adGoodsId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/adgoods/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-155}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function toEdit(id){ + location.href = WST.U('admin/adgoods/toEdit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Adgoods/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function loadQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +var oldSort; +function changeSort(t,id){ + $(t).attr('ondblclick'," "); +var html = "<input type='text' id='sort-"+id+"' style='width:30px;padding:2px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); +} +function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/adgoods/changeSort'),{id:id,adSort:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); +} + + + +//查询 +function adsQuery(){ + var query = WST.getParams('.query'); + grid.set('url',WST.U('admin/adgoods/pageQuery',query)); +} + +function editInit(){ + var laydate = layui.laydate; + form = layui.form; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'adspic'}, + compress:false,//默认不对图片进行压缩 + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var html = '<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" />'; + $('#preview').html(html); + // 图片路径 + $('#adGoodsImg').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + + /* 表单验证 */ + $('#adsForm').validator({ + fields: { + adGoodsStatus: { + rule:"required", + msg:{required:"请选择广告商品类型"}, + tip:"请选择广告商品类型", + ok:"验证通过", + }, + adId: { + rule:"required;", + msg:{required:"广告名称不能为空"}, + tip:"请输入广告名称", + ok:"验证通过", + }, + adGoodsImg: { + rule:"required;", + msg:{required:"请上传广告图片"}, + tip:"请上传广告图片", + ok:"", + }, + goodsId: { + rule:"required;", + msg:{required:"请上传广告商品"}, + tip:"请上传广告商品", + ok:"", + }, + startDate: { + rule:"required;match(lt, endDate, date)", + msg:{required:"请选择广告开始时间",match:"必须小于广告结束时间"}, + ok:"验证通过", + }, + endDate: { + rule:"required;match(gt, startDate, date)", + msg:{required:"请选择广告结束时间",match:"必须大于广告开始时间"}, + ok:"验证通过", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Adgoods/'+((params.adGoodsId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Adgoods/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +// \ No newline at end of file diff --git a/hyhproject/admin/view/adgoods/ads.js b/hyhproject/admin/view/adgoods/ads.js new file mode 100755 index 0000000..067abd9 --- /dev/null +++ b/hyhproject/admin/view/adgoods/ads.js @@ -0,0 +1,189 @@ +var grid; +function initGrid(){ + grid = $("#maingrid").ligerGrid({ + url:WST.U('admin/Ads/pageQuery'), + pageSize:WST.pageSize, + pageSizeOptions:WST.pageSizeOptions, + height:'99%', + width:'100%', + minColToggle:6, + rownumbers:true, + columns: [ + { display: '标题', name: 'adName', isSort: false}, + { display: '广告位置', name: 'adPositionId', isSort: false,render:function(rowdata, rowindex, value){ + return rowdata['positionName']; + }}, + { display: '广告网址', name: 'adURL', isSort: false}, + { display: '广告开始日期', name: 'adStartDate', isSort: false}, + { display: '广告结束日期', name: 'adEndDate', isSort: false}, + { display: '图标', name: 'adFile', height: '300', isSort: false,render:function(rowdata, rowindex, value){ + var adFile = rowdata['adFile'].split(','); + return'<img src="'+WST.conf.IMGURL+'/'+adFile[0]+'" height="28px" />'; + }}, + { display: '点击数', name: 'adClickNum', isSort: false}, + { display: '排序号', name: 'adSort', isSort: false,render:function(rowdata, rowindex, value){ + return '<span style="cursor:pointer;" ondblclick="changeSort(this,'+rowdata["adId"]+');">'+value+'</span>'; + }}, + { display: '操作', name: 'op',isSort: false,render: function (rowdata, rowindex, value){ + var h = ""; + if(WST.GRANT.GGGL_02)h += "<a href='"+WST.U('admin/Ads/toEdit','id='+rowdata['adId'])+"'>修改</a> "; + if(WST.GRANT.GGGL_03)h += "<a href='javascript:toDel(" + rowdata['adId'] + ")'>删除</a> "; + return h; + }} + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +var oldSort; +function changeSort(t,id){ + $(t).attr('ondblclick'," "); +var html = "<input type='text' id='sort-"+id+"' style='width:30px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); +} +function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/ads/changeSort'),{id:id,adSort:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); +} + + + +//查询 +function adsQuery(){ + var query = WST.getParams('.query'); + grid.set('url',WST.U('admin/ads/pageQuery',query)); +} + +function editInit(){ + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'adspic'}, + compress:false,//默认不对图片进行压缩 + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var html = '<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" />'; + $('#preview').html(html); + // 图片路径 + $('#adFile').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + + /* 表单验证 */ + $('#adsForm').validator({ + fields: { + adPositionId: { + rule:"required", + msg:{required:"请选择广告位置"}, + tip:"请选择广告位置", + ok:"验证通过", + }, + adName: { + rule:"required;", + msg:{required:"广告标题不能为空"}, + tip:"请输入广告标题", + ok:"验证通过", + }, + adFile: { + rule:"required;", + msg:{required:"请上传广告图片"}, + tip:"请上传广告图片", + ok:"", + }, + adStartDate: { + rule:"required;match(lt, adEndDate, date)", + msg:{required:"请选择广告开始时间",match:"必须小于广告结束时间"}, + ok:"验证通过", + }, + adEndDate: { + rule:"required;match(gt, adStartDate, date)", + msg:{required:"请选择广告结束时间",match:"必须大于广告开始时间"}, + ok:"验证通过", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/'+((params.adId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Ads/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +var positionInfo; +/*获取地址*/ +function addPosition(pType, val, getSize) +{ + $.post(WST.U('admin/Adpositions/getPositon'),{'positionType':pType},function(data,textStatus){ + positionInfo = data; + var html='<option value="">请选择</option>'; + $(data).each(function(k,v){ + var selected; + if(v.positionId==val){ + selected = 'selected="selected"'; + getPhotoSize(v.positionId); + } + html +='<option '+selected+' value="'+v.positionId+'">'+v.positionName+'</option>'; + }); + $('#adPositionId').html(html); + }) +} +/*获取图片尺寸 以及设置图片显示方式*/ +function getPhotoSize(pType) +{ + $(positionInfo).each(function(k,v){ + if(v.positionId==pType){ + $('#img_size').html(v.positionWidth+'x'+v.positionHeight); + if(v.positionWidth>v.positionHeight){ + $('.ads-h-list').removeClass('ads-h-list').addClass('ads-w-list'); + } + } + }); + +} \ No newline at end of file diff --git a/hyhproject/admin/view/adgoods/edit.html b/hyhproject/admin/view/adgoods/edit.html new file mode 100755 index 0000000..0f1a152 --- /dev/null +++ b/hyhproject/admin/view/adgoods/edit.html @@ -0,0 +1,92 @@ +{extend name="base" /} +{block name="css"} +<style> +#preview img{max-width: 600px;max-height:150px;} +</style> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/adgoods/admgrs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="adsForm"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>广告名称<font color='red'>*</font>:</th> + <td> + <select id="adId" name="adId" class='ipt' maxLength='20'> + <option value=''>请选择</option> + {volist name="result" id='vo'} + <option {if $data['adName'] == $vo['adName']}selected{/if} value="{$vo['adId']}">{$vo['adName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>广告商品类型<font color='red'>*</font>:</th> + <td> + <select id="adGoodsStatus" name="adGoodsStatus" class='ipt' maxLength='20'> + <option value="">-请选择-</option> + + <option {if $data['adGoodsStatus'] == 1}selected{/if} value="1">-精选-</option> + <option {if $data['adGoodsStatus'] == 2}selected{/if} value="2">-推荐-</option> + <option {if $data['adGoodsStatus'] == 3}selected{/if} value="3">-热卖-</option> + </select> + </td> + </tr> + <tr> + <tr> + <tr> + <th>广告商品ID<font color='red'>*</font>:</th> + <td><input type='text' id='goodsId' name="goodsId" value="{$data['goodsId']}" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th>广告图片<font color='red'>*</font>:</th> + <td><div id='adFilePicker'>上传广告图</div><span id='uploadMsg'></span> + <div> + 图片大小:<span id="img_size">300x300</span>(px),格式为 gif, jpg, jpeg, png + </div> + </td> + + </tr> + <tr> + <th>预览图<font color='red'> </font>:</th> + <td> + <div id="preview" style="min-height:30px;"> + {if ($data['adGoodsImg']!='')} + <img src="__IMGURL__/{$data['adGoodsImg']}"> + {/if} + </div> + <input type="hidden" name="adGoodsImg" id="adGoodsImg" class="ipt" value="{$data['adGoodsImg']}" /> + </td> + </tr> + <th >广告开始时间<font color='red'>*</font>:</th> + <td> + <input type="text" style="margin:0px;vertical-align:baseline;" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value="{$data['startDate']}" /> + </td> + </tr> + <tr> + <th>广告结束时间<font color='red'>*</font>:</th> + <td> + <input type="text" style="margin:0px;vertical-align:baseline;" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value="{$data['endDate']}" /> + </td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="adGoodsId" class="ipt" value="{$data['adGoodsId']+0}" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ +editInit(); +//初始化位置类型 +}); + +</script> +{/block} + diff --git a/hyhproject/admin/view/adgoods/list.html b/hyhproject/admin/view/adgoods/list.html new file mode 100755 index 0000000..e1939fd --- /dev/null +++ b/hyhproject/admin/view/adgoods/list.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/adgoods/admgrs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>广告位置类型主要用于确定广告在商城里的位置,调用时把广告代码放入相应位置即可显示广告</li> + </ul> +</div> +<form autocomplete="off" > +<div class="wst-toolbar"> + <select name="adId" id="adId" class="query"> + <option value="">请选择广告名称</option> + <option value=''>请选择</option> + {volist name="result" id='vo'} + <option value="{$vo['adId']}">{$vo['adName']}</option> + {/volist} + </select> + <button class="btn btn-primary" type='button' onclick="javascript:loadQuery()"><i class='fa fa-search'></i>查询</button> + {if WSTGrant('GGGL_01')} + <button class="btn btn-success f-right btn-fixtop" type='button' onclick="javascript:location.href='<?=url("admin/adgoods/toEdit")?>'"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +</form> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/adpositions/adpositions.js b/hyhproject/admin/view/adpositions/adpositions.js new file mode 100755 index 0000000..a83baa0 --- /dev/null +++ b/hyhproject/admin/view/adpositions/adpositions.js @@ -0,0 +1,124 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'位置名称', name:'positionName', width: 230}, + {title:'宽度', name:'positionWidth' ,width:30}, + {title:'高度', name:'positionHeight' ,width:30}, + {title:'位置类型', name:'' ,width:30, align:'center', renderer: function(val,item,rowIndex){ + var pName; + switch(item['positionType']){ + case 2: + pName='微信版'; + break; + case 3: + pName='手机版'; + break; + case 4: + pName='APP版'; + break; + default: + pName='PC版'; + break; + } + return pName; + }}, + {title:'位置代码', name:'positionCode' ,width:40}, + {title:'操作', name:'' ,width:60, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.GGWZ_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+item['positionId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.GGWZ_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['positionId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-175,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/Adpositions/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-175}); + }else{ + mmg.resize({height:h-130}); + } + }}); +} +function toEdit(id){ + location.href = WST.U('admin/Adpositions/toedit','id='+id); +} +function loadQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/AdPositions/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + +function editInit(){ + /* 表单验证 */ + $('#adPositionsForm').validator({ + fields: { + positionType: { + rule:"required", + msg:{required:"请选择位置类型"}, + tip:"请选择位置类型", + ok:"", + }, + positionName: { + rule:"required;", + msg:{required:"请输入位置名称"}, + tip:"请输入位置名称", + ok:"", + }, + positionCode: { + rule:"required;", + msg:{required:"请输入位置代码"}, + tip:"请输入位置代码", + ok:"", + }, + positionWidth: { + rule:"required;", + msg:{required:"请输入建议宽度"}, + ok:"", + }, + positionHeight: { + rule:"required", + msg:{required:"请输入建议高度"}, + ok:"", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Adpositions/'+((params.positionId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Adpositions/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/adpositions/edit.html b/hyhproject/admin/view/adpositions/edit.html new file mode 100755 index 0000000..bd8644a --- /dev/null +++ b/hyhproject/admin/view/adpositions/edit.html @@ -0,0 +1,67 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/adpositions/adpositions.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="adPositionsForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>位置类型<font color='red'>*</font>:</th> + <td> + <select id="positionType" name="positionType" class='ipt' maxLength='20'> + <option value="">-请选择-</option> + {volist name=":WSTDatas('ADS_TYPE')" id='vo'} + <option <?=($data['positionType']==$vo['dataVal'])?'selected':'';?> value="{$vo['dataVal']}">{$vo['dataName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>位置名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="positionName" name="positionName" value='{$data['positionName']}' class="ipt" /> + </td> + </tr> + <tr> + <th>位置代码<font color='red'>*</font>:</th> + <td> + <input type="text" id="positionCode" name="positionCode" value='{$data['positionCode']}' class="ipt" /> + </td> + </tr> + <tr> + <th>建议宽度<font color='red'>*</font>:</th> + <td> + <input type="text" id="positionWidth" name="positionWidth" value='{$data['positionWidth']}' class="ipt" maxLength='4' /> + </td> + </tr> + <tr> + <th>建议高度<font color='red'>*</font>:</th> + <td> + <input type='text' id='positionHeight' name="positionHeight" value='{$data['positionHeight']}' class='ipt' maxLength='4'/> + </td> + </tr> + <tr> + <th>排序号<font color='red'> </font>:</th> + <td> + <input type='text' id='apSort' name="apSort" value='{$data['apSort']}' class='ipt' maxLength='10'/> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="positionId" class="ipt" value="{$data['positionId']+0}" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" onclick="javascript:history.go(-1)" class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){editInit()}); +</script> +{/block} + diff --git a/hyhproject/admin/view/adpositions/list.html b/hyhproject/admin/view/adpositions/list.html new file mode 100755 index 0000000..565c5a1 --- /dev/null +++ b/hyhproject/admin/view/adpositions/list.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/adpositions/adpositions.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>广告位置类型主要用于确定广告在商城里的位置,调用时把广告代码放入相应位置即可显示广告。</li> + <li>该功能为开发者功能,普通使用者请勿随意修改,以免影响系统使用。</li> + </ul> +</div> +<form autocomplete="off" > +{if WSTGrant('GGWZ_01')} +<div class="wst-toolbar"> + <select name="positionType" id="positionType" class="query"> + <option value="">请选择广告位置类型</option> + {volist name=":WSTDatas('ADS_TYPE')" id='vo'} + <option value="{$vo['dataVal']}">{$vo['dataName']}</option> + {/volist} + </select> + <input type='text' id='key' class="query" placeholder='位置代码'/> + <button type="button" class="btn btn-primary" onclick="javascript:loadQuery()"><i class='fa fa-search'></i>查询</button> + <button class="btn btn-success f-right" type='button' onclick="javascript:location.href='<?=url("admin/Adpositions/toEdit")?>'"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +</form> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/ads/admgrs.js b/hyhproject/admin/view/ads/admgrs.js new file mode 100755 index 0000000..d8c4fd1 --- /dev/null +++ b/hyhproject/admin/view/ads/admgrs.js @@ -0,0 +1,210 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'图标', name:'' ,width:50, align:'center', renderer: function(val,item,rowIndex){ + var adFile = item['adFile'].split(','); + return'<img src="'+WST.conf.IMGURL+'/'+adFile[0]+'" height="28px" width="100"/>'; + }}, + {title:'标题', name:'adName', width: 100}, + {title:'广告位置', name:'positionName' ,width:80}, + {title:'广告网址', name:'adURL' ,width:130}, + {title:'广告开始日期', name:'adStartDate' ,width:30}, + {title:'广告结束日期', name:'adEndDate' ,width:30}, + + {title:'点击数', name:'adClickNum' ,width:15}, + {title:'排序号', name:'adSort' ,width:15, renderer: function(val,item,rowIndex){ + return '<span style="color:blue;cursor:pointer;" ondblclick="changeSort(this,'+item["adId"]+');">'+val+'</span>'; + }}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.GGGL_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+item['adId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.GGGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['adId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/ads/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-155}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function toEdit(id){ + location.href = WST.U('admin/ads/toedit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function loadQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +var oldSort; +function changeSort(t,id){ + $(t).attr('ondblclick'," "); +var html = "<input type='text' id='sort-"+id+"' style='width:30px;padding:2px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); +} +function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/ads/changeSort'),{id:id,adSort:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); +} + + + +//查询 +function adsQuery(){ + var query = WST.getParams('.query'); + grid.set('url',WST.U('admin/ads/pageQuery',query)); +} + +function editInit(){ + var laydate = layui.laydate; + form = layui.form; + laydate.render({ + elem: '#adStartDate' + }); + laydate.render({ + elem: '#adEndDate' + }); + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'adspic'}, + compress:false,//默认不对图片进行压缩 + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var html = '<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" />'; + $('#preview').html(html); + // 图片路径 + $('#adFile').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + + /* 表单验证 */ + $('#adsForm').validator({ + fields: { + adPositionId: { + rule:"required", + msg:{required:"请选择广告位置"}, + tip:"请选择广告位置", + ok:"验证通过", + }, + adName: { + rule:"required;", + msg:{required:"广告标题不能为空"}, + tip:"请输入广告标题", + ok:"验证通过", + }, + adFile: { + rule:"required;", + msg:{required:"请上传广告图片"}, + tip:"请上传广告图片", + ok:"", + }, + adStartDate: { + rule:"required;match(lt, adEndDate, date)", + msg:{required:"请选择广告开始时间",match:"必须小于广告结束时间"}, + ok:"验证通过", + }, + adEndDate: { + rule:"required;match(gt, adStartDate, date)", + msg:{required:"请选择广告结束时间",match:"必须大于广告开始时间"}, + ok:"验证通过", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/'+((params.adId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Ads/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +var positionInfo; +/*获取地址*/ +function addPosition(pType, val, getSize) +{ + $.post(WST.U('admin/Adpositions/getPositon'),{'positionType':pType},function(data,textStatus){ + positionInfo = data; + var html='<option value="">请选择</option>'; + $(data).each(function(k,v){ + var selected; + if(v.positionId==val){ + selected = 'selected="selected"'; + getPhotoSize(v.positionId); + } + html +='<option '+selected+' value="'+v.positionId+'">'+v.positionName+'</option>'; + }); + $('#adPositionId').html(html); + layui.form.render('select'); + }) +} +/*获取图片尺寸 以及设置图片显示方式*/ +function getPhotoSize(pType) +{ + $(positionInfo).each(function(k,v){ + if(v.positionId==pType){ + $('#img_size').html(v.positionWidth+'x'+v.positionHeight); + if(v.positionWidth>v.positionHeight){ + $('.ads-h-list').removeClass('ads-h-list').addClass('ads-w-list'); + } + } + }); + +} \ No newline at end of file diff --git a/hyhproject/admin/view/ads/ads.js b/hyhproject/admin/view/ads/ads.js new file mode 100755 index 0000000..067abd9 --- /dev/null +++ b/hyhproject/admin/view/ads/ads.js @@ -0,0 +1,189 @@ +var grid; +function initGrid(){ + grid = $("#maingrid").ligerGrid({ + url:WST.U('admin/Ads/pageQuery'), + pageSize:WST.pageSize, + pageSizeOptions:WST.pageSizeOptions, + height:'99%', + width:'100%', + minColToggle:6, + rownumbers:true, + columns: [ + { display: '标题', name: 'adName', isSort: false}, + { display: '广告位置', name: 'adPositionId', isSort: false,render:function(rowdata, rowindex, value){ + return rowdata['positionName']; + }}, + { display: '广告网址', name: 'adURL', isSort: false}, + { display: '广告开始日期', name: 'adStartDate', isSort: false}, + { display: '广告结束日期', name: 'adEndDate', isSort: false}, + { display: '图标', name: 'adFile', height: '300', isSort: false,render:function(rowdata, rowindex, value){ + var adFile = rowdata['adFile'].split(','); + return'<img src="'+WST.conf.IMGURL+'/'+adFile[0]+'" height="28px" />'; + }}, + { display: '点击数', name: 'adClickNum', isSort: false}, + { display: '排序号', name: 'adSort', isSort: false,render:function(rowdata, rowindex, value){ + return '<span style="cursor:pointer;" ondblclick="changeSort(this,'+rowdata["adId"]+');">'+value+'</span>'; + }}, + { display: '操作', name: 'op',isSort: false,render: function (rowdata, rowindex, value){ + var h = ""; + if(WST.GRANT.GGGL_02)h += "<a href='"+WST.U('admin/Ads/toEdit','id='+rowdata['adId'])+"'>修改</a> "; + if(WST.GRANT.GGGL_03)h += "<a href='javascript:toDel(" + rowdata['adId'] + ")'>删除</a> "; + return h; + }} + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +var oldSort; +function changeSort(t,id){ + $(t).attr('ondblclick'," "); +var html = "<input type='text' id='sort-"+id+"' style='width:30px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); +} +function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/ads/changeSort'),{id:id,adSort:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); +} + + + +//查询 +function adsQuery(){ + var query = WST.getParams('.query'); + grid.set('url',WST.U('admin/ads/pageQuery',query)); +} + +function editInit(){ + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'adspic'}, + compress:false,//默认不对图片进行压缩 + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var html = '<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" />'; + $('#preview').html(html); + // 图片路径 + $('#adFile').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + + /* 表单验证 */ + $('#adsForm').validator({ + fields: { + adPositionId: { + rule:"required", + msg:{required:"请选择广告位置"}, + tip:"请选择广告位置", + ok:"验证通过", + }, + adName: { + rule:"required;", + msg:{required:"广告标题不能为空"}, + tip:"请输入广告标题", + ok:"验证通过", + }, + adFile: { + rule:"required;", + msg:{required:"请上传广告图片"}, + tip:"请上传广告图片", + ok:"", + }, + adStartDate: { + rule:"required;match(lt, adEndDate, date)", + msg:{required:"请选择广告开始时间",match:"必须小于广告结束时间"}, + ok:"验证通过", + }, + adEndDate: { + rule:"required;match(gt, adStartDate, date)", + msg:{required:"请选择广告结束时间",match:"必须大于广告开始时间"}, + ok:"验证通过", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Ads/'+((params.adId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Ads/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +var positionInfo; +/*获取地址*/ +function addPosition(pType, val, getSize) +{ + $.post(WST.U('admin/Adpositions/getPositon'),{'positionType':pType},function(data,textStatus){ + positionInfo = data; + var html='<option value="">请选择</option>'; + $(data).each(function(k,v){ + var selected; + if(v.positionId==val){ + selected = 'selected="selected"'; + getPhotoSize(v.positionId); + } + html +='<option '+selected+' value="'+v.positionId+'">'+v.positionName+'</option>'; + }); + $('#adPositionId').html(html); + }) +} +/*获取图片尺寸 以及设置图片显示方式*/ +function getPhotoSize(pType) +{ + $(positionInfo).each(function(k,v){ + if(v.positionId==pType){ + $('#img_size').html(v.positionWidth+'x'+v.positionHeight); + if(v.positionWidth>v.positionHeight){ + $('.ads-h-list').removeClass('ads-h-list').addClass('ads-w-list'); + } + } + }); + +} \ No newline at end of file diff --git a/hyhproject/admin/view/ads/edit.html b/hyhproject/admin/view/ads/edit.html new file mode 100755 index 0000000..44b4c3a --- /dev/null +++ b/hyhproject/admin/view/ads/edit.html @@ -0,0 +1,117 @@ +{extend name="base" /} +{block name="css"} +<style> +#preview img{max-width: 600px;max-height:150px;} +</style> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/ads/admgrs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="adsForm"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>位置类型<font color='red'>*</font>:</th> + <td> + <select id="positionType" name="positionType" class='ipt' maxLength='20' onchange='javascript:addPosition(this.value);'> + <option value=''>请选择</option> + {volist name=":WSTDatas('ADS_TYPE')" id='vo'} + <option {if $data['positionType'] == $vo['dataVal']}selected{/if} value="{$vo['dataVal']}">{$vo['dataName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>广告位置<font color='red'>*</font>:</th> + <td> + <select id="adPositionId" name="adPositionId" class='ipt' maxLength='20' onchange='javascript:getPhotoSize(this.value);'> + <option value="">-请选择-</option> + </select> + </td> + </tr> + <tr> + <!--添加链接类型--> + <th width='150'>链接类型<font color='red'>*</font>:</th> + <td> + <select id="targetType" name="targetType" class='ipt' maxLength='20'> + <option {if $data['targetType'] == 1}selected{/if} value="1">商品</option> + <option {if $data['targetType'] == 2}selected{/if} value="2">店铺</option> + <option {if $data['targetType'] == 3}selected{/if} value="3">活动</option> + </select> + </td> + </tr> + <!--添加链接类型结束--> + <tr> + <tr> + <th>广告标题<font color='red'>*</font>:</th> + <td><input type='text' id='adName' name="adName" value='{$data['adName']}' class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th>广告图片<font color='red'>*</font>:</th> + <td><div id='adFilePicker'>上传广告图</div><span id='uploadMsg'></span> + <div> + 图片大小:<span id="img_size">300x300</span>(px),格式为 gif, jpg, jpeg, png + </div> + </td> + + </tr> + <tr> + <th>预览图<font color='red'> </font>:</th> + <td> + <div id="preview" style="min-height:30px;"> + {if ($data['adFile']!='')} + <img src="__IMGURL__/{$data['adFile']}"> + {/if} + </div> + <input type="hidden" name="adFile" id="adFile" class="ipt" value="{$data['adFile']}" /> + </td> + + + </tr> + <tr> + <th>广告网址<font color='red'> </font>:</th> + <td> + <input type="text" id="adURL" class="ipt" maxLength="200" value='{$data['adURL']}' /> + </td> + </tr> + <tr> + <th >广告开始时间<font color='red'>*</font>:</th> + <td> + <input type="text" style="margin:0px;vertical-align:baseline;" id="adStartDate" name="adStartDate" class="laydate-icon ipt" maxLength="20" value='{$data['adStartDate']}' /> + </td> + </tr> + <tr> + <th>广告结束时间<font color='red'>*</font>:</th> + <td> + <input type="text" style="margin:0px;vertical-align:baseline;" id="adEndDate" name="adEndDate" class="laydate-icon ipt" maxLength="20" value='{$data['adEndDate']}' /> + </td> + </tr> + <tr> + <th>广告排序号:</th> + <td> + <input type="text" id="adSort" class="ipt" maxLength="20" value='{$data['adSort']}' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="adId" class="ipt" value="{$data['adId']+0}" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ + +editInit(); +//初始化位置类型 +addPosition("{$data['positionType']}","{$data['adPositionId']}"); +}); + +</script> +{/block} + diff --git a/hyhproject/admin/view/ads/list.html b/hyhproject/admin/view/ads/list.html new file mode 100755 index 0000000..c844ce3 --- /dev/null +++ b/hyhproject/admin/view/ads/list.html @@ -0,0 +1,42 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/ads/admgrs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>广告位置类型主要用于确定广告在商城里的位置,调用时把广告代码放入相应位置即可显示广告</li> + </ul> +</div> +<form autocomplete="off" > +<div class="wst-toolbar"> + <select name="positionType" id="positionType" class="query" onchange='javascript:addPosition(this.value);'> + <option value="">请选择广告位置类型</option> + {volist name=":WSTDatas('ADS_TYPE')" id='vo'} + <option value="{$vo['dataVal']}">{$vo['dataName']}</option> + {/volist} + </select> + <select name="adPositionId" id="adPositionId" class="query" > + <option value="">请选择</option> + </select> + <button class="btn btn-primary" type='button' onclick="javascript:loadQuery()"><i class='fa fa-search'></i>查询</button> + {if WSTGrant('GGGL_01')} + <button class="btn btn-success f-right btn-fixtop" type='button' onclick="javascript:location.href='<?=url("admin/ads/toEdit")?>'"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +</form> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/areas/areas.js b/hyhproject/admin/view/areas/areas.js new file mode 100755 index 0000000..bcdde48 --- /dev/null +++ b/hyhproject/admin/view/areas/areas.js @@ -0,0 +1,149 @@ +var mmg; +function initGrid(){ + var parentId=$('#h_areaId').val(); + var h = WST.pageHeight(); + var cols = [ + {title:'地区名称', name:'areaName', width: 300}, + {title:'是否显示', name:'isShow', width: 30,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['isShow']==1)?"checked":"")+' name="isShow2" lay-skin="switch" lay-filter="isShow2" data="'+item['areaId']+'" lay-text="显示|隐藏">'; + + }}, + {title:'排序字母', name:'areaKey', width: 30}, + {title:'排序号', name:'areaSort', width: 30}, + {title:'操作', name:'' ,width:140, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' onclick='javascript:toView("+item['areaId']+")'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.DQGL_02)h += "<a class='btn btn-blue' onclick='javascript:toEdit("+item['areaId']+","+item["parentId"]+")'><i class='fa fa-pencil'></i>修改</a>"; + if(WST.GRANT.DQGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['areaId'] + ")'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/areas/pageQuery','parentId='+parentId), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render('','gridForm'); + layui.form.on('switch(isShow2)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(0,id); + }else{ + toggleIsShow(1,id); + } + }); + }) +} + +function toggleIsShow(t,v){ + if(!WST.GRANT.DQGL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/areas/editiIsShow'),{id:v,isShow:t},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toReturn(){ + location.href=WST.U('admin/areas/index','parentId='+$('#h_parentId').val()); +} + +function letterOnblur(obj){ + if($.trim(obj.value)=='')return; + if($('#areaKey').val()!=='')return; + var loading = WST.msg('正在生成排序字母,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/areas/letterObtain'),{code:obj.value},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status == 1){ + $('#areaKey').val(json.msg); + } + }); +} + +function toEdit(id,pid){ + $('#areaForm')[0].reset(); + if(id>0){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/areas/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json){ + WST.setValues(json); + layui.form.render(); + editsBox(id); + } + }); + }else{ + WST.setValues({parentId:pid,areaId:0}); + layui.form.render(); + editsBox(id); + } +} +function toView(id){ + location.href = WST.U('admin/areas/index','parentId='+id); +} +function editsBox(id){ + var box = WST.open({title:(id>0)?'修改地区':"新增地区",type:1,content:$('#areasBox'),area: ['460px', '260px'],btn:['确定','取消'], + end:function(){$('#areasBox').hide();},yes:function(){ + $('#areaForm').submit(); + }}); + $('#areaForm').validator({ + fields: { + areaName: { + tip: "请输入地区名称", + rule: '地区名称:required;length[~10];' + }, + areaKey: { + tip: "请输入排序字母", + rule: '排序字母:required;length[~1];' + }, + areaSort: { + tip: "请输入排序号", + rule: '排序号:required;length[~8];' + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/areas/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#areasBox').hide(); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该地区吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/areas/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/areas/list.html b/hyhproject/admin/view/areas/list.html new file mode 100755 index 0000000..c0d7130 --- /dev/null +++ b/hyhproject/admin/view/areas/list.html @@ -0,0 +1,55 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/areas/areas.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initGrid();}) +</script> +{/block} +{block name="main"} +<input type='hidden' id='h_areaId' value='{$pArea["areaId"]}'/> +<input type='hidden' id='h_parentId' value='{$pArea["parentId"]}'/> +<div class="wst-toolbar"> + {if condition="($pArea['areaId'] != 0)"} + 上级地区:{$pArea['areaName']} + <button class="btn f-right" onclick='javascript:toReturn(0)'><i class="fa fa-angle-double-left"></i>返回</button> + {/if} + {if WSTGrant('DQGL_01')} + <button class="btn btn-success f-right btn-mright" onclick='javascript:toEdit(0,{$pArea["areaId"]})'><i class='fa fa-plus'></i>新增</button> + {/if} + <div style='clear:both'></div> +</div> +<form lay-filter='gridForm' class='layui-form wst-grid'> +<div id="mmg" class="mmg"></div> +</form> +<div id="pg" style="text-align: right;"></div> +<div id='areasBox' style='display:none'> + <form id='areaForm' autocomplete="off" class='layui-form'> + <input type='hidden' class='ipt' id='areaId' /> + <input type='hidden' class='ipt' id='parentId' /> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>地区名称<font color='red'>*</font>:</th> + <td><input type='text' id='areaName' name="areaName" class='ipt' maxLength='20' style='width:200px;' onblur='javascript:letterOnblur(this)'/></td> + </tr> + <tr> + <th width='100'>是否显示<font color='red'>*</font>:</th> + <td height='24'> + <input type="checkbox" id='isShow' name='isShow' value="1" lay-skin="switch" lay-filter="switchTest" class="ipt" lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th width='100'>排序字母<font color='red'>*</font>:</th> + <td><input type='text' id='areaKey' name='areaKey' class='ipt' style='width:60px;' maxLength='1'/></td> + </tr> + <tr> + <th width='100'>排序号<font color='red'>*</font>:</th> + <td><input type='text' id='areaSort' name='areaSort' class='ipt' style='width:60px;' onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" maxLength='10' value='0'/></td> + </tr> + </table> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/articlecats/articlecats.js b/hyhproject/admin/view/articlecats/articlecats.js new file mode 100755 index 0000000..5135c47 --- /dev/null +++ b/hyhproject/admin/view/articlecats/articlecats.js @@ -0,0 +1,149 @@ +var grid,oldData = {}; +function initGrid(){ + grid = $('#maingrid').WSTGridTree({ + url:WST.U('admin/articlecats/pageQuery'), + rownumbers:true, + columns: [ + { display: '分类名称', name: 'catName', id:'catId', align: 'left',isSort: false,render: function (item) + { + oldData[item.catId] = item.catName; + return '<input type="text" size="40" value="'+item.catName+'" onblur="javascript:editName('+item.catId+',this)"/>'; + }}, + { display: '分类类型', width: 100, name: 'catType',isSort: false, + render: function (item) + { + if (parseInt(item.catType) == 1) return '<span>系统菜单</span>'; + return '<span>普通类型</span>'; + } + }, + { display: '是否显示', width: 80, name: 'isShow',isSort: false, + render: function (item) + { + return '<input type="checkbox" '+((item.isShow==1)?"checked":"")+' class="ipt" lay-skin="switch" lay-filter="isShow" data="'+item.catId+'" lay-text="显示|隐藏">'; + } + }, + { display: '排序号', name: 'catSort',width: 60,isSort: false}, + { display: '操作', name: 'op',width: 250,isSort: false, + render: function (rowdata,e){ + var h = ""; + if(WST.GRANT.WZFL_01)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["catId"]+",0)'><i class='fa fa-plus'></i>新增子分类</a> "; + if(WST.GRANT.WZFL_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["parentId"]+","+rowdata["catId"]+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.WZFL_03 && rowdata["catType"]==0)h += "<a class='btn btn-red' href='javascript:toDel("+rowdata["parentId"]+","+rowdata["catId"]+","+rowdata["catType"]+")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ], + callback:function(){ + layui.form.render(); + } + }); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){}}); +} +function toggleIsShow(id,isShow){ + if(!WST.GRANT.WZFL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articlecats/editiIsShow'),{id:id,isShow:isShow},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(pid,id){ + $('#articlecatForm')[0].reset(); + if(id>0){ + $.post(WST.U('admin/articlecats/get'),{id:id},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json){ + WST.setValues(json); + layui.form.render(); + editsBox(id); + } + }); + }else{ + WST.setValues({parentId:pid,catName:'',isShow:1,catSort:0}); + layui.form.render(); + editsBox(id); + } +} + +function editsBox(id){ + var title =(id>0)?"修改文章分类":"新增文章分类"; + var box = WST.open({title:title,type:1,content:$('#articlecatBox'),area: ['465px', '250px'],btn:['确定','取消'], + end:function(){$('#articlecatBox').hide();},yes:function(){ + $('#articlecatForm').submit(); + }}); + $('#articlecatForm').validator({ + fields: { + catName: { + tip: "请输入分类名称", + rule: '分类名称:required;length[~10];' + }, + catSort: { + tip: "请输入排序号", + rule: '排序号:required;length[~8];' + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articlecats/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#articlecatBox').hide(); + layer.close(box); + grid.reload(params.parentId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function toDel(pid,id,type){ + var box = WST.confirm({content:"您确定要删除该分类以及其下的文章吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articlecats/del'),{id:id,type:type},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + grid.reload(pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function editName(id,obj){ + if($.trim(obj.value)=='' || $.trim(obj.value)==oldData[id]){ + obj.value = oldData[id]; + return; + } + $.post(WST.U('admin/articlecats/editName'),{id:id,catName:obj.value},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + oldData[id] = $.trim(obj.value); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/articlecats/list.html b/hyhproject/admin/view/articlecats/list.html new file mode 100755 index 0000000..8005fba --- /dev/null +++ b/hyhproject/admin/view/articlecats/list.html @@ -0,0 +1,51 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/wstgridtree.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/articlecats/articlecats.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initGrid();}) +</script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于文章分类的管理。分类可分为“普通菜单”和“系统系统”。</li> + <li>“系统菜单”一般在商城前台有进行调用,非开发者请勿直接删除“系统菜单”,以免造成数据丢失。</li> + </ul> +</div> +<style>.mmGrid{border-bottom:0px;}</style> +{if WSTGrant('WZFL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style='clear:both'></div> +</div> +{/if} +<div class='wst-grid'> +<div class='mmGrid layui-form' id="maingrid"></div> +</div> +<div id='articlecatBox' style='display:none' class="layui-form"> + <form id='articlecatForm' autocomplete="off"> + <input type='hidden' id='parentId' name="parentId" class='ipt' /> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>分类名称<font color='red'>*</font>:</th> + <td><input type='text' id='catName' name="catName" class='ipt' maxLength='20' style='width:200px;'/></td> + </tr> + <tr> + <th width='100'>是否显示<font color='red'>*</font>:</th> + <td height='24'> + <input type="checkbox" id="isShow" name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow1" lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th width='100'>排序号<font color='red'>*</font>:</th> + <td><input type='text' id='catSort' name='catSort' class='ipt' style='width:60px;' onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" maxLength='10' value='0'/></td> + </tr> + </table> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/articles/articles.js b/hyhproject/admin/view/articles/articles.js new file mode 100755 index 0000000..45919e1 --- /dev/null +++ b/hyhproject/admin/view/articles/articles.js @@ -0,0 +1,193 @@ +var mmg,combo; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'文章ID', name:'articleId' ,width:30,sortable:true}, + {title:'标题', name:'articleTitle' ,width:200,sortable:true}, + {title:'分类', name:'catName' ,width:100,sortable:true}, + {title:'是否显示', name:'isShow' ,width:50,sortable:true, renderer: function(val,item,rowIndex){ + return '<form autocomplete="off" class="layui-form" lay-filter="gridForm"><input type="checkbox" id="isShow" name="isShow" '+((item['isShow']==1)?"checked":"")+' lay-skin="switch" value="1" lay-filter="isShow" lay-text="显示|隐藏" data="'+item['articleId']+'"></form>'; + }}, + {title:'最后编辑者', name:'staffName' ,width:50,sortable:true}, + {title:'创建时间', name:'createTime' ,width:120,sortable:true}, + {title:'操作', name:'' ,width:100, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.WZGL_02)h += "<a class='btn btn-blue' onclick='javascript:toEdit("+item['articleId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.WZGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['articleId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST',checkCol:true,multiSelect:true, + url: WST.U('admin/articles/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render('','gridForm'); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(1,id); + }else{ + toggleIsShow(0,id); + } + }); + }) +} + +function initCombo(v){ + var setting = { + check: { + enable: true, + chkStyle: "radio", + radioType: "all" + }, + view: { + dblClickExpand: false + }, + async: { + enable: true, + url:WST.U('admin/articlecats/listQuery2','hasRoot='+v), + autoParam:["id", "name=n", "level=lv"] + }, + callback: { + onClick: onClick, + onCheck: onCheck + } + }; + $.fn.zTree.init($("#dropDownTree"), setting); +} +function onClick(e, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj("dropDownTree"); + zTree.checkNode(treeNode, !treeNode.checked, null, true); + return false; +} + +function onCheck(e, treeId, treeNode) { + var zTree = $.fn.zTree.getZTreeObj("dropDownTree"); + var nodes = zTree.getCheckedNodes(true); + var v = [],ids = []; + for (var i=0, l=nodes.length; i<l; i++) { + v .push(nodes[i].name); + ids.push(nodes[i].id); + } + + $("#catSel").attr("value", v.join(',')); + $('#catId').val(ids.join(',')); + hideMenu(); +} +function showMenu(){ + var cityObj = $("#catSel"); + var cityOffset = $("#catSel").offset(); + $("#ztreeMenuContent").css({left:cityOffset.left + "px", top:cityOffset.top + cityObj.outerHeight() + "px"}).slideDown("fast"); + $("body").bind("mousedown", onBodyDown); +} +function hideMenu(){ + $("#ztreeMenuContent").fadeOut("fast"); + $("body").unbind("mousedown", onBodyDown); +} +function onBodyDown(event) { + if (!(event.target.id == "menuBtn" || event.target.id == "citySel" || event.target.id == "ztreeMenuContent" || $(event.target).parents("#ztreeMenuContent").length>0)) { + hideMenu(); + } +} +function loadGrid(){ + mmg.load({key:$('#key').val(),catId:$('#catId').val(),page:1}); +} + +function toggleIsShow(t,v){ + if(!WST.GRANT.WZGL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articles/editiIsShow'),{id:v,isShow:t},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toggleIsShow(t,v){ + if(!WST.GRANT.WZGL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articles/editiIsShow'),{id:v,isShow:t},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + location.href=WST.U('admin/articles/toEdit','id='+id); +} + +function toEdits(id){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articles/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + setTimeout(function(){ + location.href=WST.U('admin/articles/index'); + },1000); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该文章吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articles/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function toBatchDel(){ + var rows = mmg.selectedRows(); + if(rows.length==0){ + WST.msg('请选择要删除的文章',{icon:2}); + return; + } + var ids = []; + for(var i=0;i<rows.length;i++){ + ids.push(rows[i]['articleId']); + } + var box = WST.confirm({content:"您确定要删除这些文章吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/articles/delByBatch'),{ids:ids.join(',')},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/articles/edit.html b/hyhproject/admin/view/articles/edit.html new file mode 100755 index 0000000..f6d2421 --- /dev/null +++ b/hyhproject/admin/view/articles/edit.html @@ -0,0 +1,166 @@ +{extend name="base" /} +{block name="css"} +<link href="__ADMIN__/js/ztree/css/zTreeStyle/zTreeStyle.css?v={$v}" rel="stylesheet" type="text/css" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/ztree/jquery.ztree.all-3.5.js?v={$v}"></script> +<script src="__STATIC__/plugins/webuploader/webuploader.js?v={$v}" type="text/javascript" ></script> +<script src="__STATIC__/plugins//kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +<script src="__ADMIN__/articles/articles.js?v={$v}" type="text/javascript"></script> +<script> +$(function () { + initCombo(0); + {if condition="$object['articleId'] !=0 "} + WST.setValues({$object}); + {/if} + $('#articleForm').validator({ + fields: { + articleTitle: { + tip: "请输入文章名称", + rule: '文章名称:required;length[~50];' + }, + catIds: { + tip: "请选择文章分类", + rule: "文章分类:required;", + target:"#catIdt" + }, + articleKey: { + tip: "请输入关键字", + rule: '关键字:required;length[~100];' + }, + layoutType: { + tip: "请选择移动端布局样式", + rule: '关键字:required;length[~100];' + }, + articleContent: { + tip: "请输入文章内容", + rule: '文章内容:required;' + } + }, + valid: function(form){ + var articleId = $('#articleId').val(); + toEdits(articleId); + } + }) +}); +</script> +{/block} +{block name="main"} +<input type='hidden' id='articleId' value='{$object["articleId"]}'/> +<form id='articleForm' autocomplete="off"> +<table class='wst-form wst-box-top '> + <tr> + <th width='150'>文章标题<font color='red'>*</font>:</th> + <td><input type="text" id='articleTitle' name='articleTitle' maxLength='50' style='width:300px;' class='ipt'/></td> + </tr> + <tr> + <th width='150' align='right'>分类类型<font color='red'>*</font>:</th> + <td> + <input id="catSel" type="text" readonly onclick="showMenu();" style='width:250px;' value="{$object.catName}"/> + <div id="ztreeMenuContent" class="ztreeMenuContent"> + <ul id="dropDownTree" class="ztree" style="margin-top:0; width:250px; height: 300px;"></ul> + </div> + <input id="catId" class="text ipt" autocomplete="off" type="hidden" value=""/> + </td> + </tr> + <tr> + <th width='150'>是否显示<font color='red'>*</font>:</th> + <td height='24' class="layui-form"> + <input type="checkbox" id="isShow" {if $object['isShow']==1}checked{/if} name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow" lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th width='150'>关键字<font color='red'>*</font>:</th> + <td><input type="text" id='articleKey' name='articleKey' maxLength='120' style='width:600px;' class='ipt'/></td> + </tr> + <tr > + <th>移动端布局样式预览图:</th> + <td class="typeState" style="padding-top: 10px;"> + <li> + <input type='radio' name='TypeStatus' class='ipt' value='1'/> + <label> + <img src="__ADMIN__/img/news_1.png" style="width:150px;height:80px;"> + </label> + </li> + <li> + <input type='radio' name='TypeStatus' class='ipt' value='2' /> + <label> + <img src="__ADMIN__/img/news_2.png" style="width:150px;height:80px;"> + </label> + </li> + <li> + <input type='radio' name='TypeStatus' class='ipt' value='3' /> + <label> + <img src="__ADMIN__/img/news_3.png" style="width:150px;height:80px;"> + </label> + </li> + </td> + </tr> + <tr> + <th>封面图片:</th> + <td> + <div id='coverImgPicker'>请上传封面图片</div><span id='coverImgMsg'></span>图片大小:230x195(px),格式为 gif, jpg, jpeg, png + <input type="hidden" id='coverImg' name="coverImg" class="ipt"/> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:70px;" id="preview">{if ($object['articleId']!=0 && $object['coverImg'])}<img src="__IMGURL__/{$object['coverImg']}" height="152" />{/if}</div></td> + </tr> + <tr> + <th width='150'>文章内容<font color='red'>*</font>:</th> + <td> + <textarea id='articleContent' name='articleContent' class="form-control ipt" style='width:80%;height:400px'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>保&nbsp;存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> +</table> + </form> + <script> +$(function(){ + //文件上传 + WST.upload({ + pick:'#coverImgPicker', + formData: {dir:'articles',isThumb:1}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#coverImgMsg').empty().hide(); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="152" />'); + $('#coverImg').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#coverImgMsg').show().html('已上传'+rate+"%"); + } + }); + //编辑器 + KindEditor.ready(function(K) { + editor1 = K.create('textarea[name="articleContent"]', { + height:'350px', + uploadJson : WST.conf.ROOT+'/admin/articles/editorUpload', + allowFileManager : false, + allowImageUpload : true, + allowMediaUpload : false, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','media','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } + }); + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/articles/list.html b/hyhproject/admin/view/articles/list.html new file mode 100755 index 0000000..155875f --- /dev/null +++ b/hyhproject/admin/view/articles/list.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="css"} +<link href="__ADMIN__/js/ztree/css/zTreeStyle/zTreeStyle.css?v={$v}" rel="stylesheet" type="text/css" /> +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/ztree/jquery.ztree.all-3.5.js?v={$v}"></script> +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/articles/articles.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initCombo(1);initGrid();}) +</script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <input id="catSel" type="text" readonly onclick="showMenu();" style='width:250px;' /> + <div id="ztreeMenuContent" class="ztreeMenuContent"> + <ul id="dropDownTree" class="ztree" style="margin-top:0; width:250px; height: 300px;"></ul> + </div> + <input id="catId" class="text ipt" autocomplete="off" type="hidden" value=""/> + <input type='text' id='key' placeholder='文章标题'/> + <button class="btn btn-primary" onclick='javascript:loadGrid()'><i class='fa fa-search'></i>查询</button> + {if WSTGrant('WZGL_03')} + <button class="btn btn-danger f-right btn-fixtop" onclick='javascript:toBatchDel()' style='margin-left:10px;'><i class='fa fa-trash'></i>批量删除</button> + {/if} + {if WSTGrant('WZGL_01')} + <button class="btn btn-success f-right btn-fixtop" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + {/if} + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/attributes/attributes.js b/hyhproject/admin/view/attributes/attributes.js new file mode 100755 index 0000000..947b366 --- /dev/null +++ b/hyhproject/admin/view/attributes/attributes.js @@ -0,0 +1,134 @@ +var mmg; +$(function(){ + var h = WST.pageHeight(); + var cols = [ + {title:'属性名称', name:'attrName', width: 10}, + {title:'所属商品分类', name:'goodsCatNames', width: 160}, + {title:'属性类型', name:'attrType', width: 5,renderer: function(val,item,rowIndex){ + return (val==1)?'多选项':(val==2?'下拉框':'输入框'); + }}, + {title:'属性选项', name:'attrVal', width: 260}, + {title:'是否显示', name:'attrVal', width: 20,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['isShow']==1)?"checked":"")+' id="isShow1" name="isShow1" value="1" class="ipt" lay-skin="switch" lay-filter="isShow1" data="'+item['attrId']+'" lay-text="显示|隐藏">' + }}, + {title:'排序号', name:'attrSort', width: 5}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.SPSX_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+ item['attrId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.SPSX_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['attrId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/attributes/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(data){ + layui.form.render(); + layui.form.on('switch(isShow1)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); + }) +}); + +//------------------属性类型---------------// +function toEdit(attrId){ + $("select[id^='bcat_0_']").remove(); + $('#attrForm').get(0).reset(); + $.post(WST.U('admin/attributes/get'),{attrId:attrId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + layui.form.render(); + if(json.goodsCatId>0){ + var goodsCatPath = json.goodsCatPath.split("_"); + $('#bcat_0').val(goodsCatPath[0]); + var opts = {id:'bcat_0',val:goodsCatPath[0],childIds:goodsCatPath,className:'goodsCats'} + WST.ITSetGoodsCats(opts); + } + var title =(attrId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#attrBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#attrBox').hide();},yes:function(){ + $('#attrForm').submit(); + }}); + $('#attrForm').validator({ + rules: { + attrType: function() { + return ($('#attrType').val()!='0'); + } + }, + fields: { + 'attrName': {rule:"required",msg:{required:'请输入属性名称'}}, + 'attrVal': 'required(attrType)' + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + params.goodsCatId = WST.ITGetGoodsCatVal('goodsCats'); + $.post(WST.U('admin/attributes/'+((params.attrId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#attrBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} +function loadGrid(){ + var keyName = $("#keyName").val(); + var goodsCatPath = WST.ITGetAllGoodsCatVals('cat_0','pgoodsCats'); + mmg.load({"page":1,"keyName":keyName,"goodsCatPath":goodsCatPath.join('_')}); +} + +function toDel(attrId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/attributes/del'),{attrId:attrId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function toggleIsShow( attrId, isShow){ + $.post(WST.U('admin/attributes/setToggle'), {'attrId':attrId, 'isShow':isShow}, function(data, textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} + +function changeArrType(v){ + if(v>0){ + $('#attrValTr').show(); + }else{ + $('#attrValTr').hide(); + } +} diff --git a/hyhproject/admin/view/attributes/list.html b/hyhproject/admin/view/attributes/list.html new file mode 100755 index 0000000..29ad612 --- /dev/null +++ b/hyhproject/admin/view/attributes/list.html @@ -0,0 +1,87 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/attributes/attributes.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div class="f-left"> + <div id="pcat_0_box" class="f-left"> + <select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </div> + <input type="text" id="keyName" placeholder="请输入属性名称"/> + <button class="btn btn-primary" onclick="loadGrid(0)"><i class='fa fa-search'></i>查询</button> + </div> + + {if WSTGrant('SPSX_01')} + <button class="btn btn-success f-right" onclick="javascript:toEdit(0);"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='attrBox' style='display:none'> + <form id="attrForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + <input type="hidden" id="attrId" value="" class="ipt" /> + 所属商品分类<font color='red'>*</font>:</th> + <td id="bcat_0_box"> + <select id="bcat_0" class='ipt goodsCats' level="0" onchange="WST.ITGoodsCats({id:'bcat_0',val:this.value,isRequire:false,className:'goodsCats'});" data-rule='所属商品分类:required;' data-target="#msg_bcat_0"> + <option value="">-请选择-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <span class='msg-box' id='msg_bcat_0' style='color:red;'>(至少选择一个商品分类)</span> + </td> + </tr> + <tr> + <th>属性名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="attrName" name="attrName" class="ipt" maxLength='20'/> + </td> + </tr> + <tr> + <th>属性类型<font color='red'>*</font>:</th> + <td> + <select id='attrType' class='ipt' onchange='changeArrType(this.value)'> + <option value='0'>输入框</option> + <option value='1'>多选项</option> + <option value='2'>下拉项</option> + </select> + </td> + </tr> + <tr id='attrValTr' style='display:none'> + <th>属性选项<font color='red'>*</font>:</th> + <td> + <input type="text" id="attrVal" name="attrVal" class="ipt" style='width:70%' placeholder="每个属性选项以,号分隔" data-msg='请输入属性选项'/> + </td> + </tr> + <tr> + <th>是否显示<font color='red'> </font>:</th> + <td class='layui-form'> + <input type="checkbox" id="isShow" name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow" lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="attrSort" name="attrSort" class="ipt" maxLength='20'/> + </td> + </tr> + </table> + </form> +</div> +{/block} diff --git a/hyhproject/admin/view/banks/banks.js b/hyhproject/admin/view/banks/banks.js new file mode 100755 index 0000000..52dba5e --- /dev/null +++ b/hyhproject/admin/view/banks/banks.js @@ -0,0 +1,90 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'银行名称', name:'bankName', width: 100}, + {title:'操作', name:'' ,width:70, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.YHGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit("+item['bankId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.YHGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['bankId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/banks/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/banks/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/banks/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.bankId){ + WST.setValues(json); + toEdit(json.bankId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#bankBox'),area: ['450px', '160px'], + btn:['确定','取消'],end:function(){$('#bankBox').hide();},yes:function(){ + $('#bankForm').submit(); + }}); + $('#bankForm').validator({ + fields: { + bankName: { + rule:"required;", + msg:{required:"银行名称不能为空"}, + tip:"请输入银行名称", + ok:"", + }, + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.bankId = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/banks/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#bankBox').hide(); + $('#bankForm')[0].reset(); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + +} \ No newline at end of file diff --git a/hyhproject/admin/view/banks/list.html b/hyhproject/admin/view/banks/list.html new file mode 100755 index 0000000..baf7b12 --- /dev/null +++ b/hyhproject/admin/view/banks/list.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/banks/banks.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +{if WSTGrant('YHGL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +{/if} +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='bankBox' style='display:none'> + <form id='bankForm' autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>银行名称<font color='red'>*</font>:</th> + <td><input type='text' id='bankName' name="bankName" class='ipt' maxLength='20'/></td> + </tr> + </table> + </form> + </div> +<script> + $(function(){initGrid()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/base.html b/hyhproject/admin/view/base.html new file mode 100755 index 0000000..9ee1d13 --- /dev/null +++ b/hyhproject/admin/view/base.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"/> +<title>后台管理中心 - {:WSTConf('CONF.mallName')}</title> +<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> +<link rel="stylesheet" href="__ADMIN__/js/bootstrap/css/bootstrap.min.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/layui/css/layui.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/font-awesome/css/font-awesome.min.css" type="text/css" /> +<script src="__ADMIN__/js/jquery.min.js"></script> +{block name="css"}{/block} +<link href="__ADMIN__/css/common.css?v={$v}" rel="stylesheet" type="text/css" /> +<script> +window.conf = {"DOMAIN":"{:str_replace('index.php','',$Request.root.true)}","ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}",'GRANT':'{:implode(",",session("WST_STAFF.privileges"))}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}","ROUTES":'{:WSTRoute()}'} +</script> +<script language="javascript" type="text/javascript" src="__STATIC__/js/common.js"></script> +</head> +<body class="hold-transition skin-blue sidebar-mini"> +<div id="j-loader"><img src="__ADMIN__/img/ajax-loader.gif"/></div> +{block name="main"}{/block} +<script src="__ADMIN__/js/bootstrap/js/bootstrap.min.js"></script> +<script language="javascript" type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script language="javascript" type="text/javascript" src="__ADMIN__/js/common.js"></script> +{block name="js"}{/block} +{:hook('initCronHook')} +</body> +</html> \ No newline at end of file diff --git a/hyhproject/admin/view/brands/brands.js b/hyhproject/admin/view/brands/brands.js new file mode 100755 index 0000000..a2f8ccc --- /dev/null +++ b/hyhproject/admin/view/brands/brands.js @@ -0,0 +1,88 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'品牌名称', name:'brandName', width: 100}, + {title:'品牌介绍', name:'brandDesc', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['brandDesc']+"</p></span>"; + }}, + {title:'商铺', name:'shopName', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['shopName']+"</p></span>"; + }}, + {title:'主营分类', name:'catName', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['catName']+"</p></span>"; + }}, + {title:'品牌图标', name:'img', width: 100, renderer: function(val,item,rowIndex){ + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:40px;width:40px;' src='"+WST.conf.IMGURL+"/"+item['brandImg'] + +"'><span class='imged' style='left:45px;' ><img style='height:150px;width:150px;' src='"+WST.conf.IMGURL+"/"+item['brandImg']+"'></span></span>"; + }}, + {title:'操作', name:'' ,width:70, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.PPGL_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+item["brandId"]+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.PPGL_03)h += "<a class='btn btn-red' href='javascript:toDel("+item["brandId"]+")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/brands/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +function loadGrid(){ + mmg.load({page:1,key:$('#key').val(),id:$('#catId').val()}); +} + +function toEdit(id){ + location.href=WST.U('admin/brands/toEdit','id='+id); +} + +function toEdits(id){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/brands/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + setTimeout(function(){ + location.href=WST.U('admin/brands/index'); + },1000); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该品牌吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/brands/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function toolTip(){ + $('body').mousemove(function(e){ + var windowH = $(window).height(); + if(e.pageY >= windowH*0.8){ + var top = windowH*0.233; + $('.imged').css('margin-top',-top); + }else{ + var top = windowH*0.06; + $('.imged').css('margin-top',-top); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/brands/edit.html b/hyhproject/admin/view/brands/edit.html new file mode 100755 index 0000000..e9e6da6 --- /dev/null +++ b/hyhproject/admin/view/brands/edit.html @@ -0,0 +1,142 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<style> +.goodsCat{display:inline-block;width:150px} +</style> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/webuploader/webuploader.js?v={$v}" type="text/javascript" ></script> +<script src="__STATIC__/plugins//kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +<script src="__ADMIN__/brands/brands.js?v={$v}" type="text/javascript"></script> +<script> +$(function () { + {if condition="$object['brandId'] !=0"} + WST.setValues({$object}); + {/if} + $('#brandForm').validator({ + fields: { + brandName: { + tip: "请输入品牌名称", + rule: '品牌名称:required;length[~50];' + }, + shopId: { + tip: "请输入店铺ID", + rule: '品牌名称:required;' + }, + catId: { + tip: "请选择分类", + rule: 'checked(1~);length[~16];' + }, + brandDesc: { + tip: "请输入品牌介绍", + rule: '品牌介绍:required;' + } + }, + valid: function(form){ + var brandId = $('#brandId').val(); + toEdits(brandId); + } + }) +}); +</script> +{/block} +{block name="main"} +<input type='hidden' id='brandId' value='{$object["brandId"]}'/> +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="brandForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>品牌名称<font color='red'>*</font>:</th> + <td><input type="text" id='brandName' name='brandName' maxLength='20' style='width:300px;' class='ipt'/></td> + </tr> + <tr> + <th width='150' align='right'>店铺ID<font color='red'>*</font>:</th> + <td><input type="text" id='shopId' name='shopId' maxLength='20' style='width:300px;' class='ipt'/></td> + </tr> + <tr> + <th width='150' align='right'>所属分类<font color='red'>*</font>:</th> + <td> + {volist name="gcatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' id='catId' name='catId' class="ipt" value='{$vo["catId"]}' + {if condition="$object['brandId'] !=0 "} + {if in_array($vo["catId"],$object['catIds'])==1}checked{/if} + {/if} + >&nbsp;{$vo["catName"]}&nbsp; + </label> + {/volist} + </td> + </tr> + <tr width='150'> + <th align='right'>品牌图标<font color='red'>*</font>:</th> + <td> + <div> + <div id="filePicker" style='margin-left:0px;float:left; width: 100px'>上传图片</div> + <div style='margin-left:5px;float:left'>图片大小:400 x 200 (px),格式为 gif, jpg, jpeg,bmp, png</div> + <input id="brandImg" name="brandImg" class="text ipt" autocomplete="off" type="hidden" value="{$object.brandImg}"/> + <div style="clear:both;"></div> + </div> + </td> + </tr> + <tr > + <th align='right' height='152'>预览图:</th> + <td > + <div id="preview" > + {if $object['brandId']!=0} + <img src="__IMGURL__/{$object['brandImg']}" class="ipt" height='152'/> + {/if} + </div> + </td> + </tr> + <tr> + <th width='150'>品牌介绍<font color='red'>*</font>:</th> + <td> + <textarea id='brandDesc' name='brandDesc' class="form-control ipt" style='width:80%;height:400px'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>保&nbsp;存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> +</table> + </form> + <script> +$(function(){ + //文件上传 + WST.upload({ + pick:'#filePicker', + formData: {dir:'brands',mWidth:500,mHeight:250}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#preview').html('<img src="'+WST.conf.IMGURL+"/"+json.savePath+json.thumb+'" height="200" />'); + $('#brandImg').val(json.savePath+json.name); + } + } + }); + //编辑器 + KindEditor.ready(function(K) { + editor1 = K.create('textarea[name="brandDesc"]', { + height:'350px', + uploadJson : WST.conf.ROOT+'/admin/brands/editorUpload', + allowFileManager : false, + allowImageUpload : true, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } + }); + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/brands/list.html b/hyhproject/admin/view/brands/list.html new file mode 100755 index 0000000..5a6573a --- /dev/null +++ b/hyhproject/admin/view/brands/list.html @@ -0,0 +1,32 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/brands/brands.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initGrid();}) +</script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id='catId'> + <option value='0'>所属商品分类</option> + {volist name="gcatList" id="vo"} + <option value='{$vo['catId']}'>{$vo['catName']}</option> + {/volist} + </select> + <input type='text' id='key' placeholder='品牌名称'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + {if WSTGrant('PPGL_01')} + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + {/if} + + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/carts/carts.html b/hyhproject/admin/view/carts/carts.html new file mode 100755 index 0000000..80cecdd --- /dev/null +++ b/hyhproject/admin/view/carts/carts.html @@ -0,0 +1,28 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/carts/carts.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<div class="wst-toolbar"> + +<input type="text" name="goodsName" placeholder='商品名称' id="goodsName" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +<input type="text" name="loginName" placeholder='用户名称' id="loginName" class='j-ipt'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + <button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExport()'><i class="fa fa-sign-in"></i>导出</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/carts/carts.js b/hyhproject/admin/view/carts/carts.js new file mode 100755 index 0000000..69cc116 --- /dev/null +++ b/hyhproject/admin/view/carts/carts.js @@ -0,0 +1,62 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb+"/thumb80" + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'用户名称', name:'loginName' ,width:60,sortable:true}, + {title:'商品名称', name:'goodsName', width: 120,sortable:true,renderer: function(val,item,rowIndex){ + return "<span><p>"+item['goodsName']+"</p></span>"; + }}, + {title:'购物车数量', name:'cartNum' ,width:20,sortable:true,align:'center', }, + {title:'单品价格', name:'shopPrice' ,width:20,sortable:true,align:'center', renderer: function(val,item,rowIndex){ + return '¥'+item['shopPrice']; + }}, + {title:'总价', name:'totalPrice' ,width:20,sortable:true,align:'center', renderer: function(val,item,rowIndex){ + return '¥'+item['totalPrice']; + }}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + + {title:'所属分类', name:'goodsCatName' ,width:60,renderer:function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatName']+"</p></span>"; + }}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/carts/cartsByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/carts/toExport',params); + }}); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.page = 1; + mmg.load(params); +} diff --git a/hyhproject/admin/view/cashdraws/cashdraws.js b/hyhproject/admin/view/cashdraws/cashdraws.js new file mode 100755 index 0000000..7476892 --- /dev/null +++ b/hyhproject/admin/view/cashdraws/cashdraws.js @@ -0,0 +1,90 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'提现单号', name:'cashNo', width: 100,sortable: true}, + {title:'会员类型', name:'targetType' ,width:60,sortable: true, renderer:function(val,item,rowIndex){ + return (item['targetType']==1)?"【商家】":"【会员】"; + }}, + {title:'会员名称', name:'loginName' ,width:100, renderer:function(val,item,rowIndex){ + if(item['targetType']==1){ + return WST.blank(item['userName'])+"("+item['loginName']+")"; + }else{ + return WST.blank(item['userName'])+"("+item['loginName']+")"; + } + }}, + {title:'提现银行', name:'accTargetName' ,width:60,sortable: true}, + {title:'银行卡号', name:'accNo' ,width:40,sortable: true}, + {title:'持卡人', name:'accUser' ,width:40,sortable: true}, + {title:'提现金额', name:'money' ,width:40,sortable: true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'提现时间', name:'createTime',sortable: true ,width:60}, + {title:'状态', name:'cashSatus' ,width:60,sortable: true, renderer:function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 提现成功</span>":((val==-1)?"<span class='statu-no'><i class='fa fa-ban'></i> 提现失败&nbsp;</span>":"<span class='statu-wait'><i class='fa fa-clock-o'></i> 待处理&nbsp;</span>"); + }}, + {title:'操作', name:'' ,width:120, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toView(" + item['cashId'] + ")'><i class='fa fa-search'></i>查看</a> "; + if(item['cashSatus']==0 && WST.GRANT.TXSQ_04)h += "<a class='btn btn-green' href='javascript:toEdit(" + item['cashId'] + ")'><i class='fa fa-pencil'></i>处理</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/cashdraws/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + remoteSort:true , + sortName: 'cashNo', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); +} + +function toEdit(id){ + location.href=WST.U('admin/cashdraws/toHandle','id='+id); +} +function toView(id){ + location.href=WST.U('admin/cashdraws/toView','id='+id); +} +function loadGrid(){ + mmg.load({page:1,cashNo:$('#cashNo').val(),cashSatus:$('#cashSatus').val(),targetType:$('#targetType').val()}); +} + +function save(){ + var params = WST.getParams('.ipt'); + if(typeof(params.cashSatus)=='undefined'){ + WST.msg('请选择提现结果',{icon:2}); + return; + } + if(params.cashSatus==-1 && $.trim(params.cashRemarks)==''){ + WST.msg('输入提现失败原因',{icon:2}); + return; + } + if(WST.confirm({content:'您确定该提现申请'+((params.cashSatus==1)?'成功':'失败')+'吗?',yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/cashdraws/handle'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('admin/cashdraws/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }})); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出提现申请记录吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/cashdraws/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/cashdraws/edit.html b/hyhproject/admin/view/cashdraws/edit.html new file mode 100755 index 0000000..973a4d4 --- /dev/null +++ b/hyhproject/admin/view/cashdraws/edit.html @@ -0,0 +1,85 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/cashdraws/cashdraws.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style> + th{height:25px;} +</style> +<form autocomplete='off' id='editFrom'> + <input type='hidden' id='cashId' class='ipt' value="{$object['cashId']}"/> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>会员类型:</th> + <td> + {if $object['targetType']==1}商家{else}普通会员{/if} + </td> + </tr> + <tr> + <th width='150'>会员名称:</th> + <td> + {$object['userName']}({$object['loginName']}) + </td> + </tr> + <tr> + <th width='150'>提现单号:</th> + <td> + {$object['cashNo']} + </td> + </tr> + <tr> + <th>提现金额:</th> + <td>¥{$object['money']}</td> + </tr> + <tr> + <th>提现银行:</th> + <td>{$object['accTargetName']}</td> + </tr> + <tr> + <th>开卡地区:</th> + <td> + {$object['accAreaName']} + </td> + </tr> + <tr> + <th>卡号:</th> + <td> + {$object['accNo']} + </td> + </tr> + <tr> + <th>持卡人:</th> + <td> + {$object['accUser']} + </td> + </tr> + <tr> + <th>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <th>提现结果:</th> + <td class='layui-form'> + <label> + <input type='radio' name='cashSatus' class='ipt' value='1' title='提现成功'/> + </label> + <label> + <input type='radio' name='cashSatus' class='ipt' value='-1' title='提现失败'/> + </label> + </td> + </tr> + <tr > + <th valign='top'>提现备注:<br/>(用户可见)&nbsp;&nbsp;</th> + <td> + <textarea id='cashRemarks' class='ipt' style='width:70%;height:80px;'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:save()'><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + </table> +</form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/cashdraws/list.html b/hyhproject/admin/view/cashdraws/list.html new file mode 100755 index 0000000..a6f7760 --- /dev/null +++ b/hyhproject/admin/view/cashdraws/list.html @@ -0,0 +1,42 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/cashdraws/cashdraws.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于处理来自于会员(商家)的提现请求。提现通过后系统会扣除会员(商家)的钱包金额。</li> + <li>本功能只扣除本系统的会员(商家)钱包金额,实际上的资金转账需平台线下操作。</li> + </ul> +</div> +<div class="wst-toolbar"> + <select id='targetType' class='j-ipt'> + <option value='-1'>会员类型</option> + <option value='0'>会员</option> + <option value='1'>商家</option> + </select> + <select id='cashSatus' class='j-ipt'> + <option value='-1'>提现状态</option> + <option value='0'>待处理</option> + <option value='1'>已通过</option> + </select> + <input type="text" name="cashNo" placeholder='提现单号' id="cashNo" class='j-ipt'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/cashdraws/view.html b/hyhproject/admin/view/cashdraws/view.html new file mode 100755 index 0000000..fcd6215 --- /dev/null +++ b/hyhproject/admin/view/cashdraws/view.html @@ -0,0 +1,70 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/cashdraws/cashdraws.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form autocomplete='off'> + <input type='hidden' id='cashId' class='ipt' value="{$object['cashId']}"/> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>会员类型:</th> + <td> + {if $object['targetType']==1}商家{else}普通会员{/if} + </td> + </tr> + <tr> + <th width='150'>会员名称:</th> + <td> + {$object['userName']}({$object['loginName']}) + </td> + </tr> + <tr> + <th width='150'>提现单号:</th> + <td> + {$object['cashNo']} + </td> + </tr> + <tr> + <th>提现金额:</th> + <td>¥{$object['money']}</td> + </tr> + <tr> + <th>提现银行:</th> + <td>{$object['accTargetName']}</td> + </tr> + <tr> + <th>开卡地区:</th> + <td> + {$object['accAreaName']} + </td> + </tr> + <tr> + <th>卡号:</th> + <td> + {$object['accNo']} + </td> + </tr> + <tr> + <th>持卡人:</th> + <td> + {$object['accUser']} + </td> + </tr> + <tr> + <th>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr > + <th valign='top'>提现备注:<br/>(用户可见)&nbsp;&nbsp;</th> + <td> + {$object['cashRemarks']} + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class="btn" onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + </table> +</form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/cashdraws/view_report.html b/hyhproject/admin/view/cashdraws/view_report.html new file mode 100755 index 0000000..929d989 --- /dev/null +++ b/hyhproject/admin/view/cashdraws/view_report.html @@ -0,0 +1,267 @@ +{extend name="base" /} + +{block name="css"} +<style type="text/css"> + @page + { + size: auto; /* auto is the initial value */ + margin: 0mm; /* this affects the margin in the printer settings */ + } + .table_title{ + font-size:18px;font-weight: bold;text-align: center;margin:10px; + } + .right{ + float: right; + } + .center{ + text-align: center; + } + .layui-form{ + width:95%; + margin:50px auto; + } + .red{ + color:red; + } + +</style> +{/block} + +{block name="js"} + +<script src="__ADMIN__/cashdraws/cashdraws.js?v={$v}" type="text/javascript"></script> + +{/block} + +{block name="main"} +<div class="layui-form"> + <div class="layui-form-item"> + <div class="layui-input-block" style="float: right;"> + <button class="layui-btn layui-btn-warm print">打印</button> + </div> + </div> + <div class="layui-collapse" lay-filter="test"> + <div class="layui-colla-item"> + <h2 class="layui-colla-title">点击查询/充值/扣除操作</h2> + <div class="layui-colla-content"> + <fieldset class="layui-elem-field"> + <legend>查询</legend> + <div class="layui-field-box"> + <form action="" method="get"> + <div class="wst-toolbar"> + <label class="layui-form-label">查询日期</label> + <input type="text" id="searchDate" name="searchDate" class="layui-input" maxlength="20" value="{$searchDate}" placeholder="查询日期"> + <button class="btn btn-primary search" ><i class="fa fa-search"></i>查询</button> + </div> + + </form> + </div> + </fieldset> + <fieldset class="layui-elem-field"> + <legend>充值/扣除操作</legend> + <div class="layui-field-box"> + <div class="layui-form-item"> + <label class="layui-form-label" style="width: auto;">日期选择:</label> + <div class="layui-input-inline"> + <input type="text" id="reDate" name="reDate" class="layui-input ipt" maxlength="20" value="{$searchDate}" placeholder="日期"> + </div> + </div> + <div class="layui-form-item"> + <label class="layui-form-label" style="width: auto;">充值/扣除:</label> + <div class="layui-input-block"> + <input type="radio" class="ipt" name="reType" value="1" title="充值" checked=""> + <input type="radio" class="ipt" name="reType" value="2" title="扣除"> + </div> + </div> + <div class="layui-form-item"> + <label class="layui-form-label" style="width: auto;">变动数额:</label> + <div class="layui-input-inline"> + <input type="text" id="money" name="money" class="layui-input ipt" maxlength="20" value="" placeholder="请输入变动数额"> + </div> + </div> + <div class="layui-form-item"> + <label class="layui-form-label" style="width: auto;">&nbsp;&nbsp;&nbsp;验证码:</label> + <div class="layui-input-inline"> + <input type="text" id="mobileCode" name="mobileCode" class="layui-input" maxlength="20" value="" placeholder="请输入验证码"> + + </div> + <div class="layui-word-aux""><button class="layui-btn layui-btn-normal layui-btn-sm getCode">获取验证码</button> </div> + </div> + + <div class="layui-form-item"> + <button class="layui-btn setReport" >确定提交</button> + </div> + </div> + </fieldset> + </div> + </div> + + </div> + +<!--start--> + <table class="layui-table"> + <tbody> + <tr> + <th colspan="12"> <p class="table_title">交易明细备查表-{$searchDate}</p></th> + </tr> + <tr> + <th colspan="12"> <p class="right">单位:元</p></th> + </tr> + <tr> + <td>上日余额¥ {$orders['yesterdayMoney']}</td> + <td>今日余额¥ {$orders['todayMoney']}</td> + <td>今日交易¥{$orders['allPaySum']}</td> + <td>今日代收¥ {$orders['collectionGatheringSum']}</td> + <td>今日代付¥ {$orders['coupousEarningsSum']+$orders['hasVouchersEearningsSum']+$orders['taxFeeSum']+$orders['collectionPaySum']}</td> + <td class="red">今日收益¥ {$orders['coupousEarningsSum']+$orders['hasVouchersEearningsSum']}</td> + </tr> + <tr> + <td colspan="1" >今日明细</td> + <td colspan="1" >代付款</td> + <td colspan="3" class="center">公司手续费收益</td> + <td>商品交易</td> + </tr> + <tr> + <td>合计</td> + <td>¥{$orders['taxFeeSum']}</td> + <td>¥{$orders['hasVouchersEearningsSum']}</td> + <td>合计</td> + <td>¥{$orders['coupousEarningsSum']}</td> + <td>¥{$orders['allPaySum']}</td> + </tr> + <tr> + <td>购户ID</td> + <td>今日缴税</td> + <td>已获券收益</td> + <td>商户ID</td> + <td>优惠款收益</td> + <td>销售额</td> + </tr> + {foreach name="orders['list']" item="vo"} + <tr> + <td>{$vo['loginName']} </td> + <td>{$vo['taxFee']}</td> + <td>{$vo['hasVouchersEearnings']}</td> + <td>{$vo['shopLoginName']}</td> + <td>{$vo['coupousEarnings']} </td> + <td>{$vo['realTotalMoney']}</td> + </tr> + {/foreach} + </tbody> + </table> + <table class="layui-table"> + <tbody> + <tr> + <th colspan="3"> <p class="table_title">交易明细备查表-{$searchDate}</p></th> + </tr> + <tr> + <th class="red">今日汇总:¥{$orders['collectionGatheringSum']-$orders['collectionPaySum']}</th> + <th>代收款</th> + <th>代付款</th> + </tr> + <tr> + <th>合计</th> + <th>¥{$orders['collectionGatheringSum']}</th> + <th>¥{$orders['collectionPaySum']}</th> + </tr> + <tr> + <th>商户ID</th> + <th>优惠款</th> + <th>提现金额</th> + </tr> + + {foreach name="orders['collection']" item="vo"} + <tr> + <td>{$vo['shopLoginName']}</td> + <td>{$vo['gathering']}</td> + <td>{$vo['pay']}</td> + </tr> + {/foreach} + </tbody> + </table> +<!--end--> +</div> +<script> + + $(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#searchDate' + }); + laydate.render({ + elem: '#reDate' + }); + isSend = false; + $('body').on('click','.getCode',function(){ + var params = WST.getParams('.ipt'); + if(params.money<=0){ + WST.msg('请输入变动金额','warn'); + $('#money').focus(); + return; + } + var that = $(this); + if(isSend) return; + isSend = true; + $('.ipt').removeAttr('disabled'); + $.post(WST.U('admin/Cashdraws/getMobileCode'), params, function(data) { + var json = WST.toAdminJson(data); + if(json.status == 1) { + $('.ipt').attr('disabled','disabled'); + WST.msg(json.msg, 'success'); + time = 120; + that.attr('disabled', 'disabled').html('120秒获取'); + $('#mobileCode').focus(); + var task = setInterval(function() { + time--; + that.html('' + time + "秒获取"); + if(time == 0) { + isSend = false; + clearInterval(task); + that.removeAttr('disabled').html("重新发送"); + } + }, 1000); + } else { + WST.msg(json.msg, 'warn'); + isSend = false; + } + data = json = null; + }); + }); + //修改凭证 + $('body').on('click','.setReport',function(){ + var params = {}; + params.mobileCode = $('#mobileCode').val(); + if(params.mobileCode.length<4){ + WST.msg('请输入验证码','warn'); + return; + } + var that = $(this); + that.attr('disabled','disabled'); + $.post(WST.U('admin/Cashdraws/setReport'), params, function(data) { + var json = WST.toAdminJson(data); + if(json.status == 1) { + WST.msg(json.msg, 'success'); + $('.ipt').removeAttr('disabled'); + } else { + WST.msg(json.msg, 'warn'); + } + that.removeAttr('disabled'); + data = json = null; + }); + }); + //打印 + $('body').on('click','.print',function(){ + bdhtml = window.document.body.innerHTML; + sprnstr = "<!--start-->"; + eprnstr = "<!--end-->"; + prnhtml = bdhtml.substr(bdhtml.indexOf(sprnstr)); + prnhtml = prnhtml.substring(0,prnhtml.indexOf(eprnstr)); + window.document.body.innerHTML = prnhtml; + window.print(); + location.reload(); + }); + }) + +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/chargeitems/chargeitems.js b/hyhproject/admin/view/chargeitems/chargeitems.js new file mode 100755 index 0000000..e6b58b4 --- /dev/null +++ b/hyhproject/admin/view/chargeitems/chargeitems.js @@ -0,0 +1,81 @@ +var mmg; +function initGrid(staffId){ + var h = WST.pageHeight(); + var cols = [ + {title:'充值金额', name:'chargeMoney', width: 60}, + {title:'赠送金额', name:'giveMoney' ,width:60}, + {title:'排序号', name:'itemSort' ,width:50}, + {title:'创建时间', name:'createTime' ,width:30}, + {title:'操作', name:'op' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.CZGL_02)h += "<a class='btn btn-blue' onclick='javascript:location.href=\""+WST.U('admin/Chargeitems/toEdit','id='+item['id'])+"\"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.CZGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-80),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/Chargeitems/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +function loadQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Chargeitems/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + +function editInit(){ + /* 表单验证 */ + $('#adPositionsForm').validator({ + fields: { + chargeMoney: { + rule:"required", + msg:{required:"请输入充值金额"}, + tip:"请输入充值金额", + ok:"", + }, + giveMoney: { + rule:"required;", + msg:{required:"请输入赠送金额"}, + tip:"请输入赠送金额", + ok:"", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Chargeitems/'+((params.id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Chargeitems/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/chargeitems/edit.html b/hyhproject/admin/view/chargeitems/edit.html new file mode 100755 index 0000000..1e4df55 --- /dev/null +++ b/hyhproject/admin/view/chargeitems/edit.html @@ -0,0 +1,46 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/chargeitems/chargeitems.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="adPositionsForm"> +<table class='wst-form wst-box-top'> + <tr> + + <tr> + <th width='150'>充值金额<font color='red'>*</font>:</th> + <td> + <input type="text" id="chargeMoney" name="chargeMoney" value='{$data['chargeMoney']}' class="ipt" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/> + </td> + </tr> + <tr> + <th>赠送金额<font color='red'>*</font>:</th> + <td> + <input type="text" id="giveMoney" name="giveMoney" value='{$data['giveMoney']}' class="ipt" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/> + </td> + </tr> + <tr> + <th>排序号<font color='red'> </font>:</th> + <td> + <input type='text' id='itemSort' name="itemSort" value='{$data['itemSort']}' class='ipt' maxLength='10' onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="id" class="ipt" value="{$data['id']+0}" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){editInit()}); +</script> +{/block} + diff --git a/hyhproject/admin/view/chargeitems/list.html b/hyhproject/admin/view/chargeitems/list.html new file mode 100755 index 0000000..41a26f5 --- /dev/null +++ b/hyhproject/admin/view/chargeitems/list.html @@ -0,0 +1,23 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/chargeitems/chargeitems.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +{if WSTGrant('GGWZ_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:location.href='<?=url("Chargeitems/toEdit")?>'"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/css/common.css b/hyhproject/admin/view/css/common.css new file mode 100755 index 0000000..297554e --- /dev/null +++ b/hyhproject/admin/view/css/common.css @@ -0,0 +1,333 @@ +/***验证框架样式***/ +.msg-wrap,.n-icon,.n-inline-block,.n-msg,.nice-validator [contenteditable],.nice-validator input,.nice-validator select,.nice-validator textarea{display:inline-block} +.nice-validator .msg-container .msg-box{display:block} +.nice-validator .msg-container .msg-wrap{position:static} +.msg-box{position:relative} +.msg-wrap{position:relative;white-space:nowrap;line-height:16px;font-size:12px} +.msg-wrap,.n-icon,.n-msg{vertical-align:top} +.msg-box .msg-wrap .n-error,.msg-box .msg-wrap .n-ok,.msg-box .msg-wrap .n-tip{display:block;background:0 0;box-shadow:none;padding:3px 2px} +.n-arrow{position:absolute;overflow:hidden} +.n-arrow b,.n-arrow i{position:absolute;left:0;top:0;border:0;margin:0;padding:0;overflow:hidden;font-weight:400;font-style:normal;font-size:12px;font-family:serif;line-height:14px} +.n-arrow i{text-shadow:none} +.n-icon{width:16px;height:16px;overflow:hidden;background-repeat:no-repeat} +.n-msg{display:inline-block;margin-left:1px} +.n-error{color:#c33} +.n-ok{color:#390} +.n-loading,.n-tip .n-msg{color:grey} +.n-error .n-icon{background-position:0 0} +.n-ok .n-icon{background-position:-16px 0} +.n-tip .n-icon{background-position:-32px 0} +.n-loading .n-icon{background:url(../images/loading.gif) 0 center no-repeat!important} +.n-bottom,.n-left,.n-right,.n-top{display:inline-block;line-height:0;vertical-align:top;outline:0} +.n-bottom .n-arrow,.n-top .n-arrow{height:6px;width:12px;left:8px} +.n-left .n-arrow,.n-right .n-arrow{width:6px;height:12px;top:6px} +.n-top{vertical-align:top} +.n-top .msg-wrap{margin-bottom:6px} +.n-top .n-arrow{bottom:-6px} +.n-top .n-arrow b{top:-6px} +.n-top .n-arrow i{top:-7px} +.n-bottom{vertical-align:bottom} +.n-bottom .msg-wrap{margin-top:6px} +.n-bottom .n-arrow{top:-6px} +.n-bottom .n-arrow b{top:-1px} +.n-bottom .n-arrow i{top:0} +.n-left .msg-wrap{right:100%;margin-right:6px} +.n-left .n-arrow{right:-6px} +.n-left .n-arrow b{left:-6px} +.n-left .n-arrow i{left:-7px} +.n-right .msg-wrap{margin-left:6px} +.n-right .n-arrow{left:-6px} +.n-right .n-arrow b{left:1px} +.n-right .n-arrow i{left:2px} +.n-default .n-left,.n-default .n-right{margin-top:5px} +.n-default .n-top .msg-wrap{bottom:100%} +.n-default .n-bottom .msg-wrap{top:100%} +.n-default .msg-wrap{position:absolute;z-index:1} +.n-default .msg-wrap .n-icon{background-image:url(../images/validator_default.png)} +.n-default .n-tip .n-icon{display:none} +.n-simple .msg-wrap{position:absolute;z-index:1} +.n-simple .msg-wrap .n-icon{background-image:url(../images/validator_simple.png)} +.n-simple .n-top .msg-wrap{bottom:100%} +.n-simple .n-bottom .msg-wrap{top:100%} +.n-simple .n-left,.n-simple .n-right{margin-top:5px} +.n-simple .n-bottom .msg-wrap{margin-top:3px} +.n-simple .n-tip .n-icon{display:none} +.n-yellow .msg-wrap{position:absolute;z-index:1;padding:4px 6px;font-size:12px;border:1px solid transparent;background-color:#fffcef;border-color:#ffbb76;color:#db7c22;box-shadow:0 1px 3px #ccc;border-radius:2px} +.n-yellow .msg-wrap .n-arrow b{color:#ffbb76;text-shadow:0 0 2px #ccc} +.n-yellow .msg-wrap .n-arrow i{color:#fffcef} +.n-yellow .msg-wrap .n-icon{background-image:url(../images/validator_simple.png)} +.n-yellow .n-top .msg-wrap{bottom:100%} +.n-yellow .n-bottom .msg-wrap{top:100%} +.n-yellow .n-loading,.n-yellow .n-ok,.n-yellow .n-tip{background-color:#f8fdff;border-color:#ddd;color:#333;box-shadow:0 1px 3px #ccc} +.n-yellow .n-loading .n-arrow b,.n-yellow .n-ok .n-arrow b,.n-yellow .n-tip .n-arrow b{color:#ddd;text-shadow:0 0 2px #ccc} +.n-yellow .n-loading .n-arrow i,.n-yellow .n-ok .n-arrow i,.n-yellow .n-tip .n-arrow i{color:#f8fdff} +/***系统风格样式***/ +body{background:#ffffff;font-size: 12px;overflow-x:hidden;overflow-y:auto;} +.j-layout{margin:5px;} +.j-layout .j-layout-left{border:1px solid #ccc;float:left;} +.j-layout .j-layout-center{border:1px solid #ccc;float:left;margin-left:5px;} +.j-layout .j-layout-panel{border-bottom:1px solid #ccc;height:30px;width:100%;line-height:30px;padding-left:5px;} +.wst-panel{border:1px solid #666;float:left;} +.wst-panel .panel-header{border-bottom:1px solid #666;height:30px;background:#ffffff;} +.wst-toolbar{border-bottom: 0px;line-height: 30px;padding:5px;} +.f-right{float:right;} +.f-left{float:left;} +.f-clear{clear:both} +.wst-form{width:100%;margin-bottom:20px} +.wst-form input.cfg,.wst-form input.textarea{width:340px} +.wst-form th{text-align:right;font-weight:normal} +.wst-form td{padding:2px 5px;} +.wst-box-top{margin-top:5px}label{margin-right:10px} +.webuploader-pick{background:#428bca;height:24px;border-radius:3px;line-height:24px;overflow:hidden} +.webuploader-container{height:24px;overflow:hidden;width:300px} +#j-loader{cursor: progress; position: fixed; top: -50%; left: -50%; width: 200%; height: 200%; background: #fff; z-index: 10000; overflow: hidden;} +#j-loader img{position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto;} +td.wst-bottombar{text-align:left;padding-left:155px;padding-top:10px;} +.btn-fixtop{margin-top:3px;} +.btn-mright{margin-right:10px;} +.wst-footer{padding-bottom:20px;text-align:center} +.line-break{word-break:break-all;word-wrap:break-word;} +.wst-green{color:#5FB878;} +.wst-wiki{background: #F5F5F5;color:#777;height:20px;padding:5px 8px;border:1px solid;border-color:#DCDCDC #DCDCDC #B3B3B3 #DCDCDC;border-radius:3px;} +/***订单**/ +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd} +.order-box th{font-weight:normal} +.order-box .goods-head{border-top:2px solid #fc7a64;background:#f3f3f3;display:block;height:25px;line-height:25px;margin:0 0 10px;padding:5px 0} +.order-box .goods-head .goods{float:left;width:650px;padding-left:15px} +.order-box .goods-head .price{float:left;width:100px} +.order-box .goods-head .num{float:left;width:100px} +.order-box .goods-head .t-price{float:left;width:105px} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #fdd8d2;color:#e55356;font-weight:bold;font-size:15px} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eee} +.order-box .item .goods{float:left;width:650px;padding-left:15px} +.order-box .item .goods .img{float:left;width:80px;height:80px} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px} +.order-box .item .price{float:left;width:100px} +.order-box .item .num{float:left;width:100px} +.order-box .item .t-price{float:left;width:100px} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px} +.order-box .line{border-top:1px solid #ddd} +.order-box .goods-summary{margin-top:10px} +.order-box .summary{height:30px;line-height:30px} +.order-box .orderScore{margin-right:5px} +.order-box .log td{height:25px;line-height:25px;padding-left:15px} +.order-box .log-box{height:132px} +.order-box .log-box .icon{float:left;width:60px;height:60px} +.order-box .log-box .icons{float:left;width:60px;height:60px} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat} +.order-box .log-box .arrow{float:left;color:#979797;font-size:15px;font-weight:bold;margin-top:18px} +.order-box .log-box .arrow2{color:#7ebb53} +.order-box .log-box .state{float:left;width:100%;margin-left:18px} +.order-box .log-box .state2{float:left;width:100%;position:relative} +.order-box .log-box .state2 p{float:left;width:178px;height:50px;text-align:left;margin-left:15px;color:#f05858;font-size:15px} +.order-box .log-box .state2 .path{position:absolute;z-index:10} +.order-box .log-box .state2 .path span{float:left;width:178px;height:50px;text-align:left;margin-left:15px;background:#fff} +.order-source{margin:0 5px 0 0;width:18px;height:18px;position:relative;} +.order-source2{margin:0 5px 0 0;width:16px;height:16px;position:relative;} + +/***风格管理模块**/ +.style-box{width:215px;height:315px;border:1px solid #ddd;padding:5px;margin:5px;float:left} +.style-box .style-img{width:200px;height:200px;text-align:center;vertical-align:middle;display:block;position:relative} +.style-box .style-img a{display:table-cell;vertical-align:middle;width:200px;height:200px;border:1px solid #ddd} +.style-box .style-img a img{max-width:200px;max-height:200px} +.style-box .style-txt,.style-box .style-author,.style-box .style-web{width:200px;height:25px;overflow:hidden;text-align:left;line-height:25px} +.style-box .style-op{height:30px;text-align:center;overflow:hidden} +/***推荐管理模块***/ +.recom-lbox{width:350px;height:350px;border:1px solid #ddd;padding:5px;text-align:left;overflow-x:hidden;overflow-y:auto} +.recom-lbox .head,.recom-rbox .head{border-bottom:1px solid #eee} +.recom-lbox .tck,.recom-rbox .tck{float:left;height:30px;overflow:hidden;width:25px} +.recom-lbox .ttxt{float:left;height:30px;overflow:hidden;width:290px} +.recom-lbox .trow{height:30px;overflow:hidden;line-height:30px} +.recom-rbox{width:420px;height:350px;border:1px solid #ddd;padding:5px;text-align:left;overflow-x:hidden;overflow-y:auto} +.recom-rbox .tck{float:left;height:30px;overflow:hidden;width:25px} +.recom-rbox .ttxt{float:left;height:30px;overflow:hidden;width:325px} +.recom-rbox .top{float:left;width:70px} +.recom-rbox .trow{height:30px;overflow:hidden;width:420px;line-height:30px} +.recom-rbox .s-sort{width:30px;height: 26px;} +/**微信菜单**/ +.wst-views{float:left;width:335px;padding-bottom: 10px;} +.wst-views .reveal{margin:0px 5px 0px;width:325px;height:100%;border:1px solid #e7e7eb;position:relative;} +.wst-views .revealt{position:absolute;left:0;top:0;width:100%;height:65px;background:url(../img/img_topinfo.png) 0 0 no-repeat;background-size:100%} +.wst-views .revealb{position:absolute;left:0;bottom:0;width:100%;height:46px;border-top:1px solid #e7e7eb} +.wst-views .revealb i{float:left;width:15%;height:45px;background:url(../img/img_dibu.png) -5px -10px no-repeat} +.wst-views .ui{float:right;width:85%;height:45px;display:-webkit-box} +.wst-views .li{-webkit-box-flex:1;display:block;line-height:45px;text-align:center;border-left:1px solid #e7e7eb;cursor:pointer;position:relative} +.wst-views .li:hover,.wst-views .li .list:hover{background:#eee} +.wst-views .selected{background:#eee} +.wst-views .li .lis{position:absolute;left:0;bottom:45px;width:100%;border:1px solid #e7e7eb} +.wst-views .li .list{float:left;width:100%;border-bottom:1px solid #e7e7eb} +.wst-maingr{float:right;width:72%;} +.wst-view{float:left;width:200px;height:200px;background:#eee} +.wst-view a{display:block;height:200px;line-height:200px;text-decoration:none;text-align:center;color:#3295d3} +.wst-view a:hover{color:#56b7f5} + +/***树形菜单**/ +.wst-grid{margin-left:5px;margin-right:5px;} +.wst-grid-tree-hd-cell{height:2em;padding:7px 5px;font-weight:bold;line-height:2;} +.wst-grid-tree-hd .first{width:26px;text-align: center;} +.wst-grid-tree-row .first{width:26px;text-align: center;} +.wst-grid-tree-row-cell{height:2em;border-bottom: 1px solid #f5f5f5;padding:5px 5px;} +.wst-grid-tree-space{margin-left:15px;display: inline-block;} +.wst-tree-img{font-size: 18px;margin-right: 5px;cursor: pointer;} +/**ztree右键菜单**/ +div#rMenu {background:#fff;position:absolute; visibility:hidden; top:0; text-align: left;padding: 2px;border:1px solid #eeeeee;} +div#rMenu ul li{margin: 0px;padding: 5px 10px;cursor: pointer;list-style: none outside none;border-bottom: 1px solid #eeeeee;font-size: 12px;} +.ztree li a.curSelectedNode{height:20px;} +.ztreeMenuContent{border:1px solid #eee;z-index:1000;background:#ffffff;overflow:auto;display:none; position: absolute;} + +/**修复layui**/ +.layui-form-switch{width:60px;} +.layui-tab {margin: 0px 0px;} +.layui-tab-title{height:35px;} +.layui-tab-title li{font-size:12px;line-height: 35px;} +.layui-tab-title .layui-this:after{height:36px;} +.layui-field-title{margin-top:0px;} +.layui-input:focus,.layui-textarea:focus{border-color: #66afe9;outline: 0;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);} +.layui-form-switch{margin-top:0px;height:26px;line-height:26px;} +.layui-form-switch i{height:18px;width:18px;} +.layui-form-checkbox{height:20px;line-height:18px;width:20px;padding-right:20px;} +.layui-form-checkbox i{width:20px;left:-5px;top:1px;} +.layui-form-radio i{font-size:17px;} +.layui-form-radio{line-height:21px;font-weight:normal;} +.layui-form-select dl{top:27px;} +.layui-tab-content{padding:0px;} + +/**覆盖bootstrap样式**/ +.form-control{width:200px;display:inline-block;} +textarea{width:70%;height:120px;background-color:#fff;background-image:none;border:1px solid #ccc;color:#222;border-radius:2px;box-shadow:0 1px 1px rgba(0,0,0,0.075) inset;display:inline-block;font-size:14px;padding:2px 5px;position:relative;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;vertical-align:middle;} +input[type=text],input[type=password]{display:inline-block;width:auto;height:30px;padding:6px 12px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s} +input[type=text]:focus,input[type=password]:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)} +input[type=text]::-moz-placeholder,input[type=password]::-moz-placeholder{color:#999;opacity:1} +input[type=text]:-ms-input-placeholder,input[type=password]:-ms-input-placeholder{color:#999} +input[type=text]::-webkit-input-placeholder,input[type=password]::-webkit-input-placeholder{color:#999} +input[type=text][disabled],input[type=text][readonly]{background-color:#eee;opacity:1} +input[type=text][disabled]{cursor:not-allowed} + +.btn{padding:3px 12px;} +.btn-green,.btn-blue,.btn-red{padding:5px 8px;font-size:12px;background:#ffffff;color:#777;border:1px solid #eee;} +.btn-blue:hover{color:#fff;background-color: #3598DC; border-color: #2A80B9;box-shadow: 2px 2px #ccc;} +.btn-red:hover{color:#fff;background-color: #c9302c;border-color: #ac2925;box-shadow: 2px 2px #ccc;} +.btn-green:hover{color:#fff;background-color: #5CB85C;border-color: #4E9D4E;box-shadow: 2px 2px #ccc;} +.statu-yes{color: #1BBC9D;} +.statu-no{color: #c9302c;} +.statu-wait{color: #BEC3C7;} +legend {display: inline-block;margin-bottom: 10px;width:auto;border-bottom: 0px;} +.alert{padding:8px;} +.alert-tips{margin:6px;overflow: hidden;} +.alert .head{font-size:14px;font-weight: bold;cursor: pointer;} +.alert .head .fa{margin-right: 2px;} +.alert .body{padding-left:15px;margin-top:10px;} +.alert .body li{list-style:disc;} +select{border-radius:4px;border-color:#ccc;height:30px;margin-right:5px;} +.navbar-nav .fa{margin-right: 2px;} +.btn .fa{margin-right: 2px;} +/**覆盖mmgrid**/ +.mmGrid .mmg-headWrapper{border-top:none;background: #f9f9f9} +.mmGrid .mmg-bodyWrapper .mmg-body td{color:#777;padding:4px 5px;border-left:0px;border-right:0px;border-bottom:1px solid #f5f5f5;word-wrap: break-word;word-break:break-all;} +.mmGrid .mmg-bodyWrapper .mmg-body td .mmg-index{color:#777;} +.mmGrid .mmg-headWrapper .mmg-head th {padding:6px 5px;border:0px;} +.mmPaginator .totalCountLabel{padding: 5px 0 0 0;} +.mmPaginator .pageList li{margin: 0;padding: 4px 12px;background-color: #ffffff;border: 1px solid #dddddd;border-left-width: 0;} +.mmPaginator .pageList li.active{padding: 4px 12px;border: 1px solid #dddddd;border-left-width: 0;background-color: #f5f5f5;} +.mmPaginator .pageList li.active a{color: #999999;cursor: default;} +.mmPaginator .pageList li.disable a{color: #999999;} +.mmPaginator .pageList li.disable{background: #f5f5f5;} +.mmPaginator .pageList li.disable a{color: #999999;} +.mmPaginator .pageList li a{color: #005580;text-decoration: none;} +.mmPaginator .pageList li.prev{border-left-width: 1px;-webkit-border-bottom-left-radius: 4px;border-bottom-left-radius: 4px;-webkit-border-top-left-radius: 4px;border-top-left-radius: 4px;-moz-border-radius-bottomleft: 4px;-moz-border-radius-topleft: 4px;} +.mmPaginator .limit select{height:28px;line-height:28px;margin-right:20px;} +.mmGrid .mmg-bodyWrapper .mmg-body td.colSelectedEven,.mmGrid .mmg-bodyWrapper .mmg-body td.colSelected{background:none;} +/*新增*/ +.img-remind{width: 25px;height: 25px;margin-right: 10px;margin-bottom: 5px;} +.remind-angle-left{width: 25px;height: 25px;position: absolute;bottom: -0px;left: -0px;} +.remind-angle-right{width: 25px;height: 25px;position: absolute;top: 0px;right: 0px;} +.wst-tb-bor{margin:0px;} +.wst-repair{padding:2px;padding-left:20px;border: 0px solid transparent;} +.wst-total{margin:10px 10px 20px;height:auto;overflow:hidden;border: 1px solid #eee;} +.wst-num{font-size: 15px;line-height: ;} +.wst-tb-bor{width: 60%;height: auto;overflow:hidden;float: left;} +.wst-box-top{margin-top:5px} +.wst-bor-left{margin-left:30px} +.wst-bor-right{margin-right:20px} +.wst-bor-top{margin-top: 20px;} +.wst-line-top{margin-top: 5px;} +.wst-cont-total{ width:98%;height: auto;float: right;border: 1px solid #f5f5f5;border-top: 5px solid #1d2225;border-top-left-radius:5px;border-top-right-radius:5px;box-shadow: 5px 5px 6px 3px #f5f5f5;} +.wst-summary{padding: 10px;box-shadow: 5px 5px 6px 3px #f5f5f5;} +.wst-summary .wst-summary-head{padding: 10px 10px 10px 30px; height: 40px;width: 100%;background:url('../img/title_head.png') bottom left no-repeat;} +.wst-summary .wst-summary-content{ height: 90px;overflow: hidden;} +.wst-summary .img img{ height: 4.5rem;width: 4.5rem;float: left;margin:20px 0px 20px 20px;} +.wst-summary .data{ height: 60%;width: auto;overflow:hidden;float:left;margin:10px 0px 0px 10px;} +.wst-summary .data-top{text-align:center;padding-top: 5%; width: 100%;height: 60%;font-size: 30px;font-weight: bold;} +.wst-summary .data-bottom{text-align:center; width: 100%;padding-top: 2%;height: 25%;} +.wst-summary-head .content{color: #333333;} +.wst-summary .wst-summary-content2{ height: 240px;margin-top: 5px;} +.wst-summary .wst-strip{width: 100%;height: 30%;overflow: hidden;} +.wst-summary .wst-title{width: auto;overflow:hidden;height: 22px;margin: 10px;padding-top: 1%;} +.wst-summary img{width: 65%;height: 15px;margin: 0px 5px 10px 20px;} +.wst-summary .wst-system-chunk{height: auto;overflow: hidden;border-right: 1px dotted #CCCCCC;} +.wst-summary .wst-system-strip{height: 30px;width: 100%;} +.wst-summary .wst-system-strip .title{width: 35%;text-align: right;float: left;height: 100%;padding-top: 1.5%;} +.wst-summary .wst-system-strip .text{width: 65%;text-align: left;float: left;height: 100%;padding-top: 1.5%;} +.wst-cont-total .wst-cont-bor{width: 90%;height: auto; margin: 20px;} +.wst-cont-total .wst-cont-head{width: 100%;height: 30px;line-height: 30px;font-size: 15px;} +.wst-cont-total .wst-cont-body{width: 100%;height: auto;padding: 10px;border-bottom: 1px solid #CCCCCC;} +.wst-nowrap{width: 150px;white-space:nowrap;overflow: hidden;text-overflow:ellipsis;} +.weixin{ display:block;position: relative;} +.weixin .imged{ display:none;} +.weixin:hover .imged{ position:absolute; left:60px; margin-top: -40px; display:block;border: 5px solid #bfbfbf;border-radius: 6px;} +.style-main{padding:10px} +.style-box{width:203px;height:307px;border:1px solid #ddd;padding:5px;margin:5px;float:left;box-sizing: content-box;} +.style-box .style-img{width:200px;height:200px;text-align:center;vertical-align:middle;display:block;position:relative} +.style-box .style-img a{display:table-cell;vertical-align:middle;width:200px;height:200px;border:1px solid #ddd} +.style-box .style-img a img{max-width:200px;max-height:200px} +.style-box .style-txt,.style-box .style-author,.style-box .style-web{width:200px;height:25px;overflow:hidden;text-align:left;line-height:25px} +.style-box .style-op{height:30px;text-align:center;overflow:hidden} +.nav li a,.nav li a:hover,.nav-list li a,.nav-list li a:hover{display:block;text-decoration:none;outline:0;border-bottom:0 none} +.nav li{float:left} +.tab-wrap{margin-top:10px} +.tab-nav{margin-bottom:15px;padding-left:1px;border-bottom:1px solid #e0e0e0} +.tab-nav li{margin-bottom:-1px;margin-left:-1px} +.tab-nav li a,.tab-nav li a:hover{padding:0 20px;height:35px;line-height:35px;font-weight:bold;font-size:16px;border:1px solid transparent;border-top-width:2px} +.tab-nav .current a,.tab-nav .current a:hover{border-color:#34b4e0 #e0e0e0 #f6f6f6} +.tab-content .tab-pane{display:none} +.tab-content .in{display:block} +.label{border-radius:.25em;color:#fff;display:inline;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:baseline;white-space:nowrap} +a.label:hover,a.label:focus{color:#fff;cursor:pointer;text-decoration:none}a{text-decoration:none} +.form-item input[type=checkbox] {margin-left:0;position: relative;} +.form-item label {display: inline-block;} +.addoncfg-title{font-size:18px;font-weight:bold;} +.weixin:hover .imged{ position:absolute; left:60px; margin-top: -40px; display:block;border: 5px solid #bfbfbf;border-radius: 6px;} + +/**tip提示***/ +.tip-yellow{z-index:10000;text-align:left;border:1px solid #000;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;padding:6px 8px;min-width:50px;max-width:300px;color:#fff;background-color:#000} +.tip-yellow .tip-inner{font:12px/16px arial,helvetica,sans-serif} +.tip-yellow .tip-arrow-top{margin-top:-6px;margin-left:-5px;top:0;left:50%;width:9px;height:6px;} +.tip-yellow .tip-arrow-right{margin-top:-4px;margin-left:0;top:50%;left:100%;width:6px;height:9px;} +.tip-yellow .tip-arrow-bottom{margin-top:0;margin-left:-5px;top:100%;left:50%;width:9px;height:6px;} +.tip-yellow .tip-arrow-left{margin-top:-4px;margin-left:-6px;top:50%;left:0;width:6px;height:9px;} + +/* 图标替换 */ +.layui-layer-icowst1,.layui-layer-icowst2,.layui-layer-icowst3{background-image:url(../../../../static/images/wst_icon.png)!important;background-repeat:no-repeat!important;background-size:cover!important} +.layui-layer-icowst2{background-position:-40px 0!important} +.layui-layer-icowst3{background-position:-80px -1px!important} +.layui-layer-icowstloading{background-image:url(../../../../static/images/loading.gif)!important;background-repeat:no-repeat!important;background-size:206% auto!important;background-position:-16px -16px!important} +.wst-table-1 th{width: 150px;text-align: right;} + +.typeState li{display: inline-block;} \ No newline at end of file diff --git a/hyhproject/admin/view/css/index.css b/hyhproject/admin/view/css/index.css new file mode 100755 index 0000000..4b5a025 --- /dev/null +++ b/hyhproject/admin/view/css/index.css @@ -0,0 +1,176 @@ +body,html{height:100%;overflow:hidden;} +.layout-boxed body,.layout-boxed html{height:100%} +body{font-family:'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;font-weight:400;font-size:12px;} +.wrapper{height:100%;position:relative;overflow-x:hidden;overflow-y:auto} +.wrapper:after,.wrapper:before{content:" ";display:table} +.wrapper:after{clear:both} +.wrapper:after,.wrapper:before{content:" ";display:table} +.wrapper:after{clear:both} +.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,.5);position:relative} +.layout-boxed{background:url(../img/boxed-bg.jpg) repeat fixed} +.content-wrapper,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:170px;z-index:820} +.layout-top-nav .content-wrapper,.layout-top-nav .main-footer{margin-left:0} +@media (max-width:767px){.content-wrapper,.main-footer{margin-left:0} +} +@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .main-footer{margin-left:0} +} +@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .main-footer{-webkit-transform:translate(160px,0);-ms-transform:translate(160px,0);-o-transform:translate(160px,0);transform:translate(160px,0)} +} +.content-wrapper{min-height:100%;background-color:#ecf0f5;z-index:800} +.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de} +.fixed .left-side,.fixed .main-header,.fixed .main-sidebar{position:fixed} +.fixed .main-header{top:0;right:0;left:0} +.fixed .content-wrapper,.fixed .right-side{padding-top:50px} +@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px} +} +.fixed.layout-boxed .wrapper{max-width:100%} +.fixed .wrapper{overflow:hidden} +.hold-transition .content-wrapper,.hold-transition .left-side,.hold-transition .main-footer,.hold-transition .main-header .logo,.hold-transition .main-header .navbar,.hold-transition .main-sidebar,.hold-transition .menu-open .fa-angle-left,.hold-transition .right-side{-webkit-transition:none;-o-transition:none;transition:none} +.content{height:100%;margin:0 auto;} +.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:'Source Sans Pro',sans-serif} +a{color:#337ab7} +a:active,a:focus,a:hover{outline:0;text-decoration:none;color:#23527c} +.page-header{margin:10px 0 20px 0;font-size:22px} +.page-header>small{color:#666;display:block;margin-top:5px} +.main-header{position:relative;max-height:50px;z-index:1030} +.main-header .navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:170px;border:none;min-height:40px;border-radius:0} +.layout-top-nav .main-header .navbar{margin-left:0} +.main-header #navbar-search-input.form-control{background:rgba(255,255,255,.2);border-color:transparent} +.main-header #navbar-search-input.form-control:active,.main-header #navbar-search-input.form-control:focus{border-color:rgba(0,0,0,.1);background:rgba(255,255,255,.9)} +.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1} +.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc} +.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc} +.main-header .navbar-custom-menu,.main-header .navbar-right{float:right} +@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:0 0} +} +@media (max-width:767px){.main-header .navbar-right{float:none} +.navbar-collapse .main-header .navbar-right{margin:7.5px -15px} +.main-header .navbar-right>li{color:inherit;border:0} +} +.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;font-family:fontAwesome} +.main-header .sidebar-toggle:before{content:"\f0c9"} +.main-header .sidebar-toggle:hover{color:#fff} +.main-header .sidebar-toggle:active,.main-header .sidebar-toggle:focus{background:0 0} +.main-header .sidebar-toggle .icon-bar{display:none} +.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px} +.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9} +.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:170px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;padding:0 15px;font-weight:300;overflow:hidden} +.main-header .logo .logo-lg{display:block;font-weight: bold;font-size: 25px;text-shadow: 3px 3px 7px #000;} +.main-header .logo .logo-lg .logo-txt{font-size:20px;margin-left:2px;height:50px;line-height:50px} +.main-header .logo .logo-mini{display:none;text-shadow: 3px 3px 7px #000;} +.main-header .navbar-brand{color:#fff} +.content-header{position:relative;} +.content-header>h1{margin:0;font-size:24px} +.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300} +.content-header>.breadcrumb{border-bottom:solid 2px #222d32;height:40px;line-height:31px;background:0 0;margin-top:0;margin-bottom:0;font-size:12px;padding:5px 5px;border-radius:2px} +.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block} +.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px} +.content-header>.breadcrumb>li+li:before{content:'>\00a0'} +@media (max-width:991px){.content-header>.breadcrumb{position:relative;top:0;right:0;float:none;background:#d2d6de;padding-left:10px} +.content-header>.breadcrumb li:before{color:#97a0b3} +} +.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px} +@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left} +.navbar-custom-menu .navbar-nav{margin:0;float:left} +.navbar-custom-menu .navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px} +} +@media (max-width:767px){.main-header{position:relative} +.main-header .logo,.main-header .navbar{width:100%;float:none} +.main-header .navbar{margin:0} +.main-header .navbar-custom-menu{float:right} +.navbar .nav-top .top-menu span{display:none;} +} +@media (max-width:991px){.navbar-collapse.pull-left{float:none!important} +.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px} +} +.main-sidebar{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:170px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out} +@media (max-width:767px){.main-sidebar{padding-top:100px} +} +@media (max-width:767px){.main-sidebar{-webkit-transform:translate(-160px,0);-ms-transform:translate(-160px,0);-o-transform:translate(-160px,0);transform:translate(-160px,0)} +} +@media (min-width:768px){.sidebar-collapse .main-sidebar{-webkit-transform:translate(-160px,0);-ms-transform:translate(-160px,0);-o-transform:translate(-160px,0);transform:translate(-160px,0)} +} +@media (max-width:767px){.navbar .nav-top .top-menu span{display:none;}.sidebar-open .main-sidebar{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)} +} +.navbar-nav > .user-menu .user-image {float: left;width: 25px;height: 25px;border-radius: 50%;margin-right: 10px;margin-top: -2px;} +@media (max-width: 767px) {.navbar-nav > .user-menu .user-image {float: none;margin-right: 0;margin-top: -8px;line-height: 10px;}} +.sidebar{padding-bottom:10px} +.sidebar-form input:focus{border-color:transparent} +.user-panel{position:relative;width:100%;padding:20px 10px 20px 10px;overflow:hidden} +.user-panel:after,.user-panel:before{content:" ";display:table} +.user-panel:after{clear:both} +.user-panel:after,.user-panel:before{content:" ";display:table} +.user-panel:after{clear:both} +.user-panel>.image>img{width:100%;max-width:45px;height:auto} +.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px} +.user-panel>.info>p{font-weight:600;margin-bottom:9px} +.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px} +.user-panel>.info>a>.fa,.user-panel>.info>a>.glyphicon,.user-panel>.info>a>.ion{margin-right:3px} +.user-panel>.button{margin-top:10px;} +.sidebar-menu{list-style:none;margin:0;padding:0} +.sidebar-menu>li{position:relative;margin:0;padding:0} +.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block;} +.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px} +.sidebar-menu>li .badge,.sidebar-menu>li .label{margin-right:5px} +.sidebar-menu>li .badge{margin-top:3px} +.sidebar-menu li.header{padding:10px 25px 10px 15px;} +.sidebar-menu li>a>.fa-angle-left,.sidebar-menu li>a>.pull-right-container>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px;-webkit-transition:transform .5s ease;-o-transition:transform .5s ease;transition:transform .5s ease} +.sidebar-menu li>a>.fa-angle-left{position:absolute;top:50%;right:10px;margin-top:-8px} +.sidebar-menu .menu-open>a>.fa-angle-left,.sidebar-menu .menu-open>a>.pull-right-container>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)} +.sidebar-menu .active>.treeview-menu{display:block;} +@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .main-footer,.sidebar-mini.sidebar-collapse .right-side{margin-left:50px!important;z-index:840} +.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0);width:50px!important;z-index:850} +.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative} +.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0} +.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px} +.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px} +.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px} +.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.button,.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.button,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu li.header,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{display:none!important;-webkit-transform:translateZ(0)} +.sidebar-mini.sidebar-collapse .main-header .logo{width:50px} +.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px} +.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none} +.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px} +} +.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>.treeview-menu,.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right){display:block!important;position:absolute;width:160px;left:50px} +.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit} +.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>a>.pull-right-container{position:relative!important;float:right;width:auto!important;left:160px!important;top:-22px!important;z-index:900} +.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>a>.pull-right-container>.label:not(:first-of-type){display:none} +.sidebar-mini:not(.sidebar-mini-expand-feature).sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:40px;margin-left:0} +.sidebar-expanded-on-hover .content-wrapper,.sidebar-expanded-on-hover .main-footer{margin-left:50px} +.sidebar-expanded-on-hover .main-sidebar{box-shadow:3px 0 8px rgba(0,0,0,.125)} +.main-sidebar .user-panel,.sidebar-menu,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden} +.sidebar-menu:hover{overflow:visible} +.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip} +.sidebar-menu li>a{position:relative} +.sidebar-menu li>a>.pull-right-container{position:absolute;right:10px;top:50%;margin-top:0px} +.treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px} +.treeview-menu .treeview-menu{padding-left:20px} +.treeview-menu>li{margin:0} +.treeview-menu>li>a{padding:5px 5px 5px 25px;display:block;color:#b8c7ce;} +.treeview-menu>li>a>.fa,.treeview-menu>li>a>.glyphicon,.treeview-menu>li>a>.ion{width:20px} +.treeview-menu>li>a>.fa-angle-down,.treeview-menu>li>a>.fa-angle-left,.treeview-menu>li>a>.pull-right-container>.fa-angle-down,.treeview-menu>li>a>.pull-right-container>.fa-angle-left{width:auto} + +.main-header>.navbar .nav-top{display:inline;margin-bottom:0px;margin-top:0px;} +.main-header>.navbar .nav-top li{line-height:50px;height:37px;overflow:hidden;list-style:none;display:inline-block;color:#fff;margin-right:20px;} +.main-header>.navbar .nav-top li a{color:#fff;} +.main-header>.navbar .nav-top>li>a>.fa{width:15px;} +.navbar-nav>li>a{padding-top:15px;padding-bottom:15px;font-size: 14px;} +.content-wrapper .content-header button{padding:0px;position: absolute;right: 0px;top:0px;background:#fff;border:0;height:38px;line-height:40px;width:40px;outline:0} +.content-wrapper .content-header button:hover{background:#fafafa} +.content-wrapper .content-header button i{color: #999;} +.dropdown-menu{min-width:120px;box-shadow:#eee;border-color:#eee;} +.dropdown-menu>li>a{font-size:12px;} +.dropdown-menu>li>a>.fa{margin-right:10px;} +/***风格覆盖***/ +.skin-blue .main-header .navbar{background:#2cabe3;} +.skin-blue .main-header .logo{background:#2cabe3;} +.wst-focus{background: rgba(0,0,0,0.1);color: #f6f6f6} + +.edit-pass{display: inline-block;background:#F7FCFF;padding:3px 5px;margin-right:5px;color:#000000;border-radius:4px;} +.logout{display: inline-block;background:#F7FCFF;padding:3px 5px;color:#000000;border-radius:4px;} +.edit-pass:hover{background:#f5f5f5;} +.logout:hover{background:#f5f5f5;} +.edit-pass i,.logout i{color:#000000;margin-right:2px;} +.edit-pass span,.logout span{color:#000000;font-size:12px;} + + diff --git a/hyhproject/admin/view/css/login.css b/hyhproject/admin/view/css/login.css new file mode 100755 index 0000000..61f8665 --- /dev/null +++ b/hyhproject/admin/view/css/login.css @@ -0,0 +1,53 @@ +body{margin:0;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0;font-size:14px;font-family:"微软雅黑",Arial,Helvetica,sans-serif} +#logo{position:absolute;top:5px;left:5px;text-align:center} +.login_logo{margin-left: 23px;width:70px;height:70px;float:left;} +.login_logo img{width:100%;height: 100%;} +#loginFrame{background:url(../img/login_bg.png) #4771a0 no-repeat center center fixed;background-size:cover;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover} + + +/* 图标替换 */ +.layui-layer-icowst1,.layui-layer-icowst2,.layui-layer-icowst3{background-image:url(../../../../static/images/wst_icon.png)!important;background-repeat:no-repeat!important;background-size:cover!important} +.layui-layer-icowst2{background-position:-40px 0!important} +.layui-layer-icowst3{background-position:-80px -1px!important} +.layui-layer-icowstloading{background-image:url(../../../../static/images/loading.gif)!important;background-repeat:no-repeat!important;background-size:206% auto!important;background-position:-16px -16px!important} + +.wst-clear{clear: both;} +.wst-lo{ position: absolute;left: 50%;margin-left: -350px;top: 35%;margin-top: -140px;width: 700px;} +.wst-lo .head{position:absolute;top:-80px;left:27%;width:252px;height:110px;line-height:55px;font-size:20px;color:#fff;font-family:"microsoft yahei";text-shadow:#717070 1px 1px 1px;text-align:center;background:url(../img/logo.png) 0 0 no-repeat;background-size:100%} +.wst-lo-left{float:left;width:235px;height:256px;background-size:cover} +.wst-lo-left img{margin-left:45px} +#verifyImg{ cursor: pointer;width: 108px;border-top-right-radius: 6px;border-bottom-right-radius: 6px;height: 32px;position: absolute;z-index: 100;top:-7px;right: 18px;} + +.login_title{float:right;width:340px;text-align:left;margin-top:4px;color:#fff;} +.login_title .title_cn{font-size:30px;position: relative;} +.login_title .title_en{position: relative;} +.login-wrapper {text-align: center;position:relative; } +.login-wrapper .frame{padding-right:0px;position:relative;} +.login-wrapper .text2{margin-bottom:0;width:222px;} +.login-wrapper .logo {margin-bottom: 45px;position: relative;left: -2px; } +.login-wrapper .boxbg{opacity:0.3;margin: 0 auto;padding: 35px 0 30px;float: none;width: 500px;box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);border-radius: 5px;background: #fff; height:300px;} +.login-wrapper .boxbg2{position:relative;opacity:0.16;margin: 0 auto;padding: 35px 0 30px;float: none;width: 400px;box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.1);border-radius: 5px;background: #fff; height:240px;margin-left:150px;filter:alpha(opacity=16)} +.login-wrapper .box {position:absolute;top:17px;left:162px; margin: 0 auto;padding: 35px 0 30px;float: none;width: 380px; } +.login-wrapper .box .content-wrap {width: 82%;margin: 0 auto; } +.login-wrapper .box h6 {text-transform: uppercase;margin: 0 0 12px 0;font-size: 18px;font-weight: 600; } +.login-wrapper .box input[type="text"], +.login-wrapper .box input[type="password"] { border-radius: 0;font-size: 15px;height:30px;margin-bottom: 10px;border:0;padding-left: 12px;border-bottom:1px solid #244eac;} +.login-wrapper .box input[type="password"] {margin-bottom: 10px; } +.login-wrapper .box input:-moz-placeholder {color: #9ba8b6;font-size: 15px;letter-spacing: 0px;font-style: italic; } +.login-wrapper .box input:-ms-input-placeholder {color: #9ba8b6;font-style: italic;letter-spacing: 0px;font-size: 15px; } +.login-wrapper .box input::-webkit-input-placeholder {color: #9ba8b6;font-style: italic;letter-spacing: 0px;font-size: 15px; } +.login-wrapper .box .login {text-transform: uppercase;font-size: 13px;padding: 8px 30px; } +.login-wrapper .no-account {margin: 0 auto;float: none;text-align: center;font-size: 14px;margin-top: 25px; } +.login-wrapper .no-account p {display: inline-block;color: #eee; } +.login-wrapper .login-box{background-color: #fff;padding: 17px;border-radius: 3px; margin-bottom: 15px; padding-left: 55px;} +.login-head{width:90px;height:90px;background-size:contain;position: absolute;top: 56px; right: 0; } +.login-head img{width:100%;height: 100%;} +.login-icon1,.login-icon2,.login-icon3{width:25px;height:25px;background:url(../img/login_icon.png) no-repeat;position:absolute;} +.login-icon1{top:55px;left:50px;background-position: 0 0;} +.login-icon2{top:95px;left:50px;background-position: 0 -30px;} +.login-icon3{top:136px;left:50px;background-position: 0 -61px;} +.login-header{width:445px;margin:0 auto;margin-bottom:20px;} +.login-footer{color:#fff;width:360px;margin:0 auto;margin-top:30px;position:relative;text-align:center;} +.login-footer .line1{position:absolute;width:95px;font-size:0;line-height:1px;border-bottom:1px solid #fff;top: 10px;left:0; } +.login-footer .line2{position:absolute;width:95px;font-size:0;line-height:1px;border-bottom:1px solid #fff;top: 10px;right:0; } +#loginbtn{background: url(../img/login-btn.png) no-repeat;background-position: -1px -2px;} \ No newline at end of file diff --git a/hyhproject/admin/view/css/skins/skin-blue.min.css b/hyhproject/admin/view/css/skins/skin-blue.min.css new file mode 100755 index 0000000..c2219cd --- /dev/null +++ b/hyhproject/admin/view/css/skins/skin-blue.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a,.skin-blue .sidebar-menu>li.menu-open>a{color:#fff;background:#1e282c}.skin-blue .sidebar-menu>li.active>a{border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .sidebar-menu .treeview-menu>li>a{color:#8aa4af}.skin-blue .sidebar-menu .treeview-menu>li.active>a,.skin-blue .sidebar-menu .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8} \ No newline at end of file diff --git a/hyhproject/admin/view/css/style.css b/hyhproject/admin/view/css/style.css new file mode 100755 index 0000000..94b39b0 --- /dev/null +++ b/hyhproject/admin/view/css/style.css @@ -0,0 +1,207 @@ +@CHARSET "UTF-8"; +body,html{height:100%} +body{padding:0;margin:0;overflow-x:hidden} +.layui-layer-icowst1,.layui-layer-icowst2,.layui-layer-icowst3{background-image:url(../../../../static/images/wst_icon.png)!important;background-repeat:no-repeat!important;background-size:cover!important} +.layui-layer-icowst2{background-position:-40px 0!important} +.layui-layer-icowst3{background-position:-80px -1px!important} +.layui-layer-icowstloading{background-image:url(../../../../static/images/loading.gif)!important;background-repeat:no-repeat!important;background-size:206% auto!important;background-position:-16px -16px!important} +.wst-top-link{display:inline-block;height:26px;line-height:26px;padding-left:10px;text-decoration:none;color:#333} +.wst-link{display:block;height:26px;line-height:26px;padding-left:10px;text-decoration:none;color:#333} +.wst-link:hover{background:#ffeeac} +.wst-space{color:#e7e7e7} +.wst-topmenu{margin:0;padding:0;height:88px;line-height:31px;background:url(../img/img_top_bg.png);position:relative;border-top:1px solid #1d438b} +.wst-topmenu-logo{color:#e7e7e7;padding-left:5px;line-height:26px} +.wst-topmenu-welcome{position:absolute;height:24px;line-height:24px;right:30px;top:2px;color:#070a0c} +.wst-topmenu-welcome a{color:#fff;text-decoration:none} +.wst-topmenu-welcome .website{background:url('../img/icon_topmenu.png') -5px -5px no-repeat;width:15px;height:15px;background-size:700%;display:inline-block} +.wst-topmenu-welcome .selfshop{background:url('../img/icon_topmenu.png') -22px -5px no-repeat;width:15px;height:15px;background-size:700%;display:inline-block} +.wst-topmenu-welcome .support{background:url('../img/icon_topmenu.png') -58px -5px no-repeat;width:16px;height:15px;background-size:700%;display:inline-block} +.wst-topmenu-welcome .clear{background:url('../img/icon_topmenu.png') -38px -5px no-repeat;width:15px;height:15px;background-size:700%;display:inline-block} +.wst-topmenu-welcome .password{background:url('../img/icon_topmenu.png') -69px -5px no-repeat;width:15px;height:15px;background-size:700%;display:inline-block} +.wst-topmenu-welcome .logout{background:url('../img/icon_topmenu.png') -84px -5px no-repeat;width:15px;height:15px;background-size:700%;display:inline-block} +#wst-tabs .l-tab-links{border-bottom:3px solid #157abf} +.l-tab-links{border-bottom:2px solid #157abf} +.l-tab-links{background:0} +.l-tab-links li{background:url("../img/tabs-item-over-bg.gif") repeat scroll 0 0} +.l-tab-links .l-tab-links-item-right{background:url("../img/tabs2-item-right-bg.gif") repeat scroll 0 0} +.l-tab-links .l-tab-links-item-left{background:url("../img/tabs2-item-left-bg.gif") repeat scroll 0 0} +.l-tab-links .l-selected .l-tab-links-item-left{background:url("../img/tabs-item-left-bg.gif") repeat scroll 0 0} +.l-tab-links .l-selected .l-tab-links-item-right{background:url("../img/tabs-item-right-bg.gif") repeat scroll 0 0} +.l-tab-links li.l-selected{background:url("../img/tabs-item-bg.gif") repeat scroll 0 0} +.l-tab-links li a{margin-left:33px} +.l-tab-links li.l-selected a{color:#fff} +#wst-tabs .l-tab-links li a{margin-left:33px;font-weight:bold}#wst-tabs .l-tab-links li.l-selected a{color:#fff;font-weight:bold} +.l-layout-left .l-layout-header-toggle{background:url("../img/togglebar.gif") repeat scroll -20px 0} +.l-layout-header,.l-accordion-header{background:url("../img/layout-header.gif") repeat scroll -20px 0} +.l-layout-header .l-layout-header-inner,.l-accordion-header .l-accordion-header-inner,.l-layout-header{color:#fff} +.l-layout-collapse-left,.l-layout-collapse-right{background:#43aedf} +.l-accordion-toggle{background:url("../img/togglebar.gif") repeat scroll 0 0} +.l-accordion-toggle-open{background-position:0 -40px} +.l-accordion-toggle-close{background-position:0 0} +.body-gray2014 #wst-framecenter{margin-top:3px} +#wst-pageinit{position:absolute;left:0;top:0;width:100%;background:white url('../img/loading.gif') no-repeat centerheight:100%;z-index:99999} +.btn{-moz-user-select:none;background-image:none;border:1px solid #ccc;cursor:pointer;display:inline-block;font-size:14px;font-weight:normal;line-height:1.42857;margin-bottom:0;text-align:center;vertical-align:middle;white-space:nowrap;border-radius:3px;height:24px;line-height:1.2;padding:2px 8px;background:#fafafa none repeat scroll 0 0} +.btn-green{background:#43b97e none repeat scroll 0 0;border-color:green;color:#fff} +.btn-red{background:red none repeat scroll 0 0;border-color:red;color:#fff} +.btn-blue{background:#1d9ed9 none repeat scroll 0 0;border-color:#157abf;color:#fff} +.btn:hover,.btn:focus,.btn:active,.btn.active{background-color:#ddd} +.btn-green:hover,.btn-green:focus,.btn-green:active,.btn-green.active{background-color:green;border-color:green;color:#fff} +.btn-red:hover,.btn-red:focus,.btn-red:active,.btn-red.active{background-color:red;border-color:red;color:#fff} +.btn-blue:hover,.btn-blue:focus,.btn-blue:active,.btn-blue.active{background-color:#428bca;border-color:#428bca;color:#fff} +.btn-disabled{color:#ccc} +.wst-toolbar{padding:5px} +.wst-body{padding:5px} +.wst-footer{padding-bottom:20px;text-align:center} +.f-right{float:right} +.f-left{float:left} +.f-clear{clear:both} +.wst-form{width:100%;margin-bottom:20px} +.wst-form input.cfg,.wst-form input.textarea{width:340px} +.wst-form th{text-align:right} +.wst-form td{padding:2px 5px} +.wst-box-top{margin-top:5px}label{margin-right:10px} +input[type=text],input[type=password]{background-color:#fff;border:1px solid #ccc;color:#222;border-radius:2px;box-shadow:0 1px 1px rgba(0,0,0,0.075) inset;display:inline-block;font-size:14px;height:20px;padding:2px 5px;position:relative;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;vertical-align:middle;width:auto;margin:2px} +textarea{background-color:#fff;background-image:none;border:1px solid #ccc;color:#222;border-radius:2px;box-shadow:0 1px 1px rgba(0,0,0,0.075) inset;display:inline-block;font-size:14px;padding:2px 5px;position:relative;transition:border-color .15s ease-in-out 0s,box-shadow .15s ease-in-out 0s;vertical-align:middle;margin:2px} +select{background-color:#fff;border:1px solid #ccc;border-radius:2px;height:24px;margin:2px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 1px rgba(0,0,0,0.075) inset} +input[type="radio"],input[type="checkbox"]{margin:2px}td.head-ititle{background:url('../img/img_seller_ggjt.png') no-repeat 5px 4px;padding-left:28px;padding-bottom:5px;font-weight:bold} +.webuploader-pick{background:#428bca;height:24px;border-radius:3px;line-height:24px;overflow:hidden} +.webuploader-container{height:24px;overflow:hidden;width:300px} +.l-text{background:white none repeat scroll 0 0;border:1px solid #fff;height:25px;line-height:25px;position:relative;width:160px;margin:2px} +.l-trigger,.l-trigger-hover,.l-trigger-pressed{top:6px} +.l-grid-header{background:#fff url("../img/header-bg.gif") repeat-x scroll left bottom;border-bottom:1px solid #ddd;overflow:hidden;width:100%} +.l-grid-hd-cell{border-right:1px solid #ddd;margin:0;overflow:hidden;padding:0;text-align:center} +.l-grid-row-alt .l-grid-row-cell-rownumbers,.l-selected .l-grid-row-cell-rownumbers,.l-grid-row-over .l-grid-row-cell-rownumbers,.l-grid-row-cell-rownumbers{background:#eee none repeat scroll 0 0} +.l-grid-row-cell{border-bottom:1px dotted #a3bae9;border-right:1px solid #ddd;overflow:hidden;text-align:center}#maingrid{border:1px solid #ddd} +.wst-grid-tree .row-hover{background:#e0ecff} +.wst-grid-tree .row-selected{background:#dcf8a8} +.wst-grid-tree .bg-color{background:#f5f5f5} +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd} +.order-box th{font-weight:normal} +.order-box .goods-head{border-top:2px solid #fc7a64;background:#f3f3f3;display:block;height:25px;line-height:25px;margin:0 0 10px;padding:5px 0} +.order-box .goods-head .goods{float:left;width:650px;padding-left:15px} +.order-box .goods-head .price{float:left;width:100px} +.order-box .goods-head .num{float:left;width:100px} +.order-box .goods-head .t-price{float:left;width:105px} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #fdd8d2;color:#e55356;font-weight:bold;font-size:15px} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eee} +.order-box .item .goods{float:left;width:650px;padding-left:15px} +.order-box .item .goods .img{float:left;width:80px;height:80px} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px} +.order-box .item .price{float:left;width:100px} +.order-box .item .num{float:left;width:100px} +.order-box .item .t-price{float:left;width:100px} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px} +.order-box .line{border-top:1px solid #ddd} +.order-box .goods-summary{margin-top:10px} +.order-box .summary{height:30px;line-height:30px} +.order-box .orderScore{margin-right:5px} +.order-box .log td{height:25px;line-height:25px;padding-left:15px} +.order-box .log-box{height:132px} +.order-box .log-box .icon{float:left;width:60px;height:60px} +.order-box .log-box .icons{float:left;width:60px;height:60px} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat} +.order-box .log-box .arrow{float:left;color:#979797;font-size:15px;font-weight:bold;margin-top:18px} +.order-box .log-box .arrow2{color:#7ebb53} +.order-box .log-box .state{float:left;width:100%;margin-left:18px} +.order-box .log-box .state2{float:left;width:100%;position:relative} +.order-box .log-box .state2 p{float:left;width:178px;height:50px;text-align:left;margin-left:15px;color:#f05858;font-size:15px} +.order-box .log-box .state2 .path{position:absolute;z-index:10} +.order-box .log-box .state2 .path span{float:left;width:178px;height:50px;text-align:left;margin-left:15px;background:#fff} +.recom-lbox{width:350px;height:350px;border:1px solid #ddd;padding:5px;text-align:left;overflow-x:hidden;overflow-y:auto} +.recom-lbox .head,.recom-rbox .head{border-bottom:1px solid #eee} +.recom-lbox .tck,.recom-rbox .tck{float:left;height:30px;overflow:hidden;width:25px} +.recom-lbox .ttxt{float:left;height:30px;overflow:hidden;width:305px} +.recom-lbox .trow{backbgound:#eee;height:30px;overflow:hidden;line-height:30px} +.recom-rbox{width:420px;height:350px;border:1px solid #ddd;padding:5px;text-align:left;overflow-x:hidden;overflow-y:auto} +.recom-rbox .tck{float:left;height:30px;overflow:hidden;width:25px} +.recom-rbox .ttxt{float:left;height:30px;overflow:hidden;width:325px} +.recom-rbox .top{float:left;width:70px} +.recom-rbox .trow{height:30px;overflow:hidden;width:420px;line-height:30px} +.recom-rbox .s-sort{width:20px} +.wst-grid-tree-hd{background:#fff url("../img/header-bg.gif") repeat-x scroll left bottom;border-bottom:1px solid #ddd} +.wstmart-login-tips{border-bottom:1px solid #ddd;box-shadow:0 1px 3px #ddd;line-height:30px;padding-left:10px} +.wstmart-version-tips,.wstmart-accredit-tips{border-bottom:1px solid #ddd;box-shadow:0 1px 3px #ddd;display:none;background:url('../img/ico_5.png') no-repeat;font-weight:bold;height:25px;line-height:23px;padding-left:30px} +.wstmart-version-tips a,.wstmart-accredit-tips a{color:#e9754f} +.wstmart-version-tips a:hover,.wstmart-accredit-tips a:hover{color:#fe9c3d} +.wst-summary{margin:5px;border:1px solid #ddd;margin-bottom:20px;max-width:99%;width:99%;border-collapse:collapse;border-spacing:0} +.wst-summary .wst-summary-head{background:url("../img/img_seller_ggjt.png") no-repeat scroll 5px 7px;font-weight:bold;margin:5px;padding-left:28px} +.wst-summary tr:nth-child(2n){background:#f9f9f9} +.wst-summary td{padding:5px;vertical-align:middle;border:1px solid #ddd} +.wst-summary tr:hover{background:#f9f9f9} +.wst-desc-head{height:25px;line-height:25px;font-weight:bold;margin:5px 5px 2px 5px} +.wst-desc-body{height:20px;line-height:20px;margin-left:5px} +.wst-desc-body a{color:#000;text-decoration:none} +.tbr-m{padding:0 5px 0 5px;height:30px;line-height:30px} +.wst-views{float:left;width:26%;height:60%} +.wst-views .reveal{margin:0 auto;width:68%;height:100%;border:1px solid #e7e7eb;position:relative} +.wst-views .revealt{position:absolute;left:0;top:0;width:100%;height:65px;background:url(../img/img_topinfo.png) 0 0 no-repeat;background-size:100%} +.wst-views .revealb{position:absolute;left:0;bottom:0;width:100%;height:46px;border-top:1px solid #e7e7eb} +.wst-views .revealb i{float:left;width:15%;height:46px;background:url(../img/img_dibu.png) -5px -10px no-repeat} +.wst-views .ui{float:right;width:85%;height:46px;display:-webkit-box} +.wst-views .li{-webkit-box-flex:1;display:block;line-height:46px;text-align:center;border-left:1px solid #e7e7eb;cursor:pointer;position:relative} +.wst-views .li:hover,.wst-views .li .list:hover{background:#eee} +.wst-views .selected{background:#eee} +.wst-views .li .lis{position:absolute;left:0;bottom:46px;width:100%;border:1px solid #e7e7eb} +.wst-views .li .list{float:left;width:100%;border-bottom:1px solid #e7e7eb} +.wst-maingr{float:right;width:72%} +.wst-view{float:left;width:200px;height:200px;background:#eee} +.wst-view a{display:block;height:200px;line-height:200px;text-decoration:none;text-align:center;color:#3295d3} +.wst-view a:hover{color:#56b7f5} +.style-main{padding:10px} +.style-box{width:200px;height:300px;border:1px solid #ddd;padding:5px;margin:5px;float:left} +.style-box .style-img{width:200px;height:200px;text-align:center;vertical-align:middle;display:block;position:relative} +.style-box .style-img a{display:table-cell;vertical-align:middle;width:200px;height:200px;border:1px solid #ddd} +.style-box .style-img a img{max-width:200px;max-height:200px} +.style-box .style-txt,.style-box .style-author,.style-box .style-web{width:200px;height:25px;overflow:hidden;text-align:left;line-height:25px} +.style-box .style-op{height:30px;text-align:center;overflow:hidden} +.nav li a,.nav li a:hover,.nav-list li a,.nav-list li a:hover{display:block;text-decoration:none;outline:0;border-bottom:0 none} +.nav li{float:left} +.tab-wrap{margin-top:10px} +.tab-nav{margin-bottom:15px;padding-left:1px;border-bottom:1px solid #e0e0e0} +.tab-nav li{margin-bottom:-1px;margin-left:-1px} +.tab-nav li a,.tab-nav li a:hover{padding:0 20px;height:35px;line-height:35px;font-weight:bold;font-size:16px;border:1px solid transparent;border-top-width:2px} +.tab-nav .current a,.tab-nav .current a:hover{border-color:#34b4e0 #e0e0e0 #f6f6f6} +.tab-content .tab-pane{display:none} +.tab-content .in{display:block} +.label{border-radius:.25em;color:#fff;display:inline;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:baseline;white-space:nowrap} +a.label:hover,a.label:focus{color:#fff;cursor:pointer;text-decoration:none}a{text-decoration:none} +.label:empty{display:none} +.label-default{background-color:#777} +.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e} +.label-primary{background-color:#428bca} +.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9} +.label-success{background-color:#5cb85c} +.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44} +.label-info{background-color:#5bc0de} +.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5} +.label-warning{background-color:#f0ad4e} +.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f} +.label-danger{background-color:#d9534f} +.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c} +.label-gray{background-color:#e6e6e6} +.label-gray[href]:hover,.label-danger[href]:focus{background-color:#eee} +.line-break{word-break:break-all;word-wrap:break-word} +.order-source{margin:0 5px 0 0;width:18px;height:18px;position:relative;top:5px} +.order-source2{margin:0 5px 0 0;width:16px;height:16px;position:relative;top:5px} + +.wst-tips-box{height: auto;line-height:25px;-moz-border-radius: 5px; -webkit-border-radius: 5px; color:red;border:1px dotted #F0A869;background:#FFFFCC;padding:5px 5px 5px 15px;margin-left:10px;margin-bottom: 5px;margin-top:10px;} +.wst-tips-box .icon{width:20px;height: 20px;float:left;background: url('../img/icon_tstb.png') no-repeat;background-size: 100%} +.wst-tips-box .tips{float: left;padding-left: 5px;} +.line-break{word-break:break-all;word-wrap:break-word;} \ No newline at end of file diff --git a/hyhproject/admin/view/css/tip-yellowsimple_arrows.gif b/hyhproject/admin/view/css/tip-yellowsimple_arrows.gif new file mode 100755 index 0000000..6fac0e6 Binary files /dev/null and b/hyhproject/admin/view/css/tip-yellowsimple_arrows.gif differ diff --git a/hyhproject/admin/view/datas/datas.js b/hyhproject/admin/view/datas/datas.js new file mode 100755 index 0000000..ef1be9d --- /dev/null +++ b/hyhproject/admin/view/datas/datas.js @@ -0,0 +1,241 @@ +var zTree,mmg,rMenu,diff = 0; +function layout(){ + var h = WST.pageHeight(); + var w = WST.pageWidth(); + $('.j-layout').width(w-10); + $('.j-layout-left').width(200).height(h-98); + $('.j-layout-center').width(w-220).height(h-98); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + diff = v?98:53; + $('.j-layout-left').height(h-diff); + $('#menuTree').height(h-diff-40); + $('.j-layout-center').height(h-diff); + if(mmg)mmg.resize({height:h-diff-110}); + }}); +} +function initGrid(id){ + var h = WST.pageHeight(); + var cols = [ + {title:'数据名称', name:'dataName', width: 100}, + {title:'数据值', name:'dataVal' ,width:100}, + {title:'排序号', name:'dataSort' ,width:10}, + {title:'操作', name:'' ,width:60, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.SJGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit(" + item['id'] + ")'><i class='fa fa-pencil'></i>编辑</a> "; + if(WST.GRANT.SJGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['id'] + ","+item['catId']+")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + mmg = $('.mmg').mmGrid({height: (diff==0)?(h-205):(h-diff-110),cols: cols,method:'POST',indexCol: true, + url: WST.U("admin/datas/childQuery"), fullWidthRows: true, autoLoad: false, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.load({id:id}); + $('#m_add').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + editMenu({menuId:0,menuName:'',parentId:treeNode.id,pnode:treeNode,menuSort:0}); + }); + $('#m_edit').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + getForEditMenu(treeNode.id); + return false; + }); + $('#m_del').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + layer.confirm('您确定要删除该菜单['+treeNode.name+']吗?', {btn: ['确定','取消']}, function(){ + var loading = WST.msg('正在提交请求,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datacats/del'),{id:treeNode.id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + zTree.reAsyncChildNodes(treeNode.getParentNode(), "refresh",true); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }); + return false; + }); + isInit = true; +} +var isInit = false; +$(window).resize(function(){layout();}); +$(function(){ + layout(); + $('#menuTree').height(WST.pageHeight()-95); + var setting = { + view: { + selectedMulti: false, + dblClickExpand:false + }, + async: { + enable: true, + url:WST.U('admin/datacats/listQuery'), + autoParam:["id", "name=n", "level=lv"] + }, + callback:{ + onRightClick: onRightClick, + onClick: onClick, + onAsyncSuccess: onAsyncSuccess + } + }; + $.fn.zTree.init($("#menuTree"), setting); + zTree = $.fn.zTree.getZTreeObj("menuTree"); + rMenu = $("#rMenu"); +}); +function loadGrid(id){ + mmg.load({id:id,page:1}); +} +function onAsyncSuccess(event, treeId, treeNode, msg){ + var json = WST.toAdminJson(msg); + if(json && json.id==0){ + var treeNode = zTree.getNodeByTId('menuTree_1'); + zTree.reAsyncChildNodes(treeNode, "refresh",true); + zTree.expandAll(treeNode,true); + } +} +function onClick(e,treeId, treeNode){ + if(treeNode.id>0){ + $('.wst-toolbar').show(); + $('#maingrid').show(); + }else{ + $('.wst-toolbar').hide(); + $('#maingrid').hide(); + } + if(!isInit){ + initGrid(treeNode.id); + }else{ + loadGrid(treeNode.id); + } +} +function onRightClick(event, treeId, treeNode) { + if(!treeNode)return; + if(!WST.GRANT.CDGL_01 && !WST.GRANT.CDGL_02 && !WST.GRANT.CDGL_03)return; + if(!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) { + zTree.cancelSelectedNode(); + showRMenu("root", event.clientX, event.clientY); + }else if(treeNode && !treeNode.noR) { + zTree.selectNode(treeNode); + showRMenu("node", event.clientX, event.clientY); + } +} +function showRMenu(type, x, y) { + $("#rMenu ul").show(); + y += document.body.scrollTop; + x += document.body.scrollLeft; + rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"}); + $("body").bind("mousedown", onBodyMouseDown); +} +function hideRMenu() { + if (rMenu) rMenu.css({"visibility": "hidden"}); + $("body").unbind("mousedown", onBodyMouseDown); +} +function onBodyMouseDown(event){ + if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length>0)) { + rMenu.css({"visibility" : "hidden"}); + } +} +function getForEditMenu(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datacats/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.catId){ + editMenu(json); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function editMenu(obj){ + WST.setValues(obj); + var box = WST.open({ title:(obj.catId==0)?'新增数据分类':"编辑数据分类",type: 1,area: ['430px', '190px'], + content:$('#menuBox'), + btn:['确定','取消'], + end:function(){$('#menuBox').hide();}, + yes: function(index, layero){ + if(!$('#catName').isValid())return; + if(!$('#catCode').isValid())return; + var params = WST.getParams('.ipt2'); + params.catId = obj.catId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datacats/'+((params.catId)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#menuForm')[0].reset(); + treeNode = zTree.getNodeByTId('menuTree_1'); + zTree.reAsyncChildNodes(treeNode, "refresh",true); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datas/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.id){ + WST.setValues(json); + toEdit(json.id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + var title = "新增数据"; + if(id>0){ + title = "编辑数据"; + }else{ + $('#dataForm')[0].reset(); + } + var box = WST.open({title:title,type:1,content:$('#dataBox'),area: ['450px', '240px'],btn:['确定','取消'], + end:function(){$('#dataBox').hide();}, + yes:function(){ + if(!$('#dataName').isValid())return; + if(!$('#dataVal').isValid())return; + var params = WST.getParams('.ipt'); + params.catId = zTree.getSelectedNodes()[0].id; + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datas/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#dataForm')[0].reset(); + layer.close(box); + loadGrid(params.catId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function toDel(id,pid){ + var box = WST.confirm({content:"您确定要删除该数据吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/datas/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/datas/list.html b/hyhproject/admin/view/datas/list.html new file mode 100755 index 0000000..87e46b0 --- /dev/null +++ b/hyhproject/admin/view/datas/list.html @@ -0,0 +1,77 @@ +{extend name="base" /} +{block name="css"} +<link href="__ADMIN__/js/ztree/css/zTreeStyle/zTreeStyle.css?v={$v}" rel="stylesheet" type="text/css" /> +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/ztree/jquery.ztree.all-3.5.js?v={$v}"></script> +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/datas/datas.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要提供系统基础数据元的管理功能,开发者可以在此配置系统的基础选项值。</li> + <li>该功能为开发者功能,普通使用者请勿随意修改,以免影响系统使用。</li> + </ul> +</div> +<div class="j-layout"> + <div class='j-layout-left'> + <div class='j-layout-panel layui-colla-title'>数据分类管理</div> + <ul id="menuTree" class="ztree" style='overflow:auto'></ul> + </div> + <div class='j-layout-center' style='border:1px solid #ccc;float:left;margin-left:5px;'> + <div class='j-layout-panel layui-colla-title'>数据管理</div> + {if WSTGrant('SJGL_01')} + <div class="wst-toolbar" style='display:none'> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style='clear:both'></div> + </div> + {/if} + <div id="maingrid" style='display:none'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> + </div> + </div> +</div> +<div id='menuBox' style='display:none'> +<form id='menuForm'> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>数据分类名称<font color='red'>*</font>:</th> + <td><input type='text' id='catName' class='ipt2' data-rule="数据分类名称: required;"/></td> + </tr> + <tr> + <th width='100'>数据分类代码<font color='red'>*</font>:</th> + <td><input type='text' id='catCode' class='ipt2' data-rule="数据分类代码: required;" /></td> + </tr> + </table> +</form> +</div> +<div id='dataBox' style='display:none'> + <form id='dataForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>数据名称<font color='red'>*</font>:</th> + <td><input type='text' id='dataName' class='ipt' data-rule="数据名称: required;"/></td> + </tr> + <tr> + <th>数据值<font color='red'>*</font>:</th> + <td><input type='text' id='dataVal' class='ipt' data-rule="数据值: required;"/></td> + </tr> + <tr> + <th>排序号<font color='red'> </font>:</th> + <td><input onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" type='text' id='dataSort' class='ipt' /></td> + </tr> + </table> + </form> +</div> +<div id="rMenu"> + <ul> + {if WSTGrant('SJFL_01')}<li id="m_add" >新增分类</li>{/if} + {if WSTGrant('SJFL_02')}<li id="m_edit">编辑分类</li>{/if} + {if WSTGrant('SJFL_03')}<li id="m_del" style='border-bottom:0px;'>删除分类</li>{/if} + </ul> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/ectday/ectday.html b/hyhproject/admin/view/ectday/ectday.html new file mode 100755 index 0000000..923e1b9 --- /dev/null +++ b/hyhproject/admin/view/ectday/ectday.html @@ -0,0 +1,54 @@ +{if !empty($object)} +<form id='editFrom'> +<table class='wst-form'> + <tr> + <td colspan='2' class='head-ititle'>订单信息</td> + </tr> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['transactionId']}</td> + </tr> + <tr> + <th>用户名称:</th> + <td>¥{$object['loginName']}</td> + </tr> + <tr> + <th>ECT发送方:</th> + <td>{$object['fromAccount']}</td> + </tr> + <tr> + <th>ECT接收方:</th> + <td>{$object['toAccount']}</td> + </tr> + <tr> + <th>备注:</th> + <td>{$object['dataRemarks']}</td> + </tr> + <tr> + <th>ECT数量:</th> + <td>{$object['ectNum']}</td> + </tr> + <tr> + <th>创建时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <th width='120'>管理员意见:</th> + <td> + <label><input type='radio' {if $object['status']==1} checked{/if} onclick='WST.showHide(0,"#tr")' name='status' id='refundStatus1' value='1'/>同意</label> + <label style='margin-left:15px;'><input type='radio' {if $object['status']==2} checked{/if} onclick='WST.showHide(1,"#tr")' name='status' id='refundStatus0' value='2'/>不同意</label> + </td> + </tr> + <tr> + <td colspan='2' style='text-align:center;padding-top:30px;'> + <button type="button" class="btn btn-primary btn-mright" onclick="javascript:toEcttarget({$object['id']})"><i class="fa fa-check"></i>确&nbsp;&nbsp;定</button> + <button type="button" class="btn" onclick='javascript:layer.close(w)'><i class="fa fa-angle-double-left"></i>取&nbsp;&nbsp;消</button> + </td> + </tr> +</table> +</form> +{else} +<div style='color:red;margin:20px;'> +该订单不存在或已退款。 +</div> +{/if} diff --git a/hyhproject/admin/view/ectday/ectday.js b/hyhproject/admin/view/ectday/ectday.js new file mode 100755 index 0000000..ccd48d6 --- /dev/null +++ b/hyhproject/admin/view/ectday/ectday.js @@ -0,0 +1,87 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'会员名称', name:'loginName' ,width:100,sortable: true}, + {title:'ECT返还数量', name:'ectNum' ,width:40,sortable: true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'交易时间', name:'giveTime' ,width:60,sortable: true,renderer:function(val,item,rowIndex){ + var today=new Date(parseInt(item['giveTime'])*1000); + var y=today.getFullYear(); + var m=today.getMonth()+1; + var d=today.getDate(); + var h=today.getHours(); + var i=today.getMinutes(); + var s=today.getSeconds(); + return (y+"-"+m+"-"+d+" "+h+":"+i+":"+s); + }}, + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/ectday/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + remoteSort:true , + sortName: 'ectNo', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} +function toView(loginName){ + location.href=WST.U('admin/ectdeal/index','loginName='+loginName); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/ectday/toExport',params); + }}); +} +function toHandle(id){ + var ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/ectday/toHandle',{id:id}),{},function(data){ + layer.close(ll); + w =WST.open({type: 1,title:"订单退款",shade: [0.6, '#000'],offset:'50px',border: [0],content:data,area: ['550px', '380px']}); + }); +} +function toEcttarget(id){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = {}; + params.status = $('#refundStatus1')[0].checked?1:2; + params.id = id; + ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/ectday/ectTarget'),params,function(data){ + layer.close(ll); + var json = WST.toAdminJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + loadGrid(); + layer.close(w); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }) +} \ No newline at end of file diff --git a/hyhproject/admin/view/ectday/list.html b/hyhproject/admin/view/ectday/list.html new file mode 100755 index 0000000..c59e45d --- /dev/null +++ b/hyhproject/admin/view/ectday/list.html @@ -0,0 +1,39 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/ectday/ectday.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于处理来自于会员(商家)的提现请求。提现通过后系统会扣除会员(商家)的钱包金额。</li> + <li>本功能只扣除本系统的会员(商家)钱包金额,实际上的资金转账需平台线下操作。</li> + </ul> +</div> +<div class="wst-toolbar"> + <input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> + 至 + <input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + <input type="text" name="loginName" placeholder='用户名称' id="loginName" class='j-ipt' value="{$Request.param.loginName}"/> + <button class="btn btn-primary" id="search" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:history.back()'><i class="fa fa-sign-in"></i>返回</button> + <!--<button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button>--> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); + if($("#loginName").val()!=""){ + $("#search").click(); + } +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/ectdeal/ectdeal.js b/hyhproject/admin/view/ectdeal/ectdeal.js new file mode 100755 index 0000000..a06a830 --- /dev/null +++ b/hyhproject/admin/view/ectdeal/ectdeal.js @@ -0,0 +1,94 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'ECT交易ID', name:'ectId', width: 100,sortable: true}, + {title:'会员名称', name:'loginName' ,width:100,sortable: true}, + {title:'ECT获取方式', name:'dataSrc' ,width:60,sortable: true,renderer:function(val,item,rowIndex){ + if(item['dataSrc']=="1"){ + return '注册'; + }else if(item['dataSrc']=="2"){ + return "推荐"; + }else if(item['dataSrc']=="3"){ + return "交易"; + }else if(item['dataSrc']=="4"){ + return "提现"; + }else if(item['dataSrc']=="5"){ + return "联盟积分转换"; + }else if(item['dataSrc']=="6"){ + return "成为商家"; + }else if(item['dataSrc']=="7"){ + return "推荐成为商家"; + }else if(item['dataSrc']=="8"){ + return "成为线上商城商家"; + }else if(item['dataSrc']=="9"){ + return "推荐成为线上商城商家"; + }else if(item['dataSrc']=="10"){ + return ""; + }else if(item['dataSrc']=="11"){ + return "购物"; + }else if(item['dataSrc']=="12"){ + return "结算"; + }else if(item['dataSrc']=="13"){ + return "退款"; + }else if(item['dataSrc']=="14"){ + return "充值"; + }else { + return ""; + } + }}, + {title:'备注', name:'dataRemarks' ,width:40,sortable: true}, + {title:'ECT变动数量', name:'ectNum' ,width:40,sortable: true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'创建时间', name:'createTime' ,width:40,sortable: true,renderer:function(val,item,rowIndex){ + var today=new Date(parseInt(item['createTime'])*1000); + var y=today.getFullYear(); + var m=today.getMonth()+1; + var d=today.getDate(); + var h=today.getHours(); + var i=today.getMinutes(); + var s=today.getSeconds(); + return (y+"-"+m+"-"+d+" "+h+":"+i+":"+s); + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/ectdeal/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + remoteSort:true , + sortName: 'ectNo', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); + mmg.on('loadSuccess',function(e,data){ + if(data.items[0].sumEct!=undefined){ + $('#sunNum').text(data.items[0].sumEct); + } + if(data.items[0].sumCashEct!=undefined){ + $('#sumCashEct').text(data.items[0].sumCashEct); + } + if(data.items[0].sumCashChong!=undefined){ + $('#sumCashChong').text(data.items[0].sumCashChong); + } + }) +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} \ No newline at end of file diff --git a/hyhproject/admin/view/ectdeal/list.html b/hyhproject/admin/view/ectdeal/list.html new file mode 100755 index 0000000..d11be54 --- /dev/null +++ b/hyhproject/admin/view/ectdeal/list.html @@ -0,0 +1,43 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/ectdeal/ectdeal.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于查看会员以及商户获取ECT途径</li> + </ul> +</div> +<div class="wst-toolbar"> + <input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> + 至 + <input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + + <input type="text" name="loginName" placeholder='会员名称' id="loginName" class='j-ipt' value="{$Request.param.loginName}"/> + <button class="btn btn-primary" id="search" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <span style="font-size: 14px;margin-left: 50px;">ect结算总金额: <span id="sunNum"></span></span> + <span style="font-size: 14px;margin-left: 50px;">ect提现总金额: <span id="sumCashEct"></span></span> + <span style="font-size: 14px;margin-left: 50px;">ect充值总金额: <span id="sumCashChong"></span></span> + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:history.back()'><i class="fa fa-sign-in"></i>返回</button> + + <!-- <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> --> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); + if($('#loginName').val()!=''){ + $('#search').click(); + } +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/ecttarget/ecttarget.html b/hyhproject/admin/view/ecttarget/ecttarget.html new file mode 100755 index 0000000..923e1b9 --- /dev/null +++ b/hyhproject/admin/view/ecttarget/ecttarget.html @@ -0,0 +1,54 @@ +{if !empty($object)} +<form id='editFrom'> +<table class='wst-form'> + <tr> + <td colspan='2' class='head-ititle'>订单信息</td> + </tr> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['transactionId']}</td> + </tr> + <tr> + <th>用户名称:</th> + <td>¥{$object['loginName']}</td> + </tr> + <tr> + <th>ECT发送方:</th> + <td>{$object['fromAccount']}</td> + </tr> + <tr> + <th>ECT接收方:</th> + <td>{$object['toAccount']}</td> + </tr> + <tr> + <th>备注:</th> + <td>{$object['dataRemarks']}</td> + </tr> + <tr> + <th>ECT数量:</th> + <td>{$object['ectNum']}</td> + </tr> + <tr> + <th>创建时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <th width='120'>管理员意见:</th> + <td> + <label><input type='radio' {if $object['status']==1} checked{/if} onclick='WST.showHide(0,"#tr")' name='status' id='refundStatus1' value='1'/>同意</label> + <label style='margin-left:15px;'><input type='radio' {if $object['status']==2} checked{/if} onclick='WST.showHide(1,"#tr")' name='status' id='refundStatus0' value='2'/>不同意</label> + </td> + </tr> + <tr> + <td colspan='2' style='text-align:center;padding-top:30px;'> + <button type="button" class="btn btn-primary btn-mright" onclick="javascript:toEcttarget({$object['id']})"><i class="fa fa-check"></i>确&nbsp;&nbsp;定</button> + <button type="button" class="btn" onclick='javascript:layer.close(w)'><i class="fa fa-angle-double-left"></i>取&nbsp;&nbsp;消</button> + </td> + </tr> +</table> +</form> +{else} +<div style='color:red;margin:20px;'> +该订单不存在或已退款。 +</div> +{/if} diff --git a/hyhproject/admin/view/ecttarget/ecttarget.js b/hyhproject/admin/view/ecttarget/ecttarget.js new file mode 100755 index 0000000..88acd9e --- /dev/null +++ b/hyhproject/admin/view/ecttarget/ecttarget.js @@ -0,0 +1,150 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'ECT交易ID', name:'transactionId', width: 100,sortable: true}, + {title:'会员名称', name:'loginName' ,width:100,sortable: true}, + {title:'ECT发送方', name:'fromAccount' ,width:60,sortable: true}, + {title:'ECT接收方', name:'toAccount' ,width:40,sortable: true}, + {title:'备注', name:'dataRemarks' ,width:40,sortable: true}, + {title:'ECT提现数量', name:'ectNum' ,width:40,sortable: true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'创建时间', name:'createTime' ,width:60,sortable: true,renderer:function(val,item,rowIndex){ + var today=new Date(parseInt(item['createTime'])*1000); + var y=today.getFullYear(); + var m=today.getMonth()+1; + var d=today.getDate(); + var h=today.getHours(); + var i=today.getMinutes(); + var s=today.getSeconds(); + return (y+"-"+m+"-"+d+" "+h+"-"+i+"-"+s); + }}, + {title:'状态', name:'status' ,width:50,renderer: function (val,item,rowIndex){ + if(item['status']==1){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已同意</span>"; + }else if(item['status']==2){ + return "<span class='statu-no'><i class='fa fa-check-circle'></i> 未同意</span>"; + }else{ + return "<span class='statu-no'><i class='fa fa-ban'></i>未审核</span>"; + } + }}, + {title:'操作', name:'op' ,width:180, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += '<a class="btn btn-blue" href="javascript:toView(\'' + item['loginName'] + '\');"><i class="fa fa-search"></i>查看记录</a> '; + h += '<a class="btn btn-blue" href="javascript:toEctDay(\'' + item['loginName'] + '\');"><i class="fa fa-search"></i>查看返还</a> '; + if(item['status']==0){ + h += "<a class='btn btn-blue' href='javascript:toHandle(" + item['id'] + ")'><i class='fa fa-pencil'></i>处理</a> "; + } + + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/ecttarget/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + remoteSort:true , + sortName: 'ectNo', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); + mmg.on('loadSuccess',function(e,data){ + if(data.items[0].sumEct!=undefined){ + $('#sunNum').text(data.items[0].sumEct); + } + }) +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} +function toView(loginName){ + location.href=WST.U('admin/ectdeal/index','loginName='+loginName); +} +function toEctDay(loginName){ + location.href=WST.U('admin/ectday/index','loginName='+loginName); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/ecttarget/toExport',params); + }}); +} +function toHandle(id){ + var ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/ecttarget/toHandle',{id:id}),{},function(data){ + layer.close(ll); + w =WST.open({type: 1,title:"ECT提现操作",shade: [0.6, '#000'],offset:'50px',border: [0],content:data,area: ['550px', '380px']}); + }); +} +var click =false; +function toEcttarget(id){ + if (click==true) return; + $('#editFrom').isValid(function(v){ + if(v){ + var params = {}; + params.status = $('#refundStatus1')[0].checked?1:2; + params.id = id; + ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/ecttarget/ectTarget'),params,function(data){ + + var json = WST.toAdminJson(data); + if(json.status==1){ + if(params.status == 1){ + $.ajax({ + url: "http://moacapi.juzi199.com/api/ect/ect_transfer", + type: "POST", + data:{ + 'id':id + }, + dataType: "jsonp", //指定服务器返回的数据类型 + success: function (ect_data) { + var json = WST.toAdminJson(ect_data); + //console.log(json); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + }else{ + alert(json.msg); + } + click=true; + loadGrid(); + layer.close(ll); + layer.close(w); + } + }); + }else{ + WST.msg('拒绝'+json.msg, {icon: 2}); + loadGrid(); + layer.close(w); + click=true; + } + + + }else{ + + WST.msg(json.msg, {icon: 2}); + layer.close(w); + click=true; + } + }); + } + }) +} \ No newline at end of file diff --git a/hyhproject/admin/view/ecttarget/list.html b/hyhproject/admin/view/ecttarget/list.html new file mode 100755 index 0000000..bd1ad23 --- /dev/null +++ b/hyhproject/admin/view/ecttarget/list.html @@ -0,0 +1,37 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/ecttarget/ecttarget.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于处理来自于会员(商家)的提现请求。提现通过后系统会扣除会员(商家)的钱包金额。</li> + <li>本功能只扣除本系统的会员(商家)钱包金额,实际上的资金转账需平台线下操作。</li> + </ul> +</div> +<div class="wst-toolbar"> + <input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> + 至 + <input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + <input type="text" name="ectNo" placeholder='交易ID' id="ectNo" class='j-ipt'/> + <input type="text" name="loginName" placeholder='会员名称' id="loginName" class='j-ipt'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <!-- <span style="font-size: 14px;margin-left: 50px;">ect提现总金额: <span id="sunNum"></span></span> --> + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/enter_license.html b/hyhproject/admin/view/enter_license.html new file mode 100755 index 0000000..157d762 --- /dev/null +++ b/hyhproject/admin/view/enter_license.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/js/license.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} + </head> + <body> + <body> + <form id='editFrom' name="editFrom" method="post" id="myform" autocomplete="off"> + <table class="wst-form" style='margin-top:30px;'> + <tr> + <th align='right'>授权域名 <font color='red'>*</font>:</th> + <td> + {:request()->root(true)} + </td> + </tr> + <tr> + <th align='right' width='150'>授权码 <font color='red'>*</font>:</th> + <td> + <input type='text' id='license' name='license' style='width:400px;' data-rule="授权码: required;"/> + </td> + </tr> + <tr id='licenseTr' style='display:none'> + <th align='right'>授权状态 :</th> + <td id='licenseStatus' style='color:red;'></td> + </tr> + <tr> + <td colspan='2' style='padding-left:250px;padding-top:15px;'> + <button type="button" class="btn btn-primary btn-mright" onclick='edit()'>提&nbsp;交</button> + <button type="reset" class="btn">重&nbsp;置</button> + </td> + </tr> + </table> + </form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/express/express.js b/hyhproject/admin/view/express/express.js new file mode 100755 index 0000000..020746c --- /dev/null +++ b/hyhproject/admin/view/express/express.js @@ -0,0 +1,156 @@ +var mmg; +function initGrid(staffId){ + var h = WST.pageHeight(); + var cols = [ + {title:'图标', name:'expressImg' ,width:50, align:'center', renderer: function(val,item,rowIndex){ + return '<img src="'+WST.conf.IMGURL+'/'+item['expressImg']+'" height="28px" />'; + }}, + {title:'快递名称', name:'expressName', width: 160}, + {title:'快递代码', name:'expressCode' ,width:60}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.KDGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit(" + item['expressId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.KDGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['expressId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-155),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/express/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-155}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/express/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/express/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.expressId){ + WST.setValues(json); + //显示原来的图片 + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.expressImg+'" height="75px" />'); + $('#isImg').val('ok'); + toEdit(json.expressId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + if(!isInitUpload){ + initUpload(); + } + var title = "新增"; + if(id>0){ + title = "编辑"; + }else{ + $('#expressForm')[0].reset(); + } + var box = WST.open({title:title,type:1,content:$('#expressBox'),area: ['450px', '400px'],btn:['确定','取消'], + end:function(){ + $('#expressBox').hide(); + //重置表单 + $('#expressForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#expressImg').val(''); + },yes:function(){ + $('#expressForm').submit(); + },cancel:function(){ + //重置表单 + $('#expressForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#expressImg').val(''); + }}); + $('#expressForm').validator({ + fields: { + expressName: { + rule:"required;", + msg:{required:"快递名称不能为空"}, + tip:"请输入快递名称", + ok:"", + }, + expressImg: { + rule:"required;", + msg:{required:"请上传图标"}, + tip:"请上传图标", + ok:"", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.expressId = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/express/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#expressForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#expressImg').val(''); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + + }); + +} +var isInitUpload = false; +function initUpload(){ + isInitUpload = true; + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'accreds'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#expressImg').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/express/list.html b/hyhproject/admin/view/express/list.html new file mode 100755 index 0000000..05f190d --- /dev/null +++ b/hyhproject/admin/view/express/list.html @@ -0,0 +1,59 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/express/express.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} +{block name="main"} +{if WSTGrant('KDGL_01')} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于管理快递公司的信息。快递代码主要用于物流插件的快递识别查询,填写时请参照各物流插件的快递代码填写。</li> + </ul> +</div> +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +{/if} +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='expressBox' style='display:none'> + <form id='expressForm' autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>快递名称<font color='red'>*</font>:</th> + <td><input type='text' id='expressName' name="expressName" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th width='100'>快递代码:</th> + <td><input type='text' id='expressCode' name="expressCode" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <td colspan="2" style="padding-left: 35px;">快递代码是用于物流查询,请查询所启用插件的快递代码</td> + </tr> + <tr> + <th>图标:</th> + <td> + <div id='adFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='expressImg' name="expressImg" class="ipt" /> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:70px;" id="preview"></div></td> + </tr> + </table> + </form> + </div> +<script> + $(function(){initGrid()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/friendlinks/friendlinks.js b/hyhproject/admin/view/friendlinks/friendlinks.js new file mode 100755 index 0000000..7fe08c0 --- /dev/null +++ b/hyhproject/admin/view/friendlinks/friendlinks.js @@ -0,0 +1,154 @@ +var mmg,isInitUpload = false; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'网站名称', name:'friendlinkName', width: 80}, + {title:'网址', name:'friendlinkUrl' ,width:100}, + {title:'图标', name:'friendlinkIco' ,width:30,renderer:function(val,item,rowIndex){ + if(item['friendlinkIco']){ + return '<img src="'+WST.conf.IMGURL+'/'+item['friendlinkIco']+'" height="28px" />'; + }else{ + return ""; + } + }}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.YQGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit("+item['friendlinkId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.YQGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['friendlinkId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/Friendlinks/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function initUpload(){ + //文件上传 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'friendlinks'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#friendlinkIco').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/friendlinks/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/friendlinks/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.friendlinkId){ + WST.setValues(json); + //显示原来的图片 + if(json.friendlinkIco!=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.friendlinkIco+'" height="70px" />'); + }else{ + $('#preview').empty(); + } + toEdit(json.friendlinkId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + if(!isInitUpload){ + isInitUpload = true; + initUpload(); + } + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#friendlinkBox'),area: ['450px', '350px'],btn: ['确定','取消'], + yes:function(){ + $('#friendlinkForm').submit(); + },cancel:function(){ + $('#friendlinkBox').hide(); + //重置表单 + $('#friendlinkForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#friendlinkIco').val(''); + },end:function(){ + $('#friendlinkBox').hide(); + //重置表单 + $('#friendlinkForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#friendlinkIco').val(''); + + }}); + $('#friendlinkForm').validator({ + fields: { + friendlinkName: { + rule:"required;", + msg:{required:"网站名称不能为空"}, + tip:"请输入网站名称", + ok:"", + }, + friendlinkUrl: { + rule: "required;", + msg: {required: "网址不能为空"}, + tip: "请输入网址", + ok: "", + } + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.friendlinkId = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/friendlinks/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#friendlinkBox').hide(); + $('#friendlinkForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#friendlinkIco').val(''); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} diff --git a/hyhproject/admin/view/friendlinks/list.html b/hyhproject/admin/view/friendlinks/list.html new file mode 100755 index 0000000..c2ff6bd --- /dev/null +++ b/hyhproject/admin/view/friendlinks/list.html @@ -0,0 +1,60 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/friendlinks/friendlinks.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} + +{block name="main"} +{if WSTGrant('YQGL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='friendlinkBox' style='display:none'> + <form id='friendlinkForm' method="post" autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>网站名称<font color='red'>*</font>:</th> + <td><input type='text' id='friendlinkName' name="friendlinkName" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th width='100'>图标:</th> + <td> + <div id='adFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='friendlinkIco' class='ipt'/> + </td> + </tr> + <tr> + <th width='100'>预览图:</th> + <td> + <div style="min-height:70px;" id="preview"></div> + </td> + </tr> + <tr> + <th width='100'>网址<font color='red'>*</font>:</th> + <td><input type='text' id='friendlinkUrl' name="friendlinkUrl" class='ipt' maxLength='120'/></td> + </tr> + <tr> + <th width='100'>网站排序号:</th> + <td><input type='text' id='friendlinkSort' class='ipt' maxLength='20'/></td> + </tr> + + </table> + </form> + + </div> +<script> +$(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/goods/goods.js b/hyhproject/admin/view/goods/goods.js new file mode 100755 index 0000000..1eefd26 --- /dev/null +++ b/hyhproject/admin/view/goods/goods.js @@ -0,0 +1,285 @@ +var mmg; + +function initSaleGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb+"/thumb80" + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'商品ID', name:'goodsId' ,width:60,sortable:true}, + {title:'商品名称', name:'goodsName', width: 120,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'商品编号', name:'goodsSn' ,width:60,sortable:true}, + {title:'价格', name:'shopPrice' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return '¥'+item['shopPrice']; + }}, + {title:'优惠率', name:'discountRate' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return item['discountRate']+'%'; + }}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + {title:'店铺电话', name:'phone' ,width:60,sortable:true}, + {title:'申请上架时间', name:'saleTime' ,width:60,sortable:true}, + {title:'审核通过时间', name:'createTime' ,width:60,sortable:true}, + {title:'所属分类', name:'goodsCatName' ,width:60,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatName']+"</p></span>"; + }}, + + {title:'销量', name:'saleNum' ,width:20,sortable:true,align:'center'}, + {title:'状态', name:'isSale' ,width:30,renderer: function (val,item,rowIndex){ + if(item['isSale']==1){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已上架</span>"; + }else{ + return "<span class='statu-no'><i class='fa fa-ban'></i>已下架</span>"; + } + }}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + // h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; +// h += "<a class='btn btn-red' href='javascript:toPay(" + item['goodsId'] + ",1)'><i class='fa fa-ban'></i>添加ECT支付</a> "; + if(WST.GRANT.SJSP_04)h += "<a class='btn btn-red' href='javascript:illegal(" + item['goodsId'] + ",1)'><i class='fa fa-ban'></i>违规下架</a> "; + if(WST.GRANT.SJSP_03)h += "<a class='btn btn-red' href='javascript:del(" + item['goodsId'] + ",1)'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goods/saleByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.goodsCatIdPath = WST.ITGetAllGoodsCatVals('cat_0','pgoodsCats').join('_'); + params.page = 1; + mmg.load(params); +} + +function toPay(id,type){ + var box = WST.confirm({content:"您确定要添加ECT支付吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goods/goodsEct'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function toExportSale(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/goods/toExportSale',params); + }}); +} +function del(id,type){ + var box = WST.confirm({content:"您确定要删除该商品吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goods/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function illegal(id,type){ + var w = WST.open({type: 1,title:((type==1)?"商品违规原因":"商品不通过原因"),shade: [0.6, '#000'],border: [0], + content: '<textarea id="illegalRemarks" rows="7" style="width:100%" maxLength="200"></textarea>', + area: ['500px', '260px'],btn: ['确定', '关闭窗口'], + yes: function(index, layero){ + var illegalRemarks = $.trim($('#illegalRemarks').val()); + if(illegalRemarks==''){ + WST.msg(((type==1)?'请输入违规原因 !':'请输入不通过原因!'), {icon: 5}); + return; + } + var ll = WST.msg('数据处理中,请稍候...'); + $.post(WST.U('admin/goods/illegal'),{id:id,illegalRemarks:illegalRemarks},function(data){ + layer.close(w); + layer.close(ll); + var json = WST.toAdminJson(data); + if(json.status>0){ + WST.msg(json.msg, {icon: 1}); + loadGrid(); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); +} + +function initAuditGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'商品ID', name:'goodsId' ,width:30,sortable:true}, + {title:'&nbsp;', name:'goodsName', width: 30, renderer: function(val,item,rowIndex){ + return "<span class='weixin'><img class='img' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'><img class='imged' style='height:200px;width:200px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span>"; + }}, + {title:'商品名称', name:'goodsName', width: 160,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'商品编号', name:'goodsSn' ,width:60,sortable:true}, + {title:'价格', name:'shopPrice' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return '¥'+item['shopPrice']; + }}, + {title:'优惠率', name:'discountRate' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return item['discountRate']+'%'; + }}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + {title:'店铺电话', name:'phone' ,width:60,sortable:true}, + {title:'所属分类', name:'goodsCatName' ,width:60,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatName']+"</p></span>"; + }}, + {title:'销量', name:'saleNum' ,width:20,sortable:true,align:'center'}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + // h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId']+"&key="+item['verfiycode'])+"'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.DSHSP_04)h += "<a class='btn btn-blue' href='javascript:allow(" + item['goodsId'] + ",0)'><i class='fa fa-check'></i>审核通过</a> "; + if(WST.GRANT.DSHSP_04)h += "<a class='btn btn-red' href='javascript:illegal(" + item['goodsId'] + ",0)'><i class='fa fa-ban'></i>审核不通过</a> "; + if(WST.GRANT.DSHSP_03)h += "<a class='btn btn-red' href='javascript:del(" + item['goodsId'] + ",0)'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:40, cols: cols,method:'POST',checkCol:true,multiSelect:true, + url: WST.U('admin/goods/auditByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +// 批量审核通过 +function toBatchAllow(){ + var rows = mmg.selectedRows(); + if(rows.length==0){ + WST.msg('请选择商品',{icon:2}); + return; + } + var ids = []; + for(var i=0;i<rows.length;i++){ + ids.push(rows[i]['goodsId']); + } + + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goods/batchAllow'),{ids:ids.join(',')},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +// 批量审核不通过 +function toBatchIllegal(){ + var rows = mmg.selectedRows(); + if(rows.length==0){ + WST.msg('请选择商品',{icon:2}); + return; + } + var ids = []; + for(var i=0;i<rows.length;i++){ + ids.push(rows[i]['goodsId']); + } + // 先显示弹出框,让用户输入审核不通原因 + var w = WST.open({type: 1,title:"商品不通过原因",shade: [0.6, '#000'],border: [0], + content: '<textarea id="illegalRemarks" rows="7" style="width:96%" maxLength="200"></textarea>', + area: ['500px', '260px'],btn: ['确定', '关闭窗口'], + yes: function(index, layero){ + var illegalRemarks = $.trim($('#illegalRemarks').val()); + if(illegalRemarks==''){ + WST.msg('请输入不通过原因!', {icon: 5}); + return; + } + var ll = WST.msg('数据处理中,请稍候...'); + $.post(WST.U('admin/goods/batchIllegal'),{ids:ids.join(','),illegalRemarks:illegalRemarks},function(data){ + layer.close(w); + layer.close(ll); + var json = WST.toAdminJson(data); + if(json.status>0){ + WST.msg(json.msg, {icon: 1}); + loadGrid(); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + + +} + +function allow(id,type){ + var box = WST.confirm({content:"您确定审核通过该商品吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goods/allow'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function initIllegalGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsName', width: 30, renderer: function(val,item,rowIndex){ + return "<span class='weixin'><img class='img' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'><img class='imged' style='height:200px;width:200px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span>"; + }}, + {title:'商品名称', name:'goodsName', width: 100,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'商品编号', name:'goodsSn' ,width:60,sortable:true}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + {title:'所属分类', name:'goodsCatName' ,width:60,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'违规原因', name:'illegalRemarks' ,width:160}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId']+"&key="+item['verfiycode'])+"'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.WGSP_04)h += "<a class='btn btn-blue' href='javascript:allow(" + item['goodsId'] + ",0)'><i class='fa fa-check'></i>审核通过</a> "; + if(WST.GRANT.WGSP_03)h += "<a class='btn btn-red' href='javascript:del(" + item['goodsId'] + ",0)'><i class='fa fa-trash-o'></i>删除</a></div> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goods/illegalByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toolTip(){ + WST.toolTip(); +} diff --git a/hyhproject/admin/view/goods/list_audit.html b/hyhproject/admin/view/goods/list_audit.html new file mode 100755 index 0000000..ee84a8e --- /dev/null +++ b/hyhproject/admin/view/goods/list_audit.html @@ -0,0 +1,41 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goods/goods.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt hide'/> +<select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} +</select> +<input type="text" name="goodsName" placeholder='商品名称/商品编号' id="goodsName" class='j-ipt'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + +{if WSTGrant('DSHSP_04')} +<button class="btn btn-danger f-right" onclick='javascript:toBatchIllegal()' style='margin-left:10px;'><i class='fa fa-ban'></i>批量不通过</button> +<button class="btn btn-success f-right" onclick='javascript:toBatchAllow()' style='margin-left:10px;'><i class='fa fa-check'></i>批量通过</button> +{/if} + +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initAuditGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goods/list_illegal.html b/hyhproject/admin/view/goods/list_illegal.html new file mode 100755 index 0000000..6d4acfb --- /dev/null +++ b/hyhproject/admin/view/goods/list_illegal.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goods/goods.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt hide'/> +<select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} +</select> +<input type="text" name="goodsName" placeholder='商品名称/商品编号' id="goodsName" class='j-ipt'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg layui-form"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initIllegalGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goods/list_sale.html b/hyhproject/admin/view/goods/list_sale.html new file mode 100755 index 0000000..4c20f22 --- /dev/null +++ b/hyhproject/admin/view/goods/list_sale.html @@ -0,0 +1,51 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goods/goods.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt hide'/> +<select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} +</select> +<input type="text" name="goodsName" placeholder='商品名称/商品编号' id="goodsName" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExportSale()'><i class="fa fa-sign-in"></i>导出</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +$(function(){initSaleGrid();}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goods/list_shelves.html b/hyhproject/admin/view/goods/list_shelves.html new file mode 100755 index 0000000..3760676 --- /dev/null +++ b/hyhproject/admin/view/goods/list_shelves.html @@ -0,0 +1,95 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goods/goods.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt hide'/> +<select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} +</select> +<input type="text" name="goodsName" placeholder='商品名称/商品编号' id="goodsName" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + function initShelvesGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb+"/thumb80" + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'商品名称', name:'goodsName', width: 120,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'商品编号', name:'goodsSn' ,width:60,sortable:true}, + {title:'价格', name:'shopPrice' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return '¥'+item['shopPrice']; + }}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + {title:'申请上架时间', name:'saleTime' ,width:60,sortable:true}, + {title:'审核通过时间', name:'createTime' ,width:60,sortable:true}, + {title:'所属分类', name:'goodsCatName' ,width:60,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatName']+"</p></span>"; + }}, + + {title:'销量', name:'saleNum' ,width:20,sortable:true,align:'center'}, + {title:'状态', name:'isSale' ,width:30,renderer: function (val,item,rowIndex){ + if(item['isSale']==1){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已上架</span>"; + }else{ + return "<span class='statu-no'><i class='fa fa-ban'></i>已下架</span>"; + } + }}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goods/shelvesByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +$(function(){initShelvesGrid();}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsappraises/edit.html b/hyhproject/admin/view/goodsappraises/edit.html new file mode 100755 index 0000000..0c1aa44 --- /dev/null +++ b/hyhproject/admin/view/goodsappraises/edit.html @@ -0,0 +1,126 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/goodsappraises/goodsappraises.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<script type="text/javascript" src="__STATIC__/plugins/raty/jquery.raty.min.js"></script> +<script> +$(function(){ +var options = { + hints : ['很不满意', '不满意', '一般', '满意', '非常满意'], + width:200, + targetKeep: true, + starHalf:'__STATIC__/plugins/raty/img/star-half-big.png', + starOff:'__STATIC__/plugins/raty/img/star-off-big.png', + starOn:'__STATIC__/plugins/raty/img/star-on-big.png', + cancelOff: '__STATIC__/plugins/raty/img/cancel-off-big.png', + cancelOn: '__STATIC__/plugins/raty/img/cancel-on-big.png' + } + options.target='#goodsScore_hint'; + options.score='{$data['goodsScore']}'; + $('.goodsScore').raty(options); + + options.target='#timeScore_hint'; + options.score='{$data['timeScore']}'; + $('.timeScore').raty(options); + + options.target='#serviceScore_hint'; + options.score='{$data['serviceScore']}'; + $('.serviceScore').raty(options); + + editInit(); + + +}); +</script> +<form id="goodsAppraisesForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>商品:</th> + <td> + <img src='__IMGURL__/{$data["goodsImg"]}' width='50' style="float:left;" />&nbsp; + <p style="float:left;height:50px;line-height:25px;width:245px;overflow:hidden;margin-left:5px;">{$data['goodsName']}</p> + </td> + </tr> + <tr> + <th>所属订单:</th> + <td> + {$data['orderNo']} + </td> + </tr> + <tr> + <th>用户:</th> + <td> + {$data['loginName']} + </td> + </tr> + <tr> + <th>评价:</th> + <td> + <div style='width:500px;'> + <div style='float:left;width:70px;'>商品评分:</div> + <div style='float:left;width:430px;'> + <div class="goodsScore" class="ipt" style='float:left'></div> + <div id="goodsScore_hint" style='float:left'></div> + </div> + </div> + <div id="score_error"></div> + + <div style='width:500px;'> + <div style='float:left;width:70px;'> 时效评分:</div> + <div style='float:left;width:430px;'> + <div class="timeScore" class="ipt" style='float:left'></div> + <div id="timeScore_hint" style='float:left'></div> + </div> + </div> + + <div style='width:500px;'> + <div style='float:left;width:70px;'>服务评分:</div> + <div style='float:left;width:430px;'> + <div class="serviceScore" class="ipt" style='float:left'></div> + <div id="serviceScore_hint" style='float:left'></div> + </div> + </div> + </td> + + </tr> + <tr> + <th>状态:</th> + <td class='layui-form'> + <input type="checkbox" id="isShow" {if $data['isShow']==1}checked{/if} name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow" lay-text="显示|隐藏"> + </tr> + <tr> + <th>评语:</th> + <td> + <textarea style="width:300px;height:100px" id="content" name="content" class="ipt">{$data['content']}</textarea> + </td> + </tr> + <tr> + <th>附件:</th> + <td> + <div id="appraise-img"> + {if !empty($data['images'])} + {volist name="$data['images']" id="img"} + <img src="__IMGURL__/{$img}/thumb80" layer-src="__IMGURL__/{$img}" width="50" /> + {/volist} + {/if} + </div> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class="wst-bottombar"> + <input type="hidden" name="id" id="id" class="ipt" value="{$data['id']+0}" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ + parent.showImg({photos: $('#appraise-img')}); +}); + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsappraises/goodsappraises.js b/hyhproject/admin/view/goodsappraises/goodsappraises.js new file mode 100755 index 0000000..24766fa --- /dev/null +++ b/hyhproject/admin/view/goodsappraises/goodsappraises.js @@ -0,0 +1,139 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'商品主图', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:40px;width:40px;' src='"+WST.conf.IMGURL+"/"+thumb + +"'><span class='imged' style='left:45px;'><img style='height:150px;width:150px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'订单号', name:'orderNo',sortable: true, width: 90}, + {title:'商品', name:'goodsName',sortable: true, width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + + {title:'商品评分', name:'goodsScore',sortable: true, width: 80, renderer: function(val,item,rowIndex){ + var s="<div style='line-height:28px;'>"; + for(var i=0;i<val;++i){ + s +="<img src='"+WST.conf.ROOT+"/hyhproject/admin/view/goodsappraises/icon_score_yes.png'>"; + } + s += "</div>"; + return s; + }}, + {title:'时效评分', name:'timeScore',sortable: true, width: 80, renderer: function(val,item,rowIndex){ + var s="<div style='line-height:28px;'>"; + for(var i=0;i<val;++i){ + s +="<img src='"+WST.conf.ROOT+"/hyhproject/admin/view/goodsappraises/icon_score_yes.png'>"; + } + s += "</div>"; + return s; + }}, + {title:'服务评分', name:'serviceScore',sortable: true, width: 80, renderer: function(val,item,rowIndex){ + var s="<div style='line-height:28px;'>"; + for(var i=0;i<val;++i){ + s +="<img src='"+WST.conf.ROOT+"/hyhproject/admin/view/goodsappraises/icon_score_yes.png'>"; + } + s += "</div>"; + return s; + }}, + {title:'评价内容', name:'content', width: 155}, + {title:'状态', name:'isShow', width: 20,sortable: true, renderer: function(val,item,rowIndex){ + return (val==0)?"<span class='statu-no'><i class='fa fa-ban'></i> 隐藏</span>":"<span class='statu-yes'><i class='fa fa-check-circle'></i> 显示</span></h3>"; + }}, + {title:'操作', name:'' ,width:95, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.PJGL_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/goodsappraises/toEdit','id='+item['id'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.PJGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goodsappraises/pageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'orderNo', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsappraises/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function loadGrid(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} + +function editInit(){ + + +/* 表单验证 */ + $('#goodsAppraisesForm').validator({ + fields: { + content: { + rule:"required;length(3~50)", + msg:{length:"评价内容为3-50个字",required:"评价内容为3-50个字"}, + tip:"评价内容为3-50个字", + ok:"", + }, + score: { + rule:"required", + msg:{required:"评分必须大于0"}, + ok:"", + target:"#score_error", + }, + + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + //获取修改的评分 + params.goodsScore = $('.goodsScore').find('[name=score]').val(); + params.timeScore = $('.timeScore').find('[name=score]').val(); + params.serviceScore = $('.serviceScore').find('[name=score]').val(); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsappraises/'+((params.id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/goodsappraises/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} +function toolTip(){ + $('body').mousemove(function(e){ + var windowH = $(window).height(); + if(e.pageY >= windowH*0.8){ + var top = windowH*0.233; + $('.imged').css('margin-top',-top); + }else{ + var top = windowH*0.06; + $('.imged').css('margin-top',-top); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsappraises/icon_score_yes.png b/hyhproject/admin/view/goodsappraises/icon_score_yes.png new file mode 100755 index 0000000..975fe7f Binary files /dev/null and b/hyhproject/admin/view/goodsappraises/icon_score_yes.png differ diff --git a/hyhproject/admin/view/goodsappraises/list.html b/hyhproject/admin/view/goodsappraises/list.html new file mode 100755 index 0000000..cdee8c3 --- /dev/null +++ b/hyhproject/admin/view/goodsappraises/list.html @@ -0,0 +1,34 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsappraises/goodsappraises.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div id="query" style="float:left;"> + <select id="areaId1" class='query' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'query'});" > + <option value="-1">-请选择地区-</option> + {foreach $area1 as $v} + <option value="<?=$v['areaId']?>"><?=$v['areaName']?></option> + {/foreach} + </select> + <input type="text" name="shopName" placeholder='店铺名称' id="shopName" class="query" /> + <input type="text" name="goodsName" placeholder='商品名称' id="goodsName" class="query" /> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:loadGrid()"><i class="fa fa-search"></i>查询</button> + </div> + <div style="clear:both"></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg layui-form"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}); +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodscats/goodscats.js b/hyhproject/admin/view/goodscats/goodscats.js new file mode 100755 index 0000000..1f4fd97 --- /dev/null +++ b/hyhproject/admin/view/goodscats/goodscats.js @@ -0,0 +1,276 @@ +var grid,oldData = {},oldorderData = {}; +function initGrid(){ + grid = $('#maingrid').WSTGridTree({ + url:WST.U('admin/goodscats/pageQuery'), + pageSize:10000, + pageSizeOptions:[10000], + height:'99%', + width:'100%', + minColToggle:6, + delayLoad :true, + rownumbers:true, + columns: [ + { display: '分类名称', width: 350,name: 'catName', id:'catId', align: 'left',isSort: false,render: function (item) + { + oldData[item.catId] = item.catName; + return '<input type="text" size="40" value="'+item.catName+'" onblur="javascript:editName('+item.catId+',this)"/>'; + }}, + { display: '自营是否显示', width: 70, name: 'isSelfShow',isSort: false, + render: function (item) + { + return '<input type="checkbox" '+((item.isSelfShow==1)?"checked":"")+' class="ipt" lay-skin="switch" lay-filter="isSelfShow" data="'+item.catId+'" lay-text="显示|隐藏">'; + } + }, + { display: '推荐楼层', width: 70, name: 'isFloor',isSort: false, + render: function (itemf) + { + return '<input type="checkbox" '+((itemf.isFloor==1)?"checked":"" )+' class="ipt" lay-skin="switch" lay-filter="isFloor" data="'+itemf.catId+'" lay-text="是|否">'; + } + }, + { display: '是否显示', width: 70, name: 'isShow',isSort: false, + render: function (item) + { + return '<input type="checkbox" '+((item.isShow==1)?"checked":"")+' class="ipt" lay-skin="switch" lay-filter="isShow" data="'+item.catId+'" lay-text="显示|隐藏">'; + } + }, + { display: '排序号', name: 'catSort',width: 50,isSort: false,render: function (item) + { + oldorderData[item.catId] = item.catSort; + return '<input type="text" style="width:50px" value="'+item.catSort+'" onblur="javascript:editOrder('+item.catId+',this)"/>'; + }}, + { display: '佣金', width: 50, name: 'commissionRate',isSort: false, + render: function (item) + { + return item["commissionRate"]+'%'; + } + }, + { display: '质保金', width: 50, name: 'payDeposit',isSort: false, + render: function (item) + { + return item["payDeposit"]; + } + }, + { display: '操作', name: 'op',width: 170,isSort: false, + render: function (rowdata){ + var h = ""; + if(WST.GRANT.SPFL_01)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["catId"]+",0)'><i class='fa fa-plus'></i>新增子分类</a> "; + if(WST.GRANT.SPFL_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["parentId"]+","+rowdata["catId"]+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.SPFL_03)h += "<a class='btn btn-red' href='javascript:toDel("+rowdata["parentId"]+","+rowdata["catId"]+")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ], + callback:function(){ + layui.form.render(); + } + }); + layui.form.on('switch(isSelfShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsSelfShow(id, 1); + }else{ + toggleIsSelfShow(id, 0); + } + }); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); + layui.form.on('switch(isFloor)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsFloor(id, 1); + }else{ + toggleIsFloor(id, 0); + } + }); +} +function toggleIsSelfShow(id,isSelfShow){ + if(!WST.GRANT.SPFL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodscats/editiIsSelfShow'),{id:id,isSelfShow:isSelfShow},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function toggleIsFloor(id,isFloor){ + if(!WST.GRANT.SPFL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodscats/editiIsFloor'),{id:id,isFloor:isFloor},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toggleIsShow(id,isShow){ + if(!WST.GRANT.SPFL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodscats/editiIsShow'),{id:id,isShow:isShow},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(pid,id){ + $('#goodscatsForm')[0].reset(); + if(id>0){ + $.post(WST.U('admin/goodscats/get'),{id:id},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json){ + WST.setValues(json); + layui.form.render(); + if(json.catImg){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.catImg+'" height="70px" />'); + }else{ + $('#preview').html(''); + } + editsBox(id); + } + }); + }else{ + WST.setValues({parentId:pid,catName:'',isShow:1,isFloor:0,catSort:0,catImg:''}); + $('#preview').html(''); + layui.form.render(); + editsBox(id); + } +} +var isInitUpload = false; +function editsBox(id,v){ + if(!isInitUpload)initUpload(); + var title =(id>0)?"修改商品分类":"新增商品分类"; + var box = WST.open({title:title,type:1,content:$('#goodscatsBox'),area: ['465px', '400px'],btn:['确定','取消'], + end:function(){$('#goodscatsBox').hide();},yes:function(){ + $('#goodscatsForm').submit(); + }}); + $('#goodscatsForm').validator({ + fields: { + catName: { + tip: "请输入商品分类名称", + rule: '商品分类名称:required;length[~20];' + }, + commissionRate: { + tip: "请输入分类的佣金", + rule: '分类的佣金:required;' + }, + catSort: { + tip: "请输入排序号", + rule: '排序号:required;length[~8];' + }, + payDeposit: { + tip: "请输入质保金", + rule: '分类的质保金:required;length[~20];' + }, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodscats/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#goodscatsBox').hide(); + layer.close(box); + grid.reload(params.parentId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function toDel(pid,id){ + var box = WST.confirm({content:"您确定要删除该商品分类并下架该分类下的所有商品吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodscats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + grid.reload(pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function initUpload(){ + isInitUpload = true; + //文件上传 + WST.upload({ + pick:'#catFilePicker', + formData: {dir:'goodscats'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + +} + +function editName(id,obj){ + if($.trim(obj.value)=='' || $.trim(obj.value)==oldData[id]){ + obj.value = oldData[id]; + return; + } + $.post(WST.U('admin/goodscats/editName'),{id:id,catName:obj.value},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + oldData[id] = $.trim(obj.value); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function editOrder(id,obj){ + if($.trim(obj.value)=='' || $.trim(obj.value)==editOrder[id]){ + obj.value = editOrder[id]; + return; + } + $.post(WST.U('admin/goodscats/editOrder'),{id:id,catSort:obj.value},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + editOrder[id] = $.trim(obj.value); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/goodscats/list.html b/hyhproject/admin/view/goodscats/list.html new file mode 100755 index 0000000..7808445 --- /dev/null +++ b/hyhproject/admin/view/goodscats/list.html @@ -0,0 +1,80 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/wstgridtree.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodscats/goodscats.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){initGrid();}) +</script> +{/block} +{block name="main"} +<style>.mmGrid{border-bottom:0px;}</style> +{if WSTGrant('SPFL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style='clear:both'></div> +</div> +{/if} +<div class='wst-grid'> + <div class='mmGrid layui-form' id="maingrid"></div> +</div> +<div id='goodscatsBox' style='display:none' class='layui-form'> + <form id='goodscatsForm' autocomplete="off"> + <input type='hidden' id='parentId' name="parentId" class='ipt'/> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>商品分类名称<font color='red'>*</font>:</th> + <td><input type='text' id='catName' name="catName" class='ipt' maxLength='20' style='width:200px;'/></td> + </tr> + <tr> + <th>图标:</th> + <td> + <div id='catFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='catImg' name="catImg" class="ipt" /> + + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:70px;" id="preview"></div></td> + </tr> + <tr> + <th width='100'>佣金<font color='red'>*</font>:</th> + <td height='24'> + <input type="text" id="commissionRate" name="commissionRate" class="ipt" value="-1" data-target="#msg_commissionRate" size='7' class='ipt'>%<span id='msg_commissionRate'>(-1代表继承上级佣金)</span> + </td> + </tr> + <tr> + <th width='100'>应交质保金<font color='red'>*</font>:</th> + <td height='50'> + <input type="text" id="payDeposit" name="payDeposit" class="ipt" value="-1" data-target="#payDeposit" size='7' class='ipt'><span id='payDeposit'>(-1代表继承上级质保金)</span> + </td> + </tr> + <tr> + <th width='100'>是否显示<font color='red'>*</font>:</th> + <td height='24'> + <input type="checkbox" id="isShow" name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow1" lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th width='100'>是否首页楼层<font color='red'>*</font>:</th> + <td height='24'> + <input type="checkbox" id="isFloor" name="isFloor" value="1" class="ipt" lay-skin="switch" lay-filter="isFloor1" lay-text="是|否"> + </td> + </tr> + <tr> + <th width='100'>楼层副标题<font color='red'> </font>:</th> + <td><input type='text' id='subTitle' name='subTitle' class='ipt' style='width:200px;' /></td> + </tr> + <tr> + <th width='100'>排序号<font color='red'>*</font>:</th> + <td><input type='text' id='catSort' name='catSort' class='ipt' style='width:60px;' onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" maxLength='10' value='0'/></td> + </tr> + </table> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/catdetail.html b/hyhproject/admin/view/goodsclassify/catdetail.html new file mode 100755 index 0000000..06cbee1 --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/catdetail.html @@ -0,0 +1,46 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<input type='hidden' id="classifyId" value='{$id}'/> +<div class="wst-toolbar"> + +{if WSTGrant('DQGL_01')} + <button class="btn btn-primary f-right btn-mright" onclick='javascript:toEdits(0,{$id})'><i class='fa fa-plus'></i>新增</button> + {/if} +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='attrBox' style='display:none'> + <form id="attrForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + <input type="hidden" id="classifyId" value='{$id}' class="ipt" /> + 所属商品分类<font color='red'>*</font>:</th> + <td id="bcat_0_box"> + <select id="catId" class='ipt goodsCats' level="0" onchange="WST.ITGoodsCats({id:'bcat_0',val:this.value,isRequire:false,className:'goodsCats'});" data-rule='所属商品分类:required;' data-target="#msg_bcat_0"> + <option value="">-请选择-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <span class='msg-box' id='msg_bcat_0' style='color:red;'>(至少选择一个商品分类)</span> + </td> + </tr> + </table> + </form> +</div> +<script> +$(function(){initcatDetailGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/cats.html b/hyhproject/admin/view/goodsclassify/cats.html new file mode 100755 index 0000000..f52a8e2 --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/cats.html @@ -0,0 +1,52 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<div class="wst-toolbar"> + {$classify} : 查看活动分类页 + <input type="hidden" value="{$classifyId}" id="classifyId"> + <button class="btn btn-primary f-right btn-mright" onclick='javascript:toAddCats(0,{$classifyId})'><i class='fa'></i>新增活动</button> + <button class="btn btn-info f-right btn-mright" onclick='javascript:history.back()'><i class='fa'></i>返回</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='attrBox' style='display:none'> + <form id="attrForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + 活动名称<font color='red'>*</font>:</th> + <td> + <input type="text" name="recomName" id="recomName" placeholder="填写分类名称" class="jipt"> + </td></tr> + <tr > + <th width='150' >排序号码<font color='red'>*</font>:</th> + <td > + <input type="text" name="recomOrder" class="jipt" id="recomOrder" placeholder="填写排序序号" style="margin-top: 20px;"> + <p>排序号越大越靠前</p> + </td> + </tr> + <tr class="wst-order-rate" > + <th width='120'>有效时间<font color='red'>*</font>:</th> + <td colspan='3'> + <input type='text' id='startTime' name='startTime' class='jipt laydate-icon' onclick="laydate({format: 'YYYY-MM-DD hh:mm:ss',istime:true})" data-rule="开始日期: required;datetime;"/> + 至 + <input type='text' id='endTime' name='endTime' class='jipt laydate-icon' onclick="laydate({format: 'YYYY-MM-DD hh:mm:ss',istime:true})" data-rule="结束日期: required;datetime;match(gt, startTime, datetime)"/> + </td> + </tr> + </table> + </form> +</div> +<script> +$(function(){initCatsGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/detail.html b/hyhproject/admin/view/goodsclassify/detail.html new file mode 100755 index 0000000..4e0216d --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/detail.html @@ -0,0 +1,25 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<input type='hidden' id="catId" value='{$id}'/> +<div class="wst-toolbar"> + +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + +$(function(){initDetailGrid();}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/goodsclassify.js b/hyhproject/admin/view/goodsclassify/goodsclassify.js new file mode 100755 index 0000000..fd4c5bb --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/goodsclassify.js @@ -0,0 +1,494 @@ +var mmg; +//获取商品总分类首页 +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'商品名称', name:'goodsclassifyName', width: 160,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsclassifyName']+"</p></span>"; + }}, + {title:'排序',name:'orderby',width:100,sortale:true}, + {title:'时间',name:'create_time',width:100,sortale:true}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='javascript:catdetail(" + item['goodsclassifyId'] + ")'><i class='fa fa-search'></i>绑定分类</a> "; + if(WST.GRANT.DSHSP_04)h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['goodsclassifyId'] + ",0)'><i class='fa fa-check'></i>修改</a> "; + if(WST.GRANT.DSHSP_04)h += "<a class='btn btn-blue' target='_blank' href='javascript:muji(" + item['goodsclassifyId'] + ")'><i class='fa fa-search'></i>设置活动页</a> "; + if(WST.GRANT.DSHSP_03)h += "<a class='btn btn-red' href='javascript:del(" + item['goodsclassifyId'] + ",0)'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + mmg = $('.mmg').mmGrid({height: h-85,indexCol:true, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +//-修改商品总分类---------------// +function toEdit(goodsclassifyId){ + $('#attrForm').get(0).reset(); + $.post(WST.U('admin/goodsclassify/get'),{goodsclassifyId:goodsclassifyId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + var title =(goodsclassifyId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#attrBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#attrBox').hide();},yes:function(){ + $('#attrForm').submit(); + }}); + $('#attrForm').validator({ + fields: { + 'goodsclassifyName': {rule:"required",msg:{required:'请输入属性名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/'+((params.goodsclassifyId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#attrBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} +//删除商品总分类 +function del(goodsclassifyId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/del'),{goodsclassifyId:goodsclassifyId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +//查看总分类下的商品分类 +function catdetail(goodsclassifyId){ + location.href=WST.U('admin/goodsclassify/catdetail','goodsclassifyId='+goodsclassifyId); +} +//获取商品分类的列表 +function initcatDetailGrid(){ + var classifyId=$('#classifyId').val(); + + var h = WST.pageHeight(); + var cols = [ + {title:'商品名称', name:'catName', width: 160,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['catName']+"</p></span>"; + }}, + {title:'时间',name:'createTime',width:100,sortale:true}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='javascript:detail(" + item['catId'] + ")'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.DSHSP_03)h += "<a class='btn btn-red' href='javascript:catDel(" + item['catId'] + ","+classifyId+")'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + mmg = $('.mmg').mmGrid({height: h-85,indexCol:true, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/catdetailPage','classifyId='+classifyId), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +//查看总分类下的商品 +function detail(catId){ + location.href=WST.U('admin/goodsclassify/detail','catId='+catId); +} +// +function initDetailGrid(){ + var catId=$('#catId').val(); + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb+"/thumb80" + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'商品名称', name:'goodsName', width: 160,sortable:true,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + {title:'商品编号', name:'goodsSn' ,width:60,sortable:true}, + {title:'价格', name:'shopPrice' ,width:20,sortable:true, renderer: function(val,item,rowIndex){ + return '¥'+item['shopPrice']; + }}, + {title:'所属店铺', name:'shopName' ,width:60,sortable:true}, + {title:'所属分类', name:'goodsCatName' ,width:60,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatName']+"</p></span>"; + }}, + {title:'销量', name:'saleNum' ,width:20,sortable:true,align:'center'}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/detailByPage','catId='+catId), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +//给商品总分类新增商品分类 +function toEdits(catId,classifyId){ + $('#attrForm').get(0).reset(); + $.post(WST.U('admin/goodsclassify/gets'),{catId:catId,classifyId:classifyId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + var title =(catId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#attrBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#attrBox').hide();},yes:function(){ + $('#attrForm').submit(); + }}); + $('#attrForm').validator({ + fields: { + 'goodsclassifyName': {rule:"required",msg:{required:'请输入属性名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/add_cat'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#attrBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} +//删除商品总分类下的商品分类 +function catDel(catId,classifyId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/catdel'),{catId:catId,classifyId:classifyId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +//去往设置活动页 +function muji(goodsclassifyId){ + location.href=WST.U('admin/goodsclassify/setdetail','goodsclassifyId='+goodsclassifyId); +} +//获取活动页列表 +function initsetDetailGrid(){ + var classifyId=$('#classifyId').val(); + var h = WST.pageHeight(); + var cols = [ + {title:'商品ID',name:'goodsId',width:30,sortale:true}, + {title:'商品名称', name:'goodsName', width: 180,sortable:true}, + {title:'商品分类',name:'recomName',width:60,sortale:true}, + {title:'排序',name:'goodsOrder',width:40,sortale:true,align:'center',renderer:function(val, item, rowIndex){ + return '<span style="cursor:pointer;" ondblclick="changeSort(this,'+item["recomGoodsId"]+');">'+val+'</span>'; + }}, + {title:'价格',name:'shopPrice',width:50,sortale:true,align:'center'}, + {title:'时间',name:'createTime',width:100,sortale:true,align:'center'}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.DSHSP_03)h += "<a class='btn btn-red' href='javascript:goodsDel(" + item['recomGoodsId'] + ")'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + mmg = $('.mmg').mmGrid({height: h-85,indexCol:true, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/setdetailPage','classifyId='+classifyId), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.page = 1; + mmg.load(params); +} +//删除活动分类的商品 +function goodsDel(recomGoodsId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/goodsDel'),{recomGoodsId:recomGoodsId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +//查看活动页的活动分类 +function cats(classifyId){ + location.href=WST.U('admin/goodsclassify/cats','classifyId='+classifyId); +} +// 查看、新增活动页的活动分类列表 +function initCatsGrid(){ + var classifyId=$('#classifyId').val(); + var h = WST.pageHeight(); + var cols = [ + {title:'所属分类', name:'goodsclassifyName' ,width:60,sortable:true}, + {title:'活动名称', name:'recomName', width: 60,sortable:true}, + {title:'活动排序', name:'recomOrder' ,width:60,sortable:true,align:'center'}, + {title:'开始时间', name:'startTime' ,width:80,sortable:true,align:'center'}, + {title:'结束时间', name:'endTime' ,width:80,sortable:true,align:'center'}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank'href='javascript:toAddCats(" + item['recomId'] + ")'><i class='fa fa-check'></i>修改</a> "; + h += "<a class='btn btn-blue' target='_blank'href='javascript:catsDel(" + item['recomId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/catsPage','classifyId='+classifyId), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +//添加活动页的活动分类 +function toAddCats(recomId,classifyId){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startTime', + type: 'datetime' + }); + laydate.render({ + elem: '#endTime', + type: 'datetime' + }); + $('#attrForm').get(0).reset(); + $.post(WST.U('admin/goodsclassify/getCats'),{recomId:recomId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + layui.form.render(); + var title =(recomId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#attrBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#attrBox').hide();},yes:function(){ + $('#attrForm').submit(); + }}); + $('#attrForm').validator({ + fields: { + 'goodsclassifyName': {rule:"required",msg:{required:'请输入属性名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.jipt'); + params.classifyId=classifyId; + params.recomId=recomId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/'+((params.recomId==0)?"addCats":"editCats")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#attrBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} +//删除活动设置页的活动分类 +function catsDel(recomId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/catsDel'),{recomId:recomId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='2'){ + var con = WST.confirm({content:"此活动下有活动商品,确定连活动商品一起删除吗",yes:function(){ + $.post(WST.U('admin/goodsclassify/catsDel'),{recomId:recomId,m:2},function(data,textStatus){ + var js= WST.toAdminJson(data); + if(js.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(con); + loadGrid(); + }else{ + WST.msg(js.msg,{icon:2}); + } + }) + }}) + }else if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +//查看设置活动页的推荐商品 +function recom(goodsclassifyId){ + location.href=WST.U('admin/goodsclassify/recom','goodsclassifyId='+goodsclassifyId); +} +//设置活动页、推荐商品的商品列表 +function initrecomDetailGrid(){ + var classifyId=$('#classifyId').val(); + var h = WST.pageHeight(); + var cols = [ + {title:'商品ID',name:'goodsId',width:30,sortale:true}, + {title:'商品名称', name:'goodsName', width: 180,sortable:true}, + {title:'排序',name:'goodsOrder',width:100,sortale:true,align:'center',renderer:function(val, item, rowIndex){ + return '<span style="cursor:pointer;" ondblclick="changeSort(this,'+item["recomActiveId"]+');">'+val+'</span>'; + }}, + {title:'价格',name:'shopPrice',width:100,sortale:true,align:'center'}, + {title:'时间',name:'createTime',width:100,sortale:true,align:'center'}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + if(WST.GRANT.DSHSP_03)h += "<a class='btn btn-red' href='javascript:recomActiveDel(" + item['recomActiveId'] + ")'><i class='fa fa-trash-o'></i>删除</a>"; + return h; + }} + ]; + mmg = $('.mmg').mmGrid({height: h-85,indexCol:true, cols: cols,method:'POST', + url: WST.U('admin/goodsclassify/recomPage','classifyId='+classifyId), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +//删除活动分类的商品 +function recomActiveDel(recomActiveId){ + var box = WST.confirm({content:"您确定要删除该属性吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/recomActiveDel'),{recomActiveId:recomActiveId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +//添加设置活动页的推荐商品 +function mujiGoods(recomActiveId,classifyId){ + var laydate = layui.laydate; + $('#goodsForm').get(0).reset(); + $.post(WST.U('admin/goodsclassify/getrecomActive'),{recomActiveId:recomActiveId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + var title ="新增"; + var box = WST.open({title:title,type:1,content:$('#goodsBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#goodsBox').hide();},yes:function(){ + $('#goodsForm').submit(); + }}); + $('#goodsForm').validator({ + fields: { + 'goodsclassifyName': {rule:"required",msg:{required:'请输入属性名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.classifyId=classifyId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/addrecomActive'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#goodsBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} +//姓曾活动设置页/活动商品 +function toAddGoods(recomGoodsId){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startTime', + type: 'datetime' + }); + laydate.render({ + elem: '#endTime', + type: 'datetime' + }); + $('#goodsForm').get(0).reset(); + $.post(WST.U('admin/goodsclassify/getGoods'),{recomGoodsId:recomGoodsId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + var title ="新增"; + var box = WST.open({title:title,type:1,content:$('#goodsBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#goodsBox').hide();},yes:function(){ + $('#goodsForm').submit(); + }}); + $('#goodsForm').validator({ + fields: { + 'recomId': {rule:"required",msg:{required:'请选择分类名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsclassify/addGoods'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#attrBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} diff --git a/hyhproject/admin/view/goodsclassify/list.html b/hyhproject/admin/view/goodsclassify/list.html new file mode 100755 index 0000000..e6760b6 --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/list.html @@ -0,0 +1,48 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +{if WSTGrant('SPSX_01')} + <button class="btn btn-primary f-right" onclick="javascript:toEdit(0);"><i class='fa fa-plus'></i>新增</button> + {/if} + +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<div id='attrBox' style='display:none'> + <form id="attrForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + <input type="hidden" id="goodsclassifyId" value="" class="ipt" /> + 商品总分类ID<font color='red'>*</font>:</th> + </tr> + <tr> + <th>商品总分类名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="goodsclassifyName" name="goodsclassifyName" class="ipt" maxLength='20'/> + </td> + </tr> + <tr> + <th>商品分类序号<font>*</font>:</th> + <td> + <input type="text" id="orderby" name="orderby" class="ipt" maxLength='20'/> + 数字越大越靠前 + </td> + </tr> + </table> + </form> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/recom.html b/hyhproject/admin/view/goodsclassify/recom.html new file mode 100755 index 0000000..254e257 --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/recom.html @@ -0,0 +1,67 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<input type='hidden' id="classifyId" value='{$id}'/> +<div class="wst-toolbar"> + {$result} : 推荐商品详情页 + <input type="text" name="goodsId" placeholder='商品ID' id="goodsId" class='j-ipt' style="width: 100px;margin-left: 20px;"/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> +{if WSTGrant('DQGL_01')} + <button class="btn btn-primary f-right btn-mright" onclick='javascript:mujiGoods(0,{$id})'><i class='fa fa-plus'></i>新增商品</button> + <button class="btn btn-info f-right btn-mright" onclick='javascript:history.back()'><i class='fa'></i>返回</button> + {/if} +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='goodsBox' style='display:none'> + <form id="goodsForm"> + <table class='wst-form wst-box-top'> + <tr > + <th width='150'>填写商品ID<font color='red'>*</font>:</th> + <td > + <textarea type="text" name="goodsId" class="ipt" id="goodsId" placeholder="填写商品ID:批量添加商品,请用英文逗号隔开" style="margin-top: 10px;height: 100px;"> + </textarea> + </td> + </tr> + </table> + </form> +</div> +<script> + var oldSort; + function changeSort(t,id){ + //alert(id); + $(t).attr('ondblclick'," "); + var html = "<input type='text' id='sort-"+id+"' style='width:40px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); + } + function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/goodsclassify/changeRecom'),{id:id,goodsOrder:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); + } +$(function(){initrecomDetailGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsclassify/setdetail.html b/hyhproject/admin/view/goodsclassify/setdetail.html new file mode 100755 index 0000000..849c75e --- /dev/null +++ b/hyhproject/admin/view/goodsclassify/setdetail.html @@ -0,0 +1,86 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsclassify/goodsclassify.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<input type='hidden' id="classifyId" value='{$id}'/> +<div class="wst-toolbar"> + {$result}活动页 + <select name="recomId" id="recomId" style="margin-left: 20px;" class='j-ipt'> + <option value="">请选择</option> + {volist name="classify" id="vo"} + <option value="{$vo['recomId']}">{$vo['recomName']}</option> + {/volist} + </select> + <input type="text" name="goodsId" placeholder='商品ID' id="goodsId" class='j-ipt' style="width: 100px;"/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> +{if WSTGrant('DQGL_01')} + <button class="btn btn-info f-right btn-mright" onclick='javascript:cats({$id})'><i class='fa'></i>查看/新增活动</button> + <button class="btn btn-default f-right btn-mright" onclick='javascript:recom({$id})'><i class='fa'></i>推荐商品</button> + <button class="btn btn-primary f-right btn-mright" onclick='javascript:toAddGoods()'><i class='fa fa-plus'></i>新增商品</button> + {/if} +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='goodsBox' style='display:none'> + <form id="goodsForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + 选择活动<font color='red'>*</font>:</th> + <td> + <select name="recomId" id="recomId" class="ipt"> + <option value="">请选择活动</option> + {volist name="classify" id="vo"} + <option value="{$vo.recomId}">{$vo.recomName}</option> + {/volist} + </select> + </td> + </tr> + <tr > + <th width='150'>填写商品ID<font color='red'>*</font>:</th> + <td > + <textarea type="text" name="goodsId" class="ipt" id="goodsId" placeholder="填写商品ID:批量添加商品,请用英文逗号隔开" style="margin-top: 10px;height: 100px;"> + </textarea> + </td> + </tr> + </table> + </form> +</div> +<script> + var oldSort; + function changeSort(t,id){ + //alert(id); + $(t).attr('ondblclick'," "); + var html = "<input type='text' id='sort-"+id+"' style='width:40px;' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); + oldSort = $(t).html(); + } + function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/goodsclassify/changeSet'),{id:id,goodsOrder:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); + } +$(function(){initsetDetailGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsconsult/edit.html b/hyhproject/admin/view/goodsconsult/edit.html new file mode 100755 index 0000000..e33695e --- /dev/null +++ b/hyhproject/admin/view/goodsconsult/edit.html @@ -0,0 +1,57 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/goodsconsult/goodsconsult.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="goodsconsultForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>商品:</th> + <td> + <img src='__IMGURL__/{$data["goodsImg"]}' width='50' style="float:left;" />&nbsp; + <p style="float:left;height:50px;line-height:25px;width:245px;overflow:hidden;margin-left:5px;">{$data['goodsName']}</p> + </td> + </tr> + <tr> + <th>用户:</th> + <td> + {if($data['loginName']!='')} + {$data['loginName']} + {else /} + 游客 + {/if} + </td> + </tr> + <tr> + <th>状态:</th> + <td> + <label><input type="radio" class="ipt" id="isShow" name="isShow" value="1" <?=$data['isShow']==1?'checked':'';?> />显示</label> + <label><input type="radio" class="ipt" id="isShow" name="isShow" value="0" <?=$data['isShow']==0?'checked':'';?> />隐藏</label> + </td> + </tr> + <tr> + <th>咨询内容:</th> + <td> + <textarea style="width:300px;height:100px" id="consultContent" name="consultContent" class="ipt">{$data['consultContent']}</textarea> + </td> + </tr> + <tr> + <th>回复内容:</th> + <td> + <textarea style="width:300px;height:100px" id="reply" name="reply" class="ipt">{$data['reply']}</textarea> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="id" class="ipt" value="{$data['id']+0}" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" onclick="javascript:history.go(-1)" class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){editInit();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsconsult/goodsconsult.js b/hyhproject/admin/view/goodsconsult/goodsconsult.js new file mode 100755 index 0000000..313200a --- /dev/null +++ b/hyhproject/admin/view/goodsconsult/goodsconsult.js @@ -0,0 +1,108 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'商品主图', name:'goodsImg', width: 100, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + //thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:40px;width:40px;' src='"+WST.conf.IMGURL+"/"+thumb + +"'><span class='imged' style='left:45px;'><img style='height:150px;width:150px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'商品', name:'goodsName', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsName']+"</p></span>"; + }}, + + {title:'咨询内容', name:'consultContent', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['consultContent']+"</p></span>"; + }}, + {title:'回复内容', name:'reply', width: 100,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['reply']+"</p></span>"; + }}, + {title:'状态', name:'isShow', width: 100, renderer: function(val,item,rowIndex){ + return (val==0)?"<span class='statu-no'><i class='fa fa-ban'></i> 隐藏</span>":"<span class='statu-yes'><i class='fa fa-check-circle'></i> 显示</span></h3>"; + }}, + {title:'操作', name:'' ,width:70, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.SPZX_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/goodsconsult/toEdit','id='+item['id'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.SPZX_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/goodsconsult/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsconsult/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function loadGrid(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} + +function editInit(){ +/* 表单验证 */ + $('#goodsconsultForm').validator({ + fields: { + consultContent: { + rule:"required;length(3~200)", + msg:{length:"评价内容为3-200个字",required:"评价内容为3-200个字"}, + tip:"评价内容为3-200个字", + ok:"", + }, + reply: { + rule:"required;length(3~200)", + msg:{length:"回复内容为3-200个字",required:"回复内容为3-200个字"}, + tip:"回复内容为3-200个字", + ok:"" + }, + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/goodsconsult/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/goodsconsult/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} +function toolTip(){ + $('body').mousemove(function(e){ + var windowH = $(window).height(); + if(e.pageY >= windowH*0.8){ + var top = windowH*0.233; + $('.imged').css('margin-top',-top); + }else{ + var top = windowH*0.06; + $('.imged').css('margin-top',-top); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/goodsconsult/list.html b/hyhproject/admin/view/goodsconsult/list.html new file mode 100755 index 0000000..3ac2875 --- /dev/null +++ b/hyhproject/admin/view/goodsconsult/list.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/goodsconsult/goodsconsult.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div id="query" style="float:left;"> + <select id="type" name='type' class='query'> + <option value="0">-咨询类别-</option> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <option value="{$vo['dataVal']}">{$vo['dataName']}</option> + {/volist} + </select> + <input type="text" name="consultKey" placeholder='咨询内容' id="consultKey" class="query" /> + <button type="button" class='btn btn-primary btn-mright'onclick="javascript:loadGrid()" ><i class="fa fa-search"></i>查询</button> + </div> + <div style="clear:both"></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg layui-form"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}); +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/homemenus/homemenus.js b/hyhproject/admin/view/homemenus/homemenus.js new file mode 100755 index 0000000..8d7cd49 --- /dev/null +++ b/hyhproject/admin/view/homemenus/homemenus.js @@ -0,0 +1,234 @@ +var grid; +$(function(){ + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?113:53; + }}); + grid = $("#maingrid").WSTGridTree({ + url:WST.U('admin/homemenus/pageQuery'), + pageSize:10000, + pageSizeOptions:10000, + height:'99%', + width:'100%', + minColToggle:6, + delayLoad :true, + rownumbers:true, + columns: [ + { display: '菜单名称', name: 'menuName', id:"menuId", isSort: false}, + { display: '菜单Url', name: 'menuUrl', isSort: false}, + { display: '菜单类型', name: 'menuType', width:80,isSort: false,render:function(rowdata, rowindex, value){ + return (rowdata['menuType']==0)?'用户菜单':'商家菜单'; + }}, + { display: '是否显示', name: 'isShow', width:80,isSort: false,render :function(item, rowindex, value){ + return '<input type="checkbox" '+((item.isShow==1)?"checked":"")+' class="ipt" lay-skin="switch" lay-filter="isShow" data="'+item.menuId+'" lay-text="显示|隐藏">'; + }}, + { display: '排序号', name: 'menuSort', width:60,isSort: false,render:function(rowdata,rowindex,value){ + return '<span class="classSort" style="cursor:pointer;color:blue;" ondblclick="changeSort(this,'+rowdata["menuId"]+');">'+rowdata['menuSort']+'</span>'; + }}, + { display: '操作', name: 'op',width:230,isSort: false,render: function (rowdata, rowindex, value){ + var h = ""; + if(WST.GRANT.QTCD_01)h += "<a class='btn btn-blue' href='javascript:toEdit(0," + rowdata['menuId'] + ","+rowdata['menuType']+")'><i class='fa fa-plus'></i>添加子菜单</a> "; + if(WST.GRANT.QTCD_02)h += "<a class='btn btn-blue' href='javascript:getForEdit("+rowdata["parentId"]+"," + rowdata['menuId'] + ")' href='"+WST.U('admin/homemenus/toEdit','menuId='+rowdata['menuId'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.QTCD_03)h += "<a class='btn btn-red' href='javascript:toDel("+rowdata["parentId"]+"," + rowdata['menuId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ], + callback:function(){ + $('.classSort').poshytip({content:'双击修改排序号',showTimeout:0,hideTimeout:1,alignX: 'center', + offsetY: 10,timeOnScreen:1000,allowTipHover: false}); + layui.form.render(); + } + }); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); +}) + + +var oldSort; +function changeSort(t,id){ + if(!WST.GRANT.QTCD_02)return; + $(t).attr('ondblclick'," "); +var html = "<input type='text' id='sort-"+id+"' style='width:30px;padding:2px' onblur='doneChange(this,"+id+")' value='"+$(t).html()+"' />"; + $(t).html(html); + $('#sort-'+id).focus(); + $('#sort-'+id).select(); +} +function doneChange(t,id){ + var sort = ($(t).val()=='')?0:$(t).val(); + if(sort==oldSort){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + return; + } + $.post(WST.U('admin/homemenus/changeSort'),{id:id,menuSort:sort},function(data){ + var json = WST.toAdminJson(data); + if(json.status==1){ + $(t).parent().attr('ondblclick','changeSort(this,'+id+')'); + $(t).parent().html(parseInt(sort)); + } + }); +} + + + + +function toDel(pid,menuId){ + var box = WST.confirm({content:"删除该菜单会将下边的子菜单也一并删除,您确定要删除吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/homemenus/del'),{menuId:menuId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + +function edit(pid,menuId){ + //获取所有参数 + var params = WST.getParams('.ipt'); + params.menuId = menuId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/homemenus/'+((menuId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + + WST.msg("操作成功",{icon:1}); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function toggleIsShow(menuId, isShow){ + if(!WST.GRANT.QTCD_02)return; + $.post(WST.U('admin/homemenus/setToggle'), {'menuId':menuId, 'isShow':isShow}, function(data, textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + grid.reload(menuId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} + +function getForEdit(pid,menuId){ + $('#menuForm')[0].reset(); + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/homemenus/get'),{menuId:menuId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.menuId){ + WST.setValues(json); + toEdit(json.menuId,pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(menuId,parentId,tId){ + var title = "编辑"; + if(menuId==0){ + $('#menuForm')[0].reset(); + title = "新增"; + WST.setValue('isShow',1); + } + if(parentId>0){ + $('#menuTypes').hide(); + }else{ + $('#menuTypes').show(); + } + if(tId==1){$('#menuType').val(1);} + layui.form.render(); + var box = WST.open({title:title,type:1,content:$('#menuBox'),area: ['550px', '420px'],btn:['确定','取消'], + end:function(){$('#menuBox').hide();},yes:function(){ + $('#menuForm').submit(); + }}); + $('#menuForm').validator({ + fields: { + 'menuName': {rule:"required;",msg:{required:'请输入菜单名称'}}, + 'menuUrl': {rule:"required;",msg:{required:'请输入菜单Url'}}, + 'menuSort': {rule:"required;integer",msg:{required:'请输入排序号',number:"请输入数字"}} + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.menuId = menuId; + params.parentId = parentId; + params.isShow = params.isShow?params.isShow:0; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/homemenus/'+((menuId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#menuBox').hide(); + $('#menuForm')[0].reset(); + layer.close(box); + grid.reload(params.parentId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} +function loadGrid(){ + $("#maingrid").WSTGridTree({ + url:WST.U('admin/homemenus/pageQuery',{menuType:$('#s_menuType').val()}), + pageSize:10000, + pageSizeOptions:10000, + height:'99%', + width:'100%', + minColToggle:6, + delayLoad :true, + rownumbers:true, + columns: [ + { display: '菜单名称', name: 'menuName', id:"menuId", isSort: false}, + { display: '菜单Url', name: 'menuUrl', isSort: false}, + { display: '菜单类型', name: 'menuType', width:80,isSort: false,render:function(rowdata, rowindex, value){ + return (rowdata['menuType']==0)?'用户菜单':'商家菜单'; + }}, + { display: '是否显示', name: 'isShow', width:80,isSort: false,render :function(item, rowindex, value){ + return '<input type="checkbox" '+((item.isShow==1)?"checked":"")+' class="ipt" lay-skin="switch" lay-filter="isShow" data="'+item.menuId+'" lay-text="显示|隐藏">'; + }}, + { display: '排序号', name: 'menuSort', width:60,isSort: false,render:function(rowdata,rowindex,value){ + return '<span style="cursor:pointer;color:blue;" ondblclick="changeSort(this,'+rowdata["menuId"]+');">'+rowdata['menuSort']+'</span>'; + }}, + { display: '操作', name: 'op',width:230,isSort: false,render: function (rowdata, rowindex, value){ + var h = ""; + if(WST.GRANT.QTCD_01)h += "<a class='btn btn-blue' href='javascript:toEdit(0," + rowdata['menuId'] + ","+rowdata['menuType']+")'><i class='fa fa-plus'></i>添加子菜单</a> "; + if(WST.GRANT.QTCD_02)h += "<a class='btn btn-blue' href='javascript:getForEdit("+rowdata["parentId"]+"," + rowdata['menuId'] + ")' href='"+WST.U('admin/homemenus/toEdit','menuId='+rowdata['menuId'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.QTCD_03)h += "<a class='btn btn-red' href='javascript:toDel("+rowdata["parentId"]+"," + rowdata['menuId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ], + callback:function(){ + layui.form.render(); + } + }); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/homemenus/list.html b/hyhproject/admin/view/homemenus/list.html new file mode 100755 index 0000000..af976f6 --- /dev/null +++ b/hyhproject/admin/view/homemenus/list.html @@ -0,0 +1,78 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/wstgridtree.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/homemenus/homemenus.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style>.mmGrid{border-bottom:0px;}</style> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能为开发者功能,主要用于设置电脑版买家和买家菜单,普通使用者请勿随意修改,以免影响系统使用。</li> + </ul> +</div> +<div class="wst-toolbar"> + <select id='s_menuType' onchange='loadGrid()'> + <option value='-1'>菜单类型</option> + <option value='0'>用户菜单</option> + <option value='1'>商家菜单</option> + </select> + {if WSTGrant('QTCD_01')} + <button class="btn btn-success f-right" onclick="javascript:toEdit(0)"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +<div class='wst-grid'> +<div class='mmGrid layui-form' id="maingrid"></div> +</div> +<div id='menuBox' style='display:none'> + <form id='menuForm'> + <table class='wst-form wst-box-top'> + <tr> + <th>菜单名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="menuName" name="menuName" class="ipt" maxLength='20' /> + </td> + </tr> + <tr> + <th>菜单Url<font color='red'>*</font>:</th> + <td> + <input type="text" id="menuUrl" name="menuUrl" class="ipt" maxLength='200' style='width:300px'/> + </td> + </tr> + <tr> + <th>附加资源:</th> + <td> + <textarea id="menuOtherUrl" name="menuOtherUrl" class="ipt" style='width:80%'></textarea> + </td> + </tr> + + <tr id="menuTypes"> + <th>菜单类型<font color='red'>*</font>:</th> + <td> + <select id="menuType" class="ipt"> + <option value="0">用户菜单</option> + <option value="1">商家菜单</option> + </select> + </td> + </tr> + + <tr> + <th>菜单排序<font color='red'>*</font>:</th> + <td> + <input type="text" id="menuSort" name="menuSort" class="ipt" maxLength='20' /> + </td> + </tr> + <tr> + <th>是否显示<font color='red'> </font>:</th> + <td class="layui-form"> + <input type="checkbox" id="isShow" name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow1" lay-text="显示|隐藏"> + </td> + </tr> + </table> + </form> +</div> +{/block} diff --git a/hyhproject/admin/view/hooks/hooks.js b/hyhproject/admin/view/hooks/hooks.js new file mode 100755 index 0000000..5dfcf3d --- /dev/null +++ b/hyhproject/admin/view/hooks/hooks.js @@ -0,0 +1,25 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'名称', name:'name', width: 100}, + {title:'描述', name:'hookRemarks', width: 100}, + {title:'对应插件', name:'addons' ,width:70, align:'center'} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/hooks/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + + +//查询 +function hooksQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} + diff --git a/hyhproject/admin/view/hooks/list.html b/hyhproject/admin/view/hooks/list.html new file mode 100755 index 0000000..dd0bba0 --- /dev/null +++ b/hyhproject/admin/view/hooks/list.html @@ -0,0 +1,26 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/hooks/hooks.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div id="query" style="float:left;"> + <input type="text" name="keyWords" placeholder="钩子名称" id="keyWords" class="j-ipt query"> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:hooksQuery()" ><i class="fa fa-search"></i>查询</button> + </div> + + <div style="clear:both"></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/images/images.js b/hyhproject/admin/view/images/images.js new file mode 100755 index 0000000..1c36adf --- /dev/null +++ b/hyhproject/admin/view/images/images.js @@ -0,0 +1,103 @@ +function initSummary(){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/images/summary'),{rnd:Math.random()},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status==1){ + json = json.data; + var html = [],tmp,i=1,divLen = 0; + for(var key in json){ + if(key=='_WSTSummary_')continue; + tmp = json[key]; + html.push('<tr class="mmg-body wst-grid-tree-row" height="28" align="center">' + ,'<td class="wst-grid-tree-row-cell" style="width:26px;">'+(i++)+'</td>' + ,'<td class="wst-grid-tree-row-cell">'+WST.blank(tmp.directory,'未知目录')+'('+key+')'+'</td>' + ,'<td class="wst-grid-tree-row-cell" align="left">'+getCharts(json['_WSTSummary_'],tmp.data['1'],tmp.data['0'])+'</td>' + ,'<td class="wst-grid-tree-row-cell" nowrap>'+tmp.data['1']+'/'+tmp.data['0']+'</td>' + ,'<td class="wst-grid-tree-row-cell"><a class="btn btn-blue" href="'+WST.U('admin/images/lists','keyword='+key)+'"><i class="fa fa-search"></i>查看详情</a></td>'); + } + $('#list').html(html.join('')); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){}}); +} +function getCharts(maxSize,size1,size2){ + var w = WST.pageWidth()-400; + var tlen = (parseFloat(size1,10)+parseFloat(size2,10))*w/maxSize+1; + var s1len = parseFloat(size1,10)*w/maxSize; + var s2len = parseFloat(size2,10)*w/maxSize; + return ['<div style="width:'+tlen+'px"><div style="height:20px;float:left;width:'+s1len+'px;background:#5cb85c;"></div><div style="height:20px;float:left;width:'+s2len+'px;background:#ddd;"></div></div>']; +} +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'图片', name:'imgPath', width: 50, renderer: function(val,item,rowIndex){ + + // return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.ROOT+"/"+item['imgPath'] + // +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.ROOT+"/"+item['imgPath']+"'></span></span>"; + // 修改为oss 地址 mark 20180609 + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+item['imgPath']+"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['imgPath']+"'></span></span>"; + }}, + {title:'上传者', name:'userName' ,width:250, renderer: function(val,item,rowIndex){ + if(item['fromType']==1){ + return "【职员】"+item['loginName']; + }else{ + if(WST.blank(item['userType'])==''){ + return '游客'; + }else{ + if(item['userType']==1){ + return "【商家:"+item['shopName']+"】"+item['loginName']; + }else{ + return item['loginName']; + } + } + } + }}, + {title:'文件大小(M)', name:'imgSize' ,width:30}, + {title:'状态', name:'isUse' ,width:30, renderer: function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 有效</span>":"<span class='statu-no'><i class='fa fa-ban'></i> 无效</span>"; + }}, + {title:'上传时间', name:'createTime' ,width:120}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = '<a class="btn btn-blue btn-mright" href="javascript:toView('+item['imgId']+',\''+item['imgPath']+'\')"><i class="fa fa-search"></i>查看</a>'; + if(WST.GRANT.TPKJ_04)h += "<button class='btn btn-red' onclick='javascript:toDel(" + item['imgId'] + ")'><i class='fa fa-trash-o'></i>删除</button> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/images/pageQuery'), fullWidthRows: true, autoLoad: false, + plugins: [ + $('#pg').mmPaginator() + ] + }); + loadGrid(); +} +function loadGrid(){ + mmg.load({page:1,keyword:$('#key').val(),isUse:$('#isUse').val()}); +} +function toView(id,img){ + parent.showBox({title:'图片详情',type:2,content:WST.U('admin/images/checkImages','imgPath='+img),area: ['700px', '510px'],btn:['关闭']}); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该图片吗?<br/>注意:删除该图片后将不可找回!",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/images/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function toolTip(){ + WST.toolTip(); +} \ No newline at end of file diff --git a/hyhproject/admin/view/images/index.html b/hyhproject/admin/view/images/index.html new file mode 100755 index 0000000..b4a2c08 --- /dev/null +++ b/hyhproject/admin/view/images/index.html @@ -0,0 +1,32 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/images/images.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于查看系统图片空间占用情况。绿色为有效图片,灰色为无效,可删除图片。</li> + </ul> +</div> +<div id="main" class='mmGrid wst-grid'> +<table class='mmg-head wst-grid-tree' width='100%' cellspacing='0' cellpadding='0'> + <thead class='mmg-headWrapper'> + <tr class='l-grid-hd-row wst-grid-tree-hd'> + <td width='30' class='wst-grid-tree-hd-cel' height='28' style="width:26px;text-align:center;font-weight:bold;">#</td> + <td width='150' class='wst-grid-tree-hd-cell' height='28' style='text-align:center;font-weight:bold;'>目录</td> + <td class='wst-grid-tree-hd-cell'height='28' style='text-align:left;font-weight:bold;'>有效图片/无效图片</td> + <td width='80' class='wst-grid-tree-hd-cell' height='28' style='text-align:center;font-weight:bold;'>M</td> + <td width='80' class='wst-grid-tree-hd-cell' height='28' style='text-align:center;font-weight:bold;'>操作</td> + </tr> + </thead> + <tbody id='list'></tbody> +</table> +</div> +<script> +$(function(){initSummary();}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/images/list.html b/hyhproject/admin/view/images/list.html new file mode 100755 index 0000000..9c4aa00 --- /dev/null +++ b/hyhproject/admin/view/images/list.html @@ -0,0 +1,36 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/images/images.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form> +<div class="wst-toolbar"> +<select id='key' class='ipt'> + <option value=''>所有目录</option> + {volist name="$datas" key="i" id='vo'} + <option value="{$vo['dataVal']}" {if $keyword==$vo['dataVal']}selected{/if}>{$vo['dataName']}</option> + {/volist} +</select> +<select id='isUse' class='ipt'> + <option value='-1'>全部</option> + <option value='1'>有效</option> + <option value='0'>失效</option> +</select> +</form> +<button class="btn btn-primary" type='button' onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<button class="btn f-right" type='button' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> +</div> +<table id="mmg" class="mmg"> + <tr> + <th rowspan="" colspan=""></th> + </tr> +</table> +<div id="pg" style="text-align: right;"></div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/images/loading.gif b/hyhproject/admin/view/images/loading.gif new file mode 100755 index 0000000..6e5bace Binary files /dev/null and b/hyhproject/admin/view/images/loading.gif differ diff --git a/hyhproject/admin/view/images/validator_default.png b/hyhproject/admin/view/images/validator_default.png new file mode 100755 index 0000000..7bf05e7 Binary files /dev/null and b/hyhproject/admin/view/images/validator_default.png differ diff --git a/hyhproject/admin/view/images/validator_simple.png b/hyhproject/admin/view/images/validator_simple.png new file mode 100755 index 0000000..9db57bb Binary files /dev/null and b/hyhproject/admin/view/images/validator_simple.png differ diff --git a/hyhproject/admin/view/images/view.html b/hyhproject/admin/view/images/view.html new file mode 100755 index 0000000..95aa357 --- /dev/null +++ b/hyhproject/admin/view/images/view.html @@ -0,0 +1,76 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/images/images.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style type="text/css"> +*{ margin:0; padding:0; list-style:none;} +img{ border:none;} +.imgbox{ width:400px; height:400px; margin:0px auto;text-align:center;vertical-align:middle;display:block;position:relative;padding:5px;} +.imgbox a{display:table-cell;vertical-align:middle;width:400px; height:400px; } +.imgbox a img{max-width:400px;max-height:400px; } +.imgthumbbox{ width:100px; height:100px;text-align:center;vertical-align:middle;display:block;position:relative;border:1px solid #ddd;margin-bottom:10px;} +.imgthumbbox a{display:table-cell;vertical-align:middle;width:100px; height:100px; } +.imgthumbbox a img{max-width:100px;max-height:100px; } +.mimgbox{ width:100px; height:100px; text-align:center;vertical-align:middle;display:block;position:relative;border:1px solid #ddd;margin-bottom:10px;} +.mimgbox a{display:table-cell;vertical-align:middle;width:100px; height:100px; } +.mimgbox a img{max-width:100px;max-height:100px; } +.mimgthumbbox{ width:100px; height:100px; text-align:center;vertical-align:middle;display:block;position:relative;border:1px solid #ddd} +.mimgthumbbox a{display:table-cell;vertical-align:middle;width:100px; height:100px; } +.mimgthumbbox a img{max-width:100px;max-height:100px; } +.head{line-height:25px;height:25px;} +</style> +</head> +<body> +<table width='100%'> + <tr> + <td> + <div class='imgbox'> + {if $img} + <a href='__ROOT__/{$imgpath}' target="_blank"> + <img id='img' src='__ROOT__/{$imgpath}'/> + </a> + {elseif $img_oss} + <a href='__IMGURL__/{$imgpath}' target="_blank"> + <img id='img' src='__IMGURL__/{$imgpath}'/> + </a> + {else} + 图片不存在! + } + {/if} + </div> + </td> + <td width='150'> + {if $thumb} + <div><div class='head'>缩略图:</div> + <div class='imgthumbbox'> + <a href='__ROOT__/{$thumbpath}' target="_blank"> + <img src='__ROOT__/{$thumbpath}'/> + </a> + </div> + </div> + {/if} + <!-- {if $mimgpath !=''} --> + {if $mimg } + <div><div class='head'>移动端图片:</div> + <div class='mimgbox'> + <a href='__ROOT__/{$mimgpath}' target="_blank"> + <img src='__ROOT__/{$mimgpath}'/> + </a> + </div> + </div> + {/if} + <!-- {if $mthumbpath !=''} --> + {if $mthumb } + <div><div class='head'>移动端缩略图:</div> + <div class='mimgthumbbox'> + <a href='__ROOT__/{$mthumbpath}' target="_blank"> + <img src='__ROOT__/{$mthumbpath}'/> + </a> + </div> + </div> + {/if} + </td> + </tr> +</table> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/img/1.png b/hyhproject/admin/view/img/1.png new file mode 100755 index 0000000..bc4bc8b Binary files /dev/null and b/hyhproject/admin/view/img/1.png differ diff --git a/hyhproject/admin/view/img/10.png b/hyhproject/admin/view/img/10.png new file mode 100755 index 0000000..4353765 Binary files /dev/null and b/hyhproject/admin/view/img/10.png differ diff --git a/hyhproject/admin/view/img/11.png b/hyhproject/admin/view/img/11.png new file mode 100755 index 0000000..7aa87ff Binary files /dev/null and b/hyhproject/admin/view/img/11.png differ diff --git a/hyhproject/admin/view/img/12.png b/hyhproject/admin/view/img/12.png new file mode 100755 index 0000000..0f70182 Binary files /dev/null and b/hyhproject/admin/view/img/12.png differ diff --git a/hyhproject/admin/view/img/13.png b/hyhproject/admin/view/img/13.png new file mode 100755 index 0000000..37e9b61 Binary files /dev/null and b/hyhproject/admin/view/img/13.png differ diff --git a/hyhproject/admin/view/img/14.png b/hyhproject/admin/view/img/14.png new file mode 100755 index 0000000..4f64718 Binary files /dev/null and b/hyhproject/admin/view/img/14.png differ diff --git a/hyhproject/admin/view/img/15.png b/hyhproject/admin/view/img/15.png new file mode 100755 index 0000000..cf0d5c8 Binary files /dev/null and b/hyhproject/admin/view/img/15.png differ diff --git a/hyhproject/admin/view/img/2.png b/hyhproject/admin/view/img/2.png new file mode 100755 index 0000000..d0a955c Binary files /dev/null and b/hyhproject/admin/view/img/2.png differ diff --git a/hyhproject/admin/view/img/3.png b/hyhproject/admin/view/img/3.png new file mode 100755 index 0000000..f4eb6c3 Binary files /dev/null and b/hyhproject/admin/view/img/3.png differ diff --git a/hyhproject/admin/view/img/4.png b/hyhproject/admin/view/img/4.png new file mode 100755 index 0000000..dea041c Binary files /dev/null and b/hyhproject/admin/view/img/4.png differ diff --git a/hyhproject/admin/view/img/5.png b/hyhproject/admin/view/img/5.png new file mode 100755 index 0000000..be385df Binary files /dev/null and b/hyhproject/admin/view/img/5.png differ diff --git a/hyhproject/admin/view/img/6.png b/hyhproject/admin/view/img/6.png new file mode 100755 index 0000000..0192860 Binary files /dev/null and b/hyhproject/admin/view/img/6.png differ diff --git a/hyhproject/admin/view/img/7.png b/hyhproject/admin/view/img/7.png new file mode 100755 index 0000000..30b9b4a Binary files /dev/null and b/hyhproject/admin/view/img/7.png differ diff --git a/hyhproject/admin/view/img/8.png b/hyhproject/admin/view/img/8.png new file mode 100755 index 0000000..082fb0c Binary files /dev/null and b/hyhproject/admin/view/img/8.png differ diff --git a/hyhproject/admin/view/img/9.png b/hyhproject/admin/view/img/9.png new file mode 100755 index 0000000..1aa04a3 Binary files /dev/null and b/hyhproject/admin/view/img/9.png differ diff --git a/hyhproject/admin/view/img/about_1.png b/hyhproject/admin/view/img/about_1.png new file mode 100755 index 0000000..1981eb6 Binary files /dev/null and b/hyhproject/admin/view/img/about_1.png differ diff --git a/hyhproject/admin/view/img/about_2.png b/hyhproject/admin/view/img/about_2.png new file mode 100755 index 0000000..30597ba Binary files /dev/null and b/hyhproject/admin/view/img/about_2.png differ diff --git a/hyhproject/admin/view/img/about_3.png b/hyhproject/admin/view/img/about_3.png new file mode 100755 index 0000000..30ad094 Binary files /dev/null and b/hyhproject/admin/view/img/about_3.png differ diff --git a/hyhproject/admin/view/img/about_4.png b/hyhproject/admin/view/img/about_4.png new file mode 100755 index 0000000..34c5363 Binary files /dev/null and b/hyhproject/admin/view/img/about_4.png differ diff --git a/hyhproject/admin/view/img/about_5.png b/hyhproject/admin/view/img/about_5.png new file mode 100755 index 0000000..9c0f3a0 Binary files /dev/null and b/hyhproject/admin/view/img/about_5.png differ diff --git a/hyhproject/admin/view/img/about_6.png b/hyhproject/admin/view/img/about_6.png new file mode 100755 index 0000000..8c1f26e Binary files /dev/null and b/hyhproject/admin/view/img/about_6.png differ diff --git a/hyhproject/admin/view/img/about_7.png b/hyhproject/admin/view/img/about_7.png new file mode 100755 index 0000000..6dc4f9f Binary files /dev/null and b/hyhproject/admin/view/img/about_7.png differ diff --git a/hyhproject/admin/view/img/about_8.png b/hyhproject/admin/view/img/about_8.png new file mode 100755 index 0000000..74ac4ca Binary files /dev/null and b/hyhproject/admin/view/img/about_8.png differ diff --git a/hyhproject/admin/view/img/ajax-loader.gif b/hyhproject/admin/view/img/ajax-loader.gif new file mode 100755 index 0000000..6f3c953 Binary files /dev/null and b/hyhproject/admin/view/img/ajax-loader.gif differ diff --git a/hyhproject/admin/view/img/angle_12.png b/hyhproject/admin/view/img/angle_12.png new file mode 100755 index 0000000..6fd390d Binary files /dev/null and b/hyhproject/admin/view/img/angle_12.png differ diff --git a/hyhproject/admin/view/img/angle_13.png b/hyhproject/admin/view/img/angle_13.png new file mode 100755 index 0000000..0cf9c60 Binary files /dev/null and b/hyhproject/admin/view/img/angle_13.png differ diff --git a/hyhproject/admin/view/img/bg.png b/hyhproject/admin/view/img/bg.png new file mode 100755 index 0000000..ee4d649 Binary files /dev/null and b/hyhproject/admin/view/img/bg.png differ diff --git a/hyhproject/admin/view/img/btn_bg.png b/hyhproject/admin/view/img/btn_bg.png new file mode 100755 index 0000000..cf76e5f Binary files /dev/null and b/hyhproject/admin/view/img/btn_bg.png differ diff --git a/hyhproject/admin/view/img/btn_bg_hover.png b/hyhproject/admin/view/img/btn_bg_hover.png new file mode 100755 index 0000000..780a76b Binary files /dev/null and b/hyhproject/admin/view/img/btn_bg_hover.png differ diff --git a/hyhproject/admin/view/img/grid-tree-close.gif b/hyhproject/admin/view/img/grid-tree-close.gif new file mode 100755 index 0000000..7590580 Binary files /dev/null and b/hyhproject/admin/view/img/grid-tree-close.gif differ diff --git a/hyhproject/admin/view/img/grid-tree-open.gif b/hyhproject/admin/view/img/grid-tree-open.gif new file mode 100755 index 0000000..826da37 Binary files /dev/null and b/hyhproject/admin/view/img/grid-tree-open.gif differ diff --git a/hyhproject/admin/view/img/header-bg.gif b/hyhproject/admin/view/img/header-bg.gif new file mode 100755 index 0000000..8d459a3 Binary files /dev/null and b/hyhproject/admin/view/img/header-bg.gif differ diff --git a/hyhproject/admin/view/img/ico_5.png b/hyhproject/admin/view/img/ico_5.png new file mode 100755 index 0000000..2f08f1a Binary files /dev/null and b/hyhproject/admin/view/img/ico_5.png differ diff --git a/hyhproject/admin/view/img/icon_shuru.png b/hyhproject/admin/view/img/icon_shuru.png new file mode 100755 index 0000000..e5009d0 Binary files /dev/null and b/hyhproject/admin/view/img/icon_shuru.png differ diff --git a/hyhproject/admin/view/img/icon_topmenu.png b/hyhproject/admin/view/img/icon_topmenu.png new file mode 100755 index 0000000..b99129f Binary files /dev/null and b/hyhproject/admin/view/img/icon_topmenu.png differ diff --git a/hyhproject/admin/view/img/icon_tstb.png b/hyhproject/admin/view/img/icon_tstb.png new file mode 100755 index 0000000..4a5aff3 Binary files /dev/null and b/hyhproject/admin/view/img/icon_tstb.png differ diff --git a/hyhproject/admin/view/img/img_dibu.png b/hyhproject/admin/view/img/img_dibu.png new file mode 100755 index 0000000..e5628f3 Binary files /dev/null and b/hyhproject/admin/view/img/img_dibu.png differ diff --git a/hyhproject/admin/view/img/img_info1-1.png b/hyhproject/admin/view/img/img_info1-1.png new file mode 100755 index 0000000..8a2365d Binary files /dev/null and b/hyhproject/admin/view/img/img_info1-1.png differ diff --git a/hyhproject/admin/view/img/img_info1.png b/hyhproject/admin/view/img/img_info1.png new file mode 100755 index 0000000..66b5c8a Binary files /dev/null and b/hyhproject/admin/view/img/img_info1.png differ diff --git a/hyhproject/admin/view/img/img_info2-1.png b/hyhproject/admin/view/img/img_info2-1.png new file mode 100755 index 0000000..28335ae Binary files /dev/null and b/hyhproject/admin/view/img/img_info2-1.png differ diff --git a/hyhproject/admin/view/img/img_info2.png b/hyhproject/admin/view/img/img_info2.png new file mode 100755 index 0000000..425d882 Binary files /dev/null and b/hyhproject/admin/view/img/img_info2.png differ diff --git a/hyhproject/admin/view/img/img_info3-1.png b/hyhproject/admin/view/img/img_info3-1.png new file mode 100755 index 0000000..4e82bff Binary files /dev/null and b/hyhproject/admin/view/img/img_info3-1.png differ diff --git a/hyhproject/admin/view/img/img_info3.png b/hyhproject/admin/view/img/img_info3.png new file mode 100755 index 0000000..09ecc88 Binary files /dev/null and b/hyhproject/admin/view/img/img_info3.png differ diff --git a/hyhproject/admin/view/img/img_info4-1.png b/hyhproject/admin/view/img/img_info4-1.png new file mode 100755 index 0000000..79e95b9 Binary files /dev/null and b/hyhproject/admin/view/img/img_info4-1.png differ diff --git a/hyhproject/admin/view/img/img_info4.png b/hyhproject/admin/view/img/img_info4.png new file mode 100755 index 0000000..b39c60d Binary files /dev/null and b/hyhproject/admin/view/img/img_info4.png differ diff --git a/hyhproject/admin/view/img/img_info5-1.png b/hyhproject/admin/view/img/img_info5-1.png new file mode 100755 index 0000000..b779744 Binary files /dev/null and b/hyhproject/admin/view/img/img_info5-1.png differ diff --git a/hyhproject/admin/view/img/img_info5.png b/hyhproject/admin/view/img/img_info5.png new file mode 100755 index 0000000..87315c7 Binary files /dev/null and b/hyhproject/admin/view/img/img_info5.png differ diff --git a/hyhproject/admin/view/img/img_info6-1.png b/hyhproject/admin/view/img/img_info6-1.png new file mode 100755 index 0000000..76f988e Binary files /dev/null and b/hyhproject/admin/view/img/img_info6-1.png differ diff --git a/hyhproject/admin/view/img/img_info6.png b/hyhproject/admin/view/img/img_info6.png new file mode 100755 index 0000000..6c61724 Binary files /dev/null and b/hyhproject/admin/view/img/img_info6.png differ diff --git a/hyhproject/admin/view/img/img_leftimg.png b/hyhproject/admin/view/img/img_leftimg.png new file mode 100755 index 0000000..0d955a1 Binary files /dev/null and b/hyhproject/admin/view/img/img_leftimg.png differ diff --git a/hyhproject/admin/view/img/img_mrtx_gly.png b/hyhproject/admin/view/img/img_mrtx_gly.png new file mode 100755 index 0000000..5f8ebfc Binary files /dev/null and b/hyhproject/admin/view/img/img_mrtx_gly.png differ diff --git a/hyhproject/admin/view/img/img_mrtx_logo.png b/hyhproject/admin/view/img/img_mrtx_logo.png new file mode 100755 index 0000000..f9759dd Binary files /dev/null and b/hyhproject/admin/view/img/img_mrtx_logo.png differ diff --git a/hyhproject/admin/view/img/img_mrtx_yh.png b/hyhproject/admin/view/img/img_mrtx_yh.png new file mode 100755 index 0000000..5f95121 Binary files /dev/null and b/hyhproject/admin/view/img/img_mrtx_yh.png differ diff --git a/hyhproject/admin/view/img/img_seller_ggjt.png b/hyhproject/admin/view/img/img_seller_ggjt.png new file mode 100755 index 0000000..7edd87e Binary files /dev/null and b/hyhproject/admin/view/img/img_seller_ggjt.png differ diff --git a/hyhproject/admin/view/img/img_shurukuang.png b/hyhproject/admin/view/img/img_shurukuang.png new file mode 100755 index 0000000..cede00c Binary files /dev/null and b/hyhproject/admin/view/img/img_shurukuang.png differ diff --git a/hyhproject/admin/view/img/img_titlebg.png b/hyhproject/admin/view/img/img_titlebg.png new file mode 100755 index 0000000..39fa49e Binary files /dev/null and b/hyhproject/admin/view/img/img_titlebg.png differ diff --git a/hyhproject/admin/view/img/img_top_bg.png b/hyhproject/admin/view/img/img_top_bg.png new file mode 100755 index 0000000..0c3750c Binary files /dev/null and b/hyhproject/admin/view/img/img_top_bg.png differ diff --git a/hyhproject/admin/view/img/img_topinfo.png b/hyhproject/admin/view/img/img_topinfo.png new file mode 100755 index 0000000..6fdff75 Binary files /dev/null and b/hyhproject/admin/view/img/img_topinfo.png differ diff --git a/hyhproject/admin/view/img/layout-header.gif b/hyhproject/admin/view/img/layout-header.gif new file mode 100755 index 0000000..13874d7 Binary files /dev/null and b/hyhproject/admin/view/img/layout-header.gif differ diff --git a/hyhproject/admin/view/img/login-btn.png b/hyhproject/admin/view/img/login-btn.png new file mode 100755 index 0000000..853c56c Binary files /dev/null and b/hyhproject/admin/view/img/login-btn.png differ diff --git a/hyhproject/admin/view/img/login_bg.png b/hyhproject/admin/view/img/login_bg.png new file mode 100755 index 0000000..0e517a1 Binary files /dev/null and b/hyhproject/admin/view/img/login_bg.png differ diff --git a/hyhproject/admin/view/img/login_bg1.png b/hyhproject/admin/view/img/login_bg1.png new file mode 100755 index 0000000..0e517a1 Binary files /dev/null and b/hyhproject/admin/view/img/login_bg1.png differ diff --git a/hyhproject/admin/view/img/login_box_bg.png b/hyhproject/admin/view/img/login_box_bg.png new file mode 100755 index 0000000..7562183 Binary files /dev/null and b/hyhproject/admin/view/img/login_box_bg.png differ diff --git a/hyhproject/admin/view/img/login_head.png b/hyhproject/admin/view/img/login_head.png new file mode 100755 index 0000000..db15939 Binary files /dev/null and b/hyhproject/admin/view/img/login_head.png differ diff --git a/hyhproject/admin/view/img/login_icon.png b/hyhproject/admin/view/img/login_icon.png new file mode 100755 index 0000000..2fe8c7f Binary files /dev/null and b/hyhproject/admin/view/img/login_icon.png differ diff --git a/hyhproject/admin/view/img/login_logo.png b/hyhproject/admin/view/img/login_logo.png new file mode 100755 index 0000000..fa38cc6 Binary files /dev/null and b/hyhproject/admin/view/img/login_logo.png differ diff --git a/hyhproject/admin/view/img/login_logo1.png b/hyhproject/admin/view/img/login_logo1.png new file mode 100755 index 0000000..59f1273 Binary files /dev/null and b/hyhproject/admin/view/img/login_logo1.png differ diff --git a/hyhproject/admin/view/img/logo-min.png b/hyhproject/admin/view/img/logo-min.png new file mode 100755 index 0000000..9cd40e7 Binary files /dev/null and b/hyhproject/admin/view/img/logo-min.png differ diff --git a/hyhproject/admin/view/img/logo.png b/hyhproject/admin/view/img/logo.png new file mode 100755 index 0000000..d29ac01 Binary files /dev/null and b/hyhproject/admin/view/img/logo.png differ diff --git a/hyhproject/admin/view/img/logon_icon.png b/hyhproject/admin/view/img/logon_icon.png new file mode 100755 index 0000000..e9cbfc6 Binary files /dev/null and b/hyhproject/admin/view/img/logon_icon.png differ diff --git a/hyhproject/admin/view/img/main_remind.png b/hyhproject/admin/view/img/main_remind.png new file mode 100755 index 0000000..da8f2b2 Binary files /dev/null and b/hyhproject/admin/view/img/main_remind.png differ diff --git a/hyhproject/admin/view/img/main_remind1.png b/hyhproject/admin/view/img/main_remind1.png new file mode 100755 index 0000000..2c4aab2 Binary files /dev/null and b/hyhproject/admin/view/img/main_remind1.png differ diff --git a/hyhproject/admin/view/img/news_1.png b/hyhproject/admin/view/img/news_1.png new file mode 100755 index 0000000..c65094b Binary files /dev/null and b/hyhproject/admin/view/img/news_1.png differ diff --git a/hyhproject/admin/view/img/news_2.png b/hyhproject/admin/view/img/news_2.png new file mode 100755 index 0000000..ab2d381 Binary files /dev/null and b/hyhproject/admin/view/img/news_2.png differ diff --git a/hyhproject/admin/view/img/news_3.png b/hyhproject/admin/view/img/news_3.png new file mode 100755 index 0000000..10e3789 Binary files /dev/null and b/hyhproject/admin/view/img/news_3.png differ diff --git a/hyhproject/admin/view/img/order_source_1.png b/hyhproject/admin/view/img/order_source_1.png new file mode 100755 index 0000000..4b4cacd Binary files /dev/null and b/hyhproject/admin/view/img/order_source_1.png differ diff --git a/hyhproject/admin/view/img/order_source_2.png b/hyhproject/admin/view/img/order_source_2.png new file mode 100755 index 0000000..d7aa4ad Binary files /dev/null and b/hyhproject/admin/view/img/order_source_2.png differ diff --git a/hyhproject/admin/view/img/order_source_3.png b/hyhproject/admin/view/img/order_source_3.png new file mode 100755 index 0000000..d8803fd Binary files /dev/null and b/hyhproject/admin/view/img/order_source_3.png differ diff --git a/hyhproject/admin/view/img/order_source_4.png b/hyhproject/admin/view/img/order_source_4.png new file mode 100755 index 0000000..f83a077 Binary files /dev/null and b/hyhproject/admin/view/img/order_source_4.png differ diff --git a/hyhproject/admin/view/img/order_source_5.png b/hyhproject/admin/view/img/order_source_5.png new file mode 100755 index 0000000..a4f184d Binary files /dev/null and b/hyhproject/admin/view/img/order_source_5.png differ diff --git a/hyhproject/admin/view/img/tabs-item-bg.gif b/hyhproject/admin/view/img/tabs-item-bg.gif new file mode 100755 index 0000000..5a361a6 Binary files /dev/null and b/hyhproject/admin/view/img/tabs-item-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs-item-left-bg.gif b/hyhproject/admin/view/img/tabs-item-left-bg.gif new file mode 100755 index 0000000..3f77536 Binary files /dev/null and b/hyhproject/admin/view/img/tabs-item-left-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs-item-over-bg.gif b/hyhproject/admin/view/img/tabs-item-over-bg.gif new file mode 100755 index 0000000..6731654 Binary files /dev/null and b/hyhproject/admin/view/img/tabs-item-over-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs-item-right-bg.gif b/hyhproject/admin/view/img/tabs-item-right-bg.gif new file mode 100755 index 0000000..b739eaf Binary files /dev/null and b/hyhproject/admin/view/img/tabs-item-right-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs2-item-left-bg.gif b/hyhproject/admin/view/img/tabs2-item-left-bg.gif new file mode 100755 index 0000000..ac86f02 Binary files /dev/null and b/hyhproject/admin/view/img/tabs2-item-left-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs2-item-over-right-bg.gif b/hyhproject/admin/view/img/tabs2-item-over-right-bg.gif new file mode 100755 index 0000000..f73160b Binary files /dev/null and b/hyhproject/admin/view/img/tabs2-item-over-right-bg.gif differ diff --git a/hyhproject/admin/view/img/tabs2-item-right-bg.gif b/hyhproject/admin/view/img/tabs2-item-right-bg.gif new file mode 100755 index 0000000..f73160b Binary files /dev/null and b/hyhproject/admin/view/img/tabs2-item-right-bg.gif differ diff --git a/hyhproject/admin/view/img/title_head.png b/hyhproject/admin/view/img/title_head.png new file mode 100755 index 0000000..825cde3 Binary files /dev/null and b/hyhproject/admin/view/img/title_head.png differ diff --git a/hyhproject/admin/view/img/togglebar.gif b/hyhproject/admin/view/img/togglebar.gif new file mode 100755 index 0000000..d2fdb1a Binary files /dev/null and b/hyhproject/admin/view/img/togglebar.gif differ diff --git a/hyhproject/admin/view/img/topbg.jpg b/hyhproject/admin/view/img/topbg.jpg new file mode 100755 index 0000000..f987859 Binary files /dev/null and b/hyhproject/admin/view/img/topbg.jpg differ diff --git a/hyhproject/admin/view/img/user_icon_rzxx.png b/hyhproject/admin/view/img/user_icon_rzxx.png new file mode 100755 index 0000000..872cfa4 Binary files /dev/null and b/hyhproject/admin/view/img/user_icon_rzxx.png differ diff --git a/hyhproject/admin/view/index.html b/hyhproject/admin/view/index.html new file mode 100755 index 0000000..f5194fa --- /dev/null +++ b/hyhproject/admin/view/index.html @@ -0,0 +1,144 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" href="__ADMIN__/css/skins/skin-blue.min.css"type="text/css"/> +<link rel="stylesheet" href="__ADMIN__/css/index.css" type="text/css"/> +{/block} +{block name="js"} +<script src="__ADMIN__/js/index.js"></script> +{/block} +{block name="main"} +<style>body,.wrapper{overflow:hidden;}</style> +<div class="wrapper"> + <header class="main-header"> + <a href="#" class="logo"> + <span class="logo-mini">商城后台</span> + <span class="logo-lg">商城后台</span> + </a> + <nav class="navbar navbar-static-top"> + <div class="navbar-custom-menu" style='float:left'> + <ul class='nav navbar-nav'> + <li><a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> + <span class="sr-only">Toggle navigation</span> + </a></li> + {volist name='$sysMenus' id='top'} + <li><a href='#' class='top-menu' dataid='{$top['menuId']}'><i class="fa fa-{$top['menuIcon']}"></i><span>{$top['menuName']}</span></a></li> + {/volist} + </ul> + </div> + <div class="navbar-custom-menu"> + <ul class="nav navbar-nav"> + <!-- <li id='toMall'><a target='_blank' href='{:Url("home/index/index")}'><i class='fa fa-television'></i></a></li> --> + <li id='toSelft'><a target='_blank' href='{:Url('admin/shops/inself')}'><i class='fa fa-podcast'></i></a></li> + <li id='toClearCache'><a class='j-clear-cache' href='#'><i class='fa fa-spinner'></i></a></li> + <li id='toLogout'><a class='j-logout' href='#' title='退出系统'><i class='fa fa-power-off'></i></a></li> + </ul> + </div> + </nav> + </header> + <aside class="main-sidebar"> + <section class="sidebar"> + <div class="user-panel"> + <div class="pull-left image"> + <img src="__IMGURL__/{$Think.session.WST_STAFF.staffPhoto}" class="img-circle" alt="User Image"> + </div> + <div class="pull-left info"> + <p>{$Think.session.WST_STAFF.loginName}</p> + <p>系统管理员</p> + </div> + <div class='pull-left button'> + <a href='javascript:void(0);' class='j-edit-pass edit-pass'><i class='fa fa-key'></i><span>修改密码</span></a> + <a href='javascript:void(0);' class='j-logout logout'><i class='fa fa-power-off'></i><span>退出系统</span></a> + </div> + </div> + + <ul class="sidebar-menu" data-widget="tree"> + {volist name="sysMenus" key='key0' id='left0'} + {if !empty($left0['child'])} + {volist name="left0['child']" id='left1'} + <li class="treeview j-menulevel0 j-sysmenu{$left0['menuId']}" {if $key0>1}style='display:none'{/if}"> + <a href="#"> + <i class="fa fa-{$left1['menuIcon']?$left1['menuIcon']:'eercast'}"></i> <span>{$left1['menuName']}</span> + <span class="pull-right-container"> + <i class="fa fa-angle-left pull-right"></i> + </span> + </a> + {if !empty($left1['child'])} + <ul class="treeview-menu"> + {volist name="left1['child']" id='left2'} + <li><a class='menuItem' href="{:Url($left2['privilegeUrl'])}" dataid='{$left2['menuId']}'><i class="fa fa-{$left2['menuIcon']?$left2['menuIcon']:'circle-o'}"></i>{$left2['menuName']}{if !empty($left2['child'])}<i class="fa fa-angle-left pull-right"></i>{/if}</a> + {if !empty($left2['child'])} + <ul class="treeview-menu"> + {volist name="left2['child']" id='left3'} + <li> + <a class="menuItem" href="{$left3['privilegeUrl']}" dataid='{$left2['menuId']}'><i class="fa fa-{$left3['menuIcon']?$left3['menuIcon']:'circle-o'}"></i>{$left3['menuName']} + </a> + </li> + {/volist} + </ul> + {/if} + </li> + {/volist} + </ul> + {/if} + </li> + {/volist} + {/if} + {/volist} + </ul> + </section> + </aside> + <div class="content-wrapper"> + <section class="content-header"> + <ol class="breadcrumb"> + <li><a href='{$Request.root.true}' target='_blank'><i class='fa fa-map-marker'></i>首页</a></li> + </ol> + <button id='toFullSreen' class="fullscreen"><i class="fa fa-arrows-alt"></i></button> + </section> + <section class="content-iframe" style="margin:0px;padding:0;height:100%"> + <iframe id='iframe' class="iframe" width="100%" height="100%" src="{:Url('admin/index/main')}" frameborder="0"></iframe> + </section> + </div> +</div> +<div id='editPassBox' style='display:none;padding-top:5px;'> + <form id='editPassFrom' autocomplete="off"> + <table class='wst-form'> + <tr> + <th style='width:100px'>原密码:</th> + <td><input type='password' id='srcPass' name='srcPass' class='ipt' data-rule="原密码: required;" maxLength='16'/></td> + </tr> + <tr> + <th>新密码:</th> + <td><input type='password' id='newPass' name='newPass' class='ipt' data-rule="新密码: required;length[6~]" maxLength='16'/></td> + </tr> + <tr> + <th>确认密码:</th> + <td><input type='password' id='newPass2' name='newPass2' class='ipt' data-rule="确认密码: required;match(newPass);" maxLength='16'/></td> + </tr> + </table> + </form> +</div> + +<script> +var menus = {:json_encode($sysMenus)}; +function showImg(opt){ + layer.photos(opt); +} +function showBox(opts){ + return WST.open(opts); +} +$(function(){ + $('#toMall').poshytip({content:'点击打开商城首页',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toSelft').poshytip({content:'点击打开自营店铺',showTimeout:0,hideTimeout:1, + offsetY: 25,timeOnScreen:1000,allowTipHover: false}); + $('#toTechSupp').poshytip({content:'点击打开技术支持页面',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toClearCache').poshytip({content:'点击清除服务器缓存',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toLogout').poshytip({content:'点击退出系统',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toFullSreen').poshytip({content:'点击全屏展示',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/informs/handle.html b/hyhproject/admin/view/informs/handle.html new file mode 100755 index 0000000..e33f69c --- /dev/null +++ b/hyhproject/admin/view/informs/handle.html @@ -0,0 +1,158 @@ +{extend name="base" /} +{block name="css"} +{/block} +{block name="js"} +<script src="__ADMIN__/informs/informs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">举报详情</li> + </ul> + <div class="layui-tab-content" style="margin:10px;"> + <div class="layui-tab-item layui-show"> + <!-- 举报信息 --> + <div class='order-box'> + <table class='wst-form wst-table-1'> + <tr> + <td class='head-ititle'>举报信息</td> + </tr> + <tr> + <th>举报人:</th> + <td>{$data['userName']}</td> + </tr> + <tr> + <th>举报类型:</th> + <td> + {php}$reason = WSTDatas('INFORMS_TYPE',$data['informType']);{/php} + {$reason['dataName']} + </td> + </tr> + + <tr> + <th>举报内容:</th> + <td class='line-break'>{$data['informContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td id="photos-inform"> + {if !empty($data['informAnnex'])} + {volist name="$data['informAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}" /> + </a> + {/volist} + {/if} + </td> + </tr> + + <tr> + <th>投诉时间:</th> + <td>{$data['informTime']}</td> + </tr> + </table> + </div> + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <table border='0' class='wst-form wst-table-1' style='margin-top:15px;'> + <tr> + <td colspan='2' class='head'>举报结果</td> + </tr> + <tr> + <th width='80'>举报结果:</th> + <td> + {if condition="$data['informStatus'] eq 0"} + 等待处理 + {elseif condition="$data['informStatus'] eq 1"/} + 无效举报 + {elseif condition="$data['informStatus'] eq 2 "/} + 有效举报 + {elseif condition="$data['informStatus'] eq 3 "/} + 恶意举报 + {/if} + </td> + </tr> + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <tr> + <th valign='top'>处理信息:</th> + <td class='line-break'> + {$data['respondContent']} + </td> + </tr> + {/if} + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <tr> + <th>处理时间:</th> + <td>{$data['finalHandleTime']}&nbsp;</td> + </tr> + {/if} + <tr> + <td colspan='2' style='text-align:center;'> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + </table> + {/if} + <!--举报结果 --> + {if condition="$data['informStatus'] eq 0"} + <div class='order-box' style="border-bottom: 1px solid transparent;"> + <table class='wst-form wst-table-1'> + <tr> + <td class='head-ititle'>举报结果</td> + </tr> + <tr> + <td align='right' valign='right' width='120'>当前举报流程:</td> + <td style='color:red'> + {:WSTLangComplainStatus($data['informStatus'])} + </td> + </tr> + <tr> + <th>举报结果<font color='red'>*</font>:</th> + <td class='layui-form'> + <li> + <label> + <input type='radio' name='informStatus' class='ipt' value='1' title='无效举报--商品会正常销售'/> + </label> + </li> + <li> + <label> + <input type='radio' name='informStatus' class='ipt' value='2' title='有效举报--商品将被违规下架'/> + </label> + </li> + <li> + <label> + <input type='radio' name='informStatus' class='ipt' value='3' title='恶意举报--该用户所有未处理举报将被取消且将被禁止举报'/> + </label> + </li> + </td> + </tr> + <tr> + <th>处理信息<font color='red'>*</font>:</th> + <td class='line-break'> + <textarea id='finalResult' style='height:150px;width:100%' placeholder=''></textarea> + </td> + </tr> + + + <tr> + <td colspan='2' align='center' > + <button type="button" class="btn btn-primary btn-mright"style="margin-top:10px ;" onclick='javascript:finalHandle({$data["informId"]})'><i class="fa fa-gavel"></i> +处&nbsp;理</button> + <button type="button" class="btn"style="margin-top:10px ;" onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> + + </table> + </div> + {/if} + </div> +<div> + </div> +</div> +</div> +<script> +$(function(){ + parent.showImg({photos: $('#photos-inform')}); +}); +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/informs/informs.js b/hyhproject/admin/view/informs/informs.js new file mode 100755 index 0000000..bdf9803 --- /dev/null +++ b/hyhproject/admin/view/informs/informs.js @@ -0,0 +1,92 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsImg', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + // thumb = thumb.replace('.','_thumb.'); + return "<span class='weixin'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'举报商品',sortable: true, name:'goodsName',renderer: function(val,item,rowIndex){ + return "<a style='color:blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><span><p class='wst-nowrap'>"+item['goodsName']+"</p></span></a>"; + }}, + {title:'举报店铺',sortable: true, name:'shopName'}, + {title:'举报人', name:'userName', width: 30,sortable: true, renderer: function(val,item,rowIndex){ + return WST.blank(item['userName'],item['loginName']); + }}, + {title:'举报类型',sortable: true, name:'informType'}, + {title:'举报时间',sortable: true, name:'informTime'}, + {title:'状态', name:'informStatus', renderer: function(val,item,rowIndex){ + if(val==0) + return "<span class='statu-wait'><i class='fa fa-clock-o'></i> 等待处理</span>"; + else if(val==1) + return "<span class='statu-no'><i class='fa fa-ban'></i> 无效举报</span>"; + else if(val==2) + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 有效举报</span>"; + else if(val==3) + return "<span class='statu-no'><i class='fa fa-exclamation-triangle'></i> 恶意举报</span>"; + }}, + {title:'操作', name:'op' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toView(" + item['informId'] + ")'><i class='fa fa-search'></i>查看</a> "; + if(item['informStatus']==0) + h += "<a class='btn btn-blue' href='javascript:toHandle(" + item['informId'] + ")'><i class='fa fa-pencil'></i>处理</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Informs/pageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'informTime', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toView(id){ + location.href=WST.U('admin/Informs/view','cid='+id); +} +function toHandle(id){ + location.href=WST.U('admin/Informs/toHandle','cid='+id); +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} + + + +function finalHandle(id){ + var params = {}; + params.cid = id; + params.finalResult = $.trim($('#finalResult').val()); + params.informStatus = $('input:radio:checked').val(); + if(params.finalResult==''){ + WST.msg('请输入处理信息!',{icon:2}); + return; + } + if(typeof(params.informStatus)=='undefined'){ + WST.msg('请选择处理结果',{icon:2}); + return; + } + var c = WST.confirm({title:'信息提示',content:'您确定处理该举报商品吗?',yes:function(){ + layer.close(c); + $.post(WST.U('Admin/Informs/finalHandle'),params,function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + location.reload(); + }else if(json.status == '2'){ + location.href=WST.U('admin/informs/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + diff --git a/hyhproject/admin/view/informs/list.html b/hyhproject/admin/view/informs/list.html new file mode 100755 index 0000000..712c046 --- /dev/null +++ b/hyhproject/admin/view/informs/list.html @@ -0,0 +1,28 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/informs/informs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id='informStatus' class='j-ipt'> + <option value='-1'>举报处理状态</option> + <option value='0'>等待处理</option> + <option value='1'>无效举报</option> + <option value='2'>有效举报</option> + <option value='3'>恶意举报</option> + </select> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/informs/view.html b/hyhproject/admin/view/informs/view.html new file mode 100755 index 0000000..3015be0 --- /dev/null +++ b/hyhproject/admin/view/informs/view.html @@ -0,0 +1,97 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/informs/informs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id="wst-tabs" style="width:100%; height:99%;overflow: hidden;" class="liger-tab"> + <div id="wst-tab-1" tabId="wst-tab-1" title="举报详情" class='wst-tab' style="height: 100%"> + <div style="margin:10px"> + <!-- 投诉信息 --> + <div class='order-box'> + <table class='wst-form wst-table-1'> + <tr> + <td class='head-ititle'>举报信息</td> + </tr> + <tr> + <th>举报人:</th> + <td>{$data['userName']}</td> + </tr> + <tr> + <th>举报类型:</th> + <td> + {php}$reason = WSTDatas('INFORMS_TYPE',$data['informType']);{/php} + {$reason['dataName']} + </td> + </tr> + + <tr> + <th>举报内容:</th> + <td class='line-break'>{$data['informContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td id="photos-inform"> + {if !empty($data['informAnnex'])} + {volist name="$data['informAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}" /> + </a> + {/volist} + {/if} + </td> + </tr> + + <tr> + <th>投诉时间:</th> + <td>{$data['informTime']}</td> + </tr> + </table> +</div> + <table border='0' class='wst-form wst-table-1' style='margin-top:15px;'> + <tr> + <td colspan='2' class='head'>举报结果</td> + </tr> + <tr> + <th width='80'>举报结果:</th> + <td> + {if condition="$data['informStatus'] eq 0"} + 等待处理 + {elseif condition="$data['informStatus'] eq 1"/} + 无效举报 + {elseif condition="$data['informStatus'] eq 2 "/} + 有效举报 + {elseif condition="$data['informStatus'] eq 3 "/} + 恶意举报 + {/if} + </td> + </tr> + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <tr> + <th valign='top'>处理信息:</th> + <td class='line-break'> + {$data['respondContent']} + </td> + </tr> + {/if} + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <tr> + <th>处理时间:</th> + <td>{$data['finalHandleTime']}&nbsp;</td> + </tr> + {/if} + <tr> + <td colspan='2' align='center'> + <button type="button" class="btn" onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> + </table> + </div> +</div> +</div> + +<script> +$(function(){ + parent.showImg({photos: $('#photos-inform')}); +}); +</script> +{/block} diff --git a/hyhproject/admin/view/js/bootstrap/css/bootstrap.min.css b/hyhproject/admin/view/js/bootstrap/css/bootstrap.min.css new file mode 100755 index 0000000..ed3905e --- /dev/null +++ b/hyhproject/admin/view/js/bootstrap/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.eot b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.eot new file mode 100755 index 0000000..b93a495 Binary files /dev/null and b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.eot differ diff --git a/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.svg b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.svg new file mode 100755 index 0000000..94fb549 --- /dev/null +++ b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata></metadata> +<defs> +<font id="glyphicons_halflingsregular" horiz-adv-x="1200" > +<font-face units-per-em="1200" ascent="960" descent="-240" /> +<missing-glyph horiz-adv-x="500" /> +<glyph horiz-adv-x="0" /> +<glyph horiz-adv-x="400" /> +<glyph unicode=" " /> +<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" /> +<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xa0;" /> +<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" /> +<glyph unicode="&#x2000;" horiz-adv-x="650" /> +<glyph unicode="&#x2001;" horiz-adv-x="1300" /> +<glyph unicode="&#x2002;" horiz-adv-x="650" /> +<glyph unicode="&#x2003;" horiz-adv-x="1300" /> +<glyph unicode="&#x2004;" horiz-adv-x="433" /> +<glyph unicode="&#x2005;" horiz-adv-x="325" /> +<glyph unicode="&#x2006;" horiz-adv-x="216" /> +<glyph unicode="&#x2007;" horiz-adv-x="216" /> +<glyph unicode="&#x2008;" horiz-adv-x="162" /> +<glyph unicode="&#x2009;" horiz-adv-x="260" /> +<glyph unicode="&#x200a;" horiz-adv-x="72" /> +<glyph unicode="&#x202f;" horiz-adv-x="260" /> +<glyph unicode="&#x205f;" horiz-adv-x="325" /> +<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" /> +<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" /> +<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" /> +<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" /> +<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" /> +<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " /> +<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" /> +<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" /> +<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" /> +<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" /> +<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" /> +<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" /> +<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" /> +<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" /> +<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" /> +<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" /> +<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" /> +<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" /> +<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" /> +<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" /> +<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" /> +<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" /> +<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" /> +<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" /> +<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" /> +<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " /> +<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" /> +<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" /> +<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> +<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" /> +<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" /> +<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" /> +<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" /> +<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" /> +<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" /> +<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" /> +<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" /> +<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" /> +<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" /> +<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> +<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" /> +<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" /> +<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" /> +<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" /> +<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" /> +<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" /> +<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" /> +<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" /> +<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" /> +<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" /> +<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" /> +<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" /> +<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" /> +<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" /> +<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" /> +<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" /> +<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" /> +<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" /> +<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" /> +<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" /> +<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" /> +<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" /> +<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" /> +<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" /> +<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" /> +<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" /> +<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" /> +<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" /> +<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" /> +<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" /> +<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" /> +<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" /> +<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" /> +<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" /> +<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" /> +<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" /> +<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" /> +<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" /> +<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" /> +<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" /> +<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> +<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" /> +<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" /> +<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" /> +<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" /> +<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" /> +<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" /> +<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" /> +<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" /> +<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" /> +<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" /> +<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" /> +<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" /> +<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" /> +<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" /> +<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" /> +<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" /> +<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" /> +<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" /> +<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" /> +<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" /> +<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" /> +<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" /> +<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" /> +<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" /> +<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " /> +<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" /> +<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" /> +<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" /> +<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" /> +<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" /> +<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" /> +<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" /> +<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" /> +<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" /> +<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" /> +<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" /> +<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " /> +<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " /> +<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" /> +<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" /> +<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" /> +<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" /> +<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" /> +<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" /> +<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" /> +<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" /> +<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> +<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" /> +<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" /> +<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" /> +<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" /> +<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" /> +<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" /> +<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" /> +<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" /> +<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" /> +<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" /> +<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" /> +<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" /> +<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" /> +<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" /> +<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" /> +<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" /> +<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" /> +<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" /> +<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " /> +<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> +<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" /> +<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" /> +<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" /> +<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" /> +<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" /> +<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" /> +<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" /> +<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" /> +<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" /> +<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" /> +<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" /> +<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" /> +<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" /> +<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" /> +<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" /> +<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" /> +<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" /> +<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" /> +<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" /> +<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" /> +<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" /> +<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" /> +<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" /> +<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " /> +<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" /> +<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" /> +<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" /> +<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" /> +<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> +<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" /> +<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" /> +<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> +<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" /> +<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" /> +<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" /> +<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" /> +<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" /> +<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" /> +<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" /> +<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" /> +<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" /> +<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" /> +<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" /> +<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" /> +<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" /> +<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" /> +<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" /> +<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" /> +<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" /> +<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" /> +<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" /> +<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" /> +<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" /> +<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" /> +<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" /> +<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" /> +<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" /> +<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" /> +<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" /> +</font> +</defs></svg> \ No newline at end of file diff --git a/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.ttf b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.ttf new file mode 100755 index 0000000..1413fc6 Binary files /dev/null and b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.ttf differ diff --git a/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff new file mode 100755 index 0000000..9e61285 Binary files /dev/null and b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff differ diff --git a/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff2 b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff2 new file mode 100755 index 0000000..64539b5 Binary files /dev/null and b/hyhproject/admin/view/js/bootstrap/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/hyhproject/admin/view/js/bootstrap/js/bootstrap.min.js b/hyhproject/admin/view/js/bootstrap/js/bootstrap.min.js new file mode 100755 index 0000000..854296c --- /dev/null +++ b/hyhproject/admin/view/js/bootstrap/js/bootstrap.min.js @@ -0,0 +1,8 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + * vn:00119f3fc12403a05a1ef5609ff96e66 + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){ +this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/common.js b/hyhproject/admin/view/js/common.js new file mode 100755 index 0000000..a6e8828 --- /dev/null +++ b/hyhproject/admin/view/js/common.js @@ -0,0 +1,548 @@ +/**WST.GRANR--权限函数,保留,请勿覆盖**/ +WST.tips = function(content, selector, options){ + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'100px'}, options); + return layer.confirm(opts.content,{icon: 3, title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + options.time = 1000; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + }else if(options.icon==16){ + options.icon='wstloading'; + options.time = 0; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:2000,shade: [0.4, '#000000']},options); + return layer.msg(msg,opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.pageSizeOptions = [50,100,150,200]; +WST.pageSize = 50; +WST.toAdminJson = function(str){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} +WST.upload = function(opts){ + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('admin/index/uploadPic')},opts); + var uploader = WebUploader.create(_opts); + uploader.on('uploadSuccess', function( file,response ) { + var json = WST.toAdminJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} +WST.getAreas = function(obj,id,val,fval,callback){ + var params = {}; + params.parentId = id; + $("#"+obj).empty(); + $("#"+obj).html("<option value=''>请选择</option>"); + var s = []; + if(fval!=''){ + s = fval.split(','); + for(var i=0;i<s.length;i++){ + $("#"+s[i]).empty(); + $("#"+s[i]).html("<option value=''>请选择</option>"); + } + } + if(id == 0 || id == ''){ + s = fval.split(','); + for(var i=0;i<s.length;i++){ + $("#"+s[i]).empty(); + $("#"+s[i]).html("<option value=''>请选择</option>"); + } + return; + } + $.post(WST.U('admin/areas/listQuery'),params,function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status==1 && json.data){ + var opts,html=[]; + html.push("<option value=''>请选择</option>"); + for(var i=0;i<json.data.length;i++){ + opts = json.data[i]; + html.push('<option value="'+opts.areaId+'" '+((val==opts.areaId)?'selected':'')+'>'+opts.areaName+'</option>'); + } + $("#"+obj).html(html.join('')); + if(typeof(callback)=='function')callback(); + } + }); +} +$(function(){ + if(WST.conf && WST.conf.GRANT)WST.getGrants(WST.conf.GRANT); + WST.hidePageLoading(); +}) +WST.getGrants = function(grant){ + WST['GRANT'] = {}; + if(!grant)return; + var str = grant.split(','); + for(var i=0;i<str.length;i++){ + WST['GRANT'][str[i]] = true; + } +} +/** + * 把对象变成数组 + */ +WST.arrayParams = function(v){ + var p = WST.getParams(v); + var params = []; + for(var key in p){ + params.push(key+"="+p[key]); + } + return params; +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('admin/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('admin/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('admin/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('admin/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} + +WST.hidePageLoading = function(){ + $(window).load(function () { + window.setTimeout(function () { + $('#j-loader').fadeOut(); + }, 10); + }); +} + +$.fn.WSTTips = function(opts){ + var obj = this; + var pobj = obj.parent(); + var isShow = true; + var log = {w:pobj.width(),h:pobj.height()}; + $(document.body).css('overflow-y','hidden'); + obj.click(function(){ + if(isShow){ + pobj.animate({height:opts.height,width:opts.width},300,function(){ + isShow = false; + if(opts.callback)opts.callback(isShow); + }); + }else{ + pobj.animate({width:'99%'},300,function(){ + pobj.animate({height:'100%'},100,function(){ + isShow = true; + if(opts.callback)opts.callback(isShow); + }); + }); + } + $(document).css('overflow-y','auto'); + }) + +} + +WST.toolTip = function(){ + $('body').mousemove(function(e){ + var windowH = $(window).height(); + if(e.pageY >= windowH*0.72){ + var top = windowH*0.28; + $('.imged').css('margin-top',-top); + }else{ + var top = windowH*0.055; + $('.imged').css('margin-top',-top); + } + }); +} +/*! nice-validator 1.0.4 + * (c) 2012-2016 Jony Zhang <niceue@live.com>, MIT Licensed + * https://github.com/niceue/nice-validator + */ +!function(e){"object"==typeof module&&module.exports?module.exports=e(require("jquery")):"function"==typeof define&&define.amd?require(["jquery"],e):e(jQuery)}(function(e,t){"use strict";function i(t,n){function s(){a._init(a.$el[0],n,!!arguments[0])}var a=this;return a instanceof i?(a.$el=e(t),void(a.$el.length?(s(),i.pending&&e(window).on("validatorready",s)):J(t)&&(G[t]=n))):new i(t,n)}function n(t){function i(){var t=this.options;for(var i in t)i in Y&&(this[i]=t[i]);e.extend(this,{_valHook:function(){return null!==this.element.getAttribute("contenteditable")?"text":"val"},getValue:function(){var t=this.element;return"number"===t.type&&t.validity&&t.validity.badInput?"NaN":e(t)[this._valHook()]()},setValue:function(t){e(this.element)[this._valHook()](this.value=t)},getRangeMsg:function(e,t,i){function n(e,t){return o?e>t:e>=t}if(t){var s,a=this,r=a.messages[a._r]||"",l=t[0].split("~"),o="false"===t[1],u=l[0],d=l[1],c="rg",f=[""],g=U(e)&&+e===+e;return 2===l.length?u&&d?(g&&n(e,+u)&&n(+d,e)&&(s=!0),f=f.concat(l),c=o?"gtlt":"rg"):u&&!d?(g&&n(e,+u)&&(s=!0),f.push(u),c=o?"gt":"gte"):!u&&d&&(g&&n(+d,e)&&(s=!0),f.push(d),c=o?"lt":"lte"):(e===+u&&(s=!0),f.push(u),c="eq"),r&&(i&&r[c+i]&&(c+=i),f[0]=r[c]),s||a._rules&&(a._rules[a._i].msg=a.renderMsg.apply(null,f))}},renderMsg:function(){var e=arguments,t=e[0],i=e.length;if(t){for(;--i;)t=t.replace("{"+i+"}",e[i]);return t}}})}function n(i,n,s){this.key=i,this.validator=t,e.extend(this,s,n)}return i.prototype=t,n.prototype=new i,n}function s(e,t){if(Q(e)){var i,n=t?t===!0?this:t:s.prototype;for(i in e)g(i)&&(n[i]=r(e[i]))}}function a(e,t){if(Q(e)){var i,n=t?t===!0?this:t:a.prototype;for(i in e)n[i]=e[i]}}function r(t){switch(e.type(t)){case"function":return t;case"array":var i=function(){return t[0].test(this.value)||t[1]||!1};return i.msg=t[1],i;case"regexp":return function(){return t.test(this.value)}}}function l(t){var i,n,s;if(t&&t.tagName){switch(t.tagName){case"INPUT":case"SELECT":case"TEXTAREA":case"BUTTON":case"FIELDSET":i=t.form||e(t).closest("."+k);break;case"FORM":i=t;break;default:i=e(t).closest("."+k)}for(n in G)if(e(i).is(n)){s=G[n];break}return e(i).data(h)||e(i)[h](s).data(h)}}function o(e,t){var i=U(z(e,M+"-"+t));if(i&&(i=new Function("return "+i)()))return r(i)}function u(e,t,i){var n=t.msg,s=t._r;return Q(n)&&(n=n[s]),J(n)||(n=z(e,O+"-"+s)||z(e,O)||(i?J(i)?i:i[s]:"")),n}function d(e){var t;return e&&(t=I.exec(e)),t&&t[0]}function c(e){return"INPUT"===e.tagName&&"checkbox"===e.type||"radio"===e.type}function f(e){return Date.parse(e.replace(/\.|\-/g,"/"))}function g(e){return/^\w+$/.test(e)}function m(e){var t="#"===e.charAt(0);return e=e.replace(/([:.{(|)}\/\[\]])/g,"\\$1"),t?e:'[name="'+e+'"]:first'}var p,h="validator",v="."+h,_=".rule",y=".field",b=".form",k="nice-"+h,w="msg-box",x="aria-required",V="aria-invalid",M="data-rule",O="data-msg",F="data-tip",$="data-ok",C="data-timely",E="data-target",A="data-display",j="data-must",T="novalidate",N=":verifiable",S=/(&)?(!)?\b(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\|)?/g,q=/(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/,R=/(?:([^:;\(\[]*):)?(.*)/,D=/[^\x00-\xff]/g,I=/top|right|bottom|left/,H=/(?:(cors|jsonp):)?(?:(post|get):)?(.+)/i,L=/[<>'"`\\]|&#x?\d+[A-F]?;?|%3[A-F]/gim,B=e.noop,P=e.proxy,U=e.trim,W=e.isFunction,J=function(e){return"string"==typeof e},Q=function(e){return e&&"[object Object]"===Object.prototype.toString.call(e)},X=document.documentMode||+(navigator.userAgent.match(/MSIE (\d+)/)&&RegExp.$1),z=function(e,i,n){return e&&e.tagName?n===t?e.getAttribute(i):void(null===n?e.removeAttribute(i):e.setAttribute(i,""+n)):null},G={},K={debug:0,theme:"default",ignore:"",focusInvalid:!0,focusCleanup:!1,stopOnError:!1,beforeSubmit:null,valid:null,invalid:null,validation:null,validClass:"n-valid",invalidClass:"n-invalid",bindClassTo:null},Y={timely:1,display:null,target:null,ignoreBlank:!1,showOk:!0,dataFilter:function(e){if(J(e)||Q(e)&&("error"in e||"ok"in e))return e},msgMaker:function(t){var i;return i='<span role="alert" class="msg-wrap n-'+t.type+'">'+t.arrow,t.result?e.each(t.result,function(e,n){i+='<span class="n-'+n.type+'">'+t.icon+'<span class="n-msg">'+n.msg+"</span></span>"}):i+=t.icon+'<span class="n-msg">'+t.msg+"</span>",i+="</span>"},msgWrapper:"span",msgArrow:"",msgIcon:'<span class="n-icon"></span>',msgClass:"",msgStyle:"",msgShow:null,msgHide:null},Z={default:{formClass:"n-default",msgClass:"n-right"}};return e.fn.validator=function(t){var n=this,s=arguments;return n.is(N)?n:(n.is("form")||(n=this.find("form")),n.length||(n=this),n.each(function(){var n=e(this).data(h);if(n)if(J(t)){if("_"===t.charAt(0))return;n[t].apply(n,[].slice.call(s,1))}else t&&(n._reset(!0),n._init(this,t));else new i(this,t)}),this)},e.fn.isValid=function(e,i){var n,s,a=l(this[0]),r=W(e);return!a||(r||i!==t||(i=e),a.checkOnly=!!i,s=a.options,n=a._multiValidate(this.is(N)?this:this.find(N),function(t){t||!s.focusInvalid||a.checkOnly||a.$el.find("["+V+"]:first").focus(),r&&(e.length?e(t):t&&e()),a.checkOnly=!1}),r?this:n)},e.expr.pseudos.verifiable=function(e){var t=e.nodeName.toLowerCase();return("input"===t&&!{submit:1,button:1,reset:1,image:1}[e.type]||"select"===t||"textarea"===t||"true"===e.contentEditable)&&!e.disabled},e.expr.pseudos.filled=function(t){return!!U(e(t).val())},i.prototype={_init:function(t,i,r){var l,o,u,d=this;W(i)&&(i={valid:i}),i=d._opt=i||{},u=z(t,"data-"+h+"-option"),u=d._dataOpt=u&&"{"===u.charAt(0)?new Function("return "+u)():{},o=d._themeOpt=Z[i.theme||u.theme||K.theme],l=d.options=e.extend({},K,Y,o,d.options,i,u),r||(d.rules=new s(l.rules,(!0)),d.messages=new a(l.messages,(!0)),d.Field=n(d),d.elements=d.elements||{},d.deferred={},d.errors={},d.fields={},d._initFields(l.fields)),d.$el.data(h)||(d.$el.data(h,d).addClass(k+" "+l.formClass).on("form-submit-validate",function(e,t,i,n,s){d.vetoed=s.veto=!d.isValid,d.ajaxFormOptions=n}).on("submit"+v+" validate"+v,P(d,"_submit")).on("reset"+v,P(d,"_reset")).on("showmsg"+v,P(d,"_showmsg")).on("hidemsg"+v,P(d,"_hidemsg")).on("focusin"+v+" click"+v,N,P(d,"_focusin")).on("focusout"+v+" validate"+v,N,P(d,"_focusout")).on("keyup"+v+" input"+v+" compositionstart compositionend",N,P(d,"_focusout")).on("click"+v,":radio,:checkbox","click",P(d,"_focusout")).on("change"+v,'select,input[type="file"]',"change",P(d,"_focusout")),d._NOVALIDATE=z(t,T),z(t,T,T)),J(l.target)&&d.$el.find(l.target).addClass("msg-container")},_guessAjax:function(t){function i(t,i,n){return!!(t&&t[i]&&e.map(t[i],function(e){return~e.namespace.indexOf(n)?1:null}).length)}var n=this;if(!(n.isAjaxSubmit=!!n.options.valid)){var s=(e._data||e.data)(t,"events");n.isAjaxSubmit=i(s,"valid","form")||i(s,"submit","form-plugin")}},_initFields:function(e){function t(e,t){if(null===t||r){var i=a.elements[e];i&&a._resetElement(i,!0),delete a.fields[e]}else a.fields[e]=new a.Field(e,J(t)?{rule:t}:t,a.fields[e])}var i,n,s,a=this,r=null===e;if(r&&(e=a.fields),Q(e))for(i in e)if(~i.indexOf(","))for(n=i.split(","),s=n.length;s--;)t(U(n[s]),e[i]);else t(i,e[i]);a.$el.find(N).each(function(){a._parse(this)})},_parse:function(e){var t,i,n,s=this,a=e.name,r=z(e,M);if(r&&z(e,M,null),e.id&&("#"+e.id in s.fields||!a||null!==r&&(t=s.fields[a])&&r!==t.rule&&e.id!==t.key)&&(a="#"+e.id),a)return t=s.getField(a,!0),t.rule=r||t.rule,(i=z(e,A))&&(t.display=i),t.rule&&((null!==z(e,j)||/\b(?:match|checked)\b/.test(t.rule))&&(t.must=!0),/\brequired\b/.test(t.rule)&&(t.required=!0,z(e,x,!0)),(n=z(e,C))?t.timely=+n:t.timely>3&&z(e,C,t.timely),s._parseRule(t),t.old={}),J(t.target)&&z(e,E,t.target),J(t.tip)&&z(e,F,t.tip),s.fields[a]=t},_parseRule:function(i){var n=R.exec(i.rule);n&&(i._i=0,n[1]&&(i.display=n[1]),n[2]&&(i._rules=[],n[2].replace(S,function(){var n=arguments;n[4]=n[4]||n[5],i._rules.push({and:"&"===n[1],not:"!"===n[2],or:"|"===n[6],method:n[3],params:n[4]?e.map(n[4].split(", "),U):t})})))},_multiValidate:function(i,n){var s=this,a=s.options;return s.hasError=!1,a.ignore&&(i=i.not(a.ignore)),i.each(function(){if(s._validate(this),s.hasError&&a.stopOnError)return!1}),n&&(s.validating=!0,e.when.apply(null,e.map(s.deferred,function(e){return e})).done(function(){n.call(s,!s.hasError),s.validating=!1})),e.isEmptyObject(s.deferred)?!s.hasError:t},_submit:function(i){var n=this,s=n.options,a=i.target,r="submit"===i.type&&!i.isDefaultPrevented();i.preventDefault(),p&&~(p=!1)||n.submiting||"validate"===i.type&&n.$el[0]!==a||W(s.beforeSubmit)&&s.beforeSubmit.call(n,a)===!1||(n.isAjaxSubmit===t&&n._guessAjax(a),n._debug("log","\n<<< event: "+i.type),n._reset(),n.submiting=!0,n._multiValidate(n.$el.find(N),function(t){var i,l=t||2===s.debug?"valid":"invalid";t||(s.focusInvalid&&n.$el.find("["+V+"]:first").focus(),i=e.map(n.errors,function(e){return e})),n.submiting=!1,n.isValid=t,W(s[l])&&s[l].call(n,a,i),n.$el.trigger(l+b,[a,i]),n._debug("log",">>> "+l),t&&(n.vetoed?e(a).ajaxSubmit(n.ajaxFormOptions):r&&!n.isAjaxSubmit&&document.createElement("form").submit.call(a))}))},_reset:function(e){var t=this;t.errors={},e&&(t.reseting=!0,t.$el.find(N).each(function(){t._resetElement(this)}),delete t.reseting)},_resetElement:function(e,t){this._setClass(e,null),this.hideMsg(e),t&&z(e,x,null)},_focusin:function(e){var t,i,n=this,s=n.options,a=e.target;n.validating||"click"===e.type&&document.activeElement===a||(s.focusCleanup&&"true"===z(a,V)&&(n._setClass(a,null),n.hideMsg(a)),i=z(a,F),i?n.showMsg(a,{type:"tip",msg:i}):(z(a,M)&&n._parse(a),(t=z(a,C))&&(8!==t&&9!==t||n._focusout(e))))},_focusout:function(t){var i,n,s,a,r,l,o,u,d,f=this,g=f.options,m=t.target,p=t.type,h="focusin"===p,v="validate"===p,_=0;if("compositionstart"===p&&(f.pauseValidate=!0),"compositionend"===p&&(f.pauseValidate=!1),!f.pauseValidate&&(n=m.name&&c(m)?f.$el.find('input[name="'+m.name+'"]').get(0):m,s=f.getField(n))){if(i=s._e,s._e=p,d=s.timely,!v){if(!d||c(m)&&"click"!==p)return;if(r=s.getValue(),s.ignoreBlank&&!r&&!h)return void f.hideMsg(m);if("focusout"===p){if("change"===i)return;if(2===d||8===d){if(!r)return;a=s.old,s.isValid&&!a.showOk?f.hideMsg(m):f._makeMsg(m,s,a)}}else{if(d<2&&!t.data)return;if(l=+new Date,l-(m._ts||0)<100)return;if(m._ts=l,"keyup"===p){if("input"===i)return;if(o=t.keyCode,u={8:1,9:1,16:1,32:1,46:1},9===o&&!r)return;if(o<48&&!u[o])return}h||(_=d<100?"click"===p||"SELECT"===m.tagName?0:400:d)}}g.ignore&&e(m).is(g.ignore)||(clearTimeout(s._t),_?s._t=setTimeout(function(){f._validate(m,s)},_):(v&&(s.old={}),f._validate(m,s)))}},_setClass:function(t,i){var n=e(t),s=this.options;s.bindClassTo&&(n=n.closest(s.bindClassTo)),n.removeClass(s.invalidClass+" "+s.validClass),null!==i&&n.addClass(i?s.validClass:s.invalidClass)},_showmsg:function(t,i,n){var s=this,a=t.target;e(a).is(N)?s.showMsg(a,{type:i,msg:n}):"tip"===i&&s.$el.find(N+"["+F+"]",a).each(function(){s.showMsg(this,{type:i,msg:n})})},_hidemsg:function(t){var i=e(t.target);i.is(N)&&this.hideMsg(i)},_validatedField:function(t,i,n){var s=this,a=s.options,r=i.isValid=n.isValid=!!n.isValid,l=r?"valid":"invalid";n.key=i.key,n.ruleName=i._r,n.id=t.id,n.value=i.value,s.elements[i.key]=n.element=t,s.isValid=s.$el[0].isValid=r?s.isFormValid():r,r?n.type="ok":(s.submiting&&(s.errors[i.key]=n.msg),s.hasError=!0),i.old=n,W(i[l])&&i[l].call(s,t,n),W(a.validation)&&a.validation.call(s,t,n),e(t).attr(V,!r||null).trigger(l+y,[n,s]),s.$el.triggerHandler("validation",[n,s]),s.checkOnly||(s._setClass(t,n.skip||"tip"===n.type?null:r),s._makeMsg.apply(s,arguments))},_makeMsg:function(t,i,n){i.msgMaker&&(n=e.extend({},n),"focusin"===i._e&&(n.type="tip"),this[n.showOk||n.msg||"tip"===n.type?"showMsg":"hideMsg"](t,n,i))},_validatedRule:function(i,n,s,a){n=n||c.getField(i),a=a||{};var r,l,o,d,c=this,f=n._r,g=n.timely,m=9===g||8===g,p=!1;if(null===s)return c._validatedField(i,n,{isValid:!0,skip:!0}),void(n._i=0);if(s===t?o=!0:s===!0||""===s?p=!0:J(s)?r=s:Q(s)&&(s.error?r=s.error:(r=s.ok,p=!0)),l=n._rules[n._i],l.not&&(r=t,p="required"===f||!p),l.or)if(p)for(;n._i<n._rules.length&&n._rules[n._i].or;)n._i++;else o=!0;else l.and&&(n.isValid||(o=!0));o?p=!0:(p&&n.showOk!==!1&&(d=z(i,$),r=null===d?J(n.ok)?n.ok:r:d,!J(r)&&J(n.showOk)&&(r=n.showOk),J(r)&&(a.showOk=p)),p&&!m||(r=(u(i,n,r||l.msg||c.messages[f])||c.messages.fallback).replace(/\{0\|?([^\}]*)\}/,function(e,t){return c._getDisplay(i,n.display)||t||c.messages[0]})),p||(n.isValid=p),a.msg=r,e(i).trigger((p?"valid":"invalid")+_,[f,r])),!m||o&&!l.and||(p||n._m||(n._m=r),n._v=n._v||[],n._v.push({type:p?o?"tip":"ok":"error",msg:r||l.msg})),c._debug("log"," "+n._i+": "+f+" => "+(p||r)),(p||m)&&n._i<n._rules.length-1?(n._i++,c._checkRule(i,n)):(n._i=0,m?(a.isValid=n.isValid,a.result=n._v,a.msg=n._m||"",n.value||"focusin"!==n._e||(a.type="tip")):a.isValid=p,c._validatedField(i,n,a),delete n._m,delete n._v)},_checkRule:function(i,n){var s,a,r,l=this,u=n.key,d=n._rules[n._i],c=d.method,f=d.params;l.submiting&&l.deferred[u]||(r=n.old,n._r=c,r&&!n.must&&!d.must&&d.result!==t&&r.ruleName===c&&r.id===i.id&&n.value&&r.value===n.value?s=d.result:(a=o(i,c)||l.rules[c]||B,s=a.call(n,i,f,n),a.msg&&(d.msg=a.msg)),Q(s)&&W(s.then)?(l.deferred[u]=s,n.isValid=t,!l.checkOnly&&l.showMsg(i,{type:"loading",msg:l.messages.loading},n),s.then(function(s,a,r){var o,u=U(r.responseText),c=n.dataFilter;/jsonp?/.test(this.dataType)?u=s:"{"===u.charAt(0)&&(u=e.parseJSON(u)),o=c.call(this,u,n),o===t&&(o=c.call(this,u.data,n)),d.data=this.data,d.result=n.old?o:t,l._validatedRule(i,n,o)},function(e,t){l._validatedRule(i,n,l.messages[t]||t)}).always(function(){delete l.deferred[u]})):l._validatedRule(i,n,s))},_validate:function(e,t){var i=this;if(!e.disabled&&null===z(e,T)&&(t=t||i.getField(e),t&&(t._rules||i._parse(e),t._rules)))return i._debug("info",t.key),t.isValid=!0,t.element=e,t.value=t.getValue(),t.required||t.must||t.value||c(e)?(i._checkRule(e,t),t.isValid):(i._validatedField(e,t,{isValid:!0}),!0)},_debug:function(e,t){window.console&&this.options.debug&&console[e](t)},test:function(e,i){var n,s,a,r,l=this,o=q.exec(i);return o&&(a=o[1],a in l.rules&&(r=o[2]||o[3],r=r?r.split(", "):t,s=l.getField(e,!0),s._r=a,s.value=s.getValue(),n=l.rules[a].call(s,e,r))),n===!0||n===t||null===n},_getDisplay:function(e,t){return J(t)?t:W(t)?t.call(this,e):""},_getMsgOpt:function(t,i){var n=i?i:this.options;return e.extend({type:"error",pos:d(n.msgClass),target:n.target,wrapper:n.msgWrapper,style:n.msgStyle,cls:n.msgClass,arrow:n.msgArrow,icon:n.msgIcon},J(t)?{msg:t}:t)},_getMsgDOM:function(i,n){var s,a,r,l,o=e(i);if(o.is(N)?(r=n.target||z(i,E),r&&(r=W(r)?r.call(this,i):this.$el.find(r),r.length&&(r.is(N)?i=r.get(0):r.hasClass(w)?s=r:l=r)),s||(a=c(i)&&i.name||!i.id?i.name:i.id,s=this.$el.find(n.wrapper+"."+w+'[for="'+a+'"]'))):s=o,!n.hide&&!s.length)if(o=this.$el.find(r||i),s=e("<"+n.wrapper+">").attr({class:w+(n.cls?" "+n.cls:""),style:n.style||t,for:a}),c(i)){var u=o.parent();s.appendTo(u.is("label")?u.parent():u)}else l?s.appendTo(l):s[n.pos&&"right"!==n.pos?"insertBefore":"insertAfter"](o);return s},showMsg:function(t,i,n){if(t){var s,a,r,l,o=this,u=o.options;if(Q(t)&&!t.jquery&&!i)return void e.each(t,function(e,t){var i=o.elements[e]||o.$el.find(m(e))[0];o.showMsg(i,t)});e(t).is(N)&&(n=n||o.getField(t)),(a=(n||u).msgMaker)&&(i=o._getMsgOpt(i,n),t=e(t).get(0),i.msg||"error"===i.type||(r=z(t,"data-"+i.type),null!==r&&(i.msg=r)),J(i.msg)&&(l=o._getMsgDOM(t,i),!I.test(l[0].className)&&l.addClass(i.cls),6===X&&"bottom"===i.pos&&(l[0].style.marginTop=e(t).outerHeight()+"px"),l.html(a.call(o,i))[0].style.display="",W(s=n&&n.msgShow||u.msgShow)&&s.call(o,l,i.type)))}},hideMsg:function(t,i,n){var s,a,r=this,l=r.options;t=e(t).get(0),e(t).is(N)&&(n=n||r.getField(t),n&&(n.isValid||r.reseting)&&z(t,V,null)),i=r._getMsgOpt(i,n),i.hide=!0,a=r._getMsgDOM(t,i),a.length&&(W(s=n&&n.msgHide||l.msgHide)?s.call(r,a,i.type):(a[0].style.display="none",a[0].innerHTML=null))},getField:function(e,i){var n,s,a=this;if(J(e))n=e,e=t;else{if(z(e,M))return a._parse(e);n=e.id&&"#"+e.id in a.fields||!e.name?"#"+e.id:e.name}return((s=a.fields[n])||i&&(s=new a.Field(n)))&&(s.element=e),s},setField:function(e,t){var i={};e&&(J(e)?i[e]=t:i=e,this._initFields(i))},isFormValid:function(){var e,t,i=this.fields;for(e in i)if(t=i[e],t._rules&&(t.required||t.must||t.value)&&!t.isValid)return!1;return!0},holdSubmit:function(e){this.submiting=e===t||e},cleanUp:function(){this._reset(1)},destroy:function(){this._reset(1),this.$el.off(v).removeData(h),z(this.$el[0],T,this._NOVALIDATE)}},e(window).on("beforeunload",function(){this.focus()}),e(document).on("click",":submit",function(){var e,t=this;t.form&&(e=t.getAttributeNode("formnovalidate"),(e&&null!==e.nodeValue||null!==z(t,T))&&(p=!0))}).on("focusin submit validate","form,."+k,function(t){if(null===z(this,T)){var i,n=e(this);!n.data(h)&&(i=l(this))&&(e.isEmptyObject(i.fields)?(z(this,T,T),n.off(v).removeData(h)):"focusin"===t.type?i._focusin(t):i._submit(t))}}),new a({fallback:"This field is not valid.",loading:"Validating..."}),new s({required:function(t,i){var n=this,s=U(n.value),a=!0;if(i)if(1===i.length){if(g(i[0])){if(n.rules[i[0]]){if(!s&&!n.test(t,i[0]))return z(t,x,null),null;z(t,x,!0)}}else if(!s&&!e(i[0],n.$el).length)return null}else if("not"===i[0])e.each(i.slice(1),function(){return a=s!==U(this)});else if("from"===i[0]){var r,l=n.$el.find(i[1]),o="_validated_";return a=l.filter(function(){var e=n.getField(this);return e&&!!U(e.getValue())}).length>=(i[2]||1),a?s||(r=null):r=u(l[0],n)||!1,e(t).data(o)||l.data(o,1).each(function(){t!==this&&n._validate(this)}).removeData(o),r}return a&&!!s},integer:function(e,t){var i,n="0|",s="[1-9]\\d*",a=t?t[0]:"*";switch(a){case"+":i=s;break;case"-":i="-"+s;break;case"+0":i=n+s;break;case"-0":i=n+"-"+s;break;default:i=n+"-?"+s}return i="^(?:"+i+")$",new RegExp(i).test(this.value)||this.messages.integer[a]},match:function(t,i){if(i){var n,s,a,r,l,o,u,d,c=this,g="eq";if(1===i.length?a=i[0]:(g=i[0],a=i[1]),o=m(a),u=c.$el.find(o)[0]){if(d=c.getField(u),n=c.value,s=d.getValue(),c._match||(c.$el.on("valid"+y+v,o,function(){e(t).trigger("validate")}),c._match=d._match=1),!c.required&&""===n&&""===s)return null;if(l=i[2],l&&(/^date(time)?$/i.test(l)?(n=f(n),s=f(s)):"time"===l&&(n=+n.replace(/:/g,""),s=+s.replace(/:/g,""))),"eq"!==g&&!isNaN(+n)&&isNaN(+s))return!0;switch(r=c.messages.match[g].replace("{1}",c._getDisplay(t,d.display||a)),g){case"lt":return+n<+s||r;case"lte":return+n<=+s||r;case"gte":return+n>=+s||r;case"gt":return+n>+s||r;case"neq":return n!==s||r;default:return n===s||r}}}},range:function(e,t){return this.getRangeMsg(this.value,t)},checked:function(e,t){if(c(e)){var i,n,s=this;return e.name?n=s.$el.find('input[name="'+e.name+'"]').filter(function(){var e=this;return!i&&c(e)&&(i=e),!e.disabled&&e.checked}).length:(i=e,n=i.checked),t?s.getRangeMsg(n,t):!!n||u(i,s,"")||s.messages.required}},length:function(e,t){var i=this.value,n=("true"===t[1]?i.replace(D,"xx"):i).length;return this.getRangeMsg(n,t,t[1]?"_2":"")},remote:function(t,i){if(i){var n,s=this,a=H.exec(i[0]),r=s._rules[s._i],l={},o="",u=a[3],d=a[2]||"POST",c=(a[1]||"").toLowerCase();return r.must=!0,l[t.name]=s.value,i[1]&&e.map(i.slice(1),function(e){var t,i;~e.indexOf("=")?o+="&"+e:(t=e.split(":"),e=U(t[0]),i=U(t[1])||e,l[e]=s.$el.find(m(i)).val())}),l=e.param(l)+o,!s.must&&r.data&&r.data===l?r.result:("cors"!==c&&/^https?:/.test(u)&&!~u.indexOf(location.host)&&(n="jsonp"),e.ajax({url:u,type:d,data:l,dataType:n}))}},filter:function(e,t){var i=this.value,n=i.replace(t?new RegExp("["+t[0]+"]","gm"):L,"");n!==i&&this.setValue(n)}}),i.config=function(t,i){function n(e,t){"rules"===e?new s(t):"messages"===e?new a(t):e in Y?Y[e]=t:K[e]=t}Q(t)?e.each(t,n):J(t)&&n(t,i)},i.setTheme=function(t,i){Q(t)?e.extend(!0,Z,t):J(t)&&Q(i)&&(Z[t]=e.extend(Z[t],i))},i.load=function(t){if(t){var n,s,a,r=document,l={},o=r.scripts[0];t.replace(/([^?=&]+)=([^&#]*)/g,function(e,t,i){l[t]=i}),n=l.dir||i.dir,i.css||""===l.css||(s=r.createElement("link"),s.rel="stylesheet",s.href=i.css=n+"jquery.validator.css",o.parentNode.insertBefore(s,o)),i.local||""===l.local||(i.local=(l.local||r.documentElement.lang||"en").replace("_","-"),i.pending=1,s=r.createElement("script"),s.src=n+"local/"+i.local+".js",a="onload"in s?"onload":"onreadystatechange",s[a]=function(){s.readyState&&!/loaded|complete/.test(s.readyState)||(s=s[a]=null,delete i.pending,e(window).triggerHandler("validatorready"))},o.parentNode.insertBefore(s,o))}},function(){for(var e,t,n=document.scripts,s=n.length,a=/(.*validator(?:\.min)?.js)(\?.*(?:local|css|dir)(?:=[\w\-]*)?)?/;s--&&!t;)e=n[s],t=(e.hasAttribute?e.src:e.getAttribute("src",4)||"").match(a);t&&(i.dir=t[1].split("/").slice(0,-1).join("/")+"/",i.load(t[2]))}(),e[h]=i}); + +(function(factory){typeof module==="object"&&module.exports?module.exports=factory(require("jquery")):typeof define==="function"&&define.amd?require(["jquery"],factory):factory(jQuery)}(function($){$.validator.config({rules:{digits:[/^\d+$/,"请填写数字"],letters:[/^[a-z]+$/i,"请填写字母"],date:[/^\d{4}-\d{2}-\d{2}$/,"请填写有效的日期,格式:yyyy-mm-dd"],time:[/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/,"请填写有效的时间,00:00到23:59之间"],email:[/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i,"请填写有效的邮箱"],url:[/^(https?|s?ftp):\/\/\S+$/i,"请填写有效的网址"],qq:[/^[1-9]\d{4,}$/,"请填写有效的QQ号"],IDcard:[/^\d{6}(19|2\d)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/,"请填写正确的身份证号码"],tel:[/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/,"请填写有效的电话号码"],mobile:[/^1[3-9]\d{9}$/,"请填写有效的手机号"],zipcode:[/^\d{6}$/,"请检查邮政编码格式"],chinese:[/^[\u0391-\uFFE5]+$/,"请填写中文字符"],username:[/^\w{3,12}$/,"请填写3-12位数字、字母、下划线"],password:[/^[\S]{6,16}$/,"请填写6-16位字符,不能包含空格"],accept:function(element,params){if(!params){return true}var ext=params[0],value=$(element).val();return(ext==="*")||(new RegExp(".(?:"+ext+")$","i")).test(value)||this.renderMsg("只接受{1}后缀的文件",ext.replace(/\|/g,","))}},messages:{0:"此处",fallback:"{0}格式不正确",loading:"正在验证...",error:"网络异常",timeout:"请求超时",required:"{0}不能为空",remote:"{0}已被使用",integer:{"*":"请填写整数","+":"请填写正整数","+0":"请填写正整数或0","-":"请填写负整数","-0":"请填写负整数或0"},match:{eq:"{0}与{1}不一致",neq:"{0}与{1}不能相同",lt:"{0}必须小于{1}",gt:"{0}必须大于{1}",lte:"{0}不能大于{1}",gte:"{0}不能小于{1}"},range:{rg:"请填写{1}到{2}的数",gte:"请填写不小于{1}的数",lte:"请填写最大{1}的数",gtlt:"请填写{1}到{2}之间的数",gt:"请填写大于{1}的数",lt:"请填写小于{1}的数"},checked:{eq:"请选择{1}项",rg:"请选择{1}到{2}项",gte:"请至少选择{1}项",lte:"请最多选择{1}项"},length:{eq:"请填写{1}个字符",rg:"请填写{1}到{2}个字符",gte:"请至少填写{1}个字符",lte:"请最多填写{1}个字符",eq_2:"",rg_2:"",gte_2:"",lte_2:""}}});var TPL_ARROW='<span class="n-arrow"><b>◆</b><i>◆</i></span>';$.validator.setTheme({"simple_right":{formClass:"n-simple",msgClass:"n-right"},"simple_bottom":{formClass:"n-simple",msgClass:"n-bottom"},"yellow_top":{formClass:"n-yellow",msgClass:"n-top",msgArrow:TPL_ARROW},"yellow_right":{formClass:"n-yellow",msgClass:"n-right",msgArrow:TPL_ARROW},"yellow_right_effect":{formClass:"n-yellow",msgClass:"n-right",msgArrow:TPL_ARROW,msgShow:function($msgbox,type){var $el=$msgbox.children();if($el.is(":animated")){return}if(type==="error"){$el.css({left:"20px",opacity:0}).delay(100).show().stop().animate({left:"-4px",opacity:1},150).animate({left:"3px"},80).animate({left:0},80)}else{$el.css({left:0,opacity:1}).fadeIn(200)}},msgHide:function($msgbox,type){var $el=$msgbox.children();$el.stop().delay(100).show().animate({left:"20px",opacity:0},300,function(){$msgbox.hide()})}}})})); +/**tip插件**/ +(function($){var tips=[],reBgImage=/^url\(["']?([^"'\)]*)["']?\);?$/i,rePNG=/\.png$/i,ie6=!!window.createPopup&&document.documentElement.currentStyle.minWidth=="undefined";function handleWindowResize(){$.each(tips,function(){this.refresh(true)})}$(window).resize(handleWindowResize);$.Poshytip=function(elm,options){this.$elm=$(elm);this.opts=$.extend({},$.fn.poshytip.defaults,options);this.$tip=$(['<div class="',this.opts.className,'">','<div class="tip-inner tip-bg-image"></div>','<div class="tip-arrow tip-arrow-top tip-arrow-right tip-arrow-bottom tip-arrow-left"></div>',"</div>"].join("")).appendTo(document.body);this.$arrow=this.$tip.find("div.tip-arrow");this.$inner=this.$tip.find("div.tip-inner");this.disabled=false;this.content=null;this.init()};$.Poshytip.prototype={init:function(){tips.push(this);var title=this.$elm.attr("title");this.$elm.data("title.poshytip",title!==undefined?title:null).data("poshytip",this);if(this.opts.showOn!="none"){this.$elm.bind({"mouseenter.poshytip":$.proxy(this.mouseenter,this),"mouseleave.poshytip":$.proxy(this.mouseleave,this)});switch(this.opts.showOn){case"hover":if(this.opts.alignTo=="cursor"){this.$elm.bind("mousemove.poshytip",$.proxy(this.mousemove,this))}if(this.opts.allowTipHover){this.$tip.hover($.proxy(this.clearTimeouts,this),$.proxy(this.mouseleave,this))}break;case"focus":this.$elm.bind({"focus.poshytip":$.proxy(this.showDelayed,this),"blur.poshytip":$.proxy(this.hideDelayed,this)});break}}},mouseenter:function(e){if(this.disabled){return true}this.$elm.attr("title","");if(this.opts.showOn=="focus"){return true}this.showDelayed()},mouseleave:function(e){if(this.disabled||this.asyncAnimating&&(this.$tip[0]===e.relatedTarget||jQuery.contains(this.$tip[0],e.relatedTarget))){return true}if(!this.$tip.data("active")){var title=this.$elm.data("title.poshytip");if(title!==null){this.$elm.attr("title",title)}}if(this.opts.showOn=="focus"){return true}this.hideDelayed()},mousemove:function(e){if(this.disabled){return true}this.eventX=e.pageX;this.eventY=e.pageY;if(this.opts.followCursor&&this.$tip.data("active")){this.calcPos();this.$tip.css({left:this.pos.l,top:this.pos.t});if(this.pos.arrow){this.$arrow[0].className="tip-arrow tip-arrow-"+this.pos.arrow}}},show:function(){if(this.disabled||this.$tip.data("active")){return}this.reset();this.update();if(!this.content){return}this.display();if(this.opts.timeOnScreen){this.hideDelayed(this.opts.timeOnScreen)}},showDelayed:function(timeout){this.clearTimeouts();this.showTimeout=setTimeout($.proxy(this.show,this),typeof timeout=="number"?timeout:this.opts.showTimeout)},hide:function(){if(this.disabled||!this.$tip.data("active")){return}this.display(true)},hideDelayed:function(timeout){this.clearTimeouts();this.hideTimeout=setTimeout($.proxy(this.hide,this),typeof timeout=="number"?timeout:this.opts.hideTimeout)},reset:function(){this.$tip.queue([]).detach().css("visibility","hidden").data("active",false);this.$inner.find("*").poshytip("hide");if(this.opts.fade){this.$tip.css("opacity",this.opacity)}this.$arrow[0].className="tip-arrow tip-arrow-top tip-arrow-right tip-arrow-bottom tip-arrow-left";this.asyncAnimating=false},update:function(content,dontOverwriteOption){if(this.disabled){return}var async=content!==undefined;if(async){if(!dontOverwriteOption){this.opts.content=content}if(!this.$tip.data("active")){return}}else{content=this.opts.content}var self=this,newContent=typeof content=="function"?content.call(this.$elm[0],function(newContent){self.update(newContent)}):content=="[title]"?this.$elm.data("title.poshytip"):content;if(this.content!==newContent){this.$inner.empty().append(newContent);this.content=newContent}this.refresh(async)},refresh:function(async){if(this.disabled){return}if(async){if(!this.$tip.data("active")){return}var currPos={left:this.$tip.css("left"),top:this.$tip.css("top")}}this.$tip.css({left:0,top:0}).appendTo(document.body);if(this.opacity===undefined){this.opacity=this.$tip.css("opacity")}var bgImage=this.$tip.css("background-image").match(reBgImage),arrow=this.$arrow.css("background-image").match(reBgImage);if(bgImage){var bgImagePNG=rePNG.test(bgImage[1]);if(ie6&&bgImagePNG){this.$tip.css("background-image","none");this.$inner.css({margin:0,border:0,padding:0});bgImage=bgImagePNG=false}else{this.$tip.prepend('<table class="tip-table" border="0" cellpadding="0" cellspacing="0"><tr><td class="tip-top tip-bg-image" colspan="2"><span></span></td><td class="tip-right tip-bg-image" rowspan="2"><span></span></td></tr><tr><td class="tip-left tip-bg-image" rowspan="2"><span></span></td><td></td></tr><tr><td class="tip-bottom tip-bg-image" colspan="2"><span></span></td></tr></table>').css({border:0,padding:0,"background-image":"none","background-color":"transparent"}).find(".tip-bg-image").css("background-image",'url("'+bgImage[1]+'")').end().find("td").eq(3).append(this.$inner)}if(bgImagePNG&&!$.support.opacity){this.opts.fade=false}}if(arrow&&!$.support.opacity){if(ie6&&rePNG.test(arrow[1])){arrow=false; +this.$arrow.css("background-image","none")}this.opts.fade=false}var $table=this.$tip.find("> table.tip-table");if(ie6){this.$tip[0].style.width="";$table.width("auto").find("td").eq(3).width("auto");var tipW=this.$tip.width(),minW=parseInt(this.$tip.css("min-width")),maxW=parseInt(this.$tip.css("max-width"));if(!isNaN(minW)&&tipW<minW){tipW=minW}else{if(!isNaN(maxW)&&tipW>maxW){tipW=maxW}}this.$tip.add($table).width(tipW).eq(0).find("td").eq(3).width("100%")}else{if($table[0]){$table.width("auto").find("td").eq(3).width("auto").end().end().width(document.defaultView&&document.defaultView.getComputedStyle&&parseFloat(document.defaultView.getComputedStyle(this.$tip[0],null).width)||this.$tip.width()).find("td").eq(3).width("100%")}}this.tipOuterW=this.$tip.outerWidth();this.tipOuterH=this.$tip.outerHeight();this.calcPos();if(arrow&&this.pos.arrow){this.$arrow[0].className="tip-arrow tip-arrow-"+this.pos.arrow;this.$arrow.css("visibility","inherit")}if(async&&this.opts.refreshAniDuration){this.asyncAnimating=true;var self=this;this.$tip.css(currPos).animate({left:this.pos.l,top:this.pos.t},this.opts.refreshAniDuration,function(){self.asyncAnimating=false})}else{this.$tip.css({left:this.pos.l,top:this.pos.t})}},display:function(hide){var active=this.$tip.data("active");if(active&&!hide||!active&&hide){return}this.$tip.stop();if((this.opts.slide&&this.pos.arrow||this.opts.fade)&&(hide&&this.opts.hideAniDuration||!hide&&this.opts.showAniDuration)){var from={},to={};if(this.opts.slide&&this.pos.arrow){var prop,arr;if(this.pos.arrow=="bottom"||this.pos.arrow=="top"){prop="top";arr="bottom"}else{prop="left";arr="right"}var val=parseInt(this.$tip.css(prop));from[prop]=val+(hide?0:(this.pos.arrow==arr?-this.opts.slideOffset:this.opts.slideOffset));to[prop]=val+(hide?(this.pos.arrow==arr?this.opts.slideOffset:-this.opts.slideOffset):0)+"px"}if(this.opts.fade){from.opacity=hide?this.$tip.css("opacity"):0;to.opacity=hide?0:this.opacity}this.$tip.css(from).animate(to,this.opts[hide?"hideAniDuration":"showAniDuration"])}hide?this.$tip.queue($.proxy(this.reset,this)):this.$tip.css("visibility","inherit");if(active){var title=this.$elm.data("title.poshytip");if(title!==null){this.$elm.attr("title",title)}}this.$tip.data("active",!active)},disable:function(){this.reset();this.disabled=true},enable:function(){this.disabled=false},destroy:function(){this.reset();this.$tip.remove();delete this.$tip;this.content=null;this.$elm.unbind(".poshytip").removeData("title.poshytip").removeData("poshytip");tips.splice($.inArray(this,tips),1)},clearTimeouts:function(){if(this.showTimeout){clearTimeout(this.showTimeout);this.showTimeout=0}if(this.hideTimeout){clearTimeout(this.hideTimeout);this.hideTimeout=0}},calcPos:function(){var pos={l:0,t:0,arrow:""},$win=$(window),win={l:$win.scrollLeft(),t:$win.scrollTop(),w:$win.width(),h:$win.height()},xL,xC,xR,yT,yC,yB;if(this.opts.alignTo=="cursor"){xL=xC=xR=this.eventX;yT=yC=yB=this.eventY}else{var elmOffset=this.$elm.offset(),elm={l:elmOffset.left,t:elmOffset.top,w:this.$elm.outerWidth(),h:this.$elm.outerHeight()};xL=elm.l+(this.opts.alignX!="inner-right"?0:elm.w);xC=xL+Math.floor(elm.w/2);xR=xL+(this.opts.alignX!="inner-left"?elm.w:0);yT=elm.t+(this.opts.alignY!="inner-bottom"?0:elm.h);yC=yT+Math.floor(elm.h/2);yB=yT+(this.opts.alignY!="inner-top"?elm.h:0)}switch(this.opts.alignX){case"right":case"inner-left":pos.l=xR+this.opts.offsetX;if(this.opts.keepInViewport&&pos.l+this.tipOuterW>win.l+win.w){pos.l=win.l+win.w-this.tipOuterW}if(this.opts.alignX=="right"||this.opts.alignY=="center"){pos.arrow="left"}break;case"center":pos.l=xC-Math.floor(this.tipOuterW/2);if(this.opts.keepInViewport){if(pos.l+this.tipOuterW>win.l+win.w){pos.l=win.l+win.w-this.tipOuterW}else{if(pos.l<win.l){pos.l=win.l}}}break;default:pos.l=xL-this.tipOuterW-this.opts.offsetX;if(this.opts.keepInViewport&&pos.l<win.l){pos.l=win.l}if(this.opts.alignX=="left"||this.opts.alignY=="center"){pos.arrow="right"}}switch(this.opts.alignY){case"bottom":case"inner-top":pos.t=yB+this.opts.offsetY;if(!pos.arrow||this.opts.alignTo=="cursor"){pos.arrow="top"}if(this.opts.keepInViewport&&pos.t+this.tipOuterH>win.t+win.h){pos.t=yT-this.tipOuterH-this.opts.offsetY;if(pos.arrow=="top"){pos.arrow="bottom"}}break;case"center":pos.t=yC-Math.floor(this.tipOuterH/2);if(this.opts.keepInViewport){if(pos.t+this.tipOuterH>win.t+win.h){pos.t=win.t+win.h-this.tipOuterH}else{if(pos.t<win.t){pos.t=win.t}}}break;default:pos.t=yT-this.tipOuterH-this.opts.offsetY;if(!pos.arrow||this.opts.alignTo=="cursor"){pos.arrow="bottom"}if(this.opts.keepInViewport&&pos.t<win.t){pos.t=yB+this.opts.offsetY;if(pos.arrow=="bottom"){pos.arrow="top"}}}this.pos=pos}};$.fn.poshytip=function(options){if(typeof options=="string"){var args=arguments,method=options;Array.prototype.shift.call(args);if(method=="destroy"){this.die?this.die("mouseenter.poshytip").die("focus.poshytip"):$(document).undelegate(this.selector,"mouseenter.poshytip").undelegate(this.selector,"focus.poshytip")}return this.each(function(){var poshytip=$(this).data("poshytip"); +if(poshytip&&poshytip[method]){poshytip[method].apply(poshytip,args)}})}var opts=$.extend({},$.fn.poshytip.defaults,options);if(!$("#poshytip-css-"+opts.className)[0]){$(['<style id="poshytip-css-',opts.className,'" type="text/css">',"div.",opts.className,"{visibility:hidden;position:absolute;top:0;left:0;}","div.",opts.className," table.tip-table, div.",opts.className," table.tip-table td{margin:0;font-family:inherit;font-size:inherit;font-weight:inherit;font-style:inherit;font-variant:inherit;vertical-align:middle;}","div.",opts.className," td.tip-bg-image span{display:block;font:1px/1px sans-serif;height:",opts.bgImageFrameSize,"px;width:",opts.bgImageFrameSize,"px;overflow:hidden;}","div.",opts.className," td.tip-right{background-position:100% 0;}","div.",opts.className," td.tip-bottom{background-position:100% 100%;}","div.",opts.className," td.tip-left{background-position:0 100%;}","div.",opts.className," div.tip-inner{background-position:-",opts.bgImageFrameSize,"px -",opts.bgImageFrameSize,"px;}","div.",opts.className," div.tip-arrow{visibility:hidden;position:absolute;overflow:hidden;font:1px/1px sans-serif;}","</style>"].join("")).appendTo("head")}if(opts.liveEvents&&opts.showOn!="none"){var handler,deadOpts=$.extend({},opts,{liveEvents:false});switch(opts.showOn){case"hover":handler=function(){var $this=$(this);if(!$this.data("poshytip")){$this.poshytip(deadOpts).poshytip("mouseenter")}};this.live?this.live("mouseenter.poshytip",handler):$(document).delegate(this.selector,"mouseenter.poshytip",handler);break;case"focus":handler=function(){var $this=$(this);if(!$this.data("poshytip")){$this.poshytip(deadOpts).poshytip("showDelayed")}};this.live?this.live("focus.poshytip",handler):$(document).delegate(this.selector,"focus.poshytip",handler);break}return this}return this.each(function(){new $.Poshytip(this,opts)})};$.fn.poshytip.defaults={content:"[title]",className:"tip-yellow",bgImageFrameSize:10,showTimeout:500,hideTimeout:100,timeOnScreen:0,showOn:"hover",liveEvents:false,alignTo:"cursor",alignX:"right",alignY:"top",offsetX:-22,offsetY:18,keepInViewport:true,allowTipHover:true,followCursor:false,fade:true,slide:true,slideOffset:8,showAniDuration:300,hideAniDuration:300,refreshAniDuration:200}})(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/images/loading.gif b/hyhproject/admin/view/js/images/loading.gif new file mode 100755 index 0000000..b1565d7 Binary files /dev/null and b/hyhproject/admin/view/js/images/loading.gif differ diff --git a/hyhproject/admin/view/js/images/top.jpg b/hyhproject/admin/view/js/images/top.jpg new file mode 100755 index 0000000..a3fa4d4 Binary files /dev/null and b/hyhproject/admin/view/js/images/top.jpg differ diff --git a/hyhproject/admin/view/js/images/topicon.gif b/hyhproject/admin/view/js/images/topicon.gif new file mode 100755 index 0000000..0c747d1 Binary files /dev/null and b/hyhproject/admin/view/js/images/topicon.gif differ diff --git a/hyhproject/admin/view/js/index.js b/hyhproject/admin/view/js/index.js new file mode 100755 index 0000000..350bc33 --- /dev/null +++ b/hyhproject/admin/view/js/index.js @@ -0,0 +1,17 @@ +/*! AdminLTE app.js +* ================ +* Main JS application file for AdminLTE v2. This file +* should be included in all pages. It controls some layout +* options and implements exclusive AdminLTE plugins. +* +* @Author Almsaeed Studio +* @Support <https://www.almsaeedstudio.com> +* @Email <abdullah@almsaeedstudio.com> +* @version 2.4.0 +* @repository git://github.com/almasaeed2010/AdminLTE.git +* @license MIT <http://opensource.org/licenses/MIT> +*/ +if(typeof jQuery==="undefined"){throw new Error("AdminLTE requires jQuery")}+function(g){var f="lte.boxrefresh";var c={source:"",params:{},trigger:".refresh-btn",content:".box-body",loadInContent:true,responseType:"",overlayTemplate:'<div class="overlay"><div class="fa fa-refresh fa-spin"></div></div>',onLoadStart:function(){},onLoadDone:function(h){return h}};var b={data:'[data-widget="box-refresh"]'};var d=function(i,h){this.element=i;this.options=h;this.$overlay=g(h.overlay);if(h.source===""){throw new Error("Source url was not defined. Please specify a url in your BoxRefresh source option.")}this._setUpListeners();this.load()};d.prototype.load=function(){this._addOverlay();this.options.onLoadStart.call(g(this));g.get(this.options.source,this.options.params,function(h){if(this.options.loadInContent){g(this.options.content).html(h)}this.options.onLoadDone.call(g(this),h);this._removeOverlay()}.bind(this),this.options.responseType!==""&&this.options.responseType)};d.prototype._setUpListeners=function(){g(this.element).on("click",b.trigger,function(h){if(h){h.preventDefault()}this.load()}.bind(this))};d.prototype._addOverlay=function(){g(this.element).append(this.$overlay)};d.prototype._removeOverlay=function(){g(this.element).remove(this.$overlay)};function e(h){return this.each(function(){var k=g(this);var j=k.data(f);if(!j){var i=g.extend({},c,k.data(),typeof h=="object"&&h);k.data(f,(j=new d(k,i)))}if(typeof j=="string"){if(typeof j[h]=="undefined"){throw new Error("No method named "+h)}j[h]()}})}var a=g.fn.boxRefresh;g.fn.boxRefresh=e;g.fn.boxRefresh.Constructor=d;g.fn.boxRefresh.noConflict=function(){g.fn.boxRefresh=a;return this};g(window).on("load",function(){g(b.data).each(function(){e.call(g(this))})})}(jQuery)+function(d){var b="lte.boxwidget";var f={animationSpeed:500,collapseTrigger:'[data-widget="collapse"]',removeTrigger:'[data-widget="remove"]',collapseIcon:"fa-minus",expandIcon:"fa-plus",removeIcon:"fa-times"};var a={data:".box",collapsed:".collapsed-box",body:".box-body",footer:".box-footer",tools:".box-tools"};var h={collapsed:"collapsed-box"};var i={collapsed:"collapsed.boxwidget",expanded:"expanded.boxwidget",removed:"removed.boxwidget"};var e=function(k,j){this.element=k;this.options=j;this._setUpListeners()};e.prototype.toggle=function(){var j=!d(this.element).is(a.collapsed);if(j){this.collapse()}else{this.expand()}};e.prototype.expand=function(){var l=d.Event(i.expanded);var k=this.options.collapseIcon;var j=this.options.expandIcon;d(this.element).removeClass(h.collapsed);d(this.element).find(a.tools).find("."+j).removeClass(j).addClass(k);d(this.element).find(a.body+", "+a.footer).slideDown(this.options.animationSpeed,function(){d(this.element).trigger(l)}.bind(this))};e.prototype.collapse=function(){var k=d.Event(i.collapsed);var l=this.options.collapseIcon;var j=this.options.expandIcon;d(this.element).find(a.tools).find("."+l).removeClass(l).addClass(j);d(this.element).find(a.body+", "+a.footer).slideUp(this.options.animationSpeed,function(){d(this.element).addClass(h.collapsed);d(this.element).trigger(k)}.bind(this))};e.prototype.remove=function(){var j=d.Event(i.removed);d(this.element).slideUp(this.options.animationSpeed,function(){d(this.element).trigger(j);d(this.element).remove()}.bind(this))};e.prototype._setUpListeners=function(){var j=this;d(this.element).on("click",this.options.collapseTrigger,function(k){if(k){k.preventDefault()}j.toggle()});d(this.element).on("click",this.options.removeTrigger,function(k){if(k){k.preventDefault()}j.remove()})};function g(j){return this.each(function(){var m=d(this);var l=m.data(b);if(!l){var k=d.extend({},f,m.data(),typeof j=="object"&&j);m.data(b,(l=new e(m,k)))}if(typeof j=="string"){if(typeof l[j]=="undefined"){throw new Error("No method named "+j)}l[j]()}})}var c=d.fn.boxWidget;d.fn.boxWidget=g;d.fn.boxWidget.Constructor=e;d.fn.boxWidget.noConflict=function(){d.fn.boxWidget=c;return this};d(window).on("load",function(){d(a.data).each(function(){g.call(d(this))})})}(jQuery)+function(d){var b="lte.controlsidebar";var e={slide:true};var a={sidebar:".control-sidebar",data:'[data-toggle="control-sidebar"]',open:".control-sidebar-open",bg:".control-sidebar-bg",wrapper:".wrapper",content:".content-wrapper",boxed:".layout-boxed"};var h={open:"control-sidebar-open",fixed:"fixed"};var i={collapsed:"collapsed.controlsidebar",expanded:"expanded.controlsidebar"};var g=function(k,j){this.element=k;this.options=j;this.hasBindedResize=false;this.init()};g.prototype.init=function(){if(!d(this.element).is(a.data)){d(this).on("click",this.toggle)}this.fix();d(window).resize(function(){this.fix()}.bind(this))};g.prototype.toggle=function(j){if(j){j.preventDefault()}this.fix();if(!d(a.sidebar).is(a.open)&&!d("body").is(a.open)){this.expand()}else{this.collapse()}};g.prototype.expand=function(){if(!this.options.slide){d("body").addClass(h.open)}else{d(a.sidebar).addClass(h.open)}d(this.element).trigger(d.Event(i.expanded))};g.prototype.collapse=function(){d("body, "+a.sidebar).removeClass(h.open); +d(this.element).trigger(d.Event(i.collapsed))};g.prototype.fix=function(){if(d("body").is(a.boxed)){this._fixForBoxed(d(a.bg))}};g.prototype._fixForBoxed=function(j){j.css({position:"absolute",height:d(a.wrapper).height()})};function f(j){return this.each(function(){var m=d(this);var l=m.data(b);if(!l){var k=d.extend({},e,m.data(),typeof j=="object"&&j);m.data(b,(l=new g(m,k)))}if(typeof j=="string"){l.toggle()}})}var c=d.fn.controlSidebar;d.fn.controlSidebar=f;d.fn.controlSidebar.Constructor=g;d.fn.controlSidebar.noConflict=function(){d.fn.controlSidebar=c;return this};d(document).on("click",a.data,function(j){if(j){j.preventDefault()}f.call(d(this),"toggle")})}(jQuery)+function(g){var f="lte.directchat";var c={data:'[data-widget="chat-pane-toggle"]',box:".direct-chat"};var e={open:"direct-chat-contacts-open"};var a=function(h){this.element=h};a.prototype.toggle=function(h){h.parents(c.box).first().toggleClass(e.open)};function d(h){return this.each(function(){var j=g(this);var i=j.data(f);if(!i){j.data(f,(i=new a(j)))}if(typeof h=="string"){i.toggle(j)}})}var b=g.fn.directChat;g.fn.directChat=d;g.fn.directChat.Constructor=a;g.fn.directChat.noConflict=function(){g.fn.directChat=b;return this};g(document).on("click",c.data,function(h){if(h){h.preventDefault()}d.call(g(this),"toggle")})}(jQuery)+function(h){var g="lte.layout";var c={slimscroll:true,resetHeight:true};var b={wrapper:".wrapper",contentWrapper:".content-wrapper",layoutBoxed:".layout-boxed",mainFooter:".main-footer",mainHeader:".main-header",sidebar:".sidebar",controlSidebar:".control-sidebar",fixed:".fixed",sidebarMenu:".sidebar-menu",logo:".main-header .logo"};var f={fixed:"fixed",holdTransition:"hold-transition"};var e=function(i){this.options=i;this.bindedResize=false;this.activate()};e.prototype.activate=function(){this.fix();this.fixSidebar();h("body").removeClass(f.holdTransition);if(this.options.resetHeight){h("body, html, "+b.wrapper).css({"height":"auto","min-height":"100%"})}if(!this.bindedResize){h(window).resize(function(){this.fix();this.fixSidebar();h(b.logo+", "+b.sidebar).one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",function(){this.fix();this.fixSidebar()}.bind(this))}.bind(this));this.bindedResize=true}h(b.sidebarMenu).on("expanded.tree",function(){this.fix();this.fixSidebar()}.bind(this));h(b.sidebarMenu).on("collapsed.tree",function(){this.fix();this.fixSidebar()}.bind(this))};e.prototype.fix=function(){h(b.layoutBoxed+" > "+b.wrapper).css("overflow","hidden");var l=h(b.mainFooter).outerHeight()||0;var n=h(b.mainHeader).outerHeight()+l;var m=h(window).height();var i=h(b.sidebar).height()||0;if(h("body").hasClass(f.fixed)){h(b.contentWrapper).css("min-height",m-l);h(".content-iframe").height(m-l)}else{var k;if(m>=i){h(b.contentWrapper).css("min-height",m-n);k=m-n;h(".content-iframe").height(m-n-40)}else{h(b.contentWrapper).css("min-height",i);k=i;h(".content-iframe").height(i-40)}var j=h(b.controlSidebar);if(typeof j!=="undefined"){if(j.height()>k){h(b.contentWrapper).css("min-height",j.height())}h(".content-iframe").height(j.height())}}};e.prototype.fixSidebar=function(){if(!h("body").hasClass(f.fixed)){if(typeof h.fn.slimScroll!=="undefined"){h(b.sidebar).slimScroll({destroy:true}).height("auto")}return}if(this.options.slimscroll){if(typeof h.fn.slimScroll!=="undefined"){h(b.sidebar).slimScroll({height:(h(window).height()-h(b.mainHeader).height())+"px",color:"rgba(0,0,0,0.2)",size:"3px"})}}};function d(i){return this.each(function(){var l=h(this);var k=l.data(g);if(!k){var j=h.extend({},c,l.data(),typeof i==="object"&&i);l.data(g,(k=new e(j)))}if(typeof i==="string"){if(typeof k[i]==="undefined"){throw new Error("No method named "+i)}k[i]()}})}var a=h.fn.layout;h.fn.layout=d;h.fn.layout.Constuctor=e;h.fn.layout.noConflict=function(){h.fn.layout=a;return this};h(window).on("load",function(){d.call(h("body"))})}(jQuery)+function(d){var b="lte.pushmenu";var e={collapseScreenSize:767,expandOnHover:false,expandTransitionDelay:200};var a={collapsed:".sidebar-collapse",open:".sidebar-open",mainSidebar:".main-sidebar",contentWrapper:".content-wrapper",searchInput:".sidebar-form .form-control",button:'[data-toggle="push-menu"]',mini:".sidebar-mini",expanded:".sidebar-expanded-on-hover",layoutFixed:".fixed"};var h={collapsed:"sidebar-collapse",open:"sidebar-open",mini:"sidebar-mini",expanded:"sidebar-expanded-on-hover",expandFeature:"sidebar-mini-expand-feature",layoutFixed:"fixed"};var i={expanded:"expanded.pushMenu",collapsed:"collapsed.pushMenu"};var g=function(j){this.options=j;this.init()};g.prototype.init=function(){if(this.options.expandOnHover||(d("body").is(a.mini+a.layoutFixed))){this.expandOnHover();d("body").addClass(h.expandFeature)}d(a.contentWrapper).click(function(){if(d(window).width()<=this.options.collapseScreenSize&&d("body").hasClass(h.open)){this.close()}}.bind(this));d(a.searchInput).click(function(j){j.stopPropagation()})};g.prototype.toggle=function(){var k=d(window).width(); +var j=!d("body").hasClass(h.collapsed);if(k<=this.options.collapseScreenSize){j=d("body").hasClass(h.open)}if(!j){this.open()}else{this.close()}};g.prototype.open=function(){var j=d(window).width();if(j>this.options.collapseScreenSize){d("body").removeClass(h.collapsed).trigger(d.Event(i.expanded))}else{d("body").addClass(h.open).trigger(d.Event(i.expanded))}};g.prototype.close=function(){var j=d(window).width();if(j>this.options.collapseScreenSize){d("body").addClass(h.collapsed).trigger(d.Event(i.collapsed))}else{d("body").removeClass(h.open+" "+h.collapsed).trigger(d.Event(i.collapsed))}};g.prototype.expandOnHover=function(){d(a.mainSidebar).hover(function(){if(d("body").is(a.mini+a.collapsed)&&d(window).width()>this.options.collapseScreenSize){this.expand()}}.bind(this),function(){if(d("body").is(a.expanded)){this.collapse()}}.bind(this))};g.prototype.expand=function(){setTimeout(function(){d("body").removeClass(h.collapsed).addClass(h.expanded)},this.options.expandTransitionDelay)};g.prototype.collapse=function(){setTimeout(function(){d("body").removeClass(h.expanded).addClass(h.collapsed)},this.options.expandTransitionDelay)};function f(j){return this.each(function(){var m=d(this);var l=m.data(b);if(!l){var k=d.extend({},e,m.data(),typeof j=="object"&&j);m.data(b,(l=new g(k)))}if(j==="toggle"){l.toggle()}})}var c=d.fn.pushMenu;d.fn.pushMenu=f;d.fn.pushMenu.Constructor=g;d.fn.pushMenu.noConflict=function(){d.fn.pushMenu=c;return this};d(document).on("click",a.button,function(j){j.preventDefault();f.call(d(this),"toggle")});d(window).on("load",function(){f.call(d(a.button))})}(jQuery)+function(h){var g="lte.todolist";var c={onCheck:function(i){return i},onUnCheck:function(i){return i}};var b={data:'[data-widget="todo-list"]'};var e={done:"done"};var f=function(j,i){this.element=j;this.options=i;this._setUpListeners()};f.prototype.toggle=function(i){i.parents(b.li).first().toggleClass(e.done);if(!i.prop("checked")){this.unCheck(i);return}this.check(i)};f.prototype.check=function(i){this.options.onCheck.call(i)};f.prototype.unCheck=function(i){this.options.onUnCheck.call(i)};f.prototype._setUpListeners=function(){var i=this;h(this.element).on("change ifChanged","input:checkbox",function(){i.toggle(h(this))})};function d(i){return this.each(function(){var l=h(this);var k=l.data(g);if(!k){var j=h.extend({},c,l.data(),typeof i=="object"&&i);l.data(g,(k=new f(l,j)))}if(typeof k=="string"){if(typeof k[i]=="undefined"){throw new Error("No method named "+i)}k[i]()}})}var a=h.fn.todoList;h.fn.todoList=d;h.fn.todoList.Constructor=f;h.fn.todoList.noConflict=function(){h.fn.todoList=a;return this};h(window).on("load",function(){h(b.data).each(function(){d.call(h(this))})})}(jQuery)+function(e){var b="lte.tree";var f={animationSpeed:500,accordion:true,followLink:false,trigger:".treeview a"};var a={tree:".tree",treeview:".treeview",treeviewMenu:".treeview-menu",open:".menu-open, .active",li:"li",data:'[data-widget="tree"]',active:".active"};var h={open:"menu-open active",tree:"tree"};var i={collapsed:"collapsed.tree",expanded:"expanded.tree"};var d=function(k,j){this.element=k;this.options=j;e(this.element).addClass(h.tree);e(a.treeview+a.active,this.element).addClass(h.open);this._setUpListeners()};d.prototype.toggle=function(n,m){var l=n.next(a.treeviewMenu);var j=n.parent();var k=j.hasClass(h.open);if(!j.is(a.treeview)){return}if(!this.options.followLink||n.attr("href")==="#"){m.preventDefault()}if(k){this.collapse(l,j)}else{this.expand(l,j)}};d.prototype.expand=function(k,l){var n=e.Event(i.expanded);if(this.options.accordion){var j=l.siblings(a.open);var m=j.children(a.treeviewMenu);this.collapse(m,j)}l.addClass(h.open);k.slideDown(this.options.animationSpeed,function(){e(this.element).trigger(n)}.bind(this))};d.prototype.collapse=function(k,j){var l=e.Event(i.collapsed);k.find(a.open).removeClass(h.open);j.removeClass(h.open);k.slideUp(this.options.animationSpeed,function(){k.find(a.open+" > "+a.treeview).slideUp();e(this.element).trigger(l)}.bind(this))};d.prototype._setUpListeners=function(){var j=this;e(this.element).on("click",this.options.trigger,function(k){j.toggle(e(this),k)})};function g(j){return this.each(function(){var m=e(this);var l=m.data(b);if(!l){var k=e.extend({},f,m.data(),typeof j=="object"&&j);m.data(b,new d(m,k))}})}var c=e.fn.tree;e.fn.tree=g;e.fn.tree.Constructor=d;e.fn.tree.noConflict=function(){e.fn.tree=c;return this};e(window).on("load",function(){e(a.data).each(function(){g.call(e(this))})})}(jQuery)+function(a){a.GZSTLayout={requestFullscreen:function(){var b=document.documentElement;if(b.requestFullscreen){b.requestFullscreen()}else{if(b.mozRequestFullScreen){b.mozRequestFullScreen()}else{if(b.webkitRequestFullScreen){b.webkitRequestFullScreen()}}}},exitFullscreen:function(){var b=document;if(b.exitFullscreen){b.exitFullscreen()}else{if(b.mozCancelFullScreen){b.mozCancelFullScreen()}else{if(b.webkitCancelFullScreen){b.webkitCancelFullScreen()}}}},showSidebarMenu:function(d){var c=false; +a(".j-sysmenu"+d).each(function(){if(a(this).hasClass("menu-open")){c=true}});var b=0;a(".j-menulevel0").each(function(){if(a(this).hasClass("j-sysmenu"+d)){a(this).show();if(!c&&b==0){a(this).addClass("menu-open active")}b++}else{a(this).hide()}})},positionWay:function(h){var f=null,g=[];for(var e=0;e<menus.length;e++){if(menus[e]["child"]&&menus[e]["child"].length){for(var d=0;d<menus[e]["child"].length;d++){if(menus[e]["child"][d]["child"]&&menus[e]["child"][d]["child"].length){for(var c=0;c<menus[e]["child"][d]["child"].length;c++){if(menus[e]["child"][d]["child"][c]["child"]&&menus[e]["child"][d]["child"][c]["child"].length){for(var b=0;b<menus[e]["child"][d]["child"][c]["child"].length;b++){if(menus[e]["child"][d]["child"][c]["child"][b]["menuId"]==h){g.push(menus[e]["child"][d]["child"][c]["child"][b]["menuName"]);f=menus[e]["child"][d]["child"][c]["child"][d];break}}}if(menus[e]["child"][d]["child"][c]["menuId"]==h){g.push(menus[e]["child"][d]["child"][c]["menuName"]);f=menus[e]["child"][d];break}}if(g.length>0&&f["menuId"]==menus[e]["child"][d]["menuId"]){g.push(menus[e]["child"][d]["menuName"]);f=menus[e];break}}}if(g.length>0&&f["menuId"]==menus[e]["menuId"]){g.push(menus[e]["menuName"]);f=menus[e];break}}}g=g.reverse();for(var e=0;e<g.length;e++){if(e==0){g[e]="<li><a href='#'><i class='fa fa-map-marker'></i>"+g[e]+"</a></li>"}else{g[e]="<li>"+g[e]+"</li>"}}return g},showPosition:function(){var h=a(this),g=h.parent();g.addClass("active").siblings().removeClass("active");a(".navbar-custom-menu>ul>li.open").removeClass("open");var f=a(this).attr("href");var e=a(this).attr("dataid");var c=a.trim(a(this).text());var b=true;if(f==undefined||a.trim(f).length==0){return false}var i=a.GZSTLayout.positionWay(e);a(".breadcrumb").html(i.join(""));a("#iframe").attr("src",f);return false},initEvent:function(){a(".menuItem").on("click",a.GZSTLayout.showPosition);a(".top-menu").click(function(){a(this).parent().addClass("wst-focus").siblings().removeClass("wst-focus");a.GZSTLayout.showSidebarMenu(a(this).attr("dataid"))});a(".j-clear-cache").on("click",clearCache);a(".j-edit-pass").on("click",editPassBox);a(".j-logout").on("click",logout);a(".fullscreen").on("click",function(){if(!a(this).attr("fullscreen")){a(this).attr("fullscreen","true");a.GZSTLayout.requestFullscreen()}else{a(this).removeAttr("fullscreen");a.GZSTLayout.exitFullscreen()}})}};a(function(){a.GZSTLayout.initEvent()})}(jQuery);function logout(){var a=WST.msg("正在退出系统...",{icon:16,time:60000,offset:"200px"});$.post(WST.U("admin/index/logout"),{},function(c,d){layer.close(a);var b=WST.toAdminJson(c);if(b.status=="1"){WST.msg(b.msg,{icon:1,offset:"200px"},function(){location.href=WST.U("admin/index/login")})}else{WST.msg(b.msg,{icon:2,offset:"200px"})}})}function clearCache(){var a=WST.msg("正在清除服务器缓存...",{icon:16,time:60000,offset:"200px"});$.post(WST.U("admin/index/clearCache"),{},function(c,d){layer.close(a);var b=WST.toAdminJson(c);if(b.status=="1"){WST.msg(b.msg,{icon:1,offset:"200px"})}else{WST.msg(b.msg,{icon:2,offset:"200px"})}})}function editPassBox(){var a=WST.open({type:1,title:"修改密码",shade:[0.6,"#000"],border:[0],content:$("#editPassBox"),area:["450px","250px"],btn:["确定","取消"],yes:function(c,b){$("#editPassFrom").isValid(function(d){if(d){var f=WST.getParams(".ipt");var e=WST.msg("鏁版嵁澶勭悊涓紝璇风◢鍊�...");$.post(WST.U("admin/Staffs/editMyPass"),f,function(h){layer.close(e);var g=WST.toAdminJson(h);if(g.status==1){WST.msg(g.msg,{icon:1});layer.close(a)}else{WST.msg(g.msg,{icon:2})}})}})}})}; \ No newline at end of file diff --git a/hyhproject/admin/view/js/jquery.min.js b/hyhproject/admin/view/js/jquery.min.js new file mode 100755 index 0000000..969e7cb --- /dev/null +++ b/hyhproject/admin/view/js/jquery.min.js @@ -0,0 +1,6 @@ +/*! jQuery v2.0.0 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license +//@ sourceMappingURL=jquery.min.map +*/ +(function(e,undefined){var t,n,r=typeof undefined,i=e.location,o=e.document,s=o.documentElement,a=e.jQuery,u=e.$,l={},c=[],f="2.0.0",p=c.concat,h=c.push,d=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=f.trim,x=function(e,n){return new x.fn.init(e,n,t)},b=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^-ms-/,N=/-([\da-z])/gi,E=function(e,t){return t.toUpperCase()},S=function(){o.removeEventListener("DOMContentLoaded",S,!1),e.removeEventListener("load",S,!1),x.ready()};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,t,n){var r,i;if(!e)return this;if("string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:T.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof x?t[0]:t,x.merge(this,x.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:o,!0)),C.test(r[1])&&x.isPlainObject(t))for(r in t)x.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=o.getElementById(r[2]),i&&i.parentNode&&(this.length=1,this[0]=i),this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?n.ready(e):(e.selector!==undefined&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return d.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,t,n,r,i,o,s=arguments[0]||{},a=1,u=arguments.length,l=!1;for("boolean"==typeof s&&(l=s,s=arguments[1]||{},a=2),"object"==typeof s||x.isFunction(s)||(s={}),u===a&&(s=this,--a);u>a;a++)if(null!=(e=arguments[a]))for(t in e)n=s[t],r=e[t],s!==r&&(l&&r&&(x.isPlainObject(r)||(i=x.isArray(r)))?(i?(i=!1,o=n&&x.isArray(n)?n:[]):o=n&&x.isPlainObject(n)?n:{},s[t]=x.extend(l,o,r)):r!==undefined&&(s[t]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=a),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){(e===!0?--x.readyWait:x.isReady)||(x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(o,[x]),x.fn.trigger&&x(o).trigger("ready").off("ready")))},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray,isWindow:function(e){return null!=e&&e===e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if("object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(t){return!1}return!0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:JSON.parse,parseXML:function(e){var t,n;if(!e||"string"!=typeof e)return null;try{n=new DOMParser,t=n.parseFromString(e,"text/xml")}catch(r){t=undefined}return(!t||t.getElementsByTagName("parsererror").length)&&x.error("Invalid XML: "+e),t},noop:function(){},globalEval:function(e){var t,n=eval;e=x.trim(e),e&&(1===e.indexOf("use strict")?(t=o.createElement("script"),t.text=e,o.head.appendChild(t).parentNode.removeChild(t)):n(e))},camelCase:function(e){return e.replace(k,"ms-").replace(N,E)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,s=j(e);if(n){if(s){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(s){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:function(e){return null==e?"":v.call(e)},makeArray:function(e,t){var n=t||[];return null!=e&&(j(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:g.call(t,e,n)},merge:function(e,t){var n=t.length,r=e.length,i=0;if("number"==typeof n)for(;n>i;i++)e[r++]=t[i];else while(t[i]!==undefined)e[r++]=t[i++];return e.length=r,e},grep:function(e,t,n){var r,i=[],o=0,s=e.length;for(n=!!n;s>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,s=j(e),a=[];if(s)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(a[a.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(a[a.length]=r);return p.apply([],a)},guid:1,proxy:function(e,t){var n,r,i;return"string"==typeof t&&(n=e[t],t=e,e=n),x.isFunction(e)?(r=d.call(arguments,2),i=function(){return e.apply(t||this,r.concat(d.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):undefined},access:function(e,t,n,r,i,o,s){var a=0,u=e.length,l=null==n;if("object"===x.type(n)){i=!0;for(a in n)x.access(e,t,a,n[a],!0,o,s)}else if(r!==undefined&&(i=!0,x.isFunction(r)||(s=!0),l&&(s?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(x(e),n)})),t))for(;u>a;a++)t(e[a],n,s?r:r.call(e[a],a,t(e[a],n)));return i?e:l?t.call(e):u?t(e[0],n):o},now:Date.now,swap:function(e,t,n,r){var i,o,s={};for(o in t)s[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=s[o];return i}}),x.ready.promise=function(t){return n||(n=x.Deferred(),"complete"===o.readyState?setTimeout(x.ready):(o.addEventListener("DOMContentLoaded",S,!1),e.addEventListener("load",S,!1))),n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function j(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}t=x(o),function(e,undefined){var t,n,r,i,o,s,a,u,l,c,f,p,h,d,g,m,y="sizzle"+-new Date,v=e.document,b={},w=0,T=0,C=ot(),k=ot(),N=ot(),E=!1,S=function(){return 0},j=typeof undefined,D=1<<31,A=[],L=A.pop,q=A.push,H=A.push,O=A.slice,F=A.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},P="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",R="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=M.replace("w","w#"),$="\\["+R+"*("+M+")"+R+"*(?:([*^$|!~]?=)"+R+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+R+"*\\]",B=":("+M+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",I=RegExp("^"+R+"+|((?:^|[^\\\\])(?:\\\\.)*)"+R+"+$","g"),z=RegExp("^"+R+"*,"+R+"*"),_=RegExp("^"+R+"*([>+~]|"+R+")"+R+"*"),X=RegExp(R+"*[+~]"),U=RegExp("="+R+"*([^\\]'\"]*)"+R+"*\\]","g"),Y=RegExp(B),V=RegExp("^"+W+"$"),G={ID:RegExp("^#("+M+")"),CLASS:RegExp("^\\.("+M+")"),TAG:RegExp("^("+M.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+B),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),"boolean":RegExp("^(?:"+P+")$","i"),needsContext:RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},J=/^[^{]+\{\s*\[native \w/,Q=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,et=/'|\\/g,tt=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,nt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{H.apply(A=O.call(v.childNodes),v.childNodes),A[v.childNodes.length].nodeType}catch(rt){H={apply:A.length?function(e,t){q.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function it(e){return J.test(e+"")}function ot(){var e,t=[];return e=function(n,i){return t.push(n+=" ")>r.cacheLength&&delete e[t.shift()],e[n]=i}}function st(e){return e[y]=!0,e}function at(e){var t=c.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ut(e,t,n,r){var i,o,s,a,u,f,d,g,x,w;if((t?t.ownerDocument||t:v)!==c&&l(t),t=t||c,n=n||[],!e||"string"!=typeof e)return n;if(1!==(a=t.nodeType)&&9!==a)return[];if(p&&!r){if(i=Q.exec(e))if(s=i[1]){if(9===a){if(o=t.getElementById(s),!o||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&m(t,o)&&o.id===s)return n.push(o),n}else{if(i[2])return H.apply(n,t.getElementsByTagName(e)),n;if((s=i[3])&&b.getElementsByClassName&&t.getElementsByClassName)return H.apply(n,t.getElementsByClassName(s)),n}if(b.qsa&&(!h||!h.test(e))){if(g=d=y,x=t,w=9===a&&e,1===a&&"object"!==t.nodeName.toLowerCase()){f=gt(e),(d=t.getAttribute("id"))?g=d.replace(et,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=f.length;while(u--)f[u]=g+mt(f[u]);x=X.test(e)&&t.parentNode||t,w=f.join(",")}if(w)try{return H.apply(n,x.querySelectorAll(w)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(I,"$1"),t,n,r)}o=ut.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},l=ut.setDocument=function(e){var t=e?e.ownerDocument||e:v;return t!==c&&9===t.nodeType&&t.documentElement?(c=t,f=t.documentElement,p=!o(t),b.getElementsByTagName=at(function(e){return e.appendChild(t.createComment("")),!e.getElementsByTagName("*").length}),b.attributes=at(function(e){return e.className="i",!e.getAttribute("className")}),b.getElementsByClassName=at(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),b.sortDetached=at(function(e){return 1&e.compareDocumentPosition(c.createElement("div"))}),b.getById=at(function(e){return f.appendChild(e).id=y,!t.getElementsByName||!t.getElementsByName(y).length}),b.getById?(r.find.ID=function(e,t){if(typeof t.getElementById!==j&&p){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},r.filter.ID=function(e){var t=e.replace(tt,nt);return function(e){return e.getAttribute("id")===t}}):(r.find.ID=function(e,t){if(typeof t.getElementById!==j&&p){var n=t.getElementById(e);return n?n.id===e||typeof n.getAttributeNode!==j&&n.getAttributeNode("id").value===e?[n]:undefined:[]}},r.filter.ID=function(e){var t=e.replace(tt,nt);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),r.find.TAG=b.getElementsByTagName?function(e,t){return typeof t.getElementsByTagName!==j?t.getElementsByTagName(e):undefined}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=b.getElementsByClassName&&function(e,t){return typeof t.getElementsByClassName!==j&&p?t.getElementsByClassName(e):undefined},d=[],h=[],(b.qsa=it(t.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+R+"*(?:value|"+P+")"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){var t=c.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&h.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(b.matchesSelector=it(g=f.webkitMatchesSelector||f.mozMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){b.disconnectedMatch=g.call(e,"div"),g.call(e,"[s!='']:x"),d.push("!=",B)}),h=h.length&&RegExp(h.join("|")),d=d.length&&RegExp(d.join("|")),m=it(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},S=f.compareDocumentPosition?function(e,n){if(e===n)return E=!0,0;var r=n.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(n);return r?1&r||!b.sortDetached&&n.compareDocumentPosition(e)===r?e===t||m(v,e)?-1:n===t||m(v,n)?1:u?F.call(u,e)-F.call(u,n):0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,n){var r,i=0,o=e.parentNode,s=n.parentNode,a=[e],l=[n];if(e===n)return E=!0,0;if(!o||!s)return e===t?-1:n===t?1:o?-1:s?1:u?F.call(u,e)-F.call(u,n):0;if(o===s)return lt(e,n);r=e;while(r=r.parentNode)a.unshift(r);r=n;while(r=r.parentNode)l.unshift(r);while(a[i]===l[i])i++;return i?lt(a[i],l[i]):a[i]===v?-1:l[i]===v?1:0},c):c},ut.matches=function(e,t){return ut(e,null,null,t)},ut.matchesSelector=function(e,t){if((e.ownerDocument||e)!==c&&l(e),t=t.replace(U,"='$1']"),!(!b.matchesSelector||!p||d&&d.test(t)||h&&h.test(t)))try{var n=g.call(e,t);if(n||b.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return ut(t,c,null,[e]).length>0},ut.contains=function(e,t){return(e.ownerDocument||e)!==c&&l(e),m(e,t)},ut.attr=function(e,t){(e.ownerDocument||e)!==c&&l(e);var n=r.attrHandle[t.toLowerCase()],i=n&&n(e,t,!p);return i===undefined?b.attributes||!p?e.getAttribute(t):(i=e.getAttributeNode(t))&&i.specified?i.value:null:i},ut.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},ut.uniqueSort=function(e){var t,n=[],r=0,i=0;if(E=!b.detectDuplicates,u=!b.sortStable&&e.slice(0),e.sort(S),E){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return e};function lt(e,t){var n=t&&e,r=n&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ct(e,t,n){var r;return n?undefined:(r=e.getAttributeNode(t))&&r.specified?r.value:e[t]===!0?t.toLowerCase():null}function ft(e,t,n){var r;return n?undefined:r=e.getAttribute(t,"type"===t.toLowerCase()?1:2)}function pt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ht(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function dt(e){return st(function(t){return t=+t,st(function(n,r){var i,o=e([],n.length,t),s=o.length;while(s--)n[i=o[s]]&&(n[i]=!(r[i]=n[i]))})})}i=ut.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r];r++)n+=i(t);return n},r=ut.selectors={cacheLength:50,createPseudo:st,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(tt,nt),e[3]=(e[4]||e[5]||"").replace(tt,nt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||ut.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&ut.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return G.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&Y.test(n)&&(t=gt(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(tt,nt).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&C(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=ut.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),s="last"!==e.slice(-4),a="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,h,d,g=o!==s?"nextSibling":"previousSibling",m=t.parentNode,v=a&&t.nodeName.toLowerCase(),x=!u&&!a;if(m){if(o){while(g){f=t;while(f=f[g])if(a?f.nodeName.toLowerCase()===v:1===f.nodeType)return!1;d=g="only"===e&&!d&&"nextSibling"}return!0}if(d=[s?m.firstChild:m.lastChild],s&&x){c=m[y]||(m[y]={}),l=c[e]||[],h=l[0]===w&&l[1],p=l[0]===w&&l[2],f=h&&m.childNodes[h];while(f=++h&&f&&f[g]||(p=h=0)||d.pop())if(1===f.nodeType&&++p&&f===t){c[e]=[w,h,p];break}}else if(x&&(l=(t[y]||(t[y]={}))[e])&&l[0]===w)p=l[1];else while(f=++h&&f&&f[g]||(p=h=0)||d.pop())if((a?f.nodeName.toLowerCase()===v:1===f.nodeType)&&++p&&(x&&((f[y]||(f[y]={}))[e]=[w,p]),f===t))break;return p-=i,p===r||0===p%r&&p/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||ut.error("unsupported pseudo: "+e);return i[y]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?st(function(e,n){var r,o=i(e,t),s=o.length;while(s--)r=F.call(e,o[s]),e[r]=!(n[r]=o[s])}):function(e){return i(e,0,n)}):i}},pseudos:{not:st(function(e){var t=[],n=[],r=s(e.replace(I,"$1"));return r[y]?st(function(e,t,n,i){var o,s=r(e,null,i,[]),a=e.length;while(a--)(o=s[a])&&(e[a]=!(t[a]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:st(function(e){return function(t){return ut(e,t).length>0}}),contains:st(function(e){return function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:st(function(e){return V.test(e||"")||ut.error("unsupported lang: "+e),e=e.replace(tt,nt).toLowerCase(),function(t){var n;do if(n=p?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===c.activeElement&&(!c.hasFocus||c.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Z.test(e.nodeName)},input:function(e){return K.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:dt(function(){return[0]}),last:dt(function(e,t){return[t-1]}),eq:dt(function(e,t,n){return[0>n?n+t:n]}),even:dt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:dt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:dt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:dt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(t in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})r.pseudos[t]=pt(t);for(t in{submit:!0,reset:!0})r.pseudos[t]=ht(t);function gt(e,t){var n,i,o,s,a,u,l,c=k[e+" "];if(c)return t?0:c.slice(0);a=e,u=[],l=r.preFilter;while(a){(!n||(i=z.exec(a)))&&(i&&(a=a.slice(i[0].length)||a),u.push(o=[])),n=!1,(i=_.exec(a))&&(n=i.shift(),o.push({value:n,type:i[0].replace(I," ")}),a=a.slice(n.length));for(s in r.filter)!(i=G[s].exec(a))||l[s]&&!(i=l[s](i))||(n=i.shift(),o.push({value:n,type:s,matches:i}),a=a.slice(n.length));if(!n)break}return t?a.length:a?ut.error(e):k(e,u).slice(0)}function mt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function yt(e,t,r){var i=t.dir,o=r&&"parentNode"===i,s=T++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,r,a){var u,l,c,f=w+" "+s;if(a){while(t=t[i])if((1===t.nodeType||o)&&e(t,r,a))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[y]||(t[y]={}),(l=c[i])&&l[0]===f){if((u=l[1])===!0||u===n)return u===!0}else if(l=c[i]=[f],l[1]=e(t,r,a)||n,l[1]===!0)return!0}}function vt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,s=[],a=0,u=e.length,l=null!=t;for(;u>a;a++)(o=e[a])&&(!n||n(o,r,i))&&(s.push(o),l&&t.push(a));return s}function bt(e,t,n,r,i,o){return r&&!r[y]&&(r=bt(r)),i&&!i[y]&&(i=bt(i,o)),st(function(o,s,a,u){var l,c,f,p=[],h=[],d=s.length,g=o||Ct(t||"*",a.nodeType?[a]:a,[]),m=!e||!o&&t?g:xt(g,p,e,a,u),y=n?i||(o?e:d||r)?[]:s:m;if(n&&n(m,y,a,u),r){l=xt(y,h),r(l,[],a,u),c=l.length;while(c--)(f=l[c])&&(y[h[c]]=!(m[h[c]]=f))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(f=y[c])&&l.push(m[c]=f);i(null,y=[],l,u)}c=y.length;while(c--)(f=y[c])&&(l=i?F.call(o,f):p[c])>-1&&(o[l]=!(s[l]=f))}}else y=xt(y===s?y.splice(d,y.length):y),i?i(null,s,y,u):H.apply(s,y)})}function wt(e){var t,n,i,o=e.length,s=r.relative[e[0].type],u=s||r.relative[" "],l=s?1:0,c=yt(function(e){return e===t},u,!0),f=yt(function(e){return F.call(t,e)>-1},u,!0),p=[function(e,n,r){return!s&&(r||n!==a)||((t=n).nodeType?c(e,n,r):f(e,n,r))}];for(;o>l;l++)if(n=r.relative[e[l].type])p=[yt(vt(p),n)];else{if(n=r.filter[e[l].type].apply(null,e[l].matches),n[y]){for(i=++l;o>i;i++)if(r.relative[e[i].type])break;return bt(l>1&&vt(p),l>1&&mt(e.slice(0,l-1)).replace(I,"$1"),n,i>l&&wt(e.slice(l,i)),o>i&&wt(e=e.slice(i)),o>i&&mt(e))}p.push(n)}return vt(p)}function Tt(e,t){var i=0,o=t.length>0,s=e.length>0,u=function(u,l,f,p,h){var d,g,m,y=[],v=0,x="0",b=u&&[],T=null!=h,C=a,k=u||s&&r.find.TAG("*",h&&l.parentNode||l),N=w+=null==C?1:Math.random()||.1;for(T&&(a=l!==c&&l,n=i);null!=(d=k[x]);x++){if(s&&d){g=0;while(m=e[g++])if(m(d,l,f)){p.push(d);break}T&&(w=N,n=++i)}o&&((d=!m&&d)&&v--,u&&b.push(d))}if(v+=x,o&&x!==v){g=0;while(m=t[g++])m(b,y,l,f);if(u){if(v>0)while(x--)b[x]||y[x]||(y[x]=L.call(p));y=xt(y)}H.apply(p,y),T&&!u&&y.length>0&&v+t.length>1&&ut.uniqueSort(p)}return T&&(w=N,a=C),b};return o?st(u):u}s=ut.compile=function(e,t){var n,r=[],i=[],o=N[e+" "];if(!o){t||(t=gt(e)),n=t.length;while(n--)o=wt(t[n]),o[y]?r.push(o):i.push(o);o=N(e,Tt(i,r))}return o};function Ct(e,t,n){var r=0,i=t.length;for(;i>r;r++)ut(e,t[r],n);return n}function kt(e,t,n,i){var o,a,u,l,c,f=gt(e);if(!i&&1===f.length){if(a=f[0]=f[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&p&&r.relative[a[1].type]){if(t=(r.find.ID(u.matches[0].replace(tt,nt),t)||[])[0],!t)return n;e=e.slice(a.shift().value.length)}o=G.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],r.relative[l=u.type])break;if((c=r.find[l])&&(i=c(u.matches[0].replace(tt,nt),X.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=i.length&&mt(a),!e)return H.apply(n,i),n;break}}}return s(e,f)(i,t,!p,n,X.test(e)),n}r.pseudos.nth=r.pseudos.eq;function Nt(){}Nt.prototype=r.filters=r.pseudos,r.setFilters=new Nt,b.sortStable=y.split("").sort(S).join("")===y,l(),[0,0].sort(S),b.detectDuplicates=E,at(function(e){if(e.innerHTML="<a href='#'></a>","#"!==e.firstChild.getAttribute("href")){var t="type|href|height|width".split("|"),n=t.length;while(n--)r.attrHandle[t[n]]=ft}}),at(function(e){if(null!=e.getAttribute("disabled")){var t=P.split("|"),n=t.length;while(n--)r.attrHandle[t[n]]=ct}}),x.find=ut,x.expr=ut.selectors,x.expr[":"]=x.expr.pseudos,x.unique=ut.uniqueSort,x.text=ut.getText,x.isXMLDoc=ut.isXML,x.contains=ut.contains}(e);var D={};function A(e){var t=D[e]={};return x.each(e.match(w)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?D[e]||A(e):x.extend({},e);var t,n,r,i,o,s,a=[],u=!e.once&&[],l=function(f){for(t=e.memory&&f,n=!0,s=i||0,i=0,o=a.length,r=!0;a&&o>s;s++)if(a[s].apply(f[0],f[1])===!1&&e.stopOnFalse){t=!1;break}r=!1,a&&(u?u.length&&l(u.shift()):t?a=[]:c.disable())},c={add:function(){if(a){var n=a.length;(function s(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==r&&s(n)})})(arguments),r?o=a.length:t&&(i=n,l(t))}return this},remove:function(){return a&&x.each(arguments,function(e,t){var n;while((n=x.inArray(t,a,n))>-1)a.splice(n,1),r&&(o>=n&&o--,s>=n&&s--)}),this},has:function(e){return e?x.inArray(e,a)>-1:!(!a||!a.length)},empty:function(){return a=[],o=0,this},disable:function(){return a=u=t=undefined,this},disabled:function(){return!a},lock:function(){return u=undefined,t||c.disable(),this},locked:function(){return!u},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!a||n&&!u||(r?u.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!n}};return c},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var s=o[0],a=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var s=o[2],a=o[3];r[o[1]]=s.add,a&&s.add(function(){n=a},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=s.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=d.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),s=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?d.call(arguments):r,n===a?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},a,u,l;if(r>1)for(a=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(s(t,l,n)).fail(o.reject).progress(s(t,u,a)):--i;return i||o.resolveWith(l,n),o.promise()}}),x.support=function(t){var n=o.createElement("input"),r=o.createDocumentFragment(),i=o.createElement("div"),s=o.createElement("select"),a=s.appendChild(o.createElement("option"));return n.type?(n.type="checkbox",t.checkOn=""!==n.value,t.optSelected=a.selected,t.reliableMarginRight=!0,t.boxSizingReliable=!0,t.pixelPosition=!1,n.checked=!0,t.noCloneChecked=n.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!a.disabled,n=o.createElement("input"),n.value="t",n.type="radio",t.radioValue="t"===n.value,n.setAttribute("checked","t"),n.setAttribute("name","t"),r.appendChild(n),t.checkClone=r.cloneNode(!0).cloneNode(!0).lastChild.checked,t.focusinBubbles="onfocusin"in e,i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===i.style.backgroundClip,x(function(){var n,r,s="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",a=o.getElementsByTagName("body")[0];a&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",a.appendChild(n).appendChild(i),i.innerHTML="",i.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",x.swap(a,null!=a.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===i.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(i,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(i,null)||{width:"4px"}).width,r=i.appendChild(o.createElement("div")),r.style.cssText=i.style.cssText=s,r.style.marginRight=r.style.width="0",i.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),a.removeChild(n))}),t):t}({});var L,q,H=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,O=/([A-Z])/g;function F(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=x.expando+Math.random()}F.uid=1,F.accepts=function(e){return e.nodeType?1===e.nodeType||9===e.nodeType:!0},F.prototype={key:function(e){if(!F.accepts(e))return 0;var t={},n=e[this.expando];if(!n){n=F.uid++;try{t[this.expando]={value:n},Object.defineProperties(e,t)}catch(r){t[this.expando]=n,x.extend(e,t)}}return this.cache[n]||(this.cache[n]={}),n},set:function(e,t,n){var r,i=this.key(e),o=this.cache[i];if("string"==typeof t)o[t]=n;else if(x.isEmptyObject(o))this.cache[i]=t;else for(r in t)o[r]=t[r]},get:function(e,t){var n=this.cache[this.key(e)];return t===undefined?n:n[t]},access:function(e,t,n){return t===undefined||t&&"string"==typeof t&&n===undefined?this.get(e,t):(this.set(e,t,n),n!==undefined?n:t)},remove:function(e,t){var n,r,i=this.key(e),o=this.cache[i];if(t===undefined)this.cache[i]={};else{x.isArray(t)?r=t.concat(t.map(x.camelCase)):t in o?r=[t]:(r=x.camelCase(t),r=r in o?[r]:r.match(w)||[]),n=r.length;while(n--)delete o[r[n]]}},hasData:function(e){return!x.isEmptyObject(this.cache[e[this.expando]]||{})},discard:function(e){delete this.cache[this.key(e)]}},L=new F,q=new F,x.extend({acceptData:F.accepts,hasData:function(e){return L.hasData(e)||q.hasData(e)},data:function(e,t,n){return L.access(e,t,n)},removeData:function(e,t){L.remove(e,t)},_data:function(e,t,n){return q.access(e,t,n)},_removeData:function(e,t){q.remove(e,t)}}),x.fn.extend({data:function(e,t){var n,r,i=this[0],o=0,s=null;if(e===undefined){if(this.length&&(s=L.get(i),1===i.nodeType&&!q.get(i,"hasDataAttrs"))){for(n=i.attributes;n.length>o;o++)r=n[o].name,0===r.indexOf("data-")&&(r=x.camelCase(r.substring(5)),P(i,r,s[r]));q.set(i,"hasDataAttrs",!0)}return s}return"object"==typeof e?this.each(function(){L.set(this,e)}):x.access(this,function(t){var n,r=x.camelCase(e);if(i&&t===undefined){if(n=L.get(i,e),n!==undefined)return n;if(n=L.get(i,r),n!==undefined)return n;if(n=P(i,r,undefined),n!==undefined)return n}else this.each(function(){var n=L.get(this,r);L.set(this,r,t),-1!==e.indexOf("-")&&n!==undefined&&L.set(this,e,t)})},null,t,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){L.remove(this,e)})}});function P(e,t,n){var r;if(n===undefined&&1===e.nodeType)if(r="data-"+t.replace(O,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:H.test(n)?JSON.parse(n):n}catch(i){}L.set(e,t,n)}else n=undefined;return n}x.extend({queue:function(e,t,n){var r;return e?(t=(t||"fx")+"queue",r=q.get(e,t),n&&(!r||x.isArray(n)?r=q.access(e,t,x.makeArray(n)):r.push(n)),r||[]):undefined},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),s=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,s,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return q.get(e,n)||q.access(e,n,{empty:x.Callbacks("once memory").add(function(){q.remove(e,[t+"queue",n])})})}}),x.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),n>arguments.length?x.queue(this[0],e):t===undefined?this:this.each(function(){var n=x.queue(this,e,t); +x._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=x.Deferred(),o=this,s=this.length,a=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=undefined),e=e||"fx";while(s--)n=q.get(o[s],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(a));return a(),i.promise(t)}});var R,M,W=/[\t\r\n]/g,$=/\r/g,B=/^(?:input|select|textarea|button)$/i;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[x.propFix[e]||e]})},addClass:function(e){var t,n,r,i,o,s=0,a=this.length,u="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,s=0,a=this.length,u=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];a>s;s++)if(n=this[s],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(W," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,i="boolean"==typeof t;return x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,s=0,a=x(this),u=t,l=e.match(w)||[];while(o=l[s++])u=i?u:!a.hasClass(o),a[u?"addClass":"removeClass"](o)}else(n===r||"boolean"===n)&&(this.className&&q.set(this,"__className__",this.className),this.className=this.className||e===!1?"":q.get(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(W," ").indexOf(t)>=0)return!0;return!1},val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=x.isFunction(e),this.each(function(n){var i,o=x(this);1===this.nodeType&&(i=r?e.call(this,n,o.val()):e,null==i?i="":"number"==typeof i?i+="":x.isArray(i)&&(i=x.map(i,function(e){return null==e?"":e+""})),t=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&t.set(this,i,"value")!==undefined||(this.value=i))});if(i)return t=x.valHooks[i.type]||x.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&(n=t.get(i,"value"))!==undefined?n:(n=i.value,"string"==typeof n?n.replace($,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,s=o?null:[],a=o?i+1:r.length,u=0>i?a:o?i:0;for(;a>u;u++)if(n=r[u],!(!n.selected&&u!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),s=i.length;while(s--)r=i[s],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,t,n){var i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===r?x.prop(e,t,n):(1===s&&x.isXMLDoc(e)||(t=t.toLowerCase(),i=x.attrHooks[t]||(x.expr.match.boolean.test(t)?M:R)),n===undefined?i&&"get"in i&&null!==(o=i.get(e,t))?o:(o=x.find.attr(e,t),null==o?undefined:o):null!==n?i&&"set"in i&&(o=i.set(e,n,t))!==undefined?o:(e.setAttribute(t,n+""),n):(x.removeAttr(e,t),undefined))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.boolean.test(n)&&(e[r]=!1),e.removeAttribute(n)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,t,n){var r,i,o,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return o=1!==s||!x.isXMLDoc(e),o&&(t=x.propFix[t]||t,i=x.propHooks[t]),n!==undefined?i&&"set"in i&&(r=i.set(e,n,t))!==undefined?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){return e.hasAttribute("tabindex")||B.test(e.nodeName)||e.href?e.tabIndex:-1}}}}),M={set:function(e,t,n){return t===!1?x.removeAttr(e,n):e.setAttribute(n,n),n}},x.each(x.expr.match.boolean.source.match(/\w+/g),function(e,t){var n=x.expr.attrHandle[t]||x.find.attr;x.expr.attrHandle[t]=function(e,t,r){var i=x.expr.attrHandle[t],o=r?undefined:(x.expr.attrHandle[t]=undefined)!=n(e,t,r)?t.toLowerCase():null;return x.expr.attrHandle[t]=i,o}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,t){return x.isArray(t)?e.checked=x.inArray(x(e).val(),t)>=0:undefined}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var I=/^key/,z=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,X=/^([^.]*)(?:\.(.+)|)$/;function U(){return!0}function Y(){return!1}function V(){try{return o.activeElement}catch(e){}}x.event={global:{},add:function(e,t,n,i,o){var s,a,u,l,c,f,p,h,d,g,m,y=q.get(e);if(y){n.handler&&(s=n,n=s.handler,o=s.selector),n.guid||(n.guid=x.guid++),(l=y.events)||(l=y.events={}),(a=y.handle)||(a=y.handle=function(e){return typeof x===r||e&&x.event.triggered===e.type?undefined:x.event.dispatch.apply(a.elem,arguments)},a.elem=e),t=(t||"").match(w)||[""],c=t.length;while(c--)u=X.exec(t[c])||[],d=m=u[1],g=(u[2]||"").split(".").sort(),d&&(p=x.event.special[d]||{},d=(o?p.delegateType:p.bindType)||d,p=x.event.special[d]||{},f=x.extend({type:d,origType:m,data:i,handler:n,guid:n.guid,selector:o,needsContext:o&&x.expr.match.needsContext.test(o),namespace:g.join(".")},s),(h=l[d])||(h=l[d]=[],h.delegateCount=0,p.setup&&p.setup.call(e,i,g,a)!==!1||e.addEventListener&&e.addEventListener(d,a,!1)),p.add&&(p.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),o?h.splice(h.delegateCount++,0,f):h.push(f),x.event.global[d]=!0);e=null}},remove:function(e,t,n,r,i){var o,s,a,u,l,c,f,p,h,d,g,m=q.hasData(e)&&q.get(e);if(m&&(u=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(a=X.exec(t[l])||[],h=g=a[1],d=(a[2]||"").split(".").sort(),h){f=x.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,p=u[h]||[],a=a[2]&&RegExp("(^|\\.)"+d.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));s&&!p.length&&(f.teardown&&f.teardown.call(e,d,m.handle)!==!1||x.removeEvent(e,h,m.handle),delete u[h])}else for(h in u)x.event.remove(e,h+t[l],n,r,!0);x.isEmptyObject(u)&&(delete m.handle,q.remove(e,"events"))}},trigger:function(t,n,r,i){var s,a,u,l,c,f,p,h=[r||o],d=y.call(t,"type")?t.type:t,g=y.call(t,"namespace")?t.namespace.split("."):[];if(a=u=r=r||o,3!==r.nodeType&&8!==r.nodeType&&!_.test(d+x.event.triggered)&&(d.indexOf(".")>=0&&(g=d.split("."),d=g.shift(),g.sort()),c=0>d.indexOf(":")&&"on"+d,t=t[x.expando]?t:new x.Event(d,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=g.join("."),t.namespace_re=t.namespace?RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=undefined,t.target||(t.target=r),n=null==n?[t]:x.makeArray(n,[t]),p=x.event.special[d]||{},i||!p.trigger||p.trigger.apply(r,n)!==!1)){if(!i&&!p.noBubble&&!x.isWindow(r)){for(l=p.delegateType||d,_.test(l+d)||(a=a.parentNode);a;a=a.parentNode)h.push(a),u=a;u===(r.ownerDocument||o)&&h.push(u.defaultView||u.parentWindow||e)}s=0;while((a=h[s++])&&!t.isPropagationStopped())t.type=s>1?l:p.bindType||d,f=(q.get(a,"events")||{})[t.type]&&q.get(a,"handle"),f&&f.apply(a,n),f=c&&a[c],f&&x.acceptData(a)&&f.apply&&f.apply(a,n)===!1&&t.preventDefault();return t.type=d,i||t.isDefaultPrevented()||p._default&&p._default.apply(h.pop(),n)!==!1||!x.acceptData(r)||c&&x.isFunction(r[d])&&!x.isWindow(r)&&(u=r[c],u&&(r[c]=null),x.event.triggered=d,r[d](),x.event.triggered=undefined,u&&(r[c]=u)),t.result}},dispatch:function(e){e=x.event.fix(e);var t,n,r,i,o,s=[],a=d.call(arguments),u=(q.get(this,"events")||{})[e.type]||[],l=x.event.special[e.type]||{};if(a[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),t=0;while((i=s[t++])&&!e.isPropagationStopped()){e.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(o.namespace))&&(e.handleObj=o,e.data=o.data,r=((x.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,a),r!==undefined&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,s=[],a=t.delegateCount,u=e.target;if(a&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!==this;u=u.parentNode||this)if(u.disabled!==!0||"click"!==e.type){for(r=[],n=0;a>n;n++)o=t[n],i=o.selector+" ",r[i]===undefined&&(r[i]=o.needsContext?x(i,this).index(u)>=0:x.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&s.push({elem:u,handlers:r})}return t.length>a&&s.push({elem:this,handlers:t.slice(a)}),s},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,s=t.button;return null==e.pageX&&null!=t.clientX&&(n=e.target.ownerDocument||o,r=n.documentElement,i=n.body,e.pageX=t.clientX+(r&&r.scrollLeft||i&&i.scrollLeft||0)-(r&&r.clientLeft||i&&i.clientLeft||0),e.pageY=t.clientY+(r&&r.scrollTop||i&&i.scrollTop||0)-(r&&r.clientTop||i&&i.clientTop||0)),e.which||s===undefined||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=z.test(i)?this.mouseHooks:I.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return 3===e.target.nodeType&&(e.target=e.target.parentNode),s.filter?s.filter(e,o):e},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==V()&&this.focus?(this.focus(),!1):undefined},delegateType:"focusin"},blur:{trigger:function(){return this===V()&&this.blur?(this.blur(),!1):undefined},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&x.nodeName(this,"input")?(this.click(),!1):undefined},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==undefined&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)},x.Event=function(e,t){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.getPreventDefault&&e.getPreventDefault()?U:Y):this.type=e,t&&x.extend(this,t),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,undefined):new x.Event(e,t)},x.Event.prototype={isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=U,e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=U,e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=U,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,t,n,r,i){var o,s;if("object"==typeof e){"string"!=typeof t&&(n=n||t,t=undefined);for(s in e)this.on(s,t,n,e[s],i);return this}if(null==n&&null==r?(r=t,n=t=undefined):null==r&&("string"==typeof t?(r=n,n=undefined):(r=n,n=t,t=undefined)),r===!1)r=Y;else if(!r)return this;return 1===i&&(o=r,r=function(e){return x().off(e),o.apply(this,arguments)},r.guid=o.guid||(o.guid=x.guid++)),this.each(function(){x.event.add(this,e,r,n,t)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,x(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return(t===!1||"function"==typeof t)&&(n=t,t=undefined),n===!1&&(n=Y),this.each(function(){x.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];return n?x.event.trigger(e,t,n,!0):undefined}});var G=/^.[^:#\[\.,]*$/,J=x.expr.match.needsContext,Q={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return t=this,this.pushStack(x(e).filter(function(){for(r=0;i>r;r++)if(x.contains(t[r],this))return!0}));for(n=[],r=0;i>r;r++)x.find(e,this[r],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t=x(e,this),n=t.length;return this.filter(function(){var e=0;for(;n>e;e++)if(x.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(Z(this,e||[],!0))},filter:function(e){return this.pushStack(Z(this,e||[],!1))},is:function(e){return!!e&&("string"==typeof e?J.test(e)?x(e,this.context).index(this[0])>=0:x.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],s=J.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(s?s.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?g.call(x(e),this[0]):g.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function K(e,t){while((e=e[t])&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return K(e,"nextSibling")},prev:function(e){return K(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(Q[e]||x.unique(i),"p"===e[0]&&i.reverse()),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,t,n){var r=[],i=n!==undefined;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&x(e).is(n))break;r.push(e)}return r},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function Z(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(G.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return g.call(t,e)>=0!==n})}var et=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,tt=/<([\w:]+)/,nt=/<|&#?\w+;/,rt=/<(?:script|style|link)/i,it=/^(?:checkbox|radio)$/i,ot=/checked\s*(?:[^=]|=\s*.checked.)/i,st=/^$|\/(?:java|ecma)script/i,at=/^true\/(.*)/,ut=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,lt={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};lt.optgroup=lt.option,lt.tbody=lt.tfoot=lt.colgroup=lt.caption=lt.col=lt.thead,lt.th=lt.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===undefined?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=ct(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=ct(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(gt(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&ht(gt(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++)1===e.nodeType&&(x.cleanData(gt(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var t=this[0]||{},n=0,r=this.length;if(e===undefined&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!rt.test(e)&&!lt[(tt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(et,"<$1></$2>");try{for(;r>n;n++)t=this[n]||{},1===t.nodeType&&(x.cleanData(gt(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=p.apply([],e);var r,i,o,s,a,u,l=0,c=this.length,f=this,h=c-1,d=e[0],g=x.isFunction(d);if(g||!(1>=c||"string"!=typeof d||x.support.checkClone)&&ot.test(d))return this.each(function(r){var i=f.eq(r);g&&(e[0]=d.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(r=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),i=r.firstChild,1===r.childNodes.length&&(r=i),i)){for(o=x.map(gt(r,"script"),ft),s=o.length;c>l;l++)a=r,l!==h&&(a=x.clone(a,!0,!0),s&&x.merge(o,gt(a,"script"))),t.call(this[l],a,l);if(s)for(u=o[o.length-1].ownerDocument,x.map(o,pt),l=0;s>l;l++)a=o[l],st.test(a.type||"")&&!q.access(a,"globalEval")&&x.contains(u,a)&&(a.src?x._evalUrl(a.src):x.globalEval(a.textContent.replace(ut,"")))}return this}}),x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=[],i=x(e),o=i.length-1,s=0;for(;o>=s;s++)n=s===o?this:this.clone(!0),x(i[s])[t](n),h.apply(r,n.get());return this.pushStack(r)}}),x.extend({clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),u=x.contains(e.ownerDocument,e);if(!(x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(s=gt(a),o=gt(e),r=0,i=o.length;i>r;r++)mt(o[r],s[r]);if(t)if(n)for(o=o||gt(e),s=s||gt(a),r=0,i=o.length;i>r;r++)dt(o[r],s[r]);else dt(e,a);return s=gt(a,"script"),s.length>0&&ht(s,!u&&gt(e,"script")),a},buildFragment:function(e,t,n,r){var i,o,s,a,u,l,c=0,f=e.length,p=t.createDocumentFragment(),h=[];for(;f>c;c++)if(i=e[c],i||0===i)if("object"===x.type(i))x.merge(h,i.nodeType?[i]:i);else if(nt.test(i)){o=o||p.appendChild(t.createElement("div")),s=(tt.exec(i)||["",""])[1].toLowerCase(),a=lt[s]||lt._default,o.innerHTML=a[1]+i.replace(et,"<$1></$2>")+a[2],l=a[0];while(l--)o=o.firstChild;x.merge(h,o.childNodes),o=p.firstChild,o.textContent=""}else h.push(t.createTextNode(i));p.textContent="",c=0;while(i=h[c++])if((!r||-1===x.inArray(i,r))&&(u=x.contains(i.ownerDocument,i),o=gt(p.appendChild(i),"script"),u&&ht(o),n)){l=0;while(i=o[l++])st.test(i.type||"")&&n.push(i)}return p},cleanData:function(e){var t,n,r,i=e.length,o=0,s=x.event.special;for(;i>o;o++){if(n=e[o],x.acceptData(n)&&(t=q.access(n)))for(r in t.events)s[r]?x.event.remove(n,r):x.removeEvent(n,r,t.handle);L.discard(n),q.discard(n)}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"text",async:!1,global:!1,success:x.globalEval})}});function ct(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function ft(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function pt(e){var t=at.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function ht(e,t){var n=e.length,r=0;for(;n>r;r++)q.set(e[r],"globalEval",!t||q.get(t[r],"globalEval"))}function dt(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(q.hasData(e)&&(o=q.access(e),s=x.extend({},o),l=o.events,q.set(t,s),l)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)x.event.add(t,i,l[i][n])}L.hasData(e)&&(a=L.access(e),u=x.extend({},a),L.set(t,u))}}function gt(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return t===undefined||t&&x.nodeName(e,t)?x.merge([e],n):n}function mt(e,t){var n=t.nodeName.toLowerCase();"input"===n&&it.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}x.fn.extend({wrapAll:function(e){var t;return x.isFunction(e)?this.each(function(t){x(this).wrapAll(e.call(this,t))}):(this[0]&&(t=x(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this)},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var yt,vt,xt=/^(none|table(?!-c[ea]).+)/,bt=/^margin/,wt=RegExp("^("+b+")(.*)$","i"),Tt=RegExp("^("+b+")(?!px)[a-z%]+$","i"),Ct=RegExp("^([+-])=("+b+")","i"),kt={BODY:"block"},Nt={position:"absolute",visibility:"hidden",display:"block"},Et={letterSpacing:0,fontWeight:400},St=["Top","Right","Bottom","Left"],jt=["Webkit","O","Moz","ms"];function Dt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=jt.length;while(i--)if(t=jt[i]+n,t in e)return t;return r}function At(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function Lt(t){return e.getComputedStyle(t,null)}function qt(e,t){var n,r,i,o=[],s=0,a=e.length;for(;a>s;s++)r=e[s],r.style&&(o[s]=q.get(r,"olddisplay"),n=r.style.display,t?(o[s]||"none"!==n||(r.style.display=""),""===r.style.display&&At(r)&&(o[s]=q.access(r,"olddisplay",Pt(r.nodeName)))):o[s]||(i=At(r),(n&&"none"!==n||!i)&&q.set(r,"olddisplay",i?n:x.css(r,"display"))));for(s=0;a>s;s++)r=e[s],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[s]||"":"none"));return e}x.fn.extend({css:function(e,t){return x.access(this,function(e,t,n){var r,i,o={},s=0;if(x.isArray(t)){for(r=Lt(e),i=t.length;i>s;s++)o[t[s]]=x.css(e,t[s],!1,r);return o}return n!==undefined?x.style(e,t,n):x.css(e,t)},e,t,arguments.length>1)},show:function(){return qt(this,!0)},hide:function(){return qt(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:At(this))?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=yt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=x.camelCase(t),u=e.style;return t=x.cssProps[a]||(x.cssProps[a]=Dt(u,a)),s=x.cssHooks[t]||x.cssHooks[a],n===undefined?s&&"get"in s&&(i=s.get(e,!1,r))!==undefined?i:u[t]:(o=typeof n,"string"===o&&(i=Ct.exec(n))&&(n=(i[1]+1)*i[2]+parseFloat(x.css(e,t)),o="number"),null==n||"number"===o&&isNaN(n)||("number"!==o||x.cssNumber[a]||(n+="px"),x.support.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&(n=s.set(e,n,r))===undefined||(u[t]=n)),undefined)}},css:function(e,t,n,r){var i,o,s,a=x.camelCase(t);return t=x.cssProps[a]||(x.cssProps[a]=Dt(e.style,a)),s=x.cssHooks[t]||x.cssHooks[a],s&&"get"in s&&(i=s.get(e,!0,n)),i===undefined&&(i=yt(e,t,r)),"normal"===i&&t in Et&&(i=Et[t]),""===n||n?(o=parseFloat(i),n===!0||x.isNumeric(o)?o||0:i):i}}),yt=function(e,t,n){var r,i,o,s=n||Lt(e),a=s?s.getPropertyValue(t)||s[t]:undefined,u=e.style;return s&&(""!==a||x.contains(e.ownerDocument,e)||(a=x.style(e,t)),Tt.test(a)&&bt.test(t)&&(r=u.width,i=u.minWidth,o=u.maxWidth,u.minWidth=u.maxWidth=u.width=a,a=s.width,u.width=r,u.minWidth=i,u.maxWidth=o)),a};function Ht(e,t,n){var r=wt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function Ot(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,s=0;for(;4>o;o+=2)"margin"===n&&(s+=x.css(e,n+St[o],!0,i)),r?("content"===n&&(s-=x.css(e,"padding"+St[o],!0,i)),"margin"!==n&&(s-=x.css(e,"border"+St[o]+"Width",!0,i))):(s+=x.css(e,"padding"+St[o],!0,i),"padding"!==n&&(s+=x.css(e,"border"+St[o]+"Width",!0,i)));return s}function Ft(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Lt(e),s=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=yt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Tt.test(i))return i;r=s&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+Ot(e,t,n||(s?"border":"content"),r,o)+"px"}function Pt(e){var t=o,n=kt[e];return n||(n=Rt(e,t),"none"!==n&&n||(vt=(vt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(vt[0].contentWindow||vt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=Rt(e,t),vt.detach()),kt[e]=n),n}function Rt(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,t){x.cssHooks[t]={get:function(e,n,r){return n?0===e.offsetWidth&&xt.test(x.css(e,"display"))?x.swap(e,Nt,function(){return Ft(e,t,r)}):Ft(e,t,r):undefined},set:function(e,n,r){var i=r&&Lt(e);return Ht(e,n,r?Ot(e,t,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,t){return t?x.swap(e,{display:"inline-block"},yt,[e,"marginRight"]):undefined}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,t){x.cssHooks[t]={get:function(e,n){return n?(n=yt(e,t),Tt.test(n)?x(e).position()[t]+"px":n):undefined}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+St[r]+t]=o[r]||o[r-2]||o[0];return i}},bt.test(e)||(x.cssHooks[e+t].set=Ht)});var Mt=/%20/g,Wt=/\[\]$/,$t=/\r?\n/g,Bt=/^(?:submit|button|image|reset|file)$/i,It=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&It.test(this.nodeName)&&!Bt.test(e)&&(this.checked||!it.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace($t,"\r\n")}}):{name:t.name,value:n.replace($t,"\r\n")}}).get()}}),x.param=function(e,t){var n,r=[],i=function(e,t){t=x.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(t===undefined&&(t=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){i(this.name,this.value)});else for(n in e)zt(n,e[n],t,i);return r.join("&").replace(Mt,"+")};function zt(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||Wt.test(e)?r(e,i):zt(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)zt(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var _t,Xt,Ut=x.now(),Yt=/\?/,Vt=/#.*$/,Gt=/([?&])_=[^&]*/,Jt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Qt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Kt=/^(?:GET|HEAD)$/,Zt=/^\/\//,en=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,tn=x.fn.load,nn={},rn={},on="*/".concat("*");try{Xt=i.href}catch(sn){Xt=o.createElement("a"),Xt.href="",Xt=Xt.href}_t=en.exec(Xt.toLowerCase())||[];function an(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[]; +if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function un(e,t,n,r){var i={},o=e===rn;function s(a){var u;return i[a]=!0,x.each(e[a]||[],function(e,a){var l=a(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):undefined:(t.dataTypes.unshift(l),s(l),!1)}),u}return s(t.dataTypes[0])||!i["*"]&&s("*")}function ln(e,t){var n,r,i=x.ajaxSettings.flatOptions||{};for(n in t)t[n]!==undefined&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,t,n){if("string"!=typeof e&&tn)return tn.apply(this,arguments);var r,i,o,s=this,a=e.indexOf(" ");return a>=0&&(r=e.slice(a),e=e.slice(0,a)),x.isFunction(t)?(n=t,t=undefined):t&&"object"==typeof t&&(i="POST"),s.length>0&&x.ajax({url:e,type:i,dataType:"html",data:t}).done(function(e){o=arguments,s.html(r?x("<div>").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Xt,type:"GET",isLocal:Qt.test(_t[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":on,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ln(ln(e,x.ajaxSettings),t):ln(x.ajaxSettings,e)},ajaxPrefilter:an(nn),ajaxTransport:an(rn),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),f=c.context||c,p=c.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Jt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Xt)+"").replace(Vt,"").replace(Zt,_t[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=en.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===_t[1]&&a[2]===_t[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(_t[3]||("http:"===_t[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),un(nn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Kt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Yt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Gt.test(r)?r.replace(Gt,"$1_="+Ut++):r+(Yt.test(r)?"&":"?")+"_="+Ut++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+on+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(f,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=un(rn,c,t,T)){T.readyState=1,u&&p.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=cn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(f,[m,C,T]):h.rejectWith(f,[T,C,y]),T.statusCode(g),g=undefined,u&&p.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(f,[T,C]),u&&(p.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function cn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(f){return{state:"parsererror",error:s?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("<script>").prop({async:!0,charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),o.head.appendChild(t[0])},abort:function(){n&&n()}}}});var pn=[],hn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=pn.pop()||x.expando+"_"+Ut++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,s,a=t.jsonp!==!1&&(hn.test(t.url)?"url":"string"==typeof t.data&&!(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&hn.test(t.data)&&"data");return a||"jsonp"===t.dataTypes[0]?(i=t.jsonpCallback=x.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,a?t[a]=t[a].replace(hn,"$1"+i):t.jsonp!==!1&&(t.url+=(Yt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return s||x.error(i+" was not called"),s[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){s=arguments},r.always(function(){e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,pn.push(i)),s&&x.isFunction(o)&&o(s[0]),s=o=undefined}),"script"):undefined}),x.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(e){}};var dn=x.ajaxSettings.xhr(),gn={0:200,1223:204},mn=0,yn={};e.ActiveXObject&&x(e).on("unload",function(){for(var e in yn)yn[e]();yn=undefined}),x.support.cors=!!dn&&"withCredentials"in dn,x.support.ajax=dn=!!dn,x.ajaxTransport(function(e){var t;return x.support.cors||dn&&!e.crossDomain?{send:function(n,r){var i,o,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(i in e.xhrFields)s[i]=e.xhrFields[i];e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||n["X-Requested-With"]||(n["X-Requested-With"]="XMLHttpRequest");for(i in n)s.setRequestHeader(i,n[i]);t=function(e){return function(){t&&(delete yn[o],t=s.onload=s.onerror=null,"abort"===e?s.abort():"error"===e?r(s.status||404,s.statusText):r(gn[s.status]||s.status,s.statusText,"string"==typeof s.responseText?{text:s.responseText}:undefined,s.getAllResponseHeaders()))}},s.onload=t(),s.onerror=t("error"),t=yn[o=mn++]=t("abort"),s.send(e.hasContent&&e.data||null)},abort:function(){t&&t()}}:undefined});var vn,xn,bn=/^(?:toggle|show|hide)$/,wn=RegExp("^(?:([+-])=|)("+b+")([a-z%]*)$","i"),Tn=/queueHooks$/,Cn=[Dn],kn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=wn.exec(t),s=i.cur(),a=+s||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(x.cssNumber[e]?"":"px"),"px"!==r&&a){a=x.css(i.elem,e,!0)||n||1;do u=u||".5",a/=u,x.style(i.elem,e,a+r);while(u!==(u=i.cur()/s)&&1!==u&&--l)}i.unit=r,i.start=a,i.end=o[1]?a+(o[1]+1)*n:n}return i}]};function Nn(){return setTimeout(function(){vn=undefined}),vn=x.now()}function En(e,t){x.each(t,function(t,n){var r=(kn[t]||[]).concat(kn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function Sn(e,t,n){var r,i,o=0,s=Cn.length,a=x.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=vn||Nn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,s=0,u=l.tweens.length;for(;u>s;s++)l.tweens[s].run(o);return a.notifyWith(e,[l,o,n]),1>o&&u?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:vn||Nn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),c=l.props;for(jn(c,l.opts.specialEasing);s>o;o++)if(r=Cn[o].call(l,e,c,l.opts))return r;return En(l,c),x.isFunction(l.opts.start)&&l.opts.start.call(e,l),x.fx.timer(x.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function jn(e,t){var n,r,i,o,s;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),s=x.cssHooks[r],s&&"expand"in s){o=s.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(Sn,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],kn[n]=kn[n]||[],kn[n].unshift(t)},prefilter:function(e,t){t?Cn.unshift(e):Cn.push(e)}});function Dn(e,t,n){var r,i,o,s,a,u,l,c,f,p=this,h=e.style,d={},g=[],m=e.nodeType&&At(e);n.queue||(c=x._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,f=c.empty.fire,c.empty.fire=function(){c.unqueued||f()}),c.unqueued++,p.always(function(){p.always(function(){c.unqueued--,x.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),a=q.get(e,"fxshow");for(r in t)if(o=t[r],bn.exec(o)){if(delete t[r],u=u||"toggle"===o,o===(m?"hide":"show")){if("show"!==o||a===undefined||a[r]===undefined)continue;m=!0}g.push(r)}if(s=g.length){a=q.get(e,"fxshow")||q.access(e,"fxshow",{}),"hidden"in a&&(m=a.hidden),u&&(a.hidden=!m),m?x(e).show():p.done(function(){x(e).hide()}),p.done(function(){var t;q.remove(e,"fxshow");for(t in d)x.style(e,t,d[t])});for(r=0;s>r;r++)i=g[r],l=p.createTween(i,m?a[i]:0),d[i]=a[i]||x.style(e,i),i in a||(a[i]=l.start,m&&(l.end=l.start,l.start="width"===i||"height"===i?1:0))}}function An(e,t,n,r,i){return new An.prototype.init(e,t,n,r,i)}x.Tween=An,An.prototype={constructor:An,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=An.propHooks[this.prop];return e&&e.get?e.get(this):An.propHooks._default.get(this)},run:function(e){var t,n=An.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):An.propHooks._default.set(this),this}},An.prototype.init.prototype=An.prototype,An.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},An.propHooks.scrollTop=An.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(Ln(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(At).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),s=function(){var t=Sn(this,x.extend({},e),o);s.finish=function(){t.stop(!0)},(i||q.get(this,"finish"))&&t.stop(!0)};return s.finish=s,i||o.queue===!1?this.each(s):this.queue(o.queue,s)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=undefined),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=x.timers,s=q.get(this);if(i)s[i]&&s[i].stop&&r(s[i]);else for(i in s)s[i]&&s[i].stop&&Tn.test(i)&&r(s[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));(t||!n)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=q.get(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,s=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;s>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function Ln(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=St[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:Ln("show"),slideUp:Ln("hide"),slideToggle:Ln("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=An.prototype.init,x.fx.tick=function(){var e,t=x.timers,n=0;for(vn=x.now();t.length>n;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||x.fx.stop(),vn=undefined},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){xn||(xn=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(xn),xn=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===undefined?this:this.each(function(t){x.offset.setOffset(this,e,t)});var t,n,i=this[0],o={top:0,left:0},s=i&&i.ownerDocument;if(s)return t=s.documentElement,x.contains(t,i)?(typeof i.getBoundingClientRect!==r&&(o=i.getBoundingClientRect()),n=qn(s),{top:o.top+n.pageYOffset-t.clientTop,left:o.left+n.pageXOffset-t.clientLeft}):o},x.offset={setOffset:function(e,t,n){var r,i,o,s,a,u,l,c=x.css(e,"position"),f=x(e),p={};"static"===c&&(e.style.position="relative"),a=f.offset(),o=x.css(e,"top"),u=x.css(e,"left"),l=("absolute"===c||"fixed"===c)&&(o+u).indexOf("auto")>-1,l?(r=f.position(),s=r.top,i=r.left):(s=parseFloat(o)||0,i=parseFloat(u)||0),x.isFunction(t)&&(t=t.call(e,n,a)),null!=t.top&&(p.top=t.top-a.top+s),null!=t.left&&(p.left=t.left-a.left+i),"using"in t?t.using.call(e,p):f.css(p)}},x.fn.extend({position:function(){if(this[0]){var e,t,n=this[0],r={top:0,left:0};return"fixed"===x.css(n,"position")?t=n.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(r=e.offset()),r.top+=x.css(e[0],"borderTopWidth",!0),r.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-r.top-x.css(n,"marginTop",!0),left:t.left-r.left-x.css(n,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,n){var r="pageYOffset"===n;x.fn[t]=function(i){return x.access(this,function(t,i,o){var s=qn(t);return o===undefined?s?s[n]:t[i]:(s?s.scrollTo(r?e.pageXOffset:o,r?o:e.pageYOffset):t[i]=o,undefined)},t,i,arguments.length,null)}});function qn(e){return x.isWindow(e)?e:9===e.nodeType&&e.defaultView}x.each({Height:"height",Width:"width"},function(e,t){x.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){x.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),s=n||(r===!0||i===!0?"margin":"border");return x.access(this,function(t,n,r){var i;return x.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):r===undefined?x.css(t,n,s):x.style(t,n,r,s)},t,o?r:undefined,o,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&"object"==typeof module.exports?module.exports=x:"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}),"object"==typeof e&&"object"==typeof e.document&&(e.jQuery=e.$=x)})(window); \ No newline at end of file diff --git a/hyhproject/admin/view/js/license.js b/hyhproject/admin/view/js/license.js new file mode 100755 index 0000000..a59ceb5 --- /dev/null +++ b/hyhproject/admin/view/js/license.js @@ -0,0 +1,19 @@ +function edit(){ + var params = {}; + params.license = $('#license').val(); + $('#licenseTr').hide(); + $('#editFrom').isValid(function(v){ + if(v){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/index/verifyLicense'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1' && json.license){ + $('#licenseTr').show(); + $('#licenseStatus').html(json.license.licenseStatus); + }else{ + WST.msg("授权码验证失败",{icon:1}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/js/core/base.js b/hyhproject/admin/view/js/ligerui/js/core/base.js new file mode 100755 index 0000000..2d4556a --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/js/core/base.js @@ -0,0 +1,1290 @@ +/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + //ligerui 继承方法 + Function.prototype.ligerExtend = function (parent, overrides) + { + if (typeof parent != 'function') return this; + //保存对父类的引用 + this.base = parent.prototype; + this.base.constructor = parent; + //继承 + var f = function () { }; + f.prototype = parent.prototype; + this.prototype = new f(); + this.prototype.constructor = this; + //附加属性方法 + if (overrides) $.extend(this.prototype, overrides); + }; + //延时加载 + Function.prototype.ligerDefer = function (o, defer, args) + { + var fn = this; + return setTimeout(function () { fn.apply(o, args || []); }, defer); + }; + + // 核心对象 + window.liger = $.ligerui = { + version: 'V1.3.2', + managerCount: 0, + //组件管理器池 + managers: {}, + managerIdPrev: 'ligerui', + //管理器id已经存在时自动创建新的 + autoNewId: true, + //错误提示 + error: { + managerIsExist: '管理器id已经存在' + }, + pluginPrev: 'liger', + attrPrev:'data', + getId: function (prev) + { + prev = prev || this.managerIdPrev; + var id = prev + (1000 + this.managerCount); + this.managerCount++; + return id; + }, + add: function (manager) + { + if (arguments.length == 2) + { + var m = arguments[1]; + m.id = m.id || m.options.id || arguments[0].id; + this.addManager(m); + return; + } + if (!manager.id) manager.id = this.getId(manager.__idPrev()); + //if (this.managers[manager.id]) manager.id = this.getId(manager.__idPrev()); + //if (this.managers[manager.id]) + //{ + // throw new Error(this.error.managerIsExist); + //} + this.managers[manager.id] = manager; + }, + remove: function (arg) + { + if (typeof arg == "string" || typeof arg == "number") + { + delete liger.managers[arg]; + } + else if (typeof arg == "object") + { + if (arg instanceof liger.core.Component) + { + delete liger.managers[arg.id]; + } + else + { + if (!$(arg).attr(this.idAttrName)) return false; + delete liger.managers[$(arg).attr(this.idAttrName)]; + } + } + + }, + //获取ligerui对象 + //1,传入ligerui ID + //2,传入Dom Object + get: function (arg, idAttrName) + { + idAttrName = idAttrName || "ligeruiid"; + if (typeof arg == "string" || typeof arg == "number") + { + return liger.managers[arg]; + } + else if (typeof arg == "object") + { + var domObj = arg.length ? arg[0] : arg; + var id = domObj[idAttrName] || $(domObj).attr(idAttrName); + if (!id) return null; + return liger.managers[id]; + } + return null; + }, + //根据类型查找某一个对象 + find: function (type) + { + var arr = []; + for (var id in this.managers) + { + var manager = this.managers[id]; + if (type instanceof Function) + { + if (manager instanceof type) + { + arr.push(manager); + } + } + else if (type instanceof Array) + { + if ($.inArray(manager.__getType(), type) != -1) + { + arr.push(manager); + } + } + else + { + if (manager.__getType() == type) + { + arr.push(manager); + } + } + } + return arr; + }, + //$.fn.liger{Plugin} 和 $.fn.ligerGet{Plugin}Manager + //会调用这个方法,并传入作用域(this) + //parm [plugin] 插件名 + //parm [args] 参数(数组) + //parm [ext] 扩展参数,定义命名空间或者id属性名 + run: function (plugin, args, ext) + { + if (!plugin) return; + ext = $.extend({ + defaultsNamespace: 'ligerDefaults', + methodsNamespace: 'ligerMethods', + controlNamespace: 'controls', + idAttrName: 'ligeruiid', + isStatic: false, + hasElement: true, //是否拥有element主体(比如drag、resizable等辅助性插件就不拥有) + propertyToElemnt: null //链接到element的属性名 + }, ext || {}); + plugin = plugin.replace(/^ligerGet/, ''); + plugin = plugin.replace(/^liger/, ''); + if (this == null || this == window || ext.isStatic) + { + if (!liger.plugins[plugin]) + { + liger.plugins[plugin] = { + fn: $[liger.pluginPrev + plugin], + isStatic: true + }; + } + return new $.ligerui[ext.controlNamespace][plugin]($.extend({}, $[ext.defaultsNamespace][plugin] || {}, $[ext.defaultsNamespace][plugin + 'String'] || {}, args.length > 0 ? args[0] : {})); + } + if (!liger.plugins[plugin]) + { + liger.plugins[plugin] = { + fn: $.fn[liger.pluginPrev + plugin], + isStatic: false + }; + } + if (/Manager$/.test(plugin)) return liger.get(this, ext.idAttrName); + this.each(function () + { + if (this[ext.idAttrName] || $(this).attr(ext.idAttrName)) + { + var manager = liger.get(this[ext.idAttrName] || $(this).attr(ext.idAttrName)); + if (manager && args.length > 0) manager.set(args[0]); + //已经执行过 + return; + } + if (args.length >= 1 && typeof args[0] == 'string') return; + //只要第一个参数不是string类型,都执行组件的实例化工作 + var options = args.length > 0 ? args[0] : null; + var p = $.extend({}, $[ext.defaultsNamespace][plugin], $[ext.defaultsNamespace][plugin + 'String'], options); + if (ext.propertyToElemnt) p[ext.propertyToElemnt] = this; + if (ext.hasElement) + { + new $.ligerui[ext.controlNamespace][plugin](this, p); + } + else + { + new $.ligerui[ext.controlNamespace][plugin](p); + } + }); + if (this.length == 0) return null; + if (args.length == 0) return liger.get(this, ext.idAttrName); + if (typeof args[0] == 'object') return liger.get(this, ext.idAttrName); + if (typeof args[0] == 'string') + { + var manager = liger.get(this, ext.idAttrName); + if (manager == null) return; + if (args[0] == "option") + { + if (args.length == 2) + return manager.get(args[1]); //manager get + else if (args.length >= 3) + return manager.set(args[1], args[2]); //manager set + } + else + { + var method = args[0]; + if (!manager[method]) return; //不存在这个方法 + var parms = Array.apply(null, args); + parms.shift(); + return manager[method].apply(manager, parms); //manager method + } + } + return null; + }, + + //扩展 + //1,默认参数 + //2,本地化扩展 + defaults: {}, + //3,方法接口扩展 + methods: {}, + //命名空间 + //核心控件,封装了一些常用方法 + core: {}, + //命名空间 + //组件的集合 + controls: {}, + //plugin 插件的集合 + plugins: {} + }; + + + //扩展对象 + $.ligerDefaults = {}; + + //扩展对象 + $.ligerMethos = {}; + + //关联起来 + liger.defaults = $.ligerDefaults; + liger.methods = $.ligerMethos; + + //获取ligerui对象 + //parm [plugin] 插件名,可为空 + $.fn.liger = function (plugin) + { + if (plugin) + { + return liger.run.call(this, plugin, arguments); + } + else + { + return liger.get(this); + } + }; + + + //组件基类 + //1,完成定义参数处理方法和参数属性初始化的工作 + //2,完成定义事件处理方法和事件属性初始化的工作 + liger.core.Component = function (options) + { + //事件容器 + this.events = this.events || {}; + //配置参数 + this.options = options || {}; + //子组件集合索引 + this.children = {}; + }; + $.extend(liger.core.Component.prototype, { + __getType: function () + { + return 'liger.core.Component'; + }, + __idPrev: function () + { + return 'ligerui'; + }, + + //设置属性 + // arg 属性名 value 属性值 + // arg 属性/值 value 是否只设置事件 + set: function (arg, value,value2) + { + if (!arg) return; + if (typeof arg == 'object') + { + var tmp; + if (this.options != arg) + { + $.extend(this.options, arg); + tmp = arg; + } + else + { + tmp = $.extend({}, arg); + } + if (value == undefined || value == true) + { + for (var p in tmp) + { + if (p.indexOf('on') == 0) + this.set(p, tmp[p]); + } + } + if (value == undefined || value == false) + { + for (var p in tmp) + { + if (p.indexOf('on') != 0) + this.set(p, tmp[p], value2); + } + } + return; + } + var name = arg; + //事件参数 + if (name.indexOf('on') == 0) + { + if (typeof value == 'function') + this.bind(name.substr(2), value); + return; + } + if (!this.options) this.options = {}; + if (this.trigger('propertychange', [arg, value]) == false) return; + this.options[name] = value; + var pn = '_set' + name.substr(0, 1).toUpperCase() + name.substr(1); + if (this[pn]) + { + this[pn].call(this, value, value2); + } + this.trigger('propertychanged', [arg, value]); + }, + + //获取属性 + get: function (name) + { + var pn = '_get' + name.substr(0, 1).toUpperCase() + name.substr(1); + if (this[pn]) + { + return this[pn].call(this, name); + } + return this.options[name]; + }, + + hasBind: function (arg) + { + var name = arg.toLowerCase(); + var event = this.events[name]; + if (event && event.length) return true; + return false; + }, + + //触发事件 + //data (可选) Array(可选)传递给事件处理函数的附加参数 + trigger: function (arg, data) + { + if (!arg) return; + var name = arg.toLowerCase(); + var event = this.events[name]; + if (!event) return; + data = data || []; + if ((data instanceof Array) == false) + { + data = [data]; + } + for (var i = 0; i < event.length; i++) + { + var ev = event[i]; + if (ev.handler.apply(ev.context, data) == false) + return false; + } + }, + + //绑定事件 + bind: function (arg, handler, context) + { + if (typeof arg == 'object') + { + for (var p in arg) + { + this.bind(p, arg[p]); + } + return; + } + if (typeof handler != 'function') return false; + var name = arg.toLowerCase(); + var event = this.events[name] || []; + context = context || this; + event.push({ handler: handler, context: context }); + this.events[name] = event; + }, + + //取消绑定 + unbind: function (arg, handler) + { + if (!arg) + { + this.events = {}; + return; + } + var name = arg.toLowerCase(); + var event = this.events[name]; + if (!event || !event.length) return; + if (!handler) + { + delete this.events[name]; + } + else + { + for (var i = 0, l = event.length; i < l; i++) + { + if (event[i].handler == handler) + { + event.splice(i, 1); + break; + } + } + } + }, + destroy: function () + { + liger.remove(this); + } + }); + + + //界面组件基类, + //1,完成界面初始化:设置组件id并存入组件管理器池,初始化参数 + //2,渲染的工作,细节交给子类实现 + //parm [element] 组件对应的dom element对象 + //parm [options] 组件的参数 + liger.core.UIComponent = function (element, options) + { + liger.core.UIComponent.base.constructor.call(this, options); + var extendMethods = this._extendMethods(); + if (extendMethods) $.extend(this, extendMethods); + this.element = element; + this._init(); + this._preRender(); + this.trigger('render'); + this._render(); + this.trigger('rendered'); + this._rendered(); + }; + liger.core.UIComponent.ligerExtend(liger.core.Component, { + __getType: function () + { + return 'liger.core.UIComponent'; + }, + //扩展方法 + _extendMethods: function () + { + + }, + _init: function () + { + this.type = this.__getType(); + if (!this.element) + { + this.id = this.options.id || liger.getId(this.__idPrev()); + } + else + { + this.id = this.options.id || this.element.id || liger.getId(this.__idPrev()); + } + //存入管理器池 + liger.add(this); + + if (!this.element) return; + + //读取attr方法,并加载到参数,比如['url'] + var attributes = this.attr(); + if (attributes && attributes instanceof Array) + { + for (var i = 0; i < attributes.length; i++) + { + var name = attributes[i]; + if ($(this.element).attr(name)) + { + this.options[name] = $(this.element).attr(name); + } + } + } + //读取ligerui这个属性,并加载到参数,比如 ligerui = "width:120,heigth:100" + var p = this.options; + if ($(this.element).attr("ligerui")) + { + try + { + var attroptions = $(this.element).attr("ligerui"); + if (attroptions.indexOf('{') != 0) attroptions = "{" + attroptions + "}"; + eval("attroptions = " + attroptions + ";"); + if (attroptions) $.extend(p, attroptions); + } + catch (e) { } + } + + //v1.3.2增加 从data-XX 加载属性 + function loadDataOp(control, jelement) + { + var op = {}; + if (!control || control.indexOf('.') != -1) return op; + var defaultOp = liger.defaults[control]; + if (!defaultOp) return op; + for (var name in defaultOp) + { + if (jelement.attr(liger.attrPrev + "-" + name)) + { + var value = jelement.attr(liger.attrPrev + "-" + name); + if (typeof (defaultOp[name]) == "boolean") + { + op[name] = value == "true" || value == "1"; + } else + { + op[name] = value; + } + } + } + return op; + } + + $.extend(p, loadDataOp(this.__getType(), $(this.element))); + + }, + //预渲染,可以用于继承扩展 + _preRender: function () + { + + }, + _render: function () + { + + }, + _rendered: function () + { + if (this.element) + { + $(this.element).attr("ligeruiid", this.id); + } + }, + _setCls: function (value) + { + if (this.element && value) + { + $(this.element).addClass(value); + } + }, + //返回要转换成ligerui参数的属性,比如['url'] + attr: function () + { + return []; + }, + destroy: function () + { + if (this.element) + { + $(this.element).remove(); + } + this.options = null; + liger.remove(this); + } + }); + + + //表单控件基类 + liger.controls.Input = function (element, options) + { + liger.controls.Input.base.constructor.call(this, element, options); + }; + + liger.controls.Input.ligerExtend(liger.core.UIComponent, { + __getType: function () + { + return 'liger.controls.Input'; + }, + attr: function () + { + return ['nullText']; + }, + setValue: function (value) + { + return this.set('value', value); + }, + getValue: function () + { + return this.get('value'); + }, + //设置只读 + _setReadonly: function (readonly) + { + var wrapper = this.wrapper || this.text; + if (!wrapper || !wrapper.hasClass("l-text")) return; + var inputText = this.inputText; + if (readonly) + { + if (inputText) inputText.attr("readonly", "readonly"); + wrapper.addClass("l-text-readonly"); + } else + { + if (inputText) inputText.removeAttr("readonly"); + wrapper.removeClass("l-text-readonly"); + } + }, + setReadonly: function (readonly) + { + return this.set('readonly', readonly); + }, + setEnabled: function () + { + return this.set('disabled', false); + }, + setDisabled: function () + { + return this.set('disabled', true); + }, + updateStyle: function () + { + + }, + resize: function (width, height) + { + this.set({ width: width, height: height + 2 }); + } + }); + + //全局窗口对象 + liger.win = { + //顶端显示 + top: false, + + //遮罩 + mask: function (win) + { + function setHeight() + { + if (!liger.win.windowMask) return; + var h = $(window).height() + $(window).scrollTop(); + liger.win.windowMask.height(h); + } + if (!this.windowMask) + { + this.windowMask = $("<div class='l-window-mask' style='display: block;'></div>").appendTo('body'); + $(window).bind('resize.ligeruiwin', setHeight); + $(window).bind('scroll', setHeight); + } + this.windowMask.show(); + setHeight(); + this.masking = true; + }, + + //取消遮罩 + unmask: function (win) + { + var jwins = $("body > .l-dialog:visible,body > .l-window:visible"); + for (var i = 0, l = jwins.length; i < l; i++) + { + var winid = jwins.eq(i).attr("ligeruiid"); + if (win && win.id == winid) continue; + //获取ligerui对象 + var winmanager = liger.get(winid); + if (!winmanager) continue; + //是否模态窗口 + var modal = winmanager.get('modal'); + //如果存在其他模态窗口,那么不会取消遮罩 + if (modal) return; + } + if (this.windowMask) + this.windowMask.hide(); + this.masking = false; + }, + + //显示任务栏 + createTaskbar: function () + { + if (!this.taskbar) + { + this.taskbar = $('<div class="l-taskbar"><div class="l-taskbar-tasks"></div><div class="l-clear"></div></div>').appendTo('body'); + if (this.top) this.taskbar.addClass("l-taskbar-top"); + this.taskbar.tasks = $(".l-taskbar-tasks:first", this.taskbar); + this.tasks = {}; + } + this.taskbar.show(); + this.taskbar.animate({ bottom: 0 }); + return this.taskbar; + }, + + //关闭任务栏 + removeTaskbar: function () + { + var self = this; + self.taskbar.animate({ bottom: -32 }, function () + { + self.taskbar.remove(); + self.taskbar = null; + }); + }, + activeTask: function (win) + { + for (var winid in this.tasks) + { + var t = this.tasks[winid]; + if (winid == win.id) + { + t.addClass("l-taskbar-task-active"); + } + else + { + t.removeClass("l-taskbar-task-active"); + } + } + }, + + //获取任务 + getTask: function (win) + { + var self = this; + if (!self.taskbar) return; + if (self.tasks[win.id]) return self.tasks[win.id]; + return null; + }, + + + //增加任务 + addTask: function (win) + { + var self = this; + if (!self.taskbar) self.createTaskbar(); + if (self.tasks[win.id]) return self.tasks[win.id]; + var title = win.get('title'); + var task = self.tasks[win.id] = $('<div class="l-taskbar-task"><div class="l-taskbar-task-icon"></div><div class="l-taskbar-task-content">' + title + '</div></div>'); + self.taskbar.tasks.append(task); + self.activeTask(win); + task.bind('click', function () + { + self.activeTask(win); + if (win.actived) + win.min(); + else + win.active(); + }).hover(function () + { + $(this).addClass("l-taskbar-task-over"); + }, function () + { + $(this).removeClass("l-taskbar-task-over"); + }); + return task; + }, + + hasTask: function () + { + for (var p in this.tasks) + { + if (this.tasks[p]) + return true; + } + return false; + }, + + //移除任务 + removeTask: function (win) + { + var self = this; + if (!self.taskbar) return; + if (self.tasks[win.id]) + { + self.tasks[win.id].unbind(); + self.tasks[win.id].remove(); + delete self.tasks[win.id]; + } + if (!self.hasTask()) + { + self.removeTaskbar(); + } + }, + + //前端显示 + setFront: function (win) + { + var wins = liger.find(liger.core.Win); + for (var i in wins) + { + var w = wins[i]; + if (w == win) + { + $(w.element).css("z-index", "9200"); + this.activeTask(w); + } + else + { + $(w.element).css("z-index", "9100"); + } + } + } + }; + + + //窗口基类 window、dialog + liger.core.Win = function (element, options) + { + liger.core.Win.base.constructor.call(this, element, options); + }; + + liger.core.Win.ligerExtend(liger.core.UIComponent, { + __getType: function () + { + return 'liger.controls.Win'; + }, + mask: function () + { + if (this.options.modal) + liger.win.mask(this); + }, + unmask: function () + { + if (this.options.modal) + liger.win.unmask(this); + }, + min: function () + { + }, + max: function () + { + }, + active: function () + { + } + }); + + + liger.draggable = { + dragging: false + }; + + liger.resizable = { + reszing: false + }; + + + liger.toJSON = typeof JSON === 'object' && JSON.stringify ? JSON.stringify : function (o) + { + var f = function (n) + { + return n < 10 ? '0' + n : n; + }, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + quote = function (value) + { + escapable.lastIndex = 0; + return escapable.test(value) ? + '"' + value.replace(escapable, function (a) + { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + value + '"'; + }; + if (o === null) return 'null'; + var type = typeof o; + if (type === 'undefined') return undefined; + if (type === 'string') return quote(o); + if (type === 'number' || type === 'boolean') return '' + o; + if (type === 'object') + { + if (typeof o.toJSON === 'function') + { + return liger.toJSON(o.toJSON()); + } + if (o.constructor === Date) + { + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + } + var pairs = []; + if (o.constructor === Array) + { + for (var i = 0, l = o.length; i < l; i++) + { + pairs.push(liger.toJSON(o[i]) || 'null'); + } + return '[' + pairs.join(',') + ']'; + } + var name, val; + for (var k in o) + { + type = typeof k; + if (type === 'number') + { + name = '"' + k + '"'; + } else if (type === 'string') + { + name = quote(k); + } else + { + continue; + } + type = typeof o[k]; + if (type === 'function' || type === 'undefined') + { + continue; + } + val = liger.toJSON(o[k]); + pairs.push(name + ':' + val); + } + return '{' + pairs.join(',') + '}'; + } + }; + + //获取 默认的编辑构造器 + liger.getEditor = function (e) + { + var type = e.type, control = e.control, master = e.master; + if (!type) return null; + var inputTag = 0; + if (control) control = control.substr(0, 1).toUpperCase() + control.substr(1); + var defaultOp = { + create: function (container, editParm, controlOptions) + { + //field in form , column in grid + var field = editParm.field || editParm.column, options = controlOptions || {}; + var isInGrid = editParm.column ? true : false; + var p = $.extend({}, e.options); + var inputType = "text"; + if ($.inArray(type, ["password", "file", "checkbox", "radio"]) != -1) inputType = type; + if (e.password) inputType = "password"; + var inputBody = $("<input type='" + inputType + "'/>"); + if (e.body) + { + inputBody = e.body.clone(); + } + inputBody.appendTo(container); + if (editParm.field) + { + var txtInputName = field.name; + var prefixID = $.isFunction(options.prefixID) ? options.prefixID(master) : (options.prefixID || ""); + p.id = field.id || (prefixID + field.name); + if ($.inArray(type, ["select", "combobox", "autocomplete", "popup"]) != -1) + { + txtInputName = field.textField || field.comboboxName; + if (field.comboboxName && !field.id) + p.id = (options.prefixID || "") + field.comboboxName; + } + if ($.inArray(type, ["select", "combobox", "autocomplete", "popup", "radiolist", "checkboxlist", "listbox"]) != -1) + { + p.valueFieldID = prefixID + field.name; + } + if (!e.body) + { + var inputName = prefixID + txtInputName; + var inputId = new Date().getTime() + "_" + ++inputTag + "_" + field.name; + inputBody.attr($.extend({ + id: inputId, + name: inputName + }, field.attr)); + if (field.cssClass) + { + inputBody.addClass(field.cssClass); + } + if (field.validate && !master.options.unSetValidateAttr) + { + inputBody.attr('validate', liger.toJSON(field.validate)); + } + } + $.extend(p, field.options); + } + if (field.dictionary) //字典字段,比如:男|女 + { + field.editor = field.editor || {}; + if (!field.editor.data) + { + var dicEditorData = [], dicItems = field.dictionary.split('|'); + $(dicItems).each(function (i, dicItem) + { + var dics = dicItem.split(','); + var dicItemId = dics[0], dicItemText = dics.length >= 2 ? dics[1] : dics[0]; + dicEditorData.push({ + id: dicItemId, + value: dicItemId, + text: dicItemText + }); + }); + field.editor.data = dicEditorData; + } + } + if (field.editor) + { + if (field.editor.options) + { + $.extend(p, field.editor.options); + delete field.editor.options; + } + if (field.editor.valueColumnName) + { + p.valueField = field.editor.valueColumnName; + delete field.editor.valueColumnName; + } + if (field.editor.displayColumnName) + { + p.textField = field.editor.displayColumnName; + delete field.editor.displayColumnName; + } + //可扩展参数,支持动态加载 + var ext = field.editor.p || field.editor.ext; + if (ext) + { + ext = typeof (ext) == 'function' ? ext(editParm) : ext; + $.extend(p, ext); + delete field.editor.p; + delete field.editor.ext; + } + $.extend(p, field.editor); + } + + if (isInGrid) + { + p.host_grid = this; + p.host_grid_row = editParm.record; + p.host_grid_column = editParm.column; + } else + { + p.host_form = this; + + if (field.readonly || p.host_form.get('readonly')) + { + p.readonly = true; + } + } + //返回的是ligerui对象 + var lobj = inputBody['liger' + control](p); + if (isInGrid) + { + setTimeout(function () { inputBody.focus(); }, 100); + } + return lobj; + }, + getValue: function (editor, editParm) + { + var field = editParm.field || editParm.column; + if (editor.getValue) + { + var value = editor.getValue(); + var edtirType = editParm.column ? editParm.column.editor.type : editParm.field.type; + //isArrayValue属性可将提交字段数据改成[id1,id2,id3]的形式 + if (field && field.editor && field.editor.isArrayValue && value) + { + value = value.split(';'); + } + //isRef属性可将提交字段数据改成[id,value]的形式 + if (field && field.editor && field.editor.isRef && editor.getText) + { + value = [value, editor.getText()]; + } + //isRefMul属性可将提交字段数据改成[[id1,value1],[id2,value2]]的形式 + if (field && field.editor && field.editor.isRefMul && editor.getText) + { + var vs = value.split(';'); + var ts = editor.getText().split(';'); + value = []; + for (var i = 0; i < vs.length; i++) + { + value.push([vs[i], ts[i]]); + } + } + if (edtirType == "int" || edtirType == "digits") + { + value = value ? parseInt(value, 10) : 0; + } + else if (edtirType == "float" || edtirType == "number") + { + value = value ? parseFloat(value) : 0; + } + return value; + } + }, + setValue: function (editor, value, editParm) + { + var field = editParm.field || editParm.column; + if (editor.setValue) + { + //设置了isArrayValue属性- 如果获取到的数据是[id1,id2,id3]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isArrayValue && value) + { + value = value.join(';'); + } + //设置了isRef属性-如果获取到的数据是[id,text]的形式,需要获取[0] + if (field && field.editor && field.editor.isRef && $.isArray(value)) + { + value = value[0]; + } + //设置了isRefMul属性- 获取到[[id1,value1],[id2,value2]]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isRefMul && $.isArray(value)) + { + var vs = []; + for (var i = 0; i < value.length; i++) + { + vs.push(value[i].length > 1 ? value[i][1] : value[i][0]); + } + value = vs.join(';'); + } + editor.setValue(value); + } + }, + //从控件获取到文本信息 + getText: function (editor, editParm) + { + var field = editParm.field || editParm.column; + if (editor.getText) + { + var text = editor.getText(); + if (text) return text; + } + }, + //设置文本信息到控件去 + setText: function (editor, text, editParm) + { + if (text && editor.setText) + { + editor.setText(text); + } + //如果没有把数据保存到 textField 字段,那么需要获取值字段 + else + { + var field = editParm.field || editParm.column; + text = editor.setValue() || editParm.value || ""; + //如果获取到的数据是[id,text]的形式,需要获取[0] + if (field && field.editor && field.editor.isRef && $.isArray(text) && text.length > 1) + { + text = text[1]; + } + //在grid的编辑里面 获取到[[id1,value1],[id2,value2]]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isRefMul && $.isArray(text) && text.length > 1) + { + var vs = []; + for (var i = 0; i < text.length; i++) + { + vs.push(text[1]); + } + text = vs.join(';'); + } + if (editor.setText) + { + editor.setText(text); + } + } + }, + getSelected: function (editor, editParm) + { + if (editor.getSelected) + { + return editor.getSelected(); + } + }, + resize: function (editor, width, height, editParm) + { + if (editParm.field) width = width - 2; + if (editor.resize) editor.resize(width, height); + }, + setEnabled: function (editor, isEnabled) + { + if (isEnabled) + { + if (editor.setEnabled) editor.setEnabled(); + } + else + { + if (editor.setDisabled) editor.setDisabled(); + } + }, + destroy: function (editor, editParm) + { + if (editor.destroy) editor.destroy(); + } + }; + + return $.extend({}, defaultOp, liger.editorCreatorDefaults || {}, e); + } + + + //几个默认的编辑器构造函数 + liger.editors = { + "text": { + control: 'TextBox' + }, + "date": { + control: 'DateEditor', + setValue: function (editor, value, editParm) + { + // /Date(1328423451489)/ + if (typeof value == "string" && /^\/Date/.test(value)) + { + value = value.replace(/^\//, "new ").replace(/\/$/, ""); + eval("value = " + value); + } + editor.setValue(value); + } + }, + "combobox": { + control: 'ComboBox' + }, + "spinner": { + control: 'Spinner' + }, + "checkbox": { + control: 'CheckBox' + }, + "checkboxlist": { + control: 'CheckBoxList', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "radiolist": { + control: 'RadioList', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "listbox": { + control: 'ListBox', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "popup": { + control: 'PopupEdit' + }, + "number": { + control: 'TextBox', + options: { number: true } + }, + "currency": { + control: 'TextBox', + options: { currency: true } + }, + "digits": { + control: 'TextBox', + options: { digits: true } + }, + "password": { + control: 'TextBox', + password: true + } + }; + liger.editors["string"] = liger.editors["text"]; + liger.editors["select"] = liger.editors["combobox"]; + liger.editors["int"] = liger.editors["digits"]; + liger.editors["float"] = liger.editors["number"]; + liger.editors["chk"] = liger.editors["checkbox"]; + liger.editors["popupedit"] = liger.editors["popup"]; + + //jQuery version fix + $.fn.live = $.fn.on ? $.fn.on : $.fn.live; + if (!$.browser) + { + var userAgent = navigator.userAgent.toLowerCase(); + $.browser = { + version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1], + safari: /webkit/.test(userAgent), + opera: /opera/.test(userAgent), + msie: /msie/.test(userAgent) && !/opera/.test(userAgent), + mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) + }; + } +})(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/js/core/inject.js b/hyhproject/admin/view/js/ligerui/js/core/inject.js new file mode 100755 index 0000000..cf85ffc --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/js/core/inject.js @@ -0,0 +1,283 @@ +/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + /* + 以html的方式加载组件 + 程序会查询以 liger-插件名 类名的Dom,从dom加载相应的参数并调用插件 + 比如遇到 .liger-grid 的dom,会找到 liger.defaults.Grid 加载需要的参数 + 而在config.Grid中配置了这些参数的类型,会动态得加载data,而columns会设置为数组 + 参数处理的优先级为: + 1,ignores 忽略不处理的参数 + 2,dom存在 {属性名} 的类名 ,比如 <ul class="columns"></ul> ,便会将这个参数设置为复杂属性(object或array):找到相应的defaults和config来加载 + defaults是先找$.liger.inject.defaults,找不到再找liger.defaults的 + config为{父配置}.{属性名},比如 config.Grid.columns + 3,直接读取 data-{属性名} 或者 {属性名} 的dom属性 + */ + liger.inject = { + + prev: 'liger-', + + /* + 命名规则:插件名_属性名(包括第N级的属性) (插件名首字母大写,属性名首字母小写) + 获取规则:获取default时会先找这里,找不到再找liger.defaults,比如 liger.defaults.Grid_columns + 备注:这里只定义了参数的列表 + */ + defaults: { + Grid_detail: { + height: null, + onShowDetail: null + }, + Grid_editor: 'ComboBox,DateEditor,Spinner,TextBox,PopupEdit,CheckBoxList,RadioList,Grid_editor', + Grid_popup: 'PopupEdit', + Grid_grid: 'Grid', + Grid_condition: 'Form', + Grid_toolbar: 'Toolbar', + Grid_fields: 'Form_fields', + Form_editor: 'ComboBox,DateEditor,Spinner,TextBox,PopupEdit,CheckBoxList,RadioList,Form_editor', + Form_grid: 'Grid', + Form_columns: 'Grid_columns', + Form_condition: 'Form', + Form_popup: 'PopupEdit', + Form_buttons: 'Button', + Portal_panel: 'Panel' + }, + /* + config里面配置了某插件参数或者复杂属性参数的类型(动态加载、数组、默认参数) + */ + config: { + Grid: { + //动态 + dynamics: 'data,isChecked,detail,rowDraggingRender,toolbar,columns', + //数组 + arrays: 'columns', + //复杂属性columns + columns: { + dynamics: 'render,totalSummary,headerRender,columns,editor,columns', + arrays: 'columns', + textProperty: 'display', + columns: 'liger.inject.config.Grid.columns', + editor: { + dynamics: 'data,columns,render,renderItem,grid,condition,ext', + grid: 'liger.inject.config.Grid', + condition: 'liger.inject.config.Form' + } + }, + toolbar: { + arrays: 'items' + } + }, + Form: { + dynamics: 'validate,fields,buttons', + arrays: 'fields,buttons', + fields: { + textProperty: 'label', + dynamics: 'validate,editor', + editor: { + dynamics: 'data,columns,render,renderItem,grid,condition,attr', + grid: 'liger.inject.config.Grid', + condition: 'liger.inject.config.Form' + } + }, + buttons: 'liger.inject.config.Button' + }, + PopupEdit: { + dynamics: 'grid,condition' + }, + Button: { + textProperty: 'text', + dynamics: 'click' + }, + ComboBox: { + dynamics: 'columns,data,tree,grid,condition,render,parms,renderItem' + }, + ListBox: { + dynamics: 'columns,data,render,parms' + }, + RadioList: { + dynamics: 'data,parms' + }, + CheckBoxList: { + dynamics: 'data,parms' + }, + Panel: { + }, + Portal: { + //动态 + dynamics: 'rows,columns', + //数组 + arrays: 'rows,columns', + //复杂属性 columns + columns: { + dynamics: 'panels', + arrays: 'panels' + }, + //复杂属性 rows + rows: { + dynamics: 'panels', + arrays: 'panels' + }, + toolbar: { + arrays: 'items' + } + } + }, + + parse: function (code) + { + try + { + if (code == null) return null; + return new Function("return " + code + ";")(); + } catch (e) + { + return null; + } + }, + + parseDefault: function (value) + { + var g = this; + if (!value) return value; + var result = {}; + $(value.split(',')).each(function (index, name) + { + if (!name) return; + name = name.substr(0, 1).toUpperCase() + name.substr(1); + $.extend(result, g.parse("liger.defaults." + name)); + }); + return result; + }, + + fotmatValue: function (value, type) + { + if (type == "boolean") + return value == "true" || value == "1"; + if (type == "number" && value) + return parseFloat(value.toString()); + return value; + }, + + getOptions: function (e) + { + var jelement = e.jelement, defaults = e.defaults, config = e.config; + config = $.extend({ + ignores: "", + dynamics: "", + arrays: "" + }, config); + var g = this, options = {}, value; + if (config.textProperty) options[config.textProperty] = jelement.text(); + for (var proName in defaults) + { + var className = proName.toLowerCase(); + var subElement = $("> ." + className, jelement); + //忽略 + if ($.inArray(proName, config.ignores.split(',')) != -1) continue; + //判断子节点 (复杂属性) + if (subElement.length) + { + var defaultName = e.controlName + "_" + proName; + var subDefaults = g.defaults[defaultName] || liger.defaults[defaultName], subConfig = config[proName]; + if (typeof (subDefaults) == "string") subDefaults = g.parseDefault(subDefaults); + else if (typeof (subDefaults) == "funcion") subDefaults = subDefaults(); + if (typeof (subConfig) == "string") subConfig = g.parse(subConfig); + else if (typeof (subConfig) == "funcion") subConfig = subConfig(); + if (subDefaults) + { + if ($.inArray(proName, config.arrays.split(',')) != -1) + { + value = []; + $(">div,>li,>input", subElement).each(function () + { + value.push(g.getOptions({ + defaults: subDefaults, + controlName: e.controlName, + config: subConfig, + jelement: $(this) + })); + }); + options[proName] = value; + } else + { + options[proName] = g.getOptions({ + defaults: subDefaults, + controlName: e.controlName, + config: subConfig, + jelement: subElement + }); + } + } + subElement.remove(); + } + //动态值 + else if ($.inArray(proName, config.dynamics.split(',')) != -1 || proName.indexOf('on') == 0) + { + value = g.parse(jelement.attr("data-" + proName) || jelement.attr(proName)); + if (value) + { + options[proName] = g.fotmatValue(value, typeof (defaults[proName])); + } + } + //默认处理 + else + { + value = jelement.attr("data-" + proName) || jelement.attr(proName); + if (value) + { + options[proName] = g.fotmatValue(value, typeof (defaults[proName])); + } + } + } + var dataOptions = jelement.attr("data-options") || jelement.attr("data-property"); + if (dataOptions) dataOptions = g.parse("{" + dataOptions + "}"); + if (dataOptions) $.extend(options, dataOptions); + return options; + }, + + init: function () + { + var g = this, configs = this.config; + for (var name in g.defaults) + { + if (typeof (g.defaults[name]) == "string") + { + g.defaults[name] = g.parseDefault(g.defaults[name]); + } + } + for (var controlName in liger.controls) + { + var config = configs[controlName] || {}; + var className = g.prev + controlName.toLowerCase(); + $("." + className).each(function () + { + var jelement = $(this), value; + var defaults = $.extend({ + onrender: null, + onrendered: null + }, liger.defaults[controlName]); + var options = g.getOptions({ + defaults: defaults, + controlName: controlName, + config: config, + jelement: jelement + }); + jelement[liger.pluginPrev + controlName](options); + }); + } + } + + } + + $(function () + { + liger.inject.init(); + }); + +})(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/js/ligerui.all.js b/hyhproject/admin/view/js/ligerui/js/ligerui.all.js new file mode 100755 index 0000000..3c9578d --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/js/ligerui.all.js @@ -0,0 +1,22675 @@ +/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +* vn:00119f3fc12403a05a1ef5609ff96e66 +* +*/ +(function ($) +{ + //ligerui 继承方法 + Function.prototype.ligerExtend = function (parent, overrides) + { + if (typeof parent != 'function') return this; + //保存对父类的引用 + this.base = parent.prototype; + this.base.constructor = parent; + //继承 + var f = function () { }; + f.prototype = parent.prototype; + this.prototype = new f(); + this.prototype.constructor = this; + //附加属性方法 + if (overrides) $.extend(this.prototype, overrides); + }; + //延时加载 + Function.prototype.ligerDefer = function (o, defer, args) + { + var fn = this; + return setTimeout(function () { fn.apply(o, args || []); }, defer); + }; + + // 核心对象 + window.liger = $.ligerui = { + version: 'V1.3.2', + managerCount: 0, + //组件管理器池 + managers: {}, + managerIdPrev: 'ligerui', + //管理器id已经存在时自动创建新的 + autoNewId: true, + //错误提示 + error: { + managerIsExist: '管理器id已经存在' + }, + pluginPrev: 'liger', + attrPrev:'data', + getId: function (prev) + { + prev = prev || this.managerIdPrev; + var id = prev + (1000 + this.managerCount); + this.managerCount++; + return id; + }, + add: function (manager) + { + if (arguments.length == 2) + { + var m = arguments[1]; + m.id = m.id || m.options.id || arguments[0].id; + this.addManager(m); + return; + } + if (!manager.id) manager.id = this.getId(manager.__idPrev()); + //if (this.managers[manager.id]) manager.id = this.getId(manager.__idPrev()); + //if (this.managers[manager.id]) + //{ + // throw new Error(this.error.managerIsExist); + //} + this.managers[manager.id] = manager; + }, + remove: function (arg) + { + if (typeof arg == "string" || typeof arg == "number") + { + delete liger.managers[arg]; + } + else if (typeof arg == "object") + { + if (arg instanceof liger.core.Component) + { + delete liger.managers[arg.id]; + } + else + { + if (!$(arg).attr(this.idAttrName)) return false; + delete liger.managers[$(arg).attr(this.idAttrName)]; + } + } + + }, + //获取ligerui对象 + //1,传入ligerui ID + //2,传入Dom Object + get: function (arg, idAttrName) + { + idAttrName = idAttrName || "ligeruiid"; + if (typeof arg == "string" || typeof arg == "number") + { + return liger.managers[arg]; + } + else if (typeof arg == "object") + { + var domObj = arg.length ? arg[0] : arg; + var id = domObj[idAttrName] || $(domObj).attr(idAttrName); + if (!id) return null; + return liger.managers[id]; + } + return null; + }, + //根据类型查找某一个对象 + find: function (type) + { + var arr = []; + for (var id in this.managers) + { + var manager = this.managers[id]; + if (type instanceof Function) + { + if (manager instanceof type) + { + arr.push(manager); + } + } + else if (type instanceof Array) + { + if ($.inArray(manager.__getType(), type) != -1) + { + arr.push(manager); + } + } + else + { + if (manager.__getType() == type) + { + arr.push(manager); + } + } + } + return arr; + }, + //$.fn.liger{Plugin} 和 $.fn.ligerGet{Plugin}Manager + //会调用这个方法,并传入作用域(this) + //parm [plugin] 插件名 + //parm [args] 参数(数组) + //parm [ext] 扩展参数,定义命名空间或者id属性名 + run: function (plugin, args, ext) + { + if (!plugin) return; + ext = $.extend({ + defaultsNamespace: 'ligerDefaults', + methodsNamespace: 'ligerMethods', + controlNamespace: 'controls', + idAttrName: 'ligeruiid', + isStatic: false, + hasElement: true, //是否拥有element主体(比如drag、resizable等辅助性插件就不拥有) + propertyToElemnt: null //链接到element的属性名 + }, ext || {}); + plugin = plugin.replace(/^ligerGet/, ''); + plugin = plugin.replace(/^liger/, ''); + if (this == null || this == window || ext.isStatic) + { + if (!liger.plugins[plugin]) + { + liger.plugins[plugin] = { + fn: $[liger.pluginPrev + plugin], + isStatic: true + }; + } + return new $.ligerui[ext.controlNamespace][plugin]($.extend({}, $[ext.defaultsNamespace][plugin] || {}, $[ext.defaultsNamespace][plugin + 'String'] || {}, args.length > 0 ? args[0] : {})); + } + if (!liger.plugins[plugin]) + { + liger.plugins[plugin] = { + fn: $.fn[liger.pluginPrev + plugin], + isStatic: false + }; + } + if (/Manager$/.test(plugin)) return liger.get(this, ext.idAttrName); + this.each(function () + { + if (this[ext.idAttrName] || $(this).attr(ext.idAttrName)) + { + var manager = liger.get(this[ext.idAttrName] || $(this).attr(ext.idAttrName)); + if (manager && args.length > 0) manager.set(args[0]); + //已经执行过 + return; + } + if (args.length >= 1 && typeof args[0] == 'string') return; + //只要第一个参数不是string类型,都执行组件的实例化工作 + var options = args.length > 0 ? args[0] : null; + var p = $.extend({}, $[ext.defaultsNamespace][plugin], $[ext.defaultsNamespace][plugin + 'String'], options); + if (ext.propertyToElemnt) p[ext.propertyToElemnt] = this; + if (ext.hasElement) + { + new $.ligerui[ext.controlNamespace][plugin](this, p); + } + else + { + new $.ligerui[ext.controlNamespace][plugin](p); + } + }); + if (this.length == 0) return null; + if (args.length == 0) return liger.get(this, ext.idAttrName); + if (typeof args[0] == 'object') return liger.get(this, ext.idAttrName); + if (typeof args[0] == 'string') + { + var manager = liger.get(this, ext.idAttrName); + if (manager == null) return; + if (args[0] == "option") + { + if (args.length == 2) + return manager.get(args[1]); //manager get + else if (args.length >= 3) + return manager.set(args[1], args[2]); //manager set + } + else + { + var method = args[0]; + if (!manager[method]) return; //不存在这个方法 + var parms = Array.apply(null, args); + parms.shift(); + return manager[method].apply(manager, parms); //manager method + } + } + return null; + }, + + //扩展 + //1,默认参数 + //2,本地化扩展 + defaults: {}, + //3,方法接口扩展 + methods: {}, + //命名空间 + //核心控件,封装了一些常用方法 + core: {}, + //命名空间 + //组件的集合 + controls: {}, + //plugin 插件的集合 + plugins: {} + }; + + + //扩展对象 + $.ligerDefaults = {}; + + //扩展对象 + $.ligerMethos = {}; + + //关联起来 + liger.defaults = $.ligerDefaults; + liger.methods = $.ligerMethos; + + //获取ligerui对象 + //parm [plugin] 插件名,可为空 + $.fn.liger = function (plugin) + { + if (plugin) + { + return liger.run.call(this, plugin, arguments); + } + else + { + return liger.get(this); + } + }; + + + //组件基类 + //1,完成定义参数处理方法和参数属性初始化的工作 + //2,完成定义事件处理方法和事件属性初始化的工作 + liger.core.Component = function (options) + { + //事件容器 + this.events = this.events || {}; + //配置参数 + this.options = options || {}; + //子组件集合索引 + this.children = {}; + }; + $.extend(liger.core.Component.prototype, { + __getType: function () + { + return 'liger.core.Component'; + }, + __idPrev: function () + { + return 'ligerui'; + }, + + //设置属性 + // arg 属性名 value 属性值 + // arg 属性/值 value 是否只设置事件 + set: function (arg, value,value2) + { + if (!arg) return; + if (typeof arg == 'object') + { + var tmp; + if (this.options != arg) + { + $.extend(this.options, arg); + tmp = arg; + } + else + { + tmp = $.extend({}, arg); + } + if (value == undefined || value == true) + { + for (var p in tmp) + { + if (p.indexOf('on') == 0) + this.set(p, tmp[p]); + } + } + if (value == undefined || value == false) + { + for (var p in tmp) + { + if (p.indexOf('on') != 0) + this.set(p, tmp[p], value2); + } + } + return; + } + var name = arg; + //事件参数 + if (name.indexOf('on') == 0) + { + if (typeof value == 'function') + this.bind(name.substr(2), value); + return; + } + if (!this.options) this.options = {}; + if (this.trigger('propertychange', [arg, value]) == false) return; + this.options[name] = value; + var pn = '_set' + name.substr(0, 1).toUpperCase() + name.substr(1); + if (this[pn]) + { + this[pn].call(this, value, value2); + } + this.trigger('propertychanged', [arg, value]); + }, + + //获取属性 + get: function (name) + { + var pn = '_get' + name.substr(0, 1).toUpperCase() + name.substr(1); + if (this[pn]) + { + return this[pn].call(this, name); + } + return this.options[name]; + }, + + hasBind: function (arg) + { + var name = arg.toLowerCase(); + var event = this.events[name]; + if (event && event.length) return true; + return false; + }, + + //触发事件 + //data (可选) Array(可选)传递给事件处理函数的附加参数 + trigger: function (arg, data) + { + if (!arg) return; + var name = arg.toLowerCase(); + var event = this.events[name]; + if (!event) return; + data = data || []; + if ((data instanceof Array) == false) + { + data = [data]; + } + for (var i = 0; i < event.length; i++) + { + var ev = event[i]; + if (ev.handler.apply(ev.context, data) == false) + return false; + } + }, + + //绑定事件 + bind: function (arg, handler, context) + { + if (typeof arg == 'object') + { + for (var p in arg) + { + this.bind(p, arg[p]); + } + return; + } + if (typeof handler != 'function') return false; + var name = arg.toLowerCase(); + var event = this.events[name] || []; + context = context || this; + event.push({ handler: handler, context: context }); + this.events[name] = event; + }, + + //取消绑定 + unbind: function (arg, handler) + { + if (!arg) + { + this.events = {}; + return; + } + var name = arg.toLowerCase(); + var event = this.events[name]; + if (!event || !event.length) return; + if (!handler) + { + delete this.events[name]; + } + else + { + for (var i = 0, l = event.length; i < l; i++) + { + if (event[i].handler == handler) + { + event.splice(i, 1); + break; + } + } + } + }, + destroy: function () + { + liger.remove(this); + } + }); + + + //界面组件基类, + //1,完成界面初始化:设置组件id并存入组件管理器池,初始化参数 + //2,渲染的工作,细节交给子类实现 + //parm [element] 组件对应的dom element对象 + //parm [options] 组件的参数 + liger.core.UIComponent = function (element, options) + { + liger.core.UIComponent.base.constructor.call(this, options); + var extendMethods = this._extendMethods(); + if (extendMethods) $.extend(this, extendMethods); + this.element = element; + this._init(); + this._preRender(); + this.trigger('render'); + this._render(); + this.trigger('rendered'); + this._rendered(); + }; + liger.core.UIComponent.ligerExtend(liger.core.Component, { + __getType: function () + { + return 'liger.core.UIComponent'; + }, + //扩展方法 + _extendMethods: function () + { + + }, + _init: function () + { + this.type = this.__getType(); + if (!this.element) + { + this.id = this.options.id || liger.getId(this.__idPrev()); + } + else + { + this.id = this.options.id || this.element.id || liger.getId(this.__idPrev()); + } + //存入管理器池 + liger.add(this); + + if (!this.element) return; + + //读取attr方法,并加载到参数,比如['url'] + var attributes = this.attr(); + if (attributes && attributes instanceof Array) + { + for (var i = 0; i < attributes.length; i++) + { + var name = attributes[i]; + if ($(this.element).attr(name)) + { + this.options[name] = $(this.element).attr(name); + } + } + } + //读取ligerui这个属性,并加载到参数,比如 ligerui = "width:120,heigth:100" + var p = this.options; + if ($(this.element).attr("ligerui")) + { + try + { + var attroptions = $(this.element).attr("ligerui"); + if (attroptions.indexOf('{') != 0) attroptions = "{" + attroptions + "}"; + eval("attroptions = " + attroptions + ";"); + if (attroptions) $.extend(p, attroptions); + } + catch (e) { } + } + + //v1.3.2增加 从data-XX 加载属性 + function loadDataOp(control, jelement) + { + var op = {}; + if (!control || control.indexOf('.') != -1) return op; + var defaultOp = liger.defaults[control]; + if (!defaultOp) return op; + for (var name in defaultOp) + { + if (jelement.attr(liger.attrPrev + "-" + name)) + { + var value = jelement.attr(liger.attrPrev + "-" + name); + if (typeof (defaultOp[name]) == "boolean") + { + op[name] = value == "true" || value == "1"; + } else + { + op[name] = value; + } + } + } + return op; + } + + $.extend(p, loadDataOp(this.__getType(), $(this.element))); + + }, + //预渲染,可以用于继承扩展 + _preRender: function () + { + + }, + _render: function () + { + + }, + _rendered: function () + { + if (this.element) + { + $(this.element).attr("ligeruiid", this.id); + } + }, + _setCls: function (value) + { + if (this.element && value) + { + $(this.element).addClass(value); + } + }, + //返回要转换成ligerui参数的属性,比如['url'] + attr: function () + { + return []; + }, + destroy: function () + { + if (this.element) + { + $(this.element).remove(); + } + this.options = null; + liger.remove(this); + } + }); + + + //表单控件基类 + liger.controls.Input = function (element, options) + { + liger.controls.Input.base.constructor.call(this, element, options); + }; + + liger.controls.Input.ligerExtend(liger.core.UIComponent, { + __getType: function () + { + return 'liger.controls.Input'; + }, + attr: function () + { + return ['nullText']; + }, + setValue: function (value) + { + return this.set('value', value); + }, + getValue: function () + { + return this.get('value'); + }, + //设置只读 + _setReadonly: function (readonly) + { + var wrapper = this.wrapper || this.text; + if (!wrapper || !wrapper.hasClass("l-text")) return; + var inputText = this.inputText; + if (readonly) + { + if (inputText) inputText.attr("readonly", "readonly"); + wrapper.addClass("l-text-readonly"); + } else + { + if (inputText) inputText.removeAttr("readonly"); + wrapper.removeClass("l-text-readonly"); + } + }, + setReadonly: function (readonly) + { + return this.set('readonly', readonly); + }, + setEnabled: function () + { + return this.set('disabled', false); + }, + setDisabled: function () + { + return this.set('disabled', true); + }, + updateStyle: function () + { + + }, + resize: function (width, height) + { + this.set({ width: width, height: height + 2 }); + } + }); + + //全局窗口对象 + liger.win = { + //顶端显示 + top: false, + + //遮罩 + mask: function (win) + { + function setHeight() + { + if (!liger.win.windowMask) return; + var h = $(window).height() + $(window).scrollTop(); + liger.win.windowMask.height(h); + } + if (!this.windowMask) + { + this.windowMask = $("<div class='l-window-mask' style='display: block;'></div>").appendTo('body'); + $(window).bind('resize.ligeruiwin', setHeight); + $(window).bind('scroll', setHeight); + } + this.windowMask.show(); + setHeight(); + this.masking = true; + }, + + //取消遮罩 + unmask: function (win) + { + var jwins = $("body > .l-dialog:visible,body > .l-window:visible"); + for (var i = 0, l = jwins.length; i < l; i++) + { + var winid = jwins.eq(i).attr("ligeruiid"); + if (win && win.id == winid) continue; + //获取ligerui对象 + var winmanager = liger.get(winid); + if (!winmanager) continue; + //是否模态窗口 + var modal = winmanager.get('modal'); + //如果存在其他模态窗口,那么不会取消遮罩 + if (modal) return; + } + if (this.windowMask) + this.windowMask.hide(); + this.masking = false; + }, + + //显示任务栏 + createTaskbar: function () + { + if (!this.taskbar) + { + this.taskbar = $('<div class="l-taskbar"><div class="l-taskbar-tasks"></div><div class="l-clear"></div></div>').appendTo('body'); + if (this.top) this.taskbar.addClass("l-taskbar-top"); + this.taskbar.tasks = $(".l-taskbar-tasks:first", this.taskbar); + this.tasks = {}; + } + this.taskbar.show(); + this.taskbar.animate({ bottom: 0 }); + return this.taskbar; + }, + + //关闭任务栏 + removeTaskbar: function () + { + var self = this; + self.taskbar.animate({ bottom: -32 }, function () + { + self.taskbar.remove(); + self.taskbar = null; + }); + }, + activeTask: function (win) + { + for (var winid in this.tasks) + { + var t = this.tasks[winid]; + if (winid == win.id) + { + t.addClass("l-taskbar-task-active"); + } + else + { + t.removeClass("l-taskbar-task-active"); + } + } + }, + + //获取任务 + getTask: function (win) + { + var self = this; + if (!self.taskbar) return; + if (self.tasks[win.id]) return self.tasks[win.id]; + return null; + }, + + + //增加任务 + addTask: function (win) + { + var self = this; + if (!self.taskbar) self.createTaskbar(); + if (self.tasks[win.id]) return self.tasks[win.id]; + var title = win.get('title'); + var task = self.tasks[win.id] = $('<div class="l-taskbar-task"><div class="l-taskbar-task-icon"></div><div class="l-taskbar-task-content">' + title + '</div></div>'); + self.taskbar.tasks.append(task); + self.activeTask(win); + task.bind('click', function () + { + self.activeTask(win); + if (win.actived) + win.min(); + else + win.active(); + }).hover(function () + { + $(this).addClass("l-taskbar-task-over"); + }, function () + { + $(this).removeClass("l-taskbar-task-over"); + }); + return task; + }, + + hasTask: function () + { + for (var p in this.tasks) + { + if (this.tasks[p]) + return true; + } + return false; + }, + + //移除任务 + removeTask: function (win) + { + var self = this; + if (!self.taskbar) return; + if (self.tasks[win.id]) + { + self.tasks[win.id].unbind(); + self.tasks[win.id].remove(); + delete self.tasks[win.id]; + } + if (!self.hasTask()) + { + self.removeTaskbar(); + } + }, + + //前端显示 + setFront: function (win) + { + var wins = liger.find(liger.core.Win); + for (var i in wins) + { + var w = wins[i]; + if (w == win) + { + $(w.element).css("z-index", "9200"); + this.activeTask(w); + } + else + { + $(w.element).css("z-index", "9100"); + } + } + } + }; + + + //窗口基类 window、dialog + liger.core.Win = function (element, options) + { + liger.core.Win.base.constructor.call(this, element, options); + }; + + liger.core.Win.ligerExtend(liger.core.UIComponent, { + __getType: function () + { + return 'liger.controls.Win'; + }, + mask: function () + { + if (this.options.modal) + liger.win.mask(this); + }, + unmask: function () + { + if (this.options.modal) + liger.win.unmask(this); + }, + min: function () + { + }, + max: function () + { + }, + active: function () + { + } + }); + + + liger.draggable = { + dragging: false + }; + + liger.resizable = { + reszing: false + }; + + + liger.toJSON = typeof JSON === 'object' && JSON.stringify ? JSON.stringify : function (o) + { + var f = function (n) + { + return n < 10 ? '0' + n : n; + }, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + quote = function (value) + { + escapable.lastIndex = 0; + return escapable.test(value) ? + '"' + value.replace(escapable, function (a) + { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + value + '"'; + }; + if (o === null) return 'null'; + var type = typeof o; + if (type === 'undefined') return undefined; + if (type === 'string') return quote(o); + if (type === 'number' || type === 'boolean') return '' + o; + if (type === 'object') + { + if (typeof o.toJSON === 'function') + { + return liger.toJSON(o.toJSON()); + } + if (o.constructor === Date) + { + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + } + var pairs = []; + if (o.constructor === Array) + { + for (var i = 0, l = o.length; i < l; i++) + { + pairs.push(liger.toJSON(o[i]) || 'null'); + } + return '[' + pairs.join(',') + ']'; + } + var name, val; + for (var k in o) + { + type = typeof k; + if (type === 'number') + { + name = '"' + k + '"'; + } else if (type === 'string') + { + name = quote(k); + } else + { + continue; + } + type = typeof o[k]; + if (type === 'function' || type === 'undefined') + { + continue; + } + val = liger.toJSON(o[k]); + pairs.push(name + ':' + val); + } + return '{' + pairs.join(',') + '}'; + } + }; + + //获取 默认的编辑构造器 + liger.getEditor = function (e) + { + var type = e.type, control = e.control, master = e.master; + if (!type) return null; + var inputTag = 0; + if (control) control = control.substr(0, 1).toUpperCase() + control.substr(1); + var defaultOp = { + create: function (container, editParm, controlOptions) + { + //field in form , column in grid + var field = editParm.field || editParm.column, options = controlOptions || {}; + var isInGrid = editParm.column ? true : false; + var p = $.extend({}, e.options); + var inputType = "text"; + if ($.inArray(type, ["password", "file", "checkbox", "radio"]) != -1) inputType = type; + if (e.password) inputType = "password"; + var inputBody = $("<input type='" + inputType + "'/>"); + if (e.body) + { + inputBody = e.body.clone(); + } + inputBody.appendTo(container); + if (editParm.field) + { + var txtInputName = field.name; + var prefixID = $.isFunction(options.prefixID) ? options.prefixID(master) : (options.prefixID || ""); + p.id = field.id || (prefixID + field.name); + if ($.inArray(type, ["select", "combobox", "autocomplete", "popup"]) != -1) + { + txtInputName = field.textField || field.comboboxName; + if (field.comboboxName && !field.id) + p.id = (options.prefixID || "") + field.comboboxName; + } + if ($.inArray(type, ["select", "combobox", "autocomplete", "popup", "radiolist", "checkboxlist", "listbox"]) != -1) + { + p.valueFieldID = prefixID + field.name; + } + if (!e.body) + { + var inputName = prefixID + txtInputName; + var inputId = new Date().getTime() + "_" + ++inputTag + "_" + field.name; + inputBody.attr($.extend({ + id: inputId, + name: inputName + }, field.attr)); + if (field.cssClass) + { + inputBody.addClass(field.cssClass); + } + if (field.validate && !master.options.unSetValidateAttr) + { + inputBody.attr('validate', liger.toJSON(field.validate)); + } + } + $.extend(p, field.options); + } + if (field.dictionary) //字典字段,比如:男|女 + { + field.editor = field.editor || {}; + if (!field.editor.data) + { + var dicEditorData = [], dicItems = field.dictionary.split('|'); + $(dicItems).each(function (i, dicItem) + { + var dics = dicItem.split(','); + var dicItemId = dics[0], dicItemText = dics.length >= 2 ? dics[1] : dics[0]; + dicEditorData.push({ + id: dicItemId, + value: dicItemId, + text: dicItemText + }); + }); + field.editor.data = dicEditorData; + } + } + if (field.editor) + { + if (field.editor.options) + { + $.extend(p, field.editor.options); + delete field.editor.options; + } + if (field.editor.valueColumnName) + { + p.valueField = field.editor.valueColumnName; + delete field.editor.valueColumnName; + } + if (field.editor.displayColumnName) + { + p.textField = field.editor.displayColumnName; + delete field.editor.displayColumnName; + } + //可扩展参数,支持动态加载 + var ext = field.editor.p || field.editor.ext; + if (ext) + { + ext = typeof (ext) == 'function' ? ext(editParm) : ext; + $.extend(p, ext); + delete field.editor.p; + delete field.editor.ext; + } + $.extend(p, field.editor); + } + + if (isInGrid) + { + p.host_grid = this; + p.host_grid_row = editParm.record; + p.host_grid_column = editParm.column; + } else + { + p.host_form = this; + + if (field.readonly || p.host_form.get('readonly')) + { + p.readonly = true; + } + } + //返回的是ligerui对象 + var lobj = inputBody['liger' + control](p); + if (isInGrid) + { + setTimeout(function () { inputBody.focus(); }, 100); + } + return lobj; + }, + getValue: function (editor, editParm) + { + var field = editParm.field || editParm.column; + if (editor.getValue) + { + var value = editor.getValue(); + var edtirType = editParm.column ? editParm.column.editor.type : editParm.field.type; + //isArrayValue属性可将提交字段数据改成[id1,id2,id3]的形式 + if (field && field.editor && field.editor.isArrayValue && value) + { + value = value.split(';'); + } + //isRef属性可将提交字段数据改成[id,value]的形式 + if (field && field.editor && field.editor.isRef && editor.getText) + { + value = [value, editor.getText()]; + } + //isRefMul属性可将提交字段数据改成[[id1,value1],[id2,value2]]的形式 + if (field && field.editor && field.editor.isRefMul && editor.getText) + { + var vs = value.split(';'); + var ts = editor.getText().split(';'); + value = []; + for (var i = 0; i < vs.length; i++) + { + value.push([vs[i], ts[i]]); + } + } + if (edtirType == "int" || edtirType == "digits") + { + value = value ? parseInt(value, 10) : 0; + } + else if (edtirType == "float" || edtirType == "number") + { + value = value ? parseFloat(value) : 0; + } + return value; + } + }, + setValue: function (editor, value, editParm) + { + var field = editParm.field || editParm.column; + if (editor.setValue) + { + //设置了isArrayValue属性- 如果获取到的数据是[id1,id2,id3]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isArrayValue && value) + { + value = value.join(';'); + } + //设置了isRef属性-如果获取到的数据是[id,text]的形式,需要获取[0] + if (field && field.editor && field.editor.isRef && $.isArray(value)) + { + value = value[0]; + } + //设置了isRefMul属性- 获取到[[id1,value1],[id2,value2]]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isRefMul && $.isArray(value)) + { + var vs = []; + for (var i = 0; i < value.length; i++) + { + vs.push(value[i].length > 1 ? value[i][1] : value[i][0]); + } + value = vs.join(';'); + } + editor.setValue(value); + } + }, + //从控件获取到文本信息 + getText: function (editor, editParm) + { + var field = editParm.field || editParm.column; + if (editor.getText) + { + var text = editor.getText(); + if (text) return text; + } + }, + //设置文本信息到控件去 + setText: function (editor, text, editParm) + { + if (text && editor.setText) + { + editor.setText(text); + } + //如果没有把数据保存到 textField 字段,那么需要获取值字段 + else + { + var field = editParm.field || editParm.column; + text = editor.setValue() || editParm.value || ""; + //如果获取到的数据是[id,text]的形式,需要获取[0] + if (field && field.editor && field.editor.isRef && $.isArray(text) && text.length > 1) + { + text = text[1]; + } + //在grid的编辑里面 获取到[[id1,value1],[id2,value2]]的形式,需要合并为一个完整字符串 + if (field && field.editor && field.editor.isRefMul && $.isArray(text) && text.length > 1) + { + var vs = []; + for (var i = 0; i < text.length; i++) + { + vs.push(text[1]); + } + text = vs.join(';'); + } + if (editor.setText) + { + editor.setText(text); + } + } + }, + getSelected: function (editor, editParm) + { + if (editor.getSelected) + { + return editor.getSelected(); + } + }, + resize: function (editor, width, height, editParm) + { + if (editParm.field) width = width - 2; + if (editor.resize) editor.resize(width, height); + }, + setEnabled: function (editor, isEnabled) + { + if (isEnabled) + { + if (editor.setEnabled) editor.setEnabled(); + } + else + { + if (editor.setDisabled) editor.setDisabled(); + } + }, + destroy: function (editor, editParm) + { + if (editor.destroy) editor.destroy(); + } + }; + + return $.extend({}, defaultOp, liger.editorCreatorDefaults || {}, e); + } + + + //几个默认的编辑器构造函数 + liger.editors = { + "text": { + control: 'TextBox' + }, + "date": { + control: 'DateEditor', + setValue: function (editor, value, editParm) + { + // /Date(1328423451489)/ + if (typeof value == "string" && /^\/Date/.test(value)) + { + value = value.replace(/^\//, "new ").replace(/\/$/, ""); + eval("value = " + value); + } + editor.setValue(value); + } + }, + "combobox": { + control: 'ComboBox' + }, + "spinner": { + control: 'Spinner' + }, + "checkbox": { + control: 'CheckBox' + }, + "checkboxlist": { + control: 'CheckBoxList', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "radiolist": { + control: 'RadioList', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "listbox": { + control: 'ListBox', + body: $('<div></div>'), + resize: function (editor, width, height, editParm) + { + editor.set('width', width - 2); + } + }, + "popup": { + control: 'PopupEdit' + }, + "number": { + control: 'TextBox', + options: { number: true } + }, + "currency": { + control: 'TextBox', + options: { currency: true } + }, + "digits": { + control: 'TextBox', + options: { digits: true } + }, + "password": { + control: 'TextBox', + password: true + } + }; + liger.editors["string"] = liger.editors["text"]; + liger.editors["select"] = liger.editors["combobox"]; + liger.editors["int"] = liger.editors["digits"]; + liger.editors["float"] = liger.editors["number"]; + liger.editors["chk"] = liger.editors["checkbox"]; + liger.editors["popupedit"] = liger.editors["popup"]; + + //jQuery version fix + $.fn.live = $.fn.on ? $.fn.on : $.fn.live; + if (!$.browser) + { + var userAgent = navigator.userAgent.toLowerCase(); + $.browser = { + version: (userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1], + safari: /webkit/.test(userAgent), + opera: /opera/.test(userAgent), + msie: /msie/.test(userAgent) && !/opera/.test(userAgent), + mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent) + }; + } +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + /* + 以html的方式加载组件 + 程序会查询以 liger-插件名 类名的Dom,从dom加载相应的参数并调用插件 + 比如遇到 .liger-grid 的dom,会找到 liger.defaults.Grid 加载需要的参数 + 而在config.Grid中配置了这些参数的类型,会动态得加载data,而columns会设置为数组 + 参数处理的优先级为: + 1,ignores 忽略不处理的参数 + 2,dom存在 {属性名} 的类名 ,比如 <ul class="columns"></ul> ,便会将这个参数设置为复杂属性(object或array):找到相应的defaults和config来加载 + defaults是先找$.liger.inject.defaults,找不到再找liger.defaults的 + config为{父配置}.{属性名},比如 config.Grid.columns + 3,直接读取 data-{属性名} 或者 {属性名} 的dom属性 + */ + liger.inject = { + + prev: 'liger-', + + /* + 命名规则:插件名_属性名(包括第N级的属性) (插件名首字母大写,属性名首字母小写) + 获取规则:获取default时会先找这里,找不到再找liger.defaults,比如 liger.defaults.Grid_columns + 备注:这里只定义了参数的列表 + */ + defaults: { + Grid_detail: { + height: null, + onShowDetail: null + }, + Grid_editor: 'ComboBox,DateEditor,Spinner,TextBox,PopupEdit,CheckBoxList,RadioList,Grid_editor', + Grid_popup: 'PopupEdit', + Grid_grid: 'Grid', + Grid_condition: 'Form', + Grid_toolbar: 'Toolbar', + Grid_fields: 'Form_fields', + Form_editor: 'ComboBox,DateEditor,Spinner,TextBox,PopupEdit,CheckBoxList,RadioList,Form_editor', + Form_grid: 'Grid', + Form_columns: 'Grid_columns', + Form_condition: 'Form', + Form_popup: 'PopupEdit', + Form_buttons: 'Button', + Portal_panel: 'Panel' + }, + /* + config里面配置了某插件参数或者复杂属性参数的类型(动态加载、数组、默认参数) + */ + config: { + Grid: { + //动态 + dynamics: 'data,isChecked,detail,rowDraggingRender,toolbar,columns', + //数组 + arrays: 'columns', + //复杂属性columns + columns: { + dynamics: 'render,totalSummary,headerRender,columns,editor,columns', + arrays: 'columns', + textProperty: 'display', + columns: 'liger.inject.config.Grid.columns', + editor: { + dynamics: 'data,columns,render,renderItem,grid,condition,ext', + grid: 'liger.inject.config.Grid', + condition: 'liger.inject.config.Form' + } + }, + toolbar: { + arrays: 'items' + } + }, + Form: { + dynamics: 'validate,fields,buttons', + arrays: 'fields,buttons', + fields: { + textProperty: 'label', + dynamics: 'validate,editor', + editor: { + dynamics: 'data,columns,render,renderItem,grid,condition,attr', + grid: 'liger.inject.config.Grid', + condition: 'liger.inject.config.Form' + } + }, + buttons: 'liger.inject.config.Button' + }, + PopupEdit: { + dynamics: 'grid,condition' + }, + Button: { + textProperty: 'text', + dynamics: 'click' + }, + ComboBox: { + dynamics: 'columns,data,tree,grid,condition,render,parms,renderItem' + }, + ListBox: { + dynamics: 'columns,data,render,parms' + }, + RadioList: { + dynamics: 'data,parms' + }, + CheckBoxList: { + dynamics: 'data,parms' + }, + Panel: { + }, + Portal: { + //动态 + dynamics: 'rows,columns', + //数组 + arrays: 'rows,columns', + //复杂属性 columns + columns: { + dynamics: 'panels', + arrays: 'panels' + }, + //复杂属性 rows + rows: { + dynamics: 'panels', + arrays: 'panels' + }, + toolbar: { + arrays: 'items' + } + } + }, + + parse: function (code) + { + try + { + if (code == null) return null; + return new Function("return " + code + ";")(); + } catch (e) + { + return null; + } + }, + + parseDefault: function (value) + { + var g = this; + if (!value) return value; + var result = {}; + $(value.split(',')).each(function (index, name) + { + if (!name) return; + name = name.substr(0, 1).toUpperCase() + name.substr(1); + $.extend(result, g.parse("liger.defaults." + name)); + }); + return result; + }, + + fotmatValue: function (value, type) + { + if (type == "boolean") + return value == "true" || value == "1"; + if (type == "number" && value) + return parseFloat(value.toString()); + return value; + }, + + getOptions: function (e) + { + var jelement = e.jelement, defaults = e.defaults, config = e.config; + config = $.extend({ + ignores: "", + dynamics: "", + arrays: "" + }, config); + var g = this, options = {}, value; + if (config.textProperty) options[config.textProperty] = jelement.text(); + for (var proName in defaults) + { + var className = proName.toLowerCase(); + var subElement = $("> ." + className, jelement); + //忽略 + if ($.inArray(proName, config.ignores.split(',')) != -1) continue; + //判断子节点 (复杂属性) + if (subElement.length) + { + var defaultName = e.controlName + "_" + proName; + var subDefaults = g.defaults[defaultName] || liger.defaults[defaultName], subConfig = config[proName]; + if (typeof (subDefaults) == "string") subDefaults = g.parseDefault(subDefaults); + else if (typeof (subDefaults) == "funcion") subDefaults = subDefaults(); + if (typeof (subConfig) == "string") subConfig = g.parse(subConfig); + else if (typeof (subConfig) == "funcion") subConfig = subConfig(); + if (subDefaults) + { + if ($.inArray(proName, config.arrays.split(',')) != -1) + { + value = []; + $(">div,>li,>input", subElement).each(function () + { + value.push(g.getOptions({ + defaults: subDefaults, + controlName: e.controlName, + config: subConfig, + jelement: $(this) + })); + }); + options[proName] = value; + } else + { + options[proName] = g.getOptions({ + defaults: subDefaults, + controlName: e.controlName, + config: subConfig, + jelement: subElement + }); + } + } + subElement.remove(); + } + //动态值 + else if ($.inArray(proName, config.dynamics.split(',')) != -1 || proName.indexOf('on') == 0) + { + value = g.parse(jelement.attr("data-" + proName) || jelement.attr(proName)); + if (value) + { + options[proName] = g.fotmatValue(value, typeof (defaults[proName])); + } + } + //默认处理 + else + { + value = jelement.attr("data-" + proName) || jelement.attr(proName); + if (value) + { + options[proName] = g.fotmatValue(value, typeof (defaults[proName])); + } + } + } + var dataOptions = jelement.attr("data-options") || jelement.attr("data-property"); + if (dataOptions) dataOptions = g.parse("{" + dataOptions + "}"); + if (dataOptions) $.extend(options, dataOptions); + return options; + }, + + init: function () + { + var g = this, configs = this.config; + for (var name in g.defaults) + { + if (typeof (g.defaults[name]) == "string") + { + g.defaults[name] = g.parseDefault(g.defaults[name]); + } + } + for (var controlName in liger.controls) + { + var config = configs[controlName] || {}; + var className = g.prev + controlName.toLowerCase(); + $("." + className).each(function () + { + var jelement = $(this), value; + var defaults = $.extend({ + onrender: null, + onrendered: null + }, liger.defaults[controlName]); + var options = g.getOptions({ + defaults: defaults, + controlName: controlName, + config: config, + jelement: jelement + }); + jelement[liger.pluginPrev + controlName](options); + }); + } + } + + } + + $(function () + { + liger.inject.init(); + }); + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerAccordion = function (options) + { + return $.ligerui.run.call(this, "ligerAccordion", arguments); + }; + + $.fn.ligerGetAccordionManager = function () + { + return $.ligerui.get(this); + }; + + $.ligerDefaults.Accordion = { + height: null, + speed: "normal", + changeHeightOnResize: false, + heightDiff: 0 // 高度补差 + }; + $.ligerMethos.Accordion = {}; + + $.ligerui.controls.Accordion = function (element, options) + { + $.ligerui.controls.Accordion.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Accordion.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Accordion'; + }, + __idPrev: function () + { + return 'Accordion'; + }, + _extendMethods: function () + { + return $.ligerMethos.Accordion; + }, + _render: function () + { + var g = this, p = this.options; + g.accordion = $(g.element); + if (!g.accordion.hasClass("l-accordion-panel")) g.accordion.addClass("l-accordion-panel"); + var selectedIndex = 0; + if ($("> div[lselected=true]", g.accordion).length > 0) + selectedIndex = $("> div", g.accordion).index($("> div[lselected=true]", g.accordion)); + + $("> div", g.accordion).each(function (i, box) + { + var header = $('<div class="l-accordion-header"><div class="l-accordion-toggle"></div><div class="l-accordion-header-inner"></div></div>'); + if (i == selectedIndex) + $(".l-accordion-toggle", header).addClass("l-accordion-toggle-open"); + if ($(box).attr("title")) + { + $(".l-accordion-header-inner", header).html($(box).attr("title")); + $(box).attr("title", ""); + } + $(box).before(header); + if (!$(box).hasClass("l-accordion-content")) $(box).addClass("l-accordion-content"); + + if ($(box).attr("data-icon")) + { + header.addClass("l-accordion-header-hasicon"); + header.append('<i><img src="' + $(box).attr("data-icon") + '" /></i>'); + } + }); + $(".l-accordion-header", g.accordion).removeClass("l-accordion-header-downfirst"); + $(".l-accordion-content:visible", g.accordion).next(".l-accordion-header:first").addClass("l-accordion-header-downfirst"); + + //add Even + $(".l-accordion-toggle", g.accordion).each(function () + { + if (!$(this).hasClass("l-accordion-toggle-open") && !$(this).hasClass("l-accordion-toggle-close")) + { + $(this).addClass("l-accordion-toggle-close"); + } + if ($(this).hasClass("l-accordion-toggle-close")) + { + $(this).parent().next(".l-accordion-content:visible").hide(); + } + }); + $(".l-accordion-header", g.accordion).hover(function () + { + $(this).addClass("l-accordion-header-over"); + }, function () + { + $(this).removeClass("l-accordion-header-over"); + }); + $(".l-accordion-toggle", g.accordion).hover(function () + { + if ($(this).hasClass("l-accordion-toggle-open")) + $(this).addClass("l-accordion-toggle-open-over"); + else if ($(this).hasClass("l-accordion-toggle-close")) + $(this).addClass("l-accordion-toggle-close-over"); + }, function () + { + if ($(this).hasClass("l-accordion-toggle-open")) + $(this).removeClass("l-accordion-toggle-open-over"); + else if ($(this).hasClass("l-accordion-toggle-close")) + $(this).removeClass("l-accordion-toggle-close-over"); + }); + $(">.l-accordion-header", g.accordion).click(function () + { + var togglebtn = $(".l-accordion-toggle:first", this); + if (togglebtn.hasClass("l-accordion-toggle-close")) + { + togglebtn.removeClass("l-accordion-toggle-close") + .removeClass("l-accordion-toggle-close-over l-accordion-toggle-open-over") + togglebtn.addClass("l-accordion-toggle-open"); + $(this).next(".l-accordion-content") + .show(p.speed) + .siblings(".l-accordion-content:visible").hide(p.speed); + $(this).siblings(".l-accordion-header").find(".l-accordion-toggle").removeClass("l-accordion-toggle-open").addClass("l-accordion-toggle-close"); + } + else + { + togglebtn.removeClass("l-accordion-toggle-open") + .removeClass("l-accordion-toggle-close-over l-accordion-toggle-open-over") + .addClass("l-accordion-toggle-close"); + $(this).next(".l-accordion-content").hide(p.speed); + } + $(".l-accordion-header", g.accordion).removeClass("l-accordion-header-downfirst"); + $(".l-accordion-content:visible", g.accordion).next(".l-accordion-header:first").addClass("l-accordion-header-downfirst"); + }); + //init + g.headerHoldHeight = 0; + $("> .l-accordion-header", g.accordion).each(function () + { + g.headerHoldHeight += $(this).height(); + }); + if (p.height && typeof (p.height) == 'string' && p.height.indexOf('%') > 0) + { + g.onResize(); + if (p.changeHeightOnResize) + { + $(window).resize(function () + { + g.onResize(); + }); + } + } + else + { + if (p.height) + { + g.height = p.heightDiff + p.height; + g.accordion.height(g.height); + g.setHeight(p.height); + } + else + { + g.header = g.accordion.height(); + } + } + + g.set(p); + }, + onResize: function () + { + var g = this, p = this.options; + if (!p.height || typeof (p.height) != 'string' || p.height.indexOf('%') == -1) return false; + //set accordion height + if (g.accordion.parent()[0].tagName.toLowerCase() == "body") + { + var windowHeight = $(window).height(); + windowHeight -= parseInt(g.layout.parent().css('paddingTop')); + windowHeight -= parseInt(g.layout.parent().css('paddingBottom')); + g.height = p.heightDiff + windowHeight * parseFloat(g.height) * 0.01; + } + else + { + g.height = p.heightDiff + (g.accordion.parent().height() * parseFloat(p.height) * 0.01); + } + g.accordion.height(g.height); + g.setContentHeight(g.height - g.headerHoldHeight); + }, + setHeight: function (height) + { + var g = this, p = this.options; + g.accordion.height(height); + height -= g.headerHoldHeight; + $("> .l-accordion-content", g.accordion).height(height); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerButton = function (options) + { + return $.ligerui.run.call(this, "ligerButton", arguments); + }; + $.fn.ligerGetButtonManager = function () + { + return $.ligerui.run.call(this, "ligerGetButtonManager", arguments); + }; + + $.ligerDefaults.Button = { + width: 60, + text: 'Button', + disabled: false, + click: null, + icon : null + }; + + $.ligerMethos.Button = {}; + + $.ligerui.controls.Button = function (element, options) + { + $.ligerui.controls.Button.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Button.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'Button'; + }, + __idPrev: function () + { + return 'Button'; + }, + _extendMethods: function () + { + return $.ligerMethos.Button; + }, + _render: function () + { + var g = this, p = this.options; + g.button = $(g.element); + g.button.addClass("l-button"); + g.button.append('<div class="l-button-l"></div><div class="l-button-r"></div><span></span>'); + g.button.hover(function () { + if (p.disabled) return; + g.button.addClass("l-button-over"); + }, function () { + if (p.disabled) return; + g.button.removeClass("l-button-over"); + }); + p.click && g.button.click(function () + { + if (!p.disabled) + p.click(); + }); + g.set(p); + }, + _setIcon : function(url) + { + var g = this; + if (!url) + { + g.button.removeClass("l-button-hasicon"); + g.button.find('img').remove(); + } else + { + g.button.addClass("l-button-hasicon"); + g.button.append('<img src="' + url + '" />'); + } + }, + _setEnabled: function (value) + { + if (value) + this.button.removeClass("l-button-disabled"); + }, + _setDisabled: function (value) + { + if (value) { + this.button.addClass("l-button-disabled"); + this.options.disabled = true; + } else { + this.button.removeClass("l-button-disabled"); + this.options.disabled = false; + } + }, + _setWidth: function (value) + { + this.button.width(value); + }, + _setText: function (value) + { + $("span", this.button).html(value); + }, + setValue: function (value) + { + this.set('text', value); + }, + getValue: function () + { + return this.options.text; + }, + setEnabled: function () + { + this.set('disabled', false); + }, + setDisabled: function () + { + this.set('disabled', true); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerCheckBox = function (options) + { + return $.ligerui.run.call(this, "ligerCheckBox", arguments); + }; + $.fn.ligerGetCheckBoxManager = function () + { + return $.ligerui.run.call(this, "ligerGetCheckBoxManager", arguments); + }; + $.ligerDefaults.CheckBox = { + disabled: false, + readonly : false //只读 + }; + + $.ligerMethos.CheckBox = {}; + + $.ligerui.controls.CheckBox = function (element, options) + { + $.ligerui.controls.CheckBox.base.constructor.call(this, element, options); + }; + $.ligerui.controls.CheckBox.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'CheckBox'; + }, + __idPrev: function () + { + return 'CheckBox'; + }, + _extendMethods: function () + { + return $.ligerMethos.CheckBox; + }, + _render: function () + { + var g = this, p = this.options; + g.input = $(g.element); + g.link = $('<a class="l-checkbox"></a>'); + g.wrapper = g.input.addClass('l-hidden').wrap('<div class="l-checkbox-wrapper"></div>').parent(); + g.wrapper.prepend(g.link); + g.link.click(function () + { + if (g.input.attr('disabled') || g.input.attr('readonly')) { return false; } + if (p.disabled || p.readonly) return false; + if (g.trigger('beforeClick', [g.element]) == false) return false; + if ($(this).hasClass("l-checkbox-checked")) + { + g._setValue(false); + } + else + { + g._setValue(true); + } + g.input.trigger("change"); + }); + g.wrapper.hover(function () + { + if (!p.disabled) + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + this.set(p); + this.updateStyle(); + }, + _setCss: function (value) + { + this.wrapper.css(value); + }, + _setValue: function (value) + { + var g = this, p = this.options; + if (!value) + { + g.input[0].checked = false; + g.link.removeClass('l-checkbox-checked'); + } + else + { + g.input[0].checked = true; + g.link.addClass('l-checkbox-checked'); + } + }, + _setDisabled: function (value) + { + if (value) + { + this.input.attr('disabled', true); + this.wrapper.addClass("l-disabled"); + } + else + { + this.input.attr('disabled', false); + this.wrapper.removeClass("l-disabled"); + } + }, + _getValue: function () + { + return this.element.checked; + }, + updateStyle: function () + { + if (this.input.attr('disabled')) + { + this.wrapper.addClass("l-disabled"); + this.options.disabled = true; + } + if (this.input[0].checked) + { + this.link.addClass('l-checkbox-checked'); + } + else + { + this.link.removeClass('l-checkbox-checked'); + } + } + }); +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerCheckBoxList = function (options) + { + return $.ligerui.run.call(this, "ligerCheckBoxList", arguments); + }; + + $.ligerDefaults.CheckBoxList = { + rowSize: 3, //每行显示元素数 + valueField: 'id', //值成员 + textField: 'text', //显示成员 + valueFieldID:null, //隐藏域 + name : null, //表单名 + split: ";", //分隔符 + data: null, //数据 + parms: null, //ajax提交表单 + url: null, //数据源URL(需返回JSON) + urlParms: null, //url带参数 + ajaxContentType: null, + ajaxType : 'post', + onSuccess: null, + onError: null, + css: null, //附加css + value: null, //值 + valueFieldCssClass : null + }; + + //扩展方法 + $.ligerMethos.CheckBoxList = $.ligerMethos.CheckBoxList || {}; + + + $.ligerui.controls.CheckBoxList = function (element, options) + { + $.ligerui.controls.CheckBoxList.base.constructor.call(this, element, options); + }; + $.ligerui.controls.CheckBoxList.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'CheckBoxList'; + }, + _extendMethods: function () + { + return $.ligerMethos.CheckBoxList; + }, + _init: function () + { + $.ligerui.controls.CheckBoxList.base._init.call(this); + }, + _render: function () + { + var g = this, p = this.options; + g.data = p.data; + g.valueField = null; //隐藏域(保存值) + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.valueField = $(this.element); + if ($(this.element).is(":text")) + { + g.valueField.hide(); + } + } + else if (p.valueFieldID) + { + g.valueField = $("#" + p.valueFieldID + ":input,[name=" + p.valueFieldID + "]:input"); + if (g.valueField.length == 0) g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = p.valueFieldID; + } + else + { + g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = g.id + "_val"; + } + if (g.valueField[0].name == null) g.valueField[0].name = g.valueField[0].id; + if (p.valueFieldCssClass) + { + g.valueField.addClass(p.valueFieldCssClass); + } + g.valueField.attr("data-ligerid", g.id); + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.checkboxList = $('<div></div>').insertBefore(this.element); + } else + { + g.checkboxList = $(this.element); + } + g.checkboxList.html('<div class="l-checkboxlist-inner"><table cellpadding="0" cellspacing="0" border="0" class="l-checkboxlist-table"></table></div>').addClass("l-checkboxlist").append(g.valueField); + g.checkboxList.table = $("table:first", g.checkboxList); + + g.set(p); + + g._addClickEven(); + }, + destroy: function () + { + if (this.checkboxList) this.checkboxList.remove(); + this.options = null; + $.ligerui.remove(this); + }, + clear : function() + { + this._changeValue(""); + this.trigger('clear'); + }, + _setCss : function(css) + { + if (css) { + this.checkboxList.addClass(css); + } + }, + _setDisabled: function (value) + { + //禁用样式 + if (value) + { + this.checkboxList.addClass('l-checkboxlist-disabled'); + $("input:checkbox", this.radioList).attr("disabled", true); + + } else + { + this.checkboxList.removeClass('l-checkboxlist-disabled'); + $("input:checkbox", this.radioList).removeAttr("disabled"); + } + }, + _setWidth: function (value) + { + this.checkboxList.width(value); + }, + _setHeight: function (value) + { + this.checkboxList.height(value); + }, + indexOf : function(item) + { + var g = this, p = this.options; + if (!g.data) return -1; + for (var i = 0, l = g.data.length; i < l; i++) + { + if (typeof (item) == "object") + { + if (g.data[i] == item) return i; + } else + { + if (g.data[i][p.valueField].toString() == item.toString()) return i; + } + } + return -1; + }, + removeItems : function(items) + { + var g = this; + if (!g.data) return; + $(items).each(function (i,item) + { + var index = g.indexOf(item); + if (index == -1) return; + g.data.splice(index, 1); + }); + g.refresh(); + }, + removeItem: function (item) + { + if (!this.data) return; + var index = this.indexOf(item); + if (index == -1) return; + this.data.splice(index, 1); + this.refresh(); + }, + insertItem: function (item,index) + { + var g = this; + if (!g.data) g.data = []; + g.data.splice(index, 0, item); + g.refresh(); + }, + addItems: function (items) + { + var g = this; + if (!g.data) g.data = []; + $(items).each(function (i, item) + { + g.data.push(item); + }); + g.refresh(); + }, + addItem: function (item) + { + var g = this; + if (!g.data) g.data = []; + g.data.push(item); + g.refresh(); + }, + _setValue: function (value) + { + var g = this, p = this.options; + p.value = value; + g.valueField.val(p.value); + this._dataInit(); + }, + setValue: function (value) + { + this._setValue(value); + }, + _setUrl: function (url) { + if (!url) return; + var g = this, p = this.options; + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var parms = $.isFunction(p.parms) ? p.parms() : p.parms; + if (p.ajaxContentType == "application/json" && typeof (parms) != "string") + { + parms = liger.toJSON(parms); + } + $.ajax({ + type: p.ajaxType || 'post', + url: url, + data: parms, + cache: false, + dataType: 'json', + contentType: p.ajaxContentType, + success: function (data) { + g.setData(data); + g.trigger('success', [data]); + }, + error: function (XMLHttpRequest, textStatus) { + g.trigger('error', [XMLHttpRequest, textStatus]); + } + }); + }, + setUrl: function (url) { + return this._setUrl(url); + }, + setParm: function (name, value) { + if (!name) return; + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + parms[name] = value; + g.set('parms', parms); + }, + clearContent: function () + { + var g = this, p = this.options; + $("table", g.checkboxList).html(""); + }, + _setData : function(data) + { + this.setData(data); + }, + setData: function (data) + { + var g = this, p = this.options; + if (!data || !data.length) return; + g.data = data; + g.refresh(); + g.updateStyle(); + }, + refresh:function() + { + var g = this, p = this.options, data = this.data; + this.clearContent(); + if (!data) return; + var out = [], rowSize = p.rowSize, appendRowStart = false, name = p.name || g.id; + for (var i = 0; i < data.length; i++) + { + var val = data[i][p.valueField], txt = data[i][p.textField], id = g.id + "-" + i; + var newRow = i % rowSize == 0; + //0,5,10 + if (newRow) + { + if (appendRowStart) out.push('</tr>'); + out.push("<tr>"); + appendRowStart = true; + } + out.push("<td><input type='checkbox' name='" + name + "' value='" + val + "' id='" + id + "'/><label for='" + id + "'>" + txt + "</label></td>"); + } + if (appendRowStart) out.push('</tr>'); + g.checkboxList.table.append(out.join('')); + }, + _getValue: function () + { + var g = this, p = this.options, name = p.name || g.id; + var values = []; + $('input:checkbox[name="' + name + '"]:checked').each(function () + { + values.push(this.value); + }); + if (!values.length) return null; + return values.join(p.split); + }, + getValue: function () + { + //获取值 + return this._getValue(); + }, + + getText : function() + { + var g = this, p = this.options, name = p.name || g.id; + var values = []; + $('input:checkbox[name="' + name + '"]:checked').each(function () + { + values.push($(this).next("label").text()); + }); + if (!values.length) return null; + return values.join(p.split); + }, + updateStyle: function () + { + this._dataInit(); + }, + _dataInit: function () + { + var g = this, p = this.options; + var value = g.valueField.val(); + g._changeValue(value); + }, + //设置值到 隐藏域 + _changeValue: function (value) + { + var g = this, p = this.options, name = p.name || g.id; + var valueArr = value ? value.split(p.split) : []; + $("input:checkbox[name='" + name + "']", g.checkboxList).each(function () + { + this.checked = $.inArray(this.value, valueArr) > -1; + }); + g.valueField.val(value); + g.selectedValue = value; + }, + _addClickEven: function () + { + var g = this, p = this.options; + //选项点击 + g.checkboxList.click(function (e) + { + var value = g.getValue(); + if (value) g.valueField.val(value); + }); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerComboBox = function (options) + { + return $.ligerui.run.call(this, "ligerComboBox", arguments); + }; + + $.fn.ligerGetComboBoxManager = function () + { + return $.ligerui.run.call(this, "ligerGetComboBoxManager", arguments); + }; + + $.ligerDefaults.ComboBox = { + resize: true, //是否调整大小 + isMultiSelect: false, //是否多选 + isShowCheckBox: false, //是否选择复选框 + columns: null, //表格状态 + width : null, + selectBoxWidth: null, //宽度 + selectBoxHeight: 120, //高度 + selectBoxPosYDiff : -3, //下拉框位置y坐标调整 + onBeforeSelect: false, //选择前事件 + onAfterShowData : null, + onSelected: null, //选择值事件 + initValue: null, + value : null, + initText: null, + valueField: 'id', + textField: 'text', + dataParmName : null, + valueFieldID: null, + ajaxComplete: null, + ajaxBeforeSend: null, + ajaxContentType : null, + slide: false, //是否以动画的形式显示 + split: ";", + data: null, + dataGetter : null, //下拉框数据集获取函数 + tree: null, //下拉框以树的形式显示,tree的参数跟LigerTree的参数一致 + treeLeafOnly: true, //是否只选择叶子 + condition: null, //列表条件搜索 参数同 ligerForm + grid: null, //表格 参数同 ligerGrid + onStartResize: null, + onEndResize: null, + hideOnLoseFocus: true, + hideGridOnLoseFocus: false, + url: null, //数据源URL(需返回JSON) + urlParms: null, //url带参数 + selectBoxRender: null, //自定义selectbox的内容 + selectBoxRenderUpdate: null, //自定义selectbox(发生值改变) + detailEnabled : true, //detailUrl是否有效 + detailUrl: null, //确定选项的时候,使用这个detailUrl加载到详细的数据 + detailPostIdField : null, //提交数据id字段名 + detailDataParmName:null, //返回数据data字段名 + detailParms: null, //附加参数 + detailDataGetter: null, + delayLoad: false, //是否延时加载 + triggerToLoad : false, //是否在点击下拉按钮时加载 + emptyText: null, //空行 + addRowButton: '新增', //新增按钮 + addRowButtonClick: null, //新增事件 + triggerIcon: null, // + onSuccess: null, + onBeforeSetData: null, + onError: null, + onBeforeOpen: null, //打开下拉框前事件,可以通过return false来阻止继续操作,利用这个参数可以用来调用其他函数,比如打开一个新窗口来选择值 + onButtonClick: null, //右侧图标按钮事件,可以通过return false来阻止继续操作,利用这个参数可以用来调用其他函数,比如打开一个新窗口来选择值 + onTextBoxKeyDown: null, + onTextBoxKeyEnter : null, + render: null, //文本框显示html函数 + absolute: true, //选择框是否在附加到body,并绝对定位 + cancelable: true, //可取消选择 + css: null, //附加css + parms: null, //ajax提交表单 + renderItem: null, //选项自定义函数 + autocomplete: false, //自动完成 + autocompleteAllowEmpty: true, //是否允许空值搜索 + isTextBoxMode : false, //是否文本框的形式 + highLight: false, //自动完成是否匹配字符高亮显示 + readonly: false, //是否只读 + ajaxType: 'post', + alwayShowInTop: false, //下拉框是否一直显示在上方 + alwayShowInDown: false, //下拉框是否一直显示在上方 + valueFieldCssClass: null, + isRowReadOnly: null, //选项是否只读的判定函数 + rowClsRender: null, //选项行 class name 自定义函数 + keySupport: false, //按键支持: 上、下、回车 支 + initIsTriggerEvent: false, //初始化时是否触发选择事件 + conditionSearchClick: null, //下拉框表格搜索按钮自定义函数 + onChangeValue: null, + delayLoadGrid: true, //是否在按下显示下拉框的时候才 加载 grid + setTextBySource : true //设置文本框值时是否从数据源中加载 + }; + + $.ligerDefaults.ComboBoxString = { + Search: "搜索" + }; + + //扩展方法 + $.ligerMethos.ComboBox = $.ligerMethos.ComboBox || {}; + + + $.ligerui.controls.ComboBox = function (element, options) + { + $.ligerui.controls.ComboBox.base.constructor.call(this, element, options); + }; + $.ligerui.controls.ComboBox.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'ComboBox'; + }, + _extendMethods: function () + { + return $.ligerMethos.ComboBox; + }, + _init: function () + { + $.ligerui.controls.ComboBox.base._init.call(this); + var p = this.options; + if (p.columns) + { + p.isShowCheckBox = true; + } + if (p.isMultiSelect) + { + p.isShowCheckBox = true; + } + if (p.triggerToLoad) + { + p.delayLoad = true; + } + }, + _render: function () + { + var g = this, p = this.options; + g.data = p.data; + g.inputText = null; + g.select = null; + g.textFieldID = ""; + g.valueFieldID = ""; + g.valueField = null; //隐藏域(保存值) + + if ($(this.element).is(":hidden")) + { + g.valueField = $(this.element); + + g.textFieldID = p.textFieldID || (this.element.id + "_txt"); + g.inputText = $('<input type="text" readonly="true"/>'); + g.inputText.attr("id", g.textFieldID).insertAfter($(this.element)); + + if (g.valueField.attr("validate")) + { + g.inputText.attr("validate", g.valueField.attr("validate")); + g.valueField.removeAttr("validate"); + } + if (g.valueField.attr("validateMessage")) + { + g.inputText.attr("validateMessage", g.valueField.attr("validateMessage")); + g.valueField.removeAttr("validateMessage"); + } + } + else if (this.element.tagName.toLowerCase() == "input") + { + this.element.readOnly = true; + g.inputText = $(this.element); + g.textFieldID = this.element.id; + } + else if (this.element.tagName.toLowerCase() == "select") + { + $(this.element).hide(); + g.select = $(this.element); + p.isMultiSelect = false; + p.isShowCheckBox = false; + p.cancelable = false; + g.textFieldID = p.textFieldID || (this.element.id + "_txt"); + g.inputText = $('<input type="text" readonly="true"/>'); + g.inputText.attr("id", g.textFieldID).insertAfter($(this.element)); + + + if (g.select.attr("validate")) + { + g.inputText.attr("validate", g.select.attr("validate")); + g.select.removeAttr("validate"); + } + if (g.select.attr("validateMessage")) + { + g.inputText.attr("validateMessage", g.select.attr("validateMessage")); + g.select.removeAttr("validateMessage"); + } + if (!p.value && this.element.value) + { + p.value = this.element.value; + } + + } + if (g.inputText[0].name == undefined) g.inputText[0].name = g.textFieldID; + + g.inputText.attr("data-comboboxid", g.id); + + if (g.valueField == null) + { + if (p.valueFieldID) + { + g.valueField = $("#" + p.valueFieldID + ":input,[name=" + p.valueFieldID + "]:input").filter("input:hidden"); + if (g.valueField.length == 0) g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = p.valueFieldID; + } + else + { + g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = g.textFieldID + "_val"; + } + } + if (p.valueFieldCssClass) + { + g.valueField.addClass(p.valueFieldCssClass); + } + if (g.valueField[0].name == undefined) g.valueField[0].name = g.valueField[0].id; + //update by superzoc 增加初始值 + if (p.initValue != null) g.valueField[0].value = p.initValue; + g.valueField.attr("data-ligerid", g.id); + //开关 + g.link = $('<div class="l-trigger"><div class="l-trigger-icon"></div></div>'); + if (p.triggerIcon) g.link.find("div:first").addClass(p.triggerIcon); + //下拉框 + g.selectBox = $('<div class="l-box-select" style="display:none"><div class="l-box-select-inner"><table cellpadding="0" cellspacing="0" border="0" class="l-box-select-table"></table></div></div>'); + g.selectBox.table = $("table:first", g.selectBox); + g.selectBoxInner = g.selectBox.find(".l-box-select-inner:first"); + //外层 + g.wrapper = g.inputText.wrap('<div class="l-text l-text-combobox"></div>').parent(); + g.wrapper.append('<div class="l-text-l"></div><div class="l-text-r"></div>'); + g.wrapper.append(g.link); + //添加个包裹, + g.textwrapper = g.wrapper.wrap('<div class="l-text-wrapper"></div>').parent(); + + if (p.absolute) + g.selectBox.appendTo('body').addClass("l-box-select-absolute"); + else + g.textwrapper.append(g.selectBox); + + g.textwrapper.append(g.valueField); + g.inputText.addClass("l-text-field"); + if (p.isShowCheckBox && !g.select) + { + $("table", g.selectBox).addClass("l-table-checkbox"); + } else + { + p.isShowCheckBox = false; + $("table", g.selectBox).addClass("l-table-nocheckbox"); + } + //开关 事件 + g.link.hover(function () + { + if (p.disabled || p.readonly) return; + this.className = "l-trigger-hover"; + }, function () + { + if (p.disabled || p.readonly) return; + this.className = "l-trigger"; + }).mousedown(function () + { + if (p.disabled || p.readonly) return; + this.className = "l-trigger-pressed"; + }).mouseup(function () + { + if (p.disabled || p.readonly) return; + this.className = "l-trigger-hover"; + }).click(function () + { + if (p.disabled || p.readonly) return; + if (g.trigger('buttonClick') == false) return false; + if (g.trigger('beforeOpen') == false) return false; + if (p.triggerToLoad && !g.triggerLoaded) + { + g.triggerLoaded = true; + g._setUrl(p.url, function () + { + g._toggleSelectBox(g.selectBox.is(":visible")); + }); + } else + { + g._toggleSelectBox(g.selectBox.is(":visible")); + } + }); + g.inputText.click(function () + { + if (p.disabled || p.readonly) return; + if (g.trigger('beforeOpen') == false) return false; + if (!p.autocomplete) + { + if (p.triggerToLoad && !g.triggerLoaded) + { + g.triggerLoaded = true; + g._setUrl(p.url, function () + { + g._toggleSelectBox(g.selectBox.is(":visible")); + }); + } else + { + g._toggleSelectBox(g.selectBox.is(":visible")); + } + } else + { + g.updateSelectBoxPosition(); + } + }).blur(function () + { + if (p.disabled) return; + g.wrapper.removeClass("l-text-focus"); + }).focus(function () + { + if (p.disabled || p.readonly) return; + g.wrapper.addClass("l-text-focus"); + }).change(function () + { + g.trigger('changeValue', [this.value]); + }); + g.wrapper.hover(function () + { + if (p.disabled || p.readonly) return; + g.wrapper.addClass("l-text-over"); + }, function () + { + if (p.disabled || p.readonly) return; + g.wrapper.removeClass("l-text-over"); + }); + g.resizing = false; + g.selectBox.hover(null, function (e) + { + if (p.hideOnLoseFocus && g.selectBox.is(":visible") && !g.boxToggling && !g.resizing) + { + g._toggleSelectBox(true); + } + }); + //下拉框内容初始化 + g.bulidContent(); + + g.set(p, null, "init"); + //下拉框宽度、高度初始化 + if (p.selectBoxWidth) + { + g.selectBox.width(p.selectBoxWidth); + } + else + { + g.selectBox.css('width', g.wrapper.css('width')); + } + if (p.grid) + { + if (p.delayLoadGrid) + { + g.bind('show', function () + { + if (!g.grid) + { + g.setGrid(p.grid); + g.set('SelectBoxHeight', p.selectBoxHeight); + } + }); + } + else + { + if (!g.grid) + { + g.setGrid(p.grid); + g.set('SelectBoxHeight', p.selectBoxHeight); + } + } + } + g.updateSelectBoxPosition(); + $(document).bind("click.combobox", function (e) + { + //修改点击空白处隐藏下拉框功能 + if (g.selectBox.is(":visible") && $((e.target || e.srcElement)).closest(".l-box-select, .l-text-combobox").length == 0) + { + g._toggleSelectBox(true); + } + }); + }, + destroy: function () + { + if (this.wrapper) this.wrapper.remove(); + if (this.selectBox) this.selectBox.remove(); + this.options = null; + $.ligerui.remove(this); + }, + clear: function () + { + this._changeValue("", ""); + $("a.l-checkbox-checked", this.selectBox).removeClass("l-checkbox-checked"); + $("td.l-selected", this.selectBox).removeClass("l-selected"); + $(":checkbox", this.selectBox).each(function () { this.checked = false; }); + this.trigger('clear'); + }, + _setSelectBoxHeight: function (height) + { + if (!height) return; + var g = this, p = this.options; + if (p.grid) + { + g.grid && g.grid.set('height', g.getGridHeight(height)); + } else if (!p.tree) + { + var itemsleng = $("tr", g.selectBox.table).length; + if (!p.selectBoxHeight && itemsleng < 8) p.selectBoxHeight = itemsleng * 30; + if (p.selectBoxHeight) + { + if (itemsleng < 8) + { + g.selectBoxInner.height('auto'); + } else + { + g.selectBoxInner.height(p.selectBoxHeight); + } + } + } else + { + g.selectBoxInner.height(p.selectBoxHeight); + } + }, + _setCss: function (css) + { + if (css) + { + this.wrapper.addClass(css); + } + }, + //取消选择 + _setCancelable: function (value) + { + var g = this, p = this.options; + if (!value && g.unselect) + { + g.unselect.remove(); + g.unselect = null; + } + if (!value && !g.unselect) return; + g.unselect = $('<div class="l-trigger l-trigger-cancel"><div class="l-trigger-icon"></div></div>').hide(); + g.wrapper.hover(function () + { + g.unselect.show(); + }, function () + { + g.unselect.hide(); + }) + if (!p.disabled && !p.readonly && p.cancelable) + { + g.wrapper.append(g.unselect); + } + g.unselect.hover(function () + { + this.className = "l-trigger-hover l-trigger-cancel"; + }, function () + { + this.className = "l-trigger l-trigger-cancel"; + }).click(function () + { + g.clear(); + }); + }, + _setDisabled: function (value) + { + //禁用样式 + if (value) + { + this.wrapper.addClass('l-text-disabled'); + } else + { + this.wrapper.removeClass('l-text-disabled'); + } + }, + _setReadonly: function (readonly) + { + if (readonly) + { + this.wrapper.addClass("l-text-readonly"); + } else + { + this.wrapper.removeClass("l-text-readonly"); + } + }, + _setLable: function (label) + { + var g = this, p = this.options; + if (label) + { + if (g.labelwrapper) + { + g.labelwrapper.find(".l-text-label:first").html(label + ':&nbsp'); + } + else + { + g.labelwrapper = g.textwrapper.wrap('<div class="l-labeltext"></div>').parent(); + g.labelwrapper.prepend('<div class="l-text-label" style="float:left;display:inline;">' + label + ':&nbsp</div>'); + g.textwrapper.css('float', 'left'); + } + if (!p.labelWidth) + { + p.labelWidth = $('.l-text-label', g.labelwrapper).outerWidth(); + } + else + { + $('.l-text-label', g.labelwrapper).outerWidth(p.labelWidth); + } + $('.l-text-label', g.labelwrapper).width(p.labelWidth); + $('.l-text-label', g.labelwrapper).height(g.wrapper.height()); + g.labelwrapper.append('<br style="clear:both;" />'); + if (p.labelAlign) + { + $('.l-text-label', g.labelwrapper).css('text-align', p.labelAlign); + } + g.textwrapper.css({ display: 'inline' }); + g.labelwrapper.width(g.wrapper.outerWidth() + p.labelWidth + 2); + } + }, + _setWidth: function (value) + { + var g = this, p = this.options; + if (value > 20) + { + g.wrapper.css({ width: value }); + g.inputText.css({ width: value - 20 }); + if (!p.selectBoxWidth) + { + g.selectBox.css({ width: value }); + } + } + }, + _setHeight: function (value) + { + var g = this; + if (value > 10) + { + g.wrapper.height(value); + g.inputText.height(value - 2); + } + }, + _setResize: function (resize) + { + var g = this, p = this.options; + if (p.columns) + { + return; + } + //调整大小支持 + if (resize && $.fn.ligerResizable) + { + var handles = p.selectBoxHeight ? 'e' : 'se,s,e'; + g.selectBox.ligerResizable({ + handles: handles, onStartResize: function () + { + g.resizing = true; + g.trigger('startResize'); + }, onEndResize: function () + { + g.resizing = false; + if (g.trigger('endResize') == false) + return false; + }, onStopResize: function (current, e) + { + if (g.grid) + { + if (current.newWidth) + { + g.selectBox.width(current.newWidth); + } + if (current.newHeight) + { + g.set({ selectBoxHeight: current.newHeight }); + } + g.grid.refreshSize(); + g.trigger('endResize'); + return false; + } + return true; + } + }); + g.selectBox.append("<div class='l-btn-nw-drop'></div>"); + } + }, + //查找Text,适用多选和单选 + findTextByValue: function (value) + { + var g = this, p = this.options; + if (value == null) return ""; + var texts = ""; + var contain = function (checkvalue) + { + var targetdata = value.toString().split(p.split); + for (var i = 0; i < targetdata.length; i++) + { + if (targetdata[i] == checkvalue && targetdata[i] != "") return true; + } + return false; + }; + //当combobox下拉一个grid时, 不能直接取data. 必须取grid的data. + //原写法$(g.data) 仅适用于无grid时的典型情形 + var d; + if (g.options.grid && g.options.grid.data) + d = g.options.grid.data.Rows; + else + d = g.data; + $(d).each(function (i, item) + { + var val = item[p.valueField]; + var txt = item[p.textField]; + if (contain(val)) + { + texts += txt + p.split; + } + }); + if (texts.length > 0) texts = texts.substr(0, texts.length - 1); + return texts; + }, + //查找Value,适用多选和单选 + findValueByText: function (text) + { + var g = this, p = this.options; + if (!text && text == "") return ""; + var contain = function (checkvalue) + { + var targetdata = text.toString().split(p.split); + for (var i = 0; i < targetdata.length; i++) + { + if (targetdata[i] == checkvalue) return true; + } + return false; + }; + var values = ""; + $(g.data).each(function (i, item) + { + var val = item[p.valueField]; + var txt = item[p.textField]; + if (contain(txt)) + { + values += val + p.split; + } + }); + if (values.length > 0) values = values.substr(0, values.length - 1); + return values; + }, + insertItem: function (data, index) + { + var g = this, p = this.options; + g.data = g.data || []; + g.data.splice(index, 0, data); + g.setData(g.data); + }, + addItem: function (data) + { + var g = this, p = this.options; + g.insertItem(data, (g.data || []).length); + }, + _setIsTextBoxMode : function(value){ + var g = this, p = this.options; + if (value) + { + g.inputText.removeAttr("readonly"); + } + }, + _setValue: function (value, text) + { + var g = this, p = this.options; + var isInit = false, isTriggerEvent = true; + if (text == "init") + { + text = null; + isInit = true; + isTriggerEvent = p.initIsTriggerEvent ? true : false; + } + if (p.isTextBoxMode) + { + text = value; + } else + { + text = text || g.findTextByValue(value); + } + if (p.tree) + { + + //刷新树的选中状态 + setTimeout(function () + { + if (p.setTextBySource) + { + //刷新树的选中状态并更新文本框 + g.selectValueByTree(value); + } else + { + g.treeSelectInit(value); + } + }, 100); + } + else if (!p.isMultiSelect) + { + g._changeValue(value, text, isTriggerEvent); + $("tr[value='" + value + "'] td", g.selectBox).addClass("l-selected"); + $("tr[value!='" + value + "'] td", g.selectBox).removeClass("l-selected"); + } + else + { + g._changeValue(value, text, isTriggerEvent); + if (value != null) + { + var targetdata = value.toString().split(p.split); + $("table.l-table-checkbox :checkbox", g.selectBox).each(function () { this.checked = false; }); + for (var i = 0; i < targetdata.length; i++) + { + $("table.l-table-checkbox tr[value=" + targetdata[i] + "] :checkbox", g.selectBox).each(function () { this.checked = true; }); + } + } + } + if (p.selectBoxRenderUpdate) + { + p.selectBoxRenderUpdate.call(g, { + selectBox: g.selectBox, + value: value, + text: text + }); + } + }, + selectValue: function (value) + { + this._setValue(value); + }, + bulidContent: function () + { + var g = this, p = this.options; + this.clearContent(); + if (g.select) + { + g.setSelect(); + } + else if (p.tree) + { + g.setTree(p.tree); + } + }, + reload: function () + { + var g = this, p = this.options; + if (p.url) + { + g.set('url', p.url); + } + else if (g.grid) + { + g.grid.reload(); + } + }, + _setUrl: function (url,callback) + { + if (!url) return; + var g = this, p = this.options; + if (p.readonly) //只读状态不加载数据 + { + return; + } + if (p.delayLoad && !g.isAccessDelay && !g.triggerLoaded) + { + g.isAccessDelay = true;//已经有一次延时加载了 + return; + } + url = $.isFunction(url) ? url.call(g) : url; + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var parms = $.isFunction(p.parms) ? p.parms.call(g) : p.parms; + if (p.ajaxContentType == "application/json" && typeof (parms) != "string") + { + parms = liger.toJSON(parms); + } + var ajaxOp = { + type: p.ajaxType, + url: url, + data: parms, + cache: false, + dataType: 'json', + beforeSend: p.ajaxBeforeSend, + complete: p.ajaxComplete, + success: function (result) + { + var data = $.isFunction(p.dataGetter) ? data = p.dataGetter.call(g, result) : result; + data = p.dataParmName && data ? data[p.dataParmName] : data; + if (g.trigger('beforeSetData', [data]) == false) +{ + return; + } + g.setData(data); + g.trigger('success', [data]); + if ($.isFunction(callback)) callback(data); + }, + error: function (XMLHttpRequest, textStatus) + { + g.trigger('error', [XMLHttpRequest, textStatus]); + } + }; + if (p.ajaxContentType) + { + ajaxOp.contentType = p.ajaxContentType; + } + $.ajax(ajaxOp); + }, + setUrl: function (url,callback) + { + return this._setUrl(url, callback); + }, + setParm: function (name, value) + { + if (!name) return; + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + parms[name] = value; + g.set('parms', parms); + }, + clearContent: function () + { + var g = this, p = this.options; + if (!g) return; + $("table", g.selectBox).html(""); + if (!g) return; + //清除下拉框内容的时候重设高度 + g._setSelectBoxHeight(p.selectBoxHeight); + //modify end + //g.inputText.val(""); + //g.valueField.val(""); + }, + setSelect: function () + { + var g = this, p = this.options; + this.clearContent(); + g.data = []; + $('option', g.select).each(function (i) + { + var val = $(this).val(); + var txt = $(this).html(); + g.data.push({ + text: txt, + id: val + }); + var tr = $("<tr><td index='" + i + "' value='" + val + "' text='" + txt + "'>" + txt + "</td>"); + $("table.l-table-nocheckbox", g.selectBox).append(tr); + + $("td", tr).hover(function () + { + $(this).addClass("l-over").siblings("td").removeClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + }); + $('td:eq(' + g.select[0].selectedIndex + ')', g.selectBox).each(function () + { + if ($(this).hasClass("l-selected")) + { + g.selectBox.hide(); + return; + } + $(".l-selected", g.selectBox).removeClass("l-selected"); + $(this).addClass("l-selected"); + if (g.select[0].selectedIndex != $(this).attr('index') && g.select[0].onchange) + { + g.select[0].selectedIndex = $(this).attr('index'); g.select[0].onchange(); + } + var newIndex = parseInt($(this).attr('index')); + g.select[0].selectedIndex = newIndex; + g.select.trigger("change"); + g.selectBox.hide(); + var value = $(this).attr("value"); + var text = $(this).html(); + if (p.render) + { + g.inputText.val(p.render(value, text)); + } + else + { + g.inputText.val(text); + } + }); + g._addClickEven(); + }, + _setData: function (data) + { + this.setData(data); + }, + getRowIndex : function(value) + { + var g = this, p = this.options; + if (!value) return -1; + if (!g.data || !g.data.length) return -1; + for (var i = 0; i < g.data.length; i++) + { + if (g.data[i] == null) continue; + var val = g.data[i][p.valueField]; + if (val == value) return i; + } + return -1; + }, + //获取行数据 + getRow : function(value) + { + var g = this, p = this.options; + if (!value) return null; + if (!g.data || !g.data.length) return null; + for (var i = 0; i < g.data.length; i++) + { + if (g.data[i] == null) continue; + var val = g.data[i][p.valueField]; + if (val == value) return g.data[i]; + } + return null; + }, + setData: function (data) + { + var g = this, p = this.options; + if (g.select) return; + if (p.selectBoxRender) + { + p.selectBoxRender.call(g, { + selectBox: g.selectBox, + data : data + }); + return; + } + if (!data || !data.length) data = []; + if (g.data != data) g.data = data; + g.data = $.isFunction(g.data) ? g.data() : g.data; + this.clearContent(); + if (p.columns) + { + g.selectBox.table.headrow = $("<tr class='l-table-headerow'><td width='18px'></td></tr>"); + g.selectBox.table.append(g.selectBox.table.headrow); + g.selectBox.table.addClass("l-box-select-grid"); + for (var j = 0; j < p.columns.length; j++) + { + var headrow = $("<td columnindex='" + j + "' columnname='" + p.columns[j].name + "'>" + p.columns[j].header + "</td>"); + if (p.columns[j].width) + { + headrow.width(p.columns[j].width); + } + g.selectBox.table.headrow.append(headrow); + + } + } + var out = []; + if (p.emptyText) + { + g.emptyRow = {}; + g.emptyRow[p.textField] = p.emptyText; + g.emptyRow[p.valueField] = p.emptyValue != undefined ? p.emptyValue : ""; + data.splice(0, 0, g.emptyRow); + } + for (var i = 0; i < data.length; i++) + { + var val = data[i][p.valueField]; + var txt = data[i][p.textField]; + var isRowReadOnly = $.isFunction(p.isRowReadOnly) ? p.isRowReadOnly(data[i]) : false; + if (!p.columns) + { + out.push("<tr value='" + val + "'"); + + var cls = []; + if (isRowReadOnly) cls.push(" rowreadonly "); + if ($.isFunction(p.rowClsRender)) cls.push(p.rowClsRender(data[i])); + if (cls.length) + { + out.push(" class='"); + out.push(cls.join('')); + out.push("'"); + } + out.push(">"); + if (p.isShowCheckBox) + { + out.push("<td style='width:18px;' index='" + i + "' value='" + val + "' text='" + txt + "' ><input type='checkbox' /></td>"); + } + var itemHtml = txt; + if (p.renderItem) + { + itemHtml = p.renderItem.call(g, { + data: data[i], + value: val, + text: txt, + key: g.inputText.val() + }); + } else if (p.autocomplete && p.highLight) + { + itemHtml = g._highLight(txt, g.inputText.val()); + } else + { + itemHtml = "<span>" + itemHtml + "</span>"; + } + out.push("<td index='" + i + "' value='" + val + "' text='" + txt + "' align='left'>" + itemHtml + "</td></tr>"); + } else + { + out.push("<tr value='" + val + "'"); + if (isRowReadOnly) out.push(" class='rowreadonly'"); + out.push(">"); + out.push("<td style='width:18px;' index='" + i + "' value='" + val + "' text='" + txt + "' ><input type='checkbox' /></td>"); + for (var j = 0; j < p.columns.length; j++) + { + var columnname = p.columns[j].name; + out.push("<td>" + data[i][columnname] + "</td>"); + } + out.push('</tr>'); + } + } + if (!p.columns) + { + if (p.isShowCheckBox) + { + $("table.l-table-checkbox", g.selectBox).append(out.join('')); + } else + { + $("table.l-table-nocheckbox", g.selectBox).append(out.join('')); + } + } else + { + g.selectBox.table.append(out.join('')); + } + if (p.addRowButton && p.addRowButtonClick && !g.addRowButton) + { + g.addRowButton = $('<div class="l-box-select-add"><a href="javascript:void(0)" class="link"><div class="icon"></div></a></div>'); + g.addRowButton.find(".link").append(p.addRowButton).click(p.addRowButtonClick); + g.selectBoxInner.after(g.addRowButton); + } + g.set('selectBoxHeight', p.selectBoxHeight); + //自定义复选框支持 + if (p.isShowCheckBox && $.fn.ligerCheckBox) + { + $("table input:checkbox", g.selectBox).ligerCheckBox(); + } + $(".l-table-checkbox input:checkbox", g.selectBox).change(function () + { + if (this.checked && g.hasBind('beforeSelect')) + { + var parentTD = null; + if ($(this).parent().get(0).tagName.toLowerCase() == "div") + { + parentTD = $(this).parent().parent(); + } else + { + parentTD = $(this).parent(); + } + if (parentTD != null && g.trigger('beforeSelect', [parentTD.attr("value"), parentTD.attr("text")]) == false) + { + g.selectBox.slideToggle("fast"); + return false; + } + } + if (!p.isMultiSelect) + { + if (this.checked) + { + $("input:checked", g.selectBox).not(this).each(function () + { + this.checked = false; + $(".l-checkbox-checked", $(this).parent()).removeClass("l-checkbox-checked"); + }); + g.selectBox.slideToggle("fast"); + } + } + g._checkboxUpdateValue(); + }); + $("table.l-table-nocheckbox td", g.selectBox).hover(function () + { + if (!$(this).parent().hasClass("rowreadonly")) + { + $(this).addClass("l-over"); + } + }, function () + { + $(this).removeClass("l-over"); + }); + g._addClickEven(); + //选择项初始化 + if (!p.autocomplete) + { + g.updateStyle(); + } + + g.trigger('afterShowData', [data]); + }, + //树 + setTree: function (tree) + { + var g = this, p = this.options; + this.clearContent(); + g.selectBox.table.remove(); + if (tree.checkbox != false) + { + tree.onCheck = function () + { + var nodes = g.treeManager.getChecked(); + var value = []; + var text = []; + $(nodes).each(function (i, node) + { + if (p.treeLeafOnly && node.data.children) return; + value.push(node.data[p.valueField]); + text.push(node.data[p.textField]); + }); + g._changeValue(value.join(p.split), text.join(p.split), true); + }; + } + else + { + tree.onSelect = function (node) + { + if (g.trigger('BeforeSelect',[node]) == false) return; + if (p.treeLeafOnly && node.data.children) return; + var value = node.data[p.valueField]; + var text = node.data[p.textField]; + g._changeValue(value, text,true); + g.selectBox.hide(); + }; + tree.onCancelSelect = function (node) + { + g._changeValue("", "", true); + }; + } + tree.onAfterAppend = function (domnode, nodedata) + { + if (!g.treeManager) return; + var value = null; + if (p.initValue) value = p.initValue; + else if (g.valueField.val() != "") value = g.valueField.val(); + g.selectValueByTree(value); + }; + g.tree = $("<ul></ul>"); + $("div:first", g.selectBox).append(g.tree); + //新增下拉框中获取树对象的接口 + g.innerTree = g.tree.ligerTree(tree); + g.treeManager = g.tree.ligerGetTreeManager(); + }, + //新增下拉框中获取树对象的接口 + getTree: function () + { + return this.innerTree; + }, + selectValueByTree: function (value) + { + var g = this, p = this.options; + if (value != null) + { + var text = g.treeSelectInit(value); + + g._changeValue(value, text, p.initIsTriggerEvent); + } + }, + //Tree选择状态初始化 + treeSelectInit: function (value) + { + var g = this, p = this.options; + if (value != null) + { + var text = ""; + var valuelist = value.toString().split(p.split); + $(valuelist).each(function (i, item) + { + g.treeManager.selectNode(item.toString(), false); + text += g.treeManager.getTextByID(item); + if (i < valuelist.length - 1) text += p.split; + }); + return text; + } + }, + //表格 + setGrid: function (grid) + { + var g = this, p = this.options; + if (g.grid) return; + p.hideOnLoseFocus = p.hideGridOnLoseFocus ? true : false; + this.clearContent(); + g.selectBox.addClass("l-box-select-lookup"); + g.selectBox.table.remove(); + var panel = $("div:first", g.selectBox); + var conditionPanel = $("<div></div>").appendTo(panel); + var gridPanel = $("<div></div>").appendTo(panel); + g.conditionPanel = conditionPanel; + //搜索框 + if (p.condition) + { + var conditionParm = $.extend({ + labelWidth: 60, + space: 20, + width: p.selectBoxWidth + }, p.condition); + g.condition = conditionPanel.ligerForm(conditionParm); + } else + { + conditionPanel.remove(); + } + //列表 + grid = $.extend({ + columnWidth: 120, + alternatingRow: false, + frozen: true, + rownumbers: true, + allowUnSelectRow: true + }, grid, { + width: "100%", + height: g.getGridHeight(), + inWindow: false, + parms: p.parms, + isChecked: function (rowdata) + { + var value = g.getValue(); + if (!value) return false; + if (!p.valueField || !rowdata[p.valueField]) return false; + return $.inArray(rowdata[p.valueField].toString(), value.split(p.split)) != -1; + } + }); + g.grid = g.gridManager = gridPanel.ligerGrid(grid); + g.grid.bind('afterShowData', function () + { + g.updateSelectBoxPosition(); + }); + var selecteds = [], onGridSelect = function () + { + var value = [], text = []; + $(selecteds).each(function (i, rowdata) + { + value.push(rowdata[p.valueField]); + text.push(rowdata[p.textField]); + }); + if (grid.checkbox) + g.selected = selecteds; + else if (selecteds.length) + g.selected = selecteds[0]; + else + g.selected = null; + g._changeValue(value.join(p.split), text.join(p.split),true); + g.trigger('gridSelect', { + value: value.join(p.split), + text: text.join(p.split), + data: selecteds + }); + }, removeSelected = function (rowdata) + { + for (var i = selecteds.length - 1; i >= 0; i--) + { + if (selecteds[i][p.valueField] == rowdata[p.valueField]) + { + selecteds.splice(i, 1); + } + } + }, addSelected = function (rowdata) + { + for (var i = selecteds.length - 1; i >= 0; i--) + { + if (selecteds[i][p.valueField] == rowdata[p.valueField]) + { + return; + } + } + selecteds.push(rowdata); + }; + if (grid.checkbox) + { + var onCheckRow = function (checked, rowdata) + { + checked && addSelected(rowdata); + !checked && removeSelected(rowdata); + }; + g.grid.bind('CheckAllRow', function (checked) + { + $(g.grid.rows).each(function (i, rowdata) + { + onCheckRow(checked, rowdata); + }); + onGridSelect(); + }); + g.grid.bind('CheckRow', function (checked, rowdata) + { + onCheckRow(checked, rowdata); + onGridSelect(); + }); + } + else + { + g.grid.bind('SelectRow', function (rowdata) + { + selecteds = [rowdata]; + onGridSelect(); + g._toggleSelectBox(true); + }); + g.grid.bind('UnSelectRow', function () + { + selecteds = []; + onGridSelect(); + }); + } + g.bind('show', function () + { + g.grid.refreshSize(); + }); + g.bind("clear", function () + { + selecteds = []; + g.grid.selecteds = []; + g.grid._showData(); + }); + if (p.condition) + { + var containerBtn1 = $('<li style="margin-right:9px"><div></div></li>'); + var containerBtn2 = $('<li style="margin-right:9px;float:right"><div></div></li>'); + $("ul:first", conditionPanel).append(containerBtn1).append(containerBtn2).after('<div class="l-clear"></div>'); + $("div", containerBtn1).ligerButton({ + text: p.Search, width: 40, + click: function () + { + var rules = g.condition.toConditions(); + if (p.conditionSearchClick) + { + p.conditionSearchClick({ + grid: g.grid, + rules: rules + }); + } else + { + if (g.grid.get('url')) + { + g.grid.setParm(grid.conditionParmName || 'condition', $.ligerui.toJSON(rules)); + g.grid.reload(); + } else + { + g.grid.loadData($.ligerFilter.getFilterFunction(rules)); + } + } + } + }); + $("div", containerBtn2).ligerButton({ + text: '关闭', width: 40, + click: function () + { + g.selectBox.hide(); + } + }); + } + g.grid.refreshSize(); + }, + getGridHeight: function (height) + { + var g = this, p = this.options; + height = height || g.selectBox.height(); + height -= g.conditionPanel.height(); + return height; + }, + _getValue: function () + { + + var g = this, p = this.options; + if (p.isTextBoxMode) + { + return g.inputText.val(); + } + return $(this.valueField).val(); + }, + getValue: function () + { + //获取值 + return this._getValue(); + }, + getSelected: function () + { + return this.selected; + }, + + upFocus : function() + { + var g = this, p = this.options; + if (g.grid) + { + if (!g.grid.rows || !g.grid.rows.length) return; + var selected = g.grid.getSelected(); + if (selected) + { + var index = $.inArray(selected, g.grid.rows); + if (index - 1 < g.grid.rows.length) + { + g.grid.unselect(selected); + g.grid.select(g.grid.rows[index - 1]); + } + } + else + { + g.grid.select(g.grid.rows[0]); + } + + } else + { + var currentIndex = g.selectBox.table.find("td.l-over").attr("index"); + if (currentIndex == undefined || currentIndex == "0") + { + return; + } + else + { + currentIndex = parseInt(currentIndex) - 1; + } + g.selectBox.table.find("td.l-over").removeClass("l-over"); + g.selectBox.table.find("td[index=" + currentIndex + "]").addClass("l-over"); + + g._scrollAdjust(currentIndex); + } + }, + downFocus : function() + { + var g = this, p = this.options; + if (g.grid) + { + if (!g.grid.rows || !g.grid.rows.length) return; + var selected = g.grid.getSelected(); + if (selected) + { + var index = $.inArray(selected, g.grid.rows); + if (index + 1 < g.grid.rows.length) + { + g.grid.unselect(selected); + g.grid.select(g.grid.rows[index + 1]); + } + } + else + { + g.grid.select(g.grid.rows[0]); + } + + } else + { + var currentIndex = g.selectBox.table.find("td.l-over").attr("index"); + if (currentIndex == g.data.length - 1) return; + if (currentIndex == undefined) + { + currentIndex = 0; + } + else + { + currentIndex = parseInt(currentIndex) + 1; + } + g.selectBox.table.find("td.l-over").removeClass("l-over"); + g.selectBox.table.find("td[index=" + currentIndex + "]").addClass("l-over"); + + g._scrollAdjust(currentIndex); + } + }, + + + _scrollAdjust:function(currentIndex) + { + var g = this, p = this.options; + var boxHeight = $(".l-box-select-inner", g.selectBox).height(); + var fullHeight = $(".l-box-select-inner table", g.selectBox).height(); + if (fullHeight <= boxHeight) return; + var pageSplit = parseInt(fullHeight / boxHeight) + ((fullHeight % boxHeight) ? 1 : 0);//分割成几屏 + var itemHeight = fullHeight / g.data.length; //单位高度 + //计算出位于第几屏 + var pageCurrent = parseInt((currentIndex + 1) * itemHeight / boxHeight) + (((currentIndex + 1) * itemHeight % boxHeight) ? 1 : 0); + $(".l-box-select-inner", g.selectBox).scrollTop((pageCurrent - 1) * boxHeight); + }, + + getText: function () + { + return this.inputText.val(); + }, + setText: function (value) + { + var g = this, p = this.options; + if (p.isTextBoxMode) return; + g.inputText.val(value); + }, + updateStyle: function () + { + var g = this, p = this.options; + p.initValue = g._getValue(); + g._dataInit(); + }, + _dataInit: function () + { + var g = this, p = this.options; + var value = null; + if (p.initValue != null && p.initText != null) + { + g._changeValue(p.initValue, p.initText); + } + //根据值来初始化 + if (p.initValue != null) + { + value = p.initValue; + if (p.tree) + { + if (value) + g.selectValueByTree(value); + } + else if (g.data) + { + var text = g.findTextByValue(value); + g._changeValue(value, text); + } + } + else if (g.valueField.val() != "") + { + value = g.valueField.val(); + if (p.tree) + { + if (value) + g.selectValueByTree(value); + } + else if (g.data) + { + var text = g.findTextByValue(value); + g._changeValue(value, text); + } + } + if (!p.isShowCheckBox) + { + $("table tr", g.selectBox).find("td:first").each(function () + { + if (value != null && value == $(this).attr("value")) + { + $(this).addClass("l-selected"); + } else + { + $(this).removeClass("l-selected"); + } + }); + } + else + { + $(":checkbox", g.selectBox).each(function () + { + var parentTD = null; + var checkbox = $(this); + if (checkbox.parent().get(0).tagName.toLowerCase() == "div") + { + parentTD = checkbox.parent().parent(); + } else + { + parentTD = checkbox.parent(); + } + if (parentTD == null) return; + $(".l-checkbox", parentTD).removeClass("l-checkbox-checked"); + checkbox[0].checked = false; + var valuearr = (value || "").toString().split(p.split); + $(valuearr).each(function (i, item) + { + if (value != null && item == parentTD.attr("value")) + { + $(".l-checkbox", parentTD).addClass("l-checkbox-checked"); + checkbox[0].checked = true; + } + }); + }); + } + }, + //设置值到 文本框和隐藏域 + //isSelectEvent:是否选择事件 + _changeValue: function (newValue, newText,isSelectEvent) + { + var g = this, p = this.options; + g.valueField.val(newValue); + if (p && p.render) + { + g.inputText.val(p.render(newValue, newText)); + } + else + { + g.inputText.val(newText); + } + if (g.select) + { + $("option", g.select).each(function () + { + $(this).attr("selected", $(this).attr("value") == newValue); + }); + } + g.selectedValue = newValue; + g.selectedText = newText; + + g.inputText.trigger("change"); + + if (isSelectEvent && newText) + { + g.inputText.focus(); + } + + var rowData = null; + if (newValue && typeof(newValue) == "string" && newValue.indexOf(p.split) > -1) + { + rowData = []; + var values = newValue.split(p.split); + $(values).each(function (i, v) + { + rowData.push(g.getRow(v)); + }); + } + else if(newValue) + { + rowData = g.getRow(newValue); + } + if (isSelectEvent) + { + g.trigger('selected', [newValue, newText, rowData]); + } + }, + //更新选中的值(复选框) + _checkboxUpdateValue: function () + { + var g = this, p = this.options; + var valueStr = ""; + var textStr = ""; + $("input:checked", g.selectBox).each(function () + { + var parentTD = null; + if ($(this).parent().get(0).tagName.toLowerCase() == "div") + { + parentTD = $(this).parent().parent(); + } else + { + parentTD = $(this).parent(); + } + if (!parentTD) return; + valueStr += parentTD.attr("value") + p.split; + textStr += parentTD.attr("text") + p.split; + }); + if (valueStr.length > 0) valueStr = valueStr.substr(0, valueStr.length - 1); + if (textStr.length > 0) textStr = textStr.substr(0, textStr.length - 1); + g._changeValue(valueStr, textStr); + }, + loadDetail : function(value,callback) + { + var g = this, p = this.options; + var parms = $.isFunction(p.detailParms) ? p.detailParms.call(g) : p.detailParms; + parms[p.detailPostIdField || "id"] = value; + if (p.ajaxContentType == "application/json") + { + parms = liger.toJSON(parms); + } + var ajaxOp = { + type: p.ajaxType, + url: p.detailUrl, + data: parms, + cache: true, + dataType: 'json', + beforeSend: p.ajaxBeforeSend, + complete: p.ajaxComplete, + success: function (result) +{ + var data = $.isFunction(p.detailDataGetter) ? p.detailDataGetter(result) : result; + data = p.detailDataParmName ? data[p.detailDataParmName] : data; + callback && callback(data); + } + }; + + if (p.ajaxContentType) + { + ajaxOp.contentType = p.ajaxContentType; + } + $.ajax(ajaxOp); + + }, + enabledLoadDetail : function() + { + var g = this, p = this.options; + return p.detailUrl && p.detailEnabled ? true : false; + }, + _addClickEven: function () + { + var g = this, p = this.options; + //选项点击 + $(".l-table-nocheckbox td", g.selectBox).click(function () + { + var jcell = $(this); + var value = jcell.attr("value"); + var index = parseInt($(this).attr('index')); + var data = g.data[index]; + var text = jcell.attr("text"); + var isRowReadonly = jcell.parent().hasClass("rowreadonly"); + if (isRowReadonly) return; + + if (g.enabledLoadDetail()) + { + g.loadDetail(value,function (rd) + { + g.data[index] = data = rd; + onItemClick(); + }); + } else + { + onItemClick(); + } + function onItemClick() + { + if (g.hasBind('beforeSelect') && g.trigger('beforeSelect', [value, text, data]) == false) + { + if (p.slide) g.selectBox.slideToggle("fast"); + else g.selectBox.hide(); + return false; + } + g.selected = data; + if ($(this).hasClass("l-selected")) + { + if (p.slide) g.selectBox.slideToggle("fast"); + else g.selectBox.hide(); + return; + } + $(".l-selected", g.selectBox).removeClass("l-selected"); + jcell.addClass("l-selected"); + if (g.select) + { + if (g.select[0].selectedIndex != index) + { + g.select[0].selectedIndex = index; + g.select.trigger("change"); + } + } + if (p.slide) + { + g.boxToggling = true; + g.selectBox.hide("fast", function () + { + g.boxToggling = false; + }) + } else g.selectBox.hide(); + g.lastInputText = text; + g._changeValue(value, text, true); + } + }); + }, + updateSelectBoxPosition: function () + { + var g = this, p = this.options; + if (p && p.absolute) + { + var contentHeight = $(document).height(); + if (p.alwayShowInTop || Number(g.wrapper.offset().top + 1 + g.wrapper.outerHeight() + g.selectBox.height()) > contentHeight + && contentHeight > Number(g.selectBox.height() + 1)) + { + //若下拉框大小超过当前document下边框,且当前document上留白大于下拉内容高度,下拉内容向上展现 + g.selectBox.css({ left: g.wrapper.offset().left, top: g.wrapper.offset().top - 1 - g.selectBox.height() + (p.selectBoxPosYDiff || 0) }); + } else + { + g.selectBox.css({ left: g.wrapper.offset().left, top: g.wrapper.offset().top + 1 + g.wrapper.outerHeight() + (p.selectBoxPosYDiff || 0) }); + } + if (p.alwayShowInDown) + { + g.selectBox.css({ left: g.wrapper.offset().left, top: g.wrapper.offset().top + 1 + g.wrapper.outerHeight() }); + } + } + else + { + var topheight = g.wrapper.offset().top - $(window).scrollTop(); + var selfheight = g.selectBox.height() + textHeight + 4; + if (topheight + selfheight > $(window).height() && topheight > selfheight) + { + g.selectBox.css("marginTop", -1 * (g.selectBox.height() + textHeight + 5) + (p.selectBoxPosYDiff || 0)); + } + } + }, + _toggleSelectBox: function (isHide) + { + var g = this, p = this.options; + + if (!g || !p) return; + //避免同一界面弹出多个菜单的问题 + var managers = $.ligerui.find($.ligerui.controls.ComboBox); + for (var i = 0, l = managers.length; i < l; i++) + { + var o = managers[i]; + if (o.id != g.id) + { + if (o.selectBox.is(":visible") != null && o.selectBox.is(":visible")) + { + o.selectBox.hide(); + } + } + } + managers = $.ligerui.find($.ligerui.controls.DateEditor); + for (var i = 0, l = managers.length; i < l; i++) + { + var o = managers[i]; + if (o.id != g.id) + { + if (o.dateeditor.is(":visible") != null && o.dateeditor.is(":visible")) + { + o.dateeditor.hide(); + } + } + } + var textHeight = g.wrapper.height(); + g.boxToggling = true; + if (isHide) + { + if (p.slide) + { + g.selectBox.slideToggle('fast', function () + { + g.boxToggling = false; + }); + } + else + { + g.selectBox.hide(); + g.boxToggling = false; + } + } + else + { + g.updateSelectBoxPosition(); + if (p.slide) + { + g.selectBox.slideToggle('fast', function () + { + g.boxToggling = false; + if (!p.isShowCheckBox && $('td.l-selected', g.selectBox).length > 0) + { + var offSet = ($('td.l-selected', g.selectBox).offset().top - g.selectBox.offset().top); + $(".l-box-select-inner", g.selectBox).animate({ scrollTop: offSet }); + } + }); + } + else + { + g._selectBoxShow(); + g.boxToggling = false; + if (!g.tree && !g.grid && !p.isShowCheckBox && $('td.l-selected', g.selectBox).length > 0) + { + var offSet = ($('td.l-selected', g.selectBox).offset().top - g.selectBox.offset().top); + $(".l-box-select-inner", g.selectBox).animate({ scrollTop: offSet }); + } + } + } + g.isShowed = g.selectBox.is(":visible"); + g.trigger('toggle', [isHide]); + g.trigger(isHide ? 'hide' : 'show'); + }, + _selectBoxShow : function() + { + var g = this, p = this.options; + + if (p.readonly) return; + if (!p.grid && !p.tree) + { + if (g.selectBox.table.find("tr").length || (p.selectBoxRender && g.selectBoxInner.html())) + { + g.selectBox.show(); + } else + { + g.selectBox.hide(); + } + return; + } + g.selectBox.show(); + return; + }, + _highLight: function (str, key) + { + if (!str) return str; + var index = str.indexOf(key); + if (index == -1) return str; + return str.substring(0, index) + "<span class='l-highLight'>" + key + "</span>" + str.substring(key.length + index); + }, + _setAutocomplete: function (value) + { + var g = this, p = this.options; + if (!value) return; + if (p.readonly) return; + g.inputText.removeAttr("readonly"); + g.lastInputText = g.inputText.val(); + g.inputText.keyup(function (event) + { + if (event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13) //up 、down、enter + { + return; + } + if (this._acto) + clearTimeout(this._acto); + this._acto = setTimeout(function () + { + if (g.lastInputText == g.inputText.val()) return; + + + + + var currentKey = g.inputText.val(); + if (currentKey) + { + currentKey = currentKey.replace(/(^\s*)|(\s*$)/g, ""); + } + else + { + p.initValue = ""; + g.valueField.val(""); + } + + g.lastInputText = g.inputText.val(); + + if ($.isFunction(value)) + { + value.call(g, { + key: currentKey, + show: function () + { + g._selectBoxShow(); + } + }); + return; + } + if (!p.autocompleteAllowEmpty && !currentKey) + { + g.clear(); + g.selectBox.hide(); + return; + } + if (p.url) + { + g.setParm('key', currentKey); + g.setUrl(p.url, function () + { + g._selectBoxShow(); + }); + } else if (p.grid) + { + g.grid.setParm('key', currentKey); + g.grid.reload(); + } + + this._acto = null; + }, 300); + }); + } + }); + + $.ligerui.controls.ComboBox.prototype.setValue = $.ligerui.controls.ComboBox.prototype.selectValue; + //设置文本框和隐藏控件的值 + $.ligerui.controls.ComboBox.prototype.setInputValue = $.ligerui.controls.ComboBox.prototype._changeValue; + + + //Key Init + (function () + { + $(document).unbind('keydown.ligercombobox'); + $(document).bind('keydown.ligercombobox',function (event) + { + function down() + { + if (!combobox.selectBox.is(":visible")) + { + combobox.selectBox.show(); + } + combobox.downFocus(); + } + function toSelect() + { + if (!curGridSelected) + { + combobox._changeValue(value, curTd.attr("text"), true); + combobox.selectBox.hide(); + combobox.trigger('textBoxKeyEnter', [{ + element: curTd.get(0) + }]); + } + else + { + combobox._changeValue(curGridSelected[combobox_op.valueField], curGridSelected[combobox_op.textField], true); + + combobox.selectBox.hide(); + combobox.trigger('textBoxKeyEnter', [{ + rowdata: curGridSelected + }]); + } + } + var curInput = $("input:focus"); + if (curInput.length && curInput.attr("data-comboboxid")) + { + var combobox = liger.get(curInput.attr("data-comboboxid")); + if (!combobox) return; + var combobox_op = combobox.options; + if (!combobox.get("keySupport")) return; + if (event.keyCode == 38) //up + { + combobox.upFocus(); + } else if (event.keyCode == 40) //down + { + if (combobox.hasBind('textBoxKeyDown')) + { + combobox.trigger('textBoxKeyDown', [ + { + callback: function () + { + down(); + } + }]); + } + else + { + down(); + } + } + else if (event.keyCode == 13) //enter + { + if (!combobox.selectBox.is(":visible")) return; + var curGridSelected = null; + if (combobox.grid) + { + curGridSelected = combobox.grid.getSelected(); + + } + var curTd = combobox.selectBox.table.find("td.l-over"); + if (curGridSelected || curTd.length) + { + var value = curTd.attr("value"); + if (curGridSelected && curGridSelected.ID) value = curGridSelected.ID; + + if (combobox.enabledLoadDetail()) + { + combobox.loadDetail(value, function (data) + { + if (!curGridSelected) + { + var index = combobox.getRowIndex(value); + if (index == -1) return; + combobox.data = combobox.data || []; + combobox.data[index] = combobox.selected = data; + } + toSelect(); + }); + } else + { + toSelect(); + } + + } + + } + } + }); + + })(); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerDateEditor = function () + { + return $.ligerui.run.call(this, "ligerDateEditor", arguments); + }; + + $.fn.ligerGetDateEditorManager = function () + { + return $.ligerui.run.call(this, "ligerGetDateEditorManager", arguments); + }; + + $.ligerDefaults.DateEditor = { + format: "yyyy-MM-dd hh:mm", + width : null, + showTime: false, + onChangeDate: false, + absolute: true, //选择框是否在附加到body,并绝对定位 + cancelable: true, //可取消选择 + readonly: false //是否只读 + }; + $.ligerDefaults.DateEditorString = { + dayMessage: ["日", "一", "二", "三", "四", "五", "六"], + monthMessage: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + todayMessage: "今天", + closeMessage: "关闭" + }; + $.ligerMethos.DateEditor = {}; + + $.ligerui.controls.DateEditor = function (element, options) + { + $.ligerui.controls.DateEditor.base.constructor.call(this, element, options); + }; + $.ligerui.controls.DateEditor.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'DateEditor'; + }, + __idPrev: function () + { + return 'DateEditor'; + }, + _extendMethods: function () + { + return $.ligerMethos.DateEditor; + }, + _render: function () + { + var g = this, p = this.options; + if (!p.showTime && p.format.indexOf(" hh:mm") > -1) + p.format = p.format.replace(" hh:mm", ""); + if (this.element.tagName.toLowerCase() != "input" || this.element.type != "text") + return; + g.inputText = $(this.element); + if (!g.inputText.hasClass("l-text-field")) + g.inputText.addClass("l-text-field"); + g.link = $('<div class="l-trigger"><div class="l-trigger-icon"></div></div>'); + g.text = g.inputText.wrap('<div class="l-text l-text-date"></div>').parent(); + g.text.append('<div class="l-text-l"></div><div class="l-text-r"></div>'); + g.text.append(g.link); + //添加个包裹, + g.textwrapper = g.text.wrap('<div class="l-text-wrapper"></div>').parent(); + var dateeditorHTML = ""; + dateeditorHTML += "<div class='l-box-dateeditor' style='display:none'>"; + dateeditorHTML += " <div class='l-box-dateeditor-header'>"; + dateeditorHTML += " <div class='l-box-dateeditor-header-btn l-box-dateeditor-header-prevyear'><span></span></div>"; + dateeditorHTML += " <div class='l-box-dateeditor-header-btn l-box-dateeditor-header-prevmonth'><span></span></div>"; + dateeditorHTML += " <div class='l-box-dateeditor-header-text'><a class='l-box-dateeditor-header-month'></a> , <a class='l-box-dateeditor-header-year'></a></div>"; + dateeditorHTML += " <div class='l-box-dateeditor-header-btn l-box-dateeditor-header-nextmonth'><span></span></div>"; + dateeditorHTML += " <div class='l-box-dateeditor-header-btn l-box-dateeditor-header-nextyear'><span></span></div>"; + dateeditorHTML += " </div>"; + dateeditorHTML += " <div class='l-box-dateeditor-body'>"; + dateeditorHTML += " <table cellpadding='0' cellspacing='0' border='0' class='l-box-dateeditor-calendar'>"; + dateeditorHTML += " <thead>"; + dateeditorHTML += " <tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr>"; + dateeditorHTML += " </thead>"; + dateeditorHTML += " <tbody>"; + dateeditorHTML += " <tr class='l-first'><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr><tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr><tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr><tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr><tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr><tr><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td><td align='center'></td></tr>"; + dateeditorHTML += " </tbody>"; + dateeditorHTML += " </table>"; + dateeditorHTML += " <ul class='l-box-dateeditor-monthselector'><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>"; + dateeditorHTML += " <ul class='l-box-dateeditor-yearselector'><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>"; + dateeditorHTML += " <ul class='l-box-dateeditor-hourselector'><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>"; + dateeditorHTML += " <ul class='l-box-dateeditor-minuteselector'><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>"; + dateeditorHTML += " </div>"; + dateeditorHTML += " <div class='l-box-dateeditor-toolbar'>"; + dateeditorHTML += " <div class='l-box-dateeditor-time'></div>"; + dateeditorHTML += " <div class='l-button l-button-today'></div>"; + dateeditorHTML += " <div class='l-button l-button-close'></div>"; + dateeditorHTML += " <div class='l-clear'></div>"; + dateeditorHTML += " </div>"; + dateeditorHTML += "</div>"; + g.dateeditor = $(dateeditorHTML); + if (p.absolute) + g.dateeditor.appendTo('body').addClass("l-box-dateeditor-absolute"); + else + g.textwrapper.append(g.dateeditor); + g.header = $(".l-box-dateeditor-header", g.dateeditor); + g.body = $(".l-box-dateeditor-body", g.dateeditor); + g.toolbar = $(".l-box-dateeditor-toolbar", g.dateeditor); + + g.body.thead = $("thead", g.body); + g.body.tbody = $("tbody", g.body); + g.body.monthselector = $(".l-box-dateeditor-monthselector", g.body); + g.body.yearselector = $(".l-box-dateeditor-yearselector", g.body); + g.body.hourselector = $(".l-box-dateeditor-hourselector", g.body); + g.body.minuteselector = $(".l-box-dateeditor-minuteselector", g.body); + + g.toolbar.time = $(".l-box-dateeditor-time", g.toolbar); + g.toolbar.time.hour = $("<a></a>"); + g.toolbar.time.minute = $("<a></a>"); + g.buttons = { + btnPrevYear: $(".l-box-dateeditor-header-prevyear", g.header), + btnNextYear: $(".l-box-dateeditor-header-nextyear", g.header), + btnPrevMonth: $(".l-box-dateeditor-header-prevmonth", g.header), + btnNextMonth: $(".l-box-dateeditor-header-nextmonth", g.header), + btnYear: $(".l-box-dateeditor-header-year", g.header), + btnMonth: $(".l-box-dateeditor-header-month", g.header), + btnToday: $(".l-button-today", g.toolbar), + btnClose: $(".l-button-close", g.toolbar) + }; + var nowDate = new Date(); + g.now = { + year: nowDate.getFullYear(), + month: nowDate.getMonth() + 1, //注意这里 + day: nowDate.getDay(), + date: nowDate.getDate(), + hour: nowDate.getHours(), + minute: nowDate.getMinutes() + }; + //当前的时间 + g.currentDate = { + year: nowDate.getFullYear(), + month: nowDate.getMonth() + 1, + day: nowDate.getDay(), + date: nowDate.getDate(), + hour: nowDate.getHours(), + minute: nowDate.getMinutes() + }; + //选择的时间 + g.selectedDate = null; + //使用的时间 + g.usedDate = null; + + + + //初始化数据 + //设置周日至周六 + $("td", g.body.thead).each(function (i, td) + { + $(td).html(p.dayMessage[i]); + }); + //设置一月到十一二月 + $("li", g.body.monthselector).each(function (i, li) + { + $(li).html(p.monthMessage[i]); + }); + //设置按钮 + g.buttons.btnToday.html(p.todayMessage); + g.buttons.btnClose.html(p.closeMessage); + //设置时间 + if (p.showTime) + { + g.toolbar.time.show(); + g.toolbar.time.append(g.toolbar.time.hour).append(":").append(g.toolbar.time.minute); + $("li", g.body.hourselector).each(function (i, item) + { + var str = i; + if (i < 10) str = "0" + i.toString(); + $(this).html(str); + }); + $("li", g.body.minuteselector).each(function (i, item) + { + var str = i; + if (i < 10) str = "0" + i.toString(); + $(this).html(str); + }); + } + //设置主体 + g.bulidContent(); + //初始化 + //初始值 + if (p.initValue) + { + g.inputText.val(p.initValue); + } + if (g.inputText.val() != "") + { + g.onTextChange(); + } + /************** + **bulid evens** + *************/ + g.dateeditor.hover(null, function (e) + { + if (g.dateeditor.is(":visible") && !g.editorToggling) + { + g.toggleDateEditor(true); + } + }); + //toggle even + g.link.hover(function () + { + if (p.disabled) return; + this.className = "l-trigger-hover"; + }, function () + { + if (p.disabled) return; + this.className = "l-trigger"; + }).mousedown(function () + { + if (p.disabled) return; + this.className = "l-trigger-pressed"; + }).mouseup(function () + { + if (p.disabled) return; + this.className = "l-trigger-hover"; + }).click(function () + { + if (p.disabled) return; + g.bulidContent(); + g.toggleDateEditor(g.dateeditor.is(":visible")); + }); + //不可用属性时处理 + if (p.disabled) + { + g.inputText.attr("readonly", "readonly"); + g.text.addClass('l-text-disabled'); + } + g.buttons.btnClose.click(function () + { + g.toggleDateEditor(true); + }); + //日期 点击 + $("td", g.body.tbody).hover(function () + { + if ($(this).hasClass("l-box-dateeditor-today")) return; + $(this).addClass("l-box-dateeditor-over"); + }, function () + { + $(this).removeClass("l-box-dateeditor-over"); + }).click(function () + { + $(".l-box-dateeditor-selected", g.body.tbody).removeClass("l-box-dateeditor-selected"); + if (!$(this).hasClass("l-box-dateeditor-today")) + $(this).addClass("l-box-dateeditor-selected"); + g.currentDate.date = parseInt($(this).html()); + g.currentDate.day = new Date(g.currentDate.year, g.currentDate.month - 1, 1).getDay(); + if ($(this).hasClass("l-box-dateeditor-out")) + { + if ($("tr", g.body.tbody).index($(this).parent()) == 0) + { + if (--g.currentDate.month == 0) + { + g.currentDate.month = 12; + g.currentDate.year--; + } + } else + { + if (++g.currentDate.month == 13) + { + g.currentDate.month = 1; + g.currentDate.year++; + } + } + } + g.selectedDate = { + year: g.currentDate.year, + month: g.currentDate.month, + date: g.currentDate.date + }; + g.showDate(); + g.editorToggling = true; + g.dateeditor.slideToggle('fast', function () + { + g.editorToggling = false; + }); + }); + + $(".l-box-dateeditor-header-btn", g.header).hover(function () + { + $(this).addClass("l-box-dateeditor-header-btn-over"); + }, function () + { + $(this).removeClass("l-box-dateeditor-header-btn-over"); + }); + //选择年份 + g.buttons.btnYear.click(function () + { + //build year list + if (!g.body.yearselector.is(":visible")) + { + $("li", g.body.yearselector).each(function (i, item) + { + var currentYear = g.currentDate.year + (i - 4); + if (currentYear == g.currentDate.year) + $(this).addClass("l-selected"); + else + $(this).removeClass("l-selected"); + $(this).html(currentYear); + }); + } + + g.body.yearselector.slideToggle(); + }); + g.body.yearselector.hover(function () { }, function () + { + $(this).slideUp(); + }); + $("li", g.body.yearselector).click(function () + { + g.currentDate.year = parseInt($(this).html()); + g.body.yearselector.slideToggle(); + g.bulidContent(); + }); + //select month + g.buttons.btnMonth.click(function () + { + $("li", g.body.monthselector).each(function (i, item) + { + //add selected style + if (g.currentDate.month == i + 1) + $(this).addClass("l-selected"); + else + $(this).removeClass("l-selected"); + }); + g.body.monthselector.slideToggle(); + }); + g.body.monthselector.hover(function () { }, function () + { + $(this).slideUp("fast"); + }); + $("li", g.body.monthselector).click(function () + { + var index = $("li", g.body.monthselector).index(this); + g.currentDate.month = index + 1; + g.body.monthselector.slideToggle(); + g.bulidContent(); + }); + + //选择小时 + g.toolbar.time.hour.click(function () + { + $("li", g.body.hourselector).each(function (i, item) + { + //add selected style + if (g.currentDate.hour == i) + $(this).addClass("l-selected"); + else + $(this).removeClass("l-selected"); + }); + g.body.hourselector.slideToggle(); + }); + g.body.hourselector.hover(function () { }, function () + { + $(this).slideUp("fast"); + }); + $("li", g.body.hourselector).click(function () + { + var index = $("li", g.body.hourselector).index(this); + g.currentDate.hour = index; + g.body.hourselector.slideToggle(); + g.bulidContent(); + g.showDate(); + }); + //选择分钟 + g.toolbar.time.minute.click(function () + { + $("li", g.body.minuteselector).each(function (i, item) + { + //add selected style + if (g.currentDate.minute == i) + $(this).addClass("l-selected"); + else + $(this).removeClass("l-selected"); + }); + g.body.minuteselector.slideToggle("fast", function () + { + var index = $("li", this).index($('li.l-selected', this)); + if (index > 29) + { + var offSet = ($('li.l-selected', this).offset().top - $(this).offset().top); + $(this).animate({ scrollTop: offSet }); + } + }); + }); + g.body.minuteselector.hover(function () { }, function () + { + $(this).slideUp("fast"); + }); + $("li", g.body.minuteselector).click(function () + { + var index = $("li", g.body.minuteselector).index(this); + g.currentDate.minute = index; + g.body.minuteselector.slideToggle("fast"); + g.bulidContent(); + g.showDate(); + }); + + //上个月 + g.buttons.btnPrevMonth.click(function () + { + if (--g.currentDate.month == 0) + { + g.currentDate.month = 12; + g.currentDate.year--; + } + g.bulidContent(); + }); + //下个月 + g.buttons.btnNextMonth.click(function () + { + if (++g.currentDate.month == 13) + { + g.currentDate.month = 1; + g.currentDate.year++; + } + g.bulidContent(); + }); + //上一年 + g.buttons.btnPrevYear.click(function () + { + g.currentDate.year--; + g.bulidContent(); + }); + //下一年 + g.buttons.btnNextYear.click(function () + { + g.currentDate.year++; + g.bulidContent(); + }); + //今天 + g.buttons.btnToday.click(function () + { + g.currentDate = { + year: g.now.year, + month: g.now.month, + day: g.now.day, + date: g.now.date + }; + g.selectedDate = { + year: g.now.year, + month: g.now.month, + day: g.now.day, + date: g.now.date + }; + g.showDate(); + g.dateeditor.slideToggle("fast"); + }); + //文本框 + g.inputText.change(function () + { + g.onTextChange(); + }).blur(function () + { + g.text.removeClass("l-text-focus"); + }).focus(function () + { + g.text.addClass("l-text-focus"); + }); + g.text.hover(function () + { + g.text.addClass("l-text-over"); + }, function () + { + g.text.removeClass("l-text-over"); + }); + //LEABEL 支持 + if (p.label) + { + g.labelwrapper = g.textwrapper.wrap('<div class="l-labeltext"></div>').parent(); + g.labelwrapper.prepend('<div class="l-text-label" style="float:left;display:inline;">' + p.label + ':&nbsp</div>'); + g.textwrapper.css('float', 'left'); + if (!p.labelWidth) + { + p.labelWidth = $('.l-text-label', g.labelwrapper).outerWidth(); + } else + { + $('.l-text-label', g.labelwrapper).outerWidth(p.labelWidth); + } + $('.l-text-label', g.labelwrapper).width(p.labelWidth); + $('.l-text-label', g.labelwrapper).height(g.text.height()); + g.labelwrapper.append('<br style="clear:both;" />'); + if (p.labelAlign) + { + $('.l-text-label', g.labelwrapper).css('text-align', p.labelAlign); + } + g.textwrapper.css({ display: 'inline' }); + g.labelwrapper.width(g.text.outerWidth() + p.labelWidth + 2); + } + + g.set(p); + //增加鼠标在日期控件外点击隐藏日期选择框功能 + $(document).bind("click.dateeditor", function (e) + { + if (g.dateeditor.is(":visible") && $((e.target || e.srcElement)).closest( ".l-box-dateeditor, .l-text-date" ).length == 0) + { + g.toggleDateEditor(true); + } + }); + }, + destroy: function () + { + if (this.textwrapper) this.textwrapper.remove(); + if (this.dateeditor) this.dateeditor.remove(); + this.options = null; + $.ligerui.remove(this); + }, + bulidContent: function () + { + var g = this, p = this.options; + //当前月第一天星期 + var thismonthFirstDay = new Date(g.currentDate.year, g.currentDate.month - 1, 1).getDay(); + //当前月天数 + var nextMonth = g.currentDate.month; + var nextYear = g.currentDate.year; + if (++nextMonth == 13) + { + nextMonth = 1; + nextYear++; + } + var monthDayNum = new Date(nextYear, nextMonth - 1, 0).getDate(); + //当前上个月天数 + var prevMonthDayNum = new Date(g.currentDate.year, g.currentDate.month - 1, 0).getDate(); + + g.buttons.btnMonth.html(p.monthMessage[g.currentDate.month - 1]); + g.buttons.btnYear.html(g.currentDate.year); + g.toolbar.time.hour.html(g.currentDate.hour); + g.toolbar.time.minute.html(g.currentDate.minute); + if (g.toolbar.time.hour.html().length == 1) + g.toolbar.time.hour.html("0" + g.toolbar.time.hour.html()); + if (g.toolbar.time.minute.html().length == 1) + g.toolbar.time.minute.html("0" + g.toolbar.time.minute.html()); + $("td", this.body.tbody).each(function () { this.className = "" }); + $("tr", this.body.tbody).each(function (i, tr) + { + $("td", tr).each(function (j, td) + { + var id = i * 7 + (j - thismonthFirstDay); + var showDay = id + 1; + if (g.selectedDate && g.currentDate.year == g.selectedDate.year && + g.currentDate.month == g.selectedDate.month && + id + 1 == g.selectedDate.date) + { + if (j == 0 || j == 6) + { + $(td).addClass("l-box-dateeditor-holiday") + } + $(td).addClass("l-box-dateeditor-selected"); + $(td).siblings().removeClass("l-box-dateeditor-selected"); + } + else if (g.currentDate.year == g.now.year && + g.currentDate.month == g.now.month && + id + 1 == g.now.date) + { + if (j == 0 || j == 6) + { + $(td).addClass("l-box-dateeditor-holiday") + } + $(td).addClass("l-box-dateeditor-today"); + } + else if (id < 0) + { + showDay = prevMonthDayNum + showDay; + $(td).addClass("l-box-dateeditor-out") + .removeClass("l-box-dateeditor-selected"); + } + else if (id > monthDayNum - 1) + { + showDay = showDay - monthDayNum; + $(td).addClass("l-box-dateeditor-out") + .removeClass("l-box-dateeditor-selected"); + } + else if (j == 0 || j == 6) + { + $(td).addClass("l-box-dateeditor-holiday") + .removeClass("l-box-dateeditor-selected"); + } + else + { + td.className = ""; + } + + $(td).html(showDay); + }); + }); + }, + updateSelectBoxPosition: function () + { + var g = this, p = this.options; + if (p.absolute) + { + var contentHeight = $(document).height(); + if (Number(g.text.offset().top + 1 + g.text.outerHeight() + g.dateeditor.height()) > contentHeight + && contentHeight > Number(g.dateeditor.height() + 1)) + { + //若下拉框大小超过当前document下边框,且当前document上留白大于下拉内容高度,下拉内容向上展现 + g.dateeditor.css({ left: g.text.offset().left, top: g.text.offset().top - 1 - g.dateeditor.height() }); + } else + { + g.dateeditor.css({ left: g.text.offset().left, top: g.text.offset().top + 1 + g.text.outerHeight() }); + } + } + else + { + if (g.text.offset().top + 4 > g.dateeditor.height() && g.text.offset().top + g.dateeditor.height() + textHeight + 4 - $(window).scrollTop() > $(window).height()) + { + g.dateeditor.css("marginTop", -1 * (g.dateeditor.height() + textHeight + 5)); + g.showOnTop = true; + } + else + { + g.showOnTop = false; + } + } + }, + toggleDateEditor: function (isHide) + { + var g = this, p = this.options; + //避免同一界面弹出过个菜单的问题 + var managers = $.ligerui.find($.ligerui.controls.ComboBox); + for ( var i = 0, l = managers.length; i < l; i++) { + var o = managers[i]; + if(o.id!=g.id){ + if(o.selectBox.is(":visible")!=null&&o.selectBox.is(":visible")){ + o.selectBox.hide(); + } + } + } + managers = $.ligerui.find($.ligerui.controls.DateEditor); + for ( var i = 0, l = managers.length; i < l; i++) { + var o = managers[i]; + if(o.id!=g.id){ + if(o.dateeditor.is(":visible")!=null&&o.dateeditor.is(":visible")){ + o.dateeditor.hide(); + } + } + } + var textHeight = g.text.height(); + g.editorToggling = true; + if (isHide) + { + g.dateeditor.hide('fast', function () + { + g.editorToggling = false; + }); + } + else + { + g.updateSelectBoxPosition(); + g.dateeditor.slideDown('fast', function () + { + g.editorToggling = false; + }); + } + }, + showDate: function () + { + var g = this, p = this.options; + if (!this.currentDate) return; + this.currentDate.hour = parseInt(g.toolbar.time.hour.html(), 10); + this.currentDate.minute = parseInt(g.toolbar.time.minute.html(), 10); + var dateStr = this.currentDate.year + '/' + this.currentDate.month + '/' + this.currentDate.date + ' ' + this.currentDate.hour + ':' + this.currentDate.minute; + var myDate = new Date(dateStr); + dateStr = g.getFormatDate(myDate); + this.inputText.val(dateStr); + this.onTextChange(); + }, + isDateTime: function (dateStr) + { + var g = this, p = this.options; + var r = dateStr.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/); + if (r == null) return false; + var d = new Date(r[1], r[3] - 1, r[4]); + if (d == "NaN") return false; + return (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4]); + }, + isLongDateTime: function (dateStr) + { + var g = this, p = this.options; + var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2})$/; + var r = dateStr.match(reg); + if (r == null) return false; + var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6]); + if (d == "NaN") return false; + return (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6]); + }, + getFormatDate: function (date) + { + if (date === null || date == "NaN") return null; + var g = this, p = this.options; + var format = p.format; + var o = { + "M+": date.getMonth() + 1, + "d+": date.getDate(), + "h+": date.getHours(), + "m+": date.getMinutes(), + "s+": date.getSeconds(), + "q+": Math.floor((date.getMonth() + 3) / 3), + "S": date.getMilliseconds() + } + if (/(y+)/.test(format)) + { + format = format.replace(RegExp.$1, (date.getFullYear() + "") + .substr(4 - RegExp.$1.length)); + } + for (var k in o) + { + if (new RegExp("(" + k + ")").test(format)) + { + format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] + : ("00" + o[k]).substr(("" + o[k]).length)); + } + } + return format; + }, + clear: function () + { + this.set('value', ''); + this.usedDate = null; + }, + //取消选择 + _setCancelable: function (value) + { + var g = this, p = this.options; + if (!value && g.unselect) + { + g.unselect.remove(); + g.unselect = null; + } + if (!value && !g.unselect) return; + g.unselect = $('<div class="l-trigger l-trigger-cancel"><div class="l-trigger-icon"></div></div>').hide(); + g.text.hover(function () + { + g.unselect.show(); + }, function () + { + g.unselect.hide(); + }) + if (!p.disabled && p.cancelable) + { + g.text.append(g.unselect); + } + g.unselect.hover(function () + { + this.className = "l-trigger-hover l-trigger-cancel"; + }, function () + { + this.className = "l-trigger l-trigger-cancel"; + }).click(function () + { + if (p.readonly) return; + g.clear(); + }); + }, + //恢复 + _rever: function () + { + var g = this, p = this.options; + if (!g.usedDate) + { + g.inputText.val(""); + } else + { + g.inputText.val(g.getFormatDate(g.usedDate)); + } + }, + _getMatch: function (format) + { + var r = [-1, -1, -1, -1, -1, -1], groupIndex = 0, regStr = "^", str = format || this.options.format; + while (true) + { + var tmp_r = str.match(/^yyyy|MM|dd|mm|hh|HH|ss|-|\/|:|\s/); + if (tmp_r) + { + var c = tmp_r[0].charAt(0); + var mathLength = tmp_r[0].length; + var index = 'yMdhms'.indexOf(c); + if (index != -1) + { + r[index] = groupIndex + 1; + regStr += "(\\d{1," + mathLength + "})"; + } else + { + var st = c == ' ' ? '\\s' : c; + regStr += "(" + st + ")"; + } + groupIndex++; + if (mathLength == str.length) + { + regStr += "$"; + break; + } + str = str.substring(mathLength); + } else + { + return null; + } + } + return { reg: new RegExp(regStr), position: r }; + }, + _bulidDate: function (dateStr) + { + var g = this, p = this.options; + var r = this._getMatch(); + if (!r) return null; + var t = dateStr.match(r.reg); + if (!t) return null; + var tt = { + y: r.position[0] == -1 ? 1900 : t[r.position[0]], + M: r.position[1] == -1 ? 0 : parseInt(t[r.position[1]], 10) - 1, + d: r.position[2] == -1 ? 1 : parseInt(t[r.position[2]], 10), + h: r.position[3] == -1 ? 0 : parseInt(t[r.position[3]], 10), + m: r.position[4] == -1 ? 0 : parseInt(t[r.position[4]], 10), + s: r.position[5] == -1 ? 0 : parseInt(t[r.position[5]], 10) + }; + if (tt.M < 0 || tt.M > 11 || tt.d < 0 || tt.d > 31) return null; + var d = new Date(tt.y, tt.M, tt.d); + if (p.showTime) + { + if (tt.m < 0 || tt.m > 59 || tt.h < 0 || tt.h > 23 || tt.s < 0 || tt.s > 59) return null; + d.setHours(tt.h); + d.setMinutes(tt.m); + d.setSeconds(tt.s); + } + return d; + }, + updateStyle: function () + { + this.onTextChange(); + }, + onTextChange: function () + { + var g = this, p = this.options; + var val = g.inputText.val(); + if (!val) + { + g.selectedDate = null; + return true; + } + var newDate = g._bulidDate(val); + if (!newDate) + { + g._rever(); + return; + } + else + { + g.usedDate = newDate; + } + g.selectedDate = { + year: g.usedDate.getFullYear(), + month: g.usedDate.getMonth() + 1, //注意这里 + day: g.usedDate.getDay(), + date: g.usedDate.getDate(), + hour: g.usedDate.getHours(), + minute: g.usedDate.getMinutes() + }; + g.currentDate = { + year: g.usedDate.getFullYear(), + month: g.usedDate.getMonth() + 1, //注意这里 + day: g.usedDate.getDay(), + date: g.usedDate.getDate(), + hour: g.usedDate.getHours(), + minute: g.usedDate.getMinutes() + }; + var formatVal = g.getFormatDate(newDate); + g.inputText.val(formatVal); + g.trigger('changeDate', [formatVal]); + if ($(g.dateeditor).is(":visible")) + g.bulidContent(); + }, + _setHeight: function (value) + { + var g = this; + if (value > 4) + { + g.text.css({ height: value }); + g.inputText.css({ height: value }); + g.textwrapper.css({ height: value }); + } + }, + _setWidth: function (value) + { + var g = this; + if (value > 20) + { + g.text.css({ width: value }); + g.inputText.css({ width: value - 20 }); + g.textwrapper.css({ width: value }); + } + }, + _setValue: function (value) + { + var g = this; + if (!value) g.inputText.val(''); + if (typeof value == "string") + { + if (/^\/Date/.test(value)) + { + value = value.replace(/^\//, "new ").replace(/\/$/, ""); + eval("value = " + value); + } + g.inputText.val(value); + g.usedDate = value; + } + if (typeof value == "object") + { + if (value instanceof Date) + { + g.inputText.val(g.getFormatDate(value)); + g.onTextChange(); + } + } + }, + _getValue: function () + { + return this.usedDate; + }, + setEnabled: function () + { + var g = this, p = this.options; + this.inputText.removeAttr("readonly"); + this.text.removeClass('l-text-disabled'); + p.disabled = false; + }, + setDisabled: function () + { + var g = this, p = this.options; + this.inputText.attr("readonly", "readonly"); + this.text.addClass('l-text-disabled'); + p.disabled = true; + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ + +(function ($) +{ + var l = $.ligerui; + + //全局事件 + $(".l-dialog-btn").live('mouseover', function () + { + $(this).addClass("l-dialog-btn-over"); + }).live('mouseout', function () + { + $(this).removeClass("l-dialog-btn-over"); + }); + $(".l-dialog-tc .l-dialog-close").live('mouseover', function () + { + $(this).addClass("l-dialog-close-over"); + }).live('mouseout', function () + { + $(this).removeClass("l-dialog-close-over"); + }); + + + $.ligerDialog = function () + { + return l.run.call(null, "ligerDialog", arguments, { isStatic: true }); + }; + + //dialog 图片文件夹的路径 预加载 + $.ligerui.DialogImagePath = "../../lib/ligerUI/skins/Aqua/images/win/"; + + function prevImage(paths) + { + for (var i in paths) + { + $('<img />').attr('src', l.DialogImagePath + paths[i]); + } + } + //prevImage(['dialog.gif', 'dialog-winbtns.gif', 'dialog-bc.gif', 'dialog-tc.gif']); + + $.ligerDefaults.Dialog = { + cls: null, //给dialog附加css class + contentCls: null, + id: null, //给dialog附加id + buttons: null, //按钮集合 + isDrag: true, //是否拖动 + width: 280, //宽度 + height: null, //高度,默认自适应 + content: '', //内容 + target: null, //目标对象,指定它将以appendTo()的方式载入 + url: null, //目标页url,默认以iframe的方式载入 + urlParms: null, //传参 + load: false, //是否以load()的方式加载目标页的内容 + type: 'none', //类型 warn、success、error、question + left: null, //位置left + top: null, //位置top + modal: true, //是否模态对话框 + data: null, //传递数据容器 + name: null, //创建iframe时 作为iframe的name和id + isResize: false, // 是否调整大小 + allowClose: true, //允许关闭 + opener: null, + timeParmName: null, //是否给URL后面加上值为new Date().getTime()的参数,如果需要指定一个参数名即可 + closeWhenEnter: null, //回车时是否关闭dialog + isHidden: true, //关闭对话框时是否只是隐藏,还是销毁对话框 + show: true, //初始化时是否马上显示 + title: '提示', //头部 + showMax: false, //是否显示最大化按钮 + showToggle: false, //是否显示收缩窗口按钮 + showMin: false, //是否显示最小化按钮 + slide: $.browser.msie ? false : true, //是否以动画的形式显示 + fixedType: null, //在固定的位置显示, 可以设置的值有n, e, s, w, ne, se, sw, nw + showType: null, //显示类型,可以设置为slide(固定显示时有效) + layoutMode : 1, //1 九宫布局, 2 上中下布局 + onLoaded: null, + onExtend: null, + onExtended: null, + onCollapse: null, + onCollapseed: null, + onContentHeightChange: null, + onClose: null, + onClosed: null, + onStopResize: null, + minIsHide : false //最小化仅隐藏 + }; + $.ligerDefaults.DialogString = { + titleMessage: '提示', //提示文本标题 + ok: '确定', + yes: '是', + no: '否', + cancel: '取消', + waittingMessage: '正在等待中,请稍候...' + }; + + $.ligerMethos.Dialog = $.ligerMethos.Dialog || {}; + + + l.controls.Dialog = function (options) + { + l.controls.Dialog.base.constructor.call(this, null, options); + }; + l.controls.Dialog.ligerExtend(l.core.Win, { + __getType: function () + { + return 'Dialog'; + }, + __idPrev: function () + { + return 'Dialog'; + }, + _extendMethods: function () + { + return $.ligerMethos.Dialog; + }, + _render: function () + { + var g = this, p = this.options; + var tmpId = ""; + g.set(p, true); + var dialog = $('<div class="l-dialog"><table class="l-dialog-table" cellpadding="0" cellspacing="0" border="0"><tbody><tr><td class="l-dialog-tl"></td><td class="l-dialog-tc"><div class="l-dialog-tc-inner"><div class="l-dialog-icon"></div><div class="l-dialog-title"></div><div class="l-dialog-winbtns"><div class="l-dialog-winbtn l-dialog-close"></div></div></div></td><td class="l-dialog-tr"></td></tr><tr><td class="l-dialog-cl"></td><td class="l-dialog-cc"><div class="l-dialog-body"><div class="l-dialog-image"></div> <div class="l-dialog-content"></div><div class="l-dialog-buttons"><div class="l-dialog-buttons-inner"></div></td><td class="l-dialog-cr"></td></tr><tr><td class="l-dialog-bl"></td><td class="l-dialog-bc"></td><td class="l-dialog-br"></td></tr></tbody></table></div>'); + $('body').append(dialog); + g.dialog = dialog; + if (p.layoutMode == 2) //上中下布局,不再需要这左右的单元格了 + { + dialog.find("td.l-dialog-tl,td.l-dialog-cl,td.l-dialog-bl,td.l-dialog-tr,td.l-dialog-cr,td.l-dialog-br").remove(); + } + g.element = dialog[0]; + g.dialog.body = $(".l-dialog-body:first", g.dialog); + g.dialog.header = $(".l-dialog-tc-inner:first", g.dialog); + g.dialog.winbtns = $(".l-dialog-winbtns:first", g.dialog.header); + g.dialog.buttons = $(".l-dialog-buttons:first", g.dialog); + g.dialog.content = $(".l-dialog-content:first", g.dialog); + g.set(p, false); + + if (p.allowClose == false) $(".l-dialog-close", g.dialog).remove(); + if (p.target || p.url || p.type == "none") + { + p.type = null; + g.dialog.addClass("l-dialog-win"); + + } + if (p.cls) g.dialog.addClass(p.cls); + if (p.id) g.dialog.attr("id", p.id); + + //设置锁定屏幕、拖动支持 和设置图片 + g.mask(); + if (p.isDrag) + g._applyDrag(); + if (p.isResize) + g._applyResize(); + if (p.type) + g._setImage(); + else + { + $(".l-dialog-image", g.dialog).remove(); + g.dialog.content.addClass("l-dialog-content-noimage"); + } + if (p.contentCls) + g.dialog.content.addClass(p.contentCls); + if (!p.show) + { + g.unmask(); + g.dialog.hide(); + } + //设置主体内容 + if (p.target) + { + g.dialog.content.prepend(p.target); + $(p.target).show(); + } + else if (p.url) + { + var url = $.isFunction(p.url) ? p.url.call(g) : p.url; + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (p.timeParmName) + { + urlParms = urlParms || {}; + urlParms[p.timeParmName] = new Date().getTime(); + } + if (urlParms) + { + for (var name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + if (p.load) + { + g.dialog.body.load(url, function () + { + g._saveStatus(); + g.trigger('loaded'); + }); + } + else + { + g.jiframe = $("<iframe frameborder='0'></iframe>"); + var framename = p.name ? p.name : "ligerwindow" + new Date().getTime(); + g.jiframe.attr("name", framename); + g.jiframe.attr("id", framename); + g.dialog.content.prepend(g.jiframe); + g.dialog.content.addClass("l-dialog-content-nopadding l-dialog-content-frame"); + + setTimeout(function () + { + if (g.dialog.body.find(".l-dialog-loading:first").length == 0) + g.dialog.body.append("<div class='l-dialog-loading' style='display:block;'></div>"); + var iframeloading = $(".l-dialog-loading:first", g.dialog.body); + g.jiframe[0].dialog = g;//增加窗口对dialog对象的引用 + /* + 可以在子窗口这样使用: + var dialog = frameElement.dialog; + var dialogData = dialog.get('data');//获取data参数 + dialog.set('title','新标题'); //设置标题 + dialog.close();//关闭dialog + */ + g.jiframe.attr("src", url).bind('load.dialog', function () + { + iframeloading.hide(); + g.trigger('loaded'); + }); + g.frame = window.frames[g.jiframe.attr("name")]; + }, 0); + // 为了解决ie下对含有iframe的div窗口销毁不正确,进而导致第二次打开时焦点不在当前图层的问题 + // 加入以下代码 + tmpId = 'jquery_ligerui_' + new Date().getTime(); + g.tmpInput = $("<input></input>"); + g.tmpInput.attr("id", tmpId); + g.dialog.content.prepend(g.tmpInput); + } + } + if (p.opener) g.dialog.opener = p.opener; + //设置按钮 + if (p.buttons) + { + $(p.buttons).each(function (i, item) + { + var btn = $('<div class="l-dialog-btn"><div class="l-dialog-btn-l"></div><div class="l-dialog-btn-r"></div><div class="l-dialog-btn-inner"></div></div>'); + $(".l-dialog-btn-inner", btn).html(item.text); + $(".l-dialog-buttons-inner", g.dialog.buttons).prepend(btn); + item.width && btn.width(item.width); + item.onclick && btn.click(function () + { + item.onclick(item, g, i); + }); + item.cls && btn.addClass(item.cls); + }); + } else + { + g.dialog.buttons.remove(); + } + $(".l-dialog-buttons-inner", g.dialog.buttons).append("<div class='l-clear'></div>"); + + + $(".l-dialog-title", g.dialog) + .bind("selectstart", function () { return false; }); + g.dialog.click(function () + { + l.win.setFront(g); + }); + //设置事件 + $(".l-dialog-tc .l-dialog-close", g.dialog).click(function () + { + if (p.isHidden) + g.hide(); + else + g.close(); + }); + if (!p.fixedType) + { + if (p.width == 'auto') + { + setTimeout(function () + { + resetPos() + }, 100); + } else + { + resetPos(); + } + } + function resetPos() + { + //位置初始化 + var left = 0; + var top = 0; + var width = p.width || g.dialog.width(); + if (p.slide == true) p.slide = 'fast'; + if (p.left != null) left = p.left; + else p.left = left = 0.5 * ($(window).width() - width); + if (p.top != null) top = p.top; + else p.top = top = 0.5 * ($(window).height() - g.dialog.height()) + $(window).scrollTop() - 10; + if (left < 0) p.left = left = 0; + if (top < 0) p.top = top = 0; + g.dialog.css({ left: left, top: top }); + } + g.show(); + $('body').bind('keydown.dialog', function (e) + { + var key = e.which; + if (key == 13) + { + g.enter(); + } + else if (key == 27) + { + g.esc(); + } + }); + + g._updateBtnsWidth(); + g._saveStatus(); + g._onReisze(); + if (tmpId != "") + { + $("#" + tmpId).focus(); + $("#" + tmpId).remove(); + } + }, + _borderX: 12, + _borderY: 32, + doMax: function (slide) + { + var g = this, p = this.options; + var width = $(window).width(), height = $(window).height(), left = 0, top = 0; + if (l.win.taskbar) + { + height -= l.win.taskbar.outerHeight(); + if (l.win.top) top += l.win.taskbar.outerHeight(); + } + if (slide) + { + g.dialog.body.animate({ width: width - g._borderX }, p.slide); + g.dialog.animate({ left: left, top: top }, p.slide); + g.dialog.content.animate({ height: height - g._borderY - g.dialog.buttons.outerHeight() }, p.slide, function () + { + g._onReisze(); + }); + } + else + { + g.set({ width: width, height: height, left: left, top: top }); + g._onReisze(); + } + }, + //最大化 + max: function () + { + var g = this, p = this.options; + if (g.winmax) + { + g.winmax.addClass("l-dialog-recover"); + g.doMax(p.slide); + if (g.wintoggle) + { + if (g.wintoggle.hasClass("l-dialog-extend")) + g.wintoggle.addClass("l-dialog-toggle-disabled l-dialog-extend-disabled"); + else + g.wintoggle.addClass("l-dialog-toggle-disabled l-dialog-collapse-disabled"); + } + if (g.resizable) g.resizable.set({ disabled: true }); + if (g.draggable) g.draggable.set({ disabled: true }); + g.maximum = true; + + $(window).bind('resize.dialogmax', function () + { + g.doMax(false); + }); + } + }, + + //恢复 + recover: function () + { + var g = this, p = this.options; + if (g.winmax) + { + g.winmax.removeClass("l-dialog-recover"); + if (p.slide) + { + g.dialog.body.animate({ width: g._width - g._borderX }, p.slide); + g.dialog.animate({ left: g._left, top: g._top }, p.slide); + g.dialog.content.animate({ height: g._height - g._borderY - g.dialog.buttons.outerHeight() }, p.slide, function () + { + g._onReisze(); + }); + } + else + { + g.set({ width: g._width, height: g._height, left: g._left, top: g._top }); + g._onReisze(); + } + if (g.wintoggle) + { + g.wintoggle.removeClass("l-dialog-toggle-disabled l-dialog-extend-disabled l-dialog-collapse-disabled"); + } + + $(window).unbind('resize.dialogmax'); + } + if (this.resizable) this.resizable.set({ disabled: false }); + if (g.draggable) g.draggable.set({ disabled: false }); + g.maximum = false; + }, + + //最小化 + min: function () + { + var g = this, p = this.options; + if (p.minIsHide) + { + g.dialog.hide(); + } + else + { + var task = l.win.getTask(this); + if (p.slide) + { + g.dialog.body.animate({ width: 1 }, p.slide); + task.y = task.offset().top + task.height(); + task.x = task.offset().left + task.width() / 2; + g.dialog.animate({ left: task.x, top: task.y }, p.slide, function () + { + g.dialog.hide(); + }); + } + else + { + g.dialog.hide(); + } + } + g.unmask(); + g.minimize = true; + g.actived = false; + }, + + active: function () + { + var g = this, p = this.options; + if (g.minimize) + { + var width = g._width, height = g._height, left = g._left, top = g._top; + if (g.maximum) + { + width = $(window).width(); + height = $(window).height(); + left = top = 0; + if (l.win.taskbar) + { + height -= l.win.taskbar.outerHeight(); + if (l.win.top) top += l.win.taskbar.outerHeight(); + } + } + if (p.slide) + { + g.dialog.body.animate({ width: width - g._borderX }, p.slide); + g.dialog.animate({ left: left, top: top }, p.slide); + } + else + { + g.set({ width: width, height: height, left: left, top: top }); + } + } + g.actived = true; + g.minimize = false; + l.win.setFront(g); + g.show(); + }, + + //展开 收缩 + toggle: function () + { + + var g = this, p = this.options; + if (!g.wintoggle) return; + if (g.wintoggle.hasClass("l-dialog-extend")) + g.extend(); + else + g.collapse(); + }, + + //收缩 + collapse: function (slide) + { + var g = this, p = this.options; + if (!g.wintoggle) return; + if (p.slide && slide != false) + g.dialog.content.animate({ height: 1 }, p.slide); + else + g.dialog.content.height(1); + if (this.resizable) this.resizable.set({ disabled: true }); + + g.wintoggle.addClass("l-dialog-extend"); + }, + + //展开 + extend: function () + { + var g = this, p = this.options; + if (!g.wintoggle) return; + var contentHeight = g._height - g._borderY - g.dialog.buttons.outerHeight(); + if (p.slide) + g.dialog.content.animate({ height: contentHeight }, p.slide); + else + g.dialog.content.height(contentHeight); + if (this.resizable) this.resizable.set({ disabled: false }); + + + g.wintoggle.removeClass("l-dialog-extend"); + }, + _updateBtnsWidth: function () + { + var g = this; + var btnscount = $(">div", g.dialog.winbtns).length; + g.dialog.winbtns.width(22 * btnscount); + }, + _setLeft: function (value) + { + if (!this.dialog) return; + if (value != null) + this.dialog.css({ left: value }); + }, + _setTop: function (value) + { + if (!this.dialog) return; + if (value != null) + this.dialog.css({ top: value }); + }, + _setWidth: function (value) + { + if (!this.dialog) return; + if (value >= this._borderX) + { + this.dialog.body.width(value - this._borderX); + } + }, + _setHeight: function (value) + { + var g = this, p = this.options; + if (!this.dialog) return; + if (value == "auto") + { + g.dialog.content.height('auto'); + } else if (value >= this._borderY) + { + var height = value - this._borderY - g.dialog.buttons.outerHeight(); + if (g.trigger('ContentHeightChange', [height]) == false) return; + if (p.load) + { + g.dialog.body.height(height); + } else + { + g.dialog.content.height(height); + } + g.trigger('ContentHeightChanged', [height]); + } + }, + _setShowMax: function (value) + { + var g = this, p = this.options; + if (value) + { + if (!g.winmax) + { + g.winmax = $('<div class="l-dialog-winbtn l-dialog-max"></div>').appendTo(g.dialog.winbtns) + .hover(function () + { + if ($(this).hasClass("l-dialog-recover")) + $(this).addClass("l-dialog-recover-over"); + else + $(this).addClass("l-dialog-max-over"); + }, function () + { + $(this).removeClass("l-dialog-max-over l-dialog-recover-over"); + }).click(function () + { + if ($(this).hasClass("l-dialog-recover")) + g.recover(); + else + g.max(); + }); + } + } + else if (g.winmax) + { + g.winmax.remove(); + g.winmax = null; + } + g._updateBtnsWidth(); + }, + _setShowMin: function (value) + { + var g = this, p = this.options; + if (value) + { + if (!g.winmin) + { + g.winmin = $('<div class="l-dialog-winbtn l-dialog-min"></div>').appendTo(g.dialog.winbtns) + .hover(function () + { + $(this).addClass("l-dialog-min-over"); + }, function () + { + $(this).removeClass("l-dialog-min-over"); + }).click(function () + { + g.min(); + }); + if (!p.minIsHide) + { + l.win.addTask(g); + } + } + } + else if (g.winmin) + { + g.winmin.remove(); + g.winmin = null; + } + g._updateBtnsWidth(); + }, + _setShowToggle: function (value) + { + var g = this, p = this.options; + if (value) + { + if (!g.wintoggle) + { + g.wintoggle = $('<div class="l-dialog-winbtn l-dialog-collapse"></div>').appendTo(g.dialog.winbtns) + .hover(function () + { + if ($(this).hasClass("l-dialog-toggle-disabled")) return; + if ($(this).hasClass("l-dialog-extend")) + $(this).addClass("l-dialog-extend-over"); + else + $(this).addClass("l-dialog-collapse-over"); + }, function () + { + $(this).removeClass("l-dialog-extend-over l-dialog-collapse-over"); + }).click(function () + { + if ($(this).hasClass("l-dialog-toggle-disabled")) return; + if (g.wintoggle.hasClass("l-dialog-extend")) + { + if (g.trigger('extend') == false) return; + g.wintoggle.removeClass("l-dialog-extend"); + g.extend(); + g.trigger('extended'); + } + else + { + if (g.trigger('collapse') == false) return; + g.wintoggle.addClass("l-dialog-extend"); + g.collapse(); + g.trigger('collapseed') + } + }); + } + } + else if (g.wintoggle) + { + g.wintoggle.remove(); + g.wintoggle = null; + } + }, + //按下回车 + enter: function () + { + var g = this, p = this.options; + var isClose; + if (p.closeWhenEnter != undefined) + { + isClose = p.closeWhenEnter; + } + else if (p.type == "warn" || p.type == "error" || p.type == "success" || p.type == "question") + { + isClose = true; + } + if (isClose) + { + g.close(); + } + }, + esc: function () + { + + }, + _removeDialog: function () + { + var g = this, p = this.options; + if (p.showType && p.fixedType) + { + g.dialog.animate({ bottom: -1 * p.height }, function () + { + remove(); + }); + } + else + { + remove(); + } + function remove() + { + var jframe = $('iframe', g.dialog); + if (jframe.length) + { + var frame = jframe[0]; + frame.src = "about:blank"; + if (frame.contentWindow && frame.contentWindow.document) + { + try + { + frame.contentWindow.document.write(''); + } catch (e) + { + } + } + $.browser.msie && CollectGarbage(); + jframe.remove(); + } + g.dialog.remove(); + } + }, + close: function () + { + var g = this, p = this.options; + if (g.trigger('Close') == false) return; + g.doClose(); + if (g.trigger('Closed') == false) return; + }, + doClose: function () + { + var g = this; + l.win.removeTask(this); + $.ligerui.remove(this); + g.unmask(); + g._removeDialog(); + $('body').unbind('keydown.dialog'); + }, + _getVisible: function () + { + return this.dialog.is(":visible"); + }, + _setUrl: function (url) + { + var g = this, p = this.options; + p.url = url; + if (p.load) + { + g.dialog.body.html("").load(p.url, function () + { + g.trigger('loaded'); + }); + } + else if (g.jiframe) + { + g.jiframe.attr("src", p.url); + } + }, + _setContent: function (content) + { + this.dialog.content.html(content); + }, + _setTitle: function (value) + { + var g = this; var p = this.options; + if (value) + { + $(".l-dialog-title", g.dialog).html(value); + } + }, + _hideDialog: function () + { + var g = this, p = this.options; + if (p.showType && p.fixedType) + { + g.dialog.animate({ bottom: -1 * p.height }, function () + { + g.dialog.hide(); + }); + } else + { + g.dialog.hide(); + } + }, + hidden: function () + { + var g = this; + l.win.removeTask(g); + g.dialog.hide(); + g.unmask(); + }, + show: function () + { + var g = this, p = this.options; + g.mask(); + if (p.fixedType) + { + if (p.showType) + { + g.dialog.css({ bottom: -1 * p.height }).addClass("l-dialog-fixed"); + g.dialog.show().animate({ bottom: 0 }); + } + else + { + g.dialog.show().css({ bottom: 0 }).addClass("l-dialog-fixed"); + } + } + else + { + g.dialog.show(); + } + //前端显示 + $.ligerui.win.setFront.ligerDefer($.ligerui.win, 100, [g]); + }, + setUrl: function (url) + { + this._setUrl(url); + }, + _saveStatus: function () + { + var g = this; + g._width = g.dialog.body.width(); + g._height = g.dialog.body.height(); + var top = 0; + var left = 0; + if (!isNaN(parseInt(g.dialog.css('top')))) + top = parseInt(g.dialog.css('top')); + if (!isNaN(parseInt(g.dialog.css('left')))) + left = parseInt(g.dialog.css('left')); + g._top = top; + g._left = left; + }, + _applyDrag: function () + { + var g = this, p = this.options; + if ($.fn.ligerDrag) + { + g.draggable = g.dialog.ligerDrag({ + handler: '.l-dialog-title', animate: false, + onStartDrag: function () + { + l.win.setFront(g); + var mask = $("<div class='l-dragging-mask' style='display:block'></div>").height(g.dialog.height()); + g.dialog.append(mask); + g.dialog.content.addClass('l-dialog-content-dragging'); + }, + onDrag: function (current, e) + { + var pageY = e.pageY || e.screenY; + if (pageY < 0) return false; + }, + onStopDrag: function () + { + g.dialog.find("div.l-dragging-mask:first").remove(); + g.dialog.content.removeClass('l-dialog-content-dragging'); + if (p.target) + { + var triggers1 = l.find($.ligerui.controls.DateEditor); + var triggers2 = l.find($.ligerui.controls.ComboBox); + //更新所有下拉选择框的位置 + $($.merge(triggers1, triggers2)).each(function () + { + if (this.updateSelectBoxPosition) + this.updateSelectBoxPosition(); + }); + } + g._saveStatus(); + } + }); + } + }, + _onReisze: function () + { + var g = this, p = this.options; + if (p.target || p.url) + { + var manager = $(p.target).liger(); + if (!manager) manager = $(p.target).find(":first").liger(); + if (!manager) return; + var contentHeight = g.dialog.content.height(); + var contentWidth = g.dialog.content.width(); + manager.trigger('resize', [{ width: contentWidth, height: contentHeight }]); + } + }, + _applyResize: function () + { + var g = this, p = this.options; + if ($.fn.ligerResizable) + { + g.resizable = g.dialog.ligerResizable({ + onStopResize: function (current, e) + { + var top = 0; + var left = 0; + if (!isNaN(parseInt(g.dialog.css('top')))) + top = parseInt(g.dialog.css('top')); + if (!isNaN(parseInt(g.dialog.css('left')))) + left = parseInt(g.dialog.css('left')); + if (current.diffLeft) + { + g.set({ left: left + current.diffLeft }); + } + if (current.diffTop) + { + g.set({ top: top + current.diffTop }); + } + if (current.newWidth) + { + g.set({ width: current.newWidth }); + g.dialog.body.css({ width: current.newWidth - g._borderX }); + } + if (current.newHeight) + { + g.set({ height: current.newHeight }); + } + g._onReisze(); + g._saveStatus(); + g.trigger('stopResize'); + return false; + }, animate: false + }); + } + }, + _setImage: function () + { + var g = this, p = this.options; + if (p.type) + { + var alertCss = { paddingLeft: 74, paddingRight: 15, paddingBottom: 30 }; + if (p.type == 'success' || p.type == 'donne' || p.type == 'ok') + { + $(".l-dialog-image", g.dialog).addClass("l-dialog-image-donne").show(); + g.dialog.content.css(alertCss); + } + else if (p.type == 'error') + { + $(".l-dialog-image", g.dialog).addClass("l-dialog-image-error").show(); + g.dialog.content.css(alertCss); + } + else if (p.type == 'warn') + { + $(".l-dialog-image", g.dialog).addClass("l-dialog-image-warn").show(); + g.dialog.content.css(alertCss); + } + else if (p.type == 'question') + { + $(".l-dialog-image", g.dialog).addClass("l-dialog-image-question").show(); + g.dialog.content.css(alertCss); + } + } + } + }); + l.controls.Dialog.prototype.hide = l.controls.Dialog.prototype.hidden; + + + + $.ligerDialog.open = function (p) + { + return $.ligerDialog(p); + }; + $.ligerDialog.close = function () + { + var dialogs = l.find(l.controls.Dialog.prototype.__getType()); + for (var i in dialogs) + { + var d = dialogs[i]; + d.destroy.ligerDefer(d, 5); + } + l.win.unmask(); + }; + $.ligerDialog.show = function (p) + { + var dialogs = l.find(l.controls.Dialog.prototype.__getType()); + if (dialogs.length) + { + for (var i in dialogs) + { + dialogs[i].show(); + return; + } + } + return $.ligerDialog(p); + }; + $.ligerDialog.hide = function () + { + var dialogs = l.find(l.controls.Dialog.prototype.__getType()); + for (var i in dialogs) + { + var d = dialogs[i]; + d.hide(); + } + }; + $.ligerDialog.tip = function (options) + { + options = $.extend({ + showType: 'slide', + width: 240, + modal: false, + height: 100 + }, options || {}); + + $.extend(options, { + fixedType: 'se', + type: 'none', + isDrag: false, + isResize: false, + showMax: false, + showToggle: false, + showMin: false + }); + return $.ligerDialog.open(options); + }; + $.ligerDialog.alert = function (content, title, type, callback, options) + { + content = content || ""; + if (typeof (title) == "function") + { + callback = title; + type = null; + } + else if (typeof (type) == "function") + { + callback = type; + } + var btnclick = function (item, Dialog, index) + { + Dialog.close(); + if (callback) + callback(item, Dialog, index); + }; + p = { + content: content, + buttons: [{ text: $.ligerDefaults.DialogString.ok, onclick: btnclick }] + }; + if (typeof (title) == "string" && title != "") p.title = title; + if (typeof (type) == "string" && type != "") p.type = type; + $.extend(p, { + showMax: false, + showToggle: false, + showMin: false + }, options || {}); + return $.ligerDialog(p); + }; + + $.ligerDialog.confirm = function (content, title, callback) + { + if (typeof (title) == "function") + { + callback = title; + type = null; + } + var btnclick = function (item, Dialog) + { + Dialog.close(); + if (callback) + { + callback(item.type == 'ok'); + } + }; + p = { + type: 'question', + content: content, + buttons: [ + { + text: $.ligerDefaults.DialogString.yes, onclick: btnclick, type: 'ok', cls: 'l-dialog-btn-ok' + }, { + text: $.ligerDefaults.DialogString.no, onclick: btnclick, type: 'no', cls: 'l-dialog-btn-no' + } + ] + }; + if (typeof (title) == "string" && title != "") p.title = title; + $.extend(p, { + showMax: false, + showToggle: false, + showMin: false + }); + return $.ligerDialog(p); + }; + $.ligerDialog.warning = function (content, title, callback, options) + { + if (typeof (title) == "function") + { + callback = title; + type = null; + } + var btnclick = function (item, Dialog) + { + Dialog.close(); + if (callback) + { + callback(item.type); + } + }; + p = { + type: 'question', + content: content, + buttons: [{ text: $.ligerDefaults.DialogString.yes, onclick: btnclick, type: 'yes' }, { text: $.ligerDefaults.DialogString.no, onclick: btnclick, type: 'no' }, { text: $.ligerDefaults.DialogString.cancel, onclick: btnclick, type: 'cancel' }] + }; + if (typeof (title) == "string" && title != "") p.title = title; + $.extend(p, { + showMax: false, + showToggle: false, + showMin: false + }, options || {}); + return $.ligerDialog(p); + }; + $.ligerDialog.waitting = function (title) + { + title = title || $.ligerDefaults.Dialog.waittingMessage; + return $.ligerDialog.open({ cls: 'l-dialog-waittingdialog', type: 'none', content: '<div style="padding:4px">' + title + '</div>', allowClose: false }); + }; + $.ligerDialog.closeWaitting = function () + { + var dialogs = l.find(l.controls.Dialog); + for (var i in dialogs) + { + var d = dialogs[i]; + if (d.dialog.hasClass("l-dialog-waittingdialog")) + d.close(); + } + }; + $.ligerDialog.success = function (content, title, onBtnClick, options) + { + return $.ligerDialog.alert(content, title, 'success', onBtnClick, options); + }; + $.ligerDialog.error = function (content, title, onBtnClick, options) + { + return $.ligerDialog.alert(content, title, 'error', onBtnClick, options); + }; + $.ligerDialog.warn = function (content, title, onBtnClick, options) + { + return $.ligerDialog.alert(content, title, 'warn', onBtnClick, options); + }; + $.ligerDialog.question = function (content, title, options) + { + return $.ligerDialog.alert(content, title, 'question', null, options); + }; + + + $.ligerDialog.prompt = function (title, value, multi, callback) + { + var target = $('<input type="text" class="l-dialog-inputtext"/>'); + if (typeof (multi) == "function") + { + callback = multi; + } + if (typeof (value) == "function") + { + callback = value; + } + else if (typeof (value) == "boolean") + { + multi = value; + } + if (typeof (multi) == "boolean" && multi) + { + target = $('<textarea class="l-dialog-textarea"></textarea>'); + } + if (typeof (value) == "string" || typeof (value) == "int") + { + target.val(value); + } + var btnclick = function (item, Dialog, index) + { + Dialog.close(); + if (callback) + { + callback(item.type == 'yes', target.val()); + } + } + p = { + title: title, + target: target, + width: 320, + buttons: [{ text: $.ligerDefaults.DialogString.ok, onclick: btnclick, type: 'yes' }, { text: $.ligerDefaults.DialogString.cancel, onclick: btnclick, type: 'cancel' }] + }; + return $.ligerDialog(p); + }; + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ + +(function ($) +{ + var l = $.ligerui; + + $.fn.ligerDrag = function (options) + { + return l.run.call(this, "ligerDrag", arguments, + { + idAttrName: 'ligeruidragid', hasElement: false, propertyToElemnt: 'target' + } + ); + }; + + $.fn.ligerGetDragManager = function () + { + return l.run.call(this, "ligerGetDragManager", arguments, + { + idAttrName: 'ligeruidragid', hasElement: false, propertyToElemnt: 'target' + }); + }; + + $.ligerDefaults.Drag = { + onStartDrag: false, + onDrag: false, + onStopDrag: false, + handler: null, + //鼠标按下再弹起,如果中间的间隔小于[dragDelay]毫秒,那么认为是点击,不会进行拖拽操作 + clickDelay : 100, + //代理 拖动时的主体,可以是'clone'或者是函数,放回jQuery 对象 + proxy: true, + revert: false, + animate: true, + onRevert: null, + onEndRevert: null, + //接收区域 jQuery对象或者jQuery选择字符 + receive: null, + //进入区域 + onDragEnter: null, + //在区域移动 + onDragOver: null, + //离开区域 + onDragLeave: null, + //在区域释放 + onDrop: null, + disabled: false, + proxyX: null, //代理相对鼠标指针的位置,如果不设置则对应target的left + proxyY: null + }; + + + l.controls.Drag = function (options) + { + l.controls.Drag.base.constructor.call(this, null, options); + }; + + l.controls.Drag.ligerExtend(l.core.UIComponent, { + __getType: function () + { + return 'Drag'; + }, + __idPrev: function () + { + return 'Drag'; + }, + _render: function () + { + var g = this, p = this.options; + this.set(p); + g.cursor = "move"; + g.handler.css('cursor', g.cursor); + g.mouseDowned = false; + g.handler.bind('mousedown.drag', function (e) + { + if (p.disabled) return; + if (e.button == 2) return; + g.mouseDowned = true; + $(document).bind("selectstart.drag", function () { return false; }); + setTimeout(function () + { + //如果过了N毫秒,鼠标还没有弹起来,才认为是启动drag + if (g.mouseDowned) + { + g._start.call(g, e); + } + }, p.clickDelay || 100); + }).bind('mousemove.drag', function () + { + if (p.disabled) return; + g.handler.css('cursor', g.cursor); + }).bind('mouseup.drag', function () + { + $(document).unbind("selectstart.drag"); + }); + + $(document).bind('mouseup', function () + { + g.mouseDowned = false; + }); + }, + _rendered: function () + { + this.options.target.ligeruidragid = this.id; + }, + _start: function (e) + { + var g = this, p = this.options; + if (g.reverting) return; + if (p.disabled) return; + g.current = { + target: g.target, + left: g.target.offset().left, + top: g.target.offset().top, + startX: e.pageX || e.screenX, + startY: e.pageY || e.clientY + }; + if (g.trigger('startDrag', [g.current, e]) == false) return false; + g.cursor = "move"; + g._createProxy(p.proxy, e); + //代理没有创建成功 + if (p.proxy && !g.proxy) return false; + (g.proxy || g.handler).css('cursor', g.cursor); + $(document).bind('mousemove.drag', function () + { + g._drag.apply(g, arguments); + }); + l.draggable.dragging = true; + $(document).bind('mouseup.drag', function () + { + l.draggable.dragging = false; + g._stop.apply(g, arguments); + }); + }, + _drag: function (e) + { + var g = this, p = this.options; + if (!g.current) return; + var pageX = e.pageX || e.screenX; + var pageY = e.pageY || e.screenY; + g.current.diffX = pageX - g.current.startX; + g.current.diffY = pageY - g.current.startY; + (g.proxy || g.handler).css('cursor', g.cursor); + if (g.receive) + { + g.receive.each(function (i, obj) + { + var receive = $(obj); + var xy = receive.offset(); + if (pageX > xy.left && pageX < xy.left + receive.width() + && pageY > xy.top && pageY < xy.top + receive.height()) + { + if (!g.receiveEntered[i]) + { + g.receiveEntered[i] = true; + g.trigger('dragEnter', [obj, g.proxy || g.target, e]); + } + else + { + g.trigger('dragOver', [obj, g.proxy || g.target, e]); + } + } + else if (g.receiveEntered[i]) + { + g.receiveEntered[i] = false; + g.trigger('dragLeave', [obj, g.proxy || g.target, e]); + } + }); + } + if (g.hasBind('drag')) + { + if (g.trigger('drag', [g.current, e]) != false) + { + g._applyDrag(); + } + else + { + if (g.proxy) + { + g._removeProxy(); + } else + { + g._stop(); + } + } + } + else + { + g._applyDrag(); + } + }, + _stop: function (e) + { + var g = this, p = this.options; + $(document).unbind('mousemove.drag'); + $(document).unbind('mouseup.drag'); + $(document).unbind("selectstart.drag"); + if (g.receive) + { + g.receive.each(function (i, obj) + { + if (g.receiveEntered[i]) + { + g.trigger('drop', [obj, g.proxy || g.target, e]); + } + }); + } + if (g.proxy) + { + if (p.revert) + { + if (g.hasBind('revert')) + { + if (g.trigger('revert', [g.current, e]) != false) + g._revert(e); + else + g._removeProxy(); + } + else + { + g._revert(e); + } + } + else + { + g._applyDrag(g.target); + g._removeProxy(); + } + } + g.cursor = 'move'; + g.trigger('stopDrag', [g.current, e]); + g.current = null; + g.handler.css('cursor', g.cursor); + }, + _revert: function (e) + { + var g = this; + g.reverting = true; + g.proxy.animate({ + left: g.current.left, + top: g.current.top + }, function () + { + g.reverting = false; + g._removeProxy(); + g.trigger('endRevert', [g.current, e]); + g.current = null; + }); + }, + _applyDrag: function (applyResultBody) + { + var g = this, p = this.options; + applyResultBody = applyResultBody || g.proxy || g.target; + var cur = {}, changed = false; + var noproxy = applyResultBody == g.target; + if (g.current.diffX) + { + if (noproxy || p.proxyX == null) + cur.left = g.current.left + g.current.diffX; + else + cur.left = g.current.startX + p.proxyX + g.current.diffX; + changed = true; + } + if (g.current.diffY) + { + if (noproxy || p.proxyY == null) + cur.top = g.current.top + g.current.diffY; + else + cur.top = g.current.startY + p.proxyY + g.current.diffY; + changed = true; + } + if (applyResultBody == g.target && g.proxy && p.animate) + { + g.reverting = true; + applyResultBody.animate(cur, function () + { + g.reverting = false; + }); + } + else + { + applyResultBody.css(cur); + } + }, + _setReceive: function (receive) + { + this.receiveEntered = {}; + if (!receive) return; + if (typeof receive == 'string') + this.receive = $(receive); + else + this.receive = receive; + }, + _setHandler: function (handler) + { + var g = this, p = this.options; + if (!handler) + g.handler = $(p.target); + else + g.handler = (typeof handler == 'string' ? $(handler, p.target) : handler); + }, + _setTarget: function (target) + { + this.target = $(target); + }, + _setCursor: function (cursor) + { + this.cursor = cursor; + (this.proxy || this.handler).css('cursor', cursor); + }, + _createProxy: function (proxy, e) + { + if (!proxy) return; + var g = this, p = this.options; + if (typeof proxy == 'function') + { + g.proxy = proxy.call(this.options.target, g, e); + } + else if (proxy == 'clone') + { + g.proxy = g.target.clone().css('position', 'absolute'); + g.proxy.appendTo('body'); + } + else + { + g.proxy = $("<div class='l-draggable'></div>"); + g.proxy.width(g.target.width()).height(g.target.height()) + g.proxy.attr("dragid", g.id).appendTo('body'); + } + g.proxy.css({ + left: p.proxyX == null ? g.current.left : g.current.startX + p.proxyX, + top: p.proxyY == null ? g.current.top : g.current.startY + p.proxyY + }).show(); + }, + _removeProxy: function () + { + var g = this; + if (g.proxy) + { + g.proxy.remove(); + g.proxy = null; + } + } + + }); + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerEasyTab = function () + { + return $.ligerui.run.call(this, "ligerEasyTab", arguments); + }; + $.fn.ligerGetEasyTabManager = function () + { + return $.ligerui.run.call(this, "ligerGetEasyTabManager", arguments); + }; + + $.ligerDefaults.EasyTab = {}; + + $.ligerMethos.EasyTab = {}; + + $.ligerui.controls.EasyTab = function (element, options) + { + $.ligerui.controls.EasyTab.base.constructor.call(this, element, options); + }; + $.ligerui.controls.EasyTab.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'EasyTab'; + }, + __idPrev: function () + { + return 'EasyTab'; + }, + _extendMethods: function () + { + return $.ligerMethos.EasyTab; + }, + _render: function () + { + var g = this, p = this.options; + g.tabs = $(this.element); + g.tabs.addClass("l-easytab"); + var selectedIndex = 0; + if ($("> div[lselected=true]", g.tabs).length > 0) + selectedIndex = $("> div", g.tabs).index($("> div[lselected=true]", g.tabs)); + g.tabs.ul = $('<ul class="l-easytab-header"></ul>'); + $("> div", g.tabs).each(function (i, box) + { + var li = $('<li><span></span></li>'); + if (i == selectedIndex) + $("span", li).addClass("l-selected"); + if ($(box).attr("title")) + { + $("span", li).html($(box).attr("title")); + $(box).removeAttr("title"); + } + g.tabs.ul.append(li); + if (!$(box).hasClass("l-easytab-panelbox")) $(box).addClass("l-easytab-panelbox"); + }); + g.tabs.ul.prependTo(g.tabs); + //init + $(".l-easytab-panelbox:eq(" + selectedIndex + ")", g.tabs).show().siblings(".l-easytab-panelbox").hide(); + //add even + $("> ul:first span", g.tabs).click(function () + { + if ($(this).hasClass("l-selected")) return; + var i = $("> ul:first span", g.tabs).index(this); + $(this).addClass("l-selected").parent().siblings().find("span.l-selected").removeClass("l-selected"); + $(".l-easytab-panelbox:eq(" + i + ")", g.tabs).show().siblings(".l-easytab-panelbox").hide(); + }).not("l-selected").hover(function () + { + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + g.set(p); + } + }); + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerFilter = function () + { + return $.ligerui.run.call(this, "ligerFilter", arguments); + }; + + $.fn.ligerGetFilterManager = function () + { + return $.ligerui.run.call(this, "ligerGetFilterManager", arguments); + }; + + $.ligerDefaults.Filter = { + //字段列表 + fields: [], + //字段类型 - 运算符 的对应关系 + operators: {}, + //自定义输入框(如下拉框、日期) + editors: {}, + buttonCls : null + }; + $.ligerDefaults.FilterString = { + strings: { + "and": "并且", + "or": "或者", + "equal": "相等", + "notequal": "不相等", + "startwith": "以..开始", + "endwith": "以..结束", + "like": "相似", + "greater": "大于", + "greaterorequal": "大于或等于", + "less": "小于", + "lessorequal": "小于或等于", + "in": "包括在...", + "notin": "不包括...", + "addgroup": "增加分组", + "addrule": "增加条件", + "deletegroup": "删除分组" + } + }; + + $.ligerDefaults.Filter.operators['string'] = + $.ligerDefaults.Filter.operators['text'] = + ["equal", "notequal", "startwith", "endwith", "like", "greater", "greaterorequal", "less", "lessorequal", "in", "notin"]; + + $.ligerDefaults.Filter.operators['number'] = + $.ligerDefaults.Filter.operators['int'] = + $.ligerDefaults.Filter.operators['float'] = + $.ligerDefaults.Filter.operators['date'] = + ["equal", "notequal", "greater", "greaterorequal", "less", "lessorequal", "in", "notin"]; + + $.ligerDefaults.Filter.editors['string'] = + { + create: function (container, field) + { + var input = $("<input type='text'/>"); + container.append(input); + input.ligerTextBox(field.editor.options || {}); + return input; + }, + setValue: function (input, value) + { + input.val(value); + }, + getValue: function (input) + { + return input.liger('option', 'value'); + }, + destroy: function (input) + { + input.liger('destroy'); + } + }; + + $.ligerDefaults.Filter.editors['date'] = + { + create: function (container, field) + { + var input = $("<input type='text'/>"); + container.append(input); + input.ligerDateEditor(field.editor.options || {}); + return input; + }, + setValue: function (input, value) + { + input.liger('option', 'value', value); + }, + getValue: function (input, field) + { + return input.liger('option', 'value'); + }, + destroy: function (input) + { + input.liger('destroy'); + } + }; + + $.ligerDefaults.Filter.editors['number'] = + { + create: function (container, field) + { + var input = $("<input type='text'/>"); + container.append(input); + var options = { + minValue: field.editor.minValue, + maxValue: field.editor.maxValue + }; + input.ligerSpinner($.extend(options, field.editor.options || {})); + return input; + }, + setValue: function (input, value) + { + input.val(value); + }, + getValue: function (input, field) + { + var isInt = field.editor.type == "int"; + if (isInt) + return parseInt(input.val(), 10); + else + return parseFloat(input.val()); + }, + destroy: function (input) + { + input.liger('destroy'); + } + }; + + $.ligerDefaults.Filter.editors['combobox'] = + { + create: function (container, field) + { + var input = $("<input type='text'/>"); + container.append(input); + var options = { + data: field.data, + slide: false, + valueField: field.editor.valueField || field.editor.valueColumnName, + textField: field.editor.textField || field.editor.displayColumnName + }; + $.extend(options, field.editor.options || {}); + input.ligerComboBox(options); + return input; + }, + setValue: function (input, value) + { + input.liger('option', 'value', value); + }, + getValue: function (input) + { + return input.liger('option', 'value'); + }, + destroy: function (input) + { + input.liger('destroy'); + } + }; + + //过滤器组件 + $.ligerui.controls.Filter = function (element, options) + { + $.ligerui.controls.Filter.base.constructor.call(this, element, options); + }; + + $.ligerui.controls.Filter.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Filter' + }, + __idPrev: function () + { + return 'Filter'; + }, + _init: function () + { + var g = this, p = this.options; + $.ligerui.controls.Filter.base._init.call(this); + //编辑构造器初始化 + for (var type in liger.editors) + { + var editor = liger.editors[type]; + //如果没有默认的或者已经定义 + if (!editor || type in p.editors) continue; + p.editors[type] = liger.getEditor($.extend({ + type: type, + master: g + }, editor)); + } + }, + _render: function () + { + var g = this, p = this.options; + + g.set(p); + //事件:增加分组 + $(g.element).bind("click", function (e) + { + e.preventDefault(); + var jthis = $((e.target || e.srcElement)); + var cn = jthis.get(0).className; + if (cn.indexOf("addgroup") >= 0) + { + var jtable = jthis.parent().parent().parent().parent(); + g.addGroup(jtable); + } + else if (cn.indexOf("deletegroup") >= 0) + { + var jtable = jthis.parent().parent().parent().parent(); + g.deleteGroup(jtable); + } + else if (cn.indexOf("addrule") >= 0) + { + var jtable = jthis.parent().parent().parent().parent(); + g.addRule(jtable); + } + else if (cn.indexOf("deleterole") >= 0) + { + var rulerow = jthis.parent().parent(); + g.deleteRule(rulerow); + } + }); + + }, + + //设置字段列表 + _setFields: function (fields) + { + var g = this, p = this.options; + if (g.group) g.group.remove(); + g.group = $(g._bulidGroupTableHtml()).appendTo(g.element); + p.buttonCls && g.group.find(".addgroup,.addrule,.deletegroup").addClass(p.buttonCls); + }, + + //输入框列表 + editors: {}, + + //输入框计算器 + editorCounter: 0, + + //增加分组 + //parm [jgroup] jQuery对象(主分组的table dom元素) + addGroup: function (jgroup) + { + var g = this, p = this.options; + jgroup = $(jgroup || g.group); + var lastrow = $(">tbody:first > tr:last", jgroup); + var groupHtmlArr = []; + groupHtmlArr.push('<tr class="l-filter-rowgroup"><td class="l-filter-cellgroup" colSpan="4">'); + var altering = !jgroup.hasClass("l-filter-group-alt"); + groupHtmlArr.push(g._bulidGroupTableHtml(altering, true)); + groupHtmlArr.push('</td></tr>'); + var row = $(groupHtmlArr.join('')); + p.buttonCls && row.find(".addgroup,.addrule,.deletegroup").addClass(p.buttonCls); + lastrow.before(row); + var jtable = row.find("table:first"); + if (p.addDefult) + { + g.addRule(jtable); + } + return jtable; + }, + + //删除分组 + deleteGroup: function (group) + { + var g = this, p = this.options; + $("td.l-filter-value", group).each(function () + { + var rulerow = $(this).parent(); + $("select.fieldsel", rulerow).unbind(); + g.removeEditor(rulerow); + }); + $(group).parent().parent().remove(); + }, + + + //删除编辑器 + removeEditor: function (rulerow) + { + var g = this, p = this.options; + var type = $(rulerow).attr("editortype"); + var id = $(rulerow).attr("editorid"); + var editor = g.editors[id]; + if (editor && p.editors[type].destroy) + { + p.editors[type].destroy(editor); + } + $("td.l-filter-value:first", rulerow).html(""); + }, + + //设置规则 + //parm [group] 分组数据 + //parm [jgruop] 分组table dom jQuery对象 + setData: function (group, jgroup) + { + var g = this, p = this.options; + jgroup = jgroup || g.group; + var lastrow = $(">tbody:first > tr:last", jgroup); + if (jgroup) + { + jgroup.find(">tbody:first > tr").not(lastrow).remove(); + } + $("select:first", lastrow).val(group.op); + if (group.rules) + { + $(group.rules).each(function () + { + var rulerow = g.addRule(jgroup); + var fieldName = this.field; + + var field = (function () + { + for (var i = 0; i < p.fields.length; i++) + { + if (p.fields[i].name == fieldName) + { + return p.fields[i]; + } + } + return null; + })(); + $("select.opsel", rulerow).html(g._bulidOpSelectOptionsHtml(this.type || "string", field.operator )); + rulerow.attr("fieldtype", this.type || "string"); + $("select.opsel", rulerow).val(this.op); + $("select.fieldsel", rulerow).val(this.field).trigger('change'); + var editorid = rulerow.attr("editorid"); + if (editorid && g.editors[editorid]) + { + var field = g.getField(this.field); + if (field && field.editor) + { + var editParm = { + field: field, + filter: g + }; + p.editors[field.editor.type].setValue.call(g, g.editors[editorid], this.value, editParm); + } + } + else + { + $(":text", rulerow).val(this.value); + } + }); + } + if (group.groups) + { + $(group.groups).each(function () + { + var subjgroup = g.addGroup(jgroup); + g.setData(this, subjgroup); + }); + } + }, + + //增加一个条件 + //parm [jgroup] 分组的jQuery对象 + addRule: function (jgroup) + { + var g = this, p = this.options; + jgroup = jgroup || g.group; + var lastrow = $(">tbody:first > tr:last", jgroup); + var rulerow = $(g._bulidRuleRowHtml()); + lastrow.before(rulerow); + if (p.fields.length) + { + //如果第一个字段启用了自定义输入框 + g.appendEditor(rulerow, p.fields[0]); + } + + //事件:字段列表改变时 + $("select.fieldsel", rulerow).bind('change', function () + { + var jopsel = $(this).parent().next().find("select:first"); + var fieldName = $(this).val(); + if (!fieldName) return; + var field = g.getField(fieldName); + //字段类型处理 + var fieldType = field.type || "string"; + var oldFieldtype = rulerow.attr("fieldtype"); + if (fieldType != oldFieldtype) + { + jopsel.html(g._bulidOpSelectOptionsHtml(fieldType,field.operator )); + rulerow.attr("fieldtype", fieldType); + } + //当前的编辑器 + var editorType = null; + //上一次的编辑器 + var oldEditorType = rulerow.attr("editortype"); + if (g.enabledEditor(field)) editorType = field.editor.type; + if (oldEditorType) + { + //如果存在旧的输入框 + g.removeEditor(rulerow); + } + if (editorType) + { + //如果当前选择的字段定义了输入框 + g.appendEditor(rulerow, field); + } else + { + rulerow.removeAttr("editortype").removeAttr("editorid"); + $("td.l-filter-value:first", rulerow).html('<input type="text" class="valtxt l-text" />'); + } + }); + return rulerow; + }, + + //删除一个条件 + deleteRule: function (rulerow) + { + $("select.fieldsel", rulerow).unbind(); + this.removeEditor(rulerow); + $(rulerow).remove(); + }, + + //附加一个输入框 + appendEditor: function (rulerow, field) + { + var g = this, p = this.options; + if (g.enabledEditor(field)) + { + var container = $("td.l-filter-value:first", rulerow).html(""); + var editor = p.editors[field.editor.type]; + + var editorTag = ++g.editorCounter; + + var editParm = { + filter: g + }; + editParm.field = $.extend(true, {}, field); + editParm.field.name = field.name + "_" + editorTag; + g.editors[editorTag] = editor.create.call(this, container, editParm); + rulerow.attr("editortype", field.editor.type).attr("editorid", editorTag); + } + }, + + //获取分组数据 + getData: function (group) + { + var g = this, p = this.options; + group = group || g.group; + + var groupData = {}; + + $("> tbody > tr", group).each(function (i, row) + { + var rowlast = $(row).hasClass("l-filter-rowlast"); + var rowgroup = $(row).hasClass("l-filter-rowgroup"); + if (rowgroup) + { + var groupTable = $("> td:first > table:first", row); + if (groupTable.length) + { + if (!groupData.groups) groupData.groups = []; + groupData.groups.push(g.getData(groupTable)); + } + } + else if (rowlast) + { + groupData.op = $(".groupopsel:first", row).val(); + } + else + { + var fieldName = $("select.fieldsel:first", row).val(); + var field = g.getField(fieldName); + var op = $(".opsel:first", row).val(); + var value = g._getRuleValue(row, field); + var type = $(row).attr("fieldtype") || "string"; + if (!groupData.rules) groupData.rules = []; + if (value != null) + { + groupData.rules.push({ + field: fieldName, op: op, value: value, type: type + }); + } + } + }); + + return groupData; + }, + + _getRuleValue: function (rulerow, field) + { + var g = this, p = this.options; + var editorid = $(rulerow).attr("editorid"); + var editortype = $(rulerow).attr("editortype"); + var editor = g.editors[editorid]; + var editParm = { + field: field, + filter: g + }; + if (editor) + { + return p.editors[editortype].getValue.call(g, editor, editParm); + } + return $(".valtxt:first", rulerow).val(); + }, + + //判断某字段是否启用自定义的输入框 + enabledEditor: function (field) + { + var g = this, p = this.options; + if (!field.editor || !field.editor.type) return false; + return (field.editor.type in p.editors); + }, + + //根据fieldName 获取 字段 + getField: function (fieldname) + { + var g = this, p = this.options; + for (var i = 0, l = p.fields.length; i < l; i++) + { + var field = p.fields[i]; + if (field.name == fieldname) return field; + } + return null; + }, + + //获取一个分组的html + _bulidGroupTableHtml: function (altering, allowDelete) + { + var g = this, p = this.options; + var tableHtmlArr = []; + tableHtmlArr.push('<table cellpadding="0" cellspacing="0" border="0" class="l-filter-group'); + if (altering) + tableHtmlArr.push(' l-filter-group-alt'); + tableHtmlArr.push('"><tbody>'); + tableHtmlArr.push('<tr class="l-filter-rowlast"><td class="l-filter-rowlastcell" align="right" colSpan="4">'); + //and or + tableHtmlArr.push('<select class="groupopsel">'); + tableHtmlArr.push('<option value="and">' + p.strings['and'] + '</option>'); + tableHtmlArr.push('<option value="or">' + p.strings['or'] + '</option>'); + tableHtmlArr.push('</select>'); + + //add group + tableHtmlArr.push('<input type="button" value="' + p.strings['addgroup'] + '" class="addgroup">'); + //add rule + tableHtmlArr.push('<input type="button" value="' + p.strings['addrule'] + '" class="addrule">'); + if (allowDelete) + tableHtmlArr.push('<input type="button" value="' + p.strings['deletegroup'] + '" class="deletegroup">'); + + tableHtmlArr.push('</td></tr>'); + + tableHtmlArr.push('</tbody></table>'); + return tableHtmlArr.join(''); + }, + + //获取字段值规则的html + _bulidRuleRowHtml: function (fields) + { + var g = this, p = this.options; + fields = fields || p.fields; + var rowHtmlArr = []; + var fieldType = fields && fields.length && fields[0].type ? fields[0].type : "string"; + rowHtmlArr.push('<tr fieldtype="' + fieldType + '"><td class="l-filter-column">'); + rowHtmlArr.push('<select class="fieldsel">'); + for (var i = 0, l = fields.length; i < l; i++) + { + var field = fields[i]; + rowHtmlArr.push('<option value="' + field.name + '"'); + if (i == 0) rowHtmlArr.push(" selected "); + rowHtmlArr.push('>'); + rowHtmlArr.push(field.display); + rowHtmlArr.push('</option>'); + } + rowHtmlArr.push("</select>"); + rowHtmlArr.push('</td>'); + + rowHtmlArr.push('<td class="l-filter-op">'); + rowHtmlArr.push('<select class="opsel">'); + rowHtmlArr.push(g._bulidOpSelectOptionsHtml(fieldType, fields && fields.length ? fields[0].operator : null)); + rowHtmlArr.push('</select>'); + rowHtmlArr.push('</td>'); + rowHtmlArr.push('<td class="l-filter-value">'); + rowHtmlArr.push('<input type="text" class="valtxt" />'); + rowHtmlArr.push('</td>'); + rowHtmlArr.push('<td>'); + rowHtmlArr.push('<div class="l-icon-cross deleterole"></div>'); + rowHtmlArr.push('</td>'); + rowHtmlArr.push('</tr>'); + return rowHtmlArr.join(''); + }, + + //获取一个运算符选择框的html + _bulidOpSelectOptionsHtml: function (fieldType, operator) + { + var g = this, p = this.options; + var ops = p.operators[fieldType]; + var opHtmlArr = []; + if (operator && operator.length) + { + ops = operator.split(','); + } + if (!ops || !ops.length) + { + ops = ["equal", "notequal"]; + } + for (var i = 0, l = ops.length; i < l; i++) + { + var op = ops[i]; + opHtmlArr[opHtmlArr.length] = '<option value="' + op + '">'; + opHtmlArr[opHtmlArr.length] = p.strings[op]; + opHtmlArr[opHtmlArr.length] = '</option>'; + } + return opHtmlArr.join(''); + } + + + }); + + $.ligerFilter = function () { }; + $.ligerFilter.filterTranslator = { + translateGroup: function (group) + { + var out = []; + if (group == null) return " 1==1 "; + var appended = false; + out.push('('); + if (group.rules != null) + { + for (var i in group.rules) + { + if (i == "indexOf") + continue; + var rule = group.rules[i]; + if (appended) + out.push(this.getOperatorQueryText(group.op)); + out.push(this.translateRule(rule)); + appended = true; + } + } + if (group.groups != null) + { + for (var j in group.groups) + { + var subgroup = group.groups[j]; + if (appended) + out.push(this.getOperatorQueryText(group.op)); + out.push(this.translateGroup(subgroup)); + appended = true; + } + } + out.push(')'); + if (appended == false) return " 1==1 "; + return out.join(''); + }, + + translateRule: function (rule) + { + var out = []; + if (rule == null) return " 1==1 "; + if (rule.op == "like" || rule.op == "startwith" || rule.op == "endwith") + { + out.push('/'); + if (rule.op == "startwith") + out.push('^'); + out.push(rule.value); + if (rule.op == "endwith") + out.push('$'); + out.push('/i.test('); + out.push('o["'); + out.push(rule.field); + out.push('"]'); + out.push(')'); + return out.join(''); + } + out.push('o["'); + out.push(rule.field); + out.push('"]'); + out.push(this.getOperatorQueryText(rule.op)); + out.push('"'); + out.push(rule.value); + out.push('"'); + return out.join(''); + }, + + getOperatorQueryText: function (op) + { + switch (op) + { + case "equal": + return " == "; + case "notequal": + return " != "; + case "greater": + return " > "; + case "greaterorequal": + return " >= "; + case "less": + return " < "; + case "lessorequal": + return " <= "; + case "and": + return " && "; + case "or": + return " || "; + default: + return " == "; + } + } + + }; + $.ligerFilter.getFilterFunction = function (condition) + { + if ($.isArray(condition)) + condition = { op: "and", rules: condition }; + var fnbody = ' return ' + $.ligerFilter.filterTranslator.translateGroup(condition); + return new Function("o", fnbody); + }; + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerForm = function () + { + return $.ligerui.run.call(this, "ligerForm", arguments); + }; + + $.ligerui.getConditions = function (form, options) + { + if (!form) return null; + form = liger.get($(form)); + if (form && form.toConditions) return form.toConditions(); + }; + + $.ligerDefaults = $.ligerDefaults || {}; + $.ligerDefaults.Form = { + width: null, // 表单的宽度 + //控件宽度 + inputWidth: 180, + //标签宽度 + labelWidth: 90, + //间隔宽度 + space: 40, + rightToken: ':', + //标签对齐方式 + labelAlign: 'left', + //控件对齐方式 + align: 'left', + + autoTypePrev : 'ui-', + //字段 + /* + 数组的集合,支持的类型包括在$.ligerDefaults.Form.editors,这个editors同Grid的editors继承于base.js中提供的编辑器集合,具体可以看liger.editors + 字段的参数参考 127行左右的 $.ligerDefaults.Form_fields, + ui内置的编辑表单元素都会调用ui的表单插件集合,所以这些字段都有属于自己的"liger对象",可以同liger.get("[ID]")的方式获取,这里的[ID]获取方式优先级如下: + 1,定义了field.id 则取field.id + 2,如果是下拉框和PopupEdit,并且定义了comboboxName,则取comboboxName(如果表单定义了prefixID,需要加上) + 3,默认取field.name(如果表单定义了prefixID,需要加上) + */ + fields: [], + //创建的表单元素是否附加ID + appendID: true, + //生成表单元素ID、Name的前缀 + prefixID: null, + //json解析函数 + toJSON: $.ligerui.toJSON, + labelCss: null, + fieldCss: null, + spaceCss: null, + onAfterSetFields: null, + // 参数同 ligerButton + buttons: null, //按钮组 + readonly: false, //是否只读 + editors: {}, //编辑器集合,使用同$.ligerDefaults.Grid.editors + //验证 + validate: null, + //不设置validate属性到inuput + unSetValidateAttr: false, + tab: null, + clsTab: 'ui-tabs-nav ui-helper-clearfix', + clsTabItem: 'ui-state-default', + clsTabItemSelected: 'ui-tabs-selected', + clsTabContent: 'ui-tabs-panel ui-widget-content' + }; + + $.ligerDefaults.FormString = { + invalidMessage: '存在{errorCount}个字段验证不通过,请检查!', + detailMessage: '详细', + okMessage: '确定' + }; + + $.ligerDefaults.Form.editors.textarea = + { + create: function (container, editParm, p) + { + var editor = $('<textarea class="l-textarea" />'); + var id = (p.prefixID || "") + editParm.field.name; + if ($("#" + id).length) + { + editor = $("#" + id); + } + editor.attr({ + id: id, + name: id + }); + if (editParm.field.editor && editParm.field.editor.height) + { + editor.height(editParm.field.editor.height); + } + if (p.readonly) editor.attr("readonly", true); + container.append(editor); + return editor; + }, + getValue: function (editor, editParm) + { + return editor.val(); + }, + setValue: function (editor, value, editParm) + { + editor.val(value); + }, + resize: function (editor, width, height, editParm) + { + editor.css({ + width: width - 2 + }).parent().css("width", "auto"); + } + }; + + $.ligerDefaults.Form.editors.hidden = + { + create: function (container, editParm, p) + { + var editor = $('<input type = "hidden" />'); + var id = (p.prefixID || "") + editParm.field.name; + if ($("#" + id).length) + { + editor = $("#" + id); + } + //添加options.attr属性的设置 + editor.attr($.extend({ + id: id, + name: id + }, editParm.field.attr)); + var eo = editParm.field.editor || editParm.field.options; + eo && editor.val(eo.value); + container.append(editor); + return editor; + }, + getValue: function (editor, editParm) + { + return editor.val(); + }, + setValue: function (editor, value, editParm) + { + editor.val(value); + } + }; + + $.ligerDefaults.Form_fields = { + name: null, //字段name + textField: null, //文本框name + type: null, //表单类型 + editor: null, //编辑器扩展 + label: null, //Label + labelInAfter: false, //label显示在后面 + afterContent: null, //后置内容 + beforeContent : null, //前置内容 + hideSpace: false, + hideLabel: false, + rightToken: null, + attrRender: null, + style : null, + containerCls : null, + newline: true, //换行显示 + op: null, //操作符 附加到input + vt: null, //值类型 附加到input + attr: null, //属性列表 附加到input + validate: null //验证参数,比如required:true + }; + + $.ligerDefaults.Form_editor = { + }; + + //description 自动创建自定义风格的表单-编辑器构造函数 + //格式为: + //{ + // name: jinput.attr("name"), + // control: { + // getValue: function () + // { + // return jinput.val(); + // }, + // setValue: function (value) + // { + // jinput.val(value); + // } + // } + //} + //editorBulider -> editorBuilder 命名错误 + //param {jinput} 表单元素jQuery对象 比如input、select、textarea + $.ligerDefaults.Form.editorBulider = function (jinput) + { + //这里this就是form的ligerui对象 + var g = this, p = this.options; + if (!jinput || !jinput.length) return; + var options = {}, ltype = jinput.attr("ltype"), field = {}; + if (p.readonly) options.readonly = true; + options = $.extend({ + width: (field.width || p.inputWidth) - 2 + }, field.options, field.editor, options); + var control = null; + + if (ltype == "autocomplete") + options.autocomplete = true; + if (jinput.is("select") && ltype != "none") + { + control = jinput.ligerComboBox(options); + } + else if (jinput.is(":password") && ltype != "none") + { + control = jinput.ligerTextBox(options); + } + else if (jinput.is(":radio") && ltype != "none") + { + control = jinput.ligerRadio(options); + } + else if (jinput.is(":checkbox") && ltype != "none") + { + control = jinput.ligerCheckBox(options); + } + else if (jinput.is("textarea") && ltype != "none") + { + jinput.addClass("l-textarea"); + + control = { + getValue: function () + { + return jinput.val(); + }, + setValue: function (value) + { + jinput.val(value); + } + }; + } + else if (ltype && ltype != "none") + { + if (jinput.is(":text")) + { + switch (ltype) + { + case "select": + case "combobox": + case "autocomplete": + control = jinput.ligerComboBox(options); + break; + case "spinner": + control = jinput.ligerSpinner(options); + break; + case "date": + control = jinput.ligerDateEditor(options); + break; + case "popup": + control = jinput.ligerPopupEdit(options); + break; + case "currency": + control = options.currency = true; + case "float": + case "number": + options.number = true; + control = jinput.ligerTextBox(options); + break; + case "int": + case "digits": + options.digits = true; + default: + control = jinput.ligerTextBox(options); + break; + } + } + else if (jinput.is(":hidden")) + { + switch (ltype) + { + case "select": + case "combobox": + case "autocomplete": + control = jinput.ligerComboBox(options); + break; + case "checkboxlist": + control = jinput.ligerCheckBoxList(options); + break; + case "radiolist": + control = jinput.ligerRadioList(options); + break; + case "listbox": + control = jinput.ligerListBox(options); + break; + } + } + } + else //没有定义ltype的 text or hidden + { + var classname = jinput.get(0).className; + if (classname) + { + var autoTypePrev = p.autoTypePrev || "ui-"; + if (classname.indexOf(autoTypePrev) != -1) + { + classname = classname.replace(autoTypePrev, ""); + } + } + if (!classname && (jinput.is(":hidden") || jinput.is(":text")) && jinput.attr("name")) //没有匹配的classname + { + control = { + getValue: function () + { + return jinput.val(); + }, + setValue: function (value) + { + jinput.val(value); + } + }; + } + else + { + switch (classname) + { + case "textbox": + case "password": + control = jinput.ligerTextBox(options); + break; + case "datepicker": + control = jinput.ligerDateEditor(options); + break; + case "spinner": + control = jinput.ligerSpinner(options); + break; + case "checkbox": + control = jinput.ligerCheckBox(options); + break; + case "combobox": + control = jinput.ligerComboBox(options); + break; + case "checkboxlist": + control = jinput.ligerCheckBoxList(options); + break; + case "radiolist": + control = jinput.ligerRadioList(options); + break; + case "listbox": + control = jinput.ligerListBox(options); + break; + } + } + } + if (!control) return null; + return { + name: jinput.attr("name"), + control: control + }; + } + + //表单组件 + $.ligerui.controls.Form = function (element, options) + { + $.ligerui.controls.Form.base.constructor.call(this, element, options); + }; + + $.ligerui.controls.Form.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Form' + }, + __idPrev: function () + { + return 'Form'; + }, + _init: function () + { + var g = this, p = this.options; + $.ligerui.controls.Form.base._init.call(this); + //编辑构造器初始化 + for (var type in liger.editors) + { + var editor = liger.editors[type]; + //如果没有默认的或者已经定义 + if (!editor || type in p.editors) continue; + p.editors[type] = liger.getEditor($.extend({ + type: type, + master: g + }, editor)); + } + }, + _render: function () + { + var g = this, p = this.options; + var jform = $(this.element); + g.form = jform.is("form") ? jform : jform.parents("form:first"); + //生成ligerui表单样式 + $("input,select,textarea", jform).each(function () + { + var result = p.editorBulider.call(g, $(this)); + if (result) + { + g.autoEditors = g.autoEditors || []; + g.autoEditors.push(result); + } + }); + if (g.autoEditors && g.autoEditors.length && p.validate) + { + g.validate = g.validate || {}; + $(g.autoEditors).each(function () + { + var name = this.name; + var control = this.control; + if (name && control.inputText && control.inputText.attr("validate")) + { + var v = null, vm = null; + eval("v = " + control.inputText.attr("validate")); + if (v) + { + g.validate.rules = g.validate.rules || {}; + g.validate.rules[name] = v; + } + if (control.inputText.attr("validateMessage")) + { + eval("vm = " + control.inputText.attr("validateMessage")); + if (vm) + { + g.validate.messages = g.validate.messages || {}; + g.validate.messages[name] = vm; + } + } + } + }); + } + + + g.set(p); + g.initValidate(); + if (p.buttons) + { + var jbuttons = $('<ul class="l-form-buttons"></ul>').appendTo(jform); + $(p.buttons).each(function () + { + var jbutton = $('<li><div></div></li>').appendTo(jbuttons); + $("div:first", jbutton).ligerButton(this); + }); + } + + if (!g.element.id) g.element.id = g.id; + //分组 收缩/展开 + $("#" + g.element.id + " .togglebtn").live('click', function () + { + if ($(this).hasClass("togglebtn-down")) $(this).removeClass("togglebtn-down"); + else $(this).addClass("togglebtn-down"); + var boxs = $(this).parent().nextAll("ul,div"); + for (var i = 0; i < boxs.length; i++) + { + var jbox = $(boxs[i]); + if (jbox.hasClass("l-group")) break; + if ($(this).hasClass("togglebtn-down")) + { + jbox.hide(); + } else + { + jbox.show(); + } + + } + }); + }, + _setWidth: function (value) + { + var g = this, p = this.options; + if (value) g.form.width(value); + }, + getEditor: function (name) + { + var g = this, p = this.options; + if (!g.editors) return; + var o = find(null); + if (o) return o; + if (p.tab && p.tab.items) + { + for (var i = 0; i < p.tab.items.length; i++) + { + var item = p.tab.items[i]; + var o = find(item, i); + if (o) return o; + } + } + return null; + function find(tabitem, tabindex) + { + var fields = tabitem == null ? p.fields : tabitem.fields; + for (var i = 0, l = fields.length; i < l; i++) + { + var field = fields[i]; + var eIndex = tabindex == null ? i : "tab" + tabindex + "_" + i; + if (field.name == name && g.editors[eIndex]) + { + return g.editors[eIndex].control; + } + } + } + }, + getField: function (index) + { + var g = this, p = this.options; + if (!p.fields) return null; + return p.fields[index]; + }, + toConditions: function () + { + var g = this, p = this.options; + var conditions = []; + + $(p.fields).each(function (fieldIndex, field) + { + var name = field.name, textField = field.textField, editor = g.editors[fieldIndex]; + if (!editor || !name) return; + var value = editor.editor.getValue.call(g, editor.control, { + field: field + }); + if (value != null && value !== "") + { + conditions.push({ + op: field.operator || "like", + field: name, + value: value, + type: field.type || "string" + }); + } + }); + return conditions; + }, + //预处理字段 , 处理分组 + _preSetFields: function (fields) + { + var g = this, p = this.options, lastVisitedGroup = null, lastVisitedGroupIcon = null; + //分组: 先填充没有设置分组的字段 + $(p.fields).each(function (i, field) + { + if (p.readonly || field.readonly || (field.editor && field.editor.readonly)) + { + //if (!field.editor) field.editor = {}; + //field.editor.readonly = field.editor.readonly || true; + delete field.validate; + } + if (field.type == "hidden") return; + field.type = field.type || "text"; + if (field.newline == null) field.newline = true; + if (lastVisitedGroup && !field.group) + { + field.group = lastVisitedGroup; + field.groupicon = lastVisitedGroupIcon; + } + if (field.group) + { + field.group = field.group.toString().replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + lastVisitedGroup = field.group; + lastVisitedGroupIcon = field.groupicon; + } + }); + + }, + _setReadonly: function (readonly) + { + var g = this, p = this.options; + if (readonly && g.editors) + { + for (var index in g.editors) + { + var control = g.editors[index].control; + if (control && control._setReadonly) control._setReadonly(true); + } + } + }, + _setFields: function (fields) + { + var g = this, p = this.options; + if ($.isFunction(p.prefixID)) p.prefixID = p.prefixID(g); + var jform = $(g.element).addClass("l-form"); + g._initFieldsValidate({ + fields: fields + }); + g._initFieldsHtml({ + panel: jform, + fields: fields + }); + g._createEditors({ + fields: fields + }); + g.trigger('afterSetFields'); + }, + _initFieldsValidate: function (e) + { + var g = this, p = this.options; + var fields = e.fields; + g.validate = g.validate || {}; + + + + if (fields && fields.length) + { + $(fields).each(function (index, field) + { + var name = field.name, + readonly = (field.readonly || (field.editor && field.editor.readonly)) ? true : false, + txtInputName = (p.prefixID || "") + (field.textField || field.id || field.name); + if (field.validate && !readonly) + { + g.validate.rules = g.validate.rules || {}; + g.validate.rules[txtInputName] = field.validate; + if (field.validateMessage) + { + g.validate.messages = g.validate.messages || {}; + g.validate.messages[txtInputName] = field.validateMessage; + } + } + }); + } + }, + _initFieldsHtml: function (e) + { + var g = this, p = this.options; + var jform = e.panel, + fields = e.fields, + idPrev = e.idPrev || g.id, + tabindex = e.tabindex; + $(">.l-form-container", jform).remove(); + var lineWidth = 0, maxWidth = 0; + if (fields && fields.length) + { + g._preSetFields(fields); + var out = ['<div class="l-form-container">'], + appendULStartTag = false, + lastVisitedGroup = null, + groups = []; + $(fields).each(function (index, field) + { + if (!field.group) field.group = ""; + if ($.inArray(field.group, groups) == -1) + groups.push(field.group); + }); + $(groups).each(function (groupIndex, group) + { + $(fields).each(function (i, field) + { + if (field.group != group) return; + var index = $.inArray(field, fields); + var name = field.id || field.name, newline = field.newline; + var inputName = (p.prefixID || "") + (field.id || field.name); + if (!name) return; + if (field.type == "hidden") + { + if (!$("#" + inputName).length) + out.push('<div style="display:none" id="' + (idPrev + "|" + i) + '"></div>'); + return; + } + var toAppendGroupRow = field.group && field.group != lastVisitedGroup; + if (index == 0 || toAppendGroupRow) newline = true; + if (newline) + { + lineWidth = 0; + if (appendULStartTag) + { + out.push('</ul>'); + appendULStartTag = false; + } + if (toAppendGroupRow) + { + out.push('<div class="l-group'); + if (field.groupicon) + out.push(' l-group-hasicon'); + out.push('">'); + if (field.groupicon) + out.push('<img src="' + field.groupicon + '" />'); + out.push('<span>' + field.group + '</span></div>'); + lastVisitedGroup = field.group; + } + out.push('<ul>'); + appendULStartTag = true; + } + out.push('<li class="l-fieldcontainer'); + if (newline) + { + out.push(' l-fieldcontainer-first'); + } + if (field.containerCls) + { + out.push(' ' + field.containerCls); + } + out.push('"'); + if (field.style) + { + out.push(' style="' + field.style + '"'); + } + out.push(' fieldindex="' + index + '"'); + if (tabindex != null) + { + out.push(' tabindex="' + tabindex + '"'); + } + if (field.attrRender) + { + out.push(' ' + field.attrRender()); + } + out.push('><ul>'); + //append field 编辑后面自定义内容 + if (field.beforeContent) //前置内容 + { + var beforeContent = $.isFunction(field.beforeContent) ? field.afterContent(field) : field.beforeContent; + beforeContent && out.push(beforeContent); + } + if (!field.hideLabel && !field.labelInAfter) + { + out.push(g._buliderLabelContainer(field, index)); + } + //append input + out.push(g._buliderControlContainer(field, index, e.idPrev)); + if (field.labelInAfter) + { + out.push(g._buliderLabelContainer(field, index)); + } + //append field 编辑后面自定义内容 + if (field.afterContent) + { + var afterContent = $.isFunction(field.afterContent) ? field.afterContent(field) : field.afterContent; + afterContent && out.push(afterContent); + } + //append space + if (!field.hideSpace) + { + out.push(g._buliderSpaceContainer(field, index)); + } + out.push('</ul></li>'); + + lineWidth += (field.width || p.inputWidth || 0); + lineWidth += (field.space || p.space || 0); + lineWidth += (field.labelWidth || p.labelWidth || 0); + if (lineWidth > maxWidth) maxWidth = lineWidth; + }); + }); + if (appendULStartTag) + { + out.push('</ul>'); + appendULStartTag = false; + } + out.push('<div class="l-clear"></div>'); + out.push('</div>'); + jform.append(out.join('')); + if (!p.width || maxWidth > p.width) + { + //jform.width(maxWidth + 10); + } + $(".l-group .togglebtn", jform).remove(); + $(".l-group", jform).width(jform.width() * 0.95).append("<div class='togglebtn'></div>"); + } + }, + _createEditors : function(e) + { + var g = this, p = this.options; + var fields = e.fields, + idPrev = e.idPrev || g.id, + editPrev = e.editPrev || ""; + g.editors = g.editors || {}; + var jform = $(g.element); + $(fields).each(function (fieldIndex, field) + { + var container = document.getElementById(idPrev + "|" + fieldIndex), + editor = p.editors[field.type], + editId = editPrev + fieldIndex; + if (!container) return; + container = $(container); + var editorControl = g._createEditor(editor, container, { + field: field + }, container.width(), container.height()); + if (!editorControl) return; + if (g.editors[editId] && g.editors[editId].control && g.editors[editId].control.destroy) + { + g.editors[editId].control.destroy(); + } + g.editors[editId] = { + control: editorControl, + editor: editor + }; + }); + }, + getChanges: function () + { + //本函数返回当前数据与上一次数据之间的差异. 如果没有差异, 则返回空对象. + //注意!! getData会导致数据被刷新. 必须严格控制getData的调用. + //调用本函数不会导致刷新数据. + var g = this, p = this.options; + var originData = g.data; + var curData = g.getData(); + g.data = originData; + + var c = {}; + for (var k in originData) + { + if (curData[k] != originData[k]) + c[k] = curData[k]; + } + return c; + }, + setEnabled: function (arg, isEnabled) + { + var fieldNames = []; + if ($.isArray(arg)) fieldNames = arg; + if (typeof (arg) == "string") fieldNames.push(arg); + var g = this, p = this.options; + setEnabledInFields(p.fields); + if (p.tab && p.tab.items) + { + for (var i = 0; i < p.tab.items.length; i++) + { + var item = p.tab.items[i]; + setEnabledInFields(item.fields, i); + } + } + function setEnabledInFields(fields, tabIndex) + { + $(fields).each(function (fieldIndex, field) + { + var name = field.name, + textField = field.textField, + editPrev = tabIndex == null ? "" : "tab" + tabIndex + "_", + editor = g.editors[editPrev + fieldIndex]; + if (!editor || !name) return; + if (!editor.editor || !editor.editor.setEnabled) return; + if ($.inArray(name, fieldNames) == -1) return; + editor.editor.setEnabled(editor.control, isEnabled); + }); + } + }, + setVisible: function (arg, isVisible) + { + var fieldNames = []; + if ($.isArray(arg)) fieldNames = arg; + if (typeof (arg) == "string") fieldNames.push(arg); + var g = this, p = this.options; + setVisibleInFields(p.fields); + if (p.tab && p.tab.items) + { + for (var i = 0; i < p.tab.items.length; i++) + { + var item = p.tab.items[i]; + setVisibleInFields(item.fields, i); + } + } + function setVisibleInFields(fields, tabIndex) + { + $(fields).each(function (fieldIndex, field) + { + var name = field.name; + if ($.inArray(name, fieldNames) == -1) return; + g._setFieldPanelVisible(tabIndex, fieldIndex, isVisible); + }); + } + }, + _setFieldPanelVisible: function (tabindex, fieldindex, visible) + { + var g = this, p = this.options; + if (tabindex == null) + { + $("li.l-fieldcontainer[fieldindex=" + fieldindex + "]", g.element)[visible ? 'show' : 'hide'](); + } + else + { + $("div."+p.clsTabContent+"[data-index=" + tabindex + "] li.l-fieldcontainer[fieldindex=" + fieldindex + "]", g.element)[visible ? 'show' : 'hide'](); + } + }, + getData: function () + { + var g = this, p = this.options; + g.data = g.formData || {}; + + if (g.autoEditors && g.autoEditors.length) + { + $(g.autoEditors).each(function () + { + var name = this.name; + var control = this.control; + if (name && control && control.getValue) + { + g.data[name] = control.getValue(); + } + }); + } + getFieldValueToData(p.fields); + if (p.tab && p.tab.items) + { + for (var i = 0; i < p.tab.items.length; i++) + { + var item = p.tab.items[i]; + getFieldValueToData(item.fields, i); + } + } + function getFieldValueToData(fields, tabIndex) + { + $(fields).each(function (fieldIndex, field) + { + + var name = field.name, + textField = field.textField, + editPrev = tabIndex == null ? "" : "tab" + tabIndex + "_", + editor = g.editors[editPrev + fieldIndex]; + if (!editor) return; + if (name) + { + var value = editor.editor.getValue.call(g, editor.control, { + field: field + }); + g._setValueByName(g.data, name, value); + } + if (textField && editor.editor.getText) + { + var value = editor.editor.getText.call(g, editor.control, { + field: field + }); + g._setValueByName(g.data, textField, value); + } + }); + } + return g.data; + }, + _setData: function (data) + { + this.setData(data); + }, + setData: function (data) + { + var g = this, p = this.options; + g.data = data || {}; + + if (g.autoEditors && g.autoEditors.length) + { + $(g.autoEditors).each(function () + { + var name = this.name; + var control = this.control; + if (name && g.data[name] && control && control.setValue) + { + control.setValue(g.data[name]); + } + }); + } + + setDataToFields(p.fields); + if (p.tab && p.tab.items) + { + for (var i = 0; i < p.tab.items.length; i++) + { + var item = p.tab.items[i]; + setDataToFields(item.fields, i); + } + } + function setDataToFields(fields, tabIndex) + { + $(fields).each(function (fieldIndex, field) + { + var name = field.name, + textField = field.textField, + editPrev = tabIndex == null ? "" : "tab" + tabIndex + "_", + editor = g.editors[editPrev + fieldIndex]; + if (!editor) return; + if (name && (name in g.data)) + { + var value = g._getValueByName(g.data, name); + editor.editor.setValue.call(g,editor.control, value, { + field: field + }); + } + if (textField && (textField in g.data)) + { + var text = g._getValueByName(g.data, textField); + editor.editor.setText.call(g, editor.control, text, { + field: field + }); + } + }); + } + }, + _setValueByName: function (data, name, value) + { + if (!data || !name) return null; + if (name.indexOf('.') == -1) + { + data[name] = value; + } + else + { + try + { + new Function("data,value", "data." + name + "=value;")(data, value); + } + catch (e) + { + } + } + }, + _getValueByName: function (data, name) + { + if (!data || !name) return null; + if (name.indexOf('.') == -1) + { + return data[name]; + } + else + { + try + { + return new Function("data", "return data." + name + ";")(data); + } + catch (e) + { + return null; + } + } + }, + //验证 + valid: function () + { + var g = this, p = this.options; + if (!g.form || !g.validator) return true; + return g.form.valid(); + }, + showFieldError: function (name, errorText) + { + var element = $("[name=" + name + "]", this.element); + if (element.hasClass("l-textarea")) + { + element.addClass("l-textarea-invalid"); + } + else if (element.hasClass("l-text-field")) + { + element.parent().addClass("l-text-invalid"); + } + $(element).removeAttr("title").ligerHideTip(); + $(element).attr("title", errorText).ligerTip({ + distanceX: 5, + distanceY: -3, + auto: true + }); + }, + hideFieldError: function (name) + { + var element = $("[name=" + name + "]", this.element); + if (element.hasClass("l-textarea")) + { + element.removeClass("l-textarea-invalid"); + } + else + { + element.parent().removeClass("l-text-invalid"); + } + $(element).removeAttr("title").ligerHideTip(); + }, + //设置验证 + initValidate: function () + { + var g = this, p = this.options; + if (!g.form || !p.validate || !g.form.validate) + { + g.validator = null; + return; + } + var validate = p.validate == true ? {} : p.validate; + var validateOptions = $.extend({ + errorPlacement: function (lable, element) + { + if (!$(lable).html()) + { + return; + } + if (!element.attr("id")) + { + var eleid = new Date().getTime(); + element.attr("id", eleid); + lable.attr("for", eleid); + } + if (element.hasClass("l-textarea")) + { + element.addClass("l-textarea-invalid"); + } + else if (element.hasClass("l-text-field")) + { + element.parent().addClass("l-text-invalid"); + } + $(element).removeAttr("title").ligerHideTip(); + $(element).attr("title", $(lable).html()).ligerTip({ + distanceX: 5, + distanceY: -3, + auto: true + }); + }, + success: function (lable) + { + var eleId = lable.attr("for"); + if (!eleId) return; + var element = $("#" + eleId); + if (element.hasClass("l-textarea")) + { + element.removeClass("l-textarea-invalid"); + } + else + { + element.parent().removeClass("l-text-invalid"); + } + $(element).removeAttr("title").ligerHideTip(); + } + }, validate, { + rules: g.validate.rules, + messages: g.validate.messages + }); + + g.validator = g.form.validate(validateOptions); + }, + setFieldValidate: function (name, validate, messages) + { + var jele = $("[name=" + name + "]"); + if (!jele.length || !jele.rules) return; + var oldRule = jele.rules("remove"); + if (oldRule) //旧的验证移除验证结果 + { + if (jele.hasClass("l-text-field")) + { + jele.parent().removeClass("l-text-invalid"); + } + jele.removeAttr("title").ligerHideTip(); + if (oldRule.required)//旧的验证包括必填规则,移除* + { + jele.parents("li:first").next("li:first").find(".l-star").remove(); + } + } + if (!validate)//没有定义新的验证规则 + { + return; + } + var rule = $.extend({}, validate, { messages: messages }); + jele.rules("add", rule); + if (validate.required) + { + //验证包括必填规则,添加* + jele.parents("li:first").next("li:first").append('<span class="l-star">*</span>'); + } + }, + //提示 验证错误信息 + showInvalid: function () + { + var g = this, p = this.options; + if (!g.validator) return; + var invalidMessage = p.invalidMessage.replace('{errorCount}', g.validator.errorList.length); + if (p.showInvalid) + { + p.showInvalid(invalidMessage); + } else + { + var jmessage = $('<div><div class="invalid">' + invalidMessage + '<a class="viewInvalidDetail" href="javascript:void(0)">' + p.detailMessage + '</a></div><div class="invalidDetail" style="display:none;">' + getInvalidInf(g.validator.errorList) + '</div></div>'); + jmessage.find("a.viewInvalidDetail:first").bind('click', function () + { + $(this).parent().next("div.invalidDetail").toggle(); + }); + $.ligerDialog.open({ + type: 'error', + width: 350, + showMax: false, + showToggle: false, + showMin: false, + target: jmessage, + buttons: [ + { + text: p.okMessage, onclick: function (item, dailog) + { + dailog.close(); + } + } + ] + }); + } + }, + _createEditor: function (editorBuilder, container, editParm, width, height) + { + var g = this, p = this.options; + try + { + var editor = editorBuilder.create.call(this, container, editParm, p); + if (editor && editorBuilder.resize) + editorBuilder.resize.call(this, editor, width, height, editParm); + return editor; + } catch (e) + { + return null; + } + }, + //标签部分 + _buliderLabelContainer: function (field) + { + var g = this, p = this.options; + var label = field.label || field.display; + var labelWidth = field.labelWidth || field.labelwidth || p.labelWidth; + var labelAlign = field.labelAlign || p.labelAlign; + if (label) + { + var rightToken = field.rightToken; + if (rightToken == null || rightToken == "") rightToken = p.rightToken; + label += rightToken; + } + var out = []; + out.push('<li'); + if (p.labelCss) + { + out.push(' class="' + p.labelCss + '"'); + } + out.push(' style="'); + if (/px$/i.test(labelWidth) || /auto/i.test(labelWidth) || /%$/i.test(labelWidth)) + { + out.push('width:' + labelWidth + ';'); + } + else if (labelWidth) + { + out.push('width:' + labelWidth + 'px;'); + } + if (labelAlign && labelAlign != "top") + { + out.push('text-align:' + labelAlign + ';'); + } + + out.push('">'); + if (label) + { + out.push(label); + } + out.push('</li>'); + return out.join(''); + }, + //控件部分 + _buliderControlContainer: function (field, fieldIndex, idPrev) + { + var g = this, p = this.options; + var width = field.width || p.inputWidth, + align = field.align || field.textAlign || field.textalign || p.align, + out = [], + idPrev = idPrev || g.id; + var labelAlign = field.labelAlign || p.labelAlign; + out.push('<li'); + out.push(' id="' + (idPrev + "|" + fieldIndex) + '"'); + if (p.fieldCss) + { + out.push(' class="' + p.fieldCss + '"'); + } + out.push(' style="'); + if (/px$/i.test(width) || /auto/i.test(width) || /%$/i.test(width)) + { + out.push('width:' + width + ';'); + } + else if (width) + { + out.push('width:' + width + 'px;'); + } + if (align) + { + out.push('text-align:' + align + ';'); + } + if (labelAlign == "top") + { + out.push('clear:both;'); + } + out.push('">'); + out.push('</li>'); + return out.join(''); + }, + //间隔部分 + _buliderSpaceContainer: function (field) + { + var g = this, p = this.options; + var spaceWidth = field.space || field.spaceWidth || p.space; + if (field.space === 0 || field.spaceWidth === 0) spaceWidth = 0; + var out = []; + out.push('<li'); + if (p.spaceCss) + { + out.push(' class="' + p.spaceCss + '"'); + } + out.push(' style="'); + if (/px$/i.test(spaceWidth) || /auto/i.test(spaceWidth) || /%$/i.test(spaceWidth)) + { + out.push('width:' + spaceWidth + ';'); + } + if (spaceWidth) + { + out.push('width:' + spaceWidth + 'px;'); + } + out.push('">'); + if (field.validate && field.validate.required) + { + out.push("<span class='l-star'>*</span>"); + } + out.push('</li>'); + return out.join(''); + }, + _getInputAttrHtml: function (field) + { + var out = [], type = (field.type || "text").toLowerCase(); + if (type == "textarea") + { + field.cols && out.push('cols="' + field.cols + '" '); + field.rows && out.push('rows="' + field.rows + '" '); + } + out.push('ltype="' + type + '" '); + field.op && out.push('op="' + field.op + '" '); + field.vt && out.push('vt="' + field.vt + '" '); + if (field.attr) + { + for (var attrp in field.attr) + { + out.push(attrp + '="' + field.attr[attrp] + '" '); + } + } + return out.join(''); + }, + _setTab: function (tab) + { + var g = this, p = this.options; + if (!tab || !tab.items) return; + var jtab = $('<div class="l-form-tabs"></div>').appendTo(g.element); + var jtabNav = $('<ul class="' + p.clsTab + '" original-title="">').appendTo(jtab); + for (var i = 0; i < tab.items.length; i++) + { + var tabItem = tab.items[i], + jnavItem = $('<li class="'+p.clsTabItem+'"><a href="javascript:void(0)"></a></li>').appendTo(jtabNav), + jcontentItem = $('<div class="'+p.clsTabContent+'">').appendTo(jtab), + idPrev = g.id + "|tdb" + i; + jnavItem.add(jcontentItem).attr("data-index", i); + if (tabItem.id) + { + jnavItem.attr("data-id", tabItem.id); + } + jnavItem.find("a:first").text(tabItem.title); + g._initFieldsValidate({ + fields: tabItem.fields + }); + g._initFieldsHtml({ + panel: jcontentItem, + fields: tabItem.fields, + tabindex : i, + idPrev: idPrev + }); + g._createEditors({ + fields: tabItem.fields, + idPrev: idPrev, + editPrev: 'tab' + i + "_" + }); + } + jtabNav.find("li").click(function () + { + $(this).addClass(p.clsTabItemSelected); + }, function () + { + $(this).removeClass(p.clsTabItemSelected); + }).click(function () + { + var index = $(this).attr("data-index"); + g.selectTab(index); + }); + g.selectTab(0); + }, + selectTab: function (index) + { + var g = this, p = this.options; + var jtab = $(g.element).find(".l-form-tabs:first"); + var links = jtab.find(".ui-tabs-nav li"), contents = jtab.find(".ui-tabs-panel"); + + links.filter("[data-index=" + index + "]") + .addClass(p.clsTabItemSelected); + links.filter("[data-index!=" + index + "]") + .removeClass(p.clsTabItemSelected); + contents.filter("[data-index=" + index + "]").show(); + contents.filter("[data-index!=" + index + "]").hide(); + }, + destroy: function () + { + try + { + var g = this, p = this.options; + liger.remove(this); + for (var index in g.editors) + { + var control = g.editors[index].control; + if (control && control.destroy) control.destroy(); + } + $(g.element).remove(); + } + catch (e) + { + + } + } + }); + + + function getInvalidInf(errorList) + { + var out = []; + $(errorList).each(function (i, error) + { + var label = $(error.element).parents("li:first").prev("li:first").html(); + var message = error.message; + out.push('<div>' + label + ' ' + message + '</div>'); + }); + return out.join(''); + } + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ + +(function ($) +{ + var l = $.ligerui; + + $.fn.ligerGrid = function (options) + { + return $.ligerui.run.call(this, "ligerGrid", arguments); + }; + + $.fn.ligerGetGridManager = function () + { + return $.ligerui.run.call(this, "ligerGetGridManager", arguments); + }; + + $.ligerDefaults.Grid = { + title: null, + width: 'auto', //宽度值 + height: 'auto', //宽度值 + columnWidth: null, //默认列宽度 + resizable: true, //table是否可伸缩 + url: false, //ajax url + urlParms: null, //url带参数 + data: null, //初始化数据 + usePager: true, //是否分页 + hideLoadButton : false, //是否隐藏刷新按钮 + pagerRender : null, //分页栏自定义渲染函数 + page: 1, //默认当前页 + pageSize: 10, //每页默认的结果数 + pageSizeOptions: [10, 20, 30, 40, 50], //可选择设定的每页结果数 + parms: [], //提交到服务器的参数 + columns: [], //数据源 + minColToggle: 1, //最小显示的列 + dataType: 'server', //数据源:本地(local)或(server),本地是将读取p.data。不需要配置,取决于设置了data或是url + dataAction: 'server', //提交数据的方式:本地(local)或(server),选择本地方式时将在客服端分页、排序。 + showTableToggleBtn: false, //是否显示'显示隐藏Grid'按钮 + switchPageSizeApplyComboBox: false, //切换每页记录数是否应用ligerComboBox + allowAdjustColWidth: true, //是否允许调整列宽 + checkbox: false, //是否显示复选框 + isSingleCheck: false, //复选框选择的时候是否单选模式 + allowHideColumn: true, //是否显示'切换列层'按钮 + enabledEdit: false, //是否允许编辑 + isScroll: true, //是否滚动 + dateFormat: 'yyyy-MM-dd', //默认时间显示格式 + inWindow: true, //是否以窗口的高度为准 height设置为百分比时可用 + statusName: '__status', //状态名 + method: 'post', //获取数据http方式 + async: true, + fixedCellHeight: true, //是否固定单元格的高度 + heightDiff: 0, //高度补差,当设置height:100%时,可能会有高度的误差,可以通过这个属性调整 + cssClass: null, //类名 + root: 'Rows', //数据源字段名 + record: 'Total', //数据源记录数字段名 + pageParmName: 'page', //页索引参数名,(提交给服务器) + pagesizeParmName: 'pagesize', //页记录数参数名,(提交给服务器) + sortnameParmName: 'sortname', //页排序列名(提交给服务器) + sortorderParmName: 'sortorder', //页排序方向(提交给服务器) + allowUnSelectRow: false, //是否允许反选行 + alternatingRow: true, //奇偶行效果 + mouseoverRowCssClass: 'l-grid-row-over', + enabledSort: true, //是否允许排序 + rowClsRender: null, //行自定义css class渲染器 + rowAttrRender: null, //行自定义属性渲染器(包括style,也可以定义) + groupColumnName: null, //分组 - 列名 + groupColumnDisplay: '分组', //分组 - 列显示名字 + groupRender: null, //分组 - 渲染器 + totalRender: null, //统计行(全部数据) + delayLoad: false, //初始化时是否不加载 + where: null, //数据过滤查询函数,(参数一 data item,参数二 data item index) + selectRowButtonOnly: false, //复选框模式时,是否只允许点击复选框才能选择行 + selectable: true, + whenRClickToSelect: false, //右击行时是否选中 + contentType: null, //Ajax contentType参数 + checkboxColWidth: 27, //复选框列宽度 + detailColWidth: 29, //明细列宽度 + clickToEdit: true, //是否点击单元格的时候就编辑 + detailToEdit: false, //是否点击明细的时候进入编辑 + onEndEdit: null, + minColumnWidth: 80, + tree: null, //treeGrid模式 + isChecked: null, //复选框 初始化函数 + isSelected: null, //选择 初始化函数 + frozen: true, //是否固定列 + frozenDetail: false, //明细按钮是否在固定列中 + frozenCheckbox: true, //复选框按钮是否在固定列中 + detail: null, + detailHeight: 260, + isShowDetailToggle: null, //是否显示展开/收缩明细的判断函数 + rownumbers: false, //是否显示行序号 + frozenRownumbers: true, //行序号是否在固定列中 + rownumbersColWidth: 26, + colDraggable: false, //是否允许表头拖拽 + rowDraggable: false, //是否允许行拖拽 + rowDraggingRender: null, + autoCheckChildren: true, //是否自动选中子节点 + onRowDragDrop: null, //行拖拽事件 + rowHeight: 28, //行默认的高度 + headerRowHeight: 28, //表头行的高度 + toolbar: null, //工具条,参数同 ligerToolbar的,额外参数有title、icon + toolbarShowInLeft: true, //工具条显示在左边 + headerImg: null, //表格头部图标 + editorTopDiff: 3, //编辑器top误差 + editorLeftDiff: 1, //编辑器left误差 + editorHeightDiff: -1, //编辑器高度误差 + unSetValidateAttr: true, //是否不设置validate属性到inuput + autoFilter: false, //自动生成高级查询, 需要filter/toolbar组件支持. 需要引用skins/ligerui-icons.css + rowSelectable: true, //是否允许选择 + scrollToPage: false, //滚动时分页 + scrollToAppend: true, //滚动时分页 是否追加分页的形式 + onDragCol: null, //拖动列事件 + onToggleCol: null, //切换列事件 + onChangeSort: null, //改变排序事件 + onSuccess: null, //成功获取服务器数据的事件 + onDblClickRow: null, //双击行事件 + onSelectRow: null, //选择行事件 + onBeforeSelectRow:null, //选择前事件 + onUnSelectRow: null, //取消选择行事件 + onBeforeCheckRow: null, //选择前事件,可以通过return false阻止操作(复选框) + onCheckRow: null, //选择事件(复选框) + onBeforeCheckAllRow: null, //选择前事件,可以通过return false阻止操作(复选框 全选/全不选) + onCheckAllRow: null, //选择事件(复选框 全选/全不选)onextend + onBeforeShowData: null, //显示数据前事件,可以通过reutrn false阻止操作 + onAfterShowData: null, //显示完数据事件 + onError: null, //错误事件 + onSubmit: null, //提交前事件 + onReload: null, //刷新事件,可以通过return false来阻止操作 + onToFirst: null, //第一页,可以通过return false来阻止操作 + onToPrev: null, //上一页,可以通过return false来阻止操作 + onToNext: null, //下一页,可以通过return false来阻止操作 + onToLast: null, //最后一页,可以通过return false来阻止操作 + onAfterAddRow: null, //增加行后事件 + onBeforeEdit: null, //编辑前事件 + onBeforeSubmitEdit: null, //验证编辑器结果是否通过 + onAfterEdit: null, //结束编辑后事件 + onLoading: null, //加载时函数 + onLoaded: null, //加载完函数 + onContextmenu: null, //右击事件 + onBeforeCancelEdit: null, //取消编辑前事件 + onAfterSubmitEdit: null, //提交后事件 + onRowDragDrop: null, //行拖拽后事件 + onGroupExtend: null, //分组展开事件 + onGroupCollapse: null, //分组收缩事件 + onTreeExpand: null, //树展开事件 + onTreeCollapse: null, //树收缩事件 + onTreeExpanded: null, //树展开事件 + onTreeCollapsed: null, //树收缩事件 + onLoadData: null, //加载数据前事件 + onHeaderCellBulid: null + }; + $.ligerDefaults.GridString = { + errorMessage: '发生错误', + pageStatMessage: '显示从{from}到{to},总 {total} 条 。每页显示:{pagesize}', + pageTextMessage: 'Page', + loadingMessage: '加载中...', + findTextMessage: '查找', + noRecordMessage: '没有符合条件的记录存在', + isContinueByDataChanged: '数据已经改变,如果继续将丢失数据,是否继续?', + cancelMessage: '取消', + saveMessage: '保存', + applyMessage: '应用', + draggingMessage: '{count}行' + }; + + $.ligerDefaults.Grid_columns = { + id: null, + name: null, + totalSummary: null, + display: null, + headerRender: null, + isAllowHide: true, + isSort: false, + type: null, + columns: null, + width: 120, + minWidth: 80, + format: null, + align: 'left', + hide: false, + editor: null, + render: null, + textField: null //真正显示的字段名,如果设置了,在编辑状态时,会调用创建编辑器的setText和getText方法 + }; + $.ligerDefaults.Grid_editor = { + type: null, + ext: null, + onChange: null, + onChanged: null + }; + //接口方法扩展 + $.ligerMethos.Grid = $.ligerMethos.Grid || {}; + + //排序器扩展 + $.ligerDefaults.Grid.sorters = $.ligerDefaults.Grid.sorters || {}; + + //格式化器扩展 + $.ligerDefaults.Grid.formatters = $.ligerDefaults.Grid.formatters || {}; + + //编辑器扩展 + $.ligerDefaults.Grid.editors = $.ligerDefaults.Grid.editors || {}; + + + $.ligerDefaults.Grid.sorters['date'] = function (val1, val2) + { + return val1 < val2 ? -1 : val1 > val2 ? 1 : 0; + }; + $.ligerDefaults.Grid.sorters['int'] = function (val1, val2) + { + return parseInt(val1) < parseInt(val2) ? -1 : parseInt(val1) > parseInt(val2) ? 1 : 0; + }; + $.ligerDefaults.Grid.sorters['float'] = function (val1, val2) + { + return parseFloat(val1) < parseFloat(val2) ? -1 : parseFloat(val1) > parseFloat(val2) ? 1 : 0; + }; + $.ligerDefaults.Grid.sorters['string'] = function (val1, val2) + { + if (!val1) return false; + return val1.localeCompare(val2); + }; + + + $.ligerDefaults.Grid.formatters['date'] = function (value, column) + { + function getFormatDate(date, dateformat) + { + var g = this, p = this.options; + if (isNaN(date)) return null; + var format = dateformat; + var o = { + "M+": date.getMonth() + 1, + "d+": date.getDate(), + "h+": date.getHours(), + "m+": date.getMinutes(), + "s+": date.getSeconds(), + "q+": Math.floor((date.getMonth() + 3) / 3), + "S": date.getMilliseconds() + } + if (/(y+)/.test(format)) + { + format = format.replace(RegExp.$1, (date.getFullYear() + "") + .substr(4 - RegExp.$1.length)); + } + for (var k in o) + { + if (new RegExp("(" + k + ")").test(format)) + { + format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] + : ("00" + o[k]).substr(("" + o[k]).length)); + } + } + return format; + } + if (!value) return ""; + // /Date(1328423451489)/ + if (typeof (value) == "string" && /^\/Date/.test(value)) + { + value = value.replace(/^\//, "new ").replace(/\/$/, ""); + eval("value = " + value); + } + if (value instanceof Date) + { + var format = column.format || this.options.dateFormat || "yyyy-MM-dd"; + return getFormatDate(value, format); + } + else + { + return value.toString(); + } + } + + //引用类型,数据形式表现为[id,text] + $.ligerDefaults.Grid.formatters['ref'] = function (value) + { + if ($.isArray(value)) return value.length > 1 ? value[1] : value[0]; + return value; + }; + + + $.ligerui.controls.Grid = function (element, options) + { + $.ligerui.controls.Grid.base.constructor.call(this, element, options); + }; + + $.ligerui.controls.Grid.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return '$.ligerui.controls.Grid'; + }, + __idPrev: function () + { + return 'grid'; + }, + _extendMethods: function () + { + return $.ligerMethos.Grid; + }, + _init: function () + { + $.ligerui.controls.Grid.base._init.call(this); + var g = this, p = this.options; + p.dataType = p.url ? "server" : "local"; + if (p.dataType == "local") + { + p.data = p.data || []; + p.dataAction = "local"; + } + if (p.isScroll == false) + { + p.height = 'auto'; + } + if (!p.frozen) + { + p.frozenCheckbox = false; + p.frozenDetail = false; + p.frozenRownumbers = false; + } + if (p.detailToEdit) + { + p.enabledEdit = true; + p.clickToEdit = false; + p.detail = { + height: 'auto', + onShowDetail: function (record, container, callback) + { + $(container).addClass("l-grid-detailpanel-edit"); + g.beginEdit(record, function (rowdata, column) + { + var editContainer = $("<div class='l-editbox'></div>"); + editContainer.width(120).height(p.rowHeight + 1); + editContainer.appendTo(container); + return editContainer; + }); + function removeRow() + { + $(container).parent().parent().remove(); + g.collapseDetail(record); + } + $("<div class='l-clear'></div>").appendTo(container); + $("<div class='l-button'>" + p.saveMessage + "</div>").appendTo(container).click(function () + { + g.endEdit(record); + removeRow(); + }); + $("<div class='l-button'>" + p.applyMessage + "</div>").appendTo(container).click(function () + { + g.submitEdit(record); + }); + $("<div class='l-button'>" + p.cancelMessage + "</div>").appendTo(container).click(function () + { + g.cancelEdit(record); + removeRow(); + }); + } + }; + } + if (p.tree)//启用分页模式 + { + p.tree.childrenName = p.tree.childrenName || "children"; + p.tree.isParent = p.tree.isParent || function (rowData) + { + var exist = p.tree.childrenName in rowData; + return exist; + }; + p.tree.isExtend = p.tree.isExtend || function (rowData) + { + if ('isextend' in rowData && rowData['isextend'] == false) + return false; + return true; + }; + } + //编辑构造器初始化 + for (var type in liger.editors) + { + var editor = liger.editors[type]; + //如果没有默认的或者已经定义 + if (!editor || type in p.editors) continue; + p.editors[type] = liger.getEditor($.extend({ + type: type, + master: g + }, editor)); + } + }, + _render: function () + { + var g = this, p = this.options; + g.grid = $(g.element); + g.grid.addClass("l-panel"); + var gridhtmlarr = []; + gridhtmlarr.push(" <div class='l-panel-header'><span class='l-panel-header-text'></span></div>"); + gridhtmlarr.push(" <div class='l-grid-loading'></div>"); + gridhtmlarr.push(" <div class='l-panel-topbar' style='display:none'><div class='l-panel-topbarinner'></div></div><div class='l-clear'></div>"); + gridhtmlarr.push(" <div class='l-panel-bwarp'>"); + gridhtmlarr.push(" <div class='l-panel-body'>"); + gridhtmlarr.push(" <div class='l-grid'>"); + gridhtmlarr.push(" <div class='l-grid-dragging-line'></div>"); + gridhtmlarr.push(" <div class='l-grid-popup'><table cellpadding='0' cellspacing='0'><tbody></tbody></table></div>"); + + gridhtmlarr.push(" <div class='l-grid1'>"); + gridhtmlarr.push(" <div class='l-grid-header l-grid-header1'>"); + gridhtmlarr.push(" <div class='l-grid-header-inner'><table class='l-grid-header-table' cellpadding='0' cellspacing='0'><tbody></tbody></table></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-grid-body l-grid-body1'>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" </div>"); + + gridhtmlarr.push(" <div class='l-grid2'>"); + gridhtmlarr.push(" <div class='l-grid-header l-grid-header2'>"); + gridhtmlarr.push(" <div class='l-grid-header-inner'><table class='l-grid-header-table' cellpadding='0' cellspacing='0'><tbody></tbody></table></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-grid-body l-grid-body2 l-scroll'>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" </div>"); + + + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-panel-bar'>"); + gridhtmlarr.push(" <div class='l-panel-bbar-inner'>"); + gridhtmlarr.push(" <div class='l-bar-group l-bar-message'><span class='l-bar-text'></span></div>"); + gridhtmlarr.push(" <div class='l-bar-group l-bar-selectpagesize'></div>"); + gridhtmlarr.push(" <div class='l-bar-separator'></div>"); + gridhtmlarr.push(" <div class='l-bar-group'>"); + gridhtmlarr.push(" <div class='l-bar-button l-bar-btnfirst'><span></span></div>"); + gridhtmlarr.push(" <div class='l-bar-button l-bar-btnprev'><span></span></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-bar-separator'></div>"); + gridhtmlarr.push(" <div class='l-bar-group'><span class='pcontrol'> <input type='text' size='4' value='1' style='width:20px' maxlength='3' /> / <span></span></span></div>"); + gridhtmlarr.push(" <div class='l-bar-separator'></div>"); + gridhtmlarr.push(" <div class='l-bar-group'>"); + gridhtmlarr.push(" <div class='l-bar-button l-bar-btnnext'><span></span></div>"); + gridhtmlarr.push(" <div class='l-bar-button l-bar-btnlast'><span></span></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-bar-separator'></div>"); + gridhtmlarr.push(" <div class='l-bar-group'>"); + gridhtmlarr.push(" <div class='l-bar-button l-bar-btnload'><span></span></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" <div class='l-bar-separator'></div>"); + + gridhtmlarr.push(" <div class='l-clear'></div>"); + gridhtmlarr.push(" </div>"); + gridhtmlarr.push(" </div>"); + g.grid.html(gridhtmlarr.join('')); + //头部 + g.header = $(".l-panel-header:first", g.grid); + //主体 + g.body = $(".l-panel-body:first", g.grid); + //底部工具条 + g.toolbar = $(".l-panel-bar:first", g.grid); + //显示/隐藏列 + g.popup = $(".l-grid-popup:first", g.grid); + //加载中 + g.gridloading = $(".l-grid-loading:first", g.grid); + //调整列宽层 + g.draggingline = $(".l-grid-dragging-line", g.grid); + //顶部工具栏 + g.topbar = $(".l-panel-topbarinner:first", g.grid); + + g.gridview = $(".l-grid:first", g.grid); + g.gridview.attr("id", g.id + "grid"); + g.gridview1 = $(".l-grid1:first", g.gridview); + g.gridview2 = $(".l-grid2:first", g.gridview); + //表头 + g.gridheader = $(".l-grid-header:first", g.gridview2); + //表主体 + g.gridbody = $(".l-grid-body:first", g.gridview2); + //处理autoFilter + if (p.autoFilter) + { + var item = { + text: '高级查询', + gridid: g.id, + click: function () + { + g.showFilter(); + }, + icon: 'search2' + }; + if (p.toolbar && p.toolbar.items) + { + p.toolbar.items.push(item); + } + else + { + p.toolbar = { + items: [item] + }; + } + } + //frozen + g.f = {}; + //表头 + g.f.gridheader = $(".l-grid-header:first", g.gridview1); + //表主体 + g.f.gridbody = $(".l-grid-body:first", g.gridview1); + + g.currentData = null; + g.changedCells = {}; + g.editors = {}; //多编辑器同时存在 + g.editor = { editing: false }; //单编辑器,配置clickToEdit + + g.cacheData = {}; //缓存数据 + + if (p.height == "auto") + { + g.bind("SysGridHeightChanged", function () + { + if (g.enabledFrozen()) + g.gridview.height(Math.max(g.gridview1.height(), g.gridview2.height())); + }); + } + + var pc = $.extend({}, p); + + this._bulid(); + this._setColumns(p.columns); + + delete pc['columns']; + delete pc['data']; + delete pc['url']; + g.set(pc); + if (!p.delayLoad) + { + if (p.url) + g.set({ url: p.url }); + else if (p.data) + g.set({ data: p.data }); + } + }, + _setFrozen: function (frozen) + { + if (frozen) + this.grid.addClass("l-frozen"); + else + this.grid.removeClass("l-frozen"); + }, + _setCssClass: function (value) + { + this.grid.addClass(value); + }, + _setLoadingMessage: function (value) + { + this.gridloading.html(value); + }, + _setToolbar: function (value) + { + var g = this, p = this.options; + if (value && $.fn.ligerToolBar) + { + g.topbar.parent().show(); + g.toolbarManager = g.topbar.ligerToolBar(value); + if (value.title) + { + var jtitle = $("<div class='l-panel-topbartitle'><span>" + value.title + "</span></div>"); + if (value.icon) + { + jtitle.append("<img class='l-panel-topbaricon' src='" + value.icon + "'></img>"); + jtitle.addClass("l-panel-topbartitle-hasicon"); + } + g.topbar.parent().append(jtitle); + } + if (p.toolbarShowInLeft) + { + g.topbar.addClass("l-panel-topbarinner-left"); + } + } else + { + g.topbar.parent().remove(); + } + }, + isHorizontalScrollShowed: function () + { + var g = this; + var inner = g.gridbody.find(".l-grid-body-inner:first"); + if (!inner.length) return false; + //20为横向滚动条的宽度 + return g.gridbody.width() - 20 < inner.width(); + }, + _setHeight: function (h) + { + var g = this, p = this.options; + g.unbind("SysGridHeightChanged"); + if (h == "auto") + { + g.bind("SysGridHeightChanged", function () + { + if (g.enabledFrozen()) + g.gridview.height(Math.max(g.gridview1.height(), g.gridview2.height())); + }); + return; + } + h = g._calculateGridBodyHeight(h); + if (h > 0) + { + g.gridbody.height(h); + + if (p.frozen) + { + //解决冻结列和活动列由上至下滚动错位的问题 + var w = g.gridbody.width(), w2 = $(":first-child", g.gridbody).width(); + if (w2 && (w2 + 18 > w)) + { + if (h > 18) + g.f.gridbody.height(h - 18); + } else + { + g.f.gridbody.height(h); + } + } + + var gridHeaderHeight = p.headerRowHeight * (g._columnMaxLevel - 1) + p.headerRowHeight - 1; + g.gridview.height(h + gridHeaderHeight); + } + g._updateHorizontalScrollStatus.ligerDefer(g, 10); + }, + _calculateGridBodyHeight: function (h) + { + var g = this, p = this.options; + if (typeof h == "string" && h.indexOf('%') > 0) + { + if (p.inWindow) + h = $(window).height() * parseInt(h) * 0.01; + else + h = g.grid.parent().height() * parseInt(h) * 0.01; + } + if (p.title) h -= 24; + if (p.usePager && p.pagerRender || !p.scrollToPage) h -= g.toolbar.outerHeight(); + if (p.totalRender) h -= 25; + if (p.toolbar) h -= g.topbar.outerHeight(); + var gridHeaderHeight = p.headerRowHeight * (g._columnMaxLevel - 1) + p.headerRowHeight - 1; + h -= (gridHeaderHeight || 0); + return h; + }, + _updateHorizontalScrollStatus: function () + { + var g = this, p = this.options; + if (g.isHorizontalScrollShowed()) + { + g.gridview.addClass("l-grid-hashorizontal"); + } + else + { + g.gridview.removeClass("l-grid-hashorizontal"); + } + }, + _updateFrozenWidth: function () + { + var g = this, p = this.options; + if (g.enabledFrozen()) + { + g.gridview1.width(g.f.gridtablewidth); + var view2width = g.gridview.width() - g.f.gridtablewidth; + g.gridview2.css({ left: g.f.gridtablewidth }); + if (view2width > 0) g.gridview2.css({ width: view2width }); + } + }, + _setWidth: function (value) + { + var g = this, p = this.options; + if (g.enabledFrozen()) g._onResize(); + }, + _setUrl: function (value) + { + this.options.url = value; + if (value) + { + this.options.dataType = "server"; + this.loadData(true); + } + else + { + this.options.dataType = "local"; + } + }, + removeParm: function (name) + { + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + if (parms instanceof Array) + { + removeArrItem(parms, function (p) { return p.name == name; }); + } else + { + delete parms[name]; + } + g.set('parms', parms); + }, + setParm: function (name, value) + { + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + if (parms instanceof Array) + { + removeArrItem(parms, function (p) { return p.name == name; }); + parms.push({ name: name, value: value }); + } else + { + parms[name] = value; + } + g.set('parms', parms); + }, + _setData: function (value) + { + this.loadData(this.options.data); + this.trigger('afterSetData'); + }, + //刷新数据 + loadData: function (loadDataParm,sourceType) + { + var g = this, p = this.options; + g.loading = true; + g.trigger('loadData'); + var clause = null; + var loadServer = true; + if (typeof (loadDataParm) == "function") + { + clause = loadDataParm; + if (g.lastData) + { + g.data = g.lastData; + } else + { + g.data = g.currentData; + if (!g.data) g.data = {}; + if (!g.data[p.root]) g.data[p.root] = []; + g.lastData = g.data; + } + loadServer = false; + } + else if (typeof (loadDataParm) == "boolean") + { + loadServer = loadDataParm; + } + else if (typeof (loadDataParm) == "object" && loadDataParm) + { + loadServer = false; + p.dataType = "local"; + p.data = loadDataParm; + } + else if (typeof (loadDataParm) == "number") + { + p.newPage = loadDataParm; + } + //参数初始化 + if (!p.newPage) p.newPage = 1; + if (p.dataAction == "server") + { + if (!p.sortOrder) p.sortOrder = "asc"; + } + var param = []; + if (p.parms) + { + var parms = $.isFunction(p.parms) ? p.parms() : p.parms; + if (parms.length) + { + $(parms).each(function () + { + param.push({ name: this.name, value: this.value }); + }); + for (var i = parms.length - 1; i >= 0; i--) + { + if (parms[i].temp) + parms.splice(i, 1); + } + } + else if (typeof parms == "object") + { + for (var name in parms) + { + param.push({ name: name, value: parms[name] }); + } + } + } + if (p.dataAction == "server") + { + if (p.usePager) + { + param.push({ name: p.pageParmName, value: p.newPage }); + param.push({ name: p.pagesizeParmName, value: p.pageSize }); + } + if (p.sortName) + { + param.push({ name: p.sortnameParmName, value: p.sortName }); + param.push({ name: p.sortorderParmName, value: p.sortOrder }); + } + }; + $(".l-bar-btnload span", g.toolbar).addClass("l-disabled"); + if (p.dataType == "local") + { + //原语句: g.filteredData = p.data || g.currentData; + //该语句修改了p.data, 导致过滤数据后, 丢失了初始数据. + g.filteredData = $.extend(true, {}, p.data || g.currentData); + if (clause) + g.filteredData[p.root] = g._searchData(g.filteredData[p.root], clause); + if (p.usePager) + g.currentData = g._getCurrentPageData(g.filteredData); + else + { + g.currentData = g.filteredData; + } + g._convertTreeData(); + g._showData(); + } + else if (p.dataAction == "local" && !loadServer) + { + if (g.data && g.data[p.root]) + { + g.filteredData = g.data; + if (clause) + g.filteredData[p.root] = g._searchData(g.filteredData[p.root], clause); + g.currentData = g._getCurrentPageData(g.filteredData); + g._convertTreeData(); + g._showData(); + } + } + else + { + g.loadServerData(param, clause, sourceType); + //g.loadServerData.ligerDefer(g, 10, [param, clause]); + } + g.loading = false; + }, + _convertTreeData: function () + { + var g = this, p = this.options; + if (p.tree && p.tree.idField && p.tree.parentIDField) + { + g.currentData[p.root] = g.arrayToTree(g.currentData[p.root], p.tree.idField, p.tree.parentIDField); + g.currentData[p.record] = g.currentData[p.root].length; + } + }, + loadServerData: function (param, clause, sourceType) + { + var g = this, p = this.options; + var url = p.url; + if ($.isFunction(url)) url = url.call(g); + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var ajaxOptions = { + type: p.method, + url: url, + data: param, + async: p.async, + dataType: 'json', + beforeSend: function () + { + if (g.hasBind('loading')) + { + g.trigger('loading'); + } + else + { + g.toggleLoading(true); + } + }, + success: function (data) + { + g.trigger('success', [data, g]); + if (!data || !data[p.root] || !data[p.root].length) + { + g.currentData = g.data = {}; + g.currentData[p.root] = g.data[p.root] = []; + if (data && data[p.record]) + { + g.currentData[p.record] = g.data[p.record] = data[p.record]; + } else + { + g.currentData[p.record] = g.data[p.record] = 0; + } + g._convertTreeData(); + g._showData(sourceType); + return; + } + g.data = data; + //保存缓存数据-记录总数 + if (g.data[p.record] != null) + { + g.cacheData.records = g.data[p.record]; + } + if (p.dataAction == "server") //服务器处理好分页排序数据 + { + g.currentData = g.data; + //读取缓存数据-记录总数(当没有返回总记录数) + if (g.currentData[p.record] == null && g.cacheData.records) + { + g.currentData[p.record] = g.cacheData.records; + } + } + else //在客户端处理分页排序数据 + { + g.filteredData = g.data; + if (clause) g.filteredData[p.root] = g._searchData(g.filteredData[p.root], clause); + if (p.usePager) + g.currentData = g._getCurrentPageData(g.filteredData); + else + g.currentData = g.filteredData; + } + g._convertTreeData(); + g._showData.ligerDefer(g, 10, [sourceType]); + }, + complete: function () + { + g.trigger('complete', [g]); + if (g.hasBind('loaded')) + { + g.trigger('loaded', [g]); + } + else + { + g.toggleLoading.ligerDefer(g, 10, [false]); + } + }, + error: function (XMLHttpRequest, textStatus, errorThrown) + { + g.currentData = g.data = {}; + g.currentData[p.root] = g.data[p.root] = []; + g.currentData[p.record] = g.data[p.record] = 0; + g.toggleLoading.ligerDefer(g, 10, [false]); + $(".l-bar-btnload span", g.toolbar).removeClass("l-disabled"); + g.trigger('error', [XMLHttpRequest, textStatus, errorThrown]); + } + }; + if (p.contentType) ajaxOptions.contentType = p.contentType; + if (p.contentType == "application/json" && typeof (parms) != "string") + { + ajaxOptions.data = converParmJson(param) + } + $.ajax(ajaxOptions); + + function converParmJson(parm) + { + if (!parm) return "null"; + var o = parm, result = {}; + if ($.isArray(o)) + { + for (var i = 0; i < o.length; i++) + { + result[o[i].name] = o[i].value; + } + } else + { + result = o; + } + return liger.toJSON(result); + } + }, + toggleLoading: function (show) + { + this.gridloading[show ? 'show' : 'hide'](); + }, + _createEditor: function (editorBuilder, container, editParm, width, height) + { + var editor = editorBuilder.create.call(this, container, editParm); + if (editorBuilder.setValue) + editorBuilder.setValue.call(this, editor, editParm.value, editParm); + if (editParm.column.editor && editParm.column.editor.initSelect) + { + if (editor.element && $(editor.element).is(":text")) + { + $(editor.element).select(); + } + if (editor instanceof jQuery) + { + if (editor.is(":text")) editor.select(); + else editor.find(":text").select(); + } + } + if (editorBuilder.setText && editParm.column.textField) + editorBuilder.setText.call(this, editor, editParm.text, editParm); + if (editorBuilder.resize) + editorBuilder.resize.call(this, editor, width, height, editParm); + return editor; + }, + /* + @description 使一行进入编辑状态 + @param {rowParm} rowindex或者rowdata + @param {containerBulider} 编辑器填充层构造器 + */ + beginEdit: function (rowParm, containerBulider) + { + var g = this, p = this.options; + if (!p.enabledEdit) return; + var rowdata = g.getRow(rowParm); + if (rowdata._editing) return; + if (g.trigger('beginEdit', { record: rowdata, rowindex: rowdata['__index'] }) == false) return; + g.editors[rowdata['__id']] = {}; + rowdata._editing = true; + g.reRender({ rowdata: rowdata }); + containerBulider = containerBulider || function (rowdata, column) + { + var cellobj = g.getCellObj(rowdata, column); + var container = $(cellobj).html(""); + g.setCellEditing(rowdata, column, true); + return container; + }; + for (var i = 0, l = g.columns.length; i < l; i++) + { + var column = g.columns[i]; + if (!column.name || !column.editor || !column.editor.type || !p.editors[column.editor.type]) continue; + var editor = p.editors[column.editor.type]; + var editParm = { + record: rowdata, + value: g._getValueByName(rowdata, column.name), + column: column, + rowindex: rowdata['__index'], + grid: g + }; + var container = containerBulider(rowdata, column); + var width = container.width(), height = container.height(); + var editorControl = g._createEditor(editor, container, editParm, width, height); + g.editors[rowdata['__id']][column['__id']] = { + editor: editor, + input: editorControl, + editParm: editParm, + container: container + }; + } + g.trigger('afterBeginEdit', { record: rowdata, rowindex: rowdata['__index'] }); + + }, + cancelEdit: function (rowParm) + { + var g = this; + if (rowParm == undefined) + { + for (var rowid in g.editors) + { + g.cancelEdit(rowid); + } + } + else + { + var rowdata = g.getRow(rowParm); + if (!g.editors[rowdata['__id']]) return; + if (g.trigger('beforeCancelEdit', { record: rowdata, rowindex: rowdata['__index'] }) == false) return; + for (var columnid in g.editors[rowdata['__id']]) + { + var o = g.editors[rowdata['__id']][columnid]; + if (o.editor.destroy) o.editor.destroy(o.input, o.editParm); + } + delete g.editors[rowdata['__id']]; + delete rowdata['_editing']; + g.reRender({ rowdata: rowdata }); + } + }, + addEditRow: function (rowdata, containerBulider) + { + this.submitEdit(); + rowdata = this.add(rowdata); + this.beginEdit(rowdata, containerBulider); + }, + submitEdit: function (rowParm) + { + var g = this, p = this.options; + if (rowParm == undefined) + { + for (var rowid in g.editors) + { + g.submitEdit(rowid); + } + } + else + { + var rowdata = g.getRow(rowParm); + var newdata = {}; + if (!rowdata || !g.editors[rowdata['__id']]) return; + for (var columnid in g.editors[rowdata['__id']]) + { + var o = g.editors[rowdata['__id']][columnid]; + var column = o.editParm.column; + if (column.name) + { + newdata[column.name] = o.editor.getValue(o.input, o.editParm); + } + if (column.textField && o.editor.getText) + { + newdata[column.textField] = o.editor.getText(o.input, o.editParm); + } + } + if (g.trigger('beforeSubmitEdit', { record: rowdata, rowindex: rowdata['__index'], newdata: newdata }) == false) + return false; + g.updateRow(rowdata, newdata); + g.trigger('afterSubmitEdit', { record: rowdata, rowindex: rowdata['__index'], newdata: newdata }); + } + }, + _enabledEditByCell : function(cell) + { + var g = this, p = this.options; + var column = g.getColumn(cell); + if (!column) return false; + return column.editor && column.editor.type; + }, + //结束当前的编辑 并进入下一个单元格的编辑状态(如果位于最后单元格,进入下一行第一个单元格) + endEditToNext : function() + { + var g = this, p = this.options; + var editor = g.editor, jnext = null, jprev = null; + if (editor) + { + var editParm = editor.editParm; + var column = editParm.column; + var columnIndex = $.inArray(column, g.columns); + var cell = g.getCellObj(editParm.record, editParm.column); + jprev = $(cell); + jnext = jprev.next(); + if (!jnext.length) jnext = getNextRowCell();//已经是当前行最后一个单元格了 + if (jnext.length) + { + //获取到下一个可编辑的列 + while (!g._enabledEditByCell(jnext.get(0))) + { + jprev = jnext; + jnext = jnext.next(); + if (!jnext.length)//已经是当前行最后一个单元格了 + { + jnext = getNextRowCell(); + } + } + } + //获取下一行第一个列对象 + function getNextRowCell() + { + return jprev.parent("tr").next(".l-grid-row").find("td:first"); + } + } + + g.endEdit(); + if (jnext && jnext.length) + { + g._applyEditor(jnext.get(0)); + } + }, + endEdit: function (rowParm) + { + var g = this, p = this.options; + if (g.editor.editing) + { + var o = g.editor; + g.trigger('sysEndEdit', [g.editor.editParm]); + g.trigger('endEdit', [g.editor.editParm]); + if (o.editor.destroy) o.editor.destroy(o.input, o.editParm); + g.editor.container.remove(); + g.reRender({ rowdata: g.editor.editParm.record, column: g.editor.editParm.column }); + g.trigger('afterEdit', [g.editor.editParm]); + g.editor = { editing: false }; + } + else if (rowParm != undefined) + { + var rowdata = g.getRow(rowParm); + if (!g.editors[rowdata['__id']]) return; + if (g.submitEdit(rowParm) == false) return false; + for (var columnid in g.editors[rowdata['__id']]) + { + var o = g.editors[rowdata['__id']][columnid]; + if (o.editor.destroy) o.editor.destroy(o.input, o.editParm); + } + delete g.editors[rowdata['__id']]; + delete rowdata['_editing']; + g.trigger('afterEdit', { record: rowdata, rowindex: rowdata['__index'] }); + } + else + { + for (var rowid in g.editors) + { + g.endEdit(rowid); + } + } + g._fixHeight.ligerDefer(g, 10); + }, + setWidth: function (w) + { + return this._setWidth(w); + }, + setHeight: function (h) + { + return this._setHeight(h); + }, + //是否启用复选框列 + enabledCheckbox: function () + { + return this.options.checkbox ? true : false; + }, + //是否固定列 + enabledFrozen: function () + { + var g = this, p = this.options; + if (!p.frozen) return false; + var cols = g.columns || []; + if (g.enabledDetail() && p.frozenDetail || g.enabledCheckbox() && p.frozenCheckbox + || p.frozenRownumbers && p.rownumbers) return true; + for (var i = 0, l = cols.length; i < l; i++) + { + if (cols[i].frozen) + { + return true; + } + } + this._setFrozen(false); + return false; + }, + //是否启用明细编辑 + enabledDetailEdit: function () + { + if (!this.enabledDetail()) return false; + return this.options.detailToEdit ? true : false; + }, + //是否启用明细列 + enabledDetail: function () + { + if (this.options.detail && this.options.detail.onShowDetail) return true; + return false; + }, + //是否启用分组 + enabledGroup: function () + { + return this.options.groupColumnName ? true : false; + }, + deleteSelectedRow: function () + { + if (!this.selected) return; + for (var i in this.selected) + { + var o = this.selected[i]; + if (o['__id'] in this.records) + this._deleteData.ligerDefer(this, 10, [o]); + } + this.reRender.ligerDefer(this, 20); + }, + removeRange: function (rowArr) + { + var g = this, p = this.options; + $.each(rowArr, function () + { + g._removeData(this); + }); + g.reRender(); + }, + remove: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + g._removeData(rowParm); + g.reRender(); + }, + deleteRange: function (rowArr) + { + var g = this, p = this.options; + $.each(rowArr, function () + { + g._deleteData(this); + }); + g.reRender(); + }, + deleteRow: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata) return; + g._deleteData(rowdata); + g.reRender(); + g.isDataChanged = true; + }, + _deleteData: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + rowdata[p.statusName] = 'delete'; + if (p.tree) + { + var children = g.getChildren(rowdata, true); + if (children) + { + for (var i = 0, l = children.length; i < l; i++) + { + children[i][p.statusName] = 'delete'; + } + } + } + g.deletedRows = g.deletedRows || []; + g.deletedRows.push(rowdata); + g._removeSelected(rowdata); + }, + /* + @param {arg} column index、column name、column、单元格 + @param {value} 值 + @param {rowParm} rowindex或者rowdata + */ + updateCell: function (arg, value, rowParm) + { + var g = this, p = this.options; + var column, cellObj, rowdata; + if (typeof (arg) == "string") //column name + { + for (var i = 0, l = g.columns.length; i < l; i++) + { + if (g.columns[i].name == arg) + { + g.updateCell(i, value, rowParm); + } + } + return; + } + if (typeof (arg) == "number") + { + column = g.columns[arg]; + rowdata = g.getRow(rowParm); + cellObj = g.getCellObj(rowdata, column); + } + else if (typeof (arg) == "object" && arg['__id']) + { + column = arg; + rowdata = g.getRow(rowParm); + cellObj = g.getCellObj(rowdata, column); + } + else + { + cellObj = arg; + var ids = cellObj.id.split('|'); + var columnid = ids[ids.length - 1]; + column = g._columns[columnid]; + var row = $(cellObj).parent(); + rowdata = rowdata || g.getRow(row[0]); + } + if (value != null && column.name) + { + g._setValueByName(rowdata, column.name, value); + if (rowdata[p.statusName] != 'add') + rowdata[p.statusName] = 'update'; + g.isDataChanged = true; + } + g.reRender({ rowdata: rowdata, column: column }); + }, + addRows: function (rowdataArr, neardata, isBefore, parentRowData) + { + var g = this, p = this.options; + $(rowdataArr).each(function () + { + g.addRow(this, neardata, isBefore, parentRowData); + }); + }, + _createRowid: function () + { + return "r" + (1000 + this.recordNumber); + }, + _isRowId: function (str) + { + return (str in this.records); + }, + _addNewRecord: function (o, previd, pid) + { + var g = this, p = this.options; + g.recordNumber++; + o['__id'] = g._createRowid(); + o['__previd'] = previd; + if (previd && previd != -1) + { + var prev = g.records[previd]; + if (prev['__nextid'] && prev['__nextid'] != -1) + { + var prevOldNext = g.records[prev['__nextid']]; + if (prevOldNext) + prevOldNext['__previd'] = o['__id']; + } + prev['__nextid'] = o['__id']; + o['__index'] = prev['__index'] + 1; + } + else + { + o['__index'] = 0; + } + if (p.tree) + { + if (pid && pid != -1) + { + var parent = g.records[pid]; + o['__pid'] = pid; + o['__level'] = parent['__level'] + 1; + } + else + { + o['__pid'] = -1; + o['__level'] = 1; + } + o['__hasChildren'] = o[p.tree.childrenName] ? true : false; + } + o[p.statusName] = o[p.statusName] || "nochanged"; + g.rows[o['__index']] = o; + g.records[o['__id']] = o; + return o; + }, + //将原始的数据转换成适合 grid的行数据 + _getRows: function (data) + { + var g = this, p = this.options; + var targetData = []; + function load(data) + { + if (!data || !data.length) return; + for (var i = 0, l = data.length; i < l; i++) + { + var o = data[i]; + targetData.push(o); + if (o[p.tree.childrenName]) + { + load(o[p.tree.childrenName]); + } + } + } + load(data); + return targetData; + }, + _updateGridData: function () + { + var g = this, p = this.options; + g.recordNumber = 0; + g.rows = []; + g.records = {}; + var previd = -1; + function load(data, pid) + { + if (!data || !data.length) return; + for (var i = 0, l = data.length; i < l; i++) + { + var o = data[i]; + g.formatRecord(o); + if (o[p.statusName] == "delete") continue; + g._addNewRecord(o, previd, pid); + previd = o['__id']; + if (o['__hasChildren']) + { + load(o[p.tree.childrenName], o['__id']); + } + } + } + load(g.currentData[p.root], -1); + return g.rows; + }, + _moveData: function (from, to, isAfter) + { + var g = this, p = this.options; + var fromRow = g.getRow(from); + var toRow = g.getRow(to); + var fromIndex, toIndex; + var listdata = g._getParentChildren(fromRow); + fromIndex = $.inArray(fromRow, listdata); + listdata.splice(fromIndex, 1); + listdata = g._getParentChildren(toRow); + toIndex = $.inArray(toRow, listdata); + listdata.splice(toIndex + (isAfter ? 1 : 0), 0, fromRow); + }, + move: function (from, to, isAfter) + { + this._moveData(from, to, isAfter); + this.reRender(); + }, + moveRange: function (rows, to, isAfter) + { + for (var i in rows) + { + this._moveData(rows[i], to, isAfter); + } + this.reRender(); + }, + up: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var listdata = g._getParentChildren(rowdata); + var index = $.inArray(rowdata, listdata); + if (index == -1 || index == 0) return; + var selected = g.getSelected(); + g.move(rowdata, listdata[index - 1], false); + g.select(selected); + }, + down: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var listdata = g._getParentChildren(rowdata); + var index = $.inArray(rowdata, listdata); + if (index == -1 || index == listdata.length - 1) return; + var selected = g.getSelected(); + g.move(rowdata, listdata[index + 1], true); + g.select(selected); + }, + addRow: function (rowdata, neardata, isBefore, parentRowData) + { + var g = this, p = this.options; + rowdata = rowdata || {}; + g._addData(rowdata, parentRowData, neardata, isBefore); + g.reRender(); + //标识状态 + rowdata[p.statusName] = 'add'; + if (p.tree) + { + var children = g.getChildren(rowdata, true); + if (children) + { + for (var i = 0, l = children.length; i < l; i++) + { + children[i][p.statusName] = 'add'; + } + } + } + g.isDataChanged = true; + p.total = p.total ? (p.total + 1) : 1; + p.pageCount = Math.ceil(p.total / p.pageSize); + g._buildPager(); + g.trigger('SysGridHeightChanged'); + g.trigger('afterAddRow', [rowdata]); + return rowdata; + }, + updateRow: function (rowDom, newRowData) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowDom); + //标识状态 + g.isDataChanged = true; + $.extend(rowdata, newRowData || {}); + if (rowdata[p.statusName] != 'add') + rowdata[p.statusName] = 'update'; + g.reRender.ligerDefer(g, 10, [{ rowdata: rowdata }]); + return rowdata; + }, + setCellEditing: function (rowdata, column, editing) + { + var g = this, p = this.options; + var cell = g.getCellObj(rowdata, column); + var methodName = editing ? 'addClass' : 'removeClass'; + $(cell)[methodName]("l-grid-row-cell-editing"); + if (rowdata['__id'] != 0) + { + var prevrowobj = $(g.getRowObj(rowdata['__id'])).prev(); + //当使用可编辑的grid带分组时,第一行的prev对象是分组行,不具备id等getRow方法中需要的信息 + if (!prevrowobj.length + || prevrowobj.length <= 0 + || prevrowobj[0].id == null + || prevrowobj[0].id == "") + { + return; + } + var prevrow = g.getRow(prevrowobj[0]); + var cellprev = g.getCellObj(prevrow, column); + if (!cellprev) return; + $(cellprev)[methodName]("l-grid-row-cell-editing-topcell"); + } + if (column['__previd'] != -1 && column['__previd'] != null) + { + var cellprev = $(g.getCellObj(rowdata, column)).prev(); + $(cellprev)[methodName]("l-grid-row-cell-editing-leftcell"); + } + }, + reRender: function (e) + { + var g = this, p = this.options; + e = e || {}; + var rowdata = e.rowdata, + column = e.column, + //只重渲染统计行 + totalOnly = e.totalOnly; + if (column && (column.isdetail || column.ischeckbox)) return; + if (rowdata && rowdata[p.statusName] == "delete") return; + if (totalOnly) + { + $(g.columns).each(function () + { + reRenderTotal(this); + }); + } + else if (rowdata && column) + { + var cell = g.getCellObj(rowdata, column); + $(cell).html(g._getCellHtml(rowdata, column)); + if (!column.issystem) + g.setCellEditing(rowdata, column, false); + } + else if (rowdata) + { + $(g.columns).each(function () + { + g.reRender({ rowdata: rowdata, column: this }); + }); + } + else if (column) + { + for (var rowid in g.records) + { + g.reRender({ rowdata: g.records[rowid], column: column }); + } + reRenderTotal(column); + } + else + { + g._showData(); + } + + function reRenderTotal(column) + { + if (!column.totalSummary) return; + for (var i = 0; i < g.totalNumber; i++) + { + var tobj = document.getElementById(g.id + "|total" + i + "|" + column['__id']); + $("div:first", tobj).html(g._getTotalCellContent(column, g.groups && g.groups[i] ? g.groups[i] : g.currentData[p.root])); + } + } + }, + getData: function (status, removeStatus) + { + var g = this, p = this.options; + var data = []; + if (removeStatus == undefined) removeStatus = true; + for (var rowid in g.records) + { + var o = $.extend(true, {}, g.records[rowid]); + if (o[p.statusName] == status || status == undefined) + { + data.push(g.formatRecord(o, removeStatus)); + } + } + return data; + }, + //格式化数据 + formatRecord: function (o, removeStatus) + { + delete o['__id']; + delete o['__previd']; + delete o['__nextid']; + delete o['__index']; + if (this.options.tree) + { + delete o['__pid']; + delete o['__level']; + delete o['__hasChildren']; + } + if (removeStatus) delete o[this.options.statusName]; + return o; + }, + getUpdated: function () + { + return this.getData('update', true); + }, + getDeleted: function () + { + return this.deletedRows; + }, + getAdded: function () + { + return this.getData('add', true); + }, + getChanges: function () + { + //getChanges函数必须保留__status属性,否则根本不知道哪些是新增的,哪些是被删除的. + //则本函数返回的结果毫无意义. + var g = this, p = this.options; + var data = []; + if (this.deletedRows) + { + $(this.deletedRows).each(function () + { + var o = $.extend(true, {}, this); + data.push(g.formatRecord(o, false)); + }); + } + $.merge(data, g.getData("update", false)); + $.merge(data, g.getData("add", false)); + return data; + }, + getColumn: function (columnParm) + { + var g = this, p = this.options; + if (typeof columnParm == "string") // column id + { + if (g._isColumnId(columnParm)) + return g._columns[columnParm]; + else + return g.columns[parseInt(columnParm)]; + } + else if (typeof (columnParm) == "number") //column index + { + return g.columns[columnParm]; + } + else if (typeof columnParm == "object" && columnParm.nodeType == 1) //column header cell + { + var ids = columnParm.id.split('|'); + var columnid = ids[ids.length - 1]; + return g._columns[columnid]; + } + return columnParm; + }, + getColumnByName: function (columnname) + { + var g = this, p = this.options; + for (i = 0; i < g.columns.length; i++) + { + if (g.columns[i].name == columnname) + { + return g.columns[i]; + } + } + return null; + }, + getColumnType: function (columnname) + { + var g = this, p = this.options; + for (i = 0; i < g.columns.length; i++) + { + if (g.columns[i].name == columnname) + { + if (g.columns[i].type) return g.columns[i].type; + return "string"; + } + } + return null; + }, + //是否包含汇总 + isTotalSummary: function () + { + var g = this, p = this.options; + for (var i = 0; i < g.columns.length; i++) + { + if (g.columns[i].totalSummary) return true; + } + return false; + }, + //根据层次获取列集合 + //如果columnLevel为空,获取叶节点集合 + getColumns: function (columnLevel) + { + var g = this, p = this.options; + var columns = []; + for (var id in g._columns) + { + var col = g._columns[id]; + if (columnLevel != undefined) + { + if (col['__level'] == columnLevel) columns.push(col); + } + else + { + if (col['__leaf']) columns.push(col); + } + } + return columns; + }, + //改变排序 + changeSort: function (columnName, sortOrder) + { + var g = this, p = this.options; + if (g.loading) return true; + if (p.dataAction == "local") + { + var columnType = g.getColumnType(columnName); + if (!g.sortedData) + g.sortedData = g.filteredData; + if (!g.sortedData || !g.sortedData[p.root]) + return; + if (p.sortName == columnName) + { + g.sortedData[p.root].reverse(); + } else + { + g.sortedData[p.root].sort(function (data1, data2) + { + return g._compareData(data1, data2, columnName, columnType); + }); + } + if (p.usePager) + g.currentData = g._getCurrentPageData(g.sortedData); + else + g.currentData = g.sortedData; + g._showData(); + } + p.sortName = columnName; + p.sortOrder = sortOrder; + if (p.dataAction == "server") + { + g.loadData(p.where); + } + }, + //改变分页 + changePage: function (ctype) + { + var g = this, p = this.options; + if (g.loading) return true; + if (p.dataAction != "local" && g.isDataChanged && !confirm(p.isContinueByDataChanged)) + return false; + p.pageCount = parseInt($(".pcontrol span", g.toolbar).html()); + switch (ctype) + { + case 'first': if (p.page == 1) return; p.newPage = 1; break; + case 'prev': if (p.page == 1) return; if (p.page > 1) p.newPage = parseInt(p.page) - 1; break; + case 'next': if (p.page >= p.pageCount) return; p.newPage = parseInt(p.page) + 1; break; + case 'last': if (p.page >= p.pageCount) return; p.newPage = p.pageCount; break; + case 'input': + var nv = parseInt($('.pcontrol input', g.toolbar).val()); + if (isNaN(nv)) nv = 1; + if (nv < 1) nv = 1; + else if (nv > p.pageCount) nv = p.pageCount; + $('.pcontrol input', g.toolbar).val(nv); + p.newPage = nv; + break; + } + if (p.newPage == p.page) return false; + if (p.newPage == 1) + { + $(".l-bar-btnfirst span", g.toolbar).addClass("l-disabled"); + $(".l-bar-btnprev span", g.toolbar).addClass("l-disabled"); + } + else + { + $(".l-bar-btnfirst span", g.toolbar).removeClass("l-disabled"); + $(".l-bar-btnprev span", g.toolbar).removeClass("l-disabled"); + } + if (p.newPage == p.pageCount) + { + $(".l-bar-btnlast span", g.toolbar).addClass("l-disabled"); + $(".l-bar-btnnext span", g.toolbar).addClass("l-disabled"); + } + else + { + $(".l-bar-btnlast span", g.toolbar).removeClass("l-disabled"); + $(".l-bar-btnnext span", g.toolbar).removeClass("l-disabled"); + } + g.trigger('changePage', [p.newPage]); + if (p.dataAction == "server") + { + if (!p.parms) + { + p.parms = []; + } + if ($.isArray(p.parms)) + { + p.parms.push({ name: "changepage", value: "1", temp: true }); + } else + { + p.parms["changepage"] = "1"; + } + g.loadData(p.where); + } + else + { + g.currentData = g._getCurrentPageData(g.filteredData); + //增加以下一句调用: 在显示数据之前, 应该先调用转换tree的函数. + //否则会导致树的数据重复显示 + if (p.tree) + { + var childrenName = p.tree.childrenName; + $(g.filteredData[p.root]).each(function (index, item) + { + if (item[childrenName]) + item[childrenName] = []; + }); + g._convertTreeData(); + } + g._showData(); + } + }, + getSelectedRow: function () + { + for (var i in this.selected) + { + var o = this.selected[i]; + if (o['__id'] in this.records) + return o; + } + return null; + }, + getSelectedRows: function () + { + var arr = []; + for (var i in this.selected) + { + var o = this.selected[i]; + if (o['__id'] in this.records) + arr.push(o); + } + return arr; + }, + getSelectedRowObj: function () + { + for (var i in this.selected) + { + var o = this.selected[i]; + if (o['__id'] in this.records) + return this.getRowObj(o); + } + return null; + }, + getSelectedRowObjs: function () + { + var arr = []; + for (var i in this.selected) + { + var o = this.selected[i]; + if (o['__id'] in this.records) + arr.push(this.getRowObj(o)); + } + return arr; + }, + getCellObj: function (rowParm, column) + { + var rowdata = this.getRow(rowParm); + column = this.getColumn(column); + return document.getElementById(this._getCellDomId(rowdata, column)); + }, + getRowObj: function (rowParm, frozen) + { + var g = this, p = this.options; + if (rowParm == null) return null; + if (typeof (rowParm) == "string") + { + if (g._isRowId(rowParm)) + return document.getElementById(g.id + (frozen ? "|1|" : "|2|") + rowParm); + else + return document.getElementById(g.id + (frozen ? "|1|" : "|2|") + g.rows[parseInt(rowParm)]['__id']); + } + else if (typeof (rowParm) == "number") + { + return document.getElementById(g.id + (frozen ? "|1|" : "|2|") + g.rows[rowParm]['__id']); + } + else if (typeof (rowParm) == "object" && rowParm['__id']) //rowdata + { + return g.getRowObj(rowParm['__id'], frozen); + } + return rowParm; + }, + getRow: function (rowParm) + { + var g = this, p = this.options; + if (rowParm == null) return null; + if (typeof (rowParm) == "string") + { + if (g._isRowId(rowParm)) + return g.records[rowParm]; + else + return g.rows[parseInt(rowParm)]; + } + else if (typeof (rowParm) == "number") + { + return g.rows[parseInt(rowParm)]; + } + else if (typeof (rowParm) == "object" && rowParm.nodeType == 1 && !rowParm['__id']) //dom对象 + { + return g._getRowByDomId(rowParm.id); + } + return rowParm; + }, + _setColumnVisible: function (column, hide) + { + var g = this, p = this.options; + if (!hide) //显示 + { + column._hide = false; + document.getElementById(column['__domid']).style.display = ""; + //判断分组列是否隐藏,如果隐藏了则显示出来 + if (column['__pid'] != -1) + { + var pcol = g._columns[column['__pid']]; + if (pcol._hide) + { + document.getElementById(pcol['__domid']).style.display = ""; + this._setColumnVisible(pcol, hide); + } + } + } + else //隐藏 + { + column._hide = true; + document.getElementById(column['__domid']).style.display = "none"; + //判断同分组的列是否都隐藏,如果是则隐藏分组列 + if (column['__pid'] != -1) + { + var hideall = true; + var pcol = this._columns[column['__pid']]; + for (var i = 0; pcol && i < pcol.columns.length; i++) + { + if (!pcol.columns[i]._hide) + { + hideall = false; + break; + } + } + if (hideall) + { + pcol._hide = true; + document.getElementById(pcol['__domid']).style.display = "none"; + this._setColumnVisible(pcol, hide); + } + } + } + }, + //显示隐藏列 + toggleCol: function (columnparm, visible, toggleByPopup) + { + var g = this, p = this.options; + var column; + if (typeof (columnparm) == "number") + { + column = g.columns[columnparm]; + } + else if (typeof (columnparm) == "object" && columnparm['__id']) + { + column = columnparm; + } + else if (typeof (columnparm) == "string") + { + if (g._isColumnId(columnparm)) // column id + { + column = g._columns[columnparm]; + } + else // column name + { + $(g.columns).each(function () + { + if (this.name == columnparm) + g.toggleCol(this, visible, toggleByPopup); + }); + return; + } + } + if (!column) return; + var columnindex = column['__leafindex']; + var headercell = document.getElementById(column['__domid']); + if (!headercell) return; + headercell = $(headercell); + var cells = []; + for (var i in g.rows) + { + var obj = g.getCellObj(g.rows[i], column); + if (obj) cells.push(obj); + } + for (var i = 0; i < g.totalNumber; i++) + { + var tobj = document.getElementById(g.id + "|total" + i + "|" + column['__id']); + if (tobj) cells.push(tobj); + } + var colwidth = column._width; + //显示列 + if (visible && column._hide) + { + if (column.frozen) + g.f.gridtablewidth += (parseInt(colwidth) + 1); + else + g.gridtablewidth += (parseInt(colwidth) + 1); + g._setColumnVisible(column, false); + $(cells).show(); + } + //隐藏列 + else if (!visible && !column._hide) + { + if (column.frozen) + g.f.gridtablewidth -= (parseInt(colwidth) + 1); + else + g.gridtablewidth -= (parseInt(colwidth) + 1); + g._setColumnVisible(column, true); + $(cells).hide(); + } + if (column.frozen) + { + $("div:first", g.f.gridheader).width(g.f.gridtablewidth); + $("div:first", g.f.gridbody).width(g.f.gridtablewidth); + } + else + { + $("div:first", g.gridheader).width(g.gridtablewidth + 40); + if (g.gridtablewidth) + { + $("div:first", g.gridbody).width(g.gridtablewidth); + } else + { + $("div:first", g.gridbody).css("width", "auto"); + } + } + g._updateFrozenWidth(); + if (!toggleByPopup) + { + $(':checkbox[columnindex=' + columnindex + "]", g.popup).each(function () + { + this.checked = visible; + if ($.fn.ligerCheckBox) + { + var checkboxmanager = $(this).ligerGetCheckBoxManager(); + if (checkboxmanager) checkboxmanager.updateStyle(); + } + }); + } + }, + //设置列宽 + setColumnWidth: function (columnparm, newwidth) + { + var g = this, p = this.options; + if (!newwidth) return; + newwidth = parseInt(newwidth, 10); + var column; + if (typeof (columnparm) == "number") + { + column = g.columns[columnparm]; + } + else if (typeof (columnparm) == "object" && columnparm['__id']) + { + column = columnparm; + } + else if (typeof (columnparm) == "string") + { + if (g._isColumnId(columnparm)) // column id + { + column = g._columns[columnparm]; + } + else // column name + { + $(g.columns).each(function () + { + if (this.name == columnparm) + g.setColumnWidth(this, newwidth); + }); + return; + } + } + if (!column) return; + var mincolumnwidth = p.minColumnWidth; + if (column.minWidth) mincolumnwidth = column.minWidth; + newwidth = newwidth < mincolumnwidth ? mincolumnwidth : newwidth; + var diff = newwidth - column._width; + if (g.trigger('beforeChangeColumnWidth', [column, newwidth]) == false) return; + column._width = newwidth; + if (column.frozen) + { + g.f.gridtablewidth += diff; + $("div:first", g.f.gridheader).width(g.f.gridtablewidth); + $("div:first", g.f.gridbody).width(g.f.gridtablewidth); + } + else + { + g.gridtablewidth += diff; + $("div:first", g.gridheader).width(g.gridtablewidth + 40); + $("div:first", g.gridbody).width(g.gridtablewidth); + } + $(document.getElementById(column['__domid'])).css('width', newwidth); + var cells = []; + for (var rowid in g.records) + { + var obj = g.getCellObj(g.records[rowid], column); + if (obj) cells.push(obj); + + if (!g.enabledDetailEdit() && g.editors[rowid] && g.editors[rowid][column['__id']]) + { + var o = g.editors[rowid][column['__id']]; + if (o.editor.resize) o.editor.resize(o.input, newwidth, o.container.height(), o.editParm); + } + } + for (var i = 0; i < g.totalNumber; i++) + { + var tobj = document.getElementById(g.id + "|total" + i + "|" + column['__id']); + if (tobj) cells.push(tobj); + } + $(cells).css('width', newwidth).find("> div.l-grid-row-cell-inner:first").css('width', newwidth - 8); + + g._updateFrozenWidth(); + g._updateHorizontalScrollStatus.ligerDefer(g, 10); + + g.trigger('afterChangeColumnWidth', [column, newwidth]); + }, + //改变列表头内容 + changeHeaderText: function (columnparm, headerText) + { + var g = this, p = this.options; + var column; + if (typeof (columnparm) == "number") + { + column = g.columns[columnparm]; + } + else if (typeof (columnparm) == "object" && columnparm['__id']) + { + column = columnparm; + } + else if (typeof (columnparm) == "string") + { + if (g._isColumnId(columnparm)) // column id + { + column = g._columns[columnparm]; + } + else // column name + { + $(g.columns).each(function () + { + if (this.name == columnparm) + g.changeHeaderText(this, headerText); + }); + return; + } + } + if (!column) return; + var columnindex = column['__leafindex']; + var headercell = document.getElementById(column['__domid']); + $(".l-grid-hd-cell-text", headercell).html(headerText); + if (p.allowHideColumn) + { + $(':checkbox[columnindex=' + columnindex + "]", g.popup).parent().next().html(headerText); + } + }, + //改变列的位置 + changeCol: function (from, to, isAfter) + { + var g = this, p = this.options; + if (!from || !to) return; + var fromCol = g.getColumn(from); + var toCol = g.getColumn(to); + fromCol.frozen = toCol.frozen; + var fromColIndex, toColIndex; + var fromColumns = fromCol['__pid'] == -1 ? p.columns : g._columns[fromCol['__pid']].columns; + var toColumns = toCol['__pid'] == -1 ? p.columns : g._columns[toCol['__pid']].columns; + fromColIndex = $.inArray(fromCol, fromColumns); + toColIndex = $.inArray(toCol, toColumns); + var sameParent = fromColumns == toColumns; + var sameLevel = fromCol['__level'] == toCol['__level']; + toColumns.splice(toColIndex + (isAfter ? 1 : 0), 0, fromCol); + if (!sameParent) + { + fromColumns.splice(fromColIndex, 1); + } + else + { + if (isAfter) fromColumns.splice(fromColIndex, 1); + else fromColumns.splice(fromColIndex + 1, 1); + } + g._setColumns(p.columns); + g.reRender(); + }, + + + collapseDetail: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata) return; + for (var i = 0, l = g.columns.length; i < l; i++) + { + if (g.columns[i].isdetail) + { + var row = g.getRowObj(rowdata); + var cell = g.getCellObj(rowdata, g.columns[i]); + $(row).next("tr.l-grid-detailpanel").hide(); + $(".l-grid-row-cell-detailbtn:first", cell).removeClass("l-open"); + g.trigger('SysGridHeightChanged'); + return; + } + } + }, + extendDetail: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata) return; + for (var i = 0, l = g.columns.length; i < l; i++) + { + if (g.columns[i].isdetail) + { + var row = g.getRowObj(rowdata); + var cell = g.getCellObj(rowdata, g.columns[i]); + $(row).next("tr.l-grid-detailpanel").show(); + $(".l-grid-row-cell-detailbtn:first", cell).addClass("l-open"); + g.trigger('SysGridHeightChanged'); + return; + } + } + }, + getParent: function (rowParm) + { + var g = this, p = this.options; + if (!p.tree) return null; + var rowdata = g.getRow(rowParm); + if (!rowdata) return null; + if (rowdata['__pid'] in g.records) return g.records[rowdata['__pid']]; + else return null; + }, + getChildren: function (rowParm, deep) + { + var g = this, p = this.options; + if (!p.tree) return null; + var rowData = g.getRow(rowParm); + if (!rowData) return null; + var arr = []; + function loadChildren(data) + { + if (data[p.tree.childrenName]) + { + for (var i = 0, l = data[p.tree.childrenName].length; i < l; i++) + { + var o = data[p.tree.childrenName][i]; + if (o[p.statusName] == 'delete') continue; + arr.push(o); + if (deep) + loadChildren(o); + } + } + } + loadChildren(rowData); + return arr; + }, + isLeaf: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata) return; + return rowdata['__hasChildren'] ? false : true; + }, + hasChildren: function (rowParm) + { + var g = this, p = this.options; + var rowdata = this.getRow(rowParm); + if (!rowdata) return; + return (rowdata[p.tree.childrenName] && rowdata[p.tree.childrenName].length) ? true : false; + }, + existRecord: function (record) + { + for (var rowid in this.records) + { + if (this.records[rowid] == record) return true; + } + return false; + }, + _removeSelected: function (rowdata) + { + var g = this, p = this.options; + if (p.tree) + { + var children = g.getChildren(rowdata, true); + if (children) + { + for (var i = 0, l = children.length; i < l; i++) + { + var index2 = $.inArray(children[i], g.selected); + if (index2 != -1) g.selected.splice(index2, 1); + } + } + } + var index = $.inArray(rowdata, g.selected); + if (index != -1) g.selected.splice(index, 1); + }, + _getParentChildren: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var listdata; + if (p.tree && g.existRecord(rowdata) && rowdata['__pid'] in g.records) + { + listdata = g.records[rowdata['__pid']][p.tree.childrenName]; + } + else + { + listdata = g.currentData[p.root]; + } + return listdata; + }, + _removeData: function (rowdata) + { + var g = this, p = this.options; + var listdata = g._getParentChildren(rowdata); + var index = $.inArray(rowdata, listdata); + if (index != -1) + { + listdata.splice(index, 1); + } + g._removeSelected(rowdata); + }, + _addData: function (rowdata, parentdata, neardata, isBefore) + { + var g = this, p = this.options; + if (!g.currentData) g.currentData = {}; + if (!g.currentData[p.root]) g.currentData[p.root] = []; + var listdata = g.currentData[p.root]; + if (neardata) + { + if (p.tree) + { + if (parentdata) + listdata = parentdata[p.tree.childrenName]; + else if (neardata['__pid'] in g.records) + listdata = g.records[neardata['__pid']][p.tree.childrenName]; + } + var index = $.inArray(neardata, listdata); + listdata.splice(index == -1 ? -1 : index + (isBefore ? 0 : 1), 0, rowdata); + } + else + { + if (p.tree && parentdata) + { + listdata = parentdata[p.tree.childrenName]; + } + listdata.push(rowdata); + } + }, + //移动数据(树) + //parm [parentdata] 附加到哪一个节点下级 + //parm [neardata] 附加到哪一个节点的上方/下方 + //parm [isBefore] 是否附加到上方 + _appendData: function (rowdata, parentdata, neardata, isBefore) + { + var g = this, p = this.options; + rowdata[p.statusName] = "update"; + g._removeData(rowdata); + g._addData(rowdata, parentdata, neardata, isBefore); + }, + appendRange: function (rows, parentdata, neardata, isBefore) + { + var g = this, p = this.options; + var toRender = false; + $.each(rows, function (i, item) + { + if (item['__id'] && g.existRecord(item)) + { + if (g.isLeaf(parentdata)) g.upgrade(parentdata); + g._appendData(item, parentdata, neardata, isBefore); + toRender = true; + } + else + { + g.appendRow(item, parentdata, neardata, isBefore); + } + }); + if (toRender) g.reRender(); + + }, + appendRow: function (rowdata, parentdata, neardata, isBefore) + { + var g = this, p = this.options; + if ($.isArray(rowdata)) + { + g.appendRange(rowdata, parentdata, neardata, isBefore); + return; + } + if (rowdata['__id'] && g.existRecord(rowdata)) + { + g._appendData(rowdata, parentdata, neardata, isBefore); + g.reRender(); + return; + } + if (parentdata && g.isLeaf(parentdata)) g.upgrade(parentdata); + g.addRow(rowdata, neardata, isBefore ? true : false, parentdata); + }, + + + upgrade: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata || !p.tree) return; + rowdata[p.tree.childrenName] = rowdata[p.tree.childrenName] || []; + rowdata['__hasChildren'] = true; + var rowobjs = [g.getRowObj(rowdata)]; + if (g.enabledFrozen()) rowobjs.push(g.getRowObj(rowdata, true)); + $("> td > div > .l-grid-tree-space:last", rowobjs).addClass("l-grid-tree-link l-grid-tree-link-open"); + }, + demotion: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + if (!rowdata || !p.tree) return; + var rowobjs = [g.getRowObj(rowdata)]; + if (g.enabledFrozen()) rowobjs.push(g.getRowObj(rowdata, true)); + $("> td > div > .l-grid-tree-space:last", rowobjs).removeClass("l-grid-tree-link l-grid-tree-link-open l-grid-tree-link-close"); + if (g.hasChildren(rowdata)) + { + var children = g.getChildren(rowdata); + for (var i = 0, l = children.length; i < l; i++) + { + g.deleteRow(children[i]); + } + } + rowdata['__hasChildren'] = false; + }, + + collapseAll: function () + { + var g = this, p = this.options; + $(g.rows).each(function (rowIndex, rowParm) + { + var targetRowObj = g.getRowObj(rowParm); + var linkbtn = $(".l-grid-tree-link", targetRowObj); + if (linkbtn.hasClass("l-grid-tree-link-close")) return; + g.toggle(rowParm); + }); + }, + expandAll: function () + { + var g = this, p = this.options; + $(g.rows).each(function (rowIndex, rowParm) + { + var targetRowObj = g.getRowObj(rowParm); + var linkbtn = $(".l-grid-tree-link", targetRowObj); + if (linkbtn.hasClass("l-grid-tree-link-open")) return; + g.toggle(rowParm); + }); + }, + + collapse: function (rowParm) + { + var g = this, p = this.options; + var targetRowObj = g.getRowObj(rowParm); + var linkbtn = $(".l-grid-tree-link", targetRowObj); + if (linkbtn.hasClass("l-grid-tree-link-close")) return; + g.toggle(rowParm); + }, + expand: function (rowParm) + { + var g = this, p = this.options; + var targetRowObj = g.getRowObj(rowParm); + var linkbtn = $(".l-grid-tree-link", targetRowObj); + if (linkbtn.hasClass("l-grid-tree-link-open")) return; + g.toggle(rowParm); + }, + toggle: function (rowParm) + { + if (!rowParm) return; + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var targetRowObj = [g.getRowObj(rowdata)]; + if (g.enabledFrozen()) targetRowObj.push(g.getRowObj(rowdata, true)); + var level = rowdata['__level'], indexInCollapsedRows; + var linkbtn = $(".l-grid-tree-link:first", targetRowObj); + var opening = true; + g.collapsedRows = g.collapsedRows || []; + var isToExpanding = linkbtn.hasClass("l-grid-tree-link-close"); + + function toggleChildren(items) + { + for (var i = 0, l = items.length; i < l; i++) + { + var o = items[i]; + var subchildren = g.getChildren(o, false); + var haschildren = subchildren && subchildren.length ? true : false; + var currentRow = $([g.getRowObj(o['__id'])]); + if (g.enabledFrozen()) currentRow = currentRow.add(g.getRowObj(o['__id'], true)); + if (haschildren) + { + //如果这个子节点原来是折叠状态的,那么子节点的子节点不做处理 + if ($(".l-grid-tree-link", currentRow).hasClass("l-grid-tree-link-close")) + { + currentRow.show(); + } + //如果是展开状态的 + else + { + currentRow.show(); + toggleChildren(subchildren); + } + } + else + { + $(".l-grid-tree-link", currentRow).removeClass("l-grid-tree-link-close").addClass("l-grid-tree-link-open"); + currentRow.show(); + } + + } + } + function update() + { + var children = []; + //折叠,那么直接隐藏所有子节点即可 + if (!opening) + { + children = g.getChildren(rowdata, true); + $(children).each(function () + { + $(g.getRowObj(this)).hide(); + if (g.enabledFrozen()) $(g.getRowObj(this, true)).hide(); + }); + g.trigger('treeCollapsed', [rowdata]); + return; + } + + //展开,下面逻辑处理(选择性递归) + children = g.getChildren(rowdata, false); + + toggleChildren(children); + + + g.trigger('treeExpanded', [rowdata]); + } + + + if (isToExpanding) //收缩 + { + function linkbtn_expand() + { + linkbtn.removeClass("l-grid-tree-link-close").addClass("l-grid-tree-link-open"); + indexInCollapsedRows = $.inArray(rowdata, g.collapsedRows); + if (indexInCollapsedRows != -1) g.collapsedRows.splice(indexInCollapsedRows, 1); + } + var e = { + update: function () + { + linkbtn_expand(); + update(); + } + }; + if (g.hasBind('treeExpand') && g.trigger('treeExpand', [rowdata, e]) == false) return false; + linkbtn_expand(); + } + else //折叠 + { + function linkbtn_collapse() + { + linkbtn.addClass("l-grid-tree-link-close").removeClass("l-grid-tree-link-open"); + indexInCollapsedRows = $.inArray(rowdata, g.collapsedRows); + if (indexInCollapsedRows == -1) g.collapsedRows.push(rowdata); + } + var e = { + update: function () + { + linkbtn_collapse(); + update(); + } + }; + if (g.hasBind('treeCollapse') && g.trigger('treeCollapse', [rowdata, e]) == false) return false; + opening = false; + linkbtn_collapse(); + } + + update(); + + + }, + _bulid: function () + { + var g = this; + g._clearGrid(); + //创建头部 + g._initBuildHeader(); + //宽度高度初始化 + g._initHeight(); + //创建底部工具条 + g._initFootbar(); + //创建分页 + g._buildPager(); + //创建事件 + g._setEvent(); + }, + _setColumns: function (columns) + { + var g = this; + //初始化列 + g._initColumns(); + //创建表头 + g._initBuildGridHeader(); + //创建 显示/隐藏 列 列表 + g._initBuildPopup(); + }, + _initBuildHeader: function () + { + var g = this, p = this.options; + if (p.title) + { + $(".l-panel-header-text", g.header).html(p.title); + if (p.headerImg) + g.header.append("<img src='" + p.headerImg + "' />").addClass("l-panel-header-hasicon"); + } + else + { + g.header.hide(); + } + if (p.toolbar) + { + if ($.fn.ligerToolBar) + { + g.toolbarManager = g.topbar.ligerToolBar(p.toolbar); + //原语句不知道为什么, toolbar的父div高度为0. 导致样式有问题. + if (g.topbar.height() == 0) + g.topbar.parent().height(25); + else + g.topbar.parent().height(g.topbar.height()); + } + } + else + { + g.topbar.parent().remove(); + } + }, + _createColumnId: function (column) + { + if (column.id != null && column.id != "") return column.id.toString(); + return "c" + (100 + this._columnCount); + }, + _isColumnId: function (str) + { + return (str in this._columns); + }, + _initColumns: function () + { + var g = this, p = this.options; + g._columns = {}; //全部列的信息 + g._columnCount = 0; + g._columnLeafCount = 0; + g._columnMaxLevel = 1; + if (!p.columns) return; + function removeProp(column, props) + { + for (var i in props) + { + if (props[i] in column) + delete column[props[i]]; + } + } + //设置id、pid、level、leaf,返回叶节点数,如果是叶节点,返回1 + function setColumn(column, level, pid, previd) + { + if (column.editorType) + { + column.editor = column.editor || {}; + column.editor.type = column.editorType; + } + removeProp(column, ['__id', '__pid', '__previd', '__nextid', '__domid', '__leaf', '__leafindex', '__level', '__colSpan', '__rowSpan']); + if (level > g._columnMaxLevel) g._columnMaxLevel = level; + g._columnCount++; + column['__id'] = g._createColumnId(column); + column['__domid'] = g.id + "|hcell|" + column['__id']; + g._columns[column['__id']] = column; + if (!column.columns || !column.columns.length) + column['__leafindex'] = g._columnLeafCount++; + column['__level'] = level; + column['__pid'] = pid; + column['__previd'] = previd; + if (!column.columns || !column.columns.length) + { + column['__leaf'] = true; + return 1; + } + var leafcount = 0; + var newid = -1; + for (var i = 0, l = column.columns.length; i < l; i++) + { + var col = column.columns[i]; + leafcount += setColumn(col, level + 1, column['__id'], newid); + newid = col['__id']; + } + column['__leafcount'] = leafcount; + return leafcount; + } + var lastid = -1; + //行序号 + if (p.rownumbers) + { + var frozenRownumbers = g.enabledGroup() ? false : p.frozen && p.frozenRownumbers; + var col = { isrownumber: true, issystem: true, width: p.rownumbersColWidth, frozen: frozenRownumbers }; + setColumn(col, 1, -1, lastid); + lastid = col['__id']; + } + //明细列 + if (g.enabledDetail()) + { + var frozenDetail = g.enabledGroup() ? false : p.frozen && p.frozenDetail; + var col = { isdetail: true, issystem: true, width: p.detailColWidth, frozen: frozenDetail }; + setColumn(col, 1, -1, lastid); + lastid = col['__id']; + } + //复选框列 + if (g.enabledCheckbox()) + { + var frozenCheckbox = g.enabledGroup() ? false : p.frozen && p.frozenCheckbox; + var col = { ischeckbox: true, issystem: true, width: p.detailColWidth, frozen: frozenCheckbox }; + setColumn(col, 1, -1, lastid); + lastid = col['__id']; + } + for (var i = 0, l = p.columns.length; i < l; i++) + { + var col = p.columns[i]; + //增加以下一句. 因为在低版本IE中, 可能因为修改了prototype, + //导致这里取出undefined, 并进一步导致后续的函数调用出错. + if (!col) continue; + setColumn(col, 1, -1, lastid); + lastid = col['__id']; + } + //设置colSpan和rowSpan + for (var id in g._columns) + { + var col = g._columns[id]; + if (col['__leafcount'] > 1) + { + col['__colSpan'] = col['__leafcount']; + } + if (col['__leaf'] && col['__level'] != g._columnMaxLevel) + { + col['__rowSpan'] = g._columnMaxLevel - col['__level'] + 1; + } + } + //叶级别列的信息 + g.columns = g.getColumns(); + $(g.columns).each(function (i, column) + { + column.columnname = column.name; + column.columnindex = i; + column.type = column.type || "string"; + column.islast = i == g.columns.length - 1; + column.isSort = column.isSort == false ? false : true; + column.frozen = column.frozen ? true : false; + column._width = g._getColumnWidth(column); + column._hide = column.hide ? true : false; + }); + }, + _getColumnWidth: function (column) + { + var g = this, p = this.options; + if (column._width) return column._width; + var colwidth = column.width || p.columnWidth; + if (!colwidth || colwidth == "auto") + { + var autoColumnNumber = 0, noAutoColumnWidth = 0; + $(g.columns).each(function (i, col) + { + var colwidth = col.width || p.columnWidth; + var isAuto = (!colwidth || colwidth == "auto") ? true : false; + if (isAuto) autoColumnNumber++; + else noAutoColumnWidth += (parseInt(g._getColumnWidth(col)) + 1); + }); + colwidth = parseInt((g.grid.width() - noAutoColumnWidth) / autoColumnNumber) - 1; + } + if (typeof (colwidth) == "string" && colwidth.indexOf('%') > 0) + { + /* + * 修复行控件宽度被忽略的bug + */ + var lwidth = 0; + if (g.enabledDetail()) + { + lwidth += p.detailColWidth; + } + if (g.enabledCheckbox()) + { + lwidth += p.checkboxColWidth; + } + if (g.options.rownumbers) + { + lwidth += g.options.rownumbersColWidth; + } + column._width = colwidth = parseInt(parseInt(colwidth) * 0.01 * (g.grid.width() - lwidth - (g.columns.length / 2) - 1)); + } + if (column.minWidth && colwidth < column.minWidth) colwidth = column.minWidth; + if (column.maxWidth && colwidth > column.maxWidth) colwidth = column.maxWidth; + return colwidth; + }, + _createHeaderCell: function (column) + { + var g = this, p = this.options; + var jcell = $("<td class='l-grid-hd-cell'><div class='l-grid-hd-cell-inner'><span class='l-grid-hd-cell-text'></span></div></td>"); + jcell.attr("id", column['__domid']); + if (!column['__leaf']) + jcell.addClass("l-grid-hd-cell-mul"); + if (column.columnindex == g.columns.length - 1) + { + jcell.addClass("l-grid-hd-cell-last"); + } + if (column.isrownumber) + { + jcell.addClass("l-grid-hd-cell-rownumbers"); + jcell.html("<div class='l-grid-hd-cell-inner'></div>"); + } + if (column.ischeckbox) + { + jcell.addClass("l-grid-hd-cell-checkbox"); + jcell.html("<div class='l-grid-hd-cell-inner'><div class='l-grid-hd-cell-text l-grid-hd-cell-btn-checkbox'></div></div>"); + } + if (column.isdetail) + { + jcell.addClass("l-grid-hd-cell-detail"); + jcell.html("<div class='l-grid-hd-cell-inner'><div class='l-grid-hd-cell-text l-grid-hd-cell-btn-detail'></div></div>"); + } + if (column.heightAlign) + { + $(".l-grid-hd-cell-inner:first", jcell).css("textAlign", column.heightAlign); + } + if (column['__colSpan']) jcell.attr("colSpan", column['__colSpan']); + if (column['__rowSpan']) + { + jcell.attr("rowSpan", column['__rowSpan']); + jcell.height(p.headerRowHeight * column['__rowSpan']); + var paddingTop = (p.headerRowHeight * column['__rowSpan'] - p.headerRowHeight) / 2 - 5; + $(".l-grid-hd-cell-inner:first", jcell).css("paddingTop", paddingTop); + } else + { + jcell.height(p.headerRowHeight); + } + if (column['__leaf']) + { + jcell.width(column['_width']); + jcell.attr("columnindex", column['__leafindex']); + } + var cellHeight = jcell.height(); + if (!column['__rowSpan'] && cellHeight > 10) $(">div:first", jcell).height(cellHeight); + if (column._hide) jcell.hide(); + if (column.name) jcell.attr({ columnname: column.name }); + var headerText = ""; + if (column.display && column.display != "") + headerText = column.display; + else if (column.headerRender) + headerText = column.headerRender(column); + else + headerText = "&nbsp;"; + $(".l-grid-hd-cell-text:first", jcell).html(headerText); + if (!column.issystem && column['__leaf'] && column.resizable !== false && $.fn.ligerResizable && p.allowAdjustColWidth) + { + g.colResizable[column['__id']] = jcell.ligerResizable({ + handles: 'e', + onStartResize: function (e, ev) + { + this.proxy.hide(); + g.draggingline.css({ height: g.body.height(), top: 0, left: ev.pageX - g.grid.offset().left + parseInt(g.body[0].scrollLeft) }).show(); + }, + onResize: function (e, ev) + { + g.colresizing = true; + g.draggingline.css({ left: ev.pageX - g.grid.offset().left + parseInt(g.body[0].scrollLeft) }); + $('body').add(jcell).css('cursor', 'e-resize'); + }, + onStopResize: function (e) + { + g.colresizing = false; + $('body').add(jcell).css('cursor', 'default'); + g.draggingline.hide(); + g.setColumnWidth(column, parseInt(column._width) + e.diffX); + return false; + } + }); + } + g.trigger('headerCellBulid', [jcell, column]); + return jcell; + }, + _initBuildGridHeader: function () + { + var g = this, p = this.options; + g.gridtablewidth = 0; + g.f.gridtablewidth = 0; + if (g.colResizable) + { + for (var i in g.colResizable) + { + g.colResizable[i].destroy(); + } + g.colResizable = null; + } + g.colResizable = {}; + $("tbody:first", g.gridheader).html(""); + $("tbody:first", g.f.gridheader).html(""); + for (var level = 1; level <= g._columnMaxLevel; level++) + { + var columns = g.getColumns(level); //获取level层次的列集合 + var islast = level == g._columnMaxLevel; //是否最末级 + var tr = $("<tr class='l-grid-hd-row'></tr>"); + var trf = $("<tr class='l-grid-hd-row'></tr>"); + if (!islast) tr.add(trf).addClass("l-grid-hd-mul"); + $("tbody:first", g.gridheader).append(tr); + $("tbody:first", g.f.gridheader).append(trf); + $(columns).each(function (i, column) + { + (column.frozen ? trf : tr).append(g._createHeaderCell(column)); + if (column['__leaf']) + { + var colwidth = column['_width']; + if (!column.frozen) + g.gridtablewidth += (parseInt(colwidth) ? parseInt(colwidth) : 0) + 1; + else + g.f.gridtablewidth += (parseInt(colwidth) ? parseInt(colwidth) : 0) + 1; + } + }); + } + if (g._columnMaxLevel > 0) + { + var h = p.headerRowHeight * g._columnMaxLevel; + g.gridheader.add(g.f.gridheader).height(h); + if (p.rownumbers && p.frozenRownumbers) g.f.gridheader.find("td:first").height(h); + } + g._updateFrozenWidth(); + $("div:first", g.gridheader).width(g.gridtablewidth + 40); + }, + _initBuildPopup: function () + { + var g = this, p = this.options; + $(':checkbox', g.popup).unbind(); + $('tbody tr', g.popup).remove(); + $(g.columns).each(function (i, column) + { + if (column.issystem) return; + if (column.isAllowHide == false) return; + var chk = 'checked="checked"'; + if (column._hide) chk = ''; + var header = column.display; + $('tbody', g.popup).append('<tr><td class="l-column-left"><input type="checkbox" ' + chk + ' class="l-checkbox" columnindex="' + i + '"/></td><td class="l-column-right">' + header + '</td></tr>'); + }); + if ($.fn.ligerCheckBox) + { + $('input:checkbox', g.popup).ligerCheckBox( + { + onBeforeClick: function (obj) + { + if (!obj.checked) return true; + if ($('input:checked', g.popup).length <= p.minColToggle) + return false; + return true; + } + }); + } + //表头 - 显示/隐藏'列控制'按钮事件 + if (p.allowHideColumn) + { + $('tr', g.popup).hover(function () + { + $(this).addClass('l-popup-row-over'); + }, + function () + { + $(this).removeClass('l-popup-row-over'); + }); + var onPopupCheckboxChange = function () + { + if ($('input:checked', g.popup).length + 1 <= p.minColToggle) + { + return false; + } + g.toggleCol(parseInt($(this).attr("columnindex")), this.checked, true); + }; + if ($.fn.ligerCheckBox) + $(':checkbox', g.popup).bind('change', onPopupCheckboxChange); + else + $(':checkbox', g.popup).bind('click', onPopupCheckboxChange); + } + }, + _initHeight: function () + { + var g = this, p = this.options; + if (p.height == 'auto') + { + g.gridbody.height('auto'); + g.f.gridbody.height('auto'); + } + if (p.width) + { + g.grid.width(p.width); + } + g._onResize.call(g); + }, + _initFootbar: function () + { + var g = this, p = this.options; + if (p.usePager) + { + if (p.pagerRender) + { + g.toolbar.html(p.pagerRender.call(g)); + return; + } + if (p.scrollToPage) + { + g.toolbar.hide(); + return; + } + //创建底部工具条 - 选择每页显示记录数 + var optStr = ""; + var selectedIndex = -1; + $(p.pageSizeOptions).each(function (i, item) + { + var selectedStr = ""; + if (p.pageSize == item) selectedIndex = i; + optStr += "<option value='" + item + "' " + selectedStr + " >" + item + "</option>"; + }); + + $('.l-bar-selectpagesize', g.toolbar).append("<select name='rp'>" + optStr + "</select>"); + if (selectedIndex != -1) $('.l-bar-selectpagesize select', g.toolbar)[0].selectedIndex = selectedIndex; + if (p.switchPageSizeApplyComboBox && $.fn.ligerComboBox) + { + $(".l-bar-selectpagesize select", g.toolbar).ligerComboBox( + { + onBeforeSelect: function () + { + if (p.url && g.isDataChanged && !confirm(p.isContinueByDataChanged)) + return false; + return true; + }, + width: 45 + }); + } + } + else + { + g.toolbar.hide(); + } + }, + _searchData: function (data, clause) + { + var g = this, p = this.options; + var newData = new Array(); + for (var i = 0; i < data.length; i++) + { + if (clause(data[i], i)) + { + newData[newData.length] = data[i]; + } + } + return newData; + }, + _clearGrid: function () + { + var g = this, p = this.options; + g._fixRows(); + for (var i in g.rows) + { + var rowobj = $(g.getRowObj(g.rows[i])); + if (g.enabledFrozen()) + rowobj = rowobj.add(g.getRowObj(g.rows[i], true)); + rowobj.unbind(); + } + //清空数据 + g.gridbody.html(""); + g.f.gridbody.html(""); + g.recordNumber = 0; + g.records = {}; + g.rows = []; + g._fixRows(); + //清空选择的行 + g.selected = []; + g.totalNumber = 0; + //编辑器计算器 + g.editorcounter = 0; + }, + _fixRows : function() + { + var g = this, p = this.options; + if (!g.rows) return; + for (var i in g.rows) + { + if ($.isFunction(g.rows[i])) + { + delete g.rows[i]; + } + } + }, + + _fillGridBody: function (data, frozen,sourceType) + { + var g = this, p = this.options; + //加载数据 + var gridhtmlarr = sourceType == "scrollappend" ? [] : ['<div class="l-grid-body-inner"><table class="l-grid-body-table" cellpadding=0 cellspacing=0><tbody>']; + if (g.enabledGroup()) //启用分组模式 + { + var groups = []; //分组列名数组 + var groupsdata = []; //切成几块后的数据 + g.groups = groupsdata; + for (var rowparm in data) + { + var item = data[rowparm]; + var groupColumnValue = item[p.groupColumnName]; + var valueIndex = $.inArray(groupColumnValue, groups); + if (valueIndex == -1) + { + groups.push(groupColumnValue); + valueIndex = groups.length - 1; + groupsdata.push([]); + } + groupsdata[valueIndex].push(item); + } + $(groupsdata).each(function (i, item) + { + if (groupsdata.length == 1) + gridhtmlarr.push('<tr class="l-grid-grouprow l-grid-grouprow-last l-grid-grouprow-first"'); + if (i == groupsdata.length - 1) + gridhtmlarr.push('<tr class="l-grid-grouprow l-grid-grouprow-last"'); + else if (i == 0) + gridhtmlarr.push('<tr class="l-grid-grouprow l-grid-grouprow-first"'); + else + gridhtmlarr.push('<tr class="l-grid-grouprow"'); + gridhtmlarr.push(' groupindex"=' + i + '" >'); + gridhtmlarr.push('<td colSpan="' + g.columns.length + '" class="l-grid-grouprow-cell">'); + gridhtmlarr.push('<span class="l-grid-group-togglebtn">&nbsp;&nbsp;&nbsp;&nbsp;</span>'); + if (p.groupRender) + gridhtmlarr.push(p.groupRender(groups[i], item, p.groupColumnDisplay)); + else + gridhtmlarr.push(p.groupColumnDisplay + ':' + groups[i]); + + + gridhtmlarr.push('</td>'); + gridhtmlarr.push('</tr>'); + + gridhtmlarr.push(g._getHtmlFromData(item, frozen)); + //汇总 + if (g.isTotalSummary()) + gridhtmlarr.push(g._getTotalSummaryHtml(item, "l-grid-totalsummary-group", frozen)); + }); + } + else + { + gridhtmlarr.push(g._getHtmlFromData(data, frozen)); + } + if (!sourceType == "scrollappend") + { + gridhtmlarr.push('</tbody></table></div>'); + } + + if (sourceType == "scrollappend") + { + (frozen ? g.f.gridbody : g.gridbody).find("tbody:first").append(gridhtmlarr.join('')); + } + else + { + (frozen ? g.f.gridbody : g.gridbody).html(gridhtmlarr.join('')); + } + + if (frozen) + { + g.f.gridbody.find(">l-jplace").remove(); + g.f.gridbody.append('<div class="l-jplace"></div>'); + } + + if (p.usePager && p.scrollToPage && !p.scrollToAppend) + { + var jgridbodyinner = frozen ? g.f.gridbody.find("> .l-grid-body-inner") : g.gridbody.find("> .l-grid-body-inner"); + var jreplace = jgridbodyinner.find("> .l-scrollreplacetop"); + jreplace = jreplace.length ? jreplace : $('<div class="l-scrollreplacetop"></div>').prependTo(jgridbodyinner); + jreplace.css("width", "80%").height(g.lastScrollTop); + + jreplace = jgridbodyinner.find("> .l-scrollreplacebottom"); + jreplace = jreplace.length ? jreplace : $('<div class="l-scrollreplacebottom"></div>').appendTo(jgridbodyinner); + jreplace.css("width", "80%").height((p.pageCount - p.newPage) * g._getOnePageHeight()); + } + //分组时不需要 + if (!g.enabledGroup()) + { + //创建汇总行 + g._bulidTotalSummary(frozen); + } + $("> div:first", g.gridbody).width(g.gridtablewidth); + g._onResize(); + }, + _showData: function (sourceType) + { + var g = this, p = this.options; + g.changedCells = {}; + var data = g.currentData[p.root]; + if (p.usePager) + { + //更新总记录数 + if (p.dataAction == "server" && g.data && g.data[p.record]) + p.total = g.data[p.record]; + else if (g.filteredData && g.filteredData[p.root]) + p.total = g.filteredData[p.root].length; + else if (g.data && g.data[p.root]) + p.total = g.data[p.root].length; + else if (data) + p.total = data.length; + + p.page = p.newPage; + if (!p.total) p.total = 0; + if (!p.page) p.page = 1; + p.pageCount = Math.ceil(p.total / p.pageSize); + if (!p.pageCount) p.pageCount = 1; + if (!p.scrollToPage) + { + //更新分页 + g._buildPager(); + } + } + //加载中 + $('.l-bar-btnloading:first', g.toolbar).removeClass('l-bar-btnloading'); + if (g.trigger('beforeShowData', [g.currentData]) == false) return; + if (sourceType != "scrollappend") + { + g._clearGrid(); + } + g.isDataChanged = false; + if (!data || !data.length) + { + g.gridview.addClass("l-grid-empty"); + $(g.element).addClass("l-empty"); + $("<div></div>").addClass("l-grid-body-inner").appendTo(g.gridbody).css({ + width: g.gridheader.find(">div:first").width(), + height: g.gridbody.height() + }); + if (p.pagerRender) + { + g.toolbar.html(p.pagerRender.call(g)); + return; + } + g._onResize.ligerDefer(g, 50); + return; + } + else + { + g.gridview.removeClass("l-grid-empty"); + $(g.element).removeClass("l-empty"); + } + $(".l-bar-btnload:first span", g.toolbar).removeClass("l-disabled"); + g._updateGridData(); + if (g.enabledFrozen()) + g._fillGridBody(g.rows, true, sourceType); + g._fillGridBody(g.rows, false, sourceType); + g.trigger('SysGridHeightChanged'); + if (sourceType == "scroll") + { + g.trigger('sysScrollLoaded'); + } + if (p.totalRender) + { + $(".l-panel-bar-total", g.element).remove(); + $(".l-panel-bar", g.element).before('<div class="l-panel-bar-total">' + p.totalRender(g.data, g.filteredData) + '</div>'); + } + if (p.mouseoverRowCssClass) + { + for (var i in g.rows) + { + var rowobj = $(g.getRowObj(g.rows[i])); + if (g.enabledFrozen()) + rowobj = rowobj.add(g.getRowObj(g.rows[i], true)); + rowobj.bind('mouseover.gridrow', function () + { + g._onRowOver(this, true); + }).bind('mouseout.gridrow', function () + { + g._onRowOver(this, false); + }); + } + } + g._fixHeight(); + if (p.pagerRender) + { + g.toolbar.html(p.pagerRender.call(g)); + return; + } + g.gridbody.trigger('scroll.grid'); + g.trigger('afterShowData', [g.currentData]); + }, + _fixHeight: function () + { + var g = this, p = this.options; + if (p.fixedCellHeight || !p.frozen) return; + var column1, column2; + for (var i in g.columns) + { + var column = g.columns[i]; + if (column1 && column2) break; + if (column.frozen && !column1) + { + column1 = column; + continue; + } + if (!column.frozen && !column2) + { + column2 = column; + continue; + } + } + if (!column1 || !column2) return; + for (var rowid in g.records) + { + var cell1 = g.getCellObj(rowid, column1), cell2 = g.getCellObj(rowid, column2); + var height = Math.max($(cell1).height(), ($(cell2).height())); + $(cell1).add(cell2).height(height); + } + }, + _getRowDomId: function (rowdata, frozen) + { + return this.id + "|" + (frozen ? "1" : "2") + "|" + rowdata['__id']; + }, + _getCellDomId: function (rowdata, column) + { + return this._getRowDomId(rowdata, column.frozen) + "|" + column['__id']; + }, + _getHtmlFromData: function (data, frozen) + { + if (!data) return ""; + var g = this, p = this.options; + var gridhtmlarr = []; + for (var i = 0, l = data.length; i < l; i++) + { + var item = data[i]; + var rowid = item['__id']; + if (!item) continue; + gridhtmlarr.push('<tr'); + gridhtmlarr.push(' id="' + g._getRowDomId(item, frozen) + '"'); + gridhtmlarr.push(' class="l-grid-row'); //class start + if (!frozen && g.enabledCheckbox() && p.isChecked && p.isChecked(item)) + { + g.select(item); + gridhtmlarr.push(' l-selected'); + } + else if (g.isSelected(item)) + { + gridhtmlarr.push(' l-selected'); + } + else if (p.isSelected && p.isSelected(item)) + { + g.select(item); + gridhtmlarr.push(' l-selected'); + } + if (item['__index'] % 2 == 1 && p.alternatingRow) + gridhtmlarr.push(' l-grid-row-alt'); + //自定义css class + if (p.rowClsRender) + { + var rowcls = p.rowClsRender(item, rowid); + rowcls && gridhtmlarr.push(' ' + rowcls); + } + gridhtmlarr.push('" '); //class end + if (p.rowAttrRender) gridhtmlarr.push(p.rowAttrRender(item, rowid)); + if (p.tree && g.collapsedRows && g.collapsedRows.length) + { + var isHide = function () + { + var pitem = g.getParent(item); + while (pitem) + { + if ($.inArray(pitem, g.collapsedRows) != -1) return true; + pitem = g.getParent(pitem); + } + return false; + }; + if (isHide()) gridhtmlarr.push(' style="display:none;" '); + } + else if (p.tree && p.tree.isExtend) + { + var isHide = function () + { + var pitem = g.getParent(item); + while (pitem) + { + if (p.tree.isExtend(pitem) == false) return true; + pitem = g.getParent(pitem); + } + return false; + }; + if (isHide()) gridhtmlarr.push(' style="display:none;" '); + } + gridhtmlarr.push('>'); + $(g.columns).each(function (columnindex, column) + { + if (frozen != column.frozen) return; + gridhtmlarr.push('<td'); + gridhtmlarr.push(' id="' + g._getCellDomId(item, this) + '"'); + //如果是行序号(系统列) + if (this.isrownumber) + { + gridhtmlarr.push(' class="l-grid-row-cell l-grid-row-cell-rownumbers" style="width:' + this.width + 'px"><div class="l-grid-row-cell-inner"'); + if (p.fixedCellHeight) + gridhtmlarr.push(' style = "height:' + p.rowHeight + 'px;" '); + else + gridhtmlarr.push(' style = "min-height:' + p.rowHeight + 'px;" '); + gridhtmlarr.push('>' + (parseInt(item['__index']) + 1) + '</div></td>'); + return; + } + //如果是复选框(系统列) + if (this.ischeckbox) + { + gridhtmlarr.push(' class="l-grid-row-cell l-grid-row-cell-checkbox" style="width:' + this.width + 'px"><div class="l-grid-row-cell-inner"'); + if (p.fixedCellHeight) + gridhtmlarr.push(' style = "height:' + p.rowHeight + 'px;" '); + else + gridhtmlarr.push(' style = "min-height:' + p.rowHeight + 'px;" '); + gridhtmlarr.push('>'); + gridhtmlarr.push('<span class="l-grid-row-cell-btn-checkbox"></span>'); + gridhtmlarr.push('</div></td>'); + return; + } + //如果是明细列(系统列) + else if (this.isdetail) + { + gridhtmlarr.push(' class="l-grid-row-cell l-grid-row-cell-detail" style="width:' + this.width + 'px"><div class="l-grid-row-cell-inner"'); + if (p.fixedCellHeight) + gridhtmlarr.push(' style = "height:' + p.rowHeight + 'px;" '); + else + gridhtmlarr.push(' style = "min-height:' + p.rowHeight + 'px;" '); + gridhtmlarr.push('>'); + if (!p.isShowDetailToggle || p.isShowDetailToggle(item)) + { + gridhtmlarr.push('<span class="l-grid-row-cell-detailbtn"></span>'); + } + gridhtmlarr.push('</div></td>'); + return; + } + var colwidth = this._width; + gridhtmlarr.push(' class="l-grid-row-cell '); + if (g.changedCells[rowid + "_" + this['__id']]) gridhtmlarr.push("l-grid-row-cell-edited "); + if (this.islast) + gridhtmlarr.push('l-grid-row-cell-last '); + gridhtmlarr.push('"'); + //if (this.columnname) gridhtmlarr.push('columnname="' + this.columnname + '"'); + gridhtmlarr.push(' style = "'); + gridhtmlarr.push('width:' + colwidth + 'px; '); + if (column._hide) + { + gridhtmlarr.push('display:none;'); + } + gridhtmlarr.push(' ">'); + gridhtmlarr.push(g._getCellHtml(item, column)); + gridhtmlarr.push('</td>'); + }); + gridhtmlarr.push('</tr>'); + } + return gridhtmlarr.join(''); + }, + _getCellHtml: function (rowdata, column) + { + var g = this, p = this.options; + if (column.isrownumber) + return '<div class="l-grid-row-cell-inner">' + (parseInt(rowdata['__index']) + 1) + '</div>'; + var htmlarr = []; + htmlarr.push('<div class="l-grid-row-cell-inner"'); + //htmlarr.push('<div'); + htmlarr.push(' style = "width:' + parseInt(column._width - 8) + 'px;'); + if (p.fixedCellHeight) htmlarr.push('height:' + p.rowHeight + 'px;'); + htmlarr.push('min-height:' + p.rowHeight + 'px; '); + if (column.align) htmlarr.push('text-align:' + column.align + ';'); + var content = g._getCellContent(rowdata, column); + htmlarr.push('">' + content + '</div>'); + return htmlarr.join(''); + }, + _setValueByName: function (data, name, value) + { + if (!data || !name) return null; + if (name.indexOf('.') == -1) + { + data[name] = value; + } + else + { + try + { + new Function("data,value", "data." + name + "=value;")(data, value); + } + catch (e) + { + } + } + }, + _getValueByName: function (data, name) + { + if (!data || !name) return null; + if (name.indexOf('.') == -1) + { + return data[name]; + } + else + { + try + { + return new Function("data", "return data." + name + ";")(data); + } + catch (e) + { + return null; + } + } + }, + _getCellContent: function (rowdata, column) + { + var g = this, p = this.options; + if (!rowdata || !column) return ""; + if (column.isrownumber) return parseInt(rowdata['__index']) + 1; + var rowid = rowdata['__id']; + var rowindex = rowdata['__index']; + var value = g._getValueByName(rowdata, column.name); + var text = g._getValueByName(rowdata, column.textField); + var content = ""; + if (column.render) + { + content = column.render.call(g, rowdata, rowindex, value, column); + } + else if (p.formatters[column.type]) + { + content = p.formatters[column.type].call(g, value, column); + } + else if (text != null) + { + content = text.toString(); + } + else if (value != null) + { + content = value.toString(); + } + if (p.tree && (p.tree.columnName != null && p.tree.columnName == column.name || p.tree.columnId != null && p.tree.columnId == column.id)) + { + content = g._getTreeCellHtml(content, rowdata); + } + return content || ""; + }, + _getTreeCellHtml: function (oldContent, rowdata) + { + var level = rowdata['__level']; + var g = this, p = this.options; + //var isExtend = p.tree.isExtend(rowdata); + var isExtend = g.collapsedRows == null ? p.tree.isExtend(rowdata) : $.inArray(rowdata, g.collapsedRows || []) == -1; + var isParent = p.tree.isParent(rowdata); + var content = ""; + level = parseInt(level) || 1; + for (var i = 1; i < level; i++) + { + content += "<div class='l-grid-tree-space'></div>"; + } + + if (isExtend && isParent) + content += "<div class='l-grid-tree-space l-grid-tree-link l-grid-tree-link-open'></div>"; + else if (isParent) + content += "<div class='l-grid-tree-space l-grid-tree-link l-grid-tree-link-close'></div>"; + else + content += "<div class='l-grid-tree-space'></div>"; + content += "<span class='l-grid-tree-content'>" + oldContent + "</span>"; + return content; + }, + _applyEditor: function (obj) + { + var g = this, p = this.options; + var rowcell = obj, ids = rowcell.id.split('|'); + var columnid = ids[ids.length - 1], column = g._columns[columnid]; + var row = $(rowcell).parent(), rowdata = g.getRow(row[0]), rowid = rowdata['__id'], rowindex = rowdata['__index']; + if (!column || !column.editor) return; + var columnname = column.name, columnindex = column.columnindex; + if (column.editor.type && p.editors[column.editor.type]) + { + var currentdata = g._getValueByName(rowdata, columnname); + var editParm = { record: rowdata, value: currentdata, column: column, rowindex: rowindex }; + if (column.textField) editParm.text = g._getValueByName(rowdata, column.textField); + if (g.trigger('beforeEdit', [editParm]) == false) return false; + g.lastEditRow = rowdata; + liger.lastEditGrid = g; + var editor = p.editors[column.editor.type], + jcell = $(rowcell), offset = $(rowcell).offset(), + width = $(rowcell).width(), height = $(rowcell).height(), + container = $("<div class='l-grid-editor'></div>").appendTo(g.grid), + left = 0, + top = 0, + pc = jcell.position(), + pb = g.gridbody.position(), + pv = g.gridview2.position(), + //加上括号解决不能正常判定topBar的高度。不加括号会忽略后面运算出来的值 + topbarHeight = (p.toolbar ? g.topbar.parent().outerHeight() : 0) + (p.title ? g.header.outerHeight() : 0), + left = pc.left + pb.left + pv.left, + top = pc.top + pb.top + pv.top + topbarHeight; + + jcell.html(""); + g.setCellEditing(rowdata, column, true); + + var isIE = (!!window.ActiveXObject || "ActiveXObject" in window) ? true : false, + isIE8 = $.browser.version.indexOf('8') == 0; + if (isIE) + { + height -= isIE8 ? 1 : 2; + top -= 1; + left -= 1; + } + else if ($.browser.mozilla) + { + height -= 1; + top -= 1; + left -= 1; + } + else if ($.browser.safari) + { + top -= 1; + } else + { + height -= 1; + } + left += p.editorLeftDiff || 0; + top += p.editorTopDiff || 0; + height += p.editorHeightDiff || 0; + + container + .css({ left: left, top: top }) + .show(); + if (column.textField) editParm.text = g._getValueByName(rowdata, column.textField); + var editorInput = g._createEditor(editor, container, editParm, width, height - 1); + g.editor = { editing: true, editor: editor, input: editorInput, editParm: editParm, container: container }; + g.unbind('sysEndEdit'); + g.bind('sysEndEdit', function () + { + var newValue = editor.getValue(editorInput, editParm); + if (column.textField && editor.getText) + { + editParm.text = editor.getText(editorInput, editParm); + } + if (editor.getSelected) + { + editParm.selected = editor.getSelected(editorInput, editParm); + } + if (newValue != currentdata) + { + $(rowcell).addClass("l-grid-row-cell-edited"); + g.changedCells[rowid + "_" + column['__id']] = true; + editParm.value = newValue; + } + if (column.editor.onChange) column.editor.onChange.call(editorInput, editParm); + if (g._checkEditAndUpdateCell(editParm)) + { + if (column.editor.onChanged) column.editor.onChanged.call(editorInput, editParm); + } + }); + } + }, + _checkEditAndUpdateCell: function (editParm) + { + var g = this, p = this.options; + if (g.trigger('beforeSubmitEdit', [editParm]) == false) return false; + var column = editParm.column; + if (editParm.text && column.textField) g._setValueByName(editParm.record, column.textField, editParm.text); + g.updateCell(column, editParm.value, editParm.record); + if (column.render || g.enabledTotal()) g.reRender({ column: column }); + g.reRender({ rowdata: editParm.record }); + return true; + }, + _getCurrentPageData: function (source) + { + var g = this, p = this.options; + var data = {}; + data[p.root] = []; + if (!source || !source[p.root] || !source[p.root].length) + { + data[p.record] = 0; + return data; + } + data[p.record] = source[p.root].length; + if (!p.newPage) p.newPage = 1; + for (i = (p.newPage - 1) * p.pageSize; i < source[p.root].length && i < p.newPage * p.pageSize; i++) + { + data[p.root].push(source[p.root][i]); + } + return data; + }, + //比较某一列两个数据 + _compareData: function (data1, data2, columnName, columnType) + { + var g = this, p = this.options; + var val1 = data1[columnName], val2 = data2[columnName]; + if (val1 == null && val2 != null) return 1; + else if (val1 == null && val2 == null) return 0; + else if (val1 != null && val2 == null) return -1; + if (p.sorters[columnType]) + return p.sorters[columnType].call(g, val1, val2); + else + return val1 < val2 ? -1 : val1 > val2 ? 1 : 0; + }, + _getTotalInfo : function(column, data) + { + var g = this, p = this.options; + try{ + var totalsummaryArr = []; + if (!column.totalSummary) return null; + var sum = 0, count = 0, avg = 0, min = 0, max = 0; + if (data && data.length) + { + max = parseFloat(data[0][column.name]); + min = parseFloat(data[0][column.name]); + for (var i = 0; i < data.length; i++) + { + if (data[i][p.statusName] == 'delete') continue; + count += 1; + var value = data[i][column.name]; + if (typeof (value) == "string") value = value.replace(/\$|\,/g, ''); + value = parseFloat(value); + if (!value) continue; + sum += value; + if (value > max) max = value; + if (value < min) min = value; + } + avg = sum * 1.0 / data.length; + } + return { + sum: sum, + count: count, + avg: avg, + min: min, + max: max + }; + } catch (e) + { + return {}; + } + }, + _getTotalCellContent: function (column, data) + { + var g = this, p = this.options; + var totalsummaryArr = []; + if (column.totalSummary) + { + var isExist = function (type) + { + for (var i = 0; i < types.length; i++) + if (types[i].toLowerCase() == type.toLowerCase()) return true; + return false; + }; + var info = g._getTotalInfo(column, data); + if (column.totalSummary.render) + { + var renderhtml = column.totalSummary.render(info, column, g.data); + totalsummaryArr.push(renderhtml); + } + else if (column.totalSummary.type && info) + { + var types = column.totalSummary.type.split(','); + if (isExist('sum')) + totalsummaryArr.push("<div>Sum=" + info.sum.toFixed(2) + "</div>"); + if (isExist('tsum')) + totalsummaryArr.push("<div>" + sum.toFixed(0) + "</div>"); + if (isExist('count')) + totalsummaryArr.push("<div>Count=" + info.count + "</div>"); + if (isExist('max')) + totalsummaryArr.push("<div>Max=" + info.max.toFixed(2) + "</div>"); + if (isExist('min')) + totalsummaryArr.push("<div>Min=" + info.min.toFixed(2) + "</div>"); + if (isExist('avg')) + totalsummaryArr.push("<div>Avg=" + info.avg.toFixed(2) + "</div>"); + } + } + return totalsummaryArr.join(''); + }, + _getTotalSummaryHtml: function (data, classCssName, frozen) + { + var g = this, p = this.options; + var totalsummaryArr = []; + if (classCssName) + totalsummaryArr.push('<tr class="l-grid-totalsummary ' + classCssName + '">'); + else + totalsummaryArr.push('<tr class="l-grid-totalsummary">'); + $(g.columns).each(function (columnindex, column) + { + if (this.frozen != frozen) return; + //如果是行序号(系统列) + if (this.isrownumber) + { + totalsummaryArr.push('<td class="l-grid-totalsummary-cell l-grid-totalsummary-cell-rownumbers" style="width:' + this.width + 'px"><div>&nbsp;</div></td>'); + return; + } + //如果是复选框(系统列) + if (this.ischeckbox) + { + totalsummaryArr.push('<td class="l-grid-totalsummary-cell l-grid-totalsummary-cell-checkbox" style="width:' + this.width + 'px"><div>&nbsp;</div></td>'); + return; + } + //如果是明细列(系统列) + else if (this.isdetail) + { + totalsummaryArr.push('<td class="l-grid-totalsummary-cell l-grid-totalsummary-cell-detail" style="width:' + this.width + 'px"><div>&nbsp;</div></td>'); + return; + } + totalsummaryArr.push('<td class="l-grid-totalsummary-cell'); + if (this.islast) + totalsummaryArr.push(" l-grid-totalsummary-cell-last"); + totalsummaryArr.push('" '); + totalsummaryArr.push('id="' + g.id + "|total" + g.totalNumber + "|" + column.__id + '" '); + totalsummaryArr.push('width="' + this._width + '" '); + columnname = this.columnname; + if (columnname) + { + totalsummaryArr.push('columnname="' + columnname + '" '); + } + totalsummaryArr.push('columnindex="' + columnindex + '" '); + totalsummaryArr.push('><div class="l-grid-totalsummary-cell-inner"'); + if (column.align) + totalsummaryArr.push(' style="text-Align:' + column.align + ';"'); + totalsummaryArr.push('>'); + totalsummaryArr.push(g._getTotalCellContent(column, data)); + totalsummaryArr.push('</div></td>'); + }); + totalsummaryArr.push('</tr>'); + if (!frozen) g.totalNumber++; + return totalsummaryArr.join(''); + }, + _bulidTotalSummary: function (frozen) + { + var g = this, p = this.options; + if (!g.isTotalSummary()) return false; + if (!g.currentData || g.currentData[p.root].length == 0) return false; + var totalRow = $(g._getTotalSummaryHtml(g.currentData[p.root], null, frozen)); + $("tbody:first", frozen ? g.f.gridbody : g.gridbody).append(totalRow); + if (frozen) g.totalRow1 = totalRow; + else g.totalRow2 = totalRow; + }, + updateTotalSummary: function () + { + var g = this, p = this.options; + g.reRender({ totalOnly: true }); + }, + _buildPager: function () + { + var g = this, p = this.options; + if (p.pagerRender) + { + return; + } + $('.pcontrol input', g.toolbar).val(p.page); + if (!p.pageCount) p.pageCount = 1; + $('.pcontrol span', g.toolbar).html(p.pageCount); + var r1 = parseInt((p.page - 1) * p.pageSize) + 1.0; + var r2 = parseInt(r1) + parseInt(p.pageSize) - 1; + if (!p.total) p.total = 0; + if (p.total < r2) r2 = p.total; + if (!p.total) r1 = r2 = 0; + if (r1 < 0) r1 = 0; + if (r2 < 0) r2 = 0; + var stat = p.pageStatMessage; + stat = stat.replace(/{from}/, r1); + stat = stat.replace(/{to}/, r2); + stat = stat.replace(/{total}/, p.total); + stat = stat.replace(/{pagesize}/, p.pageSize); + $('.l-bar-text', g.toolbar).html(stat); + if (!p.total) + { + $(".l-bar-btnfirst span,.l-bar-btnprev span,.l-bar-btnnext span,.l-bar-btnlast span", g.toolbar) + .addClass("l-disabled"); + } + if (p.hideLoadButton) + { + $('.l-bar-btnload:first', g.toolbar).parent().hide(); + $('.l-bar-btnload:first', g.toolbar).parent().next().hide(); + } + if (p.page == 1) + { + $(".l-bar-btnfirst span", g.toolbar).addClass("l-disabled"); + $(".l-bar-btnprev span", g.toolbar).addClass("l-disabled"); + } + else if (p.page > p.pageCount && p.pageCount > 0) + { + $(".l-bar-btnfirst span", g.toolbar).removeClass("l-disabled"); + $(".l-bar-btnprev span", g.toolbar).removeClass("l-disabled"); + } + if (p.page == p.pageCount) + { + $(".l-bar-btnlast span", g.toolbar).addClass("l-disabled"); + $(".l-bar-btnnext span", g.toolbar).addClass("l-disabled"); + } + else if (p.page < p.pageCount && p.pageCount > 0) + { + $(".l-bar-btnlast span", g.toolbar).removeClass("l-disabled"); + $(".l-bar-btnnext span", g.toolbar).removeClass("l-disabled"); + } + }, + _getRowIdByDomId: function (domid) + { + var ids = domid.split('|'); + var rowid = ids[2]; + return rowid; + }, + _getRowByDomId: function (domid) + { + return this.records[this._getRowIdByDomId(domid)]; + }, + //在外部点击的时候,判断是否在编辑状态,比如弹出的层点击的,如果自定义了编辑器,而且生成的层没有包括在grid内部,建议重载 + _isEditing: function (jobjs) + { + var g = this; + if (jobjs.hasClass("l-box-dateeditor") || jobjs.hasClass("l-box-select")) return true; + + //判断是否位于编辑器弹出的框 + if (jobjs.hasClass("l-dialog")) + { + var ids = []; + jobjs.find(".l-dialog").each(function () + { + var curId = $(this).attr("ligeruiid"); + if (curId) + { + ids.push(curId); + } + }); + if (g._editorIncludeCotrols(ids)) + { + return true; + } + } + return false; + + }, + _getSrcElementByEvent: function (e) + { + var g = this; + var obj = (e.target || e.srcElement); + var jobjs = $(obj).parents().add(obj); + var fn = function (parm) + { + for (var i = 0, l = jobjs.length; i < l; i++) + { + if (typeof parm == "string") + { + if ($(jobjs[i]).hasClass(parm)) return jobjs[i]; + } + else if (typeof parm == "object") + { + if (jobjs[i] == parm) return jobjs[i]; + } + } + return null; + }; + if (fn("l-grid-editor")) return { editing: true, editor: fn("l-grid-editor") }; + if (jobjs.index(this.element) == -1) + { + if (g._isEditing(jobjs)) return { editing: true }; + else return { out: true }; + } + var indetail = false; + if (jobjs.hasClass("l-grid-detailpanel") && g.detailrows) + { + for (var i = 0, l = g.detailrows.length; i < l; i++) + { + if (jobjs.index(g.detailrows[i]) != -1) + { + indetail = true; + break; + } + } + } + var r = { + grid: fn("l-panel"), + indetail: indetail, + frozen: fn(g.gridview1[0]) ? true : false, + header: fn("l-panel-header"), //标题 + gridheader: fn("l-grid-header"), //表格头 + gridbody: fn("l-grid-body"), + total: fn("l-panel-bar-total"), //总汇总 + popup: fn("l-grid-popup"), + toolbar: fn("l-panel-bar") + }; + if (r.gridheader) + { + r.hrow = fn("l-grid-hd-row"); + r.hcell = fn("l-grid-hd-cell"); + r.hcelltext = fn("l-grid-hd-cell-text"); + r.checkboxall = fn("l-grid-hd-cell-checkbox"); + if (r.hcell) + { + var columnid = r.hcell.id.split('|')[2]; + r.column = g._columns[columnid]; + } + } + if (r.gridbody) + { + r.row = fn("l-grid-row"); + r.cell = fn("l-grid-row-cell"); + r.checkbox = fn("l-grid-row-cell-btn-checkbox"); + r.groupbtn = fn("l-grid-group-togglebtn"); + r.grouprow = fn("l-grid-grouprow"); + r.detailbtn = fn("l-grid-row-cell-detailbtn"); + r.detailrow = fn("l-grid-detailpanel"); + r.totalrow = fn("l-grid-totalsummary"); + r.totalcell = fn("l-grid-totalsummary-cell"); + r.rownumberscell = $(r.cell).hasClass("l-grid-row-cell-rownumbers") ? r.cell : null; + r.detailcell = $(r.cell).hasClass("l-grid-row-cell-detail") ? r.cell : null; + r.checkboxcell = $(r.cell).hasClass("l-grid-row-cell-checkbox") ? r.cell : null; + r.treelink = fn("l-grid-tree-link"); + r.editor = fn("l-grid-editor"); + + + if (r.row) r.data = this._getRowByDomId(r.row.id); + if (r.cell) r.editing = $(r.cell).hasClass("l-grid-row-cell-editing"); + if (r.editor) r.editing = true; + if (r.editing) r.out = false; + } + if (r.toolbar) + { + r.first = fn("l-bar-btnfirst"); + r.last = fn("l-bar-btnlast"); + r.next = fn("l-bar-btnnext"); + r.prev = fn("l-bar-btnprev"); + r.load = fn("l-bar-btnload"); + r.button = fn("l-bar-button"); + } + + return r; + }, + + _editorIncludeCotrols : function(ids){ + var g = this, p = this.options; + if (!ids || !ids.length) return false; + if (g.editor && g.editor.input) + { + if (g._controlIncludeCotrols(g.editor.input, ids)) return true; + } + else if (g.editors) + { + for (var a in g.editors) + { + if(!g.editors[a]) continue; + for (var b in g.editors[a]) + { + var editor = g.editors[a][b]; + if (editor && editor.input) + { + if (g._controlIncludeCotrols(editor.input, ids)) return true; + } + } + } + } + return false; + }, + + _controlIncludeCotrols: function (control,ids) + { + var g = this, p = this.options; + if (!control || !control.includeControls || !control.includeControls.length) return false; + + for(var i = 0;i< control.includeControls.length;i++){ + var sub = control.includeControls[i]; + if ($.inArray(sub.id, ids) != -1) return true; + } + return false; + }, + + _getOnePageHeight : function() + { + var g = this, p = this.options; + return (parseFloat(p.rowHeight || 24) + 1)*parseInt(p.pageSize); + }, + + _setEvent: function () + { + var g = this, p = this.options; + g.grid.bind("mousedown.grid", function (e) + { + g._onMouseDown.call(g, e); + }); + g.grid.bind("dblclick.grid", function (e) + { + g._onDblClick.call(g, e); + }); + g.grid.bind("contextmenu.grid", function (e) + { + return g._onContextmenu.call(g, e); + }); + $(document).bind("mouseup.grid", function (e) + { + g._onMouseUp.call(g, e); + }); + $(document).bind("click.grid", function (e) + { + g._onClick.call(g, e); + }); + $(window).bind("resize.grid", function (e) + { + g._onResize.call(g); + }); + $(document).bind("keydown.grid", function (e) + { + if (e.ctrlKey) g.ctrlKey = true; + }); + $(document).bind("keyup.grid", function (e) + { + delete g.ctrlKey; + }); + //表体 - 滚动联动事件 + g.gridbody.bind('scroll.grid', function () + { + var scrollLeft = g.gridbody.scrollLeft(); + var scrollTop = g.gridbody.scrollTop(); + if (scrollLeft != null) + g.gridheader[0].scrollLeft = scrollLeft; + if (scrollTop != null) + g.f.gridbody[0].scrollTop = scrollTop; + + if (p.scrollToPage && p.usePager && !g.loading) + { + var innerHeight = g.gridbody.find(".l-grid-body-inner:first").height(); + var toHeight = scrollTop + g.gridbody.height(); + if (p.scrollToAppend) + { + if (p.newPage != p.pageCount) + { + if (toHeight >= innerHeight) + { + g.reload(p.newPage + 1, "scrollappend"); + } + } + } else + { + var topage = toHeight >= innerHeight ? p.pageCount : Math.ceil(toHeight / g._getOnePageHeight()); + if (!g.scrollLoading) + { + g.scrollLoading = true; + g.lastScrollTop = scrollTop; + g.unbind("sysScrollLoaded"); + g.bind("sysScrollLoaded", function () + { + g.gridbody.scrollTop(scrollTop); + setTimeout(function () + { + g.scrollLoading = false; + }, 500); + }); + g.scrollLoading = true; + + g.reload(topage, "scroll"); + + } + } + } + g.trigger('SysGridHeightChanged'); + }); + //工具条 - 切换每页记录数事件 + $('select', g.toolbar).change(function () + { + if (g.isDataChanged && p.dataAction != "local" && !confirm(p.isContinueByDataChanged)) + return false; + p.newPage = 1; + p.pageSize = this.value; + g.loadData(p.dataAction != "local" ? p.where : false); + }); + //工具条 - 切换当前页事件 + $('span.pcontrol :text', g.toolbar).blur(function (e) + { + g.changePage('input'); + }); + $("div.l-bar-button", g.toolbar).hover(function () + { + $(this).addClass("l-bar-button-over"); + }, function () + { + $(this).removeClass("l-bar-button-over"); + }); + //列拖拽支持 + if ($.fn.ligerDrag && p.colDraggable) + { + g.colDroptip = $("<div class='l-drag-coldroptip' style='display:none'><div class='l-drop-move-up'></div><div class='l-drop-move-down'></div></div>").appendTo('body'); + g.gridheader.add(g.f.gridheader).ligerDrag({ + revert: true, animate: false, + proxyX: 0, proxyY: 0, + proxy: function (draggable, e) + { + var src = g._getSrcElementByEvent(e); + if (src.hcell && src.column) + { + var content = $(".l-grid-hd-cell-text:first", src.hcell).html(); + var proxy = $("<div class='l-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div></div>").appendTo('body'); + proxy.append(content); + return proxy; + } + }, + onRevert: function () { return false; }, + onRendered: function () + { + this.set('cursor', 'default'); + g.children[this.id] = this; + }, + onStartDrag: function (current, e) + { + if (e.button == 2) return false; + if (g.colresizing) return false; + this.set('cursor', 'default'); + var src = g._getSrcElementByEvent(e); + if (!src.hcell || !src.column || src.column.issystem || src.hcelltext) return false; + if ($(src.hcell).css('cursor').indexOf('resize') != -1) return false; + this.draggingColumn = src.column; + g.coldragging = true; + + var gridOffset = g.grid.offset(); + this.validRange = { + top: gridOffset.top, + bottom: gridOffset.top + g.gridheader.height(), + left: gridOffset.left - 10, + right: gridOffset.left + g.grid.width() + 10 + }; + }, + onDrag: function (current, e) + { + this.set('cursor', 'default'); + var column = this.draggingColumn; + if (!column) return false; + if (g.colresizing) return false; + if (g.colDropIn == null) + g.colDropIn = -1; + var pageX = e.pageX; + var pageY = e.pageY; + var visit = false; + var gridOffset = g.grid.offset(); + var validRange = this.validRange; + if (pageX < validRange.left || pageX > validRange.right + || pageY > validRange.bottom || pageY < validRange.top) + { + g.colDropIn = -1; + g.colDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes").addClass("l-drop-no"); + return; + } + for (var colid in g._columns) + { + var col = g._columns[colid]; + if (column == col) + { + visit = true; + continue; + } + if (col.issystem) continue; + var sameLevel = col['__level'] == column['__level']; + var isAfter = !sameLevel ? false : visit ? true : false; + if (column.frozen != col.frozen) isAfter = col.frozen ? false : true; + if (g.colDropIn != -1 && g.colDropIn != colid) continue; + var cell = document.getElementById(col['__domid']); + var offset = $(cell).offset(); + var range = { + top: offset.top, + bottom: offset.top + $(cell).height(), + left: offset.left - 10, + right: offset.left + 10 + }; + if (isAfter) + { + var cellwidth = $(cell).width(); + range.left += cellwidth; + range.right += cellwidth; + } + if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom) + { + var height = p.headerRowHeight; + if (col['__rowSpan']) height *= col['__rowSpan']; + g.colDroptip.css({ + left: range.left + 5, + top: range.top - 9, + height: height + 9 * 2 + }).show(); + g.colDropIn = colid; + g.colDropDir = isAfter ? "right" : "left"; + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no").addClass("l-drop-yes"); + break; + } + else if (g.colDropIn != -1) + { + g.colDropIn = -1; + g.colDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes").addClass("l-drop-no"); + } + } + }, + onStopDrag: function (current, e) + { + var column = this.draggingColumn; + g.coldragging = false; + if (g.colDropIn != -1) + { + g.changeCol.ligerDefer(g, 0, [column, g.colDropIn, g.colDropDir == "right"]); + g.colDropIn = -1; + } + g.colDroptip.hide(); + this.set('cursor', 'default'); + } + }); + } + //行拖拽支持 + if ($.fn.ligerDrag && p.rowDraggable) + { + g.rowDroptip = $("<div class='l-drag-rowdroptip' style='display:none'></div>").appendTo('body'); + g.gridbody.add(g.f.gridbody).ligerDrag({ + revert: true, animate: false, + proxyX: 0, proxyY: 0, + proxy: function (draggable, e) + { + var src = g._getSrcElementByEvent(e); + if (src.row) + { + var content = p.draggingMessage.replace(/{count}/, draggable.draggingRows ? draggable.draggingRows.length : 1); + if (p.rowDraggingRender) + { + content = p.rowDraggingRender(draggable.draggingRows, draggable, g); + } + var proxy = $("<div class='l-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div>" + content + "</div>").appendTo('body'); + return proxy; + } + }, + onRevert: function () { return false; }, + onRendered: function () + { + this.set('cursor', 'default'); + g.children[this.id] = this; + }, + onStartDrag: function (current, e) + { + if (e.button == 2) return false; + if (g.colresizing) return false; + if (!g.columns.length) return false; + this.set('cursor', 'default'); + var src = g._getSrcElementByEvent(e); + if (!src.cell || !src.data || src.checkbox) return false; + var ids = src.cell.id.split('|'); + var column = g._columns[ids[ids.length - 1]]; + if (src.rownumberscell || src.detailcell || src.checkboxcell || column == g.columns[0]) + { + if (g.enabledCheckbox()) + { + this.draggingRows = g.getSelecteds(); + if (!this.draggingRows || !this.draggingRows.length) return false; + } + else + { + this.draggingRows = [src.data]; + } + this.draggingRow = src.data; + this.set('cursor', 'move'); + g.rowdragging = true; + this.validRange = { + top: g.gridbody.offset().top, + bottom: g.gridbody.offset().top + g.gridbody.height(), + left: g.grid.offset().left - 10, + right: g.grid.offset().left + g.grid.width() + 10 + }; + } + else + { + return false; + } + }, + onDrag: function (current, e) + { + var rowdata = this.draggingRow; + if (!rowdata) return false; + var rows = this.draggingRows ? this.draggingRows : [rowdata]; + if (g.colresizing) return false; + if (g.rowDropIn == null) g.rowDropIn = -1; + var pageX = e.pageX; + var pageY = e.pageY; + var visit = false; + var validRange = this.validRange; + if (pageX < validRange.left || pageX > validRange.right + || pageY > validRange.bottom || pageY < validRange.top) + { + g.rowDropIn = -1; + g.rowDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no"); + return; + } + for (var i in g.rows) + { + var rd = g.rows[i]; + var rowid = rd['__id']; + if (rowdata == rd) visit = true; + if ($.inArray(rd, rows) != -1) continue; + var isAfter = visit ? true : false; + if (g.rowDropIn != -1 && g.rowDropIn != rowid) continue; + var rowobj = g.getRowObj(rowid); + var offset = $(rowobj).offset(); + var range = { + top: offset.top - 4, + bottom: offset.top + $(rowobj).height() + 4, + left: g.grid.offset().left, + right: g.grid.offset().left + g.grid.width() + }; + if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom) + { + var lineTop = offset.top; + if (isAfter) lineTop += $(rowobj).height(); + g.rowDroptip.css({ + left: range.left, + top: lineTop, + width: range.right - range.left + }).show(); + g.rowDropIn = rowid; + g.rowDropDir = isAfter ? "bottom" : "top"; + if (p.tree && pageY > range.top + 5 && pageY < range.bottom - 5) + { + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-yes").addClass("l-drop-add"); + g.rowDroptip.hide(); + g.rowDropInParent = true; + } + else + { + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-add").addClass("l-drop-yes"); + g.rowDroptip.show(); + g.rowDropInParent = false; + } + break; + } + else if (g.rowDropIn != -1) + { + g.rowDropIn = -1; + g.rowDropInParent = false; + g.rowDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no"); + } + } + }, + onStopDrag: function (current, e) + { + var rows = this.draggingRows; + g.rowdragging = false; + for (var i = 0; i < rows.length; i++) + { + var children = rows[i].children; + if (children) + { + rows = $.grep(rows, function (node, i) + { + var isIn = $.inArray(node, children) == -1; + return isIn; + }); + } + } + if (g.rowDropIn != -1) + { + if (p.tree) + { + var neardata, prow; + if (g.rowDropInParent) + { + prow = g.getRow(g.rowDropIn); + } + else + { + neardata = g.getRow(g.rowDropIn); + prow = g.getParent(neardata); + } + g.appendRange(rows, prow, neardata, g.rowDropDir != "bottom"); + g.trigger('rowDragDrop', { + rows: rows, + parent: prow, + near: neardata, + after: g.rowDropDir == "bottom" + }); + } + else + { + g.moveRange(rows, g.rowDropIn, g.rowDropDir == "bottom"); + g.trigger('rowDragDrop', { + rows: rows, + parent: prow, + near: g.getRow(g.rowDropIn), + after: g.rowDropDir == "bottom" + }); + } + + g.rowDropIn = -1; + } + g.rowDroptip.hide(); + this.set('cursor', 'default'); + } + }); + } + }, + _onRowOver: function (rowParm, over) + { + if (l.draggable.dragging) return; + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var methodName = over ? "addClass" : "removeClass"; + if (over && g.editor.editing) + { + $("tr." + p.mouseoverRowCssClass, g.gridview).removeClass(p.mouseoverRowCssClass); + } + if (g.enabledFrozen()) + $(g.getRowObj(rowdata, true))[methodName](p.mouseoverRowCssClass); + $(g.getRowObj(rowdata, false))[methodName](p.mouseoverRowCssClass); + }, + _onMouseUp: function (e) + { + var g = this, p = this.options; + if (l.draggable.dragging) + { + var src = g._getSrcElementByEvent(e); + + //drop in header cell + if (src.hcell && src.column) + { + g.trigger('dragdrop', [{ type: 'header', column: src.column, cell: src.hcell }, e]); + } + else if (src.row) + { + g.trigger('dragdrop', [{ type: 'row', record: src.data, row: src.row }, e]); + } + } + }, + _onMouseDown: function (e) + { + var g = this, p = this.options; + }, + _onContextmenu: function (e) + { + var g = this, p = this.options; + var src = g._getSrcElementByEvent(e); + if (src.row) + { + if (p.whenRClickToSelect) + g.select(src.data); + if (g.hasBind('contextmenu')) + { + return g.trigger('contextmenu', [{ data: src.data, rowindex: src.data['__index'], row: src.row }, e]); + } + } + else if (src.hcell) + { + if (!p.allowHideColumn) return true; + var columnindex = $(src.hcell).attr("columnindex"); + if (columnindex == undefined) return true; + var left = (e.pageX - g.body.offset().left + parseInt(g.body[0].scrollLeft)); + if (columnindex == g.columns.length - 1) left -= 50; + g.popup.css({ left: left, top: g.gridheader.height() + 1 }); + g.popup.toggle(); + return false; + } + }, + _onDblClick: function (e) + { + var g = this, p = this.options; + var src = g._getSrcElementByEvent(e); + if (src.row) + { + g.trigger('dblClickRow', [src.data, src.data['__id'], src.row]); + } + }, + _onClick: function (e) + { + var obj = (e.target || e.srcElement); + var g = this, p = this.options; + var src = g._getSrcElementByEvent(e); + if (src.out) + { + if (g.editor.editing && !$.ligerui.win.masking) g.endEdit(); + if (p.allowHideColumn) g.popup.hide(); + return; + } + if (src.indetail || src.editing) + { + return; + } + if (g.editor.editing) + { + g.endEdit(); + } + if (p.allowHideColumn) + { + if (!src.popup) + { + g.popup.hide(); + } + } + if (src.checkboxall) //复选框全选 + { + var row = $(src.hrow); + var uncheck = row.hasClass("l-checked"); + if (g.trigger('beforeCheckAllRow', [!uncheck, g.element]) == false) return false; + if (uncheck) + { + row.removeClass("l-checked"); + } + else + { + row.addClass("l-checked"); + } + g.selected = []; + for (var rowid in g.records) + { + if (uncheck) + g.unselect(g.records[rowid]); + else + g.select(g.records[rowid]); + } + g.trigger('checkAllRow', [!uncheck, g.element]); + } + else if (src.hcelltext) //排序 + { + var hcell = $(src.hcelltext).parent().parent(); + if (!p.enabledSort || !src.column) return; + if (src.column.isSort == false) return; + if (p.url && p.dataAction != "local" && g.isDataChanged && !confirm(p.isContinueByDataChanged)) return; + var sort = $(".l-grid-hd-cell-sort:first", hcell); + var columnName = src.column.name; + if (!columnName) return; + if (sort.length > 0) + { + if (sort.hasClass("l-grid-hd-cell-sort-asc")) + { + sort.removeClass("l-grid-hd-cell-sort-asc").addClass("l-grid-hd-cell-sort-desc"); + hcell.removeClass("l-grid-hd-cell-asc").addClass("l-grid-hd-cell-desc"); + g.trigger('ChangeSort', [columnName, 'desc']); + g.changeSort(columnName, 'desc'); + } + else if (sort.hasClass("l-grid-hd-cell-sort-desc")) + { + sort.removeClass("l-grid-hd-cell-sort-desc").addClass("l-grid-hd-cell-sort-asc"); + hcell.removeClass("l-grid-hd-cell-desc").addClass("l-grid-hd-cell-asc"); + g.trigger('ChangeSort', [columnName, 'asc']); + g.changeSort(columnName, 'asc'); + } + } + else + { + hcell.removeClass("l-grid-hd-cell-desc").addClass("l-grid-hd-cell-asc"); + $(src.hcelltext).after("<span class='l-grid-hd-cell-sort l-grid-hd-cell-sort-asc'>&nbsp;&nbsp;</span>"); + g.trigger('ChangeSort', [columnName, 'asc']); + g.changeSort(columnName, 'asc'); + } + $(".l-grid-hd-cell-sort", g.gridheader).add($(".l-grid-hd-cell-sort", g.f.gridheader)).not($(".l-grid-hd-cell-sort:first", hcell)).remove(); + } + //明细 + else if (src.detailbtn && p.detail) + { + var item = src.data; + var row = $([g.getRowObj(item, false)]); + if (g.enabledFrozen()) row = row.add(g.getRowObj(item, true)); + var rowid = item['__id']; + if ($(src.detailbtn).hasClass("l-open")) + { + if (p.detail.onCollapse) + p.detail.onCollapse(item, $(".l-grid-detailpanel-inner:first", nextrow)[0]); + row.next("tr.l-grid-detailpanel").hide(); + $(src.detailbtn).removeClass("l-open"); + } + else + { + var nextrow = row.next("tr.l-grid-detailpanel"); + if (nextrow.length > 0) + { + nextrow.show(); + if (p.detail.onExtend) + p.detail.onExtend(item, $(".l-grid-detailpanel-inner:first", nextrow)[0]); + $(src.detailbtn).addClass("l-open"); + g.trigger('SysGridHeightChanged'); + return; + } + $(src.detailbtn).addClass("l-open"); + var frozenColNum = 0; + for (var i = 0; i < g.columns.length; i++) + if (g.columns[i].frozen) frozenColNum++; + var detailRow = $("<tr class='l-grid-detailpanel'><td><div class='l-grid-detailpanel-inner' style='display:none'></div></td></tr>"); + var detailFrozenRow = $("<tr class='l-grid-detailpanel'><td><div class='l-grid-detailpanel-inner' style='display:none'></div></td></tr>"); + detailRow.find("div:first").width(g.gridheader.find("div:first").width() - 50); + detailRow.attr("id", g.id + "|detail|" + rowid); + g.detailrows = g.detailrows || []; + g.detailrows.push(detailRow[0]); + g.detailrows.push(detailFrozenRow[0]); + var detailRowInner = $("div:first", detailRow); + detailRowInner.parent().attr("colSpan", g.columns.length - frozenColNum); + row.eq(0).after(detailRow); + if (frozenColNum > 0) + { + detailFrozenRow.find("td:first").attr("colSpan", frozenColNum); + row.eq(1).after(detailFrozenRow); + } + if (p.detail.onShowDetail) + { + p.detail.onShowDetail(item, detailRowInner[0], function () + { + g.trigger('SysGridHeightChanged'); + }); + $("div:first", detailFrozenRow).add(detailRowInner).show().height(p.detail.height || p.detailHeight); + } + else if (p.detail.render) + { + detailRowInner.append(p.detail.render()); + detailRowInner.show(); + } + g.trigger('SysGridHeightChanged'); + } + } + else if (src.groupbtn) + { + var grouprow = $(src.grouprow); + var opening = true; + if ($(src.groupbtn).hasClass("l-grid-group-togglebtn-close")) + { + $(src.groupbtn).removeClass("l-grid-group-togglebtn-close"); + + if (grouprow.hasClass("l-grid-grouprow-last")) + { + $("td:first", grouprow).width('auto'); + } + } + else + { + opening = false; + $(src.groupbtn).addClass("l-grid-group-togglebtn-close"); + if (grouprow.hasClass("l-grid-grouprow-last")) + { + $("td:first", grouprow).width(g.gridtablewidth); + } + } + var currentRow = grouprow.next(".l-grid-row,.l-grid-totalsummary-group,.l-grid-detailpanel"); + while (true) + { + if (currentRow.length == 0) break; + if (opening) + { + currentRow.show(); + //如果是明细展开的行,并且之前的状态已经是关闭的,隐藏之 + if (currentRow.hasClass("l-grid-detailpanel") && !currentRow.prev().find("td.l-grid-row-cell-detail:first span.l-grid-row-cell-detailbtn:first").hasClass("l-open")) + { + currentRow.hide(); + } + } + else + { + currentRow.hide(); + } + currentRow = currentRow.next(".l-grid-row,.l-grid-totalsummary-group,.l-grid-detailpanel"); + } + g.trigger(opening ? 'groupExtend' : 'groupCollapse'); + g.trigger('SysGridHeightChanged'); + } + //树 - 伸展/收缩节点 + else if (src.treelink) + { + g.toggle(src.data); + } + else if (src.row && g.enabledCheckbox()) //复选框选择行 + { + //复选框 + var selectRowButtonOnly = p.selectRowButtonOnly ? true : false; + if (p.enabledEdit) selectRowButtonOnly = true; + if (obj.tagName.toLowerCase() == "a") return; + if ((src.checkbox || !selectRowButtonOnly) && p.selectable != false) + { + var row = $(src.row); + var uncheck = row.hasClass("l-selected"); + if (g.trigger('beforeCheckRow', [!uncheck, src.data, src.data['__id'], src.row]) == false) + return false; + var met = uncheck ? 'unselect' : 'select'; + g[met](src.data); + if (p.tree && p.autoCheckChildren) + { + var children = g.getChildren(src.data, true); + for (var i = 0, l = children.length; i < l; i++) + { + g[met](children[i]); + } + } + g.trigger('checkRow', [!uncheck, src.data, src.data['__id'], src.row]); + } + if (!src.checkbox && src.cell && p.enabledEdit && p.clickToEdit) + { + g._applyEditor(src.cell); + } + } + else if (src.row && !g.enabledCheckbox() && p.selectable != false) + { + if (src.cell && p.enabledEdit && p.clickToEdit) + { + g._applyEditor(src.cell); + } + + //选择行 + if ($(src.row).hasClass("l-selected")) + { + if (!p.allowUnSelectRow) + { + $(src.row).addClass("l-selected-again"); + return; + } + g.unselect(src.data); + } + else + { + g.select(src.data); + } + } + else if (src.toolbar) + { + if (src.first) + { + if (g.trigger('toFirst', [g.element]) == false) return false; + g.changePage('first'); + } + else if (src.prev) + { + if (g.trigger('toPrev', [g.element]) == false) return false; + g.changePage('prev'); + } + else if (src.next) + { + if (g.trigger('toNext', [g.element]) == false) return false; + g.changePage('next'); + } + else if (src.last) + { + if (g.trigger('toLast', [g.element]) == false) return false; + g.changePage('last'); + } + else if (src.load) + { + if ($("span", src.load).hasClass("l-disabled")) return false; + if (g.trigger('reload', [g.element]) == false) return false; + if (p.url && g.isDataChanged && !confirm(p.isContinueByDataChanged)) + return false; + g.loadData(p.where); + } + } + }, + select: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var rowid = rowdata['__id']; + var rowobj = g.getRowObj(rowid); + if (!p.rowSelectable || g.trigger('beforeSelectRow', [rowdata, rowid, rowobj]) == false) return; + var rowobj1 = g.getRowObj(rowid, true); + if ((!g.enabledCheckbox() && !g.ctrlKey) || p.isSingleCheck) //单选 + { + for (var i in g.selected) + { + var o = g.selected[i]; + if (o['__id'] in g.records) + { + $(g.getRowObj(o)).removeClass("l-selected l-selected-again"); + if (g.enabledFrozen()) + $(g.getRowObj(o, true)).removeClass("l-selected l-selected-again"); + } + } + g.selected = []; + } + if (rowobj) $(rowobj).addClass("l-selected"); + if (rowobj1) $(rowobj1).addClass("l-selected"); + g.selected[g.selected.length] = rowdata; + g.trigger('selectRow', [rowdata, rowid, rowobj]); + }, + unselect: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + var rowid = rowdata['__id']; + var rowobj = g.getRowObj(rowid); + var rowobj1 = g.getRowObj(rowid, true); + $(rowobj).removeClass("l-selected l-selected-again"); + if (g.enabledFrozen()) + $(rowobj1).removeClass("l-selected l-selected-again"); + g._removeSelected(rowdata); + g.trigger('unSelectRow', [rowdata, rowid, rowobj]); + }, + isSelected: function (rowParm) + { + var g = this, p = this.options; + var rowdata = g.getRow(rowParm); + for (var i in g.selected) + { + if (g.selected[i] == rowdata) return true; + } + return false; + }, + arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式 + { + var g = this, p = this.options; + var childrenName = "children"; + if (p.tree) childrenName = p.tree.childrenName; + if (!data || !data.length) return []; + var targetData = []; //存储数据的容器(返回) + var records = {}; + var itemLength = data.length; //数据集合的个数 + for (var i = 0; i < itemLength; i++) + { + var o = data[i]; + var key = getKey(o[id]); + records[key] = o; + } + for (var i = 0; i < itemLength; i++) + { + var currentData = data[i]; + var key = getKey(currentData[pid]); + var parentData = records[key]; + if (!parentData) + { + targetData.push(currentData); + continue; + } + parentData[childrenName] = parentData[childrenName] || []; + parentData[childrenName].push(currentData); + } + return targetData; + + function getKey(key) + { + if (typeof (key) == "string") key = key.replace(/[.]/g, '').toLowerCase(); + return key; + } + }, + _onResize: function () + { + var g = this, p = this.options; + if (p.height && p.height != 'auto') + { + var windowHeight = $(window).height(); + //if(g.windowHeight != undefined && g.windowHeight == windowHeight) return; + + var h = 0; + var parentHeight = null; + if (typeof (p.height) == "string" && p.height.indexOf('%') > 0) + { + var gridparent = g.grid.parent(); + if (p.inWindow) + { + parentHeight = windowHeight; + parentHeight -= parseInt($('body').css('paddingTop')); + parentHeight -= parseInt($('body').css('paddingBottom')); + } + else + { + parentHeight = gridparent.height(); + } + h = parentHeight * parseInt(p.height) * 0.01; + if (p.inWindow || gridparent[0].tagName.toLowerCase() == "body") + h -= (g.grid.offset().top - parseInt($('body').css('paddingTop'))); + } + else + { + h = parseInt(p.height); + } + + h += p.heightDiff; + g.windowHeight = windowHeight; + g._setHeight(h); + } + else + { + g._updateHorizontalScrollStatus.ligerDefer(g, 10); + } + if (g.enabledFrozen()) + { + var gridView1Width = g.gridview1.width(); + var gridViewWidth = g.gridview.width(); + if (gridViewWidth - gridView1Width <= 0) + { + g.gridview2.css({ + width: 'auto' + }); + } else + { + g.gridview2.css({ + width: gridViewWidth - gridView1Width + }); + } + } + + g.trigger('SysGridHeightChanged'); + }, + showFilter: function () + { + var g = this, p = this.options; + if (g.winfilter) + { + g.winfilter.show(); + return; + } + var filtercontainer = $('<div id="' + g.id + '_filtercontainer"></div>').width(380).height(120).hide(); + var filter = filtercontainer.ligerFilter({ fields: getFields() }); + filter.addRule($(filter.element.firstChild)); + return g.winfilter = $.ligerDialog.open({ + width: 420, height: 208, + target: filtercontainer, isResize: true, top: 50, + buttons: [ + { text: '确定', onclick: function (item, dialog) { loadData(); dialog.hide(); } }, + { text: '取消', onclick: function (item, dialog) { dialog.hide(); } } + ] + }); + + //将grid的columns转换为filter的fields + function getFields() + { + var fields = []; + //如果是多表头,那么g.columns为最低级的列 + $(g.columns).each(function () + { + var o = { name: this.name, display: this.display }; + var isNumber = this.type == "int" || this.type == "number" || this.type == "float"; + var isDate = this.type == "date"; + if (isNumber) o.type = "number"; + if (isDate) o.type = "date"; + if (this.editor) + { + o.editor = this.editor; + } + fields.push(o); + }); + return fields; + } + + function loadData() + { + var data = filter.getData(); + if (g.options.dataType == "server") + { + //服务器过滤数据 + loadServerData(data); + } + else + { + //本地过滤数据 + loadClientData(data); + } + } + + function loadServerData(data) + { + if (data && data.rules && data.rules.length) + { + g.setParm("where", JSON.stringify(data)); + } else + { + g.removeParm("where"); + } + g.loadData(); + } + function loadClientData(data) + { + g.loadData($.ligerFilter.getFilterFunction(data)); + } + } + }); + + $.ligerui.controls.Grid.prototype.enabledTotal = $.ligerui.controls.Grid.prototype.isTotalSummary; + $.ligerui.controls.Grid.prototype.add = $.ligerui.controls.Grid.prototype.addRow; + $.ligerui.controls.Grid.prototype.update = $.ligerui.controls.Grid.prototype.updateRow; + $.ligerui.controls.Grid.prototype.append = $.ligerui.controls.Grid.prototype.appendRow; + $.ligerui.controls.Grid.prototype.getSelected = $.ligerui.controls.Grid.prototype.getSelectedRow; + $.ligerui.controls.Grid.prototype.getSelecteds = $.ligerui.controls.Grid.prototype.getSelectedRows; + $.ligerui.controls.Grid.prototype.getCheckedRows = $.ligerui.controls.Grid.prototype.getSelectedRows; + $.ligerui.controls.Grid.prototype.getCheckedRowObjs = $.ligerui.controls.Grid.prototype.getSelectedRowObjs; + $.ligerui.controls.Grid.prototype.setOptions = $.ligerui.controls.Grid.prototype.set; + $.ligerui.controls.Grid.prototype.reload = $.ligerui.controls.Grid.prototype.loadData; + $.ligerui.controls.Grid.prototype.refreshSize = $.ligerui.controls.Grid.prototype._onResize; + $.ligerui.controls.Grid.prototype.append = $.ligerui.controls.Grid.prototype.appendRange; + + + + function removeArrItem(arr, filterFn) + { + for (var i = arr.length - 1; i >= 0; i--) + { + if (filterFn(arr[i])) + { + arr.splice(i, 1); + } + } + } +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerLayout = function (options) + { + return $.ligerui.run.call(this, "ligerLayout", arguments); + }; + + $.fn.ligerGetLayoutManager = function () + { + return $.ligerui.run.call(this, "ligerGetLayoutManager", arguments); + }; + + + $.ligerDefaults.Layout = { + topHeight: 50, + bottomHeight: 50, + leftWidth: 110, + centerWidth: 300, + rightWidth: 170, + centerBottomHeight: 100, + allowCenterBottomResize: true, + inWindow: true, //是否以窗口的高度为准 height设置为百分比时可用 + heightDiff: 0, //高度补差 + height: '100%', //高度 + onHeightChanged: null, + isLeftCollapse: false, //初始化时 左边是否隐藏 + isRightCollapse: false, //初始化时 右边是否隐藏 + allowLeftCollapse: true, //是否允许 左边可以隐藏 + allowRightCollapse: true, //是否允许 右边可以隐藏 + allowLeftResize: true, //是否允许 左边可以调整大小 + allowRightResize: true, //是否允许 右边可以调整大小 + allowTopResize: true, //是否允许 头部可以调整大小 + allowBottomResize: true, //是否允许 底部可以调整大小 + space: 3, //间隔 + onEndResize: null, //调整大小结束事件 + minLeftWidth: 80, //调整左侧宽度时的最小允许宽度 + minRightWidth: 80, //调整右侧宽度时的最小允许宽度 + onLeftToggle: null, //左边收缩/展开事件 + onRightToggle: null //右边收缩/展开事件 + }; + + $.ligerMethos.Layout = {}; + + $.ligerui.controls.Layout = function (element, options) + { + $.ligerui.controls.Layout.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Layout.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Layout'; + }, + __idPrev: function () + { + return 'Layout'; + }, + _extendMethods: function () + { + return $.ligerMethos.Layout; + }, + _init: function() + { + $.ligerui.controls.Layout.base._init.call(this); + + var g = this, p = this.options; + if (p.InWindow != null && p.inWindow == null) p.inWindow = p.InWindow; //旧版本命名错误纠正 + }, + _render: function () + { + var g = this, p = this.options; + g.layout = $(this.element); + g.layout.addClass("l-layout"); + g.width = g.layout.width(); + //top + if ($("> div[position=top]", g.layout).length > 0) + { + g.top = $("> div[position=top]", g.layout).wrap('<div class="l-layout-top" style="top:0px;"></div>').parent(); + g.top.content = $("> div[position=top]", g.top); + if (!g.top.content.hasClass("l-layout-content")) + g.top.content.addClass("l-layout-content"); + g.topHeight = p.topHeight; + if (g.topHeight) + { + g.top.height(g.topHeight); + } + } + //bottom + if ($("> div[position=bottom]", g.layout).length > 0) + { + g.bottom = $("> div[position=bottom]", g.layout).wrap('<div class="l-layout-bottom"></div>').parent(); + g.bottom.content = $("> div[position=bottom]", g.bottom); + if (!g.bottom.content.hasClass("l-layout-content")) + g.bottom.content.addClass("l-layout-content"); + + g.bottomHeight = p.bottomHeight; + if (g.bottomHeight) + { + g.bottom.height(g.bottomHeight); + } + //set title + var bottomtitle = g.bottom.content.attr("title"); + if (bottomtitle) + { + g.bottom.header = $('<div class="l-layout-header"></div>'); + g.bottom.prepend(g.bottom.header); + g.bottom.header.html(bottomtitle); + g.bottom.content.attr("title", ""); + } + } + //left + if ($("> div[position=left]", g.layout).length > 0) + { + g.left = $("> div[position=left]", g.layout).wrap('<div class="l-layout-left" style="left:0px;"></div>').parent(); + g.left.header = $('<div class="l-layout-header"><div class="l-layout-header-toggle"></div><div class="l-layout-header-inner"></div></div>'); + g.left.prepend(g.left.header); + g.left.header.toggle = $(".l-layout-header-toggle", g.left.header); + g.left.content = $("> div[position=left]", g.left); + if (!g.left.content.hasClass("l-layout-content")) + g.left.content.addClass("l-layout-content"); + if (!p.allowLeftCollapse) $(".l-layout-header-toggle", g.left.header).remove(); + //set title + var lefttitle = g.left.content.attr("title"); + if (lefttitle) + { + g.left.content.attr("title", ""); + $(".l-layout-header-inner", g.left.header).html(lefttitle); + } + //set title + if (g.left.content.attr("hidetitle")) + { + g.left.content.attr("title", ""); + g.left.header.remove(); + } + //set width + g.leftWidth = p.leftWidth; + if (g.leftWidth) + g.left.width(g.leftWidth); + } + //center + if ($("> div[position=center]", g.layout).length > 0) + { + g.center = $("> div[position=center]", g.layout).wrap('<div class="l-layout-center" ></div>').parent(); + g.center.content = $("> div[position=center]", g.center); + g.center.content.addClass("l-layout-content"); + //set title + var centertitle = g.center.content.attr("title"); + if (centertitle) + { + g.center.content.attr("title", ""); + g.center.header = $('<div class="l-layout-header"></div>'); + g.center.prepend(g.center.header); + g.center.header.html(centertitle); + } + if (g.center.content.attr("hidetitle")) + { + g.center.content.attr("title", ""); + g.center.header.remove(); + } + //set width + g.centerWidth = p.centerWidth; + if (g.centerWidth) + g.center.width(g.centerWidth); + + //centerBottom + if ($("> div[position=centerbottom]", g.layout).length > 0) + { + g.centerBottom = $("> div[position=centerbottom]", g.layout).wrap('<div class="l-layout-centerbottom" ></div>').parent(); + g.centerBottom.content = $("> div[position=centerbottom]", g.centerBottom); + g.centerBottom.content.addClass("l-layout-content"); + //set title + var centertitle = g.centerBottom.content.attr("title"); + if (centertitle) + { + g.centerBottom.content.attr("title", ""); + g.centerBottom.header = $('<div class="l-layout-header"></div>'); + g.centerBottom.prepend(g.centerBottom.header); + g.centerBottom.header.html(centertitle); + } + if (g.centerBottom.content.attr("hidetitle")) + { + g.centerBottom.content.attr("title", ""); + if (g.centerBottom.header) + { + g.centerBottom.header.remove(); + } + } + if (g.centerWidth) + g.centerBottom.width(g.centerWidth); + } + } + //right + if ($("> div[position=right]", g.layout).length > 0) + { + g.right = $("> div[position=right]", g.layout).wrap('<div class="l-layout-right"></div>').parent(); + + g.right.header = $('<div class="l-layout-header"><div class="l-layout-header-toggle"></div><div class="l-layout-header-inner"></div></div>'); + g.right.prepend(g.right.header); + g.right.header.toggle = $(".l-layout-header-toggle", g.right.header); + if (!p.allowRightCollapse) $(".l-layout-header-toggle", g.right.header).remove(); + g.right.content = $("> div[position=right]", g.right); + if (!g.right.content.hasClass("l-layout-content")) + g.right.content.addClass("l-layout-content"); + + //set title + var righttitle = g.right.content.attr("title"); + if (righttitle) + { + g.right.content.attr("title", ""); + $(".l-layout-header-inner", g.right.header).html(righttitle); + } + if (g.right.content.attr("hidetitle")) + { + g.right.content.attr("title", ""); + g.right.header.remove(); + } + //set width + g.rightWidth = p.rightWidth; + if (g.rightWidth) + g.right.width(g.rightWidth); + } + //lock + g.layout.lock = $("<div class='l-layout-lock'></div>"); + g.layout.append(g.layout.lock); + //DropHandle + g._addDropHandle(); + + //Collapse + g.isLeftCollapse = p.isLeftCollapse; + g.isRightCollapse = p.isRightCollapse; + g.leftCollapse = $('<div class="l-layout-collapse-left" style="display: none; "><div class="l-layout-collapse-left-toggle"></div></div>'); + g.rightCollapse = $('<div class="l-layout-collapse-right" style="display: none; "><div class="l-layout-collapse-right-toggle"></div></div>'); + g.layout.append(g.leftCollapse).append(g.rightCollapse); + g.leftCollapse.toggle = $("> .l-layout-collapse-left-toggle", g.leftCollapse); + g.rightCollapse.toggle = $("> .l-layout-collapse-right-toggle", g.rightCollapse); + g._setCollapse(); + //init + g._bulid(); + $(window).resize(function () + { + g._onResize(); + }); + g.set(p); + g.mask.height(g.layout.height()); + }, + setLeftCollapse: function (isCollapse) + { + var g = this, p = this.options; + if (!g.left) return false; + g.isLeftCollapse = isCollapse; + if (g.isLeftCollapse) + { + g.leftCollapse.show(); + g.leftDropHandle && g.leftDropHandle.hide(); + g.left.hide(); + } + else + { + g.leftCollapse.hide(); + g.leftDropHandle && g.leftDropHandle.show(); + g.left.show(); + } + g._onResize(); + + g.trigger('leftToggle', [isCollapse]); + }, + setRightCollapse: function (isCollapse) + { + var g = this, p = this.options; + if (!g.right) return false; + g.isRightCollapse = isCollapse; + g._onResize(); + if (g.isRightCollapse) + { + g.rightCollapse.show(); + g.rightDropHandle && g.rightDropHandle.hide(); + g.right.hide(); + } + else + { + g.rightCollapse.hide(); + g.rightDropHandle && g.rightDropHandle.show(); + g.right.show(); + } + g._onResize(); + + g.trigger('rightToggle', [isCollapse]); + }, + _bulid: function () + { + var g = this, p = this.options; + $("> .l-layout-left .l-layout-header,> .l-layout-right .l-layout-header", g.layout).hover(function () + { + $(this).addClass("l-layout-header-over"); + }, function () + { + $(this).removeClass("l-layout-header-over"); + + }); + $(".l-layout-header-toggle", g.layout).hover(function () + { + $(this).addClass("l-layout-header-toggle-over"); + }, function () + { + $(this).removeClass("l-layout-header-toggle-over"); + + }); + $(".l-layout-header-toggle", g.left).click(function () + { + g.setLeftCollapse(true); + }); + $(".l-layout-header-toggle", g.right).click(function () + { + g.setRightCollapse(true); + }); + //set top + g.middleTop = 0; + if (g.top) + { + g.middleTop += g.top.height(); + g.middleTop += parseInt(g.top.css('borderTopWidth')); + g.middleTop += parseInt(g.top.css('borderBottomWidth')); + g.middleTop += p.space; + } + if (g.left) + { + g.left.css({ top: g.middleTop }); + g.leftCollapse.css({ top: g.middleTop }); + } + if (g.center) g.center.css({ top: g.middleTop }); + if (g.right) + { + g.right.css({ top: g.middleTop }); + g.rightCollapse.css({ top: g.middleTop }); + } + //set left + if (g.left) g.left.css({ left: 0 }); + g._onResize(); + g._onResize(); + }, + _setCollapse: function () + { + var g = this, p = this.options; + g.leftCollapse.hover(function () + { + $(this).addClass("l-layout-collapse-left-over"); + }, function () + { + $(this).removeClass("l-layout-collapse-left-over"); + }); + g.leftCollapse.toggle.hover(function () + { + $(this).addClass("l-layout-collapse-left-toggle-over"); + }, function () + { + $(this).removeClass("l-layout-collapse-left-toggle-over"); + }); + g.rightCollapse.hover(function () + { + $(this).addClass("l-layout-collapse-right-over"); + }, function () + { + $(this).removeClass("l-layout-collapse-right-over"); + }); + g.rightCollapse.toggle.hover(function () + { + $(this).addClass("l-layout-collapse-right-toggle-over"); + }, function () + { + $(this).removeClass("l-layout-collapse-right-toggle-over"); + }); + g.leftCollapse.toggle.click(function () + { + g.setLeftCollapse(false); + }); + g.rightCollapse.toggle.click(function () + { + g.setRightCollapse(false); + }); + if (g.left && g.isLeftCollapse) + { + g.leftCollapse.show(); + g.leftDropHandle && g.leftDropHandle.hide(); + g.left.hide(); + } + if (g.right && g.isRightCollapse) + { + g.rightCollapse.show(); + g.rightDropHandle && g.rightDropHandle.hide(); + g.right.hide(); + } + }, + _addDropHandle: function () + { + var g = this, p = this.options; + if (g.left && p.allowLeftResize) + { + g.leftDropHandle = $("<div class='l-layout-drophandle-left'></div>"); + g.layout.append(g.leftDropHandle); + g.leftDropHandle && g.leftDropHandle.show(); + g.leftDropHandle.mousedown(function (e) + { + g._start('leftresize', e); + }); + } + if (g.right && p.allowRightResize) + { + g.rightDropHandle = $("<div class='l-layout-drophandle-right'></div>"); + g.layout.append(g.rightDropHandle); + g.rightDropHandle && g.rightDropHandle.show(); + g.rightDropHandle.mousedown(function (e) + { + g._start('rightresize', e); + }); + } + if (g.top && p.allowTopResize) + { + g.topDropHandle = $("<div class='l-layout-drophandle-top'></div>"); + g.layout.append(g.topDropHandle); + g.topDropHandle.show(); + g.topDropHandle.mousedown(function (e) + { + g._start('topresize', e); + }); + } + if (g.bottom && p.allowBottomResize) + { + g.bottomDropHandle = $("<div class='l-layout-drophandle-bottom'></div>"); + g.layout.append(g.bottomDropHandle); + g.bottomDropHandle.show(); + g.bottomDropHandle.mousedown(function (e) + { + g._start('bottomresize', e); + }); + } + if (g.centerBottom && p.allowCenterBottomResize) + { + g.centerBottomDropHandle = $("<div class='l-layout-drophandle-centerbottom'></div>"); + g.layout.append(g.centerBottomDropHandle); + g.centerBottomDropHandle.show(); + g.centerBottomDropHandle.mousedown(function (e) + { + g._start('centerbottomresize', e); + }); + } + g.draggingxline = $("<div class='l-layout-dragging-xline'></div>"); + g.draggingyline = $("<div class='l-layout-dragging-yline'></div>"); + g.mask = $("<div class='l-dragging-mask'></div>"); + g.layout.append(g.draggingxline).append(g.draggingyline).append(g.mask); + }, + _setDropHandlePosition: function () + { + var g = this, p = this.options; + if (g.leftDropHandle) + { + g.leftDropHandle.css({ left: g.left.width() + parseInt(g.left.css('left')), height: g.middleHeight, top: g.middleTop }); + } + if (g.rightDropHandle) + { + g.rightDropHandle.css({ left: parseInt(g.right.css('left')) - p.space, height: g.middleHeight, top: g.middleTop }); + } + if (g.topDropHandle) + { + g.topDropHandle.css({ top: g.top.height() + parseInt(g.top.css('top')), width: g.top.width() }); + } + if (g.bottomDropHandle) + { + g.bottomDropHandle.css({ top: parseInt(g.bottom.css('top')) - p.space, width: g.bottom.width() }); + } + if (g.centerBottomDropHandle) + { + g.centerBottomDropHandle.css({ + top: parseInt(g.centerBottom.css('top')) - p.space, + left: parseInt(g.center.css('left')), + width: g.center.width() + }); + } + }, + _onResize: function () + { + var g = this, p = this.options; + var oldheight = g.layout.height(); + //set layout height + var h = 0; + var windowHeight = $(window).height(); + var parentHeight = null; + if (typeof (p.height) == "string" && p.height.indexOf('%') > 0) + { + var layoutparent = g.layout.parent(); + if (p.inWindow || layoutparent[0].tagName.toLowerCase() == "body") + { + parentHeight = windowHeight; + parentHeight -= parseInt($('body').css('paddingTop')); + parentHeight -= parseInt($('body').css('paddingBottom')); + } + else + { + parentHeight = layoutparent.height(); + } + h = parentHeight * parseFloat(p.height) * 0.01; + if (p.inWindow || layoutparent[0].tagName.toLowerCase() == "body") + h -= (g.layout.offset().top - parseInt($('body').css('paddingTop'))); + } + else + { + h = parseInt(p.height); + } + h += p.heightDiff; + g.layout.height(h); + g.layoutHeight = g.layout.height(); + g.middleWidth = g.layout.width(); + g.middleHeight = g.layout.height(); + if (g.top) + { + g.middleHeight -= g.top.height(); + g.middleHeight -= parseInt(g.top.css('borderTopWidth')); + g.middleHeight -= parseInt(g.top.css('borderBottomWidth')); + g.middleHeight -= p.space; + } + if (g.bottom) + { + g.middleHeight -= g.bottom.height(); + g.middleHeight -= parseInt(g.bottom.css('borderTopWidth')); + g.middleHeight -= parseInt(g.bottom.css('borderBottomWidth')); + g.middleHeight -= p.space; + } + //specific + g.middleHeight -= 2; + + if (g.hasBind('heightChanged') && g.layoutHeight != oldheight) + { + g.trigger('heightChanged', [{ layoutHeight: g.layoutHeight, diff: g.layoutHeight - oldheight, middleHeight: g.middleHeight}]); + } + + if (g.center) + { + g.centerWidth = g.middleWidth; + if (g.left) + { + if (g.isLeftCollapse) + { + g.centerWidth -= g.leftCollapse.width(); + g.centerWidth -= parseInt(g.leftCollapse.css('borderLeftWidth')); + g.centerWidth -= parseInt(g.leftCollapse.css('borderRightWidth')); + g.centerWidth -= parseInt(g.leftCollapse.css('left')); + g.centerWidth -= p.space; + } + else + { + g.centerWidth -= g.leftWidth; + g.centerWidth -= parseInt(g.left.css('borderLeftWidth')); + g.centerWidth -= parseInt(g.left.css('borderRightWidth')); + g.centerWidth -= parseInt(g.left.css('left')); + g.centerWidth -= p.space; + } + } + if (g.right) + { + if (g.isRightCollapse) + { + g.centerWidth -= g.rightCollapse.width(); + g.centerWidth -= parseInt(g.rightCollapse.css('borderLeftWidth')); + g.centerWidth -= parseInt(g.rightCollapse.css('borderRightWidth')); + g.centerWidth -= parseInt(g.rightCollapse.css('right')); + g.centerWidth -= p.space; + } + else + { + g.centerWidth -= g.rightWidth; + g.centerWidth -= parseInt(g.right.css('borderLeftWidth')); + g.centerWidth -= parseInt(g.right.css('borderRightWidth')); + g.centerWidth -= p.space; + } + } + g.centerLeft = 0; + if (g.left) + { + if (g.isLeftCollapse) + { + g.centerLeft += g.leftCollapse.width(); + g.centerLeft += parseInt(g.leftCollapse.css('borderLeftWidth')); + g.centerLeft += parseInt(g.leftCollapse.css('borderRightWidth')); + g.centerLeft += parseInt(g.leftCollapse.css('left')); + g.centerLeft += p.space; + } + else + { + g.centerLeft += g.left.width(); + g.centerLeft += parseInt(g.left.css('borderLeftWidth')); + g.centerLeft += parseInt(g.left.css('borderRightWidth')); + g.centerLeft += p.space; + } + } + g.center.css({ left: g.centerLeft }); + g.centerWidth >= 0 && g.center.width(g.centerWidth); + g.middleHeight >= 0 && g.center.height(g.middleHeight); + var contentHeight = g.middleHeight; + if (g.center.header) contentHeight -= g.center.header.height(); + contentHeight >= 0 && g.center.content.height(contentHeight); + + g._updateCenterBottom(true); + } + if (g.left) + { + g.leftCollapse.height(g.middleHeight); + g.left.height(g.middleHeight); + } + if (g.right) + { + g.rightCollapse.height(g.middleHeight); + g.right.height(g.middleHeight); + //set left + g.rightLeft = 0; + + if (g.left) + { + if (g.isLeftCollapse) + { + g.rightLeft += g.leftCollapse.width(); + g.rightLeft += parseInt(g.leftCollapse.css('borderLeftWidth')); + g.rightLeft += parseInt(g.leftCollapse.css('borderRightWidth')); + g.rightLeft += p.space; + } + else + { + g.rightLeft += g.left.width(); + g.rightLeft += parseInt(g.left.css('borderLeftWidth')); + g.rightLeft += parseInt(g.left.css('borderRightWidth')); + g.rightLeft += parseInt(g.left.css('left')); + g.rightLeft += p.space; + } + } + if (g.center) + { + g.rightLeft += g.center.width(); + g.rightLeft += parseInt(g.center.css('borderLeftWidth')); + g.rightLeft += parseInt(g.center.css('borderRightWidth')); + g.rightLeft += p.space; + } + g.right.css({ left: g.rightLeft }); + } + if (g.bottom) + { + g.bottomTop = g.layoutHeight - g.bottom.height() - 2; + g.bottom.css({ top: g.bottomTop }); + } + g._setDropHandlePosition(); + + }, + //加了centerBottom以后,需要对centerBottom进行刷新处理一下 + _updateCenterBottom: function (isHeightResize) + { + var g = this, p = this.options; + if (g.centerBottom) + { + if (isHeightResize) + { + var centerBottomHeight = g.centerBottomHeight || p.centerBottomHeight; + g.centerBottom.css({ left: g.centerLeft }); + g.centerWidth >= 0 && g.centerBottom.width(g.centerWidth); + var centerHeight = g.center.height(), centerTop = parseInt(g.center.css("top")); + g.centerBottom.height(centerBottomHeight) + g.centerBottom.css({ top: centerTop + centerHeight - centerBottomHeight + 2 }); + g.center.height(centerHeight - centerBottomHeight - 2); + } + var centerLeft = parseInt(g.center.css("left")); + g.centerBottom.width(g.center.width()).css({ left: centerLeft }); + } + }, + _start: function (dragtype, e) + { + var g = this, p = this.options; + g.dragtype = dragtype; + if (dragtype == 'leftresize' || dragtype == 'rightresize') + { + g.xresize = { startX: e.pageX }; + g.draggingyline.css({ left: e.pageX - g.layout.offset().left, height: g.middleHeight, top: g.middleTop }).show(); + $('body').css('cursor', 'col-resize'); + g.mask.height(g.layout.height()).removeClass("l-layout-ymask").addClass("l-layout-xmask").show(); + } + else if (dragtype == 'topresize' || dragtype == 'bottomresize') + { + g.yresize = { startY: e.pageY }; + g.draggingxline.css({ top: e.pageY - g.layout.offset().top, width: g.layout.width() }).show(); + $('body').css('cursor', 'row-resize'); + g.mask.height(g.layout.height()).removeClass("l-layout-xmask").addClass("l-layout-ymask").show(); + } + else if (dragtype == 'centerbottomresize') + { + g.yresize = { startY: e.pageY }; + g.draggingxline.css({ top: e.pageY - g.layout.offset().top, width: g.layout.width() }).show(); + $('body').css('cursor', 'row-resize'); + g.mask.height(g.layout.height()).removeClass("l-layout-xmask").addClass("l-layout-ymask").show(); + } + else + { + return; + } + g.layout.lock.width(g.layout.width()); + g.layout.lock.height(g.layout.height()); + g.layout.lock.show(); + if ($.browser.msie || $.browser.safari) $('body').bind('selectstart', function () { return false; }); // 不能选择 + + $(document).bind('mouseup', function () + { + g._stop.apply(g, arguments); + }); + $(document).bind('mousemove', function () + { + g._drag.apply(g, arguments); + }); + }, + _drag: function (e) + { + var g = this, p = this.options; + if (g.xresize) + { + g.xresize.diff = e.pageX - g.xresize.startX; + g.draggingyline.css({ left: e.pageX - g.layout.offset().left }); + $('body').css('cursor', 'col-resize'); + } + else if (g.yresize) + { + g.yresize.diff = e.pageY - g.yresize.startY; + g.draggingxline.css({ top: e.pageY - g.layout.offset().top }); + $('body').css('cursor', 'row-resize'); + } + }, + _stop: function (e) + { + var g = this, p = this.options; + var diff; + if (g.xresize && g.xresize.diff != undefined) + { + diff = g.xresize.diff; + if (g.dragtype == 'leftresize') + { + if (p.minLeftWidth) + { + if (g.leftWidth + g.xresize.diff < p.minLeftWidth) + return; + } + g.leftWidth += g.xresize.diff; + g.left.width(g.leftWidth); + if (g.center) + g.center.width(g.center.width() - g.xresize.diff).css({ left: parseInt(g.center.css('left')) + g.xresize.diff }); + else if (g.right) + g.right.width(g.left.width() - g.xresize.diff).css({ left: parseInt(g.right.css('left')) + g.xresize.diff }); + } + else if (g.dragtype == 'rightresize') + { + if (p.minRightWidth) + { + if (g.rightWidth - g.xresize.diff < p.minRightWidth) + return; + } + g.rightWidth -= g.xresize.diff; + g.right.width(g.rightWidth).css({ left: parseInt(g.right.css('left')) + g.xresize.diff }); + if (g.center) + g.center.width(g.center.width() + g.xresize.diff); + else if (g.left) + g.left.width(g.left.width() + g.xresize.diff); + } + g._updateCenterBottom(); + } + else if (g.yresize && g.yresize.diff != undefined) + { + diff = g.yresize.diff; + if (g.dragtype == 'topresize') + { + g.top.height(g.top.height() + g.yresize.diff); + g.middleTop += g.yresize.diff; + g.middleHeight -= g.yresize.diff; + if (g.left) + { + g.left.css({ top: g.middleTop }).height(g.middleHeight); + g.leftCollapse.css({ top: g.middleTop }).height(g.middleHeight); + } + if (g.center) g.center.css({ top: g.middleTop }).height(g.middleHeight); + if (g.right) + { + g.right.css({ top: g.middleTop }).height(g.middleHeight); + g.rightCollapse.css({ top: g.middleTop }).height(g.middleHeight); + } + g._updateCenterBottom(true); + } + else if (g.dragtype == 'bottomresize') + { + g.bottom.height(g.bottom.height() - g.yresize.diff); + g.middleHeight += g.yresize.diff; + g.bottomTop += g.yresize.diff; + g.bottom.css({ top: g.bottomTop }); + if (g.left) + { + g.left.height(g.middleHeight); + g.leftCollapse.height(g.middleHeight); + } + if (g.center) g.center.height(g.middleHeight); + if (g.right) + { + g.right.height(g.middleHeight); + g.rightCollapse.height(g.middleHeight); + } + g._updateCenterBottom(true); + } + else if (g.dragtype == 'centerbottomresize') + { + g.centerBottomHeight = g.centerBottomHeight || p.centerBottomHeight; + g.centerBottomHeight -= g.yresize.diff; + var centerBottomTop = parseInt(g.centerBottom.css("top")); + g.centerBottom.css("top" , centerBottomTop + g.yresize.diff); + g.centerBottom.height(g.centerBottom.height() - g.yresize.diff); + g.center.height(g.center.height() + g.yresize.diff); + } + } + g.trigger('endResize', [{ + direction: g.dragtype ? g.dragtype.replace(/resize/, '') : '', + diff: diff + }, e]); + g._setDropHandlePosition(); + g.draggingxline.hide(); + g.draggingyline.hide(); + g.mask.hide(); + g.xresize = g.yresize = g.dragtype = false; + g.layout.lock.hide(); + if ($.browser.msie || $.browser.safari) + $('body').unbind('selectstart'); + $(document).unbind('mousemove', g._drag); + $(document).unbind('mouseup', g._stop); + $('body').css('cursor', ''); + + } + }); + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerListBox = function (options) + { + return $.ligerui.run.call(this, "ligerListBox", arguments); + }; + + $.ligerDefaults.ListBox = { + isMultiSelect: false, //是否多选 + isShowCheckBox: false, //是否选择复选框 + columns: null, //表格状态 + width: 150, //宽度 + height: 100, //高度 + onSelect: false, //选择前事件 + onSelected: null, //选择值事件 + valueField: 'id', //值成员 + textField: 'text', //显示成员 + valueFieldID: null, //值 隐藏域 表单名 + split: ";", //分隔符 + data: null, //数据 + parms: null, //ajax提交表单 + url: null, //数据源URL(需返回JSON) + urlParms: null, //url带参数 + ajaxContentType: null, + ajaxType : 'post', + onSuccess: null, + onError: null, + render: null, //显示html自定义函数 + css: null, //附加css + value: null, //值 + valueFieldCssClass: null + }; + + //扩展方法 + $.ligerMethos.ListBox = $.ligerMethos.ListBox || {}; + + + $.ligerui.controls.ListBox = function (element, options) + { + $.ligerui.controls.ListBox.base.constructor.call(this, element, options); + }; + $.ligerui.controls.ListBox.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'ListBox'; + }, + _extendMethods: function () + { + return $.ligerMethos.ListBox; + }, + _init: function () + { + $.ligerui.controls.ListBox.base._init.call(this); + }, + _render: function () + { + var g = this, p = this.options; + g.data = p.data; + g.valueField = null; //隐藏域(保存值) + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.valueField = $(this.element); + if ($(this.element).is(":text")) + { + g.valueField.hide(); + } + } + else if (p.valueFieldID) + { + g.valueField = $("#" + p.valueFieldID + ":input,[name=" + p.valueFieldID + "]:input"); + if (g.valueField.length == 0) g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = p.valueFieldID; + } + else + { + g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = g.id + "_val"; + } + if (g.valueField[0].name == null) g.valueField[0].name = g.valueField[0].id; + if (p.valueFieldCssClass) + { + g.valueField.addClass(p.valueFieldCssClass); + } + g.valueField.attr("data-ligerid", g.id); + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.selectBox = $('<div></div>').insertBefore(this.element); + } else + { + g.selectBox = $(this.element); + } + g.selectBox.html('<div class="l-listbox-inner"><table cellpadding="0" cellspacing="0" border="0" class="l-listbox-table"></table></div>').addClass("l-listbox").append(g.valueField); + g.selectBox.table = $("table:first", g.selectBox); + + g.set(p); + + g._addClickEven(); + }, + destroy: function () + { + if (this.selectBox) this.selectBox.remove(); + this.options = null; + $.ligerui.remove(this); + }, + clear : function() + { + this._changeValue(""); + this.trigger('clear'); + }, + _setIsShowCheckBox : function(value) + { + if (value) + { + $("table", this.selectBox).addClass("l-table-checkbox"); + } else + { + $("table", this.selectBox).addClass("l-table-nocheckbox"); + } + }, + _setCss: function (css) + { + if (css) + { + this.selectBox.addClass(css); + } + }, + _setDisabled: function (value) + { + //禁用样式 + if (value) + { + this.selectBox.addClass('l-text-disabled'); + } else + { + this.selectBox.removeClass('l-text-disabled'); + } + }, + _setWidth: function (value) + { + this.selectBox.width(value); + }, + _setHeight: function (value) + { + this.selectBox.height(value); + }, + getText : function() + { + var value = this.getValue(); + return this.findTextByValue(value); + }, + //查找Text,适用多选和单选 + findTextByValue: function (value) + { + var g = this, p = this.options; + if (value == null || value == "") return ""; + var texts = []; + var contain = function (checkvalue) + { + var targetdata = value.toString().split(p.split); + for (var i = 0; i < targetdata.length; i++) + { + if (targetdata[i] == checkvalue) return true; + } + return false; + }; + $(g.data).each(function (i, item) + { + var val = item[p.valueField]; + var txt = item[p.textField]; + if (contain(val)) + { + texts.push(txt); + } + }); + return texts.join(p.split); + }, + getDataByValue: function (value) + { + var g = this, p = this.options; + for (var i = 0, l = g.data.length; i < l; i++) + { + if (g.data[i][p.valueField] == value) return g.data[i]; + } + return null; + }, + indexOf: function (item) + { + var g = this, p = this.options; + if (!g.data) return -1; + var isObj = typeof (item) == "object"; + for (var i = 0, l = g.data.length; i < l; i++) + { + if (isObj) + { + if (g.data[i] == item) return i; + } else + { + if (g.data[i][p.valueField] && g.data[i][p.valueField].toString() == item.toString()) return i; + } + } + return -1; + }, + removeItems : function(items) + { + var g = this; + if (!g.data) return; + $(items).each(function (i,item) + { + var index = g.indexOf(item); + if (index == -1) return; + g.data.splice(index, 1); + }); + g.refresh(); + }, + removeItem: function (item) + { + if (!this.data) return; + var index = this.indexOf(item); + if (index == -1) return; + this.data.splice(index, 1); + this.refresh(); + }, + insertItem: function (item,index) + { + var g = this; + if (!g.data) g.data = []; + g.data.splice(index, 0, item); + g.refresh(); + }, + addItems: function (items) + { + var g = this; + if (!g.data) g.data = []; + $(items).each(function (i, item) + { + g.data.push(item); + }); + g.refresh(); + }, + addItem: function (item) + { + var g = this; + if (!g.data) g.data = []; + g.data.push(item); + g.refresh(); + }, + getSelectedItems: function() + { + var g = this, p = this.options; + if (!g.data) return null; + var value = g.getValue(); + if (!value) return null; + var items = []; + $(value.split(p.split)).each(function () + { + var index = g.indexOf(this.toString()); + if (index != -1) items.push(g.data[index]); + }); + return items; + }, + _setValue: function (value) + { + var g = this, p = this.options; + p.value = value; + this._dataInit(); + }, + setValue: function (value) + { + this._setValue(value); + }, + _setUrl: function (url) + { + if (!url) return; + var g = this, p = this.options; + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var parms = $.isFunction(p.parms) ? p.parms() : p.parms; + if (p.ajaxContentType == "application/json" && typeof (parms) != "string") + { + parms = liger.toJSON(parms); + } + var ajaxOp = { + type: p.ajaxType || 'post', + url: url, + data: parms, + cache: false, + dataType: 'json', + success: function (data) + { + g.setData(data); + g.trigger('success', [data]); + }, + error: function (XMLHttpRequest, textStatus) + { + g.trigger('error', [XMLHttpRequest, textStatus]); + } + }; + + if (p.ajaxContentType) + { + ajaxOp.contentType = p.ajaxContentType; + } + $.ajax(ajaxOp); + }, + reload : function() + { + this.set('url', this.options.url); + }, + setUrl: function (url) + { + return this._setUrl(url); + }, + setParm: function (name, value) + { + if (!name) return; + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + parms[name] = value; + g.set('parms', parms); + }, + clearContent: function () + { + var g = this, p = this.options; + $("table", g.selectBox).html(""); + }, + _setColumns : function(columns) + { + var g = this, p = this.options; + p.columns = columns; + g.refresh(); + }, + _setData : function(data) + { + this.setData(data); + }, + setData: function (data) + { + var g = this, p = this.options; + if (!data || !data.length) return; + g.data = data; + g.refresh(); + g.updateStyle(); + }, + refresh:function() + { + var g = this, p = this.options, data = this.data; + this.clearContent(); + if (!data) return; + if (p.columns) + { + g.selectBox.table.headrow = $("<tr class='l-table-headerow'><td width='18px' class='l-checkboxrow'></td></tr>"); + g.selectBox.table.append(g.selectBox.table.headrow); + g.selectBox.table.addClass("l-listbox-grid"); + for (var j = 0; j < p.columns.length; j++) + { + var headrow = $("<td columnindex='" + j + "' columnname='" + p.columns[j].name + "'>" + p.columns[j].header + "</td>"); + if (p.columns[j].width) + { + headrow.width(p.columns[j].width); + } + g.selectBox.table.headrow.append(headrow); + + } + } + var out = []; + for (var i = 0; i < data.length; i++) + { + var val = data[i][p.valueField]; + var txt = data[i][p.textField]; + var valueIndexStr = " value='" + val + "' index='" + i + "'"; + if (!p.columns) + { + out.push("<tr " + valueIndexStr + ">"); + out.push("<td style='width:18px;' class='l-checkboxrow'><input type='checkbox'" + valueIndexStr + "/></td>"); + var itemHtml = txt; + if (p.render) + { + itemHtml = p.render({ + data: data[i], + value: val, + text: txt + }); + } + out.push("<td align='left'>" + itemHtml + "</td></tr>"); + } else + { + out.push("<tr " + valueIndexStr + "><td style='width:18px;' class='l-checkboxrow'><input type='checkbox' " + valueIndexStr + "/></td>"); + for (var j = 0; j < p.columns.length; j++) + { + var columnname = p.columns[j].name; + out.push("<td>" + data[i][columnname] + "</td>"); + } + out.push('</tr>'); + } + } + g.selectBox.table.append(out.join('')); + }, + _getValue: function () + { + return $(this.valueField).val(); + }, + getValue: function () + { + //获取值 + return this._getValue(); + }, + updateStyle: function () + { + this._dataInit(); + }, + selectAll: function () + { + var g = this, p = this.options; + var values = []; + $("tr", g.selectBox).each(function () + { + var jrow = $(this); + values.push(jrow.attr("value")); + }); + $("tr", g.selectBox).addClass("l-selected").find(":checkbox").each(function () { this.checked = true; }); + g.valueField.val(values.join(p.split)); + }, + _dataInit: function () + { + var g = this, p = this.options; + var value = p.value; + //根据值来初始化 + if (value != null) + { + g._changeValue(value); + } + else if (g.valueField.val() != "") + { + p.value = g.valueField.val(); + } + var valueArr = (value || "").toString().split(p.split); + + $("tr.l-selected", g.selectBox) + .removeClass("l-selected") + .find(":checkbox").each(function () { this.checked = false; }); + $(valueArr).each(function (i, item) + { + $("tr[value='" + item + "']", g.selectBox) + .addClass("l-selected") + .find(":checkbox").each(function () { this.checked = true; }); + }); + }, + //设置值到 隐藏域 + _changeValue: function (newValue) + { + var g = this, p = this.options; + g.valueField.val(newValue); + g.selectedValue = newValue; + }, + //更新值到隐藏域 + _updateValue: function () + { + var g = this, p = this.options; + var values = []; + $("tr", g.selectBox).each(function () + { + var jrow = $(this); + if (jrow.hasClass("l-selected")) + { + values.push(jrow.attr("value")); + } + }); + g._changeValue(values.join(p.split)); + }, + _addClickEven: function () + { + var g = this, p = this.options; + //选项点击 + g.selectBox.click(function (e) + { + var obj = (e.target || e.srcElement); + var jrow = $(obj).parents("tr:first"); + if (!jrow.length) return; + var value = jrow.attr("value"); + var text = g.findTextByValue(value), data = g.getDataByValue(value); + if (g.hasBind('select')) + { + if (g.trigger('select', [value, text, data]) == false) + { + return false; + } + } + if (!p.isMultiSelect) + { + $("tr.l-selected", g.selectBox).not(jrow) + .removeClass("l-selected") + .find(":checkbox").each(function () { this.checked = false }); + } + if (jrow.hasClass("l-selected")) + { + jrow.removeClass("l-selected"); + } else + { + jrow.addClass("l-selected"); + } + jrow.find(":checkbox").each(function () { this.checked = jrow.hasClass("l-selected"); }); + g._updateValue(); + g.trigger('selected', [value, text, data]); + }); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.ligerMenu = function (options) + { + return $.ligerui.run.call(null, "ligerMenu", arguments); + }; + + $.ligerDefaults.Menu = { + width: 120, + top: 0, + left: 0, + cls : null, + items: null, + shadow: true + }; + + $.ligerMethos.Menu = {}; + + $.ligerui.controls.Menu = function (options) + { + $.ligerui.controls.Menu.base.constructor.call(this, null, options); + }; + $.ligerui.controls.Menu.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Menu'; + }, + __idPrev: function () + { + return 'Menu'; + }, + _extendMethods: function () + { + return $.ligerMethos.Menu; + }, + _render: function () + { + var g = this, p = this.options; + g.menuItemCount = 0; + //全部菜单 + g.menus = {}; + //顶级菜单 + g.menu = g.createMenu(); + g.element = g.menu[0]; + g.menu.css({ top: p.top, left: p.left, width: p.width }); + p.cls && g.menu.addClass(p.cls); + + p.items && $(p.items).each(function (i, item) + { + g.addItem(item); + }); + + $(document).bind('click.menu', function () + { + for (var menuid in g.menus) + { + var menu = g.menus[menuid]; + if (!menu) return; + menu.hide(); + if (menu.shadow) menu.shadow.hide(); + } + }); + g.set(p); + }, + show: function (options, menu) + { + var g = this, p = this.options; + if (menu == undefined) menu = g.menu; + if (options && options.left != undefined) + { + menu.css({ left: options.left }); + } + if (options && options.top != undefined) + { + menu.css({ top: options.top }); + } + menu.show(); + g.updateShadow(menu); + }, + updateShadow: function (menu) + { + var g = this, p = this.options; + if (!p.shadow) return; + menu.shadow.css({ + left: menu.css('left'), + top: menu.css('top'), + width: menu.outerWidth(), + height: menu.outerHeight() + }); + if (menu.is(":visible")) + menu.shadow.show(); + else + menu.shadow.hide(); + }, + hide: function (menu) + { + var g = this, p = this.options; + if (menu == undefined) menu = g.menu; + g.hideAllSubMenu(menu); + menu.hide(); + g.updateShadow(menu); + }, + toggle: function () + { + var g = this, p = this.options; + g.menu.toggle(); + g.updateShadow(g.menu); + }, + removeItem: function (itemid) + { + var g = this, p = this.options; + $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).remove(); + }, + setEnabled: function (itemid) + { + var g = this, p = this.options; + $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).removeClass("l-menu-item-disable"); + }, + setMenuText : function(itemid,text) + { + var g = this, p = this.options; + $("> .l-menu-item[menuitemid=" + itemid + "] >.l-menu-item-text:first", g.menu.items).html(text); + }, + setDisabled: function (itemid) + { + var g = this, p = this.options; + $("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).addClass("l-menu-item-disable"); + }, + isEnable: function (itemid) + { + var g = this, p = this.options; + return !$("> .l-menu-item[menuitemid=" + itemid + "]", g.menu.items).hasClass("l-menu-item-disable"); + }, + getItemCount: function () + { + var g = this, p = this.options; + return $("> .l-menu-item", g.menu.items).length; + }, + addItem: function (item, menu) + { + var g = this, p = this.options; + if (!item) return; + if (menu == undefined) menu = g.menu; + + if (item.line) + { + menu.items.append('<div class="l-menu-item-line"></div>'); + return; + } + var ditem = $('<div class="l-menu-item"><div class="l-menu-item-text"></div> </div>'); + var itemcount = $("> .l-menu-item", menu.items).length; + menu.items.append(ditem); + ditem.attr("ligeruimenutemid", ++g.menuItemCount); + item.id && ditem.attr("menuitemid", item.id); + item.text && $(">.l-menu-item-text:first", ditem).html(item.text); + item.icon && ditem.prepend('<div class="l-menu-item-icon l-icon-' + item.icon + '"></div>'); + item.img && ditem.prepend('<div class="l-menu-item-icon"><img style="width:16px;height:16px;margin:2px;" src="' + item.img + '" /></div>'); + if (item.disable || item.disabled) + ditem.addClass("l-menu-item-disable"); + if (item.children) + { + ditem.append('<div class="l-menu-item-arrow"></div>'); + var newmenu = g.createMenu(ditem.attr("ligeruimenutemid")); + g.menus[ditem.attr("ligeruimenutemid")] = newmenu; + newmenu.width(p.width); + newmenu.hover(null, function () + { + if (!newmenu.showedSubMenu) + g.hide(newmenu); + }); + $(item.children).each(function () + { + g.addItem(this, newmenu); + }); + } + item.click && ditem.click(function () + { + if ($(this).hasClass("l-menu-item-disable")) return; + item.click(item, itemcount); + }); + item.dblclick && ditem.dblclick(function () + { + if ($(this).hasClass("l-menu-item-disable")) return; + item.dblclick(item, itemcount); + }); + + var menuover = $("> .l-menu-over:first", menu); + ditem.hover(function () + { + if ($(this).hasClass("l-menu-item-disable")) return; + var itemtop = $(this).offset().top; + var top = itemtop - menu.offset().top; + menuover.css({ top: top }); + g.hideAllSubMenu(menu); + if (item.children) + { + var ligeruimenutemid = $(this).attr("ligeruimenutemid"); + if (!ligeruimenutemid) return; + if (g.menus[ligeruimenutemid]) + { + g.show({ top: itemtop, left: $(this).offset().left + $(this).width() - 5 }, g.menus[ligeruimenutemid]); + menu.showedSubMenu = true; + } + } + }, function () + { + if ($(this).hasClass("l-menu-item-disable")) return; + var ligeruimenutemid = $(this).attr("ligeruimenutemid"); + if (item.children) + { + var ligeruimenutemid = $(this).attr("ligeruimenutemid"); + if (!ligeruimenutemid) return; + }; + }); + }, + hideAllSubMenu: function (menu) + { + var g = this, p = this.options; + if (menu == undefined) menu = g.menu; + $("> .l-menu-item", menu.items).each(function () + { + if ($("> .l-menu-item-arrow", this).length > 0) + { + var ligeruimenutemid = $(this).attr("ligeruimenutemid"); + if (!ligeruimenutemid) return; + g.menus[ligeruimenutemid] && g.hide(g.menus[ligeruimenutemid]); + } + }); + menu.showedSubMenu = false; + }, + createMenu: function (parentMenuItemID) + { + var g = this, p = this.options; + var menu = $('<div class="l-menu" style="display:none"><div class="l-menu-yline"></div><div class="l-menu-over"><div class="l-menu-over-l"></div> <div class="l-menu-over-r"></div></div><div class="l-menu-inner"></div></div>'); + parentMenuItemID && menu.attr("ligeruiparentmenuitemid", parentMenuItemID); + menu.items = $("> .l-menu-inner:first", menu); + menu.appendTo('body'); + if (p.shadow) + { + menu.shadow = $('<div class="l-menu-shadow"></div>').insertAfter(menu); + g.updateShadow(menu); + } + menu.hover(null, function () + { + if (!menu.showedSubMenu) + $("> .l-menu-over:first", menu).css({ top: -24 }); + }); + if (parentMenuItemID) + g.menus[parentMenuItemID] = menu; + else + g.menus[0] = menu; + return menu; + } + }); + //旧写法保留 + $.ligerui.controls.Menu.prototype.setEnable = $.ligerui.controls.Menu.prototype.setEnabled; + $.ligerui.controls.Menu.prototype.setDisable = $.ligerui.controls.Menu.prototype.setDisabled; + + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerMenuBar = function (options) + { + return $.ligerui.run.call(this, "ligerMenuBar", arguments); + }; + $.fn.ligerGetMenuBarManager = function () + { + return $.ligerui.run.call(this, "ligerGetMenuBarManager", arguments); + }; + + $.ligerDefaults.MenuBar = {}; + + $.ligerMethos.MenuBar = {}; + + $.ligerui.controls.MenuBar = function (element, options) + { + $.ligerui.controls.MenuBar.base.constructor.call(this, element, options); + }; + $.ligerui.controls.MenuBar.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'MenuBar'; + }, + __idPrev: function () + { + return 'MenuBar'; + }, + _extendMethods: function () + { + return $.ligerMethos.MenuBar; + }, + _render: function () + { + var g = this, p = this.options; + g.menubar = $(this.element); + if (!g.menubar.hasClass("l-menubar")) g.menubar.addClass("l-menubar"); + if (p && p.items) + { + $(p.items).each(function (i, item) + { + g.addItem(item); + }); + } + $(document).click(function () + { + $(".l-panel-btn-selected", g.menubar).removeClass("l-panel-btn-selected"); + }); + g.set(p); + }, + addItem: function (item) + { + var g = this, p = this.options; + var ditem = $('<div class="l-menubar-item l-panel-btn"><span></span><div class="l-panel-btn-l"></div><div class="l-panel-btn-r"></div><div class="l-menubar-item-down"></div></div>'); + g.menubar.append(ditem); + item.id && ditem.attr("menubarid", item.id); + item.text && $("span:first", ditem).html(item.text); + item.disable && ditem.addClass("l-menubar-item-disable"); + item.click && ditem.click(function () { item.click(item); }); + if (item.menu) + { + var menu = $.ligerMenu(item.menu); + ditem.hover(function () + { + g.actionMenu && g.actionMenu.hide(); + var left = $(this).offset().left; + var top = $(this).offset().top + $(this).height(); + menu.show({ top: top, left: left }); + g.actionMenu = menu; + $(this).addClass("l-panel-btn-over l-panel-btn-selected").siblings(".l-menubar-item").removeClass("l-panel-btn-selected"); + }, function () + { + $(this).removeClass("l-panel-btn-over"); + }); + } + else + { + ditem.hover(function () + { + $(this).addClass("l-panel-btn-over"); + }, function () + { + $(this).removeClass("l-panel-btn-over"); + }); + $(".l-menubar-item-down", ditem).remove(); + } + + } + }); + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.ligerMessageBox = function (options) + { + return $.ligerui.run.call(null, "ligerMessageBox", arguments, { isStatic: true }); + }; + + + $.ligerDefaults.MessageBox = { + isDrag: true + }; + + $.ligerMethos.MessageBox = {}; + + $.ligerui.controls.MessageBox = function (options) + { + $.ligerui.controls.MessageBox.base.constructor.call(this, null, options); + }; + $.ligerui.controls.MessageBox.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'MessageBox'; + }, + __idPrev: function () + { + return 'MessageBox'; + }, + _extendMethods: function () + { + return $.ligerMethos.MessageBox; + }, + _render: function () + { + var g = this, p = this.options; + var messageBoxHTML = ""; + messageBoxHTML += '<div class="l-messagebox">'; + messageBoxHTML += ' <div class="l-messagebox-lt"></div><div class="l-messagebox-rt"></div>'; + messageBoxHTML += ' <div class="l-messagebox-l"></div><div class="l-messagebox-r"></div> '; + messageBoxHTML += ' <div class="l-messagebox-image"></div>'; + messageBoxHTML += ' <div class="l-messagebox-title">'; + messageBoxHTML += ' <div class="l-messagebox-title-inner"></div>'; + messageBoxHTML += ' <div class="l-messagebox-close"></div>'; + messageBoxHTML += ' </div>'; + messageBoxHTML += ' <div class="l-messagebox-content">'; + messageBoxHTML += ' </div>'; + messageBoxHTML += ' <div class="l-messagebox-buttons"><div class="l-messagebox-buttons-inner">'; + messageBoxHTML += ' </div></div>'; + messageBoxHTML += ' </div>'; + g.messageBox = $(messageBoxHTML); + $('body').append(g.messageBox); + g.messageBox.close = function () + { + g._removeWindowMask(); + g.messageBox.remove(); + }; + //设置参数属性 + p.width && g.messageBox.width(p.width); + p.title && $(".l-messagebox-title-inner", g.messageBox).html(p.title); + p.content && $(".l-messagebox-content", g.messageBox).html(p.content); + if (p.buttons) + { + $(p.buttons).each(function (i, item) + { + var btn = $('<div class="l-messagebox-btn"><div class="l-messagebox-btn-l"></div><div class="l-messagebox-btn-r"></div><div class="l-messagebox-btn-inner"></div></div>'); + $(".l-messagebox-btn-inner", btn).html(item.text); + $(".l-messagebox-buttons-inner", g.messageBox).append(btn); + item.width && btn.width(item.width); + item.onclick && btn.click(function () { item.onclick(item, i, g.messageBox) }); + }); + $(".l-messagebox-buttons-inner", g.messageBox).append("<div class='l-clear'></div>"); + } + var boxWidth = g.messageBox.width(); + var sumBtnWidth = 0; + $(".l-messagebox-buttons-inner .l-messagebox-btn", g.messageBox).each(function () + { + sumBtnWidth += $(this).width(); + }); + $(".l-messagebox-buttons-inner", g.messageBox).css({ marginLeft: parseInt((boxWidth - sumBtnWidth) * 0.5) }); + //设置背景、拖动支持 和设置图片 + g._applyWindowMask(); + g._applyDrag(); + g._setImage(); + + //位置初始化 + var left = 0; + var top = 0; + var width = p.width || g.messageBox.width(); + if (p.left != null) left = p.left; + else p.left = left = 0.5 * ($(window).width() - width); + if (p.top != null) top = p.top; + else p.top = top = 0.5 * ($(window).height() - g.messageBox.height()) + $(window).scrollTop() - 10; + if (left < 0) p.left = left = 0; + if (top < 0) p.top = top = 0; + g.messageBox.css({ left: left, top: top }); + + //设置事件 + $(".l-messagebox-btn", g.messageBox).hover(function () + { + $(this).addClass("l-messagebox-btn-over"); + }, function () + { + $(this).removeClass("l-messagebox-btn-over"); + }); + $(".l-messagebox-close", g.messageBox).hover(function () + { + $(this).addClass("l-messagebox-close-over"); + }, function () + { + $(this).removeClass("l-messagebox-close-over"); + }).click(function () + { + g.messageBox.close(); + }); + g.set(p); + }, + close: function () + { + var g = this, p = this.options; + this.g._removeWindowMask(); + this.messageBox.remove(); + }, + _applyWindowMask: function () + { + var g = this, p = this.options; + $(".l-window-mask").remove(); + $("<div class='l-window-mask' style='display: block;'></div>").appendTo($("body")); + }, + _removeWindowMask: function () + { + var g = this, p = this.options; + $(".l-window-mask").remove(); + }, + _applyDrag: function () + { + var g = this, p = this.options; + if (p.isDrag && $.fn.ligerDrag) + g.messageBox.ligerDrag({ handler: '.l-messagebox-title-inner', animate: false }); + }, + _setImage: function () + { + var g = this, p = this.options; + if (p.type) + { + if (p.type == 'success' || p.type == 'donne') + { + $(".l-messagebox-image", g.messageBox).addClass("l-messagebox-image-donne").show(); + $(".l-messagebox-content", g.messageBox).css({ paddingLeft: 64, paddingBottom: 30 }); + } + else if (p.type == 'error') + { + $(".l-messagebox-image", g.messageBox).addClass("l-messagebox-image-error").show(); + $(".l-messagebox-content", g.messageBox).css({ paddingLeft: 64, paddingBottom: 30 }); + } + else if (p.type == 'warn') + { + $(".l-messagebox-image", g.messageBox).addClass("l-messagebox-image-warn").show(); + $(".l-messagebox-content", g.messageBox).css({ paddingLeft: 64, paddingBottom: 30 }); + } + else if (p.type == 'question') + { + $(".l-messagebox-image", g.messageBox).addClass("l-messagebox-image-question").show(); + $(".l-messagebox-content", g.messageBox).css({ paddingLeft: 64, paddingBottom: 40 }); + } + } + } + }); + + + $.ligerMessageBox.show = function (p) + { + return $.ligerMessageBox(p); + }; + $.ligerMessageBox.alert = function (title, content, type, onBtnClick) + { + title = title || ""; + content = content || title; + var onclick = function (item, index, messageBox) + { + messageBox.close(); + if (onBtnClick) + onBtnClick(item, index, messageBox); + }; + p = { + title: title, + content: content, + buttons: [{ text: '确定', onclick: onclick}] + }; + if (type) p.type = type; + return $.ligerMessageBox(p); + }; + $.ligerMessageBox.confirm = function (title, content, callback) + { + var onclick = function (item, index, messageBox) + { + messageBox.close(); + if (callback) + { + callback(index == 0); + } + }; + p = { + type: 'question', + title: title, + content: content, + buttons: [{ text: '是', onclick: onclick }, { text: '否', onclick: onclick}] + }; + return $.ligerMessageBox(p); + }; + $.ligerMessageBox.success = function (title, content, onBtnClick) + { + return $.ligerMessageBox.alert(title, content, 'success', onBtnClick); + }; + $.ligerMessageBox.error = function (title, content, onBtnClick) + { + return $.ligerMessageBox.alert(title, content, 'error', onBtnClick); + }; + $.ligerMessageBox.warn = function (title, content, onBtnClick) + { + return $.ligerMessageBox.alert(title, content, 'warn', onBtnClick); + }; + $.ligerMessageBox.question = function (title, content) + { + return $.ligerMessageBox.alert(title, content, 'question'); + }; + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerPanel = function (options) + { + return $.ligerui.run.call(this, "ligerPanel", arguments); + }; + + $.ligerDefaults.Panel = { + width: 400, + height : 300, + title: 'Panel', + content: null, //内容 + url: null, //远程内容Url + urlParms: null, //传参 + frameName: null, //创建iframe时 作为iframe的name和id + data: null, //可用于传递到iframe的数据 + showClose: false, //是否显示关闭按钮 + showToggle: true, //是否显示收缩按钮 + showRefresh: false, //是否显示刷新按钮 + icon: null, //左侧按钮 + onClose:null, //关闭前事件 + onClosed:null, //关闭事件 + onLoaded: null, //url模式 加载完事件 + onToggle: null //收缩/展开事件 + }; + + $.ligerDefaults.PanelString = { + refreshMessage: '刷新', + closeMessage: '关闭', + expandMessage: '展开', + collapseMessage: '收起' + }; + + $.ligerMethos.Panel = {}; + + $.ligerui.controls.Panel = function (element, options) + { + $.ligerui.controls.Panel.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Panel.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Panel'; + }, + __idPrev: function () + { + return 'Panel'; + }, + _extendMethods: function () + { + return $.ligerMethos.Panel; + }, + _init: function () + { + var g = this, p = this.options; + $.ligerui.controls.Panel.base._init.call(this); + p.content = p.content || $(g.element).html(); + }, + _render: function () + { + var g = this, p = this.options; + g.panel = $(g.element).addClass("l-panel").html(""); + g.panel.append('<div class="l-panel-header"><span></span><div class="icons"></div></div><div class="l-panel-content"></div>'); + + g.set(p); + + g.panel.find(".l-panel-header").hover(function () + { + $(this).addClass("l-panel-header-hover"); + }, function () + { + $(this).removeClass("l-panel-header-hover"); + }); + + g.panel.bind("click.panel", function (e) + { + var obj = (e.target || e.srcElement), jobj = $(obj); + if (jobj.hasClass("l-panel-header-toggle")) + { + + + var isShowed = !g.panel.find(".l-panel-header .l-panel-header-toggle:first").hasClass("l-panel-header-toggle-hide"); + + g.toggle(); + g.trigger('toggle', [isShowed]); + + + } else if (jobj.hasClass("l-panel-header-close")) + { + g.close(); + } else if (jobj.hasClass("l-panel-header-refresh")) + { + g.refresh(); + } + }); + }, + _setChildren: function(children) + { + var g = this, p = this.options; + var tagNames = { + input : ["textbox", "combobox", "select"] + }; + var PluginNameMatchs = + { + "grid" : "ligerGrid", + "toolbar":"ligerToolBar", + "tree":"ligerTree", + "form":"ligerForm", + "menu":"ligerMenu", + "menubar":"ligerMenuBar", + "portal":"ligerPortal", + "combobox":"ligerComboBox", + "textbox":"ligerTextBox", + "spinner":"ligerSpinner", + "listbox":"ligerListBox", + "checkbox":"ligerCheckBox", + "radio":"ligerRadio", + "checkboxlist":"ligerCheckBoxList", + "radiolist":"ligerRadioList", + "popupedit":"ligerPopupEdit", + "button":"ligerButton", + "dateeditor":"ligerDateEditor", + "dialog":"ligerDialog", + "panel":"ligerPanel", + "layout":"ligerLayout", + "accordion":"ligerAccordion", + "tab":"ligerTab" + }; + if (!children || !children.length) return; + for (var i = 0; i < children.length; i++) + { + var child = children[i], type = child.type; + var tagName = tagNames[type] || "div"; + var plugin = PluginNameMatchs[type]; + if (!plugin) continue; + var element = document.createElement(tagName); + g.panel.find(".l-panel-content").append(element); + var childOp = $.extend({},child); + childOp.type = null; + $(element)[plugin](childOp); + } + }, + collapse: function () + { + var g = this, p = this.options; + var toggle = g.panel.find(".l-panel-header .l-panel-header-toggle:first"); + if (toggle.hasClass("l-panel-header-toggle-hide")) return; + g.toggle(); + }, + expand: function () + { + var g = this, p = this.options; + var toggle = g.panel.find(".l-panel-header .l-panel-header-toggle:first"); + if (!toggle.hasClass("l-panel-header-toggle-hide")) return; + g.toggle(); + }, + toggle : function() + { + var g = this, p = this.options; + var toggle = g.panel.find(".l-panel-header .l-panel-header-toggle:first"); + if (toggle.hasClass("l-panel-header-toggle-hide")) + { + toggle.removeClass("l-panel-header-toggle-hide"); + toggle.attr("title", p.collapseMessage); + } else + { + toggle.addClass("l-panel-header-toggle-hide"); + toggle.attr("title", p.expandMessage); + } + g.panel.find(".l-panel-content:first").toggle(); + }, + refresh : function() + { + var g = this, p = this.options; + g.set('url', p.url); + }, + _setShowToggle:function(v) + { + var g = this, p = this.options; + var header = g.panel.find(".l-panel-header:first"); + if (v) + { + var toggle = $("<a class='l-panel-icon l-panel-header-toggle'></a>"); + toggle.appendTo(header.find(".icons")); + toggle.attr("title", p.collapseMessage); + } else + { + header.find(".l-panel-header-toggle").remove(); + } + }, + _setContent: function (v) + { + var g = this, p = this.options; + var content = g.panel.find(".l-panel-content:first"); + if (v) + { + content.html(v); + } + }, + _setUrl: function (url) + { + var g = this, p = this.options; + var content = g.panel.find(".l-panel-content:first"); + if (url) + { + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + if(!g.jiframe) + { + g.jiframe = $("<iframe frameborder='0'></iframe>"); + var framename = p.frameName ? p.frameName : "ligerpanel" + new Date().getTime(); + g.jiframe.attr("name", framename); + g.jiframe.attr("id", framename); + content.prepend(g.jiframe); + g.jiframe[0].panel = g;//增加窗口对panel对象的引用 + + g.frame = window.frames[g.jiframe.attr("name")]; + } + setTimeout(function () + { + if (content.find(".l-panel-loading:first").length == 0) + content.append("<div class='l-panel-loading' style='display:block;'></div>"); + var iframeloading = $(".l-panel-loading:first", content); + + /* + 可以在子窗口这样使用: + var panel = frameElement.panel; + var panelData = dialog.get('data');//获取data参数 + panel.set('title','新标题'); //设置标题 + panel.close();//关闭panel + */ + g.jiframe.attr("src", url).bind('load.panel', function () + { + iframeloading.hide(); + g.trigger('loaded'); + }); + }, 0); + } + }, + _setShowClose: function (v) + { + var g = this, p = this.options; + var header = g.panel.find(".l-panel-header:first"); + if (v) + { + var btn = $("<a class='l-panel-icon l-panel-header-close'></a>"); + btn.appendTo(header.find(".icons")); + btn.attr("title", p.closeMessage); + } else + { + header.find(".l-panel-header-close").remove(); + } + }, + _setShowRefresh: function (v) + { + var g = this, p = this.options; + var header = g.panel.find(".l-panel-header:first"); + if (v) + { + var btn = $("<a class='l-panel-icon l-panel-header-refresh'></a>"); + btn.appendTo(header.find(".icons")); + btn.attr("title", p.refreshMessage); + } else + { + header.find(".l-panel-header-refresh").remove(); + } + }, + close:function() + { + var g = this, p = this.options; + if (g.trigger('close') == false) return; + g.panel.remove(); + g.trigger('closed'); + }, + show: function () + { + this.panel.show(); + }, + _setIcon : function(url) + { + var g = this; + if (!url) + { + g.panel.removeClass("l-panel-hasicon"); + g.panel.find('img').remove(); + } else + { + g.panel.addClass("l-panel-hasicon"); + g.panel.append('<img src="' + url + '" />'); + } + }, + _setWidth: function (value) + { + + if (typeof (value) == "string") + { + if (value.indexOf('%') > -1) + { + this.panel.width(value); + } + else + { + this.panel.width(parseInt(value)); + } + } else + { + this.panel.width(value); + } + }, + _setHeight: function (value) + { + var g = this, p = this.options; + var header = g.panel.find(".l-panel-header:first"); + this.panel.find(".l-panel-content:first").height(value - header.height()); + }, + _setTitle: function (value) + { + this.panel.find(".l-panel-header span:first").text(value); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerPopupEdit = function (options) + { + return $.ligerui.run.call(this, "ligerPopupEdit", arguments); + }; + + $.fn.ligerGetPopupEditManager = function () + { + return $.ligerui.run.call(this, "ligerGetPopupEditManager", arguments); + }; + + $.ligerDefaults.PopupEdit = { + valueFieldID: null, //生成的value input:hidden 字段名 + css: null, //附加css + onButtonClick: null, //利用这个参数来调用其他函数,比如打开一个新窗口来选择值 + nullText: null, //不能为空时的提示 + disabled: false, //是否无效 + method: 'post', //获取数据http方式 + async: true, + cancelable: true, + width: 200, + heigth: null, + render: null, //显示函数 + split: ';', + data: [], + grid: null, //在可查询、可分页列表的弹出框 中选择值 + condition: null, // 条件字段,比如 {fields:[{ name : 'Title' ,op : 'like', vt : 'string',type:'text' }]} + valueField: 'id', //值字段 + textField: 'text', //显示字段 + parms: null, + onSelect: null, //选择事件,可阻止 + onSelected: null, //选择后事件 + valueFieldCssClass: null, + searchClick: null //弹窗查询搜索按钮自定义函数 + }; + + + //扩展方法 + $.ligerMethos.PopupEdit = $.ligerMethos.PopupEdit || {}; + + $.ligerui.controls.PopupEdit = function (element, options) + { + $.ligerui.controls.PopupEdit.base.constructor.call(this, element, options); + }; + $.ligerui.controls.PopupEdit.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'PopupEdit'; + }, + _extendMethods: function () + { + return $.ligerMethos.PopupEdit; + }, + _init: function () + { + $.ligerui.controls.PopupEdit.base._init.call(this); + }, + _render: function () + { + var g = this, p = this.options; + g.inputText = null; + //文本框初始化 + if (this.element.tagName.toLowerCase() == "input") + { + this.element.readOnly = true; + g.inputText = $(this.element); + g.textFieldID = this.element.id; + } + if (g.inputText[0].name == undefined) g.inputText[0].name = g.textFieldID; + //隐藏域初始化 + g.valueField = null; + if (p.valueFieldID) + { + g.valueField = $("#" + p.valueFieldID + ":input"); + if (g.valueField.length == 0) g.valueField = $('<input type="hidden"/>'); + if (g.valueField[0].name == undefined) g.valueField[0].id = g.valueField[0].name = p.valueFieldID; + } + else + { + g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = g.textFieldID + "_val"; + } + if (g.valueField[0].name == undefined) g.valueField[0].name = g.valueField[0].id; + if (p.valueFieldCssClass) + { + g.valueField.addClass(p.valueFieldCssClass); + } + //开关 + g.link = $('<div class="l-trigger"><div class="l-trigger-icon"></div></div>'); + //外层 + g.wrapper = g.inputText.wrap('<div class="l-text l-text-popup"></div>').parent(); + g.wrapper.append('<div class="l-text-l"></div><div class="l-text-r"></div>'); + g.wrapper.append(g.link); + g.wrapper.append(g.valueField); + //修复popup控件没有data-ligerid的问题 + g.valueField.attr("data-ligerid", g.id); + g.inputText.addClass("l-text-field"); + //开关 事件 + g.link.hover(function () + { + if (p.disabled) return; + this.className = "l-trigger-hover"; + }, function () + { + if (p.disabled) return; + this.className = "l-trigger"; + }).mousedown(function () + { + if (p.disabled) return; + this.className = "l-trigger-pressed"; + }).mouseup(function () + { + if (p.disabled) return; + this.className = "l-trigger-hover"; + }).click(function () + { + if (p.disabled) return; + if (g.trigger('buttonClick') == false) return false; + }); + g.inputText.click(function () + { + if (p.disabled) return; + }).blur(function () + { + if (p.disabled) return; + g.wrapper.removeClass("l-text-focus"); + }).focus(function () + { + if (p.disabled) return; + g.wrapper.addClass("l-text-focus"); + }); + g.wrapper.hover(function () + { + if (p.disabled) return; + g.wrapper.addClass("l-text-over"); + }, function () + { + if (p.disabled) return; + g.wrapper.removeClass("l-text-over"); + }); + + g.set(p); + g.setTextByVal(g.getValue()); + //alert(g.getValue()); + }, + destroy: function () + { + if (this.wrapper) this.wrapper.remove(); + this.options = null; + $.ligerui.remove(this); + }, + clear: function () + { + var g = this, p = this.options; + g.inputText.val(""); + g.valueField.val(""); + }, + _setCss: function (css) + { + if (css) + { + this.wrapper.addClass(css); + } + }, + //取消选择 + _setCancelable: function (value) + { + var g = this, p = this.options; + if (!value && g.unselect) + { + g.unselect.remove(); + g.unselect = null; + } + if (!value && !g.unselect) return; + g.unselect = $('<div class="l-trigger l-trigger-cancel"><div class="l-trigger-icon"></div></div>').hide(); + g.wrapper.hover(function () + { + g.unselect.show(); + }, function () + { + g.unselect.hide(); + }) + if (!p.disabled && p.cancelable) + { + g.wrapper.append(g.unselect); + } + g.unselect.hover(function () + { + this.className = "l-trigger-hover l-trigger-cancel"; + }, function () + { + this.className = "l-trigger l-trigger-cancel"; + }).click(function () + { + g.clear(); + }); + }, + _setDisabled: function (value) + { + if (value) + { + this.wrapper.addClass('l-text-disabled'); + } else + { + this.wrapper.removeClass('l-text-disabled'); + } + }, + _setWidth: function (value) + { + var g = this; + if (value > 20) + { + g.wrapper.css({ width: value }); + g.inputText.css({ width: value - 20 }); + } + }, + _setHeight: function (value) + { + var g = this; + if (value > 10) + { + g.wrapper.height(value); + g.inputText.height(value - 2); + } + }, + getData: function () + { + var g = this, p = this.options; + var data = []; + var v = $(g.valueField).val(), t = $(g.inputText).val(); + var values = v ? v.split(p.split) : null, texts = t ? t.split(p.split) : null; + $(values).each(function (i) + { + var o = {}; + o[p.textField] = texts[i]; + o[p.valueField] = values[i]; + data.push(o); + }); + return data; + }, + _getText: function () + { + return $(this.inputText).val(); + }, + _getValue: function () + { + return $(this.valueField).val(); + }, + getValue: function () + { + return this._getValue(); + }, + getText: function () + { + return this._getText(); + }, + //设置值到 隐藏域 + setValue: function (value, text) + { + if (value == '') return; + var g = this, p = this.options; + if (arguments.length >= 2) + { + g.setValue(value); + g.setText(text); + return; + } + g.valueField.val(value); + //g.setTextByVal(value); + }, + //根据值设置文本 value:数值或文本 + setTextByVal: function (value) + { + value = (typeof (value) != "string") ? value.toString : value; + if (value == '') return; + + var g = this, text = [], p = this.options, gridData = []; + if (g.valueField.val() != value) g.valueField.val(value); + + var gridparms = p.grid; + if ($.isFunction(gridparms)) gridparms = gridparms(); + var gridOptions = $.extend({ + parms: p.parms + }, gridparms); + + if (p.data.length > 0) + { + gridData = p.data.Rows; + } else if (gridOptions.url) + { + g.loadServerData(gridOptions.url, value); + return; + } else + { + gridData = gridOptions.data.Rows; + } + + + var values = value.split(p.split); + + $(gridData).each(function (i, rowdata) + { + if ($.inArray(rowdata[p.valueField], values) != -1) + { + text.push(rowdata[p.textField]); + } + }); + text = text.join(p.split); + g.setText(text); + }, + loadServerData: function (param, value) + { + var g = this, p = this.options, gdata = []; + if ($.isFunction(param)) param = param(); + var ajaxOptions = { + type: p.method, + url: param, + async: p.async, + //data: [], + dataType: 'json', + success: function (data) + { + //g.trigger('success', [data, g]); + gridData = $.extend(true, {}, data); + p.data = gridData; + gridData = data.Rows; + var values = value.split(p.split); + var text = []; + + $(gridData).each(function (i, rowdata) + { + if ($.inArray(rowdata[p.valueField], values) != -1) + { + text.push(rowdata[p.textField]); + } + }); + text = text.join(p.split); + g.setText(text); + return; + }, + error: function (XMLHttpRequest, textStatus, errorThrown) + { + return; + } + + } + $.ajax(ajaxOptions); + + }, + //设置值到 文本框 + setText: function (text) + { + var g = this, p = this.options; + if (p.render) + { + g.inputText.val(p.render(text)); + } + else + { + g.inputText.val(text); + } + }, + addValue: function (value, text) + { + var g = this, p = this.options; + if (!value) return; + var v = g.getValue(), t = g.getText(); + if (!v) + { + g.setValue(value); + g.setText(text); + } else + { + var arrV = [], arrT = [], old = v.split(p.split), value = value.split(p.split), text = text.split(p.split); + for (var i = 0, l = value.length; i < l; i++) + { + if ($.inArray(value[i], old) == -1) + { + arrV.push(value[i]); + arrT.push(text[i]); + } + } + if (arrV.length) + { + g.setValue(v + p.split + arrV.join(p.split)); + g.setText(t + p.split + arrT.join(p.split)); + } + } + }, + removeValue: function (value, text) + { + var g = this, p = this.options; + if (!value) return; + var v = g.getValue(), t = g.getText(); + if (!v) return; + var oldV = v.split(p.split), oldT = t.split(p.split), value = value.split(p.split); + for (var i = 0, index = -1, l = value.length; i < l; i++) + { + if ((index = $.inArray(value[i], oldV)) != -1) + { + oldV.splice(index, 1); + oldT.splice(index, 1); + } + } + g.setValue(oldV.join(p.split)); + g.setText(oldT.join(p.split)); + }, + _setGrid: function (value) + { + if (!value) return; + var g = this, p = this.options; + var gridOptions = $.extend({ + parms: p.parms + }, p.grid); + + this.bind('buttonClick', function () + { + function getLastSelected() + { + try{ + return g.getData(); + } catch (e) + { + return null; + } + } + if (!g.popupFn) + { + var options = { + grid: gridOptions, + condition: p.condition, + valueField: p.valueField, + textField: p.textField, + split: p.split, + searchClick : p.searchClick, + lastSelected: getLastSelected(), + onSelect: function (e) + { + if (g.trigger('select', e) == false) return; + if (p.grid.checkbox) + { + g.addValue(e.value, e.text); + g.removeValue(e.remvoeValue, e.remvoeText); + } else + { + g.setValue(e.value); + g.setText(e.text); + } + g.trigger('selected', e); + }, + selectInit: function (rowdata) + { + var value = g.getValue(); + if (!value) return false; + if (!p.valueField || !rowdata[p.valueField]) return false; + return $.inArray(rowdata[p.valueField].toString(), value.split(p.split)) != -1; + } + }; + g.popupFn = $.ligerui.getPopupFn(options, g); + } + g.popupFn(); + }); + } + }); + + + + //创建一个可查询、可分页列表的选取弹出框 需要dialog,grid,form等插件的支持 + $.ligerui.getPopupFn = function (p,master) + { + p = $.extend({ + title: '选择数据', //窗口标题 + width: 700, //窗口宽度 + height: 320, //列表高度 + top: null, + left: null, + split: ';', + valueField: null, //接收表格的value字段名 + textField: null, //接收表格的text字段名 + grid: null, //表格的参数 同ligerGrid + condition: null, //搜索表单的参数 同ligerForm + onSelect: function (p) { }, //选取函数 + searchClick : p.searchClick, + selectInit: function (rowdata) { return false } //选择初始化 + }, p); + if (!p.grid) return; + var win, grid, condition, lastSelected = p.lastSelected || []; + return function () + { + show(); + return false; + }; + function show() + { + function getGridHeight(height) + { + height = height || p.height; + height -= conditionPanel.height(); + return height; + } + if (win) + { + grid._showData(); + win.show(); + grid.refreshSize(); + lastSelected = grid.selected.concat(); + return; + } + var panle = $("<div></div>"); + var conditionPanel = $("<div></div>"); + var gridPanel = $("<div></div>"); + panle.append(conditionPanel).append(gridPanel); + + if (p.condition) + { + var conditionParm = $.extend({ + labelWidth: 60, + space: 20 + }, p.condition); + setTimeout(function () + { + condition = conditionPanel.ligerForm(conditionParm); + }, 50); + } else + { + conditionPanel.remove(); + } + var gridParm = $.extend({ + columnWidth: 120, + alternatingRow: false, + frozen: true, + rownumbers: true + }, p.grid, { + width: "100%", + height: getGridHeight(), + isChecked: p.selectInit, + isSelected: p.selectInit, + inWindow: false + }); + //grid + grid = gridPanel.ligerGrid(gridParm); + //搜索按钮 + if (p.condition) + { + + setTimeout(function () + { + var containerBtn1 = $('<li style="margin-right:9px"><div></div></li>'); + $("ul:first", conditionPanel).append(containerBtn1).after('<div class="l-clear"></div>'); + $("div", containerBtn1).ligerButton({ + text: '搜索', + click: function () + { + var rules = condition.toConditions(); + if (p.searchClick) + { + p.searchClick({ + grid: grid, + rules: rules + }); + } else + { + if (grid.get('url')) + { + grid.setParm(grid.conditionParmName || 'condition', $.ligerui.toJSON(rules)); + grid.reload(); + } else + { + grid.loadData($.ligerFilter.getFilterFunction(rules)); + } + } + } + }); + }, 100); + } + //dialog + win = $.ligerDialog.open({ + title: p.title, + width: p.width, + height: 'auto', + top: p.top, + left: p.left, + target: panle, + isResize: true, + cls: 'l-selectorwin', + onContentHeightChange: function (height) + { + grid.set('height', getGridHeight(height)); + return false; + }, + onStopResize: function () + { + grid.refreshSize(); + }, + buttons: [ + { text: '选择', onclick: function (item, dialog) { toSelect(); dialog.hide(); } }, + { text: '取消', onclick: function (item, dialog) { dialog.hide(); } } + ] + }); + + if (master) + { + master.includeControls = master.includeControls || []; + master.includeControls.push(win); + } + grid.refreshSize(); + } + function exist(value, data) + { + for (var i = 0; data && data[i]; i++) + { + var item = data[i]; + if (item[p.valueField] == value) return true; + } + return false; + } + function toSelect() + { + var selected = grid.selected || []; + var value = [], text = [], data = []; + $(selected).each(function (i, rowdata) + { + p.valueField && value.push(rowdata[p.valueField]); + p.textField && text.push(rowdata[p.textField]); + var o = $.extend(true, {}, this); + grid.formatRecord(o, true); + data.push(o); + }); + var unSelected = []; + $(lastSelected).each(function (i, item) + { + if (!exist(item[p.valueField], selected) && exist(item[p.valueField], grid.rows)) + { + unSelected.push(item); + } + }); + var removeValue = [], removeText = [], removeData = []; + $(unSelected).each(function (i, rowdata) + { + p.valueField && removeValue.push(rowdata[p.valueField]); + p.textField && removeText.push(rowdata[p.textField]); + var o = $.extend(true, {}, this); + grid.formatRecord(o, true); + removeData.push(o); + }); + p.onSelect({ + value: value.join(p.split), + text: text.join(p.split), + data: data, + remvoeValue: removeValue.join(p.split), + remvoeText: removeText.join(p.split), + removeData: removeData + }); + } + }; + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerPortal = function (options) + { + return $.ligerui.run.call(this, "ligerPortal", arguments); + }; + + $.ligerDefaults.Portal = { + width: null, + /*行元素:组件允许以纵向方式分割为几块 + 每一块(行)允许自定义N个列(column) + 每一列允许自定义N个Panel(最小元素) + rows:[ + {columns:[ + { + width : '50%', + panels : [{width:'100%',content:'内容'},{width:'100%',url:@url1}] + },{ + width : '50%', + panels : [{width:'100%',url:@url2}] + } + ]} + ] + */ + rows: null, + /* 列元素: 组件将认为只存在一个row(块), + 这一块 允许自定义N个列(column),结构同上 + */ + columns:null, + url: null, //portal结构定义URL + method: 'get', //获取数据http方式 + parms: null, //提交到服务器的参数 + draggable: false, //是否允许拖拽 + onLoaded:null //url模式 加载完事件 + }; + $.ligerDefaults.Portal_rows = { + width: null, + height: null + }; + $.ligerDefaults.Portal_columns = { + width: null, + height: null + }; + + $.ligerMethos.Portal = {}; + + + + $.ligerui.controls.Portal = function (element, options) + { + $.ligerui.controls.Portal.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Portal.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Portal'; + }, + __idPrev: function () + { + return 'Portal'; + }, + _extendMethods: function () + { + return $.ligerMethos.Portal; + }, + _init: function () + { + var g = this, p = this.options; + $.ligerui.controls.Portal.base._init.call(this); + if ($(">div", g.element).length) //如果已经定义了DIV子元素,那么这些元素将会转换为columns,这里暂时保存到tempInitPanels + { + p.columns = []; + $(">div", g.element).each(function (i, jpanel) + { + p.columns[i] = { + panels :[] + }; + }); + + g.tempInitPanels = $("<div></div>"); + $(">div", g.element).appendTo(g.tempInitPanels); + } + if (!p.rows && p.columns) + { + p.rows = [{ + columns: p.columns + }]; + } + }, + _render: function () + { + var g = this, p = this.options; + + g.portal = $(g.element).addClass("l-portal").html(""); + + g.set(p); + + }, + _setRows: function (rows) + { + var g = this, p = this.options; + g.rows = []; + if (rows && rows.length) + { + for (var i = 0; i < rows.length; i++) + { + var row = rows[i]; + var jrow = $('<div class="l-row"></div>').appendTo(g.portal); + g.rows[i] = g._renderRow({ + row: row, + rowIndex: i, + jrow: jrow + }); + jrow.append('<div class="l-clear"></div>'); + } + } + }, + _renderRow : function(e) + { + var row = e.row, rowIndex = e.rowIndex, jrow = e.jrow; + var g = this, p = this.options; + var rowObj = { + element : jrow[0] + }; + if (row.width) + { + if (typeof (row.width) == "string") + { + if (row.width.indexOf('%') > -1 ) + { + jrow.width(row.width); + } + else + { + jrow.width(parseInt(row.width)); + } + } else + { + jrow.width(row.width); + } + } + if (row.height) jrow.height(row.height); + if (row.columns) rowObj.columns = []; + if (row.columns && row.columns.length) + { + for (var i = 0; i < row.columns.length; i++) + { + var column = row.columns[i]; + var jcolumn = $('<div class="l-column"></div>').appendTo(jrow); + rowObj.columns[i] = g._renderColumn({ + column: column, + columnIndex: i, + jcolumn: jcolumn, + rowIndex : rowIndex + }); + } + } + return rowObj; + }, + remove: function (e) + { + var g = this, p = this.options; + var rowIndex = e.rowIndex, columnIndex = e.columnIndex, index = e.index; + if (index == null) index = -1; + if (index >= 0 && g.rows[rowIndex] && g.rows[rowIndex].columns && g.rows[rowIndex].columns[columnIndex] && g.rows[rowIndex].columns[columnIndex].panels) + { + var panel = g.rows[rowIndex].columns[columnIndex].panels[index]; + panel && panel.close(); + g._updatePortal(); + } + }, + add: function (e) + { + var g = this, p = this.options; + var rowIndex = e.rowIndex, columnIndex = e.columnIndex, index = e.index, panel = e.panel; + if (index == null) index = -1; + if (!(g.rows[rowIndex] && g.rows[rowIndex].columns && g.rows[rowIndex].columns[columnIndex])) return; + var gColumn = g.rows[rowIndex].columns[columnIndex], pColumn = p.rows[rowIndex].columns[columnIndex], ligerPanel, jcolumn = $(gColumn.element); + pColumn.panels = pColumn.panels || []; + gColumn.panels = gColumn.panels || []; + pColumn.panels.splice(index, 0, panel); + if (index < 0) + { + var jpanel = $('<div></div>').insertBefore(gColumn.jplace); + ligerPanel = jpanel.ligerPanel(panel); + } else if(gColumn.panels[index]) + { + var jpanel = $('<div></div>').insertBefore(gColumn.panels[index].panel); + ligerPanel = jpanel.ligerPanel(panel); + } + if (ligerPanel) + { + ligerPanel.bind('closed', g._createPanelClosed()); + g.setPanelEvent({ + panel: ligerPanel + }); + gColumn.panels.splice(index, 0, ligerPanel); + } + g._updatePortal(); + }, + _createPanelClosed : function () + { + var g = this, p = this.options; + return function () + { + var panel = this;//ligerPanel对象 + var panels = g.getPanels(); + var rowIndex, columnIndex, index; + $(panels).each(function () + { + if (this.panel == panel) + { + rowIndex = this.rowIndex; + columnIndex = this.columnIndex; + index = this.index; + } + }); + p.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); + g.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); + }; + }, + _renderColumn: function (e) + { + var column = e.column, columnIndex = e.columnIndex, jcolumn = e.jcolumn; + var rowIndex = e.rowIndex; + var g = this, p = this.options; + var columnObj = { + element : jcolumn[0] + }; + if (column.width) jcolumn.width(column.width); + if (column.height) jcolumn.height(column.height); + if (column.panels) columnObj.panels = []; + if (column.panels && column.panels.length) + { + for (var i = 0; i < column.panels.length; i++) + { + var panel = column.panels[i]; + var jpanel = $('<div></div>').appendTo(jcolumn); + columnObj.panels[i] = jpanel.ligerPanel(panel); + columnObj.panels[i].bind('closed', g._createPanelClosed()); + g.setPanelEvent({ + panel: columnObj.panels[i] + }); + } + } else if(g.tempInitPanels) + { + + var tempPanel = g.tempInitPanels.find(">div:eq(" + columnIndex + ")"); + if (tempPanel.length) + { + columnObj.panels = []; + var panelOptions = {}; + var jelement = tempPanel.clone(); + if (liger.inject && liger.inject.getOptions) + { + panelOptions = liger.inject.getOptions({ + jelement: jelement, + defaults: $.ligerDefaults.Panel, + config: liger.inject.config.Panel + }); + } + columnObj.panels[0] = jelement.appendTo(jcolumn).ligerPanel(panelOptions); + columnObj.panels[0].bind('closed', g._createPanelClosed()); + g.setPanelEvent({ + panel: columnObj.panels[0] + }); + } + } + columnObj.jplace = $('<div class="l-column-place"></div>').appendTo(jcolumn); + return columnObj; + }, + setPanelEvent: function(e) + { + //panel:ligerui对象,jpanel:jQuery dom对象 + var panel = e.panel, jpanel = panel.panel; + var g = this, p = this.options; + //拖拽支持 + if ($.fn.ligerDrag && p.draggable) + { + jpanel.addClass("l-panel-draggable").ligerDrag({ + proxy: false, revert: true, + handler: ".l-panel-header span:first", + onRendered: function () + { + }, + onStartDrag: function (current, e) + { + g.portal.find(">.l-row").addClass("l-row-dragging"); + this.jplace = $('<div class="l-panel-place"></div>'); + this.jplace.height(jpanel.height()); + jpanel.width(jpanel.width()); + jpanel.addClass("l-panel-dragging"); + jpanel.css("position", "absolute"); + jpanel.after(this.jplace); + g._updatePortal(); + }, + onDrag: function (current, e) + { + var pageX = e.pageX || e.screenX, pageY = e.pageY || e.screenY; + var height = jpanel.height(), width = jpanel.width(), offset = jpanel.offset(); + var centerX = offset.left + width / 2, centerY = offset.top + 10; + var panels = g.getPanels(), emptyColumns = g.getEmptyColumns(); + var result = getPositionIn(panels, emptyColumns, centerX, centerY); + if (result) + { + //判断是否跟上次匹配的位置一致 + if (this.placeStatus) + { + if (this.placeStatus.panel && result.panel) + { + if (this.placeStatus.panel.rowIndex == result.panel.rowIndex && + this.placeStatus.panel.columnIndex == result.panel.columnIndex && + this.placeStatus.panel.index == result.panel.index && + this.placeStatus.position == result.position) + { + return; + } + } + if (this.placeStatus.column && result.column) //定位到空元素行 + { + if (this.placeStatus.column.rowIndex == result.column.rowIndex && this.placeStatus.column.columnIndex == result.column.columnIndex && this.placeStatus.position == result.position) + { + return; + } + } + } + if (result.position == "top") + { + this.jplace.insertBefore(result.panel ? result.panel.jpanel : result.column.jplace); + this.savedPosition = result.panel ? result.panel : result.column + this.savedPosition.inTop = true; + } else if (result.position == "bottom") + { + this.jplace.insertAfter(result.panel.jpanel); + this.savedPosition = result.panel; + this.savedPosition.inTop = false; + } + this.placeStatus = result; + } + else//没有匹配到 + { + this.placeStatus = null; + } + + //从指定的元素集合匹配位置 + function getPositionIn(panels, columns, x, y) + { + for (i = 0, l = panels.length; i < l; i++) + { + var o = panels[i]; + if (o.panel == panel) //如果是本身 + { + continue; + } + var r = positionIn(o, null, x, y); + if (r) return r; + } + for (i = 0, l = columns.length; i < l; i++) + { + var column = columns[i]; + var r = positionIn(null, column, x, y); + if (r) return r; + } + return null; + } + //坐标在目标区域范围内 x,y为panel标题栏中间的位置 + function positionIn(panel, column, x, y) + { + var jelement = panel ? panel.jpanel : column.jplace; + if (!jelement) return null; + var height = jelement.height(), width = jelement.width(); + var left = jelement.offset().left, top = jelement.offset().top; + var diff = 3; + if (x > left - diff && x < left + width + diff) + { + if (y > top - diff && y < top + height / 2 + diff) + { + return { + panel: panel, + column: column, + position: "top" + }; + } + if (y > top + height / 2 - diff && y < top + height + diff) + { + return { + panel: panel, + column: column, + position: panel ? "bottom" : "top" + }; + } + } + return null; + } + }, + onStopDrag: function (current, e) + { + g.portal.find(">.l-row").removeClass("l-row-dragging"); + panel.set('width', panel.get('width')); + jpanel.removeClass("l-panel-dragging"); + //将jpanel替换到jplace的位置 + if (this.jplace) + { + jpanel.css({ + "position": "relative", + "left": null, + "top": null + }); + jpanel.insertAfter(this.jplace); + g.portal.find(">.l-row > .l-column >.l-panel-place").remove(); + + if (this.savedPosition) + { + var panels = g.getPanels(); + var rowIndex, columnIndex, index; + $(panels).each(function () + { + if (this.panel == panel) + { + rowIndex = this.rowIndex; + columnIndex = this.columnIndex; + index = this.index; + } + }); + var oldPanelOptions = p.rows[rowIndex].columns[columnIndex].panels[index]; + var oldPanel = g.rows[rowIndex].columns[columnIndex].panels[index]; + p.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); + g.rows[rowIndex].columns[columnIndex].panels.splice(index, 1); + + if (this.savedPosition.panel) + { + + p.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels.splice(this.savedPosition.index + this.savedPosition.inTop ? -1 : 0, 0, oldPanelOptions); + g.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels.splice(this.savedPosition.index + this.savedPosition.inTop ? -1 : 0, 0, oldPanel); + } else + { + p.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels = [oldPanelOptions]; + g.rows[this.savedPosition.rowIndex].columns[this.savedPosition.columnIndex].panels = [oldPanel]; + } + } + } + g._updatePortal(); + + return false; + } + }); + } + + }, + _updatePortal:function() + { + var g = this, p = this.options; + $(g.rows).each(function (rowIndex) + { + $(this.columns).each(function (columnIndex) + { + if (this.panels && this.panels.length) + { + $(this.element).removeClass("l-column-empty"); + } else + { + $(this.element).addClass("l-column-empty"); + } + }); + }); + }, + getPanels : function () + { + var g = this, p = this.options; + var panels = []; + $(g.rows).each(function (rowIndex) + { + $(this.columns).each(function (columnIndex) + { + $(this.panels).each(function (index) + { + panels.push({ + rowIndex: rowIndex, + columnIndex: columnIndex, + index: index, + panel : this, + jpanel : this.panel + }); + }); + }); + }); + return panels; + }, + getPanel: function (e) + { + var g = this, p = this.options; + e = $.extend({ + rowIndex: 0, + columnIndex: 0, + index : 0 + }, e); + var panel = null; + $(g.rows).each(function (rowIndex) + { + $(this.columns).each(function (columnIndex) + { + $(this.panels).each(function (index) + { + if (panel) return; + if (rowIndex == e.rowIndex && columnIndex == e.columnIndex && index == e.index) + { + panel = this; + } + }); + }); + }); + return panel; + }, + getEmptyColumns:function(){ + var g = this, p = this.options; + var columns = []; + $(g.rows).each(function (rowIndex) + { + $(this.columns).each(function (columnIndex) + { + if (!this.panels || !this.panels.length) + { + columns.push({ + rowIndex: rowIndex, + columnIndex: columnIndex, + jplace : this.jplace + }); + } + }); + }); + return columns; + }, + _setUrl: function (url) + { + var g = this, p = this.options; + if (!url) return; + $.ajax({ + url: url, data: p.parms, type: p.method, dataType: 'json', + success: function (rows) + { + g.set('rows', rows); + } + }); + }, + _setWidth: function (value) + { + value && this.portal.width(value); + }, + collapseAll: function () + { + var g = this, p = this.options; + var panels = g.getPanels(); + $(panels).each(function (i,o) + { + var panel = o.panel; + panel.collapse(); + }); + }, + expandAll: function () + { + var g = this, p = this.options; + var panels = g.getPanels(); + $(panels).each(function (i, o) + { + var panel = o.panel; + panel.expand(); + }); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ + +(function ($) +{ + + $.fn.ligerRadio = function () + { + return $.ligerui.run.call(this, "ligerRadio", arguments); + }; + + $.fn.ligerGetRadioManager = function () + { + return $.ligerui.run.call(this, "ligerGetRadioManager", arguments); + }; + + $.ligerDefaults.Radio = { disabled: false }; + + $.ligerMethos.Radio = {}; + + $.ligerui.controls.Radio = function (element, options) + { + $.ligerui.controls.Radio.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Radio.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'Radio'; + }, + __idPrev: function () + { + return 'Radio'; + }, + _extendMethods: function () + { + return $.ligerMethos.Radio; + }, + _render: function () + { + var g = this, p = this.options; + g.input = $(this.element); + g.link = $('<a href="javascript:void(0)" class="l-radio"></a>'); + g.wrapper = g.input.addClass('l-hidden').wrap('<div class="l-radio-wrapper"></div>').parent(); + g.wrapper.prepend(g.link); + g.input.change(function () + { + if (this.checked) + { + g.link.addClass('l-radio-checked'); + } + else + { + g.link.removeClass('l-radio-checked'); + } + return true; + }); + g.link.click(function () + { + g._doclick(); + }); + g.wrapper.hover(function () + { + if (!p.disabled) + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + this.element.checked && g.link.addClass('l-radio-checked'); + + if (this.element.id) + { + $("label[for=" + this.element.id + "]").click(function () + { + g._doclick(); + }); + } + g.set(p); + }, + setValue: function (value) + { + var g = this, p = this.options; + if (!value) + { + g.input[0].checked = false; + g.link.removeClass('l-radio-checked'); + } + else + { + g.input[0].checked = true; + g.link.addClass('l-radio-checked'); + } + }, + getValue: function () + { + return this.input[0].checked; + }, + setEnabled: function () + { + this.input.attr('disabled', false); + this.wrapper.removeClass("l-disabled"); + this.options.disabled = false; + }, + setDisabled: function () + { + this.input.attr('disabled', true); + this.wrapper.addClass("l-disabled"); + this.options.disabled = true; + }, + updateStyle: function () + { + if (this.input.attr('disabled')) + { + this.wrapper.addClass("l-disabled"); + this.options.disabled = true; + } + if (this.input[0].checked) + { + this.link.addClass('l-checkbox-checked'); + } + else + { + this.link.removeClass('l-checkbox-checked'); + } + }, + _doclick: function () + { + var g = this, p = this.options; + if (g.input.attr('disabled')) { return false; } + g.input.trigger('click').trigger('change'); + var formEle; + if (g.input[0].form) formEle = g.input[0].form; + else formEle = document; + $("input:radio[name=" + g.input[0].name + "]", formEle).not(g.input).trigger("change"); + return false; + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerRadioList = function (options) + { + return $.ligerui.run.call(this, "ligerRadioList", arguments); + }; + + $.ligerDefaults.RadioList = { + rowSize: 3, //每行显示元素数 + valueField: 'id', //值成员 + textField: 'text', //显示成员 + valueFieldID: null, //隐藏域 + name: null, //表单名 + data: null, //数据 + parms: null, //ajax提交表单 + url: null, //数据源URL(需返回JSON) + urlParms: null, //url带参数 + ajaxContentType: null, + ajaxType: 'post', + onSuccess: null, + onError: null, + onSelect: null, + css: null, //附加css + value: null, //值 + valueFieldCssClass: null + }; + + //扩展方法 + $.ligerMethos.RadioList = $.ligerMethos.RadioList || {}; + + + $.ligerui.controls.RadioList = function (element, options) + { + $.ligerui.controls.RadioList.base.constructor.call(this, element, options); + }; + $.ligerui.controls.RadioList.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'RadioList'; + }, + _extendMethods: function () + { + return $.ligerMethos.RadioList; + }, + _init: function () + { + $.ligerui.controls.RadioList.base._init.call(this); + }, + _render: function () + { + var g = this, p = this.options; + g.data = p.data; + g.valueField = null; //隐藏域(保存值) + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.valueField = $(this.element); + if ($(this.element).is(":text")) + { + g.valueField.hide(); + } + } + else if (p.valueFieldID) + { + g.valueField = $("#" + p.valueFieldID + ":input,[name=" + p.valueFieldID + "]:input"); + if (g.valueField.length == 0) g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = p.valueFieldID; + } + else + { + g.valueField = $('<input type="hidden"/>'); + g.valueField[0].id = g.valueField[0].name = g.id + "_val"; + } + if (g.valueField[0].name == null) g.valueField[0].name = g.valueField[0].id; + if (p.valueFieldCssClass) + { + g.valueField.addClass(p.valueFieldCssClass); + } + g.valueField.attr("data-ligerid", g.id); + + + if ($(this.element).is(":hidden") || $(this.element).is(":text")) + { + g.radioList = $('<div></div>').insertBefore(this.element); + } else + { + g.radioList = $(this.element); + } + g.radioList.html('<div class="l-radiolist-inner"><table cellpadding="0" cellspacing="0" border="0" class="l-radiolist-table"></table></div>').addClass("l-radiolist").append(g.valueField); + g.radioList.table = $("table:first", g.radioList); + + + p.value = g.valueField.val() || p.value; + + g.set(p); + + g._addClickEven(); + }, + destroy: function () + { + if (this.radioList) this.radioList.remove(); + this.options = null; + $.ligerui.remove(this); + }, + clear: function () + { + this._changeValue(""); + this.trigger('clear'); + }, + _setCss: function (css) + { + if (css) + { + this.radioList.addClass(css); + } + }, + _setDisabled: function (value) + { + //禁用样式 + if (value) + { + this.radioList.addClass('l-radiolist-disabled'); + $("input:radio", this.radioList).attr("disabled", true); + } else + { + this.radioList.removeClass('l-radiolist-disabled'); + $("input:radio", this.radioList).removeAttr("disabled"); + } + }, + _setWidth: function (value) + { + this.radioList.width(value); + }, + _setHeight: function (value) + { + this.radioList.height(value); + }, + indexOf: function (item) + { + var g = this, p = this.options; + if (!g.data) return -1; + for (var i = 0, l = g.data.length; i < l; i++) + { + if (typeof (item) == "object") + { + if (g.data[i] == item) return i; + } else + { + if (g.data[i][p.valueField].toString() == item.toString()) return i; + } + } + return -1; + }, + removeItems: function (items) + { + var g = this; + if (!g.data) return; + $(items).each(function (i, item) + { + var index = g.indexOf(item); + if (index == -1) return; + g.data.splice(index, 1); + }); + g.refresh(); + }, + removeItem: function (item) + { + if (!this.data) return; + var index = this.indexOf(item); + if (index == -1) return; + this.data.splice(index, 1); + this.refresh(); + }, + insertItem: function (item, index) + { + var g = this; + if (!g.data) g.data = []; + g.data.splice(index, 0, item); + g.refresh(); + }, + addItems: function (items) + { + var g = this; + if (!g.data) g.data = []; + $(items).each(function (i, item) + { + g.data.push(item); + }); + g.refresh(); + }, + addItem: function (item) + { + var g = this; + if (!g.data) g.data = []; + g.data.push(item); + g.refresh(); + }, + _setValue: function (value) + { + var g = this, p = this.options; + g.valueField.val(value); + p.value = value; + this._dataInit(); + }, + setValue: function (value) + { + this._setValue(value); + }, + _setUrl: function (url) + { + var g = this, p = this.options; + if (!url) return; + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var parms = $.isFunction(p.parms) ? p.parms() : p.parms; + if (p.ajaxContentType == "application/json" && typeof (parms) != "string") + { + parms = liger.toJSON(parms); + } + $.ajax({ + type: 'post', + url: url, + data: parms, + cache: false, + dataType: 'json', + contentType: p.ajaxContentType, + success: function (data) + { + g.setData(data); + g.trigger('success', [data]); + }, + error: function (XMLHttpRequest, textStatus) + { + g.trigger('error', [XMLHttpRequest, textStatus]); + } + }); + }, + setUrl: function (url) + { + return this._setUrl(url); + }, + setParm: function (name, value) + { + if (!name) return; + var g = this; + var parms = g.get('parms'); + if (!parms) parms = {}; + parms[name] = value; + g.set('parms', parms); + }, + clearContent: function () + { + var g = this, p = this.options; + $("table", g.radioList).html(""); + }, + _setData: function (data) + { + this.setData(data); + }, + setData: function (data) + { + var g = this, p = this.options; + if (!data || !data.length) return; + g.data = data; + g.refresh(); + g.updateStyle(); + }, + refresh: function () + { + var g = this, p = this.options, data = this.data; + this.clearContent(); + if (!data) return; + var out = [], rowSize = p.rowSize, appendRowStart = false, name = p.name || g.id; + for (var i = 0; i < data.length; i++) + { + var val = data[i][p.valueField], txt = data[i][p.textField], id = g.id + "-" + i; + var newRow = i % rowSize == 0; + //0,5,10 + if (newRow) + { + if (appendRowStart) out.push('</tr>'); + out.push("<tr>"); + appendRowStart = true; + } + out.push("<td><input type='radio' name='" + name + "' value='" + val + "' id='" + id + "'/><label for='" + id + "'>" + txt + "</label></td>"); + } + if (appendRowStart) out.push('</tr>'); + g.radioList.table.append(out.join('')); + }, + _getValue: function () + { + var g = this, p = this.options, name = p.name || g.id; + return $('input:radio[name="' + name + '"]:checked').val(); + }, + getValue: function () + { + //获取值 + return this._getValue(); + }, + updateStyle: function () + { + var g = this, p = this.options; + g._dataInit(); + $(":radio", g.element).change(function () + { + var value = g.getValue(); + g.trigger('select', [{ + value: value + }]); + }); + }, + _dataInit: function () + { + var g = this, p = this.options; + var value = g.valueField.val() || g._getValue() || p.value; + g._changeValue(value); + }, + //设置值到 隐藏域 + _changeValue: function (newValue) + { + var g = this, p = this.options, name = p.name || g.id; + $("input:radio[name='" + name + "']", g.radioList).each(function () + { + this.checked = this.value == newValue; + }); + g.valueField.val(newValue); + g.selectedValue = newValue; + }, + _addClickEven: function () + { + var g = this, p = this.options; + //选项点击 + g.radioList.click(function (e) + { + var value = g.getValue(); + if (value) g.valueField.val(value); + }); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerResizable = function (options) + { + return $.ligerui.run.call(this, "ligerResizable", arguments, + { + idAttrName: 'ligeruiresizableid', hasElement: false, propertyToElemnt: 'target' + }); + }; + + $.fn.ligerGetResizableManager = function () + { + return $.ligerui.run.call(this, "ligerGetResizableManager", arguments, + { + idAttrName: 'ligeruiresizableid', hasElement: false, propertyToElemnt: 'target' + }); + }; + + + $.ligerDefaults.Resizable = { + handles: 'n, e, s, w, ne, se, sw, nw', + maxWidth: 2000, + maxHeight: 2000, + minWidth: 20, + minHeight: 20, + scope: 3, + animate: false, + onStartResize: function (e) { }, + onResize: function (e) { }, + onStopResize: function (e) { }, + onEndResize: null + }; + + $.ligerui.controls.Resizable = function (options) + { + $.ligerui.controls.Resizable.base.constructor.call(this, null, options); + }; + + $.ligerui.controls.Resizable.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Resizable'; + }, + __idPrev: function () + { + return 'Resizable'; + }, + _render: function () + { + var g = this, p = this.options; + g.target = $(p.target); + g.set(p); + + g.target.mousemove(function (e) + { + if (p.disabled) return; + g.dir = g._getDir(e); + if (g.dir) + g.target.css('cursor', g.dir + '-resize'); + else if (g.target.css('cursor').indexOf('-resize') > 0) + g.target.css('cursor', 'default'); + if (p.target.ligeruidragid) + { + var drag = $.ligerui.get(p.target.ligeruidragid); + if (drag && g.dir) + { + drag.set('disabled', true); + } else if (drag) + { + drag.set('disabled', false); + } + } + }).mousedown(function (e) + { + if (p.disabled) return; + if (g.dir) + { + g._start(e); + } + }); + }, + _rendered: function () + { + this.options.target.ligeruiresizableid = this.id; + }, + _getDir: function (e) + { + var g = this, p = this.options; + var dir = ''; + var xy = g.target.offset(); + var width = g.target.width(); + var height = g.target.height(); + var scope = p.scope; + var pageX = e.pageX || e.screenX; + var pageY = e.pageY || e.screenY; + if (pageY >= xy.top && pageY < xy.top + scope) + { + dir += 'n'; + } + else if (pageY <= xy.top + height && pageY > xy.top + height - scope) + { + dir += 's'; + } + if (pageX >= xy.left && pageX < xy.left + scope) + { + dir += 'w'; + } + else if (pageX <= xy.left + width && pageX > xy.left + width - scope) + { + dir += 'e'; + } + if (p.handles == "all" || dir == "") return dir; + if ($.inArray(dir, g.handles) != -1) return dir; + return ''; + }, + _setHandles: function (handles) + { + if (!handles) return; + this.handles = handles.replace(/(\s*)/g, '').split(','); + }, + _createProxy: function () + { + var g = this; + g.proxy = $('<div class="l-resizable"></div>'); + g.proxy.width(g.target.width()).height(g.target.height()) + g.proxy.attr("resizableid", g.id).appendTo('body'); + }, + _removeProxy: function () + { + var g = this; + if (g.proxy) + { + g.proxy.remove(); + g.proxy = null; + } + }, + _start: function (e) + { + var g = this, p = this.options; + g._createProxy(); + g.proxy.css({ + left: g.target.offset().left, + top: g.target.offset().top, + position: 'absolute' + }); + g.current = { + dir: g.dir, + left: g.target.offset().left, + top: g.target.offset().top, + startX: e.pageX || e.screenX, + startY: e.pageY || e.clientY, + width: g.target.width(), + height: g.target.height() + }; + $(document).bind("selectstart.resizable", function () { return false; }); + $(document).bind('mouseup.resizable', function () + { + g._stop.apply(g, arguments); + }); + $(document).bind('mousemove.resizable', function () + { + g._drag.apply(g, arguments); + }); + g.proxy.show(); + g.trigger('startResize', [g.current, e]); + }, + changeBy: { + t: ['n', 'ne', 'nw'], + l: ['w', 'sw', 'nw'], + w: ['w', 'sw', 'nw', 'e', 'ne', 'se'], + h: ['n', 'ne', 'nw', 's', 'se', 'sw'] + }, + _drag: function (e) + { + var g = this, p = this.options; + if (!g.current) return; + if (!g.proxy) return; + g.proxy.css('cursor', g.current.dir == '' ? 'default' : g.current.dir + '-resize'); + var pageX = e.pageX || e.screenX; + var pageY = e.pageY || e.screenY; + g.current.diffX = pageX - g.current.startX; + g.current.diffY = pageY - g.current.startY; + g._applyResize(g.proxy); + g.trigger('resize', [g.current, e]); + }, + _stop: function (e) + { + var g = this, p = this.options; + if (g.hasBind('stopResize')) + { + if (g.trigger('stopResize', [g.current, e]) != false) + g._applyResize(); + } + else + { + g._applyResize(); + } + g._removeProxy(); + g.trigger('endResize', [g.current, e]); + $(document).unbind("selectstart.resizable"); + $(document).unbind('mousemove.resizable'); + $(document).unbind('mouseup.resizable'); + }, + _applyResize: function (applyResultBody) + { + var g = this, p = this.options; + var cur = { + left: g.current.left, + top: g.current.top, + width: g.current.width, + height: g.current.height + }; + var applyToTarget = false; + if (!applyResultBody) + { + applyResultBody = g.target; + applyToTarget = true; + if (!isNaN(parseInt(g.target.css('top')))) + cur.top = parseInt(g.target.css('top')); + else + cur.top = 0; + if (!isNaN(parseInt(g.target.css('left')))) + cur.left = parseInt(g.target.css('left')); + else + cur.left = 0; + } + if ($.inArray(g.current.dir, g.changeBy.l) > -1) + { + cur.left += g.current.diffX; + g.current.diffLeft = g.current.diffX; + + } + else if (applyToTarget) + { + delete cur.left; + } + if ($.inArray(g.current.dir, g.changeBy.t) > -1) + { + cur.top += g.current.diffY; + g.current.diffTop = g.current.diffY; + } + else if (applyToTarget) + { + delete cur.top; + } + if ($.inArray(g.current.dir, g.changeBy.w) > -1) + { + cur.width += (g.current.dir.indexOf('w') == -1 ? 1 : -1) * g.current.diffX; + g.current.newWidth = cur.width; + } + else if (applyToTarget) + { + delete cur.width; + } + if ($.inArray(g.current.dir, g.changeBy.h) > -1) + { + cur.height += (g.current.dir.indexOf('n') == -1 ? 1 : -1) * g.current.diffY; + g.current.newHeight = cur.height; + } + else if (applyToTarget) + { + delete cur.height; + } + if (applyToTarget && p.animate) + applyResultBody.animate(cur); + else + applyResultBody.css(cur); + } + }); + + + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerSpinner = function () + { + return $.ligerui.run.call(this, "ligerSpinner", arguments); + }; + $.fn.ligerGetSpinnerManager = function () + { + return $.ligerui.run.call(this, "ligerGetSpinnerManager", arguments); + }; + + $.ligerDefaults.Spinner = { + type: 'float', //类型 float:浮点数 int:整数 time:时间 + isNegative: true, //是否负数 + decimalplace: 2, //小数位 type=float时起作用 + step: 0.1, //每次增加的值 + interval: 50, //间隔,毫秒 + value : null, + onChangeValue: false, //改变值事件 + minValue: null, //最小值 + maxValue: null, //最大值 + disabled: false, + readonly: false //是否只读 + }; + + $.ligerMethos.Spinner = {}; + + $.ligerui.controls.Spinner = function (element, options) + { + $.ligerui.controls.Spinner.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Spinner.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'Spinner'; + }, + __idPrev: function () + { + return 'Spinner'; + }, + _extendMethods: function () + { + return $.ligerMethos.Spinner; + }, + _init: function () + { + $.ligerui.controls.Spinner.base._init.call(this); + var p = this.options; + if (p.type == 'float') + { + p.step = 0.1; + p.interval = 50; + } else if (p.type == 'int') + { + p.step = 1; + p.interval = 100; + } else if (p.type == 'time') + { + p.step = 1; + p.interval = 100; + } else + { + p.type = "int"; + p.step = 1; + p.interval = 100; + } + }, + _render: function () + { + var g = this, p = this.options; + g.interval = null; + g.inputText = null; + g.value = null; + g.textFieldID = ""; + if (this.element.tagName.toLowerCase() == "input" && this.element.type && this.element.type == "text") + { + g.inputText = $(this.element); + if (this.element.id) + g.textFieldID = this.element.id; + } + else + { + g.inputText = $('<input type="text"/>'); + g.inputText.appendTo($(this.element)); + } + if (g.textFieldID == "" && p.textFieldID) + g.textFieldID = p.textFieldID; + + g.link = $('<div class="l-trigger"><div class="l-spinner-up"><div class="l-spinner-icon"></div></div><div class="l-spinner-split"></div><div class="l-spinner-down"><div class="l-spinner-icon"></div></div></div>'); + g.wrapper = g.inputText.wrap('<div class="l-text"></div>').parent(); + g.wrapper.append('<div class="l-text-l"></div><div class="l-text-r"></div>'); + g.wrapper.append(g.link).after(g.selectBox).after(g.valueField); + g.link.up = $(".l-spinner-up", g.link); + g.link.down = $(".l-spinner-down", g.link); + g.inputText.addClass("l-text-field"); + + if (p.disabled) + { + g.wrapper.addClass("l-text-disabled"); + } + //初始化 + if (!g._isVerify(g.inputText.val())) + { + g.value = g._getDefaultValue(); + g._showValue(g.value); + } + //事件 + g.link.up.hover(function () + { + if (!p.disabled) + $(this).addClass("l-spinner-up-over"); + }, function () + { + clearInterval(g.interval); + $(document).unbind("selectstart.spinner"); + $(this).removeClass("l-spinner-up-over"); + }).mousedown(function () + { + if (!p.disabled) + { + g._uping.call(g); + g.interval = setInterval(function () + { + g._uping.call(g); + }, p.interval); + $(document).bind("selectstart.spinner", function () { return false; }); + } + }).mouseup(function () + { + clearInterval(g.interval); + g.inputText.trigger("change").focus(); + $(document).unbind("selectstart.spinner"); + }); + g.link.down.hover(function () + { + if (!p.disabled) + $(this).addClass("l-spinner-down-over"); + }, function () + { + clearInterval(g.interval); + $(document).unbind("selectstart.spinner"); + $(this).removeClass("l-spinner-down-over"); + }).mousedown(function () + { + if (!p.disabled) + { + g.interval = setInterval(function () + { + g._downing.call(g); + }, p.interval); + $(document).bind("selectstart.spinner", function () { return false; }); + } + }).mouseup(function () + { + clearInterval(g.interval); + g.inputText.trigger("change").focus(); + $(document).unbind("selectstart.spinner"); + }); + + g.inputText.change(function () + { + var value = g.inputText.val(); + g.value = g._getVerifyValue(value); + g.trigger('changeValue', [g.value]); + g._showValue(g.value); + }).blur(function () + { + g.wrapper.removeClass("l-text-focus"); + }).focus(function () + { + g.wrapper.addClass("l-text-focus"); + }); + g.wrapper.hover(function () + { + if (!p.disabled) + g.wrapper.addClass("l-text-over"); + }, function () + { + g.wrapper.removeClass("l-text-over"); + }); + g.set(p); + }, + _setValue: function (value) + { + if (value != null) + this.inputText.val(value); + }, + _setWidth: function (value) + { + var g = this; + if (value > 20) + { + g.wrapper.css({ width: value }); + g.inputText.css({ width: value - 20 }); + } + }, + _setHeight: function (value) + { + var g = this; + if (value > 10) + { + g.wrapper.height(value); + g.inputText.height(value - 2); + g.link.height(value - 4); + } + }, + _setDisabled: function (value) + { + if (value) + { + this.wrapper.addClass("l-text-disabled"); + } + else + { + this.wrapper.removeClass("l-text-disabled"); + } + }, + _showValue: function (value) + { + var g = this, p = this.options; + if (!value || value == "NaN") value = 0; + if (p.type == 'float') + { + value = parseFloat(value).toFixed(p.decimalplace); + } + this.inputText.val(value) + }, + _setValue: function (value) + { + this._showValue(value); + }, + setValue: function (value) + { + this._showValue(value); + }, + getValue: function () + { + return this.inputText.val(); + }, + _round: function (v, e) + { + var g = this, p = this.options; + var t = 1; + for (; e > 0; t *= 10, e--) { } + for (; e < 0; t /= 10, e++) { } + return Math.round(v * t) / t; + }, + _isInt: function (str) + { + var g = this, p = this.options; + var strP = p.isNegative ? /^-?\d+$/ : /^\d+$/; + if (!strP.test(str)) return false; + if (parseFloat(str) != str) return false; + return true; + }, + _isFloat: function (str) + { + var g = this, p = this.options; + var strP = p.isNegative ? /^-?\d+(\.\d+)?$/ : /^\d+(\.\d+)?$/; + if (!strP.test(str)) return false; + if (parseFloat(str) != str) return false; + return true; + }, + _isTime: function (str) + { + var g = this, p = this.options; + var a = str.match(/^(\d{1,2}):(\d{1,2})$/); + if (a == null) return false; + if (a[1] > 24 || a[2] > 60) return false; + return true; + + }, + _isVerify: function (str) + { + var g = this, p = this.options; + if (p.type == 'float') + { + if (!g._isFloat(str)) return false; + var value = parseFloat(str); + if (p.minValue != undefined && p.minValue > value) return false; + if (p.maxValue != undefined && p.maxValue < value) return false; + return true; + } else if (p.type == 'int') + { + if (!g._isInt(str)) return false; + var value = parseInt(str); + if (p.minValue != undefined && p.minValue > value) return false; + if (p.maxValue != undefined && p.maxValue < value) return false; + return true; + } else if (p.type == 'time') + { + return g._isTime(str); + } + return false; + }, + _getVerifyValue: function (value) + { + var g = this, p = this.options; + var newvalue = null; + if (p.type == 'float') + { + newvalue = g._round(value, p.decimalplace); + } + else if (p.type == 'int') + { + newvalue = parseInt(value); + } else if (p.type == 'time') + { + newvalue = value; + } + if (!g._isVerify(newvalue)) + { + return g.value; + } else + { + return newvalue; + } + }, + _isOverValue: function (value) + { + var g = this, p = this.options; + if (p.minValue != null && p.minValue > value) return true; + if (p.maxValue != null && p.maxValue < value) return true; + return false; + }, + _getDefaultValue: function () + { + var g = this, p = this.options; + if (p.type == 'float' || p.type == 'int') { return 0; } + else if (p.type == 'time') { return "00:00"; } + }, + _addValue: function (num) + { + var g = this, p = this.options; + var value = g.inputText.val(); + value = parseFloat(value) + num; + if (g._isOverValue(value)) return; + g._showValue(value); + g.inputText.trigger("change"); + }, + _addTime: function (minute) + { + var g = this, p = this.options; + var value = g.inputText.val(); + var a = value.match(/^(\d{1,2}):(\d{1,2})$/); + newminute = parseInt(a[2]) + minute; + if (newminute < 10) newminute = "0" + newminute; + value = a[1] + ":" + newminute; + if (g._isOverValue(value)) return; + g._showValue(value); + g.inputText.trigger("change"); + }, + _uping: function () + { + var g = this, p = this.options; + if (p.type == 'float' || p.type == 'int') + { + g._addValue(p.step); + } else if (p.type == 'time') + { + g._addTime(p.step); + } + }, + _downing: function () + { + var g = this, p = this.options; + if (p.type == 'float' || p.type == 'int') + { + g._addValue(-1 * p.step); + } else if (p.type == 'time') + { + g._addTime(-1 * p.step); + } + }, + _isDateTime: function (dateStr) + { + var g = this, p = this.options; + var r = dateStr.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/); + if (r == null) return false; + var d = new Date(r[1], r[3] - 1, r[4]); + if (d == "NaN") return false; + return (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4]); + }, + _isLongDateTime: function (dateStr) + { + var g = this, p = this.options; + var reg = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2})$/; + var r = dateStr.match(reg); + if (r == null) return false; + var d = new Date(r[1], r[3] - 1, r[4], r[5], r[6]); + if (d == "NaN") return false; + return (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4] && d.getHours() == r[5] && d.getMinutes() == r[6]); + } + }); + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerTab = function (options) + { + return $.ligerui.run.call(this, "ligerTab", arguments); + }; + + $.fn.ligerGetTabManager = function () + { + return $.ligerui.run.call(this, "ligerGetTabManager", arguments); + }; + + $.ligerDefaults.Tab = { + height: null, + heightDiff: 0, // 高度补差 + changeHeightOnResize: false, + contextmenu: true, + dblClickToClose: false, //是否双击时关闭 + dragToMove: false, //是否允许拖动时改变tab项的位置 + showSwitch: false, //显示切换窗口按钮 + showSwitchInTab: false, //切换窗口按钮显示在最后一项 + data: null, //传递数据容器 + onBeforeOverrideTabItem: null, + onAfterOverrideTabItem: null, + onBeforeRemoveTabItem: null, + onAfterRemoveTabItem: null, + onBeforeAddTabItem: null, + onAfterAddTabItem: null, + onBeforeSelectTabItem: null, + onAfterSelectTabItem: null, + onCloseOther: null, + onCloseAll: null, + onClose: null, + onReload: null, + onSwitchRender : null //当切换窗口层构件时的事件 + }; + $.ligerDefaults.TabString = { + closeMessage: "关闭当前页", + closeOtherMessage: "关闭其他", + closeAllMessage: "关闭所有", + reloadMessage: "刷新" + }; + + $.ligerMethos.Tab = {}; + + $.ligerui.controls.Tab = function (element, options) + { + $.ligerui.controls.Tab.base.constructor.call(this, element, options); + }; + $.ligerui.controls.Tab.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Tab'; + }, + __idPrev: function () + { + return 'Tab'; + }, + _extendMethods: function () + { + return $.ligerMethos.Tab; + }, + _render: function () + { + var g = this, p = this.options; + if (p.height) g.makeFullHeight = true; + g.tab = $(this.element); + g.tab.addClass("l-tab"); + if (p.contextmenu && $.ligerMenu) + { + g.tab.menu = $.ligerMenu({ width: 100, items: [ + { text: p.closeMessage, id: 'close', click: function () + { + g._menuItemClick.apply(g, arguments); + } + }, + { text: p.closeOtherMessage, id: 'closeother', click: function () + { + g._menuItemClick.apply(g, arguments); + } + }, + { text: p.closeAllMessage, id: 'closeall', click: function () + { + g._menuItemClick.apply(g, arguments); + } + }, + { text: p.reloadMessage, id: 'reload', click: function () + { + g._menuItemClick.apply(g, arguments); + } + } + ] + }); + } + g.tab.content = $('<div class="l-tab-content"></div>'); + $("> div", g.tab).appendTo(g.tab.content); + g.tab.content.appendTo(g.tab); + g.tab.links = $('<div class="l-tab-links"><ul style="left: 0px; "></ul><div class="l-tab-switch"></div></div>'); + g.tab.links.prependTo(g.tab); + g.tab.links.ul = $("ul", g.tab.links); + var lselecteds = $("> div[lselected=true]", g.tab.content); + var haslselected = lselecteds.length > 0; + g.selectedTabId = lselecteds.attr("tabid"); + $("> div", g.tab.content).each(function (i, box) + { + var li = $('<li class=""><a></a><div class="l-tab-links-item-left"></div><div class="l-tab-links-item-right"></div></li>'); + var contentitem = $(this); + if (contentitem.attr("title")) + { + $("> a", li).html(contentitem.attr("title")); + contentitem.attr("title", ""); + } + var tabid = contentitem.attr("tabid"); + if (tabid == undefined) + { + tabid = g.getNewTabid(); + contentitem.attr("tabid", tabid); + if (contentitem.attr("lselected")) + { + g.selectedTabId = tabid; + } + } + li.attr("tabid", tabid); + if (!haslselected && i == 0) g.selectedTabId = tabid; + var showClose = contentitem.attr("showClose"); + if (showClose) + { + li.append("<div class='l-tab-links-item-close'></div>"); + } + $("> ul", g.tab.links).append(li); + if (!contentitem.hasClass("l-tab-content-item")) contentitem.addClass("l-tab-content-item"); + if (contentitem.find("iframe").length > 0) + { + var iframe = $("iframe:first", contentitem); + if (iframe[0].readyState != "complete") + { + if (contentitem.find(".l-tab-loading:first").length == 0) + contentitem.prepend("<div class='l-tab-loading' style='display:block;'></div>"); + var iframeloading = $(".l-tab-loading:first", contentitem); + iframe.bind('load.tab', function () + { + iframeloading.hide(); + }); + } + } + }); + //init + g.selectTabItem(g.selectedTabId); + //set content height + if (p.height) + { + if (typeof (p.height) == 'string' && p.height.indexOf('%') > 0) + { + g.onResize(); + if (p.changeHeightOnResize) + { + $(window).resize(function () + { + g.onResize.call(g); + }); + } + } else + { + g.setHeight(p.height); + } + } + if (g.makeFullHeight) + g.setContentHeight(); + //add even + $("li", g.tab.links).each(function () + { + g._addTabItemEvent($(this)); + }); + g.tab.bind('dblclick.tab', function (e) + { + if (!p.dblClickToClose) return; + g.dblclicking = true; + var obj = (e.target || e.srcElement); + var tagName = obj.tagName.toLowerCase(); + if (tagName == "a") + { + var tabid = $(obj).parent().attr("tabid"); + var allowClose = $(obj).parent().find("div.l-tab-links-item-close").length ? true : false; + if (allowClose) + { + g.removeTabItem(tabid); + } + } + g.dblclicking = false; + }); + + g.set(p); + //set tab links width + setTimeout(setLinksWidth, 100); + $(window).resize(function () + { + setLinksWidth.call(g); + }); + + function setLinksWidth() + { + //modify by js 2016.08.13 + //var w = g.tab.width() - parseInt(g.tab.links.css("marginLeft"), 10) - parseInt(g.tab.links.css("marginRight"), 10); + //g.tab.links.width(w); + } + + g.bind('sysWidthChange', function () + { + setLinksWidth.call(g); + }); + }, + _setShowSwitch: function (value) + { + var g = this, p = this.options; + if (value) + { + if (!$(".l-tab-switch", g.tab.links).length) + { + $("<div class='l-tab-switch'></div>").appendTo(g.tab.links); + } + $(g.tab).addClass("l-tab-switchable"); + $(".l-tab-switch", g.tab).click(function () + { + g.toggleSwitch(this); + }); + } + else + { + $(g.tab).removeClass("l-tab-switchable"); + $("body > .l-tab-windowsswitch").remove(); + } + }, + _setShowSwitchInTab:function(value) + { + var g = this, p = this.options; + if (p.showSwitch && value) + { + $(g.tab).removeClass("l-tab-switchable"); + $(".l-tab-switch", g.tab).remove(); + var tabitem = $("<li class='l-tab-itemswitch'><a></a><div class='l-tab-links-item-left'></div><div class='l-tab-links-item-right'></div></li>"); + tabitem.appendTo(g.tab.links.ul); + tabitem.click(function () + { + g.toggleSwitch(this); + }); + } else + { + $(".l-tab-itemswitch", g.tab.ul).remove(); + } + }, + toggleSwitch: function (btn) + { + var g = this, p = this.options; + if ($("body > .l-tab-windowsswitch").length) + { + $("body > .l-tab-windowsswitch").remove(); + return; + } + if (btn == null) return; + var windowsswitch = $("<div class='l-tab-windowsswitch'></div>").appendTo('body'); + var tabItems = g.tab.links.ul.find('>li'); + var selectedTabItemID = g.getSelectedTabItemID(); + tabItems.each(function (i, item) + { + var jlink = $("<a href='javascript:void(0)'></a>"); + jlink.text($(item).find("a").text()); + var tabid = $(item).attr("tabid"); + if (tabid == null) return; + if (tabid == selectedTabItemID) + { + jlink.addClass("selected"); + } + jlink.attr("tabid", tabid); + windowsswitch.append(jlink); + }); + windowsswitch.css({ + top: $(btn).offset().top + $(btn).height(), + left: $(btn).offset().left - windowsswitch.width() + }); + windowsswitch.find("a").bind("click", function (e) + { + var tabid = $(this).attr("tabid"); + if (tabid == undefined) return; + g.selectTabItem(tabid); + g.moveToTabItem(tabid); + $("body > .l-tab-windowsswitch").remove(); + }); + g.trigger('switchRender', [windowsswitch]); + }, + _applyDrag: function (tabItemDom) + { + var g = this, p = this.options; + g.droptip = g.droptip || $("<div class='l-tab-drag-droptip' style='display:none'><div class='l-drop-move-up'></div><div class='l-drop-move-down'></div></div>").appendTo('body'); + var drag = $(tabItemDom).ligerDrag( + { + revert: true, animate: false, + proxy: function () + { + var name = $(this).find("a").html(); + g.dragproxy = $("<div class='l-tab-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div></div>").appendTo('body'); + g.dragproxy.append(name); + return g.dragproxy; + }, + onRendered: function () + { + this.set('cursor', 'pointer'); + }, + onStartDrag: function (current, e) + { + if (!$(tabItemDom).hasClass("l-selected")) return false; + if (e.button == 2) return false; + var obj = e.srcElement || e.target; + if ($(obj).hasClass("l-tab-links-item-close")) return false; + }, + onDrag: function (current, e) + { + if (g.dropIn == null) + g.dropIn = -1; + var tabItems = g.tab.links.ul.find('>li'); + var targetIndex = tabItems.index(current.target); + tabItems.each(function (i, item) + { + if (targetIndex == i) + { + return; + } + var isAfter = i > targetIndex; + if (g.dropIn != -1 && g.dropIn != i) return; + var offset = $(this).offset(); + var range = { + top: offset.top, + bottom: offset.top + $(this).height(), + left: offset.left - 10, + right: offset.left + 10 + }; + if (isAfter) + { + range.left += $(this).width(); + range.right += $(this).width(); + } + var pageX = e.pageX || e.screenX; + var pageY = e.pageY || e.screenY; + if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom) + { + g.droptip.css({ + left: range.left + 5, + top: range.top - 9 + }).show(); + g.dropIn = i; + g.dragproxy.find(".l-drop-icon").removeClass("l-drop-no").addClass("l-drop-yes"); + } + else + { + g.dropIn = -1; + g.droptip.hide(); + g.dragproxy.find(".l-drop-icon").removeClass("l-drop-yes").addClass("l-drop-no"); + } + }); + }, + onStopDrag: function (current, e) + { + if (g.dropIn > -1) + { + var to = g.tab.links.ul.find('>li:eq(' + g.dropIn + ')').attr("tabid"); + var from = $(current.target).attr("tabid"); + setTimeout(function () + { + g.moveTabItem(from, to); + }, 0); + g.dropIn = -1; + g.dragproxy.remove(); + } + g.droptip.hide(); + this.set('cursor', 'default'); + } + }); + return drag; + }, + _setDragToMove: function (value) + { + if (!$.fn.ligerDrag) return; //需要ligerDrag的支持 + var g = this, p = this.options; + if (value) + { + if (g.drags) return; + g.drags = g.drags || []; + g.tab.links.ul.find('>li').each(function () + { + g.drags.push(g._applyDrag(this)); + }); + } + }, + moveTabItem: function (fromTabItemID, toTabItemID) + { + var g = this; + var from = g.tab.links.ul.find(">li[tabid=" + fromTabItemID + "]"); + var to = g.tab.links.ul.find(">li[tabid=" + toTabItemID + "]"); + var index1 = g.tab.links.ul.find(">li").index(from); + var index2 = g.tab.links.ul.find(">li").index(to); + if (index1 < index2) + { + to.after(from); + } + else + { + to.before(from); + } + }, + //设置tab按钮(左和右),显示返回true,隐藏返回false + setTabButton: function () + { + var g = this, p = this.options; + var sumwidth = 0; + $("li", g.tab.links.ul).each(function () + { + sumwidth += $(this).width() + 2; + }); + var mainwidth = g.tab.width(); + if (sumwidth > mainwidth) + { + if (!$(".l-tab-links-left", g.tab).length) + { + g.tab.links.append('<div class="l-tab-links-left"><span></span></div><div class="l-tab-links-right"><span></span></div>'); + g.setTabButtonEven(); + } + return true; + } else + { + g.tab.links.ul.animate({ left: 0 }); + $(".l-tab-links-left,.l-tab-links-right", g.tab.links).remove(); + return false; + } + }, + //设置左右按钮的事件 标签超出最大宽度时,可左右拖动 + setTabButtonEven: function () + { + var g = this, p = this.options; + $(".l-tab-links-left", g.tab.links).hover(function () + { + $(this).addClass("l-tab-links-left-over"); + }, function () + { + $(this).removeClass("l-tab-links-left-over"); + }).click(function () + { + g.moveToPrevTabItem(); + }); + $(".l-tab-links-right", g.tab.links).hover(function () + { + $(this).addClass("l-tab-links-right-over"); + }, function () + { + $(this).removeClass("l-tab-links-right-over"); + }).click(function () + { + g.moveToNextTabItem(); + }); + }, + //切换到上一个tab + moveToPrevTabItem: function (tabid) + { + var g = this, p = this.options; + var tabItems = $("> li", g.tab.links.ul), + nextBtn = $(".l-tab-links-right", g.tab), + prevBtn = $(".l-tab-links-left", g.tab); + if (!nextBtn.length || !prevBtn.length) return false; + var nextBtnOffset = nextBtn.offset(), prevBtnOffset = prevBtn.offset(); + //计算应该移动到的标签项,并计算从第一项到这个标签项的上一项的宽度总和 + var moveToTabItem = null, currentWidth = 0; + var prevBtnLeft = prevBtnOffset.left + prevBtn.outerWidth(); + for (var i = 0, l = tabItems.length; i < l; i++) + { + var tabitem = $(tabItems[i]); + var offset = tabitem.offset(); + var start = offset.left, end = offset.left + tabitem.outerWidth(); + if (tabid != null) + { + if (start < prevBtnLeft && tabitem.attr("tabid") == tabid) + { + moveToTabItem = tabitem; + break; + } + } + else if (start < prevBtnLeft && end >= prevBtnLeft) + { + moveToTabItem = tabitem; + break; + } + currentWidth += tabitem.outerWidth() + parseInt(tabitem.css("marginLeft")) + + parseInt(tabitem.css("marginRight")); + } + if (moveToTabItem == null) return false; + //计算出正确的移动位置 + var left = currentWidth - prevBtn.outerWidth(); + g.tab.links.ul.animate({ left: -1 * left }); + return true; + }, + //切换到下一个tab + moveToNextTabItem: function (tabid) + { + var g = this, p = this.options; + var tabItems = $("> li", g.tab.links.ul), + nextBtn = $(".l-tab-links-right", g.tab), + prevBtn = $(".l-tab-links-left", g.tab); + if (!nextBtn.length || !prevBtn.length) return false; + var nextBtnOffset = nextBtn.offset(), prevBtnOffset = prevBtn.offset(); + //计算应该移动到的标签项,并计算从第一项到这个标签项的宽度总和 + var moveToTabItem = null, currentWidth = 0; + for (var i = 0, l = tabItems.length; i < l; i++) + { + var tabitem = $(tabItems[i]); + currentWidth += tabitem.outerWidth() + + parseInt(tabitem.css("marginLeft")) + + parseInt(tabitem.css("marginRight")); + var offset = tabitem.offset(); + var start = offset.left, end = offset.left + tabitem.outerWidth(); + if (tabid != null) + { + if (end > nextBtnOffset.left && tabitem.attr("tabid") == tabid) + { + moveToTabItem = tabitem; + break; + } + } + else if (start <= nextBtnOffset.left && end > nextBtnOffset.left) + { + moveToTabItem = tabitem; + break; + } + } + if (moveToTabItem == null) return false; + //计算出正确的移动位置 + var left = currentWidth - (nextBtnOffset.left - prevBtnOffset.left) + + parseInt(moveToTabItem.css("marginLeft")) + parseInt(moveToTabItem.css("marginRight")); + g.tab.links.ul.animate({ left: -1 * left }); + return true; + }, + //切换到指定的项目项 + moveToTabItem: function (tabid) + { + var g = this, p = this.options; + if (!g.moveToPrevTabItem(tabid)) + { + g.moveToNextTabItem(tabid); + } + }, + getTabItemCount: function () + { + var g = this, p = this.options; + return $("li", g.tab.links.ul).length; + }, + getSelectedTabItemID: function () + { + var g = this, p = this.options; + return $("li.l-selected", g.tab.links.ul).attr("tabid"); + }, + removeSelectedTabItem: function () + { + var g = this, p = this.options; + g.removeTabItem(g.getSelectedTabItemID()); + }, + //覆盖选择的tabitem + overrideSelectedTabItem: function (options) + { + var g = this, p = this.options; + g.overrideTabItem(g.getSelectedTabItemID(), options); + }, + //覆盖 + overrideTabItem: function (targettabid, options) + { + var g = this, p = this.options; + if (g.trigger('beforeOverrideTabItem', [targettabid]) == false) + return false; + var tabid = options.tabid; + if (tabid == undefined) tabid = g.getNewTabid(); + var url = options.url; + var content = options.content; + var target = options.target; + var text = options.text; + var showClose = options.showClose; + var height = options.height; + //如果已经存在 + if (g.isTabItemExist(tabid)) + { + return; + } + var tabitem = $("li[tabid=" + targettabid + "]", g.tab.links.ul); + var contentitem = $(".l-tab-content-item[tabid=" + targettabid + "]", g.tab.content); + if (!tabitem || !contentitem) return; + tabitem.attr("tabid", tabid); + contentitem.attr("tabid", tabid); + if ($("iframe", contentitem).length == 0 && url) + { + contentitem.html("<iframe frameborder='0'></iframe>"); + } + else if (content) + { + contentitem.html(content); + } + $("iframe", contentitem).attr("name", tabid); + if (showClose == undefined) showClose = true; + if (showClose == false) $(".l-tab-links-item-close", tabitem).remove(); + else + { + if ($(".l-tab-links-item-close", tabitem).length == 0) + tabitem.append("<div class='l-tab-links-item-close'></div>"); + } + if (text == undefined) text = tabid; + if (height) contentitem.height(height); + $("a", tabitem).text(text); + $("iframe", contentitem).attr("src", url); + + + g.trigger('afterOverrideTabItem', [targettabid]); + }, + //设置页签项标题 + setHeader: function(tabid,header) + { + $("li[tabid=" + tabid + "] a", this.tab.links.ul).text(header); + }, + //选中tab项 + selectTabItem: function (tabid) + { + var g = this, p = this.options; + if (g.trigger('beforeSelectTabItem', [tabid]) == false) + return false; + g.selectedTabId = tabid; + $("> .l-tab-content-item[tabid=" + tabid + "]", g.tab.content).show().siblings().hide(); + $("li[tabid=" + tabid + "]", g.tab.links.ul).addClass("l-selected").siblings().removeClass("l-selected"); + g.trigger('afterSelectTabItem', [tabid]); + }, + //移动到最后一个tab + moveToLastTabItem: function () + { + var g = this, p = this.options; + var sumwidth = 0; + $("li", g.tab.links.ul).each(function () + { + sumwidth += $(this).width() + 2; + }); + var mainwidth = g.tab.width(); + if (sumwidth > mainwidth) + { + var btnWitdth = $(".l-tab-links-right", g.tab.links).width(); + g.tab.links.ul.animate({ left: -1 * (sumwidth - mainwidth + btnWitdth + 2) }); + } + }, + getTabItemTitle: function (tabid) + { + var g = this, p = this.options; + return $("li[tabid=" + tabid + "] a", g.tab.links.ul).text(); + }, + setTabItemTitle: function (tabid, title) + { + var g = this, p = this.options; + $("li[tabid=" + tabid + "] a", g.tab.links.ul).text(title); + }, + getTabItemSrc: function (tabid) + { + var g = this, p = this.options; + return $(".l-tab-content-item[tabid=" + tabid + "] iframe", g.tab.content).attr("src"); + }, + setTabItemSrc: function (tabid, url) + { + var g = this, p = this.options; + var contentitem = $(".l-tab-content-item[tabid=" + tabid + "]", g.tab.content); + var iframeloading = $(".l-tab-loading:first", contentitem); + var iframe = $(".l-tab-content-item[tabid=" + tabid + "] iframe", g.tab.content); + iframeloading.show(); + iframe.attr("src", url).unbind('load.tab').bind('load.tab', function () + { + iframeloading.hide(); + }); + }, + + + + //判断tab是否存在 + isTabItemExist: function (tabid) + { + var g = this, p = this.options; + return $("li[tabid=" + tabid + "] a", g.tab.links.ul).length > 0; + }, + //增加一个tab + addTabItem: function (options) + { + var g = this, p = this.options; + if (g.trigger('beforeAddTabItem', [options]) == false) + return false; + var tabid = options.tabid; + if (tabid == undefined) tabid = g.getNewTabid(); + var url = options.url, content = options.content, text = options.text, showClose = options.showClose, height = options.height; + //如果已经存在 + if (g.isTabItemExist(tabid)) + { + g.selectTabItem(tabid); + return; + } + var tabitem = $("<li><a></a><div class='l-tab-links-item-left'></div><div class='l-tab-links-item-right'></div><div class='l-tab-links-item-close'></div></li>"); + var contentitem = $("<div class='l-tab-content-item'><div class='l-tab-loading' style='display:block;'></div><iframe frameborder='0'></iframe></div>"); + var iframeloading = $("div:first", contentitem); + var iframe = $("iframe:first", contentitem); + if (g.makeFullHeight) + { + var newheight = g.tab.height() - g.tab.links.height(); + contentitem.height(newheight); + } + tabitem.attr("tabid", tabid); + contentitem.attr("tabid", tabid); + if (url) + { + iframe[0].tab = g;//增加iframe对tab对象的引用 + if (options.data) + { + iframe[0].openerData = options.data; + } + iframe.attr("name", tabid) + .attr("id", tabid) + .attr("src", url) + .bind('load.tab', function () + { + iframeloading.hide(); + if (options.callback) + options.callback(); + }); + } + else + { + iframe.remove(); + iframeloading.remove(); + } + if (content) + { + contentitem.html(content); + if (options.callback) + options.callback(); + } + else if (options.target) + { + contentitem.append(options.target); + if (options.callback) + options.callback(); + } + if (showClose == undefined) showClose = true; + if (showClose == false) $(".l-tab-links-item-close", tabitem).remove(); + if (text == undefined) text = tabid; + if (height) contentitem.height(height); + $("a", tabitem).text(text); + if ($(".l-tab-itemswitch", g.tab.links.ul).length) + { + tabitem.insertBefore($(".l-tab-itemswitch", g.tab.links.ul)); + } else + { + g.tab.links.ul.append(tabitem); + } + g.tab.content.append(contentitem); + g.selectTabItem(tabid); + if (g.setTabButton()) + { + g.moveToTabItem(tabid); + } + //增加事件 + g._addTabItemEvent(tabitem); + if (p.dragToMove && $.fn.ligerDrag) + { + g.drags = g.drags || []; + tabitem.each(function () + { + g.drags.push(g._applyDrag(this)); + }); + } + g.toggleSwitch(); + g.trigger('afterAddTabItem', [options]); + }, + _addTabItemEvent: function (tabitem) + { + var g = this, p = this.options; + tabitem.click(function () + { + var tabid = $(this).attr("tabid"); + g.selectTabItem(tabid); + }); + //右键事件支持 + g.tab.menu && g._addTabItemContextMenuEven(tabitem); + $(".l-tab-links-item-close", tabitem).hover(function () + { + $(this).addClass("l-tab-links-item-close-over"); + }, function () + { + $(this).removeClass("l-tab-links-item-close-over"); + }).click(function () + { + var tabid = $(this).parent().attr("tabid"); + g.removeTabItem(tabid); + }); + + }, + //移除tab项 + removeTabItem: function (tabid) + { + var g = this, p = this.options; + if (g.trigger('beforeRemoveTabItem', [tabid]) == false) + return false; + var currentIsSelected = $("li[tabid=" + tabid + "]", g.tab.links.ul).hasClass("l-selected"); + if (currentIsSelected) + { + $(".l-tab-content-item[tabid=" + tabid + "]", g.tab.content).prev().show(); + $("li[tabid=" + tabid + "]", g.tab.links.ul).prev().addClass("l-selected").siblings().removeClass("l-selected"); + } + var contentItem = $(".l-tab-content-item[tabid=" + tabid + "]", g.tab.content); + var jframe = $('iframe', contentItem); + if (jframe.length) + { + var frame = jframe[0]; + frame.src = "about:blank"; + try + { + frame.contentWindow.document.write(''); + } catch (e) + { + } + $.browser.msie && CollectGarbage(); + jframe.remove(); + } + contentItem.remove(); + $("li[tabid=" + tabid + "]", g.tab.links.ul).remove(); + g.setTabButton(); + g.trigger('afterRemoveTabItem', [tabid]); + }, + + hideTabItem: function (tabid) + { + var g = this, p = this.options; + var currentIsSelected = $("li[tabid=" + tabid + "]", g.tab.links.ul).hasClass("l-selected"); + if (currentIsSelected) + { + $(".l-tab-content-item[tabid=" + tabid + "]", g.tab.content).prev().show(); + $("li[tabid=" + tabid + "]", g.tab.links.ul).prev().addClass("l-selected").siblings().removeClass("l-selected"); + } + $("li[tabid=" + tabid + "]", g.tab.links.ul).hide(); + $(".l-tab-content-item[tabid=" + tabid + "]", g.tab.content).hide(); + + + }, + showTabItem: function (tabid) + { + var g = this, p = this.options; + $("li[tabid=" + tabid + "]", g.tab.links.ul).show(); + }, + + + addHeight: function (heightDiff) + { + var g = this, p = this.options; + var newHeight = g.tab.height() + heightDiff; + g.setHeight(newHeight); + }, + setHeight: function (height) + { + var g = this, p = this.options; + g.tab.height(height); + g.setContentHeight(); + }, + setContentHeight: function () + { + var g = this, p = this.options; + var newheight = g.tab.height() - g.tab.links.height(); + g.tab.content.height(newheight); + $("> .l-tab-content-item", g.tab.content).height(newheight); + }, + getNewTabid: function () + { + var g = this, p = this.options; + g.getnewidcount = g.getnewidcount || 0; + return 'tabitem' + (++g.getnewidcount); + }, + //notabid 过滤掉tabid的 + //noclose 过滤掉没有关闭按钮的 + getTabidList: function (notabid, noclose) + { + var g = this, p = this.options; + var tabidlist = []; + $("> li", g.tab.links.ul).each(function () + { + if ($(this).attr("tabid") + && $(this).attr("tabid") != notabid + && (!noclose || $(".l-tab-links-item-close", this).length > 0)) + { + tabidlist.push($(this).attr("tabid")); + } + }); + return tabidlist; + }, + removeOther: function (tabid, compel) + { + var g = this, p = this.options; + var tabidlist = g.getTabidList(tabid, true); + $(tabidlist).each(function () + { + g.removeTabItem(this); + }); + }, + reload: function (tabid) + { + var g = this, p = this.options; + var contentitem = $(".l-tab-content-item[tabid=" + tabid + "]"); + var iframeloading = $(".l-tab-loading:first", contentitem); + var iframe = $("iframe:first", contentitem); + var url = $(iframe).attr("src"); + iframeloading.show(); + iframe.attr("src", url).unbind('load.tab').bind('load.tab', function () + { + iframeloading.hide(); + }); + }, + removeAll: function (compel) + { + var g = this, p = this.options; + var tabidlist = g.getTabidList(null, true); + $(tabidlist).each(function () + { + g.removeTabItem(this); + }); + }, + onResize: function () + { + var g = this, p = this.options; + if (!p.height || typeof (p.height) != 'string' || p.height.indexOf('%') == -1) return false; + //set tab height + if (g.tab.parent()[0].tagName.toLowerCase() == "body") + { + var windowHeight = $(window).height(); + windowHeight -= parseInt(g.tab.parent().css('paddingTop')); + windowHeight -= parseInt(g.tab.parent().css('paddingBottom')); + g.height = p.heightDiff + windowHeight * parseFloat(g.height) * 0.01; + } + else + { + g.height = p.heightDiff + (g.tab.parent().height() * parseFloat(p.height) * 0.01); + } + g.tab.height(g.height); + g.setContentHeight(); + }, + _menuItemClick: function (item) + { + var g = this, p = this.options; + if (!item.id || !g.actionTabid) return; + switch (item.id) + { + case "close": + if (g.trigger('close') == false) return; + g.removeTabItem(g.actionTabid); + g.actionTabid = null; + break; + case "closeother": + if (g.trigger('closeother') == false) return; + g.removeOther(g.actionTabid); + break; + case "closeall": + if (g.trigger('closeall') == false) return; + g.removeAll(); + g.actionTabid = null; + break; + case "reload": + if (g.trigger('reload', [{ tabid: g.actionTabid }]) == false) return; + g.selectTabItem(g.actionTabid); + g.reload(g.actionTabid); + break; + } + }, + _addTabItemContextMenuEven: function (tabitem) + { + var g = this, p = this.options; + tabitem.bind("contextmenu", function (e) + { + if (!g.tab.menu) return; + g.actionTabid = tabitem.attr("tabid"); + g.tab.menu.show({ top: e.pageY, left: e.pageX }); + if ($(".l-tab-links-item-close", this).length == 0) + { + g.tab.menu.setDisabled('close'); + } + else + { + g.tab.menu.setEnabled('close'); + } + return false; + }); + } + }); + + + +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerTextBox = function () + { + return $.ligerui.run.call(this, "ligerTextBox", arguments); + }; + + $.fn.ligerGetTextBoxManager = function () + { + return $.ligerui.run.call(this, "ligerGetTextBoxManager", arguments); + }; + + $.ligerDefaults.TextBox = { + onChangeValue: null, + onMouseOver: null, + onMouseOut: null, + onBlur: null, + onFocus: null, + width: null, + disabled: false, + initSelect : false, + value: null, //初始化值 + precision: 2, //保留小数位(仅currency时有效) + nullText: null, //不能为空时的提示 + digits: false, //是否限定为数字输入框 + number: false, //是否限定为浮点数格式输入框 + currency: false, //是否显示为货币形式 + readonly: false //是否只读 + }; + + + $.ligerui.controls.TextBox = function (element, options) + { + $.ligerui.controls.TextBox.base.constructor.call(this, element, options); + }; + + $.ligerui.controls.TextBox.ligerExtend($.ligerui.controls.Input, { + __getType: function () + { + return 'TextBox' + }, + __idPrev: function () + { + return 'TextBox'; + }, + _init: function () + { + $.ligerui.controls.TextBox.base._init.call(this); + var g = this, p = this.options; + if (!p.width) + { + p.width = $(g.element).width(); + } + if ($(this.element).attr("readonly")) + { + p.readonly = true; + } else if (p.readonly) + { + $(this.element).attr("readonly", true); + } + }, + _render: function () + { + var g = this, p = this.options; + g.inputText = $(this.element); + //外层 + g.wrapper = g.inputText.wrap('<div class="l-text"></div>').parent(); + g.wrapper.append('<div class="l-text-l"></div><div class="l-text-r"></div>'); + if (!g.inputText.hasClass("l-text-field")) + g.inputText.addClass("l-text-field"); + this._setEvent(); + if (p.digits || p.number || p.currency) + { + g.inputText.addClass("l-text-field-number"); + } + + g.set(p); + g.formatValue(); + }, + destroy: function () + { + var g = this; + if (g.wrapper) + { + g.wrapper.remove(); + } + g.options = null; + liger.remove(this); + }, + _getValue: function () + { + var g = this, p = this.options; + + if (g.inputText.hasClass("l-text-field-null")) + { + return ""; + } + if (p.digits || p.number || p.currency) + { + return g.parseNumber(); + } + return g.inputText.val(); + }, + _setNullText: function () + { + this.checkNotNull(); + }, + formatValue: function () + { + var g = this, p = this.options; + var v = g.inputText.val() || ""; + if (v == "") return ""; + if (p.currency) + { + g.inputText.val(currencyFormatter(v, p.precision)); + } else if(p.number && p.precision && v) + { + var value = parseFloat(g.inputText.val()).toFixed(p.precision); + g.inputText.val(value); + } + }, + checkNotNull: function () + { + var g = this, p = this.options; + + if (p.nullText && p.nullText != "null" && !p.disabled && !p.readonly) + { + if (!g.inputText.val()) + { + g.inputText.addClass("l-text-field-null").val(p.nullText); + return; + } + } else + { + g.inputText.removeClass("l-text-field-null"); + } + }, + _setEvent: function () + { + var g = this, p = this.options; + function validate() + { + var value = g.inputText.val(); + if (!value || value == "-") return true; + + var r = (p.digits ? /^-?\d+$/ : /^(-?\d+)(\.)?(\d+)?$/).test(value); + return r; + } + function keyCheck() + { + if (!validate()) + { + g.inputText.val(g.parseNumber()); + } + } + if (p.digits || p.number || p.currency) + { + g.inputText.keyup(keyCheck).bind("paste", keyCheck); + } + g.inputText.bind('blur.textBox', function () + { + g.trigger('blur'); + g.checkNotNull(); + g.formatValue(); + g.wrapper.removeClass("l-text-focus"); + }).bind('focus.textBox', function () + { + if (p.readonly) return; + g.trigger('focus'); + if (p.nullText) + { + if ($(this).hasClass("l-text-field-null")) + { + $(this).removeClass("l-text-field-null").val(""); + } + } + g.wrapper.addClass("l-text-focus"); + + if (p.digits || p.number || p.currency) + { + $(this).val(g.parseNumber()); + if (p.initSelect) + { + setTimeout(function () + { + g.inputText.select(); + }, 150); + } + } + }) + .change(function () + { + g.trigger('changeValue', [this.value]); + }); + g.wrapper.hover(function () + { + g.trigger('mouseOver'); + g.wrapper.addClass("l-text-over"); + }, function () + { + g.trigger('mouseOut'); + g.wrapper.removeClass("l-text-over"); + }); + }, + + //将value转换为有效的数值 + //1,去除无效字符 2,小数点保留 + parseNumber : function(value) + { + var g = this, p = this.options; + var isInt = p.digits ? true : false; + value = value || g.inputText.val(); + if (value == null || value == "") return ""; + if (!(p.digits || p.number || p.currency)) return value; + if (typeof (value) != "string") value = (value || "").toString(); + var sign = /^\-/.test(value); + if (isInt) + { + if (value == "0") return value; + value = value.replace(/\D+|^[0]+/g, ''); + } else + { + value = value.replace(/[^0-9.]/g, ''); + if (/^[0]+[1-9]+/.test(value)) + { + value = value.replace(/^[0]+/, ''); + } + } + if (!isInt && p.precision) + { + value = parseFloat(value).toFixed(p.precision); + if (value == "NaN") return "0"; + } + if (sign) value = "-" + value; + return value; + }, + + _setDisabled: function (value) + { + var g = this, p = this.options; + if (value) + { + this.inputText.attr("readonly", "readonly"); + this.wrapper.addClass("l-text-disabled"); + } + else if (!p.readonly) + { + this.inputText.removeAttr("readonly"); + this.wrapper.removeClass('l-text-disabled'); + } + }, + _setWidth: function (value) + { + if (value > 20) + { + this.wrapper.css({ width: value }); + this.inputText.css({ width: value - 4 }); + } + }, + _setHeight: function (value) + { + if (value > 10) + { + this.wrapper.height(value); + this.inputText.height(value - 2); + } + }, + _setValue: function (value) + { + if (value != null) + this.inputText.val(value); + this.checkNotNull(); + }, + _setLabel: function (value) + { + var g = this, p = this.options; + if (!g.labelwrapper) + { + g.labelwrapper = g.wrapper.wrap('<div class="l-labeltext"></div>').parent(); + var lable = $('<div class="l-text-label" style="float:left;">' + value + ':&nbsp</div>'); + g.labelwrapper.prepend(lable); + g.wrapper.css('float', 'left'); + if (!p.labelWidth) + { + p.labelWidth = lable.width(); + } + else + { + g._setLabelWidth(p.labelWidth); + } + lable.height(g.wrapper.height()); + if (p.labelAlign) + { + g._setLabelAlign(p.labelAlign); + } + g.labelwrapper.append('<br style="clear:both;" />'); + g.labelwrapper.width(p.labelWidth + p.width + 2); + } + else + { + g.labelwrapper.find(".l-text-label").html(value + ':&nbsp'); + } + }, + _setLabelWidth: function (value) + { + var g = this, p = this.options; + if (!g.labelwrapper) return; + g.labelwrapper.find(".l-text-label").width(value); + }, + _setLabelAlign: function (value) + { + var g = this, p = this.options; + if (!g.labelwrapper) return; + g.labelwrapper.find(".l-text-label").css('text-align', value); + }, + updateStyle: function () + { + var g = this, p = this.options; + if (g.inputText.attr('readonly')) + { + g.wrapper.addClass("l-text-readonly"); + p.disabled = true; + } + else + { + g.wrapper.removeClass("l-text-readonly"); + p.disabled = false; + } + if (g.inputText.attr('disabled')) + { + g.wrapper.addClass("l-text-disabled"); + p.disabled = true; + } + else + { + g.wrapper.removeClass("l-text-disabled"); + p.disabled = false; + } + if (g.inputText.hasClass("l-text-field-null") && g.inputText.val() != p.nullText) + { + g.inputText.removeClass("l-text-field-null"); + } + g.formatValue(); + }, + setValue: function (value) + { + this._setValue(value); + this.trigger('changeValue', [value]); + } + }); + + function currencyFormatter(num, precision) + { + var cents, sign; + if (!num) num = 0; + num = num.toString().replace(/\$|\,/g, '').replace(/[a-zA-Z]+/g, ''); + if (num.indexOf('.') > -1) num = num.replace(/[0]+$/g, ''); + if (isNaN(num)) + num = 0; + sign = (num == (num = Math.abs(num))); + + if (precision == null) + { + num = num.toString(); + cents = num.indexOf('.') != -1 ? num.substr(num.indexOf('.') + 1) : ''; + if (cents) + { + num = Math.floor(num * 1); + num = num.toString(); + } + } + else + { + precision = parseInt(precision); + var r = Math.pow(10, precision); + num = Math.floor(num * r + 0.50000000001); + cents = num % 100; + num = Math.floor(num / r).toString(); + while (cents.toString().length < precision) + { + cents = "0" + cents; + } + } + for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3) ; i++) + num = num.substring(0, num.length - (4 * i + 3)) + ',' + + num.substring(num.length - (4 * i + 3)); + var numStr = "" + (((sign) ? '' : '-') + '' + num); + if (cents) numStr += ('.' + cents); + return numStr; + } + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ + +(function ($) +{ + //气泡,可以在制定位置显示 + $.ligerTip = function (p) + { + return $.ligerui.run.call(null, "ligerTip", arguments); + }; + + //在指定Dom Element右侧显示气泡 + //target:将ligerui对象ID附加上 + $.fn.ligerTip = function (options) + { + this.each(function () + { + var p = $.extend({}, $.ligerDefaults.ElementTip, options || {}); + p.target = p.target || this; + //如果是自动模式:鼠标经过时显示,移开时关闭 + if (p.auto || options == undefined) + { + if (!p.content) + { + p.content = this.title; + if (p.removeTitle) + $(this).removeAttr("title"); + } + p.content = p.content || this.title; + $(this).bind('mouseover.tip', function () + { + p.x = $(this).offset().left + $(this).width() + (p.distanceX || 0); + p.y = $(this).offset().top + (p.distanceY || 0); + $.ligerTip(p); + }).bind('mouseout.tip', function () + { + + var tipmanager = $.ligerui.managers[this.ligeruitipid]; + if (tipmanager) + { + tipmanager.remove(); + } + }); + } + else + { + if (p.target.ligeruitipid) return; + p.x = $(this).offset().left + $(this).width() + (p.distanceX || 0); + p.y = $(this).offset().top + (p.distanceY || 0); + p.x = p.x || 0; + p.y = p.y || 0; + $.ligerTip(p); + } + }); + return $.ligerui.get(this, 'ligeruitipid'); + }; + //关闭指定在Dom Element(附加了ligerui对象ID,属性名"ligeruitipid")显示的气泡 + $.fn.ligerHideTip = function (options) + { + return this.each(function () + { + var p = options || {}; + if (p.isLabel == undefined) + { + //如果是lable,将查找指定的input,并找到ligerui对象ID + p.isLabel = this.tagName.toLowerCase() == "label" && $(this).attr("for") != null; + } + var target = this; + if (p.isLabel) + { + var forele = $("#" + $(this).attr("for")); + if (forele.length == 0) return; + target = forele[0]; + } + var tipmanager = $.ligerui.managers[target.ligeruitipid]; + if (tipmanager) + { + tipmanager.remove(); + } + }).unbind('mouseover.tip').unbind('mouseout.tip'); + }; + + + $.fn.ligerGetTipManager = function () + { + return $.ligerui.get(this); + }; + + + $.ligerDefaults = $.ligerDefaults || {}; + + + //隐藏气泡 + $.ligerDefaults.HideTip = {}; + + //气泡 + $.ligerDefaults.Tip = { + content: null, + callback: null, + width: 150, + height: null, + x: 0, + y: 0, + appendIdTo: null, //保存ID到那一个对象(jQuery)(待移除) + target: null, + auto: null, //是否自动模式,如果是,那么:鼠标经过时显示,移开时关闭,并且当content为空时自动读取attr[title] + removeTitle: true //自动模式时,默认是否移除掉title + }; + + //在指定Dom Element右侧显示气泡,通过$.fn.ligerTip调用 + $.ligerDefaults.ElementTip = { + distanceX: 1, + distanceY: -3, + auto: null, + removeTitle: true + }; + + $.ligerMethos.Tip = {}; + + $.ligerui.controls.Tip = function (options) + { + $.ligerui.controls.Tip.base.constructor.call(this, null, options); + }; + $.ligerui.controls.Tip.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'Tip'; + }, + __idPrev: function () + { + return 'Tip'; + }, + _extendMethods: function () + { + return $.ligerMethos.Tip; + }, + _render: function () + { + var g = this, p = this.options; + var tip = $('<div class="l-verify-tip"><div class="l-verify-tip-corner"></div><div class="l-verify-tip-content"></div></div>'); + g.tip = tip; + g.tip.attr("id", g.id); + if (p.content) + { + $("> .l-verify-tip-content:first", tip).html(p.content); + tip.appendTo('body'); + } + else + { + return; + } + tip.css({ left: p.x, top: p.y }).show(); + p.width && $("> .l-verify-tip-content:first", tip).width(p.width - 8); + p.height && $("> .l-verify-tip-content:first", tip).width(p.height); + eee = p.appendIdTo; + if (p.appendIdTo) + { + p.appendIdTo.attr("ligerTipId", g.id); + } + if (p.target) + { + $(p.target).attr("ligerTipId", g.id); + p.target.ligeruitipid = g.id; + } + p.callback && p.callback(tip); + g.set(p); + }, + _setContent: function (content) + { + $("> .l-verify-tip-content:first", this.tip).html(content); + }, + remove: function () + { + if (this.options.appendIdTo) + { + this.options.appendIdTo.removeAttr("ligerTipId"); + } + if (this.options.target) + { + $(this.options.target).removeAttr("ligerTipId"); + this.options.target.ligeruitipid = null; + } + this.tip.remove(); + } + }); +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + $.fn.ligerToolBar = function (options) + { + return $.ligerui.run.call(this, "ligerToolBar", arguments); + }; + + $.fn.ligerGetToolBarManager = function () + { + return $.ligerui.run.call(this, "ligerGetToolBarManager", arguments); + }; + + $.ligerDefaults.ToolBar = {}; + + $.ligerMethos.ToolBar = {}; + + $.ligerui.controls.ToolBar = function (element, options) + { + $.ligerui.controls.ToolBar.base.constructor.call(this, element, options); + }; + $.ligerui.controls.ToolBar.ligerExtend($.ligerui.core.UIComponent, { + __getType: function () + { + return 'ToolBar'; + }, + __idPrev: function () + { + return 'ToolBar'; + }, + _extendMethods: function () + { + return $.ligerMethos.ToolBar; + }, + _render: function () + { + var g = this, p = this.options; + g.toolbarItemCount = 0; + g.toolBar = $(this.element); + g.toolBar.addClass("l-toolbar"); + g.set(p); + }, + _setItems: function (items) + { + var g = this; + g.toolBar.html(""); + $(items).each(function (i, item) + { + g.addItem(item); + }); + }, + removeItem: function (itemid) + { + var g = this, p = this.options; + $("> .l-toolbar-item[toolbarid=" + itemid + "]", g.toolBar).remove(); + }, + setEnabled: function (itemid) + { + var g = this, p = this.options; + $("> .l-toolbar-item[toolbarid=" + itemid + "]", g.toolBar).removeClass("l-toolbar-item-disable"); + }, + setDisabled: function (itemid) + { + var g = this, p = this.options; + $("> .l-toolbar-item[toolbarid=" + itemid + "]", g.toolBar).addClass("l-toolbar-item-disable"); + }, + isEnable: function (itemid) + { + var g = this, p = this.options; + return !$("> .l-toolbar-item[toolbarid=" + itemid + "]", g.toolBar).hasClass("l-toolbar-item-disable"); + }, + addItem: function (item) + { + var g = this, p = this.options; + if (item.line || item.type == "line") + { + g.toolBar.append('<div class="l-bar-separator"></div>'); + return; + } + if (item.type == "text") + { + g.toolBar.append('<div class="l-toolbar-item l-toolbar-text"><span>' + item.text || "" + '</span></div>'); + return; + } + var ditem = $('<div class="l-toolbar-item l-panel-btn"><span></span><div class="l-panel-btn-l"></div><div class="l-panel-btn-r"></div></div>'); + g.toolBar.append(ditem); + if(!item.id) item.id = 'item-'+(++g.toolbarItemCount); + ditem.attr("toolbarid", item.id); + if (item.img) + { + ditem.append("<img src='" + item.img + "' />"); + ditem.addClass("l-toolbar-item-hasicon"); + } + else if (item.icon) + { + ditem.append("<div class='l-icon l-icon-" + item.icon + "'></div>"); + ditem.addClass("l-toolbar-item-hasicon"); + } + else if (item.color) + { + ditem.append("<div class='l-toolbar-item-color' style='background:"+item.color+"'></div>"); + ditem.addClass("l-toolbar-item-hasicon"); + } + item.text && $("span:first", ditem).html(item.text); + item.disable && ditem.addClass("l-toolbar-item-disable"); + item.click && ditem.click(function () { if ($(this).hasClass("l-toolbar-item-disable")) return;item.click(item); }); + if (item.menu) + { + item.menu = $.ligerMenu(item.menu); + ditem.hover(function () + { + if ($(this).hasClass("l-toolbar-item-disable")) return; + g.actionMenu && g.actionMenu.hide(); + var left = $(this).offset().left; + var top = $(this).offset().top + $(this).height(); + item.menu.show({ top: top, left: left }); + g.actionMenu = item.menu; + $(this).addClass("l-panel-btn-over"); + }, function () + { + if ($(this).hasClass("l-toolbar-item-disable")) return; + $(this).removeClass("l-panel-btn-over"); + }); + } + else + { + ditem.hover(function () + { + if ($(this).hasClass("l-toolbar-item-disable")) return; + $(this).addClass("l-panel-btn-over"); + }, function () + { + if ($(this).hasClass("l-toolbar-item-disable")) return; + $(this).removeClass("l-panel-btn-over"); + }); + } + } + }); + //旧写法保留 + $.ligerui.controls.ToolBar.prototype.setEnable = $.ligerui.controls.ToolBar.prototype.setEnabled; + $.ligerui.controls.ToolBar.prototype.setDisable = $.ligerui.controls.ToolBar.prototype.setDisabled; +})(jQuery);/** +* jQuery ligerUI 1.3.3 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + $.fn.ligerTree = function (options) + { + return $.ligerui.run.call(this, "ligerTree", arguments); + }; + + $.fn.ligerGetTreeManager = function () + { + return $.ligerui.run.call(this, "ligerGetTreeManager", arguments); + }; + + $.ligerDefaults.Tree = { + url: null, + urlParms: null, //url带参数 + data: null, + checkbox: true, + autoCheckboxEven: true, + enabledCompleteCheckbox : true, //是否启用半选择 + parentIcon: 'folder', + childIcon: 'leaf', + textFieldName: 'text', + attribute: ['id', 'url'], + treeLine: true, //是否显示line + nodeWidth: 90, + statusName: '__status', + isLeaf: null, //是否子节点的判断函数 + single: false, //是否单选 + needCancel: true, //已选的是否需要取消操作 + onBeforeExpand: function () { }, + onContextmenu: function () { }, + onExpand: function () { }, + onBeforeCollapse: function () { }, + onCollapse: function () { }, + onBeforeSelect: function () { }, + onSelect: function () { }, + onBeforeCancelSelect: function () { }, + onCancelselect: function () { }, + onCheck: function () { }, + onSuccess: function () { }, + onError: function () { }, + onClick: function () { }, + idFieldName: 'id', + parentIDFieldName: null, + topParentIDValue: 0, + onBeforeAppend: function () { }, //加载数据前事件,可以通过return false取消操作 + onAppend: function () { }, //加载数据时事件,对数据进行预处理以后 + onAfterAppend: function () { }, //加载数据完事件 + slide: true, //是否以动画的形式显示 + iconFieldName: 'icon', + nodeDraggable: false, //是否允许拖拽 + nodeDraggingRender: null, + btnClickToToggleOnly: true, //是否点击展开/收缩 按钮时才有效 + ajaxType: 'post', + ajaxContentType : null, + render: null, //自定义函数 + selectable: null, //可选择判断函数 + /* + 是否展开 + 1,可以是true/false + 2,也可以是数字(层次)N 代表第1层到第N层都是展开的,其他收缩 + 3,或者是判断函数 函数参数e(data,level) 返回true/false + + 优先级没有节点数据的isexpand属性高,并没有delay属性高 + */ + isExpand: null, + /* + 是否延迟加载 + 1,可以是true/false + 2,也可以是数字(层次)N 代表第N层延迟加载 + 3,或者是字符串(Url) 加载数据的远程地址 + 4,如果是数组,代表这些层都延迟加载,如[1,2]代表第1、2层延迟加载 + 5,再是函数(运行时动态获取延迟加载参数) 函数参数e(data,level),返回true/false或者{url:...,parms:...} + + 优先级没有节点数据的delay属性高 + */ + delay: null, + + //id字段 + idField: null, + //parent id字段,可用于线性数据转换为tree数据 + parentIDField: null, + iconClsFieldName : null + }; + + $.ligerui.controls.Tree = function (element, options) + { + $.ligerui.controls.Tree.base.constructor.call(this, element, options); + }; + + $.ligerui.controls.Tree.ligerExtend($.ligerui.core.UIComponent, { + _init: function () + { + $.ligerui.controls.Tree.base._init.call(this); + var g = this, p = this.options; + if (p.single) p.autoCheckboxEven = false; + }, + _render: function () + { + var g = this, p = this.options; + g.set(p, true); + g.tree = $(g.element); + g.tree.addClass('l-tree'); + g.toggleNodeCallbacks = []; + g.sysAttribute = ['isexpand', 'ischecked', 'href', 'style', 'delay']; + g.loading = $("<div class='l-tree-loading'></div>"); + g.tree.after(g.loading); + g.data = []; + g.maxOutlineLevel = 1; + g.treedataindex = 0; + g._applyTree(); + g._setTreeEven(); + g.set(p, false); + }, + _setTreeLine: function (value) + { + if (value) this.tree.removeClass("l-tree-noline"); + else this.tree.addClass("l-tree-noline"); + }, + _setParms: function () + { + var g = this, p = this.options; + if ($.isFunction(p.parms)) p.parms = p.parms(); + }, + reload: function (callback) + { + var g = this, p = this.options; + g.clear(); + g.loadData(null, p.url, null, { + success: callback + }); + }, + + //刷新节点 + reloadNode: function (node, data, callback) + { + var g = this, p = this.options; + g.clear(node); + if (typeof (data) == "string") + { + g.loadData(node, data, null, { + success: callback + }); + } else + { + if (!data) return; + if (p.idField && p.parentIDField) + { + data = g.arrayToTree(data, p.idField, p.parentIDField); + } + g.append(node, data); + } + }, + _setUrl: function (url) + { + var g = this, p = this.options; + if (url) + { + g.clear(); + g.loadData(null, url); + } + }, + _setData: function (data) + { + if (data) + { + this.clear(); + this.append(null, data); + } + }, + setData: function (data) + { + this.set('data', data); + }, + getData: function () + { + return this.data; + }, + //是否包含子节点 + hasChildren: function (treenodedata) + { + if (this.options.isLeaf) return !this.options.isLeaf(treenodedata); + return treenodedata.children ? true : false; + }, + //获取父节点 数据 + getParent: function (treenode, level) + { + var g = this; + treenode = g.getNodeDom(treenode); + var parentTreeNode = g.getParentTreeItem(treenode, level); + if (!parentTreeNode) return null; + var parentIndex = $(parentTreeNode).attr("treedataindex"); + return g._getDataNodeByTreeDataIndex(g.data,parentIndex); + }, + //获取父节点 + getParentTreeItem: function (treenode, level) + { + var g = this; + treenode = g.getNodeDom(treenode); + var treeitem = $(treenode); + if (treeitem.parent().hasClass("l-tree")) + return null; + if (level == undefined) + { + if (treeitem.parent().parent("li").length == 0) + return null; + return treeitem.parent().parent("li")[0]; + } + var currentLevel = parseInt(treeitem.attr("outlinelevel")); + var currenttreeitem = treeitem; + for (var i = currentLevel - 1; i >= level; i--) + { + currenttreeitem = currenttreeitem.parent().parent("li"); + } + return currenttreeitem[0]; + }, + getChecked: function () + { + var g = this, p = this.options; + if (!this.options.checkbox) return null; + var nodes = []; + $(".l-checkbox-checked", g.tree).parent().parent("li").each(function () + { + var treedataindex = parseInt($(this).attr("treedataindex")); + nodes.push({ target: this, data: g._getDataNodeByTreeDataIndex(g.data, treedataindex) }); + }); + return nodes; + }, + getCheckedData: function () + { + var g = this, p = this.options; + if (!this.options.checkbox) return null; + var nodes = []; + $(".l-checkbox-checked", g.tree).parent().parent("li").each(function () + { + var treedataindex = parseInt($(this).attr("treedataindex")); + nodes.push(g._getDataNodeByTreeDataIndex(g.data, treedataindex)); + }); + return nodes; + }, + + + + //add by superzoc 12/24/2012 + refreshTree: function () + { + var g = this, p = this.options; + $.each(this.getChecked(), function (k, v) + { + g._setParentCheckboxStatus($(v.target)); + }); + }, + getSelected: function () + { + var g = this, p = this.options; + var node = {}; + node.target = $(".l-selected", g.tree).parent("li")[0]; + if (node.target) + { + var treedataindex = parseInt($(node.target).attr("treedataindex")); + node.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + return node; + } + return null; + }, + //升级为父节点级别 + upgrade: function (treeNode) + { + var g = this, p = this.options; + $(".l-note", treeNode).each(function () + { + $(this).removeClass("l-note").addClass("l-expandable-open"); + }); + $(".l-note-last", treeNode).each(function () + { + $(this).removeClass("l-note-last").addClass("l-expandable-open"); + }); + $("." + g._getChildNodeClassName(), treeNode).each(function () + { + $(this) + .removeClass(g._getChildNodeClassName()) + .addClass(g._getParentNodeClassName(true)); + }); + }, + //降级为叶节点级别 + demotion: function (treeNode) + { + var g = this, p = this.options; + if (!treeNode && treeNode[0].tagName.toLowerCase() != 'li') return; + var islast = $(treeNode).hasClass("l-last"); + $(".l-expandable-open", treeNode).each(function () + { + $(this).removeClass("l-expandable-open") + .addClass(islast ? "l-note-last" : "l-note"); + }); + $(".l-expandable-close", treeNode).each(function () + { + $(this).removeClass("l-expandable-close") + .addClass(islast ? "l-note-last" : "l-note"); + }); + $("." + g._getParentNodeClassName(true), treeNode).each(function () + { + $(this) + .removeClass(g._getParentNodeClassName(true)) + .addClass(g._getChildNodeClassName()); + }); + }, + collapseAll: function () + { + var g = this, p = this.options; + $(".l-expandable-open", g.tree).click(); + }, + expandAll: function () + { + var g = this, p = this.options; + $(".l-expandable-close", g.tree).click(); + }, + arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式 + { + var g = this, p = this.options; + var childrenName = "children"; + if (!data || !data.length) return []; + var targetData = []; //存储数据的容器(返回) + var records = {}; + var itemLength = data.length; //数据集合的个数 + for (var i = 0; i < itemLength; i++) + { + var o = data[i]; + var key = getKey(o[id]); + records[key] = o; + } + for (var i = 0; i < itemLength; i++) + { + var currentData = data[i]; + var key = getKey(currentData[pid]); + var parentData = records[key]; + if (!parentData) + { + targetData.push(currentData); + continue; + } + parentData[childrenName] = parentData[childrenName] || []; + parentData[childrenName].push(currentData); + } + return targetData; + + function getKey(key) + { + if (typeof (key) == "string") key = key.replace(/[.]/g, '').toLowerCase(); + return key; + } + }, + loadData: function (node, url, param, e) + { + var g = this, p = this.options; + e = $.extend({ + showLoading: function () + { + g.loading.show(); + }, + success: function () { }, + error: function () { }, + hideLoading: function () + { + g.loading.hide(); + } + }, e || {}); + var ajaxtype = p.ajaxType; + //解决树无法设置parms的问题 + param = $.extend(($.isFunction(p.parms) ? p.parms() : p.parms), param); + if (p.ajaxContentType == "application/json" && typeof (param) != "string") + { + param = liger.toJSON(param); + } + var urlParms = $.isFunction(p.urlParms) ? p.urlParms.call(g) : p.urlParms; + if (urlParms) + { + for (name in urlParms) + { + url += url.indexOf('?') == -1 ? "?" : "&"; + url += name + "=" + urlParms[name]; + } + } + var ajaxOp = { + type: ajaxtype, + url: url, + data: param, + dataType: 'json', + beforeSend: function () + { + e.showLoading(); + }, + success: function (data) + { + if (!data) return; + if (p.idField && p.parentIDField) + { + data = g.arrayToTree(data, p.idField, p.parentIDField); + } + e.hideLoading(); + g.append(node, data); + g.trigger('success', [data]); + e.success(data); + }, + error: function (XMLHttpRequest, textStatus, errorThrown) + { + try + { + e.hideLoading(); + g.trigger('error', [XMLHttpRequest, textStatus, errorThrown]); + e.error(XMLHttpRequest, textStatus, errorThrown); + } + catch (e) + { + + } + } + }; + if (p.ajaxContentType) + { + ajaxOp.contentType = p.ajaxContentType; + } + $.ajax(ajaxOp); + }, + + //清空 + clear: function (node) + { + var g = this, p = this.options; + if (!node) + { + g.toggleNodeCallbacks = []; + g.data = null; + g.data = []; + g.nodes = null; + g.tree.html(""); + } else + { + + var nodeDom = g.getNodeDom(node); + var nodeData = g._getDataNodeByTreeDataIndex(g.data, $(nodeDom).attr("treedataindex")); + $(nodeDom).find("ul.l-children").remove(); + if (nodeData) nodeData.children = []; + } + }, + + //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex + getNodeDom: function (nodeParm) + { + var g = this, p = this.options; + if (nodeParm == null) return nodeParm; + if (typeof (nodeParm) == "string" || typeof (nodeParm) == "number") + { + return $("li[treedataindex=" + nodeParm + "]", g.tree).get(0); + } + else if (typeof (nodeParm) == "object" && 'treedataindex' in nodeParm) //nodedata + { + return g.getNodeDom(nodeParm['treedataindex']); + } else if(nodeParm.target && nodeParm.data) + { + return nodeParm.target; + } + return nodeParm; + }, + hide: function (treeNode) + { + var g = this, p = this.options; + treeNode = g.getNodeDom(treeNode); + if (treeNode) $(treeNode).hide(); + }, + show: function (treeNode) + { + var g = this, p = this.options; + treeNode = g.getNodeDom(treeNode); + if (treeNode) $(treeNode).show(); + }, + //parm [treeNode] dom节点(li)、节点数据 或者节点 dataindex + remove: function (treeNode) + { + var g = this, p = this.options; + treeNode = g.getNodeDom(treeNode); + var treedataindex = parseInt($(treeNode).attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + if (treenodedata) g._setTreeDataStatus([treenodedata], 'delete'); + var parentNode = g.getParentTreeItem(treeNode); + //复选框处理 + if (p.checkbox) + { + g._setParentCheckboxStatus($(treeNode)); + } + $(treeNode).remove(); + g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); + }, + _updateStyle: function (ul) + { + var g = this, p = this.options; + var itmes = $(" > li", ul); + var treeitemlength = itmes.length; + if (!treeitemlength) return; + //遍历设置子节点的样式 + itmes.each(function (i, item) + { + if (i == 0 && !$(this).hasClass("l-first")) + $(this).addClass("l-first"); + if (i == treeitemlength - 1 && !$(this).hasClass("l-last")) + $(this).addClass("l-last"); + if (i == 0 && i == treeitemlength - 1) + $(this).addClass("l-onlychild"); + $("> div .l-note,> div .l-note-last", this) + .removeClass("l-note l-note-last") + .addClass(i == treeitemlength - 1 ? "l-note-last" : "l-note"); + g._setTreeItem(this, { isLast: i == treeitemlength - 1 }); + }); + }, + //parm [domnode] dom节点(li)、节点数据 或者节点 dataindex + update: function (domnode, newnodedata) + { + var g = this, p = this.options; + domnode = g.getNodeDom(domnode); + var treedataindex = parseInt($(domnode).attr("treedataindex")); + nodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + for (var attr in newnodedata) + { + nodedata[attr] = newnodedata[attr]; + if (attr == p.textFieldName) + { + $("> .l-body > span", domnode).text(newnodedata[attr]); + } + } + }, + //增加节点集合 + //parm [newdata] 数据集合 Array + //parm [parentNode] dom节点(li)、节点数据 或者节点 dataindex + //parm [nearNode] 附加到节点的上方/下方(非必填) + //parm [isAfter] 附加到节点的下方(非必填) + append: function (parentNode, newdata, nearNode, isAfter) + { + var g = this, p = this.options; + parentNode = g.getNodeDom(parentNode); + if (g.trigger('beforeAppend', [parentNode, newdata]) == false) return false; + if (!newdata || !newdata.length) return false; + if (p.idFieldName && p.parentIDFieldName) + newdata = g.arrayToTree(newdata, p.idFieldName, p.parentIDFieldName); + g._addTreeDataIndexToData(newdata); + g._setTreeDataStatus(newdata, 'add'); + if (nearNode != null) + { + nearNode = g.getNodeDom(nearNode); + } + g.trigger('append', [parentNode, newdata]) + g._appendData(parentNode, newdata); + if (parentNode == null)//增加到根节点 + { + var gridhtmlarr = g._getTreeHTMLByData(newdata, 1, [], true); + gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; + if (nearNode != null) + { + $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join('')); + g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); + } + else + { + //remove last node class + if ($("> li:last", g.tree).length > 0) + g._setTreeItem($("> li:last", g.tree)[0], { isLast: false }); + g.tree.append(gridhtmlarr.join('')); + } + $(".l-body", g.tree).hover(function () + { + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + g._upadteTreeWidth(); + g.trigger('afterAppend', [parentNode, newdata]) + return; + } + var treeitem = $(parentNode); + var outlineLevel = parseInt(treeitem.attr("outlinelevel")); + + var hasChildren = $("> ul", treeitem).length > 0; + if (!hasChildren) + { + treeitem.append("<ul class='l-children'></ul>"); + //设置为父节点 + g.upgrade(parentNode); + } + var isLast = []; + for (var i = 1; i <= outlineLevel - 1; i++) + { + var currentParentTreeItem = $(g.getParentTreeItem(parentNode, i)); + isLast.push(currentParentTreeItem.hasClass("l-last")); + } + isLast.push(treeitem.hasClass("l-last")); + var gridhtmlarr = g._getTreeHTMLByData(newdata, outlineLevel + 1, isLast, true); + gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; + if (nearNode != null) + { + $(nearNode)[isAfter ? 'after' : 'before'](gridhtmlarr.join('')); + g._updateStyle(parentNode ? $("ul:first", parentNode) : g.tree); + } + else + { + //remove last node class + if ($("> .l-children > li:last", treeitem).length > 0) + g._setTreeItem($("> .l-children > li:last", treeitem)[0], { isLast: false }); + $(">.l-children", parentNode).append(gridhtmlarr.join('')); + } + g._upadteTreeWidth(); + $(">.l-children .l-body", parentNode).hover(function () + { + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + g.trigger('afterAppend', [parentNode, newdata]); + }, + //parm [nodeParm] dom节点(li)、节点数据 或者节点 dataindex + cancelSelect: function (nodeParm, isTriggerEvent) + { + var g = this, p = this.options; + var domNode = g.getNodeDom(nodeParm); + var treeitem = $(domNode); + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + var treeitembody = $(">div:first", treeitem); + if (p.checkbox) + $(".l-checkbox", treeitembody).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked"); + else + treeitembody.removeClass("l-selected"); + if (isTriggerEvent != false) + { + g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0] }]); + } + }, + //选择节点(参数:条件函数、Dom节点或ID值) + selectNode: function (selectNodeParm,isTriggerEvent) + { + var g = this, p = this.options; + var clause = null; + if (typeof (selectNodeParm) == "function") + { + clause = selectNodeParm; + } + else if (typeof (selectNodeParm) == "object") + { + var treeitem = $(selectNodeParm); + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + var treeitembody = $(">div:first", treeitem); + if (!treeitembody.length) + { + treeitembody = $("li[treedataindex=" + treedataindex + "] >div:first", g.tree); + } + if (p.checkbox) + { + $(".l-checkbox", treeitembody).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked"); + } + else + { + $("div.l-selected", g.tree).removeClass("l-selected"); + treeitembody.addClass("l-selected"); + } + if (isTriggerEvent != false) + { + g.trigger('select', [{ data: treenodedata, target: treeitembody.parent().get(0) }]); + } + return; + } + else + { + clause = function (data) + { + if (!data[p.idFieldName] && data[p.idFieldName] != 0) return false; + return strTrim(data[p.idFieldName].toString()) == strTrim(selectNodeParm.toString()); + }; + } + $("li", g.tree).each(function () + { + var treeitem = $(this); + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + if (clause(treenodedata, treedataindex)) + { + g.selectNode(this, isTriggerEvent); + } + else + { + //修复多选checkbox为true时调用该方法会取消已经选中节点的问题 + if (!g.options.checkbox) + { + g.cancelSelect(this, isTriggerEvent); + } + } + }); + }, + getTextByID: function (id) + { + var g = this, p = this.options; + var data = g.getDataByID(id); + if (!data) return null; + return data[p.textFieldName]; + }, + getDataByID: function (id) + { + var g = this, p = this.options; + var data = null; + + if (g.data && g.data.length) + { + return find(g.data); + } + + function find(items) + { + for (var i = 0; i < items.length; i++) + { + var dataItem = items[i]; + if (dataItem[p.idFieldName] == id) return dataItem; + if (dataItem.children && dataItem.children.length) + { + var o = find(dataItem.children); + if (o) return o; + } + } + return null; + } + + + $("li", g.tree).each(function () + { + if (data) return; + var treeitem = $(this); + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + if (treenodedata[p.idFieldName].toString() == id.toString()) + { + data = treenodedata; + } + }); + return data; + }, + arrayToTree: function (data, id, pid) //将ID、ParentID这种数据格式转换为树格式 + { + if (!data || !data.length) return []; + var targetData = []; //存储数据的容器(返回) + var records = {}; + var itemLength = data.length; //数据集合的个数 + for (var i = 0; i < itemLength; i++) + { + var o = data[i]; + records[o[id]] = o; + } + for (var i = 0; i < itemLength; i++) + { + var currentData = data[i]; + var parentData = records[currentData[pid]]; + if (!parentData) + { + targetData.push(currentData); + continue; + } + parentData.children = parentData.children || []; + parentData.children.push(currentData); + } + return targetData; + }, + + + + + //根据数据索引获取数据 + _getDataNodeByTreeDataIndex: function (data, treedataindex) + { + var g = this, p = this.options; + for (var i = 0; i < data.length; i++) + { + if (data[i].treedataindex == treedataindex) + return data[i]; + if (data[i].children) + { + var targetData = g._getDataNodeByTreeDataIndex(data[i].children, treedataindex); + if (targetData) return targetData; + } + } + return null; + }, + //设置数据状态 + _setTreeDataStatus: function (data, status) + { + var g = this, p = this.options; + $(data).each(function () + { + this[p.statusName] = status; + if (this.children) + { + g._setTreeDataStatus(this.children, status); + } + }); + }, + //设置data 索引 + _addTreeDataIndexToData: function (data) + { + var g = this, p = this.options; + $(data).each(function () + { + if (this.treedataindex != undefined) return; + this.treedataindex = g.treedataindex++; + if (this.children) + { + g._addTreeDataIndexToData(this.children); + } + }); + }, + _addToNodes: function (data) + { + var g = this, p = this.options; + g.nodes = g.nodes || []; + g.nodes.push(data); + if (!data.children) return; + $(data.children).each(function (i, item) + { + g._addToNodes(item); + }); + }, + //添加项到g.data + _appendData: function (treeNode, data) + { + var g = this, p = this.options; + var treedataindex = parseInt($(treeNode).attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + if (g.treedataindex == undefined) g.treedataindex = 0; + if (treenodedata && treenodedata.children == undefined) treenodedata.children = []; + $(data).each(function (i, item) + { + if (treenodedata) + treenodedata.children[treenodedata.children.length] = item; + else + g.data[g.data.length] = item; + g._addToNodes(item); + }); + }, + _setTreeItem: function (treeNode, options) + { + var g = this, p = this.options; + if (!options) return; + treeNode = g.getNodeDom(treeNode); + var treeItem = $(treeNode); + var outlineLevel = parseInt(treeItem.attr("outlinelevel")); + if (options.isLast != undefined) + { + if (options.isLast == true) + { + treeItem.removeClass("l-last").addClass("l-last"); + $("> div .l-note", treeItem).removeClass("l-note").addClass("l-note-last"); + $(".l-children li", treeItem) + .find(".l-box:eq(" + (outlineLevel - 1) + ")") + .removeClass("l-line"); + } + else if (options.isLast == false) + { + treeItem.removeClass("l-last"); + $("> div .l-note-last", treeItem).removeClass("l-note-last").addClass("l-note"); + + $(".l-children li", treeItem) + .find(".l-box:eq(" + (outlineLevel - 1) + ")") + .removeClass("l-line") + .addClass("l-line"); + } + } + }, + _upadteTreeWidth: function () + { + var g = this, p = this.options; + var treeWidth = g.maxOutlineLevel * 22; + if (p.checkbox) treeWidth += 22; + if (p.parentIcon || p.childIcon) treeWidth += 22; + treeWidth += p.nodeWidth; + g.tree.width(treeWidth); + }, + _getChildNodeClassName: function () + { + var g = this, p = this.options; + return 'l-tree-icon-' + p.childIcon; + }, + _getParentNodeClassName: function (isOpen) + { + var g = this, p = this.options; + var nodeclassname = 'l-tree-icon-' + p.parentIcon; + if (isOpen) nodeclassname += '-open'; + return nodeclassname; + }, + //判断节点是否展开状态,返回true/false + _isExpand: function (o, level) + { + var g = this, p = this.options; + var isExpand = o.isExpand != null ? o.isExpand : (o.isexpand != null ? o.isexpand : p.isExpand); + if (isExpand == null) return true; + if (typeof (isExpand) == "function") isExpand = p.isExpand({ data: o, level: level }); + if (typeof (isExpand) == "boolean") return isExpand; + if (typeof (isExpand) == "string") return isExpand == "true"; + if (typeof (isExpand) == "number") return isExpand > level; + return true; + }, + //获取节点的延迟加载状态,返回true/false (本地模式) 或者是object({url :'...',parms:null})(远程模式) + _getDelay: function (o, level) + { + var g = this, p = this.options; + var delay = o.delay != null ? o.delay : p.delay; + if (delay == null) return false; + if (typeof (delay) == "function") delay = delay({ data: o, level: level }); + if (typeof (delay) == "boolean") return delay; + if (typeof (delay) == "string") return { url: delay }; + if (typeof (delay) == "number") delay = [delay]; + if ($.isArray(delay)) return $.inArray(level, delay) != -1; + if (typeof (delay) == "object" && delay.url) return delay; + return false; + }, + //根据data生成最终完整的tree html + _getTreeHTMLByData: function (data, outlineLevel, isLast, isExpand) + { + var g = this, p = this.options; + if (g.maxOutlineLevel < outlineLevel) + g.maxOutlineLevel = outlineLevel; + isLast = isLast || []; + outlineLevel = outlineLevel || 1; + var treehtmlarr = []; + if (!isExpand) treehtmlarr.push('<ul class="l-children" style="display:none">'); + else treehtmlarr.push("<ul class='l-children'>"); + for (var i = 0; i < data.length; i++) + { + var o = data[i]; + var isFirst = i == 0; + var isLastCurrent = i == data.length - 1; + var delay = g._getDelay(o, outlineLevel); + var isExpandCurrent = delay ? false : g._isExpand(o, outlineLevel); + + treehtmlarr.push('<li '); + if (o.treedataindex != undefined) + treehtmlarr.push('treedataindex="' + o.treedataindex + '" '); + if (isExpandCurrent) + treehtmlarr.push('isexpand=' + o.isexpand + ' '); + treehtmlarr.push('outlinelevel=' + outlineLevel + ' '); + //增加属性支持 + for (var j = 0; j < g.sysAttribute.length; j++) + { + if ($(this).attr(g.sysAttribute[j])) + data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]); + } + for (var j = 0; j < p.attribute.length; j++) + { + if (o[p.attribute[j]]) + treehtmlarr.push(p.attribute[j] + '="' + o[p.attribute[j]] + '" '); + } + + //css class + treehtmlarr.push('class="'); + isFirst && treehtmlarr.push('l-first '); + isLastCurrent && treehtmlarr.push('l-last '); + isFirst && isLastCurrent && treehtmlarr.push('l-onlychild '); + treehtmlarr.push('"'); + treehtmlarr.push('>'); + treehtmlarr.push('<div class="l-body'); + if (p.selectable && p.selectable(o) == false) + { + treehtmlarr.push(' l-unselectable'); + } + treehtmlarr.push('">'); + for (var k = 0; k <= outlineLevel - 2; k++) + { + if (isLast[k]) treehtmlarr.push('<div class="l-box"></div>'); + else treehtmlarr.push('<div class="l-box l-line"></div>'); + } + if (g.hasChildren(o)) + { + if (isExpandCurrent) treehtmlarr.push('<div class="l-box l-expandable-open"></div>'); + else treehtmlarr.push('<div class="l-box l-expandable-close"></div>'); + if (p.checkbox) + { + if (o.ischecked) + treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>'); + else + treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>'); + } + if (p.parentIcon) + { + //node icon + treehtmlarr.push('<div class="l-box l-tree-icon '); + treehtmlarr.push(g._getParentNodeClassName(isExpandCurrent ? true : false) + " "); + if (p.iconFieldName && o[p.iconFieldName]) + treehtmlarr.push('l-tree-icon-none'); + else if (p.iconClsFieldName && o[p.iconClsFieldName]) + treehtmlarr.push('l-tree-icon-' + o[p.iconClsFieldName] + " "); + treehtmlarr.push('">'); + if (p.iconFieldName && o[p.iconFieldName]) + treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />'); + treehtmlarr.push('</div>'); + } + } + else + { + if (isLastCurrent) treehtmlarr.push('<div class="l-box l-note-last"></div>'); + else treehtmlarr.push('<div class="l-box l-note"></div>'); + if (p.checkbox) + { + if (o.ischecked) + treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-checked"></div>'); + else + treehtmlarr.push('<div class="l-box l-checkbox l-checkbox-unchecked"></div>'); + } + if (p.childIcon) + { + //node icon + treehtmlarr.push('<div class="l-box l-tree-icon '); + treehtmlarr.push(g._getChildNodeClassName() + " "); + if (p.iconFieldName && o[p.iconFieldName]) + treehtmlarr.push('l-tree-icon-none'); + else if (p.iconClsFieldName && o[p.iconClsFieldName]) + treehtmlarr.push('l-tree-icon-' + o[p.iconClsFieldName] + " "); + + treehtmlarr.push('">'); + if (p.iconFieldName && o[p.iconFieldName]) + treehtmlarr.push('<img src="' + o[p.iconFieldName] + '" />'); + treehtmlarr.push('</div>'); + } + } + if (p.render) + { + treehtmlarr.push('<span>' + p.render(o, o[p.textFieldName]) + '</span>'); + } else + { + treehtmlarr.push('<span>' + o[p.textFieldName] + '</span>'); + } + treehtmlarr.push('</div>'); + if (g.hasChildren(o)) + { + var isLastNew = []; + for (var k = 0; k < isLast.length; k++) + { + isLastNew.push(isLast[k]); + } + isLastNew.push(isLastCurrent); + if (delay) + { + if (delay == true) + { + g.toggleNodeCallbacks.push({ + data: o, + callback: function (dom, o) + { + var content = g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join(''); + $(dom).append(content); + $(">.l-children .l-body", dom).hover(function () + { + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + g._removeToggleNodeCallback(o); + } + }); + } + else if (delay.url) + { + (function (o, url, parms) + { + g.toggleNodeCallbacks.push({ + data: o, + callback: function (dom, o) + { + g.loadData(dom, url, parms, { + showLoading: function () + { + $("div.l-expandable-close:first", dom).addClass("l-box-loading"); + }, + hideLoading: function () + { + $("div.l-box-loading:first", dom).removeClass("l-box-loading"); + } + }); + g._removeToggleNodeCallback(o); + } + }); + })(o, delay.url, delay.parms); + } + } + else + { + treehtmlarr.push(g._getTreeHTMLByData(o.children, outlineLevel + 1, isLastNew, isExpandCurrent).join('')); + } + + } + treehtmlarr.push('</li>'); + } + treehtmlarr.push("</ul>"); + return treehtmlarr; + + }, + _removeToggleNodeCallback: function (nodeData) + { + var g = this, p = this.options; + for (var i = 0; i <= g.toggleNodeCallbacks.length; i++) + { + if (g.toggleNodeCallbacks[i] && g.toggleNodeCallbacks[i].data == nodeData) + { + g.toggleNodeCallbacks.splice(i, 1); + break; + } + } + }, + //根据简洁的html获取data + _getDataByTreeHTML: function (treeDom) + { + var g = this, p = this.options; + var data = []; + $("> li", treeDom).each(function (i, item) + { + var dataindex = data.length; + data[dataindex] = + { + treedataindex: g.treedataindex++ + }; + data[dataindex][p.textFieldName] = $("> span,> a", this).html(); + for (var j = 0; j < g.sysAttribute.length; j++) + { + if ($(this).attr(g.sysAttribute[j])) + data[dataindex][g.sysAttribute[j]] = $(this).attr(g.sysAttribute[j]); + } + for (var j = 0; j < p.attribute.length; j++) + { + if ($(this).attr(p.attribute[j])) + data[dataindex][p.attribute[j]] = $(this).attr(p.attribute[j]); + } + if ($("> ul", this).length > 0) + { + data[dataindex].children = g._getDataByTreeHTML($("> ul", this)); + } + }); + return data; + }, + _applyTree: function () + { + var g = this, p = this.options; + g.data = g._getDataByTreeHTML(g.tree); + var gridhtmlarr = g._getTreeHTMLByData(g.data, 1, [], true); + gridhtmlarr[gridhtmlarr.length - 1] = gridhtmlarr[0] = ""; + g.tree.html(gridhtmlarr.join('')); + g._upadteTreeWidth(); + $(".l-body", g.tree).hover(function () + { + $(this).addClass("l-over"); + }, function () + { + $(this).removeClass("l-over"); + }); + }, + _getSrcElementByEvent: function (e) + { + var g = this; + var obj = (e.target || e.srcElement); + var tag = obj.tagName.toLowerCase(); + var jobjs = $(obj).parents().add(obj); + var fn = function (parm) + { + for (var i = jobjs.length - 1; i >= 0; i--) + { + if ($(jobjs[i]).hasClass(parm)) return jobjs[i]; + } + return null; + }; + if (jobjs.index(this.element) == -1) return { out: true }; + var r = { + tree: fn("l-tree"), + node: fn("l-body"), + checkbox: fn("l-checkbox"), + icon: fn("l-tree-icon"), + text: tag == "span" + }; + if (r.node) + { + var treedataindex = parseInt($(r.node).parent().attr("treedataindex")); + r.data = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + } + return r; + }, + _setTreeEven: function () + { + var g = this, p = this.options; + if (g.hasBind('contextmenu')) + { + g.tree.bind("contextmenu", function (e) + { + var obj = (e.target || e.srcElement); + var treeitem = null; + if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box")) + treeitem = $(obj).parent().parent(); + else if ($(obj).hasClass("l-body")) + treeitem = $(obj).parent(); + else if (obj.tagName.toLowerCase() == "li") + treeitem = $(obj); + if (!treeitem) return; + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + return g.trigger('contextmenu', [{ data: treenodedata, target: treeitem[0] }, e]); + }); + } + g.tree.click(function (e) + { + var obj = (e.target || e.srcElement); + var treeitem = null; + if (obj.tagName.toLowerCase() == "a" || obj.tagName.toLowerCase() == "span" || $(obj).hasClass("l-box")) + treeitem = $(obj).parent().parent(); + else if ($(obj).hasClass("l-body")) + treeitem = $(obj).parent(); + else + treeitem = $(obj); + if (!treeitem) return; + var treedataindex = parseInt(treeitem.attr("treedataindex")); + var treenodedata = g._getDataNodeByTreeDataIndex(g.data, treedataindex); + var treeitembtn = $("div.l-body:first", treeitem).find("div.l-expandable-open:first,div.l-expandable-close:first"); + var clickOnTreeItemBtn = $(obj).hasClass("l-expandable-open") || $(obj).hasClass("l-expandable-close"); + if (!$(obj).hasClass("l-checkbox") && !clickOnTreeItemBtn) + { + if (!treeitem.hasClass("l-unselectable")) + { + if ($(">div:first", treeitem).hasClass("l-selected") && p.needCancel) + { + if (g.trigger('beforeCancelSelect', [{ data: treenodedata, target: treeitem[0] }]) == false) + return false; + + $(">div:first", treeitem).removeClass("l-selected"); + g.trigger('cancelSelect', [{ data: treenodedata, target: treeitem[0] }]); + } + else + { + if (g.trigger('beforeSelect', [{ data: treenodedata, target: treeitem[0] }]) == false) + return false; + $(".l-body", g.tree).removeClass("l-selected"); + $(">div:first", treeitem).addClass("l-selected"); + g.trigger('select', [{ data: treenodedata, target: treeitem[0] }]) + } + } + } + //chekcbox even + if ($(obj).hasClass("l-checkbox")) + { + if (p.autoCheckboxEven) + { + //状态:未选中 + if ($(obj).hasClass("l-checkbox-unchecked")) + { + $(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked"); + $(".l-children .l-checkbox", treeitem) + .removeClass("l-checkbox-incomplete l-checkbox-unchecked") + .addClass("l-checkbox-checked"); + g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]); + } + //状态:选中 + else if ($(obj).hasClass("l-checkbox-checked")) + { + $(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked"); + $(".l-children .l-checkbox", treeitem) + .removeClass("l-checkbox-incomplete l-checkbox-checked") + .addClass("l-checkbox-unchecked"); + g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]); + } + //状态:未完全选中 + else if ($(obj).hasClass("l-checkbox-incomplete")) + { + $(obj).removeClass("l-checkbox-incomplete").addClass("l-checkbox-checked"); + $(".l-children .l-checkbox", treeitem) + .removeClass("l-checkbox-incomplete l-checkbox-unchecked") + .addClass("l-checkbox-checked"); + g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]); + } + g._setParentCheckboxStatus(treeitem); + } + else + { + //状态:未选中 + if ($(obj).hasClass("l-checkbox-unchecked")) + { + $(obj).removeClass("l-checkbox-unchecked").addClass("l-checkbox-checked"); + //是否单选 + if (p.single) + { + $(".l-checkbox", g.tree).not(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked"); + } + g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, true]); + } + //状态:选中 + else if ($(obj).hasClass("l-checkbox-checked")) + { + $(obj).removeClass("l-checkbox-checked").addClass("l-checkbox-unchecked"); + g.trigger('check', [{ data: treenodedata, target: treeitem[0] }, false]); + } + } + } + //状态:已经张开 + else if (treeitembtn.hasClass("l-expandable-open") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn)) + { + if (g.trigger('beforeCollapse', [{ data: treenodedata, target: treeitem[0] }]) == false) + return false; + treeitembtn.removeClass("l-expandable-open").addClass("l-expandable-close"); + if (p.slide) + $("> .l-children", treeitem).slideToggle('fast'); + else + $("> .l-children", treeitem).hide(); + $("> div ." + g._getParentNodeClassName(true), treeitem) + .removeClass(g._getParentNodeClassName(true)) + .addClass(g._getParentNodeClassName()); + g.trigger('collapse', [{ data: treenodedata, target: treeitem[0] }]); + } + //状态:没有张开 + else if (treeitembtn.hasClass("l-expandable-close") && (!p.btnClickToToggleOnly || clickOnTreeItemBtn)) + { + if (g.trigger('beforeExpand', [{ data: treenodedata, target: treeitem[0] }]) == false) + return false; + + $(g.toggleNodeCallbacks).each(function () + { + if (this.data == treenodedata) + { + this.callback(treeitem[0], treenodedata); + } + }); + treeitembtn.removeClass("l-expandable-close").addClass("l-expandable-open"); + var callback = function () + { + g.trigger('expand', [{ data: treenodedata, target: treeitem[0] }]); + }; + if (p.slide) + { + $("> .l-children", treeitem).slideToggle('fast', callback); + } + else + { + $("> .l-children", treeitem).show(); + callback(); + } + $("> div ." + g._getParentNodeClassName(), treeitem) + .removeClass(g._getParentNodeClassName()) + .addClass(g._getParentNodeClassName(true)); + } + g.trigger('click', [{ data: treenodedata, target: treeitem[0] }]); + }); + + //节点拖拽支持 + if ($.fn.ligerDrag && p.nodeDraggable) + { + g.nodeDroptip = $("<div class='l-drag-nodedroptip' style='display:none'></div>").appendTo('body'); + g.tree.ligerDrag({ + revert: true, animate: false, + proxyX: 20, proxyY: 20, + proxy: function (draggable, e) + { + var src = g._getSrcElementByEvent(e); + if (src.node) + { + var content = "dragging"; + if (p.nodeDraggingRender) + { + content = p.nodeDraggingRender(draggable.draggingNodes, draggable, g); + } + else + { + content = ""; + var appended = false; + for (var i in draggable.draggingNodes) + { + var node = draggable.draggingNodes[i]; + if (appended) content += ","; + content += node.text; + appended = true; + } + } + var proxy = $("<div class='l-drag-proxy' style='display:none'><div class='l-drop-icon l-drop-no'></div>" + content + "</div>").appendTo('body'); + return proxy; + } + }, + onRevert: function () { return false; }, + onRendered: function () + { + this.set('cursor', 'default'); + g.children[this.id] = this; + }, + onStartDrag: function (current, e) + { + if (e.button == 2) return false; + this.set('cursor', 'default'); + var src = g._getSrcElementByEvent(e); + if (src.checkbox) return false; + if (p.checkbox) + { + var checked = g.getChecked(); + this.draggingNodes = []; + for (var i in checked) + { + this.draggingNodes.push(checked[i].data); + } + if (!this.draggingNodes || !this.draggingNodes.length) return false; + } + else + { + this.draggingNodes = [src.data]; + } + this.draggingNode = src.data; + this.set('cursor', 'move'); + g.nodedragging = true; + this.validRange = { + top: g.tree.offset().top, + bottom: g.tree.offset().top + g.tree.height(), + left: g.tree.offset().left, + right: g.tree.offset().left + g.tree.width() + }; + }, + onDrag: function (current, e) + { + var nodedata = this.draggingNode; + if (!nodedata) return false; + var nodes = this.draggingNodes ? this.draggingNodes : [nodedata]; + if (g.nodeDropIn == null) g.nodeDropIn = -1; + var pageX = e.pageX; + var pageY = e.pageY; + var visit = false; + var validRange = this.validRange; + if (pageX < validRange.left || pageX > validRange.right + || pageY > validRange.bottom || pageY < validRange.top) + { + + g.nodeDropIn = -1; + g.nodeDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no"); + return; + } + for (var i = 0, l = g.nodes.length; i < l; i++) + { + var nd = g.nodes[i]; + var treedataindex = nd['treedataindex']; + if (nodedata['treedataindex'] == treedataindex) visit = true; + if ($.inArray(nd, nodes) != -1) continue; + var isAfter = visit ? true : false; + if (g.nodeDropIn != -1 && g.nodeDropIn != treedataindex) continue; + var jnode = $("li[treedataindex=" + treedataindex + "] div:first", g.tree); + var offset = jnode.offset(); + var range = { + top: offset.top, + bottom: offset.top + jnode.height(), + left: g.tree.offset().left, + right: g.tree.offset().left + g.tree.width() + }; + if (pageX > range.left && pageX < range.right && pageY > range.top && pageY < range.bottom) + { + var lineTop = offset.top; + if (isAfter) lineTop += jnode.height(); + g.nodeDroptip.css({ + left: range.left, + top: lineTop, + width: range.right - range.left + }).show(); + g.nodeDropIn = treedataindex; + g.nodeDropDir = isAfter ? "bottom" : "top"; + if (pageY > range.top + 7 && pageY < range.bottom - 7) + { + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-yes").addClass("l-drop-add"); + g.nodeDroptip.hide(); + g.nodeDropInParent = true; + } + else + { + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-no l-drop-add").addClass("l-drop-yes"); + g.nodeDroptip.show(); + g.nodeDropInParent = false; + } + break; + } + else if (g.nodeDropIn != -1) + { + g.nodeDropIn = -1; + g.nodeDropInParent = false; + g.nodeDroptip.hide(); + this.proxy.find(".l-drop-icon:first").removeClass("l-drop-yes l-drop-add").addClass("l-drop-no"); + } + } + }, + onStopDrag: function (current, e) + { + var nodes = this.draggingNodes; + g.nodedragging = false; + if (g.nodeDropIn != -1) + { + for (var i = 0; i < nodes.length; i++) + { + var children = nodes[i].children; + if (children) + { + nodes = $.grep(nodes, function (node, i) + { + var isIn = $.inArray(node, children) == -1; + return isIn; + }); + } + } + for (var i in nodes) + { + var node = nodes[i]; + if (g.nodeDropInParent) + { + g.remove(node); + g.append(g.nodeDropIn, [node]); + } + else + { + g.remove(node); + g.append(g.getParent(g.nodeDropIn), [node], g.nodeDropIn, g.nodeDropDir == "bottom") + } + } + g.nodeDropIn = -1; + } + g.nodeDroptip.hide(); + this.set('cursor', 'default'); + } + }); + } + }, + //递归设置父节点的状态 + _setParentCheckboxStatus: function (treeitem) + { + var g = this, p = this.options; + //当前同级别或低级别的节点是否都选中了 + var isCheckedComplete = $(".l-checkbox-unchecked", treeitem.parent()).length == 0; + //当前同级别或低级别的节点是否都没有选中 + var isCheckedNull = $(".l-checkbox-checked", treeitem.parent()).length == 0; + + if (isCheckedNull) + { + treeitem.parent().prev().find("> .l-checkbox") + .removeClass("l-checkbox-checked l-checkbox-incomplete") + .addClass("l-checkbox-unchecked"); + } + else + { + if (isCheckedComplete || !p.enabledCompleteCheckbox) + { + treeitem.parent().prev().find(".l-checkbox") + .removeClass("l-checkbox-unchecked l-checkbox-incomplete") + .addClass("l-checkbox-checked"); + } + else + { + treeitem.parent().prev().find("> .l-checkbox") + .removeClass("l-checkbox-unchecked l-checkbox-checked") + .addClass("l-checkbox-incomplete"); + } + } + if (treeitem.parent().parent("li").length > 0) + g._setParentCheckboxStatus(treeitem.parent().parent("li")); + } + }); + + + + function strTrim(str) + { + if (!str) return str; + return str.replace(/(^\s*)|(\s*$)/g, ''); + }; + +})(jQuery);/** +* jQuery ligerUI 1.3.2 +* +* http://ligerui.com +* +* Author daomi 2015 [ gd_star@163.com ] +* +*/ +(function ($) +{ + + var l = $.ligerui; + + l.windowCount = 0; + + $.ligerWindow = function (options) + { + return l.run.call(null, "ligerWindow", arguments, { isStatic: true }); + }; + + $.ligerWindow.show = function (p) + { + return $.ligerWindow(p); + }; + + $.ligerDefaults.Window = { + showClose: true, + showMax: true, + showToggle: true, + showMin: true, + title: 'window', + load: false, + onLoaded: null, + onClose: null, + onRegain: null, + onMax: null, + modal: false //是否模态窗口 + }; + + $.ligerMethos.Window = {}; + + l.controls.Window = function (options) + { + l.controls.Window.base.constructor.call(this, null, options); + }; + l.controls.Window.ligerExtend(l.core.Win, { + __getType: function () + { + return 'Window'; + }, + __idPrev: function () + { + return 'Window'; + }, + _extendMethods: function () + { + return $.ligerMethos.Window; + }, + _render: function () + { + var g = this, p = this.options; + g.window = $('<div class="l-window"><div class="l-window-header"><div class="l-window-header-buttons"><div class="l-window-toggle"></div><div class="l-window-max"></div><div class="l-window-close"></div><div class="l-clear"></div></div><div class="l-window-header-inner"></div></div><div class="l-window-content"></div></div>'); + g.element = g.window[0]; + g.window.content = $(".l-window-content", g.window); + g.window.header = $(".l-window-header", g.window); + g.window.buttons = $(".l-window-header-buttons:first", g.window); + if (p.url) + { + if (p.load) + { + g.window.content.load(p.url, function () + { + g.trigger('loaded'); + }); + g.window.content.addClass("l-window-content-scroll"); + } + else + { + var iframe = $("<iframe frameborder='0' src='" + p.url + "'></iframe>"); + var framename = "ligeruiwindow" + l.windowCount++; + if (p.name) framename = p.name; + iframe.attr("name", framename).attr("id", framename); + p.framename = framename; + iframe.appendTo(g.window.content); + g.iframe = iframe; + } + } + else if (p.content) + { + var content = $("<div>" + p.content + "</div>"); + content.appendTo(g.window.content); + } + else if (p.target) + { + g.window.content.append(p.target); + p.target.show(); + } + + + + this.mask(); + + g.active(); + + $('body').append(g.window); + + g.set({ width: p.width, height: p.height }); + //位置初始化 + var left = 0; + var top = 0; + if (p.left != null) left = p.left; + else p.left = left = 0.5 * ($(window).width() - g.window.width()); + if (p.top != null) top = p.top; + else p.top = top = 0.5 * ($(window).height() - g.window.height()) + $(window).scrollTop() - 10; + if (left < 0) p.left = left = 0; + if (top < 0) p.top = top = 0; + + + g.set(p); + + p.framename && $(">iframe", g.window.content).attr('name', p.framename); + if (!p.showToggle) $(".l-window-toggle", g.window).remove(); + if (!p.showMax) $(".l-window-max", g.window).remove(); + if (!p.showClose) $(".l-window-close", g.window).remove(); + + g._saveStatus(); + + //拖动支持 + if ($.fn.ligerDrag) + { + g.draggable = g.window.drag = g.window.ligerDrag({ + handler: '.l-window-header-inner', onStartDrag: function () + { + g.active(); + }, onStopDrag: function () + { + g._saveStatus(); + }, animate: false + }); + } + //改变大小支持 + if ($.fn.ligerResizable) + { + g.resizeable = g.window.resizable = g.window.ligerResizable({ + onStartResize: function () + { + g.active(); + $(".l-window-max", g.window).removeClass("l-window-regain"); + }, + onStopResize: function (current, e) + { + var top = 0; + var left = 0; + if (!isNaN(parseInt(g.window.css('top')))) + top = parseInt(g.window.css('top')); + if (!isNaN(parseInt(g.window.css('left')))) + left = parseInt(g.window.css('left')); + if (current.diffTop) + g.window.css({ top: top + current.diffTop }); + if (current.diffLeft) + g.window.css({ left: left + current.diffLeft }); + if (current.newWidth) + g.window.width(current.newWidth); + if (current.newHeight) + g.window.content.height(current.newHeight - 28); + + g._saveStatus(); + return false; + } + }); + g.window.append("<div class='l-btn-nw-drop'></div>"); + } + //设置事件 + $(".l-window-toggle", g.window).click(function () + { + if ($(this).hasClass("l-window-toggle-close")) + { + g.collapsed = false; + $(this).removeClass("l-window-toggle-close"); + } else + { + g.collapsed = true; + $(this).addClass("l-window-toggle-close"); + } + g.window.content.slideToggle(); + }).hover(function () + { + if (g.window.drag) + g.window.drag.set('disabled', true); + }, function () + { + if (g.window.drag) + g.window.drag.set('disabled', false); + }); + $(".l-window-close", g.window).click(function () + { + if (g.trigger('close') == false) return false; + g.window.hide(); + l.win.removeTask(g); + }).hover(function () + { + if (g.window.drag) + g.window.drag.set('disabled', true); + }, function () + { + if (g.window.drag) + g.window.drag.set('disabled', false); + }); + $(".l-window-max", g.window).click(function () + { + if ($(this).hasClass("l-window-regain")) + { + if (g.trigger('regain') == false) return false; + g.window.width(g._width).css({ left: g._left, top: g._top }); + g.window.content.height(g._height - 28); + $(this).removeClass("l-window-regain"); + } + else + { + if (g.trigger('max') == false) return false; + g.window.width($(window).width() - 2).css({ left: 0, top: 0 }); + g.window.content.height($(window).height() - 28).show(); + $(this).addClass("l-window-regain"); + } + }); + }, + _saveStatus: function () + { + var g = this; + g._width = g.window.width(); + g._height = g.window.height(); + var top = 0; + var left = 0; + if (!isNaN(parseInt(g.window.css('top')))) + top = parseInt(g.window.css('top')); + if (!isNaN(parseInt(g.window.css('left')))) + left = parseInt(g.window.css('left')); + g._top = top; + g._left = left; + }, + min: function () + { + this.window.hide(); + this.minimize = true; + this.actived = false; + }, + _setShowMin: function (value) + { + var g = this, p = this.options; + if (value) + { + if (!g.winmin) + { + g.winmin = $('<div class="l-window-min"></div>').prependTo(g.window.buttons) + .click(function () + { + g.min(); + }); + l.win.addTask(g); + } + } + else if (g.winmin) + { + g.winmin.remove(); + g.winmin = null; + } + }, + _setLeft: function (value) + { + if (value != null) + this.window.css({ left: value }); + }, + _setTop: function (value) + { + if (value != null) + this.window.css({ top: value }); + }, + _setWidth: function (value) + { + if (value > 0) + this.window.width(value); + }, + _setHeight: function (value) + { + if (value > 28) + this.window.content.height(value - 28); + }, + _setTitle: function (value) + { + if (value) + $(".l-window-header-inner", this.window.header).html(value); + }, + _setUrl: function (url) + { + var g = this, p = this.options; + p.url = url; + if (p.load) + { + g.window.content.html("").load(p.url, function () + { + if (g.trigger('loaded') == false) return false; + }); + } + else if (g.jiframe) + { + g.jiframe.attr("src", p.url); + } + }, + hide: function () + { + var g = this, p = this.options; + this.unmask(); + this.window.hide(); + }, + show: function () + { + var g = this, p = this.options; + this.mask(); + this.window.show(); + }, + remove: function () + { + var g = this, p = this.options; + this.unmask(); + this.window.remove(); + }, + active: function () + { + var g = this, p = this.options; + if (g.minimize) + { + var width = g._width, height = g._height, left = g._left, top = g._top; + if (g.maximum) + { + width = $(window).width(); + height = $(window).height(); + left = top = 0; + if (l.win.taskbar) + { + height -= l.win.taskbar.outerHeight(); + if (l.win.top) top += l.win.taskbar.outerHeight(); + } + } + g.set({ width: width, height: height, left: left, top: top }); + } + g.actived = true; + g.minimize = false; + l.win.setFront(g); + g.show(); + l.win.setFront(this); + }, + setUrl: function (url) + { + return _setUrl(url); + } + }); + +})(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-all.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-all.css new file mode 100755 index 0000000..a48f9d0 --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-all.css @@ -0,0 +1,8 @@ +@import url("ligerui-common.css"); +@import url("ligerui-dialog.css"); +@import url("ligerui-form.css"); +@import url("ligerui-grid.css"); +@import url("ligerui-layout.css"); +@import url("ligerui-menu.css"); +@import url("ligerui-tab.css"); +@import url("ligerui-tree.css"); \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-common.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-common.css new file mode 100755 index 0000000..47337fc --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-common.css @@ -0,0 +1,170 @@ +/* ------------- + * commom * +* ------------- */ +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;} +legend{color:#000;}del,ins{text-decoration:none;} + +body{font-family: "微软雅黑", "宋体", Arial, sans-serif; font-size: 12px; } +.l-clear{ clear:both; width:1px; height:1px; overflow:hidden;} +.l-hidden {display: none;} +.l-loading +{ + position: absolute;z-index: 91000; top:40%; left:50%; overflow:hidden; + background:url('../images/common/loading.gif') no-repeat 0px 0px;width:24px; height:24px; + display:none; +} +/* ------------- + * 滚动条颜色 * +* ------------- */ +.l-scroll +{ + scrollbar-face-color:#C6D7FF; scrollbar-3dlight-color:#B5CBF7; scrollbar-darkshadow-color:#B5CBF7; + scrollbar-base-color:#B5CBF7; + scrollbar-shadow-color: #FFF; scrollbar-highlight-color: #FFF; scrollbar-track-color:#FFF; scrollbar-arrow-color:#4A6184; +} +.l-noscroll +{ + overflow:hidden; +} +/* Draggable */ +.l-draggable{ overflow:hidden; border-style:solid; border-width:1px; opacity:0.5; filter:alpha(opacity=50); position:absolute; top:0; left:0; z-index:14000; background:#f2f1f1; border-color:#aaa;} +/* Resizable */ +.l-resizable { display:none; overflow:hidden; border-style:dashed; border-width:1px; opacity:0.5; filter:alpha(opacity=50); position:absolute; top:0; left:0; z-index:15000; background:#f2f1f1; } + + .l-dragging-mask { + width:100%;height:100%; overflow:hidden; position:absolute;top:0px; left:0px; z-index:11000; display:none; filter: Alpha +(opacity=1);background:white; -moz-opacity:.01;opacity:0.01; +} + /* -------------- + * icon * +* ------------ */ +.l-icon-checkbox {background:url('../images/icon/checkbox.gif') no-repeat center;} + +.l-icon-cross{background:url('../images/icon/cross.gif') no-repeat center; width:16px; height:16px; line-height:16px;} +/* ------------- + * 按钮 * +* ------------- */ +.l-button { + height: 23px; + overflow: hidden; + width: 60px; + line-height: 23px; + cursor: pointer; + position: relative; text-align:center; + border: solid 1px #A3C0E8;color:#333333; + background:#E0EDFF url(../images/controls/button-bg.gif) repeat-x center; +} + +.l-button-over{ + background: #FFBE76 url(../images/controls/button-bg-over.gif) repeat-x center; border-color:#D6A886; +} +.l-button-disabled { + background-image:url('../images/common/button-disabled.gif'); color:#9D9D9E;border: solid 1px #D3D3D3; +} +.l-button-hasicon { + padding-left: 20px; +} +.l-button-hasicon img { + position:absolute; top:4px; left:3px; width:16px; height:16px; +} +/* + Draggable +*/ +.l-drag-proxy { border: 1px solid #BDD1EE;position: absolute;z-index: 1001;height:25px; line-height:25px; padding-left:19px; padding-right:4px; background:white; } +.l-drag-proxy .l-drop-icon{position: absolute; top:5px; left:4px;width:16px; height:16px; } +.l-drop-no{background: white url('../images/common/drop-icons.gif') no-repeat 0px -20px; width:16px; height:16px; overflow:hidden;} +.l-drop-yes{background: white url('../images/common/drop-icons.gif') no-repeat 0px 0px; width:16px; height:16px; overflow:hidden;} +.l-drop-add{background: white url('../images/common/drop-icons.gif') no-repeat -20px 0px; width:16px; height:16px; overflow:hidden;} +.l-drag-coldroptip{width:9px; position:absolute; height:44px; z-index:1000;} +.l-drop-move-up{background:transparent url('../images/common/drop-icons.gif') no-repeat -40px 0px; width:9px; height:9px; overflow:hidden;position:absolute; top:0px;} +.l-drop-move-down{background: transparent url('../images/common/drop-icons.gif') no-repeat -60px 0px; width:9px; height:9px; overflow:hidden; position:absolute; bottom:0px;} + + .l-drag-nodedroptip,.l-drag-rowdroptip{width:9px; position:absolute; height:1px; background-color:red; z-index:1000; line-height:1px; overflow:hidden;} + + + + /* filter */ +table.l-filter-group{ background:white; font-size:12px;} +table.l-filter-group select,table.l-filter-group .valtxt{border:1px solid #d3d3d3;} +table.l-filter-group .addgroup{} +table.l-filter-group .addrule{} +table.l-filter-group .deletegroup{} +table.l-filter-group .deleterole{ cursor:pointer;} +table.l-filter-group-alt{ background:#F2F2F2;} +td.l-filter-groupcell{ padding-left:20px;} +td.l-filter-column{ padding:2px;} +td.l-filter-op{padding:2px;} +td.l-filter-value{padding:2px;} +tr.l-filter-rowlastcell{ text-align:right;_width:300px; min-width:300px;padding:2px;} +table.l-filter-group-alt,.l-panel table.l-filter-group-alt{background:#f5f5f5;margin-left:20px; margin-top:4px; padding:5px;border:1px solid #d3d3d3;} +table.l-filter-group-alt .l-filter-value{ padding-right:6px;} +td.l-filter-cellgroup{ padding:3px;} +table.l-filter-group-alt table.l-filter-group{background:white;margin-left:20px; margin-top:4px; padding:5px;border:1px solid #d3d3d3;} + + +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} + +.ui-widget-content { + border: 1px solid #aaaaaa; + color: #222222; +} +.ui-widget-content a { + color: #222222; +} +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border: 1px solid #d3d3d3; + background: #e6e6e6; + font-weight: normal; + color: #555555; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited { + color: #555555; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + border: 1px solid #999999; + background: #dadada; + font-weight: normal; + color: #212121; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited { + color: #212121; + text-decoration: none; +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active { + border: 1px solid #aaaaaa; + background: #ffffff; + font-weight: normal; + color: #212121; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #212121; + text-decoration: none; +} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-dialog.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-dialog.css new file mode 100755 index 0000000..008520a --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-dialog.css @@ -0,0 +1,254 @@ +/* 任务栏 */ +.l-taskbar{background-image:url('../images/win/taskbar.png'); background-repeat:repeat-x; height:36px; line-height:36px; overflow:hidden; width:100%; position:fixed; left:0px; bottom:-36px; display:none; z-index: 11000;} +.l-taskbar-tasks{ width:100%; margin-top:2px;} +.l-taskbar-task{ height:26px; line-height:26px;overflow:hidden; margin:2px; float:left; margin-left:2px; position:relative; cursor:pointer; background-repeat:repeat-x;} +.l-taskbar-task{ background-image:url('../images/win/taskbar-task.gif'); border:1px solid #676F7F;} +.l-taskbar-task-icon{ position:absolute; left:5px; top:3px;width:24px; height:25px; overflow:hidden;background:url('../images/win/taskicon.gif') no-repeat;} +.l-taskbar-task-content{ margin-left:27px; color:White; font-weight:bold; margin-right:10px;} +.l-taskbar-task-over{ border-color:#A7ADB5;background-position:0px -30px;} +.l-taskbar-task-active{border-color:#A2A8AF;background-position:0px -60px; } +.l-taskbar{_position:absolute;_bottom:auto;_top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0))); _background-image:url('../images/win/taskbar.gif');} +.l-taskbar-top{ bottom:auto; top:0px; background-color:White; padding-bottom:1px; border-bottom:1px solid #687079;} +.l-taskbar-top{_position:absolute;_top:expression(eval(document.documentElement.scrollTop));} +/* ------------------ + * messagebox * +* --------------- */ +.l-messagebox{ position:absolute;top:100px; left:100px; width:300px; background:#F2F8FF;border-bottom:1px solid #82BCD8;z-index: 9001; } + +.l-messagebox-title,.l-messagebox-close,.l-messagebox-close-over,.l-messagebox-btn,.l-messagebox-btn-l,.l-messagebox-btn-r,.l-messagebox-lt,.l-messagebox-rt +{background-image:url('../images/win/box.gif'); background-repeat:no-repeat;} +.l-messagebox .l-messagebox-title{ background-repeat:repeat-x;} + +.l-messagebox-title{height:21px; line-height:21px; color:White; font-weight:bold; background-position:0px -99px;} + + + +.l-messagebox-image{ width:35px; height:35px; overflow:hidden; display:none; position:absolute; top:30px; left:15px;background:url('../images/win/box-icons.gif') no-repeat;} +.l-messagebox-image-donne{background-position:0px 0px; } +.l-messagebox-image-error{background-position:0px -115px; } +.l-messagebox-image-question{background-position:0px -70px;height:45px; } +.l-messagebox-image-warn{background-position:0px -35px; } +.l-messagebox-title-inner{ padding-left:10px;} +.l-messagebox-content{ padding-left:20px; padding-top:10px;padding-bottom:20px;} +.l-messagebox-buttons{ height:30px; position:relative; text-align:center; margin-top:4px;} +.l-messagebox-buttons-inner{ margin-left:10px;} +.l-messagebox-close{ width:13px; height:13px; overflow:hidden; position:absolute; right:4px;top:4px; cursor:pointer; background-position:-8px -24px;} +.l-messagebox-close-over{background-position:-8px -37px;} +.l-messagebox-lt{width:3px; height:3px; overflow:hidden;position:absolute; top:0; left:0; z-index:12;background-position:0px -48px;} +.l-messagebox-rt{width:3px; height:3px; overflow:hidden; position:absolute; top:0; right:0;z-index:12;background-position:-4px -48px;} +.l-messagebox-l{ background:#82BCD8; width:1px; height:100%; position:absolute; top:0px; left:0px;overflow:hidden; } +.l-messagebox-r{ background:#82BCD8; width:1px; height:100%; position:absolute; top:0px; right:0px; overflow:hidden; } + +.l-messagebox-btn{ height:24px; overflow:hidden;background:url('../images/win/box.gif') repeat-x; width:70px; line-height:24px; cursor:pointer; position:relative; float:left; margin-left:5px;} +.l-messagebox-btn-inner{ text-align:center;} + + +/* -------------- + * window * +* ------------ */ +.l-window-mask{ + position:absolute;left:0;top:0;width:100%;height:100%; filter:alpha(opacity=25);opacity:0.25;background:#777;display1:none;font-size:1px; *zoom:1;overflow:hidden; display:none;z-index: 9000; + } +.l-window-mask-nobackground{ + position:absolute;left:0;top:0;width:100%;height:100%; display1:none;font-size:1px; *zoom:1;overflow:hidden; display:none;z-index: 9000; + } +.l-window-dragging +{ + filter:alpha(opacity=80);opacity:0.80; +} +.l-window-dragging .l-window-content +{ + visibility:hidden; +} +.l-window{ position:absolute; border:1px solid #AFCCF1;background:#F5F8F9;z-index: 9100;left:0; top:0;margin:0;padding:0; } +.l-window-header{ position:relative;padding-left:10px; color:#183152; font-weight:bold;height:25px; line-height:24px; background:#E2EDFE url('../images/panel/panel-header.gif') repeat-x; overflow:hidden;} +.l-window-header-buttons{position:absolute; top:3px; right:3px; height:20px; } +.l-window-toggle{float:left;height:16px; width:16px; overflow:hidden; background:url('../images/panel/panel-tools.gif');background-position:0px 0px; cursor:pointer; margin-left:5px; } +.l-window-min{float:left;height:16px; width:16px; overflow:hidden; background:url('../images/panel/panel-tools.gif');background-position:-16px 0px; cursor:pointer; margin-left:5px; } +.l-window-max{float:left;height:16px; width:16px; overflow:hidden; background:url('../images/panel/panel-tools.gif');background-position:-16px -16px; cursor:pointer; margin-left:5px; } +.l-window-regain{float:left;height:16px; width:16px; overflow:hidden; background:url('../images/panel/panel-tools.gif');background-position:-32px -16px; cursor:pointer; margin-left:5px; } +.l-window-toggle-close +{ + background-position:0px -16px; +} +.l-window-close{float:left;height:16px; width:16px; overflow:hidden; background:url('../images/panel/panel-tools.gif');background-position:-32px 0px; cursor:pointer; margin-left:5px; } +.l-window-content{ overflow:hidden; width:100%;} +.l-window-content-scroll{ overflow:scroll;} +.l-window-content iframe{border:none; width:100%; height:100%;} + + + /* -------------- + * dialog * +* ------------ */ +.l-dialog{ position:absolute;z-index: 10000; padding:0; margin:0;font-size:12px; border: 1px solid #BED5F3;border-radius: 5px;box-shadow: 0 1px 6px rgba(99,99,99,.3);} +.l-dialog table{ table-layout:auto;} +.l-dialog-fixed +{ + position:fixed; right:0px; bottom:-100px; + _position:absolute;_bottom:auto;_top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0))); +} +.l-dialog-table{ } +.l-dialog-body{ position:relative; overflow:hidden;} +.l-dialog{ padding:0; margin:0;font-size:12px; } +.l-dialog td,.l-dialog tr,.l-dialog td div{font-size:12px; } +.l-dialog-cc{ background:white;} +.l-dialog-tl,.l-dialog-tr,.l-dialog-bl,.l-dialog-br,.l-dialog-cl,.l-dialog-cr{width:0px; background:none;padding:0;margin:0;} +.l-dialog-tl,.l-dialog-tc,.l-dialog-tr{ height:26px;} +.l-dialog-bl,.l-dialog-bc,.l-dialog-br{ height:0px;background:none;padding:0;margin:0;} + + +.l-dialog-tl{ background:none;border-bottom: 1px solid #f5f5f5;} +.l-dialog-tc{font-size: 14px;font-weight: bold;height: 29px;line-height: 29px;background: -webkit-gradient(linear, 0 0, 0 100%, from(#EFF5FE), to(#D6E4F4)); padding-left: 10px;background: -o-linear-gradient(top, #EFF5FE, #D6E4F4);_background:#EFF5FE; +background: -ms-linear-gradient(top, #EFF5FE 0%,#D6E4F4 100%); +background: linear-gradient(top, #EFF5FE, #D6E4F4);background: -moz-linear-gradient(top, #EFF5FE, #D6E4F4); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#EFF5FE', endColorstr='#D6E4F4'); + +} +.l-dialog-tr{background:none;border-bottom: 1px solid #f5f5f5;} +.l-dialog-bl{background:none;} +.l-dialog-bc{background:none;} +.l-dialog-br{background:none;} +.l-dialog-cl{background:none;} +.l-dialog-cr{background:none;} +.l-dialog-cl{background:none;} +.l-dialog-cl,.l-dialog-cc,.l-dialog-cr{border-top: 1px solid #BED5F3;} + +.l-dialog-loading{position:absolute;top: 30%; left:40%; background:#fff url('../images/common/loading.gif') no-repeat; padding:8px; z-index:99000; height:auto; border:0;} + +.l-dialog-winbtns{ position:absolute;right:0px; top:4px; height:16px;} +.l-dialog-winbtn{background:url('../images/win/dialog-winbtns.gif') no-repeat;cursor:pointer;overflow:hidden; width:17px; height:16px; float:right; margin-right:4px;} + +.l-dialog-close{background-position:-85px 0px;} +.l-dialog-close-over{background-position:-85px -16px;} +.l-dialog-close-disabled{background-position:-24px -32px; cursor:default;} +.l-dialog-min{ background-position:0px 0px;} +.l-dialog-min-over{background-position:0px -16px;} +.l-dialog-min-disabled{background-position:0px -32px;cursor:default;} +.l-dialog-max{background-position:-17px 0px;} +.l-dialog-max-over{background-position:-17px -16px;} +.l-dialog-max-disabled{background-position:-17px -32px;cursor:default;} +.l-dialog-recover{background-position:-34px 0px;} +.l-dialog-recover-over{background-position:-34px -16px;} +.l-dialog-recover-disabled{background-position:-34px -32px;cursor:default;} + +.l-dialog-collapse{background-position:-51px 0px;} +.l-dialog-collapse-over{background-position:-51px -16px;} +.l-dialog-collapse-disabled{background-position:-51px -32px;cursor:default;} +.l-dialog-extend{background-position:-68px 0px;} +.l-dialog-extend-over{background-position:-68px -16px;} +.l-dialog-extend-disabled{background-position:-68px -32px;cursor:default;} + +.l-dialog-tc-inner{ position:relative;height:26px; line-height:26px; width:100%; } +.l-dialog-title { color:#000;font-weight:bold; font-weight:700; text-shadow:none; padding-left:3px; padding-right:20px; text-align:left; padding-top:0px;} + +.l-dialog-content{ padding-left:18px; padding-top:14px;padding-bottom:12px; overflow:auto;} +.l-dialog-content-noimage {padding-left:6px; padding-top:10px;padding-bottom:10px;} +.l-dialog-content-dragging iframe { } +.l-dialog-win .l-dialog-content{ } +.l-dialog-content-nopadding{ padding:0;} +.l-dialog-content iframe {border: none;width: 100%;height: 100%;} +.l-dialog-image{ width:48px; height:48px; overflow:hidden; display:none; position:absolute; top:10px; left:10px;background:url('../images/win/dialog-icons.gif') no-repeat;} +.l-dialog-image-donne{ background-position:0px 0px; } +.l-dialog-image-error{ background-position:0px -48px; } +.l-dialog-image-question{ background-position:0px -144px; } +.l-dialog-image-warn{ background-position:0px -96px; } + +.l-dialog-image-loading{ background:white url('../images/common/loading2.gif') no-repeat center; width:28px; height:28px;} + +.l-dialog-buttons{ height:30px; line-height:30px; position:relative;margin-top:4px;padding-top:6px; border-top:1px solid #D3E3F7; overflow:hidden; margin-bottom:2px;} +.l-dialog-buttons-inner{} + +.l-dialog-btn-l,.l-dialog-btn-r{display:none;} +.l-dialog-buttons +{ + padding: 4px 8px; + text-align: right; + white-space: nowrap; + border-top: 1px solid #ececec; + border-radius: 0 0 2px 2px; + background: #fcfcfc; + background: -moz-linear-gradient(top, #fcfcfc, #f4f4f4); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#fcfcfc), to(#f4f4f4)); + background: -o-linear-gradient(top, #fcfcfc, #f4f4f4); + background: -ms-linear-gradient(top, #fcfcfc 0%,#f4f4f4 100%); + background: linear-gradient(top, #fcfcfc, #f4f4f4); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#f4f4f4'); +} +.l-dialog-btn{ + display: inline-block; + zoom: 1; + margin-left: 10px; + height: 24px; + border: 1px solid #c1c1c1; + border-radius: 2px; + box-shadow: 0 1px 1px rgba(0,0,0,0.15); + background: #ffffff; + background: -moz-linear-gradient(top, #ffffff, #f4f4f4); + background: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f4f4f4)); + background: -o-linear-gradient(top, #ffffff, #f4f4f4); + background: -ms-linear-gradient(top, #ffffff 0%,#f4f4f4 100%); + background: linear-gradient(top, #ffffff, #f4f4f4); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f4f4f4'); + font: 12px 宋体b8b\4f53; + color: #555; + vertical-align: middle; + cursor: pointer; +} +.l-dialog-btn-highlight { +border: 1px solid #3279a0; +box-shadow: 0 1px 1px rgba(0,0,0,0.3); +background: #337fa9; +background: -moz-linear-gradient(top, #4994be, #337fa9); +background: -webkit-gradient(linear, 0 0, 0 100%, from(#4994be), to(#337fa9)); +background: -o-linear-gradient(top, #4994be, #337fa9); +background: -ms-linear-gradient(top, #4994be 0%,#337fa9 100%); +background: linear-gradient(top, #4994be, #337fa9); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4994be', endColorstr='#337fa9'); +font-weight: bold; +color: #fff; +text-shadow: 0 2px 2px rgba(0,0,0,0.22); +} + .l-dialog-btn:hover +{ + background: #f4f4f4; + color: #555; +} + .l-dialog-btn-highlight:hover + { + filter: progid:DXImageTransform.Microsoft.Gradient(enabled=false); + background: #3286b4; + color: #fff; + } +.l-dialog-content-frame { + overflow:hidden; +} +.l-dialog-btn{ height:25px; overflow:hidden; width:70px; line-height:25px; cursor:pointer; position:relative; float:right; margin-right:5px;} + +.l-dialog-btn-inner{ text-align:center;} + + +.l-dialog-inputtext{ width:280px; border:1px solid #0099CC; line-height:23px; height:25px;} +.l-dialog-textarea{ width:280px; border:1px solid #0099CC; height:80px;} + +.l-messagebox-btn {background-position:0px 0px;} +.l-messagebox-btn-over { background-position:0px -51px;} + +.l-messagebox-btn-l { height:24px; position:absolute; left:0px; top:0px; width:4px;background-position:0px -24px;} +.l-messagebox-btn-over .l-messagebox-btn-l {background-position:0px -75px;} +.l-messagebox-btn-r { height:24px; position:absolute; right:0px; top:0px; width:4px;background-position:-4px -24px;} +.l-messagebox-btn-over .l-messagebox-btn-r {background-position:-4px -75px;} + + +/* 选择窗口,填充模式,隐藏滚动条 */ +.l-selectorwin .l-dialog-content { + overflow:hidden; padding:0px; +} +.l-selectorwin .l-dialog-content .l-form { + margin:0; padding:2px; background:#EAF2FF;border-bottom: 1px solid #AECAF0; +} +.l-selectorwin .l-dialog-buttons { + margin-top: 0; +} +.l-selectorwin .l-panel { + border:0; +} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-form.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-form.css new file mode 100755 index 0000000..b1fed21 --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-form.css @@ -0,0 +1,559 @@ + /* 表单 */ +.l-form { margin:7px;overflow:hidden;} +.l-form .l-group{ clear:both; margin:0; height:28px; line-height:28px; font-weight:bold; font-size:12px; color:#333; border-bottom:solid 1px #ebebeb; padding-top:5px;margin-bottom:10px; display:block; position:relative; clear:both;} +.l-group span{ + float:left; + width:90px; + text-align: left; +} +.l-group-hasicon span { +margin-left: 40px; +} +.l-form .l-group-hasicon{ } +.l-form .l-group-hasicon img{ width:16px; height:16px; position:absolute; left:6px; top:6px;} +.l-form .l-group-hasicon div{ width:16px; height:16px; position:absolute; left:6px; top:6px;} +.l-form ul, .l-form li{ list-style:none;} +.l-form ul{ clear:both; margin-top:2px; margin-bottom:2px;} +.l-form .l-fieldcontainer ul { margin:0;} +.l-form .l-fieldcontainer { padding:0; } +.l-form .l-fieldcontainer-first { + clear: left; +} +.l-form li{ float:left; overflow:hidden; text-align:left; line-height:23px;padding:0; padding-top:2px; padding-bottom:2px; position:relative;} +.l-form li textarea{ height:80px;} +.l-form .l-form-buttons{ clear:both; margin-top:10px;} +.l-form .l-form-buttons li { + float: left; margin-right:7px; +} +.l-hidden{ display:none;} +.l-form-container { + clear: both; + overflow: hidden; +} +/* ------------- + * 多行文本框颜色 * +* ------------- */ +.l-textarea{border:1px solid #A8AAAD; outline:none;} + .l-textarea:hover{border-color:#01AAEE;} +.l-textarea-invalid,.l-textarea:focus{ border-color:#FF8801;} +.l-textarea-invalid{border-color:#FF7777; background:#FFEEEE url(../images/common/invalid-line.gif) repeat-x bottom;} +.l-textarea-invalid:hover,.l-textarea-invalid:focus{border-color:#FF7777;} +/* ------------- + * 文本框/下拉框/日期框/调整器 * +* ------------- */ +.l-text-wrapper{ position:relative;} +/* 文本框、下来框、日期框、调整器都使用到这个 */ +.l-text +{ + position:relative; + border:1px solid #AECAF0; height:20px; line-height:20px; + width:130px; background:white; +} +/* 文本框 验证不通过 */ +.l-text-invalid{ border-color:#FF7777; background:#FFEEEE url(../images/common/invalid-line.gif) repeat-x bottom;} + +.l-text-invalid .l-text-field{ background:none;} +/*只读时边框*/ +.l-text-disabled +{ + border-color:#C2C2C2; + background:#E0E0E0; +} +/*只读时文本框*/ +.l-text-disabled .l-text-field{ + background:#E0E0E0; +} +/* 编辑状态 */ +.l-text-editing +{ + +} +/* 只读状态*/ +.l-text-readonly { + background:none; border:0; margin:2px; + border-bottom:1px solid #b1b1b1; +} +.l-text-readonly input { + background:none; border:0; +} +.l-text-readonly .l-trigger,.l-text-readonly .l-trigger-icon { + display:none; +} +.l-text-readonly .l-trigger-cancel +{ + display:none; cursor:auto; +} +/* 表单文本框 input:text */ +.l-text-field +{ + position:absolute; top:0px; left:0px; + width:110px; + border:0; margin:0; outline:none; +} + +.l-text-field-number { + text-align: right; +} +/* 表单文本框 内容为空时 */ +.l-text-field-null +{ color:#C1C1C1; +} + +/* 下拉框/日期/调整器 右侧那个可点击的区域 分别是普通、经过、按住状态 */ +.l-trigger,.l-trigger-hover,.l-trigger-pressed +{ + cursor:pointer; + position:absolute; + top:1px;right:1px; + width:16px; height:16px; + overflow:hidden; +} +.l-trigger +{ + border:1px solid #AECAF0; + background:#DBEBFF url('../images/controls/bg-trigger.gif') repeat-x left; +} +.l-trigger-hover +{ + border:1px solid #EABE4E; + background:#fedc75 url('../images/controls/bg-trigger-over.gif') repeat-x left; +} +.l-trigger-pressed +{ + border:1px solid #EABE4E; + background:#fedc75 url('../images/controls/bg-trigger-pressed.gif') repeat-x left; +} + +/* l-text-popup */ +.l-text-popup .l-trigger,.l-text-popup .l-trigger-hover,.l-text-popup .l-trigger-pressed +{ + top:0px;right:0px; + width:16px;height:100%;border:none; border-left:1px solid #AECAF0; +} +.l-text-popup .l-trigger-cancel +{ + right :19px; border:0; background:transparent;height:100%; +} + +.l-text-popup .l-trigger-icon +{ + background: url('../images/icon/icon-select.gif') no-repeat 55% 55% transparent; +} +.l-text-popup .l-trigger-cancel .l-trigger-icon +{ + background: url('../images/icon/icon-unselect.gif') no-repeat 50% 53% transparent; +} + + +/* 下拉框/日期 取消选择 */ +.l-trigger-cancel { + right:20px; background:transparent; border:0px; +} +.l-trigger-cancel .l-trigger-icon ,.l-text-date .l-trigger-cancel .l-trigger-icon{ + background:url('../images/icon/icon-unselect.gif') no-repeat 50% 60% transparent; +} +.l-text-date .l-trigger,.l-text-date .l-trigger-hover,.l-text-date .l-trigger-pressed { + background:none;border:none; +} +.l-text-date .l-trigger-icon { + background-image: url('../images/dateeditor/date.gif'); +} +/* 下拉框/日期 右侧那个可点击的区域里面的图标 */ +.l-trigger-icon +{ width:100%; + height:100%; + background:url('../images/icon/icon-down.gif') no-repeat 50% 50%; +} +/* ------------- + * 调整器 * +* ------------- */ +.l-spinner-up .l-spinner-icon,.l-spinner-down .l-spinner-icon{overflow: hidden;position: absolute;left: 0px;top: 50%;margin-top: -3px;width: 100%;height: 6px;background: no-repeat center top;} +.l-spinner-down-over,.l-spinner-up-over{background:#fedc75 url('../images/controls/bg-trigger-over.gif') repeat-x left;} +.l-spinner-up .l-spinner-icon{background-image: url(../images/icon/icon-up.gif);} +.l-spinner-down .l-spinner-icon{background-image: url(../images/icon/icon-down.gif);} +.l-spinner-up,.l-spinner-down {width: 100%;height: 50%;overflow: hidden;display: block;position: absolute;left: 0px;top: 0px;} +.l-spinner-down{top: 50%;} +.l-spinner-split{overflow: hidden;width: 13px;height: 1px;position: absolute;left: 1px;top: 50%;z-index: 10;background: #B5B8C8; } + +/* ------------- + * 验证 * +* ------------- */ +.l-verify-star { color:Red;} +.l-star { color:Red;} +/* ------------- + * 下拉框 * +* ------------- */ +.l-box-select +{ + display:none; + position:absolute; padding:0px; + border:1px solid #AECAF0; background:white; + width:130px; height:auto; + margin-top:1px; + z-index:9300; font-size:12px; line-height:18px; +} +.l-box-select-grid{border-bottom:1px solid #A3C0E8;border-right:1px solid #A3C0E8;} +.l-box-select-grid thead td,.l-box-select-grid tr.l-table-headerow td{ +background:#DBEBFF url('../images/controls/bg-panel-title.gif') repeat-x left; +} +.l-box-select-grid td{padding:0;margin:0;height:22px; line-height:22px; border-left:1px solid #A3C0E8;border-top:1px solid #A3C0E8; } +.l-box-select strong{ + font-weight: bold; +} +.l-box-select-lookup { + height:auto; +} +.l-box-select-lookup .l-panel { + border:0; +} +.l-box-select-lookup .l-form { + margin:0; padding:2px; background:#EAF2FF;border-bottom: 1px solid #AECAF0; +} +.l-box-select-lookup .l-box-select-inner { + padding:0;overflow:hidden; height:auto; +} +.l-box-select-absolute +{ + margin-top:0px; +} +.l-box-select-inner{ margin:0; padding:0; width:100%;overflow:auto; height:120px;color:#333;} +.l-box-select-inner .l-box-select-table{margin:0; padding:0; width:100%; } +.l-box-select .l-table-nocheckbox td:hover,.l-box-select .l-table-nocheckbox td.l-over{ background-color:#FFE7A2; cursor:pointer;} +.l-box-select .l-table-nocheckbox td.l-selected{ background-color:#FFBD69;} +.l-box-select .l-box-select-table td{ padding:2px; text-align:left;} +.l-box-select-add { + border-top: 1px solid #ddd; + background: #f5f5f5; + padding-left: 5px; +} +.l-box-select-add .link { + line-height: 30px; display:block; +padding-left: 20px; +position: relative; +color: #555555; +cursor: pointer; +outline: medium none; +text-decoration: none; +} +.l-box-select-add .link .icon { + background:url('../images/icon/spr_icons.gif') no-repeat; width:12px; height:12px; line-height:12px; overflow:hidden;left: 1px;position: absolute;top: 8px; +} + +.l-box-select-add a:hover { +color: #2A66BB; +} +/* listbox */ +.l-listbox { + border:1px solid #AECAF0; background:white; + width:130px; height:120px;font-size:12px; line-height:18px; +} +.l-listbox-grid{border-bottom:1px solid #A3C0E8;border-right:1px solid #A3C0E8;} +.l-listbox-grid thead td,.l-listbox-grid tr.l-table-headerow td{ +background:#DBEBFF url('../images/controls/bg-panel-title.gif') repeat-x left; border-top:none; +} +.l-listbox-grid td{padding:0;margin:0;height:22px; line-height:22px; border-left:1px solid #A3C0E8;border-top:1px solid #A3C0E8; } +.l-listbox-inner{ margin:0; padding:0; width:100%;overflow:auto; height:100%;color:#333;} +.l-listbox-inner .l-listbox-table{margin:0; padding:0; width:100%; } +.l-listbox tr:hover td,.l-listbox tr.l-over td{ background-color:#DFE8F6; cursor:pointer; border-bottom:1px dotted #89A8E3;border-top:1px dotted #89A8E3; } +.l-listbox tr.l-selected td{ background-color:#C6D7EF;border-bottom:1px dotted #89A8E3;border-top:1px dotted #89A8E3;} +.l-listbox td{ padding:2px; text-align:left;border-top:1px solid #ffffff;border-bottom:1px solid #fff;} +.l-listbox .l-listbox-grid td{border-top:1px solid #89A8E3;border-bottom:1px solid #89A8E3;} +.l-listbox .l-table-nocheckbox .l-checkboxrow { display:none;width:0px;} +/* radiolist */ +.l-radiolist td { + padding: 2px 4px; +} +.l-radiolist-disabled td { + color:#ccc +} +/* checkboxlist */ +.l-checkboxlist td { + padding: 2px 4px; +} +.l-checkboxlist-disabled td { + color:#ccc +} +/* 下拉框 右下角调整大小图标 */ +.l-btn-nw-drop +{ + position:absolute; + right:0px;bottom:0px; + width:8px; height:8px;background:url('../images/icon/icon-drop.gif') no-repeat 50% 50%; +} + +/* ------------- + * 复选框 * +* ------------- */ +.l-checkbox-wrapper{ + display: -moz-inline-stack;display:inline-block; zoom: 1;*display: inline;margin:0 auto;margin-right:2px; padding:0;} +.l-checkbox-wrapper label{margin-right:5px;} +a.l-checkbox { + background:url('../images/controls/checkbox.gif') no-repeat 0 0; + vertical-align: middle; + height: 13px; + width: 13px; margin:0 auto; + overflow:hidden; + display: -moz-inline-stack;display:inline-block; zoom: 1;*display: inline; + margin-right:5px; +} +div.l-disabled a.l-checkbox +{ + background-position:-39px 0; +} +div.l-disabled a.l-checkbox-checked +{ + background-position:-39px -13px; +} +a.l-checkbox-checked +{ + background-position:0 -13px; +} +.l-over a.l-checkbox +{ + background-position:-13px 0px; +} +.l-over a.l-checkbox-checked +{ + background-position:-13px -13px; +} +/* ------------- + * 单选框 * +* ------------- */ +.l-radio-wrapper{ + display: -moz-inline-stack;display:inline-block; zoom: 1;*display: inline; margin-right:2px; +} +.l-radio-wrapper label{margin-right:5px;} +a.l-radio { + background:url('../images/controls/radio.gif') no-repeat 0 0; + vertical-align: middle; + height: 13px; + width: 13px; + overflow:hidden; + display: -moz-inline-stack;display:inline-block; zoom: 1;*display: inline; + margin-right:5px; +} +a.l-radio-checked +{ + background-position:0 -13px; +} +div.l-disabled a.l-radio +{ + background-position:-26px 0; +} +div.l-disabled a.l-radio-checked +{ + background-position:-26px -13px; +} +.l-over a.l-radio +{ + background-position:-13px 0px; +} +.l-over a.l-radio-checked +{ + background-position:-13px -13px; +} +/* ----------------------- + * 日期控件 * +* ----------------------- */ +.l-box-dateeditor +{ + position:absolute; padding:0px; overflow:hidden; + border:1px solid #A3C0E8; background:white; + width:200px; + margin-top:1px; + z-index:9999; +} +.l-box-dateeditor-absolute +{ + margin-top:0px; +} +.l-box-dateeditor-header +{ + width:100%; height: 23px; background:url(../images/controls/dateeditor-header-bg.gif) repeat-x -2px center; text-align:center; + position:relative; text-align:center; +} +.l-box-dateeditor-header-text +{ + margin:0 auto; color:#1542B3; line-height:23px; font-weight:lighter;text-align:center; +} +.l-box-dateeditor-header-text a +{color:#1542B3; text-decoration:none;cursor:pointer; +} +.l-box-dateeditor-header-btn +{ + top:0;width:23px; height:23px;position:absolute; cursor:pointer; +} +.l-box-dateeditor-header-btn-over +{ + background: url(../images/icon/bar-button-over.gif) no-repeat center; +} +.l-box-dateeditor-header-btn span +{ + width:20px; height:20px; display:block; position:absolute; top:2px; left:2px; +} +.l-box-dateeditor-header-prevmonth{left:24px; } +.l-box-dateeditor-header-prevmonth span{background: url(../images/dateeditor/icon-prev.gif) no-repeat center;} +.l-box-dateeditor-header-nextmonth{right:24px;} +.l-box-dateeditor-header-nextmonth span{background: url(../images/dateeditor/icon-next.gif) no-repeat center;} + +.l-box-dateeditor-header-prevyear{left:4px; } +.l-box-dateeditor-header-prevyear span{background: url(../images/dateeditor/icon-first.gif) no-repeat center;} +.l-box-dateeditor-header-nextyear{ right:4px;} +.l-box-dateeditor-header-nextyear span{background: url(../images/dateeditor/icon-last.gif) no-repeat center;} + +.l-box-dateeditor-body{border:1px solid #A3C0E8; border-left:none; border-right:none; text-align:center; position:relative; } +.l-box-dateeditor-body table{ margin:0 auto;} + +.l-box-dateeditor-monthselector,.l-box-dateeditor-yearselector,.l-box-dateeditor-hourselector,.l-box-dateeditor-minuteselector{ background:white; list-style:none; margin:0 auto; padding:0; position:absolute;top:0px;left:0px; width:100%; display:none; height:100%; overflow:hidden;} +.l-box-dateeditor-minuteselector{ overflow:auto;} +.l-box-dateeditor-monthselector li{ float:left; width:50px; line-height:20px; height:20px; margin:5px; margin-top:5px;border:1px solid #d3d3d3; cursor:pointer;} +.l-box-dateeditor-yearselector li{ float:left; width:50px; line-height:20px; height:20px; margin:5px; margin-top:5px;border:1px solid #d3d3d3; cursor:pointer;} +.l-box-dateeditor-hourselector li{ float:left; width:36px; line-height:17px; height:17px; margin-left:8px; margin-top:2px;margin-bottom:2px; border:1px solid #d3d3d3; cursor:pointer;} +.l-box-dateeditor-minuteselector li{ float:left; width:21px; line-height:18px; height:18px; margin-left:6px; margin-bottom:3px;margin-top:3px; border:1px solid #d3d3d3; cursor:pointer;} +.l-box-dateeditor-monthselector li:hover,.l-box-dateeditor-monthselector li.l-selected,.l-box-dateeditor-monthselector li.l-over,.l-box-dateeditor-yearselector li:hover,.l-box-dateeditor-yearselector li.l-selected,.l-box-dateeditor-yearselector li.l-over,.l-box-dateeditor-hourselector li:hover,.l-box-dateeditor-hourselector li.l-selected,.l-box-dateeditor-hourselector li.l-over,.l-box-dateeditor-minuteselector li:hover,.l-box-dateeditor-minuteselector li.l-selected,.l-box-dateeditor-minuteselector li.l-over +{background-color: #FFE7A2;border: solid 1px #FFBD69;} + +.l-box-dateeditor-body thead td{ border-bottom:1px solid #d3d3d3;} +.l-box-dateeditor-body td{ width:30px; height:19px; line-height:19px; font-size:12px; } +.l-box-dateeditor-body tbody td{border:1px solid white;cursor:pointer;} +.l-box-dateeditor-body tbody td.l-box-dateeditor-today +{background-color: #FFBD69; } +.l-box-dateeditor-body tbody td.l-box-dateeditor-over,.l-box-dateeditor-body tbody td.l-box-dateeditor-selected + { background-color: #FFE7A2; } +.l-box-dateeditor-body tbody td.l-box-dateeditor-holiday +{ + color:#C00000; +} +.l-box-dateeditor-body tbody td.l-box-dateeditor-out +{ + color:#888888; +} +.l-box-dateeditor-toolbar +{ + padding-left:10px; + width:100%; height: 28px; background:url(../images/controls/dateeditor-bar-bg.gif) repeat-x 1px center; + text-align:right; position:relative; +} +.l-box-dateeditor-time{ width:30px; display:none; height:18px; margin-top:4px; float:left;color:#333;} +.l-box-dateeditor-time a{ text-decoration:none; font-weight:bold; color:#333; font-size:13px; cursor:pointer;} +.l-box-dateeditor-toolbar .l-button {width:50px ; height:19px; line-height:19px; } +.l-box-dateeditor-toolbar .l-button-today { float:left;margin-left:20px; margin-top:4px;} +.l-box-dateeditor-toolbar .l-button-close { float:left; margin-left:15px;margin-top:4px;} + +.l-highLight {background:#FFD144; +} +/* ----------------------- + * 验证 * +* ----------------------- */ +.l-validate-error{color:red;} +.l-validate-warn{color:orange;} +.l-verify-tip{ padding:0; margin:0;position:absolute; display:block;} +.l-verify-tip-corner{ padding:0; margin:0;position:absolute;background:url('../images/form/verify-corner.gif') no-repeat; width:8px; line-height:9px; height:9px; overflow:hidden; top:5px; left:0px; z-index:10001;} +.l-verify-tip-content{margin:0; position:absolute; left:7px;top:0px;border:1px solid #FFC340; background:#FFFCC7; z-index:10000; padding:4px 8px; width:100px; font-size:12px; } + +.l-exclamation{ width:16px; height:16px; overflow:hidden; display:block; background:url('../images/common/exclamation.gif') no-repeat;} + +/* ----------------------- + * 文件框 * +* ----------------------- */ +.l-file{} +.l-file a{padding-right:10px;} + + +.l-form .l-group .togglebtn{ + position:absolute; top:6px; right:15px; + background:url(../images/common/toggle.gif) no-repeat 0px 0px; + height:10px; width:9px; cursor:pointer; + left:auto;top:12px;right:6px; +} +.l-form .l-group .togglebtn-down{ background-position:0px -10px;} + +.l-box-select .l-grid-row { + cursor: pointer; +} + +/* l-form-tabs */ +.l-form-tabs { + position: relative; + padding: 4px; + zoom: 1; + padding: 0; + background: none; + border-width: 0; +} + +.l-form-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; + padding-left: 0; + background: transparent; + border-width: 0; + border-radius: 0; + -moz-border-radius: 0; + -webkit-border-radius: 0; + line-height: 0.8em; + font-size: 95%; + color: #555; +} + +.l-form-tabs .ui-tabs-nav li { + list-style: none; + border: 1px solid #aaaaaa; + float: left; + position: relative; + top: 1px; + margin: 0 .2em 1px 0; + border-bottom: 0 !important; + padding: 0; + white-space: nowrap; + line-height: 24px; + cursor:pointer; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +.l-form-tabs .ui-tabs-nav li a { + float: left; + padding: 0px 10px; + text-decoration: none; +} + +.l-form-tabs .ui-tabs-nav li.ui-tabs-selected { + margin-bottom: 0; + padding-bottom: 1px; +} + +.l-form-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { + cursor: text; +} + +.l-form-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { + cursor: pointer; +} + +.l-form-tabs .ui-tabs-panel { + display: block; + border-width: 0; + background: none; + padding: 6px; padding-bottom:20px; + -moz-border-radius-topright: 4px; + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; +} + +.l-form-tabs .ui-tabs-hide { + display: none !important; +} + +.l-form-tabs ul.ui-tabs-nav li { + font-weight: bold; +} + +.l-form-tabs .ui-tabs-panel { + background: #fefefe; + border-width: 1px; +} + +.l-form-tabs .ui-tabs-selected { + background: #fefefe; +} diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-grid.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-grid.css new file mode 100755 index 0000000..f1db3be --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-grid.css @@ -0,0 +1,576 @@ + +/* ----------------------- + * 表格 * +* ----------------------- */ +.l-grid-mask{ + position:absolute;left:0;top:0;width:100%;height:100%; + display1:none;font-size:1px; *zoom:1;overflow:hidden; display:none;z-index: 9000; +} +.l-selectorwin .l-panel { + +} +.l-panel table{ width:auto;} +.l-panel table,.l-panel td{ margin:0; padding:0;} +.l-panel-btn +{ + display:block; + height:22px; overflow:hidden; line-height:22px; position:relative; + padding-left:15px; padding-right:15px; cursor:pointer; + text-align:center;color: #2C4D79; text-decoration:none; cursor:pointer; +} +.l-panel-btn .l-panel-btn-l,.l-panel-btn .l-panel-btn-r{ display:none;} +.l-panel-btn-over,.l-panel-btn-selected{background: #E0EDFF url(../images/panel/panel-btn.gif) repeat-x;} +.l-panel-btn-over .l-panel-btn-l,.l-panel-btn-over .l-panel-btn-r,.l-panel-btn-selected .l-panel-btn-l,.l-panel-btn-selected .l-panel-btn-r{ display:block; } +.l-panel-btn-l +{ + position:absolute; width:3px; left:0px; top:0px;height:22px; + background: #E0EDFF url(../images/panel/panel-btn-l.gif) no-repeat; +} +.l-panel-btn-r +{position:absolute; width:3px; right:0px; top:0px;height:22px; + background: #E0EDFF url(../images/panel/panel-btn-r.gif) no-repeat; +} +.l-panel-header{ +color: #15428B; +font-weight: bold; +font-size: 11px; + height:24px; +border-bottom:1px solid #99BBE8; +background: url('../images/panel/header-bg.gif') repeat-x left -1px; position:relative; +} +.l-panel-header-hasicon{ padding-left:13px;} +.l-panel-header img{ position:absolute; left:6px; top:5px; width:16px; height:16px; border:0px;} +.l-panel-header-text{ line-height:22px;padding-left:10px;} + +.l-panel-body +{ + position:relative; overflow:hidden; width:100%; +} + +.l-panel .l-toolbar { + background:none;border:0; +} +.l-panel-topbar { + padding:0; +} +.l-panel-topbarinner { + float:right; +} +.l-panel-topbarinner-left +{ + float:left; +} +.l-panel-topbartitle { + font-weight:bold; padding:0;margin:0;margin-left:9px; +} +.l-panel-topbartitle-hasicon { + padding-left:24px;position:relative; +} +.l-panel-topbaricon { + width:16px; height:16px; position:absolute; left:0px; top:6px; +} +.l-panel-body .l-grid +{ + +} +.l-grid +{ + position:relative;text-align:left; +} +.l-grid-empty .l-grid-body-inner { + width:100%; +} +.l-grid-empty .l-grid-body { + overflow:hidden; +} +.l-grid-hashorizontal .l-grid-body1 .l-jplace { + height:19px; +} +.l-grid td div +{ + font-size:12px; +} + .l-grid table{border-spacing:0 0;} +.l-grid-header { + border-bottom: 1px solid #A3C0E8; + height: 22px; + line-height: 22px; + background: #E2F0FF url('../images/grid/header-bg.gif') repeat-x left bottom; + overflow: hidden; + width: 100%; +} +.l-grid-scroller { +position: relative; + top: 0px; + left: 0px; height:220px;overflow: auto; +} +.l-grid-scroller-noscroll +{ + height:auto;overflow:hidden; +} +.l-grid-body +{ +position: relative; width:100%; + top: 0px; + left: 0px; overflow: auto; +} +.l-grid-body-table +{ + +} +.l-grid-body-table tr.l-checked td +{ + background:#DCF8A8 +} +.l-grid-popup +{ + background: #eee url(../images/grid/popup-line.gif) repeat-y -1px top; + border: 1px solid #ccc; + border-top: 0px; + overflow: auto; + left: 0px; + position: absolute; + z-index: 999; display:none; +} +.l-grid-loading +{ + position: absolute;z-index: 91000; border:1px solid #9BBBE6; top:40%; left:50%; + background:white url('../images/common/loading.gif') no-repeat 8px 6px; padding-left:38px; + padding-top:10px; padding-bottom:10px; padding-right:10px; margin-left:-60px; display:none; +} +.l-grid-editor +{ + position: absolute;z-index: 999;display:none; text-align:center; +} +.l-grid-editor .l-checkbox-wrapper{ margin-top:2px;} +.l-grid-popup table +{ + display: table; + border-collapse: separate; + border-color: gray; margin:2px; +} +.l-grid-popup table tbody +{display: table-row-group; +vertical-align: middle; +border-color: inherit; +} +.l-grid-popup table td +{ + padding: 2px 3px; + cursor: default; +} +.l-grid-popup td.l-column-left +{ +border-right: 1px solid #ccc; +} + +.l-grid-popup td.l-column-right +{ +border-left: 1px solid #fff; +padding-right: 10px; +} + +.l-grid-popup tr:hover .l-column-right,.l-grid-popup tr.l-popup-row-over .l-column-right +{ + border-right: 1px solid #d2e3ec;border-top: 1px solid #d2e3ec;border-bottom: 1px solid #d2e3ec; +} + +.l-grid-popup tr:hover .l-column-left,.l-grid-popup tr.l-popup-row-over .l-column-left +{ + border-left: 1px solid #d2e3ec;border-top: 1px solid #d2e3ec;border-bottom: 1px solid #d2e3ec; +} +.l-grid-popup table tr:hover,.l-grid-popup table tr.l-popup-row-over +{ + background: #d5effc url(../images/grid/popup-row-over.gif) repeat-x top; + border: 1px solid #a8d8eb; +} +.l-grid-hd-cell-mul +{ + border-bottom: 1px solid #A3C0E8; +} +.l-grid-hd-cell-detail +{ + padding:0; margin:0; +} +.l-grid-hd-cell-inner +{ + text-align:center; +} + +.l-grid-dragging-line +{ + background:#EC4262;width:1px;position:absolute; display:none; z-index:9999; padding:0; margin:0; +} +.l-grid-hd-cell-dropleft +{ + position:absolute;left:0px;top:0px; + display: block;background: url(../images/icon/icon-prev.gif) no-repeat -2px center;width: 16px;height: 24px; + z-index: 3; display:none; +} +.l-grid-hd-cell-dropright +{ + position:absolute;right:0px;top:0px; + display: block;background: url(../images/icon/icon-next.gif) no-repeat 0px center;width: 16px;height: 24px; + z-index: 3; display:none; +} +.l-grid-hd-cell-drop +{ + position:absolute;right:-1px;top:0px;display: block; width:2px; height:24px; z-index:3; cursor:e-resize; +} +.l-grid-hd-cell-sort +{ + overflow:hidden; +} +.l-grid-hd-cell-sort-asc +{ + background:url('../images/icon/icon-sort-asc.gif') no-repeat center; +} +.l-grid-hd-cell-sort-desc +{ + background:url('../images/icon/icon-sort-desc.gif') no-repeat center; +} +.l-grid-hd-cell-btn +{ + position:absolute; right:0px; top:0px; overflow:hidden; border-left:1px solid #C1D6F0; cursor:pointer; +} +.l-grid-hd-cell-btn span +{ + border-left:1px solid #F1F5FC; width:14px; height:22px;background:url('../images/icon/icon-down.gif') no-repeat 2px 8px; display:block; +} +.l-grid-hd-cell-drophandle +{ + width:5px; height:22px; cursor:col-resize; float:right;position:absolute; top:0px; right:-3px; +} +.l-grid-hd-cell-text +{ + text-align:center; + cursor:pointer; + overflow:hidden; +} +.l-grid-hd-cell +{ + padding:0; margin:0;overflow:hidden; + border-right:1px solid #A3C0E8; + text-align:center; +} +.l-grid-hd-cell-last +{ + +} +.l-grid-hd-cell-over,.l-grid-hd-cell-on +{ +} +.l-grid-row +{ +} +.l-grid-row-last +{ +} +.l-grid-totalsummary +{ + border-bottom:1px solid #A3C0E8; background:#EEF3FF; padding-top:5px; padding-bottom:5px; +} +.l-grid-totalsummary-nobottom +{ + border-bottom:none; +} +.l-grid-totalsummary td +{ + border-right:1px solid #EEF3FF; text-align:center;line-height: 23px; +} +.l-grid-totalsummary .l-grid-totalsummary-cell-last +{ border-right:1px solid #A3C0E8; +} +.l-grid-totalsummary .l-grid-totalsummary-cell-inner +{ + margin-left:3px; margin-right:3px; min-height:23px;_height:23px; +} +.l-grid-totalsummary .l-grid-totalsummary-cell-inner div +{ + height:22px; line-height:22px; +} +/* + detail +*/ +.l-grid-detailpanel +{ + border-right:1px solid #A3C0E8;border-bottom:1px solid #A3C0E8; +} +.l-grid-detailpanel-inner +{ + overflow:auto; margin-bottom:2px; +} + +.l-grid-row-alt .l-grid-row-cell +{ + background:#F5F5F5; +} +.l-grid-row-over .l-grid-row-cell,.l-grid-row-over +{ + background:#E0ECFF +} +.l-selected .l-grid-row-cell,.l-selected +{ + background:#DCF8A8 +} + +.l-grid-row-cell +{ + overflow:hidden; + border-right:1px solid #A3C0E8;border-bottom:1px solid #A3C0E8; + text-align:center;overflow:hidden; +} +.l-grid-row-last .l-grid-row-cell +{border-bottom:none; +} +.l-grid-row-cell-last +{ + +} +.l-grid-row-cell-detail .l-grid-row-cell-inner{margin-left:0px; margin-right:0px; width:27px; overflow:hidden;} +.l-grid-row-cell-detail .l-grid-row-cell-inner span +{ + display:block; width:21px; height:21px; background:url('../images/grid/grid-detail-close.gif') no-repeat 5px 5px; + cursor:pointer; overflow:hidden; +} +.l-grid-row-cell-detail .l-grid-row-cell-inner span.l-open +{ + background:url('../images/grid/grid-detail-open.gif') no-repeat 5px 5px; +} + +.l-grid-row-cell-checkbox .l-grid-row-cell-inner{margin-left:0px; margin-right:0px;} +.l-grid-row-cell-checkbox span,.l-grid-hd-cell-checkbox .l-grid-hd-cell-inner div +{ + display:block; width:13px; height:13px; background:url('../images/controls/checkbox.gif') no-repeat; + background-position:0px 0px; + cursor:pointer; overflow:hidden; margin-left:7px; margin-top:3px; +} +.l-checked .l-grid-row-cell-checkbox span,.l-checked .l-grid-hd-cell-checkbox .l-grid-hd-cell-inner div +{ + background-position:0px -13px; +} +.l-selected .l-grid-row-cell-checkbox span,.l-selected .l-grid-hd-cell-checkbox .l-grid-hd-cell-inner div +{ + background-position:0px -13px; +} +.l-grid-hd-cell-inner { + overflow: hidden; +} +.l-grid-hd-cell-checkbox +{ + padding:0; margin:0; +} + +.l-grid-row-cell-edited .l-grid-row-cell-inner +{ + background-image:url('../images/icon/icon-edited.gif'); + background-repeat:no-repeat; + background-position:2px 2px; +} +.l-grid-row-cell-inner +{ + text-align:center;line-height:22px; min-height:22px; _height:22px; + margin-left:3px; margin-right:3px; overflow:hidden; +} +.l-grid-row-cell-inner-fixedheight +{ + height:22px; +} +.l-panel-bar +{ + height:32px;background:#C9DFFF url('../images/panel/bar-bg.gif') repeat-x left bottom;overflow:hidden;border:0; + border-top:1px solid #84A0C4; +} +.l-panel-bbar-inner +{ + margin-top: 3px; + padding-left: -2px; + width:100%; position:relative; min-width:530px;_width:530px; +} +.l-bar-message +{ + position:absolute; right:0px; +} +.l-bar-group { +float: left; +background: none; +height: 24px; +margin: 0px 5px; +} +.l-bar-right +{ + float:right; +} +.l-bar-separator { +float: left; +height: 18px; +border-left: 1px solid #9AC6FF; +border-right: 1px solid white; +margin: 2px; +} +.l-bar-button { +float: left; +width: 22px; +height: 22px; +border: 0px; +cursor: pointer; +overflow: hidden; +margin-top: 4px; +} +.l-bar-button-over +{ + background: url(../images/icon/bar-button-over.gif) no-repeat center; +} +.l-bar-button span { +width: 16px; +height: 16px; +display: block; margin-left:2px; margin-top:2px; +float: left; overflow:hidden; +} +.l-bar-btnfirst span +{ +background: url(../images/icon/icon-first.gif) no-repeat; background-position:0px 0px; +} +.l-bar-btnprev span { +background: url(../images/icon/icon-prev.gif) no-repeat ; background-position:0px 0px; +} +.l-bar-btnnext span { +background: url(../images/icon/icon-next.gif) no-repeat; background-position:0px 0px; +} +.l-bar-btnlast span { +background: url(../images/icon/icon-last.gif) no-repeat; background-position:0px 0px; +} +.l-bar-btnload span { +background: url(../images/icon/icon-load.gif) no-repeat; background-position:0px 0px; +} +.l-bar-btnloading span { +background: url(../images/icon/icon-loading.gif) no-repeat; background-position:0px 0px; +} +.l-bar-button .l-disabled +{ + background-position:0px -16px; +} +.l-bar-text +{ + line-height:20px; +} + +/* + grouping +*/ +.l-grid .l-grid-grouprow{ border-right:1px solid #A3C0E8} +.l-grid .l-grid-grouprow-cell{ padding:6px; border-bottom:1px solid #A3C0E8; background:#EAF3FF;} +.l-grid .l-grid-group-togglebtn{background:url('../images/grid/grid-detail-open.gif') no-repeat center; cursor:pointer} +.l-grid .l-grid-group-togglebtn-close{background:url('../images/grid/grid-detail-close.gif') no-repeat center;} +.l-grid .l-grid-totalsummary-group td{ background-color:#F5EEFB; border-color:#F5EEFB;} +/* + foot total +*/ + .l-panel-bar-total{ background:#F5F9FF; padding:8px; border-top:1px solid #84A0C4;} +/* + tree grid +*/ +.l-grid-tree-space +{ + width:18px; height:20px; line-height:20px; overflow:hidden; float:left; +} +.l-grid-tree-link-open +{ + cursor:pointer;background:url('../images/grid/grid-tree-open.gif') no-repeat center; +} +.l-grid-tree-link-close +{ + cursor:pointer;background:url('../images/grid/grid-tree-close.gif') no-repeat center; +} +/* + frozen grid +*/ +.l-grid1{ display:none;} +.l-grid1 .l-grid-body{overflow:hidden;} +.l-grid1 .l-grid-detailpanel{border-right:1px solid white;} +.l-frozen .l-grid2{position:absolute; top:0px; left:0px; width:100%; } +.l-frozen .l-grid2 .l-grid-body{overflow-x:auto;} +.l-frozen .l-grid1{position:absolute; top:0px; left:0px;display:block;} + + +.l-grid-gray +{border-top:1px solid #DDDDDD; +} +.l-grid-gray .l-grid-header + { + border-bottom:1px solid #DDDDDD; + background:#E2F0FF url('../images/grid/header2-bg.jpg') repeat-x left bottom; + } +.l-grid-gray .l-grid-hd-cell +{ + border-right:1px solid #DDDDDD; +} +.l-grid-gray .l-grid-row-cell { + border-bottom: 1px solid #DDDDDD; + border-right: 1px solid #DDDDDD; +} +/* + 菜单条 +*/ +.l-menubar +{ + background: url('../images/panel/panel-menu.gif') repeat-x; height:24px; border:1px solid #ADBED6;border-top:1px solid #EFF7F7; + +} +.l-menubar-item +{ + float:left; margin-left:6px; +} +.l-menubar-item-down +{ + width:7px; height:4px; line-height:4px; + background:url('../images/panel/panel-menu-item-down.gif') no-repeat center; position:absolute; right:4px; top:9px; top:9px\9;_top:4px; +} +.l-menubar-item-over +{ +} +/* + 工具条 +*/ +.l-toolbar +{ + background:#CEDFEF url('../images/panel/panel-toolbar.gif') repeat-x; height:23px; + border:1px solid #9CBAE7; border-top:1px solid #EFF7F7; +} +.l-toolbar-item +{ + float:left;margin-left:4px; +} +.l-toolbar-item .l-icon,.l-toolbar-item img{ position:absolute; left:2px; top:2px; display:block;} +.l-toolbar-item img{ width:16px; height:16px; border:0px;} +.l-toolbar-item-hasicon{ padding-left:22px;} +.l-toolbar-item-disable{cursor:default;} +.l-toolbar-item-disable span{color: #A1A1A1;} +.l-toolbar-item-color{border: 1px solid #ccc;position: absolute;width: 14px;height: 14px;left: 3px;top: 3px;} +/* + 搜索栏 +*/ +.l-panel-search +{height:28px; padding-top:3px; padding-left:3px; + border-left:1px solid #99BBE8; border-right:1px solid #99BBE8; +} +.l-panel-search-item +{ + float:left; margin-left:5px; +} + +/* + 编辑 +*/ +.l-grid-row-cell-editing-topcell {border-bottom-color:#CC8F81;} +.l-grid-row-cell-editing-leftcell {border-right-color:#CC8F81;} +.l-grid-row-cell-editing{ border-color:#CC8F81;} +.l-grid-row-cell .l-text,.l-grid-editor .l-text{ border:0px; border:none;} +.l-grid-detailpanel-edit{ padding-top:7px;padding-bottom:3px; background-color:#FAFAFF;} +.l-grid-detailpanel .l-editbox{ float:left; margin:2px;margin-left:6px; margin-right:10px;} +.l-grid-detailpanel .l-button{float:left;margin:2px;margin-left:4px; margin-right:6px;} +.l-grid-detailpanel .l-clear{ clear:both;} + + +.l-grid-row-alt .l-grid-row-cell-rownumbers,.l-selected .l-grid-row-cell-rownumbers,.l-grid-row-over .l-grid-row-cell-rownumbers,.l-grid-row-cell-rownumbers{ background:#E0ECFF;} + diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-layout.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-layout.css new file mode 100755 index 0000000..07d01ed --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-layout.css @@ -0,0 +1,143 @@ + +/* -------------- + * layout * +* ------------ */ +.l-layout{ position:relative;} +.l-layout-left,.l-layout-right,.l-layout-center,.l-layout-top,.l-layout-bottom,.l-layout-centerbottom{position:absolute;border:1px solid #BED5F3; background:white; z-index:10; overflow:hidden;} +.l-layout-top{width:100%;} +.l-layout-bottom{width:100%} + +.l-layout-left .l-layout-header-toggle{position:absolute; top:3px; right:3px; height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');background-position:-20px 0px; cursor:pointer;} +.l-layout-left .l-layout-header-toggle-over{ background-position:-20px -20px;} + +.l-layout-right .l-layout-header-toggle{position:absolute; top:3px; left:3px; height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');background-position:-20px -40px; cursor:pointer;} +.l-layout-right .l-layout-header-toggle-over{ background-position:-20px -60px;} + +.l-layout-center .l-layout-header{ cursor:default;} +.l-layout-centerbottom .l-layout-header{ cursor:default;} + +.l-layout-header{ position:relative;padding-left:10px; color:#183152; font-weight:bold;height:25px; line-height:24px; background:#E5EFFE url('../images/layout/layout-header.gif') repeat-x; overflow:hidden; cursor:pointer} +.l-layout-header-inner{padding-right:22px;} +.l-layout-right .l-layout-header-inner { padding-left:22px; padding-right:auto;} +.l-layout-header-over{background:#EFF4FE url('../images/layout/layout-header-over.gif') repeat-x;} + +.l-layout-collapse-left,.l-layout-collapse-right{ width:24px; background:#EAF2FE;border:1px solid #B8D0D6; position:absolute;top:0px; display:none; height:100%;z-index:10;} +.l-layout-collapse-left-over,.l-layout-collapse-right-over{background:#F5F9FA;} +.l-layout-collapse-left-toggle,.l-layout-collapse-right-toggle{position:absolute; height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');cursor:pointer;} +.l-layout-collapse-left{left:2px;} +.l-layout-collapse-left-toggle{top:0px; right:2px; background-position:-20px -40px;} +.l-layout-collapse-left-toggle-over{background-position:-20px -60px;} + +.l-layout-collapse-right{right:2px;} +.l-layout-collapse-right-toggle{top:0px; left:2px; background-position:-20px 0px;} +.l-layout-collapse-right-toggle-over{background-position:-20px -20px;} + + + +.l-layout-drophandle-left{ position:absolute;width:5px;cursor:col-resize; z-index:10;display:none;} +.l-layout-drophandle-right{ position:absolute;width:5px;cursor:col-resize; z-index:10;display:none;} +.l-layout-drophandle-top{ position:absolute;height:5px;cursor:row-resize; z-index:10;display:none; line-height:1px;overflow:hidden;} +.l-layout-drophandle-bottom{ position:absolute;height:5px;cursor:row-resize; z-index:10;display:none;line-height:1px;overflow:hidden;} + +.l-layout-drophandle-centerbottom{ position:absolute;height:5px;cursor:row-resize; z-index:10;display:none;line-height:1px;overflow:hidden;} + +.l-layout-dragging-xline{ background:#E0E4E2;height:4px;position:absolute;display:none; z-index:9999; padding:0; margin:0;line-height:1px; overflow:hidden;} +.l-layout-dragging-yline{ background:#E0E4E2;width:4px;position:absolute;display:none; z-index:9999; padding:0; margin:0;} +.l-layout-lock{ position:absolute; width:100%; height:100%; display:none; z-index:9990; margin:0; padding:0;} +.l-layout-content{position:relative; background:white; overflow:hidden;} + +.l-layout-drophandle{ position:absolute; top:0px; left:-5px; width:5px;cursor:col-resize; z-index:10;height:100%; display:none;} +.l-layout-collapse{ width:24px; background:#EAF2FE;border:1px solid #B8D0D6; position:absolute; top:0px; left:4px; display:none; height:100%;z-index:10;} +.l-layout-collapse-over{background:#F5F9FA;} +.l-layout-collapse-toggle{position:absolute; top:0px; right:2px; height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');background-position:-20px -40px; cursor:pointer;} +.l-layout-collapse-toggle-over{background-position:-20px -60px;} +.l-layout-dragging-line{ background:#E0E4E2;width:4px;position:absolute;top:0px; display:none; z-index:9999; padding:0; margin:0;height:100%;} + +.l-layout-xmask { + cursor: col-resize;z-index:9990; +} +.l-layout-ymask { + cursor: row-resize;z-index:9990; +} +/* -------------- + * accordion * +* ------------ */ +.l-accordion-panel{ border-left:1px solid #BED5F3; border-right:1px solid #BED5F3; border-bottom:1px solid #BED5F3; } +.l-accordion-toggle{ position:absolute; top:2px; right:4px; height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');cursor:pointer;} +.l-accordion-toggle-close{ background-position:0px 0px;} +.l-accordion-toggle-close-over{ background-position:0px -20px;} +.l-accordion-toggle-open{ background-position:0px -40px;} +.l-accordion-toggle-open-over{ background-position:0px -60px;} +.l-accordion-header{ position:relative;padding-left:10px; color:#183152; font-weight:bold;height:25px; line-height:24px; background:#E5EFFE url('../images/layout/accordion-header.gif') repeat-x; overflow:hidden; cursor:pointer;} +.l-accordion-header-over{background:#EFF4FE url('../images/layout/accordion-header-over.gif') repeat-x;} +.l-accordion-content{position:relative;overflow:auto; background:white url('../images/layout/accordion-content.gif') repeat-x;} + +.l-layout-left .l-accordion-panel{ border-left:none; border-right:none; } +.l-accordion-header i { + display: none; +} +.l-accordion-header-hasicon { + padding-left:30px;position:relative; +} +.l-accordion-header-hasicon i { + display:block;position:absolute;left:5px;top:5px;width:16px;height:16px;margin:0;padding:0; +} + .l-accordion-header-hasicon i img { + width:16px;height:16px; + } +/* -------------- + * panel * +* ------------ */ +.l-panel { + border: 1px solid #99BBE8; + position: relative; + text-align: left; +} +.l-panel-dragging { + z-index:999; +} +.l-panel-content { + background: white; +} +.l-panel-loading{ position: absolute;z-index: 91000; top:0; left:0;background:white url('../images/common/bigloading.gif') no-repeat center 40%; width:100%; height:100%;_height:800px;display:none;} +.l-panel-header{ position:relative;padding-left:10px; color:#183152; font-weight:bold;height:25px; line-height:24px; background:#E5EFFE url('../images/layout/panel-header2.gif') repeat-x; overflow:hidden; } +.l-panel-header-toggle{ height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');background-position:-60px 0px; cursor:pointer; float:right;} +.l-panel-header-toggle-hide {background-position:-60px -40px;} +.l-panel-header-close{ height:20px; width:20px; overflow:hidden; background:url('../images/layout/togglebar.gif');background-position:-40px -20px; cursor:pointer; float:right;} +.l-panel-header .icons { + width:80px; position:absolute; right:0px;top:0px; +} +.l-panel-content iframe { + width: 100%; + height: 100%; + overflow: hidden; +} + +/* -------------- + * Portal * +* ------------ */ +.l-portal .l-row-dragging { + +} +.l-panel-place { + width:100%; height:180px; border:1px dashed #88B0E4; background:white; + margin-bottom:10px; +} +.l-column-place { + height:4px;width:100%; +} +.l-portal .l-row-dragging .l-column-place { + border:1px dashed #C48AD7; +} +.l-column-empty .l-column-place { + height:80px; +} +.l-portal .l-row { + clear:both;margin-bottom:7px; +} +.l-portal .l-column { + float:left;margin-right:10px; +} +.l-portal .l-column .l-panel { + margin-bottom:10px; +} diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-menu.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-menu.css new file mode 100755 index 0000000..f3dd518 --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-menu.css @@ -0,0 +1,27 @@ + +/* -------------- + * menu * +* ------------ */ + +.l-menu { border:1px solid #979797; background:#F5F5F5;position:absolute; overflow:hidden; padding-bottom:2px; z-index:1001} +.l-menu-shadow{z-index:1000; + FILTER: progid:DXImageTransform.Microsoft.Blur(pixelRadius=2,MakeShadow=false,ShadowOpacity=0.2); + BACKGROUND: #ddd; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -moz-box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.2); +position: absolute;} +.l-menu-inner{ position:relative;width:100%;z-index:103;} +.l-menu-over{position:absolute;top:-24px;left:2px; z-index:102; height:22px; overflow:hidden;background:url('../images/menu/menu-item-over-m.gif') repeat-x;width:97%;} +.l-menu-yline { background:url('../images/menu/menu-line-y.gif') repeat-y; width:2px; height:2000px; position:absolute; left:28px; top:1px; z-index:101;} +.l-menu-over-l{background:url('../images/menu/menu-item-over-l.gif') no-repeat; width:28px; height:22px; position:absolute;top:0; left:0;} +.l-menu-over-r{background:url('../images/menu/menu-item-over-r.gif') no-repeat; width:3px;height:22px; position:absolute;top:0; right:0;} +.l-menu-item { position:relative; height:23px; line-height:23px; width:100%; cursor:pointer;} +.l-menu-item-line{background:url('../images/menu/menu-line-x.gif') repeat-x; height:2px; width:100%; margin-top:1px; margin-bottom:1px; margin-left:30px; line-height:2px; overflow:hidden;} +.l-menu-item-arrow{background:url('../images/menu/menu-item-arrow.gif') no-repeat; position:absolute; top:8px; right:9px; width:4px; height:7px;} +.l-menu-item-text{color:#000000;left: 33px;position: absolute;top: 0;} +.l-menu-item-icon{ left: 3px;top: 0;position: absolute; width:25px; height:22px; overflow:hidden;} +.l-menu-item-color{border: 1px solid #cccccc;left: 6px;top: 3px;position: absolute;width: 16px;height: 16px;overflow: hidden;} +.l-menu-item-disable{ cursor:default;} +.l-menu-item-disable .l-menu-item-text{ color:#A1A1A1;} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tab.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tab.css new file mode 100755 index 0000000..95c5b59 --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tab.css @@ -0,0 +1,107 @@ + +/* ----------------------- + * tab * +* ----------------------- */ + +.l-tab-loading{ position: absolute;z-index: 91000; top:0; left:0;background:white url('../images/common/bigloading.gif') no-repeat center 40%; width:100%; height:100%;_height:800px;display:none;} + +.l-tab-links{position:relative; height:26px; background:#F0F5F6; width:100%; overflow:hidden; +background:url('../images/layout/tabs-bg.gif') repeat-x; border-bottom:1px solid #BED5F3;} +.l-tab-links-left{position:absolute; top:1px; left:0; width:17px; height:23px; overflow:hidden; background:url(../images/layout/tabs-tools.gif) 0px 0px; z-index:13; cursor:pointer;} +.l-tab-links-right{ position:absolute; top:1px; right:0;width:17px; height:23px; overflow:hidden;background:url(../images/layout/tabs-tools.gif) -51px 0px;z-index:13; cursor:pointer;} +.l-tab-links-left-over{ background-position:-17px 0px;} +.l-tab-links-right-over{ background-position:-68px 0px;} +.l-tab-links-left-invalid{ background-position:-34px 0px;} +.l-tab-links-right-invalid{ background-position:-85px 0px;} + + + + +.l-tab-switch { position:absolute; + top:1px; right:0;width:17px; + height:23px; overflow:hidden;background:url(../images/layout/tabs-tools.gif) -102px 0px;z-index:13; cursor:pointer; display:none; } +.l-tab-itemswitch +{ + width: 26px;border-top-right-radius: 3px;background: #fff; position:relative; +} +.l-tab-links .l-tab-itemswitch a +{ + width:7px;height:4px; line-height:4px;background:url(../images/layout/tabs-tools.gif) 0px -30px; position:absolute; + left : 50%;top:50%;margin-left:-4px; margin-top:-2px; +} +.l-tab-switchable .l-tab-links-right +{ + right:18px; +} +.l-tab-switchable .l-tab-switch +{ + display:block; +} +.l-tab-windowsswitch +{ + border:1px solid #BED5F3; padding:1px; background:#ffffff;position: absolute; + z-index: 9900; +} +.l-tab-windowsswitch .theline { + height:1px;line-height:1px;margin-top:5px; margin-bottom:5px;border:none; + border-bottom:1px dashed #DCDCDC; +} +.l-tab-windowsswitch .closeall { + background:url(../images/layout/closeall.gif);height:16px; line-height:16px;width:16px; +} + .l-tab-windowsswitch a + { + display:block; text-decoration:none; height:24px; line-height:24px; border:1px solid #fff; color:#333; padding:0 5px; + width:130px; overflow:hidden;margin:1px; + } + .l-tab-windowsswitch a:hover + { + border:1px solid #d3d3d3; + background:#f9f9f9; + } + .l-tab-windowsswitch a.selected + { + border:1px solid #B9D2F2; + background:#CADDF5; + } + +.l-tab-links ul{ list-style:none; margin:0; padding:0; width:9999px; height:26px; overflow:hidden; position:absolute; top:0; left:0;} +.l-tab-links li{ float:left; margin:0; padding:0; margin-left:2px; height: 26px; line-height:26px; cursor:pointer;background:url(../images/layout/tabs-item-bg.gif); position:relative; overflow:hidden; border:none; } +.l-tab-links li.l-selected{background:url(../images/layout/tabs-item-over-bg.gif);} +.l-tab-links li a{ display:block; margin-left:6px; margin-right:37px; text-decoration:none; color:#333;} +.l-tab-links-item-left{ position:absolute;top:0; left:0;width:2px; height:26px; background:url(../images/layout/tabs-item-left-bg.gif)} +.l-tab-links-item-right{position:absolute;top:0; right:0;width:2px; height:26px;background:url(../images/layout/tabs-item-right-bg.gif)} + +.l-tab-links-item-close{ width:11px; height:11px; overflow:hidden; position:absolute; top:4px; right:2px; z-index:12;background:url(../images/icon/icon-close.gif); cursor:pointer;} +.l-tab-links-item-close-over{background:url(../images/icon/icon-close-over.gif);} + +.l-tab-content{ margin:0 auto; padding:0; border:none; width:100%;} +.l-tab-content-item{ width:100%; height:100%; overflow:hidden; position:relative;} +.l-tab-content-item iframe{width:100%; height:100%; border:none;} + + +.l-tab-drag-proxy { border: 1px solid #BDD1EE;position: absolute;z-index: 1001;height:25px; line-height:25px; padding-left:19px; padding-right:4px; background:white; } +.l-tab-drag-proxy .l-drop-icon{position: absolute; top:5px; left:4px;width:16px; height:16px; } +.l-drop-no{background: white url('../images/common/drop-icons.gif') no-repeat 0px -20px; width:16px; height:16px; overflow:hidden;} +.l-drop-yes{background: white url('../images/common/drop-icons.gif') no-repeat 0px 0px; width:16px; height:16px; overflow:hidden;} + +.l-tab-drag-droptip +{ + width:9px; position:absolute; top:30px; left:30px; height:44px; z-index:1000; +} +.l-tab-drag-droptip .l-drop-move-up{ position:absolute; top:0px;} +.l-tab-drag-droptip .l-drop-move-down{ position:absolute; bottom:0px;} + +.l-drop-move-up{background:transparent url('../images/common/drop-icons.gif') no-repeat -40px 0px; width:9px; height:9px; overflow:hidden;} +.l-drop-move-down{background: transparent url('../images/common/drop-icons.gif') no-repeat -60px 0px; width:9px; height:9px; overflow:hidden;} +/* ----------------------- + * easytab * +* ----------------------- */ +.l-easytab{ padding:0px; position:relative;} +.l-easytab .l-easytab-header{margin:0; padding:0; list-style:none;position:absolute; top:0px; left:0px; z-index:101;} +.l-easytab .l-easytab-header { padding-left:3px;} +.l-easytab .l-easytab-header li{ float:left; margin-left:2px;} +.l-easytab .l-easytab-header li span{ display:block; line-height:22px; height:22px; padding-left:8px; padding-right:8px; background:url('../images/controls/bg-tab-title.gif') repeat-x; color:#333; text-decoration:none;border:1px solid #AECAF0; color:#283B56; border-bottom:none;} +.l-easytab .l-easytab-header li span.l-over{background:url('../images/controls/bg-tab-title-over.gif') repeat-x;border:1px solid #DAB364; cursor:pointer;border-bottom:none;} +.l-easytab .l-easytab-header li span.l-selected{ background:none; background:white; border-top:3px solid #FFBD69;height:20px;color:#355686; border-left:1px solid #DAB364;border-right:1px solid #DAB364;border-bottom:1px solid white;border-bottom:none; } +.l-easytab .l-easytab-panelbox{ border:1px solid #AECAF0; clear:left; position:absolute;top:23px; padding:4px;z-index:100;} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tree.css b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tree.css new file mode 100755 index 0000000..732090e --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/Aqua/css/ligerui-tree.css @@ -0,0 +1,79 @@ + +/* -------------- + * tree * +* ------------ */ +.l-tree +{ + margin:0; padding:0; list-style:none; overflow:hidden; position:relative; display:block; background:white; +} +.l-tree-loading +{ + position: absolute;z-index: 91000; top:40%; left:50%; overflow:hidden; + background:url('../images/tree/loading.gif') no-repeat 0px 0px;width:24px; height:24px; + display:none; +} +.l-tree a,.l-tree span{color: #333;height: 22px;line-height: 22px; text-decoration:none;} +.l-tree .l-body span +{ + display: block; + float: left;_display: inherit;_float:none;*display: inherit;*float:none; +} +.l-tree ul,.l-tree li{list-style:none; margin:0; padding:0;} +.l-tree li {clear: both;display: block;cursor: pointer;} +.l-tree li .l-body{ height:22px;line-height: 22px; overflow:hidden;width: 2000px;} +.l-tree .l-box +{ + width:22px; height:22px; overflow:hidden; float:left; background:url('../images/tree/tree.gif');background-position:-22px -220px; +} +.l-tree li .l-body .l-box-loading +{ + background:url('../images/tree/nodeloading4.gif') no-repeat 5px 5px; cursor:default; +} +.l-tree-noline .l-box +{ + background-image:url('../images/tree/tree-noline.gif'); +} +.l-tree .l-expandable-close{background-position:0px -44px;} +.l-tree .l-first .l-expandable-close{background-position:0px -22px;} +.l-tree .l-last .l-expandable-close{ background-position:0px -66px;} +.l-tree .l-onlychild .l-expandable-close{background-position:0px 0px;} + +.l-tree .l-expandable-open{background-position:0px -132px;} +.l-tree .l-first .l-expandable-open{background-position:0px -110px;} +.l-tree .l-last .l-expandable-open{ background-position:0px -154px;} +.l-tree .l-onlychild .l-expandable-open{background-position:0px -88px;} + +.l-tree .l-over +{ + background: none; +} +.l-tree .l-over span +{ + text-decoration:underline; +} +.l-tree .l-selected +{ + background: none; +} +.l-tree .l-selected span{background: #D9E8FB; border:1px solid #B5CBEC; padding:0px 2px;height: 20px; +line-height: 20px;} + +.l-tree .l-line{background-position:0px -176px;} +.l-tree .l-note{ background-position:0px -198px;} + +.l-tree .l-note{ background-position:0px -198px;} +.l-tree .l-note-last{ background-position:0px -220px;} +.l-tree .l-checkbox-unchecked{ background-position:-22px 0px;} +.l-tree .l-checkbox-checked{ background-position:-22px -22px;} +.l-tree .l-checkbox-incomplete{ background-position:-22px -44px;} + +.l-tree .l-over .l-checkbox-unchecked{ background-position:-44px 0px;} +.l-tree .l-over .l-checkbox-checked{ background-position:-44px -22px;} +.l-tree .l-over .l-checkbox-incomplete{ background-position:-44px -44px;} + + +.l-tree .l-tree-icon-folder{ background-position:-22px -88px;} +.l-tree .l-tree-icon-none{ background:none;} +.l-tree .l-tree-icon-none img{border: 0;height: 16px;width: 16px; top:2px; margin-top:2px; margin-left:2px;} +.l-tree .l-tree-icon-folder-open{background-position:-44px -88px;} +.l-tree .l-tree-icon-leaf{background-position:-22px -110px;} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/bigloading.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/bigloading.gif new file mode 100755 index 0000000..b1565d7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/bigloading.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-disabled.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-disabled.gif new file mode 100755 index 0000000..29b169b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-disabled.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-over.gif new file mode 100755 index 0000000..39a0b96 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button.gif new file mode 100755 index 0000000..d53d233 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/button.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/drop-icons.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/drop-icons.gif new file mode 100755 index 0000000..a7355e1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/drop-icons.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/exclamation.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/exclamation.gif new file mode 100755 index 0000000..dcd851a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/exclamation.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/invalid-line.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/invalid-line.gif new file mode 100755 index 0000000..fb7e0f3 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/invalid-line.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/loading.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/loading.gif new file mode 100755 index 0000000..1d46b9b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/loading.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/table.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/table.png new file mode 100755 index 0000000..abcd936 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/table.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/toggle.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/toggle.gif new file mode 100755 index 0000000..1d797ff Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/common/toggle.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-over.gif new file mode 100755 index 0000000..50a00e5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-pressed.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-pressed.gif new file mode 100755 index 0000000..0000344 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title-pressed.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title.gif new file mode 100755 index 0000000..7629553 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-panel-title.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-over.gif new file mode 100755 index 0000000..50a00e5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-pressed.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-pressed.gif new file mode 100755 index 0000000..6182b11 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title-pressed.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title.gif new file mode 100755 index 0000000..7629553 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-tab-title.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-text.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-text.gif new file mode 100755 index 0000000..78d43f6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-text.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-over.gif new file mode 100755 index 0000000..f787af3 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-pressed.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-pressed.gif new file mode 100755 index 0000000..8e8354d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger-pressed.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger.gif new file mode 100755 index 0000000..7629553 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/bg-trigger.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-l.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-l.gif new file mode 100755 index 0000000..12b72bc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-l.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-r.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-r.gif new file mode 100755 index 0000000..56e3356 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn-r.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn.gif new file mode 100755 index 0000000..8ed3705 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/btn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg-over.gif new file mode 100755 index 0000000..58843b5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg.gif new file mode 100755 index 0000000..828d11c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/button-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/checkbox.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/checkbox.gif new file mode 100755 index 0000000..ec9b9c8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/checkbox.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-bar-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-bar-bg.gif new file mode 100755 index 0000000..228532f Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-bar-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-header-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-header-bg.gif new file mode 100755 index 0000000..dd13f93 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/dateeditor-header-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/radio.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/radio.gif new file mode 100755 index 0000000..87759a7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/controls/radio.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/date.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/date.gif new file mode 100755 index 0000000..4ad2403 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/date.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-first.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-first.gif new file mode 100755 index 0000000..bb2aba6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-first.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-last.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-last.gif new file mode 100755 index 0000000..61483e9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-last.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-next.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-next.gif new file mode 100755 index 0000000..2cd62cc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-next.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-prev.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-prev.gif new file mode 100755 index 0000000..b440a29 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/dateeditor/icon-prev.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/form/verify-corner.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/form/verify-corner.gif new file mode 100755 index 0000000..d5004c7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/form/verify-corner.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox-checked.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox-checked.gif new file mode 100755 index 0000000..1f202e7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox-checked.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox.gif new file mode 100755 index 0000000..146e638 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-checkbox.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-close.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-close.gif new file mode 100755 index 0000000..8dbb049 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-close.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-open.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-open.gif new file mode 100755 index 0000000..99bfbab Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-detail-open.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-close.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-close.gif new file mode 100755 index 0000000..7590580 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-close.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-open.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-open.gif new file mode 100755 index 0000000..826da37 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/grid-tree-open.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg-over.gif new file mode 100755 index 0000000..9f6beb9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg.gif new file mode 100755 index 0000000..b9a2858 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header2-bg.jpg b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header2-bg.jpg new file mode 100755 index 0000000..2078e5b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/header2-bg.jpg differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-line.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-line.gif new file mode 100755 index 0000000..fd1aafc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-line.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-row-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-row-over.gif new file mode 100755 index 0000000..c17b74d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/grid/popup-row-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/bar-button-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/bar-button-over.gif new file mode 100755 index 0000000..485ed08 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/bar-button-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox-checked.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox-checked.gif new file mode 100755 index 0000000..1f202e7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox-checked.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox.gif new file mode 100755 index 0000000..146e638 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/checkbox.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/cross.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/cross.gif new file mode 100755 index 0000000..8db7f98 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/cross.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close-over.gif new file mode 100755 index 0000000..b9c88be Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close.gif new file mode 100755 index 0000000..fec18b8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-close.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-down.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-down.gif new file mode 100755 index 0000000..ec99bfd Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-down.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-drop.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-drop.gif new file mode 100755 index 0000000..837c305 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-drop.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-edited.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-edited.gif new file mode 100755 index 0000000..7ef32c9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-edited.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-first.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-first.gif new file mode 100755 index 0000000..9495352 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-first.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-last.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-last.gif new file mode 100755 index 0000000..95ad391 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-last.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-line.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-line.gif new file mode 100755 index 0000000..fd1aafc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-line.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-load.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-load.gif new file mode 100755 index 0000000..43cc2df Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-load.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-next.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-next.gif new file mode 100755 index 0000000..0b5d27b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-next.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-prev.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-prev.gif new file mode 100755 index 0000000..b6986f0 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-prev.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-select.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-select.gif new file mode 100755 index 0000000..3d2ef54 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-select.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-asc.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-asc.gif new file mode 100755 index 0000000..6dac09e Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-asc.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-desc.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-desc.gif new file mode 100755 index 0000000..6400a46 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-sort-desc.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-unselect.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-unselect.gif new file mode 100755 index 0000000..f4d87c2 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-unselect.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-up.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-up.gif new file mode 100755 index 0000000..37f0ff3 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/icon-up.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/spr_icons.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/spr_icons.gif new file mode 100755 index 0000000..7ea9681 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/icon/spr_icons.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-content.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-content.gif new file mode 100755 index 0000000..942487f Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-content.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header-over.gif new file mode 100755 index 0000000..cc841b1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header.gif new file mode 100755 index 0000000..a9b586f Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/accordion-header.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/closeAll.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/closeAll.gif new file mode 100755 index 0000000..ccd43fa Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/closeAll.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header-over.gif new file mode 100755 index 0000000..a2fd6e8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header.gif new file mode 100755 index 0000000..18d137c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-header.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-sidebar-header.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-sidebar-header.gif new file mode 100755 index 0000000..534b452 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/layout-sidebar-header.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-bottom.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-bottom.gif new file mode 100755 index 0000000..acecfe7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-bottom.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-left.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-left.gif new file mode 100755 index 0000000..ef2675e Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-left.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-right.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-right.gif new file mode 100755 index 0000000..6274ea5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-right.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-top.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-top.gif new file mode 100755 index 0000000..0f673ec Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/mini-top.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-content.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-content.gif new file mode 100755 index 0000000..1aa83dc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-content.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header-over.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header-over.gif new file mode 100755 index 0000000..cc841b1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header-over.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header.gif new file mode 100755 index 0000000..a9b586f Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header2.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header2.gif new file mode 100755 index 0000000..07605b8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/panel-header2.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-bg.gif new file mode 100755 index 0000000..b42ba47 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-bg.gif new file mode 100755 index 0000000..f2c2c42 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-left-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-left-bg.gif new file mode 100755 index 0000000..848e41e Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-left-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-over-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-over-bg.gif new file mode 100755 index 0000000..1cd2696 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-over-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-right-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-right-bg.gif new file mode 100755 index 0000000..b707692 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-item-right-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-tools.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-tools.gif new file mode 100755 index 0000000..6c366bb Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/tabs-tools.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/togglebar.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/togglebar.gif new file mode 100755 index 0000000..0fc297c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/layout/togglebar.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-arrow.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-arrow.gif new file mode 100755 index 0000000..6876f6c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-arrow.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-down.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-down.gif new file mode 100755 index 0000000..6f298de Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-down.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-l.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-l.gif new file mode 100755 index 0000000..e05de19 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-l.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-m.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-m.gif new file mode 100755 index 0000000..6d1d1a0 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-m.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-r.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-r.gif new file mode 100755 index 0000000..93da6e1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-item-over-r.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-x.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-x.gif new file mode 100755 index 0000000..3ff3d27 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-x.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-y.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-y.gif new file mode 100755 index 0000000..8a9bd09 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/menu/menu-line-y.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/bar-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/bar-bg.gif new file mode 100755 index 0000000..e5598b6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/bar-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.gif new file mode 100755 index 0000000..cd9b70d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.jpg b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.jpg new file mode 100755 index 0000000..2078e5b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header-bg.jpg differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header2-bg.jpg b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header2-bg.jpg new file mode 100755 index 0000000..74009fd Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/header2-bg.jpg differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-l.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-l.gif new file mode 100755 index 0000000..1bb83d8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-l.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-r.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-r.gif new file mode 100755 index 0000000..f485e42 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn-r.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn.gif new file mode 100755 index 0000000..e02e3e4 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-btn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-header.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-header.gif new file mode 100755 index 0000000..55d5db5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-header.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu-item-down.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu-item-down.gif new file mode 100755 index 0000000..6f298de Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu-item-down.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu.gif new file mode 100755 index 0000000..e36cc7b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-menu.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-toolbar.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-toolbar.gif new file mode 100755 index 0000000..551731a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-toolbar.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-tools.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-tools.gif new file mode 100755 index 0000000..b46081b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/panel/panel-tools.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder-open.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder-open.gif new file mode 100755 index 0000000..9a112a0 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder-open.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder.gif new file mode 100755 index 0000000..b37e076 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/folder.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/loading.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/loading.gif new file mode 100755 index 0000000..1d46b9b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/loading.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading.gif new file mode 100755 index 0000000..10f52c7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading2.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading2.gif new file mode 100755 index 0000000..aeee11d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading2.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading3.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading3.gif new file mode 100755 index 0000000..8c848c3 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading3.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading4.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading4.gif new file mode 100755 index 0000000..f9c00ba Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/nodeloading4.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-leaf.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-leaf.gif new file mode 100755 index 0000000..9e4f2a6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-leaf.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-level.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-level.gif new file mode 100755 index 0000000..9e4f2a6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-level.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-noline.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-noline.gif new file mode 100755 index 0000000..7cd6780 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-noline.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-close.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-close.gif new file mode 100755 index 0000000..01ef0a9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-close.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-open.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-open.gif new file mode 100755 index 0000000..a959cd9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status-open.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status.gif new file mode 100755 index 0000000..dde337a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree-status.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree.gif new file mode 100755 index 0000000..b50dcb7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/tree/tree.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_55_fbf9ee_1x400.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100755 index 0000000..ad3d634 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_65_ffffff_1x400.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_65_ffffff_1x400.png new file mode 100755 index 0000000..42ccba2 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_dadada_1x400.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_dadada_1x400.png new file mode 100755 index 0000000..5a46b47 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_dadada_1x400.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_e6e6e6_1x400.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100755 index 0000000..86c2baa Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_95_fef1ec_1x400.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_95_fef1ec_1x400.png new file mode 100755 index 0000000..4443fdc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_highlight-soft_75_cccccc_1x100.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100755 index 0000000..7c9fa6c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/ui/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box-icons.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box-icons.gif new file mode 100755 index 0000000..52270fe Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box-icons.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box.gif new file mode 100755 index 0000000..bf66df9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/box.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-bc.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-bc.gif new file mode 100755 index 0000000..7e10f05 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-bc.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-icons.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-icons.gif new file mode 100755 index 0000000..dedb393 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-icons.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-tc.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-tc.gif new file mode 100755 index 0000000..a5f556c Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-tc.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-winbtns.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-winbtns.gif new file mode 100755 index 0000000..e086810 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog-winbtns.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog.gif new file mode 100755 index 0000000..324f6ad Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialog.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialogbtn.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialogbtn.gif new file mode 100755 index 0000000..3ccff45 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/dialogbtn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar-task.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar-task.gif new file mode 100755 index 0000000..fea09b2 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar-task.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.gif new file mode 100755 index 0000000..cc9d96a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.png b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.png new file mode 100755 index 0000000..fbc78e6 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskbar.png differ diff --git a/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskicon.gif b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskicon.gif new file mode 100755 index 0000000..6bf1462 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/Aqua/images/win/taskicon.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/add.gif b/hyhproject/admin/view/js/ligerui/skins/icons/add.gif new file mode 100755 index 0000000..6332fef Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/add.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/archives.gif b/hyhproject/admin/view/js/ligerui/skins/icons/archives.gif new file mode 100755 index 0000000..9ca6ddb Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/archives.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/attibutes.gif b/hyhproject/admin/view/js/ligerui/skins/icons/attibutes.gif new file mode 100755 index 0000000..2eb4e98 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/attibutes.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/back.gif b/hyhproject/admin/view/js/ligerui/skins/icons/back.gif new file mode 100755 index 0000000..6117efd Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/back.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/bluebook.gif b/hyhproject/admin/view/js/ligerui/skins/icons/bluebook.gif new file mode 100755 index 0000000..e562697 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/bluebook.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/bookpen.gif b/hyhproject/admin/view/js/ligerui/skins/icons/bookpen.gif new file mode 100755 index 0000000..a4529b4 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/bookpen.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/busy.gif b/hyhproject/admin/view/js/ligerui/skins/icons/busy.gif new file mode 100755 index 0000000..4dc2f42 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/busy.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/calendar.gif b/hyhproject/admin/view/js/ligerui/skins/icons/calendar.gif new file mode 100755 index 0000000..8a057cf Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/calendar.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/candle.gif b/hyhproject/admin/view/js/ligerui/skins/icons/candle.gif new file mode 100755 index 0000000..9c4badc Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/candle.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/coffee.gif b/hyhproject/admin/view/js/ligerui/skins/icons/coffee.gif new file mode 100755 index 0000000..9ddd530 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/coffee.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/comment.gif b/hyhproject/admin/view/js/ligerui/skins/icons/comment.gif new file mode 100755 index 0000000..d1f6c46 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/comment.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/communication.gif b/hyhproject/admin/view/js/ligerui/skins/icons/communication.gif new file mode 100755 index 0000000..902fa71 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/communication.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/config.gif b/hyhproject/admin/view/js/ligerui/skins/icons/config.gif new file mode 100755 index 0000000..d669df1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/config.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/customers.gif b/hyhproject/admin/view/js/ligerui/skins/icons/customers.gif new file mode 100755 index 0000000..cb23c40 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/customers.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/cut.gif b/hyhproject/admin/view/js/ligerui/skins/icons/cut.gif new file mode 100755 index 0000000..abe68ae Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/cut.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/database.gif b/hyhproject/admin/view/js/ligerui/skins/icons/database.gif new file mode 100755 index 0000000..0516c86 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/database.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/delete.gif b/hyhproject/admin/view/js/ligerui/skins/icons/delete.gif new file mode 100755 index 0000000..08f2493 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/delete.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/discuss.gif b/hyhproject/admin/view/js/ligerui/skins/icons/discuss.gif new file mode 100755 index 0000000..8a7c5c1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/discuss.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/down.gif b/hyhproject/admin/view/js/ligerui/skins/icons/down.gif new file mode 100755 index 0000000..c9088c8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/down.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/edit.gif b/hyhproject/admin/view/js/ligerui/skins/icons/edit.gif new file mode 100755 index 0000000..fc761ed Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/edit.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/graywarn.gif b/hyhproject/admin/view/js/ligerui/skins/icons/graywarn.gif new file mode 100755 index 0000000..1f6ea7b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/graywarn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/greenwarn.gif b/hyhproject/admin/view/js/ligerui/skins/icons/greenwarn.gif new file mode 100755 index 0000000..364cbd1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/greenwarn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/help.gif b/hyhproject/admin/view/js/ligerui/skins/icons/help.gif new file mode 100755 index 0000000..1c31539 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/help.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/home.gif b/hyhproject/admin/view/js/ligerui/skins/icons/home.gif new file mode 100755 index 0000000..26cee92 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/home.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/lock.gif b/hyhproject/admin/view/js/ligerui/skins/icons/lock.gif new file mode 100755 index 0000000..956f5f3 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/lock.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/logout.gif b/hyhproject/admin/view/js/ligerui/skins/icons/logout.gif new file mode 100755 index 0000000..46af928 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/logout.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/mailbox.gif b/hyhproject/admin/view/js/ligerui/skins/icons/mailbox.gif new file mode 100755 index 0000000..c6b7f6f Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/mailbox.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/memeber.gif b/hyhproject/admin/view/js/ligerui/skins/icons/memeber.gif new file mode 100755 index 0000000..fd0c5c9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/memeber.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/modify.gif b/hyhproject/admin/view/js/ligerui/skins/icons/modify.gif new file mode 100755 index 0000000..fc761ed Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/modify.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/msn.gif b/hyhproject/admin/view/js/ligerui/skins/icons/msn.gif new file mode 100755 index 0000000..bebfdf8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/msn.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/myaccount.gif b/hyhproject/admin/view/js/ligerui/skins/icons/myaccount.gif new file mode 100755 index 0000000..dcd5ea8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/myaccount.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/ok.gif b/hyhproject/admin/view/js/ligerui/skins/icons/ok.gif new file mode 100755 index 0000000..315a5e0 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/ok.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/outbox.gif b/hyhproject/admin/view/js/ligerui/skins/icons/outbox.gif new file mode 100755 index 0000000..063b493 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/outbox.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/pager.gif b/hyhproject/admin/view/js/ligerui/skins/icons/pager.gif new file mode 100755 index 0000000..3bbfbec Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/pager.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/photograph.gif b/hyhproject/admin/view/js/ligerui/skins/icons/photograph.gif new file mode 100755 index 0000000..61abcc1 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/photograph.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/plus.gif b/hyhproject/admin/view/js/ligerui/skins/icons/plus.gif new file mode 100755 index 0000000..09c29d8 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/plus.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/prev.gif b/hyhproject/admin/view/js/ligerui/skins/icons/prev.gif new file mode 100755 index 0000000..820cc7d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/prev.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/print.gif b/hyhproject/admin/view/js/ligerui/skins/icons/print.gif new file mode 100755 index 0000000..86e7526 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/print.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/process.gif b/hyhproject/admin/view/js/ligerui/skins/icons/process.gif new file mode 100755 index 0000000..104c6a7 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/process.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/qq.gif b/hyhproject/admin/view/js/ligerui/skins/icons/qq.gif new file mode 100755 index 0000000..26b5040 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/qq.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/refresh.gif b/hyhproject/admin/view/js/ligerui/skins/icons/refresh.gif new file mode 100755 index 0000000..4378c9a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/refresh.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/right.gif b/hyhproject/admin/view/js/ligerui/skins/icons/right.gif new file mode 100755 index 0000000..50eafb5 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/right.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/role.gif b/hyhproject/admin/view/js/ligerui/skins/icons/role.gif new file mode 100755 index 0000000..4d61c40 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/role.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/save-disabled.gif b/hyhproject/admin/view/js/ligerui/skins/icons/save-disabled.gif new file mode 100755 index 0000000..25e8837 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/save-disabled.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/save.gif b/hyhproject/admin/view/js/ligerui/skins/icons/save.gif new file mode 100755 index 0000000..22a0750 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/save.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/search.gif b/hyhproject/admin/view/js/ligerui/skins/icons/search.gif new file mode 100755 index 0000000..34e039a Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/search.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/search2.gif b/hyhproject/admin/view/js/ligerui/skins/icons/search2.gif new file mode 100755 index 0000000..2a67f97 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/search2.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/settings.gif b/hyhproject/admin/view/js/ligerui/skins/icons/settings.gif new file mode 100755 index 0000000..a41667d Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/settings.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/true.gif b/hyhproject/admin/view/js/ligerui/skins/icons/true.gif new file mode 100755 index 0000000..a9c2904 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/true.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/up.gif b/hyhproject/admin/view/js/ligerui/skins/icons/up.gif new file mode 100755 index 0000000..64706a9 Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/up.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/icons/view.gif b/hyhproject/admin/view/js/ligerui/skins/icons/view.gif new file mode 100755 index 0000000..aba044b Binary files /dev/null and b/hyhproject/admin/view/js/ligerui/skins/icons/view.gif differ diff --git a/hyhproject/admin/view/js/ligerui/skins/ligerui-icons.css b/hyhproject/admin/view/js/ligerui/skins/ligerui-icons.css new file mode 100755 index 0000000..b9351d2 --- /dev/null +++ b/hyhproject/admin/view/js/ligerui/skins/ligerui-icons.css @@ -0,0 +1,52 @@ +.l-icon{ width:16px; height:16px; overflow:hidden;} +.l-icon-add{ background:url('icons/add.gif') no-repeat center;} +.l-icon-edit{ background:url('icons/edit.gif') no-repeat center;} +.l-icon-view{ background:url('icons/view.gif') no-repeat center;} +.l-icon-delete{ background:url('icons/delete.gif') no-repeat center;} +.l-icon-back{ background:url('icons/back.gif') no-repeat center;} +.l-icon-bluebook{ background:url('icons/bluebook.gif') no-repeat center;} +.l-icon-bookpen{ background:url('icons/bookpen.gif') no-repeat center;} +.l-icon-coffee{ background:url('icons/coffee.gif') no-repeat center;} +.l-icon-cut{ background:url('icons/cut.gif') no-repeat center;} +.l-icon-discuss{ background:url('icons/discuss.gif') no-repeat center;} +.l-icon-graywarn{ background:url('icons/graywarn.gif') no-repeat center;} +.l-icon-greenwarn{ background:url('icons/greenwarn.gif') no-repeat center;} +.l-icon-help{ background:url('icons/help.gif') no-repeat center;} +.l-icon-home{ background:url('icons/home.gif') no-repeat center;} +.l-icon-lock{ background:url('icons/lock.gif') no-repeat center;} +.l-icon-logout{ background:url('icons/logout.gif') no-repeat center;} +.l-icon-mailbox{ background:url('icons/mailbox.gif') no-repeat center;} +.l-icon-memeber{ background:url('icons/memeber.gif') no-repeat center;} +.l-icon-modify{ background:url('icons/modify.gif') no-repeat center;} +.l-icon-msn{ background:url('icons/msn.gif') no-repeat center;} +.l-icon-ok{ background:url('icons/ok.gif') no-repeat center;} +.l-icon-outbox{ background:url('icons/outbox.gif') no-repeat center;} +.l-icon-pager{ background:url('icons/pager.gif') no-repeat center;} +.l-icon-photograph{ background:url('icons/photograph.gif') no-repeat center;} +.l-icon-prev{ background:url('icons/prev.gif') no-repeat center;} +.l-icon-print{ background:url('icons/print.gif') no-repeat center;} +.l-icon-qq{ background:url('icons/qq.gif') no-repeat center;} +.l-icon-refresh{ background:url('icons/refresh.gif') no-repeat center;} +.l-icon-right{ background:url('icons/right.gif') no-repeat center;} +.l-icon-save-disabled{ background:url('icons/save-disabled.gif') no-repeat center;} +.l-icon-save{ background:url('icons/save.gif') no-repeat center;} +.l-icon-search{ background:url('icons/search.gif') no-repeat center;} +.l-icon-search2{ background:url('icons/search2.gif') no-repeat center;} +.l-icon-settings{ background:url('icons/settings.gif') no-repeat center;} +.l-icon-TRUE{ background:url('icons/TRUE.gif') no-repeat center;} +.l-icon-up{ background:url('icons/up.gif') no-repeat center;} +.l-icon-down{ background:url('icons/down.gif') no-repeat center;} +.l-icon-role{ background:url('icons/role.gif') no-repeat center;} +.l-icon-config{ background:url('icons/config.gif') no-repeat center;} +.l-icon-address{ background:url('icons/address.gif') no-repeat center;} +.l-icon-process{ background:url('icons/process.gif') no-repeat center;} +.l-icon-archives{ background:url('icons/archives.gif') no-repeat center;} +.l-icon-attibutes{ background:url('icons/attibutes.gif') no-repeat center;} +.l-icon-busy{ background:url('icons/busy.gif') no-repeat center;} +.l-icon-calendar{ background:url('icons/calendar.gif') no-repeat center;} +.l-icon-comment{ background:url('icons/comment.gif') no-repeat center;} +.l-icon-plus{ background:url('icons/plus.gif') no-repeat center;} +.l-icon-communication{ background:url('icons/communication.gif') no-repeat center;} +.l-icon-customers{ background:url('icons/customers.gif') no-repeat center;} +.l-icon-database{ background:url('icons/database.gif') no-repeat center;} +.l-icon-myaccount{ background:url('icons/myaccount.gif') no-repeat center;} diff --git a/hyhproject/admin/view/js/login.js b/hyhproject/admin/view/js/login.js new file mode 100755 index 0000000..e0c497a --- /dev/null +++ b/hyhproject/admin/view/js/login.js @@ -0,0 +1,39 @@ +function login(){ + var public_key=$('#token').val(); + var exponent="10001"; + var res = ''; + if(WST.conf.IS_CRYPT=='1'){ + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var res = rsa.encrypt($.trim($('#loginPwd').val())); + }else{ + res = $.trim($('#loginPwd').val()); + } + var loading = WST.msg('加载中', {icon: 16,time:60000,offset: '200px'}); + var params = WST.getParams('.ipt'); + params.loginPwd = res; + $.post(WST.U('admin/index/checkLogin'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("登录成功",{icon:1,offset: '200px'},function(){ + if(parent){ + parent.location.href=WST.U('admin/index/index');; + }else{ + location.href=WST.U('admin/index/index'); + } + }); + }else{ + getVerify('#verifyImg'); + WST.msg(json.msg,{icon:2,offset: '200px'}); + } + }); +} +var getVerify = function(img){ + $(img).attr('src',WST.U('admin/index/getVerify','rnd='+Math.random())); +} +$(document).keypress(function(e) { + if(e.which == 13) { + login(); + } +}); diff --git a/hyhproject/admin/view/js/main.js b/hyhproject/admin/view/js/main.js new file mode 100755 index 0000000..3121c4a --- /dev/null +++ b/hyhproject/admin/view/js/main.js @@ -0,0 +1,134 @@ +var myChart; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + loadStat(); + loadStat1(); + getLastVersion(); +}) +function getLastVersion(){ + $.post(WST.U('admin/index/getVersion'),{},function(data,textStatus){ + var json = {}; + try{ + if(typeof(data )=="object"){ + json = data; + }else{ + json = eval("("+data+")"); + } + }catch(e){} + if(json){ + if(json.version && json.version!='same'){ + $('#wstmart-version-tips').show(); + $('#wstmart_version').html(json.version); + $('#wstmart_down').attr('href',json.downloadUrl); + } + if(json.accredit=='no'){ + $('#wstmart-accredit-tips').show(); + } + if(json.licenseStatus)$('#licenseStatus').html(json.licenseStatus); + } + }); +} +function loadStat(){ + $.post(WST.U('admin/reports/getNewUser'),WST.getParams('.ipt'),function(data,textStatus){ + var json = WST.toAdminJson(data); + myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + if(json.status=='1'){ + var option = { + tooltip: { + trigger: 'axis' + }, + legend: { + data:['新增会员'] + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: json.data.days + }, + yAxis: { + type: 'value' + }, + series: [ + { + name:'新增会员', + type:'line', + data:json.data.u0 + } + ] + }; + + myChart.setOption(option); + window.onresize = myChart.resize + } + }); +} +function loadStat1(){ + $.post(WST.U('admin/reports/getOrders'),WST.getParams('.ipt'),function(data,textStatus){ + var json = WST.toAdminJson(data); + var myChart1 = echarts.init(document.getElementById('main1')); + myChart1.clear(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + y: 'top', + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + legend: { + data:['总订单'] + }, + xAxis : [ + { + type : 'category', + splitLine : {show : false}, + data : json.data.days + } + ], + yAxis : [ + { + type : 'value', + position: 'right' + } + ], + series : [ + { + name:'总订单', + type:'line', + data:json.data['total'] + } + ] + }; + myChart1.setOption(option); + window.onresize = myChart1.resize + }else{ + } + + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/js/mmgrid/img/arrow_down.png b/hyhproject/admin/view/js/mmgrid/img/arrow_down.png new file mode 100755 index 0000000..69f7ff0 Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/arrow_down.png differ diff --git a/hyhproject/admin/view/js/mmgrid/img/arrow_up.png b/hyhproject/admin/view/js/mmgrid/img/arrow_up.png new file mode 100755 index 0000000..293c29f Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/arrow_up.png differ diff --git a/hyhproject/admin/view/js/mmgrid/img/furley_bg.png b/hyhproject/admin/view/js/mmgrid/img/furley_bg.png new file mode 100755 index 0000000..a5e603e Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/furley_bg.png differ diff --git a/hyhproject/admin/view/js/mmgrid/img/furley_bg_@2X.png b/hyhproject/admin/view/js/mmgrid/img/furley_bg_@2X.png new file mode 100755 index 0000000..c430d20 Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/furley_bg_@2X.png differ diff --git a/hyhproject/admin/view/js/mmgrid/img/loading.gif b/hyhproject/admin/view/js/mmgrid/img/loading.gif new file mode 100755 index 0000000..b4802a5 Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/loading.gif differ diff --git a/hyhproject/admin/view/js/mmgrid/img/sort-asc.png b/hyhproject/admin/view/js/mmgrid/img/sort-asc.png new file mode 100755 index 0000000..ddbf62b Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/sort-asc.png differ diff --git a/hyhproject/admin/view/js/mmgrid/img/sort-desc.png b/hyhproject/admin/view/js/mmgrid/img/sort-desc.png new file mode 100755 index 0000000..6756f5c Binary files /dev/null and b/hyhproject/admin/view/js/mmgrid/img/sort-desc.png differ diff --git a/hyhproject/admin/view/js/mmgrid/mmGrid-all.js b/hyhproject/admin/view/js/mmgrid/mmGrid-all.js new file mode 100755 index 0000000..5299725 --- /dev/null +++ b/hyhproject/admin/view/js/mmgrid/mmGrid-all.js @@ -0,0 +1,1611 @@ +/** + * Author: meimeidev + */ + +!function($){ + var MMGrid = function (element, options) { + this._id = (((1 + Math.random()) * 0x10000) | 0).toString(16); + this._loadCount = 0; + this.opts = options; + this._initLayout($(element)); + this._initHead(); + this._initOptions(); + this._initEvents(); + this._setColsWidth(); + if(this.opts.fullWidthRows){ + this._fullWidthRows(); + } + + //初始化插件 + for(var i=0; i< this.opts.plugins.length; i++){ + var plugin = this.opts.plugins[i]; + plugin.init($.extend(element, this)); + } + + if(options.autoLoad){ + var that = this; + this.opts = options; + setTimeout(function(){ + + if(options.url){ + that.load(); + }else{ + that.load(options.items); + } + },0); //chrome style problem + } + + }; + + //see: http://tanalin.com/en/articles/ie-version-js/ + var browser = function(){ + var isIE=!!window.ActiveXObject; + var isIE10 = isIE && !!window.atob; + var isIE9 = isIE && document.addEventListener && !window.atob; + var isIE8 = isIE && document.querySelector && !document.addEventListener; + var isIE7 = isIE && window.XMLHttpRequest && !document.querySelector; + var isIE6 = isIE && !window.XMLHttpRequest; + + return { + isIE: isIE + , isIE6: isIE6 + , isIE7: isIE7 + , isIE8: isIE8 + , isIE9: isIE9 + , isIE10: isIE10 + }; + }(); + + MMGrid.prototype = { + + _initLayout: function($el){ + var opts = this.opts; + var $elParent = $el.parent(); + var elIndex = $el.index(); + + var mmGrid = [ + '<div class="mmGrid">', + '<style></style>', + '<div class="mmg-headWrapper">', + '<table class="mmg-head" cellspacing="0"></table>', + '</div>', + '<div class="mmg-colResizePointer"></div>', + '<div class="mmg-colResizePointer-before"></div>', + '<div class="mmg-backboard">', + '<a class="mmg-btnBackboardUp"></a>', + '</div>', + '<div class="mmg-bodyWrapper"></div>', + '<a class="mmg-btnBackboardDn"></a>', + '<div class="mmg-message">'+ this.opts.noDataText +'</div>', + '<div class="mmg-mask mmg-transparent"></div>', + '<div class="mmg-loading">', + '<div class="mmg-loadingImg"></div>', + '<div class="mmg-loadingText">'+ this.opts.loadingText +'</div>', + '</div>', + + '</div>' + ]; + //fix in IE7,IE6 + if(browser.isIE7 || browser.isIE6){ + $el.prop('cellspacing',0); + } + + + //cached object + var $mmGrid = $(mmGrid.join('')); + this.$mmGrid = $mmGrid; + this.$style = $mmGrid.find('style'); + this.$headWrapper = $mmGrid.find('.mmg-headWrapper'); + this.$head = $mmGrid.find('.mmg-head'); + this.$backboard = $mmGrid.find('.mmg-backboard'); + this.$bodyWrapper = $mmGrid.find('.mmg-bodyWrapper'); + this.$body = $el.removeAttr("style").addClass('mmg-body'); + this._insertEmptyRow(); + this.$body.appendTo(this.$bodyWrapper); + + + + //放回原位置 + if(elIndex === 0 || $elParent.children().length == 0){ + $elParent.prepend(this.$mmGrid); + }else{ + $elParent.children().eq(elIndex-1).after(this.$mmGrid); + } + + + // fix in ie6 + if(browser.isIE6 && (!opts.width || opts.width === 'auto')){ + $mmGrid.width('100%'); + $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width())); + }else{ + $mmGrid.width(opts.width); + } + + if(browser.isIE6 && (!opts.height || opts.height === 'auto')){ + $mmGrid.height('100%'); + $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height())); + }else{ + $mmGrid.height(opts.height); + } + + if(opts.checkCol){ + var chkHtml = opts.multiSelect ? '<input type="checkbox" class="checkAll" >' + : '<input type="checkbox" disabled="disabled" class="checkAll">'; + opts.cols.unshift({title:chkHtml,width: 20, align: 'center' ,lockWidth: true, checkCol: true, renderer:function(){ + return '<input type="checkbox" class="mmg-check">'; + }}); + } + + if(opts.indexCol){ + opts.cols.unshift({title:'#',width: opts.indexColWidth, align: 'center' ,lockWidth: true, indexCol:true, renderer:function(val,item,rowIndex){ + return '<label class="mmg-index">' + (rowIndex+1) + '</label>'; + }}); + } + + } + + ,_expandCols: function(cols){ + var newCols = []; + if(!cols){ + return newCols; + } + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(col.cols){ + newCols.push(col); + newCols.push.apply(newCols,this._expandCols(col.cols)); + }else{ + newCols.push(col); + } + } + return newCols; + } + ,_leafCols: function(){ + var opts = this.opts; + var newCols = []; + var cols = this._expandCols(opts.cols); + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(!col.cols){ + newCols.push(col); + } + } + return newCols; + } + + ,_expandThs: function(){ + return this.$head.find('th').sort(function(a, b){ + return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex')); + }); + } + + ,_leafThs: function(){ + return this.$head.find('th').filter(function(){ + return !$.data(this,'col').cols; + }).sort(function(a, b){ + return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex')); + }); + } + + + ,_colsWithTitleDeep: function(cols,deep){ + var newCols = []; + if(!cols){ + return newCols; + } + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(deep === 1){ + newCols.push(col); + }else{ + newCols.push.apply(newCols, this._colsWithTitleDeep(col.cols, deep-1)); + } + } + return newCols; + } + + ,_titleDeep: function(cols){ + var deep = 1; + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(col.cols){ + var newDeep = 1 + this._titleDeep(col.cols); + if(deep < newDeep){ + deep = newDeep; + } + } + } + return deep; + } + + , _titleHtml: function(col, rowspan){ + var opts = this.opts; + + var titleHtml = []; + if(!col.cols){ + titleHtml.push('<th class="'); + var colIndex = $.inArray(col, this._expandCols(opts.cols)); + titleHtml.push(this._genColClass(colIndex)); + titleHtml.push(' " '); + titleHtml.push(' rowspan="'); + titleHtml.push(rowspan); + titleHtml.push('" colspan="'); + titleHtml.push(1); + titleHtml.push('" data-colIndex="'); + titleHtml.push(colIndex); + titleHtml.push('" >'); + titleHtml.push('<div class="mmg-titleWrapper" >'); + titleHtml.push('<span class="mmg-title '); + if(col.sortable) titleHtml.push('mmg-canSort '); + titleHtml.push('">'); + if(col.titleHtml){ + titleHtml.push(col.titleHtml); + }else{ + titleHtml.push(col.title); + } + titleHtml.push('</span><div class="mmg-sort"></div>'); + if(!col.lockWidth) titleHtml.push('<div class="mmg-colResize"></div>'); + titleHtml.push('</div></th>'); + }else{ + var displayColsLength = col.cols.length; + $.each(col.cols, function(index, item){ + if(item.hidden){ + displayColsLength--; + } + }); + if(displayColsLength === 0){ + col.hidden = true; + } + titleHtml.push('<th class="'); + var colIndex = $.inArray(col, this._expandCols(opts.cols)); + titleHtml.push(this._genColClass(colIndex)); + titleHtml.push(' mmg-groupCol" '); + titleHtml.push(' rowspan="'); + titleHtml.push(rowspan-1); + titleHtml.push('" colspan="'); + titleHtml.push(displayColsLength); + titleHtml.push('" data-colIndex="'); + titleHtml.push(colIndex); + titleHtml.push('" >'); + titleHtml.push('<div class="mmg-titleWrapper" >'); + titleHtml.push('<span class="mmg-title '); + if(col.sortable) titleHtml.push('mmg-canSort '); + titleHtml.push('">'); + if(col.titleHtml){ + titleHtml.push(col.titleHtml); + }else{ + titleHtml.push(col.title); + } + titleHtml.push('</span><div class="mmg-sort"></div>'); + titleHtml.push('</div></th>'); + } + + return titleHtml.join(""); + } + + , _initHead: function(){ + var that = this; + var opts = this.opts; + var $head = this.$head; + + if(opts.cols){ + var theadHtmls = ['<thead>']; + + //获取标题深度 + var titleDeep = that._titleDeep(opts.cols); + for(var deep=1; deep<= titleDeep; deep++){ + var cols = that._colsWithTitleDeep(opts.cols, deep); + theadHtmls.push('<tr>'); + for(var colIndex=0; colIndex< cols.length; colIndex++){ + var col = cols[colIndex]; + theadHtmls.push(this._titleHtml(col, titleDeep-deep+1)); + } + theadHtmls.push('</tr>'); + } + theadHtmls.push('</thead>'); + $head.html(theadHtmls.join('')); + } + + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + $.each($ths,function(index){ + if(!expandCols[index].width){ + expandCols[index].width = 100; + } + $.data(this,'col-width',expandCols[index].width); + $.data(this,'col',expandCols[index]); + }); + + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $bodyWrapper = this.$bodyWrapper; + if(opts.height !== 'auto'){ + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + + + + //初始化排序状态 + if(opts.sortName){ + for(var colIndex=0; colIndex< expandCols.length; colIndex++){ + var col = expandCols[colIndex]; + if(col.sortName === opts.sortName || col.name === opts.sortName){ + var $th= $ths.eq(colIndex); + $.data($th.find('.mmg-title')[0],'sortStatus',opts.sortStatus); + $th.find('.mmg-sort').addClass('mmg-'+opts.sortStatus); + } + } + } + } + + , _initOptions: function(){ + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $backboard = this.$backboard; + $mmGrid.find('a.mmg-btnBackboardDn').css({ + 'top': $headWrapper.outerHeight(true) + }).slideUp('fast'); + + var cols = this._leafCols(); + if(cols){ + var bbHtml = ['<h1>显示列</h1>']; + for(var colIndex=0; colIndex<cols.length; colIndex++){ + bbHtml.push('<label '); + if(cols[colIndex].checkCol || cols[colIndex].indexCol){ + bbHtml.push('style="display:none;" '); + } + var col = cols[colIndex]; + bbHtml.push('><input type="checkbox" '); + if(!col.hidden) bbHtml.push('checked="checked"'); + if(col.lockDisplay) bbHtml.push(' disabled="disabled"'); + bbHtml.push('/><span>'); + if(col.title){ + bbHtml.push(col.title); + }else{ + bbHtml.push('未命名'); + } + + bbHtml.push('</span></label>'); + } + $backboard.append($(bbHtml.join(''))); + } + } + + , _initEvents: function(){ + var that = this; + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $head = this.$head; + var $bodyWrapper = this.$bodyWrapper; + var $body = this.$body; + var $backboard = this.$backboard; + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + var leafCols = this._leafCols(); + + //调整浏览器 + if(opts.width === 'auto' || opts.height === 'auto' || (typeof opts.width === 'string' && opts.width.indexOf('%') === opts.width.length-1) || + typeof opts.height === 'string' && opts.height.indexOf('%') === opts.height.length-1){ + $(window).on('resize', function(){ + that.resize(); + }); + } + + //滚动条事件 + $bodyWrapper.on('scroll', function(){ + $head.css('left',- $(this).scrollLeft()); + }); + + //向下按钮 + var $btnBackboardDn = $mmGrid.find('a.mmg-btnBackboardDn').on('click', function(){ + var backboardHeight = $mmGrid.height() - $headWrapper.outerHeight(true); + if(opts.height === 'auto'&& opts.backboardMinHeight !== 'auto' && backboardHeight < opts.backboardMinHeight){ + backboardHeight = opts.backboardMinHeight; + } + $backboard.height(backboardHeight); + if(opts.height === 'auto'){ + $mmGrid.height($headWrapper.outerHeight(true) + $backboard.outerHeight(true)); + } + $backboard.slideDown(); + $btnBackboardDn.slideUp('fast'); + + that._hideMessage(); + }); + $body.on('mouseenter', function(){ + $btnBackboardDn.slideUp('fast'); + }); + $mmGrid.on('mouseleave', function(){ + $btnBackboardDn.slideUp('fast'); + }); + $headWrapper.on('mouseenter',function(){ + if($backboard.is(':hidden') && opts.showBackboard){ + $btnBackboardDn.slideDown('fast'); + } + }); + //向上按钮 + $mmGrid.find('a.mmg-btnBackboardUp').on('click', function(){ + $backboard.slideUp().queue(function(next){ + if(!that.rowsLength() || (that.rowsLength() === 1 && $body.find('tr.emptyRow').length === 1)){ + that._showNoData(); + } + if(opts.height === 'auto'){ + $mmGrid.height('auto'); + } + next(); + }); + }); + + //隐藏列 + $backboard.on('click', ':checkbox', function(){ + var index = $backboard.find('label').index($(this).parent()); + //最后一个不隐藏 + var last = 1; + if(opts.checkCol){ + last = last + 1; + } + if(opts.indexCol){ + last = last + 1; + } + if($backboard.find('label :checked').length < last){ + this.checked = true; + return; + } + + var col = leafCols[index]; + if(this.checked){ + col.hidden = false; + + }else{ + col.hidden = true; + } + + var $ths = $head.find('th'); + for(var colIndex=$ths.length-1; colIndex>=0; colIndex--){ + var $th = $ths.eq(colIndex); + var iCol = $th.data('col'); + if(iCol.cols){ + var hidden = true; + var colspan = 0; + $.each(iCol.cols,function(index,item){ + if(!item.hidden){ + hidden = false; + colspan++; + } + }); + //IE bug + if(colspan !== 0){ + $th.prop('colspan',colspan); + } + iCol.hidden = hidden; + } + } + + that._setColsWidth(); + $backboard.height($mmGrid.height() - $headWrapper.outerHeight(true)); + if(opts.height !== 'auto'){ + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + $mmGrid.find('a.mmg-btnBackboardDn').css({ + 'top': $headWrapper.outerHeight(true) + }) + }); + + + + //排序事件 + $head.on('click', '.mmg-title', function(){ + var $this = $(this); + var $titles = $ths.find('.mmg-title'); + + //当前列不允许排序 + var col =$this.parent().parent().data('col'); + if(!col.sortable){ + return; + } + //取得当前列下一个排序状态 + var sortStatus = $.data(this, 'sortStatus') === 'asc' ? 'desc' : 'asc'; + //清除排序状态 + $.each($titles, function(){ + $.removeData(this,'sortStatus'); + }); + $ths.find('.mmg-sort').removeClass('mmg-asc').removeClass('mmg-desc'); + //设置当前列排序状态 + $.data(this, 'sortStatus', sortStatus); + $this.siblings('.mmg-sort').addClass('mmg-'+sortStatus); + + if(opts.url && opts.remoteSort){ + that.load() + }else{ + that._nativeSorter($.inArray(col, leafCols), sortStatus); + that._setStyle(); + } + }).on('mousedown', '.mmg-colResize', function(e){ + //调整列宽 + var $resize = $(this); + var start = e.pageX; + var $colResizePointer = $mmGrid.find('.mmg-colResizePointer') + .css('left', e.pageX - $headWrapper.offset().left).show(); + + var scrollLeft = $head.position().left; + var $colResizePointerBefore = $mmGrid.find('.mmg-colResizePointer-before') + .css('left', $resize.parent().parent().position().left + scrollLeft).show(); + //取消文字选择 + document.selection && document.selection.empty && ( document.selection.empty(), 1) + || window.getSelection && window.getSelection().removeAllRanges(); + document.body.onselectstart = function () { + return false; + }; + $headWrapper.css('-moz-user-select','none'); + + $mmGrid.on('mousemove', function(e){ + $colResizePointer.css('left', e.pageX - $headWrapper.offset().left); + }).on('mouseup', function(e){ + //改变宽度 + var $th = $resize.parent().parent(); + var width = $th.width() + e.pageX - start; + $.data($th[0], 'col-width', width); + that._setColsWidth(); + $headWrapper.mouseleave(); + }).on('mouseleave',function(){ + $mmGrid.off('mouseup').off('mouseleave').off('mousemove'); + $colResizePointer.hide(); + $colResizePointerBefore.hide(); + document.body.onselectstart = function(){ + return true;//开启文字选择 + }; + $headWrapper.css('-moz-user-select','text'); + }); + }); + + //选中事件 + var $body = this.$body; + $body.on('click','td',function(e){ + var $this = $(this); + var event = jQuery.Event("cellSelected"); + event.target = e.target; + that.$body.triggerHandler(event, [$.data($this.parent()[0], 'item'), $this.parent().index(), $this.index()]); + + if(event.isPropagationStopped()){ + return; + } + if(!$this.parent().hasClass('selected')){ + that.select($this.parent().index()); + }else{ + that.deselect($this.parent().index()); + } + }); + + $body.on('click','tr > td .mmg-check',function(e){ + e.stopPropagation(); + var $this = $(this); + if(this.checked){ + that.select($($this.parents('tr')[0]).index()); + }else{ + that.deselect($($this.parents('tr')[0]).index()); + } + }); + + //checkbox列 + if(opts.checkCol){ + $head.find('th .checkAll').on('click', function(){ + if(this.checked){ + that.select('all'); + }else{ + that.deselect('all'); + } + }); + } + + //IE6不支持hover + if (browser.isIE6){ + $body.on('mouseenter','tr', function () { + $(this).toggleClass('hover'); + }).on('mouseleave','tr', function () { + $(this).toggleClass('hover'); + }); + }; + + + } + + , _rowHtml: function(item, rowIndex){ + var opts = this.opts; + var expandCols = this._expandCols(opts.cols); + var leafCols = this._leafCols(); + + + if($.isPlainObject(item)){ + var trHtml = []; + trHtml.push('<tr>'); + for(var colIndex=0; colIndex < leafCols.length; colIndex++){ + var col = leafCols[colIndex]; + trHtml.push('<td class="'); + var index = $.inArray(col, expandCols); + trHtml.push(this._genColClass(index)); + if(opts.nowrap){ + trHtml.push(' nowrap'); + } + trHtml.push('"><span class="'); + if(opts.nowrap){ + trHtml.push('nowrap'); + } + trHtml.push('">'); + if(col.renderer){ + trHtml.push(col.renderer(item[col.name],item,rowIndex)); + }else{ + trHtml.push(item[col.name]); + } + + trHtml.push('</span></td>'); + }; + trHtml.push('</tr>'); + return trHtml.join(''); + } + } + + , _populate: function(items){ + var opts = this.opts; + var $body = this.$body; + + this._hideMessage(); + if(items && items.length !== 0 && opts.cols){ + + var tbodyHtmls = []; + tbodyHtmls.push('<tbody>'); + for(var rowIndex=0; rowIndex < items.length; rowIndex++){ + var item = items[rowIndex]; + tbodyHtmls.push(this._rowHtml(item, rowIndex)); + } + tbodyHtmls.push('</tbody>'); + $body.empty().html(tbodyHtmls.join('')); + var $trs = $body.find('tr'); + for(var rowIndex=0; rowIndex < items.length; rowIndex++){ + $.data($trs.eq(rowIndex)[0],'item',items[rowIndex]); + } + }else{ + this._insertEmptyRow(); + this._showNoData(); + } + this._setStyle(); + + if(opts.fullWidthRows && this._loadCount <= 1){ + this._fullWidthRows(); + } + } + + , _insertEmptyRow: function(){ + var $body = this.$body; + $body.empty().html('<tbody><tr class="emptyRow"><td style="border: 0px;background: none;">&nbsp;</td></tr></tbody>'); + } + , _removeEmptyRow: function(){ + var $body = this.$body; + $body.find('tr.emptyRow').remove(); + } + + /* 生成列类 */ + , _genColClass: function(colIndex){ + return 'mmg'+ this._id +'-col'+colIndex; + } + + , _setStyle: function(){ + var $head = this.$head; + var $ths = this._expandThs(); + var $body = this.$body; + var leafCol = this._leafCols(); + + //head + $ths.eq(0).addClass('first'); + $ths.eq(-1).addClass('last'); + //body + $body.find('tr,td').removeClass('even') + .removeClass('colSelected').removeClass('colSelectedEven'); + + $body.find('tr:odd').addClass('even'); + + + + var sortIndex = $.inArray($head.find('.mmg-title').filter(function(){ + return $.data(this,'sortStatus') === 'asc' || $(this).data('sortStatus') === 'desc'; + }).parent().parent().data('col'), leafCol); + + $body.find('tr > td:nth-child('+(sortIndex+1)+')').addClass('colSelected') + .filter(':odd').addClass('colSelectedEven'); + + this._resizeHeight(); + + } + , _setColsWidth: function(){ + var opts = this.opts; + var $style = this.$style; + var $head = this.$head; + + var $bodyWrapper = this.$bodyWrapper; + var $body = this.$body; + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + + var scrollTop = $bodyWrapper.scrollTop(); + var scrollLeft = $head.position().left; + + $bodyWrapper.width(9999); + $body.width('auto'); + var styleText = []; + for(var colIndex=0; colIndex<$ths.length; colIndex++){ + var $th = $ths.eq(colIndex); + styleText.push('.mmGrid .'+this._genColClass(colIndex) + ' {'); + var width = $.data($th[0],'col-width'); + styleText.push('width: '+ width +'px;'); + styleText.push('max-width: '+ width +'px;'); + + var col = expandCols[colIndex]; + if(col.align){ + styleText.push('text-align: '+col.align+';'); + } + if(col.hidden){ + styleText.push('display: none; '); + } + styleText.push(' }'); + } + + $body.detach(); + try{ + $style.text(styleText.join('')); + }catch(error){ + $style[0].styleSheet.cssText = styleText.join('');//IE fix + } + $body.width($head.width()-2); + $bodyWrapper.width('100%'); + $bodyWrapper.append($body); + + //调整滚动条 + + $bodyWrapper.scrollLeft(-scrollLeft); + if($bodyWrapper.scrollLeft() === 0){ + $head.css('left', 0); + } + + $bodyWrapper.scrollTop(scrollTop); + } + , _fullWidthRows: function(){ + var opts = this.opts; + var $bodyWrapper = this.$bodyWrapper; + var $mmGrid = this.$mmGrid; + var $head = this.$head; + var scrollWidth = $bodyWrapper.width() - $bodyWrapper[0].clientWidth; + + if(scrollWidth && browser.isIE){ + scrollWidth = scrollWidth + 1; + } + + var fitWidth = $mmGrid.width() - $head.width() - scrollWidth; + if(fitWidth < -20){ + return; + } + + var thsArr = []; + var $ths = this._leafThs(); + var leafCol = this._leafCols(); + for(var i=0; i< leafCol.length; i++){ + var col = leafCol[i]; + var $th = $ths.eq(i); + if(!col.lockWidth && $th.is(':visible')){ + thsArr.push($th); + } + } + + var increaseWidth = Math.floor(fitWidth / thsArr.length); + var maxColWidthIndex = 0; + for(var i=0; i< thsArr.length; i++){ + var $th = thsArr[i]; + var colWidth = $.data($th[0], 'col-width') + increaseWidth; + $.data($th[0], 'col-width', colWidth); + + var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width'); + if(maxColWidth < colWidth){ + maxColWidthIndex = i; + } + } + + var remainWidth = fitWidth - increaseWidth * thsArr.length; + var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width'); + $.data(thsArr[maxColWidthIndex][0], 'col-width', maxColWidth + remainWidth); + this._setColsWidth(); + } + + + , _showLoading: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-mask').show(); + + var $loading = $mmGrid.find('.mmg-loading'); + $loading.css({ + 'left': ($mmGrid.width() - $loading.width()) / 2, + 'top': ($mmGrid.height() - $loading.height()) / 2 + }).show(); + } + , _hideLoading: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-mask').hide(); + $mmGrid.find('.mmg-loading').hide(); + } + , _showNoData: function(){ + this._showMessage(this.opts.noDataText); + } + + , _showLoadError: function(){ + this._showMessage(this.opts.loadErrorText); + } + + , _showMessage: function(msg){ + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $message = $mmGrid.find('.mmg-message'); + $message.css({ + 'left': ($mmGrid.width() - $message.width()) / 2, + 'top': ($mmGrid.height() + $headWrapper.height() - $message.height()) / 2 + }).text(msg).show(); + } + , _hideMessage: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-message').hide(); + } + + , _nativeSorter: function(colIndex, sortStatus){ + var leafCols = this._leafCols(); + var col = leafCols[colIndex]; + + this.$body.find('tr > td:nth-child('+(colIndex+1)+')') + .sortElements(function(a, b){ + var av = $.text($(a)); + var bv = $.text($(b)); + //排序前转换 + if(col.type === 'number'){ + av = parseFloat(av); + bv = parseFloat(bv); + }else{ + //各个浏览器localeCompare的结果不一致 + return sortStatus === 'desc' ? -av.localeCompare(bv) : av.localeCompare(bv); + } + return av > bv ? (sortStatus === 'desc' ? -1 : 1) : (sortStatus === 'desc' ? 1 : -1); + }, function(){ + return this.parentNode; + }); + } + + , _refreshSortStatus: function(){ + var $ths = this.$head.find('th'); + var sortColIndex = -1; + var sortStatus = ''; + $ths.find('.mmg-title').each(function(index, item){ + var status = $.data(item, 'sortStatus'); + if(status){ + sortColIndex = index; + sortStatus = status; + } + }); + var sortStatus = sortStatus === 'desc' ? 'asc' : 'desc'; + if(sortColIndex >=0){ + $ths.eq(sortColIndex).find('.mmg-title').data('sortStatus',sortStatus).click(); + } + } + + , _loadAjax: function(args){ + var that = this; + var opts = this.opts; + var params = {}; + //opt的params可以使函数,例如收集过滤的参数 + if($.isFunction(opts.params)){ + var p = opts.params(); + if(!p){ + return; + } + params = $.extend(params, p); + }else if($.isPlainObject(opts.params)){ + //modify by gzshangtao + if(args){ + opts.params = $.extend(params, args); + } + params = $.extend(params, opts.params); + } + + if(opts.remoteSort){ + var sortName = ''; + var sortStatus = ''; + var $titles = this.$head.find('.mmg-title'); + for(var colIndex=0; colIndex<$titles.length; colIndex++){ + var status = $.data($titles[colIndex], 'sortStatus'); + if(status){ + var col = $titles.eq(colIndex).parent().parent().data('col'); + sortName = col.sortName ? + col.sortName : col.name; + sortStatus = status; + } + } + if(sortName){ + params.sort = sortName+'.'+sortStatus; + } + } + + + //插件参数合并 + var pluginParams = {}; + for(var i=0; i< this.opts.plugins.length; i++){ + var plugin = this.opts.plugins[i]; + $.extend(pluginParams, plugin.params()); + } + params = $.extend(params, pluginParams); + + //合并load的参数 + params = $.extend(params, args); + that._showLoading(); + $.ajax({ + type: opts.method, + url: opts.url, + data: params, + dataType: 'json', + cache: opts.cache + }).done(function(data){ + try{ + //获得root对象 + var items = data; + if($.isArray(data[opts.root])){ + items = data[opts.root]; + } + that._populate(items); + that._hideLoading(); + if(!opts.remoteSort){ + that._refreshSortStatus(); + } + + if(data && $.isArray(data[opts.root])){ + data = $.extend(args, data); + } + that.$body.triggerHandler('loadSuccess', data); + + }catch(e){ + that._hideLoading(); + that._showLoadError(); + throw e; + } + + }).fail(function(data){ + that._hideLoading(); + that._showLoadError(); + that.$body.triggerHandler('loadError', data); + }); + + } + + , _loadNative: function(args){ + this._populate(args); + this._refreshSortStatus(); + this.$body.triggerHandler('loadSuccess', args); + } + , load: function(args){ + try{ + var modify = 'gzshangtao'; + var opts = this.opts; + this._hideMessage(); + this._loadCount = this._loadCount + 1 ; + + if($.isArray(args)){ + //加载本地数据 + this._loadNative(args); + }else if(opts.url){ + this._loadAjax(args); + }else if(opts.items){ + this._loadNative(opts.items); + }else{ + this._loadNative([]); + } + }catch(e){ + this._showLoadError(); + throw e; + } + } + + //重设尺寸--modify by gzshangtao + , resize: function(_opts){ + if(_opts && _opts.width)this.opts.width = _opts.width; + if(_opts && _opts.height)this.opts.height = _opts.height; + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $bodyWrapper = this.$bodyWrapper; + + // fix in ie6 + if(browser.isIE6 && (!opts.width || opts.width === 'auto')){ + $mmGrid.width('100%'); + $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width())); + }else{ + $mmGrid.width(opts.width); + } + + if(opts.height !== 'auto'){ + if(browser.isIE6 && (!opts.height || opts.height === 'auto')){ + $mmGrid.height('100%'); + $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height())); + }else{ + $mmGrid.height(opts.height); + } + + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + + //调整message + var $message = $mmGrid.find('.mmg-message'); + if($message.is(':visible')){ + $message.css({ + 'left': ($mmGrid.width() - $message.width()) / 2, + 'top': ($mmGrid.height() + $headWrapper.height() - $message.height()) / 2 + }); + } + //调整loading + var $mask = $mmGrid.find('.mmg-mask'); + if($mask.is(':visible')){ + $mask.width($mmGrid.width()).height($mmGrid.height()); + var $loadingWrapper = $mmGrid.find('.mmg-loading'); + $loadingWrapper.css({ + 'left': ($mmGrid.width() - $loadingWrapper.width()) / 2, + 'top': ($mmGrid.height() - $loadingWrapper.height()) / 2 + }) + } + + $bodyWrapper.trigger('scroll'); + + this._resizeHeight(); + } + + , _resizeHeight: function(){ + var opts = this.opts; + var $bodyWrapper = this.$bodyWrapper; + var $body= this.$body; + if(opts.height === 'auto' && browser.isIE7){ + $bodyWrapper.height('auto'); + if($bodyWrapper.width() < $body.width()){ + $bodyWrapper.height($bodyWrapper.height() + $bodyWrapper.height() - $bodyWrapper[0].clientHeight + 1); + } + } + } + + //选中 + , select: function(args){ + var opts = this.opts; + var $body = this.$body; + var $head = this.$head; + + if(typeof args === 'number'){ + var $tr = $body.find('tr').eq(args); + if(!opts.multiSelect){ + $body.find('tr.selected').removeClass('selected'); + if(opts.checkCol){ + $body.find('tr > td').find('.mmg-check').prop('checked',''); + } + } + if(!$tr.hasClass('selected')){ + $tr.addClass('selected'); + if(opts.checkCol){ + $tr.find('td .mmg-check').prop('checked','checked'); + } + } + }else if(typeof args === 'function'){ + $.each($body.find('tr'), function(index){ + if(args($.data(this, 'item'), index)){ + var $this = $(this); + if(!$this.hasClass('selected')){ + $this.addClass('selected'); + if(opts.checkCol){ + $this.find('td .mmg-check').prop('checked','checked'); + } + } + } + }); + }else if(args === undefined || (typeof args === 'string' && args === 'all')){ + $body.find('tr.selected').removeClass('selected'); + $body.find('tr').addClass('selected'); + $body.find('tr > td').find('.mmg-check').prop('checked','checked'); + }else{ + return; + } + + if(opts.checkCol){ + var $checks = $body.find('tr > td').find('.mmg-check'); + if($checks.length === $checks.filter(':checked').length){ + $head.find('th .checkAll').prop('checked','checked'); + } + } + + + } + //取消选中 + , deselect: function(args){ + var opts = this.opts; + var $body = this.$body; + var $head = this.$head; + if(typeof args === 'number'){ + $body.find('tr').eq(args).removeClass('selected'); + if(opts.checkCol){ + $body.find('tr').eq(args).find('td .mmg-check').prop('checked',''); + } + }else if(typeof args === 'function'){ + $.each($body.find('tr'), function(index){ + if(args($.data(this, 'item'), index)){ + $(this).removeClass('selected'); + if(opts.checkCol){ + $(this).find('td .mmg-check').prop('checked',''); + } + } + }); + }else if(args === undefined || (typeof args === 'string' && args === 'all')){ + $body.find('tr.selected').removeClass('selected'); + if(opts.checkCol){ + $body.find('tr > td').find('.mmg-check').prop('checked',''); + } + }else{ + return; + } + + $head.find('th .checkAll').prop('checked',''); + + } + , selectedRows: function(){ + var $body = this.$body; + var selected = []; + $.each($body.find('tr.selected'), function(index ,item){ + selected.push($.data(this,'item')); + }); + return selected; + } + + , selectedRowsIndex: function(){ + var $body = this.$body; + var $trs = this.$body.find('tr') + var selected = []; + $.each($body.find('tr.selected'), function(index){ + selected.push($trs.index(this)); + }); + return selected; + } + + , rows: function(){ + var $body = this.$body; + var items = []; + $.each($body.find('tr'), function(){ + items.push($.data(this,'item')); + }); + return items; + } + + , row: function(index){ + var $body = this.$body; + if(index !== undefined && index >= 0){ + var $tr = $body.find('tr').eq(index); + if($tr.length !== 0){ + return $.data($tr[0],'item'); + } + } + } + + , rowsLength: function(){ + var $body = this.$body; + var length = $body.find('tr').length; + if(length === 1 && $body.find('tr.emptyRow').length === 1){ + return 0; + } + return length; + } + + //添加数据,第一个参数可以为数组 + , addRow: function(item, index){ + var $tbody = this.$body.find('tbody'); + + if($.isArray(item)){ + for(var i=item.length-1; i >= 0; i--){ + this.addRow(item[i], index); + } + return ; + } + + if(!$.isPlainObject(item)){ + return ; + } + + this._hideMessage(); + this._removeEmptyRow(); + + var $tr; + + if(index === undefined || index < 0){ + $tr = $(this._rowHtml(item, this.rowsLength())); + $tbody.append($tr); + }else{ + $tr = $(this._rowHtml(item, index)); + if(index === 0){ + $tbody.prepend($tr); + }else{ + var $before = $tbody.find('tr').eq(index-1); + //找不到就插到最后 + if($before.length === 0){ + $tbody.append($tr); + }else{ + $before.after($($tr)); + } + } + } + $tr.data('item', item); + this._setStyle(); + + + this.$body.triggerHandler('rowInserted', [item, index]); + } + //更新行内容,两个参数都必填 + , updateRow: function(item, index){ + var opts = this.opts; + var $tbody = this.$body.find('tbody'); + if(!$.isPlainObject(item)){ + return ; + } + var oldItem = this.row(index); + + var $tr = $tbody.find('tr').eq(index); + var checked = $tr.find('td:first :checkbox').is(':checked'); + $tr.html(this._rowHtml(item, index).slice(4,-5)); + if(opts.checkCol){ + $tr.find('td:first :checkbox').prop('checked',checked); + } + + $tr.data('item', item); + this._setStyle(); + + this.$body.triggerHandler('rowUpdated', [oldItem, item, index]); + } + + //删除行,参数可以为索引数组 + , removeRow: function(index){ + var that = this; + var $tbody = that.$body.find('tbody'); + + if($.isArray(index)){ + for(var i=index.length-1; i >= 0; i--){ + that.removeRow(index[i]); + } + return ; + } + + if(index === undefined){ + var $trs = $tbody.find('tr'); + for(var i=$trs.length-1; i >= 0; i--){ + that.removeRow(i); + } + }else{ + var item = that.row(index); + $tbody.find('tr').eq(index).remove(); + this.$body.triggerHandler('rowRemoved', [item, index]); + } + this._setStyle(); + if(this.rowsLength() === 0){ + this._showNoData(); + this._insertEmptyRow(); + } + } + }; + + $.fn.mmGrid = function(){ + if(arguments.length === 0 || typeof arguments[0] === 'object'){ + var option = arguments[0] + , data = this.data('mmGrid') + , options = $.extend(true, {}, $.fn.mmGrid.defaults, option); + if (!data) { + data = new MMGrid(this, options); + this.data('mmGrid', data); + } + return $.extend(true, this, data); + } + if(typeof arguments[0] === 'string'){ + var data = this.data('mmGrid'); + var fn = data[arguments[0]]; + if(fn){ + var args = Array.prototype.slice.call(arguments); + return fn.apply(data,args.slice(1)); + } + } + }; + + $.fn.mmGrid.defaults = { + width: 'auto' + , height: '280px' + , cols: [] + , url: false + , params: {} + , method: 'POST' + , cache: false + , root: 'items' + , items: [] + , autoLoad: true + , remoteSort: false + , sortName: '' + , sortStatus: 'asc' + , loadingText: '正在载入...' + , noDataText: '没有数据' + , loadErrorText: '数据加载出现异常' + , multiSelect: false + , checkCol: false + , indexCol: false + , indexColWidth: 40 + , fullWidthRows: false + , nowrap: false + , showBackboard: true + , backboardMinHeight: 125 + , plugins: [] //插件 插件必须实现 init($mmGrid)和params()方法,参考mmPaginator + }; +// event : loadSuccess(e,data), loadError(e, data), cellSelected(e, item, rowIndex, colIndex) +// rowInserted(e,item, rowIndex), rowUpdated(e, oldItem, newItem, rowIndex), rowRemoved(e,item, rowIndex) +// + + + $.fn.mmGrid.Constructor = MMGrid; + + + // see: http://james.padolsey.com/javascript/sorting-elements-with-jquery/ + $.fn.sortElements = (function(){ + var sort = [].sort; + return function(comparator, getSortable) { + getSortable = getSortable || function(){return this;}; + var placements = this.map(function(){ + var sortElement = getSortable.call(this), + parentNode = sortElement.parentNode, + nextSibling = parentNode.insertBefore( + document.createTextNode(''), + sortElement.nextSibling + ); + return function() { + if (parentNode === this) { + throw new Error( + "You can't sort elements if any one is a descendant of another." + ); + } + parentNode.insertBefore(this, nextSibling); + parentNode.removeChild(nextSibling); + }; + }); + return sort.call(this, comparator).each(function(i){ + placements[i].call(getSortable.call(this)); + }); + }; + })(); +}(window.jQuery); + + +!function($){ + var MMPaginator = function(element, options){ + this.$el = $(element); + this.opts = options; + }; + + MMPaginator.prototype = { + _initLayout: function(){ + var that = this; + var $el = this.$el; + var opts = this.opts; + + $el.addClass("mmPaginator"); + var pgHtmls = [ + '<div class="totalCountLabel"></div>', + '<ul class="pageList"></ul>', + '<div class="limit"><select></select></div>' + ]; + $el.append($(pgHtmls.join(''))); + + this.$totalCountLabel = $el.find('.totalCountLabel'); + this.$pageList = $el.find('.pageList'); + this.$limitList = $el.find('.limit select'); + + var $limitList = this.$limitList + $.each(opts.limitList, function(){ + var $option = $('<option></option>') + .prop('value',this) + .text(that.formatString(opts.limitLabel,[this])); + $limitList.append($option); + }); + + $limitList.on('change', function(){ + $el.data('page', 1); + that.$mmGrid.load(); + }); + + } + + , _plain: function(page, totalCount, limit){ + var that = this; + var $el = this.$el; + var $pageList = this.$pageList; + + var totalPage = totalCount % limit === 0 ? parseInt(totalCount/limit) : parseInt(totalCount/limit) + 1; + totalPage = totalPage ? totalPage : 0; + if(totalPage === 0){ + page = 1; + }else if(page > totalPage){ + page = totalPage; + }else if(page < 1 && totalPage != 0){ + page = 1; + } + // + var $prev = $('<li class="prev"><a>«</a></li>'); + if(page<=1){ + $prev.addClass('disable'); + }else{ + $prev.find('a').on('click', function(){ + $el.data('page', page-1); + that.$mmGrid.load(); + }); + } + $pageList.append($prev); + ///// + var list = [1]; + if(page > 4 ){ + list.push('...'); + } + for(var i= 0; i < 5; i++){ + var no = page - 2 + i; + if(no > 1 && no <= totalPage-1){ + list.push(no); + } + } + if(page+1 < totalPage-1){ + list.push('...'); + } + if(totalPage>1){ + list.push(totalPage); + } + $.each(list, function(index, item){ + var $li = $('<li><a></a></li>'); + if(item === '...'){ + $li.addClass('').html('...'); + }else if(item === page){ + $li.addClass('active').find('a').text(item); + }else{ + $li.find('a').text(item).prop('title','第'+item+'页').on('click', function(e){ + $el.data('page', item); + that.$mmGrid.load(); + }); + } + $pageList.append($li); + }); + // + var $next = $('<li class="next"><a title="下一页">»</a></li>'); + if(page>=totalPage){ + $next.addClass('disable'); + }else{ + $next.find('a').on('click', function(){ + $el.data('page', page+1); + that.$mmGrid.load(); + }); + } + $pageList.append($next); + } + + , _search: function(page, totalCount, limit){ + + } + + , load: function(params){ + var $el = this.$el; + var $limitList = this.$limitList; + var opts = this.opts; + + if(!params){ + params = {}; + } + + var page = params[opts.pageParamName]; + if(page === undefined || page === null){ + page = $el.data('page'); + } + $el.data('page', page); + + var totalCount = params[opts.totalCountName]; + if(totalCount === undefined){ + totalCount = 0; + } + $el.data('totalCount', totalCount); + + var limit = params[opts.limitParamName]; + if(!limit){ + limit = $limitList.val(); + } + this.$limitList.val(limit); + + this.$totalCountLabel.html(this.formatString(opts.totalCountLabel,[totalCount])); + this.$pageList.empty(); + + this._plain(page, totalCount, this.$limitList.val()); + } + + , formatString: function(text, args){ + return text.replace(/{(\d+)}/g, function(match, number) { + return typeof args[number] != 'undefined' + ? args[number] + : match + ; + }); + } + + , params: function(){ + var opts = this.opts; + var $el = this.$el; + var $limitList = this.$limitList; + + var params = {}; + params[opts.pageParamName] = $el.data('page'); + params[opts.limitParamName] = $limitList.val(); + return params; + } + + , init: function($grid){ + var that = this; + var opts = that.opts; + this.$mmGrid = $grid; + this._initLayout(); + this.$mmGrid.on('loadSuccess', function(e, data){ + that.load(data); + }); + + var params = {}; + params[opts.totalCountName] = 0; + params[opts.pageParamName] = opts.page; + params[opts.limitParamName] = opts.limit; + this.load(params); + + if($grid.opts.indexCol){ + var indexCol = $grid.opts.cols[0]; + indexCol.renderer = function(val,item,rowIndex){ + var params = that.params(); + return '<label class="mmg-index">' + + (rowIndex + 1 + ((params[opts.pageParamName]-1) * params[opts.limitParamName])) + + '</label>'; + }; + } + + } + + }; + + $.fn.mmPaginator = function(){ + + if(arguments.length === 0 || typeof arguments[0] === 'object'){ + var option = arguments[0] + , data = this.data('mmPaginator') + , options = $.extend(true, {}, $.fn.mmPaginator.defaults, option); + if (!data) { + data = new MMPaginator(this[0], options); + this.data('mmPaginator', data); + } + return $.extend(true, this, data); + } + if(typeof arguments[0] === 'string'){ + var data = this.data('mmPaginator'); + var fn = data[arguments[0]]; + if(fn){ + var args = Array.prototype.slice.call(arguments); + return fn.apply(data,args.slice(1)); + } + } + }; + + $.fn.mmPaginator.defaults = { + style: 'plain' + , totalCountName: 'totalCount' + , page: 1 + , pageParamName: 'page' + , limitParamName: 'limit' + , limitLabel: '每页{0}条' + , totalCountLabel: '共<span>{0}</span>条记录' + , limit: undefined + , limitList: [20, 30, 40, 50] + }; + + $.fn.mmPaginator.Constructor = MMPaginator; + +}(window.jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/mmgrid/mmGrid.css b/hyhproject/admin/view/js/mmgrid/mmGrid.css new file mode 100755 index 0000000..fd25724 --- /dev/null +++ b/hyhproject/admin/view/js/mmgrid/mmGrid.css @@ -0,0 +1,485 @@ + +.mmGrid{ + position: relative; + overflow: hidden; + background: #fff; + border: 1px solid #ccc; + text-align: left; +} + +.mmGrid table{ + border-collapse: separate; + border-spacing: 0; + text-align: left; + +} + +.mmGrid input[type="radio"], +.mmGrid input[type="checkbox"]{ + margin: 0; +} + +/* 遮罩 */ +.mmGrid .mmg-mask{ + position: absolute; + left: 0; + top: 0; + display: none; + width: 100%; + height: 100%; + background: #ddd; + + +} + +/* 半透明 */ +.mmGrid .mmg-transparent{ + /* IE 8 */ + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; + /* IE 5-7 */ + filter: alpha(opacity=50); + /* Netscape */ + -moz-opacity: 0.5; + /* Safari 1.x */ + -khtml-opacity: 0.5; + /* Good browsers */ + opacity: 0.5; +} + +/* loading */ +.mmGrid .mmg-loading{ + position: absolute; + display: none; + text-align: center; + +} + +.mmGrid .mmg-loading .mmg-loadingImg{ + margin: 5px auto; + width: 32px; + height: 32px; + background: url(img/loading.gif) no-repeat center center; +} + +.mmGrid .mmg-loading .mmg-loadingText{ + +} + +/* 标题包装 */ +.mmGrid .mmg-headWrapper{ + position: relative; + overflow: hidden; + width: 9999px; + + background: #eee; /* Old browsers */ + background: -moz-linear-gradient(top, #f9f9f9 0%, #eaeaea 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f9f9f9), color-stop(100%,#eaeaea)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #f9f9f9 0%,#eaeaea 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #f9f9f9 0%,#eaeaea 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #f9f9f9 0%,#eaeaea 100%); /* IE10+ */ + background: linear-gradient(to bottom, #f9f9f9 0%,#eaeaea 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f9f9f9', endColorstr='#eaeaea',GradientType=0 ); /* IE6-8 */ + + -moz-box-shadow: 0 0px 2px #bbb; + -webkit-box-shadow: 0 0px 2px #bbb; + box-shadow: 0 0px 2px #bbb; + border-top: 2px solid #b00; + z-index: 1; + +} + +/* 标题 */ +.mmGrid .mmg-headWrapper .mmg-head{ + position: relative; +} + +.mmGrid .mmg-headWrapper .mmg-head th{ + position: relative; + padding: 0 5px; + border-right: 1px solid #ddd; + border-bottom: 1px solid #d2d2d2; + overflow: hidden; +} + +.mmGrid .mmg-headWrapper .mmg-head th.mmg-groupCol{ + /* 分组列 */ +} + +.mmGrid .mmg-headWrapper .mmg-head th input{ + height: 2em; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper{ + position: relative; + height: 2em; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-colResize{ + position: absolute; + top: 0; + right: -6px; + _right: -4px; + width: 4px; + height: 100%; + cursor: col-resize; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-title{ + display: inline-block; + *display: inline; + *zoom: 1; + height: 2em; + font-weight: bold; + line-height: 2; + vertical-align: top; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-canSort{ + cursor: pointer; + text-decoration: underline; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-sort{ + overflow: hidden; + display: none; + width: 7px; + height: 2em; + margin-left: 2px; + vertical-align: top; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-asc{ + display: inline-block; + *display: inline; + *zoom: 1; + background: url(img/sort-asc.png) no-repeat center center; +} + +.mmGrid .mmg-headWrapper .mmg-head th .mmg-titleWrapper .mmg-desc{ + display: inline-block; + *display: inline; + *zoom: 1; + background: url(img/sort-desc.png) no-repeat center center; +} + +.mmGrid .mmg-colResizePointer{ + position: absolute; + top: 0; + left: 0; + display: none; + width: 1px; + height: 100%; + background: #999; + cursor: col-resize; + z-index: 1; +} + +.mmGrid .mmg-colResizePointer-before{ + position: absolute; + top: 0; + left: 0; + display: none; + width: 1px; + height: 100%; + background: #999; + cursor: col-resize; + z-index: 1; +} + +/* 背板 */ +.mmGrid .mmg-backboard{ + position: relative; + display: none; + background-image: url(img/furley_bg.png); + background-image: -webkit-image-set( + url(img/furley_bg.png) 1x, + url(img/furley_bg_@2X.png) 2x + ); + -webkit-box-shadow: inset 0 0 2px 1px #d9d9d9; + -moz-box-shadow: inset 0 0 2px 1px #d9d9d9; + -o-box-shadow: inset 0 0 2px 1px #d9d9d9; + -ms-box-shadow: inset 0 0 2px 1px #d9d9d9; + box-shadow: inset 0 0 2px 1px #d9d9d9; + text-align: left; +} +.mmGrid .mmg-backboard h1{ + margin: 0 10px 5px 10px; + padding: 10px 0 5px 0; + font-size: 1em; + font-weight: bold; + line-height: 1.8; + border-bottom: 1px solid #ccc; +} + +.mmGrid .mmg-backboard label{ + display: inline-block; + *display: inline; + *zoom: 1; + width: 95px; + font-size: 1em; + line-height: 2.2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.mmGrid .mmg-backboard label input{ + margin: 0 5px 0 10px; + padding: 0px; + border: 0px; +} + +/* 内容包装器 */ +.mmGrid .mmg-bodyWrapper{ + position: relative; + overflow: auto; + width: 9999px; + min-height: 0%; /* fix IE9 hover bug see: http://jsfiddle.net/pjkix/86Lfv/ */ +} + +/* 内容 */ +.mmGrid .mmg-bodyWrapper .mmg-body{ + table-layout: fixed; +} + +.mmGrid .mmg-bodyWrapper .mmg-body tr{ + +} + +.mmGrid .mmg-bodyWrapper .mmg-body tr.even{ + background: #f9f9f9; +} + +.mmGrid .mmg-bodyWrapper .mmg-body td{ + padding: 0 5px; + border-right: 1px solid #e4e4e4; + border-bottom: 1px solid #e4e4e4; + line-height: 2; +} + +.mmGrid .mmg-bodyWrapper .mmg-body td.colSelected{ + background: #f7f7f7; +} + +.mmGrid .mmg-bodyWrapper .mmg-body td.colSelectedEven{ + background: #f5f5f5; +} + +.mmGrid .mmg-bodyWrapper .mmg-body tr.hover td{ + background: #e1eff8; +} + +.mmGrid .mmg-bodyWrapper .mmg-body tr:hover td{ + background: #e1eff8; +} + +.mmGrid .mmg-bodyWrapper .mmg-body tr.selected td{ + background: #fff5cc; +} + +.mmGrid .mmg-bodyWrapper .mmg-body td .mmg-index{ + color: #555; +} + +.mmGrid .nowrap{ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; +} + +/* 消息 */ +.mmGrid .mmg-message{ + position: absolute; + display: none; + text-align: center; +} + +.mmGrid .mmg-btnBackboardDn{ + position: absolute; + top: 0; + right: 20px; + display: block; + width: 50px; + height: 20px; + background: #fff url(img/arrow_down.png) no-repeat center center; + border: 1px solid #ccc; + border-top: 0; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + -webkit-box-shadow: 1px 1px 3px #ccc; + -moz-box-shadow: 1px 1px 3px #ccc; + -o-box-shadow: 1px 1px 3px #ccc; + -ms-box-shadow: 1px 1px 3px #ccc; + box-shadow:1px 1px 3px #ccc; + cursor: pointer; +} + +.mmGrid .mmg-backboard .mmg-btnBackboardUp{ + position: absolute; + right: 20px; + bottom: 0; + display: block; + width: 50px; + height: 20px; + background: #fff url(img/arrow_up.png) no-repeat center center; + border: 1px solid #ccc; + border-bottom: 0; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + -webkit-box-shadow: 1px 1px 3px #ccc; + -moz-box-shadow: 1px 1px 3px #ccc; + -o-box-shadow: 1px 1px 3px #ccc; + -ms-box-shadow: 1px 1px 3px #ccc; + box-shadow:1px 1px 3px #ccc; + cursor: pointer; +} +.mmPaginator { + margin: 5px 0; + white-space: nowrap; +} + +.mmPaginator .totalCountLabel{ + display: inline-block; + *display: inline; + *zoom: 1; + margin: 0 5px 0 0; + padding: 1px 0 0 0; + line-height: 1.5; + vertical-align: top; +} +.mmPaginator .totalCountLabel span{ + color: #b00; + font-weight: bold; +} + +.mmPaginator .pageList{ + display: inline-block; + *display: inline; + *zoom: 1; + margin: 0 5px 0 0; + padding: 0; + list-style: none; +} + +.mmPaginator .pageList li{ + display: inline-block; + *display: inline; + *zoom: 1; + margin: 0 2px; + padding: 0 6px; + background: #fff; + border: 1px solid #ccc; + line-height: 1.5; + vertical-align: top; + +} + +.mmPaginator .pageList li.active{ + background: none; + padding-top: 1px; + border: 0; +} + +.mmPaginator .pageList li.disable a{ + color: #333; + cursor: default; +} + +.mmPaginator .pageList li.disable{ + background: #efefef; +} + +.mmPaginator .pageList li.disable a{ + color: #333; + cursor: default; +} + +.mmPaginator .pageList li a{ + color: #b00; + text-align: center; + cursor: pointer; +} + +.mmPaginator .pageList li a.head{ + +} + +.mmPaginator .pageList li a.headDisable{ + +} + +.mmPaginator .pageList li a.prev{ + +} + +.mmPaginator .pageList li a.prevDisable{ + +} + +.mmPaginator .pageList li a.next{ + +} + +.mmPaginator .pageList li a.nextDisable{ + +} + +.mmPaginator .pageList li a.tail{ + +} + +.mmPaginator .pageList li a.tailDisable{ + +} + +.mmPaginator .pageList li a.current{ + +} + +.mmPaginator .pageList li a.skip{ + +} + +.mmPaginator .limit{ + display: inline-block; + *display: inline; + *zoom: 1; + line-height: 1.5; + vertical-align: top; +} + +.mmPaginator .limit select{ + border: 1px solid #ccc; + padding: 1px; + width: auto; + height: auto; + margin: 0; + line-height: 1.5; + font-size: 1em; +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyhproject/admin/view/js/mmgrid/mmGrid.js b/hyhproject/admin/view/js/mmgrid/mmGrid.js new file mode 100755 index 0000000..1e26b16 --- /dev/null +++ b/hyhproject/admin/view/js/mmgrid/mmGrid.js @@ -0,0 +1,6 @@ +!function(c){var b=function(f,d){this._id=(((1+Math.random())*65536)|0).toString(16);this._loadCount=0;this.opts=d;this._initLayout(c(f));this._initHead();this._initOptions();this._initEvents();this._setColsWidth();if(this.opts.fullWidthRows){this._fullWidthRows()}for(var e=0;e<this.opts.plugins.length;e++){var h=this.opts.plugins[e];h.init(c.extend(f,this))}if(d.autoLoad){var g=this;this.opts=d;setTimeout(function(){if(d.url){g.load()}else{g.load(d.items)}},0)}};var a=function(){var d=!!window.ActiveXObject;var h=d&&!!window.atob;var e=d&&document.addEventListener&&!window.atob;var f=d&&document.querySelector&&!document.addEventListener;var g=d&&window.XMLHttpRequest&&!document.querySelector;var i=d&&!window.XMLHttpRequest;return{isIE:d,isIE6:i,isIE7:g,isIE8:f,isIE9:e,isIE10:h}}();b.prototype={_initLayout:function(g){var h=this.opts;var f=g.parent();var e=g.index();var j=['<div class="mmGrid">',"<style></style>",'<div class="mmg-headWrapper">','<table class="mmg-head" cellspacing="0"></table>',"</div>",'<div class="mmg-colResizePointer"></div>','<div class="mmg-colResizePointer-before"></div>','<div class="mmg-backboard">','<a class="mmg-btnBackboardUp"></a>',"</div>",'<div class="mmg-bodyWrapper"></div>','<a class="mmg-btnBackboardDn"></a>','<div class="mmg-message">'+this.opts.noDataText+"</div>",'<div class="mmg-mask mmg-transparent"></div>','<div class="mmg-loading">','<div class="mmg-loadingImg"></div>','<div class="mmg-loadingText">'+this.opts.loadingText+"</div>","</div>","</div>"];if(a.isIE7||a.isIE6){g.prop("cellspacing",0)}var d=c(j.join(""));this.$mmGrid=d;this.$style=d.find("style");this.$headWrapper=d.find(".mmg-headWrapper");this.$head=d.find(".mmg-head");this.$backboard=d.find(".mmg-backboard");this.$bodyWrapper=d.find(".mmg-bodyWrapper");this.$body=g.removeAttr("style").addClass("mmg-body");this._insertEmptyRow();this.$body.appendTo(this.$bodyWrapper);if(e===0||f.children().length==0){f.prepend(this.$mmGrid)}else{f.children().eq(e-1).after(this.$mmGrid)}if(a.isIE6&&(!h.width||h.width==="auto")){d.width("100%");d.width(d.width()-(d.outerWidth(true)-d.width()))}else{d.width(h.width)}if(a.isIE6&&(!h.height||h.height==="auto")){d.height("100%");d.height(d.height()-(d.outerHeight(true)-d.height()))}else{d.height(h.height)}if(h.checkCol){var i=h.multiSelect?'<input type="checkbox" class="checkAll" >':'<input type="checkbox" disabled="disabled" class="checkAll">';h.cols.unshift({title:i,width:20,align:"center",lockWidth:true,checkCol:true,renderer:function(){return'<input type="checkbox" class="mmg-check">'}})}if(h.indexCol){h.cols.unshift({title:"#",width:h.indexColWidth,align:"center",lockWidth:true,indexCol:true,renderer:function(l,k,m){return'<label class="mmg-index">'+(m+1)+"</label>"}})}},_expandCols:function(g){var f=[];if(!g){return f}for(var e=0;e<g.length;e++){var d=g[e];if(d.cols){f.push(d);f.push.apply(f,this._expandCols(d.cols))}else{f.push(d)}}return f},_leafCols:function(){var g=this.opts;var f=[];var h=this._expandCols(g.cols);for(var e=0;e<h.length;e++){var d=h[e];if(!d.cols){f.push(d)}}return f},_expandThs:function(){return this.$head.find("th").sort(function(e,d){return parseInt(c(e).data("colindex"))-parseInt(c(d).data("colindex"))})},_leafThs:function(){return this.$head.find("th").filter(function(){return !c.data(this,"col").cols}).sort(function(e,d){return parseInt(c(e).data("colindex"))-parseInt(c(d).data("colindex"))})},_colsWithTitleDeep:function(h,d){var g=[];if(!h){return g}for(var f=0;f<h.length;f++){var e=h[f];if(d===1){g.push(e)}else{g.push.apply(g,this._colsWithTitleDeep(e.cols,d-1))}}return g},_titleDeep:function(g){var d=1;for(var f=0;f<g.length;f++){var e=g[f];if(e.cols){var h=1+this._titleDeep(e.cols);if(d<h){d=h}}}return d},_titleHtml:function(e,h){var f=this.opts;var g=[];if(!e.cols){g.push('<th class="');var d=c.inArray(e,this._expandCols(f.cols));g.push(this._genColClass(d));g.push(' " ');g.push(' rowspan="');g.push(h);g.push('" colspan="');g.push(1);g.push('" data-colIndex="');g.push(d);g.push('" >');g.push('<div class="mmg-titleWrapper" >');g.push('<span class="mmg-title ');if(e.sortable){g.push("mmg-canSort ")}g.push('">');if(e.titleHtml){g.push(e.titleHtml)}else{g.push(e.title)}g.push('</span><div class="mmg-sort"></div>');if(!e.lockWidth){g.push('<div class="mmg-colResize"></div>')}g.push("</div></th>")}else{var i=e.cols.length;c.each(e.cols,function(j,k){if(k.hidden){i--}});if(i===0){e.hidden=true}g.push('<th class="');var d=c.inArray(e,this._expandCols(f.cols));g.push(this._genColClass(d));g.push(' mmg-groupCol" ');g.push(' rowspan="');g.push(h-1);g.push('" colspan="');g.push(i);g.push('" data-colIndex="');g.push(d);g.push('" >');g.push('<div class="mmg-titleWrapper" >');g.push('<span class="mmg-title ');if(e.sortable){g.push("mmg-canSort ")}g.push('">');if(e.titleHtml){g.push(e.titleHtml)}else{g.push(e.title)}g.push('</span><div class="mmg-sort"></div>');g.push("</div></th>")}return g.join("")},_initHead:function(){var i=this;var d=this.opts;var j=this.$head; +if(d.cols){var h=["<thead>"];var r=i._titleDeep(d.cols);for(var o=1;o<=r;o++){var l=i._colsWithTitleDeep(d.cols,o);h.push("<tr>");for(var n=0;n<l.length;n++){var g=l[n];h.push(this._titleHtml(g,r-o+1))}h.push("</tr>")}h.push("</thead>");j.html(h.join(""))}var k=this._expandThs();var f=this._expandCols(d.cols);c.each(k,function(s){if(!f[s].width){f[s].width=100}c.data(this,"col-width",f[s].width);c.data(this,"col",f[s])});var p=this.$mmGrid;var m=this.$headWrapper;var e=this.$bodyWrapper;if(d.height!=="auto"){e.height(p.height()-m.outerHeight(true))}if(d.sortName){for(var n=0;n<f.length;n++){var g=f[n];if(g.sortName===d.sortName||g.name===d.sortName){var q=k.eq(n);c.data(q.find(".mmg-title")[0],"sortStatus",d.sortStatus);q.find(".mmg-sort").addClass("mmg-"+d.sortStatus)}}}},_initOptions:function(){var g=this.opts;var d=this.$mmGrid;var i=this.$headWrapper;var h=this.$backboard;d.find("a.mmg-btnBackboardDn").css({"top":i.outerHeight(true)}).slideUp("fast");var j=this._leafCols();if(j){var k=["<h1>显示列</h1>"];for(var f=0;f<j.length;f++){k.push("<label ");if(j[f].checkCol||j[f].indexCol){k.push('style="display:none;" ')}var e=j[f];k.push('><input type="checkbox" ');if(!e.hidden){k.push('checked="checked"')}if(e.lockDisplay){k.push(' disabled="disabled"')}k.push("/><span>");if(e.title){k.push(e.title)}else{k.push("未命名")}k.push("</span></label>")}h.append(c(k.join("")))}},_initEvents:function(){var i=this;var d=this.opts;var n=this.$mmGrid;var m=this.$headWrapper;var j=this.$head;var f=this.$bodyWrapper;var h=this.$body;var o=this.$backboard;var k=this._expandThs();var e=this._expandCols(d.cols);var g=this._leafCols();if(d.width==="auto"||d.height==="auto"||(typeof d.width==="string"&&d.width.indexOf("%")===d.width.length-1)||typeof d.height==="string"&&d.height.indexOf("%")===d.height.length-1){c(window).on("resize",function(){i.resize()})}f.on("scroll",function(){j.css("left",-c(this).scrollLeft())});var l=n.find("a.mmg-btnBackboardDn").on("click",function(){var p=n.height()-m.outerHeight(true);if(d.height==="auto"&&d.backboardMinHeight!=="auto"&&p<d.backboardMinHeight){p=d.backboardMinHeight}o.height(p);if(d.height==="auto"){n.height(m.outerHeight(true)+o.outerHeight(true))}o.slideDown();l.slideUp("fast");i._hideMessage()});h.on("mouseenter",function(){l.slideUp("fast")});n.on("mouseleave",function(){l.slideUp("fast")});m.on("mouseenter",function(){if(o.is(":hidden")&&d.showBackboard){l.slideDown("fast")}});n.find("a.mmg-btnBackboardUp").on("click",function(){o.slideUp().queue(function(p){if(!i.rowsLength()||(i.rowsLength()===1&&h.find("tr.emptyRow").length===1)){i._showNoData()}if(d.height==="auto"){n.height("auto")}p()})});o.on("click",":checkbox",function(){var s=o.find("label").index(c(this).parent());var u=1;if(d.checkCol){u=u+1}if(d.indexCol){u=u+1}if(o.find("label :checked").length<u){this.checked=true;return}var q=g[s];if(this.checked){q.hidden=false}else{q.hidden=true}var t=j.find("th");for(var v=t.length-1;v>=0;v--){var x=t.eq(v);var w=x.data("col");if(w.cols){var r=true;var p=0;c.each(w.cols,function(y,z){if(!z.hidden){r=false;p++}});if(p!==0){x.prop("colspan",p)}w.hidden=r}}i._setColsWidth();o.height(n.height()-m.outerHeight(true));if(d.height!=="auto"){f.height(n.height()-m.outerHeight(true))}n.find("a.mmg-btnBackboardDn").css({"top":m.outerHeight(true)})});j.on("click",".mmg-title",function(){var s=c(this);var p=k.find(".mmg-title");var q=s.parent().parent().data("col");if(!q.sortable){return}var r=c.data(this,"sortStatus")==="asc"?"desc":"asc";c.each(p,function(){c.removeData(this,"sortStatus")});k.find(".mmg-sort").removeClass("mmg-asc").removeClass("mmg-desc");c.data(this,"sortStatus",r);s.siblings(".mmg-sort").addClass("mmg-"+r);if(d.url&&d.remoteSort){i.load()}else{i._nativeSorter(c.inArray(q,g),r);i._setStyle()}}).on("mousedown",".mmg-colResize",function(s){var q=c(this);var u=s.pageX;var p=n.find(".mmg-colResizePointer").css("left",s.pageX-m.offset().left).show();var t=j.position().left;var r=n.find(".mmg-colResizePointer-before").css("left",q.parent().parent().position().left+t).show();document.selection&&document.selection.empty&&(document.selection.empty(),1)||window.getSelection&&window.getSelection().removeAllRanges();document.body.onselectstart=function(){return false};m.css("-moz-user-select","none");n.on("mousemove",function(v){p.css("left",v.pageX-m.offset().left)}).on("mouseup",function(x){var w=q.parent().parent();var v=w.width()+x.pageX-u;c.data(w[0],"col-width",v);i._setColsWidth();m.mouseleave()}).on("mouseleave",function(){n.off("mouseup").off("mouseleave").off("mousemove");p.hide();r.hide();document.body.onselectstart=function(){return true};m.css("-moz-user-select","text")})});var h=this.$body;h.on("click","td",function(r){var q=c(this);var p=jQuery.Event("cellSelected");p.target=r.target;i.$body.triggerHandler(p,[c.data(q.parent()[0],"item"),q.parent().index(),q.index()]);if(p.isPropagationStopped()){return}if(!q.parent().hasClass("selected")){i.select(q.parent().index())}else{i.deselect(q.parent().index()) +}});h.on("click","tr > td .mmg-check",function(q){q.stopPropagation();var p=c(this);if(this.checked){i.select(c(p.parents("tr")[0]).index())}else{i.deselect(c(p.parents("tr")[0]).index())}});if(d.checkCol){j.find("th .checkAll").on("click",function(){if(this.checked){i.select("all")}else{i.deselect("all")}})}if(a.isIE6){h.on("mouseenter","tr",function(){c(this).toggleClass("hover")}).on("mouseleave","tr",function(){c(this).toggleClass("hover")})}},_rowHtml:function(l,j){var d=this.opts;var e=this._expandCols(d.cols);var g=this._leafCols();if(c.isPlainObject(l)){var h=[];h.push("<tr>");for(var k=0;k<g.length;k++){var f=g[k];h.push('<td class="');var i=c.inArray(f,e);h.push(this._genColClass(i));if(d.nowrap){h.push(" nowrap")}h.push('"><span class="');if(d.nowrap){h.push("nowrap")}h.push('">');if(f.renderer){h.push(f.renderer(l[f.name],l,j))}else{h.push(l[f.name])}h.push("</span></td>")}h.push("</tr>");return h.join("")}},_populate:function(e){var g=this.opts;var i=this.$body;this._hideMessage();if(e&&e.length!==0&&g.cols){var h=[];h.push("<tbody>");for(var j=0;j<e.length;j++){var f=e[j];h.push(this._rowHtml(f,j))}h.push("</tbody>");i.empty().html(h.join(""));var d=i.find("tr");for(var j=0;j<e.length;j++){c.data(d.eq(j)[0],"item",e[j])}}else{this._insertEmptyRow();this._showNoData()}this._setStyle();if(g.fullWidthRows&&this._loadCount<=1){this._fullWidthRows()}},_insertEmptyRow:function(){var d=this.$body;d.empty().html('<tbody><tr class="emptyRow"><td style="border: 0px;background: none;">&nbsp;</td></tr></tbody>')},_removeEmptyRow:function(){var d=this.$body;d.find("tr.emptyRow").remove()},_genColClass:function(d){return"mmg"+this._id+"-col"+d},_setStyle:function(){var d=this.$head;var e=this._expandThs();var f=this.$body;var h=this._leafCols();e.eq(0).addClass("first");e.eq(-1).addClass("last");f.find("tr,td").removeClass("even").removeClass("colSelected").removeClass("colSelectedEven");f.find("tr:odd").addClass("even");var g=c.inArray(d.find(".mmg-title").filter(function(){return c.data(this,"sortStatus")==="asc"||c(this).data("sortStatus")==="desc"}).parent().parent().data("col"),h);f.find("tr > td:nth-child("+(g+1)+")").addClass("colSelected").filter(":odd").addClass("colSelectedEven");this._resizeHeight()},_setColsWidth:function(){var d=this.opts;var e=this.$style;var n=this.$head;var h=this.$bodyWrapper;var m=this.$body;var o=this._expandThs();var i=this._expandCols(d.cols);var j=h.scrollTop();var l=n.position().left;h.width(9999);m.width("auto");var f=[];for(var q=0;q<o.length;q++){var r=o.eq(q);f.push(".mmGrid ."+this._genColClass(q)+" {");var g=c.data(r[0],"col-width");f.push("width: "+g+"px;");f.push("max-width: "+g+"px;");var k=i[q];if(k.align){f.push("text-align: "+k.align+";")}if(k.hidden){f.push("display: none; ")}f.push(" }")}m.detach();try{e.text(f.join(""))}catch(p){e[0].styleSheet.cssText=f.join("")}m.width(n.width()-2);h.width("100%");h.append(m);h.scrollLeft(-l);if(h.scrollLeft()===0){n.css("left",0)}h.scrollTop(j)},_fullWidthRows:function(){var e=this.opts;var h=this.$bodyWrapper;var t=this.$mmGrid;var p=this.$head;var o=h.width()-h[0].clientWidth;if(o&&a.isIE){o=o+1}var g=t.width()-p.width()-o;if(g<-20){return}var d=[];var q=this._leafThs();var s=this._leafCols();for(var n=0;n<s.length;n++){var j=s[n];var u=q.eq(n);if(!j.lockWidth&&u.is(":visible")){d.push(u)}}var k=Math.floor(g/d.length);var r=0;for(var n=0;n<d.length;n++){var u=d[n];var m=c.data(u[0],"col-width")+k;c.data(u[0],"col-width",m);var l=c.data(d[r][0],"col-width");if(l<m){r=n}}var f=g-k*d.length;var l=c.data(d[r][0],"col-width");c.data(d[r][0],"col-width",l+f);this._setColsWidth()},_showLoading:function(){var d=this.$mmGrid;d.find(".mmg-mask").show();var e=d.find(".mmg-loading");e.css({"left":(d.width()-e.width())/2,"top":(d.height()-e.height())/2}).show()},_hideLoading:function(){var d=this.$mmGrid;d.find(".mmg-mask").hide();d.find(".mmg-loading").hide()},_showNoData:function(){this._showMessage(this.opts.noDataText)},_showLoadError:function(){this._showMessage(this.opts.loadErrorText)},_showMessage:function(g){var d=this.$mmGrid;var f=this.$headWrapper;var e=d.find(".mmg-message");e.css({"left":(d.width()-e.width())/2,"top":(d.height()+f.height()-e.height())/2}).text(g).show()},_hideMessage:function(){var d=this.$mmGrid;d.find(".mmg-message").hide()},_nativeSorter:function(e,f){var g=this._leafCols();var d=g[e];this.$body.find("tr > td:nth-child("+(e+1)+")").sortElements(function(j,i){var k=c.text(c(j));var h=c.text(c(i));if(d.type==="number"){k=parseFloat(k);h=parseFloat(h)}else{return f==="desc"?-k.localeCompare(h):k.localeCompare(h)}return k>h?(f==="desc"?-1:1):(f==="desc"?1:-1)},function(){return this.parentNode})},_refreshSortStatus:function(){var e=this.$head.find("th");var d=-1;var f="";e.find(".mmg-title").each(function(h,i){var g=c.data(i,"sortStatus");if(g){d=h;f=g}});var f=f==="desc"?"asc":"desc";if(d>=0){e.eq(d).find(".mmg-title").data("sortStatus",f).click()}},_loadAjax:function(o){var n=this;var d=this.opts; +var j={};if(c.isFunction(d.params)){var f=d.params();if(!f){return}j=c.extend(j,f)}else{if(c.isPlainObject(d.params)){if(o){d.params=c.extend(j,o)}j=c.extend(j,d.params)}}if(d.remoteSort){var r="";var h="";var e=this.$head.find(".mmg-title");for(var s=0;s<e.length;s++){var k=c.data(e[s],"sortStatus");if(k){var g=e.eq(s).parent().parent().data("col");r=g.sortName?g.sortName:g.name;h=k}}if(r){j.sort=r+"."+h}}var q={};for(var l=0;l<this.opts.plugins.length;l++){var m=this.opts.plugins[l];c.extend(q,m.params())}j=c.extend(j,q);j=c.extend(j,o);n._showLoading();c.ajax({type:d.method,url:d.url,data:j,dataType:"json",cache:d.cache}).done(function(p){try{var i=p;if(c.isArray(p[d.root])){i=p[d.root]}n._populate(i);n._hideLoading();if(!d.remoteSort){n._refreshSortStatus()}if(p&&c.isArray(p[d.root])){p=c.extend(o,p)}n.$body.triggerHandler("loadSuccess",p)}catch(t){n._hideLoading();n._showLoadError();throw t}}).fail(function(i){n._hideLoading();n._showLoadError();n.$body.triggerHandler("loadError",i)})},_loadNative:function(d){this._populate(d);this._refreshSortStatus();this.$body.triggerHandler("loadSuccess",d)},load:function(d){try{var h="gzshangtao";var f=this.opts;this._hideMessage();this._loadCount=this._loadCount+1;if(c.isArray(d)){this._loadNative(d)}else{if(f.url){this._loadAjax(d)}else{if(f.items){this._loadNative(f.items)}else{this._loadNative([])}}}}catch(g){this._showLoadError();throw g}},resize:function(g){if(g&&g.width){this.opts.width=g.width}if(g&&g.height){this.opts.height=g.height}var h=this.opts;var d=this.$mmGrid;var i=this.$headWrapper;var k=this.$bodyWrapper;if(a.isIE6&&(!h.width||h.width==="auto")){d.width("100%");d.width(d.width()-(d.outerWidth(true)-d.width()))}else{d.width(h.width)}if(h.height!=="auto"){if(a.isIE6&&(!h.height||h.height==="auto")){d.height("100%");d.height(d.height()-(d.outerHeight(true)-d.height()))}else{d.height(h.height)}k.height(d.height()-i.outerHeight(true))}var f=d.find(".mmg-message");if(f.is(":visible")){f.css({"left":(d.width()-f.width())/2,"top":(d.height()+i.height()-f.height())/2})}var j=d.find(".mmg-mask");if(j.is(":visible")){j.width(d.width()).height(d.height());var e=d.find(".mmg-loading");e.css({"left":(d.width()-e.width())/2,"top":(d.height()-e.height())/2})}k.trigger("scroll");this._resizeHeight()},_resizeHeight:function(){var d=this.opts;var f=this.$bodyWrapper;var e=this.$body;if(d.height==="auto"&&a.isIE7){f.height("auto");if(f.width()<e.width()){f.height(f.height()+f.height()-f[0].clientHeight+1)}}},select:function(e){var h=this.opts;var i=this.$body;var d=this.$head;if(typeof e==="number"){var g=i.find("tr").eq(e);if(!h.multiSelect){i.find("tr.selected").removeClass("selected");if(h.checkCol){i.find("tr > td").find(".mmg-check").prop("checked","")}}if(!g.hasClass("selected")){g.addClass("selected");if(h.checkCol){g.find("td .mmg-check").prop("checked","checked")}}}else{if(typeof e==="function"){c.each(i.find("tr"),function(j){if(e(c.data(this,"item"),j)){var k=c(this);if(!k.hasClass("selected")){k.addClass("selected");if(h.checkCol){k.find("td .mmg-check").prop("checked","checked")}}}})}else{if(e===undefined||(typeof e==="string"&&e==="all")){i.find("tr.selected").removeClass("selected");i.find("tr").addClass("selected");i.find("tr > td").find(".mmg-check").prop("checked","checked")}else{return}}}if(h.checkCol){var f=i.find("tr > td").find(".mmg-check");if(f.length===f.filter(":checked").length){d.find("th .checkAll").prop("checked","checked")}}},deselect:function(e){var f=this.opts;var g=this.$body;var d=this.$head;if(typeof e==="number"){g.find("tr").eq(e).removeClass("selected");if(f.checkCol){g.find("tr").eq(e).find("td .mmg-check").prop("checked","")}}else{if(typeof e==="function"){c.each(g.find("tr"),function(h){if(e(c.data(this,"item"),h)){c(this).removeClass("selected");if(f.checkCol){c(this).find("td .mmg-check").prop("checked","")}}})}else{if(e===undefined||(typeof e==="string"&&e==="all")){g.find("tr.selected").removeClass("selected");if(f.checkCol){g.find("tr > td").find(".mmg-check").prop("checked","")}}else{return}}}d.find("th .checkAll").prop("checked","")},selectedRows:function(){var e=this.$body;var d=[];c.each(e.find("tr.selected"),function(f,g){d.push(c.data(this,"item"))});return d},selectedRowsIndex:function(){var f=this.$body;var d=this.$body.find("tr");var e=[];c.each(f.find("tr.selected"),function(g){e.push(d.index(this))});return e},rows:function(){var e=this.$body;var d=[];c.each(e.find("tr"),function(){d.push(c.data(this,"item"))});return d},row:function(d){var f=this.$body;if(d!==undefined&&d>=0){var e=f.find("tr").eq(d);if(e.length!==0){return c.data(e[0],"item")}}},rowsLength:function(){var e=this.$body;var d=e.find("tr").length;if(d===1&&e.find("tr.emptyRow").length===1){return 0}return d},addRow:function(h,e){var d=this.$body.find("tbody");if(c.isArray(h)){for(var f=h.length-1;f>=0;f--){this.addRow(h[f],e)}return}if(!c.isPlainObject(h)){return}this._hideMessage();this._removeEmptyRow();var g;if(e===undefined||e<0){g=c(this._rowHtml(h,this.rowsLength())); +d.append(g)}else{g=c(this._rowHtml(h,e));if(e===0){d.prepend(g)}else{var j=d.find("tr").eq(e-1);if(j.length===0){d.append(g)}else{j.after(c(g))}}}g.data("item",h);this._setStyle();this.$body.triggerHandler("rowInserted",[h,e])},updateRow:function(i,e){var h=this.opts;var d=this.$body.find("tbody");if(!c.isPlainObject(i)){return}var j=this.row(e);var g=d.find("tr").eq(e);var f=g.find("td:first :checkbox").is(":checked");g.html(this._rowHtml(i,e).slice(4,-5));if(h.checkCol){g.find("td:first :checkbox").prop("checked",f)}g.data("item",i);this._setStyle();this.$body.triggerHandler("rowUpdated",[j,i,e])},removeRow:function(f){var j=this;var d=j.$body.find("tbody");if(c.isArray(f)){for(var g=f.length-1;g>=0;g--){j.removeRow(f[g])}return}if(f===undefined){var e=d.find("tr");for(var g=e.length-1;g>=0;g--){j.removeRow(g)}}else{var h=j.row(f);d.find("tr").eq(f).remove();this.$body.triggerHandler("rowRemoved",[h,f])}this._setStyle();if(this.rowsLength()===0){this._showNoData();this._insertEmptyRow()}}};c.fn.mmGrid=function(){if(arguments.length===0||typeof arguments[0]==="object"){var g=arguments[0],h=this.data("mmGrid"),e=c.extend(true,{},c.fn.mmGrid.defaults,g);if(!h){h=new b(this,e);this.data("mmGrid",h)}return c.extend(true,this,h)}if(typeof arguments[0]==="string"){var h=this.data("mmGrid");var f=h[arguments[0]];if(f){var d=Array.prototype.slice.call(arguments);return f.apply(h,d.slice(1))}}};c.fn.mmGrid.defaults={width:"auto",height:"280px",cols:[],url:false,params:{},method:"POST",cache:false,root:"items",items:[],autoLoad:true,remoteSort:false,sortName:"",sortStatus:"asc",loadingText:"正在载入...",noDataText:"没有数据",loadErrorText:"数据加载出现异常",multiSelect:false,checkCol:false,indexCol:false,indexColWidth:40,fullWidthRows:false,nowrap:false,showBackboard:true,backboardMinHeight:125,plugins:[]};c.fn.mmGrid.Constructor=b;c.fn.sortElements=(function(){var d=[].sort;return function(f,g){g=g||function(){return this};var e=this.map(function(){var i=g.call(this),h=i.parentNode,j=h.insertBefore(document.createTextNode(""),i.nextSibling);return function(){if(h===this){throw new Error("You can't sort elements if any one is a descendant of another.")}h.insertBefore(this,j);h.removeChild(j)}});return d.call(this,f).each(function(h){e[h].call(g.call(this))})}})()}(window.jQuery);!function(a){var b=function(d,c){this.$el=a(d);this.opts=c};b.prototype={_initLayout:function(){var e=this;var c=this.$el;var d=this.opts;c.addClass("mmPaginator");var g=['<div class="totalCountLabel"></div>','<ul class="pageList"></ul>','<div class="limit"><select></select></div>'];c.append(a(g.join("")));this.$totalCountLabel=c.find(".totalCountLabel");this.$pageList=c.find(".pageList");this.$limitList=c.find(".limit select");var f=this.$limitList;a.each(d.limitList,function(){var h=a("<option></option>").prop("value",this).text(e.formatString(d.limitLabel,[this]));f.append(h)});f.on("change",function(){c.data("page",1);e.$mmGrid.load()})},_plain:function(k,m,e){var h=this;var o=this.$el;var n=this.$pageList;var g=m%e===0?parseInt(m/e):parseInt(m/e)+1;g=g?g:0;if(g===0){k=1}else{if(k>g){k=g}else{if(k<1&&g!=0){k=1}}}var c=a('<li class="prev"><a>«</a></li>');if(k<=1){c.addClass("disable")}else{c.find("a").on("click",function(){o.data("page",k-1);h.$mmGrid.load()})}n.append(c);var j=[1];if(k>4){j.push("...")}for(var f=0;f<5;f++){var l=k-2+f;if(l>1&&l<=g-1){j.push(l)}}if(k+1<g-1){j.push("...")}if(g>1){j.push(g)}a.each(j,function(i,p){var q=a("<li><a></a></li>");if(p==="..."){q.addClass("").html("...")}else{if(p===k){q.addClass("active").find("a").text(p)}else{q.find("a").text(p).prop("title","第"+p+"页").on("click",function(r){o.data("page",p);h.$mmGrid.load()})}}n.append(q)});var d=a('<li class="next"><a title="下一页">»</a></li>');if(k>=g){d.addClass("disable")}else{d.find("a").on("click",function(){o.data("page",k+1);h.$mmGrid.load()})}n.append(d)},_search:function(e,d,c){},load:function(i){var e=this.$el;var h=this.$limitList;var f=this.opts;if(!i){i={}}var g=i[f.pageParamName];if(g===undefined||g===null){g=e.data("page")}e.data("page",g);var d=i[f.totalCountName];if(d===undefined){d=0}e.data("totalCount",d);var c=i[f.limitParamName];if(!c){c=h.val()}this.$limitList.val(c);this.$totalCountLabel.html(this.formatString(f.totalCountLabel,[d]));this.$pageList.empty();this._plain(g,d,this.$limitList.val())},formatString:function(d,c){return d.replace(/{(\d+)}/g,function(e,f){return typeof c[f]!="undefined"?c[f]:e})},params:function(){var d=this.opts;var c=this.$el;var e=this.$limitList;var f={};f[d.pageParamName]=c.data("page");f[d.limitParamName]=e.val();return f},init:function(c){var f=this;var e=f.opts;this.$mmGrid=c;this._initLayout();this.$mmGrid.on("loadSuccess",function(i,h){f.load(h)});var g={};g[e.totalCountName]=0;g[e.pageParamName]=e.page;g[e.limitParamName]=e.limit;this.load(g);if(c.opts.indexCol){var d=c.opts.cols[0];d.renderer=function(j,h,k){var i=f.params();return'<label class="mmg-index">'+(k+1+((i[e.pageParamName]-1)*i[e.limitParamName]))+"</label>" +}}}};a.fn.mmPaginator=function(){if(arguments.length===0||typeof arguments[0]==="object"){var f=arguments[0],g=this.data("mmPaginator"),d=a.extend(true,{},a.fn.mmPaginator.defaults,f);if(!g){g=new b(this[0],d);this.data("mmPaginator",g)}return a.extend(true,this,g)}if(typeof arguments[0]==="string"){var g=this.data("mmPaginator");var e=g[arguments[0]];if(e){var c=Array.prototype.slice.call(arguments);return e.apply(g,c.slice(1))}}};a.fn.mmPaginator.defaults={style:"plain",totalCountName:"totalCount",page:1,pageParamName:"page",limitParamName:"limit",limitLabel:"每页{0}条",totalCountLabel:"共<span>{0}</span>条记录",limit:undefined,limitList:[20,30,40,50]};a.fn.mmPaginator.Constructor=b}(window.jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/js/wstgridtree.js b/hyhproject/admin/view/js/wstgridtree.js new file mode 100755 index 0000000..d7d7853 --- /dev/null +++ b/hyhproject/admin/view/js/wstgridtree.js @@ -0,0 +1 @@ +$.fn.WSTGridTree=function(k){var j=(new Date().getTime()+Math.round(Math.random()*700));var f={id:"wst_"+j,tbodyId:"wst_tbody_"+j,width:"100%",headerRowHeight:28,rowHeight:28,nodeNum:0,params:{},level:0};var a=$.extend(f,k);var i=$(this);var d;var c=function(){var o=[],l,p,m;o.push('<table class="mmg-head wst-grid-tree" cellspacing="0" cellpadding="0" width="'+a.width+'"><thead id="'+a.tbodyId+'" class="mmg-headWrapper"><tr height="'+a.headerRowHeight+'" class="mmg-head wst-grid-tree-hd">');if(a.rownumbers){o.push('<td class="wst-grid-tree-hd-cell first" style="width:26px;">#</td>')}for(var n=0;n<a.columns.length;n++){l=a.columns[n];m=l.width?('width="'+l.width+'"'):"";if(l.id){d=l.id;o.push('<td class="wst-grid-tree-hd-cell" style="text-align:left;padding-left:5px;" '+m+">"+l.display+"</td>")}else{p=(l.align?(' style="text-align:'+l.align+'" '):"");o.push('<td class="wst-grid-tree-hd-cell" '+p+" "+m+">"+l.display+"</td>")}}o.push("</tr></thead></table>");$(i).html(o.join(""))};var h=function(){var l=$.extend(a,{pid:a.tbodyId,params:{},level:0});b(l)};var b=function(l){$("tr[id^='"+a.pid+"_']").remove();$.getJSON(l.url,l.params,function(v,o){if(v.Rows){var x,r,m,p,y,q,n,w;v=v.Rows;var z=a.pid;for(var u=0;u<v.length;u++){m=v[u];n=l.pid+"_"+a.nodeNum;a.nodeNum++;x=[];x.push('<tr id="'+n+'" height="'+a.rowHeight+'" class="mmg mmg-body wst-grid-tree-row j-'+m[d]+'" dataid="'+m[d]+'" pdataid="'+n+'" lv="'+l.level+'">');if(a.rownumbers){x.push('<td class="wst-grid-tree-row-cell first"><label class="mmg-index" style="margin-right:0px">'+(u+1)+"</label></td>")}for(var t=0;t<a.columns.length;t++){r=a.columns[t];if(r.render){p=r.render(m)}else{p=m[r.name]}q=r.width?('width="'+r.width+'"'):"";if(r.id){w="";for(var s=0;s<l.level;s++){w+='<div class="wst-grid-tree-space"></div>'}w+='<div class="l-grid-tree-link fa fa-folder wst-tree-img" dataid="'+m[d]+'" pdataid="'+n+'" lv="'+l.level+'"></div>';x.push('<td class="wst-grid-tree-row-cell" style="text-align:left" '+q+">"+w+p+"</td>")}else{y=(r.align?(' style="text-align:'+r.align+'" '):"");x.push('<td class="wst-grid-tree-row-cell" '+y+" "+q+">"+p+"</td>")}}x.push("</tr>");$(x.join("")).insertAfter($("#"+z));z=n;$("#"+n+" .wst-tree-img").click(function(){if($(this).hasClass("fa-folder")){$(this).removeClass("fa-folder").addClass("fa-folder-open");if($("tr[id^='"+$(this).attr("pdataid")+"_']").size()==0){l.pid=$(this).attr("pdataid");l.params[d]=$(this).attr("dataid");l.level=parseInt($(this).attr("lv"),10)+1;b(l)}else{$("tr[id^='"+$(this).attr("pdataid")+"_']").each(function(){$(this).show()})}}else{$(this).removeClass("fa-folder-open").addClass("fa-folder");$("tr[id^='"+$(this).attr("pdataid")+"_']").each(function(){$(this).hide()})}g();e()})}g();e()}if(a.callback){a.callback()}})};var g=function(){var l=false;$(".wst-grid-tree-row").each(function(){$(this).removeClass("bg-color");if($(this).is(":visible")){if(l){$(this).addClass("bg-color")}l=!l;$(this).click(function(){$(this).addClass("row-selected").siblings().removeClass("row-selected");$(this).addClass("row-selected").siblings().each(function(){if($(this).hasClass("bg-color2")&&!$(this).hasClass("row-selected")){$(this).removeClass("bg-color2").addClass("bg-color")}})})}})};var e=function(){var l=1;$(".wst-grid-tree-row").each(function(){if($(this).is(":visible")){$(this).find(".l-grid-row-cell-rownumbers").html(l++)}})};c();h();return{reload:function(o){if(o&&o>0){var l=$(".j-"+o);var n={params:{}};n["pid"]=l.attr("id");n["params"][d]=o;n["level"]=parseInt(l.attr("lv"),10)+1;var m=$.extend(a,n);b(m)}else{h()}}}}; \ No newline at end of file diff --git a/hyhproject/admin/view/js/ztree/css/demo.css b/hyhproject/admin/view/js/ztree/css/demo.css new file mode 100755 index 0000000..f6dba0d --- /dev/null +++ b/hyhproject/admin/view/js/ztree/css/demo.css @@ -0,0 +1,33 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0;padding: 0;border: 0;outline: 0;font-weight: inherit;font-style: inherit;font-size: 100%;font-family: inherit;vertical-align: baseline;} +body {color: #2f332a;font: 15px/21px Arial, Helvetica, simsun, sans-serif;background: #f0f6e4 \9;} +h1, h2, h3, h4, h5, h6 {color: #2f332a;font-weight: bold;font-family: Helvetica, Arial, sans-serif;padding-bottom: 5px;} +h1 {font-size: 24px;line-height: 34px;text-align: center;} +h2 {font-size: 14px;line-height: 24px;padding-top: 5px;} +h6 {font-weight: normal;font-size: 12px;letter-spacing: 1px;line-height: 24px;text-align: center;} +a {color:#3C6E31;text-decoration: underline;} +a:hover {background-color:#3C6E31;color:white;} +input.radio {margin: 0 2px 0 8px;} +input.radio.first {margin-left:0;} +input.empty {color: lightgray;} +code {color: #2f332a;} +.highlight_red {color:#A60000;} +.highlight_green {color:#A7F43D;} +li {list-style: circle;font-size: 12px;} +li.title {list-style: none;} +ul.list {margin-left: 17px;} + +div.content_wrap {width: 600px;height:380px;} +div.content_wrap div.left{float: left;width: 250px;} +div.content_wrap div.right{float: right;width: 340px;} +div.zTreeDemoBackground {width:250px;height:362px;text-align:left;} + +ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #f0f6e4;width:220px;height:360px;overflow-y:scroll;overflow-x:auto;} +ul.log {border: 1px solid #617775;background: #f0f6e4;width:300px;height:170px;overflow: hidden;} +ul.log.small {height:45px;} +ul.log li {color: #666666;list-style: none;padding-left: 10px;} +ul.log li.dark {background-color: #E3E3E3;} + +/* ruler */ +div.ruler {height:20px; width:220px; background-color:#f0f6e4;border: 1px solid #333; margin-bottom: 5px; cursor: pointer} +div.ruler div.cursor {height:20px; width:30px; background-color:#3C6E31; color:white; text-align: right; padding-right: 5px; cursor: pointer} \ No newline at end of file diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_close.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_close.png new file mode 100755 index 0000000..68ccb3c Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_close.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_open.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_open.png new file mode 100755 index 0000000..d6ff36d Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/1_open.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/2.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/2.png new file mode 100755 index 0000000..9eff506 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/2.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/3.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/3.png new file mode 100755 index 0000000..d7ba6d0 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/3.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/4.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/4.png new file mode 100755 index 0000000..753e2bf Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/4.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/5.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/5.png new file mode 100755 index 0000000..0c5eccd Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/5.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/6.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/6.png new file mode 100755 index 0000000..070b835 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/6.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/7.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/7.png new file mode 100755 index 0000000..532b037 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/7.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/8.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/8.png new file mode 100755 index 0000000..a8f3a86 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/8.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/9.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/9.png new file mode 100755 index 0000000..4db73cd Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/diy/9.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/line_conn.gif b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/line_conn.gif new file mode 100755 index 0000000..d561d36 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/line_conn.gif differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/loading.gif b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/loading.gif new file mode 100755 index 0000000..e8c2892 Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/loading.gif differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.gif b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.gif new file mode 100755 index 0000000..50c94fd Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.gif differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.png b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.png new file mode 100755 index 0000000..ffda01e Binary files /dev/null and b/hyhproject/admin/view/js/ztree/css/zTreeStyle/img/zTreeStandard.png differ diff --git a/hyhproject/admin/view/js/ztree/css/zTreeStyle/zTreeStyle.css b/hyhproject/admin/view/js/ztree/css/zTreeStyle/zTreeStyle.css new file mode 100755 index 0000000..4a1705b --- /dev/null +++ b/hyhproject/admin/view/js/ztree/css/zTreeStyle/zTreeStyle.css @@ -0,0 +1,97 @@ +/*------------------------------------- +zTree Style + +version: 3.5.19 +author: Hunter.z +email: hunter.z@263.net +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ + +.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} +.ztree {margin:0; padding:5px; color:#333} +.ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} +.ztree li ul{ margin:0; padding:0 0 0 18px} +.ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;} + +.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent; + text-decoration:none; vertical-align:top; display: inline-block} +.ztree li a:hover {text-decoration:underline} +.ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid; + opacity:0.8; filter:alpha(opacity=80)} +.ztree li a.tmpTargetNode_prev {} +.ztree li a.tmpTargetNode_next {} +.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; + font-size:12px; border:1px #7EC4CC solid; *border:0px} +.ztree li span {line-height:16px; margin-right:2px} +.ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; + border:0 none; cursor: pointer;outline:none; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +.ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto} +.ztree li span.button.chk.checkbox_false_full {background-position:0 0} +.ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px} +.ztree li span.button.chk.checkbox_false_part {background-position:0 -28px} +.ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px} +.ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} +.ztree li span.button.chk.checkbox_true_full {background-position:-14px 0} +.ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px} +.ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px} +.ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px} +.ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} +.ztree li span.button.chk.radio_false_full {background-position:-28px 0} +.ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px} +.ztree li span.button.chk.radio_false_part {background-position:-28px -28px} +.ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px} +.ztree li span.button.chk.radio_false_disable {background-position:-28px -56px} +.ztree li span.button.chk.radio_true_full {background-position:-42px 0} +.ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px} +.ztree li span.button.chk.radio_true_part {background-position:-42px -28px} +.ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px} +.ztree li span.button.chk.radio_true_disable {background-position:-42px -56px} + +.ztree li span.button.switch {width:18px; height:18px} +.ztree li span.button.root_open{background-position:-92px -54px} +.ztree li span.button.root_close{background-position:-74px -54px} +.ztree li span.button.roots_open{background-position:-92px 0} +.ztree li span.button.roots_close{background-position:-74px 0} +.ztree li span.button.center_open{background-position:-92px -18px} +.ztree li span.button.center_close{background-position:-74px -18px} +.ztree li span.button.bottom_open{background-position:-92px -36px} +.ztree li span.button.bottom_close{background-position:-74px -36px} +.ztree li span.button.noline_open{background-position:-92px -72px} +.ztree li span.button.noline_close{background-position:-74px -72px} +.ztree li span.button.root_docu{ background:none;} +.ztree li span.button.roots_docu{background-position:-56px 0} +.ztree li span.button.center_docu{background-position:-56px -18px} +.ztree li span.button.bottom_docu{background-position:-56px -36px} +.ztree li span.button.noline_docu{ background:none;} + +.ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} + +.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} + +ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} + +span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} +.zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} + +/* level style*/ +/*.ztree li span.button.level0 { + display:none; +} +.ztree li ul.level0 { + padding:0; + background:none; +}*/ \ No newline at end of file diff --git a/hyhproject/admin/view/js/ztree/jquery.ztree.all-3.5.js b/hyhproject/admin/view/js/ztree/jquery.ztree.all-3.5.js new file mode 100755 index 0000000..ba73b78 --- /dev/null +++ b/hyhproject/admin/view/js/ztree/jquery.ztree.all-3.5.js @@ -0,0 +1,16 @@ +(function($){var settings={},roots={},caches={},_consts={className:{BUTTON:"button",LEVEL:"level",ICO_LOADING:"ico_loading",SWITCH:"switch",NAME:"node_name"},event:{NODECREATED:"ztree_nodeCreated",CLICK:"ztree_click",EXPAND:"ztree_expand",COLLAPSE:"ztree_collapse",ASYNC_SUCCESS:"ztree_async_success",ASYNC_ERROR:"ztree_async_error",REMOVE:"ztree_remove",SELECTED:"ztree_selected",UNSELECTED:"ztree_unselected"},id:{A:"_a",ICON:"_ico",SPAN:"_span",SWITCH:"_switch",UL:"_ul"},line:{ROOT:"root",ROOTS:"roots",CENTER:"center",BOTTOM:"bottom",NOLINE:"noline",LINE:"line"},folder:{OPEN:"open",CLOSE:"close",DOCU:"docu"},node:{CURSELECTED:"curSelectedNode"}},_setting={treeId:"",treeObj:null,view:{addDiyDom:null,autoCancelSelected:true,dblClickExpand:true,expandSpeed:"fast",fontCss:{},nameIsHTML:false,selectedMulti:true,showIcon:true,showLine:true,showTitle:true,txtSelectedEnable:false},data:{key:{children:"children",name:"name",title:"",url:"url",icon:"icon"},simpleData:{enable:false,idKey:"id",pIdKey:"pId",rootPId:null},keep:{parent:false,leaf:false}},async:{enable:false,contentType:"application/x-www-form-urlencoded",type:"post",dataType:"text",url:"",autoParam:[],otherParam:[],dataFilter:null},callback:{beforeAsync:null,beforeClick:null,beforeDblClick:null,beforeRightClick:null,beforeMouseDown:null,beforeMouseUp:null,beforeExpand:null,beforeCollapse:null,beforeRemove:null,onAsyncError:null,onAsyncSuccess:null,onNodeCreated:null,onClick:null,onDblClick:null,onRightClick:null,onMouseDown:null,onMouseUp:null,onExpand:null,onCollapse:null,onRemove:null}},_initRoot=function(setting){var r=data.getRoot(setting);if(!r){r={};data.setRoot(setting,r)}r[setting.data.key.children]=[];r.expandTriggerFlag=false;r.curSelectedList=[];r.noSelection=true;r.createdNodes=[];r.zId=0;r._ver=(new Date()).getTime()},_initCache=function(setting){var c=data.getCache(setting);if(!c){c={};data.setCache(setting,c)}c.nodes=[];c.doms=[]},_bindEvent=function(setting){var o=setting.treeObj,c=consts.event;o.bind(c.NODECREATED,function(event,treeId,node){tools.apply(setting.callback.onNodeCreated,[event,treeId,node])});o.bind(c.CLICK,function(event,srcEvent,treeId,node,clickFlag){tools.apply(setting.callback.onClick,[srcEvent,treeId,node,clickFlag])});o.bind(c.EXPAND,function(event,treeId,node){tools.apply(setting.callback.onExpand,[event,treeId,node])});o.bind(c.COLLAPSE,function(event,treeId,node){tools.apply(setting.callback.onCollapse,[event,treeId,node])});o.bind(c.ASYNC_SUCCESS,function(event,treeId,node,msg){tools.apply(setting.callback.onAsyncSuccess,[event,treeId,node,msg])});o.bind(c.ASYNC_ERROR,function(event,treeId,node,XMLHttpRequest,textStatus,errorThrown){tools.apply(setting.callback.onAsyncError,[event,treeId,node,XMLHttpRequest,textStatus,errorThrown])});o.bind(c.REMOVE,function(event,treeId,treeNode){tools.apply(setting.callback.onRemove,[event,treeId,treeNode])});o.bind(c.SELECTED,function(event,treeId,node){tools.apply(setting.callback.onSelected,[treeId,node])});o.bind(c.UNSELECTED,function(event,treeId,node){tools.apply(setting.callback.onUnSelected,[treeId,node])})},_unbindEvent=function(setting){var o=setting.treeObj,c=consts.event;o.unbind(c.NODECREATED).unbind(c.CLICK).unbind(c.EXPAND).unbind(c.COLLAPSE).unbind(c.ASYNC_SUCCESS).unbind(c.ASYNC_ERROR).unbind(c.REMOVE).unbind(c.SELECTED).unbind(c.UNSELECTED)},_eventProxy=function(event){var target=event.target,setting=data.getSetting(event.data.treeId),tId="",node=null,nodeEventType="",treeEventType="",nodeEventCallback=null,treeEventCallback=null,tmp=null;if(tools.eqs(event.type,"mousedown")){treeEventType="mousedown"}else{if(tools.eqs(event.type,"mouseup")){treeEventType="mouseup"}else{if(tools.eqs(event.type,"contextmenu")){treeEventType="contextmenu"}else{if(tools.eqs(event.type,"click")){if(tools.eqs(target.tagName,"span")&&target.getAttribute("treeNode"+consts.id.SWITCH)!==null){tId=tools.getNodeMainDom(target).id;nodeEventType="switchNode"}else{tmp=tools.getMDom(setting,target,[{tagName:"a",attrName:"treeNode"+consts.id.A}]);if(tmp){tId=tools.getNodeMainDom(tmp).id;nodeEventType="clickNode"}}}else{if(tools.eqs(event.type,"dblclick")){treeEventType="dblclick";tmp=tools.getMDom(setting,target,[{tagName:"a",attrName:"treeNode"+consts.id.A}]);if(tmp){tId=tools.getNodeMainDom(tmp).id;nodeEventType="switchNode"}}}}}}if(treeEventType.length>0&&tId.length==0){tmp=tools.getMDom(setting,target,[{tagName:"a",attrName:"treeNode"+consts.id.A}]);if(tmp){tId=tools.getNodeMainDom(tmp).id}}if(tId.length>0){node=data.getNodeCache(setting,tId);switch(nodeEventType){case"switchNode":if(!node.isParent){nodeEventType=""}else{if(tools.eqs(event.type,"click")||(tools.eqs(event.type,"dblclick")&&tools.apply(setting.view.dblClickExpand,[setting.treeId,node],setting.view.dblClickExpand))){nodeEventCallback=handler.onSwitchNode}else{nodeEventType=""}}break;case"clickNode":nodeEventCallback=handler.onClickNode;break}}switch(treeEventType){case"mousedown":treeEventCallback=handler.onZTreeMousedown;break; +case"mouseup":treeEventCallback=handler.onZTreeMouseup;break;case"dblclick":treeEventCallback=handler.onZTreeDblclick;break;case"contextmenu":treeEventCallback=handler.onZTreeContextmenu;break}var proxyResult={stop:false,node:node,nodeEventType:nodeEventType,nodeEventCallback:nodeEventCallback,treeEventType:treeEventType,treeEventCallback:treeEventCallback};return proxyResult},_initNode=function(setting,level,n,parentNode,isFirstNode,isLastNode,openFlag){if(!n){return}var r=data.getRoot(setting),childKey=setting.data.key.children;n.level=level;n.tId=setting.treeId+"_"+(++r.zId);n.parentTId=parentNode?parentNode.tId:null;n.open=(typeof n.open=="string")?tools.eqs(n.open,"true"):!!n.open;if(n[childKey]&&n[childKey].length>0){n.isParent=true;n.zAsync=true}else{n.isParent=(typeof n.isParent=="string")?tools.eqs(n.isParent,"true"):!!n.isParent;n.open=(n.isParent&&!setting.async.enable)?n.open:false;n.zAsync=!n.isParent}n.isFirstNode=isFirstNode;n.isLastNode=isLastNode;n.getParentNode=function(){return data.getNodeCache(setting,n.parentTId)};n.getPreNode=function(){return data.getPreNode(setting,n)};n.getNextNode=function(){return data.getNextNode(setting,n)};n.getIndex=function(){return data.getNodeIndex(setting,n)};n.getPath=function(){return data.getNodePath(setting,n)};n.isAjaxing=false;data.fixPIdKeyValue(setting,n)},_init={bind:[_bindEvent],unbind:[_unbindEvent],caches:[_initCache],nodes:[_initNode],proxys:[_eventProxy],roots:[_initRoot],beforeA:[],afterA:[],innerBeforeA:[],innerAfterA:[],zTreeTools:[]},data={addNodeCache:function(setting,node){data.getCache(setting).nodes[data.getNodeCacheId(node.tId)]=node},getNodeCacheId:function(tId){return tId.substring(tId.lastIndexOf("_")+1)},addAfterA:function(afterA){_init.afterA.push(afterA)},addBeforeA:function(beforeA){_init.beforeA.push(beforeA)},addInnerAfterA:function(innerAfterA){_init.innerAfterA.push(innerAfterA)},addInnerBeforeA:function(innerBeforeA){_init.innerBeforeA.push(innerBeforeA)},addInitBind:function(bindEvent){_init.bind.push(bindEvent)},addInitUnBind:function(unbindEvent){_init.unbind.push(unbindEvent)},addInitCache:function(initCache){_init.caches.push(initCache)},addInitNode:function(initNode){_init.nodes.push(initNode)},addInitProxy:function(initProxy,isFirst){if(!!isFirst){_init.proxys.splice(0,0,initProxy)}else{_init.proxys.push(initProxy)}},addInitRoot:function(initRoot){_init.roots.push(initRoot)},addNodesData:function(setting,parentNode,index,nodes){var childKey=setting.data.key.children,params;if(!parentNode[childKey]){parentNode[childKey]=[];index=-1}else{if(index>=parentNode[childKey].length){index=-1}}if(parentNode[childKey].length>0&&index===0){parentNode[childKey][0].isFirstNode=false;view.setNodeLineIcos(setting,parentNode[childKey][0])}else{if(parentNode[childKey].length>0&&index<0){parentNode[childKey][parentNode[childKey].length-1].isLastNode=false;view.setNodeLineIcos(setting,parentNode[childKey][parentNode[childKey].length-1])}}parentNode.isParent=true;if(index<0){parentNode[childKey]=parentNode[childKey].concat(nodes)}else{params=[index,0].concat(nodes);parentNode[childKey].splice.apply(parentNode[childKey],params)}},addSelectedNode:function(setting,node){var root=data.getRoot(setting);if(!data.isSelectedNode(setting,node)){root.curSelectedList.push(node)}},addCreatedNode:function(setting,node){if(!!setting.callback.onNodeCreated||!!setting.view.addDiyDom){var root=data.getRoot(setting);root.createdNodes.push(node)}},addZTreeTools:function(zTreeTools){_init.zTreeTools.push(zTreeTools)},exSetting:function(s){$.extend(true,_setting,s)},fixPIdKeyValue:function(setting,node){if(setting.data.simpleData.enable){node[setting.data.simpleData.pIdKey]=node.parentTId?node.getParentNode()[setting.data.simpleData.idKey]:setting.data.simpleData.rootPId}},getAfterA:function(setting,node,array){for(var i=0,j=_init.afterA.length;i<j;i++){_init.afterA[i].apply(this,arguments)}},getBeforeA:function(setting,node,array){for(var i=0,j=_init.beforeA.length;i<j;i++){_init.beforeA[i].apply(this,arguments)}},getInnerAfterA:function(setting,node,array){for(var i=0,j=_init.innerAfterA.length;i<j;i++){_init.innerAfterA[i].apply(this,arguments)}},getInnerBeforeA:function(setting,node,array){for(var i=0,j=_init.innerBeforeA.length;i<j;i++){_init.innerBeforeA[i].apply(this,arguments)}},getCache:function(setting){return caches[setting.treeId]},getNodeIndex:function(setting,node){if(!node){return null}var childKey=setting.data.key.children,p=node.parentTId?node.getParentNode():data.getRoot(setting);for(var i=0,l=p[childKey].length-1;i<=l;i++){if(p[childKey][i]===node){return i}}return -1},getNextNode:function(setting,node){if(!node){return null}var childKey=setting.data.key.children,p=node.parentTId?node.getParentNode():data.getRoot(setting);for(var i=0,l=p[childKey].length-1;i<=l;i++){if(p[childKey][i]===node){return(i==l?null:p[childKey][i+1])}}return null},getNodeByParam:function(setting,nodes,key,value){if(!nodes||!key){return null}var childKey=setting.data.key.children; +for(var i=0,l=nodes.length;i<l;i++){if(nodes[i][key]==value){return nodes[i]}var tmp=data.getNodeByParam(setting,nodes[i][childKey],key,value);if(tmp){return tmp}}return null},getNodeCache:function(setting,tId){if(!tId){return null}var n=caches[setting.treeId].nodes[data.getNodeCacheId(tId)];return n?n:null},getNodeName:function(setting,node){var nameKey=setting.data.key.name;return""+node[nameKey]},getNodePath:function(setting,node){if(!node){return null}var path;if(node.parentTId){path=node.getParentNode().getPath()}else{path=[]}if(path){path.push(node)}return path},getNodeTitle:function(setting,node){var t=setting.data.key.title===""?setting.data.key.name:setting.data.key.title;return""+node[t]},getNodes:function(setting){return data.getRoot(setting)[setting.data.key.children]},getNodesByParam:function(setting,nodes,key,value){if(!nodes||!key){return[]}var childKey=setting.data.key.children,result=[];for(var i=0,l=nodes.length;i<l;i++){if(nodes[i][key]==value){result.push(nodes[i])}result=result.concat(data.getNodesByParam(setting,nodes[i][childKey],key,value))}return result},getNodesByParamFuzzy:function(setting,nodes,key,value){if(!nodes||!key){return[]}var childKey=setting.data.key.children,result=[];value=value.toLowerCase();for(var i=0,l=nodes.length;i<l;i++){if(typeof nodes[i][key]=="string"&&nodes[i][key].toLowerCase().indexOf(value)>-1){result.push(nodes[i])}result=result.concat(data.getNodesByParamFuzzy(setting,nodes[i][childKey],key,value))}return result},getNodesByFilter:function(setting,nodes,filter,isSingle,invokeParam){if(!nodes){return(isSingle?null:[])}var childKey=setting.data.key.children,result=isSingle?null:[];for(var i=0,l=nodes.length;i<l;i++){if(tools.apply(filter,[nodes[i],invokeParam],false)){if(isSingle){return nodes[i]}result.push(nodes[i])}var tmpResult=data.getNodesByFilter(setting,nodes[i][childKey],filter,isSingle,invokeParam);if(isSingle&&!!tmpResult){return tmpResult}result=isSingle?tmpResult:result.concat(tmpResult)}return result},getPreNode:function(setting,node){if(!node){return null}var childKey=setting.data.key.children,p=node.parentTId?node.getParentNode():data.getRoot(setting);for(var i=0,l=p[childKey].length;i<l;i++){if(p[childKey][i]===node){return(i==0?null:p[childKey][i-1])}}return null},getRoot:function(setting){return setting?roots[setting.treeId]:null},getRoots:function(){return roots},getSetting:function(treeId){return settings[treeId]},getSettings:function(){return settings},getZTreeTools:function(treeId){var r=this.getRoot(this.getSetting(treeId));return r?r.treeTools:null},initCache:function(setting){for(var i=0,j=_init.caches.length;i<j;i++){_init.caches[i].apply(this,arguments)}},initNode:function(setting,level,node,parentNode,preNode,nextNode){for(var i=0,j=_init.nodes.length;i<j;i++){_init.nodes[i].apply(this,arguments)}},initRoot:function(setting){for(var i=0,j=_init.roots.length;i<j;i++){_init.roots[i].apply(this,arguments)}},isSelectedNode:function(setting,node){var root=data.getRoot(setting);for(var i=0,j=root.curSelectedList.length;i<j;i++){if(node===root.curSelectedList[i]){return true}}return false},removeNodeCache:function(setting,node){var childKey=setting.data.key.children;if(node[childKey]){for(var i=0,l=node[childKey].length;i<l;i++){data.removeNodeCache(setting,node[childKey][i])}}data.getCache(setting).nodes[data.getNodeCacheId(node.tId)]=null},removeSelectedNode:function(setting,node){var root=data.getRoot(setting);for(var i=0,j=root.curSelectedList.length;i<j;i++){if(node===root.curSelectedList[i]||!data.getNodeCache(setting,root.curSelectedList[i].tId)){root.curSelectedList.splice(i,1);setting.treeObj.trigger(consts.event.UNSELECTED,[setting.treeId,node]);i--;j--}}},setCache:function(setting,cache){caches[setting.treeId]=cache},setRoot:function(setting,root){roots[setting.treeId]=root},setZTreeTools:function(setting,zTreeTools){for(var i=0,j=_init.zTreeTools.length;i<j;i++){_init.zTreeTools[i].apply(this,arguments)}},transformToArrayFormat:function(setting,nodes){if(!nodes){return[]}var childKey=setting.data.key.children,r=[];if(tools.isArray(nodes)){for(var i=0,l=nodes.length;i<l;i++){r.push(nodes[i]);if(nodes[i][childKey]){r=r.concat(data.transformToArrayFormat(setting,nodes[i][childKey]))}}}else{r.push(nodes);if(nodes[childKey]){r=r.concat(data.transformToArrayFormat(setting,nodes[childKey]))}}return r},transformTozTreeFormat:function(setting,sNodes){var i,l,key=setting.data.simpleData.idKey,parentKey=setting.data.simpleData.pIdKey,childKey=setting.data.key.children;if(!key||key==""||!sNodes){return[]}if(tools.isArray(sNodes)){var r=[];var tmpMap=[];for(i=0,l=sNodes.length;i<l;i++){tmpMap[sNodes[i][key]]=sNodes[i]}for(i=0,l=sNodes.length;i<l;i++){if(tmpMap[sNodes[i][parentKey]]&&sNodes[i][key]!=sNodes[i][parentKey]){if(!tmpMap[sNodes[i][parentKey]][childKey]){tmpMap[sNodes[i][parentKey]][childKey]=[]}tmpMap[sNodes[i][parentKey]][childKey].push(sNodes[i])}else{r.push(sNodes[i])}}return r}else{return[sNodes]}}},event={bindEvent:function(setting){for(var i=0,j=_init.bind.length; +i<j;i++){_init.bind[i].apply(this,arguments)}},unbindEvent:function(setting){for(var i=0,j=_init.unbind.length;i<j;i++){_init.unbind[i].apply(this,arguments)}},bindTree:function(setting){var eventParam={treeId:setting.treeId},o=setting.treeObj;if(!setting.view.txtSelectedEnable){o.bind("selectstart",handler.onSelectStart).css({"-moz-user-select":"-moz-none"})}o.bind("click",eventParam,event.proxy);o.bind("dblclick",eventParam,event.proxy);o.bind("mouseover",eventParam,event.proxy);o.bind("mouseout",eventParam,event.proxy);o.bind("mousedown",eventParam,event.proxy);o.bind("mouseup",eventParam,event.proxy);o.bind("contextmenu",eventParam,event.proxy)},unbindTree:function(setting){var o=setting.treeObj;o.unbind("selectstart",handler.onSelectStart).unbind("click",event.proxy).unbind("dblclick",event.proxy).unbind("mouseover",event.proxy).unbind("mouseout",event.proxy).unbind("mousedown",event.proxy).unbind("mouseup",event.proxy).unbind("contextmenu",event.proxy)},doProxy:function(e){var results=[];for(var i=0,j=_init.proxys.length;i<j;i++){var proxyResult=_init.proxys[i].apply(this,arguments);results.push(proxyResult);if(proxyResult.stop){break}}return results},proxy:function(e){var setting=data.getSetting(e.data.treeId);if(!tools.uCanDo(setting,e)){return true}var results=event.doProxy(e),r=true,x=false;for(var i=0,l=results.length;i<l;i++){var proxyResult=results[i];if(proxyResult.nodeEventCallback){x=true;r=proxyResult.nodeEventCallback.apply(proxyResult,[e,proxyResult.node])&&r}if(proxyResult.treeEventCallback){x=true;r=proxyResult.treeEventCallback.apply(proxyResult,[e,proxyResult.node])&&r}}return r}},handler={onSwitchNode:function(event,node){var setting=data.getSetting(event.data.treeId);if(node.open){if(tools.apply(setting.callback.beforeCollapse,[setting.treeId,node],true)==false){return true}data.getRoot(setting).expandTriggerFlag=true;view.switchNode(setting,node)}else{if(tools.apply(setting.callback.beforeExpand,[setting.treeId,node],true)==false){return true}data.getRoot(setting).expandTriggerFlag=true;view.switchNode(setting,node)}return true},onClickNode:function(event,node){var setting=data.getSetting(event.data.treeId),clickFlag=((setting.view.autoCancelSelected&&(event.ctrlKey||event.metaKey))&&data.isSelectedNode(setting,node))?0:(setting.view.autoCancelSelected&&(event.ctrlKey||event.metaKey)&&setting.view.selectedMulti)?2:1;if(tools.apply(setting.callback.beforeClick,[setting.treeId,node,clickFlag],true)==false){return true}if(clickFlag===0){view.cancelPreSelectedNode(setting,node)}else{view.selectNode(setting,node,clickFlag===2)}setting.treeObj.trigger(consts.event.CLICK,[event,setting.treeId,node,clickFlag]);return true},onZTreeMousedown:function(event,node){var setting=data.getSetting(event.data.treeId);if(tools.apply(setting.callback.beforeMouseDown,[setting.treeId,node],true)){tools.apply(setting.callback.onMouseDown,[event,setting.treeId,node])}return true},onZTreeMouseup:function(event,node){var setting=data.getSetting(event.data.treeId);if(tools.apply(setting.callback.beforeMouseUp,[setting.treeId,node],true)){tools.apply(setting.callback.onMouseUp,[event,setting.treeId,node])}return true},onZTreeDblclick:function(event,node){var setting=data.getSetting(event.data.treeId);if(tools.apply(setting.callback.beforeDblClick,[setting.treeId,node],true)){tools.apply(setting.callback.onDblClick,[event,setting.treeId,node])}return true},onZTreeContextmenu:function(event,node){var setting=data.getSetting(event.data.treeId);if(tools.apply(setting.callback.beforeRightClick,[setting.treeId,node],true)){tools.apply(setting.callback.onRightClick,[event,setting.treeId,node])}return(typeof setting.callback.onRightClick)!="function"},onSelectStart:function(e){var n=e.originalEvent.srcElement.nodeName.toLowerCase();return(n==="input"||n==="textarea")}},tools={apply:function(fun,param,defaultValue){if((typeof fun)=="function"){return fun.apply(zt,param?param:[])}return defaultValue},canAsync:function(setting,node){var childKey=setting.data.key.children;return(setting.async.enable&&node&&node.isParent&&!(node.zAsync||(node[childKey]&&node[childKey].length>0)))},clone:function(obj){if(obj===null){return null}var o=tools.isArray(obj)?[]:{};for(var i in obj){o[i]=(obj[i] instanceof Date)?new Date(obj[i].getTime()):(typeof obj[i]==="object"?tools.clone(obj[i]):obj[i])}return o},eqs:function(str1,str2){return str1.toLowerCase()===str2.toLowerCase()},isArray:function(arr){return Object.prototype.toString.apply(arr)==="[object Array]"},$:function(node,exp,setting){if(!!exp&&typeof exp!="string"){setting=exp;exp=""}if(typeof node=="string"){return $(node,setting?setting.treeObj.get(0).ownerDocument:null)}else{return $("#"+node.tId+exp,setting?setting.treeObj:null)}},getMDom:function(setting,curDom,targetExpr){if(!curDom){return null}while(curDom&&curDom.id!==setting.treeId){for(var i=0,l=targetExpr.length;curDom.tagName&&i<l;i++){if(tools.eqs(curDom.tagName,targetExpr[i].tagName)&&curDom.getAttribute(targetExpr[i].attrName)!==null){return curDom +}}curDom=curDom.parentNode}return null},getNodeMainDom:function(target){return($(target).parent("li").get(0)||$(target).parentsUntil("li").parent().get(0))},isChildOrSelf:function(dom,parentId){return($(dom).closest("#"+parentId).length>0)},uCanDo:function(setting,e){return true}},view={addNodes:function(setting,parentNode,index,newNodes,isSilent){if(setting.data.keep.leaf&&parentNode&&!parentNode.isParent){return}if(!tools.isArray(newNodes)){newNodes=[newNodes]}if(setting.data.simpleData.enable){newNodes=data.transformTozTreeFormat(setting,newNodes)}if(parentNode){var target_switchObj=$$(parentNode,consts.id.SWITCH,setting),target_icoObj=$$(parentNode,consts.id.ICON,setting),target_ulObj=$$(parentNode,consts.id.UL,setting);if(!parentNode.open){view.replaceSwitchClass(parentNode,target_switchObj,consts.folder.CLOSE);view.replaceIcoClass(parentNode,target_icoObj,consts.folder.CLOSE);parentNode.open=false;target_ulObj.css({"display":"none"})}data.addNodesData(setting,parentNode,index,newNodes);view.createNodes(setting,parentNode.level+1,newNodes,parentNode,index);if(!isSilent){view.expandCollapseParentNode(setting,parentNode,true)}}else{data.addNodesData(setting,data.getRoot(setting),index,newNodes);view.createNodes(setting,0,newNodes,null,index)}},appendNodes:function(setting,level,nodes,parentNode,index,initFlag,openFlag){if(!nodes){return[]}var html=[],childKey=setting.data.key.children;var tmpPNode=(parentNode)?parentNode:data.getRoot(setting),tmpPChild=tmpPNode[childKey],isFirstNode,isLastNode;if(!tmpPChild||index>=tmpPChild.length){index=-1}for(var i=0,l=nodes.length;i<l;i++){var node=nodes[i];if(initFlag){isFirstNode=((index===0||tmpPChild.length==nodes.length)&&(i==0));isLastNode=(index<0&&i==(nodes.length-1));data.initNode(setting,level,node,parentNode,isFirstNode,isLastNode,openFlag);data.addNodeCache(setting,node)}var childHtml=[];if(node[childKey]&&node[childKey].length>0){childHtml=view.appendNodes(setting,level+1,node[childKey],node,-1,initFlag,openFlag&&node.open)}if(openFlag){view.makeDOMNodeMainBefore(html,setting,node);view.makeDOMNodeLine(html,setting,node);data.getBeforeA(setting,node,html);view.makeDOMNodeNameBefore(html,setting,node);data.getInnerBeforeA(setting,node,html);view.makeDOMNodeIcon(html,setting,node);data.getInnerAfterA(setting,node,html);view.makeDOMNodeNameAfter(html,setting,node);data.getAfterA(setting,node,html);if(node.isParent&&node.open){view.makeUlHtml(setting,node,html,childHtml.join(""))}view.makeDOMNodeMainAfter(html,setting,node);data.addCreatedNode(setting,node)}}return html},appendParentULDom:function(setting,node){var html=[],nObj=$$(node,setting);if(!nObj.get(0)&&!!node.parentTId){view.appendParentULDom(setting,node.getParentNode());nObj=$$(node,setting)}var ulObj=$$(node,consts.id.UL,setting);if(ulObj.get(0)){ulObj.remove()}var childKey=setting.data.key.children,childHtml=view.appendNodes(setting,node.level+1,node[childKey],node,-1,false,true);view.makeUlHtml(setting,node,html,childHtml.join(""));nObj.append(html.join(""))},asyncNode:function(setting,node,isSilent,callback){var i,l;if(node&&!node.isParent){tools.apply(callback);return false}else{if(node&&node.isAjaxing){return false}else{if(tools.apply(setting.callback.beforeAsync,[setting.treeId,node],true)==false){tools.apply(callback);return false}}}if(node){node.isAjaxing=true;var icoObj=$$(node,consts.id.ICON,setting);icoObj.attr({"style":"","class":consts.className.BUTTON+" "+consts.className.ICO_LOADING})}var tmpParam={};for(i=0,l=setting.async.autoParam.length;node&&i<l;i++){var pKey=setting.async.autoParam[i].split("="),spKey=pKey;if(pKey.length>1){spKey=pKey[1];pKey=pKey[0]}tmpParam[spKey]=node[pKey]}if(tools.isArray(setting.async.otherParam)){for(i=0,l=setting.async.otherParam.length;i<l;i+=2){tmpParam[setting.async.otherParam[i]]=setting.async.otherParam[i+1]}}else{for(var p in setting.async.otherParam){tmpParam[p]=setting.async.otherParam[p]}}var _tmpV=data.getRoot(setting)._ver;$.ajax({contentType:setting.async.contentType,cache:false,type:setting.async.type,url:tools.apply(setting.async.url,[setting.treeId,node],setting.async.url),data:tmpParam,dataType:setting.async.dataType,success:function(msg){if(_tmpV!=data.getRoot(setting)._ver){return}var newNodes=[];try{if(!msg||msg.length==0){newNodes=[]}else{if(typeof msg=="string"){newNodes=eval("("+msg+")")}else{newNodes=msg}}}catch(err){newNodes=msg}if(node){node.isAjaxing=null;node.zAsync=true}view.setNodeLineIcos(setting,node);if(newNodes&&newNodes!==""){newNodes=tools.apply(setting.async.dataFilter,[setting.treeId,node,newNodes],newNodes);view.addNodes(setting,node,-1,!!newNodes?tools.clone(newNodes):[],!!isSilent)}else{view.addNodes(setting,node,-1,[],!!isSilent)}setting.treeObj.trigger(consts.event.ASYNC_SUCCESS,[setting.treeId,node,msg]);tools.apply(callback)},error:function(XMLHttpRequest,textStatus,errorThrown){if(_tmpV!=data.getRoot(setting)._ver){return}if(node){node.isAjaxing=null}view.setNodeLineIcos(setting,node);setting.treeObj.trigger(consts.event.ASYNC_ERROR,[setting.treeId,node,XMLHttpRequest,textStatus,errorThrown]) +}});return true},cancelPreSelectedNode:function(setting,node,excludeNode){var list=data.getRoot(setting).curSelectedList,i,n;for(i=list.length-1;i>=0;i--){n=list[i];if(node===n||(!node&&(!excludeNode||excludeNode!==n))){$$(n,consts.id.A,setting).removeClass(consts.node.CURSELECTED);if(node){data.removeSelectedNode(setting,node);break}else{list.splice(i,1);setting.treeObj.trigger(consts.event.UNSELECTED,[setting.treeId,n])}}}},createNodeCallback:function(setting){if(!!setting.callback.onNodeCreated||!!setting.view.addDiyDom){var root=data.getRoot(setting);while(root.createdNodes.length>0){var node=root.createdNodes.shift();tools.apply(setting.view.addDiyDom,[setting.treeId,node]);if(!!setting.callback.onNodeCreated){setting.treeObj.trigger(consts.event.NODECREATED,[setting.treeId,node])}}}},createNodes:function(setting,level,nodes,parentNode,index){if(!nodes||nodes.length==0){return}var root=data.getRoot(setting),childKey=setting.data.key.children,openFlag=!parentNode||parentNode.open||!!$$(parentNode[childKey][0],setting).get(0);root.createdNodes=[];var zTreeHtml=view.appendNodes(setting,level,nodes,parentNode,index,true,openFlag),parentObj,nextObj;if(!parentNode){parentObj=setting.treeObj}else{var ulObj=$$(parentNode,consts.id.UL,setting);if(ulObj.get(0)){parentObj=ulObj}}if(parentObj){if(index>=0){nextObj=parentObj.children()[index]}if(index>=0&&nextObj){$(nextObj).before(zTreeHtml.join(""))}else{parentObj.append(zTreeHtml.join(""))}}view.createNodeCallback(setting)},destroy:function(setting){if(!setting){return}data.initCache(setting);data.initRoot(setting);event.unbindTree(setting);event.unbindEvent(setting);setting.treeObj.empty();delete settings[setting.treeId]},expandCollapseNode:function(setting,node,expandFlag,animateFlag,callback){var root=data.getRoot(setting),childKey=setting.data.key.children;var tmpCb,_callback;if(!node){tools.apply(callback,[]);return}if(root.expandTriggerFlag){_callback=callback;tmpCb=function(){if(_callback){_callback()}if(node.open){setting.treeObj.trigger(consts.event.EXPAND,[setting.treeId,node])}else{setting.treeObj.trigger(consts.event.COLLAPSE,[setting.treeId,node])}};callback=tmpCb;root.expandTriggerFlag=false}if(!node.open&&node.isParent&&((!$$(node,consts.id.UL,setting).get(0))||(node[childKey]&&node[childKey].length>0&&!$$(node[childKey][0],setting).get(0)))){view.appendParentULDom(setting,node);view.createNodeCallback(setting)}if(node.open==expandFlag){tools.apply(callback,[]);return}var ulObj=$$(node,consts.id.UL,setting),switchObj=$$(node,consts.id.SWITCH,setting),icoObj=$$(node,consts.id.ICON,setting);if(node.isParent){node.open=!node.open;if(node.iconOpen&&node.iconClose){icoObj.attr("style",view.makeNodeIcoStyle(setting,node))}if(node.open){view.replaceSwitchClass(node,switchObj,consts.folder.OPEN);view.replaceIcoClass(node,icoObj,consts.folder.OPEN);if(animateFlag==false||setting.view.expandSpeed==""){ulObj.show();tools.apply(callback,[])}else{if(node[childKey]&&node[childKey].length>0){ulObj.slideDown(setting.view.expandSpeed,callback)}else{ulObj.show();tools.apply(callback,[])}}}else{view.replaceSwitchClass(node,switchObj,consts.folder.CLOSE);view.replaceIcoClass(node,icoObj,consts.folder.CLOSE);if(animateFlag==false||setting.view.expandSpeed==""||!(node[childKey]&&node[childKey].length>0)){ulObj.hide();tools.apply(callback,[])}else{ulObj.slideUp(setting.view.expandSpeed,callback)}}}else{tools.apply(callback,[])}},expandCollapseParentNode:function(setting,node,expandFlag,animateFlag,callback){if(!node){return}if(!node.parentTId){view.expandCollapseNode(setting,node,expandFlag,animateFlag,callback);return}else{view.expandCollapseNode(setting,node,expandFlag,animateFlag)}if(node.parentTId){view.expandCollapseParentNode(setting,node.getParentNode(),expandFlag,animateFlag,callback)}},expandCollapseSonNode:function(setting,node,expandFlag,animateFlag,callback){var root=data.getRoot(setting),childKey=setting.data.key.children,treeNodes=(node)?node[childKey]:root[childKey],selfAnimateSign=(node)?false:animateFlag,expandTriggerFlag=data.getRoot(setting).expandTriggerFlag;data.getRoot(setting).expandTriggerFlag=false;if(treeNodes){for(var i=0,l=treeNodes.length;i<l;i++){if(treeNodes[i]){view.expandCollapseSonNode(setting,treeNodes[i],expandFlag,selfAnimateSign)}}}data.getRoot(setting).expandTriggerFlag=expandTriggerFlag;view.expandCollapseNode(setting,node,expandFlag,animateFlag,callback)},isSelectedNode:function(setting,node){if(!node){return false}var list=data.getRoot(setting).curSelectedList,i;for(i=list.length-1;i>=0;i--){if(node===list[i]){return true}}return false},makeDOMNodeIcon:function(html,setting,node){var nameStr=data.getNodeName(setting,node),name=setting.view.nameIsHTML?nameStr:nameStr.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");html.push("<span id='",node.tId,consts.id.ICON,"' title='' treeNode",consts.id.ICON," class='",view.makeNodeIcoClass(setting,node),"' style='",view.makeNodeIcoStyle(setting,node),"'></span><span id='",node.tId,consts.id.SPAN,"' class='",consts.className.NAME,"'>",name,"</span>") +},makeDOMNodeLine:function(html,setting,node){html.push("<span id='",node.tId,consts.id.SWITCH,"' title='' class='",view.makeNodeLineClass(setting,node),"' treeNode",consts.id.SWITCH,"></span>")},makeDOMNodeMainAfter:function(html,setting,node){html.push("</li>")},makeDOMNodeMainBefore:function(html,setting,node){html.push("<li id='",node.tId,"' class='",consts.className.LEVEL,node.level,"' tabindex='0' hidefocus='true' treenode>")},makeDOMNodeNameAfter:function(html,setting,node){html.push("</a>")},makeDOMNodeNameBefore:function(html,setting,node){var title=data.getNodeTitle(setting,node),url=view.makeNodeUrl(setting,node),fontcss=view.makeNodeFontCss(setting,node),fontStyle=[];for(var f in fontcss){fontStyle.push(f,":",fontcss[f],";")}html.push("<a id='",node.tId,consts.id.A,"' class='",consts.className.LEVEL,node.level,"' treeNode",consts.id.A,' onclick="',(node.click||""),'" ',((url!=null&&url.length>0)?"href='"+url+"'":"")," target='",view.makeNodeTarget(node),"' style='",fontStyle.join(""),"'");if(tools.apply(setting.view.showTitle,[setting.treeId,node],setting.view.showTitle)&&title){html.push("title='",title.replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),"'")}html.push(">")},makeNodeFontCss:function(setting,node){var fontCss=tools.apply(setting.view.fontCss,[setting.treeId,node],setting.view.fontCss);return(fontCss&&((typeof fontCss)!="function"))?fontCss:{}},makeNodeIcoClass:function(setting,node){var icoCss=["ico"];if(!node.isAjaxing){icoCss[0]=(node.iconSkin?node.iconSkin+"_":"")+icoCss[0];if(node.isParent){icoCss.push(node.open?consts.folder.OPEN:consts.folder.CLOSE)}else{icoCss.push(consts.folder.DOCU)}}return consts.className.BUTTON+" "+icoCss.join("_")},makeNodeIcoStyle:function(setting,node){var icoStyle=[];if(!node.isAjaxing){var icon=(node.isParent&&node.iconOpen&&node.iconClose)?(node.open?node.iconOpen:node.iconClose):node[setting.data.key.icon];if(icon){icoStyle.push("background:url(",icon,") 0 0 no-repeat;")}if(setting.view.showIcon==false||!tools.apply(setting.view.showIcon,[setting.treeId,node],true)){icoStyle.push("width:0px;height:0px;")}}return icoStyle.join("")},makeNodeLineClass:function(setting,node){var lineClass=[];if(setting.view.showLine){if(node.level==0&&node.isFirstNode&&node.isLastNode){lineClass.push(consts.line.ROOT)}else{if(node.level==0&&node.isFirstNode){lineClass.push(consts.line.ROOTS)}else{if(node.isLastNode){lineClass.push(consts.line.BOTTOM)}else{lineClass.push(consts.line.CENTER)}}}}else{lineClass.push(consts.line.NOLINE)}if(node.isParent){lineClass.push(node.open?consts.folder.OPEN:consts.folder.CLOSE)}else{lineClass.push(consts.folder.DOCU)}return view.makeNodeLineClassEx(node)+lineClass.join("_")},makeNodeLineClassEx:function(node){return consts.className.BUTTON+" "+consts.className.LEVEL+node.level+" "+consts.className.SWITCH+" "},makeNodeTarget:function(node){return(node.target||"_blank")},makeNodeUrl:function(setting,node){var urlKey=setting.data.key.url;return node[urlKey]?node[urlKey]:null},makeUlHtml:function(setting,node,html,content){html.push("<ul id='",node.tId,consts.id.UL,"' class='",consts.className.LEVEL,node.level," ",view.makeUlLineClass(setting,node),"' style='display:",(node.open?"block":"none"),"'>");html.push(content);html.push("</ul>")},makeUlLineClass:function(setting,node){return((setting.view.showLine&&!node.isLastNode)?consts.line.LINE:"")},removeChildNodes:function(setting,node){if(!node){return}var childKey=setting.data.key.children,nodes=node[childKey];if(!nodes){return}for(var i=0,l=nodes.length;i<l;i++){data.removeNodeCache(setting,nodes[i])}data.removeSelectedNode(setting);delete node[childKey];if(!setting.data.keep.parent){node.isParent=false;node.open=false;var tmp_switchObj=$$(node,consts.id.SWITCH,setting),tmp_icoObj=$$(node,consts.id.ICON,setting);view.replaceSwitchClass(node,tmp_switchObj,consts.folder.DOCU);view.replaceIcoClass(node,tmp_icoObj,consts.folder.DOCU);$$(node,consts.id.UL,setting).remove()}else{$$(node,consts.id.UL,setting).empty()}},scrollIntoView:function(dom){if(!dom){return}if(dom.scrollIntoViewIfNeeded){dom.scrollIntoViewIfNeeded()}else{if(dom.scrollIntoView){dom.scrollIntoView(false)}else{try{dom.focus().blur()}catch(e){}}}},setFirstNode:function(setting,parentNode){var childKey=setting.data.key.children,childLength=parentNode[childKey].length;if(childLength>0){parentNode[childKey][0].isFirstNode=true}},setLastNode:function(setting,parentNode){var childKey=setting.data.key.children,childLength=parentNode[childKey].length;if(childLength>0){parentNode[childKey][childLength-1].isLastNode=true}},removeNode:function(setting,node){var root=data.getRoot(setting),childKey=setting.data.key.children,parentNode=(node.parentTId)?node.getParentNode():root;node.isFirstNode=false;node.isLastNode=false;node.getPreNode=function(){return null};node.getNextNode=function(){return null};if(!data.getNodeCache(setting,node.tId)){return}$$(node,setting).remove();data.removeNodeCache(setting,node);data.removeSelectedNode(setting,node); +for(var i=0,l=parentNode[childKey].length;i<l;i++){if(parentNode[childKey][i].tId==node.tId){parentNode[childKey].splice(i,1);break}}view.setFirstNode(setting,parentNode);view.setLastNode(setting,parentNode);var tmp_ulObj,tmp_switchObj,tmp_icoObj,childLength=parentNode[childKey].length;if(!setting.data.keep.parent&&childLength==0){parentNode.isParent=false;parentNode.open=false;tmp_ulObj=$$(parentNode,consts.id.UL,setting);tmp_switchObj=$$(parentNode,consts.id.SWITCH,setting);tmp_icoObj=$$(parentNode,consts.id.ICON,setting);view.replaceSwitchClass(parentNode,tmp_switchObj,consts.folder.DOCU);view.replaceIcoClass(parentNode,tmp_icoObj,consts.folder.DOCU);tmp_ulObj.css("display","none")}else{if(setting.view.showLine&&childLength>0){var newLast=parentNode[childKey][childLength-1];tmp_ulObj=$$(newLast,consts.id.UL,setting);tmp_switchObj=$$(newLast,consts.id.SWITCH,setting);tmp_icoObj=$$(newLast,consts.id.ICON,setting);if(parentNode==root){if(parentNode[childKey].length==1){view.replaceSwitchClass(newLast,tmp_switchObj,consts.line.ROOT)}else{var tmp_first_switchObj=$$(parentNode[childKey][0],consts.id.SWITCH,setting);view.replaceSwitchClass(parentNode[childKey][0],tmp_first_switchObj,consts.line.ROOTS);view.replaceSwitchClass(newLast,tmp_switchObj,consts.line.BOTTOM)}}else{view.replaceSwitchClass(newLast,tmp_switchObj,consts.line.BOTTOM)}tmp_ulObj.removeClass(consts.line.LINE)}}},replaceIcoClass:function(node,obj,newName){if(!obj||node.isAjaxing){return}var tmpName=obj.attr("class");if(tmpName==undefined){return}var tmpList=tmpName.split("_");switch(newName){case consts.folder.OPEN:case consts.folder.CLOSE:case consts.folder.DOCU:tmpList[tmpList.length-1]=newName;break}obj.attr("class",tmpList.join("_"))},replaceSwitchClass:function(node,obj,newName){if(!obj){return}var tmpName=obj.attr("class");if(tmpName==undefined){return}var tmpList=tmpName.split("_");switch(newName){case consts.line.ROOT:case consts.line.ROOTS:case consts.line.CENTER:case consts.line.BOTTOM:case consts.line.NOLINE:tmpList[0]=view.makeNodeLineClassEx(node)+newName;break;case consts.folder.OPEN:case consts.folder.CLOSE:case consts.folder.DOCU:tmpList[1]=newName;break}obj.attr("class",tmpList.join("_"));if(newName!==consts.folder.DOCU){obj.removeAttr("disabled")}else{obj.attr("disabled","disabled")}},selectNode:function(setting,node,addFlag){if(!addFlag){view.cancelPreSelectedNode(setting,null,node)}$$(node,consts.id.A,setting).addClass(consts.node.CURSELECTED);data.addSelectedNode(setting,node);setting.treeObj.trigger(consts.event.SELECTED,[setting.treeId,node])},setNodeFontCss:function(setting,treeNode){var aObj=$$(treeNode,consts.id.A,setting),fontCss=view.makeNodeFontCss(setting,treeNode);if(fontCss){aObj.css(fontCss)}},setNodeLineIcos:function(setting,node){if(!node){return}var switchObj=$$(node,consts.id.SWITCH,setting),ulObj=$$(node,consts.id.UL,setting),icoObj=$$(node,consts.id.ICON,setting),ulLine=view.makeUlLineClass(setting,node);if(ulLine.length==0){ulObj.removeClass(consts.line.LINE)}else{ulObj.addClass(ulLine)}switchObj.attr("class",view.makeNodeLineClass(setting,node));if(node.isParent){switchObj.removeAttr("disabled")}else{switchObj.attr("disabled","disabled")}icoObj.removeAttr("style");icoObj.attr("style",view.makeNodeIcoStyle(setting,node));icoObj.attr("class",view.makeNodeIcoClass(setting,node))},setNodeName:function(setting,node){var title=data.getNodeTitle(setting,node),nObj=$$(node,consts.id.SPAN,setting);nObj.empty();if(setting.view.nameIsHTML){nObj.html(data.getNodeName(setting,node))}else{nObj.text(data.getNodeName(setting,node))}if(tools.apply(setting.view.showTitle,[setting.treeId,node],setting.view.showTitle)){var aObj=$$(node,consts.id.A,setting);aObj.attr("title",!title?"":title)}},setNodeTarget:function(setting,node){var aObj=$$(node,consts.id.A,setting);aObj.attr("target",view.makeNodeTarget(node))},setNodeUrl:function(setting,node){var aObj=$$(node,consts.id.A,setting),url=view.makeNodeUrl(setting,node);if(url==null||url.length==0){aObj.removeAttr("href")}else{aObj.attr("href",url)}},switchNode:function(setting,node){if(node.open||!tools.canAsync(setting,node)){view.expandCollapseNode(setting,node,!node.open)}else{if(setting.async.enable){if(!view.asyncNode(setting,node)){view.expandCollapseNode(setting,node,!node.open);return}}else{if(node){view.expandCollapseNode(setting,node,!node.open)}}}}};$.fn.zTree={consts:_consts,_z:{tools:tools,view:view,event:event,data:data},getZTreeObj:function(treeId){var o=data.getZTreeTools(treeId);return o?o:null},destroy:function(treeId){if(!!treeId&&treeId.length>0){view.destroy(data.getSetting(treeId))}else{for(var s in settings){view.destroy(settings[s])}}},init:function(obj,zSetting,zNodes){var setting=tools.clone(_setting);$.extend(true,setting,zSetting);setting.treeId=obj.attr("id");setting.treeObj=obj;setting.treeObj.empty();settings[setting.treeId]=setting;if(typeof document.body.style.maxHeight==="undefined"){setting.view.expandSpeed=""}data.initRoot(setting);var root=data.getRoot(setting),childKey=setting.data.key.children; +zNodes=zNodes?tools.clone(tools.isArray(zNodes)?zNodes:[zNodes]):[];if(setting.data.simpleData.enable){root[childKey]=data.transformTozTreeFormat(setting,zNodes)}else{root[childKey]=zNodes}data.initCache(setting);event.unbindTree(setting);event.bindTree(setting);event.unbindEvent(setting);event.bindEvent(setting);var zTreeTools={setting:setting,addNodes:function(parentNode,index,newNodes,isSilent){if(!parentNode){parentNode=null}if(parentNode&&!parentNode.isParent&&setting.data.keep.leaf){return null}var i=parseInt(index,10);if(isNaN(i)){isSilent=!!newNodes;newNodes=index;index=-1}else{index=i}if(!newNodes){return null}var xNewNodes=tools.clone(tools.isArray(newNodes)?newNodes:[newNodes]);function addCallback(){view.addNodes(setting,parentNode,index,xNewNodes,(isSilent==true))}if(tools.canAsync(setting,parentNode)){view.asyncNode(setting,parentNode,isSilent,addCallback)}else{addCallback()}return xNewNodes},cancelSelectedNode:function(node){view.cancelPreSelectedNode(setting,node)},destroy:function(){view.destroy(setting)},expandAll:function(expandFlag){expandFlag=!!expandFlag;view.expandCollapseSonNode(setting,null,expandFlag,true);return expandFlag},expandNode:function(node,expandFlag,sonSign,focus,callbackFlag){if(!node||!node.isParent){return null}if(expandFlag!==true&&expandFlag!==false){expandFlag=!node.open}callbackFlag=!!callbackFlag;if(callbackFlag&&expandFlag&&(tools.apply(setting.callback.beforeExpand,[setting.treeId,node],true)==false)){return null}else{if(callbackFlag&&!expandFlag&&(tools.apply(setting.callback.beforeCollapse,[setting.treeId,node],true)==false)){return null}}if(expandFlag&&node.parentTId){view.expandCollapseParentNode(setting,node.getParentNode(),expandFlag,false)}if(expandFlag===node.open&&!sonSign){return null}data.getRoot(setting).expandTriggerFlag=callbackFlag;if(!tools.canAsync(setting,node)&&sonSign){view.expandCollapseSonNode(setting,node,expandFlag,true,showNodeFocus)}else{node.open=!expandFlag;view.switchNode(this.setting,node);showNodeFocus()}return expandFlag;function showNodeFocus(){var a=$$(node,setting).get(0);if(a&&focus!==false){view.scrollIntoView(a)}}},getNodes:function(){return data.getNodes(setting)},getNodeByParam:function(key,value,parentNode){if(!key){return null}return data.getNodeByParam(setting,parentNode?parentNode[setting.data.key.children]:data.getNodes(setting),key,value)},getNodeByTId:function(tId){return data.getNodeCache(setting,tId)},getNodesByParam:function(key,value,parentNode){if(!key){return null}return data.getNodesByParam(setting,parentNode?parentNode[setting.data.key.children]:data.getNodes(setting),key,value)},getNodesByParamFuzzy:function(key,value,parentNode){if(!key){return null}return data.getNodesByParamFuzzy(setting,parentNode?parentNode[setting.data.key.children]:data.getNodes(setting),key,value)},getNodesByFilter:function(filter,isSingle,parentNode,invokeParam){isSingle=!!isSingle;if(!filter||(typeof filter!="function")){return(isSingle?null:[])}return data.getNodesByFilter(setting,parentNode?parentNode[setting.data.key.children]:data.getNodes(setting),filter,isSingle,invokeParam)},getNodeIndex:function(node){if(!node){return null}var childKey=setting.data.key.children,parentNode=(node.parentTId)?node.getParentNode():data.getRoot(setting);for(var i=0,l=parentNode[childKey].length;i<l;i++){if(parentNode[childKey][i]==node){return i}}return -1},getSelectedNodes:function(){var r=[],list=data.getRoot(setting).curSelectedList;for(var i=0,l=list.length;i<l;i++){r.push(list[i])}return r},isSelectedNode:function(node){return data.isSelectedNode(setting,node)},reAsyncChildNodes:function(parentNode,reloadType,isSilent){if(!this.setting.async.enable){return}var isRoot=!parentNode;if(isRoot){parentNode=data.getRoot(setting)}if(reloadType=="refresh"){var childKey=this.setting.data.key.children;for(var i=0,l=parentNode[childKey]?parentNode[childKey].length:0;i<l;i++){data.removeNodeCache(setting,parentNode[childKey][i])}data.removeSelectedNode(setting);parentNode[childKey]=[];if(isRoot){this.setting.treeObj.empty()}else{var ulObj=$$(parentNode,consts.id.UL,setting);ulObj.empty()}}view.asyncNode(this.setting,isRoot?null:parentNode,!!isSilent)},refresh:function(){this.setting.treeObj.empty();var root=data.getRoot(setting),nodes=root[setting.data.key.children];data.initRoot(setting);root[setting.data.key.children]=nodes;data.initCache(setting);view.createNodes(setting,0,root[setting.data.key.children],null,-1)},removeChildNodes:function(node){if(!node){return null}var childKey=setting.data.key.children,nodes=node[childKey];view.removeChildNodes(setting,node);return nodes?nodes:null},removeNode:function(node,callbackFlag){if(!node){return}callbackFlag=!!callbackFlag;if(callbackFlag&&tools.apply(setting.callback.beforeRemove,[setting.treeId,node],true)==false){return}view.removeNode(setting,node);if(callbackFlag){this.setting.treeObj.trigger(consts.event.REMOVE,[setting.treeId,node])}},selectNode:function(node,addFlag,isSilent){if(!node){return}if(tools.uCanDo(setting)){addFlag=setting.view.selectedMulti&&addFlag; +if(node.parentTId){view.expandCollapseParentNode(setting,node.getParentNode(),true,false,showNodeFocus)}else{if(!isSilent){try{$$(node,setting).focus().blur()}catch(e){}}}view.selectNode(setting,node,addFlag)}function showNodeFocus(){if(isSilent){return}var a=$$(node,setting).get(0);view.scrollIntoView(a)}},transformTozTreeNodes:function(simpleNodes){return data.transformTozTreeFormat(setting,simpleNodes)},transformToArray:function(nodes){return data.transformToArrayFormat(setting,nodes)},updateNode:function(node,checkTypeFlag){if(!node){return}var nObj=$$(node,setting);if(nObj.get(0)&&tools.uCanDo(setting)){view.setNodeName(setting,node);view.setNodeTarget(setting,node);view.setNodeUrl(setting,node);view.setNodeLineIcos(setting,node);view.setNodeFontCss(setting,node)}}};root.treeTools=zTreeTools;data.setZTreeTools(setting,zTreeTools);if(root[childKey]&&root[childKey].length>0){view.createNodes(setting,0,root[childKey],null,-1)}else{if(setting.async.enable&&setting.async.url&&setting.async.url!==""){view.asyncNode(setting)}}return zTreeTools}};var zt=$.fn.zTree,$$=tools.$,consts=zt.consts})(jQuery);(function(f){var A={event:{CHECK:"ztree_check"},id:{CHECK:"_check"},checkbox:{STYLE:"checkbox",DEFAULT:"chk",DISABLED:"disable",FALSE:"false",TRUE:"true",FULL:"full",PART:"part",FOCUS:"focus"},radio:{STYLE:"radio",TYPE_ALL:"all",TYPE_LEVEL:"level"}},n={check:{enable:false,autoCheckTrigger:false,chkStyle:A.checkbox.STYLE,nocheckInherit:false,chkDisabledInherit:false,radioType:A.radio.TYPE_LEVEL,chkboxType:{"Y":"ps","N":"ps"}},data:{key:{checked:"checked"}},callback:{beforeCheck:null,onCheck:null}},w=function(B){var C=z.getRoot(B);C.radioCheckedList=[]},d=function(B){},o=function(B){var C=B.treeObj,D=r.event;C.bind(D.CHECK,function(G,F,H,E){G.srcEvent=F;u.apply(B.callback.onCheck,[G,H,E])})},y=function(B){var C=B.treeObj,D=r.event;C.unbind(D.CHECK)},p=function(H){var I=H.target,K=z.getSetting(H.data.treeId),F="",C=null,D="",G="",B=null,E=null;if(u.eqs(H.type,"mouseover")){if(K.check.enable&&u.eqs(I.tagName,"span")&&I.getAttribute("treeNode"+r.id.CHECK)!==null){F=u.getNodeMainDom(I).id;D="mouseoverCheck"}}else{if(u.eqs(H.type,"mouseout")){if(K.check.enable&&u.eqs(I.tagName,"span")&&I.getAttribute("treeNode"+r.id.CHECK)!==null){F=u.getNodeMainDom(I).id;D="mouseoutCheck"}}else{if(u.eqs(H.type,"click")){if(K.check.enable&&u.eqs(I.tagName,"span")&&I.getAttribute("treeNode"+r.id.CHECK)!==null){F=u.getNodeMainDom(I).id;D="checkNode"}}}}if(F.length>0){C=z.getNodeCache(K,F);switch(D){case"checkNode":B=m.onCheckNode;break;case"mouseoverCheck":B=m.onMouseoverCheck;break;case"mouseoutCheck":B=m.onMouseoutCheck;break}}var J={stop:D==="checkNode",node:C,nodeEventType:D,nodeEventCallback:B,treeEventType:G,treeEventCallback:E};return J},v=function(J,D,F,G,I,H,E){if(!F){return}var C=J.data.key.checked;if(typeof F[C]=="string"){F[C]=u.eqs(F[C],"true")}F[C]=!!F[C];F.checkedOld=F[C];if(typeof F.nocheck=="string"){F.nocheck=u.eqs(F.nocheck,"true")}F.nocheck=!!F.nocheck||(J.check.nocheckInherit&&G&&!!G.nocheck);if(typeof F.chkDisabled=="string"){F.chkDisabled=u.eqs(F.chkDisabled,"true")}F.chkDisabled=!!F.chkDisabled||(J.check.chkDisabledInherit&&G&&!!G.chkDisabled);if(typeof F.halfCheck=="string"){F.halfCheck=u.eqs(F.halfCheck,"true")}F.halfCheck=!!F.halfCheck;F.check_Child_State=-1;F.check_Focus=false;F.getCheckStatus=function(){return z.getCheckStatus(J,F)};if(J.check.chkStyle==r.radio.STYLE&&J.check.radioType==r.radio.TYPE_ALL&&F[C]){var B=z.getRoot(J);B.radioCheckedList.push(F)}},a=function(D,E,C){var B=D.data.key.checked;if(D.check.enable){z.makeChkFlag(D,E);C.push("<span ID='",E.tId,r.id.CHECK,"' class='",k.makeChkClass(D,E),"' treeNode",r.id.CHECK,(E.nocheck===true?" style='display:none;'":""),"></span>")}},l=function(D,C){C.checkNode=function(I,H,J,G){var E=this.setting.data.key.checked;if(I.chkDisabled===true){return}if(H!==true&&H!==false){H=!I[E]}G=!!G;if(I[E]===H&&!J){return}else{if(G&&u.apply(this.setting.callback.beforeCheck,[this.setting.treeId,I],true)==false){return}}if(u.uCanDo(this.setting)&&this.setting.check.enable&&I.nocheck!==true){I[E]=H;var F=j(I,r.id.CHECK,this.setting);if(J||this.setting.check.chkStyle===r.radio.STYLE){k.checkNodeRelation(this.setting,I)}k.setChkClass(this.setting,F,I);k.repairParentChkClassWithSelf(this.setting,I);if(G){this.setting.treeObj.trigger(r.event.CHECK,[null,this.setting.treeId,I])}}};C.checkAllNodes=function(E){k.repairAllChk(this.setting,!!E)};C.getCheckedNodes=function(F){var E=this.setting.data.key.children;F=(F!==false);return z.getTreeCheckedNodes(this.setting,z.getRoot(this.setting)[E],F)};C.getChangeCheckedNodes=function(){var E=this.setting.data.key.children;return z.getTreeChangeCheckedNodes(this.setting,z.getRoot(this.setting)[E])};C.setChkDisabled=function(F,E,G,H){E=!!E;G=!!G;H=!!H;k.repairSonChkDisabled(this.setting,F,E,H);k.repairParentChkDisabled(this.setting,F.getParentNode(),E,G)};var B=C.updateNode;C.updateNode=function(G,H){if(B){B.apply(C,arguments)}if(!G||!this.setting.check.enable){return +}var E=j(G,this.setting);if(E.get(0)&&u.uCanDo(this.setting)){var F=j(G,r.id.CHECK,this.setting);if(H==true||this.setting.check.chkStyle===r.radio.STYLE){k.checkNodeRelation(this.setting,G)}k.setChkClass(this.setting,F,G);k.repairParentChkClassWithSelf(this.setting,G)}}},q={getRadioCheckedList:function(E){var D=z.getRoot(E).radioCheckedList;for(var C=0,B=D.length;C<B;C++){if(!z.getNodeCache(E,D[C].tId)){D.splice(C,1);C--;B--}}return D},getCheckStatus:function(C,E){if(!C.check.enable||E.nocheck||E.chkDisabled){return null}var B=C.data.key.checked,D={checked:E[B],half:E.halfCheck?E.halfCheck:(C.check.chkStyle==r.radio.STYLE?(E.check_Child_State===2):(E[B]?(E.check_Child_State>-1&&E.check_Child_State<2):(E.check_Child_State>0)))};return D},getTreeCheckedNodes:function(J,C,I,F){if(!C){return[]}var D=J.data.key.children,B=J.data.key.checked,H=(I&&J.check.chkStyle==r.radio.STYLE&&J.check.radioType==r.radio.TYPE_ALL);F=!F?[]:F;for(var G=0,E=C.length;G<E;G++){if(C[G].nocheck!==true&&C[G].chkDisabled!==true&&C[G][B]==I){F.push(C[G]);if(H){break}}z.getTreeCheckedNodes(J,C[G][D],I,F);if(H&&F.length>0){break}}return F},getTreeChangeCheckedNodes:function(G,D,F){if(!D){return[]}var H=G.data.key.children,C=G.data.key.checked;F=!F?[]:F;for(var E=0,B=D.length;E<B;E++){if(D[E].nocheck!==true&&D[E].chkDisabled!==true&&D[E][C]!=D[E].checkedOld){F.push(D[E])}z.getTreeChangeCheckedNodes(G,D[E][H],F)}return F},makeChkFlag:function(I,D){if(!D){return}var C=I.data.key.children,B=I.data.key.checked,F=-1;if(D[C]){for(var H=0,E=D[C].length;H<E;H++){var J=D[C][H];var G=-1;if(I.check.chkStyle==r.radio.STYLE){if(J.nocheck===true||J.chkDisabled===true){G=J.check_Child_State}else{if(J.halfCheck===true){G=2}else{if(J[B]){G=2}else{G=J.check_Child_State>0?2:0}}}if(G==2){F=2;break}else{if(G==0){F=0}}}else{if(I.check.chkStyle==r.checkbox.STYLE){if(J.nocheck===true||J.chkDisabled===true){G=J.check_Child_State}else{if(J.halfCheck===true){G=1}else{if(J[B]){G=(J.check_Child_State===-1||J.check_Child_State===2)?2:1}else{G=(J.check_Child_State>0)?1:0}}}if(G===1){F=1;break}else{if(G===2&&F>-1&&H>0&&G!==F){F=1;break}else{if(F===2&&G>-1&&G<2){F=1;break}else{if(G>-1){F=G}}}}}}}}D.check_Child_State=F}},h={},m={onCheckNode:function(F,E){if(E.chkDisabled===true){return false}var D=z.getSetting(F.data.treeId),B=D.data.key.checked;if(u.apply(D.callback.beforeCheck,[D.treeId,E],true)==false){return true}E[B]=!E[B];k.checkNodeRelation(D,E);var C=j(E,r.id.CHECK,D);k.setChkClass(D,C,E);k.repairParentChkClassWithSelf(D,E);D.treeObj.trigger(r.event.CHECK,[F,D.treeId,E]);return true},onMouseoverCheck:function(E,D){if(D.chkDisabled===true){return false}var C=z.getSetting(E.data.treeId),B=j(D,r.id.CHECK,C);D.check_Focus=true;k.setChkClass(C,B,D);return true},onMouseoutCheck:function(E,D){if(D.chkDisabled===true){return false}var C=z.getSetting(E.data.treeId),B=j(D,r.id.CHECK,C);D.check_Focus=false;k.setChkClass(C,B,D);return true}},i={},e={checkNodeRelation:function(K,E){var I,G,F,D=K.data.key.children,C=K.data.key.checked,B=r.radio;if(K.check.chkStyle==B.STYLE){var J=z.getRadioCheckedList(K);if(E[C]){if(K.check.radioType==B.TYPE_ALL){for(G=J.length-1;G>=0;G--){I=J[G];if(I[C]&&I!=E){I[C]=false;J.splice(G,1);k.setChkClass(K,j(I,r.id.CHECK,K),I);if(I.parentTId!=E.parentTId){k.repairParentChkClassWithSelf(K,I)}}}J.push(E)}else{var H=(E.parentTId)?E.getParentNode():z.getRoot(K);for(G=0,F=H[D].length;G<F;G++){I=H[D][G];if(I[C]&&I!=E){I[C]=false;k.setChkClass(K,j(I,r.id.CHECK,K),I)}}}}else{if(K.check.radioType==B.TYPE_ALL){for(G=0,F=J.length;G<F;G++){if(E==J[G]){J.splice(G,1);break}}}}}else{if(E[C]&&(!E[D]||E[D].length==0||K.check.chkboxType.Y.indexOf("s")>-1)){k.setSonNodeCheckBox(K,E,true)}if(!E[C]&&(!E[D]||E[D].length==0||K.check.chkboxType.N.indexOf("s")>-1)){k.setSonNodeCheckBox(K,E,false)}if(E[C]&&K.check.chkboxType.Y.indexOf("p")>-1){k.setParentNodeCheckBox(K,E,true)}if(!E[C]&&K.check.chkboxType.N.indexOf("p")>-1){k.setParentNodeCheckBox(K,E,false)}}},makeChkClass:function(C,F){var B=C.data.key.checked,H=r.checkbox,E=r.radio,G="";if(F.chkDisabled===true){G=H.DISABLED}else{if(F.halfCheck){G=H.PART}else{if(C.check.chkStyle==E.STYLE){G=(F.check_Child_State<1)?H.FULL:H.PART}else{G=F[B]?((F.check_Child_State===2||F.check_Child_State===-1)?H.FULL:H.PART):((F.check_Child_State<1)?H.FULL:H.PART)}}}var D=C.check.chkStyle+"_"+(F[B]?H.TRUE:H.FALSE)+"_"+G;D=(F.check_Focus&&F.chkDisabled!==true)?D+"_"+H.FOCUS:D;return r.className.BUTTON+" "+H.DEFAULT+" "+D},repairAllChk:function(F,I){if(F.check.enable&&F.check.chkStyle===r.checkbox.STYLE){var D=F.data.key.checked,H=F.data.key.children,C=z.getRoot(F);for(var E=0,B=C[H].length;E<B;E++){var G=C[H][E];if(G.nocheck!==true&&G.chkDisabled!==true){G[D]=I}k.setSonNodeCheckBox(F,G,I)}}},repairChkClass:function(C,D){if(!D){return}z.makeChkFlag(C,D);if(D.nocheck!==true){var B=j(D,r.id.CHECK,C);k.setChkClass(C,B,D)}},repairParentChkClass:function(C,D){if(!D||!D.parentTId){return}var B=D.getParentNode();k.repairChkClass(C,B);k.repairParentChkClass(C,B) +},repairParentChkClassWithSelf:function(B,D){if(!D){return}var C=B.data.key.children;if(D[C]&&D[C].length>0){k.repairParentChkClass(B,D[C][0])}else{k.repairParentChkClass(B,D)}},repairSonChkDisabled:function(G,I,F,D){if(!I){return}var H=G.data.key.children;if(I.chkDisabled!=F){I.chkDisabled=F}k.repairChkClass(G,I);if(I[H]&&D){for(var E=0,C=I[H].length;E<C;E++){var B=I[H][E];k.repairSonChkDisabled(G,B,F,D)}}},repairParentChkDisabled:function(D,E,C,B){if(!E){return}if(E.chkDisabled!=C&&B){E.chkDisabled=C}k.repairChkClass(D,E);k.repairParentChkDisabled(D,E.getParentNode(),C,B)},setChkClass:function(B,D,C){if(!D){return}if(C.nocheck===true){D.hide()}else{D.show()}D.attr("class",k.makeChkClass(B,C))},setParentNodeCheckBox:function(L,E,K,H){var D=L.data.key.children,B=L.data.key.checked,I=j(E,r.id.CHECK,L);if(!H){H=E}z.makeChkFlag(L,E);if(E.nocheck!==true&&E.chkDisabled!==true){E[B]=K;k.setChkClass(L,I,E);if(L.check.autoCheckTrigger&&E!=H){L.treeObj.trigger(r.event.CHECK,[null,L.treeId,E])}}if(E.parentTId){var J=true;if(!K){var C=E.getParentNode()[D];for(var G=0,F=C.length;G<F;G++){if((C[G].nocheck!==true&&C[G].chkDisabled!==true&&C[G][B])||((C[G].nocheck===true||C[G].chkDisabled===true)&&C[G].check_Child_State>0)){J=false;break}}}if(J){k.setParentNodeCheckBox(L,E.getParentNode(),K,H)}}},setSonNodeCheckBox:function(L,E,K,H){if(!E){return}var D=L.data.key.children,B=L.data.key.checked,I=j(E,r.id.CHECK,L);if(!H){H=E}var C=false;if(E[D]){for(var G=0,F=E[D].length;G<F;G++){var J=E[D][G];k.setSonNodeCheckBox(L,J,K,H);if(J.chkDisabled===true){C=true}}}if(E!=z.getRoot(L)&&E.chkDisabled!==true){if(C&&E.nocheck!==true){z.makeChkFlag(L,E)}if(E.nocheck!==true&&E.chkDisabled!==true){E[B]=K;if(!C){E.check_Child_State=(E[D]&&E[D].length>0)?(K?2:0):-1}}else{E.check_Child_State=-1}k.setChkClass(L,I,E);if(L.check.autoCheckTrigger&&E!=H&&E.nocheck!==true&&E.chkDisabled!==true){L.treeObj.trigger(r.event.CHECK,[null,L.treeId,E])}}}},t={tools:i,view:e,event:h,data:q};f.extend(true,f.fn.zTree.consts,A);f.extend(true,f.fn.zTree._z,t);var c=f.fn.zTree,u=c._z.tools,r=c.consts,k=c._z.view,z=c._z.data,s=c._z.event,j=u.$;z.exSetting(n);z.addInitBind(o);z.addInitUnBind(y);z.addInitCache(d);z.addInitNode(v);z.addInitProxy(p,true);z.addInitRoot(w);z.addBeforeA(a);z.addZTreeTools(l);var x=k.createNodes;k.createNodes=function(E,F,C,B,D){if(x){x.apply(k,arguments)}if(!C){return}k.repairParentChkClassWithSelf(E,B)};var b=k.removeNode;k.removeNode=function(C,D){var B=D.getParentNode();if(b){b.apply(k,arguments)}if(!D||!B){return}k.repairChkClass(C,B);k.repairParentChkClass(C,B)};var g=k.appendNodes;k.appendNodes=function(G,I,C,B,D,F,H){var E="";if(g){E=g.apply(k,arguments)}if(B){z.makeChkFlag(G,B)}return E}})(jQuery);(function(f){var C={event:{DRAG:"ztree_drag",DROP:"ztree_drop",RENAME:"ztree_rename",DRAGMOVE:"ztree_dragmove"},id:{EDIT:"_edit",INPUT:"_input",REMOVE:"_remove"},move:{TYPE_INNER:"inner",TYPE_PREV:"prev",TYPE_NEXT:"next"},node:{CURSELECTED_EDIT:"curSelectedNode_Edit",TMPTARGET_TREE:"tmpTargetzTree",TMPTARGET_NODE:"tmpTargetNode"}},m={edit:{enable:false,editNameSelectAll:false,showRemoveBtn:true,showRenameBtn:true,removeTitle:"remove",renameTitle:"rename",drag:{autoExpandTrigger:false,isCopy:true,isMove:true,prev:true,next:true,inner:true,minMoveSize:5,borderMax:10,borderMin:-5,maxShowNodeNum:5,autoOpenTime:500}},view:{addHoverDom:null,removeHoverDom:null},callback:{beforeDrag:null,beforeDragOpen:null,beforeDrop:null,beforeEditName:null,beforeRename:null,onDrag:null,onDragMove:null,onDrop:null,onRename:null}},x=function(E){var F=A.getRoot(E),D=A.getRoots();F.curEditNode=null;F.curEditInput=null;F.curHoverNode=null;F.dragFlag=0;F.dragNodeShowBefore=[];F.dragMaskList=new Array();D.showHoverDom=true},c=function(D){},n=function(D){var E=D.treeObj;var F=q.event;E.bind(F.RENAME,function(H,J,I,G){v.apply(D.callback.onRename,[H,J,I,G])});E.bind(F.DRAG,function(H,G,J,I){v.apply(D.callback.onDrag,[G,J,I])});E.bind(F.DRAGMOVE,function(H,G,J,I){v.apply(D.callback.onDragMove,[G,J,I])});E.bind(F.DROP,function(J,I,L,K,M,H,G){v.apply(D.callback.onDrop,[I,L,K,M,H,G])})},z=function(D){var E=D.treeObj;var F=q.event;E.unbind(F.RENAME);E.unbind(F.DRAG);E.unbind(F.DRAGMOVE);E.unbind(F.DROP)},o=function(K){var L=K.target,O=A.getSetting(K.data.treeId),M=K.relatedTarget,I="",E=null,F="",J="",D=null,H=null,G=null;if(v.eqs(K.type,"mouseover")){G=v.getMDom(O,L,[{tagName:"a",attrName:"treeNode"+q.id.A}]);if(G){I=v.getNodeMainDom(G).id;F="hoverOverNode"}}else{if(v.eqs(K.type,"mouseout")){G=v.getMDom(O,M,[{tagName:"a",attrName:"treeNode"+q.id.A}]);if(!G){I="remove";F="hoverOutNode"}}else{if(v.eqs(K.type,"mousedown")){G=v.getMDom(O,L,[{tagName:"a",attrName:"treeNode"+q.id.A}]);if(G){I=v.getNodeMainDom(G).id;F="mousedownNode"}}}}if(I.length>0){E=A.getNodeCache(O,I);switch(F){case"mousedownNode":D=l.onMousedownNode;break;case"hoverOverNode":D=l.onHoverOverNode;break;case"hoverOutNode":D=l.onHoverOutNode;break}}var N={stop:false,node:E,nodeEventType:F,nodeEventCallback:D,treeEventType:J,treeEventCallback:H}; +return N},w=function(F,J,I,D,H,E,G){if(!I){return}I.isHover=false;I.editNameFlag=false},k=function(E,D){D.cancelEditName=function(G){var F=A.getRoot(this.setting);if(!F.curEditNode){return}j.cancelCurEditNode(this.setting,G?G:null,true)};D.copyNode=function(J,I,H,L){if(!I){return null}if(J&&!J.isParent&&this.setting.data.keep.leaf&&H===q.move.TYPE_INNER){return null}var K=this,F=v.clone(I);if(!J){J=null;H=q.move.TYPE_INNER}if(H==q.move.TYPE_INNER){function G(){j.addNodes(K.setting,J,-1,[F],L)}if(v.canAsync(this.setting,J)){j.asyncNode(this.setting,J,L,G)}else{G()}}else{j.addNodes(this.setting,J.parentNode,-1,[F],L);j.moveNode(this.setting,J,F,H,false,L)}return F};D.editName=function(F){if(!F||!F.tId||F!==A.getNodeCache(this.setting,F.tId)){return}if(F.parentTId){j.expandCollapseParentNode(this.setting,F.getParentNode(),true)}j.editNode(this.setting,F)};D.moveNode=function(H,G,F,K){if(!G){return G}if(H&&!H.isParent&&this.setting.data.keep.leaf&&F===q.move.TYPE_INNER){return null}else{if(H&&((G.parentTId==H.tId&&F==q.move.TYPE_INNER)||i(G,this.setting).find("#"+H.tId).length>0)){return null}else{if(!H){H=null}}}var J=this;function I(){j.moveNode(J.setting,H,G,F,false,K)}if(v.canAsync(this.setting,H)&&F===q.move.TYPE_INNER){j.asyncNode(this.setting,H,K,I)}else{I()}return G};D.setEditable=function(F){this.setting.edit.enable=F;return this.refresh()}},p={setSonNodeLevel:function(G,D,I){if(!I){return}var H=G.data.key.children;I.level=(D)?D.level+1:0;if(!I[H]){return}for(var F=0,E=I[H].length;F<E;F++){if(I[H][F]){A.setSonNodeLevel(G,I,I[H][F])}}}},g={},l={onHoverOverNode:function(G,F){var E=A.getSetting(G.data.treeId),D=A.getRoot(E);if(D.curHoverNode!=F){l.onHoverOutNode(G)}D.curHoverNode=F;j.addHoverDom(E,F)},onHoverOutNode:function(G,F){var E=A.getSetting(G.data.treeId),D=A.getRoot(E);if(D.curHoverNode&&!A.isSelectedNode(E,D.curHoverNode)){j.removeTreeDom(E,D.curHoverNode);D.curHoverNode=null}},onMousedownNode:function(S,K){var aa,X,R=A.getSetting(S.data.treeId),W=A.getRoot(R),L=A.getRoots();if(S.button==2||!R.edit.enable||(!R.edit.drag.isCopy&&!R.edit.drag.isMove)){return true}var ad=S.target,J=A.getRoot(R).curSelectedList,T=[];if(!A.isSelectedNode(R,K)){T=[K]}else{for(aa=0,X=J.length;aa<X;aa++){if(J[aa].editNameFlag&&v.eqs(ad.tagName,"input")&&ad.getAttribute("treeNode"+q.id.INPUT)!==null){return true}T.push(J[aa]);if(T[0].parentTId!==J[aa].parentTId){T=[K];break}}}j.editNodeBlur=true;j.cancelCurEditNode(R);var ag=f(R.treeObj.get(0).ownerDocument),M=f(R.treeObj.get(0).ownerDocument.body),Z,N,ab,ac=false,ae=R,I=R,D,H,U=null,G=null,Q=null,E=q.move.TYPE_INNER,Y=S.clientX,V=S.clientY,O=(new Date()).getTime();if(v.uCanDo(R)){ag.bind("mousemove",P)}function P(a6){if(W.dragFlag==0&&Math.abs(Y-a6.clientX)<R.edit.drag.minMoveSize&&Math.abs(V-a6.clientY)<R.edit.drag.minMoveSize){return true}var a0,aW,ay,aR,aJ,aQ=R.data.key.children;M.css("cursor","pointer");if(W.dragFlag==0){if(v.apply(R.callback.beforeDrag,[R.treeId,T],true)==false){af(a6);return true}for(a0=0,aW=T.length;a0<aW;a0++){if(a0==0){W.dragNodeShowBefore=[]}ay=T[a0];if(ay.isParent&&ay.open){j.expandCollapseNode(R,ay,!ay.open);W.dragNodeShowBefore[ay.tId]=true}else{W.dragNodeShowBefore[ay.tId]=false}}W.dragFlag=1;L.showHoverDom=false;v.showIfameMask(R,true);var ai=true,al=-1;if(T.length>1){var aw=T[0].parentTId?T[0].getParentNode()[aQ]:A.getNodes(R);aJ=[];for(a0=0,aW=aw.length;a0<aW;a0++){if(W.dragNodeShowBefore[aw[a0].tId]!==undefined){if(ai&&al>-1&&(al+1)!==a0){ai=false}aJ.push(aw[a0]);al=a0}if(T.length===aJ.length){T=aJ;break}}}if(ai){D=T[0].getPreNode();H=T[T.length-1].getNextNode()}Z=i("<ul class='zTreeDragUL'></ul>",R);for(a0=0,aW=T.length;a0<aW;a0++){ay=T[a0];ay.editNameFlag=false;j.selectNode(R,ay,a0>0);j.removeTreeDom(R,ay);if(a0>R.edit.drag.maxShowNodeNum-1){continue}aR=i("<li id='"+ay.tId+"_tmp'></li>",R);aR.append(i(ay,q.id.A,R).clone());aR.css("padding","0");aR.children("#"+ay.tId+q.id.A).removeClass(q.node.CURSELECTED);Z.append(aR);if(a0==R.edit.drag.maxShowNodeNum-1){aR=i("<li id='"+ay.tId+"_moretmp'><a> ... </a></li>",R);Z.append(aR)}}Z.attr("id",T[0].tId+q.id.UL+"_tmp");Z.addClass(R.treeObj.attr("class"));Z.appendTo(M);N=i("<span class='tmpzTreeMove_arrow'></span>",R);N.attr("id","zTreeMove_arrow_tmp");N.appendTo(M);R.treeObj.trigger(q.event.DRAG,[a6,R.treeId,T])}if(W.dragFlag==1){if(ab&&N.attr("id")==a6.target.id&&Q&&(a6.clientX+ag.scrollLeft()+2)>(f("#"+Q+q.id.A,ab).offset().left)){var a5=f("#"+Q+q.id.A,ab);a6.target=(a5.length>0)?a5.get(0):a6.target}else{if(ab){ab.removeClass(q.node.TMPTARGET_TREE);if(Q){f("#"+Q+q.id.A,ab).removeClass(q.node.TMPTARGET_NODE+"_"+q.move.TYPE_PREV).removeClass(q.node.TMPTARGET_NODE+"_"+C.move.TYPE_NEXT).removeClass(q.node.TMPTARGET_NODE+"_"+C.move.TYPE_INNER)}}}ab=null;Q=null;ac=false;ae=R;var a1=A.getSettings();for(var aS in a1){if(a1[aS].treeId&&a1[aS].edit.enable&&a1[aS].treeId!=R.treeId&&(a6.target.id==a1[aS].treeId||f(a6.target).parents("#"+a1[aS].treeId).length>0)){ac=true;ae=a1[aS]}}var av=ag.scrollTop(),a4=ag.scrollLeft(),aj=ae.treeObj.offset(),aD=ae.treeObj.get(0).scrollHeight,aT=ae.treeObj.get(0).scrollWidth,a2=(a6.clientY+av-aj.top),aP=(ae.treeObj.height()+aj.top-a6.clientY-av),aK=(a6.clientX+a4-aj.left),au=(ae.treeObj.width()+aj.left-a6.clientX-a4),ax=(a2<R.edit.drag.borderMax&&a2>R.edit.drag.borderMin),a7=(aP<R.edit.drag.borderMax&&aP>R.edit.drag.borderMin),aN=(aK<R.edit.drag.borderMax&&aK>R.edit.drag.borderMin),ar=(au<R.edit.drag.borderMax&&au>R.edit.drag.borderMin),ak=a2>R.edit.drag.borderMin&&aP>R.edit.drag.borderMin&&aK>R.edit.drag.borderMin&&au>R.edit.drag.borderMin,aH=(ax&&ae.treeObj.scrollTop()<=0),aG=(a7&&(ae.treeObj.scrollTop()+ae.treeObj.height()+10)>=aD),an=(aN&&ae.treeObj.scrollLeft()<=0),aB=(ar&&(ae.treeObj.scrollLeft()+ae.treeObj.width()+10)>=aT); +if(a6.target&&v.isChildOrSelf(a6.target,ae.treeId)){var at=a6.target;while(at&&at.tagName&&!v.eqs(at.tagName,"li")&&at.id!=ae.treeId){at=at.parentNode}var aA=true;for(a0=0,aW=T.length;a0<aW;a0++){ay=T[a0];if(at.id===ay.tId){aA=false;break}else{if(i(ay,R).find("#"+at.id).length>0){aA=false;break}}}if(aA&&a6.target&&v.isChildOrSelf(a6.target,at.id+q.id.A)){ab=f(at);Q=at.id}}ay=T[0];if(ak&&v.isChildOrSelf(a6.target,ae.treeId)){if(!ab&&(a6.target.id==ae.treeId||aH||aG||an||aB)&&(ac||(!ac&&ay.parentTId))){ab=ae.treeObj}if(ax){ae.treeObj.scrollTop(ae.treeObj.scrollTop()-10)}else{if(a7){ae.treeObj.scrollTop(ae.treeObj.scrollTop()+10)}}if(aN){ae.treeObj.scrollLeft(ae.treeObj.scrollLeft()-10)}else{if(ar){ae.treeObj.scrollLeft(ae.treeObj.scrollLeft()+10)}}if(ab&&ab!=ae.treeObj&&ab.offset().left<ae.treeObj.offset().left){ae.treeObj.scrollLeft(ae.treeObj.scrollLeft()+ab.offset().left-ae.treeObj.offset().left)}}Z.css({"top":(a6.clientY+av+3)+"px","left":(a6.clientX+a4+3)+"px"});var aF=0;var aE=0;if(ab&&ab.attr("id")!=ae.treeId){var aO=Q==null?null:A.getNodeCache(ae,Q),aI=((a6.ctrlKey||a6.metaKey)&&R.edit.drag.isMove&&R.edit.drag.isCopy)||(!R.edit.drag.isMove&&R.edit.drag.isCopy),ap=!!(D&&Q===D.tId),aM=!!(H&&Q===H.tId),aY=(ay.parentTId&&ay.parentTId==Q),aL=(aI||!aM)&&v.apply(ae.edit.drag.prev,[ae.treeId,T,aO],!!ae.edit.drag.prev),ao=(aI||!ap)&&v.apply(ae.edit.drag.next,[ae.treeId,T,aO],!!ae.edit.drag.next),ah=(aI||!aY)&&!(ae.data.keep.leaf&&!aO.isParent)&&v.apply(ae.edit.drag.inner,[ae.treeId,T,aO],!!ae.edit.drag.inner);function a3(){ab=null;Q="";E=q.move.TYPE_INNER;N.css({"display":"none"});if(window.zTreeMoveTimer){clearTimeout(window.zTreeMoveTimer);window.zTreeMoveTargetNodeTId=null}}if(!aL&&!ao&&!ah){a3()}else{var aC=f("#"+Q+q.id.A,ab),aV=aO.isLastNode?null:f("#"+aO.getNextNode().tId+q.id.A,ab.next()),aX=aC.offset().top,aZ=aC.offset().left,aU=aL?(ah?0.25:(ao?0.5:1)):-1,aq=ao?(ah?0.75:(aL?0.5:0)):-1,am=(a6.clientY+av-aX)/aC.height();if((aU==1||am<=aU&&am>=-0.2)&&aL){aF=1-N.width();aE=aX-N.height()/2;E=q.move.TYPE_PREV}else{if((aq==0||am>=aq&&am<=1.2)&&ao){aF=1-N.width();aE=(aV==null||(aO.isParent&&aO.open))?(aX+aC.height()-N.height()/2):(aV.offset().top-N.height()/2);E=q.move.TYPE_NEXT}else{if(ah){aF=5-N.width();aE=aX;E=q.move.TYPE_INNER}else{a3()}}}if(ab){N.css({"display":"block","top":aE+"px","left":(aZ+aF)+"px"});aC.addClass(q.node.TMPTARGET_NODE+"_"+E);if(U!=Q||G!=E){O=(new Date()).getTime()}if(aO&&aO.isParent&&E==q.move.TYPE_INNER){var az=true;if(window.zTreeMoveTimer&&window.zTreeMoveTargetNodeTId!==aO.tId){clearTimeout(window.zTreeMoveTimer);window.zTreeMoveTargetNodeTId=null}else{if(window.zTreeMoveTimer&&window.zTreeMoveTargetNodeTId===aO.tId){az=false}}if(az){window.zTreeMoveTimer=setTimeout(function(){if(E!=q.move.TYPE_INNER){return}if(aO&&aO.isParent&&!aO.open&&(new Date()).getTime()-O>ae.edit.drag.autoOpenTime&&v.apply(ae.callback.beforeDragOpen,[ae.treeId,aO],true)){j.switchNode(ae,aO);if(ae.edit.drag.autoExpandTrigger){ae.treeObj.trigger(q.event.EXPAND,[ae.treeId,aO])}}},ae.edit.drag.autoOpenTime+50);window.zTreeMoveTargetNodeTId=aO.tId}}}}}else{E=q.move.TYPE_INNER;if(ab&&v.apply(ae.edit.drag.inner,[ae.treeId,T,null],!!ae.edit.drag.inner)){ab.addClass(q.node.TMPTARGET_TREE)}else{ab=null}N.css({"display":"none"});if(window.zTreeMoveTimer){clearTimeout(window.zTreeMoveTimer);window.zTreeMoveTargetNodeTId=null}}U=Q;G=E;R.treeObj.trigger(q.event.DRAGMOVE,[a6,R.treeId,T])}return false}ag.bind("mouseup",af);function af(ao){if(window.zTreeMoveTimer){clearTimeout(window.zTreeMoveTimer);window.zTreeMoveTargetNodeTId=null}U=null;G=null;ag.unbind("mousemove",P);ag.unbind("mouseup",af);ag.unbind("selectstart",F);M.css("cursor","auto");if(ab){ab.removeClass(q.node.TMPTARGET_TREE);if(Q){f("#"+Q+q.id.A,ab).removeClass(q.node.TMPTARGET_NODE+"_"+q.move.TYPE_PREV).removeClass(q.node.TMPTARGET_NODE+"_"+C.move.TYPE_NEXT).removeClass(q.node.TMPTARGET_NODE+"_"+C.move.TYPE_INNER)}}v.showIfameMask(R,false);L.showHoverDom=true;if(W.dragFlag==0){return}W.dragFlag=0;var am,ai,an;for(am=0,ai=T.length;am<ai;am++){an=T[am];if(an.isParent&&W.dragNodeShowBefore[an.tId]&&!an.open){j.expandCollapseNode(R,an,!an.open);delete W.dragNodeShowBefore[an.tId]}}if(Z){Z.remove()}if(N){N.remove()}var ah=((ao.ctrlKey||ao.metaKey)&&R.edit.drag.isMove&&R.edit.drag.isCopy)||(!R.edit.drag.isMove&&R.edit.drag.isCopy);if(!ah&&ab&&Q&&T[0].parentTId&&Q==T[0].parentTId&&E==q.move.TYPE_INNER){ab=null}if(ab){var aj=Q==null?null:A.getNodeCache(ae,Q);if(v.apply(R.callback.beforeDrop,[ae.treeId,T,aj,E,ah],true)==false){j.selectNodes(I,T);return}var ak=ah?v.clone(T):T;function al(){if(ac){if(!ah){for(var ar=0,aq=T.length;ar<aq;ar++){j.removeNode(R,T[ar])}}if(E==q.move.TYPE_INNER){j.addNodes(ae,aj,-1,ak)}else{j.addNodes(ae,aj.getParentNode(),E==q.move.TYPE_PREV?aj.getIndex():aj.getIndex()+1,ak)}}else{if(ah&&E==q.move.TYPE_INNER){j.addNodes(ae,aj,-1,ak)}else{if(ah){j.addNodes(ae,aj.getParentNode(),E==q.move.TYPE_PREV?aj.getIndex():aj.getIndex()+1,ak)}else{if(E!=q.move.TYPE_NEXT){for(ar=0,aq=ak.length; +ar<aq;ar++){j.moveNode(ae,aj,ak[ar],E,false)}}else{for(ar=-1,aq=ak.length-1;ar<aq;aq--){j.moveNode(ae,aj,ak[aq],E,false)}}}}}j.selectNodes(ae,ak);var ap=i(ak[0],R).get(0);j.scrollIntoView(ap);R.treeObj.trigger(q.event.DROP,[ao,ae.treeId,ak,aj,E,ah])}if(E==q.move.TYPE_INNER&&v.canAsync(ae,aj)){j.asyncNode(ae,aj,false,al)}else{al()}}else{j.selectNodes(I,T);R.treeObj.trigger(q.event.DROP,[ao,R.treeId,T,null,null,null])}}ag.bind("selectstart",F);function F(){return false}if(S.preventDefault){S.preventDefault()}return true}},h={getAbs:function(E){var G=E.getBoundingClientRect(),D=document.body.scrollTop+document.documentElement.scrollTop,F=document.body.scrollLeft+document.documentElement.scrollLeft;return[G.left+F,G.top+D]},inputFocus:function(D){if(D.get(0)){D.focus();v.setCursorPosition(D.get(0),D.val().length)}},inputSelect:function(D){if(D.get(0)){D.focus();D.select()}},setCursorPosition:function(E,F){if(E.setSelectionRange){E.focus();E.setSelectionRange(F,F)}else{if(E.createTextRange){var D=E.createTextRange();D.collapse(true);D.moveEnd("character",F);D.moveStart("character",F);D.select()}}},showIfameMask:function(K,I){var H=A.getRoot(K);while(H.dragMaskList.length>0){H.dragMaskList[0].remove();H.dragMaskList.shift()}if(I){var L=i("iframe",K);for(var G=0,E=L.length;G<E;G++){var F=L.get(G),D=v.getAbs(F),J=i("<div id='zTreeMask_"+G+"' class='zTreeMask' style='top:"+D[1]+"px; left:"+D[0]+"px; width:"+F.offsetWidth+"px; height:"+F.offsetHeight+"px;'></div>",K);J.appendTo(i("body",K));H.dragMaskList.push(J)}}}},d={addEditBtn:function(E,F){if(F.editNameFlag||i(F,q.id.EDIT,E).length>0){return}if(!v.apply(E.edit.showRenameBtn,[E.treeId,F],E.edit.showRenameBtn)){return}var G=i(F,q.id.A,E),D="<span class='"+q.className.BUTTON+" edit' id='"+F.tId+q.id.EDIT+"' title='"+v.apply(E.edit.renameTitle,[E.treeId,F],E.edit.renameTitle)+"' treeNode"+q.id.EDIT+" style='display:none;'></span>";G.append(D);i(F,q.id.EDIT,E).bind("click",function(){if(!v.uCanDo(E)||v.apply(E.callback.beforeEditName,[E.treeId,F],true)==false){return false}j.editNode(E,F);return false}).show()},addRemoveBtn:function(D,E){if(E.editNameFlag||i(E,q.id.REMOVE,D).length>0){return}if(!v.apply(D.edit.showRemoveBtn,[D.treeId,E],D.edit.showRemoveBtn)){return}var G=i(E,q.id.A,D),F="<span class='"+q.className.BUTTON+" remove' id='"+E.tId+q.id.REMOVE+"' title='"+v.apply(D.edit.removeTitle,[D.treeId,E],D.edit.removeTitle)+"' treeNode"+q.id.REMOVE+" style='display:none;'></span>";G.append(F);i(E,q.id.REMOVE,D).bind("click",function(){if(!v.uCanDo(D)||v.apply(D.callback.beforeRemove,[D.treeId,E],true)==false){return false}j.removeNode(D,E);D.treeObj.trigger(q.event.REMOVE,[D.treeId,E]);return false}).bind("mousedown",function(H){return true}).show()},addHoverDom:function(D,E){if(A.getRoots().showHoverDom){E.isHover=true;if(D.edit.enable){j.addEditBtn(D,E);j.addRemoveBtn(D,E)}v.apply(D.view.addHoverDom,[D.treeId,E])}},cancelCurEditNode:function(K,L,H){var J=A.getRoot(K),G=K.data.key.name,E=J.curEditNode;if(E){var F=J.curEditInput,I=L?L:(H?E[G]:F.val());if(v.apply(K.callback.beforeRename,[K.treeId,E,I,H],true)===false){return false}E[G]=I;var D=i(E,q.id.A,K);D.removeClass(q.node.CURSELECTED_EDIT);F.unbind();j.setNodeName(K,E);E.editNameFlag=false;J.curEditNode=null;J.curEditInput=null;j.selectNode(K,E,false);K.treeObj.trigger(q.event.RENAME,[K.treeId,E,H])}J.noSelection=true;return true},editNode:function(G,H){var D=A.getRoot(G);j.editNodeBlur=false;if(A.isSelectedNode(G,H)&&D.curEditNode==H&&H.editNameFlag){setTimeout(function(){v.inputFocus(D.curEditInput)},0);return}var F=G.data.key.name;H.editNameFlag=true;j.removeTreeDom(G,H);j.cancelCurEditNode(G);j.selectNode(G,H,false);i(H,q.id.SPAN,G).html("<input type=text class='rename' id='"+H.tId+q.id.INPUT+"' treeNode"+q.id.INPUT+" >");var E=i(H,q.id.INPUT,G);E.attr("value",H[F]);if(G.edit.editNameSelectAll){v.inputSelect(E)}else{v.inputFocus(E)}E.bind("blur",function(I){if(!j.editNodeBlur){j.cancelCurEditNode(G)}}).bind("keydown",function(I){if(I.keyCode=="13"){j.editNodeBlur=true;j.cancelCurEditNode(G)}else{if(I.keyCode=="27"){j.cancelCurEditNode(G,null,true)}}}).bind("click",function(I){return false}).bind("dblclick",function(I){return false});i(H,q.id.A,G).addClass(q.node.CURSELECTED_EDIT);D.curEditInput=E;D.noSelection=false;D.curEditNode=H},moveNode:function(N,G,Q,F,ab,H){var S=A.getRoot(N),L=N.data.key.children;if(G==Q){return}if(N.data.keep.leaf&&G&&!G.isParent&&F==q.move.TYPE_INNER){return}var V=(Q.parentTId?Q.getParentNode():S),P=(G===null||G==S);if(P&&G===null){G=S}if(P){F=q.move.TYPE_INNER}var D=(G.parentTId?G.getParentNode():S);if(F!=q.move.TYPE_PREV&&F!=q.move.TYPE_NEXT){F=q.move.TYPE_INNER}if(F==q.move.TYPE_INNER){if(P){Q.parentTId=null}else{if(!G.isParent){G.isParent=true;G.open=!!G.open;j.setNodeLineIcos(N,G)}Q.parentTId=G.tId}}var I,K;if(P){I=N.treeObj;K=I}else{if(!H&&F==q.move.TYPE_INNER){j.expandCollapseNode(N,G,true,false)}else{if(!H){j.expandCollapseNode(N,G.getParentNode(),true,false)}}I=i(G,N);K=i(G,q.id.UL,N); +if(!!I.get(0)&&!K.get(0)){var Z=[];j.makeUlHtml(N,G,Z,"");I.append(Z.join(""))}K=i(G,q.id.UL,N)}var X=i(Q,N);if(!X.get(0)){X=j.appendNodes(N,Q.level,[Q],null,-1,false,true).join("")}else{if(!I.get(0)){X.remove()}}if(K.get(0)&&F==q.move.TYPE_INNER){K.append(X)}else{if(I.get(0)&&F==q.move.TYPE_PREV){I.before(X)}else{if(I.get(0)&&F==q.move.TYPE_NEXT){I.after(X)}}}var U,T,J=-1,W=0,aa=null,E=null,Y=Q.level;if(Q.isFirstNode){J=0;if(V[L].length>1){aa=V[L][1];aa.isFirstNode=true}}else{if(Q.isLastNode){J=V[L].length-1;aa=V[L][J-1];aa.isLastNode=true}else{for(U=0,T=V[L].length;U<T;U++){if(V[L][U].tId==Q.tId){J=U;break}}}}if(J>=0){V[L].splice(J,1)}if(F!=q.move.TYPE_INNER){for(U=0,T=D[L].length;U<T;U++){if(D[L][U].tId==G.tId){W=U}}}if(F==q.move.TYPE_INNER){if(!G[L]){G[L]=new Array()}if(G[L].length>0){E=G[L][G[L].length-1];E.isLastNode=false}G[L].splice(G[L].length,0,Q);Q.isLastNode=true;Q.isFirstNode=(G[L].length==1)}else{if(G.isFirstNode&&F==q.move.TYPE_PREV){D[L].splice(W,0,Q);E=G;E.isFirstNode=false;Q.parentTId=G.parentTId;Q.isFirstNode=true;Q.isLastNode=false}else{if(G.isLastNode&&F==q.move.TYPE_NEXT){D[L].splice(W+1,0,Q);E=G;E.isLastNode=false;Q.parentTId=G.parentTId;Q.isFirstNode=false;Q.isLastNode=true}else{if(F==q.move.TYPE_PREV){D[L].splice(W,0,Q)}else{D[L].splice(W+1,0,Q)}Q.parentTId=G.parentTId;Q.isFirstNode=false;Q.isLastNode=false}}}A.fixPIdKeyValue(N,Q);A.setSonNodeLevel(N,Q.getParentNode(),Q);j.setNodeLineIcos(N,Q);j.repairNodeLevelClass(N,Q,Y);if(!N.data.keep.parent&&V[L].length<1){V.isParent=false;V.open=false;var O=i(V,q.id.UL,N),R=i(V,q.id.SWITCH,N),M=i(V,q.id.ICON,N);j.replaceSwitchClass(V,R,q.folder.DOCU);j.replaceIcoClass(V,M,q.folder.DOCU);O.css("display","none")}else{if(aa){j.setNodeLineIcos(N,aa)}}if(E){j.setNodeLineIcos(N,E)}if(!!N.check&&N.check.enable&&j.repairChkClass){j.repairChkClass(N,V);j.repairParentChkClassWithSelf(N,V);if(V!=Q.parent){j.repairParentChkClassWithSelf(N,Q)}}if(!H){j.expandCollapseParentNode(N,Q.getParentNode(),true,ab)}},removeEditBtn:function(D,E){i(E,q.id.EDIT,D).unbind().remove()},removeRemoveBtn:function(D,E){i(E,q.id.REMOVE,D).unbind().remove()},removeTreeDom:function(D,E){E.isHover=false;j.removeEditBtn(D,E);j.removeRemoveBtn(D,E);v.apply(D.view.removeHoverDom,[D.treeId,E])},repairNodeLevelClass:function(E,G,F){if(F===G.level){return}var H=i(G,E),K=i(G,q.id.A,E),J=i(G,q.id.UL,E),D=q.className.LEVEL+F,I=q.className.LEVEL+G.level;H.removeClass(D);H.addClass(I);K.removeClass(D);K.addClass(I);J.removeClass(D);J.addClass(I)},selectNodes:function(G,E){for(var F=0,D=E.length;F<D;F++){j.selectNode(G,E[F],F>0)}}},t={tools:h,view:d,event:g,data:p};f.extend(true,f.fn.zTree.consts,C);f.extend(true,f.fn.zTree._z,t);var b=f.fn.zTree,v=b._z.tools,q=b.consts,j=b._z.view,A=b._z.data,s=b._z.event,i=v.$;A.exSetting(m);A.addInitBind(n);A.addInitUnBind(z);A.addInitCache(c);A.addInitNode(w);A.addInitProxy(o);A.addInitRoot(x);A.addZTreeTools(k);var u=j.cancelPreSelectedNode;j.cancelPreSelectedNode=function(F,G){var H=A.getRoot(F).curSelectedList;for(var E=0,D=H.length;E<D;E++){if(!G||G===H[E]){j.removeTreeDom(F,H[E]);if(G){break}}}if(u){u.apply(j,arguments)}};var y=j.createNodes;j.createNodes=function(G,H,E,D,F){if(y){y.apply(j,arguments)}if(!E){return}if(j.repairParentChkClassWithSelf){j.repairParentChkClassWithSelf(G,D)}};var r=j.makeNodeUrl;j.makeNodeUrl=function(D,E){return D.edit.enable?null:(r.apply(j,arguments))};var a=j.removeNode;j.removeNode=function(E,F){var D=A.getRoot(E);if(D.curEditNode===F){D.curEditNode=null}if(a){a.apply(j,arguments)}};var B=j.selectNode;j.selectNode=function(F,G,E){var D=A.getRoot(F);if(A.isSelectedNode(F,G)&&D.curEditNode==G&&G.editNameFlag){return false}if(B){B.apply(j,arguments)}j.addHoverDom(F,G);return true};var e=v.uCanDo;v.uCanDo=function(E,F){var D=A.getRoot(E);if(F&&(v.eqs(F.type,"mouseover")||v.eqs(F.type,"mouseout")||v.eqs(F.type,"mousedown")||v.eqs(F.type,"mouseup"))){return true}if(D.curEditNode){j.editNodeBlur=false;D.curEditInput.focus()}return(!D.curEditNode)&&(e?e.apply(j,arguments):true)}})(jQuery); \ No newline at end of file diff --git a/hyhproject/admin/view/login.html b/hyhproject/admin/view/login.html new file mode 100755 index 0000000..95c81fd --- /dev/null +++ b/hyhproject/admin/view/login.html @@ -0,0 +1,63 @@ +<!DOCTYpE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<meta http-equiv="X-Ua-Compatible" content="IE=edge"> +<meta name="Keywords" content=""/> +<meta name="Description" content=""/> +<link rel="stylesheet" href="__STATIC__/plugins/layui/css/layui.css" type="text/css" /> +<link href="__ADMIN__/css/login.css?v={$v}" rel="stylesheet" type="text/css" /> +<title>后台管理中心登录 - {:WSTConf('CONF.mallName')}</title> +</head> +<body id="loginFrame"> + +<div class="wst-lo-center "> + <div class="wst-lo"> + <div class="login-header"> + <div class='login_logo'> + <!--<img src="__ADMIN__/img/login_logo.png">--> + </div> + <div class="login_title"> + <div class='title_cn'> 后台管理系统</div> + <div class='title_en'>Background Management System</div> + </div> + <div class="wst-clear"></div> + </div> + <div class="login-wrapper"> + <div class="boxbg2"></div> + <div class="box"> + <div class="content-wrap"> + <div class="login-box"> + <div class="login-head"><img src="__ADMIN__/img/login_head.png"></div> + <div class="login-icon1"></div> + <div class="login-icon2"></div> + <div class="login-icon3"></div> + <input id='loginName' type="text" class="layui-input ipt "> + <input id='loginPwd' type="password" class="layui-input ipt"> + <div class="frame"> + <input type='text' id='verifyCode' class='layui-input ipt text2'> + <img id='verifyImg' src="{:url('admin/index/getVerify')}" onclick='javascript:getVerify(this)'> + </div> + </div> + <button id="loginbtn" type="button" onclick='javascript:login()' class="layui-btn layui-btn-big layui-btn-normal" style="width: 100%;">登&nbsp;&nbsp;&nbsp;&nbsp;录</button> + </div> + </div> + </div> + <div class="login-footer"> + <div class="line1"></div> + <div class="line2"></div>{:WSTConf('CONF.mallName')}</div> + </div> +</div> + +<input type='hidden' id='token' value='{:WSTConf("CONF.pwdModulusKey")}'/> +<script type='text/javascript' src='__STATIC__/js/jquery.min.js'></script> +<script> +window.conf = {"DOMAIN":"{:str_replace('index.php','',$Request.root.true)}","ROOT":"__ROOT__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} +</script> +<script type='text/javascript' src='__STATIC__/js/common.js'></script> +<script language="javascript" type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__ADMIN__/js/common.js'></script> +<script src="__ADMIN__/js/login.js?v={$v}" type="text/javascript"></script> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/admin/view/logmoneys/box.html b/hyhproject/admin/view/logmoneys/box.html new file mode 100755 index 0000000..1faa12c --- /dev/null +++ b/hyhproject/admin/view/logmoneys/box.html @@ -0,0 +1,36 @@ +<form id="userForm" autocomplete="off" > +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>账号<font color='red'>*</font>:</th> + <td width='370'> + {$object['loginName']}{if $object['userName']!=''}({$object['userName']}){/if} + </td> + </tr> + <tr> + <th width='150'>类型<font color='red'>*</font>:</th> + <td width='370'> + <lable><input type='radio' name='moneyType' value='1'/>充值 </lable> + <lable><input type='radio' name='moneyType' value='0'/>提现 </lable> + </td> + </tr> + <tr> + <th width='150'>充值金额<font color='red'>*</font>:</th> + <td width='370'> + <input type='text' id='money' maxLength='5'/> + </td> + </tr> + <tr> + <th width='150'>充值备注<font color='red'>*</font>:</th> + <td width='370'> + <textarea style='width:80%;height:50px;' id='remark'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <input type="hidden" name="id" id="userId" class="ipt" value="<?=(int)$object['userId']?>" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> \ No newline at end of file diff --git a/hyhproject/admin/view/logmoneys/list.html b/hyhproject/admin/view/logmoneys/list.html new file mode 100755 index 0000000..4985f2f --- /dev/null +++ b/hyhproject/admin/view/logmoneys/list.html @@ -0,0 +1,41 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/logmoneys/logmoneys.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this" >会员</li> + <li >商家</li> + </ul> + <div class="layui-tab-content" style="padding: 0px 0;"> + <div id="template_user" class="layui-tab-item layui-show"> + <div class="wst-toolbar"> + 账号:<input type='text' id='key1' placeholder='账号'/> + <button class="btn btn-primary" onclick="javascript:loadUserGrid(0)"><i class="fa fa-search"></i>查询</button> + </div> + <div class='wst-grid'> + <div id="mmg1" class="mmg1"></div> + <div id="pg1" style="text-align: right;"></div> + </div> + </div> + <div id="template_shop" class="layui-tab-item "> + <div class="wst-toolbar"> + 账号:<input type='text' id='key2' placeholder='账号/店铺名称'/> + <button class="btn btn-primary" onclick="javascript:loadShopGrid(0)"><i class="fa fa-search"></i>查询</button> + </div> + <div class='wst-grid'> + <div id="mmg2" class="mmg2"></div> + <div id="pg2" style="text-align: right;"></div> + </div> + </div> + </div> +</div> +<script> +$(function(){initTab();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/logmoneys/list_log.html b/hyhproject/admin/view/logmoneys/list_log.html new file mode 100755 index 0000000..a0404aa --- /dev/null +++ b/hyhproject/admin/view/logmoneys/list_log.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/logmoneys/logmoneys.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">{$object['userName']}({$object['loginName']})资金流水</li> + </ul> + <div class="layui-tab-content" style='padding:0px;'> + <div class="layui-tab-item layui-show"> + <div class="wst-toolbar"> + <input type="text" id="startDate" name="startDate" class="ipt laydate-icon" maxLength="20" /> + 至 + <input type="text" id="endDate" name="endDate" class="ipt laydate-icon" maxLength="20" /> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:loadMoneyGrid({$object['userType']},{$object['userId']})'><i class="fa fa-search"></i>查询</button> + <button type="button" class="btn f-right" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + <div style='clear: both'></div> + </div> + <div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> + </div> + </div> +</div> +<script> + $(function(){moneyGridInit({$object['userType']},{$object['userId']});}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/logmoneys/logmoneys.js b/hyhproject/admin/view/logmoneys/logmoneys.js new file mode 100755 index 0000000..d73b410 --- /dev/null +++ b/hyhproject/admin/view/logmoneys/logmoneys.js @@ -0,0 +1,134 @@ +var mmg1,mmg2,mmg3,h; +function initTab(){ + var element = layui.element; + var isInit = false; + element.on('tab(msgTab)', function(data){ + if(data.index==1){ + if(!isInit){ + isInit = true; + shopGridInit(); + }else{ + loadShopGrid(); + } + } + }); + userGridInit(); +} +function userGridInit(){ + h = WST.pageHeight(); + var cols = [ + {title:'账号', name:'loginName', width: 50,sortable: true}, + {title:'名称', name:'userName' ,width:80,sortable: true}, + {title:'可用金额', name:'userMoney' ,width:200,sortable: true,renderer: function (rowdata, rowindex, value){ + return '¥'+rowindex['userMoney']; + }}, + {title:'冻结金额', name:'lockMoney' ,width:70,sortable: true,renderer: function (rowdata, rowindex, value){ + return '¥'+rowindex['lockMoney']; + }}, + {title:'操作', name:'op' ,width:20,renderer: function (val,item,rowIndex){ + return '<a class="btn btn-blue" href="javascript:tologmoneys(0,'+item['userId']+')"><i class="fa fa-search"></i>查看</a>'; + }} + ]; + + mmg1 = $('.mmg1').mmGrid({ + height: h-120, + indexCol: true, + indexColWidth:50, + cols: cols, + method:'POST', + url: WST.U('admin/logmoneys/pageQueryByUser'), + fullWidthRows:true, + autoLoad: true, + remoteSort:true , + sortName: 'userMoney', + sortStatus: 'desc', + plugins: [ + $('#pg1').mmPaginator({}) + ] + }); +} +function shopGridInit(){ + h = WST.pageHeight(); + var cols = [ + {title:'账号', name:'loginName', width: 50}, + {title:'商家', name:'shopName' ,width:80}, + {title:'可用金额', name:'shopMoney' ,width:200,renderer: function (rowdata, rowindex, value){ + return '¥'+rowindex['shopMoney']; + }}, + {title:'冻结金额', name:'lockMoney' ,width:70,renderer: function (rowdata, rowindex, value){ + return '¥'+rowindex['lockMoney']; + }}, + {title:'操作', name:'op' ,width:20,renderer: function (val,item,rowIndex){ + return '<a class="btn btn-blue" href="javascript:tologmoneys(1,'+item['shopId']+')"><i class="fa fa-search"></i>查看</a>'; + }} + ]; + + mmg2 = $('.mmg2').mmGrid({height: h-120,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/logmoneys/pageQueryByShop'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg2').mmPaginator({}) + ] + }); +} +function loadUserGrid(){ + mmg1.load({page:1,key:$('#key1').val()}); +} +function loadShopGrid(){ + mmg2.load({page:1,key:$('#key2').val()}); +} +function tologmoneys(t,id){ + location.href= WST.U('admin/logmoneys/tologmoneys','id='+id+"&type="+t+"&startDate="+$('#startDate').val()+"&endDate="+'&endDate='+$('#endDate').val()); +} + +function moneyGridInit(type,id){ + var h = WST.pageHeight(); + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var cols = [ + // {title:'来源', name:'dataSrc', width: 30}, + {title:'金额', name:'money' ,width:200,renderer: function (rowdata, rowindex, value){ + if(rowindex['moneyType']==1){ + return '<font color="red">+¥'+rowindex['money']+'</font>'; + }else{ + return '<font color="green">-¥'+rowindex['money']+'</font>'; + } + }}, + {title:'券种', name:'moneyName' ,width:200,renderer: function (rowdata, rowindex, value){ + var str = ''; + switch(rowdata){ + case 1: + str = '产品券'; + break; + case 2: + str = '优惠券'; + break; + case 3: + str = '旺旺券'; + break; + case 4: + str = '现金'; + break; + } + return str; + }}, + {title:'备注', name:'remark',width:370}, + {title:'外部流水', name:'tradeNo',width:120}, + {title:'日期', name:'createTime' ,width:60} + ]; + + mmg3 = $('.mmg').mmGrid({height: h-120,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/logmoneys/pageQuery','type='+type+'&id='+id), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +function loadMoneyGrid(t,id){ + mmg3.load({page:1,id:id,type:t,startDate:$('#startDate').val(),endDate:$('#endDate').val()}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/logoperates/list.html b/hyhproject/admin/view/logoperates/list.html new file mode 100755 index 0000000..cd63ff8 --- /dev/null +++ b/hyhproject/admin/view/logoperates/list.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/logoperates/logoperates.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于查看商城职员的操作日志信息。点击“查看”可以查看该操作传送到后台的传送内容。</li> + </ul> +</div> +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" placeholder='开始日期' maxLength="20" /> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" placeholder='结束日期' maxLength="20" /> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='viewBox' style='display:none;'> +<table class='wst-form wst-box-top'> + <tr> + <td id='content' style='word-break:break-all;'></td> + </tr> +</table> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/logoperates/logoperates.js b/hyhproject/admin/view/logoperates/logoperates.js new file mode 100755 index 0000000..66d56e7 --- /dev/null +++ b/hyhproject/admin/view/logoperates/logoperates.js @@ -0,0 +1,57 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var h = WST.pageHeight(); + var cols = [ + {title:'职员', name:'staffName', width: 50}, + {title:'操作功能', name:'operateDesc' ,width:80,renderer: function (val,item,rowIndex){ + return item['menuName']+"-"+item['operateDesc']; + }}, + {title:'访问路径', name:'operateUrl' ,width:200}, + {title:'操作IP', name:'operateIP' ,width:70}, + {title:'操作时间', name:'operateTime' ,width:70}, + {title:'传递参数', name:'op' ,width:30,renderer: function (val,item,rowIndex){ + return "<a class='btn btn-blue' onclick='javascript:toView("+item['operateId']+")'><i class='fa fa-search'></i>查看</a>"; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true,indexColWidth:50,cols: cols,method:'POST', + url: WST.U('admin/logoperates/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); +}) +function loadGrid(){ + mmg.load({page:1,startDate:$('#startDate').val(),endDate:$('#endDate').val()}); +} +function toView(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/logoperates/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status==1){ + $('#content').html(json.data.content); + var box = WST.open({ title:"传递参数",type: 1,area: ['500px', '350px'], + content:$('#viewBox'), + btn:['关闭'], + end:function(){$('#viewBox').hide();}, + yes: function(index, layero){ + layer.close(box); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/logsms/list.html b/hyhproject/admin/view/logsms/list.html new file mode 100755 index 0000000..c6969c0 --- /dev/null +++ b/hyhproject/admin/view/logsms/list.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/logsms/logsms.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于查看商城短信的发送情况。“消息内容”仅做调试参考,不是实际发送内容。</li> + </ul> +</div> +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" placeholder='开始日期' maxLength="20" /> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" placeholder='结束日期' maxLength="20" /> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='viewBox' style='display:none;'> +<table class='wst-form wst-box-top'> + <tr> + <td id='content' style='word-break:break-all;'></td> + </tr> +</table> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/logsms/logsms.js b/hyhproject/admin/view/logsms/logsms.js new file mode 100755 index 0000000..b25353e --- /dev/null +++ b/hyhproject/admin/view/logsms/logsms.js @@ -0,0 +1,35 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var h = WST.pageHeight(); + var cols = [ + {title:'使用者ID', name:'smsUserId', width: 30}, + {title:'消息内容', name:'smsContent' ,width:120}, + {title:'消息代码', name:'smsCode' ,width:120}, + {title:'发送方式', name:'smsFunc' ,width:80}, + {title:'发送号码', name:'smsPhoneNumber' ,width:100}, + {title:'消息IP', name:'smsIP' ,width:70}, + {title:'发送时间', name:'createTime' ,width:70}, + {title:'返回状态', name:'smsReturnCode' ,width:30} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true,indexColWidth:50,cols: cols,method:'POST', + url: WST.U('admin/logsms/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); +}) +function loadGrid(){ + mmg.load({page:1,startDate:$('#startDate').val(),endDate:$('#endDate').val()}); +} diff --git a/hyhproject/admin/view/logstafflogins/list.html b/hyhproject/admin/view/logstafflogins/list.html new file mode 100755 index 0000000..8e43e6b --- /dev/null +++ b/hyhproject/admin/view/logstafflogins/list.html @@ -0,0 +1,26 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/logstafflogins/logstafflogins.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于查看商城职员的登录日志信息。</li> + </ul> +</div> +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" placeholder='开始日期' maxLength="20" /> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" placeholder='结束日期' maxLength="20" /> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/logstafflogins/logstafflogins.js b/hyhproject/admin/view/logstafflogins/logstafflogins.js new file mode 100755 index 0000000..f33f107 --- /dev/null +++ b/hyhproject/admin/view/logstafflogins/logstafflogins.js @@ -0,0 +1,30 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var h = WST.pageHeight(); + var cols = [ + {title:'职员', name:'staffName', width: 50}, + {title:'登录时间', name:'loginTime' ,width:100}, + {title:'登录IP', name:'loginIp' ,width:100} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true,indexColWidth:50,cols: cols,method:'POST', + url: WST.U('admin/logstafflogins/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); +}) +function loadGrid(){ + mmg.load({page:1,startDate:$('#startDate').val(),endDate:$('#endDate').val()}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/main.html b/hyhproject/admin/view/main.html new file mode 100755 index 0000000..a6ca679 --- /dev/null +++ b/hyhproject/admin/view/main.html @@ -0,0 +1,422 @@ +{extend name="base" /} + +{block name="js"} + +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> + +<script src="__ADMIN__/js/main.js?v={$v}" type="text/javascript"></script> + +<script> + +function enterLicense(){ + + location.href='{:Url("admin/index/enterLicense")}'; + +} + +</script> + +{/block} + +{block name="main"} +<div width='100%' border='0' class="layui-row"> + + <div class="layui-col-md12" > + + <div class="wst-total wst-summary"> + + <div class='wst-summary-head layui-col-md12'> + + <span class="content">全部概况</span> + + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/13.png"/></div> + <div class="data"> + <p class="data-top" style="color: #e14e5f;">{$object['qlg']['fastPay']}</p> + <div class="data-bottom">代快付值</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/14.png"/></div> + <div class="data"> + <p class="data-top" style="color: #fabd3a;;">{$object['qlg']['slowPay']}</p> + <div class="data-bottom">代慢付值</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/15.png"/></div> + <div class="data"> + <p class="data-top" style="color: #f1635f;">{$object['qlg']['vouchersSummarySum']}</p> + <div class="data-bottom">预代付值</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/1.png"/></div> + <div class="data"> + <p class="data-top" style="color: #00a9ed;">{$object['qlg']['personalCount']}</p> + <div class="data-bottom">个体认证数</div> + </div> + </div> + </div> + + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/2.png"/></div> + <div class="data"> + <p class="data-top" style="color: #4ce1f9;">{$object['qlg']['companyCount']}</p> + <div class="data-bottom">合作认证数</div> + </div> + </div> + </div> + + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/3.png"/></div> + <div class="data"> + <p class="data-top" style="color: #f9be5e;">{$object['qlg']['updateCount']}</p> + <div class="data-bottom">合作商数量</div> + </div> + </div> + </div> + + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/4.png"/></div> + <div class="data"> + <p class="data-top" style="color: #b3705a;">{$object['qlg']['shopCount']}</p> + <div class="data-bottom">已上线店铺</div> + </div> + </div> + </div> + + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/5.png"/></div> + <div class="data"> + <p class="data-top" style="color: #4bc38b;">{$object['qlg']['payCount']}</p> + <div class="data-bottom">已消费用户数</div> + </div> + </div> + </div> + + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/6.png"/></div> + <div class="data"> + <p class="data-top" style="color: #5aa237;">{$object['qlg']['orderSum']}</p> + <div class="data-bottom">已完成订单总额</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/10.png"/></div> + <div class="data"> + <p class="data-top" style="color: #7e5dcc;">{$object['qlg']['productSum']}</p> + <div class="data-bottom">产品券抵现</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/11.png"/></div> + <div class="data"> + <p class="data-top" style="color: #fc822b;">{$object['qlg']['couponsSum']}</p> + <div class="data-bottom">优惠券抵现</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/12.png"/></div> + <div class="data"> + <p class="data-top" style="color: #1fafec;">{$object['qlg']['wangSum']}</p> + <div class="data-bottom">旺旺券抵现</div> + </div> + </div> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <a href="/admin/users/personalreview.html"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/7.png"/></div> + <div class="data"> + <p class="data-top" style="color: #2e7cbf;">{$object['qlg']['personalWaitCount']}</p> + <div class="data-bottom">个体待审核</div> + </div> + </div> + </a> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <a href="/admin/users/companyreview.html"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/8.png"/></div> + <div class="data"> + <p class="data-top" style="color: #fcc639;">{$object['qlg']['companyWaitCount']}</p> + <div class="data-bottom">合作待审核</div> + </div> + </div> + </a> + </div> + <div class="layui-col-md4" style="height: auto;overflow: hidden;"> + <a href="/admin/users/userupdatelist.html"> + <div class="wst-summary-content"> + <div class="img"><img src="__ADMIN__/img/9.png"/></div> + <div class="data"> + <p class="data-top" style="color: #ee2d18;">{$object['qlg']['updateWaitCount']}</p> + <div class="data-bottom">合作商待审核</div> + </div> + </div> + </a> + </div> + </div> + + </div> + + + +</div> +<div width='100%' border='0' class="layui-row"> + + <div class="layui-col-md12" > + + <div class="wst-total wst-summary"> + + <div class='wst-summary-head layui-col-md12'> + + <span class="content">今日统计</span> + + </div> + + <div class="layui-col-md4"style="height: auto;overflow: hidden;"> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info1.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #73c734;">{$object['tody']['userType0']}</p> + + <div class="data-bottom">今日新增会员</div> + + </div> + + </div> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info4.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #1fafec;">{$object['tody']['userType1']}</p> + + <div class="data-bottom">今日新增商家</div> + + </div> + + </div> + + </div> + + <div class="layui-col-md4"style="height: auto;overflow: hidden;"> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info2.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #15b5e9;">{$object['tody']['shopApplys']}</p> + + <div class="data-bottom">今日开店申请</div> + + </div> + + </div> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info5.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #0c8ae1;">{$object['tody']['compalins']}</p> + + <div class="data-bottom">今日新增投诉</div> + + </div> + + </div> + + </div> + + <div class="layui-col-md4"style="height: auto;overflow: hidden;"> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info3.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #da53d3;">{$object['mall']['saleGoods']}/{$object['tody']['auditGoods']}</p> + + <div class="data-bottom">上架商品/待审核</div> + + </div> + + </div> + + <div class="wst-summary-content"> + + <div class="img"><img src="__ADMIN__/img/img_info6.png"/></div> + + <div class="data"> + + <p class="data-top" style="color: #ae1aa2;">{$object['tody']['order']}</p> + + <div class="data-bottom">今日新增订单</div> + + </div> + + </div> + + </div> + + </div> + + <div class="wst-total wst-summary"> + + <div class='wst-summary-head layui-col-md12'> + + <span class="content">商城统计</span> + + </div> + + <div class="wst-summary-content2 layui-col-md6"> + + <div class="wst-strip"> + + <div class="wst-title">会员总数</div> + + <img src="__ADMIN__/img/img_info1-1.png"/><span class="wst-num">{$object['mall']['userType0']}个</span> + + </div> + + <div class="wst-strip"> + + <div class="wst-title">上架商品总数/待审核数</div> + + <img src="__ADMIN__/img/img_info3-1.png"/><span class="wst-num">{$object['mall']['saleGoods']}/{$object['mall']['auditGoods']}个</span> + + </div> + + <div class="wst-strip"> + + <div class="wst-title">品牌总数</div> + + <img src="__ADMIN__/img/img_info5-1.png"/><span class="wst-num">{$object['mall']['brands']}个</span> + + </div> + + </div> + + <div class="wst-summary-content2 layui-col-md6"> + + <div class="wst-strip"> + + <div class="wst-title">商家总数</div> + + <img src="__ADMIN__/img/img_info2-1.png"/><span class="wst-num">{$object['mall']['userType1']}个</span> + + </div> + + <div class="wst-strip"> + + <div class="wst-title">订单总数</div> + + <img src="__ADMIN__/img/img_info4-1.png"/><span class="wst-num">0个</span> + + </div> + + <div class="wst-strip"> + + <div class="wst-title">评价总数</div> + + <img src="__ADMIN__/img/img_info6-1.png"/><span class="wst-num">{$object['mall']['appraise']}个</span> + + </div> + + </div> + + </div> + + </div> + + + +</div> + +<div class="wst-total wst-summary" style="height: 400px;> + + <div class='wst-summary-head layui-col-md12'> + + <span class="content">最近1个月新增会员</span> + + <div id="main" style='width:100%;height:350px;'></div> + + </div> + +</div> + +<div class="wst-total wst-summary" style="height: 400px;"> + + <div class='wst-summary-head layui-col-md12'> + + <span class="content">最近1个月订单数</span> + + <div id="main1" style='width:100%;height:350px;'></div> + + </div> + +</div> + +<div class="wst-total wst-summary" style='padding-bottom:40px'> + + + + <div class="wst-system-strip"> + + <div class="title"><span>服务器操作系统:</span></div> + + <div class="text">{$Think.PHP_OS}</div> + + </div> + + <div class="wst-system-strip"> + + <div class="title"><span>PHP版本:</span></div> + + <div class="text">{$Think.PHP_VERSION}</div> + + </div> + + </div> + + + +</div> + +<input type="hidden" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value="{$object['time']['startDate']}" placeholder='开始日期'/> + +<input type="hidden" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value="{$object['time']['endDate']}" placeholder='结束日期'/> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/member/member.html b/hyhproject/admin/view/member/member.html new file mode 100755 index 0000000..09e5395 --- /dev/null +++ b/hyhproject/admin/view/member/member.html @@ -0,0 +1,29 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/member/member.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<input type="text" name="loginName" placeholder='会员名称' id="loginName" class='j-ipt'/> +<input type="text" name="userPhone" placeholder='会员联系方式' id="userPhone" class='j-ipt'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + + <button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExport()'><i class="fa fa-sign-in"></i>导出</button> + +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/member/member.js b/hyhproject/admin/view/member/member.js new file mode 100755 index 0000000..644e8df --- /dev/null +++ b/hyhproject/admin/view/member/member.js @@ -0,0 +1,42 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}); +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'登陆账号', name:'loginName', width: 120,sortable:true}, + {title:'真实姓名', name:'trueName' ,width:60,sortable:true}, + {title:'联系方式', name:'userPhone' ,width:20,sortable:true}, + {title:'最后登录时间', name:'lastTime' ,width:60,sortable:true}, + {title:'登录次数', name:'logNum' ,width:60,sortable:true}, + {title:'订单数量', name:'orderNum' ,width:60,sortable:true}, + {title:'创建时间', name:'createTime' ,width:20,sortable:true,align:'center'}, + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/member/memberByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.page = 1; + mmg.load(params); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/member/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/menus/list.html b/hyhproject/admin/view/menus/list.html new file mode 100755 index 0000000..6e8c3e1 --- /dev/null +++ b/hyhproject/admin/view/menus/list.html @@ -0,0 +1,102 @@ +{extend name="base" /} +{block name="css"} +<link href="__ADMIN__/js/ztree/css/zTreeStyle/zTreeStyle.css?v={$v}" rel="stylesheet" type="text/css" /> +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/ztree/jquery.ztree.all-3.5.js?v={$v}"></script> +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/menus/menu.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>左侧为菜单栏,点击菜单,然后再点击右键添加菜单,菜单中的图标使用<a href='http://fontawesome.dashgame.com/' target='_blank'>Fontawesome</a>图标,不需要fa-前缀。</li> + <li>右侧为菜单对应的操作权限。若想为系统添加一个菜单则要一个设置为“菜单权限”的权限,该菜单才能显示。</li> + <li>该功能为开发者功能,普通使用者请勿随意修改,以免影响系统使用。</li> + </ul> +</div> +<div class="j-layout"> + <div class='j-layout-left'> + <div class='j-layout-panel layui-colla-title'>菜单管理</div> + <ul id="menuTree" class="ztree" style='overflow:auto'></ul> + </div> + <div class='j-layout-center' style='border:1px solid #ccc;float:left;margin-left:5px;'> + <div class='j-layout-panel layui-colla-title'>权限管理</div> + {if WSTGrant('QXGL_01')} + <div class="wst-toolbar" style='display:none'> + <button class="btn btn-success btn-sm f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新&nbsp;增</button> + <div style='clear:both'></div> + </div> + {/if} + <div id="maingrid" style='display:none'> + <div id="mmg" class="mmg"></div> + </div> + </div> + <div style='clear:both;'></div> +</div> +<div id='menuBox' style='display:none'> +<form id='menuForm'> + <input type='hidden' id='parentId' class='ipt2' maxLength='20'/> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>菜单名称<font color='red'>*</font>:</th> + <td><input type='text' id='menuName' class='ipt2' maxLength='20' data-rule="菜单名称: required;"/></td> + </tr> + <tr> + <th width='100'>菜单图标<font color='red'>*</font>:</th> + <td><input type='text' id='menuIcon' class='ipt2' maxLength='20'/></td> + </tr> + <tr> + <th width='100'>菜单排序<font color='red'>*</font>:</th> + <td><input type='text' id='menuSort' class='ipt2' maxLength='5'/></td> + </tr> + </table> +</form> +</div> +<div id='privilegeBox' style='display:none'> + <form id='privilegeForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>权限名称<font color='red'>*</font>:</th> + <td><input type='text' id='privilegeName' class='ipt' maxLength='20' data-rule="权限名称: required;"/></td> + </tr> + <tr> + <th>权限代码<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='privilegeId' value="0" /> + <input type='text' id='privilegeCode' class='ipt' maxLength='30' onblur='javascript:checkPrivilegeCode(this)' data-rule="权限代码: required;"/></td> + </tr> + <tr> + <th>是否菜单权限<font color='red'>*</font>:</th> + <td height='24'> + <label> + <input type="radio" id="isMenuPrivilege1" name="isMenuPrivilege" class="ipt" value="1">是 + </label> + <label> + <input type="radio" id="isMenuPrivilege1" name="isMenuPrivilege" class="ipt" value="0" checked>否 + </label> + </td> + </tr> + <tr> + <th>权限资源:</th> + <td><input type='text' id='privilegeUrl' class='ipt' maxLength='100' style='width:90%'/></td> + </tr> + <tr> + <th>关联资源:<br/>(以,号分隔)&nbsp;&nbsp;&nbsp;</th> + <td> + <textarea id='otherPrivilegeUrl' class='ipt' style='width:90%;height:60px;'></textarea> + </td> + </tr> + </table> + </form> +</div> +<div id="rMenu"> + <ul> + {if WSTGrant('CDGL_01')}<li id="m_add" >新增菜单</li>{/if} + {if WSTGrant('CDGL_02')}<li id="m_edit">编辑菜单</li>{/if} + {if WSTGrant('CDGL_03')}<li id="m_del" style='border-bottom:0px;'>删除菜单</li>{/if} + </ul> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/menus/menu.js b/hyhproject/admin/view/menus/menu.js new file mode 100755 index 0000000..71a1eff --- /dev/null +++ b/hyhproject/admin/view/menus/menu.js @@ -0,0 +1,252 @@ +var zTree,mmg,rMenu; +function layout(){ + var h = WST.pageHeight(); + var w = WST.pageWidth(); + $('.j-layout').width(w-8); + $('.j-layout-left').width(200).height(h-113); + $('.j-layout-center').width(w-220).height(h-113); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?113:53; + $('.j-layout-left').height(h-diff); + $('#menuTree').height(h-diff-40); + $('.j-layout-center').height(h-diff); + }}); +} +function initGrid(){ + var cols = [ + {title:'权限名称', name:'privilegeName', width: 130}, + {title:'权限代码', name:'privilegeCode' ,width:60}, + {title:'是否菜单权限', name:'isMenuPrivilege' ,width:50,renderer: function(val){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 是&nbsp;</span>":"<span class='statu-no'><i class='fa fa-ban'></i> 否&nbsp;</span>"; + }}, + {title:'权限资源', name:'privilegeUrl' ,width:150}, + {title:'关联资源', name:'otherPrivilegeUrl' }, + {title:'操作', name:'' ,width:110, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.QXGL_02)h += "<button class='btn btn-blue' onclick='javascript:getForEdit(" + item['privilegeId'] + ")'><i class='fa fa-pencil'></i>编辑</button> "; + if(WST.GRANT.QXGL_03)h += "<button class='btn btn-red' onclick='javascript:toDel(" + item['privilegeId'] + ")'><i class='fa fa-trash-o'></i>删除</button> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: 'auto',indexCol: true, cols: cols,method:'POST',nowrap: true, + url: WST.U("admin/privileges/listQuery"), fullWidthRows: true, autoLoad: false + }); + $('#m_add').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + editMenu({menuId:0,menuName:'',menuIcon:'',parentId:treeNode.id,pnode:treeNode,menuSort:0}); + }); + $('#m_edit').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + getForEditMenu(treeNode.id); + return false; + }); + $('#m_del').click(function(){ + treeNode = zTree.getSelectedNodes()[0]; + layer.confirm('您确定要删除该菜单['+treeNode.name+']吗?', {btn: ['确定','取消']}, function(){ + var loading = WST.msg('正在提交请求,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/menus/del'),{id:treeNode.id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + zTree.reAsyncChildNodes(treeNode.getParentNode(), "refresh",true); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }); + return false; + }) +} +$(window).resize(function(){layout();}); +$(function(){ + layout(); + $('#menuTree').height(WST.pageHeight()-153); + var setting = { + view: { + selectedMulti: false, + dblClickExpand:false + }, + async: { + enable: true, + url:WST.U('admin/menus/listQuery'), + autoParam:["id", "name=n", "level=lv"] + }, + callback:{ + onRightClick: onRightClick, + onClick: onClick, + onAsyncSuccess: onAsyncSuccess + } + }; + $.fn.zTree.init($("#menuTree"), setting); + zTree = $.fn.zTree.getZTreeObj("menuTree"); + rMenu = $("#rMenu"); + initGrid(); +}) +function loadPrivileges(id){ + mmg.load({page:1,id:id}); +} +function onAsyncSuccess(event, treeId, treeNode, msg){ + var json = WST.toAdminJson(msg); + if(json && json.id==0){ + var treeNode = zTree.getNodeByTId('menuTree_1'); + zTree.reAsyncChildNodes(treeNode, "refresh",true); + zTree.expandAll(treeNode,true); + } +} +function onClick(e,treeId, treeNode){ + if(treeNode.id>0){ + $('.wst-toolbar').show(); + $('#maingrid').show(); + }else{ + $('.wst-toolbar').hide(); + $('#maingrid').hide(); + } + loadPrivileges(treeNode.id); +} +function onRightClick(event, treeId, treeNode) { + if(!treeNode)return; + if(!WST.GRANT.CDGL_01 && !WST.GRANT.CDGL_02 && !WST.GRANT.CDGL_03)return; + if(!treeNode && event.target.tagName.toLowerCase() != "button" && $(event.target).parents("a").length == 0) { + zTree.cancelSelectedNode(); + showRMenu("root", event.clientX, event.clientY); + }else if(treeNode && !treeNode.noR) { + zTree.selectNode(treeNode); + showRMenu("node", event.clientX, event.clientY); + } +} +function showRMenu(type, x, y) { + $("#rMenu ul").show(); + y += document.body.scrollTop; + x += document.body.scrollLeft; + rMenu.css({"top":y+"px", "left":x+"px", "visibility":"visible"}); + $("body").bind("mousedown", onBodyMouseDown); +} +function hideRMenu() { + if (rMenu) rMenu.css({"visibility": "hidden"}); + $("body").unbind("mousedown", onBodyMouseDown); +} +function onBodyMouseDown(event){ + if (!(event.target.id == "rMenu" || $(event.target).parents("#rMenu").length>0)) { + rMenu.css({"visibility" : "hidden"}); + } +} +function getForEditMenu(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/menus/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.menuId){ + editMenu(json); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function editMenu(obj){ + WST.setValues(obj); + var box = WST.open({ title:(obj.menuId==0)?'新增菜单':"编辑菜单",type: 1,area: ['430px', '230px'], + content:$('#menuBox'), + btn:['确定','取消'], + end:function(){$('#menuBox').hide()}, + yes: function(index, layero){ + if(!$('#menuName').isValid())return; + var params = WST.getParams('.ipt2'); + params.menuId = obj.menuId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/menus/'+((params.menuId)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#menuForm')[0].reset(); + treeNode = zTree.getSelectedNodes()[0]; + if(params.menuId){ + zTree.reAsyncChildNodes(treeNode.getParentNode(), "refresh",true); + }else{ + zTree.reAsyncChildNodes(treeNode, "refresh",true); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/privileges/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.privilegeId){ + WST.setValues(json); + toEdit(json.privilegeId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + var title = "新增权限"; + if(id>0){ + title = "编辑权限"; + }else{ + $('#privilegeForm')[0].reset(); + } + $("#privilegeId").val(id); + var box = WST.open({title:title,type:1,content:$('#privilegeBox'),area: ['450px', '350px'],btn:['确定','取消'], + end:function(){$('#privilegeBox').hide()}, + yes:function(){ + if(!$('#privilegeName').isValid())return; + if(!$('#privilegeCode').isValid())return; + var params = WST.getParams('.ipt'); + params.menuId = zTree.getSelectedNodes()[0].id; + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/privileges/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#privilegeForm')[0].reset(); + layer.close(box); + loadPrivileges(params.menuId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该权限吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/privileges/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadPrivileges(zTree.getSelectedNodes()[0].id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function checkPrivilegeCode(obj){ + var privilegeId = $("#privilegeId").val(); + if($.trim(obj.value)=='')return; + var loading = WST.msg('正在检测代码是否存在,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/privileges/checkPrivilegeCode'),{privilegeId:privilegeId,code:obj.value},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status!='1'){ + WST.msg(json.msg,{icon:2}); + $('#privilegeCode').val(''); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/messages/list.html b/hyhproject/admin/view/messages/list.html new file mode 100755 index 0000000..4823f83 --- /dev/null +++ b/hyhproject/admin/view/messages/list.html @@ -0,0 +1,99 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<style> +body{overflow:hidden;} +.layui-tab-content{padding:0px;} +</style> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/messages/message.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">消息列表</li> + <li >发送消息</li> + </ul> + <div class="layui-tab-content" > + <div class="layui-tab-item layui-show"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>发送类型<font color='red'>*</font>:</th> + <td style="text-align:left;" colspan='3' class='layui-form'> + <label><input type="radio" lay-filter="sendType" name="sendType" id="sendType" value="users" class='ipt' checked title='会员'></label> + <label><input type="radio" lay-filter="sendType" name="sendType" id="sendType" value="shop" class='ipt' title='店铺'></label> + <label><input type="radio" lay-filter="sendType" name="sendType" id="theUser" value="theUser" class='ipt' title='指定账号'></label> + </td> + </tr> + <tr id="user_query" style="display:none;"> + <th></th> + <td> + <input type='text' id='loginName' name="loginName" value='' style="width:200px;" maxLength='20' placeholder="请输入要发送消息的账号"/> + + </td> + <td><button type="button" class='btn btn-primary btn-mright' onclick="userQuery()"><i class="fa fa-search"></i>查询</button></td> + </tr> + <tr id="send_to" style="display:none;"> + <th>指定接收账号<font color='red'>*</font>:</th> + <td width="200"> + <select ondblclick="WST.multSelect({left:'ltarget',right:'rtarget',vtarget:'rtarget',val:'htarget'})" size="12" id="ltarget" multiple="" style="width:200px;height:160px;"> + </select> + </td> + <td width="10"> + <input type='hidden' id='htarget' value='' class='ipt'/> + <button onclick="javascript:WST.multSelect({left:'ltarget',right:'rtarget',vtarget:'rtarget',val:'htarget'})" class="btn btn-primary" type="button">&gt;&gt;</button> + <br> + <br> + <button onclick="javascript:WST.multSelect({left:'rtarget',right:'ltarget',vtarget:'rtarget',val:'htarget'})" class="btn btn-primary" type="button">&lt;&lt;</button> + </td> + <td> + <select ondblclick="WST.multSelect({left:'rtarget',right:'ltarget',vtarget:'rtarget',val:'htarget'})" size="12" id="rtarget" multiple="" style="width:200px;height:160px;"> + </select> + </td> + </tr> + + <tr> + <th>消息内容<font color='red'> </font>:</th> + <td colspan="10"> + <textarea class='ipt' name="msgContent" id="msgContent" style="width:700px;height:150px;"></textarea> + </td> + </tr> +{if WSTGrant('SCXX_01')} + <tr> + <td colspan='4' align='center'> + <button type="button" onclick="sendMsg()" class='btn btn-primary btn-mright'><i class="fa fa-share"></i>发送</button> + <button type="button" onclick='javascript:history.go(-1)' class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +{/if} + </table> + +</div> + +<div class="layui-tab-item"> + <div autocomplete='off' class="wst-toolbar"> + <select style="float:left;" name="msgType" id="msgType" class="query"> + <option value="-1">消息类型</option> + <option value="0">手工</option> + <option value="1">系统</option> + </select> + <input type="text" name="msgContent" placeholder='系统内容' id="msgContent" class="query" /> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:msgQuery()"><i class="fa fa-search"></i>查询</button> + </div> + <div style="clear:both"></div> + <table id="mmg" class="mmg"> + <tr> + <th rowspan="" colspan=""></th> + </tr> + </table> + <div id="pg" style="text-align: right;"></div> +</div> + + +</div> + +{/block} + diff --git a/hyhproject/admin/view/messages/message.js b/hyhproject/admin/view/messages/message.js new file mode 100755 index 0000000..420aad7 --- /dev/null +++ b/hyhproject/admin/view/messages/message.js @@ -0,0 +1,162 @@ +var grid; +var h; +$(function(){ + form = layui.form; + form.on('radio(sendType)', function(data){ + if(data.value=='theUser'){ + $('#user_query').show(); + $('#send_to').show(); + }else{ + $('#user_query').hide(); + $('#send_to').hide(); + } + }); + var element = layui.element; + var isInit = false; + element.on('tab(msgTab)', function(data){ + if(data.index==1){ + if(!isInit){ + isInit = true; + initGrid(); + }else{ + msgQuery(); + } + } + }); +}); +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'消息类型', name:'msgType', width: 30,renderer: function(val,item,rowIndex){ + return (val==0)?'手工发送':'系统发送'; + }}, + {title:'发送者', name:'stName' ,width:50}, + {title:'接收者', name:'loginName' ,width:50,renderer: function(val,item,rowIndex){ + return (val!=null)?val:item['shopName']; + }}, + {title:'消息内容', name:'msgContent' ,width:280}, + {title:'阅读状态', name:'msgStatus' ,width:30,renderer: function(val,item,rowIndex){ + return (val==0)?"<span class='statu-no'><i class='fa fa-ban'></i> 未读</span>":"<span class='statu-yes'><i class='fa fa-check-circle'></i> 已读</span>"; + }}, + {title:'有效状态', name:'dataFlag' ,width:30, align:'center',renderer: function(val,item,rowIndex){ + return (val==-1)?"<span class='statu-wait'><i class='fa fa-ban'></i> 已删除</span>":"<span class='statu-yes'><i class='fa fa-check-circle'></i> 有效</span>"; + }}, + {title:'发送时间', name:'createTime' ,width:80}, + + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.SCXX_00)h += "<button class='btn btn-blue' onclick='javascript:showFullMsg("+item['id']+")'><i class='fa fa-search'></i>查看</button> "; + if(WST.GRANT.SCXX_03)h += "<button class='btn btn-red' onclick='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</button> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-120,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Messages/pageQuery'), fullWidthRows: true, autoLoad: false, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + msgQuery(); +} + + + +function showFullMsg(id){ + parent.showBox({title:'内容详情',type:2,content:WST.U('admin/messages/showFullMsg','id='+id),area: ['800px', '500px'],btn:['关闭']}); + +} + +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/messages/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + msgQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +//切换卡 +$(function (){ +//编辑器 +KindEditor.ready(function(K) { +editor1 = K.create('textarea[name="msgContent"]', { + uploadJson : WST.conf.ROOT+'/admin/messages/editorUpload', + height:'350px', + allowFileManager : false, + allowImageUpload : true, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } +}); +}); +}); + + +function sendToTheUser(t){ + if($('#theUser').prop('checked')){ + $('#user_query').show(); + $('#send_to').show(); + }else{ + $('#user_query').hide(); + $('#send_to').hide(); + } + + } + //账号模糊查找 + function userQuery(){ + var key = $('#loginName').val(); + var html = ''; + $.post(WST.U('admin/messages/userQuery'),{'loginName':key},function(text,dataStatus){ + $(text).each(function(k,v){ + html += '<option value="'+v.userId+'">'+v.loginName+'</option>'; + }); + $('#ltarget').html(html); + }); + + } + //发送消息 + function sendMsg(){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/messages/add'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#ltarget').html(''); + $('#rtarget').html(''); + $('#loginName').val(''); + editor1.html(''); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + + +function msgQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); + } + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/messages/msg.html b/hyhproject/admin/view/messages/msg.html new file mode 100755 index 0000000..f274b4d --- /dev/null +++ b/hyhproject/admin/view/messages/msg.html @@ -0,0 +1,15 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/messages/message.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins//kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +{/block} +{block name="main"} +<style> +body{overflow:auto;padding:5px;} +</style> +<div class="l-loading" style="display: block" id="wst-loading"></div> +<div id="msg"> + <p>{$data['msgContent']}</p> +</div> +{/block} + diff --git a/hyhproject/admin/view/mobilebtns/list.html b/hyhproject/admin/view/mobilebtns/list.html new file mode 100755 index 0000000..b082e0d --- /dev/null +++ b/hyhproject/admin/view/mobilebtns/list.html @@ -0,0 +1,87 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/mobilebtns/mobilebtns.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于设置移动/微信端顶部按钮图标及其链接地址。若“所属插件”栏有值的记录请谨慎操作,以免造成插件新增或者删除失败。</li> + </ul> +</div> +<form autocomplete="off"> +<div class="wst-toolbar"> + <select id="btnSrc1" class="query"> + <option value="-1">请选择按钮位置</option> + <option value="0">手机版</option> + <option value="1">微信版</option> + </select> + <input type="text" name="btnName" placeholder="按钮名称" id="btnName1" class="query"> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:loadGrid()"><i class="fa fa-search"></i>查询</button> + {if WSTGrant('ANGL_01')} + <button type='button' class="btn btn-success f-right btn-fixtop" onclick="javascript:toEdit(0)"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +</form> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> + +<div id='mbtnBox' style='display:none'> + <form id='mbtnForm' method="post" autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>按钮名称<font color='red'>*</font>:</th> + <td><input type='text' id='btnName' name="btnName" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th width='150'>按钮Url<font color='red'>*</font>:</th> + <td><input type='text' id='btnUrl' name="btnUrl" class='ipt' /></td> + </tr> + <tr> + <th>图标:</th> + <td> + <div id='adFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='btnImg' name="btnImg" class="ipt" /> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="max-height:70px;max-width:70px;" id="preview"></div></td> + </tr> + <tr> + <th>按钮类别:</th> + <td> + <select id="btnSrc" class="ipt"> + <option value="0">手机版</option> + <option value="1">微信版</option> + </select> + </td> + </tr> + <tr> + <th>所属插件:</th> + <td> + <input type="text" id="addonsName" class="ipt" /> + </td> + </tr> + <tr> + <th>排序号:</th> + <td> + <input type="text" id="btnSort" class="ipt" /> + </td> + </tr> + </table> + </form> + </div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/mobilebtns/mobilebtns.js b/hyhproject/admin/view/mobilebtns/mobilebtns.js new file mode 100755 index 0000000..ac55bba --- /dev/null +++ b/hyhproject/admin/view/mobilebtns/mobilebtns.js @@ -0,0 +1,170 @@ +var mmg,isInitUpload = false; +function initGrid(staffId){ + var h = WST.pageHeight(); + var cols = [ + {title:'图标', name:'btnImg', width: 50,renderer: function(val,item,rowIndex){ + return '<img src="'+WST.conf.IMGURL+'/'+item['btnImg']+'" height="60px" style="margin-top:5px;" />'; + }}, + {title:'按钮名称', name:'btnName' ,width:60}, + {title:'按钮Url', name:'btnUrl' ,width:350}, + {title:'按钮类别', name:'btnSrc' ,width:20,renderer: function(val,item,rowIndex){ + return val==0?'手机版':'微信版'; + }}, + {title:'所属插件', name:'addonsName' ,width:20}, + {title:'排序号', name:'btnSort' ,width:10}, + {title:'操作', name:'' ,width:100, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.ANGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit(" + item['id'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.ANGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-155),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/mobilebtns/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); + +} +function loadGrid(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/mobileBtns/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.id){ + WST.setValues(json); + //显示原来的图片 + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.btnImg+'" height="70px;"/>'); + $('#isImg').val('ok'); + toEdit(json.id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + if(!isInitUpload){ + initUpload(); + isInitUpload = true; + } + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#mbtnBox'),area: ['450px', '400px'],btn: ['确定','取消'],yes:function(){ + $('#mbtnForm').submit(); + },cancel:function(){ + //重置表单 + $('#mbtnForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#btnImg').val(''); + + },end:function(){ + //重置表单 + $('#mbtnForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + $('#btnImg').val(''); + $('#mbtnBox').hide(); + + }}); + $('#mbtnForm').validator({ + fields: { + btnName: { + rule:"required;", + msg:{required:"请输入按钮名称"}, + tip:"请输入按钮名称", + ok:"", + }, + btnUrl: { + rule:"required;", + msg:{required:"请输入按Url"}, + tip:"请输入按Url", + ok:"", + }, + btnImg: { + rule:"required;", + msg:{required:"请上传图标"}, + tip:"请上传图标", + ok:"", + }, + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/mobileBtns/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#mbtnForm')[0].reset(); + //清空预览图 + $('#preview').html(''); + //清空图片隐藏域 + $('#btnImg').val(''); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} +function initUpload(){ + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'sysconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#btnImg').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } +}); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/mobileBtns/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/navs/edit.html b/hyhproject/admin/view/navs/edit.html new file mode 100755 index 0000000..8b78a8f --- /dev/null +++ b/hyhproject/admin/view/navs/edit.html @@ -0,0 +1,72 @@ + +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/navs/navs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form id="navForm"> +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>导航位置<font color='red'> </font>:</th> + <td> + <select id="navType" class='ipt' maxLength='20'> + <option value="0">顶部</option> + <option value="1">底部</option> + </select> + </td> + </tr> + <tr> + <th>导航名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="navTitle" name="navTitle" class="ipt" maxLength='50' style='width:300px;'/> + </td> + </tr> + <tr> + <th>导航链接<font color='red'>*</font>:</th> + <td> + <input type='text' id='navUrl' name="navUrl" class='ipt' style='width:500px;'/> + </td> + </tr> + <tr> + <th>是否显示<font color='red'> </font>:</th> + <td class='layui-form'> + <input type="checkbox" {if $data['isShow']==1}checked{/if} class="ipt" id="isShow" name="isShow" lay-skin="switch" lay-filter="isShow" value='1' lay-text="显示|隐藏"> + </td> + </tr> + <tr> + <th>打开方式<font color='red'>*</font>:</th> + <td class='layui-form'> + + <lable> + <input type="radio" name="isOpen" value="1" id="isOpen" class="ipt" <?=($data['isOpen']!==0)?'checked="checked"':'';?> title='新窗口打开'/> + </lable> + <lable> + <input type="radio" name="isOpen" value="0" id="isOpen" class="ipt" <?=($data['isOpen']===0)?'checked="checked"':'';?> title='页面跳转'/> + </lable> + </td> + </tr> + <tr> + <th>导航排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="navSort" class="ipt" maxLength="20" /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$data['id']+0}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +<script> +$(function(){ + WST.setValues(<?=json_encode($data)?>); +}); +</script> +{/block} + diff --git a/hyhproject/admin/view/navs/list.html b/hyhproject/admin/view/navs/list.html new file mode 100755 index 0000000..47893d8 --- /dev/null +++ b/hyhproject/admin/view/navs/list.html @@ -0,0 +1,31 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/navs/navs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于设置电脑版商城导航栏菜单。</li> + </ul> +</div> +</div> +{if WSTGrant('DHGL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:location.href='<?=url("admin/Navs/toEdit")?>'"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/navs/navs.js b/hyhproject/admin/view/navs/navs.js new file mode 100755 index 0000000..ac0fe8d --- /dev/null +++ b/hyhproject/admin/view/navs/navs.js @@ -0,0 +1,114 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'导航类型', name:'navType', width: 30, renderer: function(val,item,rowIndex){ + return (val==0)?'顶部':'底部'; + }}, + {title:'导航名称', name:'navTitle',width:30 }, + {title:'导航链接', name:'navUrl' ,width:120}, + {title:'是否显示', name:'isShow',width:20, renderer: function(val,item,rowIndex){ + return '<span class="layui-form"><input type="checkbox" '+ ((item.isShow==1)?"checked":"" )+' class="ipt" id="isShow" name="isShow" lay-skin="switch" lay-filter="isShow" data="'+item['id']+'" lay-text="显示|隐藏"></span>'; + }}, + {title:'打开方式', name:'isOpen',width:30,renderer: function(val,item,rowIndex){ + return (val==1)?'<span style="cursor:pointer" onclick="isShowtoggle(\'isOpen\','+item['id']+', 0)">新窗口打开</span>':'<span style="cursor:pointer" onclick="isShowtoggle(\'isOpen\','+item['id']+', 1)">页面跳转</span>'; + }}, + {title:'排序号', name:'navSort',width:10}, + {title:'操作', name:'op' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.DHGL_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/Navs/toEdit','id='+item['id'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.DHGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-158),indexCol: true, cols: cols,method:'POST',nowrap: true, + url: WST.U('admin/Navs/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render(); + layui.form.on('switch(isShow)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + isShowtoggle('isShow',id, 1); + }else{ + isShowtoggle('isShow',id, 0); + } + }); + }) + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Navs/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function edit(id){ + //获取所有参数 + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Navs/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Navs/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function isShowtoggle(field, id, val){ + if(!WST.GRANT.DHGL_02)return; + $.post(WST.U('admin/Navs/editiIsShow'), {'field':field, 'id':id, 'val':val}, function(data, textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} +/*表单验证*/ +$('#navForm').validator({ + fields:{ + navTitle:{rule:'required',msg:{required:"请输入导航名称"},tip:"请输入导航名称",ok:"",}, + navUrl: {rule:"required;",msg:{required:"请输入导航链接"},tip:"请输入导航链接",ok:"",}, + }, + valid:function(form){ + edit($('#id').val()); + } + }); + +function changeFlink(obj){ + var flink = $(obj).val(); + if(flink==1) + $("#articles").hide(); + else + $("#articles").show(); + +} +function changeArticles(obj){ + var url = $(obj).val(); + + $("#navUrl").val(url); +} diff --git a/hyhproject/admin/view/ordercomplains/handle.html b/hyhproject/admin/view/ordercomplains/handle.html new file mode 100755 index 0000000..69ef081 --- /dev/null +++ b/hyhproject/admin/view/ordercomplains/handle.html @@ -0,0 +1,338 @@ +{extend name="base" /} +{block name="css"} +{/block} +{block name="js"} +<script src="__ADMIN__/ordercomplains/ordercomplains.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">投诉详情</li> + <li>订单详情</li> + </ul> + <div class="layui-tab-content" > + <div class="layui-tab-item layui-show"> + <!-- 投诉信息 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>投诉信息</td> + </tr> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>投诉人:</th> + <td>{$order['userName']}</td> + </tr> + <tr> + <th>投诉类型:</th> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$order['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <th>投诉内容:</th> + <td class='line-break'>{$order['complainContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td> + <div id="complainAnnex"> + {if !empty($order['complainAnnex'])} + {volist name="$order['complainAnnex']" id="img"} + <img style='cursor:pointer' src="__IMGURL__/{$img}" layer-src="__IMGURL__/{$img}/thumb80" width="50" /> + {/volist} + {/if} + </div> + </td> + </tr> + + <tr> + <th>投诉时间:</th> + <td>{$order['complainTime']}</td> + </tr> + </table> + </div> + + <!-- 应诉信息 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>应诉信息</td> + </tr> + <tr> + <th width='100'>移交应付时间:</th> + <td>{$order['deliverRespondTime']}</td> + </tr> + <tr> + <th>应诉人:</th> + <td>{$order['order']['shopName']}</td> + </tr> + <tr> + <th>应诉信息:</th> + <td class='line-break'>{$order['respondContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td> + <div id="respondAnnex"> + {if !empty($order['respondAnnex'])} + {volist name="$order['respondAnnex']" id="img"} + <img style='cursor:pointer' src="__IMGURL__/{$img}" layer-src="__IMGURL__/{$img}/thumb80" width="50" /> + {/volist} + {/if} + </div> + </td> + </tr> + <tr> + <th>应诉时间:</th> + <td> + {$order['respondTime']} + </td> + </tr> + {if condition="$order['complainStatus'] == 0"} + <tr> + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary" onclick='javascript:deliverNext({$order["complainId"]})'><i class="fa fa-share"></i>移交卖家应诉</button> + </td> + </tr> + {/if} + </table> + </div> + + + <!-- 仲裁结果 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>仲裁结果</td> + </tr> + + + <tr> + <td align='right' valign='right' width='120'>当前订单状态:</td> + <td> + {:WSTLangOrderStatus($order['order']['orderStatus'])} + </td> + </tr> + <tr> + <td align='right' valign='right' width='120'>当前仲裁流程:</td> + <td style='color:red'> + {:WSTLangComplainStatus($order['complainStatus'])} + </td> + </tr> + <tr> + <th>仲裁结果:</th> + <td class='line-break'> + {if condition="$order['complainStatus'] neq 4"} + <textarea id='finalResult' style='height:150px;width:100%' placeholder='若无需转交应诉人应诉则直接填写仲裁结果进行仲裁'></textarea> + {else/} + {$order['finalResult']} + {/if} + </td> + </tr> + + + <tr> + <td colspan='2' align='center'> + {if condition="$order['complainStatus'] neq 4"} + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:finalHandle({$order["complainId"]},{$order["order"]["orderStatus"]})'><i class="fa fa-gavel"></i> +仲&nbsp;裁</button> + {/if} + <button type="button" class="btn" onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> + + </table> + </div> + </div> + + <div class="layui-tab-item"> + <div style='margin:10px;'> + <div class='order-box'> + <div class='box-head'>日志信息</div> + {if in_array($object['orderStatus'],[-2,0,1,2])} + <div class='log-box'> +<div class="state"> +{if $object['payType']==1} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{else} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{/if} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==2)"}icon43 {/if}"></span></div> +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> +</div> + <div class="state2"> + <div class="path"> + {volist name="$object['log']" id="lo"} + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + {/volist} + </div> + <p>下单</p>{if $object['payType']==1}<p>支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + </div> + <div class="wst-clear"></div> + </div> + {else} + <div> + <table class='log'> + {volist name='$object["log"]' id='vo'} + <tr> + <td>{$vo['logTime']}</td> + <td>{$vo['logContent']}</td> + </tr> + {/volist} + </table> + </div> + {/if} + </div> + <!-- 订单信息 --> + <div class='order-box'> + <div class='box-head'>订单信息</div> + <table class='wst-form'> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>支付方式:</th> + <td>{:WSTLangPayType($object['payType'])}</td> + </tr> + <tr> + <th>配送方式:</th> + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + </tr> + {if $object['expressNo']!=''} + <tr> + <th>快递公司:</th> + <td>{$object['expressName']}</td> + </tr> + <tr> + <th>快递号:</th> + <td>{$object['expressNo']}</td> + </tr> + {/if} + <tr> + <th>买家留言:</th> + <td>{$object['orderRemarks']}</td> + </tr> + </table> + </div> + <!-- 发票信息 --> + <div class='order-box'> + <div class='box-head'>发票信息</div> + <table class='wst-form'> + <tr> + <th width='100'>是否需要发票:</th> + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + </tr> + <tr> + <th>发票抬头:</th> + <td>{$object['invoiceClient']}</td> + </tr> + </table> + </div> + <!-- 收货人信息 --> + <div class='order-box'> + <div class='box-head'>收货人信息</div> + <table class='wst-form'> + <tr> + <th width='100'>收货人:</th> + <td>{$object['userName']}</td> + </tr> + <tr> + <th>收货地址:</th> + <td>{$object['userAddress']}</td> + </tr> + <tr> + <th>联系方式:</th> + <td>{$object['userPhone']}</td> + </tr> + </table> + </div> + <!-- 商品信息 --> + <div class='order-box'> + <div class='box-head'>商品清单</div> + <div class='goods-head'> + <div class='goods'>商品</div> + <div class='price'>单价</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + </div> + <div class='goods-item'> + <div class='shop'> + {$object['shopName']} + {if $object['shopQQ'] !=''} + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $object['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + <div class='goods-list'> + {volist name='$object["goods"]' id='vo2'} + <div class='item'> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{$vo2["goodsName"]}</div> + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + </div> + <div class='price'>¥{$vo2['goodsPrice']}</div> + <div class='num'>{$vo2['goodsNum']}</div> + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + <div class='f-clear'></div> + </div> + {/volist} + </div> + </div> + <div class='goods-footer'> + <div class='goods-summary' style='text-align:right'> + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + <div class='summary line'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + </div> + </div> + </div> + <div class='wst-footer'><input type='button' value='返回' class='btn btn-blue' onclick='javascript:history.go(-1)'></div> +<div> + </div> +</div> +</div> + + + +</div> +<script> +$(function(){ + parent.showImg({photos: $('#respondAnnex')}); + parent.showImg({photos: $('#complainAnnex')}); +}); + +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/ordercomplains/list.html b/hyhproject/admin/view/ordercomplains/list.html new file mode 100755 index 0000000..3854a03 --- /dev/null +++ b/hyhproject/admin/view/ordercomplains/list.html @@ -0,0 +1,39 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/ordercomplains/ordercomplains.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='ipt j-ipt hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-ipt'});"> + <option value="-1">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="orderNo" placeholder='订单编号' id="orderNo" class='j-ipt'/> +<select id='complainStatus' class='j-ipt'> + <option value='-1'>投诉处理状态</option> + <option value='0'>新投诉</option> + <option value='1'>转给应诉人</option> + <option value='2'>应诉人回应</option> + <option value='3'>等待仲裁</option> + <option value='4'>已仲裁</option> +</select> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/ordercomplains/ordercomplains.js b/hyhproject/admin/view/ordercomplains/ordercomplains.js new file mode 100755 index 0000000..4e49cee --- /dev/null +++ b/hyhproject/admin/view/ordercomplains/ordercomplains.js @@ -0,0 +1,120 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'投诉人', name:'userName', width: 30,sortable: true, renderer: function(val,item,rowIndex){ + return WST.blank(item['userName'],item['loginName']); + }}, + {title:'投诉订单号', name:'orderNo',sortable: true, renderer: function(val,item,rowIndex){ + var h = ""; + if(item['orderSrc']==0){ + h += "<img class='order-source2' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_1.png'>"; + }else if(item['orderSrc']==1){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_3.png'>"; + }else if(item['orderSrc']==2){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_2.png'>"; + }else if(item['orderSrc']==3){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_4.png'>"; + }else if(item['orderSrc']==4){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_5.png'>"; + } + h += item['orderNo']; + return h; + }}, + {title:'订单来源',name:'orderCodeTitle'}, + {title:'被投诉人',sortable: true, name:'shopName'}, + {title:'投诉类型',sortable: true, name:'complainType'}, + {title:'投诉时间',sortable: true, name:'complainTime'}, + {title:'状态', name:'complainStatus', renderer: function(val,item,rowIndex){ + var html='23123213'; + if(val==0) + return '新投诉'; + else if(val==1) + return '转给应诉人'; + else if(val==2) + return '应诉人回应'; + else if(val==3) + return '等待仲裁'; + else if(val==4) + return '已仲裁'; + }}, + {title:'操作', name:'op' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toView(" + item['complainId'] + ")'><i class='fa fa-search'></i>查看</a> "; + if(item['complainStatus']!=4) + h += "<a class='btn btn-blue' href='javascript:toHandle(" + item['complainId'] + ")'><i class='fa fa-pencil'></i>处理</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/orderComplains/pageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'complainTime', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toView(id){ + location.href=WST.U('admin/orderComplains/view','cid='+id); +} +function toHandle(id){ + location.href=WST.U('admin/orderComplains/toHandle','cid='+id); +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} + + +function deliverNext(id){ + WST.confirm({content:'您确定要转交给应诉人应诉吗?',yes:function(){ + $.post(WST.U('Admin/Ordercomplains/deliverRespond'),{id:id},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg('投诉已移交应诉人',{icon:1},function(){ + location.reload(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function finalHandle(id){ + var params = {}; + params.cid = id; + params.finalResult = $.trim($('#finalResult').val()); + if(params.finalResult==''){ + WST.msg('请输入仲裁结果!',{icon:2}); + return; + } + + var c = WST.confirm({title:'信息提示',content:'您确定仲裁该订单投诉吗?',yes:function(){ + layer.close(c); + $.post(WST.U('Admin/OrderComplains/finalHandle'),params,function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + diff --git a/hyhproject/admin/view/ordercomplains/view.html b/hyhproject/admin/view/ordercomplains/view.html new file mode 100755 index 0000000..bebcc6b --- /dev/null +++ b/hyhproject/admin/view/ordercomplains/view.html @@ -0,0 +1,333 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/ordercomplains/ordercomplains.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id="wst-tabs" style="width:100%; height:99%;overflow: hidden; border: 1px solid #D3D3d3;" class="liger-tab"> + <div id="wst-tab-1" tabId="wst-tab-1" title="投诉详情" class='wst-tab' style="height: 100%"> + <div style="margin:10px"> + <!-- 投诉信息 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>投诉信息</td> + </tr> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>投诉人:</th> + <td>{$order['userName']}</td> + </tr> + <tr> + <th>投诉类型:</th> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$order['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + + <tr> + <th>投诉内容:</th> + <td class='line-break'>{$order['complainContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td> + <div id="complainAnnex"> + {if !empty($order['complainAnnex'])} + {volist name="$order['complainAnnex']" id="img"} + <img src="__IMGURL__/{$img}" layer-src="__IMGURL__/{$img}" width="50" /> + {/volist} + {/if} + </div> + </td> + </tr> + + <tr> + <th>投诉时间:</th> + <td>{$order['complainTime']}</td> + </tr> + </table> + </div> + + <!-- 应诉信息 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>应诉信息</td> + </tr> + <tr> + <th width='100'>移交应付时间:</th> + <td>{$order['deliverRespondTime']}</td> + </tr> + <tr> + <th>应诉人:</th> + <td>{$order['order']['shopName']}</td> + </tr> + <tr> + <th>应诉信息:</th> + <td class='line-break'>{$order['respondContent']}</td> + </tr> + <tr> + <th>附件:</th> + <td> + <div id="respondAnnex"> + {if !empty($order['respondAnnex'])} + {volist name="$order['respondAnnex']" id="img"} + <img src="__IMGURL__/{$img}" layer-src="__IMGURL__/{$img}" width="50" /> + {/volist} + {/if} + </div> + </td> + </tr> + + <tr> + <th>应诉时间:</th> + <td> + {$order['respondTime']} + </td> + </tr> + + </table> + </div> + + + <!-- 仲裁结果 --> + <div class='order-box'> + <table class='wst-form'> + <tr> + <td class='head-ititle'>仲裁结果</td> + </tr> + <tr> + <th>处理状态:</th> + <td> + {if condition="$order['complainStatus'] eq 0"} + 等待处理 + {elseif condition="$order['complainStatus'] eq 1"/} + 等待应诉人回应 + {elseif condition="$order['complainStatus'] eq 2"/} + 应诉人回应 + {elseif condition="$order['complainStatus'] eq 3"/} + 等待仲裁 + {elseif condition="$order['complainStatus'] eq 4"/} + 已仲裁 + {/if} + </td> + </tr> + <tr> + <td align='right' valign='right' width='120'>当前订单状态:</td> + <td> + {:WSTLangOrderStatus($order['order']['orderStatus'])} + </td> + </tr> + <tr> + <th>仲裁结果:</th> + <td class='line-break'> + {$order['finalResult']} + </td> + </tr> + <th>仲裁时间:</th> + <td> + {$order['finalResultTime']} + </td> + </tr> + + <tr> + <td colspan='2' align='center'> + <button type="button" onclick="javascript:history.go(-1)"class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + + </table> + </div> + </div> +</div> + <div title="订单详情" class='wst-tab' id="order-detail" style="height: 99%"> + <div style='margin:10px;'> + <div class='order-box'> + <div class='box-head'>日志信息</div> + {if in_array($object['orderStatus'],[-2,0,1,2])} + <div class='log-box'> +<div class="state"> +{if $object['payType']==1} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{else} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{/if} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==2)"}icon43 {/if}"></span></div> +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> +</div> + <div class="state2"> + <div class="path"> + {volist name="$object['log']" id="lo"} + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + {/volist} + </div> + <p>下单</p>{if $object['payType']==1}<p>支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + </div> + <div class="wst-clear"></div> + </div> + {else} + <div> + <table class='log'> + {volist name='$object["log"]' id='vo'} + <tr> + <td>{$vo['logTime']}</td> + <td>{$vo['logContent']}</td> + </tr> + {/volist} + </table> + </div> + {/if} + </div> + <!-- 订单信息 --> + <div class='order-box'> + <div class='box-head'>订单信息</div> + <table class='wst-form'> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>支付方式:</th> + <td>{:WSTLangPayType($object['payType'])}</td> + </tr> + {if($object['payType']==1)} + <tr> + <th>交易流水:</th> + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + </tr> + {/if} + <tr> + <th>配送方式:</th> + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + </tr> + {if $object['expressNo']!=''} + <tr> + <th>快递公司:</th> + <td>{$object['expressName']}</td> + </tr> + <tr> + <th>快递号:</th> + <td>{$object['expressNo']}</td> + </tr> + {/if} + <tr> + <th>买家留言:</th> + <td>{$object['orderRemarks']}</td> + </tr> + </table> + </div> + <!-- 发票信息 --> + <div class='order-box'> + <div class='box-head'>发票信息</div> + <table class='wst-form'> + <tr> + <th width='100'>是否需要发票:</th> + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + </tr> + <tr> + <th>发票抬头:</th> + <td>{$object['invoiceClient']}</td> + </tr> + </table> + </div> + <!-- 收货人信息 --> + <div class='order-box'> + <div class='box-head'>收货人信息</div> + <table class='wst-form'> + <tr> + <th width='100'>收货人:</th> + <td>{$object['userName']}</td> + </tr> + <tr> + <th>收货地址:</th> + <td>{$object['userAddress']}</td> + </tr> + <tr> + <th>联系方式:</th> + <td>{$object['userPhone']}</td> + </tr> + </table> + </div> + <!-- 商品信息 --> + <div class='order-box'> + <div class='box-head'>商品清单</div> + <div class='goods-head'> + <div class='goods'>商品</div> + <div class='price'>单价</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + </div> + <div class='goods-item'> + <div class='shop'> + {$object['shopName']} + {if $object['shopQQ'] !=''} + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $object['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + <div class='goods-list'> + {volist name='$object["goods"]' id='vo2'} + <div class='item'> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{$vo2["goodsName"]}</div> + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + </div> + <div class='price'>¥{$vo2['goodsPrice']}</div> + <div class='num'>{$vo2['goodsNum']}</div> + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + <div class='f-clear'></div> + </div> + {/volist} + </div> + </div> + <div class='goods-footer'> + <div class='goods-summary' style='text-align:right'> + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + <div class='summary line'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + </div> + </div> + </div> + <div class='wst-footer'><button type="button" onclick='javascript:history.go(-1)' class='btn'><i class="fa fa-angle-double-left"></i>返回</button></div> +<div> + </div> + + +</div> +<script> +$(function(){ + parent.showImg({photos: $('#respondAnnex')}); + parent.showImg({photos: $('#complainAnnex')}); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/orderrefunds/box_refund.html b/hyhproject/admin/view/orderrefunds/box_refund.html new file mode 100755 index 0000000..793b63b --- /dev/null +++ b/hyhproject/admin/view/orderrefunds/box_refund.html @@ -0,0 +1,150 @@ +{if !empty($object)} + +<form id='editFrom'> + +<table class='wst-form'> + + <tr> + + <td colspan='2' class='head-ititle'>订单信息</td> + + </tr> + + <tr> + + <th width='100'>订单编号:</th> + + <td>{$object['orderNo']}</td> + + </tr> + + {if $object['payFrom']!=''} + + <tr> + + <th>支付方式:</th> + + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + + </tr> + + {/if} + + <tr> + + <th>订单总金额:</th> + + <td>¥{$object['totalMoney']}&nbsp;&nbsp;&nbsp;&nbsp;【商品总金额:¥{$object['goodsMoney']}&nbsp;&nbsp;&nbsp;&nbsp;运费:¥{$object['deliverMoney']}】</td> + + </tr> + + <tr> + + <th>应收总金额:</th> + + <td>¥{$object['realTotalMoney']}</td> + + </tr> + + <tr> + + <td colspan='2' class='head-ititle'>退款信息</td> + + </tr> + + <tr> + + <th>退款原因:</th> + + <td> + + {php} + + $rs = WSTDatas('REFUND_TYPE',$object['refundReson']); + + echo $rs['dataName'].(($object['refundOtherReson']!='')?":".$object['refundOtherReson']:""); + + {/php}</td> + + </tr> + <tr> + + <th>退回产品券:</th> + + <td>¥{$object['backProductNum']}&nbsp;&nbsp;&nbsp;&nbsp;实付产品券:¥{$object['productNum']}</td> + + </tr> + <tr> + + <th>退回优惠券:</th> + + <td>¥{$object['backCouponsNum']}&nbsp;&nbsp;&nbsp;&nbsp;实付产品券:¥{$object['couponsNum']}</td> + + </tr> + <tr> + + <th>退回旺旺券:</th> + + <td>¥{$object['backWangNum']}&nbsp;&nbsp;&nbsp;&nbsp;实付产品券:¥{$object['wangNum']}</td> + + </tr> + <tr> + <th>实付现金:</th> + + <td>¥{$object['moneyNum']}</td> + + </tr> +<!-- <tr> + + <th>申请退款:</th> + + <td>¥{$object['backMoney']}</td> + + </tr> + + <tr> + + <th>申请退回积分:</th> + + <td>{$object['useScore']}(积分抵扣¥{$object['scoreMoney']})</td> + + </tr> --> + + <tr> + + <th>操作备注:</th> + + <td> + + <textarea id='content' style='width:90%;height:60px;' placeholder='操作备注,用户可见' maxLength='200'></textarea> + + </td> + + </tr> + + <tr> + + <td colspan='2' style='text-align:center;padding-top:30px;'> + + <button type="button" class="btn btn-primary btn-mright" onclick="javascript:orderRefund({$object['refundId']})"><i class="fa fa-check"></i>确&nbsp;&nbsp;定</button> + + <button type="button" class="btn" onclick='javascript:layer.close(w)'><i class="fa fa-angle-double-left"></i>取&nbsp;&nbsp;消</button> + + </td> + + </tr> + +</table> + +</form> + +{else} + +<div style='color:red;margin:20px;'> + +该订单不存在或已退款。 + +</div> + +{/if} + diff --git a/hyhproject/admin/view/orderrefunds/list.html b/hyhproject/admin/view/orderrefunds/list.html new file mode 100755 index 0000000..b8375b1 --- /dev/null +++ b/hyhproject/admin/view/orderrefunds/list.html @@ -0,0 +1,52 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/orderrefunds/orderrefunds.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='ipt j-ipt hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-ipt'});"> + <option value="-1">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="orderNo" placeholder='订单编号' id="orderNo" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt'/> +<select id='deliverType' class='j-ipt'> + <option value='-1'>配送方式</option> + <option value='1'>自提</option> + <option value='0'>送货上门</option> + </select> +<select id='isRefund' class='j-ipt'> + <option value='-1'>退款状态</option> + <option value='1'>已退款</option> + <option value='0'>未退款</option> +</select> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + <button class="btn btn-primary" onclick='javascript:loadRefundGrid(0)'><i class="fa fa-search"></i>查询</button> + + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/orderrefunds/toExport',params); + }}); +} +$(function(){initRefundGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/orderrefunds/orderrefunds.js b/hyhproject/admin/view/orderrefunds/orderrefunds.js new file mode 100755 index 0000000..1f5ffb3 --- /dev/null +++ b/hyhproject/admin/view/orderrefunds/orderrefunds.js @@ -0,0 +1,136 @@ +var grid; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function toView(id){ + location.href=WST.U('admin/orders/view','id='+id); +} +function initRefundGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'订单编号', name:'orderNo',sortable: true, renderer: function(val,item,rowIndex){ + var h = ""; + if(item['orderSrc']==0){ + h += "<img class='order-source2' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_1.png'>"; + }else if(item['orderSrc']==1){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_3.png'>"; + }else if(item['orderSrc']==2){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_2.png'>"; + }else if(item['orderSrc']==3){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_4.png'>"; + }else if(item['orderSrc']==4){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_5.png'>"; + } + h += item['orderNo']; + return h; + }}, + {title:'申请人', name:'loginName',sortable: true}, + {title:'店铺', name:'shopName',sortable: true}, + {title:'订单来源', name:'orderCodeTitle',width:40,sortable: true}, + {title:'配送方式', name:'deliverType',width:40,sortable: true}, + {title:'支付方式', name:'payFrom' , width: 30,sortable:true, renderer:function(val,item,rowIndex){ + if(item['payFrom']==null){ + return ""; + }else if(item['payFrom']=='wallets'){ + return "余额"; + }else if(item['payFrom']=='ect'){ + return "ECT"; + }else if(item['payFrom']=='alipays' || item['payFrom']=='app_alipays'){ + return "支付宝"; + }else if(item['payFrom']=='weixinpays'){ + return "微信"; + }else if(item['payFrom']=='cod'){ + return "货到付款"; + }else if(item['payFrom']=='qlgpay'){ + return "全亮共支付"; + }else{ + return item['payFrom']; + } + }}, + {title:'实收金额', name:'realTotalMoney', width:30,sortable: true,renderer: function(val,item,rowIndex){ + return "¥"+val; + }}, + {title:'产品券退款', name:'backProductNum',width:30,sortable: true, renderer: function(val,item,rowIndex){ + return "¥"+val; + }}, + {title:'优惠券退款', name:'backCouponsNum',width:30,sortable: true, renderer: function(val,item,rowIndex){ + return "¥"+val; + }}, + {title:'产品券退款', name:'backWangNum',width:30,sortable: true, renderer: function(val,item,rowIndex){ + return "¥"+val; + }}, + // {title:'申请退款金额', name:'backMoney',width:30,sortable: true, renderer: function(val,item,rowIndex){ + // return "¥"+val; + // }}, + {title:'申请时间', name:'createTime',sortable: true}, + {title:'退款状态', name:'refundStatus', width:30,sortable: true,renderer: function(val,item,rowIndex){ + if(item['refundStatus']==1){ + return "待后台处理"; + }else if(item['refundStatus']==2){ + return "后台已处理"; + }else{ + return "<span style='color: red'>商家未处理</span>" + } + }}, + {title:'退款备注', name:'refundRemark'}, + {title:'操作', name:'op' ,width:120, align:'center', renderer: function(val,item,rowIndex){ + var h = ''; + if(item['isRefund']==0){ + if(WST.GRANT.TKDD_04)h += "<a class='btn btn-blue' href='javascript:toRefund(" + item['refundId'] + ")'><i class='fa fa-search'></i>退款</a> "; + } + h += "<a class='btn btn-blue' href='javascript:toView(" + item['orderId'] + ")'><i class='fa fa-search'></i>详情</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/orderrefunds/refundPageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'createTime', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadRefundGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} +var w; +function toRefund(id){ + var ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/orderrefunds/toRefund',{id:id}),{},function(data){ + layer.close(ll); + w =WST.open({type: 1,title:"订单退款",shade: [0.6, '#000'],offset:'50px',border: [0],content:data,area: ['550px', '380px']}); + }); +} +function orderRefund(id){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = {}; + params.content = $.trim($('#content').val()); + params.id = id; + ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/orderrefunds/orderRefund'),params,function(data){ + layer.close(ll); + var json = WST.toAdminJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + loadRefundGrid(); + layer.close(w); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }) +} + diff --git a/hyhproject/admin/view/orders/certificate_list.html b/hyhproject/admin/view/orders/certificate_list.html new file mode 100755 index 0000000..6cd0a95 --- /dev/null +++ b/hyhproject/admin/view/orders/certificate_list.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<style type="text/css"> + .mmGrid .nowrap{ + overflow: auto; + white-space: normal; + } +</style> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/orders/orders.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + +<select id='certificateStatus' class='j-ipt'> + <option value=''>审核状态</option> + <option value='0'>未上传</option> + <option value='1'>无需上传</option> + <option value='2'>待审核</option> + <option value='3'>已审核</option> + <option value='4'>已拒绝</option> +</select><!-- +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> --> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initCertificateGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/orders/list.html b/hyhproject/admin/view/orders/list.html new file mode 100755 index 0000000..cdba619 --- /dev/null +++ b/hyhproject/admin/view/orders/list.html @@ -0,0 +1,58 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/orders/orders.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<input type="hidden" id="userId" class="j-ipt" value='{$userId}' autocomplete="off"/> +<div class="wst-toolbar"> +<select id="areaId1" class='ipt j-ipt hide' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-ipt'});"> + <option value="-1">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="orderNo" placeholder='订单编号' id="orderNo" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt'/> +<select id='orderStatus' class='j-ipt'> + <option value='10000'>订单状态</option> + <option value='0'>待发货</option> + <option value='-2'>待支付</option> + <option value='-1'>已取消</option> + <option value='1'>配送中</option> + <option value='2'>已收货</option> + <option value='-3'>用户拒收</option> +</select> +<select id='payType' class='j-ipt'> + <option value='-1'>支付方式</option> + <option value='0'>货到付款</option> + <option value='1'>在线支付</option> +</select> +<select id='deliverType' class='j-ipt'> + <option value='-1'>配送方式</option> + <option value='1'>自提</option> + <option value='0'>送货上门</option> +</select> + +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<input type="text" id="userPhone" name="userPhone" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='联系方式'/> +<input type="text" id="investmentStaff" name="investmentStaff" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='对接人员名字'/> + + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class="fa fa-search"></i>查询</button> + {if($userId>0)}<button class="btn f-right btn-fixtop" onclick="javascript:history.go(-1)" style="margin-left: 10px;"><i class="fa fa-angle-double-left"></i>返回</button>{/if} + <button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/orders/orders.js b/hyhproject/admin/view/orders/orders.js new file mode 100755 index 0000000..fb6b8dd --- /dev/null +++ b/hyhproject/admin/view/orders/orders.js @@ -0,0 +1,246 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) + +function initCertificateGrid(){ + var p = WST.arrayParams('.j-ipt'); + var h = WST.pageHeight(); + var cols = [ + {title:'店铺名', name:'shop', width: 50,sortable:true, renderer:function(val,item,rowIndex){ + return val.shopName; + }}, + {title:'店铺电话', name:'shop', width: 100,sortable:true, renderer:function(val,item,rowIndex){ + return val.phone; + }}, + {title:'应付款', name:'payNum', width: 100,sortable:true}, + {title:'订单组', name:'list', width: 500,sortable:true, renderer:function(val,item,rowIndex){ + var html = ''; + $.each(val,function(i,v){ + html+='订单号:'+v['orderNo']+',应付款:'+v['payable']+','; + // console.log(v); + }) + return html; + }}, + {title:'商家凭证', name:'imgUrl', width: 100,sortable:true, renderer:function(val,item,rowIndex){ + return"<span><img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+val+"'</span>"; + }}, + {title:'凭证备注', name:'content', width: 100,sortable:true}, + {title:'审核状态', name:'status', width: 30,sortable:true, renderer:function(val,item,rowIndex){ + var html = ''; + switch(val){ + case 0: + html = '未上传' + break; + case 1: + html = '无需上传' + break; + case 2: + html = '待审核' + break; + case 3: + html = '已通过' + break; + case 4: + html = '已拒绝' + break; + } + return html; + }}, + // {title:'对接人员', name:'investmentStaff', width: 100,sortable:true}, + {title:'操作' , width: 30,name:'status', renderer:function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.PZCZ_00 && typeof(item.id) != 'undefined'){ + h += "<a data-id='"+item.id+"'class='btn btn-blue applyAction'> <i class='fa fa-pencil'></i>审核</a> "; + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/orders/getCertificate',p.join('&')), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +$("body").on("click",'.uploadImg',function(){ + layer.open({ + type: 1, + title: false, + closeBtn: 0, + area: '90%', + skin: 'layui-layer-nobg', //没有背景色 + shadeClose: true, + content: '<div ><img src="'+$(this).attr('src')+'"></div>' + }); +}); +$("body").on("click",'.applyAction',function(){ + let id = $(this).attr('data-id'); + layer.open({ + type: 1, + title: '审核操作', + closeBtn: 1, + shadeClose: true, + area: '50%', + btn: ['确定'], + btnAlign: 'c', //按钮居中 + // skin: '', + content: '<div style="text-align:center;margin-top:1rem;padding-top:1rem;">审核处理:<label><input type="radio" class="status" value="1" name="status" onclick="javascript:WST.showHide(0,&quot;#trApplyDesc&quot;);" title="通过">通过' + + ' </label> ' + + '<label><input type="radio" class="status" value="2" name="status" onclick="javascript:WST.showHide(1,&quot;#trApplyDesc&quot;);" title="不通过">拒绝' + + '</label>' + + '<div id="trApplyDesc" style="display:none">' + + '<th>不通过原因<font color="red">*</font>:</th>' + + '<td><textarea id="applyDesc" class="ipt" style="width:300px;height:100px;" maxlength="100" data-rule="不通过原因:required(#status-1:checked);"></textarea></td>' + + '</div></div>', + yes: function(index){ + + let obj = $("input[name='status']:checked"); + let status =obj.val(); + if(!status){ + WST.msg('请选择通过或不通过', {icon: 2,time:3000}); + return; + } + let applyDesc = $('#applyDesc').val(); + if(2 == status && '' == applyDesc ){ + WST.msg('请输入拒绝理由', {icon: 2,time:3000}); + $('#applyDesc').focus(); + return; + } + let msgArr = ['通过','拒绝']; + + let msg = "您确定要"+msgArr[status-1]+"此用户的凭证信息?"; + let box = WST.confirm({content:msg,yes:function(){ + let loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Orders/certificateSet'),{id:id,status:status,'reasonsForRefusal':applyDesc},function(data,textStatus){ + layer.close(loading); + let json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + layer.close(index); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + } + }); +}); +function initGrid(){ + var p = WST.arrayParams('.j-ipt'); + var h = WST.pageHeight(); + var cols = [ + {title:'订单编号', name:'orderNo', width: 50,sortable:true, renderer:function(val,item,rowIndex){ + var h = ""; + if(item['orderSrc']==0){ + h += "<img class='order-source2' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_1.png'>"; + }else if(item['orderSrc']==1){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_3.png'>"; + }else if(item['orderSrc']==2){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_2.png'>"; + }else if(item['orderSrc']==3){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_4.png'>"; + }else if(item['orderSrc']==4){ + h += "<img class='order-source' src='"+WST.conf.ROOT+"/hyhproject/admin/view/img/order_source_5.png'>"; + } + h += item['orderNo']; + return h; + }}, + {title:'购户', name:'loginName', width: 120,sortable:true}, + {title:'收货人', name:'userName', width: 120,sortable:true}, + {title:'商户', name:'shopLoginName', width: 120,sortable:true}, + {title:'店铺', name:'shopName', width: 90,sortable:true}, + {title:'交易额', name:'realTotalMoney', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'购户付现', name:'moneyNum', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'旺旺券', name:'wangNum', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'产品券', name:'productNum', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'产品券税', name:'productTaxFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'产品券手续费', name:'productHandlingFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + // {title:'产品券手续费+税', name:'productHandlingFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){ + // return item['productTaxFee']+val; + // }}, + {title:'优惠券', name:'couponsNum', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'优惠券税', name:'couponsTaxFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'优惠券手续费', name:'couponsHandlingFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){return '¥'+val;}}, + + // {title:'优惠券手续费+税', name:'couponsHandlingFee', width: 30,sortable:true, renderer:function(val,item,rowIndex){ + // return item['couponsTaxFee']+val;; + // }}, + {title:'商户付现', name:'payable', width: 30,sortable:true, renderer:function(val,item,rowIndex){ + if(val<0){ + return Math.abs(val); + }else{ + return 0; + } + }}, + // {title:'支付方式', name:'payType' , width: 30,sortable:true}, + // // mark by cheng 添加支付通道显示 + // {title:'支付通道', name:'payFrom' , width: 30,sortable:true, renderer:function(val,item,rowIndex){ + // if(item['payFrom']==null){ + // return ""; + // }else if(item['payFrom']=='wallets'){ + // return "余额"; + // }else if(item['payFrom']=='ect'){ + // return "ECT"; + // }else if(item['payFrom']=='alipays'){ + // return "支付宝"; + // }else{ + // return item['payFrom']; + // } + // }}, + // {title:'配送方式', name:'deliverType', width: 30,sortable:true}, + // {title:'订单来源', name:'orderCodeTitle', width: 30,sortable:true}, + {title:'下单时间', name:'createTime', width: 100,sortable:true}, + {title:'订单状态', name:'orderStatus', width: 30,sortable:true, renderer:function(val,item,rowIndex){ + if(item['orderStatus']==-1){ + return "<span class='statu-no'><i class='fa fa-ban'></i> "+item.status+"</span>"; + }else if(item['orderStatus']==-3){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> "+item.status+"</span>"; + }else if(item['orderStatus']==2){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> "+item.status+"</span>"; + }else{ + return "<span class='statu-wait'><i class='fa fa-clock-o'></i> "+item.status+"</span>"; + } + }}, + // {title:'对接人员', name:'investmentStaff', width: 100,sortable:true}, + {title:'操作' , width: 30,name:'status', renderer:function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toView(" + item['orderId'] + ")'><i class='fa fa-search'></i>详情</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true,indexColWidth:50, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/orders/pageQuery',p.join('&')), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +function toView(id){ + location.href=WST.U('admin/orders/view','id='+id); +} +function loadGrid(){ + var p = WST.getParams('.j-ipt'); + p.page = 1; + mmg.load(p); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/orders/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/orders/view.html b/hyhproject/admin/view/orders/view.html new file mode 100755 index 0000000..cc54e2c --- /dev/null +++ b/hyhproject/admin/view/orders/view.html @@ -0,0 +1,481 @@ +{extend name="base" /} + +{block name="main"} + +<div style='margin:10px;'> + + <div class='order-box'> + + <div class='box-head'>日志信息</div> + + {if in_array($object['orderStatus'],[-2,0,1,2])} + + <div class='log-box'> + +<div class="state"> + +{if $object['payType']==1} + +<div class="icon"> + + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> + +</div> + +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + +{else} + +<div class="icon"> + + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> + +</div> + +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + +{/if} + +<div class="icon"> + + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> + +</div> + +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> + +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==0)"}icon43 {/if}"></span></div> + +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> + +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> + +</div> + + <div class="state2"> + + <div class="path"> + + {volist name="$object['log']" id="lo"} + + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + + {/volist} + + </div> + + <p>下单</p>{if $object['payType']==1}<p>等待支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + + </div> + + <div class="wst-clear"></div> + + </div> + + {else} + + <div> + + <table class='log'> + + {volist name='$object["log"]' id='vo'} + + <tr> + + <td>{$vo['logTime']}</td> + + <td>{$vo['logContent']}</td> + + </tr> + + {/volist} + + </table> + + </div> + + {/if} + + </div> + + <!-- 订单信息 --> + + <div class='order-box'> + + <div class='box-head'>订单信息</div> + + <table class='wst-form'> + + <tr> + + <th width='100'>订单编号:</th> + + <td>{$object['orderNo']}</td> + + </tr> + + <tr> + + <th>支付方式:</th> + + <td>{:WSTLangPayType($object['payType'])}</td> + + </tr> + + {if($object['payType']==1 && $object['isPay']==1)} + + <tr> + + <th>支付时间:</th> + + <td>{$object['payTime']}</td> + + </tr> + + <tr> + + <th>交易流水:</th> + + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + + </tr> + + {/if} + + <tr> + + <th>配送方式:</th> + + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + + </tr> + + {if $object['expressNo']!=''} + + <tr> + + <th>快递公司:</th> + + <td>{$object['expressName']}</td> + + </tr> + + <tr> + + <th>快递号:</th> + + <td>{$object['expressNo']}</td> + + </tr> + + {/if} + + <tr> + + <th>买家留言:</th> + + <td>{$object['orderRemarks']}</td> + + </tr> + + </table> + + </div> + + {:hook('adminDocumentOrderView',['orderId'=>$object['orderId']])} + + {if $object['isRefund']==1} + + <!-- 退款信息 --> + + <div class='order-box'> + + <div class='box-head'>退款信息</div> + + <table class='wst-form'> + + <tr> + + <th width='100'>退款备注:</th> + + <td>{$object['refundRemark']}</td> + + </tr> + + <tr> + + <th>退款时间:</th> + + <td>{$object['refundTime']}</td> + + </tr> + + </table> + + </div> + + {/if} + + <!-- 发票信息 --> + + <div class='order-box'> + + <div class='box-head'>发票信息</div> + + <table class='wst-form'> + + <tr> + + <th width='100'>是否需要发票:</th> + + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + + </tr> + + {if $object['isInvoice']==1} + + {php}$invoiceArr = json_decode($object['invoiceJson'],true);{/php} + + <tr> + + <th>发票抬头:</th> + + <td> + + {if $object['isInvoice']==1} + + {$invoiceArr['invoiceHead']} + + {/if} + + </td> + + </tr> + + {if isset($invoiceArr['invoiceCode'])} + + <tr> + + <th>发票税号:</th> + + <td> + + {$invoiceArr['invoiceCode']} + + </td> + + </tr> + + {/if} + + {/if} + + </table> + + </div> + + <!-- 收货人信息 --> + + <div class='order-box'> + + <div class='box-head'>收货人信息</div> + + <table class='wst-form'> + + <tr> + + <th width='100'>下单会员:</th> + + <td>{$object['loginName']}</td> + + </tr> + + <tr> + + <th width='100'>收货人:</th> + + <td>{$object['userName']}</td> + + </tr> + + <tr> + + <th>收货地址:</th> + + <td>{$object['userAddress']}</td> + + </tr> + + <tr> + + <th>联系方式:</th> + + <td>{$object['userPhone']}</td> + + </tr> + + </table> + + </div> + <!-- 会员凭证 --> + <div class='order-box'> + <div class='box-head'>会员凭证</div> + <table class='wst-form'> + <tr> + <td width=''>凭证图</td> + <td width=''>内容</td> + </tr> + {if !empty($object["userCertificate"])} + {foreach name = '$object["userCertificate"]' item = "uc"} + <tr> + <td><img src="__IMGURL__/{$uc['imgUrl']}" /></td> + <td>{$uc['content']}</td> + </tr> + {/foreach} + {/if} + </table> + </div> + <!-- <div class='order-box'> + <div class='box-head'>商家凭证</div> + <table class='wst-form'> + <tr> + <td width=''>凭证图</td> + <td width=''>内容</td> + </tr> + {if !empty($object["shopCertificate"])} + {foreach name = '$object["shopCertificate"]' item = "sc"} + <tr> + <td><img src="__IMGURL__/{$sc['imgUrl']}" /></td> + <td>{$sc['content']}</td> + </tr> + {/foreach} + {/if} + </table> --> + </div> + <!-- 商品信息 --> + + <div class='order-box'> + + <div class='box-head'>商品清单</div> + + <div class='goods-head'> + + <div class='goods'>商品</div> + + <div class='price'>单价</div> + + <div class='num'>数量</div> + + <div class='t-price'>总价</div> + + </div> + + <div class='goods-item'> + + <div class='shop'> + + {$object['shopName']} + + {if $object['shopQQ'] !=''} + + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + + <img border="0" style='vertical-align:middle;' src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + + </a> + + {/if} + + {if $object['shopWangWang'] !=''} + + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + + <img border="0" style='vertical-align:middle;' src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + + </a> + + {/if} + + </div> + + <div class='goods-list'> + + {volist name='$object["goods"]' id='vo2'} + + {:hook('adminDocumentOrderViewGoodsPromotion',['goods'=>$vo2])} + + <div class='item j-g{$vo2['goodsId']}'> + + <div class='goods'> + + <div class='img'> + + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + + </a> + + </div> + + <div class='name'>{if $vo2["goodsCode"]=='gift'}【赠品】{/if}{$vo2["goodsName"]}</div> + + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + + </div> + + <div class='price'>¥{$vo2['goodsPrice']}</div> + + <div class='num'>{$vo2['goodsNum']}</div> + + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + + <div class='f-clear'></div> + + </div> + + {/volist} + + </div> + + </div> + + <div class='goods-footer'> + + <div class='goods-summary' style='text-align:right'> + + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + + <div class='summary'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + + <div class='summary line'>积分抵扣金额:¥-<span>{$object['scoreMoney']}</span></div> + + {:hook('adminDocumentOrderSummaryView',['order'=>$object])} + + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div class='summary'>使用产品券:¥<span>{$object['productNum']}</span></div> + <div class='summary'>使用优惠券:¥<span>{$object['couponsNum']}</span></div> + <div class='summary'>使用旺旺券:¥<span>{$object['wangNum']}</span></div> + <div class='summary'>使用现金:¥<span>{$object['moneyNum']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + + </div> + + </div> + + </div> + + <div class='wst-footer'> + + <button type="button" class="btn" onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</div> + +<div> + +{/block} + diff --git a/hyhproject/admin/view/payments/list.html b/hyhproject/admin/view/payments/list.html new file mode 100755 index 0000000..6347b91 --- /dev/null +++ b/hyhproject/admin/view/payments/list.html @@ -0,0 +1,17 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +<script> + $(function(){initGrid()}); +</script> + +{/block} diff --git a/hyhproject/admin/view/payments/pay_alipays.html b/hyhproject/admin/view/payments/pay_alipays.html new file mode 100755 index 0000000..fe83281 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_alipays.html @@ -0,0 +1,63 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>支付宝账户<font color='red'>*</font>:</th> + <td> + <input type="text" id="payAccount" name="payAccount" value="{$object['payAccount']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>合作者身份(parterID)<font color='red'>*</font>:</th> + <td> + <input type="text" id="parterID" name="parterID" value="{$object['parterID']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>交易安全校验码(key)<font color='red'>*</font>:</th> + <td> + <input type="text" id="parterKey" name="parterKey" value="{$object['parterKey']?? ''}" class="cfg" maxLength='200' /> + <input type="hidden" id="payIcon" value="{$object['payIcon']?? ''}" class="cfg" maxLength='20' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;" >{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +<script> + +</script> +{/block} + diff --git a/hyhproject/admin/view/payments/pay_app_alipays.html b/hyhproject/admin/view/payments/pay_app_alipays.html new file mode 100755 index 0000000..f67c393 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_app_alipays.html @@ -0,0 +1,63 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>应用appId<font color='red'>*</font>:</th> + <td> + <input type="text" id="appId" name="appId" value="{$object['appId']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>应用私钥<font color='red'>*</font>:</th> + <td> + <textarea id="rsaPrivateKey" name="rsaPrivateKey" style="width:340px;height:100px;" class="cfg">{$object['rsaPrivateKey']?? ''}</textarea> + <input type="hidden" id="payIcon" value="{$object['payIcon']?? ''}" class="cfg" maxLength='20' /> + </td> + </tr> + <tr> + <th>支付宝公钥<font color='red'>*</font>:</th> + <td> + <textarea id="alipayrsaPublicKey" name="alipayrsaPublicKey" style="width:340px;height:100px;" class="cfg">{$object['alipayrsaPublicKey']?? ''}</textarea> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;" >{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"'><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +<script> + +</script> +{/block} + diff --git a/hyhproject/admin/view/payments/pay_app_weixinpays.html b/hyhproject/admin/view/payments/pay_app_weixinpays.html new file mode 100755 index 0000000..dedca47 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_app_weixinpays.html @@ -0,0 +1,67 @@ + +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>APPID<font color='red'>*</font>:</th> + <td> + <input type="text" id="appId" name="appId" value="{$object['appId'] ?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>微信支付商户号<font color='red'>*</font>:(mch_id)&nbsp;&nbsp;&nbsp;&nbsp;</th> + <td> + <input type="text" id="mchId" name="mchId" value="{$object['mchId']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>API密钥(key)<font color='red'>*</font>:</th> + <td> + <input type="text" id="apiKey" name="apiKey" value="{$object['apiKey']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>Appsecret<font color='red'>*</font>:</th> + <td> + <input type="text" id="appsecret" name="appsecret" value="{$object['appsecret']?? ''}" class="cfg" maxLength='100' /> + <input type="hidden" id="payIcon" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;">{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +{/block} + diff --git a/hyhproject/admin/view/payments/pay_cod.html b/hyhproject/admin/view/payments/pay_cod.html new file mode 100755 index 0000000..4962998 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_cod.html @@ -0,0 +1,48 @@ + +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='20' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:200px;height:100px;" >{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + <tr> + <th>是否在线支付:</th> + <td> + 否 + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +{/block} + diff --git a/hyhproject/admin/view/payments/pay_unionpays.html b/hyhproject/admin/view/payments/pay_unionpays.html new file mode 100755 index 0000000..09cd690 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_unionpays.html @@ -0,0 +1,56 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>商户账号<font color='red'>*</font>:</th> + <td> + <input type="text" id="unionMerId" name="unionMerId" value="{$object['unionMerId']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>签名证书密码<font color='red'>*</font>:</th> + <td> + <input type="text" id="unionSignCertPwd" name="unionSignCertPwd" value="{$object['unionSignCertPwd']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;" >{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +<script> + +</script> +{/block} + diff --git a/hyhproject/admin/view/payments/pay_wallets.html b/hyhproject/admin/view/payments/pay_wallets.html new file mode 100755 index 0000000..63ca85a --- /dev/null +++ b/hyhproject/admin/view/payments/pay_wallets.html @@ -0,0 +1,44 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;" >{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +<script> + +</script> +{/block} + diff --git a/hyhproject/admin/view/payments/pay_weixinpays.html b/hyhproject/admin/view/payments/pay_weixinpays.html new file mode 100755 index 0000000..5341721 --- /dev/null +++ b/hyhproject/admin/view/payments/pay_weixinpays.html @@ -0,0 +1,67 @@ + +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/payments/payments.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>支付名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="payName" name="payName" value="{$object['payName']}" class="ipt" maxLength='100' /> + </td> + </tr> + <tr> + <th>APPID<font color='red'>*</font>:</th> + <td> + <input type="text" id="appId" name="appId" value="{$object['appId'] ?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>微信支付商户号<font color='red'>*</font>:(mch_id)&nbsp;&nbsp;&nbsp;&nbsp;</th> + <td> + <input type="text" id="mchId" name="mchId" value="{$object['mchId']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>API密钥(key)<font color='red'>*</font>:</th> + <td> + <input type="text" id="apiKey" name="apiKey" value="{$object['apiKey']?? ''}" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>Appsecret<font color='red'>*</font>:</th> + <td> + <input type="text" id="appsecret" name="appsecret" value="{$object['appsecret']?? ''}" class="cfg" maxLength='100' /> + <input type="hidden" id="payIcon" class="cfg" maxLength='100' /> + </td> + </tr> + <tr> + <th>支付方式描述<font color='red'>*</font>:</th> + <td> + <textarea id="payDesc" name="payDesc" class="ipt" style="width:340px;height:100px;">{$object['payDesc']}</textarea> + </td> + </tr> + <tr> + <th>排序号<font color='red'>*</font>:</th> + <td> + <input type="text" id="payOrder" name="payOrder" value="{$object['payOrder']}" class="ipt" maxLength='20' /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" id="id" value="{$object['id']}" /> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> + + +{/block} + diff --git a/hyhproject/admin/view/payments/payments.js b/hyhproject/admin/view/payments/payments.js new file mode 100755 index 0000000..6374b0b --- /dev/null +++ b/hyhproject/admin/view/payments/payments.js @@ -0,0 +1,99 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'名称', name:'payName', width: 30}, + {title:'描述', name:'payDesc' }, + {title:'状态', name:'enabled', renderer: function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 开启</span>":"<span class='statu-no'><i class='fa fa-ban'></i> 关闭</span>"; + }}, + {title:'排序号', name:'payOrder' }, + {title:'操作', name:'op' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(item['enabled']==1){ + if(WST.GRANT.ZFGL_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/payments/toEdit','id='+item['id']+'&payCode='+item['payCode'])+"'><i class='fa fa-pencil'></i>编辑</a> "; + if(WST.GRANT.ZFGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>卸载</a> "; + } + else{ + if(WST.GRANT.ZFGL_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/payments/toEdit','id='+item['id']+'&payCode='+item['payCode'])+"'><i class='fa fa-gear'></i>安装</a> "; + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-40),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/payments/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定卸载吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/payments/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function edit(id){ + //获取所有参数 + var params = WST.getParams('.ipt'); + //接收配置信息并转成JSON + var configs = WST.getParams('.cfg'); + //保存配置信息 + params.payConfig = configs; + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/payments/'+((id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/payments/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +$(function(){ + $('#payForm').validator({ + fields: { + /*默认验证*/ + payName: {rule:"required;",msg:{required:"请输入支付名称"},tip:"请输入支付名称",ok:"",}, + payDesc: {rule:"required;",msg:{required:"请输入支付描述"},tip:"请输入支付描述",ok:"",}, + payOrder: {rule:"required;",msg:{required:"请输入排序号"},tip:"请输入排序号",ok:"",}, + /*微信验证*/ + appId: {rule:"required;",msg:{required:"请输入APPID"},tip:"请输入APPID",ok:"",}, + mchId: {rule:"required;",msg:{required:"请输入微信支付商户号(mch_id)"},tip:"请输入微信支付商户号(mch_id)",ok:"",}, + apiKey: {rule:"required;",msg:{required:"请输入API密钥(key)"},tip:"请输入API密钥(key)",ok:"",}, + appsecret: {rule:"required;",msg:{required:"请输入Appsecret"},tip:"请输入Appsecret",ok:"",}, + /*支付宝验证*/ + payAccount: {rule:"required;",msg:{required:"请输入支付宝账户"},tip:"请输入支付宝账户",ok:"",}, + parterID: {rule:"required;",msg:{required:"请输入合作者身份(parterID)"},tip:"请输入合作者身份(parterID)",ok:"",}, + parterKey: {rule:"required;",msg:{required:"请输入交易安全校验码(key"},tip:"请输入交易安全校验码(key",ok:"",}, + /*银联支付验证*/ + unionAccount: {rule:"required;",msg:{required:"请输入银联商户账号"},tip:"请输入银联商户账号",ok:"",}, + unionSignCertPwd: {rule:"required;",msg:{required:"请输入签名证书密码"},tip:"请输入签名证书密码",ok:"",}, + /*APP支付宝支付*/ + rsaPrivateKey: {rule:"required;",msg:{required:"请输入应用私钥"},tip:"请输入应用私钥",ok:"",}, + alipayrsaPublicKey: {rule:"required;",msg:{required:"请输入支付宝公钥"},tip:"请输入支付宝公钥",ok:"",} + + }, + valid:function(form){ + edit($('#id').val()) + }, + }); + +}); \ No newline at end of file diff --git a/hyhproject/admin/view/platform/platform.html b/hyhproject/admin/view/platform/platform.html new file mode 100755 index 0000000..849f975 --- /dev/null +++ b/hyhproject/admin/view/platform/platform.html @@ -0,0 +1,93 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/platform/platform.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='load()'><i class="fa fa-search"></i>查询</button> +<form id="payForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>app注册数量<font color='red'>*</font>:</th> + <td> + <span id="appNum">{$object['appNum']}</span> + </td> + </tr> + <tr> + <th width='150'>pc注册数量<font color='red'>*</font>:</th> + <td><span id="pcNum">{$object['pcNum']}</span> + </td> + </tr> + <tr> + <th width='150'>webapp注册数量<font color='red'>*</font>:</th> + <td><span id="webappNum">{$object['webappNum']}</span> + </td> + </tr> + <tr> + <th width='150'>下单用户数量<font color='red'>*</font>:</th> + <td><span id="validUser">{$object['validUser']}</span> + </td> + </tr> + <tr> + <th width='150'>转换率<font color='red'>*</font>:</th> + <td><span id="orderRade">{$object['orderRade']}</span> + </td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<div class="wst-toolbar"> + +<!-- <input type="text" name="goodsName" placeholder='商品名称' id="goodsName" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +<input type="text" name="loginName" placeholder='用户名称' id="loginName" class='j-ipt'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> --> +<!-- <button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExport()'><i class="fa fa-sign-in"></i>导出</button> --> +<div style='clear:both'></div> +</div> +<!-- <div class='wst-grid'> +<div id="mmg" class="mmg layui-form"></div> +<div id="pg" style="text-align: right;"></div> +</div> --> +<script> + function load(){ + var start=document.getElementById('startDate').value; + var end=document.getElementById('endDate').value; + $.ajax({ + url:"{:url('platform/index')}", + type:"post", + data:{end:end,start:start}, + dataType:"json", + success:function(data){ + if (data.status==1) { + $('#appNum').text(data.data.appNum) + $('#pcNum').text(data.data.pcNum) + $('#webappNum').text(data.data.webappNum) + $('#validUser').text(data.data.validUser) + $('#orderRade').text(data.data.orderRade) + } + } + }) + // $.post("{:url('platform/index')}",{ + // end:end,start:start + // },function(data){ + // if (data.status==1) { + // alert(data) + // } + // }) + } +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/platform/platform.js b/hyhproject/admin/view/platform/platform.js new file mode 100755 index 0000000..77b0530 --- /dev/null +++ b/hyhproject/admin/view/platform/platform.js @@ -0,0 +1,41 @@ +var mmg; +$(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'app注册数量', name:'appNum' ,width:30,sortable:true}, + {title:'pc注册数量', name:'pcNum' ,width:30,sortable:true}, + {title:'webapp注册数量', name:'webNum' ,width:30,sortable:true}, + // {title:'商品名称', name:'goodsName', width: 120,sortable:true,renderer: function(val,item,rowIndex){ + // return "<span><p>"+item['goodsName']+"</p></span>"; + // }}, + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/platform/platformByPage'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'goodsSn',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/platform/toExport',params); + }}); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.page = 1; + mmg.load(params); +} diff --git a/hyhproject/admin/view/platform/view_data.html b/hyhproject/admin/view/platform/view_data.html new file mode 100755 index 0000000..d591047 --- /dev/null +++ b/hyhproject/admin/view/platform/view_data.html @@ -0,0 +1,145 @@ +{extend name="base" /} + +{block name="css"} + +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> + +{/block} + +{block name="js"} + +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> + +<script src="__ADMIN__/platform/platform.js?v={$v}" type="text/javascript"></script> + + + +{/block} + +{block name="main"} + +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<select name="dataType" id="dataType" class="query j-ipt"> + <option value="0">请选择券种类型</option> + <option value="1">预获产品券</option> + <option value="2">预获优惠券</option> + <option value="3">已获产品券</option> + <option value="4">己获优惠券</option> + <option value="5">旺旺券</option> +</select> +<input type="checkbox" id="" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> + +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> + +至 + +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> + +<button class="btn btn-primary" id="search" onclick='load()'><i class="fa fa-search"></i>查询</button> + +<form id="payForm" autocomplete="off"> + +<table class='wst-form wst-box-top'> + + <tr> + + <th width='150'>合计:</th> + + <td> + + <span><font color='red' id="num">0</font></span> + + </td> + + </tr> + + + + <!-- <td colspan='2' align='center' class='wst-bottombar'> + + + + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + + </td> + --> + +</table> + +</form> + +<div class="wst-toolbar"> + + + +<!-- <input type="text" name="goodsName" placeholder='商品名称' id="goodsName" class='j-ipt'/> + +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + +<input type="text" name="loginName" placeholder='用户名称' id="loginName" class='j-ipt'/> + +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> --> + +<!-- <button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExport()'><i class="fa fa-sign-in"></i>导出</button> --> + +<div style='clear:both'></div> + +</div> + +<!-- <div class='wst-grid'> + +<div id="mmg" class="mmg layui-form"></div> + +<div id="pg" style="text-align: right;"></div> + +</div> --> + +<script> + + function load(){ + var dataType=document.getElementById('dataType').value; + if(0 == dataType){ + alert('请选择券种类型');return; + } + var start=document.getElementById('startDate').value; + + var end=document.getElementById('endDate').value; + $('#search').attr('disabled','disabled'); + $.ajax({ + + url:"{:url('platform/viewData')}", + + type:"post", + + data:{dataType:dataType,end:end,start:start}, + + dataType:"json", + + success:function(data){ + if (data.status==1) { + $('#num').text(data.data.num) ; + } + $('#search').removeAttr('disabled'); + } + }) + + // $.post("{:url('platform/index')}",{ + + // end:end,start:start + + // },function(data){ + + // if (data.status==1) { + + // alert(data) + + // } + + // }) + + } + +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/recommends/brands.html b/hyhproject/admin/view/recommends/brands.html new file mode 100755 index 0000000..654634b --- /dev/null +++ b/hyhproject/admin/view/recommends/brands.html @@ -0,0 +1,91 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/recommends/recommends.js?v=1{$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style> +input[type=text]{padding: 6px 5px;} +</style> +<form autocomplete='off'> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于前台品牌展示的推荐设置。</li> + <li>本功能为扩展功能,开发者可通过组合不同的商品分类和推荐类型在前台进行品牌信息的展示</li> + </ul> +</div> +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>商品分类<font color='red'>*</font>:</th> + <td colspan='2'> + <select id="cat12_0" class='ipt pgoodsCats1_2' level="0" onchange="WST.ITGoodsCats({id:'cat12_0',val:this.value,isRequire:false,className:'pgoodsCats1_2'});"> + <option value=''>请选择</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + <td> + &nbsp; + </td> + <tr> + <th width='120'>搜索:</th> + <td colspan='2'> + <input type='text' id='key_2' style='width:250px' class='ipt_2' placeholder='品牌名称'/> + <button type="button" class="btn btn-primary" onclick='javascript:loadBrands("_2")'><i class="fa fa-search"></i>搜索</button> + </td> + <td> + 商品分类<font color='red'>*</font>: + <select id="cat22_0" class='ipt pgoodsCats2_2' level="0" onchange="WST.ITGoodsCats({id:'cat22_0',val:this.value,isRequire:false,className:'pgoodsCats2_2',afterFunc:'listQueryByBrands'});"> + <option value=''>所有分类</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <input type='hidden' id='dataType_2' value='0'/> + </td> + </tr> + <tr> + <th>请选择<font color='red'>*</font>:</th> + <td width='320'> + <div class="recom-lbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.lchk_2')" type="checkbox"></div> + <div class="ttxt">品牌</div> + </div> + <div id="llist_2" style="width:350px;"></div> + </div> + </td> + <td align='center'> + <input type='button' value='》》' class='btn btn-primary' onclick='javascript:moveRight("_2")'/> + <br/><br/> + <input type='button' value='《《' class='btn btn-primary' onclick='javascript:moveLeft("_2")'/> + <input type='hidden' id='ids_2'/> + </td> + <td> + <div class="recom-rbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.rchk_2')" type="checkbox"></div> + <div class="ttxt">品牌</div> + <div class="top">排序</div> + </div> + <div id="rlist_2"></div> + </div> + </td> + </tr> + {if WSTGrant('PPTJ_04')} + <tr> + <td colspan='4' align='center' style='padding-top:10px;'> + <button type="button" class="btn btn-primary" onclick='javascript:editBrands("_2")'><i class="fa fa-check"></i>保存</button> + </td> + </tr> + {/if} +</table> +</form> +<script> +$(function(){ + listQueryByBrands('_2'); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){}}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/recommends/goods.html b/hyhproject/admin/view/recommends/goods.html new file mode 100755 index 0000000..cb5b627 --- /dev/null +++ b/hyhproject/admin/view/recommends/goods.html @@ -0,0 +1,97 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/recommends/recommends.js?v=1{$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style> +input[type=text]{padding: 6px 5px;} +</style> +<form autocomplete='off'> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于前台商品展示的推荐设置,例如首页各楼层,猜你喜欢,最新上架,热销商品,推荐商城等等。</li> + <li>若未进行过商品的推荐操作,则系统默认按照商品销量、上架时间排序;若有设置过则以设置的商品及排序为主。</li> + <li>本功能为扩展功能,开发者可通过组合不同的商品分类和推荐类型在前台进行商品信息的展示</li> + </ul> +</div> +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>商品分类<font color='red'>*</font>:</th> + <td colspan='2'> + <select id="cat12_0" class='ipt pgoodsCats1_2' level="0" onchange="WST.ITGoodsCats({id:'cat12_0',val:this.value,isRequire:false,className:'pgoodsCats1_2'});"> + <option value=''>请选择</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + <td> + 商品分类<font color='red'>*</font>: + <select id="cat22_0" class='ipt pgoodsCats2_2' level="0" onchange="WST.ITGoodsCats({id:'cat22_0',val:this.value,isRequire:false,className:'pgoodsCats2_2',afterFunc:'listQueryByGoods'});"> + <option value=''>所有分类</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + <tr> + <th width='120'>搜索:</th> + <td colspan='2'> + <input type='text' id='key_2' style='width:250px' class='ipt_2' placeholder='商品名称、商品编号'/> + <button type="button" class="btn btn-primary" onclick='javascript:loadGoods("_2")'><i class="fa fa-search"></i>搜索</button> + </td> + <td style='padding-left:30px;'> + 类型<font color='red'>*</font>: + <select id='dataType_2' onchange='listQueryByGoods("_2")'> + <option value='0'>推荐</option> + <option value='1'>热销</option> + <option value='2'>精品</option> + <option value='3'>新品</option> + </select> + </td> + </tr> + <tr> + <th>请选择<font color='red'>*</font>:</th> + <td width='320'> + <div class="recom-lbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.lchk_2')" type="checkbox"></div> + <div class="ttxt">商品</div> + </div> + <div id="llist_2" style="width:350px;"></div> + </div> + </td> + <td align='center'> + <input type='button' value='》》' class='btn btn-primary' onclick='javascript:moveRight("_2")'/> + <br/><br/> + <input type='button' value='《《' class='btn btn-primary' onclick='javascript:moveLeft("_2")'/> + <input type='hidden' id='ids_2'/> + </td> + <td> + <div class="recom-rbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.rchk_2')" type="checkbox"></div> + <div class="ttxt">商品</div> + <div class="top">排序</div> + </div> + <div id="rlist_2"></div> + </div> + </td> + </tr> + {if WSTGrant('SPTJ_04')} + <tr> + <td colspan='4' align='center' style='padding-top:10px;'> + <button type="button" class="btn btn-primary" onclick='javascript:editGoods("_2")'><i class="fa fa-check"></i>保存</button> + </td> + </tr> + {/if} +</table> +</form> +<script> +$(function(){ + listQueryByGoods('_2'); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){}}); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/recommends/recommends.js b/hyhproject/admin/view/recommends/recommends.js new file mode 100755 index 0000000..5bae7f9 --- /dev/null +++ b/hyhproject/admin/view/recommends/recommends.js @@ -0,0 +1,276 @@ +function moveRight(suffix){ + $('input[name="lchk'+suffix+'"]:checked').each(function(){ + var html = []; + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="rchk'+suffix+'" class="rchk'+suffix+'" value="'+$(this).val()+'"></div>'); + html.push('<div class="ttxt">'+$(this).parent().parent().find('.ttxt').html()+'</div>'); + html.push('<div class="top"><input type="text" class="s-sort s-ipt'+suffix+'" value="0" v="'+$(this).val()+'"></div></div>'); + $(this).parent().parent().remove(); + $('#rlist'+suffix).append(html.join('')); + }); + var ids = []; + $('input[name="rchk'+suffix+'"]').each(function(){ + ids.push($(this).val()); + }); + $('#ids'+suffix).val(ids.join(',')); +} +function moveLeft(suffix){ + $('input[name="rchk'+suffix+'"]:checked').each(function(){ + var html = []; + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="lchk'+suffix+'" class="lchk'+suffix+'" value="'+$(this).val()+'"></div>'); + html.push('<div class="ttxt">'+$(this).parent().parent().find('.ttxt').html()+'</div></div>'); + $(this).parent().parent().remove(); + $('#llist'+suffix).append(html.join('')); + }) +} +/**商品**/ +function loadGoods(suffix){ + var params = WST.getParams('.ipt'+suffix); + params.key = params['key'+suffix]; + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats1'+suffix); + if(params.goodsCatId==''){ + WST.msg('请选择一个商品分类',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/searchGoods'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(!json.data)return; + json = json.data; + $("#llist"+suffix).empty(); + var ids = $('#ids'+suffix).val().split(','); + var data,html=[]; + for(var i=0;i<json.length;i++){ + data = json[i]; + if($.inArray(data.goodsId.toString(),ids)==-1){ + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="lchk'+suffix+'" class="lchk'+suffix+'" value="'+data.goodsId+'"></div>'); + html.push('<div class="ttxt">【'+data.shopName+'】'+data.goodsName+'</div></div>'); + } + } + $("#llist"+suffix).html(html.join('')); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function listQueryByGoods(suffix){ + suffix = (typeof(suffix)=='object')?'_2':suffix; + $('#rlist'+suffix).empty(); + $('#ids'+suffix).val(''); + var params = {}; + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/listQueryByGoods'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(json.data && json.data.length){ + json = json.data; + var data,html=[],ids = []; + for(var i=0;i<json.length;i++){ + data = json[i]; + ids.push(data.dataId); + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="rchk'+suffix+'" class="rchk'+suffix+'" value="'+data.dataId+'"></div>'); + html.push('<div class="ttxt">【'+data.shopName+'】'+data.goodsName+'</div>'); + html.push('<div class="top"><input type="text" class="s-sort s-ipt'+suffix+'" value="'+data.dataSort+'" v="'+data.dataId+'"></div></div>'); + } + $('#ids'+suffix).val(ids.join(',')); + $("#rlist"+suffix).html(html.join('')); + } + if(WST.ITGetGoodsCatVal('pgoodsCats1'+suffix)>0)loadGoods(suffix); + } + }); +} +function editGoods(suffix){ + var params = {},ids = []; + $('input[name="rchk'+suffix+'"]').each(function(){ + ids.push($(this).val()); + }); + $('.s-ipt'+suffix).each(function(){ + params['ipt'+$(this).attr('v')] = $(this).val(); + }) + params.ids = ids.join(','); + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/editGoods'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("保存成功",{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +/***店铺**/ +function loadShops(suffix){ + var params = WST.getParams('.ipt'+suffix); + params.key = params['key'+suffix]; + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats1'+suffix); + if(params.goodsCatId==''){ + WST.msg('请选择一个经营范围',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/searchShops'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(!json.data)return; + json = json.data; + $("#llist"+suffix).empty(); + var ids = $('#ids'+suffix).val().split(','); + var data,html=[]; + for(var i=0;i<json.length;i++){ + data = json[i]; + if($.inArray(data.shopId.toString(),ids)==-1){ + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="lchk'+suffix+'" class="lchk'+suffix+'" value="'+data.shopId+'"></div>'); + html.push('<div class="ttxt">【'+data.shopSn+'】'+data.shopName+'</div></div>'); + } + } + $("#llist"+suffix).html(html.join('')); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function listQueryByShops(suffix){ + suffix = (typeof(suffix)=='object')?'_2':suffix; + $('#rlist'+suffix).empty(); + $('#ids'+suffix).val(''); + var params = {}; + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/listQueryByShops'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(json.data && json.data.length){ + json = json.data; + var data,html=[],ids = []; + for(var i=0;i<json.length;i++){ + data = json[i]; + ids.push(data.dataId); + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="rchk'+suffix+'" class="rchk'+suffix+'" value="'+data.dataId+'"></div>'); + html.push('<div class="ttxt">【'+data.shopSn+'】'+data.shopName+'</div>'); + html.push('<div class="top"><input type="text" class="s-sort s-ipt'+suffix+'" value="'+data.dataSort+'" v="'+data.dataId+'"></div></div>'); + } + $('#ids'+suffix).val(ids.join(',')); + $("#rlist"+suffix).html(html.join('')); + } + if(WST.ITGetGoodsCatVal('pgoodsCats1'+suffix)>0)loadShops(suffix); + } + }); +} + +function editShops(suffix){ + var params = {},ids = []; + $('input[name="rchk'+suffix+'"]').each(function(){ + ids.push($(this).val()); + }); + $('.s-ipt'+suffix).each(function(){ + params['ipt'+$(this).attr('v')] = $(this).val(); + }) + params.ids = ids.join(','); + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/editShops'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("保存成功",{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/**品牌**/ +function loadBrands(suffix){ + var params = WST.getParams('.ipt'+suffix); + params.key = params['key'+suffix]; + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats1'+suffix); + if(params.goodsCatId==''){ + WST.msg('请选择一个商品分类',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/searchBrands'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(!json.data)return; + json = json.data; + $("#llist"+suffix).empty(); + var ids = $('#ids'+suffix).val().split(','); + var data,html=[]; + for(var i=0;i<json.length;i++){ + data = json[i]; + if($.inArray(data.brandId.toString(),ids)==-1){ + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="lchk'+suffix+'" class="lchk'+suffix+'" value="'+data.brandId+'"></div>'); + html.push('<div class="ttxt">'+data.brandName+'</div></div>'); + } + } + $("#llist"+suffix).html(html.join('')); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function listQueryByBrands(suffix){ + suffix = (typeof(suffix)=='object')?'_2':suffix; + $('#rlist'+suffix).empty(); + $('#ids'+suffix).val(''); + var params = {}; + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/listQueryByBrands'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(json.data && json.data.length){ + json = json.data; + var data,html=[],ids = []; + for(var i=0;i<json.length;i++){ + data = json[i]; + ids.push(data.dataId); + html.push('<div class="trow"><div class="tck"><input type="checkbox" name="rchk'+suffix+'" class="rchk'+suffix+'" value="'+data.dataId+'"></div>'); + html.push('<div class="ttxt">'+data.brandName+'</div>'); + html.push('<div class="top"><input type="text" class="s-sort s-ipt'+suffix+'" value="'+data.dataSort+'" v="'+data.dataId+'"></div></div>'); + } + $('#ids'+suffix).val(ids.join(',')); + $("#rlist"+suffix).html(html.join('')); + } + if(WST.ITGetGoodsCatVal('pgoodsCats1'+suffix)>0)loadBrands(suffix); + } + }); +} + +function editBrands(suffix){ + var params = {},ids = []; + $('input[name="rchk'+suffix+'"]').each(function(){ + ids.push($(this).val()); + }); + $('.s-ipt'+suffix).each(function(){ + params['ipt'+$(this).attr('v')] = $(this).val(); + }) + params.ids = ids.join(','); + params.dataType = $('#dataType'+suffix).val(); + params.goodsCatId = WST.ITGetGoodsCatVal('pgoodsCats2'+suffix); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/recommends/editBrands'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("保存成功",{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/recommends/shops.html b/hyhproject/admin/view/recommends/shops.html new file mode 100755 index 0000000..a325b6f --- /dev/null +++ b/hyhproject/admin/view/recommends/shops.html @@ -0,0 +1,91 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/recommends/recommends.js?v=1{$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style> +input[type=text]{padding: 6px 5px;} +</style> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于前台店铺展示的推荐设置</li> + <li>本功能为扩展功能,开发者可通过组合不同的商品分类和推荐类型在前台进行店铺信息的展示</li> + </ul> +</div> +<form autocomplete='off'> +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>经营范围<font color='red'>*</font>:</th> + <td colspan='2'> + <select id="cat12_0" class='ipt pgoodsCats1_2' level="0" onchange="WST.ITGoodsCats({id:'cat12_0',val:this.value,isRequire:false,className:'pgoodsCats1_2'});"> + <option value=''>请选择</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + <td> + &nbsp; + </td> + <tr> + <th width='120'>搜索:</th> + <td colspan='2'> + <input type='text' id='key_2' style='width:250px' class='ipt_2' placeholder='店铺名称、店铺编号'/> + <button type="button" class="btn btn-primary" onclick='javascript:loadShops("_2")'><i class="fa fa-search"></i>搜索</button> + </td> + <td> + 经营范围<font color='red'>*</font>: + <select id="cat22_0" class='ipt pgoodsCats2_2' level="0" onchange="WST.ITGoodsCats({id:'cat22_0',val:this.value,isRequire:false,className:'pgoodsCats2_2',afterFunc:'listQueryByShops'});"> + <option value=''>所有范围</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <input type='hidden' id='dataType_2' value='0'/> + </td> + </tr> + <tr> + <th>请选择<font color='red'>*</font>:</th> + <td width='320'> + <div class="recom-lbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.lchk_2')" type="checkbox"></div> + <div class="ttxt">店铺</div> + </div> + <div id="llist_2" style="width:350px;"></div> + </div> + </td> + <td align='center'> + <input type='button' value='》》' class='btn btn-primary' onclick='javascript:moveRight("_2")'/> + <br/><br/> + <input type='button' value='《《' class='btn btn-primary' onclick='javascript:moveLeft("_2")'/> + <input type='hidden' id='ids_2'/> + </td> + <td> + <div class="recom-rbox"> + <div class="trow head"> + <div class="tck"><input onclick="WST.checkChks(this,'.rchk_2')" type="checkbox"></div> + <div class="ttxt">店铺</div> + <div class="top">排序</div> + </div> + <div id="rlist_2"></div> + </div> + </td> + </tr> + {if WSTGrant('DPTJ_04')} + <tr> + <td colspan='4' align='center' style='padding-top:10px;'> + <button type="button" class="btn btn-primary" onclick='javascript:editShops("_2")'><i class="fa fa-check"></i>保存</button> + </td> + </tr> + {/if} +</table> +</form> +<script> +$(function(){ + listQueryByShops('_2'); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){}}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_new_user.html b/hyhproject/admin/view/reports/stat_new_user.html new file mode 100755 index 0000000..9625af3 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_new_user.html @@ -0,0 +1,101 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/stat_new_user.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='javascript:loadStat()'><i class='fa fa-search'></i>查询</button> +</div> +<div id="main" style='float:left;width:75%;height:90%;'> +</div> +<div id="content" style='float:left;width:25%;height:90%;position: relative;margin-top: 200px;'> + <table> + <tr><th width='150'>会员增长数量<font color='red'>*</font>:<span id="groupNum"></span></th><td></td></tr> + <tr><th width='150'>会员增长率<font color='red'>*</font>:<span id="groupRate"></span></th><td></td></tr> + </table> +</table> +</div> +<!-- <div class='wst-grid' style='float:left;width:15%;height:90%;position: relative;margin-top:200px;'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> --> +<!-- <script> +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'会员增长数量', name:'loginName', width: 120,sortable:true}, + {title:'真实姓名', name:'trueName' ,width:60,sortable:true}, + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),cols: cols,method:'POST', + url: WST.U('admin/reports/statNewUserPage') + }); +} +$(function(){initGrid();}) +</script> --> +<script> + function loadStat(){ + var loading = WST.msg('正在查询数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/reports/statNewUser'),WST.getParams('.ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + + if(json.status=='1'){ + $("#groupNum").text(JSON.stringify(json.groupNum)); + var num = 5.9758966564164646; + var a=JSON.stringify(json.groupRate); + if(a.length >=3){ + a = (Number(num.toFixed(2))+0.01); + } + $("#groupRate").text(a); + var option = { + tooltip: { + trigger: 'axis' + }, + legend: { + data:['会员','店铺'] + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: json.data.days + }, + yAxis: { + type: 'value' + }, + series: [ + { + name:'会员', + type:'line', + data:json.data.u0 + }, + { + name:'店铺', + type:'line', + data:json.data.u1 + } + ] + }; + + myChart.setOption(option); + } + }); +} +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_new_user.js b/hyhproject/admin/view/reports/stat_new_user.js new file mode 100755 index 0000000..9a3eaf2 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_new_user.js @@ -0,0 +1,15 @@ +var myChart; +$(function(){ + var h = WST.pageHeight(); + $('#main').height(h-50); + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + myChart = echarts.init(document.getElementById('main')); + loadStat(); +}); + diff --git a/hyhproject/admin/view/reports/stat_orders.html b/hyhproject/admin/view/reports/stat_orders.html new file mode 100755 index 0000000..88db9a6 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_orders.html @@ -0,0 +1,20 @@ +{extend name="base" /} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/stat_orders.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}' placeholder='结束日期'/> +支付方式: +<select id='payType' class='ipt'> + <option value='-1'>全部</option> + <option value='0'>货到付款</option> + <option value='1'>在线支付</option> +</select> +<button class="btn btn-primary" onclick='javascript:loadStat()'><i class='fa fa-search'></i>查询</button> +</div> +<div id="main" style='width:100%;height:99%;'></div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_orders.js b/hyhproject/admin/view/reports/stat_orders.js new file mode 100755 index 0000000..fabe2d6 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_orders.js @@ -0,0 +1,127 @@ +$(function(){ + var h = WST.pageHeight(); + $('#main').height(h-50); + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + loadStat(); +}); +function loadStat(){ + var loading = WST.msg('正在查询数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/reports/statOrders'),WST.getParams('.ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + y: 'top', + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + legend: { + data:['电脑端','微信端','触屏端','安卓端','苹果端'] + }, + xAxis : [ + { + type : 'category', + splitLine : {show : false}, + data : json.data.days + } + ], + yAxis : [ + { + type : 'value', + position: 'right' + } + ], + series : [ + { + name:'电脑端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p0'] + }, + { + name:'微信端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p1'] + }, + { + name:'触屏端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p2'] + }, + { + name:'安卓端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p3'] + }, + { + name:'苹果端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p3'] + }, + { + name:'销售额', + type:'line', + data:json.data['total'] + }, + + { + name:'销售来源细分', + type:'pie', + tooltip : { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + center: [160,130], + radius : [0, 50], + itemStyle : { + normal : { + labelLine : { + length : 20 + } + } + }, + data:[ + {value:json.data.map.p0, name:'电脑端'}, + {value:json.data.map.p1, name:'微信端'}, + {value:json.data.map.p2, name:'触屏端'}, + {value:json.data.map.p3, name:'安卓端'}, + {value:json.data.map.p4, name:'苹果端'} + ] + } + ] + }; + myChart.setOption(option); + }else{ + WST.msg('没有查询到记录'); + } + + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_sales.html b/hyhproject/admin/view/reports/stat_sales.html new file mode 100755 index 0000000..8e07ad2 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_sales.html @@ -0,0 +1,22 @@ +{extend name="base" /} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/stat_sales.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}' placeholder='结束日期'/> +<div class='f-left tbr-m'> +支付方式: +<select id='payType' class='ipt'> + <option value='-1'>全部</option> + <option value='0'>货到付款</option> + <option value='1'>在线支付</option> +</select> +</div> +<button class="btn btn-primary" onclick='javascript:loadStat()'><i class='fa fa-search'></i>查询</button> +</div> +<div id="main" style='width:100%;height:99%;'></div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_sales.js b/hyhproject/admin/view/reports/stat_sales.js new file mode 100755 index 0000000..20f239b --- /dev/null +++ b/hyhproject/admin/view/reports/stat_sales.js @@ -0,0 +1,126 @@ +$(function(){ + var h = WST.pageHeight(); + $('#main').height(h-50); + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + loadStat(); +}); +function loadStat(){ + var loading = WST.msg('正在查询数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/reports/statSales'),WST.getParams('.ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + y: 'top', + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + legend: { + data:['电脑端','微信端','触屏端','安卓端','苹果端'] + }, + xAxis : [ + { + type : 'category', + splitLine : {show : false}, + data : json.data.days + } + ], + yAxis : [ + { + type : 'value', + position: 'right' + } + ], + series : [ + { + name:'电脑端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p0'] + }, + { + name:'微信端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p1'] + }, + { + name:'触屏端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p2'] + }, + { + name:'安卓端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p3'] + }, + { + name:'苹果端', + type:'line', + tooltip : {trigger: 'item'}, + stack: '来源', + data:json.data['p4'] + }, + { + name:'销售额', + type:'line', + data:json.data['total'] + }, + + { + name:'销售来源细分', + type:'pie', + tooltip : { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + center: [160,130], + radius : [0, 50], + itemStyle : { + normal : { + labelLine : { + length : 20 + } + } + }, + data:[ + {value:json.data.map.p0, name:'电脑端'}, + {value:json.data.map.p1, name:'微信端'}, + {value:json.data.map.p2, name:'触屏端'}, + {value:json.data.map.p3, name:'安卓端'}, + {value:json.data.map.p4, name:'苹果端'} + ] + } + ] + }; + myChart.setOption(option); + }else{ + WST.msg('没有查询到记录'); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_user_login.html b/hyhproject/admin/view/reports/stat_user_login.html new file mode 100755 index 0000000..a6d0db8 --- /dev/null +++ b/hyhproject/admin/view/reports/stat_user_login.html @@ -0,0 +1,14 @@ +{extend name="base" /} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/stat_user_login.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" placeholder='开始日期' id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}'/> +至 +<input type="text" placeholder='结束日期' id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}'/> +<button class="btn btn-primary" onclick='javascript:loadStat()'><i class='fa fa-search'></i>查询</button> +</div> +<div id="main" style='width:100%;height:99%;'></div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/stat_user_login.js b/hyhproject/admin/view/reports/stat_user_login.js new file mode 100755 index 0000000..9b3b1bf --- /dev/null +++ b/hyhproject/admin/view/reports/stat_user_login.js @@ -0,0 +1,63 @@ +$(function(){ + var h = WST.pageHeight(); + $('#main').height(h-50); + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + loadStat(); +}); +function loadStat(){ + var loading = WST.msg('正在查询数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/reports/statUserLogin'),WST.getParams('.ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + if(json.status=='1'){ + var option = { + tooltip: { + trigger: 'axis' + }, + legend: { + data:['会员','店铺'] + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: json.data.days + }, + yAxis: { + type: 'value' + }, + series: [ + { + name:'会员', + type:'line', + data:json.data.u0 + }, + { + name:'店铺', + type:'line', + data:json.data.u1 + } + ] + }; + + myChart.setOption(option); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/top_sale_goods.html b/hyhproject/admin/view/reports/top_sale_goods.html new file mode 100755 index 0000000..ccca16f --- /dev/null +++ b/hyhproject/admin/view/reports/top_sale_goods.html @@ -0,0 +1,41 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/top_sale_goods.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='ipt'/> +<input type="text" name="goodsName" placeholder='商品名称' id="goodsName" class='ipt'/> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +function toExport(){ + var params = {}; + params = WST.getParams('.ipt'); + params.goodsCatIdPath = WST.ITGetAllGoodsCatVals('cat_0','pgoodsCats').join('_'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/reports/toExportGoods',params); + }}); +} +$(function(){initSaleGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/top_sale_goods.js b/hyhproject/admin/view/reports/top_sale_goods.js new file mode 100755 index 0000000..43214a4 --- /dev/null +++ b/hyhproject/admin/view/reports/top_sale_goods.js @@ -0,0 +1,47 @@ +var mmg; +function initSaleGrid(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'goodsName', width: 30, renderer: function(val,item,rowIndex){ + var thumb = item['goodsImg']; + // thumb = thumb.replace('.','_thumb.'); + thumb = thumb+'?x-oss-process=image/resize,w_60,h_60'; + return "<span class='weixin'><a target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+thumb + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['goodsImg']+"'></span></span>"; + }}, + {title:'商品名称', name:'goodsName', width: 150}, + {title:'商品编号', name:'goodsSn', width: 80}, + {title:'所属店铺', name:'shopName', width: 150}, + {title:'订单总数', name:'orderNum', width: 80}, + {title:'浏览总数', name:'pageNum', width: 80}, + {title:'销量总数', name:'goodsNum' , width: 20}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><i class='fa fa-search'></i>查看</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/reports/topSaleGoodsByPage',WST.getParams('.ipt')), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.ipt'); + params.goodsCatIdPath = WST.ITGetAllGoodsCatVals('cat_0','pgoodsCats').join('_'); + params.page = 1; + mmg.load(params); +} +function toolTip(){ + WST.toolTip(); +} diff --git a/hyhproject/admin/view/reports/top_sale_shop.html b/hyhproject/admin/view/reports/top_sale_shop.html new file mode 100755 index 0000000..14c3f96 --- /dev/null +++ b/hyhproject/admin/view/reports/top_sale_shop.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/reports/top_sale_shop.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='ipt'/> +<input type="text" id="startDate" name="startDate" class="laydate-icon ipt" maxLength="20" value='{$startDate}' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon ipt" maxLength="20" value='{$endDate}' placeholder='结束日期'/> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + function toExport(){ + var params = {}; + params = WST.getParams('.ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/reports/toExportShop',params); + }}); +} +$(function(){initSaleGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/reports/top_sale_shop.js b/hyhproject/admin/view/reports/top_sale_shop.js new file mode 100755 index 0000000..3a48012 --- /dev/null +++ b/hyhproject/admin/view/reports/top_sale_shop.js @@ -0,0 +1,46 @@ +var mmg; +function initSaleGrid(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' +}); + var h = WST.pageHeight(); + var cols = [ + {title:'&nbsp;', name:'shopImg', width: 30, renderer:function(val,item,rowIndex){ + return "<span class='weixin'><a target='_blank' href='"+WST.U("home/goods/detail","id="+item['goodsId'])+"'><img id='img' onmouseout='toolTip()' onmouseover='toolTip()' style='height:60px;width:60px;' src='"+WST.conf.IMGURL+"/"+item['shopImg'] + +"'><span class='imged' ><img style='height:180px;width:180px;' src='"+WST.conf.IMGURL+"/"+item['shopImg']+"'></span></span>"; + }}, + {title:'店铺ID', name:'shopId', width: 30}, + {title:'店铺', name:'shopName', width: 130}, + {title:'结算所得ECT', name:'ectNum', width: 130,renderer:function(val,item,rowIndex){ + if(item['ectNum']==null){ + return "0.00000"; + }else{ + return item['ectNum']; + } + }}, + {title:'销售额', name:'totalMoney', width: 130, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'在线支付总金额', name:'onLinePayMoney', width: 130, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'在线支付实际收入', name:'onLinePayTrueMoney', width: 130, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'货到付款实际收入', name:'offLinePayMoney', width: 130, renderer:function(val,item,rowIndex){return '¥'+val;}}, + {title:'订单数', name:'orderNum', width: 50}, + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/reports/topShopSalesByPage',WST.getParams('.ipt')), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.ipt'); + params.page = 1; + mmg.load(params); +} +function toolTip(){ + WST.toolTip(); +} diff --git a/hyhproject/admin/view/roles/edit.html b/hyhproject/admin/view/roles/edit.html new file mode 100755 index 0000000..608c20d --- /dev/null +++ b/hyhproject/admin/view/roles/edit.html @@ -0,0 +1,57 @@ +{extend name="base" /} +{block name="css"} +<link href="__ADMIN__/js/ztree/css/zTreeStyle/zTreeStyle.css?v={$v}" rel="stylesheet" type="text/css" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/ztree/jquery.ztree.all-3.5.js?v={$v}"></script> +<script src="__ADMIN__/roles/roles.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form autocomplete='off'> +<input type='hidden' id='roleId' class='ipt' value="{$object['roleId']}"/> +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>角色名称<font color='red'>*</font></th> + <td><input type="text" id='roleName' class='ipt' value="{$object['roleName']}" maxLength='20' data-rule="角色名称: required;"/></td> + </tr> + <tr> + <th>角色备注</th> + <td><input type="text" id='roleDesc' class='ipt' value="{$object['roleDesc']}" style='width:70%' maxLength='100'/></td> + </tr> + <tr> + <th valign='top'>权限</th> + <td> + <ul id="menuTree" class="ztree"></ul> + </td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <button type="button" onclick='javascript:save()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="button" onclick='javascript:history.go(-1)' class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +var zTree,rolePrivileges = '{$object['privileges']}'.split(','); +$(function(){ + var roleId = $('#roleId').val(); + var setting = { + check: { + enable: true + }, + async: { + enable: true, + url:WST.U('admin/privileges/listQueryByRole'), + autoParam:["id", "name=n", "level=lv"], + otherParam:["roleId",roleId] + }, + callback:{ + onNodeCreated:getNodes + } + }; + $.fn.zTree.init($("#menuTree"), setting); + zTree = $.fn.zTree.getZTreeObj("menuTree"); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/roles/list.html b/hyhproject/admin/view/roles/list.html new file mode 100755 index 0000000..6d9d196 --- /dev/null +++ b/hyhproject/admin/view/roles/list.html @@ -0,0 +1,29 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/roles/roles.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于设置角色对应的权限。若职员拥有什么角色,则自动该角色下的所有权限。</li> + </ul> +</div> +{if WSTGrant('JSGL_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + <div style='clear:both'></div> +</div> +{/if} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/roles/roles.js b/hyhproject/admin/view/roles/roles.js new file mode 100755 index 0000000..321f476 --- /dev/null +++ b/hyhproject/admin/view/roles/roles.js @@ -0,0 +1,71 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'角色名称', name:'roleName', width: 30}, + {title:'角色备注', name:'roleDesc' }, + {title:'操作', name:'' ,width:140, lockWidth:true,align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.JSGL_02)h += "<a class='btn btn-blue' onclick='javascript:toEdit(" + item['roleId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.JSGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['roleId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-153),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/roles/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?153:125; + mmg.resize({height:h-diff}) + }}); +} +function toEdit(id){ + location.href=WST.U('admin/roles/toEdit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该角色吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/roles/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function getNodes(event, treeId, treeNode){ + zTree.expandNode(treeNode,true, true, true); + if($.inArray(treeNode.privilegeCode,rolePrivileges)>-1){ + zTree.checkNode(treeNode,true,true); + } +} +function save(){ + if(!$('#roleName').isValid())return; + var nodes = zTree.getChangeCheckedNodes(); + var privileges = []; + for(var i=0;i<nodes.length;i++){ + if(nodes[i].isParent==0)privileges.push(nodes[i].privilegeCode); + } + var params = WST.getParams('.ipt'); + params.privileges = privileges.join(','); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/roles/'+((params.roleId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('admin/roles/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} diff --git a/hyhproject/admin/view/settlements/edit.html b/hyhproject/admin/view/settlements/edit.html new file mode 100755 index 0000000..c6d11bb --- /dev/null +++ b/hyhproject/admin/view/settlements/edit.html @@ -0,0 +1,116 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/settlements/shopsettlements.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">结算详情</li> + <li >结算商品列表</li> + </ul> + <div class="layui-tab-content" > + <div class="layui-tab-item layui-show"> + <form autocomplete='off'> + <input type='hidden' id='settlementId' class='ipt' value="{$object['settlementId']}"/> + <table class='wst-form wst-box-top'> + + <tr> + <td colspan='2' class='head-ititle'>结算信息</td> + </tr> + <tr> + <th>店铺:</th> + <td>{$object['shopName']}</td> + </tr> + <tr> + <th width='150'>申请单号:</th> + <td> + {$object['settlementNo']} + </td> + </tr> + <tr> + <th>结算金额:</th> + <td>¥{$object['settlementMoney']}</td> + </tr> + <tr> + <th>结算佣金:</th> + <td>¥{$object['commissionFee']}</td> + </tr> + <tr> + <th>返还金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <td align='center' colspan='2'> + <div class='mmGrid'> + <table class='mmg-head wst-grid-tree' width="100%" cellspacing="0" cellpadding="0"> + <thead class='mmg-headWrapper'> + <tr height='28' class='mmg-head wst-grid-tree-hd'> + <th class='wst-grid-tree-hd-cell' style='width:35px;text-align:center;font-weight:bold;'>#</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>订单号</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>支付方式</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>商品金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>运费</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>订单总金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>积分抵扣</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>实付金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>佣金</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>下单时间</th> + </tr> + </thead> + {volist name='$object["list"]' id='vo'} + <tr class='mmg-body wst-grid-tree-row' height='28' {if $vo['payType']==0}style='background:#eeeeee;'{/if}> + <td class='wst-grid-tree-row-cell' align="center">{$key+1}</td> + <td class='wst-grid-tree-row-cell'>{$vo['orderNo']}</td> + <td class='wst-grid-tree-row-cell'>{:WSTLangPayType($vo['payType'])}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['goodsMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['deliverMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['totalMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['scoreMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['realTotalMoney']}</td> + <td class='wst-grid-tree-row-cell' style='background:#ffffff;'>¥{$vo['commissionFee']}</td> + <td class='wst-grid-tree-row-cell'>{$vo['createTime']}</td> + </tr> + {/volist} + </table> + </div> + </td> + </tr> + <tr > + <th valign='top'>结算备注:<br/>(店铺可见)&nbsp;&nbsp;</th> + <td> + <textarea id='remarks' class='ipt' style='width:70%;height:80px;'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type='button' class="btn btn-primary" onclick='javascript:save()'><i class="fa fa-check-circle"></i>提交</button> + <button type='button' class="btn" onclick='javascript:history.go(-1)'><i class="fa fa-check-circle"></i>返回</button> + </td> + </tr> + </table> + </form> + </div> + <div class="layui-tab-item"> + <table id="mmg" class="mmg"> + <tr> + <th rowspan="" colspan=""></th> + </tr> + </table> + <div id="pg" style="text-align: right;"></div> + </div> +</div> +</div> +<script> +$(function(){ + intView('{$object["settlementId"]}'); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/list.html b/hyhproject/admin/view/settlements/list.html new file mode 100755 index 0000000..d4cfd59 --- /dev/null +++ b/hyhproject/admin/view/settlements/list.html @@ -0,0 +1,38 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/settlements/shopsettlements.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于处理来自于商家订单的结算申请,结算时不管在线支付和货到付款都会先收取订单佣金,然后再返还在线支付的结算款。</li> + <li>订单结算款会返还到商家在本系统中的商家钱包中</li> + </ul> +</div> +<div class="wst-toolbar"> +<input type="text" name="settlementNo" placeholder='结算单号' id="settlementNo" class='j-ipt'/> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt'/> +<select id='settlementStatus' class='j-ipt'> + <option value='-1'>全部</option> + <option value='0'>未结算</option> + <option value='1'>已结算</option> +</select> +<button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +<button class="btn btn-primary f-right btn-fixtop" onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/list_order.html b/hyhproject/admin/view/settlements/list_order.html new file mode 100755 index 0000000..6d3cc65 --- /dev/null +++ b/hyhproject/admin/view/settlements/list_order.html @@ -0,0 +1,31 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/settlements/settlements.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type='hidden' id='id' value='{$id}'/> +<input type="text" name="orderNo" placeholder='订单号' id="orderNo" class='j-ipt'/> +<select id='payType' class='j-ipt'> + <option value='-1'>支付方式</option> + <option value='1'>在线支付</option> + <option value='0'>货到付款</option> + </select> +<button class="btn btn-primary btn-mright" type='button' onclick='javascript:loadOrderGrid()'><i class='fa fa-search'></i>查询</button> +<button class="btn f-right" type='button' onclick='javascript:location.href="{:Url('admin/settlements/toShopIndex')}"'><i class="fa fa-angle-double-left"></i>返回</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initOrderGrid('{$id}'); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/list_shop.html b/hyhproject/admin/view/settlements/list_shop.html new file mode 100755 index 0000000..b9c76ce --- /dev/null +++ b/hyhproject/admin/view/settlements/list_shop.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/settlements/settlements.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于按商家进行批量结算。结算时不需要商家申请,管理员点击“生成结算单”则自动完成订单的佣金结算和在线支付订单返款。</li> + <li>订单结算款会返还到商家在本系统中的商家钱包中</li> + </ul> +</div> +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" name="shopName" placeholder='店铺名称/店铺编号' id="shopName" class='j-ipt'/> +<button class="btn btn-primary" type='button' onclick='javascript:loadShopGrid()'><i class='fa fa-search'></i>查询</button> +{if WSTGrant('SJJS_04')} +<button class="btn btn-success" type='button' onclick='javascript:generateSettleByShop()'><i class="fa fa-check-circle"></i>生成结算单</button> +{/if} +<div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){ + initGrid(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/settlements.js b/hyhproject/admin/view/settlements/settlements.js new file mode 100755 index 0000000..e806366 --- /dev/null +++ b/hyhproject/admin/view/settlements/settlements.js @@ -0,0 +1,107 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺编号', name:'shopSn', width: 130}, + {title:'店铺名称', name:'shopName' ,width:100}, + {title:'店主姓名', name:'shopkeeper', width: 130}, + {title:'店主联系电话', name:'telephone' ,width:100}, + {title:'待结算订单数', name:'noSettledOrderNum' ,width:60}, + {title:'待结算佣金', name:'noSettledOrderFee' ,width:40, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'操作', name:'' ,width:120, align:'center', renderer: function(val,item,rowIndex){ + var h = "<span id='s_"+item['shopId']+"' dataval='"+item['shopName']+"'></span><a href='javascript:toView(" + item['shopId'] + ")'>订单列表</a>&nbsp;&nbsp;"; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, indexColWidth:50,cols: cols,method:'POST',checkCol:true,multiSelect:true, + url: WST.U('admin/settlements/pageShopQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); +} +function toView(id){ + location.href=WST.U('admin/settlements/toOrders','id='+id); +} +function initOrderGrid(id){ + var h = WST.pageHeight(); + var cols = [ + {title:'订单号', name:'orderNo', width: 130}, + {title:'支付方式', name:'payTypeName' ,width:100}, + {title:'商品金额', name:'goodsMoney', width: 130}, + {title:'运费', name:'deliverMoney' ,width:100, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'订单总金额', name:'totalMoney' ,width:60, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'实付金额', name:'realTotalMoney' ,width:40, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'佣金', name:'commissionFee' ,width:40, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'下单时间', name:'createTime' ,width:120, align:'center'} + ]; + + mmg = $('.mmg').mmGrid({height: h-95,indexCol: true, indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/settlements/pageShopOrderQuery','id='+id), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadShopGrid(){ + var areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + mmg.load({page:1,shopName:$('#shopName').val(),areaIdPath:areaIdPath}); +} +function loadOrderGrid(){ + var id = $('#id').val(); + mmg.load({page:1,orderNo:$('#orderNo').val(),payType:$('#payType').val(),id:id}); +} +var generateNo = 0; +var shops = []; +function generateSettle(){ + var shopId = shops[generateNo]; + var shopName = $('#s_'+shopId).attr('dataval'); + var load = WST.msg('正在生成【'+shopName+'】结算单,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/settlements/generateSettleByShop'),{id:shopId},function(data,textStatus){ + layer.close(load); + var json = WST.toAdminJson(data); + if(json.status==1){ + if(generateNo<(shops.length-1)){ + generateNo++; + generateSettle(); + }else{ + WST.msg(json.msg,{icon:1}); + loadShopGrid(); + } + }else{ + WST.msg(json.msg,{icon:2}); + loadShopGrid(); + } + }); +} +function generateSettleByShop(){ + var rows = mmg.selectedRows(); + if(rows.length==0){ + WST.msg('请选择要结算的商家!',{icon:2}); + return; + } + var ids = []; + for(var i=0;i<rows.length;i++){ + ids.push(rows[i]['shopId']); + } + shops = ids; + WST.confirm({content:'您确定生成选中商家的结算单吗?',yes:function(){ + generateNo = 0; + generateSettle(); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/shopsettlements.js b/hyhproject/admin/view/settlements/shopsettlements.js new file mode 100755 index 0000000..59a7265 --- /dev/null +++ b/hyhproject/admin/view/settlements/shopsettlements.js @@ -0,0 +1,116 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'结算单号', name:'settlementNo', width: 130,sortable:true}, + {title:'申请店铺', name:'shopName' ,width:100,sortable:true}, + {title:'结算金额', name:'settlementMoney' ,width:100,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'结算佣金', name:'commissionFee' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'店铺扣除质保金', name:'cashDeposit' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + if(val==null) val=0 + return '¥'+val; + }}, + {title:'返还金额', name:'backMoney' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'支付方式', name:'payName',width:60,sortable:true}, + {title:'申请时间', name:'createTime',sortable:true}, + {title:'状态', name:'settlementStatus' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 已结算&nbsp;</span>":"<span class='statu-yes'><i class='fa fa-check-circle'></i> 未结算&nbsp;</span>"; + }}, + {title:'操作', name:'' ,width:120, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toView(" + item['settlementId'] + ")'><i class='fa fa-search'></i>查看</a>&nbsp;&nbsp;"; + if(item['settlementStatus']==0 && WST.GRANT.JSSQ_04)h += "<a class='btn btn-primary' href='javascript:toEdit(" + item['settlementId'] + ")'>处理</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/settlements/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?173:128; + mmg.resize({height:h-diff}) + }}); +} +function toEdit(id){ + location.href=WST.U('admin/settlements/toHandle','id='+id); +} +function toView(id){ + location.href=WST.U('admin/settlements/toView','id='+id); +} +function loadGrid(){ + mmg.load({page:1,settlementNo:$('#settlementNo').val(),settlementStatus:$('#settlementStatus').val(),shopName:$('#shopName').val()}); +} + +function save(){ + if(WST.confirm({content:'您确定提交该结算单吗?',yes:function(){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/settlements/handle'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('admin/settlements/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }})); +} +var flag = false; +function intView(id){ + var h = WST.pageHeight(); + var element = layui.element; + var isInit = false; + element.on('tab(msgTab)', function(data){ + if(data.index==1){ + if(!isInit){ + isInit = true; + initGoodsGrid(id); + } + } + }); +} +function initGoodsGrid(id){ + var h = WST.pageHeight(); + var cols = [ + {title:'订单号', name:'orderNo', width: 60}, + {title:'商品名称', name:'goodsName' ,width:200}, + {title:'商品规格', name:'goodsSpecNames',width:200, renderer:function(val,item,rowIndex){ + if(WST.blank(val)!=''){ + val = val.split('@@_@@'); + return val.join(','); + } + }}, + {title:'商品价格', name:'goodsPrice' ,width:30, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'购买数量', name:'goodsNum' ,width:20}, + {title:'佣金比率', name:'commissionRate',width:20} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/settlements/pageGoodsQuery','id='+id), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出结算记录吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/settlements/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/settlements/view.html b/hyhproject/admin/view/settlements/view.html new file mode 100755 index 0000000..8345685 --- /dev/null +++ b/hyhproject/admin/view/settlements/view.html @@ -0,0 +1,113 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/settlements/shopsettlements.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">结算详情</li> + <li >结算商品列表</li> + </ul> + <div class="layui-tab-content" style='padding:0px'> + <div class="layui-tab-item layui-show"> + <form autocomplete='off'> + <input type='hidden' id='settlementId' class='ipt' value="{$object['settlementId']}"/> + <table class='wst-form wst-box-top'> + <tr> + <th height='25'>店铺:</th> + <td>{$object['shopName']}</td> + </tr> + <tr> + <th width='150'>申请单号:</th> + <td height='25'> + {$object['settlementNo']} + </td> + </tr> + <tr> + <th height='25'>结算金额:</th> + <td>¥{$object['settlementMoney']}</td> + </tr> + <tr> + <th height='25'>结算佣金:</th> + <td>¥{$object['commissionFee']}</td> + </tr> +<!-- <tr> + <th height='25'>店铺扣除质保金:</th> + <td></td> + </tr> --> + <tr> + <th height='25'>返还金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th height='25'>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <td align='center' colspan='2'> + <div class='mmGrid'> + <table class='mmg-head wst-grid-tree' width="100%" cellspacing="0" cellpadding="0"> + <thead class='mmg-headWrapper'> + <tr height='28' class='mmg-head wst-grid-tree-hd'> + <th class='wst-grid-tree-hd-cell' style='width:35px;text-align:center;font-weight:bold;'>#</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>订单号</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>支付方式</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>商品金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>运费</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>订单总金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>积分抵扣</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>实付金额</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>佣金</th> + <th class='wst-grid-tree-hd-cell' style='text-align:left;font-weight:bold;'>下单时间</th> + </tr> + </thead> + {volist name='$object["list"]' id='vo'} + <tr class='mmg-body wst-grid-tree-row' height='28' {if $vo['payType']==0}style='background:#eeeeee;'{/if}> + <td class='wst-grid-tree-row-cell' align="center">{$key+1}</td> + <td class='wst-grid-tree-row-cell'>{$vo['orderNo']}</td> + <td class='wst-grid-tree-row-cell'>{:WSTLangPayType($vo['payType'])}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['goodsMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['deliverMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['totalMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['scoreMoney']}</td> + <td class='wst-grid-tree-row-cell'>¥{$vo['realTotalMoney']}</td> + <td class='wst-grid-tree-row-cell' style='background:#ffffff;'>¥{$vo['commissionFee']}</td> + <td class='wst-grid-tree-row-cell'>{$vo['createTime']}</td> + </tr> + {/volist} + </table> + </div> + </td> + </tr> + <tr > + <th valign='top'>结算备注:<br/>(店铺可见)&nbsp;&nbsp;</th> + <td>{$object['remarks']}</td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + </table> + </form> + </div> + <div class="layui-tab-item"> + <table id="mmg" class="mmg"> + <tr> + <th rowspan="" colspan=""></th> + </tr> + </table> + <div id="pg" style="text-align: right;"></div> + </div> + </div> +</div> +<script> +$(function(){ + intView('{$object["settlementId"]}'); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/add.html b/hyhproject/admin/view/shops/add.html new file mode 100755 index 0000000..7c3a012 --- /dev/null +++ b/hyhproject/admin/view/shops/add.html @@ -0,0 +1,455 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>新增类型<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isNew' id='isNew1' value='1' onclick='javascript:WST.showHide(1,".newUserTr1");WST.showHide(0,"#newUserTr0")' checked title='新账号'> + </label> + <label> + <input type='radio' class='ipt' name='isNew' value='0' onclick='javascript:WST.showHide(0,".newUserTr1");WST.showHide(1,"#newUserTr0")' title='已有账号'> + </label> + </td> + </tr> + <tr id='newUserTr0' style='display:none'> + <th width='150' valign="top">请输入用户账号<font color='red'>*</font>:</th> + <td> + <input type="text" id='keyName' name='keyName' class='ipt' placeholder='请输入用户账号/手机'/> + <input type='button' value='查询' class='btn btn-primary' onclick='javascript:getUserByKey()'> + <div id='keyNameBox' style='height:30px;line-height:30px'></div> + <input type='hidden' class='ipt' id='shopUserId' value='0'/> + </td> + </tr> + <tr class='newUserTr1'> + <th width='150'>登录账号<font color='red'>*</font>:</th> + <td><input type="text" id='loginName' name='loginName' class='ipt' value=" " maxLength='20' data-rule="登录账号: required(#isNew1:checked);length[6~20];remote(post:{:url('admin/users/checkLoginKey')})" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr class='newUserTr1'> + <th>登录密码<font color='red'>*</font>:</th> + <td><input type="password" id='loginPwd' class='ipt' maxLength='20' value='88888888' data-rule="登录密码: required(#isNew1:checked);length[6~20];" data-target="#msg_loginPwd"/> + <span class='msg-box' id='msg_loginPwd'>(默认为88888888)</span> + </td> + </tr> + <tr> + <th width='150'>店铺编号<font color='red'>*</font>:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:ignoreBlank;length[1~20];remote(post:{:url('admin/shops/checkShopSn')})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>(为空则自动生成'S000000001'类型号码)</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='100' data-rule="公司名称: required;"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' /> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' /> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' /> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' /> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营类目:checked"{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}'/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div><span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + <img id='preview' width='150' height='150' src="__IMGURL__/{:WSTConf('CONF.shopLogo')}"/> + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' maxLength='200'/><span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span></td> + + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' maxLength='200'/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' onclick='javascript:WST.showHide(1,"#trInvoice")' title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' onclick='javascript:WST.showHide(0,"#trInvoice")' checked title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' style='display:none'> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' checked title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费(元)<font color='red'>*</font>:</th> + <td><input type="text" id='freight' class='ipt' maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' value='0' onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>入驻商联系人信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt'/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' data-rule="mobile" id='applyLinkTel'/> + </td> + </tr> + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' data-rule="email" class='ipt' id='applyLinkEmail'/> + </td> + </tr> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' style='display:none'> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>公司信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt'/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt'/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px'/> + </td> + </tr> + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon'/> + </td> + </tr> + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='businessEndDate' readonly class='ipt laydate-icon' /> + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" /> + </td> + </tr> + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'></textarea> + </td> + </tr> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt'/> + </td> + </tr> + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='legalCertificateEndDate' readonly class='ipt laydate-icon' />&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <img id='legalCertificateImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <img id='businessLicenceImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' /> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <img id='bankAccountPermitImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> +</table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>商标注册证</legend> + <table class='wst-form wst-box-top'> + <tr> + <th>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt'/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='organizationCodeEndDate' readonly class='ipt laydate-icon'/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th valign="top">商标注册证电子版:</th> + <td> + <span style='color:gray;'>复印件需加盖公司红章扫描上传,三证合一的此处请上传营业执照电子版</span><br/> + <input type='hidden' id='organizationCodeImg' class='ipt'/> + <div id='organizationCodeImgPicker'>请上传商标注册证电子版</div> + <span id='organizationCodeImgMsg'></span> + <img id='organizationCodeImgPreview' src='' style='display:none' width='150'> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>税务信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' /> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'></span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <img id='taxpayerQualificationImgPreview' src='' style='display:none' width='150'> + </td> + </tr> +</table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>结算账号信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='ipt' maxlength='50' data-rule='银行开户名:required;'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}">{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright b' onclick='javascript:add()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script> +$(function(){initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'',bankAreaId:'',bankAreaIdPath:'',isEdit:false});}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/apply_edit.html b/hyhproject/admin/view/shops/apply_edit.html new file mode 100755 index 0000000..864097d --- /dev/null +++ b/hyhproject/admin/view/shops/apply_edit.html @@ -0,0 +1,152 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +.apply-img{text-align: center;} +.apply-img img{max-width: 50%} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> +<input type='hidden' id='userId' class='ipt' value="{$object['userId']}"/> + <tr> + <th width='150'>申请会员:</th> + <td height='23'>{$object['user']['loginName']}</td> + </tr> + <tr> + <th width='150'>实名名称:</th> + <td height='23'>{$object['user']['trueName']}</td> + </tr> + <tr> + <th width='150'>申请时间:</th> + <td height='23'>{$object['applyTime']}</td> + </tr> + + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;" value="{$object['shopName']}"/></td> + </tr> + <tr> + <th width='150'>直营人姓名<font color='red'>*</font>:</th> + <td><input type="text" id='userName' class='ipt' maxLength='100' data-rule="直营人姓名: required;" value="{$object['userName']}"/></td> + </tr> + <tr> + <th width='150'>联系电话</th> + <td><input type="text" id='phone' class='ipt' maxLength='100' data-rule="联系电话: required;" value="{$object['phone']}"/></td> + </tr> + <tr> + <th>店铺所在地<font color='red'>*</font>:</th> + <td height='23'>{$object['area']}</td> + </td> + </tr> + <tr> + <th>店铺详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='店铺详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>开户行<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankName' class='ipt' data-rule='开户行:required;' value="{$object['bankName']}"/> + </td> + </tr> + <tr> + <th>开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='accountName' class='ipt' data-rule='开户名:required;' value="{$object['accountName']}"/> + </td> + </tr> + <tr> + <th>银行卡号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' data-rule='银行卡号:required;' value="{$object['bankNo']}"/> + </td> + </tr> + </table> +</fieldset> + +<fieldset class="layui-elem-field layui-field-title apply-img"> +<legend><b>照片信息</b></legend> + +<fieldset class="layui-elem-field"> + <legend>身份证正面</legend> + <div class="layui-field-box"> + <img id='idCardFrontImg' src='__IMGURL__/{$object['idCardFrontImg']}'> + </div> +</fieldset> +<fieldset class="layui-elem-field"> + <legend>身份证反面</legend> + <div class="layui-field-box"> + <img id='idCardBackImg' src='__IMGURL__/{$object['idCardBackImg']}'> + </div> +</fieldset> +<fieldset class="layui-elem-field"> + <legend>直营人委托书</legend> + <div class="layui-field-box"> + <img id='commissionImg' src='__IMGURL__/{$object['commissionImg']}'> + </div> +</fieldset> +<fieldset class="layui-elem-field"> + <legend>手持身份证和营业执照</legend> + <div class="layui-field-box"> + <img id='businessLicenceImg' src='__IMGURL__/{$object['businessLicenceImg']}'> + </div> +</fieldset> +<fieldset class="layui-elem-field"> + <legend>手持确认书照:</legend> + <div class="layui-field-box"> + <img id='confirmationImg' src='__IMGURL__/{$object['confirmationImg']}'> + </div> +</fieldset> +</fieldset> + +<fieldset class="layui-elem-field layui-field-title"> +<legend>申请状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>处理结果<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='status' id='status2' value='1' {if $object['status']==1}checked{/if} onclick='javascript:WST.showHide(1,".deposit");WST.showHide(0,"#trApplyDesc")' data-rule="处理结果:checked" title='通过'> + </label> + <label> + <input type='radio' class='ipt' name='status' id='status-1' value='2' {if $object['status']==2}checked{/if} onclick='javascript:WST.showHide(1,"#trApplyDesc");WST.showHide(0,".deposit")' title='不通过'> + </label> + </td> + </tr> + + + <tr id='trApplyDesc' style='display:none'> + <th>不通过原因<font color='red'>*</font>:</th> + <td><textarea id='applyDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="不通过原因:required(#status-1:checked);">{$object['applyDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:apply()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> + +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/apply_edit2.html b/hyhproject/admin/view/shops/apply_edit2.html new file mode 100755 index 0000000..52f9626 --- /dev/null +++ b/hyhproject/admin/view/shops/apply_edit2.html @@ -0,0 +1,625 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>申请会员:</th> + <td height='23'>{$object['loginName']}</td> + </tr> + <tr> + <th width='150'>申请时间:</th> + <td height='23'>{$object['applyTime']}</td> + </tr> + <tr> + <th width='150'>店铺编号:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:ignoreBlank;length[1~20];remote(post:{:url('admin/shops/checkShopSn','shopId='.$object['shopId'])})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>(为空则自动生成'S000000001'类型号码)</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;" value="{$object['shopName']}"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='100' data-rule="公司名称: required;" value="{$object['shopCompany']}"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' value="{$object['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' value="{$object['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$object['telephone']}"/> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' onclick="divShow()" class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1} data-rule="经营类目:checked"{/if} {if array_key_exists($vo['catId'],$object['catshops'])}checked{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th >食品许可证</th> + <td > + <input type='hidden' id='shopLicense' class='ipt' value='{$shoplicense["shopLicense"]}'/> + <div id='shopLicenseImgPicker'>请上传食品许可证电子版</div> + <span id='shopLicenseImgMsg'></span> + <a id='shopLicenseImgPreview_a' href='__IMGURL__/{$shoplicense["shopLicense"]}' target='_blank'> + <img id='shopLicenseImgPreview' src='__IMGURL__/{$shoplicense["shopLicense"]}' {if $shoplicense['shopLicense']==''} style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}'/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div> + <span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + <img id='preview' width='150' height='150' src="__IMGURL__/{$object['shopImg']}"/> + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' maxLength='200' value="{$object['shopQQ']}"/></td> + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' maxLength='200' value="{$object['shopWangWang']}"/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' onclick='javascript:WST.showHide(1,"#trInvoice")' {if $object['isInvoice']==1}checked{/if} title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' onclick='javascript:WST.showHide(0,"#trInvoice")' {if $object['isInvoice']==0}checked{/if} title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)" value="{$object['invoiceRemarks']}"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' {if $object['shopAtive']==1}checked{/if} title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' {if $object['shopAtive']==0}checked{/if} title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费(元):</th> + <td><input type="text" id='freight' class='ipt' maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)" value="{$object['freight']}"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>入驻联系人信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt' value="{$object['applyLinkMan']}"/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' id='applyLinkTel' data-rule="mobile" value="{$object['applyLinkTel']}"/> + </td> + </tr> + <!-- + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' class='ipt' data-rule="email" id='applyLinkEmail' value="{$object['applyLinkEmail']}"/> + </td> + </tr> + --> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $object['isInvestment']==1}checked{/if} title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $object['isInvestment']==0}checked{/if} title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' {if $object['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$object['investmentStaff']}"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>公司信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt' value="{$object['businessLicence']}"/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt' value="{$object['legalPersonName']}"/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <!-- + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px' value="{$object['licenseAddress']}"/> + </td> + </tr> + --> + <!-- + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon' value="{$object['establishmentDate']}"/> + </td> + </tr> +--> +<!-- + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' value="{$object['businessStartDate']}"/> - + <input type='text' id='businessEndDate' readonly class='ipt laydate-icon' value="{$object['businessEndDate']}" {if $object['isLongbusinessDate']==1}style='display:none'{/if}/> + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1' {if $object['isLongbusinessDate']==1}checked{/if}/>长期</label> + </td> + </tr> +--> +<!-- + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" value="{$object['registeredCapital']}"/> + </td> + </tr> +--> +<!-- + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'>{$object['empiricalRange']}</textarea> + </td> + </tr> +--> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt' value="{$object['legalCertificate']}"/> + </td> + </tr> + <!-- + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateStartDate']}"/> - + <input type='text' id='legalCertificateEndDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateEndDate']}" {if $object['isLonglegalCertificateDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1' {if $object['isLonglegalCertificateDate']==1}checked{/if}/>长期</label> + </td> + </tr> +--> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt' value='{$object['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <a id='legalCertificateImgPreview_a' href='__IMGURL__/{$object['legalCertificateImg']}' target='_blank'> + <img id='legalCertificateImgPreview' src='__IMGURL__/{$object['legalCertificateImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt' value='{$object['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <a id='businessLicenceImgPreview_a' href='__IMGURL__/{$object['businessLicenceImg']}' target='_blank'> + <img id='businessLicenceImgPreview' src='__IMGURL__/{$object['businessLicenceImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' value='{$object['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <a id='bankAccountPermitImgPreview_a' href='__IMGURL__/{$object['bankAccountPermitImg']}' target='_blank'> + <img id='bankAccountPermitImgPreview' src='__IMGURL__/{$object['bankAccountPermitImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th width='120' align='right'>补充材料<font color='red'>*</font>:</th> + <td> + <div id="batchUpload" class="ipt wst-batchupload" style="border:1px solid #ccc;width: 700px" > + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 其它相关资料请上传到补充材料(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="ipt placeholder {if !empty($object['auxiliary'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['auxiliary']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo.auxiliaryImg}"> + </p> + <input type="hidden" v="{$vo.auxiliaryImg}" iv="{$vo.auxiliaryImg}" class="ipt j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar"> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + <div style='clear:both;'></div> + </td> + </tr> + </table> +</fieldset> +<!-- <fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt' value="{$object['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeStartDate']}"/> - + <input type='text' id='organizationCodeEndDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeEndDate']}" {if $object['isLongOrganizationCodeDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1' {if $object['isLongOrganizationCodeDate']==1}checked{/if}/>长期</label> + </td> + </tr> + </table> +</fieldset> --> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th valign="top">商标注册证电子版:</th> + <td> + <span style='color:gray;'>请上传商标注册证或品牌授权证</span><br/> + <input type='hidden' id='organizationCodeImg' class='ipt' value='{$object['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证或品牌授权证</div> + <span id='organizationCodeImgMsg'></span> + <a id='organizationCodeImgPreview_a' href='__IMGURL__/{$object['organizationCodeImg']}' target='_blank'> + <img id='organizationCodeImgPreview' src='__IMGURL__/{$object['organizationCodeImg']}' width='150'> + </td> + </tr> + </table> +</fieldset> +<<!-- fieldset class="layui-elem-field layui-field-title"> +<legend>税务信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt' value='{$object["taxpayerNo"]}'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' value='{$object["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$object['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <a href='__IMGURL__/{$vo}' target='_blank'> + <img class="step_pic" width="75" height="75" src="__IMGURL__/{$vo}" v="{$vo}"> + </a> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt' value='{$object["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <a id='taxpayerQualificationImgPreview_a' href='__IMGURL__/{$object["taxpayerQualificationImg"]}' target='_blank'> + <img id='taxpayerQualificationImgPreview' src='__IMGURL__/{$object["taxpayerQualificationImg"]}' width='150'> + </a> + </td> + </tr> + </table> +</fieldset> --> +<fieldset class="layui-elem-field layui-field-title"> +<legend>结算账号信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='ipt' maxlength='50' data-rule='纳税人识别号:required;' value='{$object["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;' value='{$object["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <!-- + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> +--> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>申请状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>处理结果<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus2' value='2' {if $object['applyStatus']==2}checked{/if} onclick='javascript:WST.showHide(1,".deposit");WST.showHide(0,"#trApplyDesc")' data-rule="处理结果:checked" title='通过'> + </label> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus-1' value='-1' {if $object['applyStatus']==-1}checked{/if} onclick='javascript:WST.showHide(1,"#trApplyDesc");WST.showHide(0,".deposit")' title='不通过'> + </label> + </td> + </tr> + + <tr id='trDeposit' class="deposit" style='display:none'> + <th>应缴保证金<font color='red'>*</font>:</th> + <td> + <input type='text' name='payDeposit' id='payDeposit' class='ipt' value="{$cashDeposit['payDeposit']}"/> + </td> + </tr> + + <tr id='trPassDesc' class="deposit" style='display:none'> + <th>实缴保证金<font color='red'>*</font>:</th> + <td> + <input type='text' name='cashDeposit' id='cashDeposit' class='ipt' value="{$cashDeposit['cashDeposit']}"/> + </td> + </tr> + + + <tr id='trApplyDesc' style='display:none'> + <th>不通过原因<font color='red'>*</font>:</th> + <td><textarea id='applyDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="不通过原因:required(#applyStatus-1:checked);">{$object['applyDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:apply()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +<script type="text/javascript"> + $(function(){ + /********** 轮播广告图片上传 **********/ + var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shops'},uploadSuccess:function(file,response){ + var json = WST.toAdminJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" value="'+json.savePath+json.name+'" class="a-ipt j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + + function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); + } + }); +function divShow(){ +var checkboxText= new Array(); +var checkboxValue= new Array(); +var checkboxStr=document.getElementsByName("goodsCatIds"); + for(var i=0; i<checkboxStr.length; i++){ + if(checkboxStr[i].checked){ + //alert(checkboxStr[i].value+","+checkboxStr[i].nextSibling.nodeValue); + checkboxValue.push(checkboxStr[i].value); + checkboxText.push(checkboxStr[i].nextSibling.nodeValue.trim()); + } + } +var foot='393'; +if(checkboxValue.indexOf(foot)!="-1"){ + document.getElementById("license").style.cssText = "display: table-row;vertical-align: inherit;border-color: inherit;"; + }else{ + document.getElementById("license").style.cssText = "display:none" + } +} + + +</script> +<script> +$(function(){ + initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'{$object["areaIdPath"]}',bankAreaId:'{$object["bankAreaId"]}',bankAreaIdPath:'{$object["bankAreaIdPath"]}',businessAreaPath:'{$object["businessAreaPath"]}'}); + shopLicenseUpload (); +}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/deposit.html b/hyhproject/admin/view/shops/deposit.html new file mode 100755 index 0000000..e69712d --- /dev/null +++ b/hyhproject/admin/view/shops/deposit.html @@ -0,0 +1,93 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='topDeposit' autocomplete='off'> +<fieldset class="layui-elem-field layui-field-title"> +<table class='wst-form wst-box-top'> + <tr> + <th>请输入店铺ID:</th> + <td> + <input type='text' name="shopId" id='shopId' class='ipt' onblur="upperName()" style='width:200px'/> + </td> + </tr> + + <tr> + <th>店铺名称:</th> + <td> + <input type='text' name="shopName" id='shopName' class='ipt' value="" style='width:200px' /> + </td> + </tr> + + <tr> + <th>质保金管理<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus' value='1' onclick='javascript:WST.showHide(1,"#trPassDesc");WST.showHide(0,"#trApplyDesc");WST.showHide(0,"#offCause")' title='充值'> + </label> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus' value='2' onclick='javascript:WST.showHide(1,"#trApplyDesc");WST.showHide(1,"#offCause");WST.showHide(0,"#trPassDesc")' title='扣除'> + </label> + </td> + </tr> + + <tr id='trPassDesc' style='display:none'> + <th>充值保证金金额<font color='red'>*</font>:</th> + <td> + <input type='text' name='addDeposit' id='addDeposit' class='ipt' value=""/> + </td> + </tr> + <tr id='trApplyDesc' style='display:none'> + <th>扣除质保金金额<font color='red'>*</font>:</th> + <td> + <input type='text' name='offDeposit' id='offDeposit' class='ipt' value=""/> + </td> + </tr> + <tr id='offCause' style='display:none'> + <th>扣除质保金原因<font color='red'>*</font>:</th> + <td> + <textarea name="offCause" id='offCause' class='ipt' style='width:300px;height:100px;' maxLength='100' placeholder="格式如:您的店铺商品因出质量问题,现被扣除质保金,详情联系公司运营人员。电话:"></textarea> + + <!-- <input type='text' name='offCause' id='offCause' class='ipt' placeholder="如:您的店铺因未及时续约,现已被下架,详情联系公司运营人员。电话:010-60609086"/> --> + + </td> + </tr> + + <tr> + <td colspan='2' align='center'> + <input type="submit" value="提交" class='btn btn-blue' /> + <input type="button" onclick="javascript:history.go(-1)" class='btn' value="返回" /> + </td> + </tr> +</table> +</fieldset> +</form> +<script> + +function upperName(){ + var shopId = document.getElementById('shopId').value; + $.post(WST.U('admin/shops/upShopName'),{shopId:shopId},function(data){ + // alert(JSON.stringify(data)); + // $('#shopName').html(data['shopName']); + $('#shopName').val(data['shopName']); + } + , "json") +} + + +$(function() { + editInit() + }); + +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/detail.html b/hyhproject/admin/view/shops/detail.html new file mode 100755 index 0000000..1a16cdd --- /dev/null +++ b/hyhproject/admin/view/shops/detail.html @@ -0,0 +1,73 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<input type="text" id="startDate" name="startDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='开始日期'/> +至 +<input type="text" id="endDate" name="endDate" class="laydate-icon j-ipt" maxLength="20" value='' placeholder='结束日期'/> +<select name="nonTime" id="nonTime" class="query j-ipt" > + <option value="">请选择未登录天数</option> + <option value="20">20天未登录</option> + <option value="30">30天未登录</option> + <option value="40">40天未登录</option> + <option value="50">50天未登录</option> +</select> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + <button class="btn btn-primary btn-fixtop f-right" style="margin-left: 10px;" onclick='javascript:toExports()'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); +}) +function initDetailGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺名称', name:'shopName',width:100 }, + {title:'公司名称', name:'shopCompany',width:100 }, + {title:'注册时间', name:'applyTime',width:100 }, + {title:'联系人姓名', name:'shopkeeper',width:60 }, + {title:'联系人电话', name:'telephone',width:60 }, + {title:'未登录天数', name:'nonTime',width:30,align:'center' }, + {title:'登录频次', name:'loginNum',width:30,align:'center' }, + {title:'商品数量', name:'goodsNum',width:30,align:'center' }, + {title:'未付款订单', name:'nonpayOrder',width:10,align:'center' }, + {title:'交易成功', name:'successOrder',width:10,align:'center' }, + {title:'已取消订单', name:'cancelOrder',width:10,align:'center' }, + {title:'已发货订单', name:'deliveredOrder',width:30,align:'center' }, + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/detailByPage'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toExports(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/shops/toExports',params); + }}); +} +$(function(){initDetailGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/edit.html b/hyhproject/admin/view/shops/edit.html new file mode 100755 index 0000000..74e05fb --- /dev/null +++ b/hyhproject/admin/view/shops/edit.html @@ -0,0 +1,42 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">店铺信息</li> + <li>公司信息</li> + <li>税务及银行信息</li> + </ul> + <div class="layui-tab-content" style="padding: 10px 0;"> + <div class="layui-tab-item layui-show"> + {include file='shops/edit0'/} + </div> + <div class="layui-tab-item"> + {include file='shops/edit1'/} + </div> + <div class="layui-tab-item"> + {include file='shops/edit2'/} + </div> + </div> +</div> +</form> +<script> + +$(function(){initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'{$object["areaIdPath"]}',bankAreaId:'{$object["bankAreaId"]}',bankAreaIdPath:'{$object["bankAreaIdPath"]}',businessAreaPath:'{$object["businessAreaPath"]}',isEdit:true});}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/edit0.html b/hyhproject/admin/view/shops/edit0.html new file mode 100755 index 0000000..d8da618 --- /dev/null +++ b/hyhproject/admin/view/shops/edit0.html @@ -0,0 +1,212 @@ +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>店铺编号<font color='red'>*</font>:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:{if $object['shopId']>0}required;length[1~20];{else /}ignoreBlank;{/if}remote(post:{:url('admin/shops/checkShopSn',array('shopId'=>$object['shopId']))})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>{if $object['shopId']==0}(为空则自动生成'S000000001'类型号码){/if}</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' value="{$object['shopName']}" maxLength='20' data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='20' value="{$object['shopCompany']}" data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' value="{$object['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' value="{$object['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$object['telephone']}"/> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营类目:checked"{/if} {if array_key_exists($vo['catId'],$object['catshops'])}checked{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}' {if array_key_exists($vo['accredId'],$object['accreds'])}checked{/if}/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div><span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + {if $object["shopImg"]!=''} + <img id='preview' width='150' height='150' src='__IMGURL__/{$object["shopImg"]}'/> + {else} + <img id='preview' width='150' height='150' src="__IMGURL__/{:WSTConf('CONF.shopLogo')}"/> + {/if} + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' value="{$object['shopQQ']}" maxLength='200'/><span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span></td> + + </tr> + <tr> + <th>旺旺类型<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='0' class="ipt" name='shopWangWangType'{if $object['shopWangWangType']==0}checked{/if}/>淘宝旺旺 + </label> + <label> + <input type='radio' value='1' class="ipt" name='shopWangWangType'{if $object['shopWangWangType']==1}checked{/if}/>阿里旺旺 + </label> + + </td> + </tr> + <tr> + <th>旺旺号:</th> + <td><input type="text" id='shopWangWang' class='ipt' value="{$object['shopWangWang']}" maxLength='200'/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' {if $object['isInvoice']==1}checked{/if} onclick='javascript:WST.showHide(1,"#trInvoice")' title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' {if $object['isInvoice']==0}checked{/if} onclick='javascript:WST.showHide(0,"#trInvoice")' title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' value="{$object['invoiceRemarks']}" style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' {if $object['shopAtive']==1}checked{/if} title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' {if $object['shopAtive']==0}checked{/if} title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费:</th> + <td><input type="text" id='freight' class='ipt' value="{$object['freight']}" maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>入驻商联系人信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt' value="{$object['applyLinkMan']}"/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' id='applyLinkTel' data-rule="mobile" value="{$object['applyLinkTel']}"/> + </td> + </tr> + <!-- + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' class='ipt' data-rule="email" id='applyLinkEmail' value="{$object['applyLinkEmail']}"/> + </td> + </tr> + --> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $object['isInvestment']==1}checked{/if} title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $object['isInvestment']==0}checked{/if} title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' {if $object['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$object['investmentStaff']}"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>店铺状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>店铺状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopStatus' id='shopStatus-1' value='-1' {if $object['shopStatus']==-1}checked{/if} onclick='javascript:WST.showHide(1,"#trStatusDesc")' title='停止'> + </label> + <label> + <input type='radio' class='ipt' name='shopStatus' value='1' {if $object['shopStatus']==1}checked{/if} onclick='javascript:WST.showHide(0,"#trStatusDesc")' title='正常'> + </label> + </td> + </tr> + <tr id='trStatusDesc' {if $object['shopStatus']==1}style='display:none'{/if}> + <th>停止原因<font color='red'>*</font>:</th> + <td><textarea id='statusDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="停止原因:required(#shopStatus-1:checked);">{$object['statusDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> \ No newline at end of file diff --git a/hyhproject/admin/view/shops/edit1.html b/hyhproject/admin/view/shops/edit1.html new file mode 100755 index 0000000..b933952 --- /dev/null +++ b/hyhproject/admin/view/shops/edit1.html @@ -0,0 +1,257 @@ +<fieldset class="layui-elem-field layui-field-title"> +<legend>公司信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['businessLicenceType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt' value="{$object['businessLicence']}"/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt' value="{$object['legalPersonName']}"/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <!-- + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px' value="{$object['licenseAddress']}"/> + </td> + </tr> + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon' value="{$object['establishmentDate']}"/> + </td> + </tr> + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' value="{$object['businessStartDate']}"/> - + <input type='text' id='businessEndDate' {if $object['isLongbusinessDate']==1}style='display:none'{/if} readonly class='ipt laydate-icon' value="{$object['businessEndDate']}"/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1' {if $object['isLongbusinessDate']==1}checked{/if}/>长期</label> + </td> + </tr> + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" value="{$object['registeredCapital']}"/> + </td> + </tr> + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'>{$object['empiricalRange']}</textarea> + </td> + </tr> +--> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['legalCertificateType']==$vo['dataVal']}{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt' value="{$object['legalCertificate']}"/> + </td> + </tr> + <!-- + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateStartDate']}"/> - + <input type='text' id='legalCertificateEndDate' readonly value="{$object['legalCertificateEndDate']}" {if $object['isLonglegalCertificateDate']==1}style='display:none'{/if} class='ipt laydate-icon' />&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1' {if $object['isLonglegalCertificateDate']==1}checked{/if}/>长期</label> + + </td> + </tr> +--> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt' value='{$object['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <a id='legalCertificateImgPreview_a' href='__IMGURL__/{$object['legalCertificateImg']}' target='_blank'> + <img id='legalCertificateImgPreview' src='__IMGURL__/{$object["legalCertificateImg"]}' {if $object["legalCertificateImg"] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt' value='{$object['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <a id='businessLicenceImgPreview_a' href='__IMGURL__/{$object['businessLicenceImg']}' target='_blank'> + <img id='businessLicenceImgPreview' src='__IMGURL__/{$object['businessLicenceImg']}' {if $object['businessLicenceImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' value='{$object['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <a id='bankAccountPermitImgPreview_a' href='__IMGURL__/{$object['bankAccountPermitImg']}' target='_blank'> + <img id='bankAccountPermitImgPreview' src='__IMGURL__/{$object['bankAccountPermitImg']}' {if $object['bankAccountPermitImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th width='120' align='right'>补充材料:</th> + <td> + <div id="batchUpload" class="ipt wst-batchupload" style="border:1px solid #ccc;width: 700px" > + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 其它相关资料请上传到补充材料(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="ipt placeholder {if !empty($object['auxiliary'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['auxiliary']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo.auxiliaryImg}"> + </p> + <input type="hidden" v="{$vo.auxiliaryImg}" iv="{$vo.auxiliaryImg}" class="ipt j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar"> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + <div style='clear:both;'></div> + </td> + </tr> + </table> + +</fieldset> +<!-- +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt' value="{$object['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeStartDate']}"/> - + <input type='text' id='organizationCodeEndDate' readonly value="{$object['organizationCodeEndDate']}" {if $object['isLongOrganizationCodeDate']==1}style='display:none'{/if} class='ipt laydate-icon'/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1' {if $object['isLongOrganizationCodeDate']==1}checked{/if}/>长期</label> + </td> + </tr> +</table> +</fieldset> +--> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + + <tr> + + <td> + + <input type='hidden' id='organizationCodeImg' class='ipt' value='{$object['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证</div> + <span id='organizationCodeImgMsg'></span> + <a id='organizationCodeImgPreview_a' href='__IMGURL__/{$object['organizationCodeImg']}' target='_blank'> + <img id='organizationCodeImgPreview' src='__IMGURL__/{$object['organizationCodeImg']}' {if $object['organizationCodeImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +<script> + $(function(){ + /********** 轮播广告图片上传 **********/ + var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shops'},uploadSuccess:function(file,response){ + var json = WST.toAdminJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" value="'+json.savePath+json.name+'" class="a-ipt j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + + function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); + } + }); +</script> + diff --git a/hyhproject/admin/view/shops/edit2.html b/hyhproject/admin/view/shops/edit2.html new file mode 100755 index 0000000..b1b2ab5 --- /dev/null +++ b/hyhproject/admin/view/shops/edit2.html @@ -0,0 +1,101 @@ +<!-- +<fieldset class="layui-elem-field layui-field-title"> +<legend>税务信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt' value='{$object["taxpayerNo"]}'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' value='{$object["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$object['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <a href='__IMGURL__/{$vo}' target='_blank'> + <img class="step_pic" width="75" height="75" src="__IMGURL__/{$vo}" v="{$vo}"> + </a> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt' value='{$object["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <a id='taxpayerQualificationImgPreview_a' href='__IMGURL__/{$object["taxpayerQualificationImg"]}' target='_blank'> + <img id='taxpayerQualificationImgPreview' src='__IMGURL__/{$object["taxpayerQualificationImg"]}' {if $object["taxpayerQualificationImg"]==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + </table> +</fieldset> +--> +<fieldset class="layui-elem-field layui-field-title"> +<legend>结算账号信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' maxlength='50' class='ipt' data-rule='银行开户名:required;' value='{$object["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;' value='{$object["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <!-- + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> +--> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> \ No newline at end of file diff --git a/hyhproject/admin/view/shops/edit_apply.html b/hyhproject/admin/view/shops/edit_apply.html new file mode 100755 index 0000000..cb081cb --- /dev/null +++ b/hyhproject/admin/view/shops/edit_apply.html @@ -0,0 +1,625 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>申请会员:</th> + <td height='23'>{$object['loginName']}</td> + </tr> + <tr> + <th width='150'>申请时间:</th> + <td height='23'>{$object['applyTime']}</td> + </tr> + <tr> + <th width='150'>店铺编号:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:ignoreBlank;length[1~20];remote(post:{:url('admin/shops/checkShopSn','shopId='.$object['shopId'])})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>(为空则自动生成'S000000001'类型号码)</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;" value="{$object['shopName']}"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='100' data-rule="公司名称: required;" value="{$object['shopCompany']}"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' value="{$object['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' value="{$object['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$object['telephone']}"/> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' onclick="divShow()" class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1} data-rule="经营类目:checked"{/if} {if array_key_exists($vo['catId'],$object['catshops'])}checked{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th >食品许可证</th> + <td > + <input type='hidden' id='shopLicense' class='ipt' value='{$shoplicense["shopLicense"]}'/> + <div id='shopLicenseImgPicker'>请上传食品许可证电子版</div> + <span id='shopLicenseImgMsg'></span> + <a id='shopLicenseImgPreview_a' href='__IMGURL__/{$shoplicense["shopLicense"]}' target='_blank'> + <img id='shopLicenseImgPreview' src='__IMGURL__/{$shoplicense["shopLicense"]}' {if $shoplicense['shopLicense']==''} style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}'/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div> + <span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + <img id='preview' width='150' height='150' src="__IMGURL__/{$object['shopImg']}"/> + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' maxLength='200' value="{$object['shopQQ']}"/></td> + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' maxLength='200' value="{$object['shopWangWang']}"/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' onclick='javascript:WST.showHide(1,"#trInvoice")' {if $object['isInvoice']==1}checked{/if} title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' onclick='javascript:WST.showHide(0,"#trInvoice")' {if $object['isInvoice']==0}checked{/if} title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)" value="{$object['invoiceRemarks']}"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' {if $object['shopAtive']==1}checked{/if} title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' {if $object['shopAtive']==0}checked{/if} title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费(元):</th> + <td><input type="text" id='freight' class='ipt' maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)" value="{$object['freight']}"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>入驻联系人信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt' value="{$object['applyLinkMan']}"/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' id='applyLinkTel' data-rule="mobile" value="{$object['applyLinkTel']}"/> + </td> + </tr> + <!-- + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' class='ipt' data-rule="email" id='applyLinkEmail' value="{$object['applyLinkEmail']}"/> + </td> + </tr> + --> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $object['isInvestment']==1}checked{/if} title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $object['isInvestment']==0}checked{/if} title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' {if $object['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$object['investmentStaff']}"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>公司信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt' value="{$object['businessLicence']}"/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt' value="{$object['legalPersonName']}"/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <!-- + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px' value="{$object['licenseAddress']}"/> + </td> + </tr> + --> + <!-- + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon' value="{$object['establishmentDate']}"/> + </td> + </tr> +--> +<!-- + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' value="{$object['businessStartDate']}"/> - + <input type='text' id='businessEndDate' readonly class='ipt laydate-icon' value="{$object['businessEndDate']}" {if $object['isLongbusinessDate']==1}style='display:none'{/if}/> + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1' {if $object['isLongbusinessDate']==1}checked{/if}/>长期</label> + </td> + </tr> +--> +<!-- + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" value="{$object['registeredCapital']}"/> + </td> + </tr> +--> +<!-- + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'>{$object['empiricalRange']}</textarea> + </td> + </tr> +--> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt' value="{$object['legalCertificate']}"/> + </td> + </tr> + <!-- + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateStartDate']}"/> - + <input type='text' id='legalCertificateEndDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateEndDate']}" {if $object['isLonglegalCertificateDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1' {if $object['isLonglegalCertificateDate']==1}checked{/if}/>长期</label> + </td> + </tr> +--> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt' value='{$object['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <a id='legalCertificateImgPreview_a' href='__IMGURL__/{$object['legalCertificateImg']}' target='_blank'> + <img id='legalCertificateImgPreview' src='__IMGURL__/{$object['legalCertificateImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt' value='{$object['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <a id='businessLicenceImgPreview_a' href='__IMGURL__/{$object['businessLicenceImg']}' target='_blank'> + <img id='businessLicenceImgPreview' src='__IMGURL__/{$object['businessLicenceImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' value='{$object['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <a id='bankAccountPermitImgPreview_a' href='__IMGURL__/{$object['bankAccountPermitImg']}' target='_blank'> + <img id='bankAccountPermitImgPreview' src='__IMGURL__/{$object['bankAccountPermitImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th width='120' align='right'>补充材料<font color='red'>*</font>:</th> + <td> + <div id="batchUpload" class="ipt wst-batchupload" style="border:1px solid #ccc;width: 700px" > + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 其它相关资料请上传到补充材料(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="ipt placeholder {if !empty($object['auxiliary'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['auxiliary']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo.auxiliaryImg}"> + </p> + <input type="hidden" v="{$vo.auxiliaryImg}" iv="{$vo.auxiliaryImg}" class="ipt j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar"> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + <div style='clear:both;'></div> + </td> + </tr> + </table> +</fieldset> +<!-- <fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt' value="{$object['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeStartDate']}"/> - + <input type='text' id='organizationCodeEndDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeEndDate']}" {if $object['isLongOrganizationCodeDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1' {if $object['isLongOrganizationCodeDate']==1}checked{/if}/>长期</label> + </td> + </tr> + </table> +</fieldset> --> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th valign="top">商标注册证电子版:</th> + <td> + <span style='color:gray;'>请上传商标注册证或品牌授权证</span><br/> + <input type='hidden' id='organizationCodeImg' class='ipt' value='{$object['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证或品牌授权证</div> + <span id='organizationCodeImgMsg'></span> + <a id='organizationCodeImgPreview_a' href='__IMGURL__/{$object['organizationCodeImg']}' target='_blank'> + <img id='organizationCodeImgPreview' src='__IMGURL__/{$object['organizationCodeImg']}' width='150'> + </td> + </tr> + </table> +</fieldset> +<<!-- fieldset class="layui-elem-field layui-field-title"> +<legend>税务信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt' value='{$object["taxpayerNo"]}'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' value='{$object["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$object['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <a href='__IMGURL__/{$vo}' target='_blank'> + <img class="step_pic" width="75" height="75" src="__IMGURL__/{$vo}" v="{$vo}"> + </a> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt' value='{$object["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <a id='taxpayerQualificationImgPreview_a' href='__IMGURL__/{$object["taxpayerQualificationImg"]}' target='_blank'> + <img id='taxpayerQualificationImgPreview' src='__IMGURL__/{$object["taxpayerQualificationImg"]}' width='150'> + </a> + </td> + </tr> + </table> +</fieldset> --> +<fieldset class="layui-elem-field layui-field-title"> +<legend>结算账号信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='ipt' maxlength='50' data-rule='纳税人识别号:required;' value='{$object["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;' value='{$object["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <!-- + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> +--> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>申请状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>处理结果<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus2' value='2' {if $object['applyStatus']==2}checked{/if} onclick='javascript:WST.showHide(1,".deposit");WST.showHide(0,"#trApplyDesc")' data-rule="处理结果:checked" title='通过'> + </label> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus-1' value='-1' {if $object['applyStatus']==-1}checked{/if} onclick='javascript:WST.showHide(1,"#trApplyDesc");WST.showHide(0,".deposit")' title='不通过'> + </label> + </td> + </tr> + + <tr id='trDeposit' class="deposit" style='display:none'> + <th>应缴保证金<font color='red'>*</font>:</th> + <td> + <input type='text' name='payDeposit' id='payDeposit' class='ipt' value="{$cashDeposit['payDeposit']}"/> + </td> + </tr> + + <tr id='trPassDesc' class="deposit" style='display:none'> + <th>实缴保证金<font color='red'>*</font>:</th> + <td> + <input type='text' name='cashDeposit' id='cashDeposit' class='ipt' value="{$cashDeposit['cashDeposit']}"/> + </td> + </tr> + + + <tr id='trApplyDesc' style='display:none'> + <th>不通过原因<font color='red'>*</font>:</th> + <td><textarea id='applyDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="不通过原因:required(#applyStatus-1:checked);">{$object['applyDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:apply()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +<script type="text/javascript"> + $(function(){ + /********** 轮播广告图片上传 **********/ + var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shops'},uploadSuccess:function(file,response){ + var json = WST.toAdminJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" value="'+json.savePath+json.name+'" class="a-ipt j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + + function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); + } + }); +function divShow(){ +var checkboxText= new Array(); +var checkboxValue= new Array(); +var checkboxStr=document.getElementsByName("goodsCatIds"); + for(var i=0; i<checkboxStr.length; i++){ + if(checkboxStr[i].checked){ + //alert(checkboxStr[i].value+","+checkboxStr[i].nextSibling.nodeValue); + checkboxValue.push(checkboxStr[i].value); + checkboxText.push(checkboxStr[i].nextSibling.nodeValue.trim()); + } + } +var foot='393'; +if(checkboxValue.indexOf(foot)!="-1"){ + document.getElementById("license").style.cssText = "display: table-row;vertical-align: inherit;border-color: inherit;"; + }else{ + document.getElementById("license").style.cssText = "display:none" + } +} + + +</script> +<script> +$(function(){ + initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'{$object["areaIdPath"]}',bankAreaId:'{$object["bankAreaId"]}',bankAreaIdPath:'{$object["bankAreaIdPath"]}',businessAreaPath:'{$object["businessAreaPath"]}'}); + shopLicenseUpload (); +}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/list.html b/hyhproject/admin/view/shops/list.html new file mode 100755 index 0000000..20785e6 --- /dev/null +++ b/hyhproject/admin/view/shops/list.html @@ -0,0 +1,148 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} + </select> + <div id="select" class='j-ipt' style="float: left;"> + <select id="cat" class='j-ipt'> + <option value="">-商品分类-</option> + {volist name="catList" id="vi"} + <option value="{$vi['catId']}">{$vi['catName']}</option> + {/volist} + </select> + </div> + <input type="text" id="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + <select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> + </select> + <input type="text" name="userPhone" placeholder='联系方式' id="userPhone" class='j-ipt'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + + {if WSTGrant('DPGL_01')} + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + {/if} + <button class="btn btn-success f-right" onclick='javascript:toDeposit(0)'>质保金管理</button> + <button class="btn btn-primary btn-fixtop" style="margin-left: 10px;" onclick='javascript:toExport()'><i class="fa fa-sign-in"></i>导出</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> + +<div id='accredBox' style='display:none'> + <form id='topCommission' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th>店铺ID:</th> + <td> + <input type='text' name="shopId" id='shopId' class='ipt' value="" style='width:120px' disabled="disabled"> + </td> + </tr> +<!-- + <tr> + <th>店铺名称:</th> + <td> + <input type='text' name="shopsName" id='shopsName' class='ipt' value="" style='width:120px' /> + </td> + </tr> --> + + <tr> + <th>佣金扣点<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='text' class='ipt' name='commission' id='commission' value="" style='width:80px'>% + </label> + </td> + </tr> + +<!-- <tr> + <th>业务员提成<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='text' class='ipt' name='comDeduct' id='comDeduct' value="" style='width:80px'>% + </label> + </td> + </tr> --> + + <tr> + <th>业务员名称<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='text' class='ipt' name='userName' id='userName' style='width:120px' onchange='changeUser()'> + </label> + </td> + </tr> + + <tr> + <th>业务员手机号<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='text' class='ipt' name='usersPhone' id='usersPhone' value="" style='width:120px'> + </label> + </td> + </tr> + + <tr> + <th>业务员编号<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='text' class='ipt' name='userId' id='userId' value="" style='width:80px' disabled="disabled"> + </label> + </td> + </tr> + + + + </table> + </form> +</div> + +<script> + +function changeUser(){ + var userName=document.getElementById("userName").value; + $.post(WST.U('admin/shops/staffs'),{userName:userName,},function(data){ + // alert(JSON.stringify(data)) + var json = WST.toAdminJson(data); + if(json.status == -1){ + WST.msg(json.msg,{icon:2}); + }else{ + $("#userId").empty(); + $("#usersPhone").empty(); + $('#userId').val(json['userId']); + $('#usersPhone').val(json['userPhone']); + } + + } + , "json") + } + + + + + + function toExport(){ + var params = {}; + params = WST.getParams('.j-ipt'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/shops/toExport',params); + }}); +} +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/list_apply.html b/hyhproject/admin/view/shops/list_apply.html new file mode 100755 index 0000000..92db88d --- /dev/null +++ b/hyhproject/admin/view/shops/list_apply.html @@ -0,0 +1,34 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<!-- <select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> --> +<input type="text" id="shopName" placeholder='店铺名称' class='j-ipt'/> +<!-- <input type="text" id="investmentStaff" placeholder='对接商城招商人' class='j-ipt'/> --> +<!-- <select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> +</select> --> +<button class="btn btn-primary" onclick='javascript:loadApplyGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initApplyGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/list_stop.html b/hyhproject/admin/view/shops/list_stop.html new file mode 100755 index 0000000..80620e3 --- /dev/null +++ b/hyhproject/admin/view/shops/list_stop.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} + </select> + <input type="text" id="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + <select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> + </select> + <button class="btn btn-primary" onclick='javascript:loadStopGrid(0)'><i class='fa fa-search'></i>查询</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initStopGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops/shops.js b/hyhproject/admin/view/shops/shops.js new file mode 100755 index 0000000..d98b105 --- /dev/null +++ b/hyhproject/admin/view/shops/shops.js @@ -0,0 +1,660 @@ +var mmg; + +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺编号', name:'shopSn', width: 30,sortable: true}, + {title:'店铺账号', name:'loginName',width: 60,sortable: true}, + {title:'店铺名称', name:'shopName',width: 60,sortable: true}, + {title:'店主姓名', name:'shopkeeper',width: 40,hidden: true,sortable: true}, + {title:'店主联系电话', name:'telephone',width: 30,hidden: true,sortable: true}, + {title:'商品数量', name:'goodsNum',width: 30,sortable: true,align:'center'}, + {title:'店铺地址', name:'shopAddress',width:120 }, + {title:'主营类目', name:'catName',width:60,sortable: true,}, + {title:'所属公司', name:'shopCompany',width: 60,hidden: true}, + {title:'申请时间', name:'applyTime',width: 60}, + {title:'通过时间', name:'createTime',width: 60}, + {title:'营业状态', name:'shopAtive' ,width: 20,sortable: true,renderer: function (val,item,rowIndex){ + return (item['shopAtive']==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 营业中</span>":"<span class='statu-wait'><i class='fa fa-coffee'></i> 休息中</span>"; + }}, + // {title:'ECT支付', name:'shopAtive' ,width: 20,sortable: true,renderer: function (val,item,rowIndex){ + // return (item['status']==1)?"<a class='btn btn-red statu-yes' href='javascript:toPay(" + item['shopId']+ ","+item['status']+ ")'><i class='fa'></i>关闭</a>":"<a class='btn btn-red statu-no' href='javascript:toPay(" + item['shopId'] + ")'><i class='fa'></i>开启</a>"; + + // }}, + {title:'操作', name:'' ,width:250, renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.DPGL_02)h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.DPGL_03 && item['shopId']!=1)h += "<a class='btn btn-red' href='javascript:toDel(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + h += "<a class='btn btn-blue' href='"+WST.U('admin/logmoneys/tologmoneys','id='+item['shopId'])+"&type=1'><i class='fa fa-search'></i>商家资金</a>"; + h += "<a class='btn btn-blue' href='javascript:toCommission(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>设置佣金扣点</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/pageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'shopSn', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + + +function toCommission(shopId){ + $('#topCommission')[0].reset(); + $.post(WST.U('admin/shops/commission'),{shopId:shopId},function(data,textStatus){ + // dump($data);die; + var json = WST.toAdminJson(data); + if(json){ + WST.setValues(json); + layui.form.render(); + editsBox(shopId); + } + }); +} + +function editsBox(shopId){ + var title =(shopId>0)?"修改":"新增"; + var box = WST.open({title:title,type:1,content:$('#accredBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#accredBox').hide();},yes:function(){ + $('#topCommission').submit(); + }}); + $('#topCommission').validator({ + fields: { + 'commission': {rule:"required",msg:{required:'请输入佣金扣点'}}, + }, + // fields: { + // 'comDeduct': {rule:"required",msg:{required:'请输入提成比例'}}, + // }, + fields: { + 'userName': {rule:"required",msg:{required:'请输入业务员名称'}}, + }, + fields: { + 'usersPhone': {rule:"required",msg:{required:'请输入业务员电话'}}, + }, + fields: { + 'userId': {rule:"required",msg:{required:'请输入业务员编号'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/upCommission/'+(shopId)),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#accredBox').hide(); + grid.reload(secTyepId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + + +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +function initApplyGrid(){ + + var h = WST.pageHeight(); + var cols = [ + {title:'申请人账号', name:'loginName', width: 30}, + {title:'申请人姓名', name:'trueName', width: 30}, + {title:'店铺名称', name:'shopName',width:100 }, + {title:'直营人', name:'userName',width:100 }, + {title:'申请联系人电话', name:'phone',width:30 }, + {title:'店铺地址', name:'shopAddress',width:30 }, + {title:'申请日期', name:'applyTime' }, + {title:'申请状态', name:'status' ,width:30,renderer: function (val,item,rowIndex){ + if(item['status']==0){ + return "<span class='statu-wait'><i class='fa fa-clock-o'></i> 待处理</span>"; + }else if(item['status']==1){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 申请成功</span>"; + }else{ + return "<span class='statu-no'><i class='fa fa-ban'></i> 申请失败</span>"; + } + }}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.DPSQ_04)h += "<a class='btn btn-blue' href='javascript:toHandle(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>操作</a> "; + if(item['status']==-1){ + if(WST.GRANT.DPSQ_03)h += "<a class='btn btn-red' href='javascript:toDelApply(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/shopApplyList'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadApplyGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +function toPay(id,status){ + var box = WST.confirm({content:"您确定修改ECT支付状态吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/payments/pay'),{id:id,status:status},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function toHandle(id){ + location.href = WST.U('admin/shops/applyEdit','id='+id); +} +function toDelApply(id){ + var box = WST.confirm({content:"您确定要彻底删除该店铺申请信息吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/delApply'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function initStopGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺编号', name:'shopSn', width: 30}, + {title:'店铺账号', name:'loginName', width: 60}, + {title:'店铺名称', name:'shopName',width: 120}, + {title:'店主姓名', name:'shopkeeper',width: 40,hidden: true}, + {title:'店主联系电话', name:'telephone',hidden: true}, + {title:'店铺地址', name:'shopAddress',width:350 }, + {title:'所属公司', name:'shopCompany',hidden: true }, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + h += "<a class='btn btn-red' href='javascript:toDel(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/pageStopQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadStopGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +var initTab2 = false,initTab3 = false; +function initUpload(isEdit){ + if(!isEdit){ + legalCertificateImgUpload(); + businessLicenceImgUpload(); + bankAccountPermitImgUpload(); + shopLicenseUpload(); + organizationCodeUpload(); + taxRegistrationCertificateUpload(); + taxpayerQualificationUpload(); + }else{ + var element = layui.element; + element.on('tab(msgTab)', function(data){ + if(data.index==1){ + if(initTab2)return; + initTab2 = true; + legalCertificateImgUpload(); + businessLicenceImgUpload(); + bankAccountPermitImgUpload(); + organizationCodeUpload(); + shopLicenseUpload(); + }else if(data.index==2){ + if(initTab3)return; + initTab3 = true; + taxRegistrationCertificateUpload(); + taxpayerQualificationUpload(); + } + }); + } +} +function legalCertificateImgUpload (){ + WST.upload({ + pick:'#legalCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#legalCertificateImgMsg').empty().hide(); + $('#legalCertificateImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#legalCertificateImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#legalCertificateImg').val(json.savePath+json.name); + $('#msg_legalCertificateImg').hide(); + } + }, + progress:function(rate){ + $('#legalCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function businessLicenceImgUpload(){ + WST.upload({ + pick:'#businessLicenceImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#businessLicenceImgMsg').empty().hide(); + $('#businessLicenceImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#businessLicenceImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#businessLicenceImg').val(json.savePath+json.name); + $('#msg_businessLicenceImg').hide(); + } + }, + progress:function(rate){ + $('#businessLicenceImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function bankAccountPermitImgUpload(){ + WST.upload({ + pick:'#bankAccountPermitImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#bankAccountPermitImgMsg').empty().hide(); + $('#bankAccountPermitImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#bankAccountPermitImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#bankAccountPermitImg').val(json.savePath+json.name); + $('#msg_bankAccountPermitImg').hide(); + } + }, + progress:function(rate){ + $('#bankAccountPermitImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function organizationCodeUpload(){ + WST.upload({ + pick:'#organizationCodeImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#organizationCodeImgMsg').empty().hide(); + $('#organizationCodeImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#organizationCodeImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#organizationCodeImg').val(json.savePath+json.name); + $('#msg_organizationCodeImg').hide(); + } + }, + progress:function(rate){ + $('#organizationCodeImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function shopLicenseUpload (){ + WST.upload({ + pick:'#shopLicenseImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#shopLicenseImgMsg').empty().hide(); + $('#shopLicenseImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#shopLicenseImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#shopLicense').val(json.savePath+json.name); + $('#msg_shopLicenseImg').hide(); + } + }, + progress:function(rate){ + $('#shopLicenseImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function taxRegistrationCertificateUpload(){ + var uploader = WST.upload({ + pick:'#taxRegistrationCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + fileNumLimit:3, + callback:function(f,file){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#taxRegistrationCertificateImgMsg').empty().hide(); + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'><a target='_blank' href='"+WST.conf.IMGURL+"/"+json.savePath+json.name+"'>"+ + "<img class='step_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></a></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/View/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#taxRegistrationCertificateImgBox').append(tdiv); + $('#msg_taxRegistrationCertificateImg').hide(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + if($('#taxRegistrationCertificateImgBox').children().size()<=0){ + $('#msg_taxRegistrationCertificateImg').show(); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#taxRegistrationCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function taxpayerQualificationUpload(){ + WST.upload({ + pick:'#taxpayerQualificationImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#taxpayerQualificationImgMsg').empty().hide(); + $('#taxpayerQualificationImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#taxpayerQualificationImgPreview_a').attr('href',WST.conf.IMGURL+"/"+json.savePath+json.name); + $('#taxpayerQualificationImg').val(json.savePath+json.name); + $('#msg_taxpayerQualificationImg').hide(); + } + }, + progress:function(rate){ + $('#taxpayerQualificationImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function initEdit(opts){ + var laydate = layui.laydate; + laydate.render({elem: '#establishmentDate'}); + laydate.render({elem: '#businessStartDate'}); + laydate.render({elem: '#businessEndDate'}); + laydate.render({elem: '#legalCertificateStartDate'}); + laydate.render({elem: '#legalCertificateEndDate'}); + laydate.render({elem: '#organizationCodeStartDate'}); + laydate.render({elem: '#organizationCodeEndDate'}); + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#preview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb); + $('#shopImg').val(json.savePath+json.name); + $('#editFrom').validator('hideMsg', '#shopImg'); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',opts.serviceStartTime); + initTime('#serviceEndTime',opts.serviceEndTime); + if($('#shopId').val()>0){ + var areaIdPath = opts.areaIdPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas',isRequire:true} + WST.ITSetAreas(aopts); + if(opts.bankAreaIdPath!=''){ + var areaIdPath = opts.bankAreaIdPath.split("_"); + $('#barea_0').val(areaIdPath[0]); + var aopts = {id:'barea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-bareas',isRequire:true} + WST.ITSetAreas(aopts); + } + if(opts.businessAreaPath!=''){ + var areaIdPath = opts.businessAreaPath.split("_"); + $('#carea_0').val(areaIdPath[0]); + var aopts = {id:'carea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-careas',isRequire:false} + WST.ITSetAreas(aopts); + } + } + initUpload(opts.isEdit); +} +function delVO(obj){ + $(obj).parent().remove(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); +} +function toEdit(id){ + location.href=WST.U('admin/shops/toEdit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该店铺吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function checkLoginKey(obj){ + if($.trim(obj.value)=='')return; + var params = {key:obj.value,userId:0}; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/checkLoginKey'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status!='1'){ + WST.msg(json.msg,{icon:2}); + obj.value = ''; + } + }); +} +function save(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + params.businessAreaPath0 = WST.ITGetAreaVal('j-careas'); + var p= $('.file-panel').text(); + if(p!=""){ + WST.msg('请先上传补充材料',{icon:6}); + return; + } + var shopAds = []; + $('.j-gallery-img').each(function(){ + shopAds.push($(this).attr('v')); + }); + + params.shopAds = shopAds.join(','); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + if(params.shopStatus==1){ + location.href=WST.U('admin/shops/index'); + }else{ + location.href=WST.U('admin/shops/stopIndex'); + } + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function getUserByKey(){ + if($.trim($('#keyName').val())=='')return; + $('#keyNameBox').html(''); + $('#shopUserId').val(0); + var loading = WST.msg('正在查询用户信息...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/getUserByKey'),{key:$('#keyName').val()},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + $('#keyNameBox').html('用户:'+json.data.loginName); + $('#shopUserId').val(json.data.userId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function add(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + params.businessAreaPath0 = WST.ITGetAreaVal('j-careas'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/add'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + location.href=WST.U('admin/shops/index'); + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function apply(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(params.applyStatus==-1 && params.applyDesc==''){ + WST.msg('请输入审核不通过原因!',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/handleApply'),params,function(data,textStatus){ + //layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + location.href=WST.U('admin/shops/apply'); + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function initTime($id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $($id).append(html.join('')); +} +//质保金管理 +function toDeposit(){ + location.href=WST.U('admin/shops/toDeposit'); +} + +function editInit(){ + /* 表单验证 */ + $('#topDeposit').validator({ + valid: function(form) { + var params = WST.getParams('.ipt'); + if(params.shopId=='') { + WST.msg('请填写店铺编号', { + icon: 2 + }); + return; + } + if(params.applyStatus==1 && params.addDeposit=='') { + WST.msg('请填写充值质保金金额', { + icon: 2 + }); + return; + } + if(params.applyStatus==2 && params.offDeposit=='') { + WST.msg('请填写扣除质保金金额', { + icon: 2 + }); + return; + } + if(params.applyStatus==2 && params.offCause=='') { + WST.msg('请填写扣除质保原因', { + icon: 2 + }); + return; + } + $.post(WST.U('admin/shops/topDeposit'), params, function(data, textStatus) { + var json = WST.toAdminJson(data); + if(json.status == 1) { + WST.msg(json.msg, { + icon: 1 + }, function() { + // $('#goodsOrder').val(+$('#goodsOrder').val()+1); + $('#cashDeposit').val(''); + //location.href = WST.AU('hyhlimitactive://Hyhlimitactive/getGoodsAdd'); + }); + } else { + WST.msg(json.msg, { + icon: 2 + }); + } + }); + + } + }); +} + + diff --git a/hyhproject/admin/view/shops/view_apply.html b/hyhproject/admin/view/shops/view_apply.html new file mode 100755 index 0000000..5622008 --- /dev/null +++ b/hyhproject/admin/view/shops/view_apply.html @@ -0,0 +1,21 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +店铺名称:<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +是否招商推广: +<select id="isInvestment" class='ipt'> + <option value="">-请选择-</option> + <option value="1">是</option> + <option value="0">否</option> +</select> +<button class="btn btn-primary" onclick='javascript:loadApplyGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div id="maingrid"></div> +<script> +$(function(){initApplyGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/add.html b/hyhproject/admin/view/shops_back/add.html new file mode 100755 index 0000000..c1049a6 --- /dev/null +++ b/hyhproject/admin/view/shops_back/add.html @@ -0,0 +1,455 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>新增类型<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isNew' id='isNew1' value='1' onclick='javascript:WST.showHide(1,".newUserTr1");WST.showHide(0,"#newUserTr0")' checked title='新账号'> + </label> + <label> + <input type='radio' class='ipt' name='isNew' value='0' onclick='javascript:WST.showHide(0,".newUserTr1");WST.showHide(1,"#newUserTr0")' title='已有账号'> + </label> + </td> + </tr> + <tr id='newUserTr0' style='display:none'> + <th width='150' valign="top">请输入用户账号<font color='red'>*</font>:</th> + <td> + <input type="text" id='keyName' name='keyName' class='ipt' placeholder='请输入用户账号/手机'/> + <input type='button' value='查询' class='btn btn-primary' onclick='javascript:getUserByKey()'> + <div id='keyNameBox' style='height:30px;line-height:30px'></div> + <input type='hidden' class='ipt' id='shopUserId' value='0'/> + </td> + </tr> + <tr class='newUserTr1'> + <th width='150'>登录账号<font color='red'>*</font>:</th> + <td><input type="text" id='loginName' name='loginName' class='ipt' value=" " maxLength='20' data-rule="登录账号: required(#isNew1:checked);length[6~20];remote(post:{:url('admin/users/checkLoginKey')})" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr class='newUserTr1'> + <th>登录密码<font color='red'>*</font>:</th> + <td><input type="password" id='loginPwd' class='ipt' maxLength='20' value='88888888' data-rule="登录密码: required(#isNew1:checked);length[6~20];" data-target="#msg_loginPwd"/> + <span class='msg-box' id='msg_loginPwd'>(默认为88888888)</span> + </td> + </tr> + <tr> + <th width='150'>店铺编号<font color='red'>*</font>:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:ignoreBlank;length[1~20];remote(post:{:url('admin/shops/checkShopSn')})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>(为空则自动生成'S000000001'类型号码)</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='100' data-rule="公司名称: required;"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' /> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' /> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' /> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' /> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营类目:checked"{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}'/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div><span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + <img id='preview' width='150' height='150' src="__ROOT__/{:WSTConf('CONF.shopLogo')}"/> + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' maxLength='200'/><span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span></td> + + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' maxLength='200'/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' onclick='javascript:WST.showHide(1,"#trInvoice")' title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' onclick='javascript:WST.showHide(0,"#trInvoice")' checked title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' style='display:none'> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' checked title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费(元)<font color='red'>*</font>:</th> + <td><input type="text" id='freight' class='ipt' maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' value='0' onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>入驻商联系人信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt'/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' data-rule="mobile" id='applyLinkTel'/> + </td> + </tr> + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' data-rule="email" class='ipt' id='applyLinkEmail'/> + </td> + </tr> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' style='display:none'> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>公司信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt'/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt'/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px'/> + </td> + </tr> + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon'/> + </td> + </tr> + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='businessEndDate' readonly class='ipt laydate-icon' /> + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" /> + </td> + </tr> + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'></textarea> + </td> + </tr> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt'/> + </td> + </tr> + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='legalCertificateEndDate' readonly class='ipt laydate-icon' />&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <img id='legalCertificateImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <img id='businessLicenceImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' /> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <img id='bankAccountPermitImgPreview' src='' style='display:none' width='150'> + + </td> + </tr> +</table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>商标注册证</legend> + <table class='wst-form wst-box-top'> + <tr> + <th>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt'/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' /> - + <input type='text' id='organizationCodeEndDate' readonly class='ipt laydate-icon'/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1'/>长期</label> + </td> + </tr> + <tr> + <th valign="top">商标注册证电子版:</th> + <td> + <span style='color:gray;'>复印件需加盖公司红章扫描上传,三证合一的此处请上传营业执照电子版</span><br/> + <input type='hidden' id='organizationCodeImg' class='ipt'/> + <div id='organizationCodeImgPicker'>请上传商标注册证电子版</div> + <span id='organizationCodeImgMsg'></span> + <img id='organizationCodeImgPreview' src='' style='display:none' width='150'> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>税务信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' /> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'></span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <img id='taxpayerQualificationImgPreview' src='' style='display:none' width='150'> + </td> + </tr> +</table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> + <legend>结算账号信息</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='ipt' maxlength='50' data-rule='银行开户名:required;'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}">{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright b' onclick='javascript:add()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script> +$(function(){initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'',bankAreaId:'',bankAreaIdPath:'',isEdit:false});}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/edit.html b/hyhproject/admin/view/shops_back/edit.html new file mode 100755 index 0000000..3f0daa1 --- /dev/null +++ b/hyhproject/admin/view/shops_back/edit.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">店铺信息</li> + <li>公司信息</li> + <li>税务及银行信息</li> + </ul> + <div class="layui-tab-content" style="padding: 10px 0;"> + <div class="layui-tab-item layui-show"> + {include file='shops/edit0'/} + </div> + <div class="layui-tab-item"> + {include file='shops/edit1'/} + </div> + <div class="layui-tab-item"> + {include file='shops/edit2'/} + </div> + </div> +</div> +</form> +<script> +$(function(){initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'{$object["areaIdPath"]}',bankAreaId:'{$object["bankAreaId"]}',bankAreaIdPath:'{$object["bankAreaIdPath"]}',businessAreaPath:'{$object["businessAreaPath"]}',isEdit:true});}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/edit0.html b/hyhproject/admin/view/shops_back/edit0.html new file mode 100755 index 0000000..7e8f413 --- /dev/null +++ b/hyhproject/admin/view/shops_back/edit0.html @@ -0,0 +1,198 @@ +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>店铺编号<font color='red'>*</font>:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:{if $object['shopId']>0}required;length[1~20];{else /}ignoreBlank;{/if}remote(post:{:url('admin/shops/checkShopSn',array('shopId'=>$object['shopId']))})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>{if $object['shopId']==0}(为空则自动生成'S000000001'类型号码){/if}</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' value="{$object['shopName']}" maxLength='20' data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='20' value="{$object['shopCompany']}" data-rule="店铺名称: required;"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' value="{$object['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' value="{$object['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$object['telephone']}"/> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营类目:checked"{/if} {if array_key_exists($vo['catId'],$object['catshops'])}checked{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}' {if array_key_exists($vo['accredId'],$object['accreds'])}checked{/if}/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div><span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + {if $object["shopImg"]!=''} + <img id='preview' width='150' height='150' src='__ROOT__/{$object["shopImg"]}'/> + {else} + <img id='preview' width='150' height='150' src="__ROOT__/{:WSTConf('CONF.shopLogo')}"/> + {/if} + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' value="{$object['shopQQ']}" maxLength='200'/><span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span></td> + + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' value="{$object['shopWangWang']}" maxLength='200'/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' {if $object['isInvoice']==1}checked{/if} onclick='javascript:WST.showHide(1,"#trInvoice")' title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' {if $object['isInvoice']==0}checked{/if} onclick='javascript:WST.showHide(0,"#trInvoice")' title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' value="{$object['invoiceRemarks']}" style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' {if $object['shopAtive']==1}checked{/if} title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' {if $object['shopAtive']==0}checked{/if} title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费:</th> + <td><input type="text" id='freight' class='ipt' value="{$object['freight']}" maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>入驻商联系人信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt' value="{$object['applyLinkMan']}"/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' id='applyLinkTel' data-rule="mobile" value="{$object['applyLinkTel']}"/> + </td> + </tr> + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' class='ipt' data-rule="email" id='applyLinkEmail' value="{$object['applyLinkEmail']}"/> + </td> + </tr> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $object['isInvestment']==1}checked{/if} title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $object['isInvestment']==0}checked{/if} title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' {if $object['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$object['investmentStaff']}"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>店铺状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>店铺状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopStatus' id='shopStatus-1' value='-1' {if $object['shopStatus']==-1}checked{/if} onclick='javascript:WST.showHide(1,"#trStatusDesc")' title='停止'> + </label> + <label> + <input type='radio' class='ipt' name='shopStatus' value='1' {if $object['shopStatus']==1}checked{/if} onclick='javascript:WST.showHide(0,"#trStatusDesc")' title='正常'> + </label> + </td> + </tr> + <tr id='trStatusDesc' {if $object['shopStatus']==1}style='display:none'{/if}> + <th>停止原因<font color='red'>*</font>:</th> + <td><textarea id='statusDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="停止原因:required(#shopStatus-1:checked);">{$object['statusDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/edit1.html b/hyhproject/admin/view/shops_back/edit1.html new file mode 100755 index 0000000..b9f9c7d --- /dev/null +++ b/hyhproject/admin/view/shops_back/edit1.html @@ -0,0 +1,170 @@ +<fieldset class="layui-elem-field layui-field-title"> +<legend>公司信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['businessLicenceType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt' value="{$object['businessLicence']}"/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt' value="{$object['legalPersonName']}"/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px' value="{$object['licenseAddress']}"/> + </td> + </tr> + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon' value="{$object['establishmentDate']}"/> + </td> + </tr> + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' value="{$object['businessStartDate']}"/> - + <input type='text' id='businessEndDate' {if $object['isLongbusinessDate']==1}style='display:none'{/if} readonly class='ipt laydate-icon' value="{$object['businessEndDate']}"/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1' {if $object['isLongbusinessDate']==1}checked{/if}/>长期</label> + </td> + </tr> + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" value="{$object['registeredCapital']}"/> + </td> + </tr> + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'>{$object['empiricalRange']}</textarea> + </td> + </tr> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['legalCertificateType']==$vo['dataVal']}{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt' value="{$object['legalCertificate']}"/> + </td> + </tr> + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateStartDate']}"/> - + <input type='text' id='legalCertificateEndDate' readonly value="{$object['legalCertificateEndDate']}" {if $object['isLonglegalCertificateDate']==1}style='display:none'{/if} class='ipt laydate-icon' />&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1' {if $object['isLonglegalCertificateDate']==1}checked{/if}/>长期</label> + + </td> + </tr> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt' value='{$object['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <a id='legalCertificateImgPreview_a' href='__ROOT__/{$object['legalCertificateImg']}' target='_blank'> + <img id='legalCertificateImgPreview' src='__ROOT__/{$object['legalCertificateImg']}' {if $object['legalCertificateImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt' value='{$object['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <a id='businessLicenceImgPreview_a' href='__ROOT__/{$object['businessLicenceImg']}' target='_blank'> + <img id='businessLicenceImgPreview' src='__ROOT__/{$object['businessLicenceImg']}' {if $object['businessLicenceImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' value='{$object['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <a id='bankAccountPermitImgPreview_a' href='__ROOT__/{$object['bankAccountPermitImg']}' target='_blank'> + <img id='bankAccountPermitImgPreview' src='__ROOT__/{$object['bankAccountPermitImg']}' {if $object['bankAccountPermitImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt' value="{$object['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeStartDate']}"/> - + <input type='text' id='organizationCodeEndDate' readonly value="{$object['organizationCodeEndDate']}" {if $object['isLongOrganizationCodeDate']==1}style='display:none'{/if} class='ipt laydate-icon'/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1' {if $object['isLongOrganizationCodeDate']==1}checked{/if}/>长期</label> + </td> + </tr> +</table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + + <tr> + + <td> + + <input type='hidden' id='organizationCodeImg' class='ipt' value='{$object['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证</div> + <span id='organizationCodeImgMsg'></span> + <a id='organizationCodeImgPreview_a' href='__ROOT__/{$object['organizationCodeImg']}' target='_blank'> + <img id='organizationCodeImgPreview' src='__ROOT__/{$object['organizationCodeImg']}' {if $object['organizationCodeImg'] ==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/edit2.html b/hyhproject/admin/view/shops_back/edit2.html new file mode 100755 index 0000000..e0dce6b --- /dev/null +++ b/hyhproject/admin/view/shops_back/edit2.html @@ -0,0 +1,97 @@ +<fieldset class="layui-elem-field layui-field-title"> +<legend>税务信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt' value='{$object["taxpayerNo"]}'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' value='{$object["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$object['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <a href='__ROOT__/{$vo}' target='_blank'> + <img class="step_pic" width="75" height="75" src="__ROOT__/{$vo}" v="{$vo}"> + </a> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt' value='{$object["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <a id='taxpayerQualificationImgPreview_a' href='__ROOT__/{$object["taxpayerQualificationImg"]}' target='_blank'> + <img id='taxpayerQualificationImgPreview' src='__ROOT__/{$object["taxpayerQualificationImg"]}' {if $object["taxpayerQualificationImg"]==''}style='display:none'{/if} width='150'> + </a> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>结算账号信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' maxlength='50' class='ipt' data-rule='银行开户名:required;' value='{$object["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;' value='{$object["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save()'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</fieldset> \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/edit_apply.html b/hyhproject/admin/view/shops_back/edit_apply.html new file mode 100755 index 0000000..7ceac4b --- /dev/null +++ b/hyhproject/admin/view/shops_back/edit_apply.html @@ -0,0 +1,476 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<style> +.goodsCat{display:inline-block;width:150px} +.accreds{display:inline-block;width:150px} +</style> +<form id='editFrom' autocomplete='off'> +<input type='hidden' id='shopId' class='ipt' value="{$object['shopId']}"/> +<fieldset class="layui-elem-field layui-field-title"> +<legend>基础信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>申请会员:</th> + <td height='23'>{$object['loginName']}</td> + </tr> + <tr> + <th width='150'>申请时间:</th> + <td height='23'>{$object['applyTime']}</td> + </tr> + <tr> + <th width='150'>店铺编号:</th> + <td><input type="text" id='shopSn' name='shopSn' class='ipt' value="{$object['shopSn']}" maxLength='20' data-rule="店铺编号:ignoreBlank;length[1~20];remote(post:{:url('admin/shops/checkShopSn','shopId='.$object['shopId'])})" data-target="#msg_shopSn"/><span class='msg-box' id='msg_shopSn'>(为空则自动生成'S000000001'类型号码)</span></td> + </tr> + <tr> + <th width='150'>店铺名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopName' class='ipt' maxLength='20' data-rule="店铺名称: required;" value="{$object['shopName']}"/></td> + </tr> + <tr> + <th width='150'>公司名称<font color='red'>*</font>:</th> + <td><input type="text" id='shopCompany' class='ipt' maxLength='100' data-rule="公司名称: required;" value="{$object['shopCompany']}"/></td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$object['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='ipt' data-rule='公司电话:required;' value="{$object['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='ipt' data-rule='公司紧急联系人:required;' value="{$object['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$object['telephone']}"/> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' class='ipt' name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营类目:checked"{/if} {if array_key_exists($vo['catId'],$object['catshops'])}checked{/if}/>{$vo["catName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {volist name="accredList" id="vo"} + <label class='accreds'> + <input type='checkbox' class='ipt' name='accredIds' value='{$vo["accredId"]}'/>{$vo["accredName"]} + </label> + {/volist} + </td> + </tr> + <tr> + <th>店铺图标<font color='red'>*</font>:</th> + <td> + <div id='shopImgPicker'>上传店铺图标</div><span id='uploadMsg'></span><span class='msg-box' id='msg_shopImg'></span> + <img id='preview' width='150' height='150' src="__ROOT__/{$object['shopImg']}"/> + <input type="hidden" id='shopImg' class='ipt' value="{$object['shopImg']}" data-rule="店铺图标: required;" data-target='#msg_shopImg'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type="text" id='shopQQ' class='ipt' maxLength='200' value="{$object['shopQQ']}"/></td> + </tr> + <tr> + <th>阿里旺旺:</th> + <td><input type="text" id='shopWangWang' class='ipt' maxLength='200' value="{$object['shopWangWang']}"/></td> + </tr> + + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='isInvoice' id='isInvoice1' value='1' onclick='javascript:WST.showHide(1,"#trInvoice")' {if $object['isInvoice']==1}checked{/if} title='是'> + </label> + <label> + <input type='radio' class='ipt' name='isInvoice' value='0' onclick='javascript:WST.showHide(0,"#trInvoice")' {if $object['isInvoice']==0}checked{/if} title='否'> + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input type="text" id='invoiceRemarks' class='ipt' style='width:500px;' maxLength='100' data-rule="发票说明:required(#isInvoice1:checked)" value="{$object['invoiceRemarks']}"/></td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='shopAtive' value='1' {if $object['shopAtive']==1}checked{/if} title='营业中'> + </label> + <label> + <input type='radio' class='ipt' name='shopAtive' value='0' {if $object['shopAtive']==0}checked{/if} title='休息中'> + </label> + </td> + </tr> + <tr> + <th>默认运费(元):</th> + <td><input type="text" id='freight' class='ipt' maxLength='8' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)" value="{$object['freight']}"/></td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt' id='serviceStartTime'></select> + 至 + <select class='ipt' id='serviceEndTime'></select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>入驻联系人信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>联系人姓名:</th> + <td> + <input type='text' id='applyLinkMan' class='ipt' value="{$object['applyLinkMan']}"/> + </td> + </tr> + <tr> + <th>联系人手机:</th> + <td> + <input type='text' class='ipt' id='applyLinkTel' data-rule="mobile" value="{$object['applyLinkTel']}"/> + </td> + </tr> + <tr> + <th>联系人电子邮箱:</th> + <td> + <input type='text' name='applyLinkEmail' class='ipt' data-rule="email" id='applyLinkEmail' value="{$object['applyLinkEmail']}"/> + </td> + </tr> + <tr> + <th>对接商城招商人员:</th> + <td class='layui-form'> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment1' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $object['isInvestment']==1}checked{/if} title='有'/> + </label> + <label> + <input type='radio' name='isInvestment' class='ipt' id='isInvestment0' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $object['isInvestment']==0}checked{/if} title='无'/> + </label> + </td> + </tr> + <tr id='investmentStaffTr' {if $object['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$object['investmentStaff']}"/> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>公司信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>执照类型:</th> + <td> + <select id='businessLicenceType' class='ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号:</th> + <td><input type='text' id='businessLicence' class='ipt' value="{$object['businessLicence']}"/><br/><span style='color:gray;'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名:</th> + <td> + <input type='text' id='legalPersonName' class='ipt' value="{$object['legalPersonName']}"/> + <br/><span style='color:gray;'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <tr> + <th>营业执照所在地:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:false,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址:</th> + <td> + <input type='text' id='licenseAddress' class='ipt' style='width:550px' value="{$object['licenseAddress']}"/> + </td> + </tr> + <tr> + <th>成立日期:</th> + <td> + <input type='text' id='establishmentDate' readonly class='ipt laydate-icon' value="{$object['establishmentDate']}"/> + </td> + </tr> + <tr> + <th>营业期限:</th> + <td> + <input type='text' id='businessStartDate' readonly class='ipt laydate-icon' value="{$object['businessStartDate']}"/> - + <input type='text' id='businessEndDate' readonly class='ipt laydate-icon' value="{$object['businessEndDate']}" {if $object['isLongbusinessDate']==1}style='display:none'{/if}/> + <label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' value='1' {if $object['isLongbusinessDate']==1}checked{/if}/>长期</label> + </td> + </tr> + <tr> + <th>注册资本(万元):</th> + <td> + <input type='text' id='registeredCapital' class='ipt' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" value="{$object['registeredCapital']}"/> + </td> + </tr> + <tr> + <th>经营范围:</th> + <td> + <textarea id='empiricalRange' class='ipt' style='width:550px;height:150px;'>{$object['empiricalRange']}</textarea> + </td> + </tr> + <tr> + <th>法人代表证件类型:</th> + <td> + <select id='legalCertificateType' class='ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号:</th> + <td> + <input type='text' id='legalCertificate' class='ipt' value="{$object['legalCertificate']}"/> + </td> + </tr> + <tr> + <th>有效期:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateStartDate']}"/> - + <input type='text' id='legalCertificateEndDate' readonly class='ipt laydate-icon' value="{$object['legalCertificateEndDate']}" {if $object['isLonglegalCertificateDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' value='1' {if $object['isLonglegalCertificateDate']==1}checked{/if}/>长期</label> + </td> + </tr> + <tr> + <th>法人证件电子版:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='ipt' value='{$object['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <a id='legalCertificateImgPreview_a' href='__ROOT__/{$object['legalCertificateImg']}' target='_blank'> + <img id='legalCertificateImgPreview' src='__ROOT__/{$object['legalCertificateImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>营业执照电子版:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='ipt' value='{$object['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <a id='businessLicenceImgPreview_a' href='__ROOT__/{$object['businessLicenceImg']}' target='_blank'> + <img id='businessLicenceImgPreview' src='__ROOT__/{$object['businessLicenceImg']}' width='150'> + </a> + </td> + </tr> + <tr> + <th>银行开户许可证电子版:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='ipt' value='{$object['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <a id='bankAccountPermitImgPreview_a' href='__ROOT__/{$object['bankAccountPermitImg']}' target='_blank'> + <img id='bankAccountPermitImgPreview' src='__ROOT__/{$object['bankAccountPermitImg']}' width='150'> + </a> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>组织机构代码:</th> + <td> + <input type='text' id='organizationCode' class='ipt' value="{$object['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeStartDate']}"/> - + <input type='text' id='organizationCodeEndDate' readonly class='ipt laydate-icon' value="{$object['organizationCodeEndDate']}" {if $object['isLongOrganizationCodeDate']==1}style='display:none'{/if}/>&nbsp;&nbsp;&nbsp; + <label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='ipt' onclick='WST.showHide(this.checked?0:1,"#organizationCodeEndDate")' value='1' {if $object['isLongOrganizationCodeDate']==1}checked{/if}/>长期</label> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>商标注册证</legend> +<table class='wst-form wst-box-top'> + <tr> + <th valign="top">商标注册证电子版:</th> + <td> + <span style='color:gray;'>请上传商标注册证或品牌授权证</span><br/> + <input type='hidden' id='organizationCodeImg' class='ipt' value='{$object['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证或品牌授权证</div> + <span id='organizationCodeImgMsg'></span> + <a id='organizationCodeImgPreview_a' href='__ROOT__/{$object['organizationCodeImg']}' target='_blank'> + <img id='organizationCodeImgPreview' src='__ROOT__/{$object['organizationCodeImg']}' width='150'> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>税务信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>纳税人类型:</th> + <td> + <select id='taxpayerType' class='ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $object['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号:</th> + <td><input type='text' id='taxpayerNo' class='ipt' value='{$object["taxpayerNo"]}'/><br/><span style='color:gray;'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版:</th> + <td> + <span style='color:gray;'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”;<br/>此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='ipt' value='{$object["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$object['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <a href='__ROOT__/{$vo}' target='_blank'> + <img class="step_pic" width="75" height="75" src="__ROOT__/{$vo}" v="{$vo}"> + </a> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版:</th> + <td> + <span style='color:gray;'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='ipt' value='{$object["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <a id='taxpayerQualificationImgPreview_a' href='__ROOT__/{$object["taxpayerQualificationImg"]}' target='_blank'> + <img id='taxpayerQualificationImgPreview' src='__ROOT__/{$object["taxpayerQualificationImg"]}' width='150'> + </a> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>结算账号信息</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='ipt' maxlength='50' data-rule='纳税人识别号:required;' value='{$object["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='ipt' maxlength='20' data-rule='对公结算银行账号:required;' value='{$object["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + </table> +</fieldset> +<fieldset class="layui-elem-field layui-field-title"> +<legend>申请状态</legend> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>处理结果<font color='red'>*</font>:</th> + <td class='layui-form'> + <label> + <input type='radio' class='ipt' name='applyStatus' value='2' {if $object['applyStatus']==2}checked{/if} onclick='javascript:WST.showHide(0,"#trApplyDesc")' data-rule="处理结果:checked" title='通过'> + </label> + <label> + <input type='radio' class='ipt' name='applyStatus' id='applyStatus-1' value='-1' {if $object['applyStatus']==-1}checked{/if} onclick='javascript:WST.showHide(1,"#trApplyDesc")' title='不通过'> + </label> + </td> + </tr> + <tr id='trApplyDesc' {if $object['applyStatus']==1}style='display:none'{/if}> + <th>不通过原因<font color='red'>*</font>:</th> + <td><textarea id='applyDesc' class='ipt' style='width:500px;height:100px;' maxLength='100' data-rule="不通过原因:required(#applyStatus-1:checked);">{$object['applyDesc']}</textarea></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:apply()'><i class="fa fa-check"></i>保存</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left" ></i>返回</button> + </td> + </tr> +</table> +</fieldset> +</form> +<script> +$(function(){initEdit({serviceStartTime:'{:date("H:i",strtotime($object["serviceStartTime"]))}',serviceEndTime:'{:date("H:i",strtotime($object["serviceEndTime"]))}',areaId:'{$object["areaId"]}',areaIdPath:'{$object["areaIdPath"]}',bankAreaId:'{$object["bankAreaId"]}',bankAreaIdPath:'{$object["bankAreaIdPath"]}',businessAreaPath:'{$object["businessAreaPath"]}'});}) +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/list.html b/hyhproject/admin/view/shops_back/list.html new file mode 100755 index 0000000..bece8cc --- /dev/null +++ b/hyhproject/admin/view/shops_back/list.html @@ -0,0 +1,36 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} + </select> + <input type="text" id="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + <select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> + </select> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + {if WSTGrant('DPGL_01')} + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + {/if} + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/list_apply.html b/hyhproject/admin/view/shops_back/list_apply.html new file mode 100755 index 0000000..c0b7f22 --- /dev/null +++ b/hyhproject/admin/view/shops_back/list_apply.html @@ -0,0 +1,34 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +<select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} +</select> +<input type="text" id="shopName" placeholder='店铺名称' class='j-ipt'/> +<input type="text" id="investmentStaff" placeholder='对接商城招商人' class='j-ipt'/> +<select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> +</select> +<button class="btn btn-primary" onclick='javascript:loadApplyGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initApplyGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/list_stop.html b/hyhproject/admin/view/shops_back/list_stop.html new file mode 100755 index 0000000..80620e3 --- /dev/null +++ b/hyhproject/admin/view/shops_back/list_stop.html @@ -0,0 +1,33 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <select id="areaId1" class='j-ipt j-areas' level="0" onchange="WST.ITAreas({id:'areaId1',val:this.value,className:'j-areas'});"> + <option value="">-商家所在地-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} + </select> + <input type="text" id="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> + <select id="isInvestment" class='j-ipt'> + <option value="-1">-是否招商推广-</option> + <option value="1">是</option> + <option value="0">否</option> + </select> + <button class="btn btn-primary" onclick='javascript:loadStopGrid(0)'><i class='fa fa-search'></i>查询</button> + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> +$(function(){initStopGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/shops.js b/hyhproject/admin/view/shops_back/shops.js new file mode 100755 index 0000000..7feb990 --- /dev/null +++ b/hyhproject/admin/view/shops_back/shops.js @@ -0,0 +1,491 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺编号', name:'shopSn', width: 30,sortable: true}, + {title:'店铺账号', name:'loginName',width: 60,sortable: true}, + {title:'店铺名称', name:'shopName',width: 120,sortable: true}, + {title:'店主姓名', name:'shopkeeper',width: 40,hidden: true,sortable: true}, + {title:'店主联系电话', name:'telephone',width: 30,hidden: true,sortable: true}, + {title:'店铺地址', name:'shopAddress',width:300 }, + {title:'所属公司', name:'shopCompany',width: 60,hidden: true}, + {title:'营业状态', name:'shopAtive' ,width: 20,sortable: true,renderer: function (val,item,rowIndex){ + return (item['shopAtive']==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 营业中</span>":"<span class='statu-wait'><i class='fa fa-coffee'></i> 休息中</span>"; + }}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.DPGL_02)h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.DPGL_03 && item['shopId']!=1)h += "<a class='btn btn-red' href='javascript:toDel(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + h += "<a class='btn btn-blue' href='"+WST.U('admin/logmoneys/tologmoneys','id='+item['shopId'])+"&type=1'><i class='fa fa-search'></i>商家资金</a>"; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/pageQuery'), fullWidthRows: true, autoLoad: true, + remoteSort:true , + sortName: 'shopSn', + sortStatus: 'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +function initApplyGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'申请人账号', name:'loginName', width: 30}, + {title:'店铺名称', name:'shopName',width:100 }, + {title:'所属公司', name:'shopCompany',width:100 }, + {title:'申请联系人', name:'applyLinkMan',width:30 }, + {title:'申请联系人电话', name:'applyLinkTel',width:30 }, + {title:'对接商城招商人员', name:'applyLinkTel' ,width:50,renderer: function (val,item,rowIndex){ + return (item['isInvestment']==1)?item['investmentStaff']:'-'; + }}, + {title:'申请日期', name:'applyTime' }, + {title:'申请状态', name:'applyStatus' ,width:30,renderer: function (val,item,rowIndex){ + if(item['applyStatus']==1){ + return "<span class='statu-wait'><i class='fa fa-clock-o'></i> 待处理</span>"; + }else if(item['applyStatus']==2){ + return "<span class='statu-yes'><i class='fa fa-check-circle'></i> 申请成功</span>"; + }else{ + return "<span class='statu-no'><i class='fa fa-ban'></i> 申请失败</span>"; + } + }}, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.DPSQ_04)h += "<a class='btn btn-blue' href='javascript:toHandle(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>操作</a> "; + if(item['applyStatus']==-1 || item['applyStatus'] == 1){ + if(WST.GRANT.DPSQ_03)h += "<a class='btn btn-red' href='javascript:toDelApply(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/pageQueryByApply'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadApplyGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +function toHandle(id){ + location.href = WST.U('admin/shops/toHandleApply','id='+id); +} +function toDelApply(id){ + var box = WST.confirm({content:"您确定要彻底删除该店铺申请信息吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/delApply'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function initStopGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'店铺编号', name:'shopSn', width: 30}, + {title:'店铺账号', name:'loginName', width: 60}, + {title:'店铺名称', name:'shopName',width: 120}, + {title:'店主姓名', name:'shopkeeper',width: 40,hidden: true}, + {title:'店主联系电话', name:'telephone',hidden: true}, + {title:'店铺地址', name:'shopAddress',width:350 }, + {title:'所属公司', name:'shopCompany',hidden: true }, + {title:'操作', name:'' ,width:80, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['shopId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + h += "<a class='btn btn-red' href='javascript:toDel(" + item['shopId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-85),indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/shops/pageStopQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadStopGrid(){ + var params = WST.getParams('.j-ipt'); + params.areaIdPath = WST.ITGetAllAreaVals('areaId1','j-areas').join('_'); + params.page = 1; + mmg.load(params); +} +var initTab2 = false,initTab3 = false; +function initUpload(isEdit){ + if(!isEdit){ + legalCertificateImgUpload(); + businessLicenceImgUpload(); + bankAccountPermitImgUpload(); + organizationCodeUpload(); + taxRegistrationCertificateUpload(); + taxpayerQualificationUpload(); + }else{ + var element = layui.element; + element.on('tab(msgTab)', function(data){ + if(data.index==1){ + if(initTab2)return; + initTab2 = true; + legalCertificateImgUpload(); + businessLicenceImgUpload(); + bankAccountPermitImgUpload(); + organizationCodeUpload(); + }else if(data.index==2){ + if(initTab3)return; + initTab3 = true; + taxRegistrationCertificateUpload(); + taxpayerQualificationUpload(); + } + }); + } +} +function legalCertificateImgUpload (){ + WST.upload({ + pick:'#legalCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#legalCertificateImgMsg').empty().hide(); + $('#legalCertificateImgPreview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb).show(); + $('#legalCertificateImgPreview_a').attr('href',WST.conf.ROOT+"/"+json.savePath+json.name); + $('#legalCertificateImg').val(json.savePath+json.name); + $('#msg_legalCertificateImg').hide(); + } + }, + progress:function(rate){ + $('#legalCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function businessLicenceImgUpload(){ + WST.upload({ + pick:'#businessLicenceImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#businessLicenceImgMsg').empty().hide(); + $('#businessLicenceImgPreview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb).show(); + $('#businessLicenceImgPreview_a').attr('href',WST.conf.ROOT+"/"+json.savePath+json.name); + $('#businessLicenceImg').val(json.savePath+json.name); + $('#msg_businessLicenceImg').hide(); + } + }, + progress:function(rate){ + $('#businessLicenceImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function bankAccountPermitImgUpload(){ + WST.upload({ + pick:'#bankAccountPermitImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#bankAccountPermitImgMsg').empty().hide(); + $('#bankAccountPermitImgPreview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb).show(); + $('#bankAccountPermitImgPreview_a').attr('href',WST.conf.ROOT+"/"+json.savePath+json.name); + $('#bankAccountPermitImg').val(json.savePath+json.name); + $('#msg_bankAccountPermitImg').hide(); + } + }, + progress:function(rate){ + $('#bankAccountPermitImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function organizationCodeUpload(){ + WST.upload({ + pick:'#organizationCodeImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#organizationCodeImgMsg').empty().hide(); + $('#organizationCodeImgPreview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb).show(); + $('#organizationCodeImgPreview_a').attr('href',WST.conf.ROOT+"/"+json.savePath+json.name); + $('#organizationCodeImg').val(json.savePath+json.name); + $('#msg_organizationCodeImg').hide(); + } + }, + progress:function(rate){ + $('#organizationCodeImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function taxRegistrationCertificateUpload(){ + var uploader = WST.upload({ + pick:'#taxRegistrationCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + fileNumLimit:3, + callback:function(f,file){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#taxRegistrationCertificateImgMsg').empty().hide(); + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'><a target='_blank' href='"+json.savePath+json.name+"'>"+ + "<img class='step_pic"+"' width='75' height='75' src='"+WST.conf.ROOT+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></a></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/wstmart/home/View/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#taxRegistrationCertificateImgBox').append(tdiv); + $('#msg_taxRegistrationCertificateImg').hide(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + if($('#taxRegistrationCertificateImgBox').children().size()<=0){ + $('#msg_taxRegistrationCertificateImg').show(); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#taxRegistrationCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function taxpayerQualificationUpload(){ + WST.upload({ + pick:'#taxpayerQualificationImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#taxpayerQualificationImgMsg').empty().hide(); + $('#taxpayerQualificationImgPreview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb).show(); + $('#taxpayerQualificationImgPreview_a').attr('href',WST.conf.ROOT+"/"+json.savePath+json.name); + $('#taxpayerQualificationImg').val(json.savePath+json.name); + $('#msg_taxpayerQualificationImg').hide(); + } + }, + progress:function(rate){ + $('#taxpayerQualificationImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function initEdit(opts){ + var laydate = layui.laydate; + laydate.render({elem: '#establishmentDate'}); + laydate.render({elem: '#businessStartDate'}); + laydate.render({elem: '#businessEndDate'}); + laydate.render({elem: '#legalCertificateStartDate'}); + laydate.render({elem: '#legalCertificateEndDate'}); + laydate.render({elem: '#organizationCodeStartDate'}); + laydate.render({elem: '#organizationCodeEndDate'}); + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#preview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb); + $('#shopImg').val(json.savePath+json.name); + $('#editFrom').validator('hideMsg', '#shopImg'); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',opts.serviceStartTime); + initTime('#serviceEndTime',opts.serviceEndTime); + if($('#shopId').val()>0){ + var areaIdPath = opts.areaIdPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas',isRequire:true} + WST.ITSetAreas(aopts); + if(opts.bankAreaIdPath!=''){ + var areaIdPath = opts.bankAreaIdPath.split("_"); + $('#barea_0').val(areaIdPath[0]); + var aopts = {id:'barea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-bareas',isRequire:true} + WST.ITSetAreas(aopts); + } + if(opts.businessAreaPath!=''){ + var areaIdPath = opts.businessAreaPath.split("_"); + $('#carea_0').val(areaIdPath[0]); + var aopts = {id:'carea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-careas',isRequire:false} + WST.ITSetAreas(aopts); + } + } + initUpload(opts.isEdit); +} +function delVO(obj){ + $(obj).parent().remove(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); +} +function toEdit(id){ + location.href=WST.U('admin/shops/toEdit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该店铺吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function checkLoginKey(obj){ + if($.trim(obj.value)=='')return; + var params = {key:obj.value,userId:0}; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/checkLoginKey'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status!='1'){ + WST.msg(json.msg,{icon:2}); + obj.value = ''; + } + }); +} +function save(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + params.businessAreaPath0 = WST.ITGetAreaVal('j-careas'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + if(params.shopStatus==1){ + location.href=WST.U('admin/shops/index'); + }else{ + location.href=WST.U('admin/shops/stopIndex'); + } + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function getUserByKey(){ + if($.trim($('#keyName').val())=='')return; + $('#keyNameBox').html(''); + $('#shopUserId').val(0); + var loading = WST.msg('正在查询用户信息...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/getUserByKey'),{key:$('#keyName').val()},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + $('#keyNameBox').html('用户:'+json.data.loginName); + $('#shopUserId').val(json.data.userId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function add(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + params.businessAreaPath0 = WST.ITGetAreaVal('j-careas'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/add'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + location.href=WST.U('admin/shops/index'); + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function apply(){ + $('#editFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + params.businessAreaPath0 = WST.ITGetAreaVal('j-careas'); + if(params.applyStatus==-1 && params.applyDesc==''){ + WST.msg('请输入审核不通过原因!',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/shops/handleApply'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:1000},function(){ + location.href=WST.U('admin/shops/apply'); + }); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function initTime($id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $($id).append(html.join('')); +} \ No newline at end of file diff --git a/hyhproject/admin/view/shops_back/view_apply.html b/hyhproject/admin/view/shops_back/view_apply.html new file mode 100755 index 0000000..5622008 --- /dev/null +++ b/hyhproject/admin/view/shops_back/view_apply.html @@ -0,0 +1,21 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/shops/shops.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> +店铺名称:<input type="text" name="shopName" placeholder='店铺名称' id="shopName" class='j-ipt'/> +是否招商推广: +<select id="isInvestment" class='ipt'> + <option value="">-请选择-</option> + <option value="1">是</option> + <option value="0">否</option> +</select> +<button class="btn btn-primary" onclick='javascript:loadApplyGrid(0)'><i class='fa fa-search'></i>查询</button> +<div style='clear:both'></div> +</div> +<div id="maingrid"></div> +<script> +$(function(){initApplyGrid();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/speccats/list.html b/hyhproject/admin/view/speccats/list.html new file mode 100755 index 0000000..16cf243 --- /dev/null +++ b/hyhproject/admin/view/speccats/list.html @@ -0,0 +1,71 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/speccats/speccats.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <div class="f-left"> + <div id="pcat_0_box" class="f-left"> + <select id="cat_0" class='ipt pgoodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:false,className:'pgoodsCats'});"> + <option value="">-所属商品分类-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </div> + <input type="text" id="keyName" placeholder="请输入规格名称"/> + <button class="btn btn-primary" onclick="loadGrid(0)"><i class='fa fa-search'></i>查询</button> + </div> + {if WSTGrant('SPGG_01')} + <button class="btn btn-success f-right" onclick="javascript:toEditCat(0);"><i class='fa fa-plus'></i>新增</button> + {/if} + <div style="clear:both"></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg layui-form"></div> +</div> +<div id="pg" style="text-align: right;"></div> +<div id='specCatsBox' style='display:none'> + <form id="specCatsForm"> + <input type='hidden' id='catId' class='ipt'/> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'> + 所属商品分类<font color='red'>*</font>:</th> + <td id="bcat_0_box"> + <select id="bcat_0" class='ipt goodsCats' level="0" onchange="WST.ITGoodsCats({id:'bcat_0',val:this.value,isRequire:false,className:'goodsCats'});" data-rule='所属商品分类:required;' data-target="#msg_bcat_0"> + <option value="">-请选择-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + <span class='msg-box' id='msg_bcat_0' style='color:red;'>(至少选择一个商品分类)</span> + </td> + </tr> + <tr> + <th>规格名称<font color='red'>*</font>:</th> + <td> + <input type="text" id="catName" name="catName" class="ipt" maxLength='20'/> + </td> + </tr> + <tr> + <th>是否允许上传图片<font color='red'> </font>:</th> + <td class='layui-form'> + <input type="checkbox" id="isAllowImg" name="isAllowImg" value="1" class="ipt" lay-skin="switch" lay-filter="isAllowImg" lay-text="是|否"> + <span style='color:red;margin-left:20px;'>(*同一分类下只能设置一个上传图片的规格分类)</span> + </td> + </tr> + <tr> + <th>是否显示<font color='red'> </font>:</th> + <td class='layui-form'> + <input type="checkbox" id="isShow" name="isShow" value="1" class="ipt" lay-skin="switch" lay-filter="isShow" lay-text="显示|隐藏"> + </td> + </tr> + </table> + </form> +</div> +{/block} diff --git a/hyhproject/admin/view/speccats/speccats.js b/hyhproject/admin/view/speccats/speccats.js new file mode 100755 index 0000000..305d1a6 --- /dev/null +++ b/hyhproject/admin/view/speccats/speccats.js @@ -0,0 +1,187 @@ +var mmg; +$(function(){ + var h = WST.pageHeight(); + var cols = [ + {title:'规格类型', name:'catName', width: 10}, + {title:'所属商品分类', name:'goodsCatNames', width: 300,renderer: function(val,item,rowIndex){ + return "<span ><p class='wst-nowrap'>"+item['goodsCatNames']+"</p></span>"; + }}, + {title:'是否允许上传图片', name:'isAllowImg', width: 10,renderer: function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 允许</span>":''; + }}, + {title:'是否显示', name:'attrVal', width: 10,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['isShow']==1)?"checked":"")+' id="isShow1" name="isShow1" value="1" class="ipt" lay-skin="switch" lay-filter="isShow1" data="'+item['catId']+'" lay-text="显示|隐藏">' + }}, + {title:'操作', name:'op' ,width:50, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(item.specId>0){ + if(WST.GRANT.SPGG_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+ item['catId']+"," + item['id'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.SPGG_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }else{ + if(WST.GRANT.SPGG_02)h += "<a class='btn btn-blue' href='javascript:toEditCat(" + item['id'] + ")' ><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.SPGG_03)h += "<a class='btn btn-red' href='javascript:toDelCat(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/speccats/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(data){ + layui.form.render(); + layui.form.on('switch(isShow1)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(id, 1); + }else{ + toggleIsShow(id, 0); + } + }); + }) +}) +//------------------规格类型---------------// +function toEditCat(catId){ + $("select[id^='bcat_0_']").remove(); + $('#specCatsForm').get(0).reset(); + $.post(WST.U('admin/speccats/get'),{catId:catId},function(data,textStatus){ + var json = WST.toAdminJson(data); + WST.setValues(json); + layui.form.render(); + if(json.goodsCatId>0){ + var goodsCatPath = json.goodsCatPath.split("_"); + $('#bcat_0').val(goodsCatPath[0]); + var opts = {id:'bcat_0',val:goodsCatPath[0],childIds:goodsCatPath,className:'goodsCats'} + WST.ITSetGoodsCats(opts); + } + var title =(catId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#specCatsBox'),area: ['750px', '260px'],btn:['确定','取消'], + end:function(){$('#specCatsBox').hide();},yes:function(){ + $('#specCatsForm').submit(); + }}); + $('#specCatsForm').validator({ + fields: { + 'catName': {rule:"required remote;",msg:{required:'请输入规格名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + params.goodsCatId = WST.ITGetGoodsCatVal('goodsCats'); + $.post(WST.U('admin/speccats/'+((params.catId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#specCatsBox').hide(); + loadGrid(); + layer.close(box); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + + }); +} + +function loadGrid(){ + var keyName = $("#keyName").val(); + var goodsCatPath = WST.ITGetAllGoodsCatVals('cat_0','pgoodsCats'); + mmg.load({"page":1,"keyName":keyName,"goodsCatPath":goodsCatPath.join('_')}); +} + +function toDelCat(catId){ + var box = WST.confirm({content:"您确定要删除该类型吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/speccats/del'),{catId:catId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function toggleIsShow( catId, isShow){ + $.post(WST.U('admin/speccats/setToggle'), {'catId':catId, 'isShow':isShow}, function(data, textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} + +//------------------规格---------------// +function toDel(specId){ + var box = WST.confirm({content:"您确定要删除该规格吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/specs/del'),{specId:specId},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function toEdit(catId,specId){ + $.post(WST.U('admin/specs/get'),{specId:specId},function(data,textStatus){ + var json = WST.toAdminJson(data); + $('#specForm').get(0).reset(); + WST.setValues(json); + + var title =(specId==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#specBox'),area: ['450px', '160px'],btn:['确定','取消'],yes:function(){ + $('#specForm').submit(); + }}); + $('#specForm').validator({ + rules: { + remote: function(el){ + return $.post(WST.U('admin/specs/checkSpecName'),{"specName":el.value,"catId":catId},function(data,textStatus){}); + } + }, + fields: { + 'specName': {rule:"required; remote;",msg:{required:'请输入规格名称'}}, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + params.catId = catId; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/specs/'+((specId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + $('#specForm')[0].reset(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + }); +} diff --git a/hyhproject/admin/view/staffs/add.html b/hyhproject/admin/view/staffs/add.html new file mode 100755 index 0000000..5e87016 --- /dev/null +++ b/hyhproject/admin/view/staffs/add.html @@ -0,0 +1,106 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}' type="text/javascript"></script> +<script src="__ADMIN__/staffs/staffs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form autocomplete='off'> +<input type='hidden' id='staffId' class='ipt' value="{$object['staffId']}"/> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>登录账号<font color='red'>*</font>:</th> + <td width='300'><input type="text" id='loginName' class='ipt' maxLength='20' data-rule="登录账号: required;" onblur='javascript:checkLoginKey(this)'/></td> + <td rowspan='5'> + <div style='border:1px solid #ccc;width:130px;height:130px;margin-bottom:5px;'> + <img id='prevwPhoto' height='130' height='130' src='__ADMIN__/img/img_mrtx_gly.png'/> + </div> + <div id='photoPicker' style='margin-left:32px;'>上传头像<span id='uploadMsg'></span></div> + <input type='hidden' id='staffPhoto' class='ipt' value=''/> + </td> + </tr> + <tr> + <th width='120'>登录密码<font color='red'>*</font>:</th> + <td><input type="text" id='loginPwd' class='ipt' maxLength='20' data-rule="登录密码: required;"/></td> + </tr> + <tr> + <th>职员名称<font color='red'>*</font>:</th> + <td><input type="text" id='staffName' class='ipt' maxLength='20' data-rule="职员名称: required;"/></td> + </tr> + <tr> + <th>职员编号:</th> + <td><input type="text" id='staffNo' class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th>角色:</th> + <td> + <select id='staffRoleId' class='ipt'> + <option value='0'>请选择</option> + {volist name="roles" id="vo"} + <option value="{$vo['roleId']}">{$vo.roleName}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>手机号码:</th> + <td><input type="text" id='staffPhone' class='ipt' maxLength='11' data-rule="mobile"/></td> + </tr> + <tr> + <th>微信OPENID:</th> + <td><input type="text" id='wxOpenId' class='ipt' maxLength='100'/></td> + </tr> + <tr> + <th>工作状态:</th> + <td colspan='2' class="layui-form"> + <label> + <input id="workStatus1" name="workStatus" value="1" class='ipt' {if condition="$object['workStatus'] == 1"}checked{/if} type="radio" title='在职'> + </label> + <label> + <input id="workStatus0" name="workStatus" value="0" class='ipt' {if condition="$object['workStatus'] == 0"}checked{/if} type="radio" title='离职'> + </label> + + </td> + </tr> + <tr> + <th>账号状态:</th> + <td colspan='2' class="layui-form"> + <label> + <input type='radio' id='staffStatus1' class='ipt' name='staffStatus' {if condition="$object['staffStatus'] == 1"}checked{/if} value='1' title='开启'> + </label> + <label> + <input type='radio' id='staffStatus0' class='ipt' name='staffStatus' {if condition="$object['staffStatus'] == 0"}checked{/if} value='0' title='停用'> + </label> + </td> + </tr> + <tr> + <td colspan='3' align='center' class='wst-bottombar'> + <button type="button" onclick='javascript:save()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="button" onclick='javascript:history.go(-1)' class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ + WST.upload({ + pick:'#photoPicker', + formData: {dir:'staffs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#prevwPhoto').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.name); + $('#staffPhoto').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/staffs/edit.html b/hyhproject/admin/view/staffs/edit.html new file mode 100755 index 0000000..383f630 --- /dev/null +++ b/hyhproject/admin/view/staffs/edit.html @@ -0,0 +1,102 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}' type="text/javascript"></script> +<script src="__ADMIN__/staffs/staffs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form autocomplete='off'> +<input type='hidden' id='staffId' class='ipt' value="{$object['staffId']}"/> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>登录账号:</th> + <td width='300'>{$object['loginName']}</td> + <td rowspan='5'> + <div style='border:1px solid #ccc;width:130px;height:130px;margin-bottom:5px;'> + <img id='prevwPhoto' height='130' width='130' src='__IMGURL__/{if $object["staffPhoto"] != " " }{$object["staffPhoto"]} {else}__ADMIN__/img/img_mrtx_gly.png{/if}'/> + </div> + <div id='photoPicker' style='margin-left:32px;'>上传头像<span id='uploadMsg'></span></div> + <input type='hidden' id='staffPhoto' class='ipt' value='{$object["staffPhoto"]}'/> + </td> + </tr> + <tr> + <th>职员名称<font color='red'>*</font>:</th> + <td><input type="text" id='staffName' class='ipt' value="{$object['staffName']}" maxLength='20' data-rule="职员名称: required;"/></td> + </tr> + <tr> + <th>职员编号:</th> + <td><input type="text" id='staffNo' class='ipt' value="{$object['staffNo']}" maxLength='20'/></td> + </tr> + <tr> + <th>角色:</th> + <td> + <select id='staffRoleId' class='ipt'> + <option value='0'>请选择</option> + {volist name="roles" id="vo"} + <option value="{$vo['roleId']}" {if condition="$object['staffRoleId'] == $vo['roleId']"}selected{/if}>{$vo.roleName}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>手机号码:</th> + <td><input type="text" id='staffPhone' class='ipt' maxLength='100' data-rule="mobile" value="{$object['staffPhone']}"/></td> + </tr> + <tr> + <th>微信OPENID:</th> + <td><input type="text" id='wxOpenId' class='ipt' maxLength='100' value="{$object['wxOpenId']}"/></td> + </tr> + <tr> + <th>工作状态:</th> + <td class="layui-form"> + <label> + <input id="workStatus1" name="workStatus" value="1" class='ipt' {if condition="$object['workStatus'] == 1"}checked{/if} type="radio" title='在职'> + </label> + <label> + <input id="workStatus0" name="workStatus" value="0" class='ipt' {if condition="$object['workStatus'] == 0"}checked{/if} type="radio" title='离职'> + </label> + + </td> + </tr> + <tr> + <th>账号状态:</th> + <td colspan='2' class="layui-form"> + <label> + <input type='radio' id='staffStatus1' class='ipt' name='staffStatus' {if condition="$object['staffStatus'] == 1"}checked{/if} value='1' title='开启'> + </label> + <label> + <input type='radio' id='staffStatus0' class='ipt' name='staffStatus' {if condition="$object['staffStatus'] == 0"}checked{/if} value='0' title='停用'> + </label> + </td> + </tr> + <tr> + <td colspan='3' align='center' class='wst-bottombar'> + <button type="button" onclick='javascript:save()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="button" onclick='javascript:history.go(-1)' class='btn'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ + WST.upload({ + pick:'#photoPicker', + formData: {dir:'staffs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#prevwPhoto').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.name); + $('#staffPhoto').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/staffs/list.html b/hyhproject/admin/view/staffs/list.html new file mode 100755 index 0000000..d9d82e3 --- /dev/null +++ b/hyhproject/admin/view/staffs/list.html @@ -0,0 +1,45 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/staffs/staffs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>该功能主要用于设置商城职员信息,可以对职员的操作权限,账号,密码等进行设置。</li> + </ul> +</div> +<div class="wst-toolbar"> + <input id='key' type='text' class='form-control' placeholder='账号/姓名/编号'> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> + {if WSTGrant('ZYGL_01')} + <button class="btn btn-success f-right" onclick='javascript:toEdit(0)'><i class='fa fa-plus'></i>新增</button> + {/if} + <div style='clear:both'></div> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<div id='editPassBox' style='display:none;padding-top:5px;'> + <form id='editPassFrom' autocomplete="off"> + <table class='wst-form'> + <tr> + <th>新密码:</th> + <td><input type='password' id='newPass' name='newPass' class='ipt' data-rule="新密码: required;length[6~]" maxLength='16'/></td> + </tr> + <tr> + <th>确认密码:</th> + <td><input type='password' id='newPass2' name='newPass2' class='ipt' data-rule="确认密码: required;match(newPass);" maxLength='16'/></td> + </tr> + </table> + </form> +</div> +<script> +$(function(){initGrid({$Think.session.WST_STAFF.staffId});}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/staffs/staffs.js b/hyhproject/admin/view/staffs/staffs.js new file mode 100755 index 0000000..beb7fe1 --- /dev/null +++ b/hyhproject/admin/view/staffs/staffs.js @@ -0,0 +1,109 @@ +var mmg; +function initGrid(staffId){ + var h = WST.pageHeight(); + var cols = [ + {title:'职员账号', name:'loginName', width: 60}, + {title:'职员名称', name:'staffName' ,width:60}, + {title:'职员角色', name:'roleName' ,width:50}, + {title:'职员编号', name:'staffNo' ,width:30}, + {title:'工作状态', name:'workStatus' ,width:20,renderer: function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 在职</span>":"<span class='statu-no'><i class='fa fa-ban'></i> 离职</span>"; + }}, + {title:'登录时间', name:'lastTime' ,width:100}, + {title:'登录IP', name:'lastIP' ,width:60}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.ZYGL_02)h += "<a class='btn btn-blue' onclick='javascript:toEditPass(" + item['staffId'] + ")'><i class='fa fa-key'></i>修改密码</a> "; + if(WST.GRANT.ZYGL_02)h += "<a class='btn btn-blue' onclick='javascript:toEdit(" + item['staffId'] + ")'><i class='fa fa-pencil'></i>修改</a> "; + if(item['staffId']!=1 && item['staffId']!=staffId && WST.GRANT.ZYGL_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['staffId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: (h-155),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/staffs/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + var diff = v?155:128; + mmg.resize({height:h-diff}) + }}); +} +function loadGrid(){ + mmg.load({page:1,key:$('#key').val()}); +} +function toEdit(id){ + location.href=WST.U('admin/staffs/'+((id==0)?'toAdd':'toEdit'),'id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该职员吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/staffs/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + loadGrid(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function checkLoginKey(obj){ + if($.trim(obj.value)=='')return; + var params = {key:obj.value,userId:0}; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/staffs/checkLoginKey'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status!='1'){ + WST.msg(json.msg,{icon:2}); + obj.value = ''; + } + }); +} +function save(){ + var params = WST.getParams('.ipt'); + if(params.staffId==0){ + if(!$('#loginName').isValid())return; + if(!$('#loginPwd').isValid())return; + } + if(!$('#staffName').isValid())return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/staffs/'+((params.staffId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('admin/staffs/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function toEditPass(id){ + var w = WST.open({type: 1,title:"修改密码",shade: [0.6, '#000'],border: [0],content:$('#editPassBox'),area: ['450px', '200px'], + btn: ['确定', '取消'],end:function(){$('#editPassBox').hide();},yes: function(index, layero){ + $('#editPassFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + params.staffId = id; + var ll = WST.msg('数据处理中,请稍候...'); + $.post(WST.U('admin/Staffs/editPass'),params,function(data){ + layer.close(ll); + var json = WST.toAdminJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + layer.close(w); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + }}) + } + }); +} diff --git a/hyhproject/admin/view/styles/index.html b/hyhproject/admin/view/styles/index.html new file mode 100755 index 0000000..0ac3581 --- /dev/null +++ b/hyhproject/admin/view/styles/index.html @@ -0,0 +1,40 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/styles/styles.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + {volist name="$cats" id='vo'} + <li {if condition="$key==0"}class="layui-this"{/if} onclick="listQuery('{$vo['styleSys']}')">{$vo['styleSys']}</li> + {/volist} + </ul> + <div class="layui-tab-content" style="padding: 10px 0;"> + {volist name="$cats" id='vo'} + <div id="style_{$vo['styleSys']}" class="layui-tab-item {if condition="$key==0"}layui-show{/if}"> + </div> + {/volist} + </div> +</div> +<script id="tblist" type="text/html"> +{{# var dl = d['list'];for(var i = 0; i < dl.length; i++){ }} +<div class='style-box'> + <div class='style-img'> + <a href='#'> + <img src='__ROOT__/hyhproject//{{d["sys"]}}/view/{{dl[i]["stylePath"]}}/img/screenshot.png'/> + </a> + </div> + <div class='style-txt'>标题:{{dl[i]['styleName']}}</div> + <div class='style-author'>作者:{{dl[i]['styleAuthor']}}</div> + <div class='style-author'>介绍:{{# if(dl[i]['styleShopSite']!=''){}}<a target='_blank' href='{{dl[i]['styleShopSite']}}'>访问网址</a>{{# }else{ }}无{{#}}}</div> + <div class='style-op'> + {{# if(dl[i]['isUse']==1){}} + <button class='btn btn-disabled style_{{dl[i]['id']}}' dataid='{{dl[i]['id']}}' type='button' disabled><i class='fa fa-check-circle'></i>应用中</button> + {{# }else{ }} + <button class='btn btn-success style_{{dl[i]['id']}}' dataid='{{dl[i]['id']}}' type='button'><i class='fa fa-check-circle'></i>启用</button> + {{# } }} + </div> +</div> +{{#}}} +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/styles/styles.js b/hyhproject/admin/view/styles/styles.js new file mode 100755 index 0000000..12bdea2 --- /dev/null +++ b/hyhproject/admin/view/styles/styles.js @@ -0,0 +1,38 @@ +var laytpl = layui.laytpl; +$(function (){ + listQuery('home'); +}); +function listQuery(styleSys){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/styles/listQueryBySys'),{styleSys:styleSys},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data, function(html){ + $('#style_'+styleSys).html(html); + }); + $('.btn').click(function(){ + changeStyle($(this),$(this).attr('dataid')); + }); + } + }); +} +function changeStyle(obj,id){ + if(obj.hasClass('btn-disabled'))return; + var box = WST.confirm({content:"您确定要使用这套风格吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/styles/changeStyle'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + $('.btn-disabled').attr('disabled',false).val('启用').addClass('btn-success').removeClass('btn-disabled'); + $('.style_'+id).removeClass('btn-success').addClass('btn-disabled').attr('disabled',true).val('应用中'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config0.html b/hyhproject/admin/view/sysconfigs/config0.html new file mode 100755 index 0000000..29943d4 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config0.html @@ -0,0 +1,157 @@ +<?php $grant = WSTGrant('SCPZ_02'); ?> + +<div class="layui-tab-item layui-show layui-form"> + + <table class='wst-form wst-box-top'> + + <tr> + + <th width='150'>商城名称:</th> + + <td><input type="text" id='mallName' class='ipt' value="{$object['mallName']}" maxLength='100' placeholder='对外的简称'/></td> + + </tr> + + <tr> + + <th width='150'>商城特色介绍:</th> + + <td><input type="text" id='mallSlogan' class='ipt' style='width:70%' value="{$object['mallSlogan']}" maxLength='50' placeholder='商城特色短语介绍'/></td> + + </tr> + + <tr> + + <th>商城开关:</th> + + <td> + + <input type="checkbox" {if $object['seoMallSwitch']==1}checked{/if} value='1' class="ipt" id="seoMallSwitch" name="seoMallSwitch" lay-skin="switch" lay-filter="seoMallSwitch" lay-text="开|关"> + + </td> + + </tr> + + <tr id="close" {if $object['seoMallSwitch']==1}style="display:none;"{/if}> + + <th width='150'>商城关闭原因:</th> + + <td><input type="text" id='seoMallSwitchDesc' class='ipt' style='width:70%' value="{$object['seoMallSwitchDesc']}" maxLength='50' placeholder='原因'/></td> + + </tr> + + <tr> + + <th>商品是否需要审核:</th> + + <td> + + <input type="checkbox" {if $object['isGoodsVerify']==1}checked{/if} class="ipt" value='1' id="isGoodsVerify" name="isGoodsVerify" lay-skin="switch" lay-filter="isGoodsVerify" lay-text="是|否"> + + </td> + + </tr> + + <tr> + + <th>底部设置:</th> + + <td> + + <textarea id='mallFooter' class='ipt' placeholder='显示在网站最底部的内容'>{$object['mallFooter']}</textarea> + + </td> + + </tr> + + <tr> + + <th>访问统计:</th> + + <td><textarea id='visitStatistics' class='ipt' placeholder='用于统计网站访问信息的代码'>{$object['visitStatistics']}</textarea></td> + + </tr> + + <tr> + + <th>客服QQ设置:</th> + + <td><input type="text" id='serviceQQ' class='ipt' value="{$object['serviceQQ']}" maxLength='200' placeholder='显示在网站的客服QQ好,多个QQ以,号分割'/></td> + + </tr> + + <tr> + + <th>联系电话:</th> + + <td><input type="text" id='serviceTel' class='ipt' value="{$object['serviceTel']}" maxLength='200' placeholder="显示在网站的联系电话"/></td> + + </tr> + + <tr> + + <th>联系邮箱:</th> + + <td><input type="text" id='serviceEmail' class='ipt' value="{$object['serviceEmail']}" maxLength='200' placeholder="显示在网站的联系邮箱"/></td> + + </tr> + + <tr> + + <th>热搜关键词:</th> + + <td><input type="text" id='hotWordsSearch' class='ipt' value="{$object['hotWordsSearch']}" maxLength='100' placeholder='商城搜索栏下的引导搜索词' style='width:70%'/></td> + + </tr> + + <tr> + + <th>热搜广告词(商品):</th> + + <td><input type="text" id='adsGoodsWordsSearch' class='ipt' value="{$object['adsGoodsWordsSearch']}" maxLength='100' placeholder='商城搜索栏里的搜索词' style='width:70%'/></td> + + </tr> + + <tr> + + <th>热搜广告词(店铺):</th> + + <td><input type="text" id='adsShopWordsSearch' class='ipt' value="{$object['adsShopWordsSearch']}" maxLength='100' placeholder='商城搜索栏里的搜索词' style='width:70%'/></td> + + </tr> + + <tr> + + <th>账号禁用关键字:</th> + + <td><textarea id='registerLimitWords' class='ipt' placeholder='禁止用户注册时的账号内容'>{$object['registerLimitWords']}</textarea></td> + + </tr> + + <tr> + + <th>禁用关键字:</th> + + <td><textarea id='limitWords' class='ipt' placeholder='禁止用户发布的商品、评价内容'>{$object['limitWords']}</textarea></td> + + </tr> + + {if ($grant)} + + <tr> + + <td colspan='2' align='center'> + + <button type="button" onclick='javascript:edit()' style='margin-right:15px;' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + + </td> + + </tr> + + {/if} + + </table> + +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config1.html b/hyhproject/admin/view/sysconfigs/config1.html new file mode 100755 index 0000000..962368c --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config1.html @@ -0,0 +1,69 @@ +<div class="layui-tab-item layui-form"> + <fieldset class="layui-elem-field layui-field-title"> + <legend>邮件服务器设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>SMTP服务器:</th> + <td><input type="text" id='mailSmtp' class='ipt' maxLength='100' value='{$object["mailSmtp"]}'/></td> + </tr> + <tr> + <th>SMTP端口:</th> + <td><input type="text" id='mailPort' class='ipt' maxLength='10' value='{$object["mailPort"]}'/></td> + </tr> + <tr> + <th>是否验证SMTP:</th> + <td> + <input type="checkbox" {if $object['mailAuth']==1}checked{/if} class="ipt" id="mailAuth" name="mailAuth" value='1' lay-skin="switch" lay-filter="mailAuth" lay-text="是|否"> + </td> + </tr> + <tr> + <th>SMTP发件人邮箱:</th> + <td><input type="text" id='mailAddress' class='ipt' value='{$object["mailAddress"]}' maxLength='100'/></td> + </tr> + <tr> + <th>SMTP登录账号:</th> + <td><input type="text" id='mailUserName' class='ipt' value='{$object["mailUserName"]}' maxLength='100'/></td> + </tr> + <tr> + <th>SMTP登录密码:</th> + <td><input type="text" id='mailPassword' class='ipt' value='{$object["mailPassword"]}' maxLength='100'/></td> + </tr> + <tr> + <th>发件人名称:</th> + <td><input type="text" id='mailSendTitle' class='ipt' value='{$object["mailSendTitle"]}' maxLength='100'/></td> + </tr> + </table> + </fieldset> + <fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;"> + <legend>短信服务器设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th colspan='2' style='text-align:left;padding-left:40px'><span style='color:gray;'>(请确保在“拓展管理-插件管理"中有安装相应的短信插件”)</span></th> + </tr> + <tr style='display:none'> + <th >开启手机验证:</th> + <td> + <input type="checkbox" checked class="ipt" id="smsOpen" value='1' name="smsOpen" value='1' lay-skin="switch" lay-filter="smsOpen" lay-text="开|关"> + </td> + </tr> + <tr> + <th width='150'>每个号码每日发送数:</th> + <td><input type="text" id='smsLimit' class='ipt' value="{$object['smsLimit']}" maxLength='100'/></td> + </tr> + <tr> + <th>开启短信发送验证码:</th> + <td> + <input type="checkbox" {if $object['smsVerfy']==1}checked{/if} class="ipt" id="smsVerfy" value='1' name="smsVerfy" value='1' lay-skin="switch" lay-filter="smsVerfy" lay-text="开|关"> + </td> + </tr> + {if ($grant)} + <tr> + <td colspan='2' align='center'> + <button type="button" onclick='javascript:edit()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + {/if} + </table> + </fieldset> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config2.html b/hyhproject/admin/view/sysconfigs/config2.html new file mode 100755 index 0000000..ad44169 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config2.html @@ -0,0 +1,174 @@ +<div class="layui-tab-item layui-form"> + <fieldset class="layui-elem-field layui-field-title"> + <legend>订单设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>开启积分支付:</th> + <td> + <input type="checkbox" {if $object['isOpenScorePay']==1}checked{/if} class="ipt" id="isOpenScorePay" name="isOpenScorePay" value='1' lay-skin="switch" lay-filter="isOpenScorePay" lay-text="开|关"> + </td> + </tr> + <tr id='scoreToMoneyTr' {if $object['isOpenScorePay']==0}style='display:none'{/if}> + <th>积分兑换金额:</th> + <td> + 积分支付时<input type="text" id='scoreToMoney' class='ipt' value="{$object['scoreToMoney']}" maxLength='5' style='width:60px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>个积分抵1个金额 + </td> + </tr> + <tr> + <th>开启下单获积分:</th> + <td> + <input type="checkbox" {if $object['isOrderScore']==1}checked{/if} class="ipt" id="isOrderScore" name="isOrderScore" value='1' lay-skin="switch" lay-filter="isOrderScore" lay-text="开|关"> + </td> + </tr> + <tr id='moneyToScoreTr' {if $object['isOrderScore']==0}style='display:none'{/if}> + <th>金额兑换积分:</th> + <td> + 下单后订单金额1元可获得<input type="text" id='moneyToScore' class='ipt' value="{$object['moneyToScore']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/>个积分 + <span style='color:gray;'> + </span> + </td> + </tr> + <tr> + <th>开启评价获积分:</th> + <td> + <input type="checkbox" {if $object['isAppraisesScore']==1}checked{/if} class="ipt" id="isAppraisesScore" name="isAppraisesScore" value='1' lay-skin="switch" lay-filter="isAppraisesScore" lay-text="开|关"> + </td> + </tr> + <tr id='appraisesScoreTr' {if $object['isAppraisesScore']==0}style='display:none'{/if}> + <th>评价获得积分:</th> + <td> + <input type="text" id='appraisesScore' class='ipt' value="{$object['appraisesScore']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/>个积分 + <span style='color:gray;'> + </span> + </td> + </tr> + <tr> + <tr> + <th>结算方式:</th> + <td> + <label> + <input type='radio' id='statementType' name='statementType' class='ipt' value='0' {if $object['statementType']==0}checked{/if} title='即时结算'> + </label> + <label> + <input type='radio' id='statementType' name='statementType' class='ipt' value='1' {if $object['statementType']==1}checked{/if} title='统一结算'> + </label> + <span style='color:gray;'>(即时结算指用户确认收货就把钱打到商家钱包,统一结算指系统定时结算或者商家管理员手工结算) + </span> + </td> + </tr> + <tr style='display:none'> + <th>积分与金钱兑换比例:</th> + <td><input type="text" id='scoreCashRatio' class='ipt' value="{$object['scoreCashRatio']}" maxLength='20'/></td> + </tr> + <tr style='display:none'> + <th>结算金额设置:</th> + <td><input type="text" id='settlementStartMoney' class='ipt' value="{$object['settlementStartMoney']}" maxLength='10'/></td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>积分设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>开启积分签到:</th> + <td> + <input type="checkbox" {if $object['signScoreSwitch']==1}checked{/if} class="ipt" id="signScoreSwitch" name="signScoreSwitch" value='1' lay-skin="switch" lay-filter="signScoreSwitch" lay-text="开|关"> + </td> + </tr> + <tr id="signScore" {if $object['signScoreSwitch']==0}style="display:none;"{/if}> + <th>累计签到获得的积分:</th> + <td>&nbsp;</td> + </tr> + <tr id="signScores" {if $object['signScoreSwitch']==0}style="display:none;"{/if}> + <th></th> + <td> + <table><tbody> + <tr> + <th>第1天:</th><td><input type="text" id='signScore0' class='ipt' value="{$object['signScore0']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第2天:</th><td><input type="text" id='signScore1' class='ipt' value="{$object['signScore1']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第3天:</th><td><input type="text" id='signScore2' class='ipt' value="{$object['signScore2']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第4天:</th><td><input type="text" id='signScore3' class='ipt' value="{$object['signScore3']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第5天:</th><td><input type="text" id='signScore4' class='ipt' value="{$object['signScore4']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第6天:</th><td><input type="text" id='signScore5' class='ipt' value="{$object['signScore5']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第7天:</th><td><input type="text" id='signScore6' class='ipt' value="{$object['signScore6']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第8天:</th><td><input type="text" id='signScore7' class='ipt' value="{$object['signScore7']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第9天:</th><td><input type="text" id='signScore8' class='ipt' value="{$object['signScore8']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第10天:</th><td><input type="text" id='signScore9' class='ipt' value="{$object['signScore9']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第11天:</th><td><input type="text" id='signScore10' class='ipt' value="{$object['signScore10']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第12天:</th><td><input type="text" id='signScore11' class='ipt' value="{$object['signScore11']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第13天:</th><td><input type="text" id='signScore12' class='ipt' value="{$object['signScore12']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第14天:</th><td><input type="text" id='signScore13' class='ipt' value="{$object['signScore13']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第15天:</th><td><input type="text" id='signScore14' class='ipt' value="{$object['signScore14']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第16天:</th><td><input type="text" id='signScore15' class='ipt' value="{$object['signScore15']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第17天:</th><td><input type="text" id='signScore16' class='ipt' value="{$object['signScore16']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第18天:</th><td><input type="text" id='signScore17' class='ipt' value="{$object['signScore17']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第19天:</th><td><input type="text" id='signScore18' class='ipt' value="{$object['signScore18']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第20天:</th><td><input type="text" id='signScore19' class='ipt' value="{$object['signScore19']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第21天:</th><td><input type="text" id='signScore20' class='ipt' value="{$object['signScore20']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第22天:</th><td><input type="text" id='signScore21' class='ipt' value="{$object['signScore21']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第23天:</th><td><input type="text" id='signScore22' class='ipt' value="{$object['signScore22']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第24天:</th><td><input type="text" id='signScore23' class='ipt' value="{$object['signScore23']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第25天:</th><td><input type="text" id='signScore24' class='ipt' value="{$object['signScore24']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第26天:</th><td><input type="text" id='signScore25' class='ipt' value="{$object['signScore25']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第27天:</th><td><input type="text" id='signScore26' class='ipt' value="{$object['signScore26']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第28天:</th><td><input type="text" id='signScore27' class='ipt' value="{$object['signScore27']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第29天:</th><td><input type="text" id='signScore28' class='ipt' value="{$object['signScore28']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第30天:</th><td><input type="text" id='signScore29' class='ipt' value="{$object['signScore29']}" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr><span style='color:gray;'>(单位(个),必须第1天大于0才能签到,填写为空则为0;填写第1天为0则保存所有为0;填写中间位或最后位为零则取前一天积分,类推取得不为0的积分)</tr> + </tbody></table> + </td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>提现设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>用户提现设置:</th> + <td>至少<input type="text" id='drawCashUserLimit' class='ipt' value="{$object['drawCashUserLimit']}" maxLength='10' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>元以上方能申请提现。</td> + </tr> + <tr> + <th>商家提现设置:</th> + <td>至少<input type="text" id='drawCashShopLimit' class='ipt' value="{$object['drawCashShopLimit']}" maxLength='10' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>元以上方能申请提现。</td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>定时设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>未支付订单失效时间:</th> + <td>下单后<input type="text" id='autoCancelNoPayDays' class='ipt' value="{$object['autoCancelNoPayDays']}" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>小时</td> + </tr> + <tr> + <th>自动收货期限:</th> + <td>发货后<input type="text" id='autoReceiveDays' class='ipt' value="{$object['autoReceiveDays']}" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>天自动收货</td> + </tr> + <tr> + <th>自动评价期限:</th> + <td>确认收货后<input type="text" id='autoAppraiseDays' class='ipt' value="{$object['autoAppraiseDays']}" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>天自动好评</td> + </tr> + {if ($grant)} + <tr> + <td colspan='2' align='center'> + <button type="button" onclick='javascript:edit()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + {/if} + </table> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config3.html b/hyhproject/admin/view/sysconfigs/config3.html new file mode 100755 index 0000000..76fcbcf --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config3.html @@ -0,0 +1,29 @@ +<div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>密码加密传输:</th> + <td><input type="checkbox" {if $object['isCryptPwd']==1}checked{/if} value='1' class="ipt" id="isCryptPwd" name="isCryptPwd" lay-skin="switch" lay-filter="isCryptPwd" lay-text="开|关"><span style='color:gray;margin-left:5px;'>开启则用户登录、支付密码加密后再进行提交。<font color='red'>注意:该功能需开启openssl扩展支持!</font></span> + </td> + </tr> + <tr class='pwdCryptKeyTr' {if $object['isCryptPwd']==0}style='display:none'{/if}> + <th width='150'>商城密匙:</th> + <td> + <textarea id='pwdPrivateKey' style='height:250px' class="ipt" placeholder='请输入用于登录、支付密码加密传输的密匙,请勿留空'>{$object['pwdPrivateKey']}</textarea> + </td> + </tr> + <tr class='pwdCryptKeyTr' {if $object['isCryptPwd']==0}style='display:none'{/if}> + <th width='150'>Modulus:</th> + <td> + <textarea id='pwdModulusKey' class="ipt" placeholder='请输入用于登录、支付密码加密传输的16进制公钥,请勿留空'>{$object['pwdModulusKey']}</textarea> + </td> + </tr> + {if ($grant)} + <tr> + <td colspan='2' align="center"> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + {/if} + </table> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config4.html b/hyhproject/admin/view/sysconfigs/config4.html new file mode 100755 index 0000000..bfe2660 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config4.html @@ -0,0 +1,113 @@ +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/colpick/css/colpick.css" /> +<script src="__STATIC__/plugins/colpick/js/colpick.js"></script> +<div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th>水印位置:</th> + <td> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="0" {if ($object['watermarkPosition']==0)}checked{/if} title='无'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="1" {if ($object['watermarkPosition']==1)}checked{/if} title='左上'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="3" {if ($object['watermarkPosition']==3)}checked{/if} title='右上'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="5" {if ($object['watermarkPosition']==5)}checked{/if} title='居中'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="7" {if ($object['watermarkPosition']==7)}checked{/if} title='左下'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="9" {if ($object['watermarkPosition']==9)}checked{/if} title='右下'/></label> + <span style="color:gray;">设置为"无"则视为关闭水印</span> + </td> + </tr> + <tr> + <th width='150'>水印文字:</th> + <td> + <input type="text" id='watermarkWord' class='ipt' value="{$object['watermarkWord']}" maxLength='50' /> + <span style="color:gray;">当文字和图片同时存在时以文字为主</span> + </td> + </tr> + <tr> + <th>水印文字大小:</th> + <td> + <input type="text" id='watermarkSize' class='ipt' value="{$object['watermarkSize']}" maxLength='2'/> + <span style="color:gray;">建议大小为20</span> + </td> + </tr> + <tr> + <th>水印文字颜色:</th> + <td> + <input type="text" id='watermarkColor' class='ipt' value="{$object['watermarkColor']}" /> + <span style="color:gray;">仅支持16进制的颜色:如#00FF00</span> + </td> + </tr> + <tr> + <th>水印文字字体路径:</th> + <td> + <input type="text" id='watermarkTtf' class='ipt' value="{$object['watermarkTtf']}" placeholder="如:WSTMart/ttf/1.ttf" /> + <span style="color:gray;">后缀为.ttf,若留空则使用默认字体</span> + </td> + </tr> + <tr> + <th>水印文件:</th> + <td> + <div id='watermarkFilePicker'>上传图标</div><span id='watermarkFileMsg'></span> + <input type="hidden" id='watermarkFile' class='ipt' value="{$object['watermarkFile']}" /> + </td> + </tr> + <tr> + <th width='100'>水印图预览:</th> + <td> + <div style="min-height:70px;" id="preview"> + {if (isset($object['watermarkFile']))} + <img id='watermarkFilePrevw' src="__IMGURL__/{$object['watermarkFile']}" style="max-height:75px;" /> + {/if} + </div> + <span style="color:gray;">水印图最终大小由上传的图片大小决定</span> + </td> + </tr> + + <tr> + <th>水印透明度:</th> + <td> + <input type="text" id='watermarkOpacity' class='ipt' value="{$object['watermarkOpacity']}" /> + <br> + <span style="color:gray;">水印的透明度,可选值为0-100。当设置为100时则为不透明</span> + </td> + </tr> + <tr> + <th>商城Logo:</th> + <td> + <div id='mallLogoPicker'>请上传商城Logo</div><span id='mallLogoMsg'></span> + <img src='__IMGURL__/{$object["mallLogo"]}' width='120' hiegth='120' id='mallLogoPrevw'/> + <input type="hidden" id='mallLogo' class='ipt' value='{$object["mallLogo"]}'/> + </td> + </tr> + <tr> + <th>默认店铺头像:</th> + <td> + <div id='shopLogoPicker'>请上传默认店铺头像</div><span id='shopLogoMsg'></span> + <img src='__IMGURL__/{$object["shopLogo"]}' width='120' hiegth='120' id='shopLogoPrevw'/> + <input type="hidden" id='shopLogo' class='ipt' value='{$object["shopLogo"]}'/> + </td> + </tr> + <tr> + <th>默认会员头像:</th> + <td> + <div id='userLogoPicker'>请上传默认会员头像</div><span id='userLogoMsg'></span> + <img src='__IMGURL__/{$object["userLogo"]}' width='120' hiegth='120' id='userLogoPrevw'/> + <input type="hidden" id='userLogo' class='ipt' value='{$object["userLogo"]}'/> + </td> + </tr> + <tr> + <th>默认商品图片:</th> + <td> + <div id='goodsLogoPicker'>请上传默认商品图片</div><span id='goodsLogoMsg'></span> + <img src='__IMGURL__/{$object["goodsLogo"]}' width='120' hiegth='120' id='goodsLogoPrevw'/> + <input type="hidden" id='goodsLogo' class='ipt' value='{$object["goodsLogo"]}'/> + </td> + </tr> + {if ($grant)} + <tr> + <td colspan='2' align="center"> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + {/if} + </table> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config5.html b/hyhproject/admin/view/sysconfigs/config5.html new file mode 100755 index 0000000..bb650f8 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config5.html @@ -0,0 +1,24 @@ +<div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>商城标题:</th> + <td><input type="text" id='seoMallTitle' class='ipt' value="{$object['seoMallTitle']}" maxLength='100'/></td> + </tr> + <tr> + <th>商城关键字:</th> + <td><input type="text" id='seoMallKeywords' class='ipt' style='width:70%' value="{$object['seoMallKeywords']}" maxLength='100'/></td> + </tr> + <tr> + <th>商城描述:</th> + <td><input type="text" id='seoMallDesc' class='ipt' style='width:70%' value="{$object['seoMallDesc']}" maxLength='100'/></td> + </tr> + <tr> + {if ($grant)} + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button type="reset" class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + {/if} + </tr> + </table> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/config6.html b/hyhproject/admin/view/sysconfigs/config6.html new file mode 100755 index 0000000..37e4255 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/config6.html @@ -0,0 +1,152 @@ +<style> +.staffName label{width:120px;display:inline-block;} +.staffName label input[type='checkbox']{margin-right:5px;} +</style> +<div class="layui-tab-item staffName"> + <table class='wst-form wst-box-top'> + <tr> + <td colspan='2'> + <div id='alertTips' class='alert alert-success alert-tips fade in' style='margin:0px 0px'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>因微信通和短信通知会在事件发生的时候触发,请勿同时发送给太多人,以免造成提交延时影响用户体验。</li> + </ul> + </div> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>用户下单:</td> + </tr> + <tr> + <th width='150'>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxSubmitOrderTip' class='ipt' {if $object["wxSubmitOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxSubmitOrderTip,smsSubmitOrderTip","submitOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsSubmitOrderTip' class='ipt' {if $object["smsSubmitOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxSubmitOrderTip,smsSubmitOrderTip","submitOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt submitOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["submitOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>支付订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxPayOrderTip' class='ipt' {if $object["wxPayOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxPayOrderTip,smsPayOrderTip","payOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsPayOrderTip' class='ipt' {if $object["smsPayOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxPayOrderTip,smsPayOrderTip","payOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt payOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["payOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>取消订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxCancelOrderTip' class='ipt' {if $object["wxCancelOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxCancelOrderTip,smsCancelOrderTip","cancelOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsCancelOrderTip' class='ipt' {if $object["smsCancelOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxCancelOrderTip,smsCancelOrderTip","cancelOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt cancelOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["cancelOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>拒收订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxRejectOrderTip' class='ipt' {if $object["wxRejectOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxRejectOrderTip,smsRejectOrderTip","rejectOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsRejectOrderTip' class='ipt' {if $object["smsRejectOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxRejectOrderTip,smsRejectOrderTip","rejectOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt rejectOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["rejectOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>申请退款:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxRefundOrderTip' class='ipt' {if $object["wxRefundOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxRefundOrderTip,smsRefundOrderTip","refundOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsRefundOrderTip' class='ipt' {if $object["smsRefundOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxRefundOrderTip,smsRefundOrderTip","refundOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt refundOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["refundOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>订单投诉:</td> + </tr> + <tr> + <th>提示方式:</th> + <td> + <label><input type='checkbox' id='wxComplaintOrderTip' class='ipt' {if $object["wxComplaintOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxComplaintOrderTip,smsComplaintOrderTip","complaintOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsComplaintOrderTip' class='ipt' {if $object["smsComplaintOrderTip"]==1}checked{/if} onclick='javascript:checkTip("wxComplaintOrderTip,smsComplaintOrderTip","complaintOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt complaintOrderTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["complaintOrderTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>申请提现:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxCashDrawsTip' class='ipt' {if $object["wxCashDrawsTip"]==1}checked{/if} onclick='javascript:checkTip("wxCashDrawsTip,smsCashDrawsTip","cashDrawsTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsCashDrawsTip' class='ipt' {if $object["smsCashDrawsTip"]==1}checked{/if} onclick='javascript:checkTip("wxCashDrawsTip,smsCashDrawsTip","cashDrawsTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + {volist name='list' id='vo'} + <label class='staffName'><input type='checkbox' class='ipt cashDrawsTipUsers' value='{$vo['staffId']}' {if in_array($vo['staffId'],$object["cashDrawsTipUsers"])}checked{/if}/>{$vo['staffName']}</label> + {/volist} + </td> + </tr> + <tr> + {if ($grant)} + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button type="reset" class="btn" ><i class="fa fa-refresh"></i>重置</button> + </td> + {/if} + </tr> + </table> +</div> \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/dataConfigs.html b/hyhproject/admin/view/sysconfigs/dataConfigs.html new file mode 100755 index 0000000..1c5c21a --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/dataConfigs.html @@ -0,0 +1,33 @@ +<?php $grant = WSTGrant('SCPZ_02'); ?> + +<div class="layui-tab-item layui-show layui-form"> + + <table class='wst-form wst-box-top'> + <input type="hidden" id='isDataConfigs' class='ipt' value="1"> + {foreach $dataConfigs as $vo} + <tr> + <th width='350'>{$vo.fieldName}</th> + <td><input type="text" id='{$vo.configId}' class='ipt' value="{$vo.fieldValue}" maxLength='100' placeholder='{$vo.fieldName}'/></td> + </tr> + {/foreach} + + + {if ($grant)} + + <tr> + + <td colspan='2' align='center'> + + <button type="button" onclick='javascript:edit()' style='margin-right:15px;' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + + </td> + + </tr> + + {/if} + + </table> + +</div> diff --git a/hyhproject/admin/view/sysconfigs/edit.html b/hyhproject/admin/view/sysconfigs/edit.html new file mode 100755 index 0000000..9b710ab --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/edit.html @@ -0,0 +1,63 @@ +{extend name="base" /} + +{block name="css"} + +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> + +<style> + +.layui-form-label{width:140px;} + +.layui-input-block{ margin-left: 170px;} + +#wst-tab-5 input[type="text"]{width:50%} + +td{height:40px; } + +</style> + +{/block} + +{block name="js"} + +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}' type="text/javascript"></script> + +<script src="__ADMIN__/sysconfigs/sysconfigs.js?v={$v}" type="text/javascript"></script> + +{/block} + +{block name="main"} + +<form autocomplete='off'> + +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + + <ul class="layui-tab-title"> + <li class="layui-this">数据配置</li> + <!-- <li class="layui-this">基础设置</li> + + <li>服务器设置</li> + + <li>运营设置</li> + + <li>密匙设置</li> + + <li>图片设置</li> + + <li>通知设置</li> + + <li>SEO设置</li> + --> + </ul> + + <div class="layui-tab-content" style="padding: 10px 0;"> + + {include file='sysconfigs/dataConfigs,sysconfigs/config1,sysconfigs/config2,sysconfigs/config3,sysconfigs/config4,sysconfigs/config6,sysconfigs/config5' /} + + </div> + +</div> + +</form> + +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/sysconfigs/sysconfigs.js b/hyhproject/admin/view/sysconfigs/sysconfigs.js new file mode 100755 index 0000000..3885a50 --- /dev/null +++ b/hyhproject/admin/view/sysconfigs/sysconfigs.js @@ -0,0 +1,156 @@ +var layer = layui.layer; +var laytpl, form,laypage; +$(function(){ + form = layui.form; + form.render(); + form.on('switch(seoMallSwitch)', function(data){ + if(this.checked){ + WST.showHide(0,'#close'); + }else{ + WST.showHide(1,'#close'); + } + }); + form.on('switch(signScoreSwitch)', function(data){ + if(this.checked){ + WST.showHide(1,'#signScore,#signScores') + }else{ + WST.showHide(0,'#signScore,#signScores') + } + }); + form.on('switch(isOpenScorePay)', function(data){ + if(this.checked){ + WST.showHide(1,'#scoreToMoneyTr') + }else{ + WST.showHide(0,'#scoreToMoneyTr') + } + }); + form.on('switch(isOrderScore)', function(data){ + if(this.checked){ + WST.showHide(1,'#moneyToScoreTr') + }else{ + WST.showHide(0,'#moneyToScoreTr') + } + }); + form.on('switch(isAppraisesScore)', function(data){ + if(this.checked){ + WST.showHide(1,'#appraisesScoreTr') + }else{ + WST.showHide(0,'#appraisesScoreTr') + } + }); + form.on('switch(isCryptPwd)', function(data){ + if(this.checked){ + WST.showHide(1,'.pwdCryptKeyTr') + }else{ + WST.showHide(0,'.pwdCryptKeyTr') + } + }); + var element = layui.element; + element.on('tab(msgTab)', function(data){ + if(data.index==4)initUploads(); + }); +}); +var isInitUpload = false; +function initUploads(){ + if(isInitUpload)return; + var uploads = ['watermarkFile','mallLogo','shopLogo','userLogo','goodsLogo'],key; + for(var i=0;i<uploads.length;i++){ + key = uploads[i]; + WST.upload({ + k:key, + pick:'#'+key+"Picker", + formData: {dir:'sysconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#'+this.k+'Msg').empty().hide(); + $('#'+this.k+'Prevw').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.name); + $('#'+this.k).val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#'+this.k+'Msg').show().html('已上传'+rate+"%"); + } + }); + } + isInitUpload = true; +} +function checkTip(ids,obj){ + var ids = ids.split(','); + if(!$('#'+ids[0])[0].checked && !$('#'+ids[1])[0].checked)$('.'+obj).each(function(){ + $(this).attr('checked',false); + }) +} +function edit(){ + if(!WST.GRANT.SCPZ_02)return; + var params = WST.getParams('.ipt'); + var signScore = ''; + for(var i=0;i<30;i++){ + if(i>0 && params.signScore0!=0){ + if(!params['signScore'+i] || params['signScore'+i]==0){ + params['signScore'+i] = params['signScore'+(i-1)]; + } + } + if(!params.signScore0 || params.signScore0==0){ + signScore += '0,'; + }else{ + if(!params['signScore'+i])params['signScore'+i] = 0; + signScore += params['signScore'+i] + ','; + } + } + params.signScore = signScore; + var strTitle = ['用户下单','支付订单','取消订单','拒收订单','申请退款','订单投诉','用户提现']; + var strTip = ['SubmitOrderTip','PayOrderTip','CancelOrderTip','RejectOrderTip', + 'RefundOrderTip','ComplaintOrderTip','CashDrawsTip']; + var strUser = ['submitOrderTipUsers','payOrderTipUsers','cancelOrderTipUsers','rejectOrderTipUsers', + 'refundOrderTipUsers','complaintOrderTipUsers','cashDrawsTipUsers']; + var ids = [],wxId = '',smsId; + for(var i=0;i<strUser.length;i++){ + ids = []; + $('.'+strUser[i]).each(function(){ + if($(this)[0].checked)ids.push($(this).val()); + }); + wxId = 'wx'+strTip[i]; + smsId = 'sms'+strTip[i]; + params[wxId] = $('#'+wxId)[0].checked?1:0; + params[smsId] = $('#'+smsId)[0].checked?1:0; + params[strUser[i]] = ids.join(','); + if(params[wxId]==0 && params[smsId]==0 && ids.length>0){ + WST.msg('请选择'+strTitle[i]+'提醒方式',{icon:1}); + return; + } + if((params[wxId]==1 || params[smsId]==1) && ids.length==0){ + WST.msg('请选择'+strTitle[i]+'提醒人',{icon:1}); + return; + } + } + var loading = WST.msg('正在保存数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/sysconfigs/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + } + }); +} + + +$(function(){ + $('#watermarkColor').colpick({ + layout:'hex', + submit:1, + colorScheme:'dark', + onChange:function(hsb,hex,rgb,el,bySetColor) { + $(el).css('border-color','#'+hex); + }, + onSubmit:function(hsb,hex,rgb,el,bySetColor){ + if(!bySetColor) $(el).val('#'+hex); + $(el).colpickHide(); + } + }).keyup(function(){ + $(this).colpickSetColor(this.value); + $(this).colpickHide(); + }); + +}); \ No newline at end of file diff --git a/hyhproject/admin/view/templatemsgs/edit_email.html b/hyhproject/admin/view/templatemsgs/edit_email.html new file mode 100755 index 0000000..c599a6c --- /dev/null +++ b/hyhproject/admin/view/templatemsgs/edit_email.html @@ -0,0 +1,49 @@ +{extend name="base" /} +{block name="js"} +<script src="__STATIC__/plugins/kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +<script src="__ADMIN__/templatemsgs/templatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form autocomplete='off'> +<input type='hidden' id='id' class='ipt' value="{$object['id']}"/> +<input type='hidden' id='tplCode' class='ipt' value="{$object['tplCode']}"/> +<table class='wst-form wst-box-top layui-form'> + <tr> + <th width='120'>发送时机:</th> + <td> + {volist name=':WSTDatas("TEMPLATE_EMAIL")' id='vo'} + {if $vo['dataVal']==$object['tplCode']}{$vo['dataName']}{/if} + {/volist} + </td> + </tr> + <tr> + <th>内容:</th> + <td> + <textarea id='tplContent' name='tplContent' style='width:70%;height:100px;' class='ipt' maxLength='150'>{$object['tplContent']}</textarea> + </td> + </tr> + <tr> + <th>是否开启:</th> + <td> + <input type="checkbox" {if $object['status']==1}checked{/if} value='1' class="ipt" id="isShow2" name="seoMallSwitch" lay-skin="switch" lay-filter="isShow2" lay-text="开启|关闭"> + </td> + </tr> + <tr> + <th valign="top">说明:</th> + <td id='tplDesc'>{$object['tplDesc']}</td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:save(1)'><i class="fa fa-check"></i>保存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){ + initEditor(); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/templatemsgs/edit_msg.html b/hyhproject/admin/view/templatemsgs/edit_msg.html new file mode 100755 index 0000000..f53adc3 --- /dev/null +++ b/hyhproject/admin/view/templatemsgs/edit_msg.html @@ -0,0 +1,43 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/templatemsgs/templatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form autocomplete='off'> +<input type='hidden' id='id' class='ipt' value="{$object['id']}"/> +<input type='hidden' id='tplCode' class='ipt' value="{$object['tplCode']}"/> +<table class='wst-form wst-box-top layui-form'> + <tr> + <th width='120'>发送时机:</th> + <td> + {volist name=':WSTDatas("TEMPLATE_SYS")' id='vo'} + {if $vo['dataVal']==$object['tplCode']}{$vo['dataName']}{/if} + {/volist} + </td> + </tr> + <tr> + <th>内容:</th> + <td> + <textarea id='tplContent' style='width:70%;height:100px;' class='ipt' maxLength='150'>{$object['tplContent']}</textarea> + </td> + </tr> + <tr> + <th>是否开启:</th> + <td> + <input type="checkbox" {if $object['status']==1}checked{/if} value='1' class="ipt" id="isShow" name="seoMallSwitch" lay-skin="switch" lay-filter="isShow" lay-text="开启|关闭"> + </td> + </tr> + <tr> + <th valign="top">说明:</th> + <td id='tplDesc'>{$object['tplDesc']}</td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:save(0)'><i class="fa fa-check"></i>保存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/templatemsgs/edit_sms.html b/hyhproject/admin/view/templatemsgs/edit_sms.html new file mode 100755 index 0000000..b69b08d --- /dev/null +++ b/hyhproject/admin/view/templatemsgs/edit_sms.html @@ -0,0 +1,43 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/templatemsgs/templatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form autocomplete='off'> +<input type='hidden' id='id' class='ipt' value="{$object['id']}"/> +<input type='hidden' id='tplCode' class='ipt' value="{$object['tplCode']}"/> +<table class='wst-form wst-box-top layui-form'> + <tr> + <th width='120'>发送时机:</th> + <td> + {volist name=':WSTDatas("TEMPLATE_SMS")' id='vo'} + {if $vo['dataVal']==$object['tplCode']}{$vo['dataName']}{/if} + {/volist} + </td> + </tr> + <tr> + <th>内容:</th> + <td> + <textarea id='tplContent' style='width:70%;height:100px;' class='ipt' maxLength='150'>{$object['tplContent']}</textarea> + </td> + </tr> + <tr> + <th>是否开启:</th> + <td> + <input type="checkbox" {if $object['status']==1}checked{/if} value='1' class="ipt" id="isShow3" name="seoMallSwitch" lay-skin="switch" lay-filter="isShow3" lay-text="开启|关闭"> + </td> + </tr> + <tr> + <th valign="top">说明:</th> + <td id='tplDesc'>{$object['tplDesc']}</td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:save(2)'><i class="fa fa-check"></i>保存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/templatemsgs/list.html b/hyhproject/admin/view/templatemsgs/list.html new file mode 100755 index 0000000..679356b --- /dev/null +++ b/hyhproject/admin/view/templatemsgs/list.html @@ -0,0 +1,61 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +<style> +body{overflow:hidden;} +</style> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/templatemsgs/templatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief " lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li {if condition="$src==0"}class="layui-this"{/if} onclick="initGridMsg(0)">消息模板</li> + <li {if condition="$src==1"}class="layui-this"{/if} onclick="initGridEmail(0)">邮件模板</li> + <li {if condition="$src==2"}class="layui-this"{/if} onclick="initGridSMS(0)">短信模板</li> + </ul> + <div class="layui-tab-content " style="padding: 0px 0;"> + <div id="template_msg" class="layui-tab-item {if condition='$src==0'}layui-show{/if}"> + <div class='wst-grid' style='margin-top:5px'> + <div id="mmg1" class="mmg1 layui-form"></div> + <div id="pg1" style="text-align: right;"></div> + </div> + </div> + <div id="template_email" class="layui-tab-item {if condition='$src==1'}layui-show{/if}"> + <div class='wst-grid' style='margin-top:5px'> + <div id="mmg2" class="mmg2 layui-form"></div> + <div id="pg2" style="text-align: right;"></div> + </div> + </div> + <div id="template_sms" class="layui-tab-item {if condition='$src==2'}layui-show{/if}"> + <div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于管理短信发送的模板格式。</li> + <li>若短信服务商未要求预先定义模板,则发送时以本系统模板为主(例如中国网建)。</li> + <li>若短信服务商要求必须预先定义模板的(例如阿里云-云通信),则本系统中的模板仅作为建模参考,发送格式以短信服务商上的模板为主。</li> + </ul> + </div> + <div class='wst-grid'> + <div id="mmg3" class="mmg3 layui-form"></div> + <div id="pg3" style="text-align: right;"></div> + </div> + </div> + </div> +</div> +<script> + $(function(){ + h = WST.pageHeight(); + {if condition='$src==1'} + initGridEmail(0); + {elseif condition='$src==2'} + initGridSMS(0); + {else/} + initGridMsg(0); + {/if} + }); +</script> +{/block} + diff --git a/hyhproject/admin/view/templatemsgs/templatemsgs.js b/hyhproject/admin/view/templatemsgs/templatemsgs.js new file mode 100755 index 0000000..b91cf72 --- /dev/null +++ b/hyhproject/admin/view/templatemsgs/templatemsgs.js @@ -0,0 +1,196 @@ +var mmg,h; +function initGridMsg(){ + var cols = [ + {title:'发送时机', name:'tplCode', width: 80}, + {title:'发送内容', name:'tplContent' ,width:600}, + {title:'是否开启', name:'status',align:'center',width:50,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['status']==1)?"checked":"")+' name="isShow2" lay-skin="switch" lay-filter="isShow2" data="'+item['id']+'" lay-text="开启|关闭">'; + + }}, + {title:'操作', name:'' ,width:20, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.XXMB_02)h += "<a class='btn btn-blue' onclick='javascript:toEditMsg("+item['id']+")'><i class='fa fa-pencil'></i>修改</a> "; + return h; + }} + ]; + + mmg = $('.mmg1').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/templatemsgs/pageMsgQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg1').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render(); + layui.form.on('switch(isShow2)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(0,id); + }else{ + toggleIsShow(1,id); + } + }); + }) +} +function initGridEmail(){ + var cols = [ + {title:'发送时机', name:'tplCode', width: 80}, + {title:'发送内容', name:'tplContent' ,width:600}, + {title:'是否开启', name:'status',align:'center',width:50,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['status']==1)?"checked":"")+' name="isShow3" lay-skin="switch" lay-filter="isShow3" data="'+item['id']+'" lay-text="开启|关闭">'; + + }}, + {title:'操作', name:'' ,width:20, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.XXMB_02)h += "<a class='btn btn-blue' onclick='javascript:toEditEmail("+item['id']+")'><i class='fa fa-pencil'></i>修改</a> "; + return h; + }} + ]; + + mmg = $('.mmg2').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/templatemsgs/pageEmailQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg2').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render(); + layui.form.on('switch(isShow3)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(0,id); + }else{ + toggleIsShow(1,id); + } + }); + }) +} +function initGridSMS(){ + var cols = [ + {title:'发送时机', name:'tplCode', width: 80}, + {title:'发送内容', name:'tplContent' ,width:600}, + {title:'是否开启', name:'status',align:'center',width:50,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['status']==1)?"checked":"")+' name="isShow4" lay-skin="switch" lay-filter="isShow4" data="'+item['id']+'" lay-text="开启|关闭">'; + + }}, + {title:'操作', name:'' ,width:20, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.XXMB_02)h += "<a class='btn btn-blue' onclick='javascript:toEditSMS("+item['id']+")'><i class='fa fa-pencil'></i>修改</a> "; + return h; + }} + ]; + + mmg = $('.mmg3').mmGrid({height: h-182,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/templatemsgs/pageSMSQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg3').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render(); + layui.form.on('switch(isShow4)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(0,id); + }else{ + toggleIsShow(1,id); + } + }); + }) + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-182}); + }else{ + mmg.resize({height:h-124}); + } + }}); +} + +function toggleIsShow(t,v){ + if(!WST.GRANT.DQGL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/TemplateMsgs/editiIsShow'),{id:v,status:t},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +var editor1; +function initEditor(){ + KindEditor.ready(function(K) { + editor1 = K.create('textarea[name="tplContent"]', { + uploadJson : WST.conf.ROOT+'/admin/messages/editorUpload', + height:'350px', + allowFileManager : false, + allowImageUpload : true, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } + }); + }); +} + +function toEditMsg(id){ + location.href = WST.U('admin/templatemsgs/toEditMsg','id='+id); +} +function toEditEmail(id){ + location.href = WST.U('admin/templatemsgs/toEditEmail','id='+id); +} +function toEditSMS(id){ + location.href = WST.U('admin/templatemsgs/toEditSMS','id='+id); +} +function save(type){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var params = WST.getParams('.ipt'); + $.post(WST.U('admin/templatemsgs/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href = WST.U('admin/templatemsgs/index','src='+type); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +var isInit1 = false; +var isInit2 = false; +var isInit3 = false; +//切换卡 +$(function (){ + var element = layui.element; + element.on('tab(msgTab)', function(data){ + if(data.index==0){ + if(!isInit1){ + isInit1 = true; + initGridMsg(); + } + }else if(data.index==1){ + if(!isInit2){ + isInit2 = true; + initGridEmail(); + } + }else if(data.index==2){ + if(!isInit3){ + isInit3 = true; + initGridSMS(); + } + } + }); +}); + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/userranks/edit.html b/hyhproject/admin/view/userranks/edit.html new file mode 100755 index 0000000..ca270f6 --- /dev/null +++ b/hyhproject/admin/view/userranks/edit.html @@ -0,0 +1,62 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/userranks/userranks.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="userRankForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>会员等级名称<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="rankName" name="rankName" value="{$data['rankName']}" /> + </td> + </tr> + <tr> + <th width='100'>会员等级图标:</th> + <td><div id='userranksPicker'>上传图标</div><span id='uploadMsg'></span></td> + </tr> + <tr> + <th width='100'>预览图:</th> + <td> + <div style="min-height:30px;" id="preview"> + {if (isset($data['userrankImg']))} + <img src="__IMGURL__/{$data['userrankImg']}" height="25" /> + {/if} + </div> + <input type="hidden" name="userrankImg" id="userrankImg" value="{$data['userrankImg']}" class="ipt" /> + + </td> + </tr> + + <tr> + <th>积分下限(大于或等于)<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="startScore" name="startScore" value="{$data['startScore']}" /> + </td> + </tr> + <tr> + <th>积分上限(小于)<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="endScore" name="endScore" value="{$data['endScore']}" /> + </td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="rankId" class="ipt" value="{$data['rankId']+0}" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){editInit()}); +</script> + +{/block} + diff --git a/hyhproject/admin/view/userranks/list.html b/hyhproject/admin/view/userranks/list.html new file mode 100755 index 0000000..54b2d2d --- /dev/null +++ b/hyhproject/admin/view/userranks/list.html @@ -0,0 +1,23 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/userranks/userranks.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +{if WSTGrant('HYDJ_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:location.href='<?=url("userranks/toEdit")?>'"><i class='fa fa-plus'></i> 新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/userranks/userranks.js b/hyhproject/admin/view/userranks/userranks.js new file mode 100755 index 0000000..9666274 --- /dev/null +++ b/hyhproject/admin/view/userranks/userranks.js @@ -0,0 +1,111 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'会员等级图标', name:'userrankImg', width: 30,renderer:function(val,item,rowIndex){ + return '<img src="'+WST.conf.IMGURL+'/'+item['userrankImg']+'" height="28px" />'; + }}, + {title:'会员等级名称', name:'rankName' ,width:100}, + {title:'积分下限', name:'startScore' ,width:100}, + {title:'积分上限', name:'endScore' ,width:60}, + {title:'操作', name:'' ,width:180, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.HYDJ_02)h += "<a class='btn btn-blue' onclick='javascript:toEdit("+item['rankId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.HYDJ_03)h += "<a class='btn btn-red' onclick='javascript:toDel(" + item['rankId'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/userranks/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toEdit(id){ + location.href = WST.U('admin/userranks/toEdit','id='+id); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/userranks/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + mmg.load(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function editInit(){ + /* 表单验证 */ + $('#userRankForm').validator({ + fields: { + rankName: { + rule:"required", + msg:{required:"请输入会员等级名称"}, + tip:"请输入会员等级名称", + ok:"", + }, + userrankImg: { + rule:"required", + msg:{required:"请输上传会员图标"}, + tip:"请输上传会员图标", + ok:"", + } + + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/userranks/'+((params.rankId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/userranks/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + +//文件上传 +WST.upload({ + pick:'#userranksPicker', + formData: {dir:'userranks'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //保存上传的图片路径 + $('#userrankImg').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="25" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } +}); + + +}; + + + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/users/account.js b/hyhproject/admin/view/users/account.js new file mode 100755 index 0000000..ed69d80 --- /dev/null +++ b/hyhproject/admin/view/users/account.js @@ -0,0 +1,173 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'账号', name:'loginName', width: 30,sortable:true}, + {title:'用户名', name:'userName' ,width:100,sortable:true}, + {title:'手机号码', name:'userPhone' ,width:100,sortable:true}, + {title:'电子邮箱', name:'userEmail' ,width:60,sortable:true}, + {title:'最后登录时间', name:'lastTime' ,width:60,sortable:true}, + {title:'状态', name:'userStatus' ,width:20, renderer:function(val,item,rowIndex){ + return '<input type="checkbox" '+((val==1)?"checked":"")+' lay-skin="switch" lay-filter="userStatus" data="'+item['userId']+'" lay-text="启用|停用">'; + }}, + {title:'操作', name:'' ,width:170, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.ZHGL_02)h += "<a class='btn btn-blue' onclick='javascript:getForEdit("+item['userId']+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.ZHGL_02)h += "<a class='btn btn-blue' onclick='javascript:resetPayPwd(" + item['userId'] + ")'><i class='fa fa-key'></i>重置支付密码</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-155,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Users/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'lastTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render('','gridForm'); + layui.form.on('switch(userStatus)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + //信息框-例2 + layer.msg('确定要启用此账户吗?', { + time: 0 //不自动关闭 + ,btn: ['确定', '取消'] + ,yes: function(index){ + changeUserStatus(id, 1); + setTimeout(function(){ layer.close(index); }, 2000); + } + }); + + }else{ + layer.open({ + type: 1, + title: '禁用说明', + closeBtn: 1, + shadeClose: true, + area: '50%', + btn: ['确定'], + btnAlign: 'c', //按钮居中 + // skin: '', + content: '<div style="margin:10px;">禁用时长:<input id="lockTime" class="ipt" style="marign:5px;width:200px;" class="ipt" placeholder="请输入禁用时长,单位(小时)"></div>' + + '<div style="margin:10px;">禁用原因:<textarea id="lockReason" class="ipt" style="width:300px;height:100px;" maxlength="100"></textarea></div>', + yes: function(index){ + let lockTime = $('#lockTime').val(); + if('' == lockTime){ + WST.msg('请输入禁用时间', {icon: 2,time:3000}); + $('#lockTime').focus(); + return; + } + let lockReason = $('#lockReason').val(); + if('' == lockReason){ + WST.msg('请输入禁用原因', {icon: 2,time:3000}); + $('#lockReason').focus(); + return; + } + + changeUserStatus(id, 0, lockTime, lockReason); + setTimeout(function(){ layer.close(index); }, 2000); + } + }) + + } + }); + }) + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-155}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} + + +function resetPayPwd(id){ + var box = WST.confirm({content:"您确定重置支付密码为666666吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/resetPayPwd'),{userId:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("重置成功",{icon:1}); + layer.close(box); + accountQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getForEdit(id){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/get'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + //清空密码 + json.loginPwd = ''; + if(json.userId){ + WST.setValues(json); + layui.form.render(); + $('#loginName').html(json.loginName); + $('#userId').val(json.userId); + toEdit(json.userId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + var box = WST.open({title:'编辑',type:1,content:$('#accountBox'),area: ['450px', '260px'],btn:['确定','取消'],yes:function(){ + $('#accountForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(id>0) + params.userId = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/users/editAccount'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + $('#accountForm')[0].reset(); + layer.close(box); + accountQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }else{ + return false; + } + }); + + + + },cancel:function(){$('#accountForm')[0].reset();},end:function(){$('#accountBox').hide();$('#accountForm')[0].reset();}}); + +} + +function changeUserStatus(id, status, lockTime ,lockReason){ + if(!WST.GRANT.ZHGL_02)return; + $.post(WST.U('admin/Users/changeUserStatus'), {'id':id, 'status':status,'lockTime':lockTime, 'lockReason':lockReason}, function(data, textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + accountQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} + + +function accountQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} + + \ No newline at end of file diff --git a/hyhproject/admin/view/users/account_list.html b/hyhproject/admin/view/users/account_list.html new file mode 100755 index 0000000..85a73f3 --- /dev/null +++ b/hyhproject/admin/view/users/account_list.html @@ -0,0 +1,70 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/users/account.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于管理会员(商家)的账号信息,您可以通过各种条件查询会员账号。</li> + </ul> +</div> +<div class="wst-toolbar"> + <form> + <div id="query"> + <input type="text" name="loginName1" placeholder='账号/店铺名称' id="loginName1" class="query" /> + <select name="userType" id="userType" class="query"> + <option value="">会员类型</option> + <option value="0">普通会员</option> + <option value="1">商家</option> + </select> + <select name="userStatus1" id="userStatus1" class="query"> + <option value="">账号状态</option> + <option value="1">启用</option> + <option value="0">停用</option> + </select> + <button type="button" class='btn btn-primary btn-mright' onclick="javascript:accountQuery()" ><i class="fa fa-search"></i>查询</button> + </div> + </form> + <div style="clear:both"></div> +</div> +<form autocomplete="off" class='layui-form wst-grid' lay-filter='gridForm'> +<div id="mmg" class="mmg"></div> +</form> +<div id="pg" style="text-align: right;"></div> +<div id='accountBox' style='display:none'> + <form id='accountForm' autocomplete="off" class='layui-form'> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>账号<font color='red'>*</font>:</th> + <td height='30'> + <input type="hidden" name="userId" id="userId"> + <div id="loginName"></div> + </td> + </tr> + <tr> + <th>密码<font color='red'>*</font>:</th> + <td><input type='password' id='loginPwd' data-rule="length[6~20];" placeholder="为空则说明不修改密码" class='ipt' maxLength='20'/></td> + </tr> + <tr> + <th>会员状态<font color='red'>*</font>:</th> + <td height='30'> + <input type="checkbox" class='ipt' value='1' name="userStatus" id="userStatus" lay-skin="switch" lay-text="启用|停用"> + </td> + + </tr> + </table> + </form> + </div> +<script> + $(function(){ + initGrid() + + }); +</script> + +{/block} diff --git a/hyhproject/admin/view/users/auth.js b/hyhproject/admin/view/users/auth.js new file mode 100755 index 0000000..2740fd9 --- /dev/null +++ b/hyhproject/admin/view/users/auth.js @@ -0,0 +1,611 @@ +let mmg; +var QLG = QLG || {}; +let authActionUrl=''; +QLG.init=function (typeNum){ + if(1 == typeNum){ + authActionUrl = 'personalAction'; + }else if(2 == typeNum){ + authActionUrl = 'companyAction'; + }else if(3 == typeNum){ + authActionUrl = 'setUserUpdate'; + } + +} +function showMsg(title,html){ + layer.open({ + type: 1, + title: title, + closeBtn: 1, + shadeClose: true, + area: '50%', + btn: ['确定'], + btnAlign: 'c', //按钮居中 + // skin: '', + content: html + }); +} + +$("body").on("click",'.showShopImg',function(){ + let imgs = $(this).attr('data-imgs'); + let imgsArr = imgs.split(','); + let html=''; + $.each(imgsArr,function(i,v){ + html+='<img src="'+WST.conf.IMGURL+'/'+v+'"><br>'; + }) + showMsg('商铺图片组',html) +}); +//亲人认证 +$("body").on("click",'.family_personal',function(){ + let userId = $(this).attr('data-userId'); + $.post(WST.U('admin/Users/authFamilyList'),{'isPersonal':1,'userId':userId},function(data) { + let json = WST.toAdminJson(data); + if(1 == json.status){ + if('undefined' == typeof(json.data)){ + WST.msg('没有相关数据', {icon: 2,time:3000}); + return; + } + let auth_html = '<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"></fieldset> ' + + '<table class="layui-table" lay-even="" lay-skin="row">' + + ' <thead>' + + ' <tr>' + + ' <th>本人ID</th>' + + ' <th>亲人ID</th>' + + ' <th>亲人姓名</th>' + + ' <th>亲人身份证</th>' + + ' <th>关系</th>' + + ' <th>关系证明照</th>' + + ' <th>身份证正面</th>' + + ' <th>身份证反面</th>' + + ' </tr> ' + + ' </thead>' + + ' <tbody>'; + let tdStr=''; + $.each(json.data,function(){ + tdStr+='<tr><td>'+this.userId+'</td>'; + tdStr+='<td>'+this.familyId+'</td>'; + tdStr+='<td>'+this.familyName+'</td>'; + tdStr+='<td>'+this.familyIdCard+'</td>'; + tdStr+='<td>'+this.familyRelations+'</td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.familyRelationsImg+'\' /></td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.idCardFrontImg+'\' /></td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.idCardBackImg+'\' /></td></tr>'; + }); + auth_html+=tdStr+'</tbody>' + + '</table> '; + showMsg('亲人认证列表',auth_html) + return; + } + WST.msg('数据读取出错,请重试', {icon: 2,time:3000}); + return; + }); +}); +//亲人报备 +$("body").on("click",'.family_report',function(){ + let userId = $(this).attr('data-userId'); + $.post(WST.U('admin/Users/authFamilyList'),{'isPersonal':0,'userId':userId},function(data) { + let json = WST.toAdminJson(data); + if(1 == json.status){ + if('undefined' == typeof(json.data)){ + WST.msg('没有相关数据', {icon: 2,time:3000}); + return; + } + let auth_html = '<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"></fieldset> ' + + '<table class="layui-table" lay-even="" lay-skin="row">' + + ' <thead>' + + ' <tr>' + + ' <th>本人ID</th>' + + ' <th>报备姓名</th>' + + ' <th>报备身份证</th>' + + ' <th>关系</th>' + + ' <th>关系证明照</th>' + + ' </tr> ' + + ' </thead>' + + ' <tbody>'; + let tdStr=''; + $.each(json.data,function(){ + tdStr+='<tr><td>'+this.userId+'</td>'; + tdStr+='<td>'+this.familyName+'</td>'; + tdStr+='<td>'+this.familyIdCard+'</td>'; + tdStr+='<td>'+this.familyRelations+'</td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.familyRelationsImg+'\' /></td></tr>'; + }); + auth_html+=tdStr+'</tbody>' + + '</table> '; + showMsg('亲人报备列表',auth_html) + return; + } + WST.msg('数据读取出错,请重试', {icon: 2,time:3000}); + return; + }); +}); +//合作认证 +$("body").on("click",'.company_partner',function(){ + let userId = $(this).attr('data-userId'); + $.post(WST.U('admin/Users/authCompanyList'),{'userId':userId},function(data) { + let json = WST.toAdminJson(data); + if(1 == json.status){ + if('undefined' == typeof(json.data)){ + WST.msg('没有相关数据', {icon: 2,time:3000}); + return; + } + let auth_html = '<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"></fieldset> ' + + '<table class="layui-table" lay-even="" lay-skin="row">' + + ' <thead>' + + ' <tr>' + + ' <th>本人ID</th>' + + ' <th>合伙人ID</th>' + + ' <th>合伙人姓名</th>' + + ' <th>身份证</th>' + + ' <th>职位</th>' + + ' <th>持股比例</th>' + + ' <th>手持营业执照照片</th>' + + ' <th>身份证正面</th>' + + ' <th>身份证反面</th>' + + ' </tr> ' + + ' </thead>' + + ' <tbody>'; + let tdStr=''; + $.each(json.data,function(){ + tdStr+='<tr><td>'+this.userId+'</td>'; + tdStr+='<td>'+this.partnerId+'</td>'; + tdStr+='<td>'+this.uName+'</td>'; + tdStr+='<td>'+this.idCard+'</td>'; + tdStr+='<td>'+this.positionName+'</td>'; + tdStr+='<td>'+this.stake+'</td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.businessImg+'\' /></td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.idCardFrontImg+'\' /></td>'; + tdStr+='<td>'+"<img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+this.idCardBackImg+'\' /></td> </tr>'; + }); + auth_html+=tdStr+'/tbody>' + + '</table> '; + showMsg('合作人认证列表',auth_html) + return; + } + WST.msg('数据读取出错,请重试', {icon: 2,time:3000}); + return; + }); +}); +//银行卡列表 +$("body").on("click",'.company_bank',function(){ + let userId = $(this).attr('data-userId'); + $.post(WST.U('admin/Users/authCompanyBank'),{'userId':userId},function(data) { + let json = WST.toAdminJson(data); + if(1 == json.status){ + if('undefined' == typeof(json.data)){ + WST.msg('没有相关数据', {icon: 2,time:3000}); + return; + } + let auth_html = '<fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"></fieldset> ' + + '<table class="layui-table" lay-even="" lay-skin="row">' + + ' <thead>' + + ' <tr>' + + ' <th>本人ID</th>' + + ' <th>银行名</th>' + + ' <th>开户名</th>' + + ' <th>卡号</th>' + + ' </tr> ' + + ' </thead>' + + ' <tbody>'; + let tdStr=''; + $.each(json.data,function(){ + tdStr+='<tr><td>'+this.userId+'</td>'; + tdStr+='<td>'+this.bankName+'</td>'; + tdStr+='<td>'+this.accountName+'</td>'; + tdStr+='<td>'+this.bankNo+'</td></tr>'; + }); + auth_html+=tdStr+'</tbody>' + + '</table> '; + showMsg('合作人银行卡列表',auth_html) + return; + } + WST.msg('数据读取出错,请重试', {icon: 2,time:3000}); + return; + }); +}); +$("body").on("click",'.authAction',function(){ + let id = $(this).attr('data-id'); + layer.open({ + type: 1, + title: '审核操作', + closeBtn: 1, + shadeClose: true, + area: '50%', + btn: ['确定'], + btnAlign: 'c', //按钮居中 + // skin: '', + content: '<div style="text-align:center;margin-top:1rem;padding-top:1rem;">审核处理:<label><input type="radio" class="status" value="1" name="status" onclick="javascript:WST.showHide(0,&quot;#trApplyDesc&quot;);" title="通过">通过' + + ' </label> ' + + '<label><input type="radio" class="status" value="2" name="status" onclick="javascript:WST.showHide(1,&quot;#trApplyDesc&quot;);" title="不通过">拒绝' + + '</label>' + + '<div id="trApplyDesc" style="display:none">' + + '<th>不通过原因<font color="red">*</font>:</th>' + + '<td><textarea id="applyDesc" class="ipt" style="width:300px;height:100px;" maxlength="100" data-rule="不通过原因:required(#status-1:checked);"></textarea></td>' + + '</div></div>', + yes: function(index){ + + let obj = $("input[name='status']:checked"); + let status =obj.val(); + if(!status){ + WST.msg('请选择通过或不通过', {icon: 2,time:3000}); + return; + } + let applyDesc = $('#applyDesc').val(); + if(2 == status && '' == applyDesc ){ + WST.msg('请输入拒绝理由', {icon: 2,time:3000}); + $('#applyDesc').focus(); + return; + } + let msgArr = ['通过','拒绝']; + + let msg = "您确定要"+msgArr[status-1]+"此用户的申请信息?"; + let box = WST.confirm({content:msg,yes:function(){ + let loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Users/'+authActionUrl),{id:id,status:status,'reasonsForRefusal':applyDesc},function(data,textStatus){ + layer.close(loading); + let json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + layer.close(index); + userQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + } + }); +}); +$("body").on("click",'.uploadImg',function(){ + layer.open({ + type: 1, + title: false, + closeBtn: 0, + area: '90%', + skin: 'layui-layer-nobg', //没有背景色 + shadeClose: true, + content: '<div ><img src="'+$(this).attr('src')+'"></div>' + }); +}); + +function initPersonalGrid(){ + let h = WST.pageHeight(); + let cols = [ + {title:'账号', name:'loginName', width: 130,sortable:true}, + {title:'手机号码', name:'userPhone' ,width:100,sortable:true}, + {title:'户主姓名', name:'householdName' ,width:100,sortable:true}, + {title:'身份证', name:'householdIdCard' ,width:100,sortable:true}, + {title:'居住地址', name:'houseAddress' ,width:100,sortable:true}, + {title:'手持户口本照片', name:'accountBookImg' ,width:100,sortable:true ,renderer:function(val,item,rowIndex) { + return"<span><img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+val+"'</span>"; + }}, + {title:'认证信息', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex) { + let h = ""; + h += "<a data-userId='"+item.userId+"'class='family_personal'>亲人认证</a> "; + h += "<a data-userId='"+item.userId+"'class='family_report'> 亲人报备</a> "; + return h; + }}, + {title:'申请时间', name:'createTime' ,width:120,sortable:true,renderer:function(val,item,rowIndex) { + return getLocalTime(val); + + }}, + {title:'状态/操作', name:'status' ,width:60,sortable:true, renderer:function(val,item,rowIndex) { + let h = ""; + if(val==1){ + h += "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已通过&nbsp;</span>"; + if (WST.GRANT.GTRZSH_01) { + h += "<a data-id='" + item.id + "'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else if(val==2){ + h += "<span class='statu-no'><i class='fa fa-ban'></i> 已拒绝&nbsp;</span>"; + if (WST.GRANT.GTRZSH_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else { + h += "<span class='statu-wait'><i class='fa fa-clock-o'></i> 待审核&nbsp;</span>"; + if (WST.GRANT.GTRZSH_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>审核</a> "; + } + } + return h; + } + }]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Users/getPersonalReview'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-173}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function initCompanyGrid(){ + let h = WST.pageHeight(); + let cols = [ + {title:'账号', name:'loginName', width: 130,sortable:true}, + {title:'手机号码', name:'userPhone' ,width:100,sortable:true}, + {title:'合作名', name:'companyName' ,width:100,sortable:true}, + {title:'直营人姓名', name:'trueName' ,width:100,sortable:true}, + {title:'身份证', name:'idCard' ,width:100,sortable:true}, + {title:'公司地址', name:'companyAddress' ,width:100,sortable:true}, + // {title:'手持户口本照片', name:'accountBookImg' ,width:100,sortable:true ,renderer:function(val,item,rowIndex) { + // return"<span><img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+val+"'</span>"; + // }}, + {title:'认证信息', name:'' ,width:150, align:'center', renderer: function(val,item,rowIndex) { + let h = ""; + h += "<a data-userId='"+item.userId+"'class='company_partner'>合作人员</a> "; + h += "<a data-userId='"+item.userId+"'class='company_bank'> 银行卡列表</a> "; + return h; + }}, + {title:'申请时间', name:'createTime' ,width:120,sortable:true,renderer:function(val,item,rowIndex) { + return getLocalTime(val); + + }}, + {title:'状态/操作', name:'status' ,width:60,sortable:true, renderer:function(val,item,rowIndex) { + let h = ""; + if(val==1){ + h += "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已通过&nbsp;</span>"; + if (WST.GRANT.HZRZSH_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else if(val==2){ + h += "<span class='statu-no'><i class='fa fa-ban'></i> 已拒绝&nbsp;</span>"; + if (WST.GRANT.HZRZSH_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else { + h += "<span class='statu-wait'><i class='fa fa-clock-o'></i> 待审核&nbsp;</span>"; + if (WST.GRANT.HZRZSH_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>审核</a> "; + } + } + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Users/getCompanyReview'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-173}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function toEdit(id){ + location.href=WST.U('admin/users/toEdit','id='+id); +} +function toRecharge(id){ + location.href=WST.U('admin/users/toRecharge','id='+id); +} +function toExport(){ + let params = {}; + params = WST.getParams('.query'); + let box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/users/toExport',params); + }}); +} + +function toDel(id,userType){ + let msg = (userType==1)?"您要删除的用户是商家用户,您确定要删除吗?":"您确定要删除该用户吗?"; + let box = WST.confirm({content:msg,yes:function(){ + let loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Users/del'),{id:id},function(data,textStatus){ + layer.close(loading); + let json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + userQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function userQuery(){ + let query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +function initApplyGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'账号', name:'loginName', width: 130,sortable:true}, + {title:'用户名', name:'trueName' ,width:100,sortable:true}, + {title:'手机号码', name:'userPhone' ,width:100,sortable:true}, + {title:'店铺名', name:'shopName' ,width:100,sortable:true}, + {title:'直营人', name:'userName' ,width:100,sortable:true}, + {title:'店铺电话', name:'phone' ,width:100,sortable:true}, + {title:'申请级别', name:'applyLevel' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + var str = ''; + switch(val){ + case '2': + str = '商超'; + break; + case '3': + str = '商厦'; + break; + case '4': + str = '商都'; + break; + + } + return str; + }}, + {title:'确认书', name:'confirmImg' ,width:100,sortable:true ,renderer:function(val,item,rowIndex) { + return"<span><img class='uploadImg' style='width:80px;height:80px;' src='"+WST.conf.IMGURL+'/'+val+"'</span>"; + }}, + {title:'店铺图片组', name:'shopImg' ,width:100,sortable:true ,renderer:function(val,item,rowIndex) { + return"<span data-imgs='"+val+"' class='showShopImg'>查看</span>"; + }}, + {title:'申请区域', name:'province' ,width:100,sortable:true ,renderer:function(val,item,rowIndex) { + var html='<span>'+item.province.areaName+'-'+item.city.areaName+'-'; + switch(item.applyLevel){ + case '4': + html +='<a style="color:red;">'+item.county.areaName+'</a>'; + // html +=item.town.areaName+'-'+item.village.areaName; + break; + case '3': + html +=item.county.areaName+'-'; + html +='<a style="color:red;">'+item.town.areaName+'</a>'; + // html +=item.village.areaName; + break; + case '2': + html +=item.county.areaName+'-'+item.town.areaName+'-'; + html +='<a style="color:red;">'+item.village.areaName+'</a>'; + break; + } + html+='</span>'; + return html; + }}, + {title:'申请时间', name:'createTime' ,width:120,sortable:true,renderer:function(val,item,rowIndex) { + return getLocalTime(val); + + }}, + {title:'状态/操作', name:'status' ,width:60,sortable:true, renderer:function(val,item,rowIndex) { + let h = ""; + if(val==1){ + h += "<span class='statu-yes'><i class='fa fa-check-circle'></i> 已通过&nbsp;</span>"; + if (WST.GRANT.SQSJ_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else if(val==2){ + h += "<span class='statu-no'><i class='fa fa-ban'></i> 已拒绝&nbsp;</span>"; + if (WST.GRANT.SQSJ_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>修改</a> "; + } + }else { + h += "<span class='statu-wait'><i class='fa fa-clock-o'></i> 待审核&nbsp;</span>"; + if (WST.GRANT.SQSJ_01) { + h += "<a data-id='"+item.id+"'class='btn btn-blue authAction'> <i class='fa fa-pencil'></i>审核</a> "; + } + } + return h; + } + }]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Users/getUserUpdateList'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-173}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function editInit(){ + /* 表单验证 */ + $('#userForm').validator({ + dataFilter: function(data) { + if (data.ok === '该登录账号可用' ) return ""; + else return "已被注册"; + }, + rules: { + loginName: function(element) { + return /\w{5,}/.test(element.value) || '账号应为5-16字母、数字或下划线'; + }, + myRemote: function(element){ + return $.post(WST.U('admin/users/checkLoginKey'),{'loginName':element.value,'userId':$('#userId').val()},function(data,textStatus){}); + } + }, + fields: { + loginName: { + rule:"required;loginName;myRemote", + msg:{required:"请输入会员账号"}, + tip:"请输入会员账号", + ok:"", + }, + userPhone: { + rule:"mobile;myRemote", + ok:"", + }, + userEmail: { + rule:"email;myRemote", + ok:"", + }, + userScore: { + rule:"integer[+0]", + msg:{integer:"当前积分只能是正整数"}, + tip:"当前积分只能是正整数", + ok:"", + }, + userTotalScore: { + rule:"match[gte, userScore];integer[+0];", + msg:{integer:"当前积分只能是正整数",match:'会员历史积分必须不小于会员积分'}, + tip:"当前积分只能是正整数", + ok:"", + }, + userQQ: { + rule:"integer[+]", + msg:{integer:"QQ只能是数字"}, + tip:"QQ只能是数字", + ok:"", + }, + + }, + + valid: function(form){ + let params = WST.getParams('.ipt'); + let loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Users/'+((params.userId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + let json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Users/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + + + +//上传头像 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'users'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + let json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#userPhoto').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="152" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +/** + * 时间戳格式化函数 + */ +function getLocalTime(nS) { + return new Date(parseInt(nS) * 1000).toLocaleString().substr(0,19); +} \ No newline at end of file diff --git a/hyhproject/admin/view/users/company_review_list.html b/hyhproject/admin/view/users/company_review_list.html new file mode 100755 index 0000000..d1d7508 --- /dev/null +++ b/hyhproject/admin/view/users/company_review_list.html @@ -0,0 +1,32 @@ +<script src="users.js"></script>{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/users/auth.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>合作认证审核列表。</li> + </ul> +</div> +<div class="wst-toolbar"> + <form autocomplete="off" > + <div id="query" style="float:left;"> + <input type="text" name="loginName" placeholder='账号/手机' id="loginName" class="query" /> + <button type="button" class="btn btn-primary" onclick="javascript:userQuery()" ><i class="fa fa-search"></i>查询</button> + </div><br /> + </form> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + + $(function(){QLG.init(2);initCompanyGrid()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/users/edit.html b/hyhproject/admin/view/users/edit.html new file mode 100755 index 0000000..108e731 --- /dev/null +++ b/hyhproject/admin/view/users/edit.html @@ -0,0 +1,103 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__ADMIN__/users/users.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="userForm" autocomplete="off" class='layui-form'> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>账号<font color='red'>*</font>:</th> + <td width='370'> + {if ($data['userId']>0)} + {$data['loginName']} + {else /} + <input type="text" class="ipt" id="loginName" name="loginName" /> + {/if} + + </td> + <td rowspan="5"> + <div id="preview" > + <img src="__IMGURL__/{if $data['userPhoto']==''}{:WSTConf('CONF.userLogo')}{else}{$data['userPhoto']}{/if}" height="150" /> + </div> + <div id='adFilePicker' style="margin-left:40px;">上传头像</div> + <input type="hidden" id="userPhoto" class="ipt" /> + <span id='uploadMsg'></span> + + </td> + </tr> + {if ((int)$data['userId']==0)} + <tr> + <th>密码<font color='red'>*</font>:</th> + <td><input type="password" id='loginPwd' class='ipt' maxLength='20' value='66666666' data-rule="登录密码: required;length[6~20]" data-target="#msg_loginPwd"/> + <span id='msg_loginPwd'>(默认为66666666)</span> + </td> + </tr> + {/if} + <tr> + <th>用户名:</th> + <td> + <input type="text" class="ipt" id="userName" name="userName" value="{$data['userName']}" /> + </td> + </tr> + <tr> + <th>性别<font color='red'>*</font>:</th> + <td> + <label><input type="radio" class="ipt" id="userSex" name="userSex" <?=($data['userSex']==1)?'checked':'';?> value="1" title='男'/></label> + <label><input type="radio" class="ipt" id="userSex" name="userSex" <?=($data['userSex']==2)?'checked':'';?> value="2" title='女'/></label> + <label><input type="radio" class="ipt" id="userSex" name="userSex" <?=($data['userSex']==0)?'checked':'';?> value="0" title='保密'/></label> + </td> + </tr> + <tr> + <th>手机号码:</th> + <td> + <input type="text" class="ipt" id="userPhone" name="userPhone" value="{$data['userPhone']}" /> + </td> + </tr> + <tr> + <th>电子邮箱:</th> + <td> + <input type="text" class="ipt" id="userEmail" name="userEmail" value="{$data['userEmail']}" /> + </td> + </tr> + <tr> + <th>QQ:</th> + <td> + <input type="text" class="ipt" id="userQQ" name="userQQ" value="{$data['userQQ']}" /> + </td> + </tr> + <tr> + <th>是否允许举报<font color='red'>*</font>:</th> + <td> + <label><input type="radio" class="ipt" id="isInform" name="isInform" <?=($data['isInform']==1)?'checked':'';?> value="1" title='允许举报商品'/></label> + <label><input type="radio" class="ipt" id="isInform" name="isInform" <?=($data['isInform']==0)?'checked':'';?> value="0" title='禁止举报商品'/></label> + </td> + </tr> + {if ((int)$data['userId']==0)} + <tr> + <th>会员状态<font color='red'>*</font>:</th> + <td> + <input type="checkbox" style='width:80px;' class="ipt" checked name="userStatus" id='userStatus' lay-skin="switch" title="开关" value='1' lay-text="启用|停用"> + </td> + </tr> + {/if} + + <tr> + <td colspan='2' align='center'> + <input type="hidden" name="id" id="userId" class="ipt" value="<?=(int)$data['userId']?>" /> + <button type="submit" class="btn btn-primary btn-mright" ><i class="fa fa-check"></i>提交</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){editInit()}); +</script> + +{/block} + diff --git a/hyhproject/admin/view/users/list.html b/hyhproject/admin/view/users/list.html new file mode 100755 index 0000000..66f5beb --- /dev/null +++ b/hyhproject/admin/view/users/list.html @@ -0,0 +1,49 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/users/users.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于管理会员(商家的会员身份)资料,您可以通过各种条件查询会员资料。</li> + <li>本功能主要以买家身份涉及的资料为主,例如买家的积分,资金和消费记录。商家资金在财务模块的资金管理中查看。</li> + </ul> +</div> +<div class="wst-toolbar"> + <form autocomplete="off" > + <div id="query" style="float:left;"> + <select name="userType" id="userType" class="query"> + <option value="">会员类型</option> + <option value="0">普通会员</option> + <option value="1">商家</option> + </select> + <input type="text" name="loginName1" placeholder='账号/店铺名称' id="loginName1" class="query" /> + <input type="text" name="loginPhone" placeholder='手机号码' id="loginPhone" class="query" /> + <input type="text" name="loginEmail" placeholder='电子邮箱' id="loginEmail" class="query" /> + <button type="button" class="btn btn-primary" onclick="javascript:userQuery()" ><i class="fa fa-search"></i>查询</button> + + </div> + + {if WSTGrant('HYGL_01')} <button type="button" class="btn btn-primary f-right btn-fixtop" style='margin-left:10px;' onclick='javascript:toExport(0)'><i class="fa fa-sign-in"></i>导出</button> + <button type="button" class="btn btn-success f-right" style='margin-top:3px;' onclick="javascript:toEdit()"><i class="fa fa-plus"></i>新增</button> + + {/if} + <div style="clear:both"></div> +</form> + + +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + + $(function(){initGrid()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/users/personal_review_list.html b/hyhproject/admin/view/users/personal_review_list.html new file mode 100755 index 0000000..474b51a --- /dev/null +++ b/hyhproject/admin/view/users/personal_review_list.html @@ -0,0 +1,32 @@ +<script src="users.js"></script>{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/users/auth.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>个体认证审核列表。</li> + </ul> +</div> +<div class="wst-toolbar"> + <form autocomplete="off" > + <div id="query" style="float:left;"> + <input type="text" name="loginName" placeholder='账号/手机' id="loginName" class="query" /> + <button type="button" class="btn btn-primary" onclick="javascript:userQuery()" ><i class="fa fa-search"></i>查询</button> + </div><br /> + </form> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + + $(function(){QLG.init(1);initPersonalGrid()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/users/recharge.html b/hyhproject/admin/view/users/recharge.html new file mode 100755 index 0000000..e68c30b --- /dev/null +++ b/hyhproject/admin/view/users/recharge.html @@ -0,0 +1,170 @@ +{extend name="base" /} + +{block name="css"} + +{/block} + +{block name="js"} + +{/block} + +{block name="main"} + +<div class="l-loading" style="display: block" id="wst-loading"></div> + +<table class='wst-form wst-box-top'> + + <tr> + + <th width='150'>账号<font color='red'>*</font>:</th> + + <td width='370'> + + {if ($data['userId']>0)} + + {$data['loginName']} + + {else /} + + <input type="text" class="ipt" id="loginName" name="loginName" /> + + {/if} + + + + </td> + + </tr> + + <tr> + + <th>选择币种<font color='red'>*</font>:</th> + + <td> + + <select class="ipt" id="rechargeCurrency" name="rechargeCurrency" > + <option value="0">请选择</option> + <option value="1">预获产品券</option> + <option value="2">预获优惠券</option> + <option value="3">产品券</option> + <option value="4">优惠券</option> + <option value="5">旺旺券</option> + </select> + + </td> + + </tr> + + <tr> + + <th>充值/扣除<font color='red'>*</font>:</th> + + <td> + + <input type="radio" name="rechargeType" id="recharge" value="1" checked> + + <label for="recharge">充值</label> + + <input type="radio" name="rechargeType" id="deduct" value="0"> + + <label for="deduct">扣除</label> + + </td> + + </tr> + + <tr> + + <th>充值/扣除数量<font color='red'>*</font>:</th> + + <td> + + <input type="text" class="ipt" id="rechargeNum" name="rechargeNum" value="" /> + + </td> + + </tr> + + + + + + <tr> + + <td colspan='2' align='center'> + + <input type="hidden" name="id" id="userId" class="ipt" value="<?=(int)$data['userId']?>" /> + + <button type="submit" class="btn btn-primary btn-mright submit" ><i class="fa fa-check"></i>提交</button> + + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + + </td> + + </tr> + +</table> + +<script> + + $(".submit").click(function(){ + + + + var userId = $('#userId').val(); + + var loginName = $('#loginName').val(); + + var rechargeCurrency = $('#rechargeCurrency').val(); + + var rechargeType = $("input[name='rechargeType']:checked").val(); + + var rechargeNum = $('#rechargeNum').val(); + + if(!rechargeNum || rechargeNum <= 0){ + + WST.msg('请正确输入充值或扣除数量'); + + return; + + } + + $(".submit").attr('disabled','disabled'); + $.ajax({ + + type: "POST", + + url:WST.U('admin/users/recharge'), + + data:{"loginName":loginName,"userId":userId,"rechargeNum":rechargeNum,"rechargeType":rechargeType,"rechargeCurrency":rechargeCurrency}, + + dataType:"json", + + success:function(response){ + + alert(response.msg); + + $(".submit").removeAttr('disabled'); + + },error:function(data){ + + WST.msg(data); + + $(".submit").removeAttr('disabled'); + + } + + }); + + }); + + + +</script> + + + +{/block} + + + diff --git a/hyhproject/admin/view/users/update_list.html b/hyhproject/admin/view/users/update_list.html new file mode 100755 index 0000000..dd4c80c --- /dev/null +++ b/hyhproject/admin/view/users/update_list.html @@ -0,0 +1,32 @@ +<script src="users.js"></script>{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/users/auth.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>申请升级审核列表。</li> + </ul> +</div> +<div class="wst-toolbar"> + <form autocomplete="off" > + <div id="query" style="float:left;"> + <input type="text" name="loginName" placeholder='账号/手机' id="loginName" class="query" /> + <button type="button" class="btn btn-primary" onclick="javascript:userQuery()" ><i class="fa fa-search"></i>查询</button> + </div><br /> + </form> +</div> +<div class='wst-grid'> +<div id="mmg" class="mmg"></div> +<div id="pg" style="text-align: right;"></div> +</div> +<script> + + $(function(){QLG.init(3);initApplyGrid();}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/users/users.js b/hyhproject/admin/view/users/users.js new file mode 100755 index 0000000..b1df54d --- /dev/null +++ b/hyhproject/admin/view/users/users.js @@ -0,0 +1,205 @@ +var mmg; +function initGrid(){ + $("body").on("click",'.uploadImg',function(){ + layer.open({ + type: 1, + title: false, + closeBtn: 0, + area: '90%', + skin: 'layui-layer-nobg', //没有背景色 + shadeClose: true, + content: '<div ><img src="'+$(this).attr('src')+'"></div>' + }); + }); + var h = WST.pageHeight(); + var cols = [ + {title:'账号', name:'loginName', width: 130,sortable:true}, + {title:'用户名', name:'userName' ,width:100,sortable:true}, + {title:'手机号码', name:'userPhone' ,width:100,sortable:true}, + {title:'推荐人', name:'pName' ,width:60,sortable:true}, + {title:'预获产品券', name:'expectedProductNum' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'预获优惠券', name:'expectedCouponsNum' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'产品券', name:'productNum' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'优惠券', name:'couponsNum' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'旺旺券', name:'wangNum' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '¥'+val; + }}, + {title:'注册确认书', name:'regConfirmImg' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + return '<img class="uploadImg" style="width:80px;height:80px;" src = "'+WST.conf.IMGURL+'/'+val+'"/>'; + }}, + // {title:'可用金额', name:'userMoney' ,width:50,sortable:true, renderer:function(val,item,rowIndex){ + // return '¥'+val; + // }}, + // {title:'冻结金额', name:'lockMoney' ,width:40,sortable:true, renderer:function(val,item,rowIndex){ + // return '¥'+val; + // }}, + // {title:'积分', name:'userScore' ,width:50,sortable:true}, + // {title:'ECT', name:'userECT' ,width:50,sortable:true}, + // {title:'等级', name:'rank' ,width:60,sortable:true}, + {title:'注册时间', name:'createTime' ,width:120,sortable:true}, + {title:'状态', name:'userStatus' ,width:60,sortable:true, renderer:function(val,item,rowIndex){ + return (val==1)?"<span class='statu-yes'><i class='fa fa-check-circle'></i> 启用&nbsp;</span>":"<span class='statu-no'><i class='fa fa-ban'></i> 停用&nbsp;</span>"; + }}, + {title:'操作', name:'' ,width:150, align:'center', renderer: function(val,rowdata,rowIndex){ + var h = ""; + if(WST.GRANT.HYGL_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/Users/toEdit','id='+rowdata['userId'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.HYGL_03)h += "<a class='btn btn-red' href='javascript:toDel(" + rowdata['userId'] + ","+rowdata['userType']+")'><i class='fa fa-trash-o'></i>删除</a> "; + if(WST.GRANT.HYGL_04)h += "<a class='btn btn-blue' href='javascript:toRecharge(" + rowdata['userId'] + ")'><i class='fa fa-pencil'></i>充值</a> " + h += "<br/><a href='"+WST.U('admin/userscores/touserscores','id='+rowdata['userId'])+"'>积分</a> "; + h += "<a href='"+WST.U('admin/logmoneys/tologmoneys','id='+rowdata['userId'])+"&type=0'>用户资金</a> "; + h += "<a href='"+WST.U('admin/orders/index','userId='+rowdata['userId'])+"&type=0'>消费信息</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-173,indexCol: true,indexColWidth:50, cols: cols,method:'POST', + url: WST.U('admin/Users/pageQuery'), fullWidthRows: true, autoLoad: true,remoteSort: true,sortName:'createTime',sortStatus:'desc', + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-173}); + }else{ + mmg.resize({height:h-128}); + } + }}); +} +function toEdit(id){ + location.href=WST.U('admin/users/toEdit','id='+id); +} +function toRecharge(id){ + location.href=WST.U('admin/users/toRecharge','id='+id); +} +function toExport(){ + var params = {}; + params = WST.getParams('.query'); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('admin/users/toExport',params); + }}); +} + +function toDel(id,userType){ + var msg = (userType==1)?"您要删除的用户是商家用户,您确定要删除吗?":"您确定要删除该用户吗?"; + var box = WST.confirm({content:msg,yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Users/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + userQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function userQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +} +function editInit(){ + /* 表单验证 */ + $('#userForm').validator({ + dataFilter: function(data) { + if (data.ok === '该登录账号可用' ) return ""; + else return "已被注册"; + }, + rules: { + loginName: function(element) { + return /\w{5,}/.test(element.value) || '账号应为5-16字母、数字或下划线'; + }, + myRemote: function(element){ + return $.post(WST.U('admin/users/checkLoginKey'),{'loginName':element.value,'userId':$('#userId').val()},function(data,textStatus){}); + } + }, + fields: { + loginName: { + rule:"required;loginName;myRemote", + msg:{required:"请输入会员账号"}, + tip:"请输入会员账号", + ok:"", + }, + userPhone: { + rule:"mobile;myRemote", + ok:"", + }, + userEmail: { + rule:"email;myRemote", + ok:"", + }, + userScore: { + rule:"integer[+0]", + msg:{integer:"当前积分只能是正整数"}, + tip:"当前积分只能是正整数", + ok:"", + }, + userTotalScore: { + rule:"match[gte, userScore];integer[+0];", + msg:{integer:"当前积分只能是正整数",match:'会员历史积分必须不小于会员积分'}, + tip:"当前积分只能是正整数", + ok:"", + }, + userQQ: { + rule:"integer[+]", + msg:{integer:"QQ只能是数字"}, + tip:"QQ只能是数字", + ok:"", + }, + + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/Users/'+((params.userId==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/Users/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + + + +//上传头像 + WST.upload({ + pick:'#adFilePicker', + formData: {dir:'users'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#userPhoto').val(json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="152" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} diff --git a/hyhproject/admin/view/userscores/box.html b/hyhproject/admin/view/userscores/box.html new file mode 100755 index 0000000..ec2d6ab --- /dev/null +++ b/hyhproject/admin/view/userscores/box.html @@ -0,0 +1,36 @@ +<form id="userForm" autocomplete="off" > +<table class='wst-form wst-box-top'> + <tr> + <th width='120'>账号<font color='red'>*</font>:</th> + <td height='25'> + {$object['loginName']}{if $object['userName']!=''}({$object['userName']}){/if} + </td> + </tr> + <tr> + <th>类型<font color='red'>*</font>:</th> + <td width='370' class='layui-form'> + <label><input type='radio' class='ipt' name='scoreType' value='1' checked title='增加'/> </label> + <label><input type='radio' class='ipt' name='scoreType' value='0' title='减少'/> </label> + </td> + </tr> + <tr> + <th>调节积分<font color='red'>*</font>:</th> + <td width='370'> + <input type='text' id='score' class='ipt' maxLength='8' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/> + </td> + </tr> + <tr> + <th>调节备注<font color='red'>*</font>:</th> + <td width='370'> + <textarea style='width:80%;height:50px;' class='ipt' id='dataRemarks' maxLength='200'></textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center' style='padding-top:8px;'> + <input type="hidden" name="id" id="userId" class="ipt" value="<?=(int)$object['userId']?>" /> + <input type="button" value="提交" class='btn btn-primary btn-mright' onclick='javascript:editScore()'/> + <input type="button" onclick="javascript:closeFrom()" class='btn' value="返回" /> + </td> + </tr> +</table> +</form> \ No newline at end of file diff --git a/hyhproject/admin/view/userscores/list.html b/hyhproject/admin/view/userscores/list.html new file mode 100755 index 0000000..676466b --- /dev/null +++ b/hyhproject/admin/view/userscores/list.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/userscores/userscores.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + <ul class="layui-tab-title"> + <li class="layui-this">{$object['userName']}({$object['loginName']})积分流水</li> + </ul> + <div class="layui-tab-content" style='padding:0px;'> + <div class="layui-tab-item layui-show"> + <div class="wst-toolbar"> + <input type="text" id="startDate" name="startDate" placeholder='开始日期' class="laydate-icon ipt" maxLength="20" /> + 至 + <input type="text" id="endDate" name="endDate" placeholder='结束日期' class="laydate-icon ipt" maxLength="20" /> + <button class="btn btn-primary btn-mright" onclick='javascript:loadGrid({$object['userId']})'><i class='fa fa-search'></i>查询</button> + <button class="btn btn-gray f-right" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + <button class="btn btn-success btn-mright f-right" onclick="javascript:toAdd({$object['userId']})"><i class='fa fa-plus'></i>新增</button> + + <div style='clear: both'></div> + </div> + <div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> + </div> + </div> +</div> +<script> + $(function(){gridInit({$object['userId']});}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/userscores/userscores.js b/hyhproject/admin/view/userscores/userscores.js new file mode 100755 index 0000000..93efe50 --- /dev/null +++ b/hyhproject/admin/view/userscores/userscores.js @@ -0,0 +1,61 @@ +var mmg; +function gridInit(id){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startDate' + }); + laydate.render({ + elem: '#endDate' + }); + var h = WST.pageHeight(); + var cols = [ + {title:'来源', name:'dataSrc', width: 60}, + {title:'积分变化', name:'dataSrc',width: 60,renderer: function (val,item,rowIndex){ + if(item['scoreType']==1){ + return '<font color="red">+'+item['score']+'</font>'; + }else{ + return '<font color="green">-'+item['score']+'</font>'; + } + }}, + {title:'备注', name:'dataRemarks',width: 60}, + {title:'日期', name:'createTime',width: 40} + ]; + + mmg = $('.mmg').mmGrid({height: (h-120),indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/userscores/pageQuery','id='+id), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function loadGrid(id){ + mmg.load({page:1,id:id,startDate:$('#startDate').val(),endDate:$('#endDate').val()}); +} +var w; +function toAdd(id){ + var ll = WST.msg('正在加载信息,请稍候...'); + $.post(WST.U('admin/userscores/toAdd',{id:id}),{},function(data){ + layer.close(ll); + w =WST.open({type: 1,title:"调节会员积分",shade: [0.6, '#000'],offset:'50px',border: [0],content:data,area: ['550px', '260px'],success:function(){ + layui.form.render(); + }}); + }); +} +function editScore(){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/userscores/add'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + closeFrom(); + loadGrid(params.userId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function closeFrom(){ + layer.close(w); +} \ No newline at end of file diff --git a/hyhproject/admin/view/wsysconfigs/edit.html b/hyhproject/admin/view/wsysconfigs/edit.html new file mode 100755 index 0000000..a00db9f --- /dev/null +++ b/hyhproject/admin/view/wsysconfigs/edit.html @@ -0,0 +1,68 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<style> +body{overflow:hidden} +</style> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}' type="text/javascript"></script> +<script src="__ADMIN__/wsysconfigs/wsysconfigs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style> +input[type="text"]{width:70%} +textarea{width:70%;height:100px;} +#wst-tab-5 input[type="text"]{width:50%} +</style> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于设置与微信认证平台交互的认证信息。“微信验证代码”需与微信自定义菜单中的state参数值保持一致。</li> + </ul> +</div> +<form autocomplete='off'> +<div class='wst-tab layui-form' style='margin-top:20px'> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>是否开启微信端:</th> + <td> + <input type="checkbox" {if $object['wxenabled']==1}checked{/if} value='1' class="ipt" id="wxenabled" name="wxenabled" lay-skin="switch" lay-filter="wxenabled" lay-text="开启|关闭"> + </td> + </tr> + <tr> + <th width='150'>微信 APP ID:</th> + <td><input type="text" id='wxAppId' class='ipt' value="{$object['wxAppId']}" maxLength='100'/></td> + </tr> + <tr> + <th>微信 APP SECRET</th> + <td><input type="text" id='wxAppKey' class='ipt' value="{$object['wxAppKey']}" maxLength='100'/></td> + </tr> + <tr> + <th>微信验证代码:</th> + <td><input type="text" id='wxAppCode' class='ipt' value="{$object['wxAppCode']}" maxLength='100'/></td> + </tr> + <tr> + <th>微信公众号二维码:</th> + <td> + <div id='wxAppLogoPicker'>请上传微信公众号二维码</div><span id='wxAppLogoMsg'></span> + <div id="wxAppLogoPrevw"> + {if($object["wxAppLogo"])} + <img src='__IMGURL__/{$object["wxAppLogo"]}' width='120' hiegth='120'/> + {/if} + </div> + <input type="hidden" id='wxAppLogo' class='ipt' value='{$object["wxAppLogo"]}'/> + </td> + </tr> + {if WSTGrant('WX_GZHSZ_04')} + <tr> + <td colspan='2' style='padding-left:300px;padding-top:30px'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + {/if} + </table> +</div> +</form> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wsysconfigs/wsysconfigs.js b/hyhproject/admin/view/wsysconfigs/wsysconfigs.js new file mode 100755 index 0000000..a66252c --- /dev/null +++ b/hyhproject/admin/view/wsysconfigs/wsysconfigs.js @@ -0,0 +1,32 @@ +$(function(){ + WST.upload({ + k:"wxAppLogo", + pick:"#wxAppLogoPicker", + formData: {dir:'sysconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#wxAppLogoMsg').empty().hide(); + $('#wxAppLogoPrevw').empty(); + $('#wxAppLogoPrevw').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.name+'" width="120" hiegth="120"/>'); + $('#wxAppLogo').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#'+this.k+'Msg').show().html('已上传'+rate+"%"); + } + }); +}) +function edit(){ + if(!WST.GRANT.WX_GZHSZ_04)return; + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在保存数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wsysconfigs/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/admin/view/wxmenus/edit.html b/hyhproject/admin/view/wxmenus/edit.html new file mode 100755 index 0000000..82ba9c1 --- /dev/null +++ b/hyhproject/admin/view/wxmenus/edit.html @@ -0,0 +1,100 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<style> +body{overflow: hidden} +</style> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/webuploader/webuploader.js?v={$v}" type="text/javascript" ></script> +<script src="__ADMIN__/wxmenus/wxmenus.js?v={$v}" type="text/javascript"></script> +<script> +$(function () { + {if condition="$object['menuId'] !=0 "} + WST.setValues({$object}); + {/if} + $('#menuForm').validator({ + fields: { + menuName: { + tip: "请输入菜单名称", + rule: '菜单名称:required;length[~16];' + } + }, + valid: function(form){ + var menuId = $('#menuId').val(); + toEdits(menuId); + } + }) +}); +</script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="menuForm" autocomplete="off"> +<input type='hidden' id='menuId' name="menuId" value="{$menuId}" class='ipt'/> +<input type='hidden' id='parentId' name="parentId" value="{$parentId}" class='ipt'/> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>菜单名称<font color='red'>*</font>:</th> + <td><input type="text" id='menuName' name='menuName' maxLength='20' style='width:300px;' class='ipt'/></td> + </tr> + <tr style="display:none;"> + <th>子菜单内容<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' id="content" name='content' value='0' class='ipt' checked onclick="javascript:wayChange(1)">跳转网页 + </label> + <label> + <input type='radio' id="content" name='content' value='1' class='ipt' onclick="javascript:wayChange(0)">发送消息 + </label> + </td> + </tr> + <tr id="urltext"> + <th>跳转网址:</th> + <td><input type="text" id='menuUrl' name='menuUrl' maxLength='255' style='width:500px;' class='ipt' data-tip="输入网址时以http://或https://开头"/></td> + </tr> + <tr class="newstext" style="display:none;"> + <th></th> + <td> + <label> + <input type='radio' name='material' value='1' checked onclick="javascript:matChange(1)">文字 + </label> + <label> + <input type='radio' name='material' value='2' onclick="javascript:matChange(2)">图片 + </label> + <label> + <input type='radio' name='material' value='3' onclick="javascript:matChange(3)">图文 + </label> + <label> + <input type='radio' name='material' value='4' onclick="javascript:matChange(4)">语音 + </label> + <label> + <input type='radio' name='material' value='5' onclick="javascript:matChange(5)">视频 + </label> + </td> + </tr> + <tr class="newstext" style="display:none;"> + <th></th> + <td> + <div class="wst-view j-view" id="view1"><a href="javascript:void(0);" onclick="javascript:addMaterial(1);">选择文本</a></div> + <div class="wst-view j-view" id="view2" style="display:none;"><a href="javascript:void(0);" onclick="javascript:addMaterial(2);">选择文本素材</a></div> + <div class="wst-view j-view" id="view3" style="display:none;"><a href="javascript:void(0);" onclick="javascript:addMaterial(3);">选择图文素材</a></div> + <div class="wst-view j-view" id="view4" style="display:none;"><a href="javascript:void(0);" onclick="javascript:addMaterial(4);">选择语音素材</a></div> + <div class="wst-view j-view" id="view5" style="display:none;"><a href="javascript:void(0);" onclick="javascript:addMaterial(5);">选择视频素材</a></div> + </td> + </tr> + <tr> + <th width="100">排序号<font color="red">*</font>:</th> + <td><input type="text" id="menuSort" name="menuSort" class="ipt" style="width:60px;" onkeypress="return WST.isNumberKey(event);" onkeyup="javascript:WST.isChinese(this,1)" maxlength="10" value="0" aria-required="true" data-tip="请输入排序号"></td> + </tr> + <tr> + <td colspan='2' align='center'> + <button type="submit" class="btn btn-primary btn-mright"><i class="fa fa-check"></i>保&nbsp;存</button> + <button type="button" class="btn" onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返&nbsp;回</button> + </td> + </tr> +</table> + </form> +<div id='wxmenusBox' style='display:none'> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wxmenus/list.html b/hyhproject/admin/view/wxmenus/list.html new file mode 100755 index 0000000..08bc5f1 --- /dev/null +++ b/hyhproject/admin/view/wxmenus/list.html @@ -0,0 +1,41 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/wstgridtree.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/wxmenus/wxmenus.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initGrid();inView();}) +</script> +{/block} +{block name="main"} +<style> +html{height: 100%;} +body{height: 100%;overflow:hidden} +.mmGrid{border-bottom:0px} +</style> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能主要用于管理微信公众号菜单,使用前请先在微信认证平台中停用了微信公众号自定义菜单功能。</li> + </ul> +</div> +<div class="wst-toolbar"> +{if WSTGrant('WX_ZDYCD_01')} + <button class="btn btn-success f-right" onclick='javascript:toEdit(0,0)'><i class='fa fa-plus'></i>新增</button> +{/if} +{if WSTGrant('WX_ZDYCD_00')} + <button class="btn btn-success f-right" style="margin-right:10px;" onclick='javascript:adSynchro();'><i class='fa fa-cloud-upload'></i>同步到微信菜单</button> + <button class="btn btn-success f-right" style="margin-right:10px;" onclick='javascript:wxSynchro();'><i class='fa fa-cloud-upload'></i>与微信菜单同步</button> +{/if} + <div style='clear:both'></div> +</div> +<div class="wst-views"> + <div class="reveal"> + <div class="revealt"></div> + <div class="revealb"><i></i><div class="ui" id="list"></div></div> + </div> +</div> + <div class='mmGrid layui-form wst-maingr' id="maingrid"></div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wxmenus/wxmenus.js b/hyhproject/admin/view/wxmenus/wxmenus.js new file mode 100755 index 0000000..cfe74c9 --- /dev/null +++ b/hyhproject/admin/view/wxmenus/wxmenus.js @@ -0,0 +1,185 @@ +var grid; +function initGrid(){ + grid = $('#maingrid').WSTGridTree({ + url:WST.U('admin/wxmenus/pageQuery'), + pageSize:10000, + pageSizeOptions:[10000], + height:'99%', + width:'100%', + minColToggle:6, + delayLoad :true, + rownumbers:true, + columns: [ + { display: '分类名称',width:120,name: 'menuName', id:'menuId', align: 'left',isSort: false}, + { display: '页面地址',name: 'menuUrl',isSort: false, + render: function (rowdata){ + var m = "<div class='urled' style='word-wrap: break-word;padding:6px;'>"+rowdata.menuUrl+"</div>"; + return m; + }}, + { display: '类型', name: 'type',width: 100,isSort: false, + render: function (rowdata){ + if(rowdata['menuType']==0)t = ""; + if(rowdata['menuType']==1)t = "点击推送"; + if(rowdata['menuType']==2)t = "跳转地址"; + if(rowdata['menuType']==3)t = "扫码推送"; + if(rowdata['menuType']==4)t = "扫码推送且弹出“消息接收中”提示框"; + if(rowdata['menuType']==5)t = "系统拍照发图"; + if(rowdata['menuType']==6)t = "拍照或者相册发图"; + if(rowdata['menuType']==7)t = "微信相册发图"; + if(rowdata['menuType']==8)t = "地理位置选择"; + if(rowdata['menuType']==9)t = "下发消息(除文本消息)"; + if(rowdata['menuType']==10)t = "图文消息地址"; + return t; + }}, + { display: '序号', name: 'menuSort',width: 80,isSort: false}, + { display: '操作', name: 'op',width: 150,isSort: false, + render: function (rowdata){ + var h = ""; + if(WST.GRANT.WX_ZDYCD_01)if(rowdata['parentId']==0)h += "<a class='btn btn-green' href='javascript:toEdit("+rowdata["menuId"]+",0)'><i class='fa fa-plus'></i>新增子菜单</a> "; + if(WST.GRANT.WX_ZDYCD_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["parentId"]+","+rowdata["menuId"]+")'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.WX_ZDYCD_03)h += "<a class='btn btn-red' href='javascript:toDel("+rowdata["parentId"]+","+rowdata["menuId"]+")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ] + }); +} +//与微信菜单同步 +function wxSynchro(){ + var box = WST.confirm({content:"您确定与微信菜单同步吗?",yes:function(){ + var loading = WST.msg('正在同步数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxmenus/synchroWx'),'',function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + inView(); + WST.msg(json.msg,{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +//同步到微信菜单 +function adSynchro(){ + var box = WST.confirm({content:"您确定同步到微信菜单吗?",yes:function(){ + var loading = WST.msg('正在同步数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxmenus/synchroAd'),'',function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function toEdit(parentId,menuId){ + location.href=WST.U('admin/wxmenus/toEdit','menuId='+menuId+'&parentId='+parentId); +} +function wayChange(type){ + if(type==1){ + WST.showHide(1,'#urltext'); + WST.showHide('','.newstext'); + }else{ + WST.showHide('','#urltext'); + WST.showHide(1,'.newstext'); + } +} +function matChange(n){ + $("#view"+n).show().siblings('.j-view').hide(); +} +//素材选择 +function addMaterial(n){ + var title = '选择文本素材'; + if(n==2)title= '选择图文素材'; + if(n==3)title= '选择图文素材'; + if(n==4)title= '选择语音素材'; + if(n==5)title= '选择视频素材'; + var box = WST.open({title:title,type:1,content:$('#wxmenusBox'),area: ['800px', '500px'],btn:['确定','取消'],yes:function(){ + }}); +} +function toEdits(id){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxmenus/'+((id>0)?"edit":"add")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('admin/wxmenus/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function toDel(pid,id){ + var box = WST.confirm({content:"您确定要删除该菜单吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxmenus/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + inView(); + WST.msg(json.msg,{icon:1}); + layer.close(box); + grid.reload(pid); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function inView(){ + $.post(WST.U('admin/wxmenus/listQuery'),'',function(data,textStatus){ + var json = WST.toAdminJson(data); + $("#list").html(''); + if(json && json.length>0){ + var html = []; + for(var i=0;i<json.length;i++){ + var me = json[i]; + html.push('<div class="li" onclick="javascript:liSelected(this);">'+WST.cutStr(me.menuName,8)); + html.push('<div class="lis" style="display:none;">'); + if(me.listSon.length>0){ + for(var s=0;s<me.listSon.length;s++){ + html.push('<span class="list">'+WST.cutStr(me.listSon[s].menuName,8)+'</span>'); + } + } + html.push("</div>"); + html.push("</div>"); + } + $("#list").html(html.join("")); + } + }); +} +function liSelected(obj){ + $(obj).addClass('selected').children('.lis').show(); + $(obj).siblings().removeClass('selected').children('.lis').hide(); +} +$(function(){ + var windowH = $(window).height(); + var windowW = $(window).width(); + $('.urled').css('width',windowW/4); + if(windowH > 820){ + $('.wst-views').css('height',800); + }else{ + $('.wst-views').css('height',windowH-35); + } + $('.wst-maingr').css('width',windowW-335); +}) +$(window).resize(function(){ + var windowH = $(window).height(); + var windowW = $(window).width(); + $('.urled').css('width',windowW/4); + if(windowH > 820){ + $('.wst-views').css('height',800); + }else{ + $('.wst-views').css('height',windowH-35); + } + $('.wst-maingr').css('width',windowW-335); +}) \ No newline at end of file diff --git a/hyhproject/admin/view/wxpassivereplys/news.html b/hyhproject/admin/view/wxpassivereplys/news.html new file mode 100755 index 0000000..c3d32f0 --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/news.html @@ -0,0 +1,38 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/wxpassivereplys/news.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +{if WSTGrant('WX_TWXX_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:location.href='<?=url("wxpassivereplys/newsEdit")?>'"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<script id="tblist" type="text/html"> +{{# var dl = d['Rows'];for(var i = 0; i < dl.length; i++){ }} +<div class='style-box'> + <div class='style-img'> + <a href="javascript:void(0)"> + <img src='{{dl[i]["picUrl"]}}'/> + </a> + </div> + <div class='style-txt'>关键字:{{dl[i]['keyword']}}</div> + <div class='style-txt'>标题:{{dl[i]['title']}}</div> + <div class='style-author'>描述:{{dl[i]['description']}}</div> + <div class='style-op'> + {{# if(WST.GRANT.WX_TWXX_02){ }}<a class='btn btn-blue' onclick="toEdit({{dl[i]['id']}})"><i class='fa fa-pencil'></i>编辑</a> {{# } }}&nbsp; + {{# if(WST.GRANT.WX_TWXX_03){ }}<a class='btn btn-red' onclick="toDel({{dl[i]['id']}})"><i class='fa fa-trash-o'></i>删除</a> {{# } }} + </div> +</div> +{{#}}} +</script> +<div id="maingrid"></div> + + +<script> +$(function (){ + listQuery('home'); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wxpassivereplys/news.js b/hyhproject/admin/view/wxpassivereplys/news.js new file mode 100755 index 0000000..6aca05b --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/news.js @@ -0,0 +1,128 @@ + +function listQuery(){ + var loading = WST.msg('正在获取数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxpassivereplys/newsPageQuery'),{},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + var gettpl = document.getElementById('tblist').innerHTML; + layui.laytpl(gettpl).render(json.data, function(html){ + $('#maingrid').html(html); + }); + } + }); +} + + +function toEdit(id){ + location.href=WST.U('admin/wxpassivereplys/newsEdit',{'id':id}); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxpassivereplys/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + listQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function newsEditInit(){ + /* 表单验证 */ + $('#replyForm').validator({ + fields: { + keyword: { + rule:"required", + msg:{required:"请输入关键字"}, + tip:"请输入关键字", + ok:"", + }, + title: { + rule:"required", + msg:{required:"请输入标题"}, + tip:"请输入标题", + ok:"", + }, + description: { + rule:"required", + msg:{required:"请输入描述"}, + tip:"请输入描述", + ok:"", + }, + picUrl: { + rule:"required", + msg:{required:"封面图片不能为空"}, + tip:"封面图片不能为空", + ok:"", + }, + content: { + rule:"required", + msg:{required:"请输入回复内容"}, + tip:"请输入回复内容", + ok:"", + }, + url: { + rule:"required", + msg:{required:"请输入图文链接"}, + tip:"请输入图文链接", + ok:"", + } + + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxpassivereplys/'+((params.id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/wxpassivereplys/news'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + + +//文件上传 +WST.upload({ + pick:'#adFilePicker', + formData: {dir:'wechat'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toAdminJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + // $('#picUrl').val('http://'+document.domain+WST.conf.ROOT+'/'+json.savePath+json.thumb); + $('#picUrl').val(WST.conf.IMGURL+'/'+json.savePath+json.name); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } +}); + + + +}; + + + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/wxpassivereplys/news_edit.html b/hyhproject/admin/view/wxpassivereplys/news_edit.html new file mode 100755 index 0000000..3c03f77 --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/news_edit.html @@ -0,0 +1,85 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/wxpassivereplys/news.js?v={$v}" type="text/javascript"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} +{block name="main"} +<style> +#replyForm input[type="text"]{ + width: 200px; +} +</style> +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="replyForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>关键字<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="keyword" name="keyword" value="{$data['keyword']}" /> + </td> + </tr> + <tr> + <th width='150'>标题<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="title" name="title" value="{$data['title']}" /> + </td> + </tr> + + <th width='150'>描述<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="description" name="description" value="{$data['description']}" /> + </td> + </tr> + + + + <th width='150'>封面图片<font color='red'>*</font>:</th> + <td> + <div id='adFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='picUrl' class='ipt' {if ($data['picUrl']!='')}value="{$data['picUrl']}"{/if}/> + </td> + </tr> + <th width='150'>封面图片预览<font color='red'> </font>:</th> + <td> + <div style="max-width:360px;max-height:200px;min-height:70px;" id="preview"> + {if ($data['picUrl']!='')} + <img src="{$data['picUrl']}" style="max-width:360px;max-height:200px;" /> + {/if} + </div> + </td> + </tr> + + + <tr> + <th>回复内容<font color='red'>*</font>:</th> + <td> + <textarea id="content" name="content" class="ipt" style="width:300px;height:150px;">{$data['content']}</textarea> + </td> + </tr> + + <th width='150'>图文链接<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="url" name="url" value="{$data['url']}" /> + </td> + </tr> + + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="id" class="ipt" value="{$data['id']}" /> + <input type="hidden" name="msgType" id="msgType" class="ipt" value="news" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> + +</table> +</form> +<script> +$(function(){newsEditInit()}); +</script> + +{/block} + diff --git a/hyhproject/admin/view/wxpassivereplys/text.html b/hyhproject/admin/view/wxpassivereplys/text.html new file mode 100755 index 0000000..a8d22dc --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/text.html @@ -0,0 +1,23 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/wxpassivereplys/text.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +{if WSTGrant('WX_WBXX_01')} +<div class="wst-toolbar"> + <button class="btn btn-success f-right" onclick="javascript:location.href='<?=url("wxpassivereplys/textEdit")?>'"><i class='fa fa-plus'></i>新增</button> + <div style="clear:both"></div> +</div> +{/if} +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script> + $(function(){initGrid()}); +</script> +{/block} diff --git a/hyhproject/admin/view/wxpassivereplys/text.js b/hyhproject/admin/view/wxpassivereplys/text.js new file mode 100755 index 0000000..ab20cbb --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/text.js @@ -0,0 +1,90 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'关键字', name:'keyword', width: 100}, + {title:'回复内容', name:'content', width: 100}, + {title:'操作', name:'' ,width:70, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.WX_WBXX_02)h += "<a class='btn btn-blue' href='"+WST.U('admin/wxpassivereplys/textEdit','id='+item['id'])+"'><i class='fa fa-pencil'></i>修改</a> "; + if(WST.GRANT.WX_WBXX_03)h += "<a class='btn btn-red' href='javascript:toDel(" + item['id'] + ")'><i class='fa fa-trash-o'></i>删除</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-80,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/wxpassivereplys/textPageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} +function toDel(id){ + var box = WST.confirm({content:"您确定要删除该记录吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxpassivereplys/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + addonsQuery(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function textEditInit(){ + /* 表单验证 */ + $('#replyForm').validator({ + fields: { + keyword: { + rule:"required", + msg:{required:"请输入关键字"}, + tip:"请输入关键字", + ok:"", + }, + content: { + rule:"required", + msg:{required:"请输入回复内容"}, + tip:"请输入回复内容", + ok:"", + } + + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxpassivereplys/'+((params.id==0)?"add":"edit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href=WST.U('Admin/wxpassivereplys/text'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + + + + +}; + +//查询 +function addonsQuery(){ + var query = WST.getParams('.query'); + query.page = 1; + mmg.load(query); +}; + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/wxpassivereplys/text_edit.html b/hyhproject/admin/view/wxpassivereplys/text_edit.html new file mode 100755 index 0000000..7e7e5b2 --- /dev/null +++ b/hyhproject/admin/view/wxpassivereplys/text_edit.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/wxpassivereplys/text.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<div class="l-loading" style="display: block" id="wst-loading"></div> +<form id="replyForm" autocomplete="off"> +<table class='wst-form wst-box-top'> + <tr> + <th width='150'>关键字<font color='red'>*</font>:</th> + <td> + <input type="text" class="ipt" id="keyword" name="keyword" value="{$data['keyword']}" /> + </td> + </tr> + <th>回复内容<font color='red'>*</font>:</th> + <td> + <textarea id="content" name="content" class="ipt" style="width:300px;height:150px;">{$data['content']}</textarea> + </td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <input type="hidden" name="id" id="id" class="ipt" value="{$data['id']}" /> + <input type="hidden" name="msgType" id="msgType" class="ipt" value="text" /> + <button type="submit" class='btn btn-primary btn-mright'><i class="fa fa-check"></i>提交</button> + <button type="button" class='btn' onclick="javascript:history.go(-1)"><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script> +$(function(){textEditInit()}); +</script> + +{/block} + diff --git a/hyhproject/admin/view/wxtemplatemsgs/edit.html b/hyhproject/admin/view/wxtemplatemsgs/edit.html new file mode 100755 index 0000000..2b5a6cf --- /dev/null +++ b/hyhproject/admin/view/wxtemplatemsgs/edit.html @@ -0,0 +1,81 @@ +{extend name="base" /} +{block name="js"} +<script src="__ADMIN__/wxtemplatemsgs/wxtemplatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<form autocomplete='off'> +<input type='hidden' id='id' class='ipt' value="{$object['id']}"/> +<input type='hidden' id='tplCode' class='ipt' value="{$object['tplCode']}"/> +<table class='wst-form wst-box-top layui-form'> + <tr> + <th width='120'>发送时机:</th> + <td> + {volist name=':WSTDatas("TEMPLATE_WX")' id='vo'} + {if $vo['dataVal']==$object['tplCode']}{$vo['dataName']}{/if} + {/volist} + </td> + </tr> + <tr> + <th>模板ID:</th> + <td> + <input type='text' id='tplExternaId' class='ipt' style='width:70%' maxLength='200' value='{$object['tplExternaId']}'> + </td> + </tr> + <tr> + <th>内容:</th> + <td> + <textarea id='tplContent' style='width:70%;height:100px;' class='ipt' maxLength='150'>{$object['tplContent']}</textarea> + </td> + </tr> + <tr> + <th>是否开启:</th> + <td> + <input type="checkbox" {if $object['status']==1}checked{/if} value='1' class="ipt" id="isShow" name="seoMallSwitch" lay-skin="switch" lay-filter="isShow" lay-text="开启|关闭"> + </td> + </tr> + <tr> + <th>参数设置:</th> + <td> + <div class='wst-toolbar'> + <font color='red'>(双击表格修改参数及内容)</font> + <button type="button" class='btn btn-success f-right' onclick='javascript:addNewRow()'><i class="fa fa-plus"></i>新增</button> + <div style='clear:both;'></div> + </div> + <div id='paramGrid'> + <table border='1' width='100%'> + <tr> + <td width='20%'>变量名</td> + <td width='73%'>内容</td> + <td width='50'>操作</td> + </tr> + <tbody id='paramlist'> + </tbody> + </table> + <script id="paramjs" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr id='tr_{{i}}'> + <td><input type="text" style="width:92%" id="fiedlCode_{{i}}" value='{{d[i].fieldCode}}'/></td> + <td><input type="text" style="width:98%" id="fiedlVal_{{i}}" value='{{d[i].fieldVal}}'/></td> + <td> + <input type="button" value="删除" class="btn btn-danger" onclick="javascript:deleteRow({{i}})"> + </td> + </tr> + {{# } }} + </script> + </div> + </td> + </tr> + <tr> + <th valign="top">说明:</th> + <td id='tplDesc'>{$object['tplDesc']}</td> + </tr> + <tr> + <td colspan='2' align='center' class='wst-bottombar'> + <button type="button" class='btn btn-primary btn-mright' onclick='javascript:save(0)'><i class="fa fa-check"></i>保存</button> + <button type="button" class='btn' onclick='javascript:history.go(-1)'><i class="fa fa-angle-double-left"></i>返回</button> + </td> + </tr> +</table> +</form> +<script>$(function(){initParamGrid();})</script> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wxtemplatemsgs/list.html b/hyhproject/admin/view/wxtemplatemsgs/list.html new file mode 100755 index 0000000..4c2b3e4 --- /dev/null +++ b/hyhproject/admin/view/wxtemplatemsgs/list.html @@ -0,0 +1,25 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/wxtemplatemsgs/wxtemplatemsgs.js?v={$v}" type="text/javascript"></script> +{/block} +{block name="main"} +<style>.body li{height:22px;}</style> +<div id='alertTips' class='alert alert-success alert-tips fade in'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>本功能使用微信公众号接口,需在注册并认证“服务号”,并获得模板消息的使用权限,<a class='wst-wiki' target='_blank' href='https://mp.weixin.qq.com/wiki'>微信公众平台文档</a>。</li> + <li>本系统中的模板仅供参考,建议在公众平台模板库中选择“<strong>IT科技 互联网|电子商务 | IT科技 IT软件与服务</strong>”的行业,然后添加与本模板内容相同的模板。</li> + <li>因微信对通知内容要求较严格,不支持营销、到期提醒类消息推送,详细规则<a class='wst-wiki' href='https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751288' target='_blank'>查看</a>。</li> + </ul> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg layui-form"></div> + <div id="pg" style="text-align: right;"></div> +</div> +<script>$(function(){initGrid();})</script> +{/block} + diff --git a/hyhproject/admin/view/wxtemplatemsgs/wxtemplatemsgs.js b/hyhproject/admin/view/wxtemplatemsgs/wxtemplatemsgs.js new file mode 100755 index 0000000..1f5a90f --- /dev/null +++ b/hyhproject/admin/view/wxtemplatemsgs/wxtemplatemsgs.js @@ -0,0 +1,114 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'发送时机', name:'tplCode', width: 100}, + {title:'模板ID', name:'tplExternaId', width: 100}, + {title:'发送内容', name:'tplContent', width: 500}, + {title:'是否开启', name:'status',align:'center',width:50,renderer: function(val,item,rowIndex){ + return '<input type="checkbox" '+((item['status']==1)?"checked":"")+' name="isShow4" lay-skin="switch" lay-filter="isShow4" data="'+item['id']+'" lay-text="开启|关闭">'; + + }}, + {title:'操作', name:'' ,width:30, align:'center', renderer: function(val,item,rowIndex){ + var h=""; + if(WST.GRANT.XXMB_02)h += "<a class='btn btn-blue' href='javascript:toEdit(" + item['id'] + ")'><i class='fa fa-pencil'></i>编辑</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-165,indexCol: true, cols: cols,method:'POST',nowrap:true, + url: WST.U('admin/wxtemplatemsgs/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); + mmg.on('loadSuccess',function(){ + layui.form.render(); + layui.form.on('switch(isShow4)', function(data){ + var id = $(this).attr("data"); + if(this.checked){ + toggleIsShow(0,id); + }else{ + toggleIsShow(1,id); + } + }); + }) + $('#headTip').WSTTips({width:90,height:35,callback:function(v){ + if(v){ + mmg.resize({height:h-165}); + }else{ + mmg.resize({height:h-87}); + } + }}); +} +function toggleIsShow(t,v){ + if(!WST.GRANT.DQGL_02)return; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/TemplateMsgs/editiIsShow'),{id:v,status:t},function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + grid.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function initParamGrid(){ + var loading = WST.msg('正在加载数据,请稍后...', {icon: 16,time:60000}); + var params = {parentId:$('#id').val()}; + $.post(WST.U('admin/wxtemplatemsgs/listQuery'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + childrenNum = json.data?json.data.length:0; + var gettpl = document.getElementById('paramjs').innerHTML; + layui.laytpl(gettpl).render(json.data, function(html){ + $('#paramlist').html(html); + }); + } + }); +} +var childrenNum = 0; +function addNewRow(){ + var html = ['<tr id="tr_'+childrenNum+'">', + '<td><input type="text" style="width:92%" id="fiedlCode_'+childrenNum+'"/></td>', + '<td><input type="text" style="width:98%" id="fiedlVal_'+childrenNum+'"/></td>', + '<td><input type="button" value="删除" class="btn btn-danger" onclick="javascript:deleteRow('+childrenNum+')"></td>', + '</tr>' + ]; + $('#paramlist').append(html.join('')); + childrenNum++; +} +function deleteRow(n){ + $('#tr_'+n).remove(); +} +function toEdit(id){ + location.href = WST.U('admin/wxtemplatemsgs/toEdit','id='+id); +} +function save(type){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var params = WST.getParams('.ipt'); + params.num = childrenNum; + for(var i=0;i<=params.num;i++){ + if($.trim($('#fiedlCode_'+i).val())!=''){ + params['code_'+i] = $('#fiedlCode_'+i).val(); + params['val_'+i] = $('#fiedlVal_'+i).val(); + } + } + $.post(WST.U('admin/wxtemplatemsgs/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + location.href = WST.U('admin/wxtemplatemsgs/index','src='+type); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + + + + \ No newline at end of file diff --git a/hyhproject/admin/view/wxusers/list.html b/hyhproject/admin/view/wxusers/list.html new file mode 100755 index 0000000..8a92e7a --- /dev/null +++ b/hyhproject/admin/view/wxusers/list.html @@ -0,0 +1,35 @@ +{extend name="base" /} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__ADMIN__/js/mmgrid/mmGrid.css?v={$v}" /> +{/block} +{block name="js"} +<script src="__ADMIN__/js/mmgrid/mmGrid.js?v={$v}" type="text/javascript"></script> +<script src="__ADMIN__/wxusers/wxusers.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){initGrid();}) +</script> +{/block} +{block name="main"} +<div class="wst-toolbar"> + <input type='text' id='key' placeholder='用户名称'/> + <button class="btn btn-primary" onclick='javascript:loadGrid(0)'><i class='fa fa-search'></i>查询</button> +{if WSTGrant('WX_ZDYCD_00')} + <button class="btn btn-success f-right" style="margin-right:10px;" onclick='javascript:wxSynchro();'><i class='fa fa-cloud-upload'></i>与微信用户管理同步</button> +{/if} + <div style='clear:both'></div> +</div> +<div class='wst-grid'> + <div id="mmg" class="mmg"></div> +</div> +<div id="pg" style="text-align: right;"></div> +<div id='wxusersBox' style='display:none'> + <form id='wxusersForm' autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th width='100'>用户备注<font color='red'>*</font>:</th> + <td><input type='text' id='userRemark' name="userRemark" class='ipt' maxLength='20' style='width:200px;' data-msg-required="请输入备注" data-tip="请输入备注"/></td> + </tr> + </table> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/admin/view/wxusers/wxusers.js b/hyhproject/admin/view/wxusers/wxusers.js new file mode 100755 index 0000000..0c9f2a5 --- /dev/null +++ b/hyhproject/admin/view/wxusers/wxusers.js @@ -0,0 +1,112 @@ +var mmg; +function initGrid(){ + var h = WST.pageHeight(); + var cols = [ + {title:'用户头像', name:'userPhoto', width: 100, renderer: function(val,item,rowIndex){ + if(item["userPhoto"]){ + var i = '<span><img style="height:20px;" src="'+item["userPhoto"]+'" /></span>'; + return i; + } + }}, + {title:'用户名称', name:'userName', width: 100}, + {title:'性别', name:'userSex', width: 100, renderer: function(val,item,rowIndex){ + if(item['userSex']==0)s = "保密"; + if(item['userSex']==1)s = "男"; + if(item['userSex']==2)s = "女"; + return s; + }}, + {title:'用户所在地', name:'userAreas', width: 100}, + {title:'openId', name:'openId', width: 100}, + {title:'用户关注时间', name:'subscribeTime', width: 100, renderer: function(val,item,rowIndex){ + if(WST.blank(item["subscribeTime"]))return item["subscribeTime"]; + }}, + {title:'用户备注', name:'userRemark', width: 100}, + {title:'操作', name:'' ,width:70, align:'center', renderer: function(val,item,rowIndex){ + var h = ""; + if(WST.GRANT.WX_ZDYCD_02)h += "<a class='btn btn-blue' href='javascript:toEdit("+rowdata["userId"]+")'><i class='fa fa-pencil'></i>修改备注</a> "; + return h; + }} + ]; + + mmg = $('.mmg').mmGrid({height: h-85,indexCol: true, cols: cols,method:'POST', + url: WST.U('admin/wxusers/pageQuery'), fullWidthRows: true, autoLoad: true, + plugins: [ + $('#pg').mmPaginator({}) + ] + }); +} + +function loadGrid(){ + mmg.load({page:1,key:$('#key').val()}); +} + +//与微信用户管理同步 +var userTotal,num=0; +function wxSynchro(){ + var box = WST.confirm({content:"您确定与微信用户管理同步吗?</br>(用户越多同步时间将越久)",yes:function(){ + var loading = WST.msg('正在同步数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxusers/synchroWx'),'',function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + userTotal = json.data; + WST.msg(json.msg,{icon:1}); + layer.close(box); + loadGrid(); + wxLoad(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function wxLoad(){ + id = userTotal[num]['openId']; + $.post(WST.U('admin/wxusers/wxLoad'),{id:id},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json.status=='1'){ + if(num < userTotal.length-1){ + num++ + WST.msg("当前正在同步第"+num+"个用户,进度"+num+"/"+userTotal.length); + wxLoad(); + return; + }else{ + num=0; + WST.msg("同步完成",{icon:1}); + loadGrid(); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function toEdit(id){ + $('#wxusersForm')[0].reset(); + $.post(WST.U('admin/wxusers/getById'),{id:id},function(data,textStatus){ + var json = WST.toAdminJson(data); + if(json){ + WST.setValues(json); + var box = WST.open({title:'修改备注',type:1,content:$('#wxusersBox'),area: ['460px', '160px'],btn:['确定','取消'], + end:function(){$('#wxusersBox').hide();},yes:function(){ + if(!$('#userRemark').isValid())return; + var params = WST.getParams('.ipt'); + params.id = id; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('admin/wxusers/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toAdminJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#wxusersBox').hide(); + layer.close(box); + loadGrid(params.parentId); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/app/.DS_Store b/hyhproject/app/.DS_Store new file mode 100755 index 0000000..27701b6 Binary files /dev/null and b/hyhproject/app/.DS_Store differ diff --git a/hyhproject/app/._.DS_Store b/hyhproject/app/._.DS_Store new file mode 100755 index 0000000..054f94f Binary files /dev/null and b/hyhproject/app/._.DS_Store differ diff --git a/hyhproject/app/common/function.php b/hyhproject/app/common/function.php new file mode 100755 index 0000000..2c9729c --- /dev/null +++ b/hyhproject/app/common/function.php @@ -0,0 +1,21 @@ +<?php +use think\Db; +/** + * ============================================================================ + */ +/** + * 获取购物车数量 + */ +function WSTCartNum(){ + $userId = session('WST_USER.userId'); + $cartNum = Db::name('carts')->where(['userId'=>$userId])->field('cartId')->select(); + $count = count($cartNum); + return $count; +} +function appLogOut(){ + Db::name('users')->where(['userId'=>1])->setField('token',''); + session('WST_USER',null); + //setcookie("loginPwd", null); + session('WST_MO_WlADDRESS',null); +} + diff --git a/hyhproject/app/conf/config.php b/hyhproject/app/conf/config.php new file mode 100755 index 0000000..3d26a52 --- /dev/null +++ b/hyhproject/app/conf/config.php @@ -0,0 +1,14 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + +]; diff --git a/hyhproject/app/controller/.DS_Store b/hyhproject/app/controller/.DS_Store new file mode 100755 index 0000000..163c6c3 Binary files /dev/null and b/hyhproject/app/controller/.DS_Store differ diff --git a/hyhproject/app/controller/._.DS_Store b/hyhproject/app/controller/._.DS_Store new file mode 100755 index 0000000..2aa1e22 Binary files /dev/null and b/hyhproject/app/controller/._.DS_Store differ diff --git a/hyhproject/app/controller/Alipays.php b/hyhproject/app/controller/Alipays.php new file mode 100755 index 0000000..13b2ead --- /dev/null +++ b/hyhproject/app/controller/Alipays.php @@ -0,0 +1,622 @@ +<?php + +namespace wstmart\app\controller; + +use think\Loader; + +use wstmart\common\model\Payments as M; + +use wstmart\app\model\Orders as OM; + +use wstmart\common\model\LogPayParams as PM; + +use wstmart\common\model\ChargeItems as CM; + +use wstmart\common\model\LogMoneys as LM; + +/** + + * ============================================================================ + + * 阿里支付控制器 + + */ + +class Alipays extends Base{ + + + + /** + + * 初始化 + + */ + + private $alipayConfig; + + public function _initialize() { + + header ("Content-type: text/html; charset=utf-8"); + + Loader::import ( 'app_alipay.aop.AopClient' ); + + Loader::import ( 'app_alipay.aop.request.AlipayTradeAppPayRequest' ); + + $m = new M(); + + $payment = $m->getPayment("app_alipays"); + + $this->alipayConfig = array( + + 'app_id' =>trim($payment['appId']), + + 'rsaPrivateKey' =>trim($payment['rsaPrivateKey']),//'请填写开发者私钥去头去尾去回车,一行字符串' + + 'alipayrsaPublicKey' =>trim($payment['alipayrsaPublicKey']),//公钥 + + 'format' =>'json',//格式 + + 'charset' =>'UTF-8', + + 'signType' =>'RSA2', + + 'seller_email'=>'ect@ect99.com' + + ); + + } + + + + /** + + * 支付宝支付跳转方法 + + */ + + public function toAliPay(){ + +// echo "<span style='font-size:40px;'>暂停APP支付,请选择WAP端支付宝支付</span>"; + +// return; + + $payObj = input("payObj/s"); + + + + $call_back_url = ""; + + $notify_url = ""; + + $subject = ""; + + $total_fee = 0; + + $transId = 0; + + $userId = 0; + + $payParams = array(); + + if($payObj=="recharge"){//充值 + + $itemId = (int)input("itemId/d"); + + $orderAmount = 0; + + if($itemId>0){ + + $cm = new CM(); + + $item = $cm->getItemMoney($itemId); + + $total_fee = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + + }else{ + + $total_fee = (int)input("needPay/d"); + + } + + + + $shopId = (int)session('WST_USER.shopId'); + + $targetType = ($shopId>0)?1:0; + + $targetId = (int)session('WST_USER.userId'); + + if($targetType==1){//商家 + + $targetId = $shopId; + + } + + $userId = $targetId; + + $out_trade_no = WSTOrderNo(); + + $transId = $out_trade_no; + + $payParams["targetId"] = $targetId; + + $payParams["targetType"] = $targetType; + + $payParams["itemId"] = $itemId; + + $payParams["payObj"] = $payObj; + + + + //$call_back_url = url("app/users/index","",true,true); + + $notify_url = url("app/alipays/aliNotify","",true,true); + + $subject = '钱包充值'; + + }else{ + + $orderNo = input('orderNo'); + + $isBatch = (int)input('isBatch'); + + $userId = (int)session('WST_USER.userId'); + + $m = new OM(); + + $obj = array(); + + $obj["userId"] = $userId; + + $obj["orderNo"] = input("orderNo/s"); + + $obj["isBatch"] = (int)input("isBatch/d"); + + $rs = $m->getOrderPayInfo($obj); + + if(empty($rs)){ + + echo "<span style='font-size:40px;'>找不到此订单!</span>"; + + return; + + }else{ + + $m = new M(); + + $om = new OM(); + + $data = $om->checkOrderPay($obj); + + if($data["status"]==-1){ + + echo "<span style='font-size:40px;'>您的订单已支付,不要重复支付!</span>"; + + return; + + }else if($data["status"]==-2){ + + echo "<span style='font-size:40px;'>您的订单因商品库存不足,不能支付!</span>"; + + return; + + } + + } + + $order = $om->getPayOrders($obj); + + $total_fee = $order["needPay"]; + + $payRand = $order["payRand"]; + + $out_trade_no = $obj["orderNo"]."a".$payRand; + + $transId = $obj["orderNo"]; + + + + $payParams["userId"] = $userId; + + $payParams["isBatch"] = $isBatch; + + $payParams["orderNo"] = $orderNo; + + + + //$call_back_url = url("app/orders/index","",true,true); + + $notify_url = url("app/alipays/aliNotify","",true,true); + + $subject = '支付购买商品费用'; + + } + + $data = array(); + + $data["userId"] = $userId; + + $data["transId"] = $transId; + + $data["paramsVa"] = json_encode($payParams); + + $data["payFrom"] = 'alipays'; + + $m = new PM(); + + $m->addPayLog($data); + + + + + + + + + + + + + + //建立请求 + + $aop = new \AopClient; + + $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do"; + + $aop->appId = $this->alipayConfig['app_id']; + + $aop->rsaPrivateKey = $this->alipayConfig['rsaPrivateKey']; + + $aop->alipayrsaPublicKey = $this->alipayConfig['alipayrsaPublicKey']; + + $aop->apiVersion = '1.0'; + + $aop->signType = "RSA2"; + + $aop->postCharset = $this->alipayConfig['charset']; + + $aop->format = $this->alipayConfig['format']; + + //$aop->charset = $this->alipayConfig['charset']; + + + + + + + + //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay + + $request = new \AlipayTradeAppPayRequest(); + + // 异步通知地址 + + //$notify_url = urlencode($notify_url); + + // 订单标题 + + $subject = $subject; + + // 订单详情 + + $body = $subject; + + //SDK已经封装掉了公共参数,这里只需要传入业务参数 + + $bizcontent = "{\"body\":\"".$body."\"," + + . "\"subject\": \"".$subject."\"," + + . "\"out_trade_no\": \"".$out_trade_no."\"," + + . "\"timeout_express\": \"30m\"," + + . "\"total_amount\": \"".$total_fee."\"," + + . "\"product_code\":\"QUICK_MSECURITY_PAY\"" + + . "}"; + + $request->setNotifyUrl($notify_url); + + $request->setBizContent($bizcontent); + + //这里和普通的接口调用不同,使用的是sdkExecute + + $response = $aop->sdkExecute($request); + + // 注意:这里不需要使用htmlspecialchars进行转义,直接返回即可 + + echo $response; + + } + + /** + + * 验签 + + * @param [type] $postParams [description] + + * @return [type] [description] + + */ + + public function checkSign($postParams){ + + + + $aop = new \AopClient; + + $aop->alipayrsaPublicKey = $this->alipayConfig['alipayrsaPublicKey']; + + $flag = $aop->rsaCheckV1($postParams, NULL, "RSA2"); + + return $flag; + + } + + /** + + * 服务器异步通知页面方法 + + * + + */ + + function alinotify() { + + //验签通过后再实现业务逻辑,比如修改订单表中的支付状态。 + + /** + + ①验签通过后核实如下参数trade_status、out_trade_no、total_amount、seller_id + + ②修改订单表 + + **/ + // if(!isset($_POST['app_id'])){ + // $_POST = $_GET; + // } + if(!$this->checkSign($_POST)){//验签 + + return false; + + } + + + + //验证app_id是否为该商户本身 + + if($this->alipayConfig['app_id'] != $_POST['app_id']){ + + return false; + + } + + + + //校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方 + + if(isset($_POST['seller_email']) && ($_POST['seller_email'] != $_POST['seller_email'])){ + + return false; + + } + + $out_trade_no = $_POST['out_trade_no'];//获取交易号 + + $tradeNo = explode("a",$out_trade_no);//实际订单号 + + $om = new OM(); + + //商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号 + + $orderInfo = $om->getOrderByOrderNo($tradeNo['0'],'needPay,isPay');//取订单信息; + + if(empty($orderInfo)){ + + return false; + + } + + //判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额) + + // if ($_POST['total_amount'] != $orderInfo['needPay']){ + + + + // return false; + + // } + + if(0==$orderInfo["isPay"] && ($_POST['trade_status']=="TRADE_SUCCESS" || $_POST['trade_status']=="TRADE_FINISHED")){ + + //处理订单 + + $obj["trade_no"] = $_POST['trade_no'];//支付宝交易号 + + $obj["out_trade_no"] = $tradeNo[0];//实际订单号 + + $obj["payFrom"] = 'alipays'; + + $obj["total_fee"] = $_POST['total_amount'];//订单金额 + + + + $m = new PM(); + + $payParams = $m->getPayLog(["transId"=>$obj["out_trade_no"]]); + + if(isSet($payParams["payObj"]) && $payParams["payObj"]=='recharge'){ + + + + $obj["targetId"] = $payParams["targetId"]; + + $obj["targetType"] = $payParams["targetType"]; + + $obj["itemId"] = $payParams["itemId"];; + + // 支付成功业务逻辑 + + $m = new LM(); + + $rs = $m->complateRecharge ( $obj ); + + }else{ + + //$payFrom = $om->getOrderPayFrom($tradeNo[0]); + + $obj["userId"] = $payParams["userId"]; + + $obj["isBatch"] = $payParams["isBatch"]; + + //支付成功业务逻辑 + + $rs = $om->complatePay($obj); + + } + + + + if($rs["status"]==1){ + + echo 'success';// 请不要修改或删除 + + }else{ + + echo 'fail'; + + } + + } + + //echo "success";// 请不要修改或删除 + + // // 计算得出通知验证结果 + + // $alipayNotify = new \AlipayNotify ( $this->alipayConfig ); + + // $verify_result = $alipayNotify->verifyNotify (); + + + + // if ($verify_result) { + + // $notify_data = $_POST['notify_data']; + + // // 获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 + + // // 解析notify_data + + // // 注意:该功能PHP5环境及以上支持,需开通curl、SSL等PHP配置环境。建议本地调试时使用PHP开发软件 + + // $doc = new \DOMDocument (); + + // $doc->loadXML ( $notify_data ); + + // if (! empty ( $doc->getElementsByTagName ( "notify" )->item ( 0 )->nodeValue )) { + + // // 交易号 + + // $trade_no = $doc->getElementsByTagName ( "trade_no" )->item ( 0 )->nodeValue; + + // // 商户订单号 + + // $out_trade_no = $doc->getElementsByTagName ( "out_trade_no" )->item ( 0 )->nodeValue; + + + + // $total_fee = $doc->getElementsByTagName( "total_fee" )->item(0)->nodeValue; + + // // 支付宝交易号 + + // $trade_no = $doc->getElementsByTagName ( "trade_no" )->item ( 0 )->nodeValue; + + // // 交易状态 + + // $trade_status = $doc->getElementsByTagName ( "trade_status" )->item ( 0 )->nodeValue; + + // if ($trade_status == 'TRADE_FINISHED' OR $trade_status == 'TRADE_SUCCESS') { + + // $obj["trade_no"] = $trade_no; + + // $tradeNo = explode("a",$out_trade_no); + + + + // $obj["out_trade_no"] = $tradeNo[0]; + + // $obj["payFrom"] = 'alipays'; + + // $obj["total_fee"] = $total_fee; + + + + // $m = new PM(); + + // $payParams = $m->getPayLog(["transId"=>$obj["out_trade_no"]]); + + // if(isSet($payParams["payObj"]) && $payParams["payObj"]=='recharge'){ + + + + // $obj["targetId"] = $payParams["targetId"]; + + // $obj["targetType"] = $payParams["targetType"]; + + // $obj["itemId"] = $payParams["itemId"];; + + // // 支付成功业务逻辑 + + // $m = new LM(); + + // $rs = $m->complateRecharge ( $obj ); + + // }else{ + + // //$payFrom = $om->getOrderPayFrom($tradeNo[0]); + + // $obj["userId"] = $payParams["userId"]; + + // $obj["isBatch"] = $payParams["isBatch"]; + + // //支付成功业务逻辑 + + // $rs = $om->complatePay($obj); + + // } + + + + // if($rs["status"]==1){ + + // echo 'success'; + + // }else{ + + // echo 'fail'; + + // } + + // } + + // echo "success"; // 请不要修改或删除 + + // } + + // } else { + + // // 验证失败 + + // echo "fail"; + + // } + + } + + + +} + diff --git a/hyhproject/app/controller/Appport.php b/hyhproject/app/controller/Appport.php new file mode 100755 index 0000000..bc0701a --- /dev/null +++ b/hyhproject/app/controller/Appport.php @@ -0,0 +1,130 @@ +<?php +namespace wstmart\app\controller; +use think\Loader; +use wstmart\app\model\AppPort as M; +use wstmart\common\model\LogPayParams as PM; +use wstmart\common\model\ChargeItems as CM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 阿里支付控制器 + */ +class Appport extends Base{ + /* + * app新版首页轮播图 + * */ + public function appBanner(){ + $m=new M(); + $result=$m->appBanner(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /** + * app新版首页桔子头条接口 + */ + public function appNews(){ + $m = new M(); + $result = $m->appNews(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /** + * app新版首页桔子头条列表页接口 + */ + public function appNewsLists(){ + $m = new M(); + $result = $m->appNewsLists(); + dump($result); + //exit(json_encode(WSTReturn('',1,$result))); + } + /** + * app新版桔子头条分类接口 + */ + public function appNewsClass(){ + $m = new M(); + $result = $m->appNewsClass(); + dump($result); + //exit(json_encode(WSTReturn('',1,$result))); + } + /** + * app新版桔子头条详情页接口 + */ + public function appNewsDetail(){ + $m = new M(); + $result = $m->appNewsDetail(); + dump($result); + //exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版秒杀接口 + * */ + public function appSecKill(){ + $m=new M(); + $result=$m->appSecKill(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版ect专区/活动区 图片接口 + * */ + public function appEctAct(){ + $m=new M(); + $result=$m->appEctAct(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版品牌热卖接口 + * */ + public function appBrands(){ + $m=new M(); + $result=$m->appBrands(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版居家好帮手广告位接口 + * */ + public function appJadvertis(){ + $m=new M(); + $result=$m->appJadvertis(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版潮流先锋广告位接口 + * */ + public function appCadvertis(){ + $m=new M(); + $result=$m->appCadvertis(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版食品超市广告位接口 + * */ + public function appSadvertis(){ + $m=new M(); + $result=$m->appSadvertis(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app新版家电馆广告位接口 + * */ + public function appDadvertis(){ + $m=new M(); + $result=$m->appDadvertis(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } + /* + * app为你推荐接口 + /*/ + public function recommend(){ + $m=new M(); + $result=$m->recommend(); + //dump($result); + exit(json_encode(WSTReturn('',1,$result))); + } +} diff --git a/hyhproject/app/controller/Areas.php b/hyhproject/app/controller/Areas.php new file mode 100755 index 0000000..033130c --- /dev/null +++ b/hyhproject/app/controller/Areas.php @@ -0,0 +1,103 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Areas as M; +use think\Db; +/** + * ============================================================================ + * 地区控制器 + */ +class Areas extends Base{ + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + exit(jsonReturn('', 1,$rs)); + } +// CREATE TABLE `hyh_user_trees` ( +// `id` int(11) NOT NULL AUTO_INCREMENT, +// `uid` int(11) NOT NULL DEFAULT '0' COMMENT '用户id', +// `pid` int(11) NOT NULL DEFAULT '0' COMMENT '父ID', +// `bid` int(11) NOT NULL DEFAULT '0' COMMENT '家族ID', +// `lft` int(11) NOT NULL DEFAULT '1' COMMENT '左节点', +// `rgt` int(11) NOT NULL DEFAULT '2' COMMENT '右节点', +// `t_level` smallint(6) NOT NULL DEFAULT '0' COMMENT '层级', +// `update_time` int(10) NOT NULL DEFAULT '0' COMMENT '时间', +// PRIMARY KEY (`id`) +// ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT; + public function tmp(){ + return; + set_time_limit(0); + $user_list = Db::table('rd_users')->where('1=1')->field('user_id,first_leader,shop_id')->order('user_id asc')->select(); + foreach ($user_list as $v) { + $u_info = Db::table('rd_users')->where('user_id='.$v['user_id'])->field('user_id,first_leader,shop_id')->find(); + $userId = $u_info['shop_id']; + if($userId){ + if($u_info['first_leader']){ + $p_info = Db::table('rd_users')->where('user_id='.$u_info['first_leader'])->field('user_id,shop_id')->find(); + $pid = $p_info['shop_id']; + }else{ + $pid = 0; + } + ectLog($userId,10,1,'注册送ect',['userECT'=>['exp','userECT+10']]); + if($pid){ + ectLog($pid,5,1,'推荐送ect',['userECT'=>['exp','userECT+5']]); + } + $this->create_tree($userId,$pid,0); + } + + } + die('ok'); + } + function create_tree($uid,$pid){ + if(!$uid) return; + if(Db::name('user_trees')->where(array('uid'=>$uid))->find()) return;//树里有 + if($pid){ + $p_info = Db::name('user_trees')->where(array('uid'=>$pid))->field('bid,t_level')->find(); + if($p_info['t_level']){ + $t_level = $p_info['t_level'] + 1; + }else{ + $t_level = 2; + } + if($p_info['bid']){ + $bid = $p_info['bid']; + }else{ + $bid = $pid; + } + + }else{ + $bid = $uid; + $t_level = 1; + } + $set = array( + 'uid'=>$uid, + 'pid'=>$pid, + 'bid'=>$bid, + 't_level'=>$t_level, + 'update_time'=>time() + ); + Db::name('user_trees')->insert($set); + //获取家族树最顶级节点,重建树 + $this->rebuild_tree($bid,1);//重建树,建立有左右值的数据表,对整个结构重新进行一次编号 + + } + function rebuild_tree($root, $left) { + // the right value of this node is the left value + 1 + $right = $left+1; + // get all children of this node + $trees = Db::name('user_trees')->where(array('pid'=>$root))->field('uid')->select(); + if($trees){ + foreach ($trees as $k => $v) { + $right = $this->rebuild_tree($v['uid'], $right); + } + } + $set = array( + 'lft' => $left, + 'rgt' => $right, + ); + Db::name('user_trees')->where(array('uid'=>$root))->update($set); + // return the right value of this node + 1 + return $right + 1; + } +} diff --git a/hyhproject/app/controller/Articles.php b/hyhproject/app/controller/Articles.php new file mode 100755 index 0000000..915d503 --- /dev/null +++ b/hyhproject/app/controller/Articles.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Tags as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Articles extends Base{ + /** + * 获取首页惠员快报 + */ + public function getIndexNews(){ + $m = new M(); + $rs = $m->listArticle('new',10,86400); + exit(jsonReturn('', 1,$rs)); + } + /** + * 获取惠员快报列表 + */ + public function getNewsList(){ + $m = new M(); + $rs = $m->newArticle(); + exit(jsonReturn('', 1,$rs)); + } + //添加显示会员快报 make cheng 20180227 + public function showArticle(){ + $m = new M(); + $article = $m->showArticle(); + exit(jsonReturn('', 1,$article)); + } + + /** + *桔子头条分类 + */ + public function orange(){ + $m = new M(); + $orange = $m->orangeType(); +// print_r($orange);die; + exit(json_encode(WSTReturn('ok',1,$orange))); + } + /** + * 桔子头条文章 + */ + public function headLine(){ + $catId = (int)input('catId'); + // $catId = 61; + $m = new M(); + $clog = $m->clog($catId); + // print_r($clog);die; + exit(json_encode(WSTReturn('ok',1,$clog))); + } + + /** + * 桔子头条文章详情 + */ + public function detail(){ + $articleId = (int)input('articleId'); + // $articleId = '113'; + $m = new M(); + $detail = $m->detail($articleId); + // print_r($detail);die; + exit(json_encode(WSTReturn('ok',1,$detail))); + } +} diff --git a/hyhproject/app/controller/Auth.php b/hyhproject/app/controller/Auth.php new file mode 100755 index 0000000..4165674 --- /dev/null +++ b/hyhproject/app/controller/Auth.php @@ -0,0 +1,560 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Auth as M; +use wstmart\common\model\AuthFamily as FM; +/** + * ============================================================================ + * 认证控制器 + */ +class Auth extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + + /** + * 获取认证信息 + */ + public function getAuthInfo(){ + $m = new M(); + $isCompany = (int)input('post.isCompany');//1是合作认证 + if(1 == $isCompany){ + $m->setTable('auth_company'); + } + $authInfo = $m->getInfo(['userId'=>$this->getUserId()],'*'); + exit(jsonReturn('',1,$authInfo)); + } + /** + * 添加/编辑认证信息 + */ + public function setAuthInfo(){ + $m = new M(); + $isCompany = (int)input('post.isCompany');//1是合作认证 + $data = input('post.'); + unset($data['headImgTag']); + unset($data['accountBookImgTag']); + $userId = $this->getUserId(); + if(1 == $isCompany){ + if($this->user['authType'] == 1) exit(jsonReturn('没有权限!')); + + $m->setTable('auth_personal'); + if($m->getField(['status'=>0,'userId'=>$userId],'id')){ + exit(jsonReturn('当前账户已申请个人认证,请等待审核')); + } + $m->setTable('auth_company'); + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('company')->check($data)){ + exit(jsonReturn($validate->getError())); + } + }else{ + if($this->user['authType'] == 2) exit(jsonReturn('没有权限!')); + $m->setTable('auth_company'); + if($m->getField(['status'=>0,'userId'=>$userId],'id')){ + exit(jsonReturn('当前账户已申请合作认证,请等待审核')); + } + $m->setTable('auth_personal'); + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('personal')->check($data)){ + exit(jsonReturn($validate->getError())); + } + $fm = new FM(); + if($fm->getInfo(['familyIdCard'=>$data['householdIdCard']],'id')){ + exit(jsonReturn('该身份证已报备,请更换')); + } + } + $isUpdate = 0; + $authId = 0; + $data['userId'] = $userId; + $authInfo = $m->getInfo(['userId'=>$userId],'id,status'); + if($authInfo){ + if(!empty($data['authId'])){//更新状态 + $authId = $authInfo['id']; + if($authId == $data['authId']){//更新 + $payPwd = $data['payPwd']; + if(md5($payPwd) != $this->user['payPwd']){ + exit(jsonReturn('操作密码错误')); + } + $isUpdate = 1; + if(1 == $authInfo['status']) { + $data['status'] = 1; + unset($data['householdIdCard']);//成功不可以更改身份证号 + }else{ + $data['status'] = 0;//拒绝时 + } + + }else{ + exit(jsonReturn('没有权限!')); + } + }else{ + exit(jsonReturn('请不要重复提交')); + } + }else{ + $userPhone = session('Reg_UserPhone'); + if(!$userPhone){ + exit(jsonReturn('操作超时,请重试!')); + } + $verify = session('RegCode_UserPhone'); + $startTime = (int)session('RegCode_UserPhone_Time'); + if((time()-$startTime)>120){ + exit(jsonReturn('验证码已超过有效期,请重新发送!')); + } + $mobileCode = $data['mobileCode']; + if($mobileCode=="" || $verify != $mobileCode){ + exit(jsonReturn('短信验证码错误!')); + } + //$loginName = WSTRandomLoginName($log + $data['status'] = 0; + } + + unset($data['authId']); + unset($data['mobileCode']); + unset($data['isCompany']); + unset($data['payPwd']); + if($isUpdate){ + $isSuccess = $m->updateInfo(['id'=>$authId],$data); + }else{ + $isSuccess = $m->insertInfo($data); + } + if(false !== $isSuccess){ + session('Reg_UserPhone',null); + $userPhone = getAdminPhone(); + $tpl = WSTMsgTemplates('PHONE_USER_UPDATE_NOTICE'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$this->user['loginName']]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$userPhone,$params,'PHONE_USER_UPDATE_NOTICE',0); + } + exit(jsonReturn('提交成功,请等待系统审核',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + /** + * 获取验证码 + */ + public function getPhoneCode(){ + $userPhone = input("post.userPhone"); + if($this->user['userPhone'] && $this->user['userPhone'] != $userPhone){ + exit(jsonReturn("手机号错误!")); + } + $rs = array(); + if(!WSTIsPhone($userPhone)){ + exit(jsonReturn("手机号格式不正确!")); + } + $m = Model('common/Users'); + $rs = $m->checkUserPhone($userPhone,$this->getUserId()); + if($rs["status"]!=1){ + exit(jsonReturn($rs['msg'])); + } + $phoneVerify = rand(1000,9999); + $tpl = WSTMsgTemplates('PHONE_USER_AUTH_NOTICE'); + $rv['status'] = -1; + $rv['msg'] = '发送失败'; + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['code'=>$phoneVerify]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$userPhone,$params,'PHONE_USER_AUTH_NOTICE',$phoneVerify); + } + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + session('Reg_UserPhone',$userPhone); + session('RegCode_UserPhone',$phoneVerify); + session('RegCode_UserPhone_Time',time()); + } + exit(json_encode($rv)); + } + /** + * 获取亲人报备列表 + */ + public function getAuthFamilyReportSelect(){ + $m = new FM(); + $authInfo = $m->getList(['userId'=>$this->getUserId()],'*'); + exit(jsonReturn('',1,$authInfo)); + } + /** + * 获取亲人报备信息 + */ + public function getAuthFamilyReportInfo(){ + $m = new FM(); + $id = (int)input('post.id'); + $authInfo = $m->getInfo(['userId'=>$this->getUserId(),'id'=>$id],'*'); + exit(jsonReturn('',1,$authInfo)); + } + + + /** + * 添加/编辑亲人报备信息 + */ + public function setAuthFamilyReport(){ + $m = new FM(); + $data = input('post.'); + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('report')->check($data)){ + exit(jsonReturn($validate->getError())); + } + $userId = $this->getUserId(); + $data['userId'] = $userId; + if(!empty($data['id'])){//更新状态 + $id = $data['id']; + unset($data['id']); + $authInfo = $m->getInfo(['userId'=>$userId,'id'=>$id],'id'); + if(!$authInfo){ + exit(jsonReturn('未找到此信息')); + } + $isSuccess = $m->updateInfo(['id'=>$id],$data); + }else{ + $isSuccess = $m->insertInfo($data); + } + if($isSuccess){ + exit(jsonReturn('提交成功',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + /** + * 获取亲人认证列表 + */ + public function getAuthFamilyPersonalSelect(){ + $m = new FM(); + $m->setTable('auth_family_personal'); + $authInfo = $m->getSelect(['userId'=>$this->getUserId()],'*'); + exit(jsonReturn('',1,$authInfo)); + } + /** + * 获取亲人认证信息 + */ + public function getAuthFamilyPersonalInfo(){ + $m = new FM(); + $m->setTable('auth_family_personal'); + $id = (int)input('post.id'); + $authInfo = $m->getInfo(['userId'=>$this->getUserId(),'id'=>$id],'*'); + exit(jsonReturn('',1,$authInfo)); + } + /** + * 获取亲人认证信息 + */ + public function getAuthInfoByMobile(){ + $m = new M(); + //$isPartner = (int)input('post.isPartner'); + // if(1 == $isPartner){//合作认证 + // $userPhone = session('partner_UserPhone'); + // $verify = session('partnerCode_UserPhone'); + // $startTime = (int)session('partner_UserPhone_Time'); + // }else{ + $userPhone = session('auth_UserPhone'); + $verify = session('authCode_UserPhone'); + $startTime = (int)session('auth_UserPhone_Time'); + //} + + if(!$userPhone){ + exit(jsonReturn('操作超时,请重试!')); + } + if((time()-$startTime)>1200){ + exit(jsonReturn('验证码已超过有效期,请重新发送!')); + } + $mobileCode = input('post.mobileCode'); + if($mobileCode=="" || $verify != $mobileCode){ + exit(jsonReturn('短信验证码错误!')); + } + session('auth_ok',1); + $authInfo = $m->getAuthInfoByMobile($userPhone); + exit(json_encode($authInfo)); + } + /** + * 删除报备或认证信息 + * @return [type] [description] + */ + public function delAuthFamily(){ + $m = new FM(); + $payPwd = input("post.payPwd"); + if(md5($payPwd) != $this->user['payPwd']){ + exit(jsonReturn('操作密码错误')); + } + $id = input("post.id"); + $isReport = (int)input('post.isReport');//0是亲人认证,1是亲人报备 + if(0 == $isReport){ + $m->setTable('auth_family_personal'); + } + $rs = $m->updateInfo(['userId'=>$this->getUserId(),'id'=>$id],['dataFlag'=>-1]); + if(false !== $rs){ + exit(jsonReturn('成功',1)); + } + exit(jsonReturn('失败,请重试',1)); + } + /** + * 获取亲人验证码 + */ + public function getFamilyPhoneCode(){ + if($this->user['authType'] == 2) exit(jsonReturn('没有权限!')); + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + exit(jsonReturn("手机号格式不正确!")); + } + if($this->user['userPhone'] && $this->user['userPhone'] == $userPhone){ + exit(jsonReturn("请输入实名认证的亲人手机号!")); + } + $m = Model('common/Users'); + $rs = $m->checkUserPhone($userPhone,0,'loginName'); + if($rs["status"]==1){ + exit(jsonReturn('手机号不存在')); + } + $rv['status'] = -1; + $rv['msg'] = '发送失败'; + $phoneVerify = rand(1000,9999); + $tpl = WSTMsgTemplates('PHONE_USER_AUTH_FAMILY_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$rs['loginName'],'code'=>$phoneVerify]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$userPhone,$params,'PHONE_USER_AUTH_FAMILY_VERFIY',$phoneVerify); + } + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + session('auth_UserPhone',$userPhone); + session('authCode_UserPhone',$phoneVerify); + session('auth_UserPhone_Time',time()); + } + exit(json_encode($rv)); + } + /** + * 添加/编辑亲人认证信息 + */ + public function setAuthFamilyPersonal(){ + if($this->user['authType'] == 2) exit(jsonReturn('没有权限!')); + $data = input('post.'); + + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('family')->check($data)){ + exit(jsonReturn($validate->getError())); + } + + $id = isset($data['id']) ? $data['id'] : 0; + if(!$id){ + $userPhone = session('auth_UserPhone'); + if(!$userPhone){ + exit(jsonReturn('操作超时,请重试!')); + } + $auth_ok = session('auth_ok'); + if(empty($auth_ok)) exit(jsonReturn('操作超时,请重新再试!')); + + + $where['userPhone']=$userPhone; + $userInfo = getUserInfo($where,'userId'); + if($userInfo){ + $data['familyId']=$userInfo['userId']; + $am = new M(); + $familyInfo = $am->getInfo(['userId'=>$userInfo['userId'],'status'=>1],'householdName,householdIdCard'); + if(!$familyInfo){ + exit(jsonReturn('亲人认证账号必须为个人实名通过会员!')); + } + $data['familyName'] = $familyInfo['householdName']; + $data['familyIdCard'] = $familyInfo['householdIdCard']; + }else{ + exit(jsonReturn('未找到用户')); + } + } + unset($data['id']); + $userId = $this->getUserId(); + $data['userId'] = $userId; + $m = new FM(); + $m->setTable('auth_family_personal'); + if(!$id && $m->getInfo(['familyId'=>$data['familyId'],'userId'=>$userId],'id')){ + exit(jsonReturn('此亲人已认证,请更换')); + } + if($id){//编辑 + $isSuccess = $m->updateInfo(['userId'=>$userId,'id'=>$id],$data); + }else{//新增 + $isSuccess = $m->insertInfo($data); + } + + if(false !== $isSuccess){ + session('auth_UserPhone',null); + session('auth_ok',null); + exit(jsonReturn('提交成功',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + /** + * 获取银行列表 + */ + public function getBankNameList(){ + $bankList = Model('banks')->listQuery(); + exit(jsonReturn('',1,$bankList)); + } + /** + * 获取会员银行列表 + */ + public function getCompanyBankList(){ + $bankList = Model('CompanyBank')->getSelect(['userId'=>$this->getUserId()],'*'); + exit(jsonReturn('',1,$bankList)); + } + /** + * 获取会员银行卡信息 + */ + public function getCompanyBankInfo(){ + $id = (int)input('post.id/d'); + $bankInfo = Model('CompanyBank')->getInfo(['userId'=>$this->getUserId(),'id'=>$id],'id,bankName,accountName,bankNo'); + exit(jsonReturn('',1,$bankInfo)); + } + /** + * 删行会员银行卡 + */ + public function delCompanyBank(){ + if($this->user['authType'] != 2) exit(jsonReturn('没有权限!')); + $id = (int)input('post.id/d'); + $payPwd = input("post.payPwd"); + if(md5($payPwd) != $this->user['payPwd']){ + exit(jsonReturn('操作密码错误')); + } + $rs = Model('CompanyBank')->updateInfo(['userId'=>$this->getUserId(),'id'=>$id],['dataFlag'=>-1]); + if(false !== $rs){ + exit(jsonReturn('删除成功',1)); + } + exit(jsonReturn('删除失败,请重试')); + } + /** + * 添加/编辑银行卡信息 + */ + public function setBank(){ + if($this->user['authType'] != 2) exit(jsonReturn('合作认证账号才可以添加银行卡')); + $m = Model('CompanyBank'); + $data = input('post.'); + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('bank')->check($data)){ + exit(jsonReturn($validate->getError())); + } + $id = isset($data['id']) ? $data['id'] : 0; + $data['userId'] = $this->getUserId(); + if($id){//编辑 + $isSuccess = $m->updateInfo(['userId'=>$data['userId'],'id'=>$id],$data); + }else{//新增 + $isSuccess = $m->insertInfo($data); + } + if(false !== $isSuccess){ + exit(jsonReturn('提交成功',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + /** + * 获取合作人验证码 + */ + public function getPartnerPhoneCode(){ + if(2 != $this->user['authType'])exit(jsonReturn('个人认证不可添加合作人')); + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + exit(jsonReturn("手机号格式不正确!")); + } + if($this->user['userPhone'] && $this->user['userPhone'] == $userPhone){ + exit(jsonReturn("请输入实名认证的手机号!")); + } + $m = Model('common/Users'); + $rs = $m->checkUserPhone($userPhone,0,'loginName'); + if($rs["status"]==1){ + exit(jsonReturn('手机号不存在')); + } + $rv['status'] = -1; + $rv['msg'] = '发送失败'; + $phoneVerify = rand(1000,9999); + $tpl = WSTMsgTemplates('PHONE_USER_AUTH_PARTNER_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$rs['loginName'],'code'=>$phoneVerify]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$userPhone,$params,'PHONE_USER_AUTH_PARTNER_VERFIY',$phoneVerify); + } + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + session('auth_UserPhone',$userPhone); + session('authCode_UserPhone',$phoneVerify); + session('auth_UserPhone_Time',time()); + } + exit(json_encode($rv)); + } + /** + * 添加/编辑合伙人认证信息 + */ + public function setAuthPartner(){ + if(2 != $this->user['authType'])exit(jsonReturn('个人认证不可添加合作人')); + $data = input('post.'); + + $validate = \think\Loader::validate('Auth'); + if(!$validate->scene('partner')->check($data)){ + exit(jsonReturn($validate->getError())); + } + + $userId = $this->getUserId(); + if(isset($data['id'])){ + $m->setTable('auth_company_partner'); + $info = $m->getInfo(['id'=>$data['id'],'dataFlag'=>1],'userId,partnerId'); + if(!$info || $info['userId'] != $userId){ + exit(jsonReturn('没有权限!')); + } + $where['userId']=$info['partnerId']; + $userInfo = getUserInfo($where,'userId,authType'); + }else{ + $userPhone = session('auth_UserPhone'); + if(!$userPhone){ + exit(jsonReturn('操作超时,请重试!')); + } + $auth_ok = session('auth_ok'); + if(empty($auth_ok)) exit(jsonReturn('操作超时,请重新再试!')); + + $where['userPhone']=$userPhone; + $userInfo = getUserInfo($where,'userId,authType'); + } + + if($userInfo){ + $data['partnerId']=$userInfo['userId']; + $am = new M(); + if(1 == $userInfo['authType']){ + $field = 'householdName uName,householdIdCard idCard'; + $uName = 'familyName'; + $idCard = 'familyIdCard'; + }elseif(2 == $userInfo['authType']){ + $am->setTable('auth_company'); + $field = 'trueName uName,idCard'; + $uName = 'uName'; + $idCard = 'idCard'; + }else{ + exit(jsonReturn('合作认证账号必须为实名通过会员')); + } + $authInfo = $am->getInfo(['userId'=>$userInfo['userId'],'status'=>1],$field); + if(!$authInfo){ + exit(jsonReturn('合作认证账号必须为实名通过会员!')); + } + $data[$uName] = $authInfo['uName']; + $data[$idCard] = $authInfo['idCard']; + }else{ + exit(jsonReturn('未找到用户')); + } + $id = isset($data['id']) ? $data['id'] : 0; + unset($data['id']); + $data['userId'] = $userId; + $m = new FM(); + $m->setTable('auth_company_partner'); + if(!$id && $m->getInfo(['partnerId'=>$data['partnerId'],'userId'=>$userId],'id')){ + exit(jsonReturn('此合作人已认证,请更换')); + } + if($id){//编辑 + $stakeSum = $m->getSum(['userId'=>$userId,'id'=>['<>',$id]],'stake'); + if(($stakeSum + $data['stake']) > 100){ + exit(jsonReturn('股份分配超出100%比例,当前最大修改比例'.(100-$stakeSum),1)); + } + $isSuccess = $m->updateInfo(['userId'=>$userId,'id'=>$id],$data); + }else{//新增 + $stakeSum = $m->getSum(['userId'=>$userId],'stake'); + if(($stakeSum + $data['stake']) > 100){ + exit(jsonReturn('股份分配超出100%比例,当前最大修改比例'.(100-$stakeSum),1)); + } + $isSuccess = $m->insertInfo($data); + } + + if(false !== $isSuccess){ + session('auth_UserPhone',null); + session('auth_ok',null); + exit(jsonReturn('提交成功',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + +} diff --git a/hyhproject/app/controller/Base.php b/hyhproject/app/controller/Base.php new file mode 100755 index 0000000..4960d47 --- /dev/null +++ b/hyhproject/app/controller/Base.php @@ -0,0 +1,112 @@ +<?php +namespace wstmart\app\controller; +use think\Controller; +/** + * ============================================================================ + * 基础控制器 + */ +class Base extends Controller { + //token + private $token = ''; + //用户 id + private $userId = 0; + + protected $user = []; + + public function __construct(){ + parent::__construct(); + + } + // 权限验证方法 + protected function checkDataAuth(){ + $shopId = (int)input('post.shopId'); + if(!$shopId ){ + exit(jsonReturn('参数传递不完整')); + } + $shopInfo = Model('shops')->getFieldsById($shopId,'shopId,userId'); + if(empty($shopInfo) || $shopInfo['userId'] != $this->getUserId()){ + exit(jsonReturn('没有权限!'.$this->getUserId())); + } + session('WST_USER.shopId',$shopId); + } + // 权限验证方法 + protected function checkAuth(){ + //正式上线要解开注释 + $user = session('WST_USER'); + if(empty($user)){ + if(!$this->checkToken()){ + die('{"status":-999,"msg":"您还未登录!"}'); + } + }else{ + $this->user = $user; + } + //商家需要判断是否有优惠款未提交 + if($this->user['userType'] == 1 && strtolower(request()->controller()) != 'shoporders'){ + $rs = Model('common/Orders')->checkCertificate($this->getUserId()); + if(1 != $rs['status']){ + exit(json_encode($rs)); + } + } + // if(0 == $this->user['userStatus']){ + // die('{"status":-1,"msg":"此账号已被禁用,请重新登录!"}'); + // } + } + /** + * token检查验证 + * @return [type] [description] + */ + protected function checkToken(){ + $token = $this->request->header('HYH-Token'); + if (empty($token)) { + return false;//未发送token + } + $this->token = $token; + $user = getUserByToken($token); + if (empty($user)) { + return false;//登录已失效! + } + $this->user = $user; + session('WST_USER',$user); + return true; + } + /** + * 获取会员ID + * @return [type] [description] + */ + public function getUserId(){ + return $this->user['userId']; + } + /** + * 获取推荐ID + * @return [type] [description] + */ + public function getPid(){ + return Model('UserTrees')->getField($this->userId); + } + /** + * 上传图片 + */ + public function uploadPic(){ + return WSTUploadPic(0); + } + /** + * 获取验证码 + */ + public function getVerify(){ + WSTVerify(); + } + //登录验证方法--商家 + protected function checkShopAuth(){ + // $user = session('WST_USER'); + // if(empty($user)){ + // if(!$this->checkToken()){ + // // die('{"status":-999,"msg":"您还未登录"}'); + // } + if(empty($this->user['userType']) || $this->user['userType'] == 0) die('{"status":-2,"msg":"请先申请开店"}'); + // }else{ + // if($user['userType'] == 0) die('{"status":-2,"msg":"请先申请开店"}'); + // $this->user = $user; + // } + + } +} \ No newline at end of file diff --git a/hyhproject/app/controller/Brands.php b/hyhproject/app/controller/Brands.php new file mode 100755 index 0000000..5668fa4 --- /dev/null +++ b/hyhproject/app/controller/Brands.php @@ -0,0 +1,26 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Brands as M; +/** + * ============================================================================ + * 品牌控制器 + */ +class Brands extends Base{ + /** + * 主页 + */ + public function index(){ + return $this->fetch('brands'); + } + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['brandImg'] = WSTImg($v['brandImg'],2); + } + return $rs; + } +} diff --git a/hyhproject/app/controller/Carts.php b/hyhproject/app/controller/Carts.php new file mode 100755 index 0000000..462a118 --- /dev/null +++ b/hyhproject/app/controller/Carts.php @@ -0,0 +1,199 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Carts as M; +use wstmart\common\model\UserAddress; +use wstmart\common\model\Payments; +/** + * ============================================================================ + * 购物车控制器 + */ +class Carts extends Base{ + + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 批量修改购物车状态 + */ + public function batchChangeCartGoods(){ + $m = new M(); + $rs = $m->batchChangeCartGoods(); + exit(json_encode($rs)); + } + /** + * 查看购物车列表 + */ + public function index(){ + $m = new M(); + $carts = $m->getCarts(false); + exit(jsonReturn("",1,$carts)); + } + /** + * 加入购物车 + */ + public function addCart(){ + $m = new M(); + $rs = $m->addCart(); + $rs['cartNum'] = WSTCartNum(); + exit(json_encode($rs)); + } + /** + * 修改购物车商品状态 + */ + public function changeCartGoods(){ + $m = new M(); + $rs = $m->changeCartGoods(); + exit(json_encode($rs)); + } + /** + * 删除购物车里的商品 + */ + public function delCart(){ + $m = new M(); + $rs= $m->delCart(); + exit(json_encode($rs)); + } + /** + * 计算运费、惠宝和总商品价格 + */ + public function getCartMoney(){ + $m = new M(); + $data = $m->getCartMoney(); + exit(json_encode($rs)); + } + /** + * 计算运费、惠宝和总商品价格 + */ + public function getMoney(){ + $type = (int)input('type'); + if($type == 1){ + $rs = model('carts')->getMoney();//立即下单获取价格 + }else{ + $m = new M(); + $rs =$m->getCartMoney();//购物车获取价格 + } + exit(json_encode($rs)); + } + /** + * 计算运费、惠宝和总商品价格/虚拟商品 + */ + public function getQuickCartMoney(){ + $m = new M(); + $data = $m->getQuickCartMoney(); + return $data; + } + /** + * 立即购买保存下参数 + * @return [type] [description] + */ + public function buy(){ + $rs = model('Carts')->buy(); + exit(json_encode($rs)); + } + /** + * 跳去购物车结算页面 + */ + public function settlement(){ + + $m = new M(); + //获取一个用户地址 + $addressId = (int)input('addressId'); + $ua = new UserAddress(); + if($addressId>0){ + $userAddress = $ua->getById($addressId); + }else{ + $userAddress = $ua->getDefaultAddress(); + } + //$this->assign('userAddress',$userAddress); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('4',-1,true);//具体支付场景1pc,2wap,3微信,4app + + //dump($payments); + //获取已选的购物车商品 + //$carts = $m->getCarts(true, 0, $userAddress);// 添加运费显示 mark hsf 20171116 + $userId = (int)session('WST_USER.userId'); + $areaId2 = isset($userAddress['areaId2']) ? $userAddress['areaId2'] : 0; + + $type = (int)input('type'); + if($type == 1){ + $carts = model('carts')->buyNow($areaId2);//立即下单结算方式 + }else{ + $carts = $m->getCarts(true, 0, $areaId2); + } + if(empty($carts['carts'])){ + exit(jsonReturn('未找到相关商品',-1)); + } +// //$carts = $m->getCarts(true, 0, $userAddress);购物车结算方式 + hook("appControllerCartsSettlement",["carts"=>$carts,"payments"=>&$payments]); +// //ect整合相关优惠还有判断不能和在线支付商品一块 +// hook("ectIntegration",["carts"=>&$carts,'isSettlement'=>true,'uId'=>(int)session('WST_USER.userId')]); +// +// //获取用户惠宝 + $user = model('users')->getFieldsById($userId,'userScore,loginName,userMoney,userECT'); +// //计算可用惠宝和金额 +// $goodsTotalMoney = round((($carts['goodsTotalMoney'] - $carts['promotionMoney'] - $carts['allShippingMoney']) * HuiScale()),2);//$carts['goodsTotalMoney']; 惠宝最多可抵用20% mark 20170907 +// $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); +// $useOrderScore =0; +// $useOrderMoney = 0; +// // if(!isset($carts['ect_pay']) || !$carts['ect_pay']){ +// if($user['userScore']>$goodsTotalScore){//个人所有积分大于订单可抵用的积分 +// $useOrderScore = $goodsTotalScore;//可抵下的积分 +// $useOrderMoney = $goodsTotalMoney;//可抵下的金额 +// }else{ +// $useOrderScore = $user['userScore'];//可抵下的积分为自已所有的积分 +// $useOrderMoney = WSTScoreToMoney($useOrderScore);//转换成金额 +// } +// // } + $data = $carts; + $data['loginName'] = $user['loginName']; + $data['userMoney'] = $user['userMoney']; + $data['userECT'] = $user['userECT']; + $data['userAddress'] = $userAddress; + $data['payments'] = $payments; + $data['useOrderScore'] = 0;// $useOrderScore;//可抵积分 + $data['useOrderMoney'] = 0;//$useOrderMoney;//可抵积分换算成金额 + exit(jsonReturn('',1,$data)); + } + /** + * 跳去虚拟商品购物车结算页面 + */ + public function quickSettlement(){ + $m = new M(); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('2'); + $this->assign('payments',$payments); + //获取用户惠宝 + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + //获取已选的购物车商品 + $carts = $m->getQuickCarts(); + //计算可用惠宝和金额 + $goodsTotalMoney = $carts['goodsTotalMoney']; + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + $useOrderScore =0; + $useOrderMoney = 0; + if($user['userScore']>$goodsTotalScore){ + $useOrderScore = $goodsTotalScore; + $useOrderMoney = $goodsTotalMoney; + }else{ + $useOrderScore = $user['userScore']; + $useOrderMoney = WSTScoreToMoney($useOrderScore); + } + $this->assign('userOrderScore',$useOrderScore); + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + return $this->fetch('settlement_quick'); + } + + /** + * APP购物车推荐商品 + */ + public function recommendGoods(){ + $m = new M(); + $recommendGoods = $m->recommendGoods(); + exit(json_encode($recommendGoods)); + } +} diff --git a/hyhproject/app/controller/Cashconfigs.php b/hyhproject/app/controller/Cashconfigs.php new file mode 100755 index 0000000..0bf19b2 --- /dev/null +++ b/hyhproject/app/controller/Cashconfigs.php @@ -0,0 +1,54 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 提现账号控制器 + */ +class Cashconfigs extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看提现账号 + */ + public function index(){ + $this->assign('area',model('areas')->listQuery(0)); + $this->assign('banks',model('banks')->listQuery(0)); + return $this->fetch('users/cashconfigs/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashConfigs')->pageQuery(0,$userId); + return jsonReturn("", 1,$data); + } + /** + * 获取记录 + */ + public function getById(){ + $id = (int)input('id'); + return model('CashConfigs')->getById($id); + } + /** + * 新增 + */ + public function add(){ + return model('CashConfigs')->add(); + } + /** + * 编辑 + */ + public function edit(){ + return model('CashConfigs')->edit(); + } + /** + * 删除 + */ + public function del(){ + return model('CashConfigs')->del(); + } +} diff --git a/hyhproject/app/controller/Cashdraws.php b/hyhproject/app/controller/Cashdraws.php new file mode 100755 index 0000000..87c3d6f --- /dev/null +++ b/hyhproject/app/controller/Cashdraws.php @@ -0,0 +1,34 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 提现记录控制器 + */ +class Cashdraws extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看用户提现记录 + */ + public function index(){ + return $this->fetch('users/cashdraws/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashDraws')->pageQuery(0,$userId); + return jsonReturn("", 1,$data); + } + + /** + * 提现 + */ + public function drawMoney(){ + return model('CashDraws')->drawMoney(); + } +} diff --git a/hyhproject/app/controller/Chain3.php b/hyhproject/app/controller/Chain3.php new file mode 100755 index 0000000..4e43cb3 --- /dev/null +++ b/hyhproject/app/controller/Chain3.php @@ -0,0 +1,34 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Chain3 extends Chain3base{ + public function __construct(){ + parent::__construct(); + $this->wei = 8; + } + /** + *查询ect余额 + * + * @return void + */ + public function get_Balance(){ + $address = $this->getCoinbase();//trim(input('post.address')); + $this->web3->eth->getBalance($address , function ($err, $balance) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $my_balance = $balance->toString(); + $my_balance = $my_balance/pow(10,$this->wei); + $data['balance'] = $my_balance; + exit(jsonReturn('',1,$data)); + } + }); + } + + +} diff --git a/hyhproject/app/controller/Chain3base.php b/hyhproject/app/controller/Chain3base.php new file mode 100755 index 0000000..30f7047 --- /dev/null +++ b/hyhproject/app/controller/Chain3base.php @@ -0,0 +1,117 @@ +<?php +namespace wstmart\app\controller; +use think\Controller; +Vendor('web3.vendor.autoload'); +use Web3\Web3; +/** + * ============================================================================ + * 默认控制器 + */ +class Chain3base extends Controller{ + /** + * web3 + * + * @var \Web3\Web3 + */ + protected $web3; + + protected $wei = 18; + /** + * testRinkebyHost + * + * @var string + */ + protected $testRinkebyHost = 'http://localhost'; + + /** + * testHost + * + * @var string + */ + protected $testHost = 'http://localhost:8545'; + + /** + * coinbase + * + * @var string + */ + protected $coinbase; + + public function __construct(){ + $web3 = new Web3($this->testHost); + $this->web3 = $web3; + } + public function getCoinbase(){ + $this->web3->eth->coinbase(function ($err, $coinbase) { + if ($err !== null) { + $this->coinbase = 0; + //return $this->fail($err->getMessage()); + } + $this->coinbase = $coinbase; + }); + return $this->coinbase; + + ////获取本机账号列表 + // $this->web3->eth->accounts(function ($err, $accounts) use ($eth) { + // if ($err !== null) { + // echo 'Error: ' . $err->getMessage(); + // return; + // } + // dump($accounts); + // }); + } + /** + *创建账号 + * + * @return void + */ + protected function create_account(){ + $pass = trim(input('post.pass')); + if(strlen($pass) < 6 ){ + exit(jsonReturn('密码最低6位')); + } + $web3->personal->newAccount($pass, function ($err, $account) use (&$newAccount) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $data['account'] = $account; + exit(jsonReturn('',1,$data)); + } + }); + } + protected function get_Balance(){ + $address = trim(input('post.address')); + $this->web3->eth->getBalance($address , function ($err, $balance) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $my_balance = $balance->toString(); + $my_balance = $my_balance/pow(10,$this->wei); + $data['balance'] = $my_balance; + exit(jsonReturn('',1,$data)); + } + }); + } + //账号解锁 + protected function unlock_account($pass,$address){ + $web3->personal->unlockAccount($address, $pass, function ($err, $unlocked) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + // return; + } + if($unlocked) { + $data['unlock'] = 1;//$unlocked; + exit(jsonReturn('',1,$data)); + } else { + $data['unlock'] = 0; + exit(jsonReturn('',1,$data)); + //echo 'New account isn\'t unlocked' . PHP_EOL; + } + }); + } +} diff --git a/hyhproject/app/controller/Ect.php b/hyhproject/app/controller/Ect.php new file mode 100755 index 0000000..56ec8cd --- /dev/null +++ b/hyhproject/app/controller/Ect.php @@ -0,0 +1,148 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Orders as OM; +use wstmart\app\model\EctElevenPay as M; +/** + * ============================================================================ + * 默认控制器 + */ +class Ect extends Base{ + + /** + * 跳去支付页面 + */ + public function payment(){ + $data = []; + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + + $m = new OM(); + $rs = $m->getOrderPayInfo($data);//获取订单金额以及用户钱包金额 + + $pay['list'] = $m->getByUnique();// 根据订单唯一流水获取订单信息 + + if(empty($rs)){//已支付或者找不到此订单 + exit(jsonReturn('读取失败',-1)); + }else{ + $pay['needPay'] = $rs['needPay'];//需付款 + //获取用户钱包 + $user = model('users')->getFieldsById($data['userId'],'userECT,payPwd'); + $pay['userECT'] = $user['userECT']; + $payPwd = $user['payPwd']; + $payPwd = empty($payPwd)?0:1; + $pay['payPwd'] = $payPwd;//1有密码0没设置密码 + } + exit(jsonReturn('',1,$pay)); + + } + private function getHTTPS($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_REFERER, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $result = curl_exec($ch); + curl_close($ch); + return $result; + } + public function getDollerPrice(){ + $now_doller = db('doller')->where('id=1')->cache(true)->value('doller'); + exit(jsonReturn('',1,['now_doller'=>$now_doller])); + } + public function getToEctNum(){ + try{ + $url ='https://api.tokencan.net/exchange-open-api/open/api/get_ticker?symbol=ectusdt'; + $t_info = $this->getHTTPS($url); + $t_info = json_decode($t_info); + if(is_object($t_info)){ + $total_money = input('total_money'); + $t_usdt_price = $t_info->data->last; + $now_doller = db('doller')->where('id=1')->value('doller'); + $now_rmb = round($t_usdt_price*$now_doller,2); + $to_ect_num = round($total_money/$now_rmb,2); + $ect_discount = Model('payments')->getPaymentDiscount('ect'); + $ect_msg=''; + if($ect_discount >= 0.9 && $ect_discount <1){ + $ect_msg=',ECT支付'.($ect_discount*10).'折'; + $to_ect_num *= $ect_discount; + } + $msg='当前ECT价格:'.$now_rmb.',订单价格:'.$total_money.$ect_msg.',共需:'.round($to_ect_num,2).' ECT'; + session('ect_rmb_price',$now_rmb); + exit(jsonReturn($msg,1,['ect_num'=>$to_ect_num])); + } + }catch (\Exception $e) { + exit(jsonReturn('获取价格失败!',-1)); + } + + + } + + /** + * 返回获取双11优惠券所需的ect数量和价格 + * @return [type] [description] + */ + public function getEctNum(){ + $m = new M(); + $result = $m->getEctNum(); + exit(json_decode($result)); + } + /** + * 支付双十一优惠券的ect价格 + */ + public function payElevenEct(){ + $m = new M(); + $result = $m->payElevenEct(); + exit(json_decode($result)); + } + /** + * 当前用户的ECT数量 + * @return [type] [description] + */ + public function userECT(){ + $data['ectNum'] = model('Ectwallet')->getEctNum(); + // $data['eAddressInfo'] = model('Ectwallet')->getDefaultAddress(); + // return WSTReturn('',1,$data); + exit(jsonReturn('',1,$data)); + } + + + /** + * ECT支付 + */ + public function payByEct(){ + $m = new OM(); + exit(json_encode($m->payByEct())); + } + ///** + // *查询ect余额 + // * + // * @return void + // */ + // public function get_balance(){ + // $ect_model = Model('Ect'); + // $address = $ect_model->getCoinbase();//trim(input('post.address')); + // if(strlen($address)<=40){ + // exit(jsonReturn('地址不正确')); + // } + // dump($ect_model->getBalance($address)); + // } + // public function get_mc_Balance(){ + // $address = $this->getCoinbase();//trim(input('post.address')); + // $this->web3->eth->getBalance($address , function ($err, $balance) { + // if ($err !== null) { + // exit(jsonReturn($err->getMessage())); + // // echo 'Error: ' . $err->getMessage(); + // //return; + // }else{ + // $my_balance = $balance->toString(); + // $my_balance = $my_balance/pow(10,$this->wei); + // $data['balance'] = $my_balance; + // exit(jsonReturn('',1,$data)); + // } + // }); + // } + +} diff --git a/hyhproject/app/controller/Ectwallets.php b/hyhproject/app/controller/Ectwallets.php new file mode 100755 index 0000000..7861cb6 --- /dev/null +++ b/hyhproject/app/controller/Ectwallets.php @@ -0,0 +1,232 @@ +<?php + +namespace wstmart\app\controller; + +use wstmart\common\model\Ectwallet; + +/** + + * ============================================================================ + + * 用户电子钱包控制器 + + */ + + + +class Ectwallets extends Base{ + + + + protected $beforeActionList = ['checkAuth'];// 访问这些except下的方法不需要执行前置操作 + + /** + + * 设置为默认地址 + + */ + + public function setDefault(){ + + $rs = model('Ectwallet')->setDefault(); + + exit(json_encode($rs)); + + // return $rs; + + } + + /** + + * [index description] + + * @return [type] [description] + + */ + + public function index(){ + + $data['ectNum'] = model('Ectwallet')->getEctNum(); + + $data['eAddressInfo'] = model('Ectwallet')->getDefaultAddress(); + + // return WSTReturn('',1,$data); + + exit(jsonReturn('',1,$data)); + + } + + /** + + * [listQuery 钱包地址列表页] + + * @return [type] [description] + + */ + + public function listQuery(){ + + $data = model('Ectwallet')->listQuery(); + + exit(jsonReturn('',1,$data)); + + } + + /** + + * 跳去修改地址 + + */ + + public function edit(){ + + $id = input('post.eWalletId/d'); + + $m = model('Ectwallet'); + + $data = $m->infoById($id); + + // return WSTReturn('',1,$data); + + exit(jsonReturn('',1,$data)); + + } + + /** + + * 新增 + + */ + + public function add(){ + + $m = model('Ectwallet'); + + $rs = $m->add(); + + exit(json_encode($rs)); + + } + + /** + + * 修改 + + */ + + public function toEdit(){ + + $m = model('Ectwallet'); + + $rs = $m->edit(); + + exit(json_encode($rs)); + + } + + /** + + * 删除 + + */ + + public function del(){ + + $m = model('Ectwallet'); + + $rs = $m->del(); + + exit(json_encode($rs)); + + } + + /** + + * 获取ect变更记录 + + */ + + public function getEctLog(){ + + $m = model('Ectwallet'); + + $rs = $m->getEctLog(); + + exit(jsonReturn('',1,$rs)); + + } + + /** + + * 获取ect充值记录 + + */ + + public function getEctRechargeLog(){ + + $m = model('Ectwallet'); + + $rs = $m->getEctRechargeLog(); + + exit(jsonReturn('',1,$rs)); + + } + + /** + + * 获取ect提现记录 + + */ + + public function getUserEctCashLog(){ + + $m = model('Ectwallet'); + + $rs = $m->getUserEctCashLog(); + + exit(jsonReturn('',1,$rs)); + + } + + + + /** + + * 获取ect地址 + + */ + + public function getEctAddress(){ + + $m = model('Ectwallet'); + + $rs = $m->getEctAddress(); + + exit(json_encode($rs)); + + } + + /** + + * [withdraw 提现] + + * @return [type] [description] + + */ + + public function withdraw(){ + + $m = model('Ectwallet'); + + $rs = $m->withdraw(); + + exit(json_encode($rs)); + + } + + + + + +} + diff --git a/hyhproject/app/controller/Error.php b/hyhproject/app/controller/Error.php new file mode 100755 index 0000000..0579672 --- /dev/null +++ b/hyhproject/app/controller/Error.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 错误处理控制器 + */ +class Error extends Base{ + public function index(){ + header("HTTP/1.0 404 Not Found"); + return $this->fetch('error_sys'); + } + public function message(){ + $code = input('code'); + if($code !== null && session($code)!=''){ + $this->assign('message',session($code)); + }else{ + $this->assign('message','操作错误,请联系商城管理员'); + } + return $this->fetch('error_lost'); + } +} diff --git a/hyhproject/app/controller/Favorites.php b/hyhproject/app/controller/Favorites.php new file mode 100755 index 0000000..7ed3a9f --- /dev/null +++ b/hyhproject/app/controller/Favorites.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Favorites as M; +/** + * ============================================================================ + * 收藏控制器 + */ +class Favorites extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 关注的商品 + */ + public function goods(){ + return $this->fetch('users/favorites/list_goods'); + } + /** + * 关注的店铺 + */ + public function shops(){ + return $this->fetch('users/favorites/list_shops'); + } + /** + * 关注的商品列表 + */ + public function listGoodsQuery(){ + $m = new M(); + $data = $m->listGoodsQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + exit(jsonReturn("", 1,$data)); + } + /** + * 关注的店铺列表 + */ + public function listShopQuery(){ + $m = new M(); + $data = $m->listShopQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['shopImg'] = WSTImg($v['shopImg'],3); + if(!empty($v['goods'])){ + foreach($v['goods'] as $k1=>$v1){ + $v[$k1]['goodsImg'] = WSTImg($v1['goodsImg'],3); + } + } + } + exit(jsonReturn("", 1,$data)); + } + /** + * 取消关注 + */ + public function cancel(){ + $m = new M(); + $rs = $m->del(); + exit(jsonReturn("", 1,$rs)); + } + /** + * 增加关注 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + exit(jsonReturn("", 1,$rs)); + } +} diff --git a/hyhproject/app/controller/Goods.php b/hyhproject/app/controller/Goods.php new file mode 100755 index 0000000..d65d298 --- /dev/null +++ b/hyhproject/app/controller/Goods.php @@ -0,0 +1,213 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\GoodsCats; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['only'=>'history'] + ]; + public function tmp(){ + return; + $orderNo = [100066190,100066186,100065840,100065770,100065490,100065420,100065405,100065276,100064963,100064930,100064926,100064915,100064510,100064322,100064274,100064226,100064215,100064090,100064053,100063762,100063655,100063493,100063482,100063471,100063460,100063375,100063224,100063106,100063095,100063084,100063062,100063040,100063036,100063025,100063014,100063003,100062992,100062815,100066422,100066411,100066396,100066245]; + foreach ($orderNo as &$key) { + echo $key; + dump(model('OrderRefunds')->byRefund($key)); + } + } + /** + * 商品主页 + */ + public function detail(){ + + $m = model('goods'); + //获取商品id mark 20180323 + $goods_id = input('goodsId/d'); + $goods = $m->getBySale($goods_id); + hook('mobileControllerGoodsIndex',['getParams'=>input()]); + // 找不到商品记录 + if(empty($goods)) exit(jsonReturn("此商品已下架或被删除!".$goods_id, -22)); + //记录用户浏览商品 + $userId = (int)session('WST_USER.userId'); + if($userId){ + $data['userId']= $userId; + $data['goodsId']=$goods['goodsId']; + $data['path']='3'; + $data['create_time']=time(); + $result=db('page_view')->insert($data); + } + $goods['goodsDesc']=htmlspecialchars_decode($goods['goodsDesc']); + $rule = '/<img src="\/(upload.*?)"/'; + preg_match_all($rule, $goods['goodsDesc'], $images); + + foreach($images[0] as $k=>$v){ + $goods['goodsDesc'] = str_replace('/'.$images[1][$k], '__ROOT__/'.WSTConf("CONF.goodsLogo") . "\" data-echo=\"__ROOT__/".WSTImg($images[1][$k],0), $goods['goodsDesc']); + } + if(!empty($goods)){ + // $history = cookie("wx_history_goods"); + // $history = is_array($history)?$history:[]; + // array_unshift($history, (string)$goods['goodsId']); + // $history = array_values(array_unique($history)); + // if(!empty($history)){ + // cookie("wx_history_goods",$history,25920000); + // } + + $goods['imgcount'] = count($goods['gallery']); + //$goods['imgwidth'] = 'width:'.$goods['imgcount'].'00%'; + } + //添加注册推荐人 mark 20180323 + $goods['goods_url'] = url('mgoods-'.$goods_id.'.html','pName='.session('WST_USER.loginName'),'',true); + $goods['goodsCount'] = $m->getGoodsCount($goods['shopId']);//全部商品数 + $goods['shopAccreds'] = model('shops')->shopAccreds($goods['shopId']);//店铺认证 + $goods['newGoodsCount'] = $m->getNewGoodsCount($goods['shopId']);//上新数 + $goods['favoritesShopsNum'] = model('favorites')->getFavoritesShopsNum($goods['shopId']);//关注数 + $goods['isFavorites'] = 0;//未关注该商品 + if($userId){ + $isFavorites = model('favorites')->isGetFavorites($goods['goodsId'],$userId); + if($isFavorites){ + $goods['isFavorites'] = 1;//已关注该商品 + } + } + $couponList = $this->getCouponList(0); + if(isset($couponList['data'])){ + $goods['couponList'] = $couponList['data'];//优惠券列表 + }else{ + $goods['couponList'] = [];//优惠券列表 + } + + $goods['promotionList'] = $this->getPromotionList($goods['shopId'], $goods['goodsId'],0);//获取可用的满减活动 + $goods['oneAppraises'] = model('goods_appraises')->getOneAppraises($goods['goodsId']);//获取一个评论 + + $goods['showWhsle'] = 0;//是否显示批发价 + // $hyhlm_id = session('WST_USER.hyhlm_id');//联盟ID + // if($hyhlm_id){ + // $lm_info = getLMUserByID($hyhlm_id,'u_level'); + // if($lm_info['u_level'] >= 1){ + // $goods['showWhsle'] = 1; + // } + // } + // hook('afterGetGoods',['params'=>&$goods]); + + //dump($goods);die; + //exit(json_encode($goods)); + // dump(hook('mobileDocumentGoodsPropDetail')); + // dump(hook('mobileDocumentGoodsPromotionDetail',['goods'=>$goods])); + //die; + $rsv = jsonReturn('', 1,$goods); + + exit($rsv); + } + function gbk_to_utf8($data) { + if( is_array($data) ) { + foreach ($data as $k => $v) { + if ( is_array($v) ) { + $data[$k] = $this->gbk_to_utf8($v); + } else { + $data[$k] = iconv('GBK', 'UTF-8//IGNORE', $v); + } + } + return $data; + } else { + $data = iconv('GBK', 'UTF-8//IGNORE', $data); + return $data; + } + } + /** + * 获取优惠券列表 + * @param integer $returnJson [是否返回json数据] + * @return [type] [description] + */ + public function getCouponList($returnJson = 1){ + return; + $m = new \addons\coupon\model\Coupons(); + $data = $m->getCouponsByGoods(); + if($returnJson == 1){ + exit(json_encode($data)); + }else{ + return $data; + } + } + /** + * 获取满就送列表 + * @param [type] $shopId [商铺ID] + * @param [type] $goodsId [商品ID] + * @param integer $returnJson [是否返回json数据] + * @return [type] [description] + */ + public function getPromotionList($shopId=0,$goodsId=0,$returnJson = 1){ + return; + $shopId = ($shopId==0)?(int)input('shopId'):$shopId; + $goodsId = ($goodsId==0)?(int)input('goodsId'):$goodsId; + $rm = new \addons\reward\model\Rewards(); + $data = $rm->getAvailableRewards($shopId, $goodsId); + if($returnJson == 1){ + exit(json_encode("",1,$data)); + }else{ + return $data; + } + } + /** + * 商品列表 + */ + public function lists(){ + $this->assign("keyword", input('keyword')); + $this->assign("catId", input('catId/d')); + $this->assign("brandId", input('brandId/d')); + return $this->fetch('goods_list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = model('goods'); + $gc = new GoodsCats(); + $catId = (int)input('catId'); + if($catId>0){ + $goodsCatIds = $gc->getParentIs($catId); + }else{ + $goodsCatIds = []; + } + $from = (int)input("from", 0); + $scale = 0; + switch ($from){ + case 1: + $scale = dataConf('discountRateGtToShopping'); + break; + case 2: + $scale = dataConf('discountRateGtToHelp'); + break; + case 3: + $scale = dataConf('discountRateGtToHelpShopping'); + break; + } + $_where['discountRate'] = [">=", $scale]; + $rs = $m->pageQuery($goodsCatIds, $_where); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + // `券`标签 + hook('afterQueryGoods',['page'=>&$rs]); + exit(jsonReturn("", 1,$rs)); + } + + /** + * 浏览历史页面 + */ + public function history(){ + return $this->fetch('users/history/list'); + } + /** + * 获取浏览历史 + */ + public function historyQuery(){ + $rs = model('goods')->historyQuery(); + if(!empty($rs)){ + foreach($rs['Rows'] as $k=>$v){ + $rs['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + } + return $rs; + } +} diff --git a/hyhproject/app/controller/Goodsappraises.php b/hyhproject/app/controller/Goodsappraises.php new file mode 100755 index 0000000..043cc2b --- /dev/null +++ b/hyhproject/app/controller/Goodsappraises.php @@ -0,0 +1,44 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\GoodsAppraises as M; +/** + * ============================================================================ + * 评价控制器 + */ +class GoodsAppraises extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'getbyid'],// 只要访问only下的方法才才需要执行前置操作 + ]; + /** + * 根据商品id评论 + */ + public function getById(){ + $m = new M(); + $rs = $m->getById(); + exit(json_encode($rs)); + } + /** + * 根据订单id,用户id,商品id获取评价 + */ + public function getAppr(){ + $m = model('GoodsAppraises'); + $rs = $m->getAppr(); + if(!empty($rs['data']['images'])){ + $imgs = explode(',',$rs['data']['images']); + foreach($imgs as $k=>$v){ + $imgs[$k] = WSTImg($v,1); + } + $rs['data']['images'] = $imgs; + } + return $rs; + } + /** + * 添加评价 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } +} diff --git a/hyhproject/app/controller/Goodscats.php b/hyhproject/app/controller/Goodscats.php new file mode 100755 index 0000000..5b189b2 --- /dev/null +++ b/hyhproject/app/controller/Goodscats.php @@ -0,0 +1,32 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function index(){ + $m = new M(); + $goodsCatList = $m->getGoodsCats(); + exit(jsonReturn('',1,$goodsCatList)); + } + public function getGoodsCat(){ + $m = new M(); + $goodsCatList = $m->getGoodsCat(); + exit(jsonReturn('',1,$goodsCatList)); + } + /** + * 获取分类名 + * @return [type] [description] + */ + public function getCatName(){ + $m = new M(); + $rs = $m->getCatName(); + exit(jsonReturn('',1,$rs)); + } + +} diff --git a/hyhproject/app/controller/Goodsconsult.php b/hyhproject/app/controller/Goodsconsult.php new file mode 100755 index 0000000..63fe2bf --- /dev/null +++ b/hyhproject/app/controller/Goodsconsult.php @@ -0,0 +1,35 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\GoodsConsult as CG; +/** + * ============================================================================ + * 商品咨询控制器 + */ +class GoodsConsult extends Base{ + /** + * 商品咨询页 + */ + public function index(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/list'); + } + /** + * 根据商品id获取商品咨询 + */ + public function listQuery(){ + $m = new CG(); + return $m->listQuery(); + } + /** + * 发布商品咨询页 + */ + public function consult(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/consult'); + } + public function add(){ + $m = new CG(); + return $m->add(); + } + +} diff --git a/hyhproject/app/controller/Index.php b/hyhproject/app/controller/Index.php new file mode 100755 index 0000000..5bb1e0e --- /dev/null +++ b/hyhproject/app/controller/Index.php @@ -0,0 +1,122 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Index as M; +/** + * ============================================================================ + * 默认控制器 + */ +class Index extends Base{ + public function tmp(){ + //$orderId = 80; + // model('common/Settlements')->speedySettlement($orderId); + // dump(input('post.')); + //dump(Model('orders')->receive(56,1)); + } + /** + * 分配券值 + * @return [type] [description] + */ + public function startGiveVouchers(){ + Model('UserVouchers')->startGiveVouchers(); + } + /** + * 首页 + */ + public function index(){ + echo 'hello';die; + echo request()->ip();die; + $m = new M(); + hook('mobileControllerIndexIndex',['getParams'=>input()]); + + //秒杀商品 + // $now_time = time(); //当前时间 + // if(is_int($now_time/7200)){ //双整点时间,如:10:00, 12:00 + // $start_time = $now_time; + // }else{ + // $start_time = floor($now_time/7200)*7200; //取得前一个双整点时间 + // } + // $end_time = $start_time+7200; //结束时间 + + $year = date("Y"); + $month = date("m"); + $day = date("d"); + $start_time = mktime(8,0,0,$month,$day,$year);//当天开始时间戳 + $end_time= mktime(20,0,0,$month,$day,$year);//当天结束时间戳 + $this->assign('start_time',$start_time); + $this->assign('end_time',$end_time); + + $news = $m->getSysMsg('msg'); + $this->assign('news',$news); + $ads['count'] = count(model("common/Tags")->listAds("mo-ads-index",99,86400)); + $ads['width'] = 'width:'.$ads['count'].'00%'; + $this->assign("ads", $ads); + return $this->fetch('index'); + } + /** + * 楼层 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + if(isset($rs['goods'])){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + /** + * 猜你喜欢 + * @return [type] [description] + */ + public function guess_like(){ + $m = new M(); + $rs = $m->guess_like(); + if(isset($rs['goods'])){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + exit(jsonReturn('',1,$rs)); + } + /** + * 热卖推荐/ + * @return [type] [description] + */ + public function getHotGoods(){ + $m = new M(); + $rs = $m->getHotGoods(); + foreach ($rs['Rows'] as &$v){ + $v['goodsImg'] = WSTImg($v['goodsImg'],2); + } + exit(jsonReturn('',1,$rs)); + } + /** + * 猜你喜欢 + * @return [type] [description] + */ + public function getIndexAds(){ + $m = new M(); + $rs['ads'] = $m->getIndexAds(); + $rs['top_img'] = $m->getIndexTopImg(); + $rs['cross_img'] = $m->getIndexCrossImg(); + return $rs; + } + + /** + * 转换url + */ + public function transfor(){ + $data = input('param.'); + $url = $data['url']; + unset($data['url']); + echo Url($url,$data); + } + /** + * 跳去登录之前的地址 + */ + public function sessionAddress(){ + session('WST_MO_WlADDRESS',input('url')); + return jsonReturn("", 1); + } +} diff --git a/hyhproject/app/controller/Invoices.php b/hyhproject/app/controller/Invoices.php new file mode 100755 index 0000000..12269f0 --- /dev/null +++ b/hyhproject/app/controller/Invoices.php @@ -0,0 +1,31 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Invoices as M; +/** + * ============================================================================ + * 发票信息控制器 + */ +class Invoices extends Base{ + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(5);// 移动版只显示5条发票信息 + exit(jsonReturn('',1,$rs)); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } +} diff --git a/hyhproject/app/controller/Juhui.php b/hyhproject/app/controller/Juhui.php new file mode 100755 index 0000000..b45dd1d --- /dev/null +++ b/hyhproject/app/controller/Juhui.php @@ -0,0 +1,15 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Juhui extends Base{ + /** + * 首页 + */ + public function index(){ + return $this->fetch('juhui'); + } + +} diff --git a/hyhproject/app/controller/Logmoneys.php b/hyhproject/app/controller/Logmoneys.php new file mode 100755 index 0000000..d316ff1 --- /dev/null +++ b/hyhproject/app/controller/Logmoneys.php @@ -0,0 +1,59 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 资金流水控制器 + */ +class Logmoneys extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看用户资金流水 + */ + public function usermoneys(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $rs['isSetPayPwd'] = ($rs['payPwd']=='')?0:1; + unset($rs['payPwd']); + $rs['num'] = count(model('cashConfigs')->listQuery(0,$userId)); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/list'); + } + /** + * 资金流水 + */ + public function record(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/record'); + } + /** + * 列表 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('LogMoneys')->pageQuery("",$userId); + return jsonReturn("", 1,$data); + } + /** + * 验证支付密码 + */ + public function checkPayPwd(){ + return model('app/users')->checkPayPwd(); + } + + /** + * 充值[用户] + */ + public function toRecharge(){ + $payments = model('common/payments')->recharePayments('2'); + $this->assign('payments',$payments); + //print_r($payments); + $chargeItems = model('common/ChargeItems')->queryList(); + $this->assign('chargeItems',$chargeItems); + return $this->fetch('users/recharge/recharge'); + } +} diff --git a/hyhproject/app/controller/Messages.php b/hyhproject/app/controller/Messages.php new file mode 100755 index 0000000..949b495 --- /dev/null +++ b/hyhproject/app/controller/Messages.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Messages as M; +/** + * ============================================================================ + * 商城消息控制器 + */ +class Messages extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看商城消息 + */ + public function msgList(){ + $m = new M(); + exit(jsonReturn('',1,$m->pageQuery())); + //return $this->fetch('users/messages/list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 获取指定ID详情 + */ + public function getById(){ + $m = new M(); + exit(jsonReturn('',1,$m->getById())); + } + /** + * 删除消息 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 批量删除消息 + */ + public function batchDel(){ + $m = new M(); + return $m->batchDel(); + } +} diff --git a/hyhproject/app/controller/News.php b/hyhproject/app/controller/News.php new file mode 100755 index 0000000..6e6d8f0 --- /dev/null +++ b/hyhproject/app/controller/News.php @@ -0,0 +1,39 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Articles as M; +/** + * ============================================================================ + * 新闻控制器 + */ +class News extends Base{ + /** + * 列表查询 + */ + public function view(){ + $articleId = (int)input('articleId'); + $this->assign('articleId',$articleId); + return $this->fetch('articles/news_list'); + } + /** + * 获取商城快讯列表 + */ + public function getNewsList(){ + $m = new M(); + $data = $m->getArticles(); + foreach($data as $k=>$v){ + $data[$k]['articleContent'] = strip_tags(html_entity_decode($v['articleContent'])); + $data[$k]['createTime'] = date('Y-m-d',strtotime($data[$k]['createTime'])); + } + return $data; + } + /** + * 查看详情 + */ + public function getNews(){ + $m = new M(); + $data = $m->getNewsById(); + $data['articleContent']=htmlspecialchars_decode($data['articleContent']); + $data['createTime'] = date('Y-m-d',strtotime($data['createTime'])); + return $data; + } +} diff --git a/hyhproject/app/controller/Ordercomplains.php b/hyhproject/app/controller/Ordercomplains.php new file mode 100755 index 0000000..9e35719 --- /dev/null +++ b/hyhproject/app/controller/Ordercomplains.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\OrderComplains as M; +/** + * ============================================================================ + * 投诉控制器 + */ +class orderComplains extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + public function complain(){ + $oId = (int)input('oId'); + $this->assign('oId',$oId); + return $this->fetch('users/orders/orders_complains'); + } + /** + * 保存订单投诉信息 + */ + public function saveComplain(){ + return model('OrderComplains')->saveComplain(); + } + /** + * 获取投诉类型 + * @return [type] [description] + */ + public function getComplainCause(){ + exit(jsonReturn("",1,WSTDatas('ORDER_COMPLAINT'))); + } + /** + * 用户投诉列表 + */ + public function index(){ + return $this->fetch('users/orders/list_complains'); + } + + /** + * 获取用户投诉列表 + */ + public function complainByPage(){ + $m = model('OrderComplains'); + return $m->queryUserComplainByPage(); + + } + + /** + * 用户查投诉详情 + */ + public function getComplainDetail(){ + $rs = model('OrderComplains')->getComplainDetail(0); + $annex = $rs['complainAnnex']; + if($annex){ + foreach($annex as $k=>$v){ + $annex1[] = WSTImg($v,2); + } + $rs['complainAnnex'] = $annex1; + } + return $rs; + } + +} diff --git a/hyhproject/app/controller/Orderrefunds.php b/hyhproject/app/controller/Orderrefunds.php new file mode 100755 index 0000000..f8b4006 --- /dev/null +++ b/hyhproject/app/controller/Orderrefunds.php @@ -0,0 +1,25 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\OrderRefunds as M; +/** + * ============================================================================ + * 订单退款控制器 + */ +class Orderrefunds extends Base{ + /** + * 用户申请退款 + */ + public function refund(){ + $m = new M(); + $rs = $m->refund(); + return $rs; + } + /** + * 商家处理是否同意 + */ + public function shopRefund(){ + $m = new M(); + $rs = $m->shopRefund(); + return $rs; + } +} diff --git a/hyhproject/app/controller/Orders.php b/hyhproject/app/controller/Orders.php new file mode 100755 index 0000000..8acb05e --- /dev/null +++ b/hyhproject/app/controller/Orders.php @@ -0,0 +1,341 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Orders as M; +use wstmart\common\model\Payments; + +/** + * ============================================================================ + * 订单控制器 + */ +class Orders extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /*********************************************** 用户操作订单 ************************************************************/ + /** + * 提醒发货 + */ + public function noticeDeliver(){ + $m = new M(); + return $m->noticeDeliver(); + } + /** + * 提交订单 + */ + public function submit(){ + $m = new M(); + $rs = $m->submit(3); + exit(json_encode($rs)); + } + /** + * 提交虚拟订单 + */ + public function quickSubmit(){ + $m = new M(); + $rs = $m->quickSubmit(); + return $rs; + } + /** + * 在线支付方式 + */ + public function succeed(){ + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('4',-1,true);//具体支付场景1pc,2wap,3微信,4app + exit(jsonReturn('',1,$payments)); + // $this->assign('payments',$payments); + // $this->assign('orderNo',input("get.orderNo")); + // $this->assign('isBatch',(int)input("get.isBatch/d",0)); + // return $this->fetch("users/orders/orders_pay_list"); + } + /** + * 订单管理 + */ + public function index(){ + $type = input('param.type',''); + $this->assign('type',$type); + return $this->fetch("users/orders/orders_list"); + } + public function findExpress(){ + $orderId = (int)input("orderId"); + $userId = $this->getUserId(); + $where['userId'] = $userId; + if(!$orderId){ + $where['orderStatus'] = 1;//待收货状态 + $orderId = model('orders')->where($where)->max('orderId'); + }else{ + $where['orderId'] = $orderId; + $find = model('orders')->where($where)->value('orderId');//杜绝别人查看物流情况 + if(!$find){ + exit(jsonReturn('获取失败',-1)); + } + } + if($orderId){ + $m = new \addons\kuaidi\model\Kuaidi(); + $rs = $m->getOrderExpress($orderId); + $express = json_decode($rs, true); + $state = isset($express["state"])?$express["state"]:'-1'; + $data = $m->getOrderInfo($orderId); + $data["express"]["stateTxt"] = $this->getExpressState($state); + $express["express"] = $data["express"]; + $express["goodsImg"] = $data["goodsImg"]; + exit(jsonReturn('',1,$express)); + }else{ + exit(jsonReturn('获取失败',-1)); + } + + } + public function getExpressState($state){ + $stateTxt = ""; + switch ($state) { + case '0':$stateTxt="运输中";break; + case '1':$stateTxt="揽件";break; + case '2':$stateTxt="疑难";break; + case '3':$stateTxt="收件人已签收";break; + case '4':$stateTxt="已退签";break; + case '5':$stateTxt="派件中";break; + case '6':$stateTxt="退回";break; + default:$stateTxt="暂未获取到状态";break; + } + return $stateTxt; + } + /** + * 订单列表 + */ + public function getOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0,1: 待收货 + 2:待评价/已完成 + */ + $flag = -1; + $type = input('param.type'); + $status = []; + switch ($type) { + case 'waitPay': + $status=[-2]; + break; + case 'waitDeliver': + $status=[0]; + break; + case 'waitReceive': + $status=[1]; + break; + case 'waitAppraise': + $status=[2]; + $flag=0; + break; + case 'finish': + $status=[2]; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-5,-4,-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->userOrdersByPage($status,$flag); + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + // param.pagesize = 10; + //param.page = Number( $('#currPage').val() ) + 1; + exit(jsonReturn('',1,$rs)); + } + + /** + * 订单详情 + */ + public function getDetail(){ + $m = new M(); + $rs = $m->getByView((int)input('id')); + $rs['status'] = WSTLangOrderStatus($rs['orderStatus']); + $rs['payInfo'] = WSTLangPayType($rs['payType']); + $rs['deliverInfo'] = WSTLangDeliverType($rs['deliverType']); + foreach($rs['goods'] as $k=>$v){ + $v['goodsImg'] = WSTImg($v['goodsImg'],3); + } + // 优惠券钩子 + hook('mobileDocumentOrderSummaryView',['rs'=>&$rs]); + // 满就送钩子 + hook('mobileDocumentOrderViewGoodsPromotion',['rs'=>&$rs]); + exit(jsonReturn('',1,$rs)); + } + + /** + * 用户确认收货 + */ + public function receive(){ + $m = new M(); + $rs = $m->receive(); + exit(json_encode($rs)); + } + + /** + * 获取上传凭证 + */ + public function getCertificate(){ + $m = new M(); + $rs = $m->viewCertificate(); + exit(json_encode($rs)); + } + /** + * 用户上传凭证 + */ + public function uploadCertificate(){ + $m = new M(); + $rs = $m->uploadCertificate(); + exit(json_encode($rs)); + } + /** + * 用户-评价页 + */ + public function getOrderAppraise(){ + $m = model('Orders'); + $oId = (int)input('oId'); + //根据订单id获取 商品信息 + $data = $m->getOrderInfoAndAppr(); + $data['shopName']=model('shops')->getShopName($oId); + $data['oId']=$oId; + exit(jsonReturn('',1,$data)); + } + /** + * 用户取消订单 + */ + public function cancellation(){ + $m = new M(); + $rs = $m->cancel(); + return $rs; + } + /** + * 获取取消订单原因 + * @return [type] [description] + */ + public function getCancelCause(){ + exit(jsonReturn("",1,WSTDatas('ORDER_CANCEL'))); + } + /** + * 获取拒收订单原因 + * @return [type] [description] + */ + public function getRejectCause(){ + exit(jsonReturn("",1,WSTDatas('ORDER_REJECT'))); + } + /** + * 获取申请退款原因 + * @return [type] [description] + */ + public function getRefundCause(){ + exit(jsonReturn("",1,WSTDatas('REFUND_TYPE'))); + } + /** + * 用户拒收订单 + */ + public function reject(){ + $m = new M(); + $rs = $m->reject(); + exit(json_encode($rs)); + } + + /** + * 用户退款 + */ + public function getRefund(){ + $orderId = (int)input('id'); + $userId = $this->getUserId(); + $orders = model('orders')->where(['orderId'=>$orderId,'userId'=>$userId,'dataFlag'=>1])->field('orderStatus')->find(); + if(empty($orders))return jsonReturn("无效的订单"); + $m = new M(); + $data = $m->getMoneyByOrder($orderId); + exit(jsonReturn("",1,$data)); + } + /** + * 获取快递公司列表 + * @return [type] [description] + */ + public function getExpress(){ + $express = model('Express')->listQuery(); + exit(jsonReturn("",1,$express)); + } + /** + * 用户-延时收货 + */ + public function delay(){ + $m = new M(); + $rs = $m->delay(); + return $rs; + } + + + + /*********************************************** 商家操作订单 ************************************************************/ + + // /** + // * 商家-查看订单列表 + // */ + // public function sellerOrder(){ + // $type = input('param.type',''); + // $this->assign('type',$type); + // $express = model('Express')->listQuery(); + // $this->assign('express',$express); + // return $this->fetch('users/sellerorders/orders_list'); + // } + + // /** + // * 商家-订单列表 + // */ + // public function getSellerOrderList(){ + // /* + // -3:拒收、退款列表 + // -2:待付款列表 + // -1:已取消订单 + // 0: 待发货 + // 1,2:待评价/已完成 + // */ + // $type = input('param.type'); + // $status = []; + // switch ($type) { + // case 'waitPay': + // $status=-2; + // break; + // case 'waitDeliver': + // $status=0; + // break; + // case 'waitReceive': + // $status=1; + // break; + // case 'waitDelivery': + // $status=0; + // break; + // case 'finish': + // $status=2; + // break; + // case 'abnormal': // 退款/拒收 与取消合并 + // $status=[-1,-3]; + // break; + // default: + // $status=[-5,-4,-3,-2,-1,0,1,2]; + // break; + // } + // $m = new M(); + // $rs = $m->shopOrdersByPage($status); + // //dump($rs);die; + // foreach($rs['Rows'] as $k=>$v){ + // if(!empty($v['list'])){ + // foreach($v['list'] as $k1=>$v1){ + // $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + // } + // } + // } + // return $rs; + // } +} diff --git a/hyhproject/app/controller/Position.php b/hyhproject/app/controller/Position.php new file mode 100755 index 0000000..68e44d8 --- /dev/null +++ b/hyhproject/app/controller/Position.php @@ -0,0 +1,25 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Position as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Position extends Base{ + /** + * 获取地区名字 + */ + public function getAreaName(){ + $m = new M(); + $rs = $m->getAreaName(); + exit(jsonReturn('', 1,$rs)); + } + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + exit(jsonReturn('', 1,$rs)); + } +} diff --git a/hyhproject/app/controller/Qlgpay.php b/hyhproject/app/controller/Qlgpay.php new file mode 100755 index 0000000..1fd808f --- /dev/null +++ b/hyhproject/app/controller/Qlgpay.php @@ -0,0 +1,45 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Orders as OM; +/** + * ============================================================================ + * 全亮共支付 + */ +class Qlgpay extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 跳去支付页面 + */ + public function payment(){ + $data = []; + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $m = new OM(); + $rs = $m->getOrderPayInfo($data);//获取订单金额以及用户钱包金额 + + $pay['list'] = $m->getByUnique();// 根据订单唯一流水获取订单信息 + + if(empty($rs)){//已支付或者找不到此订单 + exit(jsonReturn('读取失败',-1)); + }else{ + $pay['needPay'] = $rs['needPay'];//需付款 + + } + $userId = $this->getUserId(); + $m = new OM(); + $pay = array_merge($pay,$m->getPayMoney($userId,$pay['needPay'])); + exit(jsonReturn('',1,$pay)); + + } + /* + * 钱包支付 + */ + public function payByQlg(){ + $m = new OM(); + exit(json_encode($m->payByQlg())); + } +} diff --git a/hyhproject/app/controller/Shoporders.php b/hyhproject/app/controller/Shoporders.php new file mode 100755 index 0000000..cab0e43 --- /dev/null +++ b/hyhproject/app/controller/Shoporders.php @@ -0,0 +1,145 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Orders as M; +// use think\Loader; +/** + * ============================================================================ + * 订单控制器 + */ + +class Shoporders extends Base{ + // protected $beforeActionList = [ + // 'checksession', //在任何操作执行前执行checksession方法 + // 'islogin' => ['except'=>'login'], //在除login之外的其他方法执行前先执行islogin方法 + // 'removesession' => ['only'=>'logout'], //在logout执行前先执行removesession + // ]; + protected $beforeActionList = [ + 'checkAuth',//=>['only'=>'shopjoin,getshopjoininfo'], + 'checkDataAuth' + ]; + + /** + * 查看订单凭证 + * @return [type] [description] + */ + public function viewCertificate(){ + $m = new M(); + $rs = $m->viewCertificate(1); + exit(json_encode($rs)); + } + /** + * 商家-订单列表 + */ + public function getSellerOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0: 待发货 + 1,2:待评价/已完成 + */ + $type = input('param.type'); + $status = []; + $shopConfirm = -1; + switch ($type) { + case 'waitPay': + $status=-2; + break; + case 'waitDeliver': + $status=0; + $shopConfirm = 1; + break; + case 'waitConfirm': + $status=0; + $shopConfirm = '0,2'; + break; + case 'waitReceive': + $status=1; + break; + case 'finish': + $status=2; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-5,-4,-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->shopOrderList($status,0,$shopConfirm); + //dump($rs);die; + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + exit(jsonReturn('',1,$rs)); + } + /** + * 订单确认 + * @return [type] [description] + */ + public function orderConfirm(){ + $m = new M(); + $rs = $m->orderConfirm(); + exit(jsonReturn('',1,$rs)); + } + /** + * 查看未提交和已提交凭证 + */ + public function getCertificate(){ + $m = new M(); + $rs = $m->getShopCertificate(); + exit(json_encode($rs)); + } + /** + * 获取已提交的凭证信息 + */ + public function getCertificateInfo(){ + $m = Model('common/Table'); + $m->setTable('order_shop_certificate'); + $id = (int)input('id'); + $rs = $m->getInfo(['id'=>$id,'shopId'=>(int)session('WST_USER.shopId')],'id,content,imgUrl'); + exit(jsonReturn('',1,$rs)); + } + /** + * 商家上传凭证 + */ + public function uploadCertificate(){ + $m = new M(); + $rs = $m->uploadShopCertificate(); + exit(json_encode($rs)); + } + /** + * 商家发货 + */ + public function deliver(){ + $m = new M(); + $rs = $m->deliver(); + return $rs; + } + /** + * 商家修改订单价格 + */ + // public function editOrderMoney(){ + // $m = new M(); + // $rs = $m->editOrderMoney(); + // return $rs; + // } + /** + * 商家-操作退款 + */ + public function toShopRefund(){ + return model('OrderRefunds')->getRefundMoneyByOrder((int)input('id')); + } + /** + * 商家处理是否同意退款 + */ + public function shopRefund(){ + $rs = model('OrderRefunds')->shopRefund(); + exit(json_encode($rs)) ; + } +} diff --git a/hyhproject/app/controller/Shopping.php b/hyhproject/app/controller/Shopping.php new file mode 100755 index 0000000..c9f4b9c --- /dev/null +++ b/hyhproject/app/controller/Shopping.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Shopping as M; +/** + * ============================================================================ + * 逛商铺处理类 + */ +class Shopping extends Base{ + + /** + * 获取助微吧轮播 + * @return [type] [description] + */ + public function getHelpCarousel(){ + $m = new M(); + exit(json_encode($m->getHelpCarousel())); + } + /** + * 搜索助微吧商品列表 + * @return [type] [description] + */ + public function getHelpShops(){ + $m = new M(); + exit(json_encode($m->getHelpShops())); + } + public function searchHelpGoods(){ + $m = new M(); + exit(jsonReturn($m->searchHelpGoods())); + } + + /** + * 获取逛商都/助微吧推荐商品 + * @return [type] [description] + */ + public function getGoods(){ + $m = new M(); + exit(json_encode($m->getGoods())); + // $m = Model('common/Table'); + // $m->setTable('shops'); + } + /** + * 获取逛商铺轮播 + * @return [type] [description] + */ + public function getCarousel(){ + $m = new M(); + exit(json_encode($m->getCarousel())); + } + + /** + * 获取逛商铺列表 + * @return [type] [description] + */ + public function getShops(){ + $m = new M(); + exit(json_encode($m->getShops())); + } + /** + * 获取商铺首页 + * @return [type] [description] + */ + public function getShopInfo(){ + $m = Model('shops'); + exit(json_encode($m->getShopIndex())); + // $m = Model('common/Table'); + // $m->setTable('shops'); + } + /** + * 获取店铺首页商品列表 + */ + public function getShopIndexGoodsList(){ + $m = Model('common/Shops'); + $rs = $m->getShopIndexGoodsList(0,'goodsId,goodsImg,goodsName,shopPrice,saleNum,discountRate','goodsOrder DESC,saleNum DESC,goodsId DESC'); + exit(json_encode($rs)); + } +} diff --git a/hyhproject/app/controller/Shops.php b/hyhproject/app/controller/Shops.php new file mode 100755 index 0000000..6503acd --- /dev/null +++ b/hyhproject/app/controller/Shops.php @@ -0,0 +1,646 @@ +<?php +namespace wstmart\app\controller; +use wstmart\home\model\Goods; +use wstmart\common\model\GoodsCats; +use wstmart\common\model\Table as M; +use wstmart\common\model\Shops as SM; +// use think\Loader; +/** + * ============================================================================ + * 门店控制器 + */ + +class Shops extends Base{ + // protected $beforeActionList = [ + // 'checksession', //在任何操作执行前执行checksession方法 + // 'islogin' => ['except'=>'login'], //在除login之外的其他方法执行前先执行islogin方法 + // 'removesession' => ['only'=>'logout'], //在logout执行前先执行removesession + // ]; + protected $beforeActionList = [ + 'checkAuth'=>['except'=>'pagequery'], + 'checkDataAuth'=>['only'=>'setspecs,getspecs,getspeccats,delspecset,getgoodsspeccats,addgoods,editgoods,getgoodsinfo,uploadshopimg,delgoods,delshop,shopinfo,getsellerorderlist,orderconfirm,getgoodslist,viewcertificate,userupdate,getshopimg,getbank'], + 'checkShopAuth' => ['except'=>'shopjoin,getshopjoininfo,usershoplist,pagequery'], + ]; + /** + * 获取商家入驻信息 + */ + public function getShopJoinInfo(){ + $where['userId'] = $this->getUserId(); + $where['shopId'] = (int)input('post.shopId'); + $where['dataFlag'] = 1; + $m = new M(); + $m->setTable('shops'); + $shopInfo = $m->getInfo($where,'shopName,userName,phone,provinceId,cityId,countyId,townId,villageId,shopAddress,lng,lat,bankName,accountName,bankNo,idCardFrontImg,idCardBackImg,commissionImg,businessLicenceImg,confirmationImg'); + if($shopInfo){ + exit(jsonReturn('',1,$shopInfo)); + } + exit(jsonReturn('获取失败!')); + } + /** + * 商家入驻 + */ + public function shopJoin(){ + $data = input('post.'); + $validate = \think\Loader::validate('Shops'); + if(!$validate->scene('join')->check($data)){ + exit(jsonReturn($validate->getError())); + } + $data['shopType'] = (int)input('post.shopType',1); + $data['userId'] = $this->getUserId(); + $data['status']=0; + $m = new M(); + $m->setTable('shops'); + $shopId = isset($data['shopId']) ? $data['shopId'] : 0; + if($shopId){ + //unset($data['shopId']); + $isSuccess = $m->updateInfo(['shopId'=>$shopId,'userId'=>$data['userId']],$data); + //$m->insertInfo($data); + }else{ + if($m->getField(['userId'=>$data['userId'],'shopName'=>$data['shopName'],'dataFlag'=>1],'shopId')){ + exit(jsonReturn('请不要重复提交')); + } + $data['createTime'] = time(); + $isSuccess = $m->insertInfo($data); + } + if(false !== $isSuccess){ + $userPhone = getAdminPhone(); + $tpl = WSTMsgTemplates('PHONE_ADMIN_SHOP_APPLAY_NOTICE'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$this->user['loginName']]]; + $m = Model('common/LogSms'); + $rv = $m->sendSMS(0,$userPhone,$params,'PHONE_ADMIN_SHOP_APPLAY_NOTICE',0); + } + exit(jsonReturn('提交成功,请等待系统审核',1)); + }else{ + exit(jsonReturn('操作失败,请重试')); + } + } + /** + * 商家列表 + * @return [type] [description] + */ + public function userShopList(){ + $m = new M(); + $m->setTable('shops'); + $where['userId'] = $this->getUserId(); + $where['shopType'] = (int)input('post.shopType',1); + //$where['status']=1; + $where['dataFlag']=1; + $shops = $m->getList($where,'shopId,shopName,shopImg,status'); + exit(jsonReturn('',1,$shops)); + } + /** + * 获取商家信息 + * @return [type] [description] + */ + public function shopInfo(){ + $m = new SM(); + $rs = $m->shopInfo(); + exit(json_encode($rs)); + } + /** + * 获取商家图片 + * @return [type] [description] + */ + public function getShopImg(){ + $m = new SM(); + $rs = $m->getShopImg(); + exit(json_encode($rs)); + } + + /** + * [删除店铺] + * @return [type] [description] + */ + public function delShop(){ + $shopId=(int)input('post.shopId'); + if($shopId){ + $payPwd = input('post.payPwd'); + if(md5($payPwd) != $this->user['payPwd']){ + exit(jsonReturn('密码错误')); + } + $m = new M(); + $m->setTable('shops'); + $rs = $m->updateInfo(['shopId'=>(int)$shopId,'userId'=>$this->getUserId()],['dataFlag'=>-1]); + if(false !== $rs){ + exit(jsonReturn('删除店铺成功',1)); + } + } + exit(jsonReturn('删除店铺失败')); + } + /** + * 添加规格 + * @return [type] [description] + */ + public function setSpecs(){ + $m = new SM(); + $rs = $m->setSpecs($this->getUserId()); + exit(json_encode($rs)); + } + /** + * 获名总规格名 + * @return [type] [description] + */ + public function getSpecs(){ + $m = new SM(); + $rs = $m->getSpecs(); + exit(json_encode($rs)); + } + /** + * 删除总规格名 + * @return [type] [description] + */ + public function delSpecSet(){ + $m = new M(); + $m->setTable('spec_set'); + $rs = $m->updateInfo(['id'=>(int)input('post.id'),'userId'=>$this->getUserId()],['dataFlag'=>-1]); + if(false !== $rs){ + exit(jsonReturn('删除成功!',1)); + } + exit(jsonReturn('删除失败!')); + } + /** + * 获名总规格下属性名和属性值 + */ + public function getSpecCats(){ + $m = new SM(); + $rs = $m->getSpecCats($this->getUserId()); + exit(json_encode($rs)); + } + /** + * 获名商品总规格下属性名和属性值 + */ + public function getGoodsSpecCats(){ + $m = new SM(); + $rs = $m->getGoodsSpecCats($this->getUserId()); + exit(json_encode($rs)); + } + /** + * 获名商品分类 + */ + public function getGoodsCats(){ + $pid = (int)input('post.pid'); + $m = Model('common/GoodsCats'); + $rs = $m->listQuery($pid,-1,'catId,catName'); + exit(jsonReturn('',1,$rs)); + } + /** + * 添加商品 + */ + public function addGoods(){ + $m = new SM(); + $rs = $m->addGoods(); + exit(json_encode($rs)); + } + /** + * 编辑商品 + */ + public function editGoods(){ + $m = new SM(); + $rs = $m->editGoods(); + exit(json_encode($rs)); + } + /** + * 申请商超/商厦/商都 + * @param [type] $userId [description] + * @return [type] [description] + */ + public function userUpdate(){ + $m = new SM(); + if(2 == $this->user['authType'] && 1 == $this->user['userType'] ){ + $rs = $m->userUpdate($this->getUserId()); + }else{ + $rs = WSTReturn('仅合作认证用户并开店成功后可申请'); + } + exit(json_encode($rs)); + } + /** + * 获取申请商超/商厦/商都信息 + * @param [type] $userId [description] + * @return [type] [description] + */ + public function getUserUpdate(){ + $m = new SM(); + if(2 == $this->user['authType'] && 1 == $this->user['userType'] ){ + $rs = $m->getUserUpdate($this->getUserId()); + }else{ + $rs = WSTReturn('仅合作认证用户并开店成功后可申请'.$this->user['authType']); + } + exit(json_encode($rs)); + } + public function getBank(){ + $m = new M(); + $m->setTable('shops'); + $bankInfo = $m->getInfo(['shopId'=>(int)input('post.shopId')],'bankName,accountName,bankNo'); + exit(jsonReturn('',1,$bankInfo)); + } + //商家申请提现 + public function withdrawal(){ + $rs = Model('Common/CashDraws')->drawWangByShop(); + exit(json_encode($rs)); + } + /** + * 获取商品信息 + */ + public function getGoodsInfo(){ + $m = new SM(); + $rs = $m->getGoodsInfo(); + exit(json_encode($rs)); + } + + /** + * 上传店铺主图和轮播图 + */ + public function uploadShopImg(){ + $m = new SM(); + $rs = $m->uploadShopImg(); + exit(json_encode($rs)); + } + + /** + * 获取商品列表 + */ + public function getGoodsList(){ + $m = new SM(); + $rs = $m->getGoodsList(); + exit(json_encode($rs)); + } + /** + * 获取店铺首页商品列表 + */ + public function getShopIndexGoodsList(){ + $m = new SM(); + $rs = $m->getShopIndexGoodsList(0,'goodsImg,goodsName,shopPrice,saleNum','goodsOrder DESC,saleNum DESC'); + exit(json_encode($rs)); + } + + /** + * 删除商品 + */ + public function delGoods(){ + $goodsId = (int)input('post.goodsId/d'); + if($goodsId){ + $m = new M(); + $m->setTable('goods'); + if(false !== $m->updateInfo(['goodsId'=>$goodsId],['dataFlag'=>-1])){ + exit(jsonReturn('删除成功',1)); + } + + } + exit(jsonReturn('删除失败')); + } + + + /** + * 店铺公告页 + */ + public function notice(){ + $notice = model('shops')->getNotice(); + $this->assign('notice',$notice); + return $this->fetch('shops/shops/notice'); + } + /** + * 修改店铺公告 + */ + public function editNotice(){ + $s = model('shops'); + return $s->editNotice(); + } + /** + * 商家登录 + */ + public function login(){ + $USER = session('WST_USER'); + if(!empty($USER) && isset($USER['shopId'])){ + $this->redirect("shops/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('shop_login'); + } + /** + * 商家中心 + */ + public function index(){ + session('WST_MENID1',null); + session('WST_MENUID31',null); + $s = model('shops'); + $data = $s->getShopSummary((int)session('WST_USER.shopId')); + $this->assign('data',$data); + return $this->fetch('shops/index'); + } + /** + * 店铺列表 + */ + public function pageQuery(){ + $m = model('shops'); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['shopImg'] = WSTImg($v['shopImg'],3); + } + exit(jsonReturn('',1,$rs)); + } + /** + * 店铺街 + */ + public function shopStreet(){ + $g = new GoodsCats(); + $goodsCats = $g->listQuery(0); + $this->assign('goodscats',$goodsCats); + //店铺街列表 + $s = model('shops'); + $pagesize = 10; + $selectedId = input("get.id/d"); + $this->assign('selectedId',$selectedId); + $list = $s->pageQuery($pagesize); + $this->assign('list',$list); + $this->assign('keyword',input('keyword')); + $this->assign('keytype',1); + return $this->fetch('shop_street'); + } + /** + * 店铺详情 + */ + public function home(){ + $shopId = (int)input("param.shopId/d"); + hook("homeBeforeGoShopHome",["shopId"=>$shopId]); + hook("goShopAfterAddView",["shopId"=>$shopId,'path'=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo($shopId); + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(1778 != $shopId && !empty($this->is_icp)) return $this->fetch('error_lost'); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect(Url('home/shops/selfShop'),$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + //dump($data['list']);die; + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + return $this->fetch('shop_home'); + } + + /** + * 店铺分类 + */ + public function cat(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d"); + $data['shop'] = $s->getShopInfo($shopId); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect('shops/selfShop',$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + return $this->fetch('shop_home'); + } + + /** + * 查看店铺设置 + */ + public function info(){ + $s = model('shops'); + $object = $s->getByView((int)session('WST_USER.shopId')); + $bankList= model('banks')->listQuery(); + $this->assign('bankList',$bankList); + $this->assign('object',$object); + return $this->fetch('shops/shops/view'); + } + /** + * 自营店铺 + */ + public function selfShop(){ + hook("homeBeforeGoSelfShop",["shopId"=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo(1); + if(empty($data['shop']))return $this->fetch('error_lost'); + $this->assign('selfShop',1); + $data['shopcats'] = model('ShopCats')->getShopCats(1); + $this->assign('goodsName',urldecode(input("param.goodsName")));//搜索 + // 店长推荐 + $data['rec'] = $s->getRecGoods('rec',6); + // 热销商品 + $data['hot'] = $s->getRecGoods('hot',6); + $this->assign('data',$data); + return $this->fetch('self_shop'); + } + + /** + * 编辑店铺资料 + */ + public function editInfo(){ + + $rs = model('shops')->editInfo(); + return $rs; + } + + /** + * 获取店铺金额 + */ + public function getShopMoney(){ + $rs = model('shops')->getFieldsById((int)session('WST_USER.shopId'),'shopMoney,lockMoney,rechargeMoney'); + $urs = model('users')->getFieldsById((int)session('WST_USER.userId'),'payPwd'); + $rs['isSetPayPwd'] = ($urs['payPwd']=='')?0:1; + $rs['isDraw'] = ((float)WSTConf('CONF.drawCashShopLimit')<=$rs['shopMoney'])?1:0; + unset($urs); + return WSTReturn('',1,$rs); + } + + + /** + * 跳去商家入驻 + */ + public function join(){ + $rs = model('shops')->checkApply(); + $this->assign('isApply',(!empty($rs) && $rs['applyStatus']>=1)?1:0); + $this->assign('applyStep',empty($rs)?1:$rs['applyStep']); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['105']))$articles['105']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['106']))$articles['106']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['107']))$articles['107']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['108']))$articles['108']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join'); + } + + public function joinStep1(){ + session('apply_step',1); + $rs = model('shops')->checkApply(); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['109']))$articles['109']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join_step1'); + } + public function joinStep2(){ + $step = (int)session('apply_step'); + if($step<1){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',2); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step2'); + } + public function saveStep2(){ + $step = (int)session('apply_step'); + if($step<2){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = \think\Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep1')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep2($data); + } + } + public function joinStep3(){ + $step = (int)session('apply_step'); + if($step<2){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',3); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step3'); + } + public function saveStep3(){ + $step = (int)session('apply_step'); + if($step<3){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = \think\Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep2')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep3($data); + } + } + public function joinStep4(){ + $step = (int)session('apply_step'); + if($step<3){ + $this->redirect(Url('home/shops/joinStep4')); + exit(); + } + session('apply_step',4); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $banks = model('banks')->listQuery(); + $this->assign('bankList',$banks); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step4'); + } + public function saveStep4(){ + $step = (int)session('apply_step'); + if($step<4){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = \think\Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep3')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep4($data); + } + } + public function joinStep5(){ + $step = (int)session('apply_step'); + if($step<4){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',5); + $shopLicense=db('shop_license')->alias('a') + ->join('shops b','b.shopId= a.shopId') + ->where('b.userId',(int)session("WST_USER.userId"))->find(); + $this->assign('shopLicense',$shopLicense); + $goodsCatList = model('goodsCats')->listQuery(0); + $this->assign('goodsCatList',$goodsCatList); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step5'); + } + public function saveStep5(){ + $step = (int)session('apply_step'); + if($step<5){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = think\Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep4')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep5($data); + } + } + public function joinSuccess(){ + $step = (int)session('apply_step'); + if($step<5){ + $this->redirect(Url('home/shops/joinStep1')); + } + session('apply_step',5); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + /** + * 入驻进度查询 + */ + public function checkapplystatus(){ + $apply = model('shops')->getShopApply(); + if(empty($apply)){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + }else{ + if($apply['applyStatus']==0){ + session('apply_step',$apply['applyStep']); + $this->redirect(Url('home/shops/joinStep'.$apply['applyStep'])); + exit(); + }else{ + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + } + } +} diff --git a/hyhproject/app/controller/Switchs.php b/hyhproject/app/controller/Switchs.php new file mode 100755 index 0000000..e8c1aa3 --- /dev/null +++ b/hyhproject/app/controller/Switchs.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\app\controller; +/** + * ============================================================================ + * 关闭提示处理控制器 + */ +use think\Controller; +class Switchs extends Controller{ + public function __construct(){ + parent::__construct(); + WSTConf('CONF',WSTConfig()); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPcStyleId')); + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wstappStyle')?WSTConf('CONF.wstappStyle'):'default'; + $replace['__APP__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/wstmart/app/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + } + public function index(){ + return $this->fetch('error_switch'); + } +} diff --git a/hyhproject/app/controller/Tag.php b/hyhproject/app/controller/Tag.php new file mode 100755 index 0000000..962ea76 --- /dev/null +++ b/hyhproject/app/controller/Tag.php @@ -0,0 +1,13 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Tag as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Tag extends Base{ + public function articleDetail(){ + $m = new M(); + exit(json_encode($m->articleDetail())); + } +} diff --git a/hyhproject/app/controller/Tags.php b/hyhproject/app/controller/Tags.php new file mode 100755 index 0000000..6f3d52a --- /dev/null +++ b/hyhproject/app/controller/Tags.php @@ -0,0 +1,13 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Tags as M; +/** + * ============================================================================ + * 标签业务处理类 + */ +class Tags extends Base{ + public function articleDetail(){ + $m = new M(); + exit(json_encode($m->articleDetail())); + } +} diff --git a/hyhproject/app/controller/Tmp.php b/hyhproject/app/controller/Tmp.php new file mode 100755 index 0000000..92ed58b --- /dev/null +++ b/hyhproject/app/controller/Tmp.php @@ -0,0 +1,14 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Aliyunoss as M; +use think\Db; +/** + * ============================================================================ + * 地区控制器 + */ +class Tmp extends Base{ + public function index(){ + $m = new M(); + dump($m->getInfo('upload/goods/2018-03/5ab477676fccc.jpg')); + } +} diff --git a/hyhproject/app/controller/Unionpays.php b/hyhproject/app/controller/Unionpays.php new file mode 100755 index 0000000..da89272 --- /dev/null +++ b/hyhproject/app/controller/Unionpays.php @@ -0,0 +1,211 @@ +<?php +namespace wstmart\app\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 银联支付控制器 + */ +class Unionpays extends Base{ + + /** + * 初始化 + */ + private $unionConfig; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('unionpay.sdk.acp_service'); + $m = new M(); + $this->unionConfig = $m->getPayment("unionpays"); + + $config = array(); + $config["signCertPwd"] = $this->unionConfig["unionSignCertPwd"];//"000000" + $config["signMethod"] = "01"; + + $config["frontUrl"] = url("app/orders/index","",true,true); + $config["backUrl"] = url("app/unionpays/notify","",true,true); + new \SDKConfig($config); + } + + + public function getUnionpaysUrl(){ + $m = new OM(); + $payObj = input("payObj/s"); + $data = array(); + if($payObj=="recharge"){ + $needPay = input("needPay/d"); + $data["status"] = $needPay>0?1:-1; + }else{ + $userId = (int)session('WST_USER.userId'); + $data = $m->checkOrderPay(); + } + return $data; + } + + /** + * 生成支付代码 + * @param array $order 订单信息 + * @param array $config_value 支付方式信息 + */ + public function toUnionpay(){ + + $payObj = input("payObj/s"); + $m = new OM(); + $obj = array(); + $data = array(); + $orderAmount = 0; + $orderId = ""; + $extra_param = ""; + if($payObj=="recharge"){//充值 + $orderAmount = input("needPay/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $data["status"] = $orderAmount>0?1:-1; + $orderId = WSTOrderNo(); + $extra_param = $payObj."|".$targetId."|".$targetType; + + }else{ + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $data = $m->checkOrderPay($obj); + if($data["status"]==1){ + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $order = $m->getPayOrders($obj); + $orderAmount = $order["needPay"]; + $payRand = $order["payRand"]; + $orderId = $obj["orderNo"]."a".$payRand; + $extra_param = $payObj."|".$userId."|".$obj["isBatch"]; + } + } + + if($data["status"]==1){ + $params = array( + //以下信息非特殊情况不需要改动 + 'version' => \SDKConfig::$version, //版本号 + 'encoding' => 'utf-8', //编码方式 + 'txnType' => '01', //交易类型 + 'txnSubType' => '01', //交易子类 + 'bizType' => '000201', //业务类型 + 'frontUrl' => \SDKConfig::$frontUrl, //前台通知地址 + 'backUrl' => \SDKConfig::$backUrl, //后台通知地址 + 'signMethod' => \SDKConfig::$signMethod,//签名方法 + 'channelType' => '08', //渠道类型,07-PC,08-手机 + 'accessType' => '0', //接入类型 + 'currencyCode' => '156', //交易币种,境内商户固定156 + //TODO 以下信息需要填写 + 'merId' => $this->unionConfig["unionMerId"], //"777290058110048",//商户代码 + 'orderId' => $orderId, //商户订单号,8-32位数字字母,不能含“-”或“_” + 'txnTime' => date('YmdHis'), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间 + 'txnAmt' => $orderAmount*100, //交易金额,单位分,此处默认取demo演示页面传递的参数 + // 订单超时时间。 + //'payTimeout' => date('YmdHis', strtotime('+15 minutes')), + + 'reqReserved' => $extra_param, + ); + $acpService = new \AcpService(); + $acpService::sign ( $params ); + $uri = \SDKConfig::$frontTransUrl; + $html_form = $acpService::createAutoFormHtml( $params, $uri ); + echo $html_form; + }else{ + + } + } + + /** + * 异步回调接口 + */ + public function notify(){ + + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){//验证成功 + $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + // 解释: 交易成功且结束,即不可再做任何操作。 + if($_POST['respMsg'] == 'Success!'){ + $m = new OM(); + $extras = explode("|",$_POST['reqReserved']); + $rs = array(); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $obj = array (); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $_POST["out_trade_no"];; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["total_fee"] = $_POST['total_fee']; + $obj["payFrom"] = 'unionpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //商户订单号 + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $tradeNo[0]; + $obj["total_fee"] = $_POST['total_fee']; + + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = 'unionpays'; + //支付成功业务逻辑 + $rs = $m->complatePay($obj); + } + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + } + }else{ + echo "fail"; //验证失败 + } + } + + /** + * 同步回调接口 + */ + public function response(){ + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){ //验证成功 + $order_sn = $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + $respMsg = $_POST['respMsg']; //交易状态 + + if($_POST['respMsg'] == 'success'){ + $m = new OM(); + $extras = explode("|",$_POST['extra_param']); + if($extras[0]=="recharge"){//充值 + $this->redirect(url("app/users/index")); + }else{ + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["orderNo"] = $tradeNo[0]; + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $rs = $m->getOrderType($obj); + $this->redirect(url("app/orders/index")); + } + }else { + $this->error('支付失败'); + } + }else { + $this->error('支付失败'); + } + } + +} diff --git a/hyhproject/app/controller/Useraddress.php b/hyhproject/app/controller/Useraddress.php new file mode 100755 index 0000000..2b38b5d --- /dev/null +++ b/hyhproject/app/controller/Useraddress.php @@ -0,0 +1,66 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\UserAddress as M; +/** + * 用户地址控制器 + */ +class UserAddress extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 获取地址信息 + */ + public function getList(){ + $m = new M(); + $userId = session('WST_USER.userId'); + $data['addressList'] = $m->listQuery($userId); + //获取省级地区信息 + //$data['area'] = model('app/Areas')->listQuery(0); + exit(jsonReturn('',1,$data)); + //$this->assign('type', (int)input('type')); + //$this->assign('addressId', (int)input('addressId'));//结算选中的地址 + + } + /** + * 获取地址信息 + */ + public function getById(){ + $m = new M(); + $data = $m->getById(input('post.addressId/d')); + exit(jsonReturn('',1,$data)); + } + public function getArea(){ + //获取省级地区信息 + $data['area'] = model('app/Areas')->listQuery(0); + exit(jsonReturn('',1,$data)); + } + + /** + * 设置为默认地址 + */ + public function setDefault(){ + $m = new M(); + exit(json_encode($m->setDefault())); + } + /** + * 新增/编辑地址 + */ + public function edits(){ + $m = new M(); + if(input('post.addressId/d')){ + $rs = $m->edit(); + }else{ + $rs = $m->add(); + } + exit(json_encode($rs)); + } + /** + * 删除地址 + */ + public function del(){ + $m = new M(); + exit(json_encode($m->del())); + } +} diff --git a/hyhproject/app/controller/Users.php b/hyhproject/app/controller/Users.php new file mode 100755 index 0000000..28553d0 --- /dev/null +++ b/hyhproject/app/controller/Users.php @@ -0,0 +1,841 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Users as M; +use wstmart\app\model\Favorites; +use wstmart\app\model\Messages; +use wstmart\common\model\LogSms; +use wstmart\common\model\Users as MUsers; +use wstmart\common\model\UserTrees; +use think\Collection; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'checklogin,login,check_login_name,get_puser_info,register,getverify,toregister,forgetpass,forgetpasst,forgetpasss,forgetpassf,findpass,getfindphone,resetpass,getphoneverifycode,checkuserphone']// 访问这些except下的方法不需要执行前置操作 + ]; + /** + * 我的亲人投资列表 + * @return [type] [description] + */ + public function familyInvestmentList(){ + //if(0 == $this->user['authType'])exit(jsonReturn('请先实名认证')); + $m = Model('common/Table'); + + $userId = $this->getUserId(); + $list = db('auth_company_partner p') + ->join('__AUTH_FAMILY_PERSONAL__ f','f.familyId=p.partnerId') + ->join('__AUTH_COMPANY__ c','c.userId=p.userId') + ->where(['f.userId'=>$userId,'p.dataFlag'=>1,'c.status'=>1]) + ->field('c.userId,c.companyName,c.headImg,c.companyAddress,c.createTime,p.positionName,p.stake') + ->select(); + //->paginate(input('pageSize/d',10))->toArray(); + $m->setTable('auth_company_partner'); + foreach ($list as &$v) { + $v['headImg'] = WSTImg($v['headImg'],3); + $v['count'] = $m->getCount(['userId'=>$v['userId'],'dataFlag'=>1],'id'); + } + exit(jsonReturn('',1,$list)); + } + //合作认证详细信息 + public function investmentInfo(){ + $userId = input('userId'); + $m = Model('common/Table'); + $m->setTable('auth_company_partner'); + $list = $m->getList(['userId'=>$userId,'dataFlag'=>1],'uName,positionName,businessImg,stake,createTime'); + exit(jsonReturn('',1,$list)); + } + /** + * 获取合作券值 + * @return [type] [description] + */ + public function getInvestmentMoney(){ + $userId = input('userId'); + $field = 'productNum,couponsNum'; + $m = Model('common/Table'); + $m->setTable('users'); + $info = $m->getInfo(['userId'=>$userId],$field); + exit(jsonReturn('',1,$info)); + + } + /** + * 分配券值 + * @return [type] [description] + */ + public function distributionInvestmentMoney(){ + $m = new MUsers(); + $rs = $m->distributionInvestmentMoney(); + exit(json_encode($rs)); + } + + /** + * 检测会员名 + */ + public function check_login_name(){ + $loginName = input('post.loginName'); + if(strlen($loginName) < 6 ){ + exit(jsonReturn('用户名不能小于6个字符!')); + } + exit(json_encode(WSTCheckLoginKey($loginName))); + } + /** + * 获取券值 + * @return [type] [description] + */ + public function getMoney(){ + $type = (int)input('post.type'); + $typeName = ['0'=>'productNum,couponsNum,wangNum','1'=>'productNum','2'=>'couponsNum','3'=>'wangNum']; + if(array_key_exists($type, $typeName)){ + $m = Model('common/Table'); + $m->setTable('users'); + $info = $m->getInfo(['userId'=>$this->getUserId()],$typeName[$type]); + exit(jsonReturn('',1,$info)); + } + + } + /** + * 获取推荐人信息 + */ + public function get_puser_info(){ + $pName = trim(input('post.pName')); + $pInfo = getUserInfo(['loginName|userPhone'=>$pName],'loginName,userPhone'); + if($pInfo){ + exit(jsonReturn('',1,$pInfo)); + } + exit(jsonReturn('未找到推荐信息'.$pName)); + } + /** + * 我家朋友 + */ + public function myFriend(){ + $m = new MUsers(); + $userId = $this->getUserId(); + $rs = $m->myFriend($userId); + $rs['user'] = ['userId'=>$userId,'loginName'=>$this->user['loginName']]; + $rs['share_url'] = 'http://t.ect99.com/mobile/reg/reg.html?pName='.$this->user['loginName']; + exit(jsonReturn('',1,$rs)); + } + /** + * 我家朋友列表 + */ + public function myFriendList(){ + $m = new MUsers(); + $userId = $this->getUserId(); + $rs = $m->myFriendList($userId); + exit(jsonReturn('',1,$rs)); + } + + /** + * 会员登录 + */ + public function checkLogin(){ + $m = new M(); + $rs = $m->checkLogin(3); + $rs['url'] = session('WST_MO_WlADDRESS'); + exit(json_encode($rs)); + } + public function get_name_and_money(){ + $data['name'] = session('WST_USER.loginName'); + $data['money'] = session('WST_USER.userMoney'); + $data['userECT'] = session('WST_USER.userECT'); + exit(jsonReturn('',1,$data)); + } + /** + * 会员注册 + */ + public function register(){ + $m = new M(); + $rs = $m->regist(3); + $rs['url'] = session('WST_MO_WlADDRESS'); + exit(json_encode($rs)); + } + /** + * 手机号码是否存在 + */ + public function checkUserPhone(){ + $userPhone = input("post.userPhone"); + $m = new M(); + $rs = $m->checkUserPhone($userPhone,$this->getUserId()); + if($rs["status"]!=1){ + exit(jsonReturn("手机号已注册",-1)); + }else{ + exit(jsonReturn("",1)); + } + } + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + exit(jsonReturn("手机号格式不正确!")); + } + $m = new M(); + $rs = $m->checkUserPhone($userPhone,0,'loginName'); + //是否是推荐人注册 0不是,1是 + if(0 == WSTConf('CONF.referrerOpen')){ + if($rs["status"]!=1){ + exit(jsonReturn("手机号已存在!")); + }else{ + $phoneVerify = rand(1000,9999); + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + } + }else{ + if($rs["status"]==1){ + exit(jsonReturn("手机号不存在!")); + }else{ + $phoneVerify = rand(1000,9999); + $tpl = WSTMsgTemplates('PHONE_PUSER_REGISTER_VERFIY'); + } + } + $rv['status'] = -1; + $rv['msg'] = '发送失败'; + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['name'=>$rs['data']['loginName'],'code'=>$phoneVerify]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyCode',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + exit(json_encode($rv)); + } + /** + * 会员中心 + */ + public function index(){ + $userId = $this->getUserId(); + $m = new M(); + $user = $m->getById($userId); + if($user['userName']=='') + $user['userName']=$user['loginName']; + $this->assign('user', $user); + + //商城未读消息的数量 及 各订单状态数量 + $data = model('index')->getSysMsg('msg','order'); + $this->assign('data',$data); + return $this->fetch('users/index'); + } + /** + * 会员中心 + */ + public function getIndex(){ + $userId = $this->getUserId(); + $m = Model('common/Table'); + $m->setTable('user_vouchers_summary'); + $data = $m->getInfo(['userId'=>$userId],'expectedProductNum,expectedCouponsNum'); + $m->setTable('shops'); + $shopIds = $m->getColumn(['status'=>1,'userId'=>$userId],'shopId'); + if($shopIds){ + $m->setTable('orders'); + $data['expectedWangNum'] = $m->getField(['shopId'=>['in',$shopIds],'orderStatus'=>['BETWEEN','0,1']],'SUM((productNum - productHandlingFee - productTaxFee) + (couponsNum - couponsHandlingFee - couponsTaxFee) + wangNum)');//预获旺旺券 + }else{ + $data['expectedWangNum'] = 0;//预获旺旺券 + } + $data['expectedProductNum'] = isset($data['expectedProductNum']) ? $data['expectedProductNum'] : 0; + $data['expectedCouponsNum'] = isset($data['expectedCouponsNum']) ? $data['expectedCouponsNum'] : 0; + $data['user'] = getUserInfo(['userId'=>$userId],'userId,loginName,userType,userName,trueName,userPhone,userPhoto,userStatus,token,userLevel,authType,couponsNum,productNum,wangNum'); + if(1 == $this->user['authType']){ + $m->setTable('auth_personal'); + $data['user']['userPhoto'] = $m->getField(['userId'=>$userId,'status'=>1],'headImg'); + }elseif(2 == $this->user['authType']){ + $m->setTable('auth_company`'); + $data['user']['userPhoto'] = $m->getField(['userId'=>$userId,'status'=>1],'headImg'); + } + //$data['favoritesNum'] = $this->getFavoritesNum(0); + //商城未读消息的数量 及 各订单状态数量 + //$data['sysMsg'] = $this->getSysMsg(0); + + exit(jsonReturn("",1,$data)); + } + /** + * 设置点赞记数 + */ + public function setRewardLike(){ + $rewardId = (int)input("param.rewardId/d",0); + $isLike = (int)input("param.isLike/d",0); + if($rewardId){ + $s = model('shops'); + $s->setRewardLike($rewardId,$this->getUserId(),$isLike); + exit(jsonReturn('',1)); + } + exit(jsonReturn('设置失败')); + } + /** + * 商城未读消息的数量 及 各订单状态数量 + * @param integer $returnJson [1代表返回json数据,其他代表返回数组] + */ + public function getSysMsg($returnJson = 1){ + $data = model('index')->getSysMsg('msg','order'); + if($returnJson == 1){ + exit(jsonReturn("",1,$data)); + }else{ + return $data; + } + } + /** + * 商城未读消息的数量 + * @param integer $returnJson [1代表返回json数据,其他代表返回数组] + */ + public function getMsgNum($returnJson = 1){ + $data = model('index')->getSysMsg('msg'); + if($returnJson == 1){ + exit(jsonReturn("",1,$data)); + }else{ + return $data; + } + } + /** + * 商城各订单状态数量 + * @param integer $returnJson [1代表返回json数据,其他代表返回数组] + */ + public function getOrderNum($returnJson = 1){ + $data = model('index')->getSysMsg('','order'); + if($returnJson == 1){ + exit(jsonReturn("",1,$data)); + }else{ + return $data; + } + } + /** + * 获取会员信息 + * @param integer $returnJson [1代表返回json数据,其他代表返回数组] + */ + public function getUserInfo($returnJson = 1){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getUserInfo($userId,'*'); + // $where = []; + // $where['cr.userId'] = $this->getUserId(); + // $where['cr.isUse'] = 0; + // $now=time(); + // // $where['ck.begin_time']=array('lt',$now); + // $where['ck.end_time']=array('gt',$now); + + // $user['couponNum'] = db('coupon_record')->alias('cr') + // ->join('__COUPON_KIND__ ck','cr.couponId=ck.Id','inner') + // ->where($where) + // ->count(); + + if($returnJson == 1){ + exit(jsonReturn("",1,$user)); + }else{ + return $user; + } + } + /** + * 获取会员关注商品数和关注商家数 + * @param integer $returnJson [description] + * @return [type] [description] + */ + public function getFavoritesNum($returnJson = 1){ + $m = new Favorites(); + $data = $m->getFavoritesNum($this->getUserId()); + $data['shareNum'] = (int)model('UserTrees')->getShareNum(['pid'=>$this->getUserId()]); + if($returnJson == 1){ + exit(jsonReturn("",1,$data)); + }else{ + return $data; + } + } + /** + * 个人信息 + */ + public function edit(){ + $userId = $this->getUserId(); + $m = new M(); + $user = $m->getById($userId); + exit(jsonReturn('',1,$user)); + //$this->assign('user', $user); + //return $this->fetch('users/edit'); + } + /** + * 编辑个人信息 + */ + public function editUserInfo(){ + $m = new M(); + return $m->edit(); + } + /** + * 账户安全 + */ + public function security(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $userPhone = $user['userPhone']; + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $user['payPwd'] = empty($payPwd)?0:1; + $user['userPhone'] = empty($userPhone)?0:1; + //$this->assign('user', $user); + session('Edit_userPhone_Time', null); + exit(jsonReturn('',1,$user)); + //return $this->fetch('users/security/index'); + } + /** + * 修改登录密码 + */ + public function editLoginPass(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + exit(jsonReturn('',1,$user)); + // $this->assign('user', $user); + // return $this->fetch('users/security/user_login_pass'); + } + public function editloginPwd(){ + $m = new M(); + $userId = $this->getUserId(); + return $m->editPass($userId); + } + /** + * 修改支付密码 + */ + public function editPayPass(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $user['payPwd'] = empty($payPwd)?0:1; + exit(jsonReturn('',1,$user)); + //$this->assign('user', $user); + //return $this->fetch('users/security/user_pay_pass'); + } + public function editpayPwd(){ + $m = new M(); + $userId = $this->getUserId(); + exit(json_encode($m->editPayPass($userId))); + } + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $user['backType'] = ($backType==1 && time()<floatval($timeVerify)+10*60)?1:0; + exit(jsonReturn('',1,$user)); + //$this->assign('user', $user); + //return $this->fetch('users/security/user_back_paypwd'); + } + /** + * 忘记支付密码:发送短信 + */ + public function backpayCode(){ + $m = new MUsers(); + $data = $m->getById($this->getUserId()); + $userPhone = $data['userPhone']; + $phoneVerify = rand(1000,9999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['code'=>$phoneVerify]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + exit(jsonReturn('短信发送成功!',1)); + } + exit(json_encode($rv)); + } + /** + * 忘记支付密码:验证短信 + */ + public function verifybackPay(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + exit(jsonReturn("校验码已失效,请重新发送!")); + } + if($phoneVerify==session('Verify_backPaypwd_info.phoneVerify')){ + session('Type_backPaypwd',1); + exit(jsonReturn("验证成功",1)); + } + exit(jsonReturn("校验码不一致,请重新输入!")); + } + /** + * 忘记支付密码:重置密码 + */ + public function resetbackPay(){ + $m = new M(); + exit(json_encode($m->resetbackPay())); + } + /** + * 修改手机 + */ + public function editPhone(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + //$this->assign('user', $user); + session('Edit_userPhone_Time', null); + exit(jsonReturn('',1,$user)); + //return $this->fetch('users/security/user_phone'); + } + /** + * 绑定手机:发送短信验证码 + */ + public function sendCodeTie(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return jsonReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,$this->getUserId()); + if($rs["status"]!=1){ + return jsonReturn("手机号已存在!"); + exit(); + } + $data = $m->getById($this->getUserId()); + $phoneVerify = rand(1000,9999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'sendCodeTie',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return jsonReturn('短信发送成功!',1); + } + exit(json_encode($rv)); + } + /** + * 绑定手机 + */ + public function phoneEdit(){ + $phoneVerify = input("post.phoneCode"); + $process = input("post.process"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return jsonReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new M(); + $rs = $m->editPhone($this->getUserId(),session('Verify_info.userPhone')); + exit(json_encode($rs)); + } + return jsonReturn("校验码不一致,请重新输入!"); + } + /** + * 修改手机:发送短信验证码 + */ + public function sendCodeEdit(){ + $m = new MUsers(); + $data = $m->getById($this->getUserId()); + $userPhone = $data['userPhone']; + $phoneVerify = rand(1000,9999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + exit(jsonReturn('短信发送成功!',1)); + } + exit(json_encode($rv)); +} + /** + * 修改手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return jsonReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + session('Edit_userPhone_Time',time()); + exit(jsonReturn("验证成功",1)); + } + exit(jsonReturn("校验码不一致,请重新输入!",-1)); + } + public function editPhoneo(){ + $m = new M(); + $userId = $this->getUserId(); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $timeVerify = session('Edit_userPhone_Time'); + if(time()>floatval($timeVerify)+15*60){ + $user['phoneType'] = 1; + }else{ + $user['phoneType'] = 0; + } + $this->assign('user', $user); + return $this->fetch('users/security/user_phone'); + } + /** + * 用户退出 + */ + public function logout(){ + model('users')->appLogOut($this->getUserId()); + return jsonReturn("",1); + } + + /************************************************* 忘记密码 ********************************************************/ + // 页面过期/失效 + protected function expire($msg=''){ + $message = $msg?$msg:'页面已失效!'; + return jsonReturn($message,-1); + //$html = '<h1>'.$message.'</h1><script>setTimeout(function(){location.href="'.url('app/users/index','','',true).'";},1000)</script>'; + //return $this->display($html); + } + /** + * 忘记密码 + */ + public function forgetPass(){ + return $this->fetch('forget_pass'); + } + public function forgetPasst(){ + if(time()<floatval(session('findPass.findTime'))+30*60){ + $userId = session('findPass.userId'); + $m = new M(); + $info = $m->getUserInfo($userId,'loginName,userPhone'); + if($info['userPhone']!='')$info['userPhone'] = WSTStrReplace($info['userPhone'],'*',3); + //if($info['userEmail']!='')$info['userEmail'] = WSTStrReplace($info['userEmail'],'*',2,'@'); + exit(jsonReturn('',1,$info)); + }else{ + exit($this->expire()); + } + } + + /** + * 重置密码 + */ + public function resetPass(){ + if(!session('findPass')){ + exit($this->expire()); + } + return $this->fetch('forget_pass3'); +} +public function forgetPasss(){ + if(!session('findPass')){ + exit($this->expire()); + } + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->expire('请在同一浏览器操作!'); + } + $uId = session('findPass.userId'); + $key = session("findPass.key"); + // 验证邮箱中的验证码 + $secretCode = input('secretCode'); + if($key==$secretCode){ + session('REST_userId',$uId); + session('REST_success','1'); + return jsonReturn('验证成功',1); +}else{ + return jsonReturn('校验码错误',-1); +} + +} + /** + * 找回密码 + */ + public function findPass(){ + //禁止缓存 + header('Cache-Control:no-cache,must-revalidate'); + header('Pragma:no-cache'); + //$code = input("post.verifyCode"); + $step = input("post.step/d"); + switch ($step) { + case 1:#第一步,验证身份 + // if(!WSTVerifyCheck($code)){ + // return jsonReturn('验证码错误!',-1); + // } + $loginName = input("post.loginName"); + $rs = WSTCheckLoginKey($loginName); + if($rs["status"]==1){ + return jsonReturn("用户名不存在!"); + exit(); + } + $m = new M(); + $info = $m->checkAndGetLoginInfo($loginName); + if ($info != false) { + session('findPass',array('userId'=>$info['userId'],'loginName'=>$loginName,'userPhone'=>$info['userPhone'],'userEmail'=>$info['userEmail'],'loginSecret'=>$info['loginSecret'],'findTime'=>time())); + return jsonReturn("操作成功",1); + }else return jsonReturn("用户名不存在!"); + break; + case 2:#第二步,验证方式 + if (session('findPass.loginName') != null ){ + if(input("post.modes")==1){ + if ( session('findPass.userPhone') == null) { + return jsonReturn('Error-10002:你没有预留手机号码,请联系客服找回密码!',-1); + } + $phoneVerify = input("post.Checkcode"); + if(!$phoneVerify){ + return jsonReturn('校验码不能为空!',-1); + } + return $this->checkfindPhone($phoneVerify); + }else{ + if (session('findPass.userEmail')==null) { + return jsonReturn('你没有预留邮箱,请通过联系客服找回密码!',-1); + } + if(!WSTVerifyCheck($code)){ + return jsonReturn('验证码错误!',-1); + } + return $this->getfindEmail(); + } + }else exit($this->expire()); + break; + case 3:#第三步,设置新密码 + $resetPass = session('REST_success'); + if($resetPass != 1)exit($this->expire()); + $loginPwd = input("post.loginPwd"); + $repassword = input("post.repassword"); + $decrypt_data = WSTRSA($loginPwd); + $decrypt_data2 = WSTRSA($repassword); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $loginPwd = $decrypt_data['data']; + $repassword = $decrypt_data2['data']; + }else{ + return jsonReturn('设置失败'); + } + if ($loginPwd == $repassword) { + $m = new M(); + $rs = $m->resetPass(); + if($rs['status']==1){ + exit(json_encode($rs)); + }else{ + exit(json_encode($rs)); + } + }else return jsonReturn('两次密码不同!',-1); + break; + default: + exit($this->expire()); + break; + } +} + /** + * 手机验证码获取 + */ + public function getfindPhone(){ + session('WST_USER',session('findPass.userId')); + if(session('findPass.userPhone')==''){ + return jsonReturn('Error-10001:你没有预留手机号码,请联系客服找回密码!',-1); + } + $phoneVerify = rand(1000,9999); + session('WST_USER',null); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['code'=>$phoneVerify]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,session('findPass.userPhone'),$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + // 记录发送短信的时间,用于验证是否过期 + session('REST_Time',time()); + $USER = ''; + $USER['phoneVerify'] = $phoneVerify; + $USER['time'] = time(); + session('findPhone',$USER); + exit(jsonReturn('短信发送成功!',1)); + } + exit(json_encode($rv)); + } + /** + * 手机验证码检测 + * -1 错误,1正确 + */ + public function checkfindPhone($phoneVerify){ + if(!session('findPhone.phoneVerify') || time()>floatval(session('findPhone.time'))+10*60){ + return jsonReturn("校验码已失效,请重新发送!"); + exit(); + } + if (session('findPhone.phoneVerify') == $phoneVerify ) { + $fuserId = session('findPass.userId'); + if(!empty($fuserId)){ + session('REST_userId',$fuserId); + session('REST_success','1'); + $rs['status'] = 1; + $rs['url'] = url('app/users/resetPass'); + exit(json_encode($rs)); + } + return jsonReturn('无效用户',-1); + } + return jsonReturn('校验码错误!',-1); + } + /** + * 发送验证邮件/找回密码 + */ + public function getfindEmail(){ + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('findPass.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail(session('findPass.userEmail'),'密码重置',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + $uId = session('findPass.userId'); + session("findPass.key", $code); + // 发起重置密码的时间; + session('REST_Time',time()); + return jsonReturn("发送成功",1); + }else{ + return jsonReturn($sendRs['msg'],-1); + } + } + /** 获取分享信息 mark cheng 20180320*/ + public function get_share(){ + $name = session('WST_USER.loginName'); + $data['url'] = 'http://www.juzi199.com/mobile/users/reg?pName='.$name; + $data['bg_share'] = 'upload/sysconfigs/share_3.png'; + $data['title'] = '新会员注册,即送388元红包,10个ECT,马上注册吧!'; + $data['desc'] = '新会员注册,即送388元红包,10个ECT,马上注册吧!'; + exit(jsonReturn('',1,$data)); + } + /*获取用户分享列表*/ + public function getShareList(){ + $m = new M(); + return $m->getShareList(); + } + /** + * 获取用户分享信息 * + */ + public function getShareInfo(){ + $m = new MUsers(); + return $m->getShareInfo(); + } +} diff --git a/hyhproject/app/controller/Userscores.php b/hyhproject/app/controller/Userscores.php new file mode 100755 index 0000000..1031b04 --- /dev/null +++ b/hyhproject/app/controller/Userscores.php @@ -0,0 +1,38 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\UserScores as MUserscores; +/** + * ============================================================================ + * 地区控制器 + */ +class Userscores extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看 + */ + public function index(){ + $rs = model('Users')->getFieldsById((int)session('WST_USER.userId'),['userScore','userTotalScore']); + $this->assign('object',$rs); + return $this->fetch('users/userscores/list'); + } + /** + * 获取数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('UserScores')->pageQuery($userId); + return jsonReturn("", 1,$data); + } + /** + * 签到惠宝 + */ + public function signScore(){ + $m = new MUserscores(); + $userId = (int)session('WST_USER.userId'); + $rs = $m->signScore($userId); + return $rs; + } +} diff --git a/hyhproject/app/controller/Uservouchers.php b/hyhproject/app/controller/Uservouchers.php new file mode 100755 index 0000000..d3de113 --- /dev/null +++ b/hyhproject/app/controller/Uservouchers.php @@ -0,0 +1,66 @@ +<?php +namespace wstmart\app\controller; +use wstmart\app\model\Index as M; +use wstmart\admin\model\CashDraws as CM; +/** + * ============================================================================ + * 默认控制器 + */ +class Uservouchers extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'startgivevouchers,savedaymoney']// 访问这些except下的方法不需要执行前置操作 + ]; + /** + * 保存每日券值 + * @return [type] [description] + */ + public function saveDayMoney(){ + $date = date('Y-m-d'); + $m = new CM(); + $m->viewReport($date,1); + } + /** + * 分配券值 + * @return [type] [description] + */ + public function startGiveVouchers(){ + Model('UserVouchers')->startGiveVouchers(); + } + //获取券值 + public function getVouchers(){ + $m = Model('common/Table'); + $vouchersType = (int)input('post.vouchersType');//1产品券2优惠券3旺旺券 + $isExpected = (int)input('post.isExpected');//是否是预获值 + $userId = $this->getUserId(); + $list = []; + if(1 == $isExpected){ + if(1 == $vouchersType || 2 == $vouchersType){ + $vouchersNames = [1=>'expectedProductNum',2=>'expectedCouponsNum']; + $m->setTable('user_vouchers_notice'); + $list = $m->getSelect(['userId'=>$userId,$vouchersNames[$vouchersType]=>['>=',0.01],'isShow'=>1],$vouchersNames[$vouchersType].' num,remark,moneyType,createTime','id DESC'); + if(!empty($list['Rows'])){ + foreach ($list['Rows'] as &$v) { + $v['createTime'] = date('Y-m-d H:i:s',$v['createTime']); + } + } + }else{ + $m->setTable('shops'); + $shopIds = $m->getColumn(['status'=>1,'userId'=>$userId],'shopId'); + // dump($shopIds); + if($shopIds){ + $m->setTable('orders'); + $list = db('orders')->where(['shopId'=>['in',$shopIds],'orderStatus'=>['BETWEEN','0,1'],'num'=>['>=',0.01],'dataFlag'=>1])->field('SUM((productNum - productHandlingFee - productTaxFee) + (couponsNum - couponsHandlingFee - couponsTaxFee) + wangNum) num ,CONCAT("订单编号:",orderNo,",收入") as remark,dataFlag moneyType,createTime')->group('orderId')->order('orderId DESC')->paginate(input('pageSize/d',10))->toArray(); + } + } + }else{ + $m->setTable('shops'); + $shopIds = $m->getColumn(['status'=>1,'userId'=>$userId],'shopId'); + $m->setTable('log_moneys'); + $list = db('log_moneys')->where("((targetType = 0 AND targetId = $userId ) OR (targetType = 1 AND targetId IN (".implode(',',$shopIds) ."))) AND moneyName = $vouchersType AND dataFlag=1")->field('money num,remark,moneyType,createTime')->order('id DESC')->paginate(input('pageSize/d',10))->toArray(); + //dump(db()->_sql()); + // $list = $m->getSelect(['targetType'=>0,'targetId'=>$userId,'moneyName'=>$vouchersType,'dataFlag'=>1],'money num,remark,moneyType,createTime','id DESC'); + } + exit(jsonReturn('',1,$list)); + } +} diff --git a/hyhproject/app/controller/Wallets.php b/hyhproject/app/controller/Wallets.php new file mode 100755 index 0000000..9363f0c --- /dev/null +++ b/hyhproject/app/controller/Wallets.php @@ -0,0 +1,48 @@ +<?php +namespace wstmart\app\controller; +use wstmart\common\model\Orders as OM; +/** + * ============================================================================ + * 源宝控制器 + */ +class Wallets extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 跳去支付页面 + */ + public function payment(){ + $data = []; + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $this->assign('data',$data); + $m = new OM(); + $rs = $m->getOrderPayInfo($data);//获取订单金额以及用户钱包金额 + + $pay['list'] = $m->getByUnique();// 根据订单唯一流水获取订单信息 + + if(empty($rs)){//已支付或者找不到此订单 + exit(jsonReturn('读取失败',-1)); + }else{ + $pay['needPay'] = $rs['needPay'];//需付款 + //获取用户钱包 + $user = model('users')->getFieldsById($data['userId'],'userMoney,payPwd'); + $pay['userMoney'] = $user['userMoney']; + $payPwd = $user['payPwd']; + $payPwd = empty($payPwd)?0:1; + $pay['payPwd'] = $payPwd;//1有密码0没设置密码 + } + exit(jsonReturn('',1,$pay)); + + } + /** + * 钱包支付 + */ + public function payByWallet(){ + $m = new OM(); + exit(json_encode($m->payByWallet())); + } +} diff --git a/hyhproject/app/controller/Weixinpays.php b/hyhproject/app/controller/Weixinpays.php new file mode 100755 index 0000000..4d22d68 --- /dev/null +++ b/hyhproject/app/controller/Weixinpays.php @@ -0,0 +1,185 @@ +<?php +namespace wstmart\app\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +use wstmart\common\model\ChargeItems as CM; +/** + * ============================================================================ + * 微信支付控制器 + */ +class Weixinpays extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('wxpay.WxPayConf'); + Loader::import('wxpay.WxJsApiPay'); + + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + $this->wxpayConfig['notifyurl'] = url("app/weixinpays/notify","",true,true); + $this->wxpayConfig['returnurl'] = url("app/orders/index","",true,true); + $this->wxpayConfig['curl_timeout'] = 30; + + // 初始化WxPayConf + new \WxPayConf($this->wxpayConfig); + } + + + public function toWeixinPay(){ + $data = []; + $payObj = input("payObj/s"); + if($payObj=="recharge"){ + $cm = new CM(); + $itemId = (int)input("itemId/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $needPay = 0; + if($itemId>0){ + $item = $cm->getItemMoney($itemId); + $needPay = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $needPay = (int)input("needPay/d"); + } + $out_trade_no = WSTOrderNo(); + $body = "钱包充值"; + $data["status"] = $needPay>0?1:-1; + $attach = $payObj."@".$targetId."@".$targetType."@".$needPay."@".$itemId; + $returnurl = url("app/logmoneys/usermoneys","",true,true); + }else{ + + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $pkey = base64_decode(input("pkey")); + $extras = explode ( "@",$pkey); + + $m = new OM(); + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $obj["orderNo"] = input("orderNo"); + $obj["isBatch"] = (int)input("isBatch"); + + $rs = $m->getByUnique(); + $this->assign('rs',$rs); + $body = "支付订单"; + $order = $m->getPayOrders($obj); + $needPay = $order["needPay"]; + $payRand = $order["payRand"]; + $out_trade_no = $obj["orderNo"]."a1".$payRand; + $attach = $userId."@".$obj["orderNo"]."@".$obj["isBatch"]; + $returnurl = url("app/orders/index","",true,true); + } + } + + // 初始化WxPayConf + new \WxPayConf ( $this->wxpayConfig ); + //使用统一支付接口 + $notify_url = $this->wxpayConfig ['notifyurl']; + $unifiedOrder = new \UnifiedOrder(); + $unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号 + $unifiedOrder->setParameter("notify_url",$notify_url);//通知地址 + $unifiedOrder->setParameter("trade_type","MWEB");//交易类型 + $unifiedOrder->setParameter("attach",$attach);//扩展参数 + $unifiedOrder->setParameter("body",$body);//商品描述 + $needPay = WSTBCMoney($needPay,0,2); + $unifiedOrder->setParameter("total_fee", $needPay * 100);//总金额 + + $wap_name = WSTConf('CONF.mallName'); + $unifiedOrder->setParameter("scene_info", "{'h5_info': {'type':'Wap','wap_url': '".$notify_url."','wap_name': '".$wap_name."'}}");//总金额 + + $this->assign('needPay',$needPay); + $this->assign('returnUrl',$returnurl ); + $this->assign('payObj',$payObj); + $wxResult = $unifiedOrder->getResult(); + $this->assign('mweb_url',$wxResult['mweb_url']."&redirect_url".urlencode($returnurl)); + return $this->fetch('users/orders/orders_wxpay'); + } + + + public function notify() { + // 使用通用通知接口 + $notify = new \Notify(); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $notify->saveData ( $xml ); + if ($notify->checkSign () == FALSE) { + $notify->setReturnParameter ( "return_code", "FAIL" ); // 返回状态码 + $notify->setReturnParameter ( "return_msg", "签名失败" ); // 返回信息 + } else { + $notify->setReturnParameter ( "return_code", "SUCCESS" ); // 设置返回码 + } + $returnXml = $notify->returnXml (); + if ($notify->checkSign () == TRUE) { + if ($notify->data ["return_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } elseif ($notify->data ["result_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } else { + $order = $notify->getData (); + $rs = $this->process($order); + if($rs["status"]==1){ + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + } + } + + //订单处理 + private function process($order) { + + $obj = array(); + $obj["trade_no"] = $order['transaction_id']; + + $obj["total_fee"] = (float)$order["total_fee"]/100; + $extras = explode ( "@", $order ["attach"] ); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $itemId = (int)$extras [4]; + + $obj["out_trade_no"] = $order['out_trade_no']; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["payFrom"] = 'weixinpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + $obj["userId"] = $extras[0]; + $obj["out_trade_no"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = "weixinpays"; + // 支付成功业务逻辑 + $m = new OM(); + $rs = $m->complatePay ( $obj ); + } + + return $rs; + + } + +} diff --git a/hyhproject/app/model/.DS_Store b/hyhproject/app/model/.DS_Store new file mode 100755 index 0000000..137f5b7 Binary files /dev/null and b/hyhproject/app/model/.DS_Store differ diff --git a/hyhproject/app/model/._.DS_Store b/hyhproject/app/model/._.DS_Store new file mode 100755 index 0000000..b7c15a2 Binary files /dev/null and b/hyhproject/app/model/._.DS_Store differ diff --git a/hyhproject/app/model/._Goods.php b/hyhproject/app/model/._Goods.php new file mode 100755 index 0000000..728d10b Binary files /dev/null and b/hyhproject/app/model/._Goods.php differ diff --git a/hyhproject/app/model/._Shops.php b/hyhproject/app/model/._Shops.php new file mode 100755 index 0000000..69b4dc2 Binary files /dev/null and b/hyhproject/app/model/._Shops.php differ diff --git a/hyhproject/app/model/AppPort.php b/hyhproject/app/model/AppPort.php new file mode 100755 index 0000000..41f0c7a --- /dev/null +++ b/hyhproject/app/model/AppPort.php @@ -0,0 +1,224 @@ +<?php +namespace wstmart\app\model; +use think\Model; +use think\Db; +/** + * ============================================================================ + * 文章类 + */ +class AppPort extends Model{ + /* + * APP首页轮播图 + * */ + public function appBanner(){ + $result=listAds('app_new_top_banner',8,0); + return $result; + } + /** + * app新版桔子头条 + */ + public function appNews(){ + $catId=8; + $where = array(); + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $catIds=db('article_cats')->where(['parentId'=>$catId,'dataFlag'=>1])->column('catId'); + $where['catId']=array('in',$catIds); + $result = Db::name('articles')->where($where)->field('articleId,articleTitle,catId')->select(); + return $result; + } + /** + * app新版桔子头条分类接口 + */ + public function appNewsClass(){ + $catId=(int)input('catId/d'); + $where = array(); + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $id=db('article_cats')->where(['catId'=>$catId,'dataFlag'=>1])->value('parentId'); + $where['parentId']=$id; + $result = Db::name('article_cats')->where($where)->select(); + return $result; + } + /** + * app新版桔子头条 + */ + public function appNewsLists(){ + $catId=(int)input('catId/d'); + $articleId=(int)input('articleId'); + $where = array(); + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $id=db('article_cats')->where(['catId'=>$catId,'dataFlag'=>1])->value('parentId'); + $where['parentId']=$id; + $result = Db::name('article_cats')->where($where)->select(); + return $result; + } + /** + * app新版桔子头条详情页借口 + */ + public function appNewsDetail(){ + $articleId=(int)input('articleId'); + $where = array(); + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $where['articleId']=$articleId; + $result = Db::name('articles')->where($where)->select(); + return $result; + } + /* + * app新版秒杀接口 + * */ + public function appSecKill(){ + $now=time(); + $where=[]; + $where['startTime']=array('elt',$now); + $where['endTime']=array('egt',$now); + $result=Db::name('hyhsale_goods')->alias('gu') + ->join('__GOODS__ g','gu.goodsId=g.goodsId','inner') + ->where('g.dataFlag=1 and g.isSale=1 and g.goodsStatus=1 and gu.dataFlag=1 and gu.hyhsaleStatus=1 and gu.isSelf=0') + ->where($where) + ->field('gu.goodsId,g.marketPrice,gu.goodsPrice,gu.totalNum,gu.startTime,gu.endTime,g.goodsName,g.goodsImg,gu.specsId') + ->select(); + foreach($result as &$v){ + $v['goodsImg']=WSTImg($v['goodsImg'],3); + } + return $result; + } + /* + * app新版ect专区/活动层接口 + * */ + public function appEctAct(){ + $result['ect']=listAds('app_new_ect_left',1,0); + $result['act']=listAds('app_new_act_photo',1,0); + return $result; + } + /* + * app新版品牌热卖接口 + * */ + public function appBrands(){ + $result['brands']=listAds('app_new_page_brand',1,0); + $result['brandsList']=db('brands b') + ->join('hyhbrands_rec hr','b.brandId=hr.brandId') + ->whereNotIn('hr.isSelf',1) + ->field('b.brandId,brandName,brandImg,shopId,findOrder') + ->where(['dataFlag'=>1])->limit(6)->order('findOrder desc')->select(); + return $result; + } + /* + * app新版居家好帮手广告位接口 + * */ + public function appJadvertis(){ + //居家好帮手左上位置 + $row['left']=listAds('app_new_jujia_lt',2,0); + $row['right']=listAds('app_new_jujia_rt',2,0); + $result['zxz']=listAds('app_new_jujia_lul',1,0); + $result['zxy']=listAds('app_new_jujia_lur',1,0); + $result['yxz']=listAds('app_new_jujia_rul',1,0); + $result['yxy']=listAds('app_new_jujia_rur',1,0); + $row['under']= array_merge($result['zxz'],$result['zxy'],$result['yxz'],$result['yxy']); + return $row; + } + /* + * app新版潮流先锋广告位接口 + * */ + public function appCadvertis(){ + //潮流先锋左上位置 + $row['left']=listAds('app_new_chao_lt',2,0); + //潮流先锋左下左位置 + $result['zxz']=listAds('app_new_chao_lul',1,0); + //潮流先锋左下右位置 + $result['zxy']=listAds('app_new_chao_lur',1,0); + //潮流先锋右上位置 + $row['right']=listAds('app_new_chao_rt',2,0); + //潮流先锋右下左位置 + $result['yxz']=listAds('app_new_chao_rul',1,0); + //潮流先锋右下右位置 + $result['yxy']=listAds('app_new_chao_rur',1,0); + $row['under']= array_merge($result['zxz'],$result['zxy'],$result['yxz'],$result['yxy']); + return $row; + } + /* + * app新版食品超市广告位接口 + * */ + public function appSadvertis(){ + //食品超市左上位置 + $row['left']=listAds('app_new_shi_lt',2,0); + //食品超市左下左位置 + $result['zxz']=listAds('app_new_shi_lul',1,0); + //食品超市左下右位置 + $result['zxy']=listAds('app_new_shi_lur',1,0); + //食品超市右上位置 + $row['right']=listAds('app_new_shi_rt',2,0); + //食品超市右下左位置 + $result['yxz']=listAds('app_new_shi_rul',1,0); + //食品超市右下右位置 + $result['yxy']=listAds('app_new_shi_rur',1,0); + $row['under']= array_merge($result['zxz'],$result['zxy'],$result['yxz'],$result['yxy']); + return $row; + } + /* + * app新版家电馆广告位接口 + * */ + public function appDadvertis(){ + //家电馆左上位置 + $row['left']=listAds('app_new_dian_lt',2,0); + //家电馆左下左位置 + $result['zxz']=listAds('app_new_dian_lul',1,0); + //家电馆左下右位置 + $result['zxy']=listAds('app_new_dian_lur',1,0); + //家电馆右上位置 + $row['right']=listAds('app_new_dian_rt',2,0); + //家电馆右下左位置 + $result['yxz']=listAds('app_new_dian_rul',1,0); + //家电馆右下右位置 + $result['yxy']=listAds('app_new_dian_rur',1,0); + $row['under']= array_merge($result['zxz'],$result['zxy'],$result['yxz'],$result['yxy']); + return $row; + } + /* + * app为你推荐接口 + * */ + public function recommend(){ + $userId=session('WST_USER.userId'); + $page = (int)input('post.page/d'); + $cacheData = cache('APP_CATS_RECOMMEND_'.$page.'_'.$userId); + if($cacheData)return $cacheData; + $childId=[]; + $catId=[]; + $goodsCat=[]; + $goods_ids=db('page_view')->where('userId',$userId)->field('count(goodsId)num,goodsId')->group('goodsId')->order('num desc')->limit('10')->select(); + foreach($goods_ids as $key=>$value){ + $childId[]=$value['goodsId']; + } + if(!$userId ||count($childId)<4){ + $goods_ids=db('page_view')->field('count(goodsId)num,goodsId')->group('goodsId')->order('num desc')->limit('10')->select(); + foreach($goods_ids as $key=>$value){ + $childId[]=$value['goodsId']; + } + } + + $catIds=db('goods')->whereIn('goodsId',$childId)->field('goodsCatIdPath')->select(); + foreach($catIds as $key=>$value){ + $cat=explode("_",$value['goodsCatIdPath']); + //$goodsCat=current($cat); + $goodsCatId=next($cat); + $cat=db('goods_cats')->where(['catId'=>$goodsCatId,'dataFlag'=>1])->value('catId'); + $catId[]=$cat; + } + $catId=array_unique(array_filter($catId)); + //dump($catId); + $childId=db('goods_cats')->whereIn('parentId',$catId)->field('catId')->select(); + //dump($childId); + foreach($childId as $k=>$v){ + foreach($v as $kk=>$vv){ + $goodsCat[]=$vv; + } + } + $goods=db('goods')->whereIn('goodsCatId',$goodsCat)->where('dataFlag=1 AND isSale=1 AND goodsStatus=1') + ->field('goodsId,goodsName,goodsImg,shopId,marketPrice,shopPrice') + ->paginate(input('pagesize/d'))->toArray(); + cache('APP_CATS_RECOMMEND_'.$page.'_'.$userId,$goods,3600); + return $goods; + } +} diff --git a/hyhproject/app/model/Articles.php b/hyhproject/app/model/Articles.php new file mode 100755 index 0000000..79e6fcd --- /dev/null +++ b/hyhproject/app/model/Articles.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\app\model; +use think\Db; +/** + * ============================================================================ + * 文章类 + */ +class Articles extends Base{ + /** + * 获取资讯中心的子集分类id + */ + public function getChildIds(){ + $ids = cache('NEW_IDS'); + if(!$ids){ + $data = Db::name('article_cats')->cache(true)->select(); + foreach($data as $k=>$v){ + if($v['parentId']!=7 && $v['catId']!=7 && $v['parentId']!=0 ){ + $ids[] = $v['catId']; + } + } + cache('NEW_IDS',$ids); + } + return $ids; + } + + /** + * 获取咨询中中心所有文章 + */ + public function getArticles(){ + // 获取咨询中心下的所有分类id + $ids = $this->getChildIds(); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>['in',$ids], + 'a.isShow'=>1, + 'a.dataFlag'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.catType'=>0, + ]) + ->order('createTime desc') + ->paginate((int)input('pagesize')); + return $rs; + } + + + /** + * 根据id获取资讯文章 + */ + public function getNewsById(){ + $id = (int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + return $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where('ac.catType=0 and a.dataFlag=1 and a.isShow=1') + ->cache(true) + ->find($id); + } +} diff --git a/hyhproject/app/model/Base.php b/hyhproject/app/model/Base.php new file mode 100755 index 0000000..06ce69f --- /dev/null +++ b/hyhproject/app/model/Base.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Base as CBase; +/** + * ============================================================================ + * 基础模型器 + */ + +class Base extends CBase {} \ No newline at end of file diff --git a/hyhproject/app/model/Carts.php b/hyhproject/app/model/Carts.php new file mode 100755 index 0000000..cdbb473 --- /dev/null +++ b/hyhproject/app/model/Carts.php @@ -0,0 +1,303 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Carts as CCarts; +use think\Db; +/** + * 购物类 + */ +class Carts extends CCarts{ + /** + * 购买保存下参数 + * @param integer $goodsId [description] + * @param integer $goodsSpecId [description] + * @param integer $buyNum [description] + * @param integer $uId [description] + * @return [type] [description] + */ + public function buy($goodsId=0, $goodsSpecId=0, $buyNum =0, $uId=0){ + + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + if(!$userId){ + return WSTReturn('购买失败,请先登录',-999); + } + $goodsId = ($goodsId==0)?input('goodsId/d'):$goodsId; + if(!$goodsId){ + exit(jsonReturn('请输入参数值!',-1)); + } + $goodsSpecId = ($goodsSpecId==0)?input('goodsSpecId/d',0):$goodsSpecId; + $buyNum = ($buyNum==0)?input('buyNum/d',1):$buyNum; + $goodsType = (int)input('goodsType/d',1); //1逛商都2助微吧 + $buyNum = ($buyNum>0)?$buyNum:1; + //验证传过来的商品是否合法 + $chk = $this->checkGoodsSaleSpec($goodsId,$goodsSpecId); + if($chk['status']==-1)return $chk; + $goodsSpecId = $chk['data']['goodsSpecId']; + //检测库存是否足够 + if($chk['data']['stock']<$buyNum){ + return WSTReturn("购买失败,商品库存不足", -1); + } + $carts = []; + $carts['goodsId'] = $goodsId; + $carts['goodsSpecId'] = $goodsSpecId; + $carts['buyNum'] = $buyNum; + $carts['goodsType'] = $goodsType; + session('HYH_CARTS',$carts); + return WSTReturn("添加成功", 1); + } + /** + * 现在购买 + * isSettlement 是结算页面 + * uId 会员ID,默认为当前ID + * userAddress 会员地址 + */ + public function buyNow($areaId2=0, $uId=0){ + $hyhCarts = session('HYH_CARTS'); + $goodsId = $hyhCarts['goodsId']; + $goodsSpecId =$hyhCarts['goodsSpecId']; + $buyNum = $hyhCarts['buyNum']; + $areaId2 = ($areaId2==0)?input('areaId2/d'):$areaId2; + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + if(!$goodsId){ + exit(jsonReturn('请勿重新下单!',-2)); + } + if(!$userId){ + exit(jsonReturn('请重新登录下单!',-999)); + } + $where = []; + $where['g.goodsId'] = $goodsId; + $where['g.dataFlag'] = 1; + $where['g.goodsStatus'] = 1; + $where['g.isSale'] = 1; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.status'] = 1; + if($goodsSpecId){ + $where['gs.id'] = $goodsSpecId; + } + //获取商品和商店信息 + $rs = Db::name('goods g') + ->join('__SHOPS__ s','s.shopId=g.shopId','left') + ->join('__GOODS_SPECS__ gs','g.goodsId=gs.goodsId','left') + ->where($where) + ->field('s.userId,s.shopId,s.shopName,s.userId shopUserId,s.shopLevel,g.goodsId,g.goodsName,g.shopPrice,g.goodsStock,g.isSpec,g.marketPrice,gs.specPrice,gs.specStock,g.goodsImg,gs.specIds,g.goodsCatId,g.freight,g.isFreeShipping,gs.initNum,gs.whslePrice') + ->find(); + if(!$rs){ + exit(jsonReturn('商品读取失败',-1)); + } + + $cartsInfo[$rs['shopId']]['isFreeShipping'] = (bool)$rs['isFreeShipping']; + $cartsInfo[$rs['shopId']]['promotion'] = []; + $cartsInfo[$rs['shopId']]['promotionMoney'] = 0; + $cartsInfo[$rs['shopId']]['shopId'] = $rs['shopId']; + $cartsInfo[$rs['shopId']]['shopName'] = $rs['shopName']; + $cartsInfo[$rs['shopId']]['userId'] = $rs['userId']; + if($rs['isSpec']==1){ + $rs['shopPrice'] = $rs['specPrice']; + $rs['goodsStock'] = $rs['specStock']; + }else{ + $rs['initNum'] = 0; + $rs['whslePrice'] = 0; + } + $hyhCarts['goodsType'] = (int) $hyhCarts['goodsType']; + if(2 == $hyhCarts['goodsType']){//助微吧购物判断店主等级 + $tm = Model('common/Table'); + $tm->setTable('shops'); + //换算为3级循环等级 + if(0 == $rs['shopLevel']){ + $maxSaleMoney = dataConf('helpLevel0MaxSaleMoney'); + }else{ + //$nowLevel = $rs['shopLevel'] % 3; + $tm->setTable('users'); + //最大可销售金额 + $maxSaleMoney = $tm->getField(['userId'=>$rs['shopUserId']],'helpMaxSaleMoney'); + } + + $tm->setTable('shops'); + //当前销售值 + $nowSaleMoney = $tm->getSum(['userId'=>$rs['shopUserId']],'helpSaleMoney'); + if(($nowSaleMoney+$rs['shopPrice']) > $maxSaleMoney ){ + exit(jsonReturn('当前助微吧商户可销售额不足!',-1)); + } + + } + $cartsInfo[$rs['shopId']]['goodsMoney'] = $rs['shopPrice'] * $buyNum; + //判断能否购买,预设allowBuy值为10,为将来的各种情况预留10个情况值,从0到9 + $rs['allowBuy'] = 10; + if($rs['goodsStock']<=0){ + //$rs['allowBuy'] = 0;//库存不足 + exit(jsonReturn('库存不足',-1)); + }else if($rs['goodsStock']<$buyNum){ + //$rs['allowBuy'] = 1;//库存比购买数小 + $buyNum = $rs['goodsStock']; + } + + + $rs['specNames'] = []; + //加载规格值 + if($goodsSpecId>0){ + $specs = DB::name('spec_items')->alias('s')->join('__SPEC_CATS__ sc','s.catId=sc.catId','left') + ->where(['s.goodsId'=>$rs['goodsId'],'s.dataFlag'=>1])->field('catName,itemId,itemName')->select(); + if(count($specs)>0){ + $specMap = []; + foreach ($specs as $key =>$v){ + $specMap[$v['itemId']] = $v; + } + $strName = []; + if($rs['specIds']!=''){ + $str = explode(':',$rs['specIds']); + foreach ($str as $vv){ + if(isset($specMap[$vv]))$strName[] = $specMap[$vv]; + } + $rs['specNames'] = $strName; + } + + } + } + $cartsInfo[$rs['shopId']]['list']['0'] = $rs; + $cartsInfo[$rs['shopId']]['list']['0']['promotion'] = []; + $cartsInfo[$rs['shopId']]['list']['0']['goodsSpecId'] = $goodsSpecId; + $cartsInfo[$rs['shopId']]['list']['0']['cartNum'] = $buyNum; + $cartsInfo[$rs['shopId']]['list']['0']['cartId'] = $goodsSpecId; + $goodsTotalMoney = $rs['shopPrice'] * $buyNum ; + $goodsTotalNum = 1; + $cartData = ['carts'=>$cartsInfo,'goodsTotalMoney'=>$goodsTotalMoney,'goodsTotalNum'=>$goodsTotalNum,'promotionMoney'=>0]; + //秒杀活动监听 + hook("beforeSettlement",["carts"=>&$cartData]); + $allShippingMoney = 0; + if(empty($cartData['carts']['is_seckilling'])){ + //批发插件 mart hsf 20171116 + hook("mobileControllerCartsSettlement",["carts"=>&$cartData]); + //店铺优惠活动监听 + hook('afterQueryCarts',["carts"=>&$cartData,'isSettlement'=>true,'isVirtual'=>false,'uId'=>$userId]); + //ect整合相关优惠还有判断不能和在线支付商品一块 + hook("ectIntegration",["carts"=>&$cartData,'isSettlement'=>true,'uId'=>$userId]); + //11.11会场商品结算钩子 + hook("orderCatsDoubleEleven",["carts"=>&$cartData,'isSettlement'=>true,'uId'=>$userId]); + + } + //添加运费计算 + if($rs['isFreeShipping']){ + $cartData['carts'][$rs['shopId']]["shippingMoney"] = 0; + }else{ + $cartData['carts'][$rs['shopId']]["shippingMoney"] = $rs['freight']; +// if($areaId2){ +// $cartData['carts'][$rs['shopId']]["shippingMoney"] = WSTOrderFreight($rs['shopId'],$areaId2); +// }else{ +// $cartData['carts'][$rs['shopId']]["shippingMoney"] = WSTOrderFreight($rs['shopId'],-1); +// } + $allShippingMoney += $cartData['carts'][$rs['shopId']]["shippingMoney"]; + } + if($allShippingMoney){ + $cartData['goodsTotalMoney'] += $allShippingMoney; + } + $cartData['allShippingMoney'] = $allShippingMoney;//添加总运费 + $cartData['goodsType'] = $hyhCarts['goodsType']; + return $cartData; + } + /** + * 计算订单金额 + */ + public function getMoney($areaId2=0, $uId=0){ + $data = ['shops'=>[],'totalMoney'=>0,'totalGoodsMoney'=>0]; + $userId = $uId==0?(int)session('WST_USER.userId'):$uId; + $areaId = input('post.areaId2/d',-1); + //计算各店铺运费及金额 + $deliverType = (int)input('deliverType');//0是快递,1是自提,自提的不要运费,先取消 + $carts = $this->buyNow($areaId,$userId); + $shopFreight = 0; + $maxScoreMoney = 0;//初始化最大可用惠宝数 mark hsf 20171117 + $total_promotion_money = 0;//初始化合计优惠 mark hsf 20170303 + $data['maxScoreMoneySum'] = 0; + foreach ($carts['carts'] as &$v){//优化一下循环效率 mark hsf 20171118 + + // if($v['isFreeShipping']){ + // $data['shops'][$v['shopId']]['freight'] = 0; + // }else{ + // $shopFreight = ($deliverType==1)?0:WSTOrderFreight($v['shopId'],$areaId); + // $data['shops'][$v['shopId']]['freight'] = $shopFreight; + // } + if($v['isFreeShipping']){ + $shopFreight = 0; + }else{ + if($deliverType == 0){ + $shopFreight = $v['shippingMoney']; + } + } + + $data['shops'][$v['shopId']]['freight'] = $shopFreight; + $data['shops'][$v['shopId']]['oldGoodsMoney'] = $v['goodsMoney']; + $data['shops'][$v['shopId']]['goodsMoney'] = $v['goodsMoney']+$shopFreight-$v['promotionMoney']; + $data['totalGoodsMoney'] += $v['goodsMoney']-$v['promotionMoney']; + $data['totalMoney'] += $v['goodsMoney'] + $shopFreight-$v['promotionMoney']; + $total_promotion_money += $v['promotionMoney'];//合计优惠 mark hsf 20170303 + /* + * 计算最大可用惠宝,添加验证批发价的惠宝可抵用 mark hsf 20171117 + */ + // foreach ($v['list'] as &$val) { + // if(isset($val['isWhsle'])){//是批发价的 + // $maxScoreMoney += (int)($val['shopPrice'] * $val['cartNum'] * HuiWhsleScale());//可用惠宝默认抵10% + // }else{ + // $maxScoreMoney += (int)($val['shopPrice'] * $val['cartNum'] * HuiScale()); + // } + // } + /* + *----------end------------- + */ + } + //批发插件 mart hsf 20171116 + hook("mobileControllerCartsSettlement",["carts"=>&$carts]); + //放钩子计算11.11订单的分类商品使用优惠券后的金额 + hook("orderCatsCouponEleven",['data'=>&$data,'carts'=>&$carts,'isSettlement'=>true,'uId'=>$userId]); + if(isset($data['couponMoney']) && $data['couponMoney'] > 0 ){ + $total_promotion_money += $data['couponMoney']; + } + //此处放钩子计算商家使用优惠券后的金额-根据优惠券ID计算 + hook("afterCalculateCartMoney",["data"=>&$data,'carts'=>$carts,'isVirtual'=>false,'uId'=>$userId]); + //ect整合相关优惠还有判断不能和在线支付商品一块 + hook("ectIntegration",["carts"=>&$carts,'isSettlement'=>true,'uId'=>$userId]); + $maxScoreMoney = $data['maxScoreMoneySum']-($total_promotion_money * HuiScale());//减去优惠过的 + $maxScoreMoney = $maxScoreMoney < 0 ? 0 : $maxScoreMoney; + $data['totalGoodsMoney'] = ($data['totalGoodsMoney']>$data['totalMoney'])?$data['totalMoney']:$data['totalGoodsMoney']; + //echo $data['totalGoodsMoney']; + $data['maxScore'] = 0; + $data['maxScoreMoney'] = 0; + $data['useScore'] = 0; + $data['scoreMoney'] = 0; +// //计算最大可用惠宝 +// /** +// * 最多金额抵用20% mark 20170907 +// */ +// //$maxScoreMoney = (int)($data['totalGoodsMoney'] * HuiScale());//$data['totalGoodsMoney']; //惠宝最多可抵用20% mark 20170907 +// $maxScore = WSTScoreToMoney($maxScoreMoney,true);//WSTScoreToMoney($data['totalGoodsMoney'],true); +// /* +// -------------------end---------------- +// */ +// //最大可用惠宝不能大于用户惠宝 +// $user = model('users')->getFieldsById($userId,'userScore'); +// if($maxScore>$user['userScore']){ +// $maxScore = $user['userScore']; +// $maxScoreMoney = WSTScoreToMoney($maxScore); +// } +// $data['maxScore'] = $maxScore; +// $data['maxScoreMoney'] = $maxScoreMoney; +// //判断是否使用惠宝 +// $isUseScore = (int)input('isUseScore'); +// if($isUseScore==1){ +// //不能比用户惠宝还多 +// $useScore = (float)input('useScore'); +// if($useScore>$maxScore)$useScore = $maxScore; +// $data['useScore'] = $useScore; +// $data['scoreMoney'] = WSTScoreToMoney($useScore); +// } +// if((isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1) || (isset($carts['promotion_goods']) && $carts['promotion_goods'] == 1)){//不可抵用惠宝 +// $data['useScore']=0; +// $data['scoreMoney']=0; +// } + //$carts['promotionMoney'] = isset($carts['promotionMoney']) ? $carts['promotionMoney'] : 0; + $data['couponMoney'] = isset($data['couponMoney']) ? $data['couponMoney'] : 0; + $data['realTotalMoney'] = WSTPositiveNum($data['totalMoney'] - $data['scoreMoney'] - $data['couponMoney']); + //dump($data); + return WSTReturn('',1,$data); + } + +} diff --git a/hyhproject/app/model/Chain3.php b/hyhproject/app/model/Chain3.php new file mode 100755 index 0000000..80a669a --- /dev/null +++ b/hyhproject/app/model/Chain3.php @@ -0,0 +1,32 @@ +<?php +namespace wstmart\app\model; +/** + * ============================================================================ + * 基础模型器 + */ +class Chain3 extends Chain3base { + + + protected $tokenabi; + protected $bytecode; + public function __construct(){ + parent::__construct(); + } + protected function get_Balance(){ + $this->wei=8; + $address = trim(input('post.address')); + $this->web3->eth->getBalance($address , function ($err, $balance) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $my_balance = $balance->toString(); + $my_balance = $my_balance/pow(10,$this->wei); + $data['balance'] = $my_balance; + exit(jsonReturn('',1,$data)); + } + }); + } + +} \ No newline at end of file diff --git a/hyhproject/app/model/Chain3base.php b/hyhproject/app/model/Chain3base.php new file mode 100755 index 0000000..653e441 --- /dev/null +++ b/hyhproject/app/model/Chain3base.php @@ -0,0 +1,115 @@ +<?php +namespace wstmart\app\model; +use think\Model; +use think\Db; +Vendor('web3.vendor.autoload'); +use Web3\Web3; +/** + * ============================================================================ + * 基础模型器 + */ +class Chain3base extends Model{ + + /** + * web3 + * + * @var \Web3\Web3 + */ + protected $web3; + + protected $wei = 18; + + /** + * testHost + * + * @var string + */ + protected $testHost = 'http://localhost:8545'; + + /** + * coinbase + * + * @var string + */ + protected $coinbase=0; + + public function __construct(){ + parent::__construct(); + $web3 = new Web3($this->testHost); + $this->web3 = $web3; + } + public function getCoinbase(){ + $this->web3->eth->coinbase(function ($err, $coinbase) { + if ($err !== null) { + + //return $this->fail($err->getMessage()); + }else{ + $this->coinbase = $coinbase; + } + }); + return $this->coinbase; + ////获取本机账号列表 + // $this->web3->eth->accounts(function ($err, $accounts) use ($eth) { + // if ($err !== null) { + // echo 'Error: ' . $err->getMessage(); + // return; + // } + // dump($accounts); + // }); + } + /** + *创建账号 + * + * @return void + */ + public function createAccount($pass){ + $web3->personal->newAccount($pass, function ($err, $account) use (&$newAccount) { + if ($err !== null) { + return WSTReturn($err->getMessage()); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $data['account'] = $account; + return WSTReturn('',1,$data); + } + }); + } + public function getBalance($address){ + $msg=''; + $status=-1; + $data['balance']=0; + $this->web3->eth->getBalance($address , function ($err, $balance) use (&$msg,&$status,&$data) { + if ($err !== null) { + $msg=$err->getMessage(); + //return WSTReturn($err->getMessage()); + //echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $my_balance = $balance->toString(); + $my_balance = $my_balance/pow(10,$this->wei); + $status=1; + $data['balance'] = $my_balance; + } + }); + return WSTReturn($msg,$status,$data); + } + //账号解锁 + public function unlock_account($pass,$address){ + $web3->personal->unlockAccount($address, $pass, function ($err, $unlocked) { + if ($err !== null) { + exit(jsonReturn($err->getMessage())); + // echo 'Error: ' . $err->getMessage(); + // return; + } + if($unlocked) { + $data['unlock'] = 1;//$unlocked; + return WSTReturn('',1,$data); + } else { + $data['unlock'] = 0; + return WSTReturn('',1,$data); + //echo 'New account isn\'t unlocked' . PHP_EOL; + } + }); + } + +} \ No newline at end of file diff --git a/hyhproject/app/model/Ect.php b/hyhproject/app/model/Ect.php new file mode 100755 index 0000000..feb3339 --- /dev/null +++ b/hyhproject/app/model/Ect.php @@ -0,0 +1,73 @@ +<?php +namespace wstmart\app\model; +use Web3\Contract; +/** + * ============================================================================ + * 基础模型器 + */ +class Ect extends Chain3base { + + + // protected $tokenabi; + protected $contractAddress; + protected $bytecode; + protected $contract; + //protected $wei=8; + public function __construct(){ + parent::__construct(); + $this->contractAddress = '0x4c7e99ee6fa3103bfd7f44d3d196fcbf52af988e'; + $tokenabi= '[{ "constant":true,"inputs":[],"name":"name","outputs":[ { "name":"","type":"string" } ],"payable":false,"stateMutability":"view", "type":"function" },{ "constant":false, "inputs":[{ "name":"_spender","type":"address"},{ "name":"_value","type":"uint256"} ],"name":"approve", "outputs":[ { "name":"success", "type":"bool" } ],"payable":false,"stateMutability":"nonpayable", "type":"function" },{ "constant":true,"inputs":[],"name":"totalSupply", "outputs":[ { "name":"","type":"uint256"} ],"payable":false,"stateMutability":"view", "type":"function" },{ "constant":false, "inputs":[{ "name":"_from", "type":"address"},{ "name":"_to", "type":"address"},{ "name":"_value","type":"uint256"} ],"name":"transferFrom","outputs":[ { "name":"success", "type":"bool" } ],"payable":false,"stateMutability":"nonpayable", "type":"function" },{ "constant":true,"inputs":[],"name":"decimals","outputs":[ { "name":"","type":"uint8"} ],"payable":false,"stateMutability":"view", "type":"function" },{ "constant":true,"inputs":[{ "name":"_owner","type":"address"} ],"name":"balanceOf", "outputs":[ { "name":"balance", "type":"uint256"} ],"payable":false,"stateMutability":"view", "type":"function" },{ "constant":true,"inputs":[],"name":"symbol","outputs":[ { "name":"","type":"string" } ],"payable":false,"stateMutability":"view", "type":"function" },{ "constant":false, "inputs":[{ "name":"_to", "type":"address"},{ "name":"_value","type":"uint256"} ],"name":"transfer","outputs":[ { "name":"success", "type":"bool" } ],"payable":false,"stateMutability":"nonpayable", "type":"function" },{ "constant":true,"inputs":[{ "name":"_owner","type":"address"},{ "name":"_spender","type":"address"} ],"name":"allowance", "outputs":[ { "name":"remaining", "type":"uint256"} ],"payable":false,"stateMutability":"view", "type":"function" },{ "inputs":[{ "name":"_initialAmount","type":"uint256"},{ "name":"_tokenName","type":"string" },{ "name":"_decimalUnits", "type":"uint8"},{ "name":"_tokenSymbol","type":"string" } ],"payable":false,"stateMutability":"nonpayable", "type":"constructor"},{ "anonymous":false,"inputs":[{ "indexed":true, "name":"_from", "type":"address"},{ "indexed":true, "name":"_to", "type":"address"},{ "indexed":false,"name":"_value","type":"uint256"} ],"name":"Transfer","type":"event"},{ "anonymous":false,"inputs":[{ "indexed":true, "name":"_owner","type":"address"},{ "indexed":true, "name":"_spender","type":"address"},{ "indexed":false,"name":"_value","type":"uint256"} ],"name":"Approval","type":"event"}]'; + /** + * bytecode + * GameToken abi from https://github.com/sc0Vu/GameToken + * + * @var string + */ + $this->bytecode = '608060405234801561001057600080fd5b50604051610d9c380380610d9c833981018060405281019080805190602001909291908051820192919060200180519060200190929190805182019291905050508160ff16600a0a8402600081905550600054600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555082600190805190602001906100bc9291906100f8565b5081600260006101000a81548160ff021916908360ff16021790555080600390805190602001906100ee9291906100f8565b505050505061019d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061013957805160ff1916838001178555610167565b82800160010185558215610167579182015b8281111561016657825182559160200191906001019061014b565b5b5090506101749190610178565b5090565b61019a91905b8082111561019657600081600090555060010161017e565b5090565b90565b610bf0806101ac6000396000f300608060405260043610610099576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461009e578063095ea7b31461012e57806318160ddd1461019357806323b872dd146101be578063313ce5671461024357806370a082311461027457806395d89b41146102cb578063a9059cbb1461035b578063dd62ed3e146103c0575b600080fd5b3480156100aa57600080fd5b506100b3610437565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f35780820151818401526020810190506100d8565b50505050905090810190601f1680156101205780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013a57600080fd5b50610179600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506104d5565b604051808215151515815260200191505060405180910390f35b34801561019f57600080fd5b506101a86105c7565b6040518082815260200191505060405180910390f35b3480156101ca57600080fd5b50610229600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105cd565b604051808215151515815260200191505060405180910390f35b34801561024f57600080fd5b50610258610839565b604051808260ff1660ff16815260200191505060405180910390f35b34801561028057600080fd5b506102b5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061084c565b6040518082815260200191505060405180910390f35b3480156102d757600080fd5b506102e0610895565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610320578082015181840152602081019050610305565b50505050905090810190601f16801561034d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036757600080fd5b506103a6600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610933565b604051808215151515815260200191505060405180910390f35b3480156103cc57600080fd5b50610421600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b3d565b6040518082815260200191505060405180910390f35b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104cd5780601f106104a2576101008083540402835291602001916104cd565b820191906000526020600020905b8154815290600101906020018083116104b057829003601f168201915b505050505081565b600081600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015801561069a575081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410155b15156106a557600080fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b600260009054906101000a900460ff1681565b6000600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60038054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561092b5780601f106109005761010080835404028352916020019161092b565b820191906000526020600020905b81548152906001019060200180831161090e57829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410158015610a035750600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401115b1515610a0e57600080fd5b60008373ffffffffffffffffffffffffffffffffffffffff1614151515610a3457600080fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050929150505600a165627a7a723058201853053f855381fcc17a5ab6369b7109a7c774cf3774b69463ad0e4e0e5d9fe90029'; + $this->contract = new Contract($this->web3->provider, $tokenabi); + } + public function getBalance($address){ + $contract = $this->contract; + $contract->at($this->contractAddress)->call('balanceOf', $address, [ + 'from' => $address + ], function ($err, $result) use ($contract) { + if ($err !== null) { + return $this->fail($err->getMessage()); + } + if (isset($result)) { + dump($result); + // $bn = Utils::toBn($result); + // $this->assertEquals($bn->toString(), '10000', 'Balance should be 10000.'); + //$this->assertTrue($result !== null); + } + }); + // $this->contract->at($this->contractAddress)->eth->getBalance($address,function ($err, $balance) { + // if ($err === null) { + // if (isset($balance)) { + // dump($balance); + // return; + // } + // } + // }); + + parent::getBalance($address); + + } + public function getEctBalance($address){ + + $this->web3->eth->getBalance($address , function ($err, $balance) { + if ($err !== null) { + return WSTReturn($err->getMessage()); + // echo 'Error: ' . $err->getMessage(); + //return; + }else{ + $my_balance = $balance->toString(); + $my_balance = $my_balance/pow(10,$this->wei); + $data['balance'] = $my_balance; + return WSTReturn('',1,$data); + } + }); + } + + +} \ No newline at end of file diff --git a/hyhproject/app/model/EctElevenPay.php b/hyhproject/app/model/EctElevenPay.php new file mode 100755 index 0000000..96ed0b4 --- /dev/null +++ b/hyhproject/app/model/EctElevenPay.php @@ -0,0 +1,102 @@ +<?php +namespace wstmart\app\model; +use think\Db; +use think\Loader; +/** + * 双十一优惠券 + */ +class EctElevenPay extends Base{ + /** + * 返回获取双11优惠券所需的ect数量和价格 + * @return [type] [description] + */ + public function getEctNum(){ + try{ + $url ='https://api.tokencan.net/exchange-open-api/open/api/get_ticker?symbol=ectusdt'; + $t_info = $this->getHTTPS($url); + $t_info = json_decode($t_info); + if(is_object($t_info)){ + $total_money = 11.11;//input('total_money'); + $t_usdt_price = $t_info->data->last; + $now_doller = Db::name('doller')->where('id=1')->value('doller'); + $now_rmb = round($t_usdt_price*$now_doller,2); + $to_ect_num = round($total_money/$now_rmb,2); + $msg=''; + session('ect_rmb_price',$now_rmb); + exit(jsonReturn($msg,1,['now_rmb'=>$now_rmb,'ect_num'=>$to_ect_num])); + } + }catch (\Exception $e) { + exit(jsonReturn('获取价格失败!',-1)); + } + } + + private function getHTTPS($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_REFERER, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $result = curl_exec($ch); + curl_close($ch); + return $result; + } + + + /** + * 支付双十一优惠券的ect价格 + */ + public function payElevenEct(){ + try{ + $userId = (int)session('WST_USER.userId'); + if(!$userId) exit(jsonReturn('请先登录!',-999)); + //获取用户钱包 + $user = model('users')->get($userId); + + // if($user->payPwd=='')return WSTReturn('您未设置支付密码,请先设置密码',-1); + // if($user->payPwd!=md5($payPwd.$user->loginSecret))return WSTReturn('您的支付密码不正确',-1); + $ect_rmb_price = session('ect_rmb_price'); + if($ect_rmb_price<0.05){ + exit(jsonReturn('ECT价格出错!',-1)); + } + $price = 11.11; + $needPay = round($price/$ect_rmb_price,2); + + $needPay = $needPay > 0 ? $needPay : 0; + if($needPay > $user->userECT) exit(jsonReturn('您的钱包ECT不足!',-2)); + + $cfgm = Db::name('coupon_record')->where(['couponId'=>11,'userId'=>$userId])->find(); + if($cfgm){ + exit(jsonReturn('您已购买过该优惠券,不可重复购买!',-3)); + } + + //创建一条支出流水记录 + // $lm = []; + // $lm['targetType'] = 0; + // $lm['targetId'] = $userId; + // $lm['dataId'] = 0; + // $lm['dataSrc'] = 1; + // $lm['remark'] = '购买双十一神券支出¥'.$needPay; + // $lm['moneyType'] = 0; + // $lm['money'] = $needPay; + // $lm['payType'] = 'ect'; + // $a = model('common/LogMoneys')->add($lm); + + ectLog($userId,$needPay,11,'11.11神券支出',['userECT'=>['exp','userECT-'.$needPay]],2); + + + $m = new \addons\hyhcouponset\model\Hyhcouponset(); + + $data= $m->giftBag($userId,$secTypeId = 104); + // dump($data);die; + // Db::commit(); + exit(jsonReturn('扣款成功!',1)); + }catch(\Exception $e){ + // Db::rollback();errLog($e); + exit(jsonReturn('扣款失败!',-1)); + } + + } + +} diff --git a/hyhproject/app/model/Favorites.php b/hyhproject/app/model/Favorites.php new file mode 100755 index 0000000..8ddb9f6 --- /dev/null +++ b/hyhproject/app/model/Favorites.php @@ -0,0 +1,78 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Favorites as CFavorites; +/** + * ============================================================================ + * + * ============================================================================ + * 收藏类 + */ +class Favorites extends CFavorites{ + /** + * 获取会员关注商品数和关注商家数 + */ + function getFavoritesNum($userId){ + $data['goodsFavoritesNum'] = $this->where(['userId'=>$userId,'favoriteType'=>0])->count(); + $data['shopFavoritesNum'] = $this->where(['userId'=>$userId,'favoriteType'=>1])->count(); + return $data; + } + /** + * 获取关注商家数 + */ + function getFavoritesShopsNum($shopId=0){ + $shopId=$shopId==0?(int)input('shopId'):$shopId; + return $this->where(['targetId'=>$shopId,'favoriteType'=>1])->cache('true',3600)->count(); + } + /** + * 获取商品是否关注 + */ + function isGetFavorites($goodsId,$userId){ + $goodsId=$goodsId==0?(int)input('goodsId'):$goodsId; + $userId=$userId==0?(int)input('userId'):$userId; + return $this->where(['userId'=>$userId,'favoriteType'=>0,'targetId'=>$goodsId])->find(); + } + /** + * 上新的店铺列表 + */ + public function listShopQuery(){ + $pagesize = input("param.pagesize/d",5); + $goodsSize = input("param.goodsSize/d",6); + $userId = 0;//(int)session('WST_USER.userId');0就是显示所有商铺 + if($userId){ + $page = db("favorites")->alias('f') + ->join('__SHOPS__ s','s.shopId = f.targetId','left') + ->field('f.favoriteId,f.targetId,s.shopId,s.shopName,s.shopImg') + ->where(['f.userId'=> $userId,'favoriteType'=> 1])//'s.shopId'=>['in','1,2,3,6,20']]) + ->order('f.favoriteId desc') + ->paginate($pagesize)->toArray(); + + }else{ + $page = db("shops s") + ->join('__GOODS__ g','s.shopId = g.shopId','left') + ->field('s.shopId,count(goodsId) as goodsNum,s.shopName,s.shopImg') + ->where(['g.isSale'=>1, 'g.goodsStatus'=>1,'g.dataFlag'=>1]) + ->group('g.shopId') + ->order('saleTime DESC') + ->cache(true,7200) + ->paginate($pagesize) + ->toArray(); + } + foreach ($page['Rows'] as &$v){ + $field = 'goodsId,goodsImg,saleTime';//goodsName,shopPrice, + $goods = db('goods') + ->where(['dataFlag'=> 1,'isSale'=>1,'goodsStatus'=> 1,'shopId'=> $v["shopId"]]) + ->field($field) + ->cache(true,7200) + ->limit($goodsSize) + ->order('saleTime desc') + ->select(); + if($goods){ + $v['newTime'] = $goods['0']['saleTime']; + }else{ + $v['newTime'] = date('Y-m-d'); + } + $v['goods'] = $goods; + } + return $page; + } +} diff --git a/hyhproject/app/model/Goods.php b/hyhproject/app/model/Goods.php new file mode 100755 index 0000000..e1205ad --- /dev/null +++ b/hyhproject/app/model/Goods.php @@ -0,0 +1,228 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Goods as CGoods; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends CGoods{ + /** + * 获取列表 + */ + public function pageQuery($goodsCatIds = [], $_where=[]){ + //查询条件 + $keyword = input('keyword'); + $brandId = input('brandId/d'); + $where = $where2 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + if($brandId>0)$where['g.brandId'] = $brandId; + //排序条件 + $orderBy = input('condition/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('desc/d',0)==1)?1:0; + $pageBy = ['saleNum','shopPrice','visitNum','saleTime']; + $pageOrder = ['desc','asc']; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $where = array_merge($where, $_where); + $list = Db::name('goods')->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId") + ->where($where) + ->field('goodsId,goodsName,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pagesize/d'))->toArray(); + return $list; + } + /** + * 获取指定商品销量 + * @param [type] $goodsIds [description] + * @return [type] [description] + */ + public function getSales($goodsIds){ + if(is_array($goodsIds)){ + $where['og.goodsId'] = array('in',$goodsIds); + }else{ + $where['og.goodsId'] = $goodsIds; + } + $where['o.isPay'] = 1; + return Db::name('orders')->alias('o')->join('__ORDER_GOODS__ og','o.orderId=og.orderId')->cache(true,3600)->where($where)->sum('goodsNum'); + } + /** + * 获取店铺所有宝贝数量 + * @param [type] $shopId [description] + * @return [type] [description] + */ + public function getGoodsCount($shopId=0){ + $shopId=$shopId==0?(int)input('shopId'):$shopId; + $where['shopId'] = $shopId; + $where['isSale'] = 1; + $where['dataFlag'] = 1; + $where['goodsStatus'] = 1; + return $this->where($where)->cache(true,3600)->count('goodsId'); + } + /** + * 获取店铺上新宝贝数量,一周内的 + * @param [type] $shopId [description] + * @return [type] [description] + */ + public function getNewGoodsCount($shopId=0){ + $shopId=$shopId==0?(int)input('shopId'):$shopId; + $where['shopId'] = $shopId; + $where['isSale'] = 1; + $where['dataFlag'] = 1; + $where['goodsStatus'] = 1; + return $this->where($where)->whereTime('saleTime','last week')->cache(true,3600)->count('goodsId'); + } + /** + * 获取新品 + * @param [type] $goodsIds [description] + * @return [type] [description] + */ + public function getNew($goodsIds){ + if(is_array($goodsIds)){ + $where['og.goodsId'] = array('in',$goodsIds); + }else{ + $where['og.goodsId'] = $goodsIds; + } + $where['o.isPay'] = 1; + return Db::name('orders')->alias('o')->join('__ORDER_GOODS__ og','o.orderId=og.orderId')->cache(true,3600)->where($where)->sum('goodsNum'); + } + /** + * 获取商品资料在前台展示 + */ + public function getBySale($goodsId){ + $key = input('key'); + // 浏览量 + $this->where('goodsId',$goodsId)->setInc('visitNum',1); + $rs = Db::name('goods')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->find(); + if(!empty($rs)){ + $rs['read'] = false; + //判断是否可以公开查看 + $viKey = WSTShopEncrypt($rs['shopId']); + if(($rs['isSale']==0 || $rs['goodsStatus']==0) && $viKey != $key)return []; + if($key!='')$rs['read'] = true; + //获取店铺信息 + $rs['shop'] = model('shops')->getBriefShop((int)$rs['shopId']); + if(empty($rs['shop']))return []; + //获取商店的授权商店分类和商铺电话信息 + // $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left')->join('__SHOPS__ s','s.shopId = cs.shopId','left') + // ->where('cs.shopId',$rs['shopId'])->field('cs.shopId,s.shopTel,gc.catId,gc.catName')->select(); + // $rs['shop']['catId'] = $goodsCats[0]['catId']; + // $rs['shop']['shopTel'] = $goodsCats[0]['shopTel']; + + // $cat = []; + // foreach ($goodsCats as $v){ + // $cat[] = $v['catName']; + // } + // $rs['shop']['cat'] = implode(',',$cat); + // if(empty($rs['shop']))return []; + $gallery = []; + $gallery[] = $rs['goodsImg']; + + if($rs['gallery']!=''){//有多个图片就把多个一维图片地址合成一个数组 + $tmp = explode(',',$rs['gallery']); + $gallery = array_merge($gallery,$tmp); + } + + $rs['gallery'] = $gallery; + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,gc.catName,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + $rs['spec']=[]; + //把属于同一个分类的规格整合到一块 + foreach ($specs as $key =>$v){ + $rs['spec'][$v['catId']]['name'] = $v['catName']; + $rs['spec'][$v['catId']]['list'][] = $v; + } + //dump($rs['spec']);die; + //获取销售规格,商品规格的具体属性 + $sales = Db::name('goods_specs')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->field('id,isDefault,productNo,specIds,marketPrice,specPrice,specStock,initNum,whslePrice')->select(); + if(!empty($sales)){ + //将规格ID格式如:3:4:5:6:7,设为数组键名,与$rs['spec']['catId']['list']['itemId'] 对应 + /*实例 + //$specs转换后$rs['spec']数据 + [11] => array(2) {//11代表规格分类ID + ["name"] => string(12) "机身颜色"//规格分类名称 + ["list"] => array(2) {//当前分类11下的数据 + [0] => array(6) { + ["isAllowImg"] => int(1) + ["catName"] => string(12) "机身颜色" + ["catId"] => int(11) + ["itemId"] => int(5)//这个即代表数据的ID,3:4:(5):6:7就是对应的这个 + ["itemName"] => string(6) "黄色" + ["itemImg"] => string(44) "upload/goods/2017-11/5a0a7e2ee935c_thumb.jpg" + } + [1] => array(6) { + ["isAllowImg"] => int(1) + ["catName"] => string(12) "机身颜色" + ["catId"] => int(11) + ["itemId"] => int(10) + ["itemName"] => string(6) "灰色" + ["itemImg"] => string(44) "upload/goods/2017-11/5a0a7e3970fed_thumb.jpg" + } + } + } + //$sales原始数据 + [0] => array(7) { + ["id"] => int(3) + ["isDefault"] => int(1) + ["productNo"] => string(1) "3" + ["specIds"] => string(9) "3:4:5:6:7" + ["marketPrice"] => string(7) "1070.00" + ["specPrice"] => string(7) "1002.00" + ["specStock"] => int(0) + } + //$sales下面转换后数据 + ["3:4:5:6:7"] => array(6) { + ["id"] => int(3) + ["isDefault"] => int(1) + ["productNo"] => string(1) "3" + ["marketPrice"] => string(7) "1070.00" + ["specPrice"] => string(7) "1002.00" + ["specStock"] => int(0) + }*/ + foreach ($sales as $key =>$v){ + $str = explode(':',$v['specIds']); + sort($str); + unset($v['specIds']); + $rs['saleSpec'][implode(':',$str)] = $v; + } + } + //获取商品属性 + $rs['attrs'] = Db::name('attributes')->alias('a')->join('goods_attributes ga','a.attrId=ga.attrId','inner') + ->where(['a.isShow'=>1,'dataFlag'=>1,'goodsId'=>$goodsId])->field('a.attrName,ga.attrVal') + ->order('attrSort asc')->select(); + //获取商品评分 + $rs['scores'] = Db::name('goods_scores')->where('goodsId',$goodsId)->field('totalScore,totalUsers')->find(); + $rs['scores']['totalScores'] = ($rs['scores']['totalScore']==0)?5:WSTScore($rs['scores']['totalScore'],$rs['scores']['totalUsers'],5,0,3); + WSTUnset($rs, 'totalUsers'); + //关注 + $f = model('Favorites'); + $rs['favShop'] = $f->checkFavorite($rs['shopId'],1); + $rs['favGood'] = $f->checkFavorite($goodsId,0); + //$rs['isEct'] = (int)Db::name('goods_pay')->where('goodsId',$goodsId)->value('ectPay'); + } + //dump($rs);die; + return $rs; + } + + + public function historyQuery(){ + $ids = cookie("wx_history_goods"); + if(empty($ids))return []; + $where = []; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['goodsId'] = ['in',$ids]; + $orderBy = "field(`goodsId`,".implode(',',$ids).")"; + return Db::name('goods') + ->where($where)->field('goodsId,goodsName,goodsImg,saleNum,shopPrice') + ->order($orderBy) + ->paginate((int)input('pagesize'))->toArray(); + } +} diff --git a/hyhproject/app/model/GoodsAppraises.php b/hyhproject/app/model/GoodsAppraises.php new file mode 100755 index 0000000..276bdcf --- /dev/null +++ b/hyhproject/app/model/GoodsAppraises.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\GoodsAppraises as CGoodsAppraises; +use think\Db; +/** + * ============================================================================ + * 评价类 + */ +class GoodsAppraises extends CGoodsAppraises{ + /** + * 获取评论 + */ + public function getAppr(){ + $oId = (int)input('oId'); + $uId = (int)session('WST_USER.userId'); + $gId = (int)input('gId'); + $specId = (int)input('sId'); + $orderGoodsId = (int)input('orderGoodsId'); + $rs = $this->where(['orderId'=>$oId,'userId'=>$uId,'goodsId'=>$gId,'goodsSpecId'=>$specId,'orderGoodsId'=>$orderGoodsId])->find(); + if($rs!==false){ + $rs = !empty($rs)?$rs:['goodsScore'=>'','timeScore'=>'','serviceScore'=>'','content'=>'']; + return jsonReturn('',1,$rs); + } + return jsonReturn('获取出错',-1); + } + /** + * 根据商品id取一试图评论 + */ + public function getOneAppraises($goodsId){ + $goodsId=$goodsId==0?(int)input('goodsId'):$goodsId; + // 处理匿名 + $anonymous = 1; + $where = ['ga.goodsId'=>$goodsId, + 'ga.dataFlag'=>1, + 'ga.isShow'=>1]; + $rs = $this->alias('ga') + ->field('DISTINCT(ga.id),ga.content,ga.images,ga.shopReply,ga.replyTime,ga.createTime,ga.goodsScore,ga.serviceScore,ga.timeScore,ga.shopId,u.userPhoto,u.loginName,u.userPhone,og.goodsSpecNames') + ->join('__USERS__ u','ga.userId=u.userId','left') + ->join('__ORDER_GOODS__ og','og.orderId=ga.orderId and og.goodsId=ga.goodsId','inner') + ->where($where) + ->order('id desc') + ->find(); + + if($rs){ + // 格式化时间 + //$rs['createTime'] = date('Y-m-d',strtotime($rs['createTime'])); + $rs['goodsSpecNames'] = str_replace('@@_@@',',',$rs['goodsSpecNames']); + // 总评分 + //$rs['avgScore'] = ceil(($rs['goodsScore'] + $rs['serviceScore'] + $rs['timeScore'])/3); + if($anonymous){ + $start = floor((strlen($rs['userPhone'])/2))-1; + $rs['userPhone'] = substr_replace($rs['userPhone'],'***',$start,3); + $rs['loginName'] = $rs['userPhone']; + } + }else{ + $rs = []; + } + + return $rs; + } +} diff --git a/hyhproject/app/model/GoodsCats.php b/hyhproject/app/model/GoodsCats.php new file mode 100755 index 0000000..0d4ade0 --- /dev/null +++ b/hyhproject/app/model/GoodsCats.php @@ -0,0 +1,96 @@ +<?php +namespace wstmart\app\model; +use think\Cache; +/** + * ============================================================================ + * 商品分类类 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function getGoodsCats(){ + $list = cache('WST_CACHE_GOODS_CAT_MOB'); + if(!$list){ + //查询一级分类 + $trs1s = $this->where(["dataFlag"=>1,"isShow"=>1,"parentId"=>0])->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs1 = array(); + $list = array(); + $rs2 = array(); + $maprs = array(); + $ids = array(); + foreach ($trs1s as $key =>$v){ + $trs1[$key]['catId'] = $v['catId']; + $trs1[$key]['parentId'] = $v['parentId']; + $trs1[$key]['catName'] = $v['catName']; + $ids[] = $v['catId']; + } + $ids[] = -1; + //查询二级分类 + $trs2s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs2 = array(); + $ids = array(); + foreach ($trs2s as $key =>$v){ + $trs2[$key]['catId'] = $v['catId']; + $trs2[$key]['parentId'] = $v['parentId']; + $trs2[$key]['catName'] = $v['catName']; + } + foreach ($trs2 as $v2){ + $ids[] = $v2['catId']; + $maprs[$v2['parentId']][] = $v2; + } + $ids[] = -1; + //查询三级分类 + $trs3s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName,catImg')->order('catSort asc')->select(); + $trs3 = array(); + $ids = array(); + foreach ($trs3s as $key =>$v){ + $trs3[$key]['catId'] = $v['catId']; + $trs3[$key]['parentId'] = $v['parentId']; + $trs3[$key]['catName'] = $v['catName']; + $trs3[$key]['catImg'] = strval($v['catImg']); + } + foreach ($trs3 as $v2){ + $maprs[$v2['parentId']][] = $v2; + } + //倒序建立樹形 + foreach ($trs2 as $v2){ + $v2['childList'] = []; + if(isset($maprs[$v2['catId']]))$v2['childList'] = $maprs[$v2['catId']]; + $rs2[] = $v2; + } + foreach ($trs1 as $v2){ + foreach ($rs2 as $vv2){ + if($vv2['parentId']==$v2['catId']){ + $v2['childList'][] = $vv2; + } + } + $list[] = $v2; + } + Cache::set('WST_CACHE_GOODS_CAT_MOB',$list); + } + return $list; + } + /** + * 获取分类名 + * @return [type] [description] + */ + public function getCatName(){ + $catId = (int)input('post.catId'); + $rs = $this->where(['catId'=>$catId])->field('catName')->find(); + return $rs; + } + /** + * 获取分类信息 + * @param integer $parentId [description] + * @return [type] [description] + */ + public function getGoodsCat($parentId=0){ + $parentId=$parentId==0?(int)input('parentId'):$parentId; + $field = 'catId,parentId,catName,catImg'; + // if($parentId > 0){//不是父级分类要加小图片 + // $field .= ',catImg'; + // } + return $this->where(["dataFlag"=>1,"isShow"=>1,"parentId"=>$parentId])->field($field)->order('catSort asc')->cache(true,864000)->select(); + } +} diff --git a/hyhproject/app/model/Index.php b/hyhproject/app/model/Index.php new file mode 100755 index 0000000..e660cd6 --- /dev/null +++ b/hyhproject/app/model/Index.php @@ -0,0 +1,227 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Tags as T; +use think\Db; +/** + * ============================================================================ + * 默认类 + */ +class Index extends Base{ + /** + * 楼层 + */ + public function pageQuery(){ + $limit = (int)input('post.currPage');//楼层页码 + if($limit>9)return; + $cacheData = cache('MO_CATS_ADS'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('goods_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'isFloor'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select();//按设定排序获取分类名称,异步下拉加载,传输楼层的层楼 + if($rs){ + $rs= $rs[0];//用select就选第一个,其实可以改成find + $t = new T(); + $rs['ads'] = $t->listAds('mo-ads-'.$limit,'1');//获取手机版楼层页面的广告图 + $rs['goods'] = Db::name('goods')->alias('g')->join('__RECOMMENDS__ r','g.goodsId=r.dataId') + ->where(['r.goodsCatId'=>$rs['catId'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'r.dataSrc'=>0,'r.dataType'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.saleNum')->order('r.dataSort asc')->limit(6)->select(); + if(empty($rs['goods'])){ + $rs['goods'] = Db::name('goods')->alias('g') + ->where(['g.goodsCatIdPath'=>['like',$rs['catId'].'_%'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'g.isHot'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.saleNum') + ->order('saleNum desc,goodsId asc')->limit(6)->select(); + } + $rs['currPage'] = $limit; + } + cache('MO_CATS_ADS'.$limit,$rs,86400); + return $rs; + } + /** + * 猜你喜欢 + */ + public function guess_like(){ + $userId=(int)session('WST_USER.userId'); + //$userId=50; + $page = (int)input('post.page/d'); + $cacheData = cache('APP_CATS_LIKE_'.$page.'_'.$userId); + if($cacheData)return $cacheData; + $pagesize = input('pagesize/d'); + $childId=[]; + $parentId=[]; + //$goods_result["Rows"]= '';//Db::name('goods')->alias('g')->join('__RECOMMENDS__ r','g.goodsId=r.dataId') + //->where(['g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'r.dataSrc'=>0,'r.dataType'=>1]) + //->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.saleNum')->order('rand()')->paginate($pagesize)->toArray(); + //用户登录状态 + // if($userId){ + // //查找登录账号浏览过的记录 + // $goods_ids=db('page_view')->where('userId',$userId)->field('count(goodsId)num,goodsId') + // ->group('goodsId')->order('num desc')->limit('18')->select(); + // if($goods_ids){ + // foreach($goods_ids as $key=>$value){ + // $childId[]=$value['goodsId']; + // } + // //根据查找到的商品分类,寻找最顶级商品分类 + // $goods_parents=$this->getParentIs($childId); + // foreach($goods_parents as $k=>$v){ + // $parentId[]=$v; + // } + // } + + // } + //用户未登录或顶级商品分类过少时进行全表查询 + if(!$userId || count($parentId)<3){ + + $goods_ids=db('page_view')->where('1=1')->field('count(goodsId)num,goodsId') + ->group('goodsId')->order('num desc,id desc')->limit('18')->select(); + foreach($goods_ids as $key=>$value){ + $childId[]=$value['goodsId']; + } + ////根据查找到的商品分类,寻找最顶级商品分类 + $goods_parents=$this->getParentIs($childId); + foreach($goods_parents as $k=>$v){ + $parentId[]=$v; + } + } + //根据父级分类查找所有子级商品 + $goods_child=$this->getChild('',$parentId); + $pagesize = input('pagesize/d'); + //展现顶级分类下所有子级分类的商品 + $goods_result=db('goods')->whereIn('goodsCatId',$goods_child)->order('visitNum desc') + ->where(['isSale'=>1,'dataFlag'=>1,'goodsStatus'=>1,'isHot'=>1]) + ->field('goodsId,goodsName,goodsImg,shopPrice,saleNum') + ->paginate($pagesize)->toArray(); + // if(empty($goods_result["Rows"])){ + // $goods_result = Db::name('goods')->alias('g') + // ->where(['g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'g.isHot'=>1]) + // ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.saleNum') + // ->order('rand()')->paginate($pagesize)->toArray(); + // } + + cache('APP_CATS_LIKE_'.$page.'_'.$userId,$goods_result,3600); + return $goods_result; + } + /** + * 热卖推荐 + */ + public function getHotGoods(){ + $page = (int)input('page',1); + $cacheData = cache('QLG_HOT_GOODS_'.$page); + if($cacheData)return $cacheData; + $rs = Db::name('goods') + ->where(['isSale'=>1,'dataFlag'=>1,'goodsStatus'=>1]) + ->field('goodsId,goodsName,goodsImg,shopPrice,saleNum,discountRate') + ->order('discountRate DESC,goodsId DESC') + ->paginate(input('pageSize/d',10))->toArray(); + cache('QLG_HOT_GOODS_'.$page,$rs,3600); + return $rs; + } + /** + * 迭代获取下级 + * 获取一个分类下的所有子级分类id + */ + public function getChild($data,$pid){ + if(!$pid){ + return; + } + $childId = db('goods_cats')->where("dataFlag=1")->whereIn('parentId',$pid)->field('catId,parentId')->select(); + //获取该分类id下的所有子级分类id + foreach($childId as $key=>$value){ + $child[]=$value['catId']; + } + static $ids = array(); + foreach($childId as $k=>$v){ + //dump($childId); + $ids[] = $v['catId'];//将找到的下级分类id放入静态数组 + //再找下当前id是否还存在下级id + $this->getChild($childId, $v['catId']); + } + return $ids; + } + /** + * 根据子分类获取其父级分类 + */ + public function getParentIs($id,$data = array()){ + $data[] = $id; + $parentId = db('goods_cats')->where("dataFlag=1")->whereIn('catId',$id)->field('parentId')->select(); + foreach($parentId as $key=>$value){ + $parent[]=$value['parentId']; + } + + if(!isset($parent)){ + krsort($data); + //判断是否有值为0的数组元素; + foreach ($data as $k => $v) { + foreach ($v as $key => $value) { + if(!$value){ + unset($v[$key]); + } + } + if(!$v){ + unset($data[$k]); + } + } + $da=array_unique(current($data)); + return $da; + }else{ + return $this->getParentIs($parent,$data); + } + } + //获取所有小广告位 + public function getIndexAds(){ + $cacheData = cache('APP_CATS_ADS'); + if($cacheData)return $cacheData; + $where['positionCode'] = ['LIKE','%mo-ads-index-%']; + $where['positionType'] = 3; + $where['dataFlag'] = 1; + $positions_list = Db::name('ad_positions')->where($where)->field('positionId,positionName')->cache(true,86400)->select(); + unset($where['positionCode'] ); + $date = date('Y-m-d'); + $where['adStartDate'] = ['<=',$date]; + $where['adEndDate'] = ['>=',$date]; + $list=[]; + foreach($positions_list as &$v){ + $where['adPositionId'] = $v['positionId']; + $list[$v['positionId']]['name'] = $v['positionName']; + $ads_list = Db::name('ads')->where($where)->field('adFile,adURL,targetType')->cache(true,86400)->select(); + $list[$v['positionId']]['list'] = $ads_list; + } + cache('APP_CATS_ADS',$list,86400); + return $list; + } + //获取首页轮播图 + public function getIndexTopImg(){ + $cacheData = cache('APP_TOP_IMG'); + if($cacheData)return $cacheData; + $ads_list=[]; + $ads_list = listAds('mo-ads-index',9,86400); + cache('APP_TOP_IMG',$ads_list,86400); + return $ads_list; + } + //获取首页横图 + public function getIndexCrossImg(){ + $cacheData = cache('APP_CROSS_IMG'); + if($cacheData)return $cacheData; + $ads_list=[]; + $ads_list['cross_top'] = listAds('mo-index-cross-top',6,86400); + $ads_list['cross_bottom'] = listAds('mo-index-cross-down',6,86400); + cache('APP_CROSS_IMG',$ads_list,86400); + return $ads_list; + } + /** + * 获取系统消息 + */ + function getSysMsg($msg='',$order=''){ + $data = []; + $userId = (int)session('WST_USER.userId'); + if($msg!=''){ + $data['message']['num'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + } + if($order!=''){ + $data['order']['waitPay'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['order']['waitSend'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>0,'dataFlag'=>1])->count(); + $data['order']['waitReceive'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>1,'dataFlag'=>1])->count(); + $data['order']['waitAppraise'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + $data['order']['cancelNum'] = 0;//Db::name('orders')->where('userId='.$userId.' AND (orderStatus=-1 OR orderStatus=-3)')->count(); + + } + return $data; + } +} diff --git a/hyhproject/app/model/Messages.php b/hyhproject/app/model/Messages.php new file mode 100755 index 0000000..d424178 --- /dev/null +++ b/hyhproject/app/model/Messages.php @@ -0,0 +1,106 @@ +<?php +namespace wstmart\app\model; +use think\Db; +use wstmart\common\model\Messages as CMessages; +/** + * ============================================================================ + * 商城消息 + */ +class Messages extends CMessages{ + /** + * 获取列表 + */ + public function pageQuery(){ + $from = input('from/d'); + $userId = (int)session('WST_USER.userId'); + $where['receiveUserId'] = (int)$userId; + $where['dataFlag'] = 1; + if(isset($from)){ + $where['from'] = $from; + } + $page = $this->where($where)->order('msgStatus asc,id desc')->cache(true,30)->paginate(input('pagesize/d'))->toArray(); + // foreach ($page['Rows'] as $key => $v){ + // $page['Rows'][$key]['msgContent'] = WSTMSubstr(strip_tags(htmlspecialchars_decode($v['msgContent'])),0,140); + // } + foreach ($page['Rows'] as &$v){ + if($v['from'] == 1){ + $msgJson = json_decode($v['msgJson']); + //dump($msgJson);die; + $shopId = Db::name('orders')->where(['orderId'=>$msgJson->dataId])->cache(true,86400)->value('shopId'); + $shopImg = Db::name('shops')->where(['shopId'=>$shopId])->cache(true,86400)->value('shopImg'); + // Db::name('order o') + // ->join('__SHOPS s','o.shopId=s.shopId','inner join') + // ->field('shopId,shopImg') + // ->where(['o.orderId'=>$msgJson['dataId']]) + // ->cache(true,86400) + // ->find(); + $v['img'] = WSTImg($shopImg,3); + }else{ + $v['img'] = ''; + } + } + return $page; + } + /** + * 获取某一条消息详情 + */ + public function getById(){ + $userId = (int)session('WST_USER.userId'); + $id = (int)input('msgId'); + $data = $this->get(['id'=>$id,'receiveUserId'=>$userId]); + if(!empty($data)){ + //$data['msgContent'] = htmlspecialchars_decode($data['msgContent']); + if($data['msgStatus']==0) + model('Messages')->where('id',$id)->setField('msgStatus',1); + } + return $data; + } + + /** + * 删除 + */ + public function del(){ + $userId = (int)session('WST_USER.userId'); + $id = input('id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>$id,'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 批量删除 + */ + public function batchDel(){ + $userId = (int)session('WST_USER.userId'); + $ids = input('ids/a'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>['in',$ids],'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 标记为已读 + */ + public function batchRead(){ + $userId = (int)session('WST_USER.userId'); + $ids = input('ids/a'); + $data = []; + $data['msgStatus'] = 1; + $result = $this->update($data,['id'=>['in',$ids],'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("操作成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + +} diff --git a/hyhproject/app/model/Orders.php b/hyhproject/app/model/Orders.php new file mode 100755 index 0000000..b9399fd --- /dev/null +++ b/hyhproject/app/model/Orders.php @@ -0,0 +1,13 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Orders as COrders; +use think\Db; +/** + * ============================================================================ + * 订单类 + */ +class Orders extends COrders{ + function getOrderByOrderNo($orderNo,$field='*'){ + return $this->where(['dataFlag'=>1,'orderNo|orderunique'=>$orderNo])->field($field)->find(); + } +} diff --git a/hyhproject/app/model/Payments.php b/hyhproject/app/model/Payments.php new file mode 100755 index 0000000..48c0f7a --- /dev/null +++ b/hyhproject/app/model/Payments.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Payments as CPayments; +/** + * ============================================================================ + * 支付管理业务处理 + */ +class Payments extends CPayments{ +} diff --git a/hyhproject/app/model/Shops.php b/hyhproject/app/model/Shops.php new file mode 100755 index 0000000..a878e93 --- /dev/null +++ b/hyhproject/app/model/Shops.php @@ -0,0 +1,291 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Shops as CShops; +use think\Db; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends CShops{ + public function getShopIndex(){ + $shopId = (int)input('shopId'); + $shopInfo = $this->where(['shopId'=>$shopId,'status'=>1,'shopStatus'=>1,'dataFlag'=>1])->field('shopImg,shopName,lat,lng,userName,phone')->find(); + if(!$shopInfo) return WSTReturn('未找到此店铺'); + $shopInfo['shopAds'] = (string)Db::name('shop_configs')->where(['shopId'=>$shopId])->value('shopAds'); + return WSTReturn('',1,$shopInfo); + } + /** + * 店铺街列表 + */ + public function pageQuery($pagesize){ + $catId = (int)input("id"); + $keyword = input("keyword"); + $condition = input("condition"); + $desc = input("desc"); + $datas = array('sort'=>array('1'=>'ss.totalScore/ss.totalUsers'),'desc'=>array('desc','asc')); + $rs = $this->alias('s'); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.status'] = 1; + if($keyword!='')$where['s.shopName'] = ['like','%'.$keyword.'%']; + if($catId>0){ + $rs->join('__CAT_SHOPS__ cs','cs.shopId = s.shopId','left'); + $where['cs.catId'] = $catId; + } + $order = ['s.shopId'=>'asc']; + if($condition>0){ + $order = [$datas['sort'][$condition]=>$datas['desc'][$desc]]; + } + $page = $rs->join('__SHOP_SCORES__ ss','ss.shopId = s.shopId','left') + ->where($where)->order($order) + ->field('s.shopId,s.shopImg,s.shopName,s.shopCompany,ss.totalScore,ss.totalUsers,ss.goodsScore,ss.goodsUsers,ss.serviceScore,ss.serviceUsers,ss.timeScore,ss.timeUsers,s.areaIdPath') + ->paginate($pagesize)->toArray(); + foreach ($page['Rows'] as $key =>$v){ + //商品列表 + $goods = db('goods')->where(['dataFlag'=> 1,'isSale'=>1,'goodsStatus'=> 1,'shopId'=> $v["shopId"]])->field('goodsId,goodsName,shopPrice,goodsImg') + ->order('saleTime desc')->limit(3)->select(); + $page['Rows'][$key]['goods'] = $goods; + } + if(empty($page['Rows']))return $page; + $shopIds = []; + $areaIds = []; + foreach ($page['Rows'] as $key =>$v){ + $shopIds[] = $v['shopId']; + // $tmp = explode('_',$v['areaIdPath']); + // $areaIds[] = $tmp[1]; + //$page['Rows'][$key]['areaId'] = $tmp[1]; + //总评分 + $page['Rows'][$key]['totalScore'] = WSTScore($v["totalScore"]/3, $v["totalUsers"]); + $page['Rows'][$key]['goodsScore'] = WSTScore($v['goodsScore'],$v['goodsUsers']); + $page['Rows'][$key]['serviceScore'] = WSTScore($v['serviceScore'],$v['serviceUsers']); + $page['Rows'][$key]['timeScore'] = WSTScore($v['timeScore'],$v['timeUsers']); + } + $rccredMap = []; + $goodsCatMap = []; + $areaMap = []; + //认证、地址、分类 + if(!empty($shopIds)){ + $rccreds = Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','a.accredId=sac.accredId and a.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('sac.shopId,accredName,accredImg')->select(); + foreach ($rccreds as $v){ + $rccredMap[$v['shopId']][] = $v; + } + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[$v['shopId']][] = $v['catName']; + } + $areas = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$areaIds)->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->select(); + foreach ($areas as $v){ + $areaMap[$v['areaId']] = $v; + } + } + foreach ($page['Rows'] as $key =>$v){ + $page['Rows'][$key]['accreds'] = (isset($rccredMap[$v['shopId']]))?$rccredMap[$v['shopId']]:[]; + $page['Rows'][$key]['catshops'] = (isset($goodsCatMap[$v['shopId']]))?implode(',',$goodsCatMap[$v['shopId']]):''; + //$page['Rows'][$key]['areas']['areaName1'] = (isset($areaMap[$v['areaId']]['areaName1']))?$areaMap[$v['areaId']]['areaName1']:''; + //$page['Rows'][$key]['areas']['areaName2'] = (isset($areaMap[$v['areaId']]['areaName2']))?$areaMap[$v['areaId']]['areaName2']:''; + } + return $page; + } + /** + * 获取卖家中心信息 + */ + public function getShopSummary(){ + $shopId = (int)input('shopId',1); + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'dataFlag'=>1]) + ->field('s.shopId,shopImg,shopName,shopkeeper,shopAddress,shopQQ,shopTel,serviceStartTime,serviceEndTime,isInvoice,invoiceRemarks,cs.*') + ->find(); + //评分 + $scores['totalScore'] = WSTScore($shop['totalScore'],$shop['totalUsers']); + $scores['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $scores['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $scores['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + $shop['scores'] = $scores; + //认证 + $accreds = $this->shopAccreds($shopId); + $shop['accreds'] = $accreds; + return ['shop'=>$shop]; + } + /** + * 自营店铺楼层 + */ + public function getFloorData(){ + $limit = (int)input('post.currPage'); + $cacheData = cache('WX_SHOP_FLOOR'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('shop_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'shopId'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select(); + if($rs){ + $rs= $rs[0]; + $goods = Db::name('goods')->where('shopCatId1','=',$rs['catId'])->where(['dataFlag'=>1,'goodsStatus'=>1])->field('goodsId,goodsName,goodsImg,shopPrice,saleNum')->order('isHot desc')->limit(4)->select(); + $rs['goods'] = $goods; + $rs['currPage'] = $limit; + } + cache('WX_SHOP_FLOOR'.$limit,$rs,86400); + return $rs; + } + /** + * 根据订单id 获取店铺名称 + */ + public function getShopName($oId){ + return $this->alias('s') + ->join('__ORDERS__ o',"s.shopId=o.shopId",'inner') + ->where("o.orderId=$oId") + ->value('s.shopName'); + + } + /** + * 添加查看记数 + * @param [type] $rewardId [description] + * @param [type] $userId [description] + */ + public function setRewardVisit($rewardId,$userId){ + $reward_num = Db::name('reward_num'); + $where['rewardId'] = $rewardId; + $where['userId'] = $userId; + if($reward_num->where($where)->find()){ + $reward_num->where($where)->setField('isVisit',1); + }else{ + $data['rewardId'] = $rewardId; + $data['userId'] = $userId; + $data['isVisit'] = 1; + $reward_num->insert($data); + } + Db::name('rewards')->where(['rewardId'=>$rewardId])->setInc('visitNum'); + } + /** + * 点赞记数 + * @param [type] $rewardId [description] + * @param [type] $userId [description] + */ + public function setRewardLike($rewardId,$userId,$isLike){ + $reward_num = Db::name('reward_num'); + $where['rewardId'] = $rewardId; + $where['userId'] = $userId; + $dbIsLike = $reward_num->where($where)->value('isLike'); + if(isset($dbIsLike)){ + if($dbIsLike != $isLike){ + $reward_num->where($where)->setField('isLike',$isLike); + if($isLike == 1){ + Db::name('rewards')->where(['rewardId'=>$rewardId])->setInc('likeNum'); + }else{ + Db::name('rewards')->where(['rewardId'=>$rewardId])->setDec('likeNum'); + } + } + }else{ + $data['rewardId'] = $rewardId; + $data['userId'] = $userId; + $data['isLike'] = $isLike; + $reward_num->insert($data); + if($isLike == 1){ + Db::name('rewards')->where(['rewardId'=>$rewardId])->setInc('likeNum'); + } + } + + } + + /** + * mark 20180518 by zl + *获取商店特产省份 + *@param $shopId 商店id + * + */ + public function getProv($shopId=1){ + $where['shopId'] = $shopId; + $where['dataFlag'] = 1; + $where['provId'] = ['>','0']; + $prov = Db::name('shop_cats')->distinct(true)->field('provId,provName')->where($where)->order('provId asc')->select(); + return $prov; + } + /** + *获取商店特产省份 + *@param $shopId 商店id + *@param $provId 省份id + */ + public function getShopCats($shopId=1,$provId=0){ + $where['shopId'] = $shopId; + if($provId)$where['provId'] = $provId; + $where['parentId'] = 0; + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $cats = Db::name('shop_cats')->where($where) + ->field('catId,catName,shopId,provId,provName,catImg') + ->order("catId asc")->select(); + return $cats; + } + /** + *根据商店分类获取商品列表 + *@param $shopId 商店id + *@param $shopCatId1 商店一级分类 + */ + public function getGoodsByShopCats($shopId=1,$shopCatId1,$page=1){ + $cacheData = cache('APP_GOODS_BY_SHOPCAT_'.$shopId.'_'.$shopCatId1.'_'.$page); + if($cacheData)return $cacheData; + $where['shopId'] = $shopId; + $where['shopCatId1'] = $shopCatId1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $pagesize = 8; + $offset = ($page-1)*$pagesize; + $limit = "{$offset},{$pagesize}"; + $goods = Db::name('goods')->where($where)->limit($limit)->order("saleNum desc")->select(); + $list['goods'] = $goods; + $list['page'] = $page; + // $list = Db::name('goods')->where($where)->paginate($pagesize)->toArray(); + cache('APP_GOODS_BY_SHOPCAT_'.$shopId.'_'.$shopCatId1.'_'.$page,$list,600); + return $list; + } + /** + *获取首页热门特产榜单 + * + */ + public function getHotList($shopId=1){ + $where['shopId'] = $shopId; + $where['dataFlag'] = 1; + $where['isShow'] = 1; + $cat1 = cache('APP_HOT_LIST'); + if(!empty($cat1))return $cat1; + //获取一级分类 + $cat1 = Db::name('shop_cats')->field('catId,catName')->where($where)->where(['isHot'=>1,'parentId'=>0])->order('catSort asc')->select(); + if(count($cat1)>0){ + foreach($cat1 as $k=>$v){ + //获取二级分类 + $cat2 = Db::name('shop_cats')->field('catId,catName')->where($where)->where(['parentId'=>$v['catId']])->select(); + if(count($cat2)>0){ + foreach($cat2 as $kk=>$vv){ + //获取二级分类下的商品 + $vv['goods'] = $this->getGoodsByCats($shopId,$v['catId'],$vv['catId']); + if(isset($vv['goods'])){ + foreach ($vv['goods'] as $key => $value) { + $vv['goods'][$key]['goodsImg'] = WSTImg($value['goodsImg'],2); + } + } + $cat1[$k]['cat2'][] = $vv; + } + } + } + } + cache('APP_HOT_LIST',$cat1,600); + return $cat1; + } + //根据分类获取商品数据 + public function getGoodsByCats($shopId=1,$catId1,$catId2){ + $where['dataFlag'] = 1; + $where['goodsStatus'] = 1; + $where['isSale'] = 1; + $where['shopId'] = $shopId; + $where['shopCatId1'] = $catId1; + $where['shopCatId2'] = $catId2; + + $goods = Db::name('goods')->field('goodsId,goodsName,goodsImg,shopPrice')->where($where)->order('visitNum desc')->limit(2)->select(); + return $goods; + } + /** + * end + */ +} diff --git a/hyhproject/app/model/Tags.php b/hyhproject/app/model/Tags.php new file mode 100755 index 0000000..2ab1c68 --- /dev/null +++ b/hyhproject/app/model/Tags.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Tags as CTags; +use think\Db; +/** + * 标签业务处理类 + */ +class Tags extends CTags{ + + /** + * 获取最新文章 + */ + public function newArticle(){ + // $rs = Db::name('articles')->alias('a')->field('a.articleId,a.articleTitle,a.coverImg,a.createTime')->join('article_cats ac','a.catId=ac.catId','inner') + // ->where('ac.catType=0 and ac.parentId=8 and a.dataFlag=1 and ac.isShow=1')->order('a.createTime','desc')->cache(true,86400)->paginate(input('pagesize/d'))->toArray(); + //return $rs; + $page = input('page'); + $cacheData = cache('TAG_NEW_ARTICLES'.$page); + if($cacheData)return $cacheData; + $rs = Db::name('articles')->alias('a')->field('a.articleId,a.articleTitle,a.coverImg,a.createTime')->join('article_cats ac','a.catId=ac.catId','inner') + ->where('ac.catType=0 and ac.parentId<>7 and a.dataFlag=1 and ac.isShow=1 and a.isShow=1 and ac.dataFlag=1')->order('a.createTime','desc')->paginate(input('pagesize/d'))->toArray(); + cache('TAG_NEW_ARTICLES'.$page,$rs,86400); + + return $rs; + } + //添加显示会员快报 make cheng 20180227 + public function showArticle(){ + $articleId = input('articleId/d'); + $article = Db::name('articles')->where('articleId', $articleId)->field('articleTitle,articleContent,createTime')->find(); + $article['articleContent']=htmlspecialchars_decode($article['articleContent']); + return WSTReturn('', 1, $article); + } + + /** + * 桔子头条分类 + */ + + public function orangeType(){ + //$catName= '商城快讯'; + $orange = []; + //$catId =(int)Db::name('article_cats')->where(['catName'=>$catName,'dataFlag'=>1])->value('catId'); + $catId = 8; + if($catId){ + $orange = Db::name('article_cats')->where(['parentId'=>$catId,'dataFlag'=>1])->select(); + } + return $orange; +// dump($frontPage);die; + } + + /** + * @param $catName + * @return array + * 桔子头条文章 + */ + public function clog($catId){ + // $catId = input('catId'); +// echo $catId;die; + $pageSize = (int)input('pageSize/d',10); + $where = array(); + $where['isShow'] = 1; + $where['dataFlag'] = 1; + $where['catId'] = $catId; +// var_dump($where);die; + $clog = Db::name('articles')->where($where)->paginate($pageSize)->toArray(); + foreach($clog['Rows'] as &$v){ + $v['coverImg'] = WSTImg($v['coverImg'],3); + $v['articleContent']=htmlspecialchars($v['articleContent']); + } + return $clog; + } + + /** + * 桔子头条文章详情 + */ + public function detail($articleId){ + $detail = Db::name('articles')->where('articleId',$articleId)->find(); + // foreach($detail as &$v){ + // $v['coverImg'] = WSTImg($v['coverImg'],2); + // } + $detail['articleContent']=htmlspecialchars_decode($detail['articleContent']); + return $detail; + } +} diff --git a/hyhproject/app/model/Users - ╕▒▒╛.php b/hyhproject/app/model/Users - ╕▒▒╛.php new file mode 100755 index 0000000..0f24fff --- /dev/null +++ b/hyhproject/app/model/Users - ╕▒▒╛.php @@ -0,0 +1,46 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Users as CUsers; +use Think\Db; +/** + * ============================================================================ + * 用户类 + */ +class Users extends CUsers{ + /** + * 验证用户支付密码 + */ + function checkPayPwd(){ + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return jsonReturn('验证失败'); + } + $userId = (int)session('WST_USER.userId'); + $rs = $this->field('payPwd,loginSecret')->find($userId); + if($rs['payPwd']==md5($payPwd.$rs['loginSecret'])){ + return jsonReturn('',1); + } + return jsonReturn('支付密码错误',-1); + } + /** + * 获取首页数据 + * @param [type] $userId [description] + * @return [type] [description] + */ + function getIndex($userId){ + + } + function getUserInfo($userId,$field){ + return $this->where(['userId'=>$userId])->field($field)->find(); + } + function appLogOut($userId){ + $this->where(['userId'=>$userId])->setField('token',''); + session('WST_USER',null); + //setcookie("loginPwd", null); + session('WST_MO_WlADDRESS',null); + } + +} diff --git a/hyhproject/app/model/Users.php b/hyhproject/app/model/Users.php new file mode 100755 index 0000000..b9567fc --- /dev/null +++ b/hyhproject/app/model/Users.php @@ -0,0 +1,48 @@ +<?php +namespace wstmart\app\model; +use wstmart\common\model\Users as CUsers; +use Think\Db; + +/** + * ============================================================================ + * 用户类 + */ +class Users extends CUsers{ + /** + * 验证用户支付密码 + */ + function checkPayPwd(){ + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return jsonReturn('验证失败'); + } + $userId = (int)session('WST_USER.userId'); + $rs = $this->field('payPwd,loginSecret')->find($userId); + if($rs['payPwd']==md5($payPwd.$rs['loginSecret'])){ + return jsonReturn('',1); + } + return jsonReturn('支付密码错误',-1); + } + /** + * 获取首页数据 + * @param [type] $userId [description] + * @return [type] [description] + */ + function getIndex($userId){ + + } + function getUserInfo($userId,$field){ + return $this->where(['userId'=>$userId])->field($field)->find(); + } + function appLogOut($userId){ + $this->where(['userId'=>$userId])->setField('token',''); + session('WST_USER',null); + //setcookie("loginPwd", null); + session('WST_MO_WlADDRESS',null); + } + + +} diff --git a/hyhproject/app/validate/UserAddress.php b/hyhproject/app/validate/UserAddress.php new file mode 100755 index 0000000..4e20ffa --- /dev/null +++ b/hyhproject/app/validate/UserAddress.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\app\validate; +use think\Validate; +/** + * ============================================================================ + * WSTMart开源商城 + * 官网地址:http://www.wstmall.com + * 联系QQ:707563272 + * ============================================================================ + * 用户地址验证器 + */ +class UserAddress extends Validate{ + protected $rule = [ + ['userName' ,'require','请输入联系名称'], + ['userPhone' ,'require','请输入手机号码'], + ['areaId' ,'require','请选择完整地址'], + ['userAddress' ,'require','请输入详细地址'] + ]; + + protected $scene = [ + 'add' => ['userName','userPhone','areaId','userAddress'], + 'edit' => ['userName','userPhone','areaId','userAddress'] + ]; +} \ No newline at end of file diff --git a/hyhproject/command.php b/hyhproject/command.php new file mode 100755 index 0000000..7b24ef6 --- /dev/null +++ b/hyhproject/command.php @@ -0,0 +1,12 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +return []; \ No newline at end of file diff --git a/hyhproject/common/.DS_Store b/hyhproject/common/.DS_Store new file mode 100755 index 0000000..63df33a Binary files /dev/null and b/hyhproject/common/.DS_Store differ diff --git a/hyhproject/common/._.DS_Store b/hyhproject/common/._.DS_Store new file mode 100755 index 0000000..c591c75 Binary files /dev/null and b/hyhproject/common/._.DS_Store differ diff --git a/hyhproject/common/behavior/InitConfig.php b/hyhproject/common/behavior/InitConfig.php new file mode 100755 index 0000000..8db096e --- /dev/null +++ b/hyhproject/common/behavior/InitConfig.php @@ -0,0 +1,12 @@ +<?php +namespace wstmart\common\behavior; +/** + * ============================================================================ + * 初始化基础数据 + */ +class InitConfig +{ + public function run(&$params){ + WSTConf('CONF',WSTConfig()); + } +} \ No newline at end of file diff --git a/hyhproject/common/common/function.php b/hyhproject/common/common/function.php new file mode 100755 index 0000000..bffe81a --- /dev/null +++ b/hyhproject/common/common/function.php @@ -0,0 +1,2079 @@ +<?php +/** + * ============================================================================ + */ + +use think\Db; +use wstmart\common\model\Aliyunoss; + +const WST_ADDON_PATH = './addons/'; + +/******************自定义函数 start*************************/ +function getAdminPhone(){ + return '13336336128'; +} +/** + * 获取惠宝奖励模式,0分期奖励,1是一次性奖励 mark 20170914 + */ +function GetRewardScoreType(){ + return 0; +} +/** + * 惠宝抵用比例,默认20% mark 20170914 + */ +function HuiScale(){ + return 0;//0.2; +} +/** + * 批发时惠宝抵用比例,默认10% mark 20171118 + */ +function HuiWhsleScale(){ + return 0.1; +} +/** + * 获取联盟id + */ +function GetLMID($userId){ + return (int)Db::name('users')->where(['userId'=>$userId])->value('hyhlm_id'); +} +/** + * 获取商城id,根据联盟id + */ +function GetShopID($user_id){ + return (int)Db::table('rd_users')->where(['user_id'=>$user_id])->value('shop_id'); +} +/** + * 获取userId,根据shopId + */ +function GetShopInfo($shopId,$field='userId'){ + return Db::name('shops')->where(['shopId'=>$shopId])->field($field)->find(); +} + /** [getLMUserByID 根据联盟id返回] + * @param [type] $user_id [description] + * @param string $field [description] + * @return [type] [description] + */ +function getLMUserByID($user_id,$field='name'){ + $rs = Db::table('rd_users')->where(['user_id'=>$user_id])->field($field)->find(); + return $rs; +} +/** + * [getLMUserByName 根据联盟名字返回] + * @param [type] $name [description] + * @param string $field [description] + * @return [type] [description] + */ +function getLMUserByName($name,$field='user_id'){ + $rs = Db::table('rd_users')->where(['name|mobile'=>$name,'is_lock'=>0])->field($field)->find(); + return $rs; +} +/** + * [getUserByName 根据名字返回] + * @param [type] $name [description] + * @param string $field [description] + * @return [type] [description] + */ +function getUserByName($name,$field='userId'){ + $rs = Db::name('users')->where(["loginName|userPhone"=>['=',$name],'dataFlag'=>1])->field($field)->find(); + return $rs; +} +/** + * [getUserByName 根据名字返回] + * @param [type] $name [description] + * @param string $field [description] + * @return [type] [description] + */ +function getUserInfo($where,$field='userId'){ + $where['dataFlag']=1; + $rs = Db::name('users')->where($where)->field($field)->find(); + return $rs; +} + /** [getUserByID 根据id返回] + * @param [type] $userId [description] + * @param string $field [description] + * @return [type] [description] + */ +function getUserByID($userId,$field='loginName'){ + $rs = Db::name('users')->where(['userId'=>$userId])->field($field)->find(); + return $rs; +} +function getUserByToken($token,$field='*'){ + $rs = Db::name('users')->where(['token'=>$token])->field($field)->find(); + return $rs; +} +function errLog($e){ + $content = date('Y-m-d H:i:s').'-errMessage:'.$e->getMessage().',errLine:'.$e->getLine().',errInfo:'.$e->getTraceAsString().PHP_EOL.PHP_EOL; + \think\Log::write($content); + // $errAction = request()->module() . '/' . request()->controller() . '/' . request()->action(); + // \think\Log::write($errAction.'-error:'.$e->getMessage().',errAction:'.$errAction.',errFile:'.$e->getFile().',errLine:'.$e->getLine()); +} +/** + * 添加源宝记录 + * @param [type] $userId [会员ID] + * @param [type] $dataId [数据记录ID] + * @param [type] $dataSrc [流水来源 1:交易订单 2:订单结算 3:提现申请 4.退款订单 20:抽奖所得] + * @param [type] $chargeMoney [变动金额] + * @param [type] $remark [备注] + * @param int $moneyType [0:支出 1:收入] + * @param int $targetType [0:会员 1:商家] + * @param string $payFrom [支付类型 支付来源代码,和支付方式对应代码] + * @param string $trade_no [外部流水号 例如微信支付,支付宝支付的交易流水号] + */ +function addMoneyLog($userId,$dataId,$dataSrc,$chargeMoney,$moneyType,$remark='',$targetType=0,$payFrom='',$trade_no=''){ + $lm = []; + $lm['targetType'] = $targetType; + $lm['targetId'] = $userId; + $lm['dataId'] = $dataId; + $lm['dataSrc'] = $dataSrc;//抽奖获得 + $lm['remark'] = $remark; + $lm['moneyType'] = $moneyType; + $lm['money'] = $chargeMoney; + $lm['payType'] = $payFrom; + $lm['tradeNo'] = $trade_no; + $lm['createTime'] = date('Y-m-d H:i:s'); + if(Db::name('log_moneys')->insert($lm)){ + return Db::name('users')->where(['userId'=>$userId])->setField('userMoney',$chargeMoney); + } +} +/** + * 添加惠宝记录 + * @param [type] $userId [会员ID] + * @param [type] $dataId [数据记录ID] + * @param [type] $dataSrc [流水来源 1:订单 2:评价 3:订单取消返还 4:拒收返还 20:抽奖所得] + * @param [type] $chargeMoney [变动金额] + * @param [type] $remark [备注] + * @param int $moneyType [0:支出 1:收入] + */ +function addScoreLog($userId,$dataId,$dataSrc,$chargeMoney,$moneyType,$remark=''){ + $uscore = []; + $uscore['userId'] = $userId; + $uscore['score'] = $chargeMoney; + $uscore['dataSrc'] = $dataSrc; + $uscore['dataId'] = $dataId; + $uscore['dataRemarks'] = $remark; + $uscore['scoreType'] = $moneyType; + model('common/UserScores')->add($uscore,true); + return Db::name('users')->where(['userId'=>$userId])->setField('userScore',$chargeMoney); +} +/** + * 获取广告列表 + * 如 listAds('ads-hyhchosen',6,86400); + */ +function listAds($positionCode,$num,$cache = 0){ + $cacheData = cache('TAG_ADS_APP'.$positionCode); + if($cacheData)return $cacheData; + $today = date('Y-m-d'); + $rs = Db::name("ads")->alias('a')->join('__AD_POSITIONS__ ap','a.adPositionId= ap.positionId and ap.dataFlag=1','left') + ->where("a.dataFlag=1 and ap.positionCode='".$positionCode."' and adStartDate<= '$today' and adEndDate>='$today'") + ->field('adId,adName,adURL,targetType,adFile,positionWidth,positionHeight') + ->order('adSort DESC')->limit($num)->select(); + foreach ($rs as &$v) { + $v['adFile'] = WSTImg($v['adFile'],2); + } + // if(count($rs)>0){ + // foreach ($rs as $key => $v) { + // $rs[$key]['isOpen'] = false; + // if(stripos($v['adURL'],'http:')!== false || stripos($v['adURL'],'https:')!== false){ +// $rs[$key]['isOpen'] = true; + // } + // } + // } + cache('TAG_ADS_APP'.$positionCode,$rs,$cache); + return $rs; +} +function getImgUrl(){ + return 'http://img.zgqlg.com.cn/'; +} +/** + * [file_exists_oss [判断文件是否存在oss上] + * @param [type] $object [description] + * @return [type] [description] + */ +function file_exists_oss($object){ + $imgurl = getImgUrl().$object; + $ch = curl_init(); + $timeout = 10; + curl_setopt ($ch, CURLOPT_URL, $imgurl); + curl_setopt($ch, CURLOPT_HEADER, 1); + curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + + $contents = curl_exec($ch); + if (preg_match("/404/", $contents)){ + return false; + }else{ + return true; + } + + //说是在windows下可以,LINUX下无论图片在不在都返加TRUE + // if(file_get_contents($imgurl,0,null,0,1)){ + // return true; + // }else{ + // return false; + // } + + // if(@fopen( $imgurl, 'r' )){ + // return true; + // }else{ + // return false; + // } + + +} + +/******************自定义函数 end*************************/ +/*******************ect社区自己定义函数********************/ +/** + * [ectLog ect记录] + * @param [type] $userId [用户id] + * @param [type] $ectNum [ect数目] + * @param [type] $dataSrc [数据来源] + * @param [type] $remark [备注] + * @param [type] $update [更新表达式:['userECT'=>['exp','userECT+'.$recomNum]]] + * @return [type] [bool] + */ + function ectLog($userId,$ectNum,$dataSrc,$remark,$update,$ectType=1){ + if(!$ectNum || ($ectNum > 0 && $ectNum < 0.00001)) return; + // if($ectNum < 0){ + // $ectType = 2; + // }else{ + // $ectType = 1; + // } + $data['userId'] = $userId; + $data['ectNum'] = $ectNum; + $data['dataSrc'] = $dataSrc; + $data['dataRemarks'] = $remark; + $data['ectType'] = $ectType; + $data['createTime'] = time(); + if(false !== Db::name('user_ect_log')->insert($data)){ + Db::name('users')->where(['userId'=>$userId])->update($update); + return true; + } + return false; + } + /** + * [create_tree 用户表树] + * @param [type] $uid [用户id] + * @param [type] $pid [推荐人id] + * @return [type] [description] + */ + function create_tree($uid,$pid){ + if(!$uid) return; + if(Db::name('user_trees')->where(array('uid'=>$uid))->find()) return;//树里有 + if($pid){ + $p_info = Db::name('user_trees')->where(array('uid'=>$pid))->field('bid,t_level')->find(); + if($p_info['t_level']){ + $t_level = $p_info['t_level'] + 1; + }else{ + $t_level = 2; + } + if($p_info['bid']){ + $bid = $p_info['bid']; + }else{ + $bid = $pid; + } + + }else{ + $bid = $uid; + $t_level = 1; + } + $set = array( + 'uid'=>$uid, + 'pid'=>$pid, + 'bid'=>$bid, + 't_level'=>$t_level, + 'update_time'=>time() + ); + Db::name('user_trees')->insert($set); + //获取家族树最顶级节点,重建树 + // rebuild_tree($bid,1);//重建树,建立有左右值的数据表,对整个结构重新进行一次编号 + + } + function rebuild_tree($root, $left) { + // the right value of this node is the left value + 1 + $right = $left+1; + // get all children of this node + $trees = Db::name('user_trees')->where(array('pid'=>$root))->field('uid')->select(); + if($trees){ + foreach ($trees as $k => $v) { + $right = rebuild_tree($v['uid'], $right); + } + } + $set = array( + 'lft' => $left, + 'rgt' => $right, + ); + Db::name('user_trees')->where(array('uid'=>$root))->update($set); + // return the right value of this node + 1 + return $right + 1; + } + + +/******************自定义函数 end*************************/ + +/** + * 获取分类的佣金原函数 + */ +// function WSTGoodsCommissionRate($goodsCatId){ +// $cats = Db::name('goods_cats')->where('catId',$goodsCatId)->field('parentId,commissionRate')->find(); +// if(empty($cats)){ +// return 0; +// }else{ +// if((float)$cats['commissionRate']>=0)return (float)$cats['commissionRate']; +// return WSTGoodsCommissionRate($cats['parentId']); +// } +// } +/** + * 获取分类的佣金 mark 修改一下,商家批量购买佣金5% 20170914 + */ +function WSTGoodsCommissionRate($goodsCatId,$isWhsle = 0){ + $cats = Db::name('goods_cats')->where('catId',$goodsCatId)->field('parentId,commissionRate')->find(); + if(empty($cats)){ + return 0; + }else{ + if((float)$cats['commissionRate']>=0){ + if($isWhsle){ + return (float)($cats['commissionRate']/2); + }else{ + return (float)$cats['commissionRate']; + } + + } + return WSTGoodsCommissionRate($cats['parentId'],$isWhsle);//递归获取分类的佣金,因为-1是继承父级的分类佣金 + } +} +/** + * 检测登录账号是否可用 原函数 + * @param $key 要检测的内容 + */ +// function WSTCheckLoginKey($val,$userId = 0){ +// if($val=='')return WSTReturn("登录账号不能为空"); +// if(!WSTCheckFilterWords($val,WSTConf("CONF.registerLimitWords"))){ +// return WSTReturn("登录账号包含非法字符"); +// } +// $dbo = Db::name('users')->where(["loginName|userEmail|userPhone"=>['=',$val],'dataFlag'=>1]); +// if($userId>0){ +// $dbo->where("userId", "<>", $userId); +// } +// $rs = $dbo->count(); +// if($rs==0){ +// return WSTReturn("该登录账号可用",1); +// } +// return WSTReturn("对不起,登录账号已存在"); +// } +/** + * 检测登录账号是否可用 + * @param $key 要检测的内容 + */ +function WSTCheckLoginKey($val,$userId = 0){ + if($val=='')return WSTReturn("登录账号不能为空"); + if(!WSTCheckFilterWords($val,WSTConf("CONF.registerLimitWords"))){ + return WSTReturn("登录账号包含非法字符"); + } + $dbo = Db::name('users')->where(["loginName|userPhone"=>['=',$val]]); + if($userId>0){ + $dbo->where("userId", "<>", $userId); + } + if($dbo->find()){ + return WSTReturn("对不起,登录账号已存在"); + } + return WSTReturn("该登录账号可用",1); + + // $rs = $dbo->count(); + // if($rs==0){ + // $lm_info = getLMUserByName($val);//获取联盟会员信息 + // if($lm_info){ + // return WSTReturn("该登录账号已注册联盟用户"); + // } + // return WSTReturn("该登录账号可用",1); + // } + // return WSTReturn("对不起,登录账号已存在"); +} + +/***************************以上都是为修改内容*****************************/ + + + +/** + * 生成验证码 + */ +function WSTVerify(){ + ob_clean(); + $Verify = new \verify\Verify(); + $Verify->length = 4; + $Verify->entry(); +} +/** + * 核对验证码 + */ +function WSTVerifyCheck($code){ + $verify = new \verify\Verify(); + return $verify->check($code); +} +/** + * 生成数据返回值 + */ +function WSTReturn($msg,$status = -1,$data = []){ + $rs = ['status'=>$status,'msg'=>$msg]; + if(!empty($data))$rs['data'] = $data; + return $rs; +} +/** + * 生成数据返回值 + */ +function jsonReturn($msg,$status = -1,$data = []){ + //if(isset($data['status']))return json_encode($data); + $rs = ['status'=>$status,'msg'=>$msg]; + if(!empty($data))$rs['data'] = $data; + + return json_encode($rs); +} + +/** + * 检测字符串不否包含 + * @param $srcword 被检测的字符串 + * @param $filterWords 禁用使用的字符串列表 + * @return boolean true-检测到,false-未检测到 + */ +function WSTCheckFilterWords($srcword,$filterWords){ + $flag = true; + if($filterWords!=""){ + $filterWords = str_replace(",",",",$filterWords); + $words = explode(",",$filterWords); + for($i=0;$i<count($words);$i++){ + if(strpos($srcword,$words[$i]) !== false){ + $flag = false; + break; + } + } + } + return $flag; +} +function dataConf($key){ + $rs = cache('DATA_CONFIG_'.$key); + if(!$rs){ + $rs = Db::name('data_configs')->where(['fieldCode'=>$key])->value('fieldValue'); + cache('DATA_CONFIG_'.$key,$rs,0); + } + return $rs; +} +function dataConfList($field,$order='id ASC'){ + return Db::name('data_configs')->field($field)->order($order)->select(); +} +/** + * 获取指定的全局配置 + */ +function WSTConf($key,$v = ''){ + if(is_null($v)){ + if(array_key_exists('WSTMARTCONF',$GLOBALS) && array_key_exists($key,$GLOBALS['WSTMARTCONF'])){ + unset($GLOBALS['WSTMARTCONF'][$key]); + } + }else if($v === ''){ + if(array_key_exists('WSTMARTCONF',$GLOBALS)){ + $conf = $GLOBALS['WSTMARTCONF']; + $ks = explode(".",$key); + for($i=0,$k=count($ks);$i<$k;$i++){ + if(array_key_exists($ks[$i],$conf)){ + $conf = $conf[$ks[$i]]; + }else{ + return null; + } + } + return $conf; + } + }else{ + return $GLOBALS['WSTMARTCONF'][$key] = $v; + } + return null; +} + +//php获取中文字符拼音首字母 +function WSTGetFirstCharter($str){ + if(empty($str)){ + return ''; + } + $fchar=ord($str{0}); + if($fchar>=ord('A')&&$fchar<=ord('z')) return strtoupper($str{0}); + $s1=iconv('UTF-8','gb2312',$str); + $s2=iconv('gb2312','UTF-8',$s1); + $s=$s2==$str?$s1:$str; + if(empty($s{1})){ + return ''; + } + $asc=ord($s{0})*256+ord($s{1})-65536; + if($asc>=-20319 && $asc<=-20284) return 'A'; + if($asc>=-20283 && $asc<=-19776) return 'B'; + if($asc>=-19775 && $asc<=-19219) return 'C'; + if($asc>=-19218 && $asc<=-18711) return 'D'; + if($asc>=-18710 && $asc<=-18527) return 'E'; + if($asc>=-18526 && $asc<=-18240) return 'F'; + if($asc>=-18239 && $asc<=-17923) return 'G'; + if($asc>=-17922 && $asc<=-17418) return 'H'; + if($asc>=-17417 && $asc<=-16475) return 'J'; + if($asc>=-16474 && $asc<=-16213) return 'K'; + if($asc>=-16212 && $asc<=-15641) return 'L'; + if($asc>=-15640 && $asc<=-15166) return 'M'; + if($asc>=-15165 && $asc<=-14923) return 'N'; + if($asc>=-14922 && $asc<=-14915) return 'O'; + if($asc>=-14914 && $asc<=-14631) return 'P'; + if($asc>=-14630 && $asc<=-14150) return 'Q'; + if($asc>=-14149 && $asc<=-14091) return 'R'; + if($asc>=-14090 && $asc<=-13319) return 'S'; + if($asc>=-13318 && $asc<=-12839) return 'T'; + if($asc>=-12838 && $asc<=-12557) return 'W'; + if($asc>=-12556 && $asc<=-11848) return 'X'; + if($asc>=-11847 && $asc<=-11056) return 'Y'; + if($asc>=-11055 && $asc<=-10247) return 'Z'; + return null; +} + +/** + * 设置当前页面对象 + * @param int 0-用户 1-商家 + */ +function WSTLoginTarget($target = 0){ + $WST_USER = session('WST_USER'); + $WST_USER['loginTarget'] = $target; + session('WST_USER',$WST_USER); +} +/** + * 邮件发送函数 + * @param string to 要发送的邮箱地址 + * @param string subject 邮件标题 + * @param string content 邮件内容 + * @return array + */ +function WSTSendMail($to, $subject, $content) { + $mail = new \phpmailer\phpmailer(); + // 装配邮件服务器 + $mail->IsSMTP(); + $mail->SMTPDebug = 0; + $mail->Host = WSTConf("CONF.mailSmtp"); + $mail->SMTPAuth = WSTConf("CONF.mailAuth"); + $mail->Username = WSTConf("CONF.mailUserName"); + $mail->Password = WSTConf("CONF.mailPassword"); + $mail->CharSet = 'utf-8'; + // 装配邮件头信息 + $mail->From = WSTConf("CONF.mailAddress"); + $mail->AddAddress($to); + $mail->FromName = WSTConf("CONF.mailSendTitle"); + $mail->IsHTML(true); + // 装配邮件正文信息 + $mail->Subject = $subject; + $mail->Body = $content; + // 发送邮件 + $rs =array(); + if (!$mail->Send()) { + $rs['status'] = 0; + $rs['msg'] = $mail->ErrorInfo; + return $rs; + } else { + $rs['status'] = 1; + return $rs; + } +} + +/** + * 获取系统配置数据 + */ +function WSTConfig(){ + $rs = cache('WST_CONF'); + if(!$rs){ + $rv = Db::name('sys_configs')->field('fieldCode,fieldValue')->select(); + $rs = []; + foreach ($rv as $v){ + $rs[$v['fieldCode']] = $v['fieldValue']; + } + //获取风格 + $styles = Db::name('styles')->where(['isUse'=>1])->field('styleSys,stylePath,id')->select(); + if(!empty($styles)){ + foreach ($styles as $key => $v) { + $rs['wst'.$v['styleSys'].'Style'] = $v['stylePath']; + $rs['wst'.$v['styleSys'].'StyleId'] = $v['id']; + } + } + + //获取上传文件目录配置 + $data = Db::name('datas')->where('catId',3)->column('dataVal'); + foreach ($data as $key => $v){ + $data[$key] = str_replace('_','',$v); + } + $rs['wstUploads'] = $data; + if($rs['mallLicense']=='')$rs['mallSlogan'] = $rs['mallSlogan']." ".base64_decode('UG93ZXJlZCBCeSBXU1RNYXJ0'); + cache('WST_CONF',$rs,31536000); + } + return $rs; +} + +/** + * 判断手机号格式是否正确 + */ +function WSTIsPhone($phoneNo){ + //$reg = "/^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^17[0,6,7,8]{1}\d{8}$|^18[\d]{9}$/"; + $reg = "/^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^17[\d]{9}$|^18[\d]{9}$|^16[\d]{9}$|^19[\d]{9}$/"; + $rs = \think\Validate::regex($phoneNo,$reg); + return $rs; +} + +// /** +// * 检测登录账号是否可用 +// * @param $key 要检测的内容 +// */ +// function WSTCheckLoginKey($val,$userId = 0){ +// if($val=='')return WSTReturn("登录账号不能为空"); +// if(!WSTCheckFilterWords($val,WSTConf("CONF.registerLimitWords"))){ +// return WSTReturn("登录账号包含非法字符"); +// } +// $dbo = Db::name('users')->where(["loginName|userEmail|userPhone"=>['=',$val],'dataFlag'=>1]); +// if($userId>0){ +// $dbo->where("userId", "<>", $userId); +// } +// $rs = $dbo->count(); +// if($rs==0){ +// return WSTReturn("该登录账号可用",1); +// } +// return WSTReturn("对不起,登录账号已存在"); +// } + +/** + * 生成随机数账号 + */ +function WSTRandomLoginName($loginName){ + $chars = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); + //简单的派字母 + foreach ($chars as $key =>$c){ + $crs = WSTCheckLoginKey($loginName."_".$c); + if($crs['status']==1)return $loginName."_".$c; + } + //随机派三位数值 + for($i=0;$i<1000;$i++){ + $crs = WSTCheckLoginKey($loginName."_".$i); + if($crs['status']==1)return $loginName."_".$i; + } + return ''; +} + +/** + * 删除一维数组里的多个key + */ +function WSTUnset(&$data,$keys){ + if($keys!='' && is_array($data)){ + $key = explode(',',$keys); + foreach ($key as $v)unset($data[$v]); + } +} +/** + * 只允许一维数组里的某些key通过 + */ +function WSTAllow(&$data,$keys){ + if($keys!='' && is_array($data)){ + $key = explode(',',$keys); + foreach ($data as $vkeys =>$v)if(!in_array($vkeys,$key))unset($data[$vkeys]); + } +} + +/** + * 字符串替换 + * @param string $str 要替换的字符串 + * @param string $repStr 即将被替换的字符串 + * @param int $start 要替换的起始位置,从0开始 + * @param string $splilt 遇到这个指定的字符串就停止替换 + */ +function WSTStrReplace($str,$repStr,$start,$splilt = ''){ + $newStr = substr(utf8_encode($str),0,$start); + $breakNum = -1; + for ($i=$start;$i<strlen($str);$i++){ + $char = substr($str,$i,1); + if($char==$splilt){ + $breakNum = $i; + break; + } + $newStr.=$repStr; + } + if($splilt!='' && $breakNum>-1){ + for ($i=$breakNum;$i<strlen($str);$i++){ + $char = substr($str,$i,1); + $newStr.=$char; + } + } + return $newStr; +} + +/** + * 获取指定商品分类的子分类列表/获取指定的商品分类,靠$isSelf=-1判断 + */ +function WSTGoodsCats($parentId = 0,$isFloor = -1,$isSelf = 0){ + if($isSelf==1){ + return Db::name('goods_cats')->where(['dataFlag'=>1, 'isShow' => 1,'catId'=>$parentId]) + ->field("catName,catId,parentId")->order('catSort asc')->find(); + }else{ + $dbo = Db::name('goods_cats')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>$parentId]); + if($isFloor!=-1)$dbo->where('isFloor',$isFloor); + return $dbo->field("catName,catId")->order('catSort asc')->select(); + } +} + + +// /** +// * 上传图片 +// * 需要生成缩略图: isThumb=1 +// * 需要加水印:isWatermark=1 +// * pc版缩略图: width height +// * 手机版原图:mWidth mHeight +// * 缩略图:mTWidth mTHeight +// * 判断图片来源:fromType 0:商家/用户 1:平台管理员 +// */ +// function WSTUploadPic($fromType=0){ +// $fileKey = key($_FILES); +// $dir = Input('param.dir'); +// if($dir=='')return json_encode(['msg'=>'没有指定文件目录!','status'=>-1]); +// $dirs = WSTConf("CONF.wstUploads"); +// if(!in_array($dir, $dirs)){ +// return json_encode(['msg'=>'非法文件目录!','status'=>-1]); +// } +// // 上传文件 +// $file = request()->file($fileKey); +// if($file===null){ +// return json_encode(['msg'=>'上传文件不存在或超过服务器限制','status'=>-1]); +// } +// $validate = new \think\Validate([ +// ['fileMime','fileMime:image/png,image/gif,image/jpeg,image/x-ms-bmp','只允许上传jpg,gif,png,bmp类型的文件'], +// ['fileExt','fileExt:jpg,jpeg,gif,png,bmp','只允许上传后缀为jpg,gif,png,bmp的文件'], +// ['fileSize','fileSize:2097152','文件大小超出限制'],//最大2M +// ]); +// $data = ['fileMime' => $file, +// 'fileSize' => $file, +// 'fileExt'=> $file +// ]; +// if (!$validate->check($data)) { +// return json_encode(['msg'=>$validate->getError(),'status'=>-1]); +// } +// $info = $file->rule('uniqid')->move(ROOT_PATH.'/upload/'.$dir."/".date('Y-m')); +// if($info){ +// $filePath = $info->getPathname(); +// $filePath = str_replace(ROOT_PATH,'',$filePath); +// $filePath = str_replace('\\','/',$filePath); +// $name = $info->getFilename(); +// $filePath = str_replace($name,'',$filePath); +// //原图路径 +// $imageSrc = trim($filePath.$name,'/'); +// //图片记录 +// WSTRecordImages($imageSrc, (int)$fromType); +// //打开原图 +// $image = \image\Image::open($imageSrc); +// //缩略图路径 手机版原图路径 手机版缩略图路径 +// $thumbSrc = $mSrc = $mThumb = null; +// //手机版原图宽高 +// $mWidth = min($image->width(),(int)input('mWidth',700)); +// $mHeight = min($image->height(),(int)input('mHeight',700)); +// //手机版缩略图宽高 +// $mTWidth = min($image->width(),(int)input('mTWidth',250)); +// $mTHeight = min($image->height(),(int)input('mTHeight',250)); + +// /****************************** 生成缩略图 *********************************/ +// $isThumb = (int)input('isThumb'); +// if($isThumb==1){ +// //缩略图路径 +// $thumbSrc = str_replace('.', '_thumb.', $imageSrc); +// $image->thumb((int)input('width',min(300,$image->width())), (int)input('height',min(300,$image->height())),2)->save($thumbSrc,$image->type(),90); +// //是否需要生成移动版的缩略图 +// $suffix = WSTConf("CONF.wstMobileImgSuffix"); +// if(!empty($suffix)){ +// $image = \image\Image::open($imageSrc); +// $mSrc = str_replace('.',"$suffix.",$imageSrc); +// $mThumb = str_replace('.', '_thumb.',$mSrc); +// $image->thumb($mWidth, $mHeight)->save($mSrc,$image->type(),90); +// $image->thumb($mTWidth, $mTHeight, 2)->save($mThumb,$image->type(),90); +// } + + +// } +// /***************************** 添加水印 ***********************************/ +// $isWatermark=(int)input('isWatermark'); +// if($isWatermark==1 && (int)WSTConf('CONF.watermarkPosition')!==0){ +// //取出水印配置 +// $wmWord = WSTConf('CONF.watermarkWord');//文字 +// $wmFile = trim(WSTConf('CONF.watermarkFile'),'/');//水印文件 +// $wmPosition = (int)WSTConf('CONF.watermarkPosition');//水印位置 +// $wmSize = ((int)WSTConf('CONF.watermarkSize')!=0)?WSTConf('CONF.watermarkSize'):'20';//大小 +// $wmColor = (WSTConf('CONF.watermarkColor')!='')?WSTConf('CONF.watermarkColor'):'#000000';//颜色必须是16进制的 +// $wmOpacity = ((int)WSTConf('CONF.watermarkOpacity')!=0)?WSTConf('CONF.watermarkOpacity'):'100';//水印透明度 +// //是否有自定义字体文件 +// $customTtf = $_SERVER['DOCUMENT_ROOT'].WSTConf('CONF.watermarkTtf'); +// $ttf = is_file($customTtf)?$customTtf:EXTEND_PATH.'/verify/verify/ttfs/3.ttf'; +// $image = \image\Image::open($imageSrc); +// if(!empty($wmWord)){//当设置了文字水印 就一定会执行文字水印,不管是否设置了文件水印 + +// //执行文字水印 +// $image->text($wmWord, $ttf, $wmSize, $wmColor, $wmPosition)->save($imageSrc); +// if($thumbSrc!==null){ +// $image->thumb((int)input('width',min(300,$image->width())), (int)input('height',min(300,$image->height())),2)->save($thumbSrc,$image->type(),90); +// } +// //如果有生成手机版原图 +// if(!empty($mSrc)){ +// $image = \image\Image::open($imageSrc); +// $image->thumb($mWidth, $mHeight)->save($mSrc,$image->type(),90); +// $image->thumb($mTWidth, $mTHeight, 2)->save($mThumb,$image->type(),90); +// } +// }elseif(!empty($wmFile)){//设置了文件水印,并且没有设置文字水印 +// //执行图片水印 +// $image->water($wmFile, $wmPosition, $wmOpacity)->save($imageSrc); +// if($thumbSrc!==null){ +// $image->thumb((int)input('width',min(300,$image->width())), (int)input('height',min(300,$image->height())),2)->save($thumbSrc,$image->type(),90); +// } +// //如果有生成手机版原图 +// if($mSrc!==null){ +// $image = \image\Image::open($imageSrc); +// $image->thumb($mWidth, $mHeight)->save($mSrc,$image->type(),90); +// $image->thumb($mTWidth, $mTHeight,2)->save($mThumb,$image->type(),90); +// } +// } +// } +// //判断是否有生成缩略图 +// $thumbSrc = ($thumbSrc==null)?$info->getFilename():str_replace('.','_thumb.', $info->getFilename()); +// $filePath = ltrim($filePath,'/'); +// // 用户头像上传宽高限制 +// $isCut = (int)input('isCut'); +// if($isCut){ +// $imgSrc = $filePath.$info->getFilename(); +// $image = \image\Image::open($imgSrc); +// $size = $image->size();//原图宽高 +// $w = $size[0]; +// $h = $size[1]; +// $rate = $w/$h; +// if($w>$h && $w>500){ +// $newH = 500/$rate; +// $image->thumb(500, $newH)->save($imgSrc,$image->type(),90); +// }elseif($h>$w && $h>500){ +// $newW = 500*$rate; +// $image->thumb($newW, 500)->save($imgSrc,$image->type(),90); +// } +// } +// return json_encode(['status'=>1,'savePath'=>$filePath,'name'=>$info->getFilename(),'thumb'=>$thumbSrc]); +// }else{ +// //上传失败获取错误信息 +// return $file->getError(); +// } +// } +/** + * 上传图片 修改为上传至oss mark 20180609 + * 需要生成缩略图: isThumb=1 + * 需要加水印:isWatermark=1 + * pc版缩略图: width height + * 手机版原图:mWidth mHeight + * 缩略图:mTWidth mTHeight + * 判断图片来源:fromType 0:商家/用户 1:平台管理员 + */ +function WSTUploadPic($fromType=0){ + $fileKey = key($_FILES); + $dir = Input('param.dir'); + if($dir=='')return json_encode(['msg'=>'没有指定文件目录!','status'=>-1]); + $dirs = WSTConf("CONF.wstUploads"); + + if(!in_array($dir, $dirs)){ + return json_encode(['msg'=>'非法文件目录!','status'=>-1]); + } + // 上传文件 + $file = request()->file($fileKey); + if($file===null){ + return json_encode(['msg'=>'上传文件不存在或超过服务器限制','status'=>-1]); + } + $validate = new \think\Validate([ + ['fileMime','fileMime:image/png,image/gif,image/jpeg,image/x-ms-bmp','只允许上传jpg,gif,png,bmp类型的文件'], + ['fileExt','fileExt:jpg,jpeg,gif,png,bmp','只允许上传后缀为jpg,gif,png,bmp的文件'], + ['fileSize','fileSize:2097152','文件大小超出限制'],//最大2M + ]); + $data = ['fileMime' => $file, + 'fileSize' => $file, + 'fileExt'=> $file + ]; + if (!$validate->check($data)) { + return json_encode(['msg'=>$validate->getError(),'status'=>-1]); + } + //原文件名 + $file_name = $_FILES['file']['name']; + //文件大小 + $file_size = $_FILES['file']['size']; + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + //服务器上临时文件 + $filePath = $_FILES['file']['tmp_name']; + //存储在oss上的文件名 + $new_path = 'upload/'.$dir.'/'.date('Y-m').'/'; + $new_name = uniqid(). '.' . $file_ext; + $new_file_name = $new_path.$new_name; + $object = $new_file_name; + + $ossClient = new Aliyunoss(); + //上传 + $res = $ossClient->uploadFile($object, $filePath); + if($res){ + //图片记录 + WSTRecordImages($object,(int)$fromType,$file_size); + //缩略图路径 手机版原图路径 手机版缩略图路径 + $thumbSrc = $mSrc = $mThumb = null; + //获取原图信息 + $imgInfo = $ossClient->getInfo($object); + //原图高宽 + $height = (int)$imgInfo['ImageHeight']['value']; + $width = (int)$imgInfo['ImageWidth']['value']; + //pc版缩略图 + $tWidth = min($width,300); + $tHeight = min($height,300); + //手机版原图宽高 + $mWidth = min($height,(int)input('mWidth',700)); + $mHeight = min($height,(int)input('mHeight',700)); + //手机版缩略图宽高 + $mTWidth = min($width,(int)input('mTWidth',250)); + $mTHeight = min($height,(int)input('mTHeight',250)); + /****************************** 生成缩略图 *********************************/ + $isThumb = (int)input('isThumb'); + if($isThumb==1){ + //缩略图路径 + $thumbSrc =$new_name.'?x-oss-process=image/resize,m_pad,h_'.$tHeight.',w_'.$tWidth; + // $thumbSrc =$new_name.'?x-oss-process=image/resize,m_pad,h_300,w_300'; + + } + // 用户头像上传宽高限制 + $isCut = (int)input('isCut'); + if($isCut){ + // $imgSrc = $filePath.$info->getFilename(); + // $image = \image\Image::open($imgSrc); + // $size = $image->size();//原图宽高 + // $w = $size[0]; + // $h = $size[1]; + // $rate = $w/$h; + $rate = $width/$height; + if($width>$height && $width>500){ + $newH = (int)(500/$rate); + $new_name = $new_name.'?x-oss-process=image/resize,w_500,h_'.$newH; + // $image->thumb(500, $newH)->save($imgSrc,$image->type(),90); + }elseif($height>$width && $height>500){ + $newW = (int)(500*$rate); + $new_name = $new_name.'?x-oss-process=image/resize,h_500,w_'.$newW; + } + } + $thumbSrc = ($thumbSrc==null)?$new_name:$thumbSrc; + return json_encode(['status'=>1,'savePath'=>$new_path,'name'=>$new_name,'thumb'=>$thumbSrc]); + }else{ + return WSTReturn('上传失败',-1); + } +} +/** + * 上传文件 + */ +function WSTUploadFile(){ + $fileKey = key($_FILES); + $dir = Input('post.dir'); + if($dir=='')return json_encode(['msg'=>'没有指定文件目录!','status'=>-1]); + $dirs = WSTConf("CONF.wstUploads"); + if(!in_array($dir, $dirs)){ + return json_encode(['msg'=>'非法文件目录!','status'=>-1]); + } + //上传文件 + $file = request()->file($fileKey); + if($file===null){ + return json_encode(['msg'=>'上传文件不存在或超过服务器限制','status'=>-1]); + } + $validate = new \think\Validate([ + ['fileExt','fileExt:xls,xlsx,xlsm','只允许上传后缀为xls,xlsx,xlsm的文件'] + ]); + $data = ['fileExt'=> $file]; + if (!$validate->check($data)) { + return json_encode(['msg'=>$validate->getError(),'status'=>-1]); + } + $info = $file->rule('uniqid')->move(ROOT_PATH.'/upload/'.$dir."/".date('Y-m')); + //保存路径 + $filePath = $info->getPathname(); + $filePath = str_replace(ROOT_PATH,'',$filePath); + $filePath = str_replace('\\','/',$filePath); + $name = $info->getFilename(); + $filePath = str_replace($name,'',$filePath); + if($info){ + return json_encode(['status'=>1,'name'=>$info->getFilename(),'route'=>$filePath]); + }else{ + //上传失败获取错误信息 + return $file->getError(); + } +} +/** + * 生成默认商品编号/货号 + */ +function WSTGoodsNo($pref = ''){ + return $pref.(round(microtime(true),4)*10000).mt_rand(0,9); +} +/** + * 获取订单统一流水号 + */ +function WSTOrderQnique(){ + return (round(microtime(true),4)*10000).mt_rand(1000,9999); +} + + +/** +* 图片管理 +* @param $imgPath 图片路径 +* @param $fromType 0:用户/商家 1:平台管理员 +* +*/ +// function WSTRecordImages($imgPath, $fromType){ +// $data = []; +// $data['imgPath'] = $imgPath; +// if(file_exists($imgPath)){ +// $data['imgSize'] = filesize($imgPath); //返回字节数 imgsize/1024 k imgsize/1024/1024 m +// } +// //获取表名 +// $table = explode('/',$imgPath); +// $data['fromTable'] = $table[1]; +// $data['fromType'] = (int)$fromType; +// //根据类型判断所有者 +// $data['ownId'] = ((int)$fromType==0)?(int)session('WST_USER.userId'):(int)session('WST_STAFF.staffId'); +// $data['isUse'] = 0; //默认不使用 +// $data['createTime'] = date('Y-m-d H:i:s'); + +// //保存记录 +// Db::name('images')->insert($data); + +// } +/** +* 图片管理 mark 20180308 添加图片大小字段(主要是为了整合oss图片) +* @param $imgPath 图片路径 +* @param $fromType 0:用户/商家 1:平台管理员 +* @param $file_size 图片大小 +*/ +function WSTRecordImages($imgPath, $fromType,$file_size=0){ + $data = []; + $data['imgPath'] = $imgPath; + //更改为可以直接给图片大小 + if(file_exists($imgPath)){ + $data['imgSize'] = filesize($imgPath); //返回字节数 imgsize/1024 k imgsize/1024/1024 m + }else{ + $data['imgSize'] = $file_size; + } + //获取表名 + $table = explode('/',$imgPath); + $data['fromTable'] = $table[1]; + $data['fromType'] = (int)$fromType; + //根据类型判断所有者 + $data['ownId'] = ((int)$fromType==0)?(int)session('WST_USER.userId'):(int)session('WST_STAFF.staffId'); + $data['isUse'] = 0; //默认不使用 + $data['createTime'] = date('Y-m-d H:i:s'); + + //保存记录 + Db::name('images')->insert($data); + +} +// /** +// * 启用图片 +// * @param $fromType 0: 用户/商家 1:平台管理员 +// * @param $dataId 来源记录id +// * @param $imgPath 图片路径,要处理多张图片时请传入一位数组,或用","连接图片路径 +// * @param $fromTable 该记录来自哪张表 +// * @param $imgFieldName 表中的图片字段名称 +// */ +// function WSTUseImages($fromType, $dataId, $imgPath, $fromTable='', $imgFieldName=''){ +// if(empty($imgPath))return; + +// $image['fromType'] = (int)$fromType; +// //根据类型判断所有者 +// $image['ownId'] = ((int)$fromType==0)?(int)session('WST_USER.userId'):(int)session('WST_STAFF.staffId'); +// $image['dataId'] = (int)$dataId; + +// $image['isUse'] = 1;//标记为启用 +// if($fromTable!=''){ +// $tmp = ['','']; +// if(strpos($fromTable,'-')!==false){ +// $tmp = explode('-',$fromTable); +// $fromTable = str_replace('-'.$tmp[1],'',$fromTable); +// } +// $image['fromTable'] = str_replace('_','',$fromTable.$tmp[1]); +// } + +// $imgPath = is_array($imgPath)?$imgPath:explode(',',$imgPath);//转数组 + +// //用于与旧图比较 +// $newImage = $imgPath; + +// // 不为空说明执行修改 +// if($imgFieldName!=''){ +// //要操作的表名 $fromTable; +// // 获取`$fromTable`表的主键 +// $prefix = config('database.prefix'); +// $tableName = $prefix.$fromTable; +// $pk = Db::getTableInfo("$tableName", 'pk'); +// // 取出旧图 +// $oldImgPath = model("$fromTable")->where("$pk",$dataId)->value("$imgFieldName"); +// // 转数组 +// $oldImgPath = explode(',', $oldImgPath); +// // 1.要设置为启用的文件 +// $newImage = array_diff($imgPath, $oldImgPath); +// // 2.要标记为删除的文件 +// $oldImgPath = array_diff($oldImgPath, $imgPath); +// //旧图数组跟新图数组相同则不需要继续执行 +// if($newImage!=$oldImgPath)WSTUnuseImage($oldImgPath); +// } +// if(!empty($newImage)){ +// Db::name('images')->where(['imgPath'=>['in',$newImage]])->update($image); +// } +// } +/** +* 启用图片 修改 适应oss +* @param $fromType 0: 用户/商家 1:平台管理员 +* @param $dataId 来源记录id +* @param $imgPath 图片路径,要处理多张图片时请传入一位数组,或用","连接图片路径 +* @param $fromTable 该记录来自哪张表 +* @param $imgFieldName 表中的图片字段名称 +*/ +function WSTUseImages($fromType, $dataId, $imgPath, $fromTable='', $imgFieldName=''){ + if(empty($imgPath))return; + $image['fromType'] = (int)$fromType; + //根据类型判断所有者 + $image['ownId'] = ((int)$fromType==0)?(int)session('WST_USER.userId'):(int)session('WST_STAFF.staffId'); + $image['dataId'] = (int)$dataId; + + $image['isUse'] = 1;//标记为启用 + if($fromTable!=''){ + $tmp = ['','']; + if(strpos($fromTable,'-')!==false){ + $tmp = explode('-',$fromTable); + $fromTable = str_replace('-'.$tmp[1],'',$fromTable); + } + $image['fromTable'] = str_replace('_','',$fromTable.$tmp[1]); + } + // $imgPath = is_array($imgPath)?$imgPath:explode(',',$imgPath);//转数组 + //修改 去除oss图片后面的参数 + //先判断是不是数组 mark 20180612 + if(is_array($imgPath)){ + foreach ($imgPath as $key => $value) { + if(stripos($value,'?')){ + $imgPath[$key] = strstr($imgPath,'?',true); + } + } + }else{ + if(stripos($imgPath,'?'))$imgPath = strstr($imgPath,'?',true); + } + + $imgPath = is_array($imgPath)?$imgPath:explode(',',$imgPath); + + //用于与旧图比较 + $newImage = $imgPath; + // 不为空说明执行修改 + if($imgFieldName!=''){ + //要操作的表名 $fromTable; + // 获取`$fromTable`表的主键 + $prefix = config('database.prefix'); + $tableName = $prefix.$fromTable; + $pk = Db::getTableInfo("$tableName", 'pk'); + // 取出旧图 + $oldImgPath = model("$fromTable")->where("$pk",$dataId)->value("$imgFieldName"); + // 转数组 + // $oldImgPath = explode(',', $oldImgPath); + // 目前似乎数据库中似乎只有头像有参数 mark 20180612 + if(stripos($oldImgPath,'?')){ + $oldImgPath = strstr($oldImgPath,'?',true); + } + $oldImgPath = explode(',', $oldImgPath); + // 1.要设置为启用的文件 + $newImage = array_diff($imgPath, $oldImgPath); + // 2.要标记为删除的文件 + $oldImgPath = array_diff($oldImgPath, $imgPath); + //旧图数组跟新图数组相同则不需要继续执行 + if($newImage!=$oldImgPath)WSTUnuseImage($oldImgPath); + } + if(!empty($newImage)){ + + $rs = Db::name('images')->where(['imgPath'=>['in',$newImage]])->update($image); + } +} + +/** +* 编辑器图片记录 +* @param $fromType 0: 用户/商家 1:平台管理员 +* @param $dataId 来源记录id +* @param $oldDesc 旧商品描述 +* @param $newDesc 新商品描述 +*/ +function WSTEditorImageRocord($fromType, $dataId, $oldDesc, $newDesc){ + // 解义 + $oldDesc = htmlspecialchars_decode($oldDesc); + $newDesc = htmlspecialchars_decode($newDesc); + //编辑器里的图片 + $rule = '/src=".*?\/(upload.*?)"/'; + // 获取旧的src数组 + preg_match_all($rule,$oldDesc,$images); + $oldImgPath = $images[1]; + preg_match_all($rule,$newDesc,$images); + // 获取新的src数组 + $imgPath = $images[1]; + // 1.要设置为启用的文件 + $newImage = array_diff($imgPath, $oldImgPath); + // 2.要标记为删除的文件 + $oldImgPath = array_diff($oldImgPath, $imgPath); + //旧图数组跟新图数组相同则不需要继续执行 + if($newImage!=$oldImgPath){ + //标记新图启用 + WSTUseImages($fromType, $dataId, $newImage); + //标记旧图删除 + WSTUnuseImage($oldImgPath); + } +} + + +/** +* 标记删除图片 +*/ +function WSTUnuseImage($fromTable, $field = '' , $dataId = 0){ + if($fromTable=='')return; + $imgPath = $fromTable; + if($field!=''){ + $prefix = config('database.prefix'); + $tableName = $prefix.$fromTable; + $pk = Db::getTableInfo("$tableName", 'pk'); + // 取出旧图 + $imgPath = model("$fromTable")->where("$pk",$dataId)->value("$field"); + } + if(!empty($imgPath)){ + $imgPath = is_array($imgPath)?$imgPath:explode(',',$imgPath);//转数组 + Db::name('images')->where(['imgPath'=>['in',$imgPath]])->setField('isUse',0); + } +} +/** + * 获取系统根目录 + */ +function WSTRootPath(){ + return dirname(dirname(dirname(dirname(__File__)))); +} +/** + * 切换图片 + * @param $imgurl 图片路径 + * @param $imgType 图片类型 0:PC版大图 1:PC版缩略图 2:移动版大图 3:移动版缩略图 + * 图片规则 + * PC版版大图 :201635459344.jpg + * PC版版缩略图 :201635459344_thumb.jpg + * 移动版大图 :201635459344_m.jpg + * 移动版缩略图 :201635459344_m_thumb.jpg + */ +// function WSTImg($imgurl,$imgType = 1){ +// $m = WSTConf('CONF.wstMobileImgSuffix'); +// $imgurl = str_replace($m.'.','.',$imgurl); +// $imgurl = str_replace($m.'_thumb.','.',$imgurl); +// $imgurl = str_replace('_thumb.','.',$imgurl); +// $img = ''; +// switch ($imgType){ +// case 0:$img = $imgurl;break; +// case 1:$img = str_replace('.','_thumb.',$imgurl);break; +// case 2:$img = str_replace('.',$m.'.',$imgurl);break; +// case 3:$img = str_replace('.',$m.'_thumb.',$imgurl);break; +// } +// return ((file_exists(WSTRootPath()."/".$img))?$img:$imgurl); +// } + +/** + * [WSTImg 切换图片] + * @param [type] $imgurl [图片路径] + * @param integer $imgType [图片类型 0:PC版大图 1:PC版缩略图 2:移动版大图 3:移动版缩略图] + */ +function WSTImg($imgurl,$imgType = 1){ + $oss_imgurl = getImgUrl(); + $m = WSTConf('CONF.wstMobileImgSuffix'); + $imgurl = str_replace($m.'.','.',$imgurl); + $imgurl = str_replace($m.'_thumb.','.',$imgurl); + $imgurl = str_replace('_thumb.','.',$imgurl); + $img = ''; + switch($imgType){ + case 0:$img = $imgurl;break; + case 1:$img = $imgurl.'?x-oss-process=image/resize,m_pad,h_300,w_300';break; + case 2:$img = $imgurl.'?x-oss-process=image/resize,h_750,w_750';break; + case 3:$img = $imgurl.'?x-oss-process=image/resize,h_250,w_250';break; + } + return $img; +} + +/** + * 根据送货城市获取运费 + * @param $cityId 送货城市Id + * @param @shopIds 店铺ID + */ +function WSTOrderFreight($shopId,$cityId){ + $goodsFreight = ['total'=>0,'shops'=>[]]; + $rs = Db::name('shops')->alias('s')->join('__SHOP_FREIGHTS__ sf','s.shopId=sf.shopId and sf.areaId2='.$cityId,'left') + ->where(['s.shopId'=>$shopId])->field('s.freight,sf.freightId,sf.freight freight2')->find(); + if(empty($rs))return 0; + if((int)$rs['freight']<0)$rs['freight'] = 0; + if((int)$rs['freight2']<0)$rs['freight2'] = 0; + return (int)((int)$rs['freightId']>0)?$rs['freight2']:$rs['freight']; +} +/** + * 生成订单号 + */ +function WSTOrderNo(){ + $orderId = Db::name('orderids')->insertGetId(['rnd'=>time()]); + return $orderId.(fmod($orderId,7)); +} +/** + * 高精度数字相加 + * @param $num + * @param number $i 保留小数位 + */ +function WSTBCMoney($num1,$num2,$i=2){ + $num = bcadd($num1, $num2, $i); + return (float)$num; +} +/** + * 获取支付方式 + */ +function WSTLangPayType($v){ + switch($v){ + case 0:return '货到付款'; + case 1:return '在线支付'; + } +} +/** + * 收货方式 + */ +function WSTLangDeliverType($v){ + switch ($v) { + case 1:return "自提"; + case 0:return "送货上门"; + } +} +/** + * 订单状态 + */ +function WSTLangOrderStatus($v){ + switch($v){ + case -3:return '用户拒收'; + case -2:return '待支付'; + case -1:return '已取消'; + case 0:return '待发货'; + case 1:return '待收货'; + case 2:return '已收货'; + } +} +/** + * 惠宝来源 + */ +function WSTLangScore($v){ + switch($v){ + case 1:return '商品订单'; + case 2:return '评价订单'; + case 4:return '退款订单'; + case 5:return '惠宝签到'; + case 10001:return '管理员'; + default:return '其他'; + } +} +/** + * 资金来源 + */ +function WSTLangMoneySrc($v){ + switch($v){ + case 1:return '商品订单'; + case 2:return '订单结算'; + case 3:return '提现申请'; + case 4:return '钱包充值'; + default:return '其他'; + } +} +/** + * 投诉状态 + */ +function WSTLangComplainStatus($v){ + switch($v){ + case 0:return '等待处理'; + case 1:return '等待应诉人应诉'; + case 2:return '应诉人已应诉'; + case 3:return '等待仲裁'; + case 4:return '已仲裁'; + } +} +/** + * 支付来源 + */ +function WSTLangPayFrom($pkey){ + $paySrc = cache('WST_PAY_SRC'); + if(!$paySrc){ + $paySrc = Db::name('payments')->order('payOrder asc')->select(); + cache('WST_PAY_SRC',$paySrc,31622400); + } + foreach($paySrc as $v){ + if($pkey==$v['payCode'])return $v['payName']; + } + return '其他'; +} + +/** + * 插件状态 + */ +function WSTLangAddonStatus($v){ + switch($v){ + case 0:return '未安装'; + case 1:return '启用'; + case 2:return '禁用'; + } +} + +/** + * 获取业务数据内容【根据catCode获取】 + */ +function WSTDatas($catCode,$id = 0){ + $catId = (int)Db::name('data_cats')->where(['catCode'=>$catCode])->value('catId'); + $data = cache('WST_DATAS'); + if(!$data){ + $rs = Db::name('datas')->where(['dataFlag'=>1])->order('catId asc,dataSort asc,id asc')->select(); + $data = []; + foreach ($rs as $key =>$v){ + $data[$v['catId']][$v['dataVal']] = $v; + } + cache('WST_DATAS',$data,378432000); + } + if(isset($data[$catId])){ + if($id==0)return $data[$catId]; + return isset($data[$catId][$id])?$data[$catId][$id]:''; + } + return []; +} +/** + * 获取消息模板 + */ +function WSTMsgTemplates($tplCode){ + $data = cache('WST_MSG_TEMPLATES'); + if(!$data){ + $rs = Db::name('template_msgs')->order('id asc')->select(); + $data = []; + foreach ($rs as $key =>$v){ + if($v['tplType']==3 && (int)WSTConf('CONF.wxenabled')==1){ + $ps = Db::name('wx_template_params')->where('parentId',$v['id'])->select(); + $v['params'] = $ps; + } + if($v['tplContent']==''){ + $data[$v['tplCode']] = $v; + }else{ + $v['content'] = htmlspecialchars_decode($v['tplContent']); + $v['tplContent'] = strip_tags(htmlspecialchars_decode($v['tplContent'])); + $data[$v['tplCode']] = $v; + } + } + cache('WST_MSG_TEMPLATES',$data,378432000); + } + return (isset($data[$tplCode]))?$data[$tplCode]:null; +} +/** + * 发送微信消息 + */ +function WSTWxMessage($params){ + $tpl = WSTMsgTemplates($params['CODE']); + if($tpl && file_exists('wstmart'.DS.'wechat'.DS.'behavior'.DS.'InitWechatMessges.php')){ + \think\Hook::exec('wstmart\\wechat\\behavior\\InitWechatMessges','run',$params); + } +} +/** + * 批量发送微信消息 + */ +function WSTWxBatchMessage($params){ + $tpl = WSTMsgTemplates($params['CODE']); + if($tpl && file_exists('wstmart'.DS.'wechat'.DS.'behavior'.DS.'InitWechatMessges.php')){ + \think\Hook::exec('wstmart\\wechat\\behavior\\InitWechatMessges','batchRun',$params); + } +} +/** + * 截取字符串 + */ +function WSTMSubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = false){ + $newStr = ''; + if (function_exists ( "mb_substr" )) { + $newStr = mb_substr ( $str, $start, $length, $charset ); + if ($suffix && (mb_strlen($str,$charset)>$length))$newStr .= "..."; + } elseif (function_exists ( 'iconv_substr' )) { + $newStr = iconv_substr( $str, $start, $length, $charset ); + if ($suffix && (mb_strlen($str,$charset)>$length))$newStr .= "..."; + } + if($newStr==''){ + $re ['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; + $re ['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; + $re ['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; + $re ['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; + preg_match_all ( $re [$charset], $str, $match ); + $slice = join ( "", array_slice ( $match [0], $start, $length ) ); + if ($suffix) + $newStr = $slice; + } + return $newStr; +} +function WSTScore($score,$users,$type = 5,$len = 0,$total = 1){ + if((int)$score==0)return $type; + switch($type){ + case 5:return round($score/$total/$users,0); + case 10:return round($score/$total*2/$users,$len); + case 100:return round($score/$total*2/$users,$len); + } +} +function WSTShopEncrypt($shopId){ + return md5(base64_encode("wstmart".date("Y-m-d").$shopId)); +} +/** + * 根据子分类循环获取其父级分类 + */ +function WSTGoodsCatPath($catId, $data = []){ + if($catId==0)return $data; + $data[] = $catId; + $parentId = Db::name('goods_cats')->where('catId',$catId)->value('parentId'); + if($parentId==0){ + krsort($data); + return $data; + }else{ + return WSTGoodsCatPath($parentId, $data); + } +} +/** + * 提供原生分页处理 + */ +function WSTPager($total,$rs,$page,$size = 0){ + $pageSize = ($size>0)?$size:config('paginate.list_rows'); + $totalPage = ($total%$pageSize==0)?($total/$pageSize):(intval($total/$pageSize)+1); + return ['Total'=>$total,'PerPage'=>$pageSize,'CurrentPage'=>$page,'TotalPage'=>$totalPage,'Rows'=>$rs]; +} + + +/** +* 编辑器上传图片 +*/ +// function WSTEditUpload($fromType){ +// $root = str_replace('/index.php','',\think\Request::instance()->root()); +// //PHP上传失败 +// if (!empty($_FILES['imgFile']['error'])) { +// switch($_FILES['imgFile']['error']){ +// case '1': +// $error = '超过php.ini允许的大小。'; +// break; +// case '2': +// $error = '超过表单允许的大小。'; +// break; +// case '3': +// $error = '图片只有部分被上传。'; +// break; +// case '4': +// $error = '请选择图片。'; +// break; +// case '6': +// $error = '找不到临时目录。'; +// break; +// case '7': +// $error = '写文件到硬盘出错。'; +// break; +// case '8': +// $error = 'File upload stopped by extension。'; +// break; +// case '999': +// default: +// $error = '未知错误。'; +// } +// return WSTReturn(1,$error); +// } + +// $fileKey = key($_FILES); +// $dir = 'image'; // 编辑器上传图片目录 +// $dirs = WSTConf("CONF.wstUploads"); +// if(!in_array($dir, $dirs)){ +// return json_encode(['error'=>1,'message'=>'非法文件目录!']); +// } +// // 上传文件 +// $file = request()->file($fileKey); +// if($file===null){ +// return json_encode(["error"=>1,"message"=>'上传文件不存在或超过服务器限制']); +// } +// $validate = new \think\Validate([ +// ['fileMime','fileMime:image/png,image/gif,image/jpeg,image/x-ms-bmp','只允许上传jpg,gif,png,bmp类型的文件'], +// ['fileExt','fileExt:jpg,jpeg,gif,png,bmp','只允许上传后缀为jpg,gif,png,bmp的文件'], +// ['fileSize','fileSize:2097152','文件大小超出限制'],//最大2M +// ]); +// $data = ['fileMime' => $file, +// 'fileSize' => $file, +// 'fileExt'=> $file +// ]; +// if (!$validate->check($data)) { +// return json_encode(['message'=>$validate->getError(),'error'=>1]); +// } +// $info = $file->rule('uniqid')->move(ROOT_PATH.'/upload/'.$dir."/".date('Y-m')); +// if($info){ +// $filePath = $info->getPathname(); +// $filePath = str_replace(ROOT_PATH,'',$filePath); +// $filePath = str_replace('\\','/',$filePath); +// $name = $info->getFilename(); +// $imageSrc = trim($filePath,'/'); +// //图片记录 +// WSTRecordImages($imageSrc, (int)$fromType); +// return json_encode(array('error' => 0, 'url' => $root.$filePath)); +// } +// } + /** + * 编辑器上传图片 修改成上传到oss mark 20180607 + */ +function WSTEditUpload($fromType){ + //PHP上传失败 + if (!empty($_FILES['imgFile']['error'])) { + switch($_FILES['imgFile']['error']){ + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + return WSTReturn(1,$error); + } + + $fileKey = key($_FILES); + // $dir = 'image'; // 编辑器上传图片目录 + $dir = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + $dirs = WSTConf("CONF.wstUploads"); + if(!in_array($dir, $dirs)){ + return json_encode(['error'=>1,'message'=>'非法文件目录!']); + } + // 上传文件 + $file = request()->file($fileKey); + if($file===null){ + return json_encode(["error"=>1,"message"=>'上传文件不存在或超过服务器限制']); + } + $validate = new \think\Validate([ + ['fileMime','fileMime:image/png,image/gif,image/jpeg,image/x-ms-bmp','只允许上传jpg,gif,png,bmp类型的文件'], + ['fileExt','fileExt:jpg,jpeg,gif,png,bmp','只允许上传后缀为jpg,gif,png,bmp的文件'], + ['fileSize','fileSize:2097152','文件大小超出限制'],//最大2M + ]); + $data = ['fileMime' => $file, + 'fileSize' => $file, + 'fileExt'=> $file + ]; + if (!$validate->check($data)) { + return json_encode(['message'=>$validate->getError(),'error'=>1]); + } + + //原文件名 + $file_name = $_FILES['imgFile']['name']; + //文件大小 + $file_size = $_FILES['imgFile']['size']; + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + //服务器上临时文件 + $filePath = $_FILES['imgFile']['tmp_name']; + //存储在oss上的文件名 + $new_file_name = 'upload/'.$dir.'/'.date('Y-m').'/'.uniqid(). '.' . $file_ext; + $object = $new_file_name; + try{ + $ossClient = new Aliyunoss(); + //上传 + $ossClient->uploadFile($object, $filePath); + $file_url = getImgUrl().$object; + WSTRecordImages($object, (int)$fromType,$file_size); + return json_encode(array('error'=>0,'url'=>$file_url)); + + } catch(Exception $e) { + printf($e->getMessage() . "\n"); + return; + } +} + +/** + * 转义单引号 + */ +function WSTHtmlspecialchars($v){ + return htmlspecialchars($v,ENT_QUOTES); +} + +/** +* 发送商城消息 +* @param int $to 接受者d +* @param string $content 内容 +* @param array $msgJson 存放json数据 +*/ +function WSTSendMsg($to,$content,$msgJson=[],$msgType = 1){ + $message = []; + $message['msgType'] = $msgType; + $message['sendUserId'] = 1; + $message['createTime'] = date('Y-m-d H:i:s'); + $message['msgStatus'] = 0; + $message['dataFlag'] = 1; + $message['from'] = (int)$msgJson['from'];//添加指定消息来源 mark hsf 20180117 + $message['receiveUserId'] = $to; + $message['msgContent'] = $content; + $message['msgJson'] = json_encode($msgJson); + Db::name('messages')->insert($message); + +} + +/** + * 获取分类的佣金 + +function WSTGoodsCommissionRate($goodsCatId){ + $cats = Db::name('goods_cats')->where('catId',$goodsCatId)->field('parentId,commissionRate')->find(); + if(empty($cats)){ + return 0; + }else{ + if((float)$cats['commissionRate']>=0)return (float)$cats['commissionRate']; + return WSTGoodsCommissionRate($cats['parentId']); + } +} + */ +function WSTFormatIn($split,$str){ + $strdatas = explode($split,$str); + $data = array(); + for($i=0;$i<count($strdatas);$i++){ + $data[] = (int)$strdatas[$i]; + } + $data = array_unique($data); + return implode($split,$data); +} + +function WSTRandStr($len = 6){ + $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + $tmp = ''; + for($i=0;$i<$len;$i++){ + $tmp.=$str[rand(0,35)]; + } + return $tmp; +} +/** + * 金额兑惠宝 + */ +function WSTMoneyGiftScore($money){ + $moneyToScore = (float)WSTConf('CONF.moneyToScore'); + return intval($money*$moneyToScore); +} +/** + * 惠宝兑金额 + * $isBack=true则$score实际上传入金额,通过金额反推需要兑换的惠宝 + */ +function WSTScoreToMoney($score,$isBack = false){ + $scoreToMoney = (int)WSTConf('CONF.scoreToMoney'); + if($scoreToMoney<=0)return 0; + if($isBack){ + return round(strval($score*$scoreToMoney),2); + }else{ + return round($score/$scoreToMoney,2); + } +} +/** + * 头像处理 + */ +// function WSTUserPhoto($userPhoto=''){ +// if(substr($userPhoto,0,4)!='http' && $userPhoto){ +// $userPhoto = '__ROOT__/'.$userPhoto; +// }else if(!$userPhoto){ +// $userPhoto = '__ROOT__/'.WSTConf('CONF.userLogo'); +// } +// return $userPhoto; +// } +/** + * 头像处理 去除 mark + */ +function WSTUserPhoto($userPhoto=''){ + if(substr($userPhoto,0,4)!='http' && $userPhoto){ + $userPhoto = '/'.$userPhoto; + }else if(!$userPhoto){ + $userPhoto = '/'.WSTConf('CONF.userLogo'); + } + return $userPhoto; +} + +function WSTClearHookCache(){ + WSTConf('listenUrl',null); + $STAFF = session('WST_STAFF'); + if(!empty($STAFF)){ + //获取角色权限 + $STAFF['privileges'] = Db::name('privileges')->where(['dataFlag'=>1])->column('privilegeCode'); + $STAFF['menuIds'] = Db::name('menus')->where('dataFlag',1)->column('menuId'); + session('WST_STAFF',$STAFF); + } + WSTConf('protectedUrl',null); + cache('WST_HOME_MENUS',null); + cache('WST_PRO_MENUS',null); + cache('WST_MOBILE_BTN',null); + cache('hooks',null); + cache('WST_ADDONS',null); + WSTConf('WST_ADDONS',null); +} +/** + * 获取移动端首页按钮 + */ +function WSTMobileBtns($src){ + $data = cache('WST_MOBILE_BTN'); + if(!$data){ + $rs = Db::name('mobile_btns')->order('btnSort asc')->select(); + $data = []; + foreach ($rs as $key => $v) { + $data[$v['btnSrc']][] = $v; + } + cache('WST_MOBILE_BTN',$data,31536000); + } + return $data[$src]; +} + +/** + * 获取星期几 + */ +function WSTgetWeek($date){ + //强制转换日期格式 + $date_str=date('Y-m-d',strtotime($date)); + $number_wk=date("w",strtotime($date)); + $weekArr=array("星期日","星期一","星期二","星期三","星期四","星期五","星期六"); + return $weekArr[$number_wk]; +} +/** + * 获取路由规则 + */ +function WSTRoute(){ + $data = cache('WST_ROUTES'); + if(!$data){ + $routes = \think\Route::rules('*'); + $data = []; + foreach ($routes as $key => $v) { + if($v['rule']=='addon/:route')continue; + $data[$v['route']] = $v['rule']; + } + cache('WST_ROUTES',$data,31536000); + } + return json_encode($data); +} + +/** + * 获取项目根路径 + */ +function WSTRoot(){ + $url = request()->root(true); + $data = explode("/index.php",$url); + return $data[0]; +} + +/** + * URL 64位加密处理 + * @param string $data 字符串内容 + * @param boolean $isEncode true:编码 false:解码 + */ +function WSTBase64url($data,$isEncode = true) { + return ($isEncode)?rtrim(strtr(base64_encode($data), '+/', '-_'), '='):base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); +} + +/** + * 将空内容设置为特定内容 + * @param [type] $[name] [description] + */ +function WSTBlank($v,$defaultValue = ''){ + if($v=='')return $defaultValue; + if($v=='0000-00-00')return $defaultValue; + if($v=='0000-00-00 00:00:00')return $defaultValue; +} + +/** + * 判断访问端来源 + */ +function WSTVisitModule(){ + $request = request(); + if($request->isMobile()){ + return (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false)?'wechat':'mobile'; + } + return 'home'; +} +/** +* 获取图片颜色 +* @imgUrl 图片地址 +*/ +function WSTImgColor($imgUrl){ + $imageInfo = getimagesize($imgUrl); + //图片类型 + $imgType = strtolower(substr(image_type_to_extension($imageInfo[2]), 1)); + //对应函数 + $imageFun = 'imagecreatefrom' . ($imgType == 'jpg' ? 'jpeg' : $imgType); + $im = $imageFun($imgUrl); + $rgb = imagecolorat ( $im , 10 , 15 ); + $arr = array(); + $arr['r'] = ( $rgb >> 16 ) & 0xFF ; + $arr['g'] = ( $rgb >> 8 ) & 0xFF ; + $arr['b'] = $rgb & 0xFF ; + return implode(',',$arr); +} + +/** + * 获取用户等级 + */ +function WSTUserRank($userScore){ + $data = cache('WST_USER_RANK'); + if(!$data){ + $data = Db::name('user_ranks')->where('dataFlag',1)->order('startScore asc,rankId desc')->select(); + cache('WST_USER_RANK',$data,2592000); + } + if(!$data)$data = []; + foreach ($data as $key => $v) { + if($userScore>=$v['startScore'] && $userScore<=$v['endScore'])return $v; + } + return ['rankName'=>'','rankId'=>0,'userrankImg'=>'']; + +} + +/** + * 获取购物车数量 + */ +function WSTCartNum(){ + $userId = session('WST_USER.userId'); + $cartNum = Db::name('carts')->where(['userId'=>$userId])->field('cartId')->select(); + $count = count($cartNum); + return $count; +} +/** +* 增加文章访问数 +*/ +function WSTArticleVisitorNum($id){ + Db::name('articles')->where(['articleId'=>$id])->setInc('visitorNum',1); +} + +/** + * 保持数值为大于0的数值 + */ +function WSTPositiveNum($num){ + return ($num>0)?$num:0; +} + +/** + * 将字符串转换为时间戳,解决部分服务器时间不能超过2038的问题 + */ +function WSTStrToTime($str){ + if(strtotime('2099-09-09 23:59:59')){ + return strtotime($str); + }else{ + $date = new DateTime($str); + return $date->format('U'); + } +} + +/** + * 计算剩余时间 + */ +function WSTTimeToStr($second){ + $day = floor($second/(3600*24)); + $second = $second%(3600*24);//除去整天之后剩余的时间 + $hour = floor($second/3600); + $second = $second%3600;//除去整小时之后剩余的时间 + $minute = floor($second/60); + $second = $second%60;//除去整分钟之后剩余的时间 + //返回字符串 + return (($day>0)?($day.'天'):"").($hour<10?"0".$hour:$hour).':'.($minute<10?"0".$minute:$minute).':'.($second<10?"0".$second:$second); +} + +/** + * 适应mmgrid的表格返回结构 + */ +function WSTGrid($page){ + if(!is_array($page))$page = $page->toArray(); + $rs = ['status'=>1,'msg'=>'','items'=>$page['Rows'],'totalCount'=>$page['Total']]; + return $rs; +} + +/** + * RSA解密 + */ +function WSTRSA($hex_encrypt_data){ + $hex_encrypt_data = trim($hex_encrypt_data); + $isCrypt = WSTConf('CONF.isCryptPwd'); + if($isCrypt==0)return WSTReturn('success',1,$hex_encrypt_data); + + $private_key = WSTConf('CONF.pwdPrivateKey'); + if($private_key=='')return WSTReturn('fail'); + try{ + $encrypt_data = pack("H*", $hex_encrypt_data); //对十六进制数据进行转换 + openssl_private_decrypt($encrypt_data, $decrypt_data, $private_key); //解密数据 + return WSTReturn('success',1,$decrypt_data); + }catch(\Exception $e){ + return WSTReturn('fail'); + } +} +/** + * 获取订单来源提示 + */ +function WSTOrderCodeTitle($orderCode){ + $addonMaps = model("common/addons")->getAddonsMaps(); + $title = array_key_exists($orderCode,$addonMaps)?$addonMaps[$orderCode]:"普通订单"; + return $title; +} + +/** + * 循环删除指定目录下的文件及文件夹 + * @param string $dirpath 文件夹路径 + */ +function WSTDelDir($dirpath){ + $dh=opendir($dirpath); + while (($file=readdir($dh))!==false) { + if($file!="." && $file!="..") { + $fullpath=$dirpath."/".$file; + if(!is_dir($fullpath)) { + unlink($fullpath); + } else { + WSTDelDir($fullpath); + @rmdir($fullpath); + } + } + } + closedir($dh); + $isEmpty = true; + $dh=opendir($dirpath); + while (($file=readdir($dh))!== false) { + if($file!="." && $file!="..") { + $isEmpty = false; + break; + } + } + return $isEmpty; +} + +/** + * 清除整个所有缓存 + * 注意:此函数非迫不得己不要调用。能删除指定缓存的就尽量删除指定缓存。尽量只在后台管理员才做时调用,前台用户操作就不要调用了 + */ +function WSTClearAllCache(){ + cache(null); +} +function WSTShopOrderMenus(){ + $wst_user = session('WST_USER'); + $orderMenus = array("waitPay"=>"home/orders/waituserPay", + "waitDeliver"=>"home/orders/waitdelivery", + "waitReceive"=>"home/orders/delivered", + "abnormal"=>"home/orders/failure", + "finish"=>"home/orders/finished"); + if(!empty($wst_user)){ + $roleId = isset($wst_user["roleId"])?(int)$wst_user["roleId"]:0; + if($roleId>0){ + $shopMenuUrls = model("common/HomeMenus")->getShopMenuUrls(); + foreach ($orderMenus as $key => $menuUrl) { + if(!in_array($menuUrl,$shopMenuUrls)){ + unset($orderMenus[$key]); + } + } + } + } + if(count($orderMenus)==5){ + $orderMenus["all"] = ""; + } + return $orderMenus; +} diff --git a/hyhproject/common/conf/admin/tags.php b/hyhproject/common/conf/admin/tags.php new file mode 100755 index 0000000..020bc78 --- /dev/null +++ b/hyhproject/common/conf/admin/tags.php @@ -0,0 +1,15 @@ +<?php +/** + * ============================================================================ + */ +return [ + 'module_init'=> [ + 'wstmart\\admin\\behavior\\InitConfig' + ], + 'action_begin'=> [ + 'wstmart\\admin\\behavior\\ListenLoginStatus', + 'wstmart\\admin\\behavior\\ListenPrivilege', + 'wstmart\\admin\\behavior\\ListenOperate' + ] +] +?> \ No newline at end of file diff --git a/hyhproject/common/conf/app/config.php b/hyhproject/common/conf/app/config.php new file mode 100755 index 0000000..197cb87 --- /dev/null +++ b/hyhproject/common/conf/app/config.php @@ -0,0 +1,16 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + 'exception_handle' => '\\wstmart\\common\\exception\\WstAppHttpException', + // 默认输出类型 + 'default_return_type' => 'json', +]; diff --git a/hyhproject/common/conf/app/route.php b/hyhproject/common/conf/app/route.php new file mode 100755 index 0000000..023a715 --- /dev/null +++ b/hyhproject/common/conf/app/route.php @@ -0,0 +1,25 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- +\think\Route::rule([ + 'mselfshop'=>'app/shops/selfshop', //自营店铺 + 'mbrands'=>'app/brands/index', //自营店铺 + 'mstreet'=>'app/shops/shopstreet', //自营店铺 + 'mlogin'=>'app/users/login', //用户登录 + 'mregister'=>'app/users/toregister', //用户注册 + 'mforget'=>'app/users/forgetpass', //找回密码 + 'mgoods-<goodsId>'=>'app/goods/detail', + 'mshops-<shopId>'=>'app/shops/index', + 'mhshops-<shopId>'=>'app/shops/home', + 'mlist'=>'app/goods/lists', + 'mnews'=>'app/news/view', + 'mcategoty'=>'app/goodscats/index', + 'mshopgoods'=>'app/shops/shopgoodslist', +]); \ No newline at end of file diff --git a/hyhproject/common/conf/config.php b/hyhproject/common/conf/config.php new file mode 100755 index 0000000..68e9e82 --- /dev/null +++ b/hyhproject/common/conf/config.php @@ -0,0 +1,236 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + // +---------------------------------------------------------------------- + // | 应用设置 + // +---------------------------------------------------------------------- + // 应用调试模式 + 'app_debug' => true, + // 应用Trace + 'app_trace' => false, + // 应用模式状态 + 'app_status' => '', + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => [], + // 扩展配置文件 + 'extra_config_list' => ['database', 'validate'], + // 扩展函数文件 + 'extra_file_list' => [THINK_PATH.'helper'.EXT,WST_COMM."function.php",WST_HOME_COMM."function.php",WST_ADMIN_COMM."function.php"], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'PRC', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => 'trim,WSTHtmlspecialchars', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'home', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空控制器名 + 'empty_controller' => '', + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => true, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由 + 'url_route_on' => true, + // 路由配置文件(支持配置多个) + 'route_config_file' => ['route','mobile'.DS.'route'], + // 是否强制使用路由 + 'url_route_must' => false, + // 域名部署 + 'url_domain_deploy' => true, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + + // +---------------------------------------------------------------------- + // | 模板设置 + // +---------------------------------------------------------------------- + + 'template' => [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DS, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + + // 预加载自定义模板标签 + 'taglib_pre_load' => 'wstmart\common\taglib\Wst', + + ], + + // 视图输出字符串内容替换 + 'view_replace_str' => [ + '__ROOT__'=>str_replace('/index.php','',\think\Request::instance()->root()), + '__APP__'=>\think\Request::instance()->root(), + '__STATIC__'=>str_replace('/index.php','',\think\Request::instance()->root()).'/static', + '__IMGURL__'=>'http://img.zgqlg.com.cn' + ], + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + + // +---------------------------------------------------------------------- + // | 异常及错误设置 + // +---------------------------------------------------------------------- + + // 异常页面的模板文件 + 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => true, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '\\wstmart\\common\\exception\\WstHttpException', + + // +---------------------------------------------------------------------- + // | 日志设置 + // +---------------------------------------------------------------------- + + 'log' => [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => LOG_PATH, + // 日志记录级别 + 'level' => [], + ], + + // +---------------------------------------------------------------------- + // | Trace设置 开启 app_trace 后 有效 + // +---------------------------------------------------------------------- + 'trace' => [ + // 内置Html Console 支持扩展 + 'type' => 'Html', + ], + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => 'WSTMART_', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + ], + + // +---------------------------------------------------------------------- + // | 会话设置 + // +---------------------------------------------------------------------- + + 'session' => [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'hyh_', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + + // +---------------------------------------------------------------------- + // | Cookie设置 + // +---------------------------------------------------------------------- + 'cookie' => [ + // cookie 名称前缀 + 'prefix' => 'WSTMART_', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ], + + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ] +]; diff --git a/hyhproject/common/conf/config2.php b/hyhproject/common/conf/config2.php new file mode 100755 index 0000000..b7c46c1 --- /dev/null +++ b/hyhproject/common/conf/config2.php @@ -0,0 +1,236 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + // +---------------------------------------------------------------------- + // | 应用设置 + // +---------------------------------------------------------------------- + // 应用调试模式 + 'app_debug' => true, + // 应用Trace + 'app_trace' => false, + // 应用模式状态 + 'app_status' => '', + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => [], + // 扩展配置文件 + 'extra_config_list' => ['database', 'validate'], + // 扩展函数文件 + 'extra_file_list' => [THINK_PATH.'helper'.EXT,WST_COMM."function.php",WST_HOME_COMM."function.php",WST_ADMIN_COMM."function.php"], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'PRC', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => 'trim,WSTHtmlspecialchars', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'home', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空控制器名 + 'empty_controller' => '', + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => true, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由 + 'url_route_on' => true, + // 路由配置文件(支持配置多个) + 'route_config_file' => ['route','mobile'.DS.'route'], + // 是否强制使用路由 + 'url_route_must' => false, + // 域名部署 + 'url_domain_deploy' => true, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + + // +---------------------------------------------------------------------- + // | 模板设置 + // +---------------------------------------------------------------------- + + 'template' => [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 模板路径 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DS, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + + // 预加载自定义模板标签 + 'taglib_pre_load' => 'wstmart\common\taglib\Wst', + + ], + + // 视图输出字符串内容替换 + 'view_replace_str' => [ + '__ROOT__'=>str_replace('/index.php','',\think\Request::instance()->root()), + '__APP__'=>\think\Request::instance()->root(), + '__STATIC__'=>str_replace('/index.php','',\think\Request::instance()->root()).'/static', + '__IMGURL__'=>'http://img.heyuanhui.cn' + ], + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + + // +---------------------------------------------------------------------- + // | 异常及错误设置 + // +---------------------------------------------------------------------- + + // 异常页面的模板文件 + 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => true, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '\\wstmart\\common\\exception\\WstHttpException', + + // +---------------------------------------------------------------------- + // | 日志设置 + // +---------------------------------------------------------------------- + + 'log' => [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => LOG_PATH, + // 日志记录级别 + 'level' => [], + ], + + // +---------------------------------------------------------------------- + // | Trace设置 开启 app_trace 后 有效 + // +---------------------------------------------------------------------- + 'trace' => [ + // 内置Html Console 支持扩展 + 'type' => 'Html', + ], + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => 'WSTMART_', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + ], + + // +---------------------------------------------------------------------- + // | 会话设置 + // +---------------------------------------------------------------------- + + 'session' => [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'hyh_', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + ], + + // +---------------------------------------------------------------------- + // | Cookie设置 + // +---------------------------------------------------------------------- + 'cookie' => [ + // cookie 名称前缀 + 'prefix' => 'WSTMART_', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ], + + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ] +]; diff --git a/hyhproject/common/conf/home/tags.php b/hyhproject/common/conf/home/tags.php new file mode 100755 index 0000000..09875e0 --- /dev/null +++ b/hyhproject/common/conf/home/tags.php @@ -0,0 +1,13 @@ +<?php +/** + * ============================================================================ + */ +return [ + 'module_init'=> [ + 'wstmart\\home\\behavior\\InitConfig' + ], + 'action_begin'=> [ + 'wstmart\\home\\behavior\\ListenProtectedUrl' + ] +] +?> \ No newline at end of file diff --git a/hyhproject/common/conf/mobile/config.php b/hyhproject/common/conf/mobile/config.php new file mode 100755 index 0000000..7268eae --- /dev/null +++ b/hyhproject/common/conf/mobile/config.php @@ -0,0 +1,14 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + 'exception_handle' => '\\wstmart\\common\\exception\\WstMoblieHttpException', +]; diff --git a/hyhproject/common/conf/mobile/route.php b/hyhproject/common/conf/mobile/route.php new file mode 100755 index 0000000..99a9df1 --- /dev/null +++ b/hyhproject/common/conf/mobile/route.php @@ -0,0 +1,25 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- +\think\Route::rule([ + 'mselfshop'=>'mobile/shops/selfshop', //自营店铺 + 'mbrands'=>'mobile/brands/index', //自营店铺 + 'mstreet'=>'mobile/shops/shopstreet', //自营店铺 + 'mlogin'=>'mobile/users/login', //用户登录 + 'mregister'=>'mobile/users/toregister', //用户注册 + 'mforget'=>'mobile/users/forgetpass', //找回密码 + 'mgoods-<goodsId>'=>'mobile/goods/detail', + 'mshops-<shopId>'=>'mobile/shops/index', + 'mhshops-<shopId>'=>'mobile/shops/home', + 'mlist'=>'mobile/goods/lists', + 'mnews'=>'mobile/news/view', + 'mcategoty'=>'mobile/goodscats/index', + 'mshopgoods'=>'mobile/shops/shopgoodslist', +]); \ No newline at end of file diff --git a/hyhproject/common/conf/route.php b/hyhproject/common/conf/route.php new file mode 100755 index 0000000..b7d6aae --- /dev/null +++ b/hyhproject/common/conf/route.php @@ -0,0 +1,34 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- +\think\Route::rule([ + //PC版优化 + 'index'=>'home/index/index', //商品分类 + 'category-<cat>'=>'home/goods/lists', //商品分类 + 'search'=>'home/goods/search', //商品搜索 + 'goods-<id>'=>'home/goods/detail', //商品 + 'brands'=>'home/brands/index', //品牌 + 'street'=>'home/shops/shopstreet', //品牌 + 'service-<id>'=>'home/helpcenter/view', //帮助中心 + 'service'=>'home/helpcenter/view', //帮助中心 + 'news-<id>'=>'home/news/view', //新闻 + 'news'=>'home/news/view', //新闻 + 'newscats-<catId>'=>'home/news/nlist', //新闻 + 'newscats'=>'home/news/nlist', //新闻 + 'login'=>'home/users/login', //用户登录页 + 'register'=>'home/users/regist', //用户登录页 + 'forget'=>'home/users/forgetpass', //找回密码 + 'forget-step1'=>'home/users/forgetpasst', //找回密码 + 'forget-success'=>'home/users/forgetpassf', //找回密码 + 'forget-step3'=>'home/users/resetpass', //找回密码 + 'shop-login'=>'home/shops/login', //商家登录 + 'selfshop'=>'home/shops/selfshop', //自营店铺 + 'shop-<shopId>'=>'home/shops/home' //店铺主页 +]); \ No newline at end of file diff --git a/hyhproject/common/conf/tags.php b/hyhproject/common/conf/tags.php new file mode 100755 index 0000000..81c117c --- /dev/null +++ b/hyhproject/common/conf/tags.php @@ -0,0 +1,10 @@ +<?php +/** + * ============================================================================ + */ +return [ + 'app_begin'=> [ + 'wstmart\\common\\behavior\\InitConfig' + ] +] +?> \ No newline at end of file diff --git a/hyhproject/common/conf/wechat/config.php b/hyhproject/common/conf/wechat/config.php new file mode 100755 index 0000000..d105dc6 --- /dev/null +++ b/hyhproject/common/conf/wechat/config.php @@ -0,0 +1,14 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + 'exception_handle' => '\\wstmart\\common\\exception\\WstWechatHttpException', +]; diff --git a/hyhproject/common/exception/WstAppHttpException.php b/hyhproject/common/exception/WstAppHttpException.php new file mode 100755 index 0000000..4fcb54a --- /dev/null +++ b/hyhproject/common/exception/WstAppHttpException.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\common\exception; +use think\exception\Handle; +// APP异常处理类 +class WstAppHttpException extends Handle +{ + + public function render(\Exception $e) + { + if(config('app_debug')){ + return parent::render($e); + }else{ + //die('{"status":-111,"msg":"数据读取出现未知错误!"}'); + die('{"status":-111,"msg":"'.$e->getMessage().'"}'); + } + } + +} \ No newline at end of file diff --git a/hyhproject/common/exception/WstHttpException.php b/hyhproject/common/exception/WstHttpException.php new file mode 100755 index 0000000..e7c4bfd --- /dev/null +++ b/hyhproject/common/exception/WstHttpException.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\common\exception; +/** + * ============================================================================ + */ +use think\exception\Handle; + +class WstHttpException extends Handle +{ + + public function render(\Exception $e) + { + if(config('app_debug')){ + return parent::render($e); + }else{ + header("Location:".url('home/error/index')); + } + } + +} \ No newline at end of file diff --git a/hyhproject/common/exception/WstMoblieHttpException.php b/hyhproject/common/exception/WstMoblieHttpException.php new file mode 100755 index 0000000..7156d47 --- /dev/null +++ b/hyhproject/common/exception/WstMoblieHttpException.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\common\exception; +use think\exception\Handle; +// 手机版异常处理类 +class WstMoblieHttpException extends Handle +{ + + public function render(\Exception $e) + { + if(config('app_debug')){ + return parent::render($e); + }else{ + header("Location:".url('mobile/error/index')); + } + } + +} \ No newline at end of file diff --git a/hyhproject/common/exception/WstWechatHttpException.php b/hyhproject/common/exception/WstWechatHttpException.php new file mode 100755 index 0000000..dfaf92f --- /dev/null +++ b/hyhproject/common/exception/WstWechatHttpException.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\common\exception; +use think\exception\Handle; +// 微信版异常处理类 +class WstWechatHttpException extends Handle +{ + + public function render(\Exception $e) + { + if(config('app_debug')){ + return parent::render($e); + }else{ + header("Location:".url('wechat/error/index')); + } + } + +} \ No newline at end of file diff --git a/hyhproject/common/model/Addons.php b/hyhproject/common/model/Addons.php new file mode 100755 index 0000000..760f897 --- /dev/null +++ b/hyhproject/common/model/Addons.php @@ -0,0 +1,23 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 插件类 + */ +class Addons extends Base{ + + public function getAddonsMaps(){ + $addons = cache('WST_ADDONS_MAPS'); + if(!$addons){ + $list = $this->where(["dataFlag"=>1])->field("name,title")->select(); + $addons = array(); + for($i=0,$j=count($list);$i<$j;$i++){ + $addon = $list[$i]; + $addons[strtolower($addon["name"])] = $addon["title"]; + } + cache('WST_ADDONS_MAPS',$addons,86400); + } + return $addons; + } + +} diff --git a/hyhproject/common/model/Ads.php b/hyhproject/common/model/Ads.php new file mode 100755 index 0000000..8e8cf47 --- /dev/null +++ b/hyhproject/common/model/Ads.php @@ -0,0 +1,12 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 广告类 + */ +class Ads extends Base{ + public function recordClick(){ + $id = (int)input('id'); + return $this->where("adId=$id")->setInc('adClickNum'); + } +} diff --git a/hyhproject/common/model/Aliyunoss.php b/hyhproject/common/model/Aliyunoss.php new file mode 100755 index 0000000..4a380d6 --- /dev/null +++ b/hyhproject/common/model/Aliyunoss.php @@ -0,0 +1,77 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 基础控业务处理 + */ +use think\Model; +use think\Db; +vendor('oss-sdk.autoload'); +use OSS\OssClient; +use OSS\Core\OssException; +const OSS_ACCESS_ID = 'LTAIfppBmzIHRPV0'; +const OSS_ACCESS_KEY = 'OdsoQBa30zzPC38Jq9EmefbqSgFZnX'; +const OSS_ENDPOINT = 'oss-cn-hongkong.aliyuncs.com'; +const OSS_BUCKET = 'qlgmall'; +const OSS_WEB_SITE = 'img.zgqlg.com.cn'; +class Aliyunoss extends Model { + public $ossClient; + private $oss_access_id; + private $oss_access_key; + private $oss_endpoint; + private $oss_bucket; + private $oss_web_site; + public function __construct(){ + parent::__construct(); + $this->oss_access_id = OSS_ACCESS_ID; + $this->oss_access_key = OSS_ACCESS_KEY; + $this->oss_endpoint = OSS_ENDPOINT; + $this->oss_bucket = OSS_BUCKET; + $this->oss_web_site = OSS_WEB_SITE; + $this->ossClient = new OssClient($this->oss_access_id,$this->oss_access_key,$this->oss_endpoint); + } + + /** + * [getInfo 获取图片信息] + * @param [type] $object [oss图片名] + * @return [type] [description] + */ + public function getInfo($object){ + $options = array( + //不能 加入这个OssClient::OSS_FILE_DOWNLOAD;如果加入会下载下来 + // OssClient::OSS_FILE_DOWNLOAD =>'upload/image/2018-06/5b1b478de0a8123.jpg', + OssClient::OSS_PROCESS => "image/info", ); + $rs = $this->ossClient->getObject($this->oss_bucket, $object,$options); + return json_decode($rs,true); + die; + } + /** + * [uploadFile 图片上传] + * @param [type] $object [上传后的文件名] + * @param [type] $file [上传前的文件路径] + * @return [type] [description] + */ + public function uploadFile($object,$file){ + try{ + $this->ossClient->uploadFile($this->oss_bucket, $object,$file); + return true; + }catch(OssException $e){ + $e->getMessage(); + return false; + } + + } + + /** + * [del 删除文件] + * @param [type] $object [oss文件名包含路径] + * @return [type] [description] + */ + public function del($object){ + try{ + $this->ossClient->deleteObject($this->oss_bucket,$object); + }catch(OssException $e){ + return $e->getMessage(); + } + } +} \ No newline at end of file diff --git a/hyhproject/common/model/Areas.php b/hyhproject/common/model/Areas.php new file mode 100755 index 0000000..462b546 --- /dev/null +++ b/hyhproject/common/model/Areas.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 地区类 + */ +class Areas extends Base{ + + /** + * 获取所有城市-根据字母分类 + */ + public function getCityGroupByKey(){ + $rs = array(); + $rslist = $this->where('isShow=1 AND dataFlag = 1 AND areaType=1')->field('areaId,areaName,areaKey')->order('areaKey, areaSort')->select(); + foreach ($rslist as $key =>$row){ + $rs[$row["areaKey"]][] = $row; + } + return $rs; + } + /** + * 获取城市列表 + */ + public function getCitys(){ + return $this->where('isShow=1 AND dataFlag = 1 AND areaType=1')->field('areaId,areaName')->order('areaKey, areaSort')->select(); + } + + public function getArea($areaId2){ + $rs = $this->where(["isShow"=>1,"dataFlag"=>1,"areaType"=>1,"areaId"=>$areaId2])->field('areaId,areaName,areaKey')->find(); + return $rs; + } + /** + * 获取地区列表 + */ + public function listQuery($parentId = 0){ + $parentId = ($parentId>0)?$parentId:(int)input('parentId'); + return $this->where(['isShow'=>1,'dataFlag'=>1,'parentId'=>$parentId])->field('areaId,areaName,parentId')->order('areaSort desc')->select(); + } + /** + * 获取指定对象 + */ + public function getById($id){ + return $this->where(["areaId"=>(int)$id])->find()->toArray(); + } + /** + * 根据子分类获取其父级分类 + */ + public function getParentIs($id,$data = array()){ + $data[] = $id; + $parentId = $this->where('areaId',$id)->value('parentId'); + if($parentId==0){ + krsort($data); + return $data; + }else{ + return $this->getParentIs($parentId, $data); + } + } + /** + * 获取自己以及父级的地区名称 + */ + public function getParentNames($id,$data = array()){ + $areas = $this->where('areaId',$id)->field('parentId,areaName')->find(); + $data[] = $areas['areaName']; + if((int)$areas['parentId']==0){ + krsort($data); + return $data; + }else{ + return $this->getParentNames((int)$areas['parentId'], $data); + } + } + /** + * 检测是否还存在下级 + */ + public function hasChild($areaId){ + return $this->where(['parentId'=>(int)$areaId,'dataFlag'=>1,'isShow'=>1])->find(); + } +} diff --git a/hyhproject/common/model/Auth.php b/hyhproject/common/model/Auth.php new file mode 100755 index 0000000..00d12da --- /dev/null +++ b/hyhproject/common/model/Auth.php @@ -0,0 +1,85 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 验证处理类 + */ +class Auth extends Base{ + protected $table = ''; + public function __construct(){ + parent::__construct(); + $this->table = Db::name('auth_personal'); + } + public function setTable($tableName='auth_company'){ + $this->table = Db::name($tableName); + } + public function getStatusTextAttr($value,$data){ + $status = [-1=>'已拒绝',0=>'待审核',1=>'已通过']; + return $status[$data['status']]; + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getInfo($where,$field='*'){ + return $this->table->where($where)->field($field)->find(); + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getField($where,$field='id'){ + return $this->table->where($where)->value($field); + } + /** + * 插入单条信息 + * @param string $data [description] + * @return [type] [description] + */ + public function insertInfo($data){ + $data['createTime'] = time(); + return $this->table->insert($data); + } + /** + * 更新单条信息 + * @param [type] $where [description] + * @param string $data [description] + * @return [type] [description] + */ + public function updateInfo($where,$data){ + return $this->table->where($where)->update($data); + } + /** + * 根据手机号获取单条信息 + * @param [type] $where [description] + * @param string $data [description] + * @return [type] [description] + */ + public function getAuthInfoByMobile($userPhone){ + $where['userPhone']=$userPhone; + $where['dataFlag'] = 1; + $userInfo = getUserInfo($where,'userId,authType'); + if(!$userInfo) return WSTReturn('手机号不存在'); + + if(1 == $userInfo['authType']){//个人认证 + $field = 'householdName uName,householdIdCard idCard'; + }elseif(0 == $userInfo['authType']){ + return WSTReturn('请联系该用户实名认证'); + }elseif(2 == $userInfo['authType']){ + $this->setTable('auth_company'); + $field = 'trueName uName,idCard'; + //return WSTReturn('合作账号不可亲人认证'); + } + $rs = $this->getInfo(['userId'=>$userInfo['userId']],$field); + if($rs){ + return WSTReturn('成功',1,$rs); + } + return WSTReturn('获取失败,状态异常'); + } + +} diff --git a/hyhproject/common/model/AuthFamily.php b/hyhproject/common/model/AuthFamily.php new file mode 100755 index 0000000..ebb15c0 --- /dev/null +++ b/hyhproject/common/model/AuthFamily.php @@ -0,0 +1,81 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 验证处理类 + */ +class AuthFamily extends Base{ + protected $table = ''; + public function __construct(){ + parent::__construct(); + $this->table = Db::name('auth_family_report'); + } + public function setTable($tableName='auth_family_personal'){ + $this->table = Db::name($tableName); + } + public function getStatusTextAttr($value,$data){ + $status = [-1=>'已拒绝',0=>'待审核',1=>'已通过']; + return $status[$data['status']]; + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getInfo($where,$field='*'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->find(); + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getField($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->value($field); + } + /** + * 获取多条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getList($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->select();; + } + /** + * 获取多条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getSelect($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->paginate(input('pageSize/d',10))->toArray();; + } + /** + * 插入单条信息 + * @param string $data [description] + * @return [type] [description] + */ + public function insertInfo($data){ + $data['createTime'] = time(); + return $this->table->insert($data); + } + /** + * 更新单条信息 + * @param [type] $where [description] + * @param string $data [description] + * @return [type] [description] + */ + public function updateInfo($where,$data){ + return $this->table->where($where)->update($data); + } + +} + diff --git a/hyhproject/common/model/Banks.php b/hyhproject/common/model/Banks.php new file mode 100755 index 0000000..cf76f3e --- /dev/null +++ b/hyhproject/common/model/Banks.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 银行业务处理 + */ +class Banks extends Base{ + /** + * 列表 + */ + public function listQuery(){ + $data = cache('WST_BANKS'); + if(!$data){ + $data = $this->where('dataFlag',1)->field('bankId,bankName')->select(); + cache('WST_BANKS',$data,31536000); + } + return $data; + } +} diff --git a/hyhproject/common/model/Base.php b/hyhproject/common/model/Base.php new file mode 100755 index 0000000..64a62cb --- /dev/null +++ b/hyhproject/common/model/Base.php @@ -0,0 +1,25 @@ +<?php +namespace wstmart\common\model; +use think\Model; +use think\Db; +/** + * ============================================================================ + * 基础模型器 + */ + +class Base extends Model { + /** + * 获取空模型 + */ + public function getEModel($tables){ + $rs = Db::query('show columns FROM `'.config('database.prefix').$tables."`"); + $obj = []; + if($rs){ + foreach($rs as $key => $v) { + $obj[$v['Field']] = $v['Default']; + if($v['Key'] == 'PRI')$obj[$v['Field']] = 0; + } + } + return $obj; + } +} \ No newline at end of file diff --git a/hyhproject/common/model/Brands.php b/hyhproject/common/model/Brands.php new file mode 100755 index 0000000..b2afea4 --- /dev/null +++ b/hyhproject/common/model/Brands.php @@ -0,0 +1,84 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 品牌业务处理类 + */ +class Brands extends Base{ + /** + * 获取品牌列表 + */ + public function pageQuery($pagesize){ + + $id = (int)input('id'); + $where['b.dataFlag']=1; + if($id>1){ + $where['gcb.catId']=$id; + } + $rs = $this->alias('b') + ->join('__CAT_BRANDS__ gcb','gcb.brandId=b.brandId','left') + ->where($where) + ->field('b.brandId,brandName,brandImg,gcb.catId') + ->group('b.brandId,gcb.catId') + ->order('b.sortNo asc') + ->paginate($pagesize)->toArray(); + return $rs; + } + /** + * 获取品牌列表 + */ + public function listQuery($catId){ + $rs = Db::name('cat_brands')->alias('l') + ->join('__BRANDS__ b','b.brandId=l.brandId and b.dataFlag=1 and l.catId='.$catId) + ->field('b.brandId,b.brandName,b.brandImg') + ->group('b.brandId') + ->order('b.sortNo asc') + ->select(); + return $rs; + } + + /** + * 商品筛选品牌查询 + */ + public function goodsListQuery($catId){ + $rs = Db::name('cat_brands')->alias('l') + ->join('__BRANDS__ b','b.brandId=l.brandId and b.dataFlag=1 and l.catId='.$catId) + ->join('__GOODS__ g','g.brandId=b.brandId','inner') + ->field('b.brandId,b.brandName,b.brandImg') + ->group('b.brandId') + ->order('b.sortNo asc') + ->select(); + return $rs; + } + + + /** + * 根据商品id获取可供选择的品牌 + */ + public function canChoseBrands($goodsId){ + $rs = Db::name('cat_brands')->alias('l') + ->join('__BRANDS__ b','b.brandId=l.brandId and b.dataFlag=1') + ->join('__GOODS__ g','g.brandId=b.brandId','inner') + ->where(['g.goodsId'=>['in',$goodsId]]) + ->field('b.brandId,b.brandName,b.brandImg') + ->group('b.brandId') + ->order('b.sortNo asc') + ->select(); + return $rs; + } + /** + * 根据品牌id获取商品id + */ + public function getGoodsIds($brandIds){ + $rs = Db::name('goods')->field('goodsId')->where(['brandId'=>['in',$brandIds],'dataFlag'=>1,'isSale'=>1,'goodsStatus'=>1])->select(); + if(!empty($rs)){ + $bIds = []; + foreach($rs as $k=>$v){ + $bIds[$k] = $v['goodsId']; + } + return $bIds; + } + return []; + } +} diff --git a/hyhproject/common/model/Carts.php b/hyhproject/common/model/Carts.php new file mode 100755 index 0000000..70889dc --- /dev/null +++ b/hyhproject/common/model/Carts.php @@ -0,0 +1,610 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 购物车业务处理类 + */ + +class Carts extends Base{ + + /** + * 加入购物车 + */ + public function addCart(){ +//return WSTReturn("系统调试中,暂不支持购买,请等待调试完成", -1); + $userId = (int)session('WST_USER.userId'); + $goodsId = (int)input('post.goodsId'); + //goods_specs表的规格ID + $goodsSpecId = (int)input('post.goodsSpecId'); + $type = (int)input('post.type'); + //mark 添加验证 + //$m = new \addons\hyhsale\model\Hyhsale(); + // if($type == 0 && model('\addons\hyhsale\model\Hyhsale')->getEffectiveGoods(['goodsId'=>$goodsId,'specsId'=>$goodsSpecId])){ + // return WSTReturn("秒杀活动商品请点击立即购买!", -1); + // } + + $cartNum = (int)input('post.buyNum',1); + $cartNum = ($cartNum>0)?$cartNum:1; + + if($userId==0)return WSTReturn('加入购物车失败,请先登录'); + //验证传过来的商品是否合法 + $chk = $this->checkGoodsSaleSpec($goodsId,$goodsSpecId); + if($chk['status']==-1)return $chk; + //检测库存是否足够 + if($chk['data']['stock']<$cartNum)return WSTReturn("加入购物车失败,商品库存不足", -1); + //添加实物商品 + if($chk['data']['goodsType']==0){ + $goodsSpecId = $chk['data']['goodsSpecId']; + $goods = $this->where(['userId'=>$userId,'goodsId'=>$goodsId,'goodsSpecId'=>$goodsSpecId])->select(); + + if(empty($goods)){ + $data = array(); + $data['userId'] = $userId; + $data['goodsId'] = $goodsId; + $data['goodsSpecId'] = $goodsSpecId; + $data['isCheck'] = 1; + $data['cartNum'] = $cartNum; + $rs = $this->save($data); + }else{ + $rs = $this->where(['userId'=>$userId,'goodsId'=>$goodsId,'goodsSpecId'=>$goodsSpecId])->setInc('cartNum',$cartNum); + } + if(false !==$rs){ + if($type==1){ + $cartId = $this->where(['userId'=>$userId,'goodsId'=>$goodsId,'goodsSpecId'=>$goodsSpecId])->value('cartId'); + $this->where("cartId = ".$cartId." and userId=".$userId)->setField('isCheck',1); + $this->where("cartId != ".$cartId." and userId=".$userId)->setField('isCheck',0); + $this->where(['cartId' =>$cartId,'userId'=>$userId])->setField('cartNum',$cartNum); + } + return WSTReturn("添加成功", 1); + } + }else{ + //非实物商品 + $carts = []; + $carts['goodsId'] = $goodsId; + $carts['cartNum'] = $cartNum; + session('TMP_CARTS',$carts); + return WSTReturn("添加成功", 1,['forward'=>'quickSettlement']); + } + return WSTReturn("加入购物车失败", -1); + } + /** + * 验证商品是否合法 + */ + public function checkGoodsSaleSpec($goodsId,$goodsSpecId){ + $goods = model('Goods')->where(['goodsStatus'=>1,'dataFlag'=>1,'isSale'=>1,'goodsId'=>$goodsId])->field('goodsId,isSpec,goodsStock,goodsType')->find(); + if(empty($goods))return WSTReturn("添加失败,无效的商品信息", -1); + $goodsStock = (int)$goods['goodsStock']; + //有规格的话查询规格是否正确 + if($goods['isSpec']==1){ + //商品规格详细列表页 + $specs = Db::name('goods_specs')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->field('id,isDefault,specStock')->select(); + if(count($specs)==0){ + return WSTReturn("添加失败,无效的商品信息", -1); + } + //默认规格ID + $defaultGoodsSpecId = 0; + //默认规格库存 + $defaultGoodsSpecStock = 0; + //是否找到规格 + $isFindSpecId = false; + foreach ($specs as $key => $v){ + //获取默认的规格 + if($v['isDefault']==1){ + $defaultGoodsSpecId = $v['id']; + $defaultGoodsSpecStock = (int)$v['specStock']; + } + //找到相关的规格 + if($v['id']==$goodsSpecId){ + $goodsStock = (int)$v['specStock']; + $isFindSpecId = true; + } + } + + if($defaultGoodsSpecId==0)return WSTReturn("添加失败,无效的商品信息", -1);//有规格却找不到规格的话就报错 + //if(!$isFindSpecId)return WSTReturn("添加失败,未找到该规格信息", -1);//修改没有规格直接不能买 mark hsf 20180313 + if(!$isFindSpecId)return WSTReturn("", 1,['goodsSpecId'=>$defaultGoodsSpecId,'stock'=>$defaultGoodsSpecStock,'goodsType'=>$goods['goodsType']]);//如果没有找到的话就取默认的规格 mark hsf 20180313 + return WSTReturn("", 1,['goodsSpecId'=>$goodsSpecId,'stock'=>$goodsStock,'goodsType'=>$goods['goodsType']]); + }else{ + return WSTReturn("", 1,['goodsSpecId'=>0,'stock'=>$goodsStock,'goodsType'=>$goods['goodsType']]); + } + } + /** + * 删除购物车里的商品 + */ + public function delCart(){ + $userId = (int)session('WST_USER.userId'); + $id = input('post.id'); + $id = explode(',',WSTFormatIn(",",$id)); + $id = array_filter($id); + $this->where("userId = ".$userId." and cartId in(".implode(',', $id).")")->delete(); + return WSTReturn("删除成功", 1); + } + /** + * 取消购物车商品选中状态 + */ + public function disChkGoods($goodsId,$goodsSpecId,$userId){ + $this->save(['isCheck'=>0],['userId'=>$userId,'goodsId'=>$goodsId,'goodsSpecId'=>$goodsSpecId]); + } + + /** + * 获取session中购物车列表 + */ + public function getQuickCarts($uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $tmp_carts = session('TMP_CARTS'); + $where = []; + $where['goodsId'] = $tmp_carts['goodsId']; + $rs = Db::name('goods')->alias('g') + ->join('__SHOPS__ s','s.shopId=g.shopId','left') + ->where($where) + ->field('s.userId,s.shopId,s.shopName,g.goodsId,s.shopQQ,shopWangWang,g.goodsName,g.shopPrice,g.goodsStock,g.goodsImg,g.goodsCatId,g.isFreeShipping') + ->find(); + if(empty($rs))return ['carts'=>[],'goodsTotalMoney'=>0,'goodsTotalNum'=>0]; + $rs['cartNum'] = $tmp_carts['cartNum']; + $carts = []; + $cartShop = []; + $goodsTotalNum = 1; + $goodsTotalMoney = 0; + //勿删!为插件促销活动做准备接口 + $rs['promotion'] = [];//商品要优惠的活动 + $cartShop['promotion'] = [];//店铺要优惠的活动 + $cartShop['promotionMoney'] = 0;//店铺要优惠的金额 + //--------------------------- + $cartShop['isFreeShipping'] = true; + $cartShop['shopId'] = $rs['shopId']; + $cartShop['shopName'] = $rs['shopName']; + $cartShop['shopQQ'] = $rs['shopQQ']; + $cartShop['userId'] = $rs['userId']; + $cartShop['shopWangWang'] = $rs['shopWangWang']; + //判断能否购买,预设allowBuy值为10,为将来的各种情况预留10个情况值,从0到9 + $rs['allowBuy'] = 10; + if($rs['goodsStock']<0){ + $rs['allowBuy'] = 0;//库存不足 + }else if($rs['goodsStock']<$tmp_carts['cartNum']){ + //$rs['allowBuy'] = 1;//库存比购买数小 + $rs['cartNum'] = $rs['goodsStock']; + } + $cartShop['goodsMoney'] = $rs['shopPrice'] * $rs['cartNum']; + $goodsTotalMoney = $goodsTotalMoney + $rs['shopPrice'] * $rs['cartNum']; + $rs['specNames'] = []; + $rs['cartId'] = $rs['goodsId']; + unset($rs['shopName']); + $cartShop['list'][] = $rs; + $carts[$cartShop['shopId']] = $cartShop; + $cartData = ['carts'=>$carts,'goodsTotalMoney'=>$goodsTotalMoney,'goodsTotalNum'=>$goodsTotalNum,'promotionMoney'=>0]; + //店铺优惠活动监听 + hook("afterQueryCarts",["carts"=>&$cartData,'isSettlement'=>true,'isVirtual'=>true,'uId'=>$userId]); + return $cartData; + } + + /** + * 获取购物车列表 + * isSettlement 是结算页面 + * uId 会员ID,默认为当前ID + * areaId2 市id + */ + public function getCarts($isSettlement = false, $uId=0, $areaId2=0){//添加会员地址判断 mark hsf 20171116 + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $where = []; + $where['c.userId'] = $userId; + $where['g.dataFlag'] = 1; + $where['g.goodsStatus'] = 1; + $where['g.isSale'] = 1; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.status'] = 1; + if($isSettlement)$where['c.isCheck'] = 1;//在结算页面,就获取选中的商品 + //获取购物车产品,包括选中和未选中的 + $rs = Db::name('carts')->alias('c')->join('__GOODS__ g','c.goodsId=g.goodsId','inner') + ->join('__SHOPS__ s','s.shopId=g.shopId','left') + ->join('__GOODS_SPECS__ gs','c.goodsSpecId=gs.id','left') + ->where($where) + ->field('c.goodsSpecId,c.cartId,s.userId,s.shopId,s.shopName,g.goodsId,s.shopQQ,shopWangWang,g.goodsName,g.shopPrice,g.goodsStock,g.isSpec,gs.specPrice,gs.specStock,g.goodsImg,c.isCheck,gs.specIds,c.cartNum,g.goodsCatId,g.freight,g.isFreeShipping,gs.initNum,gs.whslePrice,g.marketPrice') + ->select();//添加返回起批量和批发价 mark hsf 20171117 + //dump($rs);die; + $carts = []; + $goodsIds = []; + $goodsTotalNum = 0; + $goodsTotalMoney = 0; + //将同一个店铺的商品整合到一块 + foreach ($rs as $key =>$v){ + if(!isset($carts[$v['shopId']]['goodsMoney']))$carts[$v['shopId']]['goodsMoney'] = 0; + if(!isset($carts[$v['shopId']]['isFreeShipping']))$carts[$v['shopId']]['isFreeShipping'] = true; + //勿删!为插件促销活动做准备接口 + $v['promotion'] = [];//商品优惠活动 + $carts[$v['shopId']]['promotion'] = [];//店铺优惠活动 + $carts[$v['shopId']]['promotionMoney'] = 0;//店铺要优惠的金额 + //---------------------------- + $carts[$v['shopId']]['shopId'] = $v['shopId']; + $carts[$v['shopId']]['shopName'] = $v['shopName']; + $carts[$v['shopId']]['shopQQ'] = $v['shopQQ']; + $carts[$v['shopId']]['userId'] = $v['userId']; + //如果店铺一旦不包邮了,那么就不用去判断商品是否包邮了 + if($v['isFreeShipping']==0 && $carts[$v['shopId']]['isFreeShipping'])$carts[$v['shopId']]['isFreeShipping'] = false; + $carts[$v['shopId']]['shopWangWang'] = $v['shopWangWang']; + if($v['isSpec']==1){ + $v['shopPrice'] = $v['specPrice']; + $v['goodsStock'] = $v['specStock']; + }else{ + $v['initNum'] = 0;//添加返回起批量和批发价 mark hsf 20171117 + $v['whslePrice'] = 0;//添加返回起批量和批发价 mark hsf 20171117 + } + //$v['initNum'] = $v['initNum'];//添加返回起批量和批发价 mark hsf 20171117 + //$v['whslePrice'] = $v['whslePrice'];//添加返回起批量和批发价 mark hsf 20171117 + //判断能否购买,预设allowBuy值为10,为将来的各种情况预留10个情况值,从0到9 + $v['allowBuy'] = 10; + if($v['goodsStock']<0){ + $v['allowBuy'] = 0;//库存不足 + }else if($v['goodsStock']<$v['cartNum']){ + //$v['allowBuy'] = 1;//库存比购买数小 + $v['cartNum'] = $v['goodsStock']; + } + //如果是结算的话,则要过滤了不符合条件的商品 + if($isSettlement && $v['allowBuy']!=10){ + $this->disChkGoods($v['goodsId'],(int)$v['goodsSpecId'],(int)session('WST_USER.userId')); + continue; + } + if($v['isCheck']==1){ + $carts[$v['shopId']]['goodsMoney'] = $carts[$v['shopId']]['goodsMoney'] + $v['shopPrice'] * $v['cartNum']; + $goodsTotalMoney = $goodsTotalMoney + $v['shopPrice'] * $v['cartNum']; + $goodsTotalNum++; + } + $v['specNames'] = []; + unset($v['shopName']); + $carts[$v['shopId']]['list'][] = $v; + if(!in_array($v['goodsId'],$goodsIds))$goodsIds[] = $v['goodsId']; + } + + + //dump($carts);die; + //加载规格值 + if(count($goodsIds)>0){ + $specs = DB::name('spec_items')->alias('s')->join('__SPEC_CATS__ sc','s.catId=sc.catId','left') + ->where(['s.goodsId'=>['in',$goodsIds],'s.dataFlag'=>1])->field('catName,itemId,itemName')->select(); + if(count($specs)>0){ + $specMap = []; + foreach ($specs as $key =>$v){ + $specMap[$v['itemId']] = $v; + } + foreach ($carts as $key =>$shop){ + foreach ($shop['list'] as $skey =>$v){ + $strName = []; + if($v['specIds']!=''){ + $str = explode(':',$v['specIds']); + foreach ($str as $vv){ + if(isset($specMap[$vv]))$strName[] = $specMap[$vv]; + } + } + $carts[$key]['list'][$skey]['specNames'] = $strName; + } + } + } + } + + $cartData = ['carts'=>$carts,'goodsTotalMoney'=>$goodsTotalMoney,'goodsTotalNum'=>$goodsTotalNum,'promotionMoney'=>0]; + + //秒杀活动监听 + hook("beforeSettlement",["carts"=>&$cartData]); + + $allShippingMoney = 0; + if(empty($cartData['carts']['is_seckilling'])){ + //dump($cartData);die; + //店铺优惠活动监听 + hook("afterQueryCarts",["carts"=>&$cartData,'isSettlement'=>$isSettlement,'isVirtual'=>false,'uId'=>$userId]); + //批发插件 mart hsf 20171116 + hook("mobileControllerCartsSettlement",["carts"=>&$cartData]); + //ect整合相关优惠还有判断不能和在线支付商品一块 + hook("ectIntegration",["carts"=>&$cartData,'isSettlement'=>$isSettlement,'uId'=>$userId]); + //11.11会场商品结算钩子 + hook("orderCatsDoubleEleven",["carts"=>&$cartData,'isSettlement'=>$isSettlement,'uId'=>$userId]); + } + $freight=0; + /*添加运费计算 ,要先算店铺活动,不然满送运费有问题 mark hsf 20171116 */ + $carts = &$cartData['carts']; + foreach ($carts as $val) { + if(!isset($carts[$val['shopId']]['shippingMoney']))$carts[$val['shopId']]['shippingMoney'] = 0; + + if($val['isFreeShipping']){ + $freight = 0; + }else{ + foreach ($val['list'] as &$value) { + $freight += $value['freight']; + } + +// if($areaId2){ +// $freight = WSTOrderFreight($val['shopId'],$areaId2); +// }else{ +// $freight = WSTOrderFreight($val['shopId'],-1); +// } + } + $carts[$val['shopId']]['shippingMoney'] += $freight;//累计运费 + $allShippingMoney += $freight; + } + //foreach ($carts as $v) { + $cartData['goodsTotalMoney'] += $allShippingMoney;//$v['shippingMoney']; + //} + /*-------end--------*/ + + + + // $cartData['goodsTotalMoney']-=$cartData['promotionMoney']; + // $cartData['goodsTotalMoney'] = $cartData['goodsTotalMoney'] > 0 ? $cartData['goodsTotalMoney'] : 0; + $cartData['all_carts_num'] = $this->where('userId='.$userId)->count();//添加会员的购物车产品数量 mark hsf 20180111 + $cartData['allShippingMoney'] = $allShippingMoney;//添加总运费 + return $cartData; + } + + /** + * 获取购物车商品列表 + */ + public function getCartInfo($isSettlement = false){ + $userId = (int)session('WST_USER.userId'); + $where = []; + $where['c.userId'] = $userId; + if($isSettlement)$where['c.isCheck'] = 1; + $rs = $this->alias('c')->join('__GOODS__ g','c.goodsId=g.goodsId','inner') + ->join('__GOODS_SPECS__ gs','c.goodsSpecId=gs.id','left') + ->where($where) + ->field('c.goodsSpecId,c.cartId,g.goodsId,g.goodsName,g.shopPrice,g.goodsStock,g.isSpec,gs.specPrice,gs.specStock,g.goodsImg,c.isCheck,gs.specIds,c.cartNum') + ->select(); + $goodsIds = []; + $goodsTotalMoney = 0; + $goodsTotalNum = 0; + foreach ($rs as $key =>$v){ + if(!in_array($v['goodsId'],$goodsIds))$goodsIds[] = $v['goodsId']; + if($v['isSpec']==1){ + $v['shopPrice'] = $v['specPrice']; + $v['goodsStock'] = $v['specStock']; + } + if($v['goodsStock']<$v['cartNum']){ + $v['cartNum'] = $v['goodsStock']; + } + $goodsTotalMoney = $goodsTotalMoney + $v['shopPrice'] * $v['cartNum']; + $rs[$key]['goodsImg'] = WSTImg($v['goodsImg']); + } + //加载规格值 + if(count($goodsIds)>0){ + $specs = DB::name('spec_items')->alias('s')->join('__SPEC_CATS__ sc','s.catId=sc.catId','left') + ->where(['s.goodsId'=>['in',$goodsIds],'s.dataFlag'=>1])->field('itemId,itemName')->select(); + if(count($specs)>0){ + $specMap = []; + foreach ($specs as $key =>$v){ + $specMap[$v['itemId']] = $v; + } + foreach ($rs as $key =>$v){ + $strName = []; + if($v['specIds']!=''){ + $str = explode(':',$v['specIds']); + foreach ($str as $vv){ + if(isset($specMap[$vv]))$strName[] = $specMap[$vv]['itemName']; + } + } + $rs[$key]['specNames'] = $strName; + } + } + } + $goodsTotalNum = count($rs); + return ['list'=>$rs,'goodsTotalMoney'=>sprintf("%.2f", $goodsTotalMoney),'goodsTotalNum'=>$goodsTotalNum]; + } + + /** + * 修改购物车商品状态 + */ + public function changeCartGoods(){ + $isCheck = Input('post.isCheck/d',-1); + $buyNum = Input('post.buyNum/d',1); + if($buyNum<1)$buyNum = 1; + $id = Input('post.id/d'); + $userId = (int)session('WST_USER.userId'); + $data = []; + if($isCheck!=-1)$data['isCheck'] = $isCheck; + $data['cartNum'] = $buyNum; + $this->where(['userId'=>$userId,'cartId'=>$id])->update($data); + return WSTReturn("操作成功", 1); + } + + /** + * 批量修改购物车商品状态 + */ + public function batchChangeCartGoods(){ + $ids = input('ids'); + if($ids=='')return WSTReturn("操作失败"); + $ids = explode(',',WSTFormatIn(',',$ids)); + $userId = (int)session('WST_USER.userId'); + $isCheck = ((int)input('post.isCheck/d',-1)==1)?1:0; + $this->where(['userId'=>$userId,'cartId'=>['in',$ids]])->update(['isCheck'=>$isCheck]); + return WSTReturn("操作成功", 1); + } + /** + * 计算订单金额 + */ + public function getCartMoney($uId=0){ + $data = ['shops'=>[],'totalMoney'=>0,'totalGoodsMoney'=>0]; + $areaId = input('areaId2/d',-1); + $userId = $uId==0?(int)session('WST_USER.userId'):$uId; + //计算各店铺运费及金额 + $deliverType = (int)input('deliverType');//0是快递,1是自提,自提的不要运费,先取消 mark 20170907 + $carts = $this->getCarts(true,$userId,$areaId);//计算价格添加城市运费 mark hsf 20171222 + $data['couponMoney'] = 0;//定义一个变量,存储11.11优惠券价格 + $data['maxScoreMoneySum'] = 0;//定义一个变量,存储惠宝数量 + //批发插件 mart hsf 20171116 + //hook("mobileControllerCartsSettlement",["carts"=>&$carts]); + $shopFreight = 0; + $maxScoreMoney = 0;//初始化最大可用惠宝数 mark hsf 20171117 + $total_promotion_money = 0;//初始化合计优惠 mark hsf 20170303 + foreach ($carts['carts'] as &$v){//优化一下循环效率 mark hsf 20171118 + /** + * 修改运费计算 + * 因为在获取购物车产品信息时已经加上运费了 + * mark hsf 20171222 + */ + // if($v['isFreeShipping']){ + // $data['shops'][$v['shopId']]['freight'] = 0; + // }else{ + // $shopFreight = ($deliverType==1)?0:WSTOrderFreight($v['shopId'],$areaId); + // $data['shops'][$v['shopId']]['freight'] = $shopFreight; + // } + if($v['isFreeShipping']){ + $shopFreight = 0; + }else{ + if($deliverType == 0){ + $shopFreight = $v['shippingMoney']; + } + } + $data['shops'][$v['shopId']]['freight'] = $shopFreight; + + /****************end****************/ + $data['shops'][$v['shopId']]['oldGoodsMoney'] = $v['goodsMoney']; + $data['shops'][$v['shopId']]['goodsMoney'] = $v['goodsMoney']+$shopFreight-$v['promotionMoney']; + $data['totalGoodsMoney'] += $v['goodsMoney']-$v['promotionMoney']; + $data['totalMoney'] += $v['goodsMoney'] + $shopFreight-$v['promotionMoney']; + $total_promotion_money += $v['promotionMoney'];//合计优惠 mark hsf 20170303 + /* + * 计算最大可用惠宝,添加验证批发价的惠宝可抵用 mark hsf 20171117 + */ + // foreach ($v['list'] as &$val) { + // if(isset($val['isWhsle'])){//是批发价的 + // $maxScoreMoney += (int)($val['shopPrice'] * $val['cartNum'] * HuiWhsleScale());//可用惠宝默认抵10% + // }else{ + // $maxScoreMoney += (int)($val['shopPrice'] * $val['cartNum'] * HuiScale()); + // } + // } + /****************end****************/ + } + //批发插件 mart hsf 20171116 + hook("mobileControllerCartsSettlement",["carts"=>&$carts]); + //放钩子计算11.11订单的分类商品使用优惠券后的金额 + hook("orderCatsCouponEleven",['data'=>&$data,'carts'=>&$carts,'isSettlement'=>true,'uId'=>$userId]); + if(isset($data['couponMoney']) && $data['couponMoney'] > 0 ){ + $total_promotion_money += $data['couponMoney']; + } + //此处放钩子计算商家使用优惠券后的金额-根据优惠券ID计算 + hook("afterCalculateCartMoney",["data"=>&$data,'carts'=>$carts,'isVirtual'=>false,'uId'=>$userId]); + //ect整合相关优惠还有判断不能和在线支付商品一块 + hook("ectIntegration",["carts"=>&$carts,'isSettlement'=>true,'uId'=>$userId]); + + + $maxScoreMoney = $data['maxScoreMoneySum']-($total_promotion_money * HuiScale());//减去优惠过的 + $maxScoreMoney = $maxScoreMoney < 0 ? 0 : $maxScoreMoney;//防止负数 mark 20180303 + + // dump($data) ;die; + $data['totalGoodsMoney'] = ($data['totalGoodsMoney']>$data['totalMoney'])?$data['totalMoney']:$data['totalGoodsMoney']; + $data['maxScore'] = 0; + $data['maxScoreMoney'] = 0; + $data['useScore'] = 0; + $data['scoreMoney'] = 0; + //计算最大可用惠宝 + /** + * 最多金额抵用20% mark 20170907 + */ + $maxScore = round(WSTScoreToMoney($maxScoreMoney,true),2);//WSTScoreToMoney($data['totalGoodsMoney'],true); + + /****************end****************/ + //最大可用惠宝不能大于用户惠宝 + $user = model('users')->getFieldsById($userId,'userScore'); + if($maxScore>$user['userScore']){ + $maxScore = $user['userScore']; + $maxScoreMoney = WSTScoreToMoney($maxScore); + } + $data['maxScore'] = $maxScore; + $data['maxScoreMoney'] = $maxScoreMoney; + //判断是否使用惠宝 + $isUseScore = (int)input('isUseScore'); + if($isUseScore==1){ + //不能比用户惠宝还多 + $useScore = input('useScore'); + if($useScore>$maxScore)$useScore = $maxScore; + $data['useScore'] = $useScore; + $data['scoreMoney'] = WSTScoreToMoney($useScore); + } + if((isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1) || (isset($carts['promotion_goods']) && $carts['promotion_goods'] == 1)){//不可抵用惠宝 + $data['useScore']=0; + $data['scoreMoney']=0; + } + //$carts['promotionMoney'] = isset($carts['promotionMoney']) ? $carts['promotionMoney'] : 0; + $data['couponMoney'] = isset($data['couponMoney']) ? $data['couponMoney'] : 0; + $data['realTotalMoney'] = WSTPositiveNum($data['totalMoney'] - $data['scoreMoney']- $data['couponMoney']); + //dump($data); + return WSTReturn('',1,$data); + } + + public function getQuickCartMoney($uId=0){ + $data = ['shops'=>[],'totalMoney'=>0,'totalGoodsMoney'=>0]; + $areaId = input('post.areaId2/d',-1); + //计算各店铺运费及金额 + $carts = $this->getQuickCarts(true); + $cart = current($carts['carts']); + $data['shops'][$cart['shopId']]['freight'] = 0; + $data['shops'][$cart['shopId']]['goodsMoney'] = $cart['goodsMoney']; + $data['totalGoodsMoney'] = $cart['goodsMoney']; + $data['totalMoney'] += $cart['goodsMoney']; + //此处放钩子计算商家使用优惠券后的金额-根据优惠券ID计算 + hook("afterCalculateCartMoney",["data"=>&$data,'carts'=>$carts,'isVirtual'=>true]); + $data['totalGoodsMoney'] = ($data['totalGoodsMoney']>$data['totalMoney'])?$data['totalMoney']:$data['totalGoodsMoney']; + $data['maxScore'] = 0; + $data['maxScoreMoney'] = 0; + $data['useScore'] = 0; + $data['scoreMoney'] = 0; + + /*************计算最大可用惠宝************/ + $maxScoreMoney = (int)($data['totalGoodsMoney'] * HuiScale()); + $maxScore = WSTScoreToMoney($maxScoreMoney,true); + //$maxScoreMoney = $data['totalGoodsMoney']; + //$maxScore = WSTScoreToMoney($data['totalGoodsMoney'],true); + /***********end*************/ + //最大可用惠宝不能大于用户惠宝 + $userId = $uId==0?(int)session('WST_USER.userId'):$uId; + $user = model('users')->getFieldsById($userId,'userScore'); + if($maxScore>$user['userScore']){ + $maxScore = $user['userScore']; + $maxScoreMoney = WSTScoreToMoney($maxScore,true); + } + $data['maxScore'] = $maxScore; + $data['maxScoreMoney'] = $maxScoreMoney; + //判断是否使用惠宝 + $isUseScore = (int)input('isUseScore'); + if($isUseScore==1){ + //不能比用户惠宝还多 + $useScore = (int)input('useScore'); + if($useScore>$maxScore)$useScore = $maxScore; + $data['useScore'] = $useScore; + $data['scoreMoney'] = WSTScoreToMoney($useScore); + } + $data['realTotalMoney'] = WSTPositiveNum($data['totalMoney'] - $data['scoreMoney']); + return WSTReturn('',1,$data); + } + + /** + * 删除购物车商品 + */ + public function delCartByUpdate($goodsId){ + if(is_array($goodsId)){ + $this->where(['goodsId'=>['in',$goodsId]])->delete(); + }else{ + $this->where('goodsId',$goodsId)->delete(); + } + + } + + /** + * app购物车推荐商品 + * uId 会员ID,默认为当前ID + */ + public function recommendGoods($uId=0){ + $pageSize = (int)input('pageSize/d',10); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $where = []; + $where['c.userId'] = $userId; + //获取购物车产品,包括选中和未选中的 + $catsGoods = Db::name('carts')->alias('c')->join('__GOODS__ g','c.goodsId=g.goodsId','inner') + ->where($where) + ->Distinct(true) + ->cache(true,60) + ->column('g.goodsCatId'); + $recommendGoods = Db::name('goods')->where(['goodsCatId'=>['in',$catsGoods]])->field('goodsId,goodsName,goodsImg,shopPrice')->order('saleNum desc')->cache(true,60)->paginate($pageSize) + ->toArray(); + return WSTReturn('',1,$recommendGoods); + } +} + diff --git a/hyhproject/common/model/CashConfigs.php b/hyhproject/common/model/CashConfigs.php new file mode 100755 index 0000000..2fa030f --- /dev/null +++ b/hyhproject/common/model/CashConfigs.php @@ -0,0 +1,91 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 提现账号业务处理器 + */ +class CashConfigs extends Base{ + /** + * 获取列表 + */ + public function pageQuery($targetType,$targetId){ + $type = (int)input('post.type',-1); + $where = []; + $where['targetType'] = (int)$targetType; + $where['targetId'] = (int)$targetId; + $where['c.dataFlag'] = 1; + if(in_array($type,[0,1]))$where['moneyType'] = $type; + $page = $this->alias('c')->join('__BANKS__ b','c.accTargetId=b.bankId')->where($where)->field('b.bankName,c.*')->order('c.id desc')->paginate()->toArray(); + if(count($page['Rows'])>0){ + foreach($page['Rows'] as $key => $v){ + $areas = model('areas')->getParentNames($v['accAreaId']); + $page['Rows'][$key]['areaName'] = implode('',$areas); + } + } + return $page; + } + /** + * 获取列表 + */ + public function listQuery($targetType,$targetId){ + $where = []; + $where['targetType'] = (int)$targetType; + $where['targetId'] = (int)$targetId; + $where['dataFlag'] = 1; + return $this->where($where)->field('id,accNo,accUser')->select(); + } + /** + * 获取资料 + */ + public function getById($id){ + $config = $this->get($id); + $areas = model('areas')->getParentIs($config['accAreaId']); + $config['accAreaIdPath'] = implode('_',$areas)."_"; + return $config; + } + /** + * 新增卡号 + */ + public function add(){ + $data = input('post.'); + $data['targetType'] = 0; + $data['targetId'] = (int)session('WST_USER.userId'); + $data['accType'] = 3; + $data['userId'] = (int)session('WST_USER.userId'); + $data['createTime'] = date('Y-m-d H:i:s'); + WSTUnset($data,'id'); + $result = $this->validate('CashConfigs.add')->allowField(true)->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1,['id'=>$this->id]); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑卡号 + */ + public function edit(){ + $id = (int)input('id'); + $data = input('post.'); + $userId = (int)session('WST_USER.userId'); + WSTUnset($data,'id,targetType,targetId,accType,createTime'); + $result = $this->validate('CashConfigs.edit')->allowField(true)->save($data,['id'=>$id,'targetId'=>$userId]); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除提现账号 + */ + public function del(){ + $object = $this->get((int)input('id')); + $object->dataFlag = -1; + $result = $object->save(); + if(false !== $result){ + return WSTReturn('操作成功',1); + } + return WSTReturn('操作失败',-1); + } +} diff --git a/hyhproject/common/model/CashDraws.php b/hyhproject/common/model/CashDraws.php new file mode 100755 index 0000000..6eaed2b --- /dev/null +++ b/hyhproject/common/model/CashDraws.php @@ -0,0 +1,258 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 提现流水业务处理器 + */ +class CashDraws extends Base{ + /** + * 获取列表 + */ + public function pageQuery($targetType,$targetId){ + $type = (int)input('post.type',-1); + $where = []; + $where['targetType'] = (int)$targetType; + $where['targetId'] = (int)$targetId; + if(in_array($type,[0,1]))$where['moneyType'] = $type; + return $this->where($where)->order('cashId desc')->paginate()->toArray(); + } + + /** + * 申请提现 + */ + public function drawMoney(){ + $userId = (int)session('WST_USER.userId'); + $money = (float)input('money'); + $accId = (float)input('accId'); + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return WSTReturn('提现申请失败'); + } + $limitMoney = (float)WSTConf('CONF.drawCashUserLimit'); + if($money<$limitMoney)return WSTReturn('提取金额必须大于或等于¥'.$limitMoney.'方可提现'); + if($payPwd=='')return WSTReturn('支付密码不能为空'); + //加载提现账号信息 + $acc = Db::name('cash_configs')->alias('cc') + ->join('__BANKS__ b','cc.accTargetId=b.bankId')->where(['cc.dataFlag'=>1,'id'=>$accId]) + ->field('b.bankName,cc.*')->find(); + if(empty($acc))return WSTReturn('提现账号不存在'); + $areas = model('areas')->getParentNames($acc['accAreaId']); + //加载用户 + $user = model('users')->get($userId); + $userMoney = $user->userMoney; + $rechargeMoney = $user->rechargeMoney; + $payPwd = md5($payPwd.$user->loginSecret); + if($payPwd!=$user->payPwd)return WSTReturn('支付密码错误'); + if($money>($userMoney-$rechargeMoney))return WSTReturn('提取金额不能大于用户可提现金额'); + //减去要提取的金额 + $user->userMoney = $user->userMoney-$money; + $user->lockMoney = $user->lockMoney+$money; + Db::startTrans(); + try{ + $result = $user->save(); + if(false !==$result){ + //创建提现记录 + $data = []; + $data['targetType'] = 0; + $data['targetId'] = $userId; + $data['money'] = $money; + $data['accType'] = 3; + $data['accTargetName'] = $acc['bankName']; + $data['accAreaName'] = implode('',$areas); + $data['accNo'] = $acc['accNo']; + $data['accUser'] = $acc['accUser']; + $data['cashSatus'] = 0; + $data['cashConfigId'] = $accId; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['cashNo'] = ''; + $this->save($data); + $this->cashNo = $this->cashId.(fmod($this->cashId,7)); + $this->save(); + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_CASH_DRAWS'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsCashDrawsTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['CASH_NO'=>$this->cashNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.cashDrawsTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'drawMoney',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxCashDrawsTip')==1){ + $params = []; + $params['CASH_NO'] = $this->cashNo; + $params['LOGIN_NAME'] = session('WST_USER.loginName'); + $params['MONEY'] = $money; + $params['CASH_TIME'] = date('Y-m-d H:i:s'); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_CASH_DRAW','userType'=>3,'userId'=>explode(',',WSTConf('CONF.cashDrawsTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('提现申请成功,请留意系统信息',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('提现申请失败',-1); + } + } + //旺旺券提现 + public function drawWangByShop(){ + $shopId = (int)session('WST_USER.shopId'); + $userId = (int)session('WST_USER.userId'); + $money = (float)input('money'); + $payPwd = input('payPwd'); + $limitMoney = (float)WSTConf('CONF.drawCashShopLimit'); + if($money<$limitMoney)return WSTReturn('提取金额必须大于或等于¥'.$limitMoney.'方可提现'); + if($payPwd=='')return WSTReturn('操作密码不能为空'); + $shops = model('shops')->get($shopId); + //加载用户 + $user = model('users')->get($userId); + $payPwd = md5($payPwd.$user->loginSecret); + if($payPwd!=$user->payPwd)return WSTReturn('操作密码错误'); + if($money>$user->wangNum)return WSTReturn('提取金额不能大于商家的已获旺旺券额'); + //减去要提取的金额 + $user->wangNum = $user->wangNum-$money; + Db::startTrans(); + try{ + $result = $user->save(); + if(false !==$result){ + $money = round($money - (dataConf('drawWangScale')*0.01),2);//产品券手续费 + //创建提现记录 + $data = []; + $data['targetType'] = 1; + $data['targetId'] = $shopId; + $data['money'] = $money; + $data['accType'] = 3; + $data['accTargetName'] = $shops['bankName']; + $data['accAreaName'] = ''; + $data['accNo'] = $shops['bankNo']; + $data['accUser'] = $shops['accountName']; + $data['cashSatus'] = 0; + $data['cashConfigId'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['cashNo'] = ''; + $this->save($data); + $this->cashNo = $this->cashId.(fmod($this->cashId,7)); + $this->save(); + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_CASH_DRAWS'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsCashDrawsTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['CASH_NO'=>$this->cashNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.cashDrawsTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'drawMoney',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxCashDrawsTip')==1){ + $params = []; + $params['CASH_NO'] = $this->cashNo; + $params['LOGIN_NAME'] = session('WST_USER.loginName'); + $params['MONEY'] = $money; + $params['CASH_TIME'] = date('Y-m-d H:i:s'); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_CASH_DRAW','userType'=>3,'userId'=>explode(',',WSTConf('CONF.cashDrawsTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('提现申请成功,请留意系统信息',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('提现申请失败',-1); + } + } + public function drawMoneyByShop(){ + $shopId = (int)session('WST_USER.shopId'); + $userId = (int)session('WST_USER.userId'); + $money = (float)input('money'); + $accId = (float)input('accId'); + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return WSTReturn('提现申请失败'); + } + $limitMoney = (float)WSTConf('CONF.drawCashShopLimit'); + if($money<$limitMoney)return WSTReturn('提取金额必须大于或等于¥'.$limitMoney.'方可提现'); + if($payPwd=='')return WSTReturn('支付密码不能为空'); + $shops = model('shops')->get($shopId); + $shopMoney = $shops->shopMoney; + $rechargeMoney = $shops->rechargeMoney; + $areas = model('areas')->getParentNames($shops->bankAreaId); + $bank = model('banks')->get($shops->bankId); + //加载用户 + $user = model('users')->get($userId); + $payPwd = md5($payPwd.$user->loginSecret); + if($payPwd!=$user->payPwd)return WSTReturn('支付密码错误'); + if($money>($shopMoney-$rechargeMoney))return WSTReturn('提取金额不能大于商家的可提现金额'); + //减去要提取的金额 + $shops->shopMoney = $shops->shopMoney-$money; + $shops->lockMoney = $shops->lockMoney+$money; + Db::startTrans(); + try{ + $result = $shops->save(); + if(false !==$result){ + //创建提现记录 + $data = []; + $data['targetType'] = 1; + $data['targetId'] = $shopId; + $data['money'] = $money; + $data['accType'] = 3; + $data['accTargetName'] = $bank['bankName']; + $data['accAreaName'] = implode('',$areas); + $data['accNo'] = $shops['bankNo']; + $data['accUser'] = $shops['bankUserName']; + $data['cashSatus'] = 0; + $data['cashConfigId'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['cashNo'] = ''; + $this->save($data); + $this->cashNo = $this->cashId.(fmod($this->cashId,7)); + $this->save(); + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_CASH_DRAWS'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsCashDrawsTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['CASH_NO'=>$this->cashNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.cashDrawsTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'drawMoney',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxCashDrawsTip')==1){ + $params = []; + $params['CASH_NO'] = $this->cashNo; + $params['LOGIN_NAME'] = session('WST_USER.loginName'); + $params['MONEY'] = $money; + $params['CASH_TIME'] = date('Y-m-d H:i:s'); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_CASH_DRAW','userType'=>3,'userId'=>explode(',',WSTConf('CONF.cashDrawsTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('提现申请成功,请留意系统信息',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('提现申请失败',-1); + } + } + + +} diff --git a/hyhproject/common/model/ChargeItems.php b/hyhproject/common/model/ChargeItems.php new file mode 100755 index 0000000..f2991a3 --- /dev/null +++ b/hyhproject/common/model/ChargeItems.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 充值项业务处理 + */ +class ChargeItems extends Base{ + /** + * 分页 + */ + public function queryList(){ + $where = []; + $where['dataFlag'] = 1; + return $this->where($where)->field(true)->order('itemSort asc,id asc')->select(); + } + + public function getItemMoney($itmeId){ + $where = []; + $where['dataFlag'] = 1; + $where['id'] = $itmeId; + return $this->where($where)->field("chargeMoney,giveMoney")->find(); + } +} diff --git a/hyhproject/common/model/CompanyBank.php b/hyhproject/common/model/CompanyBank.php new file mode 100755 index 0000000..052d344 --- /dev/null +++ b/hyhproject/common/model/CompanyBank.php @@ -0,0 +1,81 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 会员银行卡类 + */ +class CompanyBank extends Base{ + protected $table = ''; + public function __construct(){ + parent::__construct(); + $this->table = Db::name('company_bank'); + } + public function setTable($tableName='user_bank'){ + $this->table = Db::name($tableName); + } + public function getStatusTextAttr($value,$data){ + $status = [-1=>'已拒绝',0=>'待审核',1=>'已通过']; + return $status[$data['status']]; + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getInfo($where,$field='*'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->find(); + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getField($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->value($field); + } + /** + * 获取多条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getSelect($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->paginate(input('pageSize/d',10))->toArray(); + } + /** + * 获取多条信息不分页 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getList($where,$field='id'){ + $where['dataFlag'] = 1; + return $this->table->where($where)->field($field)->select(); + } + /** + * 插入单条信息 + * @param string $data [description] + * @return [type] [description] + */ + public function insertInfo($data){ + $data['createTime'] = time(); + return $this->table->insert($data); + } + /** + * 更新单条信息 + * @param [type] $where [description] + * @param string $data [description] + * @return [type] [description] + */ + public function updateInfo($where,$data){ + return $this->table->where($where)->update($data); + } + +} + diff --git a/hyhproject/common/model/Ectwallet.php b/hyhproject/common/model/Ectwallet.php new file mode 100755 index 0000000..7ca6447 --- /dev/null +++ b/hyhproject/common/model/Ectwallet.php @@ -0,0 +1,244 @@ +<?php +namespace wstmart\common\model; +use think\Db; +class Ectwallet extends Base{ + protected $table = 'hyh_user_ectwallet'; + /** + * 获取地址列表 + */ + public function listQuery($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $where = ['userId'=>(int)$userId,'dataFlag'=>1]; + $rs = $this->order('isDefault desc, eWalletId desc')->where($where)->select(); + return $rs; + } + + /** + * 新增 + */ + public function add($uId=0){ + $data = input('post.'); + unset($data['eWalletId']); + $data['userId'] = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $data['createTime'] = time(); + if($data['userId']==0)return WSTReturn('新增失败,请先登录'); + $result = $this->validate('EctWallet.add')->allowField(true)->save($data); + if(false !== $result){ + if((int)input('post.isDefault')==1){ + $this->where("eWalletId != $this->eWalletId and userId=".$data['userId'])->setField('isDefault',0); + } + return WSTReturn('新增成功',1,['eWalletId'=>$this->eWalletId]); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * [infoById 根据钱包地址id 获取钱包地址信息] + * @param [type] $eWalletId [钱包地址id] + * @return [type] [description] + */ + public function infoById($eWalletId){ + $where['eWalletId'] = (int)($eWalletId); + $data = Db::name('user_ectwallet')->where($where)->field('eWalletId,eAddress')->find(); + if(!empty($data))return $data; + } + /** + * 编辑 + */ + public function edit($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = (int)input('post.eWalletId/d'); + $data = input('post.'); + $result = $this->validate('EctWallet.edit')->allowField(true)->save($data,['eWalletId'=>$id,'userId'=>$userId]); + //修改默认地址 + if((int)input('post.isDefault')==1) + $this->where("eWalletId != $id and userId=".$userId)->setField('isDefault',0); + if(false !== $result){ + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = input('post.eWalletId/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['eWalletId'=>$id,'userId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 设置为默认地址 + */ + public function setDefault($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = (int)input('post.eWalletId'); + $this->where(["eWalletId"=>['<>',$id],'userId'=>$userId] )->setField('isDefault',0); + $rs = $this->where("eWalletId = $id and userId=".$userId)->setField('isDefault',1); + if(false !== $rs){ + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取默认地址 + */ + public function getDefaultAddress($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $where = ['userId'=>$userId,'dataFlag'=>1,'isDefault'=>1]; + $rs = Db::name('user_ectwallet')->where($where)->field('eWalletId,eAddress')->find(); + if(empty($rs))return ''; + return $rs; + } + /** + * 获取ect数目 + */ + public function getEctAddress($uId=0){ + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + $address = cache('USER_BLOCK_ADDRESS_'.$userId); + if(!$address){ + $where = ['userId'=>$userId]; + $address= Db::name('block_user_ect_address')->where($where)->value('address'); + if($address){ + cache('USER_BLOCK_ADDRESS_'.$userId,$address,0); + } + } + return WSTReturn('',1,['userId'=>$userId,'address'=>$address]); + } + /** + * 获取ect数目 + */ + public function getEctNum($uId=0){ + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + $where = ['userId'=>$userId]; + $num = Db::name('users')->where($where)->value('userECT'); + return $num; + } + /** + * 获取ect充值记录 + */ + public function getEctRechargeLog($uId=0){ + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + if($userId==0) return WSTReturn('请先登录','-999'); + $where = ['userId'=>$userId]; + $rs['list'] = Db::name('block_user_ect_recharge_log')->where($where)->order('id desc')->field('status,value,createTime')->paginate(10)->toArray(); + $rs['address'] = ''; + $cacheData = cache('USER_BLOCK_ADDRESS_'.$userId); + if($cacheData){ + $rs['address'] = $cacheData; + }else{ + $address= Db::name('block_user_ect_address')->where($where)->value('address'); + if($address){ + $rs['address'] = $address; + cache('USER_BLOCK_ADDRESS_'.$userId,$address,0); + } + } + return $rs; + } + /** + * 获取ect提现记录 + */ + public function getUserEctCashLog($uId=0){ + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + if($userId==0) return WSTReturn('请先登录','-999'); + $where = ['userId'=>$userId]; + $rs['list'] = Db::name('user_ect_cash_log')->where($where)->order('id desc')->field('status,ectNum,toAccount,createTime')->paginate(10)->toArray(); + return $rs; + } + + /** + * 获取ect变更记录 + */ + public function getEctLog($uId=0){ + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + $where = ['userId'=>$userId]; + $rs = Db::name('user_ect_log')->where($where)->order('createTime desc')->paginate(10)->toArray(); + return $rs; + } + /** + * 提现 + */ + public function withdraw($uId=0){ + //return WSTReturn('系统调试中,请稍候重试',-1); + $userId = ((int)($uId==0))?(int)session('WST_USER.userId'):$uId; + if($userId==0)return WSTReturn('请先登录','-999'); + //获取提现ect数量 + $ectNum = abs((float)input('post.ectNum')); + //获取支付密码 + $payPwd = input('post.payPwd'); + //获取钱包地址 + $eAddress = trim(input('post.eAddress')); + $where = ['userId'=>$userId,'eAddress'=>$eAddress]; + $exist = $this->where($where)->find(); + if(empty($exist))return WSTReturn('地址不正确',-1); + if($payPwd=='')return WSTReturn('密码不能为空'); + $user = model('users')->get($userId); + //获取用户ECT数量 + $userECT = (float)$user->userECT; + if($ectNum<500)return WSTReturn('ECT数量最低提取500',-1); + //与用户ect数量作比较 + if($userECT<$ectNum)return WSTReturn('ECT数量不足',-1); + //与数据库支付密码作比较 + if(md5($payPwd.$user->loginSecret) !=$user->payPwd)return WSTReturn('支付密码错误',-1); + $fp = fopen("cash.lock", "r"); + if(flock($fp,LOCK_EX | LOCK_NB)) {//if(flock($fp,LOCK_EX))阻塞(等待)模式 + // if(Db::table('rd_user_give_coin')->where(['user_id'=>$user->hyhlm_id])->find() || Db::table('rd_user_give_car_coin')->where(['user_id'=>$user->hyhlm_id])->find()){ + // flock($fp,LOCK_UN); + // fclose($fp); + // return WSTReturn('系统调试中,请稍候重试',-1); + // } + // if($user->userType == 0){ + // flock($fp,LOCK_UN); + // fclose($fp); + // return WSTReturn('系统调试中,请稍候重试',-1); + // } + $dataSrc = 4; + $remark ="提现"; + $ectType = 2; + $update =array('userECT'=>['exp','userECT-'.$ectNum]); + Db::startTrans(); + try { + $rs = ectLog($userId,$ectNum,$dataSrc,$remark,$update,$ectType); + $cash_id = $this->ectCashLog($userId,$ectNum,$eAddress,''); + if($rs && $cash_id){ + flock($fp,LOCK_UN); + fclose($fp); + Db::commit(); + return WSTReturn('提现成功,预计审核次日到账(节假日顺延),请耐心等待!',-1); + // return WSTReturn('提现成功',1,['id'=>$cash_id]); + }else{ + Db::rollback();errLog($e); + flock($fp,LOCK_UN); + fclose($fp); + return WSTReturn('提现失败,请重试!',-1); + } + } catch (Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('提现失败,请重试',-1); + } + }else{ + fclose($fp); + return WSTReturn('系统繁忙,请稍后再试'); + } + } + function ectCashLog($userId,$ectNum,$toAccount,$remark=''){ + $data['userId'] = $userId; + $data['ectNum'] = $ectNum; + $data['toAccount'] = $toAccount; + $data['dataRemarks'] = $remark; + $data['createTime'] = time(); + // $disabled_ids = [888,1843,15,892,1359,2150]; + // if(in_array($userId,$disabled_ids)){ + // $data['status'] = 2; + // } + return Db::name('user_ect_cash_log')->insertGetid($data); + } +} \ No newline at end of file diff --git a/hyhproject/common/model/Express.php b/hyhproject/common/model/Express.php new file mode 100755 index 0000000..482668d --- /dev/null +++ b/hyhproject/common/model/Express.php @@ -0,0 +1,15 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 快递业务处理类 + */ +use think\Db; +class Express extends Base{ + /** + * 获取快递列表 + */ + public function listQuery(){ + return $this->where('dataFlag',1)->select(); + } +} diff --git a/hyhproject/common/model/Favorites.php b/hyhproject/common/model/Favorites.php new file mode 100755 index 0000000..c6340ca --- /dev/null +++ b/hyhproject/common/model/Favorites.php @@ -0,0 +1,118 @@ +<?php +namespace wstmart\common\model; +use think\Db; +use wstmart\common\model\Shops; +/** + * ============================================================================ + * 收藏类 + */ +class Favorites extends Base{ + /** + * 关注的商品列表 + */ + public function listGoodsQuery(){ + $pagesize = input("param.pagesize/d"); + $userId = (int)session('WST_USER.userId'); + $page = Db::name("favorites")->alias('f') + ->join('__GOODS__ g','g.goodsId = f.targetId','left') + ->join('__SHOPS__ s','s.shopId = g.shopId','left') + ->field('f.favoriteId,f.targetId,g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,g.appraiseNum,s.shopId,s.shopName') + ->where(['f.userId'=> $userId,'favoriteType'=> 0]) + ->order('f.favoriteId desc') + ->paginate($pagesize)->toArray(); + foreach ($page['Rows'] as $key =>$v){ + //认证 + $shop = new Shops(); + $accreds = $shop->shopAccreds($v["shopId"]); + $page['Rows'][$key]['accreds'] = $accreds; + } + return $page; + } + /** + * 关注的店铺列表 + */ + public function listShopQuery(){ + $pagesize = input("param.pagesize/d"); + $userId = (int)session('WST_USER.userId'); + $page = Db::name("favorites")->alias('f') + ->join('__SHOPS__ s','s.shopId = f.targetId','left') + ->field('f.favoriteId,f.targetId,s.shopId,s.shopName,s.shopImg') + ->where(['f.userId'=> $userId,'favoriteType'=> 1]) + ->order('f.favoriteId desc') + ->paginate($pagesize)->toArray(); + foreach ($page['Rows'] as $key =>$v){ + //商品列表 + $goods = db('goods')->where(['dataFlag'=> 1,'isSale'=>1,'goodsStatus'=> 1,'shopId'=> $v["shopId"]])->field('goodsId,goodsName,shopPrice,goodsImg') + ->limit(10)->order('saleTime desc')->select(); + $page['Rows'][$key]['goods'] = $goods; + } + return $page; + } + /** + * 取消关注 + */ + public function del(){ + $id = input("param.id"); + $type = input("param.type/d"); + $userId = (int)session('WST_USER.userId'); + $ids = explode(',',$id); + + if(empty($ids))return WSTReturn("取消失败", -1); + $rs = $this->where(['favoriteId'=> ['in',$ids],'favoriteType'=> $type,'userId'=>$userId])->delete(); + if(false !== $rs){ + return WSTReturn("取消成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + + /** + * 新增关注 + */ + public function add(){ + $id = input("param.id/d"); + $type = input("param.type/d"); + $userId = (int)session('WST_USER.userId'); + if($userId==0)return WSTReturn('关注失败,请先登录'); + //判断记录是否存在 + $isFind = false; + if($type==0){ + $c = Db::name('goods')->where(['goodsStatus'=>1,'dataFlag'=>1,'goodsId'=>$id])->count(); + $isFind = ($c>0); + }else{ + $c = Db::name('shops')->where(['shopStatus'=>1,'dataFlag'=>1,'shopId'=>$id])->count(); + $isFind = ($c>0); + } + if(!$isFind)return WSTReturn("关注失败,无效的关注对象", -1); + $data = []; + $data['userId'] = $userId; + $data['favoriteType'] = $type; + $data['targetId'] = $id; + //判断是否已关注 + $rc = $this->where($data)->count(); + if($rc>0)return WSTReturn("关注成功", 1); + $data['createTime'] = date('Y-m-d H:i:s'); + $rs = $this->save($data); + if(false !== $rs){ + return WSTReturn("关注成功", 1,['fId'=>$this->favoriteId]); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 判断是否已关注 + */ + public function checkFavorite($id,$type,$uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $rs = $this->where(['userId'=>$userId,'favoriteType'=>$type,'targetId'=>$id])->find(); + return empty($rs)?0:$rs['favoriteId']; + } + /** + * 关注数 + */ + public function followNum($id,$type){ + $rs = $this->where(['favoriteType'=>$type,'targetId'=>$id])->count(); + return $rs; + } +} diff --git a/hyhproject/common/model/Goods.php b/hyhproject/common/model/Goods.php new file mode 100755 index 0000000..f1ac10f --- /dev/null +++ b/hyhproject/common/model/Goods.php @@ -0,0 +1,229 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends Base{ + /** + * 获取店铺商品列表 + */ + public function shopGoods($shopId){ + $msort = input("param.msort/d"); + $mdesc = input("param.mdesc/d"); + $order = array('g.saleTime'=>'desc'); + $orderFile = array('1'=>'g.isHot','2'=>'g.saleNum','3'=>'g.shopPrice','4'=>'g.shopPrice','5'=>'(gs.totalScore/gs.totalUsers)','6'=>'g.saleTime'); + $orderSort = array('0'=>'asc','1'=>'desc'); + if($msort>0){ + $order = array($orderFile[$msort]=>$orderSort[$mdesc]); + } + $goodsName = input("param.goodsName");//搜索店鋪名 + $words = $where = $where2 = $where3 = $where4 = []; + if($goodsName!=""){ + $words = explode(" ",$goodsName); + } + if(!empty($words)){ + $sarr = array(); + foreach ($words as $key => $word) { + if($word!=""){ + $sarr[] = "g.goodsName like '%$word%'"; + } + } + $where4 = implode(" or ", $sarr); + } + $sprice = input("param.sprice");//开始价格 + $eprice = input("param.eprice");//结束价格 + if($sprice!="")$where2 = "g.shopPrice >= ".(float)$sprice; + if($eprice!="")$where3 = "g.shopPrice <= ".(float)$eprice; + $ct1 = input("param.ct1/d"); + $ct2 = input("param.ct2/d"); + if($ct1>0)$where['shopCatId1'] = $ct1; + if($ct2>0)$where['shopCatId2'] = $ct2; + $goods = Db::name('goods')->alias('g') + ->join('__GOODS_SCORES__ gs','gs.goodsId = g.goodsId','left') + ->where(['g.shopId'=>$shopId,'g.isSale'=>1,'g.goodsStatus'=>1,'g.dataFlag'=>1]) + ->where($where)->where($where2)->where($where3)->where($where4) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,g.appraiseNum,g.goodsStock,g.isFreeShipping,g.saleTime,gallery')//添加上架时间 mark 20170103 + ->order($order) + ->paginate(input('pagesize/d'))->toArray(); + return $goods; + } + /** + * 新增商品 + */ + public function goodsAdd(){ + $shopId = (int)input('post.shopId'); + $data = input('post.'); + $specsIds = input('post.specsIds'); + $basicsMoney = isset($data['basicsMoney']) ? $data['basicsMoney'] : 0; + if(!is_numeric($basicsMoney)){ + return WSTReturn("商品成本价请填写数字"); + } + $aloneShop = false;//Db::name('alone_shops')->where(['shopId'=>$shopId,'dataFlag'=>1])->find(); + // if($aloneShop && !$basicsMoney){ + // return WSTReturn("请填写成本价"); + // } + WSTUnset($data,'goodsId,statusRemarks,goodsStatus,dataFlag,basicsMoney'); + if(isset($data['goodsName'])){ + if(!WSTCheckFilterWords($data['goodsName'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品名称包含非法字符"); + } + } + if(isset($data['goodsTips'])){ + if(!WSTCheckFilterWords($data['goodsTips'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品促销信息包含非法字符"); + } + } + if(isset($data['goodsDesc'])){ + if(!WSTCheckFilterWords($data['goodsDesc'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品描述包含非法字符"); + } + } + if(WSTConf("CONF.isGoodsVerify")==1){ + $data['goodsStatus'] = 0; + }else{ + $data['goodsStatus'] = 1; + } + $data['shopId'] = $shopId; + $data['saleTime'] = date('Y-m-d H:i:s'); + $data['createTime'] = date('Y-m-d H:i:s'); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + $data['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + if($data['goodsType']==0){ + $data['isSpec'] = ($specsIds!='')?1:0; + }else{ + $data['isSpec'] = 0; + } + Db::startTrans(); + try{ + //保存插件数据钩子 + hook('beforeEidtGoods',['data'=>&$data]); + + $shop = model('shops')->get($shopId); + if($shop['dataFlag'] ==-1 || $shop['shopStatus'] != 1)$data['isSale'] = 0; + $result = $this->validate(true)->allowField(true)->save($data); + if(false !== $result){ + $goodsId = $this->goodsId; + //ect支付方式 + // $ectPay=(int)input('ectPay'); + // $ect['goodsId']=$goodsId; + // $ect['ectPay']=$ectPay; + // Db::name('goods_pay')->insert($ect); + //商品图片 + WSTUseImages(0, $goodsId, $data['goodsImg']); + //商品相册 + WSTUseImages(0, $goodsId, $data['gallery']); + //商品描述图片 + WSTEditorImageRocord(0, $goodsId, '',$data['goodsDesc']); + //建立商品评分记录 + $gs = []; + $gs['goodsId'] = $goodsId; + $gs['shopId'] = $shopId; + Db::name('goods_scores')->insert($gs); + //如果是实物商品并且有销售规格则保存销售和规格值 + if($data['goodsType']==0 && $specsIds!=''){ + $specsIds = explode(',',$specsIds); + $specsArray = []; + foreach ($specsIds as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsArray))$specsArray[] = $vv; + } + } + //保存规格名称 + $specMap = []; + foreach ($specsArray as $v){ + $vv = explode('_',$v); + $sitem = []; + $sitem['shopId'] = $shopId; + $sitem['catId'] = (int)$vv[0]; + $sitem['goodsId'] = $goodsId; + $sitem['itemName'] = input('post.specName_'.$vv[0]."_".$vv[1]); + $sitem['itemImg'] = input('post.specImg_'.$vv[0]."_".$vv[1]); + $sitem['dataFlag'] = 1; + $sitem['createTime'] = date('Y-m-d H:i:s'); + $itemId = Db::name('spec_items')->insertGetId($sitem); + if($sitem['itemImg']!='')WSTUseImages(0, $itemId, $sitem['itemImg']); + $specMap[$v] = $itemId; + } + //保存销售规格 + $defaultPrice = 0;//最低价 + $totalStock = 0;//总库存 + $gspecArray = []; + $isFindDefaultSpec = false; + $defaultSpec = Input('post.defaultSpec'); + foreach ($specsIds as $v){ + $vs = explode('-',$v); + $goodsSpecIds = []; + foreach ($vs as $gvs){ + $goodsSpecIds[] = $specMap[$gvs]; + } + $gspec = []; + $gspec['specIds'] = implode(':',$goodsSpecIds); + $gspec['shopId'] = $shopId; + $gspec['goodsId'] = $goodsId; + $gspec['productNo'] = Input('productNo_'.$v); + $gspec['marketPrice'] = (float)Input('marketPrice_'.$v); + $gspec['specPrice'] = (float)Input('specPrice_'.$v); + $gspec['specStock'] = (int)Input('specStock_'.$v); + $gspec['warnStock'] = (int)Input('warnStock_'.$v); + //设置默认规格 + if($defaultSpec==$v){ + $isFindDefaultSpec = true; + $defaultPrice = $gspec['specPrice']; + $gspec['isDefault'] = 1; + }else{ + $gspec['isDefault'] = 0; + } + $gspecArray[] = $gspec; + //获取总库存 + $totalStock = $totalStock + $gspec['specStock']; + } + if(!$isFindDefaultSpec)return WSTReturn("请选择推荐规格"); + if(count($gspecArray)>0){ + Db::name('goods_specs')->insertAll($gspecArray); + //更新默认价格和总库存 + $this->where('goodsId',$goodsId)->update(['isSpec'=>1,'shopPrice'=>$defaultPrice,'goodsStock'=>$totalStock]); + } + } + //保存商品属性 + $attrsArray = []; + $attrRs = Db::name('attributes')->where(['goodsCatId'=>['in',$goodsCats],'isShow'=>1,'dataFlag'=>1]) + ->field('attrId')->select(); + foreach ($attrRs as $key =>$v){ + $attrs = []; + $attrs['attrVal'] = input('attr_'.$v['attrId']); + if($attrs['attrVal']=='')continue; + $attrs['shopId'] = $shopId; + $attrs['goodsId'] = $goodsId; + $attrs['attrId'] = $v['attrId']; + $attrs['createTime'] = date('Y-m-d H:i:s'); + $attrsArray[] = $attrs; + } + if(count($attrsArray)>0)Db::name('goods_attributes')->insertAll($attrsArray); + + + if($aloneShop){ + //保存商品成本价 + $basicsArray = []; + $now = time(); + $basicsArray['shopId'] = $shopId; + $basicsArray['goodsId'] = $goodsId; + $basicsArray['basicsMoney'] = $basicsMoney; + $basicsArray['createTime'] = $now; + Db::name('alone_goods')->insert($basicsArray); + } + hook('afterGoodsEct',['data'=>&$data,'goodsId'=>$goodsId]); + Db::commit(); + return WSTReturn("新增成功", 1,['id'=>$goodsId]); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败',-1); + } + } + +} diff --git a/hyhproject/common/model/GoodsAppraises.php b/hyhproject/common/model/GoodsAppraises.php new file mode 100755 index 0000000..0f0cd15 --- /dev/null +++ b/hyhproject/common/model/GoodsAppraises.php @@ -0,0 +1,327 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 评价类 + */ +use think\Db; +class GoodsAppraises extends Base{ + public function queryByPage(){ + $shopId = (int)session('WST_USER.shopId'); + + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['g.goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['g.shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['g.shopCatId1'] = $c1Id; + } + $where['g.shopId'] = $shopId; + + + $model = model('goods'); + $data = $model->alias('g') + ->field('g.goodsId,g.goodsImg,g.goodsName,ga.shopReply,ga.id gaId,ga.replyTime,ga.goodsScore,ga.serviceScore,ga.timeScore,ga.content,ga.images,u.loginName') + ->join('__GOODS_APPRAISES__ ga','g.goodsId=ga.goodsId','inner') + ->join('__USERS__ u','u.userId=ga.userId','inner') + ->where($where) + ->paginate()->toArray(); + if($data !== false){ + return WSTReturn('',1,$data); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 用户评价 + */ + public function userAppraise(){ + $userId = (int)session('WST_USER.userId'); + + $where = []; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['g.isSale'] = 1; + + + $where['ga.userId'] = $userId; + + + $model = model('goods'); + $data = $model->alias('g') + ->field('g.goodsId,g.goodsImg,g.goodsName,ga.goodsScore,ga.serviceScore,ga.timeScore,ga.content,ga.images,ga.shopReply,ga.replyTime,s.shopName,u.userName,o.orderNo') + ->join('__GOODS_APPRAISES__ ga','g.goodsId=ga.goodsId','inner') + ->join('__ORDERS__ o','o.orderId=ga.orderId','inner') + ->join('__USERS__ u','u.userId=ga.userId','inner') + ->join('__SHOPS__ s','o.shopId=s.shopId','inner') + ->where($where) + ->paginate()->toArray(); + if($data !== false){ + return WSTReturn('',1,$data); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 添加评价 + */ + public function add($uId=0){ + //检测订单是否有效 + $orderId = (int)input('orderId'); + $goodsId = (int)input('goodsId'); + $goodsSpecId = (int)input('goodsSpecId'); + $orderGoodsId = (int)input('orderGoodsId'); + + // 没有传order_goods表的id + if($orderGoodsId==0)return WSTReturn('数据出错,请联系管理员'); + + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + + $goodsScore = (int)input('goodsScore'); + $timeScore = (int)input('timeScore'); + $serviceScore = (int)input('serviceScore'); + $content = input('content'); + if(isset($content)){ + if(!WSTCheckFilterWords($content,WSTConf("CONF.limitWords"))){ + return WSTReturn("点评内容包含非法字符"); + } + } + $orders = model('orders')->where(['orderId'=>$orderId,'userId'=>$userId,'dataFlag'=>1])->field('orderStatus,orderNo,isAppraise,orderScore,shopId')->find(); + if(empty($orders))return WSTReturn("无效的订单"); + if($orders['orderStatus']!=2)return WSTReturn("订单状态已改变,请刷新订单后再尝试!"); + //检测商品是否已评价 + $apCount = $this->where(['orderGoodsId'=>$orderGoodsId,'dataFlag'=>1])->count(); + if($apCount>0)return WSTReturn("该商品已评价!"); + Db::startTrans(); + try{ + //增加订单评价 + $data = []; + $data['userId'] = $userId; + $data['goodsSpecId'] = $goodsSpecId; + $data['goodsId'] = $goodsId; + $data['shopId'] = $orders['shopId']; + $data['orderId'] = $orderId; + $data['goodsScore'] = $goodsScore; + $data['serviceScore'] = $serviceScore; + $data['timeScore']= $timeScore; + $data['content'] = $content; + $data['images'] = input('images'); + $data['createTime'] = date('Y-m-d H:i:s'); + $data['orderGoodsId'] = $orderGoodsId; + $rs = $this->validate('GoodsAppraises.add')->allowField(true)->save($data); + if($rs !==false){ + $lastId = $this->id; + WSTUseImages(0, $this->id, $data['images']); + //增加商品评分 + $prefix = config('database.prefix'); + $updateSql = "update ".$prefix."goods_scores set + totalScore=totalScore+".(int)($goodsScore+$serviceScore+$timeScore).", + goodsScore=goodsScore+".(int)$goodsScore.", + serviceScore=serviceScore+".(int)$serviceScore.", + timeScore=timeScore+".(int)$timeScore.", + totalUsers=totalUsers+1,goodsUsers=goodsUsers+1,serviceUsers=serviceUsers+1,timeUsers=timeUsers+1 + where goodsId=".$goodsId; + Db::execute($updateSql); + //增加商品评价数 + Db::name('goods')->where('goodsId',$goodsId)->setInc('appraiseNum'); + //增加店铺评分 + $updateSql = "update ".$prefix."shop_scores set + totalScore=totalScore+".(int)($goodsScore+$serviceScore+$timeScore).", + goodsScore=goodsScore+".(int)$goodsScore.", + serviceScore=serviceScore+".(int)$serviceScore.", + timeScore=timeScore+".(int)$timeScore.", + totalUsers=totalUsers+1,goodsUsers=goodsUsers+1,serviceUsers=serviceUsers+1,timeUsers=timeUsers+1 + where shopId=".$orders['shopId']; + Db::execute($updateSql); + // 查询该订单是否已经完成评价,修改orders表中的isAppraise + $ogRs = Db::name('order_goods')->alias('og') + ->join('__GOODS_APPRAISES__ ga','og.orderId=ga.orderId and og.goodsId=ga.goodsId and og.goodsSpecId=ga.goodsSpecId','left') + ->where('og.orderId',$orderId)->field('og.id,ga.id gid')->select(); + $isFinish = true; + foreach ($ogRs as $key => $v){ + if($v['id']>0 && $v['gid']==''){ + $isFinish = false; + break; + } + } + //订单商品全部评价完则修改订单状态 + if($isFinish){ + if(WSTConf("CONF.isAppraisesScore")==1){ + $appraisesScore = (int)WSTConf('CONF.appraisesScore'); + if($appraisesScore>0){ + //给用户增加惠宝 + $score = []; + $score['userId'] = $userId; + $score['score'] = $appraisesScore; + $score['dataSrc'] = 1; + $score['dataId'] = $orderId; + $score['dataRemarks'] = "评价订单【".$orders['orderNo']."】获得惠宝".$appraisesScore."个"; + $score['scoreType'] = 1; + $score['createTime'] = date('Y-m-d H:i:s'); + + model('UserScores')->add($score,true); + } + } + //修改订单评价状态 + model('orders')->where('orderId',$orderId)->update(['isAppraise'=>1,'isClosed'=>1]); + } + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_APPRAISES'); + $orderGoods = Db::name('order_goods')->where(['orderId'=>$orderId,'goodsId'=>$goodsId,'goodsSpecId'=>$goodsSpecId])->field('goodsName')->find(); + + $shopId = $orders['shopId']; + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${GOODS}']; + $replace = [$orders['orderNo'],$orderGoods['goodsName']]; + + $msg = array(); + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>6,'dataId'=>$lastId]; + model("common/MessageQueues")->add($msg); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $orders['orderNo']; + $params['GOODS'] = $orderGoods['goodsName']; + + $msg = array(); + $tplCode = "WX_ORDER_APPRAISES"; + $msg["shopId"] = $shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>'','params'=>$params] ; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + Db::commit(); + return WSTReturn('评价成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('评价失败',-1); + } + + } + /** + * 根据商品id取评论 + */ + public function getById(){ + // 处理匿名 + $anonymous = (int)input('anonymous',1); + $goodsId = (int)input('goodsId'); + $where = ['ga.goodsId'=>$goodsId, + 'ga.dataFlag'=>1, + 'ga.isShow'=>1]; + // 筛选条件 + $type = input('type'); + $filterWhere = ''; + switch ($type) { + case 'pic':// 晒图 + $filterWhere['ga.images'] = ['<>','']; + break; + case 'best':// 好评 + $filterWhere = "(ga.goodsScore+ga.serviceScore+ga.timeScore)>=15*0.9"; + break; + case 'good':// 中评 + $filterWhere = "(ga.goodsScore+ga.serviceScore+ga.timeScore)>=15*0.6 and (ga.goodsScore+ga.serviceScore+ga.timeScore)<15*0.9"; + break; + case 'bad':// 差评 + $filterWhere = "(ga.goodsScore+ga.serviceScore+ga.timeScore)<15*0.6"; + break; + } + $rs = $this->alias('ga') + ->field('DISTINCT(ga.id),ga.content,ga.images,ga.shopReply,ga.replyTime,ga.createTime,ga.goodsScore,ga.serviceScore,ga.timeScore,ga.shopId,ga.orderId,s.shopName,u.userPhoto,u.loginName,u.userTotalScore,goodsSpecNames') + ->join('__USERS__ u','ga.userId=u.userId','left') + ->join('__ORDER_GOODS__ og','og.orderId=ga.orderId and og.goodsId=ga.goodsId','inner') + ->join('__SHOPS__ s','ga.shopId=s.shopId','inner') + ->where($where) + ->where($filterWhere) + ->paginate() + ->toArray(); + + foreach($rs['Rows'] as $k=>$v){ + // 格式化时间 + $rs['Rows'][$k]['createTime'] = date('Y-m-d',strtotime($v['createTime'])); + $rs['Rows'][$k]['goodsSpecNames'] = str_replace('@@_@@',',',$v['goodsSpecNames']); + // 总评分 + $rs['Rows'][$k]['avgScore'] = ceil(($v['goodsScore'] + $v['serviceScore'] + $v['timeScore'])/3); + if($anonymous){ + $start = floor((strlen($v['loginName'])/2))-1; + $rs['Rows'][$k]['loginName'] = substr_replace($v['loginName'],'***',$start,3); + } + //获取用户等级 + $rrs = WSTUserRank($v['userTotalScore']); + $rs['Rows'][$k]['userTotalScore'] = $rrs['userrankImg']; + $rs['Rows'][$k]['rankName'] = empty($rrs['rankName'])?' ':$rrs['rankName']; + } + // 获取该商品 各评价数 + $eachApprNum = $this->getGoodsEachApprNum($goodsId); + $rs['bestNum'] = $eachApprNum['best']; + $rs['goodNum'] = $eachApprNum['good']; + $rs['badNum'] = $eachApprNum['bad']; + $rs['picNum'] = $eachApprNum['pic']; + $rs['sum'] = $eachApprNum['sum']; + if($rs!==false){ + return WSTReturn('',1,$rs); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 根据商品id获取各评价数 + */ + public function getGoodsEachApprNum($goodsId){ + $rs = $this->field('(goodsScore+timeScore+serviceScore) as sumScore')->where(['dataFlag'=>1,'isShow'=>1,'goodsId'=>$goodsId])->select(); + $data = []; + $best=0; + $good=0; + $bad=0; + foreach($rs as $k=>$v){ + $sumScore = $v['sumScore']; + // 计算好、差评数 + if($sumScore >= 15*0.9){ + ++$best; + }else if($sumScore < 15*0.6){ + ++$bad; + } + } + $data['best'] = $best; + $data['bad'] = $bad; + $data['good'] = count($rs)-$best-$bad; + // 晒图评价数 + $data['pic'] = $this->where(['dataFlag'=>1,'isShow'=>1,'goodsId'=>$goodsId,'images'=>['<>','']])->count(); + // 总评价数 + $data['sum'] = $this->where(['dataFlag'=>1,'isShow'=>1,'goodsId'=>$goodsId])->count(); + return $data; + } + + /** + * 商家回复评价 + */ + public function shopReply(){ + $id = (int)input('id'); + $data['shopReply'] = input('reply'); + $data['replyTime'] = date('Y-m-d'); + $rs = $this->where('id',$id)->update($data); + if($rs !== false){ + return WSTReturn('回复成功',1); + }else{ + return WSTReturn('回复失败',-1); + } + + } +} diff --git a/hyhproject/common/model/GoodsCats.php b/hyhproject/common/model/GoodsCats.php new file mode 100755 index 0000000..21860d4 --- /dev/null +++ b/hyhproject/common/model/GoodsCats.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 商品分类类 + */ +class GoodsCats extends Base{ + /** + * 获取列表 + */ + public function listQuery($parentId,$isFloor = -1,$field='*'){ + $dbo = $this->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>$parentId]); + if($isFloor!=-1)$dbo->where('isFloor',$isFloor); + return $dbo->field($field)->order('catSort asc')->select(); + } + + /** + * 根据子分类获取其父级分类 + */ + public function getParentIs($id,$data = array()){ + $data[] = $id; + $parentId = $this->where('catId',$id)->value('parentId'); + if($parentId==0){ + krsort($data); + return $data; + }else{ + return $this->getParentIs($parentId, $data); + } + } + public function getParentNames($id){ + if($id<=0)return []; + $ids = $this->getParentIs($id); + $rs = Db::name('goodsCats')->where('catId','in',$ids)->field('catName')->order('catId desc')->select(); + $names = []; + foreach($rs as $v){ + $names[] = $v['catName']; + } + return $names; + } + /** + * 获取首页楼层 + */ + public function getFloors(){ + $cats1 = Db::name('goods_cats')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>0,'isFloor'=>1]) + ->field("catName,catId,subTitle")->order('catSort asc')->limit(10)->select(); + if(!empty($cats1)){ + $ids = []; + foreach ($cats1 as $key =>$v){ + $ids[] = $v['catId']; + } + $cats2 = []; + $rs = Db::name('goods_cats')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids],'isFloor'=>1]) + ->field("parentId,catName,catId,subTitle")->order('catSort asc')->select(); + foreach ($rs as $key => $v){ + $cats2[$v['parentId']][] = $v; + } + foreach ($cats1 as $key =>$v){ + $cats1[$key]['children'] = (isset($cats2[$v['catId']]))?$cats2[$v['catId']]:[]; + } + } + return $cats1; + } +} diff --git a/hyhproject/common/model/GoodsConsult.php b/hyhproject/common/model/GoodsConsult.php new file mode 100755 index 0000000..064f36b --- /dev/null +++ b/hyhproject/common/model/GoodsConsult.php @@ -0,0 +1,167 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 商品咨询类 + */ +class GoodsConsult extends Base{ + /** + * 根据商品id获取商品咨询 + */ + public function listQuery(){ + $goodsId = (int)input('goodsId'); + $type = (int)input('type'); + $consultKey = input('consultKey'); + $where = []; + $where['gc.dataFlag'] = 1; + $where['gc.isShow'] = 1; + $where['gc.goodsId'] = $goodsId; + // 筛选类别 + if($type>0){$where['gc.consultType'] = $type;} + // 关键字搜索 + if($consultKey!=''){$where['gc.consultContent'] = ['like',"%$consultKey%"];} + $rs = $this->alias('gc') + ->join('__USERS__ u','u.userId=gc.userId','left') + ->field('gc.*,u.loginName') + ->where($where) + ->order('gc.createTime desc') + ->paginate(input('pagesize/d',5))->toArray(); + if(!empty($rs['Rows'])){ + foreach($rs['Rows'] as $k=>&$v){ + // 解义 + $v['consultContent'] = htmlspecialchars_decode($v['consultContent']); + // 处理匿名 + if($v['userId']>0){ + // 替换中间两个字符 + $start = floor((strlen($v['loginName'])/2))-1; + $v['loginName'] = substr_replace($v['loginName'],'**',$start,2); + } + } + } + return WSTReturn('', 1,$rs); + } + /** + * 根据商品id获取一条最新商品咨询 + */ + public function firstQuery($id){ + $where = []; + $where['gc.dataFlag'] = 1; + $where['gc.isShow'] = 1; + $where['gc.goodsId'] = $id; + $rs = $this->alias('gc')->join('__USERS__ u','u.userId=gc.userId','left') + ->where($where)->field('gc.*,u.loginName')->order('gc.createTime desc')->find(); + if(!empty($rs)){ + // 解义 + $rs['consultContent'] = htmlspecialchars_decode($rs['consultContent']); + // 处理匿名 + if($rs['userId']>0){ + // 替换中间两个字符 + $start = floor((strlen($rs['loginName'])/2))-1; + $rs['loginName'] = substr_replace($rs['loginName'],'**',$start,2); + } + } + return $rs; + } + /** + * 添加 + */ + public function add($uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $data = input('param.'); + $data['userId'] = $userId; + // 检测是否含有系统禁用关键字 + if(!WSTCheckFilterWords($data['consultContent'],WSTConf("CONF.limitWords"))){ + return WSTReturn("咨询内容包含非法字符"); + } + // 转义,防止xss攻击 + $data['consultContent'] = htmlspecialchars($data['consultContent']); + $rs = $this->validate('GoodsConsult.add')->allowField(true)->save($data); + if($rs===false){ + return WSTReturn($this->getError(),-1); + } + return WSTReturn('提交成功', 1); + } + /** + * 根据店铺id获取商品咨询 + */ + public function pageQuery(){ + // 查询条件 + $type = (int)input('consultType'); + $consultKey = (int)input('consultKey'); + $shopId = (int)session('WST_USER.shopId'); + $where = []; + $where['g.shopId'] = $shopId; + if($type>0){$where['consultType'] = $type;} + if($consultKey!=0){$where['consultContent'] = ['like',"%$consultKey%"];} + $rs = $this->alias('gc') + ->join('__USERS__ u','u.userId=gc.userId','left') + ->join('__GOODS__ g','g.goodsId=gc.goodsId','inner') + ->field('gc.*,u.loginName,g.goodsName,g.goodsImg') + ->where($where) + ->order('gc.replyTime asc,gc.createTime desc') + ->paginate(5)->toArray(); + if(!empty($rs['Rows'])){ + foreach($rs['Rows'] as $k=>&$v){ + // 解义 + $v['consultContent'] = htmlspecialchars_decode($v['consultContent']); + $v['reply'] = htmlspecialchars_decode($v['reply']); + // 处理匿名 + if($v['userId']>0){ + // 替换中间两个字符 + $start = floor((strlen($v['loginName'])/2))-1; + $v['loginName'] = substr_replace($v['loginName'],'**',$start,2); + } + } + } + return WSTReturn('', 1,$rs); + } + /** + * 商家回复 + */ + public function reply(){ + $data = input('param.'); + // 检测是否含有系统禁用关键字 + if(!WSTCheckFilterWords($data['reply'],WSTConf("CONF.limitWords"))){ + return WSTReturn("回复内容包含非法字符"); + } + // 转义,防止xss攻击 + $data['reply'] = htmlspecialchars($data['reply']); + $data['replyTime'] = date('Y-m-d H:i:s'); + // 检测是否已经回复过了 + $hasReply = $this->where(['id'=>(int)$data['id']])->value('reply'); + if($hasReply!='')return WSTReturn('该咨询已回复,请刷新页面后重试~'); + $rs = $this->validate('GoodsConsult.edit')->allowField(true)->update($data); + if($rs===false){ + return WSTReturn($this->getError(),-1); + } + return WSTReturn('提交成功', 1); + } + /** + * 根据用户id获取商品咨询 + */ + public function myConsultByPage(){ + $userId = (int)session('WST_USER.userId'); + $where = []; + $where['gc.userId'] = $userId; + $where['gc.dataFlag'] = 1; + $where['gc.isShow'] = 1; + $rs = $this->alias('gc') + ->join('__GOODS__ g','g.goodsId=gc.goodsId') + ->field('gc.*,g.goodsName,g.goodsImg') + ->where($where) + ->order('gc.createTime desc') + ->paginate(input('pagesize/d'))->toArray(); + if(!empty($rs['Rows'])){ + foreach($rs['Rows'] as $k=>&$v){ + // 解义 + $v['consultContent'] = htmlspecialchars_decode($v['consultContent']); + } + } + return WSTReturn('', 1,$rs); + } +} + + + + + diff --git a/hyhproject/common/model/GoodsVirtuals.php b/hyhproject/common/model/GoodsVirtuals.php new file mode 100755 index 0000000..433e838 --- /dev/null +++ b/hyhproject/common/model/GoodsVirtuals.php @@ -0,0 +1,11 @@ +<?php +namespace wstmart\common\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 虚拟商品卡券模型 + */ +class GoodsVirtuals extends Base{ + +} \ No newline at end of file diff --git a/hyhproject/common/model/HomeMenus.php b/hyhproject/common/model/HomeMenus.php new file mode 100755 index 0000000..784d7e3 --- /dev/null +++ b/hyhproject/common/model/HomeMenus.php @@ -0,0 +1,91 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 菜单业务处理 + */ +class HomeMenus extends Base{ + /** + * 获取菜单树 + */ + public function getMenus(){ + $data = cache('WST_HOME_MENUS'); + if(!$data){ + $rs = $this->where(['isShow'=>1,'dataFlag'=>1]) + ->field('menuId,parentId,menuName,menuUrl,menuType')->order('menuSort asc,menuId asc')->select(); + $m1 = ['0'=>[],'1'=>[]]; + $tmp = []; + + //获取第一级 + foreach ($rs as $key => $v){ + if($v['parentId']==0){ + $m1[$v['menuType']][$v['menuId']] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + }else{ + $tmp[$v['parentId']][] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + } + } + //获取第二级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($tmp[$v1['menuId']]))$m1[$key][$key1]['list'] = $tmp[$v1['menuId']]; + } + } + //获取第三级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($v1['list'])){ + foreach ($v1['list'] as $key2 => $v2){ + if(isset($tmp[$v2['menuId']]))$m1[$key][$key1]['list'][$key2]['list'] = $tmp[$v2['menuId']]; + } + } + } + } + cache('WST_HOME_MENUS',$m1,31536000); + return $m1; + } + return $data; + } + + /** + * 获取菜单URL + */ + public function getMenusUrl(){ + $data = cache('WST_PRO_MENUS'); + if(!$data){ + $list = $this->where('dataFlag',1)->order('menuType asc')->select(); + $menus = []; + foreach($list as $key => $v){ + $menus[strtolower($v['menuUrl'])] = $v['menuType']; + if($v['menuOtherUrl']!=''){ + $str = explode(',',$v['menuOtherUrl']); + foreach ($str as $vkey => $vv){ + if($vv=='')continue; + $menus[strtolower($vv)] = $v['menuType']; + } + } + } + cache('WST_PRO_MENUS',$menus,31536000); + return $menus; + } + return $data; + } + + /** + * 角色可访问url + */ + public function getShopMenuUrls(){ + $wst_user = session('WST_USER'); + $shopUrls = []; + if(!empty($wst_user)){ + $roleId = isset($wst_user["roleId"])?(int)$wst_user["roleId"]:0; + if($roleId>0){ + $role = model("home/ShopRoles")->getById($roleId); + $menuUrls = $role["menuUrls"]; + $shopUrls = array_merge($menuUrls,$shopUrls); + } + } + return $shopUrls; + } + +} diff --git a/hyhproject/common/model/Hooks.php b/hyhproject/common/model/Hooks.php new file mode 100755 index 0000000..e3a9395 --- /dev/null +++ b/hyhproject/common/model/Hooks.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 广告类 + */ +class Hooks extends Base{ + +} diff --git a/hyhproject/common/model/Informs.php b/hyhproject/common/model/Informs.php new file mode 100755 index 0000000..83cc425 --- /dev/null +++ b/hyhproject/common/model/Informs.php @@ -0,0 +1,126 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 收藏类 + */ +class Informs extends Base{ + /** + * 跳到举报列表 + */ + public function inform(){ + $id = input('id'); + $type = input('type'); + $userId = (int)session('WST_USER.userId'); + //判断用户是否拥有举报权利 + $s = Db::name('users')->where("userId=$userId")->find(); + if($s['isInform']==0)return WSTReturn("你已被禁止举报!", -1); + //判断记录是否存在 + $isFind = false; + $c = Db::name('goods')->where(['goodsStatus'=>1,'dataFlag'=>1,'goodsId'=>$id])->find(); + $isFind = ($c>0); + if(!$isFind)return WSTReturn("举报失败,无效的举报对象", -1); + $shopId = $c['shopId']; + $s = Db::name('shops')->where(['shopStatus'=>1,'dataFlag'=>1,'shopId'=>$shopId])->field('shopName,shopId')->find(); + $c = array_merge($c,$s); + return WSTReturn('',1,$c); + } + +/** + * 获取用户举报列表 + */ + public function queryUserInformByPage(){ + $userId = (int)session('WST_USER.userId'); + $informStatus = (int)Input('informStatus'); + + $where['oc.informTargetId'] = $userId; + if($informStatus>=0){ + $where['oc.informStatus'] = $informStatus; + } + $rs = $this->alias('oc') + ->join('__SHOPS__ s','oc.shopId=s.shopId','left') + ->join('__GOODS__ o','oc.goodId=o.goodsId and o.dataFlag=1','inner') + ->order('oc.informId asc') + ->where($where) + ->paginate()->toArray(); + + foreach($rs['Rows'] as $k=>$v){ + if($v['informStatus']==0){ + $rs['Rows'][$k]['informStatus'] = '等待处理'; + }elseif($v['informStatus']==1){ + $rs['Rows'][$k]['informStatus'] = '无效举报'; + }elseif($v['informStatus']==2){ + $rs['Rows'][$k]['informStatus'] = '有效举报'; + }elseif($v['informStatus']==3){ + $rs['Rows'][$k]['informStatus'] = '恶意举报'; + } + } + if($rs !== false){ + return WSTReturn('',1,$rs); + }else{ + return WSTReturn($this->getError(),-1); + } + } + // 判断是否已经举报过 + public function alreadyInform($goodsId,$userId){ + return $this->field('informId')->where("goodId=$goodsId and informTargetId=$userId")->find(); + } +/** + * 保存订单举报信息 + */ + public function saveInform(){ + + $userId = (int)session('WST_USER.userId'); + $data['goodId'] = (int)input('goodsId'); + //判断是否提交过举报 + $rs = $this->alreadyInform($data['goodId'],$userId); + if((int)$rs['informId']>0){ + return WSTReturn("该订单已进行了举报,请勿重提提交举报信息",-1); + } + Db::startTrans(); + try{ + $data['informTargetId'] = $userId; + $data['shopId'] = (int)input('shopsId'); + $data['informStatus'] = 0; + $data['informType'] = (int)input('informType'); + $data['informTime'] = date('Y-m-d H:i:s'); + $data['informAnnex'] = input('informAnnex'); + $data['informContent'] = input('informContent'); + $rs = $this->save($data); + if($rs !==false){ + + Db::commit(); + return WSTReturn('',1); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('举报失败',-1); + } + + /** + * 获取举报详情 + */ + public function getUserInformDetail($userType = 0){ + $userId = (int)session('WST_USER.userId'); + $id = (int)Input('id'); + if($userId==0){ + $where['informTargetId']=$userId; + } + + //获取举报信息 + $where['informId'] = $id; + $rs = Db::name('informs')->alias('oc') + ->field('oc.*,o.goodsId ,o.goodsName, o.goodsImg , s.shopId , s.shopName') + ->join('__SHOPS__ s','oc.shopId=s.shopId','left') + ->join('__GOODS__ o','oc.goodId=o.goodsId and o.dataFlag=1','inner') + ->where($where)->find(); + if($rs){ + if($rs['informAnnex']!='')$rs['informAnnex'] = explode(',',$rs['informAnnex']); + } + return $rs; + } +} \ No newline at end of file diff --git a/hyhproject/common/model/Invoices.php b/hyhproject/common/model/Invoices.php new file mode 100755 index 0000000..15e9d7e --- /dev/null +++ b/hyhproject/common/model/Invoices.php @@ -0,0 +1,63 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 发票信息类 + */ +class Invoices extends Base{ + /** + * 列表查询 + */ + public function pageQuery($limit=0,$uId=0){ + $userId = $uId==0?(int)session('WST_USER.userId'):$uId; + return $this->where(['userId'=>$userId,'dataFlag'=>1])->limit($limit)->select(); + } + /** + * 新增 + */ + public function add($uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $data = input('param.'); + $data['userId'] = $userId; + $data['createTime'] = date('Y-m-d H:i:s'); + $rs = $this->validate('Invoices.add')->allowField(true)->save($data); + if($rs!==false)return WSTReturn('新增成功',1,['id'=>$this->id]); + return WSTReturn($this->getError(),-1); + } + /** + * 修改 + */ + public function edit($uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $data = input('param.'); + $rs = $this->validate('Invoices.edit')->allowField(true)->save($data,['id'=>$data['id'],'userId'=>$userId]); + if($rs!==false)return WSTReturn('修改成功',1); + return WSTReturn($this->getError(),-1); + } + /** + * 删除 + */ + public function del(){ + $id = (int)input('id'); + $userId = (int)session('WST_USER.userId'); + $rs = $this->where(['id'=>$id,'userId'=>$userId])->setField(['dataFlag'=>-1]); + if($rs!==false)return WSTReturn('删除成功',1); + return WSTReturn('删除失败'); + } + /** + * 获取发票信息【存入订单表字段】 + */ + public function getInviceInfo($id){ + if($id==0)return json_encode(['invoiceHead'=>'个人']);// 所需发票为个人时 + $userId = (int)session('WST_USER.userId'); + $rs = $this->where(['id'=>$id,'userId'=>$userId,'dataFlag'=>1])->find(); + if(empty($rs))return []; + $jsonArr = []; + $jsonArr['type'] = 0;//0:纸质发票 1:电子发票【后续扩展】 + $jsonArr['invoiceHead'] = $rs['invoiceHead']; + $jsonArr['invoiceCode'] = $rs['invoiceCode']; + $jsonArr['id'] = $rs['id']; + return json_encode($jsonArr); + } + +} diff --git a/hyhproject/common/model/LogMoneys.php b/hyhproject/common/model/LogMoneys.php new file mode 100755 index 0000000..56a2d6e --- /dev/null +++ b/hyhproject/common/model/LogMoneys.php @@ -0,0 +1,187 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 资金流水业务处理器 + */ +class LogMoneys extends Base{ + /** + * 获取列表 + */ + public function pageQuery($targetType,$targetId){ + $type = (int)input('post.type',-1); + $where['targetType'] = (int)$targetType; + $where['targetId'] = (int)$targetId; + if(in_array($type,[0,1]))$where['moneyType'] = $type; + $page = $this->where($where)->order('id desc')->paginate()->toArray(); + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['dataSrc'] = WSTLangMoneySrc($v['dataSrc']); + } + return $page; + } + + /** + * 获取商家质保金流水 + */ + public function pageDeposit($targetType,$targetId){ + // $where['targetType'] = (int)$targetType; + $targetId = (int)$targetId; + $data = Db::name('shops_deposit_detail')->where(['shopId'=>$targetId])->order('payTime desc')->paginate()->toArray(); + // dump($data);die; + foreach ($data['Rows'] as &$v){ + $v['createTime'] = date('Y-m-d H:i:s',$v['payTime']); + $v['money'] = $v['cashDeposit']; + if($v['payType'] == 1){ + $v['dataSrc'] = '店铺认证通过时缴纳'; + $v['moneyType'] = 1; + }elseif($v['payType'] == 2){ + $v['dataSrc'] = '店铺订单中缴纳'; + $v['moneyType'] = 1; + }elseif($v['payType'] == 3){ + $v['dataSrc'] = '店铺充值缴纳'; + $v['moneyType'] = 1; + }elseif($v['payType'] == 4){ + $v['dataSrc'] = '店铺违规扣除'; + $v['moneyType'] = 0; + } + $v['remark'] = $v['dataSrc']; + } + + // dump($data);die; + return $data; + } + /** + * $lm['targetType'] = 1;//0:用户 1:商家 + $lm['targetId'] = $order->shopId;//用户/商家ID + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1;//1:交易订单 2:积分支出 + $lm['remark'] = '交易订单【'.$order->orderNo.'】退款剩余收入¥'.$backShopNum; + $lm['moneyType'] = 1;//1:收入 0:支出 + $lm['money'] = $backShopNum; + $lm['payType'] = 'qlgpay'; + $lm['moneyName'] = 1;//1产品券2优惠券3旺旺券4现金券 + $lm['createTime'] = $nowTime; + */ + + public function addMoneyLog($targetType,$targetId,$dataId,$dataSrc,$remark,$moneyType,$money,$payType,$moneyName=0){ + $lm['targetType'] = $targetType;//0:用户 1:商家 + $lm['targetId'] = $targetId;//用户/商家ID + $lm['dataId'] = $dataId; + $lm['dataSrc'] = $dataSrc;//1:交易订单 2:积分支出 + $lm['remark'] = $remark; + $lm['moneyType'] = $moneyType;//1:收入 0:支出 + $lm['money'] = $money; + $lm['payType'] = $payType; + $lm['moneyName'] = $moneyName; + $lm['createTime'] = date('Y-m-d H:i:s'); + $this->insert($lm); + if($moneyName && $moneyName <=3 ){ + $moneyNames = ['1'=>'productNum','2'=>'couponsNum','3'=>'wangNum']; + if($targetType == 1){ + $userId = Db::name('shops')->where('shopId',$targetId)->value('userId'); + }else{ + $userId = $targetId; + } + if($moneyType == 1){ + return Db::name('users')->where(["userId"=>$userId])->setInc($moneyNames[$moneyName],$money);//增加 + }else{ + return Db::name('users')->where(["userId"=>$userId])->setDec($moneyNames[$moneyName],$money);//减少 + } + } + return true; + } + + public function complateRecharge($obj){ + $trade_no = $obj["trade_no"]; + $orderNo = $obj["out_trade_no"]; + $targetId = (int)$obj["targetId"]; + $targetType = (int)$obj["targetType"]; + $itemId = (int)$obj["itemId"]; + $payFrom = (int)$obj["payFrom"]; + $payMoney = (float)$obj["total_fee"]; + + $log = $this->where(["tradeNo"=>$trade_no,"payType"=>$payFrom])->find(); + if(!empty($log)){ + return WSTReturn('已充值',-1); + } + Db::startTrans(); + try { + $giveMoney = 0; + if($itemId>0){ + $item = Db::name('charge_items')->where(["id"=>$itemId,"dataFlag"=>1])->field("chargeMoney,giveMoney")->find(); + $chargeMoney = $item["chargeMoney"]; + if($payMoney>=$chargeMoney){ + $giveMoney = $item["giveMoney"]; + } + } + $chargeMoney = $payMoney+$giveMoney; + if($targetType==1){ + $data = array(); + $data["shopMoney"] = array("exp","shopMoney+".$chargeMoney); + $data["rechargeMoney"] = array("exp","rechargeMoney+".$chargeMoney); + model('shops')->where(["shopId"=>$targetId])->update($data); + }else{ + $data = array(); + $data["userMoney"] = array("exp","userMoney+".$chargeMoney); + $data["rechargeMoney"] = array("exp","rechargeMoney+".$chargeMoney); + model('users')->where(["userId"=>$targetId])->update($data); + } + + //创建一条充值流水记录 + $lm = []; + $lm['targetType'] = $targetType; + $lm['targetId'] = $targetId; + $lm['dataId'] = $orderNo; + $lm['dataSrc'] = 4; + $lm['remark'] = '钱包充值 ¥'.$payMoney.(($giveMoney>0)?("元,送 ¥".$giveMoney." 元"):" 元"); + $lm['moneyType'] = 1; + $lm['money'] = $chargeMoney; + $lm['payType'] = $payFrom; + $lm['tradeNo'] = $trade_no; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->save($lm); + Db::commit(); + return WSTReturn('充值成功',1); + } catch (Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('充值失败',-1); + } + } + + /** + * 新增记录 + */ + public function add($log){ + $log['createTime'] = date('Y-m-d H:i:s'); + //dump($log); + if($log['moneyType']==1){ + if($log['targetType']==1){ + if($log['payType']==='ect'){ + ectLog($log['targetId'],$log['money'],12,'结算',['userECT'=>['exp','userECT+'.$log['money']]],1); + }else { + + Db::name('shops')->where(["shopId" => $log['targetId']])->setInc('shopMoney', $log['money']); + } + }else{ + if($log['payType']==='ect'){ +//dump('gfdgfd'); + ectLog($log['targetId'],$log['money'],13,'退款',['userECT'=>['exp','userECT+'.$log['money']]],1); + }else{ + Db::name('users')->where(["userId"=>$log['targetId']])->setInc('userMoney',$log['money']); + } + + } + }else{ + if($log['targetType']==1){ + Db::name('shops')->where(["shopId"=>$log['targetId']])->setDec('shopMoney',$log['money']); + }else{ + if($log['payType']==='ect'){ + ectLog($log['targetId'],$log['money'],11,'购物',['userECT'=>['exp','userECT-'.$log['money']]],2); + }else{ + Db::name('users')->where(["userId"=>$log['targetId']])->setDec('userMoney',$log['money']); + } + } + } + } +} diff --git a/hyhproject/common/model/LogPayParams.php b/hyhproject/common/model/LogPayParams.php new file mode 100755 index 0000000..06ad967 --- /dev/null +++ b/hyhproject/common/model/LogPayParams.php @@ -0,0 +1,36 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 支付参数日志类 + */ +class LogPayParams extends Base{ + + /** + * 添加支付日志 + */ + public function addPayLog($obj){ + $this->delPayLog(["transId"=>$obj["transId"]]); + $obj['createTime'] = date('Y-m-d H:i:s'); + $this->insert($obj); + } + + /** + * 获取支付日志 + */ + public function getPayLog($obj){ + $rs = $this->where($obj)->find(); + if(!empty($rs)){ + return json_decode($rs["paramsVa"],true); + } + return $rs; + } + + /** + * 删除支付日志 + */ + public function delPayLog($obj){ + return $this->where($obj)->delete(); + } + +} diff --git a/hyhproject/common/model/LogPays.php b/hyhproject/common/model/LogPays.php new file mode 100755 index 0000000..099d995 --- /dev/null +++ b/hyhproject/common/model/LogPays.php @@ -0,0 +1,32 @@ +<?php +namespace wstmart\common\model; +use think; +/** + * ============================================================================ + * 支付日志类 + */ +class LogPays extends Base{ + + /** + * 添加支付日志 + */ + public function addPayLog($obj){ + $obj['createTime'] = date('Y-m-d H:i:s'); + $this->insert($obj); + } + + /** + * 获取支付日志 + */ + public function getPayLog($obj){ + return $this->where($obj)->find(); + } + + /** + * 删除支付日志 + */ + public function delPayLog($obj){ + return $this->where($obj)->delete(); + } + +} diff --git a/hyhproject/common/model/LogSms.php b/hyhproject/common/model/LogSms.php new file mode 100755 index 0000000..d1d92c1 --- /dev/null +++ b/hyhproject/common/model/LogSms.php @@ -0,0 +1,112 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 短信日志类 + */ +class LogSms extends Base{ + + /** + * 写入并发送短讯记录 + */ + public function sendSMS($smsSrc,$phoneNumber,$params,$smsFunc,$verfyCode,$userId=0){ + //判断有没有开启短信功能 + if((int)WSTConf('CONF.smsOpen')==0)return WSTReturn('未开启短信接口'); + $userId = $userId>0?(int)session('WST_USER.userId'):$userId; + $ip = request()->ip(); + + //检测短信验证码验证是否正确 + //if(WSTConf("CONF.smsVerfy")==1){ + // if(WSTVisitModule() == 'home'){//pc版的有验证码 mark 2011204 + // $smsverfy = input("post.smsVerfy"); + // $rs = WSTVerifyCheck($smsverfy); + // if(!$rs){ + // return WSTReturn("验证码不正确!",-2); + // } + // } + //} + //检测是否超过每日短信发送数 + $date = date('Y-m-d'); + $smsRs = $this->field("count(smsId) counts,max(createTime) createTime") + ->where(["smsPhoneNumber"=>$phoneNumber]) + ->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->find(); + if($smsRs['counts']>(int)WSTConf("CONF.smsLimit")){ + return WSTReturn("超出每日短信限制!"); + } + if($smsRs['createTime'] !='' && ((time()-strtotime($smsRs['createTime']))<120)){ + return WSTReturn("请勿频繁发送短信验证"); + } + //检测IP是否超过发短信次数 + $ipRs = $this->field("count(smsId) counts,max(createTime) createTime") + ->where(["smsIP"=>$ip]) + ->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->find(); + if($ipRs['counts']>(int)WSTConf("CONF.smsLimit")){ + return WSTReturn("发送短信验证次数过多!"); + } + //if($ipRs['createTime']!='' && ((time()-strtotime($ipRs['createTime']))<120)){ + // return WSTReturn("请勿频繁发送短信验证!"); + //} + $data = array(); + $data['smsSrc'] = $smsSrc; + $data['smsUserId'] = $userId; + $data['smsPhoneNumber'] = $phoneNumber; + $data['smsContent'] = 'N/A'; + $data['smsReturnCode'] = ''; + $data['smsCode'] = $verfyCode; + $data['smsIP'] = $ip; + $data['smsFunc'] = $smsFunc; + $data['createTime'] = date('Y-m-d H:i:s'); + $this->data($data)->save(); + $rdata = ['msg'=>'短信发送失败!','status'=>-1]; + hook('sendSMS',['phoneNumber'=>$phoneNumber,"params"=>$params,'smsId'=>$this->smsId,'status'=>&$rdata]); + return $rdata; + } + /** 商家短信通知 mark hsf 20180421*/ + public function sendShopSMS($smsSrc,$phoneNumber,$params,$smsFunc,$verfyCode,$userId){ + //判断有没有开启短信功能 + if((int)WSTConf('CONF.smsOpen')==0)return WSTReturn('未开启短信接口'); + + //$shopInfo = GetShopInfo($shopId,'userId'); + $ip = request()->ip(); + + $data = array(); + $data['smsSrc'] = $smsSrc; + $data['smsUserId'] = $userId; + $data['smsPhoneNumber'] = $phoneNumber; + $data['smsContent'] = 'N/A'; + $data['smsReturnCode'] = ''; + $data['smsCode'] = $verfyCode; + $data['smsIP'] = $ip; + $data['smsFunc'] = $smsFunc; + $data['createTime'] = date('Y-m-d H:i:s'); + $this->save($data); + //dump($params); + //$rdata = ['msg'=>'短信发送失败!','status'=>-1]; + hook('sendSMS',['phoneNumber'=>$phoneNumber,"params"=>$params,'smsId'=>$this->smsId,'status'=>&$rdata]); + return $rdata; + } + /** + * 写入并发送管理员短讯记录 + */ + public function sendAdminSMS($smsSrc,$phoneNumber,$params,$smsFunc,$verfyCode,$userId=0){ + //判断有没有开启短信功能 + if((int)WSTConf('CONF.smsOpen')==0)return WSTReturn('未开启短信接口'); + $userId = $userId>0?(int)session('WST_USER.userId'):$userId; + $ip = request()->ip(); + + $data = array(); + $data['smsSrc'] = $smsSrc; + $data['smsUserId'] = $userId; + $data['smsPhoneNumber'] = $phoneNumber; + $data['smsContent'] = 'N/A'; + $data['smsReturnCode'] = ''; + $data['smsCode'] = $verfyCode; + $data['smsIP'] = $ip; + $data['smsFunc'] = $smsFunc; + $data['createTime'] = date('Y-m-d H:i:s'); + $this->save($data); + $rdata = ['msg'=>'短信发送失败!','status'=>-1]; + hook('sendSMS',['phoneNumber'=>$phoneNumber,"params"=>$params,'smsId'=>$this->smsId,'status'=>&$rdata]); + return $rdata; + } +} diff --git a/hyhproject/common/model/MessageQueues.php b/hyhproject/common/model/MessageQueues.php new file mode 100755 index 0000000..426f8af --- /dev/null +++ b/hyhproject/common/model/MessageQueues.php @@ -0,0 +1,72 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 消息队列 + */ +class MessageQueues extends Base{ + /** + * 新增 + */ + public function add($param){ + $shopId = $param["shopId"]; + $tplCode = $param["tplCode"]; + $msgcat = Db::name("shop_message_cats")->where(["msgCode"=>$tplCode])->find(); + $msgDataId = $msgcat["msgDataId"]; + $msgType = $param['msgType']; + $dbo = Db::name("shop_roles sr") + ->join("__SHOP_USERS__ su","sr.id=su.roleId"); + if($msgType==4){ + $dbo = $dbo->join("__USERS__ u","su.userId=u.userId") + ->where("u.wxOpenId!=''"); + } + // 'SELECT `su`.`userId` FROM hyh_shop_roles sr INNER JOIN `hyh_shop_users` `su` ON `sr`.`id`=`su`.`roleId` WHERE ( su.dataFlag=1 and FIND_IN_SET(1,sr.privilegeMsgs) )' + //添加店铺ID验证 mark hsf 20180403 + $list = $dbo->where("su.dataFlag=1 AND FIND_IN_SET(".$msgDataId.",sr.privilegeMsgs) AND su.shopId={$shopId}")->field("su.userId")->select(); + $suser = array(); + if($msgType==4){ + $suser = Db::name("shop_users su")->join("__USERS__ u","su.userId=u.userId") + ->where(["su.shopId"=>$shopId,"su.roleId"=>0]) + ->where("u.wxOpenId!=''") + ->field("su.userId")->find(); + }else{ + $suser = Db::name("shop_users")->where(["shopId"=>$shopId,"roleId"=>0])->field("userId")->find(); + } + if(!empty($suser)){ + $list[] = $suser; + } + if($msgType==1){ + foreach ($list as $key => $user) { + WSTSendMsg($user['userId'],$param['content'],$param['msgJson'],$msgType); + } + }else{ + $dataAll = []; + $paramJson = $param["paramJson"]; + foreach ($list as $key => $user) { + $data = []; + $paramJson["userId"] = $user["userId"]; + $data['userId'] = $user["userId"]; + $data['msgType'] = $msgType; + $data['msgCode'] = $param['tplCode']; + $data['paramJson'] = json_encode($paramJson); + $data['msgJson'] = $param['msgJson']; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['sendStatus'] = 0; + $dataAll[] = $data; + } + Db::name("message_queues")->insertAll($dataAll); + } + + } + /** + * 发送成功修改状态 + */ + public function edit($id){ + $data = []; + $data['sendStatus'] = 1; + $result = $this->where(["id"=>$id])->save($data); + return $result; + } + +} diff --git a/hyhproject/common/model/Messages.php b/hyhproject/common/model/Messages.php new file mode 100755 index 0000000..f596c2b --- /dev/null +++ b/hyhproject/common/model/Messages.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\common\model; +use wstmart\home\model\Shops; +/** + * ============================================================================ + * 商城消息 + */ +class Messages extends Base{ + /** + * 获取列表 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $where = ['receiveUserId'=>(int)$userId,'dataFlag'=>1]; + $page = model('Messages')->where($where)->order('msgStatus asc,id desc')->paginate(input('pagesize/d'))->toArray(); + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['msgContent'] = WSTMSubstr(strip_tags(htmlspecialchars_decode($v['msgContent'])),0,140); + } + return $page; + } + /** + * 获取某一条消息详情 + */ + public function getById(){ + $userId = (int)session('WST_USER.userId'); + $id = (int)input('msgId'); + $data = $this->get(['id'=>$id,'receiveUserId'=>$userId]); + if(!empty($data)){ + $data['msgContent'] = htmlspecialchars_decode($data['msgContent']); + if($data['msgStatus']==0) + model('Messages')->where('id',$id)->setField('msgStatus',1); + } + return $data; + } + + /** + * 删除 + */ + public function del(){ + $userId = (int)session('WST_USER.userId'); + $id = input('id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>$id,'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 批量删除 + */ + public function batchDel(){ + $userId = (int)session('WST_USER.userId'); + $ids = input('ids/a'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['id'=>['in',$ids],'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 标记为已读 + */ + public function batchRead(){ + $userId = (int)session('WST_USER.userId'); + $ids = input('ids/a'); + $data = []; + $data['msgStatus'] = 1; + $result = $this->update($data,['id'=>['in',$ids],'receiveUserId'=>$userId]); + if(false !== $result){ + return WSTReturn("操作成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + +} diff --git a/hyhproject/common/model/OrderComplains.php b/hyhproject/common/model/OrderComplains.php new file mode 100755 index 0000000..0ef5607 --- /dev/null +++ b/hyhproject/common/model/OrderComplains.php @@ -0,0 +1,292 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 订单投诉类 + */ +class OrderComplains extends Base{ + /** + * 获取用户投诉列表 + */ + public function queryUserComplainByPage(){ + $userId = (int)session('WST_USER.userId'); + $orderNo = (int)Input('orderNo'); + + $where['o.userId'] = $userId; + if($orderNo>0){ + $where['o.orderNo'] = ['like',"%$orderNo%"]; + } + $rs = $this->alias('oc') + ->field('oc.complainId,o.orderId,o.orderNo,s.shopId,s.shopName,oc.complainContent,oc.complainStatus,oc.complainTime,o.orderCode') + ->join('__SHOPS__ s','oc.respondTargetId=s.shopId','left') + ->join('__ORDERS__ o','oc.orderId=o.orderId and o.dataFlag=1','inner') + ->order('oc.complainId desc') + ->where($where) + ->paginate()->toArray(); + + foreach($rs['Rows'] as $k=>$v){ + if($v['complainStatus']==0){ + $rs['Rows'][$k]['complainStatus'] = '等待处理'; + }elseif($v['complainStatus']==1){ + $rs['Rows'][$k]['complainStatus'] = '等待被投诉方回应'; + }elseif($v['complainStatus']==2 || $v['complainStatus']==3 ){ + $rs['Rows'][$k]['complainStatus'] = '等待仲裁'; + }elseif($v['complainStatus']==4){ + $rs['Rows'][$k]['complainStatus'] = '已仲裁'; + } + $rs['Rows'][$k]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + } + if($rs !== false){ + return WSTReturn('',1,$rs); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取订单信息 + */ + public function getOrderInfo(){ + $userId = (int)session('WST_USER.userId'); + $orderId = (int)Input('orderId'); + + //判断是否提交过投诉 + $rs = $this->alreadyComplain($orderId,$userId); + $data = array('complainStatus'=>1); + if($rs['complainId']==''){ + $where['o.orderId'] = $orderId; + $where['o.userId'] = $userId; + //获取订单信息 + $order = db('orders')->alias('o') + ->field('o.realTotalMoney,o.orderNo,o.orderId,o.createTime,o.deliverMoney,s.shopName,s.shopId') + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->where($where) + ->find(); + if($order){ + //获取相关商品 + $goods = $this->getOrderGoods($orderId); + $order["goodsList"] = $goods; + } + $data['order'] = $order; + $data['complainStatus'] = 0; + } + + return $data; + } + // 判断是否已经投诉过 + public function alreadyComplain($orderId,$userId){ + return $this->field('complainId')->where("orderId=$orderId and complainTargetId=$userId")->find(); + } + //获取相关商品 + public function getOrderGoods($orderId){ + return db('goods')->alias('g') + ->field('og.orderId, og.goodsId ,g.goodsSn, og.goodsName , og.goodsPrice shopPrice,og.goodsImg') + ->join('__ORDER_GOODS__ og','g.goodsId = og.goodsId','inner') + ->where("og.orderId=$orderId") + ->select(); + } + + /** + * 保存订单投诉信息 + */ + public function saveComplain(){ + + $userId = (int)session('WST_USER.userId'); + $data['orderId'] = (int)input('orderId'); + //判断订单是否该用户的 + $order = db('orders')->field('orderId,shopId,orderNo')->where("userId=$userId")->find($data['orderId']); + if(!$order){ + return WSTReturn('无效的订单信息',-1); + } + + //判断是否提交过投诉 + $rs = $this->alreadyComplain($data['orderId'],$userId); + + if((int)$rs['complainId']>0){ + return WSTReturn("该订单已进行了投诉,请勿重提提交投诉信息",-1); + } + Db::startTrans(); + try{ + $data['complainTargetId'] = $userId; + $data['respondTargetId'] = $order['shopId']; + $data['complainStatus'] = 0; + $data['complainType'] = (int)input('complainType'); + $data['complainTime'] = date('Y-m-d H:i:s'); + $data['complainAnnex'] = input('complainAnnex'); + $data['complainContent'] = input('complainContent'); + $rs = $this->validate('OrderComplains.add')->save($data); + if($rs !==false){ + WSTUseImages(0, $this->complainId, $data['complainAnnex']); + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_COMPLAINT_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsComplaintOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.complaintOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'saveComplain',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxComplaintOrderTip')==1){ + $remark = WSTDatas('ORDER_COMPLAINT',(int)input('complainType')); + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REMARK'] = "【".$remark['dataName']."】".WSTMSubstr(input('complainContent'),0,20,'utf-8','...'); + $params['LOGIN_NAME'] = session('WST_USER.loginName'); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_COMPLAINT','userType'=>3,'userId'=>explode(',',WSTConf('CONF.complaintOrderTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('',1); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('投诉失败',-1); + } + + /** + * 获取投诉详情 + */ + public function getComplainDetail($userType = 0){ + $userId = (int)session('WST_USER.userId'); + $shopId = (int)session('WST_USER.shopId'); + $id = (int)Input('id'); + if($userType==0){ + $where['complainTargetId']=$userId; + }else{ + $where['needRespond'] = 1; + $where['respondTargetId'] = $shopId; + } + + //获取订单信息 + $where['complainId'] = $id; + $rs = $this->alias('oc') + ->field('oc.*,o.realTotalMoney,o.orderNo,o.orderId,o.createTime,o.deliverMoney,s.shopName,s.shopId') + ->join('__ORDERS__ o','oc.orderId=o.orderId','inner') + ->join('__SHOPS__ s','o.shopId=s.shopId') + ->where($where)->find(); + if($rs){ + if($rs['complainAnnex']!='')$rs['complainAnnex'] = explode(',',$rs['complainAnnex']); + if($rs['respondAnnex']!='')$rs['respondAnnex'] = explode(',',$rs['respondAnnex']); + + //获取相关商品 + $goods = $this->getOrderGoods($rs['orderId']); + $rs["goodsList"] = $goods; + } + return $rs; + } + + + + + + + /************************************* 商家 *********************************************/ + /** + * 获取商家被投诉列表 + */ + public function queryShopComplainByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $orderNo = (int)Input('orderNo'); + if($orderNo!=''){ + $where['o.orderNo'] = ['like',"%$orderNo%"]; + } + $where['oc.needRespond'] = 1; + $where['o.dataFlag'] = 1; + $where['oc.respondTargetId'] = $shopId; + $rs = $this->alias('oc') + ->field('oc.complainId,o.orderId,o.orderNo,u.userName,u.loginName,oc.complainContent,oc.complainStatus,oc.complainTime,o.orderCode') + ->join('__USERS__ u','oc.complainTargetId=u.userId','left') + ->join('__ORDERS__ o','oc.orderId=o.orderId') + ->where($where) + ->order('oc.complainId desc') + ->paginate() + ->toArray(); + foreach($rs['Rows'] as $k=>$v){ + if($v['complainStatus']==0){ + $rs['Rows'][$k]['complainStatus'] = '等待处理'; + }elseif($v['complainStatus']==1){ + $rs['Rows'][$k]['complainStatus'] = '等待被投诉方回应'; + $rs['Rows'][$k]['needReply'] = 1; + }elseif($v['complainStatus']==2 || $v['complainStatus']==3 ){ + $rs['Rows'][$k]['complainStatus'] = '等待仲裁'; + }elseif($v['complainStatus']==4){ + $rs['Rows'][$k]['complainStatus'] = '已仲裁'; + } + $rs['Rows'][$k]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + } + if($rs!==false){ + return WSTReturn('',1,$rs); + }else{ + return WSTReturn($this->getError,-1); + } + } + /** + * 保存订单应诉信息 + */ + public function saveRespond(){ + $shopId = (int)session('WST_USER.shopId'); + $complainId = (int)Input('complainId'); + //判断是否提交过应诉和是否有效的投诉信息 + $complainRs = $this->field('needRespond,complainStatus,orderId,complainType,complainContent')->where("complainId=$complainId AND respondTargetId=$shopId")->find(); + if((int)$complainRs['needRespond']!=1){ + return WSTReturn('无效的投诉信息',-1); + } + if((int)$complainRs['complainStatus']!=1){ + return WSTReturn('该投诉订单已进行了应诉,请勿重复提交应诉信息',-1); + } + Db::startTrans(); + try{ + $data['complainStatus'] = 3; + $data['respondTime'] = date('Y-m-d H:i:s'); + $data['respondAnnex'] = Input('respondAnnex'); + $data['respondContent'] = Input('respondContent'); + $rs = $this->validate('OrderComplains.respond')->where('complainId='.$complainId)->update($data); + if($rs !==false){ + WSTUseImages(0, $complainId, $data['respondAnnex']); + $order = Db::name('orders')->alias('o')->join('__USERS__ u','u.userId=o.userId') + ->where('orderId',$complainRs['orderId']) + ->field('o.orderNo,u.loginName')->find(); + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_COMPLAINT_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsComplaintOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.complaintOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'saveRespond',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxComplaintOrderTip')==1){ + $remark = WSTDatas('ORDER_COMPLAINT',$complainRs['complainType']); + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REMARK'] = "【".$remark['dataName']."】".WSTMSubstr($complainRs['complainContent'],0,20,'utf-8','...'); + $params['LOGIN_NAME'] = $order['loginName']; + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_COMPLAINT','userType'=>3,'userId'=>explode(',',WSTConf('CONF.complaintOrderTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('应诉成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('投诉失败',-1); + + + } + + +} diff --git a/hyhproject/common/model/OrderRefunds.php b/hyhproject/common/model/OrderRefunds.php new file mode 100755 index 0000000..794e1c7 --- /dev/null +++ b/hyhproject/common/model/OrderRefunds.php @@ -0,0 +1,297 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 退款业务处理类 + */ +class OrderRefunds extends Base{ + /** + * 用户申请退款 + */ + public function refund($uId=0){ + $orderId = (int)input('post.id'); + $reason = (int)input('post.reason'); + $content = input('post.content'); + + //$money = (float)input('post.money'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + //if($money<=0)return WSTReturn("请填写退款金额"); + $order = Db::name('orders')->alias('o')->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId','left')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->where(['o.userId'=>$userId,'o.orderId'=>$orderId,'o.orderStatus'=>['in',[-3,-1]]]) + ->field('o.orderId,s.userId,o.shopId,o.orderStatus,o.payFrom,o.orderNo,o.realTotalMoney,o.isPay,o.productNum,o.couponsNum,o.wangNum,o.payType,o.useScore,orf.id refundId')->find(); + $productNum = (float)input('post.productNum'); + $couponsNum = (float)input('post.couponsNum'); + $wangNum = (float)input('post.wangNum'); + if($productNum > $order['productNum']){ + return WSTReturn("最多可退产品券:".$order['productNum']); + } + if($couponsNum > $order['couponsNum']){ + return WSTReturn("最多可退优惠券:".$order['couponsNum']); + } + if($wangNum > $order['wangNum']){ + return WSTReturn("最多可退旺旺券:".$order['wangNum']); + } + $money = $productNum + $couponsNum + $wangNum; + $reasonData = WSTDatas('REFUND_TYPE',$reason); + if(empty($reasonData))return WSTReturn("无效的退款原因"); + if($reason==10000 && $content=='')return WSTReturn("请输入退款原因"); + if(empty($order))return WSTReturn('操作失败,请检查订单状态是否已改变'); + $allowRequest = false; + if($order['isPay']==1 || ($order['payType']==0 && $order['useScore']>0)){ + $allowRequest = true; + } + if(!$allowRequest)return WSTReturn("您的退款申请已提交,请留意退款信息"); + // if($money>$order['realTotalMoney'])return WSTReturn("申请退款金额不能大于实支付金额"); + //查看退款申请是否已存在 + $orfId = $this->where('orderId',$orderId)->value('id'); + // orderStatus:-3:用户拒收 -2:未付款的订单 -1:用户取消 0:待发货 1:配送中 2:用户确认收货 + Db::startTrans(); + try{ + $result = false; + //如果退款单存在就进行编辑 + if($orfId>0){ + $object = $this->get($orfId); + $object->refundReson = $reason; + if($reason==10000)$object->refundOtherReson = $content; + $object->backMoney = $money; + $object->backProductNum = $productNum; + $object->backCouponsNum = $couponsNum; + $object->backWangNum = $wangNum; + $object->refundStatus = 0; + $result = $object->save(); + }else{ + $data = []; + $data['orderId'] = $orderId; + $data['refundTo'] = 0; + $data['refundReson'] = $reason; + if($reason==10000)$data['refundOtherReson'] = $content; + $data['backMoney'] = $money; + $data['backProductNum'] = $productNum; + $data['backCouponsNum'] = $couponsNum; + $data['backWangNum'] = $wangNum; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['refundStatus'] = ($order['orderStatus']==-1)?1:0; + $result = $this->save($data); + } + if(false !== $result){ + //拒收、取消申请退款的话要给商家发送信息 + if($order['orderStatus']!=-1){ + $tpl = WSTMsgTemplates('ORDER_REFUND_CONFER'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$order['orderNo']]; + + $msg = array(); + $msg["shopId"] = $order['shopId']; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REASON'] = $reasonData['dataName'].(($reason==10000)?" - ".$content:""); + $params['MONEY'] = $money.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + + $msg = array(); + $tplCode = "WX_ORDER_REFUND_CONFER"; + $msg["shopId"] = $order['shopId']; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + }else{ + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_REFUND_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsRefundOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.refundOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'refund',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxRefundOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REASON'] = $reasonData['dataName'].(($reason==10000)?" - ".$content:""); + $params['MONEY'] = $money.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_REFUND','userType'=>3,'userId'=>explode(',',WSTConf('CONF.refundOrderTipUsers')),'params'=>$params]); + } + } + } + Db::commit(); + return WSTReturn('您的退款申请已提交,请留意退款信息',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + + /** + * 获取订单价格以及申请退款价格 + */ + public function getRefundMoneyByOrder($orderId = 0){ + $result= Db::name('orders')->alias('o')->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId')->where('orf.id',$orderId) + ->field('o.orderId,o.payFrom,orderNo,goodsMoney,deliverMoney,useScore,scoreMoney,totalMoney,realTotalMoney,orf.backMoney')->find(); + if($result['payFrom']=="ect"){ + $ectPrice=db('orders_ect')->where('orderId',$result['orderId'])->value('ectPrice'); + $result['ectNum']=$result['backMoney']/$ectPrice; + } + $result['ectNum']=isset($result['ectNum'])?$result['ectNum']:""; + return $result; + } + + /** + * 商家处理是否同意退款 + */ + public function shopRefund(){ + $id = (int)input('id'); + $refundStatus = (int)input('refundStatus'); + $content = input('content'); + if($id==0)return WSTReturn('无效的操作'); + if(!in_array($refundStatus,[1,-1]))return WSTReturn('无效的操作'); + if($refundStatus==-1 && $content=='')return WSTReturn('请输入拒绝原因'); + Db::startTrans(); + try{ + //返还商品库存 +// $goods=db('order_goods')->alias('og') +// ->join('order_refunds or','or.orderId=og.orderId','left') +// ->join('orders o','o.orderId=og.orderId','left') +// ->join('goods g','g.goodsId=og.goodsId','left') +// ->where('or.id',$id)->field('g.goodsId,g.goodsStock,g.saleNum,og.goodsNum,g.isSpec,o.orderCode') +// ->select(); +// //dump($goods);die; +// //返还商品库存 +// foreach ($goods as $key => $v){ +// //处理虚拟产品 +// if($v['orderCode']=='order'){ +// //修改库存 +// // dump($v['isSpec']);die; +// if($v['isSpec']>0){ +// Db::name('goods_specs')->where('id',$v['goodsSpecId'])->setInc('specStock',$v['goodsNum']); +// Db::name('goods_specs')->where('id',$v['goodsSpecId'])->setDec('saleNum',$v['goodsNum']); +// } +// Db::name('goods')->where('goodsId',$v['goodsId'])->setInc('goodsStock',$v['goodsNum']); +// Db::name('goods')->where('goodsId',$v['goodsId'])->setDec('saleNum',$v['goodsNum']); +// } +// +// } + $object = $this->get($id); + $order = Db::name('orders')->where('orderId',$object->orderId)->field('userId,shopId,orderNo,orderId,useScore')->find(); + if(!$order || $order['shopId'] != input('post.shopId')){ + return WSTReturn('未找到此订单'); + } + $object->refundStatus = $refundStatus; + if($object->refundStatus==-1)$object->shopRejectReason = $content; + $result = $object->save(); + if(false !== $result){ + //如果是拒收话要给用户发信息 + if($refundStatus==-1){ + $tpl = WSTMsgTemplates('ORDER_REFUND_FAIL'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REASON}']; + $replace = [$order['orderNo'],$content]; + WSTSendMsg($order['userId'],str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order['orderId']]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$object->refundReson); + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REASON'] = $reasonData['dataName'].(($object->refundReson==10000)?" - ".$object->refundOtherReson:""); + $params['SHOP_REASON'] = $object->shopRejectReason; + $params['MONEY'] = $object->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxMessage(['CODE'=>'WX_ORDER_REFUND_FAIL','userId'=>$order['userId'],'URL'=>Url('wechat/orders/index','',true,true),'params'=>$params]); + } + }else{ + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_REFUND_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsRefundOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.refundOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'shoprefund',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxRefundOrderTip')==1){ + $reasonData = WSTDatas('REFUND_TYPE',$object->refundReson); + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['REASON'] = $reasonData['dataName'].(($object->refundReson==10000)?" - ".$object->refundOtherReson:""); + $params['MONEY'] = $object->backMoney.(($order['useScore']>0)?("【退回积分:".$order['useScore']."】"):""); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_REFUND','userType'=>3,'userId'=>explode(',',WSTConf('CONF.refundOrderTipUsers')),'params'=>$params]); + } + } + } + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + /** + * 临时申请退款接口 + */ + public function byRefund($orderNo){ + //$orderNo = input('orderNo'); + $order = Db::name('orders o')->where(['o.orderNo'=>$orderNo,'o.orderStatus'=>['in',[0,1]]]) + ->field('o.orderId,o.shopId,o.orderStatus,o.orderNo,o.realTotalMoney,o.isPay,o.payType,o.useScore')->find(); + if(empty($order))return WSTReturn('操作失败,请检查订单状态是否已改变',-1); + $allowRequest = false; + if($order['isPay']==1 || ($order['payType']==0 && $order['useScore']>0)){ + $allowRequest = true; + } + $isfind = false; + if($this->where(['orderId'=>$order['orderId']])->find()){ + $isfind = true; + } + if(!$allowRequest || $isfind)return WSTReturn("退款申请已提交,请不要重复提交",-1); + $money=$order['realTotalMoney']; + Db::startTrans(); + try{ + if($order['orderStatus']==0){ + db('orders')->where('orderNo',$orderNo)->update(['orderStatus'=>-1]); + } + if($order['orderStatus']==1){ + db('orders')->where('orderNo',$orderNo)->update(['orderStatus'=>-3]); + } + $result = false; + //退款单进行编辑 + $data = []; + $data['orderId'] = $order['orderId']; + $data['refundTo'] = 0; + $data['refundReson'] = 5; + $data['backMoney'] = $money; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['refundStatus'] = 1; + $result = $this->insert($data); + if($result){ + Db::commit(); + return WSTReturn('您的退款申请已提交,请留意退款信息',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } +} diff --git a/hyhproject/common/model/Orders.php b/hyhproject/common/model/Orders.php new file mode 100755 index 0000000..b292cda --- /dev/null +++ b/hyhproject/common/model/Orders.php @@ -0,0 +1,3087 @@ +<?php +namespace wstmart\common\model; +use think\Db; +use think\Loader; +use wstmart\common\model\LogSms; +/** + * ============================================================================ + * 订单业务处理类 + */ +class Orders extends Base{ + /** + * 快速下单 + */ + public function quickSubmit($orderSrc = 0, $uId=0){ + $deliverType = 0; + $isInvoice = ((int)input('post.isInvoice')!=0)?1:0; + $invoiceClient = ($isInvoice==1)?input('post.invoiceClient'):''; + $payType = 1; + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + if($userId==0)return WSTReturn('下单失败,请先登录'); + $isUseScore = (int)input('isUseScore'); + $useScore = (int)input('useScore'); + //检测购物车 + $carts = model('common/carts')->getQuickCarts($uId); + if(empty($carts['carts']))return WSTReturn("请选择要购买的商品"); + //使用积分金额不能超过商品金额 + $tempScoreMoney = WSTScoreToMoney($carts['goodsTotalMoney']-$carts['promotionMoney'],true); + $useScore = ($useScore>$tempScoreMoney)?$tempScoreMoney:$useScore; + $orderScoreMap = []; + $scoreMoney = $this->getOrderScoreMoney($isUseScore,$useScore,$uId); + //生成订单 + Db::startTrans(); + try{ + //提交订单前执行钩子 + hook('beforeSubmitOrder',['carts'=>$carts,"payType"=>$payType]); + $shopOrder = current($carts['carts']); + $goods = $shopOrder['list'][0]; + if($goods['goodsStock']<$goods['cartNum'])return WSTReturn("下单失败,商品库存不足"); + //给用户分配卡券 + $cards = model('GoodsVirtuals')->where(['goodsId'=>$goods['goodsId'],'dataFlag'=>1,'shopId'=>$goods['shopId'],'isUse'=>0])->lock(true)->limit($goods['cartNum'])->select(); + if(count($cards)<$goods['cartNum'])return WSTReturn("下单失败,商品库存不足"); + //修改库存 + Db::name('goods')->where('goodsId',$goods['goodsId'])->update([ + 'goodsStock'=>['exp','goodsStock-'.$goods['cartNum']], + 'saleNum'=>['exp','saleNum+'.$goods['cartNum']], + ]); + $orderunique = WSTOrderQnique(); + $orderNo = WSTOrderNo(); + $orderScore = 0; + //创建订单 + $order = []; + $order['orderNo'] = $orderNo; + $order['orderType'] = 1; + $order['areaId'] = 0; + $order['userName'] = ''; + $order['userAddress'] = ''; + $order['userId'] = $userId; + $order['shopId'] = $shopOrder['shopId']; + $order['payType'] = $payType; + $order['goodsMoney'] = $shopOrder['goodsMoney']; + $order['deliverType'] = $deliverType; + $order['deliverMoney'] = 0; + $order['totalMoney'] = $order['goodsMoney']+$order['deliverMoney']; + $order['scoreMoney'] = 0; + $order['useScore'] = 0; + if($scoreMoney['useMoney']>0){ + $order['scoreMoney'] = $scoreMoney['useMoney']; + $order['useScore'] = $scoreMoney['useScore']; + } + $order['realTotalMoney'] = WSTPositiveNum($order['totalMoney'] - $order['scoreMoney'] - $shopOrder['promotionMoney']); + $order['needPay'] = $order['realTotalMoney']; + if($order['needPay']>0){ + $order['orderStatus'] = -2;//待付款 + $order['isPay'] = 0; + }else{ + $order['orderStatus'] = 0;//待发货 + $order['isPay'] = 1; + } + //惠宝 + $orderScore = 0; + //如果开启下单获取惠宝则有惠宝 + if(WSTConf('CONF.isOrderScore')==1){ + $orderScore = $this->round($order['goodsMoney'],0); + } + $order['orderScore'] = $orderScore; + $order['isInvoice'] = $isInvoice; + if($isInvoice==1){ + $order['invoiceJson'] = model('invoices')->getInviceInfo((int)input('param.invoiceId'));// 发票信息 + $order['invoiceClient'] = $invoiceClient; + }else{ + $order['invoiceJson'] = ''; + $order['invoiceClient'] = ''; + } + $order['orderRemarks'] = input('post.remark_'.$shopOrder['shopId']); + $order['orderunique'] = $orderunique; + $order['orderSrc'] = $orderSrc; + $order['dataFlag'] = 1; + $order['payRand'] = 1; + $order['createTime'] = date('Y-m-d H:i:s'); + //创建订单前执行钩子 + hook('beforeInsertOrder',['order'=>&$order,'carts'=>$carts]); + $result = $this->data($order,true)->isUpdate(false)->allowField(true)->save($order); + if(false !== $result){ + $orderId = $this->orderId; + //标记虚拟卡券为占用状态 + $goodsCards = []; + foreach ($cards as $key => $card) { + $card->isUse = 1; + $card->orderId = $orderId; + $card->orderNo = $orderNo; + $card->save(); + $goodsCards[] = ['cardId'=>$card->id]; + } + //创建订单商品记录 + $orderGgoods = []; + $orderGoods['orderId'] = $orderId; + $orderGoods['goodsId'] = $goods['goodsId']; + $orderGoods['goodsNum'] = $goods['cartNum']; + $orderGoods['goodsPrice'] = $goods['shopPrice']; + $orderGoods['goodsSpecId'] = 0; + $orderGoods['goodsSpecNames'] = ''; + $orderGoods['goodsName'] = $goods['goodsName']; + $orderGoods['goodsImg'] = $goods['goodsImg']; + $orderGoods['commissionRate'] = WSTGoodsCommissionRate($goods['goodsCatId']); + $orderGoods['goodsCode'] = ''; + $orderGoods['goodsType'] = 1; + $orderGoods['extraJson'] = json_encode($goodsCards); + $orderGoods['promotionJson'] = ''; + $orderTotalGoods = []; + $orderTotalGoods[] = $orderGoods; + //创建订单商品前执行钩子 + hook('beforeInsertOrderGoods',['orderId'=>$orderId,'orderGoods'=>&$orderTotalGoods,'carts'=>$carts]); + Db::name('order_goods')->insertAll($orderTotalGoods); + //计算订单佣金 + $commissionFee = 0; + if((float)$orderGoods['commissionRate']>0){ + $commissionFee += $this->round($goods['shopPrice']*1*$orderGoods['commissionRate']/100,2); + } + $this->where('orderId',$orderId)->update(['commissionFee'=>$commissionFee]); + //提交订单后执行钩子 + hook('afterSubmitOrder',['orderId'=>$orderId]); + //创建惠宝流水--如果有抵扣惠宝就肯定是开启了惠宝支付 + if($order['useScore']>0){ + $score = []; + $score['userId'] = $userId; + $score['score'] = $order['useScore']; + $score['dataSrc'] = 1; + $score['dataId'] = $orderId; + $score['dataRemarks'] = "交易订单【".$orderNo."】使用惠宝".$order['useScore']."个"; + $score['scoreType'] = 0; + model('UserScores')->add($score); + } + //建立订单记录 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = -2; + $logOrder['logContent'] = "下单成功,等待用户支付"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //等待支付-给店铺增加提示消息 + $tpl = WSTMsgTemplates('ORDER_SUBMIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$orderNo]; + + $msg = array(); + $msg["shopId"] = $shopOrder['shopId']; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_SUBMIT_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsSubmitOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$orderNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.submitOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'submit',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $orderNo; + $params['ORDER_TIME'] = date('Y-m-d H:i:s'); + $goodsNames = $goods['goodsName']."*".$goods['cartNum']; + $params['GOODS'] = $goodsNames; + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = ''; + $params['PAY_TYPE'] = WSTLangPayType($order['payType']); + + $msg = array(); + $tplCode = "WX_ORDER_SUBMIT"; + $msg["shopId"] = $shopOrder['shopId']; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxSubmitOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $orderNo; + $params['ORDER_TIME'] = date('Y-m-d H:i:s'); + $goodsNames = $goods['goodsName']."*".$goods['cartNum']; + $params['GOODS'] = $goodsNames; + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = ''; + $params['PAY_TYPE'] = WSTLangPayType($order['payType']); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_SUBMIT','userType'=>3,'userId'=>explode(',',WSTConf('CONF.submitOrderTipUsers')),'params'=>$params]); + } + } + //虚拟商品支付完成-立即发货 + if($order['needPay']==0){ + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + $this->handleVirtualGoods($orderId); + } + } + //删除session的购物车商品 + session('TMP_CARTS',null); + Db::commit(); + return WSTReturn("提交订单成功", 1,$orderunique); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('提交订单失败',-1); + } + } + /** + * 正常订单 + */ + public function submit($orderSrc = 0, $uId=0){ + + + $addressId = (int)input('post.s_addressId');//收货地址ID + $deliverType = empty(input('post.deliverType')) ? 0 : 1;//0是快递,1是自提,自提的不要运费,先取消 mark 20170907 + $isInvoice = ((int)input('post.isInvoice')!=0)?1:0;//是否开发票 + $invoiceClient = ($isInvoice==1)?input('post.invoiceClient'):'';//发票抬头 + $payType = 1;//((int)input('post.payType')!=0)?1:0;//1是在线支付0是货到付款 + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $isUseScore = 0;//(int)input('isUseScore');//是否使用惠宝支付 + $useScore = 0;//input('useScore');//惠宝抵扣金额 + + //dump($useScore);die; + if($userId==0)return WSTReturn('下单失败,请先登录',-999);//增加-999,需要登录 mark hsf 20171222 + //检测购物车 + //$carts = model('common/carts')->getCarts(true, $userId); + //if(empty($carts['carts']))return WSTReturn("请选择要购买的商品"); + //检测地址是否有效 + $address = Db::name('user_address')->where(['userId'=>$userId,'addressId'=>$addressId,'dataFlag'=>1])->find(); + if(empty($address)){ + return WSTReturn("无效的用户地址"); + } + $areaIds = []; + $areaMaps = []; + $tmp = explode('_',$address['areaIdPath']);//区域id路径 省Id_市Id_县Id 例如:440000_440100_440106_ + $address['areaId2'] = $tmp[1];//记录配送城市 + + + /** + * 添加直接提交订单和购物机结算2种方式 mark hsf 20171222 + * + */ + $type = (int)input('post.type');//是否是立即下单 + if($type==0){//购物车结算 + //检测购物车 + $carts = model('common/carts')->getCarts(true, $userId); + }else{//立即下单的 + $carts = model('carts')->buyNow($address['areaId2'], $userId);//立即下单结算方式 + } + if(empty($carts['carts']))return WSTReturn("请选择要购买的商品"); + $carts['ect_pay'] = isset($carts['ect_pay']) ? (int)$carts['ect_pay'] : 0; + $carts['goodsType'] = isset($carts['goodsType']) ? $carts['goodsType'] : 0; + if(1 == $carts['ect_pay'] || (isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1) || (isset($carts['promotion_goods']) && $carts['promotion_goods'] == 1)){//不可抵用惠宝 + $isUseScore=0; + $useScore=0; + } + + $pay_code = input('payCode'); + //$carts['ect_pay']=0; +// if($carts['ect_pay'] == 1 && $pay_code !='ect'){ +// return WSTReturn("ECT专区产品,请在APP里选择ECT支付!"); +// } + // if(!$carts['ect_pay'] && input('payCode') =='ect'){ + // //return WSTReturn("ECT支付调试中,请耐心等待!"); + // //return WSTReturn("该商品不支持ECT支付!"); + // } + + /*****************end******************/ +// if(!$carts['ect_pay'] && input('payCode') =='ect'){ +// return WSTReturn("该商品不支持ECT支付!"); +// } + // if(time() < 1539532800 && input('payCode') =='ect'){ + // return WSTReturn("ECT支付调试中,15号可用"); + // } + + if(isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1){ + $s_m = new \addons\hyhsale\model\Hyhsale(); + $s_m->batchUpdateSaleGoods($carts); + } + + // 验证商品规格是否已选 + foreach ($carts['carts'] as $v) { + foreach ($v['list'] as $val) { + $id = Db::name('goods_specs')->where(['shopId'=>$val['shopId'],'goodsId'=>$val['goodsId']])->column('id'); + if($id && $val['goodsSpecId'] == ''){ + return WSTReturn("请选择商品规格型号!"); + } + } + } + + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName'];//areaMaps键名是城市id,键名是中文名,如 [21] => "青海省" [278] =>"海东市"[2310] => "化隆" + } + $tmp = explode('_',$address['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue;//440000_440100_440106_按_截取的话最后一个是空 + $areaNames[] = $areaMaps[$vv];//返回省市区的数组 + $address['areaName'] = implode('',$areaNames);//拼接成省市区字符串 + } + } + + $address['userAddress'] = $address['areaName'].$address['userAddress'];//拼接省市区+具体地址 + WSTUnset($address, 'isDefault,dataFlag,createTime,userId');//去除多余字段 + //放钩子计算11.11订单的分类商品使用优惠券后的金额 + //hook("orderCatsCouponEleven",['carts'=>&$carts,'isSettlement'=>true,'uId'=>$userId]); + + $maxScoreMoney = 0;//初始化最大可用惠宝数 mark hsf 20171117 + $total_promotion_money = 0;//初始化合计优惠 mark hsf 20170303 + foreach ($carts['carts'] as &$v){ + $total_promotion_money += $v['promotionMoney'];//合计优惠 mark hsf 20170303 + } + unset($v); + $carts['couponMoney'] = isset($carts['couponMoney']) ? $carts['couponMoney'] : 0; + $maxScoreMoney = ($carts['goodsTotalMoney']-$carts['allShippingMoney']-$total_promotion_money-$carts['couponMoney']) * HuiScale();//减去优惠过的 + $maxScoreMoney = $maxScoreMoney < 0 ? 0 : $maxScoreMoney; + $useScore = $useScore < $maxScoreMoney ? $useScore : $maxScoreMoney; + + //计算出每个订单应该分配的金额和惠宝 + $orderScoreMoney = $this->allocScoreMoney($carts,$isUseScore,$useScore, $uId); + + //加权分配价格 + $orderPromotioneMap = $this->allocPromotioneMoney($carts, $uId); + //生成订单 + Db::startTrans(); + try{ + + //提交订单前执行钩子 + hook('beforeSubmitOrder',['carts'=>$carts,"payType"=>$payType]); + $orderunique = WSTOrderQnique(); + foreach ($carts['carts'] as $ckey =>$shopOrder){ + $orderNo = WSTOrderNo(); + $orderScore = 0; + //创建订单 + $order = []; + $order = array_merge($order,$address); + $order['orderNo'] = $orderNo; + $order['userId'] = $userId; + $order['shopId'] = $shopOrder['shopId']; + $order['payType'] = $payType; + $order['goodsType'] = $carts['goodsType']; + $order['goodsMoney'] = $shopOrder['goodsMoney']; + //计算运费和总金额 + $order['deliverType'] = $deliverType; + $order['deliverMoney']=0; + if($shopOrder['isFreeShipping']){ + $order['deliverMoney'] = 0; + }else{ + //$order['deliverMoney'] = ($deliverType==1)?0:WSTOrderFreight($shopOrder['shopId'],$order['areaId2']); + if($deliverType!=1){ + foreach ($shopOrder['list'] as &$value) { + $order['deliverMoney'] += $value['freight']; + } + } + + } + $order['totalMoney'] = $order['goodsMoney']+$order['deliverMoney']; + //惠宝支付-计算分配惠宝和金额 + $shopOrderMoney = $orderScoreMoney[$shopOrder['shopId']]; + $order['scoreMoney'] = $shopOrderMoney['useMoney']; + $order['useScore'] = $shopOrderMoney['useScore']; + + if(isset($orderPromotioneMap[$shopOrder['shopId']]['promotioneMoney'])){ + $shopPromotionMoney = $orderPromotioneMap[$shopOrder['shopId']]['promotioneMoney']; + }else{ + $shopPromotionMoney = 0; + } + //实付金额要减去惠宝兑换的金额和店铺总优惠 + $order['realTotalMoney'] = WSTPositiveNum($order['totalMoney'] - $order['scoreMoney'] - $shopOrder['promotionMoney'] - $shopPromotionMoney ); + $pay_ratio = 1; + if($pay_code == 'ect'){ + $pay_ratio_value = Db::name('payments')->where(['payCode'=>'ect'])->value('payRatio'); + if($pay_ratio_value < 0.9 || $pay_ratio_value > 1){ + $pay_ratio = 1; + }else{ + $pay_ratio = $pay_ratio_value; + } + } + $order['realTotalMoney'] *= $pay_ratio;//支付折扣价 + $order['needPay'] = $order['realTotalMoney']; + if($payType==1){ + if($order['needPay']>0){ + $order['orderStatus'] = -2;//待付款 + $order['isPay'] = 0; + }else{ + $order['orderStatus'] = 0;//待发货 + $order['isPay'] = 1; + } + }else{ + $order['orderStatus'] = 0;//待发货 + if($order['needPay']==0)$order['isPay'] = 1; + } + //惠宝 + $orderScore = 0; + //如果开启下单获取惠宝则有惠宝 + if(WSTConf('CONF.isOrderScore')==1){ + $orderScore = WSTMoneyGiftScore($order['realTotalMoney']);//惠宝按成交价的20%算 mark hsf 20180308 + } + $order['orderScore'] = $orderScore; + $order['isInvoice'] = $isInvoice; + if($isInvoice==1){ + $order['invoiceJson'] = model('invoices')->getInviceInfo((int)input('param.invoiceId'));// 发票信息 + $order['invoiceClient'] = $invoiceClient; + }else{ + $order['invoiceJson'] = '';// 发票信息 + $order['invoiceClient'] = ''; + } + $order['orderRemarks'] = input('post.remark_'.$shopOrder['shopId']); + $order['orderunique'] = $orderunique; + $order['orderSrc'] = $orderSrc; + $order['dataFlag'] = 1; + $order['payRand'] = 1; + $order['pay_name']=$carts['ect_pay']; + $order['createTime'] = date('Y-m-d H:i:s'); + $commissionRate = Db::name('shop_commission')->where('shopId',$order['shopId'])->field('commission')->find(); + //计算订单总佣金 + if((float)$commissionRate>0){ + $order['commissionFee'] = $this->round(($order['realTotalMoney']-$order['deliverMoney'])*$commissionRate['commission']/100,2); + }else{ + $order['commissionFee'] = 0; + //$order['commissionFee'] = $this->round(($order['realTotalMoney']-$order['deliverMoney'])*0.06,2); + } + $order['commissionFee'] = $order['commissionFee'] < 0?0:$order['commissionFee']; + if(isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1){ + + }else{ + //创建订单前执行钩子 + hook('beforeInsertOrder',['order'=>&$order,'carts'=>$carts]);//优惠券和满就送钩子,秒杀先关 + } + + $result = $this->data($order,true)->isUpdate(false)->allowField(true)->save($order); + if(false !== $result){ + $orderId = $this->orderId; + $orderTotalGoods = []; + //$commissionFee = 0; + foreach ($shopOrder['list'] as $gkey =>$goods){ + //创建订单商品记录 + $orderGgoods = []; + $orderGoods['orderId'] = $orderId; + $orderGoods['goodsId'] = $goods['goodsId']; + $orderGoods['goodsNum'] = $goods['cartNum']; + $orderGoods['goodsPrice'] = $goods['shopPrice']; + $orderGoods['goodsSpecId'] = $goods['goodsSpecId']; + $orderGoods['discountRate'] = Db::name('goods')->where(['goodsId'=>$goods['goodsId']])->value('discountRate'); + + if(!empty($goods['specNames'])){ + $specNams = []; + foreach ($goods['specNames'] as $pkey =>$spec){ + $specNams[] = $spec['catName'].':'.$spec['itemName']; + } + $orderGoods['goodsSpecNames'] = implode('@@_@@',$specNams); + }else{ + $orderGoods['goodsSpecNames'] = ''; + } + $orderGoods['goodsName'] = $goods['goodsName']; + $orderGoods['goodsImg'] = $goods['goodsImg']; + $orderGoods['freight'] = $goods['freight']; + /* + 根据是否批发算佣金 mark 20171117 + */ + if(empty($goods['isWhsle'])){ + $isWhsle = 0; + }else{ + $isWhsle = 1; + } + $orderGoods['commissionRate'] = WSTGoodsCommissionRate($goods['goodsCatId'],$isWhsle); + /* + -------------end------------- + */ + $orderGoods['goodsCode'] = ''; + $orderGoods['goodsType'] = 0; + $orderGoods['extraJson'] = ''; + $orderGoods['promotionJson'] = ''; + $orderTotalGoods[] = $orderGoods; + //计算订单总佣金 + // if((float)$orderGoods['commissionRate']>0){ + // $commissionFee += $this->round($orderGoods['goodsPrice']*$orderGoods['goodsNum']*$orderGoods['commissionRate']/100,2); + // } + //修改库存 + if($goods['goodsSpecId']>0){ + Db::name('goods_specs')->where('id',$goods['goodsSpecId'])->update([ + 'specStock'=>['exp','specStock-'.$goods['cartNum']], + 'saleNum'=>['exp','saleNum+'.$goods['cartNum']] + ]); + } + Db::name('goods')->where('goodsId',$goods['goodsId'])->update([ + 'goodsStock'=>['exp','goodsStock-'.$goods['cartNum']], + 'saleNum'=>['exp','saleNum+'.$goods['cartNum']], + ]); + } + if(isset($carts['is_seckilling']) && $carts['is_seckilling'] == 1){ + + }else{ + //创建订单商品前执行钩子 + hook('beforeInsertOrderGoods',['orderId'=>$orderId,'orderGoods'=>&$orderTotalGoods,'carts'=>$carts]); + } + Db::name('order_goods')->insertAll($orderTotalGoods); + //更新订单佣金 + //$this->where('orderId',$orderId)->update(['commissionFee'=>$commissionFee]); + //提交订单后执行钩子 + hook('afterSubmitOrder',['orderId'=>$orderId]); + + //创建惠宝流水--如果有抵扣惠宝就肯定是开启了惠宝支付 + if($order['useScore']>0){ + $score = []; + $score['userId'] = $userId; + $score['score'] = $order['useScore']; + $score['dataSrc'] = 1; + $score['dataId'] = $orderId; + $score['dataRemarks'] = "交易订单【".$orderNo."】使用惠宝".$order['useScore']."个"; + $score['scoreType'] = 0; + model('UserScores')->add($score); + } + + //建立订单记录 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = ($payType==1 && $order['needPay']==0)?-2:$order['orderStatus']; + $logOrder['logContent'] = ($payType==1)?"下单成功,等待用户支付":"下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + if($payType==1 && $order['needPay']==0){ + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + } + //给店铺增加提示消息 + $tpl = WSTMsgTemplates('ORDER_SUBMIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$orderNo]; + + $msg = array(); + $msg["shopId"] = $shopOrder['shopId']; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + + } + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_SUBMIT_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsSubmitOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$orderNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.submitOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'submit',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $orderNo; + $params['ORDER_TIME'] = date('Y-m-d H:i:s'); + $goodsNames = []; + foreach ($shopOrder['list'] as $gkey =>$goods){ + $goodsNames[] = $goods['goodsName']."*".$goods['cartNum']; + } + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = $order['userAddress']." ".$order['userName']; + $params['PAY_TYPE'] = WSTLangPayType($order['payType']); + + $msg = array(); + $tplCode = "WX_ORDER_SUBMIT"; + $msg["shopId"] = $shopOrder['shopId']; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxSubmitOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $orderNo; + $params['ORDER_TIME'] = date('Y-m-d H:i:s'); + $goodsNames = []; + foreach ($shopOrder['list'] as $gkey =>$goods){ + $goodsNames[] = $goods['goodsName']."*".$goods['cartNum']; + } + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = $order['userAddress']." ".$order['userName']; + $params['PAY_TYPE'] = WSTLangPayType($order['payType']); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_SUBMIT','userType'=>3,'userId'=>explode(',',WSTConf('CONF.submitOrderTipUsers')),'params'=>$params]); + } + } + } + } + /** + * 修改用户优惠券状态 + */ + if(isset($carts['recordId']) && $carts['recordId']){ + $now = time(); + Db::name('coupon_record')->where(['id'=>$carts['recordId'],'userId'=>$userId])->update(['isUse'=>1,'useTime'=>$now]); + } + /** + * 添加直接提交订单和购物机结算2种方式 mark hsf 20171222 + * + */ + if($type==0){//购物车结算 + //删除已选的购物车商品 + Db::name('carts')->where(['userId'=>$userId,'isCheck'=>1])->delete(); + }else{ + //删除session的购物车商品 + session('HYH_CARTS',null); + } + /*****************end******************/ + Db::commit(); + return WSTReturn("提交订单成功", 1,$orderunique); + }catch (\Exception $e) { + Db::rollback();errLog($e); + // dump($e); + return WSTReturn($e->getMessage(),-1); + } + } + + /** + * [allocPromotioneMoney 计算订单活动金额] + * @param [type] $carts [购物车商品] + * @param [type] $isUseScore [是否用惠宝] + * @param [type] $useScore [使用惠宝数量] + * @param integer $uId [会员ID] + * @return [type] [返回惠宝抵用金额和抵用惠宝] + */ + public function allocPromotioneMoney($carts, $uId=0){ + $orderPromotioneMap=[]; + //计算优惠出来的信息 + if($carts['promotionMoney']>0){ + foreach ($carts['carts'] as $ckey =>$shopOrder){ + + //$orderPromotioneMap[$shopOrder['shopId']]['promotioneMoney'] = 0; + $orderPromotioneMap[$shopOrder['shopId']]['promotioneMoney'] = $this->round($carts['promotionMoney']*$shopOrder['goodsMoney']/($carts['goodsTotalMoney']),2); + // foreach($shopOrder as $value){ + + // // if(in_array($value['goodsId'],$coupon_info['ids'])){ + // // $coupon_val['sum_money'] += $value['cartNum']*$value['shopPrice'];//商品 + // // //50*150/(150+260) + + // // } + // } + } + } + return $orderPromotioneMap; + } + /** + * [allocScoreMoney 计算订单可用惠宝和金额【惠宝支付使用】] + * @param [type] $carts [购物车商品] + * @param [type] $isUseScore [是否用惠宝] + * @param [type] $useScore [使用惠宝数量] + * @param integer $uId [会员ID] + * @return [type] [返回惠宝抵用金额和抵用惠宝] + */ + public function allocScoreMoney($carts,$isUseScore,$useScore, $uId=0){ + //使用惠宝金额不能超过商品金额 + //$tempScoreMoney = WSTScoreToMoney($carts['goodsTotalMoney']-$carts['promotionMoney'],true);//返回最大惠宝兑金额数量,传参实际金额即总价减去店铺要优惠的金额 + /* + * 计算最大可用惠宝,添加验证批发价的惠宝可抵用 mark hsf 20171117 + */ + $tempScoreMoney = 0; + foreach ($carts['carts'] as &$v){ + foreach ($v['list'] as &$val) { + if(isset($val['isWhsle'])){//是批发价的 + $tempScoreMoney += $this->round($val['shopPrice'] * $val['cartNum'] * HuiWhsleScale(),2);//可用惠宝默认抵10% + }else{ + $tempScoreMoney += $this->round($val['shopPrice'] * $val['cartNum'] * HuiScale(),2); + } + } + } + /* + *----------end------------- + */ + $useScore = ($useScore>$tempScoreMoney)?$tempScoreMoney:$useScore;// + $orderScoreMap = []; + $scoreMoney = $this->getOrderScoreMoney($isUseScore, $useScore, $uId);//计算可用惠宝和抵扣金额 ['useScore'=>使用的惠宝,'useMoney'=>转换后的金额,因为不一定是1:1换算的]; + $allocOrderMoney = $scoreMoney['useMoney'];//惠宝换算的金额 + $allocOrderScore = $scoreMoney['useScore'];//使用的惠宝数量 + $isLastOrder = false; //用来判断是否到最后一个订单 + $totalShop = count($carts['carts']);//获取购物车产品有几个商家 + $shopNum = 0; + foreach ($carts['carts'] as $ckey =>$shopOrder){ + $orderScoreMap[$shopOrder['shopId']]['useMoney'] = 0; + $orderScoreMap[$shopOrder['shopId']]['useScore'] = 0; + $shopNum++; + if($scoreMoney['useMoney']>0){//使用惠宝 + if($shopNum==$totalShop){//最后一个商家 + $allocMoney = $allocOrderMoney;//余下的金额 + $allocScore = $allocOrderScore;//余下的惠宝 + }else{ + $allocMoney = $this->allocOrderMoney($scoreMoney['useMoney'],$carts['goodsTotalMoney'],$shopOrder['goodsMoney']);//惠宝抵用金额*商品金额/订单总金额(不算运费) + $allocTmpMoney = $allocOrderMoney - $allocMoney;//惠宝抵用金额-店铺分配的金额,得到真实的金额 + //有可能计算出来金额比实际上还要大,所以要修正一下. + if($allocTmpMoney<0){//真实的金额<0,是有误差 + $allocMoney = $allocOrderMoney;//分配金额=惠宝抵用金额 + }else{ + $allocOrderMoney = $allocTmpMoney;//余下的金额 + } + + $allocScore = WSTScoreToMoney($allocMoney,true);//惠宝转换金额 + $allocTmpScore = $allocOrderScore - $allocScore;//使用的惠宝数量-惠宝转换金额 + //有可能计算出来金额比实际上还要大,修正分数 + + if($allocTmpScore<0){ + $allocScore = $allocOrderScore;//使用的惠宝数量 + }else{ + $allocOrderScore = $allocTmpScore;//余下的惠宝 + } + //echo $allocOrderScore.'qqq'; + } + $orderScoreMap[$shopOrder['shopId']]['useMoney'] = $allocMoney; + $orderScoreMap[$shopOrder['shopId']]['useScore'] = $allocScore; + } + } + return $orderScoreMap; + } + + /** + * 分配金额和惠宝 + */ + public function allocOrderMoney($useMoney,$totalOrderMoney,$orderMoney){ + if($useMoney>$totalOrderMoney)$useMoney = $totalOrderMoney; + return $this->round(($useMoney*$orderMoney)/$totalOrderMoney,2); + } + + /** + * 计算可用惠宝和抵扣金额 + */ + public function getOrderScoreMoney($isUseScore, $useScore, $uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + if((int)WSTConf('CONF.isOpenScorePay')==1 && $isUseScore){ + $uses = model('common/users')->getFieldsById($userId,'userScore'); + //如果又要惠宝支付又传个0或者负数就默认为0... + if($useScore<=0)$useScore = 0; + if($uses['userScore']<$useScore)$useScore = $uses['userScore']; + $money = WSTScoreToMoney($useScore); + return ['useScore'=>$useScore,'useMoney'=>$money]; + } + return ['useScore'=>0,'useMoney'=>0]; + } + + /** + * 根据订单唯一流水获取订单信息 + */ + public function getByUnique($uId=0){ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch/d',1); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + if($isBatch==1){ + $rs = $this->where(['userId'=>$userId,'orderunique'=>$orderNo])->field('orderId,orderNo,payType,needPay,orderunique,deliverMoney,userName,userPhone,userAddress')->select(); + }else{ + $rs = $this->where(['userId'=>$userId,'orderNo'=>$orderNo])->field('orderId,orderNo,payType,needPay,orderunique,deliverMoney,userName,userPhone,userAddress')->select(); + } + + $data = []; + $data['orderunique'] = $orderNo; + $data['list'] = []; + $payType = 0; + $totalMoney = 0; + $orderIds = [0]; + foreach ($rs as $key =>$v){ + if($v['payType']==1)$payType = 1; + $totalMoney = $totalMoney + $v['needPay']; + $orderIds[] = $v['orderId']; + $data['list'][] = $v; + } + $data['totalMoney'] = $totalMoney; + $data['payType'] = $payType; + //获取商品信息 + $goods = Db::name('order_goods')->where(['orderId'=>['in',$orderIds]])->select(); + foreach ($goods as $key =>$v){ + if($v['goodsSpecNames']!=''){ + $v['goodsSpecNames'] = explode('@@_@@',$v['goodsSpecNames']); + }else{ + $v['goodsSpecNames'] = []; + } + $data['goods'][$v['orderId']][] = $v; + } + //如果是在线支付的话就要加载支付信息 + if($data['payType']==1){ + //获取支付信息 + $payments = model('payments')->where(['isOnline'=>1,'enabled'=>1])->order('payOrder asc')->select(); + $data['payments'] = $payments; + } + return $data; + } + /** + * 本看凭证 + * @param [type] $isShop [1是商家] + * @return [type] [description] + */ + public function viewCertificate($isShop=0,$uId=0){ + $orderId = (int)input('post.orderId'); + if(1 == $isShop){ + $shopId = session('WST_USER.shopId'); + $order = $this->where(['orderId'=>$orderId,'shopId'=>$shopId,'dataFlag'=>1])->field('orderId')->find(); + }else{ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->where(['orderId'=>$orderId,'userId'=>$userId,'dataFlag'=>1])->field('orderId')->find(); + } + if(!$order) return WSTReturn('订单不存在',-1); + $rs = Db::name('order_certificate')->where(['orderId'=>$orderId])->order('id DESC')->find(); + if($rs){ + $rs['createTime'] = date('Y-m-d H:i:s',$rs['createTime']); + } //return WSTReturn('未找到相关数据',-1); + return WSTReturn('',1,$rs); + } + /** + * 上传凭证 + * @return [type] [description] + */ + public function uploadCertificate($isShop=0,$uId=0){ + $orderId = (int)input('post.orderId'); + if( $orderId){ + $content = input('post.content'); + if(!$content) return WSTReturn('请填写凭证说明',-1); + $imgUrl = input('post.imgUrl'); + if(!$imgUrl) return WSTReturn('请上传凭证照片',-1); + + if(1 == $isShop){ + $shopId = session('WST_USER.shopId'); + $order = $this->where(['orderId'=>$orderId,'shopId'=>$shopId,'dataFlag'=>1])->field('orderId')->find(); + }else{ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->where(['orderId'=>$orderId,'userId'=>$userId,'orderStatus'=>0,'dataFlag'=>1])->field('orderId')->find(); + } + if(!$order) return WSTReturn('订单不存在',-1); + $createTime = time(); + if(false !== Db::name('order_certificate')->insert(compact('isShop','orderId','content','imgUrl','createTime'))){ + if(1 == $isShop){ + return WSTReturn('上传凭证成功',1); + }else{ + return WSTReturn('上传凭证成功,请等待商家确认',1); + } + } + } + return WSTReturn('操作失败',-1); + } + //检查商家是否有凭证未上传 + public function checkCertificate($userId){ + $m = Model('common/Table'); + $m->setTable('order_shop_certificate'); + //已拒绝的凭证 + $certificateInfo = $m->getInfo(['userId'=>$userId,'status'=>4],'id,shopId'); + if($certificateInfo){ + return WSTReturn('您上传的凭证已拒绝,请重新提交!',-666,$certificateInfo); + } + $m->setTable('shops'); + $shopIds = $m->getColumn(['userId'=>$userId,'dataFlag'=>1],'shopId'); + if($shopIds){ + //未提交的凭证 + $m->setTable('orders'); + if(count($shopIds)>1){ + $where['shopId']=['IN',$shopIds]; + }else{ + $where['shopId']=$shopIds[0]; + } + $certificateInfo = $m->getInfo(array_merge($where,['orderStatus'=>2,'certificateStatus'=>0]),'orderId,shopId,receiveTime'); + + $start_date = date('Y-m-d',strtotime($certificateInfo['receiveTime'])); + $end_date = date('Y-m-d'); + $datetime_start = new \DateTime($start_date); + $datetime_end = new \DateTime($end_date); + $days = $datetime_start->diff($datetime_end)->days; + if($certificateInfo && (date('H') >= 21 || $days > 0)) { + return WSTReturn('您的订单需要上传凭证,请前往上传!',-555,$certificateInfo); + } + } + return WSTReturn('',1); + } + /** + * 查看未提交和已提交凭证 + * @return [type] [description] + */ + public function getShopCertificate($sId=0){ + $type = (int)input('post.type'); + if(!in_array($type,[0,1])){ + return WSTReturn('传值非法',-1); + } + $shopId = ($sId==0)?(int)session('WST_USER.shopId'):$sId; + if(0 == $type ){ + $where = ['shopId'=>$shopId,'dataFlag'=>1]; + $where['orderStatus'] = 2; + $where['certificateStatus'] = 0; + $data = $this->alias('o')->where($where) + ->field('o.orderRemarks,o.noticeDeliver,o.orderId,orderNo,goodsMoney,totalMoney,realTotalMoney,orderStatus,deliverType,deliverMoney,isAppraise,isRefund,o.deliverType deliverTypes + ,payType,payFrom,o.userPhone,userAddress,orderStatus,isPay,isAppraise,userName,orderSrc,o.createTime,o.orderCode,o.productNum,o.couponsNum,o.wangNum,o.moneyNum,o.certificateStatus,o.receiveTime,o.payable') + ->order('o.orderId', 'desc') + ->select(); + if($data){ + $orderIds = []; + foreach ($data as $v){ + $orderIds[] = $v['orderId']; + } + $goods = Db::name('order_goods')->where('orderId','in',$orderIds)->select(); + $goodsMap = []; + foreach ($goods as &$val){ + $val['goodsSpecNames'] = str_replace('@@_@@','、',$val['goodsSpecNames']); + $goodsMap[$val['orderId']][] = $val; + } + foreach ($data as &$v){ + $v['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + $v['list'] = $goodsMap[$v['orderId']]; + $v['payTypeName'] = WSTLangPayType($v['payType']); + $v['deliverTypeName'] = WSTLangDeliverType($v['deliverType']==1); + $v['deliverType'] = $v['deliverType']; + $v['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + return WSTReturn('',1,$data); + }elseif(1 == $type){ + $m = Model('common/Table'); + $m->setTable('order_shop_certificate'); + $page = $m->getSelect(['shopId'=>$shopId],'id,orderIds,createTime,status','id DESC'); + foreach ($page['Rows'] as &$v) { + $v['createTime'] = date('Y-m-d H:i:s',$v['createTime']); + $v['statusStr'] = ''; + switch ($v['status']) { + case 2: + $v['statusStr'] = '审核中'; + break; + case 3: + $v['statusStr'] = '已通过'; + break; + case 4: + $v['statusStr'] = '已拒绝'; + break; + } + $m->setTable('orders'); + $v['list'] = $m->getList(['orderId'=>['IN',$v['orderIds']]],'orderNo,payable'); + } + return WSTReturn('',1,$page); + } + } + /** + * 店铺上传凭证 + * @return [type] [description] + */ + public function uploadShopCertificate($sId=0,$uId=0){ + $orderIds = input('post.orderIds'); + if($orderIds){ + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + $userId = ($uId==0)?session('WST_USER.userId'):$uId; + $content = input('post.content'); + if(!$content) return WSTReturn('请填写凭证说明',-1); + $imgUrl = input('post.imgUrl'); + if(!$imgUrl) return WSTReturn('请上传凭证照片',-1); + $createTime = time(); + $id = (int)input('post.id'); + $status = 2; + Db::startTrans(); + try{ + if($id){ + $isSuccess = Db::name('order_shop_certificate')->where(['id'=>$id])->update(compact('content','imgUrl','createTime')); + }else{ + $isSuccess = Db::name('order_shop_certificate')->insert(compact('userId','shopId','orderIds','content','imgUrl','createTime')); + } + if(false !== $isSuccess){ + Db::name('orders')->where(['orderId'=>['IN',$orderIds]])->update(['certificateStatus'=>$status]); + Db::commit(); + return WSTReturn('上传凭证成功,请等待管理员审核!'); + } + //} + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + } + return WSTReturn('操作失败',-1); + } + /** + * 获取用户订单列表 + */ + public function userOrdersByPage($orderStatus, $isAppraise = -1, $uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $orderNo = input('post.orderNo'); + $shopName = input('post.shopName'); + $isRefund = (int)input('post.isRefund',-1); + $where = ['o.userId'=>$userId,'o.dataFlag'=>1]; + if(is_array($orderStatus)){ + $where['orderStatus'] = ['in',$orderStatus]; + }else{ + $where['orderStatus'] = $orderStatus; + } + if($isAppraise!=-1)$where['isAppraise'] = $isAppraise; + if($orderNo!=''){ + $where['o.orderNo'] = ['like',"%$orderNo%"]; + } + if($shopName != ''){ + $where['s.shopName'] = ['like',"%$shopName%"]; + } + if(in_array($isRefund,[0,1])){ + $where['isRefund'] = $isRefund; + } + + $page = $this->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__ORDER_COMPLAINS__ oc','oc.orderId=o.orderId','left') + ->join('__ORDERS_ECT__ ore','ore.orderId=o.orderId','left') + ->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId and orf.refundStatus!=-1','left') + ->where($where) + ->field('ore.orderEctNum,o.pay_name,ore.ectPrice,o.orderRemarks,o.noticeDeliver,o.orderId,o.orderNo,o.shopConfirm,s.shopName,s.shopId,s.shopQQ,s.phone,s.shopWangWang,o.goodsMoney,o.totalMoney,o.realTotalMoney, + o.orderStatus,o.deliverType,deliverMoney,isPay,payType,payFrom,o.orderStatus,needPay,isAppraise,isRefund,orderSrc,o.createTime,o.useScore,oc.complainId,orf.id refundId,o.orderCode') + ->order('o.createTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])>0){ + $orderIds = []; + foreach ($page['Rows'] as $v){ + $orderIds[] = $v['orderId']; + } + $goods = Db::name('order_goods')->where('orderId','in',$orderIds)->select(); + $goodsMap = []; + foreach ($goods as $v){ + $v['goodsSpecNames'] = str_replace('@@_@@','、',$v['goodsSpecNames']); + $v['marketPrice'] = Db::name('goods')->where(['goodsId'=>$v['goodsId']])->value('marketPrice');//添加返回市场价 mark hsf 20180112 + $goodsMap[$v['orderId']][] = $v; + } + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['allowRefund'] = 0; + //只要是已支付的,并且没有申请退款的,都可以申请退款操作 + if($v['isPay']==1 && $v['refundId']==''){ + $page['Rows'][$key]['allowRefund'] = 1; + } + //货到付款中使用了惠宝支付的也可以申请退款 + if($v['payType']==0 && $v['refundId']=='' && $v['useScore']>0){ + $page['Rows'][$key]['allowRefund'] = 1; + } + $page['Rows'][$key]['list'] = $goodsMap[$v['orderId']]; + $page['Rows'][$key]['isComplain'] = 1; + if(($v['complainId']=='') && ($v['payType']==0 || ($v['payType']==1 && $v['orderStatus']!=-2))){ + $page['Rows'][$key]['isComplain'] = ''; + } + $page['Rows'][$key]['payTypeName'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + $page['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + + } + hook('afterQueryUserOrders',['page'=>&$page]); + } + return $page; + } + /** + * 获取商家订单 + */ + public function shopOrderList($orderStatus, $sId=0, $shopConfirm=-1){ + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + $where = ['shopId'=>$shopId,'dataFlag'=>1]; + if(is_array($orderStatus)){ + $where['orderStatus'] = ['in',$orderStatus]; + }else{ + $where['orderStatus'] = $orderStatus; + } + if($shopConfirm >= 0){ + if(strpos($shopConfirm,',')){ + $where['shopConfirm'] = ['in',$shopConfirm]; + }else{ + $where['shopConfirm'] = $shopConfirm; + } + } + $page = $this->alias('o')->where($where) + ->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId and refundStatus=0','left') + ->field('o.orderRemarks,o.noticeDeliver,o.orderId,orderNo,goodsMoney,totalMoney,realTotalMoney,orderStatus,deliverType,deliverMoney,isAppraise,isRefund,o.deliverType deliverTypes + ,payType,payFrom,o.userPhone,o.shopConfirm,userAddress,orderStatus,isPay,isAppraise,userName,orderSrc,o.createTime,orf.id refundId,o.orderCode,o.productNum,o.couponsNum,o.wangNum,o.moneyNum') + ->order('o.createTime', 'desc') + ->paginate(input('post.pageSize/d',10))->toArray(); + if(count($page['Rows'])>0){ + $orderIds = []; + foreach ($page['Rows'] as $v){ + $orderIds[] = $v['orderId']; + } + $goods = Db::name('order_goods')->where('orderId','in',$orderIds)->select(); + $goodsMap = []; + foreach ($goods as $v){ + $v['goodsSpecNames'] = str_replace('@@_@@','、',$v['goodsSpecNames']); + $goodsMap[$v['orderId']][] = $v; + } + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + $page['Rows'][$key]['list'] = $goodsMap[$v['orderId']]; + $page['Rows'][$key]['payTypeName'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverTypeName'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['deliverType'] = $v['deliverType']; + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + return $page; + } + /** + * 获取商家订单 + */ + public function shopOrdersByPage($orderStatus, $sId=0){ + $orderNo = input('post.orderNo'); + $shopName = input('post.shopName'); + $payType = (int)input('post.payType'); + $deliverType = (int)input('post.deliverType'); + + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + + + $where = ['shopId'=>$shopId,'dataFlag'=>1]; + if(is_array($orderStatus)){ + $where['orderStatus'] = ['in',$orderStatus]; + }else{ + $where['orderStatus'] = $orderStatus; + } + if($orderNo!=''){ + $where['orderNo'] = ['like',"%$orderNo%"]; + } + if($shopName!=''){ + $where['shopName'] = ['like',"%$shopName%"]; + } + if($payType > -1){ + $where['payType'] = $payType; + } + if($deliverType > -1){ + $where['deliverType'] = $deliverType; + } + $page = $this->alias('o')->where($where) + ->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId and refundStatus=0','left') + ->join('__ORDERS_ECT__ ore','ore.orderId=o.orderId','left') + ->field('ore.orderEctNum,ore.ectPrice,o.orderRemarks,o.noticeDeliver,o.orderId,orderNo,goodsMoney,totalMoney,realTotalMoney,orderStatus,deliverType,deliverMoney,isAppraise,isRefund,o.deliverType deliverTypes + ,payType,payFrom,userAddress,orderStatus,isPay,isAppraise,userName,orderSrc,o.createTime,orf.id refundId,o.orderCode') + ->order('o.createTime', 'desc') + ->paginate()->toArray(); + if(count($page['Rows'])>0){ + $orderIds = []; + foreach ($page['Rows'] as $v){ + $orderIds[] = $v['orderId']; + } + $goods = Db::name('order_goods')->where('orderId','in',$orderIds)->select(); + $goodsMap = []; + foreach ($goods as $v){ + $v['goodsSpecNames'] = str_replace('@@_@@','、',$v['goodsSpecNames']); + $goodsMap[$v['orderId']][] = $v; + } + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['orderCodeTitle'] = WSTOrderCodeTitle($v['orderCode']); + $page['Rows'][$key]['list'] = $goodsMap[$v['orderId']]; + $page['Rows'][$key]['payTypeName'] = WSTLangPayType($v['payType']); + $page['Rows'][$key]['deliverTypeName'] = WSTLangDeliverType($v['deliverType']==1); + $page['Rows'][$key]['deliverType'] = $v['deliverType']; + $page['Rows'][$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + return $page; + } + /** + * 商家确认 + */ + public function orderConfirm($sId=0){ + $orderId = (int)input('post.id'); + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + $confirmType = (int)input('post.confirmType'); + if(!in_array($confirmType,[1,2])) return WSTReturn('请正确选择是否收款',-1); + $order = $this->where(['shopId'=>$shopId,'orderId'=>$orderId,'orderStatus'=>0])->field('orderId,orderNo,userId')->find(); + if(!empty($order)){ + Db::startTrans(); + try{ + $data = ['shopConfirm'=>$confirmType]; + $result = $this->where('orderId',$order['orderId'])->update($data); + //if(false != $result){ + Db::commit(); + return WSTReturn('操作成功',1); + //} + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + /** + * 商家发货 + */ + public function deliver($uId=0, $sId=0){ + $orderId = (int)input('post.id'); + $expressId = (int)input('post.expressId'); + $expressNo = input('post.expressNo'); + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->where(['shopId'=>$shopId,'orderId'=>$orderId,'orderStatus'=>0])->field('orderId,orderNo,userId,shopConfirm')->find(); + if(!empty($order)){ + if(1 != $order['shopConfirm']) return WSTReturn('请先确认订单',-1); + Db::startTrans(); + try{ + $data = ['orderStatus'=>1,'expressId'=>$expressId,'expressNo'=>$expressNo,'deliveryTime'=>date('Y-m-d H:i:s')]; + $result = $this->where('orderId',$order['orderId'])->update($data); + if(false != $result){ + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 1; + $logOrder['logContent'] = "商家已发货".(($expressNo!='')?",快递号为:".$expressNo:""); + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_DELIVERY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${EXPRESS_NO}']; + $replace = [$order['orderNo'],($expressNo=='')?'无':$expressNo]; + WSTSendMsg($order['userId'],str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + if($expressId>0){ + $express = model('express')->get($expressId); + $params['EXPRESS'] = $express->expressName; + $params['EXPRESS_NO'] = $expressNo; + }else{ + $params['EXPRESS'] = '无'; + $params['EXPRESS_NO'] = '无'; + } + $params['ORDER_NO'] = $order['orderNo']; + + WSTWxMessage(['CODE'=>'WX_ORDER_DELIVERY','userId'=>$order['userId'],'URL'=>Url('wechat/orders/index',['type'=>'waitReceive'],true,true),'params'=>$params]); + } + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + /** + * 商家修改快递单号 + */ + public function updateDeliver($uId=0, $sId=0){ + $orderId = (int)input('post.orderId'); + $expressId = (int)input('post.expressId'); + $expressNo = input('post.expressNo'); + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->where(['shopId'=>$shopId,'orderId'=>$orderId,'orderStatus'=>1])->field('orderId,orderNo,userId')->find(); + if(!empty($order)){ + Db::startTrans(); + try{ + $data = ['expressId'=>$expressId,'expressNo'=>$expressNo]; + $result = $this->where('orderId',$order['orderId'])->update($data); + if(false != $result){ + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 1; + $logOrder['logContent'] = "商家修改快递单号".(($expressNo!='')?",快递号为:".$expressNo:""); + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_DELIVERY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${EXPRESS_NO}']; + $replace = [$order['orderNo'],($expressNo=='')?'无':$expressNo]; + WSTSendMsg($order['userId'],str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$orderId]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + if($expressId>0){ + $express = model('express')->get($expressId); + $params['EXPRESS'] = $express->expressName; + $params['EXPRESS_NO'] = $expressNo; + }else{ + $params['EXPRESS'] = '无'; + $params['EXPRESS_NO'] = '无'; + } + $params['ORDER_NO'] = $order['orderNo']; + + WSTWxMessage(['CODE'=>'WX_ORDER_DELIVERY','userId'=>$order['userId'],'URL'=>Url('wechat/orders/index',['type'=>'waitReceive'],true,true),'params'=>$params]); + } + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + + + + + /** + * 用户收货[同时给外部虚拟商品收货调用] + */ + public function receive($orderId = 0,$userId = 0){ + if($orderId==0 && $userId==0){ + $orderId = (int)input('post.id'); + $userId = (int)session('WST_USER.userId'); + } + $order = $this->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->where(['o.userId'=>$userId,'o.orderId'=>$orderId,'o.orderStatus'=>1]) + ->field('o.orderId,o.orderNo,o.payType,s.userId,s.shopId,o.orderScore,o.payFrom,o.realTotalMoney,o.goodsType,commissionFee')->find(); + if(!empty($order)){ + Db::startTrans(); + try{ + $data = ['orderStatus'=>2,'receiveTime'=>date('Y-m-d H:i:s')]; + $result = $this->where('orderId',$order['orderId'])->update($data); + if(false != $result){ + //确认收货后执行钩子 + //hook('afterUserReceive',['orderId'=>$orderId]); + //dump(WSTConf('CONF.statementType')); + if(WSTConf('CONF.statementType')==1){ + //修改商家未计算订单数,先不用确认收货结算 mark hsf 20171118 + // $prefix = config('database.prefix'); + // $upSql = 'update '.$prefix.'shops set noSettledOrderNum=noSettledOrderNum+1,noSettledOrderFee=noSettledOrderFee-'.$order['commissionFee'].' where shopId='.$order['shopId']; + // Db::execute($upSql); + }else{ + //即时结算 + //调用钩子 ——张开心 + //hook('afterOrderSettlements',['order'=>&$order,'status'=>2]); + if(isset($order['is_settlements']) && $order['is_settlements'] == 1){ + + }else{ + //即时结算 + model('common/Settlements')->speedySettlement($orderId); + } + } + if (2 == $order['goodsType']){//助微吧购物 + $m = Model('common/Table'); + $userInfo = getUserInfo(['userId'=>$userId],'userType,buyHelpMoney,helpMaxSaleMoney'); + if (1 == $userInfo['userType']){//是商户购物 + //加助微吧购物金额 + $m->setTable('users'); + $m->incNum(['userId'=>$userId],'buyHelpMoney',$order['realTotalMoney']); + //加入记录 + $m->setTable('user_ect_log'); + $m->insertInfo(['userId'=>$userId,'ectNum'=>$order['realTotalMoney'],'ectType'=>1,'dataRemarks'=>'商户购物']); + //获取店铺最大等级 + $m->setTable('shops'); + $shopLevel = $m->getMax(['userId'=>$userId,'dataFlag'=>1],'shopLevel'); + //换算为3级循环等级 + $nowLevel = $shopLevel % 3; + //升级到下一级所需金额 + $upgradeMoney = dataConf('helpUpgradeLevel'.($nowLevel+1).'BuyMoney'); + //获取助微吧购物金额 + $buyHelpMoney = $userInfo['buyHelpMoney'] + $order['realTotalMoney']; + //查看是否够升级条件 + if($buyHelpMoney >= $upgradeMoney){ + //够条件,升级,并把buyHelpMoney值清0 + $m->setTable('shops'); + $m->incNum(['userId'=>$userId],'shopLevel',1); + //buyHelpMoney值清0 + $m->setTable('users'); + //购物值清零,总可销售额增加 + $m->updateInfo(['userId'=>$userId],['buyHelpMoney'=>0,'helpMaxSaleMoney'=>($userInfo['helpMaxSaleMoney'] + $order['realTotalMoney'])]); + $m->setTable('user_ect_log'); + $m->insertInfo(['userId'=>$userId,'ectNum'=>$buyHelpMoney,'ectType'=>2,'dataRemarks'=>'升级'.($nowLevel+1).'级清零前值']); + } + }else{ + $m->insertInfo(['userId'=>$userId,'ectNum'=>$order['realTotalMoney'],'ectType'=>1,'dataRemarks'=>'购户购物']); + } + } + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 2; + $logOrder['logContent'] = "用户已收货"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_RECEIVE'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$order['orderNo']]; + + $msg = array(); + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + //给用户增加惠宝 + if(WSTConf("CONF.isOrderScore")==1 && $order['orderScore']>0){ + $score = []; + $score['userId'] = $userId; + $score['score'] = $order['orderScore']; + $score['dataSrc'] = 1; + $score['dataId'] = $orderId; + $score['dataRemarks'] = "交易订单【".$order['orderNo']."】获得惠宝".$order['orderScore']."个"; + $score['scoreType'] = 1; + model('UserScores')->add($score); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['ORDER_TIME'] = date('Y-m-d H:i:s'); + //WSTWxMessage(['CODE'=>'WX_ORDER_RECEIVE','userId'=>$order['userId'],'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_RECEIVE"; + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params] ; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + } + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + // dump($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + //用户延时收货 + public function delay(){ + $id=(int)input('id'); + $find=Db::name('order_delay')->where('orderId',$id)->find(); + if($find) return WSTReturn('您已经延迟收货过了'); + $time = (int)WSTConf('CONF.autoAppraiseDays'); + $delay=(int)($time+3)*60*60*24; + $deliveryTime=(int)strtotime($this->where('orderId',$id)->value('deliveryTime')); + Db::startTrans(); + try{ + $delayTime=$deliveryTime+$delay; + $data['orderId']=$id; + $data['delayTime']=$delayTime; + $data['createTime']=time(); + db('order_delay')->insert($data); + Db::commit(); + return WSTReturn('操作成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + /** + * 用户取消订单 + */ + public function cancel($uId=0){ + $orderId = (int)input('post.id'); + hook('beforeCancelOrder',['orderId'=>$orderId]); + $reason = (int)input('post.reason'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->where(['o.userId'=>$userId,'o.orderId'=>$orderId,'o.orderStatus'=>['in',[-2,0]]]) + ->field('o.orderId,o.orderNo,s.userId,s.shopId,o.orderCode,o.orderType,o.payType,o.orderStatus,o.useScore,o.scoreMoney,o.realTotalMoney')->find(); + $reasonData = WSTDatas('ORDER_CANCEL',$reason); + if(empty($reasonData))return WSTReturn("无效的取消原因"); + if(!empty($order)){ + Db::startTrans(); + try{ + $data = ['orderStatus'=>-1,'cancelReason'=>$reason]; + //如果是货到付款取消的话,把实付金额设置为0 + if($order['payType']==0)$data['realTotalMoney'] = 0; + $result = $this->where('orderId',$order['orderId'])->update($data); + if(false != $result){ + //未付款状、货到付款取消订单态则直接退回惠宝 + if(($order['orderStatus'] == -2 && $order['payType']==1 && $order['useScore']>0) || ($order['orderStatus'] == 0 && $order['payType']==0 && $order['useScore']>0)){ + $score = []; + $score['userId'] = $userId; + $score['score'] = $order['useScore']; + $score['dataSrc'] = 1; + $score['dataId'] = $orderId; + $score['dataRemarks'] = "取消交易订单【".$order['orderNo']."】,退回惠宝".$order['useScore']."个"; + $score['scoreType'] = 1; + model('UserScores')->add($score); + } + //正常订单商品库存处理 + $goods = Db::name('order_goods')->alias('og')->join('__GOODS__ g','og.goodsId=g.goodsId','inner') + ->where('orderId',$orderId)->field('og.*,g.isSpec')->select(); + + //返还商品库存 + foreach ($goods as $key => $v){ + //处理虚拟产品 + if($v['goodsType']==1){ + $extraJson = json_decode($v['extraJson'],true); + foreach ($extraJson as $ecard) { + Db::name('goods_virtuals')->where('id',$ecard['cardId'])->update(['orderId'=>0,'orderNo'=>'','isUse'=>0]); + } + $counts = Db::name('goods_virtuals')->where(['dataFlag'=>1,'goodsId'=>$v['goodsId'],'isUse'=>0])->count(); + Db::name('goods')->where('goodsId',$v['goodsId'])->setField('goodsStock',$counts); + }else{ + if($order['orderCode']=='order'){ + //修改库存 + if($v['isSpec']>0){ + Db::name('goods_specs')->where('id',$v['goodsSpecId'])->setInc('specStock',$v['goodsNum']); + } + Db::name('goods')->where('goodsId',$v['goodsId'])->setInc('goodsStock',$v['goodsNum']); + } + } + } + + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = -1; + $logOrder['logContent'] = "用户取消订单,取消原因:".$reasonData['dataName']; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //提交订单后执行钩子 + hook('afterCancelOrder',['orderId'=>$orderId]); + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_CANCEL'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REASON}']; + $replace = [$order['orderNo'],$reasonData['dataName']]; + + $msg = array(); + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_CANCEL_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsCancelOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.cancelOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'cancel',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $goodsNames = []; + foreach ($goods as $gkey =>$g){ + $goodsNames[] = $g['goodsName']."*".$g['goodsNum']; + } + $params['REASON'] = $reasonData['dataName']; + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + //WSTWxMessage(['CODE'=>'WX_ORDER_CANCEL','userId'=>$order['userId'],'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_CANCEL"; + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>'WX_ORDER_CANCEL','URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxCancelOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $goodsNames = []; + foreach ($goods as $gkey =>$g){ + $goodsNames[] = $g['goodsName']."*".$g['goodsNum']; + } + $params['REASON'] = $reasonData['dataName']; + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_CANCEL','userType'=>3,'userId'=>explode(',',WSTConf('CONF.cancelOrderTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('订单取消成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + /** + * 用户拒收订单 + */ + public function reject($uId=0){ + $orderId = (int)input('post.id'); + $reason = (int)input('post.reason'); + $content = input('post.content'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $order = $this->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->where(['o.userId'=>$userId,'o.orderId'=>$orderId,'o.orderStatus'=>1]) + ->field('o.orderId,o.orderNo,o.shopId,s.userId,payType,o.userAddress,o.userName,o.realTotalMoney,o.scoreMoney')->find(); + $reasonData = WSTDatas('ORDER_REJECT',$reason); + if(empty($reasonData))return WSTReturn("无效的拒收原因"); + if($reason==10000 && $content=='')return WSTReturn("请输入拒收原因"); + if(!empty($order)){ + Db::startTrans(); + try{ + $data = ['orderStatus'=>-3,'rejectReason'=>$reason]; + if($reason==10000)$data['rejectOtherReason'] = $content; + //如果是货到付款拒收的话,把实付金额设置为0 + if($order['payType']==0)$data['realTotalMoney'] = 0; + $result = $this->where('orderId',$order['orderId'])->update($data); + if(false != $result){ + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = -3; + $logOrder['logContent'] = "用户拒收订单,拒收原因:".$reasonData['dataName'].(($reason==10000)?"-".$content:""); + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_REJECT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${REASON}']; + $replace = [$order['orderNo'],$reasonData['dataName'].(($reason==10000)?"-".$content:"")]; + + $msg = array(); + $msg["shopId"] = $order['shopId']; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_REJECT_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsRejectOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.rejectOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'cancel',''); + } + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $goods = Db::name('order_goods')->where('orderId',$order['orderId'])->select(); + $goodsNames = []; + foreach ($goods as $gkey =>$goods){ + $goodsNames[] = $goods['goodsName']."*".$goods['goodsNum']; + } + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = $order['userAddress']." ".$order['userName']; + $params['REASON'] = $reasonData['dataName'].(($reason==10000)?"-".$content:""); + + $msg = array(); + $tplCode = "WX_ORDER_REJECT"; + $msg["shopId"] = $order['shopId']; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxRejectOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $goods = Db::name('order_goods')->where('orderId',$order['orderId'])->select(); + $goodsNames = []; + foreach ($goods as $gkey =>$goods){ + $goodsNames[] = $goods['goodsName']."*".$goods['goodsNum']; + } + $params['GOODS'] = implode(',',$goodsNames); + $params['MONEY'] = $order['realTotalMoney'] + $order['scoreMoney']; + $params['ADDRESS'] = $order['userAddress']." ".$order['userName']; + $params['REASON'] = $reasonData['dataName'].(($reason==10000)?"-".$content:""); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_REJECT','userType'=>3,'userId'=>explode(',',WSTConf('CONF.rejectOrderTipUsers')),'params'=>$params]); + } + } + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败,请检查订单状态是否已改变'); + } + /** + * 获取订单价格 + */ + public function getMoneyByOrder($orderId = 0){ + $orderId = ($orderId>0)?$orderId:(int)input('post.id'); + $result= $this->where('orderId',$orderId)->field('orderId,orderNo,goodsMoney,deliverMoney,useScore,scoreMoney,totalMoney,realTotalMoney,payFrom,productNum,couponsNum,wangNum,moneyNum')->find(); + if($result['payFrom']=="ect"){ + $result['ectNum']=db('orders_ect')->where('orderId',$orderId)->value('orderEctNum'); + } + $result['ectNum']=isset($result['ectNum'])?$result['ectNum']:""; + return $result; + } + + + /** + * 修改订单价格 + */ + public function editOrderMoney($uId=0, $sId=0){ + $orderId = input('post.id'); + $orderMoney = (float)input('post.orderMoney'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $shopId = ($sId==0)?session('WST_USER.shopId'):$sId; + if($orderMoney<0.01)return WSTReturn("订单价格不能小于0.01"); + Db::startTrans(); + try{ + + $data = array(); + $data["realTotalMoney"] = $orderMoney; + $data["needPay"] = $orderMoney; + $data["payRand"] = array("exp","payRand+1"); + $result = $this->where(['orderId'=>$orderId,'shopId'=>$shopId,'orderStatus'=>-2])->update($data); + + if(false !== $result){ + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = -2; + $logOrder['logContent'] = "商家修改订单价格为:".$orderMoney; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + + /** + * 获取订单详情 + */ + public function getByView($orderId, $uId=0){ + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $shopId = ($uId==0)?(int)session('WST_USER.shopId'):$uId; + $orders = Db::name('orders')->alias('o')->join('__EXPRESS__ e','o.expressId=e.expressId','left') + ->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__ORDER_REFUNDS__ orf ','o.orderId=orf.orderId','left') + ->where('o.dataFlag=1 and o.orderId='.$orderId.' and ( o.userId='.$userId.' or o.shopId='.$shopId.')') + ->field('o.*,e.expressName,s.shopTel,s.shopName,s.shopQQ,s.shopWangWang,orf.id refundId,orf.refundRemark,orf.refundStatus,orf.refundTime,orf.backMoney,orf.backMoney')->find(); + if(empty($orders))return WSTReturn("无效的订单信息"); + + //获取订单信息 + $orders['log'] =Db::name('log_orders')->where('orderId',$orderId)->order('logId asc')->select(); + //获取订单商品 + $orders['goods'] = Db::name('order_goods')->alias('og')->join('__GOODS__ g','g.goodsId=og.goodsId','left')->where('orderId',$orderId)->field('og.*,g.goodsSn,g.marketPrice')->order('id asc')->select();//添加市场价返加 mark hsf 20180216 + //如果是虚拟商品 + if($orders['orderType']==1){ + foreach ($orders['goods'] as $key => $v) { + $orders['goods'][$key]['extraJson'] = json_decode($v['extraJson'],true); + } + } + return $orders; + } + + + + /** + * 根据订单id获取 商品信息跟商品评价 + */ + public function getOrderInfoAndAppr($uId=0){ + $orderId = (int)input('oId'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + //添加凭证时用户验证 mark hsf 20171206 + if(!Db::name('orders')->where(['orderId'=>$orderId,'userId'=>$userId])->find()){ + throw new \Exception($userId.'没有权限');die; + } + //----end------ + $goodsInfo = Db::name('order_goods') + ->field('id,orderId,goodsName,goodsId,goodsSpecNames,goodsImg,goodsSpecId,goodsCode') + ->where(['orderId'=>$orderId]) + ->select(); + //根据商品id 与 订单id 取评价 + $alreadys = 0;// 已评价商品数 + $count = count($goodsInfo);//订单下总商品数 + if($count>0){ + foreach($goodsInfo as $k=>$v){ + $goodsInfo[$k]['goodsSpecNames'] = str_replace('@@_@@', ';', $v['goodsSpecNames']); + $appraise = Db::name('goods_appraises') + ->field('goodsScore,serviceScore,timeScore,content,images,createTime') + ->where(['goodsId'=>$v['goodsId'], + 'goodsSpecId'=>$v['goodsSpecId'], + 'orderId'=>$orderId, + 'dataFlag'=>1, + 'isShow'=>1, + 'userId'=>$userId, + 'orderGoodsId'=>$v['id'], + ])->find(); + if(!empty($appraise)){ + ++$alreadys; + $appraise['images'] = ($appraise['images']!='')?explode(',', $appraise['images']):[]; + } + $goodsInfo[$k]['appraise'] = $appraise; + } + } + return ['count'=>$count,'Rows'=>$goodsInfo,'alreadys'=>$alreadys]; + + } + + /** + * 检查订单是否已支付 + */ + public function checkOrderPay (){ + $userId = (int)session('WST_USER.userId'); + $orderNo = input("orderNo"); + $isBatch = (int)input("isBatch"); + $rs = array(); + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + $rs = $this->field('orderId,orderNo')->where($where)->select(); + if(count($rs)>0){ + return WSTReturn('',1); + }else{ + return WSTReturn('订单已支付',-1); + } + } + + /** + * 检查订单是否已支付 + */ + public function checkOrderPay2 ($obj){ + $userId = $obj["userId"]; + $orderNo = $obj["orderNo"]; + $isBatch = $obj["isBatch"]; + $rs = array(); + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + $rs = $this->field('orderId,orderNo')->where($where)->select(); + if(count($rs)>0){ + return WSTReturn('',1); + }else{ + return WSTReturn('订单已支付',-1); + } + } + + + /** + * 虚拟商品支付处理 + */ + public function handleVirtualGoods($orderId){ + $order= Db::name('orders')->alias('o')->join('__SHOPS__ s','o.shopId=s.shopId ','inner') + ->where('orderId',$orderId)->field('orderId,orderNo,o.shopId,s.userId,o.userId ouserId,o.realTotalMoney,o.payFrom') + ->find(); + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $order['orderId']; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "商家已发货"; + $logOrder['logUserId'] = $order['userId']; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + $logOrder = []; + $logOrder['orderId'] = $order['orderId']; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "用户已收货"; + $logOrder['logUserId'] = $order['ouserId']; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //修改订单状态 + Db::name('orders')->where('orderId',$order['orderId'])->update(['orderStatus'=>2,'deliveryTime'=>date('Y-m-d H:i:s'),'receiveTime'=>date('Y-m-d H:i:s')]); + //分配卡券号 + $orderGoods = Db::name('order_goods')->where(['orderId'=>$order['orderId'],'goodsType'=>1])->field('id,goodsName,extraJson')->find(); + $cardIds = []; + $extraJson = json_decode($orderGoods['extraJson'],true); + foreach ($extraJson as $ogextra) { + $cardIds[] = $ogextra['cardId']; + } + $cards = model('common/GoodsVirtuals')->where(['id'=>['in',$cardIds]])->field('id,cardNo,cardPwd')->select(); + $cardmap = []; + foreach ($cards as $card) { + $cardmap[$card['id']] = $card; + } + $ogcards = []; + $extra = json_decode($orderGoods['extraJson'],true); + foreach ($extra as $ogextra) { + $ogextra['cardId'] = $cardmap[$ogextra['cardId']]['id']; + $ogextra['cardNo'] = $cardmap[$ogextra['cardId']]['cardNo']; + $ogextra['cardPwd'] = $cardmap[$ogextra['cardId']]['cardPwd']; + $ogextra['isUse'] = 0; + $ogcards[] = $ogextra; + } + Db::name('order_goods')->where('id',$orderGoods['id'])->update(['extraJson'=>json_encode($ogcards)]); + //即时结算 + model('common/Settlements')->speedySettlement($orderId); + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_SHOP_AUTO_DELIVERY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${GOODS}']; + $replace = [$order['orderNo'],$orderGoods['goodsName']]; + + $msg = array(); + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$order['orderId']]; + model("common/MessageQueues")->add($msg); + } + //发送一条用户信息 + $tpl = WSTMsgTemplates('ORDER_USER_AUTO_DELIVERY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}','${GOODS}']; + $replace = [$order['orderNo'],$orderGoods['goodsName']]; + WSTSendMsg($order["ouserId"],str_replace($find,$replace,$tpl['tplContent']),['from'=>1,'dataId'=>$order['orderId']]); + } + + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_PAY_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsPayOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.payOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'handleVirtualGoods',''); + } + } + //微信消息-已支付 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order['realTotalMoney']; + $params['PAY_SRC'] = WSTLangPayFrom($order['payFrom']); + //WSTWxMessage(['CODE'=>'WX_ORDER_PAY','userId'=>$order["userId"],'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_PAY"; + $msg["shopId"] = $order["shopId"]; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxPayOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $order['orderNo']; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order['realTotalMoney']; + $params['PAY_SRC'] = WSTLangPayFrom($order['payFrom']); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_PAY','userType'=>3,'userId'=>explode(',',WSTConf('CONF.payOrderTipUsers')),'params'=>$params]); + } + } + + } + + + /** + * 完成支付订单 + */ + public function complatePay ($obj){ + $trade_no = $obj["trade_no"]; + $isBatch = (int)$obj["isBatch"]; + $orderNo = $obj["out_trade_no"]; + $userId = (int)$obj["userId"]; + $payFrom = $obj["payFrom"]; + $payMoney = (float)$obj["total_fee"]; + if($payFrom!=''){ + $cnt = model('orders') + ->where(['payFrom'=>$payFrom,"userId"=>$userId,"tradeNo"=>$trade_no]) + ->count(); + if($cnt>0){ + return WSTReturn('订单已支付',-1); + } + } + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1,"needPay"=>[">",0]]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + + $orders = model('orders')->where($where)->field('needPay,orderId,payType,orderType,orderNo,shopId,commissionFee,payFrom,realTotalMoney')->select(); + if(count($orders)==0)return WSTReturn('无效的订单信息',-1); + + $needPay = 0; + foreach ($orders as $key => $v) { + $needPay += $v['needPay']; + } + //if($needPay>$payMoney){ + if(bccomp($needPay,$payMoney) == 1){ + return WSTReturn('支付金额不正确',-1); + } + $sms_num = 0; + Db::startTrans(); + try{ + $data = array(); + $data["needPay"] = 0; + $data["isPay"] = 1; + $data["orderStatus"] = 0; + $data["tradeNo"] = $trade_no; + $data["payFrom"] = $payFrom; + $data["payTime"] = date("Y-m-d H:i:s"); + $rs = model('orders')->where($where)->update($data); + + if($needPay>0 && false != $rs){ + foreach ($orders as $key =>$v){ + $orderId = $v["orderId"]; + $shop = model('shops')->get($v->shopId); + + //调用钩子 ——张开心 + hook('afterOrderSettlements',['order'=>$v,'status'=>1]); + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + //创建一条充值流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $userId; + $lm['dataId'] = $orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '交易订单【'.$v['orderNo'].'】充值¥'.$needPay; + $lm['moneyType'] = 1; + $lm['money'] = $needPay; + $lm['payType'] = $payFrom; + $lm['tradeNo'] = $trade_no; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->create($lm); + //创建一条支出流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $userId; + $lm['dataId'] = $orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '交易订单【'.$v['orderNo'].'】支出¥'.$needPay; + $lm['moneyType'] = 0; + $lm['money'] = $needPay; + $lm['payType'] = 0; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->create($lm); + + //虚拟商品处理 + if($v['orderType']==1){ + $this->handleVirtualGoods($v['orderId']); + }else{ + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_HASPAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$v['orderNo']]; + + $msg = array(); + $msg["shopId"] = $shop["shopId"]; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$orderId]; + model("common/MessageQueues")->add($msg); + } + + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_PAY_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsPayOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$v['orderNo']]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.payOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'complatePay',''); + } + } + //商家短信通知 mark hsf 20180421 + if((int)WSTConf('CONF.smsOpen')==1 && WSTIsPhone($shop['telephone'])){ + hook('afterOrderPay',['tplCode'=>'PHONE_SHOP_MSG','userId'=>$shop['userId'],"telephone"=>$shop['telephone'],'orderNo'=>$v['orderNo'],'orderStatus'=>0]); + } + $tpl = WSTMsgTemplates('PHONE_SHOP_MSG'); + if( $tpl['tplContent']!='' && $tpl['status']=='1' && $sms_num == 0){ + $sms_num = 1; + $shopInfo = GetShopInfo($shop['shopId'],'telephone,userId'); + if(WSTIsPhone($shopInfo['telephone'])){ + // $params = ['tpl'=>$tpl,'params'=>['orderNo'=>$v['orderNo'],'orderStatue'=>'已付款']]; + // $model_logsms = new LogSms(); + // $model_logsms->sendShopSMS(0,$shopInfo['telephone'],$params,'pay','',$shopInfo['userId']); + } + + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $v['orderNo']; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $v['realTotalMoney']; + $params['PAY_SRC'] = WSTLangPayFrom($v['payFrom']); + + $msg = array(); + $tplCode = "WX_ORDER_PAY"; + $msg["shopId"] = $shop["shopId"]; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxPayOrderTip')==1){ + $params = []; + $params['ORDER_NO'] = $v['orderNo']; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $v['realTotalMoney']; + $params['PAY_SRC'] = WSTLangPayFrom($v['payFrom']); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_PAY','userType'=>3,'userId'=>explode(',',WSTConf('CONF.payOrderTipUsers')),'params'=>$params]); + } + } + } + } + }else{ + $data = array(); + $data["userMoney"] = array("exp","userMoney+".$payMoney); + Db::name('users')->where("userId",$userId)->update($data); + //创建一条充值流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $userId; + $lm['dataId'] = $orderNo; + $lm['dataSrc'] = 1; + $lm['remark'] = '交易订单充值¥'.$payMoney; + $lm['moneyType'] = 1; + $lm['money'] = $payMoney; + $lm['payType'] = $payFrom; + $lm['tradeNo'] = $trade_no; + $lm['createTime'] = date('Y-m-d H:i:s'); + model('LogMoneys')->create($lm); + } + Db::commit(); + return WSTReturn('支付成功',1); + }catch (\Exception $e) { + dump($e); + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } + + /** + * 获取支付订单信息 + */ + public function getPayOrders ($obj){ + $userId = (int)$obj["userId"]; + $orderNo = $obj["orderNo"]; + $isBatch = (int)$obj["isBatch"]; + $needPay = 0; + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1,"needPay"=>[">",0]]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + $data = array(); + $needPay = model('orders')->where($where)->sum('needPay'); + $payRand = model('orders')->where($where)->max('payRand'); + $data["needPay"] = $needPay; + $data["payRand"] = $payRand; + return $data; + } + + /** + * 导出订单 + */ + public function toExport(){ + $name='订单表'; + $where = ['o.dataFlag'=>1]; + $orderStatus = (int)input('orderStatus',0); + if($orderStatus==0){ + $name='待发货订单表'; + }else if($orderStatus==-2){ + $name='待付款订单表'; + }else if($orderStatus==1){ + $name='配送中订单表'; + }else if($orderStatus==-1){ + $name='取消订单表'; + }else if($orderStatus==-3){ + $name='拒收订单表'; + }else if($orderStatus==2){ + $name='已收货订单表'; + }else if($orderStatus==10000){ + $name='取消/拒收订单表'; + }else if($orderStatus==20000){ + $name='待收货订单表'; + } + $shopId = session('WST_USER.shopId'); + $where = ['o.shopId'=>$shopId]; + $orderNo = input('orderNo'); + $shopName = input('shopName'); + + $type = (int)input('type',-1); + $payType = $type>0?$type:(int)input('payType',-1); + $deliverType = (int)input('deliverType'); + if($orderStatus == 10000)$orderStatus = [-1,-3]; + if($orderStatus == 20000)$orderStatus = [0,1]; + if(is_array($orderStatus)){ + $where['o.orderStatus'] = ['in',$orderStatus]; + }else{ + $where['o.orderStatus'] = $orderStatus; + } + if($orderNo!=''){ + $where['orderNo'] = ['like',"%$orderNo%"]; + } + if($shopName!=''){ + $where['shopName'] = ['like',"%$shopName%"]; + } + if($payType > -1){ + $where['payType'] = $payType; + } + if($deliverType > -1){ + $where['deliverType'] = $deliverType; + } + $page = $this->alias('o')->where($where)->join('__SHOPS__ s','o.shopId=s.shopId','left') + ->join('__ORDER_REFUNDS__ orf','orf.orderId=o.orderId and refundStatus=0','left') + ->join('__LOG_ORDERS__ lo','lo.orderId=o.orderId and lo.orderStatus in (-1,-3) ','left') + ->join('__ORDER_GOODS__ og','og.orderId=o.orderId','left') + ->field('o.orderId,orderNo,goodsMoney,totalMoney,realTotalMoney,o.orderStatus,deliverType,deliverMoney,isAppraise,o.deliverMoney,lo.logContent + ,payType,o.userName,o.userAddress,o.userPhone,o.orderRemarks,o.invoiceClient,o.receiveTime,o.deliveryTime,orderSrc,o.createTime,orf.id refundId,og.goodsNum,og.goodsName') + ->order('o.createTime', 'desc') + ->select(); + if(count($page)>0){ + foreach ($page as $key => $v){ + $page[$key]['payTypeName'] = WSTLangPayType($v['payType']); + $page[$key]['deliverType'] = WSTLangDeliverType($v['deliverType']==1); + $page[$key]['status'] = WSTLangOrderStatus($v['orderStatus']); + } + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + ->setLastModifiedBy("WSTMart")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('O')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('P')->setWidth(50); + $objPHPExcel->getActiveSheet()->getColumnDimension('Q')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('R')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('S')->setWidth(35); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:S1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet()->setCellValue('A1', '订单编号')->setCellValue('B1', '订单状态')->setCellValue('C1', '收货人')->setCellValue('D1', '收货地址')->setCellValue('E1', '联系方式') + ->setCellValue('F1', '支付方式')->setCellValue('G1', '配送方式')->setCellValue('H1', '买家留言')->setCellValue('I1', '发票信息')->setCellValue('J1', '订单总金额')->setCellValue('K1', '运费') + ->setCellValue('L1', '实付金额')->setCellValue('M1', '下单时间')->setCellValue('N1', '发货时间')->setCellValue('O1', '收货时间')->setCellValue('P1', '取消/拒收原因')->setCellValue('Q1', '商品名称')->setCellValue('R1', '商品数量'); + $objPHPExcel->getActiveSheet()->getStyle('A1:P1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet()->setCellValue('A'.$i, $page[$row]['orderNo'])->setCellValue('B'.$i, $page[$row]['status'])->setCellValue('C'.$i, $page[$row]['userName'])->setCellValue('D'.$i, $page[$row]['userAddress']) + ->setCellValue('E'.$i, $page[$row]['userPhone'])->setCellValue('F'.$i, $page[$row]['payTypeName'])->setCellValue('G'.$i, $page[$row]['deliverType'])->setCellValue('H'.$i, $page[$row]['orderRemarks'])->setCellValue('I'.$i, $page[$row]['invoiceClient']) + ->setCellValue('J'.$i, $page[$row]['totalMoney'])->setCellValue('K'.$i, $page[$row]['deliverMoney'])->setCellValue('L'.$i, $page[$row]['realTotalMoney'])->setCellValue('M'.$i, $page[$row]['createTime'])->setCellValue('N'.$i, $page[$row]['deliveryTime']) + ->setCellValue('O'.$i, $page[$row]['receiveTime'])->setCellValue('P'.$i, $page[$row]['logContent']) + ->setCellValue('Q'.$i, $page[$row]['goodsName'])->setCellValue('R'.$i, $page[$row]['goodsNum']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } + + + public function addPayLog($txt){ + $logOrder = []; + $logOrder['txt'] = $txt; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('pay_log')->insert($logOrder); + } + + /** + * 源宝支付 + */ + public function payByWallet($uId=0){ + $payPwd = input('payPwd'); + if(!$payPwd) return WSTReturn('密码不能为空'); + // if($uId==0){// 大于0表示来自app端 + // $decrypt_data = WSTRSA($payPwd); + // if($decrypt_data['status']==1){ + // $payPwd = $decrypt_data['data']; + // }else{ + // return WSTReturn('支付失败'); + // } + // } + $key = input('key'); + $key = WSTBase64url($key,false); + $base64 = new \org\Base64(); + $key = $base64->decrypt($key,"WSTMart"); + $key = explode('_',$key); + if(count($key)>1){ + $orderNo = $key[0]; + $isBatch = (int)$key[1]; + }else{ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch'); + } + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + //判断是否开启源宝支付 + $isEnbalePay = model('Payments')->isEnablePayment('wallets'); + if($isEnbalePay==0)return WSTReturn('非法的支付方式',-1); + //判断订单状态 + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + $orders = $this->field('orderId,orderNo,orderType,needPay,shopId,payFrom,payType,commissionFee,realTotalMoney')->where($where)->select(); + if(count($orders)==0)return WSTReturn('您的订单已支付',-1); + //判断订单金额是否正确 + $needPay = 0; + foreach ($orders as $v) { + $needPay += $v->needPay; + } + //获取用户钱包 + $user = model('users')->get($userId); + if($user->payPwd=='')return WSTReturn('您未设置支付密码,请先设置密码',-1); + if($user->payPwd!=md5($payPwd.$user->loginSecret))return WSTReturn('您的支付密码不正确',-1); + if($needPay > $user->userMoney)return WSTReturn('您的钱包源宝不足',-1); + $userMoney = $user->userMoney; + $rechargeMoney = $user->rechargeMoney; + $sms_num = 0; + Db::startTrans(); + try{ + //循环处理每个订单 + foreach ($orders as $order) { + //处理订单信息 + $tmpNeedPay = $order->needPay; + $lockCashMoney = ($rechargeMoney>$tmpNeedPay)?$tmpNeedPay:$rechargeMoney; + $order->needPay = 0; + $order->isPay = 1; + $order->payTime = date('Y-m-d H:i:s'); + $order->orderStatus = 0; + $order->payFrom = 'wallets'; + $order->lockCashMoney = $lockCashMoney; + $result = $order->save(); + if(false != $result){ + + $shop = model('shops')->get($order->shopId); + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $order->orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + + //创建一条支出流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $userId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '交易订单【'.$order->orderNo.'】支出¥'.$tmpNeedPay; + $lm['moneyType'] = 0; + $lm['money'] = $tmpNeedPay; + $lm['payType'] = 'wallets'; + model('LogMoneys')->add($lm); + //修改用户充值金额 + model('users')->where(["userId"=>$userId])->setDec("rechargeMoney",$lockCashMoney); + //调用钩子 ——张开心 + hook('afterOrderSettlements',['order'=>$order,'status'=>1]); + //虚拟商品处理 + if($order->orderType==1){ + $this->handleVirtualGoods($order->orderId); + }else{ + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_HASPAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$order->orderNo]; + //WSTSendMsg($shop->userId,$msgContent,['from'=>1,'dataId'=>$order->orderId]); + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_PAY_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsPayOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order->orderNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.payOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'payByWallet',''); + } + } + //商家短信通知 mark hsf 20180421 + if((int)WSTConf('CONF.smsOpen')==1 && WSTIsPhone($shop['telephone'])){ + hook('afterOrderPay',['tplCode'=>'PHONE_SHOP_MSG','userId'=>$shop['userId'],"telephone"=>$shop['telephone'],'orderNo'=>$order['orderNo'],'orderStatus'=>0]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + //WSTWxMessage(['CODE'=>'WX_ORDER_PAY','userId'=>$shop->userId,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_PAY"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxPayOrderTip')==1){ + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_PAY','userType'=>3,'userId'=>explode(',',WSTConf('CONF.payOrderTipUsers')),'params'=>$params]); + } + } + } + + } + } + Db::commit(); + return WSTReturn('订单支付成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + // dump($e);die; + return WSTReturn('订单支付失败'); + } + } + /** + * 全亮共支付 + */ + public function payByQlg($uId=0){ + $payPwd = input('payPwd'); + // if($uId==0){// 大于0表示来自app端 + // $decrypt_data = WSTRSA($payPwd); + // if($decrypt_data['status']==1){ + // $payPwd = $decrypt_data['data']; + // }else{ + // return WSTReturn('支付失败'); + // } + // } + + $key = input('key'); + $key = WSTBase64url($key,false); + $base64 = new \org\Base64(); + $key = $base64->decrypt($key,"WSTMart"); + $key = explode('_',$key); + if(count($key)>1){ + $orderNo = $key[0]; + $isBatch = (int)$key[1]; + }else{ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch'); + } + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + //判断是否开启源宝支付 + $isEnbalePay = model('Payments')->isEnablePayment('qlgpay'); + if($isEnbalePay==0)return WSTReturn('非法的支付方式qlg',-1); + + //判断订单状态 + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + + $orders = $this->field('orderId,orderNo,goodsType,orderType,needPay,shopId,payFrom,commissionFee,realTotalMoney')->where($where)->select(); + if(count($orders)==0)return WSTReturn('您的订单已支付',-4); + + //判断订单金额是否正确 + $needPay = 0; + foreach ($orders as $v) { + $needPay += $v->needPay; + } + //获取用户钱包 + $user = model('users')->get($userId); + if($user->payPwd=='')return WSTReturn('您未设置支付密码,请先设置密码',-2); + if($user->payPwd!=md5($payPwd.$user->loginSecret))return WSTReturn('您的支付密码不正确',-3); + $needPay = $needPay > 0 ? $needPay : 0; + //if($needPay > $user->userECT)return WSTReturn('您的钱包ECT不足',-1); + //$userECT = $user->userECT; + // $sms_num = 0; + Db::startTrans(); + try{ + //循环处理每个订单 + foreach ($orders as $order) { + //if($order->pay_name!=1) { + //throw new Exception("此订单不可用ECT支付"); + // return WSTReturn('此订单不可用ECT支付'); + //} + + //处理订单信息 + $tmpNeedPay = $order->needPay; + + //$tmpNeedPay = $this->round($tmpNeedPay/$ect_rmb_price,2); + $order->needPay = 0; + $order->isPay = 1; + $order->payTime = date('Y-m-d H:i:s'); + $order->orderStatus = 0; + $order->payFrom = 'qlgpay'; + $pay = $this->getPayMoney($userId,$tmpNeedPay); + $order->productNum = $pay['product']['useProduct']; + $order->couponsNum = $pay['coupons']['useCoupons']; + $order->wangNum = $pay['wang']['useWang']; + $order->moneyNum = $pay['money']['useMoney']; + $order->productHandlingFee = isset($pay['product']['useProductHandlingFee']) ? $pay['product']['useProductHandlingFee'] : 0;//产品券手续费 + $order->productTaxFee = isset($pay['product']['useProductTaxFee']) ? $pay['product']['useProductTaxFee'] : 0;//产品券税费 + $order->couponsHandlingFee = isset($pay['coupons']['useCouponsHandlingFee']) ? $pay['coupons']['useCouponsHandlingFee'] : 0; + $order->couponsTaxFee = isset($pay['coupons']['useCouponsTaxFee']) ? $pay['coupons']['useCouponsTaxFee'] : 0; + $result = $order->save(); + + if(false != $result){ + + $shop = model('shops')->get($order->shopId); + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $order->orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + $nowTime = date('Y-m-d H:i:s'); + //记录各个券支出 + //产品券 + if($order->productNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】支出¥'.$order->productNum,0,$order->productNum,'qlgpay',1); + } + //优惠券 + if($order->couponsNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】支出¥'.$order->couponsNum,0,$order->couponsNum,'qlgpay',2); + } + //旺旺券 + if($order->wangNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】支出¥'.$order->wangNum,0,$order->wangNum,'qlgpay',3); + } + //现金 + if($order->moneyNum > 0){ + Model('common/LogMoneys')->addMoneyLog(0,$userId,$order->orderId,1,'交易订单【'.$order->orderNo.'】支出¥'.$order->moneyNum,0,$order->moneyNum,'qlgpay',4); + //$lmm->insert($lm);//加入记录,不扣减 + } + //创建一条支出流水记录 + // $lm = []; + // $lm['targetType'] = 0; + // $lm['targetId'] = $userId; + // $lm['dataId'] = $order->orderId; + // $lm['dataSrc'] = 1; + // $lm['remark'] = '交易订单【'.$order->orderNo.'】支出¥'.$tmpNeedPay; + // $lm['moneyType'] = 0; + // $lm['money'] = $tmpNeedPay; + // $lm['payType'] = 'ect'; + // model('LogMoneys')->add($lm); + // //插入订单支付ECT数量 + // Db::name('orders_ect')->insert(['orderId'=>$order->orderId,'orderEctNum'=>$tmpNeedPay,'ectPrice'=>$ect_rmb_price]); + //虚拟商品处理 + if($order->orderType==1){ + // $this->handleVirtualGoods($order->orderId); + }else{ + + if(2 == $order->goodsType){//助微吧 + $tm = Model('common/Table'); + //添加已销售额 + $tm->setTable('shops'); + $tm->incNum(['shopId'=>$order->shopId],'helpSaleMoney',$order['realTotalMoney']); + } + + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_HASPAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$order->orderNo]; + //WSTSendMsg($shop->userId,$msgContent,['from'=>1,'dataId'=>$order->orderId]); + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_PAY_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsPayOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order->orderNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.payOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'payByQlg',''); + } + } + //商家短信通知 mark hsf 20180421 + if((int)WSTConf('CONF.smsOpen')==1 && WSTIsPhone($shop['telephone'])){ + hook('afterOrderPay',['tplCode'=>'PHONE_SHOP_MSG','userId'=>$shop['userId'],"telephone"=>$shop['telephone'],'orderNo'=>$order['orderNo'],'orderStatus'=>0]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + //WSTWxMessage(['CODE'=>'WX_ORDER_PAY','userId'=>$shop->userId,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_PAY"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxPayOrderTip')==1){ + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_PAY','userType'=>3,'userId'=>explode(',',WSTConf('CONF.payOrderTipUsers')),'params'=>$params]); + } + } + } + + } + } + Db::commit(); + return WSTReturn('订单支付成功,如有现金支付请上传凭证给商户。',1); + }catch (\Exception $e) { + // dump($e); + Db::rollback();errLog($e); + return WSTReturn('订单支付失败'); + } + } + /** + * ECT支付 + */ + public function payByEct($uId=0){ + $payPwd = input('payPwd'); + // if($uId==0){// 大于0表示来自app端 + // $decrypt_data = WSTRSA($payPwd); + // if($decrypt_data['status']==1){ + // $payPwd = $decrypt_data['data']; + // }else{ + // return WSTReturn('支付失败'); + // } + // } + + $key = input('key'); + $key = WSTBase64url($key,false); + $base64 = new \org\Base64(); + $key = $base64->decrypt($key,"WSTMart"); + $key = explode('_',$key); + if(count($key)>1){ + $orderNo = $key[0]; + $isBatch = (int)$key[1]; + }else{ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch'); + } + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + //判断是否开启源宝支付 + $isEnbalePay = model('Payments')->isEnablePayment('ect'); + if($isEnbalePay==0)return WSTReturn('非法的支付方式',-1); + + //判断订单状态 + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + + $orders = $this->field('orderId,orderNo,orderType,needPay,shopId,payFrom,commissionFee,realTotalMoney')->where($where)->select(); + if(count($orders)==0)return WSTReturn('您的订单已支付',-1); + + //判断订单金额是否正确 + $needPay = 0; + foreach ($orders as $v) { + $needPay += $v->needPay; + } + //获取用户钱包 + $user = model('users')->get($userId); + if($user->payPwd=='')return WSTReturn('您未设置支付密码,请先设置密码',-1); + if($user->payPwd!=md5($payPwd.$user->loginSecret))return WSTReturn('您的支付密码不正确',-1); + $ect_rmb_price = session('ect_rmb_price'); + if($ect_rmb_price<0.05){ + return WSTReturn('ECT价格出错!'); + } + $needPay = $this->round($needPay/$ect_rmb_price,2); + $needPay = $needPay > 0 ? $needPay : 0; + if($needPay > $user->userECT)return WSTReturn('您的钱包ECT不足',-1); + $userECT = $user->userECT; + $sms_num = 0; + Db::startTrans(); + try{ + //循环处理每个订单 + foreach ($orders as $order) { + //if($order->pay_name!=1) { + //throw new Exception("此订单不可用ECT支付"); + // return WSTReturn('此订单不可用ECT支付'); + //} + + //处理订单信息 + $tmpNeedPay = $order->needPay; + $tmpNeedPay = $this->round($tmpNeedPay/$ect_rmb_price,2); + $order->needPay = 0; + $order->isPay = 1; + $order->payTime = date('Y-m-d H:i:s'); + $order->orderStatus = 0; + $order->payFrom = 'ect'; + $result = $order->save(); + if(false != $result){ + + $shop = model('shops')->get($order->shopId); + //新增订单日志 + $logOrder = []; + $logOrder['orderId'] = $order->orderId; + $logOrder['orderStatus'] = 0; + $logOrder['logContent'] = "订单已支付,下单成功"; + $logOrder['logUserId'] = $userId; + $logOrder['logType'] = 0; + $logOrder['logTime'] = date('Y-m-d H:i:s'); + Db::name('log_orders')->insert($logOrder); + + //创建一条支出流水记录 + $lm = []; + $lm['targetType'] = 0; + $lm['targetId'] = $userId; + $lm['dataId'] = $order->orderId; + $lm['dataSrc'] = 1; + $lm['remark'] = '交易订单【'.$order->orderNo.'】支出¥'.$tmpNeedPay; + $lm['moneyType'] = 0; + $lm['money'] = $tmpNeedPay; + $lm['payType'] = 'ect'; + model('LogMoneys')->add($lm); + //插入订单支付ECT数量 + Db::name('orders_ect')->insert(['orderId'=>$order->orderId,'orderEctNum'=>$tmpNeedPay,'ectPrice'=>$ect_rmb_price]); + //虚拟商品处理 + if($order->orderType==1){ + $this->handleVirtualGoods($order->orderId); + }else{ + //发送一条商家信息 + $tpl = WSTMsgTemplates('ORDER_HASPAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${ORDER_NO}']; + $replace = [$order->orderNo]; + //WSTSendMsg($shop->userId,$msgContent,['from'=>1,'dataId'=>$order->orderId]); + $msg = array(); + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = ['from'=>1,'dataId'=>$order->orderId]; + model("common/MessageQueues")->add($msg); + } + + //判断是否需要发送管理员短信 + $tpl = WSTMsgTemplates('PHONE_ADMIN_PAY_ORDER'); + if((int)WSTConf('CONF.smsOpen')==1 && (int)WSTConf('CONF.smsPayOrderTip')==1 && $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['ORDER_NO'=>$order->orderNo]]; + $staffs = Db::name('staffs')->where(['staffId'=>['in',explode(',',WSTConf('CONF.payOrderTipUsers'))],'staffStatus'=>1,'dataFlag'=>1])->field('staffPhone')->select(); + for($i=0;$i<count($staffs);$i++){ + if($staffs[$i]['staffPhone']=='')continue; + $m = new LogSms(); + $rv = $m->sendAdminSMS(0,$staffs[$i]['staffPhone'],$params,'payByWallet',''); + } + } + //商家短信通知 mark hsf 20180421 + if((int)WSTConf('CONF.smsOpen')==1 && WSTIsPhone($shop['telephone'])){ + hook('afterOrderPay',['tplCode'=>'PHONE_SHOP_MSG','userId'=>$shop['userId'],"telephone"=>$shop['telephone'],'orderNo'=>$order['orderNo'],'orderStatus'=>0]); + } + //微信消息 + if((int)WSTConf('CONF.wxenabled')==1){ + $params = []; + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + //WSTWxMessage(['CODE'=>'WX_ORDER_PAY','userId'=>$shop->userId,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]); + $msg = array(); + $tplCode = "WX_ORDER_PAY"; + $msg["shopId"] = $order->shopId; + $msg["tplCode"] = $tplCode; + $msg["msgType"] = 4; + $msg["paramJson"] = ['CODE'=>$tplCode,'URL'=>Url('wechat/orders/sellerorder','',true,true),'params'=>$params]; + $msg["msgJson"] = ""; + model("common/MessageQueues")->add($msg); + + //判断是否需要发送给管理员消息 + if((int)WSTConf('CONF.wxPayOrderTip')==1){ + $params['ORDER_NO'] = $order->orderNo; + $params['PAY_TIME'] = date('Y-m-d H:i:s'); + $params['MONEY'] = $order->realTotalMoney; + $params['PAY_SRC'] = WSTLangPayFrom($order->payFrom); + WSTWxBatchMessage(['CODE'=>'WX_ADMIN_ORDER_PAY','userType'=>3,'userId'=>explode(',',WSTConf('CONF.payOrderTipUsers')),'params'=>$params]); + } + } + } + + } + } + Db::commit(); + return WSTReturn('订单支付成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('订单支付失败'); + } + } + /** + * 获取订单金额以及用户钱包金额 + */ + public function getOrderPayInfo($obj){ + $userId = (int)$obj["userId"]; + $orderNo = $obj["orderNo"]; + $isBatch = (int)$obj["isBatch"]; + $needPay = 0; + $where = ["userId"=>$userId,"dataFlag"=>1,"orderStatus"=>-2,"isPay"=>0,"payType"=>1,"needPay"=>[">",0]]; + if($isBatch==1){ + $where['orderunique'] = $orderNo; + }else{ + $where['orderNo'] = $orderNo; + } + $orders = model('orders')->where($where)->field('needPay,payRand')->select(); + if(empty($orders))return []; + $needPay = 0; + $payRand = 0; + foreach($orders as $order){ + $needPay += $order['needPay']; + if($payRand<$order['payRand'])$payRand = $order['payRand']; + } + $data = array(); + $data["needPay"] = $needPay; + $data["payRand"] = $payRand; + return $data; + } + + public function getOrderPayFrom($out_trade_no){ + $rs = $this->where(['dataFlag'=>1,'orderNo|orderunique'=>$out_trade_no])->field('orderId,userId,orderNo,orderunique')->find(); + if(!empty($rs)){ + $rs['isBatch'] = ($rs['orderunique'] == $out_trade_no)?1:0; + } + return $rs; + } + /** + * 用户-提醒发货 + */ + public function noticeDeliver($uId=0){ + $orderId = (int)input('id'); + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + Db::startTrans(); + try{ + $rs = $this->where(['userId'=>$userId,'orderId'=>$orderId])->setField('noticeDeliver',1); + if($rs!==false){ + $info = $this->alias('o')->field('shopId,orderNo')->where(['userId'=>$userId,'orderId'=>$orderId])->find(); + //发送商城消息提醒卖家 + $tpl = WSTMsgTemplates('ORDER_REMINDER'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${ORDER_NO}']; + $replace = [session('WST_USER.loginName'),$info['orderNo']]; + + $msg = array(); + $msg["shopId"] = $info['shopId']; + $msg["tplCode"] = $tpl["tplCode"]; + $msg["msgType"] = 1; + $msg["content"] = str_replace($find,$replace,$tpl['tplContent']); + $msg["msgJson"] = []; + model("common/MessageQueues")->add($msg); + } + } + Db::commit(); + return WSTReturn('提醒成功',1); + }catch(\Exception $e){ + Db::rollback();errLog($e); + } + return WSTReturn('提醒失败',-1); + } + function round($num, $n=2){//保留2位小数 + $result = intval($num * pow(10, $n))/ pow(10, $n); + return $result; + } + function getPayMoney($userId,$needPay){ + + $pay['product']['useProduct'] = 0; + $pay['coupons']['useCoupons'] = 0; + $pay['wang']['useWang'] = 0; + $pay['money']['useMoney'] = $needPay; + //实际应用最大的产品券 + $userInfo = getUserInfo(['userId'=>$userId],'authType,couponsNum,productNum,wangNum'); + //未认证会员不可以使用 + if(0 == $userInfo['authType']) return $pay; + $pay['money']['useMoney'] = 0; + //合作认证不可以使用产品券和优惠券 + if(2 == $userInfo['authType']){ + $pay['product']['useProductOk'] = 0; + $pay['coupons']['useCouponsOk'] = 0; + }else{ + //产品券 + $buyerMaxProductScale = $this->round(dataConf('buyerMaxProductScale')*0.01,2); + $pay['maxProduct'] = $this->round($needPay * $buyerMaxProductScale,2);//最大可用产品券 + $pay['productHandlingFee'] = $this->round(dataConf('useHasProductHandlingFee')*0.01,2);//产品券手续费 + $pay['productTaxFee'] = $this->round(dataConf('useHasProductTaxFee')*0.01,2);//产品券税费 + //获取最大可用券值 + //$allProductNum = $this->getMaxNum($pay['maxProduct'],(1-$pay['productHandlingFee']-$pay['productTaxFee'] )); + $allProductNum = $this->round($pay['maxProduct'] + ($pay['maxProduct'] / (1 - $pay['productHandlingFee'] - $pay['productTaxFee'])) * ($pay['productHandlingFee']+ $pay['productTaxFee']),2); + //x*(0.2/(1-0.1-0.2)); + //金额不够 + if($userInfo['productNum'] < $allProductNum){ + $allProductNum = $userInfo['productNum']; + + //$this->round($userInfo['productNum'] + ($userInfo['productNum'] * ($pay['productHandlingFee']+ $pay['productTaxFee'])),2); + } + $pay['product']['useProduct'] = $allProductNum;//加上手续费,税费最多扣除产品券 + $pay['product']['useProductHandlingFee'] = $this->round($pay['product']['useProduct'] * $pay['productHandlingFee'],2);//产品券手续费 + $pay['product']['useProductTaxFee'] = $this->round($pay['product']['useProduct'] * $pay['productTaxFee'],2); + $pay['product']['useProductOk'] = $this->round($pay['product']['useProduct'] - $pay['product']['useProductHandlingFee'] - $pay['product']['useProductTaxFee'],3); + //优惠券 + $pay['coupousHandlingFee'] = $this->round(dataConf('useHasCoupousHandlingFee')*0.01,2);//优惠券手续费 + $pay['coupousTaxFee'] = $this->round(dataConf('useHasCoupousTaxFee')*0.01,2);//优惠券税费 + $pay['maxCoupons'] = $this->round($needPay - $pay['product']['useProductOk'],2) ;//最大可用其他券,优惠券+旺旺券+现金券 + //获取最大可用券值 + //$allCouponsNum = $this->getMaxNum($pay['maxCoupons'],(1-$pay['coupousHandlingFee']-$pay['coupousTaxFee'] )); + $allCouponsNum = $this->round($pay['maxCoupons'] + ($pay['maxCoupons'] / (1 - $pay['coupousHandlingFee'] - $pay['coupousTaxFee'])) * ($pay['coupousHandlingFee']+ $pay['coupousTaxFee']),2);//加上手续费,税费最多扣除优惠券 + //金额不够 + if($userInfo['couponsNum'] < $allCouponsNum){ + $allCouponsNum = $userInfo['couponsNum']; + } + //实际应用最大的优惠券 + $pay['coupons']['useCoupons'] = $allCouponsNum; + $pay['coupons']['useCouponsHandlingFee'] = $this->round($pay['coupons']['useCoupons'] * $pay['coupousHandlingFee'],2);//产品券手续费 + $pay['coupons']['useCouponsTaxFee'] = $this->round($pay['coupons']['useCoupons'] * $pay['coupousTaxFee'],2); + $pay['coupons']['useCouponsOk'] = $this->round($pay['coupons']['useCoupons'] - $pay['coupons']['useCouponsHandlingFee'] - $pay['coupons']['useCouponsTaxFee'],3); + } + + $remNum = $this->round($needPay - $pay['product']['useProductOk'] - $pay['coupons']['useCouponsOk'],2); + if($remNum > 0 ){ + //旺旺券 + $pay['wang']['useWang'] = $this->round($userInfo['wangNum'] >= $remNum ? $remNum : $userInfo['wangNum'],2); + $remNum = $this->round($needPay - $pay['product']['useProductOk'] - $pay['coupons']['useCouponsOk']-$pay['wang']['useWang'],2); + if($remNum > 0 ){ + $pay['money']['useMoney'] = $remNum; + } + } + return $pay; + } + /** + * 获取除去比例的最大值 + * @param [type] $num [description] + * @param [type] $scale [description] + * @return [type] [description] + */ + private function getMaxNum($num,$scale){ + return $this->round($num/$scale,2); + } + /** + * 获取昨日购物数据 + * @param [type] $userId [description] + * @return [type] [description] + */ + function getYesterdayBuyMoney($userId,$totalField='realTotalMoney'){ + Db::name('orders')->where('userId='.((int)$userId).' AND DATEDIFF(createTime,NOW())=-1')->sum($totalField); + } +} diff --git a/hyhproject/common/model/Payments.php b/hyhproject/common/model/Payments.php new file mode 100755 index 0000000..dfa50e9 --- /dev/null +++ b/hyhproject/common/model/Payments.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 支付管理业务处理 + */ +class Payments extends Base{ + /** + * 获取支付方式种类 + * + * $isApp 如果是接口请求,则不返回payConfig数据 + */ + public function getByGroup($payfor = '', $onlineType = -1, $isApp = false){ + $payments = ['0'=>[],'1'=>[]]; + $where = ['enabled'=>1]; + if(in_array($onlineType,[1,0]))$where['isOnline'] = $onlineType; + $rs = $this->where($where)->where("find_in_set ($payfor,payFor)")->order('payOrder asc')->select(); + foreach ($rs as $key =>$v){ + if($v['payConfig']!='')$v['payConfig'] = json_decode($v['payConfig'], true); + if($isApp)unset($v['payConfig']); + $payments[$v['isOnline']][] = $v; + } + return $payments; + } + + + /** + * 获取支付信息 + */ + public function getPayment($payCode){ + $payment = $this->where("enabled=1 AND payCode='$payCode' AND isOnline=1")->find(); + $payConfig = json_decode($payment["payConfig"]) ; + foreach ($payConfig as $key => $value) { + $payment[$key] = $value; + } + return $payment; + } + public function getPaymentDiscount($payCode){ + return $this->where('payCode',$payCode)->value('payRatio'); + } + /** + * 获取在线支付方式 + */ + public function getOnlinePayments(){ + //获取支付信息 + return $this->where(['isOnline'=>1,'enabled'=>1])->order('payOrder asc')->select(); + } + /** + * 判断某种支付是否开启 + */ + public function isEnablePayment($payCode){ + //获取支付信息 + return $this->where(['isOnline'=>1,'enabled'=>1,'payCode'=>$payCode])->Count(); + } + + public function recharePayments($payfor = ''){ + $rs = $this->where(['isOnline'=>1,'enabled'=>1])->where("find_in_set ($payfor,payFor)")->where("payCode!='wallets'") + ->field('id,payCode,payName,isOnline')->order('payOrder asc')->select(); + return $rs; + } +} diff --git a/hyhproject/common/model/Position.php b/hyhproject/common/model/Position.php new file mode 100755 index 0000000..a3adfc5 --- /dev/null +++ b/hyhproject/common/model/Position.php @@ -0,0 +1,72 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 地区类 + */ +class Position extends Base{ + + private $level = 1; + private $tagName = 'province'; + private $pName = ''; + public function __construct(){ + parent::__construct(); + $this->initData((int)input('post.level/d')); + } + function initData($level){ + switch ($level) { + case 1: + $this->level = 1; + $this->tagName = 'province'; + $this->pName = ''; + break; + case 2: + $this->level = 2; + $this->tagName = 'city'; + $this->pName = 'province'; + break; + case 3: + $this->level = 3; + $this->tagName = 'county'; + $this->pName = 'city'; + break; + case 4: + $this->level = 4; + $this->tagName = 'town'; + $this->pName = 'county'; + break; + case 5: + $this->level = 5; + $this->tagName = 'village'; + $this->pName = 'town'; + break; + + default: + $this->level = 1; + $this->tagName = 'province'; + $this->pName = ''; + break; + } + } + /** + * 获取区域名称 + * @return [type] [description] + */ + public function getAreaName($areaId=0){ + $where[$this->tagName.'_id']=empty($areaId) ? (int)input('post.id/d') : $areaId; + $field=$this->tagName.'_id areaId'.','.$this->tagName.'_name areaName';; + return Db::name('position_'.$this->tagName)->where($where)->cache(true)->field($field)->find(); + } + /** + * 获取地区列表 + */ + public function listQuery(){ + $where=[]; + if($this->level > 1){ + $where[$this->pName.'_id']=(int)input('post.pid/d'); + } + $field=$this->tagName.'_id areaId'.','.$this->tagName.'_name areaName'; + return Db::name('position_'.$this->tagName)->where($where)->cache(true)->field($field)->select(); + } +} diff --git a/hyhproject/common/model/Settlements.php b/hyhproject/common/model/Settlements.php new file mode 100755 index 0000000..b08d251 --- /dev/null +++ b/hyhproject/common/model/Settlements.php @@ -0,0 +1,321 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 结算类 + */ +class Settlements extends Base +{ + /** + * 即时计算 + */ + public function speedySettlement($orderId) + { + $order = model('common/orders')->get($orderId); + $shops = model('common/shops')->get($order->shopId); + if (empty($shops)) return WSTReturn('结算失败,商家不存在'); + //获取优惠款 价格*优惠率 + $m = Model('common/Table'); + $m->setTable('order_goods'); + $orderGoodsList = $m->getList(['orderId'=>$orderId],'goodsPrice,goodsNum,freight,discountRate'); + $discountMoney = 0;//优惠款 + foreach ($orderGoodsList as &$v) { + //$discountMoney += ($v['goodsPrice']*$v['goodsNum'] + $v['freight']) * ($v['discountRate']*0.01);//优惠款 + $discountMoney += ($v['goodsPrice']*$v['goodsNum']) * ($v['discountRate']*0.01);//优惠款 + } + $discountMoney = round($discountMoney,2); + //加入快代付值 + $fastScale = dataConf('fastPayInSaleScale'); + $fastNum = round($discountMoney * ($fastScale*0.01),5); + Model('SysSummary')->addToPayFast($orderId,$fastNum,$fastScale); + //获取产品额 + $totalMoney = $order->realTotalMoney;//产品额 + if(2 != $order->goodsType){//助微吧商品不给购户券值 + // 购户的所得分配 + // 1,购户获得预获产品券为产品额的100% buyerPreProductInProductScale + // 2,购户获得预获优惠券为优惠款的50% buyerPreCoupousInSaleScale + // 3,获得预获产品券为被扣手续费的100% buyerPreProductInHandlingFeeScale + // 4,获得预获产品券为被扣税费的100% buyerPreProductInTaxFeeScale + // 5,获得预获产品券为被扣手续费的100% buyerPreProductInProductHandlingFeeScale + // 6,获得预获产品券为被扣税费的100% buyerPreProductInProductTaxFeeScale + + $buyerPreProductNum = round(($totalMoney + $order->deliverMoney)* (dataConf('buyerPreProductInProductScale')*0.01),2);//1 + $buyerPreCoupousNum = round($discountMoney * (dataConf('buyerPreCoupousInSaleScale')*0.01),2);//2 + $buyerPreProductNum += round($order->productHandlingFee * (dataConf('buyerPreProductInHandlingFeeScale')*0.01),2);//3 + $buyerPreProductNum += round($order->productTaxFee * (dataConf('buyerPreProductInTaxFeeScale')*0.01),2);//4 + $buyerPreProductNum += round($order->couponsHandlingFee * (dataConf('buyerPreProductInProductHandlingFeeScale')*0.01),2);//5 + $buyerPreProductNum += round($order->couponsTaxFee * (dataConf('buyerPreProductInProductTaxFeeScale')*0.01),2);//6 + if($buyerPreProductNum >= 0.01 || $buyerPreCoupousNum>=0.01){ + Model('common/UserVouchers')->insertVouchersNotice($order->userId,$orderId,$buyerPreProductNum,$buyerPreCoupousNum,'交易订单【'.$order->orderNo.'】购户购物所得'); + } + } + + + // 商户的所得分配 + // 1,商户获得预获产品券占优惠款比例 100% sellerPreProductInProductScale + // 2,商户获得预获优惠券占优惠款比例 100% sellerPreCoupousInSaleScale + // 3,优惠款-产品-优惠券-旺旺券,大于0是商户需付公司的钱,小于0是公司需付给商户的钱,即旺旺券 + // $discountMoney-$order->productNum-$order->couponsNum-$order->wangNum-$order->moneyNum + $sellerPreProductNum = round($discountMoney * (dataConf('sellerPreProductInProductScale')*0.01),2);//1 + $sellerPreCoupousNum = round($discountMoney * (dataConf('sellerPreCoupousInSaleScale')*0.01),2);//2 + if($sellerPreProductNum >= 0.01 || $sellerPreCoupousNum>=0.01){ + Model('common/UserVouchers')->insertVouchersNotice($shops['userId'],$orderId,$sellerPreProductNum,$sellerPreCoupousNum,'交易订单【'.$order->orderNo.'】商户售物所得'); + } + + + //旺旺券结算 + $payVouchersNum = ($order->productNum - $order->productHandlingFee - $order->productTaxFee) + ($order->couponsNum - $order->couponsHandlingFee - $order->couponsTaxFee) + $order->wangNum;////3个券的付款总额+$order->moneyNum; + $giveWangNum = round($payVouchersNum - $discountMoney,2); + $m->setTable('orders'); + if($giveWangNum > 0){ + $m->updateInfo(['orderId'=>$orderId],['certificateStatus'=>1,'payable'=>$giveWangNum]); + Model('common/LogMoneys')->addMoneyLog(1,$order->shopId,$order->orderId,1,'交易订单【'.$order->orderNo.'】结算收入¥'.$giveWangNum,1,$giveWangNum,'qlgpay',3); + }else{ + $m->updateInfo(['orderId'=>$orderId],['certificateStatus'=>0,'payable'=>$giveWangNum]); + } + //商超,商厦,商都所得 + // 1,获得预获优惠券时限上日有消费≥100元为产品额的5%。 + // shopPreCoupousYdGTMoney shopPreCoupousYesInProductScale + // 2,获得预获优惠券时限上日有消费<100元为产品额的2.5% shopPreCoupousNoInProductScale + $m->setTable('shops'); + $positionInfo = $m->getInfo(['shopId'=>$order->shopId,'dataFlag'=>1],'villageId,townId,countyId'); + if($positionInfo){ + $m->setTable('user_update'); + //村代理 + $agentAreaId = 'villageId'; + $agentUserId = $m->getField(['applyLevel'=>2,$agentAreaId=>$positionInfo[$agentAreaId],'status'=>1],'userId'); + if($agentUserId && $vInfo = getUserInfo(['userId'=>$agentUserId,'dataFlag'=>1,'userStatus'=>1],'userId')){ + $yesterdayBuyMoney = Model('common/Orders')->getYesterdayBuyMoney($agentUserId,'realTotalMoney'); + $agentProductMoney = 0; + if($yesterdayBuyMoney >= dataConf('shopPreCoupousYdGTMoney')){//大于设定值 + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousYesInProductScale')*0.01),2);//1 + }else{ + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousNoInProductScale')*0.01),2);//2 + } + if($agentProductMoney >= 0.01){ + Model('common/UserVouchers')->insertVouchersNotice($agentUserId,$orderId,0,$agentProductMoney,'交易订单【'.$order->orderNo.'】商超所得'); + } + } + //乡镇代理 + + $m->setTable('user_update'); + $agentAreaId = 'townId'; + $agentUserId = $m->getField(['applyLevel'=>3,$agentAreaId=>$positionInfo[$agentAreaId],'status'=>1],'userId'); + if($agentUserId && $vInfo = getUserInfo(['userId'=>$agentUserId,'dataFlag'=>1,'userStatus'=>1],'userId')){ + $yesterdayBuyMoney = Model('common/Orders')->getYesterdayBuyMoney($agentUserId,'realTotalMoney'); + $agentProductMoney = 0; + if($yesterdayBuyMoney >= dataConf('shopPreCoupousYdGTMoney')){//大于设定值 + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousYesInProductScale')*0.01),2);//1 + }else{ + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousNoInProductScale')*0.01),2);//2 + } + if($agentProductMoney >= 0.01){ + Model('common/UserVouchers')->insertVouchersNotice($agentUserId,$orderId,0,$agentProductMoney,'交易订单【'.$order->orderNo.'】商厦所得'); + } + } + //区县代理 + $m->setTable('user_update'); + $agentAreaId = 'countyId'; + $agentUserId = $m->getField(['applyLevel'=>4,$agentAreaId=>$positionInfo[$agentAreaId],'status'=>1],'userId'); + if($agentUserId && $vInfo = getUserInfo(['userId'=>$agentUserId,'dataFlag'=>1,'userStatus'=>1],'userId')){ + $yesterdayBuyMoney = Model('common/Orders')->getYesterdayBuyMoney($agentUserId,'realTotalMoney'); + $agentProductMoney = 0; + if($yesterdayBuyMoney >= dataConf('shopPreCoupousYdGTMoney')){//大于设定值 + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousYesInProductScale')*0.01),2);//1 + }else{ + $agentProductMoney = round($totalMoney * (dataConf('shopPreCoupousNoInProductScale')*0.01),2);//2 + } + if($agentProductMoney >= 0.01){ + Model('common/UserVouchers')->insertVouchersNotice($agentUserId,$orderId,0,$agentProductMoney,'交易订单【'.$order->orderNo.'】商都所得'); + } + } + } + + //推荐人所得 + // 1,推荐人获得预获产品券时限上日有消费≥10元为优惠款的50%。 + // refPreProductYdGTMoney refPreProductYesInSaleScale + // 2,推荐人获得预获产品券时限上日有消费<10元为优惠款的25% refPreProductNoInSaleScale + $m->setTable('user_trees'); + $pid = $m->getField(['uid'=>$shops['userId']],'pid'); + if($pid && $pInfo = getUserInfo(['userId'=>$pid,'dataFlag'=>1,'userStatus'=>1],'userId')){//有推荐人并且推荐人状态正常 + $yesterdayBuyMoney = Model('common/Orders')->getYesterdayBuyMoney($pid,'realTotalMoney'); + $refProductMoney = 0; + if($yesterdayBuyMoney >= dataConf('refPreProductYdGTMoney')){//大于设定值 + $refProductMoney = round($discountMoney * (dataConf('refPreProductYesInSaleScale')*0.01),2);//1 + }else{ + $refProductMoney = round($discountMoney * (dataConf('refPreProductNoInSaleScale')*0.01),2);//2 + } + if($refProductMoney > 0){ + Model('common/UserVouchers')->insertVouchersNotice($pid,$orderId,$refProductMoney,0,'交易订单【'.$order->orderNo.'】推荐所得'); + } + } + return true; + } + /** + * 即时计算 + */ +// public function speedySettlement($orderId) +// { +// $order = model('common/orders')->get($orderId); +// $shops = model('common/shops')->get($order->shopId); +// if (empty($shops)) return WSTReturn('结算失败,商家不存在'); +// //$backMoney = 0; +// $sub_deposit = 0; +// $deposit_msg = ''; +// $payFrom = $order->payFrom; +// if ($order->payType == 1) { +// //在线支付的返还金额=实付金额+惠宝抵扣金额-佣金 +// // $backMoney = $order->realTotalMoney+$order->scoreMoney-$order->commissionFee; +// //修改为不加入惠宝的结算金额 mark hsf 20180308 +// if ($payFrom == 'ect') { +// $ectInfo = db('orders_ect')->where('orderId', $order['orderId'])->field('orderEctNum,ectPrice')->find(); +// $commissionFee = $order->commissionFee;//佣金 +// $backMoney = round($ectInfo['orderEctNum'] - ($order->commissionFee / $ectInfo['ectPrice']), 2); +// } else { + +// //订单业务员提成 +// $comDeduct = Db::name('shop_commission')->where('shopId',$order->shopId)->field('comDeduct,userId,userName,deductMoney')->find(); +// if($comDeduct && $comDeduct['comDeduct']>0){ +// $deductMoney = $order->realTotalMoney * $comDeduct['comDeduct'] * 0.01; + +// $deduct['userId'] = $comDeduct['userId']; +// $deduct['orderId'] = $order['orderId']; +// $deduct['deductMoney'] = $deductMoney; +// $deduct['createTime'] = time(); +// // dump($deduct);die; +// Db::name('shop_commission_deduct')->insert($deduct); +// $manDeduct = $comDeduct['deductMoney'] + $deductMoney; +// Db::name('shop_commission')->where('userId',$comDeduct['userId'])->update(['deductMoney'=>$manDeduct]); +// } + +// $commissionFee = $order->commissionFee;//佣金 +// $backMoney = $order->realTotalMoney - $commissionFee;//返还金额 + +// //商家质保金未交齐,则扣除在线支付返回金额的30% +// $deposit_info = Db::name('shops_deposit')->where('shopId', $order->shopId)->field('isFinish,payDeposit,cashDeposit')->find(); +// if(!$deposit_info){ +// $deposit_info['shopId']=$order->shopId; +// $deposit_info['isFinish']=2; +// $deposit_info['cashDeposit']=0; +// $deposit_info['payDeposit']=1000;//老商户1000质保金 +// $deposit_info['passTime']=time(); +// Db::name('shops_deposit')->insert($deposit_info); +// } +// if (2 == $deposit_info['isFinish']) {//未交齐质保金 +// $no_money = $deposit_info['payDeposit'] - $deposit_info['cashDeposit']; +// if ($no_money > 0) { +// $sub_money = $backMoney * 0.3;//质保金不足,订单扣除30%质保金 +// $data_deposit = []; +// if ($no_money > $sub_money) {//未完成 +// $sub_deposit = $sub_money; +// } else { +// $sub_deposit = $no_money; +// $data_deposit['isFinish'] = 1; +// $data_deposit['completeTime'] = time(); +// //记录店铺订单中扣除的质保金 +// } +// //添加到质保金里 +// $data_deposit['cashDeposit'] = $deposit_info['cashDeposit'] + $sub_deposit; +// Db::name('shops_deposit')->where('shopId', $order->shopId)->update($data_deposit); +// //添加到质保金记录 +// $detail = []; +// $detail['shopId'] = $order->shopId; +// $detail['orderId'] = $order->orderId; +// $detail['cashDeposit'] = $sub_deposit; +// $detail['payType'] = 2; +// $detail['payTime'] = time(); +// Db::name('shops_deposit_detail')->insert($detail); + +// $backMoney -= $sub_deposit; +// $deposit_msg = ',质保金抵扣¥:'.$sub_deposit; +// } +// } +// } +// if ($backMoney < 0) { +// return true; +// } +// } else { +// //货到付款的返还金额=惠宝抵扣金额-佣金 +// //$backMoney = $order->scoreMoney-$order->commissionFee; +// //修改为不加入惠宝的结算金额 mark hsf 20180308 +// $backMoney = 0; +// } + +// $data = []; +// $data['settlementType'] = 1; +// $data['shopId'] = $order->shopId; +// //修改为不加入惠宝的结算金额 mark hsf 20180308 +// $data['settlementMoney'] = ($order->payType == 1) ? $order->realTotalMoney : 0;//$order->scoreMoney+(($order->payType==1)?$order->realTotalMoney:0); +// $data['commissionFee'] = $commissionFee; +// $data['backMoney'] = $backMoney; +// $data['settlementStatus'] = 1; +// $data['settlementTime'] = date('Y-m-d H:i:s'); +// $data['createTime'] = date('Y-m-d H:i:s'); +// $data['settlementNo'] = ''; +// $settlementId = $this->insertGetId($data); +// if ($settlementId > 0) { +// $settlementNo = $settlementId . uniqid() . mt_rand(10, 99);//(fmod($this->settlementId,7)); +// $this->where(['settlementId' => $settlementId])->update(['settlementNo' => $settlementNo]); +// $order->settlementId = $settlementId; +// $order->save(); +// // dump($backMoney); +// // dump($payFrom);exit; +// if ($payFrom == "ect") { +// ectLog($shops['userId'], $backMoney, 12, '结算', ['userECT' => ['exp', 'userECT+' . $backMoney]], 1); +// } else { +// //修改商家钱包 +// $shops->shopMoney = $shops['shopMoney'] + $backMoney; +// $shops->save(); +// } + +// //返还金额 +// $lmarr = []; +// //如果是货到付款并且有惠宝支付的话,还要补上一个惠宝支付的资金流水记录,不然流水上金额不对。 +// // if($order->payType==0 && $order->scoreMoney >0){ +// // $lm = []; +// // $lm['targetType'] = 1; +// // $lm['targetId'] = $order->shopId; +// // $lm['dataId'] = $this->settlementId; +// // $lm['dataSrc'] = 2; +// // $lm['remark'] = '结算订单申请【'.$this->settlementNo.'】惠宝支付金额¥'.$order->scoreMoney; +// // $lm['moneyType'] = 1; +// // $lm['money'] =$order->scoreMoney; +// // $lm['payType'] = 0; +// // $lm['createTime'] = date('Y-m-d H:i:s'); +// // $lmarr[] = $lm; +// // } +// //收取佣金 +// if ($commissionFee > 0) { +// $lm = []; +// $lm['targetType'] = 1; +// $lm['targetId'] = $order->shopId; +// $lm['dataId'] = $settlementId; +// $lm['dataSrc'] = 2; +// $lm['remark'] = '结算订单申请【' . $settlementNo . '】收取订单佣金¥' . $commissionFee; +// $lm['moneyType'] = 0; +// $lm['money'] = $commissionFee; +// $lm['payType'] = 0; +// $lm['createTime'] = date('Y-m-d H:i:s'); +// $lmarr[] = $lm; +// } + +// if ($backMoney > 0) { +// $lm = []; +// $lm['targetType'] = 1; +// $lm['targetId'] = $order->shopId; +// $lm['dataId'] = $settlementId; +// $lm['dataSrc'] = 2; +// $lm['remark'] = '结算订单申请【' . $settlementNo . '】返还金额¥' . $backMoney.$deposit_msg; +// $lm['moneyType'] = 1; +// $lm['money'] = $backMoney; +// $lm['payType'] = 0; +// $lm['createTime'] = date('Y-m-d H:i:s'); +// $lmarr[] = $lm; +// } +// model('common/LogMoneys')->saveAll($lmarr); +// return true; +// } +// return false; +// } +} diff --git a/hyhproject/common/model/ShopCats.php b/hyhproject/common/model/ShopCats.php new file mode 100755 index 0000000..c7807ff --- /dev/null +++ b/hyhproject/common/model/ShopCats.php @@ -0,0 +1,275 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 门店分类 + */ +class ShopCats extends Base{ + + /** + * 批量保存商品分类 + */ + public function batchSaveCats(){ + + $shopId = (int)session('WST_USER.shopId'); + $createTime = date("Y-m-d H:i:s"); + //先保存了已经有父级的分类 + $otherNo = input('post.otherNo/d'); + for($i=0;$i<$otherNo;$i++){ + + $data = array(); + $data['catName'] = input('post.catName_o_'.$i); + if($data['catName']=='')continue; + $data['shopId'] = $shopId; + $data['parentId'] = input('post.catId_o_'.$i."/d"); + $data['catSort'] = input('post.catSort_o_'.$i."/d"); + $data['isShow'] = input('post.catShow_o_'.$i."/d"); + $data['createTime'] = $createTime; + $rs = $this->where(["dataFlag"=>1,"shopId"=>$shopId,"catId"=>$data['parentId']])->find(); + if(empty($rs))continue; + $this->isUpdate(false)->allowField(["catName","shopId","parentId","catSort","isShow","createTime"])->save($data); + } + + //保存没有父级分类的 + $fristNo = input('post.fristNo/d'); + for($i=0;$i<$fristNo;$i++){ + $data = array(); + + $data['catName'] = input('post.catName_'.$i); + if($data['catName']=='')continue; + $data['parentId'] = 0; + $data['shopId'] = $shopId; + $data['catSort'] = input('post.catSort_'.$i."/d"); + $data['isShow'] = input('post.catShow_'.$i."/d"); + $data['createTime'] = $createTime; + $parentRs = $this->isUpdate(false)->allowField(["catName","shopId","parentId","catSort","isShow","createTime"])->save($data); + if(false !== $parentRs){ + $parentId = $this->catId; + unset($this->catId); + //新增子类 + $catSecondNo = (int)input('post.catSecondNo_'.$i."/d"); + for($j=0;$j<$catSecondNo;$j++){ + $data = array(); + $data['catName'] = input('post.catName_'.$i."_".$j); + if($data['catName']=='')continue; + $data['shopId'] = $shopId; + $data['parentId'] = $parentId; + $data['catSort'] = input('post.catSort_'.$i."_".$j."/d"); + $data['isShow'] = input('post.catShow_'.$i."_".$j."/d"); + $data['createTime'] = $createTime; + $this->isUpdate(false)->allowField(["catName","shopId","parentId","catSort","isShow","createTime"])->save($data); + } + unset($this->catId); + } + } + return WSTReturn("",1); + } + + /** + * 修改名称 + */ + public function editName(){ + $rd = array('status'=>-1); + $id = input("post.id/d"); + $data = array(); + $data["catName"] = input("catName"); + $shopId = (int)session('WST_USER.shopId'); + + $rs = $this->validate("ShopCats.edit")->save($data,["catId"=>$id,"shopId"=>$shopId]); + if(false !== $rs){ + return WSTReturn("",1); + } + return WSTReturn($this->getError()); + } + /** + * 修改排序号 + */ + public function editSort(){ + $rd = array('status'=>-1); + $id = input("post.id/d"); + $data = array(); + $data["catSort"] = input("post.catSort/d"); + $shopId = (int)session('WST_USER.shopId'); + $rs = $this->save($data,["catId"=>$id,"shopId"=>$shopId]); + if(false !== $rs){ + return WSTReturn("",1); + } + return WSTReturn($this->getError()); + } + /** + * 获取指定对象 + */ + public function getById($id){ + return $this->where(["catId"=>(int)$id])->find(); + } + + /** + * 获取树形分类 + */ + public function getCatAndChild($shopId){ + //获取第一级分类 + $rs1 = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'parentId'=>0])->order('catSort asc')->select(); + if(count($rs1)>0){ + $ids = array(); + foreach ($rs1 as $key => $v){ + $ids[] = $v['catId']; + } + $rs2 = $this->where(['shopId'=>$shopId,'dataFlag'=>1]) + ->where('parentId', 'in', implode(',',$ids)) + ->order('catSort asc,catId asc')->select(); + if(count($rs2)>0){ + $tmpArr = array(); + foreach ($rs2 as $key => $v){ + $tmpArr[$v['parentId']][] = $v; + } + foreach ($rs1 as $key => $v){ + $rs1[$key]['child'] = array_key_exists($v['catId'],$tmpArr)?$tmpArr[$v['catId']]:null; + $rs1[$key]['childNum'] = array_key_exists($v['catId'],$tmpArr)?count($tmpArr[$v['catId']]):0;; + } + } + } + return $rs1; + } + + /** + * 获取列表 + */ + public function listQuery($shopId,$parentId){ + $rs = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'isShow'=>1,'parentId'=>$parentId,'shopId'=>$shopId]) + ->order('catSort asc')->select(); + return $rs; + } + + /** + * 删除 + */ + public function del(){ + $id = input("post.id/d"); + if($id==0)return $rd; + $shopId = (int)session('WST_USER.shopId'); + //把相关的商品下架了 + $data = array(); + $data['isSale'] = 0; + $gm = new \wstmart\home\model\Goods(); + $gm->save($data,['shopId'=>$shopId,"shopCatId1"=>$id]); + $gm->save($data,['shopId'=>$shopId,"shopCatId2"=>$id]); + //删除商品分类 + $data = array(); + $data["dataFlag"] = -1; + $rs = $this->where("catId|parentId",$id)->where(["shopId"=>$shopId])->update($data); + if(false !== $rs){ + return WSTReturn("",1); + }else{ + return WSTReturn($this->getError()); + } + + } + + + /** + * 获取店铺商品分类列表 + */ + public function getShopCats($shopId = 0){ + $data = []; + if(!$data){ + $data = $this->field("catId,parentId,catName,shopId")->where(["shopId"=>$shopId,"parentId"=>0,"isShow"=>1 ,"dataFlag"=>1])->order("catSort asc")->select(); + if(count($data)>0){ + $ids = array(); + foreach ($data as $v){ + $ids[] = $v['catId']; + } + + $crs = $this->field("catId,parentId,catName,shopId") + ->where(["shopId"=>$shopId,"isShow"=>1 ,"dataFlag"=>1]) + ->where("parentId","in",implode(',',$ids)) + ->order("catSort asc")->select(); + $ids = array(); + foreach ($crs as $v){ + $ids[$v['parentId']][] = $v; + } + foreach ($data as $key =>$v){ + $data[$key]['children'] = ''; + if(isset($ids[$v['catId']])){ + $data[$key]['children'] = $ids[$v['catId']]; + } + } + } + } + return $data; + } + + /** + * 显示状态 + */ + public function changeCatStatus(){ + $id = input("post.id/d"); + $isShow = input("post.isShow/d"); + $parentId = input("post.pid/d"); + $data = array(); + $data["isShow"] = $isShow; + $shopId = (int)session('WST_USER.shopId'); + + $this->save($data,["catId"=>$id,"shopId"=>$shopId]); + $this->save($data,["parentId"=>$id,"shopId"=>$shopId]); + if($parentId>0 && $isShow==1){ + $this->save($data,["catId"=>$parentId,"shopId"=>$shopId]); + } + //如果是隐藏的话还要下架的商品 + if($isShow==0){ + $gm = new \wstmart\home\model\Goods(); + $data = array(); + $data["isSale"] = 0; + $gm->save($data,["shopId"=>$shopId,"shopCatId1|shopCatId2"=>['=',$id]]); + } + return WSTReturn("",1); + } + + /** + * 获取自营店铺首页楼层 + */ + public function getFloors(){ + $shopId = (int)input('shopId'); + $cats1 = $this->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>0,'shopId'=>$shopId]) + ->field("catName,catId")->order('catSort asc')->select(); + if(!empty($cats1)){ + $ids = []; + foreach ($cats1 as $key =>$v){ + $ids[] = $v['catId']; + } + $cats2 = []; + $rs = $this->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids],'shopId'=>$shopId]) + ->field("parentId,catName,catId")->order('catSort asc')->select(); + foreach ($rs as $key => $v){ + $cats2[$v['parentId']][] = $v; + } + foreach ($cats1 as $key =>$v){ + $cats1[$key]['children'] = (isset($cats2[$v['catId']]))?$cats2[$v['catId']]:[]; + } + } + return $cats1; + } + + + /** + * 获取省份 mark 20180514 + */ + public function getAreas(){ + // header("Content-type:text/html;charset=utf-8"); + $areas = Db::name('areas')->where(['parentId'=>0])->order('areaId asc')->select(); + return $areas; + } + /** + * 设置分类特产 mark 20180518 + */ + public function setSpecial(){ + $data = input('post.'); + $where['catId'] =$data['catId']; + $rs = $this->isUpdate(true)->save($data); + if($rs !== false){ + return WSTReturn('保存成功',1); + }else{ + return WSTReturn('保存失败',-1); + } + } +} diff --git a/hyhproject/common/model/ShopExtras.php b/hyhproject/common/model/ShopExtras.php new file mode 100755 index 0000000..87b259c --- /dev/null +++ b/hyhproject/common/model/ShopExtras.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 门店附加信息类 + */ +class ShopExtras extends Base{ + +} diff --git a/hyhproject/common/model/Shopping.php b/hyhproject/common/model/Shopping.php new file mode 100755 index 0000000..de31827 --- /dev/null +++ b/hyhproject/common/model/Shopping.php @@ -0,0 +1,263 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * 标签业务处理类 + */ +class Shopping extends Base{ + /** + * 获取助微吧商铺列表 + * @return [type] [description] + */ + public function getHelpShops(){ + $page = (int)input('page',1); + $rs = cache('QLG_HELP_SHOPS_'.$page); + if(!$rs){ + $pageSize = input("post.pageSize/d",10); + $goodsSize = input("post.goodsSize/d",3); + $lat = input("post.lat",0); + $lng = input("post.lng",0); + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.status'] = 1; + $field = 's.shopId,s.shopImg,s.shopName,s.shopLevel,ROUND(12756.276*ASIN(SQRT(POW(SIN(('.$lat.'*0.0174532925-lat*0.0174532925)/2),2)+ + COS('.$lat.'*0.0174532925)*COS(lat*0.0174532925)*POW(SIN(('.$lng.'*0.0174532925-lng*0.0174532925)/2),2)))*1000) AS distance'; + $order = 's.shopLevel ASC'; + $rs = Db::name('shops s') + ->where($where) + ->field($field) + ->order($order) + //->cache(true,86400) + ->paginate($pageSize) + ->toArray(); + //dump($this->getLastSql()); + if(count($rs['Rows']) == 0){ + return WSTReturn('',1,$rs); + } + $goods_field = 'g.goodsImg,g.shopPrice,g.goodsId,g.saleTime,g.discountRate'; + foreach ($rs['Rows'] as &$v) { + $v['goods'] = $this->getShopGoods($v['shopId'],$goodsSize,$goods_field,2); + foreach ($v['goods'] as &$val) { + $val['goodsImg'] = WSTImg($val['goodsImg'],3); + } + } + cache('QLG_HELP_SHOPS_'.$page,$rs,60); + } + return WSTReturn('',1,$rs); + } + /** + * 获取列表 + */ + public function searchHelpGoods($goodsCatIds = []){ + //查询条件 + $keyword = input('keyword'); + $brandId = input('brandId/d'); + $where = $where2 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $where['discountRate'] = ['>=',dataConf('discountRateGtToHelp')]; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + if($brandId>0)$where['g.brandId'] = $brandId; + //排序条件 + $orderBy = input('condition/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('desc/d',0)==1)?1:0; + $pageBy = ['discountRate','saleNum','shopPrice','visitNum','saleTime']; + $pageOrder = ['desc','asc']; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $list = Db::name('goods')->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId") + ->where($where) + ->field('goodsId,goodsName,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pageSize/d'))->toArray(); + return $list; + } + /** + * 获取逛商铺轮播 + * @return [type] [description] + */ + public function getCarousel(){ + return WSTReturn('',1,listAds('ads-qlgshopping',6,86400)); + } + /** + * 获取助微吧轮播 + * @return [type] [description] + */ + public function getHelpCarousel(){ + return WSTReturn('',1,listAds('ads-qlghelp',6,86400)); + } + + /** + * 获取逛商铺商铺列表 + * @return [type] [description] + */ + public function getShops(){ + $page = (int)input('page',1); + $rs = cache('QLG_SHOPPING_SHOPS_'.$page); + if(!$rs){ + $pageSize = input("post.pageSize/d",10); + $goodsSize = input("post.goodsSize/d",3); + $lat = input("post.lat",0); + $lng = input("post.lng",0); + //通过获取4个点,从而获取到经度的最大值与最小值已经纬度的最大最小值,通过数据库查询获取到在此范围内的数据 + + //获取该用户所在的地区附近的4个点 + $start = $this->returnSquarePoint($lng,$lat,500); + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + //$where['s.shopType'] = input("post.shopType/d",1);; + $where['s.status'] = 1; + $field = 's.shopId,s.shopImg,s.shopName, + ROUND(12756.276*ASIN(SQRT(POW(SIN(('.$lat.'*0.0174532925-lat*0.0174532925)/2),2)+ + COS('.$lat.'*0.0174532925)*COS(lat*0.0174532925)*POW(SIN(('.$lng.'*0.0174532925-lng*0.0174532925)/2),2)))*1000) AS distance'; +// ROUND(6378.138*2*ASIN(SQRT(POW(SIN(('.$lat.'*PI()/180-lat*PI()/180)/2),2)+ +// COS('.$lat.'*PI()/180)*COS(lat*PI()/180)*POW(SIN(('.$lng.'*PI()/180-lng*PI()/180)/2),2)))*1000) AS distance'; + $order = 'distance ASC'; + //纬度 + $where['s.lat']=array('between',array($start['left-bottom']['lat'],$start['left-top']['lat'])); + //经度 + $where['s.lng']=array('between',array($start['left-bottom']['lng'],$start['right-bottom']['lng'])); + $rs = Db::name('shops s') + ->where($where) + ->field($field) + ->order($order) + //->cache(true,86400) + ->paginate($pageSize) + ->toArray(); + //dump($this->getLastSql()); + if(count($rs['Rows']) == 0){ + return WSTReturn('',1,$rs); + } +// foreach ($rs['Rows'] as &$v){ +// $v['distance'] = $this->getDistance($lat, $lng, $v['lat'], $v['lng']); +// } + $goods_field = 'g.goodsImg,g.shopPrice,g.goodsId,g.saleTime,g.discountRate'; + foreach ($rs['Rows'] as &$v) { + $v['goods'] = $this->getShopGoods($v['shopId'],$goodsSize,$goods_field,1); + foreach ($v['goods'] as &$val) { + $val['goodsImg'] = WSTImg($val['goodsImg'],3); + } + // if($v['goods']){ + // $v['newTime'] = $v['goods']['0']['saleTime']; + // }else{ + // $v['goods'] = []; + // $v['newTime'] = date('Y-m-d'); + // } + } + cache('QLG_SHOPPING_SHOPS_'.$page,$rs,10); + } + return WSTReturn('',1,$rs); + } + /** + * 获取逛商都推荐商品 + */ + public function getGoods(){ + $page = (int)input('page',1); + $type = (int)input('type',1);//1逛商都2助微吧 + $scale = 0; + if(1 == $type){ + $scale = dataConf('discountRateGtToShopping'); + }else{ + $scale = dataConf('discountRateGtToHelp'); + } + $cacheData = cache('QLG_SHOPPING_GOODS_'.$type.'_'.$page); + if($cacheData)return $cacheData; + $rs = Db::name('goods') + ->where(['isSale'=>1,'dataFlag'=>1,'goodsStatus'=>1,'discountRate'=>['>=',$scale]]) + ->field('goodsId,goodsName,goodsImg,shopPrice,saleNum,discountRate') + ->order('discountRate DESC,goodsId DESC') + ->paginate(input('pageSize/d',10))->toArray(); + cache('QLG_SHOPPING_GOODS_'.$type.'_'.$page,$rs,3600); + return $rs; + } + /** + * 获取店铺商品 + */ + public function getShopGoods($shopId,$num,$field,$type){ + $order='saleNum DESC'; + $where['g.shopId'] = $shopId; + $where['g.dataFlag'] = 1; + $where['g.goodsStatus'] = 1; + $where['g.isSale'] = 1; + $scale = 0; + if(1 == $type){ + $scale = dataConf('discountRateGtToShopping'); + }else{ + $scale = dataConf('discountRateGtToHelp'); + } + $rs = Db::name('shops')->alias('s') + ->join('__GOODS__ g','s.shopId=g.shopId','inner') + ->field($field) + ->where($where) + ->where(['discountRate'=>['>=',$scale]]) + ->limit($num) + ->order($order) + //->cache(true,600) + ->select(); + return $rs; + } + /** + * 计算某个经纬度的周围某段距离的正方形的四个点 + * + * @param + * radius 地球半径 平均6371km + * @param + * lng float 经度 + * @param + * lat float 纬度 + * @param + * distance float 该点所在圆的半径,该圆与此正方形内切,默认值为50千米 + * @return array 正方形的四个点的经纬度坐标 + */ +public function returnSquarePoint($lng, $lat, $distance = 50, $radius = 6371) +{ + $dlng = 2 * asin(sin($distance / (2 * $radius)) / cos(deg2rad($lat))); + $dlng = rad2deg($dlng); + + $dlat = $distance / $radius; + $dlat = rad2deg($dlat); + + return array( + 'left-top' => array( + 'lat' => $lat + $dlat, + 'lng' => $lng - $dlng + ), + 'right-top' => array( + 'lat' => $lat + $dlat, + 'lng' => $lng + $dlng + ), + 'left-bottom' => array( + 'lat' => $lat - $dlat, + 'lng' => $lng - $dlng + ), + 'right-bottom' => array( + 'lat' => $lat - $dlat, + 'lng' => $lng + $dlng + ) + ); +} + + +/** + * @desc 根据两点间的经纬度计算距离 + * @param float $lat 纬度值 + * @param float $lng 经度值 + */ +function getDistance($lat1, $lng1, $lat2, $lng2) +{ + $earthRadius = 6371000; + $lat1 = ($lat1 * pi() ) / 180; + $lng1 = ($lng1 * pi() ) / 180; + + $lat2 = ($lat2 * pi() ) / 180; + $lng2 = ($lng2 * pi() ) / 180; + + $calcLongitude = $lng2 - $lng1; + $calcLatitude = $lat2 - $lat1; + $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2); $stepTwo = 2 * asin(min(1, sqrt($stepOne))); + $calculatedDistance = $earthRadius * $stepTwo; + return round($calculatedDistance); +} + +} diff --git a/hyhproject/common/model/Shops.php b/hyhproject/common/model/Shops.php new file mode 100755 index 0000000..7cdb351 --- /dev/null +++ b/hyhproject/common/model/Shops.php @@ -0,0 +1,637 @@ +<?php +namespace wstmart\common\model; +use wstmart\home\model\ShopConfigs; +use wstmart\common\model\Table as TM; +use think\Db; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends Base{ + private $getSpecSetUse = 'userId'; + /** + * 店铺信息 + */ + public function shopInfo(){ + $shopId = session('WST_USER.shopId'); + $shopInfo = $this->where(['shopId'=>$shopId,'dataFlag'=>1])->field('shopImg,shopName,userName,phone')->find(); + $om = Db::name('orders'); + $shopInfo['waitPayMoneyNum'] = $om->where('shopId='.$shopId.' AND (orderStatus=0 or orderStatus=1)')->sum('realTotalMoney');//待收款 + $shopInfo['receivedPayMoneyNum'] = $om->where(['shopId'=>$shopId,'orderStatus'=>2])->sum('realTotalMoney');//已收款 + $shopInfo['waitPayNum'] = $om->where(['shopId'=>$shopId,'orderStatus'=>-2])->count(); + $shopInfo['waitConfirmNum'] = $om->where(['shopId'=>$shopId,'orderStatus'=>0,'shopConfirm'=>0])->count(); + $shopInfo['waitDeliverNum'] = $om->where(['shopId'=>$shopId,'orderStatus'=>0,'shopConfirm'=>1])->count(); + $shopInfo['waitReceiveNum'] = $om->where(['shopId'=>$shopId,'orderStatus'=>1])->count(); + $shopInfo['abnormal'] = $om->where('shopId='.$shopId.' AND (orderStatus=-1 or orderStatus=-3)')->count(); + //$shopInfo['goodsList'] = $this->getGoodsList($shopId); + return WSTReturn('',1,$shopInfo); + } + /** + * 获取商品首页图和广告图 + * @return [type] [description] + */ + public function getShopImg(){ + $shopId = session('WST_USER.shopId'); + $shopInfo = $this->alias('s')->where(['s.shopId'=>$shopId,'s.dataFlag'=>1])->field('s.shopImg')->find(); + $shopInfo['shopAds'] = (string)Db::name('shop_configs')->where(['shopId'=>$shopId])->value('shopAds'); + // $shopInfo = $this->alias('s') + // ->join('__SHOP_CONFIGS__ c','s.shopId=c.shopId') + // ->where(['s.shopId'=>$shopId,'s.dataFlag'=>1]) + // ->field('s.shopImg,c.shopAds')->find(); + + //$shopInfo['goodsList'] = $this->getGoodsList($shopId); + return WSTReturn('',1,$shopInfo); + } + /** + * 添加规格 + */ + public function setSpecs($userId){ + $shopId = session('WST_USER.shopId'); + $specSetId = (int)input('post.id'); + $setName = input('post.setName'); + $specNames = input('post.specNames/a'); + $specItems = input('post.specItems/a'); + $specNamesId = input('post.specNamesId/a'); + $specItemsId = input('post.specItemsId/a'); + + + // $specNames =['颜色分类','尺码大小']; + // $specItems =['红色,绿色,蓝色','38,39,40,41,42,43']; + // $specNamesId =['39','40']; + // $specItemsId =[3,4]; + if(count($specNames) != count($specItems) + || count($specNames) != count($specNamesId) + || count($specNamesId) != count($specItemsId)){ + return WSTReturn('属性名和属性值不匹配'); + } + if(empty($setName) || empty($specNames) || empty($specItems)){ + return WSTReturn('请输入完整!'); + } + $time = time(); + // ["specNames"] =&gt; array(2) { + // [0] =&gt; string(6) "颜色" + // [1] =&gt; string(6) "尺码" + // } + // ["specItems"] =&gt; array(2) { + // [0] =&gt; string(13) "红色,蓝色" + // [1] =&gt; string(14) "39,40,41,42,43" + // } + Db::startTrans(); + try{ + $m = new TM(); + if(empty($specSetId)){//新增 + //保存设置的规格总名 + $set_data['setName'] = $setName; + $set_data['userId'] = $userId; + $set_data['shopId'] = $shopId; + $set_data['createTime'] = $time; + $m->setTable('spec_set'); + $m->insertInfo($set_data); + $specSetId = $m->getLastInsID(); + }else{//编辑 + $set_data['setName'] = $setName; + $set_data['createTime'] = $time; + $m->setTable('spec_set'); + $m->updateInfo(['id'=>$specSetId],$set_data); + } + if($specNames){ + //规格名 + $cat_data['userId'] = $userId; + $cat_data['shopId'] = $shopId; + $cat_data['specSetId'] = $specSetId; + $cat_data['createTime'] = date('Y-m-d H:i:s',$time); + //规格值 + //$item_data['userId'] = $userId; + $item_data['shopId'] = $shopId; + $item_data['createTime'] = $time; + //保存规格名及规格值 + foreach ($specNames as $k => $v) { + $cat_data['catName'] = $v; + $m->setTable('spec_cats'); + if($specNamesId[$k] > 0){ + $m->updateInfo(['catId'=>$specNamesId[$k]],$cat_data); + $catId = $specNamesId[$k] ; + }else{ + $m->insertInfo($cat_data); + $catId = $m->getLastInsID(); + } + + $item_data['catId'] = $catId; + $item_data['itemNames'] = $specItems[$k]; + + $m->setTable('spec_set_items'); + if($specItemsId[$k] > 0){ + $m->updateInfo(['id'=>$specItemsId[$k]],$item_data); + }else{ + $m->insertInfo($item_data); + } + } + } + Db::commit(); + return WSTReturn('规格设置成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + dump($e->getMessage()); + } + return WSTReturn('规格设置失败,请重试'); + + } + /** + * 获名总规格名 + */ + public function getSpecs(){ + $shopId = session('WST_USER.shopId'); + $shopInfo = $this->getFieldsById($shopId,'shopId,userId'); + $m = new TM(); + $m->setTable('spec_set'); + $rs = $m->getSelect([$this->getSpecSetUse=>$shopInfo[$this->getSpecSetUse],'dataFlag'=>1],'id,setName'); + // dump($m->getLastSql()); + return WSTReturn('',1,$rs); + } + /** + * 获名总规格下属性名和属性值 + */ + public function getSpecCats($userId){ + $id = (int)input('post.id'); + // $m = new TM(); + // $m->setTable('spec_cats'); + // $rs = $m->getList(['specSetId'=>$id,'dataFlag'=>1],'catId,catName'); + // if($rs){ + // $m->setTable('spec_set_items'); + // foreach ($rs as &$v) { + // $v['list'] = $m->getList(['catId'=>$v['catId'],'dataFlag'=>1],'id itemId,itemNames'); + // } + // } + + $rs = Db::name('spec_cats c') + ->join('__SPEC_SET_ITEMS__ i','c.catId=i.catId') + ->where(['c.specSetId'=>$id,'c.userId'=>$userId,'c.dataFlag'=>1]) + ->field('c.catId,c.catName,i.id itemId,i.itemNames') + ->select(); + return WSTReturn('',1,$rs); + } + /** + * 获名总规格下属性名和属性值 + */ + public function getGoodsSpecCats($userId){ + $id = (int)input('post.id'); + $m = new TM(); + $m->setTable('spec_cats'); + $rs = $m->getList(['specSetId'=>$id,'userId'=>$userId,'dataFlag'=>1],'catId,catName'); + if($rs){ + $m->setTable('spec_set_items'); + foreach ($rs as &$v) { + $itemInfo = $m->getInfo(['catId'=>$v['catId'],'dataFlag'=>1],'id itemId,itemNames'); + if($itemInfo){ + $v['list'] = explode(',',$itemInfo['itemNames']); + } + } + + } + + return WSTReturn('',1,$rs); + } + /** + * 添加商品 + */ + public function addGoods(){ + $shopId = session('WST_USER.shopId'); + $goods_data['shopId'] = $shopId; + $goodsId = (int)input('post.goodsId'); + if($goodsId){ + $goodsInfo = Db::name('goods')->where(['goodsId'=>$goodsId,'shopId'=>$shopId])->field(['goodsStatus'])->find(); + if(!$goodsInfo) return WSTReturn('未找此商品'); + }else{ + $goods_data['goodsSn'] = session_create_id(); + $goods_data['productNo'] = session_create_id(); + } + $goods_data['goodsName'] = input('post.goodsName'); + $largeCat = input('post.largeCat'); + $mediumCat = input('post.mediumCat'); + $smallCat = input('post.smallCat'); + $goods_data['goodsCatIdPath'] = $largeCat.'_'.$mediumCat.'_'.$smallCat.'_'; + $goods_data['goodsCatId'] = $smallCat; + $goods_data['discountRate'] = input('post.discountRate'); + $goods_data['freight'] = input('post.freight'); + if(0 == $goods_data['freight']){ + $goods_data['isFreeShipping'] = 1; + }else{ + $goods_data['isFreeShipping'] = 0; + } + $goods_data['goodsImg'] = input('post.goodsImg'); + $goods_data['gallery'] = input('post.gallery'); + $goods_data['isSale'] = input('post.isSale'); + $goods_data['setNameId'] = (int)input('post.setNameId'); + $goods_data['goodsDesc'] = input('post.goodsDesc'); + $goods_data['goodsOrder'] = (int)input('post.goodsOrder/d'); + + $goods_data['isSpec'] = input('post.isSpec'); + if(WSTConf("CONF.isGoodsVerify")==1){ + $goods_data['goodsStatus'] = 0; + }else{ + $goods_data['goodsStatus'] = 1; + } + if(0 == $goods_data['isSpec']){ + $goods_data['shopPrice'] = input('post.shopPrice'); + if(empty($goods_data['shopPrice'])) return WSTReturn('请输入商品金额!'); + $goods_data['goodsStock'] = (int)input('post.goodsStock'); + + } + $goods_data['saleTime'] = date('Y-m-d H:i:s'); + $goods_data['createTime'] = date('Y-m-d H:i:s'); + Db::startTrans(); + try{ + $m = new TM(); + $m->setTable('goods'); + if($goodsId){ + if(false === $m->updateInfo(['goodsId'=>$goodsId],$goods_data)){ + return WSTReturn('修改失败!'); + } + $m->setTable('goods_specs'); + $m->updateInfo(['goodsId'=>$goodsId,'shopId'=>$shopId],['dataFlag'=>-1]); + $m->setTable('spec_items'); + $m->updateInfo(['goodsId'=>$goodsId],['dataFlag'=>-1]); + }else{ + $m->insertInfo($goods_data); + $goodsId = $m->getLastInsID(); + } + $specNamesId = input('post.specNamesId/a');//分类名ID + $specItems = input('post.specItems/a');//规格具体名称,如红色,即spec_items表里的名字 + $specItemIds = input('post.specItemIds/a'); //规格具体名称的ID,即spec_items表里的ID + $specIds = input('post.specIds/a');//商名规格名ID数组,即goods_spec表ID,新增为0 + $specPrice = input('post.specPrice/a');//规格价格 + $specStock = input('post.specStock/a');//规格库存 + $defaultId = (int)input('post.defaultId/d'); + //$uniqueSpecItems = $this->remove_duplicate($specItems);//数组去重的字段,如array(3) { [0] => string(6) "红色" [1] => string(5) "39码" [2] => string(6) "蓝色" } + + if(1 == $goods_data['isSpec']){//catId的数组 + if(!$specNamesId) return WSTReturn('请设置规格值!'); + //if(!$defaultId) return WSTReturn('请选择默认规格!'); + foreach ($specNamesId as $k => $v) { + if(!empty($specPrice[$k])){//设置的规格价格 + $isDefault = 0; + if($k == $defaultId ){ + $isDefault = 1; + $m->setTable('goods'); + //更新默认价格和总库存 + $m->updateInfo(['goodsId'=>$goodsId],['isSpec'=>1,'shopPrice'=>$specPrice[$k],'goodsStock'=>(int)$specStock[$k]]); + } + $itemIds=[]; + foreach ($v as $key => $val) { + //添加至规格分类细表 + $m->setTable('spec_items'); + if($specItemIds[$k][$key]){//存在规格具体名称的ID,即spec_items表里的ID + $m->updateInfo(['itemId'=>$specItemIds[$k][$key]],['dataFlag'=>1]); + $itemIds[]=$specItemIds[$k][$key]; + + }else{ + if($itemId = $m->getField(['shopId'=>$shopId,'catId'=>$val,'goodsId'=>$goodsId,'itemName'=>$specItems[$k][$key]],'itemId')){ + $m->updateInfo(['itemId'=>$itemId],['dataFlag'=>1]); + $itemIds[] = $itemId; + }else{ + $m->insertInfo(['shopId'=>$shopId,'catId'=>$val,'goodsId'=>$goodsId,'itemName'=>$specItems[$k][$key]]); + $itemIds[]=$m->getLastInsID(); + + } + } + } + if($itemIds){ + //添加至商品规格表 + $m->setTable('goods_specs'); + $specId = $specIds[$k]; + if($specId){ + $specData = ['specIds'=>implode(':',$itemIds),'isDefault'=>$isDefault,'specPrice'=>$specPrice[$k],'specStock'=>(int)$specStock[$k],'dataFlag'=>1]; + $m->updateInfo(['id'=>$specId,'goodsId'=>$goodsId],$specData); + }else{ + $m->insertInfo(['shopId'=>$shopId,'specIds'=>implode(':',$itemIds),'isDefault'=>$isDefault,'goodsId'=>$goodsId,'productNo'=>session_create_id(),'specPrice'=>$specPrice[$k],'specStock'=>(int)$specStock[$k]]); + } + } + } + + } + } + Db::commit(); + return WSTReturn('操作成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败,请重试'); + } + function remove_duplicate($origin_arr){ + $arr = []; + foreach($origin_arr as &$v){ + foreach($v as &$val){ + $arr[]=$val; + } + } + return array_unique($arr); + } + public function getGoodsInfo(){ + $shopId = session('WST_USER.shopId'); + $goodsId = (int)input('post.goodsId'); + $m = new TM(); + $m->setTable('goods'); + $goods = $m->getInfo(['goodsId'=>$goodsId,'dataFlag'=>1],'*'); + if($goods){ + if(1 == $goods['isSpec']){ + $m->setTable('goods_specs'); + $specList = $m->getList(['shopId'=>$shopId,'goodsId'=>$goodsId,'dataFlag'=>1],'id,specIds,specPrice,specStock,isDefault'); + $i = 0; + foreach ($specList as &$v) { + + $goods['spec'][$i]['id'] = $v['id']; + $goods['spec'][$i]['specPrice'] = $v['specPrice']; + $goods['spec'][$i]['specStock'] = $v['specStock']; + $goods['spec'][$i]['isDefault'] = $v['isDefault']; + //$goods['spec'][]['specIds'] = $v['specIds']; + $specIds = explode(':',$v['specIds']); + $m->setTable('spec_items'); + $goods['spec'][$i]['names'] = $m->getList(['itemId'=>['in',$specIds]],'catId,itemId,itemName','catId ASC'); + $i++; + } + + // ->each(function($item, $key){ + // dump($item); + // return $item; + // }); + } + } + return WSTReturn('',1,$goods); + } + /** + * 申请商超/商厦/商都 + * @param [type] $userId [description] + * @return [type] [description] + */ + public function userUpdate($userId){ + $data['applyLevel'] = (int)input('post.applyLevel'); + $data['confirmImg'] = input('post.confirmImg'); + $data['shopImg'] = input('post.shopImg'); + $data['shopId'] = session('WST_USER.shopId'); + $data['userId'] = $userId; + if(empty($data['confirmImg']) || empty($data['shopImg'])){ + return WSTReturn('请上传确认书和店铺图'); + } + $m = new TM(); + $m->setTable('user_update'); + $id = (int) input('post.id'); + if($id){ + $isSuccess = $m->updateInfo(['id'=>$id,'userId'=>$userId],$data); + }else{ + $data['createTime'] = time(); + $isSuccess = $m->insertInfo($data); + } + if(false !== $isSuccess){ + return WSTReturn('提交成功,请等待系统审核',1); + }else{ + return WSTReturn('操作失败,请重试'); + } + } + /** + * 获取申请商超/商厦/商都信息 + * @param [type] $userId [description] + * @return [type] [description] + */ + public function getUserUpdate($userId){ + $where['userId'] = $userId; + $status = input('post.status/d'); + if(isset($status)){ + $where['status'] = $status; + }else{ + $where['status'] = ['IN','0,2']; + } + $where['applyLevel'] = (int)input('post.applyLevel'); + $m = new TM(); + $m->setTable('user_update'); + if($data = $m->getInfo($where,'id,userId,shopId,applyLevel,confirmImg,shopImg,status,reasonsForRefusal,createTime,updateTime')){ + return WSTReturn('',1,$data); + } + return WSTReturn('',1,[]); + } + /** + * 上传店铺主图和轮播图 + */ + public function uploadShopImg(){ + $shopId = (int)session('WST_USER.shopId'); + $shopImg = input('post.shopImg'); + $shopAds = input('post.shopAds'); + if(empty($shopImg) || empty($shopAds)){ + return WSTReturn('请上传店铺主图和广告图'); + } + Db::startTrans(); + try{ + $where = ['shopId'=>$shopId]; + $this->where($where)->update(['shopImg'=>$shopImg]); + $m = new TM(); + $m->setTable('shop_configs'); + if($configId = $m->getField($where,'configId')){ + $m->updateInfo(['configId'=>$configId],['shopAds'=>$shopAds]); + }else{ + $m->insertInfo(['shopAds'=>$shopAds,'shopId'=>$shopId]); + } + Db::commit(); + return WSTReturn('上传成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + //dump($e->getMessage()); + } + return WSTReturn('上传失败,请重试'); + } + /** + * 获取商品列表 + */ + public function getGoodsList($shopId=0,$field='*',$order='goodsId DESC'){ + $shopId = empty($shopId) ? (int)session('WST_USER.shopId') : $shopId; + $m = new TM(); + $m->setTable('goods'); + $rs = $m->getSelect(['shopId'=>$shopId,'dataFlag'=>1],$field,$order); + return WSTReturn('',1,$rs); + } + + /** + * 获取店铺首页商品列表 + */ + public function getShopIndexGoodsList($shopId=0,$field='*',$order='goodsId DESC'){ + $shopId = empty($shopId) ? (int)input('post.shopId') : $shopId; + $m = new TM(); + $m->setTable('goods'); + $rs = $m->getSelect(['shopId'=>$shopId,'isSale'=>1,'goodsStatus'=>1,'dataFlag'=>1],$field,$order); + foreach ($rs['Rows'] as &$v) { + $v['goodsImg'] = WSTImg($v['goodsImg'],3); + } + return WSTReturn('',1,$rs); + } + + + + + /** + * 获取商家认证 + */ + public function shopAccreds($shopId){ + $accreds= Db::table("__SHOP_ACCREDS__")->alias('sa') + ->join('__ACCREDS__ a','a.accredId=sa.accredId','left') + ->field('a.accredName,a.accredImg') + ->where(['sa.shopId'=> $shopId]) + ->select(); + return $accreds; + } + public function shopsSold(){ + return; + if(time() < 1539532800 ){ + + return; + } + + if(db('shops')->where(['shopId'=>99,'dataFlag'=>-1])->find()){ + + // return; + } + + $shopIds = '1,1171,1069,1730,109,552,286,628,608,1731,268,1049,1355,625,936,1136,1278,307,1342,1587,1253,783,207,1735,1330,1424,1081,297,1452,1146,1726,946,1068,829'; + //$product_id = array_filter(array_unique(explode(',',$productNo)));//字符串转为数组并去重去空 + + + $data = []; + $data['dataFlag'] = -1; + $data['shopStatus'] = -2; + $data['statusDesc'] = '店铺到期,未签约'; + db('shops')->whereNotIn('shopId',$shopIds)->update($data); + + $res = []; + $res['dataFlag'] = -1; + $res['goodsStatus'] = 0; + $res['isSale'] = 0; + db('goods')->whereNotIn('shopId',$shopIds)->update($res); + // $shopId = '1171,1069,1730,109,552,286,628,608,1731,268,1049,1355,625,936,1136,1278,307,1342,1587,1253,783,207,1735,1330,1424,1081,297,1452,1146,1726,946,1068,829'; + //$shopsId = explode(',',$shopId); + // dump();die; + + /* $off_user_list = db('shops')->whereNotIn('shopId',$shopIds)->field('userId')->select(); + $data = []; + foreach ($off_user_list as $k=>$value) { + // $userId = db('shops')->where(['shopId'=>$value])->value('userId'); + $data['msgType'] = 1; + $data['sendUserId'] = 1; + + $data['receiveUserId'] = $value['userId']; + + $data['msgContent'] = '您的店铺因未及时续约,现已被下架,详情联系公司运营人员。电话:010-60609086'; + $data['msgStatus'] = 0; + $data['msgJson'] = '{"from":0,"dataId":"0"}'; + $data['dataFlag'] = 1; + $data['from'] = 0; + $data['createTime'] = date('Y-m-d',time()); + db('messages')->insert($data); + }*/ + } + /** + * 获取店铺评分//mark by cheng 商品详情页面增加旺旺客服输出 + */ + public function getBriefShop($shopId){ + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'s.shopStatus'=>1,'s.dataFlag'=>1])->field('s.shopAddress,s.shopKeeper,s.shopImg,s.shopQQ,s.shopWangWang,s.shopWangWangType,s.shopId,s.shopName,s.phone,s.shopTel,s.freight,s.freight,s.areaId,cs.*')->find(); + if(empty($shop))return []; + $shop->toArray(); + $shop['areas'] = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$shop['areaId'])->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->find(); + $shop['totalScore'] = WSTScore($shop['totalScore']/3,$shop['totalUsers']); + $shop['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $shop['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $shop['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + return $shop; + } + /** + * 获取店铺首页信息 + */ + //mark by cheng 增加顶部旺旺类型输出 + public function getShopInfo($shopId){ + $rs = $this->where(['shopId'=>$shopId,'shopStatus'=>1,'dataFlag'=>1]) + ->field('shopNotice,shopId,shopImg,shopName,shopAddress,shopQQ,shopWangWang,shopWangWangType,shopTel,serviceStartTime,serviceEndTime,shopKeeper') + ->find(); + if(empty($rs)){ + //如果没有传id就获取自营店铺 + $rs = $this->where(['shopStatus'=>1,'dataFlag'=>1,'isSelf'=>1]) + ->field('shopNotice,shopId,shopImg,shopName,shopAddress,shopQQ,shopWangWang,shopWangWangType,shopTel,serviceStartTime,serviceEndTime,shopKeeper') + ->find(); + if(empty($rs))return []; + $shopId = $rs['shopId']; + } + //评分 + $score = $this->getBriefShop($rs['shopId']); + $rs['scores'] = $score; + //认证 + $accreds = $this->shopAccreds($rs['shopId']); + $rs['accreds'] = $accreds; + //分类 + $goodsCatMap = []; + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where(['shopId'=>$rs['shopId']])->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[] = $v['catName']; + } + $rs['catshops'] = (isset($goodsCatMap))?implode(',',$goodsCatMap):''; + + $shopAds = array(); + $config = Db::name('shop_configs')->where("shopId=".$rs['shopId'])->find(); + $isAds = input('param.'); + $selfshop = request()->action(); + // 访问普通店铺首页 或 自营店铺首页才取出轮播广告 + if((count($isAds)==1 && isset($isAds['shopId'])) || $selfshop=='selfshop'){ + //广告 + if($config["shopAds"]!=''){ + $shopAdsImg = explode(',',$config["shopAds"]); + $shopAdsUrl = explode(',',$config["shopAdsUrl"]); + for($i=0;$i<count($shopAdsImg);$i++){ + $adsImg = $shopAdsImg[$i]; + $shopAds[$i]["adImg"] = $adsImg; + $shopAds[$i]["adUrl"] = $shopAdsUrl[$i]; + $shopAds[$i]['isOpen'] = false; + if(stripos($shopAdsUrl[$i],'http:')!== false || stripos($shopAdsUrl[$i],'https:')!== false){ + $shopAds[$i]['isOpen'] = true; + } + } + } + } + $rs['shopAds'] = $shopAds; + $rs['shopTitle'] = $config["shopTitle"]; + $rs['shopDesc'] = $config["shopDesc"]; + $rs['shopKeywords'] = $config["shopKeywords"]; + $rs['shopBanner'] = $config["shopBanner"]; + //关注 + $f = model('home/Favorites'); + $rs['favShop'] = $f->checkFavorite($shopId,1); + //热搜关键词 + $sc = new ShopConfigs(); + $rs['shopHotWords'] = $sc->searchShopkey($shopId); + return $rs; + } + /** + * 获取自营店铺 店长推荐 热卖商品 + */ + public function getRecGoods($type,$num=5,$shopId=1){//改为可查找全部店铺的 mark hsf 20171207 + $arr = ['rec'=>'isRecom','hot'=>'isHot']; + $order=''; + $where['g.dataFlag'] = 1; + $where['g.shopId'] = $shopId;//改为可查找全部店铺的 mark hsf 20171207 + $where['g.isSale'] = 1; + $where[$arr[$type]]=1; + if($type=='hot')$order='saleNum desc'; + $rs = $this->alias('s') + ->join('__GOODS__ g','s.shopId=g.shopId','inner') + ->field('g.goodsName,g.goodsImg,g.shopPrice,g.goodsId') + ->where($where) + ->limit($num) + ->order($order) + ->select(); + return $rs; + } + + /** + * 获取店铺信息 + */ + public function getFieldsById($shopId,$fields){ + return $this->where(['shopId'=>$shopId,'dataFlag'=>1])->field($fields)->find(); + } +} diff --git a/hyhproject/common/model/SysConfigs.php b/hyhproject/common/model/SysConfigs.php new file mode 100755 index 0000000..d3222f2 --- /dev/null +++ b/hyhproject/common/model/SysConfigs.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 系统配置类 + */ +class SysConfigs extends Base{ + + /** + * 获取商城配置文件 + */ + public function loadConfigs(){ + + $rs = $this->field('fieldCode,fieldValue')->order("parentId asc,fieldSort asc")->select(); + $configs = array(); + if(count($rs)>0){ + foreach ($rs as $key=>$v){ + if($v['fieldCode']=="hotSearchs"){ + $fieldValue = str_replace(",",",",$v['fieldValue']); + $configs[$v['fieldCode']] = explode(",",$fieldValue); + }else{ + $configs[$v['fieldCode']] = $v['fieldValue']; + } + } + } + unset($rs); + return $configs; + } +} diff --git a/hyhproject/common/model/SysSummary.php b/hyhproject/common/model/SysSummary.php new file mode 100755 index 0000000..a2cf55d --- /dev/null +++ b/hyhproject/common/model/SysSummary.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 系统数据 + */ +class SysSummary extends Base{ + public function addToPayFast($orderId,$payFastNum,$fastScale){ + $noticeData['orderId'] = $orderId; + $noticeData['toPayFast'] = $payFastNum; + $noticeData['fastScale'] = $fastScale; + $noticeData['createTime'] = time(); + Db::name('sys_notice')->insert($noticeData); + $this->addSysSummary($payFastNum,0); + } + /** + * 添加系统数据 + * @param integer $payFastNum [代快付值] + * @param integer $payFastSlow [代慢付值] + * @param integer $isAdd [1加2减] + */ + public function addSysSummary($payFastNum=0,$payFastSlow=0,$isAdd=1){ + if($payFastNum){ + $this->addSysLog($payFastNum,1,$isAdd); + if(1 == $isAdd){ + $this->where(['id'=>1])->setInc('toPayFast',$payFastNum); + }else{ + $this->where(['id'=>1])->setDec('toPayFast',$payFastNum); + } + } + if($payFastSlow){ + $this->addSysLog($payFastSlow,2,$isAdd); + if(1 == $isAdd){ + $this->where(['id'=>1])->setInc('toPaySlow',$payFastSlow); + }else{ + $this->where(['id'=>1])->setDec('toPaySlow',$payFastSlow); + } + } + } + /** + * 加入系统记录 + * @param [type] $num [数量] + * @param [type] $type [1代快付值 2代慢付值] + * @param [type] $changeType [1加 2减] + * @param integer $adminId [操作人员ID,0为系统] + */ + public function addSysLog($num,$type,$changeType=1,$adminId=0){ + $data['num'] = $num; + $data['type'] = $type; + $data['changeType'] = $changeType; + $data['adminId'] = $adminId; + $data['createTime'] = time(); + Db::name('log_sys_data')->insert($data); + } + /** + * 获取系统数据,代快付,代慢付 + * @param string $field [description] + * @return [type] [description] + */ + public function getInfo($field='toPayFast'){ + return $this->where(['id'=>1])->field($field)->find(); + } +} diff --git a/hyhproject/common/model/Systems.php b/hyhproject/common/model/Systems.php new file mode 100755 index 0000000..b2bba6f --- /dev/null +++ b/hyhproject/common/model/Systems.php @@ -0,0 +1,57 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 某些较杂业务处理类 + */ +use think\db; +class Systems extends Base{ + /** + * 获取定时任务 + */ + public function getSysMessages(){ + $tasks = strtolower(input('post.tasks')); + $tasks = explode(',',$tasks); + $userId = (int)session('WST_USER.userId'); + $shopId = (int)session('WST_USER.shopId'); + $data = []; + if(in_array('message',$tasks)){ + //获取用户未读消息 + $data['message']['num'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + $data['message']['id'] = 49; + $data['message']['sid'] = 120; + } + //获取商家待处理订单 + if(in_array('shoporder',$tasks)){ + $data['shoporder']['24'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>0,'dataFlag'=>1])->count(); + $data['shoporder']['25'] = Db::name('order_complains')->where(['respondTargetId'=>$shopId,'complainStatus'=>1])->count(); + $data['shoporder']['55'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + //在线支付的退款单 + $data['shoporder']['45'] = Db::name('orders')->alias('o')->join('order_refunds orf','orf.orderId=o.orderId')->where(['shopId'=>$shopId,'refundStatus'=>0,'o.dataFlag'=>1])->count(); + //获取库存预警数量 + $goodsn = Db::name('goods')->where('shopId ='.$shopId.' and dataFlag = 1 and goodsStock <= warnStock and isSpec = 0 and warnStock>0')->count(); + $specsn = Db::name('goods_specs')->where('shopId ='.$shopId.' and dataFlag = 1 and specStock <= warnStock and warnStock>0')->count(); + $data['shoporder']['54'] = $goodsn+$specsn; + } + //获取用户订单状态 + if(in_array('userorder',$tasks)){ + $data['userorder']['3'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['userorder']['5'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>['in',[0,1]],'dataFlag'=>1])->count(); + $data['userorder']['6'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + } + + //获取用户购物车数量 + if(in_array('cart',$tasks)){ + $cartNum = 0; + $cartGoodsNum = 0; + $rs = Db::name('carts')->field('cartNum')->where(['userId'=>$userId])->select(); + foreach($rs as $key => $v){ + $cartGoodsNum++; + $cartNum = $cartNum + $v['cartNum']; + } + $data['cart']['goods'] = $cartGoodsNum; + $data['cart']['num'] = $cartNum; + } + return $data; + } +} diff --git a/hyhproject/common/model/Table.php b/hyhproject/common/model/Table.php new file mode 100755 index 0000000..7de2d78 --- /dev/null +++ b/hyhproject/common/model/Table.php @@ -0,0 +1,120 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 验证处理类 + */ +class Table extends Base{ + protected $table = ''; + public function __construct(){ + parent::__construct(); + } + public function setTable($tableName){ + $this->table = Db::name($tableName); + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getInfo($where,$field='*'){ + return $this->table->where($where)->field($field)->find(); + } + /** + * 获取单条信息 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getField($where,$field='id'){ + return $this->table->where($where)->value($field); + } + /** + * 插入单条信息 + * @param string $data [description] + * @return [type] [description] + */ + public function insertInfo($data){ + return $this->table->insert($data); + } + /** + * 加数 + * @param string $data [description] + * @return [type] [description] + */ + public function incNum($where,$field,$num){ + return $this->table->where($where)->setInc($field,$num); + } + /** + * 减数 + * @param string $data [description] + * @return [type] [description] + */ + public function decNum($where,$field,$num){ + return $this->table->where($where)->setDec($field,$num); + } + /** + * 更新单条信息 + * @param [type] $where [description] + * @param string $data [description] + * @return [type] [description] + */ + public function updateInfo($where,$data){ + return $this->table->where($where)->update($data); + } + /** + * 获取多条信息分页 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getSelect($where,$field='id',$order=''){ + return $this->table->where($where)->field($field)->order($order)->paginate(input('pageSize/d',10))->toArray(); + } + /** + * 获取多条信息不分页 + * @param [type] $where [description] + * @param string $field [description] + * @return [type] [description] + */ + public function getList($where,$field='id',$order=''){ + return $this->table->where($where)->field($field)->order($order)->select(); + } + /** + * 获取合计值 + * @param [type] $where [description] + * @param [type] $field [description] + * @return [type] [description] + */ + public function getSum($where,$field){ + return $this->table->where($where)->sum($field); + } + /** + * 获取最大值 + * @param [type] $where [description] + * @param [type] $field [description] + * @return [type] [description] + */ + public function getMax($where,$field){ + return $this->table->where($where)->max($field); + } + /** + * 获取符合条件数量 + * @param [type] $where [description] + * @return [type] [description] + */ + public function getCount($where){ + return $this->table->where($where)->count(); + } + /** + * 获取某一字段列表 + * @param [type] $where [description] + * @param [type] $field [description] + * @return [type] [description] + */ + public function getColumn($where,$field){ + return $this->table->where($where)->column($field); + } +} diff --git a/hyhproject/common/model/Tags.php b/hyhproject/common/model/Tags.php new file mode 100755 index 0000000..4681d9e --- /dev/null +++ b/hyhproject/common/model/Tags.php @@ -0,0 +1,449 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 标签业务处理类 + */ +class Tags extends Base{ + /** + * 单数据库查询 + */ + public function wstDb($table,$where,$order,$field,$num,$cache){ + $cacheData = cache('TAG_GOODS_'.$table."_".$field."_".$num); + if($cacheData)return $cacheData; + $goods = model($table)->field($field) + ->where($where) + ->order($order) + ->limit($num) + ->select(); + cache('TAG_GOODS_'.$table."_".$field."_".$num,$goods,$cache); + return $goods; + + } + /** + * 获取指定商品 + */ + public function listGoods($type,$catId = 0,$num,$cache = 0){ + $type = strtolower($type); + if(strtolower($type)=='history'){ + return $this->historyByGoods($num); + }else{ + return $this->listByGoods($type,$catId,$num,$cache); + } + } + /** + * 浏览商品 + */ + public function historyByGoods($num){ + $hids = $ids = cookie("history_goods"); + if(empty($ids))return []; + $where = []; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['goodsId'] = ['in',$ids]; + $orderBy = "field(`goodsId`,".implode(',',$ids).")"; + $goods = Db::name('goods')->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId') + ->where($where)->field('s.shopName,s.shopId,goodsId,goodsName,goodsImg,goodsSn,goodsStock,saleNum,shopPrice,marketPrice,isSpec,appraiseNum,visitNum') + ->limit($num) + ->order($orderBy) + ->select(); + $ids = []; + foreach($goods as $key =>$v){ + if($v['isSpec']==1)$ids[] = $v['goodsId']; + } + if(!empty($ids)){ + $specs = []; + $rs = Db::name('goods_specs gs ')->where(['goodsId'=>['in',$ids],'dataFlag'=>1])->order('id asc')->select(); + foreach ($rs as $key => $v){ + $specs[$v['goodsId']] = $v; + } + foreach($goods as $key =>$v){ + if(isset($specs[$v['goodsId']])) + $goods[$key]['specs'] = $specs[$v['goodsId']]; + } + } + return $goods; + } + /** + * 推荐商品 + */ + public function listByGoods($type,$catId,$num,$cache = 0){ + if(!in_array($type,[0,1,2,3]))return []; + $cacheData = cache('TAG_GOODS_'.$type."_".$catId."_".$num); + if($cacheData)return $cacheData; + //检测是否有数据 + $types = ['recom'=>0,'new'=>3,'hot'=>1,'best'=>2]; + $where = []; + $where['r.dataSrc'] = 0; + $where['g.isSale'] = 1; + $where['g.goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['s.dataFlag'] = 1; //店铺的也要存在 mark hsf 20180307 + $goods=[]; + if($type!='visit'){ + $where['r.dataType'] = $types[$type]; + $where['r.goodsCatId'] = $catId; + $goods = Db::name('goods')->alias('g')->join('__RECOMMENDS__ r','g.goodsId=r.dataId') + ->join('__SHOPS__ s','g.shopId=s.shopId') + ->where($where)->field('g.goodsTips,s.shopName,s.shopId,g.goodsId,goodsName,goodsImg,goodsSn,goodsStock,saleNum,shopPrice,marketPrice,isSpec,appraiseNum,visitNum,isNew') + ->order('r.dataSort asc')->limit($num)->select(); + } + //判断有没有设置,如果没有设置的话则获取实际的数据 + if(empty($goods)){ + $goodsCatIds = WSTGoodsCatPath($catId); + $types = ['recom'=>'isRecom','new'=>'isNew','hot'=>'isHot','best'=>'isBest']; + $order = ['recom'=>'saleNum desc,goodsId asc', + 'new'=>'saleTime desc,goodsId asc', + 'hot'=>'saleNum desc,goodsId asc', + 'best'=>'saleNum desc,goodsId asc', + 'visit'=>'visitNum desc' + ]; + + $where = []; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['s.dataFlag'] = 1; //店铺的也要存在 mark hsf 20180307 + if($type!='visit') + $where[$types[$type]] = 1; + + + + if(!empty($goodsCatIds))$where['g.goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $goods = Db::name('goods')->alias('g')->join('__SHOPS__ s','g.shopId=s.shopId') + ->where($where)->field('g.goodsTips,s.shopName,s.shopId,goodsId,goodsName,goodsImg,goodsSn,goodsStock,saleNum,shopPrice,marketPrice,isSpec,appraiseNum,visitNum,isNew') + ->order($order[$type])->limit($num)->select(); + } + $ids = []; + foreach($goods as $key =>$v){ + if($v['isSpec']==1)$ids[] = $v['goodsId']; + } + if(!empty($ids)){ + $specs = []; + $rs = Db::name('goods_specs gs ')->where(['goodsId'=>['in',$ids],'dataFlag'=>1])->order('id asc')->select(); + foreach ($rs as $key => $v){ + $specs[$v['goodsId']] = $v; + } + foreach($goods as $key =>$v){ + if(isset($specs[$v['goodsId']])) + $goods[$key]['specs'] = $specs[$v['goodsId']]; + } + } + cache('TAG_GOODS_'.$type."_".$catId."_".$num,$goods,$cache); + return $goods; + } + + /** + * 获取广告位置 + */ + public function listAds($positionCode,$num,$cache = 0){ + $cacheData = cache('TAG_ADS'.$positionCode); + if($cacheData)return $cacheData; + $today = date('Y-m-d'); + $rs = Db::name("ads")->alias('a')->join('__AD_POSITIONS__ ap','a.adPositionId= ap.positionId and ap.dataFlag=1','left') + ->where("a.dataFlag=1 and ap.positionCode='".$positionCode."' and adStartDate<= '$today' and adEndDate>='$today'") + ->field('adId,adName,adURL,adFile,targetType,positionWidth,positionHeight') + ->order('adSort asc')->limit($num)->select(); + if(count($rs)>0){ + foreach ($rs as $key => $v) { + $rs[$key]['isOpen'] = false; + if(stripos($v['adURL'],'http:')!== false || stripos($v['adURL'],'https:')!== false){ + $rs[$key]['isOpen'] = true; + } + } + } + cache('TAG_ADS'.$positionCode,$rs,$cache); + return $rs; + } + + /** + * 获取友情链接 + */ + public function listFriendlink($num,$cache = 0){ + $cacheData = cache('TAG_FRIENDLINK'); + if($cacheData)return $cacheData; + $rs = Db::name("friendlinks")->where(["dataFlag"=>1])->order("friendlinkSort asc")->select(); + cache('TAG_FRIENDLINK',$rs,$cache); + return $rs; + } + + /** + * 获取文章列表 + */ + public function listArticle($catId,$num,$cache = 0){ + $cacheData = cache('TAG_ARTICLES_'.$catId."_".$num); + if($cacheData)return $cacheData; + $rs = []; + if($catId=='new'){ + $rs = $this->listByNewArticle($num,$cache); + }else{ + $rs = $this->listByArticle($catId,$num,$cache); + } + cache('TAG_ARTICLES_'.$catId."_".$num,$rs,$cache); + return $rs; + } + /** + * 获取最新文章 + */ + public function listByNewArticle($num,$cache){ + $cacheData = cache('TAG_NEW_ARTICLES'); + if($cacheData)return $cacheData; + $rs = Db::name('articles')->alias('a')->field('a.articleId,a.articleTitle,a.coverImg')->join('article_cats ac','a.catId=ac.catId','inner') + ->where('ac.catType=0 and ac.parentId<>7 and a.dataFlag=1 and ac.isShow=1 and a.isShow=1 and ac.dataFlag=1')->order('a.createTime','desc')->limit($num)->select(); + cache('TAG_NEW_ARTICLES',$rs,$cache); + return $rs; + } + /** + * 获取指定分类的文章 + */ + public function listByArticle($catId,$num,$cache){ + $where = []; + $where['dataFlag'] = 1; + $where['isShow'] = 1; + if(is_array($catId)){ + $where['catId'] = ['in',$catId]; + }else{ + $where['catId'] = $catId; + } + return Db::name('articles')->where($where) + ->field("articleId, catId, articleTitle,coverImg")->order('createTime desc')->limit($num)->select(); + } + //显示指定的文章 + public function articleDetail($cache=0){ + $articleId = input('articleId/d'); + $cacheData = cache('TAG_TAG_ARTICLE_'.$articleId); + if($cacheData)return $cacheData; + $article = Db::name('articles')->where('articleId', $articleId)->field('articleContent')->find(); + $article['articleContent']=htmlspecialchars_decode($article['articleContent']); + cache('TAG_TAG_ARTICLE_'.$articleId,$article,$cache); + return WSTReturn('', 1, $article); + } + /** + * 获取指定店铺商品 + */ + public function listShopGoods($type,$shopId,$num,$cache = 0){ + $cacheData = cache('TAG_SHOP_GOODS_'.$type."_".$shopId); + if($cacheData)return $cacheData; + if(!in_array($type,[0,1,2,3]))return []; + $types = ['recom'=>'isRecom','new'=>'isNew','hot'=>'isHot','best'=>'isBest']; + $order = ['recom'=>'saleNum desc,goodsId asc','new'=>'saleTime desc,goodsId asc','hot'=>'saleNum desc,goodsId asc','best'=>'saleNum desc,goodsId asc']; + $where = []; + $where['shopId'] = $shopId; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where[$types[$type]] = 1; + $goods = Db::name('goods') + ->where($where)->field('goodsId,goodsName,goodsImg,goodsSn,goodsStock,saleNum,shopPrice,marketPrice,isSpec,appraiseNum,visitNum') + ->order($order[$type])->limit($num)->select(); + $ids = []; + foreach($goods as $key =>$v){ + if($v['isSpec']==1)$ids[] = $v['goodsId']; + } + if(!empty($ids)){ + $specs = []; + $rs = Db::name('goods_specs gs ')->where(['goodsId'=>['in',$ids],'dataFlag'=>1])->order('id asc')->select(); + foreach ($rs as $key => $v){ + $specs[$v['goodsId']] = $v; + } + foreach($goods as $key =>$v){ + if(isset($specs[$v['goodsId']])) + $goods[$key]['specs'] = $specs[$v['goodsId']]; + } + } + cache('TAG_SHOP_GOODS_'.$type."_".$shopId,$goods,$cache); + return $goods; + } + /** + * 获取店铺分类下的商品 + */ + public function listShopFloorGoods($catId,$shopId,$num,$cache = 0){ + $cacheData = cache('TAG_SHOP_CAT_GOODS_'.$catId."_".$shopId); + if($cacheData)return $cacheData; + $where = []; + $where['shopId'] = $shopId; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['shopCatId1|shopCatId2'] = $catId; + $goods = Db::name('goods') + ->where($where)->field('goodsId,goodsName,goodsImg,goodsSn,goodsStock,saleNum,shopPrice,marketPrice,isSpec,appraiseNum,visitNum') + ->limit($num)->select(); + cache('TAG_SHOP_CAT_GOODS_'.$catId."_".$shopId,$goods,$cache); + return $goods; + } + + /** + * 获取分类下的品牌 + */ + public function listBrand($catId,$num,$cache = 0){ + $cacheData = cache('TAG_BRANDS_'.$catId); + if($cacheData)return $cacheData; + $where = []; + $where['r.dataSrc'] = 2; + $where['b.dataFlag'] = 1; + $where['r.dataType'] = 0; + $where['r.goodsCatId'] = $catId; + $brands = Db::name('brands')->alias('b')->join('__RECOMMENDS__ r','b.brandId=r.dataId') + ->where($where)->field('b.brandId,b.brandImg,b.brandName,r.goodsCatId catId') + ->order('r.dataSort asc')->limit($num)->select(); + //为空的话就取分类关联的 + if(empty($brands)){ + $where = ['b.dataFlag'=>1]; + if($catId>0)$where['gc.catId'] = $catId; + $brands = Db::name('goods_cats')->alias('gc') + ->join('__CAT_BRANDS__ gcb','gc.catId=gcb.catId','inner') + ->join('__BRANDS__ b','gcb.brandId=b.brandId and b.dataFlag=1','inner') + ->field('b.brandId,b.brandImg,b.brandName,gcb.catId') + ->where('gc.dataFlag=1 and gc.isShow=1') + ->where($where) + ->limit($num) + ->select(); + } + cache('TAG_BRANDS_'.$catId,$brands,$cache); + return $brands; + } + + /** + * 获取分类下的店铺 + */ + public function listShop($catId,$num,$cache = 0){ + $cacheData = cache('TAG_SHOPS_'.$catId); + if($cacheData)return $cacheData; + $where = []; + $where['r.dataSrc'] = 1; + $where['b.dataFlag'] = 1; + $where['b.applyStatus'] = 2; + $where['r.dataType'] = 0; + $where['r.goodsCatId'] = $catId; + $shops = Db::name('shops')->alias('b')->join('__RECOMMENDS__ r','b.shopId=r.dataId') + ->where($where)->field('b.shopId,b.shopImg,b.shopName,r.goodsCatId catId') + ->order('r.dataSort asc')->limit($num)->select(); + //为空的话就取分类关联的 + if(empty($shops)){ + $shops = Db::name('goods_cats')->alias('gc') + ->join('__CAT_SHOPS__ gcb','gc.catId=gcb.catId','inner') + ->join('__SHOPS__ b','gcb.shopId=b.shopId and b.shopStatus=1 and b.dataFlag=1','inner') + ->field('b.shopId,b.shopImg,b.shopName,gcb.catId') + ->where('gc.dataFlag=1 and gc.isShow=1 and b.applyStatus=2 and gc.catId='.$catId) + ->limit($num) + ->select(); + } + cache('TAG_SHOPS_'.$catId,$shops,$cache); + return $shops; + } + + /** + * 获取订单列表 + */ + public function listOrder($type,$num,$cache,$fields = ''){ + if(!in_array($type,['user','shop']))return []; + $ownId = (int)($type=='user')?session('WST_USER.userId'):session('WST_USER.shopId'); + if($ownId==0)return []; + if($fields=='')$fields = 'orderId,orderNo,createTime,orderStatus,payType,deliverType,userName,realTotalMoney'; + $data = cache('TAG_ORDER_'.$type."_".$ownId); + if(!$data){ + $where = ''; + if($type=='user')$where = 'userId='.$ownId; + if($type=='shop')$where = 'shopId='.$ownId; + $db = Db::name('orders')->where($where)->limit($num)->order('createTime desc'); + if($fields!='')$db->field($fields); + $data =$db->select(); + if(!empty($data)){ + $ids = []; + foreach ($data as $key => $v) { + $ids[] = $v['orderId']; + } + $goods = Db::name('order_goods')->where('orderId in ('.implode(',',$ids).')')->order('id asc')->select(); + $goodsMap = []; + foreach($goods as $g){ + $goodsMap[$g['orderId']][] = $g; + } + foreach ($data as $key => $v) { + $data[$key]['goods'] = $goodsMap[$v['orderId']]; + } + } + cache('TAG_ORDER_'.$type."_".$ownId,$data,$cache); + } + return $data; + } + + /** + * 获取收藏商品/商家列表 + */ + public function listFavorite($type,$num,$fields = ''){ + if(!in_array($type,['goods','shop']))return []; + $userId = (int)session('WST_USER.userId'); + if($userId==0)return []; + $where = 'userId='.$userId; + $db = Db::name('favorites')->alias('f'); + if($type=='goods'){ + $db->join('__GOODS__ g','f.favoriteType=0 and f.targetId=g.goodsId and g.dataFlag=1 '); + if($fields=='')$fields = 'g.goodsId,g.goodsName,g.goodsImg,g.isSale,g.shopPrice'; + $db->field($fields); + }else{ + $db->join('__SHOPS__ s','f.favoriteType=1 and f.targetId=s.shopId and s.dataFlag=1 and s.shopStatus=1'); + if($fields=='')$fields = 's.shopName,s.shopId,s.shopImg'; + $db->field($fields); + } + $db->limit($num)->where($where); + $db->order('favoriteId desc'); + $data = $db->select(); + return $data; + } + + /** + * 获取搜索关键词 + */ + public function listSearchkey($type,$cache = 0){ + $cacheData = cache('TAG_SEARCHKEY_'.$type); + if($cacheData)return $cacheData; + $keys = WSTConf("CONF.hotWordsSearch"); + if($keys!=''){ + $keys = explode(',',$keys); + if($type==1){ + foreach ($keys as $key => $v){ + $keys[$key] = []; + $keys[$key]['name'] = $v; + $where = []; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $where['goodsName'] = ['like','%'.$v.'%']; + $keys[$key]['count'] = Db::name('goods')->where($where)->count(); + } + } + } + cache('TAG_SEARCHKEY_'.$type,$keys,$cache); + return $keys; + } + + /** + * 获取高评分商品 + */ + public function listScore($catId,$num,$cache = 0){ + $cacheData = cache('TAG_SCORE_'.$catId); + if($cacheData)return $cacheData; + $scores = WSTConf("CONF.hotWordsSearch"); + if($scores!=''){ + $where = []; + $where['serviceScore'] = ['>=',4]; + $where['g.dataFlag'] = 1; + $where['ga.dataFlag'] = 1; + $where['goodsScore'] = ['>=',4]; + $where['timeScore'] = ['>=',4]; + if($catId>0)$where['g.goodsCatIdPath'] = ['like',$catId."_%"]; + $scores = Db::name('goods')->alias('g') + ->field('g.goodsId,g.goodsImg,g.goodsName,g.shopPrice,ga.content,u.loginName,u.userName') + ->join('__GOODS_APPRAISES__ ga','g.goodsId=ga.goodsId','inner') + ->join('__USERS__ u','u.userId=ga.userId','inner') + ->where($where) + ->order('ga.createTime desc') + ->limit($num) + ->select(); + } + cache('TAG_SCORE_'.$catId,$scores,$cache); + return $scores; + } +} diff --git a/hyhproject/common/model/UserAddress.php b/hyhproject/common/model/UserAddress.php new file mode 100755 index 0000000..24c250a --- /dev/null +++ b/hyhproject/common/model/UserAddress.php @@ -0,0 +1,184 @@ +<?php +namespace wstmart\common\model; +/** + * ============================================================================ + * 用户地址 + */ +use think\Db; +class UserAddress extends Base{ + /** + * 获取列表 + */ + public function listQuery($userId){ + $where = ['userId'=>(int)$userId,'dataFlag'=>1]; + $rs = $this->order('isDefault desc, addressId desc')->where($where)->select(); + $areaIds = []; + $areaMaps = []; + foreach ($rs as $key => $v){ + $tmp = explode('_',$v['areaIdPath']); + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + $rs[$key]['areaId2'] = $tmp[1]; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName']; + } + foreach ($rs as $key => $v){ + $tmp = explode('_',$v['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue; + $areaNames[] = $areaMaps[$vv]; + } + $rs[$key]['areaName'] = implode('',$areaNames); + $rs[$key]['areaName1'] = $areaMaps[$v['areaId2']]; + } + } + return $rs; + } + /** + * 获取用户信息 + */ + public function getById($id, $uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $rs = $this->get(['addressId'=>$id,'userId'=>$userId,'dataFlag'=>1]); + if(empty($rs))return []; + $areaIds = []; + $areaMaps = []; + $tmp = explode('_',$rs['areaIdPath']); + $rs['areaId2'] = $tmp[1]; + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName']; + } + $tmp = explode('_',$rs['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue; + $areaNames[] = $areaMaps[$vv]; + $rs['areaName'] = implode('',$areaNames); + } + } + return $rs; + } + /** + * 新增 + */ + public function add($uId=0){ + $data = input('post.'); + unset($data['addressId']); + $data['userId'] = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $data['createTime'] = date('Y-m-d H:i:s'); + if($data['userId']==0)return WSTReturn('新增失败,请先登录'); + // 检测是否存在下级地区 + $hasChild = model('Areas')->hasChild(input('areaId')); + if($hasChild)return WSTReturn('请选择完整的地区信息',-1); + + $areaIds = model('Areas')->getParentIs((int)input('areaId')); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + $result = $this->validate('UserAddress.add')->allowField(true)->save($data); + if(false !== $result){ + //修改默认地址 + if((int)input('post.isDefault')==1){ + $this->where("addressId != $this->addressId and userId=".$data['userId'])->setField('isDefault',0); + } + return WSTReturn("新增成功", 1,['addressId'=>$this->addressId]); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 编辑资料 + */ + public function edit($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = (int)input('post.addressId'); + $data = input('post.'); + // 检测是否存在下级地区 + $hasChild = model('Areas')->hasChild(input('areaId')); + if($hasChild)return WSTReturn('请选择完整的地区信息',-1); + + $areaIds = model('Areas')->getParentIs((int)input('areaId')); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + $result = $this->validate('UserAddress.edit')->allowField(true)->save($data,['addressId'=>$id,'userId'=>$userId]); + //修改默认地址 + if((int)input('post.isDefault')==1) + $this->where("addressId != $id and userId=".$userId)->setField('isDefault',0); + if(false !== $result){ + //dump($result); + return WSTReturn("编辑成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 删除 + */ + public function del($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + $result = $this->update($data,['addressId'=>$id,'userId'=>$userId]); + if(false !== $result){ + return WSTReturn("删除成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + + /** + * 设置为默认地址 + */ + public function setDefault($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $id = (int)input('post.id'); + $this->where(["addressId"=>['<>',$id],'userId'=>$userId] )->setField('isDefault',0); + $rs = $this->where("addressId = $id and userId=".$userId)->setField('isDefault',1); + if(false !== $rs){ + return WSTReturn("设置成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取默认地址 + */ + public function getDefaultAddress($uId=0){ + $userId = ((int)$uId==0)?(int)session('WST_USER.userId'):$uId; + $where = ['userId'=>$userId,'dataFlag'=>1]; + $rs = $this->where($where)->order('isDefault desc,addressId desc')->find(); + if(empty($rs))return []; + $areaIds = []; + $areaMaps = []; + $tmp = explode('_',$rs['areaIdPath']); + $rs['areaId2'] = $tmp[1]; + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName']; + } + $tmp = explode('_',$rs['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue; + $areaNames[] = $areaMaps[$vv]; + $rs['areaName'] = implode('',$areaNames); + } + } + return $rs; + } +} diff --git a/hyhproject/common/model/UserReward.php b/hyhproject/common/model/UserReward.php new file mode 100755 index 0000000..820e43a --- /dev/null +++ b/hyhproject/common/model/UserReward.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\common\model; +/** + * + */ +class UserReward extends Base{ + public function getRewardList($where,$field='*'){ + return $this->where($where)->select(); + } + public function getRewardInfo($where,$field='*'){ + return $this->where($where)->find(); + } + public function addReward($data){ + $data['createTime'] = time(); + return $this->insert($data); + } +} diff --git a/hyhproject/common/model/UserScores.php b/hyhproject/common/model/UserScores.php new file mode 100755 index 0000000..9989ff1 --- /dev/null +++ b/hyhproject/common/model/UserScores.php @@ -0,0 +1,81 @@ +<?php +namespace wstmart\common\model; +use Think\Db; +/** + * ============================================================================ + * 惠宝业务处理器 + */ +class UserScores extends Base{ + /** + * 获取列表 + */ + public function pageQuery($userId){ + $type = (int)input('post.type'); + $where = ['userId'=>(int)$userId]; + if($type!=-1)$where['scoreType'] = $type; + $page = $this->where($where)->order('scoreId desc')->paginate()->toArray(); + foreach ($page['Rows'] as $key => $v){ + $page['Rows'][$key]['dataSrc'] = WSTLangScore($v['dataSrc']); + } + return $page; + } + + /** + * 新增记录 + */ + public function add($score,$isAddTotal = false){ + $score['createTime'] = date('Y-m-d H:i:s'); + $this->create($score); + $user = model('common/users')->get($score['userId']); + if($score['scoreType']==1){//收入 + $user->userScore = $user->userScore + $score['score']; + if($isAddTotal)$user->userTotalScore = $user->userTotalScore+$score['score']; + }else{ + $user->userScore = $user->userScore - $score['score']; + } + $userinfo = session('WST_USER'); + $userinfo['userScore'] = $user->userScore; + session('WST_USER',$userinfo); + $user->save(); + } + + /** + *签到获得惠宝 + */ + public function signScore($userId){ + $time = date('Y-m-d'); + $frontTime = date("Y-m-d",strtotime("-1 day")); + if(WSTConf('CONF.signScoreSwitch')==0)return WSTReturn("签到失败"); + $userscores = $this->where(["userId"=>$userId,"dataSrc"=>5,])->order('createTime desc')->find(); + if(!$userscores || date("Y-m-d",strtotime($userscores['createTime']))!=$time){//没签过或最后一次签到不是今天 + $rs = Db::name('users')->where(["userId"=>$userId])->field('userScore')->find(); + $days = $score = 0; + $days = (date("Y-m-d",strtotime($userscores['createTime']))==$frontTime)?($userscores['dataId']==30)?$userscores['dataId']:$userscores['dataId']+1:1;//是昨天签到的,第30天,返回天数,不然返回天数+1,不是昨天签到的,返回第一天 + $signScore = explode(",",WSTConf('CONF.signScore'));//返回天数每天的惠宝 + if($signScore[0]!=0){ + $score = $signScore[$days-1];//天数对应的惠宝 + } + $data['totalScore'] = $rs['userScore'] + $score;//用户惠宝+签到送的分 + $data['score'] = $score; + if($score>0){ + //添加 + $userinfo = session('WST_USER'); + $userinfo['signScoreTime'] = $time; + session('WST_USER',$userinfo); + $uscore = []; + $uscore['userId'] = $userId; + $uscore['score'] = $score; + $uscore['dataSrc'] = 5; + $uscore['dataId'] = $days; + $uscore['dataRemarks'] = "连续".$days."天签到,获得惠宝".$score."个"; + $uscore['scoreType'] = 1; + $this->add($uscore,true); + return WSTReturn("签到第".$days."天,获得".$score."个惠宝",1,$data); + }else{ + return WSTReturn("签到失败"); + } + }else{ + return WSTReturn("已签到,明天再来"); + } + } +} diff --git a/hyhproject/common/model/UserTrees.php b/hyhproject/common/model/UserTrees.php new file mode 100755 index 0000000..50efb16 --- /dev/null +++ b/hyhproject/common/model/UserTrees.php @@ -0,0 +1,16 @@ +<?php +namespace wstmart\common\model; +/** + * + */ +class UserTrees extends Base{ + public function getShareNum($where){ + return $this->where($where)->count(); + } + public function getField($where,$field='pid'){ + return $this->where($where)->value($field); + } + public function getInfo($where,$field='pid'){ + return $this->where($where)->field($field)->find(); + } +} diff --git a/hyhproject/common/model/UserVouchers.php b/hyhproject/common/model/UserVouchers.php new file mode 100755 index 0000000..a2b2369 --- /dev/null +++ b/hyhproject/common/model/UserVouchers.php @@ -0,0 +1,179 @@ +<?php +namespace wstmart\common\model; +use think\Db; +/** + * ============================================================================ + * 券数据 + */ +class UserVouchers extends Base{ + public function startGiveVouchers(){ + set_time_limit(0); + $sm = Model('common/SysSummary'); + $sysData= $sm->getInfo('toPayFast,toPaySlow'); + //获取代快付值 + $toPayFast = $sysData['toPayFast']; + //今日代快付释放值 + $payFast = round($toPayFast * (dataConf('fastPayDayScale')*0.01),2); + //获取代慢付值 + $toPaySlow = $sysData['toPaySlow']; + //今日付慢付释放值 + $paySlow = round($toPaySlow * (dataConf('slowPayDayScale')*0.01),2); + //应释放总额 + $toPaySum = $payFast + $paySlow; + Db::startTrans(); + try{ + $m = Model('common/Table'); + $m->setTable('user_vouchers_summary'); + if(1 == date('j')){ + //每月损耗 + $monthScale = round((100-dataConf('couponsNextMonthInitSacle'))*0.01,2); + $giveList = $m->getList([],'id, userId, expectedProductNum, expectedCouponsNum'); + foreach ($giveList as &$g) { + if($g['expectedProductNum'] > 0){ + $decNum = $g['expectedProductNum'] * $monthScale; + $this->insertVouchersNotice($g['userId'],0,$decNum,0,$desc='预获产品券月耗损',0,1); + } + if($g['expectedCouponsNum'] > 0){ + $decNum = $g['expectedCouponsNum'] * $monthScale; + $this->insertVouchersNotice($g['userId'],0,0,$decNum,$desc='预获优惠券月耗损',0,1); + } + } + } + $where['isDisabled'] = 0; + //总预获产品券 + $allPreProduct = $m->getSum($where,'expectedProductNum'); + //总预获优惠券 + $allPreCoupons = $m->getSum($where,'expectedCouponsNum'); + //最大释放总额 预代付值 * 比例 + $maxPayNum = round(($allPreProduct + $allPreCoupons) * (dataConf('couponsMaxGiveSacle')*0.01),2); + if($toPaySum > $maxPayNum){ + //加入代慢付值 + $addPaySlow = round($toPaySum - $maxPayNum,5); + $sm->addSysSummary(0,$addPaySlow); + } + //扣减系统释放值 + $sm->addSysSummary($payFast,$paySlow,2); + //取最小值作为总释放额 + $payNum = min($maxPayNum,$toPaySum); + if($payNum==0) return; + //每人应释放数 + $personNum = $payNum / ($allPreProduct + $allPreCoupons); + //将所有未释放的的isGive设为0 + //获取今日0点时间戳 + $today = strtotime(date("Y-m-d"),time()); + $m->updateInfo('giveDate < '.$today,['isGive'=>0]); + $list = $m->getList(['isDisabled'=>0,'isGive'=>0],' + id, + userId, + expectedProductNum, + expectedCouponsNum, + alreadyProductNum, + alreadyCouponsNum, + giveDay + '); + $time = time(); + foreach ($list as &$v) { + unset($data); + $minNumer = 15; + //都小于15不统计,直接加入代慢付 + if($v['expectedProductNum'] <= $minNumer && $v['expectedCouponsNum'] <= $minNumer){ + $toSlowNum = round($personNum * ($v['expectedProductNum'] + $v['expectedCouponsNum']),2); + $sm->addSysSummary(0,$toSlowNum); + continue; + } + if($v['expectedProductNum'] < $minNumer){//预获产品券小于15; + $personAlreadyProductNum = 0; + $personAlreadyCouponsNum = round($personNum * ($v['expectedProductNum'] + $v['expectedCouponsNum']),2); + }else if($v['expectedCouponsNum'] < $minNumer){//预获优惠券小于15 + $personAlreadyCouponsNum = 0; + $personAlreadyProductNum = round($personNum * ($v['expectedProductNum'] + $v['expectedCouponsNum']),2); + }else{//都大于15 + $couponsScale = dataConf('hasCoupousScale');//优惠券比例 + $productScale = 100 - $couponsScale;//产品券比例 + $personAlreadyProductNum = $personNum * round(($v['expectedProductNum'] + $v['expectedCouponsNum']) * ($productScale*0.01),2); + $personAlreadyCouponsNum = $personNum * round(($v['expectedProductNum'] + $v['expectedCouponsNum']) * ($couponsScale*0.01),2); + } + //实际有预获产品券小于应给值 + if($v['expectedProductNum'] < $personAlreadyProductNum){ + $personAlreadyCouponsNum += $personAlreadyProductNum; + $personAlreadyProductNum = 0; + } + //实际有预获优惠券小于应给值 + if($v['expectedCouponsNum'] < $personAlreadyCouponsNum){ + $personAlreadyProductNum += $personAlreadyCouponsNum; + $personAlreadyCouponsNum = 0; + } + //都小于就算了 + if($v['expectedProductNum'] < $personAlreadyProductNum || $v['expectedCouponsNum'] < $personAlreadyCouponsNum){ + $personAlreadyProductNum = 0; + $personAlreadyCouponsNum = 0; + } + + + if($personAlreadyProductNum >= 0.01){ + + $this->insertVouchersNotice($v['userId'],0,$personAlreadyProductNum,0,$desc='分润扣减',0,0);//预获产品券减 + //加入变动记录,最后一位//1产品券2优惠券3旺旺券4现金券 + Model('common/LogMoneys')->addMoneyLog(0,$v['userId'],0,2,'预获产品券转换所得',1,$personAlreadyProductNum,'dayPay',1); + $data['alreadyProductNum'] = $v['alreadyProductNum'] + $personAlreadyProductNum;//已获产品券加 + } + if($personAlreadyCouponsNum >= 0.01){ + $this->insertVouchersNotice($v['userId'],0,0,$personAlreadyCouponsNum,$desc='分润扣减',0,0);//预获优惠券减 + //加入变动记录,最后一位//1产品券2优惠券3旺旺券4现金券 + Model('common/LogMoneys')->addMoneyLog(0,$v['userId'],0,2,'预获优惠券转换所得',1,$personAlreadyCouponsNum,'dayPay',2); + $data['alreadyCouponsNum'] = $v['alreadyCouponsNum'] + $personAlreadyCouponsNum;//已获优惠券加 + } + $data['isGive'] = 1; + $data['giveDate'] = $time; + $data['giveDay'] = $v['giveDay'] + 1; + $m->updateInfo(['id'=>$v['id']],$data); + } + Db::commit(); + return WSTReturn("ok", 1); + }catch (\Exception $e) { + dump($e); + Db::rollback();errLog($e); + return WSTReturn($e->getMessage(),-1); + } + } + /** + * 插入会员券值记录 + * @param [type] $userId [会员ID] + * @param [type] $orderId [订单ID] + * @param integer $expectedProductNum [预获产品券] + * @param integer $expectedCouponsNum [预获优惠券] + * @param string $desc [备注] + * @param string $isAdd [1增加0扣除] + * @return [type] [description] + */ + public function insertVouchersNotice($userId,$orderId,$expectedProductNum=0,$expectedCouponsNum=0,$desc='',$isAdd=1,$isShow=1){ + //插入详细表 + $m = Model('common/Table'); + $m->setTable('user_vouchers_notice'); + $m->insertInfo(['userId'=>$userId,'orderId'=>$orderId,'expectedProductNum'=>$expectedProductNum,'expectedCouponsNum'=>$expectedCouponsNum,'remark'=>$desc,'moneyType'=>$isAdd,'isShow'=>$isShow,'createTime'=>time()]); + //插入或更新详细表 + $m->setTable('user_vouchers_summary'); + if($summaryInfo = $m->getInfo(['userId'=>$userId],'id,expectedProductNum,expectedCouponsNum')){ + if(1 == $isAdd){ + $data['expectedProductNum'] = $summaryInfo['expectedProductNum'] + $expectedProductNum; + $data['expectedCouponsNum'] = $summaryInfo['expectedCouponsNum'] + $expectedCouponsNum; + }else{ + $data['expectedProductNum'] = $summaryInfo['expectedProductNum'] - $expectedProductNum; + $data['expectedCouponsNum'] = $summaryInfo['expectedCouponsNum'] - $expectedCouponsNum; + } + $m->updateInfo(['id'=>$summaryInfo['id']],$data); + }else{ + if(0 == $isAdd){ + $expectedProductNum *= -1; + $expectedCouponsNum *= -1; + } + $data = compact('userId','expectedProductNum','expectedCouponsNum'); + $data['alreadyProductNum'] = 0; + $data['alreadyCouponsNum'] = 0; + $data['isGive'] = 1; + $data['giveDate'] = time(); + $data['giveDay'] = 0; + $m->insertInfo($data); + } + } +} diff --git a/hyhproject/common/model/Users.php b/hyhproject/common/model/Users.php new file mode 100755 index 0000000..edf202f --- /dev/null +++ b/hyhproject/common/model/Users.php @@ -0,0 +1,834 @@ +<?php +namespace wstmart\common\model; +use Think\Db; +/** + * ============================================================================ + * 用户类 + */ +class Users extends Base{ + /** + * 我家朋友 + */ + public function myFriend($userId){ + $rs = []; + $pid = Db::name('user_trees')->where(['uid'=>$userId])->value('pid'); + $rs['pInfo'] = ''; + if($pid){ + $pInfo = getUserInfo(['userId'=>$pid],'trueName,userPhone,userLevel,userStatus'); + if($pInfo) + $rs['pInfo'] = ['trueName'=>$pInfo['trueName'],'userPhone'=>$pInfo['userPhone'],'userLevel'=>$this->getUserLevelName($pInfo['userLevel']),'userStatus'=>$this->getUserStatusName($pInfo['userStatus'])]; + } + $rs['lockUserCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>0]) + ->count(); + $rs['userCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>1,'u.userLevel'=>0]) + ->count(); + + $rs['shopCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>1,'u.userLevel'=>1]) + ->count(); + $rs['storeCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>1,'u.userLevel'=>2]) + ->count(); + $rs['mallCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>1,'u.userLevel'=>3]) + ->count(); + $rs['marketCount'] = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.dataFlag'=>1,'u.userStatus'=>1,'u.userLevel'=>4]) + ->count(); + return $rs; + } + /** + * 分配券值 + * @return [type] [description] + */ + public function distributionInvestmentMoney(){ + $data = input('post.'); + $userId = $data['userId']; + $type = (int)$data['type']; + $typeName = ['1'=>'productNum','2'=>'couponsNum']; + if(array_key_exists($type, $typeName)){ + $m = Model('common/Table'); + $m->setTable('users'); + $info = $m->getInfo(['userId'=>$userId],$typeName[$type].',payPwd'); + if(md5($data['payPwd']) != $info['payPwd']){ + exit(jsonReturn('操作密码错误')); + } + if($data['num'] < 15){ + exit(jsonReturn('分配券值数量最低15')); + } + if($data['num'] > $info[$typeName[$type]]){ + exit(jsonReturn('超出最大可分配数量,最多可分配:'.$info[$typeName[$type]])); + } + Db::startTrans(); + try{ + // $isDec = $m->decNum(['userId'=>$userId],$typeName[$type],$data['num']); + // if($isDec){ + $m->setTable('auth_company_partner'); + $list = $m->getList(['userId'=>$userId,'dataFlag'=>1],'partnerId,stake'); + $allNum = 0; + foreach ($list as &$v) { + $num = $data['num']*($v['stake']*0.01); + $allNum += $num; + Model('common/LogMoneys')->addMoneyLog(0,$v['partnerId'],0,2,'合作分配',1,$num,'invPay',$type); + } + Model('common/LogMoneys')->addMoneyLog(0,$userId,0,2,'合作分配',0,$allNum,'invPay',$type); + Db::commit(); + exit(jsonReturn('操作成功',1)); + //} + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + exit(jsonReturn('操作超时,请重试')); + } + + } + /** + * 我家朋友 + */ + public function myFriendList($userId){ + $userLevel = (int)input('post.userLevel/d'); + $isLock = (int)input('post.isLock/d'); + $rs = []; + if($isLock){ + $rs = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->join('user_lock l','u.userId=l.userId') + ->where(['t.pid'=>$userId,'u.userStatus'=>0,'u.userLevel'=>$userLevel]) + ->field('u.userId,u.trueName,u.userPhone,u.userLevel,l.lockReason,l.lockTime,from_unixtime(l.createTime) createTime') + ->order('l.id DESC,u.userId DESC') + ->paginate(input('pageSize/d'))->toArray(); + }else{ + $rs = Db::name('users u') + ->join('user_trees t','u.userId=t.uid') + ->where(['t.pid'=>$userId,'u.userStatus'=>1,'u.userLevel'=>$userLevel]) + ->field('u.userId,u.trueName,u.userPhone,u.userLevel,u.createTime') + ->order('u.userId DESC') + ->paginate(input('pageSize/d'))->toArray(); + } + return $rs; + } + public function getHTTPS($url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_REFERER, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $result = curl_exec($ch); + curl_close($ch); + return $result; + } + /** + * 用户登录验证 + */ + public function checkLogin($loginSrc = 0){ + $loginName = input("post.loginName"); + $loginPwd = input("post.loginPwd"); + $code = input("post.verifyCode"); + $rememberPwd = input("post.rememberPwd",1); + // if(WSTVisitModule() == 'home'){//pc版的有验证码 mark 20170914 + // if(!WSTVerifyCheck($code) && strpos(WSTConf("CONF.captcha_model"),"4")>=0){ + // return WSTReturn('验证码错误!'); + // } + // } + if(strlen($loginName) < 3 || strlen($loginPwd) < 3){ + return WSTReturn('请输入用户名和密码!'); + } + $ip = request()->ip(); + if($loginSrc ==3 ){ + $ticket = input('post.ticket'); + $randstr = input('post.randstr'); + if($ticket && $randstr){ + try{ + $url='https://ssl.captcha.qq.com/ticket/verify?aid=2089606583&AppSecretKey=02pqzvc15HUGyhYTAck38HQ**&Ticket='.$ticket.'&Randstr='.$randstr.'&UserIP='.$ip; + $check_captcha = $this->getHTTPS($url); + $check_captcha = json_decode($check_captcha); + if('1' !== $check_captcha->response){ + if('fsdagsadfdsfsad3e3hg' != $ticket || 'hyjuoiyugsfae3fs887ts' != $randstr) return WSTReturn($check_captcha->err_msg); + } + } catch (\Exception $e) { + return WSTReturn($e->getMessage()); + } + }else{ + return WSTReturn('请先验证!'); + } + } + $rs = $this->where("loginName|userPhone",$loginName) + ->where(["dataFlag"=>1]) + ->find(); + if(isset($rs['userStatus']) && 0 == $rs['userStatus']){//禁用状态 + $lockInfo = Db::name('user_lock')->where(['userId'=>$rs['userId']])->field('lockReason,lockTime,createTime')->order('id DESC')->find(); + if($lockInfo){ + if(0 == $lockInfo['lockTime']){ + return WSTReturn("账号已禁用,禁用原因:".$lockInfo['lockReason'].',禁用时间:永久'); + } + $lockEndTime = $lockInfo['createTime']+($lockInfo['lockTime']*60); + if(time() >= $lockEndTime){//大于锁定时间 + $this->where(['userId'=>$rs['userId']])->update(['userStatus'=>1]); + }else{ + return WSTReturn("账号已禁用,禁用原因:".$lockInfo['lockReason'].',解禁日期:'.date('Y-m-d H:i:s',$lockEndTime)); + } + }else{ + return WSTReturn('账号已禁用,禁用原因:未知,禁用时间:永久'); + } + } + //hook("beforeUserLogin",["user"=>&$rs]); + /** + * 添加整合登录插件 mark 20170829 + */ + // if(empty($rs)){ + // hook("beforeUserLogin",["user"=>&$rs]); + // } + /** + * end + */ + + if(!empty($rs)){ + if($rs['loginPwd']!=md5($loginPwd.$rs['loginSecret']))return WSTReturn("密码错误"); + if($rs['userPhoto']=='')$rs['userPhoto'] = WSTConf('CONF.userLogo'); + $userId = $rs['userId']; + //获取用户等级 + $rrs = Db::name('user_ranks')->where(['dataFlag'=>1])->where('startScore','<=',$rs['userTotalScore'])->where('endScore','>=',$rs['userTotalScore'])->field('rankId,rankName,userrankImg')->find(); + $rs['rankId'] = $rrs['rankId']; + $rs['rankName'] = $rrs['rankName']; + $rs['userrankImg'] = $rrs['userrankImg']; + if(input("post.typ")==2){ + $shoprs=$this->where(["dataFlag"=>1, "userStatus"=>1,"userType"=>1,"userId"=>$userId])->find(); + if(empty($shoprs)){ + return WSTReturn('您还没申请店铺!'); + } + } + $update = []; + $update = ["lastTime"=>date('Y-m-d H:i:s'),"lastIP"=>$ip]; + $wxOpenId = session('WST_WX_OPENID'); + if($wxOpenId){ + $update['wxOpenId'] = $rs['wxOpenId'] = session('WST_WX_OPENID'); + // 保存unionId【若存在】 详见 unionId说明 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839 + $userinfo = session('WST_WX_USERINFO'); + $update['wxUnionId'] = isset($userinfo['unionid'])?$userinfo['unionid']:''; + } + $token=''; + if($loginSrc ==3 ){//添加token mark hsf 20180212 + $update['token'] = md5($userId.time().mt_rand(1,999)); + $token = $update['token'] ; + } + + $this->where(["userId"=>$userId])->update($update); + + //如果是店铺则加载店铺信息 + if($rs['userType']>=1){ + // $shop = Db::name("shops s") + // ->join("__SHOP_USERS__ su","s.shopId=su.shopId") + // ->field("s.*,su.roleId") + // ->where(["su.userId"=>$userId,"s.dataFlag" =>1])->find(); + // dump($shop);die; + /*---------修复商家登录不上 mark hsf 20180227 */ + $shop = Db::name("shops s") + ->join("__SHOP_USERS__ su","s.shopId=su.shopId") + ->field("s.*,su.roleId") + ->where(["su.userId"=>$userId,"s.dataFlag" =>1])->find(); + if(empty($shop)){ + $shop = Db::name("shops s") + ->field("s.*") + ->where(["s.userId"=>$userId,"s.dataFlag" =>1])->find(); + } + + if(!empty($shop))$rs = array_merge($shop,$rs->toArray()); + /*---------end-------------*/ + } + // //签到时间 + // if(WSTConf('CONF.signScoreSwitch')==1){ + // $rs['signScoreTime'] = 0; + // $userscores = Db::name('user_scores')->where(["userId"=>$userId,"dataSrc"=>5,])->order('createTime desc')->find(); + // if($userscores)$rs['signScoreTime'] = date("Y-m-d",strtotime($userscores['createTime'])); + // } + //记录登录日志 + $data = array(); + $data["userId"] = $userId; + $data["loginTime"] = date('Y-m-d H:i:s'); + $data["loginIp"] = $ip; + $data['loginSrc'] = $loginSrc; + Db::name('log_user_logins')->insert($data); + + $rd = $rs; + //记住密码 + // $t = time(); + // cookie("loginName", $loginName, $t+3600*24*90); + if($rememberPwd == "on"){ + $datakey = md5($rs['loginName'])."_".md5($rs['loginPwd']); + $key = $rs['loginSecret']; + //加密 + $base64 = new \org\Base64(); + $loginKey = $base64->encrypt($datakey, $key); + //cookie("loginPwd", $loginKey, $t+3600*24*90); + }else{ + // cookie("loginPwd", null); + } + session('WST_USER',$rs); + hook('afterUserLogin',['user'=>$rs]); + + return WSTReturn("登录成功","1",['token'=>$token]);//添加返回token mark hsf 20170212 + + } + return WSTReturn("用户名或密码错误"); + } + + /** + * 会员注册 + */ + public function regist($loginSrc = 0){ + // return WSTReturn('注册频繁'); + $data = array(); + $data['loginName'] = input("post.loginName"); + $data['loginPwd'] = input("post.loginPwd"); + $data['reUserPwd'] = $data['loginPwd'] ;//input("post.reUserPwd"); + $data['payPwd'] = input("post.payPwd"); + $data['regConfirmImg'] = input("post.regConfirmImg");//注册确认书 + $loginName = $data['loginName']; + if(!$data['regConfirmImg']){ + return WSTReturn("请上传注册确认书!"); + } + if($data['loginPwd']!=$data['reUserPwd']){ + return WSTReturn("两次输入密码不一致!"); + } + if(strlen($data['loginPwd']) < 6){ + return WSTReturn("登录密码不可小于6位!"); + } + if(strlen($data['payPwd']) < 6){ + return WSTReturn("操作密码不可小于6位!"); + } + foreach ($data as $v){ + if($v ==''){ + return WSTReturn("注册信息请填写完整!"); + } + } + $nameType = (int)input("post.nameType"); + $mobileCode = input("post.mobileCode"); + // if(WSTVisitModule() !='home'){ + // $code = input("post.verifyCode"); + // if(!WSTVerifyCheck($code)){ + // return WSTReturn("验证码错误!"); + // } + // } + $pInfo['userId']=0; + //添加验证推荐人了 mark hsf 20171129 + $pName = input('post.pName'); + //if($pName){//写推荐人了 + $pInfo = getUserByName($pName,'userId'); + if(!$pInfo){ + return WSTReturn("推荐人不存在!"); + } + //} + + $fp = fopen("reg.lock", "r"); + if(flock($fp,LOCK_EX | LOCK_NB)) {//if(flock($fp,LOCK_EX))阻塞(等待)模式 + //检测账号是否存在 + $crs = WSTCheckLoginKey($loginName); + if($crs['status']!=1){ + flock($fp,LOCK_UN); + fclose($fp); + return $crs; + } + //------end------// + // if($nameType==3 && WSTConf("CONF.smsOpen")==1){//手机号码 + //if(WSTConf("CONF.smsOpen")==1){//手机号码 + //$data['userPhone'] = $loginName; + $verify = session('VerifyCode_userPhone'); + $startTime = (int)session('VerifyCode_userPhone_Time'); + if((time()-$startTime)>120){ + flock($fp,LOCK_UN); + fclose($fp); + return WSTReturn("验证码已超过有效期!"); + } + if($mobileCode=="" || $verify != $mobileCode){ + flock($fp,LOCK_UN); + fclose($fp); + return WSTReturn("短信验证码错误!"); + } + //$loginName = WSTRandomLoginName($loginName); + // }else if($nameType==1){//邮箱注册 + // $data['userEmail'] = $loginName; + // $unames = explode("@",$loginName); + // $loginName = WSTRandomLoginName($unames[0]); + + // }else{ + // flock($fp,LOCK_UN); + // fclose($fp); + // return WSTReturn("注册失败,请重试!"); + // } + // if($loginName==''){ + // flock($fp,LOCK_UN); + // fclose($fp); + // return WSTReturn("注册失败!");//分派不了登录名 + // } + $data['loginName'] = $loginName; + unset($data['reUserPwd']); + unset($data['protocol']); + //检测账号,邮箱,手机是否存在 + $data["loginSecret"] = '';//rand(1000,9999); + $data['loginPwd'] = md5($data['loginPwd'].$data['loginSecret']); + $data['payPwd'] = md5($data['payPwd'].$data['loginSecret']); + $data['userType'] = 0; + $data['userName'] = input("post.userName"); + $data['userQQ'] = ""; + $data['userScore'] = 0; + $data['userTotalScore'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['dataFlag'] = 1; + $wxOpenId = session('WST_WX_OPENID'); + if($wxOpenId){ + $data['wxOpenId'] = session('WST_WX_OPENID'); + $userinfo = session('WST_WX_USERINFO'); + if($userinfo){ + $data['userName'] = $userinfo['nickname']; + $data['userSex'] = $userinfo['sex']; + $data['userPhoto'] = $userinfo['headimgurl']; + // 保存unionId【若存在】 详见 unionId说明 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839 + $data['wxUnionId'] = isset($userinfo['unionid'])?$userinfo['unionid']:''; + } + } + Db::startTrans(); + try{ + $userId = $this->data($data)->save(); + if(false !== $userId){ + //保存注册信息 + $userId = $this->userId; + $logData['userId']=$userId; + $logData['loginSrc']=$loginSrc; + $logData['createTime']=time(); + $logResult = db('login_src')->insert($logData); + + $data = array(); + $ip = request()->ip(); + $data['lastTime'] = date('Y-m-d H:i:s'); + $data['lastIP'] = $ip; + $userId = $this->userId; + $this->where(["userId"=>$userId])->update($data); + //记录登录日志 + // $data = array(); + // $data["userId"] = $userId; + // $data["loginTime"] = date('Y-m-d H:i:s'); + // $data["loginIp"] = $ip; + // $data['loginSrc'] = $loginSrc; + // Db::name('log_user_logins')->insert($data); + $user = $this->get($userId); + if($user['userPhoto']=='')$user['userPhoto'] = WSTConf('CONF.userLogo'); + session('WST_USER',$user); + //注册成功后执行钩子 + hook('afterUserRegist',['user'=>$user]); + //发送消息 + $tpl = WSTMsgTemplates('USER_REGISTER'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${MALL_NAME}']; + $replace = [$user['loginName'],WSTConf('CONF.mallName')]; + WSTSendMsg($userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>0,'dataId'=>0]); + } + create_tree($userId,$pInfo['userId']); + Db::commit(); + flock($fp,LOCK_UN); + fclose($fp); + return WSTReturn("注册成功",1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + flock($fp,LOCK_UN); + fclose($fp); + } + return WSTReturn("注册失败!"); + }else{ + fclose($fp); + return WSTReturn('系统繁忙,请稍后再试'); + } + } + + /** + * 查询用户手机是否存在 + * + */ + public function checkUserPhone($userPhone,$userId = 0,$field='userId'){ + $dbo = Db::name('users')->where(["dataFlag"=>1, "userPhone"=>$userPhone]); + if($userId>0){ + $dbo->where("userId","<>",$userId); + } + $rs = $dbo->field($field)->find(); + if($rs){ + return WSTReturn("手机号已存在!",-1,$rs); + }else{ + /* 增加检测联盟手机号 mark 20170915*/ + // if(getLMUserByName($userPhone)){ + // return WSTReturn("手机号已存在!"); + // } + /* end */ + return WSTReturn("",1); + } + // $rs = $dbo->count(); + // if($rs>0){ + // return WSTReturn("手机号已存在!"); + // }else{ + // return WSTReturn("",1); + // } + } + + /** + * 修改用户密码 + */ + public function editPass($id){ + $data = array(); + $newPass = input("post.newPass"); + $decrypt_data = WSTRSA($newPass); + if($decrypt_data['status']==1){ + $newPass = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + if(!$newPass){ + return WSTReturn('密码不能为空',-1); + } + $rs = $this->where('userId='.$id)->find(); + //核对密码 + if($rs['loginPwd']){ + $oldPass = input("post.oldPass"); + $decrypt_data2 = WSTRSA($oldPass); + if($decrypt_data2['status']==1){ + $oldPass = $decrypt_data2['data']; + }else{ + return WSTReturn('修改失败'); + } + if($rs['loginPwd']==md5($oldPass.$rs['loginSecret'])){ + $data["loginPwd"] = md5($newPass.$rs['loginSecret']); + $rs = $this->update($data,['userId'=>$id]); + if(false !== $rs){ + hook("afterEditPass",["userId"=>$id]); + return WSTReturn("密码修改成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + }else{ + return WSTReturn('原始密码错误',-1); + } + }else{ + $data["loginPwd"] = md5($newPass.$rs['loginSecret']); + $rs = $this->update($data,['userId'=>$id]); + if(false !== $rs){ + hook("afterEditPass",["userId"=>$id]); + return WSTReturn("密码修改成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + } + /** + * 修改用户支付密码 + */ + public function editPayPass($id){ + $data = array(); + $newPass = input("post.newPass"); + //添加二次密码验证 mark hsf 20180321 + $reNewPass = input("post.reNewPass"); + if($newPass != $reNewPass){ + return WSTReturn('二次密码输入不一致,请重新输入!',-1); + } + //end + $decrypt_data = WSTRSA($newPass); + if($decrypt_data['status']==1){ + $newPass = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + if(!$newPass){ + return WSTReturn('支付密码不能为空',-1); + } + $rs = $this->where('userId='.$id)->find(); + //核对密码 + if($rs['payPwd']){ + $oldPass = input("post.oldPass"); + $decrypt_data2 = WSTRSA($oldPass); + if($decrypt_data2['status']==1){ + $oldPass = $decrypt_data2['data']; + }else{ + return WSTReturn('修改失败'); + } + if($rs['payPwd']==md5($oldPass.$rs['loginSecret'])){ + $data["payPwd"] = md5($newPass.$rs['loginSecret']); + $rs = $this->update($data,['userId'=>$id]); + if(false !== $rs){ + return WSTReturn("支付密码修改成功", 1); + }else{ + return WSTReturn("支付密码修改失败",-1); + } + }else{ + return WSTReturn('原始支付密码错误',-1); + } + }else{ + $data["payPwd"] = md5($newPass.$rs['loginSecret']); + $rs = $this->update($data,['userId'=>$id]); + if(false !== $rs){ + return WSTReturn("支付密码设置成功", 1); + }else{ + return WSTReturn("支付密码修改失败",-1); + } + } + } + /** + * 重置用户支付密码 + */ + public function resetbackPay($uId=0){ + $timeVerify = session('Verify_backPaypwd_Time'); + if(time()>floatval($timeVerify)+10*60){ + session('Type_backPaypwd',null); + return WSTReturn("校验码已失效,请重新验证!"); + exit(); + } + $data = array(); + $data["payPwd"] = input("post.newPass"); + $decrypt_data = WSTRSA($data["payPwd"]); + if($decrypt_data['status']==1){ + $data["payPwd"] = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + if(!$data["payPwd"]){ + return WSTReturn('支付密码不能为空',-1); + } + $userId = ($uId==0)?(int)session('WST_USER.userId'):$uId; + $rs = $this->where('userId='.$userId)->find(); + $data["payPwd"] = md5($data["payPwd"].$rs['loginSecret']); + $rs = $this->update($data,['userId'=>$userId]); + if(false !== $rs){ + session('Type_backPaypwd',null); + session('Verify_backPaypwd_info',null); + session('Verify_backPaypwd_Time',null); + return WSTReturn("支付密码设置成功", 1); + }else{ + return WSTReturn("支付密码修改失败",-1); + } + } + /** + * 获取用户信息 + */ + public function getById($id){ + $rs = $this->get(['userId'=>(int)$id]); + $rs['ranks'] = WSTUserRank($rs['userTotalScore']); + return $rs; + } + /** + * 编辑资料 + */ + public function edit(){ + $Id = (int)session('WST_USER.userId'); + $data = input('post.'); + if(isset($data['brithday']))$data['brithday'] = ($data['brithday']=='')?date('Y-m-d'):$data['brithday']; + WSTAllow($data,'brithday,trueName,userName,userId,userPhoto,userQQ,userSex'); + Db::startTrans(); + try{ + if(isset($data['userPhoto']) && $data['userPhoto']!='') + WSTUseImages(0, $Id, $data['userPhoto'],'users','userPhoto'); + + $result = $this->allowField(true)->save($data,['userId'=>$Id]); + if(false !== $result){ + Db::commit(); + return WSTReturn("编辑成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('编辑失败',-1); + } + } + /** + * 绑定邮箱 + */ + public function editEmail($userId,$userEmail){ + $data = array(); + $data["userEmail"] = $userEmail; + Db::startTrans(); + try{ + $user = Db::name('users')->where(["userId"=>$userId])->field(["userId","loginName,userEmail"])->find(); + $rs = $this->update($data,['userId'=>$userId]); + if(false !== $rs){ + hook("afterEditEmail",["user"=>$user]); + Db::commit(); + return WSTReturn("绑定成功",1); + }else{ + Db::rollback();errLog($e); + return WSTReturn("",-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('编辑失败',-1); + } + } + /** + * 绑定手机 + */ + public function editPhone($userId,$userPhone){ + $data = array(); + $data["userPhone"] = $userPhone; + $rs = $this->update($data,['userId'=>$userId]); + if(false !== $rs){ + return WSTReturn("绑定成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 查询并加载用户资料 + */ + public function checkAndGetLoginInfo($key){ + if($key=='')return array(); + $rs = $this->where(["loginName|userEmail|userPhone"=>['=',$key],'dataFlag'=>1])->find(); + return $rs; + } + /** + * 重置用户密码 + */ + public function resetPass($uId=0){ + if(time()>floatval(session('REST_Time'))+30*60){ + return WSTReturn("连接已失效!", -1); + } + $reset_userId = (int)session('REST_userId'); + if($reset_userId==0){ + return WSTReturn("无效的用户!", -1); + } + $user = $this->where(["dataFlag"=>1,"userStatus"=>1,"userId"=>$reset_userId])->find(); + if(empty($user)){ + return WSTReturn("无效的用户!", -1); + } + $loginPwd = input("post.loginPwd"); + if($uId==0){// 大于0表示来自app端 + $decrypt_data = WSTRSA($loginPwd); + if($decrypt_data['status']==1){ + $loginPwd = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + } + if(trim($loginPwd)==''){ + return WSTReturn("无效的密码!", -1); + } + $data['loginPwd'] = md5($loginPwd.$user["loginSecret"]); + $rc = $this->update($data,['userId'=>$reset_userId]); + if(false !== $rc){ + hook("afterEditPass",["userId"=>$reset_userId]);//修改密码插件 mark 20170915 + session('REST_userId',null); + session('REST_Time',null); + session('REST_success',null); + session('findPass',null); + return WSTReturn("修改成功", 1); + } + return $rs; + } + + /** + * 获取用户可用惠宝 + */ + public function getFieldsById($userId,$fields){ + return $this->where(['userId'=>$userId,'dataFlag'=>1])->field($fields)->find(); + } + /*获取用户分享列表*/ + public function getShareList(){ + $id=session('WST_USER.userId'); + //普通用户分享列表 + $userType=(int)input('userType'); + //$userType=1; + if($userType=='0'){ + $user_lists=Db::name('user_trees')->alias('a')->join('users b','b.userId=a.uid') + ->where('a.pid',$id)->where('b.userType','0')->field('b.userId,b.loginName,b.createTime,b.userPhoto')->order('userId DESC') + ->paginate(input('pagesize/d'))->toArray(); + if(empty($user_lists)){ + exit(jsonReturn('暂无分享用户',0)); + }else{ + foreach ($user_lists['Rows'] as &$v) { + if(!Db::name('log_user_logins')->where(['userId'=>$v['userId'],'loginSrc'=>3])->field('userId')->find()){ + $v['isLogin'] = 0; + }else{ + $v['isLogin'] = 1; + } + } + exit(json_encode($user_lists)); + } + + }elseif ($userType=='1') { + $merchants_lists=Db::name('user_trees')->alias('a')->join('users b','b.userId=a.uid') + ->where('a.pid',$id)->where('b.userType','1')->field('b.userId,b.loginName,b.createTime,b.userPhoto')->order('userId DESC') + ->paginate(input('pagesize/d'))->toArray(); + + if(empty($merchants_lists)){ + exit(jsonReturn('暂无分享商家',0)); + }else{ + foreach ($merchants_lists['Rows'] as &$v) { + if(!Db::name('log_user_logins')->where(['userId'=>$v['userId'],'loginSrc'=>3])->field('userId')->find()){ + $v['isLogin'] = 0; + }else{ + $v['isLogin'] = 1; + } + } + exit(json_encode($merchants_lists)); + } + }else{ + exit(jsonReturn('请输入有效类型!',-1)); + } + } + /*获取用户分享信息*/ + public function getShareInfo(){ + $userId=session('WST_USER.userId'); + //普通用户分享列表 + $userType=(int)input('userType'); + if(in_array($userType, [0,1])){ + $sid=(int)input('sid'); + $data['ect']=Db::name('user_reward')->alias('r') + ->join('__ORDERS__ o','o.orderId=r.orderId') + ->where(['r.userId'=>$userId,'r.sid'=>$sid,'r.isSeller'=>$userType,'r.payType'=>1]) + // ->group('r.orderId') + ->field('SUM(o.realTotalMoney) order_num,SUM(r.rewardNum) reward_num') + ->find(); + $data['money']=Db::name('user_reward')->alias('r') + ->join('__ORDERS__ o','o.orderId=r.orderId') + ->where(['r.userId'=>$userId,'r.sid'=>$sid,'r.isSeller'=>$userType,'r.payType'=>2]) + // ->group('r.orderId') + ->field('SUM(o.realTotalMoney) order_num,SUM(r.rewardNum) reward_num') + ->find(); + exit(json_encode($data)); + }else{ + exit(jsonReturn('请输入有效类型!',-1)); + } + } + function getUserStatusName($userStatus){ + $statusName = '禁用'; + switch($userStatus){ + case 1: + $statusName = '正常'; + break; + } + return $statusName; + } + function getUserLevelName($userLevel){ + $levelName = '普通用户'; + switch($userLevel){ + case 1: + $levelName = '商户'; + break; + case 2: + $levelName = '商超'; + break; + case 3: + $levelName = '商厦'; + break; + case 4: + $levelName = '商都'; + break; + } + return $levelName; + } + function addUserVouchersSummary($expectedProductNum,$expectedCouponsNum){ + + } +} diff --git a/hyhproject/common/taglib/Wst.php b/hyhproject/common/taglib/Wst.php new file mode 100755 index 0000000..d8bf661 --- /dev/null +++ b/hyhproject/common/taglib/Wst.php @@ -0,0 +1,393 @@ +<?php +/** + * ============================================================================ + */ +namespace wstmart\common\taglib; +use think\template\TagLib; +class Wst extends TagLib{ + /** + * 定义标签列表 + */ + protected $tags = [ + 'friendlink' => ['attr' => 'num,key,id,cache'], + 'ads' => ['attr' => 'code,num,key,id,cache'], + 'article' => ['attr' => 'cat,num,key,id,cache'], + 'goods' => ['attr' => 'type,cat,num,key,id,cache'], + 'brand' => ['attr' => 'cat,num,key,id,cache'], + 'shop' => ['attr' => 'cat,num,key,id,cache'], + 'shopgoods' => ['attr' => 'type,shop,num,key,id,cache'], + 'shopfloorgoods' => ['attr' => 'cat,shop,num,key,id,cache'], + 'table'=>['table','where','num','order','field','id','key'], + 'order' =>['attr'=>'type,num,key,id,cache,field'], + 'favorite' =>['attr'=>'type,num,key,id,cache,field'], + 'searchkey' => ['attr' => 'type,key,id,cache'], + 'score' => ['attr'=>'cat,num,key,id,cache'] + ]; + /** + * 单表查询操作标签 + * table:表名 + * where:查询条件 + * num:limit + * order:排序条件 + * field:需要取哪些字段 + * key:序号 + * id:循环中定义的元素变量 + * {wst:table table="goods" field="goodsId,goodsName" num='6'}{/wst:table} + */ + public function tagTable($tag, $content){ + $table = $tag['table']; + $where = isset($tag['where'])?$tag['where']:'0'; + $order = isset($tag['order'])?$tag['order']:'0'; + $field = isset($tag['field'])?$tag['field']:'*'; + /*$catId = isset($tag['cat'])?$tag['cat']:0; + $flag = substr($catId, 0, 1); + if (':' == $flag) { + $catId = $this->autoBuildVar($catId); + $parseStr .= '$_result=' . $catId . ';'; + $catId = '$_result'; + } else { + $catId = $this->autoBuildVar($catId); + }*/ + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:0; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagGoods = model("common/Tags")->wstDb("'.$table.'","'.$where.'","'.$order.'","'.$field.'",'.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagGoods as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 商品数据调用 + * type:推荐/新品/热销/精品/浏览历史/看了又看 - recom/new/hot/best/history/visit + * cat:商品分类 + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:goods type='hot' cat='1' num='6'}{/wst:goods} + */ + public function tagGoods($tag, $content){ + $type = $tag['type']; + $catId = isset($tag['cat'])?$tag['cat']:0; + $flag = substr($catId, 0, 1); + if (':' == $flag) { + $catId = $this->autoBuildVar($catId); + $parseStr .= '$_result=' . $catId . ';'; + $catId = '$_result'; + } else { + $catId = $this->autoBuildVar($catId); + } + + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:0; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagGoods = model("common/Tags")->listGoods("'.$type.'",'.$catId.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagGoods as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + /** + * 广告数据调用 + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:friendlink num='6'}{/wst:ads} + */ + public function tagFriendlink($tag, $content){ + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagFriendlink = model("common/Tags")->listFriendlink('.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagFriendlink as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 广告数据调用 + * code:广告代码 + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:ads code='1' cat='1' num='6'}{/wst:ads} + */ + public function tagAds($tag, $content){ + $code = $tag['code']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagAds = model("common/Tags")->listAds("'.$code.'",'.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagAds as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 文章数据调用 + * cat:文章分类ID 或者 'new' + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:article cat='1' num='6'}{/wst:article} + */ + public function tagArticle($tag, $content){ + $cat = $tag['cat']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagArticle = model("common/Tags")->listArticle("'.$cat.'",'.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagArticle as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 店铺商品数据调用 + * type:推荐/新品/热销/精品 - recom/new/hot/best + * shop:店铺ID + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:shopgoods name='hot' cat='1' num='6'}{/wst:goods} + */ + public function tagShopGoods($tag, $content){ + $type = $tag['type']; + $shopId = isset($tag['shop'])?$tag['shop']:0; + $flag = substr($shopId, 0, 1); + if (':' == $flag) { + $shopId = $this->autoBuildVar($shopId); + $parseStr .= '$_result=' . $shopId . ';'; + $shopId = '$_result'; + } else { + $shopId = $this->autoBuildVar($shopId); + } + + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:0; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagShopGoods = model("common/Tags")->listShopGoods("'.$type.'",'.$shopId.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagShopGoods as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + + } + + /** + * 自营店铺楼层商品数据调用 + * shop:店铺ID + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:shopfloorgoods cat='1' num='6'}{/wst:shopfloorgoods} + */ + public function tagShopFloorGoods($tag, $content){ + $catId = isset($tag['cat'])?$tag['cat']:0; + $flag = substr($catId, 0, 1); + if (':' == $flag) { + $catId = $this->autoBuildVar($catId); + $parseStr .= '$_result=' . $catId . ';'; + $catId = '$_result'; + } else { + $catId = $this->autoBuildVar($catId); + } + + + $shopId = isset($tag['shop'])?$tag['shop']:0; + $flag = substr($shopId, 0, 1); + if (':' == $flag) { + $shopId = $this->autoBuildVar($shopId); + $parseStr .= '$_result=' . $shopId . ';'; + $shopId = '$_result'; + } else { + $shopId = $this->autoBuildVar($shopId); + } + + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:0; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagShopFloorGoods = model("common/Tags")->listShopFloorGoods('.$catId.','.$shopId.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagShopFloorGoods as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + + } + + /** + * 品牌数据调用 + * cat:分类ID + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:brand cat='1' num='6'}{/wst:brand} + */ + public function tagBrand($tag, $content){ + $cat = $tag['cat']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagBrand = model("common/Tags")->listBrand('.$cat.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagBrand as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 店铺数据调用 + * cat:分类ID + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:shop cat='1' num='6'}{/wst:shop} + */ + public function tagShop($tag, $content){ + $cat = $tag['cat']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagShop = model("common/Tags")->listShop('.$cat.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagShop as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 订单数据调用 + * type:订单访问者类型,可选值为user或者shop + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + *fields:需要读取的订单字段 + * {wst:order type='user' ownId='1' num='6'}{/wst:order} + */ + public function tagOrder($tag, $content){ + $type = isset($tag['type'])?$tag['type']:''; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $fields = isset($tag['field'])?$tag['field']:''; + $parse = '<?php '; + $parse .= '$wstTagOrder = model("common/Tags")->listOrder("'.$type.'",'.$num.','.$cache.',"'.$fields.'"); '; + $parse .= 'foreach($wstTagOrder as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 搜索关键词数据调用 + * type:0只获取关键词,1获取关键词和搜索关键词的搜索数 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:searchkey type='0' num='6'}{/wst:searchkey} + */ + public function tagSearchkey($tag, $content){ + $type = $tag['type']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagSearchkey = model("common/Tags")->listSearchkey('.$type.','.$cache.'); '; + $parse .= 'foreach($wstTagSearchkey as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 收藏商品/商家数据调用 + * type:收藏类型,可选值为goods或者shop + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + *fields:需要读取的记录字段 + * {wst:favorite type='user' ownId='1' num='6'}{/wst:order} + */ + public function tagFavorite($tag, $content){ + $type = isset($tag['type'])?$tag['type']:''; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $key = isset($tag['key'])?$tag['key']:'key'; + $fields = isset($tag['field'])?$tag['field']:''; + $parse = '<?php '; + $parse .= '$wstTagFavorite = model("common/Tags")->listFavorite("'.$type.'",'.$num.',"'.$fields.'"); '; + $parse .= 'foreach($wstTagFavorite as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } + + /** + * 高评分商品数据调用 + * cat:分类ID + * num:获取记录数量 + * cache:缓存时间 + * key:序号 + * id:循环中定义的元素变量 + * {wst:score type='0' num='6'}{/wst:score} + */ + public function tagScore($tag, $content){ + $cat = $tag['cat']; + $id = isset($tag['id'])?$tag['id']:'vo'; + $num = isset($tag['num'])?(int)$tag['num']:99; + $cache = isset($tag['cache'])?$tag['cache']:0; + $key = isset($tag['key'])?$tag['key']:'key'; + $parse = '<?php '; + $parse .= '$wstTagScore = model("common/Tags")->listScore('.$cat.','.$num.','.$cache.'); '; + $parse .= 'foreach($wstTagScore as $'.$key.'=>$'.$id.'){'; + $parse .= '?>'; + $parse .= $content; + $parse .= '<?php } ?>'; + return $parse; + } +} \ No newline at end of file diff --git a/hyhproject/common/validate/Auth.php b/hyhproject/common/validate/Auth.php new file mode 100755 index 0000000..91999c7 --- /dev/null +++ b/hyhproject/common/validate/Auth.php @@ -0,0 +1,115 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 认证验证器 + */ +class Auth extends Validate{ + protected $rule = [ + ['headImg' ,'require','请上传头像'], + ['householdName' ,'require|chs','请输入户主名|请输入汉字'], + ['householdIdCard' ,'require|validation_filter_id_card','请输入身份证号|身份证号错误'], + ['houseAddress' ,'require','请输入居住地址'], + ['accountBookImg' ,'require','请上传手持户口簿主页照片'], + ['payPwd' ,'require','请输入操作密码'], + + ['companyName' ,'require|chs','请输入合作名|请输入汉字'], + ['trueName' ,'require|chs','请输入姓名|请输入汉字'], + ['idCard' ,'require|validation_filter_id_card','请输入身份证号|身份证号错误'], + ['companyAddress' ,'require','请输入公司地址'], + + + ['familyName' ,'require|chs','请输入姓名|请输入汉字'], + ['familyIdCard' ,'require|validation_filter_id_card','请输入身份证号|身份证号错误'], + ['familyRelations' ,'require','请输入与户主关系'], + ['familyRelationsImg' ,'require','请上传户主关系证明照'], + ['idCardFrontImg' ,'require','请上传身份证正面照'], + ['idCardBackImg' ,'require','请上传身份证反面照'], + ['mobileCode' ,'require|length:4','请输入验证码'], + + + ['bankName' ,'require|chs','请输入银行名|请输入汉字'], + ['accountName' ,'require|chs','请输入开户名|请输入汉字'], + ['bankNo' ,'require','请输入银行卡号'], + + ['uName' ,'require|chs','请输入姓名|请输入汉字'], + ['positionName' ,'require|chs','请输入职位名|请输入汉字'], + ['businessImg' ,'require','请上传手执营业执照照片'], + ['stake' ,'require|between:1,100','请输入持股比例|持股比例范围为1-100'] + + ]; + + protected $scene = [ + 'personal' => ['headImg','householdName','householdIdCard','houseAddress','accountBookImg'],//个人实名认证 + 'company' => ['headImg','companyName','trueName','idCard','companyAddress'],//合作实名认证 + 'report' => ['familyName','familyIdCard','familyRelations','familyRelationsImg'],//亲人报备 + 'family' => ['familyRelations','familyRelationsImg','idCardFrontImg','idCardBackImg'],//亲人认证 + 'bank' => ['bankName','accountName','bankNo'],//添加银行卡 + 'partner' => ['positionName','stake','businessImg','idCardFrontImg','idCardBackImg'],//合作人认证 + ]; + // 自定义验证规则 + // protected function checkName($value,$rule,$data) + // { + // return $rule == $value ? true : '名称错误'; + // } + /** + * 身份证验证 start + */ + function validation_filter_id_card($id_card){ + if(strlen($id_card)==18){ + return $this->idcard_checksum18($id_card); + }elseif((strlen($id_card)==15)){ + $id_card=$this->idcard_15to18($id_card); + return $this->idcard_checksum18($id_card); + }else{ + return false; + } + } + // 计算身份证校验码,根据国家标准GB 11643-1999 + function idcard_verify_number($idcard_base){ + if(strlen($idcard_base)!=17){ + return false; + } + //加权因子 + $factor=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2); + //校验码对应值 + $verify_number_list=array('1','0','X','9','8','7','6','5','4','3','2'); + $checksum=0; + for($i=0;$i<strlen($idcard_base);$i++){ + $checksum += substr($idcard_base,$i,1) * $factor[$i]; + } + $mod=$checksum % 11; + $verify_number=$verify_number_list[$mod]; + return $verify_number; + } + // 将15位身份证升级到18位 + function idcard_15to18($idcard){ + if(strlen($idcard)!=15){ + return false; + }else{ + // 如果身份证顺序码是996 997 998 999,这些是为百岁以上老人的特殊编码 + if(array_search(substr($idcard,12,3),array('996','997','998','999')) !== false){ + $idcard=substr($idcard,0,6).'18'.substr($idcard,6,9); + }else{ + $idcard=substr($idcard,0,6).'19'.substr($idcard,6,9); + } + } + $idcard=$idcard.$this->idcard_verify_number($idcard); + return $idcard; + } + // 18位身份证校验码有效性检查 + function idcard_checksum18($idcard){ + if(strlen($idcard)!=18){ + return false; + } + $idcard_base=substr($idcard,0,17); + if($this->idcard_verify_number($idcard_base)!=strtoupper(substr($idcard,17,1))){ + return false; + return $user; + }else{ + return true; + } + } + /***身份证验证 end */ +} \ No newline at end of file diff --git a/hyhproject/common/validate/CashConfigs.php b/hyhproject/common/validate/CashConfigs.php new file mode 100755 index 0000000..3c0202f --- /dev/null +++ b/hyhproject/common/validate/CashConfigs.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 提现账号验证器 + */ +class CashConfigs extends Validate{ + protected $rule = [ + ['accTargetId' ,'require','请选择开卡银行'], + ['accAreaId' ,'require','请选择开卡地区'], + ['accNo' ,'require','请输入银行卡号'], + ['accUser' ,'require','请输入持卡人'] + ]; + + protected $scene = [ + 'add' => ['accTargetId','accNo','accUser'], + 'edit' => ['accTargetId','accNo','accUser'] + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/EctWallet.php b/hyhproject/common/validate/EctWallet.php new file mode 100755 index 0000000..db44d10 --- /dev/null +++ b/hyhproject/common/validate/EctWallet.php @@ -0,0 +1,16 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 用户电子钱包地址验证器 + */ +class EctWallet extends Validate{ + protected $rule= [ + ['eAddress','require|length:42','地址不能为空|长度不符合'] + ]; + protected $scene = [ + 'add' => ['eAddress'], + 'edit'=> ['eAddress'] + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/GoodsAppraises.php b/hyhproject/common/validate/GoodsAppraises.php new file mode 100755 index 0000000..f5a0824 --- /dev/null +++ b/hyhproject/common/validate/GoodsAppraises.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 评价验证器 + */ +class GoodsAppraises extends Validate{ + protected $rule = [ + ['goodsScore' ,'between:1,5','评分必须在1-5之间'], + ['serviceScore' ,'between:1,5','评分必须在1-5之间'], + ['timeScore' ,'between:1,5','评分必须在1-5之间'], + ['content' ,'require|length:3,600','点评内容不能为空|点评内容应为3-200个字'], + ]; + + protected $scene = [ + 'add' => ['goodsScore','serviceScore','timeScore','content'], + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/GoodsConsult.php b/hyhproject/common/validate/GoodsConsult.php new file mode 100755 index 0000000..7b44344 --- /dev/null +++ b/hyhproject/common/validate/GoodsConsult.php @@ -0,0 +1,19 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 商品咨询验证器 + */ +class GoodsConsult extends Validate{ + protected $rule = [ + ['consultContent' ,'require|length:3,600','请输入咨询内容|咨询内容应为3-200个字'], + ['consultType' ,'in:1,2,3,4','请选择咨询类别'], + ['reply' ,'require|length:3,600','请输入回复内容|回复内容应为3-200个字'] + ]; + + protected $scene = [ + 'add' => ['consultContent','consultType'], + 'edit' => ['reply'] + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/Informs.php b/hyhproject/common/validate/Informs.php new file mode 100755 index 0000000..99e9d46 --- /dev/null +++ b/hyhproject/common/validate/Informs.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 订单投诉验证器 + */ +class Informs extends Validate{ + protected $rule = [ + ['informType' ,'in:1,2,3,4','无效的投诉类型!'], + ['informContent' ,'require|length:3,600','投诉内容不能为空|投诉内容应为3-200个字'], + ['respondContent' ,'require|length:3,600','应诉内容不能为空|应诉内容应为3-200个字'], + ]; + + protected $scene = [ + 'add' => ['informType','informContent'], + 'edit' => ['informType','informContent'], + 'respond' =>['respondContent'], + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/Invoices.php b/hyhproject/common/validate/Invoices.php new file mode 100755 index 0000000..a4e49c0 --- /dev/null +++ b/hyhproject/common/validate/Invoices.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 发票信息验证器 + */ +class Invoices extends Validate{ + protected $rule = [ + ['invoiceHead' ,'require','请输入发票抬头'], + ]; + + protected $scene = [ + 'add' => ['invoiceHead'], + 'edit' => ['invoiceHead'], + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/OrderComplains.php b/hyhproject/common/validate/OrderComplains.php new file mode 100755 index 0000000..646933f --- /dev/null +++ b/hyhproject/common/validate/OrderComplains.php @@ -0,0 +1,20 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 订单投诉验证器 + */ +class OrderComplains extends Validate{ + protected $rule = [ + ['complainType' ,'in:1,2,3,4','无效的投诉类型!'], + ['complainContent' ,'require|length:3,600','投诉内容不能为空|投诉内容应为3-200个字'], + ['respondContent' ,'require|length:3,600','应诉内容不能为空|应诉内容应为3-200个字'], + ]; + + protected $scene = [ + 'add' => ['complainType','complainContent'], + 'edit' => ['complainType','complainContent'], + 'respond' =>['respondContent'], + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/ShopCats.php b/hyhproject/common/validate/ShopCats.php new file mode 100755 index 0000000..d3e4e98 --- /dev/null +++ b/hyhproject/common/validate/ShopCats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 门店分类验证器 + */ +class ShopCats extends Validate{ + protected $rule = [ + ['catName' ,'require|max:60','请输入分类名称|分类名称不能超过20个字符'], + ['parentId' ,'number','无效的父级分类'] + ]; + + protected $scene = [ + 'add' => ['catName','parentId'], + 'edit' => ['catName'], + ]; +} \ No newline at end of file diff --git a/hyhproject/common/validate/Shops.php b/hyhproject/common/validate/Shops.php new file mode 100755 index 0000000..60f76ac --- /dev/null +++ b/hyhproject/common/validate/Shops.php @@ -0,0 +1,112 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 店铺验证器 + */ +class Shops extends Validate{ + protected $rule = [ + //申请入驻 + ['shopName' ,'require','请输入店铺名'], + ['userName' ,'require|chs','请输入直营人姓名|直营人姓名请输入汉字'], + ['phone' ,'require','请输入联系电话'], + ['provinceId' ,'require','请选择省'], + ['cityId' ,'require','请选择市'], + ['countyId' ,'require','请选择区县'], + ['townId' ,'require','请选择乡镇'], + ['villageId' ,'require','请选择村社区'], + ['shopAddress' ,'require','请输入店铺地址'], + ['lng' ,'require','请在地图点击坐标'], + ['lat' ,'require','请在地图点击坐标'], + ['bankName' ,'require|chs','请输入银行名|银行名请输入汉字'], + ['accountName' ,'require|chs','请输入开户名|开户名请输入汉字'], + ['bankNo' ,'require','请输入银行卡号'], + ['idCardFrontImg' ,'require','请上传身份证正面照'], + ['idCardBackImg' ,'require','请上传身份证反面照'], + ['commissionImg' ,'require','请上传直营人委托书照片'], + ['businessLicenceImg' ,'require','请上传手持身份证和营业执照,背影为店铺照片'], + ['confirmationImg' ,'require','请上传确认书照片'], + + //上传产品 + ['goodsName' ,'require','请输入产品名'], + ['largeCat' ,'require|number','请选择一级分类|请选择一级分类!'], + ['mediumCat' ,'require|number','请选择二级分类|请选择二级分类!'], + ['smallCat' ,'require|number','请选择三级分类|请选择三级分类!'], + ['discountRate' ,'require|float|between:0,100','请输入优惠率|请输入优惠率!|优惠率范围0%-100%!'], + ['freight' ,'require|float','请输入运费|请输入运费!'], + ['goodsImg' ,'require','请上传商品主图'], + ['gallery' ,'require','请上传商品相册'], + ['isSale' ,'require|in:0,1','请选择商品通过审核后上下架|请选择商品通过审核后上下架!'], + ]; + + protected $scene = [ + 'join' => ['shopName','userName','phone','provinceId','cityId','countyId','townId','villageId','shopAddress','lng','lat','bankName','accountName','bankNo','idCardFrontImg','idCardBackImg','commissionImg','businessLicenceImg','confirmationImg'],//商家入驻人认证 + 'addGoods'=>['goodsName' ,'largeCat','mediumCat' ,'smallCat', 'discountRate' ,'freight' ,'goodsImg' ,'gallery' ,'isSale'], + ]; + + // 自定义验证规则 + // protected function checkName($value,$rule,$data) + // { + // return $rule == $value ? true : '名称错误'; + // } + /** + * 身份证验证 start + */ + function validation_filter_id_card($id_card){ + if(strlen($id_card)==18){ + return $this->idcard_checksum18($id_card); + }elseif((strlen($id_card)==15)){ + $id_card=$this->idcard_15to18($id_card); + return $this->idcard_checksum18($id_card); + }else{ + return false; + } + } + // 计算身份证校验码,根据国家标准GB 11643-1999 + function idcard_verify_number($idcard_base){ + if(strlen($idcard_base)!=17){ + return false; + } + //加权因子 + $factor=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2); + //校验码对应值 + $verify_number_list=array('1','0','X','9','8','7','6','5','4','3','2'); + $checksum=0; + for($i=0;$i<strlen($idcard_base);$i++){ + $checksum += substr($idcard_base,$i,1) * $factor[$i]; + } + $mod=$checksum % 11; + $verify_number=$verify_number_list[$mod]; + return $verify_number; + } + // 将15位身份证升级到18位 + function idcard_15to18($idcard){ + if(strlen($idcard)!=15){ + return false; + }else{ + // 如果身份证顺序码是996 997 998 999,这些是为百岁以上老人的特殊编码 + if(array_search(substr($idcard,12,3),array('996','997','998','999')) !== false){ + $idcard=substr($idcard,0,6).'18'.substr($idcard,6,9); + }else{ + $idcard=substr($idcard,0,6).'19'.substr($idcard,6,9); + } + } + $idcard=$idcard.$this->idcard_verify_number($idcard); + return $idcard; + } + // 18位身份证校验码有效性检查 + function idcard_checksum18($idcard){ + if(strlen($idcard)!=18){ + return false; + } + $idcard_base=substr($idcard,0,17); + if($this->idcard_verify_number($idcard_base)!=strtoupper(substr($idcard,17,1))){ + return false; + return $user; + }else{ + return true; + } + } + /***身份证验证 end */ +} \ No newline at end of file diff --git a/hyhproject/common/validate/UserAddress.php b/hyhproject/common/validate/UserAddress.php new file mode 100755 index 0000000..c42a6eb --- /dev/null +++ b/hyhproject/common/validate/UserAddress.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\common\validate; +use think\Validate; +/** + * ============================================================================ + * 用户地址验证器 + */ +class UserAddress extends Validate{ + protected $rule = [ + ['areaId' ,'require','请选择地址'], + ['userAddress' ,'require','请输入详细地址'], + ['userName' ,'require','请输入联系名称'], + ['isDefault' ,'in:0,1','请选择是否默认地址'], + ['userPhone' ,'require','请输入联系电话'], + ]; + + protected $scene = [ + 'add' => ['areaId','userAddress','userName','isDefault','userPhone'], + 'edit' => ['areaId','userAddress','userName','isDefault','userPhone'], + ]; +} \ No newline at end of file diff --git a/hyhproject/home/behavior/InitConfig.php b/hyhproject/home/behavior/InitConfig.php new file mode 100755 index 0000000..262d67e --- /dev/null +++ b/hyhproject/home/behavior/InitConfig.php @@ -0,0 +1,23 @@ +<?php +namespace wstmart\home\behavior; +/** + * ============================================================================ + * 初始化基础数据 + */ +class InitConfig +{ + public function run(&$params){ + WSTConf('protectedUrl',model('HomeMenus')->getMenusUrl()); + // 检测手机端访问 + $request = request(); + $currModel = $request->module(); + + hook('initConfigHook',['getParams'=>input()]); + + if($request->isMobile() && $currModel=='home'){ + $url = url('mobile/index/index'); + header("location:$url"); + die; + } + } +} \ No newline at end of file diff --git a/hyhproject/home/behavior/ListenProtectedUrl.php b/hyhproject/home/behavior/ListenProtectedUrl.php new file mode 100755 index 0000000..f176fc8 --- /dev/null +++ b/hyhproject/home/behavior/ListenProtectedUrl.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\home\behavior; +/** + * ============================================================================ + * 检测用户有没有登录和访问权限 + */ +class ListenProtectedUrl +{ + public function run(&$params){ + $request = request(); + $urls = WSTConf('protectedUrl'); + $visit = strtolower($request->module()."/".$request->controller()."/".$request->action()); + + //受保护资源进来检测身份 + if(isset($urls[$visit])){ + $menuType = (int)$urls[$visit]; + $userType = -1; + if((int)session('WST_USER.userId')>0)$userType = 0; + //if((int)session('WST_USER.shopId')>0)$userType = 1; + if((int)session('WST_USER.userType')>0)$userType = 1; + //未登录不允许访问受保护的资源 + if($userType==-1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您还没有登录,请先登录']); + }else{ + header("Location:".url('home/users/login')); + } + exit(); + } + //已登录但不是商家 则不允许访问受保护的商家资源 + if($userType==0 && $menuType==1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您不是商家,请先申请为商家再访问']); + }else{ + header("Location:".url('home/shops/login')); + } + exit(); + } + //商家角色权限 + if(((int)session('WST_USER.roleId')>0) && $userType==1 && $menuType==1){ + $shopMenuUrls = model('HomeMenus')->getShopMenusUrl(); + if(!in_array($visit,$shopMenuUrls)){ + header("Location:".url('home/error/index')); + exit(); + } + } + } + } +} \ No newline at end of file diff --git a/hyhproject/home/common/function.php b/hyhproject/home/common/function.php new file mode 100755 index 0000000..592fd23 --- /dev/null +++ b/hyhproject/home/common/function.php @@ -0,0 +1,171 @@ +<?php +use think\Db; +use think\Session; +/** + * ============================================================================ + */ +/** + * 查询网站帮助 + * @param $pnum 父级记录数 + * @param $cnum 子记录数 + */ +function WSTHelps($pnum = 5,$cnum = 5){ + $cats = Db::table('__ARTICLE_CATS__')->where(['catType'=>1, 'dataFlag'=>1, 'isShow' => 1, 'parentId'=>7]) + ->field("catName,catId")->order('catSort asc')->limit($pnum)->select(); + if(!empty($cats)){ + foreach($cats as $key =>$v){ + $cats[$key]['articlecats'] = Db::table('__ARTICLES__')->where(['dataFlag'=>1,'isShow' => 1,'catId'=>$v['catId']]) + ->field("articleId, catId, articleTitle")->order('createTime asc')->limit($cnum)->select(); + } + } + return $cats; +} + +/** + * 获取前台菜单 + */ +function WSTHomeMenus($menuType){ + $m1 = array(); + if($menuType==1){ + $m1 = model('home/HomeMenus')->getShopMenus(); + }else{ + $m1 = model('home/HomeMenus')->getMenus(); + } + $menuId1 = (int)input("get.homeMenuId"); + $menus = []; + $menus['menus'] = $m1[$menuType]; + //判断menuId1是否有效 + if($menuId1==0){ + $menuId1 = (int)session('WST_MENID'.$menuType); + }else{ + session('WST_MENID'.$menuType,$menuId1); + } + //检测第一级菜单是否有效 + $tmpMenuId1 = 0; + $isFind = false; + foreach ($menus['menus'] as $key => $v){ + if($tmpMenuId1==0)$tmpMenuId1 = $key; + if($key==$menuId1)$isFind = true; + } + if($isFind){ + $menus['menuId1'] = $menuId1; + }else{ + $menus['menuId1'] = $tmpMenuId1; + } + $menus['menuId3'] = session('WST_MENUID3'.$menuType); + return $menus; +} +/** + * 获取指定父级的商家店铺分类 + */ +function WSTShopCats($parentId){ + $shopId = (int)session('WST_USER.shopId'); + $dbo = Db::table('__SHOP_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>$parentId,'shopId'=>$shopId]); + // return $dbo->field("catName,catId")->order('catSort asc')->select(); + // mark 20180518 by zl + return $dbo->field("catName,catId,provName")->order('catSort asc')->select(); +} +/** + * 获取商城搜索关键字 + */ +function WSTSearchKeys(){ + $keys = WSTConf("CONF.hotWordsSearch"); + if($keys!='')$keys = explode(',',$keys); + return $keys; +} +/** + * 获取首页左侧分类、推荐品牌和广告 + */ +function WSTSideCategorys(){ + $data = cache('WST_SIDE_CATS'); + if(!$data){ + $cats1 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>0])->field("catName,catId,catImg")->order('catSort asc')->select(); + if(count($cats1)>0){ + $ids1 = [];$ids2 = [];$cats2 = [];$cats3 = [];$mcats3 = [];$mcats2 = []; + foreach ($cats1 as $key =>$v){ + $ids1[] = $v['catId']; + } + $tmp2 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids1]])->field("catName,catId,parentId,catImg")->order('catSort asc')->select(); + if(count($tmp2)>0){ + foreach ($tmp2 as $key =>$v){ + $ids2[] = $v['catId']; + } + $tmp3 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids2]])->field("catName,catId,parentId,catImg")->order('catSort asc')->select(); + if(count($tmp3)>0){ + //组装第三级 + foreach ($tmp3 as $key =>$v){ + $mcats3[$v['parentId']][] = $v; + } + } + //组装第二级 + foreach ($tmp2 as $key =>$v){ + if(isset($mcats3[$v['catId']]))$v['list'] = $mcats3[$v['catId']]; + $mcats2[$v['parentId']][] = $v; + } + //组装第一级 + foreach ($cats1 as $key =>$v){ + if(isset($mcats2[$v['catId']]))$cats1[$key]['list'] = $mcats2[$v['catId']]; + } + } + unset($ids1,$ids2,$cats2,$cats3,$mcats3,$mcats2); + } + cache('WST_SIDE_CATS',$cats1); + return $cats1; + } + return $data; +} + +/** + * 获取导航菜单 + */ +function WSTNavigations($navType){ + $data = cache('WST_NAVS'); + if(!$data){ + $rs = Db::table('__NAVS__')->where(['isShow'=>1,'navType'=>$navType])->order('navSort asc')->select(); + foreach ($rs as $key => $v){ + if(stripos($v['navUrl'],'https://')===false && stripos($v['navUrl'],'http://')===false){ + $rs[$key]['navUrl'] = str_replace('/index.php','',\think\Request::instance()->root())."/".$v['navUrl']; + } + } + cache('WST_NAVS',$data); + return $rs; + } + return $data; +} +/** + * 根据指定的商品分类获取其路径 + */ +function WSTPathGoodsCat($catId,$data = array()){ + $rs = Db::table('__GOODS_CATS__')->where(['isShow'=>1,'dataFlag'=>1,'catId'=>$catId])->field("parentId,catName,catId")->find(); + $data[] = $rs; + if($rs['parentId']==0){; + krsort($data); + return $data; + }else{ + return WSTPathGoodsCat($rs['parentId'],$data); + } +} +/** + * 处理商家结算信息提示 + */ +function WSTShopMessageBox(){ + $USER = session('WST_USER'); + $msg = []; + if($USER['shopMoney']<0){ + $msg[] = '您的账户欠费¥'.$USER['shopMoney'].',请及时充值。'; + } + if(($USER['noSettledOrderFee']+$USER['paymentMoney'])<0 && (($USER['shopMoney']+$USER['noSettledOrderFee']+$USER['paymentMoney'])<0)){ + $msg[] = '您的账户余额【¥'.$USER['shopMoney'].'】不足以缴纳订单佣金【¥'.(-1*($USER['noSettledOrderFee']+$USER['paymentMoney'])).'】,请及时充值。'; + } + return implode('||',$msg); +} +/** +* 根据商品id,返回是否已关注商品 +*/ +function WSTCheckFavorite($goodsId,$type=0){ + $userId = (int)session('WST_USER.userId'); + if($userId>0){ + return model('common/favorites')->checkFavorite($goodsId,$type); + } + return false; +} \ No newline at end of file diff --git a/hyhproject/home/conf/config.php b/hyhproject/home/conf/config.php new file mode 100755 index 0000000..4fb921a --- /dev/null +++ b/hyhproject/home/conf/config.php @@ -0,0 +1,19 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'p', + 'list_rows' => 15, + ], +]; diff --git a/hyhproject/home/controller/Base.php b/hyhproject/home/controller/Base.php new file mode 100755 index 0000000..042fb23 --- /dev/null +++ b/hyhproject/home/controller/Base.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 基础控制器 + */ +use think\Controller; +class Base extends Controller { + protected $is_icp = 1; + public function __construct(){ + + parent::__construct(); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPCStyleId')); + + hook('homeControllerBase'); + + if(WSTConf('CONF.seoMallSwitch')==0){ + $this->redirect('home/switchs/index'); + exit; + } + $this->assign('is_icp',$this->is_icp); + } + + protected function fetch($template = '', $vars = [], $replace = [], $config = []) + { + $style = WSTConf('CONF.wsthomeStyle')?WSTConf('CONF.wsthomeStyle'):'default'; + $replace['__STYLE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/home/view/'.WSTConf('CONF.wsthomeStyle'); + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + } + + /** + * 上传图片 + */ + public function uploadPic(){ + return WSTUploadPic(0); + } + /** + * 编辑器上传文件 + */ + public function editorUpload(){ + return WSTEditUpload(0); + } + + /** + * 获取验证码 + */ + public function getVerify(){ + WSTVerify(); + } + + // 登录验证方法--用户 + protected function checkAuth(){ + $USER = session('WST_USER'); + if(empty($USER)){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $this->redirect('home/users/login'); + exit; + } + } + } + //登录验证方法--商家 + protected function checkShopAuth(){ + $USER = session('WST_USER'); + if(empty($USER) || $USER['userType']!=1){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $this->redirect('home/shops/login'); + exit; + } + } + } + +} \ No newline at end of file diff --git a/hyhproject/home/controller/Goods.php b/hyhproject/home/controller/Goods.php new file mode 100755 index 0000000..68c097b --- /dev/null +++ b/hyhproject/home/controller/Goods.php @@ -0,0 +1,706 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Goods as M; +use wstmart\common\model\Goods as CM; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + protected $beforeActionList = [ + 'checkShopAuth' => ['except'=>'search,lists,detail,historybygoods,contrastgoods,contrastdel,contrast'] + ]; + /** + * 批量删除商品 + */ + public function batchDel(){ + $m = new M(); + return $m->batchDel(); + } + /** + * 修改商品库存/价格 + */ + public function editGoodsBase(){ + $m = new M(); + return $m->editGoodsBase(); + } + + /** + * 修改商品状态 + */ + public function changSaleStatus(){ + $m = new M(); + return $m->changSaleStatus(); + } + /** + * 修改商品店长推荐状态 + */ + public function changStoreRecom(){ + $m = new M(); + return $m->changStoreRecom(); + } + /** + * 批量修改商品状态 新品/精品/热销/推荐 + */ + public function changeGoodsStatus(){ + $m = new M(); + return $m->changeGoodsStatus(); + } + /** + * 批量修改商品状态 店长推荐 + */ + public function changeStoreStatus(){ + $m = new M(); + return $m->changeStoreStatus(); + } + /** + * 批量上(下)架 + */ + public function changeSale(){ + $m = new M(); + return $m->changeSale(); + } + /** + * 上架商品列表 + */ + public function sale(){ + return $this->fetch('shops/goods/list_sale'); + } + /** + * 获取上架商品列表 + */ + public function saleByPage(){ + $m = new M(); + $rs = $m->saleByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 仓库中商品 + */ + public function store(){ + return $this->fetch('shops/goods/list_store'); + } + /** + * 审核中的商品 + */ + public function audit(){ + return $this->fetch('shops/goods/list_audit'); + } + /** + * 获取审核中的商品 + */ + public function auditByPage(){ + $m = new M(); + $rs = $m->auditByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取仓库中的商品 + */ + public function storeByPage(){ + $m = new M(); + $rs = $m->storeByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 违规商品 + */ + public function illegal(){ + return $this->fetch('shops/goods/list_illegal'); + } + /* + * 设置商品特定价格 + * */ + public function limitPrice(){ + $shopId=(int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + if (Request()->isPost()) { + $goodsType = input('goodsType'); + if ($goodsType != '') $where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if ($goodsName != '') { + $where['goodsName'] = ['like', "%$goodsName%"]; + } + if ($c2Id != 0 && $c1Id != 0) { + $where['shopCatId2'] = $c2Id; + } else if ($c1Id != 0) { + $where['shopCatId1'] = $c1Id; + } + } + $lists=db('goods')->where($where)->field('goodsId,goodsName,goodsType')->select(); + //dump($lists); + if (Request()->isAjax()) { + //dump($lists); + exit(json_encode(WSTReturn('',1,$lists))); + } + $this->assign('lists',$lists); + return $this->fetch('shops/goods/list_limitprice'); + } + //获取商品货号 + public function getGoodsProduct(){ + $goodsId = (int)input('goodsId'); + $res['specs'] = db('goods_specs')->where(['goodsId'=>$goodsId])->field('productNo,specIds')->select(); + $res['goods'] = db('goods')->where(['goodsId'=>$goodsId])->field('marketPrice')->find(); + // dump($res);die; + exit(json_encode($res)); + } + + //获取商品规格 + public function getGoodsSpecs(){ + $productNo = input('productNo'); + $res = db('goods_specs')->where(['productNo'=>$productNo])->field('specIds,marketPrice')->find(); + $specs = explode(':',$res['specIds']); + $data = db('spec_items')->where(['itemId'=>['in',$specs]])->select(); + $rs['itemName'] = implode(',',array_column($data,'itemName')); + $rs['marketPrice'] = $res['marketPrice']; + exit(json_encode($rs)); + + } + /** + * 获取违规的商品 + */ + public function illegalByPage(){ + $m = new M(); + $rs = $m->illegalByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取已设置限时价格的商品 + */ + public function limitPriceByPage(){ + $m = new M(); + $rs = $m->limitPriceByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取指定显示价格的商品的商品 + */ + public function getLimitGoods(){ + $m = new M(); + $rs = $m->getLimitGoods(); + return $rs; + } + /** + * 跳去新增限时价格商品页面 + */ + public function addLimitGoods(){ + $m = new M(); + $rs = $m->addLimitGoods(); + return $rs; + } + /** + * 跳去编辑限时价格商品页面 + */ + public function editLimitGoods(){ + $m = new M(); + $rs = $m->editLimitGoods(); + return $rs; + } + /** + * 删除显示价格商品 + */ + public function delLimitGoods(){ + $m = new M(); + $rs = $m->delLimitGoods(); + return $rs; + } + /** + * 跳去新增页面 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('goods'); + $shopId=(int)session('WST_USER.shopId'); + // $object['pay']=db('shop_pay')->where(['shopId'=>$shopId,'status'=>1])->find(); + // $object['isEct']=0; + $object['ectPayRatio'] = db('payments')->where(['payCode'=>'ect'])->value('payRatio'); + $object['goodsSn'] = WSTGoodsNo(); + $object['productNo'] = WSTGoodsNo(); + $object['goodsImg'] = WSTConf('CONF.goodsLogo'); + $object['ectPay']=0;//db('goods')->alias('g')->join('goods_ectpay ge','ge.goodsId=g.goodsId','left')->value('ectPay'); + $object['alone'] =0; + $object['basicsMoney'] = 0; + // $aloneShop = db('alone_shops')->alias('as')->join('__SHOPS__ s','as.shopId=s.shopId')->where(['as.dataFlag'=>'1','as.shopId'=>$shopId])->value('as.shopId'); + // if($aloneShop){ + // $object['alone'] =1; + // } + //dump($object); + $data = ['object'=>$object,'src'=>'add']; + return $this->fetch('shops/goods/edit',$data); + } + + /** + * 新增商品 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 跳去编辑页面 + */ + public function edit(){ + $m = new M(); + $object = $m->getById(input('get.id')); + $shopId=(int)session('WST_USER.shopId'); + // $object['pay']=db('shop_pay')->where(['shopId'=>$shopId,'status'=>1])->find(); + // //$object['pay']=1; + // if($object['pay']){ + // $object['isEct']=db('goods_pay')->where('goodsId',$object['goodsId'])->value('ectPay'); + // //$object['isOnline']=db('goods_pay')->where('goodsId',$object['goodsId'])->value('onlinePay'); + // } + $object['ectPayRatio'] = db('payments')->where(['payCode'=>'ect'])->value('payRatio'); + if($object['goodsImg']=='')$object['goodsImg'] = WSTConf('CONF.goodsLogo'); + $object['ectPay']=0; + if($object['basicsMoney'] == '') $object['basicsMoney'] = 0; + $object['alone'] =0; + // $aloneShop = db('alone_shops')->alias('as')->join('__SHOPS__ s','as.shopId=s.shopId')->where(['as.dataFlag'=>'1','as.shopId'=>$shopId])->value('as.shopId'); + // if($aloneShop){ + // $object['alone'] =1; + // } + $data = ['object'=>$object,'src'=>input('src')]; + return $this->fetch('shops/goods/edit',$data); + } + + /** + * 编辑商品 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除商品 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 获取商品规格属性 + */ + public function getSpecAttrs(){ + $m = new M(); + return $m->getSpecAttrs(); + } + /** + * 进行商品搜索 + */ + public function search(){ + //获取商品记录 + $m = new M(); + $data = []; + $data['isStock'] = Input('isStock/d'); + $data['isNew'] = Input('isNew/d'); + $data['isFreeShipping'] = input('isFreeShipping/d'); + $data['orderBy'] = Input('orderBy/d'); + $data['order'] = Input('order/d',1); + $data['keyword'] = input('keyword'); + $data['sprice'] = Input('sprice/d'); + $data['eprice'] = Input('eprice/d'); + + $data['areaId'] = (int)Input('areaId'); + $aModel = model('home/areas'); + + // 获取地区 + $data['area1'] = $data['area2'] = $data['area3'] = $aModel->listQuery(); // 省级 + + // 如果有筛选地区 获取上级地区信息 + if($data['areaId']!==0){ + $areaIds = $aModel->getParentIs($data['areaId']); + /* + 2 => int 440000 + 1 => int 440100 + 0 => int 440106 + */ + $selectArea = []; + $areaName = ''; + foreach($areaIds as $k=>$v){ + $a = $aModel->getById($v); + $areaName .=$a['areaName']; + $selectArea[] = $a; + } + // 地区完整名称 + $selectArea['areaName'] = $areaName; + // 当前选择的地区 + $data['areaInfo'] = $selectArea; + + $data['area2'] = $aModel->listQuery($areaIds[2]); // 广东的下级 + + $data['area3'] = $aModel->listQuery($areaIds[1]); // 广州的下级 + } + + + $data['goodsPage'] = $m->pageQuery(); + return $this->fetch("goods_search",$data); + } + + /** + * 获取商品列表 + */ + public function lists(){ + $catId = Input('cat/d'); + $goodsCatIds = model('GoodsCats')->getParentIs($catId); + reset($goodsCatIds); + //填充参数 + $data = []; + $data['catId'] = $catId; + $data['isStock'] = Input('isStock/d'); + $data['isNew'] = Input('isNew/d'); + $data['isFreeShipping'] = input('isFreeShipping/d'); + $data['orderBy'] = Input('orderBy/d'); + $data['order'] = Input('order/d',1); + $data['sprice'] = Input('sprice'); + $data['eprice'] = Input('eprice'); + $data['attrs'] = []; + + $data['areaId'] = (int)Input('areaId'); + $aModel = model('home/areas'); + + // 获取地区 + $data['area1'] = $data['area2'] = $data['area3'] = $aModel->listQuery(); // 省级 + + // 如果有筛选地区 获取上级地区信息 + if($data['areaId']!==0){ + $areaIds = $aModel->getParentIs($data['areaId']); + /* + 2 => int 440000 + 1 => int 440100 + 0 => int 440106 + */ + $selectArea = []; + $areaName = ''; + foreach($areaIds as $k=>$v){ + $a = $aModel->getById($v); + $areaName .=$a['areaName']; + $selectArea[] = $a; + } + // 地区完整名称 + $selectArea['areaName'] = $areaName; + // 当前选择的地区 + $data['areaInfo'] = $selectArea; + + $data['area2'] = $aModel->listQuery($areaIds[2]); // 广东的下级 + + $data['area3'] = $aModel->listQuery($areaIds[1]); // 广州的下级 + } + + $vs = input('vs'); + $vs = ($vs!='')?explode(',',$vs):[]; + foreach ($vs as $key => $v){ + if($v=='' || $v==0)continue; + $v = (int)$v; + $data['attrs']['v_'.$v] = input('v_'.$v); + } + $data['vs'] = $vs; + + $brandIds = Input('brand'); + + + $bgIds = [];// 品牌下的商品Id + if(!empty($vs)){ + // 存在筛选条件,取出符合该条件的商品id,根据商品id获取可选品牌 + $goodsId = model('goods')->filterByAttributes(); + $data['brandFilter'] = model('Brands')->canChoseBrands($goodsId); + }else{ + // 取出分类下包含商品的品牌 + $data['brandFilter'] = model('Brands')->goodsListQuery((int)current($goodsCatIds)); + } + if(!empty($brandIds))$bgIds = model('Brands')->getGoodsIds($brandIds); + + + + + $data['price'] = Input('price'); + //封装当前选中的值 + $selector = []; + //处理品牌 + $brandIds = explode(',',$brandIds); + $bIds = $brandNames = []; + foreach($brandIds as $bId){ + if($bId>0){ + foreach ($data['brandFilter'] as $key =>$v){ + if($v['brandId']==$bId){ + array_push($bIds, $v['brandId']); + array_push($brandNames, $v['brandName']); + } + } + $selector[] = ['id'=>join(',',$bIds),'type'=>'brand','label'=>"品牌","val"=>join('、',$brandNames)]; + } + } + // 当前是否有品牌筛选 + if(!empty($selector)){ + $_s[] = $selector[count($selector)-1]; + $selector = $_s; + unset($data['brandFilter']); + } + $data['brandId'] = Input('brand'); + + //处理价格 + if($data['sprice']!='' && $data['eprice']!=''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>$data['sprice']."-".$data['eprice']]; + } + if($data['sprice']!='' && $data['eprice']==''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>$data['sprice']."以上"]; + } + if($data['sprice']=='' && $data['eprice']!=''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>"0-".$data['eprice']]; + } + //处理已选属性 + $goodsFilter = model('Attributes')->listQueryByFilter($catId); + $ngoodsFilter = []; + if(!empty($vs)){ + // 存在筛选条件,取出符合该条件的商品id,根据商品id获取可选属性进行拼凑 + $goodsId = model('goods')->filterByAttributes(); + // 如果同时有筛选品牌,则与品牌下的商品Id取交集 + if(!empty($bgIds))$goodsId = array_intersect($bgIds,$goodsId); + + + $attrs = model('Attributes')->getAttribute($goodsId); + // 去除已选择属性 + foreach ($attrs as $key =>$v){ + if(!in_array($v['attrId'],$vs))$ngoodsFilter[] = $v; + } + }else{ + if(!empty($bgIds))$goodsFilter = model('Attributes')->getAttribute($bgIds);// 存在品牌筛选 + // 当前无筛选条件,取出分类下所有属性 + foreach ($goodsFilter as $key =>$v){ + if(!in_array($v['attrId'],$vs))$ngoodsFilter[] = $v; + } + } + if(count($vs)>0){ + $_vv = []; + $_attrArr = []; + foreach ($goodsFilter as $key =>$v){ + if(in_array($v['attrId'],$vs)){ + foreach ($v['attrVal'] as $key2 =>$vv){ + if(strstr(input('v_'.$v['attrId']),$vv)!==false){ + array_push($_vv, $vv); + $_attrArr[$v['attrId']]['attrName'] = $v['attrName']; + $_attrArr[$v['attrId']]['val'] = $_vv; + } + } + $_vv = []; + } + } + foreach($_attrArr as $k1=>$v1){ + $selector[] = ['id'=>$k1,'type'=>'v_'.$k1,'label'=>$v1['attrName'],"val"=>join('、',$v1['val'])]; + } + } + $data['selector'] = $selector; + $data['goodsFilter'] = $ngoodsFilter; + //获取商品记录 + $m = new M(); + $data['priceGrade'] = $m->getPriceGrade($goodsCatIds); + $data['goodsPage'] = $m->pageQuery($goodsCatIds); + $catPaths = model('goodsCats')->getParentNames($catId); + $data['catNamePath'] = '全部商品分类'; + if(!empty($catPaths))$data['catNamePath'] = implode(' - ',$catPaths); + // 商品分类下级 + $where = ['parentId'=>0,'dataFlag'=>1]; + if($catId!='')$where['parentId']=$catId; + $goodsCats = model('goodsCats')->field('catId,catName')->where($where)->select(); + $this->assign('goodsCats',$goodsCats); + return $this->fetch("goods_list",$data); + } + /** + * 查看商品详情 + */ + public function detail(){ + $m = new M(); + $goods = $m->getBySale(input('id/d',0)); + $key=input('key'); + if(!empty($goods)){ + //判断是否药品 + $goods_cat=strpos($goods['goodsCatIdPath'],'389'); + if($goods_cat!==false && $key==''){ + return $this->fetch("error_lost"); + } + if((int)session('WST_USER.userId')!=""){ + $history_data['userId']=(int)session('WST_USER.userId'); + $history_data['goodsId']=$goods['goodsId']; + $history_data['path']='1'; + $history_data['create_time']=time(); + $result=db('page_view')->insert($history_data); + } + $history = cookie("history_goods"); + $history = is_array($history)?$history:[]; + array_unshift($history, (string)$goods['goodsId']); + $history = array_values(array_unique($history)); + + if(!empty($history)){ + cookie("history_goods",$history,25920000); + } + // 商品详情延迟加载 + $goods['goodsDesc']=htmlspecialchars_decode($goods['goodsDesc']); + //修改匹配规则 适应oss 地址 mark 20180615 by zl + // $rule = '/<img src="\/(upload.*?)"/'; + $rule = '/<img src=".*?\/(upload.*?)"/'; + preg_match_all($rule, $goods['goodsDesc'], $images); + foreach($images[0] as $k=>$v){ + //mark by cheng商品详情换成远程oss图片20180313 + //$goods['goodsDesc'] = str_replace($v, "<img class='goodsImg' data-original=\"__ROOT__/".WSTImg($images[1][$k],3)."\"", $goods['goodsDesc']); + $goods['goodsDesc'] = str_replace($v, "<img class='goodsImg' data-original=\"__IMGURL__/".WSTImg($images[1][$k],0)."\"", $goods['goodsDesc']); + + } + hook('afterGetGoods',['params'=>&$goods]); + $goods['is_seckilling']=isset($goods['is_seckilling'])?$goods['is_seckilling']:0; + $this->assign('goods',$goods); + $this->assign('shop',$goods['shop']); + return $this->fetch("goods_detail"); + }else{ + return $this->fetch("error_lost"); + } + } + /** + * 预警库存 + */ + public function stockwarnbypage(){ + return $this->fetch("shops/stockwarn/list"); + } + /** + * 获取预警库存列表 + */ + public function stockByPage(){ + $m = new M(); + $rs = $m->stockByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 修改预警库存 + */ + public function editwarnStock(){ + $m = new M(); + return $m->editwarnStock(); + } + + /** + * 获取商品浏览记录 + */ + public function historyByGoods(){ + $rs = model('Tags')->historyByGoods(8); + return WSTReturn('',1,$rs); + } + /** + * 记录对比商品 + */ + public function contrastGoods(){ + $id = (int)input('post.id'); + $contras = cookie("contras_goods"); + if($id>0){ + $m = new M(); + $goods = $m->getBySale($id); + $catId = explode('_',$goods['goodsCatIdPath']); + $catId = $catId[0]; + if(isset($contras['catId']) && $catId!=$contras['catId'])return WSTReturn('请选择同分类对比',-1); + if(isset($contras['list']) && count($contras['list'])>3)return WSTReturn('对比栏已满',-1); + if(!isset($contras['catId']))$contras['catId'] = $catId; + $contras['list'][$id] = $id; + cookie("contras_goods",$contras,25920000); + } + if(isset($contras['list'])){ + $m = new M(); + $list = []; + foreach($contras['list'] as $k=>$v){ + $list[] = $m->getBySale($v); + } + return WSTReturn('',1,$list); + }else{ + return WSTReturn('',1); + } + } + /** + * 删除对比商品 + */ + public function contrastDel(){ + $id = (int)input('post.id'); + $contras = cookie("contras_goods"); + if($id>0 && isset($contras['list'])){ + unset($contras['list'][$id]); + cookie("contras_goods",$contras,25920000); + }else{ + cookie("contras_goods", null); + } + return WSTReturn('删除成功',1); + } + /** + * 商品对比 + */ + public function contrast(){ + $contras = cookie("contras_goods"); + $list = []; + $list = $lists= $saleSpec = $shop = $score = $brand = $spec = []; + if(isset($contras['list'])){ + $m = new M(); + foreach($contras['list'] as $key=>$value){ + $dara = $m->getBySale($value); + if(isset($dara['saleSpec'])){ + foreach($dara['saleSpec'] as $ks=>$vs){ + if($vs['isDefault']==1){ + $dara['defaultSpec'] = $vs; + $dara['defaultSpec']['ids'] = explode(':',$ks); + } + } + $saleSpec[$value] = $dara['saleSpec']; + } + $list[] = $dara; + } + //第一个商品信息 + $goods = $list[0]; + //对比处理 + $shops['identical'] = $scores['identical'] = $brands['identical'] = 1; + foreach($list as $k=>$v){ + $shop[$v['goodsId']] = $v['shop']['shopName']; + if($goods['shop']['shopId']!=$v['shop']['shopId'])$shops['identical'] = 0; + $score[$v['goodsId']] = $v['scores']['totalScores']; + if($goods['scores']['totalScores']!=$v['scores']['totalScores'])$scores['identical'] = 0; + $brand[$v['goodsId']] = $v['brandName']; + if($goods['brandId']!=$v['brandId'])$brands['identical'] = 0; + if(isset($v['spec'])){ + foreach($v['spec'] as $k2=>$v2){ + $spec[$k2]['identical'] = 0; + $spec[$k2]['type'] = 'spec'; + $spec[$k2]['name'] = $v2['name']; + $spec[$k2]['catId'] = $k2; + foreach($v2['list'] as $ks22=>$vs22){ + $v['spec'][$k2]['list'][$ks22]['isDefault'] = (in_array($vs22['itemId'],$v['defaultSpec']['ids']))?1:0; + } + $spec[$k2]['info'][$v['goodsId']] = $v['spec'][$k2]; + } + } + } + $shops['name'] = '店铺'; + $shops['type'] = 'shop'; + $shops['info'] = $shop; + $lists[] = $shops; + $scores['name'] = '商品评分'; + $scores['type'] = 'score'; + $scores['info'] = $score; + $lists[] = $scores; + $brands['name'] = '品牌'; + $brands['type'] = 'brand'; + $brands['info'] = $brand; + $lists[] = $brands; + foreach($spec as $k3=>$v3){ + $lists[] = $v3; + } + } + $data['list'] = $list; + $data['lists'] = $lists; + $data['saleSpec'] = $saleSpec; + $this->assign('data',$data); + return $this->fetch("goods_contrast"); + } +} diff --git a/hyhproject/home/controller/Goodscats.php b/hyhproject/home/controller/Goodscats.php new file mode 100755 index 0000000..20b446c --- /dev/null +++ b/hyhproject/home/controller/Goodscats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class Goodscats extends Base{ + /** + * 获取列表 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(input('parentId/d',0)); + return WSTReturn("", 1,$rs); + } + +} \ No newline at end of file diff --git a/hyhproject/home/controller/Index.php b/hyhproject/home/controller/Index.php new file mode 100755 index 0000000..f63ec19 --- /dev/null +++ b/hyhproject/home/controller/Index.php @@ -0,0 +1,72 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Index extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['only'=>'getsysmessages'] + ]; + public function index(){ + $pay['needPay'] =200; + $userId=1;//$this->getUserId() + //产品券 + $buyerMaxProductScale = round(dataConf('buyerMaxProductScale')*0.01,2); + $pay['maxProduct'] = $pay['needPay'] * $buyerMaxProductScale;//最大可用产品券 + $pay['productHandlingFee'] = round(dataConf('useHasProductHandlingFee')*0.01,2);//产品券手续费 + $pay['productTaxFee'] = round(dataConf('useHasProductTaxFee')*0.01,2);//产品券税费 + $pay['maxAllProduct'] = $this->getMaxNum($pay['maxProduct'],(1-$pay['productHandlingFee']-$pay['productTaxFee'] ));//加上手续费,税费最多扣除产品券 + + //优惠券 + $pay['maxCoupons'] = $pay['needPay'] - $pay['maxProduct'] ;//最大可用其他券,优惠券+旺旺券+现金券 + $pay['coupousHandlingFee'] = round(dataConf('useHasCoupousHandlingFee')*0.01,2);//优惠券手续费 + $pay['coupousTaxFee'] = round(dataConf('useHasCoupousTaxFee')*0.01,2);//优惠券税费 + $pay['maxAllCoupons'] = $this->getMaxNum($pay['maxCoupons'],(1-$pay['coupousHandlingFee']-$pay['coupousTaxFee'] ));//加上手续费,税费最多扣除优惠券 + + $pay['money']['useMoney'] = 0; + $pay['wang']['useWang'] = 0; + //实际应用最大的产品券 + $userInfo = getUserInfo(['userId'=>$userId],'couponsNum,productNum,wangNum'); + $pay['product']['useProduct'] = $userInfo['productNum'] >= $pay['maxAllProduct'] ? $pay['maxAllProduct'] : $userInfo['productNum']; + $pay['product']['useProductHandlingFee'] = $pay['product']['useProduct'] * $pay['productHandlingFee'];//产品券手续费 + $pay['product']['useProductTaxFee'] = $pay['product']['useProduct'] * $pay['productTaxFee']; + $pay['product']['useProductOk'] = $pay['product']['useProduct'] - $pay['product']['useProductHandlingFee'] - $pay['product']['useProductTaxFee']; + + //实际应用最大的优惠券 + $pay['coupons']['useCoupons'] = $userInfo['couponsNum'] >= $pay['maxAllCoupons'] ? $pay['maxAllCoupons'] : $userInfo['couponsNum']; + $pay['coupons']['useCouponsHandlingFee'] = round($pay['coupons']['useCoupons'] * $pay['coupousHandlingFee'],2);//产品券手续费 + $pay['coupons']['useCouponsTaxFee'] = round($pay['coupons']['useCoupons'] * $pay['coupousTaxFee'],2); + $pay['coupons']['useCouponsOk'] = $pay['coupons']['useCoupons'] - $pay['coupons']['useCouponsHandlingFee'] - $pay['coupons']['useCouponsTaxFee']; + $remNum = $pay['needPay'] - $pay['product']['useProduct'] - $pay['coupons']['useCouponsHandlingFee']; + if($remNum > 0 ){ + //旺旺券 + $pay['wang']['useWang'] = $userInfo['wangNum'] >= $remNum ? $remNum : $userInfo['wangNum']; + $remNum = $pay['needPay'] - $pay['product']['useProduct'] - $pay['coupons']['useCouponsHandlingFee']-$pay['wang']['useWang']; + if($remNum > 0 ){ + $pay['money']['useMoney'] = $remNum; + } + } + + // dump($pay); + + return $this->fetch('index'); + } + /** + * 获取除去比例的最大值 + * @param [type] $num [description] + * @param [type] $scale [description] + * @return [type] [description] + */ + private function getMaxNum($num,$scale){ + return round($num/$scale,2); + } + /** + * 保存目录ID + */ + public function getMenuSession(){ + $menuId = input("post.menuId"); + $menuType = session('WST_USER.loginTarget'); + session('WST_MENUID3'.$menuType,$menuId); + } +} diff --git a/hyhproject/home/controller/Shopcats.php b/hyhproject/home/controller/Shopcats.php new file mode 100755 index 0000000..91859b5 --- /dev/null +++ b/hyhproject/home/controller/Shopcats.php @@ -0,0 +1,98 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\ShopCats as M; +/** + * ============================================================================ + * 门店分类控制器 + */ +class Shopcats extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->getCatAndChild(session('WST_USER.shopId'),input('post.parentId/d')); + // mark 添加省份 20180518 by zl + $areas = $m->getAreas(); + $this->assign('areas',$areas); + // 判断是否是自营 如果是自营就显示省份 + $shopId = (int)session('WST_USER.shopId');; + $this->assign('shopId',$shopId); + // end + $this->assign('list',$list); + return $this->fetch("shops/shopcats/list"); + } + + /** + * 修改名称 + */ + public function editName(){ + $m = new M(); + $rs = array(); + if(input('post.id/d')>0){ + $rs = $m->editName(); + } + return $rs; + } + /** + * 修改排序 + */ + public function editSort(){ + $m = new M(); + $rs = array(); + if(input('post.id/d')>0){ + $rs = $m->editSort(); + } + return $rs; + } + /** + * 批量保存商品分类 + */ + public function batchSaveCats(){ + $m = new M(); + $rs = $m->batchSaveCats(); + return $rs; + } + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $list = $m->listQuery((int)session('WST_USER.shopId'),input('post.parentId/d')); + $rs = array(); + $rs['status'] = 1; + $rs['list'] = $list; + return $rs; + } + + public function changeCatStatus(){ + $m = new M(); + $rs = $m->changeCatStatus(); + return $rs; + } + + + + + + /** + * 设置分类特产省份 mark 20180515 + */ + public function setSpecial(){ + $m = new M(); + $rs = $m->setSpecial(); + return $rs; + } + +} diff --git a/hyhproject/home/controller/Shopconfigs.php b/hyhproject/home/controller/Shopconfigs.php new file mode 100755 index 0000000..1709096 --- /dev/null +++ b/hyhproject/home/controller/Shopconfigs.php @@ -0,0 +1,31 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 门店配置控制器 + */ +class Shopconfigs extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 店铺设置 + */ + public function toShopCfg(){ + //获取商品信息 + $m = model('ShopConfigs'); + $this->assign('object',$m->getShopCfg((int)session('WST_USER.shopId'))); + return $this->fetch('shops/shopconfigs/shop_cfg'); + } + + /** + * 新增/修改 店铺设置 + */ + public function editShopCfg(){ + $shopId = (int)session('WST_USER.shopId'); + $m = model('ShopConfigs'); + if($shopId>0){ + $rs = $m->editShopCfg($shopId); + } + return $rs; + } + +} diff --git a/hyhproject/home/controller/Shopfreights.php b/hyhproject/home/controller/Shopfreights.php new file mode 100755 index 0000000..7c535cd --- /dev/null +++ b/hyhproject/home/controller/Shopfreights.php @@ -0,0 +1,38 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopFreights as M; +use wstmart\home\model\Areas; +use wstmart\home\model\Shops; +/** + * ============================================================================ + * 运费控制器 + */ +class Shopfreights extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 查看运费设置 + */ + public function index(){ + $shops = new Shops(); + $shopId = session('WST_USER.shopId'); + $shFreight = $shops->getShopsFreight($shopId); + $this->assign('shFreight',$shFreight);//默认运费 + return $this->fetch('shops/freights/list'); + } + /** + * 运费列表 + */ + public function listProvince(){ + $m = new M(); + return $m->listProvince(); + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } +} diff --git a/hyhproject/home/controller/Shoproles.php b/hyhproject/home/controller/Shoproles.php new file mode 100755 index 0000000..351a227 --- /dev/null +++ b/hyhproject/home/controller/Shoproles.php @@ -0,0 +1,74 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopRoles as M; +/** + * ============================================================================ + * 门店角色控制器 + */ +class Shoproles extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->pageQuery(); + $this->assign('list',$list); + return $this->fetch("shops/shoproles/list"); + } + + /** + * 查询 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 新增角色 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('shop_roles'); + $data = ['object'=>$object]; + return $this->fetch('shops/shoproles/edit',$data); + } + + /** + * 新增角色 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 修改角色 + */ + public function edit(){ + $m = new M(); + $object = $m->getById((int)input('get.id')); + $data = ['object'=>$object]; + return $this->fetch('shops/shoproles/edit',$data); + } + + /** + * 修改角色 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + +} diff --git a/hyhproject/home/controller/Shops.php b/hyhproject/home/controller/Shops.php new file mode 100755 index 0000000..3e5e149 --- /dev/null +++ b/hyhproject/home/controller/Shops.php @@ -0,0 +1,357 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Goods; +use wstmart\common\model\GoodsCats; +use think\Loader; +/** + * ============================================================================ + * 门店控制器 + */ + +class Shops extends Base{ + protected $beforeActionList = [ + 'checkShopAuth' => ['only'=>'editinfo,getshopmoney'], + 'checkAuth'=>['only'=>'join,joinstep1,joinstep2,savestep2,joinstep3,savestep3,joinstep4,savestep4,joinstep5,savestep5,joinsuccess'] + ]; + /** + * 店铺公告页 + */ + public function notice(){ + $notice = model('shops')->getNotice(); + $this->assign('notice',$notice); + return $this->fetch('shops/shops/notice'); + } + /** + * 修改店铺公告 + */ + public function editNotice(){ + $s = model('shops'); + return $s->editNotice(); + } + /** + * 商家登录 + */ + public function login(){ + $USER = session('WST_USER'); + if(!empty($USER) && isset($USER['shopId'])){ + $this->redirect("shops/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('shop_login'); + } + /** + * 商家中心 + */ + public function index(){ + session('WST_MENID1',null); + session('WST_MENUID31',null); + $s = model('shops'); + $data = $s->getShopSummary((int)session('WST_USER.shopId')); + $this->assign('data',$data); + return $this->fetch('shops/index'); + } + /** + * 店铺街 + */ + public function shopStreet(){ + $g = new GoodsCats(); + $goodsCats = $g->listQuery(0); + $this->assign('goodscats',$goodsCats); + //店铺街列表 + $s = model('shops'); + $pagesize = 10; + $selectedId = input("get.id/d"); + $this->assign('selectedId',$selectedId); + $list = $s->pageQuery($pagesize); + $this->assign('list',$list); + $this->assign('keyword',input('keyword')); + $this->assign('keytype',1); + return $this->fetch('shop_street'); + } + /** + * 店铺详情 + */ + public function home(){ + $shopId = (int)input("param.shopId/d"); + hook("homeBeforeGoShopHome",["shopId"=>$shopId]); + hook("goShopAfterAddView",["shopId"=>$shopId,'path'=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo($shopId); + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(1778 != $shopId && !empty($this->is_icp)) return $this->fetch('error_lost'); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect(Url('home/shops/selfShop'),$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + //dump($data['list']);die; + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + return $this->fetch('shop_home'); + } + + /** + * 店铺分类 + */ + public function cat(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d"); + $data['shop'] = $s->getShopInfo($shopId); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect('shops/selfShop',$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + return $this->fetch('shop_home'); + } + + /** + * 查看店铺设置 + */ + public function info(){ + $s = model('shops'); + $object = $s->getByView((int)session('WST_USER.shopId')); + $bankList= model('banks')->listQuery(); + $this->assign('bankList',$bankList); + $this->assign('object',$object); + return $this->fetch('shops/shops/view'); + } + /** + * 自营店铺 + */ + public function selfShop(){ + hook("homeBeforeGoSelfShop",["shopId"=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo(1); + if(empty($data['shop']))return $this->fetch('error_lost'); + $this->assign('selfShop',1); + $data['shopcats'] = model('ShopCats')->getShopCats(1); + $this->assign('goodsName',urldecode(input("param.goodsName")));//搜索 + // 店长推荐 + $data['rec'] = $s->getRecGoods('rec',6); + // 热销商品 + $data['hot'] = $s->getRecGoods('hot',6); + $this->assign('data',$data); + return $this->fetch('self_shop'); + } + + /** + * 编辑店铺资料 + */ + public function editInfo(){ + + $rs = model('shops')->editInfo(); + return $rs; + } + + /** + * 获取店铺金额 + */ + public function getShopMoney(){ + $rs = model('shops')->getFieldsById((int)session('WST_USER.shopId'),'shopMoney,lockMoney,rechargeMoney'); + $urs = model('users')->getFieldsById((int)session('WST_USER.userId'),'payPwd'); + $rs['isSetPayPwd'] = ($urs['payPwd']=='')?0:1; + $rs['isDraw'] = ((float)WSTConf('CONF.drawCashShopLimit')<=$rs['shopMoney'])?1:0; + unset($urs); + return WSTReturn('',1,$rs); + } + + + /** + * 跳去商家入驻 + */ + public function join(){ + $rs = model('shops')->checkApply(); + $this->assign('isApply',(!empty($rs) && $rs['applyStatus']>=1)?1:0); + $this->assign('applyStep',empty($rs)?1:$rs['applyStep']); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['105']))$articles['105']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['106']))$articles['106']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['107']))$articles['107']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['108']))$articles['108']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join'); + } + + public function joinStep1(){ + session('apply_step',1); + $rs = model('shops')->checkApply(); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['109']))$articles['109']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join_step1'); + } + public function joinStep2(){ + $step = (int)session('apply_step'); + if($step<1){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',2); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step2'); + } + public function saveStep2(){ + $step = (int)session('apply_step'); + if($step<2){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep1')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep2($data); + } + } + public function joinStep3(){ + $step = (int)session('apply_step'); + if($step<2){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',3); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step3'); + } + public function saveStep3(){ + $step = (int)session('apply_step'); + if($step<3){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep2')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep3($data); + } + } + public function joinStep4(){ + $step = (int)session('apply_step'); + if($step<3){ + $this->redirect(Url('home/shops/joinStep4')); + exit(); + } + session('apply_step',4); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $banks = model('banks')->listQuery(); + $this->assign('bankList',$banks); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step4'); + } + public function saveStep4(){ + $step = (int)session('apply_step'); + if($step<4){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep3')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep4($data); + } + } + public function joinStep5(){ + $step = (int)session('apply_step'); + if($step<4){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',5); + $shopLicense=db('shop_license')->alias('a') + ->join('shops b','b.shopId= a.shopId') + ->where('b.userId',(int)session("WST_USER.userId"))->find(); + $this->assign('shopLicense',$shopLicense); + $goodsCatList = model('goodsCats')->listQuery(0); + $this->assign('goodsCatList',$goodsCatList); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step5'); + } + public function saveStep5(){ + $step = (int)session('apply_step'); + if($step<5){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep4')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep5($data); + } + } + public function joinSuccess(){ + $step = (int)session('apply_step'); + if($step<5){ + $this->redirect(Url('home/shops/joinStep1')); + } + session('apply_step',5); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + /** + * 入驻进度查询 + */ + public function checkapplystatus(){ + $apply = model('shops')->getShopApply(); + if(empty($apply)){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + }else{ + if($apply['applyStatus']==0){ + session('apply_step',$apply['applyStep']); + $this->redirect(Url('home/shops/joinStep'.$apply['applyStep'])); + exit(); + }else{ + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + } + } +} diff --git a/hyhproject/home/controller/Shopusers.php b/hyhproject/home/controller/Shopusers.php new file mode 100755 index 0000000..9fa4d25 --- /dev/null +++ b/hyhproject/home/controller/Shopusers.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopUsers as M; +/** + * ============================================================================ + * 门店角色控制器 + */ +class Shopusers extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->pageQuery(); + $this->assign('list',$list); + return $this->fetch("shops/shopusers/list"); + } + + /** + * 查询 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 新增店铺管理员 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('shop_roles'); + $roles = model("ShopRoles")->listQuery(); + $data = ['object'=>$object,"roles"=>$roles]; + return $this->fetch('shops/shopusers/add',$data); + } + + /** + * 新增店铺管理员 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 修改店铺管理员 + */ + public function edit(){ + $m = new M(); + $object = $m->getById(input('get.id')); + $roles = model("ShopRoles")->listQuery(); + $data = ['object'=>$object,"roles"=>$roles]; + return $this->fetch('shops/shopusers/edit',$data); + } + + /** + * 编辑店铺管理员 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + +} diff --git a/hyhproject/home/controller/Users.php b/hyhproject/home/controller/Users.php new file mode 100755 index 0000000..1331499 --- /dev/null +++ b/hyhproject/home/controller/Users.php @@ -0,0 +1,974 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Users as MUsers; +use wstmart\common\model\LogSms; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'getverify,login,logout,regist,toregist,checklogin,getphoneverifycode,checkloginkey,checkemail,checkfindkey,protocol,forgetpass,forgetpasst,resetpass,forgetpasss,forgetpassf,findpass,getfindphone,checkfindphone,getfindemail,tologinbox'] + ]; + /** + * 去登录 + */ + public function login(){ + $USER = session('WST_USER'); + //如果已经登录了则直接跳去用户中心 + if(!empty($USER) && !empty($USER['userId'])){ + $this->redirect("users/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('user_login'); + } + + /** + * 用户退出 + */ + public function logout(){ + session('WST_USER',null); + setcookie("loginPwd", null); + session('WST_HO_CURRENTURL', null); + hook('afterUserLogout'); + return WSTReturn("退出成功",1); + + } + + /** + * 用户注册 + * + */ + public function regist(){ + $USER = session('WST_USER'); + //如果已经登录了则直接跳去用户中心 + if(!empty($USER) && $USER['userId']!=''){ + $this->redirect("users/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('regist'); + } + + + /** + * 新用户注册 + */ + public function toRegist(){ + $m = new MUsers(); + $rs = $m->regist(); + $rs['url'] = session('WST_HO_CURRENTURL'); + return $rs; + + } + + /** + * 验证登录 + * + */ + public function checkLogin(){ + $m = new MUsers(); + $rs = $m->checkLogin(); + $rs['url'] = session('WST_HO_CURRENTURL'); + return $rs; + } + + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $m = new MUsers(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + return $rv; + } + + + /** + * 判断手机或邮箱是否存在 + */ + public function checkLoginKey(){ + $m = new MUsers(); + if(input("post.loginName"))$val=input("post.loginName"); + if(input("post.userPhone"))$val=input("post.userPhone"); + if(input("post.userEmail"))$val=input("post.userEmail"); + $userId = (int)session('WST_USER.userId'); + $rs = WSTCheckLoginKey($val,$userId); + if($rs["status"]==1){ + return array("ok"=>""); + }else{ + return array("error"=>$rs["msg"]); + } + } + + /** + * 判断邮箱是否存在 + */ + public function checkEmail(){ + $data = $this->checkLoginKey(); + if(isset($data['error']))$data['error'] = '对不起,该邮箱已存在'; + return $data; + } + + /** + * 判断用户名是否存在/忘记密码 + */ + public function checkFindKey(){ + $m = new MUsers(); + $userId = (int)session('WST_USER.userId'); + $rs = WSTCheckLoginKey(input("post.loginName"),$userId); + if($rs["status"]==1){ + return array("error"=>"该用户不存在!"); + }else{ + return array("ok"=>""); + } + + } + + /** + * 跳到用户注册协议 + */ + public function protocol(){ + return $this->fetch("user_protocol"); + } + + /** + * 用户中心 + */ + public function index(){ + session('WST_MENID0',0); + session('WST_MENUID30',0); + // 待付款 待收货 待评价 + $info = model('home/Users')->getStatusNum(); + $this->assign($info); + $m = new MUsers(); + $data = $m->getById((int)session('WST_USER.userId')); + $this->assign('data',$data); + return $this->fetch('users/index'); + } + + + /** + * 跳去修改个人资料 + */ + public function edit(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/user_edit'); + } + /** + * 跳去修改密码页 + */ + public function editPass(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/security/user_pass'); + } + /** + * 修改密码 + */ + public function passedit(){ + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $rs = $m->editPass($userId); + return $rs; + } + /** + * 修改 + */ + public function toEdit(){ + $m = new MUsers(); + $rs = $m->edit(); + return $rs; + } + /** + * 安全设置页 + */ + public function security(){ + //获取用户信息 + $m = new MUsers(); + $data = $m->getById((int)session('WST_USER.userId')); + if($data['userPhone']!='')$data['userPhone'] = WSTStrReplace($data['userPhone'],'*',3); + if($data['userEmail']!='')$data['userEmail'] = WSTStrReplace($data['userEmail'],'*',2,'@'); + $this->assign('data',$data); + return $this->fetch('users/security/index'); + } + /** + * 修改邮箱页 + */ + public function editEmail(){ + hook('homeControllerUsersEditEmail'); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $data = $m->getById($userId); + if($data['userEmail']!='')$data['userEmail'] = WSTStrReplace($data['userEmail'],'*',2,'@'); + $this->assign('data',$data); + $process = 'One'; + $this->assign('process',$process); + if($data['userEmail']){ + return $this->fetch('users/security/user_edit_email'); + }else{ + return $this->fetch('users/security/user_email'); + } + } + /** + * 发送验证邮件/绑定邮箱 + */ + public function getEmailVerify(){ + $userEmail = input('post.userEmail'); + if(!$userEmail){ + return WSTReturn('请输入邮箱!',-1); + } + $code = input("post.verifyCode"); + $process = input("post.process"); + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $rs = WSTCheckLoginKey($userEmail,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("邮箱已存在!"); + exit(); + } + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('WST_USER.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail($userEmail,'绑定邮箱',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + // 绑定的邮箱 + session('email.val',$userEmail); + // 验证码 + session("email.key", $code); + // 发起绑定邮箱的时间; + session('email.time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + /** + * 绑定邮箱 + */ + public function emailEdit(){ + $USER = session('WST_USER'); + if(empty($USER) && $USER['userId']==''){ + $this->redirect("home/users/login"); + } + $bindTime = session('email.time'); + $code = session('email.key'); + $bindEmail = session('email.val'); + + if(time()>floatval($bindTime)+30*60)$this->error('验证码已失效!'); + $rs = WSTCheckLoginKey($bindEmail,(int)session('WST_USER.userId')); + + if($rs["status"]!=1){ + $this->error('邮箱已存在!'); + exit(); + } + $secretCode = input('secretCode'); + + if($code!=$secretCode)return WSTReturn('校验码错误',-1); + + $m = new MUsers(); + $rs = $m->editEmail((int)session('WST_USER.userId'),$bindEmail); + if($rs['status'] == 1){ + // 清空session + session('email',null); + return WSTReturn('验证通过',1); + } + $this->error('绑定邮箱失败'); + } + /** + * 完成邮箱绑定 + */ + public function doneEmailBind(){ + $this->assign('process','Three'); + return $this->fetch('users/security/user_email'); + } + /** + * 发送验证邮件/修改邮箱 + */ + public function getEmailVerifyt(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userEmail = $data['userEmail']; + if(!$userEmail){ + return WSTReturn('请输入邮箱!',-1); + } + $code = input("post.verifyCode"); + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('WST_USER.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail($userEmail,'绑定邮箱',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + // 修改的用户 + session('email.uId',(int)session('WST_USER.userId')); + // 绑定的邮箱 + session('email.val',$userEmail); + // 验证码 + session("email.key", $code); + // 发起绑定邮箱的时间; + session('email.time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + /** + * 修改邮箱 + */ + public function emailEditt(){ + $USER = session('WST_USER'); + if(empty($USER) && $USER['userId']!=''){ + $this->redirect("home/users/login"); + } + + $bindTime = session('email.time'); + $code = session('email.key'); + $bindEmail = session('email.val'); + $uId = (int)session('email.uId'); + + if(time()>floatval($bindTime)+30*60)$this->error('验证码已失效!'); + $rs = WSTCheckLoginKey($bindEmail,(int)session('WST_USER.userId')); + + if($rs["status"]!=1){ + $this->error('邮箱已存在!'); + exit(); + } + $secretCode = input('secretCode'); + + if($code!=$secretCode)return WSTReturn('校验码错误',-1); + + $m = new MUsers(); + $data = $m->getById($uId); + if($data['userId']==session('WST_USER.userId')){ + return WSTReturn('验证通过',1); + } + $this->error('无效的用户!'); + } + /** + * 修改邮箱第二步 + */ + public function editEmail2(){ + $this->assign('process','Two'); + return $this->fetch('users/security/user_edit_email'); + } + /** + * 修改邮箱第三步 + */ + public function editEmail3(){ + $this->assign('process','Three'); + return $this->fetch('users/security/user_edit_email'); + } + + + + /** + * 修改手机页 + */ + public function editPhone(){ + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $data = $m->getById($userId); + if($data['userPhone']!='')$data['userPhone'] = WSTStrReplace($data['userPhone'],'*',3); + $this->assign('data',$data); + $process = 'One'; + $this->assign('process',$process); + if($data['userPhone']){ + return $this->fetch('users/security/user_edit_phone'); + }else{ + return $this->fetch('users/security/user_phone'); + } + } + /** + * 跳到发送手机验证 + */ + public function toApply(){ + return $this->fetch("user_verify_phone"); + } + /** + * 绑定手机/获取验证码 + */ + public function getPhoneVerifyo(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyo',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function getPhoneVerifyb(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyb',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.Checkcode"); + $process = input("post.process"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("地址已失效,请重新验证身份!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new MUsers(); + $rs = $m->editPhone((int)session('WST_USER.userId'),session('Verify_info.userPhone')); + if($process=='Two'){ + $rs['process'] = $process; + }else{ + $rs['process'] = '0'; + } + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + public function editPhoneSu(){ + $pr = input("get.pr"); + $process = 'Three'; + $this->assign('process',$process); + if($pr == 'Two'){ + return $this->fetch('users/security/user_edit_phone'); + }else{ + return $this->fetch('users/security/user_phone'); + } + } + /** + * 修改手机/获取验证码 + */ + public function getPhoneVerifyt(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 修改手机 + */ + public function phoneEditt(){ + $phoneVerify = input("post.Checkcode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPhoneSut(){ + $process = 'Two'; + $this->assign('process',$process); + if(session('Verify_info2.phoneVerify')){ + return $this->fetch('users/security/user_edit_phone'); + } + $this->error('地址已失效,请重新验证身份'); + } + /** + * 处理图像裁剪 + */ + // public function editUserPhoto(){ + // $imageSrc = trim(input('post.photoSrc'),'/'); + // $image = \image\Image::open($imageSrc); + // $x = (int)input('post.x'); + // $y = (int)input('post.y'); + // $w = (int)input('post.w',150); + // $h = (int)input('post.h',150); + // $rs = $image->crop($w, $h, $x, $y, 150, 150)->save($imageSrc); + // if($rs){ + // return WSTReturn('',1,$imageSrc); + // exit; + // } + // return WSTReturn('发生未知错误.',-1); + + // } + + /** + * 处理图像裁剪 修改适应oss mark 201080612 by zl + */ + public function editUserPhoto(){ + $imageSrc = trim(input('post.photoSrc'),'/'); + //判断图片是否缩放了 + $res = strpos($imageSrc,'?x-oss-process='); + $x = (int)input('post.x'); + $y = (int)input('post.y'); + $w = (int)input('post.w',150); + $h = (int)input('post.h',150); + //判断是否缩放 如果缩放了就不加'?x-oss-process=' + if($res){ + $imageSrc=$imageSrc.',image/crop,x_'.$x.',y_'.$y.',w_'.$w.',h_'.$h.',image/resize,w_150,h_150'; + }else{ + $imageSrc=$imageSrc.'?x-oss-process=image/crop,x_'.$x.',y_'.$y.',w_'.$w.',h_'.$h.',image/resize,w_150,h_150'; + } + + return WSTReturn('',1,$imageSrc); + + } + /****************************************************** 忘记密码 **********************************************************/ + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new MUsers(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $process = 'One'; + $this->assign('data', $user); + $this->assign('process', $process); + return $this->fetch('users/security/user_edit_pay'); + } + /** + * 忘记支付密码:发送短信 + */ + public function getphoneverifypay(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 忘记支付密码:验证 + */ + public function payEditt(){ + $payVerify = input("post.Checkcode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($payVerify==session('Verify_backPaypwd_info.phoneVerify')){ + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPaySut(){ + $process = 'Two'; + $this->assign('process',$process); + if(session('Verify_backPaypwd_info.phoneVerify')){ + return $this->fetch('users/security/user_edit_pay'); + } + $this->error('地址已失效,请重新验证身份'); + } + /** + * 忘记支付密码:设置 + */ + public function payEdito(){ + $process = input("post.process"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("地址已失效,请重新验证身份!"); + exit(); + } + $m = new MUsers(); + $rs = $m->resetbackPay(); + if($process=='Two'){ + $rs['process'] = $process; + }else{ + $rs['process'] = '0'; + } + return $rs; + } + /** + * 忘记支付密码:完成 + */ + public function editPaySu(){ + $pr = input("get.pr"); + $process = 'Three'; + $this->assign('process',$process); + if($pr == 'Two'){ + return $this->fetch('users/security/user_edit_pay'); + }else{ + return $this->fetch('users/security/user_pay_pass'); + } + } + /** + * 忘记密码 + */ + public function forgetPass(){ + return $this->fetch('forget_pass'); + } + public function forgetPasst(){ + if(time()<floatval(session('findPass.findTime'))+30*60){ + $userId = session('findPass.userId'); + $m = new MUsers(); + $info = $m->getById($userId); + if($info['userPhone']!='')$info['userPhone'] = WSTStrReplace($info['userPhone'],'*',3); + if($info['userEmail']!='')$info['userEmail'] = WSTStrReplace($info['userEmail'],'*',2,'@'); + $this->assign('forgetInfo',$info); + return $this->fetch('forget_pass2'); + }else{ + $this->error('页面已过期!'); + } + } + // 重置密码 + public function resetPass(){ + if(!session('findPass')){ + $this->error('连接已失效!',url('home/users/index')); + } + if(time()>floatval(session('REST_Time'))+30*60)$this->error('连接已失效!'); + return $this->fetch('forget_pass3'); + } + // 验证校验码 + public function forgetPasss(){ + if(!session('findPass')){ + $this->error('连接已失效!'); + } + if(time()>floatval(session('REST_Time'))+30*60)$this->error('连接已失效!'); + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->error('请在同一浏览器操作!'); + } + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->expire('请在同一浏览器操作!'); + } + $uId = session('findPass.userId'); + $key = session("findPass.key"); + // 验证邮箱中的验证码 + $secretCode = input('secretCode'); + if($key==$secretCode){ + session('REST_userId',$uId); + session('REST_success','1'); + return WSTReturn('验证成功',1); + }else{ + return WSTReturn('校验码错误',-1); + } + + } + public function forgetPassf(){ + return $this->fetch('forget_pass4'); + } + /** + * 找回密码 + */ + public function findPass(){ + //禁止缓存 + header('Cache-Control:no-cache,must-revalidate'); + header('Pragma:no-cache'); + $code = input("post.verifyCode"); + $step = input("post.step/d"); + switch ($step) { + case 1:#第一步,验证身份 + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $loginName = input("post.loginName"); + $rs = WSTCheckLoginKey($loginName); + if($rs["status"]==1){ + return WSTReturn("用户名不存在!"); + exit(); + } + $m = new MUsers(); + $info = $m->checkAndGetLoginInfo($loginName); + if ($info != false) { + session('findPass',array('userId'=>$info['userId'],'loginName'=>$loginName,'userPhone'=>$info['userPhone'],'userEmail'=>$info['userEmail'],'loginSecret'=>$info['loginSecret'],'findTime'=>time())); + return WSTReturn("操作成功",1); + }else return WSTReturn("用户名不存在!"); + break; + case 2:#第二步,验证方式 + if (session('findPass.loginName') != null ){ + if(input("post.modes")==1){ + if ( session('findPass.userPhone') == null) { + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = input("post.Checkcode"); + if(!$phoneVerify){ + return WSTReturn('校验码不能为空!',-1); + } + return $this->checkfindPhone($phoneVerify); + }else{ + if (session('findPass.userEmail')==null) { + return WSTReturn('你没有预留邮箱,请通过手机号码找回密码!',-1); + } + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + return $this->getfindEmail(); + } + }else $this->error('页面已过期!'); + break; + case 3:#第三步,设置新密码 + $resetPass = session('REST_success'); + if($resetPass != 1)$this->error("页面已失效!"); + $loginPwd = input("post.loginPwd"); + $repassword = input("post.repassword"); + $decrypt_data = WSTRSA($loginPwd); + $decrypt_data2 = WSTRSA($repassword); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $loginPwd = $decrypt_data['data']; + $repassword = $decrypt_data2['data']; + }else{ + return WSTReturn('设置失败'); + } + if ($loginPwd == $repassword) { + $m = new MUsers(); + $rs = $m->resetPass(); + if($rs['status']==1){ + return $rs; + }else{ + return $rs; + } + }else return WSTReturn('两次密码不同!',-1); + break; + default: + $this->error('页面已过期!'); + break; + } + } + /** + * 手机验证码获取 + */ + public function getfindPhone(){ + session('WST_USER',session('findPass.userId')); + if(session('findPass.userPhone')==''){ + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = rand(100000,999999); + session('WST_USER',null); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,session('findPass.userPhone'),$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + // 记录发送短信的时间,用于验证是否过期 + session('REST_Time',time()); + $USER = []; + $USER['phoneVerify'] = $phoneVerify; + $USER['time'] = time(); + session('findPhone',$USER); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 手机验证码检测 + * -1 错误,1正确 + */ + public function checkfindPhone($phoneVerify){ + if(!session('findPhone.phoneVerify') || time()>floatval(session('findPhone.time'))+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if (session('findPhone.phoneVerify') == $phoneVerify ) { + $fuserId = session('findPass.userId'); + if(!empty($fuserId)){ + session('REST_userId',$fuserId); + session('REST_success','1'); + $rs['status'] = 1; + $rs['url'] = url('home/users/resetPass'); + return $rs; + } + return WSTReturn('无效用户',-1); + } + return WSTReturn('校验码错误!',-1); + } + /** + * 发送验证邮件/找回密码 + */ + public function getfindEmail(){ + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('findPass.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail(session('findPass.userEmail'),'密码重置',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + $uId = session('findPass.userId'); + session("findPass.key", $code); + // 发起重置密码的时间; + session('REST_Time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + + /** + * 加载登录小窗口 + */ + public function toLoginBox(){ + return $this->fetch('box_login'); + } + + /** + * 跳去修改支付密码页 + */ + public function editPayPass(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/security/user_pay_pass'); + } + /** + * 修改支付密码 + */ + public function payPassEdit(){ + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $rs = $m->editPayPass($userId); + return $rs; + } + + /** + * 获取用户金额 + */ + public function getUserMoney(){ + $m = new MUsers(); + $rs = $m->getFieldsById((int)session('WST_USER.userId'),'userMoney,lockMoney,rechargeMoney,payPwd'); + $rs['isSetPayPwd'] = ($rs['payPwd']=='')?0:1; + $rs['isDraw'] = ((float)WSTConf('CONF.drawCashUserLimit')<=$rs['userMoney'])?1:0; + unset($rs['payPwd']); + return WSTReturn('',1,$rs); + } +} + diff --git a/hyhproject/home/model/Articles.php b/hyhproject/home/model/Articles.php new file mode 100755 index 0000000..f3ebbce --- /dev/null +++ b/hyhproject/home/model/Articles.php @@ -0,0 +1,229 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 文章类 + */ +use think\Db; +class Articles extends Base{ + /** + * 获取帮助左侧列表 + */ + public function helpList(){ + $arts = cache('arts'); + if(!$arts){ + $rs = $this->alias('a')->join('article_cats ac','a.catId=ac.catId','inner') + ->field('a.articleId,a.catId,a.articleTitle,ac.catName') + ->where(['a.dataFlag'=>1, + 'a.isshow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>7]) + ->cache(true) + ->select(); + //同一分类下的文章放一起 + $catName = []; + $arts = []; + foreach($rs as $k=>$v){ + if(in_array($v['catName'],$catName)){ + $arts[$v['catName'].'-'.$v['catId']][] = $v; + }else{ + $catName[] = $v['catName']; + $arts[$v['catName'].'-'.$v['catId']][] = $v; + } + } + cache('arts',$arts,86400); + } + return $arts; + } + /** + * 根据id获取帮助文章 + */ + public function getHelpById(){ + $id = (int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + return $this->alias('a')->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner')->where('ac.parentId=7 and a.dataFlag=1 and a.isShow=1')->cache(true)->find($id); + } + /** + * 根据id获取资讯文章 + */ + public function getNewsById($id = 0){ + $id = $id>0?$id:(int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + return $this->alias('a') + ->field('a.*,ac.catName') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where('a.catId<>7 and ac.parentId<>7 and a.dataFlag=1 and a.isShow=1') + ->cache(true) + ->find($id); + } + + /** + * 获取资讯列表【左侧分类】 + */ + public function NewsList(){ + $list = $this->getTree(); + foreach($list as $k=>$v){ + if(!empty($v['children'])){ + foreach($v['children'] as $k1=>$v1){ + // 二级分类下的文章总条数 + $list[$k]['children'][$k1]['newsCount'] = $this->where(['catId'=>$v1['catId'], + 'dataFlag'=>1,'isShow'=>1])->cache(true)->count(); + } + } + } + return $list; + } + + public function getTree(){ + $artTree = cache('artTree'); + if(!$artTree){ + $data = Db::name('article_cats')->field('catName,catId,parentId')->where('parentId <> 7 and catId <> 7 and dataFlag=1 and isShow=1')->cache(true)->select(); + $artTree = $this->_getTree($data, 0); + cache('artTree',$artTree,86400); + } + return $artTree; + } + public function _getTree($data,$parentId){ + $tree = []; + foreach($data as $k=>$v){ + if($v['parentId']==$parentId){ + // 再找其下级分类 + $v['children'] = $this->_getTree($data,$v['catId']); + $tree[] = $v; + } + } + return $tree; + } + /** + * 根据分类id获取文章列表 + */ + public function nList(){ + $catId = (int)input('catId'); + $rs = $this->alias('a') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->field('a.*') + ->where(['a.catId'=>$catId, + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->cache(true) + ->paginate(); + return $rs; + } + /** + * 面包屑导航 + */ + public function bcNav(){ + $catId = (int)input('catId'); //分类id + $artId = (int)input('id'); //文章id + $data = Db::name('article_cats')->field('catId,parentId,catName')->cache(true)->select(); + if($artId){ + $catId = $this->where('articleId',$artId)->value('catId'); + } + $bcNav = $this->getParents($data,$catId,$isClear=true); + return $bcNav; + + } + /** + * 获取父级分类 + */ + public function getParents($data, $catId,$isClear=false){ + static $bcNav = []; + if($isClear) + $bcNav = []; + foreach($data as $k=>$v){ + if($catId == $v['catId']){ + if($catId!=0){ + $this->getParents($data, $v['parentId']); + $bcNav[] = $v; + } + } + } + return $bcNav; + } + + /** + * 记录解决情况 + */ + public function recordSolve(){ + $articleId = (int)input('id'); + $status = (int)input('status'); + if($status==1){ + $rs = $this->where('articleId',$articleId)->setInc('solve'); + }else{ + $rs = $this->where('articleId',$articleId)->setInc('unsolve'); + } + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + + /** + * 获取资讯中心的子集分类id + */ + public function getChildIds(){ + $ids = []; + $data = Db::name('article_cats')->cache(true)->select(); + foreach($data as $k=>$v){ + if($v['parentId']!=7 && $v['catId']!=7 && $v['parentId']!=0 ){ + $ids[] = $v['catId']; + } + } + return $ids; + } + + /** + * 获取咨询中中心所有文章 + */ + public function getArticles(){ + // 获取咨询中心下的所有分类id + $ids = $this->getChildIds(); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>['in',$ids], + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->distinct(true) + ->cache(true) + ->paginate(15); + return $rs; + } + + /** + * 获取指定分类下的文章 + */ + public function getArticlesByCat($catId){ + $ids = $this->getChildIds(); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>['in',$ids], + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->distinct(true) + ->cache(true) + ->select(); + $data = []; + if(!empty($rs)){ + foreach($rs as $key =>$v){ + $data[$v['articleId']] = $v; + } + } + return $data; + } +} diff --git a/hyhproject/home/model/Attributes.php b/hyhproject/home/model/Attributes.php new file mode 100755 index 0000000..1a81880 --- /dev/null +++ b/hyhproject/home/model/Attributes.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\GoodsCats as M; +/** + * ============================================================================ + * 商品属性分类 + */ +class Attributes extends Base{ + /** + * 获取可供筛选的商品属性 + */ + public function listQueryByFilter($catId){ + $m = new M(); + $ids = $m->getParentIs($catId); + if(!empty($ids)){ + $catIds = []; + foreach ($ids as $key =>$v){ + $catIds[] = $v; + } + /*$attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->where(['a.goodsCatId'=>['in',$catIds],'a.isShow'=>1,'a.dataFlag'=>1,'a.attrType'=>['<>',0]]) + ->field('a.attrId,a.attrName,a.attrVal')->order('a.attrSort asc')->select();*/ + + // 取出分类下有设置的属性。 + $attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->field('ga.attrId,GROUP_CONCAT(distinct ga.attrVal) attrVal,a.attrName') + ->where(['a.goodsCatId'=>['in',$catIds],'a.isShow'=>1,'a.dataFlag'=>1,'a.attrType'=>['<>',0]]) + ->group('ga.attrId') + ->order('a.attrSort asc') + ->select(); + foreach ($attrs as $key =>$v){ + $attrs[$key]['attrVal'] = explode(',',$v['attrVal']); + } + return $attrs; + } + return []; + } + /** + * 根据商品id获取可供选择的属性 + */ + public function getAttribute($goodsId){ + if(empty($goodsId))return []; + $attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->field('ga.attrId,GROUP_CONCAT(distinct ga.attrVal) attrVal,a.attrName') + ->where(['ga.goodsId'=>['in',$goodsId], + 'a.isShow'=>1, + 'a.dataFlag'=>1, + 'a.attrType'=>['<>',0]]) + ->group('ga.attrId') + ->order('a.attrSort asc') + ->select(); + if(empty($attrs))return []; + foreach ($attrs as $key =>$v){ + $attrs[$key]['attrVal'] = explode(',',$v['attrVal']); + } + return $attrs; + } +} diff --git a/hyhproject/home/model/Base.php b/hyhproject/home/model/Base.php new file mode 100755 index 0000000..e9fbdc5 --- /dev/null +++ b/hyhproject/home/model/Base.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Base as CBase; +/** + * ============================================================================ + * 基础模型器 + */ + +class Base extends CBase {} \ No newline at end of file diff --git a/hyhproject/home/model/Goods.php b/hyhproject/home/model/Goods.php new file mode 100755 index 0000000..f0f5cee --- /dev/null +++ b/hyhproject/home/model/Goods.php @@ -0,0 +1,1315 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Goods as CGoods; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends CGoods{ + /** + * 上架商品列表 + */ + public function saleByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where = []; + $where['shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName|m.goodsId'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $shopId = (int)session('WST_USER.shopId'); + $where['m.shopId'] = $shopId; + $rs = $this->alias('m')->join('store_recom sr','sr.goodsId=m.goodsId','left') + ->where($where) + ->field('m.goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,sr.storeStatus,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 审核中的商品 + */ + public function auditByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = 0; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + + $rs = $this->alias('m') + ->where($where) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 仓库中的商品 + */ + public function storeByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId']=$shopId; + $where['dataFlag'] = 1; + $where['isSale'] = 0; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $rs = $this->alias('m') + ->where($where) + ->where('goodsStatus','<>',-1) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 违规的商品 + */ + public function illegalByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = -1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + + $rs = $this->alias('m') + ->where($where) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,illegalRemarks,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 违规的商品 + */ + public function limitPriceByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['lp.shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['lp.dataFlag'] = 1; + $where['m.dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $rs = $this->alias('m') + ->join('limit_price lp','lp.goodsId=m.goodsId','left') + ->join('goods_specs gs','gs.id=lp.goodsSpecsId','left') + ->where($where) + ->field('m.goodsId,goodsName,goodsImg,goodsType,goodsStock,specPrice,m.saleNum,limitPrice,lp.productNo,lp.id,shopPrice,from_unixtime(startTime)startTime,from_unixtime(endTime)endTime') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 获取指定对象 + */ + public function getLimitGoods(){ + $id=(int)input('id'); + $obj = null; + if($id>0){ + $obj = Db::name('limit_price')->where(['id'=>$id])->find(); + $obj['startTime']=date('Y-m-d H:i:s',$obj['startTime']); + $obj['endTime']=date('Y-m-d H:i:s',$obj['endTime']); + }else{ + $obj = self::getEModel("limit_price"); + } + return $obj; + } + //获取商品规格 + public function getGoodsSpecs(){ + $productNo = input('productNo'); + $res = db('goods_specs')->where(['productNo'=>$productNo])->field('specIds,marketPrice')->find(); + $specs = explode(':',$res['specIds']); + $data = db('spec_items')->where(['itemId'=>['in',$specs]])->select(); + $rs['itemName'] = implode(',',array_column($data,'itemName')); + $rs['marketPrice'] = $res['marketPrice']; + // echo $rs;die; + //dump($rs);die; + + exit(json_encode($rs)); + + } +// 新增限时价格商品 + public function addLimitGoods(){ + $data=[]; + $data['goodsId']=(int)input('goodsId'); + $data['productNo']=input('productNo'); + $data['limitPrice']=input('limitPrice'); + $data['startTime']=strtotime(input('startTime')); + $data['endTime']=strtotime(input('endTime')); + $data['shopId']=(int)session('WST_USER.shopId'); + //判断商品是否是自己店铺的 + $goods=db('goods')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId']])->find(); + if(!$goods) return WSTReturn('无效商品,请重新选择'); + if($data['limitPrice']<=0) return WSTReturn('商品价格必须大于0'); + $find=db('limit_price')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId'],'productNo'=>$data['productNo'],'dataFlag'=>1])->find(); + if($find) return WSTReturn('此数据已存在',-1); + //dump($data['limitPrice']); + if($data['productNo']){ + $data['specIds']=db('goods_specs')->where(['goodsId'=>$data['goodsId'],'productNo'=>$data['productNo']])->value('specIds'); + $data['goodsSpecsId']=db('goods_specs')->where(['goodsId'=>$data['goodsId'],'productNo'=>$data['productNo']])->value('id'); + } + $result=db('limit_price')->insert($data); + if($result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn("新增失败", -1); + } + } + // 编辑限时价格商品 + public function editLimitGoods(){ + $data=[]; + $data['goodsId']=(int)input('goodsId'); + $data['productNo']=input('productNo'); + $data['limitPrice']=input('limitPrice'); + $data['startTime']=strtotime(input('startTime')); + $data['endTime']=strtotime(input('endTime')); + $data['shopId']=(int)session('WST_USER.shopId'); + $data['id']=(int)input('id'); + //判断商品是否是自己店铺的 + $goods=db('goods')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId']])->find(); + if(!$goods) return WSTReturn('无效商品,请重新选择'); + $data['shopId']=(int)session('WST_USER.shopId'); + if($data['productNo']){ + $data['specIds']=db('goods_specs')->where(['id'=>$data['id'],'productNo'=>$data['productNo']])->value('specIds'); + } + $result=db('limit_price')->where('id',$data['id'])->setField($data); + if($result){ + return WSTReturn("更新成功", 1); + }else{ + return WSTReturn("更新失败", -1); + } + } + //删除限时价格商品 + public function delLimitGoods(){ + $id = (int)input('id/d'); + Db::startTrans(); + try{ + $result = db('limit_price')->where(['id'=>$id])->update(['dataFlag'=>-1]); + if($result){ + Db::commit(); + //标记删除限时价格商品 + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback(); + } + return WSTReturn('删除失败',-1); + } + /** + * 新增商品 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $data = input('post.'); + $specsIds = input('post.specsIds'); + $basicsMoney = isset($data['basicsMoney']) ? $data['basicsMoney'] : 0; + if(!is_numeric($basicsMoney)){ + return WSTReturn("商品成本价请填写数字"); + } + $aloneShop = false;//Db::name('alone_shops')->where(['shopId'=>$shopId,'dataFlag'=>1])->find(); + // if($aloneShop && !$basicsMoney){ + // return WSTReturn("请填写成本价"); + // } + WSTUnset($data,'goodsId,statusRemarks,goodsStatus,dataFlag,basicsMoney'); + if(isset($data['goodsName'])){ + if(!WSTCheckFilterWords($data['goodsName'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品名称包含非法字符"); + } + } + if(isset($data['goodsTips'])){ + if(!WSTCheckFilterWords($data['goodsTips'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品促销信息包含非法字符"); + } + } + if(isset($data['goodsDesc'])){ + if(!WSTCheckFilterWords($data['goodsDesc'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品描述包含非法字符"); + } + } + if(WSTConf("CONF.isGoodsVerify")==1){ + $data['goodsStatus'] = 0; + }else{ + $data['goodsStatus'] = 1; + } + $data['shopId'] = $shopId; + $data['saleTime'] = date('Y-m-d H:i:s'); + $data['createTime'] = date('Y-m-d H:i:s'); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + $data['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + if($data['goodsType']==0){ + $data['isSpec'] = ($specsIds!='')?1:0; + }else{ + $data['isSpec'] = 0; + } + Db::startTrans(); + try{ + //保存插件数据钩子 + hook('beforeEidtGoods',['data'=>&$data]); + + $shop = model('shops')->get($shopId); + if($shop['dataFlag'] ==-1 || $shop['shopStatus'] != 1)$data['isSale'] = 0; + $result = $this->validate(true)->allowField(true)->save($data); + if(false !== $result){ + $goodsId = $this->goodsId; + //ect支付方式 + // $ectPay=(int)input('ectPay'); + // $ect['goodsId']=$goodsId; + // $ect['ectPay']=$ectPay; + // Db::name('goods_pay')->insert($ect); + //商品图片 + WSTUseImages(0, $goodsId, $data['goodsImg']); + //商品相册 + WSTUseImages( 0, $goodsId, $data['gallery']); + //商品描述图片 + WSTEditorImageRocord(0, $goodsId, '',$data['goodsDesc']); + //建立商品评分记录 + $gs = []; + $gs['goodsId'] = $goodsId; + $gs['shopId'] = $shopId; + Db::name('goods_scores')->insert($gs); + //如果是实物商品并且有销售规格则保存销售和规格值 + if($data['goodsType']==0 && $specsIds!=''){ + $specsIds = explode(',',$specsIds); + $specsArray = []; + foreach ($specsIds as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsArray))$specsArray[] = $vv; + } + } + //保存规格名称 + $specMap = []; + foreach ($specsArray as $v){ + $vv = explode('_',$v); + $sitem = []; + $sitem['shopId'] = $shopId; + $sitem['catId'] = (int)$vv[0]; + $sitem['goodsId'] = $goodsId; + $sitem['itemName'] = input('post.specName_'.$vv[0]."_".$vv[1]); + $sitem['itemImg'] = input('post.specImg_'.$vv[0]."_".$vv[1]); + $sitem['dataFlag'] = 1; + $sitem['createTime'] = date('Y-m-d H:i:s'); + $itemId = Db::name('spec_items')->insertGetId($sitem); + if($sitem['itemImg']!='')WSTUseImages(0, $itemId, $sitem['itemImg']); + $specMap[$v] = $itemId; + } + //保存销售规格 + $defaultPrice = 0;//最低价 + $totalStock = 0;//总库存 + $gspecArray = []; + $isFindDefaultSpec = false; + $defaultSpec = Input('post.defaultSpec'); + foreach ($specsIds as $v){ + $vs = explode('-',$v); + $goodsSpecIds = []; + foreach ($vs as $gvs){ + $goodsSpecIds[] = $specMap[$gvs]; + } + $gspec = []; + $gspec['specIds'] = implode(':',$goodsSpecIds); + $gspec['shopId'] = $shopId; + $gspec['goodsId'] = $goodsId; + $gspec['productNo'] = Input('productNo_'.$v); + $gspec['marketPrice'] = (float)Input('marketPrice_'.$v); + $gspec['specPrice'] = (float)Input('specPrice_'.$v); + $gspec['specStock'] = (int)Input('specStock_'.$v); + $gspec['warnStock'] = (int)Input('warnStock_'.$v); + //设置默认规格 + if($defaultSpec==$v){ + $isFindDefaultSpec = true; + $defaultPrice = $gspec['specPrice']; + $gspec['isDefault'] = 1; + }else{ + $gspec['isDefault'] = 0; + } + $gspecArray[] = $gspec; + //获取总库存 + $totalStock = $totalStock + $gspec['specStock']; + } + if(!$isFindDefaultSpec)return WSTReturn("请选择推荐规格"); + if(count($gspecArray)>0){ + Db::name('goods_specs')->insertAll($gspecArray); + //更新默认价格和总库存 + $this->where('goodsId',$goodsId)->update(['isSpec'=>1,'shopPrice'=>$defaultPrice,'goodsStock'=>$totalStock]); + } + } + //保存商品属性 + $attrsArray = []; + $attrRs = Db::name('attributes')->where(['goodsCatId'=>['in',$goodsCats],'isShow'=>1,'dataFlag'=>1]) + ->field('attrId')->select(); + foreach ($attrRs as $key =>$v){ + $attrs = []; + $attrs['attrVal'] = input('attr_'.$v['attrId']); + if($attrs['attrVal']=='')continue; + $attrs['shopId'] = $shopId; + $attrs['goodsId'] = $goodsId; + $attrs['attrId'] = $v['attrId']; + $attrs['createTime'] = date('Y-m-d H:i:s'); + $attrsArray[] = $attrs; + } + if(count($attrsArray)>0)Db::name('goods_attributes')->insertAll($attrsArray); + + + if($aloneShop){ + //保存商品成本价 + $basicsArray = []; + $now = time(); + $basicsArray['shopId'] = $shopId; + $basicsArray['goodsId'] = $goodsId; + $basicsArray['basicsMoney'] = $basicsMoney; + $basicsArray['createTime'] = $now; + Db::name('alone_goods')->insert($basicsArray); + } + hook('afterGoodsEct',['data'=>&$data,'goodsId'=>$goodsId]); + Db::commit(); + return WSTReturn("新增成功", 1,['id'=>$goodsId]); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback(); + return WSTReturn('新增失败',-1); + } + } + + /** + * 编辑商品资料 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $goodsId = input('post.goodsId/d'); + $specsIds = input('post.specsIds'); + $data = input('post.'); + $basicsMoney = isset($data['basicsMoney']) ? $data['basicsMoney'] : 0; + if(!is_numeric($basicsMoney)){ + return WSTReturn("商品成本价请填写数字"); + } + $aloneShop = false;//Db::name('alone_shops')->where(['shopId'=>$shopId,'dataFlag'=>1])->find(); + // if($aloneShop && !$basicsMoney){ + // return WSTReturn("请填写成本价"); + //} + WSTUnset($data,'goodsId,dataFlag,statusRemarks,goodsStatus,createTime,basicsMoney'); + $ogoods = $this->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'dataFlag'=>1])->field('goodsStatus,goodsType')->find(); + if(empty($ogoods))return WSTReturn('商品不存在'); + if(isset($data['goodsName'])){ + if(!WSTCheckFilterWords($data['goodsName'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品名称包含非法字符"); + } + } + if(isset($data['goodsTips'])){ + if(!WSTCheckFilterWords($data['goodsTips'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品促销信息包含非法字符"); + } + } + if(isset($data['goodsDesc'])){ + if(!WSTCheckFilterWords($data['goodsDesc'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品描述包含非法字符"); + } + } + //违规商品不能直接上架 + if($ogoods['goodsStatus']!=1){ + $data['goodsStatus'] = 0; + } + //不允许修改商品类型 + $data['goodsType'] = $ogoods['goodsType']; + $data['saleTime'] = date('Y-m-d H:i:s'); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + $data['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + if($data['goodsType']==0){ + $data['isSpec'] = ($specsIds!='')?1:0; + }else{ + $data['isSpec'] = 0; + } + Db::startTrans(); + try{ + //保存插件数据钩子 + hook('beforeEidtGoods',['data'=>&$data]); + + //商品图片 + WSTUseImages(0, $goodsId, $data['goodsImg'],'goods','goodsImg'); + //商品相册 + WSTUseImages(0, $goodsId, $data['gallery'],'goods','gallery'); + // 商品描述图片 + $desc = $this->where('goodsId',$goodsId)->value('goodsDesc'); + WSTEditorImageRocord(0, $goodsId, $desc, $data['goodsDesc']); + $shop = model('shops')->get($shopId); + if($shop['dataFlag'] ==-1 || $shop['shopStatus'] != 1)$data['isSale'] = 0; + //虚拟商品处理 + if($data['goodsType']==1){ + $counts = Db::name('goods_virtuals')->where(['dataFlag'=>1,'isUse'=>0,'goodsId'=>$goodsId])->Count(); + $data['goodsStock'] = $counts; + } + $result = $this->validate(true)->allowField(true)->save($data,['goodsId'=>$goodsId]); + if(false !== $result){ + //ect支付方式 + $ectPay=(int)input('ectPay'); + $findEct=db('goods_pay')->where('goodsId',$goodsId)->find(); + if($findEct){ + db('goods_pay')->where('goodsId',$goodsId)->update(['ectPay'=>$ectPay]); + }else{ + db('goods_pay')->insert(['goodsId'=>$goodsId,'ectPay'=>$ectPay]); + } + + /** + * 编辑的时候如果不想影响商品销售规格的销量,那么就要在保存的时候区别对待已经存在的规格和销售规格记录。 + * $specNameMap的保存关系是:array('页面上生成的规格值ID'=>数据库里规则值的ID) + * $specIdMap的保存关系是:array('页面上生成的销售规格ID'=>数据库里销售规格ID) + */ + $specNameMapTmp = explode(',',input('post.specmap')); + $specIdMapTmp = explode(',',input('post.specidsmap')); + $specNameMap = [];//规格值对应关系 + $specIdMap = [];//规格和表对应关系 + foreach ($specNameMapTmp as $key =>$v){ + if($v=='')continue; + $v = explode(':',$v); + $specNameMap[$v[1]] = $v[0]; //array('页面上的规则值ID'=>数据库里规则值的ID) + } + foreach ($specIdMapTmp as $key =>$v){ + if($v=='')continue; + $v = explode(':',$v); + $specIdMap[$v[1]] = $v[0]; //array('页面上的销售规则ID'=>数据库里销售规格ID) + } + //如果是实物商品并且有销售规格则保存销售和规格值 + if($data['goodsType'] ==0 && $specsIds!=''){ + //把之前之前的销售规格 + $specsIds = explode(',',$specsIds); + $specsArray = []; + foreach ($specsIds as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsArray))$specsArray[] = $vv;//过滤出不重复的规格值 + } + } + //先标记作废之前的规格值 + Db::name('spec_items')->where(['shopId'=>$shopId,'goodsId'=>$goodsId])->update(['dataFlag'=>-1]); + //保存规格名称 + $specMap = []; + foreach ($specsArray as $v){ + $vv = explode('_',$v); + $specNumId = $vv[0]."_".$vv[1]; + $sitem = []; + $sitem['itemName'] = input('post.specName_'.$specNumId); + $sitem['itemImg'] = input('post.specImg_'.$specNumId); + //如果已经存在的规格值则修改,否则新增 + if(isset($specNameMap[$specNumId]) && (int)$specNameMap[$specNumId]!=0){ + $sitem['dataFlag'] = 1; + WSTUseImages(0, (int)$specNameMap[$specNumId], $sitem['itemImg'],'spec_items','itemImg'); + Db::name('spec_items')->where(['shopId'=>$shopId,'itemId'=>(int)$specNameMap[$specNumId]])->update($sitem); + $specMap[$v] = (int)$specNameMap[$specNumId]; + }else{ + $sitem['goodsId'] = $goodsId; + $sitem['shopId'] = $shopId; + $sitem['catId'] = (int)$vv[0]; + $sitem['dataFlag'] = 1; + $sitem['createTime'] = date('Y-m-d H:i:s'); + $itemId = Db::name('spec_items')->insertGetId($sitem); + if($sitem['itemImg']!='')WSTUseImages(0, $itemId, $sitem['itemImg']); + $specMap[$v] = $itemId; + } + } + //删除已经作废的规格值 + Db::name('spec_items')->where(['shopId'=>$shopId,'goodsId'=>$goodsId,'dataFlag'=>-1])->delete(); + //保存销售规格 + $defaultPrice = 0;//默认价格 + $totalStock = 0;//总库存 + $gspecArray = []; + //把之前的销售规格值标记删除 + Db::name('goods_specs')->where(['goodsId'=>$goodsId,'shopId'=>$shopId])->update(['dataFlag'=>-1,'isDefault'=>0]); + $isFindDefaultSpec = false; + $defaultSpec = Input('post.defaultSpec'); + foreach ($specsIds as $v){ + $vs = explode('-',$v); + $goodsSpecIds = []; + foreach ($vs as $gvs){ + $goodsSpecIds[] = $specMap[$gvs]; + } + $gspec = []; + $gspec['specIds'] = implode(':',$goodsSpecIds); + $gspec['productNo'] = Input('productNo_'.$v); + $gspec['marketPrice'] = (float)Input('marketPrice_'.$v); + $gspec['specPrice'] = (float)Input('specPrice_'.$v); + $gspec['initNum'] = (int)Input('initNum_'.$v);//添加起批价数量 mark hsf 20171117 + $gspec['whslePrice'] = (float)Input('whslePrice_'.$v);//添加批发价 mark hsf 20171117 + $gspec['specStock'] = (int)Input('specStock_'.$v); + $gspec['warnStock'] = (int)Input('warnStock_'.$v); + //设置默认规格 + if($defaultSpec==$v){ + $gspec['isDefault'] = 1; + $isFindDefaultSpec = true; + $defaultPrice = $gspec['specPrice']; + }else{ + $gspec['isDefault'] = 0; + } + //如果是已经存在的值就修改内容,否则新增 + if(isset($specIdMap[$v]) && $specIdMap[$v]!=''){ + $gspec['dataFlag'] = 1; + Db::name('goods_specs')->where(['shopId'=>$shopId,'id'=>(int)$specIdMap[$v]])->update($gspec); + }else{ + $gspec['shopId'] = $shopId; + $gspec['goodsId'] = $goodsId; + $gspecArray[] = $gspec; + } + //获取总库存 + $totalStock = $totalStock + $gspec['specStock']; + } + if(!$isFindDefaultSpec)return WSTReturn("请选择推荐规格"); + //删除作废的销售规格值 + Db::name('goods_specs')->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'dataFlag'=>-1])->delete(); + if(count($gspecArray)>0){ + Db::name('goods_specs')->insertAll($gspecArray); + } + //更新推荐规格和总库存 + $this->where('goodsId',$goodsId)->update(['isSpec'=>1,'shopPrice'=>$defaultPrice,'goodsStock'=>$totalStock]); + } + //保存商品属性 + //删除之前的商品属性 + Db::name('goods_attributes')->where(['goodsId'=>$goodsId,'shopId'=>$shopId])->delete(); + //新增商品属性 + $attrsArray = []; + $attrRs = Db::name('attributes')->where(['goodsCatId'=>['in',$goodsCats],'isShow'=>1,'dataFlag'=>1]) + ->field('attrId')->select(); + foreach ($attrRs as $key =>$v){ + $attrs = []; + $attrs['attrVal'] = input('attr_'.$v['attrId']); + if($attrs['attrVal']=='')continue; + $attrs['shopId'] = $shopId; + $attrs['goodsId'] = $goodsId; + $attrs['attrId'] = $v['attrId']; + $attrs['createTime'] = date('Y-m-d H:i:s'); + $attrsArray[] = $attrs; + } + if(count($attrsArray)>0)Db::name('goods_attributes')->insertAll($attrsArray); + //删除购物车里的商品 + model('common/carts')->delCartByUpdate($goodsId); + //修改商品成本价 + + if($aloneShop){ + $now = time(); + if(Db::name('alone_goods')->where(['goodsId'=>$goodsId])->find()){ + Db::name('alone_goods')->where(['shopId'=>$shopId,'goodsId'=>$goodsId])->update(['basicsMoney'=>$basicsMoney,'updateTime'=>$now]); + }else{ + Db::name('alone_goods')->insert(['shopId'=>$shopId,'goodsId'=>$goodsId,'basicsMoney'=>$basicsMoney,'createTime'=>$now,'updateTime'=>$now]); + } + + } + //商品编辑之后执行 + hook('afterEditGoods',['goodsId'=>$goodsId]); + hook('afterChangeGoodsStatus',['goodsId'=>$goodsId]); + hook('afterGoodsEct',['data'=>&$data,'goodsId'=>$goodsId]); + Db::commit(); + return WSTReturn("编辑成功", 1,['id'=>$goodsId]); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback(); + dump($e); + return WSTReturn('编辑失败',-1); + } + } + + /** + * 获取商品资料方便编辑 + */ + public function getById($goodsId){ + $rs = $this->alias('g')->where(['g.shopId'=>(int)session('WST_USER.shopId'),'g.goodsId'=>$goodsId])->field('g.*')->find(); + isset($rs['basicsMoney']) ? $rs['basicsMoney'] : $rs['basicsMoney'] = ''; + if(!empty($rs)){ + if($rs['gallery']!='')$rs['gallery'] = explode(',',$rs['gallery']); + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + $spec0 = []; + $spec1 = []; + foreach ($specs as $key =>$v){ + if($v['isAllowImg']==1){ + $spec0[] = $v; + }else{ + $spec1[] = $v; + } + } + $rs['spec0'] = $spec0; + $rs['spec1'] = $spec1; + //获取销售规格 + $rs['saleSpec'] = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,initNum,whslePrice,specStock,warnStock,saleNum')->select(); + // print_r($rs);die; + // $rs['saleSpec'][0]['ectPrice'] = ($specPrice * '0.95'); + //获取属性值 + $rs['attrs'] = Db::name('goods_attributes')->alias('ga')->join('attributes a','ga.attrId=a.attrId','inner') + ->where('goodsId',$goodsId)->field('ga.attrId,a.attrType,ga.attrVal')->select(); + $rs['ectPay']=Db::name('goods')->alias('g')->join('goods_pay ge','ge.goodsId=g.goodsId','left')->where('g.goodsId',$goodsId)->value('ectPay'); + // echo $specPrice;die; + } + return $rs; + } + /** + * 获取商品资料在前台展示 + */ + public function getBySale($goodsId){ + $key = input('key'); + // 浏览量 + $this->where('goodsId',$goodsId)->setInc('visitNum',1); + $rs = Db::name('goods')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->find(); + if(!empty($rs)){ + $rs['read'] = false; + //判断是否可以公开查看 + $viKey = WSTShopEncrypt($rs['shopId']); + if(($rs['isSale']==0 || $rs['goodsStatus']==0) && $viKey != $key)return []; + if($key!='')$rs['read'] = true; + //获取店铺信息 + $rs['shop'] = model('shops')->getBriefShop((int)$rs['shopId']); + if(empty($rs['shop']))return []; + $gallery = []; + $gallery[] = $rs['goodsImg']; + if($rs['gallery']!=''){ + $tmp = explode(',',$rs['gallery']); + $gallery = array_merge($gallery,$tmp); + } + $rs['gallery'] = $gallery; + if($rs['isSpec']==1){ + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,gc.catName,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + foreach ($specs as $key =>$v){ + $rs['spec'][$v['catId']]['name'] = $v['catName']; + $rs['spec'][$v['catId']]['list'][] = $v; + } + + //获取销售规格 + $sales = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,specStock')->select(); + if(!empty($sales)){ + foreach ($sales as $key =>$v){ + $str = explode(':',$v['specIds']); + sort($str); + unset($v['specIds']); + $rs['saleSpec'][implode(':',$str)] = $v; + if($v['isDefault']==1)$rs['defaultSpecs'] = $v; + } + } + } + //获取商品属性 + $rs['attrs'] = Db::name('attributes')->alias('a')->join('goods_attributes ga','a.attrId=ga.attrId','inner') + ->where(['a.isShow'=>1,'dataFlag'=>1,'goodsId'=>$goodsId])->field('a.attrName,ga.attrVal') + ->order('attrSort asc')->select(); + //获取商品评分 + $rs['scores'] = Db::name('goods_scores')->where('goodsId',$goodsId)->field('totalScore,totalUsers')->find(); + $rs['scores']['totalScores'] = ($rs['scores']['totalScore']==0)?5:WSTScore($rs['scores']['totalScore'],$rs['scores']['totalUsers'],5,0,3); + WSTUnset($rs, 'totalUsers'); + //品牌名称 + $rs['brandName'] = Db::name('brands')->where(['brandId'=>$rs['brandId']])->value('brandName'); + //关注 + $f = model('Favorites'); + $rs['favShop'] = $f->checkFavorite($rs['shopId'],1); + $rs['favGood'] = $f->checkFavorite($goodsId,0); + } + return $rs; + } + + /** + * 删除商品 + */ + public function del(){ + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $result = $this->update($data,['goodsId'=>$id]); + if(false !== $result){ + WSTUnuseImage('goods','goodsImg',$id); + WSTUnuseImage('goods','gallery',$id); + // 商品描述图片 + $desc = $this->where('goodsId',$id)->value('goodsDesc'); + WSTEditorImageRocord(0, $id, $desc,''); + model('common/carts')->delCartByUpdate($id); + hook('afterChangeGoodsStatus',['goodsId'=>$id]); + Db::commit(); + //标记删除购物车 + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback(); + } + return WSTReturn('删除失败',-1); + } + /** + * 批量删除商品 + */ + public function batchDel(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('post.ids/a'); + Db::startTrans(); + try{ + $rs = $this->where(['goodsId'=>['in',$ids], + 'shopId'=>$shopId])->setField('dataFlag',-1); + if(false !== $rs){ + //标记删除购物车 + foreach ($ids as $v){ + WSTUnuseImage('goods','goodsImg',(int)$v); + WSTUnuseImage('goods','gallery',(int)$v); + // 商品描述图片 + $desc = $this->where('goodsId',(int)$v)->value('goodsDesc'); + WSTEditorImageRocord(0, (int)$v, $desc,''); + model('common/carts')->delCartByUpdate((int)$v); + hook('afterChangeGoodsStatus',['goodsId'=>(int)$v]); + } + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback(); + } + return WSTReturn('删除失败',-1); + } + + /** + * 批量上架商品 + */ + public function changeSale(){ + $ids = input('post.ids/a'); + $isSale = (int)input('post.isSale',1); + $shopId = (int)session('WST_USER.shopId'); + //判断商品是否满足上架要求 + if($isSale==1){ + //0.核对店铺状态 + $shopRs = model('shops')->find($shopId); + if($shopRs['shopStatus']!=1 || $shopRs['dataFlag']==-1){ + return WSTReturn('上架商品失败!您的店铺权限不能出售商品,如有疑问请与商城管理员联系。',-3); + } + //直接设置上架 返回受影响条数 + $where = []; + $where['g.goodsId'] = ['in',$ids]; + $where['gc.dataFlag'] = 1; + $where['g.shopId'] = $shopId; + $where['gc.isShow'] = 1; + $where['g.goodsImg'] = ['<>',""]; + $rs = $this->alias('g') + ->join('__GOODS_CATS__ gc','g.goodsCatId=gc.CatId','inner') + ->where($where)->setField('isSale',1); + if($rs!==false){ + //执行钩子事件 + foreach ($ids as $key => $gid) { + hook('afterChangeGoodsStatus',['goodsId'=>$gid]); + } + $status = ($rs==count($ids))?1:2; + if($status==1){ + return WSTReturn('商品上架成功', 1,['num'=>$rs]); + }else{ + return WSTReturn('已成功上架商品'.$rs.'件,请核对未能上架的商品信息是否完整。', 2,['num'=>$rs]); + } + }else{ + return WSTReturn('上架失败,请核对商品信息是否完整!', -2); + } + + }else{ + $rs = $this->where(['goodsId'=>['in',$ids],'shopId'=>$shopId])->setField('isSale',0); + if($rs !== false){ + //执行钩子事件 + foreach ($ids as $key => $gid) { + hook('afterChangeGoodsStatus',['goodsId'=>$gid]); + } + model('common/carts')->delCartByUpdate($ids); + return WSTReturn('商品上架成功', 1); + }else{ + return WSTReturn($this->getError(), -1); + } + } + } + /** + * 修改商品状态 + */ + public function changSaleStatus(){ + $shopId = (int)session('WST_USER.shopId'); + $allowArr = ['isHot','isNew','isBest','isRecom','storeRecom']; + $is = input('post.is'); + if(!in_array($is,$allowArr))return WSTReturn('非法操作',-1); + $status = (input('post.status',1)==1)?0:1; + $id = (int)input('post.id'); + $rs = $this->where(["shopId"=>$shopId,'goodsId'=>$id])->setField($is,$status); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 修改商品状态 + */ + public function changStoreRecom(){ + $status = (input('post.status',1)==1)?0:1; + $id = (int)input('post.id'); + $rs = db('store_recom')->where(['goodsId'=>$id])->update(['storeStatus'=>$status]); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 批量修改商品状态 + */ + public function changeGoodsStatus(){ + $shopId = (int)session('WST_USER.shopId'); + //设置为什么 hot new best rec + $allowArr = ['isHot','isNew','isBest','isRecom','storeRecom']; + $is = input('post.is'); + if(!in_array($is,$allowArr))return WSTReturn('非法操作',-1); + //设置哪一个状态 + $status = input('post.status',1); + $ids = input('post.ids/a'); + $rs = $this->where(['goodsId'=>['in',$ids],'shopId'=>$shopId])->setField($is, $status); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + + } + /** + * 批量修改商品 店长推荐 + */ + public function changeStoreStatus(){ + $ids=input('post.ids/a'); + $find = db('store_recom')->where(['goodsId'=>['in',$ids]])->column('goodsId'); + Db::startTrans(); + try{ + if(!$find){ + foreach($ids as $k=>$v){ + $info=[]; + $info['goodsId']=$v; + $info['storeStatus']= input('post.status',1); + //dump($info); + $data[]=$info; + } + $rs=db('store_recom')->insertAll($data); + } + if($find){ + foreach($find as $k=>$v){ + $rs=db('store_recom')->where('goodsId',$v)->update(['storeStatus'=>input('post.status',1)]); + } + $another=array_diff($ids,$find); + if(count($another)>0){ + foreach($another as $k=>$v){ + $info=[]; + $info['goodsId']=$v; + $info['storeStatus']= input('post.status',1); + //dump($info); + $data[]=$info; + } + $rs=db('store_recom')->insertAll($data); + } + + } + Db::commit(); + return WSTReturn("设置成功", 1); + }catch (\Exception $e) { + Db::rollback(); + } + } + /** + * 获取商品规格属性 + */ + public function getSpecAttrs(){ + $goodsType = (int)input('goodsType'); + $goodsCatId = Input('post.goodsCatId/d'); + $goodsCatIds = model('GoodsCats')->getParentIs($goodsCatId); + $data = []; + if($goodsType==0){ + $specs = Db::name('spec_cats')->where(['dataFlag'=>1,'isShow'=>1,'goodsCatId'=>['in',$goodsCatIds]])->field('catId,catName,isAllowImg')->order('isAllowImg desc,catSort asc,catId asc')->select(); + $spec0 = null; + $spec1 = []; + foreach ($specs as $key => $v){ + if($v['isAllowImg']==1){ + $spec0 = $v; + }else{ + $spec1[] = $v; + } + } + $data['spec0'] = $spec0; + $data['spec1'] = $spec1; + } + $data['attrs'] = Db::name('attributes')->where(['dataFlag'=>1,'isShow'=>1,'goodsCatId'=>['in',$goodsCatIds]])->field('attrId,attrName,attrType,attrVal')->order('attrSort asc,attrId asc')->select(); + return WSTReturn("", 1,$data); + } + + /** + * 检测商品主表的货号或者商品编号 + */ + public function checkExistGoodsKey($key,$val,$id = 0){ + if(!in_array($key,array('goodsSn','productNo')))return WSTReturn("非法的查询字段"); + $conditon = [$key=>$val]; + if($id>0)$conditon['goodsId'] = ['<>',$id]; + $rs = $dbo = $this->where($conditon)->count(); + return ($rs==0)?false:true; + } + + /** + * 获取符合筛选条件的商品ID + */ + public function filterByAttributes(){ + $vs = input('vs'); + if($vs=='')return []; + $vs = explode(',',$vs); + $goodsIds = []; + $prefix = config('database.prefix'); + //循环遍历每个属性相关的商品ID + foreach ($vs as $v){ + $goodsIds2 = []; + $attrVal = input('v_'.(int)$v); + if($attrVal=='')continue; + if(stristr($attrVal,'、')!==false){ + // 同属性多选 + $attrArr = explode('、',$attrVal); + foreach($attrArr as $v1){ + $sql = "select goodsId from ".$prefix."goods_attributes where attrId=".(int)$v." and find_in_set('".$v1."',attrVal) "; + $rs = Db::query($sql); + if(!empty($rs)){ + foreach ($rs as $vg){ + $goodsIds2[] = $vg['goodsId']; + } + } + } + }else{ + $sql = "select goodsId from ".$prefix."goods_attributes + where attrId=".(int)$v." and find_in_set('".$attrVal."',attrVal) "; + $rs = Db::query($sql); + if(!empty($rs)){ + foreach ($rs as $vg){ + $goodsIds2[] = $vg['goodsId']; + } + } + } + //如果有一个属性是没有商品的话就不需要查了 + if(empty($goodsIds2))return [-1]; + //第一次比较就先过滤,第二次以后的就找集合 + $goodsIds2[] = -1; + if(empty($goodsIds)){ + $goodsIds = $goodsIds2; + }else{ + $goodsIds = array_intersect($goodsIds,$goodsIds2); + } + } + return $goodsIds; + } + + /** + * 获取分页商品记录 + */ + public function pageQuery($goodsCatIds = []){ + //查询条件 + $isStock = input('isStock/d'); + $isNew = input('isNew/d'); + $isFreeShipping = input('isFreeShipping/d'); + $keyword = input('keyword'); + $where = $where2 = $where3 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $where['goodsCatIdPath']=['notlike','389'.'%']; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + //属性筛选 + $goodsIds = $this->filterByAttributes(); + if(!empty($goodsIds))$where['goodsId'] = ['in',$goodsIds]; + // 品牌筛选 + $brandIds = input('param.brand'); + if(!empty($brandIds)){ + $brandIds = explode(',',$brandIds); + $where['brandId'] = ['in',$brandIds]; + } + + // 发货地 + $areaId = (int)input('areaId'); + if($areaId>0)$where['areaId'] = $areaId; + //排序条件 + $orderBy = input('orderBy/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + //默认销量从高到低排序, mark by cheng 20130317 + $order = (input('order/d',1)==1)?1:0; + $pageBy = ['saleNum','shopPrice','appraiseNum','visitNum','saleTime']; + $pageOrder = ['asc','desc']; + if($isStock==1)$where['goodsStock'] = ['>',0]; + if($isNew==1)$where['isNew'] = ['=',1]; + if($isFreeShipping==1)$where['isFreeShipping'] = 1; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $sprice = input("param.sprice");//开始价格 + $eprice = input("param.eprice");//结束价格 + if($sprice!='' && $eprice!=''){ + $where['g.shopPrice'] = ['between',[(int)$sprice,(int)$eprice]]; + }elseif($sprice!=''){ + $where['g.shopPrice'] = [">=",(int)$sprice]; + }elseif($eprice!=''){ + $where['g.shopPrice'] = ["<=",(int)$eprice]; + } + $list = Db::name("goods")->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId") + ->where($where) + ->field('goodsId,goodsName,goodsSn,goodsStock,isNew,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pagesize/d',16))->toArray(); + //加载标签 + if(!empty($list['Rows'])){ + foreach ($list['Rows'] as $key => $v) { + $list['Rows'][$key]['tags'] = []; + if($v['isSelf']==1)$list['Rows'][$key]['tags'][] = "<span class='tag'>自营</span>"; + if($v['isFreeShipping']==1)$list['Rows'][$key]['tags'][] = "<span class='tag'>包邮</span>"; + } + } + //关注 + if($list['Rows']){ + foreach ($list['Rows'] as $key =>$v){ + $list['Rows'][$key]['favGood'] = model('Favorites')->checkFavorite($v['goodsId'],0); + } + } + hook('afterQueryGoods',['page'=>&$list]); + return $list; + } + /** + * 获取价格范围 + */ + public function getPriceGrade($goodsCatIds = []){ + $isStock = input('isStock/d'); + $isNew = input('isNew/d'); + $keyword = input('keyword'); + $isFreeShipping = input('isFreeShipping/d'); + $where = $where2 = $where3 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + $areaId = (int)input('areaId'); + if($areaId>0)$where['areaId'] = $areaId; + //属性筛选 + $goodsIds = $this->filterByAttributes(); + if(!empty($goodsIds))$where['goodsId'] = ['in',$goodsIds]; + //排序条件 + $orderBy = input('orderBy/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('order/d',0)==1)?1:0; + $pageBy = ['saleNum','shopPrice','appraiseNum','visitNum','saleTime']; + $pageOrder = ['asc','desc']; + if($isStock==1)$where['goodsStock'] = ['>',0]; + if($isNew==1)$where['isNew'] = ['=',1]; + if($isFreeShipping==1)$where['isFreeShipping'] = 1; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $sprice = input("param.sprice");//开始价格 + $eprice = input("param.eprice");//结束价格 + if($sprice!='' && $eprice!=''){ + $where['g.shopPrice'] = ['between',[(int)$sprice,(int)$eprice]]; + }elseif($sprice!=''){ + $where['g.shopPrice'] = [">=",(int)$sprice]; + }elseif($eprice!=''){ + $where['g.shopPrice'] = ["<=",(int)$eprice]; + } + $rs = Db::name("goods")->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId",'inner') + ->where($where) + ->field('min(shopPrice) minPrice,max(shopPrice) maxPrice')->find(); + + if($rs['maxPrice']=='')return; + $minPrice = 0; + $maxPrice = $rs['maxPrice']; + $pavg5 = ($maxPrice/5); + $prices = array(); + $price_grade = 0.0001; + for($i=-2; $i<= log10($maxPrice); $i++){ + $price_grade *= 10; + } + //区间跨度 + $span = ceil(($maxPrice - $minPrice) / 8 / $price_grade) * $price_grade; + if($span == 0){ + $span = $price_grade; + } + for($i=1;$i<=8;$i++){ + $prices[($i-1)*$span."_".($span * $i)] = ($i-1)*$span."-".($span * $i); + if(($span * $i)>$maxPrice) break; + } + + return $prices; + } + + /** + * 修改商品库存/价格 + */ + public function editGoodsBase(){ + $goodsId = (int)Input("goodsId"); + $post = input('post.'); + $data = []; + if(isset($post['goodsStock'])){ + $data['goodsStock'] = (int)input('post.goodsStock',0); + if($data['goodsStock']<0)return WSTReturn('操作失败,库存不能为负数'); + }elseif(isset($post['shopPrice'])){ + $data['shopPrice'] = (float)input('post.shopPrice',0); + if($data['shopPrice']<0.01)return WSTReturn('操作失败,价格必须大于0.01'); + }else{ + return WSTReturn('操作失败',-1); + } + $rs = $this->update($data,['goodsId'=>$goodsId,'shopId'=>(int)session('WST_USER.shopId')]); + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + /** + * 预警库存列表 + */ + public function stockByPage(){ + $where = []; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $shopId = (int)session('WST_USER.shopId'); + if($c1Id!=0)$where[] = " shopCatId1=".$c1Id; + if($c2Id!=0)$where[] = " shopCatId2=".$c2Id; + $where[] = " g.shopId = ".$shopId; + $prefix = config('database.prefix'); + $sql1 = 'SELECT g.goodsId,g.goodsName,g.goodsType,g.goodsImg,gs.specStock goodsStock ,gs.warnStock warnStock,g.isSpec,gs.productNo,gs.id,gs.specIds,g.isSale + FROM '.$prefix.'goods g inner JOIN '.$prefix.'goods_specs gs ON gs.goodsId=g.goodsId and gs.specStock <= gs.warnStock and gs.warnStock>0 + WHERE g.dataFlag = 1 and '.implode(' and ',$where); + + $sql2 = 'SELECT g.goodsId,g.goodsName,g.goodsType,g.goodsImg,g.goodsStock,g.warnStock,g.isSpec,g.productNo,0 as id,"" as specIds,g.isSale + FROM '.$prefix.'goods g + WHERE g.dataFlag = 1 and isSpec=0 and g.goodsStock<=g.warnStock + and g.warnStock>0 and '.implode(' and ',$where); + $page = (int)input('post.'.config('paginate.var_page')); + $page = ($page<=0)?1:$page; + $pageSize = 15; + $start = ($page-1)*$pageSize; + $sql = $sql1." union ".$sql2; + $sqlNum = 'select count(*) wstNum from ('.$sql.") as c"; + $sql = 'select * from ('.$sql.') as c order by isSale desc limit '.$start.','.$pageSize; + $rsNum = Db::query($sqlNum); + $rsRows = Db::query($sql); + $rs = WSTPager((int)$rsNum[0]['wstNum'],$rsRows,$page,$pageSize); + if(empty($rs['Rows']))return $rs; + $specIds = []; + foreach ($rs['Rows'] as $key =>$v){ + $specIds[$key] = explode(':',$v['specIds']); + $rss = Db::name('spec_items')->alias('si') + ->join('__SPEC_CATS__ sc','sc.catId=si.catId','left') + ->where('si.shopId = '.$shopId.' and si.goodsId = '.$v['goodsId']) + ->where('si.itemId','in',$specIds[$key]) + ->field('si.itemId,si.itemName,sc.catId,sc.catName') + ->select(); + $rs['Rows'][$key]['spec'] = $rss; + } + return $rs; + } + /** + * 预警修改预警库存 + */ + public function editwarnStock(){ + $id = input('post.id/d'); + $type = input('post.type/d'); + $number = (int)input('post.number'); + $shopId = (int)session('WST_USER.shopId'); + $data = $data2 = []; + $data['shopId'] = $data2['shopId'] = $shopId; + $datat=array('1'=>'specStock','2'=>'warnStock','3'=>'goodsStock','4'=>'warnStock'); + if(!empty($type)){ + $data[$datat[$type]] = $number; + if($type==1 || $type==2){ + $data['goodsId'] = $goodsId = input('post.goodsId/d'); + $rss = Db::name("goods_specs")->where('id', $id)->update($data); + //更新商品库存 + $goodsStock = 0; + if($rss!==false){ + $specStocks = Db::name("goods_specs")->where(['shopId'=>$shopId,'goodsId'=>$goodsId,'dataFlag'=>1])->field('specStock')->select(); + foreach ($specStocks as $key =>$v){ + $goodsStock = $goodsStock+$v['specStock']; + } + $data2['goodsStock'] = $goodsStock; + $rs = $this->update($data2,['goodsId'=>$goodsId]); + }else{ + return WSTReturn('操作失败',-1); + } + } + if($type==3 || $type==4){ + $rs = $this->update($data,['goodsId'=>$id]); + } + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败',-1); + } +} diff --git a/hyhproject/home/model/GoodsVirtuals.php b/hyhproject/home/model/GoodsVirtuals.php new file mode 100755 index 0000000..952f6fa --- /dev/null +++ b/hyhproject/home/model/GoodsVirtuals.php @@ -0,0 +1,174 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Goods as CGoodsVirtuals; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 虚拟商品卡券模型 + */ +class GoodsVirtuals extends CGoodsVirtuals{ + /** + * 导入 + */ + public function importCards($data){ + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objReader = \PHPExcel_IOFactory::load(WSTRootPath().json_decode($data)->route.json_decode($data)->name); + $objReader->setActiveSheetIndex(0); + $sheet = $objReader->getActiveSheet(); + $rows = $sheet->getHighestRow(); + $cells = $sheet->getHighestColumn(); + //数据集合 + $readData = []; + $shopId = (int)session('WST_USER.shopId'); + $goodsId = (int)input('goodsId'); + $importNum = 0; + //生成订单 + Db::startTrans(); + try{ + //读取现有的卡券 + $goodscards = Db::name('goods_virtuals')->where(['dataFlag'=>1,'goodsId'=>$goodsId])->field('cardNo')->select(); + $goodscardsMap = []; + if(count($goodscards)>0){ + foreach($goodscards as $v){ + $goodscardsMap[] = $v['cardNo']; + } + } + //循环读取每个单元格的数据 + for ($row = 2; $row <= $rows; $row++){//行数是以第2行开始 + $cards = []; + $cards['shopId'] = $shopId; + $cards['goodsId'] = $goodsId; + $cardNo = trim($sheet->getCell("A".$row)->getValue()); + if($cardNo=='')break;//如果某一行第一列为空则停止导入 + $cards['cardNo'] = $cardNo; + $cards['cardPwd'] = trim($sheet->getCell("B".$row)->getValue()); + $cards['createTime'] = date('Y-m-d H:i:s'); + if(in_array($cardNo,$goodscardsMap))continue; + $goodscardsMap[] = $cardNo; + $readData[] = $cards; + $importNum++; + } + if(count($readData)>0){ + model('GoodsVirtuals')->saveAll($readData); + $this->updateGoodsStock($goodsId); + } + Db::commit(); + return json_encode(['status'=>1,'importNum'=>$importNum]); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return json_encode(WSTReturn('导入商品卡券失败',-1)); + } + } + + /** + * 删除 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('ids'); + $id = input('id'); + if($ids=='')return WSTReturn('请选择要删除的卡券号'); + try{ + $this->where(['shopId'=>$shopId,'id'=>['in',$ids],'goodsId'=>$id])->update(['dataFlag'=>-1]); + $this->updateGoodsStock($id); + Db::commit(); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败'); + } + return WSTReturn('操作成功',1); + } + + /** + * 编辑 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $id = (int)input('id'); + //判断卡券是否有效 + $rs = $this->where(['id'=>$id,'shopId'=>$shopId,'dataFlag'=>1,'isUse'=>0])->find(); + if(empty($rs))return WSTReturn('非法的卡券'); + $cardNo = input('cardNo'); + $cardPwd = input('cardPwd'); + if($cardNo=='' || $cardPwd=='')return WSTReturn('请输入完整卡券信息'); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo,'id'=>['<>',$id]])->Count(); + if($conts>0)return WSTReturn('该卡券号已存在,请重新输入'); + $rs->cardNo = $cardNo; + $rs->cardPwd = $cardPwd; + $rs->save(); + return WSTReturn('操作成功',1); + } + + /** + * 获取虚拟商品库存列表 + */ + public function stockByPage(){ + $key = input('cardNo'); + $id = (int)input('id'); + $isUse = (int)input('isUse',-1); + $shopId = (int)session('WST_USER.shopId'); + $where = ['shopId'=>$shopId,'goodsId'=>$id,'dataFlag'=>1]; + if($key !='')$where['cardNo'] = ['like','%'.$key.'%']; + if(in_array($isUse,[0,1]))$where['isUse'] = $isUse; + $page = $this->field('orderNo,orderId,cardNo,id,cardPwd,isUse') + ->where($where)->order('id desc') + ->paginate(20)->toArray(); + return $page; + } + + /** + * 生成卡券号 + */ + public function getCardNo($shopId){ + $cardNo = date('Ymd').sprintf("%08d", rand(0,99999999)); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo])->Count(); + if($conts==0){ + return $cardNo; + }else{ + return $this->getCardNo($shopId); + } + } + + /** + * 生成卡券 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $goodsId = (int)input('goodsId'); + //判断商品是否有效 + $goods = model('goods')->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'goodsType'=>1])->find(); + if(empty($goods))return WSTReturn('非法的卡券商品'); + $cardNo = input('cardNo'); + $cardPwd = input('cardPwd'); + if($cardNo=='' || $cardPwd=='')return WSTReturn('请输入完整卡券信息'); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo])->Count(); + if($conts>0)return WSTReturn('该卡券号已存在,请重新输入'); + $data = []; + $data['cardNo'] = $cardNo; + $data['cardPwd'] = $cardPwd; + $data['dataFlag'] = 1; + $data['shopId'] = $shopId; + $data['goodsId'] = $goodsId; + $data['createTime'] = date('Y-m-d H:i:s'); + Db::startTrans(); + try{ + $this->save($data); + $this->updateGoodsStock($goodsId); + Db::commit(); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败'); + } + return WSTReturn('新增成功',1); + } + + /** + * 更新商品数量 + */ + public function updateGoodsStock($id){ + $shopId = (int)session('WST_USER.shopId'); + $counts = $this->where(['dataFlag'=>1,'goodsId'=>$id,'shopId'=>$shopId,'isUse'=>0])->Count(); + Db::name('goods')->where('goodsId',$id)->setField('goodsStock',$counts); + } +} \ No newline at end of file diff --git a/hyhproject/home/model/HomeMenus.php b/hyhproject/home/model/HomeMenus.php new file mode 100755 index 0000000..4b6f38d --- /dev/null +++ b/hyhproject/home/model/HomeMenus.php @@ -0,0 +1,205 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\HomeMenus as CHomeMenus; +use think\Db; +/** + * ============================================================================ + * 菜单业务处理 + */ +class HomeMenus extends CHomeMenus{ + /** + * 获取菜单树 + */ + public function getMenus(){ + $data = cache('WST_HOME_MENUS'); + if(!$data){ + $rs = $this->where(['isShow'=>1,'dataFlag'=>1]) + ->field('menuId,parentId,menuName,menuUrl,menuType')->order('menuSort asc,menuId asc')->select(); + $m1 = ['0'=>[],'1'=>[]]; + $tmp = []; + + //获取第一级 + foreach ($rs as $key => $v){ + if($v['parentId']==0){ + $m1[$v['menuType']][$v['menuId']] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + }else{ + $tmp[$v['parentId']][] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + } + } + //获取第二级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($tmp[$v1['menuId']]))$m1[$key][$key1]['list'] = $tmp[$v1['menuId']]; + } + } + //获取第三级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($v1['list'])){ + foreach ($v1['list'] as $key2 => $v2){ + if(isset($tmp[$v2['menuId']]))$m1[$key][$key1]['list'][$key2]['list'] = $tmp[$v2['menuId']]; + } + } + } + } + cache('WST_HOME_MENUS',$m1,31536000); + return $m1; + } + return $data; + } + + /** + * 获取店铺菜单树 + */ + public function getShopMenus(){ + $m1 = $this->getMenus(); + $userType = (int)session('WST_USER.userType'); + $menuUrls = array(); + if($userType==1){ + $shopId = (int)session('WST_USER.shopId'); + $roleId = (int)session('WST_USER.roleId'); + if($roleId>0){ + $role = model("home/ShopRoles")->getById($roleId); + $menuUrls = json_decode($role["privilegeUrls"],true); + foreach ($m1[1] as $k1 => $menus1) { + if(!array_key_exists($menus1["menuId"],$menuUrls)){ + unset($m1[1][$k1]); + }else{ + if(isset($menus1["list"])){ + if(count($menus1["list"])>0){ + foreach ($menus1["list"] as $k2 => $menus2) { + if(!array_key_exists($menus2["menuId"],$menuUrls[$menus1["menuId"]])){ + unset($m1[1][$k1]["list"][$k2]); + }else{ + if(isset($menus2["list"])){ + if(count($menus2["list"])>0){ + foreach ($menus2["list"] as $k3 => $menus3) { + $purls = $menuUrls[$menus1["menuId"]][$menus2["menuId"]]; + $urls = $purls["urls"]; + if(!in_array(strtolower($menus3["menuUrl"]),$urls)){ + unset($m1[1][$k1]["list"][$k2]["list"][$k3]); + } + } + }else{ + unset($m1[1][$k1]["list"][$k2]); + } + }else{ + unset($m1[1][$k1]["list"][$k2]); + } + } + } + if(count($m1[1][$k1]["list"])==0){ + unset($m1[1][$k1]); + } + }else{ + unset($m1[1][$k1]); + } + }else{ + unset($m1[1][$k1]); + } + } + } + } + } + return $m1; + } + + /** + * 获取菜单URL + */ + public function getMenusUrl(){ + $wst_user = session('WST_USER'); + $data = array(); + if(!empty($wst_user)){ + $data = cache('WST_PRO_MENUS'); + if(!$data){ + $list = $this->where('dataFlag',1)->order('menuType asc')->select(); + $menus = []; + foreach($list as $key => $v){ + $menus[strtolower($v['menuUrl'])] = $v['menuType']; + if($v['menuOtherUrl']!=''){ + $str = explode(',',$v['menuOtherUrl']); + foreach ($str as $vkey => $vv){ + if($vv=='')continue; + $menus[strtolower($vv)] = $v['menuType']; + } + } + } + cache('WST_PRO_MENUS',$menus,31536000); + return $menus; + } + } + return $data; + } + + /** + * 角色可访问url + */ + public function getShopMenusUrl(){ + $wst_user = session('WST_USER'); + + if(!empty($wst_user)){ + $roleId = isset($wst_user["roleId"])?(int)$wst_user["roleId"]:0; + if($roleId>0){ + $role = model("home/ShopRoles")->getById($roleId); + $menuUrls = $role["menuUrls"]; + $menuOtherUrls = $role["menuOtherUrls"]; + $shopUrls = array_merge($menuUrls,$menuOtherUrls); + } + } + $shopUrls[] = "home/shops/index"; + $shopUrls[] = "home/reports/getstatsales"; + return $shopUrls; + } + + + /** + * 获取菜单父ID + */ + public function getParentId($menuId){ + $data = cache('WST_HOME_MENUS_PARENT'); + if(!$data){ + $rs = $this->where(['isShow'=>1,'dataFlag'=>1]) + ->field('menuId,parentId,menuType')->order('menuSort asc,menuId asc')->select(); + $tmp = []; + foreach ($rs as $key => $v) { + $tmp[$v['menuId']] = $v; + } + $data = []; + foreach ($tmp as $key => $v) { + if($v['parentId']==0){ + $data[$v['menuId']] = $v; + }else{ + $data[$v['menuId']] = $tmp[$v['parentId']]; + } + } + cache('WST_HOME_MENUS_PARENT',$data,31536000); + } + return $data[$menuId]; + } + /** + * 获取店铺角色菜单 + */ + public function getRoleMenus(){ + $data = cache('WST_HOME_MENUS_SHOPROLE'); + if(!$data){ + $rs = $this->alias('m1') + ->join("__HOME_MENUS__ m2","m1.parentId=m2.menuId") + ->where(['m1.isShow'=>1,'m1.dataFlag'=>1,"m1.menuType"=>1,"m2.parentId"=>[">",0]]) + ->field('m1.menuId,m1.parentId,m2.parentId grandpaId,m1.menuName,m1.menuUrl,m1.menuOtherUrl,m1.menuType') + ->order('m1.menuSort asc,m1.menuId asc') + ->select(); + $m = array(); + //获取第一级 + foreach ($rs as $key => $v){ + $m[$v['menuId']] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'grandpaId'=>$v['grandpaId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl'],'menuOtherUrl'=>$v['menuOtherUrl']]; + } + cache('WST_HOME_MENUS_SHOPROLE',$m,31536000); + return $m; + } + return $data; + } + + + +} diff --git a/hyhproject/home/model/Imports.php b/hyhproject/home/model/Imports.php new file mode 100755 index 0000000..0cb1903 --- /dev/null +++ b/hyhproject/home/model/Imports.php @@ -0,0 +1,148 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 导入类 + */ +class Imports{ + /** + * 上传商品数据 + */ + public function importGoods($data){ + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objReader = \PHPExcel_IOFactory::load(WSTRootPath().json_decode($data)->route.json_decode($data)->name); + $objReader->setActiveSheetIndex(0); + $sheet = $objReader->getActiveSheet(); + $rows = $sheet->getHighestRow(); + $cells = $sheet->getHighestColumn(); + //数据集合 + $readData = []; + $shopId = (int)session('WST_USER.shopId'); + $importNum = 0; + $goodsCatMap = []; //记录最后一级商品分类 + $goodsCatPathMap = [];//记录商品分类路径 + $shopCatMap = [];//记录店铺分类 + $goodsCat1Map = [];//记录最后一级商品分类对应的一级分类 + $tmpGoodsCatId = 0; + $goodsCatBrandMap = [];//商品分类和品牌的对应关系 + //生成订单 + Db::startTrans(); + try{ + //循环读取每个单元格的数据 + for ($row = 3; $row <= $rows; $row++){//行数是以第3行开始 + $tmpGoodsCatId = 0; + $goods = []; + $goods['shopId'] = $shopId; + $goods['goodsName'] = trim($sheet->getCell("A".$row)->getValue()); + if($goods['goodsName']=='')break;//如果某一行第一列为空则停止导入 + $goods['goodsSn'] = trim($sheet->getCell("B".$row)->getValue()); + $goods['productNo'] = trim($sheet->getCell("C".$row)->getValue()); + $goods['marketPrice'] = trim($sheet->getCell("D".$row)->getValue()); + if(floatval($goods['marketPrice'])<0.01)$goods['marketPrice'] = 0.01; + $goods['shopPrice'] = trim($sheet->getCell("E".$row)->getValue()); + if(floatval($goods['shopPrice'])<0.01)$goods['shopPrice'] = 0.01; + $goods['goodsStock'] = trim($sheet->getCell("F".$row)->getValue()); + if(intval($goods['goodsStock'])<=0)$goods['goodsStock'] = 0; + $goods['warnStock'] = trim($sheet->getCell("G".$row)->getValue()); + if(intval($goods['warnStock'])<=0)$goods['warnStock'] = 0; + $goods['goodsImg'] = ''; + $goods['shopCatId1'] = 0; + $goods['shopCatId2'] = 0; + $goods['goodsUnit'] = trim($sheet->getCell("H".$row)->getValue()); + $goods['goodsSeoKeywords'] = trim($sheet->getCell("I".$row)->getValue()); + $goods['goodsTips'] = trim($sheet->getCell("J".$row)->getValue()); + $goods['isRecom'] = (trim($sheet->getCell("K".$row)->getValue())!='')?1:0; + $goods['isBest'] = (trim($sheet->getCell("L".$row)->getValue())!='')?1:0; + $goods['isNew'] = (trim($sheet->getCell("M".$row)->getValue())!='')?1:0; + $goods['isHot'] = (trim($sheet->getCell("N".$row)->getValue())!='')?1:0; + $goods['goodsCatId'] = 0; + //查询商城分类 + $goodsCat = trim($sheet->getCell("O".$row)->getValue()); + if(!empty($goodsCat)){ + //先判断集合是否存在,不存在的时候才查数据库 + if(isset($goodsCatMap[$goodsCat])){ + $goods['goodsCatId'] = $goodsCatMap[$goodsCat]; + $goods['goodsCatIdPath'] = $goodsCatPathMap[$goodsCat]; + $tmpGoodsCatId = $goodsCat1Map[$goodsCat]; + }else{ + $goodsCatId = Db::name('goods_cats')->where(['catName'=>$goodsCat,'dataFlag'=>1])->field('catId')->find(); + if(!empty($goodsCatId['catId'])){ + $goodsCats = model('GoodsCats')->getParentIs($goodsCatId['catId']); + $goods['goodsCatId'] = $goodsCatId['catId']; + $goods['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + //放入集合 + $goodsCatMap[$goodsCat] = $goodsCatId['catId']; + $goodsCatPathMap[$goodsCat] = implode('_',$goodsCats)."_"; + $goodsCat1Map[$goodsCat] = $goodsCats[0]; + $tmpGoodsCatId = $goodsCats[0]; + } + } + } + //查询店铺分类 + $shopGoodsCat = trim($sheet->getCell("P".$row)->getValue()); + if(!empty($shopGoodsCat)){ + //先判断集合是否存在,不存在的时候才查数据库 + if(isset($shopCatMap[$shopGoodsCat])){ + $goods['shopCatId1'] = $shopCatMap[$shopGoodsCat]['s1']; + $goods['shopCatId2'] = $shopCatMap[$shopGoodsCat]['s2']; + }else{ + $shopCat= Db::name("shop_cats")->alias('sc1') + ->join('__SHOP_CATS__ sc2','sc2.parentId=sc1.catId','left') + ->field('sc1.catId catId1,sc2.catId catId2,sc2.catName') + ->where(['sc1.shopId'=> $shopId,'sc1.dataFlag'=>1,'sc2.catName'=>$shopGoodsCat]) + ->find(); + if(!empty($shopCat)){ + $goods['shopCatId1'] = $shopCat['catId1']; + $goods['shopCatId2'] = $shopCat['catId2']; + //放入集合 + $shopCatMap[$shopGoodsCat] = []; + $shopCatMap[$shopGoodsCat]['s1'] = $goods['shopCatId1']; + $shopCatMap[$shopGoodsCat]['s2'] = $goods['shopCatId2']; + } + } + } + //查询品牌 + $brand = trim($sheet->getCell("Q".$row)->getValue()); + if(!empty($brand)){ + if(isset($goodsCatBrandMap[$brand])){ + $goods['brandId'] = $goodsCatBrandMap[$brand]; + }else{ + $brands = Db::name('brands')->alias('a')->join('__CAT_BRANDS__ cb','a.brandId=cb.brandId','inner') + ->where(['catId'=>$tmpGoodsCatId,'brandName'=>$brand,'dataFlag'=>1])->field('a.brandId')->find(); + if(!empty($brands)){ + $goods['brandId'] = $brands['brandId']; + $goodsCatBrandMap[$brand] = $brands['brandId']; + } + } + } + $goods['goodsDesc'] = trim($sheet->getCell("R".$row)->getValue()); + $goods['isSale'] = 0; + $goods['goodsStatus'] = (WSTConf("CONF.isGoodsVerify")==1)?0:1; + $goods['dataFlag'] = 1; + $goods['saleTime'] = date('Y-m-d H:i:s'); + $goods['createTime'] = date('Y-m-d H:i:s'); + $readData[] = $goods; + $importNum++; + } + if(count($readData)>0){ + $list = model('Goods')->saveAll($readData); + //建立商品评分记录 + $goodsScores = []; + foreach ($list as $key =>$v){ + $gs = []; + $gs['goodsId'] = $v['goodsId']; + $gs['shopId'] = $shopId; + $goodsScores[] = $gs; + } + if(count($goodsScores)>0)Db::name('goods_scores')->insertAll($goodsScores); + } + Db::commit(); + return json_encode(['status'=>1,'importNum'=>$importNum]); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return json_encode(WSTReturn('导入商品失败',-1)); + } + } +} \ No newline at end of file diff --git a/hyhproject/home/model/Reports.php b/hyhproject/home/model/Reports.php new file mode 100755 index 0000000..771102e --- /dev/null +++ b/hyhproject/home/model/Reports.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 报表模型类 + */ +class Reports{ + /** + * 获取商品销售排行 + */ + public function getTopSaleGoods(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('og.goodsId,g.goodsName,goodsSn,sum(og.goodsNum) goodsNum,g.goodsImg')->name('order_goods')->alias('og') + ->join('__ORDERS__ o','og.orderId=o.orderId') + ->join('__GOODS__ g','og.goodsId=g.goodsId') + ->order('goodsNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where('(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1 and o.shopId='.$shopId)->group('og.goodsId') + ->limit(10)->select(); + return WSTReturn('',1,$rs); + } + /** + * 获取销售额统计 + */ + public function getStatSales(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $payType = (int)input('payType',-1); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('left(createTime,10) createTime,sum(totalMoney) totalMoney,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('shopId',$shopId) + ->where('(payType=0 or (payType=1 and isPay=1)) and dataFlag=1 '.(in_array($payType,[0,1])?" and payType=".$payType:'')) + ->order('createTime asc') + ->group('left(createTime,10)')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + foreach($rs as $key => $v){ + $days[] = $v['createTime']; + $rdata['dayVals'][] = $v['totalMoney']; + $rdata['list'][] = ['day'=>$v['createTime'],'val'=>$v['totalMoney'],'num'=>$v['orderNum']]; + } + $rdata['days'] = $days; + } + return WSTReturn('',1,$rdata); + } + + /** + * 获取商家订单情况 + */ + public function getStatOrders(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('left(createTime,10) createTime,orderStatus,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('shopId',$shopId) + ->order('createTime asc') + ->group('left(createTime,10),orderStatus')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + $map = ['-3'=>0,'-1'=>0,'1'=>0]; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['orderStatus'].'_'.$v['createTime']] = $v['orderNum']; + } + foreach($days as $v){ + $total = 0; + $ou = 0; + $o_3 = isset($tmp['-3_'.$v])?$tmp['-3_'.$v]:0; + $o_1 = isset($tmp['-1_'.$v])?$tmp['-1_'.$v]:0; + if(isset($tmp['0_'.$v]))$ou += $tmp['0_'.$v]; + if(isset($tmp['1_'.$v]))$ou += $tmp['1_'.$v]; + if(isset($tmp['2_'.$v]))$ou += $tmp['2_'.$v]; + $rdata['-3'][] = $o_3; + $rdata['-1'][] = $o_1; + $rdata['1'][] = $ou; + $map['-3'] += $o_3; + $map['-1'] += $o_1; + $map['1'] += $ou; + $total += $o_3; + $total += $o_1; + $total += $ou; + $rdata['total'][] = $total; + $rdata['list'][] = ['day'=>$v,'o3'=>$o_3,'o1'=>$o_1,'ou'=>$ou]; + } + $rdata['days'] = $days; + $rdata['map'] = $map; + } + return WSTReturn('',1,$rdata); + } +} \ No newline at end of file diff --git a/hyhproject/home/model/Settlements.php b/hyhproject/home/model/Settlements.php new file mode 100755 index 0000000..56176f6 --- /dev/null +++ b/hyhproject/home/model/Settlements.php @@ -0,0 +1,246 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 结算类 + */ +class Settlements extends Base{ + /** + * 获取已结算的结算单列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $where = []; + $where['shopId'] = $shopId; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + return Db::name('settlements')->alias('s')->where($where)->order('settlementId', 'desc') + ->paginate(input('pagesize/d')); + } + /** + * 获取未结算订单列表 + */ + public function pageUnSettledQuery(){ + $where = []; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['settlementId'] = 0; + $where['shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->where($where)->order('orderId', 'desc') + ->field('orderId,orderNo,createTime,payType,goodsMoney,deliverMoney,totalMoney,commissionFee,realTotalMoney') + ->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])){ + foreach ($page['Rows'] as $key => $v) { + $page['Rows'][$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + return $page; + } + /** + * 结算指定的订单 + */ + public function settlement(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('ids'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['settlementId'] = 0; + $where['orderId'] = ['in',$ids]; + $where['shopId'] = $shopId; + $orders = Db::name('orders')->where($where)->field('orderId,payType,realTotalMoney,scoreMoney,commissionFee')->select(); + if(empty($orders))return WSTReturn('没有需要结算的订单,请刷新后再核对!'); + $settlementMoney = 0; + $commissionFee = 0; //平台要收的佣金 + $ids = []; + foreach ($orders as $key => $v) { + $ids[] = $v['orderId']; + if($v['payType']==1){ + $settlementMoney += $v['realTotalMoney']+$v['scoreMoney']; + }else{ + $settlementMoney += $v['scoreMoney']; + } + $commissionFee += abs($v['commissionFee']); + } + + $shops = model('shops')->get($shopId); + if(empty($shops))WSTReturn('无效的店铺结算账号!'); + Db::startTrans(); + try{ + $areaNames = model('areas')->getParentNames($shops['bankAreaId']); + $data = []; + $data['settlementType'] = 0; + $data['shopId'] = $shopId; + $data['settlementMoney'] = $settlementMoney; + $data['commissionFee'] = $commissionFee; + $data['backMoney'] = $settlementMoney-$commissionFee; + $data['settlementStatus'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['settlementNo'] = ''; + $result = $this->save($data); + if(false !== $result){ + $this->settlementNo = $this->settlementId.(fmod($this->settlementId,7)); + $this->save(); + Db::name('orders')->where(['orderId'=>['in',$ids]])->update(['settlementId'=>$this->settlementId]); + //修改商家订单情况 + $commissionFee = -1*$commissionFee;//平台要收的佣金就等于商家要付的钱 + $shops->noSettledOrderNum = $shops->noSettledOrderNum-count($orders); + $shops->paymentMoney = $shops->paymentMoney + $commissionFee; + $shops->noSettledOrderFee = $shops->noSettledOrderFee-$commissionFee; + $shops->save(); + Db::commit(); + return WSTReturn('提交结算申请成功,请留意结算信息~',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('提交结算申请失败',-1); + } + + /** + * 获取已结算订单 + */ + public function pageSettledQuery(){ + $where = []; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['o.shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->alias('o') + ->join('__SETTLEMENTS__ s','o.settlementId=s.settlementId') + ->join('__PAYMENTS__ p','o.payFrom=p.payCode')->where($where) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,totalMoney,o.commissionFee,realTotalMoney,s.settlementTime,s.settlementNo,p.payName')->order('s.settlementTime desc')->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])){ + foreach ($page['Rows'] as $key => $v) { + $page['Rows'][$key]['commissionFee'] = abs($v['commissionFee']); + $page['Rows'][$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + return $page; + } + + /** + * 获取结算订单详情 + */ + public function getById(){ + $shopId = (int)session('WST_USER.shopId'); + $settlementId = (int)input('id'); + $object = Db::name('settlements')->alias('st')->where(['settlementId'=>$settlementId,'st.shopId'=>$shopId])->join('__SHOPS__ s','s.shopId=st.shopId','left')->field('s.shopName,st.*')->find(); + if(!empty($object)){ + $object['list'] = Db::name('orders')->where(['settlementId'=>$settlementId]) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,realTotalMoney,totalMoney,scoreMoney,commissionFee,createTime') + ->order('payType desc,orderId desc')->select(); + } + return $object; + } + /** + * 导出订单 + */ + public function toExport(){ + $name='已结算订单表'; + $where = []; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['o.shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->alias('o') + ->join('__SETTLEMENTS__ s','o.settlementId=s.settlementId') + ->join('__PAYMENTS__ p','o.payFrom=p.payCode')->where($where) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,totalMoney,o.commissionFee,realTotalMoney,s.settlementTime,s.settlementNo,p.payName')->order('s.settlementTime desc')->select(); + if(count($page)){ + foreach ($page as $key => $v) { + $page[$key]['commissionFee'] = abs($v['commissionFee']); + $page[$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + ->setLastModifiedBy("WSTMart")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(30); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(30); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(20); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet()->setCellValue('A1', '订单编号')->setCellValue('B1', '支付方式')->setCellValue('C1', '商品总金额')->setCellValue('D1', '运费')->setCellValue('E1', '订单总金额') + ->setCellValue('F1', '实付金额')->setCellValue('G1', '应付佣金')->setCellValue('H1', '结算方式')->setCellValue('I1', '结算单号')->setCellValue('J1', '结算时间'); + $objPHPExcel->getActiveSheet()->getStyle('A1:J1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['orderNo']) + ->setCellValue('B'.$i, $page[$row]['payTypeNames']) + ->setCellValue('C'.$i, $page[$row]['goodsMoney']) + ->setCellValue('D'.$i, $page[$row]['deliverMoney']) + ->setCellValue('E'.$i, $page[$row]['totalMoney']) + ->setCellValue('F'.$i, $page[$row]['realTotalMoney']) + ->setCellValue('G'.$i, $page[$row]['commissionFee']) + ->setCellValue('H'.$i, $page[$row]['payName']) + ->setCellValue('I'.$i, $page[$row]['settlementNo']) + ->setCellValue('J'.$i, $page[$row]['settlementTime']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} \ No newline at end of file diff --git a/hyhproject/home/model/ShopConfigs.php b/hyhproject/home/model/ShopConfigs.php new file mode 100755 index 0000000..2cf174b --- /dev/null +++ b/hyhproject/home/model/ShopConfigs.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 门店配置类 + */ +use think\Db; +class ShopConfigs extends Base{ + /** + * 店铺设置 + */ + public function getShopCfg($id){ + $rs = $this->where("shopId=".$id)->find(); + if($rs != ''){ + //图片 + $rs['shopAds'] = ($rs['shopAds']!='')?explode(',',$rs['shopAds']):null; + //图片的广告地址 + $rs['shopAdsUrl'] = ($rs['shopAdsUrl']!='')?explode(',',$rs['shopAdsUrl']):null; + return $rs; + } + } + + /** + * 修改店铺设置 + */ + public function editShopCfg($shopId){ + $data = input('post.'); + //加载商店信息 + Db::startTrans(); + try{ + $shopcg = $this->where('shopId='.$shopId)->find(); + $scdata = array(); + $scdata["shopKeywords"] = Input("shopKeywords"); + $scdata["shopBanner"] = Input("shopBanner"); + $scdata["shopDesc"] = Input("shopDesc"); + $scdata["shopAds"] = Input("shopAds"); + $scdata["shopAdsUrl"] = Input("shopAdsUrl"); + $scdata["shopHotWords"] = Input("shopHotWords"); + $scdata["shopStreetImg"] = Input("shopStreetImg"); + WSTUseImages(0, $shopcg['configId'], $scdata['shopStreetImg'],'shop_configs','shopStreetImg'); + WSTUseImages(0, $shopcg['configId'], $scdata['shopBanner'],'shop_configs','shopBanner'); + WSTUseImages(0, $shopcg['configId'], $scdata['shopAds'],'shop_configs','shopAds'); + $rs = $this->where("shopId=".$shopId)->update($scdata); + if($rs!==false){ + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + /** + * 获取商城搜索关键字 + */ + public function searchShopkey($shopId){ + $rs = $this->where('shopId='.$shopId)->field('configId,shopHotWords')->find(); + $keys = []; + if($rs['shopHotWords']!='')$keys = explode(',',$rs['shopHotWords']); + return $keys; + } +} diff --git a/hyhproject/home/model/ShopFreights.php b/hyhproject/home/model/ShopFreights.php new file mode 100755 index 0000000..a4e0a0d --- /dev/null +++ b/hyhproject/home/model/ShopFreights.php @@ -0,0 +1,63 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use wstmart\home\model\Shops; +/** + * ============================================================================ + * 运费管理类 + */ +class ShopFreights extends Base{ + /** + * 运费列表 + */ + public function listProvince(){ + $shopId = session('WST_USER.shopId'); + $listCity = Db::name('areas')->where(['isShow'=>1,'dataFlag'=>1,'areaType'=>0])->field('areaId,areaName')->order('areaKey desc')->select(); + for ($i = 0; $i < count($listCity); $i++) { + $parentId = $listCity[$i]["areaId"]; + $listPro = Db::name('areas')->alias('a') + ->join('__SHOP_FREIGHTS__ s','a.areaId= s.areaId2 and s.shopId='.$shopId,'left') + ->where(['a.isShow'=>1,'a.dataFlag'=>1,'a.areaType'=>1,'a.parentId'=>$parentId]) + ->field('a.areaId,a.areaName,a.parentId,s.freightId,s.freight') + ->order('a.areaKey desc') + ->select(); + $listCity[$i]['listProvince'] = $listPro; + } + return $listCity; + } + + /** + * 编辑 + */ + public function edit(){ + $shopId = session('WST_USER.shopId'); + $info = input("post."); + $areas = Db::name('areas')->where('isShow=1 AND dataFlag = 1 AND areaType=1')->field('areaId')->select(); + Db::startTrans(); + if(count($areas)==0)return WSTReturn('无效的城市'); + try{ + $dataList = []; + foreach ($areas as $key => $v) { + $m = model('ShopFreights')->where(['shopId'=>$shopId,'areaId2'=>$v['areaId']])->find(); + $freight = ((int)input('post.'.$v['areaId'])>0)?(int)input('post.'.$v['areaId']):0; + if($m){ + $m->freight = $freight; + $m->save(); + }else{ + $data = []; + $data['shopId'] = $shopId; + $data['areaId2'] = $v['areaId']; + $data['freight'] = $freight; + $data['createTime'] = date('Y-m-d H:i:s'); + $dataList[] = $data; + } + } + if(count($dataList)>0)model('ShopFreights')->saveAll($dataList); + Db::commit(); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } +} diff --git a/hyhproject/home/model/ShopRoles.php b/hyhproject/home/model/ShopRoles.php new file mode 100755 index 0000000..5051c42 --- /dev/null +++ b/hyhproject/home/model/ShopRoles.php @@ -0,0 +1,153 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 门店色务类 + */ +class ShopRoles extends Base{ + /** + * 角色列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $roleName = input("roleName/s"); + $where = ["shopId"=>$shopId,"dataFlag"=>1]; + if($roleName != ""){ + $where["roleName"] = ["like","%".$roleName."%"]; + } + $page = $this + ->field('id,shopId,roleName,createTime') + ->where($where) + ->paginate(input('pagesize/d'))->toArray(); + return $page; + } + + public function listQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $where = ["shopId"=>$shopId,"dataFlag"=>1]; + $list = $this + ->field('id,shopId,roleName,createTime') + ->where($where) + ->select(); + return $list; + } + /** + * 根据id获取店铺角色 + */ + public function getById($id){ + $shopId = (int)session('WST_USER.shopId'); + $role = $this->field('id,shopId,roleName,createTime,privilegeUrls,privilegeMsgs') + ->where(["id"=>$id,"shopId"=>$shopId,"dataFlag"=>1]) + ->find(); + $menuList = json_decode($role["privilegeUrls"],true); + $menuUrls = array(); + $menuOtherUrls = array(); + foreach ($menuList as $k1 => $menus1) { + foreach ($menus1 as $k2 => $menus2) { + $menuUrls = array_merge($menuUrls,$menus2["urls"]); + $otherUrls = $menus2["otherUrls"]; + foreach ($otherUrls as $ko => $ourls) { + $othurls = explode(',',$ourls); + $menuOtherUrls = array_merge($menuOtherUrls,$othurls); + } + } + } + $role["privilegeMsgs"] = explode(",",$role["privilegeMsgs"]); + $role["menuUrls"] = array_filter($menuUrls); + $role["menuOtherUrls"] = array_filter($menuOtherUrls); + return $role; + } + + /** + * 新增店铺角色 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $data["shopId"] = $shopId; + $data["roleName"] = input('roleName/s'); + if($data["roleName"]==""){ + return WSTReturn('请输入角色名称',-1); + } + $data["privilegeMsgs"] = input('privilegeMsgs/s'); + $menuIds = input('menuIds/s'); + $urls = []; + $otherUrls = []; + if($menuIds==""){ + return WSTReturn('请选择权限',-1); + }else{ + $roleMenus = model("HomeMenus")->getRoleMenus(); + $menuIds = explode(",",$menuIds); + $menuList = array(); + for($i=0,$j=count($menuIds);$i<$j;$i++){ + $menu = $roleMenus[$menuIds[$i]]; + $menuList[$menu["grandpaId"]][$menu["parentId"]]["urls"][] = strtolower($menu["menuUrl"]); + $menuList[$menu["grandpaId"]][$menu["parentId"]]["otherUrls"][] = strtolower($menu["menuOtherUrl"]); + } + } + $data["privilegeUrls"] = json_encode($menuList); + $data["createTime"] = date("Y-m-d H:i:s"); + $result = $this->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + } + return WSTReturn('新增失败',-1); + } + + /** + * 修改店铺角色 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $id = (int)input('id'); + $data["roleName"] = input('roleName/s'); + if($data["roleName"]==""){ + return WSTReturn('请输入角色名称',-1); + } + $data["privilegeMsgs"] = input('privilegeMsgs/s'); + $menuIds = input('menuIds/s'); + $urls = []; + $otherUrls = []; + if($menuIds==""){ + return WSTReturn('请选择权限',-1); + }else{ + $roleMenus = model("HomeMenus")->getRoleMenus(); + $menuIds = explode(",",$menuIds); + $menuList = array(); + for($i=0,$j=count($menuIds);$i<$j;$i++){ + $menu = $roleMenus[$menuIds[$i]]; + $menuList[$menu["grandpaId"]][$menu["parentId"]]["urls"][] = strtolower($menu["menuUrl"]); + $menuList[$menu["grandpaId"]][$menu["parentId"]]["otherUrls"][] = strtolower($menu["menuOtherUrl"]); + } + } + $data["privilegeUrls"] = json_encode($menuList); + $result = $this->where(["id"=>$id,"shopId"=>$shopId])->update($data); + if(false !== $result){ + return WSTReturn("修改成功", 1); + } + return WSTReturn('删除失败',-1); + } + + /** + * 删除店铺角色 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $result = $this->where(["id"=>$id,"shopId"=>$shopId])->update($data); + if(false !== $result){ + //删除关联记录 + Db::name("shop_users")->where(["roleId"=>$id,"shopId"=>$shopId])->update($data); + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } +} diff --git a/hyhproject/home/model/ShopUsers.php b/hyhproject/home/model/ShopUsers.php new file mode 100755 index 0000000..2bc6e98 --- /dev/null +++ b/hyhproject/home/model/ShopUsers.php @@ -0,0 +1,202 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 门店管理员类 + */ +class ShopUsers extends Base{ + /** + * 角色列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $userName = input("userName/s"); + $where = ["s.shopId"=>$shopId,"s.dataFlag"=>1]; + if($userName != ""){ + $where["loginName"] = ["like","%".$userName."%"]; + } + $page = $this->alias('s') + ->join("__SHOP_ROLES__ r","s.roleId=r.id","LEFT") + ->join("__USERS__ u", "u.userId=s.userId and u.dataFlag=1") + ->field('s.id,s.shopId,s.roleId,u.userName,u.loginName,u.createTime,u.userStatus,r.roleName') + ->where($where) + ->paginate(input('pagesize/d'))->toArray(); + return $page; + } + + /** + * 根据id获取店铺用户 + */ + public function getById(){ + $id = (int)input('id'); + $shopId = (int)session('WST_USER.shopId'); + $user = $this->alias('s') + ->join("__SHOP_ROLES__ r","s.roleId=r.id","LEFT") + ->join("__USERS__ u", "u.userId=s.userId and u.dataFlag=1") + ->field('s.id,s.shopId,s.roleId,u.userName,u.loginName,u.createTime,u.userStatus,r.roleName') + ->where(["s.id"=>$id,"s.shopId"=>$shopId,"s.dataFlag"=>1]) + ->find(); + return $user; + } + + + /** + * 新增店铺用户 + */ + public function add(){ + $data = array(); + $roleId = (int)input("roleId"); + $data['loginName'] = input("post.loginName"); + $data['loginPwd'] = input("post.loginPwd"); + $data['reUserPwd'] = input("post.reUserPwd"); + $loginName = $data['loginName']; + if($roleId<=0){ + return WSTReturn('非法操作'); + } + //检测账号是否存在 + $crs = WSTCheckLoginKey($loginName); + if($crs['status']!=1)return $crs; + $decrypt_data = WSTRSA($data['loginPwd']); + $decrypt_data2 = WSTRSA($data['reUserPwd']); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $data['loginPwd'] = $decrypt_data['data']; + $data['reUserPwd'] = $decrypt_data2['data']; + }else{ + return WSTReturn('新增失败'); + } + if($data['loginPwd']!=$data['reUserPwd']){ + return WSTReturn("两次输入密码不一致!"); + } + foreach ($data as $v){ + if($v ==''){ + return WSTReturn("信息不完整!"); + } + } + if($loginName=='')return WSTReturn("新增失败!");//分派不了登录名 + + unset($data['reUserPwd']); + //检测账号,邮箱,手机是否存在 + $data["loginSecret"] = rand(1000,9999); + $data['loginPwd'] = md5($data['loginPwd'].$data['loginSecret']); + $data['userName'] = input("post.userName"); + $data['userQQ'] = ""; + $data['userScore'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['dataFlag'] = 1; + $data['userType'] = 1; + Db::startTrans(); + try{ + $userId = Db::name("users")->insertGetId($data); + if(false !== $userId){ + //添加门店用户 + $shopId = (int)session('WST_USER.shopId'); + $data = array(); + $data["shopId"] = $shopId; + $data["userId"] = $userId; + $data["roleId"] = (int)input("roleId"); + Db::name('shop_users')->insert($data); + $user = model("common/Users")->get($userId); + //注册成功后执行钩子 + hook('afterUserRegist',['user'=>$user]); + //发送消息 + $tpl = WSTMsgTemplates('USER_REGISTER'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${MALL_NAME}']; + $replace = [$user['loginName'],WSTConf('CONF.mallName')]; + WSTSendMsg($userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>0,'dataId'=>0]); + } + + Db::commit(); + return WSTReturn("新增成功",1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn("新增失败!"); + } + + /** + * 修改店铺用户 + */ + public function edit(){ + + $shopId = (int)session('WST_USER.shopId'); + Db::startTrans(); + try{ + $data = array(); + $roleId = (int)input("post.roleId"); + $id = (int)input("post.id"); + $newPass = input("post.newPass/s"); + if($newPass!=""){ + $decrypt_data = WSTRSA($newPass); + if($decrypt_data['status']==1){ + $newPass = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + if(!$newPass){ + return WSTReturn('密码不能为空',-1); + } + $roleUser = $this->where(["id"=>$id,"shopId"=>$shopId])->find(); + $userId = $roleUser["userId"]; + $rs = model("users")->where(["userId"=>$userId])->find(); + //核对密码 + + $oldPass = input("post.oldPass"); + $decrypt_data2 = WSTRSA($oldPass); + if($decrypt_data2['status']==1){ + $oldPass = $decrypt_data2['data']; + }else{ + return WSTReturn('修改失败'); + } + if($rs['loginPwd']==md5($oldPass.$rs['loginSecret'])){ + + $data["loginPwd"] = md5($newPass.$rs['loginSecret']); + $rs = model("users")->update($data,['userId'=>$userId]); + if(false !== $rs){ + $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update(["roleId"=>$roleId]); + hook("afterEditPass",["userId"=>$userId]); + }else{ + return WSTReturn("修改失败", -1); + } + Db::commit(); + return WSTReturn("修改成功", 1); + + }else{ + return WSTReturn('原始密码错误',-1); + } + }else{ + $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update(["roleId"=>$roleId]); + Db::commit(); + return WSTReturn("修改成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + } + + + + /** + * 删除店铺用户 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $role = $this->where(["id"=>$id,"shopId"=>$shopId])->field("userId,id")->find(); + $result = $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update($data); + if(false !== $result){ + Db::name("users")->where(["userId"=>$role["userId"]])->update(["userType"=>0]); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } +} diff --git a/hyhproject/home/model/Shops.php b/hyhproject/home/model/Shops.php new file mode 100755 index 0000000..1d5dc67 --- /dev/null +++ b/hyhproject/home/model/Shops.php @@ -0,0 +1,561 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Shops as CShops; +use wstmart\home\validate\Shops as VShop; +use think\Db; +use think\Loader; +use think\Validate; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends CShops{ + /** + * 获取店铺的默认运费 + */ + public function getShopsFreight($shopId){ + return $this->where(["dataFlag"=>1,"shopId"=>$shopId])->field('freight')->find(); + } + /** + * 获取店铺公告 + */ + public function getNotice(){ + $shopId = (int)session('WST_USER.shopId'); + return model('shops')->where(['shopId'=>$shopId])->value('shopNotice'); + } + /** + * 修改店铺公告 + */ + public function editNotice(){ + $shopId = (int)session('WST_USER.shopId'); + $shopNotice = input('shopNotice'); + if(strlen($shopNotice)>450){ + return WSTReturn('店铺公告不能超过150字'); + } + $rs = $this->where("shopId=$shopId")->setField('shopNotice',$shopNotice); + if($rs!==false)return WSTReturn('设置成功',1); + return WSTReturn('设置失败',-1); + } + + /** + * 店铺街列表 + */ + public function pageQuery($pagesize){ + $catId = input("get.id/d"); + $keyword = input("keyword"); + $userId = (int)session('WST_USER.userId'); + $rs = $this->alias('s'); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.applyStatus'] = 2; + if($keyword!='')$where['s.shopName'] = ['like','%'.$keyword.'%']; + if($catId>0){ + $rs->join('__CAT_SHOPS__ cs','cs.shopId = s.shopId','left'); + $where['cs.catId'] = $catId; + } + $page = $rs->join('__SHOP_SCORES__ ss','ss.shopId = s.shopId','left') + ->join('__USERS__ u','u.userId = s.userId','left') + ->join('__FAVORITES__ f','f.userId = '.$userId.' and f.favoriteType=1 and f.targetId=s.shopId','left') + ->where($where) + ->order('s.shopId asc') + ->field('s.shopId,s.shopImg,s.shopName,s.shopTel,s.shopQQ,s.shopWangWang,s.shopWangWangType,s.shopCompany,ss.totalScore,ss.totalUsers,ss.goodsScore,ss.goodsUsers,ss.serviceScore,ss.serviceUsers,ss.timeScore,ss.timeUsers,.u.loginName,f.favoriteId,s.areaIdPath') + ->paginate($pagesize)->toArray(); + if(empty($page['Rows']))return $page; + $shopIds = []; + $areaIds = []; + foreach ($page['Rows'] as $key =>$v){ + $shopIds[] = $v['shopId']; + $tmp = explode('_',$v['areaIdPath']); + $areaIds[] = $tmp[1]; + $page['Rows'][$key]['areaId'] = $tmp[1]; + //总评分 + $page['Rows'][$key]['totalScore'] = WSTScore($v["totalScore"], $v["totalUsers"]); + $page['Rows'][$key]['goodsScore'] = WSTScore($v['goodsScore'],$v['goodsUsers']); + $page['Rows'][$key]['serviceScore'] = WSTScore($v['serviceScore'],$v['serviceUsers']); + $page['Rows'][$key]['timeScore'] = WSTScore($v['timeScore'],$v['timeUsers']); + //商品列表 + $goods = Db::name('goods')->alias('g')->join('store_recom sr','sr.goodsId=g.goodsId','left') + ->where(['dataFlag'=> 1,'goodsStatus'=>1,'isSale'=>1,'sr.storeStatus'=>1,'shopId'=> $v["shopId"]])->field('g.goodsId,goodsName,shopPrice,goodsImg')->limit(10)->order('saleTime desc')->select(); + if(count($goods)<=3){ + $goods = Db::name('goods')->alias('g') + ->where(['dataFlag'=> 1,'goodsStatus'=>1,'isSale'=>1,'shopId'=> $v["shopId"]])->field('g.goodsId,goodsName,shopPrice,goodsImg')->limit(10)->order('saleTime desc')->select(); + } + $page['Rows'][$key]['goods'] = $goods; + //店铺商品总数 + $page['Rows'][$key]['goodsTotal'] = count($goods); + } + $rccredMap = []; + $goodsCatMap = []; + $areaMap = []; + //认证、地址、分类 + if(!empty($shopIds)){ + $rccreds = Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','a.accredId=sac.accredId and a.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('sac.shopId,accredName,accredImg')->select(); + foreach ($rccreds as $v){ + $rccredMap[$v['shopId']][] = $v; + } + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[$v['shopId']][] = $v['catName']; + } + $areas = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$areaIds)->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->select(); + foreach ($areas as $v){ + $areaMap[$v['areaId']] = $v; + } + } + foreach ($page['Rows'] as $key =>$v){ + $page['Rows'][$key]['accreds'] = (isset($rccredMap[$v['shopId']]))?$rccredMap[$v['shopId']]:[]; + $page['Rows'][$key]['catshops'] = (isset($goodsCatMap[$v['shopId']]))?implode(',',$goodsCatMap[$v['shopId']]):''; + $page['Rows'][$key]['areas']['areaName1'] = (isset($areaMap[$v['areaId']]['areaName1']))?$areaMap[$v['areaId']]['areaName1']:''; + $page['Rows'][$key]['areas']['areaName2'] = (isset($areaMap[$v['areaId']]['areaName2']))?$areaMap[$v['areaId']]['areaName2']:''; + } + return $page; + } + /** + * 获取卖家中心信息 + */ + public function getShopSummary($shopId){ + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'dataFlag'=>1]) + ->field('s.shopMoney,s.noSettledOrderFee,s.paymentMoney,s.shopId,shopImg,shopName,shopAddress,shopQQ,shopWangWang,shopTel,serviceStartTime,serviceEndTime,cs.*') + ->find(); + //评分 + $scores['totalScore'] = WSTScore($shop['totalScore'],$shop['totalUsers']); + $scores['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $scores['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $scores['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + $shop['scores'] = $scores; + //认证 + $accreds = $this->shopAccreds($shopId); + $shop['accreds'] = $accreds; + //商家访问量 + $shop['view']=db('shop_view')->where('shopId',$shopId)->field('count(shopId)view,path')->group('path')->select(); + //查看商家钱包是否足够钱 + $USER = session('WST_USER'); + $USER['shopMoney'] = $shop['shopMoney']; + $USER['noSettledOrderFee'] = $shop['noSettledOrderFee']; + $USER['paymentMoney'] = $shop['paymentMoney']; + session('WST_USER',$USER); + $stat = array(); + $date = date("Y-m-d"); + $userId = session('WST_USER.userId'); + /**********今日动态**********/ + //待查看消息数 + $stat['messageCnt'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + //今日销售金额 + $stat['saleMoney'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['egt',0],'dataFlag'=>1])->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->sum("goodsMoney"); + //今日订单数 + $stat['orderCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['egt',0],'dataFlag'=>1])->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->count(); + //待发货订单 + $stat['waitDeliveryCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>0,'dataFlag'=>1])->count(); + //待收货订单 + $stat['waitReceiveCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>1,'dataFlag'=>1])->count(); + //取消/拒收 + $stat['cancel'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['in',[-1,-3]],'dataFlag'=>1])->count(); + //库存预警 + $goodsn = Db::name('goods')->where('shopId ='.$shopId.' and dataFlag = 1 and goodsStock <= warnStock and isSpec = 0 and warnStock>0')->cache('stockWarnCnt1'.$shopId,3600)->count(); + $specsn = Db::name('goods_specs')->where('shopId ='.$shopId.' and dataFlag = 1 and specStock <= warnStock and warnStock>0')->cache('stockWarnCnt2'.$shopId,3600)->count(); + $stat['stockWarnCnt'] = $goodsn+$specsn; + + /**********商品信息**********/ + //商品总数 + $stat['goodsCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1])->cache('goodsCnt'.$shopId,3600)->count(); + //上架商品 + $stat['onSaleCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1])->cache('onSaleCnt'.$shopId,3600)->count(); + //待审核商品 + $stat['waitAuditCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>0])->cache('waitAuditCnt'.$shopId,3600)->count(); + //仓库中的商品 + $stat['unSaleCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>0])->cache('unSaleCnt'.$shopId,3600)->count(); + //违规商品 + $stat['illegalCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>-1])->cache('illegalCnt'.$shopId,3600)->count(); + //今日新品 + $stat['newGoodsCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1,'isNew'=>1])->cache('newGoodsCnt'.$shopId,3600)->count(); + + /**********订单信息**********/ + //待付款订单 + $stat['orderNeedpayCnt'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + //待结束订单 + $stat['orderWaitCloseCnt'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'dataFlag'=>1,'isClosed'=>0])->cache('orderWaitCloseCnt'.$shopId,3600)->count(); + //退货退款订单 + $stat['orderRefundCnt'] = Db::name('orders')->alias('o')->join('order_refunds orf','orf.orderId=o.orderId')->where(['shopId'=>$shopId,'refundStatus'=>0,'o.dataFlag'=>1])->count(); + //待评价订单 + $stat['orderWaitAppraisesCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>2,'dataFlag'=>1,'isAppraise'=>0])->cache('orderWaitAppraisesCnt'.$shopId,3600)->count(); + // 投诉订单数 + $stat['complainNum'] = Db::name('order_complains')->where(['respondTargetId'=>$shopId,'complainStatus'=>1])->count(); + // 近七天销售排行 + $start = date('Y-m-d H:i:s',strtotime("-7 day")); + $end = date('Y-m-d H:i:s'); + $stat['goodsTop'] = $rs = Db::field('og.goodsId,g.goodsName,goodsSn,sum(og.goodsNum) goodsNum,g.goodsImg') + ->name('order_goods') + ->alias('og') + ->join('__ORDERS__ o','og.orderId=o.orderId') + ->join('__GOODS__ g','og.goodsId=g.goodsId') + ->order('goodsNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where('(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1 and o.shopId='.$shopId)->group('og.goodsId') + ->limit(10)->select(); + return ['shop'=>$shop,'stat'=>$stat]; + } + /** + * 获取店铺信息 + */ + public function getByView($id){ + $shop = $this->alias('s')->join('__BANKS__ b','b.bankId=s.bankId','left') + ->where(['s.dataFlag'=>1,'shopId'=>$id]) + ->field('s.*,b.bankName')->find(); + $areaIds = []; + $areaMaps = []; + $tmp = explode('_',$shop['areaIdPath']); + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName']; + } + $tmp = explode('_',$shop['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue; + $areaNames[] = @$areaMaps[$vv]; + $shop['areaName'] = implode('',$areaNames); + } + } + + //获取经营范围 + $goodsCats = Db::name('goods_cats')->where(['parentId'=>0,'isShow'=>1,'dataFlag'=>1])->field('catId,catName')->select(); + $catshops = Db::name('cat_shops')->where('shopId',$id)->select(); + $catshopMaps = []; + foreach ($goodsCats as $v){ + $catshopMaps[$v['catId']] = $v['catName']; + } + $catshopNames = []; + foreach ($catshops as $key =>$v){ + if(isset($catshopMaps[$v['catId']]))$catshopNames[] = $catshopMaps[$v['catId']]; + } + $shop['catshopNames'] = implode('、',$catshopNames); + //获取认证类型 + $shop['accreds'] =Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','sac.accredId=a.accredId and a.dataFlag=1','inner') + ->where('sac.shopId',$id)->field('accredName,accredImg')->select(); + //开卡地址 + $areaNames = model('areas')->getParentNames($shop['bankAreaId']); + $shop['bankAreaName'] = implode('',$areaNames); + return $shop; + } + /** + * 获取店铺指定字段 + */ + public function getFieldsById($shopId,$fields){ + return $this->where(['shopId'=>$shopId,'dataFlag'=>1])->field($fields)->find(); + } + + /** + * 编辑店铺资料mark huang 20180312 限制银行卡信息只能修改一次 + */ + public function editInfo(){ +//添加旺旺类型mark by cheng 20180314 + $shopId = (int)session('WST_USER.shopId'); + $shop_data['shopImg'] = input('post.shopImg'); + $shop_data['isInvoice'] = input('post.isInvoice'); + $shop_data['invoiceRemarks'] = input('post.invoiceRemarks'); + $shop_data['serviceStartTime'] = input('post.serviceStartTime'); + $shop_data['serviceEndTime'] = input('post.serviceEndTime'); + $shop_data['freight'] = input('post.freight'); + $shop_data['shopQQ'] = input('post.shopQQ'); + $shop_data['shopWangWang'] = input('post.shopWangWang'); + $shop_data['shopWangWangType'] = input('post.shopWangWangType'); + $result = $this->validate('Shops.editInfo')->allowField(['shopImg','isInvoice','invoiceRemarks','serviceStartTime','serviceEndTime','freight','shopQQ','shopWangWang','shopWangWangType'])->save($shop_data,['shopId'=>$shopId]); + $bank_info = Db::name('shops')->where('shopId',$shopId)->field('bankNo,changeNum')->find(); + $bank_data['bankNo'] = input('post.bankNo'); + $result2 = true; + if($bank_info['changeNum'] == 0 && $bank_data['bankNo'] != $bank_info['bankNo']){ + $bank_data['bankUserName'] = input('post.bankUserName'); + $bank_data['bankId'] = input('post.bankId'); + $bank_data['changeNum'] = $bank_info['changeNum'] + 1; + $result2 = $this->allowField(['bankNo','bankUserName','shopId','bankId','changeNum'])->save($bank_data,['shopId'=>$shopId]); + }elseif($bank_info['changeNum'] > 0){ + if($bank_data['bankNo'] != $bank_info['bankNo'] ){ + $result2 = false; + }else{ + $result2 = true; + } + } + if(false !== $result){ + if(false == $result2){ + $msg='银行卡修改失败!'; + }else{ + $msg='!'; + } + return WSTReturn('店铺相关信息保存成功'.$msg,1); + }else{ + return WSTReturn($this->getError()); + } + } + + + /** + * 获取店铺提现账号 + */ + public function getShopAccount(){ + $shopId = (int)session('WST_USER.shopId'); + $shops = Db::name('shops')->alias('s')->join('banks b','b.bankId=s.bankId','inner')->where('s.shopId',$shopId)->field('b.bankName,s.bankAreaId,bankNo,bankUserName')->find(); + return $shops; + } + /** + * 保存入驻资料 + */ + public function saveStep2($data = []){ + $userId = (int)session('WST_USER.userId'); + //判断是否存在入驻申请 + $shops = $this->where('userId',$userId)->find(); + //新增入驻申请 + Db::startTrans(); + try{ + if(empty($shops)){ + $vshop = new VShop(); + $shop = ['userId'=>$userId,'applyStatus'=>0,'applyStep'=>2]; + $this->save($shop); + WSTAllow($data,implode(',',$vshop->scene['applyStep1'])); + $data['shopId'] = $this->shopId; + $result = Db::name('shop_extras')->insert($data); + $shopId = $this->shopId; + $WST_USER = session('WST_USER'); + $WST_USER['tempShopId'] = $shopId; + session('WST_USER',$WST_USER); + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + if($shops->applyStep<2){ + $shops->applyStep = 2; + $shops->save(); + } + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep1'])); + $result = Db::name('shop_extras')->where('shopId',$shops['shopId'])->update($data); + if(false !== $result){ + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + return WSTReturn('保存失败'); + } + } + }catch (\Exception $e) { + Db::rollback(); + return WSTReturn('保存失败',-1); + } + } + public function saveStep3($data = []){ + /* + legalCertificateImg + businessLicenceImg + bankAccountPermitImg + organizationCodeImg + */ + $auxiliary=explode(',',$data['shopAds']); + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep2'])); + //获取地区 + $areaIds = model('Areas')->getParentIs($data['businessAreaPath0']); + if(!empty($areaIds))$data['businessAreaPath'] = implode('_',$areaIds)."_"; + $areaIds = model('Areas')->getParentIs($data['areaIdPath0']); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + //if($data['isLongbusinessDate']==1)unset($data['businessEndDate']); + //if($data['isLonglegalCertificateDate']==1)unset($data['legalCertificateEndDate']); + //if($data['isLongOrganizationCodeDate']==1)unset($data['organizationCodeEndDate']); + Db::startTrans(); + try{ + if($shops->applyStep<3){ + $shops->applyStep = 3; + $shops->save(); + } + $validate = Loader::validate('Shops'); + if(!$validate->scene('applyStep2')->check($data))return WSTReturn($validate->getError()); + $seModel = model('ShopExtras'); + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + $Id = $seModel->where(['shopId'=>$shopId])->value('id');// 获取主键 + //启用上传图片 + WSTUseImages(0, $Id, $data['legalCertificateImg'],'shopextras'); + WSTUseImages(0, $Id, $data['businessLicenceImg'],'shopextras'); + WSTUseImages(0, $Id, $data['bankAccountPermitImg'],'shopextras'); + WSTUseImages(0, $Id, $data['organizationCodeImg'],'shopextras'); + $auxiliary_data=[]; + $shopAuxiliary = Db::name('shop_auxiliary')->where('shopId='.$shopId)->find(); + WSTUseImages(0, $shopAuxiliary['id'], $auxiliary,'shopauxiliary'); + Db::name('shop_auxiliary')->where('shopId='.$shopId)->delete(); + foreach($auxiliary as $k=>$v){ + $auxiliary_data[$k]['shopId']=$shopId; + $auxiliary_data[$k]['auxiliaryImg']=$v; + } + Db::name('shop_auxiliary')->insertAll($auxiliary_data); + $this->allowField(true)->save($data,['shopId'=>$shopId]); + Db::commit(); + return WSTReturn('保存成功',1); + }catch (\Exception $e) { + Db::rollback(); + return WSTReturn('保存失败',-1); + } + } + public function saveStep4($data = []){ + /* + taxRegistrationCertificateImg + taxpayerQualificationImg + */ + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep3'])); + $areaIds = model('Areas')->getParentIs($data['bankAreaId']); + if(!empty($areaIds))$data['bankAreaIdPath'] = implode('_',$areaIds)."_"; + Db::startTrans(); + try{ + if($shops->applyStep<4){ + $shops->applyStep = 4; + $shops->save(); + } + $seModel = model('ShopExtras'); + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + /*--------取消上传图片选项 mark hsf 20180104----------*/ + //$Id = $seModel->where(['shopId'=>$shopId])->value('id'); + //启用上传图片 + //WSTUseImages(0, $Id, $data['taxRegistrationCertificateImg'],'shopextras'); + // WSTUseImages(0, $Id, $data['taxpayerQualificationImg'],'shopextras'); + /*-------------------------end---------------------------*/ + $this->allowField(true)->save($data,['shopId'=>$shopId]); + Db::commit(); + return WSTReturn('保存成功',1); + }catch (\Exception $e) { + Db::rollback(); + return WSTReturn('保存失败',-1); + } + } + public function saveStep5($data = []){ + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + $filters = $vshop->scene['applyStep4']; + $filters[] = 'shopQQ'; + $filters[] = 'shopWangWang'; + WSTAllow($data,implode(',',$filters)); + $shopLicense=input('shopLicense'); + if((strpos($data['goodsCatIds'],'393')!==false)||$data['goodsCatIds']=='393'){ + if($shopLicense==""){ + + return WSTReturn('食品许可证不能为空'); + } + }else{ + $shopLicense=''; + } + Db::startTrans(); + try{ + $data['applyStatus'] = 1; + $data['applyTime'] = date('Y-m-d H:i:s'); + $find=$this->where('shopName',$data['shopName'])->find(); + if($find) return WSTReturn('此商铺名称已存在,请重新填写'); + $result = $this->allowField(true)->save($data,['shopId'=>$shopId]); + $row=db('shop_license')->insert(['shopId'=>$shopId,'shopLicense'=>$shopLicense]); + // // // 启用图片 + WSTUseImages(0, $shopId, $data['shopImg'],'shops','shopImg'); + //WSTUseImages(0, $shopId, $shopLicense,'shoplicense','shopLicense'); + + if($shops->applyStep<5){ + $shops->applyStep = 5; + $shops->save(); + } + if(false !== $result){ + //经营范围 + $goodsCats = explode(',',$data['goodsCatIds']); + foreach ($goodsCats as $v){ + if((int)$v>0)Db::name('cat_shops')->insert(['shopId'=>$shopId,'catId'=>$v]); + } + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + return WSTReturn('保存失败'); + } + }catch (\Exception $e) { + Db::rollback(); + return WSTReturn('保存失败',-1); + } + } + + /** + * 获取商家入驻资料 + */ + public function getShopApply(){ + $userId = (int)session('WST_USER.userId'); + $rs = $this->alias('s') + ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','inner') + ->where('s.userId',$userId) + ->find(); + if(!empty($rs)){ + $rs = $rs->toArray(); + $goodscats = Db::name('cat_shops')->where('shopId',$rs['shopId'])->select(); + $rs['catshops'] = []; + foreach ($goodscats as $v){ + $rs['catshops'][$v['catId']] = true; + } + $rs['taxRegistrationCertificateImgVO'] = ($rs['taxRegistrationCertificateImg']!='')?explode(',',$rs['taxRegistrationCertificateImg']):[]; + + }else{ + $rs = []; + $data1 = $this->getEModel('shops'); + $data2 = $this->getEModel('shop_extras'); + $rs = array_merge($data1,$data2); + $rs['taxRegistrationCertificateImgVO'] = []; + } + $rs['auxiliary']=db('shop_auxiliary')->where('shopId',$rs['shopId'])->select(); + return $rs; + } + + /** + * 判断是否申请入驻过 + */ + public function checkApply(){ + $userId = (int)session('WST_USER.userId'); + $rs = $this->where(['userId'=>$userId])->find(); + if(!empty($rs)){ + $WST_USER = session('WST_USER'); + $WST_USER['tempShopId'] = $rs->shopId; + session('WST_USER',$WST_USER); + session('apply_step',$rs['applyStep']); + } + return $rs; + } + /** + * 首页店铺街列表 + */ + public function indexShopQuery($num=4){ + /** 添加返回店铺街商店 mark hsf 20180223 */ + $shop_list = model('common/Tags')->listShop(0,$num,0); + foreach ($shop_list as &$v) { + $v['shopAddress'] = Db::name('shops')->where(['shopId'=>$v['shopId']])->value('shopAddress'); + $v['shopStreetImg'] = Db::name('shop_configs')->where(['shopId'=>$v['shopId']])->value('shopStreetImg'); + } + return $shop_list; + /** end */ + $rs = $this->alias('s') + ->join('__SHOP_CONFIGS__ sc','s.shopId=sc.shopId','inner') + ->field('s.shopId,s.shopName,s.shopAddress,sc.shopStreetImg') + ->limit($num) + ->select(); + return $rs; + } +} diff --git a/hyhproject/home/model/SpecItems.php b/hyhproject/home/model/SpecItems.php new file mode 100755 index 0000000..c080508 --- /dev/null +++ b/hyhproject/home/model/SpecItems.php @@ -0,0 +1,10 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 商品规格值类 + */ +use think\Db; +class SpecItems extends Base{ + +} diff --git a/hyhproject/home/model/Users.php b/hyhproject/home/model/Users.php new file mode 100755 index 0000000..7ca679b --- /dev/null +++ b/hyhproject/home/model/Users.php @@ -0,0 +1,33 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Users as CUsers; +/** + * ============================================================================ + * 用户类 + */ +use think\Db; +class Users extends CUsers{ + /** + * 获取各订单状态数、未读消息数、账户安全等级 + */ + function getStatusNum(){ + $userId = (int)session('WST_USER.userId'); + $data = []; + // 用户消息 + $data['message'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + //获取用户订单状态 + $data['waitPay'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['waitReceive'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>['in',[0,1]],'dataFlag'=>1])->count(); + $data['received'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'dataFlag'=>1])->count(); + $data['waitAppr'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + // 账户安全等级 + $level = 1; + $users = $this->field('userPhone,userEmail')->find($userId); + if(!empty($users['userPhone']))++$level; + if(!empty($users['userEmail']))++$level; + $data['level'] = $level; + //关注商品 + $data['gfavorite'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>0])->count(); + return $data; + } +} diff --git a/hyhproject/home/validate/Goods.php b/hyhproject/home/validate/Goods.php new file mode 100755 index 0000000..5510a41 --- /dev/null +++ b/hyhproject/home/validate/Goods.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\home\validate; +use think\Validate; +/** + * ============================================================================ + * 商品验证器 + */ +class Goods extends Validate{ + protected $rule = [ + ['goodsName' ,'require|max:300','请输入商品名称|商品名称不能超过100个字符'], + ['goodsImg' ,'require','请上传商品图片'], + ['goodsType' ,'in:,0,1','无效的商品类型'], + ['goodsSn' ,'checkGoodsSn:1','请输入商品编号'], + ['productNo' ,'checkProductNo:1','请输入商品货号'], + ['marketPrice' ,'checkMarketPrice:1','请输入市场价格'], + ['shopPrice' ,'checkShopPrice:1','请输入店铺价格'], + ['goodsUnit' ,'require','请输入商品单位'], + ['isSale' ,'in:,0,1','无效的上架状态'], + ['isRecom' ,'in:,0,1','无效的推荐状态'], + ['isBest' ,'in:,0,1','无效的精品状态'], + ['isNew' ,'in:,0,1','无效的新品状态'], + ['isHot' ,'in:,0,1','无效的热销状态'], + ['isFreeShipping','in:,0,1','无效的包邮状态'], + ['goodsCatId' ,'require','请选择完整商品分类'], + ['goodsDesc','require','请输入商品描述'], + ['specsIds','checkSpecsIds:1','请填写完整商品规格信息'] + ]; + /** + * 检测商品编号 + */ + protected function checkGoodsSn($value){ + $goodsId = Input('post.goodsId/d',0); + $key = Input('post.goodsSn'); + if($key=='')return '请输入商品编号'; + $isChk = model('Goods')->checkExistGoodsKey('goodsSn',$key,$goodsId); + if($isChk)return '对不起,该商品编号已存在'; + return true; + } + /** + * 检测商品货号 + */ + protected function checkProductNo($value){ + $goodsId = Input('post.goodsId/d',0); + $key = Input('post.productNo'); + if($key=='')return '请输入商品货号'; + $isChk = model('Goods')->checkExistGoodsKey('productNo',$key,$goodsId); + if($isChk)return '对不起,该商品货号已存在'; + return true; + } + /** + * 检测价格 + */ + public function checkMarketPrice(){ + $marketPrice = floatval(input('post.marketPrice')); + if($marketPrice<0.01)return '市场价格不能小于0.01'; + return true; + } + public function checkShopPrice(){ + $shopPrice = floatval(input('post.shopPrice')); + if($shopPrice<0.01)return '店铺价格不能小于0.01'; + return true; + } + /** + * 检测商品规格是否填写完整 + */ + public function checkSpecsIds(){ + $specsIds = input('post.specsIds'); + if($specsIds!=''){ + $str = explode(',',$specsIds); + $specsIds = []; + foreach ($str as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsIds))$specsIds[] = $vv; + } + } + //检测规格名称是否填写完整 + foreach ($specsIds as $v){ + if(input('post.specName_'.$v)=='')return '请填写完整商品规格值'; + } + //检测销售规格是否完整 + foreach ($str as $v){ + if(input('post.productNo_'.$v)=='')return '请填写完整商品销售规格-货号'; + if(input('post.marketPrice_'.$v)=='')return '请填写完整商品销售规格-市场价'; + if(floatval(input('post.marketPrice_'.$v))<0.01)return '商品销售规格-市场价不能小于0.01'; + if(input('post.specPrice_'.$v)=='')return '请填写完整商品销售规格-本店价'; + if(floatval(input('post.specPrice_'.$v))<0.01)return '商品销售规格-本店价不能小于0.01'; + if(input('post.specStock_'.$v)=='')return '请填写完整商品销售规格-库存'; + if(intval(input('post.specStock_'.$v))<0)return '商品销售规格-库存不能小于0'; + if(input('post.warnStock_'.$v)=='')return '请填写完整商品销售规格-预警库存'; + if(intval(input('post.warnStock_'.$v))<0)return '商品销售规格-预警库存不能小于0'; + } + if(input('post.defaultSpec')=='')return '请选择推荐规格'; + } + return true; + } +} \ No newline at end of file diff --git a/hyhproject/home/validate/Shops.php b/hyhproject/home/validate/Shops.php new file mode 100755 index 0000000..1dd4e72 --- /dev/null +++ b/hyhproject/home/validate/Shops.php @@ -0,0 +1,118 @@ +<?php +namespace wstmart\home\validate; +use think\Validate; +/** + * ============================================================================ + * 店铺验证器 + */ +class Shops extends Validate{ + protected $rule = [ + //入驻步骤1 + ['applyLinkMan','require','请输入联系人姓名'], + ['applyLinkTel','require','请输入联系人手机'], + // ['applyLinkEmail','require','请输入联系人邮箱'], + ['isInvestment','in:0,1','无效的对接商城招商人参数'], + ['investmentStaff','checkInvestment:1','请输入商城招商人员姓名'], + //入驻步骤2 + ['businessLicenceType','require','请选择执照类型'], + ['businessLicence','require','请输入营业执照注册号'], + ['legalPersonName','require','请输入法定代表人姓名'], + //['businessAreaPath0','require','请选择营业执照所在地'], + //['licenseAddress','require','请输入营业执照详细地址'], + //['establishmentDate','require','请选择成立日期'], + //['businessStartDate','require','请输入营业期限开始日期'], + //['businessEndDate','checkBusinessEndDate:1','请输入营业期限结束日期'], + //['isLongbusinessDate','in:0,1','无效的营业期限参数'], + //['registeredCapital','require','请输入注册资本'], + //['empiricalRange','require','请输入经营范围'], + ['areaIdPath0','require','请选择公司所在地'], + ['shopCompany','require','请输入公司名称'], + ['shopAddress','require','请输入公司详细地址'], + ['shopTel','require','请输入公司电话'], + // mark by cheng 添加开店必须输入旺旺和qq20130318 + //['shopWangWang','require','请输入店铺客服旺旺'], + //['shopQQ','require','请输入店铺客服QQ'], + ['shopkeeper','require','请输入公司紧急联系人'], + ['telephone','require','请输入公司紧急联系人电话'], + ['legalCertificateType','require','请选择法人代表证件类型'], + ['legalCertificate','require','请输入法定代表人证件号'], + //['legalCertificateStartDate','require','请选择法定代表人证件有效期开始日期'], + //['legalCertificateEndDate','checkLegalCertificateEndDate:1','请选择法定代表人证件有效期结束日期'], + //['isLonglegalCertificateDate','in:0,1','无效的代表人证件有效期参数'], + ['legalCertificateImg','require','请上传法人证件电子版'], + ['businessLicenceImg','require','请上传营业执照电子版'], + ['bankAccountPermitImg','require','请上传银行开户许可证电子版'], + // ['organizationCode','require','请输入组织机构代码'], + // ['organizationCodeStartDate','require','请输入商标注册证有效期开始日期'], + // ['organizationCodeEndDate','checkOrganizationCodeEndDate:1','请输入商标注册证有效期结束日期'], + // ['isLongOrganizationCodeDate','in:0,1','无效的商标注册证有效期参数'], + ['organizationCodeImg','require','请上传商标注册证电子版'], + //入驻步骤3 + /*--------取消上传图片选项 mark hsf 20180104----------*/ + //['taxpayerType','require','请选择纳税人类型'], + //['taxpayerNo','require','请输入纳税人识别号'], + //['taxRegistrationCertificateImg','require','请上传税务登记证电子版'], + //['taxpayerQualificationImg','require','请上传一般纳税人资格证电子版'], + /*-------------------------end-------------------------*/ + ['bankUserName' ,'require|max:100','请输入持卡人名称|持卡人名称长度不能能超过50个字符'], + ['bankNo' ,'require','请选择银行账号'], + ['bankId' ,'require','请选择结算银行'], + //['bankAreaId' ,'require','请选择开户所地区'], + //入驻步骤4 + ['shopName' ,'require','请输入店铺名称'], + ['shopImg' ,'require','请上传店铺图标'], + ['goodsCatIds' ,'require','请选择经营类目'], + ['isInvoice' ,'in:0,1','无效的发票类型'], + ['invoiceRemarks','checkInvoiceRemark:1','请输入发票说明'], + ['freight','integer','请输入运费'], + ['serviceStartTime','require','请选择服务开始时间'], + ['serviceEndTime','require','请选择服务结束时间'] + ]; +/* + public $scene = [ + 'editInfo' =>['shopImg','isInvoice','serviceStartTime','serviceEndTime','freight'], + 'editBank' =>['bankId','bankAreaId','bankNo','bankUserName'], + 'applyStep1'=>['applyLinkMan','applyLinkTel','applyLinkEmail','isInvestment','investmentStaff'], + 'applyStep2'=>['businessLicenceType','businessLicence','legalPersonName','businessAreaPath0','licenseAddress','establishmentDate','businessStartDate','businessEndDate','isLongbusinessDate','registeredCapital','empiricalRange','areaIdPath0','shopCompany','shopAddress','shopTel','shopkeeper','telephone','shopEmergencyLinkMan','legalCertificateType','legalCertificate','legalCertificateStartDate','legalCertificateEndDate','isLonglegalCertificateDate','legalCertificateImg','businessLicenceImg','bankAccountPermitImg','organizationCode','organizationCodeStartDate','organizationCodeEndDate','organizationCodeImg'], + 'applyStep3'=>['taxpayerType','taxpayerNo','taxRegistrationCertificateImg','taxpayerQualificationImg','bankUserName','bankNo','bankId','bankAreaId'], + 'applyStep4'=>['shopName','shopImg','goodsCatIds','isInvoice','invoiceRemarks','freight','serviceStartTime','serviceEndTime'] + ]; + */ + //添加旺旺和qq非空验证 mark by cheng 20170318 + public $scene = [ + 'editInfo' =>['shopImg','isInvoice','serviceStartTime','serviceEndTime','freight'], + 'editBank' =>['bankId','bankAreaId','bankNo','bankUserName'], + 'applyStep1'=>['applyLinkMan','applyLinkTel','applyLinkEmail','isInvestment','investmentStaff'], + 'applyStep2'=>['businessLicenceType','businessLicence','legalPersonName','businessAreaPath0','licenseAddress','establishmentDate','businessStartDate','businessEndDate','isLongbusinessDate','registeredCapital','empiricalRange','areaIdPath0','shopCompany','shopAddress','shopTel','shopkeeper','telephone','shopEmergencyLinkMan','legalCertificateType','legalCertificate','legalCertificateStartDate','legalCertificateEndDate','isLonglegalCertificateDate','legalCertificateImg','businessLicenceImg','bankAccountPermitImg','organizationCode','organizationCodeStartDate','organizationCodeEndDate','organizationCodeImg'], + 'applyStep3'=>['taxpayerType','taxpayerNo','taxRegistrationCertificateImg','taxpayerQualificationImg','bankUserName','bankNo','bankId','bankAreaId'], + 'applyStep4'=>['shopName','shopImg','goodsCatIds','isInvoice','invoiceRemarks','freight','serviceStartTime','serviceEndTime'] + ]; + + protected function checkInvoiceRemark($value){ + $isInvoice = input('post.isInvoice/d',0); + $key = Input('post.invoiceRemarks'); + return ($isInvoice==1 && $key=='')?'请输入发票说明':true; + } + + protected function checkInvestment($value){ + $isInvestment = input('post.isInvestment/d',0); + $key = Input('post.investmentStaff'); + return ($isInvestment==1 && $key=='')?'请输入商城招商人员姓名':true; + } + + protected function checkBusinessEndDate($value){ + $isLongbusinessDate = input('post.isLongbusinessDate/d',0); + $key = Input('post.businessEndDate'); + return ($isLongbusinessDate==0 && $key=='')?'请输入营业期限结束日期':true; + } + protected function checkLegalCertificateEndDate($value){ + $isLonglegalCertificateDate = input('post.isLonglegalCertificateDate/d',0); + $key = Input('post.legalCertificateEndDate'); + return ($isLonglegalCertificateDate==0 && $key=='')?'请选择法定代表人证件有效期结束日期':true; + } + protected function checkOrganizationCodeEndDate($value){ + // $isLonglegalCertificateDate = input('post.isLongOrganizationCodeDate/d',0); + // $key = Input('post.organizationCodeEndDate'); + // return ($isLonglegalCertificateDate==0 && $key=='')?'请输入商标注册证有效期结束日期':true; + } +} \ No newline at end of file diff --git a/hyhproject/home/view/default/base.html b/hyhproject/home/view/default/base.html new file mode 100755 index 0000000..d289708 --- /dev/null +++ b/hyhproject/home/view/default/base.html @@ -0,0 +1,47 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +{block name="meta"}{/block} +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> + +{/*未登录的话加载登录框所需要的文件*/} +{if ((int)session('WST_USER.userId')<=0) } +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/js/login.js?v={$v}'></script> +{/if} +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","SMS_OPEN":"{:WSTConf('CONF.smsOpen')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} +$(function() { + WST.initVisitor(); +}); +</script> +</head> + +<body> +{block name="top"} + {include file="default/top" /} +{/block} +{block name="header"} + {if isset($selfShop)} + {include file="default/self_shop_header" /} + {else /} + {include file="default/header" /} + {/if} +{/block} +{block name="main"}主内容{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}{/block} +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home/view/default/css/articles.css b/hyhproject/home/view/default/css/articles.css new file mode 100755 index 0000000..c47a3ac --- /dev/null +++ b/hyhproject/home/view/default/css/articles.css @@ -0,0 +1,46 @@ +.bc-nav{width:100%;height:35px;border-bottom:1px solid lightgreen} +.help-box{width:1200px;margin:0 auto;min-height:600px} +.help-left{width:210px;margin:15px;margin-left:0;float:left;background:#fff} +.help-right{width:970px;overflow-x:hidden;min-height:400px;background:white;float:left;margin-top:15px} +.h-content{padding:10px;width:950px;min-height:370px;text-indent:7px;font-family:"microsoft yahei"} +.h-content .head{padding-bottom:26px} +.h-content .head p{float:left;min-width:230px;font-size:16px;height:36px;line-height:36px;border-bottom:2px solid #8b8b8b} +.h-content .head p span{font-size:28px} +.h-title{height:36px;line-height:36px;text-align:center;font-size:16px;color:white;font-weight:bold} +.h-hide ul{display:none} +.h-hide p{margin:14px 5px 0 0;float:right;display:inline-block;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid#ccc} +#parent>li>span{display:block;padding-left:10px;background:#eaeaea;border-bottom:1px solid #fff}#parent>li>span:hover{cursor:pointer;background:#dadada} +#parent>li{line-height:33px;display:block} +.h-show ul{display:block} +.h-show p{margin:14px 5px 0 0;float:right;display:inline-block;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid#ccc} +.h-list{border:1px solid #dedede} +.h-list li{width:177px;line-height:20px;margin:5px 0 5px 10px;padding:2px 0;padding-left:20px;cursor:pointer} +.h-list .h-curr{margin-left:10px} +.h-curr{background:rgba(0,0,0,0) linear-gradient(to right,#eaeaea,#fff) repeat scroll 0 0;border-color:#dedede;border-image:none;border-width:1px;color:green;font-weight:bold} +.h-list a:hover li{color:green;font-weight:bold} +.bc-nav{line-height:35px} +.bc-nav>p{width:1200px;margin:0 auto} +.bc-nav>p>a{color:gray} +.b{border:1px solid #e0dddd} +.h-right-title{width:100%;height:25px;margin-left:5px;margin-top:15px} +.h-right-title>h4{float:left;font-size:19px}#square{margin:5px;width:6px;height:6px;background:#df2003;float:left} +.b-99{background:#7dd589} +.h-record{padding:5px;width:100%;height:100px;margin-top:20px;border-top:1px solid #e0dddd} +.h-record>p{padding:5px} +.h-button{width:100px;height:25px;color:#6f6666;margin-left:5px} +.h-content h1{text-align:center} +.h-content .cat-time{text-align:center;padding:10px 0} +.c{clear:both} +.b-lg{background:#7dd589} +.news-list a,.list-time{font-size:13px;letter-spacing:2px;color:#333} +.news-list li{padding:8px 5px;border-bottom:1px dashed #ccc} +.news-list a:hover{font-size:13px;letter-spacing:2px;color:#40bb6a} +.list-time{display:block;float:right} +#g-square{margin:8px 0;width:3px;height:3px;background:#333;float:left} +.n-content{width:100%;min-height:300px;overflow:hidden} +.h-page{position:relative;width:100%;height:100px;background:url(../img/img_yingyin.png) 0 68px no-repeat} +.h-page .pagination .active{background:#3fba6a;color:white} +.h-page .pagination .disabled span,.h-page .pagination .active span{left:30px;line-height:28px;padding-left:4px} +.h-page .pagination{position:relative;top:32px;left:30%;width:100%;height:30px} +.h-page .pagination li{margin:0 auto;width:28px;height:28px;border:1px solid #bfbfbf;float:left;margin-left:10px} +.h-page .pagination li a{line-height:28px;padding-left:4px} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/brandslist.css b/hyhproject/home/view/default/css/brandslist.css new file mode 100755 index 0000000..dbae116 --- /dev/null +++ b/hyhproject/home/view/default/css/brandslist.css @@ -0,0 +1,44 @@ +@CHARSET "UTF-8";.wst-brand-cat{margin:10px 0 20px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-brand-cat{margin:10px 0 0px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-brand-catt{height:23px;color:#333;border-bottom:1px dashed #b5b5b5} +.wst-brand-cat span{float:left;margin:8px 60px 0 0;padding:8px 5px} +.wst-brand-cat span:hover{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.js-selected{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.wst-brands{float:left;margin:10px 20px} +.wst-brand-img{width:200px;height:200px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-brand-img a{width:200px;height:200px;display:table-cell;vertical-align:middle} +.wst-brand-img a img{max-width:200px;max-height:200px} +.wst-brand-name{position:relative;text-align:center;height:30px;line-height:30px;color:#353535;font-family:fantasy} +.brandsPaging{padding:20px 0 50px 480px} +.wst-brands-list li{-webkit-perspective:400px;perspective:400px} +.info{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg);width:100%;height:100%;padding:20px;position:absolute;top:0;left:0;border-radius:4px;pointer-events:none;background-color:#000;opacity:.6} +.in-top .info{-webkit-transform-origin:50% 0;transform-origin:50% 0;-webkit-animation:in-top 300ms ease 0ms 1 forwards;animation:in-top 300ms ease 0ms 1 forwards} +.in-right .info{-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-animation:in-right 300ms ease 0ms 1 forwards;animation:in-right 300ms ease 0ms 1 forwards} +.in-bottom .info{-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-animation:in-bottom 300ms ease 0ms 1 forwards;animation:in-bottom 300ms ease 0ms 1 forwards} +.in-left .info{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-animation:in-left 300ms ease 0ms 1 forwards;animation:in-left 300ms ease 0ms 1 forwards} +.out-top .info{-webkit-transform-origin:50% 0;transform-origin:50% 0;-webkit-animation:out-top 300ms ease 0ms 1 forwards;animation:out-top 300ms ease 0ms 1 forwards} +.out-right .info{-webkit-transform-origin:100% 50%;transform-origin:100% 50%;-webkit-animation:out-right 300ms ease 0ms 1 forwards;animation:out-right 300ms ease 0ms 1 forwards} +.out-bottom .info{-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-animation:out-bottom 300ms ease 0ms 1 forwards;animation:out-bottom 300ms ease 0ms 1 forwards} +.out-left .info{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-animation:out-left 300ms ease 0ms 1 forwards;animation:out-left 300ms ease 0ms 1 forwards} +@-webkit-keyframes in-top{from{-webkit-transform:rotate3d(-1,0,0,90deg);transform:rotate3d(-1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-top{from{-webkit-transform:rotate3d(-1,0,0,90deg);transform:rotate3d(-1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-right{from{-webkit-transform:rotate3d(0,-1,0,90deg);transform:rotate3d(0,-1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-right{from{-webkit-transform:rotate3d(0,-1,0,90deg);transform:rotate3d(0,-1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-bottom{from{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-bottom{from{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-left{from{-webkit-transform:rotate3d(0,1,0,90deg);transform:rotate3d(0,1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-left{from{-webkit-transform:rotate3d(0,1,0,90deg);transform:rotate3d(0,1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes out-top{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(-1,0,0,104deg);transform:rotate3d(-1,0,0,104deg)} +}@keyframes out-top{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(-1,0,0,104deg);transform:rotate3d(-1,0,0,104deg)} +}@-webkit-keyframes out-right{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,-1,0,104deg);transform:rotate3d(0,-1,0,104deg)} +}@keyframes out-right{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,-1,0,104deg);transform:rotate3d(0,-1,0,104deg)} +}@-webkit-keyframes out-bottom{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(1,0,0,104deg);transform:rotate3d(1,0,0,104deg)} +}@keyframes out-bottom{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(1,0,0,104deg);transform:rotate3d(1,0,0,104deg)} +}@-webkit-keyframes out-left{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,1,0,104deg);transform:rotate3d(0,1,0,104deg)} +}@keyframes out-left{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,1,0,104deg);transform:rotate3d(0,1,0,104deg)} +} +.wst-brands-list:after{content:"";display:table;clear:both} +.wst-brands-list li{position:relative;float:left;width:200px;height:200px;margin:10px 20px 30px 20px;padding:0;list-style:none} +.wst-brands-list span{float:left;width:100%;color:#fff;margin:35px 0 10px 70px} +.wst-brands-list p{float:left;width:100%;color:#fff;font-size:20px;text-align:center} +.info,.info:after,.info:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/carts.css b/hyhproject/home/view/default/css/carts.css new file mode 100755 index 0000000..5a9ada0 --- /dev/null +++ b/hyhproject/home/view/default/css/carts.css @@ -0,0 +1,210 @@ +.stepflex{float:right;border-top:5px solid #ccc;text-align:center;width:480px;margin:60px 0px 0px 50px;} +.stepflex dl{border-top:5px solid #ccc;float:left;position:relative;top:-5px;width:160px;} +dl.doing{border-top-color:#04bd3d;} +.doing .s-num{background-position:-23px 0;} +.s-num,.s-num1{color:#fff;font-weight: 700;height:23px;line-height:23px;margin:-15px auto 0;position:relative;width:23px;border-radius:25px;} +.s-num{background:#04bd3d;} +.s-num1{background:#ccc;} +.s-text1{line-height:30px;} +.s-text{line-height:30px;color:#04bd3d;} +/**购物车**/ +.main-head{font-size:17px;font-weight:bold;height:35px;line-height:35px;} +.cart-box{width:100%;border-top:2px solid #FC7A64;} +.cart-head{background: #f3f3f3;display: block;height: 25px;line-height: 25px;margin: 0 0 5px;padding: 5px 0;} +.cart-head .chk{float:left;width:100px;padding-left:10px;} +.cart-head .goods{float:left;width:550px;} +.cart-head .price{float:left;width:105px;} +.cart-head .stock{float:left;width:105px;} +.cart-head .num{float:left;width:120px;} +.cart-head .t-price{float:left;width:105px;} +.cart-head .action{float:left;width:95px;} +.cart-box .shop{padding-left:10px;line-height:25px;border-bottom:2px solid #d0e2ff;padding-bottom:5px;} +.cart-box .shop .shop-title{width:40%;float:left;} +.cart-box .goods-list{width:100%;} +.cart-box .item{display:block;padding-top:10px;padding-bottom:10px;border-bottom:1px solid #ECECEC;} +.cart-box .item .chk{float:left;width:20px;padding-left:10px;} +.cart-box .item .goods{float:left;width:630px;} +.cart-box .item .goods .img{float:left;width:80px;height:80px;margin-left:10px;} +.cart-box .item .goods .name{float:left;width:340px;height:80px;padding-left:5px;} +.cart-box .item .goods .spec{float:left;width:180px;padding-left:5px;} +.cart-box .item .price{float:left;width:105px;} +.cart-box .item .stock{float:left;width:105px;} +.cart-box .item .num{float:left;width:120px;} +.buy-btn{color:#666;background:#eeeeee;cursor: pointer;float:left;;display:block;height:20px;line-height:20px;padding:0px 5px;border:1px solid #ddd;} +input[type="text"].buy-num{height:16px;text-align:center;width:40px;float:left;border-left:0px;border-right:0px;border-top:1px solid #ddd;border-bottom:1px solid #ddd;} +.item .t-price{float:left;width:105px;} +.item .action{float:left;width:95px;} +.selected{background:#fbfcff;} +.selected2{background:#f2f7ff;} +.cart-footer{margin-bottom:15px;} +.cart-footer .summarys1{float:left;width:360px;} +.cart-footer .summarys2{float:left;width:360px;} +.cart-footer .summarys3{float:right;width:1180px;border-top:1px dotted #ddd;padding-top:10px;} +.cart-summary{border-bottom:1px solid #eeeeee;display:block;height:50px;line-height:50px;} +.summary{float:right;height:50px;line-height:50px;padding-right:10px;} +#totalMoney{color:#C00;font-size:16px;margin-left:5px;} +.cart-btn{margin:20px 0px;padding-right:20px;} +.wst-contnue{float:left;margin-left:20px;width:105px;height:33px;line-height:33px;} +.wst-next{float:right;margin-right:20px;width:118px;height:33px;line-height:33px;} +.wst-order-success{width:135px;height:35px;line-height:35px;display: block;} +.empty-cart{height:80px;line-height:80px;font-size:20px;text-align:center;} +.empty-cart a{color:blue;font-size:20px;} +/**结算页面**/ +.box-head{font-weight:bold;height:30px;line-height:30px;} +.box-head2{font-weight:bold;height:30px;line-height:30px;padding-left:5px;} +.cart-box2{width:100%;border:1px solid #eeeeee;padding:5px 0px 10px 0px;} +.cart-head2{border-top:2px solid #e7e7e7;background: #f3f3f3;display: block;height: 25px;line-height: 25px;padding: 5px 0;} +.cart-head2 .goods2{float:left;width:745px;padding-left:15px;} +.cart-head2 .price2{float:left;width:105px;} +.cart-head2 .stock2{float:left;width:105px;} +.cart-head2 .num2{float:left;width:120px;} +.cart-head2 .t-price2{float:left;width:195px;text-align:right;} +.cart-box2 .shop2{padding-left:15px;height:35px;line-height:35px;border-bottom:2px solid #d0e2ff;color:#E55356;font-weight:bold;font-size:15px;} +.cart-box2 .item{padding:5px 0px 5px 0px} +.cart-box2 .item .goods2{float:left;width:745px;padding-left:15px;} +.cart-box2 .item .goods2 .img2{float:left;width:80px;height:80px;} +.cart-box2 .item .goods2 .name2{float:left;width:470px;height:80px;margin-left:5px;} +.cart-box2 .item .goods2 .spec2{float:left;width:180px;margin-left:5px;} +.cart-box2 .item .price2{float:left;width:105px;} +.cart-box2 .item .stock2{float:left;width:105px;} +.cart-box2 .item .num2{float:left;width:120px;} +.cart-box2 .item .t-price2{float:left;width:195px;font-weight: bold;color: #E55356;text-align:right;} +.cart-summary2{margin-top:10px;} +.summary2{height:30px;line-height:30px;} +.shop-remark{padding:0px 5px 0px 15px} +.shop-remark .shop-remark-box{width:500px;padding-top:20px;padding-bottom:30px;display: inline-block;position: relative;vertical-align: top;} +.shop-remark .shop-summary{width:650px;padding-top:20px;padding-bottom:30px;padding-left:10px;display: inline-block;border-left:1px solid #fff;} +.shop-remark .shop-summary .row{height:25px;line-height: 25px;} +.shop-remark .shop-summary dt{width:140px;display:inline-block;text-align: right} +.shop-remark .shop-summary dd{width:500px;display:inline-block} +#totalPrice{color:#FE0000;font-size:16px;margin-left:5px;} +#deliverMoney{color:#FE0000;font-size:16px;margin-left:5px;} +#orderScore{margin-right:5px;} +.wst-prev{float:left;margin-left:10px;} +.wst-order{float:right;} +/**用户地址**/ +.add-addr{font-weight: normal;color:#005ea7;display: block;float:right;margin-right: 5px;} +.add-addr:hover{color:red;} +.address-box{border-top:2px solid #FC7A64;border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{float: left;width:180px;margin: 2px 8px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame2{float: left;min-width:120px;margin: 2px 20px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;padding:6px;} +/**支付方式**/ +.pay-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.pay-boxs{padding:10px 0px 5px 5px;} +.pay-box ul{padding-left:15px;} +.pay-box ul li{width:1185px;} +.pay-box .label{width:200px;float:left;height:30px;line-height:30px;} +.pay-box .txt{height:auto;line-height:30px;width:985px;float:left;color:#999999;} +.pay-sbox{border:1px solid #eeeeee;padding:5px 0px;} +.pay-sbox-head{border-bottom: 2px solid #ddd;line-height:35px;} +.pay-tip1{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -10px;background-size: cover; } +.pay-tip2{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -71px;background-size: cover; } +.pay-tip3{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -132px;background-size: cover; } +.pay-sbox .qrcode-box{min-height: 300px;height: auto;} +.pay-sbox .tips-box{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .qrcode-box .pbox{text-align: center;margin-top: 10px;font-weight: bold;} +.pay-sbox .wst-qrcode{width:260px;height:260px;text-align:center;margin:0 auto;} +.pay-sbox .wst-qrcode img{width:260px;height:260px;} +.pay-sbox .bnt-box{line-height:35px;text-align:center;font-weight: bold;padding:5px 10px;line-height:50px;} +.pay-sbox .pay-type{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .pay-list{text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .succ-box{text-align: center;padding: 50px;} +.wst-payCode-weixinpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-weixinpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-wallets {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/wallets.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-wallets-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/wallets.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-unionpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/unionpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-unionpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/unionpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.pay-sbox .balance-box{min-height: 300px;height: auto;} +.pay-sbox .balance-box .pbox{text-align: center;padding-top: 40px;font-weight: bold;} +.pay-sbox .balance-box .pbox2{text-align: center;padding-top: 10px;font-weight: bold;} +.pbox-tip{color:#0ae;margin-left:10px;} +.pay-btn{background: #eb5f43 none repeat scroll 0 0;border: 1px solid #d33110;border-radius: 3px;color: #ffffff;cursor: pointer;outline: medium none;} +.pay-sbox .wst-pay-bnt {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px 0px;cursor:pointer;} +.pay-sbox .wst-pay-bnt:hover {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px -57px;cursor:pointer;} +.wst-wallet-box{border:1px solid #ddd;margin:10px;padding:5px;line-height: 35px;height:40px;} +.wst-wallet-box .wst-wallte-item{background:url("../img/icon_qianbaoyue.png") no-repeat;padding-left:30px;height:30px;margin-top:5px;float:left;} +/**送货方式**/ +.shipping-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.shipping-box ul{padding-left:15px;} +.shipping-box ul li{height:auto;line-height:30px;} +/**发票**/ +.invoice-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.invoice-box ul{padding-left:15px;} +.invoice-box ul li{height:auto;line-height:30px;} +/**订单成功**/ +.success-box{border:1px solid #ddd;height:300px;margin-bottom:30px;text-align:center;} +.success-box .imgs{margin: 0 auto;padding-top:72px;width:18%;} +.success-box .imgs span{color:#11cd6e;font-family:"microsoft yahei";font-size: 22px;line-height:65px;margin-left:8x} +.success-box .info{margin: 6px auto;padding-top:16px;width:100%;font-size: 20px;} +.success-box .info a{color:#51cff5;font-size: 20px;} +.success-box .info span{color:#f33d2f;font-size: 20px;} +.success-box .go{margin: 26px auto;width:12%;} +/*按钮*/ +.wst-cart-reda{font-size: 14px;color:#ffffff;background: #df2003;text-align:center;border-radius:3px;font-family:"microsoft yahei";box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);} +.wst-cart-reda:hover{color:#ffffff;background:#ea3232;box-shadow: 0 0px 0px rgba(0, 0, 0, 0.3);} +.wst-cart-asha{font-size: 14px;background: #ffffff;text-align:center;border-radius: 3px;border: 1px solid #dad7d7;font-family:"microsoft yahei";box-shadow: 0 0px 1px rgba(0, 0, 0, 0.3);} +.wst-cart-asha:hover{background:#f1f1f1;box-shadow: 0 0px 0px rgba(0, 0, 0, 0.3);} +/*自定义单选框样式*/ +.wst-radio + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;border-radius: 50px;display: inline-block;position: relative;} +.wst-radio + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-radio:checked + label{border: 1px solid #fc6047;} +.wst-radio:checked + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #fc6047;box-shadow: inset 0px 0px 10px #fc6047;text-shadow: 0px;left: 3px;font-size: 32px;z-index:100;} +.radio-box .wst-radio{position:relative;z-index:-100;left:0px;top:0px;} +.radio-box-hover{background: #fff3f3;} +.operate-box a{color:#1c9eff;} +.operate-box a:hover{color:red;} +.operate-box{float:right;display: none;margin-right: 5px;} +.mt-1{position:relative;top:1px;left:-16px;cursor:pointer;} +/**订单列表**/ +.wst-check-orders{color:#1D94D7;cursor:pointer;} +.wst-order-list{width:100%;border-collapse:collapse;border-color:grey;} +.wst-order-list .head{height: 32px;line-height: 32px;text-align: center;background: #f5f5f5;color: #666;font-weight: 400;} +.wst-order-list .goods-img{width:60px; height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left;} +.wst-order-list .goods-img a{display:table-cell;vertical-align:middle;width:60px;height:60px;} +.wst-order-list .goods-img a img{max-width:60px;max-height:60px;} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:500px;} +.wst-order-list .goods-extra{float:right;margin-left:5px;} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px;} +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd;} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px;} +.wst-order-list td,.wst-order-list th {padding: 5px 10px;border: 1px solid #e5e5e5;border-top: 0px;} +.wst-order-list td,.wst-order-list th.wst-left-noborder{border-left:0;} +.wst-order-list td,.wst-order-list th.wst-right-noborder{border-right:0;} +.wst-order-list .otbody{text-align: center;} +/* 发票信息 */ +.invoice_box{margin-top: 30px;} +.invoice_item{width:85%;margin:0 auto;overflow: hidden;padding-top: 10px;} +.invoice_left{width:25%;float: left;text-align: right;color: #666;font-size: 14px;padding: 4px 0px;} +.tc{text-align: center} +.invoice_right{width: 70%;float: left;} +.inv_ul{width: 100%;overflow-y: scroll;max-height: 132px;} +.inv_li{position: relative;border:1px solid #eee;padding:5px;margin-bottom: 10px;padding:6px;cursor: pointer;} +.inv_li_curr i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.inv_li_curr{border: 2px solid #e4393c!important;padding:6px!important;} +.inv_li:hover .inv_opabox{display: block;} +.inv_opabox{display:none;position: absolute;right: 10%;top: 8px;} +.inv_add,.inv_opabox a{color: #00a0d5;cursor: pointer;} +.inv_add:hover,.inv_opabox a:hover{color: red} +.inv_opabox a{display: inline-block;margin-right: 15px;} +.inv_li1{position: relative;border:1px solid #eee;padding:5px;margin-bottom: 10px;padding:6px;cursor: pointer;float: left;margin-right:5px;} +.inv_codebox{display: none;} +.invoice_input{height:21px!important;padding: 1px;border:none!important;} +.inv_btn{display: inline-block;padding: 5px 10px;color: #fff;background: #e74649;margin-right: 10px;border: 1px solid #e74649;} +.inv_cancel{color: #323333;text-decoration: none;border: 1px solid #ddd;box-shadow: 0 1px 1px rgba(0,1,1,.08);background-color: #f7f7f7;} + diff --git a/hyhproject/home/view/default/css/common.css b/hyhproject/home/view/default/css/common.css new file mode 100755 index 0000000..6ede9c1 --- /dev/null +++ b/hyhproject/home/view/default/css/common.css @@ -0,0 +1,297 @@ +@CHARSET "UTF-8";body{color:#333;font:12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif} +*{padding:0;margin:0} +ol,ul{list-style:none} +a{color:#333;text-decoration:none} +a:hover{text-decoration:none} +img{border:0} +select{background-color:#fff;border:1px solid #ccc;border-radius:2px;height:24px;margin:2px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 1px rgba(0,0,0,0.075) inset} +input[type=text],input[type=password]{border:1px solid #ccc;height:23px;line-height:17px;padding:2px}input[type="radio"],input[type="checkbox"]{margin:2px} +input[type=button]{cursor:pointer} +.wst-relative{position: relative;} +.wst-clear{clear:both} +.wst-lfloat{float:left} +.wst-rfloat{float:right} +.wst-hide{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px 5px} +.wst-redlink{width:95%;display:block;cursor:pointer} +.wst-redlink:hover{color:red} +.wst-fred{color:#df2003} +.wst-align-center{text-align:center} +.wst-align-left{text-align:left} +.wst-align-right{text-align:right} +.hide{display:none} +.layui-layer-icowst1,.layui-layer-icowst2,.layui-layer-icowst3{background-image:url(../../../../../static/images/wst_icon.png)!important;background-repeat:no-repeat!important;background-size:cover!important} +.layui-layer-icowst2{background-position:-40px 0!important} +.layui-layer-icowst3{background-position:-80px -1px!important} +.layui-layer-icowstloading{background-image:url(../../../../../static/images/loading.gif)!important;background-repeat:no-repeat!important;background-size:206% auto!important;background-position:-16px -16px!important} +.wst-header{margin:0 auto;width:100%;border-bottom:1px solid #eee;background:#fafafa} +.wst-header ul li{float:left} +.wst-w,.wst-main{margin:0 auto;width:100%;padding-bottom:5px;margin-bottom:5px} +.wst-footer{text-align:center;line-height:25px;width:1210px;margin:0 auto} +.index-top-ads{margin:0 auto;height:100px;width:100%;position:relative} +.index-top-ads img{width:100%;height:100px;overflow:hidden} +.close-ads{width:35px;height:12px;background:url(../img/close_ads.gif) no-repeat;position:absolute;top:10px;right:20px;float:right;z-index:199} +.wst-header .wst-nav,.wst-container,.wst-search-container,.wst-nav-menus .nav-w,.wst-lite-container{width:1200px;margin:0 auto} +.wst-header .wst-nav{height:30px} +.headlf{float:left;width:500px;font-family:Arial,"宋体";font-size:12px} +.headrf li{float:left;height:30px;line-height:30px} +.headrf li a{font-family:Arial,"宋体";font-size:12px;color:#777} +.headlf li{height:30px;line-height:30px;padding-left:0;padding-right:0} +.headlf li.spacer{color:#ddd;width:10px;text-align:center} +.headrf li.spacer{color:#ddd;width:10px;text-align:center} +.wst-header .wst-nav .j-dorpdown{position:relative;width:91px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-header .wst-nav .j-dorpdown .nowrap{white-space:nowrap} +.wst-header .wst-nav .j-dorpdown:hover{background-color:#fff;border-left:1px solid #ddd;border-right:1px solid #ddd;border-bottom:0;z-index:10000} +.wst-header .wst-nav .j-dorpdown-layer{position:absolute;z-index:1000;margin-top:-1px;background:#fff;cursor:pointer;left:-1px;border:1px solid #ddd;border-top:0;display:none} +.wst-header .last-menu{float:right;right:0;white-space:nowrap} +.wst-header .wst-nav .drop-info{position:relative;padding:0 8px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-header .wst-nav .drop-infos a{color:#fe6047} +.wst-header .wst-nav .dorpdown-user{position:absolute;z-index:1000;cursor:pointer;left:-1px;display:none} +.wst-tag{width:280px;height:180px;border-bottom:1px solid #dedbdb;border-left:1px solid #dedbdb;border-right:1px solid #dedbdb;position:relative;background-color:#fafafa;box-shadow:0 1px 1px rgba(0,0,0,0.3)} +.wst-tag:after{top:-16px;border-color:transparent transparent #f7f7f6} +.wst-tagt{padding:10px 0} +.wst-tagt .userImg{margin-left:10px;float:left;width:60px;height:60px} +.wst-tagt .userImg img{width:60px;height:60px;border-radius:1000px} +.wst-tagt-n{float:left;width:190px;margin-left:5px} +.wst-tagt-na{float:left;color:#fe6047;font-size:15px;margin-left:12px} +.wst-tagt-n img{float:left;width:18px;margin-top:5px;margin-left:6px} +.wst-tagt-ip{float:left;width:190px;line-height:18px;margin-left:12px;color:#3d3d3e} +.wst-tagb{float:left;padding:10px 0 0 30px} +.wst-tagb a{float:left;width:70px;margin-left:30px} +.wst-tagb a:hover{color:#fd5940} +.wst-tags{width:190px;padding-left:10px;clear:both} +.wst-header .wst-nav .j-dorpdown .order-list{width:86px} +.wst-header .wst-nav .j-dorpdown .product-list{width:91px} +.wst-header .wst-nav .j-dorpdown .des-list{width:91px} +.wst-header .wst-nav .j-dorpdown .foucs-list{width:91px} +.wst-header .wst-nav .j-dorpdown .sweep-list{width:215px} +.pdl5{padding-left:5px!important} +.pdr5{padding-right:5px!important} +.wst-header .wst-nav .j-dorpdown-layer div{text-align:center;line-height:24px} +.wst-header .wst-nav .j-dorpdown-layer div a:hover,.wst-header .wst-nav .drop-down a:hover{color:#df2003} +.wst-header .wst-nav .drop-down{position:relative;padding:0 18px;width:55px;margin:0 auto} +.wst-header .wst-nav .drop-down1{background:url(../img/img_icon.png) -13px -33px no-repeat} +.wst-header .wst-nav .drop-down1:hover{background:url(../img/img_icon.png) -13px -183px no-repeat} +.wst-header .wst-nav .drop-down2{background:url(../img/img_icon.png) -13px -83px no-repeat} +.wst-header .wst-nav .drop-down2:hover{background:url(../img/img_icon.png) -13px -233px no-repeat} +.wst-header .wst-nav .drop-down3{background:url(../img/img_icon.png) -12px -134px no-repeat} +.wst-header .wst-nav .drop-down3:hover{background:url(../img/img_icon.png) -12px -284px no-repeat} +.wst-header .wst-nav .drop-down4{background:url(../img/img_icon.png) -13px -108px no-repeat} +.wst-header .wst-nav .drop-down4:hover{background:url(../img/img_icon.png) -13px -258px no-repeat} +.wst-header .wst-nav .drop-down5{background:url(../img/img_icon.png) -13px -57px no-repeat} +.wst-header .wst-nav .drop-down5:hover{background:url(../img/img_icon.png) -13px -207px no-repeat} +.wst-header .wst-nav .drop-down6{background:url(../img/img_icon.png) -13px -8px no-repeat} +.wst-header .wst-nav .drop-down6:hover{background:url(../img/img_icon.png) -13px -158px no-repeat} +.j-dorpdown-layer .qrcodea .qrcodeal{float:left;margin-top:5px} +.j-dorpdown-layer .qrcodea .qrcodear{float:right;margin-right:3px} +.j-dorpdown-layer .qrcodea .qrcodear p{color:#fa8a42;font-weight:bold;text-align:center;width:88px} +.j-dorpdown-layer .qrcodea .qrcodear a{float:right;width:75px;border:1px solid #ededed;padding:0 5px;margin:0 3px 3px 0;background:#f5f5f5} +.wst-nav .headrf .drop-down .di-right{top:12px;right:0;height:7px;overflow:hidden;font-style:normal;color:#6a6a6a;display:block;position:absolute} +.wst-nav .headrf .drop-down .di-left{top:12px;left:0;height:7px;overflow:hidden;font-style:normal;display:block;position:absolute} +.wst-nav .headrf .drop-down .di-right s{position:relative;top:-14px;text-decoration:none} +.wst-nav .headrf .drop-down:hover .di-right s{top:-7} +.drop-down a{width:auto} +.wst-header .wst-nav .normal{position:relative;padding:0 8px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-lite-container{height:auto} +.wst-logo{margin:5px 5px 5px 0;float:left;height:auto} +.wst-search-box{float:left;position:relative;width:670px} +.wst-search{border:2px solid #e23c3d;height:36px;margin-left:20px;margin-top:50px;position:relative} +.wst-search .j-search-type{width:78px;top:0;line-height:36px;position:absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor:pointer;left:-2px;text-align:center} +.wst-search .j-type-list{width:70px;top:35px;line-height:36px;position:absolute;padding:0 4px;border:2px solid #e23c3d;cursor:pointer;background-color:#fff;left:-2px;z-index:100;border-top:0;display:none;text-align:center} +.wst-search .j-search-type i{color:#6a6a6a;display:block;font-style:normal;height:7px;overflow:hidden;position:absolute;right:6px;top:16px;width:0} +.j-search-type i{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;border-color:#999 transparent transparent;border-image:none;border-style:solid dashed dashed;border-width:5px;font-size:0;line-height:0} +.arrow{transition:all .2s ease-in 0s} +.over{top:10px!important;transform:rotate(180deg);transform-origin:50% 30% 0} +.over-cat{display:none} +.wst-search .j-search-type s{position:relative;top:-17px;text-decoration:none} +.wst-search .j-type-list div:hover{color:#e23c3d} +.wst-search .search-ipt{border:0 none;color:#565656;float:left;font-family:Microsoft Yahei;font-size:14px;line-height:18px;overflow:hidden;padding:0;width:560px;height:36px;border:36px;outline:0;padding-left:84px} +.wst-search .search-btn{background-color:#df2003;color:#fff;cursor:pointer;font-size:15px;font-weight:bolder;height:38px;line-height:36px;position:absolute;right:-1px;text-align:center;top:-1px;width:80px} +.wst-search-keys{color:#6c6c6c;height:25px;line-height:28px;overflow:hidden;padding-left:20px} +.wst-search-keys a{color:#6c6c6c} +.wst-cart-box{float:right;width:163px;height:40px;margin-top:50px;background-color:#df2003;position:relative;cursor:pointer} +.wst-cart-box .word{float:left;width:112px;margin-top:10px;margin-left:20px;padding-left:28px;color:#fff;font-size:14px;font-family:"microsoft yahei";background:url(../img/icon_gouwuche.png) no-repeat left center;position:relative} +.wst-cart-box .num{font-size:14pxpx;color:#fff;line-height:24px;text-align:center;position:absolute;display:block;width:27px;height:25px;background:url(../img/icon_number.png) no-repeat;right:15px;top:-18px} +.wst-cart-boxs{width:332px;margin-top:22px;border:1px solid #dedbdb;position:absolute;z-index:1200;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);left:-171px;top:18px} +.wst-cart-boxs:after{top:-16px;border-color:transparent transparent #fff} +.wst-cart-boxs .carts{background:url(../img/top_icon_cartdown.png) 28px 47px no-repeat;width:332px;height:130px;text-indent:4.5em;line-height:130px;font-size:15px;color:#b9b6b6} +.wst-cart-box .goods{float:left;width:96.666666%;border-bottom:1px dashed #bfbfbf;padding:5px} +.wst-cart-box .goods .imgs{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-cart-box .goods .imgs a{width:72px;height:72px;display:table-cell;vertical-align:middle} +.wst-cart-box .goods .imgs img{max-width:72px;max-height:72px} +.wst-cart-box .goods .number{float:left;width:50%} +.wst-cart-box .goods .number p{float:left;width:92%;margin-top:10px;padding-left:10px} +.wst-cart-box .goods .price{float:right;text-align:right} +.wst-cart-box .goods .price p{float:right;width:100%;line-height:20px;font-weight:bold;color:#df2003} +.wst-cart-box .goods .price span{float:right;width:100%;line-height:20px} +.wst-cart-box .goods .price span a:hover,.wst-cart-box .goods .number p a:hover{color:#df2003} +.wst-cart-box .comm{float:left;width:100%;font-weight:bold;line-height:32px} +.wst-cart-box .comm span{font-size:15px;color:#df2003} +.wst-cart-box .comm .span2{float:right;margin-right:10px} +.wst-cart-box .btn{color:#fff;cursor:pointer;display:block;font-size:16px;font-weight:400;line-height:30px;margin:10px 0 16px 72px;max-width:200px;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;vertical-align:middle;width:100%;border-radius:5px} +@media(min-width:400px){.wst-cart-box .btn{display:inline-block;margin-right:2.5em} +.wst-cart-box .btn:nth-of-type(even){margin-right:0}}@media(min-width:600px){.wst-cart-box .btn:nth-of-type(even){margin-right:2.5em} +.wst-cart-box .btn:nth-of-type(5){margin-right:0}} +.wst-cart-box .btn:hover{text-decoration:none} +.wst-cart-box .btn-3{background:#e3403a;border:1px solid #da251f;box-shadow:0 1px 0 #d6251f,1px 1px 1px #e02a24;font-weight:900;letter-spacing:1px;-webkit-transition:all 150ms linear;transition:all 150ms linear} +.wst-cart-box .btn-3:hover{background:#e02c26;border:1px solid rgba(0,0,0,0.05);box-shadow:1px 1px 2px rgba(255,255,255,0.2);color:#ec817d;text-decoration:none;text-shadow:-1px -1px 0 #c2211c;-webkit-transition:all 250ms linear;transition:all 250ms linear} +.wst-lite-title{float:left;padding-top:90px;padding-left:10px} +.wst-lite-index{padding-top:90px;float:right} +.wst-table td{height:35px} +.wst-footer-frd{color:#e23e3d;font-weight:bolder;font-size:18px} +.wst-footer-pno{color:red;font-weight:bolder;font-size:18px} +.wst-footer{text-align:center;line-height:25px;width:1200px;margin:0 auto} +.wst-footer-fl-box{text-align:center;margin-top:45px} +.wst-footer-cld-box{border-bottom:1px solid #d5d5d5;height:auto;line-height:30px;text-align:left;padding-bottom:20px;margin-bottom:20px} +.wst-footer-fl{font-weight:bolder;padding-top:7px;color:#fc6047;font-size:14px} +.wst-footer-hp-box{background-color:#f7f7f7;text-align:center;margin-top:20px} +.wst-footer-hp-ck1{line-height:30px;text-align:left;border-top:1px solid #f5f5f5;border-bottom:1px solid #f5f5f5;min-width:1200px} +.wst-footer-hp-ck3{margin-top:20px;padding-bottom:10px} +.wst-footer-hp-ck3 a{color:#666} +.wst-footer-hp-ck3 .copyright{color:#666} +.wst-footer-pno{color:red;font-weight:bolder;font-size:18px} +.wst-footer-wz-ca{padding-top:20px;float:left;width:180px;height:180px} +.wst-footer-wz-pt{padding-top:5px;line-height:25px} +.wst-footer-wz-pn{font-weight:bolder;margin-left:10px;font:600 16px/20px "microsoft yahei";color:#666} +.wst-footer-wz-clt{float:left;width:160px;height:180px;margin-left:6px} +.wst-footer-wz-kf{font-weight:bolder;margin-left:10px} +.wst-footer-wz-ent{color:green;font-size:16px} +.wst-footer-wz-ca a{color:#999} +.flink-hover{font-size:13px;color:#434343;margin-left:10px;margin-right:10px} +.flink-hover:hover{text-decoration:underline;color:#1e84da} +.wst-footer-info{margin:0 auto;width:1200px;height:100px} +.wst-footer-info>li{width:180px;height:80px;float:left;margin-right:60px} +.wst-footer-info-img{float:left; margin-top:15px; width: 70px; height: 70px; box-sizing: border-box; background-image: url(../img/footer_icon.png); background-repeat: no-repeat; } +.wst-fimg1{background-position: -1px -1px;} +.wst-fimg2{background-position: -241px -1px;} +.wst-fimg3{background-position: -481px -1px;} +.wst-fimg4{background-position: -721px -2px;} +.wst-fimg5{background-position: -961px -1px;} + +.wst-footer-info-text{float:left;margin-top:25px;margin-left:10px} +.wst-footer-info-text>h1{margin-bottom:5px;font-size:16px;color:#505050} +.wst-footer-info-text>p{color:#6c6c6c;font-size:} +.wst-nav-menus{border-bottom:2px solid #df2003;height:36px;margin:0 auto;min-width:1200px}#wst-categorys{float:left;height:36px;overflow:visible;position:relative;width:210px;z-index:10;top:2px} +#wst-categorys .dt a{background:url(../img/icon_fenleitubiao.png) no-repeat 16px;background-color:#df2003;color:#fff;text-indent:30px;display:block;font:400 15px/36px "microsoft yahei";height:36px;padding:0 10px;text-decoration:none;width:190px} +#wst-categorys .dd{background:rgba(38,38,38,0.7) none repeat scroll 0 0;min-height:400px} +#wst-categorys .dd-inner .item{color:#ff2706;height:35px;position:relative;z-index:1;transition:padding 100ms ease-in;-moz-transition:padding 100ms ease-in;-webkit-transition:padding 100ms ease-in;-o-transition:padding 100ms ease-in} +#wst-categorys .dd-inner .item a{color:#fff} +#wst-categorys .dd-inner h3{font-size:13px;font-weight:400;height:31px;line-height:31px;padding:0 10px;position:absolute;z-index:2} +#wst-categorys .dd-inner i{font:400 9px/14px consolas;height:14px;position:absolute;right:14px;top:9px;width:4px;z-index:1} +#wst-categorys .dd-inner .hover{height:33px;border-left:1px solid #eee;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#f7f7f7 none repeat scroll 0 0;color:#b61d1d} +#wst-categorys .dd-inner .hover a{color:#ff0c00}#wst-categorys .dd-inner .hover i{background:#f7f7f7 none repeat scroll 0 0;height:31px;left:205px;line-height:200px;overflow:hidden;top:0;width:14px} +#wst-categorys .dorpdown-layer{background:#f7f7f7 none repeat scroll 0 0;border:1px solid #eee;display:none;left:209px;overflow:hidden;position:absolute;top:36px;width:779px;min-height:600px} +#wst-categorys .dorpdown-layer .hover{display:block} +#wst-categorys .item-sub{display:block;overflow:hidden} +.cat2_tit{color:#333;font-weight:bold} +.cat2_tit i{font-style:normal;} +#wst-categorys .item-sub::after{clear:both;content:".";display:block;height:0} +#wst-categorys .subitems{background:#f7f7f7 none repeat scroll 0 0;float:left;margin-bottom:-10px;padding:6px 0 10px 20px;width:570px}#wst-categorys .subitems dl{line-height:2em;overflow:hidden;width:100%} +#wst-categorys .subitems dl.fore1 dd{border-top:medium none}#wst-categorys .subitems dt{background:#3B3B3B none repeat scroll 0 0;color:#fff;display:inline-block;line-height:24px;height:24px;margin-right:10px;padding:0 0 0 8px;white-space:nowrap} +#wst-categorys .subitems dt a{color:#fff}#wst-categorys .subitems dt i{font:400 9px/14px consolas;height:24px;margin-left:8px;width:23px;display:inline-block;color:#fff} +#wst-categorys .subitems dd{border-bottom:1px dashed #eee;padding:6px 0;width:570px} +#wst-categorys .subitems dd a{float:left;height:16px;line-height:16px;margin:4px 0;padding:0 8px;white-space:nowrap;color:#666} +#wst-categorys .subitems dd a:hover{color:#ff0c00} +#wst-categorys .item-brands{display:inline;float:right;margin:10px 10px 10px 0;overflow:hidden;width:178px} +#wst-categorys .item-brands .brands-inner{height:270px}#wst-categorys .item-brands .shops-inner{height:180px}#wst-categorys .item-brands a{display:inline;float:left;margin:7px 0 0 6px} +#wst-categorys .item-promotions{display:inline;float:right;margin-right:20px;width:168px}#wst-categorys .item-promotions a{display:block;margin-bottom:1px} +#wst-nav-items{float:left;position:relative;z-index:2}#wst-nav-items .spacer,#wst-nav-items a,#wst-nav-items li,#wst-nav-items ul{float:left}#wst-nav-items ul{width:990px;overflow:hidden;height:36px} +#wst-nav-items .spacer{display:none} +#wst-nav-items a{color:#333;font:400 16px/36px "microsoft yahei";height:36px;padding:0 20px;text-align:center;text-decoration:none} +#wst-nav-items a:hover{color:#ff2708}#wst-nav-items .spacer{background:#ddd none repeat scroll 0 0;height:24px;margin:10px 0 0;overflow:hidden;width:1px} +.wst-right-panel{height:418px;width:210px;} +.cat-icon-1,.cat-icon-2,.cat-icon-3,.cat-icon-4,.cat-icon-5,.cat-icon-6,.cat-icon-7,.cat-icon-8,.cat-icon-9,.cat-icon-10,.cat-icon-11,.cat-icon-12,.over-cat-icon{float:left;background:url(../img/icon_goodsclass_list.png) no-repeat;width:25px;height:25px;margin-top:5px;margin-right:5px; background-size: 457%; } +.cat-icon-1{background-position:-17px -19px} +.cat-icon-1-hover{background-position:-76px -19px} +.cat-icon-2{background-position:-17px -78px} +.cat-icon-2-hover{background-position:-76px -78px} +.cat-icon-3{background-position:-17px -140px} +.cat-icon-3-hover{background-position:-76px -140px} +.cat-icon-4{background-position:-17px -200px} +.cat-icon-4-hover{background-position:-76px -200px} +.cat-icon-5{background-position:-17px -259px} +.cat-icon-5-hover{background-position:-76px -259px} +.cat-icon-6{background-position:-17px -318px} +.cat-icon-6-hover{background-position:-76px -318px} +.cat-icon-7{background-position:-17px -378px} +.cat-icon-7-hover{background-position:-76px -378px} +.cat-icon-8{background-position:-17px -438px} +.cat-icon-8-hover{background-position:-76px -438px} +.cat-icon-9{background-position:-17px -500px} +.cat-icon-9-hover{background-position:-76px -500px} +.cat-icon-10{background-position:-17px -562px} +.cat-icon-10-hover{background-position:-76px -562px} +.cat-icon-11{background-position:-17px -623px} +.cat-icon-11-hover{background-position:-76px -623px} +.cat-icon-12{background-position:-17px -682px} +.cat-icon-12-hover{background-position:-76px -682px} +.over-cat-icon{background-position:-17px -682px} +.over-cat-icon-hover{background-position:-76px -682px} +.wst-route{padding:10px 0} +.wst-route,.wst-route a{color:#6c6c6c;font-size:14px;font-family:fantasy} +.wst-route a:hover{color:#eb5f43;cursor:pointer} +.wst-grey-btn{display:inline-block;border-radius:2px;background:#f7f7f7;text-align:center;text-decoration:none;cursor:pointer;border:1px solid #DDD;padding:3px 13px 3px;color:#666;background-color:#f7f7f7;background-repeat:repeat-x;background-image:-moz-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:-webkit-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:-o-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:linear-gradient(top,#f7f7f7,#f2f2f2);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7',endColorstr='#f2f2f2',GradientType=0)} +.wst-grey-btn:hover{color:red}#wst-pager{text-align:center;margin-top:20px} +.icon-phone,.icon-email{background:url(../img/iconfont_fotter.png) no-repeat} +.icon-phone{width:40px;height:30px;background-position:2px 5px;float:left} +.icon-email{width:40px;height:30px;background-position:-34px 2px;float:left} +.qr-code{width:100%;height:85px} +.qr-code img{float:left;margin-right:5px} +.call-wst{font-size:15px;color:#080808;float:left;line-height:30px;font-weight:bold} +.email-wst{font-size:25px;color:#000;float:left;line-height:30px;text-indent:16px;font-family:"microsoft yahei"} +.mb-wst{float:left;width:110px;height:90px;margin-top:10px} +.focus-wst{float:left;height:100%;width:158px} +.focus-wst-qr{height:20px;color:#171717;margin-top:2px;font-weight:bold} +.focus-wst-qra{height:20px;margin:6px 0 6px 0} +.focus-wst-qre{height:20px;margin-top:3px;font-size:15px} +.wst-contact{float:left;width:275px;height:165px;margin-left:6px;margin-top:5px}#verifyImg,#verifyImg2,#verifyImg3{cursor:pointer} +.wst-empty{width:650px;height:510px;margin:0 auto} +.empty1{background:url(../img/bgimg_error_ymcc.png) 0 123px no-repeat} +.empty2{background:url(../img/bgimg_error_xtcc.png) 0 123px no-repeat} +.empty3{background:url(../img/bgimg_error_spcc.png) 0 123px no-repeat} +.wst-empty .prompt{padding-top:123px;width:600px;margin:0 auto;text-align:center} +.wst-empty .prompt p,.wst-empty .prompt2 p,.wst-empty .prompt3 p{color:#2fc474;font-size:18px;line-height:26px;font-family:"microsoft yahei"} +.wst-empty .button{padding-top:250px;width:320px;margin:0 auto} +.wst-empty-btn{color:#fff;cursor:pointer;float:left;font-size:16px;font-weight:400;line-height:38px;width:123px;position:relative;text-decoration:none;text-transform:uppercase;vertical-align:middle;text-align:center;font-family:"microsoft yahei";border-radius:3px;margin:0 10px} +.wst-empty-btn1{background:#f9a818;font-weight:100} +.wst-empty-btn1:hover{background:#f6bd57;font-weight:900;letter-spacing:1px} +.wst-empty .prompt2{padding-top:160px;width:475px;margin:0 auto} +.wst-empty .prompt2 span{color:#fa3e3f;font-weight:bold;font-size:20px;line-height:52px;font-family:"microsoft yahei"} +.button2{padding-top:160px;width:520px;margin:0 auto} +.wst-empty .prompt3{padding-top:355px;width:588px;margin:0 auto} +.button3{padding-top:23px;width:520px;margin:0 auto} +.wst-loading-img{vertical-align:middle} +.lbel{border-radius:.25em;color:#fff;display:inline;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:baseline;white-space:nowrap} +a.lbel:hover,a.lbel:focus{color:#fff;cursor:pointer;text-decoration:none} +.lbel:empty{display:none} +.lbel-default{background-color:#777} +.lbel-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e} +.lbel-primary{background-color:#428bca} +.lbel-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9} +.lbel-success{background-color:#5cb85c} +.lbel-success[href]:hover,.label-success[href]:focus{background-color:#449d44} +.lbel-info{background-color:#5bc0de} +.lbel-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5} +.lbel-warning{background-color:#f0ad4e} +.lbel-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f} +.lbel-danger{background-color:#d9534f} +.lbel-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c} +.lbel-gray{background-color:#e6e6e6} +.lbel-gray[href]:hover,.label-danger[href]:focus{background-color:#eee} +.wst-tips-box{height:auto;line-height:25px;-moz-border-radius:5px;-webkit-border-radius:5px;color:red;border:1px dotted #f0a869;background:#ffc;padding:5px 5px 5px 15px;margin-left:10px;margin-bottom:5px;margin-top:10px} +.wst-tips-box .icon{width:20px;height:20px;float:left;background:url('../img/icon_tstb.png') no-repeat;background-size:100%} +.wst-tips-box .tips{float:left;padding-left:5px} +.s-wst-slide-items li{overflow:hidden} +.s-wst-slide-numbox{position:absolute;bottom:10px;width:100%} +.s-wst-slide-items{max-width:100%} +.s-wst-slide-controls{width:200px;text-align:center;margin:0 auto;z-index:10} +.s-wst-slide-controls span{width:13px;height:13px;text-align:center;display:inline-block;border-radius:12px;background-color:#ccc;color:white;cursor:pointer} +.s-wst-slide-controls .curr{background-color:#eadfdf;border-radius:12px;color:white;cursor:pointer} +.s-wst-slide{position:relative} +.line-break{word-break:break-all;word-wrap:break-word} +.btn-submit{width:100px;height:32px;line-height:32px;display:inline-block;position:relative;background:#e45050;color:#fff;text-align:center;font-family:'Ubuntu',sans-serif;font-size:15px;font-weight:bold;text-decoration:none;border-radius:3px;overflow:hidden;-webkit-transition:all .15s ease-in;transition:all .15s ease-in} +.btn-submit:before{content:' ';position:absolute;background:#fff;width:25px;height:50px;top:0;left:-45px;opacity:.3;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;-webkit-transform:skewX(-25deg);transform:skewX(-25deg)} +.btn-submit:hover:before{width:45px;left:205px} +.btn-cancel{width:100px;height:32px;line-height:32px;display:inline-block;position:relative;background:#f0efef;border:solid 1px #f0f0f0;color:#555;text-align:center;font-family:'Ubuntu',sans-serif;font-size:15px;font-weight:bold;text-decoration:none;border-radius:3px;overflow:hidden;-webkit-transition:all .15s ease-in;transition:all .15s ease-in} +.wst-stript{width: 100%;height: 20px;color: #666;} +.wst-stript .stript-left{width: 36%;height: 1px;background: RGB(51,51,51);display: inline-block;margin-bottom: 5px;} +.wst-stript .stript-right{width: 36%;height: 1px;background: RGB(51,51,51);display: inline-block;margin-bottom: 5px;} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/goods.css b/hyhproject/home/view/default/css/goods.css new file mode 100755 index 0000000..4050e3e --- /dev/null +++ b/hyhproject/home/view/default/css/goods.css @@ -0,0 +1,1432 @@ +@CHARSET "UTF-8"; +.wst-filters { + width: 1200px; + margin-left: auto; + margin-right: auto; + margin-top: 10px; + color: #999; +} + +.wst-filters div.item { + float: left; + margin-right: 6px; + position: relative; +} + +.wst-filters .arrow { + float: left; + position: relative; + top: 6px; + font-style: normal; + background-image: url(./../img/goods_detail_arrow_r.png); + background-repeat: no-repeat; + display: block; + width: 10px; + height: 10px; + ; +} + +.wst-filters div.dorpdown .arrow { + top: 7px; +} + +.wst-filters .item .link { + color: #666; + float: left; + border: 0px; + margin-right: 5px; + height: 22px; + line-height: 22px; + padding: 0px 5px 0px 5px; +} + +.wst-filters .item .drop-down { + float: left; + border: 1px solid transparent; + display: inline-block; + height: 23px; + line-height: 23px; + vertical-align: top; + position: relative; + background-color: #fff; + padding: 0 2px; +} + +.wst-filters .item .drop-down.hover { + border-color: #df2003; + border-bottom: 0; + z-index: 2 +} + +.wst-filters .item .dorp-down-layer { + border: 1px solid #ddd; + border-top: 0; + display: none; + left: 0px; + top: 22px; + position: absolute; + z-index: 1; + background: #fff; + min-width: 320px; + border: 1px solid #df2003; +} + +.wst-filters .item .dorp-down-layer div { + float: left; + width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 4px 8px; +} + +.wst-filters .item .dorp-down-layer div:hover, +.wst-filters .item .dorp-down-layer a:hover { + color: #df2003; +} + +.wst-filters .item .v-item { + color: #666; + border: 1px solid #ddd; + cursor: pointer; + display: inline-block; + font-size: 12px; + height: 22px; + line-height: 22px; + margin: 0 5px 5px 0; + padding: 0 30px 0 4px; + position: relative; + vertical-align: top; +} + +.wst-filters .item .v-item:hover { + border-color: #e4393c; +} + +.wst-filters .item .v-item i { + display: block; + position: absolute; + width: 25px; + height: 22px; + right: 0; + text-align: center; + font-style: normal; + top: 0; +} + +.wst-filters .item .v-item:hover i { + background-color: #e4393c; + color: #fff; +} + + +/**商品移动效果**/ + +.goods-pics { + width: 350px; + margin: 10px 0px 10px 0px; +} + +.goods-pics .items { + float: left; + height: 56px; + float: left; + -top: 3px; + overflow: hidden; + position: relative; + width: 319px; +} + +.goods-pics .items ul { + height: 56px; + position: absolute; + width: 999999px; + cursor: pointer +} + +.goods-pics .items ul li { + float: left; + text-align: center; + width: 64px; +} + +.goods-pics .prev, +.goods-pics .next { + background: #ebebeb none repeat scroll 0 0; + border: 1px solid #ddd; + cursor: pointer; + display: block; + font-family: "宋体"; + height: 54px; + line-height: 54px; + text-align: center; + text-decoration: none; + width: 10px; +} + +.goods-pics .prev { + float: left; + margin-right: 4px; +} + +.goods-pics .next { + float: right; +} + + +/**放大镜**/ + +.goods-img-box { + float: left; + height: 430px; + margin: 5px; + width: 350px; +} + +.spec-preview { + float: left; + height: 350px; + width: 345px; + margin-bottom: 5px; +} + + +/*Cloud Zoom 放大镜 */ + +.cloudzoom-lens { + width: 30px; + height: 30px; + border: 1px solid #eee; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.20); + cursor: crosshair; + z-index: 10; +} + +.cloudzoom-zoom { + background: #fff; + border: 1px solid #EEE; + width: 360px; + height: 360px; + z-index: 200; + box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.1); +} + +.cloudzoom-zoom-inside { + border: none; + box-shadow: none; +} + +.cloudzoom-blank { + opacity: 0.3; +} + + +/**商品内容**/ + +.intro { + display: inline; + float: left; + width: 628px; + min-height: 430px; + border-left: 1px solid #eee; + border-right: 1px solid #eee; + padding-bottom: 10px; +} + +.intro h2 { + color: #666; + font: 700 16px/28px Arial, "microsoft yahei"; + line-height: 25px; +} + +.intro .intro-name { + padding: 10px 20px; +} + +.intro .tips { + color: #e4393c; + font-size: 12px; +} + +.intro .summary { + margin: 0 20px; + margin-bottom: 10px; + background: url(../img/intro-bg.png) repeat-x; + line-height: 30px; + padding: 5px 0px 5px 0px; +} + +.summary .dt { + display: inline; + color: #999; + float: left; + font-family: simsun; + text-align: right; + width: 75px; + padding-left: 10px; +} + +.summary .dd { + width: 470px; + color: #585858; +} + +.summary .dd img { + margin-top: 6px; +} + +.summary .market-price { + font-weight: 400; + text-decoration: line-through; +} + +.summary .price { + color: #e40000; + display: inline-block; + font-size: 18px; + vertical-align: middle; +} + +.summary .lxy{ + font-size: 26px; +} + +.summary .appraise { + float: right; +} + +.summary .appraise-num { + color: #FF4400; +} + +.summary .infol { + float: left; + width: 100%; +} + +.summary .infor { + width: 168px; + position: absolute; + top: -61px; + right: -12px; +} + +.summary .goods-intro-bg { + position: relative; +} + +.ginfo_b { + width: 100%; +} + +.ginfo_b li { + float: left; + width: 25%; + height: 30px; + overflow: hidden; +} + +.ginfo_b li:nth-child(3) { + width: 50%; +} + +.sale_box { + margin: 0px 20px; + padding-bottom: 10px; + border: none; + box-sizing: border-box; +} + +.sale_box .dt { + display: inline; + color: #999; + float: left; + font-family: simsun; + text-align: right; + width: 75px; + padding-left: 10px; +} + +.sale_box .dd { + color: #585858; +} + +.c14_005 { + font-size: 14px; + color: #005aa0; +} + + +/**商品规格**/ + +.intro .spec { + padding: 5px 5px 5px 10px; +} + +.intro .spec .item { + width: 590px; +} + +.spec .dt { + padding-left: 20px; + line-height: 35px; + color: #999; + height: 30px; + display: inline; + float: left; + font-family: simsun; + text-align: right; + width: 75px; +} + +.spec .dd { + width: 525px; + color: #585858; +} + +.spec .j-option { + float: left; + margin: 2px 8px 2px 0px; + background: #fff; + border: 1px solid #ccc; + padding: 4px 6px; + cursor: pointer; + position: relative; +} + +.spec .j-selected i { + font-size: 0; + line-height: 0; + background: url(../img/img_gd_sel.png) no-repeat 0 0; + display: block; + width: 11px; + height: 11px; + position: absolute; + z-index: 1; + right: -1px; + bottom: -1px; +} + +.spec .j-selected { + border: 2px solid #e4393c; + padding: 3px 5px; +} + + +/**购买商品**/ + +.intro .buy { + padding: 5px 5px 5px 10px; +} + +.intro .buy .item { + width: 590px; + clear: both; +} + +.buy .dt { + padding-left: 20px; + line-height: 35px; + color: #999; + height: 30px; + display: inline; + float: left; + font-family: simsun; + text-align: right; + width: 75px; +} + +.buy .dd { + width: 525px; + line-height: 35px; + height: 30px; + color: #585858; +} + +.buy .btn {} + +.buy .addBtn { + font-weight: bold; + cursor: pointer; + display: block; + font-size: 16px; + height: 38px; + line-height: 38px; + text-align: center; + background: #FFE4D0; + border: 1px solid #F0CAB6; + color: #f40; + width: 150px; + float: left; + margin-right: 20px; +} + +.buy .addBtn:hover { + background: #f40; + color: #fff; +} + +.buy .buyBtn { + font-weight: bold; + cursor: pointer; + display: block; + font-size: 16px; + height: 38px; + line-height: 38px; + text-align: center; + background: #e4393c; + color: #fff; + width: 150px; + float: left; +} + +.buy .buyBtn:hover { + background: #df2003; + color: #fff; +} + + +/**右侧看了又看**/ + +.seeing { + float: left; + width: 210px; + height: 420px; +} + +.seeing .head { + font-size: 13px; + color: #333; + height: 25px; + line-height: 25px; + background: #f7f7f7; + text-align: center; + padding: 5px 10px +} + +.seeing .body { + width: 210px; + padding: 5px; +} + +.see-item { + padding-top: 7px; + width: 100px; + float: left; +} + +.see-item .see-img { + width: 200px; + height: 120px; + margin: 0 auto; + text-align: center; + vertical-align: middle; + display: block; + position: relative; + display: table-cell; +} + +.see-price { + display: block; + width: 100px; + height: 20px; + color: #DF2003; + font-weight: bold; +} + +.see-item .see-img img { + max-width: 90px; + max-height: 90px; +} + + +/**猜你喜欢**/ + +.wst-side { + float: left; + width: 210px; + margin-right: 5px; +} + +.goods-side { + width: 210px; +} + +.shop-intro { + padding-bottom: 13px; + width: 210px; + ; + border: 1px solid #eee; + height: auto; + margin-bottom: 10px; +} + +.shop_imgbox { + text-align: center; + background-color: #f7f7f7; + padding: 5px 0; +} + +.shop-intro .title { + height: 30px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; + box-sizing: border-box; + padding: 5px; + padding-left: 15px; +} + +.shop-name { + font-size: 14px; + color: #333; + font-weight: bold; +} + +.shop-intro .body { + padding: 10px 0; + border-top: 1px dashed #eee; + margin: 0 15px; +} + +.shop-intro .itemScore:nth-child(2) { + border-left: 1px solid #eee; + border-right: 1px solid #eee; +} + +.shop-intro .itemScore { + width: 33%; + box-sizing: border-box; + text-align: center; + padding: 5px; + float: left; +} + +.c12_e40 { + font-size: 12px; + color: #e40000; +} + +.shop-intro .footer { + padding: 5px 15px; + text-align: center; + box-sizing: border-box; +} + +.footer a:nth-child(1) { + margin-right: 6px; +} + +.footer a { + background: #fafafa; + border: 1px solid #ededed; + border-radius: 2px; + color: #666; + float: left; + height: 28px; + line-height: 28px; + text-align: center; + width: 40%; + padding-left: 13px; +} + +.footer a:hover { + background: #f5f5f5 none repeat scroll 0 0; + border-color: #e0e0e0; + color: #666; +} + +.footer .home, +.footer .home:hover { + background: url(../img/goodsdetails_icon_jrdp.png) 5px 4px no-repeat; +} + +.footer .j-fav, +.footer .j-fav:hover { + background: url(../img/iconfont_guanzhu_sel.png) 6px 7px no-repeat; +} + +.footer .j-fav2 { + background: url(../img/iconfont_guanzhu_nor.png) 5px -17px no-repeat; + transition: background-position 0.15s ease-in-out 0s; +} + +.footer .j-fav2:hover { + background: url(../img/iconfont_guanzhu_nor.png) 5px 6px no-repeat; + text-decoration: none; +} + +.goods-side .title { + line-height: 35px; + background-color: #f7f7f7; + text-align: center; +} + +.goods-side .guess-like { + min-height: 300px; + border: 1px solid #eee; + padding-bottom: 10px; +} + +.goods-side .item { + padding-top: 10px; +} + +.goods-side .item .img { + width: 200px; + margin: 0 auto; + text-align: center; + vertical-align: middle; + display: block; + position: relative; + display: table-cell; + padding: 4px; +} + +.goods-side .item .img a { + display: table-cell; + vertical-align: middle; + width: 200px; + height: 200px; +} + +.goods-side .item .img a img { + max-width: 200px; + max-height: 200px; +} + +.goods-side .item .p-price { + padding: 5px; + font-weight: bold; + color: #C00; + font-size: 14px; +} + +.goods-side .item .v-price { + text-decoration: line-through; + color: #999; + margin-left: 10px; + font-weight: normal; + font-size: 12px; +} + +.goods-side .hot-goods { + min-height: 300px; + border: 1px solid #eee; + margin-top: 15px; + padding-bottom: 10px; +} + + +/**商品详情***/ + +.wx_qrcode_fixed { + position: fixed!important; + left: inherit!important; + right: 80px; +} + +#wx_qrcode { + width: 85px; + position: relative; + float: right; + margin-right: 20px; + z-index: 99; + left: 0; +} + +#wx_qrcode:hover { + background-color: #fff; +} + +#wx_qrcode:hover .wx_qrcode_box { + display: block; +} + +.wx_qrcode_box img { + width: 100%; + height: 100%; +} + +.wx_qrcode_box { + display: none; + left: 0; + background-color: #fff; + position: absolute; + height: 110px; + width: 115px; +} + +.goods-desc { + width: 985px; + float: right; +} + +.wst-tab-box { + width: 100%; + height: auto; + margin: 0px auto; + background: #ffffff; +} + +.wst-tab-nav { + margin: 0; + padding: 0; + height: 36px; + top: 0px; + z-index: 30; + background: #f7f7f7; + width: 100%; + border: 1px solid #eee; +} + +.wst-tab-nav li { + cursor: pointer; + float: left; + margin: 0 0px; + list-style: none; + border: 1px solid #f7f7f7; + border-bottom: none; + border-left: none; + height: 36px; + line-height: 36px; + text-align: center; + color: #000000; + padding: 0 15px; +} + +.wst-tab-nav .on .appraise-num { + color: #fff; +} + +.wst-tab-nav .on { + border-top: none; + color: #fff; + font-weight: bold; + background: #e4393c; +} + +.wst-tab-nav #addCart2 { + display: none; + position: fixed; + top: 0px; + right: 20px; + z-index: 31; + background: #df2003; + padding: 5px 15px; + margin-top: 5px; + color: #ffffff; +} + +.brand_name span { + color: #005aa0; +} + +.brand_name { + margin-left: 5px; + margin-bottom: 20px; +} + +.wst-tab-content { + word-wrap: break-word; + word-break: break-all; + padding: 5px; + width: 99%; + height: auto; + border: 1px solid #eee; + border-top: none; + background: #FFF; +} + +.wst-tab-item img { + width: 100%; +} + +.goods-desc .appraise-num { + color: #FF4400; + font-weight: bold; +} + +.wst-attrs-list { + box-sizing: border-box; + border-bottom: 1px solid #eee; + margin-bottom: 10px; + padding: 20px; + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; +} + +.wst-attrs-list li { + color: #666; + padding: 5px; + width: 233px; + height: 16px; + float: left; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.buy-btn { + color: #666; + background: #eeeeee; + cursor: pointer; + float: left; + ; + display: block; + height: 27px; + line-height: 27px; + padding: 0px 10px; + border: 1px solid #ddd; +} + +input[type="text"].buy-num { + text-align: center; + width: 50px; + float: left; + border-left: 0px; + border-right: 0px; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +.goods-term-box { + padding: 0px 5px; +} + +.goods-term-box a:hover, +.wst-contrast:hover { + color: #e4393c; +} + +.wst-favorite { + float: left; + height: 38px; + position: relative; + top: -7px; + left: -7px; +} + +.wst-favorite .favorite { + height: 38px; + line-height: 38px; + padding: 5px 5px 5px 25px; +} + +.wst-favorite .j-fav, +.footer .j-fav:hover { + background: url(../img/iconfont_guanzhu_sel.png) 4px 5px no-repeat; +} + +.wst-favorite .j-fav2 { + background: url(../img/iconfont_guanzhu_nor.png) 3px -19px no-repeat; + transition: background-position 0.15s ease-in-out 0s; +} + +.wst-favorite .j-fav2:hover { + background: url(../img/iconfont_guanzhu_nor.png) 3px 5px no-repeat; + text-decoration: none; +} + +.wst-contrast { + float: left; + padding-left: 20px; + height: 23px; + line-height: 23px; + position: relative; + cursor: pointer; +} + +.wst-contrast i { + position: absolute; + top: 4px; + left: 0; + width: 15px; + height: 15px; + background: url(../img/contrast.png) 0 0 no-repeat; + background-size: 100%; +} + +.wst-cont-frame { + position: fixed; + bottom: -200px; + right: 50%; + margin-right: -602px; + z-index: 100; + width: 986px; + height: 139px; + background: #fff; + -moz-box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + -webkit-box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + -webkit-transition: all .2s linear; + transition: all .2s linear; +} + +.wst-cont-frame.show { + bottom: 0; +} + +.wst-cont-frame .head { + height: 32px; + border: 1px solid #ddd; + border-bottom: 2px solid #e23c3d; + position: relative; +} + +.wst-cont-frame .head span { + float: left; + width: 80px; + height: 36px; + line-height: 30px; + text-align: center; + font: 14px/30px 'microsoft yahei'; + position: relative; + left: -1px; + margin-top: -4px; + background: #fff; + border: 2px solid #e23c3d; + border-bottom: 0; + color: #e23c3d +} + +.wst-cont-frame .head .close { + text-align: right; + position: absolute; + right: 0; + top: 0; + padding-right: 22px; + height: 30px; + line-height: 30px; + color: #005aa0; +} + +.wst-cont-frame .list { + border: 2px solid #e23c3d; + border-top: none; + position: relative; +} + +.wst-cont-frame .goods { + padding: 6px; + color: #ccc; + height: 90px; + overflow: hidden; +} + +.wst-cont-frame .term { + float: left; + overflow: hidden; + margin-right: 10px; + padding: 17px 10px 12px 0; + border-right: 1px dotted #e23c3d; +} + +.wst-cont-frame .term:hover .info .price a { + opacity: 1; +} + +.wst-cont-frame .term .img { + float: left; + margin-right: 5px; + width: 48px; + height: 48px; + text-align: center; + border: 1px solid #fff; + overflow: hidden; +} + +.wst-cont-frame .term .info, +.wst-cont-frame .list .term-empty .info { + float: left; + width: 140px; +} + +.wst-cont-frame .term .info .name { + height: 36px; + line-height: 18px; + overflow: hidden; + display: block; + color: #333; +} + +.wst-cont-frame .term .info .price span { + color: #e4393c; + font-size: 14px; + font-family: Verdana; + font-weight: bold; +} + +.wst-cont-frame .term .info .price a { + padding-left: 10px; + color: #005aa0; + opacity: 0; +} + +.wst-cont-frame .term-empty { + float: left; + overflow: hidden; + margin-right: 10px; + padding: 17px 10px 12px 0; + border-right: 1px dotted #e23c3d; +} + +.wst-cont-frame .term-empty .img { + float: left; + margin-right: 5px; + width: 48px; + height: 48px; + text-align: center; + color: #ccc; + border: 1px solid #fff; + font: 36px/48px arial; + overflow: hidden; + background: #f6f6f6; +} + +.wst-cont-frame .term-contrast { + position: absolute; + right: 22px; + top: 22px; + width: 85px; + text-align: center; +} + +.wst-cont-frame .term-contrast .contrast { + display: block; + margin: 0 auto; + margin-bottom: 10px; + font: bold 14px/30px verdana; + width: 60px; + height: 30px; + line-height: 30px; + text-align: center; + background: #e4393c; + color: #fff; +} + +.wst-cont-frame .term-contrast .contrast:hover { + background: #e75153; +} + +.wst-cont-frame .term-contrast .empty { + color: #005aa0; +} + + +/*商品评价*/ + +.apprtime { + color: #999; + display: inline-block; + margin: 5px 0; +} + +.appraise-head { + width: 100%; + height: 80px; + display: flex; + margin: 10px auto; +} + +.appraise-head .text { + font-size: 12px; + color: #666; + font-weight: 400; +} + +.percent { + line-height: 110%; + font-size: 45px; + color: #E4393C; + font-family: arial; +} + +.percent span { + font-size: 23px; +} + +.app-head-l { + flex: 1; +} + +.app-head-lbox { + padding: 4px 10px 0 50px; +} + +.app-head-r { + flex: 5; +} + +.app-head-rbox { + display: flex; + height: 100%; + justify-content: center; + align-items: center; + padding-left: 20px; +} + +.app-hr-item { + flex: 1; +} + +.percentbox { + border: 1px solid #E4393C; + float: left; + width: 60%; + height: 14px; + margin-top: 2px; + margin-left: 10px; +} + +.percentbg { + height: 100%; + background: #E4393C; +} + +.app-hr-text { + float: left +} + +.appr-filter { + width: 100%; + height: 30px; + border: 1px solid #f5f5f5; + background-color: #fafafa; +} + +.appr-filterbox { + width: 100%; + height: 100%; +} + +.appr-filterbox li { + float: left; + padding: 5px 10px; +} + +.appr-filterbox li .curr { + background: #fafafa; + color: #e4393c; +} + +i { + font-style: normal; +} + +.apprimg { + width: 25px !important; + height: 25px; + border-radius: 50%; + float: left +} + +.appr-star, +.appr-star-off { + background-image: url(./../img/star.png); + background-repeat: no-repeat; + width: 15px; + height: 15px; + margin-right: 2px; + float: left; +} + +.appr-star-off { + background-position: -80px 0px; +} + +.userinfo { + width: 100%; + height: 26px; +} + +.appraises-box { + width: 960px; + border-bottom: 1px solid #eee; + margin: 5px 0; + padding: 0 5px; +} + +.wst-appraises-left { + width: 84%; + height: 100%; + float: left; +} + +.app-content { + margin: 10px 0; +} + +.wst-appraises-right { + width: 150px; + height: 100%; + float: left; +} + +.goods-spec-box { + width: 100%; + height: 100%; +} + +.appraiser { + height: 100%; + float: left; + padding-left: 5px; +} + +.reply-content { + line-height: 15px; + width: 100%; + border-top: 1px solid #eee; + padding-top: 10px; + color: orange; + float: left; + margin-bottom: 10px; +} + +.reply-time { + float: left; + color: #999; + padding-bottom: 10px; +} + +.reply-content>a { + color: orange; +} + +.reply-box { + width: 100%; + max-height: 110px; + position: relative; + margin-bottom: 5px; +} + +.goods-desc-box img { + display: block; +} + + +/* 商品咨询 */ + +.c999 { + color: #ccc; +} + +.consult-searchbox { + padding: 17px 0 0 43px; +} + +.search-tips { + color: #999; + padding-bottom: 10px; +} + +.search-text { + float: left; + width: 449px; + height: 28px !important; + border: 1px solid #ccc !important; + border-right: none; + font: 12px/34px simsun; + color: #999; + padding: 0 10px; +} + +.csbtn { + float: left; + width: 82px; + height: 34px; + background: #e4393c; + border: none; + line-height: 1; + color: #fff; + font-family: "Microsoft YaHei"; + font-size: 16px; + cursor: pointer; +} + +.consult-list { + padding: 0 15px 0 43px; +} + +.cs-content { + width: 75%; +} + +.ask { + padding: 15px 0 7px; +} + +.answer { + color: #ff6500; + padding-bottom: 15px; +} + +.consult-item { + font: 12px/18px simsun; + border-bottom: 1px dotted #eee; +} + +.consult-publish { + height: 300px; + border: 1px solid red; + margin-top: 20px; + border-width: 2px 1px 1px; + border-color: #999 #dedede #dedede; + border-style: solid; +} + +.consult-publish h5 { + height: 30px; + line-height: 30px; + font-size: 14px; + font-family: '\5fae\8f6f\96c5\9ed1'; + padding-left: 10px; +} + +.explain, +.consult-publish ul { + padding: 10px 20px; +} + +.consult-publish ul li { + margin-bottom: 5px; + line-height: 25px; +} + +.fbold { + font-weight: bold; + vertical-align: top; +} + +#consultContent { + width: 500px; + height: 100px; +} + +#consultCommit { + display: inline-block; + width: 72px; + height: 29px; + margin-left: 62px; + vertical-align: middle; + background: #e54043; + border: none; + color: #fff; + cursor: pointer; +} + +button:focus { + outline: none; +} + +.intro { + min-height: 445px; +} + +.j-inform { + float: right; +} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/goodslist.css b/hyhproject/home/view/default/css/goodslist.css new file mode 100755 index 0000000..20c01ca --- /dev/null +++ b/hyhproject/home/view/default/css/goodslist.css @@ -0,0 +1,243 @@ +@CHARSET "UTF-8"; +.wst-hot-sales{background:#f1f1f1;width:1200px;margin-left: auto; margin-right: auto;margin-top:10px;padding:15px 0px;overflow:hidden;height:112px;} +.wst-hot-sales .wst-sales-logo{width:60px;float:left;text-align: center;position:relative;} +.wst-hot-sales .wst-sales-box{float:left;width:1130px;overflow:hidden;} +.wst-hot-sales .wst-sales-logo .wst-hot-icon{position: absolute;top:0;left:20px;width:19px;height: 70px;padding:2px 10px;background:url(../img/img_bg_goodslist_tjrm.png) 4px 0px no-repeat;text-align: center;writing-mode:tb-rl;} +.wst-hot-sales .wst-sales-box .item{height:120px;width:263px;background:#fff;margin-left:17px;float:left;} +.wst-hot-sales .wst-sales-box .item .img{float:left;width:120px;height: 120px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;} +.wst-hot-sales .wst-sales-box .item .img a{display:table-cell;vertical-align:middle;width:120px; height:120px; padding:5px;} +.wst-hot-sales .wst-sales-box .item .img a img{max-width:110px;max-height:110px; } +.wst-hot-sales .wst-sales-box .item .des{float:left;width:130px;height: 120px; padding:5px;line-height:20px;} +.wst-hot-sales .wst-sales-box .item .des .p-sale{font-weight: bold;color:#C00;} +.wst-hot-sales .wst-sales-box .item .des .p-name{height: 40px;line-height: 20px;overflow: hidden;} +.wst-hot-sales .wst-sales-box .item .des .p-price{font-weight: bold;color:#C00;} +.wst-hot-sales .wst-sales-box .item .des .p-buy a {display: inline-block;line-height: 14px;height: 14px;border-radius: 2px;background: #F7F7F7;text-align: center;text-decoration: none;cursor: pointer;border: 1px solid #DDD;padding: 4px 13px 5px;color: #666;background-color: #f7f7f7;background-repeat: repeat-x;background-image: -moz-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: -webkit-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: -o-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: linear-gradient(top,#f7f7f7,#f2f2f2);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7', endColorstr='#f2f2f2', GradientType=0);} +.wst-hot-sales .wst-sales-box .item .des .p-buy a:hover{color:#df2003;} +.wst-filters{width:1200px;margin-left: auto;margin-right: auto;margin-top:10px;color:#999;} +.wst-filters div.item,.wst-address div.item{float:left;margin-right:6px;position:relative;} +.wst-filters .arrow,.wst-address .arrow{float:left;position: relative;top:2px;padding-right:12px;font-style: normal;} +.wst-filters .item .link,.wst-address .item .link{color:#666;float:left;border:0px;margin-right:5px;height:22px;line-height: 22px;} +.wst-filters .item .drop-down,.wst-address .item .drop-down{float:left;margin-right:5px;border: 1px solid #eee;display: inline-block;height: 23px;line-height: 23px;padding: 0 4px 0 8px;vertical-align: top;position: relative;background-color: #fff; } +.wst-filters .item .drop-down .drop-down-arrow,.wst-address .item .drop-down .drop-down-arrow{display: inline-block;width: 20px;height: 20px;vertical-align: top;background: url(../img/search.png) no-repeat 4px 7px;-webkit-transition: background-position .15s ease-in-out;-moz-transition: background-position .15s ease-in-out;transition: background-position .15s ease-in-out;} +.wst-filters .item .drop-down.hover{border-color:#df2003;border-bottom:0;z-index: 100} +.wst-address .item .drop-down.hover{border-color:#ddd;border-bottom:0;z-index: 2} +.wst-filters .item .drop-down.hover .drop-down-arrow,.wst-address .item .drop-down.hover .drop-down-arrow{background-position: 4px -44px;} +.wst-filters .item .dorp-down-layer{border: 1px solid #ddd;border-top:0;display:none;left:0px;top:22px;position:absolute;z-index: 99;background:#fff;min-width: 320px;border: 1px solid #df2003;} +.wst-address .item .dorp-down-layer{padding:10px;border: 1px solid #ddd;border-top:0;display:none;left:0px;top:22px;position:absolute;z-index: 1;background:#fff;min-width: 320px;border: 1px solid #ddd;} +.wst-filters .item .dorp-down-layer div.cat1,.wst-address .item .dorp-down-layer div.cat1{float:left;width:140px; overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +.wst-filters .item .dorp-down-layer div.cat2,.wst-address .item .dorp-down-layer div.cat2{float:left;width:80px; overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +.wst-filters .item .dorp-down-layer div:hover,.wst-filters .item .dorp-down-layer a:hover{color:#df2003;cursor:pointer;} +.wst-address .item .dorp-down-layer div:hover,.wst-address .item .dorp-down-layer a:hover{color:#ff8043;;cursor:pointer;} +.wst-filters .item .v-item,.wst-address .item .v-item{float:left;color:#666;border: 1px solid #ddd;cursor: pointer;display: inline-block;font-size: 12px;height: 22px;line-height: 22px;margin: 0 5px 5px 0;padding: 0 30px 0 4px;position: relative;vertical-align: top;} +.wst-filters .item .v-item:hover,.wst-address .item .v-item:hover{border-color: #e4393c;} +.wst-filters .item .v-item i,.wst-address .item .v-item i{ display: block;position: absolute; width: 25px;height: 22px;right: 0;text-align:center;font-style: normal;top: 0;} +.wst-filters .item .v-item:hover i,.wst-address .item .v-item:hover i{background-color: #e4393c;color: #fff;} +.wst-filters .keyword,.wst-address .keyword{height:22px;line-height:22px;} +.wst-selector{width:1200px;margin-left: auto;margin-right: auto;margin-top:10px;color:#999;} +.wst-selector .head{padding-left:10px;background: #f1f1f1 none repeat scroll 0 0;border-bottom: 1px solid #ddd;height: 34px;line-height: 34px;overflow: hidden;} +.wst-selector .main{} +.wst-selector .item{border-bottom: 1px solid #ddd;line-height: 90px;width:1200px;height:auto;border-bottom: 1px solid #ddd;} +.wst-selector .label{float:left;width:90px;padding-left:10px;} +.wst-selector .content{float:left;width:990px;height: 90px;overflow: hidden;} +.wst-selector .content .s-item{float:left;margin-right:50px;color:#666;cursor:pointer} +.wst-selector .extra{float:left;width:110px;margin-top: 5px;} +.extra_more{float: left;margin-right: 10px;position: relative;width: 39px;height: 23px;line-height: 23px;padding: 0 7px 0 4px;background: #fff;visibility: hidden;color: #333;border: 1px solid #ddd;} +.extra_multi{float: left;height: 23px;line-height: 23px;border: 1px solid #DDD;padding: 0 3px 0 18px;position: relative;background: #fff;color: #333;} +.extra_multi i,.extra_more i{position: absolute;display: block;font-style: normal;width: 13px;height: 20px;background-image: url(../img/search.png);transition:all ease 0.2s;} +.extra_more i{top: 1px;right: 2px;width: 20px;background-position: 4px 7px;} +.extra_more:hover,.extra_more:hover i{color:red;background-position: 4px -10px;} +.extra_multi:hover,.extra_multi:hover i{border-color: red;color:red;background-position: 0px -84px;} +.extra_more_on i{background-position: 4px -27px!important} +.extra_more_on:hover i{background-position: 4px -44px!important} +.extra_multi i{left: 3px;top: 1px;background-position: 0 -63px;} +.multi_on{border: 2px solid #edd28b!important;background: #fffdee;height: 120px;width:1195px!important;} +.multi_btns{width: 100%;text-align: center;margin: 10px 0;} +.multi_btns a{display: inline-block;padding: 0px 7px;border: 1px solid #ddd;color: #666;background-color: #f7f7f7;border-radius: 2px;} +.multi_btns .confirm_btn{background-color: #E74649;color: #fff;margin-right: 10px;visibility:hidden;} +.multi_btns .disable_btn{background-color: #ddd;color: #fff;} +.s-item i{position: absolute;left: 0;top: 2px;background: url(../img/search.png) no-repeat 9999px 9999px;display: inline-block;height: 12px;width: 12px;background-color: #fff;border: 1px solid #ccc;font-size: 0;visibility: hidden;} +.selected i{border-color: #e4393c;background-position: -1px -107px!important;} +.multi_on .s-item i{visibility: visible;} +.s_chk{padding-left: 18px;position:relative} +.brand_itembox{padding: 1px 0!important;height: 70px;margin: 10px 0;} +.brand_item{width: 10%;border: 1px solid #DDD;margin: -1px -1px 0 0!important;height:80px;overflow:hidden;text-align: center;background-color: #fff;} +.brand_item a.s_chk{visibility: hidden!important;} +.brand_itembox .selected{position: relative;z-index: 10;border-color: #e4393c!important;} +.brand_itembox .selected .g_bd_imgbox{border-color: #e4393c;} +.brand_item:hover{position: relative;z-index: 10;border-color: #e4393c;box-shadow: 2px 2px 3px rgba(0,0,0,.12);} +.brand_item:hover .g_bd_imgbox{border-color: #e4393c;color:#e4393c} +.brand_item:hover .g_bd_img{display: none;} +.g_bd_img{width: 100%;height: 100%;} +.g_bd_imgbox{border:1px solid transparent;width:98%;height:80px;line-height: 80px;} +.wst-selector .item-more-box{border-top: 1px solid #ddd;position: relative;text-align: center;top: -1px;transition: border-color 0.15s ease-in-out 0s;} +.wst-selector .item-more-box .item-more{position: relative;top:-1px;border-top:0px;padding:0 40px 0 20px;background: #fff none repeat scroll 0 0;border-color: #fff #ddd #ddd; border-style: solid;border-width: 1px;color: #333;cursor: pointer;display: inline-block;height: 28px;line-height: 28px;position:relative;} +.wst-selector .item-more-box .item-more i{display: inline-block;width: 20px;height: 20px;vertical-align: top;background: url(../img/search.png) no-repeat;position:absolute;top:3px;} +.wst-selector .item-more-box .item-more i.drop-down{background-position: 4px 7px;} +.wst-selector .item-more-box .item-more i.down-hover{background-position: 4px -11px;} +.wst-selector .item-more-box .item-more i.drop-up{background-position: 4px -27px;} +.wst-selector .item-more-box .item-more i.up-hover{background-position: 4px -44px;} +.wst-selector .item-more-box .item-more i.drop-down-icon{background-position: 4px -9px;} +.wst-selector .item-more-box:hover {border-color: #e4393c;} +.wst-selector .item-more-box:hover .item-more {border-color: #fff #e4393c #e4393c;color: #e4393c;} +.wst-container .goods-side{float:left;width:210px;margin-top:10px;margin-right:5px;} +.wst-container .goods-side .title{line-height:35px;background-color: #f7f7f7;text-align: center;} +.wst-container .goods-side .guess-like{min-height:300px;border:1px solid #eee;padding-bottom:10px;} +.wst-container .goods-side .item{padding-top:10px;} +.wst-container .goods-side .item .img{width:200px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.wst-container .goods-side .item .img a{display:table-cell;vertical-align:middle;width:200px; height:200px;} +.wst-container .goods-side .item .img a img{max-width:190px;max-height:190px;} +.wst-container .goods-side .item .p-price{padding:5px;font-weight: bold;color:#C00;font-size:14px;} +.wst-container .goods-side .item .v-price{text-decoration: line-through;color:#999;margin-left: 10px;font-weight: normal;font-size:12px} +.wst-container .goods-side .hot-goods{min-height:300px;border:1px solid #eee;margin-top: 15px;padding-bottom:10px;} +.wst-container .goods-main{float:right;width:980px;margin-top:10px;position: relative;} +.goods-main .goods-filters{border-top: 1px solid #ddd;margin-bottom: 5px;position: relative;z-index:4;} +.goods-main .goods-filters .line{padding:5px;height:25px;border-bottom: 1px solid #e5e5e5;} +.goods-main .goods-filters .line2{background:#f7f7f7;} +.goods-filters .line2 a{background: #fff none repeat scroll 0 0;border: 1px solid #e9e7e7;color: #333;float: left;height: 23px;line-height: 23px;padding: 0 20px;} +.goods-filters .line2 a:hover{border:1px solid #DF2003;} +.goods-filters .line .city{float:left;width:auto;} +.goods-filters .line .chk{float:left;height: 23px;line-height: 23px;margin-right:10px;} +.goods-filters .line a.curr {background: #DF2003 none repeat scroll 0 0;border: 1px solid #DF2003;color: #fff;} +.goods-filters .line .store,.goods-filters .line .store2,.goods-filters .line .store3{float:right;width:16px;height:13px;margin:5px 0px 0px 3px;} +.goods-filters .line .store{background:url(../img/store_icon_sx.png) 0px 0px no-repeat;} +.goods-filters .line .store2{background:url(../img/store_icon_sx_sel.png) 0px 0px no-repeat;} +.goods-filters .line .store3{background:url(../img/store_icon_sx_sel_up.png) 0px 0px no-repeat;} +.wst-price-ipts{float:left;position: relative;} +input.wst-price-ipt{width:66px;height: 19px;outline: none;padding-left:18px;border: 1px solid #e9e7e7;} +input.wst-price-ipt:focus{border: 1px solid #ff8043;} +.wst-price-ipt1{position: absolute;left: 14px;top: 4px;} +.wst-price-ipt2{position: absolute;right: 74px;top: 4px;} +.wst-price-but{outline: none;background:#f7f7f7;color: #9f9696;border: 1px solid #dad7d7;cursor:pointer;} +.wst-price-but:not(.disabled):not(:disabled):active, .wst-price-but.active{background: #f1f1f1;background-clip: padding-box;} +.goods-list{width:100%;} +.goods-list .goods{width:233px;margin:5px 4px 5px 6px;border:1px solid #eee;float:left;height:430px;} +.goods-list .goods:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd;} +.goods-list .goods .img{width:233px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.goods-list .goods .img a{display:table-cell;vertical-align:middle;width:233px; height:233px;} +.goods-list .goods .img a img{max-width:210px;max-height:210px;} +.goods-list .goods .p-price{height:26px;line-height:26px;padding:5px 0px 5px 12px;font-weight: bold;color:#C00;font-size:14px;width:113px;float:left;overflow: hidden;} +.goods-list .goods .p-hsale{padding:5px 12px 5px 0;width:93px;float:right;text-align: right;} +.goods-list .goods .p-hsale span{font-weight: bold;color:#df2003;} +.goods-list .goods .p-hsale .p-add-cart{line-height: 24px;display: block;border: 1px solid #DF2003;width: 75px;height: 24px;text-align: center;color: #DF2003;float: right;} +.goods-list .goods .p-hsale .p-add-cart:hover{background: #DF2003;color: white;} +.goods-list .goods .p-name{height: 40px;line-height: 20px;overflow: hidden;width:210px;margin-left:12px;} +.goods-list .goods .p-shop{padding:5px 5px 5px 12px;position: relative;} +.goods-list .goods .p-shop .contrast{position: absolute;padding-left: 17px;top:5px;right:10px;z-index: 1;} +.goods-list .goods .p-shop .contrast:hover{color:#e4393c;} +.goods-list .goods .p-shop .contrast i{position: absolute;top: 3px;left: 0;width: 14px;height: 14px;background: url(../img/contrast.png) 0 0 no-repeat;background-size: 100%;} +.goods-list .goods .p-mprice{color:#999;padding:5px 0px 5px 12px;width:113px;float:left;} +.goods-list .goods .p-mprice span{text-decoration: line-through;} +.goods-list .goods .p-appraise{padding:5px 5px 5px 0px;width:100px;float:right;text-align: right;} +.goods-list .goods .p-appraise span{font-weight: bold;color:#1499E5;} +.goods-list .goods .tags{padding-left:10px;} +.goods-list .goods .tags .tag{background:#DF2003;color:#ffffff;padding:0px 4px 1px 4px;margin-right:5px;border-radius:8%} +.img_list{padding-left: 5px;} +.img_list li{float:left;width: 25px;height: 25px;margin-right: 2px;box-sizing:border-box;} +.img_list li.curr{border: 1px solid red;} +.img_list li img{max-width: 100%;max-height: 100%;} +.wst-recommend,.wst-relook{margin-bottom: 20px;height:410px;border:1px solid #ddd;} +.wst-recommend .title,.wst-relook .title, .wst-gview .title{line-height:35px;background-color: #f7f7f7;padding:0 10px;border-top:2px solid #ddd;} +.tgoods-list{width:100%;} +.tgoods-list .goods{width:230px;margin:5px 0px 5px 6px;border:1px solid #ddd;float:left;} +.tgoods-list .goods:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd; } +.tgoods-list .goods .img{width:230px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.tgoods-list .goods .img a{display:table-cell;vertical-align:middle;width:230px; height:230px;} +.tgoods-list .goods .img a img{max-width:223px;max-height:223px;} +.tgoods-list .goods .p-price{padding:5px 0px 5px 5px;font-weight: bold;color:#df2003;width:120px;float:left;font-size:14px;} +.tgoods-list .goods .p-hsale{padding:5px 5px 5px 0;width:100px;float:right;text-align: right;} +.tgoods-list .goods .p-hsale span{font-weight: bold;color:#df2003;} +.tgoods-list .goods .p-hsale .p-add-cart{line-height: 15px;display: block;border: 1px solid #ff6a53;width: 75px;height: 15px;text-align: center;color: #ff6a53;float: right;} +.tgoods-list .goods .p-hsale .p-add-cart:hover{background: #ff6a53;color: white;} +.tgoods-list .goods .p-name{height: 40px;line-height: 20px;overflow: hidden;padding:0 5px;} +.tgoods-list .goods .p-shop{padding:5px;} +.tgoods-list .goods .p-mprice{color:#999;padding:5px 0px 5px 5px;width:120px;float:left;} +.tgoods-list .goods .p-mprice span{text-decoration: line-through;margin-left: 10px;font-weight: normal;} +.tgoods-list .goods .p-appraise{padding:5px 5px 5px 0;width:100px;float:right;text-align: right;} +.tgoods-list .goods .p-appraise span{font-weight: bold;color:#1499E5;} +.wst-gview{margin-top:10px;]margin-bottom: 20px;height:270px;border:1px solid #ddd;} +.wst-gview .view-goods .item{float:left;position:relative;width:162px; margin: 5px 0px 5px 6px;border:1px solid #eeeeee;float:left;} +.wst-gview .view-goods .item:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd; } +.wst-gview .view-goods .item .img{width:156px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.wst-gview .view-goods .item .img a{display:table-cell;vertical-align:middle;width:156px; height:156px;} +.wst-gview .view-goods .item .img a img{max-width:156px;max-height:156px;} +.wst-gview .view-goods .item .p-price{padding:5px;font-weight: bold;color:#df2003;} +.wst-gview .view-goods .item .v-price{text-decoration: line-through;color:#999;margin-left: 6px;font-weight: normal;} +/*自定义复选框-列*/ +.checkbox-box-s{float:left;width:15px;height:20px;margin-top: 3px;} +.wst-checkbox-s + label {-webkit-appearance: none;background-color: #ffffff;border: 1px solid #d5d5d5;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox-s + label:after {content: '\2714';color: #ccc;font-size: 13px;position: absolute;top: -5px;left: 1px;} +.wst-checkbox-s:checked + label{border: 1px solid #ff8043;/* 修改选框选中颜色*/} +.wst-checkbox-s:checked + label:after {content: '\2714';color: #ff8043;font-size: 13px;position: absolute;top: -5px;left: 1px;} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-6px;top:-1px;} +.checkbox-box-s label{position: relative;top:-24px;left:-4px;} +.wst-no-goods{height: 50px;line-height:50px;color:red;text-align:center;font-weight:bold;} +.wst-no-goods span{color:#999;} +/*发货地*/ +.tab-header{border-bottom:2px solid #df2003;width: 100%;height:20px;background: #fff;} +.tab li{display:block;margin:0px;float:left;background-color:#fff;height:20px;} +.tab-item1 a{background: #fff;color:gray;border:1px solid #ddd;float:left;min-width:80px;width:auto;text-align: center;} +.j-tab-selected1 a{background: #fff;border:2px solid #df2003;border-bottom: #fff solid 2px;} +.area{float: left;overflow: hidden;padding: 4px 8px;text-overflow: ellipsis;white-space: nowrap;width: 80px;} +.area-box li{float:left;width:80px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +/*商品对比*/ +.wst-contrast{width: 100%;padding-top: 20px;padding-bottom: 29px;} +.wst-contrast .goods{background: #fff;} +.wst-contrast .goods .table,.wst-contrast .table2{width: 100%;border-collapse: collapse;table-layout: fixed;border-top: 1px solid #e4e4e4;border-left: 1px solid #e4e4e4;margin-top: -1px;} +.wst-contrast .goods .table td,.wst-contrast .goods .table th{padding: 20px 0 16px;border-right: 1px solid #e4e4e4;border-bottom: 1px solid #e4e4e4;line-height: 24px;font-family: SimSun;background: #fff;} +.wst-contrast .goods .table th{width: 125px;text-align: right;font-weight: 400;background: #f7f7f7;color: #999;} +.wst-contrast .choice{margin-left: 10px;margin-bottom: 10px;text-align: left;} +.wst-contrast .choice input{margin-right: 5px;vertical-align: middle;} +.wst-contrast .choice label {display: inline-block;height: 16px;line-height: 16px;vertical-align: middle;color: #666;} +.wst-contrast .goods-item{width: 200px;margin: 0 auto;} +.wst-contrast .goods-item:hover .operation .del{opacity: 1;} +.wst-contrast .goods-item .img{width: 100%;height: 160px;text-align: center;} +.wst-contrast .goods-item .img img{width: 160px;border: 0;vertical-align: middle;} +.wst-contrast .goods-item .name{height: 32px;overflow: hidden;margin-top: 10px;line-height: 16px;color: #333;} +.wst-contrast .goods-item .price{height: 28px;line-height: 28px;margin-top: 10px;font-family: "Microsoft YaHei";font-size: 14px;color: #e4393c;} +.wst-contrast .goods-item .price span{font-size: 20px;font-weight: 400;} +.wst-contrast .goods-item .operation{position: relative;width: 100%;height: 30px;margin-top: 13px;} +.wst-contrast .goods-item .operation .see{display: block;margin-bottom: 10px;width: 80px;height: 30px;line-height: 30px;text-align: center;background: #e4393c;color: #fff;} +.wst-contrast .goods-item .operation .see:hover{background: #e75153;} +.wst-contrast .goods-item .operation .del{position: absolute;right: 0;top: 5px;font: 12px/20px SimSun;opacity: 0;} +.wst-contrast .goods-item .operation .del:hover{color: #e4393c;} +.wst-contrast .goods-fixed{position: fixed;top: 0;z-index: 100;left: 50%;width: 1200px;margin-left: -600px;} +.wst-contrast .goods-fixed .img{float:left;width: 100px;height: 100px;} +.wst-contrast .goods-fixed .img img{width: 90px;margin-top: 5px;} +.wst-contrast .goods-fixed .name{display: none;} +.wst-contrast .goods-fixed .price,.wst-contrast .goods-fixed .operation{float:left;width: 100px;} +.wst-contrast .goods-fixed .operation .del{right:-16px;} +.wst-contrast .goods-fixed2{display: none;} +.wst-contrast .goods-fixed2 th{height: 126px;} +.wst-contrast .table2 td,.wst-contrast .table2 th{padding: 20px 0 16px;border-right: 1px solid #e4e4e4;border-bottom: 1px solid #e4e4e4;line-height: 24px;font-family: SimSun;background: #fff;} +.wst-contrast .table2 th {width: 125px;text-align: right;font-weight: 400;background: #f7f7f7;color: #999;} +.wst-contrast .table2 .left-title{margin-right: 36px;} +.wst-contrast .table2 .right-title{padding-left: 35px;width: 200px;overflow: hidden;word-wrap: break-word;} +.wst-contrast .table2 .list-box{width: 200px;padding-left: 35px;} +.wst-contrast .table2 .list-box li{float: left;height: 29px;line-height: 29px;padding: 0 13px;border: 1px solid #d7d7d7;margin-right: 6px;margin-bottom: 6px;cursor: pointer;} +.wst-contrast .table2 .list-box li.img{padding:0;height: 40px;} +.wst-contrast .table2 .list-box li img{width: 40px;height: 40px;} +.wst-contrast .table2 .list-box li:hover{color: #e4393c;} +.wst-contrast .table2 .list-box li.active{color: #e4393c;border-color: #e4393c;} +.wst-contrast .table2 .identical_0.active td{background: #f4f9fd;} +.wst-contrast .table2 .identical_1.active{display: none;} +/*商品对比*/ +.wst-cont-frame{position: fixed;bottom: -200px;right: 50%;margin-right: -602px;z-index: 100;width: 986px;height: 139px;background: #fff;-moz-box-shadow: 0 0 15px rgba(221,221,221,0.8);-webkit-box-shadow: 0 0 15px rgba(221,221,221,0.8);box-shadow: 0 0 15px rgba(221,221,221,0.8);-webkit-transition: all .2s linear;transition: all .2s linear;} +.wst-cont-frame.show{bottom: 0;} +.wst-cont-frame .head{height: 32px;border: 1px solid #ddd;border-bottom: 2px solid #e23c3d;position: relative;} +.wst-cont-frame .head span{float: left;width: 80px;height: 36px;line-height: 30px;text-align: center;font: 14px/30px 'microsoft yahei';position: relative;left: -1px;margin-top: -4px;background: #fff;border: 2px solid #e23c3d;border-bottom: 0;color: #e23c3d} +.wst-cont-frame .head .close{text-align: right;position: absolute;right: 0;top: 0;padding-right: 22px;height: 30px;line-height: 30px;color: #005aa0;} +.wst-cont-frame .list{border: 2px solid #e23c3d;border-top: none;position: relative;} +.wst-cont-frame .goods{padding: 6px;color: #ccc;height: 90px;overflow: hidden;} +.wst-cont-frame .term{float: left;overflow: hidden;margin-right: 10px;padding: 17px 10px 12px 0;border-right: 1px dotted #e23c3d;} +.wst-cont-frame .term:hover .info .price a{opacity: 1;} +.wst-cont-frame .term .img{float: left;margin-right: 5px;width: 48px;height: 48px;text-align: center;border: 1px solid #fff;overflow: hidden;} +.wst-cont-frame .term .info,.wst-cont-frame .list .term-empty .info{float: left;width: 140px;} +.wst-cont-frame .term .info .name{height:36px;line-height: 18px;overflow: hidden;display: block;color: #333;} +.wst-cont-frame .term .info .price span{color: #e4393c;font-size: 14px;font-family: Verdana;font-weight: bold;} +.wst-cont-frame .term .info .price a{padding-left: 10px;color: #005aa0;opacity: 0;} +.wst-cont-frame .term-empty{float: left;overflow: hidden;margin-right: 10px;padding: 17px 10px 12px 0;border-right: 1px dotted #e23c3d;} +.wst-cont-frame .term-empty .img{float: left;margin-right: 5px;width: 48px;height: 48px;text-align: center;color: #ccc;border: 1px solid #fff;font: 36px/48px arial;overflow: hidden;background: #f6f6f6;} +.wst-cont-frame .term-contrast{position: absolute;right: 22px;top: 22px;width: 85px;text-align: center;} +.wst-cont-frame .term-contrast .contrast{display: block;margin: 0 auto;margin-bottom: 10px;font: bold 14px/30px verdana;width: 60px;height: 30px;line-height: 30px;text-align: center;background: #e4393c;color: #fff;} +.wst-cont-frame .term-contrast .contrast:hover{background: #e75153;} +.wst-cont-frame .term-contrast .empty{color: #005aa0;} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/index.css b/hyhproject/home/view/default/css/index.css new file mode 100755 index 0000000..0445ae8 --- /dev/null +++ b/hyhproject/home/view/default/css/index.css @@ -0,0 +1,2299 @@ +@CHARSET "UTF-8"; +#wst-slide .wst-slide-itemswrap, +#wst-slide .wst-slide-items, +#wst-slide .wst-slide-items li { + height: 420px; + overflow: hidden +} + +.wst-slide-controls { + position: absolute; + text-align: right; + top: -40px; + left: 50%; + transform: translateX(-50%); +} + +.wst-slide-controls span { + width: 24px; + height: 24px; + text-align: center; + display: inline-block; + line-height: 24px; + border-radius: 12px; + background-color: #333; + color: white; + cursor: pointer +} + +.wst-slide-controls .curr { + background-color: #e13335; + border-radius: 12px; + color: white; + cursor: pointer +} + +.wst-slide { + position: relative; + top: 2px +} + +.wst-slide-numbox { + width: 1200px; + margin: 0 auto; + height: 0; + position: relative; + z-index: 3 +} + +.wst-slide-items { + min-width: 1200px +} + +.wst-tab-box { + overflow: hidden; + border-right: 1px solid #eee; + width: 100%; + height: auto; + margin: 0 auto; + background: #fff +} + +.wst-tab-nav { + overflow-y: hidden; + margin: 0; + padding: 0; + height: 35px; + top: 0; + z-index: 30; + background: #fff; + width: 100%; + border-bottom: 1px solid #eee; + border-left: 1px solid #eee +} + +.wst-tab-nav li, +.wst-tab-nav .tab { + width: 40%; + cursor: pointer; + float: left; + margin: 0; + list-style: none; + border: 1px solid #eee; + border-bottom: 0; + border-left: none; + line-height: 34px; + text-align: center; + color: #000; + padding-left: 10px; + padding-right: 10px +} + +.wst-tab-nav .on { + border-top: 1px solid #ff2704; + border-bottom: 1px solid #fff; + color: #ff2704; + font-weight: bold +} + +.wst-tab-content { + padding: 5px; + width: 99%; + height: auto; + border: 1px solid #eee; + border-top: 0; + background: #FFF +} + +#wst-right-news { + width: 100%; + height: 30px; + background: #df2002; + line-height: 25px; + color: #fff +} + +#wst-right-news>p { + float: left; + margin-left: 12px; + font-weight: bold +} + +#wst-right-news>a { + display: block; + float: right; + color: #fff; + margin-right: 5px +} + +#wst-right-new-list { + height: 117px; + background-color: #fff +} + +#wst-right-new-list>div { + width: 190px; + height: 23px; + line-height: 25px; + padding-left: 10px; + white-space: nowrap; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + list-style-type: disc +} + +#wst-right-new-list>div>a { + color: #605e5e +} + +#wst-right-new-list>div>a:hover { + color: #df2002 +} + +.visitor-new-list { + height: 118px!important; + overflow: hidden; + border: 0; + background-color: #fff +} + +.visitor-new-list>li { + height: 23px!important +} + +.apply-btn { + background: url(../img/apply.png) no-repeat 0 0; + background-size: cover; + display: block; + width: 180px; + height: 60px; + margin: 20px auto 10px +} + +.shop-login { + margin-left: 60px; + height: 28px; + display: block; + color: #999 +} + +.ws-right-user { + display: block; + width: 210px; + height: 128px; + background: #fff +} + +.ws-right-user .top, +.ws-right-user .bottom { + float: left +} + +.ws-right-user .top img { + float: left; + width: 65px; + height: 65px; + margin: 10px; + border-radius: 1000px +} + +.ws-right-user .top .name { + float: left; + width: 125px +} + +.ws-right-user .top .uname { + height: 23px; + line-height: 25px; + width: 100px; + margin: 0 auto; + margin-top: 15px; + text-align: center; + color: #ff2704; + font-size: 14px; + font-family: "microsoft yahei"; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.ws-right-user .top .sign { + display: block; + width: 105px; + height: 30px; + line-height: 30px; + margin: 0 auto; + margin-top: 10px; + color: #fff; + background-color: #ff0c00; + border: 1px solid #ff0c00; + cursor: pointer; + border-radius: 5px; + box-shadow: 0 2px 0 #c3443d; + position: relative; + -webkit-transition: all .2s linear; + transition: all .2s linear +} + +.ws-right-user .top .sign:hover { + background-color: #ee4419 +} + +.ws-right-user .top .sign:focus { + outline: 0 +} + +.ws-right-user .top .sign .plus { + position: absolute; + top: 0; + width: 100%; + left: 0; + font-size: 18px; + color: #f4cf00; + font-style: normal; + opacity: 0; + text-align: center; + -webkit-transition: all .5s linear; + transition: all .5s linear +} + +.ws-right-user .top .active .plus { + top: -36px; + opacity: 1 +} + +.ws-right-user .top .actives .plus { + top: -36px; + opacity: 0; +} + +.ws-right-user .top .actives, +.ws-right-user .top .actives:hover { + color: #747171; + background-color: #eee; + border: 1px solid #ddd; + box-shadow: 0 2px 0 #ddd; +} + +.ws-right-user .bottom .left { + float: left; + width: 110px; + margin-top: 10px; + padding-left: 10px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.ws-right-user .bottom .right { + float: right; + width: 80px; + margin-top: 10px; + padding-left: 10px +} + +#wst-right-ads { + position: relative; +} + +#wst-right-ads>a>img { + width: 210px; + height: 128px; + display: block; +} + +.floor-box { + width: 100%; + margin-top: 15px; + clear: both +} + +.goods-list { + width: 100% +} + +.goods-list .goods { + width: 239px; + float: left; + height: 284px; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} + +.goods-list .goods:hover { + width: 239px; + height: 284px; + -webkit-box-shadow: 0 0 10px #cfcfcf; + -moz-box-shadow: 0 0 10px #cfcfcf; + box-shadow: 0 0 10px #cfcfcf; +} + +.goods-list .goods:hover .img a img { + transform: scale(1.05); +} + +.goods-list .goods:hover .p-name a { + color: #d82a2e; +} + +.goods-list .goods .img { + text-align: center; + position: relative; +} + +.goods-list .goods .img a { + display: block +} + +.goods-list .goods .img a img { + max-width: 180px; + max-height: 180px; + padding-top: 20px; + padding-bottom: 8px; + transition: transform .4s ease, -webkit-transform .4s ease, -moz-transform .4s ease, -o-transform .4s ease +} + +.goods-list .goods .p-price { + font-weight: 600; + color: #C00; + text-align: center; + margin-top: 3px; + font-size: 14px +} + +.goods-list .goods .p-name { + height: 40px; + line-height: 20px; + overflow: hidden; + width: 208px; + margin: 0 auto; + text-align: center +} + +.goods-list .goods .p-shop { + padding: 5px +} + +.goods-list .goods .p-mprice { + color: #999; + padding: 5px 0 5px 5px; + width: 120px; + float: left +} + +.goods-list .goods .p-mprice span { + text-decoration: line-through; + margin-left: 10px; + font-weight: normal +} + +.goods-list .goods .p-appraise { + padding: 5px 5px 5px 0; + width: 100px; + float: right; + text-align: right +} + +.goods-list .goods .p-appraise span { + font-weight: bold; + color: #1499e5 +} + +.floor-top-ads { + margin: 40px 0 0; + width: 1200px +} + +.floor-top-ads a { + float: left +} + +.floor-top-ads img { + width: 400px; + height: 110px +} + +.floor-header { + width: 100%; + height: 38px; + background: white; + margin-top: 20px; + border-bottom: 1px solid #df2002 +} + +.floor-header-f1, +.floor-header-f2, +.floor-header-f3, +.floor-header-f4, +.floor-header-f5, +.floor-header-f6, +.floor-header-f7, +.floor-header-f8, +.floor-header-f9, +.floor-header-f10 { + float: left; + background: url(../img/img_floor_titlebg.png) no-repeat 0; + height: 100%; + width: 23%; + margin-top: 1px +} + +.floor-header .tab { + float: right; + margin-right: 10px; + margin-top: 7px +} + +.floor-header .tab li { + display: block; + margin: 0; + float: left +} + +.floor-header .tab a { + font-size: 13px; + display: block; + height: 15px; + letter-spacing: 1px +} + +.floor-header .tab-item1 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected1 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item2 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected2 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item3 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected3 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item4 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected4 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item5 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected5 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item6 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected6 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item7 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected7 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item8 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected8 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item9 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected9 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item10 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected10 a { + background-color: #df2002; + color: #fff +} + +.floor-left { + float: left; + width: 20%; + height: 620px +} + +.floor-left-ads { + width: 478px; + height: 224px +} + +.floor-left-ads img { + width: 478px; + height: 224px +} + +.floor-left-title { + margin-left: 1px; + color: #fff; + font-size: 15px; + float: left; + margin-top: 13px; + position: absolute; +} + +.floor-right-title { + float: right; + color: #333; + font-size: 16px; + line-height: 38px; + margin-right: 70px; + font-weight: bold; + letter-spacing: 2px; +} + +.one_flimit { + overflow: hidden; + width: 79%; + white-space: nowrap; + text-overflow: ellipsis; +} + +.floor-right { + float: left; + width: 100%; + min-height: 570px +} + +.floor-right-ads { + width: 478px; + float: left; + border-bottom: 1px solid #eee; + border-right: 1px solid #eee; + border-left: 1px solid #eee +} + +.wst-floor-slide-items { + overflow: hidden; + height: 344px; + width: 478px; + position: relative +} + +.wst-floor-slide-items img { + height: 344px; + width: 478px +} + +#screen-left-nav { + width: 35px; + max-height: 335px; + position: fixed; + top: 40%; + left: 15%; + background: #fff; + z-index: 999; + display: block +} + +.lnav { + margin: 0 auto; + background: #fff; + line-height: 30px; + text-align: center; + overflow: hidden; + margin-top: -1px; + cursor: pointer; + display: block; + width: 30px; + height: 29px; + color: #625351; + transition: all .2s ease-in; + -moz-transition: all .2s ease-in; + -webkit-transition: all .2s ease-in; + -o-transition: all .2s ease-in; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFNDg5NURBNDY3MjA2ODExODIyQUVDNTgwRDU1MkZBQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1N0M3MTMzQTlBRTQxMUU0OEY2QkNDMkMzNDJCRDdGNiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1N0M3MTMzOTlBRTQxMUU0OEY2QkNDMkMzNDJCRDdGNiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODBkOTE3NzktZTE1Yi0yNTRkLTljYzMtOGVjNmE4ZTAyMjRjIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjIxNzkxODUyODJEQjExRTQ4RkM0REQwQTBFRkQyNTY2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+3tRxHgAAAAlQTFRFwsLCycnJ////r0pOrgAAAAN0Uk5T//8A18oNQQAAAB5JREFUeNpiYIIABhTIyAQXxgtGpUelR6VpKw0QYACUOgb65Nz92gAAAABJRU5ErkJggg==) 0 25px no-repeat +} + +.lcurr { + background: #df2003 +} + +.lcurr a { + color: white +} + +.wst-floor-slide-numbox span { + background-color: #d4d4d4; + cursor: pointer; + display: inline-block; + height: 4px; + width: 24px; + border-radius: 1.5px +} + +.wst-floor-slide-numbox .curr { + background-color: #f68d8d +} + +.wst-floor-slide-numbox>div { + position: relative; + left: 43%; + top: -20px; + z-index: 99; + height: 10px; + max-width: 300px +} + +.floor-bottom .bx_container { + margin-top: 15px +} + +.floor-right-ads .wst-floor-slide-1 { + height: 344px +} + +.ads-lunbobottom { + margin-top: 30px; + margin-bottom: 20px; + overflow: hidden +} + +.ads-lunbobottom a { + float: left +} + +.ads-lunbobottom a img { + width: 240px; + height: 320px +} + + +/* 广告墙 */ + +.ads_wall { + width: 1200px; + max-height: 480px; + margin: 0 auto; + margin-top: 30px; +} + +.ads_wall a { + overflow: hidden; + transition: all ease .4s; + display: block; +} + +.ads_wall a:hover { + transform: scale(1.01); +} + +.ads_wall a img { + width: 100%; + height: 100%; +} + +.ads_wall_l { + width: 448px; + height: 100%; +} + +.ads_wall_c { + width: 292px; + height: 100%; + margin-left: 6px; + position: relative; + text-align: center; +} + +.ads_wall_r { + width: 448px; + height: 100%; +} + +.ads_wall_item_top { + display: block; + width: 100%; + height: 237px; + margin-bottom: 6px; + position: relative; +} + +.ads_wall_item_bottom { + display: block; + width: 100%; + height: 237px; + position: relative; +} + +.ads_wall_more { + text-align: center; + font-size: 12px; + color: #fff; + position: absolute; + bottom: 20px; +} + +.ads_wall_line { + width: 30px; + height: 2px; + background-color: #fff; + margin-top: 8px; + margin-right: 10px; +} + +.wall_r_line { + width: 50px; +} + + +/* 品牌街 */ + +.brand_street_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.bs_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 23px; +} + +.brand_street { + width: 100%; + max-height: 210px; + margin-top: 10px; + box-sizing: border-box; + background-color: #eee; + padding: 5px; +} + +.brand_street li img { + width: 100%; + height: 100px; +} + +.brand_street li { + box-sizing: border-box; + border-right: 1px solid #ddd; + border-bottom: 1px solid #ddd; + width: 10%; + height: 100%; + float: left; + transition: all ease .4s; +} + +.brand_street li:nth-child(10n) { + border-right: none; +} + +.brand_street li:nth-child(n+11) { + border-bottom: none; +} + +.brand_street li:hover { + box-shadow: 0 0 5px #bdbcbc; + transform: scale(1.05); +} + + +/* 店铺街 */ + +.shop_street_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.ss_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 23px; +} + +.shop_street { + width: 100%; + height: 138px; + margin-top: 10px; + background-color: #f4f4f4; + box-sizing: border-box; + padding: 6px; +} + +.shop_street li:nth-child(n+2) { + margin-left: 0.5%; +} + +.shop_street li img { + width: 100%; + height: 100%; +} + +.shop_street li { + background-image: url(../img/shopstreet_bg.png); + background-repeat: no-repeat; + background-size: 100% auto; + width: 19.6%; + height: 100%; + float: left; + transition: all ease .4s; + position: relative; +} + +.shop_street li:hover { + transform: translateY(-5px); +} + +.ss_desc { + position: absolute; + top: 15%; + left: 9%; +} + +.ssd_tit { + font-size: 24px; + color: #ff2b2b; + font-weight: bold; + margin-bottom: 20px; +} + +.ssd_desc { + font-size: 16px; + color: #ff2b2b; +} + +.ss_entry, +.ss_shopname, +.ss_shopaddr { + font-size: 12px; + color: #fff; + position: absolute; +} + +.ss_entry { + left: 5px; + top: 5px; +} + +.ss_shopname { + right: 5px; + top: 5px; +} + +.ss_shopaddr { + right: 5px; + bottom: 5px; +} + + +/* 积分商城 */ + +.intergral_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.itl_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 15px; + margin-bottom: 10px; +} + +.itl_main { + background-color: #f4f4f4; + width: 100%; + height: 148px; + padding: 6px; + box-sizing: border-box; +} + +.itl_bg img { + width: 100%; + height: 100%; +} + +.itl_bg { + display: block; + height: 100%; + width: 238px; +} + +.itl_item:nth-child(2) { + background-color: #fcfdda; +} + +.itl_item:nth-child(3) { + background-color: #ffefd9; +} + +.itl_item:hover img { + transform: translateX(-10px); +} + +.itl_item img { + transition: all ease .4s; + position: absolute; + max-height: 100%; + right: 0; +} + +.itl_item { + display: block; + width: 468px; + height: 100%; + position: relative; + margin-left: 6px; +} + +.itl_name { + position: absolute; + font-size: 14px; + color: #333; + top: 10%; + width: 40%; + left: 5%; + overflow: hidden; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + z-index: 22; +} + +.itl_price_box { + left: 5%; + top: 45%; + position: absolute; + color: #666; + font-weight: bold; + font-size: 16px; + z-index: 22; +} + +.itl_price { + color: #df2002; +} + +.itl_score { + font-size: 12px; + color: #df2002; + font-weight: normal; +} + +.itl_btn { + position: absolute; + padding: 1px 10px; + background-color: #df2002; + border-radius: 25px; + color: #fff; + left: 5%; + top: 75%; + font-size: 11px!important; + background-color: #df2002; + color: #fff; + transition: all ease .4s; +} + +.itl_btn:hover { + transform: translateY(-5px); +} + + +/* 分销商品 */ + +.distribute_tit { + color: #df2002; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 15px; + width: 1200px; + margin: 0 auto; + margin-top: 30px; + font-size: 18px; + letter-spacing: 2px; +} + +.distribute_out { + width: 1200px; + margin: 10px auto; + height: 295px; + background-color: #f4f4f4; + padding: 6px 0; + margin-top: 10px; +} + +.dis_left_bg img { + width: 100%; + height: 100%; +} + +.dis_left_bg { + width: 237px; + height: 100%; + margin-left: 4px; +} + +.dis_list { + width: 952px; + height: 100%; +} + +.dis_list li { + margin-left: 8px; + float: left; + width: 230px; + height: 100%; + position: relative; + background-color: #fff; + overflow: hidden; +} + +.dis_list li:hover img { + transform: scale(1.1); +} + +.dis_list li img { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; + margin: auto; + transition: all ease .4s; +} + +.dis_gprice div { + transform: rotate(30deg); + position: absolute; + left: 11px; + top: 25px; + text-align: center; + right: 4px; + overflow: hidden; +} + +.dis_gprice { + background-image: url(../img/index_distribute_price_bg.png); + background-repeat: no-repeat; + width: 109px; + height: 78px; + position: absolute; + color: #df2002; + font-weight: bold; + right: 0; +} + + +/* 轮播右侧拍卖区域 */ + +.aution_out { + width: 100%; + height: 170px; + position: relative; + background-color: #fff; + overflow: hidden; +} + +.au_l_btn, +.au_r_btn { + position: absolute; + top: 40%; + background-color: rgba(0, 0, 0, .5); + color: #fff; + left: 0; + padding: 5px; + cursor: pointer; + display: none; +} + +.au_r_btn { + left: initial; + right: 0; +} + +.aution_list { + width: 100%; + position: relative; +} + +.aution_tit { + background-image: url(../img/img_floor_titlebg.png); + background-repeat: no-repeat; + background-size: auto 18px; + font-size: 16px; + color: #df2002; + letter-spacing: 2px; + padding-left: 26px; +} + +.aution_main { + float: left; + width: 210px; + height: 153px; + box-sizing: border-box; +} + +.aution_item { + position: relative; + display: block; + text-align: center; + height: 100%; + width: 100%; +} + +.aution_item img { + width: 150px; + height: 150px; +} + +.aution_time { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.3); + font-size: 16px; + color: #fff; + padding: 10px 0; +} + +.aution_h, +.aution_i, +.aution_s { + width: 24px; + height: 30px; + background-color: #df2002; + padding: 5px; + border-radius: 5px; +} + + +/* 优惠券 */ + +.coupon_out { + width: 1200px; + height: 124px; + margin: 0 auto; + margin-top: 30px; + overflow: hidden; +} + +.coupon_bg img { + width: 100%; + height: 100%; +} + +.coupon_bg { + position: relative; + width: 284px; + height: 124px; + display: block; +} + +.coupon_tit { + position: absolute; + font-size: 24px; + color: #c04f02; + right: 25%; + top: 30%; +} + +.r_btn { + position: absolute; + font-size: 16px; + color: #fff; + right: 0%; + top: 16%; + text-align: center; + width: 31px; + line-height: 21px; + padding: 0 6px; +} + +.coupon_desc { + position: absolute; + color: #e08445; + font-size: 18px; + right: 25%; + top: 66%; +} + +.coupon_item img { + width: 100%; + height: 100%; +} + +.coupon_item { + position: relative; + margin-left: 1%; + width: 24%; + height: 100%; +} + +.coupon_item_color { + color: #e21313; +} + + +/* 团购插件 */ + +.groupon_list_out { + position: absolute; + width: 255px; + height: 255px; + bottom: 29px; + left: 11%; + padding: 19px; + box-sizing: border-box; +} + +.groupon_view { + width: 100%; + height: 100%; + overflow: hidden; +} + +.groupon_list { + width: 100%; + height: 100%; + overflow: hidden; + position: relative; +} + +.groupon_list li { + float: left; + width: 217px; + height: 217px; + box-sizing: border-box; +} + +.groupon_btns { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: center; +} + +.groupon_btns .curr { + background-color: #e89593; +} + +.groupon_btns span { + display: inline-block; + width: 7px; + height: 7px; + border-radius: 50%; + background-color: #fff; + margin-left: 3px; +} + + +/* 新品、热销... */ + +.rec_area { + width: 1200px; + height: 500px; + margin: 0 auto; + margin-top: 30px; +} + +.ral { + width: 329px; + height: 100%; + background-repeat: no-repeat; + margin-right: 6px; + position: relative; +} + +.ral_box { + height: 114px; + width: 243px; + background-color: rgba(255, 255, 255, 0.8); + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 60px; + text-align: center; + letter-spacing: 2px; + padding-top: 20px; + box-sizing: border-box; +} + +.ral_box_tit { + font-size: 18px; + color: #010101; +} + +.ral_line { + width: 45px; + height: 2px; + background-color: #000; + margin: 20px auto; +} + +.ral_desc { + font-size: 12px; + color: #000; +} + +.ral img { + width: 100%; + height: 100%; +} + +.rac { + width: 642px; + height: 100%; +} + +.rac_t { + width: 100%; + height: 60%; + box-sizing: border-box; + background-color: #ffefed; +} + +.rac_t_tit, +.rac_b_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + padding: 5px; +} + +.rac_t_main { + width: 100%; + height: 80%; + margin-top: 10px; + background-color: #fff; +} + +.rac_t_main li:hover img { + transform: scale(1.05); +} + +.rac_t_main li:first-child { + margin-left: 0; +} + +.rac_t_main li { + width: 212.5px; + height: 100%; + margin-left: 2px; + float: left; +} + +.rac_t_img img { + transition: all linear .2s; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; +} + +.rac_t_img { + display: block; + height: 70%; + position: relative; + background-color: #ffefed; +} + +.rac_t_info { + background-color: #ffefed; + height: 29%; + margin-top: 1%; + padding-top: 5%; + padding-right: 1%; + box-sizing: border-box; +} + +.rac_price_color { + color: #df2002; +} + +.c666 { + color: #666; +} + +.del_line { + text-decoration: line-through; +} + +.c14_333 { + font-size: 14px; + color: #333; +} + +.rac_gname { + width: 95%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + padding-left: 5%; +} + +.f10 { + font-size: 10px; +} + +.f12 { + font-size: 12px; +} + +.f14 { + font-size: 14px; +} + +.f16 { + font-size: 16px; +} + +.f88{ + +} + +.rac_price { + margin-top: 5px; + text-align: right; +} + +.rac_b { + width: 100%; + height: 39%; + margin-top: 1%; +} + +.rac_b_l { + width: 295px; + height: 100%; + margin-left: 17.33px; +} + +.rac_bg { + background-color: #f5f5f5!important; +} + +.rac_b_main:hover img { + transform: translateX(-10px); +} + +.rac_b_main { + cursor: pointer; + width: 100%; + height: 150px; + box-sizing: border-box; + margin-top: 13px; + background-color: #fff1f9; + position: relative; +} + +.rac_b_main img { + float: right; + transition: all ease .4s; +} + +.rac_b_info { + position: absolute; + left: 25px; + top: 50px; + z-index: 2; +} + +.mb10 { + margin-bottom: 10px; +} + +.rac_desc { + padding-left: 5px; + width: 95px; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.rac_b_r { + width: 295px; + height: 100%; + margin-right: 17.33px; +} + +.rar { + width: 217px; + height: 100%; + box-sizing: border-box; + background-color: #ffedd8; +} + +.rar_tit { + font-size: 18px; + color: #ffa73b; + letter-spacing: 2px; + padding: 5px; + text-align: center; + margin: 5px; +} + +.rar_glist { + width: 166px; + margin: 0 auto; +} + +.rar_gitem:nth-child(2) { + margin-top: 30px; + background-color: #e5ecff; +} + +.rar_gitem { + width: 100%; + height: 213px; + display: block; + background-color: #ffcd92; + overflow: hidden; + position: relative; +} + +.rar_gitem:hover img { + transform: translateY(-5px); +} + +.rar_gname { + font-size: 14px; + color: #333; + text-align: center; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding-top: 5px; +} + +.rar_gdesc { + padding-top: 3px; + padding-left: 5px; + font-size: 14px; + color: #333; + width: 100%; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.rar_price { + text-align: right; + padding-right: 5px; + position: relative; + z-index: 22; +} + +.rar_line { + width: 70%; + height: 1px; + background-color: #fff; + margin: 5px auto; + margin-bottom: 3px; +} + +.rar_img img { + transition: all ease 0.4s; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; +} + +.rar_img { + width: 100%; + display: block; + height: 65%; + position: relative; +} + +.fl { + float: left; +} + +.fr { + float: right; +} + + +/* 楼层 */ + +.floor_main { + width: 100%; + height: 458px; + box-sizing: border-box; +} + +.fml { + width: 260px; + height: 100%; + position: relative; +} + +.fml img { + width: 100%; + height: 100%; +} + +.f_desc { + font-size: 24px; + color: #fff; + font-weight: bold; + position: absolute; + top: 17%; + left: 17%; +} + +.f1_catbox li { + width: 40%; + float: left; + margin-top: 10px; +} + +.f1_catbox li a { + font-size: 16px; + color: #fff; +} + +.f32 { + font-size: 32px; + vertical-align: sub; +} + +.f1_catbox { + position: absolute; + top: 28%; + left: 13%; +} + + +/* 楼层一个分类 */ + +.fh1 { + border-width: 2px; + position: relative; + margin-bottom: 2px; +} + +.fh1l_titbox { + background-position: 0 6px; + height: 88%; + width: 23%; + position: relative; + top: 7px; +} + +.fh1_tit { + font-size: 18px; + color: #df2002; + font-weight: normal; + float: left; + line-height: 35px; + margin-left: 15%; +} + +.fmr { + width: 934px; + height: 100%; + box-sizing: border-box; +} + +.fmr_glist { + width: 100%; + height: 100%; +} + +.fmr_gitem { + width: 20%; + height: 55%; + display: block; + box-sizing: border-box; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; + transition: all ease .4s; +} + +.fmr_gitem:hover { + box-shadow: 0 0 5px #bdbcbc; + transform: scale(1.01); + z-index: 22; + position: relative; +} + +.fmr_img { + width: 100%; + height: 75%; + box-sizing: border-box; + position: relative; +} + +.fmr_img img { + max-width: 100%; + max-height: 85%; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; +} + +.fmr_gname { + width: 95%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + padding: 0 2.5%; + font-size: 14px; + color: #333; + margin-top: 8px; +} + +.tc { + text-align: center; +} + + +/* 楼层两个分类 */ + +.fh2 { + border-width: 2px; + position: relative; + margin-bottom: 2px; + margin-top: 0px; +} + +.fh2l_titbox { + background-position: 0 6px; + height: 88%; + position: relative; + top: 7px; + width: 38%; +} + +.two_fmilit { + width: 81%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fh2_tit { + font-size: 18px; + color: #df2002; + font-weight: normal; + float: left; + line-height: 35px; + margin-left: 19%; + margin-right: 0px; +} + +.floor_box2 { + height: 481px; + box-sizing: border-box; + margin-top: 45px; + margin-bottom: 70px; +} + +.fb2_more { + font-weight: bold; + margin-right: -20px; +} + +.fb2_l { + width: 588px; + height: 468px; + box-sizing: border-box; + margin-right: 12px; +} + +.fb2_l_l, +.fb2_r_l { + width: 226px; + height: 438px; + box-sizing: border-box; +} + +.fb2_l_r, +.fb2_r_r { + width: 356px; + height: 438px; + box-sizing: border-box; +} + +.fb2_r { + width: 588px; + height: 468px; + box-sizing: border-box; +} + +.floor_silder { + text-align: center; + position: relative; + margin-top: 35px; +} + +.floor_silder ul { + width: 195px; + height: 225px; + margin: 0 auto; + position: relative; +} + +.floor_silder .img_first { + z-index: 100; + width: 155px; + height: 225px; + left: 20px; + top: 0; + overflow: hidden; +} + +.floor_silder .img_second { + z-index: 90; + width: 175px; + height: 200px; + left: 10px; + top: 15px; + overflow: hidden; +} + +.floor_silder .img_third { + z-index: 80; + width: 195px; + height: 170px; + left: 0px; + top: 30px; + overflow: hidden; +} + +.floor_silder li { + position: absolute; + width: 195px; + height: 225px; + margin: 0 auto; + -moz-border-radius: 4px; + border-radius: 4px; + background-color: #fff; +} + +.floor_silder li a { + display: block; + height: 205px; + padding-top: 20px; +} + +.floor_silder .caption { + height: 20px; + overflow: hidden; + font-size: 16px; + line-height: 20px; +} + +.floor_silder .sub_tit { + height: 30px; + overflow: hidden; + font-size: 14px; + color: #666; + line-height: 30px; +} + +.floor_silder li img { + width: 130px; + height: 130px; + margin-top: 5px; +} + +img { + border: 0 none; + vertical-align: top; +} + +.floor_silder .color_mask { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 225px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.floor_silder .img_first .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=0); + opacity: 0; +} + +.floor_silder .img_second .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=40); + opacity: .4; +} + +.floor_silder .img_third .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=70); + opacity: .7; +} + +.floor_silder .turn_show { + position: absolute; + top: 234px; + left: 80px; + height: 30px; + line-height: 30px; + color: #f8f6f7; +} + +.floor_silder .prev_btn, +.floor_silder .next_btn { + float: left; + text-align: center; + font-size: 14px; + font-weight: bold; + cursor: pointer; +} + +.index_iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: .2px; + -moz-osx-font-smoothing: grayscale; +} + +.floor_silder .show_num { + float: left; + padding: 0 10px; + font-family: "Tahoma"; + font-size: 14px; +} + +.floor_silder .show_num span { + display: inline-block; + width: 3px; + height: 3px; + border: 1px solid #f78a4b; + background-color: #f78a4b; + border-radius: 50%; + margin-left: 2px; +} + +.fh2l { + width: 226px; + height: 428px; + box-sizing: border-box; + margin: 0 auto; + background: linear-gradient(30deg, #f9ab57 0%, #fab775 32%, #f78a4b 100%); +} + +.fh2l_tit { + font-size: 20px; + color: #fffefe; + text-align: center; + padding-top: 30px; +} + +.fh2l_line { + width: 142px; + height: 2px; + background-color: #fff; + margin: 10px auto; +} + +.fh2l_desc { + font-size: 16px; + color: #fffefe; + text-align: center; +} + +.floor_silder .show_num .curr { + border-color: #fff!important; + background-color: #fff!important; +} + + +/*不同楼层左侧商品轮播背景色*/ + +.fh2l .floor_silder .caption { + color: #f78b4b; +} + +.fh2l_2 .floor_silder .caption { + color: #58aaf7; +} + +.fh2l_2 { + background: linear-gradient(30deg, #56abf7 0%, #7ab9f8 32%, #4da5f7 100%); +} + +.fh2l_2 .floor_silder .img_first .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .img_second .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .img_third .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .show_num span { + border-color: #4da5f7; + background-color: #4da5f7; +} + +.fh2l_5 .floor_silder .caption { + color: #f35fa9; +} + +.fh2l_5 { + background: linear-gradient(30deg, #ffddef 0%, #fdafd7 32%, #ff88d1 100%); +} + +.fh2l_5 .floor_silder .img_first .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .img_second .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .img_third .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .show_num span { + border-color: #ff88d1; + background-color: #ff88d1; +} + +.fh2l_6 .floor_silder .caption { + color: #6562f8; +} + +.fh2l_6 { + background: linear-gradient(30deg, #bcb5fd 0%, #bcb5fd 32%, #9a91fc 100%); +} + +.fh2l_6 .floor_silder .img_first .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .img_second .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .img_third .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .show_num span { + border-color: #9a91fc; + background-color: #9a91fc; +} + +.fh2l_8 .floor_silder .caption { + color: #f56363; +} + +.fh2l_8 { + background: linear-gradient(30deg, #f55757 0%, #f87b7b 32%, #f74c4c 100%); +} + +.fh2l_8 .floor_silder .img_first .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .img_second .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .img_third .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .show_num span { + border-color: #f74c4c; + background-color: #f74c4c; +} + +.fh2l_9 .floor_silder .caption { + color: #f8b467; +} + +.fh2l_9 { + background: linear-gradient(30deg, #f5a657 0%, #f5bb79 32%, #f5a34b 100%); +} + +.fh2l_9 .floor_silder .img_first .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .img_second .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .img_third .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .show_num span { + border-color: #f5a34b; + background-color: #f5a34b; +} + +.fb2_gitem { + width: 50%; + height: 55%; + display: block; + box-sizing: border-box; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; + transition: all ease .4s; +} + +.fb2_gitem:hover { + transform: scale(1.01); + box-shadow: 0 0 5px #bdbcbc; + z-index: 22; + position: relative; +} + +.fb2_img { + width: 100%; + height: 75%; + box-sizing: border-box; + position: relative; +} + +.fb2_img img { + max-width: 100%; + max-height: 85%; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; +} + +/*mar lxy 20180409 惠宝折扣样式*/ +.lxy{ + color: #df2002; + text-align: center; +} + + +/* 猜你喜欢 */ + +.like_goods_list { + margin-top: 55px; + width: 1200px; + height: 600px; + box-sizing: border-box; +} + +.lg_glist { + width: 100%; + height: 90%; +} + +.lg_glist .fmr_gitem { + border: none; +} + +.lg_glist .fmr_gitem { + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} + +.lg_glist .fmr_gitem:nth-child(5n) { + border-right: none; +} + +.lg_glist .fmr_gitem:nth-child(n+6) { + border-bottom: none; +} + +.lg_tit { + margin-bottom: 20px; + height: 30px; + line-height: 30px; + width: 100%; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-position: center center; + text-align: center; + font-size: 18px; + color: #333; +} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/login.css b/hyhproject/home/view/default/css/login.css new file mode 100755 index 0000000..84d3762 --- /dev/null +++ b/hyhproject/home/view/default/css/login.css @@ -0,0 +1,84 @@ +@CHARSET "UTF-8"; +/*登录*/ +body{margin: 0; +padding: 0;} +.wst-login_l{width: 99.9%; height:525px; background: url(../img/img_user.png) no-repeat top center;} +.wst-login_l_shop{width: 99.9%; height:475px; background: url(../img/img_shop.png) no-repeat top center;} +.wst-login_r{margin-top:3%; margin-right: 4%; padding:30px 100px 20px 46px; float:right; border:1px solid #dad7d7; background: white;box-shadow: 0 0 30px 5px rgba(0,0,0,.4);} +.wst-login-u{margin: 0 auto; width:120px; height:36px; display: block; font-size: 25px; } +input.wst-login-input-1{margin: 1px;float: left; padding:2px; padding-left:5px; font-size: 15px; outline: none; width:269px; height:36px;border:0;} +input.wst-login-input{padding:0px; padding-left:5px; font-size: 15px; outline: none; width:300px; height:36px; border:1px solid #eee;} +input.wst-regist-input{margin: 1px;float: left; padding:2px; padding-left:5px; font-size: 15px; outline: none; width:269px; height:36px;border:1px solid #eee;} +.wst-login-input:focus,.wst-login-input-1:focus,.wst-regist-input:focus,.wst-login-codein-1:focus,.wst-login-codein:focus,.wst-regist-codein:focus,.wst-regist-codemo:focus{ border:1px solid #eb654a; } +.wst-table{margin-top:20px; color: #333;font: 12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif;} +.wst-login-tr{height:30px;} +.wst-login-code-1,.wst-regist-code{height:36px; } input.wst-login-codein-1,input.wst-regist-codein{padding:0px; padding-left:5px; width:150px; height:36px; position:absolute;left: 38px; font-size: 15px; outline: none; border:0; } +.wst-login-codeim-1{margin-left:148px; } +.wst-login-ch{border:1px solid #eb654a; } +.wst-login-but{display: block; position: relative; background:#E45050; color: #ffffff; text-align: center; font-family: 'Ubuntu', sans-serif; font-size: 15px; font-weight: bold; text-decoration: none; border-radius: 3px; overflow: hidden; -webkit-transition: all 0.15s ease-in; transition: all 0.15s ease-in; } +.wst-login-but:hover {background: #ea3232; } +.wst-login-but:before {content: ' '; position: absolute; background: #ffffff; width: 25px; height: 50px; top: 0; left: -45px; opacity: 0.3; -webkit-transition: all 0.25s ease-out; transition: all 0.25s ease-out; -webkit-transform: skewX(-25deg); transform: skewX(-25deg); } +.wst-login-but:hover:before {width: 45px; left: 205px; } +.wst-login-three{height: 30px; display: block; margin-top: 15px; } /*注册*/ .wst-regist{padding:100px 20px 60px 20px; } +.wst-regist-b{background:url(../img/img_regist.png) no-repeat; background-size: cover; margin-top:3px; border-top: 2px solid #eee;border-bottom: 2px solid #eee;} +.wst-regist-c{width: 760px; margin: 0 auto; padding:20px; border-radius:5px; } +.wst-regist-head{font-size:28px; font-family:"楷体"; color:#E45050; text-align:center; } input.wst-regist-input{width:400px; margin-left:20px; } +.wst-regist-td{text-align:right; width: 150px; font-size: 15px; color:#626262; } +.wst-regist-code-1{margin-left:20px; } input.wst-regist-codein{width:150px;} +.wst-regist-codeim{margin-left:288px; } input.wst-regist-codemo{padding:0px; margin-left: 20px; padding-left:5px; font-size: 15px; outline: none; width:260px; height:36px; border:1px solid #eee; } +.wst-regist-obtain{width:134px; background:#f0efef; border-radius: 3px; border: 1px solid #eee; padding:10px 0px; cursor:pointer; color: #110f0f; border:1px solid #eee;} +.wst-regist-but{outline: none; background:#e45050; color: #ffffff; border: 1px solid #ea3232; border-radius:3px; cursor:pointer; } +.wst-regist-but:hover{background: #ea3232; } +.wst-regist-but:not(.disabled):not(:disabled):active, .wst-regist-but.active{background: #ea3232; background-clip: padding-box; } /*找回密码*/ .stepflex{float:right; border-top: 5px solid #ccc; text-align: center; width: 640px; margin: 60px 0px 0px 50px; } +.stepflex dl{border-top: 5px solid #ccc; float: left; position: relative; top: -5px; width: 160px; } dl.doing{border-top-color: #04bd3d; } +.doing .s-num{background-position: -23px 0; } +.s-num,.s-num1{color: #fff; font-weight: 700; height: 23px; line-height: 23px; margin: -15px auto 0; position: relative; width: 23px; border-radius:25px; } +.s-num{background: #04bd3d; } +.s-num1{background: #ccc; } +.s-text{line-height:30px; } +.forget-pwd{width: 750px; margin:50px auto 50px; padding:25px 0px 48px 0px; border:1px solid #bac4c3; border-radius:6px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } input.wst-forget-input{padding: 0px; margin-left:20px; padding-left:5px; font-size: 15px; outline: none; width:300px; height:36px; border-radius:3px; border:1px solid #bac4c3; } +.wst-forget-code,.wst-forget-code2{float:left; width:300px; height:36px; border-radius:3px; margin-left:20px; border:1px solid #bac4c3; } input.wst-forget-codein,input.wst-forget-codein2{padding: 0px; padding-left:5px; width:180px; height:36px; position:absolute; font-size: 15px; outline: none; border:0; border-radius:6px; } +.wst-forget-input:focus,.wst-forget-codein:focus,.wst-forget-codein2:focus{border-radius:3px; border:1px solid #eb654a; } +.wst-forget-codeim,.wst-forget-codeim2{width:116px; border-top-right-radius:6px; border-bottom-right-radius:6px; margin-left:183px; } +.wst-forget-code2{width:230px; } input.wst-forget-codein2{width:120px; } +.wst-forget-codeim2{width:112px; margin-left:118px; } +.email-verify{display:none; } +.wst-forget-td{text-align:right; width: 260px; font-size: 15px; color:#626262; } +.wst-forget-te{margin-left:20px; font-size: 15px; } +.wst-forget-select{margin-left:20px; font-size: 15px; outline: none; width:230px; height:36px; border-radius:3px; border:1px solid #bac4c3; } +.wst-forget-obtain{width:134px; height: 36px; background:#f0efef; border-radius: 3px; border: 1px solid #d3c8c7; padding:10px 0px; cursor:pointer; color: #110f0f; } +.wst-forget-c{text-align:center; } +.wst-forget-ct{font-size: 16px; color:#2d2727; } +.wst-icon-banner{width: 1200px;margin:0 auto;} +.wst-icon{width: 120px;height: 30px; display: inline-block;float: right;} +.wst-icon li{float:left;} +.wst-icon .wst-remind{color:red;font-size: 12px;padding-left: 10px;height: 30px;line-height: 30px;} +.wst-img-icon{width: 23px;height: 23px; background: url(../img/icon_login02.png) no-repeat;background-size: contain;margin-top: 3px;} +.wst-login-banner{width: 99.9%;height: 160px; } +.wst-login-banner .img-banner{height:130px; margin: 10px 10px 10px 120px; float: left;} +.wst-login-banner .img-banner img{height: 100%;} +.wst-login-banner .wst-stript{width: 2px;height: 110px;margin-top: 25px;margin-left: 20px; background: #eee;float: left;} +.wst-login-banner .wst-login-action{width:630px;height: 130px; float: right; margin: 10px 10px 10px 10px;} +.wst-login-action .wst-left{width: 200px;height: 130px; float: left;text-align: center;line-height: 130px;font-family:微软雅黑;font-weight: bold;font-size: 25px;} +.wst-login-action .wst-right-action{width: 200px;height: 130px;float: right;} +.wst-login-action .action-box{padding-top: 50px; line-height: 27px;} +.action-box .wst-location{width: 100px;height: 25px;float: right;line-height: 25px;font-size: 12px;margin-right: 40px;} +.wst-login-middle{height: 527px; background: rgba(255,76,76,0.78);} +.wst-login-middle-shop{height: 477px; background: rgb(86,169,253);} +.wst-color{background: white;} +.wst-login-banner-regist{width: 99.9%;height: 100px; } +.wst-login-banner-regist .img-banner{height:90px; margin: 10px 10px 10px 100px; float: left;} +.wst-login-banner-regist .img-banner img{height: 100%;} +.wst-login-banner-regist .wst-login-action{width:400px;height: 80px; float: right; margin: 10px 10px 10px 10px;} +.wst-item{position: relative;margin-bottom: 20px;} +.wst-item-box{border: 1px solid #eee;height: 38px;width: 310px;} +.wst-item-box .login-img{ position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px; margin-left: 4px;margin-right: 2px; border-right: 1px solid #eee;background: url(../img/icon_name.png) 1px no-repeat;background-size: 85%;float: left;} +.password-img{position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px;margin-left: 4px; margin-right: 2px; border-right: 1px solid #eee;float: left;background: url(../img/icon_passard.png) 1px no-repeat;background-size: 85%;} +.yanzheng-img{position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px; margin-left: 4px;margin-right: 2px; border-right: 1px solid #eee;float: left;background: url(../img/icon_yanzhengma.png) 1px no-repeat;background-size: 85%;} +.bottom-stript{width: 100%;height: 20px;border:1px solid red;} +.regist-border{border:1px solid #eee;} + + +.wst-login-code,.wst-regist-code{height:36px; border:1px solid #eee; } + .wst-login-codeim{margin-left:188px; } + input.wst-login-codein{padding:0px; padding-left:5px; width:180px; height:36px; position:absolute; font-size: 15px; outline: none;border:0; } \ No newline at end of file diff --git a/hyhproject/home/view/default/css/recharge.css b/hyhproject/home/view/default/css/recharge.css new file mode 100755 index 0000000..3fef8a7 --- /dev/null +++ b/hyhproject/home/view/default/css/recharge.css @@ -0,0 +1,49 @@ + +/**支付方式**/ +.pay-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.pay-boxs{padding:10px 0px 5px 5px;} +.pay-box ul{padding-left:15px;} +.pay-box ul li{width:1185px;} +.pay-box .label{width:200px;float:left;height:30px;line-height:30px;} +.pay-box .txt{height:auto;line-height:30px;width:985px;float:left;color:#999999;} +.pay-sbox{padding:5px 0px;} +.pay-sbox-head{border-bottom: 2px solid #ddd;line-height:35px;} +.pay-tip1{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -10px;background-size: cover; } +.pay-tip2{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -71px;background-size: cover; } +.pay-tip3{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -132px;background-size: cover; } +.pay-sbox .qrcode-box{min-height: 300px;height: auto;} +.pay-sbox .tips-box{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .qrcode-box .pbox{text-align: center;margin-top: 10px;font-weight: bold;} +.pay-sbox .wst-qrcode{width:260px;height:260px;text-align:center;margin:0 auto;} +.pay-sbox .wst-qrcode img{width:260px;height:260px;} +.pay-sbox .bnt-box{line-height:35px;text-align:center;font-weight: bold;padding:5px 10px;line-height:50px;} +.pay-sbox .pay-type{text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .pay-list{text-align: left;font-weight: bold;padding:5px 20px;} +.pay-sbox .succ-box{text-align: center;padding: 50px;} +.wst-payCode-weixinpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-weixinpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.pay-sbox .wst-pay-bnt {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px 0px;cursor:pointer;} +.pay-sbox .wst-pay-bnt:hover {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px -57px;cursor:pointer;} +.charge-money{font-size:18px;} +.charge-alone{line-height:50px; } +.charge-doub{padding-top: 8px;} +.charge-othermoney{width:80px;} +.j-charge-money{display: none;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{float: left;width:180px;margin: 2px 8px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame2{min-height:50px;float: left;min-width:120px;margin: 2px 20px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;padding:6px;} +.wst-form input.charge-othermoney{padding: 8px;} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/right_cart.css b/hyhproject/home/view/default/css/right_cart.css new file mode 100755 index 0000000..b95adae --- /dev/null +++ b/hyhproject/home/view/default/css/right_cart.css @@ -0,0 +1,78 @@ +@CHARSET "UTF-8";.j-global-toolbar div a{margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.toolbar-wrap{position:fixed;top:0;right:0;z-index:9990;width:35px;height:100%} +.toolbar-wrap a{text-decoration:none} +.toolbar{position:absolute;right:0;top:0;width:29px;height:100%;border-right:6px solid #333} +.toolbar-panels{position:absolute;left:35px;top:0;width:270px;height:100%;z-index:2;background:#eceaea none repeat scroll 0 0} +.toolbar-panel{width:270px;height:100%;position:absolute;background:#eceaea none repeat scroll 0 0} +.tbar-panel-header{position:relative;width:270px;height:40px;line-height:40px;background:#eceaea none repeat scroll 0 0;font-family:"microsoft yahei";font-weight:normal;margin:0;padding:0} +.tbar-panel-header .title{display:inline-block;height:40px;color:#5e5050;font:16px/40px "微软雅黑"} +.tbar-panel-cart .tbar-panel-header i{width:20px;height:18px;background-position:0 0;margin-top:11px} +.tbar-panel-header i{margin-right:4px;margin-left:10px;vertical-align:top} +.tbar-panel-header i,.tbar-panel-header .close-panel{display:inline-block;font-style:normal;background-image:url("../img/right_cart.png");background-repeat:no-repeat} +.tbar-panel-header .title em{display:inline-block;vertical-align:top} +.tbar-panel-header .close-panel{width:12px;height:12px;background-position:0 -250px;position:absolute;right:8px;top:16px;cursor:pointer;transition:transform .2s ease-out 0s} +.tbar-panel-main{position:relative;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-tipbox{display:block} +.tbar-panel-content{width:270px;overflow-y:auto;overflow-x:hidden;position:relative} +.tbar-tipbox .tip-inner{padding:6px 5px;border:1px solid #edd28b;background:#fffdee none repeat scroll 0 0;text-align:center} +.tbar-tipbox .tip-text{display:inline-block;line-height:20px;vertical-align:middle;color:#333} +.tbar-tipbox .tip-btn{display:inline-block;height:20px;line-height:20px;padding:0 5px;margin-left:5px;color:#FFF;vertical-align:middle;background:#c81623 none repeat scroll 0 0} +.tbar-panel-cart .tbar-panel-footer{height:50px;background-color:#eceaea;margin:0;padding:0} +.tbar-checkout{height:40px;padding:5px 110px 5px 5px;position:relative} +.tbar-checkout .jtc-number strong{font-family:verdana;color:#c81623} +.tbar-checkout .jtc-number{line-height:20px;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-checkout .jtc-sum{line-height:20px;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-checkout .jtc-sum strong{font-family:verdana;color:#c81623} +.tbar-checkout .jtc-btn{position:absolute;right:5px;top:7px;width:110px;height:35px;font:16px/35px "微软雅黑";text-align:center;background:#c81623 none repeat scroll 0 0;color:#FFF} +.tbar-cart-list{width:100%;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-cart-item{padding:0 5px;margin-bottom:10px;background:#FFF none repeat scroll 0 0} +.jtc-item-promo{padding:12px 0 12px 0;border-bottom:1px dashed #e1e1e1} +.jtc-item-promo .promo-tag{position:relative;float:left;width:40px;height:20px;margin-top:-1px;margin-left:-57px;margin-right:17px;text-align:center;font:12px/20px "宋体";color:#FFF;background-color:#f58813} +.jtc-item-promo .promo-text{height:18px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font:12px/18px verdana} +.jtc-item-goods{padding:10px 0;position:relative;overflow:hidden} +.jtc-item-goods .p-img{float:left;width:60px;height:60px;border:1px solid #DDD;padding:0;margin-right:5px} +.jtc-item-goods .p-img img{width:60px;height:60px} +.jtc-item-goods .p-name{height:32px;line-height:16px;margin-bottom:4px;overflow:hidden} +.jtc-item-goods .p-name a{color:#333} +.jtc-item-goods .p-price{height:25px;overflow:hidden;font:12px/16px verdana;color:#666;width:170px} +.jtc-item-goods .p-price strong{color:#c81623;font-weight:normal;float:left} +.jtc-item-goods .p-del{position:absolute;right:10px;top:46px;width:35px;height:16px;line-height:16px;color:#005aa0;text-align:right;display:none} +.tbar-panel-history div{padding:0} +.jt-history-wrap{width:235px;margin:0 auto} +.tbar-panel-history ul{overflow:hidden;margin-right:-15px;margin-top:0;list-style:outside none none;padding:0} +.tbar-panel-history .tbar-panel-header i{width:20px;height:17px;margin-top:11px;background-position:0 -100px} +.tbar-panel-follow .tbar-panel-header i{width:20px;height:17px;margin-top:11px;background-position:0 -50px} +.tbar-panel-history .jth-item{float:left;position:relative;width:100px;height:120px;margin-right:15px;background:#FFF none repeat scroll 0 0;margin-bottom:15px;padding:5px} +.tbar-panel-history .jth-item .img-wrap{display:block;width:100px;height:100px;text-align:center;margin-bottom:5px} +.tbar-panel-history .jth-item .add-cart-button{height:20px;line-height:20px;overflow:hidden;text-align:center;text-decoration:none;display:none;position:absolute;width:100px;bottom:25px;left:5px;z-index:3;color:#FFF;background:rgba(28,25,28,0.8) none repeat scroll 0 0} +.tbar-panel-history .jth-item .price{color:#c81623} +.tbar-panel-history .history-bottom-more{display:block;text-align:center;height:40px;line-height:40px;font-family:"宋体";color:#666} +.toolbar-header{position:absolute;top:0;right:-6px} +.toolbar-tabs{position:absolute;top:50%;left:0;width:35px;margin-top:-61px} +.toolbar-tab{position:relative;width:35px;height:35px;margin-bottom:1px;cursor:pointer;background-color:#333;border-radius:3px 0 0 3px;font:12px/150% Arial,Verdana,"宋体";color:#666;display:inline-block;background-image:url("../img/right_cart.png");background-repeat:no-repeat} +.tbar-tab-cart{background-position:-50px 0} +.tbar-tab-follow{background-position:-50px -50px} +.tbar-tab-history{background-position:-50px -100px} +.tbar-tab-message{background-position:-50px -144px} +.tab-ico{width:34px;height:35px;margin-left:1px;position:relative;z-index:2;background-color:#7a6e6e} +.tab-text{width:62px;height:35px;line-height:35px;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;left:35px;top:0;background-color:#333;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;padding:0;cursor:pointer} +.tab-sub{position:absolute;z-index:3;right:2px;top:-5px;height:11px;padding:1px 2px;border:1px solid #b61d1d;overflow:hidden;color:#FFF;font:11px/11px verdana;text-align:center;min-width:11px;border-radius:10px;background-color:#cc6060;background-image:linear-gradient(to bottom,#cc6060 0,#b61d1d 100%)} +.toolbar-footer{position:absolute;bottom:-1px;width:100%;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-tab-top{background-position:-50px -250px} +.tbar-tab-feedback{background-position:-50px -300px} +.footer-tab-text{width:50px;height:35px;line-height:35px;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;left:35px;top:0;background-color:#7a6e6e;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;padding:0;cursor:pointer} +.tbar-tab-hover{left:-60px;background-color:#c81623} +.tbar-tab-footer-hover{left:-48px;background-color:#c81623} +.tbar-tab-selected{background-color:#c81623} +.tbar-tab-selected .tab-sub{color:#c81623;background-color:#FFF;background-image:linear-gradient(to bottom,#FFF 0,#FFF 100%);box-shadow:1px 1px 3px rgba(0,0,0,0.3);text-shadow:1px 0 1px rgba(0,0,0,0.3)} +.tbar-tab-click-selected{background-color:#c81623} +.tbar-tab-click-selected .tab-sub{color:#c81623;background-color:#FFF;background-image:linear-gradient(to bottom,#FFF 0,#FFF 100%);box-shadow:1px 1px 3px rgba(0,0,0,0.3);text-shadow:1px 0 1px rgba(0,0,0,0.3)} +.survey-tab-ico{display:none} +.survey-tab-text{left:0;width:35px;height:30px;padding:2px 0 3px;line-height:15px;background:#c81623 none repeat scroll 0 0;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;top:0;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;cursor:pointer} +.toolbar-open{right:270px} +.j-close:hover{transform:rotate(180deg);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg)} +.tbar-panel-history .jth-item .add-cart-button:hover{background:#c81623 none repeat scroll 0 0} +.tbar-cart-item .buy-btn{background:#eee none repeat scroll 0 0;border:1px solid #ddd;color:#666;cursor:pointer;display:block;float:left;height:20px;line-height:20px;padding:0 5px} +input.right-cart-buy-num[type="text"]{border-color:#ddd -moz-use-text-color;border-style:solid none;border-width:1px 0;float:left;height:16px;text-align:center;width:40px} +.goods-remove{background:rgba(0,0,0,0) url("../img/right_cart.png") no-repeat 0 -290px;cursor:pointer;height:20px;overflow:hidden;padding:5px;position:absolute;right:-8px;top:4px;width:20px} +.right-carts-empty{margin-left:40px;margin-top:20px} diff --git a/hyhproject/home/view/default/css/security.css b/hyhproject/home/view/default/css/security.css new file mode 100755 index 0000000..9eb703e --- /dev/null +++ b/hyhproject/home/view/default/css/security.css @@ -0,0 +1,32 @@ +@CHARSET "UTF-8"; a{cursor:pointer; } +.wst-sec-info{padding:20px 0px 20px 30px; background: #fed1b0; } +.wst-sec-infor{float: left; margin-left:20px; } +.wst-sec-na{font-size:20px; color:#f06f69; line-height:20px; } +.wst-sec-grade img{width: 20px; margin-top:1px; margin-left:20px; } +.wst-sec-grade span{margin-left:8px; line-height:20px; font-family:"microsoft yahei"; } +.wst-sec-infoi{float: left; width: 100%; color:#3c3228; font-family:"microsoft yahei"; } +.wst-sec-infoin{color:#0cd8d5; } +.wst-sec-s{padding:30px 20px; font-family:"microsoft yahei"; } +.wst-sec-lists{float: left; width: 100%; min-height: 60px; line-height:60px; } +.wst-sec-green{color:#11cc71; } +.wst-sec-ash{color:#f1730f; } +.wst-sec-green img,.wst-sec-ash img{float: left; margin-top:24px; margin-right:3px; } +.wst-sec-w{color:#363636; font-size:17px; } +.wst-sec-strip{width: 300px; height: 20px; background: #d7cece; } +.wst-sec-strip2{width: 100px; height: 20px; background: #53e053; } /**/ .wst-sec-head2{margin-top:20px; padding: 28px; height: 30px; } +.wst-sec-min{width: 30%; text-align: center; height:26px; line-height:26px; background: #e0e0e0; color:#282828; font-size:15px; font-family:"microsoft yahei"; } +.wst-sec-mi{width: 13px; } +.wst-sec-min1{width: 0; height: 0; border-top: 13px solid transparent; border-left: 13px solid #e0e0e0; border-bottom: 13px solid transparent; } +.wst-sec-min2{width: 0; height: 0; border-top: 13px solid #e0e0e0; border-left: 13px solid transparent; } +.wst-sec-min3{width: 0; height: 0; border-bottom: 13px solid #e0e0e0; border-left: 13px solid transparent; } +.wst-sec-gr{color:#ffffff; background: #45d862; } +.wst-sec-gr1{border-left: 13px solid #45d862; } +.wst-sec-gr2{border-top: 13px solid #45d862; } +.wst-sec-gr3{border-bottom: 13px solid #45d862; } /*密码*/ .wst-form{float: left; margin-top:20px; margin-left:20px; } /*邮箱*/ .wst-sec-img{float: left; margin-top:3px; } +.wst-sec-prompt{margin-top:36px; margin-left:30px; } +.wst-sec-p1{margin-top:20px; font-size:15px; } +.wst-sec-p2{margin-top:20px; } +.wst-sec-su{margin: 0 auto; width: 260px; height: 120px; } +.wst-sec-sut,.wst-sec-sub{float: left; width: 100%; text-align:center; } +.wst-sec-sut{margin-top:60px; } +.wst-sec-sub{color: #11cd6e; font-size:18px; font-family:"microsoft yahei"; margin-top:6px; } /*手机*/ .wst-sec-obtain{width:130px; background:#f0efef; border-radius: 3px; border: 1px solid #d3c8c7; padding:8px 0px; cursor:pointer; color: #110f0f; } \ No newline at end of file diff --git a/hyhproject/home/view/default/css/self_shop.css b/hyhproject/home/view/default/css/self_shop.css new file mode 100755 index 0000000..53e3834 --- /dev/null +++ b/hyhproject/home/view/default/css/self_shop.css @@ -0,0 +1,184 @@ +.wst-shop-h{padding:10px 0} +.wst-shop-img{float:left;margin-top:3px;width:90px;height:90px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-img img{max-width:90px;max-height:90px;border-radius:5px} +.wst-shop-info{float:left;width:45%;margin-left:10px} +.wst-shop-info p{float:left;line-height:50px;width:100%;color:#222;font-size:17px;font-family:"microsoft yahei"} +.wst-shop-info2,.wst-shop-info3{float:left;width:100%} +.wst-shop-info2 img{float:left;width:16px;margin-right:3px} +.wst-shop-info2 span{float:left;color:#dda315;margin-right:10px} +.wst-shop-info3{margin-top:7px} +.wst-shop-code{float:left;margin-top:-3px;width:24px;height:24px;cursor:pointer;background:url(../img/img_sjck.png) no-repeat;background-size:100%} +.wst-shop-codes{width:131px;height:131px;margin-top:24px;border:1px solid #dedbdb;position:absolute;z-index:1000;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);border-radius:5px} +.wst-shop-codes:after{top:-16px;border-color:transparent transparent #fff} +.wst-shop-eva,.wst-shop-evaa{float:left;margin-right:16px} +.wst-shop-evaa{padding-left:20px} +.wst-shop-info3 .j-fav,.wst-shop-info3 .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 1px 2px no-repeat} +.wst-shop-info3 .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 0 -23px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shop-info3 .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 0 1px no-repeat;text-decoration:none} +.wst-shop-red{color:#e25041} +.wst-shop-tu{text-align:center;width:100%;height:110px} +@media screen and (max-width:1200px){.wst-shop-tu{min-width:1200px} +.s-wst-nav-menus{min-width:1200px}} +.homepage{margin-top:6px;padding:0 8px;height:22px;line-height:22px;color:#fff;border:1px solid #fff;font-size:13px!important} +.homepage:hover{color:#fc6047;background:#fff;border:1px solid #fc6047} +.s-wst-nav-menus{background:#ff6a53;width:100%;margin:0 auto;height:38px}#s-wst-nav-items ul{width:1200px;margin:0 auto} +.s-nav-li a{color:#fff;font:400 15px/36px "microsoft yahei";height:36px;padding:0 15px;text-align:center;text-decoration:none} +.s-nav-li{float:left;padding:0 16px;height:38;line-height:36px} +.s-cat-head>a{color:#fff;font:400 15px/36px "microsoft yahei"} +.s-cat-head-hover{background:#df2003} +.s-cat-head{display:block;height:38px;padding:0 10px;text-decoration:none;width:190px} +.wst-shop-sea{float:right;width:42.999999%;margin-top:20px} +.wst-shop-sea input{float:left;outline:0;font-size:15px;height:28px;width:360px;margin-right:3px;padding-left:8px;border:1px solid #fc6047} +.wst-shop-sea .search{float:left;width:60px;height:34px;line-height:32px;text-align:center;color:#fff;margin-left:6px;background:url(../img/img_bg_search.png) no-repeat} +.wst-shop-word{float:left;margin-top:8px;width:100%;height:18px;overflow:hidden} +.s-cat-head em{margin-top:10px;margin-right:-10px;display:block;width:16px;height:16px;float:left;background:url(../img/icon_class_zydp.png) no-repeat} +.shop-ct1-ct2{width:200px;height:15px;overflow:hidden;padding:5px 0;border-bottom:1px solid #e7e7e7} +.ct1-hover{background:#ff6a53;color:#fff} +.ct1-hover h3 a{color:white} +.ct1-hover .shop-ct1-ct2{border-bottom:0} +.ct1-hover .shop-ct1-ct2 a{color:white} +.shop-cat2{display:none} +.shop-cat1 h3{float:left;margin-left:3px;margin-top:2px} +.shop-cat1-title{width:220px;height:26px;margin-top:15px} +.shop-cat1{position:relative} +.shop-cat1{width:190px;height:66.3px;float:left;padding:0 10px} +.em1,.em2,.em3,.em4,.em5,.em6{float:left;display:block;width:18px;height:18px;background:url(../img/sprite@1x.png) no-repeat} +.em1{background-position:-38px -106px} +.em2{background-position:0 -105px} +.em3{background-position:0 -144px} +.em4{background-position:-75px -106px} +.em5{background-position:-106px -38px} +.em6{background-position:-143px -38px} +.shop-cat2{width:500px;max-height:400px;float:right;overflow:hidden;position:absolute;left:210px;top:0;z-index:998;background:#f0f0f0;border:2px solid #ff6a53} +.shop-cat2 li{float:left;padding:5px 16px;width:84px} +.shop-cat2 li a:hover{color:#df2003} +.s-cat{z-index:998;display:none;position:absolute;width:210px;height:400px;background:#fff} +.history-box{width:1200px;height:360px;margin:0 auto;margin-top:20px} +.history-title{width:100%;background:#ddd;height:30px;margin-bottom:10px} +.history-title p{float:left;line-height:30px;text-indent:10px} +.history-goods-list{width:1200px;height:320px} +.history-goods-list .s-goods{width:233px;margin:0 -1px 5px 5px;border:1px solid #e5e5e5;float:left} +.history-goods-list .s-goods-h:hover{border:1px solid #df2003;-webkit-box-shadow:0 0 10px #df2003;-moz-box-shadow:0 0 10px #df2003;box-shadow:0 0 10px #df2003} +.history-goods-list .s-goods .img{width:233px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;padding:4px} +.history-goods-list .s-goods .img a{display:table-cell;vertical-align:middle;width:233px;height:233px} +.history-goods-list .s-goods .img a img{max-width:210px;max-height:210px} +.history-goods-list .s-goods .p-price{padding:5px 0 5px 10px;font-weight:bold;color:#df2003;width:115px;float:left} +.history-goods-list .s-goods .p-hsale{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.history-goods-list .s-goods .p-market{padding:5px 0 5px 10px;font-weight:bold;color:gray;width:95px;float:left} +.history-goods-list .s-goods .p-appraise{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.history-goods-list .s-goods .p-hsale span{font-weight:bold;color:#df2003} +.history-goods-list .s-goods .p-market span{font-weight:bold;color:gray} +.shop_rec_out{width: 100%; margin: 0 auto; } +.s-buy-new-best-hot{width:100%;height:335px;margin-top:30px} +.s-rec{width: 1200px; margin: 0 auto; overflow: hidden; background-image: url(../img/self_shop_rec_bg.png); background-repeat: no-repeat; padding-left: 45px; background-position: 0 13px; } +.s-rec li{height: 35px; line-height: 35px; float: left; border-bottom: 1px solid #ff6a53; } +.s-rec li a{display: block; font-size:21px; font-weight: bold; color: #333; float:left; text-align:center } +.j-s-rec-selected a{color:#df2003!important;} +.s-rec-glistbox{width: 100%; background:-webkit-linear-gradient(right,#ffe9dc, #ffb3ab 40%, #ffe9dc); background:-o-linear-gradient(right,#ffe9dc, #ffb3ab 40%, #ffe9dc); background:linear-gradient(to left,#ffe9dc, #ffb3ab 40%, #ffe9dc); } +.s-rec-goods-list{width: 1200px; overflow: hidden; margin: 0 auto; height: 250px; padding: 10px 0; box-sizing: border-box; } +.s-rec-goods-list li{background-color: #fff; float: left; margin-left: 10px; width: 290px; height: 100%; box-sizing: border-box; position: relative; } +.s-rec-goods-list li:hover .rec_ginfo{opacity: 1; visibility: visible; } +.rec_ginfo{transition:all ease .4s; visibility: hidden; opacity: 0; width: 100%; height: 100%; box-sizing: border-box; position: absolute; z-index: 55; top: 0; background-color: rgba(0,0,0,0.5); } +.s-rec-goods-list li a{display:block; width:100%; height:100%; box-sizing: border-box; position: relative; } +.s1-rec-goods-list li:hover{border:1px solid #ff6a53;-webkit-box-shadow:0 0 10px #ff6a53;-moz-box-shadow:0 0 10px #ff6a53;box-shadow:0 0 10px #ff6a53} +.s-rec-goods-list img{position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; max-width: 100%; max-height: 100%; } +.s-rec-goods-price{margin-top:5px;text-align: center;} +.s-rec-goods-price>span{font-weight:bold;font-size:21px;color:#df2003} +.s-rec-goods-bottom{width:100%;overflow:hidden;box-sizing: border-box;padding: 0 60px;} +.s-rec-goods-bottom>a{line-height:20px; display:block; border:1px solid #fff; margin-top: 20px; width:80px; height:20px; text-align:center; color:#fff; border-radius:2px; } +.s-rec-goods-bottom>a:hover{background:#ff6a53;color:white;border:1px solid #ff6a53} +.s-rec-goods-desc{width: 100%; height: 41px; line-height: 38px; overflow: hidden; text-align: center; margin-top: 60px; } +.s-rec-goods-desc a{color:#fff;font-size: 20px;} +.s-floor-box{height:685px;width:100%;margin-top:15px} +.s-floor-header{width:1195px;height:36px;background:white} +.c1{border-bottom:1px solid #dc4bd1;border-left:5px solid #dc4bd1} +.c2{border-bottom:1px solid #8a5063;border-left:5px solid #8a5063} +.c3{border-bottom:1px solid #df2003;border-left:5px solid #df2003} +.c4{border-bottom:1px solid lightblue;border-left:5px solid lightblue} +.c5{border-bottom:1px solid #ff8043;border-left:5px solid #ff8043} +.c6{border-bottom:1px solid #24b0ed;border-left:5px solid #24b0ed} +.s-floor-header-f1,.s-floor-header-f2,.s-floor-header-f3,.s-floor-header-f4,.s-floor-header-f5,.s-floor-header-f6{float:left;height:100%;width:20%;margin-top:1px} +.s-floor-header .tab{float:right} +.s-floor-header .tab li{display:block;margin:0;float:left} +.s-floor-header .tab a{font-size:15px;display:block;height:15px;letter-spacing:1px} +.s-floor-header .tab-item1 a{color:gray;border:1px solid #e6e6e6;border-bottom:#dc4bd1;padding:10px} +.s-floor-header .j-tab-selected1 a{background:white;border-left:1px solid #dc4bd1;border-right:1px solid #dc4bd1;border-top:1px solid #dc4bd1;color:#dc4bd1;border-bottom:1px solid white} +.s-floor-header .tab-item2 a{color:gray;border:1px solid #e6e6e6;border-bottom:#8a5063;padding:10px} +.s-floor-header .j-tab-selected2 a{background:white;border-left:1px solid #8a5063;border-right:1px solid #8a5063;border-top:1px solid #8a5063;color:#8a5063;border-bottom:1px solid white} +.s-floor-header .tab-item3 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected3 a{background:white;border-left:1px solid #df2003;border-right:1px solid #df2003;border-top:1px solid #df2003;color:#df2003;border-bottom:1px solid white} +.s-floor-header .tab-item4 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected4 a{background:white;border-left:1px solid lightblue;border-right:1px solid lightblue;border-top:1px solid lightblue;color:lightblue;border-bottom:1px solid white} +.s-floor-header .tab-item5 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected5 a{background:white;border-left:1px solid #df2003;border-right:1px solid #df2003;border-top:1px solid #df2003;color:#df2003;border-bottom:1px solid white} +.s-floor-header .tab-item6 a{color:gray;border:1px solid #e6e6e6;border-bottom:#24b0ed;padding:10px} +.s-floor-header .j-tab-selected6 a{background:white;border-left:1px solid #24b0ed;border-right:1px solid #24b0ed;border-top:1px solid #24b0ed;color:#24b0ed;border-bottom:1px solid white} +.s-floor-right-title a{line-height:36px;font-size:16px;font-weight:bold;letter-spacing:2px} +.s-floor-right-title{height:36px;margin-right:70px;margin-left:5px} +.more{font-weight:bold} +.s-goods-list{width:1200px;border-left:1px solid #e5e5e5;height:634px} +.s-goods-list .s-goods{width:237px;height:316px;border-bottom:1px solid #e5e5e5;border-right:1px solid #e5e5e5;float:left} +.s-goods-list .s-goods-f1:hover{width:236px;height:316px;border-bottom:1px solid #dc4bd1;border-right:1px solid #dc4bd1;border-left:1px solid #dc4bd1;-webkit-box-shadow:0 0 10px #dc4bd1;-moz-box-shadow:0 0 10px #dc4bd1;box-shadow:0 0 10px #dc4bd1} +.s-goods-list .s-goods-f2:hover{width:236px;height:315px;border-bottom:1px solid #8a5063;border-right:1px solid #8a5063;border-left:1px solid #8a5063;-webkit-box-shadow:0 0 10px #8a5063;-moz-box-shadow:0 0 10px #8a5063;box-shadow:0 0 10px #8a5063} +.s-goods-list .s-goods-f3:hover{width:236px;height:315px;border-bottom:1px solid #df2003;border-right:1px solid #df2003;border-left:1px solid #df2003;-webkit-box-shadow:0 0 10px #df2003;-moz-box-shadow:0 0 10px #df2003;box-shadow:0 0 10px #df2003} +.s-goods-list .s-goods-f4:hover{width:236px;height:315px;border-bottom:1px solid lightblue;border-right:1px solid lightblue;border-left:1px solid lightblue;-webkit-box-shadow:0 0 10px lightblue;-moz-box-shadow:0 0 10px lightblue;box-shadow:0 0 10px lightblue} +.s-goods-list .s-goods-f5:hover{width:236px;height:315px;border-bottom:1px solid #ff8043;border-right:1px solid #ff8043;border-left:1px solid #ff8043;-webkit-box-shadow:0 0 10px #ff8043;-moz-box-shadow:0 0 10px #ff8043;box-shadow:0 0 10px #ff8043} +.s-goods-list .s-goods .img{width:232px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;padding:4px} +.s-goods-list .s-goods .img a{display:table-cell;vertical-align:middle;width:232px;height:232px} +.s-goods-list .s-goods .img a img{max-width:210px;max-height:210px} +.img{position:relative} +.img span{width:236px;height:30px;line-height:30px;color:#fff;opacity:.6;background:#d0260c;display:block;position:absolute;left:0;bottom:0;display:none} +.img span:hover{cursor:pointer;background:#e5280b} +.s-goods-list .s-goods .p-price{padding:5px 0 5px 10px;font-weight:bold;color:#df2003;width:115px;float:left} +.s-goods-list .s-goods .p-hsale{padding:5px 10px 5px 0;width:90px;float:right;text-align:right} +.s-goods-list .s-goods .p-market{padding:5px 0 5px 10px;font-weight:bold;color:gray;width:95px;float:left} +.s-goods-list .s-goods .p-appraise{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.s-goods-list .s-goods .p-hsale span{font-weight:bold;color:#df2003} +.s-goods-list .s-goods .p-market span{font-weight:bold;color:gray} +.p-name{margin-left:10px;width:210px} +.more{height:35px} +.more a{line-height:35px;text-align:center;background:#fff;margin-left:10px} +.s-banner{width:100%;height:500px;margin:0 auto} +#s-wst-slide .s-wst-slide-items li{height:500px;overflow:hidden} +.wst-shop-info2 img.wangwang{padding-top:1px;width:65px;height:22px} +.wst-shop-share{float:right;position:relative;top:-6px} +.notice{display:flex;align-items:center} +.notice_img{vertical-align:text-top;width:15px;height:15px} +.f15{font-size:15px} +.pdl10{padding-left:10px} + +.self_container_out{width: 100%; box-sizing:border-box;padding-top: 10px; } +.sf_headerbox{width: 1200px; margin-bottom: 10px; margin: 0 auto; } +.sfhl{float: left; height: 100%; background-image: url(./../img/self_shop_f1_bg.png); padding-left: 31px; background-repeat: no-repeat; padding-top: 18px; background-size: contain; background-position: 0px 4px; position: relative; } +/* 楼层标题背景图 */ +.f1_tit_bg{background-image: url(./../img/self_shop_f1_bg.png)} +.f2_tit_bg{background-image: url(./../img/self_shop_f2_bg.png)} +.f3_tit_bg{background-image: url(./../img/self_shop_f3_bg.png)} +.f4_tit_bg{background-image: url(./../img/self_shop_f4_bg.png)} +.f5_tit_bg{background-image: url(./../img/self_shop_f5_bg.png)} +.f6_tit_bg{background-image: url(./../img/self_shop_f6_bg.png)} +.sfh_tit{font-size: 18px; color: #df2003; text-align: left; position: relative; top: -6px; left: 1px; } +.sfhr{float: right; height: 100%; line-height: 1.5; margin-top: 22px; } +.c18_333{font-size: 14px; color: #333; } +.separatory{padding: 0 10px; } +.sf_adsbox{width: 1200px; height: 320px; box-sizing:border-box; margin: 0 auto; margin-top: 10px; } +.sf_adsbox img{width: 100%;height: 100%;} +.sf_glistbox{width: 100%;} +/* 楼层商品背景色 */ +.f1_g_bg{background-color: #fff;} +.f2_g_bg{background:-webkit-linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); background:-o-linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); background:linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); } +.f3_g_bg{background-color: #fff;} +.f4_g_bg{background:-webkit-linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); background:-o-linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); background:linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); } +.f5_g_bg{background-color: #fff;} +.f6_g_bg{background:-webkit-linear-gradient(right, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); background:-o-linear-gradient(right, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); background:linear-gradient(to left, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); } +.sf_glist{width: 1200px;box-sizing:border-box; margin: 0 auto; padding: 0 19px; } +.sf_glist li:nth-child(n+6){margin-top:0; } +.sf_glist li:nth-child(5n){background-color: #fff; margin-right:0; } +.sf_glist li:hover a{background-color: #eee;} +.sf_glist li:hover{background-color: #eee;} +.sf_glist li{margin-top: 15px; margin-bottom: 15px; background-color: #fff; float: left; width: 200px; height: 300px; margin-right: 15px; padding: 0 10px; border-radius: 8px; transition:all ease .4s; } +.sf_glist li a{transition:all ease .4s; display: block; width: 100%; height: 100%; background-color: #fff; box-sizing: border-box; padding-top: 20px; } +.sf_img img{position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; max-width: 100%; max-height: 100%; } +.sf_img{position: relative; width: 100%; height: 200px; } +.sf_gname{margin: 10px auto; font-size: 14px; color: #333; width: 100%; overflow: hidden; word-break:break-all; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; min-height: 35px; } +.sf_price{font-size: 14px; color: #df2003; } diff --git a/hyhproject/home/view/default/css/shop.css b/hyhproject/home/view/default/css/shop.css new file mode 100755 index 0000000..c0a5a61 --- /dev/null +++ b/hyhproject/home/view/default/css/shop.css @@ -0,0 +1,454 @@ +@CHARSET "UTF-8"; +body {margin: 0px auto;background: #F5F5F5} +select{box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;padding: 2px;vertical-align: middle;} +.wst-wrap {margin: 0px auto} +.wst-header {} +.wst-main {margin: auto;width: 1200px;min-height: 600px;height: auto;padding-top: 15px;} +.wst-menu {background: #FFFFFF;width: 198px;float: left;margin-right: 15px;filter: progid : DXImageTransform.Microsoft.Shadow ( color = #909090,direction = 120, strength = 4 );-moz-box-shadow: 2px 2px 10px #909090;-webkit-box-shadow: 2px 2px 10px #909090;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);} +.wst-content {background: #FFFFFF;min-height: 948px;height: auto;width: 990px;float: right;filter: progid : DXImageTransform.Microsoft.Shadow ( color = #909090,direction = 120, strength = 4 );-moz-box-shadow: 2px 2px 10px #909090;-webkit-box-shadow: 2px 2px 10px #909090;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);} +.wst-footer {border-top: 1px solid #ddd;margin-top: 5px;} +.wst-menu-title {position: relative;width: 143px;display: block;padding: 10px 5px 10px 50px;font-weight: bolder;border-top: 1px solid #ccc;color: #000000;font-size: 16px;font-family:"microsoft yahei";background:#e9e9e9;cursor:pointer;} +.wst-menu-title img{padding: 0px 0px 3px 6px;} +.wst-menu {width: 198px;margin: 0px;padding: 0px;min-height: 948px;} +.wst-menu li {list-style-type: none;padding: 0px 0px 0px 50px;height: 35px;line-height: 35px;color: #6a6868;cursor: pointer} +.wst-menu li:hover,li.wst-menua{font-weight: bolder;color: #e23e3d;border-left: 2px solid #e23e3d;} +.wst-menu .selected {background-color: #e23e3d;font-weight: bolder;color: #ffffff;} +.wst-menu .liselect {background-color: #e23e3d;font-weight: bolder;color: #ffffff;} +.wst-list {width: 100%;border-collapse: collapse;} +.wst-list thead tr{line-height: 2;} +.wst-list thead tr th {height: 35px;border-bottom: 1px solid #ccc;text-align: left;padding-left:5px;background: #eeeeee;} +.wst-list tbody tr td {line-height: 35px;text-align: left;padding-left:5px;word-wrap: break-word;word-break:break-all;} +.wst-colour{background: #e6e6e6;} +.wst-form {border-collapse: collapse;width:99%;} +.wst-form tr {height: 30px;line-height: 30px;} +.wst-form tr th {color: #707070;text-align: right} +.wst-form tr td {text-align: left} +.wst-form input,textarea {background-color: white;border: 1px solid #ccc;border-radius: 3px;box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;margin: 3px;padding: 2px;vertical-align: middle;outline: none;border:1px solid #bac4c3;} +.wst-form input:focus{border-radius:3px;border:1px solid #eb654a;} +.wst-form select{box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;padding: 2px;vertical-align: middle;} +.wst-tab-box {width: 100%;height: auto;margin: 0px auto;} +.wst-tab-nav {margin: 0;padding: 0;height: 31px;border-bottom:1px solid #f7375c;} +.wst-tab-nav li {cursor: pointer;float: left;margin: 0 0px;list-style: none;border: 1px solid #ddd;border-bottom: none;border-left: none;line-height: 30px;text-align: center;background: #eeeeee;color: #000000;padding-left: 10px;padding-right: 10px;} +.wst-tab-nav .on {background: none repeat scroll 0 0 #e45050;border-bottom: 0 none;color: #ffffff;font-weight:bold;} +.wst-tab-content {padding: 5px;width: 99%;height: auto;border: 1px solid #ddd;background: #FFF;} +.wst-gallery-imgs {height: auto} +.wst-gallery-img {width: 140px;height: 100px;float: left;overflow: hidden;position:relative;margin: 10px 5px 5px 0px;cursor: pointer;} +.wst-gallery-del {background: url('../../../View/default/images/close_botton.png') no-repeat;display: block;height: 20px;position: absolute;width:20px;right: 0px;cursor: pointer;} +.wst-gallery-goods-del {background: url('../../../View/default/images/close_botton.png') no-repeat;display: block;height: 20px;position: absolute;width:20px;right: 0px;display:none;cursor: pointer;} +.wst-shop-nav {border-bottom:6px solid #e45050;text-align: center;} +.wst-nav-box {width: 1200px;margin: 0 auto;line-height: 33px;color: #ffffff;} +.wst-nav-box li{width: 156px;text-align: center;color: #e45050;font-size: 18px;font-family:"microsoft yahei";margin-bottom:-1px;} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{color: #ffffff;background:url(../img/seller_img_bgnav.png) 0px 0px no-repeat;} +.wst-nav-box .liselect {list-style-type:none;} +.wst-appsaler {margin-top: 30px;text-align: center;margin-bottom: 30px;line-height: 30px;} +.wst-menu-title span {position: absolute;left: 20px;top: 8px;display: inline-block;width: 20px;height: 20px;background-image: url(../../../View/default/images/icon_leftmenu.png);background-repeat: no-repeat;} +.wst-tree-open{background-repeat: no-repeat;display: inline-block;width: 20px;vertical-align:middle;cursor:pointer} +.wst-tree-close{display: inline-block;width: 20px;vertical-align:middle;cursor:pointer} +.wst-tree-second{display: inline-block;width: 20px;margin-left:10px;vertical-align:middle;cursor:pointer} +.wst-fre-hov:hover{background: #fae9ec;} +.wst-state_yes{display:block;width:13px;} +.wst-state_no{display:block;width:13px;} +.wst-page-items{text-align: left;color: #ccc;} +.wst-page-items a{display: inline-block;color: #000000;display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;border: 1px solid #D5D5D5;margin: 0 2px;border-radius: 4px;vertical-align: middle;} +.wst-page-items a:hover{text-decoration: none;color: #e23e3d;font-weight:bolder;border: 1px solid #D5D5D5;} +.wst-page-items span.current{display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;color: #e23e3d;font-weight:bolder;border: 1px solid #D5D5D5;border-radius: 4px;vertical-align: middle;} +.wst-page-items span.disabled{display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;color: #bfbfbf;background: #f2f2f2;border: 1px solid #bfbfbf;border-radius: 4px;vertical-align: middle;} +.wst-shophome-img{height:120px;height:120px;text-align:center;} +.wst-shophome-area{min-height:400px;border-top:1px solid #cccccc;} +.wst-shophome-nav{width:780px;float:left;min-height:400px;} +.wst-shophome-nav .header{height:36px;background-color:#f5f5f5;line-height:36px;padding-left:10px;font-weight:bolder;} +.wst-shophome-nav .main{height:66px;background-color:#feffd4;line-height:30px;padding-left:10px;margin:10px;} +.wst-shophome-nav .current{padding-left:20px;padding-bottom:10px;color:#000000;} +.wst-goods-price-table{width:100%;border:0px;border-collapse: collapse;} +.wst-goods-price-table tr th{border:0px;text-align:left;background:#eee;padding-left:5px} +.wst-goods-fieldset{border:2px double #ddd;padding:5px;display:none;} +.wst-goods-fieldset legend{margin-left:10px;} +.wst-complain-detail{width:100%;border-collapse: collapse;} +.wst-complain-detail tr{height: 25px;line-height: 25px;} +.wst-complain-detail tr th{color: #707070;text-align: right;font-size:12px;} +.wst-complain-detail tr td {text-align: left;color: #707070;} +.wst-complain-detail .head{font-weight:bold;border-bottom:1px dotted #ddd;} +.wst-complain-left{width:250px;height:100%;border:1px solid #ddd;text-align:left;background:#ffffff;float:left;} +.wst-complain-order-head{width:240px;height:25px;line-height:25px;border-bottom:1px solid #ddd;font-weight:bold;padding:5px;background:#f5f5f5;} +.wst-complain-order-goods{width:240px;height:180px;line-height:30px;padding:5px;border-bottom:1px solid #ddd;overflow-y:auto} +.wst-complain-main{float:right;width:718px;overflow:hidden;border:1px solid #ddd;margin-right:16px;} +.wst-complain-order-info{padding:5px;display: block;height:100%;} +.wst-complain-order-info dt {float: left;width: 70px;color: #999;padding: 1px 0;display: block;height:20px;} +.wst-complain-order-info dd{overflow: hidden;color: #666;padding: 1px 0;width:170px;display: block;height:20px;} +.wst-complain-box{border-bottom:1px solid #ddd;width:718px;padding:5px;} +.wst-complain-footer{clear:both;width:100%;text-align:center;padding:5px 0;} +/*头部*/ +.wst-lite-bac{background:#ffffff;} +.wst-lite-tit{float:left;width: 100px;margin:16px 0px 0px 10px;} +.wst-lite-tit span{float:left;color: #e45050;font-size: 19px;margin-left:10px;font-family:"microsoft yahei";} +a.wst-lite-in{float:left;margin-top:6px;padding:3px 8px;color: #e45050;border:1px solid #e45050;} +a.wst-lite-in:hover{color: #ffffff;border:1px solid #ffffff;background:#e45050;} +.wst-lite-sea{float:right;background:#ffffff;margin-top:20px;} +.wst-lite-sea .search{border:2px solid #e23c3d;height: 35px;position: relative;} +.wst-lite-sea .search .j-search-type{width:78px;top:0;line-height:36px;position: absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor: pointer;left:-2px;text-align:center;} +.wst-lite-sea .search .j-type-list{width:70px;top:35px;line-height:36px;position: absolute;padding:0 4px;border:2px solid #e23c3d;cursor: pointer;background-color: #fff;left:-2px;z-index: 100;border-top:0;display: none;text-align: center;} +.wst-lite-sea .search .j-search-type i {top: 15px;right: 6px;height: 7px;width: 0px;overflow: hidden;font-style: normal;color: #6A6A6A;display: block;position: absolute;} +.wst-lite-sea .search .j-search-type s{ position: relative;top: -17px;text-decoration: none;}.wst-lite-sea .search .j-type-list div:hover{color: #e23c3d} +.wst-lite-sea .search .search-ipt{border: 2px solid #e23c3d;color: #565656;float: left;font-family: Microsoft Yahei;font-size: 14px;line-height: 30px;overflow: hidden;padding: 0;width: 330px;height:30px;border:36px;outline:none;padding-left: 84px;box-shadow: none;} +.wst-lite-sea .search .search-btn{cursor: pointer;font-size: 15px;font-weight: bolder;height: 35px;line-height: 36px;position: absolute;right: 0;text-align: center;top: 0;width: 52px;background:url(../img/btn_search_red.png) 22px 6px no-repeat;} +/*首页*/ +.wst-shop-name{margin-top:28px;margin-left:138px;} +.wst-shop-name a{color: #fe6047;font-size: 18px;font-family: "microsoft yahei";} +.wst-shop-info{padding:0px 0px 0px 10px;} +.wst-shop-img{float:left;margin-top:-32px;width:120px;height:120px;text-align:center;vertical-align:middle;display:block;position:relative;} +.wst-shop-img a{width:120px;height:120px;display:table-cell;vertical-align:middle;} +.wst-shop-img img{max-width:120px;max-height:120px;} +.wst-shop-na{float:left;margin-left:6px;width:20%;} +.wst-shop-na a{color: #fe6047;font-size: 18px;font-family: "microsoft yahei";} +.wst-shop-na2{float:left;margin-top:3px;} +.wst-shop-na2 img{float:left;width:15px;margin:4px 3px 0px 0px;cursor: pointer;} +.wst-shop-na2 span{float:left;line-height: 26px;margin-right:6px;} +.wst-shop-na3{float:left;width:100%;color: #010101;line-height:26px;} +.wst-shop-eva{float:left;width:15%;margin:0px;border-left:1px dashed #bfbfbf;} +.wst-shop-eva p{font-size: 15px;color: #010101;text-align:center;font-family: "microsoft yahei";margin:16px 0px 8px 0px;} +.wst-shop-evai{float:left;margin:8px 0px 16px 25px;} +.wst-shop-con{float:left;width:21%;margin:0px;border-left:1px dashed #bfbfbf;} +.wst-shop-con p{font-size: 15px;font-family: "microsoft yahei";line-height: 30px;margin-left:18px;} +.wst-list .wst-fre-th{padding-left: 23px;} +.wst-list .wst-fre-td{padding-left: 25px;} +/*标题*/ +.wst-shop-head{float: left;width: 100%;border-bottom: 1px solid #e45050;} +.wst-shop-head span{float: left;line-height:28px;padding:0px 28px;color:#ffffff;background:#e45050;font-weight: bold;} +.wst-shop-head a{float: right;line-height:28px;padding:0px 28px;color:#ffffff;background:#df2003;} +.wst-shop-tbar{height: 45px;margin:15px 0 0 0px;clear:both;padding:5px 10px;} +.wst-shop-content{padding:12px;clear:both;} +/*button按钮*/ +/*红*/ +.wst-shop-but{outline: none;background:#E45050;color: #ffffff;border: 1px solid #d8193e;border-radius:3px;cursor:pointer;} +.wst-shop-but:hover{background: #ea3232 none repeat scroll 0 0;cursor:pointer;} +/*button按钮*/ +.s-btn{height: 30px;line-height: 30px;margin-right: 10px;margin-top: 16px;padding: 7px 20px;color: #ffffff;background: #E45050;border-radius: 3px;cursor:pointer;} +.s-btn:hover{cursor:pointer;} +.s-btn2{height: 30px;line-height: 30px;margin-right: 10px;margin-top: 16px;padding: 7px 20px;background: #ebebeb;border:1px solid #dad7d7;border-radius: 3px;cursor:pointer;} +.s-btn:hover{cursor:pointer;} +.wst-shop-split{border-bottom:1px dotted #ccc;margin-top:10px;margin-bottom:10px;} +.wst-shop-jrdt{height:120px;} +.wst-shop-jrdt .wst-title{background:url("../img/img_majz_titlebg.png");background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-jrdt .item{width:170px;height: 58px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;} +.wst-shop-jrdt .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -45px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -170px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -296px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -422px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -550px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .title{float:left;text-align: center;height:58px;width:120px;padding-top:5px} +.wst-shop-jrdt .item .num{color:red} +.wst-shop-spxx{height:300px;margin-top: 25px;} +.wst-shop-spxx .wst-title{background:url("../img/img_majz_titlebg.png") no-repeat 0px -68px;background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-spxx .item{width:170px;height: 100px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;margin-bottom: 10px;} +.wst-shop-spxx .item .rbox{height:60px;position:relative;} +.wst-shop-spxx .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -38px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -155px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -274px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -391px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -507px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon6{background:url("../img/icon-mjzxsy.png") no-repeat -38px -232px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .title{text-align: center;height:58px;padding-top:5px} +.wst-shop-spxx .item .num{color:red} +.wst-shop-ddxx{height:280px;} +.wst-shop-ddxx .wst-title{background:url("../img/img_majz_titlebg.png") no-repeat 0px -135px;background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-ddxx .item{width:170px;height: 100px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;margin-bottom: 10px;} +.wst-shop-ddxx .item .rbox{height:60px;position:relative;} +.wst-shop-ddxx .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -38px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -154px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -273px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -391px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -509px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon6{background:url("../img/icon-mjzxsy.png") no-repeat -38px -415px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .title{text-align: center;height:58px;padding-top:5px} +.wst-shop-ddxx .item .num{color:red} +/********************************************** 新增商品页面 ****************************************************/ +/*自定义单选框样式*/ +.wst-radio + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;border-radius: 50px;display: inline-block;position: relative;} +.wst-radio + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-radio:checked + label{border: 1px solid #ff9a02;/* 修改选框选中颜色*/} +.wst-radio:checked + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #ff9a02;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #ff9a02;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.radio-box .wst-radio{position:relative;z-index:-654;left:16px;top:0px;} +.radio-box label{margin-left:-8px;margin-right:2px;} +.mt-1{position:relative;top:1px;left:0px;cursor:pointer;} +/*自定义复选框样式-行*/ +.wst-checkbox + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-checkbox:checked + label{border: 1px solid #ff9a02;/* 修改选框选中颜色*/} +.wst-checkbox:checked + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #ff9a02;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #ff9a02;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.checkbox-box .wst-checkbox{position:relative;z-index:-654;left:16px;top:-1px;} +.checkbox-box label{margin-left:-8px;margin-right:2px;} +.w-r{width:15px;height:15px;cursor:pointer;margin-left:8px;} +.wrong{background:url(../img/seller_icon_error.png) no-repeat;} +.right{background:url(../img/seller_icon_right.png) no-repeat;} +.g-handle{color:#1cbbef;display: inline-block;margin:0 3px;} +.g-handle:hover{color:#085cde;} +.spec-item{float:left;} +.spec-item .item-del{background:url(../img/icon_no.png);width:13px;height:13px;display:inline-block;position: relative;top:-10px;left:-10px;cursor:pointer;} +.spec-ipt{width:80px;} +.specs-sale-table{width:100%;border-collapse:collapse;border:1px solid #dddddd;margin-bottom:10px;} +.specs-sale-table th{padding-top:5px;text-align:center;background:#eeeeee;text-align:center;border:1px solid #dddddd} +.specs-sale-table td{text-align:center;text-align:center;border:1px solid #dddddd} +.spec-sale-goodsNo{width:150px} +.spec-sale-ipt{width:50px;} +.spec-sale-text{width:80%} +.attr-table{width:100%} +.attr-table th{text-align:right;} +.attr-table td{text-align:left;} +#goodsImgPicker{margin-left:20px;} +.spec-line{border-top:1px dashed #cccccc;margin:5px 0px 7px 0px} +.spec-head{font-weight:bold;height:30px;line-height:30px;background:url(../img/img_seller_ggjt.png) no-repeat 0px 7px;padding-left:25px;} +.spec-body{border:1px solid #cccccc;padding:5px;margin-bottom:10px;} +/************************ 商家商品管理页面 **************************/ +.goods-img{width:60px; height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left;margin:3px auto;line-height: 0px;} +.goods-img a{width:60px;height:60px;display:table-cell;vertical-align:middle;} +.goods-img a img{max-width:60px;max-height:60px;} +.goodsName{height:50px;line-height:25px;overflow: hidden;float: left;max-width: 150px;margin-left: 5px;} +.s-menu{height:25px;margin-left: 4px;margin-top:10px;} +.s-menu a{display: block;float:left;width:48px;margin-right: 10px;} +.s-menu a span{display: block;float: right;} +.s-sale,.s-sale-up,.s-new,.s-hot,.s-best,.s-rec,.s-heart,.s-del,.s-add{display: inline-block;width:18px;height:18px;background: url(../img/seller_icon_cz.png) no-repeat;} +.s-sale{background-position: -20px -24px;} +.s-sale:hover{background-position: -20px -64px;color:#F7375C;margin-top: 1px;} +.s-sale-up{background-position: -473px -24px;} +.s-sale-up:hover{background-position: -473px -64px;color:#F7375C;margin-top: 1px;} +.s-rec{background-position: -83px -24px;} +.s-rec:hover{background-position: -83px -64px;color:#F7375C;margin-top: 1px;} +.s-new{background-position: -149px -24px;} +.s-new:hover{background-position: -149px -64px;color:#F7375C;margin-top: 1px;} +.s-best{background-position: -213px -25px;} +.s-best:hover{background-position: -213px -65px;color:#F7375C;margin-top: 1px;} +.s-hot{background-position: -280px -25px;} +.s-hot:hover{background-position: -280px -65px;color:#F7375C;margin-top: 1px;} +.s-heart{background-position: -276px -25px;} +.s-heart:hover{background-position: -276px -65px;color:#F7375C;margin-top: 1px;} +.s-del{background-position: -343px -25px;} +.s-del:hover{background-position: -343px -65px;color:#F7375C;margin-top: 1px;} +.s-add{background-position: -408px -25px;} +.s-add:hover{background-position: -408px -65px;color:#F7375C;margin-top: 1px;} +/*评价管理*/ +.appra-img{width:150px; height:150px;margin:5px auto;text-align:center;vertical-align:middle;display:block;position:relative; float:left;} +.appra-img a{display:table-cell;vertical-align:middle;width:150px;height:150px;} +.appra-img a img{max-width:150px;max-height:150px;} +.appra-goodsName{float: left;height: 150px;line-height: 25px;margin-left: 5px;max-width: 240px;overflow: hidden;} +/*自定义复选框-列--方*/ +.checkbox-box-s{height:20px !important;} +.wst-checkbox-s + label {-webkit-appearance: none;background-color: #ffffff;border: 1px solid #d5d5d5;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox-s + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;box-shadow: inset 0px 0px 10px #ccc;text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-checkbox-s:checked + label{border: 1px solid #F7375C;/* 修改选框选中颜色*/} +.wst-checkbox-s:checked + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #F7375C;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #F7375C;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-5px;top:-1px;} +.checkbox-box-s label{position: relative;top:-38px;left: 1px;} +.checkbox-box-s-all label{position: relative;top:-27px;left: 1px;} +/**订单列表**/ +.wst-box-top{margin-top:5px;} +.wst-order-list{width:100%;border-collapse:separate;border-spacing: 0;border-color:grey;} +.wst-order-list .head{max-height:32px;line-height: 32px;text-align: center;background: #f5f5f5;color: #666;font-weight: 400;} +.wst-order-list .empty-row{height: 20px;} +.wst-order-list .order-head{background: #f5f5f5;height: 31px;line-height: 31px;color: #aaa;overflow: hidden;} +.wst-order-list .order-head td{padding-left:5px;padding-right:5px;border:1px solid #e5e5e5;border-bottom:0px;} +.wst-order-list .goods-box td:first-child{border-left:1px solid #e5e5e5;} +.wst-order-list .goods-box td{padding:5px;border:1px solid #e5e5e5;border-top:0px;border-left:0px;} +.wst-order-list .time{float:left;margin-right:30px;} +.wst-order-list .orderno{float:left;margin-right:30px;width:300px;text-align:left;} +.wst-order-list .address{float:left;width:580px;text-align:left} +.wst-order-list .goods-img{width:60px;height:60px;float:left;border:1px solid #efefef;} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:475px;} +.wst-order-list .goods-extra{float:right;margin-left:5px;} +.wst-order-list .j-warn .order-head{background:#fcf8e3;height: 31px;line-height: 31px;color:#8a6d3b;overflow: hidden;} +.wst-order-list .j-warn .order-head td{padding-left:5px;padding-right:5px;border:1px solid #faebcc;border-bottom:0px;} +.wst-order-list .j-warn .goods-box td:first-child{border-left:1px solid #faebcc;} +.wst-order-list .j-warn .goods-box td{padding:5px;border:1px solid #faebcc;border-top:0px;border-left:0px;} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px;} +.j-warn-order-money{color:red;font-size:19px;font-weight:bold} +.order-pc{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_1.png) 0px 0px no-repeat;background-size: 90%;} +.order-mo{float: left;margin: 7px 5px 0px 0px;width: 18px;height: 18px;background: url(../img/order_source_2.png) 0px 0px no-repeat;background-size: 100%;} +.order-wx{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_3.png) 0px 0px no-repeat;background-size: 100%;} +.order-app{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background: url(../img/order_source_4.png) 0px 0px no-repeat;background-size: 100%;} +.order-ios{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_5.png) 0px 0px no-repeat;background-size: 100%;} +/**订单详情**/ +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd;} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px} +/*流程展示*/ +.order-box .log-box{height:132px;} +.order-box .log-box .icon{float:left;width:60px;height:60px;} +.order-box .log-box .icons{float:left;width:60px;height:60px;} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat;} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat;} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat;} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat;} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat;} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat;} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat;} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat;} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat;} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat;} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat;} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat;} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat;} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat;} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat;} +.order-box .log-box .arrow{float:left;color: #979797;font-size: 15px;font-weight: bold;margin-top:18px;} +.order-box .log-box .arrow2{color: #7ebb53;} +.order-box .log-box .state{float:left;width:100%;margin-left:18px;} +.order-box .log-box .state2{float:left;width:100%;position: relative;} +.order-box .log-box .state2 p{float:left;width:180px;height:50px;text-align:left;margin-left:12px;color:#f05858;font-size: 15px;} +.order-box .log-box .state2 .path{position: absolute;z-index: 10;} +.order-box .log-box .state2 .path span{float:left;width:178px;height:50px;text-align:left;margin-left:12px;background: #ffffff;} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd;} +.order-box th{font-weight:normal;} +.order-box .goods-head{border-top:2px solid #FC7A64;background: #f3f3f3;display: block;height: 25px;line-height: 25px;margin: 0 0 10px;padding: 5px 0;} +.order-box .goods-head .goods{float:left;width:500px;padding-left:15px} +.order-box .goods-head .number{float:left;width:140px;} +.order-box .goods-head .price{float:left;width:100px;} +.order-box .goods-head .num{float:left;width:100px;} +.order-box .goods-head .t-price{float:left;width:105px;} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #FDD8D2;color:#E55356;font-weight:bold;font-size:15px;padding-bottom:5px;} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eeeeee;border-top:0px;} +.order-box .item .goods{float:left;width:500px;padding-left:15px;} +.order-box .item .number{float:left;width:140px;} +.order-box .item .goods .img{float:left;width:80px;height:80px;} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px;} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px;} +.order-box .item .price{float:left;width:100px;} +.order-box .item .num{float:left;width:100px;} +.order-box .item .t-price{float:left;width:100px;} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px;} +.order-box .line{border-top:1px solid #dddddd;} +.order-box .goods-summary{margin-top:10px;} +.order-box .summary{height:30px;line-height:30px;} +.order-box .orderScore{margin-right:5px;} +.order-box .log td{height:25px;line-height:25px;padding-left:15px;} +/********** 店铺设置 *********/ +.cfg-img-url{background: #f48c3a none repeat scroll 0 0;bottom: 0;height: 18px;left: -1px;top:178px;line-height: 18px;padding: 0 5px;position: absolute;z-index: 170;} +/************* 商家回复 *************/ +.reply-content{line-height:15px;width:100%;margin-top:-15px;border-top:1px solid #ccc;padding-top:15px;color:orange;} +.reply-box{width:100%;max-height:140px;position:relative;margin-bottom:5px;margin-top:15px;} +.wst-msg-tips-box{background-color: #f0a869;border-radius: 12px;color: white;cursor: pointer;display: inline-block;height: 24px;left: 30px;line-height: 24px;position: relative;text-align: center;top: 0;width: 24px;} +/* 商家回复 */ +.wst-list tbody tr td .spec{height: 45px;line-height: 15px;overflow: hidden;float: left;max-width: 160px;} +.wst-list tbody tr td .stockin{display:none;border:1px solid #bac4c3;width:100px;outline: none;} +.wst-list tbody tr td .stockin:focus{border:1px solid #eb654a;} +.j-messsage-box{padding:10px 5px;color:red;} +.head-ititle{background:url('../img/img_seller_ggjt.png') no-repeat 5px 4px;padding-left:28px;padding-bottom:5px;font-weight:bold;} +/**资金流水**/ +.money-add{color:red;font-size:16px;font-weight: bold;} +.money-reduce{color:green;font-size:16px;font-weight: bold;} +.money-head{background:#eeeeee;height:120px;width:100%} +.money-head .shop-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px;} +.money-head .shop-logo img{-moz-border-radius: 100px; -webkit-border-radius: 100px; } +.money-head .shop-info{float:left;padding-top:25px;padding-left:20px;} +.money-head .shop-info .shopName{height:25px;line-height:25px;} +.money-head .shop-info .money-rows{width:700px;} +.money-head .shop-info .shopMoney{height:25px;line-height:25px;width:500px;} +.money-head .shop-info .draw-tips{color:red;margin-left:20px;} +.money-head .shop-info .cashmoney-box{margin-left:20px;} +.money-head .cashbtn{padding: 3px 5px;border: 1px solid #333;} +.money-head .cashbtn:hover{padding: 3px 5px;border: 1px solid #e45050;} +.money-head .usermoney{width:150px ; float:left;} +.money-head .cashbox{width:300px; float:left;} +.money-head .lockbox{width:150px ; float:left;} + +.msgContent{padding:10px;} +.readMsg,.newMsg{width:36px;height:27px;background: url(../img/user_icon_info.png) no-repeat;} +.newMsg{background-position: -66px -6px;} +.readMsg{background-position: -11px -6px;} +.msg-content{width: 630px} +/* 商家中心首页 */ +.main{background: #f6f6f6;width: auto;min-height: 800px;padding-top: 20px;} +.main_title{padding: 5px 0;} +.c16_555{font-size: 16px;color: #555;} +.tit_label{width: 12px;height: 12px;background: #e33c3c;border-radius: 50%;display: inline-block;} +.main_middle{width:auto;height:auto;} +.main_mid_box{display:flex;width:auto;height: 100%} +.main_mid_box .mid_l{flex:2;} +.mid_l_item{padding:0 10px;flex:1;background: #fff;height: 48%;} +.complain_num{display: inline-block;width: 25px;height: 25px;background: #e33c3c;border-radius: 50%;color:#fff;text-align: center;line-height: 25px;} +.mid_main{width: 100%;height: 90%;} +.order_info{width:100%;height:100%;display: flex;} +.order_info li{flex: 1;display: flex;height: 100%;flex-direction: column;justify-content: space-around;} +.order_info li:nth-child(2){flex:1.5;} +.c32_e33{font-size: 32px;color:#e33c3c;margin-bottom: 20px} +.info_item{padding:10px 0;text-align: center;} +.item_center{display: flex;justify-content:center;align-items:center;height: 148px!important;width: 148px !important;border-radius: 50% 50% 0 50%;border-color: #e33c3c;border-style: solid;border-width: 1px 0px 0px 1px;margin: 0 auto;} +.main_mid_box .mid_c{flex:1;margin:0 20px;background: #fff;} +.index-right-item{background:#fff;min-height: 492px;margin-bottom:20px;width: 100%;overflow: hidden;} +.right-list-tit{width: 97%;border-bottom: 1px solid #eee;display: flex;margin: 0 auto;} +.right-list-tit li{padding:14px 0px;flex:1;float: left;text-align: center;} +.orderInfoList li{padding: 13px 0px !important;} +.right-list-tit li:nth-child(2){flex:2;} +.right-list{border:0px;} +.right-list li{padding:13.7px 0px;} +.c14_ff90{font-size: 14px;color:#ff9000;} +.c14_ff66{font-size: 14px;color:#ff6666;} +.wst-textover{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;} +.gTop1,.gTop2,.gTop3{text-align: left;padding-left: 13px;background-image:url(./../img/flag-each-69x26.png);background-size: 80%;background-position: 0 0;background-repeat: no-repeat;color:#fff;} +.gTop2{background-position: 0 -37px;} +.gTop3{background-position: 0 -73px;} +.top-num{text-align: left;padding-left: 13px;} +.item_sale{border-radius: 50% 50% 50% 50%;border-width: 0px 1px 1px 0px;} +.main_mid_box .mid_r{flex:1;} +.mid_r_rtop{background: #fff;height: 29%;width: 96%;margin-bottom:20px;padding-left:10px;} +.rtop_main{padding:10px 0} +.rtop_item{margin-top:5px;} +.mid_r_rbottom{background: #fff;height: 67%;width: 96%;padding-left:10px;} +.sale_info{margin-top:20px;width: 99%;height: 300px;background: #fff;padding-left:10px;} +.shop_tips li{padding: 6px 15px;width: 200px} +.shop_tips li a:hover{color:#e33c3c;} +.order_remaker{color:#ff6c00;padding: 5px;border: 1px solid #ddd;border-top:none;} +.order_from{ margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + +#shoprole th,#shoprole td{border: solid 1px #E6E6E6;} +#shoprole dl{ border-bottom: solid 1px #E6E6E6;} +#shoprole dl .dt1,#shoprole dl .dt2{ font-size: 12px; + line-height: 30px; + color: #333; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + text-align: right; + display: inline-block; + width: 120px; + padding: 0 4px; + margin: 0; + +} +#shoprole dl .dd1{ font-size: 12px; + font-size: 12px; + line-height: 30px; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + display: inline-block; + width: 690px; + padding: 0px 4px; + border-left: solid 1px #E6E6E6; +} +#shoprole dl .dd2{ + font-size: 12px; + line-height: 30px; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + display: inline-block; + width: 500px; + padding: 0px 4px; + border-left: solid 1px #E6E6E6; +} +#shoprole td label{width:120px;text-align: left;display: inline-block;} + +.uinfo>input{ width: 235px;} +.wst-form input, textarea { + background-color: white; + border: 1px solid #ccc; + border-radius: 2px; + box-shadow: 1px 1px 1px #f0f0f0 inset; + font-family: inherit; + font-size: 100%; + margin: 3px; + padding: 5px; + vertical-align: middle; +} +.uinfo-form tr td { + height: 40px; +} +.wst-list-add{float: right;line-height:16px;height:16px;margin-top:2px;} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/shopapply.css b/hyhproject/home/view/default/css/shopapply.css new file mode 100755 index 0000000..af7aeba --- /dev/null +++ b/hyhproject/home/view/default/css/shopapply.css @@ -0,0 +1,56 @@ +.stepflex{float:right;border-top:5px solid #ccc;text-align:center;width:960px;margin:60px 0px 0px 50px;} +.stepflex dl{border-top:5px solid #ccc;float:left;position:relative;top:-5px;width:160px;} +dl.doing{border-top-color:#04bd3d;} +.doing .s-num{background-position:-23px 0;} +.s-num,.s-num1{color:#fff;font-weight: 700;height:23px;line-height:23px;margin:-15px auto 0;position:relative;width:23px;border-radius:25px;} +.s-num{background:#04bd3d;} +.s-num1{background:#ccc;} +.s-text1{line-height:30px;} +.s-text{line-height:30px;color:#04bd3d;} +select{height:29px;} +.webuploader-container{overflow:hidden;} +.apply-banner{width: 100%;height:320px;position: relative;z-index: 1;top:-8px;} +.apply-msg-box{filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColorstr='#3F000000', endColorstr='#3F000000');background:rgba(0,0,0,0.25); width: 280px; height: 300px; z-index: 9; margin-top:30px; border-radius: 5px;} +.apply-msg-box h3{color:#fff;font: 600 17px/24px; color: #FFF; padding: 12px 10px 4px 10px; margin: 0 10px 10px;box-shadow: 0 1px 0 rgba(0,0,0,0.1);} +.apply-msg-box .title{color: #FFF;margin-top:10px;line-height:30px;padding-left:15px;padding-right:15px;} +.apply-msg-box ul{color: #FFF;padding-left:15px;padding-right:15px;height:149px;} +.apply-msg-box ul li{margin-top:10px;line-height:23px;list-style-type: disc;margin-left:15px;} +.apply-msg-box .bottom{border-radius:0 0 5px 5px;margin-top:10px;padding-top:10px;padding-bottom:10px;padding-left:7px;filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColorstr='#7F000000', endColorstr='#7F000000'); background:rgba(0,0,0,0.5); text-align: center;} +.wst-slide{position: relative;height:350px;overflow:hidden;top:-320px;z-index:-1} +.apply-tips{color: #777;background-color: #EEE;width: 100%;height: 60px;} +.apply-tips .title{width: 60px;height: 48px;display: inline-block;padding: 6px 12px 6px 24px;} +.apply-tips .title i{background: url(../img/ic_volume_24x24.png) no-repeat 0px 0;display: block;width: 24px;height: 24px;float: left;margin: 0 18px;} +.apply-tips .content{font: 12px/20px "microsoft yahei";vertical-align: top;display: inline-block;width: 920px;padding: 10px;} +.apply-step{font-size: 0;width: 800px;height: 110px;margin: 30px auto;overflow: hidden;} +.apply-step span { font-size: 12px; vertical-align: middle; letter-spacing: normal; word-spacing: normal; display: inline-block; *display: inline; *zoom: 1;} +.apply-step span.step { color:#777;line-height: 20px; text-align: center; width: 80px;} +.apply-step span.step i { background: url(../img/btn_80x80.png) no-repeat; display: block; width: 80px; height: 80px; margin-bottom: 10px;} +.apply-step span.step i.a { background-position: -12px 0px;} +.apply-step span.step i.b { background-position: -94px 0px;} +.apply-step span.step i.c { background-position: -176px 0px;} +.apply-step span.step i.d { background-position: -258px 0px;} +.apply-step span.step i.e { background-position: -340px 0px;} +.apply-step span.arrow { background: url(../img/btn_80x80.png) no-repeat -439px -30px; width: 60px; height: 22px; margin: 0 20px;margin-top:-25px;} +.apply-step-head{margin-top:20px;border-bottom:dotted 1px #CCC;font-weight:600;font-size:16px;line-height:30px;padding-left:10px;} + +.main-head{font-size:17px;font-weight:bold;height:35px;line-height:35px;text-align:left;} +.apply-box {border-top: 2px solid #FC7A64;border-left: 1px solid #eeeeee;border-right: 1px solid #eeeeee;border-bottom: 1px solid #eeeeee;padding: 5px 0px 0px 5px;} +.apply-agreement-box{height:350px;border:1px solid #eeeeee;padding:5px;overflow:auto;margin:0 auto;} +.apply-agreement-box .tip{color:gray} +.agreement-table{width:100%;margin-bottom:10px;} +.agreement-table th{text-align: right;width:250px;} +.agreement-table td{text-align: left} +.agreement-table .head-ititle{background:url('../img/img_seller_ggjt.png') no-repeat 5px 4px;padding-left:28px;padding-bottom:5px;font-weight:bold;} +.agreement-table input[type=text]{margin:2px;} +.agreement-table textarea{margin:2px;} +.agreement_box{text-align:center;margin-top:5px;} +.agreement-bottom{padding:10px 5px;text-align: center} +.examine-tips{text-align: center;width:100%;padding-top:60px;padding-bottom:80px;font-weight: 600;font-size:16px;color:#999;} +label{margin-right:20px;} +.webuploader-pick{padding:3px 10px;} +.goodsCat{width:140px;margin-right:20px;float:left;} +.wst-tab-box {width: 100%;height: auto;margin: 0px auto;background: #ffffff;margin-top:10px;} +.wst-tab-nav {margin: 0;padding: 0;height: 35px;top: 0px;z-index: 30;background: #ffffff;width:100%;border-bottom: 1px solid #eeeeee;border-left: 1px solid #eeeeee} +.wst-tab-nav li {width:23.24%;cursor: pointer;float: left;margin: 0 0px;list-style: none;border: 1px solid #eee;border-bottom: none;border-left: none;line-height: 34px;text-align: center;color: #000000;padding-left: 10px;padding-right: 10px;} +.wst-tab-nav .on {border-top: 1px solid #ff2704;border-bottom: 1px solid #ffffff;color: #ff2704;font-weight:bold;} +.wst-tab-content {padding: 5px;width: 99%;height: auto;border: 1px solid #eee;border-top:none;background: #FFF;} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/shophome.css b/hyhproject/home/view/default/css/shophome.css new file mode 100755 index 0000000..b7818ba --- /dev/null +++ b/hyhproject/home/view/default/css/shophome.css @@ -0,0 +1,105 @@ +@CHARSET "UTF-8"; +.wst-shop-h{padding:10px 0} +.wst-shop-img{float:left;margin-top:3px;width:90px;height:90px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-img img{max-width:90px;max-height:90px;border-radius:5px} +.wst-shop-info{float:left;width:45%;margin-left:10px} +.wst-shop-info p{float:left;line-height:50px;width:100%;color:#222;font-size:17px;font-family:"microsoft yahei"} +.wst-shop-info2,.wst-shop-info3{float:left;width:100%} +.wst-shop-info2 img{float:left;width:16px;margin-right:3px} +.wst-shop-info2 span{float:left;color:#dda315;margin-right:10px} +.wst-shop-info3{margin-top:7px} +.wst-shop-code{float:left;margin-top:-3px;width:24px;height:24px;cursor:pointer;background:url(../img/img_sjck.png) no-repeat;background-size:100%} +.wst-shop-codes{width:131px;height:131px;margin-top:24px;border:1px solid #dedbdb;position:absolute;z-index:1000;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);border-radius:5px} +.wst-shop-codes:after{top:-16px;border-color:transparent transparent #fff} +.wst-shop-eva,.wst-shop-evaa{float:left;margin-right:16px} +.wst-shop-evaa{padding-left:20px} +.wst-shop-info3 .j-fav,.wst-shop-info3 .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 1px 2px no-repeat} +.wst-shop-info3 .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 0 -23px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shop-info3 .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 0 1px no-repeat;text-decoration:none} +.wst-shop-red{color:#e25041} +.wst-shop-sea{float:right;width:42.999999%;margin-top:20px} +.wst-shop-sea input{float:left;outline:0;font-size:15px;height:32px;width:360px;margin-right:3px;padding-left:8px;border:1px solid #fc6047} +.wst-shop-sea .search{float:left;width:60px;height:32px;line-height:32px;text-align:center;color:#fff;margin-left:6px;background:url(../img/img_bg_search.png) no-repeat} +.wst-shop-word{float:left;margin-top:8px;width:100%;height:18px;overflow:hidden} +.wst-shop-tu{text-align:center;width:100%;height:110px}@media screen and (max-width:1200px){.wst-shop-tu{min-width:1200px} +.wst-shop-nav{min-width:1200px}} +.wst-shop-nav{background-color:#fc6047} +.wst-nav-box{width:1200px;margin:0 auto;line-height:36px;color:#fff} +.wst-nav-box li{padding:0 26px;text-align:center;color:#fff;font-size:15px;font-family:"microsoft yahei"} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{background:#cb2004;background-size:cover} +.wst-nav-box .liselect{list-style-type:none} +.wst-nav-box .homepage{float:right;margin-top:6px;padding:0 8px;height:22px;line-height:22px;color:#fff;border:1px solid #fff} +.wst-nav-box .homepage:hover{color:#fc6047;background:#fff;border:1px solid #fc6047} +.ck-slide{width:1200px;height:400px;margin:3px auto;margin-bottom:9px} +.ck-slide ul.ck-slide-wrapper{height:400px} +.wst-shop-contl{float:left;width:19.222222%;padding-bottom:20px} +.wst-shop-contr{float:right;width:79.555555%} +.wst-shop-cat{margin-top:9px;border:1px solid #ddd} +.wst-shop-best,.wst-shop-lat{margin-top:15px;border:1px solid #ddd} +.wst-shop-cat li{height:26px;line-height:26px;list-style-type:none} +.wst-shop-cat li:hover{color:#ff5605;cursor:pointer} +.wst-shop-cat a li{color:#666} +.wst-shop-conlp{height:35px;line-height:35px;text-align:center;background:#ebebeb;font-size:16px;font-family:"microsoft yahei"} +.wst-shop-catt{padding-left:10px} +.wst-shop-catts{padding-left:20px} +.js-shop-plus{text-indent:20px;background:url(../img/store_icon_zk.png) 2px 4px no-repeat} +.js-shop-redu{text-indent:20px;background:url(../img/store_icon_sq.png) 2px 4px no-repeat} +.wst-shop-bestg{float:left;margin:5px} +.wst-shop-besti{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-besti img{max-width:72px;max-height:72px} +.wst-shop-bestgp1{height:36px} +.wst-shop-bestgp2{line-height:20px} +.wst-shop-bestg p{float:left;width:142px;margin-left:3px;overflow:hidden} +.wst-shop-bestg a:hover{color:#ff5605} +.wst-shop-bestpi{color:#ee8f4f} +.wst-shop-bestpr{color:#d86232;font-weight:bold} +.wst-shop-bestpr2{float:right;color:#c4c2c2;text-decoration:line-through} +.wst-shop-conrp{height:35px;line-height:35px;text-indent:1em;background:#ebebeb;font-size:16px;font-family:"microsoft yahei";margin:9px 0 6px 0} +.wst-shop-recb{padding:5px 0;background:#f2efea} +.wst-shop-rgoods,.wst-shop-list .wst-shop-goods{float:left;width:218px;padding:5px;background:#fff;border:1px solid #dadada;margin:0 4px} +.wst-shop-rgoods:hover,.wst-shop-goods:hover{border:1px solid #e5e5e5;-webkit-box-shadow:0 0 10px #ddd;-moz-box-shadow:0 0 10px #ddd;box-shadow:0 0 10px #ddd} +.wst-shop-list .wst-shop-goimg{float:left;width:207px;height:207px;vertical-align:middle;display:block;position:relative} +.wst-shop-goimg a{width:207px;height:207px;padding-left:5px;padding-top:5px;display:table-cell;vertical-align:middle} +.wst-shop-goimg img{max-width:207px;max-height:207px} +.wst-shop-goimg span{width:230.5px;height:30px;line-height:30px;color:#fff;text-align:center;opacity:.8;background:#d0260c;display:block;position:absolute;left:-6px;bottom:-5px;display:none} +.wst-shop-goimg span:hover{background:#e5280b} +.wst-shop-gonam{float:left;width:100%;height:36px;color:#838383;font-size:15px;font-family:"microsoft yahei";margin-top:18px} +.wst-shop-gonam a:hover{color:#f60505} +.wst-shop-rect{float:left;width:100%;margin-top:8px;font-family:"microsoft yahei"} +.wst-shop-rect span{color:#ea523b;font-size:16px;line-height:26px;font-weight:bold} +.wst-shop-rect .wst-shop-recta{float:right;height:26px;color:#ff5605;line-height:26px;padding:0 12px;border-radius:2px;border:1px solid #dadada} +.wst-shop-rect .wst-shop-recta2{float:right;height:26px;color:#c9c3c2;line-height:26px;padding:0 12px;border-radius:2px;border:1px solid #dadada} +.wst-shop-rect .wst-shop-recta:hover{color:#fff;background:#ff5605;border:1px solid #ff5605} +.wst-shop-list{padding:10px 0} +.wst-shop-listh{float:left;width:100%;font-family:"microsoft yahei"} +.wst-shop-listh a{float:left;color:#525252;height:19px;padding:6px 16px;text-align:center;font-size:15px;border:1px solid #e9e7e7} +.wst-shop-listh a:hover{border:1px solid #ff8043} +a.wst-shop-a{color:#fff;background:#ff8043;border:1px solid #ff8043} +.wst-shop-store,.wst-shop-store2,.wst-shop-store3{float:right;width:16px;height:13px;margin:3px 0 0 3px} +.wst-shop-store{background:url(../img/store_icon_sx.png) 0 0 no-repeat} +.wst-shop-store2{background:url(../img/store_icon_sx_sel.png) 0 0 no-repeat} +.wst-shop-store3{background:url(../img/store_icon_sx_sel_up.png) 0 0 no-repeat} +.wst-price-ipts{float:left;position:relative}input.wst-price-ipt{width:66px;height:27px;outline:0;padding-left:18px;border:1px solid #e9e7e7}input.wst-price-ipt:focus{border:1px solid #ff8043} +.wst-price-ipt1{position:absolute;left:13px;top:8px} +.wst-price-ipt2{position:absolute;right:71px;top:8px} +.wst-shop-but{outline:0;background:#ebebeb;color:#9f9696;border:1px solid #dad7d7;cursor:pointer} +.wst-shop-but:not(.disabled):not(:disabled):active,.wst-shop-but.active{background:#f1f1f1;background-clip:padding-box} +.wst-shop-listg{padding-top:10px} +.wst-shop-list .wst-shop-goods{margin-bottom:6px} +.wst-shop-goodp1{margin-top:8px} +.wst-shop-goodp1,.wst-shop-goodp2{float:left;width:100%;line-height:20px;font-family:"microsoft yahei";padding:2px 0 2px 0} +.wst-shop-goodpr{color:#ea523b;font-size:16px;font-weight:bold;overflow:hidden;float:left} +.wst-shop-goodpr2{color:#ed1a8d} +.wst-shop-goodpr3{color:#c4c2c2;width:220px;overflow:hidden} +.wst-shop-goodpr4{color:#249ee7} +.wst-shop-pa{padding:28px 0 35px 300px} +.wst-shop-info2 img.wangwang{padding-top:1px;width:65px;height:22px} +.wst-shop-goimg img.goodsImg{max-width:207px;max-height:207px} +.wst-shop-share{float:right;position:relative;top:-6px;margin-right:6px} +.wst-shop-list img{max-width:1200px}@-webkit-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@-moz-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@-o-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}} +.wst-shop-rgoods:hover img{-webkit-animation:a1 1s .1s ease both;-moz-animation:a1 1s .1s ease both;animation:a1 .5s .1s ease both;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%} +.notice_img{width:15px;height:15px;vertical-align:middle} \ No newline at end of file diff --git a/hyhproject/home/view/default/css/shopstreet.css b/hyhproject/home/view/default/css/shopstreet.css new file mode 100755 index 0000000..fbee1c4 --- /dev/null +++ b/hyhproject/home/view/default/css/shopstreet.css @@ -0,0 +1,49 @@ +@CHARSET "UTF-8"; +a{cursor:pointer} +img{border:none} +.wst-shopstr-ads{padding:10px 0} +.wst-shopstr-ads img{width:1200px;height:220px} +.wst-shopstr-cat{margin:10px 0 20px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-shopstr-catt{height:23px;color:#333;border-bottom:1px dashed #b5b5b5} +.wst-shopstr-cat span{float:left;margin:8px 60px 0 0;padding:8px 5px} +.wst-shopstr-cat span:hover{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.js-selected{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.wst-shopstr-shop{margin-top:20px;padding:10px;border:1px solid #dddbdb} +.wst-shopstr-shop:hover{border:1px solid #fc6047} +.wst-shopstr-shopl{float:left;width:150px;height:150px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shopstr-shopi{float:left;width:26%;margin-left:12px} +.wst-shopstr-shopr{float:right;width:60%} +.wst-shopstr-shopl a{width:150px;height:150px;display:table-cell;vertical-align:middle} +.wst-shopstr-shopl a img{max-width:150px;max-height:150px} +.wst-shopstr-name{height:32px;line-height:32px} +.wst-shopstr-name .name{float:left;font-size:18px;color:#2e2e2e;font-weight:700;width:170px;height:30px;display:block;overflow:hidden} +.wst-shopstr-name .name:hover{color:#f53e28} +.wst-shopstr-name .favorite{padding:5px 5px 5px 23px;loat:left;border:1px solid #ededed;margin-left:5px} +.wst-shopstr-name .j-fav,.wst-shopstr-name .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 4px 5px no-repeat} +.wst-shopstr-name .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 3px -19px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shopstr-name .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 3px 5px no-repeat;text-decoration:none} +.wst-shopstr-pr{float:left;width:100%;margin-top:7px;color:#807f7f} +.wst-shopstr-pr .company{text-decoration:underline;color:#57c4f5} +.wst-shopstr-pr .company:hover{color:#31b0e9} +.wst-shopstr-score{width:118px;height:96px;position:absolute;left:25px;bottom:-95px;color:#545252;text-indent:1em;cursor:pointer;background:url(../img/img_bg_xiala.png) 0 0 no-repeat} +.wst-shopstr-score .title{font-weight:700} +.wst-shopstr-more{float:left;width:100%} +.wst-shopstr-more a{font-size:13px;color:#666} +.wst-shopstr-more a:hover{color:#eb5f43} +.wst-shopstr-more span{width:100px;height:20px;color:#fff;line-height:20px;background:url(../img/img_dztj_bg.png) no-repeat} +.wst-shopstr-good{padding-top:2px;margin-left:26px} +.wst-shopstr-goods{float:left;margin:0 3px} +.wst-shopstr-goodimg{width:100px;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shopstr-goodimg a{width:100px;height:100px;display:table-cell;vertical-align:middle} +.wst-shopstr-goodimg a img{max-width:100px;max-height:100px} +.wst-shopstr-goods span{float:left;width:100px;margin-top:1px;text-align:center;color:#fc6047;font-weight:700} +.shopstrPaging{padding:20px 0 50px 480px} +.als-container{position:relative;width:100%;margin:0 auto} +.als-viewport{position:relative;overflow:hidden;margin:0 auto} +.als-wrapper{position:relative;list-style:none} +.als-item{position:relative;display:block;text-align:center;cursor:pointer;float:left} +.als-next,.als-prev{position:absolute;cursor:pointer;clear:both} +.als-item img{width:135px;height:135px;vertical-align:middle} +.als-next,.als-prev{top:40px} +.als-prev{left:-25px} +.als-next{right:-30px} diff --git a/hyhproject/home/view/default/css/user.css b/hyhproject/home/view/default/css/user.css new file mode 100755 index 0000000..59a54bc --- /dev/null +++ b/hyhproject/home/view/default/css/user.css @@ -0,0 +1,382 @@ +@CHARSET "UTF-8"; +.wst-wrap{margin:0 auto} +.wst-main{margin:auto;width:1200px;min-height:600px;height:auto;padding-top:15px} +.wst-menu{background:#fff;width:198px;float:left;margin-right:15px;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-content{background:#fff;min-height:948px;height:auto;width:990px;float:right;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-footer{border-top:1px solid #ddd;margin-top:5px} +.wst-menu-title{position:relative;width:143px;display:block;padding:10px 5px 10px 50px;font-weight:bolder;border-top:1px solid #ccc;color:#000;font-size:16px;font-family:"microsoft yahei";background:#e9e9e9;cursor:pointer} +.wst-menu-title img{padding:0 0 3px 6px} +.wst-menu{width:198px;margin:0;padding:0;min-height:948px} +.wst-menu li{list-style-type:none;padding:0 0 0 50px;height:35px;line-height:35px;color:#6a6868;cursor:pointer} +.wst-menu li:hover,li.wst-menua{font-weight:bolder;color:#e23e3d;border-left:2px solid #e23e3d} +.wst-menu .selected{background-color:#e23e3d;font-weight:bolder;color:#fff} +.wst-menu .liselect{background-color:#e23e3d;font-weight:bolder;color:#fff} +.wst-list{width:100%;border:1px solid #ddd;border-collapse:collapse} +.wst-list thead tr th{height:40px;line-height:40px;border-bottom:1px solid #ccc;text-align:left;padding-left:5px;background:#eee} +.wst-list tbody tr td{word-wrap:break-word;word-break:break-all;height:40px;line-height:40px;text-align:left;padding-left:5px} +.wst-list tbody tr:nth-child(even){background:#fcfae1} +a:active,a:hover{text-decoration:none;color:red} +.wst-form{border-collapse:collapse} +.wst-form tr{height:30px;line-height:30px} +.wst-form tr th{color:#707070;text-align:right} +.wst-form tr td{text-align:left} +.wst-form input,textarea{background-color:white;border:1px solid #ccc;border-radius:2px;box-shadow:1px 1px 1px #f0f0f0 inset;font-family:inherit;font-size:100%;margin:3px;padding:5px;vertical-align:middle} +.wst-form select{box-shadow:2px 2px 2px #f0f0f0 inset;font-family:inherit;font-size:100%;vertical-align:middle;margin:3px} +.wst-form select option{padding:2px} +.wst-shop-nav{background-color:#e45050;border-top:6px solid #e45050;text-align:center} +.wst-nav-box{width:1200px;margin:0 auto;line-height:33px;color:#fff} +.wst-nav-box li{width:145px;text-align:center;color:#fff;font-size:18px;font-family:"microsoft yahei";margin-bottom:-1px} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{color:#e45050;background:url(../img/user_bg_nav.png) -10px 0 no-repeat} +.wst-nav-box .liselect{list-style-type:none} +.wst-appsaler{margin-top:30px;text-align:center;margin-bottom:30px;line-height:30px} +.wst-menu-title span{position:absolute;left:20px;top:8px;display:inline-block;width:20px;height:20px;background-image:url(../../../View/default/images/icon_leftmenu.png);background-repeat:no-repeat} +select{box-shadow:2px 2px 2px #f0f0f0 inset;font-family:inherit;font-size:100%;padding:2px;vertical-align:middle}input,textarea{background-color:white;border:1px solid #ccc;border-radius:4px;font-family:inherit;font-size:100%;margin:3px;padding:5px;vertical-align:middle} +.wst-tab-box{width:100%;height:auto;margin:0 auto} +.wst-tab-nav{margin:0;padding:0;height:31px} +.wst-tab-nav li{cursor:pointer;float:left;margin:0;list-style:none;border:1px solid #ddd;border-bottom:0;border-left:none;line-height:30px;text-align:center;background:#eee;color:#000;padding-left:10px;padding-right:10px} +.wst-tab-nav .on{background:none repeat scroll 0 0 #e23e3d;border-bottom:0 none;color:#fff;font-weight:bold} +.wst-tab-content{padding:5px;width:99%;height:auto;border:1px solid #ddd;background:#FFF} +.wst-appraise-box{margin:0 auto;margin-top:20px;margin-bottom:10px} +.wst-appraise-box .appraise-title{margin-top:10px;font-weight:bold;text-align:left;padding-left:30px;padding-bottom:10px} +.wst-appraise-box .appraise-title .tips{font-weight:normal;color:#999} +.wst-appraise-box .main{border:1px solid #e9e9e9;border-top:2px solid #999} +.wst-appraise-box .head{line-height:35px;background-color:#e9e9e9;font-weight:bold} +.wst-appraise-box .goods-no{float:left;width:50px;text-align:center} +.wst-appraise-box .goods-name{float:left;width:600px} +.wst-appraise-box .goods-name2{float:left;width:530px;line-height:30px} +.wst-appraise-box .goods-status{float:left;width:120px;text-align:center} +.wst-appraise-box .goods-buy-time{float:left;width:220px;text-align:center} +.wst-appraise-box .appraise-box{text-align:center;background-color:#dbeaf9;padding-top:5px} +.wst-appraise-box .goods-txt{line-height:70px} +.wst-appraise-box .goods-img{border:0;margin-top:5px;margin-bottom:5px} +.wst-appraise-box .appraise-box .main-box{width:800px;margin:0 auto} +.wst-appraise-box .appraise-box .item{line-height:40px;margin-top:5px} +.wst-appraise-box .appraise-box .item .title{float:left;width:80px;text-align:right} +.wst-appraise-box .appraise-box .item .content{float:left;width:700px;text-align:left} +.wst-appraise-box .appraise-box .btn-box{padding-right:80px;margin:15px;float:right} +.wst-goods-tb{margin-top:3px;margin-bottom:2px;border:0} +.wst-complain-detail{width:100%;border-collapse:collapse} +.wst-complain-detail tr{height:25px;line-height:25px} +.wst-complain-detail tr th{color:#707070;text-align:right;font-size:12px} +.wst-complain-detail tr td{text-align:left;color:#707070} +.wst-complain-detail .head{font-weight:bold;border-bottom:1px dotted #ddd} +.wst-complain-left{width:250px;height:100%;border:1px solid #ddd;text-align:left;background:#fff;float:left} +.wst-complain-order-head{width:240px;height:25px;line-height:25px;border-bottom:1px solid #ddd;font-weight:bold;padding:5px;background:#f5f5f5} +.wst-complain-order-goods{width:240px;height:200px;line-height:30px;padding:5px;border-bottom:1px solid #ddd;overflow-y:auto} +.wst-complain-main{float:right;width:732px;overflow:hidden;border:1px solid #ddd} +.wst-complain-order-info{padding:5px;display:block;height:100%} +.wst-complain-order-info dt{float:left;width:70px;color:#999;padding:1px 0;display:block;height:20px} +.wst-complain-order-info dd{overflow:hidden;color:#666;padding:1px 0;width:170px;display:block;height:20px} +.wst-complain-box{border-bottom:1px solid #ddd;width:732px;padding:5px} +.wst-complain-footer{clear:both;width:100%;text-align:center;padding:5px 0} +.jcrop-holder #preview-pane{display:block;position:absolute;z-index:2000;top:10px;right:10px;padding:6px;border:1px rgba(0,0,0,.4) solid;background-color:white;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2);-moz-box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2);box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2)} +#preview-pane .preview-container{width:150px;height:150px;overflow:hidden;border:1px dashed #777} +#userPhotoCutBox>p{min-width:500px;min-height:500px;background:url('../img/cut_bg.png') repeat 0 0} +#cutArea{border:1px dashed #777;position:relative;top:-2px;left:-2px;float:left}#c-btn{width:35%;margin-left:15%} +.cut-btn{width:80px;height:30px;background:#e02f2f;color:white;font-weight:bold} +.cut-help{width:150px;position:absolute;top:185px;right:10px} +.cut-help p{margin-top:7px;width:150px} +.wst-lite-bac{background:#fff} +.wst-lite-tit{float:left;width:100px;margin:16px 0 0 10px} +.wst-lite-tit span{float:left;color:#e45050;font-size:19px;margin-left:10px;font-family:"microsoft yahei"}a.wst-lite-in{float:left;margin-top:6px;padding:3px 8px;color:#e45050;border:1px solid #e45050} +a.wst-lite-in:hover{color:#fff;border:1px solid #fff;background:#e45050} +.wst-lite-sea{float:right;background:#fff;margin:20px 35px 0 0} +.wst-lite-sea .search{border:2px solid #e23c3d;height:35px;position:relative} +.wst-lite-sea .search .j-search-type{width:78px;top:0;line-height:36px;position:absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor:pointer;left:-2px;text-align:center} +.wst-lite-sea .search .j-type-list{width:70px;top:35px;line-height:36px;position:absolute;padding:0 4px;border:2px solid #e23c3d;cursor:pointer;background-color:#fff;left:-2px;z-index:100;border-top:0;display:none;text-align:center} +.wst-lite-sea .search .j-search-type i{top:15px;right:6px;height:7px;width:0;overflow:hidden;font-style:normal;color:#6a6a6a;display:block;position:absolute} +.wst-lite-sea .search .j-search-type s{position:relative;top:-17px;text-decoration:none} +.wst-lite-sea .search .j-type-list div:hover{color:#e23c3d} +.wst-lite-sea .search .search-ipt{border:0 none;color:#565656;float:left;font-family:Microsoft Yahei;font-size:14px;line-height:30px;overflow:hidden;padding:0;width:330px;height:30px;border:36px;outline:0;padding-left:84px;box-shadow:none} +.wst-lite-sea .search .search-btn{cursor:pointer;font-size:15px;font-weight:bolder;height:35px;line-height:36px;position:absolute;right:0;text-align:center;top:0;width:52px;background:url(../img/btn_search_red.png) 22px 6px no-repeat} +.wst-lite-cart{float:right;width:163px;height:40px;margin-top:20px;background:#e23c3d;position:relative;cursor:pointer} +.wst-lite-cart .word{float:left;width:112px;margin-top:4px;margin-left:20px;padding:5px 6px 7px 28px;color:#fff;font-size:14px;font-family:"microsoft yahei";background:url(../img/icon_gouwuche.png) no-repeat left center;position:relative} +.wst-lite-cart .num{font-size:14px;color:#fff;line-height:24px;text-align:center;position:absolute;display:block;width:27px;height:25px;background:url(../img/icon_number.png) no-repeat;right:19px;top:-12px} +.wst-lite-carts{width:332px;min-height:130px;margin-top:18px;border:1px solid #dedbdb;position:absolute;z-index:1200;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);left:-171px;top:22px} +.wst-lite-carts:after{top:-16px;border-color:transparent transparent #fff} +.wst-lite-carts .carts{background:url(../img/top_icon_cartdown.png) 28px 47px no-repeat;width:332px;height:130px;text-indent:4.5em;line-height:130px;font-size:15px;color:#b9b6b6} +.wst-lite-cart .goods{float:left;width:96.666666%;border-bottom:1px dashed #bfbfbf;padding:5px} +.wst-lite-cart .goods .imgs{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-lite-cart .goods .imgs a{width:72px;height:72px;display:table-cell;vertical-align:middle} +.wst-lite-cart .goods .imgs img{max-width:72px;max-height:72px} +.wst-lite-cart .goods .number{float:left;width:50%} +.wst-lite-cart .goods .number p{float:left;width:92%;margin-top:10px;padding-left:10px} +.wst-lite-cart .goods .price{float:right;text-align:right} +.wst-lite-cart .goods .price p{float:right;width:100%;line-height:20px;font-weight:bold;color:#df2003} +.wst-lite-cart .goods.price span{float:right;width:100%;line-height:20px} +.wst-lite-cart .goods .price span a:hover,.wst-lite-cart .goods .number p a:hover{color:#df2003} +.wst-lite-cart .comm{float:left;width:100%;font-weight:bold;line-height:32px} +.wst-lite-cart .comm span{font-size:15px;color:#e45050} +.wst-lite-cart .comm .span2{float:right;margin-right:10px} +.wst-lite-cart .btn{color:#fff;cursor:pointer;display:block;font-size:16px;font-weight:400;line-height:30px;margin:10px 0 16px 72px;max-width:200px;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;vertical-align:middle;width:100%;border-radius:5px} +@media(min-width:400px){.wst-lite-cart .btn{display:inline-block;margin-right:2.5em} +.wst-lite-cart .btn:nth-of-type(even){margin-right:0}}@media(min-width:600px){.wst-lite-cart .btn:nth-of-type(even){margin-right:2.5em} +.wst-lite-cart .btn:nth-of-type(5){margin-right:0}} +.wst-lite-cart .btn:hover{text-decoration:none} +.wst-lite-cart .btn-3{background:#e3403a;border:1px solid #da251f;box-shadow:0 1px 0 #d6251f,1px 1px 1px #e02a24;font-weight:900;letter-spacing:1px;-webkit-transition:all 150ms linear;transition:all 150ms linear} +.wst-lite-cart .btn-3:hover{background:#e02c26;border:1px solid rgba(0,0,0,0.05);box-shadow:1px 1px 2px rgba(255,255,255,0.2);color:#ec817d;text-decoration:none;text-shadow:-1px -1px 0 #c2211c;-webkit-transition:all 250ms linear;transition:all 250ms linear} +.wst-nav-l{float:left;width:28px;height:33px} +.wst-nav-r{float:right;width:28px;height:33px} +.wst-bottom{margin:auto;width:1200px;padding-top:20px} +.wst-bottom-m{float:left;height:29px;width:100%;border-bottom:1px solid #f24040} +.wst-bottom-ml{float:left;height:28px;line-height:28px;padding:0 10px;cursor:pointer;background:#ebebeb;border-top:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-bottom:1px solid #f24040;font-family:"microsoft yahei"} +.wst-bottom-mr{float:right;margin-right:5px;font-family:"microsoft yahei"} +.wst-bottom-ms{background:#f5f5f5;border-top:1px solid #f24040;border-left:1px solid #f24040;border-right:1px solid #f24040;border-bottom:1px solid #f5f5f5} +.wst-bottom-mr img{margin-top:7px;margin-right:5px} +.wst-bottom-mr a{line-height:28px} +.wst-bottom-g{padding:10px 0} +.wst-bottom-gs{float:left;padding:10px;width:17.333333%;margin:0 5px;border-radius:3px;border:1px solid #dadada} +.wst-bottom-i{float:left;width:208px;height:208px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-bottom-i img{max-width:208px;max-height:208px} +.wst-bottom-n1,.wst-bottom-n2,.wst-bottom-n3,.wst-bottom-n4{float:left;width:100%;font-family:"microsoft yahei"} +.wst-bottom-n1{margin-top:16px;font-size:15px} +.wst-bottom-n2{margin-top:8px} +.wst-bottom-n4{margin-top:5px} +.wst-bottom-n2l{font-size:15px;color:#eb533e;font-weight:bold} +.wst-bottom-n2r,.wst-bottom-n3r{float:right;line-height:20px} +.wst-bottom-n2r span{color:#ec198a} +.wst-bottom-n3l{color:#bab8b8;line-height:20px} +.wst-bottom-n3r span{color:#1398e3} +.wst-bottom-gs:hover{cursor:pointer;border:1px solid #f24040} +.gray{color:#707070;font-weight:bold} +.uinfo-form tr td{width:330px;height:40px} +.uinfo>input{width:235px} +.uinfo-nav{border-bottom:1px solid #e45050} +.uinfo-nav .on{background:none repeat scroll 0 0 #e45050;border-bottom:0 none;color:#fff;font-weight:bold} +select{border:solid 1px #ccc;appearance:none;-moz-appearance:none;-webkit-appearance:none;padding-right:14px;background:url("../img/arrow.png") no-repeat scroll right center transparent} +select::-ms-expand{display:none} +.wst-radio+label{-webkit-appearance:none;background-color:#fafafa;border:1px solid gray;padding:6px;border-radius:50px;display:inline-block;position:relative} +.wst-radio+label:after{content:' ';width:6px;height:6px;border-radius:50px;position:absolute;top:3px;background:#99a1a7;box-shadow:inset 0 0 10px rgba(0,0,0,0.3);text-shadow:0;left:3px;font-size:32px} +.wst-radio:checked+label{border:1px solid #ff9a02} +.wst-radio:checked+label:after{content:' ';width:6px;height:6px;border-radius:50px;position:absolute;top:3px;background:#ff9a02;box-shadow:inset 0 0 10px #ff9a02;text-shadow:0;left:3px;font-size:32px} +.radio-box .wst-radio{position:relative;z-index:-654;left:16px;top:0} +.mt-1{position:relative;top:1px;left:0;cursor:pointer} +.checkbox-box-s{height:20px!important;cursor:pointer} +.wst-checkbox-s+label{-webkit-appearance:none;background-color:#fff;border:1px solid #d5d5d5;padding:6px;display:inline-block;position:relative} +.wst-checkbox-s+label:after{content:' ';width:6px;height:6px;position:absolute;top:3px;box-shadow:inset 0 0 10px #ccc;text-shadow:0;left:3px;font-size:32px} +.wst-checkbox-s:checked+label{border:1px solid #fc7373} +.wst-checkbox-s:checked+label:after{content:' ';width:6px;height:6px;position:absolute;top:3px;background:#fc7373;box-shadow:inset 0 0 10px #fc7373;text-shadow:0;left:3px;font-size:32px} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-5px;top:-1px;cursor:pointer} +.checkbox-box-s label{position:relative;top:-48px;left:1px} +.u-menu{height:25px;margin-left:4px;margin-top:10px} +.readMsg,.newMsg{width:36px;height:27px;background:url(../img/user_icon_info.png) no-repeat} +.newMsg{background-position:-66px -6px} +.readMsg{background-position:-11px -6px} +.msg-content{width: 630px} +.s-handle{color:#1cbbef!important;display:inline-block;margin:0 3px} +.s-handle:hover{color:#085cde} +.g{color:green} +.addr-btn{width:95px!important} +.wst-addr{width:98%;border:1px solid #ccc;margin:10px} +.wst-addr tbody tr td{height:20px} +.addr-title{text-align:right;width:130px} +.del{display:block;float:right;clear:right;padding-right:5px;font-size:15px;color:#c1c1c1!important} +.del:hover{color:red!important} +.edit>a{display:block;float:right;padding-right:20px;color:#4b4bfb} +.edit>a:hover{color:#0d0dc7} +.default{width:60px;height:25px;background:orange;line-height:25px;text-align:center;color:white;float:left;clear:left;margin-left:35px} +.wst-user-head{float:left;width:100%;border-bottom:1px solid #e45050} +.wst-user-head span{float:left;line-height:28px;padding:0 28px;color:#fff;background:#e45050;font-weight:bold} +.wst-user-head a{float:right;line-height:28px;padding:0 28px;color:#fff;background:#e45050} +.wst-user-tbar{height:35px;padding:2px;clear:both;padding-top:13px;padding-left:10px} +.wst-user-content{padding:2px;clear:both;margin-top:10px} +.wst-user-buta{height:30px;line-height:30px;margin-right:10px;margin-top:16px;padding:0 20px;color:#fff;background:#e45050;border-radius:3px} +.wst-user-buta:hover{color:#fff;background:#ea3232} +.wst-user-buta2{height:29px;padding:0 20px;background:#ebebeb;border-radius:3px;border:1px solid #dad7d7;box-shadow:0 0 1px rgba(0,0,0,0.3)} +.wst-user-buta2:hover{border-radius:3px;background:#f1f1f1;box-shadow:0 0 0 rgba(0,0,0,0.3)} +.wst-sec-but:not(.disabled):not(:disabled):active,.wst-sec-but.active{background:#f96a54;background-clip:padding-box;border:1px solid #f96a54} +.wst-sec-but2{outline:0;background:#ebebeb;color:#9f9696;border:1px solid #dad7d7;border-radius:3px;cursor:pointer} +.wst-sec-but2:not(.disabled):not(:disabled):active,.wst-sec-but2.active{background:#f1f1f1;background-clip:padding-box} +.wst-order-list{width:100%;border-color:grey;border-collapse:separate;border-spacing:0} +.wst-order-list .head{height:32px;line-height:32px;text-align:center;background:#f5f5f5;color:#666;font-weight:400} +.wst-order-list .empty-row{height:20px} +.wst-order-list .order-head{background:#f5f5f5;height:31px;line-height:31px;color:#aaa;overflow:hidden} +.wst-order-list .order-head td{padding-left:5px;padding-right:5px;border:1px solid #e5e5e5;border-bottom:0} +.wst-order-list .goods-box td:first-child{border-left:1px solid #e5e5e5} +.wst-order-list .goods-box td{padding:5px;border:1px solid #e5e5e5;border-top:0;border-left:0} +.wst-order-list .time{float:left;margin-right:30px} +.wst-order-list .orderno{float:left;margin-right:30px;width:250px;text-align:left} +.wst-order-list .shop{float:left;margin-right:20px;width:150px;text-align:left} +.wst-order-list .link{float:left} +.wst-order-list .goods-img{width:60px;height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left} +.wst-order-list .goods-img a{display:table-cell;vertical-align:middle;width:60px;height:60px} +.wst-order-list .goods-img a img{max-width:60px;max-height:60px} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:500px} +.wst-order-list .goods-extra{float:right;margin-left:5px} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px} +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px;padding-left:5px;} +.order-pc{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_1.png) 0 0 no-repeat;background-size:90%} +.order-mo{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_2.png) 0 0 no-repeat;background-size:100%} +.order-wx{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_3.png) 0 0 no-repeat;background-size:100%} +.order-app{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_4.png) 0 0 no-repeat;background-size:100%} +.order-ios{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_5.png) 0 0 no-repeat;background-size:100%} +.order-box .log-box{height:132px} +.order-box .log-box .icon{float:left;width:60px;height:60px} +.order-box .log-box .icons{float:left;width:60px;height:60px} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat} +.order-box .log-box .arrow{float:left;color:#979797;font-size:15px;font-weight:bold;margin-top:18px} +.order-box .log-box .arrow2{color:#7ebb53} +.order-box .log-box .state{float:left;width:100%;margin-left:18px} +.order-box .log-box .state2{float:left;width:100%;position:relative} +.order-box .log-box .state2 p{float:left;width:185px;height:50px;text-align:left;margin-left:12px;color:#f05858;font-size:15px} +.order-box .log-box .state2 .path{position:absolute;z-index:10} +.order-box .log-box .state2 .path span{float:left;width:185px;height:50px;text-align:left;margin-left:12px;background:#fff} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd} +.order-box th{font-weight:normal} +.order-box .goods-head{border-top:2px solid #fc7a64;background:#f3f3f3;display:block;height:25px;line-height:25px;margin:0 0 10px;padding:5px 0} +.order-box .goods-head .goods{float:left;width:650px;padding-left:15px} +.order-box .goods-head .price{float:left;width:100px} +.order-box .goods-head .num{float:left;width:100px} +.order-box .goods-head .t-price{float:left;width:105px} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #fdd8d2;color:#e55356;font-weight:bold;font-size:15px;padding-bottom:5px} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eee;border-top:0} +.order-box .item .goods{float:left;width:650px;padding-left:15px} +.order-box .item .goods .img{float:left;width:80px;height:80px} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px} +.order-box .item .price{float:left;width:100px} +.order-box .item .num{float:left;width:100px} +.order-box .item .t-price{float:left;width:100px} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px} +.order-box .line{border-top:1px solid #ddd} +.order-box .goods-summary{margin-top:10px} +.order-box .summary{height:30px;line-height:30px} +.order-box .orderScore{margin-right:5px} +.order-box .log td{height:25px;line-height:25px;padding-left:15px} +.score-add{color:red;font-size:16px;font-weight:bold} +.score-reduce{color:green;font-size:16px;font-weight:bold} +.score-head{background:#eee;height:120px;width:100%} +.score-head .user-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px} +.score-head .user-logo img{-moz-border-radius:100px;-webkit-border-radius:100px} +.score-head .user-info{float:left;padding-top:25px;padding-left:20px} +.score-head .user-info .userName{height:25px;line-height:25px} +.score-head .user-info .userScore{height:25px;line-height:25px} +.score-head .user-info .draw-tips{color:red;margin-left:20px} +.money-add{color:red;font-size:16px;font-weight:bold} +.money-reduce{color:green;font-size:16px;font-weight:bold} +.money-head{background:#eee;height:120px;width:100%} +.money-head .user-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px} +.money-head .user-logo img{-moz-border-radius:100px;-webkit-border-radius:100px} +.money-head .user-info{float:left;padding-top:25px;padding-left:20px} +.money-head .user-info .userName{height:25px;line-height:25px} +.money-head .user-info .userScore{height:25px;line-height:25px} + +.score-head .user-info .cashmoney-box{margin-left:20px;} +.score-head .cashbtn{padding: 3px 5px;border: 1px solid #333;} +.score-head .cashbtn:hover{padding: 3px 5px;border: 1px solid #e45050;} +.score-head .usermoney{width:150px ; float:left;} +.score-head .cashbox{width:300px; float:left;} +.score-head .lockbox{width:150px ; float:left;} + +.wst-fav-listg{float:left;width:100%;padding-top:12px} +.wst-fav-listg a,.wst-fav-shop span{color:#6a6868} +.wst-fav-goods{float:left;width:21.88888888%;padding:10px;background:#fff;border:1px solid #dadada;border-radius:3px;margin-left:6px;margin-bottom:20px} +.wst-fav-goods:hover{border:1px solid #fe7f6c} +.wst-fav-goodp1{margin-top:8px} +.wst-fav-goodp1,.wst-fav-goodp2{float:left;width:100%;line-height:20px;font-family:"microsoft yahei"} +.wst-fav-goodpr{color:#ea523b;font-size:16px;font-weight:bold} +.wst-fav-goodpr2{color:#ed1a8d} +.wst-fav-goodpr3{color:#c4c2c2} +.wst-fav-goodpr4{color:#249ee7} +.wst-fav-goimg{float:left;width:216px;height:216px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-fav-goimg img{max-width:216px;max-height:216px;cursor:pointer} +.wst-fav-goimg span{width:216px;height:38px;line-height:38px;font-size:15px;color:#fff;opacity:.8;background:#605d56;display:block;position:absolute;left:0;bottom:0;display:none} +.wst-fav-goimg span:hover{background:#d0260c;cursor:pointer} +.wst-fav-gonam{float:left;width:100%;height:36px;color:#838383;font-size:15px;font-family:"microsoft yahei";margin-top:6px} +.wst-fav-shop{float:left;width:100%;margin-top:6px} +.wst-fav-shop span{margin-right:10px} +.wst-fav-shop img{float:left;margin-top:1px;width:15px;margin-right:3px} +.wst-fav-pa{padding:25px 0 0 350px} +.wst-favo-shop{margin-top:20px;padding:8px;border:1px solid #dddbdb} +.wst-favo-shop:hover{border:1px solid #ec7e67} +.wst-favo-shopl{float:left;width:150px} +.wst-favo-shopr{float:right;width:80%} +.wst-favo-shopimg{float:left;width:150px;height:150px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-favo-shopimg img{max-width:150px;max-height:150px} +.wst-favo-shopl p{float:left;height:25px;width:100%;line-height:25px;text-align:center;font-family:"microsoft yahei"} +.wst-favo-shopa{float:left;padding:0 8px;margin-left:3px;height:22px;line-height:22px;border:1px solid #7a7a7a;color:#7a7a7a;cursor:pointer} +.wst-favo-shopa:hover{color:#ec7e67;border:1px solid #ec7e67;box-shadow:0 0 1px rgba(0,0,0,0.3)} +.wst-favo-more{float:left;width:100%} +.wst-favo-more a{font-size:13px;color:#666} +.wst-favo-more a:hover{color:#eb5f43} +.wst-favo-more span{width:100px;height:20px;color:#ec7e67;line-height:20px;font-weight:bold;text-align:center;border-bottom:2px solid #ec7e67} +.wst-favo-good{padding-top:2px;margin-left:22px} +.wst-favo-goods{float:left;margin:0 5px} +.wst-favo-goodimg{width:135px;height:135px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-favo-goodimg a{width:135px;height:135px;display:table-cell;vertical-align:middle} +.wst-favo-goodimg a img{max-width:135px;max-height:135px} +.wst-favo-goods span{float:left;width:100%;margin-top:1px;text-align:center;color:#fc6047;font-weight:bold;font-size:15px} +.als-container{position:relative;width:100%;margin:0 auto} +.als-viewport{position:relative;overflow:hidden;margin:0 auto} +.als-wrapper{position:relative;list-style:none} +.als-item{position:relative;display:block;text-align:center;cursor:pointer;float:left} +.als-prev,.als-next{position:absolute;cursor:pointer;clear:both} +.als-item img{width:135px;height:135px;vertical-align:middle} +.als-prev,.als-next{top:40px} +.als-prev{left:-22px} +.als-next{right:-22px} +.goods-info img{margin-top:10px;display:block;float:left} +.goodsName{margin-top:10px;height:50px;line-height:50px;overflow:hidden;float:left} +.appraise-complate{width:980px;min-height:265px;margin-top:10px;border:1px solid #ccc} +.appraise-box{width:980px;height:350px;margin:10px 0;border:1px solid #ccc} +.o-goods-info{width:210px;height:258px;padding-left:5px;padding-top:5px;float:left;overflow:hidden} +.o-goods-info img{width:180px;height:180px} +.appraise-area{word-wrap:break-word;word-break:break-all;padding-top:5px;width:740px;height:100%;float:right} +.appraise-item{width:500px} +.appraise-title{margin-top:3px;float:left;width:70px;font-weight:bold} +.appraise-content{float:left;width:430px} +.complate-content{width:600px;max-height:180px;line-height:24px;overflow:hidden} +.webuploader-pick{height:25px;line-height:25px} +.appraise-btn{cursor:pointer;width:60px;height:30px;background:#e23e3d;border:0;color:#fff;border-radius:3px} +.wst-msg-tips-box{background-color:#f0a869;border-radius:12px;color:white;cursor:pointer;display:inline-block;height:24px;left:30px;line-height:24px;position:relative;text-align:center;top:0;width:24px} +.msgContent{padding:10px} +.wst-sec-but{outline:0;background:#e45050;color:#fff;border:1px solid #d33110;border-radius:3px;cursor:pointer} +.u-btn{width:80px;height:30px;font-weight:bold;cursor:pointer} +.u-btn:hover{background:#ea3232 none repeat scroll 0 0;cursor:pointer} +.s-btn{margin:10px} +.tc{text-align:center} +.g_bd{border:1px solid #f2f2f2} +.pd10{padding:10px} +.my_consultbox{margin:5px 0;width:100%;overflow:hidden} +.my_consult{width:70%;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:left} +.consult_time{float:right;margin-right:1%} +.gc_replytit{color:#ff6c00} +.c999{color:#999} +.gc_a{color:#005ea7} +.gc_a:hover{color:#005ea7} +.order_remaker{color:#ff6c00;padding:5px;border:1px solid #ddd;border-top:0} +.order_from{ margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +.wst-inform-head{float:left;width:100%;border-bottom:1px solid #e45050} +.wst-inform-head span{float:left;line-height:28px;padding:0 28px;color:#fff;background:#e45050;font-weight:bold} +.wst-inform-head a{float:right;line-height:28px;padding:0 28px;color:#fff;background:#e45050} +.wst-inform-box{border-bottom: 1px solid #ddd;height: auto;overflow:hidden;padding: 10px;line-height: 30px;} +.wst-inform-content{margin-right:50px;background:#fff;min-height:948px;height:auto;width:65%;float:left;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-remind{width: 28%;float: left;} +.inform-log-box{line-height: 20px;padding: 20px;} +.wst-inform-box .wst-shopName{ border-bottom: 1px solid #ddd;display: inline-block;width: 20%;text-align:right;} +.wst-inform-box .title{width: 20%;text-align:right;display: inline-block;vertical-align: top;} +.wst-inform-box .goods-img{width: 70%;display: inline-block;} +.wst-inform-box .goods-img .wst-img img{width: 40px;height: 40px;} +.wst-inform-box .goods-img .wst-text a{text-decoration:none;} +.wst-remind .content{float: left;} +.wst-remind .alert {color: #C09853;background-color: #FCF8E3; padding: 9px 14px;border: 1px solid #FBEED5;text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.wst-inform-box .model{width: 20%;height: 100%;display: inline-block;} +.order-box .log-box .state3{margin-left: 10px;} +.order-box .log-box .state3 p {float: left;width: 170px;margin-left: 20px;height: 30px;text-align: left;color: #f05858;font-size: 15px; +} \ No newline at end of file diff --git a/hyhproject/home/view/default/footer.html b/hyhproject/home/view/default/footer.html new file mode 100755 index 0000000..d9102cc --- /dev/null +++ b/hyhproject/home/view/default/footer.html @@ -0,0 +1,134 @@ +<div style="border-top: 1px solid #df2003;padding-bottom:25px;margin-top:35px;min-width:1200px;"></div> +<div class="wst-footer-flink"> + <div class="wst-footer" > + + <div class="wst-footer-cld-box"> + <div class="wst-footer-fl" style="text-align: left;padding-left:10px;">友情链接</div> + + <div style="padding-left:40px;"> + {wst:friendlink cache='86400'} + <div style="float:left;"><a class="flink-hover" href="{$vo['friendlinkUrl']}" target="_blank">{$vo["friendlinkName"]}</a>&nbsp;&nbsp;</div> + {/wst:friendlink} + <div class="wst-clear"></div> + </div> + </div> + + </div> +</div> +<ul class="wst-footer-info"> + <li><div class="wst-footer-info-img wst-fimg1"></div> + <div class="wst-footer-info-text"> + <h1>支付宝支付</h1> + <p>支付宝签约商家</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg2"></div> + <div class="wst-footer-info-text"> + <h1>正品保证</h1> + <p>100%原产地</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg3"></div> + <div class="wst-footer-info-text"> + <h1>退货无忧</h1> + <p>七天退货保障</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg4"></div> + <div class="wst-footer-info-text"> + <h1>免费配送</h1> + <p>满额包邮</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg5"></div> + <div class="wst-footer-info-text"> + <h1>货到付款</h1> + <p>400城市送货上门</p> + </div> + </li> +</ul> +<div class="wst-footer-help"> + <div class="wst-footer"> + <div class="wst-footer-hp-ck1"> + {volist name=":WSTHelps(5,6)" id="vo1"} + <div class="wst-footer-wz-ca"> + <div class="wst-footer-wz-pt"> + <span class="wst-footer-wz-pn">{$vo1["catName"]}</span> + <ul style='margin-left:25px;'> + {volist name="vo1['articlecats']" id="vo2"} + <li style='list-style:disc;color:#999;font-size:12px;'> + <a href="{:Url('Home/Helpcenter/view',array('id'=>$vo2['articleId']))}">{:WSTMSubstr($vo2['articleTitle'],0,8)}</a> + </li> + {/volist} + </ul> + </div> + </div> + {/volist} + + <div class="wst-contact"> + <ul> + <li style="height:30px;"> + <div class="icon-phone"></div><p class="call-wst">服务热线:</p> + </li> + <li style="height:38px;"> + {if(WSTConf('CONF.serviceTel')!='')}<p class="email-wst">{:WSTConf('CONF.serviceTel')}</p>{/if} + </li> + <li style="height:150px;"> + <div class="qr-code" style="position:relative;"> + <img src="__IMGURL__/upload/sysconfigs/app.jpg" style="height:90px;"> + + </span> + {if(WSTConf('CONF.wxenabled')==1) && WSTConf('CONF.wxAppLogo')} + <img src="__IMGURL__/{:WSTConf('CONF.wxAppLogo')}" style="height:110px;"> + {/if} + <div class="focus-wst"> + {if(WSTConf('CONF.serviceQQ')!='')} + <p class="focus-wst-qr">在线客服:</p> + <p class="focus-wst-qra"> + <a href="tencent://message/?uin={:WSTConf('CONF.serviceQQ')}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{:WSTConf('CONF.serviceQQ')}:7" alt="QQ交谈" width="71" height="24" /> + </a> + </p> + {/if} + {if(WSTConf('CONF.serviceEmail')!='')} + <p class="focus-wst-qr">商城邮箱:</p> + <p class="focus-wst-qre">{:WSTConf('CONF.serviceEmail')}</p> + {/if} + </div> + + </div> + <a style="float: left;margin-left: -70px;margin-top:5px; color: #999;">下载APP</a> + </li> + + </ul> + </div> + + + <div class="wst-clear"></div> + </div> + + <div class="wst-footer-hp-ck3"> + <div class="links"> + {php}$navs = WSTNavigations(1);{/php} + {volist name="$navs" id='vo'} + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + {if $i< count($navs)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + <div class="copyright"> + {php} + if(WSTConf('CONF.mallFooter')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.mallFooter')); + } + {/php} + {php} + if(WSTConf('CONF.visitStatistics')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.visitStatistics'))."<br/>"; + } + {/php} + + </div> + </div> + </div> +</div> +{:hook('initCronHook')} \ No newline at end of file diff --git a/hyhproject/home/view/default/header.html b/hyhproject/home/view/default/header.html new file mode 100755 index 0000000..20b534b --- /dev/null +++ b/hyhproject/home/view/default/header.html @@ -0,0 +1,141 @@ +<div class='wst-search-container'> + <div class='wst-logo'> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="120" width='240' title="{:WSTConf('CONF.mallName')}" alt="{:WSTConf('CONF.mallName')}"> + </a> + </div> + <div class="wst-search-box"> + <div class='wst-search'> + <input type="hidden" id="search-type" value="{:isset($keytype)?1:0}"/> + <ul class="j-search-box"> + <li class="j-search-type"> + {if empty($is_icp)}搜<span>{if isset($keytype)}店铺{else}商品{/if}</span>{else /}搜<span>商品&nbsp;</span>{/if}<i class="arrow"> </i> + </li> + {if empty($is_icp)} + <li class="j-type-list"> + {if isset($keytype)} + <div data="0">商品</div> + {else} + <div data="1">店铺</div> + {/if} + </li> + {/if} + </ul> + <input type="text" id='search-ipt' class='search-ipt' placeholder='{:WSTConf("CONF.adsGoodsWordsSearch")}' value='{:isset($keyword)?$keyword:""}'/> + <input type='hidden' id='adsGoodsWordsSearch' value='{:WSTConf("CONF.adsGoodsWordsSearch")}'> + <input type='hidden' id='adsShopWordsSearch' value='{:WSTConf("CONF.adsShopWordsSearch")}'> + <div id='search-btn' class="search-btn" onclick='javascript:WST.search(this.value)'>搜索</div> + </div> + <div class="wst-search-keys"> + {php}$searchKeys = WSTSearchKeys();{/php} + {volist name="$searchKeys" id="vo"} + <a href='{:Url("home/goods/search","keyword=".$vo)}'>{$vo}</a> + {if $i< count($searchKeys)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + </div> + <div class="wst-cart-box"> + <a href="{:url('home/carts/index')}" target="_blank" onclick="WST.currentUrl('{:url("home/carts/index")}');"><span class="word j-word">我的购物车<span class="num" id="goodsTotalNum">0</span></span></a> + <div class="wst-cart-boxs hide"> + <div id="list-carts"></div> + <div id="list-carts2"></div> + <div id="list-carts3"></div> + <div class="wst-clear"></div> + </div> + </div> +{/* 购物车 */} +<script id="list-cart" type="text/html"> +{{# for(var i = 0; i < d.list.length; i++){ }} + <div class="goods" id="j-goods{{ d.list[i].cartId }}"> + <div class="imgs"><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}"><img class="goodsImgc" data-original="__IMGURL__/{{ d.list[i].goodsImg }}" title="{{ d.list[i].goodsName }}"></a></div> + <div class="number"><p><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}">{{WST.cutStr(d.list[i].goodsName,26)}}</a></p><p>数量:{{ d.list[i].cartNum }}</p></div> + <div class="price"><p>¥{{ d.list[i].shopPrice }}</p><span><a href="javascript:WST.delCheckCart({{ d.list[i].cartId }})">删除</a></span></div> + </div> +{{# } }} +</script> +</div> +<div class="wst-clear"></div> +{/* 左侧菜单栏 */} +<div class="wst-nav-menus"> + <div class="nav-w" style="position: relative;"> + <div class="w-spacer"></div> + <div class="dorpdown {if isset($hideCategory)}j-index{/if}" id="wst-categorys"> + <div class="dt j-cate-dt"> + <a href="javascript:void(0)">全部商品分类</a> + </div> + <div class="dd j-cate-dd" {if !isset($hideCategory)}style="display:none" {/if}> + <div class="dd-inner"> + {volist name=":WSTSideCategorys()" id="vo" key="k"} + {php}if($vo['catId']!=389){{/php} + <div id="cat-icon-{$k}" class="item fore1 {if ($key>=12)}over-cat{/if}"> + <h3> + <div class="{if ($key>=12)} over-cat-icon {else /} cat-icon-{$k} {/if}"></div> + <a href="{:Url('home/goods/lists','cat='.$vo['catId'])}" target="_blank">{$vo['catName']}</a> + </h3> + </div> + {php}}{/php} + {/volist} + </div> + <div style="display: none;" class="dorpdown-layer" id="index_menus_sub"> + {volist name=":WSTSideCategorys()" id="vo" key="k"} + <div class="item-sub" i="{$k}"> + <div class="item-brands"> + <div class="brands-inner"> + {wst:brand cat="$vo['catId']" id="bvo" num='6' cache='86400'} + <a target="_blank" class="img-link" href="{:url('home/goods/lists',['cat'=>$bvo['catId'],'brand'=>$bvo['brandId']])}"> + <img width="83" height="65" class='categeMenuImg' data-original="__IMGURL__/{$bvo['brandImg']}"> + </a> + {/wst:brand} + <div class="wst-clear"></div> + </div> + <div class='shop-inner'> + {wst:shop cat="$vo['catId']" id="bvo" num='4' cache='86400'} + <a target="_blank" class="img-link" href="{:url('home/shops/home',['shopId'=>$bvo['shopId']])}"> + <img width="83" height="65" class='categeMenuImg' data-original="__IMGURL__/{$bvo['shopImg']}"> + </a> + {/wst:shop} + <div class="wst-clear"></div> + </div> + </div> + + <div class="subitems"> + {php}if(isset($vo['list'])){{/php} + {volist name="vo['list']" id="vo2"} + <dl class="fore2"> + <dd> + <a + class="cat2_tit" + target="_blank" + href="{:Url('home/goods/lists','cat='.$vo2['catId'])}"> + {$vo2['catName']} + <i>&gt;</i> + </a> + {php}if(isset($vo2['list'])){{/php} + {volist name="vo2['list']" id="vo3"} + <a target="_blank" href="{:Url('home/goods/lists','cat='.$vo3['catId'])}">{$vo3['catName']}</a> + {/volist} + {php}}{/php} + <div class="wst-clear"></div> + </dd> + </dl> + {/volist} + {php}}{/php} + </div> + </div> + {/volist} + </div> + </div> + </div> + {/* 横栏菜单 */} + <div id="wst-nav-items"> + <ul> + {volist name=":WSTNavigations(0)" id='vo'} + <li class="fore1"> + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + </li> + {/volist} + </ul> + </div> + +</div> +<div class="wst-clear"></div> diff --git a/hyhproject/home/view/default/header_lite.html b/hyhproject/home/view/default/header_lite.html new file mode 100755 index 0000000..402615a --- /dev/null +++ b/hyhproject/home/view/default/header_lite.html @@ -0,0 +1,12 @@ +<div class='wst-lite-container'> + <div class='wst-logo'> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="120" width='240' title="{:WSTConf('CONF.mallName')}" alt="{:WSTConf('CONF.mallName')}"> + </a> + </div> + <div class="wst-lite-title">{$liteTitle}</div> + <div class="wst-lite-index"><a href='{$Request.root.true}'>返回首页</a></div> + <div class="wst-clear"></div> +</div> +<div style="border-bottom: 2px solid #df2003;"></div> +<div class="wst-clear"></div> \ No newline at end of file diff --git a/hyhproject/home/view/default/img/alipays.png b/hyhproject/home/view/default/img/alipays.png new file mode 100755 index 0000000..3b1d45b Binary files /dev/null and b/hyhproject/home/view/default/img/alipays.png differ diff --git a/hyhproject/home/view/default/img/apply-ok.png b/hyhproject/home/view/default/img/apply-ok.png new file mode 100755 index 0000000..3a07fc2 Binary files /dev/null and b/hyhproject/home/view/default/img/apply-ok.png differ diff --git a/hyhproject/home/view/default/img/apply.png b/hyhproject/home/view/default/img/apply.png new file mode 100755 index 0000000..42cb90d Binary files /dev/null and b/hyhproject/home/view/default/img/apply.png differ diff --git a/hyhproject/home/view/default/img/arrow.png b/hyhproject/home/view/default/img/arrow.png new file mode 100755 index 0000000..0477c27 Binary files /dev/null and b/hyhproject/home/view/default/img/arrow.png differ diff --git a/hyhproject/home/view/default/img/bgimg_error_spcc.png b/hyhproject/home/view/default/img/bgimg_error_spcc.png new file mode 100755 index 0000000..5b1bd9a Binary files /dev/null and b/hyhproject/home/view/default/img/bgimg_error_spcc.png differ diff --git a/hyhproject/home/view/default/img/bgimg_error_xtcc.png b/hyhproject/home/view/default/img/bgimg_error_xtcc.png new file mode 100755 index 0000000..bc4f0c1 Binary files /dev/null and b/hyhproject/home/view/default/img/bgimg_error_xtcc.png differ diff --git a/hyhproject/home/view/default/img/bgimg_error_ymcc.png b/hyhproject/home/view/default/img/bgimg_error_ymcc.png new file mode 100755 index 0000000..f35298f Binary files /dev/null and b/hyhproject/home/view/default/img/bgimg_error_ymcc.png differ diff --git a/hyhproject/home/view/default/img/btn_80x80.png b/hyhproject/home/view/default/img/btn_80x80.png new file mode 100755 index 0000000..a37c685 Binary files /dev/null and b/hyhproject/home/view/default/img/btn_80x80.png differ diff --git a/hyhproject/home/view/default/img/btn_QQ.png b/hyhproject/home/view/default/img/btn_QQ.png new file mode 100755 index 0000000..88fae04 Binary files /dev/null and b/hyhproject/home/view/default/img/btn_QQ.png differ diff --git a/hyhproject/home/view/default/img/btn_focus.png b/hyhproject/home/view/default/img/btn_focus.png new file mode 100755 index 0000000..2ebb6a1 Binary files /dev/null and b/hyhproject/home/view/default/img/btn_focus.png differ diff --git a/hyhproject/home/view/default/img/btn_pay.png b/hyhproject/home/view/default/img/btn_pay.png new file mode 100755 index 0000000..2da394b Binary files /dev/null and b/hyhproject/home/view/default/img/btn_pay.png differ diff --git a/hyhproject/home/view/default/img/btn_search_red.png b/hyhproject/home/view/default/img/btn_search_red.png new file mode 100755 index 0000000..b4950a7 Binary files /dev/null and b/hyhproject/home/view/default/img/btn_search_red.png differ diff --git a/hyhproject/home/view/default/img/btn_slide_left.png b/hyhproject/home/view/default/img/btn_slide_left.png new file mode 100755 index 0000000..6266133 Binary files /dev/null and b/hyhproject/home/view/default/img/btn_slide_left.png differ diff --git a/hyhproject/home/view/default/img/btn_slide_right.png b/hyhproject/home/view/default/img/btn_slide_right.png new file mode 100755 index 0000000..a63ae0b Binary files /dev/null and b/hyhproject/home/view/default/img/btn_slide_right.png differ diff --git a/hyhproject/home/view/default/img/btn_sqkd_back.png b/hyhproject/home/view/default/img/btn_sqkd_back.png new file mode 100755 index 0000000..5e8be2d Binary files /dev/null and b/hyhproject/home/view/default/img/btn_sqkd_back.png differ diff --git a/hyhproject/home/view/default/img/btn_wechat.png b/hyhproject/home/view/default/img/btn_wechat.png new file mode 100755 index 0000000..88b720a Binary files /dev/null and b/hyhproject/home/view/default/img/btn_wechat.png differ diff --git a/hyhproject/home/view/default/img/close_ads.gif b/hyhproject/home/view/default/img/close_ads.gif new file mode 100755 index 0000000..c040e49 Binary files /dev/null and b/hyhproject/home/view/default/img/close_ads.gif differ diff --git a/hyhproject/home/view/default/img/contrast.png b/hyhproject/home/view/default/img/contrast.png new file mode 100755 index 0000000..b7849e7 Binary files /dev/null and b/hyhproject/home/view/default/img/contrast.png differ diff --git a/hyhproject/home/view/default/img/coupon_bg.png b/hyhproject/home/view/default/img/coupon_bg.png new file mode 100755 index 0000000..0760f3c Binary files /dev/null and b/hyhproject/home/view/default/img/coupon_bg.png differ diff --git a/hyhproject/home/view/default/img/coupon_item1.png b/hyhproject/home/view/default/img/coupon_item1.png new file mode 100755 index 0000000..dfa92a8 Binary files /dev/null and b/hyhproject/home/view/default/img/coupon_item1.png differ diff --git a/hyhproject/home/view/default/img/coupon_item2.png b/hyhproject/home/view/default/img/coupon_item2.png new file mode 100755 index 0000000..a9e04b4 Binary files /dev/null and b/hyhproject/home/view/default/img/coupon_item2.png differ diff --git a/hyhproject/home/view/default/img/coupon_item_bg.png b/hyhproject/home/view/default/img/coupon_item_bg.png new file mode 100755 index 0000000..f623fb9 Binary files /dev/null and b/hyhproject/home/view/default/img/coupon_item_bg.png differ diff --git a/hyhproject/home/view/default/img/cut_bg.png b/hyhproject/home/view/default/img/cut_bg.png new file mode 100755 index 0000000..d3a1b18 Binary files /dev/null and b/hyhproject/home/view/default/img/cut_bg.png differ diff --git a/hyhproject/home/view/default/img/detail_qr_icon.png b/hyhproject/home/view/default/img/detail_qr_icon.png new file mode 100755 index 0000000..2c46deb Binary files /dev/null and b/hyhproject/home/view/default/img/detail_qr_icon.png differ diff --git a/hyhproject/home/view/default/img/error_1.png b/hyhproject/home/view/default/img/error_1.png new file mode 100755 index 0000000..1402e8e Binary files /dev/null and b/hyhproject/home/view/default/img/error_1.png differ diff --git a/hyhproject/home/view/default/img/examine.png b/hyhproject/home/view/default/img/examine.png new file mode 100755 index 0000000..e0c6ec4 Binary files /dev/null and b/hyhproject/home/view/default/img/examine.png differ diff --git a/hyhproject/home/view/default/img/f1_bg.png b/hyhproject/home/view/default/img/f1_bg.png new file mode 100755 index 0000000..4fbac59 Binary files /dev/null and b/hyhproject/home/view/default/img/f1_bg.png differ diff --git a/hyhproject/home/view/default/img/f3_bg.png b/hyhproject/home/view/default/img/f3_bg.png new file mode 100755 index 0000000..79e3076 Binary files /dev/null and b/hyhproject/home/view/default/img/f3_bg.png differ diff --git a/hyhproject/home/view/default/img/f5_bg.png b/hyhproject/home/view/default/img/f5_bg.png new file mode 100755 index 0000000..bd3f48e Binary files /dev/null and b/hyhproject/home/view/default/img/f5_bg.png differ diff --git a/hyhproject/home/view/default/img/f7_bg.png b/hyhproject/home/view/default/img/f7_bg.png new file mode 100755 index 0000000..546880b Binary files /dev/null and b/hyhproject/home/view/default/img/f7_bg.png differ diff --git a/hyhproject/home/view/default/img/flag-each-69x26.png b/hyhproject/home/view/default/img/flag-each-69x26.png new file mode 100755 index 0000000..9db4869 Binary files /dev/null and b/hyhproject/home/view/default/img/flag-each-69x26.png differ diff --git a/hyhproject/home/view/default/img/footer_icon.png b/hyhproject/home/view/default/img/footer_icon.png new file mode 100755 index 0000000..88186e6 Binary files /dev/null and b/hyhproject/home/view/default/img/footer_icon.png differ diff --git a/hyhproject/home/view/default/img/goods_detail_arrow_r.png b/hyhproject/home/view/default/img/goods_detail_arrow_r.png new file mode 100755 index 0000000..5ef5672 Binary files /dev/null and b/hyhproject/home/view/default/img/goods_detail_arrow_r.png differ diff --git a/hyhproject/home/view/default/img/goodsdetails_iconг▀jrdp.png b/hyhproject/home/view/default/img/goodsdetails_iconг▀jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home/view/default/img/goodsdetails_iconг▀jrdp.png differ diff --git a/hyhproject/home/view/default/img/goodsdetails_iconя╝┐jrdp.png b/hyhproject/home/view/default/img/goodsdetails_iconя╝┐jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home/view/default/img/goodsdetails_iconя╝┐jrdp.png differ diff --git a/hyhproject/home/view/default/img/goodspay_img.png b/hyhproject/home/view/default/img/goodspay_img.png new file mode 100755 index 0000000..2a0c36c Binary files /dev/null and b/hyhproject/home/view/default/img/goodspay_img.png differ diff --git a/hyhproject/home/view/default/img/groupon_bg.png b/hyhproject/home/view/default/img/groupon_bg.png new file mode 100755 index 0000000..7096e15 Binary files /dev/null and b/hyhproject/home/view/default/img/groupon_bg.png differ diff --git a/hyhproject/home/view/default/img/ic_volume_24x24.png b/hyhproject/home/view/default/img/ic_volume_24x24.png new file mode 100755 index 0000000..4352277 Binary files /dev/null and b/hyhproject/home/view/default/img/ic_volume_24x24.png differ diff --git a/hyhproject/home/view/default/img/icon-mjzxsy.png b/hyhproject/home/view/default/img/icon-mjzxsy.png new file mode 100755 index 0000000..180e1c8 Binary files /dev/null and b/hyhproject/home/view/default/img/icon-mjzxsy.png differ diff --git a/hyhproject/home/view/default/img/icon_class_zydp.png b/hyhproject/home/view/default/img/icon_class_zydp.png new file mode 100755 index 0000000..9a9c0ab Binary files /dev/null and b/hyhproject/home/view/default/img/icon_class_zydp.png differ diff --git a/hyhproject/home/view/default/img/icon_dianpujie_01.png b/hyhproject/home/view/default/img/icon_dianpujie_01.png new file mode 100755 index 0000000..9498f24 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_dianpujie_01.png differ diff --git a/hyhproject/home/view/default/img/icon_dianpujie_02.png b/hyhproject/home/view/default/img/icon_dianpujie_02.png new file mode 100755 index 0000000..50119e3 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_dianpujie_02.png differ diff --git a/hyhproject/home/view/default/img/icon_dianpujie_03.png b/hyhproject/home/view/default/img/icon_dianpujie_03.png new file mode 100755 index 0000000..b2cb03d Binary files /dev/null and b/hyhproject/home/view/default/img/icon_dianpujie_03.png differ diff --git a/hyhproject/home/view/default/img/icon_dianpujie_04.png b/hyhproject/home/view/default/img/icon_dianpujie_04.png new file mode 100755 index 0000000..9290848 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_dianpujie_04.png differ diff --git a/hyhproject/home/view/default/img/icon_dianpujie_09.png b/hyhproject/home/view/default/img/icon_dianpujie_09.png new file mode 100755 index 0000000..44fe97d Binary files /dev/null and b/hyhproject/home/view/default/img/icon_dianpujie_09.png differ diff --git a/hyhproject/home/view/default/img/icon_fenlei.png b/hyhproject/home/view/default/img/icon_fenlei.png new file mode 100755 index 0000000..36daf9d Binary files /dev/null and b/hyhproject/home/view/default/img/icon_fenlei.png differ diff --git a/hyhproject/home/view/default/img/icon_fenleitubiao.png b/hyhproject/home/view/default/img/icon_fenleitubiao.png new file mode 100755 index 0000000..12577f9 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_fenleitubiao.png differ diff --git a/hyhproject/home/view/default/img/icon_goodsclass_list.png b/hyhproject/home/view/default/img/icon_goodsclass_list.png new file mode 100755 index 0000000..d5b3920 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_goodsclass_list.png differ diff --git a/hyhproject/home/view/default/img/icon_gouwuche.png b/hyhproject/home/view/default/img/icon_gouwuche.png new file mode 100755 index 0000000..495f55c Binary files /dev/null and b/hyhproject/home/view/default/img/icon_gouwuche.png differ diff --git a/hyhproject/home/view/default/img/icon_hdfk.png b/hyhproject/home/view/default/img/icon_hdfk.png new file mode 100755 index 0000000..11fdc44 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_hdfk.png differ diff --git a/hyhproject/home/view/default/img/icon_jinggao.png b/hyhproject/home/view/default/img/icon_jinggao.png new file mode 100755 index 0000000..3f2b36a Binary files /dev/null and b/hyhproject/home/view/default/img/icon_jinggao.png differ diff --git a/hyhproject/home/view/default/img/icon_left.png b/hyhproject/home/view/default/img/icon_left.png new file mode 100755 index 0000000..22897ff Binary files /dev/null and b/hyhproject/home/view/default/img/icon_left.png differ diff --git a/hyhproject/home/view/default/img/icon_login.png b/hyhproject/home/view/default/img/icon_login.png new file mode 100755 index 0000000..265f6aa Binary files /dev/null and b/hyhproject/home/view/default/img/icon_login.png differ diff --git a/hyhproject/home/view/default/img/icon_login02.png b/hyhproject/home/view/default/img/icon_login02.png new file mode 100755 index 0000000..755d8c9 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_login02.png differ diff --git a/hyhproject/home/view/default/img/icon_mfps.png b/hyhproject/home/view/default/img/icon_mfps.png new file mode 100755 index 0000000..8774cc5 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_mfps.png differ diff --git a/hyhproject/home/view/default/img/icon_name.png b/hyhproject/home/view/default/img/icon_name.png new file mode 100755 index 0000000..e8a1401 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_name.png differ diff --git a/hyhproject/home/view/default/img/icon_name2.png b/hyhproject/home/view/default/img/icon_name2.png new file mode 100755 index 0000000..088746f Binary files /dev/null and b/hyhproject/home/view/default/img/icon_name2.png differ diff --git a/hyhproject/home/view/default/img/icon_no.png b/hyhproject/home/view/default/img/icon_no.png new file mode 100755 index 0000000..6607b82 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_no.png differ diff --git a/hyhproject/home/view/default/img/icon_number.png b/hyhproject/home/view/default/img/icon_number.png new file mode 100755 index 0000000..329f881 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_number.png differ diff --git a/hyhproject/home/view/default/img/icon_passard.png b/hyhproject/home/view/default/img/icon_passard.png new file mode 100755 index 0000000..c69523a Binary files /dev/null and b/hyhproject/home/view/default/img/icon_passard.png differ diff --git a/hyhproject/home/view/default/img/icon_passard2.png b/hyhproject/home/view/default/img/icon_passard2.png new file mode 100755 index 0000000..a3c5328 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_passard2.png differ diff --git a/hyhproject/home/view/default/img/icon_play.png b/hyhproject/home/view/default/img/icon_play.png new file mode 100755 index 0000000..53372aa Binary files /dev/null and b/hyhproject/home/view/default/img/icon_play.png differ diff --git a/hyhproject/home/view/default/img/icon_qianbaoyue.png b/hyhproject/home/view/default/img/icon_qianbaoyue.png new file mode 100755 index 0000000..30d0e68 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_qianbaoyue.png differ diff --git a/hyhproject/home/view/default/img/icon_register.png b/hyhproject/home/view/default/img/icon_register.png new file mode 100755 index 0000000..4a92814 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_register.png differ diff --git a/hyhproject/home/view/default/img/icon_right.png b/hyhproject/home/view/default/img/icon_right.png new file mode 100755 index 0000000..c733472 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_right.png differ diff --git a/hyhproject/home/view/default/img/icon_sidernemu.png b/hyhproject/home/view/default/img/icon_sidernemu.png new file mode 100755 index 0000000..dbef865 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_sidernemu.png differ diff --git a/hyhproject/home/view/default/img/icon_success.png b/hyhproject/home/view/default/img/icon_success.png new file mode 100755 index 0000000..d678e43 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_success.png differ diff --git a/hyhproject/home/view/default/img/icon_thwy.png b/hyhproject/home/view/default/img/icon_thwy.png new file mode 100755 index 0000000..0e1ff6e Binary files /dev/null and b/hyhproject/home/view/default/img/icon_thwy.png differ diff --git a/hyhproject/home/view/default/img/icon_time.png b/hyhproject/home/view/default/img/icon_time.png new file mode 100755 index 0000000..ede463e Binary files /dev/null and b/hyhproject/home/view/default/img/icon_time.png differ diff --git a/hyhproject/home/view/default/img/icon_tstb.png b/hyhproject/home/view/default/img/icon_tstb.png new file mode 100755 index 0000000..4a5aff3 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_tstb.png differ diff --git a/hyhproject/home/view/default/img/icon_wyz.png b/hyhproject/home/view/default/img/icon_wyz.png new file mode 100755 index 0000000..2cbd084 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_wyz.png differ diff --git a/hyhproject/home/view/default/img/icon_yanzhengma.png b/hyhproject/home/view/default/img/icon_yanzhengma.png new file mode 100755 index 0000000..74ee520 Binary files /dev/null and b/hyhproject/home/view/default/img/icon_yanzhengma.png differ diff --git a/hyhproject/home/view/default/img/icon_yanzhengma5.png b/hyhproject/home/view/default/img/icon_yanzhengma5.png new file mode 100755 index 0000000..bcccdef Binary files /dev/null and b/hyhproject/home/view/default/img/icon_yanzhengma5.png differ diff --git a/hyhproject/home/view/default/img/icon_zhengpin.png b/hyhproject/home/view/default/img/icon_zhengpin.png new file mode 100755 index 0000000..23f692d Binary files /dev/null and b/hyhproject/home/view/default/img/icon_zhengpin.png differ diff --git a/hyhproject/home/view/default/img/icon_zixun.png b/hyhproject/home/view/default/img/icon_zixun.png new file mode 100755 index 0000000..679385a Binary files /dev/null and b/hyhproject/home/view/default/img/icon_zixun.png differ diff --git a/hyhproject/home/view/default/img/iconfont_fotter.png b/hyhproject/home/view/default/img/iconfont_fotter.png new file mode 100755 index 0000000..47f8092 Binary files /dev/null and b/hyhproject/home/view/default/img/iconfont_fotter.png differ diff --git a/hyhproject/home/view/default/img/iconfont_guanzhu_nor.png b/hyhproject/home/view/default/img/iconfont_guanzhu_nor.png new file mode 100755 index 0000000..d745042 Binary files /dev/null and b/hyhproject/home/view/default/img/iconfont_guanzhu_nor.png differ diff --git a/hyhproject/home/view/default/img/iconfont_guanzhu_sel.png b/hyhproject/home/view/default/img/iconfont_guanzhu_sel.png new file mode 100755 index 0000000..3158d26 Binary files /dev/null and b/hyhproject/home/view/default/img/iconfont_guanzhu_sel.png differ diff --git a/hyhproject/home/view/default/img/img_bg_dlzc.png b/hyhproject/home/view/default/img/img_bg_dlzc.png new file mode 100755 index 0000000..64398bc Binary files /dev/null and b/hyhproject/home/view/default/img/img_bg_dlzc.png differ diff --git a/hyhproject/home/view/default/img/img_bg_goodslist_tjrm.png b/hyhproject/home/view/default/img/img_bg_goodslist_tjrm.png new file mode 100755 index 0000000..0c8471c Binary files /dev/null and b/hyhproject/home/view/default/img/img_bg_goodslist_tjrm.png differ diff --git a/hyhproject/home/view/default/img/img_bg_search.png b/hyhproject/home/view/default/img/img_bg_search.png new file mode 100755 index 0000000..de9e23a Binary files /dev/null and b/hyhproject/home/view/default/img/img_bg_search.png differ diff --git a/hyhproject/home/view/default/img/img_bg_xiala.png b/hyhproject/home/view/default/img/img_bg_xiala.png new file mode 100755 index 0000000..2120132 Binary files /dev/null and b/hyhproject/home/view/default/img/img_bg_xiala.png differ diff --git a/hyhproject/home/view/default/img/img_bg_xpjssel.png b/hyhproject/home/view/default/img/img_bg_xpjssel.png new file mode 100755 index 0000000..12a6ca1 Binary files /dev/null and b/hyhproject/home/view/default/img/img_bg_xpjssel.png differ diff --git a/hyhproject/home/view/default/img/img_cart_bg.png b/hyhproject/home/view/default/img/img_cart_bg.png new file mode 100755 index 0000000..7a52eeb Binary files /dev/null and b/hyhproject/home/view/default/img/img_cart_bg.png differ diff --git a/hyhproject/home/view/default/img/img_dztj_bg.png b/hyhproject/home/view/default/img/img_dztj_bg.png new file mode 100755 index 0000000..a7556ff Binary files /dev/null and b/hyhproject/home/view/default/img/img_dztj_bg.png differ diff --git a/hyhproject/home/view/default/img/img_floor10_titlebg.png b/hyhproject/home/view/default/img/img_floor10_titlebg.png new file mode 100755 index 0000000..55fb9ba Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor10_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor1_titlebg.png b/hyhproject/home/view/default/img/img_floor1_titlebg.png new file mode 100755 index 0000000..a104d90 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor1_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor2_titlebg.png b/hyhproject/home/view/default/img/img_floor2_titlebg.png new file mode 100755 index 0000000..121be83 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor2_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor3_titlebg.png b/hyhproject/home/view/default/img/img_floor3_titlebg.png new file mode 100755 index 0000000..76970c8 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor3_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor4_titlebg.png b/hyhproject/home/view/default/img/img_floor4_titlebg.png new file mode 100755 index 0000000..90f5ea0 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor4_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor5_titlebg.png b/hyhproject/home/view/default/img/img_floor5_titlebg.png new file mode 100755 index 0000000..d7ebbfd Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor5_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor6_titlebg.png b/hyhproject/home/view/default/img/img_floor6_titlebg.png new file mode 100755 index 0000000..c9c8904 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor6_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor7_titlebg.png b/hyhproject/home/view/default/img/img_floor7_titlebg.png new file mode 100755 index 0000000..042ade3 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor7_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor8_titlebg.png b/hyhproject/home/view/default/img/img_floor8_titlebg.png new file mode 100755 index 0000000..32d192c Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor8_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor9_titlebg.png b/hyhproject/home/view/default/img/img_floor9_titlebg.png new file mode 100755 index 0000000..0da98cf Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor9_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_floor_titlebg.png b/hyhproject/home/view/default/img/img_floor_titlebg.png new file mode 100755 index 0000000..a8ce603 Binary files /dev/null and b/hyhproject/home/view/default/img/img_floor_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_gd_sel.png b/hyhproject/home/view/default/img/img_gd_sel.png new file mode 100755 index 0000000..a3422a4 Binary files /dev/null and b/hyhproject/home/view/default/img/img_gd_sel.png differ diff --git a/hyhproject/home/view/default/img/img_icon.png b/hyhproject/home/view/default/img/img_icon.png new file mode 100755 index 0000000..5fbd592 Binary files /dev/null and b/hyhproject/home/view/default/img/img_icon.png differ diff --git a/hyhproject/home/view/default/img/img_jrpp.png b/hyhproject/home/view/default/img/img_jrpp.png new file mode 100755 index 0000000..2e55e10 Binary files /dev/null and b/hyhproject/home/view/default/img/img_jrpp.png differ diff --git a/hyhproject/home/view/default/img/img_login01.png b/hyhproject/home/view/default/img/img_login01.png new file mode 100755 index 0000000..41e5ce0 Binary files /dev/null and b/hyhproject/home/view/default/img/img_login01.png differ diff --git a/hyhproject/home/view/default/img/img_logintitle_bg.png b/hyhproject/home/view/default/img/img_logintitle_bg.png new file mode 100755 index 0000000..9e3397f Binary files /dev/null and b/hyhproject/home/view/default/img/img_logintitle_bg.png differ diff --git a/hyhproject/home/view/default/img/img_majz_titlebg.png b/hyhproject/home/view/default/img/img_majz_titlebg.png new file mode 100755 index 0000000..8f5f1da Binary files /dev/null and b/hyhproject/home/view/default/img/img_majz_titlebg.png differ diff --git a/hyhproject/home/view/default/img/img_mrtx_yh.png b/hyhproject/home/view/default/img/img_mrtx_yh.png new file mode 100755 index 0000000..5f95121 Binary files /dev/null and b/hyhproject/home/view/default/img/img_mrtx_yh.png differ diff --git a/hyhproject/home/view/default/img/img_openshop_bg.png b/hyhproject/home/view/default/img/img_openshop_bg.png new file mode 100755 index 0000000..2c854c8 Binary files /dev/null and b/hyhproject/home/view/default/img/img_openshop_bg.png differ diff --git a/hyhproject/home/view/default/img/img_regist.png b/hyhproject/home/view/default/img/img_regist.png new file mode 100755 index 0000000..9239b4e Binary files /dev/null and b/hyhproject/home/view/default/img/img_regist.png differ diff --git a/hyhproject/home/view/default/img/img_register_main_bg.jpg b/hyhproject/home/view/default/img/img_register_main_bg.jpg new file mode 100755 index 0000000..c3d9cf3 Binary files /dev/null and b/hyhproject/home/view/default/img/img_register_main_bg.jpg differ diff --git a/hyhproject/home/view/default/img/img_scdp.png b/hyhproject/home/view/default/img/img_scdp.png new file mode 100755 index 0000000..d45d601 Binary files /dev/null and b/hyhproject/home/view/default/img/img_scdp.png differ diff --git a/hyhproject/home/view/default/img/img_seller_ggjt.png b/hyhproject/home/view/default/img/img_seller_ggjt.png new file mode 100755 index 0000000..7edd87e Binary files /dev/null and b/hyhproject/home/view/default/img/img_seller_ggjt.png differ diff --git a/hyhproject/home/view/default/img/img_shop.png b/hyhproject/home/view/default/img/img_shop.png new file mode 100755 index 0000000..f5e7cb0 Binary files /dev/null and b/hyhproject/home/view/default/img/img_shop.png differ diff --git a/hyhproject/home/view/default/img/img_sjck.png b/hyhproject/home/view/default/img/img_sjck.png new file mode 100755 index 0000000..8e10870 Binary files /dev/null and b/hyhproject/home/view/default/img/img_sjck.png differ diff --git a/hyhproject/home/view/default/img/img_top_list.png b/hyhproject/home/view/default/img/img_top_list.png new file mode 100755 index 0000000..91c63d6 Binary files /dev/null and b/hyhproject/home/view/default/img/img_top_list.png differ diff --git a/hyhproject/home/view/default/img/img_user.png b/hyhproject/home/view/default/img/img_user.png new file mode 100755 index 0000000..8f5c47c Binary files /dev/null and b/hyhproject/home/view/default/img/img_user.png differ diff --git a/hyhproject/home/view/default/img/img_userlogin_left.png b/hyhproject/home/view/default/img/img_userlogin_left.png new file mode 100755 index 0000000..5bbd3be Binary files /dev/null and b/hyhproject/home/view/default/img/img_userlogin_left.png differ diff --git a/hyhproject/home/view/default/img/img_yingyin.png b/hyhproject/home/view/default/img/img_yingyin.png new file mode 100755 index 0000000..0b1b581 Binary files /dev/null and b/hyhproject/home/view/default/img/img_yingyin.png differ diff --git a/hyhproject/home/view/default/img/index_distribute_bg.png b/hyhproject/home/view/default/img/index_distribute_bg.png new file mode 100755 index 0000000..eae59ba Binary files /dev/null and b/hyhproject/home/view/default/img/index_distribute_bg.png differ diff --git a/hyhproject/home/view/default/img/index_distribute_price_bg.png b/hyhproject/home/view/default/img/index_distribute_price_bg.png new file mode 100755 index 0000000..039bcaa Binary files /dev/null and b/hyhproject/home/view/default/img/index_distribute_price_bg.png differ diff --git a/hyhproject/home/view/default/img/index_link_bg.png b/hyhproject/home/view/default/img/index_link_bg.png new file mode 100755 index 0000000..53dad80 Binary files /dev/null and b/hyhproject/home/view/default/img/index_link_bg.png differ diff --git a/hyhproject/home/view/default/img/integral_bg.png b/hyhproject/home/view/default/img/integral_bg.png new file mode 100755 index 0000000..414901f Binary files /dev/null and b/hyhproject/home/view/default/img/integral_bg.png differ diff --git a/hyhproject/home/view/default/img/intro-bg.png b/hyhproject/home/view/default/img/intro-bg.png new file mode 100755 index 0000000..0102e2d Binary files /dev/null and b/hyhproject/home/view/default/img/intro-bg.png differ diff --git a/hyhproject/home/view/default/img/loading.gif b/hyhproject/home/view/default/img/loading.gif new file mode 100755 index 0000000..e8c2892 Binary files /dev/null and b/hyhproject/home/view/default/img/loading.gif differ diff --git a/hyhproject/home/view/default/img/logo_10.png b/hyhproject/home/view/default/img/logo_10.png new file mode 100755 index 0000000..d567ae2 Binary files /dev/null and b/hyhproject/home/view/default/img/logo_10.png differ diff --git a/hyhproject/home/view/default/img/member_pics.png b/hyhproject/home/view/default/img/member_pics.png new file mode 100755 index 0000000..7958e78 Binary files /dev/null and b/hyhproject/home/view/default/img/member_pics.png differ diff --git a/hyhproject/home/view/default/img/nocite_deliver.png b/hyhproject/home/view/default/img/nocite_deliver.png new file mode 100755 index 0000000..da071f1 Binary files /dev/null and b/hyhproject/home/view/default/img/nocite_deliver.png differ diff --git a/hyhproject/home/view/default/img/notice.png b/hyhproject/home/view/default/img/notice.png new file mode 100755 index 0000000..0ff0965 Binary files /dev/null and b/hyhproject/home/view/default/img/notice.png differ diff --git a/hyhproject/home/view/default/img/order_source_1.png b/hyhproject/home/view/default/img/order_source_1.png new file mode 100755 index 0000000..4b4cacd Binary files /dev/null and b/hyhproject/home/view/default/img/order_source_1.png differ diff --git a/hyhproject/home/view/default/img/order_source_2.png b/hyhproject/home/view/default/img/order_source_2.png new file mode 100755 index 0000000..d7aa4ad Binary files /dev/null and b/hyhproject/home/view/default/img/order_source_2.png differ diff --git a/hyhproject/home/view/default/img/order_source_3.png b/hyhproject/home/view/default/img/order_source_3.png new file mode 100755 index 0000000..d8803fd Binary files /dev/null and b/hyhproject/home/view/default/img/order_source_3.png differ diff --git a/hyhproject/home/view/default/img/order_source_4.png b/hyhproject/home/view/default/img/order_source_4.png new file mode 100755 index 0000000..f83a077 Binary files /dev/null and b/hyhproject/home/view/default/img/order_source_4.png differ diff --git a/hyhproject/home/view/default/img/order_source_5.png b/hyhproject/home/view/default/img/order_source_5.png new file mode 100755 index 0000000..a4f184d Binary files /dev/null and b/hyhproject/home/view/default/img/order_source_5.png differ diff --git a/hyhproject/home/view/default/img/pay_caifutong.png b/hyhproject/home/view/default/img/pay_caifutong.png new file mode 100755 index 0000000..5c676fd Binary files /dev/null and b/hyhproject/home/view/default/img/pay_caifutong.png differ diff --git a/hyhproject/home/view/default/img/pay_liucheng.png b/hyhproject/home/view/default/img/pay_liucheng.png new file mode 100755 index 0000000..69c422e Binary files /dev/null and b/hyhproject/home/view/default/img/pay_liucheng.png differ diff --git a/hyhproject/home/view/default/img/pay_wangyin.png b/hyhproject/home/view/default/img/pay_wangyin.png new file mode 100755 index 0000000..3283863 Binary files /dev/null and b/hyhproject/home/view/default/img/pay_wangyin.png differ diff --git a/hyhproject/home/view/default/img/right_cart.png b/hyhproject/home/view/default/img/right_cart.png new file mode 100755 index 0000000..b4e113e Binary files /dev/null and b/hyhproject/home/view/default/img/right_cart.png differ diff --git a/hyhproject/home/view/default/img/screenshot.png b/hyhproject/home/view/default/img/screenshot.png new file mode 100755 index 0000000..539c26c Binary files /dev/null and b/hyhproject/home/view/default/img/screenshot.png differ diff --git a/hyhproject/home/view/default/img/search.png b/hyhproject/home/view/default/img/search.png new file mode 100755 index 0000000..d13842e Binary files /dev/null and b/hyhproject/home/view/default/img/search.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f1_bg.png b/hyhproject/home/view/default/img/self_shop_f1_bg.png new file mode 100755 index 0000000..9282fe9 Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f1_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f2_bg.png b/hyhproject/home/view/default/img/self_shop_f2_bg.png new file mode 100755 index 0000000..4452449 Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f2_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f3_bg.png b/hyhproject/home/view/default/img/self_shop_f3_bg.png new file mode 100755 index 0000000..eb80200 Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f3_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f4_bg.png b/hyhproject/home/view/default/img/self_shop_f4_bg.png new file mode 100755 index 0000000..eb577c3 Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f4_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f5_bg.png b/hyhproject/home/view/default/img/self_shop_f5_bg.png new file mode 100755 index 0000000..5d600b6 Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f5_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_f6_bg.png b/hyhproject/home/view/default/img/self_shop_f6_bg.png new file mode 100755 index 0000000..a9b1b1d Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_f6_bg.png differ diff --git a/hyhproject/home/view/default/img/self_shop_rec_bg.png b/hyhproject/home/view/default/img/self_shop_rec_bg.png new file mode 100755 index 0000000..718af8d Binary files /dev/null and b/hyhproject/home/view/default/img/self_shop_rec_bg.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_cz.png b/hyhproject/home/view/default/img/seller_icon_cz.png new file mode 100755 index 0000000..8dd48d1 Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_cz.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_error.png b/hyhproject/home/view/default/img/seller_icon_error.png new file mode 100755 index 0000000..738d0a4 Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_error.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_pf_nor.png b/hyhproject/home/view/default/img/seller_icon_pf_nor.png new file mode 100755 index 0000000..60f2670 Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_pf_nor.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_pf_sel.png b/hyhproject/home/view/default/img/seller_icon_pf_sel.png new file mode 100755 index 0000000..ba3197c Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_pf_sel.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_right.png b/hyhproject/home/view/default/img/seller_icon_right.png new file mode 100755 index 0000000..9267e8b Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_right.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_sq.png b/hyhproject/home/view/default/img/seller_icon_sq.png new file mode 100755 index 0000000..0f1ab7a Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_sq.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_xz.png b/hyhproject/home/view/default/img/seller_icon_xz.png new file mode 100755 index 0000000..c4a9afd Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_xz.png differ diff --git a/hyhproject/home/view/default/img/seller_icon_zk.png b/hyhproject/home/view/default/img/seller_icon_zk.png new file mode 100755 index 0000000..e4fcb79 Binary files /dev/null and b/hyhproject/home/view/default/img/seller_icon_zk.png differ diff --git a/hyhproject/home/view/default/img/seller_img_bgnav.png b/hyhproject/home/view/default/img/seller_img_bgnav.png new file mode 100755 index 0000000..a69de99 Binary files /dev/null and b/hyhproject/home/view/default/img/seller_img_bgnav.png differ diff --git a/hyhproject/home/view/default/img/shop_item_bg.jpg b/hyhproject/home/view/default/img/shop_item_bg.jpg new file mode 100755 index 0000000..2e78c27 Binary files /dev/null and b/hyhproject/home/view/default/img/shop_item_bg.jpg differ diff --git a/hyhproject/home/view/default/img/shop_street_bg.png b/hyhproject/home/view/default/img/shop_street_bg.png new file mode 100755 index 0000000..edcf89f Binary files /dev/null and b/hyhproject/home/view/default/img/shop_street_bg.png differ diff --git a/hyhproject/home/view/default/img/shopstreet_bg.png b/hyhproject/home/view/default/img/shopstreet_bg.png new file mode 100755 index 0000000..a189b2f Binary files /dev/null and b/hyhproject/home/view/default/img/shopstreet_bg.png differ diff --git a/hyhproject/home/view/default/img/sprite@1x.png b/hyhproject/home/view/default/img/sprite@1x.png new file mode 100755 index 0000000..fa7f4eb Binary files /dev/null and b/hyhproject/home/view/default/img/sprite@1x.png differ diff --git a/hyhproject/home/view/default/img/star.png b/hyhproject/home/view/default/img/star.png new file mode 100755 index 0000000..b6046b7 Binary files /dev/null and b/hyhproject/home/view/default/img/star.png differ diff --git a/hyhproject/home/view/default/img/store_icon_sq.png b/hyhproject/home/view/default/img/store_icon_sq.png new file mode 100755 index 0000000..e8e8242 Binary files /dev/null and b/hyhproject/home/view/default/img/store_icon_sq.png differ diff --git a/hyhproject/home/view/default/img/store_icon_sx.png b/hyhproject/home/view/default/img/store_icon_sx.png new file mode 100755 index 0000000..eeb4904 Binary files /dev/null and b/hyhproject/home/view/default/img/store_icon_sx.png differ diff --git a/hyhproject/home/view/default/img/store_icon_sx_sel.png b/hyhproject/home/view/default/img/store_icon_sx_sel.png new file mode 100755 index 0000000..c603065 Binary files /dev/null and b/hyhproject/home/view/default/img/store_icon_sx_sel.png differ diff --git a/hyhproject/home/view/default/img/store_icon_sx_sel_up.png b/hyhproject/home/view/default/img/store_icon_sx_sel_up.png new file mode 100755 index 0000000..a8ce6de Binary files /dev/null and b/hyhproject/home/view/default/img/store_icon_sx_sel_up.png differ diff --git a/hyhproject/home/view/default/img/store_icon_zk.png b/hyhproject/home/view/default/img/store_icon_zk.png new file mode 100755 index 0000000..f62902a Binary files /dev/null and b/hyhproject/home/view/default/img/store_icon_zk.png differ diff --git a/hyhproject/home/view/default/img/top_icon_cartdown.png b/hyhproject/home/view/default/img/top_icon_cartdown.png new file mode 100755 index 0000000..0d98d5c Binary files /dev/null and b/hyhproject/home/view/default/img/top_icon_cartdown.png differ diff --git a/hyhproject/home/view/default/img/unionpays.png b/hyhproject/home/view/default/img/unionpays.png new file mode 100755 index 0000000..4078b7a Binary files /dev/null and b/hyhproject/home/view/default/img/unionpays.png differ diff --git a/hyhproject/home/view/default/img/user_bg_nav.png b/hyhproject/home/view/default/img/user_bg_nav.png new file mode 100755 index 0000000..96fc790 Binary files /dev/null and b/hyhproject/home/view/default/img/user_bg_nav.png differ diff --git a/hyhproject/home/view/default/img/user_btn_search.png b/hyhproject/home/view/default/img/user_btn_search.png new file mode 100755 index 0000000..e003c92 Binary files /dev/null and b/hyhproject/home/view/default/img/user_btn_search.png differ diff --git a/hyhproject/home/view/default/img/user_icon_cart.png b/hyhproject/home/view/default/img/user_icon_cart.png new file mode 100755 index 0000000..e7bf631 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_cart.png differ diff --git a/hyhproject/home/view/default/img/user_icon_hyp.png b/hyhproject/home/view/default/img/user_icon_hyp.png new file mode 100755 index 0000000..05821a2 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_hyp.png differ diff --git a/hyhproject/home/view/default/img/user_icon_info.png b/hyhproject/home/view/default/img/user_icon_info.png new file mode 100755 index 0000000..edc3269 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_info.png differ diff --git a/hyhproject/home/view/default/img/user_icon_num.png b/hyhproject/home/view/default/img/user_icon_num.png new file mode 100755 index 0000000..f9cd159 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_num.png differ diff --git a/hyhproject/home/view/default/img/user_icon_rzxx.png b/hyhproject/home/view/default/img/user_icon_rzxx.png new file mode 100755 index 0000000..872cfa4 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_rzxx.png differ diff --git a/hyhproject/home/view/default/img/user_icon_sider_zhankai.png b/hyhproject/home/view/default/img/user_icon_sider_zhankai.png new file mode 100755 index 0000000..abc1e52 Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_sider_zhankai.png differ diff --git a/hyhproject/home/view/default/img/user_icon_yyz.png b/hyhproject/home/view/default/img/user_icon_yyz.png new file mode 100755 index 0000000..c019bde Binary files /dev/null and b/hyhproject/home/view/default/img/user_icon_yyz.png differ diff --git a/hyhproject/home/view/default/img/wallets.png b/hyhproject/home/view/default/img/wallets.png new file mode 100755 index 0000000..e5cb027 Binary files /dev/null and b/hyhproject/home/view/default/img/wallets.png differ diff --git a/hyhproject/home/view/default/img/weixinpays.png b/hyhproject/home/view/default/img/weixinpays.png new file mode 100755 index 0000000..74119ac Binary files /dev/null and b/hyhproject/home/view/default/img/weixinpays.png differ diff --git a/hyhproject/home/view/default/img/wst_qr_code.jpg b/hyhproject/home/view/default/img/wst_qr_code.jpg new file mode 100755 index 0000000..340ba48 Binary files /dev/null and b/hyhproject/home/view/default/img/wst_qr_code.jpg differ diff --git a/hyhproject/home/view/default/img/┤Є╣│.png b/hyhproject/home/view/default/img/┤Є╣│.png new file mode 100755 index 0000000..323ac24 Binary files /dev/null and b/hyhproject/home/view/default/img/┤Є╣│.png differ diff --git a/hyhproject/home/view/default/index.html b/hyhproject/home/view/default/index.html new file mode 100755 index 0000000..b6fc4c6 --- /dev/null +++ b/hyhproject/home/view/default/index.html @@ -0,0 +1 @@ +hello \ No newline at end of file diff --git a/hyhproject/home/view/default/js/apply.js b/hyhproject/home/view/default/js/apply.js new file mode 100755 index 0000000..70fb5c0 --- /dev/null +++ b/hyhproject/home/view/default/js/apply.js @@ -0,0 +1,288 @@ +function initStep2(businessAreaPath,shopAreaIdPath){ + if(businessAreaPath!=''){ + var areaIdPath = businessAreaPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas',isRequire:true} + WST.ITSetAreas(aopts); + } + if(shopAreaIdPath!=''){ + var areaIdPath = shopAreaIdPath.split("_"); + $('#carea_0').val(areaIdPath[0]); + var aopts = {id:'carea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-careas',isRequire:true} + WST.ITSetAreas(aopts); + } + WST.upload({ + pick:'#legalCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#legalCertificateImgMsg').empty().hide(); + $('#legalCertificateImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#legalCertificateImg').val(json.savePath+json.name); + $('#msg_legalCertificateImg').hide(); + } + }, + progress:function(rate){ + $('#legalCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#businessLicenceImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#businessLicenceImgMsg').empty().hide(); + $('#businessLicenceImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#businessLicenceImg').val(json.savePath+json.name); + $('#msg_businessLicenceImg').hide(); + } + }, + progress:function(rate){ + $('#businessLicenceImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#bankAccountPermitImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#bankAccountPermitImgMsg').empty().hide(); + $('#bankAccountPermitImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#bankAccountPermitImg').val(json.savePath+json.name); + $('#msg_bankAccountPermitImg').hide(); + } + }, + progress:function(rate){ + $('#bankAccountPermitImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#organizationCodeImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#organizationCodeImgMsg').empty().hide(); + $('#organizationCodeImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#organizationCodeImg').val(json.savePath+json.name); + $('#msg_organizationCodeImg').hide(); + } + }, + progress:function(rate){ + $('#organizationCodeImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function delVO(obj){ + $(obj).parent().remove(); +} +function initStep3(areaPath){ + if(areaPath!=''){ + var areaIdPath = areaPath.split("_"); + $('#barea_0').val(areaIdPath[0]); + var aopts = {id:'barea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-bareas',isRequire:true} + WST.ITSetAreas(aopts); + } + var uploader = WST.upload({ + pick:'#taxRegistrationCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + fileNumLimit:3, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + $('#taxRegistrationCertificateImgMsg').empty().hide(); + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='step_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#taxRegistrationCertificateImgBox').append(tdiv); + $('#msg_taxRegistrationCertificateImg').hide(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + if($('#taxRegistrationCertificateImgBox').children().size()<=0){ + $('#msg_taxRegistrationCertificateImg').show(); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#taxRegistrationCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#taxpayerQualificationImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#taxpayerQualificationImgMsg').empty().hide(); + $('#taxpayerQualificationImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#taxpayerQualificationImg').val(json.savePath+json.name); + $('#msg_taxpayerQualificationImg').hide(); + } + }, + progress:function(rate){ + $('#taxpayerQualificationImgMsg').show().html('已上传'+rate+"%"); + } + }); +} + +function initStep4(){ + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#shopImgMsg').empty().hide(); + $('#shopImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#shopImg').val(json.savePath+json.name); + $('#msg_shopImg').hide(); + } + }, + progress:function(rate){ + $('#shopImgMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',$('#serviceStartTime').attr('v')); + initTime('#serviceEndTime',$('#serviceEndTime').attr('v')); +} +function initTime(id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $(id).append(html.join('')); +} +function checkProtocol(obj){ + if(obj.checked){ + $('.msg-box').hide(); + }else{ + $('.msg-box').show(); + } +} +function saveStep1(){ + if($('#protocol')[0].checked){ + location.href=WST.U('home/shops/joinStep2'); + }else{ + $('.msg-box').show(); + } +} +function saveStep2(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.a-ipt'); + var load = WST.load({msg:'正在提交请求,请稍后...'}); + $.post(WST.U('home/shops/saveStep2'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep3'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep3(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var p= $('.file-panel').text(); + if(p!=""){ + WST.msg('请先上传补充材料',{icon:6}); + return; + } + var params = WST.getParams('.a-ipt'); + if((params.isLongbusinessDate=='' || params.isLongbusinessDate==0) && params.businessEndDate==''){ + WST.msg('请选择营业期限结束日期',{icon:5}); + return; + } + if((params.isLonglegalCertificateDate=='' || params.isLonglegalCertificateDate==0) && params.legalCertificateEndDate==''){ + WST.msg('请选择法定代表人证件有效期结束日期',{icon:5}); + return; + } + // if((params.isLongOrganizationCodeDate=='' || params.isLongOrganizationCodeDate==0) && params.organizationCodeEndDate==''){ + // WST.msg('请选择组织机构代码证有效期结束日期',{icon:5}); + // return; + // } + params.businessAreaPath0 = WST.ITGetAreaVal('j-areas'); + params.areaIdPath0 = WST.ITGetAreaVal('j-careas'); + var shopAds = []; + $('.j-gallery-img').each(function(){ + shopAds.push($(this).attr('v')); + }); + var a=$('.info').text(); + + params.shopAds = shopAds.join(','); + var load = WST.load({msg:'正在提交请求,请稍后...'}); + $.post(WST.U('home/shops/saveStep3'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep4'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep4(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var load = WST.load({msg:'正在提交请求,请稍后...'}); + var params = WST.getParams('.a-ipt'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + $.post(WST.U('home/shops/saveStep4'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep5'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep5(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var load = WST.load({msg:'正在提交入驻请求,请稍后...'}); + var params = WST.getParams('.a-ipt'); + $.post(WST.U('home/shops/saveStep5'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinSuccess'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/brandslist.js b/hyhproject/home/view/default/js/brandslist.js new file mode 100755 index 0000000..df87200 --- /dev/null +++ b/hyhproject/home/view/default/js/brandslist.js @@ -0,0 +1,33 @@ +//滑过效果 +var nodes = document.querySelectorAll('.wst-brands'), _nodes = [].slice.call(nodes, 0); +var getDirection = function (ev, obj) { + var w = obj.offsetWidth, h = obj.offsetHeight, x = ev.pageX - obj.offsetLeft - w / 2 * (w > h ? h / w : 1), y = ev.pageY - obj.offsetTop - h / 2 * (h > w ? w / h : 1), d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; + return d; +}; +var addClass = function (ev, obj, state) { + var direction = getDirection(ev, obj), class_suffix = ''; + obj.className = ''; + switch (direction) { + case 0: + class_suffix = '-top'; + break; + case 1: + class_suffix = '-right'; + break; + case 2: + class_suffix = '-bottom'; + break; + case 3: + class_suffix = '-left'; + break; + } + obj.classList.add(state + class_suffix); +}; +_nodes.forEach(function (el) { + el.addEventListener('mouseover', function (ev) { + addClass(ev, this, 'in'); + }, false); + el.addEventListener('mouseout', function (ev) { + addClass(ev, this, 'out'); + }, false); +}); \ No newline at end of file diff --git a/hyhproject/home/view/default/js/carts.js b/hyhproject/home/view/default/js/carts.js new file mode 100755 index 0000000..3e50321 --- /dev/null +++ b/hyhproject/home/view/default/js/carts.js @@ -0,0 +1,683 @@ +var promotionMethod = {}; +function checkChks(obj,cobj){ + WST.checkChks(obj,cobj); + var ids = []; + $(cobj).each(function(){ + id = $(this).val(); + if(obj.checked){ + $(this).addClass('selected'); + }else{ + $(this).removeClass('selected'); + } + var cid = $(this).find(".j-chk").val(); + if(cid!='' && typeof(cid)!='undefined'){ + ids.push(cid); + statCartMoney(); + } + }); + batchChangeCartGoods(ids.join(','),obj.checked?1:0); +} +function batchChangeCartGoods(ids,isCheck){ + $.post(WST.U('home/carts/batchChangeCartGoods'),{ids:ids,isCheck:isCheck,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +function statCartMoney(){ + var cartMoney = 0,goodsTotalPrice,id; + $('.j-gchk').each(function(){ + id = $(this).val(); + goodsTotalPrice = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + $('#tprice_'+id).html(goodsTotalPrice.toFixed(2)); + if($(this).prop('checked')){ + cartMoney = cartMoney + goodsTotalPrice; + } + }); + var minusMoney = 0; + for(var key in promotionMethod){ + minusMoney = window[key](cartMoney); + cartMoney = cartMoney - minusMoney; + } + $('#totalMoney').html(cartMoney.toFixed(2)); + checkGoodsBuyStatus(); +} +function checkGoodsBuyStatus(){ + var cartNum = 0,stockNum = 0,cartId = 0; + $('.j-gchk').each(function(){ + cartId = $(this).val(); + cartNum = parseInt($('#buyNum_'+cartId).val(),10); + stockNum = parseInt($(this).attr('sval'),10);; + if(stockNum < 0 || stockNum < cartNum){ + if($(this).prop('checked')){ + $(this).parent().parent().css('border','2px solid red'); + }else{ + $(this).parent().parent().css('border','0px solid #eeeeee'); + $(this).parent().parent().css('border-bottom','1px solid #eeeeee'); + } + if(stockNum < 0){ + $('#gchk_'+cartId).attr('allowbuy',0); + $('#err_'+cartId).css('color','red').html('库存不足'); + }else{ + $('#gchk_'+cartId).attr('allowbuy',1); + $('#err_'+cartId).css('color','red').html('购买量超过库存'); + } + }else{ + $('#gchk_'+cartId).attr('allowbuy',10); + $(this).parent().parent().css('border','0px solid #eeeeee'); + $(this).parent().parent().css('border-bottom','1px solid #eeeeee'); + $('#err_'+cartId).html(''); + } + }); +} +function toSettlement(){ + var isChk = false; + $('.j-gchk').each(function(){ + if($(this).prop('checked'))isChk = true; + }); + if(!isChk){ + WST.msg('请选择要结算的商品!',{icon:1}); + return; + } + var msg = ''; + $('.j-gchk').each(function(){ + if($(this).prop('checked')){ + if($(this).attr('allowbuy')==0){ + msg = '所选商品库存不足'; + return; + }else if($(this).attr('allowbuy')==1){ + msg = '所选商品购买量大于商品库存'; + return; + } + } + }) + if(msg!=''){ + WST.msg(msg,{icon:2}); + return; + } + location.href=WST.U('home/carts/settlement'); +} + +function addrBoxOver(t){ + $(t).addClass('radio-box-hover'); + $(t).find('.operate-box').show(); +} +function addrBoxOut(t){ + $(t).removeClass('radio-box-hover'); + $(t).find('.operate-box').hide(); +} + + + +function setDeaultAddr(id){ + $.post(WST.U('home/useraddress/setDefault'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + getAddressList(); + changeAddrId(id); + } + }); +} + + +function changeAddrId(id){ + $.post(WST.U('home/useraddress/getById'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + inEffect($('#addr-'+id),1); + $('#s_addressId').val(json.data.addressId); + $("select[id^='area_0_']").remove(); + var areaIdPath = json.data.areaIdPath.split("_"); + // 设置收货地区市级id + $('#s_areaId').val(areaIdPath[1]); + + $('#area_0').val(areaIdPath[0]); + // 计算运费 + getCartMoney(); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas'} + WST.ITSetAreas(aopts); + WST.setValues(json.data); + } + }) +} + +function delAddr(id){ + WST.confirm({content:'您确定要删除该地址吗?',yes:function(index){ + $.post(WST.U('home/useraddress/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + getAddressList(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getAddressList(obj){ + var id = $('#s_addressId').val(); + var load = WST.load({msg:'正在加载记录,请稍后...'}); + $.post(WST.U('home/useraddress/listQuery'),{rnd:Math.random()},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(json.data && json.data && json.data.length){ + var html = [],tmp; + for(var i=0;i<json.data.length;i++){ + tmp = json.data[i]; + var selected = (id==tmp.addressId)?'j-selected':''; + html.push( + '<div class="wst-frame1 '+selected+'" onclick="javascript:changeAddrId('+tmp.addressId+')" id="addr-'+tmp.addressId+'" >'+tmp.userName+'<i></i></div>', + '<li class="radio-box" onmouseover="addrBoxOver(this)" onmouseout="addrBoxOut(this)">', + tmp.userName, + '&nbsp;&nbsp;', + tmp.areaName+tmp.userAddress, + '&nbsp;&nbsp;&nbsp;&nbsp;', + tmp.userPhone + ) + if(tmp.isDefault==1){ + html.push('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="j-default">默认地址</span>') + } + html.push('<div class="operate-box">'); + if(tmp.isDefault!=1){ + html.push('<a href="javascript:;" onclick="setDeaultAddr('+tmp.addressId+')">设为默认地址</a>&nbsp;&nbsp;'); + } + html.push('<a href="javascript:void(0)" onclick="javascript:toEditAddress('+tmp.addressId+',this,1,1)">编辑</a>&nbsp;&nbsp;'); + if(json.data.length>1){ + html.push('<a href="javascript:void(0)" onclick="javascript:delAddr('+tmp.addressId+',this)">删除</a></div>'); + } + html.push('<div class="wst-clear"></div>','</li>'); + } + html.push('<a style="color:#1c9eff" onclick="editAddress()" href="javascript:;">收起地址</a>'); + + + $('#addressList').html(html.join('')); + }else{ + $('#addressList').empty(); + } + }else{ + $('#addressList').empty(); + } + }) +} +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function editAddress(){ + var isNoSelected = false; + $('.j-areas').each(function(){ + isSelected = true; + if($(this).val()==''){ + isNoSelected = true; + return; + } + }) + if(isNoSelected){ + WST.msg('请选择完整收货地址!',{icon:2}); + return; + } + layer.close(layerbox); + var load = WST.load({msg:'正在提交数据,请稍后...'}); + var params = WST.getParams('.j-eipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + $.post(WST.U('home/useraddress/'+((params.addressId>0)?'toEdit':'add')),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + $('.j-edit-box').hide(); + $('.j-list-box').hide(); + $('.j-show-box').show(); + if(params.addressId==0){ + $('#s_addressId').val(json.data.addressId); + }else{ + $('#s_addressId').val(params.addressId); + } + var areaIds = WST.ITGetAllAreaVals('area_0','j-areas'); + $('#s_areaId').val(areaIds[1]); + getCartMoney(); + var areaNames = []; + $('.j-areas').each(function(){ + areaNames.push($('#'+$(this).attr('id')+' option:selected').text()); + }) + $('#s_userName').html(params.userName+'<i></i>'); + $('#s_address').html(params.userName+'&nbsp;&nbsp;&nbsp;'+areaNames.join('')+'&nbsp;&nbsp;'+params.userAddress+'&nbsp;&nbsp;'+params.userPhone); + + $('#s_address').siblings('.operate-box').find('a').attr('onclick','toEditAddress('+params.addressId+',this,1,1,1)'); + + if(params.isDefault==1){ + $('#isdefault').html('默认地址').addClass('j-default'); + }else{ + $('#isdefault').html('').removeClass('j-default'); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +var layerbox; +function showEditAddressBox(){ + getAddressList(); + toEditAddress(); +} +function emptyAddress(obj,n){ + inEffect(obj,n); + $('#addressForm')[0].reset(); + $('#s_addressId').val(0); + $('#addressId').val(0); + $("select[id^='area_0_']").remove(); + + layerbox = layer.open({ + title:'用户地址', + type: 1, + area: ['800px', '300px'], + content: $('.j-edit-box') + }); +} +function toEditAddress(id,obj,n,flag,type){ + inEffect(obj,n); + id = (id>0)?id:$('#s_addressId').val(); + $.post(WST.U('home/useraddress/getById'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(flag){ + layerbox = layer.open({ + title:'用户地址', + type: 1, + area: ['800px', '300px'], //宽高 + content: $('.j-edit-box') + }); + } + if(type!=1){ + $('.j-list-box').show(); + $('.j-show-box').hide(); + } + WST.setValues(json.data); + $('input[name="addrUserPhone"]').val(json.data.userPhone) + $("select[id^='area_0_']").remove(); + if(id>0){ + var areaIdPath = json.data.areaIdPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas'} + WST.ITSetAreas(aopts); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#isUseScore').prop('checked')?1:0; + params.useScore = $('#useScore').val(); + params.areaId2 = $('#s_areaId').val(); + params.recordId = $('#recordId').val(); + params.rnd = Math.random(); + params.deliverType = $('#deliverType').val(); + var couponIds = []; + $('.j-shop').each(function(){ + couponIds.push($(this).attr('dataval')+":"+$('#couponId_'+$(this).attr('dataval')).val()); + }); + params.couponIds = couponIds.join(','); + var load = WST.load({msg:'正在计算订单价格,请稍后...'}); + $.post(WST.U('home/carts/getCartMoney'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var shopFreight = 0; + for(var key in json.shops){ + // 设置每间店铺的运费及总价格 + $('#shopF_'+key).html(json.shops[key]['freight']); + $('#shopC_'+key).html(json.shops[key]['goodsMoney']); + shopFreight = shopFreight + json.shops[key]['freight']; + } + $('#maxScoreSpan').html(json.maxScore); + $('#maxScoreMoneySpan').html(Math.round(json.maxScoreMoney*100) / 100); + $('#isUseScore').attr('dataval',json.maxScore); + $('#deliverMoney').html(shopFreight); + $('#useScore').val(json.useScore); + $('#scoreMoney2').html(json.scoreMoney); + $('#totalMoney').html(json.realTotalMoney+'(含运费)'); + $('#orderScore').html((Math.round(json.realTotalMoney*100)/100)); + + } + }); +} +function changeDeliverType(n,index,obj){ + changeSelected(n,index,obj); + getCartMoney(); +} +function submitOrder(){ + var params = WST.getParams('.j-ipt'); + params.isUseScore = $('#isUseScore').prop('checked')?1:0 + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/orders/submit'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/orders/succeed','orderNo='+json.data); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + + +var invoicebox; +function changeInvoice(t,str,obj){ + var param = {}; + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + var loading = WST.load({msg:'正在请求数据,请稍后...'}); + $.post(WST.U('home/invoices/index'),param,function(data){ + layer.close(loading); + // layer弹出层 + invoicebox = layer.open({ + title:'发票信息', + type: 1, + area: ['628px', '420px'], //宽高 + content: data, + success :function(){ + if(param.invoiceId>0){ + $('.inv_codebox').show(); + console.log($('#invoiceCode_'+param.invoiceId)); + $('#invoice_num').val($('#invoiceCode_'+param.invoiceId).val()); + } + }, + }); + }); +} +function layerclose(){ + layer.close(invoicebox); +} + + +function changeInvoiceItem(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('.inv_editing').remove();// 删除正在编辑中的发票信息 + $('.inv_add').show(); + $('#invoiceId').val(t); + if(t==0){ + // 为个人时,隐藏识别号 + $('.inv_codebox').css({display:'none'}); + $('#invoice_num').val(' '); + }else{ + $('#invoice_num').val($('#invoiceCode_'+t).val()); + $('.inv_codebox').css({display:'block'}); + } + $("#invoice_obj").val(t); +} +// 是否需要开发票 +function changeInvoiceItem1(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('#isInvoice').val(t); +} +// 显示发票增加 +function invAdd(){ + $("#invoiceId").val(0); + $("#invoice_obj").val(1); + $('#invoice_num').val(''); + $('.inv_li').removeClass('inv_li_curr');// 移除当前选中样式 + $('.inv_ul').append('<li class="inv_li inv_li_curr inv_editing"><input type="text" id="invoiceHead" placeholder="新增单位发票抬头" value="" style="width:65%;height:21px;padding:1px;"><i></i><div style="top:8px;" class="inv_opabox"><a href="javascript:void(0)" onCLick="addInvoice()">保存</a></div></li>'); + $('.inv_ul').scrollTop($('.inv_ul')[0].scrollHeight);// 滚动到底部 + $('.inv_add').hide();// 隐藏新增按钮 + $('.inv_codebox').css({display:'block'});// 显示`纳税人识别号` +} +// 执行发票抬头新增 +function addInvoice(){ + var head = $('#invoiceHead').val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/add'),{invoiceHead:head},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + $('#invoiceId').val(json.data.id); + WST.msg(json.msg,{icon:1}); + $('.inv_editing').remove(); + var code = []; + code.push('<li class=\'inv_li inv_li_curr\' onClick="changeInvoiceItem(\''+json.data.id+'\',this)">'); + code.push('<input type="text" value="'+head+'" readonly="readonly" class="invoice_input" id="invoiceHead_'+json.data.id+'" />'); + code.push('<input type="hidden" id="invoiceCode_'+json.data.id+'" value=""} /><i></i>'); + code.push('<div class="inv_opabox">'); + code.push('<a href=\'javascript:void(0)\' onClick="invEdit(\''+json.data.id+'\',this)" class="edit_btn">编辑</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="editInvoice(\''+json.data.id+'\',this)" style="display:none;" class="save_btn">保存</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="delInvoice(\''+json.data.id+'\',this)">删除</a></div></li>'); + $('.inv_li:first').after(code.join('')); + // 显示新增按钮 + $('.inv_add').show(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +// 显示发票修改 +function invEdit(id,obj){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.removeAttr('readonly').focus(); + input.mouseup(function(){return false}); + $(obj).parent().parent().mouseup(function(){ + input.attr('readonly','readonly'); + $(obj).show().siblings('.save_btn').hide(); + }); + $(obj).hide().siblings('.save_btn').show(); + var invoice_code = $('#invoiceCode_'+id).val(); + $('.inv_codebox').css({display:'block'}) + $('#invoice_num').val(invoice_code);// 显示`纳税人识别号`) +} +// 完成发票修改 +function editInvoice(id,obj){ + var head = $('#invoiceHead_'+id).val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + alert(111); + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/edit'),{invoiceHead:head,id:id},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.attr('readonly','readonly') + $(obj).hide().siblings('.edit_btn').show(); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +// 设置页面显示值 +function setInvoiceText(invoiceHead){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)'+invoiceHead+' 明细'; + } + $('#invoice_info').html(text); + layerclose(); +} + +// 保存纳税人识别号 +function saveInvoice(){ + var isInv = $('#isInvoice').val(); + var num = $('#invoice_num').val(); + var id = $('#invoiceId').val(); + var invoiceHead = $('#invoiceHead').val();// 发票抬头 + var url = WST.U('home/Invoices/add'); + var params = {}; + if(id>0){ + url = WST.U('home/Invoices/edit'); + invoiceHead = $('#invoiceHead_'+id).val();// 发票抬头 + params.id = id; + } + params.invoiceHead = invoiceHead; + params.invoiceCode = num; + if($('#invoice_obj').val()!=0){ + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(url,params,function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + // 判断用户是否需要发票 + setInvoiceText(invoiceHead); + if(id==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }else{ + setInvoiceText(''); + } +} +// 删除发票信息 +function delInvoice(id,obj){ + WST.confirm({content:'您确定要删除该发票信息吗?',yes:function(index){ + $.post(WST.U('home/invoices/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).parent().parent().remove(); + $('#invoiceId').val(0); + // 选中 `个人` + $('.inv_li:first').click(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + + + +function changeSelected(n,index,obj){ + $('#'+index).val(n); + inEffect(obj,2); +} + +function getPayUrl(){ + var params = {}; + params.payObj = "orderPay"; + params.orderNo = $("#orderNo").val(); + params.isBatch = $("#isBatch").val(); + params.payCode = $.trim($("#payCode").val()); + if(params.payCode==""){ + WST.msg('请先选择支付方式', {icon: 5}); + return; + } + + jQuery.post(WST.U('home/'+params.payCode+'/get'+params.payCode+"Url"),params,function(data) { + var json = WST.toJson(data); + if(json.status==1){ + if(params.payCode=="weixinpays" || params.payCode=="wallets"){ + location.href = json.url; + }else{ + if(params.payCode=="unionpays"){ + location.href = WST.U('home/unionpays/tounionpays',params); + }else{ + location.href = json.url; + } + } + }else{ + WST.msg('您的订单已支付!', {icon: 5,time:1500},function(){ + window.location = WST.U('home/orders/waitReceive'); + }); + } + }); +} + +function payByWallet(){ + var params = WST.getParams('.j-ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.payPwd = rsa.encrypt(params.payPwd); + } + var load = WST.load({msg:'正在核对支付密码,请稍后...'}); + $.post(WST.U('home/wallets/payByWallet'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1,time:1500},function(){ + window.location = WST.U('home/orders/waitReceive'); + }); + }else{ + WST.msg(json.msg,{icon:2,time:1500}); + } + }); +} + +function checkScoreBox(v){ + if(v){ + var val = $('#isUseScore').attr('dataval'); + $('#useScore').val(val); + $('#scoreMoney').show(); + + }else{ + $('#scoreMoney').hide(); + } + getCartMoney(); +} + +function setPaypwd(){ + layerbox = layer.open({ + title:['设置支付密码','text-align:left'], + type: 1, + area: ['450px', '240px'], + content: $('.j-paypwd-box'), + btn: ['设置支付密码,并支付订单', '关闭'], + yes: function(index, layero){ + var newPass = $.trim($("#payPwd").val()); + var reNewPass = $.trim($("#reNewPass").val()); + if(newPass==""){ + WST.msg("请输入支付密码!"); + return false; + } + if(reNewPass==""){ + WST.msg("请输入确认支付密码!"); + return false; + } + if(newPass!=reNewPass){ + WST.msg("密码不一致!"); + return false; + } + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + newPass = rsa.encrypt(newPass); + reNewPass = rsa.encrypt(reNewPass); + } + var load = WST.load({msg:'正在提交支付密码,请稍后...'}); + $.post(WST.U('home/users/payPassEdit'),{newPass:newPass,reNewPass:reNewPass},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1,time:1500},function(){ + layer.close(layerbox); + payByWallet(); + }); + }else{ + WST.msg(json.msg,{icon:2,time:1500}); + } + }); + + return false; + }, + btn2: function(index, layero){} + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/carts_quick.js b/hyhproject/home/view/default/js/carts_quick.js new file mode 100755 index 0000000..e553b8c --- /dev/null +++ b/hyhproject/home/view/default/js/carts_quick.js @@ -0,0 +1,256 @@ +function submitOrder(){ + var params = WST.getParams('.j-ipt'); + params.isUseScore = $('#isUseScore').prop('checked')?1:0 + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/orders/quickSubmit'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/orders/succeed','orderNo='+json.data); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + inEffect(obj,2); +} +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#isUseScore').prop('checked')?1:0; + params.useScore = $('#useScore').val(); + params.rnd = Math.random(); + params.deliverType = 1; + var couponIds = []; + $('.j-shop').each(function(){ + couponIds.push($(this).attr('dataval')+":"+$('#couponId_'+$(this).attr('dataval')).val()); + }); + params.couponIds = couponIds.join(','); + var load = WST.load({msg:'正在计算订单价格,请稍后...'}); + $.post(WST.U('home/carts/getQuickCartMoney'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + for(var key in json.shops){ + $('#shopC_'+key).html(json.shops[key]['goodsMoney']); + } + $('#maxScoreSpan').html(json.maxScore); + $('#maxScoreMoneySpan').html(json.maxScoreMoney); + $('#isUseScore').attr('dataval',json.maxScore); + $('#useScore').val(json.useScore); + $('#scoreMoney2').html(json.scoreMoney); + $('#totalMoney').html(json.realTotalMoney); + } + }); +} +function checkScoreBox(v){ + if(v){ + var val = $('#isUseScore').attr('dataval'); + $('#useScore').val(val); + $('#scoreMoney').show(); + }else{ + $('#scoreMoney').hide(); + } + getCartMoney(); +} + + +var invoicebox; +function changeInvoice(t,str,obj){ + var param = {}; + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + var loading = WST.load({msg:'正在请求数据,请稍后...'}); + $.post(WST.U('home/invoices/index'),param,function(data){ + layer.close(loading); + // layer弹出层 + invoicebox = layer.open({ + title:'发票信息', + type: 1, + area: ['628px', '420px'], //宽高 + content: data, + success :function(){ + if(param.invoiceId>0){ + $('.inv_codebox').show(); + console.log($('#invoiceCode_'+param.invoiceId)); + $('#invoice_num').val($('#invoiceCode_'+param.invoiceId).val()); + } + }, + }); + }); +} +function layerclose(){ + layer.close(invoicebox); +} + + +function changeInvoiceItem(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('.inv_editing').remove();// 删除正在编辑中的发票信息 + $('.inv_add').show(); + $('#invoiceId').val(t); + if(t==0){ + // 为个人时,隐藏识别号 + $('.inv_codebox').css({display:'none'}); + $('#invoice_num').val(' '); + }else{ + $('#invoice_num').val($('#invoiceCode_'+t).val()); + $('.inv_codebox').css({display:'block'}); + } + $("#invoice_obj").val(t); +} +// 是否需要开发票 +function changeInvoiceItem1(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('#isInvoice').val(t); +} +// 显示发票增加 +function invAdd(){ + $("#invoiceId").val(0); + $("#invoice_obj").val(1); + $('#invoice_num').val(''); + $('.inv_li').removeClass('inv_li_curr');// 移除当前选中样式 + $('.inv_ul').append('<li class="inv_li inv_li_curr inv_editing"><input type="text" id="invoiceHead" placeholder="新增单位发票抬头" value="" style="width:65%;height:20px;padding:1px;"><i></i><div style="top:8px;" class="inv_opabox"><a href="javascript:void(0)" onCLick="addInvoice()">保存</a></div></li>'); + $('.inv_ul').scrollTop($('.inv_ul')[0].scrollHeight);// 滚动到底部 + $('.inv_add').hide();// 隐藏新增按钮 + $('.inv_codebox').css({display:'block'});// 显示`纳税人识别号` +} +// 执行发票抬头新增 +function addInvoice(){ + var head = $('#invoiceHead').val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/add'),{invoiceHead:head},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $('.inv_editing').remove(); + var code = []; + code.push('<li class=\'inv_li inv_li_curr\' onClick="changeInvoiceItem(\''+json.data.id+'\',this)">'); + code.push('<input type="text" value="'+head+'" readonly="readonly" class="invoice_input" id="invoiceHead_'+json.data.id+'" />'); + code.push('<input type="hidden" id="invoiceCode_'+json.data.id+'" value=""} /><i></i>'); + code.push('<div class="inv_opabox">'); + code.push('<a href=\'javascript:void(0)\' onClick="invEdit(\''+json.data.id+'\',this)" class="edit_btn">编辑</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="editInvoice(\''+json.data.id+'\',this)" style="display:none;" class="save_btn">保存</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="delInvoice(\''+json.data.id+'\',this)">删除</a></div></li>'); + $('.inv_li:first').after(code.join('')); + // 显示新增按钮 + $('.inv_add').show(); + // 修改invoiceId + $('#invoiceId').val(json.data.id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +// 显示发票修改 +function invEdit(id,obj){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.removeAttr('readonly').focus(); + input.mouseup(function(){return false}); + $(obj).parent().parent().mouseup(function(){ + input.attr('readonly','readonly'); + $(obj).show().siblings('.save_btn').hide(); + }); + $(obj).hide().siblings('.save_btn').show(); + var invoice_code = $('#invoiceCode_'+id).val(); + $('.inv_codebox').css({display:'block'}) + $('#invoice_num').val(invoice_code);// 显示`纳税人识别号`) +} +// 完成发票修改 +function editInvoice(id,obj){ + var head = $('#invoiceHead_'+id).val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/edit'),{invoiceHead:head,id:id},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.attr('readonly','readonly') + $(obj).hide().siblings('.edit_btn').show(); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +// 设置页面显示值 +function setInvoiceText(invoiceHead){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)'+invoiceHead+' 明细'; + } + $('#invoice_info').html(text); + layerclose(); +} + + +// 保存纳税人识别号 +function saveInvoice(){ + var isInv = $('#isInvoice').val(); + var num = $('#invoice_num').val(); + var id = $('#invoiceId').val(); + var invoiceHead = $('#invoiceHead').val();// 发票抬头 + var url = WST.U('home/Invoices/add'); + var params = {}; + if(id>0){ + url = WST.U('home/Invoices/edit'); + invoiceHead = $('#invoiceHead_'+id).val();// 发票抬头 + params.id = id; + } + params.invoiceHead = invoiceHead; + params.invoiceCode = num; + if($('#invoice_obj').val()!=0){ + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(url,params,function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + // 判断用户是否需要发票 + setInvoiceText(invoiceHead); + if(id==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }else{ + setInvoiceText(''); + } +} + +// 删除发票信息 +function delInvoice(id,obj){ + WST.confirm({content:'您确定要删除该发票信息吗?',yes:function(index){ + $.post(WST.U('home/invoices/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).parent().parent().remove(); + $('#invoiceId').val(0); + // 选中 `个人` + $('.inv_li:first').click(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} diff --git a/hyhproject/home/view/default/js/cloudzoom.js b/hyhproject/home/view/default/js/cloudzoom.js new file mode 100755 index 0000000..bf92172 --- /dev/null +++ b/hyhproject/home/view/default/js/cloudzoom.js @@ -0,0 +1,933 @@ +/* + Version 3.1 +*/ +(function(e) { + function s(a) { + var b = a.zoom, + c = a.Q, + g = a.R, + k = a.e, + f = a.g; + this.data = a; + this.U = this.b = null; + this.za = 0; + this.zoom = b; + this.V = !0; + this.r = this.interval = this.t = this.p = 0; + var q = this, + m; + q.b = e("<div class='" + a.K + "' style='position:absolute;overflow:hidden'></div>"); + var p = e("<img style='-webkit-touch-callout:none;position:absolute;max-width:none' src='" + v(b.T, b.options) + "'/>"); + b.options.variableMagnification && p.bind("mousewheel", + function(a, b) { + q.zoom.ia(0.1 * b); + return ! 1 + }); + q.U = p; + p.width(q.zoom.e); + p.height(q.zoom.g); + d.Ja && q.U.css("-webkit-transform", "perspective(400px)"); + var l = q.b; + l.append(p); + var h = e("<div style='position:absolute;'></div>"); + a.caption ? ("html" == b.options.captionType ? m = a.caption: "attr" == b.options.captionType && (m = e("<div class='cloudzoom-caption'>" + a.caption + "</div>")), m.css("display", "block"), h.css({ + width: k + }), l.append(h), h.append(m), e("body").append(l), this.r = m.outerHeight(), "bottom" == b.options.captionPosition ? h.css("top", f) : (h.css("top", 0), this.za = this.r)) : e("body").append(l); + l.css({ + opacity: 0, + width: k, + height: f + this.r + }); + this.zoom.C = "auto" === b.options.minMagnification ? Math.max(k / b.a.width(), f / b.a.height()) : b.options.minMagnification; + this.zoom.B = "auto" === b.options.maxMagnification ? p.width() / b.a.width() : b.options.maxMagnification; + a = l.height(); + this.V = !1; + b.options.zoomFlyOut ? (f = b.a.offset(), f.left += b.d / 2, f.top += b.c / 2, l.offset(f), l.width(0), l.height(0), l.animate({ + left: c, + top: g, + width: k, + height: a, + opacity: 1 + }, + { + duration: b.options.animationTime, + complete: function() { + q.V = !0 + } + })) : (l.offset({ + left: c, + top: g + }), l.width(k), l.height(a), l.animate({ + opacity: 1 + }, + { + duration: b.options.animationTime, + complete: function() { + q.V = !0 + } + })) + } + function x(a, b, c) { + this.a = a; + this.ba = a[0]; + this.Ca = c; + this.va = !0; + var g = this; + this.interval = setInterval(function() { + 0 < g.ba.width && 0 < g.ba.height && (clearInterval(g.interval), g.va = !1, g.Ca(a)) + }, + 100); + this.ba.src = b + } + function d(a, b) { + function c() { + k.update(); + window.Qa(c) + } + function g() { + var c; + c = "" != b.image ? b.image: "" + a.attr("src"); + k.sa(); + b.lazyLoadZoom ? a.bind("touchstart.preload " + k.options.mouseTriggerEvent + ".preload", + function() { + k.O(c, b.zoomImage) + }) : k.O(c, b.zoomImage) + } + var k = this; + b = e.extend({},e.fn.CloudZoom.defaults, b); + var f = d.qa(a, e.fn.CloudZoom.attr); + b = e.extend({},b, f); + 1 > b.easing && (b.easing = 1); + f = a.parent(); + f.is("a") && "" == b.zoomImage && (b.zoomImage = f.attr("href"), f.removeAttr("href")); + f = e("<div class='" + b.zoomClass + "'</div>"); + e("body").append(f); + this.Z = f.width(); + this.Y = f.height(); + b.zoomWidth && (this.Z = b.zoomWidth, this.Y = b.zoomHeight); + f.remove(); + this.options = b; + this.a = a; + this.g = this.e = this.d = this.c = 0; + this.H = this.m = null; + this.j = this.n = 0; + this.D = { + x: 0, + y: 0 + }; + this.Ua = this.caption = ""; + this.ea = { + x: 0, + y: 0 + }; + this.k = []; + this.pa = 0; + this.oa = ""; + this.b = this.v = this.u = null; + this.T = ""; + this.L = this.S = this.aa = !1; + this.G = null; + this.ha = this.Oa = !1; + this.l = null; + this.id = ++d.id; + this.I = this.ua = this.ta = 0; + this.o = this.h = null; + this.wa = this.B = this.C = this.f = this.i = this.ja = 0; + this.na(a); + this.ma = !1; + this.N = this.A = this.da = this.ca = 0; + if (a.is(":hidden")) var q = setInterval(function() { + a.is(":hidden") || (clearInterval(q), g()) + }, + 100); + else g(); + c() + } + function v(a, b) { + var c = b.uriEscapeMethod; + return "escape" == c ? escape(a) : "encodeURI" == c ? encodeURI(a) : a + } + function h(a) { + for (var b = "", + c, g = C("charCodeAt"), d = a[g](0) - 32, e = 1; e < a.length - 1; e++) c = a[g](e), + c ^= d & 31, + d++, + b += String[C("fromCharCode")](c); + a[g](e); + return b + } + function C(a) { + return a; + } + function y(a) { + var b = a || window.event, + c = [].slice.call(arguments, 1), + g = 0, + d = 0, + f = 0; + a = e.event.fix(b); + a.type = "mousewheel"; + b.wheelDelta && (g = b.wheelDelta / 120); + b.detail && (g = -b.detail / 3); + f = g; + void 0 !== b.axis && b.axis === b.HORIZONTAL_AXIS && (f = 0, d = -1 * g); + void 0 !== b.wheelDeltaY && (f = b.wheelDeltaY / 120); + void 0 !== b.wheelDeltaX && (d = -1 * b.wheelDeltaX / 120); + c.unshift(a, g, d, f); + return (e.event.dispatch || e.event.handle).apply(this, c) + } + var t = ["DOMMouseScroll", "mousewheel"]; + if (e.event.fixHooks) for (var n = t.length; n;) e.event.fixHooks[t[--n]] = e.event.mouseHooks; + e.event.special.mousewheel = { + setup: function() { + if (this.addEventListener) for (var a = t.length; a;) this.addEventListener(t[--a], y, !1); + else this.onmousewheel = y + }, + teardown: function() { + if (this.removeEventListener) for (var a = t.length; a;) this.removeEventListener(t[--a], y, !1); + else this.onmousewheel = null + } + }; + e.fn.extend({ + mousewheel: function(a) { + return a ? this.bind("mousewheel", a) : this.trigger("mousewheel") + }, + unmousewheel: function(a) { + return this.unbind("mousewheel", a) + } + }); + window.Qa = function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || + function(a) { + window.setTimeout(a, 20) + } + } (); + var n = document.getElementsByTagName("script"), + w = n[n.length - 1].src.lastIndexOf("/"), + z; + z = "undefined" != typeof window.CloudZoom ? window.CloudZoom.path: n[n.length - 1].src.slice(0, w); + var n = window, + D = n[h("$Bphd|`ee&")], + u = !0, + E = !1, + F = h("%KISIYZ2"), + w = h("&VRZJBJ_HJ?").length, + A = !1, + B = !1; + 5 == w ? B = !0 : 4 == w && (A = !0); + d.xa = 1E9; + e(window).bind("resize.cloudzoom", + function() { + d.xa = e(this).width() + }); + e(window).trigger("resize.cloudzoom"); + d.prototype.J = function() { + return "inside" === this.options.zoomPosition || d.xa <= this.options.autoInside ? !0 : !1 + }; + d.prototype.update = function() { + var a = this.h; + null != a && (this.q(this.D, 0), this.f != this.i && (this.i += (this.f - this.i) / this.options.easing, 1E-4 > Math.abs(this.f - this.i) && (this.i = this.f), this.Na()), a.update()) + }; + d.id = 0; + d.prototype.Ha = function(a) { + var b = this.T.replace(/^\/|\/$/g, ""); + if (0 == this.k.length) return { + href: this.options.zoomImage, + title: this.a.attr("title") + }; + if (void 0 != a) return this.k; + a = []; + for (var c = 0; c < this.k.length && this.k[c].href.replace(/^\/|\/$/g, "") != b; c++); + for (b = 0; b < this.k.length; b++) a[b] = this.k[c], + c++, + c >= this.k.length && (c = 0); + return a + }; + d.prototype.getGalleryList = d.prototype.Ha; + d.prototype.P = function() { + clearTimeout(this.ja); + null != this.o && this.o.remove() + }; + d.prototype.sa = function() { + var a = this; + this.Oa || this.a.bind("mouseover.prehov mousemove.prehov mouseout.prehov", + function(b) { + a.G = "mouseout" == b.type ? null: { + pageX: b.pageX, + pageY: b.pageY + } + }) + }; + d.prototype.Ea = function() { + this.G = null; + this.a.unbind("mouseover.prehov mousemove.prehov mouseout.prehov") + }; + d.prototype.O = function(a, b) { + var c = this; + c.a.unbind("touchstart.preload " + c.options.mouseTriggerEvent + ".preload"); + c.sa(); + this.P(); + e("body").children(".cloudzoom-fade-" + c.id).remove(); + null != this.v && (this.v.cancel(), this.v = null); + null != this.u && (this.u.cancel(), this.u = null); + this.T = "" != b && void 0 != b ? b: a; + this.L = this.S = !1; ! c.options.galleryFade || !c.aa || c.J() && null != c.h || (c.l = e(new Image).css({ + position: "absolute" + }), c.l.attr("src", c.a.attr("src")), c.l.width(c.a.width()), c.l.height(c.a.height()), c.l.offset(c.a.offset()), c.l.addClass("cloudzoom-fade-" + c.id), e("body").append(c.l)); + this.Ma(); + var g = e(new Image); + this.u = new x(g, a, + function(a, b) { + c.u = null; + c.L = !0; + c.a.attr("src", g.attr("src")); + e("body").children(".cloudzoom-fade-" + c.id).fadeOut(c.options.fadeTime, + function() { + e(this).remove(); + c.l = null + }); + void 0 !== b ? (c.P(), c.options.errorCallback({ + $element: c.a, + type: "IMAGE_NOT_FOUND", + data: b.Ga + })) : c.ra() + }) + }; + d.prototype.Ma = function() { + var a = this; + a.ja = setTimeout(function() { + a.o = e("<div class='cloudzoom-ajax-loader' style='position:absolute;left:0px;top:0px'/>"); + e("body").append(a.o); + var b = a.o.width(), + g = a.o.height(), + b = a.a.offset().left + a.a.width() / 2 - b / 2, + g = a.a.offset().top + a.a.height() / 2 - g / 2; + a.o.offset({ + left: b, + top: g + }) + }, + 250); + var b = e(new Image); + this.v = new x(b, this.T, + function(c, g) { + a.v = null; + a.S = !0; + a.e = b[0].width; + a.g = b[0].height; + void 0 !== g ? (a.P(), a.options.errorCallback({ + $element: a.a, + type: "IMAGE_NOT_FOUND", + data: g.Ga + })) : a.ra() + }) + }; + d.prototype.loadImage = d.prototype.O; + d.prototype.Ba = function() { + alert("Cloud Zoom API OK") + }; + d.prototype.apiTest = d.prototype.Ba; + d.prototype.s = function() { + null != this.h && (this.a.trigger("cloudzoom_end_zoom"), this.h.$()); + this.h = null + }; + d.prototype.$ = function() { + e(document).unbind("mousemove." + this.id); + this.a.unbind(); + null != this.b && (this.b.unbind(), this.s()); + this.a.removeData("CloudZoom"); + e("body").children(".cloudzoom-fade-" + this.id).remove(); + this.ma = !0 + }; + d.prototype.destroy = d.prototype.$; + d.prototype.Da = function(a) { + if (!this.options.hoverIntentDelay) return ! 1; + 0 === this.A && (this.A = (new Date).getTime(), this.ca = a.pageX, this.da = a.pageY); + var b = a.pageX - this.ca, + c = a.pageY - this.da, + b = Math.sqrt(b * b + c * c); + this.ca = a.pageX; + this.da = a.pageY; + a = (new Date).getTime(); + b <= this.options.hoverIntentDistance ? this.N += a - this.A: this.A = a; + if (this.N < this.options.hoverIntentDelay) return ! 0; + this.N = this.A = 0; + return ! 1 + }; + d.prototype.W = function() { + var a = this; + a.a.bind(a.options.mouseTriggerEvent + ".trigger", + function(b) { + if (!a.X() && null == a.b && !a.Da(b)) { + var c = a.a.offset(); + b = new d.F(b.pageX - c.left, b.pageY - c.top); + a.M(); + a.w(); + a.q(b, 0); + a.D = b + } + }) + }; + d.prototype.X = function() { + if (this.ma || !this.S || !this.L) return ! 0; + if (!1 === this.options.disableZoom) return ! 1; + if (!0 === this.options.disableZoom) return ! 0; + if ("auto" == this.options.disableZoom) { + if (!isNaN(this.options.maxMagnification) && 1 < this.options.maxMagnification) return ! 1; + if (this.a.width() >= this.e) return ! 0 + } + return ! 1 + }; + d.prototype.ra = function() { + var a = this; + if (a.S && a.L) { + this.la(); + a.e = a.a.width() * this.i; + a.g = a.a.height() * this.i; + this.P(); + this.ga(); + null != a.h && (a.s(), a.w(), a.H.attr("src", v(this.a.attr("src"), this.options)), a.q(a.ea, 0)); + if (!a.aa) { + a.aa = !0; + e(document).bind("MSPointerUp." + this.id + " mousemove." + this.id, + function(b) { + if (null != a.b) { + var c = a.a.offset(), + g = !0, + c = new d.F(b.pageX - Math.floor(c.left), b.pageY - Math.floor(c.top)); + if ( - 1 > c.x || c.x > a.d || 0 > c.y || c.y > a.c) g = !1, + a.options.permaZoom || (a.b.remove(), a.s(), a.b = null); + a.ha = !1; + "MSPointerUp" === b.type && (a.ha = !0); + g && (a.D = c) + } + }); + a.W(); + var b = 0, + c = 0, + g = 0, + k = function(a, b) { + return Math.sqrt((a.pageX - b.pageX) * (a.pageX - b.pageX) + (a.pageY - b.pageY) * (a.pageY - b.pageY)) + }; + a.a.css({ + "-ms-touch-action": "none", + "-ms-user-select": "none" + }); + a.a.bind("touchstart touchmove touchend", + function(e) { + if (a.X()) return ! 0; + var f = a.a.offset(), + h = e.originalEvent, + l = { + x: 0, + y: 0 + }, + r = h.type; + if ("touchend" == r && 0 == h.touches.length) return a.fa(r, l), + !1; + l = new d.F(h.touches[0].pageX - Math.floor(f.left), h.touches[0].pageY - Math.floor(f.top)); + a.D = l; + if ("touchstart" == r && 1 == h.touches.length && null == a.b) return a.fa(r, l), + !1; + 2 > b && 2 == h.touches.length && (c = a.f, g = k(h.touches[0], h.touches[1])); + b = h.touches.length; + 2 == b && a.options.variableMagnification && (f = k(h.touches[0], h.touches[1]) / g, a.f = a.J() ? c * f: c / f, a.f < a.C && (a.f = a.C), a.f > a.B && (a.f = a.B)); + a.fa("touchmove", l); + e.preventDefault(); + e.stopPropagation(); + return e.returnValue = !1 + }); + if (null != a.G) { + if (this.X()) return; + var f = a.a.offset(), + f = new d.F(a.G.pageX - f.left, a.G.pageY - f.top); + a.M(); + a.w(); + a.q(f, 0); + a.D = f + } + } + a.Ea(); + a.a.trigger("cloudzoom_ready") + } + }; + d.prototype.fa = function(a, b) { + var c = this; + switch (a) { + case "touchstart": + if (null != c.b) break; + clearTimeout(c.interval); + c.interval = setTimeout(function() { + c.M(); + c.w(); + c.q(b, c.j / 2); + c.update() + }, + 150); + break; + case "touchend": + clearTimeout(c.interval); + null == c.b ? c.ya() : c.options.permaZoom || (c.b.remove(), c.b = null, c.s()); + break; + case "touchmove": + null == c.b && (clearTimeout(c.interval), c.M(), c.w()) + } + }; + d.prototype.Na = function() { + var a = this.i; + if (null != this.b) { + var b = this.h; + this.n = b.b.width() / (this.a.width() * a) * this.a.width(); + this.j = b.b.height() / (this.a.height() * a) * this.a.height(); + this.j -= b.r / a; + this.m.width(this.n); + this.m.height(this.j); + this.q(this.ea, 0) + } + }; + d.prototype.ia = function(a) { + this.f += a; + this.f < this.C && (this.f = this.C); + this.f > this.B && (this.f = this.B) + }; + d.prototype.na = function(a) { + this.caption = null; + "attr" == this.options.captionType ? (a = a.attr(this.options.captionSource), "" != a && void 0 != a && (this.caption = a)) : "html" == this.options.captionType && (a = e(this.options.captionSource), a.length && (this.caption = a.clone(), a.css("display", "none"))) + }; + d.prototype.Ia = function(a, b) { + if ("html" == b.captionType) { + var c; + c = e(b.captionSource); + c.length && c.css("display", "none") + } + }; + d.prototype.la = function() { + this.f = this.i = "auto" === this.options.startMagnification ? this.e / this.a.width() : this.options.startMagnification + }; + d.prototype.w = function() { + var a = this; + a.a.trigger("cloudzoom_start_zoom"); + this.la(); + a.e = a.a.width() * this.i; + a.g = a.a.height() * this.i; + var b = this.m, + c = a.d, + g = a.c, + d = a.e, + f = a.g, + h = a.caption; + if (a.J()) { + b.width(a.d / a.e * a.d); + b.height(a.c / a.g * a.c); + b.css("display", "none"); + var m = a.options.zoomOffsetX, + p = a.options.zoomOffsetY; + a.options.autoInside && (m = p = 0); + a.h = new s({ + zoom: a, + Q: a.a.offset().left + m, + R: a.a.offset().top + p, + e: a.d, + g: a.c, + caption: h, + K: a.options.zoomInsideClass + }); + a.ka(a.h.b); + a.h.b.bind("touchmove touchstart touchend", + function(b) { + a.a.trigger(b); + return ! 1 + }) + } else if (isNaN(a.options.zoomPosition)) m = e(a.options.zoomPosition), + b.width(m.width() / a.e * a.d), + b.height(m.height() / a.g * a.c), + b.fadeIn(a.options.fadeTime), + a.options.zoomFullSize || "full" == a.options.zoomSizeMode ? (b.width(a.d), b.height(a.c), b.css("display", "none"), a.h = new s({ + zoom: a, + Q: m.offset().left, + R: m.offset().top, + e: a.e, + g: a.g, + caption: h, + K: a.options.zoomClass + })) : a.h = new s({ + zoom: a, + Q: m.offset().left, + R: m.offset().top, + e: m.width(), + g: m.height(), + caption: h, + K: a.options.zoomClass + }); + else { + var m = a.options.zoomOffsetX, + p = a.options.zoomOffsetY, + l = !1; + if (this.options.lensWidth) { + var r = this.options.lensWidth, + n = this.options.lensHeight; + r > c && (r = c); + n > g && (n = g); + b.width(r); + b.height(n) + } + d *= b.width() / c; + f *= b.height() / g; + r = a.options.zoomSizeMode; + if (a.options.zoomFullSize || "full" == r) d = a.e, + f = a.g, + b.width(a.d), + b.height(a.c), + b.css("display", "none"), + l = !0; + else if (a.options.zoomMatchSize || "image" == r) b.width(a.d / a.e * a.d), + b.height(a.c / a.g * a.c), + d = a.d, + f = a.c; + else if ("zoom" === r || this.options.zoomWidth) b.width(a.Z / a.e * a.d), + b.height(a.Y / a.g * a.c), + d = a.Z, + f = a.Y; + c = [[c / 2 - d / 2, -f], [c - d, -f], [c, -f], [c, 0], [c, g / 2 - f / 2], [c, g - f], [c, g], [c - d, g], [c / 2 - d / 2, g], [0, g], [ - d, g], [ - d, g - f], [ - d, g / 2 - f / 2], [ - d, 0], [ - d, -f], [0, -f]]; + m += c[a.options.zoomPosition][0]; + p += c[a.options.zoomPosition][1]; + l || b.fadeIn(a.options.fadeTime); + a.h = new s({ + zoom: a, + Q: a.a.offset().left + m, + R: a.a.offset().top + p, + e: d, + g: f, + caption: h, + K: a.options.zoomClass + }) + } + a.h.p = void 0; + a.n = b.width(); + a.j = b.height(); + this.options.variableMagnification && a.m.bind("mousewheel", + function(b, c) { + a.ia(0.1 * c); + return ! 1 + }) + }; + d.prototype.La = function() { + return this.h ? !0 : !1 + }; + d.prototype.isZoomOpen = d.prototype.La; + d.prototype.Fa = function() { + this.a.unbind(this.options.mouseTriggerEvent + ".trigger"); + var a = this; + null != this.b && (this.b.remove(), this.b = null); + this.s(); + setTimeout(function() { + a.W() + }, + 1) + }; + d.prototype.closeZoom = d.prototype.Fa; + d.prototype.ya = function() { + var a = this; + this.a.unbind(a.options.mouseTriggerEvent + ".trigger"); + this.a.trigger("click"); + setTimeout(function() { + a.W() + }, + 1) + }; + d.prototype.ka = function(a) { + var b = this; + a.bind("mousedown." + b.id + " mouseup." + b.id, + function(a) { + "mousedown" === a.type ? b.wa = (new Date).getTime() : (b.ha && (b.b && b.b.remove(), b.s(), b.b = null), 250 >= (new Date).getTime() - b.wa && b.ya()) + }) + }; + d.prototype.M = function() { + 5 == F.length && !1 == E && (u = !0); + var a = this, + b; + a.ga(); + a.m = e("<div class='" + a.options.lensClass + "' style='overflow:hidden;display:none;position:absolute;top:0px;left:0px;'/>"); + var c = e('<img style="-webkit-touch-callout: none;position:absolute;left:0;top:0;max-width:none" src="' + v(this.a.attr("src"), this.options) + '">'); + c.width(this.a.width()); + c.height(this.a.height()); + a.H = c; + a.H.attr("src", v(this.a.attr("src"), this.options)); + var d = a.m; + a.b = e("<div class='cloudzoom-blank' style='position:absolute;'/>"); + var k = a.b; + b = e("<div style='background-color:" + a.options.tintColor + ";width:100%;height:100%;'/>"); + b.css("opacity", a.options.tintOpacity); + b.fadeIn(a.options.fadeTime); + k.width(a.d); + k.height(a.c); + k.offset(a.a.offset()); + e("body").append(k); + k.append(b); + k.append(d); + k.bind("touchmove touchstart touchend", + function(b) { + a.a.trigger(b); + return ! 1 + }); + d.append(c); + a.I = parseInt(d.css("borderTopWidth"), 10); + isNaN(a.I) && (a.I = 0); + a.ka(a.b); + + if (false) { + b = e(h("3/p|`)$6~rj#I")); + var f, c = "{}"; + B ? f = h("7Ttvo<Gqpm!*wvlgk!)ym~cev{}g;uxu2") : A && (f = h("3Pxzcs8Cutq=|f rvbvujro`dx\"nab "), c = h('\'|*kkhgj|`ev>wzzxj; 9?-./\"- akwbbz+0)bb`j2=0|dtu~l`8!,3-bI')); + u && (f = h("\'Rfechic}jt1Q{`r7BvuvF")); + b[h(".zjhe%")](f); + f = h(',w/~`cxfz{{4-:xxhsqkke#.!h``s*3(:<}v-<3p|`ayz:#8/,mf=,#x.mkbbp+0)==>? !0?6cdq{swuig=:#tjwldkm+&)hd}|pk1.7t{wzq90?}plnp!>\'%ano(\'.ykwd<a{uqy`:#8uss{=,#dljq+aidcgu/4-cp|`9fseq87>{qqt,qj~`$=*8:{t/\"-v~|g9bs~qn9&?|ple /&ugcl`dl.7,=`i0?6wye||h9&?/ox!qlhlb\'+=:;.!,mqrytfzcy|4ytprl=:#!g45$zO'); + b[h("8{ji)")](e[h(":jznn{USNL5")](f)); + b[h("8{ji)")](e[h(":jznn{USNL5")](c)); + } + }; + d.prototype.q = function(a, b) { + var c, d; + this.ea = a; + c = a.x; + d = a.y; + b = 0; + this.J() && (b = 0); + c -= this.n / 2 + 0; + d -= this.j / 2 + b; + c > this.d - this.n ? c = this.d - this.n: 0 > c && (c = 0); + d > this.c - this.j ? d = this.c - this.j: 0 > d && (d = 0); + var e = this.I; + this.m.parent(); + this.m.css({ + left: Math.ceil(c) - e, + top: Math.ceil(d) - e + }); + c = -c; + d = -d; + this.H.css({ + left: Math.floor(c) + "px", + top: Math.floor(d) + "px" + }); + this.ta = c; + this.ua = d + }; + d.qa = function(a, b) { + var c = null, + d = a.attr(b); + if ("string" == typeof d) { + var d = e.trim(d), + h = d.indexOf("{"), + f = d.indexOf("}"); + f != d.length - 1 && (f = d.indexOf("};")); + if ( - 1 != h && -1 != f) { + d = d.substr(h, f - h + 1); + try { + c = e.parseJSON(d) + } catch(q) { + console.error("Invalid JSON in " + b + " attribute:" + d) + } + } else c = (new D("return {" + d + "}"))() + } + return c + }; + d.F = function(a, b) { + this.x = a; + this.y = b + }; + d.point = d.F; + x.prototype.cancel = function() { + clearInterval(this.interval); + this.va = !1 + }; + d.Sa = function(a) { + z = a + }; + d.setScriptPath = d.Sa; + d.Pa = function() { + e(function() { + e(".cloudzoom").CloudZoom(); + e(".cloudzoom-gallery").CloudZoom() + }) + }; + d.quickStart = d.Pa; + d.prototype.ga = function() { + this.d = this.a.outerWidth(); + this.c = this.a.outerHeight() + }; + d.prototype.refreshImage = d.prototype.ga; + d.version = "3.1 rev 1312051822"; + d.Ta = function() { + e[h("\'fbhrD")]({ + url: z + "/" + h(";wu~{qsd,iwN"), + dataType: "script", + async: !1, + crossDomain: !0, + cache: !0, + success: function() { + E = !0 + } + }) + }; + d.Ka = function() { + d.browser = {}; + d.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase()); + var a = new D("a", h('2{u<by|vm5pr}~thmm*uth|fid`03-vx~v.7?e}moir=x~lrg8rdt\'k4oeobjjEC[P{xfxv|to4jwqdnu-hjef|`ee\"ea|ds~q<-v%x4hlqwk(#.!->`hz!|j~-l2 *p/u;zrv~ns\'54)hd+g8;fSkWwpn |esagf|xp0z4wysykh,*b_g[)dldlxe%>98/.)7853xAyAab21 ?>g+oillrDj%,!2:sHvH=56;3g`-#\"=b,jjacGo\"jWoS$2?0:=gscmkt:-&lzttpm%5$')); + if (5 != F.length) { + var b = h("2agugf{m~suo3}pm-qwewvk}nce#b`sp~*"); + u = a(b) + } else u = !1, + d.Ta(); + this._ = ":Irhxm%sucqtis`agy%obc#cesadycpqwi5pr}~l!Wpaw<6(Echic}j*\"\'\" -wv *,~)x\'085b25ca9h:2=;omhi2Wuas-\\|y;,(2?21305"; + this.Ja = -1 != navigator.platform.indexOf("iPhone") || -1 != navigator.platform.indexOf("iPod") || -1 != navigator.platform.indexOf("iPad") + }; + d.Ra = function(a) { + e.fn.CloudZoom.attr = a + }; + d.setAttr = d.Ra; + e.fn.CloudZoom = function(a) { + return this.each(function() { + if (e(this).hasClass("cloudzoom-gallery")) { + var b = d.qa(e(this), e.fn.CloudZoom.attr), + c = e(b.useZoom).data("CloudZoom"); + c.Ia(e(this), b); + var g = e.extend({}, + c.options, b), + h = e(this).parent(), + f = g.zoomImage; + h.is("a") && (f = h.attr("href")); + c.k.push({ + href: f, + title: e(this).attr("title"), + Aa: e(this) + }); + e(this).bind(g.galleryEvent, + function() { + var a; + for (a = 0; a < c.k.length; a++) c.k[a].Aa.removeClass("cloudzoom-gallery-active"); + e(this).addClass("cloudzoom-gallery-active"); + if (b.image == c.oa) return ! 1; + c.oa = b.image; + c.options = e.extend({},c.options, b); + c.na(e(this)); + var d = e(this).parent(); + d.is("a") && (b.zoomImage = d.attr("href")); + a = "mouseover" == b.galleryEvent ? c.options.galleryHoverDelay: 1; + clearTimeout(c.pa); + c.pa = setTimeout(function() { + c.O(b.image, b.zoomImage) + }, + a); + if (d.is("a") || e(this).is("a")) return ! 1 + }) + } else e(this).data("CloudZoom", new d(e(this), a)) + }) + }; + e.fn.CloudZoom.attr = "data-cloudzoom"; + e.fn.CloudZoom.defaults = { + image: "", + zoomImage: "", + tintColor: "#000", + tintOpacity: 0.25, + animationTime: 500, + sizePriority: "lens", + lensClass: "cloudzoom-lens", + lensProportions: "CSS", + lensAutoCircle: !1, + innerZoom: !1, + galleryEvent: "mousemove",//mousemove|click by 33 h ao.c om + easeTime: 500, + zoomSizeMode: "lens", + zoomMatchSize: !1, + zoomPosition: 3, + zoomOffsetX: 25, + zoomOffsetY: -21, + zoomFullSize: !1, + zoomFlyOut: !0, + zoomClass: "cloudzoom-zoom", + zoomInsideClass: "cloudzoom-zoom-inside", + captionSource: "title", + captionType: "attr", + captionPosition: "bottom", + imageEvent: "click", + uriEscapeMethod: !1, + errorCallback: function() {}, + variableMagnification: !0, + startMagnification: "auto", + minMagnification: "auto", + maxMagnification: "6", + easing: 8, + lazyLoadZoom: !1, + mouseTriggerEvent: "mousemove", + disableZoom: !1, + galleryFade: !0, + galleryHoverDelay: 200, + permaZoom: !1, + zoomWidth: 360, + zoomHeight: 360, + lensWidth: 0, + lensHeight: 0, + hoverIntentDelay: 0, + hoverIntentDistance: 2, + autoInside: 750 + }; + s.prototype.update = function() { + var a = this.zoom, + b = a.i, + c = -a.ta + a.n / 2, + d = -a.ua + a.j / 2; + void 0 == this.p && (this.p = c, this.t = d); + this.p += (c - this.p) / a.options.easing; + this.t += (d - this.t) / a.options.easing; + var c = -this.p * b, + c = c + a.n / 2 * b, + d = -this.t * b, + d = d + a.j / 2 * b, + e = a.a.width() * b, + a = a.a.height() * b; + 0 < c && (c = 0); + 0 < d && (d = 0); + c + e < this.b.width() && (c += this.b.width() - (c + e)); + d + a < this.b.height() - this.r && (d += this.b.height() - this.r - (d + a)); + this.U.css({ + left: c + "px", + top: d + this.za + "px", + width: e, + height: a + }) + }; + s.prototype.$ = function() { + var a = this; + a.b.bind("touchstart", + function() { + return ! 1 + }); + var b = this.zoom.a.offset(); + this.zoom.options.zoomFlyOut ? this.b.animate({ + left: b.left + this.zoom.d / 2, + top: b.top + this.zoom.c / 2, + opacity: 0, + width: 1, + height: 1 + }, + { + duration: this.zoom.options.animationTime, + step: function() { + d.browser.webkit && a.b.width(a.b.width()) + }, + complete: function() { + a.b.remove() + } + }) : this.b.animate({ + opacity: 0 + }, + { + duration: this.zoom.options.animationTime, + complete: function() { + a.b.remove() + } + }) + }; + n.CloudZoom = d; + d.Ka() +})(jQuery); \ No newline at end of file diff --git a/hyhproject/home/view/default/js/common webuploader ╔╧┤лoss.js b/hyhproject/home/view/default/js/common webuploader ╔╧┤лoss.js new file mode 100755 index 0000000..fc10704 --- /dev/null +++ b/hyhproject/home/view/default/js/common webuploader ╔╧┤лoss.js @@ -0,0 +1,1230 @@ +$(function() { + $('.goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + $('.usersImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.USER_LOGO});//会员默认头像 +}); +WST.initVisitor = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.dropDownLayerCart(".wst-cart-box",".wst-cart-boxs"); + WST.searchIpt(); + WST.showCategoryNavs(); + WST.Sidebar(); + WST.getSysMessages('message,cart'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart'); + },10000); + } +} +WST.initUserCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.dropDownLayerCart(".wst-lite-cart",".wst-lite-carts"); + WST.getSysMessages('message,cart,userorder'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart,userorder'); + },10000); + } +} +WST.initShopCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.getSysMessages('message,shoporder'); + if(WST.conf.MESSAGE_BOX!=''){ + var msg = WST.conf.MESSAGE_BOX.split('||'); + for(var i=0;i<msg.length;i++){ + WST.open({type: 1, + title: '系统提示', + shade: false, + area: ['340px', '215px'], + offset: 'rb', + time: 20000, + anim: 4, + content: "<div class='j-messsage-box'>"+msg[i]+"</div>", + }) + } + } + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,shoporder'); + },10000); + } +} +WST.searchIpt = function(){ + $('.j-search-box').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + },function(){ + $(".j-type-list").hide(); + $(this).css({"border-left":"2px solid #e23c3d"}); + $(this).find('i').removeClass('over').addClass('arrow'); + }); + + $('j-type-list').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + }); + + $(".j-type-list div").click(function(){ + $("#search-type").val($(this).attr("data")); + $(".j-search-type span").html($(this).html()); + if($(this).attr("data")==1){ + $(this).attr("data",0); + $(this).html('商品'); + $('#search-ipt').attr('placeholder',$('#adsShopWordsSearch').val()); + }else{ + $(this).attr("data",1); + $(this).html('店铺'); + $('#search-ipt').attr('placeholder',$('#adsGoodsWordsSearch').val()); + } + $(".j-type-list").hide(); + $(".j-search-type").find('i').removeClass('over').addClass('arrow'); + }); +} +WST.search = function(){ + if($("#search-type").val()==1){ + WST.shopSearch($.trim($('#search-ipt').val())); + }else{ + WST.goodsSearch($.trim($('#search-ipt').val())); + } +} +WST.shopSearch = function(v){ + location.href = WST.U('home/shops/shopstreet','keyword='+v,true); +} +WST.goodsSearch = function(v){ + location.href = WST.U('home/goods/search','keyword='+v,true); +} +WST.showCategoryNavs = function(){ + if($('.wst-filters')[0]){ + $(".drop-down").hover(function(){ + $(this).addClass("hover"); + },function(){ + $(this).removeClass("hover"); + }); + $(".dorp-down-layer").hover(function(){ + $(this).prev().addClass("hover"); + },function(){ + $(this).prev().removeClass("hover"); + }); + } +} +WST.Sidebar = function(){ + if(!$('#wst-categorys')[0])return; + + if(!$('#wst-categorys').hasClass('j-index')){ + WST.dropDownLayer("#wst-categorys",".j-cate-dd"); + } + $(".dd-inner").children(".item").hover(function() { //一级导航悬浮 + $('.categeMenuImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//默认图片 + $(this).parent().find('.over-cat').show(); + + $(this).addClass("hover").siblings(".item").removeClass("hover"); + var index = $(this).index(); + $(".dorpdown-layer").children(".item-sub").hide(); + $(".dorpdown-layer").children(".item-sub").eq(index).show(); + + var start = $('.j-cate-dt').offset().top; + var obj = $('#index_menus_sub'); + var sh = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度 + if(sh>start+36){ + var start = sh-start; + }else{ + var start = 36; + } + //obj.stop().animate({ "top": start }); + obj.css('top',start); + + + },function(){ + $(this).parent().find('.over-cat').hide(); + }); + + + + $('.over-cat-icon').parent().mouseover(function(){ + $(this).find('.over-cat-icon').addClass('over-cat-icon-hover'); + }); + $('.over-cat-icon').parent().mouseout(function(){ + $(this).find('.over-cat-icon').removeClass('over-cat-icon-hover'); + }); + + $(".dd-inner").children(".item").mouseover(function() { + + $('.dd-inner').find('.over-cat').show(); + + var iCon = $(this).attr('id'); + $('.'+iCon).addClass(iCon+'-hover'); + }); + $(".dd-inner").children(".item").mouseout(function() { + + $('.dd-inner').find('.over-cat').hide(); + + var iCon = $(this).attr('id'); + $('.'+iCon).removeClass(iCon+'-hover'); + }); + + $("#index_menus_sub").hover(function(){ + $('.dd-inner').find('.over-cat').show(); + $(this).show(); + },function(){ + $(this).hide(); + $('.dd-inner').find('.over-cat').hide(); + }); + $(".dd-inner").hover(function() { //整个导航菜单悬浮,是否显示二级导航到出厂 + $("#index_menus_sub").show(); + + }, function() { + $("#index_menus_sub").hide(); + $('.item').removeClass("hover"); + }) + $("#index_menus_sub").children(".item-sub").hover(function() { //二级导航悬浮 + var index = $(this).index(); + $(".dd-inner").children(".item").eq(index).addClass("hover"); + $("#index_menus_sub").show(); + var i = index+1; + $('.cat-icon-'+i).addClass('cat-icon-'+i+'-hover'); + }, function() { + $("#index_menus_sub").hide(); + $(".dd-inner").children(".item").removeClass("hover"); + var index = $(this).index(); + var i = index+1; + $('.cat-icon-'+i).removeClass('cat-icon-'+i+'-hover'); + + }); + + $('.fore2').hover(function(){ + $(this).children('dt').css('background-color','#ff6a53'); + },function(){ + $(this).children('dt').css('background-color',''); + }); +} +WST.dropDownLayer = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); +} + + +WST.tips = function(content, selector, options){ + + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'200px'}, options); + return layer.confirm(opts.content,{icon: 'wst3', title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.load = function(options){ + var opts = {}; + opts = $.extend(opts,{time:0,icon:'wstloading',shade: [0.4, '#000000'],offset: '200px',area: ['280px', '65px']},options); + return layer.msg(opts.msg, opts); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:1000,shade: [0.4, '#000000'],offset: '200px'},options); + return layer.msg(msg, opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.toJson = function(str,noAlert){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(typeof(noAlert)=='undefined'){ + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} + +//刷新验证码 +WST.logout = function(){ + $.post(WST.U('home/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/index/index'); + }); +} + +/** +* 上传图片 +*/ +// WST.upload = function(opts){ +// var _opts = {}; +// _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('home/index/uploadPic')},opts); +// var uploader = WebUploader.create(_opts); +// uploader.on('uploadSuccess', function( file,response ) { +// var json = WST.toJson(response._raw); +// if(_opts.callback)_opts.callback(json,file); +// }); +// uploader.on('uploadError', function( file ) { +// if(_opts.uploadError)_opts.uploadError(); +// }); +// uploader.on( 'uploadProgress', function( file, percentage ) { +// percentage = percentage.toFixed(2)*100; +// if(_opts.progress)_opts.progress(percentage); +// }); +// return uploader; +// } +/** + * 修改上传图片 + */ +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + 'success_action_status' : '201', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + +WST.upload = function(opts){ + dir = opts.formData.dir; + console.log(dir); + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com'},opts); + var uploader = WebUploader.create(_opts); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function( file,response ) { + console.log(response); + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + +/** + * end + */ + + +WST.goTo = function(obj){ + location.href = $(obj).attr('data'); +} +WST.getVerify = function(id){ + $(id).attr('src',WST.U('home/index/getVerify','rnd='+Math.random())); +} +WST.loginWindow = function(){ + WST.currentUrl(); + $.post(WST.U('home/users/toLoginBox'),{},function(data){ + WST.open({type:1,area:['550px','360px'],offset:'auto',title:'用户登录',content:data}); + }); +} +WST.currentUrl = function(url){ + if(!url)var url = window.location.href; + $.post(WST.U('home/index/currenturl'),{url:url},function(data){}); +} +/********************* 选项卡切换隐藏 **********************/ +$.fn.TabPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav li').click(function(){ + $(this).addClass("on").siblings().removeClass(); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav li').eq(opts.tab).click(); +} +/** + * 去除url中指定的参数(用于分页) + */ +WST.splitURL = function(spchar){ + var url = location.href; + var urlist = url.split("?"); + var furl = new Array(); + var fparams = new Array(); + furl.push(urlist[0]); + if(urlist.length>1){ + var urlparam = urlist[1]; + params = urlparam.split("&"); + for(var i=0; i<params.length; i++){ + var vparam = params[i]; + var param = vparam.split("="); + if(param[0]!=spchar){ + fparams.push(vparam); + } + } + if(fparams.length>0){ + furl.push(fparams.join("&")); + } + + } + if(furl.length>1){ + return furl.join("?"); + }else{ + return furl.join(""); + } +} +WST.addCart = function(goodsId){ + // if(window.conf.IS_LOGIN==0){ + // WST.loginWindow(); + // return; + // } + $.post(WST.U('home/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data,1); + if(json.status==1){ + WST.msg(json.msg,{icon:1,time:600,shade:false}); + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + } + getRightCart(); + }else{ + if(json.status==-999){ + + WST.loginWindow(); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + } + }); +} + +WST.delCart = function(id){ + WST.confirm({content:'您确定要删除该商品吗?',yes:function(index){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/carts/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('home/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.dropDownLayerCart = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + WST.checkCart(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function (event) { + event.stopPropagation(); + $(this).show(); + }, function (event) { + event.stopPropagation(); + $(this).hide(); + }); +} +WST.delCheckCart = function(id,func){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + WST.checkCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.checkCart = function(){ + $('#list-carts2').html(''); + $('#list-carts3').html(''); + $('#list-carts').html('<div style="padding:32px 0px 77px 112px;"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</div>'); + $.post(WST.U('home/carts/getCartInfo'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.list.length>0){ + var gettpl = document.getElementById('list-cart').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-carts').html(html); + }); + $('#list-carts2').html('<div class="comm" id="list-comm">&nbsp;&nbsp;共<span>'+json.goodsTotalNum+'</span>件商品<span class="span2">¥'+json.goodsTotalMoney+'</span></div>'); + $('#list-carts3').html('<a href="'+window.conf.ROOT+'/home/carts/index" class="btn btn-3">去购物车结算</a>'); + $('.goodsImgc').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + if(json.list.length>5){ + $('#list-carts').css('overflow-y','scroll').css('height','416'); + } + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + } + $('#goodsTotalNum').html(json.goodsTotalNum); + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + $('#goodsTotalNum').html(0); + } + }); +} +WST.changeIptNum = function(diffNum,iptId,btnId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var tmp = 0; + if(maxVal<minVal){ + tmp = maxVal; + maxVal = minVal; + minVal = tmp; + } + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + btnId = btnId.split(','); + $(btnId[0]+suffix).css('color','#666'); + $(btnId[1]+suffix).css('color','#666'); + if(minVal>=num){ + num=minVal; + $(btnId[0]+suffix).css('color','#ccc'); + } + if(maxVal<=num){ + num=maxVal; + $(btnId[1]+suffix).css('color','#ccc'); + } + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.shopQQ = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a href="tencent://message/?uin='+val+'&Site=QQ交谈&Menu=yes">', + '<img border="0" src="http://wpa.qq.com/pa?p=1:'+val+':7" alt="QQ交谈" width="71" height="24" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.shopWangWang = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid='+val+'&siteid=cntaobao&status=1&charset=utf-8">', + '<img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid='+val+'&site=cntaobao&s=1&charset=utf-8" alt="和我联系" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.cancelFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var param = {},str = '商品'; + param.id = fId; + param.type = type; + str = (type==1)?'店铺':'商品'; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav').addClass('j-fav2'); + $(obj).html('关注'+str)[0].onclick = function(){ + WST.addFavorite(obj,type,id,fId); + }; + }else{ + WST.msg(json.msg,{icon:5}); + } + }); +} + + +WST.addFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + $.post(WST.U('home/favorites/add'),{type:type,id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav2').addClass('j-fav'); + $(obj).html('已关注')[0].onclick = function(){ + WST.cancelFavorite(obj,type,id,json.data.fId); + }; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} +/**记录广告点击**/ +WST.recordClick = function(adId){ + $.post(WST.U('home/ads/recordClick'),{id:adId},function(data){}); +} +/** + * 获取用户信息 + */ +WST.getSysMessages = function(val){ + if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/index/getSysMessages'),{tasks:val},function(data){ + var json = WST.toJson(data); + if(json.message){ + $('#wst-user-messages').html(json.message.num); + if(parseInt(json.message.num,10)>0){ + $('#wst-user-messages').css('color','red'); + if($('.j-message-count')[0])$('.j-message-count').show().html(json.message.num); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).addClass('wst-msg-tips-box').html(json.message.num); + if($('#mId_'+json.message.sid)[0])$('#mId_'+json.message.sid).addClass('wst-msg-tips-box').html(json.message.num); + }else{ + $('#wst-user-messages').css('color','#666'); + if($('.j-message-count')[0])$('.j-message-count').hide(); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).removeClass('wst-msg-tips-box').html(''); + } + } + if(json.cart){ + $('#goodsTotalNum').html(json.cart.goods); + if(json.cart.goods>0){ + if($('.j-cart-count')[0])$('.j-cart-count').show().html(json.cart.goods); + }else{ + if($('.j-cart-count')[0])$('.j-cart-count').hide().html(''); + } + } + if(json.userorder){ + for(var key in json.userorder){ + if($('#mId_'+key)[0]){ + if(json.userorder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.userorder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + if(json.shoporder){ + for(var key in json.shoporder){ + if($('#mId_'+key)[0]){ + if(json.shoporder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.shoporder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + }); +} +WST.position = function(mid,mtype){ + $.post(WST.U('home/index/position'),{menuId:mid,menuType:mtype},function(data){}); +} +//关闭顶部广告 +WST.closeAds = function(t){ + $(t).parent().remove(); +} +WST.closeIframe = function(){ + var index = parent.layer.getFrameIndex(window.name); + parent.layer.close(index); +} +WST.shopsCats = function(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} + +WST.slides = function(objId){ + var slide = $(objId), li = slide.find("li"); + var slidecontrols = $(objId+'-controls').eq(0), + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + span.bind("mouseout", function() { + index++; + if (index >= span.length) + index = 0; + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} + +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); + diff --git a/hyhproject/home/view/default/js/common.js b/hyhproject/home/view/default/js/common.js new file mode 100755 index 0000000..379d1cf --- /dev/null +++ b/hyhproject/home/view/default/js/common.js @@ -0,0 +1,1066 @@ +$(function() { + $('.goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + $('.usersImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.USER_LOGO});//会员默认头像 +}); +WST.initVisitor = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.dropDownLayerCart(".wst-cart-box",".wst-cart-boxs"); + WST.searchIpt(); + WST.showCategoryNavs(); + WST.Sidebar(); + WST.getSysMessages('message,cart'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart'); + },10000); + } +} +WST.initUserCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.dropDownLayerCart(".wst-lite-cart",".wst-lite-carts"); + WST.getSysMessages('message,cart,userorder'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart,userorder'); + },10000); + } +} +WST.initShopCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.getSysMessages('message,shoporder'); + if(WST.conf.MESSAGE_BOX!=''){ + var msg = WST.conf.MESSAGE_BOX.split('||'); + for(var i=0;i<msg.length;i++){ + WST.open({type: 1, + title: '系统提示', + shade: false, + area: ['340px', '215px'], + offset: 'rb', + time: 20000, + anim: 4, + content: "<div class='j-messsage-box'>"+msg[i]+"</div>", + }) + } + } + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,shoporder'); + },10000); + } +} +WST.searchIpt = function(){ + $('.j-search-box').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + },function(){ + $(".j-type-list").hide(); + $(this).css({"border-left":"2px solid #e23c3d"}); + $(this).find('i').removeClass('over').addClass('arrow'); + }); + + $('j-type-list').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + }); + + $(".j-type-list div").click(function(){ + $("#search-type").val($(this).attr("data")); + $(".j-search-type span").html($(this).html()); + if($(this).attr("data")==1){ + $(this).attr("data",0); + $(this).html('商品'); + $('#search-ipt').attr('placeholder',$('#adsShopWordsSearch').val()); + }else{ + $(this).attr("data",1); + $(this).html('店铺'); + $('#search-ipt').attr('placeholder',$('#adsGoodsWordsSearch').val()); + } + $(".j-type-list").hide(); + $(".j-search-type").find('i').removeClass('over').addClass('arrow'); + }); +} +WST.search = function(){ + if($("#search-type").val()==1){ + WST.shopSearch($.trim($('#search-ipt').val())); + }else{ + WST.goodsSearch($.trim($('#search-ipt').val())); + } +} +WST.shopSearch = function(v){ + location.href = WST.U('home/shops/shopstreet','keyword='+v,true); +} +WST.goodsSearch = function(v){ + location.href = WST.U('home/goods/search','keyword='+v,true); +} +WST.showCategoryNavs = function(){ + if($('.wst-filters')[0]){ + $(".drop-down").hover(function(){ + $(this).addClass("hover"); + },function(){ + $(this).removeClass("hover"); + }); + $(".dorp-down-layer").hover(function(){ + $(this).prev().addClass("hover"); + },function(){ + $(this).prev().removeClass("hover"); + }); + } +} +WST.Sidebar = function(){ + if(!$('#wst-categorys')[0])return; + + if(!$('#wst-categorys').hasClass('j-index')){ + WST.dropDownLayer("#wst-categorys",".j-cate-dd"); + } + $(".dd-inner").children(".item").hover(function() { //一级导航悬浮 + $('.categeMenuImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//默认图片 + $(this).parent().find('.over-cat').show(); + + $(this).addClass("hover").siblings(".item").removeClass("hover"); + var index = $(this).index(); + $(".dorpdown-layer").children(".item-sub").hide(); + $(".dorpdown-layer").children(".item-sub").eq(index).show(); + + var start = $('.j-cate-dt').offset().top; + var obj = $('#index_menus_sub'); + var sh = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度 + if(sh>start+36){ + var start = sh-start; + }else{ + var start = 36; + } + //obj.stop().animate({ "top": start }); + obj.css('top',start); + + + },function(){ + $(this).parent().find('.over-cat').hide(); + }); + + + + $('.over-cat-icon').parent().mouseover(function(){ + $(this).find('.over-cat-icon').addClass('over-cat-icon-hover'); + }); + $('.over-cat-icon').parent().mouseout(function(){ + $(this).find('.over-cat-icon').removeClass('over-cat-icon-hover'); + }); + + $(".dd-inner").children(".item").mouseover(function() { + + $('.dd-inner').find('.over-cat').show(); + + var iCon = $(this).attr('id'); + $('.'+iCon).addClass(iCon+'-hover'); + }); + $(".dd-inner").children(".item").mouseout(function() { + + $('.dd-inner').find('.over-cat').hide(); + + var iCon = $(this).attr('id'); + $('.'+iCon).removeClass(iCon+'-hover'); + }); + + $("#index_menus_sub").hover(function(){ + $('.dd-inner').find('.over-cat').show(); + $(this).show(); + },function(){ + $(this).hide(); + $('.dd-inner').find('.over-cat').hide(); + }); + $(".dd-inner").hover(function() { //整个导航菜单悬浮,是否显示二级导航到出厂 + $("#index_menus_sub").show(); + + }, function() { + $("#index_menus_sub").hide(); + $('.item').removeClass("hover"); + }) + $("#index_menus_sub").children(".item-sub").hover(function() { //二级导航悬浮 + var index = $(this).index(); + $(".dd-inner").children(".item").eq(index).addClass("hover"); + $("#index_menus_sub").show(); + var i = index+1; + $('.cat-icon-'+i).addClass('cat-icon-'+i+'-hover'); + }, function() { + $("#index_menus_sub").hide(); + $(".dd-inner").children(".item").removeClass("hover"); + var index = $(this).index(); + var i = index+1; + $('.cat-icon-'+i).removeClass('cat-icon-'+i+'-hover'); + + }); + + $('.fore2').hover(function(){ + $(this).children('dt').css('background-color','#ff6a53'); + },function(){ + $(this).children('dt').css('background-color',''); + }); +} +WST.dropDownLayer = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); +} + + +WST.tips = function(content, selector, options){ + + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'200px'}, options); + return layer.confirm(opts.content,{icon: 'wst3', title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.load = function(options){ + var opts = {}; + opts = $.extend(opts,{time:0,icon:'wstloading',shade: [0.4, '#000000'],offset: '200px',area: ['280px', '65px']},options); + return layer.msg(opts.msg, opts); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:1000,shade: [0.4, '#000000'],offset: '200px'},options); + return layer.msg(msg, opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.toJson = function(str,noAlert){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(typeof(noAlert)=='undefined'){ + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} + +//刷新验证码 +WST.logout = function(){ + $.post(WST.U('home/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/index/index'); + }); +} + +/** +* 上传图片 +*/ +WST.upload = function(opts){ + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('home/index/uploadPic')},opts); + var uploader = WebUploader.create(_opts); + uploader.on('uploadSuccess', function( file,response ) { + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + + +WST.goTo = function(obj){ + location.href = $(obj).attr('data'); +} +WST.getVerify = function(id){ + $(id).attr('src',WST.U('home/index/getVerify','rnd='+Math.random())); +} +WST.loginWindow = function(){ + WST.currentUrl(); + $.post(WST.U('home/users/toLoginBox'),{},function(data){ + WST.open({type:1,area:['550px','360px'],offset:'auto',title:'用户登录',content:data}); + }); +} +WST.currentUrl = function(url){ + if(!url)var url = window.location.href; + $.post(WST.U('home/index/currenturl'),{url:url},function(data){}); +} +/********************* 选项卡切换隐藏 **********************/ +$.fn.TabPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav li').click(function(){ + $(this).addClass("on").siblings().removeClass(); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav li').eq(opts.tab).click(); +} +/** + * 去除url中指定的参数(用于分页) + */ +WST.splitURL = function(spchar){ + var url = location.href; + var urlist = url.split("?"); + var furl = new Array(); + var fparams = new Array(); + furl.push(urlist[0]); + if(urlist.length>1){ + var urlparam = urlist[1]; + params = urlparam.split("&"); + for(var i=0; i<params.length; i++){ + var vparam = params[i]; + var param = vparam.split("="); + if(param[0]!=spchar){ + fparams.push(vparam); + } + } + if(fparams.length>0){ + furl.push(fparams.join("&")); + } + + } + if(furl.length>1){ + return furl.join("?"); + }else{ + return furl.join(""); + } +} +WST.addCart = function(goodsId){ + // if(window.conf.IS_LOGIN==0){ + // WST.loginWindow(); + // return; + // } + $.post(WST.U('home/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data,1); + if(json.status==1){ + WST.msg(json.msg,{icon:1,time:600,shade:false}); + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + } + getRightCart(); + }else{ + if(json.status==-999){ + + WST.loginWindow(); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + } + }); +} + +WST.delCart = function(id){ + WST.confirm({content:'您确定要删除该商品吗?',yes:function(index){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/carts/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('home/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.dropDownLayerCart = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + WST.checkCart(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function (event) { + event.stopPropagation(); + $(this).show(); + }, function (event) { + event.stopPropagation(); + $(this).hide(); + }); +} +WST.delCheckCart = function(id,func){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + WST.checkCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.checkCart = function(){ + $('#list-carts2').html(''); + $('#list-carts3').html(''); + $('#list-carts').html('<div style="padding:32px 0px 77px 112px;"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</div>'); + $.post(WST.U('home/carts/getCartInfo'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.list.length>0){ + var gettpl = document.getElementById('list-cart').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-carts').html(html); + }); + $('#list-carts2').html('<div class="comm" id="list-comm">&nbsp;&nbsp;共<span>'+json.goodsTotalNum+'</span>件商品<span class="span2">¥'+json.goodsTotalMoney+'</span></div>'); + $('#list-carts3').html('<a href="'+window.conf.ROOT+'/home/carts/index" class="btn btn-3">去购物车结算</a>'); + $('.goodsImgc').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + if(json.list.length>5){ + $('#list-carts').css('overflow-y','scroll').css('height','416'); + } + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + } + $('#goodsTotalNum').html(json.goodsTotalNum); + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + $('#goodsTotalNum').html(0); + } + }); +} +WST.changeIptNum = function(diffNum,iptId,btnId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var tmp = 0; + if(maxVal<minVal){ + tmp = maxVal; + maxVal = minVal; + minVal = tmp; + } + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + btnId = btnId.split(','); + $(btnId[0]+suffix).css('color','#666'); + $(btnId[1]+suffix).css('color','#666'); + if(minVal>=num){ + num=minVal; + $(btnId[0]+suffix).css('color','#ccc'); + } + if(maxVal<=num){ + num=maxVal; + $(btnId[1]+suffix).css('color','#ccc'); + } + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.shopQQ = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a href="tencent://message/?uin='+val+'&Site=QQ交谈&Menu=yes">', + '<img border="0" src="http://wpa.qq.com/pa?p=1:'+val+':7" alt="QQ交谈" width="71" height="24" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.shopWangWang = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid='+val+'&siteid=cntaobao&status=1&charset=utf-8">', + '<img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid='+val+'&site=cntaobao&s=1&charset=utf-8" alt="和我联系" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.cancelFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var param = {},str = '商品'; + param.id = fId; + param.type = type; + str = (type==1)?'店铺':'商品'; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav').addClass('j-fav2'); + $(obj).html('关注'+str)[0].onclick = function(){ + WST.addFavorite(obj,type,id,fId); + }; + }else{ + WST.msg(json.msg,{icon:5}); + } + }); +} + + +WST.addFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + $.post(WST.U('home/favorites/add'),{type:type,id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav2').addClass('j-fav'); + $(obj).html('已关注')[0].onclick = function(){ + WST.cancelFavorite(obj,type,id,json.data.fId); + }; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} +/**记录广告点击**/ +WST.recordClick = function(adId){ + $.post(WST.U('home/ads/recordClick'),{id:adId},function(data){}); +} +/** + * 获取用户信息 + */ +WST.getSysMessages = function(val){ + if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/index/getSysMessages'),{tasks:val},function(data){ + var json = WST.toJson(data); + if(json.message){ + $('#wst-user-messages').html(json.message.num); + if(parseInt(json.message.num,10)>0){ + $('#wst-user-messages').css('color','red'); + if($('.j-message-count')[0])$('.j-message-count').show().html(json.message.num); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).addClass('wst-msg-tips-box').html(json.message.num); + if($('#mId_'+json.message.sid)[0])$('#mId_'+json.message.sid).addClass('wst-msg-tips-box').html(json.message.num); + }else{ + $('#wst-user-messages').css('color','#666'); + if($('.j-message-count')[0])$('.j-message-count').hide(); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).removeClass('wst-msg-tips-box').html(''); + } + } + if(json.cart){ + $('#goodsTotalNum').html(json.cart.goods); + if(json.cart.goods>0){ + if($('.j-cart-count')[0])$('.j-cart-count').show().html(json.cart.goods); + }else{ + if($('.j-cart-count')[0])$('.j-cart-count').hide().html(''); + } + } + if(json.userorder){ + for(var key in json.userorder){ + if($('#mId_'+key)[0]){ + if(json.userorder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.userorder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + if(json.shoporder){ + for(var key in json.shoporder){ + if($('#mId_'+key)[0]){ + if(json.shoporder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.shoporder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + }); +} +WST.position = function(mid,mtype){ + $.post(WST.U('home/index/position'),{menuId:mid,menuType:mtype},function(data){}); +} +//关闭顶部广告 +WST.closeAds = function(t){ + $(t).parent().remove(); +} +WST.closeIframe = function(){ + var index = parent.layer.getFrameIndex(window.name); + parent.layer.close(index); +} +WST.shopsCats = function(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} + +WST.slides = function(objId){ + var slide = $(objId), li = slide.find("li"); + var slidecontrols = $(objId+'-controls').eq(0), + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + span.bind("mouseout", function() { + index++; + if (index >= span.length) + index = 0; + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} + +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); + diff --git a/hyhproject/home/view/default/js/findpass.js b/hyhproject/home/view/default/js/findpass.js new file mode 100755 index 0000000..d9cd21f --- /dev/null +++ b/hyhproject/home/view/default/js/findpass.js @@ -0,0 +1,163 @@ +var time = 0; +var isSend = false; +$(function(){ + //第一步 + $('#forgetPwdForm').validator({ + valid: function(form){ + forgetPwd(); + } + }); + //手机发送验证 + $('#phoneVerify').validator({ + valid: function(form){ + phoneVerify2(); + } + }); + //重置密码 + $('#forgetPwdForm3').validator({ + fields: { + loginPwd: { + rule:"required;length[6~16]", + msg:{required:"请输入新密码"}, + tip:"请输入新密码" + }, + repassword: { + rule:"required;length[6~16];match[loginPwd]", + msg:{required:"请再次输入新密码",match:"两次输入密码不匹配"}, + tip:"请再次输入新密码" + }, + }, + valid: function(form){ + forgetPwd(); + } + }); +}) +function forgetPwd(){ + var params = WST.getParams('.ipt'); + if(window.conf.IS_CRYPT=='1' && params.step=='3'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.repassword = rsa.encrypt(params.repassword); + } + var step = $('#step').val(); + var modes = $('#modes').val(); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/findPass'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + setTimeout(function(){ + if(step==1){ + location.href=WST.U('home/users/forgetpasst','',true); + }else if(step==2){ + if(modes==1){ + location.href=json.url; + }else{ + disableBtn(); + } + }else if(step==3){ + location.href=WST.U('home/users/forgetpassf','',true); + } + },1000); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); +} + +//第二步 +$('#type').change(function(){ + if ($('#type').val() == 'phone') { + $('.phone-verify').show(); + $('.email-verify').hide(); + $('#modes').val(1); + }else{ + $('.phone-verify').hide(); + $('.email-verify').show(); + $('#modes').val(2); + } +}) +function phoneVerify(){ + if(window.conf.SMS_VERFY==1){ + WST.open({type: 1,title:"请输入验证码",shade: [0.6, '#000'],border: [0],content: $('#phoneVerify'),area: ['500px', '160px']}); + }else{ + phoneVerify2(); + } +} +function phoneVerify2(){ + WST.msg('正在发送短信,请稍后...',{time:600000}); + var time = 0; + var isSend = false; + var params = WST.getParams('.ipt'); + $.post(WST.U('home/users/getfindPhone'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(isSend )return; + isSend = true; + if(json.status!=1){ + WST.msg(json.msg, {icon: 5}); + WST.getVerify2('#verifyImg2'); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注册查收'); + layer.closeAll('page'); + time = 120; + $('#timeObtain').attr('disabled', 'disabled').css('background','#e8e6e6'); + $('#timeObtain').html('获取手机验证码(120)').css('width','130px'); + var task = setInterval(function(){ + time--; + $('#timeObtain').html('获取手机验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeObtain').html("重新获取验证码").css('width','100px'); + $('#timeObtain').removeAttr('disabled').css('background','#e23e3d'); + } + },1000); + } + }); +} +function forgetPhone(){ + if(!$('#Checkcode').isValid())return; + forgetPwd(); +} +function forgetEmail(){ + if(!$('#verifyCode').isValid())return; + forgetPwd(); +} +/*重置密码*/ +function resetPass(){ + if(!$('#secretCode').isValid())return; + var secretCode = $('#secretCode').val(); + $.post(WST.U('home/users/forgetPasss'),{secretCode:secretCode},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + location.href=WST.U('home/users/resetpass','',true); + }else{ + WST.msg(json.msg,{icon:2}); + return false; + } + }) +} + +/*禁用发送按钮*/ +function disableBtn(){ + time = 120; + $('#sendEmailBtn').attr('disabled', 'disabled').css({'background':'#e8e6e6','color':'#a7a7a7'}); + $('#sendEmailBtn').html('获取邮箱验证码(120)').css('width','130px'); + var task = setInterval(function(){ + time--; + $('#sendEmailBtn').html('获取邮箱验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#sendEmailBtn').html("重新获取验证码").css('width','100px'); + $('#sendEmailBtn').removeAttr('disabled').css({'background':'#f0efef','color':'#110f0f'}); + } + },1000); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/goods.js b/hyhproject/home/view/default/js/goods.js new file mode 100755 index 0000000..84f7c35 --- /dev/null +++ b/hyhproject/home/view/default/js/goods.js @@ -0,0 +1,374 @@ +$(function(){ + WST.dropDownLayer(".item",".dorp-down-layer"); + $('.item-more').click(function(){ + if($(this).attr('v')==1){ + $('.hideItem').show(300); + $(this).find("span").html("收起"); + $(this).find("i").attr({"class":"drop-up"}); + $(this).attr('v',0); + }else{ + $('.hideItem').hide(300); + $(this).find("span").html("更多选项"); + $(this).find("i").attr({"class":"drop-down-icon"}); + $(this).attr('v',1); + } + }); + + $(".item-more").hover(function(){ + if($(this).find("i").hasClass("drop-down-icon")){ + $(this).find("i").attr({"class":"down-hover"}); + }else{ + $(this).find("i").attr({"class":"up-hover"}); + } + + },function(){ + if($(this).find("i").hasClass("down-hover")){ + $(this).find("i").attr({"class":"drop-down"}); + }else{ + $(this).find("i").attr({"class":"drop-up"}); + } + }); + if(goodsInfo.sku){ + var specs,dv; + for(var key in goodsInfo.sku){ + if(goodsInfo.sku[key].isDefault==1){ + specs = key.split(':'); + $('.j-option').each(function(){ + dv = $(this).attr('data-val') + if($.inArray(dv,specs)>-1){ + $(this).addClass('j-selected'); + } + }) + $('#buyNum').attr('data-max',goodsInfo.sku[key].specStock); + } + } + }else{ + $('#buyNum').attr('data-max',goodsInfo.goodsStock); + } + checkGoodsStock(); + //图片放大镜效果 + CloudZoom.quickStart(); + imagesMove({id:'.goods-pics',items:'.items'}); + //选择规格 + $('.spec .j-option').click(function(){ + $(this).addClass('j-selected').siblings().removeClass('j-selected'); + checkGoodsStock(); + }); + fixedbar(); + $('#tab').TabPanel({tab:0,callback:function(no){ + if(no==1)queryByPage(); + if(no==2)queryConsult(); + }}); + contrastGoods(1,0,2); + // 取消'手机购买'click事件 + $('#wx_qrcode').unbind(); +}); +function fixedbar(){ + var offsetTop = $("#goodsTabs").offset().top; + $(window).scroll(function() { + var scrollTop = $(document).scrollTop(); + if (scrollTop > offsetTop){ + $('#addCart2').show(); + $("#goodsTabs").css("position","fixed"); + $("#wx_qrcode").addClass('wx_qrcode_fixed'); + }else{ + $('#addCart2').hide(); + $("#goodsTabs").css("position", "static"); + $("#wx_qrcode").removeClass('wx_qrcode_fixed'); + } + }); +} +function checkGoodsStock(){ + var specIds = [],stock = 0,goodsPrice=0,marketPrice=0,goodsHuibao=0; + + if(goodsInfo.isSpec==1){ + $('.j-selected').each(function(){ + specIds.push(parseInt($(this).attr('data-val'),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + stock = goodsInfo.sku[specIds.join(':')].specStock; + marketPrice = goodsInfo.sku[specIds.join(':')].marketPrice; + goodsPrice = goodsInfo.sku[specIds.join(':')].specPrice; + goodsHuibao =Math.round(goodsInfo.sku[specIds.join(':')].specPrice * 0.8 * 100) / 100; + + } + }else{ + stock = goodsInfo.goodsStock; + marketPrice = goodsInfo.marketPrice; + goodsPrice = goodsInfo.goodsPrice; + } + $('#goods-stock').html(stock); + $('#j-market-price').html('¥'+marketPrice); + $('#j-shop-price').html('¥'+goodsPrice); + if(goodsHuibao>0){ + $('#j-shop-huibao').html('¥'+goodsHuibao); + } + + if(stock<=0){ + $('#addBtn').addClass('disabled'); + $('#buyBtn').addClass('disabled'); + }else{ + $('#addBtn').removeClass('disabled'); + $('#buyBtn').removeClass('disabled'); + } +} + +function imagesMove(opts){ + var tempLength = 0; //临时变量,当前移动的长度 + var viewNum = 5; //设置每次显示图片的个数量 + var moveNum = 2; //每次移动的数量 + var moveTime = 300; //移动速度,毫秒 + var scrollDiv = $(opts.id+" "+opts.items+" ul"); //进行移动动画的容器 + var scrollItems = $(opts.id+" "+opts.items+" ul li"); //移动容器里的集合 + var moveLength = scrollItems.eq(0).width() * moveNum; //计算每次移动的长度 + var countLength = (scrollItems.length - viewNum) * scrollItems.eq(0).width(); //计算总长度,总个数*单个长度 + + //下一张 + $(opts.id+" .next").bind("click",function(){ + if(tempLength < countLength){ + if((countLength - tempLength) > moveLength){ + scrollDiv.animate({left:"-=" + moveLength + "px"}, moveTime); + tempLength += moveLength; + }else{ + scrollDiv.animate({left:"-=" + (countLength - tempLength) + "px"}, moveTime); + tempLength += (countLength - tempLength); + } + } + }); + //上一张 + $(opts.id+" .prev").bind("click",function(){ + if(tempLength > 0){ + if(tempLength > moveLength){ + scrollDiv.animate({left: "+=" + moveLength + "px"}, moveTime); + tempLength -= moveLength; + }else{ + scrollDiv.animate({left: "+=" + tempLength + "px"}, moveTime); + tempLength = 0; + } + } + }); +} + + +/****************** 商品评价 ******************/ +function showImg(id){ + layer.photos({ + photos: '#img-file-'+id + }); +} +function apprfilter(type){ + $('.appr-filterbox li a').removeClass('curr'); + $('#filtertype').val(type); + queryByPage(1); +} + +var _first=true; +function queryByPage(p){ + var params = {}; + params.page = p; + params.goodsId = goodsInfo.id; + params.anonymous = 1; + params.type = $('#filtertype').val(); + $.post(WST.U('home/goodsappraises/getById'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#ga-box').html(html); + for(var g=0;g<=json.data.Rows.length;g++){ + showImg(g); + } + }); + // 各评价数. + $('#totalNum').html(json.data.sum); + $('#bestNum').html(json.data.bestNum); + $('#goodNum').html(json.data.goodNum); + $('#badNum').html(json.data.badNum); + $('#picNum').html(json.data.picNum); + // 选中当前筛选条件 + $('#'+params.type).addClass('curr'); + if(_first && json.data.sum>0){ + // 好、中、差评率 + var best = parseInt(json.data.bestNum/json.data.sum*100); + var good = parseInt(json.data.goodNum/json.data.sum*100); + var bad = 100-best-good; + $('.best_percent').html(best); + $('.good_percent').html(good); + $('.bad_percent').html(bad); + // 背景色 + $('#best_percentbg').css({width:best+'%'}); + $('#good_percentbg').css({width:good+'%'}); + $('#bad_percentbg').css({width:bad+'%'}); + _first = false; + } + + $('.j-lazyImg').lazyload({ effect: "fadeIn",failurelimit : 10,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + $('.apprimg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.USER_LOGO});//会员默认头像 + laypage({ + cont: 'pager', + pages:json.data.TotalPage, + curr: json.data.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} +function addCart(type,iptId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var goodsSpecId = 0; + if(goodsInfo.isSpec==1){ + var specIds = []; + $('.j-selected').each(function(){ + specIds.push($(this).attr('data-val')); + }); + + if(specIds.length==0){ + WST.msg('请选择你要购买的商品信息',{icon:2}); + } + specIds.sort(function(a,b){return a-b}); + if(goodsInfo.sku[specIds.join(':')]){ + goodsSpecId = goodsInfo.sku[specIds.join(':')].id; + } + } + var buyNum = $(iptId)[0]?$(iptId).val():1; + $.post(WST.U('home/carts/addCart'),{goodsId:goodsInfo.id,goodsSpecId:goodsSpecId,buyNum:buyNum,type:type,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + }else{ + if(type==1){ + location.href=WST.U('home/carts/settlement'); + } + } + }); + getRightCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/******************* 商品咨询 ********************/ + +// 提交商品咨询 +function consultCommit(){ + var params={}; + params.goodsId = goodsInfo.id; + $('[name="pointType"]').each(function(k,v){ + if(v.checked){params.consultType = v.value} + }) + if(!params.consultType){ + WST.msg('请选择咨询类别',{icon:2}); + return; + } + params.consultContent = $('#consultContent').val(); + if(params.consultContent == ''){ + WST.msg('请输入咨询内容',{icon:2}); + return; + } + if(params.consultContent.length<3 || params.consultContent.length>200){ + WST.msg('咨询内容应为3-200个字',{icon:2}); + return; + } + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/goodsconsult/add'),params,function(responData){ + layer.close(load); + var json = WST.toJson(responData); + if(json.status==1){ + // 发布成功 + WST.msg(json.msg,{icon:1},function(){ + // 重置咨询输入框 + $('[name="pointType"]').map(function(k,v){v.checked=false;}); + $('#consultContent').val(' '); + queryConsult(0); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} +function queryConsult(p){ + var params = {}; + params.page = p; + params.goodsId = goodsInfo.id; + params.type = $('#consultType').val(); + params.consultKey = $('#consultKey').val(); + $.post(WST.U('home/goodsconsult/listquery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data.Rows){ + var gettpl = document.getElementById('gclist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#consultBox').html(html); + }); + laypage({ + cont: 'consult-pager', + pages:json.data.TotalPage, + curr: json.data.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryConsult(e.curr); + } + } + }); + } + }); +} +//筛选咨询类别 +function filterConsult(obj, type){ + $('.gc-filter').each(function(k,v){ + $(v).removeClass('curr'); + }) + $(obj).addClass('curr'); + $('#consultType').val(type); + queryConsult(0); +} +//对比商品 +function contrastGoods(show,id,type){ + if(show==1){ + $.post(WST.U('home/goods/contrastGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(type==2 && json.data)$("#j-cont-frame").addClass('show'); + var gettpl = document.getElementById('colist').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#contrastList').html(html); + }); + $('.contImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }else{ + WST.msg(json.msg,{icon:2}); + } + if(type==1)$("#j-cont-frame").addClass('show'); + }); + }else{ + $("#j-cont-frame").removeClass('show'); + } +} +//删除 +function contrastDel(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + contrastGoods(1,0,1); + } + }); +} +function informs($goodsId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + location.href=WST.U("home/informs/inform",'id='+$goodsId); + } diff --git a/hyhproject/home/view/default/js/goodslist.js b/hyhproject/home/view/default/js/goodslist.js new file mode 100755 index 0000000..c47d189 --- /dev/null +++ b/hyhproject/home/view/default/js/goodslist.js @@ -0,0 +1,398 @@ +$(function(){ + $('.goodsImg2').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + WST.dropDownLayer(".item",".dorp-down-layer"); + $('.item-more').click(function(){ + if($(this).attr('v')==1){ + $('.hideItem').show(300,'swing',function(){ + showMoreBtn(); + }); + $(this).find("span").html("收起"); + $(this).find("i").attr({"class":"drop-up"}); + $(this).attr('v',0); + }else{ + $('.hideItem').hide(300); + $(this).find("span").html("更多选项"); + $(this).find("i").attr({"class":"drop-down-icon"}); + $(this).attr('v',1); + } + }); + + $(".item-more").hover(function(){ + if($(this).find("i").hasClass("drop-down-icon")){ + $(this).find("i").attr({"class":"down-hover"}); + }else{ + $(this).find("i").attr({"class":"up-hover"}); + } + + },function(){ + if($(this).find("i").hasClass("down-hover")){ + $(this).find("i").attr({"class":"drop-down"}); + }else{ + $(this).find("i").attr({"class":"drop-up"}); + } + }); + $('.img_list li img').mouseover(function(){ + // 商品列表小图切换 + $(this).parent().siblings().removeClass('curr'); + $(this).parent().addClass('curr'); + var oldImgDom = $(this).parent().parent().parent().children('.img').children().children(); + oldImgDom.attr('src',this.src.replace('_thumb','')); + }) +}); + +function goodsFilter(obj,vtype){ + if(vtype==1){ + $('#brand').val($(obj).attr('v')); + }else if(vtype==2){ + var price = $(obj).attr('v'); + price = price.split('_'); + $('#sprice').val(price[0]); + $('#eprice').val(price[1]); + }else if(vtype==3){ + $('#v_'+$(obj).attr('d')).val($(obj).attr('v')); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + vs.push($(obj).attr('d')); + $('#vs').val(vs.join(',')); + } + var ipts = WST.getParams('.sipt'); + if(vtype==4)ipts['order']='1'; + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); +} +function goodsOrder(orderby){ + if($('#orderBy').val()!=orderby){ + $('#order').val(1); + } + $('#orderBy').val(orderby); + goodsFilter(null,0); +} + + + +function removeFilter(id){ + if(id!='price'){ + $('#'+id).val(''); + if(id.indexOf('v_')>-1){ + id = id.replace('v_',''); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + var nvs = []; + for(var i=0;i<vs.length;i++){ + if(vs[i]!=id)nvs.push(vs[i]); + } + $('#vs').val(nvs.join(',')); + } + }else{ + $('#sprice').val(''); + $('#eprice').val(''); + } + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); +} +/*搜索列表*/ +function searchFilter(obj,vtype){ + if(vtype==1){ + $('#brand').val($(obj).attr('v')); + }else if(vtype==2){ + var price = $(obj).attr('v'); + price = price.split('_'); + $('#sprice').val(price[0]); + $('#eprice').val(price[1]); + }else if(vtype==3){ + $('#v_'+$(obj).attr('d')).val($(obj).attr('v')); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + vs.push($(obj).attr('d')); + $('#vs').val(vs.join(',')); + } + var ipts = WST.getParams('.sipt'); + if(vtype==4)ipts['order']='1'; + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/search',params.join('&'),true); +} +function searchOrder(orderby){ + if($('#orderBy').val()!=orderby){ + $('#order').val(1); + } + $('#orderBy').val(orderby); + searchFilter(null,0); +} + + +/*加入购物车*/ +$('.goods').hover(function(){ + $(this).find('.sale-num').hide(); + $(this).find('.p-add-cart').show(); +},function(){ + $(this).find('.sale-num').show(); + $(this).find('.p-add-cart').hide(); +}) + + + +/*发货地*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + if(ids[2]==1){ + $("li[id^="+preid+"_]").hide(); + $("#"+sid).show(); + }else if(ids[2]==2){ + $('#fl_1_3').hide(); + } + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("ul[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} +function choiceArea(t,pid){ + var areaName = $(t).find('a').html(); + var parent = $(t).parent().attr('id'); + var ids = parent.split("_"); + var preid = "#"+ids[0]+"_"+ids[1]+"_"+ids[2]; + if(ids[2]==3){ + $(preid).find('a').html(areaName); + // 执行发货地筛选 + $('#areaId').val(pid); + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + var url = ($(t).attr('search')==1)?'home/goods/search':'home/goods/lists'; + location.href=WST.U(url,params.join('&')); + }else{ + // 替换当前选中地区 + $(preid).find('a').html(areaName); + $(preid).removeClass('j-tab-selected'+ids[1]); + + + var next = parseInt(ids[2])+1; + var nextid = "#"+ids[0]+"_"+ids[1]+"_"+next; + $(nextid).show(); + $(nextid).addClass("j-tab-selected"+ids[1]); + // 替换下级地图标题 + $(nextid).html('<a href="javascript:void(0)">请选择</a>'); + + // 获取下级地区信息 + $.post(WST.U('home/areas/listQuery'),{parentId:pid},function(data){ + // 判断搜索页面 + var search = $(t).attr('search'); + if(search==1){search = 'search="1"';} + + var json = WST.toJson(data); + if(json.status==1){ + var html = ''; + $(json.data).each(function(k,v){ + + html +='<li onclick="choiceArea(this,'+v.areaId+')" '+search+' ><a href="javascript:void(0)">'+v.areaName+'</a></li>'; + }); + $(nextid+"_pl").html(html); + } + }); + + // 隐藏当前地区,显示下级地区 + var preid = ids[0]+"_"+ids[1]; + $("ul[id^="+preid+"_]").hide(); + $(nextid+"_pl").show(); + } +} + +/*************************************** 筛选 ******************************************/ +function showMoreBtn(){ + // 判断是否需要显示【更多】 + $('.item .content').each(function() { + if (this.scrollHeight > 34) { + $(this).parent().find('.extra .extra_more').css({visibility:'visible'}); + } + }); +} +$(function(){ + showMoreBtn(); +}) +function extra_show(obj){ + $(obj).addClass('extra_more_on'); + $(obj).parent().parent().find('ul').css({height:'auto'}); + $(obj).html('收起<i></i>'); + $(obj).attr('onClick','extra_hide(this)'); +} +function extra_hide(obj){ + // 修改点击事件 + $(obj).removeClass('extra_more_on'); + $(obj).parent().parent().find('ul').css({height:'30px'}); + $(obj).attr('onClick','extra_show(this)'); + $(obj).html('更多<i></i>'); +} +var _preObj; +function multibox_show(obj,type){ + var _topParent = $(obj).parent().parent(); + // 显示被隐藏的选项 + _topParent.find('ul').css({height:'auto'}); + // 给每个li绑定事件 + _topParent.find('ul li').each(function(){ + $(this).attr('_onclick',$(this).attr('onclick')); + $(this).removeAttr('onclick'); + $(this).click(function(){ + $(this).toggleClass('selected'); + ($('li.selected').length>0)?_topParent.find('a.confirm_btn').css({visibility:'visible'}):_topParent.find('a.confirm_btn').css({visibility:'hidden'}); + }) + }) + // 隐藏右侧按钮 + $(obj).parent().hide(); + // 显示多选盒子 + _topParent.addClass('multi_on'); + _topParent.append('<div class="multi_btns"><a class="confirm_btn" href="javascript:void(0)" onClick="multi_done(this,\''+type+'\')">确定</a><a onClick="multibox_hide(this)" href="javascript:void(0)">取消</a></div>') + // 隐藏上一个多选盒子 + if($('.multi_on').length>1){multibox_hide(_preObj)} + _preObj = obj; +} +// 完成多选 +function multi_done(obj,type){ + var ids = [],attrId=0; + // 获取选中的值 + $(obj).parent().parent().find('ul li.selected').each(function(){ + ids.push($(this).attr('v')); + if(type=='attr')attrId = $(this).attr('d'); + }) + if(ids.length==0){ + WST.msg('请选择要筛选的选项'); + return false; + } + if(type=='brand'){ + $('#brand').val(ids.join(',')); + }else if(type=='attr'){ + $('#v_'+attrId).val(ids.join('、'));// 属性名称 -> 双卡双4G_电信4G_移动4G + var vs = $('#vs').val();// 属性id【不需要再拼凑】 + vs = (vs!='')?vs.split(','):[]; + vs.push(attrId); + $('#vs').val(vs.join(',')); + + } + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); + + +} +// 多选隐藏 +function multibox_hide(obj){ + var _topParent = $(obj).parent().parent(); + // 显示被隐藏的选项 + _topParent.find('ul').css({height:'30px'}); + // 给每个li绑定事件 + _topParent.find('ul li').each(function(){ + $(this).unbind('click'); + $(this).attr('onclick',$(this).attr('_onclick')); + $(this).removeAttr('_onclick'); + $(this).removeClass('selected'); + }) + // 显示右侧按钮 + _topParent.find('div.extra').show(); + // 隐藏多选盒子 + _topParent.removeClass('multi_on'); + _topParent.find('div.multi_btns').remove(); + // 设置【更多】按钮 + var _moreBtn = _topParent.find('a.extra_more'); + _moreBtn.removeClass('extra_more_on'); + _moreBtn.attr('onClick','extra_show(this)'); + _moreBtn.html('更多<i></i>'); +} + +//对比商品 +function contrastGoods(show,id,type){ + if(show==1){ + $.post(WST.U('home/goods/contrastGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(type==2 && json.data)$("#j-cont-frame").addClass('show'); + var gettpl = document.getElementById('colist').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#contrastList').html(html); + }); + $('.contImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }else{ + WST.msg(json.msg,{icon:2}); + } + if(type==1)$("#j-cont-frame").addClass('show'); + }); + }else{ + $("#j-cont-frame").removeClass('show'); + } +} +//删除 +function contrastDels(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + contrastGoods(1,0,1); + } + }); +} +//对比商品列表 +//滑动 +function fixedGoods(){ + var offsetTop = $("#goodsTabs").offset().top; + $(window).scroll(function() { + var scrollTop = $(document).scrollTop(); + if (scrollTop > offsetTop){ + $("#goodsTabs").addClass('goods-fixed'); + $("#goodsTabs2").show(); + }else{ + $("#goodsTabs").removeClass('goods-fixed'); + $("#goodsTabs2").hide(); + } + }); +} +//删除 +function contrastDel(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href=WST.U('home/goods/contrast'); + } + }); +} +//筛选条件 +function screenContrast(obj,id){ + if ($(obj).is(':checked')) { + $(".identical_"+id).addClass('active'); + }else{ + $(".identical_"+id).removeClass('active'); + } +} +//筛选规格 +function choiceContrast(obj,itemId,catId,goodsId){ + $(obj).addClass('active').siblings('.list-box li').removeClass('active'); + $("#defaultSpec_"+goodsId+"_"+catId).val(itemId); + var specIds = []; + $(".defaultSpec_"+goodsId).each(function(){ + specIds.push(parseInt($(this).val(),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(saleSpec.sku[goodsId][specIds.join(':')]){ + stock = saleSpec.sku[goodsId][specIds.join(':')].specStock; + marketPrice = saleSpec.sku[goodsId][specIds.join(':')].marketPrice; + goodsPrice = saleSpec.sku[goodsId][specIds.join(':')].specPrice; + } + $('#goods-price-'+goodsId).html('¥ <span>'+goodsPrice+'</span>'); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/index.js b/hyhproject/home/view/default/js/index.js new file mode 100755 index 0000000..c4877a5 --- /dev/null +++ b/hyhproject/home/view/default/js/index.js @@ -0,0 +1,420 @@ +$.fn.TabiPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav .tab').click(function(){ + $(this).addClass("on").siblings().removeClass("on"); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav .tab').eq(opts.tab).click(); +} +$(function(){ + WST.slides('.wst-slide'); + $('#index-tab').TabiPanel({tab:0,callback:function(no){}}); +}); + + + +/*楼层*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("div[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} + + +/*楼层商品 加入购物车*/ +$('.goods').hover(function(){ + $(this).find('.sale-num').hide(); + $(this).find('.f-add-cart').show(); +},function(){ + $(this).find('.sale-num').show(); + $(this).find('.f-add-cart').hide(); +}) + + +/*楼层右侧滚动广告*/ +function floorAds(i){ + var slide = $('#wst-floor-slide-'+i), li = slide.find("li"); + var slidecontrols = $('#wst-floor-slide-controls-'+i), + + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 3000); + span.bind("mouseout", function() { + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} +$(function(){ + //执行楼层右侧广告js + var fRAds = $(this).find("div[id^='wst-floor-slide-controls-']").length; + for(var i=1;i<=fRAds;++i){ + floorAds(i); + } + //执行右侧底部商品切换js + var fBgoods = $(this).find("ul[id^='styleMain']").length; + for(var i=1;i<=fBgoods;++i){ + var li = $('#styleMain'+i).find('li'); + if(li.length>5){ + fBGoods(i); + }else{ + li.each(function(){$(this).css('padding-bottom','0')}) + } + + } +}) + + + + +function fBGoods(id){ + $('#styleMain'+id).bxCarousel({ + display_num: 5, + move: 1, + auto: 0, + controls: true, + prev_image: WST.conf.ROOT+'/hyhproject/home/view/default/img/btn_slide_left.png', + next_image: WST.conf.ROOT+'/hyhproject/home/view/default/img/btn_slide_right.png', + margin: 10, + auto_hover: true + }); +} + +function loadImg(){ + $('.fImg').lazyload({ failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); +} + +/*左侧楼层导航*/ +$(function() { + loadImg(); + }); +$('.lnav').click(function(){ + var i = $(this).index()+1; + i = i+'F'; + $("html,body").animate({scrollTop: $("a[name='"+i+"']").offset().top-7}, 500); +}) + +function leftNav(){ + //内容距离左边空白处宽度 + var containerW = $('.wst-container').offset().left; + left = containerW-40; + $('#screen-left-nav').css('left', left); +} +$(window).resize(function(){leftNav()}); + + +var currF,first=true; + +function cf(){ + var sumFloor = $('.floor-box').length; + for(var f=sumFloor;f>=1;--f){ + var id = '#c'+f; + if($(id).offset().top+500-$(window).scrollTop()>0){ + currF = f; + first = false; + lcurr(f) + } + } +} + + +//内容高度 +var containerH = parseInt($('.wst-main').css('height')); +$(window).scroll(function(){ +leftNav(); +//滚动条当前高度 +var scrollHeight = $(window).scrollTop(); + +// 楼层选中 +if(first){ + cf(); +}else{ + var cfh = $('#c'+currF).offset().top+500-$(window).scrollTop(); + if(cfh<0 || cfh>1200)cf(); + +} + +if(scrollHeight>=462 && scrollHeight<containerH+200){ + $('#screen-left-nav').show(); +}else{ + $('#screen-left-nav').hide(); +} + +}); +function lcurr(F){ + $('#F'+F).siblings().removeClass('lcurr'); + $('#F'+F).addClass('lcurr'); +} + +/*签到*/ +function inSign(){ + $("#j-sign").attr('disabled', 'disabled'); + $.post(WST.U('home/userscores/signScore'),{},function(data){ + var json = WST.toJson(data,true); + if(json.status==1){ + $("#j-sign .plus").html('+'+json.data.score); + $("#currentScore").html(json.data.totalScore); + $("#j-sign").addClass('active'); + setInterval(function(){ + $("#j-sign").addClass('actives').html('已签到'); + },600); + WST.msg(json.msg, {icon: 1}); + }else{ + WST.msg(json.msg, {icon: 5}); + $("#j-sign").removeAttr('disabled'); + } + }); +} +WST.countDown = function(opts){ + var f = { + zero: function(n){ + var n = parseInt(n, 10); + if(n > 0){ + if(n <= 9){ + n = n; + } + return String(n); + }else{ + return "0"; + } + }, + count: function(){ + if(opts.nowTime){ + var d = new Date(); + d.setTime(opts.nowTime.getTime()+1000); + opts.nowTime = d; + d = null; + }else{ + opts.nowTime = new Date(); + } + //现在将来秒差值 + var dur = Math.round((opts.endTime.getTime() - opts.nowTime.getTime()) / 1000), pms = { + sec: "0", + mini: "0", + hour: "0", + day: "0" + }; + if(dur > 0){ + pms.sec = f.zero(dur % 60); + pms.mini = Math.floor((dur / 60)) > 0? f.zero(Math.floor((dur / 60)) % 60) : "0"; + pms.hour = Math.floor((dur / 3600)) > 0? f.zero(Math.floor((dur / 3600)) % 24) : "0"; + pms.day = Math.floor((dur / 86400)) > 0? f.zero(Math.floor(dur / 86400)) : "0"; + } + pms.last = dur; + pms.nowTime = opts.nowTime; + opts.callback(pms); + if(pms.last>0)setTimeout(f.count, 1000); + } + }; + f.count(); +}; +// 拍卖轮播 +$(function(){ + var _p = $('.aution_list'); + var step = _p.width();// 步进值 + var totalItem = $('.aution_list .aution_main').length;// 总拍卖商品数 + if(totalItem==0)return; + var au_lbtn = $('.au_l_btn'); + var au_rbtn = $('.au_r_btn'); + + $('.ws-right-user').css({height:'85px',overflow:'hidden'});// 确保右侧不溢出轮播区域 + var nowTime = new Date(Date.parse($('.aution_list').attr('sc').replace(/-/g, "/"))); + // 倒计时 + $('.aution_main').each(function(){ + var g = $(this); + var startTime = new Date(Date.parse(g.attr('sv').replace(/-/g, "/"))); + var endTime = new Date(Date.parse(g.attr('ev').replace(/-/g, "/"))); + if(startTime.getTime()<= nowTime && endTime.getTime() >=nowTime){ + var opts = { + nowTime: nowTime, + endTime: endTime, + callback: function(data){ + if(data.last>0){ + g.find('.aution_time .aution_h').html(data.hour); + g.find('.aution_time .aution_i').html(data.mini); + g.find('.aution_time .aution_s').html(data.sec); + }else{ + g.find('.aution_time').html('拍卖活动已结束'); + } + + } + }; + WST.countDown(opts); + }else{ + g.find('.aution_time').html('拍卖活动已结束'); + } + }) + + // 设置父容器宽度 + _p.css({width:totalItem+'00%'}); + var _curr = 0;// 当前显示的index + // 右切换按钮 + au_rbtn.click(function(){ + _curr++; + if (_curr + 1 > totalItem) { _curr = 0 } + au_s(); + return false; + }); + // 左切换按钮 + au_lbtn.click(function(){ + _curr--; + if (_curr + 1 < 1) { + _curr = totalItem - 1 + } + au_s(); + return false; + }); + function au_auto_swiper() { y = setInterval(function () { au_rbtn.click() }, 5000) } + au_auto_swiper(); + $('.aution_out').bind({ mouseover: function () { clearInterval(y);au_lbtn.show();au_rbtn.show(); }, mouseout: function () { au_auto_swiper();au_lbtn.hide();au_rbtn.hide(); } }) + // 执行切换 + function au_s(){ + _p.stop().animate({left:-_curr*step}); + } +}) + +// 团购轮播 +$(function(){ + var g_list_time; + var g_obj = $('.groupon_view'); + var g_step = g_obj.width();// 步进值 + var g_list = $('.groupon_list'); // 轮播对象 + // 设置长度 + var g_list_w = $('.groupon_list li').length; + g_list.css({width:g_list_w*100+'%'}); + var g_list_i = 0; + + // 按钮 + $('.groupon_btns span').each(function(k,v){ + $(this).mouseover(function(){ + clearInterval(g_list_time); + g_list_i = k; + g_list_auto(); + }) + }); + $('.groupon_btns').mouseout(function(){glistautoplay();}) + function glistautoplay(){ + clearInterval(g_list_time); + g_list_time = setInterval(function(){ + g_list_i++; + if (g_list_i + 1 > g_list_w) { g_list_i = 0 } + g_list_auto(); + },3000); + } + function g_list_auto(){ + g_list.stop().animate({left:-g_list_i*g_step}); + $('.groupon_btns span').removeClass('curr').eq(g_list_i).addClass('curr') + } + glistautoplay(); +}); + + + +// 楼层商品轮播 +$(function(){ + var a = $(".floor_silder"); + a.each(function () { + var q = $(this); + var s = q.find("ul"); + var t = q.find("ul li"); + var c = q.find(".prev_btn"); + var w = q.find(".next_btn"); + var u = t.length; + // q.find(".show_num").find("em").html(u); + if (u == 1) { return } + var p = 0; + var y = 0; + var x = 3000; // 轮播间隔 + w.click(function () { // 下一张 + p++; + if (p + 1 > u) { p = 0 } + z(p); + v(); + return false + }); + c.click(function () { // 上一张 + p--; + if (p + 1 < 1) { + p = u - 1 + } + z(p); + v(); + return false + }); + function z(e) {// 执行轮播 + switch (e) { + case 2: + t.eq(e).css("z-index", 100).stop().animate({ width: 155, height: 225, left: 20, top: 0 }); + t.eq(e - 1).css("z-index", 80).stop().animate({ width: 195, height: 170, left: 0, top:30 }); + t.eq(e - 2).css("z-index", 90).stop().animate({ width: 175, height: 200, left: 10, top: 15 }); + t.eq(e).find(".color_mask").stop().animate({ opacity: 0 }); + t.eq(e - 1).find(".color_mask").stop().animate({ opacity: 0.7 }); + t.eq(e - 2).find(".color_mask").stop().animate({ opacity: 0.5 }); + break; + default: + t.eq(e).css("z-index", 100).stop().animate({ width: 155, height: 225, left: 20, top: 0 }); + t.eq(e - 1).css("z-index", 80).stop().animate({ width: 195, height: 170, left: 0, top: 30 }); + t.eq(e + 1).css("z-index", 90).stop().animate({ width: 175, height: 200, left: 10, top: 15 }); + t.eq(e).find(".color_mask").stop().animate({ opacity: 0 }); + t.eq(e - 1).find(".color_mask").stop().animate({ opacity: 0.7 }); + t.eq(e + 1).find(".color_mask").stop().animate({ opacity: 0.5 }); + } + } + function v() { + // 当前显示张数 + q.find(".show_num").find("span").removeClass('curr').eq(p).addClass('curr'); + } + function r() { y = setInterval(function () { w.click() }, x) } + r(); + $(this).bind({ mouseover: function () { clearInterval(y) }, mouseout: function () { r() } }) + }) + }) \ No newline at end of file diff --git a/hyhproject/home/view/default/js/jquery.als.js b/hyhproject/home/view/default/js/jquery.als.js new file mode 100755 index 0000000..74e1dbb --- /dev/null +++ b/hyhproject/home/view/default/js/jquery.als.js @@ -0,0 +1,1714 @@ +/** + * jquery.als.js + * http://als.musings.it + * jQuery plugin for list scrolling (any list with any content) + * developed for http://www.musings.it and released as a freebie + * + * animations: horizontal slide, vertical slide of lists + * types of lists: images, texts, inserted as div or as ul - li + * + * CONFIGURABLE PARAMETERS + * visible_elements: number of visible elements of a list + * scrolling_items: list scrolling step + * orientation: list orientation ("horizontal" or "vertical") + * circular: "yes" for infinite list scrolling, "no" on the contrary + * autoscroll: "yes" for automatic scrolling, "no" on the contrary + * interval: if autoscroll "yes" is the time interval between scrolling movements + * speed: speed of the scrolling movement (in msec) + * easing: easing function to use for the scrolling movement ("swing" or "linear") + * direction: if autoscroll "yes" is the scrolling direction ("left","right","up","down") + * start_from: start the scroller from a specific item (default: 0, first item) + * + * CONFIGURATION EXAMPLE: + * $("#lista").als({ + * visible_items: 4, + * scrolling_items: 2, + * orientation: "horizontal", + * circular: "yes", + * autoscroll: "yes", + * interval: 5000, + * speed: 600, + * easing: "linear", + * direction: "right", + * start_from: 0 + * }); + * + * @author Federica Sibella + * Copyright (c) 2012/14 Federica Sibella - musings(at)musings(dot)it | http://www.musings.it + * Released with double license MIT o GPLv3. + * Date: 2014/09/17 + * @version 1.7 + * + * Changelog: + * 2014.09.17: minor bug fixes on configuration controls and timeout reset on click with autoscroll + * 2014.06.17: minor bug fix on swipe control for non circular scrolling + * 2014.05.21: minor bugs revisions: destroy method and touch controls revisited + * 2014.03.24: added swipe support for touch devices + * 2014.02.01: minor bug fixes for height and width of cross-dimension (w/ respect to ALS scrolling direction) + * 2014.01.10: enhanced "destroy" method (no more instance ID needed); scroll speed as setting; easing option as setting + * 2013.04.11: added "start_from" option + * 2013.09.04: enhanced "destroy" method based on single instance + * 2013.09.13: fixed issue on initial viewport width if items widths are different from each other and start_from != 0 + */ + + + (function($){ + /********************************************************** + * Variables: als (contains data of the current instance), + * instance (number of the current instance), + * methods (methods of als plugin) + *********************************************************/ + var als = [], + instance = 0; + var methods = { + /****************************************************** + * plugin inizialization + * @param {Object} options: configuration options + ******************************************************/ + init: function(options) { + this.each(function() { + var defaults = { + visible_items: 3, + scrolling_items: 1, + orientation: "horizontal", + circular: "no", + autoscroll: "no", + interval: 4000, + speed: 600, + easing: "swing", + direction: "left", + start_from: 0 + }, + $obj = $(this), + data = $obj.data("als"), + $options = $(), + $item = $(), + $wrapper = $(), + $viewport = $(), + $prev = $(), + $next = $(), + num_items = 0, + viewport_width = 0, + wrapper_width = 0, + viewport_height = 0, + wrapper_height = 0, + initial_movement = 0, + maxHeight = 0, + maxWidth = 0, + i = 0, + j = 0, + current = 0, + timer = 0, + mm = {}; + + mm.swipeTreshold = 100, + mm.allowedTime = 300; + + $options = $.extend(defaults, options); + + /********************************************************************* + * configuration controls: autoscroll option implies + * infinite circular scrolling + *********************************************************************/ + if($options.circular == "no" && $options.autoscroll == "yes") + { + $options.circular = "yes"; + } + + /************************************* + * checking easing option + *************************************/ + if($options.easing != "linear" || $options.easing != "swing") + { + $options.easing = "swing"; + } + + /*********************************************************************************** + * define ID for the different plugin section to name them directly + **********************************************************************************/ + if(!$obj.attr("id") || $obj.attr("id") == "") + { + $obj.attr("id","als-container_" + instance); + } + + $obj.attr("data-id","als-container_" + instance); + $viewport = $obj.find(".als-viewport").attr("data-id","als-viewport_" + instance); + $wrapper = $obj.find(".als-wrapper").attr("data-id","als-wrapper_" + instance); + $item = $obj.find(".als-item"); + num_items = $item.size(); + + /*************************************************************************************** + * configuration controls: number of visible element can not be higher than + * total number of list element and scrolling items can not be more + * than visible items + * start_from number can not be higher than total number of list elements + ***************************************************************************************/ + if($options.visible_items > num_items) + { + $options.visible_items = num_items - 1; + } + + if($options.scrolling_items > $options.visible_items) + { + if($options.visible_items > 1) + { + $options.scrolling_items = $options.visible_items - 1; + } + else if($options.visible_items === 1) + { + $options.scrolling_items = $options.visible_items; + } + } + + if($options.start_from > num_items - $options.visible_items) + { + $options.start_from = 0; + } + + /****************************************************** + * prev and next button inizialization (if present) + ******************************************************/ + $prev = $obj.find(".als-prev").attr("data-id","als-prev_" + instance); + $next = $obj.find(".als-next").attr("data-id","als-next_" + instance); + + /********************************************************************* + * relative to chosen orientation I calculate width and height + * of the list wrapper (wrapper) and of the list viewport (viewport) + * @param {Object} index: internal elements index + *********************************************************************/ + switch($options.orientation) + { + case "horizontal": + default: + $item.each(function(index) + { + $(this).attr("id","als-item_" + instance + "_" + index); + wrapper_width += $(this).outerWidth(true); + + if($(this).outerHeight(true) > maxHeight) + { + maxHeight = $(this).outerHeight(true); + } + + if(i < $options.visible_items) + { + if($options.start_from == 0) + { + viewport_width += $(this).outerWidth(true); + i++; + } + else + { + if(index >= $options.start_from) + { + viewport_width += $(this).outerWidth(true); + i++; + } + } + } + + if($options.start_from != 0) + { + if(j < $options.start_from) + { + initial_movement += $(this).outerWidth(true); + j++; + } + current = $options.start_from; + } + }); + $wrapper.css("width", wrapper_width); + $item.css("left", -initial_movement); + $viewport.css("width", viewport_width); + $wrapper.css("height", maxHeight); + $viewport.css("height", maxHeight); + + if($options.circular == "yes" && $options.start_from != 0) + { + /**************************************************** + * must reset the hidden elements if start_from != 0 + ****************************************************/ + for (r = 0; r < $options.start_from; r++) + { + var position = $item.last().position(), + right_repos = position.left + $item.last().outerWidth(true); + $item.eq(r).css("left", right_repos); + } + } + break; + case "vertical": + $item.each(function(index) + { + $(this).attr("id","als-item_" + instance + "_" + index); + wrapper_height += $(this).outerHeight(true); + + if($(this).outerWidth(true) > maxWidth) + { + maxWidth = $(this).outerWidth(true); + } + + if(i < $options.visible_items) + { + if($options.start_from == 0) + { + viewport_height += $(this).outerHeight(true); + i++; + } + else + { + if(index >= $options.start_from) + { + viewport_height += $(this).outerHeight(true); + i++; + } + } + } + + if($options.start_from != 0) + { + if(j < $options.start_from) + { + initial_movement += $(this).outerHeight(true); + j++; + } + current = $options.start_from; + } + }); + $wrapper.css("height", wrapper_height); + $item.css("top", -initial_movement); + $viewport.css("height", viewport_height); + $wrapper.css("width", maxWidth); + $viewport.css("width", maxWidth); + + if($options.circular == "yes" && $options.start_from != 0) + { + /**************************************************** + * must reset the hidden elements if start_from != 0 + ****************************************************/ + for (r = 0; r < $options.start_from; r++) + { + var position = $item.last().position(), + bottom_repos = position.top + $item.last().outerHeight(true); + $item.eq(r).css("top", bottom_repos); + } + } + break + } + /************************************************** + * if circular == no don't show prev button + * at the beginning but only if start_from == 0 + **************************************************/ + if($options.circular == "no") + { + if($options.start_from == 0) + { + $prev.css("display","none"); + } + if($options.visible_items + $options.start_from == num_items) + { + $next.css("display","none"); + } + } + + + /****************************************** + * prev and next buttons inizialization + ******************************************/ + $next.on("click touchstart touchend",nextHandle); + $prev.on("click touchstart touchend",prevHandle); + + + /***************************************** + * initializing swipe-touch control + *****************************************/ + $viewport.on('touchstart', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.ox = touch.pageX; + mm.oy = touch.pageY; + mm.startTime = new Date().getTime(); + }); + + $viewport.on('touchmove', function(e) { + }); + + $viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if($options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll forth on swipe only if circular or if start_from < num_items + if($options.circular == "yes" || $options.visible_items + $options.start_from < num_items) { + nextHandle(e,$viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll back on swipe only if circular or if start_from > 0 + if($options.circular == "yes" || $options.start_from > 0) { + prevHandle(e,$viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll forth on swipe only if circular or if start_from < num_items + if($options.circular == "yes" || $options.visible_items + $options.start_from < num_items) { + nextHandle(e,$viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll back on swipe only if circular or if start_from > 0 + if($options.circular == "yes" || $options.start_from > 0) { + prevHandle(e,$viewport); + } + } + } + }); + + + /************************************************** + * saving instance parameters in a variable (data) + * for future use + **************************************************/ + $obj.data('als', + { + container : $obj, + instance : instance, + options : $options, + viewport : $viewport, + wrapper : $wrapper, + prev : $prev, + next : $next, + item : $item, + num_items : num_items, + wrapper_width : wrapper_width, + viewport_width : viewport_width, + wrapper_height : wrapper_height, + viewport_height : viewport_height, + current : current, + timer : timer, + mm : mm + }); + + data = $obj.data('als'); + als[instance] = data; + + /********************************************* + * automatic scrolling function inizialization + * if it is the case + *********************************************/ + if($options.autoscroll == "yes") + { + $.fn.als('start',instance); + $wrapper.hover(function() + { + $.fn.als('stop',$(this).attr("data-id")); + },function() + { + $.fn.als('start',$(this).attr("data-id")); + }); + } + else if($options.autoscroll == "no") + { + $.fn.als('stop',instance); + } + + /******************************************* + * increasing instance number and + * returning als variable now inizialized + ******************************************/ + instance++; + return als; + }); + }, + /***************************************************** + * step function for lists elements + * @param {Object} id: instance or ID of the element + * that calls the function + *****************************************************/ + next: function(id){ + id = find_instance(id); + var data = als[id], + mm = data.mm, + k1 = 0, k2 = 0; + /*************************************************** + * depending on list orientation I calculate + * the element horizontal or vertical movement + ***************************************************/ + switch(data.options.orientation) + { + /***************************************** + * list orientation: horizontal + ****************************************/ + case "horizontal": + default: + var shift_left = 0, + viewport_width = 0; + /************************************************ + * depending on scrolling type I calculate + * the movement and the repositioning of the + * list elements + ************************************************/ + switch(data.options.circular) + { + /**************************** + * infinite scrolling: no + ****************************/ + case "no": + default: + /******************************************************************** + * I calculate the elements' movement on the basis of the scrolling + * items number starting from the current index + ********************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + shift_left += data.item.eq(k1).outerWidth(true); + } + + /**************************************************************** + * I modify the current element on the basis of the scrolling + * elements number + ****************************************************************/ + data.current += data.options.scrolling_items; + + /******************************************************************* + * I calculate the viewport width on the basis of the width of the + * elements that will be visible AFTER the animation + *******************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_width += data.item.eq(k2).outerWidth(true); + } + + /******************************************************** + * I animate the viewport width + ********************************************************/ + data.viewport.animate({ + "width": viewport_width + }, data.options.speed, data.options.easing); + + /********************************************** + * I animate the scrolling elements + *********************************************/ + data.item.animate({ + "left": "-=" + shift_left + }, data.options.speed, data.options.easing); + /*********************************************************** + * after the animation of all elements has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { /**************************************************** + * I bind again the "click" action to the prev + * and next buttons (unbinded to prevent undesirable + * behaviour during the scrolling animation) + ***************************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + /********************************************************** + * visibility control of the prev and next buttons + **********************************************************/ + if(data.current > 0) + { + data.prev.show(); + } + + if (data.current + data.options.visible_items >= data.num_items) + { + data.next.hide(); + } + break; + /**************************** + * infinite scrolling: yes + ***************************/ + case "yes": + var memo = 0, memo_index = []; + /************************************************************************** + * I calculate displacement and memorize indices of the elements that + * I have to move because they will be then repositioned in the queue + **************************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /****************************************************** + * I control if I exceed the total number of elements + ******************************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_left += data.item.eq(k3).outerWidth(true); + memo_index[memo]= k3; + memo ++; + } + /**************************************************************** + * edit current element as a function of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /****************************************************** + * I control if I exceed the total number of elements + ******************************************************/ + if(data.current >= data.num_items) + { + data.current -= data.num_items; + } + /*********************************************************************** + * calculating the extent of the viewport based on the items that + * will be visible after scrolling + ***********************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /***************************************************** + * I control if I exceed the total number of elements + *****************************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_width += data.item.eq(k4).outerWidth(true); + } + + /****************************************************** + * viewport width animation + ******************************************************/ + data.viewport.animate({ + "width": viewport_width + }, data.options.speed, data.options.easing); + + /****************************************************************** + * scrolling animation of elements and repositioning of elements + * stored in the queue + *****************************************************************/ + data.item.animate({ + "left": "-=" + shift_left + }, data.options.speed, data.options.easing); + /*********************************************************** + * once the animation of all the elements has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { + /**************************************************************************** + * repositioning is calculated based on the location of the last element of + * the list, double check if I have to move the first element + ****************************************************************************/ + var position = data.item.last().position(), + right_repos = position.left + data.item.last().outerWidth(true); + for(k5 = 0; k5 < memo_index.length; k5++) + { + if(memo_index[k5] == 0) + { + var position = data.item.last().position(), + right_repos = position.left + data.item.last().outerWidth(true); + } + data.item.eq(memo_index[k5]).css("left", right_repos); + } + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + break; + } + break; + + /************************************** + * list orientation: vertical + **************************************/ + case "vertical": + var shift_top = 0, + viewport_height = 0; + /************************************************ + * depending on the type of sliding I calcule + * the displacement and the repositioning of the + * elements of the list + ************************************************/ + switch(data.options.circular) + { + /**************************** + * infinite scrolling: no + ***************************/ + case "no": + default: + /******************************************************************** + * displacement calculation based on the number of elements to + * slide in a single step + ********************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_top += data.item.eq(k1).outerHeight(true); + } + + /**************************************************************** + * I edit element current as a function of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /*********************************************************************** + * calculating the width of the viewport on the basis of the visible + * elements AFTER the sliding animation + ***********************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) { + viewport_height += data.item.eq(k2).outerHeight(true); + } + + /*************************************************** + * I animate the viewport width + ***************************************************/ + data.viewport.animate({ + "height": viewport_height + }, data.options.speed, data.options.easing); + /**************************************** + * I animate the elements scrolling + ****************************************/ + data.item.animate({ + "top": "-=" + shift_top + }, data.options.speed, data.options.easing); + /********************************************************** + * once the animation of all the elements has finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that has + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + + /**************************************************** + * control visibility of the scroll buttons on + * the basis of the current element + ****************************************************/ + if(data.current > 0) + { + data.prev.show(); + } + + if (data.current + data.options.visible_items >= data.num_items) + { + data.next.hide(); + } + break; + /**************************** + * infinite scrolling: yes + ****************************/ + case "yes": + var memo = 0, memo_index = []; + /**************************************************************** + * displacement calculation based on the number of elements to + * slide in a single step and memorization of items to reposition + ****************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_top += data.item.eq(k3).outerHeight(true); + memo_index[memo]= k3; + memo ++; + } + /**************************************************************** + * edit current element on the basis of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /************************************************* + * control that the index does not exceed the + * total number of the elements + ************************************************/ + if(data.current >= data.num_items) + { + data.current -= data.num_items; + } + + /****************************************************************************** + * calculating the width of viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_height += data.item.eq(k4).outerHeight(true); + } + /************************************************* + * I animate the viewport width + *************************************************/ + data.viewport.animate({ + "height": viewport_height + }); + + /**************************************************************** + * I animate the elements and reposition those previously stored + ***************************************************************/ + data.item.animate({ + "top": "-=" + shift_top + }); + /************************************************************ + * once all the elements' animations has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { + /************************************************************************ + * repositioning is calculated based on the location of the last element + * of the list. Take care to the repositioning of the first element + * that needs to be recalculated AFTER the last was eventually relocated + ************************************************************************/ + var position = data.item.last().position(), + bottom_repos = position.top + data.item.last().outerHeight(true); + for(k5 = 0; k5 < memo_index.length; k5++) + { + if(memo_index[k5] == 0) + { + var position = data.item.last().position(), + bottom_repos = position.top + data.item.last().outerHeight(true); + } + data.item.eq(memo_index[k5]).css("top", bottom_repos); + } + /********************************************* + * re bind buttons "click" event that has + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + break; + } + break; + } + + /************************************ + * save the data in als instance and + * return als object + ***********************************/ + als[id] = data; + return als; + }, + /***************************************************** + * sliding back function of the list elements + * @param {Object} id: instance or ID of the element + * that calls the function + *****************************************************/ + prev: function(id){ + id = find_instance(id); + var data = als[id], + mm = data.mm, + k1 = 0, k2 = 0; + /*************************************************** + * depending on the orientation of the list I + * calculate the horizontal or vertical displacement + * of the elements + ***************************************************/ + switch(data.options.orientation) + { + /*************************** + * horizontal orientation + ***************************/ + case "horizontal": + default: + var shift_right = 0, + viewport_width = 0; + /**************************************************** + * depending on the type of scroll (circular or not) + * I calculate the displacement and the possible + * repositioning of the elements of the list + ****************************************************/ + switch(data.options.circular) + { + /***************************** + * circular scrolling: no + *****************************/ + case "no": + default: + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that you can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + + /******************************************************************* + * calculating the displacement of the elements according to the + * number of elements to slide in a single step + *******************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_right += data.item.eq(k1).outerWidth(true); + } + + /****************************************************************************** + * calculation of the viewport width on the basis of the visible elements + * AFTER the scrolling (on the basis of their width) + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_width += data.item.eq(k2).outerWidth(true); + } + /************************************************* + * animating the viewport width + *************************************************/ + data.viewport.animate({ + "width": viewport_width + }); + /********************************** + * animating elements scrolling + **********************************/ + data.item.animate({ + "left": "+=" + shift_right + }, data.options.speed, data.options.easing); + /*********************************************************** + * once all animations have finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + + /********************************************************** + * control visibility of the scroll buttons + **********************************************************/ + if(data.current <= 0) + { + data.prev.hide(); + } + if (data.current + data.options.visible_items < data.num_items) + { + data.next.show(); + } + break; + /***************************** + * circular scrolling: yes + *****************************/ + case "yes": + var memo = 0, memo_index = []; + /*************************************************************** + * edit the current item index as a function of the elements + * to slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /************************************************** + * check if the current element has not index < 0 + **************************************************/ + if(data.current < 0) + { + data.current += data.num_items; + } + /**************************************************************** + * displacement calculation based on the elements to slide in a + * single step and memorization of the items to reposition + ****************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_right += data.item.eq(k3).outerWidth(true); + memo_index[memo]= k3; + + memo ++; + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the + * visible elements AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_width += data.item.eq(k4).outerWidth(true); + } + /************************************************************************ + * repositioning is calculated based on the location of the first element + * of the list. Special care to the repositioning of the last element + * that needs to be recalculated AFTER the first was eventually relocated + ************************************************************************/ + var position = data.item.first().position(), + left_repos = position.left - data.wrapper_width; + + for(k5 = 0; k5 < memo_index.length; k5++) + { + data.item.eq(memo_index[k5]).css("left", left_repos); + if(memo_index[k5] == 0) + { + var position0 = data.item.eq(0).position(), + new_left_repos = position0.left - data.wrapper_width; + for(k6 = 0; k6 < k5; k6++) + { + data.item.eq(memo_index[k6]).css("left", new_left_repos); + } + } + } + /************************************************************ + * timeout of 200ms is necessary to wait before making the + * scrolling animation, otherwise we can not properly manage + * the repositioning of the list elements + ************************************************************/ + setTimeout(function() + { + /**************************************** + * viewport width animation + ****************************************/ + data.viewport.animate({ + "width": viewport_width + }); + /******************************* + * list elements animation + *******************************/ + data.item.animate({ + "left": "+=" + shift_right + }, data.options.speed, data.options.easing); + /********************************************************** + * once all elements animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + }, 200); + break; + } + break; + /************************* + * vertical orientation + ************************/ + case "vertical": + var shift_bottom = 0, + viewport_height = 0; + + switch(data.options.circular) + { + /***************************** + * circular scrolling: no + ****************************/ + case "no": + default: + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /**************************************************************** + * displacement calculation based on the elements to slide + * in a single step + ****************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_bottom += data.item.eq(k1).outerHeight(true); + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_height += data.item.eq(k2).outerHeight(true); + } + /*********************************************** + * viewport width animation + **********************************************/ + data.viewport.animate({ + "height": viewport_height + }); + /***************************************** + * list elements scrolling animation + *****************************************/ + data.item.animate({ + "top": "+=" + shift_bottom + }, data.options.speed, data.options.easing); + /********************************************************** + * once all elemets animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + /*********************************************************** + * management of visibility of forward and backward buttons + **********************************************************/ + if(data.current <= 0) + { + data.prev.hide(); + } + if (data.current + data.options.visible_items < data.num_items) + { + data.next.show(); + } + break; + case "yes": + /***************************** + * circular scrolling: yes + *****************************/ + var memo = 0, memo_index = []; + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /********************************************************* + * control that the current element has not index < 0 + *********************************************************/ + if(data.current < 0) + { + data.current += data.num_items; + } + /******************************************************************** + * displacement calculation based on the elements to slide in a + * single step and memorization of those that have to be repositioned + * later + ********************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /*********************************************** + * control that the index does not exceed the + * total number of the elements + ***********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_bottom += data.item.eq(k3).outerHeight(true); + memo_index[memo]= k3; + + memo ++; + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /*********************************************** + * control that the index does not exceed the + * total number of the elements + ***********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_height += data.item.eq(k4).outerHeight(true); + } + /************************************************************************ + * repositioning is calculated based on the location of the first element + * of the list. Special care to the repositioning of the last element + * that needs to be recalculated AFTER the first was eventually relocated + ************************************************************************/ + var position = data.item.first().position(), + top_repos = position.top - data.wrapper_height; + + for(k5 = 0; k5 < memo_index.length; k5++) + { + data.item.eq(memo_index[k5]).css("top", top_repos); + if(memo_index[k5] == 0) + { + var position0 = data.item.eq(0).position(), + new_top_repos = position0.top - data.wrapper_height; + for(k6 = 0; k6 < k5; k6++) + { + data.item.eq(memo_index[k6]).css("top", new_top_repos); + } + } + } + /************************************************************ + * timeout of 200ms is necessary to wait before making the + * scrolling animation, otherwise we can not properly manage + * the repositioning of the list elements + ************************************************************/ + setTimeout(function() + { + /********************************************* + * viewport width animation + *********************************************/ + data.viewport.animate({ + "height": viewport_height + }, data.options.speed, data.options.easing); + /************************************ + * list elements scrolling animation + ***********************************/ + data.item.animate({ + "top": "+=" + shift_bottom + }, data.options.speed, data.options.easing); + /*********************************************************** + * once all elements animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + }, 200); + break; + } + break; + } + /************************************ + * saving als instance data and + * returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************************************** + * start function for automatic scrolling + * @param {Object} id: instance or ID of the element that has + * called the function + **************************************************************/ + start: function(id) + { + id = find_instance(id); + var data = als[id]; + /********************************************************** + * stopping any previous automatic scrolling + *********************************************************/ + if(data.timer != 0) + { + clearInterval(data.timer); + } + /************************************ + * depending on the direction you + * choose automatic scrolling begins + ***********************************/ + switch(data.options.direction) + { + /************************************************ + * if left or up (that means "forward") + ************************************************/ + case "left": + case "up": + default: + /************************************ + * detachment from the handler buttons + * and the animation forward start + * (next function) + ************************************/ + data.timer = setInterval(function(){ + data.next.off(); + data.prev.off(); + data.viewport.off("touchend"); + $.fn.als('next',id); + },data.options.interval); + break; + /*************************************************** + * if right or down (that means "backward") + ***************************************************/ + case "right": + case "down": + /************************************ + * detachment from the handler buttons + * and the animation forward start + * (prev function) + ************************************/ + data.timer = setInterval(function(){ + data.prev.off(); + data.next.off(); + data.viewport.off("touchend"); + $.fn.als('prev',id); + },data.options.interval); + break; + } + /************************************ + * saving als instance data and + * returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************************************** + * stop function for automatic scrolling + * @param {Object} id: instance or ID of the element that + * called the function + **************************************************************/ + stop: function(id) + { + id = find_instance(id); + var data = als[id]; + /******************************** + * stop autoscrolling + *******************************/ + clearInterval(data.timer); + /************************************ + * saving data into als instance + * and returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************** + * function that destroys als instance + **************************************/ + destroy: function() + { + id = find_instance($(this).attr("data-id")); + var data = als[id]; + data.prev.off(); + data.next.off(); + data.viewport.off(); + $.fn.als("stop",id); + $.removeData(data, "als"); + this.unbind(); + this.element = null; + } + } + + /************************** + ************************** + * service functions + ************************** + **************************/ + + /******************************************************************** + * function to find the current plugin instance + * @param {Object} id: plugin instance od ID of the element that + * called the plugin + ********************************************************************/ + function find_instance(id) + { + if(typeof(id) === "string") + { + var position = id.indexOf("_"); + if(position != -1) + { + id = id.substr(position+1); + } + } + return id + } + + /**************************************************** + * function that manages "click" action on next button + * @param e event, $obj object + ***************************************************/ + function nextHandle(e,$obj) + { + e.preventDefault(); + if($obj === undefined) + $obj = $(this); + var id = find_instance($obj.attr("data-id")), + data = als[id]; + /********************************************* + * unbinding next and prev buttons so that + * they don't interfere with current animation + ********************************************/ + data.next.off(); + data.prev.off(); + data.viewport.off("touchend"); + if(data.options.autoscroll === "yes") + { + $.fn.als("stop",id); + } + /******************************************** + * calling next function on this instance + ********************************************/ + $.fn.als("next",id); + if(data.options.autoscroll === "yes") + { + $.fn.als("start",id); + } + } + + /****************************************************** + * function that manages "click" action on prev button + * @param e event, $obj object + ******************************************************/ + function prevHandle(e,$obj) + { + e.preventDefault(); + if($obj === undefined) + $obj = $(this); + var id = find_instance($obj.attr("data-id")), + data = als[id]; + /*********************************************** + * unbinding next and prev buttons so that + * they don't interfere with current animation + **********************************************/ + data.prev.off(); + data.next.off(); + data.viewport.off("touchend"); + if(data.options.autoscroll === "yes") + { + $.fn.als("stop",id); + } + /********************************************* + * calling prev function on this instance + *********************************************/ + $.fn.als("prev",id); + if(data.options.autoscroll === "yes") + { + $.fn.als("start",id); + } + } + + /******************************************************************** + * function that generates the plugin and instantiates its methods + * @param {Object} method + *******************************************************************/ + $.fn.als = function( method ) + { + if ( methods[method] ) + { + return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); + } + else if ( typeof method === 'object' || ! method ) + { + return methods.init.apply( this, arguments ); + } + else + { + $.error( 'Method ' + method + ' does not exist on jQuery.als' ); + } + }; + +})(jQuery); \ No newline at end of file diff --git a/hyhproject/home/view/default/js/login.js b/hyhproject/home/view/default/js/login.js new file mode 100755 index 0000000..6cba749 --- /dev/null +++ b/hyhproject/home/view/default/js/login.js @@ -0,0 +1,218 @@ +function login(typ){ + var params = WST.getParams('.ipt'); + if(!$('#loginName').isValid())return; + if(!$('#loginPwd').isValid())return; + if(!$('#verifyCode').isValid())return; + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + } + var ll = WST.load({msg:'正在处理数据,请稍后...'}); + $.post(WST.U('home/users/checkLogin'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg, {icon: 1}); + var url = json.url; + if(WST.blank(url)){ + location.href = url; + }else{ + if(typ==2){ + location.href=WST.U('home/shops/index'); + }else if(typ==1){ + location.href=WST.U('home/users/index'); + }else{ + parent.location.reload(); + } + } + }else{ + layer.close(ll); + WST.msg(json.msg, {icon: 5}); + WST.getVerify('#verifyImg'); + } + + }); + return true; +} + + +function showProtocol(){ + layer.open({ + type: 2, + title: '用户注册协议', + shadeClose: true, + shade: 0.8, + area: ['1000px', ($(window).height() - 50) +'px'], + content: [WST.U('home/users/protocol')], + btn: ['同意并注册'], + yes: function(index, layero){ + layer.close(index); + } + }); +} + +var time = 0; +var isSend = false; +var isUse = false; +var index2 = null; +function getVerifyCode(){ + var params = {}; + params.userPhone = $.trim($("#loginName").val()); + if(params.userPhone==''){ + WST.msg('请输入手机号码!', {icon: 5}); + return; + } + if(isSend )return; + isSend = true; + if(window.conf.SMS_VERFY=='1'){ + var html = []; + html.push('<table class="wst-smsverfy"><tr><td width="80" align="right">'); + html.push('验证码:</td><td><input type="text" id="smsVerfyl" size="12" class="wst-text" maxLength="8">'); + html.push('<img style="vertical-align:middle;cursor:pointer;height:39px;" class="verifyImgd" src="'+WST.DOMAIN+'/hyhproject/Home/View/default/images/clickForVerify.png" title="刷新验证码" onclick="javascript:WST.getVerify(\'.verifyImgd\')"/>'); + html.push('</td></tr></table>'); + index2 = layer.open({ + title:'请输入验证码', + type: 1, + area: ['420px', '150px'], //宽高 + content: html.join(''), + btn: ['发送验证码'], + success: function(layero, index){ + WST.getVerify('.verifyImgd'); + }, + yes: function(index, layero){ + isSend = true; + params.smsVerfy = $.trim($('#smsVerfyl').val()); + if(params.smsVerfy==''){ + WST.msg('请输入验证码!', {icon: 5}); + return; + } + getPhoneVerifyCode(params); + }, + cancel:function(){ + isSend = false; + } + }); + }else{ + isSend = true; + getPhoneVerifyCode(params); + } +} + +function getPhoneVerifyCode(params){ + WST.msg('正在发送短信,请稍后...',{time:600000}); + $.post(WST.U('home/users/getPhoneVerifyCode'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg, {icon: 5}); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注意查收'); + time = 120; + $('#timeTips').css('width','100px'); + $('#timeTips').html('获取验证码(120)'); + $('#mobileCode').val(json.phoneVerifyCode); + var task = setInterval(function(){ + time--; + $('#timeTips').html('获取验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeTips').html("重新获取验证码"); + } + },1000); + } + if(json.status!=-2)layer.close(index2); + }); +} +function initRegist(){ + // 阻止按下回车键时触发短信验证码弹窗 + document.onkeydown=function(event){ + var e = event || window.event || arguments.callee.caller.arguments[0]; + if(e && e.keyCode==13){ // enter 键 + $('#reg_butt').submit(); + return false; + } + } + $('#reg_form').validator({ + rules: { + loginName: function(element) { + if(this.test(element, "mobile")===true){ + if(window.conf.SMS_OPEN=='1'){ + $("#mobileCodeDiv").show(); + $("#refreshCode").hide(); + $("#authCodeDiv").hide(); + $("#nameType").val('3'); + }else{ + $("#nameType").val('2'); + } + } + return this.test(element, "mobile")===true || '请填写有效的手机号'; + }, + mobileCode: function(element){ + if(window.conf.SMS_OPEN=='1'){ + if(this.test(document.getElementById("loginName"), "mobile")===true){ + return true; + } + } + return false; + }, + verifyCode: function(element){ + if(this.test(document.getElementById("loginName"), "mobile")===false){ + return true; + }else{ + return false; + } + }, + //自定义remote规则(注意:虽然remote规则已经内置,但这里的remote会优先于内置) + remote: function(element){ + return $.post(WST.U('home/users/checkLoginKey'),{"loginName":element.value},function(data,textStatus){ + + }); + } + }, + fields: { + 'loginName': 'required; loginName; remote;', + 'loginPwd' : '密码:required; password;', + 'reUserPwd': '确认密码:required; match(loginPwd);', + 'mobileCode': {rule:"required(mobileCode)",msg:{required:'请输入短信验证码'}}, + 'verifyCode': {rule:"required(verifyCode)",msg:{required:'请输入验证码'}} + }, + // 表单验证通过后,ajax提交 + valid: function(form){ + var me = this; + // ajax提交表单之前,先禁用submit + me.holdSubmit(); + var params = WST.getParams('.wst_ipt'); + if(WST.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.reUserPwd = rsa.encrypt(params.reUserPwd); + } + $("#reg_butt").css('color', '#999').text('正在提交..'); + $.post(WST.U('home/users/toRegist'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg('注册成功,正在跳转登录!', {icon: 1}, function(){ + var url = json.url; + if(WST.blank(url)){ + location.href = url; + }else{ + location.href=WST.U('home/users/index'); + } + }); + }else{ + me.holdSubmit(false); + WST.getVerify('#verifyImg'); + WST.msg(json.msg, {icon: 5}); + } + + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/qrcode.js b/hyhproject/home/view/default/js/qrcode.js new file mode 100755 index 0000000..b2ae4a6 --- /dev/null +++ b/hyhproject/home/view/default/js/qrcode.js @@ -0,0 +1,88 @@ + +var qrcode=function(){var qrcode=function(typeNumber,errorCorrectLevel){var PAD0=0xEC;var PAD1=0x11;var _typeNumber=typeNumber;var _errorCorrectLevel=QRErrorCorrectLevel[errorCorrectLevel];var _modules=null;var _moduleCount=0;var _dataCache=null;var _dataList=new Array();var _this={};var makeImpl=function(test,maskPattern){_moduleCount=_typeNumber*4+17;_modules=function(moduleCount){var modules=new Array(moduleCount);for(var row=0;row<moduleCount;row+=1){modules[row]=new Array(moduleCount);for(var col=0;col<moduleCount;col+=1){modules[row][col]=null;}} +return modules;}(_moduleCount);setupPositionProbePattern(0,0);setupPositionProbePattern(_moduleCount-7,0);setupPositionProbePattern(0,_moduleCount-7);setupPositionAdjustPattern();setupTimingPattern();setupTypeInfo(test,maskPattern);if(_typeNumber>=7){setupTypeNumber(test);} +if(_dataCache==null){_dataCache=createData(_typeNumber,_errorCorrectLevel,_dataList);} +mapData(_dataCache,maskPattern);};var setupPositionProbePattern=function(row,col){for(var r=-1;r<=7;r+=1){if(row+r<=-1||_moduleCount<=row+r)continue;for(var c=-1;c<=7;c+=1){if(col+c<=-1||_moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}};var getBestMaskPattern=function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i+=1){makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(_this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} +return pattern;};var setupTimingPattern=function(){for(var r=8;r<_moduleCount-8;r+=1){if(_modules[r][6]!=null){continue;} +_modules[r][6]=(r%2==0);} +for(var c=8;c<_moduleCount-8;c+=1){if(_modules[6][c]!=null){continue;} +_modules[6][c]=(c%2==0);}};var setupPositionAdjustPattern=function(){var pos=QRUtil.getPatternPosition(_typeNumber);for(var i=0;i<pos.length;i+=1){for(var j=0;j<pos.length;j+=1){var row=pos[i];var col=pos[j];if(_modules[row][col]!=null){continue;} +for(var r=-2;r<=2;r+=1){for(var c=-2;c<=2;c+=1){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}}}};var setupTypeNumber=function(test){var bits=QRUtil.getBCHTypeNumber(_typeNumber);for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[Math.floor(i/3)][i%3+_moduleCount-8-3]=mod;} +for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[i%3+_moduleCount-8-3][Math.floor(i/3)]=mod;}};var setupTypeInfo=function(test,maskPattern){var data=(_errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<6){_modules[i][8]=mod;}else if(i<8){_modules[i+1][8]=mod;}else{_modules[_moduleCount-15+i][8]=mod;}} +for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<8){_modules[8][_moduleCount-i-1]=mod;}else if(i<9){_modules[8][15-i-1+1]=mod;}else{_modules[8][15-i-1]=mod;}} +_modules[_moduleCount-8][8]=(!test);};var mapData=function(data,maskPattern){var inc=-1;var row=_moduleCount-1;var bitIndex=7;var byteIndex=0;var maskFunc=QRUtil.getMaskFunction(maskPattern);for(var col=_moduleCount-1;col>0;col-=2){if(col==6)col-=1;while(true){for(var c=0;c<2;c+=1){if(_modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} +var mask=maskFunc(row,col-c);if(mask){dark=!dark;} +_modules[row][col-c]=dark;bitIndex-=1;if(bitIndex==-1){byteIndex+=1;bitIndex=7;}}} +row+=inc;if(row<0||_moduleCount<=row){row-=inc;inc=-inc;break;}}}};var createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r+=1){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i+=1){dcdata[r][i]=0xff&buffer.getBuffer()[i+offset];} +offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=qrPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i+=1){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.getAt(modIndex):0;}} +var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalCodeCount+=rsBlocks[i].totalCount;} +var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<dcdata[r].length){data[index]=dcdata[r][i];index+=1;}}} +for(var i=0;i<maxEcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<ecdata[r].length){data[index]=ecdata[r][i];index+=1;}}} +return data;};var createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=qrBitBuffer();for(var i=0;i<dataList.length;i+=1){var data=dataList[i];buffer.put(data.getMode(),4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.getMode(),typeNumber));data.write(buffer);} +var totalDataCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalDataCount+=rsBlocks[i].dataCount;} +if(buffer.getLengthInBits()>totalDataCount*8){throw new Error('code length overflow. (' ++buffer.getLengthInBits() ++'>' ++totalDataCount*8 ++')');} +if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} +while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} +while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD1,8);} +return createBytes(buffer,rsBlocks);};_this.addData=function(data){var newData=qr8BitByte(data);_dataList.push(newData);_dataCache=null;};_this.isDark=function(row,col){if(row<0||_moduleCount<=row||col<0||_moduleCount<=col){throw new Error(row+','+col);} +return _modules[row][col];};_this.getModuleCount=function(){return _moduleCount;};_this.make=function(){makeImpl(false,getBestMaskPattern());};_this.createTableTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var qrHtml='';qrHtml+='<table style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: '+margin+'px;';qrHtml+='">';qrHtml+='<tbody>';for(var r=0;r<_this.getModuleCount();r+=1){qrHtml+='<tr>';for(var c=0;c<_this.getModuleCount();c+=1){qrHtml+='<td style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: 0px;';qrHtml+=' width: '+cellSize+'px;';qrHtml+=' height: '+cellSize+'px;';qrHtml+=' background-color: ';qrHtml+=_this.isDark(r,c)?'#000000':'#ffffff';qrHtml+=';';qrHtml+='"/>';} +qrHtml+='</tr>';} +qrHtml+='</tbody>';qrHtml+='</table>';return qrHtml;};_this.createImgTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var size=_this.getModuleCount()*cellSize+margin*2;var min=margin;var max=size-margin;return createImgTag(size,size,function(x,y){if(min<=x&&x<max&&min<=y&&y<max){var c=Math.floor((x-min)/cellSize);var r=Math.floor((y-min)/cellSize);return _this.isDark(r,c)?0:1;}else{return 1;}});};return _this;};qrcode.stringToBytes=function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);bytes.push(c&0xff);} +return bytes;};qrcode.createStringToBytes=function(unicodeData,numChars){var unicodeMap=function(){var bin=base64DecodeInputStream(unicodeData);var read=function(){var b=bin.read();if(b==-1)throw new Error();return b;};var count=0;var unicodeMap={};while(true){var b0=bin.read();if(b0==-1)break;var b1=read();var b2=read();var b3=read();var k=String.fromCharCode((b0<<8)|b1);var v=(b2<<8)|b3;unicodeMap[k]=v;count+=1;} +if(count!=numChars){throw new Error(count+' != '+numChars);} +return unicodeMap;}();var unknownChar='?'.charCodeAt(0);return function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);if(c<128){bytes.push(c);}else{var b=unicodeMap[s.charAt(i)];if(typeof b=='number'){if((b&0xff)==b){bytes.push(b);}else{bytes.push(b>>>8);bytes.push(b&0xff);}}else{bytes.push(unknownChar);}}} +return bytes;};};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil=function(){var PATTERN_POSITION_TABLE=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]];var G15=(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0);var G18=(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0);var G15_MASK=(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1);var _this={};var getBCHDigit=function(data){var digit=0;while(data!=0){digit+=1;data>>>=1;} +return digit;};_this.getBCHTypeInfo=function(data){var d=data<<10;while(getBCHDigit(d)-getBCHDigit(G15)>=0){d^=(G15<<(getBCHDigit(d)-getBCHDigit(G15)));} +return((data<<10)|d)^G15_MASK;};_this.getBCHTypeNumber=function(data){var d=data<<12;while(getBCHDigit(d)-getBCHDigit(G18)>=0){d^=(G18<<(getBCHDigit(d)-getBCHDigit(G18)));} +return(data<<12)|d;};_this.getPatternPosition=function(typeNumber){return PATTERN_POSITION_TABLE[typeNumber-1];};_this.getMaskFunction=function(maskPattern){switch(maskPattern){case QRMaskPattern.PATTERN000:return function(i,j){return(i+j)%2==0;};case QRMaskPattern.PATTERN001:return function(i,j){return i%2==0;};case QRMaskPattern.PATTERN010:return function(i,j){return j%3==0;};case QRMaskPattern.PATTERN011:return function(i,j){return(i+j)%3==0;};case QRMaskPattern.PATTERN100:return function(i,j){return(Math.floor(i/2)+Math.floor(j/3))%2==0;};case QRMaskPattern.PATTERN101:return function(i,j){return(i*j)%2+(i*j)%3==0;};case QRMaskPattern.PATTERN110:return function(i,j){return((i*j)%2+(i*j)%3)%2==0;};case QRMaskPattern.PATTERN111:return function(i,j){return((i*j)%3+(i+j)%2)%2==0;};default:throw new Error('bad maskPattern:'+maskPattern);}};_this.getErrorCorrectPolynomial=function(errorCorrectLength){var a=qrPolynomial([1],0);for(var i=0;i<errorCorrectLength;i+=1){a=a.multiply(qrPolynomial([1,QRMath.gexp(i)],0));} +return a;};_this.getLengthInBits=function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error('mode:'+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error('mode:'+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error('mode:'+mode);}}else{throw new Error('type:'+type);}};_this.getLostPoint=function(qrcode){var moduleCount=qrcode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount;col+=1){var sameCount=0;var dark=qrcode.isDark(row,col);for(var r=-1;r<=1;r+=1){if(row+r<0||moduleCount<=row+r){continue;} +for(var c=-1;c<=1;c+=1){if(col+c<0||moduleCount<=col+c){continue;} +if(r==0&&c==0){continue;} +if(dark==qrcode.isDark(row+r,col+c)){sameCount+=1;}}} +if(sameCount>5){lostPoint+=(3+sameCount-5);}}};for(var row=0;row<moduleCount-1;row+=1){for(var col=0;col<moduleCount-1;col+=1){var count=0;if(qrcode.isDark(row,col))count+=1;if(qrcode.isDark(row+1,col))count+=1;if(qrcode.isDark(row,col+1))count+=1;if(qrcode.isDark(row+1,col+1))count+=1;if(count==0||count==4){lostPoint+=3;}}} +for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount-6;col+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row,col+1)&&qrcode.isDark(row,col+2)&&qrcode.isDark(row,col+3)&&qrcode.isDark(row,col+4)&&!qrcode.isDark(row,col+5)&&qrcode.isDark(row,col+6)){lostPoint+=40;}}} +for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount-6;row+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row+1,col)&&qrcode.isDark(row+2,col)&&qrcode.isDark(row+3,col)&&qrcode.isDark(row+4,col)&&!qrcode.isDark(row+5,col)&&qrcode.isDark(row+6,col)){lostPoint+=40;}}} +var darkCount=0;for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount;row+=1){if(qrcode.isDark(row,col)){darkCount+=1;}}} +var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;};return _this;}();var QRMath=function(){var EXP_TABLE=new Array(256);var LOG_TABLE=new Array(256);for(var i=0;i<8;i+=1){EXP_TABLE[i]=1<<i;} +for(var i=8;i<256;i+=1){EXP_TABLE[i]=EXP_TABLE[i-4]^EXP_TABLE[i-5]^EXP_TABLE[i-6]^EXP_TABLE[i-8];} +for(var i=0;i<255;i+=1){LOG_TABLE[EXP_TABLE[i]]=i;} +var _this={};_this.glog=function(n){if(n<1){throw new Error('glog('+n+')');} +return LOG_TABLE[n];};_this.gexp=function(n){while(n<0){n+=255;} +while(n>=256){n-=255;} +return EXP_TABLE[n];};return _this;}();function qrPolynomial(num,shift){if(typeof num.length=='undefined'){throw new Error(num.length+'/'+shift);} +var _num=function(){var offset=0;while(offset<num.length&&num[offset]==0){offset+=1;} +var _num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i+=1){_num[i]=num[i+offset];} +return _num;}();var _this={};_this.getAt=function(index){return _num[index];};_this.getLength=function(){return _num.length;};_this.multiply=function(e){var num=new Array(_this.getLength()+e.getLength()-1);for(var i=0;i<_this.getLength();i+=1){for(var j=0;j<e.getLength();j+=1){num[i+j]^=QRMath.gexp(QRMath.glog(_this.getAt(i))+QRMath.glog(e.getAt(j)));}} +return qrPolynomial(num,0);};_this.mod=function(e){if(_this.getLength()-e.getLength()<0){return _this;} +var ratio=QRMath.glog(_this.getAt(0))-QRMath.glog(e.getAt(0));var num=new Array(_this.getLength());for(var i=0;i<_this.getLength();i+=1){num[i]=_this.getAt(i);} +for(var i=0;i<e.getLength();i+=1){num[i]^=QRMath.gexp(QRMath.glog(e.getAt(i))+ratio);} +return qrPolynomial(num,0).mod(e);};return _this;};var QRRSBlock=function(){var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16]];var qrRSBlock=function(totalCount,dataCount){var _this={};_this.totalCount=totalCount;_this.dataCount=dataCount;return _this;};var _this={};var getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};_this.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=getRsBlockTable(typeNumber,errorCorrectLevel);if(typeof rsBlock=='undefined'){throw new Error('bad rs block @ typeNumber:'+typeNumber+'/errorCorrectLevel:'+errorCorrectLevel);} +var length=rsBlock.length/3;var list=new Array();for(var i=0;i<length;i+=1){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j+=1){list.push(qrRSBlock(totalCount,dataCount));}} +return list;};return _this;}();var qrBitBuffer=function(){var _buffer=new Array();var _length=0;var _this={};_this.getBuffer=function(){return _buffer;};_this.getAt=function(index){var bufIndex=Math.floor(index/8);return((_buffer[bufIndex]>>>(7-index%8))&1)==1;};_this.put=function(num,length){for(var i=0;i<length;i+=1){_this.putBit(((num>>>(length-i-1))&1)==1);}};_this.getLengthInBits=function(){return _length;};_this.putBit=function(bit){var bufIndex=Math.floor(_length/8);if(_buffer.length<=bufIndex){_buffer.push(0);} +if(bit){_buffer[bufIndex]|=(0x80>>>(_length%8));} +_length+=1;};return _this;};var qr8BitByte=function(data){var _mode=QRMode.MODE_8BIT_BYTE;var _data=data;var _bytes=qrcode.stringToBytes(data);var _this={};_this.getMode=function(){return _mode;};_this.getLength=function(buffer){return _bytes.length;};_this.write=function(buffer){for(var i=0;i<_bytes.length;i+=1){buffer.put(_bytes[i],8);}};return _this;};var byteArrayOutputStream=function(){var _bytes=new Array();var _this={};_this.writeByte=function(b){_bytes.push(b&0xff);};_this.writeShort=function(i){_this.writeByte(i);_this.writeByte(i>>>8);};_this.writeBytes=function(b,off,len){off=off||0;len=len||b.length;for(var i=0;i<len;i+=1){_this.writeByte(b[i+off]);}};_this.writeString=function(s){for(var i=0;i<s.length;i+=1){_this.writeByte(s.charCodeAt(i));}};_this.toByteArray=function(){return _bytes;};_this.toString=function(){var s='';s+='[';for(var i=0;i<_bytes.length;i+=1){if(i>0){s+=',';} +s+=_bytes[i];} +s+=']';return s;};return _this;};var base64EncodeOutputStream=function(){var _buffer=0;var _buflen=0;var _length=0;var _base64='';var _this={};var writeEncoded=function(b){_base64+=String.fromCharCode(encode(b&0x3f));};var encode=function(n){if(n<0){}else if(n<26){return 0x41+n;}else if(n<52){return 0x61+(n-26);}else if(n<62){return 0x30+(n-52);}else if(n==62){return 0x2b;}else if(n==63){return 0x2f;} +throw new Error('n:'+n);};_this.writeByte=function(n){_buffer=(_buffer<<8)|(n&0xff);_buflen+=8;_length+=1;while(_buflen>=6){writeEncoded(_buffer>>>(_buflen-6));_buflen-=6;}};_this.flush=function(){if(_buflen>0){writeEncoded(_buffer<<(6-_buflen));_buffer=0;_buflen=0;} +if(_length%3!=0){var padlen=3-_length%3;for(var i=0;i<padlen;i+=1){_base64+='=';}}};_this.toString=function(){return _base64;};return _this;};var base64DecodeInputStream=function(str){var _str=str;var _pos=0;var _buffer=0;var _buflen=0;var _this={};_this.read=function(){while(_buflen<8){if(_pos>=_str.length){if(_buflen==0){return-1;} +throw new Error('unexpected end of file./'+_buflen);} +var c=_str.charAt(_pos);_pos+=1;if(c=='='){_buflen=0;return-1;}else if(c.match(/^\s$/)){continue;} +_buffer=(_buffer<<6)|decode(c.charCodeAt(0));_buflen+=6;} +var n=(_buffer>>>(_buflen-8))&0xff;_buflen-=8;return n;};var decode=function(c){if(0x41<=c&&c<=0x5a){return c-0x41;}else if(0x61<=c&&c<=0x7a){return c-0x61+26;}else if(0x30<=c&&c<=0x39){return c-0x30+52;}else if(c==0x2b){return 62;}else if(c==0x2f){return 63;}else{throw new Error('c:'+c);}};return _this;};var gifImage=function(width,height){var _width=width;var _height=height;var _data=new Array(width*height);var _this={};_this.setPixel=function(x,y,pixel){_data[y*_width+x]=pixel;};_this.write=function(out){out.writeString('GIF87a');out.writeShort(_width);out.writeShort(_height);out.writeByte(0x80);out.writeByte(0);out.writeByte(0);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0xff);out.writeByte(0xff);out.writeByte(0xff);out.writeString(',');out.writeShort(0);out.writeShort(0);out.writeShort(_width);out.writeShort(_height);out.writeByte(0);var lzwMinCodeSize=2;var raster=getLZWRaster(lzwMinCodeSize);out.writeByte(lzwMinCodeSize);var offset=0;while(raster.length-offset>255){out.writeByte(255);out.writeBytes(raster,offset,255);offset+=255;} +out.writeByte(raster.length-offset);out.writeBytes(raster,offset,raster.length-offset);out.writeByte(0x00);out.writeString(';');};var bitOutputStream=function(out){var _out=out;var _bitLength=0;var _bitBuffer=0;var _this={};_this.write=function(data,length){if((data>>>length)!=0){throw new Error('length over');} +while(_bitLength+length>=8){_out.writeByte(0xff&((data<<_bitLength)|_bitBuffer));length-=(8-_bitLength);data>>>=(8-_bitLength);_bitBuffer=0;_bitLength=0;} +_bitBuffer=(data<<_bitLength)|_bitBuffer;_bitLength=_bitLength+length;};_this.flush=function(){if(_bitLength>0){_out.writeByte(_bitBuffer);}};return _this;};var getLZWRaster=function(lzwMinCodeSize){var clearCode=1<<lzwMinCodeSize;var endCode=(1<<lzwMinCodeSize)+1;var bitLength=lzwMinCodeSize+1;var table=lzwTable();for(var i=0;i<clearCode;i+=1){table.add(String.fromCharCode(i));} +table.add(String.fromCharCode(clearCode));table.add(String.fromCharCode(endCode));var byteOut=byteArrayOutputStream();var bitOut=bitOutputStream(byteOut);bitOut.write(clearCode,bitLength);var dataIndex=0;var s=String.fromCharCode(_data[dataIndex]);dataIndex+=1;while(dataIndex<_data.length){var c=String.fromCharCode(_data[dataIndex]);dataIndex+=1;if(table.contains(s+c)){s=s+c;}else{bitOut.write(table.indexOf(s),bitLength);if(table.size()<0xfff){if(table.size()==(1<<bitLength)){bitLength+=1;} +table.add(s+c);} +s=c;}} +bitOut.write(table.indexOf(s),bitLength);bitOut.write(endCode,bitLength);bitOut.flush();return byteOut.toByteArray();};var lzwTable=function(){var _map={};var _size=0;var _this={};_this.add=function(key){if(_this.contains(key)){throw new Error('dup key:'+key);} +_map[key]=_size;_size+=1;};_this.size=function(){return _size;};_this.indexOf=function(key){return _map[key];};_this.contains=function(key){return typeof _map[key]!='undefined';};return _this;};return _this;};var createImgTag=function(width,height,getPixel,alt){var gif=gifImage(width,height);for(var y=0;y<height;y+=1){for(var x=0;x<width;x+=1){gif.setPixel(x,y,getPixel(x,y));}} +var b=byteArrayOutputStream();gif.write(b);var base64=base64EncodeOutputStream();var bytes=b.toByteArray();for(var i=0;i<bytes.length;i+=1){base64.writeByte(bytes[i]);} +base64.flush();var img='';img+='<img';img+='\u0020src="';img+='data:image/gif;base64,';img+=base64;img+='"';img+='\u0020width="';img+=width;img+='"';img+='\u0020height="';img+=height;img+='"';if(alt){img+='\u0020alt="';img+=alt;img+='"';} +img+='/>';return img;};return qrcode;}();/* |xGv00|ca8fc6bde81a353e7cede123b304bdb9 */ \ No newline at end of file diff --git a/hyhproject/home/view/default/js/right_cart.js b/hyhproject/home/view/default/js/right_cart.js new file mode 100755 index 0000000..9b2d9ed --- /dev/null +++ b/hyhproject/home/view/default/js/right_cart.js @@ -0,0 +1,208 @@ +$(document).ready(function(){ + var cartHeight = WST.pageHeight()-120; + $('.toolbar-tab').hover(function (){ $(this).find('.tab-text').addClass("tbar-tab-hover"); $(this).find('.footer-tab-text').addClass("tbar-tab-footer-hover"); $(this).addClass("tbar-tab-selected");},function(){ $(this).find('.tab-text').removeClass("tbar-tab-hover"); $(this).find('.footer-tab-text').removeClass("tbar-tab-footer-hover"); $(this).removeClass("tbar-tab-selected"); }); + $('.j-close').click(function(){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + $('.toolbar-wrap').removeClass('toolbar-open'); + }else{ + $('.toolbar-wrap').addClass('toolbar-open'); + } + }) + $('.j-global-toolbar').siblings().click(function(){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + $('.toolbar-wrap').removeClass('toolbar-open'); + } + }) + $('.tbar-tab-cart').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-follow').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的关注</em>"; + $('.tbar-tab-follow').append(info); + $('.tbar-tab-follow').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-history').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.tbar-tab-history').append(info); + $('.tbar-tab-history').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css({'visibility':"visible","z-index":"1"}); + getRightCart(); + }else{ + var info = "<em class='tab-text '>我的关注</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css({'visibility':"visible","z-index":"1"}); + $('.tbar-panel-follow').css('visibility','hidden'); + $('.tbar-panel-history').css('visibility','hidden'); + $('.toolbar-wrap').addClass('toolbar-open'); + $('#cart-panel').css('height',cartHeight+"px").css('overflow-y','auto'); + getRightCart(); + } + }); + $('.tbar-tab-follow').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-cart').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>购物车</em>"; + $('.tbar-tab-cart').append(info); + $('.tbar-tab-cart').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-history').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.tbar-tab-history').append(info); + $('.tbar-tab-history').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-follow').css({'visibility':"visible","z-index":"1"}); + + }else{ + var info = "<em class='tab-text '>我的关注</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + + + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css('visibility','hidden'); + $('.tbar-panel-follow').css({'visibility':"visible","z-index":"1"}); + $('.tbar-panel-history').css('visibility','hidden'); + $('.toolbar-wrap').addClass('toolbar-open'); + } + }); + $('.tbar-tab-history').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-follow').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的关注</em>"; + $('.tbar-tab-follow').append(info); + $('.tbar-tab-follow').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-cart').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>购物车</em>"; + $('.tbar-tab-cart').append(info); + $('.tbar-tab-cart').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-history').css({'visibility':"visible","z-index":"1"}); + getHistoryGoods(); + }else{ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css('visibility','hidden'); + $('.tbar-panel-follow').css('visibility','hidden'); + $('.tbar-panel-history').css({'visibility':"visible","z-index":"1"}); + $('.toolbar-wrap').addClass('toolbar-open'); + getHistoryGoods(); + } + }); +}); +function getRightCart(){ + //if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/carts/getCart'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.carts && !json.carts.length){ + $('.j-cart-count').html(json.goodsTotalNum); + if(json.goodsTotalNum>0)$('.j-cart-count').show(); + var gettpl = document.getElementById('list-rightcart').innerHTML; + laytpl(gettpl).render(json.carts, function(html){ + $('#cart-panel').html(html); + }); + $('#j-goods-count').html(json.goodsTotalNum); + $('#j-goods-total-money').html(json.goodsTotalMoney); + }else{ + $('#cart-panel').html('<p class="right-carts-empty">购物车空空如也,赶紧去选购吧~</p>'); + } + } + }); +} +function delRightCart(obj,id){ + var dataval = $(obj).attr('dataid'); + dataval = dataval.split("|"); + if($('#shop-cart-'+dataval[0]).children().size()>2){ + $('.j-goods-item-'+dataval[1]).remove(); + }else{ + $('#shop-cart-'+dataval[0]).remove(); + } + statRightCartMoney(); + $.post(WST.U('home/carts/delCart'),{id:dataval[1],rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +function jumpSettlement(){ + if($('#cart-panel').children().size()==0){ + WST.msg("您的购物车没有商品哦,请先添加商品~",{icon:2}); + return; + } + location.href=WST.U('home/carts/settlement'); +} +function getHistoryGoods(){ + $.post(WST.U('home/goods/historyByGoods'),{},function(data) { + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('list-history-goods').innerHTML; + laytpl(gettpl).render(json.data, function(html){ + $('#history-goods-panel').html(html); + }); + $('.jth-item').hover(function (){ $(this).find('.add-cart-button').show(); },function(){ $(this).find('.add-cart-button').hide(); }); + } + }); +} +function checkRightChks(cid,obj){ + WST.changeCartGoods(cid,$('#buyNum_'+cid).val(),obj.checked?1:0); + statRightCartMoney(); +} +function statRightCartMoney(){ + var cartId,goodsNum = 0,goodsMoney = 0,tmpGoodsNum = 0,tmpGoodsMoney = 0; + $('.jtc-item-goods').each(function(){ + cartId = $(this).attr('dataval'); + if($('#rcart_'+cartId).prop('checked')){ + goodsNum = parseInt($('#buyNum_'+cartId).val(),10); + goodsMoney = parseFloat($('#gprice_'+cartId).html(),10); + tmpGoodsNum++; + tmpGoodsMoney += goodsMoney*goodsNum; + } + }) + if(tmpGoodsNum==0){ + $('#j-goods-count').html(0); + $('.j-cart-count').html(0).hide(); + $('#j-goods-total-money').html(0); + }else{ + $('.j-cart-count').html(tmpGoodsNum); + $('#j-goods-count').html(tmpGoodsNum); + $('#j-goods-total-money').html(tmpGoodsMoney); + } +} diff --git a/hyhproject/home/view/default/js/self_shop.js b/hyhproject/home/view/default/js/self_shop.js new file mode 100755 index 0000000..bafff58 --- /dev/null +++ b/hyhproject/home/view/default/js/self_shop.js @@ -0,0 +1,94 @@ +/*店长推荐*/ +function gpanelOver2(obj){ +var sid = $(obj).attr("id"); +var ids = sid.split("_"); +var preid = ids[0]+"_"+ids[1]; + +$("li[id^="+preid+"_]").removeClass("j-s-rec-selected"); + +$("#"+sid).addClass("j-s-rec-selected"); + +$("div[id^="+preid+"_]").hide(); +$("#"+sid+"_pl").show(); +} + +/*楼层*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("div[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} + + + +function searchShopsGoods(){ + var params = new Array(); + params.push("shopId=" + $("#shopId").val()); + params.push("goodsName=" + $("#goodsName").val()); + document.location.href = WST.U('home/shops/home',params.join('&'),true); +} +$(function(){ + $(".s-goods").hover(function(){ + $(this).find(".s-add-cart").slideDown(100); + },function(){ + $(this).find(".s-add-cart").slideUp(100); + }); +}) + + +$(function(){ + if($('.s-wst-slide-items a').length>1)WST.slides('.s-wst-slide'); + $('.shop-cat1').hover(function(){ + $(this).addClass('ct1-hover'); + var cid = $(this).attr('cid'); + + var h = 66.3*cid+'px'; + $('.cid'+cid).css('top',h); + $('.cid'+cid).show(); + },function(){ + $(this).removeClass('ct1-hover'); + var cid = $(this).attr('cid'); + $('.cid'+cid).hide(); + }) + + + $('.shop-cat2').hover(function(){ + var cid = $(this).attr('cid'); + $('#ct1-'+cid).addClass('ct1-hover'); + $(this).show(); + },function(){ + var cid = $(this).attr('cid'); + $('#ct1-'+cid).removeClass('ct1-hover'); + $(this).hide(); + }); + + + + $('.s-cat').hover(function(){ + $('.s-cat-head').addClass('s-cat-head-hover'); + $(this).show(); + },function(){ + $('.s-cat-head').removeClass('s-cat-head-hover'); + $(this).hide(); + }); + + + $('.s-cat-head').hover(function(){ + $(this).addClass('s-cat-head-hover'); + $('.s-cat').css({left:$('.s-cat-head').offset().left}).show(); + },function(){ + $(this).removeClass('s-cat-head-hover'); + $('.s-cat').hide(); + }) + + +}); \ No newline at end of file diff --git a/hyhproject/home/view/default/js/shophome.js b/hyhproject/home/view/default/js/shophome.js new file mode 100755 index 0000000..f9c73f4 --- /dev/null +++ b/hyhproject/home/view/default/js/shophome.js @@ -0,0 +1,39 @@ +$(function() { + WST.dropDownLayer(".wst-shop-code",".wst-shop-codes"); + $(".ck-slide-wrapper img").width(1200); + $('.ck-slide').ckSlide({ + autoPlay: true, + time:5000, + isAnimate:true, + dir: 'x' + }); + $(".wst-shop-goimg").hover(function(){ + $(this).find(".js-cart").slideDown(100); + },function(){ + $(this).find(".js-cart").slideUp(100); + }); +}); +function dropDown(obj,id){ + if( $(obj).attr('class').indexOf('js-shop-plus') > -1 ){ + $(obj).removeClass('js-shop-plus').addClass('js-shop-redu'); + $('.tree_'+id).slideUp(); + }else{ + $(obj).removeClass('js-shop-redu').addClass('js-shop-plus'); + $('.tree_'+id).slideDown(); + } +} +function searchShopsGoods(obj){ + var mdesc = $('#mdesc').val(); + if($('#msort').val() != obj)mdesc = 0; + var msort = obj; + var params = new Array(); + params.push("shopId=" + $("#shopId").val()); + params.push("msort=" + obj); + params.push("mdesc=" + ((mdesc=="0")?"1":"0")); + params.push("sprice=" + $("#sprice").val()); + params.push("eprice=" + $("#eprice").val()); + params.push("ct1=" + $("#ct1").val()); + params.push("ct2=" + $("#ct2").val()); + if($("#goodsName").val()!=undefined)params.push("goodsName=" + $("#goodsName").val()); + location.href = WST.U('home/shops/home',params.join('&'),true); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/js/shopstreet.js b/hyhproject/home/view/default/js/shopstreet.js new file mode 100755 index 0000000..fe4c746 --- /dev/null +++ b/hyhproject/home/view/default/js/shopstreet.js @@ -0,0 +1,18 @@ +//筛选分类 +function screenCat(id){ + location.href=WST.U('home/shops/shopstreet','id='+id,true); +} +$(function(){ + var goodsNum = $(this).find("div[class^='wst-shopstr-shopl']").length; + for(var i=1;i<=goodsNum;++i){ + $("#js-goods"+i).als({ + visible_items: 6, + scrolling_items: 1, + orientation: "horizontal", + circular: "yes", + autoscroll: "no", + start_from: 2 + }); + } + WST.dropDownLayer(".j-score",".j-scores"); +}); \ No newline at end of file diff --git a/hyhproject/home/view/default/right_cart.html b/hyhproject/home/view/default/right_cart.html new file mode 100755 index 0000000..b2208f3 --- /dev/null +++ b/hyhproject/home/view/default/right_cart.html @@ -0,0 +1,153 @@ +<link href="__STYLE__/css/right_cart.css?v={$v}" rel="stylesheet"> +<div class="j-global-toolbar"> + <div class="toolbar-wrap j-wrap" > + <div class="toolbar"> + <div class="toolbar-panels j-panel"> + <div style="visibility: hidden;" class="j-content toolbar-panel tbar-panel-cart toolbar-animate-out"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="" class="title"><i></i><em class="title">购物车</em></a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main" > + <div class="tbar-panel-content j-panel-content"> + {if condition="session('WST_USER.userId') == 0"} + <div id="j-cart-tips" class="tbar-tipbox hide"> + <div class="tip-inner"> + <span class="tip-text">还没有登录,登录后商品将被保存</span> + <a href="#none" onclick='WST.loginWindow()' class="tip-btn j-login">登录</a> + </div> + </div> + {/if} + <div id="j-cart-render"> + <div id='cart-panel' class="tbar-cart-list"></div> + <script id="list-rightcart" type="text/html"> + {{# + var shop,goods,specs; + for(var key in d){ + shop = d[key]; + for(var i=0;i<shop.list.length;i++){ + goods = shop.list[i]; + goods.goodsImg = WST.conf.IMGURL+"/"+goods.goodsImg+"?x-oss-process=image/resize,w_300,h_300"; + specs = ''; + if(goods.specNames && goods.specNames.length>0){ + for(var j=0;j<goods.specNames.length;j++){ + specs += goods.specNames[j].itemName+ " "; + } + } + }} + <div class="tbar-cart-item" id="shop-cart-{{shop.shopId}}"> + <div class="jtc-item-promo"> + <div class="promo-text">{{shop.shopName}}</div> + </div> + <div class="jtc-item-goods j-goods-item-{{goods.cartId}}" dataval="{{goods.cartId}}"> + <div class='wst-lfloat'> + <input type='checkbox' id='rcart_{{goods.cartId}}' class='rchk' onclick='javascript:checkRightChks({{goods.cartId}},this);' {{# if(goods.isCheck==1){}}checked{{# } }}/></div> + <span class="p-img"><a target="_blank" href="{{WST.U('home/goods/detail','id='+goods.goodsId)}}" target="_blank"><img src="{{goods.goodsImg}}" title="{{goods.goodsName}}" height="50" width="50"></a></span> + <div class="p-name"> + <a target="_blank" title="{{(goods.goodsName+((specs!='')?"【"+specs+"】":""))}}" href="{{WST.U('home/goods/detail','id='+goods.goodsId)}}">{{WST.cutStr(goods.goodsName,22)}}<br/>{{specs}}</a> + </div> + <div class="p-price"> + <strong>¥<span id='gprice_{{goods.cartId}}'>{{goods.shopPrice}}</span></strong> + <div class="wst-rfloat"> + <a href="#none" class="buy-btn" id="buy-reduce_{{goods.cartId}}" onclick="javascript:WST.changeIptNum(-1,'#buyNum','#buy-reduce,#buy-add','{{goods.cartId}}','statRightCartMoney')">-</a> + <input type="text" id="buyNum_{{goods.cartId}}" class="right-cart-buy-num" value="{{goods.cartNum}}" data-max="{{goods.goodsStock}}" data-min="1" onkeyup="WST.changeIptNum(0,'#buyNum','#buy-reduce,#buy-add',{{goods.cartId}},'statRightCartMoney')" autocomplete="off" onkeypress="return WST.isNumberKey(event);" maxlength="6"/> + <a href="#none" class="buy-btn" id="buy-add_{{goods.cartId}}" onclick="javascript:WST.changeIptNum(1,'#buyNum','#buy-reduce,#buy-add','{{goods.cartId}}','statRightCartMoney')">+</a> + </div> + </div> + <span onclick="javascript:delRightCart(this,{{goods.cartId}});" dataid="{{shop.shopId}}|{{goods.cartId}}" class="goods-remove" title="删除"></span> + </div> + </div> + {{# } } }} + </script> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"> + <div class="tbar-checkout"> + <div class="jtc-number">已选<strong id="j-goods-count">0</strong>件商品 </div> + <div class="jtc-sum"> 共计:¥<strong id="j-goods-total-money">0</strong> </div> + <a class="jtc-btn j-btn" href="#none" onclick='javascript:jumpSettlement()'>去结算</a> + </div> + </div> + </div> + + <div style="visibility: hidden;" data-name="follow" class="j-content toolbar-panel tbar-panel-follow"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="#" target="_blank" class="title"> <i></i> <em class="title">我的关注</em> </a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main"> + <div class="tbar-panel-content j-panel-content"> + <div class="tbar-tipbox2"> + <div class="tip-inner"> <i class="i-loading"></i> </div> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"></div> + </div> + <div style="visibility: hidden;" class="j-content toolbar-panel tbar-panel-history toolbar-animate-in"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="#none" class="title"> <i></i> <em class="title">我的足迹</em> </a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main"> + <div class="tbar-panel-content j-panel-content"> + <div class="jt-history-wrap"> + <ul id='history-goods-panel'></ul> + <script id="list-history-goods" type="text/html"> + {{# + for(var i = 0; i < d.length; i++){ + d[i].goodsImg = WST.conf.IMGURL+"/"+d[i].goodsImg+"?x-oss-process=image/resize,w_300,h_300"; + }} + <li class="jth-item"> + <a target='_blank' href="{{WST.U('home/goods/detail','id='+d[i].goodsId)}}" class="img-wrap"><img src="{{d[i].goodsImg}}" height="100" width="100"> </a> + <a class="add-cart-button" href="javascript:WST.addCart({{d[i].goodsId}});">加入购物车</a> + <a href="#none" class="price">¥{{d[i].shopPrice}}</a> + </li> + {{# } }} + </script> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"></div> + </div> + </div> + + <div class="toolbar-header"></div> + + <div class="toolbar-tabs j-tab"> + + <div class="toolbar-tab tbar-tab-cart"> + <i class="tab-ico"></i> + <em class="tab-text">购物车</em> + <span class="tab-sub j-cart-count hide"></span> + </div> + <div class="toolbar-tab tbar-tab-follow" style='display:none'> + <i class="tab-ico"></i> + <em class="tab-text">我的关注</em> + <span class="tab-sub j-count hide">0</span> + </div> + <div class=" toolbar-tab tbar-tab-history "> + <i class="tab-ico"></i> + <em class="tab-text">我的足迹</em> + <span class="tab-sub j-count hide"></span> + </div> + <div class="toolbar-tab tbar-tab-message"> + <a target='_blank' href='{:Url("home/messages/index")}' onclick='WST.position(49,0)'> + <i class="tab-ico"></i> + <em class="tab-text">我的消息</em> + <span class="tab-sub j-message-count hide"></span> + </a> + </div> + </div> + + <div class="toolbar-footer"> + <div class="toolbar-tab tbar-tab-top"> <a href="#"> <i class="tab-ico "></i> <em class="footer-tab-text">顶部</em> </a> </div> + <div class=" toolbar-tab tbar-tab-feedback" style='display:none'> <a href="#" target="_blank"> <i class="tab-ico"></i> <em class="footer-tab-text ">反馈</em> </a> </div> + </div> + <div class="toolbar-mini"></div> + </div> + <div id="j-toolbar-load-hook"></div> + </div> +</div> +<script type='text/javascript' src='__STYLE__/js/right_cart.js?v={$v}'></script> \ No newline at end of file diff --git a/hyhproject/home/view/default/self_shop.html b/hyhproject/home/view/default/self_shop.html new file mode 100755 index 0000000..e9048a4 --- /dev/null +++ b/hyhproject/home/view/default/self_shop.html @@ -0,0 +1,187 @@ +{extend name="default/base" /} +{block name="title"}{:WSTConf('CONF.mallName')}-{:WSTConf('CONF.mallSlogan')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/self_shop.css" rel="stylesheet"> +{/block} +{block name="main"} +<input type="hidden" id="shopId" value="{$data['shop']['shopId']}"> +<input type="hidden" id="goodsName" value="{$goodsName}"> + +<div class="s-banner"> + {/* 本店分类 */} + <div class="s-cat"> + {volist name="$data['shopcats']" id="cat1" length="6"} + <div class="shop-cat1" cid="{$key}" id="ct1-{$key}"> + <div class="shop-cat1-title"> + <em class="em{$key+1}"></em> + <h3> + <a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}">{:WSTMSubstr($cat1['catName'],0,4)}</a> + </h3> + </div> + <p class="shop-ct1-ct2"> + {volist name="$cat1['children']" id="v1" key="k1" } + <a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$v1['catId']])}">{$v1['catName']}</a> + {/volist} + </p> + </div> + + <ul class="shop-cat2 cid{$key}" cid="{$key}"> + {volist name="$cat1['children']" id="cat2" length="20"} + <li><a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$cat2['catId']])}">{$cat2['catName']}</a></li> + {/volist} + </ul> + {/volist} + </div> + + {/* 横栏广告 */} + <div class="s-wst-slide" id="s-wst-slide" style="width:100%;float:right;height:500px;overflow:hidden;"> + {if($data['shop']['shopAds'])} + <ul class="s-wst-slide-items"> + {volist name="$data['shop']['shopAds']" id="vo"} + <a href="{$vo.adUrl}" {if ($vo['isOpen'])}target='_blank'{/if}><li style="background: url(__IMGURL__/{$vo.adImg}) no-repeat scroll center center;background-size:cover" ></li></a> + {/volist} + </ul> + <div class="s-wst-slide-numbox"> + <div class="s-wst-slide-controls"> + {volist name="$data['shop']['shopAds']" id="vo" key="k"} + {if condition="$k eq 1"} + <span class="curr"> </span> + {else/} + <span class=""> </span> + {/if} + {/volist} + </div> + </div> + {/if} + + </div> +</div> + +<div class="shop_rec_out"> + <div class="s-buy-new-best-hot"> + <ul class="s-rec"> + <li class="s-rec-item j-s-rec-selected" id="fl_f_0" onmouseover="gpanelOver2(this);"><a href="javascript:void(0)">店长推荐</a></li> + <li class="s-rec-item"> + <a href="javascript:void(0)">&nbsp;/&nbsp;</a> + </li> + <li class="s-rec-item" id="fl_f_1" onmouseover="gpanelOver2(this);"><a href="javascript:void(0)">热卖商品</a></li> + <div class="wst-clear"></div> + </ul> + {/* 店长推荐 */} + <div class="s-rec-glistbox" id="fl_f_0_pl"> + <ul class="s-rec-goods-list"> + {volist name="$data['rec']" id="vo" length="4" } + <li> + <a href='{:Url("home/goods/detail","id=".$vo["goodsId"])}' target='_blank'> + <img class='goodsImg' data-original="__IMGURL__/{:WSTImg($vo['goodsImg'])}" title="{$vo['goodsName']}"/> + </a> + <div class="rec_ginfo"> + <p class="s-rec-goods-desc"><a href='{:Url("home/goods/detail","id=".$vo["goodsId"])}' target='_blank'>{$vo['goodsName']}</a></p> + <div class="s-rec-goods-bottom"> + <p class="s-rec-goods-price"><span>¥{$vo['shopPrice']}</span></p> + <a href="javascript:WST.addCart({$vo['goodsId']});">加入购物车</a> + </div> + </div> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + </div> + + <div class="s-rec-glistbox" id="fl_f_1_pl" style="display:none;"> + <ul class="s-rec-goods-list"> + {volist name="$data['hot']" id="hot" length="4"} + <li> + <a href='{:Url("home/goods/detail","id=".$hot["goodsId"])}' target='_blank'> + <img class='goodsImg' data-original="__IMGURL__/{$hot['goodsImg']}" title="{$hot['goodsName']}"/> + </a> + <div class="rec_ginfo"> + <p class="s-rec-goods-desc"><a href='{:Url("home/goods/detail","id=".$hot["goodsId"])}' target='_blank'>{$hot['goodsName']}</a></p> + <div class="s-rec-goods-bottom"> + <p class="s-rec-goods-price"><span>¥{$hot['shopPrice']}</span></p> + <a href="javascript:WST.addCart({$hot['goodsId']});">加入购物车</a> + </div> + </div> + </li> + {/volist} + </ul> + <div class="wst-clear"></div> + </div> + </div> + +</div> + + +{volist name="$data['shopcats']" id="cat1" key="l" length="6"} +<div class="self_container_out"> + <div class="sf_headerbox"> + {/* 店铺一级分类 */} + <div class="sfhl f{$l}_tit_bg"> + <a class="sfh_tit" href="#">{$cat1['catName']}</a> + </div> + {/* 店铺二级分类 */} + <div class="sfhr"> + {/* 楼层二级分类 */} + {php} + $a = count($cat1['children']); + if($a>5)$a=5; + {/php} + {volist name="$cat1['children']" id="cat2" key="l2" length="5"} + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$cat2['catId']])}" class="c18_333">{$cat2['catName']}</a> + {if($l2<$a)}<span class="c18_333 separatory">/</span>{/if} + {/volist} + <span class="c18_333 separatory"> </span> + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}" class="c18_333">查看更多&nbsp;&nbsp;>></a> + </div> + <div class="wst-clear"></div> + </div> + {/* 自营店铺楼层广告 */} + {wst:ads code="self-shop-f$l" id="vo" num="1" cache="86400"} + <div class="sf_adsbox"> + <a {if ($vo['isOpen'])}target='_blank'{/if} {if ($vo['adURL']!='')}onclick="WST.recordClick({$vo['adId']})"{/if} href="{$vo.adURL}" onfocus="this.blur()"> + <img data-original="__IMGURL__/{$vo.adFile}" class="goodsImg" /> + </a> + </div> + {/wst:ads} + {/* 楼层商品列表 */} + <div class="sf_glistbox f{$l}_g_bg"> + <ul class="sf_glist"> + {wst:shopfloorgoods shop="data['shop']['shopId']" cat="cat1['catId']" cache="86400" num='10' id='sgf'} + <li> + <a target="_blank" href="{:Url('home/goods/detail','id='.$sgf['goodsId'])}" title="{$sgf['goodsName']}"> + <div class="sf_img"> + <img class='goodsImg' data-original="__IMGURL__/{$sgf['goodsImg']}" alt="{$sgf['goodsName']}" title="{$sgf['goodsName']}"/> + </div> + <p class="sf_gname"> + {$sgf['goodsName']} + </p> + <p class="sf_price"> + <span class="c11">¥</span>{:sprintf('%.1f',$sgf['shopPrice'])} + </p> + </a> + </li> + {/wst:shopfloorgoods} + <div class="wst-clear"></div> + </ul> + </div> +</div> +{/volist} +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/self_shop.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script type='text/javascript'> +$(function(){ + WST.dropDownLayer(".wst-shop-code",".wst-shop-codes"); + var qr = qrcode(10, 'M'); + var shopId = $("#shopId").val(); + var url = "{:url('mobile/shops/selfShop',array('shopId'=>$data['shop']['shopId']),true,true)}"; + qr.addData(url); + qr.make(); + $('#qrcode').html(qr.createImgTag()); +}); +</script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/self_shop_header.html b/hyhproject/home/view/default/self_shop_header.html new file mode 100755 index 0000000..c328e00 --- /dev/null +++ b/hyhproject/home/view/default/self_shop_header.html @@ -0,0 +1,82 @@ +<div class='wst-search-container'> + + <div class="wst-shop-h"> + <div class="wst-shop-img"><a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"><img class="shopsImg" data-original="__IMGURL__/{$data['shop']['shopImg']}" title="{$data['shop']['shopName']}"></a></div> + <div class="wst-shop-info"> + <p>{$data['shop']['shopName']}</p> + <div class="wst-shop-info2"> + {volist name="$data['shop']['accreds']" id="ac"} + <img src="__IMGURL__/{$ac['accredImg']}"><span>{$ac['accredName']}</span> + {/volist} + {if($data['shop']['shopQQ'])} + <a href="tencent://message/?uin={$data['shop']['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style="width:65px;height:24px;" src="http://wpa.qq.com/pa?p=1:{$data['shop']['shopQQ']}:7"> + </a> + {/if} + {if($data['shop']['shopWangWang'])} + <a href="http://www.taobao.com/webww/ww.php?ver=3&touid={$data['shop']['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8" target="_blank"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$data['shop']['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" class='wangwang'/> + </a> + {/if} + </div> + <div class="wst-shop-info3"> + <span class="wst-shop-eva">商品评价:<span class="wst-shop-red">{$data['shop']['scores']['goodsScore']}</span></span> + <span class="wst-shop-eva">时效评价:<span class="wst-shop-red">{$data['shop']['scores']['timeScore']}</span></span> + <span class="wst-shop-eva">服务评价:<span class="wst-shop-red">{$data['shop']['scores']['serviceScore']}</span></span> + {if($data['shop']['favShop']>0)} + <a href='javascript:void(0);' onclick='WST.cancelFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav">已关注</a> + {else} + <a href='javascript:void(0);' onclick='WST.addFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav2">关注店铺</a> + {/if} + <span class="wst-shop-eva">用手机逛本店 &nbsp;&nbsp;|</span> + <a class="wst-shop-code"><span class="wst-shop-codes hide"><div id='qrcode' style='width:142px;height:142px;'></div></span></a> + + </div> + </div> + <div class="wst-shop-sea"> + <input type="text" id="goodsName" value="{$goodsName}" placeholder="输入商品名称"> + <a class="search" href="javascript:void(0);" onclick="javascript:WST.goodsSearch($('#goodsName').val());">搜全站</a> + <a class="search" href="javascript:void(0);" onclick="javascript:searchShopsGoods(0);">搜本店</a> + <div class="wst-shop-word"> + {volist name="data['shop']['shopHotWords']" id="shw"} + <a href='{:Url("home/shops/home",array('shopId'=>$data['shop']['shopId'],'goodsName'=>$shw))}'>{$shw}</a>{if $i< count($data['shop']['shopHotWords'])}&nbsp;|&nbsp;{/if} + {/volist} + </div> + <div> + <div style="clear: both;"></div> + <div class="jiathis_style_24x24 wst-shop-share"> + <a class="jiathis_button_qzone"></a> + <a class="jiathis_button_tsina"></a> + <a class="jiathis_button_tqq"></a> + <a class="jiathis_button_weixin"></a> + <a class="jiathis_button_cqq"></a> + <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> + </div> + </div> + <div style="clear: both;"></div> + </div> + <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js" charset="utf-8"></script> + {:hook('distributHook',['module'=>1,'positionType'=>1,'shop'=>$data['shop'],'getParams'=>input()])} + </div> + <div class="wst-clear"></div> + </div> +</div> +{if($data['shop']['shopBanner'])}<div class="wst-shop-tu" style="background: url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat scroll center top;background-size:cover;"></div>{/if} +<div class="wst-clear"></div> +<div class="s-wst-nav-menus"> + <div id="s-wst-nav-items"> + <ul> + <li class="s-nav-li s-cat-head"style="background-color:#DF2003"><a href="{:Url('home/shops/home',['shopId'=>$data['shop']['shopId']])}" target="_blank" ><em></em>本店商品分类</a></li> + {volist name="$data['shopcats']" id="cat1" key="l" length="6"} + <li class="s-nav-li"> + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}" target="_blank">{$cat1['catName']}</a> + </li> + {/volist} + <li class="s-nav-li"> <a class="homepage" href="{:url('/')}" target="_blank">返回商城首页</a></li> + </ul> + </div> + + <span class="wst-clear"></span> + </div> +</div> +<div class="wst-clear"></div> diff --git a/hyhproject/home/view/default/shops/base.html b/hyhproject/home/view/default/shops/base.html new file mode 100755 index 0000000..9df8ee9 --- /dev/null +++ b/hyhproject/home/view/default/shops/base.html @@ -0,0 +1,115 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shop.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> + +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> +<script type='text/javascript' src='__ROOT__/static/plugins/lazyload/jquery.lazyload.min.js?v={$v}'></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}", "SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","PHONE_VERFY":"{:WSTConf('CONF.phoneVerfy')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","MESSAGE_BOX":"{:WSTShopMessageBox()}","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} + {:WSTLoginTarget(1)} +$(function() { + WST.initShopCenter(); +}); +</script> +</head> +<body> + +{block name="top"} +{include file="default/top" /} +{/block} + +{block name="header"} + +<div class='wst-lite-bac'> +<div class='wst-lite-container'> + <div class='wst-logo'><a href='{$Request.root.true}'><img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="80" width='160'></a></div> + <div class="wst-lite-tit"><span>卖家中心</span><a class="wst-lite-in" href='{$Request.root.true}'>返回商城首页</a></div> + <div class="wst-lite-sea"> + <div class='search'> + <input type="hidden" id="search-type" value="{:isset($keytype)?1:0}"/> + + <ul class="j-search-box"> + <li class="j-search-type"> + 搜<span>{if isset($keytype)}店铺{else}商品{/if}</span>&nbsp;<i class="arrow"> </i> + </li> + <li class="j-type-list"> + {if isset($keytype)} + <div data="0">商品</div> + {else} + <div data="1">店铺</div> + {/if} + </li> + </ul> + + <input type="text" id='search-ipt' class='search-ipt' value='{:isset($keyword)?$keyword:""}'/> + <div id='search-btn' class="search-btn" onclick='javascript:WST.search(this.value)'></div> + </div> + </div> + <div class="wst-clear"></div> +</div> +<div class="wst-clear"></div> +</div> +{/block} +<div class="wst-wrap"> + <div class='wst-header'> + <div class="wst-shop-nav"> + <div class="wst-nav-box"> + {php}$homeMenus = WSTHomeMenus(1);{/php} + {volist name="$homeMenus['menus']" id="vo"} + <a href="__ROOT__/{$vo['menuUrl']}?homeMenuId={$vo['menuId']}"><li class="liselect wst-lfloat {if($vo['menuId'] == $homeMenus['menuId1'])}wst-nav-boxa{/if}">{$vo['menuName']}</li></a> + {/volist} + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-nav'></div> + <div class='wst-main'> + <div class='wst-menu'> + {if isset($homeMenus['menus'][$homeMenus['menuId1']]['list']) } + {volist name="$homeMenus['menus'][$homeMenus['menuId1']]['list']" id="menus"} + <span class='wst-menu-title'>{$menus['menuName']}<img src="__STYLE__/img/user_icon_sider_zhankai.png"></span> + <ul> + {if isset($menus['list']) } + {volist name="menus['list']" id="menu" key='k'} + <li class="{if($homeMenus['menuId3']==$menu['menuId'])}wst-menua{/if} wst-menuas" onclick="getMenus('{$menu['menuId']}','{$menu['menuUrl']}')"> + {$menu['menuName']} + <span id="mId_{$menu['menuId']}"></span> + </li> + {/volist} + {/if} + </ul> + {/volist} + {/if} + + + + </div> + <div class='wst-content'> + {block name="content"}<div class="result">卖家中心</div>{/block} + </div> + </div> + <div style='clear:both;'></div> + <br/> + </div> +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}{/block} +<script> +function getMenus(menuId,menuUrl){ + $.post(WST.U('home/index/getMenuSession'), {menuId:menuId}, function(data){ + location.href=WST.U(menuUrl); + }); +} +</script> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/cashdraws/box_draw.html b/hyhproject/home/view/default/shops/cashdraws/box_draw.html new file mode 100755 index 0000000..00bb9db --- /dev/null +++ b/hyhproject/home/view/default/shops/cashdraws/box_draw.html @@ -0,0 +1,35 @@ + <form id='drawForm' autocomplete='off' > + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <table width='100%' style='margin-top:10px;' class='wst-form' style='dislay:none'> + <tr> + <th width='120' align='right'>提现账号:</th> + <td style='line-height:25px;'> + 【{$object['bankName']}】{$object['bankNo']} + </td> + </tr> + <tr> + <th width='120' align='right'>账号持有人:</th> + <td>{$object['bankUserName']}</td> + </tr> + <tr> + <th align='right'>提现金额<font color='red'>*</font>:</th> + <td> + <input type='text' id='money' class='j-ipt' style='width:250px' data-rule="提现金额: required;" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2)" onkeyup="javascript:WST.isChinese(this,1)" placeholder="可提现金额:¥{$shop['shopMoney']-$shop['rechargeMoney']}"/> + </td> + </tr> + <tr height='40'> + <th align='right'>支付密码<font color='red'>*</font>:</th> + <td> + <input type="password" style="display:none"> + <input type='password' id='payPwd' class='j-ipt' style='width:250px' data-rule="支付密码: required;"/> + </td> + </tr> + <tr> + <td colspan='2' style='text-align: center;padding-top:5px;'> + <a class='s-btn' onclick="drawMoney()">保存</a> + <a class='s-btn2' style='margin-left:10px;' onclick='layerclose()'>取消</a> + </td> + </tr> + </table> + </form> + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> diff --git a/hyhproject/home/view/default/shops/cashdraws/cashdraws.js b/hyhproject/home/view/default/shops/cashdraws/cashdraws.js new file mode 100755 index 0000000..0e6c2fe --- /dev/null +++ b/hyhproject/home/view/default/shops/cashdraws/cashdraws.js @@ -0,0 +1,113 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0);break; + case 1:pageConfigQuery(0);break; + } + }}) +}); +var isSetPayPwd = 1; +function getShopMoney(){ + $.post(WST.U('home/shops/getShopMoney'),{},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var shopMoney = json.data.shopMoney; + var rechargeMoney = json.data.rechargeMoney; + $('#shopMoney').html('¥'+shopMoney); + $('#lockMoney').html('¥'+json.data.lockMoney); + rechargeMoney = parseFloat(shopMoney - rechargeMoney) + $('#userCashMoney').html('¥'+rechargeMoney.toFixed(2)); + if(json.data.isDraw==1){ + $('#drawBtn').show(); + }else{ + $('#drawBtn').hide(); + } + isSetPayPwd = json.data.isSetPayPwd; + } + }); +} +function pageQuery(p){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + $.post(WST.U('home/cashdraws/pageQueryByShop'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + pageQuery(json.TotalPage); + return; + } + var gettpl = document.getElementById('draw-list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#draw-page-list').html(html); + }); + laypage({ + cont: 'draw-pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr); + } + } + }); + } + }); +} +var w; +function toDrawMoney(){ + if(isSetPayPwd==0){ + WST.msg('您尚未设置支付密码,请先设置支付密码',{icon:2,time:1000},function(){ + location.href = WST.U('home/users/security'); + }); + return; + } + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + $.post(WST.U('home/cashdraws/toEditByShop'),{},function(data,textStatus){ + layer.close(tips); + w = WST.open({ + type: 1, + title:"申请提现", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['550px', '250px'], + offset: '100px' + }); + }); +} +function drawMoney(){ + $('#drawForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.payPwd = rsa.encrypt(params.payPwd); + } + var tips = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/cashdraws/drawMoneyByShop'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + pageQuery(WSTCurrPage); + getShopMoney(); + layer.close(w); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function layerclose(){ + layer.close(w); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/cashdraws/list.html b/hyhproject/home/view/default/shops/cashdraws/list.html new file mode 100755 index 0000000..54ef748 --- /dev/null +++ b/hyhproject/home/view/default/shops/cashdraws/list.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}提现管理-卖家中心{__block__}{/block} +{block name='css'} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='money-head'> + <div class='shop-logo'><img height='100' width='100' src='__IMGURL__/{:session("WST_USER.shopImg")}'></div> + <div class='shop-info'> + <div class='shopName'>{:session('WST_USER.shopName')}</div> + <div class='shopMoney'> + <div class="usermoney"> + 可用资金:<font color='red' id='shopMoney'>¥0</font> + </div> + <div class="cashbox"> + <span style='margin-left:20px;'><a class="cashbtn" id='drawBtn' href="javascript:toDrawMoney();" >申请提现</a></span> + <span class='draw-tips'>(至少¥{:WSTConf('CONF.drawCashShopLimit')}方可提现)</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="wst-clear"></div> + <div class="money-rows"> + <div class="lockbox"> + 冻结资金:<font color='red' id='lockMoney'>¥0</font> + </div> + <div class="cashbox"> + <span class="cashmoney-box">可提现金额:<font color='red' id='userCashMoney'>¥0</font></span> + </div> + <div class="wst-clear"></div> + </div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>提现记录</li> + </ul> + <div class='wst-tab-content'> + <div class='wst-tab-item'> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='80'>提现单号</th> + <th width='100'>提现银行</th> + <th width='130'>开户地区</th> + <th width='130'>银行卡号</th> + <th width='100'>持卡人</th> + <th width='60'>提现金额</th> + <th width='250'>提现状态</th> + </tr> + </thead> + <script id="draw-list" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].cashNo}}</td> + <td>{{d[i].accTargetName}}</td> + <td>{{ d[i].accAreaName }}</td> + <td>{{ d[i].accNo }}</td> + <td>{{ d[i].accUser }}</td> + <td>¥{{ d[i].money }}</td> + <td {{#if(d[i].cashSatus==-1){}}style='line-height:25px;'{{#}}}> + {{#if(d[i].cashSatus==1){}}提现成功 + {{#}else if(d[i].cashSatus==-1){}}提现失败 + <br/>【原因】{{d[i].cashRemarks}} + {{#}else{}}待处理{{#}}}</td> + </tr> + {{# } }} + </script> + <tbody id="draw-page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="draw-pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/cashdraws/cashdraws.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ + getShopMoney(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/freights/freights.js b/hyhproject/home/view/default/shops/freights/freights.js new file mode 100755 index 0000000..f85553e --- /dev/null +++ b/hyhproject/home/view/default/shops/freights/freights.js @@ -0,0 +1,53 @@ +$(function(){ + areasByList(); +}); +//运费列表 +function areasByList(){ + $.post(WST.U('home/shopfreights/listProvince'),'',function(data){ + var json = WST.toJson(data); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-info').html(html); + }); + }); +} + +function treeOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/seller_icon_zk.png">'); + $('.text_'+id).show(); + $('.tree_'+id).show(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/seller_icon_sq.png">'); + $('.text_'+id).hide(); + $('.tree_'+id).hide(); + } +} + +function freightOnblur(obj,id,v){ + $postage = $(obj).val(); + if(v == 0){ + $('.possort').val($postage); + }else{ + $('.price_'+id).val($postage); + } +} + +function freightSubmit(){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopfreights/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + setTimeout(function(){ + //location.href=WST.U('home/shopfreights/index'); + },2000); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/freights/list.html b/hyhproject/home/view/default/shops/freights/list.html new file mode 100755 index 0000000..0c12249 --- /dev/null +++ b/hyhproject/home/view/default/shops/freights/list.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}运费设置 - 卖家中心{__block__}{/block} +{block name="css"}{/block} + +{block name="content"} + +<div class="wst-body"> +<div class="wst-shop-head"><span>运费设置</span></div> +<div class="wst-clear"></div> + <form autocomplete="off"> + <table id="cat_list_tab" class='wst-list wst-form'> + <thead> + <tr class="wst-colour"> + <th class="wst-fre-th">名称</th> + <th class="wst-fre-th" width="200">运费</th> + </tr> + </thead> + <tbody> + <tr class="wst-fre-hov"> + <td class="wst-fre-td"> + <span style='width:400px;height:22px;'>默认运费</span> + </td> + <td><input type='text' style='width:80px;' value="{$shFreight['freight']}" onblur="javascript:freightOnblur(this,'',0)" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + </tr> + </tbody> + <tbody id="list-info"></tbody> +</table> +<div class='wst-tbar-group' style='height:76px;text-align:center;'> + <a class='s-btn' style='margin-top:30px;width:100px;height: 30px;' type="button" onclick='javascript:freightSubmit()'>保&nbsp;存</a> +</div> +</form> +</div> +<script id="list" type="text/html"> +{{# for(var i = 0; i < d.length; i++){ }} + <tr isLoad='1' class="wst-fre-hov"> + <td class="wst-fre-td"> + <span class='wst-tree-open active' onclick='javascript:treeOpen(this,"{{ d[i].areaId }}")'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_sq.png"></span> + <span style='width:400px;height:22px;'>{{ d[i].areaName }}</span> + </td> + <td><input class='possort text_{{ d[i].areaId }}' type='text' style='width:80px;display:none;' value="" onblur='javascript:freightOnblur(this,"{{ d[i].areaId }}",2)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + </tr> +{{# for(var j = 0; j < d[i].listProvince.length; j++){ }} + <tr class="tree_{{ d[i].listProvince[j].parentId }} hide wst-fre-hov"> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <span style='width:400px;height:22px;'>{{ d[i].listProvince[j].areaName }}</span> + </td> +{{#if(typeof(d[i].listProvince[j].freight)=='object'){}} + <td><input class='price_{{ d[i].listProvince[j].parentId }} possort ipt' id="{{ d[i].listProvince[j].areaId }}" type='text' style='width:80px;' value="{$shFreight['freight']}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> +{{# }else{ }} + <td><input class='price_{{ d[i].listProvince[j].parentId }} possort ipt' id="{{ d[i].listProvince[j].areaId }}" type='text' style='width:80px;' value="{{d[i].listProvince[j].freight}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> +{{# } }} + </tr> +{{# } }} +{{# } }} +</script> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}<script type='text/javascript' src='__STYLE__/shops/freights/freights.js?v={$v}'></script>{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/edit.html b/hyhproject/home/view/default/shops/goods/edit.html new file mode 100755 index 0000000..5ae7a46 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/edit.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}<?=($object['goodsId']>0)?"编辑":"新增";?>商品-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<style> +label{margin-right:10px;} +#specsAttrBox .webuploader-container{width:80px;height:25px;line-height:25px;overflow:hidden;} +</style> +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>商品信息</li> + <li>规格属性</li> + <li>商品相册</li> + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;border:0px;'> + <form id='editform' autocomplete='off'> + <div class="wst-tab-item" style="position: relative;"> + {include file='default/shops/goods/edit0'/} + </div> + <div class="wst-tab-item" style="position: relative;display:none"> + {include file='default/shops/goods/edit1'/} + </div> + <div class="wst-tab-item" style="position: relative;display:none"> + {include file='default/shops/goods/edit2'/} + </div> + </form> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__STATIC__/plugins/kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +var initBatchUpload = false,editor1 = null,specNum = 0,src='{$src}'; +{php}unset($object['goodsDesc']);{/php} +var OBJ = <?=json_encode($object)?>; +$(function(){initEdit()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/edit0.html b/hyhproject/home/view/default/shops/goods/edit0.html new file mode 100755 index 0000000..f8b45a4 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/edit0.html @@ -0,0 +1,200 @@ +<style> +.webuploader-pick {background: #e45050 none repeat scroll 0 0;} +</style> +<input type='hidden' id='goodsId' class='j-ipt' value='{$object["goodsId"]}' /> +<table class='wst-form'> + <tr> + <th width='150'>商品名称<font color='red'>*</font>:</th> + <td width='300'> + <input type='text' class='j-ipt' id='goodsName' value='{$object["goodsName"]}' maxLength='100' data-rule='商品名称:required;'/> + </td> + <td rowspan='6'> + <div id='goodsImgBox'> + <img src='__IMGURL__/{$object["goodsImg"]}' id='preview' width='150' height='150'> + </div> + <div id='goodsImgPicker'>请上传商品图片</div><span id='uploadMsg'></span> + <input type='hidden' id='goodsImg' class='j-ipt' data-target='#msg_goodsImg' value='{if $object["goodsId"]>0}{$object["goodsImg"]}{/if}' data-rule="商品图片: required;"/> + <span class='msg-box' id='msg_goodsImg'></span> + </td> + </tr> + <tr> + <th>商品类型<font color='red'>*</font>:</th> + <td> + <select id='goodsType' class='j-ipt' onchange="changeGoodsType(this.value)" {if $object["goodsId"]>0}disabled{/if}> + <option value='0' {if($object["goodsType"]==0)}selected{/if}>实物商品</option> + {if($object["goodsType"]==1)} <option value='1' {if($object["goodsType"]==1)}selected{/if}>虚拟商品</option>{/if} + </select> + </td> + </tr> + <tr> + <th>商品编号<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='goodsSn' value='{$object["goodsSn"]}' maxLength='20' data-rule='商品编号:required;'/></td> + </tr> + <tr> + <th width='150'>商品货号<font color='red'>*</font>:</th> + <td width='300'> + <input type='text' class='j-ipt' id='productNo' value='{$object["productNo"]}' maxLength='20' data-rule='商品货号:required;'/> + </td> + </tr> + {if($object["alone"]==1)} + <tr> + <th width='150'>商品成本价:</th> + <td width='300'> + <input type='text' class='j-ipt' id='basicsMoney' value='{$object["basicsMoney"]}' maxLength='20' data-rule=''/> + </td> + </tr> + {/if} + <tr> + <th>市场价格<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='marketPrice' value='{$object["marketPrice"]}' maxLength='10' data-rule='市场价格:required;price' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th><font color='red'>小提示</font>:</th> + <td>店铺价格包含惠宝抵现20%;<br />比如店铺价格100元,会员可抵20元,商家实收80元</td> + </tr> + <tr> + <th>店铺价格<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='shopPrice' value='{$object["shopPrice"]}' maxLength='10' data-rule='店铺价格:required;price' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <!-- <tr> + <th>ect支付<font color='red'>*</font>:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='ectPay' id="ectPay-1" class='j-ipt wst-radio' value='1' {if $object['ectPay']==1}checked{/if}/><label for="ectPay-1" class="mt-1"></label>启用</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='ectPay' id="ectPay-0" class='j-ipt wst-radio' value='0' {if $object['ectPay']==0}checked{/if}/><label for="ectPay-0" class="mt-1"></label>禁用</label> + </div> + </td> + </tr> --> + {if $object["ectPayRatio"] < 1} + <tr> + <th><font color='red'>小提示</font>:</th> + <td>ECT价格为店铺价格的{$object["ectPayRatio"]*10}折;<br />比如店铺价格100元,木吉抵扣20元,付款80元,ECT按{$object["ectPayRatio"]*80}元对应ECT数量结算</td> + </tr> + <tr> + <th>ECT价格<font color='red'>*</font>:</th> + <td><input type='text' id='ectPrice' value='{$object["shopPrice"]*$object["ectPayRatio"]}' maxLength='10' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)" disabled="disabled" /></td> + </tr> + {/if} + + + <tr id='goodsStockTr' {if($object["goodsType"]==1)}style='display:none'{/if}> + <th>商品库存<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='goodsStock' value='{$object["goodsStock"]}' maxLength='10' data-rule='商品库存:required;integer[+0]' onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>预警库存<font color='red'>*</font>:</th> + <td colspan='2'><input type='text' class='j-ipt' id='warnStock' value='{$object["warnStock"]}' maxLength='10' data-rule='预警库存:required;integer[+0]' onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>商品单位<font color='red'>*</font>:</th> + <td colspan='2'><input type='text' class='j-ipt' id='goodsUnit' value='{$object["goodsUnit"]}' maxLength='10' data-rule='商品单位:required;'/></td> + </tr> + <tr> + <th>SEO关键字:</th> + <td colspan='2'><input type='text' class='j-ipt' id='goodsSeoKeywords' maxLength='100' value='{$object["goodsSeoKeywords"]}' style='width:70%'/></td> + </tr> + <tr> + <th>商品促销信息:</th> + <td colspan='2'><textarea class='j-ipt' id='goodsTips' maxLength='100' style='width:500px;height:50px'>{$object["goodsTips"]}</textarea></td> + </tr> + {:hook('homeDocumentShopEditGoods',['goodsId'=>$object["goodsId"]])} + <tr> + <th>商品状态<font color='red'>*</font>:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='isSale' id="isSale-1" class='j-ipt wst-radio' value='1' {if $object['isSale']==1}checked{/if}/><label for="isSale-1" class="mt-1"></label>上架</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='isSale' id="isSale-0" class='j-ipt wst-radio' value='0' {if $object['isSale']==0}checked{/if}/><label for="isSale-0" class="mt-1"></label>下架</label> + </div> + </td> + </tr> + <tr> + <th>商品属性:</th> + <td colspan='2'> + <div class="checkbox-box"> + <label> + <input id="isRecom" name='isRecom' class="j-ipt wst-checkbox" {if $object['isRecom']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isRecom"></label>推荐 + </label> + <label> + <input id="isBest" name="isBest" class="j-ipt wst-checkbox" {if $object['isBest']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isBest"></label>精品 + </label> + <label> + <input id="isNew" name="isNew" class="j-ipt wst-checkbox" {if $object['isNew']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isNew"></label>新品 + </label> + <label> + <input id="isHot" name="isHot" class="j-ipt wst-checkbox" {if $object['isHot']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isHot"></label>热销 + </label> + </div> + </td> + </tr> + <tr> + <th>是否包邮:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='isFreeShipping' id="isFreeShipping-1" class='j-ipt wst-radio' value='1' {if $object['isFreeShipping']==1}checked{/if}/><label for="isFreeShipping-1" class="mt-1"></label>包邮</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='isFreeShipping' id="isFreeShipping-0" class='j-ipt wst-radio' value='0' {if $object['isFreeShipping']==0}checked{/if}/><label for="isFreeShipping-0" class="mt-1"></label>不包邮</label> + </div> + </td> + </tr> + + <tr> + <th>商城分类<font color='red'>*</font>:</th> + <td colspan='2'> + <select id="cat_0" class='ipt j-goodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:true,className:'j-goodsCats',afterFunc:'lastGoodsCatCallback'});getBrands('brandId',this.value)"> + <option value="">-请选择-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>本店分类:</th> + <td colspan='2'> + <select id="shopCatId1" class='j-ipt' onchange="getShopsCats('shopCatId2',this.value,'');"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" {if $object['shopCatId1']==$vo['catId']}selected{/if}> + <!-- {$vo['catName']} --> + <!--分类后面添加特产省份mark 20180518 by zl--> + {if condition = "$vo['provName'] neq ''"} + {$vo['catName'].'('.$vo['provName'].')'} + {else/} + {$vo['catName']} + {/if} + <!--end--> + </option> + {/volist} + </select> + <select id='shopCatId2' class='j-ipt'> + <option value=''>请选择</option> + </select> + </td> + </tr> + <tr> + <th>品牌:</th> + <td colspan='2'> + <select id="brandId" class='j-ipt'> + <option value="0">-请选择-</option> + </select> + </td> + </tr> + <tr> + <th>商品描述<font color='red'>*</font>:</th> + <td colspan='2'> + <textarea rows="2" cols="60" id='goodsDesc' class='j-ipt' name='goodsDesc' data-rule='商品描述:required;'>{$object['goodsDesc']}</textarea> + </td> + </tr> + <tr> + <td colspan='3' align='center' style='text-align:center;padding-top:10px;'> + <a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> + <a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> + </td> + </tr> +</table> +<script type="text/javascript"> + $("#shopPrice").change(function(){ + // alert($(this).val()); + var txtChange = $(this).val(); + $("#ectPrice").val(txtChange*{$object['ectPayRatio']}); + }); +</script> \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/edit1.html b/hyhproject/home/view/default/shops/goods/edit1.html new file mode 100755 index 0000000..1c5c571 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/edit1.html @@ -0,0 +1,9 @@ +<div id='specsAttrBox'></div> +<div id='specTips' style='display:none'> +<div class='wst-tips-box' style='margin-left:0px;'>1.若改动商品规格时,销售规则表将会重新绘制,填写销售规格表前前选择好商品规格 +</br>2.如果不批发,起批数和批发价保留为空即可</div> +</div> +<div id='specBtns' style='margin:0px auto;text-align:center;display:none'> +<a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> +<a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> +</div> \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/edit2.html b/hyhproject/home/view/default/shops/goods/edit2.html new file mode 100755 index 0000000..7e4e823 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/edit2.html @@ -0,0 +1,45 @@ +<style> +.wst-batchupload .placeholder .webuploader-pick { + background: #e45050 none repeat scroll 0 0; +} +.wst-batchupload .statusBar .btns .uploadBtn { + background: #e45050 none repeat scroll 0 0; +} +.wst-batchupload .statusBar .btns .uploadBtn:hover{ + background: #e42525; +} +</style> +<div id="batchUpload" class="wst-batchupload"> + <div class="queueList filled"> + <div id="dndArea" class="placeholder {if !empty($object['gallery'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选50张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['gallery']" id="vo"} + <li class="state-complete" style="border: 1px solid rgb(59, 114, 165);"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo}"> + </p> + <input type="hidden" v="{$vo}" iv="{$vo}" class="j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar" {if empty($object['gallery'])}style="display: none;"{/if}> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> +</div> +<div style='margin:0px auto;text-align:center;border-top:1px solid #cccccc;padding-top:10px;'> +<a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> +<a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> +</div> diff --git a/hyhproject/home/view/default/shops/goods/goods.js b/hyhproject/home/view/default/shops/goods/goods.js new file mode 100755 index 0000000..7c340ed --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/goods.js @@ -0,0 +1,1136 @@ +/**删除批量上传的图片**/ +function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除商品图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); +} +function lastGoodsCatCallback(opts){ + if(opts.isLast && opts.val){ + getSpecAttrs(opts.val); + }else{ + $('#specBtns').hide(); + $('#specsAttrBox').empty(); + } +} +/**初始化**/ +function initEdit(){ + $('#tab').TabPanel({tab:0,callback:function(no){ + if(no==1){ + $('.j-specImg').children().each(function(){ + if(!$(this).hasClass('webuploader-pick'))$(this).css({width:'80px',height:'25px'}); + }); + } + if(!initBatchUpload && no==2){ + initBatchUpload = true; + var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'goods',isWatermark:1,isThumb:1},uploadSuccess:function(file,response){ + var json = WST.toJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" class="j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + //$li.append('<span class="btn-setDefault">默认</span>' ); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid rgb(59, 114, 165)'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); + } + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + }}); + WST.upload({ + pick:'#goodsImgPicker', + /**不让上传图片压缩,否则图片不清晰,make cheng 20180703**/ + formData: {dir:'goods',isWatermark:1,isThumb:0}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + console.log(json); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + // $('#preview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb); + // 修改为oss 地址 mark 20180612 by zll + $('#preview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb); + $('#goodsImg').val(json.savePath+json.name); + $('#msg_goodsImg').hide(); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + KindEditor.ready(function(K) { + editor1 = K.create('textarea[name="goodsDesc"]', { + height:'350px', + width:'800px', + uploadJson : WST.conf.ROOT+'/home/goods/editorUpload', + allowFileManager : false, + allowImageUpload : true, + allowMediaUpload : false, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','multiimage','media','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } + }); + }); + if(OBJ.goodsId>0){ + var goodsCatIds = OBJ.goodsCatIdPath.split('_'); + getBrands('brandId',goodsCatIds[0],OBJ.brandId); + if(goodsCatIds.length>1){ + var objId = goodsCatIds[0]; + $('#cat_0').val(objId); + var opts = {id:'cat_0',val:goodsCatIds[0],childIds:goodsCatIds,className:'j-goodsCats',afterFunc:'lastGoodsCatCallback'} + WST.ITSetGoodsCats(opts); + } + getShopsCats('shopCatId2',OBJ.shopCatId1,OBJ.shopCatId2); + } + +} +/**获取本店分类**/ +function getShopsCats(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +/**获取品牌**/ +function getBrands(objId,catId,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/brands/listQuery'),{catId:catId},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.brandId+"' "+((objVal==cat.brandId)?"selected":"")+">"+cat.brandName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +function toEdit(id,src){ + location.href = WST.U('home/goods/edit','id='+id+'&src='+src); +} +/**保存商品数据**/ +function save(){ + var va = $("input[name='defaultSpec']:checked").val(); + if(va){ + $("#marketPrice").val($("#marketPrice_"+va).val()); + $("#shopPrice").val( $("#specPrice_"+va).val()); + } + $('#editform').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + params.goodsCatId = WST.ITGetGoodsCatVal('j-goodsCats'); + params.specNum = specNum; + var specsName,specImg; + $('.j-speccat').each(function(){ + specsName = 'specName_'+$(this).attr('cat')+'_'+$(this).attr('num'); + specImg = 'specImg_'+$(this).attr('cat')+'_'+$(this).attr('num'); + if($(this)[0].checked){ + params[specsName] = $.trim($('#'+specsName).val()); + params[specImg] = $.trim($('#'+specImg).attr('v')); + } + }); + var gallery = []; + $('.j-gallery-img').each(function(){ + gallery.push($(this).attr('v')); + }); + params.gallery = gallery.join(','); + var specsIds = []; + var specidsmap = []; + $('.j-ws').each(function(){ + specsIds.push($(this).attr('v')); + specidsmap.push(WST.blank($(this).attr('sid'))+":"+$(this).attr('v')); + }); + var specmap = []; + for(var key in id2SepcNumConverter){ + specmap.push(key+":"+id2SepcNumConverter[key]); + } + params.specsIds = specsIds.join(','); + params.specidsmap = specidsmap.join(','); + params.specmap = specmap.join(','); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/goods/'+((params.goodsId==0)?"toAdd":"toEdit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + if(params.goodsType==1){ + location.href=WST.U('home/goodsvirtuals/stock','id='+json.data.id); + }else{ + location.href=WST.U('home/goods/'+src); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +var id2SepcNumConverter = {}; +/**添加普通规格值**/ +function addSpec(opts){ + var html = []; + html.push('<div class="spec-item">', + '<input type="checkbox" class="j-speccat j-speccat_'+opts.catId+' j-spec_'+opts.catId+'_'+specNum+'" cat="'+opts.catId+'" num="'+specNum+'" onclick="javascript:addSpecSaleCol()" '+opts.checked+'/>', + '<input type="text" class="spec-ipt" id="specName_'+opts.catId+'_'+specNum+'" maxLength="50" value="'+WST.blank(opts.val)+'" onblur="batchChangeTxt(this.value,'+opts.catId+','+specNum+')"/>', + '<span class="item-del" onclick="delSpec(this,'+opts.catId+','+specNum+')"></span>', + '</div>'); + $(html.join('')).insertBefore('#specAddBtn_'+opts.catId); + if(opts.itemId){ + id2SepcNumConverter[opts.itemId] = opts.catId+'_'+specNum; + } + + specNum++; +} +/**删除普通规格值**/ +function delSpec(obj,catId,num){ + if($('.j-spec_'+catId+'_'+num)[0].checked){ + $('.j-spec_'+catId+'_'+num)[0].checked = false; + addSpecSaleCol(); + } + $(obj).parent().remove(); +} +/**添加带图片的规格值**/ +function addSpecImg(opts){ + var html = []; + html.push('<tr>', + '<td>', + '<input type="checkbox" class="j-speccat j-speccat_'+opts.catId+' j-spec_'+opts.catId+'_'+specNum+'" cat="'+opts.catId+'" num="'+specNum+'" onclick="javascript:addSpecSaleCol()" '+opts.checked+'/>', + '<input type="text" id="specName_'+opts.catId+'_'+specNum+'" maxLength="50" value="'+WST.blank(opts.val)+'" onblur="batchChangeTxt(this.value,'+opts.catId+','+specNum+')"/>', + '</td>', + '<td id="uploadMsg_'+opts.catId+'_'+specNum+'">', + (opts.specImg)?'<img height="25" width="25" id="specImg_'+opts.catId+'_'+specNum+'" src="'+WST.conf.IMGURL+"/"+opts.specImg+'" v="'+opts.specImg+'"/>':"", + '</td><td><div id="specImgPicker_'+specNum+'" class="j-specImg">上传图片</div></td>' + ); + if($('#specTby').children().size()==0){ + html.push('<td><input type="button" id="specImgBtn" value="新增" onclick="addSpecImg({catId:'+opts.catId+',checked:\'\'})"/></td>'); + }else{ + html.push('<td><input type="button" id="specImgBtn" value="删除" onclick="delSpecImg(this,'+opts.catId+','+specNum+')"/></td>'); + } + html.push('</tr>'); + $('#specTby').append(html.join('')); + WST.upload({ + num:specNum, + cat:opts.catId, + pick:'#specImgPicker_'+specNum, + formData: {dir:'goods',isThumb:1}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg_'+this.cat+"_"+this.num).html('<img id="specImg_'+this.cat+"_"+this.num+'" v="'+json.savePath+json.name+'" src="'+WST.conf.IMGURL+"/"+json.savePath+json.thumb+'" height="25" width="25"/>'); + } + }, + progress:function(rate){ + $('#uploadMsg_'+this.cat+"_"+this.num).html('已上传'+rate+"%"); + } + }); + if(opts.itemId){ + id2SepcNumConverter[opts.itemId] = opts.catId+'_'+specNum; + } + specNum++; +} +/**删除带图片的规格值**/ +function delSpecImg(obj,catId,num){ + if($('.j-spec_'+catId+'_'+num)[0].checked){ + $('.j-spec_'+catId+'_'+num)[0].checked = false; + addSpecSaleCol(); + } + $(obj).parent().parent().remove(); +} +/**给销售规格表填上值**/ +function fillSepcSale(){ + var ids = '',tmpids = []; + for(var i=0;i<OBJ.saleSpec.length;i++){ + tmpids = []; + ids = OBJ.saleSpec[i].specIds; + ids = ids.split(':'); + for(var j=0;j<ids.length;j++){ + tmpids.push(id2SepcNumConverter[ids[j]]); + } + tmpids = tmpids.join('-'); + if(OBJ.saleSpec[i].isDefault)$('#isDefault_'+tmpids).attr('checked',true); + $('#productNo_'+tmpids).val(OBJ.saleSpec[i].productNo); + $('#marketPrice_'+tmpids).val(OBJ.saleSpec[i].marketPrice); + $('#specPrice_'+tmpids).val(OBJ.saleSpec[i].specPrice); + $('#initNum_'+tmpids).val(OBJ.saleSpec[i].initNum); + $('#whslePrice_'+tmpids).val(OBJ.saleSpec[i].whslePrice); + $('#specStock_'+tmpids).val(OBJ.saleSpec[i].specStock); + $('#warnStock_'+tmpids).val(OBJ.saleSpec[i].warnStock); + $('#saleNum_'+tmpids).val(OBJ.saleSpec[i].saleNum); + $('#saleNum_'+tmpids).attr('sid',OBJ.saleSpec[i].id); + } +} +/**生成销售规格表**/ +function addSpecSaleCol(){ + //获取规格分类和规格值 + var catId,snum,specCols = {},obj = []; + $('.j-speccat').each(function(){ + if($(this)[0].checked){ + catId = $(this).attr('cat'); + snum = $(this).attr('num'); + if(!specCols[catId]){ + specCols[catId] = []; + specCols[catId].push({id:catId+"_"+snum,val:$.trim($('#specName_'+catId+"_"+snum).val())}); + }else{ + specCols[catId].push({id:catId+"_"+snum,val:$.trim($('#specName_'+catId+"_"+snum).val())}); + } + } + }); + //创建表头 + $('.j-saleTd').remove(); + var html = [],specArray = [];; + for(var key in specCols){ + html.push('<th class="j-saleTd">'+$('#specCat_'+key).html()+'</th>'); + specArray.push(specCols[key]); + } + if(html.length==0){ + $('#goodsStock').removeAttr('disabled'); + $('#shopPrice').removeAttr('disabled'); + $('#marketPrice').removeAttr('disabled'); + $('#warnStock').removeAttr('disabled'); + return; + } + $(html.join('')).insertBefore('#thCol'); + //组合规格值 + this.combined = function(doubleArrays){ + var len = doubleArrays.length; + if (len >= 2) { + var arr1 = doubleArrays[0]; + var arr2 = doubleArrays[1]; + var len1 = doubleArrays[0].length; + var len2 = doubleArrays[1].length; + var newlen = len1 * len2; + var temp = new Array(newlen),ntemp; + var index = 0; + for (var i = 0; i < len1; i++) { + if(arr1[i].length){ + for (var k = 0; k < len2; k++) { + ntemp = arr1[i].slice(); + ntemp.push(arr2[k]); + temp[index] = ntemp; + index++; + } + }else{ + for (var j = 0; j < len2; j++) { + temp[index] = [arr1[i],arr2[j]]; + index++; + } + } + } + var newArray = new Array(len - 1); + newArray[0] = temp; + if (len > 2) { + var _count = 1; + for (var i = 2; i < len; i++) { + newArray[_count] = doubleArrays[i]; + _count++; + } + } + return this.combined(newArray); + }else { + return doubleArrays[0]; + } + } + + var specsRows = this.combined(specArray); + //生成规格值表 + html = []; + var id=[],key=1,specHtml = []; + var productNo = $('#productNo').val(),specProductNo = ''; + for(var i=0;i<specsRows.length;i++){ + id = [],specHtml = []; + html.push('<tr class="j-saleTd">'); + + if(specsRows[i].length){ + for(var j=0;j<specsRows[i].length;j++){ + id.push(specsRows[i][j].id); + specHtml.push('<td class="j-td_'+specsRows[i][j].id+'">' + specsRows[i][j].val + '</td>'); + } + }else{ + id.push(specsRows[i].id); + specHtml.push('<td>' + specsRows[i].val + '</td>'); + } + id = id.join('-'); + if(OBJ.goodsId==0){ + specProductNo = productNo+'-'+key; + } + html.push(' <td><input type="radio" id="isDefault_'+id+'" name="defaultSpec" class="j-ipt" value="'+id+'"/></td>'); + html.push(specHtml.join('')); + html.push(' <td><input type="text" class="spec-sale-goodsNo j-ipt" id="productNo_'+id+'" value="'+specProductNo+'" onblur="checkProductNo(this)" ></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="marketPrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="specPrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="initNum_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="whslePrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="specStock_'+id+'" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="warnStock_'+id+'" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td class="j-ws" v="'+id+'" id="saleNum_'+id+'">0</td>', + '</tr>'); + key++; + } + $('#spec-sale-tby').append(html.join('')); + //判断是否禁用商品价格和库存字段 + if($('#spec-sale-tby').html()!=''){ + $('#goodsStock').prop('disabled',true); + $('#shopPrice').prop('disabled',true); + $('#marketPrice').prop('disabled',true); + $('#warnStock').prop('disabled',true); + } + //设置销售规格表值 + if(OBJ.saleSpec)fillSepcSale(); +} +/**根据批量修改销售规格值**/ +function batchChange(v,id){ + if($.trim(v)!=''){ + $('input[type=text][id^="'+id+'_"]').val(v); + } +} +/**根据规格值修改 销售规格表 里的值**/ +function batchChangeTxt(v,catId,num){ + $('.j-td_'+catId+"_"+num).each(function(){ + $(this).html(v); + }); +} +/**检测商品销售规格值是否重复**/ +function checkProductNo(obj){ + v = $.trim(obj.value); + var num = 0; + $('input[type=text][id^="productNo_"]').each(function(){ + if(v==$.trim($(this).val()))num++; + }); + if(num>1){ + WST.msg('已存在相同的货号',{icon:2}); + obj.value = ''; + } +} +/**获取商品规格和属性**/ +function getSpecAttrs(goodsCatId){ + $('#specsAttrBox').empty(); + $('#specBtns').hide(); + specNum = 0; + $.post(WST.U('home/goods/getSpecAttrs'),{goodsCatId:goodsCatId,goodsType:$('#goodsType').val()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data){ + var html = [],tmp,str; + if(json.data.spec0 || json.data.spec1){ + html.push('<div class="spec-head">商品规格</div>'); + html.push('<div class="spec-body">'); + if(json.data.spec0){ + tmp = json.data.spec0; + html.push('<div id="specCat_'+tmp.catId+'">'+tmp.catName+'</div>'); + html.push('<table><tbody id="specTby"></tbody></table>'); + } + if(json.data.spec1){ + for(var i=0;i<json.data.spec1.length;i++){ + tmp = json.data.spec1[i]; + html.push('<div class="spec-line"></div>', + '<div id="specCat_'+tmp.catId+'">'+tmp.catName+'</div>', + '<div>', + '<input type="button" value="新增" id="specAddBtn_'+tmp.catId+'" onclick="javascript:addSpec({catId:'+tmp.catId+',checked:\'\'})"/>', + '</div>' + ); + } + } + html.push('</div>'); + html.push($('#specTips').html()); + html.push('<div id="specSaleHead" class="spec-head">销售规格</div>', + '<table class="specs-sale-table">', + ' <thead id="spec-sale-hed">', + ' <tr>', + ' <th>推荐<br/>规格</th>', + ' <th id="thCol"><font color="red">*</font>货号</th>', + ' <th><font color="red">*</font>市场价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'marketPrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>本店价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'specPrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>起批数<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'initNum\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>批发价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'whslePrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>库存<br/><input type="text" class="spec-sale-ipt" onblur="batchChange(this.value,\'specStock\')" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>预警库存<br/><input type="text" class="spec-sale-ipt" onblur="batchChange(this.value,\'warnStock\')" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th>销量</th>', + ' </tr>', + ' </thead>', + ' <tbody id="spec-sale-tby"></tbody></table>' + ); + } + if(json.data.attrs){ + html.push('<div class="spec-head">商品属性</div>'); + html.push('<div class="spec-body">'); + html.push('<table class="attr-table">'); + for(var i=0;i<json.data.attrs.length;i++){ + tmp = json.data.attrs[i]; + html.push('<tr><th width="120" nowrap>'+tmp.attrName+':</th><td>'); + if(tmp.attrType==1){ + str = tmp.attrVal.split(','); + for(var j=0;j<str.length;j++){ + html.push('<label><input type="checkbox" class="j-ipt" name="attr_'+tmp.attrId+'" value="'+str[j]+'"/>'+str[j]+'</label>'); + } + }else if(tmp.attrType==2){ + html.push('<select name="attr_'+tmp.attrId+'" id="attr_'+tmp.attrId+'" class="j-ipt">'); + html.push('<option value="0">请选择</option>'); + str = tmp.attrVal.split(','); + for(var j=0;j<str.length;j++){ + html.push('<option value="'+str[j]+'">'+str[j]+'</option>'); + } + html.push('</select>'); + }else{ + html.push('<input type="text" name="attr_'+tmp.attrId+'" id="attr_'+tmp.attrId+'" class="spec-sale-text j-ipt"/>'); + } + html.push('</td></tr>'); + } + html.push('</table>'); + html.push('</div>'); + } + $('#specsAttrBox').html(html.join('')); + //如果是编辑的话,第一次要设置之前设置的值 + if(OBJ.goodsId>0 && specNum==0){ + //设置规格值 + if(OBJ.spec0){ + for(var i=0;i<OBJ.spec0.length;i++){ + addSpecImg({catId:OBJ.spec0[i].catId,checked:'checked',val:OBJ.spec0[i].itemName,itemId:OBJ.spec0[i].itemId,specImg:OBJ.spec0[i].itemImg}); + } + } + if(OBJ.spec1){ + for(var i=0;i<OBJ.spec1.length;i++){ + addSpec({catId:OBJ.spec1[i].catId,checked:'checked',val:OBJ.spec1[i].itemName,itemId:OBJ.spec1[i].itemId}); + } + } + addSpecSaleCol(); + //设置商品属性值 + var tmp = null; + if(OBJ.attrs.length){ + for(var i=0;i<OBJ.attrs.length;i++){ + if(OBJ.attrs[i].attrType==1){ + tmp = OBJ.attrs[i].attrVal.split(','); + WST.setValue("attr_"+OBJ.attrs[i].attrId,tmp); + }else{ + WST.setValue("attr_"+OBJ.attrs[i].attrId,OBJ.attrs[i].attrVal); + } + } + } + + } + //给没有初始化的规格初始化一个输入框 + if(json.data.spec0 && !$('.j-speccat_'+json.data.spec0.catId)[0]){ + addSpecImg({catId:json.data.spec0.catId,checked:''}); + } + if(json.data.spec1){ + for(var i=0;i<json.data.spec1.length;i++){ + if(!$('.j-speccat_'+json.data.spec1[i].catId)[0])addSpec({catId:json.data.spec1[i].catId,checked:''}); + } + } + $('#specBtns').show(); + } + }); +} + +function changeGoodsType(v){ + if(v==0){ + $('#goodsStockTr').show(); + $('#goodsStock').removeAttr('disabled'); + }else{ + $('#goodsStockTr').hide(); + $('#goodsStock').prop('disabled',true); + } + var goodsCatId =WST.ITGetGoodsCatVal('j-goodsCats'); + getSpecAttrs(goodsCatId); +} +function toStock(id,src){ + location.href=WST.U('home/goodsvirtuals/stock','id='+id+"&src="+src); +} + +function saleByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/saleByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + saleByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function auditByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/auditByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + auditByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function storeByPage(p){ + $('#list1').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key1').val()); + params.page = p; + $.post(WST.U('home/goods/storeByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist1').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list1').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager1', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + storeByPage(e.curr); + } + } + }); + }else{ + $('#pager1').empty(); + } + } + }); +} +function illegalByPage(p){ + $('#list2').html('<tr><td colspan="4"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key2').val()); + params.page = p; + $.post(WST.U('home/goods/illegalByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist2').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list2').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager2', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + illegalByPage(e.curr); + } + } + }); + }else{ + $('#pager2').empty(); + } + } + }); +} +function limitPriceByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/limitPriceByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + auditByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function limitPriceGoods(){ + var params = WST.getParams('.ipt'); + //alert(JSON.stringify(params)); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/goods/limitPrice'),params,function(data){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status==1){ + var html = []; + var option1 = []; + for(i in json.data){ + if(i==0)option1 = json.data[i]; + html.push('<option value="'+json.data[i].goodsId+'" gt="'+json.data[i].goodsType+'">'+json.data[i].goodsName+'</option>'); + } + $('#goodsId').html(html.join('')); + }else{ + WST.msg("获取失败",{icon:2}); + } + }); +} +function changeGoods(){ + var goodsId=document.getElementById("goodsId").value; + $.post("getGoodsProduct",{goodsId:goodsId},function(data){ + $("#productNo").empty(); + if(data['specs']!=''){ + for(var i in data['specs']){ + $("#productNo").append("<option value='"+data['specs'][i].productNo+"'>"+data['specs'][i].productNo+"</option>"); + changeSpecs(); + } + }else{ + var html = []; + html.push('<option value="">无商品货号</option>'); + $('#productNo').html(html.join('')); + //$("#productNo").html('<option value=0>无商品货号</option>'); + document.getElementById('specs').value = ''; + } + + } + , "json") +} + +function changeSpecs(){ + var productNo=document.getElementById("productNo").value; + $.post("getGoodsSpecs",{productNo:productNo},function(data){ + document.getElementById('specs').value = data['itemName']; + }, "json") +} +//添加限时价格商品 +function addLimitGoods(id){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startTime', + type: 'datetime' + }); + laydate.render({ + elem: '#endTime', + type: 'datetime' + }); + $('#goodsForm').get(0).reset(); + $.post(WST.U('home/goods/getLimitGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + WST.setValues(json); + if(id>0){ + if(json.productNo!=""){ + $("#productNo").html("<option value='"+json.productNo+"'>"+json.productNo+"</option>"); + } + else{ + $("#productNo").html("<option value=''>无商品货号</option>"); + } + } + //alert(JSON.stringify(json.productNo)) + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#goodsBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#goodsBox').hide();},yes:function(){ + var params = WST.getParams('.j-ipt'); + //alert(JSON.stringify(params)); + if(params.goodsId==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + if(params.startTime==''){ + WST.msg('开始时间不能为空!', {icon: 5}); + return; + } + if(params.endTime==''){ + WST.msg('结束时间不能为空!', {icon: 5}); + return; + } + if(params.endTime<params.startTime){ + WST.msg('结束时间不能小于结束时间!', {icon: 5}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + params.id=id; + $.post(WST.U('home/goods/'+((id==0)?"addLimitGoods":"editLimitGoods")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + //alert(json) + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#goodsBox').hide(); + limitPriceByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + //$('#goodsForm').submit(); + }}); + }); +} +//删除限时价格商品 +function delLimitGoods(id){ + var c = WST.confirm({content:'您确定要删除商品吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goods/delLimitGoods'),{id:id},function(data){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg("删除成功",{icon:1}); + limitPriceByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function del(id,func){ + var c = WST.confirm({content:'您确定要删除商品吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goods/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + case 'illegal':illegalByPage(0);break; + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +// 批量 上架/下架 +function changeSale(i,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.isSale = i; + $.post(WST.U('home/goods/changeSale'), params, function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},(function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + })); + }else if(json.status=='-2'){ + WST.msg(json.msg, {icon: 5}); + }else if(json.status=='2'){ + WST.msg(json.msg, {icon: 5},function(){ + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else if(json.status=='-3'){ + WST.msg(json.msg, {icon: 5,time:3000}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +// 批量设置 精品/新品/推荐/热销 +function changeGoodsStatus(isWhat,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.is = isWhat; + $.post(WST.U('home/goods/changeGoodsStatus'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('设置成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('设置失败',{icon:5}); + } + }); +} +// 批量设置 店长推荐 +function changeStoreStatus(isWhat,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.is = isWhat; + $.post(WST.U('home/goods/changeStoreStatus'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('设置成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('设置失败',{icon:5}); + } + }); +} + +// 双击设置 +function changSaleStatus(isWhat, obj, id){ + var params = {}; + status = $(obj).attr('status'); + params.status = status; + params.id = id; + switch(isWhat){ + case 'r':params.is = "isRecom";break; + case 'b':params.is = "isBest";break; + case 'n':params.is = "isNew";break; + case 'h':params.is = "isHot";break; + case 's':params.is = "storeRecom";break; + } + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/changSaleStatus'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(status==0){ + $(obj).attr('status',1); + $(obj).removeClass('wrong').addClass('right'); + }else{ + $(obj).attr('status',0); + $(obj).removeClass('right').addClass('wrong'); + } + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} +// 双击修改店长推荐 +function changStoreRecom(isWhat, obj, id){ + var params = {}; + status = $(obj).attr('status'); + params.status = status; + params.id = id; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/changStoreRecom'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(status==0){ + $(obj).attr('status',1); + $(obj).removeClass('wrong').addClass('right'); + }else{ + $(obj).attr('status',0); + $(obj).removeClass('right').addClass('wrong'); + } + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} + + +//双击修改 +function toEditGoodsBase(fv,goodsId,flag){ + if((fv==2 || fv==3) && flag==1){ + WST.msg('该商品存在商品属性,不能直接修改,请进入编辑页修改', {icon: 5}); + return; + }else{ + $("#ipt_"+fv+"_"+goodsId).show(); + $("#span_"+fv+"_"+goodsId).hide(); + $("#ipt_"+fv+"_"+goodsId).focus(); + $("#ipt_"+fv+"_"+goodsId).val($("#span_"+fv+"_"+goodsId).html()); + } + +} +function endEditGoodsBase(fv,goodsId){ + $('#span_'+fv+'_'+goodsId).html($('#ipt_'+fv+'_'+goodsId).val()); + $('#span_'+fv+'_'+goodsId).show(); + $('#ipt_'+fv+'_'+goodsId).hide(); +} +function editGoodsBase(fv,goodsId){ + var vtext = $.trim($('#ipt_'+fv+'_'+goodsId).val()); + if(fv==2){ + if(vtext=='' || parseFloat(vtext,10)<=0){ + WST.msg('价格必须大于0', {icon: 5}); + return; + } + }else if(fv==3){ + if(vtext=='' || parseInt(vtext,10)<0 || vtext.indexOf('.')>-1){ + WST.msg('库存必须为正整数', {icon: 5}); + return; + } + } + var params = {}; + (fv==2)?params.shopPrice=vtext:params.goodsStock=vtext; + params.goodsId = goodsId; + $.post(WST.U('Home/Goods/editGoodsBase'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + $('#img_'+fv+'_'+goodsId).fadeTo("fast",100); + endEditGoodsBase(fv,goodsId); + $('#img_'+fv+'_'+goodsId).fadeTo("slow",0); + }else{ + WST.msg(json.msg, {icon: 5}); + } + }); +} + +function benchDel(func,flag){ + if(flag==1){ + var ids = WST.getChks('.chk1'); + }else{ + var ids = WST.getChks('.chk'); + } + + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/batchDel'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} + +function getCat(val){ + if(val==''){ + $('#cat2').html("<option value='' >-请选择-</option>"); + $('#cat3').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + //alert(JSON.stringify(data)) + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + $('#cat3').html(html.join('')); + }); +} +function resetForm(){ + location.reload(); +} + diff --git a/hyhproject/home/view/default/shops/goods/list_audit.html b/hyhproject/home/view/default/shops/goods/list_audit.html new file mode 100755 index 0000000..f990eac --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/list_audit.html @@ -0,0 +1,138 @@ +{extend name="default/shops/base" /} +{block name="title"}审核中的商品-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>审核中商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /> + <a class="s-btn" onclick="auditByPage()">查询</a> + </label> +</div> +<div class="wst-clear"></div> +<div class="wst-body"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'audit')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','audit')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','audit')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','audit')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','audit')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('audit')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + <div class="wst-clear"></div> + <table class='wst-list'> + <thead> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody style="margin-top:15px;" id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + + </td> + <td>{{d[i]['goodsSn']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"audit")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"audit")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"audit")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'audit')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','audit')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','audit')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','audit')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','audit')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('audit')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){auditByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/list_illegal.html b/hyhproject/home/view/default/shops/goods/list_illegal.html new file mode 100755 index 0000000..4a18da2 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/list_illegal.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}违规商品-会员中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>违规商品</span></div> +<div class="wst-shop-tbar"> +<label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> +</label> +<label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> +<label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" id="store-query" onclick="illegalByPage()">查询</a> +</label> +</div> +<div class="wst-clear"></div> +<form id='editform' autocomplete='off'> +<div class="wst-body"> + <table class='wst-list'> + <thead> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="benchDel('store',1)" class="s-del"><span>删除</span></a> + </div> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk1')" type='checkbox' id="all-1"/> + <label for="all-1"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th>违规原因</th> + <th width="150">操作</th> + </tr> + </thead> + <tbody id='list2'></tbody> + <tfoot> + <tr align="center"><td colspan='5' id='pager2'></td></tr> + </tfoot> + <script id="tblist2" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk1 wst-checkbox-s' id="chk-1-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-1-{{i}}"></label> + </div> + </td> + + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + <td>{{d[i]['illegalRemarks']}}</td> + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"illegal")'>[编辑]</a> + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"illegal")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +</form> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){illegalByPage(0)}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/list_limitprice.html b/hyhproject/home/view/default/shops/goods/list_limitprice.html new file mode 100755 index 0000000..70a50a1 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/list_limitprice.html @@ -0,0 +1,196 @@ +{extend name="default/shops/base" /} +{block name="title"}出售中的商品-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/layui/css/layui.css" /> +<!--<link rel="stylesheet" type="text/css" href="__STYLE__/css/common.css" />--> +<style> + body{ + color:#333;font:12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif + } +</style> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>限时价格商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="limitPriceByPage()">查询</a> + </label> + <label> + <a class="s-btn" onclick="addLimitGoods(0)">新增限时价格商品</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th width="180" >商品名称</th> + <th width="100" >商品编号</th> + <th width="40" >店铺价格</th> + <th width='40'>限时价格</th> + <th width="25" >销量</th> + <th width="25" >库存</th> + <th width="100" >开始时间</th> + <th width="100" >结束时间</th> + <th width="95">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + {{# if(d[i]['specPrice']!=null){ }} + <td>{{d[i]['specPrice']}}</td> + {{# }else{ }} + <td>{{d[i]['shopPrice']}}</td> + {{# } }} + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['limitPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['limitPrice']}}</span> + </td> + {{# } }} + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + + </td> + {{# } }} + <td>{{d[i]['startTime']}}</td> + <td>{{d[i]['endTime']}}</td> + <td> + <!--<a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a>--> + <a class="g-handle" href='javascript:addLimitGoods({{d[i]['id']}})'>[编辑价格]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"sale")'>[卡券]</a> + {{#}}} + <a class="g-handle" href="javascript:delLimitGoods({{d[i]['id']}})">[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> +</div> +<div id='goodsBox' style='display:none'> + <form id="goodsForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>商品分类<font color='red'>*</font>:</th> + <td > + <select name="cat1" id="cat1" onchange="getCat(this.value)" class=" ipt"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat3" id="cat3" class="ipt"><option value="">-请选择-</option></select> + <label style="height: 20px;"> + <a class="s-btn" onclick="limitPriceGoods()" style="height: 20px;line-height: 20px">查询</a> + </label> + </td> + </tr> + <tr> + <th width='150'>商品<font color='red'>*</font>:</th> + <td > + <select name="goodsId" id="goodsId" class="j-ipt" onchange='changeGoods()'> + <option value="">-请选择-</option> + {volist name="lists" id="vo"} + <option value="{$vo['goodsId']}">{$vo['goodsName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>商品货号:</th> + <td> + <select id='productNo' name="productNo" class='j-ipt' onchange='changeSpecs()'> + <option value="">请选择商品货号</option> + </select> + </td> + </tr> + <tr> + <th>商品规格:</th> + <td> + <input type="text" id="specs" value="" disabled="disabled" class="ipt"> + </td> + </tr> + <tr> + <th>商品限时价格<font color='red'>*</font>:</th> + <td> + <input type="text" id="limitPrice" value="" class="j-ipt"> + </td> + </tr> + <tr class="wst-order-rate" > + <th width='120'>有效时间<font color='red'>*</font>:</th> + <td colspan='3'> + <input type='text' id='startTime' name='startTime' class='j-ipt laydate-icon' value=''/> + 至 + <input type='text' id='endTime' name='endTime' class='j-ipt laydate-icon' value=''/> + </td> + </tr> + + </table> + </form> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> + $(function(){limitPriceByPage()}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/list_sale.html b/hyhproject/home/view/default/shops/goods/list_sale.html new file mode 100755 index 0000000..b71d8fc --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/list_sale.html @@ -0,0 +1,141 @@ +{extend name="default/shops/base" /} +{block name="title"}出售中的商品-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>出售中商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称/ID:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="saleByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'sale')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','sale')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','sale')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','sale')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','sale')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="changeStoreStatus('storeRecom','sale')" class="s-heart" style="width:70px"><span>店长推荐</span></a> + <a href='javascript:void(0);' onclick="benchDel('sale')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>店长推荐</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['storeStatus']}}" title='双击可修改' ondblclick='changStoreRecom("s",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['storeStatus']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"sale")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"sale")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'sale')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','sale')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','sale')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','sale')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','sale')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="changeStoreStatus('storeRecom','sale')" class="s-heart" style="width:70px"><span>店长推荐</span></a> + <a href='javascript:void(0);' onclick="benchDel('sale')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){saleByPage()}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goods/list_store.html b/hyhproject/home/view/default/shops/goods/list_store.html new file mode 100755 index 0000000..c5ce191 --- /dev/null +++ b/hyhproject/home/view/default/shops/goods/list_store.html @@ -0,0 +1,138 @@ +{extend name="default/shops/base" /} +{block name="title"}仓库中的商品-会员中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>仓库中的商品</span></div> +<div class="wst-shop-tbar"> +<label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> +</label> +<label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> +<label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" id="store-query" onclick="storeByPage()">查询</a> +</label> +</div> +<div class="wst-clear"></div> +<form id='editform' autocomplete='off'> +<div class="wst-body"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(1,'store')" class="s-sale-up"><span>上架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','store')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','store')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','store')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','store')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('store')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + + <table class='wst-list'> + <thead> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody id='list1'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager1'></td></tr> + </tfoot> + <script id="tblist1" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="display:none;width:100%;border:1px solid red;width:40px;padding:3px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="display:none;width:100%;border:1px solid red;width:40px;padding:3px;" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;color:green;">{{d[i]['goodsStock']}}</span> + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"store")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"store")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"store")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(1,'store')" class="s-sale-up"><span>上架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','store')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','store')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','store')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','store')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('store')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + </div> + </form> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){storeByPage(0);}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goodsappraises/goodsappraises.js b/hyhproject/home/view/default/shops/goodsappraises/goodsappraises.js new file mode 100755 index 0000000..e3f6ca5 --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsappraises/goodsappraises.js @@ -0,0 +1,94 @@ +/**获取本店分类**/ +function getShopsCats(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +function getCat(val){ + if(val==0){ + $('#cat2').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + }); +} +function showImg(id){ + layer.photos({ + photos: '#img-file-'+id + }); +} +function queryByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goodsappraises/queryByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + $('#list').empty(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + for(var g=0;g<=json.Rows.length;g++){ + showImg(g); + } + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} + +function reply(t,id){ + var params = {}; + if($('#reply-'+id).val()==''){ + WST.msg('回复内容不能为空',{icon:2}); + return false; + } + params.reply = $('#reply-'+id).val(); + params.id=id; + $.post(WST.U('home/goodsappraises/shopReply'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var today = new Date(); + today = today.toLocaleDateString(); + var html = '<p class="reply-content">'+params.reply+'【'+today+'】</p>' + $(t).parent().html(html); + } + }); +} diff --git a/hyhproject/home/view/default/shops/goodsappraises/list.html b/hyhproject/home/view/default/shops/goodsappraises/list.html new file mode 100755 index 0000000..e3b870b --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsappraises/list.html @@ -0,0 +1,107 @@ +{extend name="default/shops/base" /} +{block name="title"}评价列表-卖家中心{__block__}{/block} +{block name="content"} + +<div class="wst-shop-head"><span>评价列表</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="queryByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="400">商品</th> + <th>商品评分</th> + <th>服务评分</th> + <th>时效评分</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td rowspan="2">{{i+1}}</td> + <td rowspan="2"> + <div class="appra-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId'])}}"> + <img class='gImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="appra-goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + + + <td> + {{# for(var gs=0;gs<d[i]['goodsScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['serviceScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['timeScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + </tr> + <tr style="border-bottom:1px solid #ccc;"> + <td colspan='3'>评价[{{d[i]['loginName']}}]:{{d[i]['content']}} + + {{# if(WST.blank(d[i]['images'])!=''){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + <img src="__IMGURL__/{{img[g]}}/thumb80" layer-src="__IMGURL__/{{img[g]}}" width="30" height="30" /> + {{# } }} + </div> + {{# } }} + <div class="reply-box"> + {{# if(d[i]['shopReply']==null || d[i]['shopReply']=='') { }} + <textarea cols="65" rows="5" id="reply-{{d[i]['gaId']}}" ></textarea> + <a class="reply-btn s-btn" onclick="reply(this,{{d[i]['gaId']}})">回复</a> + {{# }else{ }} + <p class="reply-content">{{d[i]['shopReply']}}【{{d[i]['replyTime']}}】</p> + {{# } }} + + </div> + </td> + </tr> + + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goodsappraises/goodsappraises.js?v={$v}'></script> +<script> +$(function(){ + queryByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goodsconsult/goodsconsult.js b/hyhproject/home/view/default/shops/goodsconsult/goodsconsult.js new file mode 100755 index 0000000..70c65fe --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsconsult/goodsconsult.js @@ -0,0 +1,50 @@ +function queryByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/goodsconsult/pageQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + $('#list').empty(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} + +function reply(t,id){ + var params = {}; + if($('#reply-'+id).val()==''){ + WST.msg('回复内容不能为空',{icon:2}); + return false; + } + params.reply = $('#reply-'+id).val(); + params.id=id; + $.post(WST.U('home/goodsconsult/reply'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var today = new Date(); + var Myd = today.toLocaleDateString(); + var His = today.toLocaleTimeString(); + var html = '<p class="reply-content">'+params.reply+'【'+Myd+' '+His+'】</p>' + $(t).parent().html(html); + } + }); +} diff --git a/hyhproject/home/view/default/shops/goodsconsult/list.html b/hyhproject/home/view/default/shops/goodsconsult/list.html new file mode 100755 index 0000000..48b0ccd --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsconsult/list.html @@ -0,0 +1,85 @@ +{extend name="default/shops/base" /} +{block name="title"}商品咨询-卖家中心{__block__}{/block} +{block name="content"} +<style> +.c999{color:#999;} +.consult{margin-bottom: 15px;} +.consultImg,.consultImg a,.consultImg a img{width: 50px !important;height: 50px !important} +</style> +<div class="wst-shop-head"><span>商品咨询</span></div> +<div class="wst-shop-tbar"> + <label> + 咨询分类: + <select name="consultType" id="consultType" class="s-query"> + <option value="0">-请选择-</option> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <option value="{$vo['dataVal']}" >{$vo['dataName']}</option> + {/volist} + </select> + </label> + <label> + 关键词:<input type="text" id="consultKey" class="s-query" /><a class="s-btn" onclick="queryByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="300">商品</th> + <th>咨询内容</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td rowspan="2">{{i+1}}</td> + <td rowspan="2"> + <div class="appra-img consultImg"> + <a target='_blank' href="{{WST.U("home/goods/detail","id="+d[i]['goodsId'])}}"> + <img class='gImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="appra-goodsName" style="height:auto;"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + </tr> + <tr style="border-bottom:1px solid #ccc;"> + <td colspan='3'> + <p class='consult'> + [{{(WST.blank(d[i]['loginName'])=='')?'游客':d[i]['loginName']}}]:{{d[i]['consultContent']}} <span class="c999">({{d[i]['createTime']}})</span> + </p> + + <div class="reply-box"> + {{# if(d[i]['reply']==null || d[i]['reply']=='') { }} + <textarea style="width:98%;height:80px;" id="reply-{{d[i]['id']}}" placeholder='3~200个字符长度' maxlength='200'></textarea> + <a class="reply-btn s-btn" style="margin-left:3px;" onclick="reply(this,{{d[i]['id']}})">回复</a> + {{# }else{ }} + <p class="reply-content">{{d[i]['reply']}}【{{d[i]['replyTime']}}】</p> + {{# } }} + + </div> + </td> + </tr> + + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goodsconsult/goodsconsult.js?v={$v}'></script> +<script> +$(function(){ + queryByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goodsvirtuals/edit.html b/hyhproject/home/view/default/shops/goodsvirtuals/edit.html new file mode 100755 index 0000000..d2e1920 --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsvirtuals/edit.html @@ -0,0 +1,26 @@ +<style> + .s-btn{margin:0px;} +</style> +<form id='cardForm' autocomplete="off"> +<table class='wst-form'> + <tr> + <th>卡券号<font color='red'>*</font>:</th> + <td> + <input type='text' class='j-ipt' id='cardNo' maxLength='20' value='{$object["cardNo"]}' style='width:250px'/> + </td> + </tr> + <tr> + <th>卡券密码<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='cardPwd' maxLength='20' value='{$object["cardPwd"]}' style='width:250px'/></td> + </tr> + <tr> + <td colspan="2" style='text-align: center;padding-top: 15px;'> + <a class='s-btn' onclick="addCardFunc({$object['id']})">保存</a> + {if $object['id']==0} + <a class='s-btn' onclick="addCardFunc({$object['id']},1)" style='width:110px;'>继续新增</a> + {/if} + <a class='s-btn2' onclick="closeWin()">取消</a> + </td> + </tr> +</table> +</form> \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goodsvirtuals/list.html b/hyhproject/home/view/default/shops/goodsvirtuals/list.html new file mode 100755 index 0000000..fde6c0a --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsvirtuals/list.html @@ -0,0 +1,85 @@ +{extend name="default/shops/base" /} +{block name="title"}商品卡券-卖家中心{__block__}{/block} +{block name="content"} +<style> +.layui-layer-btn .layui-layer-btn0{background:#e45050;border-color:#e45050;} +.webuploader-container{width:80px;height:30px;overflow: hidden;float:right;margin:10px 5px 0px 5px;} +.webuploader-container .webuploader-pick{padding:5px 10px;} +</style> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<input type='hidden' id='vid' value='{$id}'/> +<div class="wst-shop-head"><span>商品卡券</span><a href="{:url('home/goods/'.$src)}">返回</a></div> +<div class="wst-shop-tbar"> + <label> + 状态:<select id='isUse' class="s-query"> + <option value='-1'>全部</option> + <option value='0'>未使用</option> + <option value='1'>已下单</option> + </select> + 卡券号:<input type="text" name="cardNo" id="cardNo" class="s-query" /> + <a class="s-btn" onclick="stockByPage()">查询</a> + <div id='importBtn' style='float:right;'>导入卡券</div> + <a style='float:right;height:30px;line-height:50px;' href='__STATIC__/template/goodsvirtuals.xls' target='_blank'>下载模板</a> + </label> +</div> +<div class="wst-shop-content"> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="delCard({$id},1)" class="s-del"><span>删除</span></a> + <a href='javascript:void(0);' onclick="editCard(0)" class="s-add"><span>新增</span></a> + </div> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.vchk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>卡券号</th> + <th>密码</th> + <th>状态</th> + <th>消费订单</th> + <th width="120">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='vchk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['id']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td>{{d[i]['cardNo']}}</td> + <td>{{d[i]['cardPwd']}}</td> + <td>{{getUseStatus(d[i]['isUse'])}}</td> + <td>{{WST.blank(d[i]['orderNo'],' - ')}}</td> + <td> + {{# if(d[i]['isUse']==0){ }} + <a class="g-handle" href='javascript:editCard({{d[i]['id']}})'>[编辑]</a> + {{# } }} + <a class="g-handle" href='javascript:delCard({{d[i]['id']}},0)'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="delCard({$id},1)" class="s-del"><span>删除</span></a> + <a href='javascript:void(0);' onclick="editCard({$id})" class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goodsvirtuals/virtuals.js?v={$v}'></script> +<script> +$(function(){stockByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/goodsvirtuals/virtuals.js b/hyhproject/home/view/default/shops/goodsvirtuals/virtuals.js new file mode 100755 index 0000000..1f8c2bb --- /dev/null +++ b/hyhproject/home/view/default/shops/goodsvirtuals/virtuals.js @@ -0,0 +1,127 @@ +function stockByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params.isUse = $.trim($('#isUse').val()); + params.cardNo = $.trim($('#cardNo').val()); + params.id = $.trim($('#vid').val()); + params.page = p; + $.post(WST.U('home/goodsvirtuals/stockByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + if(params.page>json.TotalPage && json.TotalPage >0){ + stockByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + stockByPage(e.curr); + } + } + }); + } + }); +} +function getUseStatus(v){ + switch(v){ + case 0:return '未使用'; + case 1:return '已下单'; + } +} +function closeWin(){ + layer.close(w); +} +function addCardFunc(id,isContinue){ + var params =WST.getParams('.j-ipt'); + params.id = id; + params.goodsId = $('#vid').val(); + if(params.cardNo=='' || params.cardPwd=='' || params.lastDate==''){ + WST.msg('请输入完整卡券信息',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/goodsvirtuals/'+((params.id==0)?"add":"edit")),params,function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + stockByPage(WSTCurrPage); + if(isContinue){ + $('#cardForm')[0].reset(); + }else{ + closeWin(); + } + WST.msg(json.msg, {icon: 1}); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); +} +var ll,w; +function editCard(id,goodsId){ + ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/goodsvirtuals/'+((id==0)?'toAdd':'toEdit')),{id:id},function(data){ + layer.close(ll); + w = WST.open({ + type: 1, + title:"新增卡券", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['400px', '180px'] + }); + }); +} + +function delCard(id,v){ + if(v==1){ + id = WST.getChks('.vchk'); + id = id.join(','); + } + var c = WST.confirm({content:'您确定要删除卡券吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goodsvirtuals/del'),{ids:id,id:$('#vid').val()},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + $('#all').prop('checked',false); + stockByPage(WSTCurrPage); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +var uploading = null; +$(function(){ + var uploader = WST.upload({ + server:WST.U('home/goodsvirtuals/importCards'),pick:'#importBtn', + formData: {dir:'temp',goodsId:$('#vid').val()}, + callback:function(f,file){ + layer.close(uploading); + uploader.removeFile(file); + var json = WST.toJson(f); + if(json.status==1){ + uploader.refresh(); + WST.msg('导入数据成功!已导入数据'+json.importNum+"条", {icon: 1}); + stockByPage(0); + }else{ + WST.msg('导入数据失败,出错原因:'+json.msg, {icon: 5}); + } + }, + progress:function(rate){ + uploading = WST.msg('正在导入数据,请稍后...'); + } + }); +}); diff --git a/hyhproject/home/view/default/shops/import.html b/hyhproject/home/view/default/shops/import.html new file mode 100755 index 0000000..4a1435f --- /dev/null +++ b/hyhproject/home/view/default/shops/import.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}数据导入 - 卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<div class="wst-body"> + <div class="wst-shop-head"><span>数据导入</span></div> + <table class="table table-hover table-striped table-bordered wst-form"> + <tr> + <td colspan='2' style='color:#707070;padding-left:25px;padding-top:5px;'> + <div class='wst-tips-box' style='margin-top:10px;'> + <div class='icon'></div> + <div class='tips' > + 1.请确保商品价格必须大于0,否则将自动默认为0.01。<br/> + 2.请确保商品库存不能为负数,否则将自动默认为0。<br/> + 3.请勿重复上传, 否则将造成重复商品数据。<br/> + 4.请保证导入的数据在Excel的第一个工作表(Sheet)。<br/> + 5.若Excel上某一行第一列为空则代表商品数据导入完毕。<br/> + 6.若没有数据模板,请点击<a href='__STATIC__/template/goods.xls' style='color:blue;' target='_blank'>下载Excel模板</a>。<br/> + 7.推荐使用谷歌浏览器或者火狐浏览器Firefox以获得更佳体验。<br/> + </div> + <div style="clear:both"></div> + </div> + </td> + </tr> + <tr> + <th align='right' width='90'>商品数据:</th> + <td> + <div id="filePicker" style='margin-left:0px;'>导入商品数据</div> + </td> + </tr> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> + var uploading = null; + $(function(){ + var uploader = WST.upload({ + server:"{:url('home/imports/importGoods')}",pick:'#filePicker', + formData: {dir:'temp'}, + callback:function(f,file){ + layer.close(uploading); + uploader.removeFile(file); + var json = WST.toJson(f); + if(json.status==1){ + uploader.refresh(); + WST.msg('导入数据成功!已导入数据'+json.importNum+"条", {icon: 1}); + }else{ + WST.msg('导入数据失败,出错原因:'+json.msg, {icon: 5}); + } + }, + progress:function(rate){ + uploading = WST.msg('正在导入数据,请稍后...'); + } + }); + }); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/index.html b/hyhproject/home/view/default/shops/index.html new file mode 100755 index 0000000..8b08e32 --- /dev/null +++ b/hyhproject/home/view/default/shops/index.html @@ -0,0 +1,295 @@ +{extend name="default/shops/base" /} +{block name="title"}卖家中心 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<style> +.wst-content{min-height:185px;} +</style> +{/block} +{block name="content"} +<div class='wst-shop-name'><a href='{:Url("home/shops/home","shopId=".$data["shop"]["shopId"])}'>{$data['shop']['shopName']}</a></div> +<div class="wst-shop-info"> + <span class="wst-shop-img"> + <a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"> + <img src="__IMGURL__/{:WSTImg($data['shop']['shopImg'])}" title="{$data['shop']['shopName']}" alt="{$data['shop']['shopName']}"> + </a> + </span> + <div class="wst-shop-na"> + <div class="wst-shop-na2"> + {volist name="$data['shop']['accreds']" id="sv"} + <img src="__IMGURL__/{$sv['accredImg']}" title='{$sv['accredName']}' alt='{$sv['accredName']}'> + {/volist} + </div> + <span class="wst-shop-na3">上次登录:{:session('WST_USER.lastTime')}</span> + <span class="wst-shop-na3">店铺地址:{:WSTMSubstr($data['shop']['shopAddress'],0,10)}</span> + </div> + <div class="wst-shop-eva"> + <p>商品评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['goodsScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['goodsScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-eva"> + <p>时效评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['timeScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['timeScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-eva"> + <p>服务评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['serviceScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['serviceScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-con"> + <p>电话:{$data['shop']['shopTel']}</p> + <p>QQ:{$data['shop']['shopQQ']}</p> + <p>服务时间:{php}echo date("H:i",strtotime($data['shop']['serviceStartTime']));{/php}-{php}echo date("H:i",strtotime($data['shop']['serviceEndTime']));{/php}</p> + </div> + <div class="wst-clear"></div> +</div> + + +<div class="main"> + <div class="main_middle"> + <ul class="main_mid_box"> + <li class="mid_l"> + <div class="mid_l_item"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">订单提示</span> + </div> + <div class="wst-rfloat"> + <span class="complain_num">{$data['stat']['complainNum']}</span> + <span class="c16_555">收到投诉信息</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="mid_main"> + <ul class="order_info"> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitReceiveCnt']}</p> + <span class="c14_555">待收货</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitDeliveryCnt']}</p> + <span class="c14_555">待发货</span> + </div> + </li> + <li> + <div class="item_center"> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['orderNeedpayCnt']}</p> + <span class="c14_555">待付款</span> + </div> + </div> + </li> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['cancel']}</p> + <span class="c14_555">取消/拒收</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['orderRefundCnt']}</p> + <span class="c14_555">待退款</span> + </div> + </li> + </ul> + </div> + </div> + + <div class="mid_l_item" style="margin-top:20px;"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商品信息</span> + </div> + </div> + <div class="wst-clear"></div> + <div class="mid_main"> + <ul class="order_info"> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['unSaleCnt']}</p> + <span class="c14_555">仓库中</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['stockWarnCnt']}</p> + <span class="c14_555">预警库存</span> + </div> + </li> + <li> + <div class="item_center item_sale"> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['onSaleCnt']}</p> + <span class="c14_555">出售中</span> + </div> + </div> + </li> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitAuditCnt']}</p> + <span class="c14_555">待审核</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['illegalCnt']}</p> + <span class="c14_555">违规商品</span> + </div> + </li> + </ul> + </div> + </div> + </li> + <li class="mid_c"> + <div class="index-right"> + <div class="index-right-item"> + <div class="main_title" style="padding-left:10px;"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">最近七天销售排行</span> + </div> + <div class="wst-clear"></div> + </div> + <ul class="right-list-tit"> + <li class="c12_555">序号</li> + <li class="c12_555">商品</li> + <li class="c12_555">数量</li> + </ul> + {volist name="$data['stat']['goodsTop']" id="glist" key="gkey" length="10"} + <ul class="right-list-tit right-list"> + <li class="c14_ff66"> + <div class="gTop{$gkey} top-num">{$gkey}</div> + </li> + <li class="wst-textover"><a class="c14_ff90" target="_blank" href="{:url('home/goods/detail',['id'=>$glist.goodsId])}">{:WSTMSubstr($glist.goodsName,0,15)}</a></li> + <li class="c14_ff66">{$glist.goodsNum?:0}</li> + </ul> + {/volist} + </div> + </div> + + </li> + <li class="mid_r"> + <div class="mid_r_rtop"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">平台联系方式</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="rtop_main"> + <p class="rtop_item">电话:{:WSTConf('CONF.serviceTel')}</p> + <p class="rtop_item">邮箱:{:WSTConf('CONF.serviceEmail')}</p> + </div> + </div> + <div class='mid_r_rbottom'> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商家公告</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="rbottom_main"> + <ul class="shop_tips"> + {wst:article cat="51" id="vo" num="10"} + <li class="wst-textover"><a href="{:url('home/news/view',['id'=>$vo['articleId']])}" target="_blank">{$vo.articleTitle}</a></li> + {/wst:article} + </ul> + </div> + <div style="margin-top: 130px;"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商家访问量</span> + </div> + <div class="wst-clear"></div> + </div> + </div> + <div class="rbottom_main"> + <ul class="shop_tips"> + {volist name="$data['shop']['view']" id="c"} + <p class="rtop_item" style="font-size: 15px;">{if $c['path']==1}PC端:{elseif $c['path']==2}APP端:{else}手机端:{/if}{$c['view']}</p> + {/volist} + </ul> + </div> + </div> + </li> + </ul> + </div> + + <div class="sale_info"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">近30天销售情况</span> + </div> + <div class="wst-clear"></div> + </div> + <div id="saleMain" style="width:100%;height:260px;"></div> + </div> +</div> + + +{/* 近30天 */} +<input type="hidden" id="startDate" class="ipt" value='{:date("Y-m-d",strtotime("-30 day"))}'/> +<input type="hidden" id="endDate" class="ipt" value='{:date("Y-m-d")}'/> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){saleCount()}); +// 销售统计 +function saleCount(){ + $.post(WST.U('home/reports/getStatSales'),WST.getParams('.ipt'),function(data,textStatus){ + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('saleMain')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + calculable : true, + xAxis : [ + { + type : 'category', + data : json.data.days + } + ], + yAxis : [ + { + type : 'value' + } + ], + series : [ + { + name:'销售额', + type:'line', + data:json.data.dayVals + } + ] + }; + myChart.setOption(option); + } + }); +} +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/logmoneys/list.html b/hyhproject/home/view/default/shops/logmoneys/list.html new file mode 100755 index 0000000..f5d1588 --- /dev/null +++ b/hyhproject/home/view/default/shops/logmoneys/list.html @@ -0,0 +1,70 @@ +{extend name="default/shops/base" /} +{block name="title"}资金流水-卖家中心{__block__}{/block} +{block name="content"} +<div class='money-head'> + <div class='shop-logo'><img height='100' width='100' src='__IMGURL__/{:session("WST_USER.shopImg")}'></div> + <div class='shop-info'> + <div class='shopName'>{:session('WST_USER.shopName')}</div> + <div class='shopMoney'> + 可用资金:<font color='red'>¥{$object['shopMoney']}</font> + 冻结资金:<font color='red'>¥{$object['lockMoney']}</font> + </div> + <div class="money-rows"> + <div class='shopMoney wst-lfloat'> + 应缴质保金:<font color='red'>¥{$object['deposit']['payDeposit']}</font> + 店铺质保金:<font color='red'>¥{$object['deposit']['cashDeposit']}</font> + 质保金:{if $object['deposit']['isFinish'] ==1} <font color='red'>已交齐</font>{else /}<font color='green'>未交齐</font>{/if} + </div> + </div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>资金流水</li> + <li>资金收入</li> + <li>资金支出</li> + <li>质保金流水</li> + </ul> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='150'>来源/用途</th> + <th width='100'>金额</th> + <th width='130'>日期</th> + <th width='100'>外部流水号</th> + <th width='*'>备注</th> + </tr> + </thead> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].dataSrc}}</td> + <td> + {{# if(d[i].moneyType==1){ }} + <span class="money-add">+ ¥{{ d[i].money }}</span> + {{# }else{ }} + <span class='money-reduce'> - ¥{{ d[i].money }}</span> + {{# } }} + </td> + <td>{{ d[i].createTime }}</td> + <td>{{ WST.blank(d[i].tradeNo,'-')}}</td> + <td style='line-height:23px'>{{ d[i].remark }}</td> + </tr> + {{# } }} + </script> + <tbody id="page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/logmoneys/logmoneys.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/logmoneys/logmoneys.js b/hyhproject/home/view/default/shops/logmoneys/logmoneys.js new file mode 100755 index 0000000..5be2a0a --- /dev/null +++ b/hyhproject/home/view/default/shops/logmoneys/logmoneys.js @@ -0,0 +1,77 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0,-1);break; + case 1:pageQuery(0,1);break; + case 2:pageQuery(0,0);break; + case 3:pageDeposit(0,2);break; + } + }}) +}); +function pageQuery(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + params.type = type; + $.post(WST.U('home/logmoneys/pageShopQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +//商家质保金流水 +function pageDeposit(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + // params.type = type; + $.post(WST.U('home/logmoneys/pageShopDeposit'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/messages/list.html b/hyhproject/home/view/default/shops/messages/list.html new file mode 100755 index 0000000..37a079b --- /dev/null +++ b/hyhproject/home/view/default/shops/messages/list.html @@ -0,0 +1,81 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>用户信息</span></div> +<div class="wst-clear"></div> + <div class='wst-shop-content' style='margin-top:0px;'> + <div class="s-menu"> + <a href="javascript:void(0)" onclick="batchRead()" style='margin-right:0px;float:none;width:60px;display:inline;'>标记为已读</a> | + <a href='javascript:void(0);' onclick="batchDel()" style='float:none;width:60px;display:inline;'>删除</a> + </div> + <div class='wst-page-content'> + <table class='wst-list'> + <thead> + <tr> + <th width='25'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th width='45'>状态</th> + <th>消息</th> + <th width='130'>时间</th> + <th width='100'>操作</th> + </tr> + </thead> + <script id="msg" type="text/html"> + {{# for(var i = 0, len = d.length; i < len; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{ d[i].id }}' /><label class='mt-1' for="chk-{{i}}"></label> + </div> + </td> + <td> + + {{# if(d[i].msgStatus ==1) { }} + <div class='readMsg'></div> + {{# }else{ }} + <div class='newMsg'></div> + {{# } }} + </td> + <td><div class="wst-hide msg-content">{{ d[i].msgContent }}</td> + <td>{{ d[i].createTime }}</td> + <td> + <a class="s-handle" href="javascript:showMsg({{ d[i].id }})">[查看]</a> + <a class="s-handle" href="javascript:delMsg(this,{{ d[i].id }})">[删除]</a> + &nbsp; + </td> + </tr> + {{# } }} + </script> + <tbody id="msg_box"> + + + + + + <tfoot> + <tr> + <td colspan='12' align='center'> + + <div id="wst-page" class='wst-page' style="padding-bottom:10px;"> + </div> + + </td> + </tr> + </tfoot> + </tbody> + </table> + + + + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/messages/message.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home/view/default/shops/messages/message.js b/hyhproject/home/view/default/shops/messages/message.js new file mode 100755 index 0000000..a141e41 --- /dev/null +++ b/hyhproject/home/view/default/shops/messages/message.js @@ -0,0 +1,106 @@ +$(function(){ + queryByList(); +}); +function queryByList(p){ + var params = {}; + params.page = p; + var load = WST.load({msg:'正在加载信息,请稍后...'}) + $.post(WST.U('Home/Messages/pageQuery'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.data){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + queryByList(json.TotalPage); + return; + } + var gettpl = document.getElementById('msg').innerHTML; + //复选框为未选中状态 + $('#all').attr('checked',false); + laytpl(gettpl).render(json.Rows, function(html){ + $('#msg_box').html(html); + }); + laypage({ + cont: 'wst-page', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByList(e.curr); + } + } + }); + + } + }); +} + +function showMsg(id){ + location.href=WST.U('home/messages/showShopMsg','msgId='+id); +} + +function delMsg(obj,id){ +WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var ll = WST.load('数据处理中,请稍候...'); + $.post(WST.U('Home/messages/del'),{id:id},function(data,textStatus){ + layer.close(ll); + layer.close(tips); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!', {icon: 1}, function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +}}); +} +function batchDel(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择要删除的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchDel'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} +function batchRead(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择处理的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要将这些消息标记为已读吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchRead'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} diff --git a/hyhproject/home/view/default/shops/messages/show.html b/hyhproject/home/view/default/shops/messages/show.html new file mode 100755 index 0000000..5c9cd20 --- /dev/null +++ b/hyhproject/home/view/default/shops/messages/show.html @@ -0,0 +1,25 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +<style> +.msgContent img{ + width: 100%; +} +</style> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>查看消息</span><a href="<?=url('home/Messages/shopMessage');?>">返回</a></div> +<div class="wst-clear"></div> + <div class="wst-body"> + <div class='wst-page-content'> + <div class='wst-tbar-group'> + + </div> + <div class="msgContent"> + {$data['msgContent']} + </div> + </div> + </div> +{/block} +{block name="js"} +{/block} diff --git a/hyhproject/home/view/default/shops/orders/box_refund.html b/hyhproject/home/view/default/shops/orders/box_refund.html new file mode 100755 index 0000000..70c5e29 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/box_refund.html @@ -0,0 +1,31 @@ +<table class='wst-form' style='margin-top:10px;width:90%'> + <tr> + <th width='120'>订单号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th width='120'>实付金额:</th> + <td>¥{$object['realTotalMoney']}</td> + </tr> + <tr> + <th width='120'>退款金额:</th> + <td style='color:red'>¥{$object['backMoney']}{if $object['ectNum']!=""}<font color='green'>≈{$object['ectNum']}ECT</font>{/if}</td> + </tr> + <tr> + <th width='120'>退款积分:</th> + <td style='color:red'>{$object['useScore']}个(积分抵扣¥{$object['scoreMoney']})</td> + </tr> + <tr> + <th width='120'>商家意见:</th> + <td> + <label><input type='radio' onclick='WST.showHide(0,"#tr")' name='refundStatus' id='refundStatus1' value='1' checked/>同意</label> + <label style='margin-left:15px;'><input type='radio' onclick='WST.showHide(1,"#tr")' name='refundStatus' id='refundStatus0' value='-1'/>不同意</label> + </td> + </tr> + <tr id='tr' style='display:none'> + <th width='120'>原因<font color='red'>*</font>:</th> + <td> + <textarea id='shopRejectReason' style='width:90%;height:50px;'></textarea> + </td> + </tr> +</table> \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/orders/complain_detail.html b/hyhproject/home/view/default/shops/orders/complain_detail.html new file mode 100755 index 0000000..3fc1c40 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/complain_detail.html @@ -0,0 +1,123 @@ +{extend name="default/shops/base" /} +{block name="title"}投诉详细 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>投诉详细</span></div> + + <div class='wst-shop-content'> + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>投诉信息</td> + </tr> + <tr> + <th width='80'>订单号:</th> + <td>{$data['orderNo']}</td> + </tr> + <tr> + <th>投诉类型:</th> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$data['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <th>投诉内容:</th> + <td class='line-break'>{$data['complainContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + + <td id="photos-complain"> + {volist name="$data['complainAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}?x-oss-process=image/resize,w_300,h_300" /> + </a> + {/volist} + </td> + + </tr> + <tr> + <th>投诉时间:</th> + <td>{$data['complainTime']}</td> + </tr> + </table> + + + {if condition="$data['needRespond'] eq 1 AND $data['respondContent'] neq ''"} + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>应诉信息</td> + </tr> + <tr> + <th width='80'>应诉内容:</th> + <td class='line-break'>{$data['respondContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + <td> + <div id="respondAnnex"> + {volist name="$data['respondAnnex']" id="annex2"} + <a href="javascript:void(0)"><img class='lazyImg' src="__IMGURL__/{$annex2}" layer-src="__IMGURL__/{$annex2}" height="100" width="100"/></a> + {/volist} + </div> + </td> + </tr> + <tr> + <th>应诉时间:</th> + <td>{$data['respondTime']}</td> + </tr> + </table> + {/if} + <table border='0' class='wst-complain-detail' style='margin-top:15px;'> + <tr> + <td colspan='2' class='head'>仲裁结果</td> + </tr> + <tr> + <th width='80'>仲裁结果:</th> + <td> + {if condition="$data['complainStatus'] eq 0"} + 等待处理 + {elseif condition="$data['complainStatus'] eq 1"/} + 等待应诉人回应 + {elseif condition="$data['complainStatus'] eq 2 OR $data['complainStatus'] eq 3"/} + 等待仲裁 + {elseif condition="$data['complainStatus'] eq 4"/} + 已仲裁 + {/if} + </td> + </tr> + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th valign='top'>仲裁结果:</th> + <td class='line-break'> + {$data['finalResult']} + </td> + </tr> + {/if} + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th>仲裁时间:</th> + <td>{$data['finalResultTime']}&nbsp;</td> + </tr> + {/if} + <tr> + <td colspan='2' style='text-align:center;'><a href="javascript:history.go(-1)" class="s-btn">返回</a></td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + // 调用图像层 + layer.photos({ + photos: '#photos-complain' + }); + layer.photos({ + photos: '#respondAnnex' + }); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_complain.html b/hyhproject/home/view/default/shops/orders/list_complain.html new file mode 100755 index 0000000..4a01b08 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_complain.html @@ -0,0 +1,71 @@ +{extend name="default/shops/base" /} +{block name="title"}查看投诉 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<style> +.wst-order-list tbody td{ + text-align: center; +} +.wst-order-list tbody tr{ + line-height: 30px; +} +</style> + <div class="wst-shop-head"><span>投诉订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-query" id='orderNo'/> + <a class="s-btn" onclick="complainByPage()">查询</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单编号</th> + <th>投诉方</th> + <th>投诉原因</th> + <th>投诉时间</th> + <th>投诉状态</th> + <th>操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + {{d[i]['orderNo']}} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </td> + + <td>{{WST.blank(d[i]['userName'],d[i]['loginName'])}}</td> + + <td title="{{d[i]['complainContent']}}">{{WST.cutStr(d[i]['complainContent'],50)}}</td> + + <td>{{d[i]['complainTime']}}</td> + + <td>{{d[i]['complainStatus']}}</td> + + <td> + <a style="cursor:pointer;" onclick="toView({{d[i]['complainId']}})">查看</a> + {{# if(d[i]['needReply']==1){ }}<a style="cursor:pointer;" onclick="toRespond({{d[i]['complainId']}})">应诉</a>{{# } }} + </td> + + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + complainByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_delivered.html b/hyhproject/home/view/default/shops/orders/list_delivered.html new file mode 100755 index 0000000..f103bc4 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_delivered.html @@ -0,0 +1,161 @@ +{extend name="default/shops/base" /} +{block name="title"}已发货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>已发货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="deliveredByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,1,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].payType==1){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}} + </span> + {{# } }} + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum >0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice >0){ }} + <span class="order_je">ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div>{{d[i].status}} </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + <div><a href='#none' onclick='javascript:updateDeliver({{d[i].orderId}})'>【修改运单号】</a></div> + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='deliverBox' style='display:none'> + <form id='deliverForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>快递公司:</th> + <td> + <select id='expressId'> + <option value=''>请选择</option> + {volist name="$express" id='vo'} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>快递号:</th> + <td><input type='text' id='expressNo' name="expressNo" maxLength='20' style='width:80%'></td> + </tr> + </table> + </form> + </div> + + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + deliveredByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_failure.html b/hyhproject/home/view/default/shops/orders/list_failure.html new file mode 100755 index 0000000..f53f9cb --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_failure.html @@ -0,0 +1,135 @@ +{extend name="default/shops/base" /} +{block name="title"}取消/拒收订单 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>取消/拒收订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="failureByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,10000,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].payType==1){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div>{{d[i].status}}</div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:{{d[i].goodsMoney}}</div> + <div class='line'>运费:{{d[i].deliverMoney}}</div> + <div>实付金额:{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{# if(WST.blank(d[i].refundId)!=''){ }} + <div><a href='javascript:void(0)' onclick='refund({{d[i].refundId}})'>【退款操作】</a></div> + {{# } }} + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + </tbody> + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='failureBox' style='display:none'> + <form id='failureForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>不同意原因:</th> + <td> + <textarea id='content' style='width:90%;height:100px;' maxLength='200'></textarea> + </td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){failureByPage();}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_finished.html b/hyhproject/home/view/default/shops/orders/list_finished.html new file mode 100755 index 0000000..e00ff3f --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_finished.html @@ -0,0 +1,144 @@ +{extend name="default/shops/base" /} +{block name="title"}已收货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>已收货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="finisedByPage()">查询</a> + <a class="s-btn" style='margin-top:0px;line-height:15px;height:16px;float: right;' onclick="javascript:toExport(2,2,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].isAppraise==0){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from"> + {{d[i].orderCodeTitle}} + </span> + {{# } }} + + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum >0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice >0){ }} + <span class="order_je">ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div>{{d[i].status}}</div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].isAppraise==1){}} + <div style="text-align:center;">已评价</div> + {{#}else{}} + <div style="text-align:center;">未评价</div> + {{#}}} + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + </tbody> + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + finisedByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_wait_delivery.html b/hyhproject/home/view/default/shops/orders/list_wait_delivery.html new file mode 100755 index 0000000..86d8e3f --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_wait_delivery.html @@ -0,0 +1,202 @@ +{extend name="default/shops/base" /} +{block name="title"}待发货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> +.notice{padding: 3px 6px;color: #e55454} +.notice_icon{vertical-align: text-bottom;} + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>待发货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="waitDivleryByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,0,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'> + 订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].noticeDeliver==1){ }} + <span class="notice"> + <img class="notice_icon" src="__STYLE__/img/nocite_deliver.png" alt="发货提醒" width="20" height="20" /> + 尽快发货 + </span> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}} + </span> + {{# } }} + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum > 0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice > 0){ }} + <span class="order_je">下单ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div> + {{d[i].status}} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + + <tr class='goods-box'> + <td> + + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + <div><a href='#none' onclick='javascript:deliver({{d[i].orderId}},{{d[i].deliverType}})'>【发货】</a></div> + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【用户留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='deliverBox' style='display:none'> + <form id='deliverForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>快递公司:</th> + <td> + <select id='expressId'> + <option value=''>请选择</option> + {volist name="$express" id='vo'} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>快递号:</th> + <td><input type='text' id='expressNo' maxLength='20' style='width:80%'></td> + </tr> + </table> + </form> + </div> + <div id='editMoneyBox' style='display:none'> + <form id='newOrderForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='120'>订单号:</th> + <td><span id='m_orderNo'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_goodsMoney'></span></td> + </tr> + <tr> + <th>运费:</th> + <td>¥<span id='m_deliverMoney'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_totalMoney'></span></td> + </tr> + <tr> + <th>实际支付价格:</th> + <td>¥<span id='m_realTotalMoney' class='j-warn-order-money'></span></td> + </tr> + <tr> + <th>新价格:</th> + <td><input type='text' id='m_newOrderMoney' maxLength='10' style='width:150px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'></td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waitDivleryByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/list_wait_pay.html b/hyhproject/home/view/default/shops/orders/list_wait_pay.html new file mode 100755 index 0000000..2719e29 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/list_wait_pay.html @@ -0,0 +1,167 @@ +{extend name="default/shops/base" /} +{block name="title"}待付款订单 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>待付款订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="waituserPayByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,-2,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div> + {{#if(d[i].payType==1){}} + {{# if(d[i].isPay==1){}}已支付 + {{# }else{ }} + 等待支付 + {{# } }} + {{#}else{}} + 等待发货 + {{#} }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].payType==1 && d[i].isPay==0){}} + <div><a href='#none' onclick='editOrderMoney({{d[i].orderId}})'>【修改价格】</a></div> + {{#}}} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <tr> + <td colspan="4"> + <p class="order_remaker">【用户留言】{{d[i].orderRemarks}}</p> + </td> + </tr> + {{# } }} + + + </tbody> + + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='editMoneyBox' style='display:none'> + <form id='newOrderForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='120'>订单号:</th> + <td><span id='m_orderNo'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_goodsMoney'></span></td> + </tr> + <tr> + <th>运费:</th> + <td>¥<span id='m_deliverMoney'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_totalMoney'></span></td> + </tr> + <tr> + <th>实际支付价格:</th> + <td>¥<span id='m_realTotalMoney' class='j-warn-order-money'></span></td> + </tr> + <tr> + <th>新价格:</th> + <td><input type='text' id='m_newOrderMoney' maxLength='10' style='width:150px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'></td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waituserPayByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/orders/orders.js b/hyhproject/home/view/default/shops/orders/orders.js new file mode 100755 index 0000000..af5d461 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/orders.js @@ -0,0 +1,423 @@ +function waituserPayByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waituserPayByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waituserPayByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waituserPayByPage(e.curr); + } + } + }); + } + }); +} +function waitDivleryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waitDeliveryByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitDivleryByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waitDivleryByPage(e.curr); + } + } + }); + } + }); +} +function deliveredByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/deliveredByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitDivleryByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + deliveredByPage(e.curr); + } + } + }); + } + }); +} +function editOrderMoney(id){ + var ll = WST.load({msg:'正在加载记录,请稍候...'}); + $.post(WST.U('home/orders/getMoneyByOrder'),{id:id},function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status>0 && json.data){ + var tmp = json.data; + $('#m_orderNo').html(tmp.orderNo); + $('#m_goodsMoney').html(tmp.goodsMoney); + $('#m_deliverMoney').html(tmp.deliverMoney); + $('#m_totalMoney').html(tmp.totalMoney); + $('#m_realTotalMoney').html(tmp.realTotalMoney); + WST.open({type: 1,title:"修改订单价格",shade: [0.6, '#000'],border: [0], + content: $('#editMoneyBox'),area: ['550px', '320px'],btn: ['确定','取消'], + yes:function(index, layero){ + var newOrderMoney = $('#m_newOrderMoney').val(); + WST.confirm({content:'您确定修改后的订单价格为¥<span class="j-warn-order-money">'+newOrderMoney+'</span>吗?',yes:function(cf){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/editOrderMoney'),{id:id,orderMoney:newOrderMoney},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#newOrderMoney').val(); + WST.msg(json.msg,{icon:1}); + waituserPayByPage(WSTCurrPage); + layer.close(cf); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + } + }); + } + }); +} +function deliver(id,deliverType){ + if(deliverType==1){ + WST.confirm({content:"您确定用户已提货了吗?", yes:function(tips){ + var ll = WST.load('数据处理中,请稍候...'); + $.post(WST.U('home/orders/deliver'),{id:id,expressId:0,expressNo:''},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(tips); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + }else{ + WST.open({type: 1,title:"请输入发货快递信息",shade: [0.6, '#000'], border: [0], + content: $('#deliverBox'),area: ['350px', '180px'],btn: ['确定发货','取消'], + yes:function(index, layero){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/deliver'),{id:id,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#deliverForm')[0].reset(); + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + } +} + +function updateDeliver(orderId){ + WST.open({type: 1,title:"请输入修改快递信息",shade: [0.6, '#000'], border: [0], + content: $('#deliverBox'),area: ['350px', '180px'],btn: ['确定修改','取消'], + yes:function(index, layero){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/updateDeliver'),{orderId:orderId,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#deliverForm')[0].reset(); + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +function finisedByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/finishedByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + $('.order_remaker').remove(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + finisedByPage(e.curr); + } + } + }); + } + }); +} +function failureByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/failureByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + $('.order_remaker').remove(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + failureByPage(e.curr); + } + } + }); + } + }); +} +function refund(id){ + var ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/orders/toShopRefund'),{id:id},function(data){ + layer.close(ll); + var w = WST.open({ + type: 1, + title:"退款操作", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['500px', '320px'], + btn: ['提交', '关闭窗口'], + yes: function(index, layero){ + var params = {}; + params.refundStatus = $('#refundStatus1')[0].checked?1:-1; + params.content = $.trim($('#shopRejectReason').val()); + params.id = id; + if(params.refundStatus==-1 && params.content==''){ + WST.msg('请输入不同意原因',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/orderrefunds/shoprefund'),params,function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + layer.close(w); + failureByPage(WSTCurrPage); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + }); +} +function view(id){ + location.href=WST.U('home/orders/view','id='+id); +} + + +/********** 订单投诉列表 ***********/ +function toView(id){ + location.href=WST.U('home/ordercomplains/getShopComplainDetail',{'id':id}); +} +function toRespond(id){ + location.href=WST.U('home/ordercomplains/respond',{'id':id}); +} + +function complainByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/ordercomplains/queryShopComplainByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data){ + var json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + complainByPage(e.curr); + } + } + }); + } + }); +} + + +/************ 应诉页面 ************/ +function respondInit(){ +$('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + // 调用图像层 + layer.photos({ + photos: '#photos-complain' + }); + + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'complains',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='respond_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#picBox').append(tdiv); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +function saveRespond(historyURL){ + $('#respondForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var img = []; + $('.respond_pic').each(function(){ + img.push($(this).attr('v')); + }); + params.respondAnnex = img.join(','); + $.post(WST.U('home/orderComplains/saveRespond'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('您的应诉已提交,请留意信息回复', {icon: 6},function(){ + location.href = WST.U('home/ordercomplains/shopComplain'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +//导出订单 +function toExport(typeId,status,type){ + var params = {}; + params = WST.getParams('.s-ipt'); + params.typeId = typeId; + params.orderStatus = status; + params.type = type; + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('home/orders/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/orders/print.html b/hyhproject/home/view/default/shops/orders/print.html new file mode 100755 index 0000000..bdbbb65 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/print.html @@ -0,0 +1,110 @@ +<!doctype html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>订单打印 - {:WSTConf('CONF.mallName')}</title> +</head> +<style> +body{font-size:13px;} +td,th{padding:2px;} +</style> +<body> +<table width='100%' border='0'> + <tr> + <td colspan='8' style='text-align:center;font-weight:bold;font-size:26px'>订单信息</td> + </tr> + <tr> + <td width='100' align="right">下单时间:</td> + <td width='250'>{$object['createTime']}</td> + <td width='100' align="right">支付方式:</td> + <td width='250'>{:WSTLangPayType($object['payType'])}</td> + <td width='100' align="right">订单编号:</td> + <td width='250'>{$object['orderNo']}</td> + </tr> + <tr> + <td width='100' align="right">发货时间:</td> + <td>{$object['deliveryTime']}</td> + <td width='100' align="right">配送方式:</td> + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + <td width='100' align="right">快递单号:</td> + <td>{$object['expressNo']}</td> + </tr> + {if $object['invoiceClient'] !=''} + <tr> + <td width='100' align="right">发票抬头:</td> + <td colspan="6">{$object['invoiceClient']}</td> + </tr> + {/if} + {if ($object['orderType']==0)} + <tr> + <td width='100' align="right">收货地址:</td> + <td colspan="6">{$object['userName']}&nbsp;|&nbsp;{$object['userPhone']}&nbsp;|&nbsp;{$object['userAddress']}</td> + </tr> + {/if} + {if $object['orderRemarks']!=''} + <tr> + <td width='100' align="right">订单备注:</td> + <td colspan="6">{$object['orderRemarks']}</td> + </tr> + {/if} +</table> +<table width='100%' border='1' style='border-collapse:collapse;border-color:#000;'> + <tr style='background:#cccccc;'> + <th align="left">商品名称</th> + <th align="left">商品规格</th> + <th align="left" align="left">商品价格</th> + <th align="left">商品数量</th> + <th align="left">小计</th> + </tr> + {volist name='$object["goods"]' id='vo2'} + <tr> + <td>{$vo2["goodsName"]}</td> + <td> + {if $vo2['goodsType']==1 && $object['orderStatus']==2} + <table width='100%'> + {volist name='$vo2["extraJson"]' id='vgcard'} + <tr> + <td>卡券号:{$vgcard['cardNo']}</td> + <td>卡券密码:{$vgcard['cardPwd']}</td> + </tr> + {/volist} + </table> + {else} + {:str_replace('@@_@@',';',$vo2["goodsSpecNames"])}&nbsp; + {/if} + </td> + <td>¥{$vo2['goodsPrice']}</td> + <td>{$vo2['goodsNum']}</td> + <td>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</td> + </tr> + {/volist} + </table> + <table width='100%' border='0'> + <tr> + <td colspan='6' align="right">商品总金额:¥{$object['goodsMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">运费:¥{$object['deliverMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">应付金额:¥{$object['totalMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">积分抵扣金额:¥-{$object['scoreMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">实付金额:¥{$object['realTotalMoney']}</td> + </tr> +</table> +<br/> +<table width='100%'> + <tr> + <td>商家:{$object['shopName']}&nbsp;&nbsp;&nbsp;电话:{$object['shopTel']}</td> + <td align="right">打印时间:{:date('Y-m-d H:i:s')}</td> + </tr> +</table> +</body> +<script> +window.print(); +</script> +</html> diff --git a/hyhproject/home/view/default/shops/orders/respond.html b/hyhproject/home/view/default/shops/orders/respond.html new file mode 100755 index 0000000..f451889 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/respond.html @@ -0,0 +1,113 @@ +{extend name="default/shops/base" /} +{block name="title"}应诉 - 卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<style> +.webuploader-pick { + background: #f7375c; + height:30px; +} +</style> + <div class="wst-shop-head"><span>应诉</span></div> + + <div class='wst-shop-content'> + <form id="respondForm" method="post" > + <div style='width:990px;overflow:hidden;'> + <input type='hidden' id='complainId' class='ipt' value="{$data['complainId']}"/> + <div class='wst-complain-left'> + <div class='wst-complain-order-head'>订单商品</div> + <div class='wst-complain-order-goods'> + {volist name="$data['goodsList']" id="goods" key='key2'} + <a target='_blank' href="{:Url('Home/Goods/Detail',array('id'=>$goods['goodsId']))}" title="{$goods['goodsName']}"> + <img data-original="__IMGURL__/{$goods['goodsImg']}" height="55" width="55" class='gImg'/> + </a> + {/volist} + </div> + <div class='wst-complain-order-head'>订单信息</div> + <div class='wst-complain-order-info'> + <dl> + <dt>订单编号:</dt> + <dd>{$data['orderNo']}</dd> + <dt>订单金额:</dt> + <dd>¥{$data['realTotalMoney']}</dd> + <dt>运&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;费:</dt> + <dd>¥{$data['deliverMoney']}</dd> + <dt>下单时间:</dt> + <dd>{$data['createTime']}</dd> + <dt>商&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;家:</dt> + <dd>{$data['shopName']}</dd> + </dl> + </div> + </div> + <div class='wst-complain-main'> + <div class='wst-complain-order-head' style='width:735px;'>投诉信息</div> + <div class='wst-complain-box'> + <table width='100%'> + <tr> + <td width='70' align='right'>投诉类型:</td> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$data['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <td align='right'>详情:</td> + <td class='line-break'>{$data['complainContent']}</td> + </tr> + <tr> + <td align='right'>附件:</td> + <td> + <div id="photos-complain"> + {if !empty($data['complainAnnex'])} + {volist name="$data['complainAnnex']" id="annex"} + <img class='lazyImg' layer-src="__IMGURL__/{$annex}" data-original="__IMGURL__/{$annex}" src="__IMGURL__/{$annex}" height="100" width="100"/> + {/volist} + {/if} + </div> + </td> + </tr> + </table> + </div> + <div class='wst-complain-order-head' style='width:735px;'>应诉信息</div> + <div class='wst-complain-box'> + <table width='100%'> + <tr> + <td> + <textarea id='respondContent' name="respondContent" class='ipt' autocomplete="off" style='width:700px;height:162px;' placeholder='请输入应诉内容' data-rule='应诉内容:required;' data-target='#msg_respondContent'></textarea><br/> + <div class='msg-box' id='msg_respondContent'></div> + </td> + </tr> + <tr> + <td> + <div id="filePicker" style='margin-left:0px;overflow:hidden;height:25px;magin-left:5px;'>上传附件(最多5张)</div> + </td> + </tr> + <tr> + <td> + <div id='picBox' style='height:120px;width:710px;padding:5px;'> + </td> + </tr> + </table> + </div> + </div> + <div class='wst-complain-footer'> + <a href="javascript:saveRespond()" class="s-btn">提交</a> + <a href="javascript:location.href='{:url('home/ordercomplains/shopComplain')}'" class="s-btn">返回</a> + </div> + </div> + </form> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){ + respondInit(); +}) +</script> +{/block} diff --git a/hyhproject/home/view/default/shops/orders/view.html b/hyhproject/home/view/default/shops/orders/view.html new file mode 100755 index 0000000..4e35530 --- /dev/null +++ b/hyhproject/home/view/default/shops/orders/view.html @@ -0,0 +1,247 @@ +{extend name="default/shops/base" /} +{block name="title"}订单详情 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>订单详情</span><a href="javascript:history.go(-1)">返回</a></div> +<div class='wst-shop-content'> + <div class='order-box'> + <div class='box-head'>日志信息</div> + {if in_array($object['orderStatus'],[-2,0,1,2])} + <div class='log-box'> +<div class="state"> +{if $object['payType']==1} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{else} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">················></div> +{/if} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==0)"}icon43 {/if}"></span></div> +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> +</div> + <div class="state2"> + <div class="path"> + {volist name="$object['log']" id="lo"} + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + {/volist} + </div> + <p>下单</p>{if $object['payType']==1}<p>等待支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + </div> + <div class="wst-clear"></div> + </div> + {else} + <div> + <table class='log'> + {volist name='$object["log"]' id='vo'} + <tr> + <td>{$vo['logTime']}</td> + <td>{$vo['logContent']}</td> + </tr> + {/volist} + </table> + </div> + {/if} + </div> + <!-- 订单信息 --> + <div class='order-box'> + <div class='box-head'>订单信息</div> + <table class='wst-form'> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>支付方式:</th> + <td>{:WSTLangPayType($object['payType'])}</td> + </tr> + {if($object['payType']==1 && $object['isPay']==1)} + <tr> + <th>支付时间:</th> + <td>{$object['payTime']}</td> + </tr> + <tr> + <th>支付信息:</th> + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + </tr> + {/if} + <tr> + <th>配送方式:</th> + <td> + {:WSTLangDeliverType($object['deliverType'])} + </td> + </tr> + {if $object['expressNo']!=''} + <tr> + <th>快递公司:</th> + <td>{$object['expressName']}</td> + </tr> + <tr> + <th>快递号:</th> + <td>{$object['expressNo']}</td> + </tr> + {/if} + <tr> + <th>买家留言:</th> + <td>{$object['orderRemarks']}</td> + </tr> + </table> + </div> + {:hook('homeDocumentOrderView',['orderId'=>$object['orderId']])} + + {if $object['isRefund']==1} + <!-- 退款信息 --> + <div class='order-box'> + <div class='box-head'>退款信息</div> + <table class='wst-form'> + <tr> + <th width='100'>退款金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th width='100'>退款备注:</th> + <td>{$object['refundRemark']}</td> + </tr> + <tr> + <th>退款时间:</th> + <td>{$object['refundTime']}</td> + </tr> + </table> + </div> + {/if} + <!-- 发票信息 --> + <div class='order-box'> + <div class='box-head'>发票信息</div> + <table class='wst-form'> + <tr> + <th width='100'>是否需要发票:</th> + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + </tr> + {if $object['isInvoice']==1} + {php}$invoiceArr = json_decode($object['invoiceJson'],true);{/php} + <tr> + <th>发票抬头:</th> + <td> + {if $object['isInvoice']==1} + {$invoiceArr['invoiceHead']} + {/if} + </td> + </tr> + {if isset($invoiceArr['invoiceCode'])} + <tr> + <th>发票税号:</th> + <td> + {$invoiceArr['invoiceCode']} + </td> + </tr> + {/if} + {/if} + </table> + </div> + <!-- 收货人信息 --> + {if ($object['orderType']==0)} + <div class='order-box'> + <div class='box-head'>收货人信息</div> + <table class='wst-form'> + <tr> + <th width='100'>收货人:</th> + <td>{$object['userName']}</td> + </tr> + <tr> + <th>收货地址:</th> + <td>{$object['userAddress']}</td> + </tr> + <tr> + <th>联系方式:</th> + <td>{$object['userPhone']}</td> + </tr> + </table> + </div> + {/if} + <!-- 商品信息 --> + <div class='order-box'> + <div class='box-head'>商品清单</div> + <div class='goods-head'> + <div class='goods'>商品</div> + <div class='number'>商品编号</div> + <div class='price'>单价</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + </div> + <div class='goods-item'> + <div class='shop'> + {$object['shopName']} + {if $object['shopQQ'] !=''} + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style='vertical-align:middle;' src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $object['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" style='vertical-align:middle;' src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + <div class='goods-list'> + {volist name='$object["goods"]' id='vo2'} + {:hook('homeDocumentOrderViewGoodsPromotion',['goods'=>$vo2])} + <div class='item j-g{$vo2['goodsId']}'> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{if $vo2['goodsCode']=='gift'}【赠品】{/if}{$vo2["goodsName"]}</div> + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + </div> + <div class="number">{$vo2['goodsSn']}</div> + <div class='price'>¥{$vo2['goodsPrice']}</div> + <div class='num'>{$vo2['goodsNum']}</div> + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + <div class='wst-clear'></div> + </div> + {if $vo2['goodsType']==1 && $object['orderStatus']==2} + <table width='100%' style='margin-top:5px;'> + {volist name='$vo2["extraJson"]' id='vgcard'} + <tr> + <td>卡券号:{$vgcard['cardNo']}</td> + <td>卡券密码:{$vgcard['cardPwd']}</td> + </tr> + {/volist} + </table> + {/if} + {/volist} + </div> + </div> + <div class='goods-footer'> + <div class='goods-summary' style='text-align:right'> + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + <div class='summary line'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + <div class='summary'>积分抵扣金额:¥-<span>{$object['scoreMoney']}</span></div> + {if condition="$object['useScore'] gt 0"} + <div class='summary '>使用积分数:<span>{$object['useScore']}个</span></div> + {/if} + {:hook('homeDocumentOrderSummaryView',['order'=>$object])} + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home/view/default/shops/recharge/pay_step1.html b/hyhproject/home/view/default/shops/recharge/pay_step1.html new file mode 100755 index 0000000..3276e07 --- /dev/null +++ b/hyhproject/home/view/default/shops/recharge/pay_step1.html @@ -0,0 +1,72 @@ +{extend name="default/shops/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>充值</span></div> +<div class='wst-shop-content'> + <div class='pay-sbox'> + <div> + <div> + <div class='wst-tips-box'> + <div class='icon'></div> + <div class='tips'> + 1.充值金额和赠送金额只能用于购买商品,不能提现;<br/> + </div> + <div style="clear:both"></div> + </div> + </div> + <div class="wst-form"> + <div class="pay-type">充值金额 + <div> + <div class="wst-list-box"> + {volist name="chargeItems" id="item"} + <div class="wst-frame2 {$key} " onclick="javascript:changeSelected({$item['id']},'itmeId',this)"> + {if condition="$item['giveMoney'] gt 0"} + <div class='charge-doub'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + <div>送 {$item['giveMoney']} 元</div> + {else/} + <div class='charge-alone'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + {/if} + <i></i> + </div> + {/volist} + <div class="wst-frame2 " onclick="javascript:changeSelected(0,'itmeId',this)"> + <div class='charge-alone'> + <span class="j-charge-other">其他金额</span> + <span class="j-charge-money"><input class="charge-othermoney j-ipt" id="needPay" value="1" maxlength="10" data-rule="充值金额:required;" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)" maxlength="8"></span> + </div> + <i></i> + </div> + <input type="hidden" value="" id='itmeId' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + + </div> + </div> + </div><div></div> + <div> + + <div class="pay-type">选择支付方式</div> + <div class="pay-list"> + <input type="hidden" id="payCode" name="payCode" /> + {volist name="payments" id="payment"} + {if condition="$payment['isOnline'] eq 1"} + <div class="wst-payCode-{$payment['payCode']}" data="{$payment['payCode']}"></div> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + <div class="bnt-box"> + <div onclick='javascript:getPayUrl();' class="wst-pay-bnt"></div> + </div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/recharge/recharge.js?v={$v}'></script> +{/block} + diff --git a/hyhproject/home/view/default/shops/recharge/pay_step2.html b/hyhproject/home/view/default/shops/recharge/pay_step2.html new file mode 100755 index 0000000..4dd0c23 --- /dev/null +++ b/hyhproject/home/view/default/shops/recharge/pay_step2.html @@ -0,0 +1,53 @@ + +{extend name="default/shops/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='wst-user-content'> + + <div class="pay-sbox-head"> + <div class="wst-shop-head"><span>充值</span></div> + </div> + <div style="padding-top: 27px;"> + <div class="pay-tip2"></div> + </div> + <div class='pay-sbox' > + <div class="qrcode-box"> + <div class="pbox"> + 请您扫描以下二维码,钱包充值金额:<span class="wst-fred">¥{$needPay}</span> + </div> + <div style="" class="wst-qrcode"></div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> + {if condition="$out_trade_no != '' and $code_url!=''"} + var qr = qrcode(10, 'M'); + qr.addData("{$code_url}"); + qr.make(); + $(".wst-qrcode").html(qr.createImgTag()); + + {/if} + setInterval(function(){ + var params = {}; + params.trade_no = "{$out_trade_no}"; + + $.ajax({ + url:"{:url('home/weixinpays/getPayStatus')}", + data:params, + type:"POST", + dataType:"json", + success:function(data){ + if(data.status==1){ + location.href = "{:url('home/logmoneys/shopmoneys')}"; + } + } + }); + },1500); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/recharge/recharge.js b/hyhproject/home/view/default/shops/recharge/recharge.js new file mode 100755 index 0000000..4e74c4d --- /dev/null +++ b/hyhproject/home/view/default/shops/recharge/recharge.js @@ -0,0 +1,58 @@ + +function getPayUrl(){ + var params = {}; + params.payObj = "recharge"; + params.targetType = 1; + params.needPay = $.trim($("#needPay").val()); + params.payCode = $.trim($("#payCode").val()); + params.itmeId = $.trim($("#itmeId").val()); + if(params.itmeId==0 && params.needPay<=0){ + WST.msg('请输入充值金额', {icon: 5}); + return; + } + if(params.payCode==""){ + WST.msg('请先选择支付方式', {icon: 5}); + return; + } + jQuery.post(WST.U('home/'+params.payCode+'/get'+params.payCode+"URL"),params,function(data) { + var json = WST.toJson(data); + if(json.status==1){ + location.href = json.url; + }else{ + WST.msg('充值失败', {icon: 5}); + } + }); +} + +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + if(n==0){ + $(".j-charge-other").hide(); + $(".j-charge-money").show(); + + }else{ + $(".j-charge-other").show(); + $(".j-charge-money").hide(); + } + inEffect(obj,2); +} +$(function(){ + $(".wst-frame2:first").click(); + $("#wst-check-orders").click(function(){ + $("#wst-orders-box").slideToggle(600); + }); + $("div[class^=wst-payCode]").click(function(){ + var payCode = $(this).attr("data"); + $("div[class^=wst-payCode]").each(function(){ + $(this).removeClass().addClass("wst-payCode-"+$(this).attr("data")); + }); + $(this).removeClass().addClass("wst-payCode-"+payCode+"-curr"); + $("#payCode").val(payCode); + }); + if($("div[class^=wst-payCode]").length>0){ + $("div[class^=wst-payCode]")[0].click(); + } +}); \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/stat_orders.html b/hyhproject/home/view/default/shops/reports/stat_orders.html new file mode 100755 index 0000000..f735f00 --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/stat_orders.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}销售订单统计 - 卖家中心{__block__}{/block} +{block name="content"} +<style> +.wst-list tbody tr td {height: 35px;line-height: 35px;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>销售订单统计</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <div id='main' style='height:300px;width:99%'></div> + <table id='mainTable' class='wst-list hide' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100'>日期</th> + <th width='100'>取消订单</th> + <th width='130'>拒收订单</th> + <th width='130'>正常订单</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="stat-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + </td> + <td>{{ d[i].day }}</td> + <td>{{ d[i].o3 }}</td> + <td>{{ d[i].o1 }}</td> + <td>{{ d[i].ou }}</td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/stat_orders.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/stat_orders.js b/hyhproject/home/view/default/shops/reports/stat_orders.js new file mode 100755 index 0000000..9ead9d0 --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/stat_orders.js @@ -0,0 +1,103 @@ +function loadStat(){ + var loading = WST.load({msg:'正在查询数据,请稍后...'}); + $.post(WST.U('home/reports/getStatOrders'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + y: 'top', + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + legend: { + data:['取消订单','拒收订单','正常订单'] + }, + xAxis : [ + { + type : 'category', + splitLine : {show : false}, + data : json.data.days + } + ], + yAxis : [ + { + type : 'value', + position: 'right' + } + ], + series : [ + { + name:'取消订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['-1'] + }, + { + name:'拒收订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['-3'] + }, + { + name:'正常订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['1'] + }, + { + name:'订单总数', + type:'line', + data:json.data['total'] + }, + { + name:'订单类型细分', + type:'pie', + tooltip : { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + center: [160,130], + radius : [0, 50], + itemStyle : { + normal : { + labelLine : { + length : 20 + } + } + }, + data:[ + {value:json.data.map['-3'], name:'取消订单'}, + {value:json.data.map['-1'], name:'拒收订单'}, + {value:json.data.map['1'], name:'正常订单'}, + ] + } + ] + }; + myChart.setOption(option); + var gettpl = document.getElementById('stat-tblist').innerHTML; + laytpl(gettpl).render(json.data.list, function(html){ + $('#list-box').html(html); + $('#mainTable').show(); + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/stat_sales.html b/hyhproject/home/view/default/shops/reports/stat_sales.html new file mode 100755 index 0000000..cc3e95b --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/stat_sales.html @@ -0,0 +1,49 @@ +{extend name="default/shops/base" /} +{block name="title"}销售额统计 - 卖家中心{__block__}{/block} +{block name="content"} +<style> +.wst-list tbody tr td {height: 35px;line-height: 35px;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>销售额统计</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + 支付方式:<select id='payType' class='j-ipt'> + <option value='-1'>全部</option> + <option value='0'>货到付款</option> + <option value='1'>在线支付</option> + </select> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <div id='main' style='height:300px;width:99%'></div> + <table id='mainTable' class='wst-list hide' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100'>日期</th> + <th width='100'>订单数</th> + <th width='130'>销售额</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="stat-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + </td> + <td>{{ d[i].day }}</td> + <td>{{ d[i].num }}</td> + <td>¥{{ d[i].val }}</td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/stat_sales.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/stat_sales.js b/hyhproject/home/view/default/shops/reports/stat_sales.js new file mode 100755 index 0000000..2fb394c --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/stat_sales.js @@ -0,0 +1,54 @@ +function loadStat(){ + var loading = WST.load({msg:'正在查询数据,请稍后...'}); + $.post(WST.U('home/reports/getStatSales'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + xAxis : [ + { + type : 'category', + data : json.data.days + } + ], + yAxis : [ + { + type : 'value' + } + ], + series : [ + { + name:'销售额', + type:'line', + data:json.data.dayVals + } + ] + }; + myChart.setOption(option); + var gettpl = document.getElementById('stat-tblist').innerHTML; + laytpl(gettpl).render(json.data.list, function(html){ + $('#list-box').html(html); + $('#mainTable').show(); + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/top_sale_goods.html b/hyhproject/home/view/default/shops/reports/top_sale_goods.html new file mode 100755 index 0000000..4290713 --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/top_sale_goods.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}商品销售排行 - 卖家中心{__block__}{/block} + +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>商品销售排行</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100' colspan="2">商品</th> + <th width='130'>商品编号</th> + <th width='100'>销量</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="top-sale-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + <td> + <div class='goods-img'> + <a target='_blank' href='{{WST.U("home/goods/detail","id="+d[i].goodsId)}}'> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div></td> + <td>{{ d[i].goodsName }}</td> + <td>{{ d[i].goodsSn }}</td> + <td>{{ d[i].goodsNum}}</td> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/top_sale_goods.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/reports/top_sale_goods.js b/hyhproject/home/view/default/shops/reports/top_sale_goods.js new file mode 100755 index 0000000..c206a30 --- /dev/null +++ b/hyhproject/home/view/default/shops/reports/top_sale_goods.js @@ -0,0 +1,16 @@ +function loadStat(){ + var load = WST.load({msg:'正在加载数据,请稍后...'}) + $.post(WST.U('home/reports/getTopSaleGoods'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1' && json.data){ + var gettpl = document.getElementById('top-sale-tblist').innerHTML; + laytpl(gettpl).render(json.data, function(html){ + $('#list-box').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/settlements/list.html b/hyhproject/home/view/default/shops/settlements/list.html new file mode 100755 index 0000000..957ae92 --- /dev/null +++ b/hyhproject/home/view/default/shops/settlements/list.html @@ -0,0 +1,166 @@ +{extend name="default/shops/base" /} +{block name="title"}订单结算 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li id="wst-msg-li-0">结算信息<span style="display:none;"></span></li> + <li id="wst-msg-li-1">未结算订单<span style="display:none;"></span></li> + <li id="wst-msg-li-2">已结算订单<span style="display:none;"></span></li> + </ul> + <div class="wst-tab-content" style='width:98%;'> + <div class='wst-tab-item'> + <div> + 结算单号:<input type="text" id="settlementNo_0" style='width:120px;' autocomplete="off"/> + 结算状态:<select id='isFinish_0' autocomplete="off"> + <option value='-1'>全部</option> + <option value='0'>未结算</option> + <option value='1'>已结算</option> + </select> + <a class='s-btn' onclick="getQueryPage(0)">查询</a> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;</th> + <th width='100'>结算单号</th> + <th width='40'>类型</th> + <th width='60'>结算金额</th> + <th width='80'>结算佣金</th> + <th width='80'>返还金额</th> + <th width='130'>创建时间</th> + <th width='60'>结算状态</th> + <th width='130'>结算时间</th> + <th width='*'>备注</th> + </tr> + </thead> + <script id="tblist0" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td><a style='color:blue' href='javascript:view("{{d[i].settlementId}}")'>{{d[i].settlementNo}}</a></td> + <td>{{# if(d[i].settlementType==1){ }}定时{{# }else{ }}手动{{# } }}</td> + <td>¥{{d[i].settlementMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + <td>¥{{d[i].backMoney}}</td> + <td>{{d[i].createTime}}</td> + <td>{{# if(d[i].settlementStatus==1){ }}已结算{{# }else{ }}未结算{{# } }}</td> + <td>{{WST.blank(d[i].settlementTime,'-')}}</td> + <td style='line-height:20px;'>{{WST.blank(d[i].remarks)}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody0"></tbody> + <tfoot> + <tr> + <td colspan='10' align='center' id="pager_0"></td> + </tr> + </tfoot> + </table> + </div> + {/** 待结算订单 **/} + <div class='wst-tab-item hide'> + <div> + 订单号:<input type="text" id="orderNo_1" style='width:120px;' autocomplete="off"/> + <a class='s-btn' onclick="getUnSettledOrderPage(0)">查询</a> + <!-- <a class='s-btn' style='width:110px;' onclick="settlement()">申请结算</a> --> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <!-- <th width='20'><input type='checkbox' onclick='WST.checkChks(this,".chk_1")'/></th> --> + <th width='100'>订单号</th> + <th width='130'>下单时间</th> + <th width='80'>支付方式</th> + <th width='80'>商品总金额</th> + <th width='70'>运费</th> + <th width='90'>订单总金额</th> + <th width='90'>实付金额</th> + <th width='70'>应付佣金</th> + </tr> + </thead> + <script id="tblist1" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <!-- <td><input type='checkbox' class='chk_1' value='{{d[i].orderId}}'/></td> --> + <td>{{d[i].orderNo}}</td> + <td>{{d[i].createTime}}</td> + <td>{{d[i].payTypeNames}}</td> + <td>¥{{d[i].goodsMoney}}</td> + <td>¥{{d[i].deliverMoney}}</td> + <td>¥{{d[i].totalMoney}}</td> + <td>¥{{d[i].realTotalMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody1"> + </tbody> + <tfoot> + <tr> + <td colspan='7' align='center' id="pager_1"></td> + </tr> + </tfoot> + </table> + + </div> + <div class='wst-tab-item hide'> + <div> + 结算单号:<input type="text" id="settlementNo_2" style='width:120px;' class="s-ipt" autocomplete="off"/> + 订单号:<input type="text" id="orderNo_2" style='width:120px;' class="s-ipt" autocomplete="off"/> + 结算状态:<select id='isFinish_2' class="s-ipt" autocomplete="off"> + <option value='-1'>全部</option> + <option value='0'>未结算</option> + <option value='1'>已结算</option> + </select> + <a class='s-btn' onclick="getSettleOrderPage(0)">查询</a> + <a class="s-btn" style='margin-top:0px;line-height:15px;height:16px;float: right;' onclick="javascript:toExport(0)">导出</a> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;</th> + <th width='100'>订单号</th> + <th width='80'>支付方式</th> + <th width='70'>商品总金额</th> + <th width='70'>运费</th> + <th width='70'>订单总金额</th> + <th width='70'>实付金额</th> + <th width='70'>应付佣金</th> + <th width='70'>结算方式</th> + <th width='130'>结算单号</th> + <th width='130'>结算时间</th> + </tr> + </thead> + <script id="tblist2" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i].orderNo}}</td> + <td>{{d[i].payTypeNames}}</td> + <td>¥{{d[i].goodsMoney}}</td> + <td>¥{{d[i].deliverMoney}}</td> + <td>¥{{d[i].totalMoney}}</td> + <td>¥{{d[i].realTotalMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + <td>{{d[i].payName}}</td> + <td>{{d[i].settlementNo}}</td> + <td>{{WST.blank(d[i].settlementTime,'-')}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody2"></tbody> + <tfoot> + <tr> + <td colspan='9' align='center' id="pager_2"></td> + </tr> + </tfoot> + </table> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/settlements/settlements.js?v={$v}'></script> + +{/block} diff --git a/hyhproject/home/view/default/shops/settlements/settlements.js b/hyhproject/home/view/default/shops/settlements/settlements.js new file mode 100755 index 0000000..c051e66 --- /dev/null +++ b/hyhproject/home/view/default/shops/settlements/settlements.js @@ -0,0 +1,134 @@ +$(function(){ + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:getQueryPage(0);break; + case 1:getUnSettledOrderPage(0);break; + case 2:getSettleOrderPage(0);break; + } + }}); +}); +function view(val){ + location.href=WST.U('home/settlements/view','id='+val); +} +function getQueryPage(p){ + var params = {}; + params.page = p; + params.settlementNo = $.trim($('#settlementNo_0').val()); + params.isFinish = $('#isFinish_0').val(); + $.post(WST.U('home/settlements/pageQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var json = json.data; + var gettpl = document.getElementById('tblist0').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody0').html(html); + }); + laypage({ + cont: 'pager_0', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getQueryPage(e.curr); + } + } + }); + } + }); +} +function settlement(){ + var ids = WST.getChks('.chk_1'); + if(ids.length==0){ + WST.msg('请选择要结算的订单!',{icon:2}); + return; + } + var load = WST.load({msg:'正在提交申请,请稍后...'}); + WST.confirm({content:'您确定要申请结算这些订单吗?',yes:function(){ + $.post(WST.U('home/settlements/settlement'),{ids:ids.join(',')},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + getUnSettledOrderPage(WSTCurrPage); + }); + }else{ + WST.msg(json.msg); + } + }); + }}); +} +function getUnSettledOrderPage(p){ + var params = {}; + params.page = p; + params.orderNo = $.trim($('#orderNo_1').val()); + $('#pager_1').empty(); + $.post(WST.U('home/settlements/pageUnSettledQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + getUnSettledOrderPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist1').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody1').html(html); + }); + laypage({ + cont: 'pager_1', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getUnSettledOrderPage(e.curr); + } + } + }); + } + }); +} +function getSettleOrderPage(p){ + var params = {}; + params.page = p; + params.orderNo = $.trim($('#orderNo_2').val()); + params.settlementNo = $.trim($('#settlementNo_2').val()); + params.isFinish = $.trim($('#isFinish_2').val()); + $('#pager_2').empty(); + $.post(WST.U('home/settlements/pageSettledQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist2').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody2').html(html); + }); + laypage({ + cont: 'pager_2', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getSettleOrderPage(e.curr); + } + } + }); + } + }); +} +//导出订单 +function toExport(){ + var params = {}; + params.orderNo = $.trim($('#orderNo_2').val()); + params.settlementNo = $.trim($('#settlementNo_2').val()); + params.isFinish = $.trim($('#isFinish_2').val()); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('home/settlements/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/settlements/view.html b/hyhproject/home/view/default/shops/settlements/view.html new file mode 100755 index 0000000..cc122a7 --- /dev/null +++ b/hyhproject/home/view/default/shops/settlements/view.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}结算详情-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>结算详情</span><a href="<?=url('home/settlements/index');?>">返回</a></div> +<div class="wst-clear"></div> +<div class="wst-body"> + <form id='editform' autocomplete='off'> + <div class="wst-tab-item" style="position: relative;"> + <table class='wst-form'> + <tr> + <td class='head-ititle' colspan='2'>结算信息</td> + </tr> + <tr> + <th width='120'>结算单号:</th> + <td>{$object['settlementNo']}</td> + </tr> + <tr> + <th>结算金额:</th> + <td>¥{$object['settlementMoney']}</td> + </tr> + <tr> + <th>结算佣金:</th> + <td>¥{$object['commissionFee']}</td> + </tr> + <tr> + <th>返还金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <th>结算状态:</th> + <td> + {if $object['settlementStatus']==1} + 已结算 + {else} + 待结算 + {/if} + </td> + </tr> + {if $object['settlementStatus']==1} + <tr> + <th>结算时间:</th> + <td>{$object['settlementTime']}</td> + </tr> + <tr> + <th>结算备注:</th> + <td>{$object['remarks']}</td> + </tr> + {/if} + <tr> + <td colspan='2' align="center"> + <table class='wst-list' style='margin-left:5px;'> + <thead> + <tr> + <th>序号</th> + <th>订单号</th> + <th>支付方式</th> + <th>商品金额</th> + <th>运费</th> + <th>订单总金额</th> + <th>积分抵扣</th> + <th>实付金额</th> + <th>佣金</th> + <th>下单时间</th> + </tr> + </thead> + {volist name='$object["list"]' id='vo'} + <tr> + <td>{$key+1}</td> + <td>{$vo['orderNo']}</td> + <td>{:WSTLangPayType($vo['payType'])}</td> + <td>¥{$vo['goodsMoney']}</td> + <td>¥{$vo['deliverMoney']}</td> + <td>¥{$vo['totalMoney']}</td> + <td>¥{$vo['scoreMoney']}</td> + <td>¥{$vo['realTotalMoney']}</td> + <td>¥{$vo['commissionFee']}</td> + <td>{$vo['createTime']}</td> + </tr> + {/volist} + </table> + </td> + </tr> + </table> + </div> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopcats/list.html b/hyhproject/home/view/default/shops/shopcats/list.html new file mode 100755 index 0000000..9b34873 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopcats/list.html @@ -0,0 +1,176 @@ +{extend name="default/shops/base" /} +{block name="title"}商品分类 - 卖家中心{__block__}{/block} +{block name="css"} +<!--mark 20180518 by zl--> +<meta http-equiv="Access-Control-Allow-Origin" content="*"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<!--end--> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>商品分类</span></div> +<div class="wst-clear"></div> + <div style='text-align:right;height: 36px;'> + <span></span> + <a href='javascript:addCat(1);' style='float:right;margin:9px 30px 0px 0px;'><img class="wst-lfloat" style="margin:-3px 5px 0px 0px;" src="__STYLE__/img/seller_icon_xz.png">新增</a> + </div> + <form autocomplete="off"> + <table id="cat_list_tab" class='wst-list wst-form'> + <thead> + <tr class="wst-colour"> + <th class="wst-fre-th">名称</th> + <th width='60'>排序号</th> + <th width='80' style="line-height: normal;">是否显示<br/><span style="font-weight:normal;color:red;">(双击可修改)</span></th> + <th width="150">操作</th> + </tr> + </thead> + {volist name="list" id="vo" key='i'} + <tbody> + <tr id='tr_{$i}' isLoad='1'> + <td class="wst-fre-td"> + <span class='wst-tree-open active' onclick='javascript:treeCatOpen(this,{$vo.catId})'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_zk.png"></span> + <input type='text' style='width:400px;' value='{$vo['catName']}' dataId="{$vo.catId}" onchange='javascript:editCatName(this)'/> + </td> + <td><input class='catsort' type='text' style='width:35px;' value="{$vo['catSort']}" dataId="{$vo.catId}" onchange='javascript:editCatSort(this)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + {if condition="$vo['isShow']==0 "} + <td style="cursor:pointer;" ondblclick="changeCatStatus(1,{$vo['catId']},0)"><span class='wst-state_no'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_error.png"></span></td> + {else/} + <td style="cursor:pointer;" ondblclick="changeCatStatus(0,{$vo['catId']},0)"><span class='wst-state_yes'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_right.png"></span></td> + {/if} + <td> + <a href="javascript:void(0);" onclick='javascript:addCat(this,{$vo["catId"]},{$i});' class='add btn' title='新增'>[新增]</a> + <a href="javascript:void(0);" onclick="javascript:delCat({$vo['catId']},0)" class='del btn' title='删除'>[删除]</a>&nbsp; + <!--mark 20180518 by zll--> + {if condition="$shopId eq 1"} + <a href="javascript:void(0);" onclick="javascript:setSpecial('{$vo['catId']}','{$vo['provId']}','{$vo['catImg']}','{$vo['isHot']}')" class='del btn' title='设为特产'>[设为特产]</a>&nbsp; + {/if} + <!--end--> + </td> + </tr> + {if isset($vo['childNum'])} + {if condition="$vo['childNum'] gt 0 "} + {volist name="vo['child']" id="vo2" key='i2'} + <tr id='tr_{$i}_{$i2}' class="tr_{$i} tree_{$vo.catId}" isLoad='1'> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <input type='text' style='width:400px;' value='{$vo2['catName']}' dataId="{$vo2.catId}" onchange='javascript:editCatName(this)'/> + </td> + <td><input class='catsort' type='text' style='width:35px;' value="{$vo2['catSort']}" dataId="{$vo2.catId}" onchange='javascript:editCatSort(this)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + {if condition="$vo2['isShow']==0 "} + <td style="cursor:pointer;" onclick="changeCatStatus(1,{$vo2['catId']},{$vo['catId']})"><span class='wst-state_no'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_error.png"></span></td> + {else/} + <td style="cursor:pointer;" onclick="changeCatStatus(0,{$vo2['catId']},{$vo['catId']})"><span class='wst-state_yes'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_right.png"></span></td> + {/if} + <td> + <a href="javascript:delCat({$vo2['catId']},0)" class='del btn' title='删除'>[删除]</a>&nbsp; + </td> + </tr> + {/volist} + {/if} + {/if} + </tbody> + {/volist} +</table> +</form> +<div class='wst-tbar-group' style='height: 76px;text-align: center'> + <button class='wst-shop-but hide' style='margin-top:40px;;width:80px;height: 30px;' type="button" onclick='javascript:batchSaveCats()'>保&nbsp;存</button> + <button class='wst-shop-but hide' style='margin-top:40px;margin-left:5px;width:80px;height: 30px;;' type="button" onclick='javascript:location.reload()'>取&nbsp;消</button> + <a style='float:right;margin:30px 30px 0px 0px;' href='javascript:addCat(1);'><img class="wst-lfloat" style="margin:-3px 5px 0px 0px;" src="__STYLE__/img/seller_icon_xz.png">新增</a> +</div> +</div> + + + +<script id="cat_p_tr" type="text/html"> +<tbody class='tbody_new'> + <tr class="tr_new" isload="1"> + <td class="wst-fre-td"> + <span class="wst-tree-open"><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_zk.png"></span> + <input class="catname" type="text" style="width:400px;height:22px;margin-left:6px;" dataid=""> + </td> + <td> + <input class="catsort" type="text" style="width:35px;" value="0" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"> + </td> + <td style="cursor:pointer;"> + <input class="catshow" type="checkbox" checked=""/> + </td> + <td> + <a href="javascript:void(0);" onclick="addCat(this,0,0);" class="add btn" title="新增">[新增]</a> + <a href="javascript:void(0);" class="del btn" title="删除" onclick="delCatObj(this,1)">[删除]</a>&nbsp; + </td> + </tr> +</tbody> +</script> + +<script id="cat_c_tr" type="text/html"> +<tr class="{{d.className}}" isload="1" catid="{{d.p}}"> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <input class="catname" type="text" style='width:400px' dataid=""> + </td> + <td> + <input class="catsort" type="text" style="width:35px;" value="0" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"> + </td> + <td style="cursor:pointer;"> + <input class="catshow" type="checkbox" checked=""/> + </td> + <td> + <a href="javascript:void(0);" class="del btn" title="删除" onclick="delCatObj(this,2)">[删除]</a>&nbsp; + </td> +</tr> +</script> + + +<!--模态框 mark 20180518 zll--> +<div id='shopcatsBox' style='display:none' class='layui-form'> + <form id='shopcatsForm' autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th>特产省份<font color='red'>*</font>:</th> + <td> + <select name="provId" id="provId" class="ipt" > + <option value ='0'>--请选择--</option> + + {volist name="areas" id="vv"} + <option value="{$vv['areaId']}" >{$vv['areaName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>分类图标<font color='red'>*</font>:</th> + <td> + <div id='catFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='catImg' name="catImg" class="ipt" /> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:75px;" id="preview"></div></td> + </tr> + <tr> + <th>是否热门:</th> + <td> + <input type="checkbox" id="isHot" name="isHot" value="1" class="ipt" /> + </td> + </tr> + + </table> + </form> +</div> +<!--end--> + + +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} + <!--mark 20180518--> + <script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <!--end--> + <script type='text/javascript' src='__STYLE__/shops/shopcats/shopcats.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopcats/php/get.php b/hyhproject/home/view/default/shops/shopcats/php/get.php new file mode 100755 index 0000000..2f040dd --- /dev/null +++ b/hyhproject/home/view/default/shops/shopcats/php/get.php @@ -0,0 +1,48 @@ +<?php + function gmt_iso8601($time) { + $dtStr = date("c", $time); + $mydatetime = new DateTime($dtStr); + $expiration = $mydatetime->format(DateTime::ISO8601); + $pos = strpos($expiration, '+'); + $expiration = substr($expiration, 0, $pos); + return $expiration."Z"; + } + + $id= 'LTAIOUxnwu01rA9g'; + $key= 'k0eigaxy8Gnz2V6AwcMNmwMSbQXsCf'; + $host = 'http://dianshanglian.oss-cn-beijing.aliyuncs.com'; + + $now = time(); + $expire = 30; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问 + $end = $now + $expire; + $expiration = gmt_iso8601($end); + $save_dir = $_GET['dir']; + $dir = 'upload/'.$save_dir."/".date('Y-m').'/'; + + //最大文件大小.用户可以自己设置 + $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000); + $conditions[] = $condition; + + //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录 + $start = array(0=>'starts-with', 1=>'$key', 2=>$dir); + $conditions[] = $start; + + + $arr = array('expiration'=>$expiration,'conditions'=>$conditions); + //echo json_encode($arr); + //return; + $policy = json_encode($arr); + $base64_policy = base64_encode($policy); + $string_to_sign = $base64_policy; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true)); + + $response = array(); + $response['accessid'] = $id; + $response['host'] = $host; + $response['policy'] = $base64_policy; + $response['signature'] = $signature; + $response['expire'] = $end; + //这个参数是设置用户上传指定的前缀 + $response['dir'] = $dir; + echo json_encode($response); +?> diff --git a/hyhproject/home/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js b/hyhproject/home/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js new file mode 100755 index 0000000..c49a542 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js @@ -0,0 +1,401 @@ +function addCat(obj,p,catNo){ + var html = new Array(); + if(typeof(obj)=="number"){ + $("#cat_list_tab").append($("#cat_p_tr").html()); + }else{ + var className = (p==0)?"tr_c_new":"tr_"+catNo+" tr_0"; + var gettpl = $("#cat_c_tr").html(); + laytpl(gettpl).render({"className":className,"p":p}, function(html){ + $(obj).parent().parent().parent().append(html); + }); + } + $('.wst-shop-but').show(); +} + +function delCatObj(obj,vk){ + if(vk==1){ + $(obj).parent().parent().parent().remove(); + }else{ + $(obj).parent().parent().remove(); + } + if($(".tr_0").size()==0 && $(".tbody_new").size()==0)$('.wst-shop-but').hide(); +} + +function treeCatOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_sq.png">'); + $('.tree_'+id).hide(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_zk.png">'); + $('.tree_'+id).show(); + } +} + +function delCat(id){ + var box = WST.confirm({content:"您确定要删除该商品分类吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopcats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function batchSaveCats(){ + var params = {}; + var fristNo = 0; + var secondNo = 0; + $(".tbody_new").each(function(){ + secondNo = 0; + var pobj = $(this).find(".tr_new"); + params['catName_'+fristNo] = $.trim(pobj.find(".catname").val()); + if(params['catName_'+fristNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo] = pobj.find(".catsort").val(); + params['catShow_'+fristNo] = pobj.find(".catshow").prop("checked")?1:0 + $(this).find(".tr_c_new").each(function(){ + params['catId_'+fristNo+'_'+secondNo] = fristNo; + params['catName_'+fristNo+'_'+secondNo] = $.trim($(this).find(".catname").val()); + if(params['catName_'+fristNo+'_'+secondNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo+'_'+secondNo] = $(this).find(".catsort").val(); + params['catShow_'+fristNo+'_'+secondNo] = $(this).find(".catshow").prop("checked")?1:0 + params['catSecondNo_'+fristNo] = ++secondNo; + }); + params['fristNo'] = ++fristNo; + }); + var otherNo = 0; + $(".tr_0").each(function(){ + params['catId_o_'+otherNo] = $(this).attr('catId'); + params['catName_o_'+otherNo] = $.trim($(this).find(".catname").val()); + if(params['catName_o_'+otherNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_o_'+otherNo] = $(this).find(".catsort").val(); + params['catShow_o_'+otherNo] = $(this).find(".catshow").prop("checked")?1:0; + params['otherNo'] = ++otherNo; + }); + $.post(WST.U('home/shopcats/batchSaveCats'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('新增成功!', {icon: 1,time:500},function(){ + location.reload(); + }); + }else{ + WST.msg('新增失败!', {icon: 5}); + } + }); +} + + +function editCatName(obj){ + $.post(WST.U('home/shopcats/editName'),{"id":$(obj).attr('dataId'),"catName":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} +function editCatSort(obj){ + $.post(WST.U('home/shopcats/editSort'),{"id":$(obj).attr('dataId'),"catSort":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +function changeCatStatus(isShow,id,pid){ + var params = {}; + params.id = id; + params.isShow = isShow; + params.pid = pid; + $.post(WST.U('home/shopcats/changeCatStatus'),params,function(data,textStatus){ + location.reload(); + }); + +} + + + + +//mark 修改特产省份 20180518 by zll +var isInitUpload = false; +function setSpecial(catId,provId,catImg,isHot){ + if(provId>0)$('#provId').val(provId); + if(catImg !=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+catImg+'" height="75px" />'); + $('#catImg').val(catImg); + }else{ + $('#preview').html(''); + $('#catImg').val(''); + }; + (isHot==1)?$('#isHot').prop('checked',true):$('#isHot').prop('checked',false); + if(!isInitUpload)initUpload(); + var box = layer.open({ + type:1, + title:'设置特产省份', + btn:['设置','消除特产','取消'], + content:$('#shopcatsBox'), + area:['400px','500px'], + + yes:function(){ + var params = WST.getParams('.ipt'); + params.provName = $('#provId option:selected').text(); + params.catId = catId; + if(params.provId == '0'){ + layer.msg('请选择省份'); + return false; + } + if(params.catImg==''){ + layer.msg('请选择图片'); + return false; + } + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + window.parent.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + btn2:function(){ + var params = {}; + params.catId = catId; + params.provName=''; + params.provId = '0'; + params.isHot = '0'; + params.catImg = ''; + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + + }); +} +// function initUpload(){ +// isInitUpload = true; +// //文件上传 +// WST.upload({ +// pick:'#catFilePicker', +// formData: {dir:'shopcats'}, +// accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, +// callback:function(f){ +// var json = WST.toJson(f); +// if(json.status==1){ +// $('#uploadMsg').empty().hide(); +// //将上传的图片路径赋给全局变量 +// $('#catImg').val(json.savePath+json.thumb); +// $('#preview').html('<img src="'+WST.conf.ROOT+'/'+json.savePath+json.thumb+'" height="75" />'); +// }else{ +// WST.msg(json.msg,{icon:2}); +// } +// }, +// progress:function(rate){ +// $('#uploadMsg').show().html('已上传'+rate+"%"); +// } +// }); +// } +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + // 'success_action_status' : '200', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + function initUpload(){ + + isInitUpload = true; + //文件上传 + uploader = new WebUploader.create({ + pick:'#catFilePicker', + auto: true, + swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf', + server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com', + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + + }); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + // uploader.on('uploadBeforeSend', function(obj,data, headers) { + // // console.log(obj.file); + // set_upload_param(uploader,obj.file.name,true); + + // }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function(file,response) { + console.log(response); + + pic_name = get_uploaded_object_name(file.name) + console.log(pic_name); + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(pic_name); + $('#preview').html('<img src="http://img.juzi199.com/'+pic_name+'" height="75"/>'); + + }); + uploader.on('uploadError', function( file ) { + console.log(2222); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + // console.log(file); + rate = percentage.toFixed(2)*100; + $('#uploadMsg').show().html('已上传'+rate+"%"); + }); +} + +//end \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopcats/shopcats.js b/hyhproject/home/view/default/shops/shopcats/shopcats.js new file mode 100755 index 0000000..291cc95 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopcats/shopcats.js @@ -0,0 +1,228 @@ +function addCat(obj,p,catNo){ + var html = new Array(); + if(typeof(obj)=="number"){ + $("#cat_list_tab").append($("#cat_p_tr").html()); + }else{ + var className = (p==0)?"tr_c_new":"tr_"+catNo+" tr_0"; + var gettpl = $("#cat_c_tr").html(); + laytpl(gettpl).render({"className":className,"p":p}, function(html){ + $(obj).parent().parent().parent().append(html); + }); + } + $('.wst-shop-but').show(); +} + +function delCatObj(obj,vk){ + if(vk==1){ + $(obj).parent().parent().parent().remove(); + }else{ + $(obj).parent().parent().remove(); + } + if($(".tr_0").size()==0 && $(".tbody_new").size()==0)$('.wst-shop-but').hide(); +} + +function treeCatOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_sq.png">'); + $('.tree_'+id).hide(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_zk.png">'); + $('.tree_'+id).show(); + } +} + +function delCat(id){ + var box = WST.confirm({content:"您确定要删除该商品分类吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopcats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function batchSaveCats(){ + var params = {}; + var fristNo = 0; + var secondNo = 0; + $(".tbody_new").each(function(){ + secondNo = 0; + var pobj = $(this).find(".tr_new"); + params['catName_'+fristNo] = $.trim(pobj.find(".catname").val()); + if(params['catName_'+fristNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo] = pobj.find(".catsort").val(); + params['catShow_'+fristNo] = pobj.find(".catshow").prop("checked")?1:0 + $(this).find(".tr_c_new").each(function(){ + params['catId_'+fristNo+'_'+secondNo] = fristNo; + params['catName_'+fristNo+'_'+secondNo] = $.trim($(this).find(".catname").val()); + if(params['catName_'+fristNo+'_'+secondNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo+'_'+secondNo] = $(this).find(".catsort").val(); + params['catShow_'+fristNo+'_'+secondNo] = $(this).find(".catshow").prop("checked")?1:0 + params['catSecondNo_'+fristNo] = ++secondNo; + }); + params['fristNo'] = ++fristNo; + }); + var otherNo = 0; + $(".tr_0").each(function(){ + params['catId_o_'+otherNo] = $(this).attr('catId'); + params['catName_o_'+otherNo] = $.trim($(this).find(".catname").val()); + if(params['catName_o_'+otherNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_o_'+otherNo] = $(this).find(".catsort").val(); + params['catShow_o_'+otherNo] = $(this).find(".catshow").prop("checked")?1:0; + params['otherNo'] = ++otherNo; + }); + $.post(WST.U('home/shopcats/batchSaveCats'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('新增成功!', {icon: 1,time:500},function(){ + location.reload(); + }); + }else{ + WST.msg('新增失败!', {icon: 5}); + } + }); +} + + +function editCatName(obj){ + $.post(WST.U('home/shopcats/editName'),{"id":$(obj).attr('dataId'),"catName":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} +function editCatSort(obj){ + $.post(WST.U('home/shopcats/editSort'),{"id":$(obj).attr('dataId'),"catSort":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +function changeCatStatus(isShow,id,pid){ + var params = {}; + params.id = id; + params.isShow = isShow; + params.pid = pid; + $.post(WST.U('home/shopcats/changeCatStatus'),params,function(data,textStatus){ + location.reload(); + }); + +} + + + + +//mark 修改特产省份 20180518 by zll +var isInitUpload = false; +function setSpecial(catId,provId,catImg,isHot){ + if(provId>0)$('#provId').val(provId); + if(catImg !=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+catImg+'" height="75px" />'); + $('#catImg').val(catImg); + }else{ + $('#preview').html(''); + $('#catImg').val(''); + }; + (isHot==1)?$('#isHot').prop('checked',true):$('#isHot').prop('checked',false); + if(!isInitUpload)initUpload(); + var box = layer.open({ + type:1, + title:'设置特产省份', + btn:['设置','消除特产','取消'], + content:$('#shopcatsBox'), + area:['400px','500px'], + + yes:function(){ + var params = WST.getParams('.ipt'); + params.provName = $('#provId option:selected').text(); + params.catId = catId; + if(params.provId == '0'){ + layer.msg('请选择省份'); + return false; + } + if(params.catImg==''){ + layer.msg('请选择图片'); + return false; + } + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + window.parent.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + btn2:function(){ + var params = {}; + params.catId = catId; + params.provName=''; + params.provId = '0'; + params.isHot = '0'; + params.catImg = ''; + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + + }); +} +function initUpload(){ + isInitUpload = true; + //文件上传 + WST.upload({ + pick:'#catFilePicker', + formData: {dir:'shopcats'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(json.savePath+json.thumb); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} + +//end \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.html b/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.html new file mode 100755 index 0000000..4fdf160 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.html @@ -0,0 +1,163 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺设置-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<script> +$(function(){ + $('.state-complete').css('border-color','#ddd'); +}) +</script> +<style> +.filelist .btn-del,.webuploader-pick,.wst-batchupload .placeholder .webuploader-pick,.wst-batchupload .statusBar .btns .uploadBtn{background: #e45050;} +.wst-batchupload .statusBar .btns .uploadBtn:hover {background: #e45525 none repeat scroll 0 0;} +.shopbanner{position: relative;} +.del-banner{position: absolute;top:0px;right:0px;background: #e45050 none repeat scroll 0 0 z-index: 55;color: #ffffff;cursor: pointer;height: 18px;line-height: 18px;padding: 0 5px;} +.wst-batchupload .filelist li{background:#ffffff;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>店铺设置</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + + <form name="shopCfg" id="shopCfg" autocomplete="off"> + + + <table class="wst-form"> + <tr> + <th width='120' align='right'>店铺SEO关键字<font color='red'>*</font>:</th> + <td><input type='text' id='shopKeywords' name='shopKeywords' class="ipt" value='{$object.shopKeywords}' data-rule='关键字:required;' style='width:350px;' maxLength='25' /></td> + </tr> + <tr> + <th width='120'>店铺SEO描述:</th> + <td colspan='3'> + <textarea rows="2" style='width:350px;' class="ipt" id='shopDesc' name='shopDesc' >{$object.shopDesc}</textarea> + </td> + </tr> + <tr> + <th width='120'>店铺热搜关键词:</th> + <td><input type='text' id='shopHotWords' name='shopHotWords' class="ipt" value='{$object.shopHotWords}' style='width:350px;' placeholder="店铺主页搜索栏下的引导搜索词" maxLength='100'/></td> + </tr> + + + <tr style="height:80px"> + <th width='120' align='right' valign='top'>店铺街背景:</th> + <td> + <div id="shopStreetImgPicker" style='margin-left:0px;margin-top:5px;height:30px;overflow:hidden'>上传(首页)店铺街背景图片</div> + <div>图片大小:228 x 138 (px)(格式为 gif, jpg, jpeg, png)</div> + <div style="margin-top:5px;"> + <div class="wst-lfloat shopbanner" {if empty($object.shopStreetImg)}style='display:none'{/if}> + <img id="shopStreetImgPreview" class="lazyImg" height="100" style="max-width:500px;" src="__IMGURL__/{$object.shopStreetImg}"> + <span class="del-banner" onclick="delShopStreetBg(this)">删除</span> + </div> + <input type="hidden" id="shopStreetImg" class="ipt" value="{$object.shopStreetImg}" /> + </div> + </td> + </tr> + + + <tr style="height:80px"> + <th width='120' align='right' valign='top'>顶部广告:</th> + <td> + <div id="shopBannerPicker" style='margin-left:0px;margin-top:5px;height:30px;overflow:hidden'>上传顶部广告图片</div> + <div>图片大小:1920 x 110 (px)(格式为 gif, jpg, jpeg, png)</div> + <div style="margin-top:5px;"> + <div class="wst-lfloat shopbanner" {if empty($object.shopBanner)}style='display:none'{/if}> + <img id="shopBannerPreview" class="lazyImg" height="100" style="max-width:500px;" src="__IMGURL__/{$object.shopBanner}"> + <span class="del-banner" onclick="delbanner(this)">删除</span> + </div> + <input type="hidden" id="shopBanner" class="ipt" value="{$object.shopBanner}" /> + </div> + </td> + </tr> + + + + <tr> + <th width='120' align='right'>滚动广告<font color='red'>*</font>:</th> + <td> + + <div id="batchUpload" class="wst-batchupload" style="border:1px solid #ccc"> + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 图片大小:1200 x 400 (px)(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="placeholder {if !empty($object['shopAds'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['shopAds']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo}"> + </p> + <input type="hidden" v="{$vo}" iv="{$vo}" class="j-gallery-img"> + <span class="btn-del">删除</span> + <input class="cfg-img-url" type="text" value="{$object['shopAdsUrl'][$key]}" style="width:170px;" placeholder="广告路径"> + </li> + {/volist} + </ul> + </div> + <div class="statusBar" > + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + + <div style='clear:both;'></div> + </td> + </tr> + + <tr> + <td colspan='2' style='text-align:center;padding:20px;'> + <a class='s-btn' href="javascript:save()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='javascript:location.reload();'>重&nbsp;置</a> + </td> + </tr> + </table> + + </form> + + + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shopconfigs/shop_cfg.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ +}) +function delbanner(obj){ + var c = WST.confirm({content:'您确定要删除顶部广告图片吗?',yes:function(){ + $('#shopBannerPreview').attr('src',''); + $('#shopBanner').val(''); + $(obj).hide(); + layer.close(c); + }}) + } +function delShopStreetBg(obj){ + var c = WST.confirm({content:'您确定要删除店铺街背景图片吗?',yes:function(){ + $('#shopStreetImgPreview').attr('src',''); + $('#shopStreetImg').val(''); + $(obj).hide(); + layer.close(c); + }}) +} +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.js b/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.js new file mode 100755 index 0000000..a2f32c5 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopconfigs/shop_cfg.js @@ -0,0 +1,124 @@ +function save(){ +/* 表单验证 */ +$('#shopCfg').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + // 图片路径 + var shopAds = []; + $('.j-gallery-img').each(function(){ + shopAds.push($(this).attr('v')); + }); + params.shopAds = shopAds.join(','); + // 图片轮播广告路径 + var shopAdsUrl = []; + $('.cfg-img-url').each(function(){ + shopAdsUrl.push($(this).val()); + }); + params.shopAdsUrl = shopAdsUrl.join(','); + + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + + $.post(WST.U('home/shopconfigs/editShopCfg'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} + + + + + +$(function(){ + //店铺顶部广告图上传 + WST.upload({ + pick:'#shopBannerPicker', + formData: {dir:'shopconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var shopbanner = json.savePath+json.thumb; //保存到数据库的路径 + $('#shopBanner').val(shopbanner); + $('#shopBannerPreview').parent().show(); + $('.del-banner').show(); + $('#shopBannerPreview').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.thumb); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + // 店铺街背景图上传 + WST.upload({ + pick:'#shopStreetImgPicker', + formData: {dir:'shopconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var shopbanner = json.savePath+json.thumb; //保存到数据库的路径 + $('#shopStreetImg').val(shopbanner); + $('#shopStreetImgPreview').parent().show(); + $('.del-banner').show(); + $('#shopStreetImgPreview').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.thumb); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + +/********** 轮播广告图片上传 **********/ +var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shopconfigs'},uploadSuccess:function(file,response){ + var json = WST.toJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" class="j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.append('<input class="cfg-img-url" type="text" value="" style="width:170px;" placeholder="广告路径">' ); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 +$('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + +function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); +} + + +}); \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shoproles/edit.html b/hyhproject/home/view/default/shops/shoproles/edit.html new file mode 100755 index 0000000..a093e29 --- /dev/null +++ b/hyhproject/home/view/default/shops/shoproles/edit.html @@ -0,0 +1,86 @@ +{extend name="default/shops/base" /} +{block name="title"}角色管理-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} + +<div class="wst-body"> +<div class="wst-shop-head"><span>角色管理</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + {php}$homeMenus = WSTHomeMenus(1);{/php} + <form name="shoprole" id="shoprole" autocomplete="off"> + <table class="wst-form"> + <tr> + <th width='120' align='right'>角色名称<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='id' name='id' class="ipt" value='{$object.id}' /> + <input type='text' id='roleName' name='roleName' class="ipt" value='{$object.roleName}' data-rule='请输入角色名称:required;' style='width:350px;' maxLength='25' /> + <span>设定角色名称,方便区分权限类型。</span> + </td> + </tr> + <tr> + <th width='120'>操作权限:</th> + <td> + <div > + {volist name="$homeMenus['menus']" key="k1" id="menus1"} + <dl {$k1==count($homeMenus['menus'])?"style='border-bottom:0'":""}> + <dt class="dt1"> + <label><input type="checkbox" id="{$menus1['menuId']}" class="role_{$menus1['menuId']}" value="{$menus1['menuId']}" onclick="javascript:WST.checkChks(this,'.role_{$menus1['menuId']}')"/> {$menus1["menuName"]}</label> + </dt> + <dd class="dd1"> + {volist name="$menus1['list']" key="k2" id="menus2"} + <dl {$k2==count($menus1['list'])?"style='border-bottom:0'":""}> + <dt class="dt2"> + <label><input type="checkbox" id="{$menus2['menuId']}" class="role_{$menus1['menuId']}" value="{$menus2['menuId']}" onclick="javascript:WST.checkChks(this,'.role_{$menus2['menuId']}')" /> {$menus2["menuName"]}</label> + </dt> + <dd class="dd2"> + {if isset($menus2['list'])} + {volist name="$menus2['list']" id="menus3"} + <label> + + <input type="checkbox" id="{$menus3['menuId']}" name="menuIds" class="role_{$menus1['menuId']} role_{$menus2['menuId']} ipt" value="{$menus3['menuId']}" {if isset($object['menuUrls'])}{:in_array(strtolower($menus3['menuUrl']),$object['menuUrls'])?"checked":""}{/if}/> {$menus3["menuName"]} + </label> + {/volist} + {/if} + </dd> + </dl> + + {/volist} + </dd> + </dl> + {/volist} + </div> + </td> + </tr> + <tr> + <th width='120'>消息接收权限:</th> + <td> + {volist name=":WSTDatas('SHOP_MESSAGE')" id="vo"} + <label> + + <input type="checkbox" name="privilegeMsgs" class="ipt" value="{$vo['dataVal']}" {if $object['privilegeMsgs']}{:in_array($vo['dataVal'],$object['privilegeMsgs'])?"checked":""}{/if}/> {$vo["dataName"]} + + </label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' style='text-align:center;padding:20px;'> + <a class='s-btn' href="javascript:save()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shoproles/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shoproles/shoproles.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shoproles/list.html b/hyhproject/home/view/default/shops/shoproles/list.html new file mode 100755 index 0000000..9ae795f --- /dev/null +++ b/hyhproject/home/view/default/shops/shoproles/list.html @@ -0,0 +1,54 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺角色-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺角色管理</span></div> +<div class='wst-shop-tbar'> + 角色名称:<input type='text' id="roleName" name='roleName' class="s-query" /> + <a class="s-btn" onclick="queryByPage(0)">查询</a> + <a class="s-btn wst-list-add" href='{:url("home/shoproles/add")}'>添加</a> +</div> + +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="300">角色名称</th> + <th>创建时间</th> + <th>操作</th> + </tr> + </thead> + <tbody id='loading' style='display:none'> + <tr class='empty-row'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='4' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i]["roleName"]}}</td> + <td>{{d[i]["createTime"]}}</td> + <td> + <a class="g-handle" href='javascript:toEdit({{d[i]["id"]}})'>[编辑]</a> + <a class="g-handle" href='javascript:del({{d[i]["id"]}})'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shoproles/shoproles.js?v={$v}'></script> +<script> +$(function(){queryByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shoproles/shoproles.js b/hyhproject/home/view/default/shops/shoproles/shoproles.js new file mode 100755 index 0000000..d56f290 --- /dev/null +++ b/hyhproject/home/view/default/shops/shoproles/shoproles.js @@ -0,0 +1,72 @@ + + +function queryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/shoproles/pageQuery'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('#list').empty(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + + }); +} + +function toEdit(id){ + location.href = WST.U('home/shoproles/edit','id='+id); +} + +/**保存角色数据**/ +function save(){ + $('#shoprole').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shoproles/'+((params.id==0)?"toAdd":"toEdit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shoproles/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +//删除角色 +function del(id){ + var c = WST.confirm({content:'您确定要删除该角色吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/shoproles/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + queryByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shops/notice.html b/hyhproject/home/view/default/shops/shops/notice.html new file mode 100755 index 0000000..b79ba55 --- /dev/null +++ b/hyhproject/home/view/default/shops/shops/notice.html @@ -0,0 +1,44 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺公告</span></div> +<div class="wst-clear"></div> + <div class='wst-shop-content' style='margin-top:0px;'> + <table> + <tr> + <td width="7%" style="padding-right:5px;">店铺公告:</td> + <td width="93%"> + <textarea style="width:100%;height:200px;resize:none" placeholder='请保持在150个字以内' class="ipt" id="shopNotice" maxlength='150'>{$notice}</textarea> + </td> + </tr> + </table> + <button onclick="toEdits()" class="wst-shop-but" style="margin-left: 45%;padding: 5px 10px;margin-top: 20px;">保&nbsp;存</button> + </div> +{/block} +{block name="js"} + +<script> +function toEdits(id){ + var params = WST.getParams('.ipt'); + console.log(params.shopNotice.length); + if(params.shopNotice.length>150){ + WST.msg('店铺公告不能超过150个字',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shops/editNotice'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +</script> + + +{/block} diff --git a/hyhproject/home/view/default/shops/shops/shops.js b/hyhproject/home/view/default/shops/shops/shops.js new file mode 100755 index 0000000..6ab2572 --- /dev/null +++ b/hyhproject/home/view/default/shops/shops/shops.js @@ -0,0 +1,76 @@ +var isShopUploadinit = false; +function toEdit(type){ + $('#einfo_'+type).show(); + $('#vinfo_'+type).hide(); + if(!isShopUploadinit){ + isShopUploadinit = true; + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#preview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb); + $('#shopImg').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',$('#serviceStartTime').attr('v')); + initTime('#serviceEndTime',$('#serviceStartTime').attr('v')); + } +} +function initTime($id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $($id).append(html.join('')); +} +function toCancel(type){ + $('#einfo_'+type).hide(); + $('#vinfo_'+type).show(); +} + +function editInfo(){ + $('#editFrom_1').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt_1'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shops/editInfo'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#v_shopImg').attr('src',WST.conf.IMGURL+"/"+params.shopImg); + $('#v_shopQQ').html(params.shopQQ); + $('#v_shopWangWang').html(params.shopWangWang); + if(params.isInvoice==1){ + $('#tr_isInvoice').show(); + $('#v_isInvoice').html("提供发票"); + }else{ + $('#tr_isInvoice').hide(); + $('#v_isInvoice').html("不提供发票"); + } + $('#v_freight').html(params.freight); + $('#v_serviceStartTime').html(params.serviceStartTime); + $('#v_serviceEndTime').html(params.serviceEndTime); + $('#einfo_1').hide(); + $('#vinfo_1').show(); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shops/view.html b/hyhproject/home/view/default/shops/shops/view.html new file mode 100755 index 0000000..8df744a --- /dev/null +++ b/hyhproject/home/view/default/shops/shops/view.html @@ -0,0 +1,246 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺信息-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<style> +label{margin-right:10px;} +</style> +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>店铺信息</li> + <li>银行信息</li> + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;'> + <div class="wst-tab-item" style="position: relative;"> + <table id='vinfo_1' class='wst-form'> + <tr> + <th width='150'>店铺编号:</th> + <td>{$object['shopSn']} + <!--<a href='javascript:toEdit(1)' style='float:right;'>编辑</a>--> + </td> + </tr> + <tr> + <th>店铺名称:</th> + <td>{$object['shopName']}</td> + </tr> + <tr> + <th>店铺联系人:</th> + <td>{$object['shopkeeper']}</td> + </tr> + <tr> + <th>店铺联系电话:</th> + <td>{$object['telephone']}</td> + </tr> + <tr> + <th>公司名称:</th> + <td>{$object['shopCompany']}</td> + </tr> + <tr> + <th>公司坐机电话:</th> + <td>{$object['shopTel']}</td> + </tr> + <tr> + <th>经营类目:</th> + <td>{$object['catshopNames']}</td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {php}$accredLen = count($object['accreds']);{/php} + {volist name="$object['accreds']" id="vo"} + {$vo["accredName"]}{if $i < $accredLen }、{/if} + {/volist} + </td> + </tr> + <tr> + <th>店铺图标:</th> + <td> + <img id='v_shopImg' width='150' height='150' src='__IMGURL__/{$object["shopImg"]}'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td id='v_shopQQ'>{$object['shopQQ']}</td> + </tr> + + <tr> + <th>旺旺:</th> + <td id='v_shopWangWang'>{$object['shopWangWang']}</td> + </tr> + <tr> + <th>店铺地址:</th> + <td> + {$object['areaName']} + </td> + </tr> + <tr> + <th>店铺详细地址:</th> + <td>{$object['shopAddress']}</td> + </tr> + <tr> + <th>是否提供开发票:</th> + <td id='v_isInvoice'> + {if $object['isInvoice']==1}提供发票{/if} + {if $object['isInvoice']==0}不提供发票{/if} + </td> + </tr> + <tr id='tr_isInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明:</th> + <td id='v_invoiceRemarks'>{$object['invoiceRemarks']}</td> + </tr> + <tr> + <th>默认运费:</th> + <td >¥<span id='v_freight'>{$object['freight']}</span></td> + </tr> + <tr> + <th>服务时间:</th> + <td><span id='v_serviceStartTime'>{$object['serviceStartTime']}</span>至<span id='v_serviceEndTime'>{$object['serviceEndTime']}</span> + </td> + </tr> + + <!-- mark by cheng 添加更明显的编辑信息按钮--> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href='javascript:toEdit(1)'>编辑信息</a> + + </td> + </tr> + </table> + <div></div> + <form id='editFrom_1' autocomplete="off"> + <table id='einfo_1' class='wst-form hide'> + <tr> + <th width='150'>店铺图标<font color='red'>*</font>:</th> + <td> + <img id='preview' width='150' height='150' src='__IMGURL__/{$object["shopImg"]}'/> + <div id='shopImgPicker'>请上传店铺图标</div><span id='uploadMsg'></span> + <input type='hidden' id='shopImg' class='ipt_1' value='{$object["shopImg"]}'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td> + <input class="ipt_1" id="shopQQ" value="{$object['shopQQ']}" type="text" style='width:60%'> + </td> + </tr> + <tr> + <th> </th> + <td> + <span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span> + </td> + </tr> + <tr> + <th>旺旺类型<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='0' class="ipt_1" name='shopWangWangType'{if $object['shopWangWangType']==0}checked{/if}/>淘宝旺旺 + </label> + <label> + <input type='radio' value='1' class="ipt_1" name='shopWangWangType'{if $object['shopWangWangType']==1}checked{/if}/>阿里旺旺(1688诚信通) + </label> + + </td> + </tr> + <tr> + <th>旺旺号:</th> + <td><input class="ipt_1" id="shopWangWang" value="{$object['shopWangWang']}" type="text" style='width:60%'></td> + </tr> + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='1' class="ipt_1" name='isInvoice' onclick='javascript:WST.showHide(1,"#trInvoice")' {if $object['isInvoice']==1}checked{/if}/>提供 + </label> + <label> + <input type='radio' value='0' class="ipt_1" name='isInvoice' onclick='javascript:WST.showHide(0,"#trInvoice")' {if $object['isInvoice']==0}checked{/if}/>不提供 + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="invoiceRemarks" value="{$object['invoiceRemarks']}" type="text" style='width:60%' data-rule="发票说明:required(#isInvoice1:checked)"></td> + </tr> + <tr> + <th>默认运费<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="freight" value="{$object['freight']}" size='5' maxlength="10" data-rule="默认运费:required;" type="text">¥</td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt_1' id='serviceStartTime' v="{$object['serviceStartTime']}"></select> + 至 + <select class='ipt_1' id='serviceEndTime' v="{$object['serviceEndTime']}"></select> + </td> + </tr> + <tr> + <th><font color='red'>小提示*</font>:</th> + <td>银行结算信息只能修改一次,除非必要请不要修改,当前修改次数:<font color='red'>({$object['changeNum']})</font>次</td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' class='ipt_1' data-rule='结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + + <tr> + <th>卡号<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="bankNo" value="{$object['bankNo']}" type="text" style='width:60%'></td> + </tr> + <tr> + <th>持卡人<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="bankUserName" value="{$object['bankUserName']}" type="text" style='width:60%'></td> + </tr> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href='javascript:editInfo()'>保存</a> + <a class='s-btn2' href='javascript:toCancel(1)'>取消</a> + </td> + </tr> + </table> + </form> + </div> + <div class="wst-tab-item" style="display:none;"> + <table class='wst-form'> + <tr> + <th width='150'>开卡银行:</th> + <td>{$object['bankName']}</td> + + </tr> + <!-- + <tr> + <th width='150'>开卡地区:</th> + <td>{$object['bankAreaName']}</td> + </tr> + --> + <tr> + <th>卡号:</th> + <td>{$object['bankNo']}</td> + </tr> + <tr> + <th>持卡人:</th> + <td>{$object['bankUserName']}</td> + </tr> + + </table> + </div> + + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/shops/shops/shops.js?v={$v}'></script> +<script> +$(function(){ + $('#tab').TabPanel({tab:0,callback:function(no){}}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopusers/add.html b/hyhproject/home/view/default/shops/shopusers/add.html new file mode 100755 index 0000000..2b326f7 --- /dev/null +++ b/hyhproject/home/view/default/shops/shopusers/add.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}新增帐号-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>新增帐号</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + <form name="editForm" id="editForm" autocomplete="off"> + <table class='wst-form uinfo-form' > + <tr> + <td width="100"><font color='red'>*</font>用户名</td> + <td class="uinfo"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type='hidden' id='id' name='id' class="ipt" value='0' /> + <input id="loginName" name="loginName" class="ipt wst-regist-input" tabindex="1" maxlength="30" autocomplete="off" onpaste="return false;" style="ime-mode:disabled;" placeholder="邮箱/用户名/手机号" data-rule='请输入用户名:required;' type="text" onkeyup="javascript:WST.isChinese(this,1)"/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>密码</td> + <td class="uinfo"> + <input id="loginPwd" name="loginPwd" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符" data-rule='请输入密码:required;'/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>确认密码</td> + <td class="uinfo"> + <input id="reUserPwd" name="reUserPwd" class="ipt wst-regist-input" tabindex="3" autocomplete="off" type="password" placeholder="6-16位字符" data-rule="确认密码: required; match(loginPwd)"/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>角色</td> + <td> + <select id="roleId" data-rule="required" class="ipt"> + {volist name="roles" id="role"} + <option value="{$role['id']}">{$role["roleName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href="javascript:add()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shopusers/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopusers/edit.html b/hyhproject/home/view/default/shops/shopusers/edit.html new file mode 100755 index 0000000..a0e111f --- /dev/null +++ b/hyhproject/home/view/default/shops/shopusers/edit.html @@ -0,0 +1,80 @@ +{extend name="default/shops/base" /} +{block name="title"}编辑帐号-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>编辑帐号</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + <form name="editForm" id="editForm" autocomplete="off"> + <table class='wst-form uinfo-form' > + <tr> + <td colspan="2"> + <div class='wst-tips-box'> + <div class='icon'></div> + <div class='tips'> + 1.新密码为空,则不修改帐号密码。<br/> + 2.店铺管理员不能修改角色。</div> + <div style="clear:both"></div> + </div> + </td> + </tr> + <tr> + <td width="100"><font color='red'>*</font>帐号名</td> + <td class="uinfo"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type='hidden' id='id' name='id' class="ipt" value='{$object["id"]}' /> + {$object["loginName"]} + </td> + </tr> + <tr> + <td>原密码</td> + <td class="uinfo"> + <input id="oldPass" name="oldPass" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符"/> + </td> + </tr> + <tr> + <td>新密码</td> + <td class="uinfo"> + <input id="newPass" name="newPass" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符"/> + </td> + </tr> + <tr> + <td>确认新密码</td> + <td class="uinfo"> + <input id="reNewPass" name="reNewPass" class="ipt wst-regist-input" tabindex="3" autocomplete="off" type="password" placeholder="6-16位字符" data-rule="确认密码: match(newPass)"/> + </td> + </tr> + {if $object["roleId"]>0} + <tr> + <td><font color='red'>*</font>角色</td> + <td> + <select id="roleId" data-rule="required" class="ipt"> + {volist name="roles" id="role"} + <option value="{$role['id']}" {if $object["roleId"]==$role['id']}selected{/if}>{$role["roleName"]}</option> + {/volist} + </select> + </td> + </tr> + {/if} + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href="javascript:edit()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shopusers/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopusers/list.html b/hyhproject/home/view/default/shops/shopusers/list.html new file mode 100755 index 0000000..4687e6d --- /dev/null +++ b/hyhproject/home/view/default/shops/shopusers/list.html @@ -0,0 +1,57 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺用户管理-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺帐号管理</span></div> +<div class='wst-shop-tbar'> + 帐号名:<input type='text' id="userName" class="s-query" id='userName'/> + <a class="s-btn" onclick="queryByPage(0)">查询</a> + <a class="s-btn wst-list-add" href='{:url("home/shopusers/add")}'>添加</a> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="200">帐号名</th> + <th width="200">角色名称</th> + <th>创建时间</th> + <th>操作</th> + </tr> + </thead> + <tbody id='loading' style='display:none'> + <tr class='empty-row'> + <td colspan='5'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='5' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i]["loginName"]}}</td> + <td>{{d[i]["roleId"]?d[i]["roleName"]:"管理员"}}</td> + <td>{{d[i]["createTime"]}}</td> + <td> + <a class="g-handle" href='javascript:toEdit({{d[i]["id"]}})'>[编辑]</a> + {{# if(d[i]["roleId"]>0){ }} + <a class="g-handle" href='javascript:del({{d[i]["id"]}})'>[删除]</a> + {{# } }} + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script> +$(function(){queryByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/shopusers/shopusers.js b/hyhproject/home/view/default/shops/shopusers/shopusers.js new file mode 100755 index 0000000..36592cb --- /dev/null +++ b/hyhproject/home/view/default/shops/shopusers/shopusers.js @@ -0,0 +1,110 @@ + + +function queryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/shopusers/pageQuery'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('#list').empty(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + + }); +} + +function toEdit(id){ + location.href = WST.U('home/shopusers/edit','id='+id); +} + +/**保存角色数据**/ +function add(){ + $('#editForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(WST.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.reUserPwd = rsa.encrypt(params.reUserPwd); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopusers/toAdd'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shopusers/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function edit(){ + $('#editForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(WST.conf.IS_CRYPT=='1' && params.newPass!=""){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.oldPass = rsa.encrypt(params.oldPass); + params.newPass = rsa.encrypt(params.newPass); + params.reNewPass = rsa.encrypt(params.reNewPass); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopusers/toEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shopusers/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +//删除角色 +function del(id){ + var c = WST.confirm({content:'删除店铺管理帐号,只是删除该帐号与店铺的关系,您确定要删除吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/shopusers/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + queryByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/stockwarn/list.html b/hyhproject/home/view/default/shops/stockwarn/list.html new file mode 100755 index 0000000..4b878a3 --- /dev/null +++ b/hyhproject/home/view/default/shops/stockwarn/list.html @@ -0,0 +1,110 @@ +{extend name="default/shops/base" /} +{block name="title"}库存预警 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>库存预警</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + <a class="s-btn" onclick="stockByPage()" style='margin-top:5px;'>查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="220">商品名称</th> + <th>货号</th> + <th>规格</th> + <th width="130">库存<font color='red'>(红色双击编辑)</font></th> + <th width="130">预警<font color='red'>(红色双击编辑)</font></th> + <th width="120">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + {{# if(d[i]['isSpec']==1) { }} + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-goodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + <td> + <span class="spec"> + {{# for(var s = 0; s < d[i].spec.length; s++){ }} + {{d[i].spec[s]['catName']}}:{{d[i].spec[s]['itemName']}}; + {{# } }} + </span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['id']}},1)"> + <input id="ipt_1_{{d[i]['id']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['id']}},1,{{d[i]['goodsId']}})" class="stockin" maxlength="6"/> + <span id="span_1_{{d[i]['id']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['goodsStock']}}</span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['id']}},2)"> + <input id="ipt_2_{{d[i]['id']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['id']}},2,{{d[i]['goodsId']}})" class="stockin" maxlength="6"/> + <span id="span_2_{{d[i]['id']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['warnStock']}}</span> + </td> + <td><a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[进入商品编辑]</a></td> + {{# }else{ }} + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-goodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + <td>无</td> + {{# if(d[i]['goodsType']==0){ }} + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['goodsId']}},3)"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['goodsId']}},3)" class="stockin" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['goodsStock']}}</span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['goodsId']}},4)"> + <input id="ipt_4_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['goodsId']}},4)" class="stockin" maxlength="6"/> + <span id="span_4_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['warnStock']}}</span> + </td> + {{# }else{ }} + <td width="40">{{d[i]['goodsStock']}}</td> + <td width="40">{{d[i]['warnStock']}}</td> + {{#}}} + <td> + {{#if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"stockWarnByPage")'>[进入卡券编辑]</a> + {{#}else{}} + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[进入商品编辑]</a> + {{#}}} + </td> + + {{# } }} + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/stockwarn/stockwarn.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home/view/default/shops/stockwarn/stockwarn.js b/hyhproject/home/view/default/shops/stockwarn/stockwarn.js new file mode 100755 index 0000000..ba866da --- /dev/null +++ b/hyhproject/home/view/default/shops/stockwarn/stockwarn.js @@ -0,0 +1,95 @@ +$(function(){ + stockByPage(); +}); +function toStock(id,src){ + location.href=WST.U('home/goodsvirtuals/stock','id='+id+"&src="+src); +} +function stockByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/goods/stockByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + stockByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function toEdit(id,src){ + location.href = WST.U('home/goods/edit','id='+id+'&src='+src); +} +//双击修改 +function toEditGoodsStock(id,type){ + $("#ipt_"+type+"_"+id).show(); + $("#span_"+type+"_"+id).hide(); + $("#ipt_"+type+"_"+id).focus(); + $("#ipt_"+type+"_"+id).val($("#span_"+type+"_"+id).html()); +} +function endEditGoodsStock(type,id){ + $('#span_'+type+'_'+id).html($('#ipt_'+type+'_'+id).val()); + $('#span_'+type+'_'+id).show(); + $('#ipt_'+type+'_'+id).hide(); +} +function editGoodsStock(id,type,goodsId){ + var number = $('#ipt_'+type+'_'+id).val(); + if($.trim(number)==''){ + WST.msg('库存不能为空', {icon: 5}); + return; + } + var params = {}; + params.id = id; + params.type = type; + params.goodsId = goodsId; + params.number = number; + $.post(WST.U('Home/Goods/editwarnStock'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + $('#img_'+type+'_'+id).fadeTo("fast",100); + endEditGoodsStock(type,id); + $('#img_'+type+'_'+id).fadeTo("slow",0); + }else{ + WST.msg(json.msg, {icon: 5}); + } + }); +} + +function getCat(val){ + if(val==''){ + $('#cat2').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + }); +} \ No newline at end of file diff --git a/hyhproject/home/view/default/top.html b/hyhproject/home/view/default/top.html new file mode 100755 index 0000000..1fcab84 --- /dev/null +++ b/hyhproject/home/view/default/top.html @@ -0,0 +1,191 @@ + +{wst:ads code="index-top-ads" cache='86400' id="tads"} +{if ($tads['adFile']!='')} +<div class="index-top-ads"> + <a href="{$tads['adURL']}" {if ($tads['isOpen'])}target='_blank'{/if} {if ($tads['adURL']!='')}onclick="WST.recordClick({$tads['adId']})"{/if} onfocus="this.blur();"> + <img src="__IMGURL__/{$tads['adFile']}"></a> + <a href="javascript:;" class="close-ads" onclick="WST.closeAds(this)"></a> +</div> +{/if} +{/wst:ads} + +<div class="wst-header"> + <div class="wst-nav"> + <ul class="headlf"> + {if condition="session('WST_USER.userId') >0"} + <li class="drop-info"> + <div class="drop-infos"> + <a href="{:Url('home/users/index')}">欢迎您,{:session('WST_USER.userName')?session('WST_USER.userName'):session('WST_USER.loginName')}</a> + </div> + <div class="wst-tag dorpdown-user"> + <div class="wst-tagt"> + <div class="userImg" > + <img class='usersImg' data-original="__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}"/> + </div> + <div class="wst-tagt-n"> + <div> + <span class="wst-tagt-na">{:session('WST_USER.userName')?session('WST_USER.userName'):session('WST_USER.loginName')}</span> + {if (int)session('WST_USER.rankId') > 0 } + <img src="__IMGURL__/{:session('WST_USER.userrankImg')}" title="{:session('WST_USER.rankName')}"/> + {/if} + </div> + <div class='wst-tags'> + <span class="w-lfloat"><a onclick='WST.position(15,0)' href='{:Url("home/users/edit")}'>用户资料</a></span> + <span class="w-lfloat" style="margin-left:10px;"><a onclick='WST.position(16,0)' href='{:Url("home/users/security")}'>安全设置</a></span> + </div> + </div> + <div class="wst-tagb" > + <a onclick='WST.position(5,0)' href='{:Url("home/orders/waitReceive")}'>待收货订单</a> + <a onclick='WST.position(60,0)' href='{:Url("home/logmoneys/usermoneys")}'>我的余额</a> + <a onclick='WST.position(49,0)' href='{:Url("home/messages/index")}'>我的消息</a> + <a onclick='WST.position(13,0)' href='{:Url("home/userscores/index")}'>我的积分</a> + <a onclick='WST.position(41,0)' href='{:Url("home/favorites/goods")}'>我的关注</a> + <a style='display:none'>咨询回复</a> + </div> + <div class="wst-clear"></div> + </div> + </div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <a href='{:Url("home/messages/index")}' target='_blank' onclick='WST.position(49,0)'>消息(<span id='wst-user-messages'>0</span>)</a> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="javascript:WST.logout();">退出</a></div> + </li> + {else /} + <li class="drop-info"> + <div>欢迎来到{:WSTMSubstr(WSTConf('CONF.mallName'),0,13)}<a href="{:Url('home/users/login')}" onclick="WST.currentUrl();">&nbsp;&nbsp;请&nbsp;登录</a></div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="{:Url('home/users/regist')}" onclick="WST.currentUrl();">免费注册</a></div> + </li> + {/if} + </ul> + <ul class="headrf" style='float:right;'> + <li class="j-dorpdown" style="width: 86px;"> + <div class="drop-down" style="padding-left:0px;"> + <a href="{:Url('home/users/index')}" target="_blank">我的订单<i class="di-right"><s>◇</s></i></a> + </div> + <div class='j-dorpdown-layer order-list'> + <div><a href='{:Url("home/orders/waitPay")}' onclick='WST.position(3,0)'>待付款订单</a></div> + <div><a href='{:Url("home/orders/waitReceive")}' onclick='WST.position(5,0)'>待发货订单</a></div> + <div><a href='{:Url("home/orders/waitAppraise")}' onclick='WST.position(6,0)'>待评价订单</a></div> + </div> + </li> + {if(WSTDatas('ADS_TYPE',4))} + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down2 pdr5"><i class="di-left"></i><a href="#" target="_blank">手机商城</a></div> + <div class='j-dorpdown-layer sweep-list'> + <div class="qrcodea"> + <div id='qrcodea' class="qrcodeal"></div> + <div class="qrcodear"> + <p>扫描二维码</p><span>下载手机客户端</span> + <br/> + <a >Android</a> + <br/> + <a>iPhone</a> + </div> + </div> + </div> + </li> + {/if} + {if(WSTConf('CONF.wxenabled')==1)} + <li class="spacer">|</li> + <li class="j-dorpdown" style="width:78px;"> + <div class="drop-down" style="padding:0 5px;"><a href="#" target="_blank">关注我们</a></div> + <div class='j-dorpdown-layer des-list' style="width:120px;"> + <div style="height:114px;">{if(WSTConf('CONF.wxAppLogo'))}<img src="__IMGURL__/{:WSTConf('CONF.wxAppLogo')}" style="height:114px;">{/if}</div> + <div>关注我们</div> + </div> + </li> + {/if} + <li class="spacer">|</li> + <li class="j-dorpdown" style="width:78px;"> + <div class="drop-down" style="padding:0 5px;"><a href="#" target="_blank">下载APP</a></div> + <div class='j-dorpdown-layer des-list' style="width:120px;"> + <div style="height:114px;"><img src="http://img.juzi199.com/upload/sysconfigs/app.jpg" style="height:114px;"></div> + <div>下载APP</div> + </div> + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down4 pdr5"><a href="#" target="_blank">我的收藏</a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:Url('home/favorites/goods')}" onclick='WST.position(41,0)'>商品收藏</a></div> + <div><a href="{:Url('home/favorites/shops')}" onclick='WST.position(46,0)'>店铺收藏</a></div> + </div> + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down5 pdr5" ><a href="#" target="_blank">客户服务</a></div> + <div class='j-dorpdown-layer des-list'> + <div><a href='{:Url("home/helpcenter/view","id=1")}' target='_blank'>帮助中心</a></div> + <div><a href='{:Url("home/helpcenter/view","id=8")}' target='_blank'>售后服务</a></div> + <div><a href='{:Url("home/helpcenter/view","id=3")}' target='_blank'>常见问题</a></div> + </div> + </li> + <li class="spacer">|</li> + {if condition="session('WST_USER.userId') gt 0"} + {if condition="session('WST_USER.userType') eq 0"} + <li class="j-dorpdown"> + <div class="drop-down pdl5" ><a href="#" target="_blank">{if empty($is_icp)}商家管理{else /}后台管理{/if}<i class="di-right"><s>◇</s></i></a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:url('home/shops/login')}" onclick="WST.currentUrl();">{if empty($is_icp)}商家登录{else /}后台登录{/if}</a></div> + {if empty($is_icp)}<div><a href="{:url('home/shops/join')}" rel="nofollow" onclick="WST.currentUrl('{:url("home/shops/join")}');">商家入驻</a></div>{/if} + </div> + </li> + + {else /} + <li class="j-dorpdown"> + <div class="drop-down pdl5" > + <a href="{:Url('home/shops/index')}" rel="nofollow" target="_blank">卖家中心<i class="di-right"><s>◇</s></i></a> + </div> + <div class='j-dorpdown-layer product-list last-menu'> + <div><a href='{:Url("home/orders/waitdelivery")}' onclick='WST.position(24,1)'>待发货订单</a></div> + <div><a href='{:Url("home/orders/waitdelivery")}' onclick='WST.position(25,1)'>投诉订单</a></div> + <div><a href='{:Url("home/home/goods/sale")}' onclick='WST.position(32,1)'>商品管理</a></div> + <div><a href='{:Url("home/shopcats/index")}' onclick='WST.position(30,1)'>商品分类</a></div> + </div> + </li> + {/if} + {else /} + <li class="j-dorpdown"> + <div class="drop-down pdl5" ><a href="#" target="_blank">{if empty($is_icp)}商家管理{else /}后台管理{/if}<i class="di-right"><s>◇</s></i></a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:url('home/shops/login')}" onclick="WST.currentUrl();">{if empty($is_icp)}商家登录{else /}后台登录{/if}</a></div> + {if empty($is_icp)}<div><a href="{:url('home/shops/join')}" rel="nofollow" onclick="WST.currentUrl('{:url("home/shops/join")}');">商家入驻</a></div>{/if} + </div> + </li> + + {/if} + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down5 pdr5" ><a href='{:Url("/newscats-63")}' target="_blank">行业资讯(收费)</a></div> + <div class='j-dorpdown-layer des-list'> + + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> +</div> +<script> +$(function(){ + //二维码 + //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围'L','M','Q','H' + var a = qrcode(8, 'M'); + var url = window.location.host+window.conf.APP; + a.addData(url); + a.make(); + $('#qrcodea').html(a.createImgTag()); +}); +function goShop(id){ + location.href=WST.U('home/shops/home','shopId='+id); +} +</script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> \ No newline at end of file diff --git a/hyhproject/home2/behavior/InitConfig.php b/hyhproject/home2/behavior/InitConfig.php new file mode 100755 index 0000000..7e6c240 --- /dev/null +++ b/hyhproject/home2/behavior/InitConfig.php @@ -0,0 +1,23 @@ +<?php +namespace wstmart\home\behavior; +/** + * ============================================================================ + * 初始化基础数据 + */ +class InitConfig +{ + public function run(&$params){ + WSTConf('protectedUrl',model('HomeMenus')->getMenusUrl()); + // 检测手机端访问 + $request = request(); + $currModel = $request->module(); + + hook('initConfigHook',['getParams'=>input()]); + + if($request->isMobile() && $currModel=='home'){ + $url = url('mobile/index/index'); + header("location:$url"); + die; + } + } +} \ No newline at end of file diff --git a/hyhproject/home2/behavior/ListenProtectedUrl.php b/hyhproject/home2/behavior/ListenProtectedUrl.php new file mode 100755 index 0000000..47f3fb8 --- /dev/null +++ b/hyhproject/home2/behavior/ListenProtectedUrl.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\home\behavior; +/** + * ============================================================================ + * 检测用户有没有登录和访问权限 + */ +class ListenProtectedUrl +{ + public function run(&$params){ + $request = request(); + $urls = WSTConf('protectedUrl'); + $visit = strtolower($request->module()."/".$request->controller()."/".$request->action()); + + //受保护资源进来检测身份 + if(isset($urls[$visit])){ + $menuType = (int)$urls[$visit]; + $userType = -1; + if((int)session('WST_USER.userId')>0)$userType = 0; + //if((int)session('WST_USER.shopId')>0)$userType = 1; + if((int)session('WST_USER.userType')>0)$userType = 1; + //未登录不允许访问受保护的资源 + if($userType==-1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您还没有登录,请先登录']); + }else{ + header("Location:".url('home/users/login')); + } + exit(); + } + //已登录但不是商家 则不允许访问受保护的商家资源 + if($userType==0 && $menuType==1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您不是商家,请先申请为商家再访问']); + }else{ + header("Location:".url('home/shops/login')); + } + exit(); + } + //商家角色权限 + if(((int)session('WST_USER.roleId')>0) && $userType==1 && $menuType==1){ + $shopMenuUrls = model('HomeMenus')->getShopMenusUrl(); + if(!in_array($visit,$shopMenuUrls)){ + header("Location:".url('home/error/index')); + exit(); + } + } + } + } +} \ No newline at end of file diff --git a/hyhproject/home2/common/function.php b/hyhproject/home2/common/function.php new file mode 100755 index 0000000..4ae25d1 --- /dev/null +++ b/hyhproject/home2/common/function.php @@ -0,0 +1,171 @@ +<?php +use think\Db; +use think\Session; +/** + * ============================================================================ + */ +/** + * 查询网站帮助 + * @param $pnum 父级记录数 + * @param $cnum 子记录数 + */ +function WSTHelps($pnum = 5,$cnum = 5){ + $cats = Db::table('__ARTICLE_CATS__')->where(['catType'=>1, 'dataFlag'=>1, 'isShow' => 1, 'parentId'=>7]) + ->field("catName,catId")->order('catSort asc')->limit($pnum)->select(); + if(!empty($cats)){ + foreach($cats as $key =>$v){ + $cats[$key]['articlecats'] = Db::table('__ARTICLES__')->where(['dataFlag'=>1,'isShow' => 1,'catId'=>$v['catId']]) + ->field("articleId, catId, articleTitle")->order('createTime asc')->limit($cnum)->select(); + } + } + return $cats; +} + +/** + * 获取前台菜单 + */ +function WSTHomeMenus($menuType){ + $m1 = array(); + if($menuType==1){ + $m1 = model('home/HomeMenus')->getShopMenus(); + }else{ + $m1 = model('home/HomeMenus')->getMenus(); + } + $menuId1 = (int)input("get.homeMenuId"); + $menus = []; + $menus['menus'] = $m1[$menuType]; + //判断menuId1是否有效 + if($menuId1==0){ + $menuId1 = (int)session('WST_MENID'.$menuType); + }else{ + session('WST_MENID'.$menuType,$menuId1); + } + //检测第一级菜单是否有效 + $tmpMenuId1 = 0; + $isFind = false; + foreach ($menus['menus'] as $key => $v){ + if($tmpMenuId1==0)$tmpMenuId1 = $key; + if($key==$menuId1)$isFind = true; + } + if($isFind){ + $menus['menuId1'] = $menuId1; + }else{ + $menus['menuId1'] = $tmpMenuId1; + } + $menus['menuId3'] = session('WST_MENUID3'.$menuType); + return $menus; +} +/** + * 获取指定父级的商家店铺分类 + */ +function WSTShopCats($parentId){ + $shopId = (int)session('WST_USER.shopId'); + $dbo = Db::table('__SHOP_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>$parentId,'shopId'=>$shopId]); + // return $dbo->field("catName,catId")->order('catSort asc')->select(); + // mark 20180518 by zl + return $dbo->field("catName,catId,provName")->order('catSort asc')->select(); +} +/** + * 获取商城搜索关键字 + */ +function WSTSearchKeys(){ + $keys = WSTConf("CONF.hotWordsSearch"); + if($keys!='')$keys = explode(',',$keys); + return $keys; +} +/** + * 获取首页左侧分类、推荐品牌和广告 + */ +function WSTSideCategorys(){ + $data = cache('WST_SIDE_CATS'); + if(!$data){ + $cats1 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>0])->field("catName,catId,catImg")->order('catSort asc')->select(); + if(count($cats1)>0){ + $ids1 = [];$ids2 = [];$cats2 = [];$cats3 = [];$mcats3 = [];$mcats2 = []; + foreach ($cats1 as $key =>$v){ + $ids1[] = $v['catId']; + } + $tmp2 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids1]])->field("catName,catId,parentId,catImg")->order('catSort asc')->select(); + if(count($tmp2)>0){ + foreach ($tmp2 as $key =>$v){ + $ids2[] = $v['catId']; + } + $tmp3 = Db::table('__GOODS_CATS__')->where(['dataFlag'=>1, 'isShow' => 1,'parentId'=>['in',$ids2]])->field("catName,catId,parentId,catImg")->order('catSort asc')->select(); + if(count($tmp3)>0){ + //组装第三级 + foreach ($tmp3 as $key =>$v){ + $mcats3[$v['parentId']][] = $v; + } + } + //组装第二级 + foreach ($tmp2 as $key =>$v){ + if(isset($mcats3[$v['catId']]))$v['list'] = $mcats3[$v['catId']]; + $mcats2[$v['parentId']][] = $v; + } + //组装第一级 + foreach ($cats1 as $key =>$v){ + if(isset($mcats2[$v['catId']]))$cats1[$key]['list'] = $mcats2[$v['catId']]; + } + } + unset($ids1,$ids2,$cats2,$cats3,$mcats3,$mcats2); + } + cache('WST_SIDE_CATS',$cats1); + return $cats1; + } + return $data; +} + +/** + * 获取导航菜单 + */ +function WSTNavigations($navType){ + $data = cache('WST_NAVS'); + if(!$data){ + $rs = Db::table('__NAVS__')->where(['isShow'=>1,'navType'=>$navType])->order('navSort asc')->select(); + foreach ($rs as $key => $v){ + if(stripos($v['navUrl'],'https://')===false && stripos($v['navUrl'],'http://')===false){ + $rs[$key]['navUrl'] = str_replace('/index.php','',\think\Request::instance()->root())."/".$v['navUrl']; + } + } + cache('WST_NAVS',$data); + return $rs; + } + return $data; +} +/** + * 根据指定的商品分类获取其路径 + */ +function WSTPathGoodsCat($catId,$data = array()){ + $rs = Db::table('__GOODS_CATS__')->where(['isShow'=>1,'dataFlag'=>1,'catId'=>$catId])->field("parentId,catName,catId")->find(); + $data[] = $rs; + if($rs['parentId']==0){; + krsort($data); + return $data; + }else{ + return WSTPathGoodsCat($rs['parentId'],$data); + } +} +/** + * 处理商家结算信息提示 + */ +function WSTShopMessageBox(){ + $USER = session('WST_USER'); + $msg = []; + if($USER['shopMoney']<0){ + $msg[] = '您的账户欠费¥'.$USER['shopMoney'].',请及时充值。'; + } + if(($USER['noSettledOrderFee']+$USER['paymentMoney'])<0 && (($USER['shopMoney']+$USER['noSettledOrderFee']+$USER['paymentMoney'])<0)){ + $msg[] = '您的账户余额【¥'.$USER['shopMoney'].'】不足以缴纳订单佣金【¥'.(-1*($USER['noSettledOrderFee']+$USER['paymentMoney'])).'】,请及时充值。'; + } + return implode('||',$msg); +} +/** +* 根据商品id,返回是否已关注商品 +*/ +function WSTCheckFavorite($goodsId,$type=0){ + $userId = (int)session('WST_USER.userId'); + if($userId>0){ + return model('common/favorites')->checkFavorite($goodsId,$type); + } + return false; +} \ No newline at end of file diff --git a/hyhproject/home2/conf/config.php b/hyhproject/home2/conf/config.php new file mode 100755 index 0000000..4fb921a --- /dev/null +++ b/hyhproject/home2/conf/config.php @@ -0,0 +1,19 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'p', + 'list_rows' => 15, + ], +]; diff --git a/hyhproject/home2/controller/Ads.php b/hyhproject/home2/controller/Ads.php new file mode 100755 index 0000000..e2299c6 --- /dev/null +++ b/hyhproject/home2/controller/Ads.php @@ -0,0 +1,16 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Ads as M; +/** + * ============================================================================ + * 广告控制器 + */ +class Ads extends Base{ + /** + * 记录点击次数 + */ + public function recordClick(){ + $m = new M(); + return $m->recordClick(); + } +} diff --git a/hyhproject/home2/controller/Alipays.php b/hyhproject/home2/controller/Alipays.php new file mode 100755 index 0000000..a38aa6d --- /dev/null +++ b/hyhproject/home2/controller/Alipays.php @@ -0,0 +1,283 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +use wstmart\common\model\ChargeItems as CM; +/** + * ============================================================================ + * 阿里支付控制器 + */ +class Alipays extends Base{ + + /** + * 初始化 + */ + private $aliPayConfig; + public function _initialize() { + $this->aliPayConfig = array(); + $m = new M(); + $this->aliPayConfig = $m->getPayment("alipays"); + } + + /** + * 生成支付代码 + */ + function getAlipaysUrl(){ + $payObj = input("payObj/s"); + $m = new OM(); + $obj = array(); + $data = array(); + $orderAmount = 0; + $out_trade_no = ""; + $extra_common_param = ""; + $subject = ""; + $body = ""; + if($payObj=="recharge"){//充值 + $itmeId = (int)input("itmeId/d"); + $orderAmount = 0; + if($itmeId>0){ + $cm = new CM(); + $item = $cm->getItemMoney($itmeId); + $orderAmount = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $orderAmount = (int)input("needPay/d"); + } + + $shopId = (int)session('WST_USER.shopId'); + $targetType = ($shopId>0)?1:0; + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = $shopId; + } + $data["status"] = $orderAmount>0?1:-1; + $out_trade_no = WSTOrderNo(); + $extra_common_param = $payObj."@".$targetId."@".$targetType."@".$itmeId; + $subject = '钱包充值 ¥'.$orderAmount.'元'; + $body = '钱包充值'; + }else{ + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $data = $m->checkOrderPay($obj); + if($data["status"]==1){ + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $order = $m->getPayOrders($obj); + $orderAmount = $order["needPay"]; + $payRand = $order["payRand"]; + $out_trade_no = $obj["orderNo"]."a".$payRand; + $extra_common_param = $payObj."@".$userId."@".$obj["isBatch"]; + $subject = '支付购买商品费用'.$orderAmount.'元'; + $body = '支付订单费用'; + } + } + + if($data["status"]==1){ + $return_url = url("home/alipays/response","",true,true); + $notify_url = url("home/alipays/aliNotify","",true,true); + $parameter = array( + 'extra_common_param'=> $extra_common_param, + 'service' => 'create_direct_pay_by_user', + 'partner' => $this->aliPayConfig['parterID'], + '_input_charset' => "utf-8", + 'notify_url' => $notify_url, + 'return_url' => $return_url, + /* 业务参数 */ + 'subject' => $subject, + 'body' => $body, + 'out_trade_no' => $out_trade_no, + 'total_fee' => $orderAmount, + 'quantity' => 1, + 'payment_type' => 1, + /* 物流参数 */ + 'logistics_type' => 'EXPRESS', + 'logistics_fee' => 0, + 'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE', + /* 买卖双方信息 */ + 'seller_email' => $this->aliPayConfig['payAccount'] + ); + ksort($parameter); + reset($parameter); + $param = ''; + $sign = ''; + foreach ($parameter AS $key => $val){ + $param .= "$key=" .urlencode($val). "&"; + $sign .= "$key=$val&"; + } + $param = substr($param, 0, -1); + $sign = substr($sign, 0, -1). $this->aliPayConfig['parterKey']; + $url = 'https://mapi.alipay.com/gateway.do?'.$param. '&sign='.md5($sign).'&sign_type=MD5'; + $data["url"] = $url; + } + + return $data; + } + + /** + * 支付结果同步回调 + */ + function response(){ + $m = new OM(); + $request = $_GET; + unset($request['_URL_']); + $payRes = self::notify($request); + if($payRes['status']){ + $extras = explode("@",$_GET['extra_common_param']); + if($extras[0]=="recharge"){//充值 + if($extras[2]==1){ + $this->redirect(url("home/logmoneys/shopmoneys")); + }else{ + $this->redirect(url("home/logmoneys/usermoneys")); + } + }else{ + $this->redirect(url("home/alipays/paysuccess")); + } + }else{ + $this->error('支付失败'); + } + } + + /** + * 支付结果异步回调 + */ + function aliNotify(){ + $m = new OM(); + $request = $_POST; + $payRes = self::notify($request); + if($payRes['status']){ + + $extras = explode("@",$_POST['extra_common_param']); + $rs = array(); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $itemId = (int)$extras [3]; + $obj = array (); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $_POST["out_trade_no"];; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["total_fee"] = $_POST['total_fee']; + $obj["payFrom"] = 'alipays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //商户订单号 + $obj = array(); + $tradeNo = explode("a",$_POST['out_trade_no']); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $tradeNo[0]; + $obj["total_fee"] = $_POST['total_fee']; + + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = 'alipays'; + //支付成功业务逻辑 + $rs = $m->complatePay($obj); + } + + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + }else{ + echo 'fail'; + } + } + + /** + * 支付回调接口 + */ + function notify($request){ + $returnRes = array('info'=>'','status'=>false); + $request = $this->argSort($request); + // 检查数字签名是否正确 + $isSign = $this->getSignVeryfy($request); + if (!$isSign){//签名验证失败 + $returnRes['info'] = '签名验证失败'; + return $returnRes; + } + if ($request['trade_status'] == 'TRADE_SUCCESS' || $request['trade_status'] == 'TRADE_FINISHED'){ + $returnRes['status'] = true; + } + return $returnRes; + } + + /** + * 获取返回时的签名验证结果 + */ + function getSignVeryfy($para_temp) { + $parterKey = $this->aliPayConfig["parterKey"]; + //除去待签名参数数组中的空值和签名参数 + $para_filter = $this->paraFilter($para_temp); + //对待签名参数数组排序 + $para_sort = $this->argSort($para_filter); + //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 + $prestr = $this->createLinkstring($para_sort); + + $isSgin = false; + $isSgin = $this->md5Verify($prestr, $para_temp['sign'], $parterKey); + return $isSgin; + } + + /** + * 验证签名 + */ + function md5Verify($prestr, $sign, $key) { + $prestr = $prestr . $key; + $mysgin = md5($prestr); + if($mysgin == $sign) { + return true; + }else { + return false; + } + } + + /** + * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 + */ + function createLinkstring($para) { + $arg = ""; + while (list ($key, $val) = each ($para)) { + $arg.=$key."=".$val."&"; + } + //去掉最后一个&字符 + $arg = substr($arg,0,count($arg)-2); + //如果存在转义字符,那么去掉转义 + if(get_magic_quotes_gpc()){$arg = stripslashes($arg);} + + return $arg; + } + + /** + * 除去数组中的空值和签名参数 + */ + function paraFilter($para) { + $para_filter = array(); + while (list ($key, $val) = each ($para)) { + if($key == "sign" || $key == "sign_type" || $val == "")continue; + else $para_filter[$key] = $para[$key]; + } + return $para_filter; + } + + /** + * 对数组排序 + */ + function argSort($para) { + ksort($para); + reset($para); + return $para; + } + + /** + * 检查支付结果 + */ + public function paySuccess() { + return $this->fetch('order_pay_step3'); + } + +} diff --git a/hyhproject/home2/controller/Areas.php b/hyhproject/home2/controller/Areas.php new file mode 100755 index 0000000..91a1288 --- /dev/null +++ b/hyhproject/home2/controller/Areas.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Areas as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Areas extends Base{ + /** + * 获取地区信息 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + return WSTReturn('', 1,$rs); + } +} diff --git a/hyhproject/home2/controller/Base.php b/hyhproject/home2/controller/Base.php new file mode 100755 index 0000000..042fb23 --- /dev/null +++ b/hyhproject/home2/controller/Base.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 基础控制器 + */ +use think\Controller; +class Base extends Controller { + protected $is_icp = 1; + public function __construct(){ + + parent::__construct(); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPCStyleId')); + + hook('homeControllerBase'); + + if(WSTConf('CONF.seoMallSwitch')==0){ + $this->redirect('home/switchs/index'); + exit; + } + $this->assign('is_icp',$this->is_icp); + } + + protected function fetch($template = '', $vars = [], $replace = [], $config = []) + { + $style = WSTConf('CONF.wsthomeStyle')?WSTConf('CONF.wsthomeStyle'):'default'; + $replace['__STYLE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/home/view/'.WSTConf('CONF.wsthomeStyle'); + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + } + + /** + * 上传图片 + */ + public function uploadPic(){ + return WSTUploadPic(0); + } + /** + * 编辑器上传文件 + */ + public function editorUpload(){ + return WSTEditUpload(0); + } + + /** + * 获取验证码 + */ + public function getVerify(){ + WSTVerify(); + } + + // 登录验证方法--用户 + protected function checkAuth(){ + $USER = session('WST_USER'); + if(empty($USER)){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $this->redirect('home/users/login'); + exit; + } + } + } + //登录验证方法--商家 + protected function checkShopAuth(){ + $USER = session('WST_USER'); + if(empty($USER) || $USER['userType']!=1){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $this->redirect('home/shops/login'); + exit; + } + } + } + +} \ No newline at end of file diff --git a/hyhproject/home2/controller/Brands.php b/hyhproject/home2/controller/Brands.php new file mode 100755 index 0000000..7fc8f9e --- /dev/null +++ b/hyhproject/home2/controller/Brands.php @@ -0,0 +1,34 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Brands as M; +/** + * ============================================================================ + * 品牌控制器 + */ +class Brands extends Base{ + /** + * 品牌街 + */ + public function index(){ + $m = new M(); + $pagesize = 25; + $brandsList = $m->pageQuery($pagesize); + $this->assign('list',$brandsList); + + $g = model('goodsCats'); + $goodsCats = $g->listQuery(0); + $this->assign('goodscats',$goodsCats); + + + $selectedId = (int)input("id"); + $this->assign('selectedId',$selectedId); + return $this->fetch('brands_list'); + } + /** + * 获取品牌列表 + */ + public function listQuery(){ + $m = new M(); + return ['status'=>1,'list'=>$m->listQuery(input('post.catId/d'))]; + } +} diff --git a/hyhproject/home2/controller/Carts.php b/hyhproject/home2/controller/Carts.php new file mode 100755 index 0000000..e3ea243 --- /dev/null +++ b/hyhproject/home2/controller/Carts.php @@ -0,0 +1,318 @@ +<?php + +namespace wstmart\home\controller; + +use wstmart\common\model\Carts as M; + +use wstmart\common\model\Payments as PM; + +/** + + * ============================================================================ + + * 购物车控制器 + + */ + +class Carts extends Base{ + + protected $beforeActionList = ['checkAuth']; + + /** + + * 加入购物车 + + */ + + public function addCart(){ + + $m = new M(); + + $rs = $m->addCart(); + + return $rs; + + } + + /** + + * 查看购物车列表 + + */ + + public function index(){ + + $m = new M(); + + $carts = $m->getCarts(false); + + $this->assign('carts',$carts); + + return $this->fetch('carts'); + + } + + /** + + * 删除购物车里的商品 + + */ + + public function delCart(){ + + $m = new M(); + + $rs= $m->delCart(); + + return $rs; + + } + + /** + + * 虚拟商品下单 + + */ + + public function quickSettlement(){ + + $m = new M(); + + //获取支付方式 + + $pm = new PM(); + + $payments = $pm->getByGroup('1',1); + + $carts = $m->getQuickCarts(); + + if(empty($carts['carts'])){ + + $this->assign('message','Sorry~您还未选择商品。。。'); + + return $this->fetch('error_msg'); + + } + + hook("homeControllerCartsSettlement",["carts"=>$carts,"payments"=>&$payments]); + + //获取用户惠宝 + + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + + //计算可用惠宝和金额 + + $goodsTotalMoney = $carts['goodsTotalMoney']-$carts['promotionMoney']; + + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + + $useOrderScore =0; + + $useOrderMoney = 0; + + if($user['userScore']>$goodsTotalScore){ + + $useOrderScore = $goodsTotalScore; + + $useOrderMoney = $goodsTotalMoney; + + }else{ + + $useOrderScore = $user['userScore']; + + $useOrderMoney = WSTScoreToMoney($useOrderScore); + + } + + $this->assign('userOrderScore',$useOrderScore); + + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('payments',$payments); + + $this->assign('carts',$carts); + + return $this->fetch('settlement_quick'); + + } + + /** + + * 跳去购物车结算页面 + + */ + + public function settlement(){ + + $m = new M(); + + //获取一个用户地址 + + $userAddress = model('UserAddress')->getDefaultAddress(); + + $this->assign('userAddress',$userAddress); + + //获取省份 + + $areas = model('Areas')->listQuery(); + + $this->assign('areaList',$areas); + + //获取支付方式 + + $pm = new PM(); + + $payments = $pm->getByGroup('1'); + + $carts = $m->getCarts(true); + + if(empty($carts['carts'])){ + + $this->assign('message','Sorry~您还未选择商品。。。'); + + return $this->fetch('error_msg'); + + } + + + + hook("homeControllerCartsSettlement",["carts"=>$carts,"payments"=>&$payments]); + + //获取用户惠宝 + + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + + //计算可用惠宝和金额 + $goodsTotalMoney = (($carts['goodsTotalMoney']-$carts['allShippingMoney']-$carts['promotionMoney']) * HuiScale());//$carts['goodsTotalMoney']-$carts['promotionMoney'];//惠宝最多可抵用20% mark 20170907 + + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + + $useOrderScore =0; + + $useOrderMoney = 0; + + if($user['userScore']>$goodsTotalScore){ + + $useOrderScore = $goodsTotalScore; + + $useOrderMoney = $goodsTotalMoney; + + }else{ + + $useOrderScore = $user['userScore']; + + $useOrderMoney = WSTScoreToMoney($useOrderScore); + + } + + $this->assign('userOrderScore',$useOrderScore); + + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + // dump($carts);die; + $this->assign('payments',$payments); + + return $this->fetch('settlement'); + + } + + + + /** + + * 计算运费、惠宝和总商品价格 + + */ + + public function getCartMoney(){ + + $m = new M(); + + $data = $m->getCartMoney(); + // dump($data);die; + return $data; + + } + + /** + + * 计算运费、惠宝和总商品价格 + + */ + + public function getQuickCartMoney(){ + + $m = new M(); + + $data = $m->getQuickCartMoney(); + + return $data; + + } + + /** + + * 修改购物车商品状态 + + */ + + public function changeCartGoods(){ + + $m = new M(); + + $rs = $m->changeCartGoods(); + + return $rs; + + } + + /** + + * 批量修改购物车商品状态 + + */ + + public function batchChangeCartGoods(){ + + $m = new M(); + + $rs = $m->batchChangeCartGoods(); + + return $rs; + + } + + /** + + * 获取购物车商品 + + */ + + public function getCart(){ + + $m = new M(); + + $carts = $m->getCarts(false); + + return WSTReturn("", 1,$carts); + + } + + /** + + * 获取购物车信息 + + */ + + public function getCartInfo(){ + + $m = new M(); + + $rs = $m->getCartInfo(); + + return WSTReturn("", 1,$rs); + + } +} + diff --git a/hyhproject/home2/controller/Cashconfigs.php b/hyhproject/home2/controller/Cashconfigs.php new file mode 100755 index 0000000..beb2a0e --- /dev/null +++ b/hyhproject/home2/controller/Cashconfigs.php @@ -0,0 +1,58 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\CashConfigs as M; +/** + * ============================================================================ + * 提现账号控制器 + */ +class Cashconfigs extends Base{ + protected $beforeActionList = ['checkAuth']; + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashConfigs')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + + /** + * 跳转新增/编辑页面 + */ + public function toEdit(){ + $id = (int)input('id'); + $object = []; + $m = new M(); + if($id>0){ + $object = $m->getById($id); + }else{ + $object = $m->getEModel('cash_configs'); + $object['accAreaIdPath'] = ''; + } + $this->assign('object',$object); + $this->assign('areas',model('areas')->listQuery(0)); + $this->assign('banks',model('banks')->listQuery(0)); + return $this->fetch('users/cashdraws/box_config'); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/home2/controller/Cashdraws.php b/hyhproject/home2/controller/Cashdraws.php new file mode 100755 index 0000000..9c79f9e --- /dev/null +++ b/hyhproject/home2/controller/Cashdraws.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\CashDraws as M; +use wstmart\common\model\Users as MUsers; +use wstmart\common\model\Shops as MShops; +/** + * ============================================================================ + * 提现记录控制器 + */ +class Cashdraws extends Base{ + protected $beforeActionList = [ + 'checkAuth'=>['only'=>'index,pagequery,toedit,drawmoney'], + 'checkShopAuth'=>['only'=>'shopindex,pagequerybyshop,toeditbyshop,drawmoneybyshop'] + ]; + /** + * 查看用户资金流水 + */ + public function index(){ + return $this->fetch('users/cashdraws/list'); + } + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashDraws')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + + /** + * 跳转提现页面 + */ + public function toEdit(){ + $userId = (int)session('WST_USER.userId'); + $this->assign('accs',model('CashConfigs')->listQuery(0,$userId)); + $m = new MUsers(); + $user = $m->getFieldsById($userId,["userMoney","rechargeMoney"]); + $this->assign('user',$user); + return $this->fetch('users/cashdraws/box_draw'); + } + + /** + * 提现 + */ + public function drawMoney(){ + $m = new M(); + return $m->drawMoney(); + } + + + /** + * 查看用户资金流水 + */ + public function shopIndex(){ + return $this->fetch('shops/cashdraws/list'); + } + /** + * 获取用户数据 + */ + public function pageQueryByShop(){ + $shopId = (int)session('WST_USER.shopId'); + $data = model('CashDraws')->pageQuery(1,$shopId); + return WSTReturn("", 1,$data); + } + /** + * 申请提现 + */ + public function toEditByShop(){ + $this->assign('object',model('shops')->getShopAccount()); + $m = new MShops(); + $shopId = (int)session('WST_USER.shopId'); + $shop = $m->getFieldsById($shopId,["shopMoney","rechargeMoney"]); + $this->assign('shop',$shop); + return $this->fetch('shops/cashdraws/box_draw'); + } + /** + * 提现 + */ + public function drawMoneyByShop(){ + $m = new M(); + return $m->drawMoneyByShop(); + } +} diff --git a/hyhproject/home2/controller/Error.php b/hyhproject/home2/controller/Error.php new file mode 100755 index 0000000..40db942 --- /dev/null +++ b/hyhproject/home2/controller/Error.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 错误处理控制器 + */ +class Error extends Base{ + public function index(){ + header("HTTP/1.0 404 Not Found"); + return $this->fetch('error_sys'); + } + public function goods(){ + $this->assign('message','很抱歉,您要找的商品已经找不到了~'); + return $this->fetch('error_msg'); + } + public function shop(){ + $this->assign('message','很抱歉,您要找的店铺已经找不到了~'); + return $this->fetch('error_msg'); + } + public function message(){ + $code = input('code'); + if(!empty($code) && session($code)!=''){ + $this->assign('message',session($code)); + }else{ + $this->assign('message','操作错误,请联系商城管理员'); + } + return $this->fetch('error_msg'); + } +} diff --git a/hyhproject/home2/controller/Favorites.php b/hyhproject/home2/controller/Favorites.php new file mode 100755 index 0000000..37f7b0b --- /dev/null +++ b/hyhproject/home2/controller/Favorites.php @@ -0,0 +1,54 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Favorites as M; +/** + * ============================================================================ + * 收藏控制器 + */ +class Favorites extends Base{ + protected $beforeActionList = ['checkAuth']; + /** + * 关注的商品 + */ + public function goods(){ + return $this->fetch('users/favorites/list_goods'); + } + /** + * 关注的店铺 + */ + public function shops(){ + return $this->fetch('users/favorites/list_shops'); + } + /** + * 关注的商品列表 + */ + public function listGoodsQuery(){ + $m = new M(); + $data = $m->listGoodsQuery(); + return WSTReturn("", 1,$data); + } + /** + * 关注的店铺列表 + */ + public function listShopQuery(){ + $m = new M(); + $data = $m->listShopQuery(); + return WSTReturn("", 1,$data); + } + /** + * 取消关注 + */ + public function cancel(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + /** + * 增加关注 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } +} diff --git a/hyhproject/home2/controller/Goods.php b/hyhproject/home2/controller/Goods.php new file mode 100755 index 0000000..4e10925 --- /dev/null +++ b/hyhproject/home2/controller/Goods.php @@ -0,0 +1,706 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Goods as M; +use wstmart\common\model\Goods as CM; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + protected $beforeActionList = [ + 'checkShopAuth' => ['except'=>'search,lists,detail,historybygoods,contrastgoods,contrastdel,contrast'] + ]; + /** + * 批量删除商品 + */ + public function batchDel(){ + $m = new M(); + return $m->batchDel(); + } + /** + * 修改商品库存/价格 + */ + public function editGoodsBase(){ + $m = new M(); + return $m->editGoodsBase(); + } + + /** + * 修改商品状态 + */ + public function changSaleStatus(){ + $m = new M(); + return $m->changSaleStatus(); + } + /** + * 修改商品店长推荐状态 + */ + public function changStoreRecom(){ + $m = new M(); + return $m->changStoreRecom(); + } + /** + * 批量修改商品状态 新品/精品/热销/推荐 + */ + public function changeGoodsStatus(){ + $m = new M(); + return $m->changeGoodsStatus(); + } + /** + * 批量修改商品状态 店长推荐 + */ + public function changeStoreStatus(){ + $m = new M(); + return $m->changeStoreStatus(); + } + /** + * 批量上(下)架 + */ + public function changeSale(){ + $m = new M(); + return $m->changeSale(); + } + /** + * 上架商品列表 + */ + public function sale(){ + return $this->fetch('shops/goods/list_sale'); + } + /** + * 获取上架商品列表 + */ + public function saleByPage(){ + $m = new M(); + $rs = $m->saleByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 仓库中商品 + */ + public function store(){ + return $this->fetch('shops/goods/list_store'); + } + /** + * 审核中的商品 + */ + public function audit(){ + return $this->fetch('shops/goods/list_audit'); + } + /** + * 获取审核中的商品 + */ + public function auditByPage(){ + $m = new M(); + $rs = $m->auditByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取仓库中的商品 + */ + public function storeByPage(){ + $m = new M(); + $rs = $m->storeByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 违规商品 + */ + public function illegal(){ + return $this->fetch('shops/goods/list_illegal'); + } + /* + * 设置商品特定价格 + * */ + public function limitPrice(){ + $shopId=(int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + if (Request()->isPost()) { + $goodsType = input('goodsType'); + if ($goodsType != '') $where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if ($goodsName != '') { + $where['goodsName'] = ['like', "%$goodsName%"]; + } + if ($c2Id != 0 && $c1Id != 0) { + $where['shopCatId2'] = $c2Id; + } else if ($c1Id != 0) { + $where['shopCatId1'] = $c1Id; + } + } + $lists=db('goods')->where($where)->field('goodsId,goodsName,goodsType')->select(); + //dump($lists); + if (Request()->isAjax()) { + //dump($lists); + exit(json_encode(WSTReturn('',1,$lists))); + } + $this->assign('lists',$lists); + return $this->fetch('shops/goods/list_limitprice'); + } + //获取商品货号 + public function getGoodsProduct(){ + $goodsId = (int)input('goodsId'); + $res['specs'] = db('goods_specs')->where(['goodsId'=>$goodsId])->field('productNo,specIds')->select(); + $res['goods'] = db('goods')->where(['goodsId'=>$goodsId])->field('marketPrice')->find(); + // dump($res);die; + exit(json_encode($res)); + } + + //获取商品规格 + public function getGoodsSpecs(){ + $productNo = input('productNo'); + $res = db('goods_specs')->where(['productNo'=>$productNo])->field('specIds,marketPrice')->find(); + $specs = explode(':',$res['specIds']); + $data = db('spec_items')->where(['itemId'=>['in',$specs]])->select(); + $rs['itemName'] = implode(',',array_column($data,'itemName')); + $rs['marketPrice'] = $res['marketPrice']; + exit(json_encode($rs)); + + } + /** + * 获取违规的商品 + */ + public function illegalByPage(){ + $m = new M(); + $rs = $m->illegalByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取已设置限时价格的商品 + */ + public function limitPriceByPage(){ + $m = new M(); + $rs = $m->limitPriceByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 获取指定显示价格的商品的商品 + */ + public function getLimitGoods(){ + $m = new M(); + $rs = $m->getLimitGoods(); + return $rs; + } + /** + * 跳去新增限时价格商品页面 + */ + public function addLimitGoods(){ + $m = new M(); + $rs = $m->addLimitGoods(); + return $rs; + } + /** + * 跳去编辑限时价格商品页面 + */ + public function editLimitGoods(){ + $m = new M(); + $rs = $m->editLimitGoods(); + return $rs; + } + /** + * 删除显示价格商品 + */ + public function delLimitGoods(){ + $m = new M(); + $rs = $m->delLimitGoods(); + return $rs; + } + /** + * 跳去新增页面 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('goods'); + $shopId=(int)session('WST_USER.shopId'); + // $object['pay']=db('shop_pay')->where(['shopId'=>$shopId,'status'=>1])->find(); + // $object['isEct']=0; + $object['ectPayRatio'] = db('payments')->where(['payCode'=>'ect'])->value('payRatio'); + $object['goodsSn'] = WSTGoodsNo(); + $object['productNo'] = WSTGoodsNo(); + $object['goodsImg'] = WSTConf('CONF.goodsLogo'); + $object['ectPay']=0;//db('goods')->alias('g')->join('goods_ectpay ge','ge.goodsId=g.goodsId','left')->value('ectPay'); + $object['alone'] =0; + $object['basicsMoney'] = 0; + $aloneShop = db('alone_shops')->alias('as')->join('__SHOPS__ s','as.shopId=s.shopId')->where(['as.dataFlag'=>'1','as.shopId'=>$shopId])->value('as.shopId'); + if($aloneShop){ + $object['alone'] =1; + } + //dump($object); + $data = ['object'=>$object,'src'=>'add']; + return $this->fetch('shops/goods/edit',$data); + } + + /** + * 新增商品 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 跳去编辑页面 + */ + public function edit(){ + $m = new M(); + $object = $m->getById(input('get.id')); + $shopId=(int)session('WST_USER.shopId'); + // $object['pay']=db('shop_pay')->where(['shopId'=>$shopId,'status'=>1])->find(); + // //$object['pay']=1; + // if($object['pay']){ + // $object['isEct']=db('goods_pay')->where('goodsId',$object['goodsId'])->value('ectPay'); + // //$object['isOnline']=db('goods_pay')->where('goodsId',$object['goodsId'])->value('onlinePay'); + // } + $object['ectPayRatio'] = db('payments')->where(['payCode'=>'ect'])->value('payRatio'); + if($object['goodsImg']=='')$object['goodsImg'] = WSTConf('CONF.goodsLogo'); + $object['ectPay']=0; + if($object['basicsMoney'] == '') $object['basicsMoney'] = 0; + $object['alone'] =0; + $aloneShop = db('alone_shops')->alias('as')->join('__SHOPS__ s','as.shopId=s.shopId')->where(['as.dataFlag'=>'1','as.shopId'=>$shopId])->value('as.shopId'); + if($aloneShop){ + $object['alone'] =1; + } + $data = ['object'=>$object,'src'=>input('src')]; + return $this->fetch('shops/goods/edit',$data); + } + + /** + * 编辑商品 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除商品 + */ + public function del(){ + $m = new M(); + return $m->del(); + } + /** + * 获取商品规格属性 + */ + public function getSpecAttrs(){ + $m = new M(); + return $m->getSpecAttrs(); + } + /** + * 进行商品搜索 + */ + public function search(){ + //获取商品记录 + $m = new M(); + $data = []; + $data['isStock'] = Input('isStock/d'); + $data['isNew'] = Input('isNew/d'); + $data['isFreeShipping'] = input('isFreeShipping/d'); + $data['orderBy'] = Input('orderBy/d'); + $data['order'] = Input('order/d',1); + $data['keyword'] = input('keyword'); + $data['sprice'] = Input('sprice/d'); + $data['eprice'] = Input('eprice/d'); + + $data['areaId'] = (int)Input('areaId'); + $aModel = model('home/areas'); + + // 获取地区 + $data['area1'] = $data['area2'] = $data['area3'] = $aModel->listQuery(); // 省级 + + // 如果有筛选地区 获取上级地区信息 + if($data['areaId']!==0){ + $areaIds = $aModel->getParentIs($data['areaId']); + /* + 2 => int 440000 + 1 => int 440100 + 0 => int 440106 + */ + $selectArea = []; + $areaName = ''; + foreach($areaIds as $k=>$v){ + $a = $aModel->getById($v); + $areaName .=$a['areaName']; + $selectArea[] = $a; + } + // 地区完整名称 + $selectArea['areaName'] = $areaName; + // 当前选择的地区 + $data['areaInfo'] = $selectArea; + + $data['area2'] = $aModel->listQuery($areaIds[2]); // 广东的下级 + + $data['area3'] = $aModel->listQuery($areaIds[1]); // 广州的下级 + } + + + $data['goodsPage'] = $m->pageQuery(); + return $this->fetch("goods_search",$data); + } + + /** + * 获取商品列表 + */ + public function lists(){ + $catId = Input('cat/d'); + $goodsCatIds = model('GoodsCats')->getParentIs($catId); + reset($goodsCatIds); + //填充参数 + $data = []; + $data['catId'] = $catId; + $data['isStock'] = Input('isStock/d'); + $data['isNew'] = Input('isNew/d'); + $data['isFreeShipping'] = input('isFreeShipping/d'); + $data['orderBy'] = Input('orderBy/d'); + $data['order'] = Input('order/d',1); + $data['sprice'] = Input('sprice'); + $data['eprice'] = Input('eprice'); + $data['attrs'] = []; + + $data['areaId'] = (int)Input('areaId'); + $aModel = model('home/areas'); + + // 获取地区 + $data['area1'] = $data['area2'] = $data['area3'] = $aModel->listQuery(); // 省级 + + // 如果有筛选地区 获取上级地区信息 + if($data['areaId']!==0){ + $areaIds = $aModel->getParentIs($data['areaId']); + /* + 2 => int 440000 + 1 => int 440100 + 0 => int 440106 + */ + $selectArea = []; + $areaName = ''; + foreach($areaIds as $k=>$v){ + $a = $aModel->getById($v); + $areaName .=$a['areaName']; + $selectArea[] = $a; + } + // 地区完整名称 + $selectArea['areaName'] = $areaName; + // 当前选择的地区 + $data['areaInfo'] = $selectArea; + + $data['area2'] = $aModel->listQuery($areaIds[2]); // 广东的下级 + + $data['area3'] = $aModel->listQuery($areaIds[1]); // 广州的下级 + } + + $vs = input('vs'); + $vs = ($vs!='')?explode(',',$vs):[]; + foreach ($vs as $key => $v){ + if($v=='' || $v==0)continue; + $v = (int)$v; + $data['attrs']['v_'.$v] = input('v_'.$v); + } + $data['vs'] = $vs; + + $brandIds = Input('brand'); + + + $bgIds = [];// 品牌下的商品Id + if(!empty($vs)){ + // 存在筛选条件,取出符合该条件的商品id,根据商品id获取可选品牌 + $goodsId = model('goods')->filterByAttributes(); + $data['brandFilter'] = model('Brands')->canChoseBrands($goodsId); + }else{ + // 取出分类下包含商品的品牌 + $data['brandFilter'] = model('Brands')->goodsListQuery((int)current($goodsCatIds)); + } + if(!empty($brandIds))$bgIds = model('Brands')->getGoodsIds($brandIds); + + + + + $data['price'] = Input('price'); + //封装当前选中的值 + $selector = []; + //处理品牌 + $brandIds = explode(',',$brandIds); + $bIds = $brandNames = []; + foreach($brandIds as $bId){ + if($bId>0){ + foreach ($data['brandFilter'] as $key =>$v){ + if($v['brandId']==$bId){ + array_push($bIds, $v['brandId']); + array_push($brandNames, $v['brandName']); + } + } + $selector[] = ['id'=>join(',',$bIds),'type'=>'brand','label'=>"品牌","val"=>join('、',$brandNames)]; + } + } + // 当前是否有品牌筛选 + if(!empty($selector)){ + $_s[] = $selector[count($selector)-1]; + $selector = $_s; + unset($data['brandFilter']); + } + $data['brandId'] = Input('brand'); + + //处理价格 + if($data['sprice']!='' && $data['eprice']!=''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>$data['sprice']."-".$data['eprice']]; + } + if($data['sprice']!='' && $data['eprice']==''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>$data['sprice']."以上"]; + } + if($data['sprice']=='' && $data['eprice']!=''){ + $selector[] = ['id'=>0,'type'=>'price','label'=>"价格","val"=>"0-".$data['eprice']]; + } + //处理已选属性 + $goodsFilter = model('Attributes')->listQueryByFilter($catId); + $ngoodsFilter = []; + if(!empty($vs)){ + // 存在筛选条件,取出符合该条件的商品id,根据商品id获取可选属性进行拼凑 + $goodsId = model('goods')->filterByAttributes(); + // 如果同时有筛选品牌,则与品牌下的商品Id取交集 + if(!empty($bgIds))$goodsId = array_intersect($bgIds,$goodsId); + + + $attrs = model('Attributes')->getAttribute($goodsId); + // 去除已选择属性 + foreach ($attrs as $key =>$v){ + if(!in_array($v['attrId'],$vs))$ngoodsFilter[] = $v; + } + }else{ + if(!empty($bgIds))$goodsFilter = model('Attributes')->getAttribute($bgIds);// 存在品牌筛选 + // 当前无筛选条件,取出分类下所有属性 + foreach ($goodsFilter as $key =>$v){ + if(!in_array($v['attrId'],$vs))$ngoodsFilter[] = $v; + } + } + if(count($vs)>0){ + $_vv = []; + $_attrArr = []; + foreach ($goodsFilter as $key =>$v){ + if(in_array($v['attrId'],$vs)){ + foreach ($v['attrVal'] as $key2 =>$vv){ + if(strstr(input('v_'.$v['attrId']),$vv)!==false){ + array_push($_vv, $vv); + $_attrArr[$v['attrId']]['attrName'] = $v['attrName']; + $_attrArr[$v['attrId']]['val'] = $_vv; + } + } + $_vv = []; + } + } + foreach($_attrArr as $k1=>$v1){ + $selector[] = ['id'=>$k1,'type'=>'v_'.$k1,'label'=>$v1['attrName'],"val"=>join('、',$v1['val'])]; + } + } + $data['selector'] = $selector; + $data['goodsFilter'] = $ngoodsFilter; + //获取商品记录 + $m = new M(); + $data['priceGrade'] = $m->getPriceGrade($goodsCatIds); + $data['goodsPage'] = $m->pageQuery($goodsCatIds); + $catPaths = model('goodsCats')->getParentNames($catId); + $data['catNamePath'] = '全部商品分类'; + if(!empty($catPaths))$data['catNamePath'] = implode(' - ',$catPaths); + // 商品分类下级 + $where = ['parentId'=>0,'dataFlag'=>1]; + if($catId!='')$where['parentId']=$catId; + $goodsCats = model('goodsCats')->field('catId,catName')->where($where)->select(); + $this->assign('goodsCats',$goodsCats); + return $this->fetch("goods_list",$data); + } + /** + * 查看商品详情 + */ + public function detail(){ + $m = new M(); + $goods = $m->getBySale(input('id/d',0)); + $key=input('key'); + if(!empty($goods)){ + //判断是否药品 + $goods_cat=strpos($goods['goodsCatIdPath'],'389'); + if($goods_cat!==false && $key==''){ + return $this->fetch("error_lost"); + } + if((int)session('WST_USER.userId')!=""){ + $history_data['userId']=(int)session('WST_USER.userId'); + $history_data['goodsId']=$goods['goodsId']; + $history_data['path']='1'; + $history_data['create_time']=time(); + $result=db('page_view')->insert($history_data); + } + $history = cookie("history_goods"); + $history = is_array($history)?$history:[]; + array_unshift($history, (string)$goods['goodsId']); + $history = array_values(array_unique($history)); + + if(!empty($history)){ + cookie("history_goods",$history,25920000); + } + // 商品详情延迟加载 + $goods['goodsDesc']=htmlspecialchars_decode($goods['goodsDesc']); + //修改匹配规则 适应oss 地址 mark 20180615 by zl + // $rule = '/<img src="\/(upload.*?)"/'; + $rule = '/<img src=".*?\/(upload.*?)"/'; + preg_match_all($rule, $goods['goodsDesc'], $images); + foreach($images[0] as $k=>$v){ + //mark by cheng商品详情换成远程oss图片20180313 + //$goods['goodsDesc'] = str_replace($v, "<img class='goodsImg' data-original=\"__ROOT__/".WSTImg($images[1][$k],3)."\"", $goods['goodsDesc']); + $goods['goodsDesc'] = str_replace($v, "<img class='goodsImg' data-original=\"__IMGURL__/".WSTImg($images[1][$k],0)."\"", $goods['goodsDesc']); + + } + hook('afterGetGoods',['params'=>&$goods]); + $goods['is_seckilling']=isset($goods['is_seckilling'])?$goods['is_seckilling']:0; + $this->assign('goods',$goods); + $this->assign('shop',$goods['shop']); + return $this->fetch("goods_detail"); + }else{ + return $this->fetch("error_lost"); + } + } + /** + * 预警库存 + */ + public function stockwarnbypage(){ + return $this->fetch("shops/stockwarn/list"); + } + /** + * 获取预警库存列表 + */ + public function stockByPage(){ + $m = new M(); + $rs = $m->stockByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 修改预警库存 + */ + public function editwarnStock(){ + $m = new M(); + return $m->editwarnStock(); + } + + /** + * 获取商品浏览记录 + */ + public function historyByGoods(){ + $rs = model('Tags')->historyByGoods(8); + return WSTReturn('',1,$rs); + } + /** + * 记录对比商品 + */ + public function contrastGoods(){ + $id = (int)input('post.id'); + $contras = cookie("contras_goods"); + if($id>0){ + $m = new M(); + $goods = $m->getBySale($id); + $catId = explode('_',$goods['goodsCatIdPath']); + $catId = $catId[0]; + if(isset($contras['catId']) && $catId!=$contras['catId'])return WSTReturn('请选择同分类对比',-1); + if(isset($contras['list']) && count($contras['list'])>3)return WSTReturn('对比栏已满',-1); + if(!isset($contras['catId']))$contras['catId'] = $catId; + $contras['list'][$id] = $id; + cookie("contras_goods",$contras,25920000); + } + if(isset($contras['list'])){ + $m = new M(); + $list = []; + foreach($contras['list'] as $k=>$v){ + $list[] = $m->getBySale($v); + } + return WSTReturn('',1,$list); + }else{ + return WSTReturn('',1); + } + } + /** + * 删除对比商品 + */ + public function contrastDel(){ + $id = (int)input('post.id'); + $contras = cookie("contras_goods"); + if($id>0 && isset($contras['list'])){ + unset($contras['list'][$id]); + cookie("contras_goods",$contras,25920000); + }else{ + cookie("contras_goods", null); + } + return WSTReturn('删除成功',1); + } + /** + * 商品对比 + */ + public function contrast(){ + $contras = cookie("contras_goods"); + $list = []; + $list = $lists= $saleSpec = $shop = $score = $brand = $spec = []; + if(isset($contras['list'])){ + $m = new M(); + foreach($contras['list'] as $key=>$value){ + $dara = $m->getBySale($value); + if(isset($dara['saleSpec'])){ + foreach($dara['saleSpec'] as $ks=>$vs){ + if($vs['isDefault']==1){ + $dara['defaultSpec'] = $vs; + $dara['defaultSpec']['ids'] = explode(':',$ks); + } + } + $saleSpec[$value] = $dara['saleSpec']; + } + $list[] = $dara; + } + //第一个商品信息 + $goods = $list[0]; + //对比处理 + $shops['identical'] = $scores['identical'] = $brands['identical'] = 1; + foreach($list as $k=>$v){ + $shop[$v['goodsId']] = $v['shop']['shopName']; + if($goods['shop']['shopId']!=$v['shop']['shopId'])$shops['identical'] = 0; + $score[$v['goodsId']] = $v['scores']['totalScores']; + if($goods['scores']['totalScores']!=$v['scores']['totalScores'])$scores['identical'] = 0; + $brand[$v['goodsId']] = $v['brandName']; + if($goods['brandId']!=$v['brandId'])$brands['identical'] = 0; + if(isset($v['spec'])){ + foreach($v['spec'] as $k2=>$v2){ + $spec[$k2]['identical'] = 0; + $spec[$k2]['type'] = 'spec'; + $spec[$k2]['name'] = $v2['name']; + $spec[$k2]['catId'] = $k2; + foreach($v2['list'] as $ks22=>$vs22){ + $v['spec'][$k2]['list'][$ks22]['isDefault'] = (in_array($vs22['itemId'],$v['defaultSpec']['ids']))?1:0; + } + $spec[$k2]['info'][$v['goodsId']] = $v['spec'][$k2]; + } + } + } + $shops['name'] = '店铺'; + $shops['type'] = 'shop'; + $shops['info'] = $shop; + $lists[] = $shops; + $scores['name'] = '商品评分'; + $scores['type'] = 'score'; + $scores['info'] = $score; + $lists[] = $scores; + $brands['name'] = '品牌'; + $brands['type'] = 'brand'; + $brands['info'] = $brand; + $lists[] = $brands; + foreach($spec as $k3=>$v3){ + $lists[] = $v3; + } + } + $data['list'] = $list; + $data['lists'] = $lists; + $data['saleSpec'] = $saleSpec; + $this->assign('data',$data); + return $this->fetch("goods_contrast"); + } +} diff --git a/hyhproject/home2/controller/Goodsappraises.php b/hyhproject/home2/controller/Goodsappraises.php new file mode 100755 index 0000000..4986a30 --- /dev/null +++ b/hyhproject/home2/controller/Goodsappraises.php @@ -0,0 +1,60 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\GoodsAppraises as M; +/** + * ============================================================================ + * 评价控制器 + */ +class GoodsAppraises extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'userappraise,getbyid'], + 'checkShopAuth'=>['only'=>'index,querybypage,shopreply'] + ]; + /** + * 获取评价列表 商家 + */ + public function index(){ + return $this->fetch('shops/goodsappraises/list'); + } + /** + * 获取评价列表 用户 + */ + public function myAppraise(){ + return $this->fetch('users/orders/appraise_manage'); + } + // 获取评价列表 商家 + public function queryByPage(){ + $m = new M(); + return $m->queryByPage(); + } + // 获取评价列表 用户 + public function userAppraise(){ + $m = new M(); + return $m->userAppraise(); + } + /** + * 添加评价 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + + } + /** + * 根据商品id取评论 + */ + public function getById(){ + $m = new M(); + $rs = $m->getById(); + return $rs; + } + + /** + * 商家回复评价 + */ + public function shopReply(){ + $m = new M(); + return $m->shopReply(); + } +} diff --git a/hyhproject/home2/controller/Goodscats.php b/hyhproject/home2/controller/Goodscats.php new file mode 100755 index 0000000..20b446c --- /dev/null +++ b/hyhproject/home2/controller/Goodscats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class Goodscats extends Base{ + /** + * 获取列表 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(input('parentId/d',0)); + return WSTReturn("", 1,$rs); + } + +} \ No newline at end of file diff --git a/hyhproject/home2/controller/Goodsconsult.php b/hyhproject/home2/controller/Goodsconsult.php new file mode 100755 index 0000000..69baebe --- /dev/null +++ b/hyhproject/home2/controller/Goodsconsult.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\GoodsConsult as M; +/** + * ============================================================================ + * 商品咨询控制器 + */ +class GoodsConsult extends Base{ + protected $beforeActionList = [ + 'checkShopAuth'=>['only'=>'pageQuery,shopReplyConsult,reply'] + ]; + /** + * 根据商品id获取商品咨询 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 根据店铺id获取商品咨询 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return $rs; + } + /** + * 获取商品咨询 商家 + */ + public function shopReplyConsult(){ + return $this->fetch('shops/goodsconsult/list'); + } + /** + * 商家回复 + */ + public function reply(){ + $m = new M(); + return $m->reply(); + } + /** + * 用户-商品咨询 + */ + public function myConsult(){ + return $this->fetch('users/my_consult'); + } + /** + * 用户-商品咨询列表查询 + */ + public function myConsultByPage(){ + $m = new M(); + return $m->myConsultByPage(); + } +} diff --git a/hyhproject/home2/controller/Goodsvirtuals.php b/hyhproject/home2/controller/Goodsvirtuals.php new file mode 100755 index 0000000..6e92606 --- /dev/null +++ b/hyhproject/home2/controller/Goodsvirtuals.php @@ -0,0 +1,81 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\GoodsVirtuals as M; +/** + * ============================================================================ + * 虚拟商品卡券控制器 + */ +class Goodsvirtuals extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 查看虚拟商品库存 + */ + public function stock(){ + $src = input('src','sale'); + if(!in_array($src,['sale','audit','store','stockWarnByPage','illegal']))$src = 'sale'; + $this->assign('src',$src); + $this->assign('id',(int)input('id')); + return $this->fetch("shops/goodsvirtuals/list"); + } + /** + * 获取虚拟商品库存列表 + */ + public function stockByPage(){ + $m = new M(); + $rs = $m->stockByPage(); + $rs['status'] = 1; + return $rs; + } + /** + * 跳去新增页 + */ + public function toAdd(){ + $this->assign('object',['cardNo'=>'','cardPwd'=>'','id'=>0]); + return $this->fetch('shops/goodsvirtuals/edit'); + } + /** + * 跳去编辑页 + */ + public function toEdit(){ + $m = new M(); + $rs = $m->get((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('shops/goodsvirtuals/edit'); + } + /** + * 生成卡券 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } + /** + * 导入卡券 + */ + public function importCards(){ + $rs = WSTUploadFile(); + if(json_decode($rs)->status==1){ + $m = new M(); + $rss = $m->importCards($rs); + return $rss; + } + return $rs; + } +} diff --git a/hyhproject/home2/controller/Helpcenter.php b/hyhproject/home2/controller/Helpcenter.php new file mode 100755 index 0000000..3e14a3f --- /dev/null +++ b/hyhproject/home2/controller/Helpcenter.php @@ -0,0 +1,40 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + */ +class Helpcenter extends Base{ + public function index(){ + return $this->view(); + } + + public function view(){ + //获取左侧列表 + $m = model('home/Articles'); + $list = $m->helpList(); + $data = $m->getHelpById(); + $this->assign('data',$data); + $this->assign('list',$list); + //面包屑导航 + $bcNav = []; + if(!empty($data)){ + $bcNav = $this->bcNav(); + } + $this->assign('bcNav',$bcNav); + return $this->fetch('articles/help'); + } + /** + * 记录解决情况 + */ + public function recordSolve(){ + $m = model('home/Articles'); + return $m->recordSolve(); + } + /** + * 面包屑导航 + */ + public function bcNav(){ + $m = model('home/Articles'); + return $m->bcNav(); + } +} \ No newline at end of file diff --git a/hyhproject/home2/controller/Imports.php b/hyhproject/home2/controller/Imports.php new file mode 100755 index 0000000..8eef30e --- /dev/null +++ b/hyhproject/home2/controller/Imports.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Imports as M; +/** + * ============================================================================ + * 默认控制器 + */ +class Imports extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 数据导入首页 + */ + public function index(){ + return $this->fetch('shops/import'); + } + + /** + * 上传商品数据 + */ + public function importGoods(){ + $rs = WSTUploadFile(); + if(json_decode($rs)->status==1){ + $m = new M(); + $rss = $m->importGoods($rs); + return $rss; + } + return $rs; + } +} diff --git a/hyhproject/home2/controller/Index.php b/hyhproject/home2/controller/Index.php new file mode 100755 index 0000000..703b7f6 --- /dev/null +++ b/hyhproject/home2/controller/Index.php @@ -0,0 +1,69 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Index extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['only'=>'getsysmessages'] + ]; + public function index(){ + $categorys = model('GoodsCats')->getFloors(); + $this->assign('floors',$categorys); + $this->assign('hideCategory',1); + + // 店铺街数据 + $shopStreet = model('shops')->indexShopQuery(); + $this->assign('shopStreet',$shopStreet); + //首页优惠券数据 + $m = new \addons\hyhcouponrec\model\Hyhcouponrec(); + $indexCouponsList = $m->indexCouponsList(); + //$indexCouponsList = model('/addons/hyhcouponrec/mode/hyhcouponrec')->indexCouponsList(); + $this->assign('indexCouponsList',$indexCouponsList); + // dump(coupon_list()); + return $this->fetch('index'); + } + /** + * 保存目录ID + */ + public function getMenuSession(){ + $menuId = input("post.menuId"); + $menuType = session('WST_USER.loginTarget'); + session('WST_MENUID3'.$menuType,$menuId); + } + /** + * 获取用户信息 + */ + public function getSysMessages(){ + $rs = model('Systems')->getSysMessages(); + return $rs; + } + /** + * 定位菜单以及跳转页面 + */ + public function position(){ + $menuId = (int)input("post.menuId"); + $menuType = ((int)input("post.menuType")==1)?1:0; + $menus = model('HomeMenus')->getParentId($menuId); + session('WST_MENID'.$menus['menuType'],$menus['parentId']); + session('WST_MENUID3'.$menuType,$menuId); + } + + /** + * 转换url + */ + public function transfor(){ + $data = input('param.'); + $url = $data['url']; + unset($data['url']); + echo Url($url,$data); + } + /** + * 保存url + */ + public function currenturl(){ + session('WST_HO_CURRENTURL',input('url')); + return WSTReturn("", 1); + } +} diff --git a/hyhproject/home2/controller/Informs.php b/hyhproject/home2/controller/Informs.php new file mode 100755 index 0000000..bcdac0d --- /dev/null +++ b/hyhproject/home2/controller/Informs.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Informs as M; +/** + * ============================================================================ + * 订单投诉控制器 + */ +class Informs extends Base{ + protected $beforeActionList = [ + 'checkAuth'=>['only'=>'index,queryusercomplainbypage,complain,savecomplain,getusercomplaindetail'], + 'checkShopAuth'=>['only'=>'shopcomplain,queryshopcomplainbypage,getshopcomplaindetail,respond,saverespond'] + ]; + /******************************** 用户 ******************************************/ + /** + * 查看举报列表 + */ + public function index(){ + return $this->fetch('users/informs/list_inform'); + } + /** + * 获取用户举报列表 + */ + public function queryUserInformPage(){ + $m = model('Informs'); + return $m->queryUserInformByPage(); + + } + /** + * 商品举报页面 + */ + public function inform(){ + $m = new M(); + $data = $m->inform(); + if($data['status'] == 1){ + $this->assign("data",$data); + return $this->fetch("users/informs/informs"); + }else{ + $this->assign("message",$data['msg']); + return $this->fetch("error_msg"); + } + } + /** + * 保存举报信息 + */ + public function saveInform(){ + return model('Informs')->saveInform(); + } + /** + * 用户查举报详情 + */ + public function getUserInformDetail(){ + $data = model('Informs')->getUserInformDetail(0); + $this->assign("data",$data); + return $this->fetch("users/informs/inform_detail"); + } + + + + + + +} diff --git a/hyhproject/home2/controller/Invoices.php b/hyhproject/home2/controller/Invoices.php new file mode 100755 index 0000000..2d79456 --- /dev/null +++ b/hyhproject/home2/controller/Invoices.php @@ -0,0 +1,48 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Invoices as M; +/** + * ============================================================================ + * 发票信息控制器 + */ +class Invoices extends Base{ + /** + * + */ + public function index(){ + $m = new M(); + $data = $m->pageQuery(); + $this->assign('invoiceId',(int)input('invoiceId')); + $this->assign('isInvoice',(int)input('isInvoice')); + $this->assign('data',$data); + return $this->fetch('invoices'); + } + /** + * 查询 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } + /** + * 删除 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/home2/controller/Logmoneys.php b/hyhproject/home2/controller/Logmoneys.php new file mode 100755 index 0000000..e0785d5 --- /dev/null +++ b/hyhproject/home2/controller/Logmoneys.php @@ -0,0 +1,77 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\LogMoneys as M; +/** + * ============================================================================ + * 资金流水控制器 + */ +class Logmoneys extends Base{ + protected $beforeActionList = [ + 'checkAuth'=>['only'=>'usermoneys,pageuserquery,touserrecharge'], + 'checkShopAuth'=>['only'=>'shopmoneys,pageshopquery,torecharge'] + ]; + /** + * 查看用户资金流水 + */ + public function usermoneys(){ + $rs = model('Users')->getFieldsById((int)session('WST_USER.userId'),['lockMoney','userMoney','rechargeMoney']); + $this->assign('object',$rs); + return $this->fetch('users/logmoneys/list'); + } + /** + * 查看商户资金流水 + */ + public function shopmoneys(){ + $shopId = (int)session('WST_USER.shopId'); + $rs = model('Shops')->getFieldsById($shopId,['lockMoney','shopMoney','noSettledOrderFee','paymentMoney']); + $rs['deposit'] = db('shops_deposit')->where(['shopId'=>$shopId])->field('payDeposit,cashDeposit,isFinish')->find(); + $this->assign('object',$rs); + return $this->fetch('shops/logmoneys/list'); + } + /** + * 获取用户数据 + */ + public function pageUserQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('logMoneys')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + /** + * 获取商家数据 + */ + public function pageShopQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $data = model('logMoneys')->pageQuery(1,$shopId); + return WSTReturn("", 1,$data); + } + /** + * 获取商家质保金流水 + */ + public function pageShopDeposit(){ + $shopId = (int)session('WST_USER.shopId'); + $data = model('logMoneys')->pageDeposit(1,$shopId); + return WSTReturn("", 1,$data); + } + + /** + * 充值[商家] + */ + public function toRecharge(){ + $payments = model('common/payments')->recharePayments('1'); + $this->assign('payments',$payments); + $chargeItems = model('common/ChargeItems')->queryList(); + $this->assign('chargeItems',$chargeItems); + return $this->fetch('shops/recharge/pay_step1'); + } + + /** + * 充值[用户] + */ + public function toUserRecharge(){ + $payments = model('common/payments')->recharePayments('1'); + $this->assign('payments',$payments); + $chargeItems = model('common/ChargeItems')->queryList(); + $this->assign('chargeItems',$chargeItems); + return $this->fetch('users/recharge/pay_step1'); + } +} diff --git a/hyhproject/home2/controller/Messages.php b/hyhproject/home2/controller/Messages.php new file mode 100755 index 0000000..97677c5 --- /dev/null +++ b/hyhproject/home2/controller/Messages.php @@ -0,0 +1,66 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 商城消息控制器 + */ +class Messages extends Base{ + protected $beforeActionList = ['checkAuth']; + /** + * 查看商城消息 + */ + public function index(){ + return $this->fetch('users/messages/list'); + } + /** + * 查看商城消息 + */ + public function shopMessage(){ + return $this->fetch('shops/messages/list'); + } + /** + * 获取数据 + */ + public function pageQuery(){ + $data = model('Messages')->pageQuery(); + return WSTReturn("", 1,$data); + } + /** + * 查看完整商城消息 + */ + public function showMsg(){ + $data = model('Messages')->getById(); + return $this->fetch('users/messages/show',['data'=>$data]); + } + public function showShopMsg(){ + $data = model('Messages')->getById(); + return $this->fetch('shops/messages/show',['data'=>$data]); + } + + /** + * 删除 + */ + public function del(){ + $m = model('Home/Messages'); + $rs = $m->del(); + return $rs; + } + /** + * 批量删除 + */ + public function batchDel(){ + $m = model('Home/Messages'); + $rs = $m->batchDel(); + return $rs; + } + /** + * 标记为已读 + */ + public function batchRead(){ + $m = model('Home/Messages'); + $rs = $m->batchRead(); + return $rs; + } + + +} diff --git a/hyhproject/home2/controller/News.php b/hyhproject/home2/controller/News.php new file mode 100755 index 0000000..0f7c715 --- /dev/null +++ b/hyhproject/home2/controller/News.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + */ +class News extends Base{ + /** + * 根据分类id获取文章列表 + */ + public function nList(){ + $m = model('home/articles'); + $pageObj = $m->nList(); + $news = $pageObj->toArray(); + // 分页页码 + $page = $pageObj->render(); + $this->assign('page',$page); + //获取左侧列表 + $leftList = $m->NewsList(); + $this->assign('list',$leftList); + $this->assign('newsList',$news['Rows']); + $this->assign('catId',(int)input('catId')); + //面包屑导航 + $bcNav = $this->bcNav(); + // 防止用户取出帮助中心分类 + foreach($bcNav as $k=>$v){ + if($v['catId']==7){ + $bcNav = []; + break; + } + } + // 获取title + $currTitle = ''; + foreach($bcNav as $k=>$v){ + if($v['catId']==(int)input('catId'))$currTitle = $v['catName']; + } + $this->assign('title',$currTitle); + $this->assign('bcNav',$bcNav); + // 防止没有数据时报错 + if(empty($bcNav))$this->redirect('home/News/view'); + return $this->fetch('articles/news_list'); + } + + public function view(){ + //获取左侧列表 + $m = model('home/Articles'); + $list = $m->NewsList(); + //当前分类id + $content = $m->getNewsById(); + if(63 == $content['catId']) $this->error('请付费后查看!','/newscats-63.html'); + $this->assign('catId',(int)$content['catId']); + $this->assign('list',$list); + $this->assign('content',$content); + + + //面包屑导航 + $bcNav = []; + if(!empty($content)){ + $bcNav = $this->bcNav(); + } + $this->assign('bcNav',$bcNav); + + + if((int)input('id')==0){ + // 资讯列表下的新闻 + $pageObj = $m->getArticles(); + $news = $pageObj->toArray(); + // 分页页码 + $page = $pageObj->render(); + $this->assign('page',$page); + $this->assign('index',$news['Rows']); + } + + return $this->fetch('articles/news_view'); + } + public function bcNav(){ + $m = model('home/Articles'); + return $m->bcNav(); + } + + public function index(){ + return $this->view(); + } +} \ No newline at end of file diff --git a/hyhproject/home2/controller/Ordercomplains.php b/hyhproject/home2/controller/Ordercomplains.php new file mode 100755 index 0000000..bf900c2 --- /dev/null +++ b/hyhproject/home2/controller/Ordercomplains.php @@ -0,0 +1,94 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 订单投诉控制器 + */ +class OrderComplains extends Base{ + protected $beforeActionList = [ + 'checkAuth'=>['only'=>'index,queryusercomplainbypage,complain,savecomplain,getusercomplaindetail'], + 'checkShopAuth'=>['only'=>'shopcomplain,queryshopcomplainbypage,getshopcomplaindetail,respond,saverespond'] + ]; + /******************************** 用户 ******************************************/ + /** + * 查看投诉列表 + */ + public function index(){ + return $this->fetch('users/orders/list_complain'); + } + /** + * 获取用户投诉列表 + */ + public function queryUserComplainByPage(){ + $m = model('OrderComplains'); + return $m->queryUserComplainByPage(); + + } + /** + * 订单投诉页面 + */ + public function complain(){ + $data = model('OrderComplains')->getOrderInfo(); + $this->assign("data",$data); + return $this->fetch("users/orders/complain"); + } + /** + * 保存订单投诉信息 + */ + public function saveComplain(){ + return model('OrderComplains')->saveComplain(); + } + /** + * 用户查投诉详情 + */ + public function getUserComplainDetail(){ + $data = model('OrderComplains')->getComplainDetail(0); + $this->assign("data",$data); + return $this->fetch("users/orders/complain_detail"); + } + + + /******************************* 商家 ****************************************/ + /** + * 商家-查看投诉列表 + */ + public function shopComplain(){ + return $this->fetch("shops/orders/list_complain"); + } + + /** + * 获取商家被投诉订单列表 + */ + public function queryShopComplainByPage(){ + return model('OrderComplains')->queryShopComplainByPage(); + } + + /** + * 查投诉详情 + */ + public function getShopComplainDetail(){ + $data = model('OrderComplains')->getComplainDetail(1); + $this->assign("data",$data); + return $this->fetch("shops/orders/complain_detail"); + } + + /** + * 订单应诉页面 + */ + public function respond(){ + $data = model('OrderComplains')->getComplainDetail(1); + $this->assign("data",$data); + return $this->fetch("shops/orders/respond"); + } + /** + * 保存订单应诉 + */ + public function saveRespond(){ + return model('OrderComplains')->saveRespond(); + } + + + + + +} diff --git a/hyhproject/home2/controller/Orderrefunds.php b/hyhproject/home2/controller/Orderrefunds.php new file mode 100755 index 0000000..314cf3c --- /dev/null +++ b/hyhproject/home2/controller/Orderrefunds.php @@ -0,0 +1,29 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\OrderRefunds as M; +/** + * ============================================================================ + * 订单退款控制器 + */ +class Orderrefunds extends Base{ + protected $beforeActionList = [ + 'checkAuth'=>['only'=>'refund'], + 'checkShopAuth'=>['only'=>'shoprefund'] + ]; + /** + * 用户申请退款 + */ + public function refund(){ + $m = new M(); + $rs = $m->refund(); + return $rs; + } + /** + * 商家处理是否同意 + */ + public function shopRefund(){ + $m = new M(); + $rs = $m->shopRefund(); + return $rs; + } +} diff --git a/hyhproject/home2/controller/Orders.php b/hyhproject/home2/controller/Orders.php new file mode 100755 index 0000000..43b71fb --- /dev/null +++ b/hyhproject/home2/controller/Orders.php @@ -0,0 +1,415 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Orders as M; +/** + * ============================================================================ + * 订单控制器 + */ +class Orders extends Base{ + /** + * 提交虚拟订单 + */ + public function quickSubmit(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->quickSubmit(); + return $rs; + } + /** + * 提交订单 + */ + public function submit(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->submit(); + return $rs; + } + /** + * 订单提交成功 + */ + public function succeed(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->getByUnique(); + $this->assign('object',$rs); + if(!empty($rs['list'])){ + if($rs['payType']==1 && $rs['totalMoney']>0){ + $this->assign('orderNo',input("get.orderNo")); + $this->assign('isBatch',(int)input("get.isBatch/d",1)); + $this->assign('rs',$rs); + return $this->fetch('order_pay_step1'); + }else{ + return $this->fetch('order_success'); + } + }else{ + $this->assign('message','Sorry~您要找的页面丢失了。。。'); + return $this->fetch('error_msg'); + } + } + /** + * 用户-提醒发货 + */ + public function noticeDeliver(){ + $m = new M(); + return $m->noticeDeliver(); + } + + + /** + * 用户-待付款订单 + */ + public function waitPay(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_wait_pay'); + } + /** + * 用户-获取待付款列表 + */ + public function waitPayByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage(-2); + return WSTReturn("", 1,$rs); + } + /** + * 等待收货 + */ + public function waitReceive(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_wait_receive'); + } + /** + * 获取收货款列表 + */ + public function waitReceiveByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage([0,1]); + return WSTReturn("", 1,$rs); + } + /** + * 用户-待评价 + */ + public function waitAppraise(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_appraise'); + } + /** + * 用户-待评价 + */ + public function waitAppraiseByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage(2,0); + return WSTReturn("", 1,$rs); + } + /** + * 用户-已完成订单 + */ + public function finish(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_finish'); + } + /** + * 用户-已完成订单 + */ + public function finishByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage(2,-1); + return WSTReturn("", 1,$rs); + } + /** + * 用户-加载取消订单页面 + */ + public function toCancel(){ + $this->checkAuth(); + return $this->fetch('users/orders/box_cancel'); + } + + /** + * 用户取消订单 + */ + public function cancellation(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->cancel(); + return $rs; + } + /** + * 用户-取消订单列表 + */ + public function cancel(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_cancel'); + } + /** + * 用户-获取已取消订单 + */ + public function cancelByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage(-1); + return WSTReturn("", 1,$rs); + } + /** + * 用户-拒收订单 + */ + public function toReject(){ + $this->checkAuth(); + return $this->fetch('users/orders/box_reject'); + } + /** + * 用户拒收订单 + */ + public function reject(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->reject(); + return $rs; + } + /** + * 用户-申请退款 + */ + public function toRefund(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->getMoneyByOrder((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('users/orders/box_refund'); + } + + /** + * 商家-操作退款 + */ + public function toShopRefund(){ + $this->checkShopAuth(); + $rs = model('OrderRefunds')->getRefundMoneyByOrder((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('shops/orders/box_refund'); + } + + /** + * 用户-拒收/退款列表 + */ + public function abnormal(){ + $this->checkAuth(); + return $this->fetch('users/orders/list_abnormal'); + } + /** + * 获取用户拒收/退款列表 + */ + public function abnormalByPage(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->userOrdersByPage([-3]); + return WSTReturn("", 1,$rs); + } + + + + /** + * 等待处理订单 + */ + public function waitDelivery(){ + $this->checkShopAuth(); + $express = model('Express')->listQuery(); + $this->assign('express',$express); + return $this->fetch('shops/orders/list_wait_delivery'); + } + /** + * 待处理订单 + */ + public function waitDeliveryByPage(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->shopOrdersByPage([0]); + return WSTReturn("", 1,$rs); + } + + /** + * 商家-已发货订单 + */ + public function delivered(){ + $this->checkShopAuth(); + $express = model('Express')->listQuery(); + $this->assign('express',$express); + return $this->fetch('shops/orders/list_delivered'); + } + /** + * 待处理订单 + */ + public function deliveredByPage(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->shopOrdersByPage(1); + return WSTReturn("", 1,$rs); + } + + /** + * 商家发货 + */ + public function deliver(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->deliver(); + return $rs; + } + /** + * 商家修改快递单号 + */ + public function updateDeliver(){ + $this->checkShopAuth(); + $m = new M(); + $res = $m->updateDeliver(); + return $res; + } + /** + * 用户收货 + */ + public function receive(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->receive(); + return $rs; + } + /** + * 用户-延时收货 + */ + public function delay(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->delay(); + return $rs; + } + /** + * 商家-已完成订单 + */ + public function finished(){ + $this->checkShopAuth(); + $express = model('Express')->listQuery(); + return $this->fetch('shops/orders/list_finished'); + } + /** + * 商家-已完成订单 + */ + public function finishedByPage(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->shopOrdersByPage(2); + return WSTReturn("", 1,$rs); + } + /** + * 商家-取消/拒收订单 + */ + public function failure(){ + $this->checkShopAuth(); + return $this->fetch('shops/orders/list_failure'); + } + /** + * 商家-取消/拒收订单 + */ + public function failureByPage(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->shopOrdersByPage([-1,-3]); + return WSTReturn("", 1,$rs); + } + /** + * 获取订单信息方便修改价格 + */ + public function getMoneyByOrder(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->getMoneyByOrder(); + return WSTReturn("", 1,$rs); + } + /** + * 商家修改订单价格 + */ + public function editOrderMoney(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->editOrderMoney(); + return $rs; + } + /** + * 商家-订单详情 + */ + public function view(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->getByView((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('shops/orders/view'); + } + /** + * 订单打印 + */ + public function orderPrint(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->getByView((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('shops/orders/print'); + } + + /** + * 用户-订单详情 + */ + public function detail(){ + $this->checkAuth(); + $m = new M(); + $rs = $m->getByView((int)input('id')); + $this->assign('object',$rs); + return $this->fetch('users/orders/view'); + } + + /** + * 用户-评价页 + */ + public function orderAppraise(){ + $this->checkAuth(); + $m = new M(); + //根据订单id获取 商品信息跟商品评价 + $data = $m->getOrderInfoAndAppr(); + $this->assign(['data'=>$data['Rows'], + 'count'=>$data['count'], + 'alreadys'=>$data['alreadys'] + ]); + return $this->fetch('users/orders/list_order_appraise'); + } + /** + * 设置完成评价 + */ + public function complateAppraise($orderId){ + $this->checkAuth(); + $m = new M(); + return $m->complateAppraise($orderId); + } + /** + * 商家-待付款订单 + */ + public function waituserPay(){ + $this->checkShopAuth(); + return $this->fetch('shops/orders/list_wait_pay'); + } + /** + * 商家-获取待付款列表 + */ + public function waituserPayByPage(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->shopOrdersByPage(-2); + return WSTReturn("", 1,$rs); + } + /** + * 导出订单 + */ + public function toExport(){ + $this->checkShopAuth(); + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} diff --git a/hyhproject/home2/controller/Reports.php b/hyhproject/home2/controller/Reports.php new file mode 100755 index 0000000..2bc4a6c --- /dev/null +++ b/hyhproject/home2/controller/Reports.php @@ -0,0 +1,47 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Reports as M; +/** + * ============================================================================ + * 报表控制器 + */ +class Reports extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 商品销售排行 + */ + public function topSaleGoods(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch('shops/reports/top_sale_goods'); + } + public function getTopSaleGoods(){ + $m = new M(); + return $m->getTopSaleGoods(); + } + /** + * 获取销售额 + */ + public function statSales(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch('shops/reports/stat_sales'); + } + public function getStatSales(){ + $m = new M(); + return $m->getStatSales(); + } + + /** + * 获取销售订单 + */ + public function statOrders(){ + $this->assign("startDate",date('Y-m-d',strtotime("-1month"))); + $this->assign("endDate",date('Y-m-d')); + return $this->fetch('shops/reports/stat_orders'); + } + public function getStatOrders(){ + $m = new M(); + return $m->getStatOrders(); + } +} diff --git a/hyhproject/home2/controller/Settlements.php b/hyhproject/home2/controller/Settlements.php new file mode 100755 index 0000000..6f21900 --- /dev/null +++ b/hyhproject/home2/controller/Settlements.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Settlements as M; +/** + * ============================================================================ + * 结算控制器 + */ +class Settlements extends Base{ + protected $beforeActionList = ['checkShopAuth']; + public function index(){ + return $this->fetch('shops/settlements/list'); + } + + /** + * 获取结算单 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + return WSTReturn('',1,$rs); + } + /** + * 获取待结算订单 + */ + public function pageUnSettledQuery(){ + $m = new M(); + $rs = $m->pageUnSettledQuery(); + return WSTReturn('',1,$rs); + } + /** + * 结算订单 + */ + public function settlement(){ + $m = new M(); + return $m->settlement(); + } + /** + * 获取已结算订单 + */ + public function pageSettledQuery(){ + $m = new M(); + $rs = $m->pageSettledQuery(); + return WSTReturn('',1,$rs); + } + /** + * 查看结算详情 + */ + public function view(){ + $m = new M(); + $rs = $m->getById(); + $this->assign('object',$rs); + return $this->fetch('shops/settlements/view'); + } + /** + * 导出订单 + */ + public function toExport(){ + $m = new M(); + $rs = $m->toExport(); + $this->assign('rs',$rs); + } +} diff --git a/hyhproject/home2/controller/Shopcats.php b/hyhproject/home2/controller/Shopcats.php new file mode 100755 index 0000000..91859b5 --- /dev/null +++ b/hyhproject/home2/controller/Shopcats.php @@ -0,0 +1,98 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\ShopCats as M; +/** + * ============================================================================ + * 门店分类控制器 + */ +class Shopcats extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->getCatAndChild(session('WST_USER.shopId'),input('post.parentId/d')); + // mark 添加省份 20180518 by zl + $areas = $m->getAreas(); + $this->assign('areas',$areas); + // 判断是否是自营 如果是自营就显示省份 + $shopId = (int)session('WST_USER.shopId');; + $this->assign('shopId',$shopId); + // end + $this->assign('list',$list); + return $this->fetch("shops/shopcats/list"); + } + + /** + * 修改名称 + */ + public function editName(){ + $m = new M(); + $rs = array(); + if(input('post.id/d')>0){ + $rs = $m->editName(); + } + return $rs; + } + /** + * 修改排序 + */ + public function editSort(){ + $m = new M(); + $rs = array(); + if(input('post.id/d')>0){ + $rs = $m->editSort(); + } + return $rs; + } + /** + * 批量保存商品分类 + */ + public function batchSaveCats(){ + $m = new M(); + $rs = $m->batchSaveCats(); + return $rs; + } + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $list = $m->listQuery((int)session('WST_USER.shopId'),input('post.parentId/d')); + $rs = array(); + $rs['status'] = 1; + $rs['list'] = $list; + return $rs; + } + + public function changeCatStatus(){ + $m = new M(); + $rs = $m->changeCatStatus(); + return $rs; + } + + + + + + /** + * 设置分类特产省份 mark 20180515 + */ + public function setSpecial(){ + $m = new M(); + $rs = $m->setSpecial(); + return $rs; + } + +} diff --git a/hyhproject/home2/controller/Shopconfigs.php b/hyhproject/home2/controller/Shopconfigs.php new file mode 100755 index 0000000..1709096 --- /dev/null +++ b/hyhproject/home2/controller/Shopconfigs.php @@ -0,0 +1,31 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 门店配置控制器 + */ +class Shopconfigs extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 店铺设置 + */ + public function toShopCfg(){ + //获取商品信息 + $m = model('ShopConfigs'); + $this->assign('object',$m->getShopCfg((int)session('WST_USER.shopId'))); + return $this->fetch('shops/shopconfigs/shop_cfg'); + } + + /** + * 新增/修改 店铺设置 + */ + public function editShopCfg(){ + $shopId = (int)session('WST_USER.shopId'); + $m = model('ShopConfigs'); + if($shopId>0){ + $rs = $m->editShopCfg($shopId); + } + return $rs; + } + +} diff --git a/hyhproject/home2/controller/Shopfreights.php b/hyhproject/home2/controller/Shopfreights.php new file mode 100755 index 0000000..7c535cd --- /dev/null +++ b/hyhproject/home2/controller/Shopfreights.php @@ -0,0 +1,38 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopFreights as M; +use wstmart\home\model\Areas; +use wstmart\home\model\Shops; +/** + * ============================================================================ + * 运费控制器 + */ +class Shopfreights extends Base{ + protected $beforeActionList = ['checkShopAuth']; + /** + * 查看运费设置 + */ + public function index(){ + $shops = new Shops(); + $shopId = session('WST_USER.shopId'); + $shFreight = $shops->getShopsFreight($shopId); + $this->assign('shFreight',$shFreight);//默认运费 + return $this->fetch('shops/freights/list'); + } + /** + * 运费列表 + */ + public function listProvince(){ + $m = new M(); + return $m->listProvince(); + } + + /** + * 编辑 + */ + public function edit(){ + $m = new M(); + $rs = $m->edit(); + return $rs; + } +} diff --git a/hyhproject/home2/controller/Shoproles.php b/hyhproject/home2/controller/Shoproles.php new file mode 100755 index 0000000..351a227 --- /dev/null +++ b/hyhproject/home2/controller/Shoproles.php @@ -0,0 +1,74 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopRoles as M; +/** + * ============================================================================ + * 门店角色控制器 + */ +class Shoproles extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->pageQuery(); + $this->assign('list',$list); + return $this->fetch("shops/shoproles/list"); + } + + /** + * 查询 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 新增角色 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('shop_roles'); + $data = ['object'=>$object]; + return $this->fetch('shops/shoproles/edit',$data); + } + + /** + * 新增角色 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 修改角色 + */ + public function edit(){ + $m = new M(); + $object = $m->getById((int)input('get.id')); + $data = ['object'=>$object]; + return $this->fetch('shops/shoproles/edit',$data); + } + + /** + * 修改角色 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + +} diff --git a/hyhproject/home2/controller/Shops.php b/hyhproject/home2/controller/Shops.php new file mode 100755 index 0000000..d1d502b --- /dev/null +++ b/hyhproject/home2/controller/Shops.php @@ -0,0 +1,358 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\Goods; +use wstmart\common\model\GoodsCats; +use think\Loader; +/** + * ============================================================================ + * 门店控制器 + */ + +class Shops extends Base{ + protected $beforeActionList = [ + 'checkShopAuth' => ['only'=>'editinfo,getshopmoney'], + 'checkAuth'=>['only'=>'join,joinstep1,joinstep2,savestep2,joinstep3,savestep3,joinstep4,savestep4,joinstep5,savestep5,joinsuccess'] + ]; + /** + * 店铺公告页 + */ + public function notice(){ + $notice = model('shops')->getNotice(); + $this->assign('notice',$notice); + return $this->fetch('shops/shops/notice'); + } + /** + * 修改店铺公告 + */ + public function editNotice(){ + $s = model('shops'); + return $s->editNotice(); + } + /** + * 商家登录 + */ + public function login(){ + $USER = session('WST_USER'); + if(!empty($USER) && isset($USER['shopId'])){ + $this->redirect("shops/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('shop_login'); + } + /** + * 商家中心 + */ + public function index(){ + session('WST_MENID1',null); + session('WST_MENUID31',null); + $s = model('shops'); + dump(session('WST_USER')); + $data = $s->getShopSummary((int)session('WST_USER.shopId')); + $this->assign('data',$data); + return $this->fetch('shops/index'); + } + /** + * 店铺街 + */ + public function shopStreet(){ + $g = new GoodsCats(); + $goodsCats = $g->listQuery(0); + $this->assign('goodscats',$goodsCats); + //店铺街列表 + $s = model('shops'); + $pagesize = 10; + $selectedId = input("get.id/d"); + $this->assign('selectedId',$selectedId); + $list = $s->pageQuery($pagesize); + $this->assign('list',$list); + $this->assign('keyword',input('keyword')); + $this->assign('keytype',1); + return $this->fetch('shop_street'); + } + /** + * 店铺详情 + */ + public function home(){ + $shopId = (int)input("param.shopId/d"); + hook("homeBeforeGoShopHome",["shopId"=>$shopId]); + hook("goShopAfterAddView",["shopId"=>$shopId,'path'=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo($shopId); + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(1778 != $shopId && !empty($this->is_icp)) return $this->fetch('error_lost'); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect(Url('home/shops/selfShop'),$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + //dump($data['list']);die; + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + return $this->fetch('shop_home'); + } + + /** + * 店铺分类 + */ + public function cat(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d"); + $data['shop'] = $s->getShopInfo($shopId); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)){ + $params = input(); + unset($params["shopId"]); + $this->redirect('shops/selfShop',$params); + } + if(empty($data['shop']))return $this->fetch('error_lost'); + $data['shopcats'] = $f = model('ShopCats','model')->getShopCats($shopId); + $g = model('goods'); + $data['list'] = $g->shopGoods($shopId); + $this->assign('msort',input("param.msort/d",0));//筛选条件 + $this->assign('mdesc',input("param.mdesc/d",1));//升降序 + $this->assign('sprice',input("param.sprice"));//价格范围 + $this->assign('eprice',input("param.eprice")); + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + return $this->fetch('shop_home'); + } + + /** + * 查看店铺设置 + */ + public function info(){ + $s = model('shops'); + $object = $s->getByView((int)session('WST_USER.shopId')); + $bankList= model('banks')->listQuery(); + $this->assign('bankList',$bankList); + $this->assign('object',$object); + return $this->fetch('shops/shops/view'); + } + /** + * 自营店铺 + */ + public function selfShop(){ + hook("homeBeforeGoSelfShop",["shopId"=>1]); + $s = model('shops'); + $data['shop'] = $s->getShopInfo(1); + if(empty($data['shop']))return $this->fetch('error_lost'); + $this->assign('selfShop',1); + $data['shopcats'] = model('ShopCats')->getShopCats(1); + $this->assign('goodsName',urldecode(input("param.goodsName")));//搜索 + // 店长推荐 + $data['rec'] = $s->getRecGoods('rec',6); + // 热销商品 + $data['hot'] = $s->getRecGoods('hot',6); + $this->assign('data',$data); + return $this->fetch('self_shop'); + } + + /** + * 编辑店铺资料 + */ + public function editInfo(){ + + $rs = model('shops')->editInfo(); + return $rs; + } + + /** + * 获取店铺金额 + */ + public function getShopMoney(){ + $rs = model('shops')->getFieldsById((int)session('WST_USER.shopId'),'shopMoney,lockMoney,rechargeMoney'); + $urs = model('users')->getFieldsById((int)session('WST_USER.userId'),'payPwd'); + $rs['isSetPayPwd'] = ($urs['payPwd']=='')?0:1; + $rs['isDraw'] = ((float)WSTConf('CONF.drawCashShopLimit')<=$rs['shopMoney'])?1:0; + unset($urs); + return WSTReturn('',1,$rs); + } + + + /** + * 跳去商家入驻 + */ + public function join(){ + $rs = model('shops')->checkApply(); + $this->assign('isApply',(!empty($rs) && $rs['applyStatus']>=1)?1:0); + $this->assign('applyStep',empty($rs)?1:$rs['applyStep']); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['105']))$articles['105']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['106']))$articles['106']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['107']))$articles['107']['articleContent'] = '无相关说明,请咨询商城客服~'; + if(!isset($articles['108']))$articles['108']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join'); + } + + public function joinStep1(){ + session('apply_step',1); + $rs = model('shops')->checkApply(); + $articles = model('Articles')->getArticlesByCat(53); + // 防止不存在入驻文章时报错 + if(!isset($articles['109']))$articles['109']['articleContent'] = '无相关说明,请咨询商城客服~'; + $this->assign('artiles',$articles); + return $this->fetch('shop_join_step1'); + } + public function joinStep2(){ + $step = (int)session('apply_step'); + if($step<1){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',2); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step2'); + } + public function saveStep2(){ + $step = (int)session('apply_step'); + if($step<2){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep1')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep2($data); + } + } + public function joinStep3(){ + $step = (int)session('apply_step'); + if($step<2){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',3); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step3'); + } + public function saveStep3(){ + $step = (int)session('apply_step'); + if($step<3){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep2')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep3($data); + } + } + public function joinStep4(){ + $step = (int)session('apply_step'); + if($step<3){ + $this->redirect(Url('home/shops/joinStep4')); + exit(); + } + session('apply_step',4); + $areas = model('Areas')->listQuery(); + $this->assign('areaList',$areas); + $banks = model('banks')->listQuery(); + $this->assign('bankList',$banks); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step4'); + } + public function saveStep4(){ + $step = (int)session('apply_step'); + if($step<4){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep3')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep4($data); + } + } + public function joinStep5(){ + $step = (int)session('apply_step'); + if($step<4){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + } + session('apply_step',5); + $shopLicense=db('shop_license')->alias('a') + ->join('shops b','b.shopId= a.shopId') + ->where('b.userId',(int)session("WST_USER.userId"))->find(); + $this->assign('shopLicense',$shopLicense); + $goodsCatList = model('goodsCats')->listQuery(0); + $this->assign('goodsCatList',$goodsCatList); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_step5'); + } + public function saveStep5(){ + $step = (int)session('apply_step'); + if($step<5){ + return WSTReturn('请勿跳过申请步骤'); + } + $data = input('post.'); + $validate = Loader::validate('Shops'); + if(!$validate->check($data,[],'applyStep4')){ + return WSTReturn($validate->getError()); + }else{ + return model('shops')->saveStep5($data); + } + } + public function joinSuccess(){ + $step = (int)session('apply_step'); + if($step<5){ + $this->redirect(Url('home/shops/joinStep1')); + } + session('apply_step',5); + $apply = model('shops')->getShopApply(); + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + /** + * 入驻进度查询 + */ + public function checkapplystatus(){ + $apply = model('shops')->getShopApply(); + if(empty($apply)){ + $this->redirect(Url('home/shops/joinStep1')); + exit(); + }else{ + if($apply['applyStatus']==0){ + session('apply_step',$apply['applyStep']); + $this->redirect(Url('home/shops/joinStep'.$apply['applyStep'])); + exit(); + }else{ + $this->assign('apply',$apply); + return $this->fetch('shop_join_success'); + } + } + } +} diff --git a/hyhproject/home2/controller/Shopusers.php b/hyhproject/home2/controller/Shopusers.php new file mode 100755 index 0000000..9fa4d25 --- /dev/null +++ b/hyhproject/home2/controller/Shopusers.php @@ -0,0 +1,76 @@ +<?php +namespace wstmart\home\controller; +use wstmart\home\model\ShopUsers as M; +/** + * ============================================================================ + * 门店角色控制器 + */ +class Shopusers extends Base{ + protected $beforeActionList = ['checkShopAuth']; + + /** + * 列表 + */ + public function index(){ + $m = new M(); + $list = $m->pageQuery(); + $this->assign('list',$list); + return $this->fetch("shops/shopusers/list"); + } + + /** + * 查询 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + + /** + * 新增店铺管理员 + */ + public function add(){ + $m = new M(); + $object = $m->getEModel('shop_roles'); + $roles = model("ShopRoles")->listQuery(); + $data = ['object'=>$object,"roles"=>$roles]; + return $this->fetch('shops/shopusers/add',$data); + } + + /** + * 新增店铺管理员 + */ + public function toAdd(){ + $m = new M(); + return $m->add(); + } + + /** + * 修改店铺管理员 + */ + public function edit(){ + $m = new M(); + $object = $m->getById(input('get.id')); + $roles = model("ShopRoles")->listQuery(); + $data = ['object'=>$object,"roles"=>$roles]; + return $this->fetch('shops/shopusers/edit',$data); + } + + /** + * 编辑店铺管理员 + */ + public function toEdit(){ + $m = new M(); + return $m->edit(); + } + + /** + * 删除操作 + */ + public function del(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + +} diff --git a/hyhproject/home2/controller/Switchs.php b/hyhproject/home2/controller/Switchs.php new file mode 100755 index 0000000..cb998d5 --- /dev/null +++ b/hyhproject/home2/controller/Switchs.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\home\controller; +/** + * ============================================================================ + * 关闭提示处理控制器 + */ +use think\Controller; +class Switchs extends Controller{ + public function __construct(){ + parent::__construct(); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPCStyleId')); + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wsthomeStyle')?WSTConf('CONF.wsthomeStyle'):'default'; + $replace['__STYLE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/home/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + } + public function index(){ + return $this->fetch('error_switch'); + } +} diff --git a/hyhproject/home2/controller/Tmp.php b/hyhproject/home2/controller/Tmp.php new file mode 100755 index 0000000..46b7cbb --- /dev/null +++ b/hyhproject/home2/controller/Tmp.php @@ -0,0 +1,183 @@ +<?php +namespace wstmart\home\controller; +Vendor('web3.vendor.autoload'); +use \PHPUnit\Framework\TestCase as BaseTestCase; +use Web3\Web3; +/** + * ============================================================================ + * 默认控制器 + */ +class Tmp extends Base{ + /** + * web3 + * + * @var \Web3\Web3 + */ + protected $web3; + + /** + * testRinkebyHost + * + * @var string + */ + protected $testRinkebyHost = 'http://localhost'; + + /** + * testHost + * + * @var string + */ + protected $testHost = 'http://localhost:8545'; + + /** + * coinbase + * + * @var string + */ + protected $coinbase; + + /** + * setUp + * + * @return void + */ + public function index(){ + //Loader::import('web3.src.Web3'); + + $web3 = new Web3($this->testHost); + $this->web3 = $web3; + $personal = $web3->personal; + // $personal->batch(true); + // $personal->listAccounts(); + // $personal->newAccount('123456'); + + // $personal->provider->execute(function ($err, $data) { + // if ($err !== null) { + // // do something + // return; + // } + // // do something + // }); + //dump($personal); + $web3->eth->coinbase(function ($err, $coinbase) { + if ($err !== null) { + dump($this->fail($err->getMessage())); + } + $this->coinbase = $coinbase; + }); + + $eth = $web3->eth; + $eth->accounts(function ($err, $accounts) use ($eth) { + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + dump($accounts); + }); + // $personal->unlockAccount($this->coinbase, '123456', function ($err, $unlocked) { + // if ($err !== null) { + // echo 'Error: ' . $err->getMessage(); + // return; + // } + // if ($unlocked) { + // echo 'New account is unlocked!' . PHP_EOL; + // } else { + // echo 'New account isn\'t unlocked' . PHP_EOL; + // } + // }); + + + + $web3->eth->getBalance( $this->coinbase , function ($err, $balance) { + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + echo 'Balance: ' . $balance->toString() . PHP_EOL; + }); + + + + $newAccount = ''; + + + $web3->personal->newAccount('123456', function ($err, $account) use (&$newAccount) { + dump($err); + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + $newAccount = $account; + echo 'New account: ' . $account . PHP_EOL; + }); + + dump($this->coinbase); + // $web3->eth->getWork(function ($err, $coinbase) { + // if ($err !== null) { + // dump($this->fail($err->getMessage())); + // } + // dump($coinbase); + // }); + + + + // $web3->clientVersion(function ($err, $version) { + // if ($err !== null) { + // // do something + // return; + // } + // dump($version);die; + // if (isset($client)) { + // echo 'Client version: ' . $version; + // } + // }); + die; + + + + + + $web3 = new Web3('http://localhost:8545'); + //$getPersonal = $web3->getEth; + + $personal = $web3->personal; + + $newAccount = ''; + + echo 'Personal Create Account and Unlock Account' . PHP_EOL; + + // create account + $personal->newAccount('123456', function ($err, $account) use (&$newAccount) { + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + $newAccount = $account; + echo 'New account: ' . $account . PHP_EOL; + }); + + $personal->unlockAccount($newAccount, '123456', function ($err, $unlocked) { + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + if ($unlocked) { + echo 'New account is unlocked!' . PHP_EOL; + } else { + echo 'New account isn\'t unlocked' . PHP_EOL; + } + }); + + + // get balance + $web3->eth->getBalance($newAccount, function ($err, $balance) { + if ($err !== null) { + echo 'Error: ' . $err->getMessage(); + return; + } + echo 'Balance: ' . $balance->toString() . PHP_EOL; + }); + + die; + } +} diff --git a/hyhproject/home2/controller/Unionpays.php b/hyhproject/home2/controller/Unionpays.php new file mode 100755 index 0000000..662091c --- /dev/null +++ b/hyhproject/home2/controller/Unionpays.php @@ -0,0 +1,230 @@ +<?php +namespace wstmart\home\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 银联支付控制器 + */ +class Unionpays extends Base{ + + /** + * 初始化 + */ + private $unionConfig; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('unionpay.sdk.acp_service'); + $m = new M(); + $this->unionConfig = $m->getPayment("unionpays"); + + $config = array(); + $config["signCertPwd"] = $this->unionConfig["unionSignCertPwd"];//"000000" + $config["signMethod"] = "01"; + $config["frontUrl"] = url("home/unionpays/response","",true,true); + $config["backUrl"] = url("home/unionpays/notify","",true,true); + new \SDKConfig($config); + } + + + public function getUnionpaysUrl(){ + $m = new OM(); + $payObj = input("payObj/s"); + $data = array(); + if($payObj=="recharge"){ + $needPay = input("needPay/d"); + $data["status"] = $needPay>0?1:-1; + }else{ + $userId = (int)session('WST_USER.userId'); + $data = $m->checkOrderPay(); + } + return $data; + } + + /** + * 生成支付代码 + * @param array $order 订单信息 + * @param array $config_value 支付方式信息 + */ + public function toUnionpays(){ + + $payObj = input("payObj/s"); + $m = new OM(); + $obj = array(); + $data = array(); + $orderAmount = 0; + $orderId = ""; + $extra_param = ""; + if($payObj=="recharge"){//充值 + + $itmeId = (int)input("itmeId/d"); + $orderAmount = 0; + if($itmeId>0){ + $item = $cm->getItemMoney($itmeId); + $orderAmount = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $orderAmount = (int)input("needPay/d"); + } + $shopId = (int)session('WST_USER.shopId'); + $targetType = ($shopId>0)?1:0; + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = $shopId; + } + + $data["status"] = $orderAmount>0?1:-1; + $orderId = WSTOrderNo(); + $extra_param = $payObj."|".$targetId."|".$targetType."|".$itmeId; + + }else{ + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $data = $m->checkOrderPay($obj); + if($data["status"]==1){ + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $order = $m->getPayOrders($obj); + $orderAmount = $order["needPay"]; + $payRand = $order["payRand"]; + $orderId = $obj["orderNo"]."a".$payRand; + $extra_param = $payObj."|".$userId."|".$obj["isBatch"]; + } + } + + if($data["status"]==1){ + $params = array( + //以下信息非特殊情况不需要改动 + 'version' => \SDKConfig::$version, //版本号 + 'encoding' => 'utf-8', //编码方式 + 'txnType' => '01', //交易类型 + 'txnSubType' => '01', //交易子类 + 'bizType' => '000201', //业务类型 + 'frontUrl' => \SDKConfig::$frontUrl, //前台通知地址 + 'backUrl' => \SDKConfig::$backUrl, //后台通知地址 + 'signMethod' => \SDKConfig::$signMethod,//签名方法 + 'channelType' => '07', //渠道类型,07-PC,08-手机 + 'accessType' => '0', //接入类型 + 'currencyCode' => '156', //交易币种,境内商户固定156 + //TODO 以下信息需要填写 + 'merId' => $this->unionConfig["unionMerId"], //"777290058110048",//商户代码 + 'orderId' => $orderId, //商户订单号,8-32位数字字母,不能含“-”或“_” + 'txnTime' => date('YmdHis'), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间 + 'txnAmt' => $orderAmount*100, //交易金额,单位分,此处默认取demo演示页面传递的参数 + // 订单超时时间。 + //'payTimeout' => date('YmdHis', strtotime('+15 minutes')), + + 'reqReserved' => $extra_param, + ); + $acpService = new \AcpService(); + $acpService::sign ( $params ); + $uri = \SDKConfig::$frontTransUrl; + $html_form = $acpService::createAutoFormHtml( $params, $uri ); + echo $html_form; + }else{ + + } + } + + /** + * 异步回调接口 + */ + public function notify(){ + + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){//验证成功 + $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + // 解释: 交易成功且结束,即不可再做任何操作。 + if($_POST['respMsg'] == 'Success!'){ + $m = new OM(); + $extras = explode("|",$_POST['reqReserved']); + $rs = array(); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $itemId = (int)$extras [3]; + $obj = array (); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $_POST["out_trade_no"];; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["total_fee"] = $_POST['total_fee']; + $obj["payFrom"] = 'unionpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //商户订单号 + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $tradeNo[0]; + $obj["total_fee"] = $_POST['total_fee']; + + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = 'unionpays'; + //支付成功业务逻辑 + $rs = $m->complatePay($obj); + } + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + } + }else{ + echo "fail"; //验证失败 + } + } + + /** + * 同步回调接口 + */ + public function response(){ + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){ //验证成功 + $order_sn = $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + $respMsg = $_POST['respMsg']; //交易状态 + + if($_POST['respMsg'] == 'success'){ + $m = new OM(); + $extras = explode("|",$_POST['extra_param']); + if($extras[0]=="recharge"){//充值 + if($extras[2]==1){ + $this->redirect(url("home/logmoneys/shopmoneys")); + }else{ + $this->redirect(url("home/logmoneys/usermoneys")); + } + }else{ + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["orderNo"] = $tradeNo[0]; + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $rs = $m->getOrderType($obj); + if((int)$rs["orderType"]==1){ + $this->redirect(url("home/orders/waitAppraise")); + }else{ + $this->redirect(url("home/orders/waitReceive")); + } + } + }else { + $this->error('支付失败'); + } + }else { + $this->error('支付失败'); + } + } + +} diff --git a/hyhproject/home2/controller/Useraddress.php b/hyhproject/home2/controller/Useraddress.php new file mode 100755 index 0000000..f317337 --- /dev/null +++ b/hyhproject/home2/controller/Useraddress.php @@ -0,0 +1,82 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\LogSms; +/** + * ============================================================================ + * 用户地址控制器 + */ + +class Useraddress extends Base{ + protected $beforeActionList = ['checkAuth']; + /** + * 设置为默认地址 + */ + public function setDefault(){ + return model('userAddress')->setDefault(); + } + public function index(){ + return $this->fetch('users/useraddress/list'); + } + /** + * 获取地址信息 + * 1.购物车结算有引用 + */ + public function listQuery(){ + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + if(!$userId){ + return WSTReturn('未登录', -1); + } + $list = model('Home/userAddress')->listQuery($userId); + return WSTReturn('', 1,$list); + } + + /** + * 跳去修改地址 + */ + public function edit(){ + $m = model('userAddress'); + $id=(int)input('id'); + $data = $m->getById($id); + $data = empty($data)?$m->getEModel('user_address'):$data; + //获取省级地区信息 + $area1 = model('Areas')->listQuery(0); + $this->assign(['data'=>$data, + 'area1'=>$area1]); + return $this->fetch('users/useraddress/edit'); + } + /** + * 新增 + */ + public function add(){ + $m = model('userAddress'); + $rs = $m->add(); + return $rs; + } + /** + * 修改 + */ + public function toEdit(){ + $m = model('userAddress'); + $rs = $m->edit(); + return $rs; + } + /** + * 删除 + */ + public function del(){ + $m = model('userAddress'); + $rs = $m->del(); + return $rs; + } + + /** + * 获取用户地址 + */ + public function getById(){ + $m = model('userAddress'); + $id=(int)input('id'); + $data = $m->getById($id); + return WSTReturn('', 1,$data); + } +} diff --git a/hyhproject/home2/controller/Users.php b/hyhproject/home2/controller/Users.php new file mode 100755 index 0000000..1331499 --- /dev/null +++ b/hyhproject/home2/controller/Users.php @@ -0,0 +1,974 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Users as MUsers; +use wstmart\common\model\LogSms; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'getverify,login,logout,regist,toregist,checklogin,getphoneverifycode,checkloginkey,checkemail,checkfindkey,protocol,forgetpass,forgetpasst,resetpass,forgetpasss,forgetpassf,findpass,getfindphone,checkfindphone,getfindemail,tologinbox'] + ]; + /** + * 去登录 + */ + public function login(){ + $USER = session('WST_USER'); + //如果已经登录了则直接跳去用户中心 + if(!empty($USER) && !empty($USER['userId'])){ + $this->redirect("users/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('user_login'); + } + + /** + * 用户退出 + */ + public function logout(){ + session('WST_USER',null); + setcookie("loginPwd", null); + session('WST_HO_CURRENTURL', null); + hook('afterUserLogout'); + return WSTReturn("退出成功",1); + + } + + /** + * 用户注册 + * + */ + public function regist(){ + $USER = session('WST_USER'); + //如果已经登录了则直接跳去用户中心 + if(!empty($USER) && $USER['userId']!=''){ + $this->redirect("users/index"); + } + $loginName = cookie("loginName"); + if(!empty($loginName)){ + $this->assign('loginName',cookie("loginName")); + }else{ + $this->assign('loginName',''); + } + return $this->fetch('regist'); + } + + + /** + * 新用户注册 + */ + public function toRegist(){ + $m = new MUsers(); + $rs = $m->regist(); + $rs['url'] = session('WST_HO_CURRENTURL'); + return $rs; + + } + + /** + * 验证登录 + * + */ + public function checkLogin(){ + $m = new MUsers(); + $rs = $m->checkLogin(); + $rs['url'] = session('WST_HO_CURRENTURL'); + return $rs; + } + + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $m = new MUsers(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + return $rv; + } + + + /** + * 判断手机或邮箱是否存在 + */ + public function checkLoginKey(){ + $m = new MUsers(); + if(input("post.loginName"))$val=input("post.loginName"); + if(input("post.userPhone"))$val=input("post.userPhone"); + if(input("post.userEmail"))$val=input("post.userEmail"); + $userId = (int)session('WST_USER.userId'); + $rs = WSTCheckLoginKey($val,$userId); + if($rs["status"]==1){ + return array("ok"=>""); + }else{ + return array("error"=>$rs["msg"]); + } + } + + /** + * 判断邮箱是否存在 + */ + public function checkEmail(){ + $data = $this->checkLoginKey(); + if(isset($data['error']))$data['error'] = '对不起,该邮箱已存在'; + return $data; + } + + /** + * 判断用户名是否存在/忘记密码 + */ + public function checkFindKey(){ + $m = new MUsers(); + $userId = (int)session('WST_USER.userId'); + $rs = WSTCheckLoginKey(input("post.loginName"),$userId); + if($rs["status"]==1){ + return array("error"=>"该用户不存在!"); + }else{ + return array("ok"=>""); + } + + } + + /** + * 跳到用户注册协议 + */ + public function protocol(){ + return $this->fetch("user_protocol"); + } + + /** + * 用户中心 + */ + public function index(){ + session('WST_MENID0',0); + session('WST_MENUID30',0); + // 待付款 待收货 待评价 + $info = model('home/Users')->getStatusNum(); + $this->assign($info); + $m = new MUsers(); + $data = $m->getById((int)session('WST_USER.userId')); + $this->assign('data',$data); + return $this->fetch('users/index'); + } + + + /** + * 跳去修改个人资料 + */ + public function edit(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/user_edit'); + } + /** + * 跳去修改密码页 + */ + public function editPass(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/security/user_pass'); + } + /** + * 修改密码 + */ + public function passedit(){ + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $rs = $m->editPass($userId); + return $rs; + } + /** + * 修改 + */ + public function toEdit(){ + $m = new MUsers(); + $rs = $m->edit(); + return $rs; + } + /** + * 安全设置页 + */ + public function security(){ + //获取用户信息 + $m = new MUsers(); + $data = $m->getById((int)session('WST_USER.userId')); + if($data['userPhone']!='')$data['userPhone'] = WSTStrReplace($data['userPhone'],'*',3); + if($data['userEmail']!='')$data['userEmail'] = WSTStrReplace($data['userEmail'],'*',2,'@'); + $this->assign('data',$data); + return $this->fetch('users/security/index'); + } + /** + * 修改邮箱页 + */ + public function editEmail(){ + hook('homeControllerUsersEditEmail'); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $data = $m->getById($userId); + if($data['userEmail']!='')$data['userEmail'] = WSTStrReplace($data['userEmail'],'*',2,'@'); + $this->assign('data',$data); + $process = 'One'; + $this->assign('process',$process); + if($data['userEmail']){ + return $this->fetch('users/security/user_edit_email'); + }else{ + return $this->fetch('users/security/user_email'); + } + } + /** + * 发送验证邮件/绑定邮箱 + */ + public function getEmailVerify(){ + $userEmail = input('post.userEmail'); + if(!$userEmail){ + return WSTReturn('请输入邮箱!',-1); + } + $code = input("post.verifyCode"); + $process = input("post.process"); + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $rs = WSTCheckLoginKey($userEmail,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("邮箱已存在!"); + exit(); + } + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('WST_USER.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail($userEmail,'绑定邮箱',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + // 绑定的邮箱 + session('email.val',$userEmail); + // 验证码 + session("email.key", $code); + // 发起绑定邮箱的时间; + session('email.time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + /** + * 绑定邮箱 + */ + public function emailEdit(){ + $USER = session('WST_USER'); + if(empty($USER) && $USER['userId']==''){ + $this->redirect("home/users/login"); + } + $bindTime = session('email.time'); + $code = session('email.key'); + $bindEmail = session('email.val'); + + if(time()>floatval($bindTime)+30*60)$this->error('验证码已失效!'); + $rs = WSTCheckLoginKey($bindEmail,(int)session('WST_USER.userId')); + + if($rs["status"]!=1){ + $this->error('邮箱已存在!'); + exit(); + } + $secretCode = input('secretCode'); + + if($code!=$secretCode)return WSTReturn('校验码错误',-1); + + $m = new MUsers(); + $rs = $m->editEmail((int)session('WST_USER.userId'),$bindEmail); + if($rs['status'] == 1){ + // 清空session + session('email',null); + return WSTReturn('验证通过',1); + } + $this->error('绑定邮箱失败'); + } + /** + * 完成邮箱绑定 + */ + public function doneEmailBind(){ + $this->assign('process','Three'); + return $this->fetch('users/security/user_email'); + } + /** + * 发送验证邮件/修改邮箱 + */ + public function getEmailVerifyt(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userEmail = $data['userEmail']; + if(!$userEmail){ + return WSTReturn('请输入邮箱!',-1); + } + $code = input("post.verifyCode"); + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('WST_USER.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail($userEmail,'绑定邮箱',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + // 修改的用户 + session('email.uId',(int)session('WST_USER.userId')); + // 绑定的邮箱 + session('email.val',$userEmail); + // 验证码 + session("email.key", $code); + // 发起绑定邮箱的时间; + session('email.time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + /** + * 修改邮箱 + */ + public function emailEditt(){ + $USER = session('WST_USER'); + if(empty($USER) && $USER['userId']!=''){ + $this->redirect("home/users/login"); + } + + $bindTime = session('email.time'); + $code = session('email.key'); + $bindEmail = session('email.val'); + $uId = (int)session('email.uId'); + + if(time()>floatval($bindTime)+30*60)$this->error('验证码已失效!'); + $rs = WSTCheckLoginKey($bindEmail,(int)session('WST_USER.userId')); + + if($rs["status"]!=1){ + $this->error('邮箱已存在!'); + exit(); + } + $secretCode = input('secretCode'); + + if($code!=$secretCode)return WSTReturn('校验码错误',-1); + + $m = new MUsers(); + $data = $m->getById($uId); + if($data['userId']==session('WST_USER.userId')){ + return WSTReturn('验证通过',1); + } + $this->error('无效的用户!'); + } + /** + * 修改邮箱第二步 + */ + public function editEmail2(){ + $this->assign('process','Two'); + return $this->fetch('users/security/user_edit_email'); + } + /** + * 修改邮箱第三步 + */ + public function editEmail3(){ + $this->assign('process','Three'); + return $this->fetch('users/security/user_edit_email'); + } + + + + /** + * 修改手机页 + */ + public function editPhone(){ + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $data = $m->getById($userId); + if($data['userPhone']!='')$data['userPhone'] = WSTStrReplace($data['userPhone'],'*',3); + $this->assign('data',$data); + $process = 'One'; + $this->assign('process',$process); + if($data['userPhone']){ + return $this->fetch('users/security/user_edit_phone'); + }else{ + return $this->fetch('users/security/user_phone'); + } + } + /** + * 跳到发送手机验证 + */ + public function toApply(){ + return $this->fetch("user_verify_phone"); + } + /** + * 绑定手机/获取验证码 + */ + public function getPhoneVerifyo(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyo',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function getPhoneVerifyb(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyb',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.Checkcode"); + $process = input("post.process"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("地址已失效,请重新验证身份!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new MUsers(); + $rs = $m->editPhone((int)session('WST_USER.userId'),session('Verify_info.userPhone')); + if($process=='Two'){ + $rs['process'] = $process; + }else{ + $rs['process'] = '0'; + } + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + public function editPhoneSu(){ + $pr = input("get.pr"); + $process = 'Three'; + $this->assign('process',$process); + if($pr == 'Two'){ + return $this->fetch('users/security/user_edit_phone'); + }else{ + return $this->fetch('users/security/user_phone'); + } + } + /** + * 修改手机/获取验证码 + */ + public function getPhoneVerifyt(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 修改手机 + */ + public function phoneEditt(){ + $phoneVerify = input("post.Checkcode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPhoneSut(){ + $process = 'Two'; + $this->assign('process',$process); + if(session('Verify_info2.phoneVerify')){ + return $this->fetch('users/security/user_edit_phone'); + } + $this->error('地址已失效,请重新验证身份'); + } + /** + * 处理图像裁剪 + */ + // public function editUserPhoto(){ + // $imageSrc = trim(input('post.photoSrc'),'/'); + // $image = \image\Image::open($imageSrc); + // $x = (int)input('post.x'); + // $y = (int)input('post.y'); + // $w = (int)input('post.w',150); + // $h = (int)input('post.h',150); + // $rs = $image->crop($w, $h, $x, $y, 150, 150)->save($imageSrc); + // if($rs){ + // return WSTReturn('',1,$imageSrc); + // exit; + // } + // return WSTReturn('发生未知错误.',-1); + + // } + + /** + * 处理图像裁剪 修改适应oss mark 201080612 by zl + */ + public function editUserPhoto(){ + $imageSrc = trim(input('post.photoSrc'),'/'); + //判断图片是否缩放了 + $res = strpos($imageSrc,'?x-oss-process='); + $x = (int)input('post.x'); + $y = (int)input('post.y'); + $w = (int)input('post.w',150); + $h = (int)input('post.h',150); + //判断是否缩放 如果缩放了就不加'?x-oss-process=' + if($res){ + $imageSrc=$imageSrc.',image/crop,x_'.$x.',y_'.$y.',w_'.$w.',h_'.$h.',image/resize,w_150,h_150'; + }else{ + $imageSrc=$imageSrc.'?x-oss-process=image/crop,x_'.$x.',y_'.$y.',w_'.$w.',h_'.$h.',image/resize,w_150,h_150'; + } + + return WSTReturn('',1,$imageSrc); + + } + /****************************************************** 忘记密码 **********************************************************/ + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new MUsers(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $process = 'One'; + $this->assign('data', $user); + $this->assign('process', $process); + return $this->fetch('users/security/user_edit_pay'); + } + /** + * 忘记支付密码:发送短信 + */ + public function getphoneverifypay(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 忘记支付密码:验证 + */ + public function payEditt(){ + $payVerify = input("post.Checkcode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($payVerify==session('Verify_backPaypwd_info.phoneVerify')){ + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPaySut(){ + $process = 'Two'; + $this->assign('process',$process); + if(session('Verify_backPaypwd_info.phoneVerify')){ + return $this->fetch('users/security/user_edit_pay'); + } + $this->error('地址已失效,请重新验证身份'); + } + /** + * 忘记支付密码:设置 + */ + public function payEdito(){ + $process = input("post.process"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("地址已失效,请重新验证身份!"); + exit(); + } + $m = new MUsers(); + $rs = $m->resetbackPay(); + if($process=='Two'){ + $rs['process'] = $process; + }else{ + $rs['process'] = '0'; + } + return $rs; + } + /** + * 忘记支付密码:完成 + */ + public function editPaySu(){ + $pr = input("get.pr"); + $process = 'Three'; + $this->assign('process',$process); + if($pr == 'Two'){ + return $this->fetch('users/security/user_edit_pay'); + }else{ + return $this->fetch('users/security/user_pay_pass'); + } + } + /** + * 忘记密码 + */ + public function forgetPass(){ + return $this->fetch('forget_pass'); + } + public function forgetPasst(){ + if(time()<floatval(session('findPass.findTime'))+30*60){ + $userId = session('findPass.userId'); + $m = new MUsers(); + $info = $m->getById($userId); + if($info['userPhone']!='')$info['userPhone'] = WSTStrReplace($info['userPhone'],'*',3); + if($info['userEmail']!='')$info['userEmail'] = WSTStrReplace($info['userEmail'],'*',2,'@'); + $this->assign('forgetInfo',$info); + return $this->fetch('forget_pass2'); + }else{ + $this->error('页面已过期!'); + } + } + // 重置密码 + public function resetPass(){ + if(!session('findPass')){ + $this->error('连接已失效!',url('home/users/index')); + } + if(time()>floatval(session('REST_Time'))+30*60)$this->error('连接已失效!'); + return $this->fetch('forget_pass3'); + } + // 验证校验码 + public function forgetPasss(){ + if(!session('findPass')){ + $this->error('连接已失效!'); + } + if(time()>floatval(session('REST_Time'))+30*60)$this->error('连接已失效!'); + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->error('请在同一浏览器操作!'); + } + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->expire('请在同一浏览器操作!'); + } + $uId = session('findPass.userId'); + $key = session("findPass.key"); + // 验证邮箱中的验证码 + $secretCode = input('secretCode'); + if($key==$secretCode){ + session('REST_userId',$uId); + session('REST_success','1'); + return WSTReturn('验证成功',1); + }else{ + return WSTReturn('校验码错误',-1); + } + + } + public function forgetPassf(){ + return $this->fetch('forget_pass4'); + } + /** + * 找回密码 + */ + public function findPass(){ + //禁止缓存 + header('Cache-Control:no-cache,must-revalidate'); + header('Pragma:no-cache'); + $code = input("post.verifyCode"); + $step = input("post.step/d"); + switch ($step) { + case 1:#第一步,验证身份 + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $loginName = input("post.loginName"); + $rs = WSTCheckLoginKey($loginName); + if($rs["status"]==1){ + return WSTReturn("用户名不存在!"); + exit(); + } + $m = new MUsers(); + $info = $m->checkAndGetLoginInfo($loginName); + if ($info != false) { + session('findPass',array('userId'=>$info['userId'],'loginName'=>$loginName,'userPhone'=>$info['userPhone'],'userEmail'=>$info['userEmail'],'loginSecret'=>$info['loginSecret'],'findTime'=>time())); + return WSTReturn("操作成功",1); + }else return WSTReturn("用户名不存在!"); + break; + case 2:#第二步,验证方式 + if (session('findPass.loginName') != null ){ + if(input("post.modes")==1){ + if ( session('findPass.userPhone') == null) { + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = input("post.Checkcode"); + if(!$phoneVerify){ + return WSTReturn('校验码不能为空!',-1); + } + return $this->checkfindPhone($phoneVerify); + }else{ + if (session('findPass.userEmail')==null) { + return WSTReturn('你没有预留邮箱,请通过手机号码找回密码!',-1); + } + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + return $this->getfindEmail(); + } + }else $this->error('页面已过期!'); + break; + case 3:#第三步,设置新密码 + $resetPass = session('REST_success'); + if($resetPass != 1)$this->error("页面已失效!"); + $loginPwd = input("post.loginPwd"); + $repassword = input("post.repassword"); + $decrypt_data = WSTRSA($loginPwd); + $decrypt_data2 = WSTRSA($repassword); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $loginPwd = $decrypt_data['data']; + $repassword = $decrypt_data2['data']; + }else{ + return WSTReturn('设置失败'); + } + if ($loginPwd == $repassword) { + $m = new MUsers(); + $rs = $m->resetPass(); + if($rs['status']==1){ + return $rs; + }else{ + return $rs; + } + }else return WSTReturn('两次密码不同!',-1); + break; + default: + $this->error('页面已过期!'); + break; + } + } + /** + * 手机验证码获取 + */ + public function getfindPhone(){ + session('WST_USER',session('findPass.userId')); + if(session('findPass.userPhone')==''){ + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = rand(100000,999999); + session('WST_USER',null); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,session('findPass.userPhone'),$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + // 记录发送短信的时间,用于验证是否过期 + session('REST_Time',time()); + $USER = []; + $USER['phoneVerify'] = $phoneVerify; + $USER['time'] = time(); + session('findPhone',$USER); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 手机验证码检测 + * -1 错误,1正确 + */ + public function checkfindPhone($phoneVerify){ + if(!session('findPhone.phoneVerify') || time()>floatval(session('findPhone.time'))+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if (session('findPhone.phoneVerify') == $phoneVerify ) { + $fuserId = session('findPass.userId'); + if(!empty($fuserId)){ + session('REST_userId',$fuserId); + session('REST_success','1'); + $rs['status'] = 1; + $rs['url'] = url('home/users/resetPass'); + return $rs; + } + return WSTReturn('无效用户',-1); + } + return WSTReturn('校验码错误!',-1); + } + /** + * 发送验证邮件/找回密码 + */ + public function getfindEmail(){ + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('findPass.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail(session('findPass.userEmail'),'密码重置',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + $uId = session('findPass.userId'); + session("findPass.key", $code); + // 发起重置密码的时间; + session('REST_Time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + + /** + * 加载登录小窗口 + */ + public function toLoginBox(){ + return $this->fetch('box_login'); + } + + /** + * 跳去修改支付密码页 + */ + public function editPayPass(){ + $m = new MUsers(); + //获取用户信息 + $userId = (int)session('WST_USER.userId'); + $data = $m->getById($userId); + $this->assign('data',$data); + return $this->fetch('users/security/user_pay_pass'); + } + /** + * 修改支付密码 + */ + public function payPassEdit(){ + $userId = (int)session('WST_USER.userId'); + $m = new MUsers(); + $rs = $m->editPayPass($userId); + return $rs; + } + + /** + * 获取用户金额 + */ + public function getUserMoney(){ + $m = new MUsers(); + $rs = $m->getFieldsById((int)session('WST_USER.userId'),'userMoney,lockMoney,rechargeMoney,payPwd'); + $rs['isSetPayPwd'] = ($rs['payPwd']=='')?0:1; + $rs['isDraw'] = ((float)WSTConf('CONF.drawCashUserLimit')<=$rs['userMoney'])?1:0; + unset($rs['payPwd']); + return WSTReturn('',1,$rs); + } +} + diff --git a/hyhproject/home2/controller/Userscores.php b/hyhproject/home2/controller/Userscores.php new file mode 100755 index 0000000..0a840ba --- /dev/null +++ b/hyhproject/home2/controller/Userscores.php @@ -0,0 +1,35 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\UserScores as MUserscores; +/** + * ============================================================================ + * 积分控制器 + */ +class Userscores extends Base{ + protected $beforeActionList = ['checkAuth']; + /** + * 查看商城消息 + */ + public function index(){ + $rs = model('Users')->getFieldsById((int)session('WST_USER.userId'),['userScore','userTotalScore']); + $this->assign('object',$rs); + return $this->fetch('users/userscores/list'); + } + /** + * 获取数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('UserScores')->pageQuery($userId); + return WSTReturn("", 1,$data); + } + /** + * 签到积分 + */ + public function signScore(){ + $m = new MUserscores(); + $userId = (int)session('WST_USER.userId'); + $rs = $m->signScore($userId); + return $rs; + } +} diff --git a/hyhproject/home2/controller/Wallets.php b/hyhproject/home2/controller/Wallets.php new file mode 100755 index 0000000..6643fac --- /dev/null +++ b/hyhproject/home2/controller/Wallets.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\home\controller; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\Users as UM; +/** + * ============================================================================ + * 余额控制器 + */ +class Wallets extends Base{ + /** + * 生成支付代码 + */ + function getWalletsUrl(){ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch'); + $base64 = new \org\Base64(); + $key = WSTBase64url($base64->encrypt($orderNo."_".$isBatch, "WSTMart"),true); + $data = []; + $data['status'] = 1; + $data['url'] = url('home/wallets/payment','key='.$key,'html',true); + return $data; + } + + /** + * 跳去支付页面 + */ + public function payment(){ + if((int)session('WST_USER.userId')==0){ + $this->assign('message',"对不起,您尚未登录,请先登录!"); + return $this->fetch('error_msg'); + } + $userId = (int)session('WST_USER.userId'); + $m = new UM(); + $user = $m->getFieldsById($userId,["payPwd"]); + $this->assign('hasPayPwd',($user['payPwd']!="")?1:0); + $key = input('key'); + $this->assign('paykey',$key); + $key = WSTBase64url($key,false); + $base64 = new \org\Base64(); + $key = $base64->decrypt($key,"WSTMart"); + $key = explode('_',$key); + $data = []; + $data['orderNo'] = $key[0]; + $data['isBatch'] = (int)$key[1]; + $data['userId'] = $userId; + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + if(empty($rs)){ + $this->assign('message',"您的订单已支付,请勿重复支付~"); + return $this->fetch('error_msg'); + }else{ + $this->assign('needPay',$rs['needPay']); + //获取用户钱包 + $user = model('users')->getFieldsById($data['userId'],'userMoney'); + $this->assign('userMoney',$user['userMoney']); + return $this->fetch('order_pay_wallets'); + } + } + + /** + * 钱包支付 + */ + public function payByWallet(){ + $m = new OM(); + return $m->payByWallet(); + } + +} diff --git a/hyhproject/home2/controller/Weixinpays.php b/hyhproject/home2/controller/Weixinpays.php new file mode 100755 index 0000000..d49602d --- /dev/null +++ b/hyhproject/home2/controller/Weixinpays.php @@ -0,0 +1,277 @@ +<?php +namespace wstmart\home\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +use wstmart\common\model\LogPays as PM; +use wstmart\common\model\ChargeItems as CM; +/** + * ============================================================================ + * 微信支付控制器 + */ +class Weixinpays extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('wxpay.WxPayConf'); + Loader::import('wxpay.WxQrcodePay'); + + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + $this->wxpayConfig['notifyurl'] = url("home/weixinpays/wxNotify","",true,true); + $this->wxpayConfig['curl_timeout'] = 30; + $this->wxpayConfig['returnurl'] = ""; + // 初始化WxPayConf_pub + $wxpaypubconfig = new \WxPayConf($this->wxpayConfig); + } + + /** + * 获取微信URL + */ + public function getWeixinPaysURL(){ + $m = new OM(); + $payObj = input("payObj/s"); + $pkey = ""; + $data = array(); + if($payObj=="recharge"){ + $cm = new CM(); + $itmeId = (int)input("itmeId/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $needPay = 0; + if($itmeId>0){ + $item = $cm->getItemMoney($itmeId); + $needPay = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $needPay = (int)input("needPay/d"); + } + + $data["status"] = $needPay>0?1:-1; + $pkey = $payObj."@".$targetId."@".$targetType."@".$needPay."@".$itmeId; + }else{ + $userId = (int)session('WST_USER.userId'); + $data = $m->checkOrderPay(); + if($data["status"]==1){ + $orderNo = input("orderNo/s"); + $isBatch = (int)input("isBatch/d"); + $pkey = $payObj."@".$userId."@".$orderNo; + if($isBatch==1){ + $pkey = $pkey."@1"; + }else{ + $pkey = $pkey."@2"; + } + } + } + $data["url"] = url('home/weixinpays/createQrcode',array("pkey"=>base64_encode($pkey))); + return $data; + } + + public function createQrcode() { + $pkey = base64_decode(input("pkey")); + $pkeys = explode("@", $pkey ); + $flag = true; + + $needPay = 0; + $out_trade_no = 0; + $trade_no = 0; + if($pkeys[0]=="recharge"){ + $needPay = (int)$pkeys[3]; + $out_trade_no = WSTOrderNo(); + $body = "钱包充值"; + $trade_no = $out_trade_no; + }else{ + if(count($pkeys)!= 4){ + $this->assign('out_trade_no', ""); + }else{ + $userId = (int)session('WST_USER.userId'); + $obj = array(); + $obj["userId"] = $userId; + $obj["orderNo"] = $pkeys[2]; + $obj["isBatch"] = $pkeys[3]; + $m = new OM(); + $order = $m->getPayOrders($obj); + $needPay = $order["needPay"]; + $payRand = $order["payRand"]; + $body = "支付订单费用"; + $out_trade_no = $obj["orderNo"]."a".$payRand; + $trade_no = $obj["orderNo"]; + } + } + + if($needPay>0){ + // 使用统一支付接口 + $wxQrcodePay = new \WxQrcodePay (); + $wxQrcodePay->setParameter ( "body", $body ); // 商品描述 + + $wxQrcodePay->setParameter ( "out_trade_no", $out_trade_no ); // 商户订单号 + $wxQrcodePay->setParameter ( "total_fee", $needPay * 100 ); // 总金额 + $wxQrcodePay->setParameter ( "notify_url", $this->wxpayConfig['notifyurl'] ); // 通知地址 + $wxQrcodePay->setParameter ( "trade_type", "NATIVE" ); // 交易类型 + $wxQrcodePay->setParameter ( "attach", "$pkey" ); // 附加数据 + $wxQrcodePay->SetParameter ( "input_charset", "UTF-8" ); + // 获取统一支付接口结果 + $wxQrcodePayResult = $wxQrcodePay->getResult (); + $code_url = ''; + // 商户根据实际情况设置相应的处理流程 + if ($wxQrcodePayResult ["return_code"] == "FAIL") { + // 商户自行增加处理流程 + echo "通信出错:" . $wxQrcodePayResult ['return_msg'] . "<br>"; + } elseif ($wxQrcodePayResult ["result_code"] == "FAIL") { + // 商户自行增加处理流程 + echo "错误代码:" . $wxQrcodePayResult ['err_code'] . "<br>"; + echo "错误代码描述:" . $wxQrcodePayResult ['err_code_des'] . "<br>"; + } elseif ($wxQrcodePayResult ["code_url"] != NULL) { + // 从统一支付接口获取到code_url + $code_url = $wxQrcodePayResult ["code_url"]; + // 商户自行增加处理流程 + } + $this->assign ( 'out_trade_no', $trade_no ); + $this->assign ( 'code_url', $code_url ); + $this->assign ( 'wxQrcodePayResult', $wxQrcodePayResult ); + $this->assign ( 'needPay', $needPay ); + }else{ + $flag = false; + } + + if($pkeys[0]=="recharge"){ + if($pkeys[2]==1){ + return $this->fetch('shops/recharge/pay_step2'); + }else{ + return $this->fetch('users/recharge/pay_step2'); + } + }else{ + if($flag){ + return $this->fetch('order_pay_step2'); + }else{ + return $this->fetch('order_pay_step3'); + } + } + + } + + + /** + * 检查支付结果 + */ + public function getPayStatus() { + $trade_no = input('trade_no'); + $obj = array(); + $obj["userId"] = (int)session('WST_USER.userId'); + $obj["transId"] = $trade_no; + $m = new PM(); + $log = $m->getPayLog($obj); + $data = array("status"=>-1); + // 检查是否存在,存在说明支付成功 + if(isset($log["logId"]) && $log["logId"]>0){ + $m->delPayLog($obj); + $data["status"] = 1; + }else{ + $data["status"] = -1; + } + return $data; + } + + /** + * 微信异步通知 + */ + public function wxNotify() { + // 使用通用通知接口 + $wxQrcodePay = new \WxQrcodePay (); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $wxQrcodePay->saveData ( $xml ); + // 验证签名,并回应微信。 + if ($wxQrcodePay->checkSign () == FALSE) { + $wxQrcodePay->setReturnParameter ( "return_code", "FAIL" ); // 返回状态码 + $wxQrcodePay->setReturnParameter ( "return_msg", "签名失败" ); // 返回信息 + } else { + $wxQrcodePay->setReturnParameter ( "return_code", "SUCCESS" ); //设置返回码 + } + + $returnXml = $wxQrcodePay->returnXml (); + if ($wxQrcodePay->checkSign () == TRUE) { + if ($wxQrcodePay->data ["return_code"] == "FAIL") { + echo "FAIL"; + } elseif ($wxQrcodePay->data ["result_code"] == "FAIL") { + echo "FAIL"; + } else { + // 此处应该更新一下订单状态,商户自行增删操作 + $order = $wxQrcodePay->getData (); + $trade_no = $order["transaction_id"]; + $total_fee = $order ["total_fee"]; + $pkey = $order ["attach"] ; + $pkeys = explode ( "@", $pkey ); + $out_trade_no = 0; + $userId = 0; + if($pkeys[0]=="recharge"){//充值 + $out_trade_no = $order["out_trade_no"]; + $targetId = (int)$pkeys [1]; + $userId = $targetId; + $targetType = (int)$pkeys [2]; + $itemId = (int)$pkeys [4]; + $obj = array (); + $obj["trade_no"] = $trade_no; + $obj["out_trade_no"] = $out_trade_no; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["total_fee"] = (float)$total_fee/100; + $obj["payFrom"] = 'weixinpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + + }else{//订单支付 + $userId = (int)$pkeys [1]; + $out_trade_no = $pkeys[2]; + $isBatch = (int)$pkeys[3]; + // 商户订单 + $obj = array (); + $obj["trade_no"] = $trade_no; + $obj["out_trade_no"] = $out_trade_no; + $obj["isBatch"] = $isBatch; + $obj["total_fee"] = (float)$total_fee/100; + $obj["userId"] = $userId; + $obj["payFrom"] = 'weixinpays'; + // 支付成功业务逻辑 + $m = new OM(); + $rs = $m->complatePay ( $obj ); + } + if($rs["status"]==1){ + $data = array(); + $data["userId"] = $userId; + $data["transId"] = $out_trade_no; + $m = new PM(); + $m->addPayLog($data); + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + }else{ + echo "FAIL"; + } + } + + /** + * 检查支付结果 + */ + public function paySuccess() { + return $this->fetch('order_pay_step3'); + } + +} diff --git a/hyhproject/home2/model/Articles.php b/hyhproject/home2/model/Articles.php new file mode 100755 index 0000000..fe0a79b --- /dev/null +++ b/hyhproject/home2/model/Articles.php @@ -0,0 +1,229 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 文章类 + */ +use think\Db; +class Articles extends Base{ + /** + * 获取帮助左侧列表 + */ + public function helpList(){ + $arts = cache('arts'); + if(!$arts){ + $rs = $this->alias('a')->join('article_cats ac','a.catId=ac.catId','inner') + ->field('a.articleId,a.catId,a.articleTitle,ac.catName') + ->where(['a.dataFlag'=>1, + 'a.isshow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>7]) + ->cache(true) + ->select(); + //同一分类下的文章放一起 + $catName = []; + $arts = []; + foreach($rs as $k=>$v){ + if(in_array($v['catName'],$catName)){ + $arts[$v['catName'].'-'.$v['catId']][] = $v; + }else{ + $catName[] = $v['catName']; + $arts[$v['catName'].'-'.$v['catId']][] = $v; + } + } + cache('arts',$arts,86400); + } + return $arts; + } + /** + * 根据id获取帮助文章 + */ + public function getHelpById(){ + $id = (int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + return $this->alias('a')->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner')->where('ac.parentId=7 and a.dataFlag=1 and a.isShow=1')->cache(true)->find($id); + } + /** + * 根据id获取资讯文章 + */ + public function getNewsById($id = 0){ + $id = $id>0?$id:(int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + return $this->alias('a') + ->field('a.*,ac.catName') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where('a.catId<>7 and ac.parentId<>7 and a.dataFlag=1 and a.isShow=1') + ->cache(true) + ->find($id); + } + + /** + * 获取资讯列表【左侧分类】 + */ + public function NewsList(){ + $list = $this->getTree(); + foreach($list as $k=>$v){ + if(!empty($v['children'])){ + foreach($v['children'] as $k1=>$v1){ + // 二级分类下的文章总条数 + $list[$k]['children'][$k1]['newsCount'] = $this->where(['catId'=>$v1['catId'], + 'dataFlag'=>1,'isShow'=>1])->cache(true)->count(); + } + } + } + return $list; + } + + public function getTree(){ + $artTree = cache('artTree'); + if(!$artTree){ + $data = Db::name('article_cats')->field('catName,catId,parentId')->where('parentId <> 7 and catId <> 7 and dataFlag=1 and isShow=1')->cache(true)->select(); + $artTree = $this->_getTree($data, 0); + cache('artTree',$artTree,86400); + } + return $artTree; + } + public function _getTree($data,$parentId){ + $tree = []; + foreach($data as $k=>$v){ + if($v['parentId']==$parentId){ + // 再找其下级分类 + $v['children'] = $this->_getTree($data,$v['catId']); + $tree[] = $v; + } + } + return $tree; + } + /** + * 根据分类id获取文章列表 + */ + public function nList(){ + $catId = (int)input('catId'); + $rs = $this->alias('a') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->field('a.*') + ->where(['a.catId'=>$catId, + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->cache(true) + ->paginate(); + return $rs; + } + /** + * 面包屑导航 + */ + public function bcNav(){ + $catId = (int)input('catId'); //分类id + $artId = (int)input('id'); //文章id + $data = Db::name('article_cats')->field('catId,parentId,catName')->cache(true)->select(); + if($artId){ + $catId = $this->where('articleId',$artId)->value('catId'); + } + $bcNav = $this->getParents($data,$catId,$isClear=true); + return $bcNav; + + } + /** + * 获取父级分类 + */ + public function getParents($data, $catId,$isClear=false){ + static $bcNav = []; + if($isClear) + $bcNav = []; + foreach($data as $k=>$v){ + if($catId == $v['catId']){ + if($catId!=0){ + $this->getParents($data, $v['parentId']); + $bcNav[] = $v; + } + } + } + return $bcNav; + } + + /** + * 记录解决情况 + */ + public function recordSolve(){ + $articleId = (int)input('id'); + $status = (int)input('status'); + if($status==1){ + $rs = $this->where('articleId',$articleId)->setInc('solve'); + }else{ + $rs = $this->where('articleId',$articleId)->setInc('unsolve'); + } + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + + /** + * 获取资讯中心的子集分类id + */ + public function getChildIds(){ + $ids = []; + $data = Db::name('article_cats')->cache(true)->select(); + foreach($data as $k=>$v){ + if($v['parentId']!=7 && $v['catId']!=7 && $v['parentId']!=0 ){ + $ids[] = $v['catId']; + } + } + return $ids; + } + + /** + * 获取咨询中中心所有文章 + */ + public function getArticles(){ + // 获取咨询中心下的所有分类id + $ids = $this->getChildIds(); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>['in',$ids], + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->distinct(true) + ->cache(true) + ->paginate(15); + return $rs; + } + + /** + * 获取指定分类下的文章 + */ + public function getArticlesByCat($catId){ + $ids = $this->getChildIds(); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>['in',$ids], + 'a.dataFlag'=>1, + 'a.isShow'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.parentId'=>['<>',7], + ]) + ->distinct(true) + ->cache(true) + ->select(); + $data = []; + if(!empty($rs)){ + foreach($rs as $key =>$v){ + $data[$v['articleId']] = $v; + } + } + return $data; + } +} diff --git a/hyhproject/home2/model/Attributes.php b/hyhproject/home2/model/Attributes.php new file mode 100755 index 0000000..1a81880 --- /dev/null +++ b/hyhproject/home2/model/Attributes.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\GoodsCats as M; +/** + * ============================================================================ + * 商品属性分类 + */ +class Attributes extends Base{ + /** + * 获取可供筛选的商品属性 + */ + public function listQueryByFilter($catId){ + $m = new M(); + $ids = $m->getParentIs($catId); + if(!empty($ids)){ + $catIds = []; + foreach ($ids as $key =>$v){ + $catIds[] = $v; + } + /*$attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->where(['a.goodsCatId'=>['in',$catIds],'a.isShow'=>1,'a.dataFlag'=>1,'a.attrType'=>['<>',0]]) + ->field('a.attrId,a.attrName,a.attrVal')->order('a.attrSort asc')->select();*/ + + // 取出分类下有设置的属性。 + $attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->field('ga.attrId,GROUP_CONCAT(distinct ga.attrVal) attrVal,a.attrName') + ->where(['a.goodsCatId'=>['in',$catIds],'a.isShow'=>1,'a.dataFlag'=>1,'a.attrType'=>['<>',0]]) + ->group('ga.attrId') + ->order('a.attrSort asc') + ->select(); + foreach ($attrs as $key =>$v){ + $attrs[$key]['attrVal'] = explode(',',$v['attrVal']); + } + return $attrs; + } + return []; + } + /** + * 根据商品id获取可供选择的属性 + */ + public function getAttribute($goodsId){ + if(empty($goodsId))return []; + $attrs = $this->alias('a') + ->join('__GOODS_ATTRIBUTES__ ga','ga.attrId=a.attrId','inner') + ->field('ga.attrId,GROUP_CONCAT(distinct ga.attrVal) attrVal,a.attrName') + ->where(['ga.goodsId'=>['in',$goodsId], + 'a.isShow'=>1, + 'a.dataFlag'=>1, + 'a.attrType'=>['<>',0]]) + ->group('ga.attrId') + ->order('a.attrSort asc') + ->select(); + if(empty($attrs))return []; + foreach ($attrs as $key =>$v){ + $attrs[$key]['attrVal'] = explode(',',$v['attrVal']); + } + return $attrs; + } +} diff --git a/hyhproject/home2/model/Base.php b/hyhproject/home2/model/Base.php new file mode 100755 index 0000000..7caca95 --- /dev/null +++ b/hyhproject/home2/model/Base.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Base as CBase; +/** + * ============================================================================ + * 基础模型器 + */ + +class Base extends CBase {} \ No newline at end of file diff --git a/hyhproject/home2/model/Goods.php b/hyhproject/home2/model/Goods.php new file mode 100755 index 0000000..f0fce8e --- /dev/null +++ b/hyhproject/home2/model/Goods.php @@ -0,0 +1,1315 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Goods as CGoods; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends CGoods{ + /** + * 上架商品列表 + */ + public function saleByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where = []; + $where['shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName|m.goodsId'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $shopId = (int)session('WST_USER.shopId'); + $where['m.shopId'] = $shopId; + $rs = $this->alias('m')->join('store_recom sr','sr.goodsId=m.goodsId','left') + ->where($where) + ->field('m.goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,sr.storeStatus,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 审核中的商品 + */ + public function auditByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = 0; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + + $rs = $this->alias('m') + ->where($where) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 仓库中的商品 + */ + public function storeByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId']=$shopId; + $where['dataFlag'] = 1; + $where['isSale'] = 0; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $rs = $this->alias('m') + ->where($where) + ->where('goodsStatus','<>',-1) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 违规的商品 + */ + public function illegalByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['shopId'] = $shopId; + $where['goodsStatus'] = -1; + $where['dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + + $rs = $this->alias('m') + ->where($where) + ->field('goodsId,goodsName,goodsImg,goodsType,goodsSn,isSale,isBest,isHot,isNew,isRecom,illegalRemarks,goodsStock,saleNum,shopPrice,isSpec') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 违规的商品 + */ + public function limitPriceByPage(){ + $shopId = (int)session('WST_USER.shopId'); + $where['lp.shopId'] = $shopId; + $where['goodsStatus'] = 1; + $where['lp.dataFlag'] = 1; + $where['m.dataFlag'] = 1; + $where['isSale'] = 1; + $goodsType = input('goodsType'); + if($goodsType!='')$where['goodsType'] = (int)$goodsType; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $goodsName = input('goodsName'); + if($goodsName != ''){ + $where['goodsName'] = ['like',"%$goodsName%"]; + } + if($c2Id!=0 && $c1Id!=0){ + $where['shopCatId2'] = $c2Id; + }else if($c1Id!=0){ + $where['shopCatId1'] = $c1Id; + } + $rs = $this->alias('m') + ->join('limit_price lp','lp.goodsId=m.goodsId','left') + ->join('goods_specs gs','gs.id=lp.goodsSpecsId','left') + ->where($where) + ->field('m.goodsId,goodsName,goodsImg,goodsType,goodsStock,specPrice,m.saleNum,limitPrice,lp.productNo,lp.id,shopPrice,from_unixtime(startTime)startTime,from_unixtime(endTime)endTime') + ->order('saleTime', 'desc') + ->paginate(input('pagesize/d'))->toArray(); + foreach ($rs['Rows'] as $key => $v){ + $rs['Rows'][$key]['verfiycode'] = WSTShopEncrypt($shopId); + } + return $rs; + } + /** + * 获取指定对象 + */ + public function getLimitGoods(){ + $id=(int)input('id'); + $obj = null; + if($id>0){ + $obj = Db::name('limit_price')->where(['id'=>$id])->find(); + $obj['startTime']=date('Y-m-d H:i:s',$obj['startTime']); + $obj['endTime']=date('Y-m-d H:i:s',$obj['endTime']); + }else{ + $obj = self::getEModel("limit_price"); + } + return $obj; + } + //获取商品规格 + public function getGoodsSpecs(){ + $productNo = input('productNo'); + $res = db('goods_specs')->where(['productNo'=>$productNo])->field('specIds,marketPrice')->find(); + $specs = explode(':',$res['specIds']); + $data = db('spec_items')->where(['itemId'=>['in',$specs]])->select(); + $rs['itemName'] = implode(',',array_column($data,'itemName')); + $rs['marketPrice'] = $res['marketPrice']; + // echo $rs;die; + //dump($rs);die; + + exit(json_encode($rs)); + + } +// 新增限时价格商品 + public function addLimitGoods(){ + $data=[]; + $data['goodsId']=(int)input('goodsId'); + $data['productNo']=input('productNo'); + $data['limitPrice']=input('limitPrice'); + $data['startTime']=strtotime(input('startTime')); + $data['endTime']=strtotime(input('endTime')); + $data['shopId']=(int)session('WST_USER.shopId'); + //判断商品是否是自己店铺的 + $goods=db('goods')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId']])->find(); + if(!$goods) return WSTReturn('无效商品,请重新选择'); + if($data['limitPrice']<=0) return WSTReturn('商品价格必须大于0'); + $find=db('limit_price')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId'],'productNo'=>$data['productNo'],'dataFlag'=>1])->find(); + if($find) return WSTReturn('此数据已存在',-1); + //dump($data['limitPrice']); + if($data['productNo']){ + $data['specIds']=db('goods_specs')->where(['goodsId'=>$data['goodsId'],'productNo'=>$data['productNo']])->value('specIds'); + $data['goodsSpecsId']=db('goods_specs')->where(['goodsId'=>$data['goodsId'],'productNo'=>$data['productNo']])->value('id'); + } + $result=db('limit_price')->insert($data); + if($result){ + return WSTReturn("新增成功", 1); + }else{ + return WSTReturn("新增失败", -1); + } + } + // 编辑限时价格商品 + public function editLimitGoods(){ + $data=[]; + $data['goodsId']=(int)input('goodsId'); + $data['productNo']=input('productNo'); + $data['limitPrice']=input('limitPrice'); + $data['startTime']=strtotime(input('startTime')); + $data['endTime']=strtotime(input('endTime')); + $data['shopId']=(int)session('WST_USER.shopId'); + $data['id']=(int)input('id'); + //判断商品是否是自己店铺的 + $goods=db('goods')->where(['goodsId'=>$data['goodsId'],'shopId'=>$data['shopId']])->find(); + if(!$goods) return WSTReturn('无效商品,请重新选择'); + $data['shopId']=(int)session('WST_USER.shopId'); + if($data['productNo']){ + $data['specIds']=db('goods_specs')->where(['id'=>$data['id'],'productNo'=>$data['productNo']])->value('specIds'); + } + $result=db('limit_price')->where('id',$data['id'])->setField($data); + if($result){ + return WSTReturn("更新成功", 1); + }else{ + return WSTReturn("更新失败", -1); + } + } + //删除限时价格商品 + public function delLimitGoods(){ + $id = (int)input('id/d'); + Db::startTrans(); + try{ + $result = db('limit_price')->where(['id'=>$id])->update(['dataFlag'=>-1]); + if($result){ + Db::commit(); + //标记删除限时价格商品 + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + /** + * 新增商品 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $data = input('post.'); + $specsIds = input('post.specsIds'); + $basicsMoney = isset($data['basicsMoney']) ? $data['basicsMoney'] : 0; + if(!is_numeric($basicsMoney)){ + return WSTReturn("商品成本价请填写数字"); + } + $aloneShop = Db::name('alone_shops')->where(['shopId'=>$shopId,'dataFlag'=>1])->find(); + if($aloneShop && !$basicsMoney){ + return WSTReturn("请填写成本价"); + } + WSTUnset($data,'goodsId,statusRemarks,goodsStatus,dataFlag,basicsMoney'); + if(isset($data['goodsName'])){ + if(!WSTCheckFilterWords($data['goodsName'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品名称包含非法字符"); + } + } + if(isset($data['goodsTips'])){ + if(!WSTCheckFilterWords($data['goodsTips'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品促销信息包含非法字符"); + } + } + if(isset($data['goodsDesc'])){ + if(!WSTCheckFilterWords($data['goodsDesc'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品描述包含非法字符"); + } + } + if(WSTConf("CONF.isGoodsVerify")==1){ + $data['goodsStatus'] = 0; + }else{ + $data['goodsStatus'] = 1; + } + $data['shopId'] = $shopId; + $data['saleTime'] = date('Y-m-d H:i:s'); + $data['createTime'] = date('Y-m-d H:i:s'); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + $data['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + if($data['goodsType']==0){ + $data['isSpec'] = ($specsIds!='')?1:0; + }else{ + $data['isSpec'] = 0; + } + Db::startTrans(); + try{ + //保存插件数据钩子 + hook('beforeEidtGoods',['data'=>&$data]); + + $shop = model('shops')->get($shopId); + if($shop['dataFlag'] ==-1 || $shop['shopStatus'] != 1)$data['isSale'] = 0; + $result = $this->validate(true)->allowField(true)->save($data); + if(false !== $result){ + $goodsId = $this->goodsId; + //ect支付方式 + // $ectPay=(int)input('ectPay'); + // $ect['goodsId']=$goodsId; + // $ect['ectPay']=$ectPay; + // Db::name('goods_pay')->insert($ect); + //商品图片 + WSTUseImages(0, $goodsId, $data['goodsImg']); + //商品相册 + WSTUseImages(0, $goodsId, $data['gallery']); + //商品描述图片 + WSTEditorImageRocord(0, $goodsId, '',$data['goodsDesc']); + //建立商品评分记录 + $gs = []; + $gs['goodsId'] = $goodsId; + $gs['shopId'] = $shopId; + Db::name('goods_scores')->insert($gs); + //如果是实物商品并且有销售规格则保存销售和规格值 + if($data['goodsType']==0 && $specsIds!=''){ + $specsIds = explode(',',$specsIds); + $specsArray = []; + foreach ($specsIds as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsArray))$specsArray[] = $vv; + } + } + //保存规格名称 + $specMap = []; + foreach ($specsArray as $v){ + $vv = explode('_',$v); + $sitem = []; + $sitem['shopId'] = $shopId; + $sitem['catId'] = (int)$vv[0]; + $sitem['goodsId'] = $goodsId; + $sitem['itemName'] = input('post.specName_'.$vv[0]."_".$vv[1]); + $sitem['itemImg'] = input('post.specImg_'.$vv[0]."_".$vv[1]); + $sitem['dataFlag'] = 1; + $sitem['createTime'] = date('Y-m-d H:i:s'); + $itemId = Db::name('spec_items')->insertGetId($sitem); + if($sitem['itemImg']!='')WSTUseImages(0, $itemId, $sitem['itemImg']); + $specMap[$v] = $itemId; + } + //保存销售规格 + $defaultPrice = 0;//最低价 + $totalStock = 0;//总库存 + $gspecArray = []; + $isFindDefaultSpec = false; + $defaultSpec = Input('post.defaultSpec'); + foreach ($specsIds as $v){ + $vs = explode('-',$v); + $goodsSpecIds = []; + foreach ($vs as $gvs){ + $goodsSpecIds[] = $specMap[$gvs]; + } + $gspec = []; + $gspec['specIds'] = implode(':',$goodsSpecIds); + $gspec['shopId'] = $shopId; + $gspec['goodsId'] = $goodsId; + $gspec['productNo'] = Input('productNo_'.$v); + $gspec['marketPrice'] = (float)Input('marketPrice_'.$v); + $gspec['specPrice'] = (float)Input('specPrice_'.$v); + $gspec['specStock'] = (int)Input('specStock_'.$v); + $gspec['warnStock'] = (int)Input('warnStock_'.$v); + //设置默认规格 + if($defaultSpec==$v){ + $isFindDefaultSpec = true; + $defaultPrice = $gspec['specPrice']; + $gspec['isDefault'] = 1; + }else{ + $gspec['isDefault'] = 0; + } + $gspecArray[] = $gspec; + //获取总库存 + $totalStock = $totalStock + $gspec['specStock']; + } + if(!$isFindDefaultSpec)return WSTReturn("请选择推荐规格"); + if(count($gspecArray)>0){ + Db::name('goods_specs')->insertAll($gspecArray); + //更新默认价格和总库存 + $this->where('goodsId',$goodsId)->update(['isSpec'=>1,'shopPrice'=>$defaultPrice,'goodsStock'=>$totalStock]); + } + } + //保存商品属性 + $attrsArray = []; + $attrRs = Db::name('attributes')->where(['goodsCatId'=>['in',$goodsCats],'isShow'=>1,'dataFlag'=>1]) + ->field('attrId')->select(); + foreach ($attrRs as $key =>$v){ + $attrs = []; + $attrs['attrVal'] = input('attr_'.$v['attrId']); + if($attrs['attrVal']=='')continue; + $attrs['shopId'] = $shopId; + $attrs['goodsId'] = $goodsId; + $attrs['attrId'] = $v['attrId']; + $attrs['createTime'] = date('Y-m-d H:i:s'); + $attrsArray[] = $attrs; + } + if(count($attrsArray)>0)Db::name('goods_attributes')->insertAll($attrsArray); + + + if($aloneShop){ + //保存商品成本价 + $basicsArray = []; + $now = time(); + $basicsArray['shopId'] = $shopId; + $basicsArray['goodsId'] = $goodsId; + $basicsArray['basicsMoney'] = $basicsMoney; + $basicsArray['createTime'] = $now; + Db::name('alone_goods')->insert($basicsArray); + } + hook('afterGoodsEct',['data'=>&$data,'goodsId'=>$goodsId]); + Db::commit(); + return WSTReturn("新增成功", 1,['id'=>$goodsId]); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败',-1); + } + } + + /** + * 编辑商品资料 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $goodsId = input('post.goodsId/d'); + $specsIds = input('post.specsIds'); + $data = input('post.'); + $basicsMoney = isset($data['basicsMoney']) ? $data['basicsMoney'] : 0; + if(!is_numeric($basicsMoney)){ + return WSTReturn("商品成本价请填写数字"); + } + $aloneShop = Db::name('alone_shops')->where(['shopId'=>$shopId,'dataFlag'=>1])->find(); + if($aloneShop && !$basicsMoney){ + return WSTReturn("请填写成本价"); + } + WSTUnset($data,'goodsId,dataFlag,statusRemarks,goodsStatus,createTime,basicsMoney'); + $ogoods = $this->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'dataFlag'=>1])->field('goodsStatus,goodsType')->find(); + if(empty($ogoods))return WSTReturn('商品不存在'); + if(isset($data['goodsName'])){ + if(!WSTCheckFilterWords($data['goodsName'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品名称包含非法字符"); + } + } + if(isset($data['goodsTips'])){ + if(!WSTCheckFilterWords($data['goodsTips'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品促销信息包含非法字符"); + } + } + if(isset($data['goodsDesc'])){ + if(!WSTCheckFilterWords($data['goodsDesc'],WSTConf("CONF.limitWords"))){ + return WSTReturn("商品描述包含非法字符"); + } + } + //违规商品不能直接上架 + if($ogoods['goodsStatus']!=1){ + $data['goodsStatus'] = 0; + } + //不允许修改商品类型 + $data['goodsType'] = $ogoods['goodsType']; + $data['saleTime'] = date('Y-m-d H:i:s'); + $goodsCats = model('GoodsCats')->getParentIs($data['goodsCatId']); + $data['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + if($data['goodsType']==0){ + $data['isSpec'] = ($specsIds!='')?1:0; + }else{ + $data['isSpec'] = 0; + } + Db::startTrans(); + try{ + //保存插件数据钩子 + hook('beforeEidtGoods',['data'=>&$data]); + + //商品图片 + WSTUseImages(0, $goodsId, $data['goodsImg'],'goods','goodsImg'); + //商品相册 + WSTUseImages(0, $goodsId, $data['gallery'],'goods','gallery'); + // 商品描述图片 + $desc = $this->where('goodsId',$goodsId)->value('goodsDesc'); + WSTEditorImageRocord(0, $goodsId, $desc, $data['goodsDesc']); + $shop = model('shops')->get($shopId); + if($shop['dataFlag'] ==-1 || $shop['shopStatus'] != 1)$data['isSale'] = 0; + //虚拟商品处理 + if($data['goodsType']==1){ + $counts = Db::name('goods_virtuals')->where(['dataFlag'=>1,'isUse'=>0,'goodsId'=>$goodsId])->Count(); + $data['goodsStock'] = $counts; + } + $result = $this->validate(true)->allowField(true)->save($data,['goodsId'=>$goodsId]); + if(false !== $result){ + //ect支付方式 + $ectPay=(int)input('ectPay'); + $findEct=db('goods_pay')->where('goodsId',$goodsId)->find(); + if($findEct){ + db('goods_pay')->where('goodsId',$goodsId)->update(['ectPay'=>$ectPay]); + }else{ + db('goods_pay')->insert(['goodsId'=>$goodsId,'ectPay'=>$ectPay]); + } + + /** + * 编辑的时候如果不想影响商品销售规格的销量,那么就要在保存的时候区别对待已经存在的规格和销售规格记录。 + * $specNameMap的保存关系是:array('页面上生成的规格值ID'=>数据库里规则值的ID) + * $specIdMap的保存关系是:array('页面上生成的销售规格ID'=>数据库里销售规格ID) + */ + $specNameMapTmp = explode(',',input('post.specmap')); + $specIdMapTmp = explode(',',input('post.specidsmap')); + $specNameMap = [];//规格值对应关系 + $specIdMap = [];//规格和表对应关系 + foreach ($specNameMapTmp as $key =>$v){ + if($v=='')continue; + $v = explode(':',$v); + $specNameMap[$v[1]] = $v[0]; //array('页面上的规则值ID'=>数据库里规则值的ID) + } + foreach ($specIdMapTmp as $key =>$v){ + if($v=='')continue; + $v = explode(':',$v); + $specIdMap[$v[1]] = $v[0]; //array('页面上的销售规则ID'=>数据库里销售规格ID) + } + //如果是实物商品并且有销售规格则保存销售和规格值 + if($data['goodsType'] ==0 && $specsIds!=''){ + //把之前之前的销售规格 + $specsIds = explode(',',$specsIds); + $specsArray = []; + foreach ($specsIds as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsArray))$specsArray[] = $vv;//过滤出不重复的规格值 + } + } + //先标记作废之前的规格值 + Db::name('spec_items')->where(['shopId'=>$shopId,'goodsId'=>$goodsId])->update(['dataFlag'=>-1]); + //保存规格名称 + $specMap = []; + foreach ($specsArray as $v){ + $vv = explode('_',$v); + $specNumId = $vv[0]."_".$vv[1]; + $sitem = []; + $sitem['itemName'] = input('post.specName_'.$specNumId); + $sitem['itemImg'] = input('post.specImg_'.$specNumId); + //如果已经存在的规格值则修改,否则新增 + if(isset($specNameMap[$specNumId]) && (int)$specNameMap[$specNumId]!=0){ + $sitem['dataFlag'] = 1; + WSTUseImages(0, (int)$specNameMap[$specNumId], $sitem['itemImg'],'spec_items','itemImg'); + Db::name('spec_items')->where(['shopId'=>$shopId,'itemId'=>(int)$specNameMap[$specNumId]])->update($sitem); + $specMap[$v] = (int)$specNameMap[$specNumId]; + }else{ + $sitem['goodsId'] = $goodsId; + $sitem['shopId'] = $shopId; + $sitem['catId'] = (int)$vv[0]; + $sitem['dataFlag'] = 1; + $sitem['createTime'] = date('Y-m-d H:i:s'); + $itemId = Db::name('spec_items')->insertGetId($sitem); + if($sitem['itemImg']!='')WSTUseImages(0, $itemId, $sitem['itemImg']); + $specMap[$v] = $itemId; + } + } + //删除已经作废的规格值 + Db::name('spec_items')->where(['shopId'=>$shopId,'goodsId'=>$goodsId,'dataFlag'=>-1])->delete(); + //保存销售规格 + $defaultPrice = 0;//默认价格 + $totalStock = 0;//总库存 + $gspecArray = []; + //把之前的销售规格值标记删除 + Db::name('goods_specs')->where(['goodsId'=>$goodsId,'shopId'=>$shopId])->update(['dataFlag'=>-1,'isDefault'=>0]); + $isFindDefaultSpec = false; + $defaultSpec = Input('post.defaultSpec'); + foreach ($specsIds as $v){ + $vs = explode('-',$v); + $goodsSpecIds = []; + foreach ($vs as $gvs){ + $goodsSpecIds[] = $specMap[$gvs]; + } + $gspec = []; + $gspec['specIds'] = implode(':',$goodsSpecIds); + $gspec['productNo'] = Input('productNo_'.$v); + $gspec['marketPrice'] = (float)Input('marketPrice_'.$v); + $gspec['specPrice'] = (float)Input('specPrice_'.$v); + $gspec['initNum'] = (int)Input('initNum_'.$v);//添加起批价数量 mark hsf 20171117 + $gspec['whslePrice'] = (float)Input('whslePrice_'.$v);//添加批发价 mark hsf 20171117 + $gspec['specStock'] = (int)Input('specStock_'.$v); + $gspec['warnStock'] = (int)Input('warnStock_'.$v); + //设置默认规格 + if($defaultSpec==$v){ + $gspec['isDefault'] = 1; + $isFindDefaultSpec = true; + $defaultPrice = $gspec['specPrice']; + }else{ + $gspec['isDefault'] = 0; + } + //如果是已经存在的值就修改内容,否则新增 + if(isset($specIdMap[$v]) && $specIdMap[$v]!=''){ + $gspec['dataFlag'] = 1; + Db::name('goods_specs')->where(['shopId'=>$shopId,'id'=>(int)$specIdMap[$v]])->update($gspec); + }else{ + $gspec['shopId'] = $shopId; + $gspec['goodsId'] = $goodsId; + $gspecArray[] = $gspec; + } + //获取总库存 + $totalStock = $totalStock + $gspec['specStock']; + } + if(!$isFindDefaultSpec)return WSTReturn("请选择推荐规格"); + //删除作废的销售规格值 + Db::name('goods_specs')->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'dataFlag'=>-1])->delete(); + if(count($gspecArray)>0){ + Db::name('goods_specs')->insertAll($gspecArray); + } + //更新推荐规格和总库存 + $this->where('goodsId',$goodsId)->update(['isSpec'=>1,'shopPrice'=>$defaultPrice,'goodsStock'=>$totalStock]); + } + //保存商品属性 + //删除之前的商品属性 + Db::name('goods_attributes')->where(['goodsId'=>$goodsId,'shopId'=>$shopId])->delete(); + //新增商品属性 + $attrsArray = []; + $attrRs = Db::name('attributes')->where(['goodsCatId'=>['in',$goodsCats],'isShow'=>1,'dataFlag'=>1]) + ->field('attrId')->select(); + foreach ($attrRs as $key =>$v){ + $attrs = []; + $attrs['attrVal'] = input('attr_'.$v['attrId']); + if($attrs['attrVal']=='')continue; + $attrs['shopId'] = $shopId; + $attrs['goodsId'] = $goodsId; + $attrs['attrId'] = $v['attrId']; + $attrs['createTime'] = date('Y-m-d H:i:s'); + $attrsArray[] = $attrs; + } + if(count($attrsArray)>0)Db::name('goods_attributes')->insertAll($attrsArray); + //删除购物车里的商品 + model('common/carts')->delCartByUpdate($goodsId); + //修改商品成本价 + + if($aloneShop){ + $now = time(); + if(Db::name('alone_goods')->where(['goodsId'=>$goodsId])->find()){ + Db::name('alone_goods')->where(['shopId'=>$shopId,'goodsId'=>$goodsId])->update(['basicsMoney'=>$basicsMoney,'updateTime'=>$now]); + }else{ + Db::name('alone_goods')->insert(['shopId'=>$shopId,'goodsId'=>$goodsId,'basicsMoney'=>$basicsMoney,'createTime'=>$now,'updateTime'=>$now]); + } + + } + //商品编辑之后执行 + hook('afterEditGoods',['goodsId'=>$goodsId]); + hook('afterChangeGoodsStatus',['goodsId'=>$goodsId]); + hook('afterGoodsEct',['data'=>&$data,'goodsId'=>$goodsId]); + Db::commit(); + return WSTReturn("编辑成功", 1,['id'=>$goodsId]); + }else{ + return WSTReturn($this->getError(),-1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + dump($e); + return WSTReturn('编辑失败',-1); + } + } + + /** + * 获取商品资料方便编辑 + */ + public function getById($goodsId){ + $rs = $this->alias('g')->join('__ALONE_GOODS__ ag','g.goodsId=ag.goodsId','left')->where(['g.shopId'=>(int)session('WST_USER.shopId'),'g.goodsId'=>$goodsId])->field('g.*,ag.basicsMoney')->find(); + isset($rs['basicsMoney']) ? $rs['basicsMoney'] : $rs['basicsMoney'] = ''; + if(!empty($rs)){ + if($rs['gallery']!='')$rs['gallery'] = explode(',',$rs['gallery']); + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + $spec0 = []; + $spec1 = []; + foreach ($specs as $key =>$v){ + if($v['isAllowImg']==1){ + $spec0[] = $v; + }else{ + $spec1[] = $v; + } + } + $rs['spec0'] = $spec0; + $rs['spec1'] = $spec1; + //获取销售规格 + $rs['saleSpec'] = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,initNum,whslePrice,specStock,warnStock,saleNum')->select(); + // print_r($rs);die; + // $rs['saleSpec'][0]['ectPrice'] = ($specPrice * '0.95'); + //获取属性值 + $rs['attrs'] = Db::name('goods_attributes')->alias('ga')->join('attributes a','ga.attrId=a.attrId','inner') + ->where('goodsId',$goodsId)->field('ga.attrId,a.attrType,ga.attrVal')->select(); + $rs['ectPay']=Db::name('goods')->alias('g')->join('goods_pay ge','ge.goodsId=g.goodsId','left')->where('g.goodsId',$goodsId)->value('ectPay'); + // echo $specPrice;die; + } + return $rs; + } + /** + * 获取商品资料在前台展示 + */ + public function getBySale($goodsId){ + $key = input('key'); + // 浏览量 + $this->where('goodsId',$goodsId)->setInc('visitNum',1); + $rs = Db::name('goods')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->find(); + if(!empty($rs)){ + $rs['read'] = false; + //判断是否可以公开查看 + $viKey = WSTShopEncrypt($rs['shopId']); + if(($rs['isSale']==0 || $rs['goodsStatus']==0) && $viKey != $key)return []; + if($key!='')$rs['read'] = true; + //获取店铺信息 + $rs['shop'] = model('shops')->getBriefShop((int)$rs['shopId']); + if(empty($rs['shop']))return []; + $gallery = []; + $gallery[] = $rs['goodsImg']; + if($rs['gallery']!=''){ + $tmp = explode(',',$rs['gallery']); + $gallery = array_merge($gallery,$tmp); + } + $rs['gallery'] = $gallery; + if($rs['isSpec']==1){ + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,gc.catName,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + foreach ($specs as $key =>$v){ + $rs['spec'][$v['catId']]['name'] = $v['catName']; + $rs['spec'][$v['catId']]['list'][] = $v; + } + + //获取销售规格 + $sales = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,specStock')->select(); + if(!empty($sales)){ + foreach ($sales as $key =>$v){ + $str = explode(':',$v['specIds']); + sort($str); + unset($v['specIds']); + $rs['saleSpec'][implode(':',$str)] = $v; + if($v['isDefault']==1)$rs['defaultSpecs'] = $v; + } + } + } + //获取商品属性 + $rs['attrs'] = Db::name('attributes')->alias('a')->join('goods_attributes ga','a.attrId=ga.attrId','inner') + ->where(['a.isShow'=>1,'dataFlag'=>1,'goodsId'=>$goodsId])->field('a.attrName,ga.attrVal') + ->order('attrSort asc')->select(); + //获取商品评分 + $rs['scores'] = Db::name('goods_scores')->where('goodsId',$goodsId)->field('totalScore,totalUsers')->find(); + $rs['scores']['totalScores'] = ($rs['scores']['totalScore']==0)?5:WSTScore($rs['scores']['totalScore'],$rs['scores']['totalUsers'],5,0,3); + WSTUnset($rs, 'totalUsers'); + //品牌名称 + $rs['brandName'] = Db::name('brands')->where(['brandId'=>$rs['brandId']])->value('brandName'); + //关注 + $f = model('Favorites'); + $rs['favShop'] = $f->checkFavorite($rs['shopId'],1); + $rs['favGood'] = $f->checkFavorite($goodsId,0); + } + return $rs; + } + + /** + * 删除商品 + */ + public function del(){ + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $result = $this->update($data,['goodsId'=>$id]); + if(false !== $result){ + WSTUnuseImage('goods','goodsImg',$id); + WSTUnuseImage('goods','gallery',$id); + // 商品描述图片 + $desc = $this->where('goodsId',$id)->value('goodsDesc'); + WSTEditorImageRocord(0, $id, $desc,''); + model('common/carts')->delCartByUpdate($id); + hook('afterChangeGoodsStatus',['goodsId'=>$id]); + Db::commit(); + //标记删除购物车 + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + /** + * 批量删除商品 + */ + public function batchDel(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('post.ids/a'); + Db::startTrans(); + try{ + $rs = $this->where(['goodsId'=>['in',$ids], + 'shopId'=>$shopId])->setField('dataFlag',-1); + if(false !== $rs){ + //标记删除购物车 + foreach ($ids as $v){ + WSTUnuseImage('goods','goodsImg',(int)$v); + WSTUnuseImage('goods','gallery',(int)$v); + // 商品描述图片 + $desc = $this->where('goodsId',(int)$v)->value('goodsDesc'); + WSTEditorImageRocord(0, (int)$v, $desc,''); + model('common/carts')->delCartByUpdate((int)$v); + hook('afterChangeGoodsStatus',['goodsId'=>(int)$v]); + } + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } + + /** + * 批量上架商品 + */ + public function changeSale(){ + $ids = input('post.ids/a'); + $isSale = (int)input('post.isSale',1); + $shopId = (int)session('WST_USER.shopId'); + //判断商品是否满足上架要求 + if($isSale==1){ + //0.核对店铺状态 + $shopRs = model('shops')->find($shopId); + if($shopRs['shopStatus']!=1 || $shopRs['dataFlag']==-1){ + return WSTReturn('上架商品失败!您的店铺权限不能出售商品,如有疑问请与商城管理员联系。',-3); + } + //直接设置上架 返回受影响条数 + $where = []; + $where['g.goodsId'] = ['in',$ids]; + $where['gc.dataFlag'] = 1; + $where['g.shopId'] = $shopId; + $where['gc.isShow'] = 1; + $where['g.goodsImg'] = ['<>',""]; + $rs = $this->alias('g') + ->join('__GOODS_CATS__ gc','g.goodsCatId=gc.CatId','inner') + ->where($where)->setField('isSale',1); + if($rs!==false){ + //执行钩子事件 + foreach ($ids as $key => $gid) { + hook('afterChangeGoodsStatus',['goodsId'=>$gid]); + } + $status = ($rs==count($ids))?1:2; + if($status==1){ + return WSTReturn('商品上架成功', 1,['num'=>$rs]); + }else{ + return WSTReturn('已成功上架商品'.$rs.'件,请核对未能上架的商品信息是否完整。', 2,['num'=>$rs]); + } + }else{ + return WSTReturn('上架失败,请核对商品信息是否完整!', -2); + } + + }else{ + $rs = $this->where(['goodsId'=>['in',$ids],'shopId'=>$shopId])->setField('isSale',0); + if($rs !== false){ + //执行钩子事件 + foreach ($ids as $key => $gid) { + hook('afterChangeGoodsStatus',['goodsId'=>$gid]); + } + model('common/carts')->delCartByUpdate($ids); + return WSTReturn('商品上架成功', 1); + }else{ + return WSTReturn($this->getError(), -1); + } + } + } + /** + * 修改商品状态 + */ + public function changSaleStatus(){ + $shopId = (int)session('WST_USER.shopId'); + $allowArr = ['isHot','isNew','isBest','isRecom','storeRecom']; + $is = input('post.is'); + if(!in_array($is,$allowArr))return WSTReturn('非法操作',-1); + $status = (input('post.status',1)==1)?0:1; + $id = (int)input('post.id'); + $rs = $this->where(["shopId"=>$shopId,'goodsId'=>$id])->setField($is,$status); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 修改商品状态 + */ + public function changStoreRecom(){ + $status = (input('post.status',1)==1)?0:1; + $id = (int)input('post.id'); + $rs = db('store_recom')->where(['goodsId'=>$id])->update(['storeStatus'=>$status]); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 批量修改商品状态 + */ + public function changeGoodsStatus(){ + $shopId = (int)session('WST_USER.shopId'); + //设置为什么 hot new best rec + $allowArr = ['isHot','isNew','isBest','isRecom','storeRecom']; + $is = input('post.is'); + if(!in_array($is,$allowArr))return WSTReturn('非法操作',-1); + //设置哪一个状态 + $status = input('post.status',1); + $ids = input('post.ids/a'); + $rs = $this->where(['goodsId'=>['in',$ids],'shopId'=>$shopId])->setField($is, $status); + if($rs!==false){ + return WSTReturn('设置成功',1); + }else{ + return WSTReturn($this->getError(),-1); + } + + } + /** + * 批量修改商品 店长推荐 + */ + public function changeStoreStatus(){ + $ids=input('post.ids/a'); + $find = db('store_recom')->where(['goodsId'=>['in',$ids]])->column('goodsId'); + Db::startTrans(); + try{ + if(!$find){ + foreach($ids as $k=>$v){ + $info=[]; + $info['goodsId']=$v; + $info['storeStatus']= input('post.status',1); + //dump($info); + $data[]=$info; + } + $rs=db('store_recom')->insertAll($data); + } + if($find){ + foreach($find as $k=>$v){ + $rs=db('store_recom')->where('goodsId',$v)->update(['storeStatus'=>input('post.status',1)]); + } + $another=array_diff($ids,$find); + if(count($another)>0){ + foreach($another as $k=>$v){ + $info=[]; + $info['goodsId']=$v; + $info['storeStatus']= input('post.status',1); + //dump($info); + $data[]=$info; + } + $rs=db('store_recom')->insertAll($data); + } + + } + Db::commit(); + return WSTReturn("设置成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + } + /** + * 获取商品规格属性 + */ + public function getSpecAttrs(){ + $goodsType = (int)input('goodsType'); + $goodsCatId = Input('post.goodsCatId/d'); + $goodsCatIds = model('GoodsCats')->getParentIs($goodsCatId); + $data = []; + if($goodsType==0){ + $specs = Db::name('spec_cats')->where(['dataFlag'=>1,'isShow'=>1,'goodsCatId'=>['in',$goodsCatIds]])->field('catId,catName,isAllowImg')->order('isAllowImg desc,catSort asc,catId asc')->select(); + $spec0 = null; + $spec1 = []; + foreach ($specs as $key => $v){ + if($v['isAllowImg']==1){ + $spec0 = $v; + }else{ + $spec1[] = $v; + } + } + $data['spec0'] = $spec0; + $data['spec1'] = $spec1; + } + $data['attrs'] = Db::name('attributes')->where(['dataFlag'=>1,'isShow'=>1,'goodsCatId'=>['in',$goodsCatIds]])->field('attrId,attrName,attrType,attrVal')->order('attrSort asc,attrId asc')->select(); + return WSTReturn("", 1,$data); + } + + /** + * 检测商品主表的货号或者商品编号 + */ + public function checkExistGoodsKey($key,$val,$id = 0){ + if(!in_array($key,array('goodsSn','productNo')))return WSTReturn("非法的查询字段"); + $conditon = [$key=>$val]; + if($id>0)$conditon['goodsId'] = ['<>',$id]; + $rs = $dbo = $this->where($conditon)->count(); + return ($rs==0)?false:true; + } + + /** + * 获取符合筛选条件的商品ID + */ + public function filterByAttributes(){ + $vs = input('vs'); + if($vs=='')return []; + $vs = explode(',',$vs); + $goodsIds = []; + $prefix = config('database.prefix'); + //循环遍历每个属性相关的商品ID + foreach ($vs as $v){ + $goodsIds2 = []; + $attrVal = input('v_'.(int)$v); + if($attrVal=='')continue; + if(stristr($attrVal,'、')!==false){ + // 同属性多选 + $attrArr = explode('、',$attrVal); + foreach($attrArr as $v1){ + $sql = "select goodsId from ".$prefix."goods_attributes where attrId=".(int)$v." and find_in_set('".$v1."',attrVal) "; + $rs = Db::query($sql); + if(!empty($rs)){ + foreach ($rs as $vg){ + $goodsIds2[] = $vg['goodsId']; + } + } + } + }else{ + $sql = "select goodsId from ".$prefix."goods_attributes + where attrId=".(int)$v." and find_in_set('".$attrVal."',attrVal) "; + $rs = Db::query($sql); + if(!empty($rs)){ + foreach ($rs as $vg){ + $goodsIds2[] = $vg['goodsId']; + } + } + } + //如果有一个属性是没有商品的话就不需要查了 + if(empty($goodsIds2))return [-1]; + //第一次比较就先过滤,第二次以后的就找集合 + $goodsIds2[] = -1; + if(empty($goodsIds)){ + $goodsIds = $goodsIds2; + }else{ + $goodsIds = array_intersect($goodsIds,$goodsIds2); + } + } + return $goodsIds; + } + + /** + * 获取分页商品记录 + */ + public function pageQuery($goodsCatIds = []){ + //查询条件 + $isStock = input('isStock/d'); + $isNew = input('isNew/d'); + $isFreeShipping = input('isFreeShipping/d'); + $keyword = input('keyword'); + $where = $where2 = $where3 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $where['goodsCatIdPath']=['notlike','389'.'%']; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + //属性筛选 + $goodsIds = $this->filterByAttributes(); + if(!empty($goodsIds))$where['goodsId'] = ['in',$goodsIds]; + // 品牌筛选 + $brandIds = input('param.brand'); + if(!empty($brandIds)){ + $brandIds = explode(',',$brandIds); + $where['brandId'] = ['in',$brandIds]; + } + + // 发货地 + $areaId = (int)input('areaId'); + if($areaId>0)$where['areaId'] = $areaId; + //排序条件 + $orderBy = input('orderBy/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + //默认销量从高到低排序, mark by cheng 20130317 + $order = (input('order/d',1)==1)?1:0; + $pageBy = ['saleNum','shopPrice','appraiseNum','visitNum','saleTime']; + $pageOrder = ['asc','desc']; + if($isStock==1)$where['goodsStock'] = ['>',0]; + if($isNew==1)$where['isNew'] = ['=',1]; + if($isFreeShipping==1)$where['isFreeShipping'] = 1; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $sprice = input("param.sprice");//开始价格 + $eprice = input("param.eprice");//结束价格 + if($sprice!='' && $eprice!=''){ + $where['g.shopPrice'] = ['between',[(int)$sprice,(int)$eprice]]; + }elseif($sprice!=''){ + $where['g.shopPrice'] = [">=",(int)$sprice]; + }elseif($eprice!=''){ + $where['g.shopPrice'] = ["<=",(int)$eprice]; + } + $list = Db::name("goods")->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId") + ->where($where) + ->field('goodsId,goodsName,goodsSn,goodsStock,isNew,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pagesize/d',16))->toArray(); + //加载标签 + if(!empty($list['Rows'])){ + foreach ($list['Rows'] as $key => $v) { + $list['Rows'][$key]['tags'] = []; + if($v['isSelf']==1)$list['Rows'][$key]['tags'][] = "<span class='tag'>自营</span>"; + if($v['isFreeShipping']==1)$list['Rows'][$key]['tags'][] = "<span class='tag'>包邮</span>"; + } + } + //关注 + if($list['Rows']){ + foreach ($list['Rows'] as $key =>$v){ + $list['Rows'][$key]['favGood'] = model('Favorites')->checkFavorite($v['goodsId'],0); + } + } + hook('afterQueryGoods',['page'=>&$list]); + return $list; + } + /** + * 获取价格范围 + */ + public function getPriceGrade($goodsCatIds = []){ + $isStock = input('isStock/d'); + $isNew = input('isNew/d'); + $keyword = input('keyword'); + $isFreeShipping = input('isFreeShipping/d'); + $where = $where2 = $where3 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + $areaId = (int)input('areaId'); + if($areaId>0)$where['areaId'] = $areaId; + //属性筛选 + $goodsIds = $this->filterByAttributes(); + if(!empty($goodsIds))$where['goodsId'] = ['in',$goodsIds]; + //排序条件 + $orderBy = input('orderBy/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('order/d',0)==1)?1:0; + $pageBy = ['saleNum','shopPrice','appraiseNum','visitNum','saleTime']; + $pageOrder = ['asc','desc']; + if($isStock==1)$where['goodsStock'] = ['>',0]; + if($isNew==1)$where['isNew'] = ['=',1]; + if($isFreeShipping==1)$where['isFreeShipping'] = 1; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $sprice = input("param.sprice");//开始价格 + $eprice = input("param.eprice");//结束价格 + if($sprice!='' && $eprice!=''){ + $where['g.shopPrice'] = ['between',[(int)$sprice,(int)$eprice]]; + }elseif($sprice!=''){ + $where['g.shopPrice'] = [">=",(int)$sprice]; + }elseif($eprice!=''){ + $where['g.shopPrice'] = ["<=",(int)$eprice]; + } + $rs = Db::name("goods")->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId",'inner') + ->where($where) + ->field('min(shopPrice) minPrice,max(shopPrice) maxPrice')->find(); + + if($rs['maxPrice']=='')return; + $minPrice = 0; + $maxPrice = $rs['maxPrice']; + $pavg5 = ($maxPrice/5); + $prices = array(); + $price_grade = 0.0001; + for($i=-2; $i<= log10($maxPrice); $i++){ + $price_grade *= 10; + } + //区间跨度 + $span = ceil(($maxPrice - $minPrice) / 8 / $price_grade) * $price_grade; + if($span == 0){ + $span = $price_grade; + } + for($i=1;$i<=8;$i++){ + $prices[($i-1)*$span."_".($span * $i)] = ($i-1)*$span."-".($span * $i); + if(($span * $i)>$maxPrice) break; + } + + return $prices; + } + + /** + * 修改商品库存/价格 + */ + public function editGoodsBase(){ + $goodsId = (int)Input("goodsId"); + $post = input('post.'); + $data = []; + if(isset($post['goodsStock'])){ + $data['goodsStock'] = (int)input('post.goodsStock',0); + if($data['goodsStock']<0)return WSTReturn('操作失败,库存不能为负数'); + }elseif(isset($post['shopPrice'])){ + $data['shopPrice'] = (float)input('post.shopPrice',0); + if($data['shopPrice']<0.01)return WSTReturn('操作失败,价格必须大于0.01'); + }else{ + return WSTReturn('操作失败',-1); + } + $rs = $this->update($data,['goodsId'=>$goodsId,'shopId'=>(int)session('WST_USER.shopId')]); + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + /** + * 预警库存列表 + */ + public function stockByPage(){ + $where = []; + $c1Id = (int)input('cat1'); + $c2Id = (int)input('cat2'); + $shopId = (int)session('WST_USER.shopId'); + if($c1Id!=0)$where[] = " shopCatId1=".$c1Id; + if($c2Id!=0)$where[] = " shopCatId2=".$c2Id; + $where[] = " g.shopId = ".$shopId; + $prefix = config('database.prefix'); + $sql1 = 'SELECT g.goodsId,g.goodsName,g.goodsType,g.goodsImg,gs.specStock goodsStock ,gs.warnStock warnStock,g.isSpec,gs.productNo,gs.id,gs.specIds,g.isSale + FROM '.$prefix.'goods g inner JOIN '.$prefix.'goods_specs gs ON gs.goodsId=g.goodsId and gs.specStock <= gs.warnStock and gs.warnStock>0 + WHERE g.dataFlag = 1 and '.implode(' and ',$where); + + $sql2 = 'SELECT g.goodsId,g.goodsName,g.goodsType,g.goodsImg,g.goodsStock,g.warnStock,g.isSpec,g.productNo,0 as id,"" as specIds,g.isSale + FROM '.$prefix.'goods g + WHERE g.dataFlag = 1 and isSpec=0 and g.goodsStock<=g.warnStock + and g.warnStock>0 and '.implode(' and ',$where); + $page = (int)input('post.'.config('paginate.var_page')); + $page = ($page<=0)?1:$page; + $pageSize = 15; + $start = ($page-1)*$pageSize; + $sql = $sql1." union ".$sql2; + $sqlNum = 'select count(*) wstNum from ('.$sql.") as c"; + $sql = 'select * from ('.$sql.') as c order by isSale desc limit '.$start.','.$pageSize; + $rsNum = Db::query($sqlNum); + $rsRows = Db::query($sql); + $rs = WSTPager((int)$rsNum[0]['wstNum'],$rsRows,$page,$pageSize); + if(empty($rs['Rows']))return $rs; + $specIds = []; + foreach ($rs['Rows'] as $key =>$v){ + $specIds[$key] = explode(':',$v['specIds']); + $rss = Db::name('spec_items')->alias('si') + ->join('__SPEC_CATS__ sc','sc.catId=si.catId','left') + ->where('si.shopId = '.$shopId.' and si.goodsId = '.$v['goodsId']) + ->where('si.itemId','in',$specIds[$key]) + ->field('si.itemId,si.itemName,sc.catId,sc.catName') + ->select(); + $rs['Rows'][$key]['spec'] = $rss; + } + return $rs; + } + /** + * 预警修改预警库存 + */ + public function editwarnStock(){ + $id = input('post.id/d'); + $type = input('post.type/d'); + $number = (int)input('post.number'); + $shopId = (int)session('WST_USER.shopId'); + $data = $data2 = []; + $data['shopId'] = $data2['shopId'] = $shopId; + $datat=array('1'=>'specStock','2'=>'warnStock','3'=>'goodsStock','4'=>'warnStock'); + if(!empty($type)){ + $data[$datat[$type]] = $number; + if($type==1 || $type==2){ + $data['goodsId'] = $goodsId = input('post.goodsId/d'); + $rss = Db::name("goods_specs")->where('id', $id)->update($data); + //更新商品库存 + $goodsStock = 0; + if($rss!==false){ + $specStocks = Db::name("goods_specs")->where(['shopId'=>$shopId,'goodsId'=>$goodsId,'dataFlag'=>1])->field('specStock')->select(); + foreach ($specStocks as $key =>$v){ + $goodsStock = $goodsStock+$v['specStock']; + } + $data2['goodsStock'] = $goodsStock; + $rs = $this->update($data2,['goodsId'=>$goodsId]); + }else{ + return WSTReturn('操作失败',-1); + } + } + if($type==3 || $type==4){ + $rs = $this->update($data,['goodsId'=>$id]); + } + if($rs!==false){ + return WSTReturn('操作成功',1); + }else{ + return WSTReturn('操作失败',-1); + } + } + return WSTReturn('操作失败',-1); + } +} diff --git a/hyhproject/home2/model/GoodsVirtuals.php b/hyhproject/home2/model/GoodsVirtuals.php new file mode 100755 index 0000000..952f6fa --- /dev/null +++ b/hyhproject/home2/model/GoodsVirtuals.php @@ -0,0 +1,174 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Goods as CGoodsVirtuals; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 虚拟商品卡券模型 + */ +class GoodsVirtuals extends CGoodsVirtuals{ + /** + * 导入 + */ + public function importCards($data){ + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objReader = \PHPExcel_IOFactory::load(WSTRootPath().json_decode($data)->route.json_decode($data)->name); + $objReader->setActiveSheetIndex(0); + $sheet = $objReader->getActiveSheet(); + $rows = $sheet->getHighestRow(); + $cells = $sheet->getHighestColumn(); + //数据集合 + $readData = []; + $shopId = (int)session('WST_USER.shopId'); + $goodsId = (int)input('goodsId'); + $importNum = 0; + //生成订单 + Db::startTrans(); + try{ + //读取现有的卡券 + $goodscards = Db::name('goods_virtuals')->where(['dataFlag'=>1,'goodsId'=>$goodsId])->field('cardNo')->select(); + $goodscardsMap = []; + if(count($goodscards)>0){ + foreach($goodscards as $v){ + $goodscardsMap[] = $v['cardNo']; + } + } + //循环读取每个单元格的数据 + for ($row = 2; $row <= $rows; $row++){//行数是以第2行开始 + $cards = []; + $cards['shopId'] = $shopId; + $cards['goodsId'] = $goodsId; + $cardNo = trim($sheet->getCell("A".$row)->getValue()); + if($cardNo=='')break;//如果某一行第一列为空则停止导入 + $cards['cardNo'] = $cardNo; + $cards['cardPwd'] = trim($sheet->getCell("B".$row)->getValue()); + $cards['createTime'] = date('Y-m-d H:i:s'); + if(in_array($cardNo,$goodscardsMap))continue; + $goodscardsMap[] = $cardNo; + $readData[] = $cards; + $importNum++; + } + if(count($readData)>0){ + model('GoodsVirtuals')->saveAll($readData); + $this->updateGoodsStock($goodsId); + } + Db::commit(); + return json_encode(['status'=>1,'importNum'=>$importNum]); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return json_encode(WSTReturn('导入商品卡券失败',-1)); + } + } + + /** + * 删除 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('ids'); + $id = input('id'); + if($ids=='')return WSTReturn('请选择要删除的卡券号'); + try{ + $this->where(['shopId'=>$shopId,'id'=>['in',$ids],'goodsId'=>$id])->update(['dataFlag'=>-1]); + $this->updateGoodsStock($id); + Db::commit(); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败'); + } + return WSTReturn('操作成功',1); + } + + /** + * 编辑 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $id = (int)input('id'); + //判断卡券是否有效 + $rs = $this->where(['id'=>$id,'shopId'=>$shopId,'dataFlag'=>1,'isUse'=>0])->find(); + if(empty($rs))return WSTReturn('非法的卡券'); + $cardNo = input('cardNo'); + $cardPwd = input('cardPwd'); + if($cardNo=='' || $cardPwd=='')return WSTReturn('请输入完整卡券信息'); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo,'id'=>['<>',$id]])->Count(); + if($conts>0)return WSTReturn('该卡券号已存在,请重新输入'); + $rs->cardNo = $cardNo; + $rs->cardPwd = $cardPwd; + $rs->save(); + return WSTReturn('操作成功',1); + } + + /** + * 获取虚拟商品库存列表 + */ + public function stockByPage(){ + $key = input('cardNo'); + $id = (int)input('id'); + $isUse = (int)input('isUse',-1); + $shopId = (int)session('WST_USER.shopId'); + $where = ['shopId'=>$shopId,'goodsId'=>$id,'dataFlag'=>1]; + if($key !='')$where['cardNo'] = ['like','%'.$key.'%']; + if(in_array($isUse,[0,1]))$where['isUse'] = $isUse; + $page = $this->field('orderNo,orderId,cardNo,id,cardPwd,isUse') + ->where($where)->order('id desc') + ->paginate(20)->toArray(); + return $page; + } + + /** + * 生成卡券号 + */ + public function getCardNo($shopId){ + $cardNo = date('Ymd').sprintf("%08d", rand(0,99999999)); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo])->Count(); + if($conts==0){ + return $cardNo; + }else{ + return $this->getCardNo($shopId); + } + } + + /** + * 生成卡券 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $goodsId = (int)input('goodsId'); + //判断商品是否有效 + $goods = model('goods')->where(['goodsId'=>$goodsId,'shopId'=>$shopId,'goodsType'=>1])->find(); + if(empty($goods))return WSTReturn('非法的卡券商品'); + $cardNo = input('cardNo'); + $cardPwd = input('cardPwd'); + if($cardNo=='' || $cardPwd=='')return WSTReturn('请输入完整卡券信息'); + $conts = $this->where(['shopId'=>$shopId,'dataFlag'=>1,'cardNo'=>$cardNo])->Count(); + if($conts>0)return WSTReturn('该卡券号已存在,请重新输入'); + $data = []; + $data['cardNo'] = $cardNo; + $data['cardPwd'] = $cardPwd; + $data['dataFlag'] = 1; + $data['shopId'] = $shopId; + $data['goodsId'] = $goodsId; + $data['createTime'] = date('Y-m-d H:i:s'); + Db::startTrans(); + try{ + $this->save($data); + $this->updateGoodsStock($goodsId); + Db::commit(); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('新增失败'); + } + return WSTReturn('新增成功',1); + } + + /** + * 更新商品数量 + */ + public function updateGoodsStock($id){ + $shopId = (int)session('WST_USER.shopId'); + $counts = $this->where(['dataFlag'=>1,'goodsId'=>$id,'shopId'=>$shopId,'isUse'=>0])->Count(); + Db::name('goods')->where('goodsId',$id)->setField('goodsStock',$counts); + } +} \ No newline at end of file diff --git a/hyhproject/home2/model/HomeMenus.php b/hyhproject/home2/model/HomeMenus.php new file mode 100755 index 0000000..8697113 --- /dev/null +++ b/hyhproject/home2/model/HomeMenus.php @@ -0,0 +1,205 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\HomeMenus as CHomeMenus; +use think\Db; +/** + * ============================================================================ + * 菜单业务处理 + */ +class HomeMenus extends CHomeMenus{ + /** + * 获取菜单树 + */ + public function getMenus(){ + $data = cache('WST_HOME_MENUS'); + if(!$data){ + $rs = $this->where(['isShow'=>1,'dataFlag'=>1]) + ->field('menuId,parentId,menuName,menuUrl,menuType')->order('menuSort asc,menuId asc')->select(); + $m1 = ['0'=>[],'1'=>[]]; + $tmp = []; + + //获取第一级 + foreach ($rs as $key => $v){ + if($v['parentId']==0){ + $m1[$v['menuType']][$v['menuId']] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + }else{ + $tmp[$v['parentId']][] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl']]; + } + } + //获取第二级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($tmp[$v1['menuId']]))$m1[$key][$key1]['list'] = $tmp[$v1['menuId']]; + } + } + //获取第三级 + foreach ($m1 as $key => $v){ + foreach ($v as $key1 => $v1){ + if(isset($v1['list'])){ + foreach ($v1['list'] as $key2 => $v2){ + if(isset($tmp[$v2['menuId']]))$m1[$key][$key1]['list'][$key2]['list'] = $tmp[$v2['menuId']]; + } + } + } + } + cache('WST_HOME_MENUS',$m1,31536000); + return $m1; + } + return $data; + } + + /** + * 获取店铺菜单树 + */ + public function getShopMenus(){ + $m1 = $this->getMenus(); + $userType = (int)session('WST_USER.userType'); + $menuUrls = array(); + if($userType==1){ + $shopId = (int)session('WST_USER.shopId'); + $roleId = (int)session('WST_USER.roleId'); + if($roleId>0){ + $role = model("home/ShopRoles")->getById($roleId); + $menuUrls = json_decode($role["privilegeUrls"],true); + foreach ($m1[1] as $k1 => $menus1) { + if(!array_key_exists($menus1["menuId"],$menuUrls)){ + unset($m1[1][$k1]); + }else{ + if(isset($menus1["list"])){ + if(count($menus1["list"])>0){ + foreach ($menus1["list"] as $k2 => $menus2) { + if(!array_key_exists($menus2["menuId"],$menuUrls[$menus1["menuId"]])){ + unset($m1[1][$k1]["list"][$k2]); + }else{ + if(isset($menus2["list"])){ + if(count($menus2["list"])>0){ + foreach ($menus2["list"] as $k3 => $menus3) { + $purls = $menuUrls[$menus1["menuId"]][$menus2["menuId"]]; + $urls = $purls["urls"]; + if(!in_array(strtolower($menus3["menuUrl"]),$urls)){ + unset($m1[1][$k1]["list"][$k2]["list"][$k3]); + } + } + }else{ + unset($m1[1][$k1]["list"][$k2]); + } + }else{ + unset($m1[1][$k1]["list"][$k2]); + } + } + } + if(count($m1[1][$k1]["list"])==0){ + unset($m1[1][$k1]); + } + }else{ + unset($m1[1][$k1]); + } + }else{ + unset($m1[1][$k1]); + } + } + } + } + } + return $m1; + } + + /** + * 获取菜单URL + */ + public function getMenusUrl(){ + $wst_user = session('WST_USER'); + $data = array(); + if(!empty($wst_user)){ + $data = cache('WST_PRO_MENUS'); + if(!$data){ + $list = $this->where('dataFlag',1)->order('menuType asc')->select(); + $menus = []; + foreach($list as $key => $v){ + $menus[strtolower($v['menuUrl'])] = $v['menuType']; + if($v['menuOtherUrl']!=''){ + $str = explode(',',$v['menuOtherUrl']); + foreach ($str as $vkey => $vv){ + if($vv=='')continue; + $menus[strtolower($vv)] = $v['menuType']; + } + } + } + cache('WST_PRO_MENUS',$menus,31536000); + return $menus; + } + } + return $data; + } + + /** + * 角色可访问url + */ + public function getShopMenusUrl(){ + $wst_user = session('WST_USER'); + + if(!empty($wst_user)){ + $roleId = isset($wst_user["roleId"])?(int)$wst_user["roleId"]:0; + if($roleId>0){ + $role = model("home/ShopRoles")->getById($roleId); + $menuUrls = $role["menuUrls"]; + $menuOtherUrls = $role["menuOtherUrls"]; + $shopUrls = array_merge($menuUrls,$menuOtherUrls); + } + } + $shopUrls[] = "home/shops/index"; + $shopUrls[] = "home/reports/getstatsales"; + return $shopUrls; + } + + + /** + * 获取菜单父ID + */ + public function getParentId($menuId){ + $data = cache('WST_HOME_MENUS_PARENT'); + if(!$data){ + $rs = $this->where(['isShow'=>1,'dataFlag'=>1]) + ->field('menuId,parentId,menuType')->order('menuSort asc,menuId asc')->select(); + $tmp = []; + foreach ($rs as $key => $v) { + $tmp[$v['menuId']] = $v; + } + $data = []; + foreach ($tmp as $key => $v) { + if($v['parentId']==0){ + $data[$v['menuId']] = $v; + }else{ + $data[$v['menuId']] = $tmp[$v['parentId']]; + } + } + cache('WST_HOME_MENUS_PARENT',$data,31536000); + } + return $data[$menuId]; + } + /** + * 获取店铺角色菜单 + */ + public function getRoleMenus(){ + $data = cache('WST_HOME_MENUS_SHOPROLE'); + if(!$data){ + $rs = $this->alias('m1') + ->join("__HOME_MENUS__ m2","m1.parentId=m2.menuId") + ->where(['m1.isShow'=>1,'m1.dataFlag'=>1,"m1.menuType"=>1,"m2.parentId"=>[">",0]]) + ->field('m1.menuId,m1.parentId,m2.parentId grandpaId,m1.menuName,m1.menuUrl,m1.menuOtherUrl,m1.menuType') + ->order('m1.menuSort asc,m1.menuId asc') + ->select(); + $m = array(); + //获取第一级 + foreach ($rs as $key => $v){ + $m[$v['menuId']] = ['menuId'=>$v['menuId'],'parentId'=>$v['parentId'],'grandpaId'=>$v['grandpaId'],'menuName'=>$v['menuName'],'menuUrl'=>$v['menuUrl'],'menuOtherUrl'=>$v['menuOtherUrl']]; + } + cache('WST_HOME_MENUS_SHOPROLE',$m,31536000); + return $m; + } + return $data; + } + + + +} diff --git a/hyhproject/home2/model/Imports.php b/hyhproject/home2/model/Imports.php new file mode 100755 index 0000000..0cb1903 --- /dev/null +++ b/hyhproject/home2/model/Imports.php @@ -0,0 +1,148 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 导入类 + */ +class Imports{ + /** + * 上传商品数据 + */ + public function importGoods($data){ + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objReader = \PHPExcel_IOFactory::load(WSTRootPath().json_decode($data)->route.json_decode($data)->name); + $objReader->setActiveSheetIndex(0); + $sheet = $objReader->getActiveSheet(); + $rows = $sheet->getHighestRow(); + $cells = $sheet->getHighestColumn(); + //数据集合 + $readData = []; + $shopId = (int)session('WST_USER.shopId'); + $importNum = 0; + $goodsCatMap = []; //记录最后一级商品分类 + $goodsCatPathMap = [];//记录商品分类路径 + $shopCatMap = [];//记录店铺分类 + $goodsCat1Map = [];//记录最后一级商品分类对应的一级分类 + $tmpGoodsCatId = 0; + $goodsCatBrandMap = [];//商品分类和品牌的对应关系 + //生成订单 + Db::startTrans(); + try{ + //循环读取每个单元格的数据 + for ($row = 3; $row <= $rows; $row++){//行数是以第3行开始 + $tmpGoodsCatId = 0; + $goods = []; + $goods['shopId'] = $shopId; + $goods['goodsName'] = trim($sheet->getCell("A".$row)->getValue()); + if($goods['goodsName']=='')break;//如果某一行第一列为空则停止导入 + $goods['goodsSn'] = trim($sheet->getCell("B".$row)->getValue()); + $goods['productNo'] = trim($sheet->getCell("C".$row)->getValue()); + $goods['marketPrice'] = trim($sheet->getCell("D".$row)->getValue()); + if(floatval($goods['marketPrice'])<0.01)$goods['marketPrice'] = 0.01; + $goods['shopPrice'] = trim($sheet->getCell("E".$row)->getValue()); + if(floatval($goods['shopPrice'])<0.01)$goods['shopPrice'] = 0.01; + $goods['goodsStock'] = trim($sheet->getCell("F".$row)->getValue()); + if(intval($goods['goodsStock'])<=0)$goods['goodsStock'] = 0; + $goods['warnStock'] = trim($sheet->getCell("G".$row)->getValue()); + if(intval($goods['warnStock'])<=0)$goods['warnStock'] = 0; + $goods['goodsImg'] = ''; + $goods['shopCatId1'] = 0; + $goods['shopCatId2'] = 0; + $goods['goodsUnit'] = trim($sheet->getCell("H".$row)->getValue()); + $goods['goodsSeoKeywords'] = trim($sheet->getCell("I".$row)->getValue()); + $goods['goodsTips'] = trim($sheet->getCell("J".$row)->getValue()); + $goods['isRecom'] = (trim($sheet->getCell("K".$row)->getValue())!='')?1:0; + $goods['isBest'] = (trim($sheet->getCell("L".$row)->getValue())!='')?1:0; + $goods['isNew'] = (trim($sheet->getCell("M".$row)->getValue())!='')?1:0; + $goods['isHot'] = (trim($sheet->getCell("N".$row)->getValue())!='')?1:0; + $goods['goodsCatId'] = 0; + //查询商城分类 + $goodsCat = trim($sheet->getCell("O".$row)->getValue()); + if(!empty($goodsCat)){ + //先判断集合是否存在,不存在的时候才查数据库 + if(isset($goodsCatMap[$goodsCat])){ + $goods['goodsCatId'] = $goodsCatMap[$goodsCat]; + $goods['goodsCatIdPath'] = $goodsCatPathMap[$goodsCat]; + $tmpGoodsCatId = $goodsCat1Map[$goodsCat]; + }else{ + $goodsCatId = Db::name('goods_cats')->where(['catName'=>$goodsCat,'dataFlag'=>1])->field('catId')->find(); + if(!empty($goodsCatId['catId'])){ + $goodsCats = model('GoodsCats')->getParentIs($goodsCatId['catId']); + $goods['goodsCatId'] = $goodsCatId['catId']; + $goods['goodsCatIdPath'] = implode('_',$goodsCats)."_"; + //放入集合 + $goodsCatMap[$goodsCat] = $goodsCatId['catId']; + $goodsCatPathMap[$goodsCat] = implode('_',$goodsCats)."_"; + $goodsCat1Map[$goodsCat] = $goodsCats[0]; + $tmpGoodsCatId = $goodsCats[0]; + } + } + } + //查询店铺分类 + $shopGoodsCat = trim($sheet->getCell("P".$row)->getValue()); + if(!empty($shopGoodsCat)){ + //先判断集合是否存在,不存在的时候才查数据库 + if(isset($shopCatMap[$shopGoodsCat])){ + $goods['shopCatId1'] = $shopCatMap[$shopGoodsCat]['s1']; + $goods['shopCatId2'] = $shopCatMap[$shopGoodsCat]['s2']; + }else{ + $shopCat= Db::name("shop_cats")->alias('sc1') + ->join('__SHOP_CATS__ sc2','sc2.parentId=sc1.catId','left') + ->field('sc1.catId catId1,sc2.catId catId2,sc2.catName') + ->where(['sc1.shopId'=> $shopId,'sc1.dataFlag'=>1,'sc2.catName'=>$shopGoodsCat]) + ->find(); + if(!empty($shopCat)){ + $goods['shopCatId1'] = $shopCat['catId1']; + $goods['shopCatId2'] = $shopCat['catId2']; + //放入集合 + $shopCatMap[$shopGoodsCat] = []; + $shopCatMap[$shopGoodsCat]['s1'] = $goods['shopCatId1']; + $shopCatMap[$shopGoodsCat]['s2'] = $goods['shopCatId2']; + } + } + } + //查询品牌 + $brand = trim($sheet->getCell("Q".$row)->getValue()); + if(!empty($brand)){ + if(isset($goodsCatBrandMap[$brand])){ + $goods['brandId'] = $goodsCatBrandMap[$brand]; + }else{ + $brands = Db::name('brands')->alias('a')->join('__CAT_BRANDS__ cb','a.brandId=cb.brandId','inner') + ->where(['catId'=>$tmpGoodsCatId,'brandName'=>$brand,'dataFlag'=>1])->field('a.brandId')->find(); + if(!empty($brands)){ + $goods['brandId'] = $brands['brandId']; + $goodsCatBrandMap[$brand] = $brands['brandId']; + } + } + } + $goods['goodsDesc'] = trim($sheet->getCell("R".$row)->getValue()); + $goods['isSale'] = 0; + $goods['goodsStatus'] = (WSTConf("CONF.isGoodsVerify")==1)?0:1; + $goods['dataFlag'] = 1; + $goods['saleTime'] = date('Y-m-d H:i:s'); + $goods['createTime'] = date('Y-m-d H:i:s'); + $readData[] = $goods; + $importNum++; + } + if(count($readData)>0){ + $list = model('Goods')->saveAll($readData); + //建立商品评分记录 + $goodsScores = []; + foreach ($list as $key =>$v){ + $gs = []; + $gs['goodsId'] = $v['goodsId']; + $gs['shopId'] = $shopId; + $goodsScores[] = $gs; + } + if(count($goodsScores)>0)Db::name('goods_scores')->insertAll($goodsScores); + } + Db::commit(); + return json_encode(['status'=>1,'importNum'=>$importNum]); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return json_encode(WSTReturn('导入商品失败',-1)); + } + } +} \ No newline at end of file diff --git a/hyhproject/home2/model/Reports.php b/hyhproject/home2/model/Reports.php new file mode 100755 index 0000000..7358597 --- /dev/null +++ b/hyhproject/home2/model/Reports.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 报表模型类 + */ +class Reports{ + /** + * 获取商品销售排行 + */ + public function getTopSaleGoods(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('og.goodsId,g.goodsName,goodsSn,sum(og.goodsNum) goodsNum,g.goodsImg')->name('order_goods')->alias('og') + ->join('__ORDERS__ o','og.orderId=o.orderId') + ->join('__GOODS__ g','og.goodsId=g.goodsId') + ->order('goodsNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where('(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1 and o.shopId='.$shopId)->group('og.goodsId') + ->limit(10)->select(); + return WSTReturn('',1,$rs); + } + /** + * 获取销售额统计 + */ + public function getStatSales(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $payType = (int)input('payType',-1); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('left(createTime,10) createTime,sum(totalMoney) totalMoney,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('shopId',$shopId) + ->where('(payType=0 or (payType=1 and isPay=1)) and dataFlag=1 '.(in_array($payType,[0,1])?" and payType=".$payType:'')) + ->order('createTime asc') + ->group('left(createTime,10)')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + foreach($rs as $key => $v){ + $days[] = $v['createTime']; + $rdata['dayVals'][] = $v['totalMoney']; + $rdata['list'][] = ['day'=>$v['createTime'],'val'=>$v['totalMoney'],'num'=>$v['orderNum']]; + } + $rdata['days'] = $days; + } + return WSTReturn('',1,$rdata); + } + + /** + * 获取商家订单情况 + */ + public function getStatOrders(){ + $start = date('Y-m-d 00:00:00',strtotime(input('startDate'))); + $end = date('Y-m-d 23:59:59',strtotime(input('endDate'))); + $shopId = (int)session('WST_USER.shopId'); + $rs = Db::field('left(createTime,10) createTime,orderStatus,count(orderId) orderNum')->name('orders')->whereTime('createTime','between',[$start,$end]) + ->where('shopId',$shopId) + ->order('createTime asc') + ->group('left(createTime,10),orderStatus')->select(); + $rdata = []; + if(count($rs)>0){ + $days = []; + $tmp = []; + $map = ['-3'=>0,'-1'=>0,'1'=>0]; + foreach($rs as $key => $v){ + if(!in_array($v['createTime'],$days))$days[] = $v['createTime']; + $tmp[$v['orderStatus'].'_'.$v['createTime']] = $v['orderNum']; + } + foreach($days as $v){ + $total = 0; + $ou = 0; + $o_3 = isset($tmp['-3_'.$v])?$tmp['-3_'.$v]:0; + $o_1 = isset($tmp['-1_'.$v])?$tmp['-1_'.$v]:0; + if(isset($tmp['0_'.$v]))$ou += $tmp['0_'.$v]; + if(isset($tmp['1_'.$v]))$ou += $tmp['1_'.$v]; + if(isset($tmp['2_'.$v]))$ou += $tmp['2_'.$v]; + $rdata['-3'][] = $o_3; + $rdata['-1'][] = $o_1; + $rdata['1'][] = $ou; + $map['-3'] += $o_3; + $map['-1'] += $o_1; + $map['1'] += $ou; + $total += $o_3; + $total += $o_1; + $total += $ou; + $rdata['total'][] = $total; + $rdata['list'][] = ['day'=>$v,'o3'=>$o_3,'o1'=>$o_1,'ou'=>$ou]; + } + $rdata['days'] = $days; + $rdata['map'] = $map; + } + return WSTReturn('',1,$rdata); + } +} \ No newline at end of file diff --git a/hyhproject/home2/model/Settlements.php b/hyhproject/home2/model/Settlements.php new file mode 100755 index 0000000..56176f6 --- /dev/null +++ b/hyhproject/home2/model/Settlements.php @@ -0,0 +1,246 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use think\Loader; +/** + * ============================================================================ + * 结算类 + */ +class Settlements extends Base{ + /** + * 获取已结算的结算单列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $where = []; + $where['shopId'] = $shopId; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + return Db::name('settlements')->alias('s')->where($where)->order('settlementId', 'desc') + ->paginate(input('pagesize/d')); + } + /** + * 获取未结算订单列表 + */ + public function pageUnSettledQuery(){ + $where = []; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['settlementId'] = 0; + $where['shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->where($where)->order('orderId', 'desc') + ->field('orderId,orderNo,createTime,payType,goodsMoney,deliverMoney,totalMoney,commissionFee,realTotalMoney') + ->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])){ + foreach ($page['Rows'] as $key => $v) { + $page['Rows'][$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + return $page; + } + /** + * 结算指定的订单 + */ + public function settlement(){ + $shopId = (int)session('WST_USER.shopId'); + $ids = input('ids'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['settlementId'] = 0; + $where['orderId'] = ['in',$ids]; + $where['shopId'] = $shopId; + $orders = Db::name('orders')->where($where)->field('orderId,payType,realTotalMoney,scoreMoney,commissionFee')->select(); + if(empty($orders))return WSTReturn('没有需要结算的订单,请刷新后再核对!'); + $settlementMoney = 0; + $commissionFee = 0; //平台要收的佣金 + $ids = []; + foreach ($orders as $key => $v) { + $ids[] = $v['orderId']; + if($v['payType']==1){ + $settlementMoney += $v['realTotalMoney']+$v['scoreMoney']; + }else{ + $settlementMoney += $v['scoreMoney']; + } + $commissionFee += abs($v['commissionFee']); + } + + $shops = model('shops')->get($shopId); + if(empty($shops))WSTReturn('无效的店铺结算账号!'); + Db::startTrans(); + try{ + $areaNames = model('areas')->getParentNames($shops['bankAreaId']); + $data = []; + $data['settlementType'] = 0; + $data['shopId'] = $shopId; + $data['settlementMoney'] = $settlementMoney; + $data['commissionFee'] = $commissionFee; + $data['backMoney'] = $settlementMoney-$commissionFee; + $data['settlementStatus'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['settlementNo'] = ''; + $result = $this->save($data); + if(false !== $result){ + $this->settlementNo = $this->settlementId.(fmod($this->settlementId,7)); + $this->save(); + Db::name('orders')->where(['orderId'=>['in',$ids]])->update(['settlementId'=>$this->settlementId]); + //修改商家订单情况 + $commissionFee = -1*$commissionFee;//平台要收的佣金就等于商家要付的钱 + $shops->noSettledOrderNum = $shops->noSettledOrderNum-count($orders); + $shops->paymentMoney = $shops->paymentMoney + $commissionFee; + $shops->noSettledOrderFee = $shops->noSettledOrderFee-$commissionFee; + $shops->save(); + Db::commit(); + return WSTReturn('提交结算申请成功,请留意结算信息~',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('提交结算申请失败',-1); + } + + /** + * 获取已结算订单 + */ + public function pageSettledQuery(){ + $where = []; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['o.shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->alias('o') + ->join('__SETTLEMENTS__ s','o.settlementId=s.settlementId') + ->join('__PAYMENTS__ p','o.payFrom=p.payCode')->where($where) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,totalMoney,o.commissionFee,realTotalMoney,s.settlementTime,s.settlementNo,p.payName')->order('s.settlementTime desc')->paginate(input('pagesize/d'))->toArray(); + if(count($page['Rows'])){ + foreach ($page['Rows'] as $key => $v) { + $page['Rows'][$key]['commissionFee'] = abs($v['commissionFee']); + $page['Rows'][$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + return $page; + } + + /** + * 获取结算订单详情 + */ + public function getById(){ + $shopId = (int)session('WST_USER.shopId'); + $settlementId = (int)input('id'); + $object = Db::name('settlements')->alias('st')->where(['settlementId'=>$settlementId,'st.shopId'=>$shopId])->join('__SHOPS__ s','s.shopId=st.shopId','left')->field('s.shopName,st.*')->find(); + if(!empty($object)){ + $object['list'] = Db::name('orders')->where(['settlementId'=>$settlementId]) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,realTotalMoney,totalMoney,scoreMoney,commissionFee,createTime') + ->order('payType desc,orderId desc')->select(); + } + return $object; + } + /** + * 导出订单 + */ + public function toExport(){ + $name='已结算订单表'; + $where = []; + if(input('settlementNo')!='')$where['settlementNo'] = ['like','%'.input('settlementNo').'%']; + if(input('orderNo')!='')$where['orderNo'] = ['like','%'.input('orderNo').'%']; + if((int)input('isFinish')>=0)$where['settlementStatus'] = (int)input('isFinish'); + $where['dataFlag'] = 1; + $where['orderStatus'] = 2; + $where['o.shopId'] = (int)session('WST_USER.shopId'); + $page = Db::name('orders')->alias('o') + ->join('__SETTLEMENTS__ s','o.settlementId=s.settlementId') + ->join('__PAYMENTS__ p','o.payFrom=p.payCode')->where($where) + ->field('orderId,orderNo,payType,goodsMoney,deliverMoney,totalMoney,o.commissionFee,realTotalMoney,s.settlementTime,s.settlementNo,p.payName')->order('s.settlementTime desc')->select(); + if(count($page)){ + foreach ($page as $key => $v) { + $page[$key]['commissionFee'] = abs($v['commissionFee']); + $page[$key]['payTypeNames'] = WSTLangPayType($v['payType']); + } + } + Loader::import('phpexcel.PHPExcel.IOFactory'); + $objPHPExcel = new \PHPExcel(); + // 设置excel文档的属性 + $objPHPExcel->getProperties()->setCreator("WSTMart")//创建人 + ->setLastModifiedBy("WSTMart")//最后修改人 + ->setTitle($name)//标题 + ->setSubject($name)//题目 + ->setDescription($name)//描述 + ->setKeywords("订单")//关键字 + ->setCategory("Test result file");//种类 + + // 开始操作excel表 + $objPHPExcel->setActiveSheetIndex(0); + // 设置工作薄名称 + $objPHPExcel->getActiveSheet()->setTitle(iconv('gbk', 'utf-8', 'Sheet')); + // 设置默认字体和大小 + $objPHPExcel->getDefaultStyle()->getFont()->setName(iconv('gbk', 'utf-8', '')); + $objPHPExcel->getDefaultStyle()->getFont()->setSize(11); + $styleArray = array( + 'font' => array( + 'bold' => true, + 'color'=>array( + 'argb' => 'ffffffff', + ) + ), + 'borders' => array ( + 'outline' => array ( + 'style' => \PHPExcel_Style_Border::BORDER_THIN, //设置border样式 + 'color' => array ('argb' => 'FF000000'), //设置border颜色 + ) + ) + ); + //设置宽 + $objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(25); + $objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('G')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('H')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('I')->setWidth(30); + $objPHPExcel->getActiveSheet()->getColumnDimension('J')->setWidth(30); + $objPHPExcel->getActiveSheet()->getColumnDimension('K')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('L')->setWidth(12); + $objPHPExcel->getActiveSheet()->getColumnDimension('M')->setWidth(20); + $objPHPExcel->getActiveSheet()->getColumnDimension('N')->setWidth(20); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->setFillType(\PHPExcel_Style_Fill::FILL_SOLID); + $objPHPExcel->getActiveSheet()->getStyle('A1:N1')->getFill()->getStartColor()->setARGB('333399'); + + $objPHPExcel->getActiveSheet()->setCellValue('A1', '订单编号')->setCellValue('B1', '支付方式')->setCellValue('C1', '商品总金额')->setCellValue('D1', '运费')->setCellValue('E1', '订单总金额') + ->setCellValue('F1', '实付金额')->setCellValue('G1', '应付佣金')->setCellValue('H1', '结算方式')->setCellValue('I1', '结算单号')->setCellValue('J1', '结算时间'); + $objPHPExcel->getActiveSheet()->getStyle('A1:J1')->applyFromArray($styleArray); + + for ($row = 0; $row < count($page); $row++){ + $i = $row+2; + $objPHPExcel->getActiveSheet() + ->setCellValue('A'.$i, $page[$row]['orderNo']) + ->setCellValue('B'.$i, $page[$row]['payTypeNames']) + ->setCellValue('C'.$i, $page[$row]['goodsMoney']) + ->setCellValue('D'.$i, $page[$row]['deliverMoney']) + ->setCellValue('E'.$i, $page[$row]['totalMoney']) + ->setCellValue('F'.$i, $page[$row]['realTotalMoney']) + ->setCellValue('G'.$i, $page[$row]['commissionFee']) + ->setCellValue('H'.$i, $page[$row]['payName']) + ->setCellValue('I'.$i, $page[$row]['settlementNo']) + ->setCellValue('J'.$i, $page[$row]['settlementTime']); + } + + //输出EXCEL格式 + $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); + // 从浏览器直接输出$filename + header('Content-Type:application/csv;charset=UTF-8'); + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control:must-revalidate, post-check=0, pre-check=0"); + header("Content-Type:application/force-download"); + header("Content-Type:application/vnd.ms-excel;"); + header("Content-Type:application/octet-stream"); + header("Content-Type:application/download"); + header('Content-Disposition: attachment;filename="'.$name.'.xls"'); + header("Content-Transfer-Encoding:binary"); + $objWriter->save('php://output'); + } +} \ No newline at end of file diff --git a/hyhproject/home2/model/ShopConfigs.php b/hyhproject/home2/model/ShopConfigs.php new file mode 100755 index 0000000..2cf174b --- /dev/null +++ b/hyhproject/home2/model/ShopConfigs.php @@ -0,0 +1,62 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 门店配置类 + */ +use think\Db; +class ShopConfigs extends Base{ + /** + * 店铺设置 + */ + public function getShopCfg($id){ + $rs = $this->where("shopId=".$id)->find(); + if($rs != ''){ + //图片 + $rs['shopAds'] = ($rs['shopAds']!='')?explode(',',$rs['shopAds']):null; + //图片的广告地址 + $rs['shopAdsUrl'] = ($rs['shopAdsUrl']!='')?explode(',',$rs['shopAdsUrl']):null; + return $rs; + } + } + + /** + * 修改店铺设置 + */ + public function editShopCfg($shopId){ + $data = input('post.'); + //加载商店信息 + Db::startTrans(); + try{ + $shopcg = $this->where('shopId='.$shopId)->find(); + $scdata = array(); + $scdata["shopKeywords"] = Input("shopKeywords"); + $scdata["shopBanner"] = Input("shopBanner"); + $scdata["shopDesc"] = Input("shopDesc"); + $scdata["shopAds"] = Input("shopAds"); + $scdata["shopAdsUrl"] = Input("shopAdsUrl"); + $scdata["shopHotWords"] = Input("shopHotWords"); + $scdata["shopStreetImg"] = Input("shopStreetImg"); + WSTUseImages(0, $shopcg['configId'], $scdata['shopStreetImg'],'shop_configs','shopStreetImg'); + WSTUseImages(0, $shopcg['configId'], $scdata['shopBanner'],'shop_configs','shopBanner'); + WSTUseImages(0, $shopcg['configId'], $scdata['shopAds'],'shop_configs','shopAds'); + $rs = $this->where("shopId=".$shopId)->update($scdata); + if($rs!==false){ + Db::commit(); + return WSTReturn('操作成功',1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('操作失败',-1); + } + /** + * 获取商城搜索关键字 + */ + public function searchShopkey($shopId){ + $rs = $this->where('shopId='.$shopId)->field('configId,shopHotWords')->find(); + $keys = []; + if($rs['shopHotWords']!='')$keys = explode(',',$rs['shopHotWords']); + return $keys; + } +} diff --git a/hyhproject/home2/model/ShopFreights.php b/hyhproject/home2/model/ShopFreights.php new file mode 100755 index 0000000..a4e0a0d --- /dev/null +++ b/hyhproject/home2/model/ShopFreights.php @@ -0,0 +1,63 @@ +<?php +namespace wstmart\home\model; +use think\Db; +use wstmart\home\model\Shops; +/** + * ============================================================================ + * 运费管理类 + */ +class ShopFreights extends Base{ + /** + * 运费列表 + */ + public function listProvince(){ + $shopId = session('WST_USER.shopId'); + $listCity = Db::name('areas')->where(['isShow'=>1,'dataFlag'=>1,'areaType'=>0])->field('areaId,areaName')->order('areaKey desc')->select(); + for ($i = 0; $i < count($listCity); $i++) { + $parentId = $listCity[$i]["areaId"]; + $listPro = Db::name('areas')->alias('a') + ->join('__SHOP_FREIGHTS__ s','a.areaId= s.areaId2 and s.shopId='.$shopId,'left') + ->where(['a.isShow'=>1,'a.dataFlag'=>1,'a.areaType'=>1,'a.parentId'=>$parentId]) + ->field('a.areaId,a.areaName,a.parentId,s.freightId,s.freight') + ->order('a.areaKey desc') + ->select(); + $listCity[$i]['listProvince'] = $listPro; + } + return $listCity; + } + + /** + * 编辑 + */ + public function edit(){ + $shopId = session('WST_USER.shopId'); + $info = input("post."); + $areas = Db::name('areas')->where('isShow=1 AND dataFlag = 1 AND areaType=1')->field('areaId')->select(); + Db::startTrans(); + if(count($areas)==0)return WSTReturn('无效的城市'); + try{ + $dataList = []; + foreach ($areas as $key => $v) { + $m = model('ShopFreights')->where(['shopId'=>$shopId,'areaId2'=>$v['areaId']])->find(); + $freight = ((int)input('post.'.$v['areaId'])>0)?(int)input('post.'.$v['areaId']):0; + if($m){ + $m->freight = $freight; + $m->save(); + }else{ + $data = []; + $data['shopId'] = $shopId; + $data['areaId2'] = $v['areaId']; + $data['freight'] = $freight; + $data['createTime'] = date('Y-m-d H:i:s'); + $dataList[] = $data; + } + } + if(count($dataList)>0)model('ShopFreights')->saveAll($dataList); + Db::commit(); + return WSTReturn("操作成功", 1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('操作失败',-1); + } + } +} diff --git a/hyhproject/home2/model/ShopRoles.php b/hyhproject/home2/model/ShopRoles.php new file mode 100755 index 0000000..5051c42 --- /dev/null +++ b/hyhproject/home2/model/ShopRoles.php @@ -0,0 +1,153 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 门店色务类 + */ +class ShopRoles extends Base{ + /** + * 角色列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $roleName = input("roleName/s"); + $where = ["shopId"=>$shopId,"dataFlag"=>1]; + if($roleName != ""){ + $where["roleName"] = ["like","%".$roleName."%"]; + } + $page = $this + ->field('id,shopId,roleName,createTime') + ->where($where) + ->paginate(input('pagesize/d'))->toArray(); + return $page; + } + + public function listQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $where = ["shopId"=>$shopId,"dataFlag"=>1]; + $list = $this + ->field('id,shopId,roleName,createTime') + ->where($where) + ->select(); + return $list; + } + /** + * 根据id获取店铺角色 + */ + public function getById($id){ + $shopId = (int)session('WST_USER.shopId'); + $role = $this->field('id,shopId,roleName,createTime,privilegeUrls,privilegeMsgs') + ->where(["id"=>$id,"shopId"=>$shopId,"dataFlag"=>1]) + ->find(); + $menuList = json_decode($role["privilegeUrls"],true); + $menuUrls = array(); + $menuOtherUrls = array(); + foreach ($menuList as $k1 => $menus1) { + foreach ($menus1 as $k2 => $menus2) { + $menuUrls = array_merge($menuUrls,$menus2["urls"]); + $otherUrls = $menus2["otherUrls"]; + foreach ($otherUrls as $ko => $ourls) { + $othurls = explode(',',$ourls); + $menuOtherUrls = array_merge($menuOtherUrls,$othurls); + } + } + } + $role["privilegeMsgs"] = explode(",",$role["privilegeMsgs"]); + $role["menuUrls"] = array_filter($menuUrls); + $role["menuOtherUrls"] = array_filter($menuOtherUrls); + return $role; + } + + /** + * 新增店铺角色 + */ + public function add(){ + $shopId = (int)session('WST_USER.shopId'); + $data["shopId"] = $shopId; + $data["roleName"] = input('roleName/s'); + if($data["roleName"]==""){ + return WSTReturn('请输入角色名称',-1); + } + $data["privilegeMsgs"] = input('privilegeMsgs/s'); + $menuIds = input('menuIds/s'); + $urls = []; + $otherUrls = []; + if($menuIds==""){ + return WSTReturn('请选择权限',-1); + }else{ + $roleMenus = model("HomeMenus")->getRoleMenus(); + $menuIds = explode(",",$menuIds); + $menuList = array(); + for($i=0,$j=count($menuIds);$i<$j;$i++){ + $menu = $roleMenus[$menuIds[$i]]; + $menuList[$menu["grandpaId"]][$menu["parentId"]]["urls"][] = strtolower($menu["menuUrl"]); + $menuList[$menu["grandpaId"]][$menu["parentId"]]["otherUrls"][] = strtolower($menu["menuOtherUrl"]); + } + } + $data["privilegeUrls"] = json_encode($menuList); + $data["createTime"] = date("Y-m-d H:i:s"); + $result = $this->save($data); + if(false !== $result){ + return WSTReturn("新增成功", 1); + } + return WSTReturn('新增失败',-1); + } + + /** + * 修改店铺角色 + */ + public function edit(){ + $shopId = (int)session('WST_USER.shopId'); + $id = (int)input('id'); + $data["roleName"] = input('roleName/s'); + if($data["roleName"]==""){ + return WSTReturn('请输入角色名称',-1); + } + $data["privilegeMsgs"] = input('privilegeMsgs/s'); + $menuIds = input('menuIds/s'); + $urls = []; + $otherUrls = []; + if($menuIds==""){ + return WSTReturn('请选择权限',-1); + }else{ + $roleMenus = model("HomeMenus")->getRoleMenus(); + $menuIds = explode(",",$menuIds); + $menuList = array(); + for($i=0,$j=count($menuIds);$i<$j;$i++){ + $menu = $roleMenus[$menuIds[$i]]; + $menuList[$menu["grandpaId"]][$menu["parentId"]]["urls"][] = strtolower($menu["menuUrl"]); + $menuList[$menu["grandpaId"]][$menu["parentId"]]["otherUrls"][] = strtolower($menu["menuOtherUrl"]); + } + } + $data["privilegeUrls"] = json_encode($menuList); + $result = $this->where(["id"=>$id,"shopId"=>$shopId])->update($data); + if(false !== $result){ + return WSTReturn("修改成功", 1); + } + return WSTReturn('删除失败',-1); + } + + /** + * 删除店铺角色 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $result = $this->where(["id"=>$id,"shopId"=>$shopId])->update($data); + if(false !== $result){ + //删除关联记录 + Db::name("shop_users")->where(["roleId"=>$id,"shopId"=>$shopId])->update($data); + Db::commit(); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } +} diff --git a/hyhproject/home2/model/ShopUsers.php b/hyhproject/home2/model/ShopUsers.php new file mode 100755 index 0000000..2bc6e98 --- /dev/null +++ b/hyhproject/home2/model/ShopUsers.php @@ -0,0 +1,202 @@ +<?php +namespace wstmart\home\model; +use think\Db; +/** + * ============================================================================ + * 门店管理员类 + */ +class ShopUsers extends Base{ + /** + * 角色列表 + */ + public function pageQuery(){ + $shopId = (int)session('WST_USER.shopId'); + $userName = input("userName/s"); + $where = ["s.shopId"=>$shopId,"s.dataFlag"=>1]; + if($userName != ""){ + $where["loginName"] = ["like","%".$userName."%"]; + } + $page = $this->alias('s') + ->join("__SHOP_ROLES__ r","s.roleId=r.id","LEFT") + ->join("__USERS__ u", "u.userId=s.userId and u.dataFlag=1") + ->field('s.id,s.shopId,s.roleId,u.userName,u.loginName,u.createTime,u.userStatus,r.roleName') + ->where($where) + ->paginate(input('pagesize/d'))->toArray(); + return $page; + } + + /** + * 根据id获取店铺用户 + */ + public function getById(){ + $id = (int)input('id'); + $shopId = (int)session('WST_USER.shopId'); + $user = $this->alias('s') + ->join("__SHOP_ROLES__ r","s.roleId=r.id","LEFT") + ->join("__USERS__ u", "u.userId=s.userId and u.dataFlag=1") + ->field('s.id,s.shopId,s.roleId,u.userName,u.loginName,u.createTime,u.userStatus,r.roleName') + ->where(["s.id"=>$id,"s.shopId"=>$shopId,"s.dataFlag"=>1]) + ->find(); + return $user; + } + + + /** + * 新增店铺用户 + */ + public function add(){ + $data = array(); + $roleId = (int)input("roleId"); + $data['loginName'] = input("post.loginName"); + $data['loginPwd'] = input("post.loginPwd"); + $data['reUserPwd'] = input("post.reUserPwd"); + $loginName = $data['loginName']; + if($roleId<=0){ + return WSTReturn('非法操作'); + } + //检测账号是否存在 + $crs = WSTCheckLoginKey($loginName); + if($crs['status']!=1)return $crs; + $decrypt_data = WSTRSA($data['loginPwd']); + $decrypt_data2 = WSTRSA($data['reUserPwd']); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $data['loginPwd'] = $decrypt_data['data']; + $data['reUserPwd'] = $decrypt_data2['data']; + }else{ + return WSTReturn('新增失败'); + } + if($data['loginPwd']!=$data['reUserPwd']){ + return WSTReturn("两次输入密码不一致!"); + } + foreach ($data as $v){ + if($v ==''){ + return WSTReturn("信息不完整!"); + } + } + if($loginName=='')return WSTReturn("新增失败!");//分派不了登录名 + + unset($data['reUserPwd']); + //检测账号,邮箱,手机是否存在 + $data["loginSecret"] = rand(1000,9999); + $data['loginPwd'] = md5($data['loginPwd'].$data['loginSecret']); + $data['userName'] = input("post.userName"); + $data['userQQ'] = ""; + $data['userScore'] = 0; + $data['createTime'] = date('Y-m-d H:i:s'); + $data['dataFlag'] = 1; + $data['userType'] = 1; + Db::startTrans(); + try{ + $userId = Db::name("users")->insertGetId($data); + if(false !== $userId){ + //添加门店用户 + $shopId = (int)session('WST_USER.shopId'); + $data = array(); + $data["shopId"] = $shopId; + $data["userId"] = $userId; + $data["roleId"] = (int)input("roleId"); + Db::name('shop_users')->insert($data); + $user = model("common/Users")->get($userId); + //注册成功后执行钩子 + hook('afterUserRegist',['user'=>$user]); + //发送消息 + $tpl = WSTMsgTemplates('USER_REGISTER'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${MALL_NAME}']; + $replace = [$user['loginName'],WSTConf('CONF.mallName')]; + WSTSendMsg($userId,str_replace($find,$replace,$tpl['tplContent']),['from'=>0,'dataId'=>0]); + } + + Db::commit(); + return WSTReturn("新增成功",1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn("新增失败!"); + } + + /** + * 修改店铺用户 + */ + public function edit(){ + + $shopId = (int)session('WST_USER.shopId'); + Db::startTrans(); + try{ + $data = array(); + $roleId = (int)input("post.roleId"); + $id = (int)input("post.id"); + $newPass = input("post.newPass/s"); + if($newPass!=""){ + $decrypt_data = WSTRSA($newPass); + if($decrypt_data['status']==1){ + $newPass = $decrypt_data['data']; + }else{ + return WSTReturn('修改失败'); + } + if(!$newPass){ + return WSTReturn('密码不能为空',-1); + } + $roleUser = $this->where(["id"=>$id,"shopId"=>$shopId])->find(); + $userId = $roleUser["userId"]; + $rs = model("users")->where(["userId"=>$userId])->find(); + //核对密码 + + $oldPass = input("post.oldPass"); + $decrypt_data2 = WSTRSA($oldPass); + if($decrypt_data2['status']==1){ + $oldPass = $decrypt_data2['data']; + }else{ + return WSTReturn('修改失败'); + } + if($rs['loginPwd']==md5($oldPass.$rs['loginSecret'])){ + + $data["loginPwd"] = md5($newPass.$rs['loginSecret']); + $rs = model("users")->update($data,['userId'=>$userId]); + if(false !== $rs){ + $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update(["roleId"=>$roleId]); + hook("afterEditPass",["userId"=>$userId]); + }else{ + return WSTReturn("修改失败", -1); + } + Db::commit(); + return WSTReturn("修改成功", 1); + + }else{ + return WSTReturn('原始密码错误',-1); + } + }else{ + $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update(["roleId"=>$roleId]); + Db::commit(); + return WSTReturn("修改成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + } + + + + /** + * 删除店铺用户 + */ + public function del(){ + $shopId = (int)session('WST_USER.shopId'); + $id = input('post.id/d'); + $data = []; + $data['dataFlag'] = -1; + Db::startTrans(); + try{ + $role = $this->where(["id"=>$id,"shopId"=>$shopId])->field("userId,id")->find(); + $result = $this->where(["id"=>$id,"shopId"=>$shopId,"roleId"=>[">",0]])->update($data); + if(false !== $result){ + Db::name("users")->where(["userId"=>$role["userId"]])->update(["userType"=>0]); + return WSTReturn("删除成功", 1); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + } + return WSTReturn('删除失败',-1); + } +} diff --git a/hyhproject/home2/model/Shops.php b/hyhproject/home2/model/Shops.php new file mode 100755 index 0000000..8b4eeff --- /dev/null +++ b/hyhproject/home2/model/Shops.php @@ -0,0 +1,561 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Shops as CShops; +use wstmart\home\validate\Shops as VShop; +use think\Db; +use think\Loader; +use think\Validate; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends CShops{ + /** + * 获取店铺的默认运费 + */ + public function getShopsFreight($shopId){ + return $this->where(["dataFlag"=>1,"shopId"=>$shopId])->field('freight')->find(); + } + /** + * 获取店铺公告 + */ + public function getNotice(){ + $shopId = (int)session('WST_USER.shopId'); + return model('shops')->where(['shopId'=>$shopId])->value('shopNotice'); + } + /** + * 修改店铺公告 + */ + public function editNotice(){ + $shopId = (int)session('WST_USER.shopId'); + $shopNotice = input('shopNotice'); + if(strlen($shopNotice)>450){ + return WSTReturn('店铺公告不能超过150字'); + } + $rs = $this->where("shopId=$shopId")->setField('shopNotice',$shopNotice); + if($rs!==false)return WSTReturn('设置成功',1); + return WSTReturn('设置失败',-1); + } + + /** + * 店铺街列表 + */ + public function pageQuery($pagesize){ + $catId = input("get.id/d"); + $keyword = input("keyword"); + $userId = (int)session('WST_USER.userId'); + $rs = $this->alias('s'); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.applyStatus'] = 2; + if($keyword!='')$where['s.shopName'] = ['like','%'.$keyword.'%']; + if($catId>0){ + $rs->join('__CAT_SHOPS__ cs','cs.shopId = s.shopId','left'); + $where['cs.catId'] = $catId; + } + $page = $rs->join('__SHOP_SCORES__ ss','ss.shopId = s.shopId','left') + ->join('__USERS__ u','u.userId = s.userId','left') + ->join('__FAVORITES__ f','f.userId = '.$userId.' and f.favoriteType=1 and f.targetId=s.shopId','left') + ->where($where) + ->order('s.shopId asc') + ->field('s.shopId,s.shopImg,s.shopName,s.shopTel,s.shopQQ,s.shopWangWang,s.shopWangWangType,s.shopCompany,ss.totalScore,ss.totalUsers,ss.goodsScore,ss.goodsUsers,ss.serviceScore,ss.serviceUsers,ss.timeScore,ss.timeUsers,.u.loginName,f.favoriteId,s.areaIdPath') + ->paginate($pagesize)->toArray(); + if(empty($page['Rows']))return $page; + $shopIds = []; + $areaIds = []; + foreach ($page['Rows'] as $key =>$v){ + $shopIds[] = $v['shopId']; + $tmp = explode('_',$v['areaIdPath']); + $areaIds[] = $tmp[1]; + $page['Rows'][$key]['areaId'] = $tmp[1]; + //总评分 + $page['Rows'][$key]['totalScore'] = WSTScore($v["totalScore"], $v["totalUsers"]); + $page['Rows'][$key]['goodsScore'] = WSTScore($v['goodsScore'],$v['goodsUsers']); + $page['Rows'][$key]['serviceScore'] = WSTScore($v['serviceScore'],$v['serviceUsers']); + $page['Rows'][$key]['timeScore'] = WSTScore($v['timeScore'],$v['timeUsers']); + //商品列表 + $goods = Db::name('goods')->alias('g')->join('store_recom sr','sr.goodsId=g.goodsId','left') + ->where(['dataFlag'=> 1,'goodsStatus'=>1,'isSale'=>1,'sr.storeStatus'=>1,'shopId'=> $v["shopId"]])->field('g.goodsId,goodsName,shopPrice,goodsImg')->limit(10)->order('saleTime desc')->select(); + if(count($goods)<=3){ + $goods = Db::name('goods')->alias('g') + ->where(['dataFlag'=> 1,'goodsStatus'=>1,'isSale'=>1,'shopId'=> $v["shopId"]])->field('g.goodsId,goodsName,shopPrice,goodsImg')->limit(10)->order('saleTime desc')->select(); + } + $page['Rows'][$key]['goods'] = $goods; + //店铺商品总数 + $page['Rows'][$key]['goodsTotal'] = count($goods); + } + $rccredMap = []; + $goodsCatMap = []; + $areaMap = []; + //认证、地址、分类 + if(!empty($shopIds)){ + $rccreds = Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','a.accredId=sac.accredId and a.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('sac.shopId,accredName,accredImg')->select(); + foreach ($rccreds as $v){ + $rccredMap[$v['shopId']][] = $v; + } + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[$v['shopId']][] = $v['catName']; + } + $areas = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$areaIds)->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->select(); + foreach ($areas as $v){ + $areaMap[$v['areaId']] = $v; + } + } + foreach ($page['Rows'] as $key =>$v){ + $page['Rows'][$key]['accreds'] = (isset($rccredMap[$v['shopId']]))?$rccredMap[$v['shopId']]:[]; + $page['Rows'][$key]['catshops'] = (isset($goodsCatMap[$v['shopId']]))?implode(',',$goodsCatMap[$v['shopId']]):''; + $page['Rows'][$key]['areas']['areaName1'] = (isset($areaMap[$v['areaId']]['areaName1']))?$areaMap[$v['areaId']]['areaName1']:''; + $page['Rows'][$key]['areas']['areaName2'] = (isset($areaMap[$v['areaId']]['areaName2']))?$areaMap[$v['areaId']]['areaName2']:''; + } + return $page; + } + /** + * 获取卖家中心信息 + */ + public function getShopSummary($shopId){ + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'dataFlag'=>1]) + ->field('s.shopMoney,s.noSettledOrderFee,s.paymentMoney,s.shopId,shopImg,shopName,shopAddress,shopQQ,shopWangWang,shopTel,serviceStartTime,serviceEndTime,cs.*') + ->find(); + //评分 + $scores['totalScore'] = WSTScore($shop['totalScore'],$shop['totalUsers']); + $scores['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $scores['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $scores['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + $shop['scores'] = $scores; + //认证 + $accreds = $this->shopAccreds($shopId); + $shop['accreds'] = $accreds; + //商家访问量 + $shop['view']=db('shop_view')->where('shopId',$shopId)->field('count(shopId)view,path')->group('path')->select(); + //查看商家钱包是否足够钱 + $USER = session('WST_USER'); + $USER['shopMoney'] = $shop['shopMoney']; + $USER['noSettledOrderFee'] = $shop['noSettledOrderFee']; + $USER['paymentMoney'] = $shop['paymentMoney']; + session('WST_USER',$USER); + $stat = array(); + $date = date("Y-m-d"); + $userId = session('WST_USER.userId'); + /**********今日动态**********/ + //待查看消息数 + $stat['messageCnt'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + //今日销售金额 + $stat['saleMoney'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['egt',0],'dataFlag'=>1])->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->sum("goodsMoney"); + //今日订单数 + $stat['orderCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['egt',0],'dataFlag'=>1])->whereTime('createTime', 'between', [$date.' 00:00:00', $date.' 23:59:59'])->count(); + //待发货订单 + $stat['waitDeliveryCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>0,'dataFlag'=>1])->count(); + //待收货订单 + $stat['waitReceiveCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>1,'dataFlag'=>1])->count(); + //取消/拒收 + $stat['cancel'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>['in',[-1,-3]],'dataFlag'=>1])->count(); + //库存预警 + $goodsn = Db::name('goods')->where('shopId ='.$shopId.' and dataFlag = 1 and goodsStock <= warnStock and isSpec = 0 and warnStock>0')->cache('stockWarnCnt1'.$shopId,3600)->count(); + $specsn = Db::name('goods_specs')->where('shopId ='.$shopId.' and dataFlag = 1 and specStock <= warnStock and warnStock>0')->cache('stockWarnCnt2'.$shopId,3600)->count(); + $stat['stockWarnCnt'] = $goodsn+$specsn; + + /**********商品信息**********/ + //商品总数 + $stat['goodsCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1])->cache('goodsCnt'.$shopId,3600)->count(); + //上架商品 + $stat['onSaleCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1])->cache('onSaleCnt'.$shopId,3600)->count(); + //待审核商品 + $stat['waitAuditCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>0])->cache('waitAuditCnt'.$shopId,3600)->count(); + //仓库中的商品 + $stat['unSaleCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>0])->cache('unSaleCnt'.$shopId,3600)->count(); + //违规商品 + $stat['illegalCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>-1])->cache('illegalCnt'.$shopId,3600)->count(); + //今日新品 + $stat['newGoodsCnt'] = Db::name('goods')->where(['shopId'=>$shopId,'dataFlag'=>1,'goodsStatus'=>1,'isSale'=>1,'isNew'=>1])->cache('newGoodsCnt'.$shopId,3600)->count(); + + /**********订单信息**********/ + //待付款订单 + $stat['orderNeedpayCnt'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + //待结束订单 + $stat['orderWaitCloseCnt'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'dataFlag'=>1,'isClosed'=>0])->cache('orderWaitCloseCnt'.$shopId,3600)->count(); + //退货退款订单 + $stat['orderRefundCnt'] = Db::name('orders')->alias('o')->join('order_refunds orf','orf.orderId=o.orderId')->where(['shopId'=>$shopId,'refundStatus'=>0,'o.dataFlag'=>1])->count(); + //待评价订单 + $stat['orderWaitAppraisesCnt'] = Db::name('orders')->where(['shopId'=>$shopId,'orderStatus'=>2,'dataFlag'=>1,'isAppraise'=>0])->cache('orderWaitAppraisesCnt'.$shopId,3600)->count(); + // 投诉订单数 + $stat['complainNum'] = Db::name('order_complains')->where(['respondTargetId'=>$shopId,'complainStatus'=>1])->count(); + // 近七天销售排行 + $start = date('Y-m-d H:i:s',strtotime("-7 day")); + $end = date('Y-m-d H:i:s'); + $stat['goodsTop'] = $rs = Db::field('og.goodsId,g.goodsName,goodsSn,sum(og.goodsNum) goodsNum,g.goodsImg') + ->name('order_goods') + ->alias('og') + ->join('__ORDERS__ o','og.orderId=o.orderId') + ->join('__GOODS__ g','og.goodsId=g.goodsId') + ->order('goodsNum desc') + ->whereTime('o.createTime','between',[$start,$end]) + ->where('(payType=0 or (payType=1 and isPay=1)) and o.dataFlag=1 and o.shopId='.$shopId)->group('og.goodsId') + ->limit(10)->select(); + return ['shop'=>$shop,'stat'=>$stat]; + } + /** + * 获取店铺信息 + */ + public function getByView($id){ + $shop = $this->alias('s')->join('__BANKS__ b','b.bankId=s.bankId','left') + ->where(['s.dataFlag'=>1,'shopId'=>$id]) + ->field('s.*,b.bankName')->find(); + $areaIds = []; + $areaMaps = []; + $tmp = explode('_',$shop['areaIdPath']); + foreach ($tmp as $vv){ + if($vv=='')continue; + if(!in_array($vv,$areaIds))$areaIds[] = $vv; + } + if(!empty($areaIds)){ + $areas = Db::name('areas')->where(['dataFlag'=>1,'areaId'=>['in',$areaIds]])->field('areaId,areaName')->select(); + foreach ($areas as $v){ + $areaMaps[$v['areaId']] = $v['areaName']; + } + $tmp = explode('_',$shop['areaIdPath']); + $areaNames = []; + foreach ($tmp as $vv){ + if($vv=='')continue; + $areaNames[] = @$areaMaps[$vv]; + $shop['areaName'] = implode('',$areaNames); + } + } + + //获取经营范围 + $goodsCats = Db::name('goods_cats')->where(['parentId'=>0,'isShow'=>1,'dataFlag'=>1])->field('catId,catName')->select(); + $catshops = Db::name('cat_shops')->where('shopId',$id)->select(); + $catshopMaps = []; + foreach ($goodsCats as $v){ + $catshopMaps[$v['catId']] = $v['catName']; + } + $catshopNames = []; + foreach ($catshops as $key =>$v){ + if(isset($catshopMaps[$v['catId']]))$catshopNames[] = $catshopMaps[$v['catId']]; + } + $shop['catshopNames'] = implode('、',$catshopNames); + //获取认证类型 + $shop['accreds'] =Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','sac.accredId=a.accredId and a.dataFlag=1','inner') + ->where('sac.shopId',$id)->field('accredName,accredImg')->select(); + //开卡地址 + $areaNames = model('areas')->getParentNames($shop['bankAreaId']); + $shop['bankAreaName'] = implode('',$areaNames); + return $shop; + } + /** + * 获取店铺指定字段 + */ + public function getFieldsById($shopId,$fields){ + return $this->where(['shopId'=>$shopId,'dataFlag'=>1])->field($fields)->find(); + } + + /** + * 编辑店铺资料mark huang 20180312 限制银行卡信息只能修改一次 + */ + public function editInfo(){ +//添加旺旺类型mark by cheng 20180314 + $shopId = (int)session('WST_USER.shopId'); + $shop_data['shopImg'] = input('post.shopImg'); + $shop_data['isInvoice'] = input('post.isInvoice'); + $shop_data['invoiceRemarks'] = input('post.invoiceRemarks'); + $shop_data['serviceStartTime'] = input('post.serviceStartTime'); + $shop_data['serviceEndTime'] = input('post.serviceEndTime'); + $shop_data['freight'] = input('post.freight'); + $shop_data['shopQQ'] = input('post.shopQQ'); + $shop_data['shopWangWang'] = input('post.shopWangWang'); + $shop_data['shopWangWangType'] = input('post.shopWangWangType'); + $result = $this->validate('Shops.editInfo')->allowField(['shopImg','isInvoice','invoiceRemarks','serviceStartTime','serviceEndTime','freight','shopQQ','shopWangWang','shopWangWangType'])->save($shop_data,['shopId'=>$shopId]); + $bank_info = Db::name('shops')->where('shopId',$shopId)->field('bankNo,changeNum')->find(); + $bank_data['bankNo'] = input('post.bankNo'); + $result2 = true; + if($bank_info['changeNum'] == 0 && $bank_data['bankNo'] != $bank_info['bankNo']){ + $bank_data['bankUserName'] = input('post.bankUserName'); + $bank_data['bankId'] = input('post.bankId'); + $bank_data['changeNum'] = $bank_info['changeNum'] + 1; + $result2 = $this->allowField(['bankNo','bankUserName','shopId','bankId','changeNum'])->save($bank_data,['shopId'=>$shopId]); + }elseif($bank_info['changeNum'] > 0){ + if($bank_data['bankNo'] != $bank_info['bankNo'] ){ + $result2 = false; + }else{ + $result2 = true; + } + } + if(false !== $result){ + if(false == $result2){ + $msg='银行卡修改失败!'; + }else{ + $msg='!'; + } + return WSTReturn('店铺相关信息保存成功'.$msg,1); + }else{ + return WSTReturn($this->getError()); + } + } + + + /** + * 获取店铺提现账号 + */ + public function getShopAccount(){ + $shopId = (int)session('WST_USER.shopId'); + $shops = Db::name('shops')->alias('s')->join('banks b','b.bankId=s.bankId','inner')->where('s.shopId',$shopId)->field('b.bankName,s.bankAreaId,bankNo,bankUserName')->find(); + return $shops; + } + /** + * 保存入驻资料 + */ + public function saveStep2($data = []){ + $userId = (int)session('WST_USER.userId'); + //判断是否存在入驻申请 + $shops = $this->where('userId',$userId)->find(); + //新增入驻申请 + Db::startTrans(); + try{ + if(empty($shops)){ + $vshop = new VShop(); + $shop = ['userId'=>$userId,'applyStatus'=>0,'applyStep'=>2]; + $this->save($shop); + WSTAllow($data,implode(',',$vshop->scene['applyStep1'])); + $data['shopId'] = $this->shopId; + $result = Db::name('shop_extras')->insert($data); + $shopId = $this->shopId; + $WST_USER = session('WST_USER'); + $WST_USER['tempShopId'] = $shopId; + session('WST_USER',$WST_USER); + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + if($shops->applyStep<2){ + $shops->applyStep = 2; + $shops->save(); + } + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep1'])); + $result = Db::name('shop_extras')->where('shopId',$shops['shopId'])->update($data); + if(false !== $result){ + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + return WSTReturn('保存失败'); + } + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('保存失败',-1); + } + } + public function saveStep3($data = []){ + /* + legalCertificateImg + businessLicenceImg + bankAccountPermitImg + organizationCodeImg + */ + $auxiliary=explode(',',$data['shopAds']); + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep2'])); + //获取地区 + $areaIds = model('Areas')->getParentIs($data['businessAreaPath0']); + if(!empty($areaIds))$data['businessAreaPath'] = implode('_',$areaIds)."_"; + $areaIds = model('Areas')->getParentIs($data['areaIdPath0']); + if(!empty($areaIds))$data['areaIdPath'] = implode('_',$areaIds)."_"; + //if($data['isLongbusinessDate']==1)unset($data['businessEndDate']); + //if($data['isLonglegalCertificateDate']==1)unset($data['legalCertificateEndDate']); + //if($data['isLongOrganizationCodeDate']==1)unset($data['organizationCodeEndDate']); + Db::startTrans(); + try{ + if($shops->applyStep<3){ + $shops->applyStep = 3; + $shops->save(); + } + $validate = Loader::validate('Shops'); + if(!$validate->scene('applyStep2')->check($data))return WSTReturn($validate->getError()); + $seModel = model('ShopExtras'); + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + $Id = $seModel->where(['shopId'=>$shopId])->value('id');// 获取主键 + //启用上传图片 + WSTUseImages(0, $Id, $data['legalCertificateImg'],'shopextras'); + WSTUseImages(0, $Id, $data['businessLicenceImg'],'shopextras'); + WSTUseImages(0, $Id, $data['bankAccountPermitImg'],'shopextras'); + WSTUseImages(0, $Id, $data['organizationCodeImg'],'shopextras'); + $auxiliary_data=[]; + $shopAuxiliary = Db::name('shop_auxiliary')->where('shopId='.$shopId)->find(); + WSTUseImages(0, $shopAuxiliary['id'], $auxiliary,'shopauxiliary'); + Db::name('shop_auxiliary')->where('shopId='.$shopId)->delete(); + foreach($auxiliary as $k=>$v){ + $auxiliary_data[$k]['shopId']=$shopId; + $auxiliary_data[$k]['auxiliaryImg']=$v; + } + Db::name('shop_auxiliary')->insertAll($auxiliary_data); + $this->allowField(true)->save($data,['shopId'=>$shopId]); + Db::commit(); + return WSTReturn('保存成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('保存失败',-1); + } + } + public function saveStep4($data = []){ + /* + taxRegistrationCertificateImg + taxpayerQualificationImg + */ + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + WSTAllow($data,implode(',',$vshop->scene['applyStep3'])); + $areaIds = model('Areas')->getParentIs($data['bankAreaId']); + if(!empty($areaIds))$data['bankAreaIdPath'] = implode('_',$areaIds)."_"; + Db::startTrans(); + try{ + if($shops->applyStep<4){ + $shops->applyStep = 4; + $shops->save(); + } + $seModel = model('ShopExtras'); + $seModel->allowField(true)->save($data,['shopId'=>$shopId]); + /*--------取消上传图片选项 mark hsf 20180104----------*/ + //$Id = $seModel->where(['shopId'=>$shopId])->value('id'); + //启用上传图片 + //WSTUseImages(0, $Id, $data['taxRegistrationCertificateImg'],'shopextras'); + // WSTUseImages(0, $Id, $data['taxpayerQualificationImg'],'shopextras'); + /*-------------------------end---------------------------*/ + $this->allowField(true)->save($data,['shopId'=>$shopId]); + Db::commit(); + return WSTReturn('保存成功',1); + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('保存失败',-1); + } + } + public function saveStep5($data = []){ + $shopId = (int)session('WST_USER.tempShopId'); + if($shopId==0)return WSTReturn('非法的操作'); + $shops = model('shops')->get($shopId); + if($shops['applyStatus']>=1)return WSTReturn('请勿重复申请入驻'); + //判断是否存在入驻申请 + $vshop = new VShop(); + $filters = $vshop->scene['applyStep4']; + $filters[] = 'shopQQ'; + $filters[] = 'shopWangWang'; + WSTAllow($data,implode(',',$filters)); + $shopLicense=input('shopLicense'); + if((strpos($data['goodsCatIds'],'393')!==false)||$data['goodsCatIds']=='393'){ + if($shopLicense==""){ + + return WSTReturn('食品许可证不能为空'); + } + }else{ + $shopLicense=''; + } + Db::startTrans(); + try{ + $data['applyStatus'] = 1; + $data['applyTime'] = date('Y-m-d H:i:s'); + $find=$this->where('shopName',$data['shopName'])->find(); + if($find) return WSTReturn('此商铺名称已存在,请重新填写'); + $result = $this->allowField(true)->save($data,['shopId'=>$shopId]); + $row=db('shop_license')->insert(['shopId'=>$shopId,'shopLicense'=>$shopLicense]); + // // // 启用图片 + WSTUseImages(0, $shopId, $data['shopImg'],'shops','shopImg'); + //WSTUseImages(0, $shopId, $shopLicense,'shoplicense','shopLicense'); + + if($shops->applyStep<5){ + $shops->applyStep = 5; + $shops->save(); + } + if(false !== $result){ + //经营范围 + $goodsCats = explode(',',$data['goodsCatIds']); + foreach ($goodsCats as $v){ + if((int)$v>0)Db::name('cat_shops')->insert(['shopId'=>$shopId,'catId'=>$v]); + } + Db::commit(); + return WSTReturn('保存成功',1); + }else{ + return WSTReturn('保存失败'); + } + }catch (\Exception $e) { + Db::rollback();errLog($e); + return WSTReturn('保存失败',-1); + } + } + + /** + * 获取商家入驻资料 + */ + public function getShopApply(){ + $userId = (int)session('WST_USER.userId'); + $rs = $this->alias('s') + ->join('__SHOP_EXTRAS__ ss','s.shopId=ss.shopId','inner') + ->where('s.userId',$userId) + ->find(); + if(!empty($rs)){ + $rs = $rs->toArray(); + $goodscats = Db::name('cat_shops')->where('shopId',$rs['shopId'])->select(); + $rs['catshops'] = []; + foreach ($goodscats as $v){ + $rs['catshops'][$v['catId']] = true; + } + $rs['taxRegistrationCertificateImgVO'] = ($rs['taxRegistrationCertificateImg']!='')?explode(',',$rs['taxRegistrationCertificateImg']):[]; + + }else{ + $rs = []; + $data1 = $this->getEModel('shops'); + $data2 = $this->getEModel('shop_extras'); + $rs = array_merge($data1,$data2); + $rs['taxRegistrationCertificateImgVO'] = []; + } + $rs['auxiliary']=db('shop_auxiliary')->where('shopId',$rs['shopId'])->select(); + return $rs; + } + + /** + * 判断是否申请入驻过 + */ + public function checkApply(){ + $userId = (int)session('WST_USER.userId'); + $rs = $this->where(['userId'=>$userId])->find(); + if(!empty($rs)){ + $WST_USER = session('WST_USER'); + $WST_USER['tempShopId'] = $rs->shopId; + session('WST_USER',$WST_USER); + session('apply_step',$rs['applyStep']); + } + return $rs; + } + /** + * 首页店铺街列表 + */ + public function indexShopQuery($num=4){ + /** 添加返回店铺街商店 mark hsf 20180223 */ + $shop_list = model('common/Tags')->listShop(0,$num,0); + foreach ($shop_list as &$v) { + $v['shopAddress'] = Db::name('shops')->where(['shopId'=>$v['shopId']])->value('shopAddress'); + $v['shopStreetImg'] = Db::name('shop_configs')->where(['shopId'=>$v['shopId']])->value('shopStreetImg'); + } + return $shop_list; + /** end */ + $rs = $this->alias('s') + ->join('__SHOP_CONFIGS__ sc','s.shopId=sc.shopId','inner') + ->field('s.shopId,s.shopName,s.shopAddress,sc.shopStreetImg') + ->limit($num) + ->select(); + return $rs; + } +} diff --git a/hyhproject/home2/model/SpecItems.php b/hyhproject/home2/model/SpecItems.php new file mode 100755 index 0000000..dd97ae1 --- /dev/null +++ b/hyhproject/home2/model/SpecItems.php @@ -0,0 +1,10 @@ +<?php +namespace wstmart\home\model; +/** + * ============================================================================ + * 商品规格值类 + */ +use think\Db; +class SpecItems extends Base{ + +} diff --git a/hyhproject/home2/model/Users.php b/hyhproject/home2/model/Users.php new file mode 100755 index 0000000..b2d189a --- /dev/null +++ b/hyhproject/home2/model/Users.php @@ -0,0 +1,33 @@ +<?php +namespace wstmart\home\model; +use wstmart\common\model\Users as CUsers; +/** + * ============================================================================ + * 用户类 + */ +use think\Db; +class Users extends CUsers{ + /** + * 获取各订单状态数、未读消息数、账户安全等级 + */ + function getStatusNum(){ + $userId = (int)session('WST_USER.userId'); + $data = []; + // 用户消息 + $data['message'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + //获取用户订单状态 + $data['waitPay'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['waitReceive'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>['in',[0,1]],'dataFlag'=>1])->count(); + $data['received'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'dataFlag'=>1])->count(); + $data['waitAppr'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + // 账户安全等级 + $level = 1; + $users = $this->field('userPhone,userEmail')->find($userId); + if(!empty($users['userPhone']))++$level; + if(!empty($users['userEmail']))++$level; + $data['level'] = $level; + //关注商品 + $data['gfavorite'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>0])->count(); + return $data; + } +} diff --git a/hyhproject/home2/validate/Goods.php b/hyhproject/home2/validate/Goods.php new file mode 100755 index 0000000..f3ef43f --- /dev/null +++ b/hyhproject/home2/validate/Goods.php @@ -0,0 +1,97 @@ +<?php +namespace wstmart\home\validate; +use think\Validate; +/** + * ============================================================================ + * 商品验证器 + */ +class Goods extends Validate{ + protected $rule = [ + ['goodsName' ,'require|max:300','请输入商品名称|商品名称不能超过100个字符'], + ['goodsImg' ,'require','请上传商品图片'], + ['goodsType' ,'in:,0,1','无效的商品类型'], + ['goodsSn' ,'checkGoodsSn:1','请输入商品编号'], + ['productNo' ,'checkProductNo:1','请输入商品货号'], + ['marketPrice' ,'checkMarketPrice:1','请输入市场价格'], + ['shopPrice' ,'checkShopPrice:1','请输入店铺价格'], + ['goodsUnit' ,'require','请输入商品单位'], + ['isSale' ,'in:,0,1','无效的上架状态'], + ['isRecom' ,'in:,0,1','无效的推荐状态'], + ['isBest' ,'in:,0,1','无效的精品状态'], + ['isNew' ,'in:,0,1','无效的新品状态'], + ['isHot' ,'in:,0,1','无效的热销状态'], + ['isFreeShipping','in:,0,1','无效的包邮状态'], + ['goodsCatId' ,'require','请选择完整商品分类'], + ['goodsDesc','require','请输入商品描述'], + ['specsIds','checkSpecsIds:1','请填写完整商品规格信息'] + ]; + /** + * 检测商品编号 + */ + protected function checkGoodsSn($value){ + $goodsId = Input('post.goodsId/d',0); + $key = Input('post.goodsSn'); + if($key=='')return '请输入商品编号'; + $isChk = model('Goods')->checkExistGoodsKey('goodsSn',$key,$goodsId); + if($isChk)return '对不起,该商品编号已存在'; + return true; + } + /** + * 检测商品货号 + */ + protected function checkProductNo($value){ + $goodsId = Input('post.goodsId/d',0); + $key = Input('post.productNo'); + if($key=='')return '请输入商品货号'; + $isChk = model('Goods')->checkExistGoodsKey('productNo',$key,$goodsId); + if($isChk)return '对不起,该商品货号已存在'; + return true; + } + /** + * 检测价格 + */ + public function checkMarketPrice(){ + $marketPrice = floatval(input('post.marketPrice')); + if($marketPrice<0.01)return '市场价格不能小于0.01'; + return true; + } + public function checkShopPrice(){ + $shopPrice = floatval(input('post.shopPrice')); + if($shopPrice<0.01)return '店铺价格不能小于0.01'; + return true; + } + /** + * 检测商品规格是否填写完整 + */ + public function checkSpecsIds(){ + $specsIds = input('post.specsIds'); + if($specsIds!=''){ + $str = explode(',',$specsIds); + $specsIds = []; + foreach ($str as $v){ + $vs = explode('-',$v); + foreach ($vs as $vv){ + if(!in_array($vv,$specsIds))$specsIds[] = $vv; + } + } + //检测规格名称是否填写完整 + foreach ($specsIds as $v){ + if(input('post.specName_'.$v)=='')return '请填写完整商品规格值'; + } + //检测销售规格是否完整 + foreach ($str as $v){ + if(input('post.productNo_'.$v)=='')return '请填写完整商品销售规格-货号'; + if(input('post.marketPrice_'.$v)=='')return '请填写完整商品销售规格-市场价'; + if(floatval(input('post.marketPrice_'.$v))<0.01)return '商品销售规格-市场价不能小于0.01'; + if(input('post.specPrice_'.$v)=='')return '请填写完整商品销售规格-本店价'; + if(floatval(input('post.specPrice_'.$v))<0.01)return '商品销售规格-本店价不能小于0.01'; + if(input('post.specStock_'.$v)=='')return '请填写完整商品销售规格-库存'; + if(intval(input('post.specStock_'.$v))<0)return '商品销售规格-库存不能小于0'; + if(input('post.warnStock_'.$v)=='')return '请填写完整商品销售规格-预警库存'; + if(intval(input('post.warnStock_'.$v))<0)return '商品销售规格-预警库存不能小于0'; + } + if(input('post.defaultSpec')=='')return '请选择推荐规格'; + } + return true; + } +} \ No newline at end of file diff --git a/hyhproject/home2/validate/Shops.php b/hyhproject/home2/validate/Shops.php new file mode 100755 index 0000000..7bc9483 --- /dev/null +++ b/hyhproject/home2/validate/Shops.php @@ -0,0 +1,118 @@ +<?php +namespace wstmart\home\validate; +use think\Validate; +/** + * ============================================================================ + * 店铺验证器 + */ +class Shops extends Validate{ + protected $rule = [ + //入驻步骤1 + ['applyLinkMan','require','请输入联系人姓名'], + ['applyLinkTel','require','请输入联系人手机'], + // ['applyLinkEmail','require','请输入联系人邮箱'], + ['isInvestment','in:0,1','无效的对接商城招商人参数'], + ['investmentStaff','checkInvestment:1','请输入商城招商人员姓名'], + //入驻步骤2 + ['businessLicenceType','require','请选择执照类型'], + ['businessLicence','require','请输入营业执照注册号'], + ['legalPersonName','require','请输入法定代表人姓名'], + //['businessAreaPath0','require','请选择营业执照所在地'], + //['licenseAddress','require','请输入营业执照详细地址'], + //['establishmentDate','require','请选择成立日期'], + //['businessStartDate','require','请输入营业期限开始日期'], + //['businessEndDate','checkBusinessEndDate:1','请输入营业期限结束日期'], + //['isLongbusinessDate','in:0,1','无效的营业期限参数'], + //['registeredCapital','require','请输入注册资本'], + //['empiricalRange','require','请输入经营范围'], + ['areaIdPath0','require','请选择公司所在地'], + ['shopCompany','require','请输入公司名称'], + ['shopAddress','require','请输入公司详细地址'], + ['shopTel','require','请输入公司电话'], + // mark by cheng 添加开店必须输入旺旺和qq20130318 + //['shopWangWang','require','请输入店铺客服旺旺'], + //['shopQQ','require','请输入店铺客服QQ'], + ['shopkeeper','require','请输入公司紧急联系人'], + ['telephone','require','请输入公司紧急联系人电话'], + ['legalCertificateType','require','请选择法人代表证件类型'], + ['legalCertificate','require','请输入法定代表人证件号'], + //['legalCertificateStartDate','require','请选择法定代表人证件有效期开始日期'], + //['legalCertificateEndDate','checkLegalCertificateEndDate:1','请选择法定代表人证件有效期结束日期'], + //['isLonglegalCertificateDate','in:0,1','无效的代表人证件有效期参数'], + ['legalCertificateImg','require','请上传法人证件电子版'], + ['businessLicenceImg','require','请上传营业执照电子版'], + ['bankAccountPermitImg','require','请上传银行开户许可证电子版'], + // ['organizationCode','require','请输入组织机构代码'], + // ['organizationCodeStartDate','require','请输入商标注册证有效期开始日期'], + // ['organizationCodeEndDate','checkOrganizationCodeEndDate:1','请输入商标注册证有效期结束日期'], + // ['isLongOrganizationCodeDate','in:0,1','无效的商标注册证有效期参数'], + ['organizationCodeImg','require','请上传商标注册证电子版'], + //入驻步骤3 + /*--------取消上传图片选项 mark hsf 20180104----------*/ + //['taxpayerType','require','请选择纳税人类型'], + //['taxpayerNo','require','请输入纳税人识别号'], + //['taxRegistrationCertificateImg','require','请上传税务登记证电子版'], + //['taxpayerQualificationImg','require','请上传一般纳税人资格证电子版'], + /*-------------------------end-------------------------*/ + ['bankUserName' ,'require|max:100','请输入持卡人名称|持卡人名称长度不能能超过50个字符'], + ['bankNo' ,'require','请选择银行账号'], + ['bankId' ,'require','请选择结算银行'], + //['bankAreaId' ,'require','请选择开户所地区'], + //入驻步骤4 + ['shopName' ,'require','请输入店铺名称'], + ['shopImg' ,'require','请上传店铺图标'], + ['goodsCatIds' ,'require','请选择经营类目'], + ['isInvoice' ,'in:0,1','无效的发票类型'], + ['invoiceRemarks','checkInvoiceRemark:1','请输入发票说明'], + ['freight','integer','请输入运费'], + ['serviceStartTime','require','请选择服务开始时间'], + ['serviceEndTime','require','请选择服务结束时间'] + ]; +/* + public $scene = [ + 'editInfo' =>['shopImg','isInvoice','serviceStartTime','serviceEndTime','freight'], + 'editBank' =>['bankId','bankAreaId','bankNo','bankUserName'], + 'applyStep1'=>['applyLinkMan','applyLinkTel','applyLinkEmail','isInvestment','investmentStaff'], + 'applyStep2'=>['businessLicenceType','businessLicence','legalPersonName','businessAreaPath0','licenseAddress','establishmentDate','businessStartDate','businessEndDate','isLongbusinessDate','registeredCapital','empiricalRange','areaIdPath0','shopCompany','shopAddress','shopTel','shopkeeper','telephone','shopEmergencyLinkMan','legalCertificateType','legalCertificate','legalCertificateStartDate','legalCertificateEndDate','isLonglegalCertificateDate','legalCertificateImg','businessLicenceImg','bankAccountPermitImg','organizationCode','organizationCodeStartDate','organizationCodeEndDate','organizationCodeImg'], + 'applyStep3'=>['taxpayerType','taxpayerNo','taxRegistrationCertificateImg','taxpayerQualificationImg','bankUserName','bankNo','bankId','bankAreaId'], + 'applyStep4'=>['shopName','shopImg','goodsCatIds','isInvoice','invoiceRemarks','freight','serviceStartTime','serviceEndTime'] + ]; + */ + //添加旺旺和qq非空验证 mark by cheng 20170318 + public $scene = [ + 'editInfo' =>['shopImg','isInvoice','serviceStartTime','serviceEndTime','freight'], + 'editBank' =>['bankId','bankAreaId','bankNo','bankUserName'], + 'applyStep1'=>['applyLinkMan','applyLinkTel','applyLinkEmail','isInvestment','investmentStaff'], + 'applyStep2'=>['businessLicenceType','businessLicence','legalPersonName','businessAreaPath0','licenseAddress','establishmentDate','businessStartDate','businessEndDate','isLongbusinessDate','registeredCapital','empiricalRange','areaIdPath0','shopCompany','shopAddress','shopTel','shopkeeper','telephone','shopEmergencyLinkMan','legalCertificateType','legalCertificate','legalCertificateStartDate','legalCertificateEndDate','isLonglegalCertificateDate','legalCertificateImg','businessLicenceImg','bankAccountPermitImg','organizationCode','organizationCodeStartDate','organizationCodeEndDate','organizationCodeImg'], + 'applyStep3'=>['taxpayerType','taxpayerNo','taxRegistrationCertificateImg','taxpayerQualificationImg','bankUserName','bankNo','bankId','bankAreaId'], + 'applyStep4'=>['shopName','shopImg','goodsCatIds','isInvoice','invoiceRemarks','freight','serviceStartTime','serviceEndTime'] + ]; + + protected function checkInvoiceRemark($value){ + $isInvoice = input('post.isInvoice/d',0); + $key = Input('post.invoiceRemarks'); + return ($isInvoice==1 && $key=='')?'请输入发票说明':true; + } + + protected function checkInvestment($value){ + $isInvestment = input('post.isInvestment/d',0); + $key = Input('post.investmentStaff'); + return ($isInvestment==1 && $key=='')?'请输入商城招商人员姓名':true; + } + + protected function checkBusinessEndDate($value){ + $isLongbusinessDate = input('post.isLongbusinessDate/d',0); + $key = Input('post.businessEndDate'); + return ($isLongbusinessDate==0 && $key=='')?'请输入营业期限结束日期':true; + } + protected function checkLegalCertificateEndDate($value){ + $isLonglegalCertificateDate = input('post.isLonglegalCertificateDate/d',0); + $key = Input('post.legalCertificateEndDate'); + return ($isLonglegalCertificateDate==0 && $key=='')?'请选择法定代表人证件有效期结束日期':true; + } + protected function checkOrganizationCodeEndDate($value){ + // $isLonglegalCertificateDate = input('post.isLongOrganizationCodeDate/d',0); + // $key = Input('post.organizationCodeEndDate'); + // return ($isLonglegalCertificateDate==0 && $key=='')?'请输入商标注册证有效期结束日期':true; + } +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/articles/articles.js b/hyhproject/home2/view/default/articles/articles.js new file mode 100755 index 0000000..f1c8b62 --- /dev/null +++ b/hyhproject/home2/view/default/articles/articles.js @@ -0,0 +1,24 @@ +$(function(){ + $('.h-cat>span').click(function(t){ + var li = $(this).parent(); + if( li.find('ul').is(":hidden") ){ + li.addClass('h-show').removeClass('h-hide'); + li.siblings().addClass('h-hide').removeClass('h-show'); + }else{ + li.addClass('h-hide').removeClass('h-show'); + } + + }); +}); +function solve(status){ + $.post(WST.U('home/helpcenter/recordSolve'),{'status':status,'id':$('#artId').val()},function(data,dataStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(status==1) + $('.h-record').html('感谢您的评价!'); + else{ + $('.h-record').html('请联系客服!'); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/articles/help.html b/hyhproject/home2/view/default/articles/help.html new file mode 100755 index 0000000..6d5707a --- /dev/null +++ b/hyhproject/home2/view/default/articles/help.html @@ -0,0 +1,66 @@ +{extend name="default/base" /} +{block name="title"}{if $data.articleTitle!=''}{$data.articleTitle}{else}客服中心{/if} - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="keywords" content="{$data.articleKey}" /> +<meta name="description" content="{$data.articleTitle}" /> +{/block} +{block name="css"} +<link href="__STYLE__/css/articles.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="bc-nav"> + <p> + <a href="{:url('/')}">首页</a> + <a href="#">> 客服中心</a> + {volist name="$bcNav" id="bc"} + {if ($bc['catId']!=7)} + <a href="{:url('home/helpcenter/view',['id'=>$data['articleId']])}">> {$bc['catName']}</a> + {/if} + {/volist} + {if isset($data['articleTitle'])} + <a href="{:url('home/helpcenter/view',['id'=>$data['articleId']])}">> {$data['articleTitle']}</a> + {/if} + </p> +</div> +<div class="help-box"> + <div class="help-left"> + <p class="h-title b-99">客服中心</p> + <ul id="parent"> + {volist name="$list" id="v" } + <?php $cat=explode('-',$key);?> + <li class="h-cat {if ($cat[1]==$data['catId'])}h-show{else /}h-hide{/if}"> + <span>{$cat[0]}<p></p></span> + <ul class="h-list"> + {volist name="$v" id="v1" key="k1"} + <a href="{:url('home/Helpcenter/view',['id'=>$v1['articleId']])}"><li class="{if ($v1['articleId']==$data['articleId'])}h-curr{/if}">{:WSTMSubstr($v1['articleTitle'],0,10)}</li></a> + {/volist} + </ul> + </li> + {/volist} + </ul> + </div> + {if($data.articleTitle!='')} + <div class="help-right b"> + <div class="h-right-title"><div id="square"></div><h4>{$data.articleTitle}</h4></div> + <div class="c"><input type="hidden" value="{$data.articleId}" id="artId"></div> + <div class="h-content"> + {:htmlspecialchars_decode($data.articleContent)} + </div> + <div class="c"></div> + <div class="h-record"> + <p>以上内容是否已经解决您的问题呢?</p> + <input class="h-button" onclick="solve(1)" type="button" value="是,已经解决" /> + <input class="h-button" onclick="solve(0)" type="button" value="否,咨询客服" /> + </div> + </div> + {/if} + + + <div class="c"></div> +</div> +{/block} +{block name="js"} +<script src="__STYLE__/articles/articles.js"></script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/articles/news_list.html b/hyhproject/home2/view/default/articles/news_list.html new file mode 100755 index 0000000..3170e47 --- /dev/null +++ b/hyhproject/home2/view/default/articles/news_list.html @@ -0,0 +1,73 @@ +{extend name="default/base" /} +{block name="title"} +{$title} - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="keywords" content="资讯中心,{:WSTConf('CONF.mallName')}" /> +<meta name="description" content="资讯中心,{:WSTConf('CONF.mallName')}" /> +{/block} +{block name="css"} +<link href="__STYLE__/css/articles.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="bc-nav"> + <p> + <a href="{:url('/')}">首页</a> + <a href="{:url('home/news/view')}">> 资讯中心</a> + {volist name="$bcNav" id="bc"} + <a href="{:url('home/news/nlist',['catId'=>$bc['catId']])}">> {$bc['catName']}</a> + {/volist} + </p> +</div> +<div class="help-box"> + <div class="help-left"> + <p class="h-title b-lg">资讯中心</p> + <ul id="parent"> + {volist name="$list" id="v" } + <li class="h-cat h-show"> + <span>{$v['catName']}<p></p></span> + <ul class="h-list"> + {volist name="$v['children']" id="v1" key="k1"} + <a href="{:url('home/News/nList',['catId'=>$v1['catId']])}"><li class="{if ($v1['catId']==$catId)}h-curr{/if}">{$v1['catName']}({$v1['newsCount']})</li></a> + {/volist} + </ul> + </li> + {/volist} + </ul> + </div> + <div class="help-right"> + <div class="h-content"> + {if(!input("param.catId") && !input("param.id"))} + <div class="head"><p><span>N</span>ews&nbsp;资讯中心</p><div class='wst-clear'></div></div> + <ul class="news-list"> + {volist name="$index" id="li"} + <li><div id="g-square"></div><a href="{:url('home/news/view',['id'=>$li['articleId']])}">{$li['articleTitle']}</a><span class="list-time"> {:date('Y-m-d H:i:s',strtotime($li['createTime']))}</span></li> + {/volist} + </ul> + {/if} + {if isset($newsList)} + <div class="head"><p><span>N</span>ews&nbsp;{$bc['catName']}</p><div class='wst-clear'></div></div> + <ul class="news-list"> + {if 63 == input("param.catId")} + {volist name="$newsList" id="n"} + <li><div id="g-square"></div><a ">{$n['articleTitle']}</a><span class="list-time"> {:date('Y-m-d H:i:s',strtotime($n['createTime']))}</span>5元</li> + {/volist} + {else /} + {volist name="$newsList" id="n"} + <li><div id="g-square"></div><a href="{:url('home/news/view',['id'=>$n['articleId']])}">{$n['articleTitle']}</a><span class="list-time"> {:date('Y-m-d H:i:s',strtotime($n['createTime']))}</span></li> + {/volist} + {/if} + </ul> + {/if} + {if isset($page)} + <div class="h-page">{$page}<div class='wst-clear'></div></div> + {/if} + </div> + </div> + <div class='wst-clear'></div> +</div> +{/block} +{block name="js"} +<script src="__STYLE__/articles/articles.js"></script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/articles/news_view.html b/hyhproject/home2/view/default/articles/news_view.html new file mode 100755 index 0000000..37b180e --- /dev/null +++ b/hyhproject/home2/view/default/articles/news_view.html @@ -0,0 +1,68 @@ +{extend name="default/base" /} +{block name="title"} +{if isset($content)} +{if $content.articleTitle!=''}{$content.articleTitle}{else}资讯中心{/if} +{else}资讯中心{/if} - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="keywords" content="{$content.articleKey}" /> +<meta name="description" content="{$content.articleTitle}" /> +{/block} +{block name="css"} +<link href="__STYLE__/css/articles.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="bc-nav"> + <p> + <a href="{:url('/')}">首页</a> + <a href="{:url('home/news/view')}">> 资讯中心</a> + {volist name="$bcNav" id="bc"} + <a href="{:url('home/news/nlist',['catId'=>$bc['catId']])}">> {$bc['catName']}</a> + {/volist} + {if isset($content['articleTitle'])} + <a href="{:url('home/news/view',['id'=>$content['articleId']])}">> 详情</a> + {/if} + </p> +</div> +<div class="help-box"> + <div class="help-left"> + <p class="h-title b-lg">资讯中心</p> + <ul id="parent"> + {volist name="$list" id="v" } + <li class="h-cat h-show"> + <span>{$v['catName']}<p></p></span> + <ul class="h-list"> + {volist name="$v['children']" id="v1" key="k1"} + <a href="{:url('home/News/nList',['catId'=>$v1['catId']])}"><li class="{if ($v1['catId']==$catId)}h-curr{/if}">{$v1['catName']}({$v1['newsCount']})</li></a> + {/volist} + </ul> + </li> + {/volist} + </ul> + </div> + <div class="help-right"> + <div class="h-content"> + {if(!input("param.catId") && !input("param.id"))} + <div class="head"><p><span>N</span>ews&nbsp;资讯中心</p><div class='wst-clear'></div></div> + <ul class="news-list"> + {volist name="$index" id="li"} + <li><div id="g-square"></div><a href="{:url('home/news/view',['id'=>$li['articleId']])}">{$li['articleTitle']}</a><span class="list-time"> {:date('Y-m-d H:i:s',strtotime($li['createTime']))}</span></li> + {/volist} + </ul> + {/if} + {if isset($content)} + <h1>{$content.articleTitle}</h1> + <div class="cat-time"><span>{$content.catName} </span>发布于:{:date('Y-m-d',strtotime($content.createTime))}</div> + <div class="n-content"> + {:htmlspecialchars_decode($content.articleContent)} + </div> + {/if} + </div> + </div> + <div class='wst-clear'></div> +</div> +{/block} +{block name="js"} +<script src="__STYLE__/articles/articles.js"></script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/base.html b/hyhproject/home2/view/default/base.html new file mode 100755 index 0000000..c3ee770 --- /dev/null +++ b/hyhproject/home2/view/default/base.html @@ -0,0 +1,47 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +{block name="meta"}{/block} +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> + +{/*未登录的话加载登录框所需要的文件*/} +{if ((int)session('WST_USER.userId')<=0) } +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/js/login.js?v={$v}'></script> +{/if} +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","SMS_OPEN":"{:WSTConf('CONF.smsOpen')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} +$(function() { + WST.initVisitor(); +}); +</script> +</head> + +<body> +{block name="top"} + {include file="default/top" /} +{/block} +{block name="header"} + {if isset($selfShop)} + {include file="default/self_shop_header" /} + {else /} + {include file="default/header" /} + {/if} +{/block} +{block name="main"}主内容{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}{/block} +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home2/view/default/base_js.html b/hyhproject/home2/view/default/base_js.html new file mode 100755 index 0000000..c81ad06 --- /dev/null +++ b/hyhproject/home2/view/default/base_js.html @@ -0,0 +1,25 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +<meta name="auther" content="WSTMart,www.wstmart.net" /> +<meta name="copyright" content="Copyright©2016-2066 Powered By WSTMart" /> +{block name="meta"}{/block} +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/lazyload/jquery.lazyload.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","SMS_OPEN":"{:WSTConf('CONF.smsOpen')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} +</script> +</head> +<body> +{block name="main"}主内容{/block} +{block name="js"} +{/block} +</body> diff --git a/hyhproject/home2/view/default/box_login.html b/hyhproject/home2/view/default/box_login.html new file mode 100755 index 0000000..914c05c --- /dev/null +++ b/hyhproject/home2/view/default/box_login.html @@ -0,0 +1,36 @@ +<input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> +<form method="post" autocomplete="off"> + <table class="wst-table"> + <tr class="wst-login-tr"> + <td width='90' align='right'>账号:</td> + <td><input id="loginName" name="loginName" class="ipt wst-login-input" tabindex="1" value="" autocomplete="off" type="text" data-rule="用户名: required;" data-msg-required="请填写用户名" data-tip="请输入用户名" placeholder="邮箱/用户名/手机号"/></td> + </tr> + <tr class="wst-login-tr"> + <td align='right'>密码:</td> + <td><input id="loginPwd" name="loginPwd" class="ipt wst-login-input" tabindex="2" autocomplete="off" type="password" data-rule="密码: required;" data-msg-required="请填写密码" data-tip="请输入密码" placeholder="密码"/> </td> + </tr> + <tr class="wst-login-tr"> + <td align='right'>验证码:</td> + <td> + <div class="wst-login-code"> + <input id="verifyCode" style="ime-mode:disabled" name="verifyCode" class="ipt wst-login-codein" tabindex="6" autocomplete="off" maxlength="6" type="text" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify"placeholder="验证码"/> + <img id='verifyImg' class="wst-login-codeim" src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:116px;border-top-right-radius:6px;border-bottom-right-radius:6px;"><span id="verify"></span> + </div> + </td> + </tr> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:43px;"> + <input id="rememberPwd" name="rememberPwd" class="ipt wst-login-ch" checked="checked" type="checkbox"/> + <label>记住密码</label> + <label><a style="color:#666;line-height:32px;margin-left:10px;" target='_blank' href="{:Url('home/users/regist')}">免费注册</a>&nbsp;| </label> + <label><a style="color:#666;line-height:32px;" target='_blank' href="{:url('home/users/forgetpass')}">忘记密码? </a></label> + </td> + </tr> + <tr> + <td colspan="2" style="padding-left:200px;"> + <div style="width: 100px;height:32px;line-height:32px;"><a class="wst-login-but" href="javascript:void(0);" onclick='javascript:login(3)'>登录</a></div> + </td> + </tr> + </table> + {:hook('homeDocumentLogin')} +</form> diff --git a/hyhproject/home2/view/default/brands_list.html b/hyhproject/home2/view/default/brands_list.html new file mode 100755 index 0000000..c26d080 --- /dev/null +++ b/hyhproject/home2/view/default/brands_list.html @@ -0,0 +1,80 @@ +{extend name="default/base" /} +{block name="title"}品牌街 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')},品牌街"> +<meta name="Keywords" content="{:WSTConf('CONF.seoMallKeywords')}"> +{/block} +{block name="css"} +<link href="__STATIC__/plugins/lazyload/skin/laypage.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/brandslist.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<script> +//筛选分类 +function screenCat(id){ + location.href=WST.U('home/brands/index','id='+id); +} +</script> +<input type="hidden" id="catId" value="" autocomplete="off"> +<div class="wst-container"> + <div class="wst-route"><a href="{:url('home/index/index')}" ><img style="float:left;margin-right:10px" src="__STYLE__/img/icon_dianpujie_09.png"/>首页</a> > <a href="{:url('home/brands/index')}">品牌街</a></div> + <div class="wst-brand-cat"> + <div class="wst-brand-catt">品牌行业</div> + {volist name="goodscats" id="ca" key="k"} + <span class="{if($selectedId==$ca['catId'])}js-selected{/if}" onclick="javascript:screenCat({$ca['catId']});">{$ca['catName']}</span> + {/volist} + <div class="wst-clear"></div> + </div> + + <ul class="wst-brands-list"> + {volist name="list.Rows" id="vo"} + <li class="wst-brands"> + <div class="wst-brand-img"><a target='_blank' href="{:Url('home/goods/lists',['cat'=>$vo['catId'],'brand'=>$vo['brandId']])}"><img class="goodsImg" data-original="__IMGURL__/{$vo['brandImg']}" title="{$vo['brandName']}"/></a></div> + <div class="wst-brand-name">{:WSTMSubstr($vo['brandName'],0,15)}</div> + <div class='info'> + <span><img src="__STYLE__/img/img_jrpp.png"/></span> + <p>欢迎进入{$vo['brandName']}</p> + </div> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + <div class="brandsPaging"> + <div id="brandsPaging"></div> + </div> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/brandslist.js?v={$v}'></script> +<script> +$(function(){ + if({$list['TotalPage']}>1){ + laypage({ + cont: 'brandsPaging', + pages: {$list['TotalPage']}, //总页数 + curr: {$list['CurrentPage']}, + skip: true, //是否开启跳页 + skin: '#fd6148', + groups: 3, //连续显示分页数 + prev: '<<', + next: '>>', + jump: function(e, first){ //触发分页后的回调 + if(!first){ //一定要加此判断,否则初始时会无限刷新 + var nuewurl = WST.splitURL("page"); + var ulist = nuewurl.split("?"); + if(ulist.length>1){ + location.href = nuewurl+'&page='+e.curr; + }else{ + location.href = '?page='+e.curr; + } + + } + } + }); + } +}); +</script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/carts.html b/hyhproject/home2/view/default/carts.html new file mode 100755 index 0000000..e9012d3 --- /dev/null +++ b/hyhproject/home2/view/default/carts.html @@ -0,0 +1,111 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">我的购物车</dd> + <dd></dd> + </dl> + <dl class="normal"> + <dt class="s-num1">2</dt> + <dd class="s-text1">填写核对订单信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">3</dt> + <dd class="s-text1">成功提交订单</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>我的购物车</div> + <div class='cart-box'> + <div class='cart-head'> + <div class='chk'><input type='checkbox' onclick='checkChks(this,".j-chk")'>全选</div> + <div class='goods'>商品</div> + <div class='price'>单价</div> + <div class='stock'>库存</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + <div class='action'>操作</div> + </div> + {if !empty($carts["carts"])} + {volist name='$carts["carts"]' id='vo'} + <div class='cart-item'> + <div class='shop'> + <div class='shop-title'> + <input type='checkbox' class='j-chk' onclick='checkChks(this,".j-s{$vo['shopId']}")'>{$vo['shopName']} + {if $vo['shopQQ'] !=''} + <a href="tencent://message/?uin={$vo['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$vo['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $vo['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$vo['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$vo['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + {:hook('homeDocumentCartShopPromotion',['shop'=>$vo])} + <div class='wst-clear'></div> + </div> + <div class='goods-list'> + {volist name='vo["list"]' id='vo2'} + {:hook('homeDocumentCartGoodsPromotion',['goods'=>$vo2])} + <div class='item j-chk {if $vo2["isCheck"]==1}selected{/if} j-s{$vo['shopId']} j-g{$vo2["cartId"]}'> + <div class='chk'><input id='gchk_{$vo2["cartId"]}' type='checkbox' {if $vo2["isCheck"]==1}checked{/if} mval="{$vo2['shopPrice']}" value="{$vo2['cartId']}" sval="{$vo2['goodsStock']}" allowbuy="{$vo2['allowBuy']}" class='j-chk j-s{$vo['shopId']} j-gchk' onclick='checkChks(this,".j-g{$vo2["cartId"]}")'></div> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{$vo2["goodsName"]}</div> + <div class='spec'> + {volist name='vo2["specNames"]' id='specs'} + <div>{$specs['catName']}:{$specs['itemName']}</div> + {/volist} + </div> + </div> + <div class='price'>¥{$vo2['shopPrice']}</div> + <div class='stock'>{$vo2['goodsStock']}</div> + <div class='num'> + <a href='#none' class='buy-btn' id='buy-reduce_{$vo2['cartId']}' onclick='javascript:WST.changeIptNum(-1,"#buyNum","#buy-reduce,#buy-add",{$vo2['cartId']},"statCartMoney")'>-</a> + <input type='text' id='buyNum_{$vo2['cartId']}' class='buy-num' value="{$vo2['cartNum']}" data-max="{$vo2['goodsStock']}" data-min='1' onkeyup='WST.changeIptNum(0,"#buyNum","#buy-reduce,#buy-add",{$vo2['cartId']},"statCartMoney")' autocomplete="off" onkeypress="return WST.isNumberKey(event);" maxlength="6"/> + <a href='#none' class='buy-btn' id='buy-add_{$vo2['cartId']}' onclick='javascript:WST.changeIptNum(1,"#buyNum","#buy-reduce,#buy-add",{$vo2['cartId']},"statCartMoney")'>+</a> + <div id='err_{$vo2['cartId']}' class='wst-clear'></div> + </div> + <div class='t-price'>¥<span id="tprice_{$vo2['cartId']}">{$vo2['shopPrice']*$vo2['cartNum']}</span></div> + <div class='action'><a href='javascript:WST.delCart({$vo2["cartId"]})'>删除</a></div> + <div class='wst-clear'></div> + </div> + {/volist} + </div> + </div> + {/volist} + <div class='cart-footer selected2'> + <div class='cart-summary'> + <div class='summary'>应付总金额(不含运费):¥<span id='totalMoney'>{$carts["goodsTotalMoney"]}</span></div> + <div class='wst-clear'></div> + </div> + </div> + <div class='cart-btn'> + <a href='__ROOT__/index.php' class='wst-contnue wst-cart-asha'>继续购物</a> + <a href='#none' onclick='toSettlement()' class='wst-next wst-cart-reda'>结算</a> + <div class='wst-clear'></div> + </div> + {else} + <div class='empty-cart'> + 您还没有添加商品哦,快去<a href='{:Url("home/index/index")}'>逛逛</a>吧~ + </div> + {/if} + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +<script>$(function(){statCartMoney()})</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/articles.css b/hyhproject/home2/view/default/css/articles.css new file mode 100755 index 0000000..eeb7e6e --- /dev/null +++ b/hyhproject/home2/view/default/css/articles.css @@ -0,0 +1,46 @@ +.bc-nav{width:100%;height:35px;border-bottom:1px solid lightgreen} +.help-box{width:1200px;margin:0 auto;min-height:600px} +.help-left{width:210px;margin:15px;margin-left:0;float:left;background:#fff} +.help-right{width:970px;overflow-x:hidden;min-height:400px;background:white;float:left;margin-top:15px} +.h-content{padding:10px;width:950px;min-height:370px;text-indent:7px;font-family:"microsoft yahei"} +.h-content .head{padding-bottom:26px} +.h-content .head p{float:left;min-width:230px;font-size:16px;height:36px;line-height:36px;border-bottom:2px solid #8b8b8b} +.h-content .head p span{font-size:28px} +.h-title{height:36px;line-height:36px;text-align:center;font-size:16px;color:white;font-weight:bold} +.h-hide ul{display:none} +.h-hide p{margin:14px 5px 0 0;float:right;display:inline-block;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid#ccc} +#parent>li>span{display:block;padding-left:10px;background:#eaeaea;border-bottom:1px solid #fff}#parent>li>span:hover{cursor:pointer;background:#dadada} +#parent>li{line-height:33px;display:block} +.h-show ul{display:block} +.h-show p{margin:14px 5px 0 0;float:right;display:inline-block;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid#ccc} +.h-list{border:1px solid #dedede} +.h-list li{width:177px;line-height:20px;margin:5px 0 5px 10px;padding:2px 0;padding-left:20px;cursor:pointer} +.h-list .h-curr{margin-left:10px} +.h-curr{background:rgba(0,0,0,0) linear-gradient(to right,#eaeaea,#fff) repeat scroll 0 0;border-color:#dedede;border-image:none;border-width:1px;color:green;font-weight:bold} +.h-list a:hover li{color:green;font-weight:bold} +.bc-nav{line-height:35px} +.bc-nav>p{width:1200px;margin:0 auto} +.bc-nav>p>a{color:gray} +.b{border:1px solid #e0dddd} +.h-right-title{width:100%;height:25px;margin-left:5px;margin-top:15px} +.h-right-title>h4{float:left;font-size:19px}#square{margin:5px;width:6px;height:6px;background:#df2003;float:left} +.b-99{background:#7dd589} +.h-record{padding:5px;width:100%;height:100px;margin-top:20px;border-top:1px solid #e0dddd} +.h-record>p{padding:5px} +.h-button{width:100px;height:25px;color:#6f6666;margin-left:5px} +.h-content h1{text-align:center} +.h-content .cat-time{text-align:center;padding:10px 0} +.c{clear:both} +.b-lg{background:#7dd589} +.news-list a,.list-time{font-size:13px;letter-spacing:2px;color:#333} +.news-list li{padding:8px 5px;border-bottom:1px dashed #ccc} +.news-list a:hover{font-size:13px;letter-spacing:2px;color:#40bb6a} +.list-time{display:block;float:right} +#g-square{margin:8px 0;width:3px;height:3px;background:#333;float:left} +.n-content{width:100%;min-height:300px;overflow:hidden} +.h-page{position:relative;width:100%;height:100px;background:url(../img/img_yingyin.png) 0 68px no-repeat} +.h-page .pagination .active{background:#3fba6a;color:white} +.h-page .pagination .disabled span,.h-page .pagination .active span{left:30px;line-height:28px;padding-left:4px} +.h-page .pagination{position:relative;top:32px;left:30%;width:100%;height:30px} +.h-page .pagination li{margin:0 auto;width:28px;height:28px;border:1px solid #bfbfbf;float:left;margin-left:10px} +.h-page .pagination li a{line-height:28px;padding-left:4px} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/brandslist.css b/hyhproject/home2/view/default/css/brandslist.css new file mode 100755 index 0000000..3f79335 --- /dev/null +++ b/hyhproject/home2/view/default/css/brandslist.css @@ -0,0 +1,44 @@ +@CHARSET "UTF-8";.wst-brand-cat{margin:10px 0 20px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-brand-cat{margin:10px 0 0px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-brand-catt{height:23px;color:#333;border-bottom:1px dashed #b5b5b5} +.wst-brand-cat span{float:left;margin:8px 60px 0 0;padding:8px 5px} +.wst-brand-cat span:hover{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.js-selected{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.wst-brands{float:left;margin:10px 20px} +.wst-brand-img{width:200px;height:200px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-brand-img a{width:200px;height:200px;display:table-cell;vertical-align:middle} +.wst-brand-img a img{max-width:200px;max-height:200px} +.wst-brand-name{position:relative;text-align:center;height:30px;line-height:30px;color:#353535;font-family:fantasy} +.brandsPaging{padding:20px 0 50px 480px} +.wst-brands-list li{-webkit-perspective:400px;perspective:400px} +.info{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg);width:100%;height:100%;padding:20px;position:absolute;top:0;left:0;border-radius:4px;pointer-events:none;background-color:#000;opacity:.6} +.in-top .info{-webkit-transform-origin:50% 0;transform-origin:50% 0;-webkit-animation:in-top 300ms ease 0ms 1 forwards;animation:in-top 300ms ease 0ms 1 forwards} +.in-right .info{-webkit-transform-origin:100% 0;transform-origin:100% 0;-webkit-animation:in-right 300ms ease 0ms 1 forwards;animation:in-right 300ms ease 0ms 1 forwards} +.in-bottom .info{-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-animation:in-bottom 300ms ease 0ms 1 forwards;animation:in-bottom 300ms ease 0ms 1 forwards} +.in-left .info{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-animation:in-left 300ms ease 0ms 1 forwards;animation:in-left 300ms ease 0ms 1 forwards} +.out-top .info{-webkit-transform-origin:50% 0;transform-origin:50% 0;-webkit-animation:out-top 300ms ease 0ms 1 forwards;animation:out-top 300ms ease 0ms 1 forwards} +.out-right .info{-webkit-transform-origin:100% 50%;transform-origin:100% 50%;-webkit-animation:out-right 300ms ease 0ms 1 forwards;animation:out-right 300ms ease 0ms 1 forwards} +.out-bottom .info{-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-animation:out-bottom 300ms ease 0ms 1 forwards;animation:out-bottom 300ms ease 0ms 1 forwards} +.out-left .info{-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-animation:out-left 300ms ease 0ms 1 forwards;animation:out-left 300ms ease 0ms 1 forwards} +@-webkit-keyframes in-top{from{-webkit-transform:rotate3d(-1,0,0,90deg);transform:rotate3d(-1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-top{from{-webkit-transform:rotate3d(-1,0,0,90deg);transform:rotate3d(-1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-right{from{-webkit-transform:rotate3d(0,-1,0,90deg);transform:rotate3d(0,-1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-right{from{-webkit-transform:rotate3d(0,-1,0,90deg);transform:rotate3d(0,-1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-bottom{from{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-bottom{from{-webkit-transform:rotate3d(1,0,0,90deg);transform:rotate3d(1,0,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes in-left{from{-webkit-transform:rotate3d(0,1,0,90deg);transform:rotate3d(0,1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@keyframes in-left{from{-webkit-transform:rotate3d(0,1,0,90deg);transform:rotate3d(0,1,0,90deg)}to{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)} +}@-webkit-keyframes out-top{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(-1,0,0,104deg);transform:rotate3d(-1,0,0,104deg)} +}@keyframes out-top{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(-1,0,0,104deg);transform:rotate3d(-1,0,0,104deg)} +}@-webkit-keyframes out-right{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,-1,0,104deg);transform:rotate3d(0,-1,0,104deg)} +}@keyframes out-right{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,-1,0,104deg);transform:rotate3d(0,-1,0,104deg)} +}@-webkit-keyframes out-bottom{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(1,0,0,104deg);transform:rotate3d(1,0,0,104deg)} +}@keyframes out-bottom{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(1,0,0,104deg);transform:rotate3d(1,0,0,104deg)} +}@-webkit-keyframes out-left{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,1,0,104deg);transform:rotate3d(0,1,0,104deg)} +}@keyframes out-left{from{-webkit-transform:rotate3d(0,0,0,0deg);transform:rotate3d(0,0,0,0deg)}to{-webkit-transform:rotate3d(0,1,0,104deg);transform:rotate3d(0,1,0,104deg)} +} +.wst-brands-list:after{content:"";display:table;clear:both} +.wst-brands-list li{position:relative;float:left;width:200px;height:200px;margin:10px 20px 30px 20px;padding:0;list-style:none} +.wst-brands-list span{float:left;width:100%;color:#fff;margin:35px 0 10px 70px} +.wst-brands-list p{float:left;width:100%;color:#fff;font-size:20px;text-align:center} +.info,.info:after,.info:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/carts.css b/hyhproject/home2/view/default/css/carts.css new file mode 100755 index 0000000..adadf30 --- /dev/null +++ b/hyhproject/home2/view/default/css/carts.css @@ -0,0 +1,210 @@ +.stepflex{float:right;border-top:5px solid #ccc;text-align:center;width:480px;margin:60px 0px 0px 50px;} +.stepflex dl{border-top:5px solid #ccc;float:left;position:relative;top:-5px;width:160px;} +dl.doing{border-top-color:#04bd3d;} +.doing .s-num{background-position:-23px 0;} +.s-num,.s-num1{color:#fff;font-weight: 700;height:23px;line-height:23px;margin:-15px auto 0;position:relative;width:23px;border-radius:25px;} +.s-num{background:#04bd3d;} +.s-num1{background:#ccc;} +.s-text1{line-height:30px;} +.s-text{line-height:30px;color:#04bd3d;} +/**购物车**/ +.main-head{font-size:17px;font-weight:bold;height:35px;line-height:35px;} +.cart-box{width:100%;border-top:2px solid #FC7A64;} +.cart-head{background: #f3f3f3;display: block;height: 25px;line-height: 25px;margin: 0 0 5px;padding: 5px 0;} +.cart-head .chk{float:left;width:100px;padding-left:10px;} +.cart-head .goods{float:left;width:550px;} +.cart-head .price{float:left;width:105px;} +.cart-head .stock{float:left;width:105px;} +.cart-head .num{float:left;width:120px;} +.cart-head .t-price{float:left;width:105px;} +.cart-head .action{float:left;width:95px;} +.cart-box .shop{padding-left:10px;line-height:25px;border-bottom:2px solid #d0e2ff;padding-bottom:5px;} +.cart-box .shop .shop-title{width:40%;float:left;} +.cart-box .goods-list{width:100%;} +.cart-box .item{display:block;padding-top:10px;padding-bottom:10px;border-bottom:1px solid #ECECEC;} +.cart-box .item .chk{float:left;width:20px;padding-left:10px;} +.cart-box .item .goods{float:left;width:630px;} +.cart-box .item .goods .img{float:left;width:80px;height:80px;margin-left:10px;} +.cart-box .item .goods .name{float:left;width:340px;height:80px;padding-left:5px;} +.cart-box .item .goods .spec{float:left;width:180px;padding-left:5px;} +.cart-box .item .price{float:left;width:105px;} +.cart-box .item .stock{float:left;width:105px;} +.cart-box .item .num{float:left;width:120px;} +.buy-btn{color:#666;background:#eeeeee;cursor: pointer;float:left;;display:block;height:20px;line-height:20px;padding:0px 5px;border:1px solid #ddd;} +input[type="text"].buy-num{height:16px;text-align:center;width:40px;float:left;border-left:0px;border-right:0px;border-top:1px solid #ddd;border-bottom:1px solid #ddd;} +.item .t-price{float:left;width:105px;} +.item .action{float:left;width:95px;} +.selected{background:#fbfcff;} +.selected2{background:#f2f7ff;} +.cart-footer{margin-bottom:15px;} +.cart-footer .summarys1{float:left;width:360px;} +.cart-footer .summarys2{float:left;width:360px;} +.cart-footer .summarys3{float:right;width:1180px;border-top:1px dotted #ddd;padding-top:10px;} +.cart-summary{border-bottom:1px solid #eeeeee;display:block;height:50px;line-height:50px;} +.summary{float:right;height:50px;line-height:50px;padding-right:10px;} +#totalMoney{color:#C00;font-size:16px;margin-left:5px;} +.cart-btn{margin:20px 0px;padding-right:20px;} +.wst-contnue{float:left;margin-left:20px;width:105px;height:33px;line-height:33px;} +.wst-next{float:right;margin-right:20px;width:118px;height:33px;line-height:33px;} +.wst-order-success{width:135px;height:35px;line-height:35px;display: block;} +.empty-cart{height:80px;line-height:80px;font-size:20px;text-align:center;} +.empty-cart a{color:blue;font-size:20px;} +/**结算页面**/ +.box-head{font-weight:bold;height:30px;line-height:30px;} +.box-head2{font-weight:bold;height:30px;line-height:30px;padding-left:5px;} +.cart-box2{width:100%;border:1px solid #eeeeee;padding:5px 0px 10px 0px;} +.cart-head2{border-top:2px solid #e7e7e7;background: #f3f3f3;display: block;height: 25px;line-height: 25px;padding: 5px 0;} +.cart-head2 .goods2{float:left;width:745px;padding-left:15px;} +.cart-head2 .price2{float:left;width:105px;} +.cart-head2 .stock2{float:left;width:105px;} +.cart-head2 .num2{float:left;width:120px;} +.cart-head2 .t-price2{float:left;width:195px;text-align:right;} +.cart-box2 .shop2{padding-left:15px;height:35px;line-height:35px;border-bottom:2px solid #d0e2ff;color:#E55356;font-weight:bold;font-size:15px;} +.cart-box2 .item{padding:5px 0px 5px 0px} +.cart-box2 .item .goods2{float:left;width:745px;padding-left:15px;} +.cart-box2 .item .goods2 .img2{float:left;width:80px;height:80px;} +.cart-box2 .item .goods2 .name2{float:left;width:470px;height:80px;margin-left:5px;} +.cart-box2 .item .goods2 .spec2{float:left;width:180px;margin-left:5px;} +.cart-box2 .item .price2{float:left;width:105px;} +.cart-box2 .item .stock2{float:left;width:105px;} +.cart-box2 .item .num2{float:left;width:120px;} +.cart-box2 .item .t-price2{float:left;width:195px;font-weight: bold;color: #E55356;text-align:right;} +.cart-summary2{margin-top:10px;} +.summary2{height:30px;line-height:30px;} +.shop-remark{padding:0px 5px 0px 15px} +.shop-remark .shop-remark-box{width:500px;padding-top:20px;padding-bottom:30px;display: inline-block;position: relative;vertical-align: top;} +.shop-remark .shop-summary{width:650px;padding-top:20px;padding-bottom:30px;padding-left:10px;display: inline-block;border-left:1px solid #fff;} +.shop-remark .shop-summary .row{height:25px;line-height: 25px;} +.shop-remark .shop-summary dt{width:140px;display:inline-block;text-align: right} +.shop-remark .shop-summary dd{width:500px;display:inline-block} +#totalPrice{color:#FE0000;font-size:16px;margin-left:5px;} +#deliverMoney{color:#FE0000;font-size:16px;margin-left:5px;} +#orderScore{margin-right:5px;} +.wst-prev{float:left;margin-left:10px;} +.wst-order{float:right;} +/**用户地址**/ +.add-addr{font-weight: normal;color:#005ea7;display: block;float:right;margin-right: 5px;} +.add-addr:hover{color:red;} +.address-box{border-top:2px solid #FC7A64;border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{float: left;width:180px;margin: 2px 8px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame2{float: left;min-width:120px;margin: 2px 20px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;padding:6px;} +/**支付方式**/ +.pay-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.pay-boxs{padding:10px 0px 5px 5px;} +.pay-box ul{padding-left:15px;} +.pay-box ul li{width:1185px;} +.pay-box .label{width:200px;float:left;height:30px;line-height:30px;} +.pay-box .txt{height:auto;line-height:30px;width:985px;float:left;color:#999999;} +.pay-sbox{border:1px solid #eeeeee;padding:5px 0px;} +.pay-sbox-head{border-bottom: 2px solid #ddd;line-height:35px;} +.pay-tip1{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -10px;background-size: cover; } +.pay-tip2{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -71px;background-size: cover; } +.pay-tip3{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -132px;background-size: cover; } +.pay-sbox .qrcode-box{min-height: 300px;height: auto;} +.pay-sbox .tips-box{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .qrcode-box .pbox{text-align: center;margin-top: 10px;font-weight: bold;} +.pay-sbox .wst-qrcode{width:260px;height:260px;text-align:center;margin:0 auto;} +.pay-sbox .wst-qrcode img{width:260px;height:260px;} +.pay-sbox .bnt-box{line-height:35px;text-align:center;font-weight: bold;padding:5px 10px;line-height:50px;} +.pay-sbox .pay-type{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .pay-list{text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .succ-box{text-align: center;padding: 50px;} +.wst-payCode-weixinpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-weixinpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-wallets {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/wallets.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-wallets-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/wallets.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-unionpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/unionpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-unionpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/unionpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.pay-sbox .balance-box{min-height: 300px;height: auto;} +.pay-sbox .balance-box .pbox{text-align: center;padding-top: 40px;font-weight: bold;} +.pay-sbox .balance-box .pbox2{text-align: center;padding-top: 10px;font-weight: bold;} +.pbox-tip{color:#0ae;margin-left:10px;} +.pay-btn{background: #eb5f43 none repeat scroll 0 0;border: 1px solid #d33110;border-radius: 3px;color: #ffffff;cursor: pointer;outline: medium none;} +.pay-sbox .wst-pay-bnt {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px 0px;cursor:pointer;} +.pay-sbox .wst-pay-bnt:hover {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px -57px;cursor:pointer;} +.wst-wallet-box{border:1px solid #ddd;margin:10px;padding:5px;line-height: 35px;height:40px;} +.wst-wallet-box .wst-wallte-item{background:url("../img/icon_qianbaoyue.png") no-repeat;padding-left:30px;height:30px;margin-top:5px;float:left;} +/**送货方式**/ +.shipping-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.shipping-box ul{padding-left:15px;} +.shipping-box ul li{height:auto;line-height:30px;} +/**发票**/ +.invoice-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.invoice-box ul{padding-left:15px;} +.invoice-box ul li{height:auto;line-height:30px;} +/**订单成功**/ +.success-box{border:1px solid #ddd;height:300px;margin-bottom:30px;text-align:center;} +.success-box .imgs{margin: 0 auto;padding-top:72px;width:18%;} +.success-box .imgs span{color:#11cd6e;font-family:"microsoft yahei";font-size: 22px;line-height:65px;margin-left:8x} +.success-box .info{margin: 6px auto;padding-top:16px;width:100%;font-size: 20px;} +.success-box .info a{color:#51cff5;font-size: 20px;} +.success-box .info span{color:#f33d2f;font-size: 20px;} +.success-box .go{margin: 26px auto;width:12%;} +/*按钮*/ +.wst-cart-reda{font-size: 14px;color:#ffffff;background: #df2003;text-align:center;border-radius:3px;font-family:"microsoft yahei";box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);} +.wst-cart-reda:hover{color:#ffffff;background:#ea3232;box-shadow: 0 0px 0px rgba(0, 0, 0, 0.3);} +.wst-cart-asha{font-size: 14px;background: #ffffff;text-align:center;border-radius: 3px;border: 1px solid #dad7d7;font-family:"microsoft yahei";box-shadow: 0 0px 1px rgba(0, 0, 0, 0.3);} +.wst-cart-asha:hover{background:#f1f1f1;box-shadow: 0 0px 0px rgba(0, 0, 0, 0.3);} +/*自定义单选框样式*/ +.wst-radio + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;border-radius: 50px;display: inline-block;position: relative;} +.wst-radio + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-radio:checked + label{border: 1px solid #fc6047;} +.wst-radio:checked + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #fc6047;box-shadow: inset 0px 0px 10px #fc6047;text-shadow: 0px;left: 3px;font-size: 32px;z-index:100;} +.radio-box .wst-radio{position:relative;z-index:-100;left:0px;top:0px;} +.radio-box-hover{background: #fff3f3;} +.operate-box a{color:#1c9eff;} +.operate-box a:hover{color:red;} +.operate-box{float:right;display: none;margin-right: 5px;} +.mt-1{position:relative;top:1px;left:-16px;cursor:pointer;} +/**订单列表**/ +.wst-check-orders{color:#1D94D7;cursor:pointer;} +.wst-order-list{width:100%;border-collapse:collapse;border-color:grey;} +.wst-order-list .head{height: 32px;line-height: 32px;text-align: center;background: #f5f5f5;color: #666;font-weight: 400;} +.wst-order-list .goods-img{width:60px; height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left;} +.wst-order-list .goods-img a{display:table-cell;vertical-align:middle;width:60px;height:60px;} +.wst-order-list .goods-img a img{max-width:60px;max-height:60px;} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:500px;} +.wst-order-list .goods-extra{float:right;margin-left:5px;} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px;} +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd;} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px;} +.wst-order-list td,.wst-order-list th {padding: 5px 10px;border: 1px solid #e5e5e5;border-top: 0px;} +.wst-order-list td,.wst-order-list th.wst-left-noborder{border-left:0;} +.wst-order-list td,.wst-order-list th.wst-right-noborder{border-right:0;} +.wst-order-list .otbody{text-align: center;} +/* 发票信息 */ +.invoice_box{margin-top: 30px;} +.invoice_item{width:85%;margin:0 auto;overflow: hidden;padding-top: 10px;} +.invoice_left{width:25%;float: left;text-align: right;color: #666;font-size: 14px;padding: 4px 0px;} +.tc{text-align: center} +.invoice_right{width: 70%;float: left;} +.inv_ul{width: 100%;overflow-y: scroll;max-height: 132px;} +.inv_li{position: relative;border:1px solid #eee;padding:5px;margin-bottom: 10px;padding:6px;cursor: pointer;} +.inv_li_curr i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.inv_li_curr{border: 2px solid #e4393c!important;padding:6px!important;} +.inv_li:hover .inv_opabox{display: block;} +.inv_opabox{display:none;position: absolute;right: 10%;top: 8px;} +.inv_add,.inv_opabox a{color: #00a0d5;cursor: pointer;} +.inv_add:hover,.inv_opabox a:hover{color: red} +.inv_opabox a{display: inline-block;margin-right: 15px;} +.inv_li1{position: relative;border:1px solid #eee;padding:5px;margin-bottom: 10px;padding:6px;cursor: pointer;float: left;margin-right:5px;} +.inv_codebox{display: none;} +.invoice_input{height:21px!important;padding: 1px;border:none!important;} +.inv_btn{display: inline-block;padding: 5px 10px;color: #fff;background: #e74649;margin-right: 10px;border: 1px solid #e74649;} +.inv_cancel{color: #323333;text-decoration: none;border: 1px solid #ddd;box-shadow: 0 1px 1px rgba(0,1,1,.08);background-color: #f7f7f7;} + diff --git a/hyhproject/home2/view/default/css/common.css b/hyhproject/home2/view/default/css/common.css new file mode 100755 index 0000000..9418331 --- /dev/null +++ b/hyhproject/home2/view/default/css/common.css @@ -0,0 +1,297 @@ +@CHARSET "UTF-8";body{color:#333;font:12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif} +*{padding:0;margin:0} +ol,ul{list-style:none} +a{color:#333;text-decoration:none} +a:hover{text-decoration:none} +img{border:0} +select{background-color:#fff;border:1px solid #ccc;border-radius:2px;height:24px;margin:2px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 1px rgba(0,0,0,0.075) inset} +input[type=text],input[type=password]{border:1px solid #ccc;height:23px;line-height:17px;padding:2px}input[type="radio"],input[type="checkbox"]{margin:2px} +input[type=button]{cursor:pointer} +.wst-relative{position: relative;} +.wst-clear{clear:both} +.wst-lfloat{float:left} +.wst-rfloat{float:right} +.wst-hide{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px 5px} +.wst-redlink{width:95%;display:block;cursor:pointer} +.wst-redlink:hover{color:red} +.wst-fred{color:#df2003} +.wst-align-center{text-align:center} +.wst-align-left{text-align:left} +.wst-align-right{text-align:right} +.hide{display:none} +.layui-layer-icowst1,.layui-layer-icowst2,.layui-layer-icowst3{background-image:url(../../../../../static/images/wst_icon.png)!important;background-repeat:no-repeat!important;background-size:cover!important} +.layui-layer-icowst2{background-position:-40px 0!important} +.layui-layer-icowst3{background-position:-80px -1px!important} +.layui-layer-icowstloading{background-image:url(../../../../../static/images/loading.gif)!important;background-repeat:no-repeat!important;background-size:206% auto!important;background-position:-16px -16px!important} +.wst-header{margin:0 auto;width:100%;border-bottom:1px solid #eee;background:#fafafa} +.wst-header ul li{float:left} +.wst-w,.wst-main{margin:0 auto;width:100%;padding-bottom:5px;margin-bottom:5px} +.wst-footer{text-align:center;line-height:25px;width:1210px;margin:0 auto} +.index-top-ads{margin:0 auto;height:100px;width:100%;position:relative} +.index-top-ads img{width:100%;height:100px;overflow:hidden} +.close-ads{width:35px;height:12px;background:url(../img/close_ads.gif) no-repeat;position:absolute;top:10px;right:20px;float:right;z-index:199} +.wst-header .wst-nav,.wst-container,.wst-search-container,.wst-nav-menus .nav-w,.wst-lite-container{width:1200px;margin:0 auto} +.wst-header .wst-nav{height:30px} +.headlf{float:left;width:500px;font-family:Arial,"宋体";font-size:12px} +.headrf li{float:left;height:30px;line-height:30px} +.headrf li a{font-family:Arial,"宋体";font-size:12px;color:#777} +.headlf li{height:30px;line-height:30px;padding-left:0;padding-right:0} +.headlf li.spacer{color:#ddd;width:10px;text-align:center} +.headrf li.spacer{color:#ddd;width:10px;text-align:center} +.wst-header .wst-nav .j-dorpdown{position:relative;width:91px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-header .wst-nav .j-dorpdown .nowrap{white-space:nowrap} +.wst-header .wst-nav .j-dorpdown:hover{background-color:#fff;border-left:1px solid #ddd;border-right:1px solid #ddd;border-bottom:0;z-index:10000} +.wst-header .wst-nav .j-dorpdown-layer{position:absolute;z-index:1000;margin-top:-1px;background:#fff;cursor:pointer;left:-1px;border:1px solid #ddd;border-top:0;display:none} +.wst-header .last-menu{float:right;right:0;white-space:nowrap} +.wst-header .wst-nav .drop-info{position:relative;padding:0 8px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-header .wst-nav .drop-infos a{color:#fe6047} +.wst-header .wst-nav .dorpdown-user{position:absolute;z-index:1000;cursor:pointer;left:-1px;display:none} +.wst-tag{width:280px;height:180px;border-bottom:1px solid #dedbdb;border-left:1px solid #dedbdb;border-right:1px solid #dedbdb;position:relative;background-color:#fafafa;box-shadow:0 1px 1px rgba(0,0,0,0.3)} +.wst-tag:after{top:-16px;border-color:transparent transparent #f7f7f6} +.wst-tagt{padding:10px 0} +.wst-tagt .userImg{margin-left:10px;float:left;width:60px;height:60px} +.wst-tagt .userImg img{width:60px;height:60px;border-radius:1000px} +.wst-tagt-n{float:left;width:190px;margin-left:5px} +.wst-tagt-na{float:left;color:#fe6047;font-size:15px;margin-left:12px} +.wst-tagt-n img{float:left;width:18px;margin-top:5px;margin-left:6px} +.wst-tagt-ip{float:left;width:190px;line-height:18px;margin-left:12px;color:#3d3d3e} +.wst-tagb{float:left;padding:10px 0 0 30px} +.wst-tagb a{float:left;width:70px;margin-left:30px} +.wst-tagb a:hover{color:#fd5940} +.wst-tags{width:190px;padding-left:10px;clear:both} +.wst-header .wst-nav .j-dorpdown .order-list{width:86px} +.wst-header .wst-nav .j-dorpdown .product-list{width:91px} +.wst-header .wst-nav .j-dorpdown .des-list{width:91px} +.wst-header .wst-nav .j-dorpdown .foucs-list{width:91px} +.wst-header .wst-nav .j-dorpdown .sweep-list{width:215px} +.pdl5{padding-left:5px!important} +.pdr5{padding-right:5px!important} +.wst-header .wst-nav .j-dorpdown-layer div{text-align:center;line-height:24px} +.wst-header .wst-nav .j-dorpdown-layer div a:hover,.wst-header .wst-nav .drop-down a:hover{color:#df2003} +.wst-header .wst-nav .drop-down{position:relative;padding:0 18px;width:55px;margin:0 auto} +.wst-header .wst-nav .drop-down1{background:url(../img/img_icon.png) -13px -33px no-repeat} +.wst-header .wst-nav .drop-down1:hover{background:url(../img/img_icon.png) -13px -183px no-repeat} +.wst-header .wst-nav .drop-down2{background:url(../img/img_icon.png) -13px -83px no-repeat} +.wst-header .wst-nav .drop-down2:hover{background:url(../img/img_icon.png) -13px -233px no-repeat} +.wst-header .wst-nav .drop-down3{background:url(../img/img_icon.png) -12px -134px no-repeat} +.wst-header .wst-nav .drop-down3:hover{background:url(../img/img_icon.png) -12px -284px no-repeat} +.wst-header .wst-nav .drop-down4{background:url(../img/img_icon.png) -13px -108px no-repeat} +.wst-header .wst-nav .drop-down4:hover{background:url(../img/img_icon.png) -13px -258px no-repeat} +.wst-header .wst-nav .drop-down5{background:url(../img/img_icon.png) -13px -57px no-repeat} +.wst-header .wst-nav .drop-down5:hover{background:url(../img/img_icon.png) -13px -207px no-repeat} +.wst-header .wst-nav .drop-down6{background:url(../img/img_icon.png) -13px -8px no-repeat} +.wst-header .wst-nav .drop-down6:hover{background:url(../img/img_icon.png) -13px -158px no-repeat} +.j-dorpdown-layer .qrcodea .qrcodeal{float:left;margin-top:5px} +.j-dorpdown-layer .qrcodea .qrcodear{float:right;margin-right:3px} +.j-dorpdown-layer .qrcodea .qrcodear p{color:#fa8a42;font-weight:bold;text-align:center;width:88px} +.j-dorpdown-layer .qrcodea .qrcodear a{float:right;width:75px;border:1px solid #ededed;padding:0 5px;margin:0 3px 3px 0;background:#f5f5f5} +.wst-nav .headrf .drop-down .di-right{top:12px;right:0;height:7px;overflow:hidden;font-style:normal;color:#6a6a6a;display:block;position:absolute} +.wst-nav .headrf .drop-down .di-left{top:12px;left:0;height:7px;overflow:hidden;font-style:normal;display:block;position:absolute} +.wst-nav .headrf .drop-down .di-right s{position:relative;top:-14px;text-decoration:none} +.wst-nav .headrf .drop-down:hover .di-right s{top:-7} +.drop-down a{width:auto} +.wst-header .wst-nav .normal{position:relative;padding:0 8px;border:1px solid #fafafa;border-top:0;border-bottom:0} +.wst-lite-container{height:auto} +.wst-logo{margin:5px 5px 5px 0;float:left;height:auto} +.wst-search-box{float:left;position:relative;width:670px} +.wst-search{border:2px solid #e23c3d;height:36px;margin-left:20px;margin-top:50px;position:relative} +.wst-search .j-search-type{width:78px;top:0;line-height:36px;position:absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor:pointer;left:-2px;text-align:center} +.wst-search .j-type-list{width:70px;top:35px;line-height:36px;position:absolute;padding:0 4px;border:2px solid #e23c3d;cursor:pointer;background-color:#fff;left:-2px;z-index:100;border-top:0;display:none;text-align:center} +.wst-search .j-search-type i{color:#6a6a6a;display:block;font-style:normal;height:7px;overflow:hidden;position:absolute;right:6px;top:16px;width:0} +.j-search-type i{-moz-border-bottom-colors:none;-moz-border-left-colors:none;-moz-border-right-colors:none;-moz-border-top-colors:none;border-color:#999 transparent transparent;border-image:none;border-style:solid dashed dashed;border-width:5px;font-size:0;line-height:0} +.arrow{transition:all .2s ease-in 0s} +.over{top:10px!important;transform:rotate(180deg);transform-origin:50% 30% 0} +.over-cat{display:none} +.wst-search .j-search-type s{position:relative;top:-17px;text-decoration:none} +.wst-search .j-type-list div:hover{color:#e23c3d} +.wst-search .search-ipt{border:0 none;color:#565656;float:left;font-family:Microsoft Yahei;font-size:14px;line-height:18px;overflow:hidden;padding:0;width:560px;height:36px;border:36px;outline:0;padding-left:84px} +.wst-search .search-btn{background-color:#df2003;color:#fff;cursor:pointer;font-size:15px;font-weight:bolder;height:38px;line-height:36px;position:absolute;right:-1px;text-align:center;top:-1px;width:80px} +.wst-search-keys{color:#6c6c6c;height:25px;line-height:28px;overflow:hidden;padding-left:20px} +.wst-search-keys a{color:#6c6c6c} +.wst-cart-box{float:right;width:163px;height:40px;margin-top:50px;background-color:#df2003;position:relative;cursor:pointer} +.wst-cart-box .word{float:left;width:112px;margin-top:10px;margin-left:20px;padding-left:28px;color:#fff;font-size:14px;font-family:"microsoft yahei";background:url(../img/icon_gouwuche.png) no-repeat left center;position:relative} +.wst-cart-box .num{font-size:14pxpx;color:#fff;line-height:24px;text-align:center;position:absolute;display:block;width:27px;height:25px;background:url(../img/icon_number.png) no-repeat;right:15px;top:-18px} +.wst-cart-boxs{width:332px;margin-top:22px;border:1px solid #dedbdb;position:absolute;z-index:1200;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);left:-171px;top:18px} +.wst-cart-boxs:after{top:-16px;border-color:transparent transparent #fff} +.wst-cart-boxs .carts{background:url(../img/top_icon_cartdown.png) 28px 47px no-repeat;width:332px;height:130px;text-indent:4.5em;line-height:130px;font-size:15px;color:#b9b6b6} +.wst-cart-box .goods{float:left;width:96.666666%;border-bottom:1px dashed #bfbfbf;padding:5px} +.wst-cart-box .goods .imgs{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-cart-box .goods .imgs a{width:72px;height:72px;display:table-cell;vertical-align:middle} +.wst-cart-box .goods .imgs img{max-width:72px;max-height:72px} +.wst-cart-box .goods .number{float:left;width:50%} +.wst-cart-box .goods .number p{float:left;width:92%;margin-top:10px;padding-left:10px} +.wst-cart-box .goods .price{float:right;text-align:right} +.wst-cart-box .goods .price p{float:right;width:100%;line-height:20px;font-weight:bold;color:#df2003} +.wst-cart-box .goods .price span{float:right;width:100%;line-height:20px} +.wst-cart-box .goods .price span a:hover,.wst-cart-box .goods .number p a:hover{color:#df2003} +.wst-cart-box .comm{float:left;width:100%;font-weight:bold;line-height:32px} +.wst-cart-box .comm span{font-size:15px;color:#df2003} +.wst-cart-box .comm .span2{float:right;margin-right:10px} +.wst-cart-box .btn{color:#fff;cursor:pointer;display:block;font-size:16px;font-weight:400;line-height:30px;margin:10px 0 16px 72px;max-width:200px;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;vertical-align:middle;width:100%;border-radius:5px} +@media(min-width:400px){.wst-cart-box .btn{display:inline-block;margin-right:2.5em} +.wst-cart-box .btn:nth-of-type(even){margin-right:0}}@media(min-width:600px){.wst-cart-box .btn:nth-of-type(even){margin-right:2.5em} +.wst-cart-box .btn:nth-of-type(5){margin-right:0}} +.wst-cart-box .btn:hover{text-decoration:none} +.wst-cart-box .btn-3{background:#e3403a;border:1px solid #da251f;box-shadow:0 1px 0 #d6251f,1px 1px 1px #e02a24;font-weight:900;letter-spacing:1px;-webkit-transition:all 150ms linear;transition:all 150ms linear} +.wst-cart-box .btn-3:hover{background:#e02c26;border:1px solid rgba(0,0,0,0.05);box-shadow:1px 1px 2px rgba(255,255,255,0.2);color:#ec817d;text-decoration:none;text-shadow:-1px -1px 0 #c2211c;-webkit-transition:all 250ms linear;transition:all 250ms linear} +.wst-lite-title{float:left;padding-top:90px;padding-left:10px} +.wst-lite-index{padding-top:90px;float:right} +.wst-table td{height:35px} +.wst-footer-frd{color:#e23e3d;font-weight:bolder;font-size:18px} +.wst-footer-pno{color:red;font-weight:bolder;font-size:18px} +.wst-footer{text-align:center;line-height:25px;width:1200px;margin:0 auto} +.wst-footer-fl-box{text-align:center;margin-top:45px} +.wst-footer-cld-box{border-bottom:1px solid #d5d5d5;height:auto;line-height:30px;text-align:left;padding-bottom:20px;margin-bottom:20px} +.wst-footer-fl{font-weight:bolder;padding-top:7px;color:#fc6047;font-size:14px} +.wst-footer-hp-box{background-color:#f7f7f7;text-align:center;margin-top:20px} +.wst-footer-hp-ck1{line-height:30px;text-align:left;border-top:1px solid #f5f5f5;border-bottom:1px solid #f5f5f5;min-width:1200px} +.wst-footer-hp-ck3{margin-top:20px;padding-bottom:10px} +.wst-footer-hp-ck3 a{color:#666} +.wst-footer-hp-ck3 .copyright{color:#666} +.wst-footer-pno{color:red;font-weight:bolder;font-size:18px} +.wst-footer-wz-ca{padding-top:20px;float:left;width:180px;height:180px} +.wst-footer-wz-pt{padding-top:5px;line-height:25px} +.wst-footer-wz-pn{font-weight:bolder;margin-left:10px;font:600 16px/20px "microsoft yahei";color:#666} +.wst-footer-wz-clt{float:left;width:160px;height:180px;margin-left:6px} +.wst-footer-wz-kf{font-weight:bolder;margin-left:10px} +.wst-footer-wz-ent{color:green;font-size:16px} +.wst-footer-wz-ca a{color:#999} +.flink-hover{font-size:13px;color:#434343;margin-left:10px;margin-right:10px} +.flink-hover:hover{text-decoration:underline;color:#1e84da} +.wst-footer-info{margin:0 auto;width:1200px;height:100px} +.wst-footer-info>li{width:180px;height:80px;float:left;margin-right:60px} +.wst-footer-info-img{float:left; margin-top:15px; width: 70px; height: 70px; box-sizing: border-box; background-image: url(../img/footer_icon.png); background-repeat: no-repeat; } +.wst-fimg1{background-position: -1px -1px;} +.wst-fimg2{background-position: -241px -1px;} +.wst-fimg3{background-position: -481px -1px;} +.wst-fimg4{background-position: -721px -2px;} +.wst-fimg5{background-position: -961px -1px;} + +.wst-footer-info-text{float:left;margin-top:25px;margin-left:10px} +.wst-footer-info-text>h1{margin-bottom:5px;font-size:16px;color:#505050} +.wst-footer-info-text>p{color:#6c6c6c;font-size:} +.wst-nav-menus{border-bottom:2px solid #df2003;height:36px;margin:0 auto;min-width:1200px}#wst-categorys{float:left;height:36px;overflow:visible;position:relative;width:210px;z-index:10;top:2px} +#wst-categorys .dt a{background:url(../img/icon_fenleitubiao.png) no-repeat 16px;background-color:#df2003;color:#fff;text-indent:30px;display:block;font:400 15px/36px "microsoft yahei";height:36px;padding:0 10px;text-decoration:none;width:190px} +#wst-categorys .dd{background:rgba(38,38,38,0.7) none repeat scroll 0 0;min-height:400px} +#wst-categorys .dd-inner .item{color:#ff2706;height:35px;position:relative;z-index:1;transition:padding 100ms ease-in;-moz-transition:padding 100ms ease-in;-webkit-transition:padding 100ms ease-in;-o-transition:padding 100ms ease-in} +#wst-categorys .dd-inner .item a{color:#fff} +#wst-categorys .dd-inner h3{font-size:13px;font-weight:400;height:31px;line-height:31px;padding:0 10px;position:absolute;z-index:2} +#wst-categorys .dd-inner i{font:400 9px/14px consolas;height:14px;position:absolute;right:14px;top:9px;width:4px;z-index:1} +#wst-categorys .dd-inner .hover{height:33px;border-left:1px solid #eee;border-top:1px solid #eee;border-bottom:1px solid #eee;background:#f7f7f7 none repeat scroll 0 0;color:#b61d1d} +#wst-categorys .dd-inner .hover a{color:#ff0c00}#wst-categorys .dd-inner .hover i{background:#f7f7f7 none repeat scroll 0 0;height:31px;left:205px;line-height:200px;overflow:hidden;top:0;width:14px} +#wst-categorys .dorpdown-layer{background:#f7f7f7 none repeat scroll 0 0;border:1px solid #eee;display:none;left:209px;overflow:hidden;position:absolute;top:36px;width:779px;min-height:600px} +#wst-categorys .dorpdown-layer .hover{display:block} +#wst-categorys .item-sub{display:block;overflow:hidden} +.cat2_tit{color:#333;font-weight:bold} +.cat2_tit i{font-style:normal;} +#wst-categorys .item-sub::after{clear:both;content:".";display:block;height:0} +#wst-categorys .subitems{background:#f7f7f7 none repeat scroll 0 0;float:left;margin-bottom:-10px;padding:6px 0 10px 20px;width:570px}#wst-categorys .subitems dl{line-height:2em;overflow:hidden;width:100%} +#wst-categorys .subitems dl.fore1 dd{border-top:medium none}#wst-categorys .subitems dt{background:#3B3B3B none repeat scroll 0 0;color:#fff;display:inline-block;line-height:24px;height:24px;margin-right:10px;padding:0 0 0 8px;white-space:nowrap} +#wst-categorys .subitems dt a{color:#fff}#wst-categorys .subitems dt i{font:400 9px/14px consolas;height:24px;margin-left:8px;width:23px;display:inline-block;color:#fff} +#wst-categorys .subitems dd{border-bottom:1px dashed #eee;padding:6px 0;width:570px} +#wst-categorys .subitems dd a{float:left;height:16px;line-height:16px;margin:4px 0;padding:0 8px;white-space:nowrap;color:#666} +#wst-categorys .subitems dd a:hover{color:#ff0c00} +#wst-categorys .item-brands{display:inline;float:right;margin:10px 10px 10px 0;overflow:hidden;width:178px} +#wst-categorys .item-brands .brands-inner{height:270px}#wst-categorys .item-brands .shops-inner{height:180px}#wst-categorys .item-brands a{display:inline;float:left;margin:7px 0 0 6px} +#wst-categorys .item-promotions{display:inline;float:right;margin-right:20px;width:168px}#wst-categorys .item-promotions a{display:block;margin-bottom:1px} +#wst-nav-items{float:left;position:relative;z-index:2}#wst-nav-items .spacer,#wst-nav-items a,#wst-nav-items li,#wst-nav-items ul{float:left}#wst-nav-items ul{width:990px;overflow:hidden;height:36px} +#wst-nav-items .spacer{display:none} +#wst-nav-items a{color:#333;font:400 16px/36px "microsoft yahei";height:36px;padding:0 20px;text-align:center;text-decoration:none} +#wst-nav-items a:hover{color:#ff2708}#wst-nav-items .spacer{background:#ddd none repeat scroll 0 0;height:24px;margin:10px 0 0;overflow:hidden;width:1px} +.wst-right-panel{height:418px;width:210px;} +.cat-icon-1,.cat-icon-2,.cat-icon-3,.cat-icon-4,.cat-icon-5,.cat-icon-6,.cat-icon-7,.cat-icon-8,.cat-icon-9,.cat-icon-10,.cat-icon-11,.cat-icon-12,.over-cat-icon{float:left;background:url(../img/icon_goodsclass_list.png) no-repeat;width:25px;height:25px;margin-top:5px;margin-right:5px; background-size: 457%; } +.cat-icon-1{background-position:-17px -19px} +.cat-icon-1-hover{background-position:-76px -19px} +.cat-icon-2{background-position:-17px -78px} +.cat-icon-2-hover{background-position:-76px -78px} +.cat-icon-3{background-position:-17px -140px} +.cat-icon-3-hover{background-position:-76px -140px} +.cat-icon-4{background-position:-17px -200px} +.cat-icon-4-hover{background-position:-76px -200px} +.cat-icon-5{background-position:-17px -259px} +.cat-icon-5-hover{background-position:-76px -259px} +.cat-icon-6{background-position:-17px -318px} +.cat-icon-6-hover{background-position:-76px -318px} +.cat-icon-7{background-position:-17px -378px} +.cat-icon-7-hover{background-position:-76px -378px} +.cat-icon-8{background-position:-17px -438px} +.cat-icon-8-hover{background-position:-76px -438px} +.cat-icon-9{background-position:-17px -500px} +.cat-icon-9-hover{background-position:-76px -500px} +.cat-icon-10{background-position:-17px -562px} +.cat-icon-10-hover{background-position:-76px -562px} +.cat-icon-11{background-position:-17px -623px} +.cat-icon-11-hover{background-position:-76px -623px} +.cat-icon-12{background-position:-17px -682px} +.cat-icon-12-hover{background-position:-76px -682px} +.over-cat-icon{background-position:-17px -682px} +.over-cat-icon-hover{background-position:-76px -682px} +.wst-route{padding:10px 0} +.wst-route,.wst-route a{color:#6c6c6c;font-size:14px;font-family:fantasy} +.wst-route a:hover{color:#eb5f43;cursor:pointer} +.wst-grey-btn{display:inline-block;border-radius:2px;background:#f7f7f7;text-align:center;text-decoration:none;cursor:pointer;border:1px solid #DDD;padding:3px 13px 3px;color:#666;background-color:#f7f7f7;background-repeat:repeat-x;background-image:-moz-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:-webkit-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:-o-linear-gradient(top,#f7f7f7,#f2f2f2);background-image:linear-gradient(top,#f7f7f7,#f2f2f2);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7',endColorstr='#f2f2f2',GradientType=0)} +.wst-grey-btn:hover{color:red}#wst-pager{text-align:center;margin-top:20px} +.icon-phone,.icon-email{background:url(../img/iconfont_fotter.png) no-repeat} +.icon-phone{width:40px;height:30px;background-position:2px 5px;float:left} +.icon-email{width:40px;height:30px;background-position:-34px 2px;float:left} +.qr-code{width:100%;height:85px} +.qr-code img{float:left;margin-right:5px} +.call-wst{font-size:15px;color:#080808;float:left;line-height:30px;font-weight:bold} +.email-wst{font-size:25px;color:#000;float:left;line-height:30px;text-indent:16px;font-family:"microsoft yahei"} +.mb-wst{float:left;width:110px;height:90px;margin-top:10px} +.focus-wst{float:left;height:100%;width:158px} +.focus-wst-qr{height:20px;color:#171717;margin-top:2px;font-weight:bold} +.focus-wst-qra{height:20px;margin:6px 0 6px 0} +.focus-wst-qre{height:20px;margin-top:3px;font-size:15px} +.wst-contact{float:left;width:275px;height:165px;margin-left:6px;margin-top:5px}#verifyImg,#verifyImg2,#verifyImg3{cursor:pointer} +.wst-empty{width:650px;height:510px;margin:0 auto} +.empty1{background:url(../img/bgimg_error_ymcc.png) 0 123px no-repeat} +.empty2{background:url(../img/bgimg_error_xtcc.png) 0 123px no-repeat} +.empty3{background:url(../img/bgimg_error_spcc.png) 0 123px no-repeat} +.wst-empty .prompt{padding-top:123px;width:600px;margin:0 auto;text-align:center} +.wst-empty .prompt p,.wst-empty .prompt2 p,.wst-empty .prompt3 p{color:#2fc474;font-size:18px;line-height:26px;font-family:"microsoft yahei"} +.wst-empty .button{padding-top:250px;width:320px;margin:0 auto} +.wst-empty-btn{color:#fff;cursor:pointer;float:left;font-size:16px;font-weight:400;line-height:38px;width:123px;position:relative;text-decoration:none;text-transform:uppercase;vertical-align:middle;text-align:center;font-family:"microsoft yahei";border-radius:3px;margin:0 10px} +.wst-empty-btn1{background:#f9a818;font-weight:100} +.wst-empty-btn1:hover{background:#f6bd57;font-weight:900;letter-spacing:1px} +.wst-empty .prompt2{padding-top:160px;width:475px;margin:0 auto} +.wst-empty .prompt2 span{color:#fa3e3f;font-weight:bold;font-size:20px;line-height:52px;font-family:"microsoft yahei"} +.button2{padding-top:160px;width:520px;margin:0 auto} +.wst-empty .prompt3{padding-top:355px;width:588px;margin:0 auto} +.button3{padding-top:23px;width:520px;margin:0 auto} +.wst-loading-img{vertical-align:middle} +.lbel{border-radius:.25em;color:#fff;display:inline;font-weight:700;line-height:1;padding:.2em .6em .3em;text-align:center;vertical-align:baseline;white-space:nowrap} +a.lbel:hover,a.lbel:focus{color:#fff;cursor:pointer;text-decoration:none} +.lbel:empty{display:none} +.lbel-default{background-color:#777} +.lbel-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e} +.lbel-primary{background-color:#428bca} +.lbel-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9} +.lbel-success{background-color:#5cb85c} +.lbel-success[href]:hover,.label-success[href]:focus{background-color:#449d44} +.lbel-info{background-color:#5bc0de} +.lbel-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5} +.lbel-warning{background-color:#f0ad4e} +.lbel-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f} +.lbel-danger{background-color:#d9534f} +.lbel-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c} +.lbel-gray{background-color:#e6e6e6} +.lbel-gray[href]:hover,.label-danger[href]:focus{background-color:#eee} +.wst-tips-box{height:auto;line-height:25px;-moz-border-radius:5px;-webkit-border-radius:5px;color:red;border:1px dotted #f0a869;background:#ffc;padding:5px 5px 5px 15px;margin-left:10px;margin-bottom:5px;margin-top:10px} +.wst-tips-box .icon{width:20px;height:20px;float:left;background:url('../img/icon_tstb.png') no-repeat;background-size:100%} +.wst-tips-box .tips{float:left;padding-left:5px} +.s-wst-slide-items li{overflow:hidden} +.s-wst-slide-numbox{position:absolute;bottom:10px;width:100%} +.s-wst-slide-items{max-width:100%} +.s-wst-slide-controls{width:200px;text-align:center;margin:0 auto;z-index:10} +.s-wst-slide-controls span{width:13px;height:13px;text-align:center;display:inline-block;border-radius:12px;background-color:#ccc;color:white;cursor:pointer} +.s-wst-slide-controls .curr{background-color:#eadfdf;border-radius:12px;color:white;cursor:pointer} +.s-wst-slide{position:relative} +.line-break{word-break:break-all;word-wrap:break-word} +.btn-submit{width:100px;height:32px;line-height:32px;display:inline-block;position:relative;background:#e45050;color:#fff;text-align:center;font-family:'Ubuntu',sans-serif;font-size:15px;font-weight:bold;text-decoration:none;border-radius:3px;overflow:hidden;-webkit-transition:all .15s ease-in;transition:all .15s ease-in} +.btn-submit:before{content:' ';position:absolute;background:#fff;width:25px;height:50px;top:0;left:-45px;opacity:.3;-webkit-transition:all .25s ease-out;transition:all .25s ease-out;-webkit-transform:skewX(-25deg);transform:skewX(-25deg)} +.btn-submit:hover:before{width:45px;left:205px} +.btn-cancel{width:100px;height:32px;line-height:32px;display:inline-block;position:relative;background:#f0efef;border:solid 1px #f0f0f0;color:#555;text-align:center;font-family:'Ubuntu',sans-serif;font-size:15px;font-weight:bold;text-decoration:none;border-radius:3px;overflow:hidden;-webkit-transition:all .15s ease-in;transition:all .15s ease-in} +.wst-stript{width: 100%;height: 20px;color: #666;} +.wst-stript .stript-left{width: 36%;height: 1px;background: RGB(51,51,51);display: inline-block;margin-bottom: 5px;} +.wst-stript .stript-right{width: 36%;height: 1px;background: RGB(51,51,51);display: inline-block;margin-bottom: 5px;} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/goods.css b/hyhproject/home2/view/default/css/goods.css new file mode 100755 index 0000000..ed3f07b --- /dev/null +++ b/hyhproject/home2/view/default/css/goods.css @@ -0,0 +1,1432 @@ +@CHARSET "UTF-8"; +.wst-filters { + width: 1200px; + margin-left: auto; + margin-right: auto; + margin-top: 10px; + color: #999; +} + +.wst-filters div.item { + float: left; + margin-right: 6px; + position: relative; +} + +.wst-filters .arrow { + float: left; + position: relative; + top: 6px; + font-style: normal; + background-image: url(./../img/goods_detail_arrow_r.png); + background-repeat: no-repeat; + display: block; + width: 10px; + height: 10px; + ; +} + +.wst-filters div.dorpdown .arrow { + top: 7px; +} + +.wst-filters .item .link { + color: #666; + float: left; + border: 0px; + margin-right: 5px; + height: 22px; + line-height: 22px; + padding: 0px 5px 0px 5px; +} + +.wst-filters .item .drop-down { + float: left; + border: 1px solid transparent; + display: inline-block; + height: 23px; + line-height: 23px; + vertical-align: top; + position: relative; + background-color: #fff; + padding: 0 2px; +} + +.wst-filters .item .drop-down.hover { + border-color: #df2003; + border-bottom: 0; + z-index: 2 +} + +.wst-filters .item .dorp-down-layer { + border: 1px solid #ddd; + border-top: 0; + display: none; + left: 0px; + top: 22px; + position: absolute; + z-index: 1; + background: #fff; + min-width: 320px; + border: 1px solid #df2003; +} + +.wst-filters .item .dorp-down-layer div { + float: left; + width: 140px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding: 4px 8px; +} + +.wst-filters .item .dorp-down-layer div:hover, +.wst-filters .item .dorp-down-layer a:hover { + color: #df2003; +} + +.wst-filters .item .v-item { + color: #666; + border: 1px solid #ddd; + cursor: pointer; + display: inline-block; + font-size: 12px; + height: 22px; + line-height: 22px; + margin: 0 5px 5px 0; + padding: 0 30px 0 4px; + position: relative; + vertical-align: top; +} + +.wst-filters .item .v-item:hover { + border-color: #e4393c; +} + +.wst-filters .item .v-item i { + display: block; + position: absolute; + width: 25px; + height: 22px; + right: 0; + text-align: center; + font-style: normal; + top: 0; +} + +.wst-filters .item .v-item:hover i { + background-color: #e4393c; + color: #fff; +} + + +/**商品移动效果**/ + +.goods-pics { + width: 350px; + margin: 10px 0px 10px 0px; +} + +.goods-pics .items { + float: left; + height: 56px; + float: left; + -top: 3px; + overflow: hidden; + position: relative; + width: 319px; +} + +.goods-pics .items ul { + height: 56px; + position: absolute; + width: 999999px; + cursor: pointer +} + +.goods-pics .items ul li { + float: left; + text-align: center; + width: 64px; +} + +.goods-pics .prev, +.goods-pics .next { + background: #ebebeb none repeat scroll 0 0; + border: 1px solid #ddd; + cursor: pointer; + display: block; + font-family: "宋体"; + height: 54px; + line-height: 54px; + text-align: center; + text-decoration: none; + width: 10px; +} + +.goods-pics .prev { + float: left; + margin-right: 4px; +} + +.goods-pics .next { + float: right; +} + + +/**放大镜**/ + +.goods-img-box { + float: left; + height: 430px; + margin: 5px; + width: 350px; +} + +.spec-preview { + float: left; + height: 350px; + width: 345px; + margin-bottom: 5px; +} + + +/*Cloud Zoom 放大镜 */ + +.cloudzoom-lens { + width: 30px; + height: 30px; + border: 1px solid #eee; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.20); + cursor: crosshair; + z-index: 10; +} + +.cloudzoom-zoom { + background: #fff; + border: 1px solid #EEE; + width: 360px; + height: 360px; + z-index: 200; + box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.1); +} + +.cloudzoom-zoom-inside { + border: none; + box-shadow: none; +} + +.cloudzoom-blank { + opacity: 0.3; +} + + +/**商品内容**/ + +.intro { + display: inline; + float: left; + width: 628px; + min-height: 430px; + border-left: 1px solid #eee; + border-right: 1px solid #eee; + padding-bottom: 10px; +} + +.intro h2 { + color: #666; + font: 700 16px/28px Arial, "microsoft yahei"; + line-height: 25px; +} + +.intro .intro-name { + padding: 10px 20px; +} + +.intro .tips { + color: #e4393c; + font-size: 12px; +} + +.intro .summary { + margin: 0 20px; + margin-bottom: 10px; + background: url(../img/intro-bg.png) repeat-x; + line-height: 30px; + padding: 5px 0px 5px 0px; +} + +.summary .dt { + display: inline; + color: #999; + float: left; + font-family: simsun; + text-align: right; + width: 75px; + padding-left: 10px; +} + +.summary .dd { + width: 470px; + color: #585858; +} + +.summary .dd img { + margin-top: 6px; +} + +.summary .market-price { + font-weight: 400; + text-decoration: line-through; +} + +.summary .price { + color: #e40000; + display: inline-block; + font-size: 18px; + vertical-align: middle; +} + +.summary .lxy{ + font-size: 26px; +} + +.summary .appraise { + float: right; +} + +.summary .appraise-num { + color: #FF4400; +} + +.summary .infol { + float: left; + width: 100%; +} + +.summary .infor { + width: 168px; + position: absolute; + top: -61px; + right: -12px; +} + +.summary .goods-intro-bg { + position: relative; +} + +.ginfo_b { + width: 100%; +} + +.ginfo_b li { + float: left; + width: 25%; + height: 30px; + overflow: hidden; +} + +.ginfo_b li:nth-child(3) { + width: 50%; +} + +.sale_box { + margin: 0px 20px; + padding-bottom: 10px; + border: none; + box-sizing: border-box; +} + +.sale_box .dt { + display: inline; + color: #999; + float: left; + font-family: simsun; + text-align: right; + width: 75px; + padding-left: 10px; +} + +.sale_box .dd { + color: #585858; +} + +.c14_005 { + font-size: 14px; + color: #005aa0; +} + + +/**商品规格**/ + +.intro .spec { + padding: 5px 5px 5px 10px; +} + +.intro .spec .item { + width: 590px; +} + +.spec .dt { + padding-left: 20px; + line-height: 35px; + color: #999; + height: 30px; + display: inline; + float: left; + font-family: simsun; + text-align: right; + width: 75px; +} + +.spec .dd { + width: 525px; + color: #585858; +} + +.spec .j-option { + float: left; + margin: 2px 8px 2px 0px; + background: #fff; + border: 1px solid #ccc; + padding: 4px 6px; + cursor: pointer; + position: relative; +} + +.spec .j-selected i { + font-size: 0; + line-height: 0; + background: url(../img/img_gd_sel.png) no-repeat 0 0; + display: block; + width: 11px; + height: 11px; + position: absolute; + z-index: 1; + right: -1px; + bottom: -1px; +} + +.spec .j-selected { + border: 2px solid #e4393c; + padding: 3px 5px; +} + + +/**购买商品**/ + +.intro .buy { + padding: 5px 5px 5px 10px; +} + +.intro .buy .item { + width: 590px; + clear: both; +} + +.buy .dt { + padding-left: 20px; + line-height: 35px; + color: #999; + height: 30px; + display: inline; + float: left; + font-family: simsun; + text-align: right; + width: 75px; +} + +.buy .dd { + width: 525px; + line-height: 35px; + height: 30px; + color: #585858; +} + +.buy .btn {} + +.buy .addBtn { + font-weight: bold; + cursor: pointer; + display: block; + font-size: 16px; + height: 38px; + line-height: 38px; + text-align: center; + background: #FFE4D0; + border: 1px solid #F0CAB6; + color: #f40; + width: 150px; + float: left; + margin-right: 20px; +} + +.buy .addBtn:hover { + background: #f40; + color: #fff; +} + +.buy .buyBtn { + font-weight: bold; + cursor: pointer; + display: block; + font-size: 16px; + height: 38px; + line-height: 38px; + text-align: center; + background: #e4393c; + color: #fff; + width: 150px; + float: left; +} + +.buy .buyBtn:hover { + background: #df2003; + color: #fff; +} + + +/**右侧看了又看**/ + +.seeing { + float: left; + width: 210px; + height: 420px; +} + +.seeing .head { + font-size: 13px; + color: #333; + height: 25px; + line-height: 25px; + background: #f7f7f7; + text-align: center; + padding: 5px 10px +} + +.seeing .body { + width: 210px; + padding: 5px; +} + +.see-item { + padding-top: 7px; + width: 100px; + float: left; +} + +.see-item .see-img { + width: 200px; + height: 120px; + margin: 0 auto; + text-align: center; + vertical-align: middle; + display: block; + position: relative; + display: table-cell; +} + +.see-price { + display: block; + width: 100px; + height: 20px; + color: #DF2003; + font-weight: bold; +} + +.see-item .see-img img { + max-width: 90px; + max-height: 90px; +} + + +/**猜你喜欢**/ + +.wst-side { + float: left; + width: 210px; + margin-right: 5px; +} + +.goods-side { + width: 210px; +} + +.shop-intro { + padding-bottom: 13px; + width: 210px; + ; + border: 1px solid #eee; + height: auto; + margin-bottom: 10px; +} + +.shop_imgbox { + text-align: center; + background-color: #f7f7f7; + padding: 5px 0; +} + +.shop-intro .title { + height: 30px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; + box-sizing: border-box; + padding: 5px; + padding-left: 15px; +} + +.shop-name { + font-size: 14px; + color: #333; + font-weight: bold; +} + +.shop-intro .body { + padding: 10px 0; + border-top: 1px dashed #eee; + margin: 0 15px; +} + +.shop-intro .itemScore:nth-child(2) { + border-left: 1px solid #eee; + border-right: 1px solid #eee; +} + +.shop-intro .itemScore { + width: 33%; + box-sizing: border-box; + text-align: center; + padding: 5px; + float: left; +} + +.c12_e40 { + font-size: 12px; + color: #e40000; +} + +.shop-intro .footer { + padding: 5px 15px; + text-align: center; + box-sizing: border-box; +} + +.footer a:nth-child(1) { + margin-right: 6px; +} + +.footer a { + background: #fafafa; + border: 1px solid #ededed; + border-radius: 2px; + color: #666; + float: left; + height: 28px; + line-height: 28px; + text-align: center; + width: 40%; + padding-left: 13px; +} + +.footer a:hover { + background: #f5f5f5 none repeat scroll 0 0; + border-color: #e0e0e0; + color: #666; +} + +.footer .home, +.footer .home:hover { + background: url(../img/goodsdetails_icon_jrdp.png) 5px 4px no-repeat; +} + +.footer .j-fav, +.footer .j-fav:hover { + background: url(../img/iconfont_guanzhu_sel.png) 6px 7px no-repeat; +} + +.footer .j-fav2 { + background: url(../img/iconfont_guanzhu_nor.png) 5px -17px no-repeat; + transition: background-position 0.15s ease-in-out 0s; +} + +.footer .j-fav2:hover { + background: url(../img/iconfont_guanzhu_nor.png) 5px 6px no-repeat; + text-decoration: none; +} + +.goods-side .title { + line-height: 35px; + background-color: #f7f7f7; + text-align: center; +} + +.goods-side .guess-like { + min-height: 300px; + border: 1px solid #eee; + padding-bottom: 10px; +} + +.goods-side .item { + padding-top: 10px; +} + +.goods-side .item .img { + width: 200px; + margin: 0 auto; + text-align: center; + vertical-align: middle; + display: block; + position: relative; + display: table-cell; + padding: 4px; +} + +.goods-side .item .img a { + display: table-cell; + vertical-align: middle; + width: 200px; + height: 200px; +} + +.goods-side .item .img a img { + max-width: 200px; + max-height: 200px; +} + +.goods-side .item .p-price { + padding: 5px; + font-weight: bold; + color: #C00; + font-size: 14px; +} + +.goods-side .item .v-price { + text-decoration: line-through; + color: #999; + margin-left: 10px; + font-weight: normal; + font-size: 12px; +} + +.goods-side .hot-goods { + min-height: 300px; + border: 1px solid #eee; + margin-top: 15px; + padding-bottom: 10px; +} + + +/**商品详情***/ + +.wx_qrcode_fixed { + position: fixed!important; + left: inherit!important; + right: 80px; +} + +#wx_qrcode { + width: 85px; + position: relative; + float: right; + margin-right: 20px; + z-index: 99; + left: 0; +} + +#wx_qrcode:hover { + background-color: #fff; +} + +#wx_qrcode:hover .wx_qrcode_box { + display: block; +} + +.wx_qrcode_box img { + width: 100%; + height: 100%; +} + +.wx_qrcode_box { + display: none; + left: 0; + background-color: #fff; + position: absolute; + height: 110px; + width: 115px; +} + +.goods-desc { + width: 985px; + float: right; +} + +.wst-tab-box { + width: 100%; + height: auto; + margin: 0px auto; + background: #ffffff; +} + +.wst-tab-nav { + margin: 0; + padding: 0; + height: 36px; + top: 0px; + z-index: 30; + background: #f7f7f7; + width: 100%; + border: 1px solid #eee; +} + +.wst-tab-nav li { + cursor: pointer; + float: left; + margin: 0 0px; + list-style: none; + border: 1px solid #f7f7f7; + border-bottom: none; + border-left: none; + height: 36px; + line-height: 36px; + text-align: center; + color: #000000; + padding: 0 15px; +} + +.wst-tab-nav .on .appraise-num { + color: #fff; +} + +.wst-tab-nav .on { + border-top: none; + color: #fff; + font-weight: bold; + background: #e4393c; +} + +.wst-tab-nav #addCart2 { + display: none; + position: fixed; + top: 0px; + right: 20px; + z-index: 31; + background: #df2003; + padding: 5px 15px; + margin-top: 5px; + color: #ffffff; +} + +.brand_name span { + color: #005aa0; +} + +.brand_name { + margin-left: 5px; + margin-bottom: 20px; +} + +.wst-tab-content { + word-wrap: break-word; + word-break: break-all; + padding: 5px; + width: 99%; + height: auto; + border: 1px solid #eee; + border-top: none; + background: #FFF; +} + +.wst-tab-item img { + width: 100%; +} + +.goods-desc .appraise-num { + color: #FF4400; + font-weight: bold; +} + +.wst-attrs-list { + box-sizing: border-box; + border-bottom: 1px solid #eee; + margin-bottom: 10px; + padding: 20px; + width: 100%; + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; +} + +.wst-attrs-list li { + color: #666; + padding: 5px; + width: 233px; + height: 16px; + float: left; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.buy-btn { + color: #666; + background: #eeeeee; + cursor: pointer; + float: left; + ; + display: block; + height: 27px; + line-height: 27px; + padding: 0px 10px; + border: 1px solid #ddd; +} + +input[type="text"].buy-num { + text-align: center; + width: 50px; + float: left; + border-left: 0px; + border-right: 0px; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +.goods-term-box { + padding: 0px 5px; +} + +.goods-term-box a:hover, +.wst-contrast:hover { + color: #e4393c; +} + +.wst-favorite { + float: left; + height: 38px; + position: relative; + top: -7px; + left: -7px; +} + +.wst-favorite .favorite { + height: 38px; + line-height: 38px; + padding: 5px 5px 5px 25px; +} + +.wst-favorite .j-fav, +.footer .j-fav:hover { + background: url(../img/iconfont_guanzhu_sel.png) 4px 5px no-repeat; +} + +.wst-favorite .j-fav2 { + background: url(../img/iconfont_guanzhu_nor.png) 3px -19px no-repeat; + transition: background-position 0.15s ease-in-out 0s; +} + +.wst-favorite .j-fav2:hover { + background: url(../img/iconfont_guanzhu_nor.png) 3px 5px no-repeat; + text-decoration: none; +} + +.wst-contrast { + float: left; + padding-left: 20px; + height: 23px; + line-height: 23px; + position: relative; + cursor: pointer; +} + +.wst-contrast i { + position: absolute; + top: 4px; + left: 0; + width: 15px; + height: 15px; + background: url(../img/contrast.png) 0 0 no-repeat; + background-size: 100%; +} + +.wst-cont-frame { + position: fixed; + bottom: -200px; + right: 50%; + margin-right: -602px; + z-index: 100; + width: 986px; + height: 139px; + background: #fff; + -moz-box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + -webkit-box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + box-shadow: 0 0 15px rgba(221, 221, 221, 0.8); + -webkit-transition: all .2s linear; + transition: all .2s linear; +} + +.wst-cont-frame.show { + bottom: 0; +} + +.wst-cont-frame .head { + height: 32px; + border: 1px solid #ddd; + border-bottom: 2px solid #e23c3d; + position: relative; +} + +.wst-cont-frame .head span { + float: left; + width: 80px; + height: 36px; + line-height: 30px; + text-align: center; + font: 14px/30px 'microsoft yahei'; + position: relative; + left: -1px; + margin-top: -4px; + background: #fff; + border: 2px solid #e23c3d; + border-bottom: 0; + color: #e23c3d +} + +.wst-cont-frame .head .close { + text-align: right; + position: absolute; + right: 0; + top: 0; + padding-right: 22px; + height: 30px; + line-height: 30px; + color: #005aa0; +} + +.wst-cont-frame .list { + border: 2px solid #e23c3d; + border-top: none; + position: relative; +} + +.wst-cont-frame .goods { + padding: 6px; + color: #ccc; + height: 90px; + overflow: hidden; +} + +.wst-cont-frame .term { + float: left; + overflow: hidden; + margin-right: 10px; + padding: 17px 10px 12px 0; + border-right: 1px dotted #e23c3d; +} + +.wst-cont-frame .term:hover .info .price a { + opacity: 1; +} + +.wst-cont-frame .term .img { + float: left; + margin-right: 5px; + width: 48px; + height: 48px; + text-align: center; + border: 1px solid #fff; + overflow: hidden; +} + +.wst-cont-frame .term .info, +.wst-cont-frame .list .term-empty .info { + float: left; + width: 140px; +} + +.wst-cont-frame .term .info .name { + height: 36px; + line-height: 18px; + overflow: hidden; + display: block; + color: #333; +} + +.wst-cont-frame .term .info .price span { + color: #e4393c; + font-size: 14px; + font-family: Verdana; + font-weight: bold; +} + +.wst-cont-frame .term .info .price a { + padding-left: 10px; + color: #005aa0; + opacity: 0; +} + +.wst-cont-frame .term-empty { + float: left; + overflow: hidden; + margin-right: 10px; + padding: 17px 10px 12px 0; + border-right: 1px dotted #e23c3d; +} + +.wst-cont-frame .term-empty .img { + float: left; + margin-right: 5px; + width: 48px; + height: 48px; + text-align: center; + color: #ccc; + border: 1px solid #fff; + font: 36px/48px arial; + overflow: hidden; + background: #f6f6f6; +} + +.wst-cont-frame .term-contrast { + position: absolute; + right: 22px; + top: 22px; + width: 85px; + text-align: center; +} + +.wst-cont-frame .term-contrast .contrast { + display: block; + margin: 0 auto; + margin-bottom: 10px; + font: bold 14px/30px verdana; + width: 60px; + height: 30px; + line-height: 30px; + text-align: center; + background: #e4393c; + color: #fff; +} + +.wst-cont-frame .term-contrast .contrast:hover { + background: #e75153; +} + +.wst-cont-frame .term-contrast .empty { + color: #005aa0; +} + + +/*商品评价*/ + +.apprtime { + color: #999; + display: inline-block; + margin: 5px 0; +} + +.appraise-head { + width: 100%; + height: 80px; + display: flex; + margin: 10px auto; +} + +.appraise-head .text { + font-size: 12px; + color: #666; + font-weight: 400; +} + +.percent { + line-height: 110%; + font-size: 45px; + color: #E4393C; + font-family: arial; +} + +.percent span { + font-size: 23px; +} + +.app-head-l { + flex: 1; +} + +.app-head-lbox { + padding: 4px 10px 0 50px; +} + +.app-head-r { + flex: 5; +} + +.app-head-rbox { + display: flex; + height: 100%; + justify-content: center; + align-items: center; + padding-left: 20px; +} + +.app-hr-item { + flex: 1; +} + +.percentbox { + border: 1px solid #E4393C; + float: left; + width: 60%; + height: 14px; + margin-top: 2px; + margin-left: 10px; +} + +.percentbg { + height: 100%; + background: #E4393C; +} + +.app-hr-text { + float: left +} + +.appr-filter { + width: 100%; + height: 30px; + border: 1px solid #f5f5f5; + background-color: #fafafa; +} + +.appr-filterbox { + width: 100%; + height: 100%; +} + +.appr-filterbox li { + float: left; + padding: 5px 10px; +} + +.appr-filterbox li .curr { + background: #fafafa; + color: #e4393c; +} + +i { + font-style: normal; +} + +.apprimg { + width: 25px !important; + height: 25px; + border-radius: 50%; + float: left +} + +.appr-star, +.appr-star-off { + background-image: url(./../img/star.png); + background-repeat: no-repeat; + width: 15px; + height: 15px; + margin-right: 2px; + float: left; +} + +.appr-star-off { + background-position: -80px 0px; +} + +.userinfo { + width: 100%; + height: 26px; +} + +.appraises-box { + width: 960px; + border-bottom: 1px solid #eee; + margin: 5px 0; + padding: 0 5px; +} + +.wst-appraises-left { + width: 84%; + height: 100%; + float: left; +} + +.app-content { + margin: 10px 0; +} + +.wst-appraises-right { + width: 150px; + height: 100%; + float: left; +} + +.goods-spec-box { + width: 100%; + height: 100%; +} + +.appraiser { + height: 100%; + float: left; + padding-left: 5px; +} + +.reply-content { + line-height: 15px; + width: 100%; + border-top: 1px solid #eee; + padding-top: 10px; + color: orange; + float: left; + margin-bottom: 10px; +} + +.reply-time { + float: left; + color: #999; + padding-bottom: 10px; +} + +.reply-content>a { + color: orange; +} + +.reply-box { + width: 100%; + max-height: 110px; + position: relative; + margin-bottom: 5px; +} + +.goods-desc-box img { + display: block; +} + + +/* 商品咨询 */ + +.c999 { + color: #ccc; +} + +.consult-searchbox { + padding: 17px 0 0 43px; +} + +.search-tips { + color: #999; + padding-bottom: 10px; +} + +.search-text { + float: left; + width: 449px; + height: 28px !important; + border: 1px solid #ccc !important; + border-right: none; + font: 12px/34px simsun; + color: #999; + padding: 0 10px; +} + +.csbtn { + float: left; + width: 82px; + height: 34px; + background: #e4393c; + border: none; + line-height: 1; + color: #fff; + font-family: "Microsoft YaHei"; + font-size: 16px; + cursor: pointer; +} + +.consult-list { + padding: 0 15px 0 43px; +} + +.cs-content { + width: 75%; +} + +.ask { + padding: 15px 0 7px; +} + +.answer { + color: #ff6500; + padding-bottom: 15px; +} + +.consult-item { + font: 12px/18px simsun; + border-bottom: 1px dotted #eee; +} + +.consult-publish { + height: 300px; + border: 1px solid red; + margin-top: 20px; + border-width: 2px 1px 1px; + border-color: #999 #dedede #dedede; + border-style: solid; +} + +.consult-publish h5 { + height: 30px; + line-height: 30px; + font-size: 14px; + font-family: '\5fae\8f6f\96c5\9ed1'; + padding-left: 10px; +} + +.explain, +.consult-publish ul { + padding: 10px 20px; +} + +.consult-publish ul li { + margin-bottom: 5px; + line-height: 25px; +} + +.fbold { + font-weight: bold; + vertical-align: top; +} + +#consultContent { + width: 500px; + height: 100px; +} + +#consultCommit { + display: inline-block; + width: 72px; + height: 29px; + margin-left: 62px; + vertical-align: middle; + background: #e54043; + border: none; + color: #fff; + cursor: pointer; +} + +button:focus { + outline: none; +} + +.intro { + min-height: 445px; +} + +.j-inform { + float: right; +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/goodslist.css b/hyhproject/home2/view/default/css/goodslist.css new file mode 100755 index 0000000..4ea46f1 --- /dev/null +++ b/hyhproject/home2/view/default/css/goodslist.css @@ -0,0 +1,243 @@ +@CHARSET "UTF-8"; +.wst-hot-sales{background:#f1f1f1;width:1200px;margin-left: auto; margin-right: auto;margin-top:10px;padding:15px 0px;overflow:hidden;height:112px;} +.wst-hot-sales .wst-sales-logo{width:60px;float:left;text-align: center;position:relative;} +.wst-hot-sales .wst-sales-box{float:left;width:1130px;overflow:hidden;} +.wst-hot-sales .wst-sales-logo .wst-hot-icon{position: absolute;top:0;left:20px;width:19px;height: 70px;padding:2px 10px;background:url(../img/img_bg_goodslist_tjrm.png) 4px 0px no-repeat;text-align: center;writing-mode:tb-rl;} +.wst-hot-sales .wst-sales-box .item{height:120px;width:263px;background:#fff;margin-left:17px;float:left;} +.wst-hot-sales .wst-sales-box .item .img{float:left;width:120px;height: 120px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;} +.wst-hot-sales .wst-sales-box .item .img a{display:table-cell;vertical-align:middle;width:120px; height:120px; padding:5px;} +.wst-hot-sales .wst-sales-box .item .img a img{max-width:110px;max-height:110px; } +.wst-hot-sales .wst-sales-box .item .des{float:left;width:130px;height: 120px; padding:5px;line-height:20px;} +.wst-hot-sales .wst-sales-box .item .des .p-sale{font-weight: bold;color:#C00;} +.wst-hot-sales .wst-sales-box .item .des .p-name{height: 40px;line-height: 20px;overflow: hidden;} +.wst-hot-sales .wst-sales-box .item .des .p-price{font-weight: bold;color:#C00;} +.wst-hot-sales .wst-sales-box .item .des .p-buy a {display: inline-block;line-height: 14px;height: 14px;border-radius: 2px;background: #F7F7F7;text-align: center;text-decoration: none;cursor: pointer;border: 1px solid #DDD;padding: 4px 13px 5px;color: #666;background-color: #f7f7f7;background-repeat: repeat-x;background-image: -moz-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: -webkit-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: -o-linear-gradient(top,#f7f7f7,#f2f2f2);background-image: linear-gradient(top,#f7f7f7,#f2f2f2);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7f7f7', endColorstr='#f2f2f2', GradientType=0);} +.wst-hot-sales .wst-sales-box .item .des .p-buy a:hover{color:#df2003;} +.wst-filters{width:1200px;margin-left: auto;margin-right: auto;margin-top:10px;color:#999;} +.wst-filters div.item,.wst-address div.item{float:left;margin-right:6px;position:relative;} +.wst-filters .arrow,.wst-address .arrow{float:left;position: relative;top:2px;padding-right:12px;font-style: normal;} +.wst-filters .item .link,.wst-address .item .link{color:#666;float:left;border:0px;margin-right:5px;height:22px;line-height: 22px;} +.wst-filters .item .drop-down,.wst-address .item .drop-down{float:left;margin-right:5px;border: 1px solid #eee;display: inline-block;height: 23px;line-height: 23px;padding: 0 4px 0 8px;vertical-align: top;position: relative;background-color: #fff; } +.wst-filters .item .drop-down .drop-down-arrow,.wst-address .item .drop-down .drop-down-arrow{display: inline-block;width: 20px;height: 20px;vertical-align: top;background: url(../img/search.png) no-repeat 4px 7px;-webkit-transition: background-position .15s ease-in-out;-moz-transition: background-position .15s ease-in-out;transition: background-position .15s ease-in-out;} +.wst-filters .item .drop-down.hover{border-color:#df2003;border-bottom:0;z-index: 100} +.wst-address .item .drop-down.hover{border-color:#ddd;border-bottom:0;z-index: 2} +.wst-filters .item .drop-down.hover .drop-down-arrow,.wst-address .item .drop-down.hover .drop-down-arrow{background-position: 4px -44px;} +.wst-filters .item .dorp-down-layer{border: 1px solid #ddd;border-top:0;display:none;left:0px;top:22px;position:absolute;z-index: 99;background:#fff;min-width: 320px;border: 1px solid #df2003;} +.wst-address .item .dorp-down-layer{padding:10px;border: 1px solid #ddd;border-top:0;display:none;left:0px;top:22px;position:absolute;z-index: 1;background:#fff;min-width: 320px;border: 1px solid #ddd;} +.wst-filters .item .dorp-down-layer div.cat1,.wst-address .item .dorp-down-layer div.cat1{float:left;width:140px; overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +.wst-filters .item .dorp-down-layer div.cat2,.wst-address .item .dorp-down-layer div.cat2{float:left;width:80px; overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +.wst-filters .item .dorp-down-layer div:hover,.wst-filters .item .dorp-down-layer a:hover{color:#df2003;cursor:pointer;} +.wst-address .item .dorp-down-layer div:hover,.wst-address .item .dorp-down-layer a:hover{color:#ff8043;;cursor:pointer;} +.wst-filters .item .v-item,.wst-address .item .v-item{float:left;color:#666;border: 1px solid #ddd;cursor: pointer;display: inline-block;font-size: 12px;height: 22px;line-height: 22px;margin: 0 5px 5px 0;padding: 0 30px 0 4px;position: relative;vertical-align: top;} +.wst-filters .item .v-item:hover,.wst-address .item .v-item:hover{border-color: #e4393c;} +.wst-filters .item .v-item i,.wst-address .item .v-item i{ display: block;position: absolute; width: 25px;height: 22px;right: 0;text-align:center;font-style: normal;top: 0;} +.wst-filters .item .v-item:hover i,.wst-address .item .v-item:hover i{background-color: #e4393c;color: #fff;} +.wst-filters .keyword,.wst-address .keyword{height:22px;line-height:22px;} +.wst-selector{width:1200px;margin-left: auto;margin-right: auto;margin-top:10px;color:#999;} +.wst-selector .head{padding-left:10px;background: #f1f1f1 none repeat scroll 0 0;border-bottom: 1px solid #ddd;height: 34px;line-height: 34px;overflow: hidden;} +.wst-selector .main{} +.wst-selector .item{border-bottom: 1px solid #ddd;line-height: 90px;width:1200px;height:auto;border-bottom: 1px solid #ddd;} +.wst-selector .label{float:left;width:90px;padding-left:10px;} +.wst-selector .content{float:left;width:990px;height: 90px;overflow: hidden;} +.wst-selector .content .s-item{float:left;margin-right:50px;color:#666;cursor:pointer} +.wst-selector .extra{float:left;width:110px;margin-top: 5px;} +.extra_more{float: left;margin-right: 10px;position: relative;width: 39px;height: 23px;line-height: 23px;padding: 0 7px 0 4px;background: #fff;visibility: hidden;color: #333;border: 1px solid #ddd;} +.extra_multi{float: left;height: 23px;line-height: 23px;border: 1px solid #DDD;padding: 0 3px 0 18px;position: relative;background: #fff;color: #333;} +.extra_multi i,.extra_more i{position: absolute;display: block;font-style: normal;width: 13px;height: 20px;background-image: url(../img/search.png);transition:all ease 0.2s;} +.extra_more i{top: 1px;right: 2px;width: 20px;background-position: 4px 7px;} +.extra_more:hover,.extra_more:hover i{color:red;background-position: 4px -10px;} +.extra_multi:hover,.extra_multi:hover i{border-color: red;color:red;background-position: 0px -84px;} +.extra_more_on i{background-position: 4px -27px!important} +.extra_more_on:hover i{background-position: 4px -44px!important} +.extra_multi i{left: 3px;top: 1px;background-position: 0 -63px;} +.multi_on{border: 2px solid #edd28b!important;background: #fffdee;height: 120px;width:1195px!important;} +.multi_btns{width: 100%;text-align: center;margin: 10px 0;} +.multi_btns a{display: inline-block;padding: 0px 7px;border: 1px solid #ddd;color: #666;background-color: #f7f7f7;border-radius: 2px;} +.multi_btns .confirm_btn{background-color: #E74649;color: #fff;margin-right: 10px;visibility:hidden;} +.multi_btns .disable_btn{background-color: #ddd;color: #fff;} +.s-item i{position: absolute;left: 0;top: 2px;background: url(../img/search.png) no-repeat 9999px 9999px;display: inline-block;height: 12px;width: 12px;background-color: #fff;border: 1px solid #ccc;font-size: 0;visibility: hidden;} +.selected i{border-color: #e4393c;background-position: -1px -107px!important;} +.multi_on .s-item i{visibility: visible;} +.s_chk{padding-left: 18px;position:relative} +.brand_itembox{padding: 1px 0!important;height: 70px;margin: 10px 0;} +.brand_item{width: 10%;border: 1px solid #DDD;margin: -1px -1px 0 0!important;height:80px;overflow:hidden;text-align: center;background-color: #fff;} +.brand_item a.s_chk{visibility: hidden!important;} +.brand_itembox .selected{position: relative;z-index: 10;border-color: #e4393c!important;} +.brand_itembox .selected .g_bd_imgbox{border-color: #e4393c;} +.brand_item:hover{position: relative;z-index: 10;border-color: #e4393c;box-shadow: 2px 2px 3px rgba(0,0,0,.12);} +.brand_item:hover .g_bd_imgbox{border-color: #e4393c;color:#e4393c} +.brand_item:hover .g_bd_img{display: none;} +.g_bd_img{width: 100%;height: 100%;} +.g_bd_imgbox{border:1px solid transparent;width:98%;height:80px;line-height: 80px;} +.wst-selector .item-more-box{border-top: 1px solid #ddd;position: relative;text-align: center;top: -1px;transition: border-color 0.15s ease-in-out 0s;} +.wst-selector .item-more-box .item-more{position: relative;top:-1px;border-top:0px;padding:0 40px 0 20px;background: #fff none repeat scroll 0 0;border-color: #fff #ddd #ddd; border-style: solid;border-width: 1px;color: #333;cursor: pointer;display: inline-block;height: 28px;line-height: 28px;position:relative;} +.wst-selector .item-more-box .item-more i{display: inline-block;width: 20px;height: 20px;vertical-align: top;background: url(../img/search.png) no-repeat;position:absolute;top:3px;} +.wst-selector .item-more-box .item-more i.drop-down{background-position: 4px 7px;} +.wst-selector .item-more-box .item-more i.down-hover{background-position: 4px -11px;} +.wst-selector .item-more-box .item-more i.drop-up{background-position: 4px -27px;} +.wst-selector .item-more-box .item-more i.up-hover{background-position: 4px -44px;} +.wst-selector .item-more-box .item-more i.drop-down-icon{background-position: 4px -9px;} +.wst-selector .item-more-box:hover {border-color: #e4393c;} +.wst-selector .item-more-box:hover .item-more {border-color: #fff #e4393c #e4393c;color: #e4393c;} +.wst-container .goods-side{float:left;width:210px;margin-top:10px;margin-right:5px;} +.wst-container .goods-side .title{line-height:35px;background-color: #f7f7f7;text-align: center;} +.wst-container .goods-side .guess-like{min-height:300px;border:1px solid #eee;padding-bottom:10px;} +.wst-container .goods-side .item{padding-top:10px;} +.wst-container .goods-side .item .img{width:200px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.wst-container .goods-side .item .img a{display:table-cell;vertical-align:middle;width:200px; height:200px;} +.wst-container .goods-side .item .img a img{max-width:190px;max-height:190px;} +.wst-container .goods-side .item .p-price{padding:5px;font-weight: bold;color:#C00;font-size:14px;} +.wst-container .goods-side .item .v-price{text-decoration: line-through;color:#999;margin-left: 10px;font-weight: normal;font-size:12px} +.wst-container .goods-side .hot-goods{min-height:300px;border:1px solid #eee;margin-top: 15px;padding-bottom:10px;} +.wst-container .goods-main{float:right;width:980px;margin-top:10px;position: relative;} +.goods-main .goods-filters{border-top: 1px solid #ddd;margin-bottom: 5px;position: relative;z-index:4;} +.goods-main .goods-filters .line{padding:5px;height:25px;border-bottom: 1px solid #e5e5e5;} +.goods-main .goods-filters .line2{background:#f7f7f7;} +.goods-filters .line2 a{background: #fff none repeat scroll 0 0;border: 1px solid #e9e7e7;color: #333;float: left;height: 23px;line-height: 23px;padding: 0 20px;} +.goods-filters .line2 a:hover{border:1px solid #DF2003;} +.goods-filters .line .city{float:left;width:auto;} +.goods-filters .line .chk{float:left;height: 23px;line-height: 23px;margin-right:10px;} +.goods-filters .line a.curr {background: #DF2003 none repeat scroll 0 0;border: 1px solid #DF2003;color: #fff;} +.goods-filters .line .store,.goods-filters .line .store2,.goods-filters .line .store3{float:right;width:16px;height:13px;margin:5px 0px 0px 3px;} +.goods-filters .line .store{background:url(../img/store_icon_sx.png) 0px 0px no-repeat;} +.goods-filters .line .store2{background:url(../img/store_icon_sx_sel.png) 0px 0px no-repeat;} +.goods-filters .line .store3{background:url(../img/store_icon_sx_sel_up.png) 0px 0px no-repeat;} +.wst-price-ipts{float:left;position: relative;} +input.wst-price-ipt{width:66px;height: 19px;outline: none;padding-left:18px;border: 1px solid #e9e7e7;} +input.wst-price-ipt:focus{border: 1px solid #ff8043;} +.wst-price-ipt1{position: absolute;left: 14px;top: 4px;} +.wst-price-ipt2{position: absolute;right: 74px;top: 4px;} +.wst-price-but{outline: none;background:#f7f7f7;color: #9f9696;border: 1px solid #dad7d7;cursor:pointer;} +.wst-price-but:not(.disabled):not(:disabled):active, .wst-price-but.active{background: #f1f1f1;background-clip: padding-box;} +.goods-list{width:100%;} +.goods-list .goods{width:233px;margin:5px 4px 5px 6px;border:1px solid #eee;float:left;height:430px;} +.goods-list .goods:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd;} +.goods-list .goods .img{width:233px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.goods-list .goods .img a{display:table-cell;vertical-align:middle;width:233px; height:233px;} +.goods-list .goods .img a img{max-width:210px;max-height:210px;} +.goods-list .goods .p-price{height:26px;line-height:26px;padding:5px 0px 5px 12px;font-weight: bold;color:#C00;font-size:14px;width:113px;float:left;overflow: hidden;} +.goods-list .goods .p-hsale{padding:5px 12px 5px 0;width:93px;float:right;text-align: right;} +.goods-list .goods .p-hsale span{font-weight: bold;color:#df2003;} +.goods-list .goods .p-hsale .p-add-cart{line-height: 24px;display: block;border: 1px solid #DF2003;width: 75px;height: 24px;text-align: center;color: #DF2003;float: right;} +.goods-list .goods .p-hsale .p-add-cart:hover{background: #DF2003;color: white;} +.goods-list .goods .p-name{height: 40px;line-height: 20px;overflow: hidden;width:210px;margin-left:12px;} +.goods-list .goods .p-shop{padding:5px 5px 5px 12px;position: relative;} +.goods-list .goods .p-shop .contrast{position: absolute;padding-left: 17px;top:5px;right:10px;z-index: 1;} +.goods-list .goods .p-shop .contrast:hover{color:#e4393c;} +.goods-list .goods .p-shop .contrast i{position: absolute;top: 3px;left: 0;width: 14px;height: 14px;background: url(../img/contrast.png) 0 0 no-repeat;background-size: 100%;} +.goods-list .goods .p-mprice{color:#999;padding:5px 0px 5px 12px;width:113px;float:left;} +.goods-list .goods .p-mprice span{text-decoration: line-through;} +.goods-list .goods .p-appraise{padding:5px 5px 5px 0px;width:100px;float:right;text-align: right;} +.goods-list .goods .p-appraise span{font-weight: bold;color:#1499E5;} +.goods-list .goods .tags{padding-left:10px;} +.goods-list .goods .tags .tag{background:#DF2003;color:#ffffff;padding:0px 4px 1px 4px;margin-right:5px;border-radius:8%} +.img_list{padding-left: 5px;} +.img_list li{float:left;width: 25px;height: 25px;margin-right: 2px;box-sizing:border-box;} +.img_list li.curr{border: 1px solid red;} +.img_list li img{max-width: 100%;max-height: 100%;} +.wst-recommend,.wst-relook{margin-bottom: 20px;height:410px;border:1px solid #ddd;} +.wst-recommend .title,.wst-relook .title, .wst-gview .title{line-height:35px;background-color: #f7f7f7;padding:0 10px;border-top:2px solid #ddd;} +.tgoods-list{width:100%;} +.tgoods-list .goods{width:230px;margin:5px 0px 5px 6px;border:1px solid #ddd;float:left;} +.tgoods-list .goods:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd; } +.tgoods-list .goods .img{width:230px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.tgoods-list .goods .img a{display:table-cell;vertical-align:middle;width:230px; height:230px;} +.tgoods-list .goods .img a img{max-width:223px;max-height:223px;} +.tgoods-list .goods .p-price{padding:5px 0px 5px 5px;font-weight: bold;color:#df2003;width:120px;float:left;font-size:14px;} +.tgoods-list .goods .p-hsale{padding:5px 5px 5px 0;width:100px;float:right;text-align: right;} +.tgoods-list .goods .p-hsale span{font-weight: bold;color:#df2003;} +.tgoods-list .goods .p-hsale .p-add-cart{line-height: 15px;display: block;border: 1px solid #ff6a53;width: 75px;height: 15px;text-align: center;color: #ff6a53;float: right;} +.tgoods-list .goods .p-hsale .p-add-cart:hover{background: #ff6a53;color: white;} +.tgoods-list .goods .p-name{height: 40px;line-height: 20px;overflow: hidden;padding:0 5px;} +.tgoods-list .goods .p-shop{padding:5px;} +.tgoods-list .goods .p-mprice{color:#999;padding:5px 0px 5px 5px;width:120px;float:left;} +.tgoods-list .goods .p-mprice span{text-decoration: line-through;margin-left: 10px;font-weight: normal;} +.tgoods-list .goods .p-appraise{padding:5px 5px 5px 0;width:100px;float:right;text-align: right;} +.tgoods-list .goods .p-appraise span{font-weight: bold;color:#1499E5;} +.wst-gview{margin-top:10px;]margin-bottom: 20px;height:270px;border:1px solid #ddd;} +.wst-gview .view-goods .item{float:left;position:relative;width:162px; margin: 5px 0px 5px 6px;border:1px solid #eeeeee;float:left;} +.wst-gview .view-goods .item:hover{border:1px solid #ddd;-webkit-box-shadow:0 0 10px #ddd; -moz-box-shadow:0 0 10px #ddd; box-shadow:0 0 10px #ddd; } +.wst-gview .view-goods .item .img{width:156px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative; display:table-cell; padding:4px;} +.wst-gview .view-goods .item .img a{display:table-cell;vertical-align:middle;width:156px; height:156px;} +.wst-gview .view-goods .item .img a img{max-width:156px;max-height:156px;} +.wst-gview .view-goods .item .p-price{padding:5px;font-weight: bold;color:#df2003;} +.wst-gview .view-goods .item .v-price{text-decoration: line-through;color:#999;margin-left: 6px;font-weight: normal;} +/*自定义复选框-列*/ +.checkbox-box-s{float:left;width:15px;height:20px;margin-top: 3px;} +.wst-checkbox-s + label {-webkit-appearance: none;background-color: #ffffff;border: 1px solid #d5d5d5;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox-s + label:after {content: '\2714';color: #ccc;font-size: 13px;position: absolute;top: -5px;left: 1px;} +.wst-checkbox-s:checked + label{border: 1px solid #ff8043;/* 修改选框选中颜色*/} +.wst-checkbox-s:checked + label:after {content: '\2714';color: #ff8043;font-size: 13px;position: absolute;top: -5px;left: 1px;} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-6px;top:-1px;} +.checkbox-box-s label{position: relative;top:-24px;left:-4px;} +.wst-no-goods{height: 50px;line-height:50px;color:red;text-align:center;font-weight:bold;} +.wst-no-goods span{color:#999;} +/*发货地*/ +.tab-header{border-bottom:2px solid #df2003;width: 100%;height:20px;background: #fff;} +.tab li{display:block;margin:0px;float:left;background-color:#fff;height:20px;} +.tab-item1 a{background: #fff;color:gray;border:1px solid #ddd;float:left;min-width:80px;width:auto;text-align: center;} +.j-tab-selected1 a{background: #fff;border:2px solid #df2003;border-bottom: #fff solid 2px;} +.area{float: left;overflow: hidden;padding: 4px 8px;text-overflow: ellipsis;white-space: nowrap;width: 80px;} +.area-box li{float:left;width:80px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;padding: 4px 8px;} +/*商品对比*/ +.wst-contrast{width: 100%;padding-top: 20px;padding-bottom: 29px;} +.wst-contrast .goods{background: #fff;} +.wst-contrast .goods .table,.wst-contrast .table2{width: 100%;border-collapse: collapse;table-layout: fixed;border-top: 1px solid #e4e4e4;border-left: 1px solid #e4e4e4;margin-top: -1px;} +.wst-contrast .goods .table td,.wst-contrast .goods .table th{padding: 20px 0 16px;border-right: 1px solid #e4e4e4;border-bottom: 1px solid #e4e4e4;line-height: 24px;font-family: SimSun;background: #fff;} +.wst-contrast .goods .table th{width: 125px;text-align: right;font-weight: 400;background: #f7f7f7;color: #999;} +.wst-contrast .choice{margin-left: 10px;margin-bottom: 10px;text-align: left;} +.wst-contrast .choice input{margin-right: 5px;vertical-align: middle;} +.wst-contrast .choice label {display: inline-block;height: 16px;line-height: 16px;vertical-align: middle;color: #666;} +.wst-contrast .goods-item{width: 200px;margin: 0 auto;} +.wst-contrast .goods-item:hover .operation .del{opacity: 1;} +.wst-contrast .goods-item .img{width: 100%;height: 160px;text-align: center;} +.wst-contrast .goods-item .img img{width: 160px;border: 0;vertical-align: middle;} +.wst-contrast .goods-item .name{height: 32px;overflow: hidden;margin-top: 10px;line-height: 16px;color: #333;} +.wst-contrast .goods-item .price{height: 28px;line-height: 28px;margin-top: 10px;font-family: "Microsoft YaHei";font-size: 14px;color: #e4393c;} +.wst-contrast .goods-item .price span{font-size: 20px;font-weight: 400;} +.wst-contrast .goods-item .operation{position: relative;width: 100%;height: 30px;margin-top: 13px;} +.wst-contrast .goods-item .operation .see{display: block;margin-bottom: 10px;width: 80px;height: 30px;line-height: 30px;text-align: center;background: #e4393c;color: #fff;} +.wst-contrast .goods-item .operation .see:hover{background: #e75153;} +.wst-contrast .goods-item .operation .del{position: absolute;right: 0;top: 5px;font: 12px/20px SimSun;opacity: 0;} +.wst-contrast .goods-item .operation .del:hover{color: #e4393c;} +.wst-contrast .goods-fixed{position: fixed;top: 0;z-index: 100;left: 50%;width: 1200px;margin-left: -600px;} +.wst-contrast .goods-fixed .img{float:left;width: 100px;height: 100px;} +.wst-contrast .goods-fixed .img img{width: 90px;margin-top: 5px;} +.wst-contrast .goods-fixed .name{display: none;} +.wst-contrast .goods-fixed .price,.wst-contrast .goods-fixed .operation{float:left;width: 100px;} +.wst-contrast .goods-fixed .operation .del{right:-16px;} +.wst-contrast .goods-fixed2{display: none;} +.wst-contrast .goods-fixed2 th{height: 126px;} +.wst-contrast .table2 td,.wst-contrast .table2 th{padding: 20px 0 16px;border-right: 1px solid #e4e4e4;border-bottom: 1px solid #e4e4e4;line-height: 24px;font-family: SimSun;background: #fff;} +.wst-contrast .table2 th {width: 125px;text-align: right;font-weight: 400;background: #f7f7f7;color: #999;} +.wst-contrast .table2 .left-title{margin-right: 36px;} +.wst-contrast .table2 .right-title{padding-left: 35px;width: 200px;overflow: hidden;word-wrap: break-word;} +.wst-contrast .table2 .list-box{width: 200px;padding-left: 35px;} +.wst-contrast .table2 .list-box li{float: left;height: 29px;line-height: 29px;padding: 0 13px;border: 1px solid #d7d7d7;margin-right: 6px;margin-bottom: 6px;cursor: pointer;} +.wst-contrast .table2 .list-box li.img{padding:0;height: 40px;} +.wst-contrast .table2 .list-box li img{width: 40px;height: 40px;} +.wst-contrast .table2 .list-box li:hover{color: #e4393c;} +.wst-contrast .table2 .list-box li.active{color: #e4393c;border-color: #e4393c;} +.wst-contrast .table2 .identical_0.active td{background: #f4f9fd;} +.wst-contrast .table2 .identical_1.active{display: none;} +/*商品对比*/ +.wst-cont-frame{position: fixed;bottom: -200px;right: 50%;margin-right: -602px;z-index: 100;width: 986px;height: 139px;background: #fff;-moz-box-shadow: 0 0 15px rgba(221,221,221,0.8);-webkit-box-shadow: 0 0 15px rgba(221,221,221,0.8);box-shadow: 0 0 15px rgba(221,221,221,0.8);-webkit-transition: all .2s linear;transition: all .2s linear;} +.wst-cont-frame.show{bottom: 0;} +.wst-cont-frame .head{height: 32px;border: 1px solid #ddd;border-bottom: 2px solid #e23c3d;position: relative;} +.wst-cont-frame .head span{float: left;width: 80px;height: 36px;line-height: 30px;text-align: center;font: 14px/30px 'microsoft yahei';position: relative;left: -1px;margin-top: -4px;background: #fff;border: 2px solid #e23c3d;border-bottom: 0;color: #e23c3d} +.wst-cont-frame .head .close{text-align: right;position: absolute;right: 0;top: 0;padding-right: 22px;height: 30px;line-height: 30px;color: #005aa0;} +.wst-cont-frame .list{border: 2px solid #e23c3d;border-top: none;position: relative;} +.wst-cont-frame .goods{padding: 6px;color: #ccc;height: 90px;overflow: hidden;} +.wst-cont-frame .term{float: left;overflow: hidden;margin-right: 10px;padding: 17px 10px 12px 0;border-right: 1px dotted #e23c3d;} +.wst-cont-frame .term:hover .info .price a{opacity: 1;} +.wst-cont-frame .term .img{float: left;margin-right: 5px;width: 48px;height: 48px;text-align: center;border: 1px solid #fff;overflow: hidden;} +.wst-cont-frame .term .info,.wst-cont-frame .list .term-empty .info{float: left;width: 140px;} +.wst-cont-frame .term .info .name{height:36px;line-height: 18px;overflow: hidden;display: block;color: #333;} +.wst-cont-frame .term .info .price span{color: #e4393c;font-size: 14px;font-family: Verdana;font-weight: bold;} +.wst-cont-frame .term .info .price a{padding-left: 10px;color: #005aa0;opacity: 0;} +.wst-cont-frame .term-empty{float: left;overflow: hidden;margin-right: 10px;padding: 17px 10px 12px 0;border-right: 1px dotted #e23c3d;} +.wst-cont-frame .term-empty .img{float: left;margin-right: 5px;width: 48px;height: 48px;text-align: center;color: #ccc;border: 1px solid #fff;font: 36px/48px arial;overflow: hidden;background: #f6f6f6;} +.wst-cont-frame .term-contrast{position: absolute;right: 22px;top: 22px;width: 85px;text-align: center;} +.wst-cont-frame .term-contrast .contrast{display: block;margin: 0 auto;margin-bottom: 10px;font: bold 14px/30px verdana;width: 60px;height: 30px;line-height: 30px;text-align: center;background: #e4393c;color: #fff;} +.wst-cont-frame .term-contrast .contrast:hover{background: #e75153;} +.wst-cont-frame .term-contrast .empty{color: #005aa0;} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/index.css b/hyhproject/home2/view/default/css/index.css new file mode 100755 index 0000000..eb7daef --- /dev/null +++ b/hyhproject/home2/view/default/css/index.css @@ -0,0 +1,2299 @@ +@CHARSET "UTF-8"; +#wst-slide .wst-slide-itemswrap, +#wst-slide .wst-slide-items, +#wst-slide .wst-slide-items li { + height: 420px; + overflow: hidden +} + +.wst-slide-controls { + position: absolute; + text-align: right; + top: -40px; + left: 50%; + transform: translateX(-50%); +} + +.wst-slide-controls span { + width: 24px; + height: 24px; + text-align: center; + display: inline-block; + line-height: 24px; + border-radius: 12px; + background-color: #333; + color: white; + cursor: pointer +} + +.wst-slide-controls .curr { + background-color: #e13335; + border-radius: 12px; + color: white; + cursor: pointer +} + +.wst-slide { + position: relative; + top: 2px +} + +.wst-slide-numbox { + width: 1200px; + margin: 0 auto; + height: 0; + position: relative; + z-index: 3 +} + +.wst-slide-items { + min-width: 1200px +} + +.wst-tab-box { + overflow: hidden; + border-right: 1px solid #eee; + width: 100%; + height: auto; + margin: 0 auto; + background: #fff +} + +.wst-tab-nav { + overflow-y: hidden; + margin: 0; + padding: 0; + height: 35px; + top: 0; + z-index: 30; + background: #fff; + width: 100%; + border-bottom: 1px solid #eee; + border-left: 1px solid #eee +} + +.wst-tab-nav li, +.wst-tab-nav .tab { + width: 40%; + cursor: pointer; + float: left; + margin: 0; + list-style: none; + border: 1px solid #eee; + border-bottom: 0; + border-left: none; + line-height: 34px; + text-align: center; + color: #000; + padding-left: 10px; + padding-right: 10px +} + +.wst-tab-nav .on { + border-top: 1px solid #ff2704; + border-bottom: 1px solid #fff; + color: #ff2704; + font-weight: bold +} + +.wst-tab-content { + padding: 5px; + width: 99%; + height: auto; + border: 1px solid #eee; + border-top: 0; + background: #FFF +} + +#wst-right-news { + width: 100%; + height: 30px; + background: #df2002; + line-height: 25px; + color: #fff +} + +#wst-right-news>p { + float: left; + margin-left: 12px; + font-weight: bold +} + +#wst-right-news>a { + display: block; + float: right; + color: #fff; + margin-right: 5px +} + +#wst-right-new-list { + height: 117px; + background-color: #fff +} + +#wst-right-new-list>div { + width: 190px; + height: 23px; + line-height: 25px; + padding-left: 10px; + white-space: nowrap; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + list-style-type: disc +} + +#wst-right-new-list>div>a { + color: #605e5e +} + +#wst-right-new-list>div>a:hover { + color: #df2002 +} + +.visitor-new-list { + height: 118px!important; + overflow: hidden; + border: 0; + background-color: #fff +} + +.visitor-new-list>li { + height: 23px!important +} + +.apply-btn { + background: url(../img/apply.png) no-repeat 0 0; + background-size: cover; + display: block; + width: 180px; + height: 60px; + margin: 20px auto 10px +} + +.shop-login { + margin-left: 60px; + height: 28px; + display: block; + color: #999 +} + +.ws-right-user { + display: block; + width: 210px; + height: 128px; + background: #fff +} + +.ws-right-user .top, +.ws-right-user .bottom { + float: left +} + +.ws-right-user .top img { + float: left; + width: 65px; + height: 65px; + margin: 10px; + border-radius: 1000px +} + +.ws-right-user .top .name { + float: left; + width: 125px +} + +.ws-right-user .top .uname { + height: 23px; + line-height: 25px; + width: 100px; + margin: 0 auto; + margin-top: 15px; + text-align: center; + color: #ff2704; + font-size: 14px; + font-family: "microsoft yahei"; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.ws-right-user .top .sign { + display: block; + width: 105px; + height: 30px; + line-height: 30px; + margin: 0 auto; + margin-top: 10px; + color: #fff; + background-color: #ff0c00; + border: 1px solid #ff0c00; + cursor: pointer; + border-radius: 5px; + box-shadow: 0 2px 0 #c3443d; + position: relative; + -webkit-transition: all .2s linear; + transition: all .2s linear +} + +.ws-right-user .top .sign:hover { + background-color: #ee4419 +} + +.ws-right-user .top .sign:focus { + outline: 0 +} + +.ws-right-user .top .sign .plus { + position: absolute; + top: 0; + width: 100%; + left: 0; + font-size: 18px; + color: #f4cf00; + font-style: normal; + opacity: 0; + text-align: center; + -webkit-transition: all .5s linear; + transition: all .5s linear +} + +.ws-right-user .top .active .plus { + top: -36px; + opacity: 1 +} + +.ws-right-user .top .actives .plus { + top: -36px; + opacity: 0; +} + +.ws-right-user .top .actives, +.ws-right-user .top .actives:hover { + color: #747171; + background-color: #eee; + border: 1px solid #ddd; + box-shadow: 0 2px 0 #ddd; +} + +.ws-right-user .bottom .left { + float: left; + width: 110px; + margin-top: 10px; + padding-left: 10px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden +} + +.ws-right-user .bottom .right { + float: right; + width: 80px; + margin-top: 10px; + padding-left: 10px +} + +#wst-right-ads { + position: relative; +} + +#wst-right-ads>a>img { + width: 210px; + height: 128px; + display: block; +} + +.floor-box { + width: 100%; + margin-top: 15px; + clear: both +} + +.goods-list { + width: 100% +} + +.goods-list .goods { + width: 239px; + float: left; + height: 284px; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} + +.goods-list .goods:hover { + width: 239px; + height: 284px; + -webkit-box-shadow: 0 0 10px #cfcfcf; + -moz-box-shadow: 0 0 10px #cfcfcf; + box-shadow: 0 0 10px #cfcfcf; +} + +.goods-list .goods:hover .img a img { + transform: scale(1.05); +} + +.goods-list .goods:hover .p-name a { + color: #d82a2e; +} + +.goods-list .goods .img { + text-align: center; + position: relative; +} + +.goods-list .goods .img a { + display: block +} + +.goods-list .goods .img a img { + max-width: 180px; + max-height: 180px; + padding-top: 20px; + padding-bottom: 8px; + transition: transform .4s ease, -webkit-transform .4s ease, -moz-transform .4s ease, -o-transform .4s ease +} + +.goods-list .goods .p-price { + font-weight: 600; + color: #C00; + text-align: center; + margin-top: 3px; + font-size: 14px +} + +.goods-list .goods .p-name { + height: 40px; + line-height: 20px; + overflow: hidden; + width: 208px; + margin: 0 auto; + text-align: center +} + +.goods-list .goods .p-shop { + padding: 5px +} + +.goods-list .goods .p-mprice { + color: #999; + padding: 5px 0 5px 5px; + width: 120px; + float: left +} + +.goods-list .goods .p-mprice span { + text-decoration: line-through; + margin-left: 10px; + font-weight: normal +} + +.goods-list .goods .p-appraise { + padding: 5px 5px 5px 0; + width: 100px; + float: right; + text-align: right +} + +.goods-list .goods .p-appraise span { + font-weight: bold; + color: #1499e5 +} + +.floor-top-ads { + margin: 40px 0 0; + width: 1200px +} + +.floor-top-ads a { + float: left +} + +.floor-top-ads img { + width: 400px; + height: 110px +} + +.floor-header { + width: 100%; + height: 38px; + background: white; + margin-top: 20px; + border-bottom: 1px solid #df2002 +} + +.floor-header-f1, +.floor-header-f2, +.floor-header-f3, +.floor-header-f4, +.floor-header-f5, +.floor-header-f6, +.floor-header-f7, +.floor-header-f8, +.floor-header-f9, +.floor-header-f10 { + float: left; + background: url(../img/img_floor_titlebg.png) no-repeat 0; + height: 100%; + width: 23%; + margin-top: 1px +} + +.floor-header .tab { + float: right; + margin-right: 10px; + margin-top: 7px +} + +.floor-header .tab li { + display: block; + margin: 0; + float: left +} + +.floor-header .tab a { + font-size: 13px; + display: block; + height: 15px; + letter-spacing: 1px +} + +.floor-header .tab-item1 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected1 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item2 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected2 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item3 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected3 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item4 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected4 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item5 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected5 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item6 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected6 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item7 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected7 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item8 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected8 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item9 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected9 a { + background-color: #df2002; + color: #fff +} + +.floor-header .tab-item10 a { + padding: 8px 12px 8px 12px +} + +.floor-header .j-tab-selected10 a { + background-color: #df2002; + color: #fff +} + +.floor-left { + float: left; + width: 20%; + height: 620px +} + +.floor-left-ads { + width: 478px; + height: 224px +} + +.floor-left-ads img { + width: 478px; + height: 224px +} + +.floor-left-title { + margin-left: 1px; + color: #fff; + font-size: 15px; + float: left; + margin-top: 13px; + position: absolute; +} + +.floor-right-title { + float: right; + color: #333; + font-size: 16px; + line-height: 38px; + margin-right: 70px; + font-weight: bold; + letter-spacing: 2px; +} + +.one_flimit { + overflow: hidden; + width: 79%; + white-space: nowrap; + text-overflow: ellipsis; +} + +.floor-right { + float: left; + width: 100%; + min-height: 570px +} + +.floor-right-ads { + width: 478px; + float: left; + border-bottom: 1px solid #eee; + border-right: 1px solid #eee; + border-left: 1px solid #eee +} + +.wst-floor-slide-items { + overflow: hidden; + height: 344px; + width: 478px; + position: relative +} + +.wst-floor-slide-items img { + height: 344px; + width: 478px +} + +#screen-left-nav { + width: 35px; + max-height: 335px; + position: fixed; + top: 40%; + left: 15%; + background: #fff; + z-index: 999; + display: block +} + +.lnav { + margin: 0 auto; + background: #fff; + line-height: 30px; + text-align: center; + overflow: hidden; + margin-top: -1px; + cursor: pointer; + display: block; + width: 30px; + height: 29px; + color: #625351; + transition: all .2s ease-in; + -moz-transition: all .2s ease-in; + -webkit-transition: all .2s ease-in; + -o-transition: all .2s ease-in; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpFNDg5NURBNDY3MjA2ODExODIyQUVDNTgwRDU1MkZBQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1N0M3MTMzQTlBRTQxMUU0OEY2QkNDMkMzNDJCRDdGNiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1N0M3MTMzOTlBRTQxMUU0OEY2QkNDMkMzNDJCRDdGNiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6ODBkOTE3NzktZTE1Yi0yNTRkLTljYzMtOGVjNmE4ZTAyMjRjIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjIxNzkxODUyODJEQjExRTQ4RkM0REQwQTBFRkQyNTY2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+3tRxHgAAAAlQTFRFwsLCycnJ////r0pOrgAAAAN0Uk5T//8A18oNQQAAAB5JREFUeNpiYIIABhTIyAQXxgtGpUelR6VpKw0QYACUOgb65Nz92gAAAABJRU5ErkJggg==) 0 25px no-repeat +} + +.lcurr { + background: #df2003 +} + +.lcurr a { + color: white +} + +.wst-floor-slide-numbox span { + background-color: #d4d4d4; + cursor: pointer; + display: inline-block; + height: 4px; + width: 24px; + border-radius: 1.5px +} + +.wst-floor-slide-numbox .curr { + background-color: #f68d8d +} + +.wst-floor-slide-numbox>div { + position: relative; + left: 43%; + top: -20px; + z-index: 99; + height: 10px; + max-width: 300px +} + +.floor-bottom .bx_container { + margin-top: 15px +} + +.floor-right-ads .wst-floor-slide-1 { + height: 344px +} + +.ads-lunbobottom { + margin-top: 30px; + margin-bottom: 20px; + overflow: hidden +} + +.ads-lunbobottom a { + float: left +} + +.ads-lunbobottom a img { + width: 240px; + height: 320px +} + + +/* 广告墙 */ + +.ads_wall { + width: 1200px; + max-height: 480px; + margin: 0 auto; + margin-top: 30px; +} + +.ads_wall a { + overflow: hidden; + transition: all ease .4s; + display: block; +} + +.ads_wall a:hover { + transform: scale(1.01); +} + +.ads_wall a img { + width: 100%; + height: 100%; +} + +.ads_wall_l { + width: 448px; + height: 100%; +} + +.ads_wall_c { + width: 292px; + height: 100%; + margin-left: 6px; + position: relative; + text-align: center; +} + +.ads_wall_r { + width: 448px; + height: 100%; +} + +.ads_wall_item_top { + display: block; + width: 100%; + height: 237px; + margin-bottom: 6px; + position: relative; +} + +.ads_wall_item_bottom { + display: block; + width: 100%; + height: 237px; + position: relative; +} + +.ads_wall_more { + text-align: center; + font-size: 12px; + color: #fff; + position: absolute; + bottom: 20px; +} + +.ads_wall_line { + width: 30px; + height: 2px; + background-color: #fff; + margin-top: 8px; + margin-right: 10px; +} + +.wall_r_line { + width: 50px; +} + + +/* 品牌街 */ + +.brand_street_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.bs_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 23px; +} + +.brand_street { + width: 100%; + max-height: 210px; + margin-top: 10px; + box-sizing: border-box; + background-color: #eee; + padding: 5px; +} + +.brand_street li img { + width: 100%; + height: 100px; +} + +.brand_street li { + box-sizing: border-box; + border-right: 1px solid #ddd; + border-bottom: 1px solid #ddd; + width: 10%; + height: 100%; + float: left; + transition: all ease .4s; +} + +.brand_street li:nth-child(10n) { + border-right: none; +} + +.brand_street li:nth-child(n+11) { + border-bottom: none; +} + +.brand_street li:hover { + box-shadow: 0 0 5px #bdbcbc; + transform: scale(1.05); +} + + +/* 店铺街 */ + +.shop_street_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.ss_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 23px; +} + +.shop_street { + width: 100%; + height: 138px; + margin-top: 10px; + background-color: #f4f4f4; + box-sizing: border-box; + padding: 6px; +} + +.shop_street li:nth-child(n+2) { + margin-left: 0.5%; +} + +.shop_street li img { + width: 100%; + height: 100%; +} + +.shop_street li { + background-image: url(../img/shopstreet_bg.png); + background-repeat: no-repeat; + background-size: 100% auto; + width: 19.6%; + height: 100%; + float: left; + transition: all ease .4s; + position: relative; +} + +.shop_street li:hover { + transform: translateY(-5px); +} + +.ss_desc { + position: absolute; + top: 15%; + left: 9%; +} + +.ssd_tit { + font-size: 24px; + color: #ff2b2b; + font-weight: bold; + margin-bottom: 20px; +} + +.ssd_desc { + font-size: 16px; + color: #ff2b2b; +} + +.ss_entry, +.ss_shopname, +.ss_shopaddr { + font-size: 12px; + color: #fff; + position: absolute; +} + +.ss_entry { + left: 5px; + top: 5px; +} + +.ss_shopname { + right: 5px; + top: 5px; +} + +.ss_shopaddr { + right: 5px; + bottom: 5px; +} + + +/* 积分商城 */ + +.intergral_out { + width: 1200px; + margin: 10px auto; + margin-top: 30px; +} + +.itl_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 15px; + margin-bottom: 10px; +} + +.itl_main { + background-color: #f4f4f4; + width: 100%; + height: 148px; + padding: 6px; + box-sizing: border-box; +} + +.itl_bg img { + width: 100%; + height: 100%; +} + +.itl_bg { + display: block; + height: 100%; + width: 238px; +} + +.itl_item:nth-child(2) { + background-color: #fcfdda; +} + +.itl_item:nth-child(3) { + background-color: #ffefd9; +} + +.itl_item:hover img { + transform: translateX(-10px); +} + +.itl_item img { + transition: all ease .4s; + position: absolute; + max-height: 100%; + right: 0; +} + +.itl_item { + display: block; + width: 468px; + height: 100%; + position: relative; + margin-left: 6px; +} + +.itl_name { + position: absolute; + font-size: 14px; + color: #333; + top: 10%; + width: 40%; + left: 5%; + overflow: hidden; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + z-index: 22; +} + +.itl_price_box { + left: 5%; + top: 45%; + position: absolute; + color: #666; + font-weight: bold; + font-size: 16px; + z-index: 22; +} + +.itl_price { + color: #df2002; +} + +.itl_score { + font-size: 12px; + color: #df2002; + font-weight: normal; +} + +.itl_btn { + position: absolute; + padding: 1px 10px; + background-color: #df2002; + border-radius: 25px; + color: #fff; + left: 5%; + top: 75%; + font-size: 11px!important; + background-color: #df2002; + color: #fff; + transition: all ease .4s; +} + +.itl_btn:hover { + transform: translateY(-5px); +} + + +/* 分销商品 */ + +.distribute_tit { + color: #df2002; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-size: auto 18px; + padding-left: 15px; + width: 1200px; + margin: 0 auto; + margin-top: 30px; + font-size: 18px; + letter-spacing: 2px; +} + +.distribute_out { + width: 1200px; + margin: 10px auto; + height: 295px; + background-color: #f4f4f4; + padding: 6px 0; + margin-top: 10px; +} + +.dis_left_bg img { + width: 100%; + height: 100%; +} + +.dis_left_bg { + width: 237px; + height: 100%; + margin-left: 4px; +} + +.dis_list { + width: 952px; + height: 100%; +} + +.dis_list li { + margin-left: 8px; + float: left; + width: 230px; + height: 100%; + position: relative; + background-color: #fff; + overflow: hidden; +} + +.dis_list li:hover img { + transform: scale(1.1); +} + +.dis_list li img { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; + margin: auto; + transition: all ease .4s; +} + +.dis_gprice div { + transform: rotate(30deg); + position: absolute; + left: 11px; + top: 25px; + text-align: center; + right: 4px; + overflow: hidden; +} + +.dis_gprice { + background-image: url(../img/index_distribute_price_bg.png); + background-repeat: no-repeat; + width: 109px; + height: 78px; + position: absolute; + color: #df2002; + font-weight: bold; + right: 0; +} + + +/* 轮播右侧拍卖区域 */ + +.aution_out { + width: 100%; + height: 170px; + position: relative; + background-color: #fff; + overflow: hidden; +} + +.au_l_btn, +.au_r_btn { + position: absolute; + top: 40%; + background-color: rgba(0, 0, 0, .5); + color: #fff; + left: 0; + padding: 5px; + cursor: pointer; + display: none; +} + +.au_r_btn { + left: initial; + right: 0; +} + +.aution_list { + width: 100%; + position: relative; +} + +.aution_tit { + background-image: url(../img/img_floor_titlebg.png); + background-repeat: no-repeat; + background-size: auto 18px; + font-size: 16px; + color: #df2002; + letter-spacing: 2px; + padding-left: 26px; +} + +.aution_main { + float: left; + width: 210px; + height: 153px; + box-sizing: border-box; +} + +.aution_item { + position: relative; + display: block; + text-align: center; + height: 100%; + width: 100%; +} + +.aution_item img { + width: 150px; + height: 150px; +} + +.aution_time { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.3); + font-size: 16px; + color: #fff; + padding: 10px 0; +} + +.aution_h, +.aution_i, +.aution_s { + width: 24px; + height: 30px; + background-color: #df2002; + padding: 5px; + border-radius: 5px; +} + + +/* 优惠券 */ + +.coupon_out { + width: 1200px; + height: 124px; + margin: 0 auto; + margin-top: 30px; + overflow: hidden; +} + +.coupon_bg img { + width: 100%; + height: 100%; +} + +.coupon_bg { + position: relative; + width: 284px; + height: 124px; + display: block; +} + +.coupon_tit { + position: absolute; + font-size: 24px; + color: #c04f02; + right: 25%; + top: 30%; +} + +.r_btn { + position: absolute; + font-size: 16px; + color: #fff; + right: 0%; + top: 16%; + text-align: center; + width: 31px; + line-height: 21px; + padding: 0 6px; +} + +.coupon_desc { + position: absolute; + color: #e08445; + font-size: 18px; + right: 25%; + top: 66%; +} + +.coupon_item img { + width: 100%; + height: 100%; +} + +.coupon_item { + position: relative; + margin-left: 1%; + width: 24%; + height: 100%; +} + +.coupon_item_color { + color: #e21313; +} + + +/* 团购插件 */ + +.groupon_list_out { + position: absolute; + width: 255px; + height: 255px; + bottom: 29px; + left: 11%; + padding: 19px; + box-sizing: border-box; +} + +.groupon_view { + width: 100%; + height: 100%; + overflow: hidden; +} + +.groupon_list { + width: 100%; + height: 100%; + overflow: hidden; + position: relative; +} + +.groupon_list li { + float: left; + width: 217px; + height: 217px; + box-sizing: border-box; +} + +.groupon_btns { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: center; +} + +.groupon_btns .curr { + background-color: #e89593; +} + +.groupon_btns span { + display: inline-block; + width: 7px; + height: 7px; + border-radius: 50%; + background-color: #fff; + margin-left: 3px; +} + + +/* 新品、热销... */ + +.rec_area { + width: 1200px; + height: 500px; + margin: 0 auto; + margin-top: 30px; +} + +.ral { + width: 329px; + height: 100%; + background-repeat: no-repeat; + margin-right: 6px; + position: relative; +} + +.ral_box { + height: 114px; + width: 243px; + background-color: rgba(255, 255, 255, 0.8); + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 60px; + text-align: center; + letter-spacing: 2px; + padding-top: 20px; + box-sizing: border-box; +} + +.ral_box_tit { + font-size: 18px; + color: #010101; +} + +.ral_line { + width: 45px; + height: 2px; + background-color: #000; + margin: 20px auto; +} + +.ral_desc { + font-size: 12px; + color: #000; +} + +.ral img { + width: 100%; + height: 100%; +} + +.rac { + width: 642px; + height: 100%; +} + +.rac_t { + width: 100%; + height: 60%; + box-sizing: border-box; + background-color: #ffefed; +} + +.rac_t_tit, +.rac_b_tit { + font-size: 18px; + color: #df2002; + letter-spacing: 2px; + padding: 5px; +} + +.rac_t_main { + width: 100%; + height: 80%; + margin-top: 10px; + background-color: #fff; +} + +.rac_t_main li:hover img { + transform: scale(1.05); +} + +.rac_t_main li:first-child { + margin-left: 0; +} + +.rac_t_main li { + width: 212.5px; + height: 100%; + margin-left: 2px; + float: left; +} + +.rac_t_img img { + transition: all linear .2s; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; +} + +.rac_t_img { + display: block; + height: 70%; + position: relative; + background-color: #ffefed; +} + +.rac_t_info { + background-color: #ffefed; + height: 29%; + margin-top: 1%; + padding-top: 5%; + padding-right: 1%; + box-sizing: border-box; +} + +.rac_price_color { + color: #df2002; +} + +.c666 { + color: #666; +} + +.del_line { + text-decoration: line-through; +} + +.c14_333 { + font-size: 14px; + color: #333; +} + +.rac_gname { + width: 95%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + padding-left: 5%; +} + +.f10 { + font-size: 10px; +} + +.f12 { + font-size: 12px; +} + +.f14 { + font-size: 14px; +} + +.f16 { + font-size: 16px; +} + +.f88{ + +} + +.rac_price { + margin-top: 5px; + text-align: right; +} + +.rac_b { + width: 100%; + height: 39%; + margin-top: 1%; +} + +.rac_b_l { + width: 295px; + height: 100%; + margin-left: 17.33px; +} + +.rac_bg { + background-color: #f5f5f5!important; +} + +.rac_b_main:hover img { + transform: translateX(-10px); +} + +.rac_b_main { + cursor: pointer; + width: 100%; + height: 150px; + box-sizing: border-box; + margin-top: 13px; + background-color: #fff1f9; + position: relative; +} + +.rac_b_main img { + float: right; + transition: all ease .4s; +} + +.rac_b_info { + position: absolute; + left: 25px; + top: 50px; + z-index: 2; +} + +.mb10 { + margin-bottom: 10px; +} + +.rac_desc { + padding-left: 5px; + width: 95px; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.rac_b_r { + width: 295px; + height: 100%; + margin-right: 17.33px; +} + +.rar { + width: 217px; + height: 100%; + box-sizing: border-box; + background-color: #ffedd8; +} + +.rar_tit { + font-size: 18px; + color: #ffa73b; + letter-spacing: 2px; + padding: 5px; + text-align: center; + margin: 5px; +} + +.rar_glist { + width: 166px; + margin: 0 auto; +} + +.rar_gitem:nth-child(2) { + margin-top: 30px; + background-color: #e5ecff; +} + +.rar_gitem { + width: 100%; + height: 213px; + display: block; + background-color: #ffcd92; + overflow: hidden; + position: relative; +} + +.rar_gitem:hover img { + transform: translateY(-5px); +} + +.rar_gname { + font-size: 14px; + color: #333; + text-align: center; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding-top: 5px; +} + +.rar_gdesc { + padding-top: 3px; + padding-left: 5px; + font-size: 14px; + color: #333; + width: 100%; + word-break: break-all; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.rar_price { + text-align: right; + padding-right: 5px; + position: relative; + z-index: 22; +} + +.rar_line { + width: 70%; + height: 1px; + background-color: #fff; + margin: 5px auto; + margin-bottom: 3px; +} + +.rar_img img { + transition: all ease 0.4s; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; + max-width: 100%; + max-height: 100%; +} + +.rar_img { + width: 100%; + display: block; + height: 65%; + position: relative; +} + +.fl { + float: left; +} + +.fr { + float: right; +} + + +/* 楼层 */ + +.floor_main { + width: 100%; + height: 458px; + box-sizing: border-box; +} + +.fml { + width: 260px; + height: 100%; + position: relative; +} + +.fml img { + width: 100%; + height: 100%; +} + +.f_desc { + font-size: 24px; + color: #fff; + font-weight: bold; + position: absolute; + top: 17%; + left: 17%; +} + +.f1_catbox li { + width: 40%; + float: left; + margin-top: 10px; +} + +.f1_catbox li a { + font-size: 16px; + color: #fff; +} + +.f32 { + font-size: 32px; + vertical-align: sub; +} + +.f1_catbox { + position: absolute; + top: 28%; + left: 13%; +} + + +/* 楼层一个分类 */ + +.fh1 { + border-width: 2px; + position: relative; + margin-bottom: 2px; +} + +.fh1l_titbox { + background-position: 0 6px; + height: 88%; + width: 23%; + position: relative; + top: 7px; +} + +.fh1_tit { + font-size: 18px; + color: #df2002; + font-weight: normal; + float: left; + line-height: 35px; + margin-left: 15%; +} + +.fmr { + width: 934px; + height: 100%; + box-sizing: border-box; +} + +.fmr_glist { + width: 100%; + height: 100%; +} + +.fmr_gitem { + width: 20%; + height: 55%; + display: block; + box-sizing: border-box; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; + transition: all ease .4s; +} + +.fmr_gitem:hover { + box-shadow: 0 0 5px #bdbcbc; + transform: scale(1.01); + z-index: 22; + position: relative; +} + +.fmr_img { + width: 100%; + height: 75%; + box-sizing: border-box; + position: relative; +} + +.fmr_img img { + max-width: 100%; + max-height: 85%; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; +} + +.fmr_gname { + width: 95%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + padding: 0 2.5%; + font-size: 14px; + color: #333; + margin-top: 8px; +} + +.tc { + text-align: center; +} + + +/* 楼层两个分类 */ + +.fh2 { + border-width: 2px; + position: relative; + margin-bottom: 2px; + margin-top: 0px; +} + +.fh2l_titbox { + background-position: 0 6px; + height: 88%; + position: relative; + top: 7px; + width: 38%; +} + +.two_fmilit { + width: 81%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.fh2_tit { + font-size: 18px; + color: #df2002; + font-weight: normal; + float: left; + line-height: 35px; + margin-left: 19%; + margin-right: 0px; +} + +.floor_box2 { + height: 481px; + box-sizing: border-box; + margin-top: 45px; + margin-bottom: 70px; +} + +.fb2_more { + font-weight: bold; + margin-right: -20px; +} + +.fb2_l { + width: 588px; + height: 468px; + box-sizing: border-box; + margin-right: 12px; +} + +.fb2_l_l, +.fb2_r_l { + width: 226px; + height: 438px; + box-sizing: border-box; +} + +.fb2_l_r, +.fb2_r_r { + width: 356px; + height: 438px; + box-sizing: border-box; +} + +.fb2_r { + width: 588px; + height: 468px; + box-sizing: border-box; +} + +.floor_silder { + text-align: center; + position: relative; + margin-top: 35px; +} + +.floor_silder ul { + width: 195px; + height: 225px; + margin: 0 auto; + position: relative; +} + +.floor_silder .img_first { + z-index: 100; + width: 155px; + height: 225px; + left: 20px; + top: 0; + overflow: hidden; +} + +.floor_silder .img_second { + z-index: 90; + width: 175px; + height: 200px; + left: 10px; + top: 15px; + overflow: hidden; +} + +.floor_silder .img_third { + z-index: 80; + width: 195px; + height: 170px; + left: 0px; + top: 30px; + overflow: hidden; +} + +.floor_silder li { + position: absolute; + width: 195px; + height: 225px; + margin: 0 auto; + -moz-border-radius: 4px; + border-radius: 4px; + background-color: #fff; +} + +.floor_silder li a { + display: block; + height: 205px; + padding-top: 20px; +} + +.floor_silder .caption { + height: 20px; + overflow: hidden; + font-size: 16px; + line-height: 20px; +} + +.floor_silder .sub_tit { + height: 30px; + overflow: hidden; + font-size: 14px; + color: #666; + line-height: 30px; +} + +.floor_silder li img { + width: 130px; + height: 130px; + margin-top: 5px; +} + +img { + border: 0 none; + vertical-align: top; +} + +.floor_silder .color_mask { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 225px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.floor_silder .img_first .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=0); + opacity: 0; +} + +.floor_silder .img_second .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=40); + opacity: .4; +} + +.floor_silder .img_third .color_mask { + background-color: #f89d5d; + filter: alpha(opacity=70); + opacity: .7; +} + +.floor_silder .turn_show { + position: absolute; + top: 234px; + left: 80px; + height: 30px; + line-height: 30px; + color: #f8f6f7; +} + +.floor_silder .prev_btn, +.floor_silder .next_btn { + float: left; + text-align: center; + font-size: 14px; + font-weight: bold; + cursor: pointer; +} + +.index_iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: .2px; + -moz-osx-font-smoothing: grayscale; +} + +.floor_silder .show_num { + float: left; + padding: 0 10px; + font-family: "Tahoma"; + font-size: 14px; +} + +.floor_silder .show_num span { + display: inline-block; + width: 3px; + height: 3px; + border: 1px solid #f78a4b; + background-color: #f78a4b; + border-radius: 50%; + margin-left: 2px; +} + +.fh2l { + width: 226px; + height: 428px; + box-sizing: border-box; + margin: 0 auto; + background: linear-gradient(30deg, #f9ab57 0%, #fab775 32%, #f78a4b 100%); +} + +.fh2l_tit { + font-size: 20px; + color: #fffefe; + text-align: center; + padding-top: 30px; +} + +.fh2l_line { + width: 142px; + height: 2px; + background-color: #fff; + margin: 10px auto; +} + +.fh2l_desc { + font-size: 16px; + color: #fffefe; + text-align: center; +} + +.floor_silder .show_num .curr { + border-color: #fff!important; + background-color: #fff!important; +} + + +/*不同楼层左侧商品轮播背景色*/ + +.fh2l .floor_silder .caption { + color: #f78b4b; +} + +.fh2l_2 .floor_silder .caption { + color: #58aaf7; +} + +.fh2l_2 { + background: linear-gradient(30deg, #56abf7 0%, #7ab9f8 32%, #4da5f7 100%); +} + +.fh2l_2 .floor_silder .img_first .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .img_second .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .img_third .color_mask { + background-color: #add7f5; +} + +.fh2l_2 .floor_silder .show_num span { + border-color: #4da5f7; + background-color: #4da5f7; +} + +.fh2l_5 .floor_silder .caption { + color: #f35fa9; +} + +.fh2l_5 { + background: linear-gradient(30deg, #ffddef 0%, #fdafd7 32%, #ff88d1 100%); +} + +.fh2l_5 .floor_silder .img_first .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .img_second .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .img_third .color_mask { + background-color: #f5adc9; +} + +.fh2l_5 .floor_silder .show_num span { + border-color: #ff88d1; + background-color: #ff88d1; +} + +.fh2l_6 .floor_silder .caption { + color: #6562f8; +} + +.fh2l_6 { + background: linear-gradient(30deg, #bcb5fd 0%, #bcb5fd 32%, #9a91fc 100%); +} + +.fh2l_6 .floor_silder .img_first .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .img_second .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .img_third .color_mask { + background-color: #b4b3f5; +} + +.fh2l_6 .floor_silder .show_num span { + border-color: #9a91fc; + background-color: #9a91fc; +} + +.fh2l_8 .floor_silder .caption { + color: #f56363; +} + +.fh2l_8 { + background: linear-gradient(30deg, #f55757 0%, #f87b7b 32%, #f74c4c 100%); +} + +.fh2l_8 .floor_silder .img_first .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .img_second .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .img_third .color_mask { + background-color: #f7b8b8; +} + +.fh2l_8 .floor_silder .show_num span { + border-color: #f74c4c; + background-color: #f74c4c; +} + +.fh2l_9 .floor_silder .caption { + color: #f8b467; +} + +.fh2l_9 { + background: linear-gradient(30deg, #f5a657 0%, #f5bb79 32%, #f5a34b 100%); +} + +.fh2l_9 .floor_silder .img_first .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .img_second .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .img_third .color_mask { + background-color: #f5d3b2; +} + +.fh2l_9 .floor_silder .show_num span { + border-color: #f5a34b; + background-color: #f5a34b; +} + +.fb2_gitem { + width: 50%; + height: 55%; + display: block; + box-sizing: border-box; + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; + transition: all ease .4s; +} + +.fb2_gitem:hover { + transform: scale(1.01); + box-shadow: 0 0 5px #bdbcbc; + z-index: 22; + position: relative; +} + +.fb2_img { + width: 100%; + height: 75%; + box-sizing: border-box; + position: relative; +} + +.fb2_img img { + max-width: 100%; + max-height: 85%; + position: absolute; + left: 0; + right: 0; + margin: auto; + top: 0; + bottom: 0; +} + +/*mar lxy 20180409 惠宝折扣样式*/ +.lxy{ + color: #df2002; + text-align: center; +} + + +/* 猜你喜欢 */ + +.like_goods_list { + margin-top: 55px; + width: 1200px; + height: 600px; + box-sizing: border-box; +} + +.lg_glist { + width: 100%; + height: 90%; +} + +.lg_glist .fmr_gitem { + border: none; +} + +.lg_glist .fmr_gitem { + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} + +.lg_glist .fmr_gitem:nth-child(5n) { + border-right: none; +} + +.lg_glist .fmr_gitem:nth-child(n+6) { + border-bottom: none; +} + +.lg_tit { + margin-bottom: 20px; + height: 30px; + line-height: 30px; + width: 100%; + background-image: url(../img/index_link_bg.png); + background-repeat: no-repeat; + background-position: center center; + text-align: center; + font-size: 18px; + color: #333; +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/login.css b/hyhproject/home2/view/default/css/login.css new file mode 100755 index 0000000..ca487cd --- /dev/null +++ b/hyhproject/home2/view/default/css/login.css @@ -0,0 +1,84 @@ +@CHARSET "UTF-8"; +/*登录*/ +body{margin: 0; +padding: 0;} +.wst-login_l{width: 99.9%; height:525px; background: url(../img/img_user.png) no-repeat top center;} +.wst-login_l_shop{width: 99.9%; height:475px; background: url(../img/img_shop.png) no-repeat top center;} +.wst-login_r{margin-top:3%; margin-right: 4%; padding:30px 100px 20px 46px; float:right; border:1px solid #dad7d7; background: white;box-shadow: 0 0 30px 5px rgba(0,0,0,.4);} +.wst-login-u{margin: 0 auto; width:120px; height:36px; display: block; font-size: 25px; } +input.wst-login-input-1{margin: 1px;float: left; padding:2px; padding-left:5px; font-size: 15px; outline: none; width:269px; height:36px;border:0;} +input.wst-login-input{padding:0px; padding-left:5px; font-size: 15px; outline: none; width:300px; height:36px; border:1px solid #eee;} +input.wst-regist-input{margin: 1px;float: left; padding:2px; padding-left:5px; font-size: 15px; outline: none; width:269px; height:36px;border:1px solid #eee;} +.wst-login-input:focus,.wst-login-input-1:focus,.wst-regist-input:focus,.wst-login-codein-1:focus,.wst-login-codein:focus,.wst-regist-codein:focus,.wst-regist-codemo:focus{ border:1px solid #eb654a; } +.wst-table{margin-top:20px; color: #333;font: 12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif;} +.wst-login-tr{height:30px;} +.wst-login-code-1,.wst-regist-code{height:36px; } input.wst-login-codein-1,input.wst-regist-codein{padding:0px; padding-left:5px; width:150px; height:36px; position:absolute;left: 38px; font-size: 15px; outline: none; border:0; } +.wst-login-codeim-1{margin-left:148px; } +.wst-login-ch{border:1px solid #eb654a; } +.wst-login-but{display: block; position: relative; background:#E45050; color: #ffffff; text-align: center; font-family: 'Ubuntu', sans-serif; font-size: 15px; font-weight: bold; text-decoration: none; border-radius: 3px; overflow: hidden; -webkit-transition: all 0.15s ease-in; transition: all 0.15s ease-in; } +.wst-login-but:hover {background: #ea3232; } +.wst-login-but:before {content: ' '; position: absolute; background: #ffffff; width: 25px; height: 50px; top: 0; left: -45px; opacity: 0.3; -webkit-transition: all 0.25s ease-out; transition: all 0.25s ease-out; -webkit-transform: skewX(-25deg); transform: skewX(-25deg); } +.wst-login-but:hover:before {width: 45px; left: 205px; } +.wst-login-three{height: 30px; display: block; margin-top: 15px; } /*注册*/ .wst-regist{padding:100px 20px 60px 20px; } +.wst-regist-b{background:url(../img/img_regist.png) no-repeat; background-size: cover; margin-top:3px; border-top: 2px solid #eee;border-bottom: 2px solid #eee;} +.wst-regist-c{width: 760px; margin: 0 auto; padding:20px; border-radius:5px; } +.wst-regist-head{font-size:28px; font-family:"楷体"; color:#E45050; text-align:center; } input.wst-regist-input{width:400px; margin-left:20px; } +.wst-regist-td{text-align:right; width: 150px; font-size: 15px; color:#626262; } +.wst-regist-code-1{margin-left:20px; } input.wst-regist-codein{width:150px;} +.wst-regist-codeim{margin-left:288px; } input.wst-regist-codemo{padding:0px; margin-left: 20px; padding-left:5px; font-size: 15px; outline: none; width:260px; height:36px; border:1px solid #eee; } +.wst-regist-obtain{width:134px; background:#f0efef; border-radius: 3px; border: 1px solid #eee; padding:10px 0px; cursor:pointer; color: #110f0f; border:1px solid #eee;} +.wst-regist-but{outline: none; background:#e45050; color: #ffffff; border: 1px solid #ea3232; border-radius:3px; cursor:pointer; } +.wst-regist-but:hover{background: #ea3232; } +.wst-regist-but:not(.disabled):not(:disabled):active, .wst-regist-but.active{background: #ea3232; background-clip: padding-box; } /*找回密码*/ .stepflex{float:right; border-top: 5px solid #ccc; text-align: center; width: 640px; margin: 60px 0px 0px 50px; } +.stepflex dl{border-top: 5px solid #ccc; float: left; position: relative; top: -5px; width: 160px; } dl.doing{border-top-color: #04bd3d; } +.doing .s-num{background-position: -23px 0; } +.s-num,.s-num1{color: #fff; font-weight: 700; height: 23px; line-height: 23px; margin: -15px auto 0; position: relative; width: 23px; border-radius:25px; } +.s-num{background: #04bd3d; } +.s-num1{background: #ccc; } +.s-text{line-height:30px; } +.forget-pwd{width: 750px; margin:50px auto 50px; padding:25px 0px 48px 0px; border:1px solid #bac4c3; border-radius:6px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } input.wst-forget-input{padding: 0px; margin-left:20px; padding-left:5px; font-size: 15px; outline: none; width:300px; height:36px; border-radius:3px; border:1px solid #bac4c3; } +.wst-forget-code,.wst-forget-code2{float:left; width:300px; height:36px; border-radius:3px; margin-left:20px; border:1px solid #bac4c3; } input.wst-forget-codein,input.wst-forget-codein2{padding: 0px; padding-left:5px; width:180px; height:36px; position:absolute; font-size: 15px; outline: none; border:0; border-radius:6px; } +.wst-forget-input:focus,.wst-forget-codein:focus,.wst-forget-codein2:focus{border-radius:3px; border:1px solid #eb654a; } +.wst-forget-codeim,.wst-forget-codeim2{width:116px; border-top-right-radius:6px; border-bottom-right-radius:6px; margin-left:183px; } +.wst-forget-code2{width:230px; } input.wst-forget-codein2{width:120px; } +.wst-forget-codeim2{width:112px; margin-left:118px; } +.email-verify{display:none; } +.wst-forget-td{text-align:right; width: 260px; font-size: 15px; color:#626262; } +.wst-forget-te{margin-left:20px; font-size: 15px; } +.wst-forget-select{margin-left:20px; font-size: 15px; outline: none; width:230px; height:36px; border-radius:3px; border:1px solid #bac4c3; } +.wst-forget-obtain{width:134px; height: 36px; background:#f0efef; border-radius: 3px; border: 1px solid #d3c8c7; padding:10px 0px; cursor:pointer; color: #110f0f; } +.wst-forget-c{text-align:center; } +.wst-forget-ct{font-size: 16px; color:#2d2727; } +.wst-icon-banner{width: 1200px;margin:0 auto;} +.wst-icon{width: 120px;height: 30px; display: inline-block;float: right;} +.wst-icon li{float:left;} +.wst-icon .wst-remind{color:red;font-size: 12px;padding-left: 10px;height: 30px;line-height: 30px;} +.wst-img-icon{width: 23px;height: 23px; background: url(../img/icon_login02.png) no-repeat;background-size: contain;margin-top: 3px;} +.wst-login-banner{width: 99.9%;height: 160px; } +.wst-login-banner .img-banner{height:130px; margin: 10px 10px 10px 120px; float: left;} +.wst-login-banner .img-banner img{height: 100%;} +.wst-login-banner .wst-stript{width: 2px;height: 110px;margin-top: 25px;margin-left: 20px; background: #eee;float: left;} +.wst-login-banner .wst-login-action{width:630px;height: 130px; float: right; margin: 10px 10px 10px 10px;} +.wst-login-action .wst-left{width: 200px;height: 130px; float: left;text-align: center;line-height: 130px;font-family:微软雅黑;font-weight: bold;font-size: 25px;} +.wst-login-action .wst-right-action{width: 200px;height: 130px;float: right;} +.wst-login-action .action-box{padding-top: 50px; line-height: 27px;} +.action-box .wst-location{width: 100px;height: 25px;float: right;line-height: 25px;font-size: 12px;margin-right: 40px;} +.wst-login-middle{height: 527px; background: rgba(255,76,76,0.78);} +.wst-login-middle-shop{height: 477px; background: rgb(86,169,253);} +.wst-color{background: white;} +.wst-login-banner-regist{width: 99.9%;height: 100px; } +.wst-login-banner-regist .img-banner{height:90px; margin: 10px 10px 10px 100px; float: left;} +.wst-login-banner-regist .img-banner img{height: 100%;} +.wst-login-banner-regist .wst-login-action{width:400px;height: 80px; float: right; margin: 10px 10px 10px 10px;} +.wst-item{position: relative;margin-bottom: 20px;} +.wst-item-box{border: 1px solid #eee;height: 38px;width: 310px;} +.wst-item-box .login-img{ position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px; margin-left: 4px;margin-right: 2px; border-right: 1px solid #eee;background: url(../img/icon_name.png) 1px no-repeat;background-size: 85%;float: left;} +.password-img{position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px;margin-left: 4px; margin-right: 2px; border-right: 1px solid #eee;float: left;background: url(../img/icon_passard.png) 1px no-repeat;background-size: 85%;} +.yanzheng-img{position: relative;z-index: 3;top: 0;left: 0; width: 28px;height: 28px;margin-top: 5px; margin-left: 4px;margin-right: 2px; border-right: 1px solid #eee;float: left;background: url(../img/icon_yanzhengma.png) 1px no-repeat;background-size: 85%;} +.bottom-stript{width: 100%;height: 20px;border:1px solid red;} +.regist-border{border:1px solid #eee;} + + +.wst-login-code,.wst-regist-code{height:36px; border:1px solid #eee; } + .wst-login-codeim{margin-left:188px; } + input.wst-login-codein{padding:0px; padding-left:5px; width:180px; height:36px; position:absolute; font-size: 15px; outline: none;border:0; } \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/recharge.css b/hyhproject/home2/view/default/css/recharge.css new file mode 100755 index 0000000..aa08186 --- /dev/null +++ b/hyhproject/home2/view/default/css/recharge.css @@ -0,0 +1,49 @@ + +/**支付方式**/ +.pay-box{border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-top:1px solid #eeeeee;padding:5px 0px 10px 5px;} +.pay-boxs{padding:10px 0px 5px 5px;} +.pay-box ul{padding-left:15px;} +.pay-box ul li{width:1185px;} +.pay-box .label{width:200px;float:left;height:30px;line-height:30px;} +.pay-box .txt{height:auto;line-height:30px;width:985px;float:left;color:#999999;} +.pay-sbox{padding:5px 0px;} +.pay-sbox-head{border-bottom: 2px solid #ddd;line-height:35px;} +.pay-tip1{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -10px;background-size: cover; } +.pay-tip2{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -71px;background-size: cover; } +.pay-tip3{height:37px;width:760px;text-align: center;margin:10px auto;background: url(../img/pay_liucheng.png) no-repeat 0px -132px;background-size: cover; } +.pay-sbox .qrcode-box{min-height: 300px;height: auto;} +.pay-sbox .tips-box{line-height:35px;text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .qrcode-box .pbox{text-align: center;margin-top: 10px;font-weight: bold;} +.pay-sbox .wst-qrcode{width:260px;height:260px;text-align:center;margin:0 auto;} +.pay-sbox .wst-qrcode img{width:260px;height:260px;} +.pay-sbox .bnt-box{line-height:35px;text-align:center;font-weight: bold;padding:5px 10px;line-height:50px;} +.pay-sbox .pay-type{text-align: left;font-weight: bold;padding:5px 10px;} +.pay-sbox .pay-list{text-align: left;font-weight: bold;padding:5px 20px;} +.pay-sbox .succ-box{text-align: center;padding: 50px;} +.wst-payCode-weixinpays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-weixinpays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/weixinpays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px 0px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.wst-payCode-alipays-curr {height:69px;width:167px;text-align: center;margin:10px auto;background: url(../img/alipays.png) no-repeat 0px -75px;background-size: cover;float: left;margin-right:10px;cursor:pointer;} +.pay-sbox .wst-pay-bnt {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px 0px;cursor:pointer;} +.pay-sbox .wst-pay-bnt:hover {height:40px;width:132px;text-align: center;margin:10px auto;background: url(../img/btn_pay.png) no-repeat 0px -57px;cursor:pointer;} +.charge-money{font-size:18px;} +.charge-alone{line-height:50px; } +.charge-doub{padding-top: 8px;} +.charge-othermoney{width:80px;} +.j-charge-money{display: none;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{float: left;width:180px;margin: 2px 8px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame2{min-height:50px;float: left;min-width:120px;margin: 2px 20px 2px 0px;background: #fff;border: 1px solid #ccc;padding:7px;cursor: pointer;text-align:center;overflow: hidden;position: relative;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;padding:6px;} +.wst-form input.charge-othermoney{padding: 8px;} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/right_cart.css b/hyhproject/home2/view/default/css/right_cart.css new file mode 100755 index 0000000..37edca4 --- /dev/null +++ b/hyhproject/home2/view/default/css/right_cart.css @@ -0,0 +1,78 @@ +@CHARSET "UTF-8";.j-global-toolbar div a{margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.toolbar-wrap{position:fixed;top:0;right:0;z-index:9990;width:35px;height:100%} +.toolbar-wrap a{text-decoration:none} +.toolbar{position:absolute;right:0;top:0;width:29px;height:100%;border-right:6px solid #333} +.toolbar-panels{position:absolute;left:35px;top:0;width:270px;height:100%;z-index:2;background:#eceaea none repeat scroll 0 0} +.toolbar-panel{width:270px;height:100%;position:absolute;background:#eceaea none repeat scroll 0 0} +.tbar-panel-header{position:relative;width:270px;height:40px;line-height:40px;background:#eceaea none repeat scroll 0 0;font-family:"microsoft yahei";font-weight:normal;margin:0;padding:0} +.tbar-panel-header .title{display:inline-block;height:40px;color:#5e5050;font:16px/40px "微软雅黑"} +.tbar-panel-cart .tbar-panel-header i{width:20px;height:18px;background-position:0 0;margin-top:11px} +.tbar-panel-header i{margin-right:4px;margin-left:10px;vertical-align:top} +.tbar-panel-header i,.tbar-panel-header .close-panel{display:inline-block;font-style:normal;background-image:url("../img/right_cart.png");background-repeat:no-repeat} +.tbar-panel-header .title em{display:inline-block;vertical-align:top} +.tbar-panel-header .close-panel{width:12px;height:12px;background-position:0 -250px;position:absolute;right:8px;top:16px;cursor:pointer;transition:transform .2s ease-out 0s} +.tbar-panel-main{position:relative;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-tipbox{display:block} +.tbar-panel-content{width:270px;overflow-y:auto;overflow-x:hidden;position:relative} +.tbar-tipbox .tip-inner{padding:6px 5px;border:1px solid #edd28b;background:#fffdee none repeat scroll 0 0;text-align:center} +.tbar-tipbox .tip-text{display:inline-block;line-height:20px;vertical-align:middle;color:#333} +.tbar-tipbox .tip-btn{display:inline-block;height:20px;line-height:20px;padding:0 5px;margin-left:5px;color:#FFF;vertical-align:middle;background:#c81623 none repeat scroll 0 0} +.tbar-panel-cart .tbar-panel-footer{height:50px;background-color:#eceaea;margin:0;padding:0} +.tbar-checkout{height:40px;padding:5px 110px 5px 5px;position:relative} +.tbar-checkout .jtc-number strong{font-family:verdana;color:#c81623} +.tbar-checkout .jtc-number{line-height:20px;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-checkout .jtc-sum{line-height:20px;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-checkout .jtc-sum strong{font-family:verdana;color:#c81623} +.tbar-checkout .jtc-btn{position:absolute;right:5px;top:7px;width:110px;height:35px;font:16px/35px "微软雅黑";text-align:center;background:#c81623 none repeat scroll 0 0;color:#FFF} +.tbar-cart-list{width:100%;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-cart-item{padding:0 5px;margin-bottom:10px;background:#FFF none repeat scroll 0 0} +.jtc-item-promo{padding:12px 0 12px 0;border-bottom:1px dashed #e1e1e1} +.jtc-item-promo .promo-tag{position:relative;float:left;width:40px;height:20px;margin-top:-1px;margin-left:-57px;margin-right:17px;text-align:center;font:12px/20px "宋体";color:#FFF;background-color:#f58813} +.jtc-item-promo .promo-text{height:18px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font:12px/18px verdana} +.jtc-item-goods{padding:10px 0;position:relative;overflow:hidden} +.jtc-item-goods .p-img{float:left;width:60px;height:60px;border:1px solid #DDD;padding:0;margin-right:5px} +.jtc-item-goods .p-img img{width:60px;height:60px} +.jtc-item-goods .p-name{height:32px;line-height:16px;margin-bottom:4px;overflow:hidden} +.jtc-item-goods .p-name a{color:#333} +.jtc-item-goods .p-price{height:25px;overflow:hidden;font:12px/16px verdana;color:#666;width:170px} +.jtc-item-goods .p-price strong{color:#c81623;font-weight:normal;float:left} +.jtc-item-goods .p-del{position:absolute;right:10px;top:46px;width:35px;height:16px;line-height:16px;color:#005aa0;text-align:right;display:none} +.tbar-panel-history div{padding:0} +.jt-history-wrap{width:235px;margin:0 auto} +.tbar-panel-history ul{overflow:hidden;margin-right:-15px;margin-top:0;list-style:outside none none;padding:0} +.tbar-panel-history .tbar-panel-header i{width:20px;height:17px;margin-top:11px;background-position:0 -100px} +.tbar-panel-follow .tbar-panel-header i{width:20px;height:17px;margin-top:11px;background-position:0 -50px} +.tbar-panel-history .jth-item{float:left;position:relative;width:100px;height:120px;margin-right:15px;background:#FFF none repeat scroll 0 0;margin-bottom:15px;padding:5px} +.tbar-panel-history .jth-item .img-wrap{display:block;width:100px;height:100px;text-align:center;margin-bottom:5px} +.tbar-panel-history .jth-item .add-cart-button{height:20px;line-height:20px;overflow:hidden;text-align:center;text-decoration:none;display:none;position:absolute;width:100px;bottom:25px;left:5px;z-index:3;color:#FFF;background:rgba(28,25,28,0.8) none repeat scroll 0 0} +.tbar-panel-history .jth-item .price{color:#c81623} +.tbar-panel-history .history-bottom-more{display:block;text-align:center;height:40px;line-height:40px;font-family:"宋体";color:#666} +.toolbar-header{position:absolute;top:0;right:-6px} +.toolbar-tabs{position:absolute;top:50%;left:0;width:35px;margin-top:-61px} +.toolbar-tab{position:relative;width:35px;height:35px;margin-bottom:1px;cursor:pointer;background-color:#333;border-radius:3px 0 0 3px;font:12px/150% Arial,Verdana,"宋体";color:#666;display:inline-block;background-image:url("../img/right_cart.png");background-repeat:no-repeat} +.tbar-tab-cart{background-position:-50px 0} +.tbar-tab-follow{background-position:-50px -50px} +.tbar-tab-history{background-position:-50px -100px} +.tbar-tab-message{background-position:-50px -144px} +.tab-ico{width:34px;height:35px;margin-left:1px;position:relative;z-index:2;background-color:#7a6e6e} +.tab-text{width:62px;height:35px;line-height:35px;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;left:35px;top:0;background-color:#333;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;padding:0;cursor:pointer} +.tab-sub{position:absolute;z-index:3;right:2px;top:-5px;height:11px;padding:1px 2px;border:1px solid #b61d1d;overflow:hidden;color:#FFF;font:11px/11px verdana;text-align:center;min-width:11px;border-radius:10px;background-color:#cc6060;background-image:linear-gradient(to bottom,#cc6060 0,#b61d1d 100%)} +.toolbar-footer{position:absolute;bottom:-1px;width:100%;margin:0;padding:0;font:12px/150% Arial,Verdana,"宋体";color:#666} +.tbar-tab-top{background-position:-50px -250px} +.tbar-tab-feedback{background-position:-50px -300px} +.footer-tab-text{width:50px;height:35px;line-height:35px;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;left:35px;top:0;background-color:#7a6e6e;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;padding:0;cursor:pointer} +.tbar-tab-hover{left:-60px;background-color:#c81623} +.tbar-tab-footer-hover{left:-48px;background-color:#c81623} +.tbar-tab-selected{background-color:#c81623} +.tbar-tab-selected .tab-sub{color:#c81623;background-color:#FFF;background-image:linear-gradient(to bottom,#FFF 0,#FFF 100%);box-shadow:1px 1px 3px rgba(0,0,0,0.3);text-shadow:1px 0 1px rgba(0,0,0,0.3)} +.tbar-tab-click-selected{background-color:#c81623} +.tbar-tab-click-selected .tab-sub{color:#c81623;background-color:#FFF;background-image:linear-gradient(to bottom,#FFF 0,#FFF 100%);box-shadow:1px 1px 3px rgba(0,0,0,0.3);text-shadow:1px 0 1px rgba(0,0,0,0.3)} +.survey-tab-ico{display:none} +.survey-tab-text{left:0;width:35px;height:30px;padding:2px 0 3px;line-height:15px;background:#c81623 none repeat scroll 0 0;color:#FFF;text-align:center;font-family:"微软雅黑";position:absolute;z-index:1;top:0;border-radius:3px 0 0 3px;transition:left .3s ease-in-out .1s;font-style:normal;margin:0;cursor:pointer} +.toolbar-open{right:270px} +.j-close:hover{transform:rotate(180deg);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);-ms-transform:rotate(180deg)} +.tbar-panel-history .jth-item .add-cart-button:hover{background:#c81623 none repeat scroll 0 0} +.tbar-cart-item .buy-btn{background:#eee none repeat scroll 0 0;border:1px solid #ddd;color:#666;cursor:pointer;display:block;float:left;height:20px;line-height:20px;padding:0 5px} +input.right-cart-buy-num[type="text"]{border-color:#ddd -moz-use-text-color;border-style:solid none;border-width:1px 0;float:left;height:16px;text-align:center;width:40px} +.goods-remove{background:rgba(0,0,0,0) url("../img/right_cart.png") no-repeat 0 -290px;cursor:pointer;height:20px;overflow:hidden;padding:5px;position:absolute;right:-8px;top:4px;width:20px} +.right-carts-empty{margin-left:40px;margin-top:20px} diff --git a/hyhproject/home2/view/default/css/security.css b/hyhproject/home2/view/default/css/security.css new file mode 100755 index 0000000..72c193a --- /dev/null +++ b/hyhproject/home2/view/default/css/security.css @@ -0,0 +1,32 @@ +@CHARSET "UTF-8"; a{cursor:pointer; } +.wst-sec-info{padding:20px 0px 20px 30px; background: #fed1b0; } +.wst-sec-infor{float: left; margin-left:20px; } +.wst-sec-na{font-size:20px; color:#f06f69; line-height:20px; } +.wst-sec-grade img{width: 20px; margin-top:1px; margin-left:20px; } +.wst-sec-grade span{margin-left:8px; line-height:20px; font-family:"microsoft yahei"; } +.wst-sec-infoi{float: left; width: 100%; color:#3c3228; font-family:"microsoft yahei"; } +.wst-sec-infoin{color:#0cd8d5; } +.wst-sec-s{padding:30px 20px; font-family:"microsoft yahei"; } +.wst-sec-lists{float: left; width: 100%; min-height: 60px; line-height:60px; } +.wst-sec-green{color:#11cc71; } +.wst-sec-ash{color:#f1730f; } +.wst-sec-green img,.wst-sec-ash img{float: left; margin-top:24px; margin-right:3px; } +.wst-sec-w{color:#363636; font-size:17px; } +.wst-sec-strip{width: 300px; height: 20px; background: #d7cece; } +.wst-sec-strip2{width: 100px; height: 20px; background: #53e053; } /**/ .wst-sec-head2{margin-top:20px; padding: 28px; height: 30px; } +.wst-sec-min{width: 30%; text-align: center; height:26px; line-height:26px; background: #e0e0e0; color:#282828; font-size:15px; font-family:"microsoft yahei"; } +.wst-sec-mi{width: 13px; } +.wst-sec-min1{width: 0; height: 0; border-top: 13px solid transparent; border-left: 13px solid #e0e0e0; border-bottom: 13px solid transparent; } +.wst-sec-min2{width: 0; height: 0; border-top: 13px solid #e0e0e0; border-left: 13px solid transparent; } +.wst-sec-min3{width: 0; height: 0; border-bottom: 13px solid #e0e0e0; border-left: 13px solid transparent; } +.wst-sec-gr{color:#ffffff; background: #45d862; } +.wst-sec-gr1{border-left: 13px solid #45d862; } +.wst-sec-gr2{border-top: 13px solid #45d862; } +.wst-sec-gr3{border-bottom: 13px solid #45d862; } /*密码*/ .wst-form{float: left; margin-top:20px; margin-left:20px; } /*邮箱*/ .wst-sec-img{float: left; margin-top:3px; } +.wst-sec-prompt{margin-top:36px; margin-left:30px; } +.wst-sec-p1{margin-top:20px; font-size:15px; } +.wst-sec-p2{margin-top:20px; } +.wst-sec-su{margin: 0 auto; width: 260px; height: 120px; } +.wst-sec-sut,.wst-sec-sub{float: left; width: 100%; text-align:center; } +.wst-sec-sut{margin-top:60px; } +.wst-sec-sub{color: #11cd6e; font-size:18px; font-family:"microsoft yahei"; margin-top:6px; } /*手机*/ .wst-sec-obtain{width:130px; background:#f0efef; border-radius: 3px; border: 1px solid #d3c8c7; padding:8px 0px; cursor:pointer; color: #110f0f; } \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/self_shop.css b/hyhproject/home2/view/default/css/self_shop.css new file mode 100755 index 0000000..b6e66a9 --- /dev/null +++ b/hyhproject/home2/view/default/css/self_shop.css @@ -0,0 +1,184 @@ +.wst-shop-h{padding:10px 0} +.wst-shop-img{float:left;margin-top:3px;width:90px;height:90px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-img img{max-width:90px;max-height:90px;border-radius:5px} +.wst-shop-info{float:left;width:45%;margin-left:10px} +.wst-shop-info p{float:left;line-height:50px;width:100%;color:#222;font-size:17px;font-family:"microsoft yahei"} +.wst-shop-info2,.wst-shop-info3{float:left;width:100%} +.wst-shop-info2 img{float:left;width:16px;margin-right:3px} +.wst-shop-info2 span{float:left;color:#dda315;margin-right:10px} +.wst-shop-info3{margin-top:7px} +.wst-shop-code{float:left;margin-top:-3px;width:24px;height:24px;cursor:pointer;background:url(../img/img_sjck.png) no-repeat;background-size:100%} +.wst-shop-codes{width:131px;height:131px;margin-top:24px;border:1px solid #dedbdb;position:absolute;z-index:1000;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);border-radius:5px} +.wst-shop-codes:after{top:-16px;border-color:transparent transparent #fff} +.wst-shop-eva,.wst-shop-evaa{float:left;margin-right:16px} +.wst-shop-evaa{padding-left:20px} +.wst-shop-info3 .j-fav,.wst-shop-info3 .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 1px 2px no-repeat} +.wst-shop-info3 .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 0 -23px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shop-info3 .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 0 1px no-repeat;text-decoration:none} +.wst-shop-red{color:#e25041} +.wst-shop-tu{text-align:center;width:100%;height:110px} +@media screen and (max-width:1200px){.wst-shop-tu{min-width:1200px} +.s-wst-nav-menus{min-width:1200px}} +.homepage{margin-top:6px;padding:0 8px;height:22px;line-height:22px;color:#fff;border:1px solid #fff;font-size:13px!important} +.homepage:hover{color:#fc6047;background:#fff;border:1px solid #fc6047} +.s-wst-nav-menus{background:#ff6a53;width:100%;margin:0 auto;height:38px}#s-wst-nav-items ul{width:1200px;margin:0 auto} +.s-nav-li a{color:#fff;font:400 15px/36px "microsoft yahei";height:36px;padding:0 15px;text-align:center;text-decoration:none} +.s-nav-li{float:left;padding:0 16px;height:38;line-height:36px} +.s-cat-head>a{color:#fff;font:400 15px/36px "microsoft yahei"} +.s-cat-head-hover{background:#df2003} +.s-cat-head{display:block;height:38px;padding:0 10px;text-decoration:none;width:190px} +.wst-shop-sea{float:right;width:42.999999%;margin-top:20px} +.wst-shop-sea input{float:left;outline:0;font-size:15px;height:28px;width:360px;margin-right:3px;padding-left:8px;border:1px solid #fc6047} +.wst-shop-sea .search{float:left;width:60px;height:34px;line-height:32px;text-align:center;color:#fff;margin-left:6px;background:url(../img/img_bg_search.png) no-repeat} +.wst-shop-word{float:left;margin-top:8px;width:100%;height:18px;overflow:hidden} +.s-cat-head em{margin-top:10px;margin-right:-10px;display:block;width:16px;height:16px;float:left;background:url(../img/icon_class_zydp.png) no-repeat} +.shop-ct1-ct2{width:200px;height:15px;overflow:hidden;padding:5px 0;border-bottom:1px solid #e7e7e7} +.ct1-hover{background:#ff6a53;color:#fff} +.ct1-hover h3 a{color:white} +.ct1-hover .shop-ct1-ct2{border-bottom:0} +.ct1-hover .shop-ct1-ct2 a{color:white} +.shop-cat2{display:none} +.shop-cat1 h3{float:left;margin-left:3px;margin-top:2px} +.shop-cat1-title{width:220px;height:26px;margin-top:15px} +.shop-cat1{position:relative} +.shop-cat1{width:190px;height:66.3px;float:left;padding:0 10px} +.em1,.em2,.em3,.em4,.em5,.em6{float:left;display:block;width:18px;height:18px;background:url(../img/sprite@1x.png) no-repeat} +.em1{background-position:-38px -106px} +.em2{background-position:0 -105px} +.em3{background-position:0 -144px} +.em4{background-position:-75px -106px} +.em5{background-position:-106px -38px} +.em6{background-position:-143px -38px} +.shop-cat2{width:500px;max-height:400px;float:right;overflow:hidden;position:absolute;left:210px;top:0;z-index:998;background:#f0f0f0;border:2px solid #ff6a53} +.shop-cat2 li{float:left;padding:5px 16px;width:84px} +.shop-cat2 li a:hover{color:#df2003} +.s-cat{z-index:998;display:none;position:absolute;width:210px;height:400px;background:#fff} +.history-box{width:1200px;height:360px;margin:0 auto;margin-top:20px} +.history-title{width:100%;background:#ddd;height:30px;margin-bottom:10px} +.history-title p{float:left;line-height:30px;text-indent:10px} +.history-goods-list{width:1200px;height:320px} +.history-goods-list .s-goods{width:233px;margin:0 -1px 5px 5px;border:1px solid #e5e5e5;float:left} +.history-goods-list .s-goods-h:hover{border:1px solid #df2003;-webkit-box-shadow:0 0 10px #df2003;-moz-box-shadow:0 0 10px #df2003;box-shadow:0 0 10px #df2003} +.history-goods-list .s-goods .img{width:233px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;padding:4px} +.history-goods-list .s-goods .img a{display:table-cell;vertical-align:middle;width:233px;height:233px} +.history-goods-list .s-goods .img a img{max-width:210px;max-height:210px} +.history-goods-list .s-goods .p-price{padding:5px 0 5px 10px;font-weight:bold;color:#df2003;width:115px;float:left} +.history-goods-list .s-goods .p-hsale{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.history-goods-list .s-goods .p-market{padding:5px 0 5px 10px;font-weight:bold;color:gray;width:95px;float:left} +.history-goods-list .s-goods .p-appraise{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.history-goods-list .s-goods .p-hsale span{font-weight:bold;color:#df2003} +.history-goods-list .s-goods .p-market span{font-weight:bold;color:gray} +.shop_rec_out{width: 100%; margin: 0 auto; } +.s-buy-new-best-hot{width:100%;height:335px;margin-top:30px} +.s-rec{width: 1200px; margin: 0 auto; overflow: hidden; background-image: url(../img/self_shop_rec_bg.png); background-repeat: no-repeat; padding-left: 45px; background-position: 0 13px; } +.s-rec li{height: 35px; line-height: 35px; float: left; border-bottom: 1px solid #ff6a53; } +.s-rec li a{display: block; font-size:21px; font-weight: bold; color: #333; float:left; text-align:center } +.j-s-rec-selected a{color:#df2003!important;} +.s-rec-glistbox{width: 100%; background:-webkit-linear-gradient(right,#ffe9dc, #ffb3ab 40%, #ffe9dc); background:-o-linear-gradient(right,#ffe9dc, #ffb3ab 40%, #ffe9dc); background:linear-gradient(to left,#ffe9dc, #ffb3ab 40%, #ffe9dc); } +.s-rec-goods-list{width: 1200px; overflow: hidden; margin: 0 auto; height: 250px; padding: 10px 0; box-sizing: border-box; } +.s-rec-goods-list li{background-color: #fff; float: left; margin-left: 10px; width: 290px; height: 100%; box-sizing: border-box; position: relative; } +.s-rec-goods-list li:hover .rec_ginfo{opacity: 1; visibility: visible; } +.rec_ginfo{transition:all ease .4s; visibility: hidden; opacity: 0; width: 100%; height: 100%; box-sizing: border-box; position: absolute; z-index: 55; top: 0; background-color: rgba(0,0,0,0.5); } +.s-rec-goods-list li a{display:block; width:100%; height:100%; box-sizing: border-box; position: relative; } +.s1-rec-goods-list li:hover{border:1px solid #ff6a53;-webkit-box-shadow:0 0 10px #ff6a53;-moz-box-shadow:0 0 10px #ff6a53;box-shadow:0 0 10px #ff6a53} +.s-rec-goods-list img{position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; max-width: 100%; max-height: 100%; } +.s-rec-goods-price{margin-top:5px;text-align: center;} +.s-rec-goods-price>span{font-weight:bold;font-size:21px;color:#df2003} +.s-rec-goods-bottom{width:100%;overflow:hidden;box-sizing: border-box;padding: 0 60px;} +.s-rec-goods-bottom>a{line-height:20px; display:block; border:1px solid #fff; margin-top: 20px; width:80px; height:20px; text-align:center; color:#fff; border-radius:2px; } +.s-rec-goods-bottom>a:hover{background:#ff6a53;color:white;border:1px solid #ff6a53} +.s-rec-goods-desc{width: 100%; height: 41px; line-height: 38px; overflow: hidden; text-align: center; margin-top: 60px; } +.s-rec-goods-desc a{color:#fff;font-size: 20px;} +.s-floor-box{height:685px;width:100%;margin-top:15px} +.s-floor-header{width:1195px;height:36px;background:white} +.c1{border-bottom:1px solid #dc4bd1;border-left:5px solid #dc4bd1} +.c2{border-bottom:1px solid #8a5063;border-left:5px solid #8a5063} +.c3{border-bottom:1px solid #df2003;border-left:5px solid #df2003} +.c4{border-bottom:1px solid lightblue;border-left:5px solid lightblue} +.c5{border-bottom:1px solid #ff8043;border-left:5px solid #ff8043} +.c6{border-bottom:1px solid #24b0ed;border-left:5px solid #24b0ed} +.s-floor-header-f1,.s-floor-header-f2,.s-floor-header-f3,.s-floor-header-f4,.s-floor-header-f5,.s-floor-header-f6{float:left;height:100%;width:20%;margin-top:1px} +.s-floor-header .tab{float:right} +.s-floor-header .tab li{display:block;margin:0;float:left} +.s-floor-header .tab a{font-size:15px;display:block;height:15px;letter-spacing:1px} +.s-floor-header .tab-item1 a{color:gray;border:1px solid #e6e6e6;border-bottom:#dc4bd1;padding:10px} +.s-floor-header .j-tab-selected1 a{background:white;border-left:1px solid #dc4bd1;border-right:1px solid #dc4bd1;border-top:1px solid #dc4bd1;color:#dc4bd1;border-bottom:1px solid white} +.s-floor-header .tab-item2 a{color:gray;border:1px solid #e6e6e6;border-bottom:#8a5063;padding:10px} +.s-floor-header .j-tab-selected2 a{background:white;border-left:1px solid #8a5063;border-right:1px solid #8a5063;border-top:1px solid #8a5063;color:#8a5063;border-bottom:1px solid white} +.s-floor-header .tab-item3 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected3 a{background:white;border-left:1px solid #df2003;border-right:1px solid #df2003;border-top:1px solid #df2003;color:#df2003;border-bottom:1px solid white} +.s-floor-header .tab-item4 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected4 a{background:white;border-left:1px solid lightblue;border-right:1px solid lightblue;border-top:1px solid lightblue;color:lightblue;border-bottom:1px solid white} +.s-floor-header .tab-item5 a{color:gray;border:1px solid #e6e6e6;border-bottom:#df2003;padding:10px} +.s-floor-header .j-tab-selected5 a{background:white;border-left:1px solid #df2003;border-right:1px solid #df2003;border-top:1px solid #df2003;color:#df2003;border-bottom:1px solid white} +.s-floor-header .tab-item6 a{color:gray;border:1px solid #e6e6e6;border-bottom:#24b0ed;padding:10px} +.s-floor-header .j-tab-selected6 a{background:white;border-left:1px solid #24b0ed;border-right:1px solid #24b0ed;border-top:1px solid #24b0ed;color:#24b0ed;border-bottom:1px solid white} +.s-floor-right-title a{line-height:36px;font-size:16px;font-weight:bold;letter-spacing:2px} +.s-floor-right-title{height:36px;margin-right:70px;margin-left:5px} +.more{font-weight:bold} +.s-goods-list{width:1200px;border-left:1px solid #e5e5e5;height:634px} +.s-goods-list .s-goods{width:237px;height:316px;border-bottom:1px solid #e5e5e5;border-right:1px solid #e5e5e5;float:left} +.s-goods-list .s-goods-f1:hover{width:236px;height:316px;border-bottom:1px solid #dc4bd1;border-right:1px solid #dc4bd1;border-left:1px solid #dc4bd1;-webkit-box-shadow:0 0 10px #dc4bd1;-moz-box-shadow:0 0 10px #dc4bd1;box-shadow:0 0 10px #dc4bd1} +.s-goods-list .s-goods-f2:hover{width:236px;height:315px;border-bottom:1px solid #8a5063;border-right:1px solid #8a5063;border-left:1px solid #8a5063;-webkit-box-shadow:0 0 10px #8a5063;-moz-box-shadow:0 0 10px #8a5063;box-shadow:0 0 10px #8a5063} +.s-goods-list .s-goods-f3:hover{width:236px;height:315px;border-bottom:1px solid #df2003;border-right:1px solid #df2003;border-left:1px solid #df2003;-webkit-box-shadow:0 0 10px #df2003;-moz-box-shadow:0 0 10px #df2003;box-shadow:0 0 10px #df2003} +.s-goods-list .s-goods-f4:hover{width:236px;height:315px;border-bottom:1px solid lightblue;border-right:1px solid lightblue;border-left:1px solid lightblue;-webkit-box-shadow:0 0 10px lightblue;-moz-box-shadow:0 0 10px lightblue;box-shadow:0 0 10px lightblue} +.s-goods-list .s-goods-f5:hover{width:236px;height:315px;border-bottom:1px solid #ff8043;border-right:1px solid #ff8043;border-left:1px solid #ff8043;-webkit-box-shadow:0 0 10px #ff8043;-moz-box-shadow:0 0 10px #ff8043;box-shadow:0 0 10px #ff8043} +.s-goods-list .s-goods .img{width:232px;margin:0 auto;text-align:center;vertical-align:middle;display:block;position:relative;display:table-cell;padding:4px} +.s-goods-list .s-goods .img a{display:table-cell;vertical-align:middle;width:232px;height:232px} +.s-goods-list .s-goods .img a img{max-width:210px;max-height:210px} +.img{position:relative} +.img span{width:236px;height:30px;line-height:30px;color:#fff;opacity:.6;background:#d0260c;display:block;position:absolute;left:0;bottom:0;display:none} +.img span:hover{cursor:pointer;background:#e5280b} +.s-goods-list .s-goods .p-price{padding:5px 0 5px 10px;font-weight:bold;color:#df2003;width:115px;float:left} +.s-goods-list .s-goods .p-hsale{padding:5px 10px 5px 0;width:90px;float:right;text-align:right} +.s-goods-list .s-goods .p-market{padding:5px 0 5px 10px;font-weight:bold;color:gray;width:95px;float:left} +.s-goods-list .s-goods .p-appraise{padding:5px 10px 5px 0;width:95px;float:right;text-align:right} +.s-goods-list .s-goods .p-hsale span{font-weight:bold;color:#df2003} +.s-goods-list .s-goods .p-market span{font-weight:bold;color:gray} +.p-name{margin-left:10px;width:210px} +.more{height:35px} +.more a{line-height:35px;text-align:center;background:#fff;margin-left:10px} +.s-banner{width:100%;height:500px;margin:0 auto} +#s-wst-slide .s-wst-slide-items li{height:500px;overflow:hidden} +.wst-shop-info2 img.wangwang{padding-top:1px;width:65px;height:22px} +.wst-shop-share{float:right;position:relative;top:-6px} +.notice{display:flex;align-items:center} +.notice_img{vertical-align:text-top;width:15px;height:15px} +.f15{font-size:15px} +.pdl10{padding-left:10px} + +.self_container_out{width: 100%; box-sizing:border-box;padding-top: 10px; } +.sf_headerbox{width: 1200px; margin-bottom: 10px; margin: 0 auto; } +.sfhl{float: left; height: 100%; background-image: url(./../img/self_shop_f1_bg.png); padding-left: 31px; background-repeat: no-repeat; padding-top: 18px; background-size: contain; background-position: 0px 4px; position: relative; } +/* 楼层标题背景图 */ +.f1_tit_bg{background-image: url(./../img/self_shop_f1_bg.png)} +.f2_tit_bg{background-image: url(./../img/self_shop_f2_bg.png)} +.f3_tit_bg{background-image: url(./../img/self_shop_f3_bg.png)} +.f4_tit_bg{background-image: url(./../img/self_shop_f4_bg.png)} +.f5_tit_bg{background-image: url(./../img/self_shop_f5_bg.png)} +.f6_tit_bg{background-image: url(./../img/self_shop_f6_bg.png)} +.sfh_tit{font-size: 18px; color: #df2003; text-align: left; position: relative; top: -6px; left: 1px; } +.sfhr{float: right; height: 100%; line-height: 1.5; margin-top: 22px; } +.c18_333{font-size: 14px; color: #333; } +.separatory{padding: 0 10px; } +.sf_adsbox{width: 1200px; height: 320px; box-sizing:border-box; margin: 0 auto; margin-top: 10px; } +.sf_adsbox img{width: 100%;height: 100%;} +.sf_glistbox{width: 100%;} +/* 楼层商品背景色 */ +.f1_g_bg{background-color: #fff;} +.f2_g_bg{background:-webkit-linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); background:-o-linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); background:linear-gradient(right, rgba(222,243,213,0.3) 8%, #def3d5 40%, rgba(222,243,213,0.3) 87%); } +.f3_g_bg{background-color: #fff;} +.f4_g_bg{background:-webkit-linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); background:-o-linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); background:linear-gradient(right, #f8feff 8%, #eefdff 40%, #f8feff 87%); } +.f5_g_bg{background-color: #fff;} +.f6_g_bg{background:-webkit-linear-gradient(right, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); background:-o-linear-gradient(right, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); background:linear-gradient(to left, #f0f4ff 8%, #dae3ff 40%, #f8feff 87%); } +.sf_glist{width: 1200px;box-sizing:border-box; margin: 0 auto; padding: 0 19px; } +.sf_glist li:nth-child(n+6){margin-top:0; } +.sf_glist li:nth-child(5n){background-color: #fff; margin-right:0; } +.sf_glist li:hover a{background-color: #eee;} +.sf_glist li:hover{background-color: #eee;} +.sf_glist li{margin-top: 15px; margin-bottom: 15px; background-color: #fff; float: left; width: 200px; height: 300px; margin-right: 15px; padding: 0 10px; border-radius: 8px; transition:all ease .4s; } +.sf_glist li a{transition:all ease .4s; display: block; width: 100%; height: 100%; background-color: #fff; box-sizing: border-box; padding-top: 20px; } +.sf_img img{position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; max-width: 100%; max-height: 100%; } +.sf_img{position: relative; width: 100%; height: 200px; } +.sf_gname{margin: 10px auto; font-size: 14px; color: #333; width: 100%; overflow: hidden; word-break:break-all; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; min-height: 35px; } +.sf_price{font-size: 14px; color: #df2003; } diff --git a/hyhproject/home2/view/default/css/shop.css b/hyhproject/home2/view/default/css/shop.css new file mode 100755 index 0000000..403175e --- /dev/null +++ b/hyhproject/home2/view/default/css/shop.css @@ -0,0 +1,454 @@ +@CHARSET "UTF-8"; +body {margin: 0px auto;background: #F5F5F5} +select{box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;padding: 2px;vertical-align: middle;} +.wst-wrap {margin: 0px auto} +.wst-header {} +.wst-main {margin: auto;width: 1200px;min-height: 600px;height: auto;padding-top: 15px;} +.wst-menu {background: #FFFFFF;width: 198px;float: left;margin-right: 15px;filter: progid : DXImageTransform.Microsoft.Shadow ( color = #909090,direction = 120, strength = 4 );-moz-box-shadow: 2px 2px 10px #909090;-webkit-box-shadow: 2px 2px 10px #909090;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);} +.wst-content {background: #FFFFFF;min-height: 948px;height: auto;width: 990px;float: right;filter: progid : DXImageTransform.Microsoft.Shadow ( color = #909090,direction = 120, strength = 4 );-moz-box-shadow: 2px 2px 10px #909090;-webkit-box-shadow: 2px 2px 10px #909090;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);} +.wst-footer {border-top: 1px solid #ddd;margin-top: 5px;} +.wst-menu-title {position: relative;width: 143px;display: block;padding: 10px 5px 10px 50px;font-weight: bolder;border-top: 1px solid #ccc;color: #000000;font-size: 16px;font-family:"microsoft yahei";background:#e9e9e9;cursor:pointer;} +.wst-menu-title img{padding: 0px 0px 3px 6px;} +.wst-menu {width: 198px;margin: 0px;padding: 0px;min-height: 948px;} +.wst-menu li {list-style-type: none;padding: 0px 0px 0px 50px;height: 35px;line-height: 35px;color: #6a6868;cursor: pointer} +.wst-menu li:hover,li.wst-menua{font-weight: bolder;color: #e23e3d;border-left: 2px solid #e23e3d;} +.wst-menu .selected {background-color: #e23e3d;font-weight: bolder;color: #ffffff;} +.wst-menu .liselect {background-color: #e23e3d;font-weight: bolder;color: #ffffff;} +.wst-list {width: 100%;border-collapse: collapse;} +.wst-list thead tr{line-height: 2;} +.wst-list thead tr th {height: 35px;border-bottom: 1px solid #ccc;text-align: left;padding-left:5px;background: #eeeeee;} +.wst-list tbody tr td {line-height: 35px;text-align: left;padding-left:5px;word-wrap: break-word;word-break:break-all;} +.wst-colour{background: #e6e6e6;} +.wst-form {border-collapse: collapse;width:99%;} +.wst-form tr {height: 30px;line-height: 30px;} +.wst-form tr th {color: #707070;text-align: right} +.wst-form tr td {text-align: left} +.wst-form input,textarea {background-color: white;border: 1px solid #ccc;border-radius: 3px;box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;margin: 3px;padding: 2px;vertical-align: middle;outline: none;border:1px solid #bac4c3;} +.wst-form input:focus{border-radius:3px;border:1px solid #eb654a;} +.wst-form select{box-shadow: 2px 2px 2px #f0f0f0 inset;font-family: inherit;font-size: 100%;padding: 2px;vertical-align: middle;} +.wst-tab-box {width: 100%;height: auto;margin: 0px auto;} +.wst-tab-nav {margin: 0;padding: 0;height: 31px;border-bottom:1px solid #f7375c;} +.wst-tab-nav li {cursor: pointer;float: left;margin: 0 0px;list-style: none;border: 1px solid #ddd;border-bottom: none;border-left: none;line-height: 30px;text-align: center;background: #eeeeee;color: #000000;padding-left: 10px;padding-right: 10px;} +.wst-tab-nav .on {background: none repeat scroll 0 0 #e45050;border-bottom: 0 none;color: #ffffff;font-weight:bold;} +.wst-tab-content {padding: 5px;width: 99%;height: auto;border: 1px solid #ddd;background: #FFF;} +.wst-gallery-imgs {height: auto} +.wst-gallery-img {width: 140px;height: 100px;float: left;overflow: hidden;position:relative;margin: 10px 5px 5px 0px;cursor: pointer;} +.wst-gallery-del {background: url('../../../View/default/images/close_botton.png') no-repeat;display: block;height: 20px;position: absolute;width:20px;right: 0px;cursor: pointer;} +.wst-gallery-goods-del {background: url('../../../View/default/images/close_botton.png') no-repeat;display: block;height: 20px;position: absolute;width:20px;right: 0px;display:none;cursor: pointer;} +.wst-shop-nav {border-bottom:6px solid #e45050;text-align: center;} +.wst-nav-box {width: 1200px;margin: 0 auto;line-height: 33px;color: #ffffff;} +.wst-nav-box li{width: 156px;text-align: center;color: #e45050;font-size: 18px;font-family:"microsoft yahei";margin-bottom:-1px;} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{color: #ffffff;background:url(../img/seller_img_bgnav.png) 0px 0px no-repeat;} +.wst-nav-box .liselect {list-style-type:none;} +.wst-appsaler {margin-top: 30px;text-align: center;margin-bottom: 30px;line-height: 30px;} +.wst-menu-title span {position: absolute;left: 20px;top: 8px;display: inline-block;width: 20px;height: 20px;background-image: url(../../../View/default/images/icon_leftmenu.png);background-repeat: no-repeat;} +.wst-tree-open{background-repeat: no-repeat;display: inline-block;width: 20px;vertical-align:middle;cursor:pointer} +.wst-tree-close{display: inline-block;width: 20px;vertical-align:middle;cursor:pointer} +.wst-tree-second{display: inline-block;width: 20px;margin-left:10px;vertical-align:middle;cursor:pointer} +.wst-fre-hov:hover{background: #fae9ec;} +.wst-state_yes{display:block;width:13px;} +.wst-state_no{display:block;width:13px;} +.wst-page-items{text-align: left;color: #ccc;} +.wst-page-items a{display: inline-block;color: #000000;display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;border: 1px solid #D5D5D5;margin: 0 2px;border-radius: 4px;vertical-align: middle;} +.wst-page-items a:hover{text-decoration: none;color: #e23e3d;font-weight:bolder;border: 1px solid #D5D5D5;} +.wst-page-items span.current{display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;color: #e23e3d;font-weight:bolder;border: 1px solid #D5D5D5;border-radius: 4px;vertical-align: middle;} +.wst-page-items span.disabled{display: inline-block;height: 25px;line-height: 25px;padding: 0 10px;margin: 0 2px;color: #bfbfbf;background: #f2f2f2;border: 1px solid #bfbfbf;border-radius: 4px;vertical-align: middle;} +.wst-shophome-img{height:120px;height:120px;text-align:center;} +.wst-shophome-area{min-height:400px;border-top:1px solid #cccccc;} +.wst-shophome-nav{width:780px;float:left;min-height:400px;} +.wst-shophome-nav .header{height:36px;background-color:#f5f5f5;line-height:36px;padding-left:10px;font-weight:bolder;} +.wst-shophome-nav .main{height:66px;background-color:#feffd4;line-height:30px;padding-left:10px;margin:10px;} +.wst-shophome-nav .current{padding-left:20px;padding-bottom:10px;color:#000000;} +.wst-goods-price-table{width:100%;border:0px;border-collapse: collapse;} +.wst-goods-price-table tr th{border:0px;text-align:left;background:#eee;padding-left:5px} +.wst-goods-fieldset{border:2px double #ddd;padding:5px;display:none;} +.wst-goods-fieldset legend{margin-left:10px;} +.wst-complain-detail{width:100%;border-collapse: collapse;} +.wst-complain-detail tr{height: 25px;line-height: 25px;} +.wst-complain-detail tr th{color: #707070;text-align: right;font-size:12px;} +.wst-complain-detail tr td {text-align: left;color: #707070;} +.wst-complain-detail .head{font-weight:bold;border-bottom:1px dotted #ddd;} +.wst-complain-left{width:250px;height:100%;border:1px solid #ddd;text-align:left;background:#ffffff;float:left;} +.wst-complain-order-head{width:240px;height:25px;line-height:25px;border-bottom:1px solid #ddd;font-weight:bold;padding:5px;background:#f5f5f5;} +.wst-complain-order-goods{width:240px;height:180px;line-height:30px;padding:5px;border-bottom:1px solid #ddd;overflow-y:auto} +.wst-complain-main{float:right;width:718px;overflow:hidden;border:1px solid #ddd;margin-right:16px;} +.wst-complain-order-info{padding:5px;display: block;height:100%;} +.wst-complain-order-info dt {float: left;width: 70px;color: #999;padding: 1px 0;display: block;height:20px;} +.wst-complain-order-info dd{overflow: hidden;color: #666;padding: 1px 0;width:170px;display: block;height:20px;} +.wst-complain-box{border-bottom:1px solid #ddd;width:718px;padding:5px;} +.wst-complain-footer{clear:both;width:100%;text-align:center;padding:5px 0;} +/*头部*/ +.wst-lite-bac{background:#ffffff;} +.wst-lite-tit{float:left;width: 100px;margin:16px 0px 0px 10px;} +.wst-lite-tit span{float:left;color: #e45050;font-size: 19px;margin-left:10px;font-family:"microsoft yahei";} +a.wst-lite-in{float:left;margin-top:6px;padding:3px 8px;color: #e45050;border:1px solid #e45050;} +a.wst-lite-in:hover{color: #ffffff;border:1px solid #ffffff;background:#e45050;} +.wst-lite-sea{float:right;background:#ffffff;margin-top:20px;} +.wst-lite-sea .search{border:2px solid #e23c3d;height: 35px;position: relative;} +.wst-lite-sea .search .j-search-type{width:78px;top:0;line-height:36px;position: absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor: pointer;left:-2px;text-align:center;} +.wst-lite-sea .search .j-type-list{width:70px;top:35px;line-height:36px;position: absolute;padding:0 4px;border:2px solid #e23c3d;cursor: pointer;background-color: #fff;left:-2px;z-index: 100;border-top:0;display: none;text-align: center;} +.wst-lite-sea .search .j-search-type i {top: 15px;right: 6px;height: 7px;width: 0px;overflow: hidden;font-style: normal;color: #6A6A6A;display: block;position: absolute;} +.wst-lite-sea .search .j-search-type s{ position: relative;top: -17px;text-decoration: none;}.wst-lite-sea .search .j-type-list div:hover{color: #e23c3d} +.wst-lite-sea .search .search-ipt{border: 2px solid #e23c3d;color: #565656;float: left;font-family: Microsoft Yahei;font-size: 14px;line-height: 30px;overflow: hidden;padding: 0;width: 330px;height:30px;border:36px;outline:none;padding-left: 84px;box-shadow: none;} +.wst-lite-sea .search .search-btn{cursor: pointer;font-size: 15px;font-weight: bolder;height: 35px;line-height: 36px;position: absolute;right: 0;text-align: center;top: 0;width: 52px;background:url(../img/btn_search_red.png) 22px 6px no-repeat;} +/*首页*/ +.wst-shop-name{margin-top:28px;margin-left:138px;} +.wst-shop-name a{color: #fe6047;font-size: 18px;font-family: "microsoft yahei";} +.wst-shop-info{padding:0px 0px 0px 10px;} +.wst-shop-img{float:left;margin-top:-32px;width:120px;height:120px;text-align:center;vertical-align:middle;display:block;position:relative;} +.wst-shop-img a{width:120px;height:120px;display:table-cell;vertical-align:middle;} +.wst-shop-img img{max-width:120px;max-height:120px;} +.wst-shop-na{float:left;margin-left:6px;width:20%;} +.wst-shop-na a{color: #fe6047;font-size: 18px;font-family: "microsoft yahei";} +.wst-shop-na2{float:left;margin-top:3px;} +.wst-shop-na2 img{float:left;width:15px;margin:4px 3px 0px 0px;cursor: pointer;} +.wst-shop-na2 span{float:left;line-height: 26px;margin-right:6px;} +.wst-shop-na3{float:left;width:100%;color: #010101;line-height:26px;} +.wst-shop-eva{float:left;width:15%;margin:0px;border-left:1px dashed #bfbfbf;} +.wst-shop-eva p{font-size: 15px;color: #010101;text-align:center;font-family: "microsoft yahei";margin:16px 0px 8px 0px;} +.wst-shop-evai{float:left;margin:8px 0px 16px 25px;} +.wst-shop-con{float:left;width:21%;margin:0px;border-left:1px dashed #bfbfbf;} +.wst-shop-con p{font-size: 15px;font-family: "microsoft yahei";line-height: 30px;margin-left:18px;} +.wst-list .wst-fre-th{padding-left: 23px;} +.wst-list .wst-fre-td{padding-left: 25px;} +/*标题*/ +.wst-shop-head{float: left;width: 100%;border-bottom: 1px solid #e45050;} +.wst-shop-head span{float: left;line-height:28px;padding:0px 28px;color:#ffffff;background:#e45050;font-weight: bold;} +.wst-shop-head a{float: right;line-height:28px;padding:0px 28px;color:#ffffff;background:#df2003;} +.wst-shop-tbar{height: 45px;margin:15px 0 0 0px;clear:both;padding:5px 10px;} +.wst-shop-content{padding:12px;clear:both;} +/*button按钮*/ +/*红*/ +.wst-shop-but{outline: none;background:#E45050;color: #ffffff;border: 1px solid #d8193e;border-radius:3px;cursor:pointer;} +.wst-shop-but:hover{background: #ea3232 none repeat scroll 0 0;cursor:pointer;} +/*button按钮*/ +.s-btn{height: 30px;line-height: 30px;margin-right: 10px;margin-top: 16px;padding: 7px 20px;color: #ffffff;background: #E45050;border-radius: 3px;cursor:pointer;} +.s-btn:hover{cursor:pointer;} +.s-btn2{height: 30px;line-height: 30px;margin-right: 10px;margin-top: 16px;padding: 7px 20px;background: #ebebeb;border:1px solid #dad7d7;border-radius: 3px;cursor:pointer;} +.s-btn:hover{cursor:pointer;} +.wst-shop-split{border-bottom:1px dotted #ccc;margin-top:10px;margin-bottom:10px;} +.wst-shop-jrdt{height:120px;} +.wst-shop-jrdt .wst-title{background:url("../img/img_majz_titlebg.png");background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-jrdt .item{width:170px;height: 58px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;} +.wst-shop-jrdt .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -45px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -170px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -296px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -422px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -550px -31px;height:58px;width:47px;float:left;} +.wst-shop-jrdt .item .title{float:left;text-align: center;height:58px;width:120px;padding-top:5px} +.wst-shop-jrdt .item .num{color:red} +.wst-shop-spxx{height:300px;margin-top: 25px;} +.wst-shop-spxx .wst-title{background:url("../img/img_majz_titlebg.png") no-repeat 0px -68px;background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-spxx .item{width:170px;height: 100px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;margin-bottom: 10px;} +.wst-shop-spxx .item .rbox{height:60px;position:relative;} +.wst-shop-spxx .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -38px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -155px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -274px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -391px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -507px -128px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .icon6{background:url("../img/icon-mjzxsy.png") no-repeat -38px -232px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-spxx .item .title{text-align: center;height:58px;padding-top:5px} +.wst-shop-spxx .item .num{color:red} +.wst-shop-ddxx{height:280px;} +.wst-shop-ddxx .wst-title{background:url("../img/img_majz_titlebg.png") no-repeat 0px -135px;background-size:100%;width:980px;height:40px;line-height: 40px;padding-left: 10px;font-weight: bold;} +.wst-shop-ddxx .item{width:170px;height: 100px; overflow:hidden;border:1px solid #ccc;margin-left: 20px;float:left;margin-bottom: 10px;} +.wst-shop-ddxx .item .rbox{height:60px;position:relative;} +.wst-shop-ddxx .item .icon1{background:url("../img/icon-mjzxsy.png") no-repeat -38px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon2{background:url("../img/icon-mjzxsy.png") no-repeat -154px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon3{background:url("../img/icon-mjzxsy.png") no-repeat -273px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon4{background:url("../img/icon-mjzxsy.png") no-repeat -391px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon5{background:url("../img/icon-mjzxsy.png") no-repeat -509px -320px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .icon6{background:url("../img/icon-mjzxsy.png") no-repeat -38px -415px;position:absolute; left:55px;height:60px;width:60px;} +.wst-shop-ddxx .item .title{text-align: center;height:58px;padding-top:5px} +.wst-shop-ddxx .item .num{color:red} +/********************************************** 新增商品页面 ****************************************************/ +/*自定义单选框样式*/ +.wst-radio + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;border-radius: 50px;display: inline-block;position: relative;} +.wst-radio + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-radio:checked + label{border: 1px solid #ff9a02;/* 修改选框选中颜色*/} +.wst-radio:checked + label:after {content: ' ';width: 6px;height: 6px;border-radius: 50px;position: absolute;top: 3px;background: #ff9a02;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #ff9a02;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.radio-box .wst-radio{position:relative;z-index:-654;left:16px;top:0px;} +.radio-box label{margin-left:-8px;margin-right:2px;} +.mt-1{position:relative;top:1px;left:0px;cursor:pointer;} +/*自定义复选框样式-行*/ +.wst-checkbox + label {-webkit-appearance: none;background-color: #fafafa;border: 1px solid gray;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #99a1a7;box-shadow: inset 0px 0px 10px rgba(0,0,0,0.3);text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-checkbox:checked + label{border: 1px solid #ff9a02;/* 修改选框选中颜色*/} +.wst-checkbox:checked + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #ff9a02;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #ff9a02;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.checkbox-box .wst-checkbox{position:relative;z-index:-654;left:16px;top:-1px;} +.checkbox-box label{margin-left:-8px;margin-right:2px;} +.w-r{width:15px;height:15px;cursor:pointer;margin-left:8px;} +.wrong{background:url(../img/seller_icon_error.png) no-repeat;} +.right{background:url(../img/seller_icon_right.png) no-repeat;} +.g-handle{color:#1cbbef;display: inline-block;margin:0 3px;} +.g-handle:hover{color:#085cde;} +.spec-item{float:left;} +.spec-item .item-del{background:url(../img/icon_no.png);width:13px;height:13px;display:inline-block;position: relative;top:-10px;left:-10px;cursor:pointer;} +.spec-ipt{width:80px;} +.specs-sale-table{width:100%;border-collapse:collapse;border:1px solid #dddddd;margin-bottom:10px;} +.specs-sale-table th{padding-top:5px;text-align:center;background:#eeeeee;text-align:center;border:1px solid #dddddd} +.specs-sale-table td{text-align:center;text-align:center;border:1px solid #dddddd} +.spec-sale-goodsNo{width:150px} +.spec-sale-ipt{width:50px;} +.spec-sale-text{width:80%} +.attr-table{width:100%} +.attr-table th{text-align:right;} +.attr-table td{text-align:left;} +#goodsImgPicker{margin-left:20px;} +.spec-line{border-top:1px dashed #cccccc;margin:5px 0px 7px 0px} +.spec-head{font-weight:bold;height:30px;line-height:30px;background:url(../img/img_seller_ggjt.png) no-repeat 0px 7px;padding-left:25px;} +.spec-body{border:1px solid #cccccc;padding:5px;margin-bottom:10px;} +/************************ 商家商品管理页面 **************************/ +.goods-img{width:60px; height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left;margin:3px auto;line-height: 0px;} +.goods-img a{width:60px;height:60px;display:table-cell;vertical-align:middle;} +.goods-img a img{max-width:60px;max-height:60px;} +.goodsName{height:50px;line-height:25px;overflow: hidden;float: left;max-width: 150px;margin-left: 5px;} +.s-menu{height:25px;margin-left: 4px;margin-top:10px;} +.s-menu a{display: block;float:left;width:48px;margin-right: 10px;} +.s-menu a span{display: block;float: right;} +.s-sale,.s-sale-up,.s-new,.s-hot,.s-best,.s-rec,.s-heart,.s-del,.s-add{display: inline-block;width:18px;height:18px;background: url(../img/seller_icon_cz.png) no-repeat;} +.s-sale{background-position: -20px -24px;} +.s-sale:hover{background-position: -20px -64px;color:#F7375C;margin-top: 1px;} +.s-sale-up{background-position: -473px -24px;} +.s-sale-up:hover{background-position: -473px -64px;color:#F7375C;margin-top: 1px;} +.s-rec{background-position: -83px -24px;} +.s-rec:hover{background-position: -83px -64px;color:#F7375C;margin-top: 1px;} +.s-new{background-position: -149px -24px;} +.s-new:hover{background-position: -149px -64px;color:#F7375C;margin-top: 1px;} +.s-best{background-position: -213px -25px;} +.s-best:hover{background-position: -213px -65px;color:#F7375C;margin-top: 1px;} +.s-hot{background-position: -280px -25px;} +.s-hot:hover{background-position: -280px -65px;color:#F7375C;margin-top: 1px;} +.s-heart{background-position: -276px -25px;} +.s-heart:hover{background-position: -276px -65px;color:#F7375C;margin-top: 1px;} +.s-del{background-position: -343px -25px;} +.s-del:hover{background-position: -343px -65px;color:#F7375C;margin-top: 1px;} +.s-add{background-position: -408px -25px;} +.s-add:hover{background-position: -408px -65px;color:#F7375C;margin-top: 1px;} +/*评价管理*/ +.appra-img{width:150px; height:150px;margin:5px auto;text-align:center;vertical-align:middle;display:block;position:relative; float:left;} +.appra-img a{display:table-cell;vertical-align:middle;width:150px;height:150px;} +.appra-img a img{max-width:150px;max-height:150px;} +.appra-goodsName{float: left;height: 150px;line-height: 25px;margin-left: 5px;max-width: 240px;overflow: hidden;} +/*自定义复选框-列--方*/ +.checkbox-box-s{height:20px !important;} +.wst-checkbox-s + label {-webkit-appearance: none;background-color: #ffffff;border: 1px solid #d5d5d5;padding: 6px;display: inline-block;position: relative;} +.wst-checkbox-s + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;box-shadow: inset 0px 0px 10px #ccc;text-shadow: 0px;left: 3px;font-size: 32px;} +.wst-checkbox-s:checked + label{border: 1px solid #F7375C;/* 修改选框选中颜色*/} +.wst-checkbox-s:checked + label:after {content: ' ';width: 6px;height: 6px;position: absolute;top: 3px;background: #F7375C;/* 修改选框选中颜色*/box-shadow: inset 0px 0px 10px #F7375C;/* 修改选框选中颜色*/text-shadow: 0px;left: 3px;font-size: 32px;} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-5px;top:-1px;} +.checkbox-box-s label{position: relative;top:-38px;left: 1px;} +.checkbox-box-s-all label{position: relative;top:-27px;left: 1px;} +/**订单列表**/ +.wst-box-top{margin-top:5px;} +.wst-order-list{width:100%;border-collapse:separate;border-spacing: 0;border-color:grey;} +.wst-order-list .head{max-height:32px;line-height: 32px;text-align: center;background: #f5f5f5;color: #666;font-weight: 400;} +.wst-order-list .empty-row{height: 20px;} +.wst-order-list .order-head{background: #f5f5f5;height: 31px;line-height: 31px;color: #aaa;overflow: hidden;} +.wst-order-list .order-head td{padding-left:5px;padding-right:5px;border:1px solid #e5e5e5;border-bottom:0px;} +.wst-order-list .goods-box td:first-child{border-left:1px solid #e5e5e5;} +.wst-order-list .goods-box td{padding:5px;border:1px solid #e5e5e5;border-top:0px;border-left:0px;} +.wst-order-list .time{float:left;margin-right:30px;} +.wst-order-list .orderno{float:left;margin-right:30px;width:300px;text-align:left;} +.wst-order-list .address{float:left;width:580px;text-align:left} +.wst-order-list .goods-img{width:60px;height:60px;float:left;border:1px solid #efefef;} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:475px;} +.wst-order-list .goods-extra{float:right;margin-left:5px;} +.wst-order-list .j-warn .order-head{background:#fcf8e3;height: 31px;line-height: 31px;color:#8a6d3b;overflow: hidden;} +.wst-order-list .j-warn .order-head td{padding-left:5px;padding-right:5px;border:1px solid #faebcc;border-bottom:0px;} +.wst-order-list .j-warn .goods-box td:first-child{border-left:1px solid #faebcc;} +.wst-order-list .j-warn .goods-box td{padding:5px;border:1px solid #faebcc;border-top:0px;border-left:0px;} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px;} +.j-warn-order-money{color:red;font-size:19px;font-weight:bold} +.order-pc{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_1.png) 0px 0px no-repeat;background-size: 90%;} +.order-mo{float: left;margin: 7px 5px 0px 0px;width: 18px;height: 18px;background: url(../img/order_source_2.png) 0px 0px no-repeat;background-size: 100%;} +.order-wx{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_3.png) 0px 0px no-repeat;background-size: 100%;} +.order-app{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background: url(../img/order_source_4.png) 0px 0px no-repeat;background-size: 100%;} +.order-ios{float:left;margin:7px 5px 0px 0px;width:18px;height: 18px;background:url(../img/order_source_5.png) 0px 0px no-repeat;background-size: 100%;} +/**订单详情**/ +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd;} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px} +/*流程展示*/ +.order-box .log-box{height:132px;} +.order-box .log-box .icon{float:left;width:60px;height:60px;} +.order-box .log-box .icons{float:left;width:60px;height:60px;} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat;} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat;} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat;} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat;} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat;} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat;} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat;} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat;} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat;} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat;} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat;} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat;} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat;} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat;} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat;} +.order-box .log-box .arrow{float:left;color: #979797;font-size: 15px;font-weight: bold;margin-top:18px;} +.order-box .log-box .arrow2{color: #7ebb53;} +.order-box .log-box .state{float:left;width:100%;margin-left:18px;} +.order-box .log-box .state2{float:left;width:100%;position: relative;} +.order-box .log-box .state2 p{float:left;width:180px;height:50px;text-align:left;margin-left:12px;color:#f05858;font-size: 15px;} +.order-box .log-box .state2 .path{position: absolute;z-index: 10;} +.order-box .log-box .state2 .path span{float:left;width:178px;height:50px;text-align:left;margin-left:12px;background: #ffffff;} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd;} +.order-box th{font-weight:normal;} +.order-box .goods-head{border-top:2px solid #FC7A64;background: #f3f3f3;display: block;height: 25px;line-height: 25px;margin: 0 0 10px;padding: 5px 0;} +.order-box .goods-head .goods{float:left;width:500px;padding-left:15px} +.order-box .goods-head .number{float:left;width:140px;} +.order-box .goods-head .price{float:left;width:100px;} +.order-box .goods-head .num{float:left;width:100px;} +.order-box .goods-head .t-price{float:left;width:105px;} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #FDD8D2;color:#E55356;font-weight:bold;font-size:15px;padding-bottom:5px;} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eeeeee;border-top:0px;} +.order-box .item .goods{float:left;width:500px;padding-left:15px;} +.order-box .item .number{float:left;width:140px;} +.order-box .item .goods .img{float:left;width:80px;height:80px;} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px;} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px;} +.order-box .item .price{float:left;width:100px;} +.order-box .item .num{float:left;width:100px;} +.order-box .item .t-price{float:left;width:100px;} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px;} +.order-box .line{border-top:1px solid #dddddd;} +.order-box .goods-summary{margin-top:10px;} +.order-box .summary{height:30px;line-height:30px;} +.order-box .orderScore{margin-right:5px;} +.order-box .log td{height:25px;line-height:25px;padding-left:15px;} +/********** 店铺设置 *********/ +.cfg-img-url{background: #f48c3a none repeat scroll 0 0;bottom: 0;height: 18px;left: -1px;top:178px;line-height: 18px;padding: 0 5px;position: absolute;z-index: 170;} +/************* 商家回复 *************/ +.reply-content{line-height:15px;width:100%;margin-top:-15px;border-top:1px solid #ccc;padding-top:15px;color:orange;} +.reply-box{width:100%;max-height:140px;position:relative;margin-bottom:5px;margin-top:15px;} +.wst-msg-tips-box{background-color: #f0a869;border-radius: 12px;color: white;cursor: pointer;display: inline-block;height: 24px;left: 30px;line-height: 24px;position: relative;text-align: center;top: 0;width: 24px;} +/* 商家回复 */ +.wst-list tbody tr td .spec{height: 45px;line-height: 15px;overflow: hidden;float: left;max-width: 160px;} +.wst-list tbody tr td .stockin{display:none;border:1px solid #bac4c3;width:100px;outline: none;} +.wst-list tbody tr td .stockin:focus{border:1px solid #eb654a;} +.j-messsage-box{padding:10px 5px;color:red;} +.head-ititle{background:url('../img/img_seller_ggjt.png') no-repeat 5px 4px;padding-left:28px;padding-bottom:5px;font-weight:bold;} +/**资金流水**/ +.money-add{color:red;font-size:16px;font-weight: bold;} +.money-reduce{color:green;font-size:16px;font-weight: bold;} +.money-head{background:#eeeeee;height:120px;width:100%} +.money-head .shop-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px;} +.money-head .shop-logo img{-moz-border-radius: 100px; -webkit-border-radius: 100px; } +.money-head .shop-info{float:left;padding-top:25px;padding-left:20px;} +.money-head .shop-info .shopName{height:25px;line-height:25px;} +.money-head .shop-info .money-rows{width:700px;} +.money-head .shop-info .shopMoney{height:25px;line-height:25px;width:500px;} +.money-head .shop-info .draw-tips{color:red;margin-left:20px;} +.money-head .shop-info .cashmoney-box{margin-left:20px;} +.money-head .cashbtn{padding: 3px 5px;border: 1px solid #333;} +.money-head .cashbtn:hover{padding: 3px 5px;border: 1px solid #e45050;} +.money-head .usermoney{width:150px ; float:left;} +.money-head .cashbox{width:300px; float:left;} +.money-head .lockbox{width:150px ; float:left;} + +.msgContent{padding:10px;} +.readMsg,.newMsg{width:36px;height:27px;background: url(../img/user_icon_info.png) no-repeat;} +.newMsg{background-position: -66px -6px;} +.readMsg{background-position: -11px -6px;} +.msg-content{width: 630px} +/* 商家中心首页 */ +.main{background: #f6f6f6;width: auto;min-height: 800px;padding-top: 20px;} +.main_title{padding: 5px 0;} +.c16_555{font-size: 16px;color: #555;} +.tit_label{width: 12px;height: 12px;background: #e33c3c;border-radius: 50%;display: inline-block;} +.main_middle{width:auto;height:auto;} +.main_mid_box{display:flex;width:auto;height: 100%} +.main_mid_box .mid_l{flex:2;} +.mid_l_item{padding:0 10px;flex:1;background: #fff;height: 48%;} +.complain_num{display: inline-block;width: 25px;height: 25px;background: #e33c3c;border-radius: 50%;color:#fff;text-align: center;line-height: 25px;} +.mid_main{width: 100%;height: 90%;} +.order_info{width:100%;height:100%;display: flex;} +.order_info li{flex: 1;display: flex;height: 100%;flex-direction: column;justify-content: space-around;} +.order_info li:nth-child(2){flex:1.5;} +.c32_e33{font-size: 32px;color:#e33c3c;margin-bottom: 20px} +.info_item{padding:10px 0;text-align: center;} +.item_center{display: flex;justify-content:center;align-items:center;height: 148px!important;width: 148px !important;border-radius: 50% 50% 0 50%;border-color: #e33c3c;border-style: solid;border-width: 1px 0px 0px 1px;margin: 0 auto;} +.main_mid_box .mid_c{flex:1;margin:0 20px;background: #fff;} +.index-right-item{background:#fff;min-height: 492px;margin-bottom:20px;width: 100%;overflow: hidden;} +.right-list-tit{width: 97%;border-bottom: 1px solid #eee;display: flex;margin: 0 auto;} +.right-list-tit li{padding:14px 0px;flex:1;float: left;text-align: center;} +.orderInfoList li{padding: 13px 0px !important;} +.right-list-tit li:nth-child(2){flex:2;} +.right-list{border:0px;} +.right-list li{padding:13.7px 0px;} +.c14_ff90{font-size: 14px;color:#ff9000;} +.c14_ff66{font-size: 14px;color:#ff6666;} +.wst-textover{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;} +.gTop1,.gTop2,.gTop3{text-align: left;padding-left: 13px;background-image:url(./../img/flag-each-69x26.png);background-size: 80%;background-position: 0 0;background-repeat: no-repeat;color:#fff;} +.gTop2{background-position: 0 -37px;} +.gTop3{background-position: 0 -73px;} +.top-num{text-align: left;padding-left: 13px;} +.item_sale{border-radius: 50% 50% 50% 50%;border-width: 0px 1px 1px 0px;} +.main_mid_box .mid_r{flex:1;} +.mid_r_rtop{background: #fff;height: 29%;width: 96%;margin-bottom:20px;padding-left:10px;} +.rtop_main{padding:10px 0} +.rtop_item{margin-top:5px;} +.mid_r_rbottom{background: #fff;height: 67%;width: 96%;padding-left:10px;} +.sale_info{margin-top:20px;width: 99%;height: 300px;background: #fff;padding-left:10px;} +.shop_tips li{padding: 6px 15px;width: 200px} +.shop_tips li a:hover{color:#e33c3c;} +.order_remaker{color:#ff6c00;padding: 5px;border: 1px solid #ddd;border-top:none;} +.order_from{ margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + +#shoprole th,#shoprole td{border: solid 1px #E6E6E6;} +#shoprole dl{ border-bottom: solid 1px #E6E6E6;} +#shoprole dl .dt1,#shoprole dl .dt2{ font-size: 12px; + line-height: 30px; + color: #333; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + text-align: right; + display: inline-block; + width: 120px; + padding: 0 4px; + margin: 0; + +} +#shoprole dl .dd1{ font-size: 12px; + font-size: 12px; + line-height: 30px; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + display: inline-block; + width: 690px; + padding: 0px 4px; + border-left: solid 1px #E6E6E6; +} +#shoprole dl .dd2{ + font-size: 12px; + line-height: 30px; + vertical-align: top; + letter-spacing: normal; + word-spacing: normal; + display: inline-block; + width: 500px; + padding: 0px 4px; + border-left: solid 1px #E6E6E6; +} +#shoprole td label{width:120px;text-align: left;display: inline-block;} + +.uinfo>input{ width: 235px;} +.wst-form input, textarea { + background-color: white; + border: 1px solid #ccc; + border-radius: 2px; + box-shadow: 1px 1px 1px #f0f0f0 inset; + font-family: inherit; + font-size: 100%; + margin: 3px; + padding: 5px; + vertical-align: middle; +} +.uinfo-form tr td { + height: 40px; +} +.wst-list-add{float: right;line-height:16px;height:16px;margin-top:2px;} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/shopapply.css b/hyhproject/home2/view/default/css/shopapply.css new file mode 100755 index 0000000..cad3a31 --- /dev/null +++ b/hyhproject/home2/view/default/css/shopapply.css @@ -0,0 +1,56 @@ +.stepflex{float:right;border-top:5px solid #ccc;text-align:center;width:960px;margin:60px 0px 0px 50px;} +.stepflex dl{border-top:5px solid #ccc;float:left;position:relative;top:-5px;width:160px;} +dl.doing{border-top-color:#04bd3d;} +.doing .s-num{background-position:-23px 0;} +.s-num,.s-num1{color:#fff;font-weight: 700;height:23px;line-height:23px;margin:-15px auto 0;position:relative;width:23px;border-radius:25px;} +.s-num{background:#04bd3d;} +.s-num1{background:#ccc;} +.s-text1{line-height:30px;} +.s-text{line-height:30px;color:#04bd3d;} +select{height:29px;} +.webuploader-container{overflow:hidden;} +.apply-banner{width: 100%;height:320px;position: relative;z-index: 1;top:-8px;} +.apply-msg-box{filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColorstr='#3F000000', endColorstr='#3F000000');background:rgba(0,0,0,0.25); width: 280px; height: 300px; z-index: 9; margin-top:30px; border-radius: 5px;} +.apply-msg-box h3{color:#fff;font: 600 17px/24px; color: #FFF; padding: 12px 10px 4px 10px; margin: 0 10px 10px;box-shadow: 0 1px 0 rgba(0,0,0,0.1);} +.apply-msg-box .title{color: #FFF;margin-top:10px;line-height:30px;padding-left:15px;padding-right:15px;} +.apply-msg-box ul{color: #FFF;padding-left:15px;padding-right:15px;height:149px;} +.apply-msg-box ul li{margin-top:10px;line-height:23px;list-style-type: disc;margin-left:15px;} +.apply-msg-box .bottom{border-radius:0 0 5px 5px;margin-top:10px;padding-top:10px;padding-bottom:10px;padding-left:7px;filter:progid:DXImageTransform.Microsoft.gradient(enabled='true',startColorstr='#7F000000', endColorstr='#7F000000'); background:rgba(0,0,0,0.5); text-align: center;} +.wst-slide{position: relative;height:350px;overflow:hidden;top:-320px;z-index:-1} +.apply-tips{color: #777;background-color: #EEE;width: 100%;height: 60px;} +.apply-tips .title{width: 60px;height: 48px;display: inline-block;padding: 6px 12px 6px 24px;} +.apply-tips .title i{background: url(../img/ic_volume_24x24.png) no-repeat 0px 0;display: block;width: 24px;height: 24px;float: left;margin: 0 18px;} +.apply-tips .content{font: 12px/20px "microsoft yahei";vertical-align: top;display: inline-block;width: 920px;padding: 10px;} +.apply-step{font-size: 0;width: 800px;height: 110px;margin: 30px auto;overflow: hidden;} +.apply-step span { font-size: 12px; vertical-align: middle; letter-spacing: normal; word-spacing: normal; display: inline-block; *display: inline; *zoom: 1;} +.apply-step span.step { color:#777;line-height: 20px; text-align: center; width: 80px;} +.apply-step span.step i { background: url(../img/btn_80x80.png) no-repeat; display: block; width: 80px; height: 80px; margin-bottom: 10px;} +.apply-step span.step i.a { background-position: -12px 0px;} +.apply-step span.step i.b { background-position: -94px 0px;} +.apply-step span.step i.c { background-position: -176px 0px;} +.apply-step span.step i.d { background-position: -258px 0px;} +.apply-step span.step i.e { background-position: -340px 0px;} +.apply-step span.arrow { background: url(../img/btn_80x80.png) no-repeat -439px -30px; width: 60px; height: 22px; margin: 0 20px;margin-top:-25px;} +.apply-step-head{margin-top:20px;border-bottom:dotted 1px #CCC;font-weight:600;font-size:16px;line-height:30px;padding-left:10px;} + +.main-head{font-size:17px;font-weight:bold;height:35px;line-height:35px;text-align:left;} +.apply-box {border-top: 2px solid #FC7A64;border-left: 1px solid #eeeeee;border-right: 1px solid #eeeeee;border-bottom: 1px solid #eeeeee;padding: 5px 0px 0px 5px;} +.apply-agreement-box{height:350px;border:1px solid #eeeeee;padding:5px;overflow:auto;margin:0 auto;} +.apply-agreement-box .tip{color:gray} +.agreement-table{width:100%;margin-bottom:10px;} +.agreement-table th{text-align: right;width:250px;} +.agreement-table td{text-align: left} +.agreement-table .head-ititle{background:url('../img/img_seller_ggjt.png') no-repeat 5px 4px;padding-left:28px;padding-bottom:5px;font-weight:bold;} +.agreement-table input[type=text]{margin:2px;} +.agreement-table textarea{margin:2px;} +.agreement_box{text-align:center;margin-top:5px;} +.agreement-bottom{padding:10px 5px;text-align: center} +.examine-tips{text-align: center;width:100%;padding-top:60px;padding-bottom:80px;font-weight: 600;font-size:16px;color:#999;} +label{margin-right:20px;} +.webuploader-pick{padding:3px 10px;} +.goodsCat{width:140px;margin-right:20px;float:left;} +.wst-tab-box {width: 100%;height: auto;margin: 0px auto;background: #ffffff;margin-top:10px;} +.wst-tab-nav {margin: 0;padding: 0;height: 35px;top: 0px;z-index: 30;background: #ffffff;width:100%;border-bottom: 1px solid #eeeeee;border-left: 1px solid #eeeeee} +.wst-tab-nav li {width:23.24%;cursor: pointer;float: left;margin: 0 0px;list-style: none;border: 1px solid #eee;border-bottom: none;border-left: none;line-height: 34px;text-align: center;color: #000000;padding-left: 10px;padding-right: 10px;} +.wst-tab-nav .on {border-top: 1px solid #ff2704;border-bottom: 1px solid #ffffff;color: #ff2704;font-weight:bold;} +.wst-tab-content {padding: 5px;width: 99%;height: auto;border: 1px solid #eee;border-top:none;background: #FFF;} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/shophome.css b/hyhproject/home2/view/default/css/shophome.css new file mode 100755 index 0000000..feabb60 --- /dev/null +++ b/hyhproject/home2/view/default/css/shophome.css @@ -0,0 +1,105 @@ +@CHARSET "UTF-8"; +.wst-shop-h{padding:10px 0} +.wst-shop-img{float:left;margin-top:3px;width:90px;height:90px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-img img{max-width:90px;max-height:90px;border-radius:5px} +.wst-shop-info{float:left;width:45%;margin-left:10px} +.wst-shop-info p{float:left;line-height:50px;width:100%;color:#222;font-size:17px;font-family:"microsoft yahei"} +.wst-shop-info2,.wst-shop-info3{float:left;width:100%} +.wst-shop-info2 img{float:left;width:16px;margin-right:3px} +.wst-shop-info2 span{float:left;color:#dda315;margin-right:10px} +.wst-shop-info3{margin-top:7px} +.wst-shop-code{float:left;margin-top:-3px;width:24px;height:24px;cursor:pointer;background:url(../img/img_sjck.png) no-repeat;background-size:100%} +.wst-shop-codes{width:131px;height:131px;margin-top:24px;border:1px solid #dedbdb;position:absolute;z-index:1000;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);border-radius:5px} +.wst-shop-codes:after{top:-16px;border-color:transparent transparent #fff} +.wst-shop-eva,.wst-shop-evaa{float:left;margin-right:16px} +.wst-shop-evaa{padding-left:20px} +.wst-shop-info3 .j-fav,.wst-shop-info3 .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 1px 2px no-repeat} +.wst-shop-info3 .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 0 -23px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shop-info3 .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 0 1px no-repeat;text-decoration:none} +.wst-shop-red{color:#e25041} +.wst-shop-sea{float:right;width:42.999999%;margin-top:20px} +.wst-shop-sea input{float:left;outline:0;font-size:15px;height:32px;width:360px;margin-right:3px;padding-left:8px;border:1px solid #fc6047} +.wst-shop-sea .search{float:left;width:60px;height:32px;line-height:32px;text-align:center;color:#fff;margin-left:6px;background:url(../img/img_bg_search.png) no-repeat} +.wst-shop-word{float:left;margin-top:8px;width:100%;height:18px;overflow:hidden} +.wst-shop-tu{text-align:center;width:100%;height:110px}@media screen and (max-width:1200px){.wst-shop-tu{min-width:1200px} +.wst-shop-nav{min-width:1200px}} +.wst-shop-nav{background-color:#fc6047} +.wst-nav-box{width:1200px;margin:0 auto;line-height:36px;color:#fff} +.wst-nav-box li{padding:0 26px;text-align:center;color:#fff;font-size:15px;font-family:"microsoft yahei"} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{background:#cb2004;background-size:cover} +.wst-nav-box .liselect{list-style-type:none} +.wst-nav-box .homepage{float:right;margin-top:6px;padding:0 8px;height:22px;line-height:22px;color:#fff;border:1px solid #fff} +.wst-nav-box .homepage:hover{color:#fc6047;background:#fff;border:1px solid #fc6047} +.ck-slide{width:1200px;height:400px;margin:3px auto;margin-bottom:9px} +.ck-slide ul.ck-slide-wrapper{height:400px} +.wst-shop-contl{float:left;width:19.222222%;padding-bottom:20px} +.wst-shop-contr{float:right;width:79.555555%} +.wst-shop-cat{margin-top:9px;border:1px solid #ddd} +.wst-shop-best,.wst-shop-lat{margin-top:15px;border:1px solid #ddd} +.wst-shop-cat li{height:26px;line-height:26px;list-style-type:none} +.wst-shop-cat li:hover{color:#ff5605;cursor:pointer} +.wst-shop-cat a li{color:#666} +.wst-shop-conlp{height:35px;line-height:35px;text-align:center;background:#ebebeb;font-size:16px;font-family:"microsoft yahei"} +.wst-shop-catt{padding-left:10px} +.wst-shop-catts{padding-left:20px} +.js-shop-plus{text-indent:20px;background:url(../img/store_icon_zk.png) 2px 4px no-repeat} +.js-shop-redu{text-indent:20px;background:url(../img/store_icon_sq.png) 2px 4px no-repeat} +.wst-shop-bestg{float:left;margin:5px} +.wst-shop-besti{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shop-besti img{max-width:72px;max-height:72px} +.wst-shop-bestgp1{height:36px} +.wst-shop-bestgp2{line-height:20px} +.wst-shop-bestg p{float:left;width:142px;margin-left:3px;overflow:hidden} +.wst-shop-bestg a:hover{color:#ff5605} +.wst-shop-bestpi{color:#ee8f4f} +.wst-shop-bestpr{color:#d86232;font-weight:bold} +.wst-shop-bestpr2{float:right;color:#c4c2c2;text-decoration:line-through} +.wst-shop-conrp{height:35px;line-height:35px;text-indent:1em;background:#ebebeb;font-size:16px;font-family:"microsoft yahei";margin:9px 0 6px 0} +.wst-shop-recb{padding:5px 0;background:#f2efea} +.wst-shop-rgoods,.wst-shop-list .wst-shop-goods{float:left;width:218px;padding:5px;background:#fff;border:1px solid #dadada;margin:0 4px} +.wst-shop-rgoods:hover,.wst-shop-goods:hover{border:1px solid #e5e5e5;-webkit-box-shadow:0 0 10px #ddd;-moz-box-shadow:0 0 10px #ddd;box-shadow:0 0 10px #ddd} +.wst-shop-list .wst-shop-goimg{float:left;width:207px;height:207px;vertical-align:middle;display:block;position:relative} +.wst-shop-goimg a{width:207px;height:207px;padding-left:5px;padding-top:5px;display:table-cell;vertical-align:middle} +.wst-shop-goimg img{max-width:207px;max-height:207px} +.wst-shop-goimg span{width:230.5px;height:30px;line-height:30px;color:#fff;text-align:center;opacity:.8;background:#d0260c;display:block;position:absolute;left:-6px;bottom:-5px;display:none} +.wst-shop-goimg span:hover{background:#e5280b} +.wst-shop-gonam{float:left;width:100%;height:36px;color:#838383;font-size:15px;font-family:"microsoft yahei";margin-top:18px} +.wst-shop-gonam a:hover{color:#f60505} +.wst-shop-rect{float:left;width:100%;margin-top:8px;font-family:"microsoft yahei"} +.wst-shop-rect span{color:#ea523b;font-size:16px;line-height:26px;font-weight:bold} +.wst-shop-rect .wst-shop-recta{float:right;height:26px;color:#ff5605;line-height:26px;padding:0 12px;border-radius:2px;border:1px solid #dadada} +.wst-shop-rect .wst-shop-recta2{float:right;height:26px;color:#c9c3c2;line-height:26px;padding:0 12px;border-radius:2px;border:1px solid #dadada} +.wst-shop-rect .wst-shop-recta:hover{color:#fff;background:#ff5605;border:1px solid #ff5605} +.wst-shop-list{padding:10px 0} +.wst-shop-listh{float:left;width:100%;font-family:"microsoft yahei"} +.wst-shop-listh a{float:left;color:#525252;height:19px;padding:6px 16px;text-align:center;font-size:15px;border:1px solid #e9e7e7} +.wst-shop-listh a:hover{border:1px solid #ff8043} +a.wst-shop-a{color:#fff;background:#ff8043;border:1px solid #ff8043} +.wst-shop-store,.wst-shop-store2,.wst-shop-store3{float:right;width:16px;height:13px;margin:3px 0 0 3px} +.wst-shop-store{background:url(../img/store_icon_sx.png) 0 0 no-repeat} +.wst-shop-store2{background:url(../img/store_icon_sx_sel.png) 0 0 no-repeat} +.wst-shop-store3{background:url(../img/store_icon_sx_sel_up.png) 0 0 no-repeat} +.wst-price-ipts{float:left;position:relative}input.wst-price-ipt{width:66px;height:27px;outline:0;padding-left:18px;border:1px solid #e9e7e7}input.wst-price-ipt:focus{border:1px solid #ff8043} +.wst-price-ipt1{position:absolute;left:13px;top:8px} +.wst-price-ipt2{position:absolute;right:71px;top:8px} +.wst-shop-but{outline:0;background:#ebebeb;color:#9f9696;border:1px solid #dad7d7;cursor:pointer} +.wst-shop-but:not(.disabled):not(:disabled):active,.wst-shop-but.active{background:#f1f1f1;background-clip:padding-box} +.wst-shop-listg{padding-top:10px} +.wst-shop-list .wst-shop-goods{margin-bottom:6px} +.wst-shop-goodp1{margin-top:8px} +.wst-shop-goodp1,.wst-shop-goodp2{float:left;width:100%;line-height:20px;font-family:"microsoft yahei";padding:2px 0 2px 0} +.wst-shop-goodpr{color:#ea523b;font-size:16px;font-weight:bold;overflow:hidden;float:left} +.wst-shop-goodpr2{color:#ed1a8d} +.wst-shop-goodpr3{color:#c4c2c2;width:220px;overflow:hidden} +.wst-shop-goodpr4{color:#249ee7} +.wst-shop-pa{padding:28px 0 35px 300px} +.wst-shop-info2 img.wangwang{padding-top:1px;width:65px;height:22px} +.wst-shop-goimg img.goodsImg{max-width:207px;max-height:207px} +.wst-shop-share{float:right;position:relative;top:-6px;margin-right:6px} +.wst-shop-list img{max-width:1200px}@-webkit-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@-moz-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@-o-keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}}@keyframes a1{0%{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} +100%{opacity:1;-webkit-transform:scale(1.1);-moz-transform:scale(1.1);-o-transform:scale(1.1);transform:scale(1.1)}} +.wst-shop-rgoods:hover img{-webkit-animation:a1 1s .1s ease both;-moz-animation:a1 1s .1s ease both;animation:a1 .5s .1s ease both;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%} +.notice_img{width:15px;height:15px;vertical-align:middle} \ No newline at end of file diff --git a/hyhproject/home2/view/default/css/shopstreet.css b/hyhproject/home2/view/default/css/shopstreet.css new file mode 100755 index 0000000..56c0f87 --- /dev/null +++ b/hyhproject/home2/view/default/css/shopstreet.css @@ -0,0 +1,49 @@ +@CHARSET "UTF-8"; +a{cursor:pointer} +img{border:none} +.wst-shopstr-ads{padding:10px 0} +.wst-shopstr-ads img{width:1200px;height:220px} +.wst-shopstr-cat{margin:10px 0 20px 0;padding:10px 20px;border:1px solid #dddbdb} +.wst-shopstr-catt{height:23px;color:#333;border-bottom:1px dashed #b5b5b5} +.wst-shopstr-cat span{float:left;margin:8px 60px 0 0;padding:8px 5px} +.wst-shopstr-cat span:hover{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.js-selected{cursor:pointer;color:#fff;background:#fc6047;border-radius:3px} +.wst-shopstr-shop{margin-top:20px;padding:10px;border:1px solid #dddbdb} +.wst-shopstr-shop:hover{border:1px solid #fc6047} +.wst-shopstr-shopl{float:left;width:150px;height:150px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shopstr-shopi{float:left;width:26%;margin-left:12px} +.wst-shopstr-shopr{float:right;width:60%} +.wst-shopstr-shopl a{width:150px;height:150px;display:table-cell;vertical-align:middle} +.wst-shopstr-shopl a img{max-width:150px;max-height:150px} +.wst-shopstr-name{height:32px;line-height:32px} +.wst-shopstr-name .name{float:left;font-size:18px;color:#2e2e2e;font-weight:700;width:170px;height:30px;display:block;overflow:hidden} +.wst-shopstr-name .name:hover{color:#f53e28} +.wst-shopstr-name .favorite{padding:5px 5px 5px 23px;loat:left;border:1px solid #ededed;margin-left:5px} +.wst-shopstr-name .j-fav,.wst-shopstr-name .j-fav:hover{background:url(../img/iconfont_guanzhu_sel.png) 4px 5px no-repeat} +.wst-shopstr-name .j-fav2{background:url(../img/iconfont_guanzhu_nor.png) 3px -19px no-repeat;transition:background-position .15s ease-in-out 0s} +.wst-shopstr-name .j-fav2:hover{background:url(../img/iconfont_guanzhu_nor.png) 3px 5px no-repeat;text-decoration:none} +.wst-shopstr-pr{float:left;width:100%;margin-top:7px;color:#807f7f} +.wst-shopstr-pr .company{text-decoration:underline;color:#57c4f5} +.wst-shopstr-pr .company:hover{color:#31b0e9} +.wst-shopstr-score{width:118px;height:96px;position:absolute;left:25px;bottom:-95px;color:#545252;text-indent:1em;cursor:pointer;background:url(../img/img_bg_xiala.png) 0 0 no-repeat} +.wst-shopstr-score .title{font-weight:700} +.wst-shopstr-more{float:left;width:100%} +.wst-shopstr-more a{font-size:13px;color:#666} +.wst-shopstr-more a:hover{color:#eb5f43} +.wst-shopstr-more span{width:100px;height:20px;color:#fff;line-height:20px;background:url(../img/img_dztj_bg.png) no-repeat} +.wst-shopstr-good{padding-top:2px;margin-left:26px} +.wst-shopstr-goods{float:left;margin:0 3px} +.wst-shopstr-goodimg{width:100px;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shopstr-goodimg a{width:100px;height:100px;display:table-cell;vertical-align:middle} +.wst-shopstr-goodimg a img{max-width:100px;max-height:100px} +.wst-shopstr-goods span{float:left;width:100px;margin-top:1px;text-align:center;color:#fc6047;font-weight:700} +.shopstrPaging{padding:20px 0 50px 480px} +.als-container{position:relative;width:100%;margin:0 auto} +.als-viewport{position:relative;overflow:hidden;margin:0 auto} +.als-wrapper{position:relative;list-style:none} +.als-item{position:relative;display:block;text-align:center;cursor:pointer;float:left} +.als-next,.als-prev{position:absolute;cursor:pointer;clear:both} +.als-item img{width:135px;height:135px;vertical-align:middle} +.als-next,.als-prev{top:40px} +.als-prev{left:-25px} +.als-next{right:-30px} diff --git a/hyhproject/home2/view/default/css/user.css b/hyhproject/home2/view/default/css/user.css new file mode 100755 index 0000000..5f116fc --- /dev/null +++ b/hyhproject/home2/view/default/css/user.css @@ -0,0 +1,382 @@ +@CHARSET "UTF-8"; +.wst-wrap{margin:0 auto} +.wst-main{margin:auto;width:1200px;min-height:600px;height:auto;padding-top:15px} +.wst-menu{background:#fff;width:198px;float:left;margin-right:15px;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-content{background:#fff;min-height:948px;height:auto;width:990px;float:right;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-footer{border-top:1px solid #ddd;margin-top:5px} +.wst-menu-title{position:relative;width:143px;display:block;padding:10px 5px 10px 50px;font-weight:bolder;border-top:1px solid #ccc;color:#000;font-size:16px;font-family:"microsoft yahei";background:#e9e9e9;cursor:pointer} +.wst-menu-title img{padding:0 0 3px 6px} +.wst-menu{width:198px;margin:0;padding:0;min-height:948px} +.wst-menu li{list-style-type:none;padding:0 0 0 50px;height:35px;line-height:35px;color:#6a6868;cursor:pointer} +.wst-menu li:hover,li.wst-menua{font-weight:bolder;color:#e23e3d;border-left:2px solid #e23e3d} +.wst-menu .selected{background-color:#e23e3d;font-weight:bolder;color:#fff} +.wst-menu .liselect{background-color:#e23e3d;font-weight:bolder;color:#fff} +.wst-list{width:100%;border:1px solid #ddd;border-collapse:collapse} +.wst-list thead tr th{height:40px;line-height:40px;border-bottom:1px solid #ccc;text-align:left;padding-left:5px;background:#eee} +.wst-list tbody tr td{word-wrap:break-word;word-break:break-all;height:40px;line-height:40px;text-align:left;padding-left:5px} +.wst-list tbody tr:nth-child(even){background:#fcfae1} +a:active,a:hover{text-decoration:none;color:red} +.wst-form{border-collapse:collapse} +.wst-form tr{height:30px;line-height:30px} +.wst-form tr th{color:#707070;text-align:right} +.wst-form tr td{text-align:left} +.wst-form input,textarea{background-color:white;border:1px solid #ccc;border-radius:2px;box-shadow:1px 1px 1px #f0f0f0 inset;font-family:inherit;font-size:100%;margin:3px;padding:5px;vertical-align:middle} +.wst-form select{box-shadow:2px 2px 2px #f0f0f0 inset;font-family:inherit;font-size:100%;vertical-align:middle;margin:3px} +.wst-form select option{padding:2px} +.wst-shop-nav{background-color:#e45050;border-top:6px solid #e45050;text-align:center} +.wst-nav-box{width:1200px;margin:0 auto;line-height:33px;color:#fff} +.wst-nav-box li{width:145px;text-align:center;color:#fff;font-size:18px;font-family:"microsoft yahei";margin-bottom:-1px} +.wst-nav-box li:hover,.wst-nav-box .wst-nav-boxa{color:#e45050;background:url(../img/user_bg_nav.png) -10px 0 no-repeat} +.wst-nav-box .liselect{list-style-type:none} +.wst-appsaler{margin-top:30px;text-align:center;margin-bottom:30px;line-height:30px} +.wst-menu-title span{position:absolute;left:20px;top:8px;display:inline-block;width:20px;height:20px;background-image:url(../../../View/default/images/icon_leftmenu.png);background-repeat:no-repeat} +select{box-shadow:2px 2px 2px #f0f0f0 inset;font-family:inherit;font-size:100%;padding:2px;vertical-align:middle}input,textarea{background-color:white;border:1px solid #ccc;border-radius:4px;font-family:inherit;font-size:100%;margin:3px;padding:5px;vertical-align:middle} +.wst-tab-box{width:100%;height:auto;margin:0 auto} +.wst-tab-nav{margin:0;padding:0;height:31px} +.wst-tab-nav li{cursor:pointer;float:left;margin:0;list-style:none;border:1px solid #ddd;border-bottom:0;border-left:none;line-height:30px;text-align:center;background:#eee;color:#000;padding-left:10px;padding-right:10px} +.wst-tab-nav .on{background:none repeat scroll 0 0 #e23e3d;border-bottom:0 none;color:#fff;font-weight:bold} +.wst-tab-content{padding:5px;width:99%;height:auto;border:1px solid #ddd;background:#FFF} +.wst-appraise-box{margin:0 auto;margin-top:20px;margin-bottom:10px} +.wst-appraise-box .appraise-title{margin-top:10px;font-weight:bold;text-align:left;padding-left:30px;padding-bottom:10px} +.wst-appraise-box .appraise-title .tips{font-weight:normal;color:#999} +.wst-appraise-box .main{border:1px solid #e9e9e9;border-top:2px solid #999} +.wst-appraise-box .head{line-height:35px;background-color:#e9e9e9;font-weight:bold} +.wst-appraise-box .goods-no{float:left;width:50px;text-align:center} +.wst-appraise-box .goods-name{float:left;width:600px} +.wst-appraise-box .goods-name2{float:left;width:530px;line-height:30px} +.wst-appraise-box .goods-status{float:left;width:120px;text-align:center} +.wst-appraise-box .goods-buy-time{float:left;width:220px;text-align:center} +.wst-appraise-box .appraise-box{text-align:center;background-color:#dbeaf9;padding-top:5px} +.wst-appraise-box .goods-txt{line-height:70px} +.wst-appraise-box .goods-img{border:0;margin-top:5px;margin-bottom:5px} +.wst-appraise-box .appraise-box .main-box{width:800px;margin:0 auto} +.wst-appraise-box .appraise-box .item{line-height:40px;margin-top:5px} +.wst-appraise-box .appraise-box .item .title{float:left;width:80px;text-align:right} +.wst-appraise-box .appraise-box .item .content{float:left;width:700px;text-align:left} +.wst-appraise-box .appraise-box .btn-box{padding-right:80px;margin:15px;float:right} +.wst-goods-tb{margin-top:3px;margin-bottom:2px;border:0} +.wst-complain-detail{width:100%;border-collapse:collapse} +.wst-complain-detail tr{height:25px;line-height:25px} +.wst-complain-detail tr th{color:#707070;text-align:right;font-size:12px} +.wst-complain-detail tr td{text-align:left;color:#707070} +.wst-complain-detail .head{font-weight:bold;border-bottom:1px dotted #ddd} +.wst-complain-left{width:250px;height:100%;border:1px solid #ddd;text-align:left;background:#fff;float:left} +.wst-complain-order-head{width:240px;height:25px;line-height:25px;border-bottom:1px solid #ddd;font-weight:bold;padding:5px;background:#f5f5f5} +.wst-complain-order-goods{width:240px;height:200px;line-height:30px;padding:5px;border-bottom:1px solid #ddd;overflow-y:auto} +.wst-complain-main{float:right;width:732px;overflow:hidden;border:1px solid #ddd} +.wst-complain-order-info{padding:5px;display:block;height:100%} +.wst-complain-order-info dt{float:left;width:70px;color:#999;padding:1px 0;display:block;height:20px} +.wst-complain-order-info dd{overflow:hidden;color:#666;padding:1px 0;width:170px;display:block;height:20px} +.wst-complain-box{border-bottom:1px solid #ddd;width:732px;padding:5px} +.wst-complain-footer{clear:both;width:100%;text-align:center;padding:5px 0} +.jcrop-holder #preview-pane{display:block;position:absolute;z-index:2000;top:10px;right:10px;padding:6px;border:1px rgba(0,0,0,.4) solid;background-color:white;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2);-moz-box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2);box-shadow:1px 1px 5px 2px rgba(0,0,0,0.2)} +#preview-pane .preview-container{width:150px;height:150px;overflow:hidden;border:1px dashed #777} +#userPhotoCutBox>p{min-width:500px;min-height:500px;background:url('../img/cut_bg.png') repeat 0 0} +#cutArea{border:1px dashed #777;position:relative;top:-2px;left:-2px;float:left}#c-btn{width:35%;margin-left:15%} +.cut-btn{width:80px;height:30px;background:#e02f2f;color:white;font-weight:bold} +.cut-help{width:150px;position:absolute;top:185px;right:10px} +.cut-help p{margin-top:7px;width:150px} +.wst-lite-bac{background:#fff} +.wst-lite-tit{float:left;width:100px;margin:16px 0 0 10px} +.wst-lite-tit span{float:left;color:#e45050;font-size:19px;margin-left:10px;font-family:"microsoft yahei"}a.wst-lite-in{float:left;margin-top:6px;padding:3px 8px;color:#e45050;border:1px solid #e45050} +a.wst-lite-in:hover{color:#fff;border:1px solid #fff;background:#e45050} +.wst-lite-sea{float:right;background:#fff;margin:20px 35px 0 0} +.wst-lite-sea .search{border:2px solid #e23c3d;height:35px;position:relative} +.wst-lite-sea .search .j-search-type{width:78px;top:0;line-height:36px;position:absolute;padding:0;border-right:2px solid #e23c3d;border-left:2px solid #e23c3d;cursor:pointer;left:-2px;text-align:center} +.wst-lite-sea .search .j-type-list{width:70px;top:35px;line-height:36px;position:absolute;padding:0 4px;border:2px solid #e23c3d;cursor:pointer;background-color:#fff;left:-2px;z-index:100;border-top:0;display:none;text-align:center} +.wst-lite-sea .search .j-search-type i{top:15px;right:6px;height:7px;width:0;overflow:hidden;font-style:normal;color:#6a6a6a;display:block;position:absolute} +.wst-lite-sea .search .j-search-type s{position:relative;top:-17px;text-decoration:none} +.wst-lite-sea .search .j-type-list div:hover{color:#e23c3d} +.wst-lite-sea .search .search-ipt{border:0 none;color:#565656;float:left;font-family:Microsoft Yahei;font-size:14px;line-height:30px;overflow:hidden;padding:0;width:330px;height:30px;border:36px;outline:0;padding-left:84px;box-shadow:none} +.wst-lite-sea .search .search-btn{cursor:pointer;font-size:15px;font-weight:bolder;height:35px;line-height:36px;position:absolute;right:0;text-align:center;top:0;width:52px;background:url(../img/btn_search_red.png) 22px 6px no-repeat} +.wst-lite-cart{float:right;width:163px;height:40px;margin-top:20px;background:#e23c3d;position:relative;cursor:pointer} +.wst-lite-cart .word{float:left;width:112px;margin-top:4px;margin-left:20px;padding:5px 6px 7px 28px;color:#fff;font-size:14px;font-family:"microsoft yahei";background:url(../img/icon_gouwuche.png) no-repeat left center;position:relative} +.wst-lite-cart .num{font-size:14px;color:#fff;line-height:24px;text-align:center;position:absolute;display:block;width:27px;height:25px;background:url(../img/icon_number.png) no-repeat;right:19px;top:-12px} +.wst-lite-carts{width:332px;min-height:130px;margin-top:18px;border:1px solid #dedbdb;position:absolute;z-index:1200;background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.3);left:-171px;top:22px} +.wst-lite-carts:after{top:-16px;border-color:transparent transparent #fff} +.wst-lite-carts .carts{background:url(../img/top_icon_cartdown.png) 28px 47px no-repeat;width:332px;height:130px;text-indent:4.5em;line-height:130px;font-size:15px;color:#b9b6b6} +.wst-lite-cart .goods{float:left;width:96.666666%;border-bottom:1px dashed #bfbfbf;padding:5px} +.wst-lite-cart .goods .imgs{float:left;width:72px;height:72px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-lite-cart .goods .imgs a{width:72px;height:72px;display:table-cell;vertical-align:middle} +.wst-lite-cart .goods .imgs img{max-width:72px;max-height:72px} +.wst-lite-cart .goods .number{float:left;width:50%} +.wst-lite-cart .goods .number p{float:left;width:92%;margin-top:10px;padding-left:10px} +.wst-lite-cart .goods .price{float:right;text-align:right} +.wst-lite-cart .goods .price p{float:right;width:100%;line-height:20px;font-weight:bold;color:#df2003} +.wst-lite-cart .goods.price span{float:right;width:100%;line-height:20px} +.wst-lite-cart .goods .price span a:hover,.wst-lite-cart .goods .number p a:hover{color:#df2003} +.wst-lite-cart .comm{float:left;width:100%;font-weight:bold;line-height:32px} +.wst-lite-cart .comm span{font-size:15px;color:#e45050} +.wst-lite-cart .comm .span2{float:right;margin-right:10px} +.wst-lite-cart .btn{color:#fff;cursor:pointer;display:block;font-size:16px;font-weight:400;line-height:30px;margin:10px 0 16px 72px;max-width:200px;position:relative;text-align:center;text-decoration:none;text-transform:uppercase;vertical-align:middle;width:100%;border-radius:5px} +@media(min-width:400px){.wst-lite-cart .btn{display:inline-block;margin-right:2.5em} +.wst-lite-cart .btn:nth-of-type(even){margin-right:0}}@media(min-width:600px){.wst-lite-cart .btn:nth-of-type(even){margin-right:2.5em} +.wst-lite-cart .btn:nth-of-type(5){margin-right:0}} +.wst-lite-cart .btn:hover{text-decoration:none} +.wst-lite-cart .btn-3{background:#e3403a;border:1px solid #da251f;box-shadow:0 1px 0 #d6251f,1px 1px 1px #e02a24;font-weight:900;letter-spacing:1px;-webkit-transition:all 150ms linear;transition:all 150ms linear} +.wst-lite-cart .btn-3:hover{background:#e02c26;border:1px solid rgba(0,0,0,0.05);box-shadow:1px 1px 2px rgba(255,255,255,0.2);color:#ec817d;text-decoration:none;text-shadow:-1px -1px 0 #c2211c;-webkit-transition:all 250ms linear;transition:all 250ms linear} +.wst-nav-l{float:left;width:28px;height:33px} +.wst-nav-r{float:right;width:28px;height:33px} +.wst-bottom{margin:auto;width:1200px;padding-top:20px} +.wst-bottom-m{float:left;height:29px;width:100%;border-bottom:1px solid #f24040} +.wst-bottom-ml{float:left;height:28px;line-height:28px;padding:0 10px;cursor:pointer;background:#ebebeb;border-top:1px solid #e5e5e5;border-left:1px solid #e5e5e5;border-right:1px solid #e5e5e5;border-bottom:1px solid #f24040;font-family:"microsoft yahei"} +.wst-bottom-mr{float:right;margin-right:5px;font-family:"microsoft yahei"} +.wst-bottom-ms{background:#f5f5f5;border-top:1px solid #f24040;border-left:1px solid #f24040;border-right:1px solid #f24040;border-bottom:1px solid #f5f5f5} +.wst-bottom-mr img{margin-top:7px;margin-right:5px} +.wst-bottom-mr a{line-height:28px} +.wst-bottom-g{padding:10px 0} +.wst-bottom-gs{float:left;padding:10px;width:17.333333%;margin:0 5px;border-radius:3px;border:1px solid #dadada} +.wst-bottom-i{float:left;width:208px;height:208px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-bottom-i img{max-width:208px;max-height:208px} +.wst-bottom-n1,.wst-bottom-n2,.wst-bottom-n3,.wst-bottom-n4{float:left;width:100%;font-family:"microsoft yahei"} +.wst-bottom-n1{margin-top:16px;font-size:15px} +.wst-bottom-n2{margin-top:8px} +.wst-bottom-n4{margin-top:5px} +.wst-bottom-n2l{font-size:15px;color:#eb533e;font-weight:bold} +.wst-bottom-n2r,.wst-bottom-n3r{float:right;line-height:20px} +.wst-bottom-n2r span{color:#ec198a} +.wst-bottom-n3l{color:#bab8b8;line-height:20px} +.wst-bottom-n3r span{color:#1398e3} +.wst-bottom-gs:hover{cursor:pointer;border:1px solid #f24040} +.gray{color:#707070;font-weight:bold} +.uinfo-form tr td{width:330px;height:40px} +.uinfo>input{width:235px} +.uinfo-nav{border-bottom:1px solid #e45050} +.uinfo-nav .on{background:none repeat scroll 0 0 #e45050;border-bottom:0 none;color:#fff;font-weight:bold} +select{border:solid 1px #ccc;appearance:none;-moz-appearance:none;-webkit-appearance:none;padding-right:14px;background:url("../img/arrow.png") no-repeat scroll right center transparent} +select::-ms-expand{display:none} +.wst-radio+label{-webkit-appearance:none;background-color:#fafafa;border:1px solid gray;padding:6px;border-radius:50px;display:inline-block;position:relative} +.wst-radio+label:after{content:' ';width:6px;height:6px;border-radius:50px;position:absolute;top:3px;background:#99a1a7;box-shadow:inset 0 0 10px rgba(0,0,0,0.3);text-shadow:0;left:3px;font-size:32px} +.wst-radio:checked+label{border:1px solid #ff9a02} +.wst-radio:checked+label:after{content:' ';width:6px;height:6px;border-radius:50px;position:absolute;top:3px;background:#ff9a02;box-shadow:inset 0 0 10px #ff9a02;text-shadow:0;left:3px;font-size:32px} +.radio-box .wst-radio{position:relative;z-index:-654;left:16px;top:0} +.mt-1{position:relative;top:1px;left:0;cursor:pointer} +.checkbox-box-s{height:20px!important;cursor:pointer} +.wst-checkbox-s+label{-webkit-appearance:none;background-color:#fff;border:1px solid #d5d5d5;padding:6px;display:inline-block;position:relative} +.wst-checkbox-s+label:after{content:' ';width:6px;height:6px;position:absolute;top:3px;box-shadow:inset 0 0 10px #ccc;text-shadow:0;left:3px;font-size:32px} +.wst-checkbox-s:checked+label{border:1px solid #fc7373} +.wst-checkbox-s:checked+label:after{content:' ';width:6px;height:6px;position:absolute;top:3px;background:#fc7373;box-shadow:inset 0 0 10px #fc7373;text-shadow:0;left:3px;font-size:32px} +.checkbox-box-s .wst-checkbox-s{position:relative;z-index:-654;left:-5px;top:-1px;cursor:pointer} +.checkbox-box-s label{position:relative;top:-48px;left:1px} +.u-menu{height:25px;margin-left:4px;margin-top:10px} +.readMsg,.newMsg{width:36px;height:27px;background:url(../img/user_icon_info.png) no-repeat} +.newMsg{background-position:-66px -6px} +.readMsg{background-position:-11px -6px} +.msg-content{width: 630px} +.s-handle{color:#1cbbef!important;display:inline-block;margin:0 3px} +.s-handle:hover{color:#085cde} +.g{color:green} +.addr-btn{width:95px!important} +.wst-addr{width:98%;border:1px solid #ccc;margin:10px} +.wst-addr tbody tr td{height:20px} +.addr-title{text-align:right;width:130px} +.del{display:block;float:right;clear:right;padding-right:5px;font-size:15px;color:#c1c1c1!important} +.del:hover{color:red!important} +.edit>a{display:block;float:right;padding-right:20px;color:#4b4bfb} +.edit>a:hover{color:#0d0dc7} +.default{width:60px;height:25px;background:orange;line-height:25px;text-align:center;color:white;float:left;clear:left;margin-left:35px} +.wst-user-head{float:left;width:100%;border-bottom:1px solid #e45050} +.wst-user-head span{float:left;line-height:28px;padding:0 28px;color:#fff;background:#e45050;font-weight:bold} +.wst-user-head a{float:right;line-height:28px;padding:0 28px;color:#fff;background:#e45050} +.wst-user-tbar{height:35px;padding:2px;clear:both;padding-top:13px;padding-left:10px} +.wst-user-content{padding:2px;clear:both;margin-top:10px} +.wst-user-buta{height:30px;line-height:30px;margin-right:10px;margin-top:16px;padding:0 20px;color:#fff;background:#e45050;border-radius:3px} +.wst-user-buta:hover{color:#fff;background:#ea3232} +.wst-user-buta2{height:29px;padding:0 20px;background:#ebebeb;border-radius:3px;border:1px solid #dad7d7;box-shadow:0 0 1px rgba(0,0,0,0.3)} +.wst-user-buta2:hover{border-radius:3px;background:#f1f1f1;box-shadow:0 0 0 rgba(0,0,0,0.3)} +.wst-sec-but:not(.disabled):not(:disabled):active,.wst-sec-but.active{background:#f96a54;background-clip:padding-box;border:1px solid #f96a54} +.wst-sec-but2{outline:0;background:#ebebeb;color:#9f9696;border:1px solid #dad7d7;border-radius:3px;cursor:pointer} +.wst-sec-but2:not(.disabled):not(:disabled):active,.wst-sec-but2.active{background:#f1f1f1;background-clip:padding-box} +.wst-order-list{width:100%;border-color:grey;border-collapse:separate;border-spacing:0} +.wst-order-list .head{height:32px;line-height:32px;text-align:center;background:#f5f5f5;color:#666;font-weight:400} +.wst-order-list .empty-row{height:20px} +.wst-order-list .order-head{background:#f5f5f5;height:31px;line-height:31px;color:#aaa;overflow:hidden} +.wst-order-list .order-head td{padding-left:5px;padding-right:5px;border:1px solid #e5e5e5;border-bottom:0} +.wst-order-list .goods-box td:first-child{border-left:1px solid #e5e5e5} +.wst-order-list .goods-box td{padding:5px;border:1px solid #e5e5e5;border-top:0;border-left:0} +.wst-order-list .time{float:left;margin-right:30px} +.wst-order-list .orderno{float:left;margin-right:30px;width:250px;text-align:left} +.wst-order-list .shop{float:left;margin-right:20px;width:150px;text-align:left} +.wst-order-list .link{float:left} +.wst-order-list .goods-img{width:60px;height:60px;text-align:center;vertical-align:middle;display:block;position:relative;float:left} +.wst-order-list .goods-img a{display:table-cell;vertical-align:middle;width:60px;height:60px} +.wst-order-list .goods-img a img{max-width:60px;max-height:60px} +.wst-order-list .goods-name{float:left;margin-left:5px;line-height:25px;width:500px} +.wst-order-list .goods-extra{float:right;margin-left:5px} +.wst-order-list .line{border-bottom:1px solid #ddd;margin-bottom:2px;padding-bottom:2px} +.order-box{margin-bottom:5px;border-bottom:1px solid #ddd} +.order-box .box-head{font-weight:bold;height:30px;line-height:30px;padding-left:5px;} +.order-pc{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_1.png) 0 0 no-repeat;background-size:90%} +.order-mo{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_2.png) 0 0 no-repeat;background-size:100%} +.order-wx{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_3.png) 0 0 no-repeat;background-size:100%} +.order-app{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_4.png) 0 0 no-repeat;background-size:100%} +.order-ios{float:left;margin:7px 5px 0 0;width:18px;height:18px;background:url(../img/order_source_5.png) 0 0 no-repeat;background-size:100%} +.order-box .log-box{height:132px} +.order-box .log-box .icon{float:left;width:60px;height:60px} +.order-box .log-box .icons{float:left;width:60px;height:60px} +.order-box .log-box .icon11{background:url(../img/user_icon_rzxx.png) -15px -12px no-repeat} +.order-box .log-box .icon21{background:url(../img/user_icon_rzxx.png) -105px -12px no-repeat} +.order-box .log-box .icon31{background:url(../img/user_icon_rzxx.png) -194px -12px no-repeat} +.order-box .log-box .icon41{background:url(../img/user_icon_rzxx.png) -282px -12px no-repeat} +.order-box .log-box .icon51{background:url(../img/user_icon_rzxx.png) -373px -12px no-repeat} +.order-box .log-box .icon12{background:url(../img/user_icon_rzxx.png) -15px -62px no-repeat} +.order-box .log-box .icon22{background:url(../img/user_icon_rzxx.png) -105px -62px no-repeat} +.order-box .log-box .icon32{background:url(../img/user_icon_rzxx.png) -194px -61px no-repeat} +.order-box .log-box .icon42{background:url(../img/user_icon_rzxx.png) -282px -63px no-repeat} +.order-box .log-box .icon52{background:url(../img/user_icon_rzxx.png) -373px -62px no-repeat} +.order-box .log-box .icon13{background:url(../img/user_icon_rzxx.png) -19px -123px no-repeat} +.order-box .log-box .icon23{background:url(../img/user_icon_rzxx.png) -105px -122px no-repeat} +.order-box .log-box .icon33{background:url(../img/user_icon_rzxx.png) -194px -121px no-repeat} +.order-box .log-box .icon43{background:url(../img/user_icon_rzxx.png) -282px -122px no-repeat} +.order-box .log-box .icon53{background:url(../img/user_icon_rzxx.png) -373px -121px no-repeat} +.order-box .log-box .arrow{float:left;color:#979797;font-size:15px;font-weight:bold;margin-top:18px} +.order-box .log-box .arrow2{color:#7ebb53} +.order-box .log-box .state{float:left;width:100%;margin-left:18px} +.order-box .log-box .state2{float:left;width:100%;position:relative} +.order-box .log-box .state2 p{float:left;width:185px;height:50px;text-align:left;margin-left:12px;color:#f05858;font-size:15px} +.order-box .log-box .state2 .path{position:absolute;z-index:10} +.order-box .log-box .state2 .path span{float:left;width:185px;height:50px;text-align:left;margin-left:12px;background:#fff} +.order-box .delivery-box{height:100px;border-bottom:1px solid #ddd} +.order-box th{font-weight:normal} +.order-box .goods-head{border-top:2px solid #fc7a64;background:#f3f3f3;display:block;height:25px;line-height:25px;margin:0 0 10px;padding:5px 0} +.order-box .goods-head .goods{float:left;width:650px;padding-left:15px} +.order-box .goods-head .price{float:left;width:100px} +.order-box .goods-head .num{float:left;width:100px} +.order-box .goods-head .t-price{float:left;width:105px} +.order-box .shop{padding-left:15px;height:25px;line-height:25px;border-bottom:2px solid #fdd8d2;color:#e55356;font-weight:bold;font-size:15px;padding-bottom:5px} +.order-box .item{padding-top:5px;padding-bottom:5px;border:1px solid #eee;border-top:0} +.order-box .item .goods{float:left;width:650px;padding-left:15px} +.order-box .item .goods .img{float:left;width:80px;height:80px} +.order-box .item .goods .name{float:left;width:390px;height:80px;margin-left:5px} +.order-box .item .goods .spec{float:left;width:165px;margin-left:5px} +.order-box .item .price{float:left;width:100px} +.order-box .item .num{float:left;width:100px} +.order-box .item .t-price{float:left;width:100px} +.order-box .goods-footer{padding-right:10px;margin-bottom:10px} +.order-box .line{border-top:1px solid #ddd} +.order-box .goods-summary{margin-top:10px} +.order-box .summary{height:30px;line-height:30px} +.order-box .orderScore{margin-right:5px} +.order-box .log td{height:25px;line-height:25px;padding-left:15px} +.score-add{color:red;font-size:16px;font-weight:bold} +.score-reduce{color:green;font-size:16px;font-weight:bold} +.score-head{background:#eee;height:120px;width:100%} +.score-head .user-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px} +.score-head .user-logo img{-moz-border-radius:100px;-webkit-border-radius:100px} +.score-head .user-info{float:left;padding-top:25px;padding-left:20px} +.score-head .user-info .userName{height:25px;line-height:25px} +.score-head .user-info .userScore{height:25px;line-height:25px} +.score-head .user-info .draw-tips{color:red;margin-left:20px} +.money-add{color:red;font-size:16px;font-weight:bold} +.money-reduce{color:green;font-size:16px;font-weight:bold} +.money-head{background:#eee;height:120px;width:100%} +.money-head .user-logo{float:left;margin-top:10px;margin-left:20px;width:100px;height:100px} +.money-head .user-logo img{-moz-border-radius:100px;-webkit-border-radius:100px} +.money-head .user-info{float:left;padding-top:25px;padding-left:20px} +.money-head .user-info .userName{height:25px;line-height:25px} +.money-head .user-info .userScore{height:25px;line-height:25px} + +.score-head .user-info .cashmoney-box{margin-left:20px;} +.score-head .cashbtn{padding: 3px 5px;border: 1px solid #333;} +.score-head .cashbtn:hover{padding: 3px 5px;border: 1px solid #e45050;} +.score-head .usermoney{width:150px ; float:left;} +.score-head .cashbox{width:300px; float:left;} +.score-head .lockbox{width:150px ; float:left;} + +.wst-fav-listg{float:left;width:100%;padding-top:12px} +.wst-fav-listg a,.wst-fav-shop span{color:#6a6868} +.wst-fav-goods{float:left;width:21.88888888%;padding:10px;background:#fff;border:1px solid #dadada;border-radius:3px;margin-left:6px;margin-bottom:20px} +.wst-fav-goods:hover{border:1px solid #fe7f6c} +.wst-fav-goodp1{margin-top:8px} +.wst-fav-goodp1,.wst-fav-goodp2{float:left;width:100%;line-height:20px;font-family:"microsoft yahei"} +.wst-fav-goodpr{color:#ea523b;font-size:16px;font-weight:bold} +.wst-fav-goodpr2{color:#ed1a8d} +.wst-fav-goodpr3{color:#c4c2c2} +.wst-fav-goodpr4{color:#249ee7} +.wst-fav-goimg{float:left;width:216px;height:216px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-fav-goimg img{max-width:216px;max-height:216px;cursor:pointer} +.wst-fav-goimg span{width:216px;height:38px;line-height:38px;font-size:15px;color:#fff;opacity:.8;background:#605d56;display:block;position:absolute;left:0;bottom:0;display:none} +.wst-fav-goimg span:hover{background:#d0260c;cursor:pointer} +.wst-fav-gonam{float:left;width:100%;height:36px;color:#838383;font-size:15px;font-family:"microsoft yahei";margin-top:6px} +.wst-fav-shop{float:left;width:100%;margin-top:6px} +.wst-fav-shop span{margin-right:10px} +.wst-fav-shop img{float:left;margin-top:1px;width:15px;margin-right:3px} +.wst-fav-pa{padding:25px 0 0 350px} +.wst-favo-shop{margin-top:20px;padding:8px;border:1px solid #dddbdb} +.wst-favo-shop:hover{border:1px solid #ec7e67} +.wst-favo-shopl{float:left;width:150px} +.wst-favo-shopr{float:right;width:80%} +.wst-favo-shopimg{float:left;width:150px;height:150px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-favo-shopimg img{max-width:150px;max-height:150px} +.wst-favo-shopl p{float:left;height:25px;width:100%;line-height:25px;text-align:center;font-family:"microsoft yahei"} +.wst-favo-shopa{float:left;padding:0 8px;margin-left:3px;height:22px;line-height:22px;border:1px solid #7a7a7a;color:#7a7a7a;cursor:pointer} +.wst-favo-shopa:hover{color:#ec7e67;border:1px solid #ec7e67;box-shadow:0 0 1px rgba(0,0,0,0.3)} +.wst-favo-more{float:left;width:100%} +.wst-favo-more a{font-size:13px;color:#666} +.wst-favo-more a:hover{color:#eb5f43} +.wst-favo-more span{width:100px;height:20px;color:#ec7e67;line-height:20px;font-weight:bold;text-align:center;border-bottom:2px solid #ec7e67} +.wst-favo-good{padding-top:2px;margin-left:22px} +.wst-favo-goods{float:left;margin:0 5px} +.wst-favo-goodimg{width:135px;height:135px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-favo-goodimg a{width:135px;height:135px;display:table-cell;vertical-align:middle} +.wst-favo-goodimg a img{max-width:135px;max-height:135px} +.wst-favo-goods span{float:left;width:100%;margin-top:1px;text-align:center;color:#fc6047;font-weight:bold;font-size:15px} +.als-container{position:relative;width:100%;margin:0 auto} +.als-viewport{position:relative;overflow:hidden;margin:0 auto} +.als-wrapper{position:relative;list-style:none} +.als-item{position:relative;display:block;text-align:center;cursor:pointer;float:left} +.als-prev,.als-next{position:absolute;cursor:pointer;clear:both} +.als-item img{width:135px;height:135px;vertical-align:middle} +.als-prev,.als-next{top:40px} +.als-prev{left:-22px} +.als-next{right:-22px} +.goods-info img{margin-top:10px;display:block;float:left} +.goodsName{margin-top:10px;height:50px;line-height:50px;overflow:hidden;float:left} +.appraise-complate{width:980px;min-height:265px;margin-top:10px;border:1px solid #ccc} +.appraise-box{width:980px;height:350px;margin:10px 0;border:1px solid #ccc} +.o-goods-info{width:210px;height:258px;padding-left:5px;padding-top:5px;float:left;overflow:hidden} +.o-goods-info img{width:180px;height:180px} +.appraise-area{word-wrap:break-word;word-break:break-all;padding-top:5px;width:740px;height:100%;float:right} +.appraise-item{width:500px} +.appraise-title{margin-top:3px;float:left;width:70px;font-weight:bold} +.appraise-content{float:left;width:430px} +.complate-content{width:600px;max-height:180px;line-height:24px;overflow:hidden} +.webuploader-pick{height:25px;line-height:25px} +.appraise-btn{cursor:pointer;width:60px;height:30px;background:#e23e3d;border:0;color:#fff;border-radius:3px} +.wst-msg-tips-box{background-color:#f0a869;border-radius:12px;color:white;cursor:pointer;display:inline-block;height:24px;left:30px;line-height:24px;position:relative;text-align:center;top:0;width:24px} +.msgContent{padding:10px} +.wst-sec-but{outline:0;background:#e45050;color:#fff;border:1px solid #d33110;border-radius:3px;cursor:pointer} +.u-btn{width:80px;height:30px;font-weight:bold;cursor:pointer} +.u-btn:hover{background:#ea3232 none repeat scroll 0 0;cursor:pointer} +.s-btn{margin:10px} +.tc{text-align:center} +.g_bd{border:1px solid #f2f2f2} +.pd10{padding:10px} +.my_consultbox{margin:5px 0;width:100%;overflow:hidden} +.my_consult{width:70%;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:left} +.consult_time{float:right;margin-right:1%} +.gc_replytit{color:#ff6c00} +.c999{color:#999} +.gc_a{color:#005ea7} +.gc_a:hover{color:#005ea7} +.order_remaker{color:#ff6c00;padding:5px;border:1px solid #ddd;border-top:0} +.order_from{ margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +.wst-inform-head{float:left;width:100%;border-bottom:1px solid #e45050} +.wst-inform-head span{float:left;line-height:28px;padding:0 28px;color:#fff;background:#e45050;font-weight:bold} +.wst-inform-head a{float:right;line-height:28px;padding:0 28px;color:#fff;background:#e45050} +.wst-inform-box{border-bottom: 1px solid #ddd;height: auto;overflow:hidden;padding: 10px;line-height: 30px;} +.wst-inform-content{margin-right:50px;background:#fff;min-height:948px;height:auto;width:65%;float:left;filter:progid:DXImageTransform.Microsoft.Shadow(color = #909090,direction = 120,strength = 4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:0 1px 3px rgba(0,0,0,0.3)} +.wst-remind{width: 28%;float: left;} +.inform-log-box{line-height: 20px;padding: 20px;} +.wst-inform-box .wst-shopName{ border-bottom: 1px solid #ddd;display: inline-block;width: 20%;text-align:right;} +.wst-inform-box .title{width: 20%;text-align:right;display: inline-block;vertical-align: top;} +.wst-inform-box .goods-img{width: 70%;display: inline-block;} +.wst-inform-box .goods-img .wst-img img{width: 40px;height: 40px;} +.wst-inform-box .goods-img .wst-text a{text-decoration:none;} +.wst-remind .content{float: left;} +.wst-remind .alert {color: #C09853;background-color: #FCF8E3; padding: 9px 14px;border: 1px solid #FBEED5;text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} +.wst-inform-box .model{width: 20%;height: 100%;display: inline-block;} +.order-box .log-box .state3{margin-left: 10px;} +.order-box .log-box .state3 p {float: left;width: 170px;margin-left: 20px;height: 30px;text-align: left;color: #f05858;font-size: 15px; +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/error_lost.html b/hyhproject/home2/view/default/error_lost.html new file mode 100755 index 0000000..fbb519f --- /dev/null +++ b/hyhproject/home2/view/default/error_lost.html @@ -0,0 +1,17 @@ +{extend name="default/base" /} +{block name="title"}记录找不到了 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"}{/block} +{block name="main"} +<div class="wst-container"> + <div class="wst-empty empty3"> + <div class="prompt3"> + <p>很抱歉,你来晚了一步,它已经任性的消失了...</p> + <p>你要坚强些,继续发掘别的宝贝吧</p> + </div> + <div class="button3"> + <a href="javascript:history.go(-1)" class="wst-empty-btn wst-empty-btn1">返回上一页</a> + <a href="{$Request.root.true}" class="wst-empty-btn wst-empty-btn1">返回首页</a> + </div> + </div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/error_msg.html b/hyhproject/home2/view/default/error_msg.html new file mode 100755 index 0000000..91c07f1 --- /dev/null +++ b/hyhproject/home2/view/default/error_msg.html @@ -0,0 +1,15 @@ +{extend name="default/base" /} +{block name="title"}系统提示 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"}{/block} +{block name="main"} +<div class="wst-container"> + <div class="wst-empty empty1"> + <div class="prompt"> + <p>{$message}</p> + </div> + <div class="button"> + <a href="{$Request.root.true}" class="wst-empty-btn wst-empty-btn1">返回首页</a> + </div> + </div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/error_switch.html b/hyhproject/home2/view/default/error_switch.html new file mode 100755 index 0000000..84195d8 --- /dev/null +++ b/hyhproject/home2/view/default/error_switch.html @@ -0,0 +1,18 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>提示信息 - {:WSTConf('CONF.mallName')}</title> +<meta name="auther" content="WSTMart,www.wstmart.net" /> +<meta name="copyright" content="Copyright©2016-2066 Powered By WSTMart" /> +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +</head> +<body> +<div class="wst-container"> + <div class="wst-empty empty1"> + <div class="prompt"> + <p>{if(WSTConf('CONF.seoMallSwitchDesc'))}{:WSTConf('CONF.seoMallSwitchDesc')}{else}商城暂时关闭{/if}</p> + </div> + </div> +</div> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home2/view/default/error_sys.html b/hyhproject/home2/view/default/error_sys.html new file mode 100755 index 0000000..71532a0 --- /dev/null +++ b/hyhproject/home2/view/default/error_sys.html @@ -0,0 +1,18 @@ +{extend name="default/base" /} +{block name="title"}系统出错了 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"}{/block} +{block name="main"} +<div class="wst-container"> + <div class="wst-empty empty2"> + <div class="prompt2"> + <span>OMG,系统出错了!</span> + <p>你竟然能来到这里 (╯﹏╰)</p> + <p>看来我们要去面壁思过了...</p> + </div> + <div class="button2"> + <a href="javascript:history.go(-1)" class="wst-empty-btn wst-empty-btn1">返回上一页</a> + <a href="{$Request.root.true}" class="wst-empty-btn wst-empty-btn1">返回首页</a> + </div> + </div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/footer.html b/hyhproject/home2/view/default/footer.html new file mode 100755 index 0000000..965aff7 --- /dev/null +++ b/hyhproject/home2/view/default/footer.html @@ -0,0 +1,134 @@ +<div style="border-top: 1px solid #df2003;padding-bottom:25px;margin-top:35px;min-width:1200px;"></div> +<div class="wst-footer-flink"> + <div class="wst-footer" > + + <div class="wst-footer-cld-box"> + <div class="wst-footer-fl" style="text-align: left;padding-left:10px;">友情链接</div> + + <div style="padding-left:40px;"> + {wst:friendlink cache='86400'} + <div style="float:left;"><a class="flink-hover" href="{$vo['friendlinkUrl']}" target="_blank">{$vo["friendlinkName"]}</a>&nbsp;&nbsp;</div> + {/wst:friendlink} + <div class="wst-clear"></div> + </div> + </div> + + </div> +</div> +<ul class="wst-footer-info"> + <li><div class="wst-footer-info-img wst-fimg1"></div> + <div class="wst-footer-info-text"> + <h1>支付宝支付</h1> + <p>支付宝签约商家</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg2"></div> + <div class="wst-footer-info-text"> + <h1>正品保证</h1> + <p>100%原产地</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg3"></div> + <div class="wst-footer-info-text"> + <h1>退货无忧</h1> + <p>七天退货保障</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg4"></div> + <div class="wst-footer-info-text"> + <h1>免费配送</h1> + <p>满额包邮</p> + </div> + </li> + <li><div class="wst-footer-info-img wst-fimg5"></div> + <div class="wst-footer-info-text"> + <h1>货到付款</h1> + <p>400城市送货上门</p> + </div> + </li> +</ul> +<div class="wst-footer-help"> + <div class="wst-footer"> + <div class="wst-footer-hp-ck1"> + {volist name=":WSTHelps(5,6)" id="vo1"} + <div class="wst-footer-wz-ca"> + <div class="wst-footer-wz-pt"> + <span class="wst-footer-wz-pn">{$vo1["catName"]}</span> + <ul style='margin-left:25px;'> + {volist name="vo1['articlecats']" id="vo2"} + <li style='list-style:disc;color:#999;font-size:12px;'> + <a href="{:Url('Home/Helpcenter/view',array('id'=>$vo2['articleId']))}">{:WSTMSubstr($vo2['articleTitle'],0,8)}</a> + </li> + {/volist} + </ul> + </div> + </div> + {/volist} + + <div class="wst-contact"> + <ul> + <li style="height:30px;"> + <div class="icon-phone"></div><p class="call-wst">服务热线:</p> + </li> + <li style="height:38px;"> + {if(WSTConf('CONF.serviceTel')!='')}<p class="email-wst">{:WSTConf('CONF.serviceTel')}</p>{/if} + </li> + <li style="height:150px;"> + <div class="qr-code" style="position:relative;"> + <img src="__IMGURL__/upload/sysconfigs/app.jpg" style="height:90px;"> + + </span> + {if(WSTConf('CONF.wxenabled')==1) && WSTConf('CONF.wxAppLogo')} + <img src="__IMGURL__/{:WSTConf('CONF.wxAppLogo')}" style="height:110px;"> + {/if} + <div class="focus-wst"> + {if(WSTConf('CONF.serviceQQ')!='')} + <p class="focus-wst-qr">在线客服:</p> + <p class="focus-wst-qra"> + <a href="tencent://message/?uin={:WSTConf('CONF.serviceQQ')}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{:WSTConf('CONF.serviceQQ')}:7" alt="QQ交谈" width="71" height="24" /> + </a> + </p> + {/if} + {if(WSTConf('CONF.serviceEmail')!='')} + <p class="focus-wst-qr">商城邮箱:</p> + <p class="focus-wst-qre">{:WSTConf('CONF.serviceEmail')}</p> + {/if} + </div> + + </div> + <a style="float: left;margin-left: -70px;margin-top:5px; color: #999;">下载APP</a> + </li> + + </ul> + </div> + + + <div class="wst-clear"></div> + </div> + + <div class="wst-footer-hp-ck3"> + <div class="links"> + {php}$navs = WSTNavigations(1);{/php} + {volist name="$navs" id='vo'} + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + {if $i< count($navs)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + <div class="copyright"> + {php} + if(WSTConf('CONF.mallFooter')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.mallFooter')); + } + {/php} + {php} + if(WSTConf('CONF.visitStatistics')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.visitStatistics'))."<br/>"; + } + {/php} + + </div> + </div> + </div> +</div> +{:hook('initCronHook')} \ No newline at end of file diff --git a/hyhproject/home2/view/default/forget_pass.html b/hyhproject/home2/view/default/forget_pass.html new file mode 100755 index 0000000..f911ba0 --- /dev/null +++ b/hyhproject/home2/view/default/forget_pass.html @@ -0,0 +1,66 @@ +{extend name="default/base" /} +{block name="title"}忘记密码 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {php}$liteTitle = "找回密码"{/php} + {include file="default/header_lite" /} +{/block} +{block name="main"} + <div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">填写账户名</dd> + <dd></dd> + </dl> + <dl class="normal"> + <dt class="s-num1">2</dt> + <dd class="s-text">验证身份</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">3</dt> + <dd class="s-text">重置密码</dd> + </dl> + <dl class="last"> + <dt class="s-num1">4</dt> + <dd class="s-text">完成</dd> + </dl> + </div> + <div class="wst-clear"></div> + <div class="forget-pwd"> + <form id="forgetPwdForm" autocomplete="off"> + <input type="hidden" id="step" name="step" class="ipt" value="1" autocomplete="off"> + <table class="wst-table"> + <tbody> + <tr class="wst-login-tr"> + <td class="wst-regist-td">用户名</td> + <td><input id="loginName" name="loginName" class="ipt wst-forget-input" type="text" data-rule="用户名 required;remote(post:{:url('home/users/checkFindKey')})" data-msg-required="请输入用户名" data-tip="请输入用户名" tabindex="1" value="" autocomplete="off" placeholder="邮箱/用户名/手机号"/></td> + </tr> + <tr class="wst-login-tr"> + <td class="wst-regist-td">验证码</td> + <td> + <div class="wst-forget-code"> + <input id="verifyCode" style="ime-mode:disabled" name="verifyCode" class="ipt wst-forget-codein" data-rule="验证码 required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" tabindex="6" autocomplete="off" maxlength="6" type="text" data-target="#verifyCodeTips" placeholder="验证码"/> + <img id='verifyImg' class='wst-forget-codeim' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'><span id="verifyCodeTips"></span> + </div> + <label style="float:left;margin:10px 0px 0px 5px;">看不清?<a style="color:#69b7b5;" href="javascript:WST.getVerify('#verifyImg')">换一张</a></label><span id="verify" class="wst-lfloat"></span> + </td> + </tr> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:173px;"> + <input type="submit" class="wst-regist-but" value="下一步" style="width: 88px;height:32px;"/> + </td> + </tr> + </tbody> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/js/findpass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/forget_pass2.html b/hyhproject/home2/view/default/forget_pass2.html new file mode 100755 index 0000000..d3b989a --- /dev/null +++ b/hyhproject/home2/view/default/forget_pass2.html @@ -0,0 +1,136 @@ +{extend name="default/base" /} +{block name="title"}忘记密码 - {:WSTConf('CONF.mallName')}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {php}$liteTitle = "找回密码"{/php} + {include file="default/header_lite" /} +{/block} +{block name="main"} + <div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">填写账户名</dd> + <dd></dd> + </dl> + <dl class="first doing"> + <dt class="s-num">2</dt> + <dd class="s-text">验证身份</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">3</dt> + <dd class="s-text">重置密码</dd> + </dl> + <dl class="last"> + <dt class="s-num1">4</dt> + <dd class="s-text">完成</dd> + </dl> + </div> + <div class="wst-clear"></div> + <div class="forget-pwd"> + <form id="forgetPwdForm2" autocomplete="off"> + <input type="hidden" id="step" name="step" class="ipt" value="2" autocomplete="off"> + <input type="hidden" id="modes" name="modes" class="ipt" value="1" autocomplete="off"> + <table class="wst-table"> + <tbody> + <tr class="wst-login-tr"> + <td class="wst-forget-td">请选择验证身份方式</td> + <td><select class="wst-forget-select" name="type" id="type"> + <option value="phone">手机</option> + <option value="email">邮箱</option> + </select></td> + </tr> + <tr class="wst-login-tr"> + <td class="wst-forget-td">用户名</td> + <td colspan='2'><span class="wst-forget-te">{$forgetInfo['loginName']}</span></td> + </tr> + <tr class="phone-verify wst-login-tr"> + <td class="wst-forget-td">手机</td> + <td colspan='2'><span class="wst-forget-te">{php} echo $forgetInfo['userPhone'] == '' ? "没有预留手机号码,请尝试用邮箱找回!" : $forgetInfo['userPhone'] ; {/php}</span></td> + </tr> + {if($forgetInfo['userPhone'] != '')} + <tr class="phone-verify wst-login-tr"> + <td class="wst-forget-td">手机校验码</td> + <td> + <input type="text" class="ipt wst-forget-input" style='width:230px;' name="Checkcode" id="Checkcode" data-rule="校验码required;" data-msg-required="请输入校验码" data-tip="请输入校验码" data-target="#verifyPhone" placeholder="校验码"> + </td> + <td><button id="timeObtain" class="wst-forget-obtain" type="button" onclick="javascript:phoneVerify();">点击获取校验码</button><span id="verifyPhone"></span></td> + </tr> + <tr class="phone-verify wst-login-tr"> + <td colspan="2" style="padding-left:282px;"> + <input type="button" class="wst-regist-but" value="下一步" style="width: 80px;height:32px;" onclick="javascript:forgetPhone()"/> + </td> + </tr> + {/if} + <tr class="email-verify wst-login-tr"> + <td class="wst-forget-td">邮箱地址</td> + <td colspan='2'><span class="wst-forget-te">{php} echo $forgetInfo['userEmail'] == '' ? "没有预留邮箱,请尝试用手机号码找回!" : $forgetInfo['userEmail'] ; {/php}</span></td> + </tr> + {if($forgetInfo['userEmail'] != '')} + <tr class="email-verify wst-login-tr"> + <td class="wst-regist-td">验证码</td> + <td> + <div class="wst-forget-code2"> + <input id="verifyCode" style="ime-mode:disabled;" name="verifyCode" class="ipt wst-forget-codein2" data-rule="验证码 required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" tabindex="6" autocomplete="off" maxlength="6" type="text" data-target="#verifyCodeTips" placeholder="验证码"/> + <img id='verifyImg' class='wst-forget-codeim2' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'><span id="verifyCodeTips"></span> + </div> + <label style="float:left;margin:10px 0px 0px 5px;">看不清?<a style="color:#69b7b5;" href="javascript:WST.getVerify('#verifyImg')">换一张</a></label><span id="verify" class="wst-lfloat"></span> + </td> + </tr> + + <tr class="email-verify wst-login-tr"> + <td class="wst-forget-td">邮箱校验码</td> + <td > + <input type="text" class="ipt wst-forget-input" style='width:230px;' name="secretCode" id="secretCode" data-rule="校验码required;" data-msg-required="请输入校验码" data-tip="请输入校验码" placeholder="校验码" data-target="#notice"> + <button id="sendEmailBtn" class="wst-forget-obtain" type="button" onclick="javascript:forgetEmail();">点击获取校验码</button> + </td> + <td id="notice"> + + </td> + </tr> + + + + <tr class="email-verify wst-login-tr"> + <td colspan="2" style="padding-left:282px;"> + <input type="button" class="wst-regist-but" value="下一步" style="width: 120px;height:32px;" onclick="javascript:resetPass()"/> + </td> + </tr> + {/if} + </tbody></table> + </form> + + <!-- <div id="email-prompt" style="margin-top:50px;font-size:20px;text-align: center;display: none;">邮箱成功发送,请登录邮箱查收<span style="color: #E23C3D;font-size:20px;">(30分钟有效)</span></div> --> + + + + </div> + </div> + <form method="post" id="phoneVerify" autocomplete="off" style="display:none;"> + <input type='hidden' id='VerifyId' value='' autocomplete="off"/> + <table class='wst-form' style="width:500px;padding-top:10px;"> + <tr> + <th align='right'>验证码 <font color='red'>*</font>:</th> + <td> + <input id="smsVerfy" style="ime-mode:disabled;float: left;height: 30px;" name="smsVerfy" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" class="ipt" class="text text-1" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label style="float: left;"> + <img id='verifyImg2' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg2")' style="width:115px;"> + </label> + <label class="ftx23"><a href="javascript:WST.getVerify('#verifyImg2')" class="flk13">&nbsp;看不清?换一张</a></label><div id="verify"></div> + </td> + </tr> + <tr> + <td colspan='2' style='padding:10px 0px 0px 190px;'> + <button type="submit" style="width: 120px;height:30px;">确认</button> + </td> + </tr> + </table> + </form> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/js/findpass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/forget_pass3.html b/hyhproject/home2/view/default/forget_pass3.html new file mode 100755 index 0000000..eaeec8e --- /dev/null +++ b/hyhproject/home2/view/default/forget_pass3.html @@ -0,0 +1,61 @@ +{extend name="default/base" /} +{block name="title"}忘记密码 - {:WSTConf('CONF.mallName')}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {php}$liteTitle = "找回密码"{/php} + {include file="default/header_lite" /} +{/block} +{block name="main"} + <div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">填写账户名</dd> + <dd></dd> + </dl> + <dl class="first doing"> + <dt class="s-num">2</dt> + <dd class="s-text">验证身份</dd> + </dl> + <dl class="first doing"> + <dt class="s-num">3</dt> + <dd class="s-text">重置密码</dd> + </dl> + <dl class="last"> + <dt class="s-num1">4</dt> + <dd class="s-text">完成</dd> + </dl> + </div> + <div class="wst-clear"></div> + <div class="forget-pwd"> + <form id="forgetPwdForm3" autocomplete="off"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type="hidden" id="step" name="step" class="ipt" value="3" autocomplete="off"> + <table class="phone-verify"> + <tbody> + <tr class="wst-login-tr"> + <td class="wst-regist-td" style='width:220px;'>新密码:</td> + <td><input type="password" class="ipt wst-forget-input" name="loginPwd" id="loginPwd" placeholder="6-16位字符"></td> + </tr> + <tr class="wst-login-tr"> + <td class="wst-regist-td" style='width:220px;'>确认密码:</td> + <td><input type="password" class="ipt wst-forget-input" name="repassword" id="repassword" placeholder="6-16位字符"></td> + </tr> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:242px;"> + <input type="submit" class="wst-regist-but" value="提交" style="width: 100px;height:32px;"> + </td> + </tr> + </tbody></table> + </form> + </div> + </div> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type='text/javascript' src='__STYLE__/js/findpass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/forget_pass4.html b/hyhproject/home2/view/default/forget_pass4.html new file mode 100755 index 0000000..f93cb68 --- /dev/null +++ b/hyhproject/home2/view/default/forget_pass4.html @@ -0,0 +1,40 @@ +{extend name="default/base" /} +{block name="title"}忘记密码 - {:WSTConf('CONF.mallName')}{/block} +{block name="css"} +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {php}$liteTitle = "找回密码"{/php} + {include file="default/header_lite" /} +{/block} +{block name="main"} + <div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">填写账户名</dd> + <dd></dd> + </dl> + <dl class="first doing"> + <dt class="s-num">2</dt> + <dd class="s-text">验证身份</dd> + </dl> + <dl class="first doing"> + <dt class="s-num">3</dt> + <dd class="s-text">重置密码</dd> + </dl> + <dl class="first doing"> + <dt class="s-num">4</dt> + <dd class="s-text">完成</dd> + </dl> + </div> + <div class="wst-clear"></div> + <div class="forget-pwd"> + <div class="wst-forget-c" style="margin-top:30px;"><img src="__STYLE__/img/icon_success.png"/></div> + <div class="wst-forget-c wst-forget-ct" style="margin:12px 0px;">密码修改成功!</div> + <div class="wst-forget-c" style="margin-bottom:16px;"> + <a href="{:url('home/users/login')}"><input type="submit" class="wst-regist-but" value="立即登录" style="width:180px;height:36px;font-size: 15px;"/></a> + </div> + </div> + </div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/goods_contrast.html b/hyhproject/home2/view/default/goods_contrast.html new file mode 100755 index 0000000..ac7eceb --- /dev/null +++ b/hyhproject/home2/view/default/goods_contrast.html @@ -0,0 +1,130 @@ +{extend name="default/base" /} +{block name="title"}商品对比 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')}"> +<meta name="Keywords" content="{:WSTConf('CONF.seoMallKeywords')}"> +{/block} +{block name="css"} +<link href="__STYLE__/css/goodslist.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {include file="default/header" /} +{/block} +{block name="main"} +<div class='wst-filters'> + <div class='item' style="border-left:2px solid #df2003;padding-left: 8px;"> + <a class='link' href='__ROOT__'>首页</a> + <i class="arrow">></i> + <span class='link'>商品对比</span> + </div> + <div class='wst-clear'></div> +</div> +{/* 商品展示 */} +<div class="wst-container"> + <div class="wst-contrast"> + <div class="goods" id="goodsTabs"> + <table class="table"> + <tbody><tr> + <th> + {if($data['list'])} + <div class="choice"> + <input type="checkbox" onclick="screenContrast(this,0)"> + <label>高亮不同项</label> + </div> + <div class="choice"> + <input type="checkbox" onclick="screenContrast(this,1)"> + <label>隐藏相同项</label> + </div> + {else} + <div class="choice">请选择商品对比</div> + {/if} + </th> + {volist name="$data['list']" id="go"} + <td> + <div class="goods-item"> + <div class="img"><a href="{:Url('home/goods/detail','id='.$go['goodsId'])}" target="_blank"> + <img class="goodsImg" data-original="__IMGURL__/{:WSTImg($go['goodsImg'])}" title="{$go['goodsName']}"> + </a></div> + <p class="name"><a href="{:Url('home/goods/detail','id='.$go['goodsId'])}" target="_blank">{$go['goodsName']}</a></p> + <p class="price" id="goods-price-{$go['goodsId']}">¥ <span>{$go['shopPrice']}</span></p> + <div class="operation"> + <a href="{:Url('home/goods/detail','id='.$go['goodsId'])}" target="_blank" class="see">查看</a> + {if(count($data['list'])!=1)}<a href="javascript:void(0);" onclick="javascript:contrastDel({$go['goodsId']})" class="del">删除</a>{/if} + </div> + <div class='wst-clear'></div> + </div> + </td> + {/volist} + </tr></tbody> + </table> + </div> + <div class="goods goods-fixed2" id="goodsTabs2"> + <table class="table"> + <tbody><tr> + <th> + <div class="choice">空白</div> + </th> + </tr></tbody> + </table> + </div> + <table class="table2"> + <tbody> + {volist name="$data['lists']" id="lis"} + <tr class="identical_{$lis['identical']}"> + <th> + <div class="left-title">{$lis['name']}</div> + </th> + {volist name="$data['list']" id="go"} + {php}$in = isset($lis['info'][$go['goodsId']])?$lis['info'][$go['goodsId']]:'--'{/php} + <td> + {if($lis['type']=='shop' || $lis['type']=='brand')}<div class="right-title">{$in}</div>{/if} + {if($lis['type']=='score')} + <div class="right-title"> + {for start="0" end="$in"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$in"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + {/if} + {if($lis['type']=='spec')} + {if(isset($in['list']))} + <ul class="list-box"> + {volist name="$in['list']" id="sp"} + {if($sp['isDefault']==1)}<input type="hidden" id="defaultSpec_{$go['goodsId']}_{$sp['catId']}" class="defaultSpec_{$go['goodsId']}" value="{$sp['itemId']}"/>{/if} + {if($sp['isAllowImg']==1)} + <li class="img {if($sp['isDefault']==1)}active{/if}" onclick="javascript:choiceContrast(this,{$sp['itemId']},{$sp['catId']},{$go['goodsId']});"> + <img class="goodsImg" data-original="__IMGURL__/{:WSTImg($sp['itemImg'])}" title="{$sp['itemName']}"> + </li> + {else} + <li class="{if($sp['isDefault']==1)}active{/if}" onclick="javascript:choiceContrast(this,{$sp['itemId']},{$sp['catId']},{$go['goodsId']});">{$sp['itemName']}</li> + {/if} + {/volist} + </ul> + {else} + <div class="right-title">{$in}</div> + {/if} + {/if} + </td> + {/volist} + </tr> + {/volist} + </tbody> + </table> + </div> +</div> +{/block} +{block name="js"} +<script> +var saleSpec = { + {if isset($data['saleSpec'])} + sku:{:json_encode($data['saleSpec'])} + {/if} + } +$(function(){ + fixedGoods(); +}) +</script> +<script type='text/javascript' src='__STYLE__/js/goodslist.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/goods_detail.html b/hyhproject/home2/view/default/goods_detail.html new file mode 100755 index 0000000..d8d3e0c --- /dev/null +++ b/hyhproject/home2/view/default/goods_detail.html @@ -0,0 +1,581 @@ +{extend name="default/base" /} +{block name="title"}{$goods['goodsName']} - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{$goods['goodsName']}"> +<meta name="Keywords" content="{$goods['goodsSeoKeywords']}"> +{/block} +{block name="css"} +<link href="__STYLE__/css/goods.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {include file="default/header" /} +{/block} +{block name="main"} +<div class='wst-w' style='margin-bottom:0px'> +<div class='wst-filters'> + <div class='item' style="border:1px solid transparent;border-left:2px solid #df2003;padding-left: 8px"> + <a class='link' href='__ROOT__'>首页</a> + <i class="arrow"></i> + </div> + {volist name=":WSTPathGoodsCat($goods['goodsCatId'])" id='vo'} + <div class='wst-lfloat'> + <div class='item dorpdown'> + <div class='drop-down'> + <a class='link' href='{:Url("home/goods/lists",["cat"=>$vo["catId"]])}'>{$vo['catName']}</a> + </div> + <div class="dorp-down-layer"> + {volist name=":WSTGoodsCats($vo['parentId'])" id='vo2'} + <div class="{$vo['parentId']>0?'cat2':'cat1'}"><a href='{:Url("home/goods/lists","cat=".$vo2["catId"])}'>{$vo2['catName']}</a></div> + {/volist} + </div> + </div> + <i class="arrow"></i> + </div> + {/volist} + <div class='wst-clear'></div> +</div> +</div> +<div class='wst-w'> + <div class='wst-container' style='border:1px solid #eee;'> + <div class='goods-img-box'> + <div class="goods-img spec-preview" id="preview"> + <!--兼容老的数据不适用压缩主图 make cheng 20180308 <img title="{$goods['goodsName']}" alt="{$goods['goodsName']}" src="__ROOT__/{:WSTImg($goods['goodsImg'])}" class="cloudzoom" data-cloudzoom="zoomImage:'__ROOT__/{$goods['goodsImg']}'" height="350" width="350">--> + <img title="{$goods['goodsName']}" alt="{$goods['goodsName']}" src="__IMGURL__/{$goods['goodsImg']}" class="cloudzoom" data-cloudzoom="zoomImage:'__IMGURL__/{$goods['goodsImg']}'" height="350" width="350"> + </div> + <div class="goods-pics"> + <a class="prev">&lt;</a> + <a class="next">&gt;</a> + <div class="items"> + <ul> + {volist name="$goods['gallery']" id='vo'} + <li><img title="{$goods['goodsName']}" alt="{$goods['goodsName']}" class='cloudzoom-gallery' src="__IMGURL__/{$vo}" data-cloudzoom="useZoom: '.cloudzoom', image:'__IMGURL__/{$vo}', zoomImage:'__IMGURL__/{$vo}' " width="60" height="60"></li> + {/volist} + </ul> + </div> + <div class="wst-clear"></div> + </div> + <div class="goods-term-box"> + <div class="wst-favorite"> + {if ($goods['favGood']>0)} + <a href='javascript:void(0);' onclick='WST.cancelFavorite(this,0,{$goods["goodsId"]},{$goods['favGood']})' class='favorite j-fav'>已关注</a> + {else} + <a href='javascript:void(0);' onclick='WST.addFavorite(this,0,{$goods["goodsId"]},{$goods["goodsId"]})' class='favorite j-fav2 j-fav3'>关注商品</a> + {/if} + </div> + <div class="wst-contrast" onclick="javascript:contrastGoods(1,{$goods['goodsId']},1)"><i></i>对比</div> + <a href='javascript:informs({$goods["goodsId"]})' class="j-inform">举报</a> + <div class="wst-clear"></div> + </div> + </div> + <div class='intro'> + <div class='intro-name'> + <h2>{$goods['goodsName']}</h2> + <span class='tips'>{$goods['goodsTips']}</span> + </div> + <div class='summary'> + <div class="infol"> + <div class='item'> + <div class='dt'>市场价&nbsp;</div> + <div class='dd market-price' id='j-market-price'>¥{$goods['marketPrice']}</div> + </div> + <div class='item'> + <div class='dt'>价格&nbsp;</div> + <div class='dd price' >{if $goods['is_seckilling']==1}秒杀价{/if}<span id='j-shop-price'>¥{$goods['shopPrice']}</span> + {if $goods['is_seckilling']==1}<span style="color: #000;font-size: 12px;">(秒杀商品限购4件)</span>{/if}</div> + </div> + {if $goods['is_seckilling']!=1} + <div class='item'> + <div class='dt'>到手惠宝价&nbsp;</div> + <div class='dd price lxy' id='j-shop-huibao'>¥{$goods['shopPrice']*0.8|round=###,2}</div> + </div>{/if} + <div class='goods-intro-bg'> + <div class='item'> + <ul class="ginfo_b"> + <li> + <div class='dt'>销量&nbsp;</div> + <span class='appraise-num'>{$goods['saleNum']}</span> + </li> + <li> + <div class='dt'>累计评价&nbsp;</div> + <span class='appraise-num'>{$goods['appraiseNum']}</span> + </li> + <li> + <div class='dt'>商品评分&nbsp;</div> + <div class='dd'> + {for start="0" end="$goods['scores']['totalScores']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$goods['scores']['totalScores']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </li> + <div class="wst-clear"></div> + </ul> + </div> + </div> + </div> + <div class='wst-clear'></div> + </div> + + <div class="sale_box"> + {/* 促销满就送 */} + <div class='item' id='j-promotion' style='display:none'> + <div class='dt'>促销&nbsp;</div> + <div class='dd'> + {:hook('homeDocumentGoodsPromotionDetail',['goods'=>$goods])} + </div> + </div> + {:hook('homeDocumentGoodsPropDetail',['goods'=>$goods,'getParams'=>input()])} + </div> + + <div class='spec'> + {if !empty($goods['spec'])} + {volist name="$goods['spec']" id='vo'} + <div class='item'> + <div class='dt'>{$vo['name']}&nbsp;</div> + <div class='dd'> + {volist name="$vo['list']" id='vo2'} + {if $vo2['itemImg']!=''} + <div class='j-option img' data-val="{$vo2['itemId']}" style='width:28px;height:28px;padding:0px;'><img class="cloudzoom-gallery" width="28" height="28" src="__IMGURL__/{$vo2['itemImg']}" data-cloudzoom="useZoom: '.cloudzoom', image:'__IMGURL__/{$vo2['itemImg']}', zoomImage:'__IMGURL__/{$vo2['itemImg']}' " title="{$vo2['itemName']}" alt="{$vo2['itemName']}"/><i></i></div> + {else} + <div class='j-option' data-val="{$vo2['itemId']}">{$vo2['itemName']}<i></i></div> + {/if} + {/volist} + </div> + <div class='wst-clear'></div> + </div> + {/volist} + {/if} + </div> + <div class='buy'> + <div class='item'> + <div class='dt'>数量&nbsp;</div> + <div class='dd'> + <a href='#none' class='buy-btn' id='buy-reduce' style='color:#ccc;' onclick='javascript:WST.changeIptNum(-1,"#buyNum","#buy-reduce,#buy-add")'>-</a> + <input type='text' id='buyNum' class='buy-num' value='1' data-min='1' autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum","#buy-reduce,#buy-add")' onkeypress="return WST.isNumberKey(event);" maxlength="6"/> + <a href='#none' class='buy-btn' id='buy-add' onclick='javascript:WST.changeIptNum(1,"#buyNum","#buy-reduce,#buy-add")'>+</a> + &nbsp; &nbsp;(库存:<span id='goods-stock'>0</span>&nbsp;{$goods['goodsUnit']}) + </div> + </div> + {if empty($is_icp)} + <div class='item'> + <div class='dt'>服务&nbsp;</div> + <div class='dd'>服务由 <a class="c14_005" href='{:Url("home/shops/home","shopId=".$shop["shopId"])}' target='_blank'>{$shop['shopName']}</a> 发货并提供 售后服务。</div> + </div> + {/if} + <div class='item' style='padding-left:75px;margin-top:20px;'> + {if $goods['read']} + {if $goods['goodsType']==0} + <a id='addBtn' href='javascript:void(0);' class='addBtn un-buy' >加入购物车</a> + {/if} + <a id='buyBtn' href='javascript:void(0);' class='buyBtn un-buy'>立即购买</a> + {else} + {if $goods['goodsType']==0} + <a id='addBtn' href='javascript:addCart(0,"#buyNum")' class='addBtn' >加入购物车</a> + {/if} + <a id='buyBtn' href='javascript:addCart(1,"#buyNum")' class='buyBtn'>立即购买</a> + {/if} + <div class='wst-clear'></div> + </div> + <div class="wst-relative"> + {:hook('homeDocumentGoodsDetail',['goods'=>$goods,'getParams'=>input()])} + + <div style="clear: both;"></div> + <div style="margin-top:10px;float: right;"> + <!-- JiaThis Button BEGIN --> + <div class="jiathis_style_24x24"> + <a class="jiathis_button_qzone"></a> + <a class="jiathis_button_tsina"></a> + <a class="jiathis_button_tqq"></a> + <a class="jiathis_button_weixin"></a> + <a class="jiathis_button_cqq"></a> + <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> + </div> + <div style="clear: both;"></div> + </div> + </div> + <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js" charset="utf-8"></script> + + </div> + </div> + + <div class='seeing'> + <div class='head'>看了又看</div> + <div class='body'> + {wst:goods type="visit" cat="$goods['goodsCatId']" num="5" id="visit" num="6"} + <a href="{:Url('home/goods/detail','id='.$visit['goodsId'])}"> + <div class="see-item"> + <div class="see-img"> + <img title="{$visit['goodsName']}" class="goodsImg" alt="{$visit['goodsName']}" data-original="__IMGURL__/{$visit['goodsImg']}"> + <span class="see-price">¥{$visit['shopPrice']}</span> + </div> + </div> + </a> + {/wst:goods} + + + + + </div> + </div> + <div class='wst-clear'></div> + </div> +</div> +<div class='wst-w'> + <div class='wst-container'> + <div class='wst-side'> + {if empty($is_icp)} + <div class='shop-intro'> + <div class="shop_imgbox"> + <img class="shopsImg" data-original="__IMGURL__/{$shop['shopImg']}" title="{$shop['shopName']}" style="vertical-align: middle;width:75px;height:75px;"> + </div> + <div class='title shop-name'>{$shop['shopName']}</div> + <!--mark by cheng 20180313去掉店主显示<div class='title'>店主:{$shop['shopKeeper']}</div>--> + <div class='title'>联系: + <a href="tencent://message/?uin={$shop['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img + style="vertical-align: bottom;" + border="0" + src="http://wpa.qq.com/pa?p=1:{$shop['shopQQ']}:7" alt="QQ交谈" width="60" height="20" /> + </a></div> + <!--mark by cheng 20180313添加旺旺显示--> + <div class='title'>联系:{if($shop['shopWangWangType']==0)} + <a href="http://www.taobao.com/webww/ww.php?ver=3&touid={$shop['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8" target="_blank"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$shop['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" class='wangwang'/></a>{/if} + {if($shop['shopWangWangType']==1)} + <a href="http://amos.alicdn.com/msg.aw?v=2&uid={$shop['shopWangWang']}&site=cnalichn&s=10&charset=utf-8" target="_blank" ><img border="0" src="http://amos.alicdn.com/online.aw?v=2&uid={$shop['shopWangWang']}&site=cnalichn&s=10&charset=UTF-8" alt="点击这里给我发消息" /></a>{/if} + </div> + <div class='title'>地址:{$shop['shopAddress']}</div> + <div class='body'> + <div class='itemScore'> + 描述 + <br /> + <span class="c12_e40"> + {if ($shop['goodsScore']!=0)}{$shop['goodsScore']}{else /}5{/if}</div> + </span> + <div class='itemScore'> + 服务 + <br /> + <span class="c12_e40"> + {if ($shop['serviceScore']!=0)}{$shop['goodsScore']}{else /}5{/if}</div> + </span> + <div class='itemScore'> + 物流 + <br /> + <span class="c12_e40"> + {if ($shop['timeScore']!=0)}{$shop['goodsScore']}{else /}5{/if}</div> + </span> + <div class="wst-clear"></div> + </div> + <div class='footer'> + <a class="home" href='{:Url("home/shops/home","shopId=".$shop["shopId"])}' target='_blank'>进店逛逛</a> + {if ($goods['favShop']>0)} + <a class="j-fav" href='javascript:void(0);' onclick='WST.cancelFavorite(this,1,{$shop["shopId"]},{$goods['favShop']})'>已关注</a> + {else} + <a class="j-fav2" href='javascript:void(0);' onclick='WST.addFavorite(this,1,{$shop["shopId"]},{$goods['favShop']})'>关注店铺</a> + {/if} + <div class='wst-clear'></div> + </div> + </div> + {/if} + <div class="goods-side"> + <div class="guess-like"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' cat="$goods['goodsCatId']" num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" data-original="__IMGURL__/{$vo['goodsImg']}" class="goodsImg" /></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + <div class="hot-goods"> + <div class="title">热销商品</div> + {wst:goods type='hot' num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" data-original="__IMGURL__/{$vo['goodsImg']}" class="goodsImg" /></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + </div> + </div> + <div class='goods-desc'> + <div id='tab' class="wst-tab-box"> + <ul id='goodsTabs' class="wst-tab-nav"> + <li>商品介绍</li> + <li>商品评价<span class='appraise-num'>({$goods['appraiseNum']})</span></li> + <li>商品咨询</li> + <li id="wx_qrcode"> + 手机购买 + <img src="__STYLE__/img/detail_qr_icon.png" style="vertical-align:sub" alt=""> + <div class="wx_qrcode_box"> + <div class="qrcode"></div> + <p style="margin-top:-25px;">手机扫购有惊喜</p> + </div> + </li> + {if !$goods['read']} + <a id='addCart2' href='javascript:addCart(1,"#buyNum")'>立即购买</a> + {/if} + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;min-height:1312px;'> + <div class="wst-tab-item goods-desc-box" style="position: relative;"> + <ul class='wst-attrs-list'> + {if(isset($goods['brandName']) && $goods['brandName']!='')} + <div class="brand_name">品牌:<span>{$goods['brandName']}</span></div> + {/if} + {volist name="$goods['attrs']" id="vo"} + <li title='{$vo['attrVal']}'>{$vo['attrName']}:{$vo['attrVal']}</li> + {/volist} + <div class="wst-clear"></div> + </ul> + {$goods['goodsDesc']|htmlspecialchars_decode} + </div> + <input type="hidden" id="filtertype" value="all" /> + <script id="tblist" type="text/html"> + <div class="appr-filter"> + <ul class="appr-filterbox"> + <li><a href="javascript:void(0)" onclick="apprfilter('all')" id='all'>全部评价(<span id="totalNum">0</span>)</a></li> + <li><a href="javascript:void(0)" onclick="apprfilter('pic')" id='pic'>晒图(<span id="picNum">0</span>)</a></li> + <li><a href="javascript:void(0)" onclick="apprfilter('best')" id='best'>好评(<span id="bestNum">0</span>)</a></li> + <li><a href="javascript:void(0)" onclick="apprfilter('good')" id='good'>中评(<span id="goodNum">0</span>)</a></li> + <li><a href="javascript:void(0)" onclick="apprfilter('bad')" id='bad'>差评(<span id="badNum">0</span>)</a></li> + </ul> + </div> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="appraises-box"> + <div class="wst-appraises-right"> + <div class="userinfo"> + <img data-original="__IMGURL__/{{d[i].userPhoto}}" class="apprimg" /> + <div class="appraiser"> + {{d[i]['loginName']}} + </div> + </div> + <p>{{d[i].rankName}}</p> + </div> + <div class="wst-appraises-left"> + <div class="appr-starbox"> + {{# for(var j=0;j<d[i].avgScore;++j){ }} + <div class="appr-star"></div> + {{# } }} + {{#for(var g=0;g<5-d[i].avgScore;++g){ }} + <div class="appr-star-off"></div> + {{# } }} + </div> + <div class='wst-clear'></div> + <p class="app-content"> + {{d[i]['content']}} + <div class="goods-spec-box"> + {{d[i]['goodsSpecNames']}} + </div> + </p> + {{# if(WST.blank(d[i]['images'])!=''){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + + <img src="__IMGURL__/{{img[g]}}" layer-src="__IMGURL__/{{img[g]}}" style="width:80px;height:80px;" /> + {{# } }} + </div> + {{# } }} + <span class="apprtime">{{d[i]['createTime']}}</span> + {{# if(d[i]['shopReply']!='' && d[i]['shopReply']!=null){ }} + <div class="reply-box"> + <p class="reply-content"><a href="javascript:void(0)" onclick="goShop({{d[i]['shopId']}})">{{d[i]['shopName']}}</a>:{{d[i]['shopReply']}}</p> + <p class="reply-time">{{d[i]['replyTime']}}</p> + </div> + {{# } }} + + </div> + <div class="wst-clear"></div> + </div> + {{# } }} + </script> + <div class="wst-tab-item" style="position: relative;display:none;"> + <div class="appraise-head"> + <div class="app-head-l"> + <div class="app-head-lbox"> + <strong class="text">好评度</strong> + <div class='percent'> + <i class="best_percent">0</i><span>%</span> + </div> + </div> + + </div> + <div class="app-head-r"> + <div class="app-head-rbox"> + <div class="app-hr-item"> + <div class="app-hr-text">好评(<i class="best_percent">0</i>%)</div> + <div class="percentbox"> + <div class="percentbg" id="best_percentbg" style="width:0%"></div> + </div> + </div> + <div class="app-hr-item"> + <div class="app-hr-text">中评(<i class="good_percent">0</i>%)</div> + <div class="percentbox"> + <div class="percentbg" id="good_percentbg" style="width:0%"></div> + </div> + </div> + <div class="app-hr-item"> + <div class="app-hr-text">差评(<i class="bad_percent">0</i>%)</div> + <div class="percentbox"> + <div class="percentbg" id="bad_percentbg" style="width:0%"></div> + </div> + </div> + </div> + </div> + + </div> + <div id='ga-box'> + + </div> + <div id='pager' style='text-align:center;'></div> + </div> + {/* 商品咨询 */} + <div class="wst-tab-item" style="position: relative;display:none;"> + <div class="appr-filter"> + <input type='hidden' id="consultType" value="0" /> + <ul class="appr-filterbox"> + <li><a class="gc-filter curr" href="javascript:void(0)" onclick="filterConsult(this,'0')">全部</a></li> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <li><a class="gc-filter" href="javascript:void(0)" onclick="filterConsult(this,'{$vo.dataVal}')">{$vo.dataName}</a></li> + {/volist} + </ul> + </div> + <div class="consult-searchbox"> + <p class="search-tips">温馨提示:因每位咨询者购买情况、咨询时间等不同,以下回复对咨询者3天内有效,其他网友仅供参考。</p> + <div class="searchout"> + <input type="text" class="search-text" id="consultKey" placeholder="请输入关键词" /> + <button class="csbtn" onClick="queryConsult(0)">搜索</button> + </div> + </div> + <div class="wst-clear"></div> + <div class="consult-listbox" id="consultBox"> + + </div> + <script id="gclist" type="text/html"> + <ul class='consult-list'> + {{# for(var i=0;i<d.length;++i){ }} + <li> + <ul class="consult-item"> + {/* 提问 */} + <li class='ask'> + <p class="wst-lfloat">咨询内容:</p> + <div class="wst-lfloat cs-content">{{d[i]['consultContent']}}&nbsp;<span class="c999">({{(WST.blank(d[i]['loginName'])=='')?'游客':d[i]['loginName']}})</span></div> + <div class="wst-rfloat">{{d[i]['createTime']}}</div> + <div class="wst-clear"></div> + </li> + {/* 回复 */} + {{# if(d[i]['reply']!=''){ }} + <li class='answer'> + <p class="wst-lfloat">商家回复:</p> + <div class="wst-lfloat cs-content"> + {{d[i]['reply']}} + </div> + <div class="wst-rfloat">{{d[i]['replyTime']}}</div> + <div class="wst-clear"></div> + </li> + {{# } }} + + </ul> + </li> + {{# } }} + </ul> + </script> + <div id="consult-pager" style="text-align:right;margin-top:10px;"> + 商品咨询分页占位 + </div> + {/* 发表咨询 */} + <div class="consult-publish"> + <h5>发表咨询</h5> + <div class="explain"> + 声明:您可在购买前对产品包装、颜色、运输、库存等方面进行咨询,我们有专人进行回复!因厂家随时会更改一些产品的包装、颜色、产地等参数,所以该回复仅在当时对提问者有效,其他网友仅供参考!咨询回复的工作时间为:周一至周五,9:00至18:00,请耐心等待工作人员回复。 + </div> + <ul> + <li> + <span class='fbold'>咨询类型:</span> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <label> + <input type="radio" name="pointType" value="{$vo.dataVal}" />{$vo.dataName} + </label> + {/volist} + + </li> + <li> + <span class='fbold'>咨询内容:</span> + <textarea id="consultContent" placeholder='3~200个字符长度' maxlength='200'></textarea> + </li> + <li> + <button id="consultCommit" onclick="consultCommit()">提交</button> + </li> + </ul> + </div> + </div> + </div> + </div> + <div class='wst-clear'></div> + </div> + <div class='wst-clear'></div> +</div> +{/* 对比框 */} +<div class="wst-cont-frame" id="j-cont-frame"> + <div class="head"><span>对比栏</span><a href="javascript:void(0);" class="close" onclick="javascript:contrastGoods(0,0,0)">关闭</a></div> + <div class="list"> + <div class="goods" id="contrastList"></div> + <div class="term-contrast"> + <p><a class="contrast" href="{:Url('home/goods/contrast')}" target="_blank">对比</a></p> + <p><a href="javascript:void(0);" onclick="javascript:contrastDel(0)" class="empty">清空</a></p> + </div> + </div> + <script id="colist" type="text/html"> + {{# if(d.data && d.data.length>0){ }} + {{# for(var i=0; i<d.data.length; i++){ }} + <div class="term"> + <div class="img"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><img class="contImg" data-original="__IMGURL__/{{ d.data[i].goodsImg }}" title="{{ d.data[i].goodsName }}" width="50" height="50"></a></div> + <div class="info"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><p class="name">{{ d.data[i].goodsName }}</p></a><p class="price"><span>¥{{ d.data[i].shopPrice }}</span><a href="javascript:contrastDel({{ d.data[i].goodsId }});" >删除</a></p></div> + </div> + {{# } }} + {{# } }} + {{# var data = (d.data)?d.data.length:0 }} + {{# for(var i=data+1; i<5; i++){ }} + <div class="term-empty"> + <div class="img">{{ i }}</div> + <div class="info"><p>您还可以继续添加</p></div> + </div> + {{# } }} + </script> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script> +var goodsInfo = { + id:{$goods['goodsId']}, + isSpec:{$goods['isSpec']}, + goodsStock:{$goods['goodsStock']}, + marketPrice:"{$goods['marketPrice']}", + goodsPrice:"{$goods['shopPrice']}", + goodsHuibao:"{$goods['shopPrice']*0.8}" + {if isset($goods['saleSpec'])} + ,sku:{:json_encode($goods['saleSpec'])} + {/if} +} +</script> +<script type='text/javascript' src='__STYLE__/js/cloudzoom.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/goods.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> +$(function(){ + var qr = qrcode(10, 'M'); + //var url = '{:url("mobile/goods/detail","","html",true)}?goodsId={$goods["goodsId"]}'; + var url = '{:url("/mgoods","","",true)}-{$goods["goodsId"]}'; + qr.addData(url); + qr.make(); + $('.qrcode').html(qr.createImgTag()); +}); +function goShop(id){ + location.href=WST.U('home/shops/home','shopId='+id); +} +</script> +{/block} diff --git a/hyhproject/home2/view/default/goods_list.html b/hyhproject/home2/view/default/goods_list.html new file mode 100755 index 0000000..8b69f7c --- /dev/null +++ b/hyhproject/home2/view/default/goods_list.html @@ -0,0 +1,449 @@ +{extend name="default/base" /} +{block name="title"}{$catNamePath} - 商品列表 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')}"> +<meta name="Keywords" content="{:WSTConf('CONF.seoMallKeywords')}"> +{/block} +{block name="css"} +<link href="__STYLE__/css/goodslist.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {include file="default/header" /} +{/block} +{block name="main"} +{/* 推荐热卖 */} +<div class='wst-hot-sales'> + <div class='wst-sales-logo'> + &nbsp;<span class="wst-hot-icon">热卖推荐</span> + </div> + <ul class='wst-sales-box'> + {wst:goods type='recom' cat='$catId' num='4'} + <li class="item"> + <div class="img"><a target='_blank' href='{:Url("home/goods/detail","id=".$vo["goodsId"])}'><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" title="{$vo['goodsName']}" alt="{$vo['goodsName']}" /></a></div> + <div class="des"> + <div class="p-sale">已售{$vo['saleNum']}件</div> + <div class="p-name"><a target='_blank' href='{:Url("home/goods/detail","id=".$vo["goodsId"])}'>{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}</div> + <div class="p-buy"><a href="javascript:WST.addCart({$vo['goodsId']})">加入购物车</a></div> + </div> + </li> + {/wst:goods} + </ul> +</div> + +{/* 已筛选的条件 */} +<input type="hidden" id="cat" class="sipt" value='{$catId}'/> +<input type="hidden" id="brand" class="sipt" value='{$brandId}'/> +{volist name="$vs" id="v"} +<input type="hidden" id="v_{$v}" class="sipt" value='{$attrs["v_".$v]}'/> +{/volist} +<input type="hidden" id="vs" class="sipt" value='{:implode(",",$vs)}'/> +<input type="hidden" id="orderBy" class="sipt" value='{$orderBy}'/> +<input type="hidden" id="order" class="sipt" value='{php}echo ($order=="0")?"1":"0";{/php}' autocomplete="off"/> +<input type="hidden" id="areaId" class="sipt" value='{$areaId}' /> +<div class='wst-filters'> + <div class='item' style="border-left:2px solid #df2003;padding-left: 8px;"> + <a class='link' href='__ROOT__'>首页</a> + <i class="arrow">></i> + </div> + {if($catId)} + {volist name=":WSTPathGoodsCat($catId)" id='vo'} + <div class='wst-lfloat'> + <div class='item dorpdown'> + <div class='drop-down'> + <a class='link' href='__ROOT__'>{$vo['catName']}</a> + <i class="drop-down-arrow"></i> + </div> + <div class="dorp-down-layer"> + {volist name=":WSTGoodsCats($vo['parentId'])" id='vo2'} + <div class="{$vo['parentId']>0?'cat2':'cat1'}"><a href='{:Url("home/goods/lists","cat=".$vo2["catId"])}'>{$vo2['catName']}</a></div> + {/volist} + </div> + </div> + <i class="arrow">></i> + </div> + + {/volist} + {volist name="$selector" id='vo'} + <div class='item dorpdown'> + <a class='v-item' href='javascript:void(0);' onclick="javscript:removeFilter('{$vo['type']}')"> + <span>{$vo['label']}:{$vo['val']}</span> + <i>x</i> + </a> + <i class="arrow">></i> + </div> + {/volist} + {else} + <div class='item'> + <a class='link' href='javascript:void(0);'>全部商品分类</a> + </div> + {/if} + <div class='wst-clear'></div> +</div> +{/* 筛选条件 */} +<div class="wst-selector"> + <div class='head'>商品筛选条件</div> + <div class="main"> + {php}$selectorNum = 0;{/php} + {if !empty($brandFilter)} + {php}$selectorNum++;{/php} + <div class='item'> + <div class='label'>品牌:</div> + <ul class='content brand_itembox' > + {volist name="$brandFilter" id="bv"} + <li class='s-item brand_item' onclick='javascript:goodsFilter(this,1)' v="{$bv['brandId']}"> + + <div class="g_bd_imgbox"><img src="__IMGURL__/{$bv.brandImg}" class="g_bd_img" onerror="this.style.display='none'" />{$bv['brandName']}</div> + + <a class="s_chk"><i></i></a> + </li> + {/volist} + </ul> + <div class='extra'> + <a href="javascript:void(0)" class="extra_more" onClick="extra_show(this)">更多<i></i></a> + <a href="javascript:void(0)" class="extra_multi" onClick="multibox_show(this,'brand')"><i></i>多选</a> + <div class="wst-clear"></div> + </div> + <div class='wst-clear'></div> + </div> + {/if} + {volist name="$goodsFilter" id="gv"} + {php}$selectorNum++;{/php} + <input type="hidden" id="v_{$gv['attrId']}" class="sipt" value=''/> + <div class='item <?=($selectorNum > 3)?"hideItem hide":"" ?>'> + <div class='label'>{$gv['attrName']}:</div> + <ul class='content'> + {volist name="$gv['attrVal']" id="gvi"} + <li class='s-item' onclick='javascript:goodsFilter(this,3)' d="{$gv['attrId']}" v="{$gvi}"> + <a class="s_chk"><i></i>{$gvi}</a> + </li> + {/volist} + </ul> + <div class='extra'> + <a href="javascript:void(0)" class="extra_more" onClick="extra_show(this)">更多<i></i></a> + <a href="javascript:void(0)" class="extra_multi" onClick="multibox_show(this,'attr')"><i></i>多选</a> + <div class="wst-clear"></div> + </div> + <div class='wst-clear'></div> + </div> + {/volist} + {php}$selectorNum++;{/php} + {if $sprice=='' && $eprice==''} + <div class='item <?=($selectorNum > 3)?"hideItem hide":"" ?>'> + <div class='label'>价格:</div> + <ul class='content'> + {volist name='priceGrade' id='vo' key='pKey'} + <li class='s-item' onclick='javascript:goodsFilter(this,2)' v="{$key}">{$vo}</li> + {/volist} + </ul> + <div class='extra'>&nbsp;</div> + <div class='wst-clear'></div> + </div> + {/if} + {if $selectorNum > 3} + <div class="item-more-box"> + <div class='item-more' v="1"><span>更多选项</span><i class="drop-down"></i></div> + </div> + {/if} + </div> + <div class='wst-clear'></div> +</div> + +{/* 商品展示 */} +<div class="wst-container"> + <div class='goods-side'> + <div class="guess-like"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' cat="$catId" num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + <div class="hot-goods"> + <div class="title">热销商品</div> + {wst:goods type='hot' cat="$catId" num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + </div> + <div class='goods-main'> + <div class='goods-filters'> + <div class='line line2'> + <a class="{if condition="$orderBy eq 0"}curr {/if}" href='javascript:void(0)' onclick='javascript:goodsOrder(0)'>销量<span class="{if condition="$orderBy neq 0"}store{/if}{if condition="$orderBy eq 0 and $order eq 1"}store2{/if}{if condition="$orderBy eq 0 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==1?'curr':''}" href='javascript:void(0)' onclick='javascript:goodsOrder(1)'>价格<span class="{if condition="$orderBy neq 1"}store{/if}{if condition="$orderBy eq 1 and $order eq 1"}store2{/if}{if condition="$orderBy eq 1 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==2?'curr':''}" href='javascript:void(0)' onclick='javascript:goodsOrder(2)'>评论数<span class="{if condition="$orderBy neq 2"}store{/if}{if condition="$orderBy eq 2 and $order eq 1"}store2{/if}{if condition="$orderBy eq 2 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==3?'curr':''}" href='javascript:void(0)' onclick='javascript:goodsOrder(3)'>人气<span class="{if condition="$orderBy neq 3"}store{/if}{if condition="$orderBy eq 3 and $order eq 1"}store2{/if}{if condition="$orderBy eq 3 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==4?'curr':''}" href='javascript:void(0)' onclick='javascript:goodsOrder(4)'>上架时间<span class="{if condition="$orderBy neq 4"}store{/if}{if condition="$orderBy eq 4 and $order eq 1"}store2{/if}{if condition="$orderBy eq 4 and $order eq 0"}store3{/if}"></span></a> + <div class="wst-price-ipts"> + <span class="wst-price-ipt1">¥</span><span class="wst-price-ipt2">¥</span> + <input type="text" class="sipt wst-price-ipt" id="sprice" value="{$sprice}" style="margin-left:8px;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + - <input type="text" class="sipt wst-price-ipt" id="eprice" value="{$eprice}" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <button class="wst-price-but" type="submit" style="width:60px;height: 25px;" onclick='javascript:goodsOrder()'>确定</button> + + + <div class="page" style="float:right;"> + <a href="javascript:;" onclick="page('prev')">上一页</a> + <a href="javascript:;" onclick="page('next')" >下一页</a> + </div> + </div> + <div class='line'> + <div class='wst-lfloat chk'>发货地</div> + <div class='city wst-address'> + <div class='item dorpdown'> + <div class='drop-down'> + <a class='link' href='__ROOT__'> + {if empty($areaInfo['areaName'])} + 请选择 + {else /} + {$areaInfo['areaName']} + {/if} + </a> + <i class="drop-down-arrow"></i> + </div> + + + <div class="dorp-down-layer"> + <div class="tab-header"> + <ul class="tab"> + <li class="tab-item1" id="fl_1_1" onclick="gpanelOver(this);" c="1" > + {if isset($areaInfo)} + <a href='javascript:void(0)'>{$areaInfo[0]['areaName']}</a> + {else /} + <a href='javascript:void(0)'>请选择</a> + {/if} + </li> + + {if isset($areaInfo)} + <li class="tab-item1" id="fl_1_2" onclick="gpanelOver(this);" c="1" > + <a href="javascript:void(0)">{$areaInfo[1]['areaName']}</a> + </li> + <li class="tab-item1 j-tab-selected1" id="fl_1_3" onclick="gpanelOver(this);" c="1" > + <a href="javascript:void(0)">{$areaInfo[2]['areaName']}</a> + </li> + {else /} + <li class="tab-item1" id="fl_1_2" onclick="gpanelOver(this);" c="1" pid="" > + <a href="javascript:void(0)">请选择</a> + </li> + <li class="tab-item1 j-tab-selected1" id="fl_1_3" onclick="gpanelOver(this);" c="1" pid="" > + <a href="javascript:void(0)">请选择</a> + </li> + {/if} + + + + </ul> + </div> + <ul class="area-box" id="fl_1_1_pl" style="display:none;"> + {volist name="$area1" id="area1"} + <li onclick="choiceArea(this,{$area1['areaId']})"><a href="javascript:void(0)">{$area1['areaName']}</a></li> + {/volist} + </ul> + <ul class="area-box" id="fl_1_2_pl" style="display:none;"> + {volist name="$area2" id="area2"} + <li onclick="choiceArea(this,{$area2['areaId']})"><a href="javascript:void(0)">{$area2['areaName']}</a></li> + {/volist} + </ul> + + <ul class="area-box" id="fl_1_3_pl" > + {volist name="$area3" id="area3"} + <li onclick="choiceArea(this,{$area3['areaId']})"><a href="javascript:void(0)">{$area3['areaName']}</a></li> + {/volist} + </ul> + + </div> + </div> + </div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isStock' value='1' class="sipt wst-checkbox-s" onclick="goodsFilter(this,4)" type='checkbox' id="stock" {if $isStock==1}checked{/if}/> + <label for="stock"></label> + </div> + 仅显示有货</div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isNew' value='1' class="sipt wst-checkbox-s" onclick="goodsFilter(this,4)" type='checkbox' id="new" {if $isNew==1}checked{/if}/> + <label for="new"></label> + </div> + 新品</div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isFreeShipping' value='1' class="sipt wst-checkbox-s" onclick="goodsFilter(this,4)" type='checkbox' id="freeShipping" {if $isFreeShipping==1}checked{/if}/> + <label for="freeShipping"></label> + </div> + 包邮</div> + </div> + </div> + <div class="goods-list"> + {volist name='goodsPage["Rows"]' id='vo'} + <div class="goods"> + <div class="img"> + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"> + <img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" class='goodsImg2' data-original="__IMGURL__/{$vo['goodsImg']}"/> + </a> + </div> + {php} + $img_listarr = explode(',',$vo['gallery']); + array_unshift($img_listarr,$vo['goodsImg']); + {/php} + <ul class="img_list"> + {volist name="$img_listarr" id="ils" key="ils_k" length="8"} + {if($ils!='')} + <li class="{if($ils_k==1)}curr{/if}"><img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" class='goodsImg2' data-original="__IMGURL__/{$ils}"/></li> + {/if} + {/volist} + <div class="wst-clear"></div> + </ul> + <div class="p-name"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}" class="wst-redlink" title="{$vo['goodsName']}">{$vo['goodsName']}</a></div> + <div> + <div class="p-price">¥{$vo['shopPrice']}</div> + <div class="p-hsale"> + <div class="sale-num">成交数:<span class="wst-fred">{$vo['saleNum']}</span></div> + <a class="p-add-cart" style="display:none;" href="javascript:WST.addCart({$vo['goodsId']});">加入购物车</a> + </div> + <div class='wst-clear'></div> + </div> + <div> + <div class="p-mprice">市场价<span>¥{$vo['marketPrice']}</span></div> + <div class="p-appraise">已有<span class="wst-fred">{$vo['appraiseNum']}</span>人评价</div> + <div class='wst-clear'></div> + </div> + + {if empty($is_icp)} + <div class="p-shop"> + <a href="{:Url('home/shops/home','shopId='.$vo['shopId'])}" target='_blank' class="wst-redlink">{$vo['shopName']}</a> + <a class="contrast" href="javascript:void(0);" onclick="javascript:contrastGoods(1,{$vo['goodsId']},1)"><i></i>对比</a> + </div> + {/if} + <div class="tags"> + {volist name="vo['tags']" id='tv'} + {$tv} + {/volist} + </div> + </div> + + {/volist} + <div class='wst-clear'></div> + </div> + <div style="position: absolute;bottom: -50px;width:980px;"> + <div id="wst-pager"></div> + </div> + + </div> + <div class='wst-clear'></div> + <div style="height: 50px;"></div> + + {/* 您最近浏览的商品 */} + {if cookie("history_goods")!=''} + <div class="wst-gview"> + <div class="title">您最近浏览的商品</div> + <div class="view-goods"> + {wst:goods type='history' cat="$catId" num='7'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink" href="{:Url('home/goods/detail','id='.$vo['goodsId'])}">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + <div class='wst-clear'></div> + </div> + </div> + {/if} +</div> +{/* 对比框 */} +<div class="wst-cont-frame" id="j-cont-frame"> + <div class="head"><span>对比栏</span><a href="javascript:void(0);" class="close" onclick="javascript:contrastGoods(0,0,0)">关闭</a></div> + <div class="list"> + <div class="goods" id="contrastList"></div> + <div class="term-contrast"> + <p><a class="contrast" href="{:Url('home/goods/contrast')}" target="_blank">对比</a></p> + <p><a href="javascript:void(0);" onclick="javascript:contrastDels(0)" class="empty">清空</a></p> + </div> + </div> + <script id="colist" type="text/html"> + {{# if(d.data && d.data.length>0){ }} + {{# for(var i=0; i<d.data.length; i++){ }} + <div class="term"> + <div class="img"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><img class="contImg" data-original="__IMGURL__/{{ d.data[i].goodsImg }}" title="{{ d.data[i].goodsName }}" width="50" height="50"></a></div> + <div class="info"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><p class="name">{{ d.data[i].goodsName }}</p></a><p class="price"><span>¥{{ d.data[i].shopPrice }}</span><a href="javascript:contrastDels({{ d.data[i].goodsId }});" >删除</a></p></div> + </div> + {{# } }} + {{# } }} + {{# var data = (d.data)?d.data.length:0 }} + {{# for(var i=data+1; i<5; i++){ }} + <div class="term-empty"> + <div class="img">{{ i }}</div> + <div class="info"><p>您还可以继续添加</p></div> + </div> + {{# } }} + </script> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/goodslist.js?v={$v}'></script> +<script type='text/javascript'> +$(function(){ + {if !isset($areaInfo)} + $('#fl_1_1').click(); + {/if} + contrastGoods(1,0,2); +}) +laypage({ + cont: 'wst-pager', + pages: {$goodsPage["TotalPage"]}, //总页数 + skip: true, //是否开启跳页 + skin: '#e23e3d', + groups: 3, //连续显示分页数 + curr: function(){ //通过url获取当前页,也可以同上(pages)方式获取 + var page = location.search.match(/page=(\d+)/); + return page ? page[1] : 1; + }(), + jump: function(e, first){ //触发分页后的回调 + if(!first){ //一定要加此判断,否则初始时会无限刷新 + var nuewurl = WST.splitURL("page"); + var ulist = nuewurl.split("?"); + if(ulist.length>1){ + location.href = nuewurl+'&page='+e.curr; + }else{ + location.href = '?page='+e.curr; + } + + } + } +}); + + + +var total = {$goodsPage["TotalPage"]}; +function page(t){ + var page = location.search.match(/page=(\d+)/); + var curr = 1; + if(page && page.length>1){ //说明当前url上有page参数 + curr = page[1]; // 当前页 + } + var nuewurl = WST.splitURL("page"); // 当前url + var ulist = nuewurl.split("?"); // 将传递的参数与url分开 + // 说明当前有参数. 需要带着参数一起传递 + var url = (ulist.length>1)?nuewurl+'&page=':'?page='; + + if(t=='prev'){ // 上一页 + if(curr<=1)return; + curr = parseInt(curr)-1; + location.href = url+curr; + }else{ // 下一页 + if(curr>=total)return; + curr = parseInt(curr)+1; + location.href = url+curr; + } + +} +</script> +{/block} diff --git a/hyhproject/home2/view/default/goods_search.html b/hyhproject/home2/view/default/goods_search.html new file mode 100755 index 0000000..67fbcce --- /dev/null +++ b/hyhproject/home2/view/default/goods_search.html @@ -0,0 +1,334 @@ +{extend name="default/base" /} +{block name="title"}商品搜索 -{:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')},商品关键字搜索"> +<meta name="Keywords" content="{$keyword}"> +{/block} +{block name="css"} +<link href="__STYLE__/css/goodslist.css?v={$v}" rel="stylesheet"> +{/block} +{block name="nav"} + {include file="default/header" /} +{/block} +{block name="main"} +{/* 推荐热卖 */} +<div class='wst-hot-sales'> + <div class='wst-sales-logo'> + &nbsp;<span class="wst-hot-icon">热卖推荐</span> + </div> + <ul class='wst-sales-box'> + {wst:goods type='recom' num='4'} + <li class="item"> + <div class="img"><a target='_blank' href='{:Url("home/goods/detail","id=".$vo["goodsId"])}'><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" title="{$vo['goodsName']}" alt="{$vo['goodsName']}" /></a></div> + <div class="des"> + <div class="p-sale">已售{$vo['saleNum']}件</div> + <div class="p-name"><a target='_blank' href='{:Url("home/goods/detail","id=".$vo["goodsId"])}'>{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}</div> + <div class="p-buy"><a href="javascript:WST.addCart({$vo['goodsId']})">加入购物车</a></div> + </div> + </li> + {/wst:goods} + </ul> +</div> +<input type="hidden" id="keyword" class="sipt" value='{$keyword}'/> +<input type="hidden" id="orderBy" class="sipt" value='{$orderBy}'/> +<input type="hidden" id="order" class="sipt" value='{$order}'/> +<input type="hidden" id="areaId" class="sipt" value='{$areaId}'/> +<div class='wst-filters'> + <div class='item' style="border-left:2px solid #df2003;padding-left: 8px;"> + <a class='link' href='__ROOT__'>全部结果</a> + <i class="arrow">></i> + </div> + <div class='wst-lfloat keyword'>{$keyword}</div> + <div class='wst-clear'></div> +</div> +{/* 商品展示 */} +<div class="wst-container"> + {if !empty($goodsPage["Rows"])} + <div class='goods-side'> + <div class="guess-like"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + <div class="hot-goods"> + <div class="title">热销商品</div> + {wst:goods type='hot' num='3'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + </div> + </div> + <div class='goods-main'> + <div class='goods-filters'> + <div class='line'> + <div class='wst-lfloat chk'>发货地</div> + <div class='city wst-address'> + <div class='item dorpdown'> + <div class='drop-down'> + <a class='link' href='__ROOT__'> + {if empty($areaInfo['areaName'])} + 请选择 + {else /} + {$areaInfo['areaName']} + {/if} + </a> + <i class="drop-down-arrow"></i> + </div> + <div class="dorp-down-layer"> + <div class="tab-header"> + <ul class="tab"> + <li class="tab-item1" id="fl_1_1" onclick="gpanelOver(this);" c="1" > + {if isset($areaInfo)} + <a href='javascript:void(0)'>{$areaInfo[0]['areaName']}</a> + {else /} + <a href='javascript:void(0)'>请选择</a> + {/if} + </li> + + {if isset($areaInfo)} + <li class="tab-item1" id="fl_1_2" onclick="gpanelOver(this);" c="1" > + <a href="javascript:void(0)">{$areaInfo[1]['areaName']}</a> + </li> + <li class="tab-item1 j-tab-selected1" id="fl_1_3" onclick="gpanelOver(this);" c="1" > + <a href="javascript:void(0)">{$areaInfo[2]['areaName']}</a> + </li> + {else /} + <li class="tab-item1" id="fl_1_2" onclick="gpanelOver(this);" c="1" pid="" > + <a href="javascript:void(0)">请选择</a> + </li> + <li class="tab-item1 j-tab-selected1" id="fl_1_3" onclick="gpanelOver(this);" c="1" pid="" > + <a href="javascript:void(0)">请选择</a> + </li> + {/if} + + + + </ul> + </div> + <ul class="area-box" id="fl_1_1_pl" style="display:none;"> + {volist name="$area1" id="area1"} + <li onclick="choiceArea(this,{$area1['areaId']})" search='1'><a href="javascript:void(0)">{$area1['areaName']}</a></li> + {/volist} + </ul> + <ul class="area-box" id="fl_1_2_pl" style="display:none;"> + {volist name="$area2" id="area2"} + <li onclick="choiceArea(this,{$area2['areaId']})" search='1'><a href="javascript:void(0)">{$area2['areaName']}</a></li> + {/volist} + </ul> + + <ul class="area-box" id="fl_1_3_pl"> + {volist name="$area3" id="area3"} + <li onclick="choiceArea(this,{$area3['areaId']})" search='1'><a href="javascript:void(0)">{$area3['areaName']}</a></li> + {/volist} + </ul> + + </div> + + + </div> + </div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isStock' value='1' class="sipt wst-checkbox-s" onclick="searchFilter(this,4)" type='checkbox' id="stock" {if $isStock==1}checked{/if}/> + <label for="stock"></label> + </div> + 仅显示有货</div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isNew' value='1' class="sipt wst-checkbox-s" onclick="searchFilter(this,4)" type='checkbox' id="new" {if $isNew==1}checked{/if}/> + <label for="new"></label> + </div> + 新品</div> + <div class='chk'> + <div class="checkbox-box-s"> + <input name='isFreeShipping' value='1' class="sipt wst-checkbox-s" onclick="searchFilter(this,4)" type='checkbox' id="freeShipping" {if $isFreeShipping==1}checked{/if}/> + <label for="freeShipping"></label> + </div> + 包邮</div> + </div> + <div class='line line2'> + <a class="{if condition="$orderBy eq 0"}curr {/if}" href='javascript:void(0)' onclick='javascript:searchOrder(0)'>销量<span class="{if condition="$orderBy neq 0"}store{/if}{if condition="$orderBy eq 0 and $order eq 1"}store2{/if}{if condition="$orderBy eq 0 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==1?'curr':''}" href='javascript:void(0)' onclick='javascript:searchOrder(1)'>价格<span class="{if condition="$orderBy neq 1"}store{/if}{if condition="$orderBy eq 1 and $order eq 1"}store2{/if}{if condition="$orderBy eq 1 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==2?'curr':''}" href='javascript:void(0)' onclick='javascript:searchOrder(2)'>评论数<span class="{if condition="$orderBy neq 2"}store{/if}{if condition="$orderBy eq 2 and $order eq 1"}store2{/if}{if condition="$orderBy eq 2 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==3?'curr':''}" href='javascript:void(0)' onclick='javascript:searchOrder(3)'>人气<span class="{if condition="$orderBy neq 3"}store{/if}{if condition="$orderBy eq 3 and $order eq 1"}store2{/if}{if condition="$orderBy eq 3 and $order eq 0"}store3{/if}"></span></a> + <a class="{$orderBy==4?'curr':''}" href='javascript:void(0)' onclick='javascript:searchOrder(4)'>上架时间<span class="{if condition="$orderBy neq 4"}store{/if}{if condition="$orderBy eq 4 and $order eq 1"}store2{/if}{if condition="$orderBy eq 4 and $order eq 0"}store3{/if}"></span></a> + <div class="wst-price-ipts"> + <span class="wst-price-ipt1">¥</span><span class="wst-price-ipt2">¥</span> + <input type="text" class="sipt wst-price-ipt" id="sprice" value="{$sprice}" style="margin-left:8px;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + - <input type="text" class="sipt wst-price-ipt" id="eprice" value="{$eprice}" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <button class="wst-price-but" type="submit" style="width:60px;height: 25px;" onclick='javascript:searchOrder()'>确定</button> + </div> + </div> + <div class="goods-list"> + {volist name='goodsPage["Rows"]' id='vo'} + <div class="goods"> + <div class="img"> + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" class='goodsImg2' data-original="__IMGURL__/{$vo['goodsImg']}"/></a> + </div> + {php} + $img_listarr = explode(',',$vo['gallery']); + array_unshift($img_listarr,$vo['goodsImg']); + {/php} + <ul class="img_list"> + {volist name="$img_listarr" id="ils" key="ils_k"} + {if($ils!='')} + <li class="{if($ils_k==1)}curr{/if}"><img title="{$vo['goodsName']}" alt="{$vo['goodsName']}" class='goodsImg2' data-original="__IMGURL__/{$ils}"/></li> + {/if} + {/volist} + <div class="wst-clear"></div> + </ul> + <div class="p-name"> + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}" class="wst-redlink" title="{$vo['goodsName']}">{$vo['goodsName']}</a></div> + <div> + <div class="p-price">¥{$vo['shopPrice']}</div> + <div class="p-hsale"> + <div class="sale-num">成交数:<span class="wst-fred">{$vo['saleNum']}</span></div> + <a class="p-add-cart" style="display:none;" href="javascript:WST.addCart({$vo['goodsId']});">加入购物车</a> + </div> + <div class='wst-clear'></div> + </div> + <div> + <div class="p-mprice">市场价<span>¥{$vo['marketPrice']}</span></div> + <div class="p-appraise">已有<span class="wst-fred">{$vo['appraiseNum']}</span>人评价</div> + <div class='wst-clear'></div> + </div> + {if empty($is_icp)} + <div class="p-shop"> + <a href="{:Url('home/shops/home','shopId='.$vo['shopId'])}" target='_blank' class="wst-redlink">{$vo['shopName']}</a> + <a class="contrast" href="javascript:void(0);" onclick="javascript:contrastGoods(1,{$vo['goodsId']},1)"><i></i>对比</a> + </div> + {/if} + </div> + + {/volist} + <div class='wst-clear'></div> + </div> + <div style="width:980px;"> + <div id="wst-pager"></div> + </div> + + </div> + <div class='wst-clear'></div> + {else} + <div class="wst-no-goods">很抱歉,没有找到“<span>{$keyword}</span>”为关键字的商品搜索结果。</div> + {/* 找不到商品的话就为用户推荐一些 */} + <div class="wst-recommend"> + <div class="title">为您推荐<span style="float: right;"></span></div> + <div class="tgoods-list"> + {wst:goods type='best' num='5' id='rvo'} + <div class="goods"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$rvo['goodsId'])}"><img title="{$rvo['goodsName']}" alt="{$rvo['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$rvo['goodsImg']}"/></a></div> + <div class="p-name"><a target='_blank' class="wst-redlink">{$rvo['goodsName']}</a></div> + <div> + <div class="p-price">¥{$rvo['shopPrice']}</div> + <div class="p-hsale"> + <div class="sale-num">成交数:<span class="wst-fred">{$rvo['saleNum']}</span></div> + <a class="p-add-cart" style="display:none;" href="javascript:WST.addCart({$rvo['goodsId']});">加入购物车</a> + </div> + <div class='wst-clear'></div> + </div> + <div> + <div class="p-mprice">市场价<span>¥{$rvo['marketPrice']}</span></div> + <div class="p-appraise">已有<span class="wst-fred">{$rvo['appraiseNum']}</span>人评价</div> + <div class='wst-clear'></div> + </div> + <div class="p-shop"><a href="" class="wst-redlink">{$rvo['shopName']}</a></div> + </div> + {/wst:goods} + <div class='wst-clear'></div> + </div> + </div> + {/if} + {/* 您最近浏览的商品 */} + {if cookie("history_goods")!=''} + <div class="wst-gview"> + <div class="title">您最近浏览的商品</div> + <div class="view-goods"> + {wst:goods type='history' num='7'} + <div class="item"> + <div class="img"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" alt="{$vo['goodsName']}" title="{$vo['goodsName']}"/></a></div> + <div class="p-name"><a class="wst-hide wst-redlink" href="{:Url('home/goods/detail','id='.$vo['goodsId'])}">{$vo['goodsName']}</a></div> + <div class="p-price">¥{$vo['shopPrice']}<span class="v-price">¥{$vo['marketPrice']}</span></div> + </div> + {/wst:goods} + <div class='wst-clear'></div> + </div> + </div> + {/if} +</div> +{/* 对比框 */} +<div class="wst-cont-frame" id="j-cont-frame"> + <div class="head"><span>对比栏</span><a href="javascript:void(0);" class="close" onclick="javascript:contrastGoods(0,0,0)">关闭</a></div> + <div class="list"> + <div class="goods" id="contrastList"></div> + <div class="term-contrast"> + <p><a class="contrast" href="{:Url('home/goods/contrast')}" target="_blank">对比</a></p> + <p><a href="javascript:void(0);" onclick="javascript:contrastDels(0)" class="empty">清空</a></p> + </div> + </div> + <script id="colist" type="text/html"> + {{# if(d.data && d.data.length>0){ }} + {{# for(var i=0; i<d.data.length; i++){ }} + <div class="term"> + <div class="img"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><img class="contImg" data-original="__IMGURL__/{{ d.data[i].goodsImg }}" title="{{ d.data[i].goodsName }}" width="50" height="50"></a></div> + <div class="info"><a href="{{WST.U('home/goods/detail','id='+d.data[i].goodsId)}}" target="_blank"><p class="name">{{ d.data[i].goodsName }}</p></a><p class="price"><span>¥{{ d.data[i].shopPrice }}</span><a href="javascript:contrastDels({{ d.data[i].goodsId }});" >删除</a></p></div> + </div> + {{# } }} + {{# } }} + {{# var data = (d.data)?d.data.length:0 }} + {{# for(var i=data+1; i<5; i++){ }} + <div class="term-empty"> + <div class="img">{{ i }}</div> + <div class="info"><p>您还可以继续添加</p></div> + </div> + {{# } }} + </script> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/goodslist.js?v={$v}'></script> +{if !empty($goodsPage["Rows"])} +<script type='text/javascript'> +$(function(){ + {if !isset($areaInfo)} + $('#fl_1_1').click(); + {/if} + contrastGoods(1,0,2); +}) +laypage({ + cont: 'wst-pager', + pages: {$goodsPage["TotalPage"]}, //总页数 + skip: true, //是否开启跳页 + skin: '#e23e3d', + groups: 3, //连续显示分页数 + curr: function(){ //通过url获取当前页,也可以同上(pages)方式获取 + var page = location.search.match(/page=(\d+)/); + return page ? page[1] : 1; + }(), + jump: function(e, first){ //触发分页后的回调 + if(!first){ //一定要加此判断,否则初始时会无限刷新 + var nuewurl = WST.splitURL("page"); + var ulist = nuewurl.split("?"); + if(ulist.length>1){ + location.href = nuewurl+'&page='+e.curr; + }else{ + location.href = '?page='+e.curr; + } + + } + } +}); +</script> +{/if} +{/block} diff --git a/hyhproject/home2/view/default/header.html b/hyhproject/home2/view/default/header.html new file mode 100755 index 0000000..352df2e --- /dev/null +++ b/hyhproject/home2/view/default/header.html @@ -0,0 +1,141 @@ +<div class='wst-search-container'> + <div class='wst-logo'> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="120" width='240' title="{:WSTConf('CONF.mallName')}" alt="{:WSTConf('CONF.mallName')}"> + </a> + </div> + <div class="wst-search-box"> + <div class='wst-search'> + <input type="hidden" id="search-type" value="{:isset($keytype)?1:0}"/> + <ul class="j-search-box"> + <li class="j-search-type"> + {if empty($is_icp)}搜<span>{if isset($keytype)}店铺{else}商品{/if}</span>{else /}搜<span>商品&nbsp;</span>{/if}<i class="arrow"> </i> + </li> + {if empty($is_icp)} + <li class="j-type-list"> + {if isset($keytype)} + <div data="0">商品</div> + {else} + <div data="1">店铺</div> + {/if} + </li> + {/if} + </ul> + <input type="text" id='search-ipt' class='search-ipt' placeholder='{:WSTConf("CONF.adsGoodsWordsSearch")}' value='{:isset($keyword)?$keyword:""}'/> + <input type='hidden' id='adsGoodsWordsSearch' value='{:WSTConf("CONF.adsGoodsWordsSearch")}'> + <input type='hidden' id='adsShopWordsSearch' value='{:WSTConf("CONF.adsShopWordsSearch")}'> + <div id='search-btn' class="search-btn" onclick='javascript:WST.search(this.value)'>搜索</div> + </div> + <div class="wst-search-keys"> + {php}$searchKeys = WSTSearchKeys();{/php} + {volist name="$searchKeys" id="vo"} + <a href='{:Url("home/goods/search","keyword=".$vo)}'>{$vo}</a> + {if $i< count($searchKeys)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + </div> + <div class="wst-cart-box"> + <a href="{:url('home/carts/index')}" target="_blank" onclick="WST.currentUrl('{:url("home/carts/index")}');"><span class="word j-word">我的购物车<span class="num" id="goodsTotalNum">0</span></span></a> + <div class="wst-cart-boxs hide"> + <div id="list-carts"></div> + <div id="list-carts2"></div> + <div id="list-carts3"></div> + <div class="wst-clear"></div> + </div> + </div> +{/* 购物车 */} +<script id="list-cart" type="text/html"> +{{# for(var i = 0; i < d.list.length; i++){ }} + <div class="goods" id="j-goods{{ d.list[i].cartId }}"> + <div class="imgs"><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}"><img class="goodsImgc" data-original="__IMGURL__/{{ d.list[i].goodsImg }}" title="{{ d.list[i].goodsName }}"></a></div> + <div class="number"><p><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}">{{WST.cutStr(d.list[i].goodsName,26)}}</a></p><p>数量:{{ d.list[i].cartNum }}</p></div> + <div class="price"><p>¥{{ d.list[i].shopPrice }}</p><span><a href="javascript:WST.delCheckCart({{ d.list[i].cartId }})">删除</a></span></div> + </div> +{{# } }} +</script> +</div> +<div class="wst-clear"></div> +{/* 左侧菜单栏 */} +<div class="wst-nav-menus"> + <div class="nav-w" style="position: relative;"> + <div class="w-spacer"></div> + <div class="dorpdown {if isset($hideCategory)}j-index{/if}" id="wst-categorys"> + <div class="dt j-cate-dt"> + <a href="javascript:void(0)">全部商品分类</a> + </div> + <div class="dd j-cate-dd" {if !isset($hideCategory)}style="display:none" {/if}> + <div class="dd-inner"> + {volist name=":WSTSideCategorys()" id="vo" key="k"} + {php}if($vo['catId']!=389){{/php} + <div id="cat-icon-{$k}" class="item fore1 {if ($key>=12)}over-cat{/if}"> + <h3> + <div class="{if ($key>=12)} over-cat-icon {else /} cat-icon-{$k} {/if}"></div> + <a href="{:Url('home/goods/lists','cat='.$vo['catId'])}" target="_blank">{$vo['catName']}</a> + </h3> + </div> + {php}}{/php} + {/volist} + </div> + <div style="display: none;" class="dorpdown-layer" id="index_menus_sub"> + {volist name=":WSTSideCategorys()" id="vo" key="k"} + <div class="item-sub" i="{$k}"> + <div class="item-brands"> + <div class="brands-inner"> + {wst:brand cat="$vo['catId']" id="bvo" num='6' cache='86400'} + <a target="_blank" class="img-link" href="{:url('home/goods/lists',['cat'=>$bvo['catId'],'brand'=>$bvo['brandId']])}"> + <img width="83" height="65" class='categeMenuImg' data-original="__IMGURL__/{$bvo['brandImg']}"> + </a> + {/wst:brand} + <div class="wst-clear"></div> + </div> + <div class='shop-inner'> + {wst:shop cat="$vo['catId']" id="bvo" num='4' cache='86400'} + <a target="_blank" class="img-link" href="{:url('home/shops/home',['shopId'=>$bvo['shopId']])}"> + <img width="83" height="65" class='categeMenuImg' data-original="__IMGURL__/{$bvo['shopImg']}"> + </a> + {/wst:shop} + <div class="wst-clear"></div> + </div> + </div> + + <div class="subitems"> + {php}if(isset($vo['list'])){{/php} + {volist name="vo['list']" id="vo2"} + <dl class="fore2"> + <dd> + <a + class="cat2_tit" + target="_blank" + href="{:Url('home/goods/lists','cat='.$vo2['catId'])}"> + {$vo2['catName']} + <i>&gt;</i> + </a> + {php}if(isset($vo2['list'])){{/php} + {volist name="vo2['list']" id="vo3"} + <a target="_blank" href="{:Url('home/goods/lists','cat='.$vo3['catId'])}">{$vo3['catName']}</a> + {/volist} + {php}}{/php} + <div class="wst-clear"></div> + </dd> + </dl> + {/volist} + {php}}{/php} + </div> + </div> + {/volist} + </div> + </div> + </div> + {/* 横栏菜单 */} + <div id="wst-nav-items"> + <ul> + {volist name=":WSTNavigations(0)" id='vo'} + <li class="fore1"> + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + </li> + {/volist} + </ul> + </div> + +</div> +<div class="wst-clear"></div> diff --git a/hyhproject/home2/view/default/header_lite.html b/hyhproject/home2/view/default/header_lite.html new file mode 100755 index 0000000..5b13ea4 --- /dev/null +++ b/hyhproject/home2/view/default/header_lite.html @@ -0,0 +1,12 @@ +<div class='wst-lite-container'> + <div class='wst-logo'> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="120" width='240' title="{:WSTConf('CONF.mallName')}" alt="{:WSTConf('CONF.mallName')}"> + </a> + </div> + <div class="wst-lite-title">{$liteTitle}</div> + <div class="wst-lite-index"><a href='{$Request.root.true}'>返回首页</a></div> + <div class="wst-clear"></div> +</div> +<div style="border-bottom: 2px solid #df2003;"></div> +<div class="wst-clear"></div> \ No newline at end of file diff --git a/hyhproject/home2/view/default/img/alipays.png b/hyhproject/home2/view/default/img/alipays.png new file mode 100755 index 0000000..3b1d45b Binary files /dev/null and b/hyhproject/home2/view/default/img/alipays.png differ diff --git a/hyhproject/home2/view/default/img/apply-ok.png b/hyhproject/home2/view/default/img/apply-ok.png new file mode 100755 index 0000000..3a07fc2 Binary files /dev/null and b/hyhproject/home2/view/default/img/apply-ok.png differ diff --git a/hyhproject/home2/view/default/img/apply.png b/hyhproject/home2/view/default/img/apply.png new file mode 100755 index 0000000..42cb90d Binary files /dev/null and b/hyhproject/home2/view/default/img/apply.png differ diff --git a/hyhproject/home2/view/default/img/arrow.png b/hyhproject/home2/view/default/img/arrow.png new file mode 100755 index 0000000..0477c27 Binary files /dev/null and b/hyhproject/home2/view/default/img/arrow.png differ diff --git a/hyhproject/home2/view/default/img/bgimg_error_spcc.png b/hyhproject/home2/view/default/img/bgimg_error_spcc.png new file mode 100755 index 0000000..5b1bd9a Binary files /dev/null and b/hyhproject/home2/view/default/img/bgimg_error_spcc.png differ diff --git a/hyhproject/home2/view/default/img/bgimg_error_xtcc.png b/hyhproject/home2/view/default/img/bgimg_error_xtcc.png new file mode 100755 index 0000000..bc4f0c1 Binary files /dev/null and b/hyhproject/home2/view/default/img/bgimg_error_xtcc.png differ diff --git a/hyhproject/home2/view/default/img/bgimg_error_ymcc.png b/hyhproject/home2/view/default/img/bgimg_error_ymcc.png new file mode 100755 index 0000000..f35298f Binary files /dev/null and b/hyhproject/home2/view/default/img/bgimg_error_ymcc.png differ diff --git a/hyhproject/home2/view/default/img/btn_80x80.png b/hyhproject/home2/view/default/img/btn_80x80.png new file mode 100755 index 0000000..a37c685 Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_80x80.png differ diff --git a/hyhproject/home2/view/default/img/btn_QQ.png b/hyhproject/home2/view/default/img/btn_QQ.png new file mode 100755 index 0000000..88fae04 Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_QQ.png differ diff --git a/hyhproject/home2/view/default/img/btn_focus.png b/hyhproject/home2/view/default/img/btn_focus.png new file mode 100755 index 0000000..2ebb6a1 Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_focus.png differ diff --git a/hyhproject/home2/view/default/img/btn_pay.png b/hyhproject/home2/view/default/img/btn_pay.png new file mode 100755 index 0000000..2da394b Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_pay.png differ diff --git a/hyhproject/home2/view/default/img/btn_search_red.png b/hyhproject/home2/view/default/img/btn_search_red.png new file mode 100755 index 0000000..b4950a7 Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_search_red.png differ diff --git a/hyhproject/home2/view/default/img/btn_slide_left.png b/hyhproject/home2/view/default/img/btn_slide_left.png new file mode 100755 index 0000000..6266133 Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_slide_left.png differ diff --git a/hyhproject/home2/view/default/img/btn_slide_right.png b/hyhproject/home2/view/default/img/btn_slide_right.png new file mode 100755 index 0000000..a63ae0b Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_slide_right.png differ diff --git a/hyhproject/home2/view/default/img/btn_sqkd_back.png b/hyhproject/home2/view/default/img/btn_sqkd_back.png new file mode 100755 index 0000000..5e8be2d Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_sqkd_back.png differ diff --git a/hyhproject/home2/view/default/img/btn_wechat.png b/hyhproject/home2/view/default/img/btn_wechat.png new file mode 100755 index 0000000..88b720a Binary files /dev/null and b/hyhproject/home2/view/default/img/btn_wechat.png differ diff --git a/hyhproject/home2/view/default/img/close_ads.gif b/hyhproject/home2/view/default/img/close_ads.gif new file mode 100755 index 0000000..c040e49 Binary files /dev/null and b/hyhproject/home2/view/default/img/close_ads.gif differ diff --git a/hyhproject/home2/view/default/img/contrast.png b/hyhproject/home2/view/default/img/contrast.png new file mode 100755 index 0000000..b7849e7 Binary files /dev/null and b/hyhproject/home2/view/default/img/contrast.png differ diff --git a/hyhproject/home2/view/default/img/coupon_bg.png b/hyhproject/home2/view/default/img/coupon_bg.png new file mode 100755 index 0000000..0760f3c Binary files /dev/null and b/hyhproject/home2/view/default/img/coupon_bg.png differ diff --git a/hyhproject/home2/view/default/img/coupon_item1.png b/hyhproject/home2/view/default/img/coupon_item1.png new file mode 100755 index 0000000..dfa92a8 Binary files /dev/null and b/hyhproject/home2/view/default/img/coupon_item1.png differ diff --git a/hyhproject/home2/view/default/img/coupon_item2.png b/hyhproject/home2/view/default/img/coupon_item2.png new file mode 100755 index 0000000..a9e04b4 Binary files /dev/null and b/hyhproject/home2/view/default/img/coupon_item2.png differ diff --git a/hyhproject/home2/view/default/img/coupon_item_bg.png b/hyhproject/home2/view/default/img/coupon_item_bg.png new file mode 100755 index 0000000..f623fb9 Binary files /dev/null and b/hyhproject/home2/view/default/img/coupon_item_bg.png differ diff --git a/hyhproject/home2/view/default/img/cut_bg.png b/hyhproject/home2/view/default/img/cut_bg.png new file mode 100755 index 0000000..d3a1b18 Binary files /dev/null and b/hyhproject/home2/view/default/img/cut_bg.png differ diff --git a/hyhproject/home2/view/default/img/detail_qr_icon.png b/hyhproject/home2/view/default/img/detail_qr_icon.png new file mode 100755 index 0000000..2c46deb Binary files /dev/null and b/hyhproject/home2/view/default/img/detail_qr_icon.png differ diff --git a/hyhproject/home2/view/default/img/error_1.png b/hyhproject/home2/view/default/img/error_1.png new file mode 100755 index 0000000..1402e8e Binary files /dev/null and b/hyhproject/home2/view/default/img/error_1.png differ diff --git a/hyhproject/home2/view/default/img/examine.png b/hyhproject/home2/view/default/img/examine.png new file mode 100755 index 0000000..e0c6ec4 Binary files /dev/null and b/hyhproject/home2/view/default/img/examine.png differ diff --git a/hyhproject/home2/view/default/img/f1_bg.png b/hyhproject/home2/view/default/img/f1_bg.png new file mode 100755 index 0000000..4fbac59 Binary files /dev/null and b/hyhproject/home2/view/default/img/f1_bg.png differ diff --git a/hyhproject/home2/view/default/img/f3_bg.png b/hyhproject/home2/view/default/img/f3_bg.png new file mode 100755 index 0000000..79e3076 Binary files /dev/null and b/hyhproject/home2/view/default/img/f3_bg.png differ diff --git a/hyhproject/home2/view/default/img/f5_bg.png b/hyhproject/home2/view/default/img/f5_bg.png new file mode 100755 index 0000000..bd3f48e Binary files /dev/null and b/hyhproject/home2/view/default/img/f5_bg.png differ diff --git a/hyhproject/home2/view/default/img/f7_bg.png b/hyhproject/home2/view/default/img/f7_bg.png new file mode 100755 index 0000000..546880b Binary files /dev/null and b/hyhproject/home2/view/default/img/f7_bg.png differ diff --git a/hyhproject/home2/view/default/img/flag-each-69x26.png b/hyhproject/home2/view/default/img/flag-each-69x26.png new file mode 100755 index 0000000..9db4869 Binary files /dev/null and b/hyhproject/home2/view/default/img/flag-each-69x26.png differ diff --git a/hyhproject/home2/view/default/img/footer_icon.png b/hyhproject/home2/view/default/img/footer_icon.png new file mode 100755 index 0000000..88186e6 Binary files /dev/null and b/hyhproject/home2/view/default/img/footer_icon.png differ diff --git a/hyhproject/home2/view/default/img/goods_detail_arrow_r.png b/hyhproject/home2/view/default/img/goods_detail_arrow_r.png new file mode 100755 index 0000000..5ef5672 Binary files /dev/null and b/hyhproject/home2/view/default/img/goods_detail_arrow_r.png differ diff --git a/hyhproject/home2/view/default/img/goodsdetails_iconг▀jrdp.png b/hyhproject/home2/view/default/img/goodsdetails_iconг▀jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home2/view/default/img/goodsdetails_iconг▀jrdp.png differ diff --git a/hyhproject/home2/view/default/img/goodsdetails_iconя╝┐jrdp.png b/hyhproject/home2/view/default/img/goodsdetails_iconя╝┐jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home2/view/default/img/goodsdetails_iconя╝┐jrdp.png differ diff --git a/hyhproject/home2/view/default/img/goodsdetails_icon褟鈺濃攼jrdp.png b/hyhproject/home2/view/default/img/goodsdetails_icon褟鈺濃攼jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home2/view/default/img/goodsdetails_icon褟鈺濃攼jrdp.png differ diff --git a/hyhproject/home2/view/default/img/goodsdetails_icon谐鈻€jrdp.png b/hyhproject/home2/view/default/img/goodsdetails_icon谐鈻€jrdp.png new file mode 100755 index 0000000..4453790 Binary files /dev/null and b/hyhproject/home2/view/default/img/goodsdetails_icon谐鈻€jrdp.png differ diff --git a/hyhproject/home2/view/default/img/goodspay_img.png b/hyhproject/home2/view/default/img/goodspay_img.png new file mode 100755 index 0000000..2a0c36c Binary files /dev/null and b/hyhproject/home2/view/default/img/goodspay_img.png differ diff --git a/hyhproject/home2/view/default/img/groupon_bg.png b/hyhproject/home2/view/default/img/groupon_bg.png new file mode 100755 index 0000000..7096e15 Binary files /dev/null and b/hyhproject/home2/view/default/img/groupon_bg.png differ diff --git a/hyhproject/home2/view/default/img/ic_volume_24x24.png b/hyhproject/home2/view/default/img/ic_volume_24x24.png new file mode 100755 index 0000000..4352277 Binary files /dev/null and b/hyhproject/home2/view/default/img/ic_volume_24x24.png differ diff --git a/hyhproject/home2/view/default/img/icon-mjzxsy.png b/hyhproject/home2/view/default/img/icon-mjzxsy.png new file mode 100755 index 0000000..180e1c8 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon-mjzxsy.png differ diff --git a/hyhproject/home2/view/default/img/icon_class_zydp.png b/hyhproject/home2/view/default/img/icon_class_zydp.png new file mode 100755 index 0000000..9a9c0ab Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_class_zydp.png differ diff --git a/hyhproject/home2/view/default/img/icon_dianpujie_01.png b/hyhproject/home2/view/default/img/icon_dianpujie_01.png new file mode 100755 index 0000000..9498f24 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_dianpujie_01.png differ diff --git a/hyhproject/home2/view/default/img/icon_dianpujie_02.png b/hyhproject/home2/view/default/img/icon_dianpujie_02.png new file mode 100755 index 0000000..50119e3 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_dianpujie_02.png differ diff --git a/hyhproject/home2/view/default/img/icon_dianpujie_03.png b/hyhproject/home2/view/default/img/icon_dianpujie_03.png new file mode 100755 index 0000000..b2cb03d Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_dianpujie_03.png differ diff --git a/hyhproject/home2/view/default/img/icon_dianpujie_04.png b/hyhproject/home2/view/default/img/icon_dianpujie_04.png new file mode 100755 index 0000000..9290848 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_dianpujie_04.png differ diff --git a/hyhproject/home2/view/default/img/icon_dianpujie_09.png b/hyhproject/home2/view/default/img/icon_dianpujie_09.png new file mode 100755 index 0000000..44fe97d Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_dianpujie_09.png differ diff --git a/hyhproject/home2/view/default/img/icon_fenlei.png b/hyhproject/home2/view/default/img/icon_fenlei.png new file mode 100755 index 0000000..36daf9d Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_fenlei.png differ diff --git a/hyhproject/home2/view/default/img/icon_fenleitubiao.png b/hyhproject/home2/view/default/img/icon_fenleitubiao.png new file mode 100755 index 0000000..12577f9 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_fenleitubiao.png differ diff --git a/hyhproject/home2/view/default/img/icon_goodsclass_list.png b/hyhproject/home2/view/default/img/icon_goodsclass_list.png new file mode 100755 index 0000000..d5b3920 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_goodsclass_list.png differ diff --git a/hyhproject/home2/view/default/img/icon_gouwuche.png b/hyhproject/home2/view/default/img/icon_gouwuche.png new file mode 100755 index 0000000..495f55c Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_gouwuche.png differ diff --git a/hyhproject/home2/view/default/img/icon_hdfk.png b/hyhproject/home2/view/default/img/icon_hdfk.png new file mode 100755 index 0000000..11fdc44 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_hdfk.png differ diff --git a/hyhproject/home2/view/default/img/icon_jinggao.png b/hyhproject/home2/view/default/img/icon_jinggao.png new file mode 100755 index 0000000..3f2b36a Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_jinggao.png differ diff --git a/hyhproject/home2/view/default/img/icon_left.png b/hyhproject/home2/view/default/img/icon_left.png new file mode 100755 index 0000000..22897ff Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_left.png differ diff --git a/hyhproject/home2/view/default/img/icon_login.png b/hyhproject/home2/view/default/img/icon_login.png new file mode 100755 index 0000000..265f6aa Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_login.png differ diff --git a/hyhproject/home2/view/default/img/icon_login02.png b/hyhproject/home2/view/default/img/icon_login02.png new file mode 100755 index 0000000..755d8c9 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_login02.png differ diff --git a/hyhproject/home2/view/default/img/icon_mfps.png b/hyhproject/home2/view/default/img/icon_mfps.png new file mode 100755 index 0000000..8774cc5 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_mfps.png differ diff --git a/hyhproject/home2/view/default/img/icon_name.png b/hyhproject/home2/view/default/img/icon_name.png new file mode 100755 index 0000000..e8a1401 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_name.png differ diff --git a/hyhproject/home2/view/default/img/icon_name2.png b/hyhproject/home2/view/default/img/icon_name2.png new file mode 100755 index 0000000..088746f Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_name2.png differ diff --git a/hyhproject/home2/view/default/img/icon_no.png b/hyhproject/home2/view/default/img/icon_no.png new file mode 100755 index 0000000..6607b82 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_no.png differ diff --git a/hyhproject/home2/view/default/img/icon_number.png b/hyhproject/home2/view/default/img/icon_number.png new file mode 100755 index 0000000..329f881 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_number.png differ diff --git a/hyhproject/home2/view/default/img/icon_passard.png b/hyhproject/home2/view/default/img/icon_passard.png new file mode 100755 index 0000000..c69523a Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_passard.png differ diff --git a/hyhproject/home2/view/default/img/icon_passard2.png b/hyhproject/home2/view/default/img/icon_passard2.png new file mode 100755 index 0000000..a3c5328 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_passard2.png differ diff --git a/hyhproject/home2/view/default/img/icon_play.png b/hyhproject/home2/view/default/img/icon_play.png new file mode 100755 index 0000000..53372aa Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_play.png differ diff --git a/hyhproject/home2/view/default/img/icon_qianbaoyue.png b/hyhproject/home2/view/default/img/icon_qianbaoyue.png new file mode 100755 index 0000000..30d0e68 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_qianbaoyue.png differ diff --git a/hyhproject/home2/view/default/img/icon_register.png b/hyhproject/home2/view/default/img/icon_register.png new file mode 100755 index 0000000..4a92814 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_register.png differ diff --git a/hyhproject/home2/view/default/img/icon_right.png b/hyhproject/home2/view/default/img/icon_right.png new file mode 100755 index 0000000..c733472 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_right.png differ diff --git a/hyhproject/home2/view/default/img/icon_sidernemu.png b/hyhproject/home2/view/default/img/icon_sidernemu.png new file mode 100755 index 0000000..dbef865 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_sidernemu.png differ diff --git a/hyhproject/home2/view/default/img/icon_success.png b/hyhproject/home2/view/default/img/icon_success.png new file mode 100755 index 0000000..d678e43 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_success.png differ diff --git a/hyhproject/home2/view/default/img/icon_thwy.png b/hyhproject/home2/view/default/img/icon_thwy.png new file mode 100755 index 0000000..0e1ff6e Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_thwy.png differ diff --git a/hyhproject/home2/view/default/img/icon_time.png b/hyhproject/home2/view/default/img/icon_time.png new file mode 100755 index 0000000..ede463e Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_time.png differ diff --git a/hyhproject/home2/view/default/img/icon_tstb.png b/hyhproject/home2/view/default/img/icon_tstb.png new file mode 100755 index 0000000..4a5aff3 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_tstb.png differ diff --git a/hyhproject/home2/view/default/img/icon_wyz.png b/hyhproject/home2/view/default/img/icon_wyz.png new file mode 100755 index 0000000..2cbd084 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_wyz.png differ diff --git a/hyhproject/home2/view/default/img/icon_yanzhengma.png b/hyhproject/home2/view/default/img/icon_yanzhengma.png new file mode 100755 index 0000000..74ee520 Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_yanzhengma.png differ diff --git a/hyhproject/home2/view/default/img/icon_yanzhengma5.png b/hyhproject/home2/view/default/img/icon_yanzhengma5.png new file mode 100755 index 0000000..bcccdef Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_yanzhengma5.png differ diff --git a/hyhproject/home2/view/default/img/icon_zhengpin.png b/hyhproject/home2/view/default/img/icon_zhengpin.png new file mode 100755 index 0000000..23f692d Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_zhengpin.png differ diff --git a/hyhproject/home2/view/default/img/icon_zixun.png b/hyhproject/home2/view/default/img/icon_zixun.png new file mode 100755 index 0000000..679385a Binary files /dev/null and b/hyhproject/home2/view/default/img/icon_zixun.png differ diff --git a/hyhproject/home2/view/default/img/iconfont_fotter.png b/hyhproject/home2/view/default/img/iconfont_fotter.png new file mode 100755 index 0000000..47f8092 Binary files /dev/null and b/hyhproject/home2/view/default/img/iconfont_fotter.png differ diff --git a/hyhproject/home2/view/default/img/iconfont_guanzhu_nor.png b/hyhproject/home2/view/default/img/iconfont_guanzhu_nor.png new file mode 100755 index 0000000..d745042 Binary files /dev/null and b/hyhproject/home2/view/default/img/iconfont_guanzhu_nor.png differ diff --git a/hyhproject/home2/view/default/img/iconfont_guanzhu_sel.png b/hyhproject/home2/view/default/img/iconfont_guanzhu_sel.png new file mode 100755 index 0000000..3158d26 Binary files /dev/null and b/hyhproject/home2/view/default/img/iconfont_guanzhu_sel.png differ diff --git a/hyhproject/home2/view/default/img/img_bg_dlzc.png b/hyhproject/home2/view/default/img/img_bg_dlzc.png new file mode 100755 index 0000000..64398bc Binary files /dev/null and b/hyhproject/home2/view/default/img/img_bg_dlzc.png differ diff --git a/hyhproject/home2/view/default/img/img_bg_goodslist_tjrm.png b/hyhproject/home2/view/default/img/img_bg_goodslist_tjrm.png new file mode 100755 index 0000000..0c8471c Binary files /dev/null and b/hyhproject/home2/view/default/img/img_bg_goodslist_tjrm.png differ diff --git a/hyhproject/home2/view/default/img/img_bg_search.png b/hyhproject/home2/view/default/img/img_bg_search.png new file mode 100755 index 0000000..de9e23a Binary files /dev/null and b/hyhproject/home2/view/default/img/img_bg_search.png differ diff --git a/hyhproject/home2/view/default/img/img_bg_xiala.png b/hyhproject/home2/view/default/img/img_bg_xiala.png new file mode 100755 index 0000000..2120132 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_bg_xiala.png differ diff --git a/hyhproject/home2/view/default/img/img_bg_xpjssel.png b/hyhproject/home2/view/default/img/img_bg_xpjssel.png new file mode 100755 index 0000000..12a6ca1 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_bg_xpjssel.png differ diff --git a/hyhproject/home2/view/default/img/img_cart_bg.png b/hyhproject/home2/view/default/img/img_cart_bg.png new file mode 100755 index 0000000..7a52eeb Binary files /dev/null and b/hyhproject/home2/view/default/img/img_cart_bg.png differ diff --git a/hyhproject/home2/view/default/img/img_dztj_bg.png b/hyhproject/home2/view/default/img/img_dztj_bg.png new file mode 100755 index 0000000..a7556ff Binary files /dev/null and b/hyhproject/home2/view/default/img/img_dztj_bg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor10_titlebg.png b/hyhproject/home2/view/default/img/img_floor10_titlebg.png new file mode 100755 index 0000000..55fb9ba Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor10_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor1_titlebg.png b/hyhproject/home2/view/default/img/img_floor1_titlebg.png new file mode 100755 index 0000000..a104d90 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor1_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor2_titlebg.png b/hyhproject/home2/view/default/img/img_floor2_titlebg.png new file mode 100755 index 0000000..121be83 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor2_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor3_titlebg.png b/hyhproject/home2/view/default/img/img_floor3_titlebg.png new file mode 100755 index 0000000..76970c8 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor3_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor4_titlebg.png b/hyhproject/home2/view/default/img/img_floor4_titlebg.png new file mode 100755 index 0000000..90f5ea0 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor4_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor5_titlebg.png b/hyhproject/home2/view/default/img/img_floor5_titlebg.png new file mode 100755 index 0000000..d7ebbfd Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor5_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor6_titlebg.png b/hyhproject/home2/view/default/img/img_floor6_titlebg.png new file mode 100755 index 0000000..c9c8904 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor6_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor7_titlebg.png b/hyhproject/home2/view/default/img/img_floor7_titlebg.png new file mode 100755 index 0000000..042ade3 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor7_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor8_titlebg.png b/hyhproject/home2/view/default/img/img_floor8_titlebg.png new file mode 100755 index 0000000..32d192c Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor8_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor9_titlebg.png b/hyhproject/home2/view/default/img/img_floor9_titlebg.png new file mode 100755 index 0000000..0da98cf Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor9_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_floor_titlebg.png b/hyhproject/home2/view/default/img/img_floor_titlebg.png new file mode 100755 index 0000000..a8ce603 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_floor_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_gd_sel.png b/hyhproject/home2/view/default/img/img_gd_sel.png new file mode 100755 index 0000000..a3422a4 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_gd_sel.png differ diff --git a/hyhproject/home2/view/default/img/img_icon.png b/hyhproject/home2/view/default/img/img_icon.png new file mode 100755 index 0000000..5fbd592 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_icon.png differ diff --git a/hyhproject/home2/view/default/img/img_jrpp.png b/hyhproject/home2/view/default/img/img_jrpp.png new file mode 100755 index 0000000..2e55e10 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_jrpp.png differ diff --git a/hyhproject/home2/view/default/img/img_login01.png b/hyhproject/home2/view/default/img/img_login01.png new file mode 100755 index 0000000..41e5ce0 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_login01.png differ diff --git a/hyhproject/home2/view/default/img/img_logintitle_bg.png b/hyhproject/home2/view/default/img/img_logintitle_bg.png new file mode 100755 index 0000000..9e3397f Binary files /dev/null and b/hyhproject/home2/view/default/img/img_logintitle_bg.png differ diff --git a/hyhproject/home2/view/default/img/img_majz_titlebg.png b/hyhproject/home2/view/default/img/img_majz_titlebg.png new file mode 100755 index 0000000..8f5f1da Binary files /dev/null and b/hyhproject/home2/view/default/img/img_majz_titlebg.png differ diff --git a/hyhproject/home2/view/default/img/img_mrtx_yh.png b/hyhproject/home2/view/default/img/img_mrtx_yh.png new file mode 100755 index 0000000..5f95121 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_mrtx_yh.png differ diff --git a/hyhproject/home2/view/default/img/img_openshop_bg.png b/hyhproject/home2/view/default/img/img_openshop_bg.png new file mode 100755 index 0000000..2c854c8 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_openshop_bg.png differ diff --git a/hyhproject/home2/view/default/img/img_regist.png b/hyhproject/home2/view/default/img/img_regist.png new file mode 100755 index 0000000..9239b4e Binary files /dev/null and b/hyhproject/home2/view/default/img/img_regist.png differ diff --git a/hyhproject/home2/view/default/img/img_register_main_bg.jpg b/hyhproject/home2/view/default/img/img_register_main_bg.jpg new file mode 100755 index 0000000..c3d9cf3 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_register_main_bg.jpg differ diff --git a/hyhproject/home2/view/default/img/img_scdp.png b/hyhproject/home2/view/default/img/img_scdp.png new file mode 100755 index 0000000..d45d601 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_scdp.png differ diff --git a/hyhproject/home2/view/default/img/img_seller_ggjt.png b/hyhproject/home2/view/default/img/img_seller_ggjt.png new file mode 100755 index 0000000..7edd87e Binary files /dev/null and b/hyhproject/home2/view/default/img/img_seller_ggjt.png differ diff --git a/hyhproject/home2/view/default/img/img_shop.png b/hyhproject/home2/view/default/img/img_shop.png new file mode 100755 index 0000000..f5e7cb0 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_shop.png differ diff --git a/hyhproject/home2/view/default/img/img_sjck.png b/hyhproject/home2/view/default/img/img_sjck.png new file mode 100755 index 0000000..8e10870 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_sjck.png differ diff --git a/hyhproject/home2/view/default/img/img_top_list.png b/hyhproject/home2/view/default/img/img_top_list.png new file mode 100755 index 0000000..91c63d6 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_top_list.png differ diff --git a/hyhproject/home2/view/default/img/img_user.png b/hyhproject/home2/view/default/img/img_user.png new file mode 100755 index 0000000..8f5c47c Binary files /dev/null and b/hyhproject/home2/view/default/img/img_user.png differ diff --git a/hyhproject/home2/view/default/img/img_userlogin_left.png b/hyhproject/home2/view/default/img/img_userlogin_left.png new file mode 100755 index 0000000..5bbd3be Binary files /dev/null and b/hyhproject/home2/view/default/img/img_userlogin_left.png differ diff --git a/hyhproject/home2/view/default/img/img_yingyin.png b/hyhproject/home2/view/default/img/img_yingyin.png new file mode 100755 index 0000000..0b1b581 Binary files /dev/null and b/hyhproject/home2/view/default/img/img_yingyin.png differ diff --git a/hyhproject/home2/view/default/img/index_distribute_bg.png b/hyhproject/home2/view/default/img/index_distribute_bg.png new file mode 100755 index 0000000..eae59ba Binary files /dev/null and b/hyhproject/home2/view/default/img/index_distribute_bg.png differ diff --git a/hyhproject/home2/view/default/img/index_distribute_price_bg.png b/hyhproject/home2/view/default/img/index_distribute_price_bg.png new file mode 100755 index 0000000..039bcaa Binary files /dev/null and b/hyhproject/home2/view/default/img/index_distribute_price_bg.png differ diff --git a/hyhproject/home2/view/default/img/index_link_bg.png b/hyhproject/home2/view/default/img/index_link_bg.png new file mode 100755 index 0000000..53dad80 Binary files /dev/null and b/hyhproject/home2/view/default/img/index_link_bg.png differ diff --git a/hyhproject/home2/view/default/img/integral_bg.png b/hyhproject/home2/view/default/img/integral_bg.png new file mode 100755 index 0000000..414901f Binary files /dev/null and b/hyhproject/home2/view/default/img/integral_bg.png differ diff --git a/hyhproject/home2/view/default/img/intro-bg.png b/hyhproject/home2/view/default/img/intro-bg.png new file mode 100755 index 0000000..0102e2d Binary files /dev/null and b/hyhproject/home2/view/default/img/intro-bg.png differ diff --git a/hyhproject/home2/view/default/img/loading.gif b/hyhproject/home2/view/default/img/loading.gif new file mode 100755 index 0000000..e8c2892 Binary files /dev/null and b/hyhproject/home2/view/default/img/loading.gif differ diff --git a/hyhproject/home2/view/default/img/logo_10.png b/hyhproject/home2/view/default/img/logo_10.png new file mode 100755 index 0000000..d567ae2 Binary files /dev/null and b/hyhproject/home2/view/default/img/logo_10.png differ diff --git a/hyhproject/home2/view/default/img/member_pics.png b/hyhproject/home2/view/default/img/member_pics.png new file mode 100755 index 0000000..7958e78 Binary files /dev/null and b/hyhproject/home2/view/default/img/member_pics.png differ diff --git a/hyhproject/home2/view/default/img/nocite_deliver.png b/hyhproject/home2/view/default/img/nocite_deliver.png new file mode 100755 index 0000000..da071f1 Binary files /dev/null and b/hyhproject/home2/view/default/img/nocite_deliver.png differ diff --git a/hyhproject/home2/view/default/img/notice.png b/hyhproject/home2/view/default/img/notice.png new file mode 100755 index 0000000..0ff0965 Binary files /dev/null and b/hyhproject/home2/view/default/img/notice.png differ diff --git a/hyhproject/home2/view/default/img/order_source_1.png b/hyhproject/home2/view/default/img/order_source_1.png new file mode 100755 index 0000000..4b4cacd Binary files /dev/null and b/hyhproject/home2/view/default/img/order_source_1.png differ diff --git a/hyhproject/home2/view/default/img/order_source_2.png b/hyhproject/home2/view/default/img/order_source_2.png new file mode 100755 index 0000000..d7aa4ad Binary files /dev/null and b/hyhproject/home2/view/default/img/order_source_2.png differ diff --git a/hyhproject/home2/view/default/img/order_source_3.png b/hyhproject/home2/view/default/img/order_source_3.png new file mode 100755 index 0000000..d8803fd Binary files /dev/null and b/hyhproject/home2/view/default/img/order_source_3.png differ diff --git a/hyhproject/home2/view/default/img/order_source_4.png b/hyhproject/home2/view/default/img/order_source_4.png new file mode 100755 index 0000000..f83a077 Binary files /dev/null and b/hyhproject/home2/view/default/img/order_source_4.png differ diff --git a/hyhproject/home2/view/default/img/order_source_5.png b/hyhproject/home2/view/default/img/order_source_5.png new file mode 100755 index 0000000..a4f184d Binary files /dev/null and b/hyhproject/home2/view/default/img/order_source_5.png differ diff --git a/hyhproject/home2/view/default/img/pay_caifutong.png b/hyhproject/home2/view/default/img/pay_caifutong.png new file mode 100755 index 0000000..5c676fd Binary files /dev/null and b/hyhproject/home2/view/default/img/pay_caifutong.png differ diff --git a/hyhproject/home2/view/default/img/pay_liucheng.png b/hyhproject/home2/view/default/img/pay_liucheng.png new file mode 100755 index 0000000..69c422e Binary files /dev/null and b/hyhproject/home2/view/default/img/pay_liucheng.png differ diff --git a/hyhproject/home2/view/default/img/pay_wangyin.png b/hyhproject/home2/view/default/img/pay_wangyin.png new file mode 100755 index 0000000..3283863 Binary files /dev/null and b/hyhproject/home2/view/default/img/pay_wangyin.png differ diff --git a/hyhproject/home2/view/default/img/right_cart.png b/hyhproject/home2/view/default/img/right_cart.png new file mode 100755 index 0000000..b4e113e Binary files /dev/null and b/hyhproject/home2/view/default/img/right_cart.png differ diff --git a/hyhproject/home2/view/default/img/screenshot.png b/hyhproject/home2/view/default/img/screenshot.png new file mode 100755 index 0000000..539c26c Binary files /dev/null and b/hyhproject/home2/view/default/img/screenshot.png differ diff --git a/hyhproject/home2/view/default/img/search.png b/hyhproject/home2/view/default/img/search.png new file mode 100755 index 0000000..d13842e Binary files /dev/null and b/hyhproject/home2/view/default/img/search.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f1_bg.png b/hyhproject/home2/view/default/img/self_shop_f1_bg.png new file mode 100755 index 0000000..9282fe9 Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f1_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f2_bg.png b/hyhproject/home2/view/default/img/self_shop_f2_bg.png new file mode 100755 index 0000000..4452449 Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f2_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f3_bg.png b/hyhproject/home2/view/default/img/self_shop_f3_bg.png new file mode 100755 index 0000000..eb80200 Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f3_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f4_bg.png b/hyhproject/home2/view/default/img/self_shop_f4_bg.png new file mode 100755 index 0000000..eb577c3 Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f4_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f5_bg.png b/hyhproject/home2/view/default/img/self_shop_f5_bg.png new file mode 100755 index 0000000..5d600b6 Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f5_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_f6_bg.png b/hyhproject/home2/view/default/img/self_shop_f6_bg.png new file mode 100755 index 0000000..a9b1b1d Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_f6_bg.png differ diff --git a/hyhproject/home2/view/default/img/self_shop_rec_bg.png b/hyhproject/home2/view/default/img/self_shop_rec_bg.png new file mode 100755 index 0000000..718af8d Binary files /dev/null and b/hyhproject/home2/view/default/img/self_shop_rec_bg.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_cz.png b/hyhproject/home2/view/default/img/seller_icon_cz.png new file mode 100755 index 0000000..8dd48d1 Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_cz.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_error.png b/hyhproject/home2/view/default/img/seller_icon_error.png new file mode 100755 index 0000000..738d0a4 Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_error.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_pf_nor.png b/hyhproject/home2/view/default/img/seller_icon_pf_nor.png new file mode 100755 index 0000000..60f2670 Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_pf_nor.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_pf_sel.png b/hyhproject/home2/view/default/img/seller_icon_pf_sel.png new file mode 100755 index 0000000..ba3197c Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_pf_sel.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_right.png b/hyhproject/home2/view/default/img/seller_icon_right.png new file mode 100755 index 0000000..9267e8b Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_right.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_sq.png b/hyhproject/home2/view/default/img/seller_icon_sq.png new file mode 100755 index 0000000..0f1ab7a Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_sq.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_xz.png b/hyhproject/home2/view/default/img/seller_icon_xz.png new file mode 100755 index 0000000..c4a9afd Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_xz.png differ diff --git a/hyhproject/home2/view/default/img/seller_icon_zk.png b/hyhproject/home2/view/default/img/seller_icon_zk.png new file mode 100755 index 0000000..e4fcb79 Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_icon_zk.png differ diff --git a/hyhproject/home2/view/default/img/seller_img_bgnav.png b/hyhproject/home2/view/default/img/seller_img_bgnav.png new file mode 100755 index 0000000..a69de99 Binary files /dev/null and b/hyhproject/home2/view/default/img/seller_img_bgnav.png differ diff --git a/hyhproject/home2/view/default/img/shop_item_bg.jpg b/hyhproject/home2/view/default/img/shop_item_bg.jpg new file mode 100755 index 0000000..2e78c27 Binary files /dev/null and b/hyhproject/home2/view/default/img/shop_item_bg.jpg differ diff --git a/hyhproject/home2/view/default/img/shop_street_bg.png b/hyhproject/home2/view/default/img/shop_street_bg.png new file mode 100755 index 0000000..edcf89f Binary files /dev/null and b/hyhproject/home2/view/default/img/shop_street_bg.png differ diff --git a/hyhproject/home2/view/default/img/shopstreet_bg.png b/hyhproject/home2/view/default/img/shopstreet_bg.png new file mode 100755 index 0000000..a189b2f Binary files /dev/null and b/hyhproject/home2/view/default/img/shopstreet_bg.png differ diff --git a/hyhproject/home2/view/default/img/sprite@1x.png b/hyhproject/home2/view/default/img/sprite@1x.png new file mode 100755 index 0000000..fa7f4eb Binary files /dev/null and b/hyhproject/home2/view/default/img/sprite@1x.png differ diff --git a/hyhproject/home2/view/default/img/star.png b/hyhproject/home2/view/default/img/star.png new file mode 100755 index 0000000..b6046b7 Binary files /dev/null and b/hyhproject/home2/view/default/img/star.png differ diff --git a/hyhproject/home2/view/default/img/store_icon_sq.png b/hyhproject/home2/view/default/img/store_icon_sq.png new file mode 100755 index 0000000..e8e8242 Binary files /dev/null and b/hyhproject/home2/view/default/img/store_icon_sq.png differ diff --git a/hyhproject/home2/view/default/img/store_icon_sx.png b/hyhproject/home2/view/default/img/store_icon_sx.png new file mode 100755 index 0000000..eeb4904 Binary files /dev/null and b/hyhproject/home2/view/default/img/store_icon_sx.png differ diff --git a/hyhproject/home2/view/default/img/store_icon_sx_sel.png b/hyhproject/home2/view/default/img/store_icon_sx_sel.png new file mode 100755 index 0000000..c603065 Binary files /dev/null and b/hyhproject/home2/view/default/img/store_icon_sx_sel.png differ diff --git a/hyhproject/home2/view/default/img/store_icon_sx_sel_up.png b/hyhproject/home2/view/default/img/store_icon_sx_sel_up.png new file mode 100755 index 0000000..a8ce6de Binary files /dev/null and b/hyhproject/home2/view/default/img/store_icon_sx_sel_up.png differ diff --git a/hyhproject/home2/view/default/img/store_icon_zk.png b/hyhproject/home2/view/default/img/store_icon_zk.png new file mode 100755 index 0000000..f62902a Binary files /dev/null and b/hyhproject/home2/view/default/img/store_icon_zk.png differ diff --git a/hyhproject/home2/view/default/img/top_icon_cartdown.png b/hyhproject/home2/view/default/img/top_icon_cartdown.png new file mode 100755 index 0000000..0d98d5c Binary files /dev/null and b/hyhproject/home2/view/default/img/top_icon_cartdown.png differ diff --git a/hyhproject/home2/view/default/img/unionpays.png b/hyhproject/home2/view/default/img/unionpays.png new file mode 100755 index 0000000..4078b7a Binary files /dev/null and b/hyhproject/home2/view/default/img/unionpays.png differ diff --git a/hyhproject/home2/view/default/img/user_bg_nav.png b/hyhproject/home2/view/default/img/user_bg_nav.png new file mode 100755 index 0000000..96fc790 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_bg_nav.png differ diff --git a/hyhproject/home2/view/default/img/user_btn_search.png b/hyhproject/home2/view/default/img/user_btn_search.png new file mode 100755 index 0000000..e003c92 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_btn_search.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_cart.png b/hyhproject/home2/view/default/img/user_icon_cart.png new file mode 100755 index 0000000..e7bf631 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_cart.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_hyp.png b/hyhproject/home2/view/default/img/user_icon_hyp.png new file mode 100755 index 0000000..05821a2 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_hyp.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_info.png b/hyhproject/home2/view/default/img/user_icon_info.png new file mode 100755 index 0000000..edc3269 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_info.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_num.png b/hyhproject/home2/view/default/img/user_icon_num.png new file mode 100755 index 0000000..f9cd159 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_num.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_rzxx.png b/hyhproject/home2/view/default/img/user_icon_rzxx.png new file mode 100755 index 0000000..872cfa4 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_rzxx.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_sider_zhankai.png b/hyhproject/home2/view/default/img/user_icon_sider_zhankai.png new file mode 100755 index 0000000..abc1e52 Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_sider_zhankai.png differ diff --git a/hyhproject/home2/view/default/img/user_icon_yyz.png b/hyhproject/home2/view/default/img/user_icon_yyz.png new file mode 100755 index 0000000..c019bde Binary files /dev/null and b/hyhproject/home2/view/default/img/user_icon_yyz.png differ diff --git a/hyhproject/home2/view/default/img/wallets.png b/hyhproject/home2/view/default/img/wallets.png new file mode 100755 index 0000000..e5cb027 Binary files /dev/null and b/hyhproject/home2/view/default/img/wallets.png differ diff --git a/hyhproject/home2/view/default/img/weixinpays.png b/hyhproject/home2/view/default/img/weixinpays.png new file mode 100755 index 0000000..74119ac Binary files /dev/null and b/hyhproject/home2/view/default/img/weixinpays.png differ diff --git a/hyhproject/home2/view/default/img/wst_qr_code.jpg b/hyhproject/home2/view/default/img/wst_qr_code.jpg new file mode 100755 index 0000000..340ba48 Binary files /dev/null and b/hyhproject/home2/view/default/img/wst_qr_code.jpg differ diff --git a/hyhproject/home2/view/default/img/┤Є╣│.png b/hyhproject/home2/view/default/img/┤Є╣│.png new file mode 100755 index 0000000..323ac24 Binary files /dev/null and b/hyhproject/home2/view/default/img/┤Є╣│.png differ diff --git a/hyhproject/home2/view/default/img/鈹ば勨暎鈹_png b/hyhproject/home2/view/default/img/鈹ば勨暎鈹_png new file mode 100755 index 0000000..323ac24 Binary files /dev/null and b/hyhproject/home2/view/default/img/鈹ば勨暎鈹_png differ diff --git a/hyhproject/home2/view/default/index.html b/hyhproject/home2/view/default/index.html new file mode 100755 index 0000000..83d537f --- /dev/null +++ b/hyhproject/home2/view/default/index.html @@ -0,0 +1,792 @@ +{extend name="default/base" /} +{block name="title"}{:WSTConf('CONF.mallName')} - {:WSTConf('CONF.mallSlogan')}{__block__}{/block} +{block name="meta"} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')}"> +<meta name="Keywords" content="{:WSTConf('CONF.seoMallKeywords')}"> +{/block} +{block name="css"} +<link href="__STYLE__/css/index.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +{/* 横栏广告 */} +<div class="wst-ads" style="position:relative;" > + <div class="wst-slide" id="wst-slide"> + + <ul class="wst-slide-items"> + {wst:ads code="ads-index" cache='86400'} + <a href="{$vo.adURL}" {if ($vo['isOpen'])}target='_blank'{/if} {if ($vo['adURL']!='')}onclick="WST.recordClick({$vo['adId']})"{/if}><li style="background: url(__IMGURL__/{$vo.adFile}) no-repeat scroll center top;background-size:cover;" ></li></a> + {/wst:ads} + </ul> + <div class="wst-slide-numbox"> + <div style="position:absolute;right:0;top:-420px;"> + <div class='wst-right-panel' {if !isset($hideCategory)}style="display:none;" {/if}> + {php}$signScore=explode(",",WSTConf('CONF.signScore'));{/php} + {if(WSTConf('CONF.signScoreSwitch')==1 && $signScore[0]>0)} + <div class="ws-right-user"> + <div class="top"> + <img class="usersImg" data-original="__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}"> + <div class="name"> + <a href="{:Url('home/users/index')}"><p class="uname">{if condition="session('WST_USER.userId') >0"}{:session('WST_USER.userName')?session('WST_USER.userName'):session('WST_USER.loginName')}{else}请先登录{/if}</p></a> + {if(session('WST_USER.signScoreTime')==date('Y-m-d'))} + <button id="j-sign" class="sign actives"><i class="plus">+</i>已签到</button> + {else} + <button id="j-sign" class="sign" onclick="javascript:inSign();"><i class="plus">+</i>签到领积分</button> + {/if} + </div> + </div> + <div class="bottom"> + <p class="left">当前积分:<span id="currentScore">{if condition="session('WST_USER.userId') >0"}{:session('WST_USER.userScore')}{else}0{/if}</span></p><p class="right"><a href="{:Url('home/userscores/index')}" onclick="WST.position(13,0)">积分明细</a></p> + </div> + <div class="wst-clear"></div> + </div> + {/if} + {/* 拍卖活动 */} + <div id="wst-right-ads"> + {if(WSTConf('WST_ADDONS.auction')!='') && count(auction_list())>0} + {php}$auction=auction_list();{/php} + <div class="aution_out"> + <p class="aution_tit">拍卖活动</p> + <div class="aution_list" sc="{:date('Y-m-d H:i:s')}"> + {volist name="$auction" id="au"} + <div class="aution_main" sv="{$au['startTime']}" ev="{$au['endTime']}"> + <a class="aution_item" target='_blank' href="{:addon_url('auction://goods/detail','id='.$au['auctionId'])}"> + <img title="{$au['goodsName']}" alt="{$au['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$au['goodsImg']}"/> + <div class="aution_time"> + 距离结束: + <span class="aution_h">12</span> + : + <span class="aution_i">23</span> + : + <span class="aution_s">55</span> + </div> + </a> + </div> + {/volist} + <div class="wst-clear"></div> + </div> + <span class="au_l_btn"><</span> + <span class="au_r_btn">></span> + </div> + {else /} + {wst:ads code="index-art" num='1' cache='86400'} + <a {if ($vo['isOpen'])}target='_blank'{/if} {if ($vo['adURL']!='')}onclick="WST.recordClick({$vo['adId']})"{/if} href="{$vo.adURL}" onfocus="this.blur()"> + <img data-original="__IMGURL__/{$vo.adFile}" class="goodsImg" /> + </a> + {/wst:ads} + {/if} + <div class="index-user-tab"> + <div id='index-tab' class="wst-tab-box"> + + <div class="wst-tab-nav"> + {if empty($is_icp)} <div class="tab">招商入驻</div> {/if} + <div class="tab">商城快讯</div> + </div> + <div class="wst-tab-content" style='width:99%;'> + {if empty($is_icp)} + <div class="wst-tab-item" style="position: relative;"> + <a class='apply-btn' target='_blank' href='{:Url("home/shops/join")}' onclick="WST.currentUrl('{:url("home/shops/join")}');"></a> + <a class='shop-login' href='{:Url("home/shops/login")}' onclick="WST.currentUrl();">登录商家中心</a> + </div> + {/if} + <div class="wst-tab-item" style="position: relative;"><!-- display:none --> + <div id="wst-right-new-list"{if(!session('WST_USER.userId'))}class="visitor-new-list"{/if} > + {wst:article cat="new" num='5' cache='86400'} + <div><a href="{:url('home/news/view',['id'=>$vo['articleId']])}">{if !empty($is_icp)}[付费查看]{/if}{$vo['articleTitle']}</a></div> + {/wst:article} + </div> + </div> + + </div> + </div> + </div> + + <span class="wst-clear"></span> + </div> + </div> + </div> + <div class="wst-slide-controls"> + {wst:ads code="ads-index" cache='86400' key='k'} + {if condition="$k+1 eq 1"} + <span class="curr">{$k+1}</span> + {else/} + <span class="">{$k+1}</span> + {/if} + {/wst:ads} + </div> + </div> + </div> +</div> +{/* 顶部广告位 */} +<div class='wst-main'> + {/* 领券中心 */} + + {if empty($is_icp)} + {if empty($indexCouponsList)} + {php}$indexCouponsList=coupon_list('',['s.shopImg'],4);{/php} + {/if} + {if !empty($indexCouponsList)} + <div class="coupon_out"> + <a href="{:addon_url('coupon://coupons/index')}" class="fl coupon_bg"> + <p class="coupon_tit">领券中心</p> + <p class="coupon_desc">为您汇总所有优惠券</p> + <p class="r_btn">立即查看</p> + <img src="__STYLE__/img/coupon_bg.png" alt="" /> + </a> + <div style="float:right;width: 76%;height: 124px"> + {volist name="$indexCouponsList" id="cn" length="4"} + <!--//修复首页不能领取优惠券,20080207 make cheng + <a href="{:addon_url('coupon://coupons/index')}" class="fl coupon_item"> + --> + <a href="#" class="fl coupon_item"> + <img onclick="window.location.href='{:url('home/shops/home',['shopId'=>$cn.shopId])}'" src="__IMGURL__/{$cn.shopImg}" alt="" style=" + position: absolute; + width: 70px; + height: 70px; + left:8px; + top: 30px;" /> + <p class="coupon_tit coupon_item_color">¥{$cn['couponValue']}</p> + <p class="coupon_desc coupon_item_color f16"> + {if $cn['useCondition']==1} + 满{$cn['useMoney']}减{$cn['couponValue']} + {else /} + 无门槛券 + {/if} + </p> + <p class="r_btn" onclick="receiveCoupon({$cn['couponId']})">立即领取</p> + <img src="__STYLE__/img/coupon_item_bg.png" alt="" /> + </a> + {/volist} + </div> + <div class="wst-clear"></div> + </div> + {/if} + {/if} + {/* 广告墙 */} + <div class="ads_wall"> + <div class="ads_wall_l fl"> + {/* 左上 */} + {wst:ads code="wall-left-top" num='1' cache='86400' id="aw"} + <a {if ($aw['isOpen'])}target='_blank'{/if} {if ($aw['adURL']!='')}onclick="WST.recordClick({$aw['adId']})"{/if} href="{$aw.adURL}" onfocus="this.blur()" class="ads_wall_item_top"> + <img data-original="__IMGURL__/{$aw.adFile}" class="goodsImg" /> + <div class="ads_wall_more"> + <div class="ads_wall_line fl"></div> + <p class="fl">查看更多 >></p> + <div class="wst-clear"></div> + </div> + </a> + {/wst:ads} + {/* 左下 */} + {wst:ads code="wall-left-bottom" num='1' cache='86400' id="aw"} + <a {if ($aw['isOpen'])}target='_blank'{/if} {if ($aw['adURL']!='')}onclick="WST.recordClick({$aw['adId']})"{/if} href="{$aw.adURL}" onfocus="this.blur()" class="ads_wall_item_bottom"> + <img data-original="__IMGURL__/{$aw.adFile}" class="goodsImg" /> + <div class="ads_wall_more"> + <div class="ads_wall_line fl"></div> + <p class="fl">查看更多 >></p> + <div class="wst-clear"></div> + </div> + </a> + {/wst:ads} + </div> + <div class="ads_wall_c fl"> + {/* 中间 */} + {wst:ads code="wall-center" num='1' cache='86400' id="aw"} + <a {if ($aw['isOpen'])}target='_blank'{/if} {if ($aw['adURL']!='')}onclick="WST.recordClick({$aw['adId']})"{/if} href="{$aw.adURL}" onfocus="this.blur()"> + <img data-original="__IMGURL__/{$aw.adFile}" class="goodsImg" /> + <div class="ads_wall_more" style="left:0;right:0;"> + <p>查看更多 >></p> + </div> + </a> + {/wst:ads} + </div> + <div class="ads_wall_r fr"> + {/* 右上 */} + {wst:ads code="wall-right-top" num='1' cache='86400' id="aw"} + <a {if ($aw['isOpen'])}target='_blank'{/if} {if ($aw['adURL']!='')}onclick="WST.recordClick({$aw['adId']})"{/if} href="{$aw.adURL}" onfocus="this.blur()" class="ads_wall_item_top"> + <img data-original="__IMGURL__/{$aw.adFile}" class="goodsImg" /> + <div class="ads_wall_more"> + <div class="ads_wall_line wall_r_line fl"></div> + <p class="fl">查看更多 >></p> + <div class="wst-clear"></div> + </div> + </a> + {/wst:ads} + {/* 右下 */} + {wst:ads code="wall-right-bottom" num='1' cache='86400' id="aw"} + <a {if ($aw['isOpen'])}target='_blank'{/if} {if ($aw['adURL']!='')}onclick="WST.recordClick({$aw['adId']})"{/if} href="{$aw.adURL}" onfocus="this.blur()" class="ads_wall_item_bottom"> + <img data-original="__IMGURL__/{$aw.adFile}" class="goodsImg" /> + <div class="ads_wall_more"> + <div class="ads_wall_line wall_r_line fl"></div> + <p class="fl">查看更多 >></p> + <div class="wst-clear"></div> + </div> + </a> + {/wst:ads} + </div> + <div class="wst-clear"></div> + </div> + <!-- 注释品牌街,make cheng 20180306 + {/* 品牌街 */} + <div class="brand_street_out"> + <p class="bs_tit">品牌街</p> + <ul class="brand_street"> + {wst:brand cat="0" num='20' id="brd"} + <li> + <a href="{:Url('home/goods/lists',['brand'=>$brd['brandId'],'cat'=>$brd['catId']])}"> + <img data-original="__ROOT__/{$brd.brandImg}" class="goodsImg" /> + </a> + </li> + {/wst:brand} + <div class="wst-clear"></div> + </ul> + </div> +--> + <!-- <div class="rec_area"> + <div class="ral fl"> + {if(WSTConf('WST_ADDONS.groupon')!='') && count(groupon_list())>0} + {php}$groupon=groupon_list();{/php} + <div class="ral_box"> + <a href="{:addon_url('groupon://goods/lists')}"> + <p class="ral_box_tit">爱上团购</p> + <div class="ral_line"></div> + <p class="ral_desc">尽享美好生活</p> + </a> + </div> + <img data-original="__STYLE__/img/groupon_bg.png" class="goodsImg" /> + <div class="groupon_list_out"> + <div class="groupon_view"> + <ul class="groupon_list"> + {volist name="$groupon" id="gn"} + <li> + <a href="{:addon_url('groupon://goods/detail','id='.$gn['grouponId'])}"> + <img data-original="__ROOT__/{$gn.goodsImg}" class="goodsImg" /> + </a> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + </div> + <div class="groupon_btns"> + {volist name="$groupon" id="gn" key="gn_k"} + <span {if($gn_k==1)}class="curr"{/if}></span> + {/volist} + <div class="wst-clear"></div> + </div> + </div> + {else /} + + {wst:ads code="rbnh-left-ads" num='1' cache='86400' id="rbnh"} + <a {if ($rbnh['isOpen'])}target='_blank'{/if} {if ($rbnh['adURL']!='')}onclick="WST.recordClick({$rbnh['adId']})"{/if} href="{$rbnh.adURL}" onfocus="this.blur()"> + <img data-original="__ROOT__/{$rbnh.adFile}" class="goodsImg" /> + </a> + {/wst:ads} + + {/if} + </div> + <div class="rac fl"> + <div class="rac_t"> + <p class="rac_t_tit">最新上架</p> + <ul class="rac_t_main"> + {wst:goods type="new" num='3' id="racb"} + <li> + <a class="rac_t_img" href="{:Url('home/goods/detail','id='.$racb['goodsId'])}"> + <img width="166" data-original="__ROOT__/{$racb.goodsImg}" class="goodsImg" /> + </a> + <a href="{:Url('home/goods/detail','id='.$racb['goodsId'])}"> + <div class="rac_t_info"> + <p class="c14_333 rac_gname">{$racb.goodsName}</p> + <p class="rac_price"> + <span class="f16 rac_price_color"> + <span class="f12">¥</span>{$racb.shopPrice} + </span> + &nbsp; + <span class="f14 c666 del_line"> + <span class="f10">¥</span>{$racb.marketPrice} + </span> + </p> + </div> + </a> + </li> + {/wst:goods} + <div class="wst-clear"></div> + </ul> + </div> + <div class="rac_b"> + <div class="rac_b_l fl"> + <p class="rac_b_tit">精品促销</p> + {wst:goods type="best" num='1' id="racb"} + <div class="rac_b_main rac_bg"> + <div class="rac_b_info"> + <p class="c14_333 mb10 rac_gname">{:WSTMSubStr($racb.goodsName,0,10,'utf-8')}</p> + <p class="c14_333 rac_desc">{:WSTMSubStr($racb.goodsTips,0,20,'utf-8')}</p> + </div> + <a href="{:Url('home/goods/detail','id='.$racb['goodsId'])}"> + <img width="132" height="150" data-original="__ROOT__/{$racb.goodsImg}" class="goodsImg" /> + </a> + </div> + {/wst:goods} + </div> + <div class="rac_b_r fr"> + <p class="rac_b_tit">热销商品</p> + {wst:goods type="hot" num='1' id="racb"} + <div class="rac_b_main"> + <div class="rac_b_info"> + <p class="c14_333 mb10 rac_gname">{:WSTMSubStr($racb.goodsName,0,10,'utf-8')}</p> + <p class="c14_333 rac_desc">{:WSTMSubStr($racb.goodsTips,0,20,'utf-8')} + </p> + </div> + <a href="{:Url('home/goods/detail','id='.$racb['goodsId'])}"> + <img width="132" height="150" data-original="__ROOT__/{$racb.goodsImg}" class="goodsImg" /> + </a> + </div> + {/wst:goods} + </div> + <div class="wst-clear"></div> + </div> + </div> + <div class="rar fr"> + <p class="rar_tit">推荐商品</p> + <div class="rar_glist"> + {wst:goods type="recom" num='2' id="racb"} + <a href="{:Url('home/goods/detail','id='.$racb['goodsId'])}" class="rar_gitem"> + <p class="rar_gname">{:WSTMSubStr($racb.goodsName,0,10,'utf-8')}</p> + <div class="rar_line"></div> + <p class="rar_gdesc">{:WSTMSubStr($racb.goodsTips,0,20,'utf-8')}</p> + <p class="rar_price"> + <span class="f16 rac_price_color"> + <span class="f12">¥</span>{$racb.shopPrice} + </span> + </p> + <div class="rar_img"> + <img data-original="__ROOT__/{$racb.goodsImg}" class="goodsImg" /> + </div> + </a> + {/wst:goods} + </div> + </div> + <div class="wst-clear"></div> + </div> --> + {/* 积分商城 */} + + {if(WSTConf('WST_ADDONS.integral')!='') && count(integral_list())>0} + {php}$integral=integral_list();{/php} + <div class="intergral_out"> + <p class="itl_tit">积分商城</p> + <div class="itl_main"> + <a href="{:addon_url('integral://goods/lists')}" class="itl_bg fl"> + <img src="__STYLE__/img/integral_bg.png" alt="" /> + </a> + {volist name="$integral" id="itl" length="2"} + <a href="{:addon_url('integral://goods/detail','id='.$itl['id'])}" class="itl_item fl"> + <p class="itl_name">{$itl.goodsName}</p> + <p class="itl_price_box"> + <span class="itl_price">¥{$itl.goodsPrice}</span> + <span class="itl_score">{$itl.integralNum}积分</span> + </p> + <span class="itl_btn">立即兑换</span> + <img data-original="__IMGURL__/{$itl.goodsImg}" class="goodsImg" /> + </a> + {/volist} + + <div class="wst-clear"></div> + </div> + </div> + {/if} + {/* 分销商品 */} + {if(WSTConf('WST_ADDONS.distribut')!='') && count(distribut_list())>0} + {php}$distribut=distribut_list();{/php} + <p class="distribute_tit">分销商品</p> + <div class="distribute_out"> + <div class="dis_left_bg fl"> + <a href="{:addon_url('distribut://goods/glist')}"> + <img src="__STYLE__/img/index_distribute_bg.png" /> + </a> + </div> + <ul class="dis_list fl"> + {volist name="$distribut" id="dis" length="4"} + <li> + <a href="{:Url("home/goods/detail","id=".$dis["goodsId"])}"> + <img class='goodsImg' data-original="___IMGURL__/{$dis['goodsImg']}" title="{$dis['goodsName']}"/> + <div class="dis_gprice"> + <div class="f16"><span class="f12">¥</span>{$dis['shopPrice']}</div> + </div> + </a> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + <div class="wst-clear"></div> + </div> + {/if} + + {/* 店铺街 */} + {if empty($is_icp)} + <div class="shop_street_out"> + <p class="ss_tit">店铺街</p> + <ul class="shop_street"> + <li> + <div class="ss_desc"> + <a href="{:url('home/shops/shopStreet')}"> + <p class="ssd_tit">店铺汇聚</p> + <p class="ssd_desc">更多店铺等你来<br>总有一家适合你</p> + </a> + </div> + <img src="__STYLE__/img/shop_street_bg.png" alt="" /> + </li> + {volist name="$shopStreet" id="st" length="4"} + <li> + <a href="{:url('home/shops/home',['shopId'=>$st.shopId])}" target="_blank" class="ss_entry">>>进入店铺</a> + <!-- {/* 不显示店铺名称和地址 make cheng 20180307<p class="ss_shopname">{$st.shopName}</p> + <p class="ss_shopaddr">{$st.shopAddress}</p>*/} --> + <a href="{:url('home/shops/home',['shopId'=>$st.shopId])}" target="_blank"><img src="__IMGURL__/{$st.shopStreetImg}" alt="" /></a> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + </div> + {/if} + + + {php} + $validate = [0,3,6,9]; + $newArr = []; + foreach($floors as $_k=>$_v){ + // echo "$_k"; + if(in_array($_k,$validate)){ + // echo "-1<hr />"; + $newArr[] = $_v; + $_newArr = [];// 两个分类 + }else{ + // echo "-2<hr />"; + $_newArr[] = $_v; + if(count($_newArr)==2){ + $newArr[] = $_newArr; + } + } + } + $floors = $newArr; + // dump(count($floors));die; + $oneCatFloor = [1,3,5,7]; + $floorCount = 1;// 楼层数 + {/php} + + + <div class='wst-container'> + {volist name="$floors" id="vo" key="l" length="7"} + {if(in_array($l,$oneCatFloor))} + + {/* 楼层顶部广告 */} + {php}$adsCode = "ads-".$l."-1";{/php} + {wst:ads code="$adsCode" num="1" cache='86400' id="tad"} + <div style="width:1200px;height:110px;margin:40px auto;overflow: hidden"> + <a href="{$tad['adURL']}" {if ($tad['adURL']!='')}onclick="WST.recordClick({$tad['adId']})"{/if} > + <img class='goodsImg' data-original="__IMGURL__/{$tad['adFile']}"> + </a> + </div> + {/wst:ads} + + {/* 一个分类 */} + <div class="floor_box"> + <div class="floor-header fh1 c{$floorCount}" id="c{$floorCount}"> + <div class="floor-header-f{$floorCount} fh1l_titbox"> + <p class="floor-left-title"><a name="{$l}F"></a>{$l}F</p> + <p class="floor-right-title fh1_tit one_flimit" title="{$vo['catName']}">{$vo['catName']}</p> + </div> + <ul class="tab"> + <li class="tab-item{$floorCount} j-tab-selected{$floorCount}" id="fl_{$floorCount}_0" onmouseover="gpanelOver(this);" c="{$floorCount}"> + <a href="{:Url('home/goods/lists','cat='.$vo['catId'])}">热门</a> + </li> + {/* 楼层二级分类 */} + {volist name="vo['children']" id="vo1" key="l2" length="7"} + <li class="tab-item{$floorCount}" id="fl_{$floorCount}_{$l2}" onmouseover="gpanelOver(this);" c={$floorCount}> + <a href="{:Url('home/goods/lists','cat='.$vo1['catId'])}" title="{$vo1['catName']}">{:WSTMSubstr($vo1['catName'],0,4,"utf-8",true)}</a> + </li> + {/volist} + </ul> + </div> + <div class="floor_main"> + <div class="fml fl"> + <p class="f_desc"><!--去掉图片描述-make cheng 20180306{:WSTMSubstr($vo['catName'],0,4,'utf-8')} --></p> + <img src="__STYLE__/img/f{$l}_bg.png" alt="" /> + <!--注释掉图片上的分类 make cheng 20180307 <ul class="f1_catbox"> + {volist name="vo['children']" id="vo1" key="l2" length="4"} + <li> + <a href="{:Url('home/goods/lists','cat='.$vo1['catId'])}"> + <span class="f32">·</span> + {:WSTMSubstr($vo1['catName'],0,4,'utf-8')} + </a> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + --> + </div> + <div class="fmr fr"> + <div class="fmr_glist" id="fl_{$floorCount}_0_pl"> + {/* 楼层分类下的热门商品 */} + {wst:goods type='hot' cat="vo['catId']" cache="86400" num='10' id='cs'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$cs['goodsId'])}" class="fmr_gitem fl" title="{$cs['goodsName']}"> + <div class="fmr_img"> + <img title="{$cs['goodsName']}" class='goodsImg' data-original="__IMGURL__/{:WSTImg($cs['goodsImg'])}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($cs['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$cs['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$cs['shopPrice']*0.8}</p> + </p> + </a> + {/wst:goods} + <div class="wst-clear"></div> + </div> + {volist name="vo['children']" id="vo1" key="l2"} + <div class="fmr_glist" id="fl_{$floorCount}_{$l2}_pl" style="display:none"> + {/* 楼层分类下的商品 */} + {wst:goods type='recom' cat="vo1['catId']" cache="86400" num='10' id='vo2'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo2['goodsId'])}" class="fmr_gitem fl" title="{$vo2['goodsName']}"> + <div class="fmr_img"> + <img title="{$vo2['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$vo2['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($vo2['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$vo2['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$vo2['shopPrice']*0.8}</p> + </p> + </a> + {/wst:goods} + <div class="wst-clear"></div> + </div> + {/volist} + </div> + <div class="wst-clear"></div> + </div> + </div> + {php}++$floorCount;{/php} + {else /} + {/* 两个分类 */} + <div class="floor_box floor_box2"> + <div class="fb2_l fl"> + <div class="floor-header fh2 c{$l}" id="c{$l}"> + <div class="floor-header-f1 fh2l_titbox"> + <p class="floor-left-title"><a name="{$l}F"></a>{$l}F</p> + <p class="floor-right-title fh2_tit two_fmilit" title="{$vo[0]['catName']}">{$vo[0]['catName']}</p> + </div> + <ul class="tab"> + <li class="tab-item{$floorCount} j-tab-selected{$floorCount}" id="fl_{$floorCount}_0" onmouseover="gpanelOver(this);" c="{$floorCount}"> + <a href="{:Url('home/goods/lists','cat='.$vo[0]['catId'])}">热门</a> + </li> + {/* 楼层二级分类 */} + {volist name="vo[0]['children']" id="vo1" key="l2" length="3"} + <li class="tab-item{$floorCount}" id="fl_{$floorCount}_{$l2}" onmouseover="gpanelOver(this);" c={$floorCount}> + <a href="{:Url('home/goods/lists','cat='.$vo1['catId'])}" title="{$vo1['catName']}">{:WSTMSubstr($vo1['catName'],0,4,"utf-8",true)}</a> + </li> + {/volist} + <li class="tab-item{$floorCount}"> + <a class="fb2_more" href="{:Url('home/goods/lists','cat='.$vo[0]['catId'])}">>> + </a> + </li> + </ul> + </div> + <div class="fb2_l_l fl"> + <div class="fh2l fh2l_{$floorCount}"> + <p class="fh2l_tit">{:WSTMSubstr($vo[0]['catName'],0,4,'utf-8')} ></p> + <div class="fh2l_line"></div> + <p class="fh2l_desc">{$vo[0]['subTitle']!=''??'&nbsp;'}</p> + <div class="floor_silder"> + <ul> + {wst:goods type='best' cat="vo[0]['catId']" cache="86400" key="gb_key" num='3' id='gb'} + <li class="{if($gb_key==0)}img_first{elseif($gb_key==1)}img_second{else /}img_third{/if} + "> + <a title="{$gb.goodsName}" target="_blank" href="{:Url('home/goods/detail','id='.$gb['goodsId'])}"> + <p class="caption">{:WSTMSubstr($gb.goodsName,0,8,'utf-8')}</p> + <p class="sub_tit">{:WSTMSubstr($gb.goodsTips,0,20,'utf-8')}</p> + <img width="130" height="130" data-original="__IMGURL__/{$gb.goodsImg}" class="goodsImg" /> + </a> + <div class="color_mask"></div> + </li> + {/wst:goods} + </ul> + <div class="turn_show clearfix"> + <div class="prev_btn index_iconfont"><</div> + <div class="show_num"> + {wst:goods type='best' cat="vo[0]['catId']" cache="86400" key="gb_key" num='3' id='gb'} + <span {if($gb_key==0)}class="curr"{/if}></span> + {/wst:goods} + </div> + <div class="next_btn index_iconfont">></div> + </div> + </div> + </div> + </div> + <div class="fb2_l_r fr"> + <div class="fmr_glist" id="fl_{$floorCount}_0_pl"> + {/* 楼层分类下的热门商品 */} + {wst:goods type='hot' cat="vo[0]['catId']" cache="86400" num='4' id='cs'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$cs['goodsId'])}" title="{$cs['goodsName']}" class="fb2_gitem fl"> + <div class="fb2_img"> + <img title="{$cs['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$cs['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($cs['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$cs['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$cs['shopPrice']*0.8}</p> + </p> + </a> + + + {/wst:goods} + <div class="wst-clear"></div> + </div> + {volist name="vo[0]['children']" id="vo1" key="l2"} + <div class="fmr_glist" id="fl_{$floorCount}_{$l2}_pl" style="display:none"> + {/* 楼层分类下的商品 */} + {wst:goods type='recom' cat="vo1['catId']" cache="86400" num='4' id='vo2'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo2['goodsId'])}" +title="{$vo2['goodsName']}" class="fb2_gitem fl"> + <div class="fb2_img"> + <img title="{$vo2['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$vo2['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($vo2['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$vo2['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$vo2['shopPrice']*0.8}</p> + </p> + </a> + {/wst:goods} + <div class="wst-clear"></div> + </div> + {/volist} + </div> + <div class="wst-clear"></div> + </div> + {php}++$floorCount;{/php} + {if(isset($vo[1]))} + <div class="fb2_r fl"> + <div class="floor-header fh2 c{$l}" id="c{$l}"> + <div class="floor-header-f3 fh2l_titbox"> + <p class="floor-left-title"><a name="{$l}F"></a>{$l}F</p> + <p class="floor-right-title fh2_tit two_fmilit" title="{$vo[1]['catName']}">{$vo[1]['catName']}</p> + </div> + <ul class="tab"> + <li class="tab-item{$floorCount} j-tab-selected{$floorCount}" id="fl_{$floorCount}_0" onmouseover="gpanelOver(this);" c="{$floorCount}"> + <a href="{:Url('home/goods/lists','cat='.$vo[1]['catId'])}">热门</a> + </li> + {/* 楼层二级分类 */} + {volist name="vo[1]['children']" id="vo1" key="l2" length="3"} + <li class="tab-item{$floorCount}" id="fl_{$floorCount}_{$l2}" onmouseover="gpanelOver(this);" c={$floorCount}> + <a href="{:Url('home/goods/lists','cat='.$vo1['catId'])}" title="{$vo1['catName']}">{:WSTMSubstr($vo1['catName'],0,4,"utf-8",true)}</a> + </li> + {/volist} + <li class="tab-item{$floorCount}"> + <a class="fb2_more" href="{:Url('home/goods/lists','cat='.$vo[1]['catId'])}">>> + </a> + </li> + </ul> + </div> + <div class="fb2_r_l fl"> + <div class="fh2l fh2l_{$floorCount}"> + <p class="fh2l_tit">{:WSTMSubstr($vo[1]['catName'],0,4,'utf-8')} ></p> + <div class="fh2l_line"></div> + <p class="fh2l_desc">{$vo[1]['subTitle']!=''??'&nbsp;'}</p> + <div class="floor_silder"> + <ul> + {wst:goods type='best' cat="vo[1]['catId']" cache="86400" key="gb_key" num='3' id='gb'} + <li class="{if($gb_key==0)}img_first{elseif($gb_key==1)}img_second{else /}img_third{/if} + "> + <a title="{$gb.goodsName}" target="_blank" href="{:Url('home/goods/detail','id='.$gb['goodsId'])}"> + <p class="caption">{:WSTMSubstr($gb.goodsName,0,8,'utf-8')}</p> + <p class="sub_tit">{:WSTMSubstr($gb.goodsTips,0,20,'utf-8')}</p> + <img width="130" height="130" data-original="__IMGURL__/{$gb.goodsImg}" class="goodsImg" /> + </a> + <div class="color_mask"></div> + </li> + {/wst:goods} + + </ul> + <div class="turn_show clearfix"> + <div class="prev_btn index_iconfont"><</div> + <div class="show_num"> + {wst:goods type='best' cat="vo[1]['catId']" cache="86400" key="gb_key" num='3' id='gb'} + <span {if($gb_key==0)}class="curr"{/if}></span> + {/wst:goods} + </div> + <div class="next_btn index_iconfont">></div> + </div> + </div> + </div> + </div> + <div class="fb2_r_r fr"> + <div class="fmr_glist" id="fl_{$floorCount}_0_pl"> + {/* 楼层分类下的热门商品 */} + {wst:goods type='hot' cat="vo[1]['catId']" cache="86400" num='4' id='cs'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$cs['goodsId'])}" title="{$cs['goodsName']}" class="fb2_gitem fl"> + <div class="fb2_img"> + <img title="{$cs['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$cs['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($cs['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$cs['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$cs['shopPrice']*0.8}</p> + </p> + </a> + + + {/wst:goods} + <div class="wst-clear"></div> + </div> + {volist name="vo[1]['children']" id="vo1" key="l2"} + <div class="fmr_glist" id="fl_{$floorCount}_{$l2}_pl" style="display:none"> + {/* 楼层分类下的商品 */} + {wst:goods type='recom' cat="vo1['catId']" cache="86400" num='4' id='vo2'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$vo2['goodsId'])}" +title="{$vo2['goodsName']}" class="fb2_gitem fl"> + <div class="fb2_img"> + <img title="{$vo2['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$vo2['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($vo2['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$vo2['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$vo2['shopPrice']*0.8}</p> + </p> + </a> + {/wst:goods} + <div class="wst-clear"></div> + </div> + {/volist} + </div> + <div class="wst-clear"></div> + </div> + {php}++$floorCount;{/php} + {/if} + <div class="wst-clear"></div> + </div> + {/if} + + {/volist} + {/* 猜你喜欢 */} + <div class="like_goods_list"> + <div class="lg_tit">猜你喜欢</div> + <div class="lg_glist"> + {wst:goods type='hot' cat="0" cache="86400" num='10' id='cs'} + <a target='_blank' href="{:Url('home/goods/detail','id='.$cs['goodsId'])}" class="fmr_gitem fl" title="{$cs['goodsName']}"> + <div class="fmr_img"> + <img title="{$cs['goodsName']}" class='goodsImg' data-original="__IMGURL__/{$cs['goodsImg']}"/> + </div> + <p class="fmr_gname">{:WSTMSubstr($cs['goodsName'],0,33)}</p> + <p class="f16 rac_price_color tc"> + <span class="f12">¥</span>{$cs['shopPrice']} + <p class="f12 lxy">¥惠宝抵扣价{$cs['shopPrice']*0.8}</p> + </p> + </a> + {/wst:goods} + <div class="wst-clear"></div> + </div> + </div> + </div> +</div> +{/* 右侧菜单栏 */} +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script async="async" type='text/javascript' src='__STYLE__/js/index.js?v={$v}'></script> +<!--引入领取优惠券的js20180207 make cheng--> +<script type='text/javascript' src='__ROOT__/addons/coupon/view/home/index/index.js?v={$v}'></script> +{/block} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/invoices.html b/hyhproject/home2/view/default/invoices.html new file mode 100755 index 0000000..59c9675 --- /dev/null +++ b/hyhproject/home2/view/default/invoices.html @@ -0,0 +1,62 @@ +<div class='invoice_box'> + <div class="invoice_item"> + <div class="invoice_left"> + 发票抬头: + </div> + <div class="invoice_right"> + <ul class="inv_ul"> + <li class='inv_li {if($invoiceId==0)}inv_li_curr{/if}' onClick="changeInvoiceItem('0',this)">个人<i></i></li> + {volist name='data' id="inv"} + <li class='inv_li {if($invoiceId==$inv["id"])}inv_li_curr{/if}' onClick="changeInvoiceItem('{$inv.id}',this)"> + <input type="text" value="{$inv.invoiceHead}" readonly="readonly" class="invoice_input" id="invoiceHead_{$inv.id}" /> + <input type="hidden" id="invoiceCode_{$inv.id}" value="{$inv.invoiceCode}"} /> + <i></i> + <div class="inv_opabox"> + <a href='javascript:void(0)' onClick="invEdit('{$inv.id}',this)" class="edit_btn">编辑</a> + <a href='javascript:void(0)' onClick="editInvoice('{$inv.id}',this)" style="display:none;" class="save_btn">保存</a> + <a href='javascript:void(0)' onClick="delInvoice('{$inv.id}',this)">删除</a> + </div> + </li> + {/volist} + </ul> + </div> + <div class="wst-clear"></div> + </div> + <div class="invoice_item"> + <div class="invoice_left"> + + </div> + <div class="invoice_right"> + <a class="inv_add" onClick="invAdd()">新增发票单位</a> + </div> + </div> + + + <div class="invoice_item inv_codebox"> + <div class="invoice_left"> + 纳税人识别号: + </div> + <div class="invoice_right"> + <input type="text" id="invoice_num" /> + </div> + </div> + + <div class="invoice_item"> + <div class="invoice_left"> + 发票内容: + </div> + <div class="invoice_right"> + <ul class="inv_ul1"> + <li class='inv_li1 {if($isInvoice==0)}inv_li_curr{/if}' onClick="changeInvoiceItem1('0',this)">不开发票<i></i></li> + <li class='inv_li1 {if($isInvoice==1)}inv_li_curr{/if}' onClick="changeInvoiceItem1('1',this)">明细<i></i></li> + <div calss="wst-clear"></div> + </ul> + </div> + </div> + <div class="invoice_item tc"> + <a href="javascript:void(0)" class="inv_btn" onClick="saveInvoice()">保存</a> + <a href="javascript:void(0)" class="inv_btn inv_cancel" onclick='layerclose()'>取消</a> + </div> + + <div class="wst-clear"></div> +</div> \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/apply.js b/hyhproject/home2/view/default/js/apply.js new file mode 100755 index 0000000..70fb5c0 --- /dev/null +++ b/hyhproject/home2/view/default/js/apply.js @@ -0,0 +1,288 @@ +function initStep2(businessAreaPath,shopAreaIdPath){ + if(businessAreaPath!=''){ + var areaIdPath = businessAreaPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas',isRequire:true} + WST.ITSetAreas(aopts); + } + if(shopAreaIdPath!=''){ + var areaIdPath = shopAreaIdPath.split("_"); + $('#carea_0').val(areaIdPath[0]); + var aopts = {id:'carea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-careas',isRequire:true} + WST.ITSetAreas(aopts); + } + WST.upload({ + pick:'#legalCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#legalCertificateImgMsg').empty().hide(); + $('#legalCertificateImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#legalCertificateImg').val(json.savePath+json.name); + $('#msg_legalCertificateImg').hide(); + } + }, + progress:function(rate){ + $('#legalCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#businessLicenceImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#businessLicenceImgMsg').empty().hide(); + $('#businessLicenceImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#businessLicenceImg').val(json.savePath+json.name); + $('#msg_businessLicenceImg').hide(); + } + }, + progress:function(rate){ + $('#businessLicenceImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#bankAccountPermitImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#bankAccountPermitImgMsg').empty().hide(); + $('#bankAccountPermitImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#bankAccountPermitImg').val(json.savePath+json.name); + $('#msg_bankAccountPermitImg').hide(); + } + }, + progress:function(rate){ + $('#bankAccountPermitImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#organizationCodeImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#organizationCodeImgMsg').empty().hide(); + $('#organizationCodeImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#organizationCodeImg').val(json.savePath+json.name); + $('#msg_organizationCodeImg').hide(); + } + }, + progress:function(rate){ + $('#organizationCodeImgMsg').show().html('已上传'+rate+"%"); + } + }); +} +function delVO(obj){ + $(obj).parent().remove(); +} +function initStep3(areaPath){ + if(areaPath!=''){ + var areaIdPath = areaPath.split("_"); + $('#barea_0').val(areaIdPath[0]); + var aopts = {id:'barea_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-bareas',isRequire:true} + WST.ITSetAreas(aopts); + } + var uploader = WST.upload({ + pick:'#taxRegistrationCertificateImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + fileNumLimit:3, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + $('#taxRegistrationCertificateImgMsg').empty().hide(); + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='step_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#taxRegistrationCertificateImgBox').append(tdiv); + $('#msg_taxRegistrationCertificateImg').hide(); + var imgPath = []; + $('.step_pic').each(function(){ + imgPath.push($(this).attr('v')); + }); + $('#taxRegistrationCertificateImg').val(imgPath.join(',')); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + if($('#taxRegistrationCertificateImgBox').children().size()<=0){ + $('#msg_taxRegistrationCertificateImg').show(); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#taxRegistrationCertificateImgMsg').show().html('已上传'+rate+"%"); + } + }); + WST.upload({ + pick:'#taxpayerQualificationImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#taxpayerQualificationImgMsg').empty().hide(); + $('#taxpayerQualificationImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#taxpayerQualificationImg').val(json.savePath+json.name); + $('#msg_taxpayerQualificationImg').hide(); + } + }, + progress:function(rate){ + $('#taxpayerQualificationImgMsg').show().html('已上传'+rate+"%"); + } + }); +} + +function initStep4(){ + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#shopImgMsg').empty().hide(); + $('#shopImgPreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#shopImg').val(json.savePath+json.name); + $('#msg_shopImg').hide(); + } + }, + progress:function(rate){ + $('#shopImgMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',$('#serviceStartTime').attr('v')); + initTime('#serviceEndTime',$('#serviceEndTime').attr('v')); +} +function initTime(id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $(id).append(html.join('')); +} +function checkProtocol(obj){ + if(obj.checked){ + $('.msg-box').hide(); + }else{ + $('.msg-box').show(); + } +} +function saveStep1(){ + if($('#protocol')[0].checked){ + location.href=WST.U('home/shops/joinStep2'); + }else{ + $('.msg-box').show(); + } +} +function saveStep2(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var params = WST.getParams('.a-ipt'); + var load = WST.load({msg:'正在提交请求,请稍后...'}); + $.post(WST.U('home/shops/saveStep2'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep3'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep3(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var p= $('.file-panel').text(); + if(p!=""){ + WST.msg('请先上传补充材料',{icon:6}); + return; + } + var params = WST.getParams('.a-ipt'); + if((params.isLongbusinessDate=='' || params.isLongbusinessDate==0) && params.businessEndDate==''){ + WST.msg('请选择营业期限结束日期',{icon:5}); + return; + } + if((params.isLonglegalCertificateDate=='' || params.isLonglegalCertificateDate==0) && params.legalCertificateEndDate==''){ + WST.msg('请选择法定代表人证件有效期结束日期',{icon:5}); + return; + } + // if((params.isLongOrganizationCodeDate=='' || params.isLongOrganizationCodeDate==0) && params.organizationCodeEndDate==''){ + // WST.msg('请选择组织机构代码证有效期结束日期',{icon:5}); + // return; + // } + params.businessAreaPath0 = WST.ITGetAreaVal('j-areas'); + params.areaIdPath0 = WST.ITGetAreaVal('j-careas'); + var shopAds = []; + $('.j-gallery-img').each(function(){ + shopAds.push($(this).attr('v')); + }); + var a=$('.info').text(); + + params.shopAds = shopAds.join(','); + var load = WST.load({msg:'正在提交请求,请稍后...'}); + $.post(WST.U('home/shops/saveStep3'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep4'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep4(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var load = WST.load({msg:'正在提交请求,请稍后...'}); + var params = WST.getParams('.a-ipt'); + params.bankAreaId = WST.ITGetAreaVal('j-bareas'); + $.post(WST.U('home/shops/saveStep4'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinStep5'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} +function saveStep5(){ + $('#applyFrom').isValid(function(v){ + if(v){ + var load = WST.load({msg:'正在提交入驻请求,请稍后...'}); + var params = WST.getParams('.a-ipt'); + $.post(WST.U('home/shops/saveStep5'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href = WST.U('home/shops/joinSuccess'); + }else{ + layer.close(load); + WST.msg(json.msg,{icon:5}); + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/brandslist.js b/hyhproject/home2/view/default/js/brandslist.js new file mode 100755 index 0000000..df87200 --- /dev/null +++ b/hyhproject/home2/view/default/js/brandslist.js @@ -0,0 +1,33 @@ +//滑过效果 +var nodes = document.querySelectorAll('.wst-brands'), _nodes = [].slice.call(nodes, 0); +var getDirection = function (ev, obj) { + var w = obj.offsetWidth, h = obj.offsetHeight, x = ev.pageX - obj.offsetLeft - w / 2 * (w > h ? h / w : 1), y = ev.pageY - obj.offsetTop - h / 2 * (h > w ? w / h : 1), d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; + return d; +}; +var addClass = function (ev, obj, state) { + var direction = getDirection(ev, obj), class_suffix = ''; + obj.className = ''; + switch (direction) { + case 0: + class_suffix = '-top'; + break; + case 1: + class_suffix = '-right'; + break; + case 2: + class_suffix = '-bottom'; + break; + case 3: + class_suffix = '-left'; + break; + } + obj.classList.add(state + class_suffix); +}; +_nodes.forEach(function (el) { + el.addEventListener('mouseover', function (ev) { + addClass(ev, this, 'in'); + }, false); + el.addEventListener('mouseout', function (ev) { + addClass(ev, this, 'out'); + }, false); +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/carts.js b/hyhproject/home2/view/default/js/carts.js new file mode 100755 index 0000000..3e50321 --- /dev/null +++ b/hyhproject/home2/view/default/js/carts.js @@ -0,0 +1,683 @@ +var promotionMethod = {}; +function checkChks(obj,cobj){ + WST.checkChks(obj,cobj); + var ids = []; + $(cobj).each(function(){ + id = $(this).val(); + if(obj.checked){ + $(this).addClass('selected'); + }else{ + $(this).removeClass('selected'); + } + var cid = $(this).find(".j-chk").val(); + if(cid!='' && typeof(cid)!='undefined'){ + ids.push(cid); + statCartMoney(); + } + }); + batchChangeCartGoods(ids.join(','),obj.checked?1:0); +} +function batchChangeCartGoods(ids,isCheck){ + $.post(WST.U('home/carts/batchChangeCartGoods'),{ids:ids,isCheck:isCheck,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +function statCartMoney(){ + var cartMoney = 0,goodsTotalPrice,id; + $('.j-gchk').each(function(){ + id = $(this).val(); + goodsTotalPrice = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + $('#tprice_'+id).html(goodsTotalPrice.toFixed(2)); + if($(this).prop('checked')){ + cartMoney = cartMoney + goodsTotalPrice; + } + }); + var minusMoney = 0; + for(var key in promotionMethod){ + minusMoney = window[key](cartMoney); + cartMoney = cartMoney - minusMoney; + } + $('#totalMoney').html(cartMoney.toFixed(2)); + checkGoodsBuyStatus(); +} +function checkGoodsBuyStatus(){ + var cartNum = 0,stockNum = 0,cartId = 0; + $('.j-gchk').each(function(){ + cartId = $(this).val(); + cartNum = parseInt($('#buyNum_'+cartId).val(),10); + stockNum = parseInt($(this).attr('sval'),10);; + if(stockNum < 0 || stockNum < cartNum){ + if($(this).prop('checked')){ + $(this).parent().parent().css('border','2px solid red'); + }else{ + $(this).parent().parent().css('border','0px solid #eeeeee'); + $(this).parent().parent().css('border-bottom','1px solid #eeeeee'); + } + if(stockNum < 0){ + $('#gchk_'+cartId).attr('allowbuy',0); + $('#err_'+cartId).css('color','red').html('库存不足'); + }else{ + $('#gchk_'+cartId).attr('allowbuy',1); + $('#err_'+cartId).css('color','red').html('购买量超过库存'); + } + }else{ + $('#gchk_'+cartId).attr('allowbuy',10); + $(this).parent().parent().css('border','0px solid #eeeeee'); + $(this).parent().parent().css('border-bottom','1px solid #eeeeee'); + $('#err_'+cartId).html(''); + } + }); +} +function toSettlement(){ + var isChk = false; + $('.j-gchk').each(function(){ + if($(this).prop('checked'))isChk = true; + }); + if(!isChk){ + WST.msg('请选择要结算的商品!',{icon:1}); + return; + } + var msg = ''; + $('.j-gchk').each(function(){ + if($(this).prop('checked')){ + if($(this).attr('allowbuy')==0){ + msg = '所选商品库存不足'; + return; + }else if($(this).attr('allowbuy')==1){ + msg = '所选商品购买量大于商品库存'; + return; + } + } + }) + if(msg!=''){ + WST.msg(msg,{icon:2}); + return; + } + location.href=WST.U('home/carts/settlement'); +} + +function addrBoxOver(t){ + $(t).addClass('radio-box-hover'); + $(t).find('.operate-box').show(); +} +function addrBoxOut(t){ + $(t).removeClass('radio-box-hover'); + $(t).find('.operate-box').hide(); +} + + + +function setDeaultAddr(id){ + $.post(WST.U('home/useraddress/setDefault'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + getAddressList(); + changeAddrId(id); + } + }); +} + + +function changeAddrId(id){ + $.post(WST.U('home/useraddress/getById'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + inEffect($('#addr-'+id),1); + $('#s_addressId').val(json.data.addressId); + $("select[id^='area_0_']").remove(); + var areaIdPath = json.data.areaIdPath.split("_"); + // 设置收货地区市级id + $('#s_areaId').val(areaIdPath[1]); + + $('#area_0').val(areaIdPath[0]); + // 计算运费 + getCartMoney(); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas'} + WST.ITSetAreas(aopts); + WST.setValues(json.data); + } + }) +} + +function delAddr(id){ + WST.confirm({content:'您确定要删除该地址吗?',yes:function(index){ + $.post(WST.U('home/useraddress/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + getAddressList(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function getAddressList(obj){ + var id = $('#s_addressId').val(); + var load = WST.load({msg:'正在加载记录,请稍后...'}); + $.post(WST.U('home/useraddress/listQuery'),{rnd:Math.random()},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(json.data && json.data && json.data.length){ + var html = [],tmp; + for(var i=0;i<json.data.length;i++){ + tmp = json.data[i]; + var selected = (id==tmp.addressId)?'j-selected':''; + html.push( + '<div class="wst-frame1 '+selected+'" onclick="javascript:changeAddrId('+tmp.addressId+')" id="addr-'+tmp.addressId+'" >'+tmp.userName+'<i></i></div>', + '<li class="radio-box" onmouseover="addrBoxOver(this)" onmouseout="addrBoxOut(this)">', + tmp.userName, + '&nbsp;&nbsp;', + tmp.areaName+tmp.userAddress, + '&nbsp;&nbsp;&nbsp;&nbsp;', + tmp.userPhone + ) + if(tmp.isDefault==1){ + html.push('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="j-default">默认地址</span>') + } + html.push('<div class="operate-box">'); + if(tmp.isDefault!=1){ + html.push('<a href="javascript:;" onclick="setDeaultAddr('+tmp.addressId+')">设为默认地址</a>&nbsp;&nbsp;'); + } + html.push('<a href="javascript:void(0)" onclick="javascript:toEditAddress('+tmp.addressId+',this,1,1)">编辑</a>&nbsp;&nbsp;'); + if(json.data.length>1){ + html.push('<a href="javascript:void(0)" onclick="javascript:delAddr('+tmp.addressId+',this)">删除</a></div>'); + } + html.push('<div class="wst-clear"></div>','</li>'); + } + html.push('<a style="color:#1c9eff" onclick="editAddress()" href="javascript:;">收起地址</a>'); + + + $('#addressList').html(html.join('')); + }else{ + $('#addressList').empty(); + } + }else{ + $('#addressList').empty(); + } + }) +} +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function editAddress(){ + var isNoSelected = false; + $('.j-areas').each(function(){ + isSelected = true; + if($(this).val()==''){ + isNoSelected = true; + return; + } + }) + if(isNoSelected){ + WST.msg('请选择完整收货地址!',{icon:2}); + return; + } + layer.close(layerbox); + var load = WST.load({msg:'正在提交数据,请稍后...'}); + var params = WST.getParams('.j-eipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + $.post(WST.U('home/useraddress/'+((params.addressId>0)?'toEdit':'add')),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + $('.j-edit-box').hide(); + $('.j-list-box').hide(); + $('.j-show-box').show(); + if(params.addressId==0){ + $('#s_addressId').val(json.data.addressId); + }else{ + $('#s_addressId').val(params.addressId); + } + var areaIds = WST.ITGetAllAreaVals('area_0','j-areas'); + $('#s_areaId').val(areaIds[1]); + getCartMoney(); + var areaNames = []; + $('.j-areas').each(function(){ + areaNames.push($('#'+$(this).attr('id')+' option:selected').text()); + }) + $('#s_userName').html(params.userName+'<i></i>'); + $('#s_address').html(params.userName+'&nbsp;&nbsp;&nbsp;'+areaNames.join('')+'&nbsp;&nbsp;'+params.userAddress+'&nbsp;&nbsp;'+params.userPhone); + + $('#s_address').siblings('.operate-box').find('a').attr('onclick','toEditAddress('+params.addressId+',this,1,1,1)'); + + if(params.isDefault==1){ + $('#isdefault').html('默认地址').addClass('j-default'); + }else{ + $('#isdefault').html('').removeClass('j-default'); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +var layerbox; +function showEditAddressBox(){ + getAddressList(); + toEditAddress(); +} +function emptyAddress(obj,n){ + inEffect(obj,n); + $('#addressForm')[0].reset(); + $('#s_addressId').val(0); + $('#addressId').val(0); + $("select[id^='area_0_']").remove(); + + layerbox = layer.open({ + title:'用户地址', + type: 1, + area: ['800px', '300px'], + content: $('.j-edit-box') + }); +} +function toEditAddress(id,obj,n,flag,type){ + inEffect(obj,n); + id = (id>0)?id:$('#s_addressId').val(); + $.post(WST.U('home/useraddress/getById'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(flag){ + layerbox = layer.open({ + title:'用户地址', + type: 1, + area: ['800px', '300px'], //宽高 + content: $('.j-edit-box') + }); + } + if(type!=1){ + $('.j-list-box').show(); + $('.j-show-box').hide(); + } + WST.setValues(json.data); + $('input[name="addrUserPhone"]').val(json.data.userPhone) + $("select[id^='area_0_']").remove(); + if(id>0){ + var areaIdPath = json.data.areaIdPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas'} + WST.ITSetAreas(aopts); + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#isUseScore').prop('checked')?1:0; + params.useScore = $('#useScore').val(); + params.areaId2 = $('#s_areaId').val(); + params.recordId = $('#recordId').val(); + params.rnd = Math.random(); + params.deliverType = $('#deliverType').val(); + var couponIds = []; + $('.j-shop').each(function(){ + couponIds.push($(this).attr('dataval')+":"+$('#couponId_'+$(this).attr('dataval')).val()); + }); + params.couponIds = couponIds.join(','); + var load = WST.load({msg:'正在计算订单价格,请稍后...'}); + $.post(WST.U('home/carts/getCartMoney'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var shopFreight = 0; + for(var key in json.shops){ + // 设置每间店铺的运费及总价格 + $('#shopF_'+key).html(json.shops[key]['freight']); + $('#shopC_'+key).html(json.shops[key]['goodsMoney']); + shopFreight = shopFreight + json.shops[key]['freight']; + } + $('#maxScoreSpan').html(json.maxScore); + $('#maxScoreMoneySpan').html(Math.round(json.maxScoreMoney*100) / 100); + $('#isUseScore').attr('dataval',json.maxScore); + $('#deliverMoney').html(shopFreight); + $('#useScore').val(json.useScore); + $('#scoreMoney2').html(json.scoreMoney); + $('#totalMoney').html(json.realTotalMoney+'(含运费)'); + $('#orderScore').html((Math.round(json.realTotalMoney*100)/100)); + + } + }); +} +function changeDeliverType(n,index,obj){ + changeSelected(n,index,obj); + getCartMoney(); +} +function submitOrder(){ + var params = WST.getParams('.j-ipt'); + params.isUseScore = $('#isUseScore').prop('checked')?1:0 + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/orders/submit'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/orders/succeed','orderNo='+json.data); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + + +var invoicebox; +function changeInvoice(t,str,obj){ + var param = {}; + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + var loading = WST.load({msg:'正在请求数据,请稍后...'}); + $.post(WST.U('home/invoices/index'),param,function(data){ + layer.close(loading); + // layer弹出层 + invoicebox = layer.open({ + title:'发票信息', + type: 1, + area: ['628px', '420px'], //宽高 + content: data, + success :function(){ + if(param.invoiceId>0){ + $('.inv_codebox').show(); + console.log($('#invoiceCode_'+param.invoiceId)); + $('#invoice_num').val($('#invoiceCode_'+param.invoiceId).val()); + } + }, + }); + }); +} +function layerclose(){ + layer.close(invoicebox); +} + + +function changeInvoiceItem(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('.inv_editing').remove();// 删除正在编辑中的发票信息 + $('.inv_add').show(); + $('#invoiceId').val(t); + if(t==0){ + // 为个人时,隐藏识别号 + $('.inv_codebox').css({display:'none'}); + $('#invoice_num').val(' '); + }else{ + $('#invoice_num').val($('#invoiceCode_'+t).val()); + $('.inv_codebox').css({display:'block'}); + } + $("#invoice_obj").val(t); +} +// 是否需要开发票 +function changeInvoiceItem1(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('#isInvoice').val(t); +} +// 显示发票增加 +function invAdd(){ + $("#invoiceId").val(0); + $("#invoice_obj").val(1); + $('#invoice_num').val(''); + $('.inv_li').removeClass('inv_li_curr');// 移除当前选中样式 + $('.inv_ul').append('<li class="inv_li inv_li_curr inv_editing"><input type="text" id="invoiceHead" placeholder="新增单位发票抬头" value="" style="width:65%;height:21px;padding:1px;"><i></i><div style="top:8px;" class="inv_opabox"><a href="javascript:void(0)" onCLick="addInvoice()">保存</a></div></li>'); + $('.inv_ul').scrollTop($('.inv_ul')[0].scrollHeight);// 滚动到底部 + $('.inv_add').hide();// 隐藏新增按钮 + $('.inv_codebox').css({display:'block'});// 显示`纳税人识别号` +} +// 执行发票抬头新增 +function addInvoice(){ + var head = $('#invoiceHead').val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/add'),{invoiceHead:head},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + $('#invoiceId').val(json.data.id); + WST.msg(json.msg,{icon:1}); + $('.inv_editing').remove(); + var code = []; + code.push('<li class=\'inv_li inv_li_curr\' onClick="changeInvoiceItem(\''+json.data.id+'\',this)">'); + code.push('<input type="text" value="'+head+'" readonly="readonly" class="invoice_input" id="invoiceHead_'+json.data.id+'" />'); + code.push('<input type="hidden" id="invoiceCode_'+json.data.id+'" value=""} /><i></i>'); + code.push('<div class="inv_opabox">'); + code.push('<a href=\'javascript:void(0)\' onClick="invEdit(\''+json.data.id+'\',this)" class="edit_btn">编辑</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="editInvoice(\''+json.data.id+'\',this)" style="display:none;" class="save_btn">保存</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="delInvoice(\''+json.data.id+'\',this)">删除</a></div></li>'); + $('.inv_li:first').after(code.join('')); + // 显示新增按钮 + $('.inv_add').show(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +// 显示发票修改 +function invEdit(id,obj){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.removeAttr('readonly').focus(); + input.mouseup(function(){return false}); + $(obj).parent().parent().mouseup(function(){ + input.attr('readonly','readonly'); + $(obj).show().siblings('.save_btn').hide(); + }); + $(obj).hide().siblings('.save_btn').show(); + var invoice_code = $('#invoiceCode_'+id).val(); + $('.inv_codebox').css({display:'block'}) + $('#invoice_num').val(invoice_code);// 显示`纳税人识别号`) +} +// 完成发票修改 +function editInvoice(id,obj){ + var head = $('#invoiceHead_'+id).val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + alert(111); + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/edit'),{invoiceHead:head,id:id},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.attr('readonly','readonly') + $(obj).hide().siblings('.edit_btn').show(); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +// 设置页面显示值 +function setInvoiceText(invoiceHead){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)'+invoiceHead+' 明细'; + } + $('#invoice_info').html(text); + layerclose(); +} + +// 保存纳税人识别号 +function saveInvoice(){ + var isInv = $('#isInvoice').val(); + var num = $('#invoice_num').val(); + var id = $('#invoiceId').val(); + var invoiceHead = $('#invoiceHead').val();// 发票抬头 + var url = WST.U('home/Invoices/add'); + var params = {}; + if(id>0){ + url = WST.U('home/Invoices/edit'); + invoiceHead = $('#invoiceHead_'+id).val();// 发票抬头 + params.id = id; + } + params.invoiceHead = invoiceHead; + params.invoiceCode = num; + if($('#invoice_obj').val()!=0){ + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(url,params,function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + // 判断用户是否需要发票 + setInvoiceText(invoiceHead); + if(id==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }else{ + setInvoiceText(''); + } +} +// 删除发票信息 +function delInvoice(id,obj){ + WST.confirm({content:'您确定要删除该发票信息吗?',yes:function(index){ + $.post(WST.U('home/invoices/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).parent().parent().remove(); + $('#invoiceId').val(0); + // 选中 `个人` + $('.inv_li:first').click(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + + + + +function changeSelected(n,index,obj){ + $('#'+index).val(n); + inEffect(obj,2); +} + +function getPayUrl(){ + var params = {}; + params.payObj = "orderPay"; + params.orderNo = $("#orderNo").val(); + params.isBatch = $("#isBatch").val(); + params.payCode = $.trim($("#payCode").val()); + if(params.payCode==""){ + WST.msg('请先选择支付方式', {icon: 5}); + return; + } + + jQuery.post(WST.U('home/'+params.payCode+'/get'+params.payCode+"Url"),params,function(data) { + var json = WST.toJson(data); + if(json.status==1){ + if(params.payCode=="weixinpays" || params.payCode=="wallets"){ + location.href = json.url; + }else{ + if(params.payCode=="unionpays"){ + location.href = WST.U('home/unionpays/tounionpays',params); + }else{ + location.href = json.url; + } + } + }else{ + WST.msg('您的订单已支付!', {icon: 5,time:1500},function(){ + window.location = WST.U('home/orders/waitReceive'); + }); + } + }); +} + +function payByWallet(){ + var params = WST.getParams('.j-ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.payPwd = rsa.encrypt(params.payPwd); + } + var load = WST.load({msg:'正在核对支付密码,请稍后...'}); + $.post(WST.U('home/wallets/payByWallet'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1,time:1500},function(){ + window.location = WST.U('home/orders/waitReceive'); + }); + }else{ + WST.msg(json.msg,{icon:2,time:1500}); + } + }); +} + +function checkScoreBox(v){ + if(v){ + var val = $('#isUseScore').attr('dataval'); + $('#useScore').val(val); + $('#scoreMoney').show(); + + }else{ + $('#scoreMoney').hide(); + } + getCartMoney(); +} + +function setPaypwd(){ + layerbox = layer.open({ + title:['设置支付密码','text-align:left'], + type: 1, + area: ['450px', '240px'], + content: $('.j-paypwd-box'), + btn: ['设置支付密码,并支付订单', '关闭'], + yes: function(index, layero){ + var newPass = $.trim($("#payPwd").val()); + var reNewPass = $.trim($("#reNewPass").val()); + if(newPass==""){ + WST.msg("请输入支付密码!"); + return false; + } + if(reNewPass==""){ + WST.msg("请输入确认支付密码!"); + return false; + } + if(newPass!=reNewPass){ + WST.msg("密码不一致!"); + return false; + } + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + newPass = rsa.encrypt(newPass); + reNewPass = rsa.encrypt(reNewPass); + } + var load = WST.load({msg:'正在提交支付密码,请稍后...'}); + $.post(WST.U('home/users/payPassEdit'),{newPass:newPass,reNewPass:reNewPass},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1,time:1500},function(){ + layer.close(layerbox); + payByWallet(); + }); + }else{ + WST.msg(json.msg,{icon:2,time:1500}); + } + }); + + return false; + }, + btn2: function(index, layero){} + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/carts_quick.js b/hyhproject/home2/view/default/js/carts_quick.js new file mode 100755 index 0000000..e553b8c --- /dev/null +++ b/hyhproject/home2/view/default/js/carts_quick.js @@ -0,0 +1,256 @@ +function submitOrder(){ + var params = WST.getParams('.j-ipt'); + params.isUseScore = $('#isUseScore').prop('checked')?1:0 + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/orders/quickSubmit'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/orders/succeed','orderNo='+json.data); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + inEffect(obj,2); +} +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#isUseScore').prop('checked')?1:0; + params.useScore = $('#useScore').val(); + params.rnd = Math.random(); + params.deliverType = 1; + var couponIds = []; + $('.j-shop').each(function(){ + couponIds.push($(this).attr('dataval')+":"+$('#couponId_'+$(this).attr('dataval')).val()); + }); + params.couponIds = couponIds.join(','); + var load = WST.load({msg:'正在计算订单价格,请稍后...'}); + $.post(WST.U('home/carts/getQuickCartMoney'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + for(var key in json.shops){ + $('#shopC_'+key).html(json.shops[key]['goodsMoney']); + } + $('#maxScoreSpan').html(json.maxScore); + $('#maxScoreMoneySpan').html(json.maxScoreMoney); + $('#isUseScore').attr('dataval',json.maxScore); + $('#useScore').val(json.useScore); + $('#scoreMoney2').html(json.scoreMoney); + $('#totalMoney').html(json.realTotalMoney); + } + }); +} +function checkScoreBox(v){ + if(v){ + var val = $('#isUseScore').attr('dataval'); + $('#useScore').val(val); + $('#scoreMoney').show(); + }else{ + $('#scoreMoney').hide(); + } + getCartMoney(); +} + + +var invoicebox; +function changeInvoice(t,str,obj){ + var param = {}; + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + var loading = WST.load({msg:'正在请求数据,请稍后...'}); + $.post(WST.U('home/invoices/index'),param,function(data){ + layer.close(loading); + // layer弹出层 + invoicebox = layer.open({ + title:'发票信息', + type: 1, + area: ['628px', '420px'], //宽高 + content: data, + success :function(){ + if(param.invoiceId>0){ + $('.inv_codebox').show(); + console.log($('#invoiceCode_'+param.invoiceId)); + $('#invoice_num').val($('#invoiceCode_'+param.invoiceId).val()); + } + }, + }); + }); +} +function layerclose(){ + layer.close(invoicebox); +} + + +function changeInvoiceItem(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('.inv_editing').remove();// 删除正在编辑中的发票信息 + $('.inv_add').show(); + $('#invoiceId').val(t); + if(t==0){ + // 为个人时,隐藏识别号 + $('.inv_codebox').css({display:'none'}); + $('#invoice_num').val(' '); + }else{ + $('#invoice_num').val($('#invoiceCode_'+t).val()); + $('.inv_codebox').css({display:'block'}); + } + $("#invoice_obj").val(t); +} +// 是否需要开发票 +function changeInvoiceItem1(t,obj){ + $(obj).addClass('inv_li_curr').siblings().removeClass('inv_li_curr'); + $('#isInvoice').val(t); +} +// 显示发票增加 +function invAdd(){ + $("#invoiceId").val(0); + $("#invoice_obj").val(1); + $('#invoice_num').val(''); + $('.inv_li').removeClass('inv_li_curr');// 移除当前选中样式 + $('.inv_ul').append('<li class="inv_li inv_li_curr inv_editing"><input type="text" id="invoiceHead" placeholder="新增单位发票抬头" value="" style="width:65%;height:20px;padding:1px;"><i></i><div style="top:8px;" class="inv_opabox"><a href="javascript:void(0)" onCLick="addInvoice()">保存</a></div></li>'); + $('.inv_ul').scrollTop($('.inv_ul')[0].scrollHeight);// 滚动到底部 + $('.inv_add').hide();// 隐藏新增按钮 + $('.inv_codebox').css({display:'block'});// 显示`纳税人识别号` +} +// 执行发票抬头新增 +function addInvoice(){ + var head = $('#invoiceHead').val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/add'),{invoiceHead:head},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $('.inv_editing').remove(); + var code = []; + code.push('<li class=\'inv_li inv_li_curr\' onClick="changeInvoiceItem(\''+json.data.id+'\',this)">'); + code.push('<input type="text" value="'+head+'" readonly="readonly" class="invoice_input" id="invoiceHead_'+json.data.id+'" />'); + code.push('<input type="hidden" id="invoiceCode_'+json.data.id+'" value=""} /><i></i>'); + code.push('<div class="inv_opabox">'); + code.push('<a href=\'javascript:void(0)\' onClick="invEdit(\''+json.data.id+'\',this)" class="edit_btn">编辑</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="editInvoice(\''+json.data.id+'\',this)" style="display:none;" class="save_btn">保存</a>'); + code.push('<a href=\'javascript:void(0)\' onClick="delInvoice(\''+json.data.id+'\',this)">删除</a></div></li>'); + $('.inv_li:first').after(code.join('')); + // 显示新增按钮 + $('.inv_add').show(); + // 修改invoiceId + $('#invoiceId').val(json.data.id); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +// 显示发票修改 +function invEdit(id,obj){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.removeAttr('readonly').focus(); + input.mouseup(function(){return false}); + $(obj).parent().parent().mouseup(function(){ + input.attr('readonly','readonly'); + $(obj).show().siblings('.save_btn').hide(); + }); + $(obj).hide().siblings('.save_btn').show(); + var invoice_code = $('#invoiceCode_'+id).val(); + $('.inv_codebox').css({display:'block'}) + $('#invoice_num').val(invoice_code);// 显示`纳税人识别号`) +} +// 完成发票修改 +function editInvoice(id,obj){ + var head = $('#invoiceHead_'+id).val(); + if(head.length==0){ + WST.msg('发票抬头不能为空'); + return; + } + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/Invoices/edit'),{invoiceHead:head,id:id},function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + var input = $(obj).parent().parent().find('.invoice_input'); + input.attr('readonly','readonly') + $(obj).hide().siblings('.edit_btn').show(); + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} + +// 设置页面显示值 +function setInvoiceText(invoiceHead){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)'+invoiceHead+' 明细'; + } + $('#invoice_info').html(text); + layerclose(); +} + + +// 保存纳税人识别号 +function saveInvoice(){ + var isInv = $('#isInvoice').val(); + var num = $('#invoice_num').val(); + var id = $('#invoiceId').val(); + var invoiceHead = $('#invoiceHead').val();// 发票抬头 + var url = WST.U('home/Invoices/add'); + var params = {}; + if(id>0){ + url = WST.U('home/Invoices/edit'); + invoiceHead = $('#invoiceHead_'+id).val();// 发票抬头 + params.id = id; + } + params.invoiceHead = invoiceHead; + params.invoiceCode = num; + if($('#invoice_obj').val()!=0){ + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(url,params,function(data){ + var json = WST.toJson(data); + layer.close(loading); + if(json.status==1){ + // 判断用户是否需要发票 + setInvoiceText(invoiceHead); + if(id==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }else{ + setInvoiceText(''); + } +} + +// 删除发票信息 +function delInvoice(id,obj){ + WST.confirm({content:'您确定要删除该发票信息吗?',yes:function(index){ + $.post(WST.U('home/invoices/del'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).parent().parent().remove(); + $('#invoiceId').val(0); + // 选中 `个人` + $('.inv_li:first').click(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} diff --git a/hyhproject/home2/view/default/js/cloudzoom.js b/hyhproject/home2/view/default/js/cloudzoom.js new file mode 100755 index 0000000..bf92172 --- /dev/null +++ b/hyhproject/home2/view/default/js/cloudzoom.js @@ -0,0 +1,933 @@ +/* + Version 3.1 +*/ +(function(e) { + function s(a) { + var b = a.zoom, + c = a.Q, + g = a.R, + k = a.e, + f = a.g; + this.data = a; + this.U = this.b = null; + this.za = 0; + this.zoom = b; + this.V = !0; + this.r = this.interval = this.t = this.p = 0; + var q = this, + m; + q.b = e("<div class='" + a.K + "' style='position:absolute;overflow:hidden'></div>"); + var p = e("<img style='-webkit-touch-callout:none;position:absolute;max-width:none' src='" + v(b.T, b.options) + "'/>"); + b.options.variableMagnification && p.bind("mousewheel", + function(a, b) { + q.zoom.ia(0.1 * b); + return ! 1 + }); + q.U = p; + p.width(q.zoom.e); + p.height(q.zoom.g); + d.Ja && q.U.css("-webkit-transform", "perspective(400px)"); + var l = q.b; + l.append(p); + var h = e("<div style='position:absolute;'></div>"); + a.caption ? ("html" == b.options.captionType ? m = a.caption: "attr" == b.options.captionType && (m = e("<div class='cloudzoom-caption'>" + a.caption + "</div>")), m.css("display", "block"), h.css({ + width: k + }), l.append(h), h.append(m), e("body").append(l), this.r = m.outerHeight(), "bottom" == b.options.captionPosition ? h.css("top", f) : (h.css("top", 0), this.za = this.r)) : e("body").append(l); + l.css({ + opacity: 0, + width: k, + height: f + this.r + }); + this.zoom.C = "auto" === b.options.minMagnification ? Math.max(k / b.a.width(), f / b.a.height()) : b.options.minMagnification; + this.zoom.B = "auto" === b.options.maxMagnification ? p.width() / b.a.width() : b.options.maxMagnification; + a = l.height(); + this.V = !1; + b.options.zoomFlyOut ? (f = b.a.offset(), f.left += b.d / 2, f.top += b.c / 2, l.offset(f), l.width(0), l.height(0), l.animate({ + left: c, + top: g, + width: k, + height: a, + opacity: 1 + }, + { + duration: b.options.animationTime, + complete: function() { + q.V = !0 + } + })) : (l.offset({ + left: c, + top: g + }), l.width(k), l.height(a), l.animate({ + opacity: 1 + }, + { + duration: b.options.animationTime, + complete: function() { + q.V = !0 + } + })) + } + function x(a, b, c) { + this.a = a; + this.ba = a[0]; + this.Ca = c; + this.va = !0; + var g = this; + this.interval = setInterval(function() { + 0 < g.ba.width && 0 < g.ba.height && (clearInterval(g.interval), g.va = !1, g.Ca(a)) + }, + 100); + this.ba.src = b + } + function d(a, b) { + function c() { + k.update(); + window.Qa(c) + } + function g() { + var c; + c = "" != b.image ? b.image: "" + a.attr("src"); + k.sa(); + b.lazyLoadZoom ? a.bind("touchstart.preload " + k.options.mouseTriggerEvent + ".preload", + function() { + k.O(c, b.zoomImage) + }) : k.O(c, b.zoomImage) + } + var k = this; + b = e.extend({},e.fn.CloudZoom.defaults, b); + var f = d.qa(a, e.fn.CloudZoom.attr); + b = e.extend({},b, f); + 1 > b.easing && (b.easing = 1); + f = a.parent(); + f.is("a") && "" == b.zoomImage && (b.zoomImage = f.attr("href"), f.removeAttr("href")); + f = e("<div class='" + b.zoomClass + "'</div>"); + e("body").append(f); + this.Z = f.width(); + this.Y = f.height(); + b.zoomWidth && (this.Z = b.zoomWidth, this.Y = b.zoomHeight); + f.remove(); + this.options = b; + this.a = a; + this.g = this.e = this.d = this.c = 0; + this.H = this.m = null; + this.j = this.n = 0; + this.D = { + x: 0, + y: 0 + }; + this.Ua = this.caption = ""; + this.ea = { + x: 0, + y: 0 + }; + this.k = []; + this.pa = 0; + this.oa = ""; + this.b = this.v = this.u = null; + this.T = ""; + this.L = this.S = this.aa = !1; + this.G = null; + this.ha = this.Oa = !1; + this.l = null; + this.id = ++d.id; + this.I = this.ua = this.ta = 0; + this.o = this.h = null; + this.wa = this.B = this.C = this.f = this.i = this.ja = 0; + this.na(a); + this.ma = !1; + this.N = this.A = this.da = this.ca = 0; + if (a.is(":hidden")) var q = setInterval(function() { + a.is(":hidden") || (clearInterval(q), g()) + }, + 100); + else g(); + c() + } + function v(a, b) { + var c = b.uriEscapeMethod; + return "escape" == c ? escape(a) : "encodeURI" == c ? encodeURI(a) : a + } + function h(a) { + for (var b = "", + c, g = C("charCodeAt"), d = a[g](0) - 32, e = 1; e < a.length - 1; e++) c = a[g](e), + c ^= d & 31, + d++, + b += String[C("fromCharCode")](c); + a[g](e); + return b + } + function C(a) { + return a; + } + function y(a) { + var b = a || window.event, + c = [].slice.call(arguments, 1), + g = 0, + d = 0, + f = 0; + a = e.event.fix(b); + a.type = "mousewheel"; + b.wheelDelta && (g = b.wheelDelta / 120); + b.detail && (g = -b.detail / 3); + f = g; + void 0 !== b.axis && b.axis === b.HORIZONTAL_AXIS && (f = 0, d = -1 * g); + void 0 !== b.wheelDeltaY && (f = b.wheelDeltaY / 120); + void 0 !== b.wheelDeltaX && (d = -1 * b.wheelDeltaX / 120); + c.unshift(a, g, d, f); + return (e.event.dispatch || e.event.handle).apply(this, c) + } + var t = ["DOMMouseScroll", "mousewheel"]; + if (e.event.fixHooks) for (var n = t.length; n;) e.event.fixHooks[t[--n]] = e.event.mouseHooks; + e.event.special.mousewheel = { + setup: function() { + if (this.addEventListener) for (var a = t.length; a;) this.addEventListener(t[--a], y, !1); + else this.onmousewheel = y + }, + teardown: function() { + if (this.removeEventListener) for (var a = t.length; a;) this.removeEventListener(t[--a], y, !1); + else this.onmousewheel = null + } + }; + e.fn.extend({ + mousewheel: function(a) { + return a ? this.bind("mousewheel", a) : this.trigger("mousewheel") + }, + unmousewheel: function(a) { + return this.unbind("mousewheel", a) + } + }); + window.Qa = function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || + function(a) { + window.setTimeout(a, 20) + } + } (); + var n = document.getElementsByTagName("script"), + w = n[n.length - 1].src.lastIndexOf("/"), + z; + z = "undefined" != typeof window.CloudZoom ? window.CloudZoom.path: n[n.length - 1].src.slice(0, w); + var n = window, + D = n[h("$Bphd|`ee&")], + u = !0, + E = !1, + F = h("%KISIYZ2"), + w = h("&VRZJBJ_HJ?").length, + A = !1, + B = !1; + 5 == w ? B = !0 : 4 == w && (A = !0); + d.xa = 1E9; + e(window).bind("resize.cloudzoom", + function() { + d.xa = e(this).width() + }); + e(window).trigger("resize.cloudzoom"); + d.prototype.J = function() { + return "inside" === this.options.zoomPosition || d.xa <= this.options.autoInside ? !0 : !1 + }; + d.prototype.update = function() { + var a = this.h; + null != a && (this.q(this.D, 0), this.f != this.i && (this.i += (this.f - this.i) / this.options.easing, 1E-4 > Math.abs(this.f - this.i) && (this.i = this.f), this.Na()), a.update()) + }; + d.id = 0; + d.prototype.Ha = function(a) { + var b = this.T.replace(/^\/|\/$/g, ""); + if (0 == this.k.length) return { + href: this.options.zoomImage, + title: this.a.attr("title") + }; + if (void 0 != a) return this.k; + a = []; + for (var c = 0; c < this.k.length && this.k[c].href.replace(/^\/|\/$/g, "") != b; c++); + for (b = 0; b < this.k.length; b++) a[b] = this.k[c], + c++, + c >= this.k.length && (c = 0); + return a + }; + d.prototype.getGalleryList = d.prototype.Ha; + d.prototype.P = function() { + clearTimeout(this.ja); + null != this.o && this.o.remove() + }; + d.prototype.sa = function() { + var a = this; + this.Oa || this.a.bind("mouseover.prehov mousemove.prehov mouseout.prehov", + function(b) { + a.G = "mouseout" == b.type ? null: { + pageX: b.pageX, + pageY: b.pageY + } + }) + }; + d.prototype.Ea = function() { + this.G = null; + this.a.unbind("mouseover.prehov mousemove.prehov mouseout.prehov") + }; + d.prototype.O = function(a, b) { + var c = this; + c.a.unbind("touchstart.preload " + c.options.mouseTriggerEvent + ".preload"); + c.sa(); + this.P(); + e("body").children(".cloudzoom-fade-" + c.id).remove(); + null != this.v && (this.v.cancel(), this.v = null); + null != this.u && (this.u.cancel(), this.u = null); + this.T = "" != b && void 0 != b ? b: a; + this.L = this.S = !1; ! c.options.galleryFade || !c.aa || c.J() && null != c.h || (c.l = e(new Image).css({ + position: "absolute" + }), c.l.attr("src", c.a.attr("src")), c.l.width(c.a.width()), c.l.height(c.a.height()), c.l.offset(c.a.offset()), c.l.addClass("cloudzoom-fade-" + c.id), e("body").append(c.l)); + this.Ma(); + var g = e(new Image); + this.u = new x(g, a, + function(a, b) { + c.u = null; + c.L = !0; + c.a.attr("src", g.attr("src")); + e("body").children(".cloudzoom-fade-" + c.id).fadeOut(c.options.fadeTime, + function() { + e(this).remove(); + c.l = null + }); + void 0 !== b ? (c.P(), c.options.errorCallback({ + $element: c.a, + type: "IMAGE_NOT_FOUND", + data: b.Ga + })) : c.ra() + }) + }; + d.prototype.Ma = function() { + var a = this; + a.ja = setTimeout(function() { + a.o = e("<div class='cloudzoom-ajax-loader' style='position:absolute;left:0px;top:0px'/>"); + e("body").append(a.o); + var b = a.o.width(), + g = a.o.height(), + b = a.a.offset().left + a.a.width() / 2 - b / 2, + g = a.a.offset().top + a.a.height() / 2 - g / 2; + a.o.offset({ + left: b, + top: g + }) + }, + 250); + var b = e(new Image); + this.v = new x(b, this.T, + function(c, g) { + a.v = null; + a.S = !0; + a.e = b[0].width; + a.g = b[0].height; + void 0 !== g ? (a.P(), a.options.errorCallback({ + $element: a.a, + type: "IMAGE_NOT_FOUND", + data: g.Ga + })) : a.ra() + }) + }; + d.prototype.loadImage = d.prototype.O; + d.prototype.Ba = function() { + alert("Cloud Zoom API OK") + }; + d.prototype.apiTest = d.prototype.Ba; + d.prototype.s = function() { + null != this.h && (this.a.trigger("cloudzoom_end_zoom"), this.h.$()); + this.h = null + }; + d.prototype.$ = function() { + e(document).unbind("mousemove." + this.id); + this.a.unbind(); + null != this.b && (this.b.unbind(), this.s()); + this.a.removeData("CloudZoom"); + e("body").children(".cloudzoom-fade-" + this.id).remove(); + this.ma = !0 + }; + d.prototype.destroy = d.prototype.$; + d.prototype.Da = function(a) { + if (!this.options.hoverIntentDelay) return ! 1; + 0 === this.A && (this.A = (new Date).getTime(), this.ca = a.pageX, this.da = a.pageY); + var b = a.pageX - this.ca, + c = a.pageY - this.da, + b = Math.sqrt(b * b + c * c); + this.ca = a.pageX; + this.da = a.pageY; + a = (new Date).getTime(); + b <= this.options.hoverIntentDistance ? this.N += a - this.A: this.A = a; + if (this.N < this.options.hoverIntentDelay) return ! 0; + this.N = this.A = 0; + return ! 1 + }; + d.prototype.W = function() { + var a = this; + a.a.bind(a.options.mouseTriggerEvent + ".trigger", + function(b) { + if (!a.X() && null == a.b && !a.Da(b)) { + var c = a.a.offset(); + b = new d.F(b.pageX - c.left, b.pageY - c.top); + a.M(); + a.w(); + a.q(b, 0); + a.D = b + } + }) + }; + d.prototype.X = function() { + if (this.ma || !this.S || !this.L) return ! 0; + if (!1 === this.options.disableZoom) return ! 1; + if (!0 === this.options.disableZoom) return ! 0; + if ("auto" == this.options.disableZoom) { + if (!isNaN(this.options.maxMagnification) && 1 < this.options.maxMagnification) return ! 1; + if (this.a.width() >= this.e) return ! 0 + } + return ! 1 + }; + d.prototype.ra = function() { + var a = this; + if (a.S && a.L) { + this.la(); + a.e = a.a.width() * this.i; + a.g = a.a.height() * this.i; + this.P(); + this.ga(); + null != a.h && (a.s(), a.w(), a.H.attr("src", v(this.a.attr("src"), this.options)), a.q(a.ea, 0)); + if (!a.aa) { + a.aa = !0; + e(document).bind("MSPointerUp." + this.id + " mousemove." + this.id, + function(b) { + if (null != a.b) { + var c = a.a.offset(), + g = !0, + c = new d.F(b.pageX - Math.floor(c.left), b.pageY - Math.floor(c.top)); + if ( - 1 > c.x || c.x > a.d || 0 > c.y || c.y > a.c) g = !1, + a.options.permaZoom || (a.b.remove(), a.s(), a.b = null); + a.ha = !1; + "MSPointerUp" === b.type && (a.ha = !0); + g && (a.D = c) + } + }); + a.W(); + var b = 0, + c = 0, + g = 0, + k = function(a, b) { + return Math.sqrt((a.pageX - b.pageX) * (a.pageX - b.pageX) + (a.pageY - b.pageY) * (a.pageY - b.pageY)) + }; + a.a.css({ + "-ms-touch-action": "none", + "-ms-user-select": "none" + }); + a.a.bind("touchstart touchmove touchend", + function(e) { + if (a.X()) return ! 0; + var f = a.a.offset(), + h = e.originalEvent, + l = { + x: 0, + y: 0 + }, + r = h.type; + if ("touchend" == r && 0 == h.touches.length) return a.fa(r, l), + !1; + l = new d.F(h.touches[0].pageX - Math.floor(f.left), h.touches[0].pageY - Math.floor(f.top)); + a.D = l; + if ("touchstart" == r && 1 == h.touches.length && null == a.b) return a.fa(r, l), + !1; + 2 > b && 2 == h.touches.length && (c = a.f, g = k(h.touches[0], h.touches[1])); + b = h.touches.length; + 2 == b && a.options.variableMagnification && (f = k(h.touches[0], h.touches[1]) / g, a.f = a.J() ? c * f: c / f, a.f < a.C && (a.f = a.C), a.f > a.B && (a.f = a.B)); + a.fa("touchmove", l); + e.preventDefault(); + e.stopPropagation(); + return e.returnValue = !1 + }); + if (null != a.G) { + if (this.X()) return; + var f = a.a.offset(), + f = new d.F(a.G.pageX - f.left, a.G.pageY - f.top); + a.M(); + a.w(); + a.q(f, 0); + a.D = f + } + } + a.Ea(); + a.a.trigger("cloudzoom_ready") + } + }; + d.prototype.fa = function(a, b) { + var c = this; + switch (a) { + case "touchstart": + if (null != c.b) break; + clearTimeout(c.interval); + c.interval = setTimeout(function() { + c.M(); + c.w(); + c.q(b, c.j / 2); + c.update() + }, + 150); + break; + case "touchend": + clearTimeout(c.interval); + null == c.b ? c.ya() : c.options.permaZoom || (c.b.remove(), c.b = null, c.s()); + break; + case "touchmove": + null == c.b && (clearTimeout(c.interval), c.M(), c.w()) + } + }; + d.prototype.Na = function() { + var a = this.i; + if (null != this.b) { + var b = this.h; + this.n = b.b.width() / (this.a.width() * a) * this.a.width(); + this.j = b.b.height() / (this.a.height() * a) * this.a.height(); + this.j -= b.r / a; + this.m.width(this.n); + this.m.height(this.j); + this.q(this.ea, 0) + } + }; + d.prototype.ia = function(a) { + this.f += a; + this.f < this.C && (this.f = this.C); + this.f > this.B && (this.f = this.B) + }; + d.prototype.na = function(a) { + this.caption = null; + "attr" == this.options.captionType ? (a = a.attr(this.options.captionSource), "" != a && void 0 != a && (this.caption = a)) : "html" == this.options.captionType && (a = e(this.options.captionSource), a.length && (this.caption = a.clone(), a.css("display", "none"))) + }; + d.prototype.Ia = function(a, b) { + if ("html" == b.captionType) { + var c; + c = e(b.captionSource); + c.length && c.css("display", "none") + } + }; + d.prototype.la = function() { + this.f = this.i = "auto" === this.options.startMagnification ? this.e / this.a.width() : this.options.startMagnification + }; + d.prototype.w = function() { + var a = this; + a.a.trigger("cloudzoom_start_zoom"); + this.la(); + a.e = a.a.width() * this.i; + a.g = a.a.height() * this.i; + var b = this.m, + c = a.d, + g = a.c, + d = a.e, + f = a.g, + h = a.caption; + if (a.J()) { + b.width(a.d / a.e * a.d); + b.height(a.c / a.g * a.c); + b.css("display", "none"); + var m = a.options.zoomOffsetX, + p = a.options.zoomOffsetY; + a.options.autoInside && (m = p = 0); + a.h = new s({ + zoom: a, + Q: a.a.offset().left + m, + R: a.a.offset().top + p, + e: a.d, + g: a.c, + caption: h, + K: a.options.zoomInsideClass + }); + a.ka(a.h.b); + a.h.b.bind("touchmove touchstart touchend", + function(b) { + a.a.trigger(b); + return ! 1 + }) + } else if (isNaN(a.options.zoomPosition)) m = e(a.options.zoomPosition), + b.width(m.width() / a.e * a.d), + b.height(m.height() / a.g * a.c), + b.fadeIn(a.options.fadeTime), + a.options.zoomFullSize || "full" == a.options.zoomSizeMode ? (b.width(a.d), b.height(a.c), b.css("display", "none"), a.h = new s({ + zoom: a, + Q: m.offset().left, + R: m.offset().top, + e: a.e, + g: a.g, + caption: h, + K: a.options.zoomClass + })) : a.h = new s({ + zoom: a, + Q: m.offset().left, + R: m.offset().top, + e: m.width(), + g: m.height(), + caption: h, + K: a.options.zoomClass + }); + else { + var m = a.options.zoomOffsetX, + p = a.options.zoomOffsetY, + l = !1; + if (this.options.lensWidth) { + var r = this.options.lensWidth, + n = this.options.lensHeight; + r > c && (r = c); + n > g && (n = g); + b.width(r); + b.height(n) + } + d *= b.width() / c; + f *= b.height() / g; + r = a.options.zoomSizeMode; + if (a.options.zoomFullSize || "full" == r) d = a.e, + f = a.g, + b.width(a.d), + b.height(a.c), + b.css("display", "none"), + l = !0; + else if (a.options.zoomMatchSize || "image" == r) b.width(a.d / a.e * a.d), + b.height(a.c / a.g * a.c), + d = a.d, + f = a.c; + else if ("zoom" === r || this.options.zoomWidth) b.width(a.Z / a.e * a.d), + b.height(a.Y / a.g * a.c), + d = a.Z, + f = a.Y; + c = [[c / 2 - d / 2, -f], [c - d, -f], [c, -f], [c, 0], [c, g / 2 - f / 2], [c, g - f], [c, g], [c - d, g], [c / 2 - d / 2, g], [0, g], [ - d, g], [ - d, g - f], [ - d, g / 2 - f / 2], [ - d, 0], [ - d, -f], [0, -f]]; + m += c[a.options.zoomPosition][0]; + p += c[a.options.zoomPosition][1]; + l || b.fadeIn(a.options.fadeTime); + a.h = new s({ + zoom: a, + Q: a.a.offset().left + m, + R: a.a.offset().top + p, + e: d, + g: f, + caption: h, + K: a.options.zoomClass + }) + } + a.h.p = void 0; + a.n = b.width(); + a.j = b.height(); + this.options.variableMagnification && a.m.bind("mousewheel", + function(b, c) { + a.ia(0.1 * c); + return ! 1 + }) + }; + d.prototype.La = function() { + return this.h ? !0 : !1 + }; + d.prototype.isZoomOpen = d.prototype.La; + d.prototype.Fa = function() { + this.a.unbind(this.options.mouseTriggerEvent + ".trigger"); + var a = this; + null != this.b && (this.b.remove(), this.b = null); + this.s(); + setTimeout(function() { + a.W() + }, + 1) + }; + d.prototype.closeZoom = d.prototype.Fa; + d.prototype.ya = function() { + var a = this; + this.a.unbind(a.options.mouseTriggerEvent + ".trigger"); + this.a.trigger("click"); + setTimeout(function() { + a.W() + }, + 1) + }; + d.prototype.ka = function(a) { + var b = this; + a.bind("mousedown." + b.id + " mouseup." + b.id, + function(a) { + "mousedown" === a.type ? b.wa = (new Date).getTime() : (b.ha && (b.b && b.b.remove(), b.s(), b.b = null), 250 >= (new Date).getTime() - b.wa && b.ya()) + }) + }; + d.prototype.M = function() { + 5 == F.length && !1 == E && (u = !0); + var a = this, + b; + a.ga(); + a.m = e("<div class='" + a.options.lensClass + "' style='overflow:hidden;display:none;position:absolute;top:0px;left:0px;'/>"); + var c = e('<img style="-webkit-touch-callout: none;position:absolute;left:0;top:0;max-width:none" src="' + v(this.a.attr("src"), this.options) + '">'); + c.width(this.a.width()); + c.height(this.a.height()); + a.H = c; + a.H.attr("src", v(this.a.attr("src"), this.options)); + var d = a.m; + a.b = e("<div class='cloudzoom-blank' style='position:absolute;'/>"); + var k = a.b; + b = e("<div style='background-color:" + a.options.tintColor + ";width:100%;height:100%;'/>"); + b.css("opacity", a.options.tintOpacity); + b.fadeIn(a.options.fadeTime); + k.width(a.d); + k.height(a.c); + k.offset(a.a.offset()); + e("body").append(k); + k.append(b); + k.append(d); + k.bind("touchmove touchstart touchend", + function(b) { + a.a.trigger(b); + return ! 1 + }); + d.append(c); + a.I = parseInt(d.css("borderTopWidth"), 10); + isNaN(a.I) && (a.I = 0); + a.ka(a.b); + + if (false) { + b = e(h("3/p|`)$6~rj#I")); + var f, c = "{}"; + B ? f = h("7Ttvo<Gqpm!*wvlgk!)ym~cev{}g;uxu2") : A && (f = h("3Pxzcs8Cutq=|f rvbvujro`dx\"nab "), c = h('\'|*kkhgj|`ev>wzzxj; 9?-./\"- akwbbz+0)bb`j2=0|dtu~l`8!,3-bI')); + u && (f = h("\'Rfechic}jt1Q{`r7BvuvF")); + b[h(".zjhe%")](f); + f = h(',w/~`cxfz{{4-:xxhsqkke#.!h``s*3(:<}v-<3p|`ayz:#8/,mf=,#x.mkbbp+0)==>? !0?6cdq{swuig=:#tjwldkm+&)hd}|pk1.7t{wzq90?}plnp!>\'%ano(\'.ykwd<a{uqy`:#8uss{=,#dljq+aidcgu/4-cp|`9fseq87>{qqt,qj~`$=*8:{t/\"-v~|g9bs~qn9&?|ple /&ugcl`dl.7,=`i0?6wye||h9&?/ox!qlhlb\'+=:;.!,mqrytfzcy|4ytprl=:#!g45$zO'); + b[h("8{ji)")](e[h(":jznn{USNL5")](f)); + b[h("8{ji)")](e[h(":jznn{USNL5")](c)); + } + }; + d.prototype.q = function(a, b) { + var c, d; + this.ea = a; + c = a.x; + d = a.y; + b = 0; + this.J() && (b = 0); + c -= this.n / 2 + 0; + d -= this.j / 2 + b; + c > this.d - this.n ? c = this.d - this.n: 0 > c && (c = 0); + d > this.c - this.j ? d = this.c - this.j: 0 > d && (d = 0); + var e = this.I; + this.m.parent(); + this.m.css({ + left: Math.ceil(c) - e, + top: Math.ceil(d) - e + }); + c = -c; + d = -d; + this.H.css({ + left: Math.floor(c) + "px", + top: Math.floor(d) + "px" + }); + this.ta = c; + this.ua = d + }; + d.qa = function(a, b) { + var c = null, + d = a.attr(b); + if ("string" == typeof d) { + var d = e.trim(d), + h = d.indexOf("{"), + f = d.indexOf("}"); + f != d.length - 1 && (f = d.indexOf("};")); + if ( - 1 != h && -1 != f) { + d = d.substr(h, f - h + 1); + try { + c = e.parseJSON(d) + } catch(q) { + console.error("Invalid JSON in " + b + " attribute:" + d) + } + } else c = (new D("return {" + d + "}"))() + } + return c + }; + d.F = function(a, b) { + this.x = a; + this.y = b + }; + d.point = d.F; + x.prototype.cancel = function() { + clearInterval(this.interval); + this.va = !1 + }; + d.Sa = function(a) { + z = a + }; + d.setScriptPath = d.Sa; + d.Pa = function() { + e(function() { + e(".cloudzoom").CloudZoom(); + e(".cloudzoom-gallery").CloudZoom() + }) + }; + d.quickStart = d.Pa; + d.prototype.ga = function() { + this.d = this.a.outerWidth(); + this.c = this.a.outerHeight() + }; + d.prototype.refreshImage = d.prototype.ga; + d.version = "3.1 rev 1312051822"; + d.Ta = function() { + e[h("\'fbhrD")]({ + url: z + "/" + h(";wu~{qsd,iwN"), + dataType: "script", + async: !1, + crossDomain: !0, + cache: !0, + success: function() { + E = !0 + } + }) + }; + d.Ka = function() { + d.browser = {}; + d.browser.webkit = /webkit/.test(navigator.userAgent.toLowerCase()); + var a = new D("a", h('2{u<by|vm5pr}~thmm*uth|fid`03-vx~v.7?e}moir=x~lrg8rdt\'k4oeobjjEC[P{xfxv|to4jwqdnu-hjef|`ee\"ea|ds~q<-v%x4hlqwk(#.!->`hz!|j~-l2 *p/u;zrv~ns\'54)hd+g8;fSkWwpn |esagf|xp0z4wysykh,*b_g[)dldlxe%>98/.)7853xAyAab21 ?>g+oillrDj%,!2:sHvH=56;3g`-#\"=b,jjacGo\"jWoS$2?0:=gscmkt:-&lzttpm%5$')); + if (5 != F.length) { + var b = h("2agugf{m~suo3}pm-qwewvk}nce#b`sp~*"); + u = a(b) + } else u = !1, + d.Ta(); + this._ = ":Irhxm%sucqtis`agy%obc#cesadycpqwi5pr}~l!Wpaw<6(Echic}j*\"\'\" -wv *,~)x\'085b25ca9h:2=;omhi2Wuas-\\|y;,(2?21305"; + this.Ja = -1 != navigator.platform.indexOf("iPhone") || -1 != navigator.platform.indexOf("iPod") || -1 != navigator.platform.indexOf("iPad") + }; + d.Ra = function(a) { + e.fn.CloudZoom.attr = a + }; + d.setAttr = d.Ra; + e.fn.CloudZoom = function(a) { + return this.each(function() { + if (e(this).hasClass("cloudzoom-gallery")) { + var b = d.qa(e(this), e.fn.CloudZoom.attr), + c = e(b.useZoom).data("CloudZoom"); + c.Ia(e(this), b); + var g = e.extend({}, + c.options, b), + h = e(this).parent(), + f = g.zoomImage; + h.is("a") && (f = h.attr("href")); + c.k.push({ + href: f, + title: e(this).attr("title"), + Aa: e(this) + }); + e(this).bind(g.galleryEvent, + function() { + var a; + for (a = 0; a < c.k.length; a++) c.k[a].Aa.removeClass("cloudzoom-gallery-active"); + e(this).addClass("cloudzoom-gallery-active"); + if (b.image == c.oa) return ! 1; + c.oa = b.image; + c.options = e.extend({},c.options, b); + c.na(e(this)); + var d = e(this).parent(); + d.is("a") && (b.zoomImage = d.attr("href")); + a = "mouseover" == b.galleryEvent ? c.options.galleryHoverDelay: 1; + clearTimeout(c.pa); + c.pa = setTimeout(function() { + c.O(b.image, b.zoomImage) + }, + a); + if (d.is("a") || e(this).is("a")) return ! 1 + }) + } else e(this).data("CloudZoom", new d(e(this), a)) + }) + }; + e.fn.CloudZoom.attr = "data-cloudzoom"; + e.fn.CloudZoom.defaults = { + image: "", + zoomImage: "", + tintColor: "#000", + tintOpacity: 0.25, + animationTime: 500, + sizePriority: "lens", + lensClass: "cloudzoom-lens", + lensProportions: "CSS", + lensAutoCircle: !1, + innerZoom: !1, + galleryEvent: "mousemove",//mousemove|click by 33 h ao.c om + easeTime: 500, + zoomSizeMode: "lens", + zoomMatchSize: !1, + zoomPosition: 3, + zoomOffsetX: 25, + zoomOffsetY: -21, + zoomFullSize: !1, + zoomFlyOut: !0, + zoomClass: "cloudzoom-zoom", + zoomInsideClass: "cloudzoom-zoom-inside", + captionSource: "title", + captionType: "attr", + captionPosition: "bottom", + imageEvent: "click", + uriEscapeMethod: !1, + errorCallback: function() {}, + variableMagnification: !0, + startMagnification: "auto", + minMagnification: "auto", + maxMagnification: "6", + easing: 8, + lazyLoadZoom: !1, + mouseTriggerEvent: "mousemove", + disableZoom: !1, + galleryFade: !0, + galleryHoverDelay: 200, + permaZoom: !1, + zoomWidth: 360, + zoomHeight: 360, + lensWidth: 0, + lensHeight: 0, + hoverIntentDelay: 0, + hoverIntentDistance: 2, + autoInside: 750 + }; + s.prototype.update = function() { + var a = this.zoom, + b = a.i, + c = -a.ta + a.n / 2, + d = -a.ua + a.j / 2; + void 0 == this.p && (this.p = c, this.t = d); + this.p += (c - this.p) / a.options.easing; + this.t += (d - this.t) / a.options.easing; + var c = -this.p * b, + c = c + a.n / 2 * b, + d = -this.t * b, + d = d + a.j / 2 * b, + e = a.a.width() * b, + a = a.a.height() * b; + 0 < c && (c = 0); + 0 < d && (d = 0); + c + e < this.b.width() && (c += this.b.width() - (c + e)); + d + a < this.b.height() - this.r && (d += this.b.height() - this.r - (d + a)); + this.U.css({ + left: c + "px", + top: d + this.za + "px", + width: e, + height: a + }) + }; + s.prototype.$ = function() { + var a = this; + a.b.bind("touchstart", + function() { + return ! 1 + }); + var b = this.zoom.a.offset(); + this.zoom.options.zoomFlyOut ? this.b.animate({ + left: b.left + this.zoom.d / 2, + top: b.top + this.zoom.c / 2, + opacity: 0, + width: 1, + height: 1 + }, + { + duration: this.zoom.options.animationTime, + step: function() { + d.browser.webkit && a.b.width(a.b.width()) + }, + complete: function() { + a.b.remove() + } + }) : this.b.animate({ + opacity: 0 + }, + { + duration: this.zoom.options.animationTime, + complete: function() { + a.b.remove() + } + }) + }; + n.CloudZoom = d; + d.Ka() +})(jQuery); \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/common webuploader ╔╧┤лoss.js b/hyhproject/home2/view/default/js/common webuploader ╔╧┤лoss.js new file mode 100755 index 0000000..fc10704 --- /dev/null +++ b/hyhproject/home2/view/default/js/common webuploader ╔╧┤лoss.js @@ -0,0 +1,1230 @@ +$(function() { + $('.goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + $('.usersImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.USER_LOGO});//会员默认头像 +}); +WST.initVisitor = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.dropDownLayerCart(".wst-cart-box",".wst-cart-boxs"); + WST.searchIpt(); + WST.showCategoryNavs(); + WST.Sidebar(); + WST.getSysMessages('message,cart'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart'); + },10000); + } +} +WST.initUserCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.dropDownLayerCart(".wst-lite-cart",".wst-lite-carts"); + WST.getSysMessages('message,cart,userorder'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart,userorder'); + },10000); + } +} +WST.initShopCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.getSysMessages('message,shoporder'); + if(WST.conf.MESSAGE_BOX!=''){ + var msg = WST.conf.MESSAGE_BOX.split('||'); + for(var i=0;i<msg.length;i++){ + WST.open({type: 1, + title: '系统提示', + shade: false, + area: ['340px', '215px'], + offset: 'rb', + time: 20000, + anim: 4, + content: "<div class='j-messsage-box'>"+msg[i]+"</div>", + }) + } + } + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,shoporder'); + },10000); + } +} +WST.searchIpt = function(){ + $('.j-search-box').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + },function(){ + $(".j-type-list").hide(); + $(this).css({"border-left":"2px solid #e23c3d"}); + $(this).find('i').removeClass('over').addClass('arrow'); + }); + + $('j-type-list').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + }); + + $(".j-type-list div").click(function(){ + $("#search-type").val($(this).attr("data")); + $(".j-search-type span").html($(this).html()); + if($(this).attr("data")==1){ + $(this).attr("data",0); + $(this).html('商品'); + $('#search-ipt').attr('placeholder',$('#adsShopWordsSearch').val()); + }else{ + $(this).attr("data",1); + $(this).html('店铺'); + $('#search-ipt').attr('placeholder',$('#adsGoodsWordsSearch').val()); + } + $(".j-type-list").hide(); + $(".j-search-type").find('i').removeClass('over').addClass('arrow'); + }); +} +WST.search = function(){ + if($("#search-type").val()==1){ + WST.shopSearch($.trim($('#search-ipt').val())); + }else{ + WST.goodsSearch($.trim($('#search-ipt').val())); + } +} +WST.shopSearch = function(v){ + location.href = WST.U('home/shops/shopstreet','keyword='+v,true); +} +WST.goodsSearch = function(v){ + location.href = WST.U('home/goods/search','keyword='+v,true); +} +WST.showCategoryNavs = function(){ + if($('.wst-filters')[0]){ + $(".drop-down").hover(function(){ + $(this).addClass("hover"); + },function(){ + $(this).removeClass("hover"); + }); + $(".dorp-down-layer").hover(function(){ + $(this).prev().addClass("hover"); + },function(){ + $(this).prev().removeClass("hover"); + }); + } +} +WST.Sidebar = function(){ + if(!$('#wst-categorys')[0])return; + + if(!$('#wst-categorys').hasClass('j-index')){ + WST.dropDownLayer("#wst-categorys",".j-cate-dd"); + } + $(".dd-inner").children(".item").hover(function() { //一级导航悬浮 + $('.categeMenuImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//默认图片 + $(this).parent().find('.over-cat').show(); + + $(this).addClass("hover").siblings(".item").removeClass("hover"); + var index = $(this).index(); + $(".dorpdown-layer").children(".item-sub").hide(); + $(".dorpdown-layer").children(".item-sub").eq(index).show(); + + var start = $('.j-cate-dt').offset().top; + var obj = $('#index_menus_sub'); + var sh = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度 + if(sh>start+36){ + var start = sh-start; + }else{ + var start = 36; + } + //obj.stop().animate({ "top": start }); + obj.css('top',start); + + + },function(){ + $(this).parent().find('.over-cat').hide(); + }); + + + + $('.over-cat-icon').parent().mouseover(function(){ + $(this).find('.over-cat-icon').addClass('over-cat-icon-hover'); + }); + $('.over-cat-icon').parent().mouseout(function(){ + $(this).find('.over-cat-icon').removeClass('over-cat-icon-hover'); + }); + + $(".dd-inner").children(".item").mouseover(function() { + + $('.dd-inner').find('.over-cat').show(); + + var iCon = $(this).attr('id'); + $('.'+iCon).addClass(iCon+'-hover'); + }); + $(".dd-inner").children(".item").mouseout(function() { + + $('.dd-inner').find('.over-cat').hide(); + + var iCon = $(this).attr('id'); + $('.'+iCon).removeClass(iCon+'-hover'); + }); + + $("#index_menus_sub").hover(function(){ + $('.dd-inner').find('.over-cat').show(); + $(this).show(); + },function(){ + $(this).hide(); + $('.dd-inner').find('.over-cat').hide(); + }); + $(".dd-inner").hover(function() { //整个导航菜单悬浮,是否显示二级导航到出厂 + $("#index_menus_sub").show(); + + }, function() { + $("#index_menus_sub").hide(); + $('.item').removeClass("hover"); + }) + $("#index_menus_sub").children(".item-sub").hover(function() { //二级导航悬浮 + var index = $(this).index(); + $(".dd-inner").children(".item").eq(index).addClass("hover"); + $("#index_menus_sub").show(); + var i = index+1; + $('.cat-icon-'+i).addClass('cat-icon-'+i+'-hover'); + }, function() { + $("#index_menus_sub").hide(); + $(".dd-inner").children(".item").removeClass("hover"); + var index = $(this).index(); + var i = index+1; + $('.cat-icon-'+i).removeClass('cat-icon-'+i+'-hover'); + + }); + + $('.fore2').hover(function(){ + $(this).children('dt').css('background-color','#ff6a53'); + },function(){ + $(this).children('dt').css('background-color',''); + }); +} +WST.dropDownLayer = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); +} + + +WST.tips = function(content, selector, options){ + + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'200px'}, options); + return layer.confirm(opts.content,{icon: 'wst3', title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.load = function(options){ + var opts = {}; + opts = $.extend(opts,{time:0,icon:'wstloading',shade: [0.4, '#000000'],offset: '200px',area: ['280px', '65px']},options); + return layer.msg(opts.msg, opts); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:1000,shade: [0.4, '#000000'],offset: '200px'},options); + return layer.msg(msg, opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.toJson = function(str,noAlert){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(typeof(noAlert)=='undefined'){ + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} + +//刷新验证码 +WST.logout = function(){ + $.post(WST.U('home/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/index/index'); + }); +} + +/** +* 上传图片 +*/ +// WST.upload = function(opts){ +// var _opts = {}; +// _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('home/index/uploadPic')},opts); +// var uploader = WebUploader.create(_opts); +// uploader.on('uploadSuccess', function( file,response ) { +// var json = WST.toJson(response._raw); +// if(_opts.callback)_opts.callback(json,file); +// }); +// uploader.on('uploadError', function( file ) { +// if(_opts.uploadError)_opts.uploadError(); +// }); +// uploader.on( 'uploadProgress', function( file, percentage ) { +// percentage = percentage.toFixed(2)*100; +// if(_opts.progress)_opts.progress(percentage); +// }); +// return uploader; +// } +/** + * 修改上传图片 + */ +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + 'success_action_status' : '201', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + +WST.upload = function(opts){ + dir = opts.formData.dir; + console.log(dir); + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com'},opts); + var uploader = WebUploader.create(_opts); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function( file,response ) { + console.log(response); + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + +/** + * end + */ + + +WST.goTo = function(obj){ + location.href = $(obj).attr('data'); +} +WST.getVerify = function(id){ + $(id).attr('src',WST.U('home/index/getVerify','rnd='+Math.random())); +} +WST.loginWindow = function(){ + WST.currentUrl(); + $.post(WST.U('home/users/toLoginBox'),{},function(data){ + WST.open({type:1,area:['550px','360px'],offset:'auto',title:'用户登录',content:data}); + }); +} +WST.currentUrl = function(url){ + if(!url)var url = window.location.href; + $.post(WST.U('home/index/currenturl'),{url:url},function(data){}); +} +/********************* 选项卡切换隐藏 **********************/ +$.fn.TabPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav li').click(function(){ + $(this).addClass("on").siblings().removeClass(); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav li').eq(opts.tab).click(); +} +/** + * 去除url中指定的参数(用于分页) + */ +WST.splitURL = function(spchar){ + var url = location.href; + var urlist = url.split("?"); + var furl = new Array(); + var fparams = new Array(); + furl.push(urlist[0]); + if(urlist.length>1){ + var urlparam = urlist[1]; + params = urlparam.split("&"); + for(var i=0; i<params.length; i++){ + var vparam = params[i]; + var param = vparam.split("="); + if(param[0]!=spchar){ + fparams.push(vparam); + } + } + if(fparams.length>0){ + furl.push(fparams.join("&")); + } + + } + if(furl.length>1){ + return furl.join("?"); + }else{ + return furl.join(""); + } +} +WST.addCart = function(goodsId){ + // if(window.conf.IS_LOGIN==0){ + // WST.loginWindow(); + // return; + // } + $.post(WST.U('home/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data,1); + if(json.status==1){ + WST.msg(json.msg,{icon:1,time:600,shade:false}); + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + } + getRightCart(); + }else{ + if(json.status==-999){ + + WST.loginWindow(); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + } + }); +} + +WST.delCart = function(id){ + WST.confirm({content:'您确定要删除该商品吗?',yes:function(index){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/carts/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('home/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.dropDownLayerCart = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + WST.checkCart(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function (event) { + event.stopPropagation(); + $(this).show(); + }, function (event) { + event.stopPropagation(); + $(this).hide(); + }); +} +WST.delCheckCart = function(id,func){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + WST.checkCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.checkCart = function(){ + $('#list-carts2').html(''); + $('#list-carts3').html(''); + $('#list-carts').html('<div style="padding:32px 0px 77px 112px;"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</div>'); + $.post(WST.U('home/carts/getCartInfo'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.list.length>0){ + var gettpl = document.getElementById('list-cart').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-carts').html(html); + }); + $('#list-carts2').html('<div class="comm" id="list-comm">&nbsp;&nbsp;共<span>'+json.goodsTotalNum+'</span>件商品<span class="span2">¥'+json.goodsTotalMoney+'</span></div>'); + $('#list-carts3').html('<a href="'+window.conf.ROOT+'/home/carts/index" class="btn btn-3">去购物车结算</a>'); + $('.goodsImgc').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + if(json.list.length>5){ + $('#list-carts').css('overflow-y','scroll').css('height','416'); + } + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + } + $('#goodsTotalNum').html(json.goodsTotalNum); + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + $('#goodsTotalNum').html(0); + } + }); +} +WST.changeIptNum = function(diffNum,iptId,btnId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var tmp = 0; + if(maxVal<minVal){ + tmp = maxVal; + maxVal = minVal; + minVal = tmp; + } + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + btnId = btnId.split(','); + $(btnId[0]+suffix).css('color','#666'); + $(btnId[1]+suffix).css('color','#666'); + if(minVal>=num){ + num=minVal; + $(btnId[0]+suffix).css('color','#ccc'); + } + if(maxVal<=num){ + num=maxVal; + $(btnId[1]+suffix).css('color','#ccc'); + } + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.shopQQ = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a href="tencent://message/?uin='+val+'&Site=QQ交谈&Menu=yes">', + '<img border="0" src="http://wpa.qq.com/pa?p=1:'+val+':7" alt="QQ交谈" width="71" height="24" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.shopWangWang = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid='+val+'&siteid=cntaobao&status=1&charset=utf-8">', + '<img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid='+val+'&site=cntaobao&s=1&charset=utf-8" alt="和我联系" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.cancelFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var param = {},str = '商品'; + param.id = fId; + param.type = type; + str = (type==1)?'店铺':'商品'; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav').addClass('j-fav2'); + $(obj).html('关注'+str)[0].onclick = function(){ + WST.addFavorite(obj,type,id,fId); + }; + }else{ + WST.msg(json.msg,{icon:5}); + } + }); +} + + +WST.addFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + $.post(WST.U('home/favorites/add'),{type:type,id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav2').addClass('j-fav'); + $(obj).html('已关注')[0].onclick = function(){ + WST.cancelFavorite(obj,type,id,json.data.fId); + }; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} +/**记录广告点击**/ +WST.recordClick = function(adId){ + $.post(WST.U('home/ads/recordClick'),{id:adId},function(data){}); +} +/** + * 获取用户信息 + */ +WST.getSysMessages = function(val){ + if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/index/getSysMessages'),{tasks:val},function(data){ + var json = WST.toJson(data); + if(json.message){ + $('#wst-user-messages').html(json.message.num); + if(parseInt(json.message.num,10)>0){ + $('#wst-user-messages').css('color','red'); + if($('.j-message-count')[0])$('.j-message-count').show().html(json.message.num); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).addClass('wst-msg-tips-box').html(json.message.num); + if($('#mId_'+json.message.sid)[0])$('#mId_'+json.message.sid).addClass('wst-msg-tips-box').html(json.message.num); + }else{ + $('#wst-user-messages').css('color','#666'); + if($('.j-message-count')[0])$('.j-message-count').hide(); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).removeClass('wst-msg-tips-box').html(''); + } + } + if(json.cart){ + $('#goodsTotalNum').html(json.cart.goods); + if(json.cart.goods>0){ + if($('.j-cart-count')[0])$('.j-cart-count').show().html(json.cart.goods); + }else{ + if($('.j-cart-count')[0])$('.j-cart-count').hide().html(''); + } + } + if(json.userorder){ + for(var key in json.userorder){ + if($('#mId_'+key)[0]){ + if(json.userorder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.userorder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + if(json.shoporder){ + for(var key in json.shoporder){ + if($('#mId_'+key)[0]){ + if(json.shoporder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.shoporder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + }); +} +WST.position = function(mid,mtype){ + $.post(WST.U('home/index/position'),{menuId:mid,menuType:mtype},function(data){}); +} +//关闭顶部广告 +WST.closeAds = function(t){ + $(t).parent().remove(); +} +WST.closeIframe = function(){ + var index = parent.layer.getFrameIndex(window.name); + parent.layer.close(index); +} +WST.shopsCats = function(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} + +WST.slides = function(objId){ + var slide = $(objId), li = slide.find("li"); + var slidecontrols = $(objId+'-controls').eq(0), + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + span.bind("mouseout", function() { + index++; + if (index >= span.length) + index = 0; + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} + +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); + diff --git a/hyhproject/home2/view/default/js/common webuploader 鈺斺暓鈹ば籵ss.js b/hyhproject/home2/view/default/js/common webuploader 鈺斺暓鈹ば籵ss.js new file mode 100755 index 0000000..fc10704 --- /dev/null +++ b/hyhproject/home2/view/default/js/common webuploader 鈺斺暓鈹ば籵ss.js @@ -0,0 +1,1230 @@ +$(function() { + $('.goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + $('.usersImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.USER_LOGO});//会员默认头像 +}); +WST.initVisitor = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.dropDownLayerCart(".wst-cart-box",".wst-cart-boxs"); + WST.searchIpt(); + WST.showCategoryNavs(); + WST.Sidebar(); + WST.getSysMessages('message,cart'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart'); + },10000); + } +} +WST.initUserCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.dropDownLayerCart(".wst-lite-cart",".wst-lite-carts"); + WST.getSysMessages('message,cart,userorder'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart,userorder'); + },10000); + } +} +WST.initShopCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.getSysMessages('message,shoporder'); + if(WST.conf.MESSAGE_BOX!=''){ + var msg = WST.conf.MESSAGE_BOX.split('||'); + for(var i=0;i<msg.length;i++){ + WST.open({type: 1, + title: '系统提示', + shade: false, + area: ['340px', '215px'], + offset: 'rb', + time: 20000, + anim: 4, + content: "<div class='j-messsage-box'>"+msg[i]+"</div>", + }) + } + } + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,shoporder'); + },10000); + } +} +WST.searchIpt = function(){ + $('.j-search-box').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + },function(){ + $(".j-type-list").hide(); + $(this).css({"border-left":"2px solid #e23c3d"}); + $(this).find('i').removeClass('over').addClass('arrow'); + }); + + $('j-type-list').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + }); + + $(".j-type-list div").click(function(){ + $("#search-type").val($(this).attr("data")); + $(".j-search-type span").html($(this).html()); + if($(this).attr("data")==1){ + $(this).attr("data",0); + $(this).html('商品'); + $('#search-ipt').attr('placeholder',$('#adsShopWordsSearch').val()); + }else{ + $(this).attr("data",1); + $(this).html('店铺'); + $('#search-ipt').attr('placeholder',$('#adsGoodsWordsSearch').val()); + } + $(".j-type-list").hide(); + $(".j-search-type").find('i').removeClass('over').addClass('arrow'); + }); +} +WST.search = function(){ + if($("#search-type").val()==1){ + WST.shopSearch($.trim($('#search-ipt').val())); + }else{ + WST.goodsSearch($.trim($('#search-ipt').val())); + } +} +WST.shopSearch = function(v){ + location.href = WST.U('home/shops/shopstreet','keyword='+v,true); +} +WST.goodsSearch = function(v){ + location.href = WST.U('home/goods/search','keyword='+v,true); +} +WST.showCategoryNavs = function(){ + if($('.wst-filters')[0]){ + $(".drop-down").hover(function(){ + $(this).addClass("hover"); + },function(){ + $(this).removeClass("hover"); + }); + $(".dorp-down-layer").hover(function(){ + $(this).prev().addClass("hover"); + },function(){ + $(this).prev().removeClass("hover"); + }); + } +} +WST.Sidebar = function(){ + if(!$('#wst-categorys')[0])return; + + if(!$('#wst-categorys').hasClass('j-index')){ + WST.dropDownLayer("#wst-categorys",".j-cate-dd"); + } + $(".dd-inner").children(".item").hover(function() { //一级导航悬浮 + $('.categeMenuImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//默认图片 + $(this).parent().find('.over-cat').show(); + + $(this).addClass("hover").siblings(".item").removeClass("hover"); + var index = $(this).index(); + $(".dorpdown-layer").children(".item-sub").hide(); + $(".dorpdown-layer").children(".item-sub").eq(index).show(); + + var start = $('.j-cate-dt').offset().top; + var obj = $('#index_menus_sub'); + var sh = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度 + if(sh>start+36){ + var start = sh-start; + }else{ + var start = 36; + } + //obj.stop().animate({ "top": start }); + obj.css('top',start); + + + },function(){ + $(this).parent().find('.over-cat').hide(); + }); + + + + $('.over-cat-icon').parent().mouseover(function(){ + $(this).find('.over-cat-icon').addClass('over-cat-icon-hover'); + }); + $('.over-cat-icon').parent().mouseout(function(){ + $(this).find('.over-cat-icon').removeClass('over-cat-icon-hover'); + }); + + $(".dd-inner").children(".item").mouseover(function() { + + $('.dd-inner').find('.over-cat').show(); + + var iCon = $(this).attr('id'); + $('.'+iCon).addClass(iCon+'-hover'); + }); + $(".dd-inner").children(".item").mouseout(function() { + + $('.dd-inner').find('.over-cat').hide(); + + var iCon = $(this).attr('id'); + $('.'+iCon).removeClass(iCon+'-hover'); + }); + + $("#index_menus_sub").hover(function(){ + $('.dd-inner').find('.over-cat').show(); + $(this).show(); + },function(){ + $(this).hide(); + $('.dd-inner').find('.over-cat').hide(); + }); + $(".dd-inner").hover(function() { //整个导航菜单悬浮,是否显示二级导航到出厂 + $("#index_menus_sub").show(); + + }, function() { + $("#index_menus_sub").hide(); + $('.item').removeClass("hover"); + }) + $("#index_menus_sub").children(".item-sub").hover(function() { //二级导航悬浮 + var index = $(this).index(); + $(".dd-inner").children(".item").eq(index).addClass("hover"); + $("#index_menus_sub").show(); + var i = index+1; + $('.cat-icon-'+i).addClass('cat-icon-'+i+'-hover'); + }, function() { + $("#index_menus_sub").hide(); + $(".dd-inner").children(".item").removeClass("hover"); + var index = $(this).index(); + var i = index+1; + $('.cat-icon-'+i).removeClass('cat-icon-'+i+'-hover'); + + }); + + $('.fore2').hover(function(){ + $(this).children('dt').css('background-color','#ff6a53'); + },function(){ + $(this).children('dt').css('background-color',''); + }); +} +WST.dropDownLayer = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); +} + + +WST.tips = function(content, selector, options){ + + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'200px'}, options); + return layer.confirm(opts.content,{icon: 'wst3', title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.load = function(options){ + var opts = {}; + opts = $.extend(opts,{time:0,icon:'wstloading',shade: [0.4, '#000000'],offset: '200px',area: ['280px', '65px']},options); + return layer.msg(opts.msg, opts); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:1000,shade: [0.4, '#000000'],offset: '200px'},options); + return layer.msg(msg, opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.toJson = function(str,noAlert){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(typeof(noAlert)=='undefined'){ + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} + +//刷新验证码 +WST.logout = function(){ + $.post(WST.U('home/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/index/index'); + }); +} + +/** +* 上传图片 +*/ +// WST.upload = function(opts){ +// var _opts = {}; +// _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('home/index/uploadPic')},opts); +// var uploader = WebUploader.create(_opts); +// uploader.on('uploadSuccess', function( file,response ) { +// var json = WST.toJson(response._raw); +// if(_opts.callback)_opts.callback(json,file); +// }); +// uploader.on('uploadError', function( file ) { +// if(_opts.uploadError)_opts.uploadError(); +// }); +// uploader.on( 'uploadProgress', function( file, percentage ) { +// percentage = percentage.toFixed(2)*100; +// if(_opts.progress)_opts.progress(percentage); +// }); +// return uploader; +// } +/** + * 修改上传图片 + */ +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + 'success_action_status' : '201', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + +WST.upload = function(opts){ + dir = opts.formData.dir; + console.log(dir); + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com'},opts); + var uploader = WebUploader.create(_opts); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function( file,response ) { + console.log(response); + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + +/** + * end + */ + + +WST.goTo = function(obj){ + location.href = $(obj).attr('data'); +} +WST.getVerify = function(id){ + $(id).attr('src',WST.U('home/index/getVerify','rnd='+Math.random())); +} +WST.loginWindow = function(){ + WST.currentUrl(); + $.post(WST.U('home/users/toLoginBox'),{},function(data){ + WST.open({type:1,area:['550px','360px'],offset:'auto',title:'用户登录',content:data}); + }); +} +WST.currentUrl = function(url){ + if(!url)var url = window.location.href; + $.post(WST.U('home/index/currenturl'),{url:url},function(data){}); +} +/********************* 选项卡切换隐藏 **********************/ +$.fn.TabPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav li').click(function(){ + $(this).addClass("on").siblings().removeClass(); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav li').eq(opts.tab).click(); +} +/** + * 去除url中指定的参数(用于分页) + */ +WST.splitURL = function(spchar){ + var url = location.href; + var urlist = url.split("?"); + var furl = new Array(); + var fparams = new Array(); + furl.push(urlist[0]); + if(urlist.length>1){ + var urlparam = urlist[1]; + params = urlparam.split("&"); + for(var i=0; i<params.length; i++){ + var vparam = params[i]; + var param = vparam.split("="); + if(param[0]!=spchar){ + fparams.push(vparam); + } + } + if(fparams.length>0){ + furl.push(fparams.join("&")); + } + + } + if(furl.length>1){ + return furl.join("?"); + }else{ + return furl.join(""); + } +} +WST.addCart = function(goodsId){ + // if(window.conf.IS_LOGIN==0){ + // WST.loginWindow(); + // return; + // } + $.post(WST.U('home/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data,1); + if(json.status==1){ + WST.msg(json.msg,{icon:1,time:600,shade:false}); + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + } + getRightCart(); + }else{ + if(json.status==-999){ + + WST.loginWindow(); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + } + }); +} + +WST.delCart = function(id){ + WST.confirm({content:'您确定要删除该商品吗?',yes:function(index){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/carts/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('home/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.dropDownLayerCart = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + WST.checkCart(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function (event) { + event.stopPropagation(); + $(this).show(); + }, function (event) { + event.stopPropagation(); + $(this).hide(); + }); +} +WST.delCheckCart = function(id,func){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + WST.checkCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.checkCart = function(){ + $('#list-carts2').html(''); + $('#list-carts3').html(''); + $('#list-carts').html('<div style="padding:32px 0px 77px 112px;"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</div>'); + $.post(WST.U('home/carts/getCartInfo'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.list.length>0){ + var gettpl = document.getElementById('list-cart').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-carts').html(html); + }); + $('#list-carts2').html('<div class="comm" id="list-comm">&nbsp;&nbsp;共<span>'+json.goodsTotalNum+'</span>件商品<span class="span2">¥'+json.goodsTotalMoney+'</span></div>'); + $('#list-carts3').html('<a href="'+window.conf.ROOT+'/home/carts/index" class="btn btn-3">去购物车结算</a>'); + $('.goodsImgc').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.ROOT+'/'+window.conf.GOODS_LOGO});//商品默认图片 + if(json.list.length>5){ + $('#list-carts').css('overflow-y','scroll').css('height','416'); + } + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + } + $('#goodsTotalNum').html(json.goodsTotalNum); + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + $('#goodsTotalNum').html(0); + } + }); +} +WST.changeIptNum = function(diffNum,iptId,btnId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var tmp = 0; + if(maxVal<minVal){ + tmp = maxVal; + maxVal = minVal; + minVal = tmp; + } + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + btnId = btnId.split(','); + $(btnId[0]+suffix).css('color','#666'); + $(btnId[1]+suffix).css('color','#666'); + if(minVal>=num){ + num=minVal; + $(btnId[0]+suffix).css('color','#ccc'); + } + if(maxVal<=num){ + num=maxVal; + $(btnId[1]+suffix).css('color','#ccc'); + } + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.shopQQ = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a href="tencent://message/?uin='+val+'&Site=QQ交谈&Menu=yes">', + '<img border="0" src="http://wpa.qq.com/pa?p=1:'+val+':7" alt="QQ交谈" width="71" height="24" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.shopWangWang = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid='+val+'&siteid=cntaobao&status=1&charset=utf-8">', + '<img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid='+val+'&site=cntaobao&s=1&charset=utf-8" alt="和我联系" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.cancelFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var param = {},str = '商品'; + param.id = fId; + param.type = type; + str = (type==1)?'店铺':'商品'; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav').addClass('j-fav2'); + $(obj).html('关注'+str)[0].onclick = function(){ + WST.addFavorite(obj,type,id,fId); + }; + }else{ + WST.msg(json.msg,{icon:5}); + } + }); +} + + +WST.addFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + $.post(WST.U('home/favorites/add'),{type:type,id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav2').addClass('j-fav'); + $(obj).html('已关注')[0].onclick = function(){ + WST.cancelFavorite(obj,type,id,json.data.fId); + }; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} +/**记录广告点击**/ +WST.recordClick = function(adId){ + $.post(WST.U('home/ads/recordClick'),{id:adId},function(data){}); +} +/** + * 获取用户信息 + */ +WST.getSysMessages = function(val){ + if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/index/getSysMessages'),{tasks:val},function(data){ + var json = WST.toJson(data); + if(json.message){ + $('#wst-user-messages').html(json.message.num); + if(parseInt(json.message.num,10)>0){ + $('#wst-user-messages').css('color','red'); + if($('.j-message-count')[0])$('.j-message-count').show().html(json.message.num); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).addClass('wst-msg-tips-box').html(json.message.num); + if($('#mId_'+json.message.sid)[0])$('#mId_'+json.message.sid).addClass('wst-msg-tips-box').html(json.message.num); + }else{ + $('#wst-user-messages').css('color','#666'); + if($('.j-message-count')[0])$('.j-message-count').hide(); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).removeClass('wst-msg-tips-box').html(''); + } + } + if(json.cart){ + $('#goodsTotalNum').html(json.cart.goods); + if(json.cart.goods>0){ + if($('.j-cart-count')[0])$('.j-cart-count').show().html(json.cart.goods); + }else{ + if($('.j-cart-count')[0])$('.j-cart-count').hide().html(''); + } + } + if(json.userorder){ + for(var key in json.userorder){ + if($('#mId_'+key)[0]){ + if(json.userorder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.userorder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + if(json.shoporder){ + for(var key in json.shoporder){ + if($('#mId_'+key)[0]){ + if(json.shoporder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.shoporder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + }); +} +WST.position = function(mid,mtype){ + $.post(WST.U('home/index/position'),{menuId:mid,menuType:mtype},function(data){}); +} +//关闭顶部广告 +WST.closeAds = function(t){ + $(t).parent().remove(); +} +WST.closeIframe = function(){ + var index = parent.layer.getFrameIndex(window.name); + parent.layer.close(index); +} +WST.shopsCats = function(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} + +WST.slides = function(objId){ + var slide = $(objId), li = slide.find("li"); + var slidecontrols = $(objId+'-controls').eq(0), + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + span.bind("mouseout", function() { + index++; + if (index >= span.length) + index = 0; + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} + +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); + diff --git a/hyhproject/home2/view/default/js/common.js b/hyhproject/home2/view/default/js/common.js new file mode 100755 index 0000000..379d1cf --- /dev/null +++ b/hyhproject/home2/view/default/js/common.js @@ -0,0 +1,1066 @@ +$(function() { + $('.goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + $('.usersImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.USER_LOGO});//会员默认头像 +}); +WST.initVisitor = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.dropDownLayerCart(".wst-cart-box",".wst-cart-boxs"); + WST.searchIpt(); + WST.showCategoryNavs(); + WST.Sidebar(); + WST.getSysMessages('message,cart'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart'); + },10000); + } +} +WST.initUserCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.dropDownLayerCart(".wst-lite-cart",".wst-lite-carts"); + WST.getSysMessages('message,cart,userorder'); + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,cart,userorder'); + },10000); + } +} +WST.initShopCenter = function(){ + WST.dropDownLayer(".j-dorpdown",".j-dorpdown-layer"); + WST.dropDownLayer(".drop-info",".wst-tag"); + WST.searchIpt(); + WST.getSysMessages('message,shoporder'); + if(WST.conf.MESSAGE_BOX!=''){ + var msg = WST.conf.MESSAGE_BOX.split('||'); + for(var i=0;i<msg.length;i++){ + WST.open({type: 1, + title: '系统提示', + shade: false, + area: ['340px', '215px'], + offset: 'rb', + time: 20000, + anim: 4, + content: "<div class='j-messsage-box'>"+msg[i]+"</div>", + }) + } + } + if(WST.conf.TIME_TASK=='1'){ + setInterval(function(){ + WST.getSysMessages('message,shoporder'); + },10000); + } +} +WST.searchIpt = function(){ + $('.j-search-box').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + },function(){ + $(".j-type-list").hide(); + $(this).css({"border-left":"2px solid #e23c3d"}); + $(this).find('i').removeClass('over').addClass('arrow'); + }); + + $('j-type-list').hover(function(){ + $(".j-type-list").show(); + $(this).find('i').removeClass('arrow').addClass('over'); + $(this).css({"border-left":"2px solid #e23c3d"}); + }); + + $(".j-type-list div").click(function(){ + $("#search-type").val($(this).attr("data")); + $(".j-search-type span").html($(this).html()); + if($(this).attr("data")==1){ + $(this).attr("data",0); + $(this).html('商品'); + $('#search-ipt').attr('placeholder',$('#adsShopWordsSearch').val()); + }else{ + $(this).attr("data",1); + $(this).html('店铺'); + $('#search-ipt').attr('placeholder',$('#adsGoodsWordsSearch').val()); + } + $(".j-type-list").hide(); + $(".j-search-type").find('i').removeClass('over').addClass('arrow'); + }); +} +WST.search = function(){ + if($("#search-type").val()==1){ + WST.shopSearch($.trim($('#search-ipt').val())); + }else{ + WST.goodsSearch($.trim($('#search-ipt').val())); + } +} +WST.shopSearch = function(v){ + location.href = WST.U('home/shops/shopstreet','keyword='+v,true); +} +WST.goodsSearch = function(v){ + location.href = WST.U('home/goods/search','keyword='+v,true); +} +WST.showCategoryNavs = function(){ + if($('.wst-filters')[0]){ + $(".drop-down").hover(function(){ + $(this).addClass("hover"); + },function(){ + $(this).removeClass("hover"); + }); + $(".dorp-down-layer").hover(function(){ + $(this).prev().addClass("hover"); + },function(){ + $(this).prev().removeClass("hover"); + }); + } +} +WST.Sidebar = function(){ + if(!$('#wst-categorys')[0])return; + + if(!$('#wst-categorys').hasClass('j-index')){ + WST.dropDownLayer("#wst-categorys",".j-cate-dd"); + } + $(".dd-inner").children(".item").hover(function() { //一级导航悬浮 + $('.categeMenuImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//默认图片 + $(this).parent().find('.over-cat').show(); + + $(this).addClass("hover").siblings(".item").removeClass("hover"); + var index = $(this).index(); + $(".dorpdown-layer").children(".item-sub").hide(); + $(".dorpdown-layer").children(".item-sub").eq(index).show(); + + var start = $('.j-cate-dt').offset().top; + var obj = $('#index_menus_sub'); + var sh = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条距离顶部高度 + if(sh>start+36){ + var start = sh-start; + }else{ + var start = 36; + } + //obj.stop().animate({ "top": start }); + obj.css('top',start); + + + },function(){ + $(this).parent().find('.over-cat').hide(); + }); + + + + $('.over-cat-icon').parent().mouseover(function(){ + $(this).find('.over-cat-icon').addClass('over-cat-icon-hover'); + }); + $('.over-cat-icon').parent().mouseout(function(){ + $(this).find('.over-cat-icon').removeClass('over-cat-icon-hover'); + }); + + $(".dd-inner").children(".item").mouseover(function() { + + $('.dd-inner').find('.over-cat').show(); + + var iCon = $(this).attr('id'); + $('.'+iCon).addClass(iCon+'-hover'); + }); + $(".dd-inner").children(".item").mouseout(function() { + + $('.dd-inner').find('.over-cat').hide(); + + var iCon = $(this).attr('id'); + $('.'+iCon).removeClass(iCon+'-hover'); + }); + + $("#index_menus_sub").hover(function(){ + $('.dd-inner').find('.over-cat').show(); + $(this).show(); + },function(){ + $(this).hide(); + $('.dd-inner').find('.over-cat').hide(); + }); + $(".dd-inner").hover(function() { //整个导航菜单悬浮,是否显示二级导航到出厂 + $("#index_menus_sub").show(); + + }, function() { + $("#index_menus_sub").hide(); + $('.item').removeClass("hover"); + }) + $("#index_menus_sub").children(".item-sub").hover(function() { //二级导航悬浮 + var index = $(this).index(); + $(".dd-inner").children(".item").eq(index).addClass("hover"); + $("#index_menus_sub").show(); + var i = index+1; + $('.cat-icon-'+i).addClass('cat-icon-'+i+'-hover'); + }, function() { + $("#index_menus_sub").hide(); + $(".dd-inner").children(".item").removeClass("hover"); + var index = $(this).index(); + var i = index+1; + $('.cat-icon-'+i).removeClass('cat-icon-'+i+'-hover'); + + }); + + $('.fore2').hover(function(){ + $(this).children('dt').css('background-color','#ff6a53'); + },function(){ + $(this).children('dt').css('background-color',''); + }); +} +WST.dropDownLayer = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function () { + $(this).find(layer).show(); + }, function () { + $(this).find(layer).hide(); + }); +} + + +WST.tips = function(content, selector, options){ + + var opts = {}; + opts = $.extend(opts, {tips:1, time:2000, maxWidth: 260}, options); + return layer.tips(content, selector, opts); +} +WST.open = function(options){ + var opts = {}; + opts = $.extend(opts, {offset:'100px'}, options); + return layer.open(opts); +} +WST.confirm = function(options){ + var opts = {}; + opts = $.extend(opts, {title:'系统提示',offset:'200px'}, options); + return layer.confirm(opts.content,{icon: 'wst3', title:opts.title,offset:opts.offset},options.yes,options.cancel); +} +WST.load = function(options){ + var opts = {}; + opts = $.extend(opts,{time:0,icon:'wstloading',shade: [0.4, '#000000'],offset: '200px',area: ['280px', '65px']},options); + return layer.msg(opts.msg, opts); +} +WST.msg = function(msg, options, func){ + var opts = {}; + if(options){ + if(options.icon==1){ + options.icon='wst1'; + }else if(options.icon==2 || options.icon==5){ + options.icon='wst2'; + }else if(options.icon==3){ + options.icon='wst3'; + } + } + //有抖動的效果,第二位是函數 + if(typeof(options)!='function'){ + opts = $.extend(opts,{time:1000,shade: [0.4, '#000000'],offset: '200px'},options); + return layer.msg(msg, opts, func); + }else{ + return layer.msg(msg, options); + } +} +WST.toJson = function(str,noAlert){ + var json = {}; + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(typeof(noAlert)=='undefined'){ + if(json.status && json.status=='-999'){ + WST.msg('对不起,您已经退出系统!请重新登录',{icon:5},function(){ + if(window.parent){ + window.parent.location.reload(); + }else{ + location.reload(); + } + }); + }else if(json.status && json.status=='-998'){ + WST.msg('对不起,您没有操作权限,请与管理员联系'); + return; + } + } + }catch(e){ + WST.msg("系统发生错误:"+e.getMessage,{icon:5}); + json = {}; + } + return json; +} + +//刷新验证码 +WST.logout = function(){ + $.post(WST.U('home/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/index/index'); + }); +} + +/** +* 上传图片 +*/ +WST.upload = function(opts){ + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('home/index/uploadPic')},opts); + var uploader = WebUploader.create(_opts); + uploader.on('uploadSuccess', function( file,response ) { + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + + +WST.goTo = function(obj){ + location.href = $(obj).attr('data'); +} +WST.getVerify = function(id){ + $(id).attr('src',WST.U('home/index/getVerify','rnd='+Math.random())); +} +WST.loginWindow = function(){ + WST.currentUrl(); + $.post(WST.U('home/users/toLoginBox'),{},function(data){ + WST.open({type:1,area:['550px','360px'],offset:'auto',title:'用户登录',content:data}); + }); +} +WST.currentUrl = function(url){ + if(!url)var url = window.location.href; + $.post(WST.U('home/index/currenturl'),{url:url},function(data){}); +} +/********************* 选项卡切换隐藏 **********************/ +$.fn.TabPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav li').click(function(){ + $(this).addClass("on").siblings().removeClass(); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav li').eq(opts.tab).click(); +} +/** + * 去除url中指定的参数(用于分页) + */ +WST.splitURL = function(spchar){ + var url = location.href; + var urlist = url.split("?"); + var furl = new Array(); + var fparams = new Array(); + furl.push(urlist[0]); + if(urlist.length>1){ + var urlparam = urlist[1]; + params = urlparam.split("&"); + for(var i=0; i<params.length; i++){ + var vparam = params[i]; + var param = vparam.split("="); + if(param[0]!=spchar){ + fparams.push(vparam); + } + } + if(fparams.length>0){ + furl.push(fparams.join("&")); + } + + } + if(furl.length>1){ + return furl.join("?"); + }else{ + return furl.join(""); + } +} +WST.addCart = function(goodsId){ + // if(window.conf.IS_LOGIN==0){ + // WST.loginWindow(); + // return; + // } + $.post(WST.U('home/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data,1); + if(json.status==1){ + WST.msg(json.msg,{icon:1,time:600,shade:false}); + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + } + getRightCart(); + }else{ + if(json.status==-999){ + + WST.loginWindow(); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + } + }); +} + +WST.delCart = function(id){ + WST.confirm({content:'您确定要删除该商品吗?',yes:function(index){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/carts/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('home/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.dropDownLayerCart = function(dropdown,layer){ + $(dropdown).hover(function () { + $(this).find(layer).show(); + WST.checkCart(); + }, function () { + $(this).find(layer).hide(); + }); + $(layer).hover(function (event) { + event.stopPropagation(); + $(this).show(); + }, function (event) { + event.stopPropagation(); + $(this).hide(); + }); +} +WST.delCheckCart = function(id,func){ + $.post(WST.U('home/carts/delCart'),{id:id,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + WST.checkCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +WST.checkCart = function(){ + $('#list-carts2').html(''); + $('#list-carts3').html(''); + $('#list-carts').html('<div style="padding:32px 0px 77px 112px;"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</div>'); + $.post(WST.U('home/carts/getCartInfo'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.list.length>0){ + var gettpl = document.getElementById('list-cart').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-carts').html(html); + }); + $('#list-carts2').html('<div class="comm" id="list-comm">&nbsp;&nbsp;共<span>'+json.goodsTotalNum+'</span>件商品<span class="span2">¥'+json.goodsTotalMoney+'</span></div>'); + $('#list-carts3').html('<a href="'+window.conf.ROOT+'/home/carts/index" class="btn btn-3">去购物车结算</a>'); + $('.goodsImgc').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + if(json.list.length>5){ + $('#list-carts').css('overflow-y','scroll').css('height','416'); + } + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + } + $('#goodsTotalNum').html(json.goodsTotalNum); + }else{ + $('#list-carts').html('<p class="carts">购物车中空空如也,赶紧去选购吧~</p>'); + $('#goodsTotalNum').html(0); + } + }); +} +WST.changeIptNum = function(diffNum,iptId,btnId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var tmp = 0; + if(maxVal<minVal){ + tmp = maxVal; + maxVal = minVal; + minVal = tmp; + } + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + btnId = btnId.split(','); + $(btnId[0]+suffix).css('color','#666'); + $(btnId[1]+suffix).css('color','#666'); + if(minVal>=num){ + num=minVal; + $(btnId[0]+suffix).css('color','#ccc'); + } + if(maxVal<=num){ + num=maxVal; + $(btnId[1]+suffix).css('color','#ccc'); + } + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.shopQQ = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a href="tencent://message/?uin='+val+'&Site=QQ交谈&Menu=yes">', + '<img border="0" src="http://wpa.qq.com/pa?p=1:'+val+':7" alt="QQ交谈" width="71" height="24" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.shopWangWang = function(val){ + if(WST.blank(val) !=''){ + return [ + '<a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid='+val+'&siteid=cntaobao&status=1&charset=utf-8">', + '<img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid='+val+'&site=cntaobao&s=1&charset=utf-8" alt="和我联系" />', + '</a>' + ].join(''); + }else{ + return ''; + } +} +WST.cancelFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var param = {},str = '商品'; + param.id = fId; + param.type = type; + str = (type==1)?'店铺':'商品'; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav').addClass('j-fav2'); + $(obj).html('关注'+str)[0].onclick = function(){ + WST.addFavorite(obj,type,id,fId); + }; + }else{ + WST.msg(json.msg,{icon:5}); + } + }); +} + + +WST.addFavorite = function(obj,type,id,fId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + $.post(WST.U('home/favorites/add'),{type:type,id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + $(obj).removeClass('j-fav2').addClass('j-fav'); + $(obj).html('已关注')[0].onclick = function(){ + WST.cancelFavorite(obj,type,id,json.data.fId); + }; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/** + * 循环调用及设置商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param childIds 分类路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetGoodsCats = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((opts.childIds[0]==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastgoodscat'); + tidObj.attr('lastgoodscat',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetGoodsCats(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} + +/** + * 循环创建商品分类 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITGoodsCats = function(opts){ + opts.className = opts.className?opts.className:"j-goodsCats"; + var obj = $('#'+opts.id); + obj.attr('lastgoodscat',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastgoodscat'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastgoodscat',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/goodscats/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + opts.isLast = false; + json = json.data; + var html = []; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + var cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastgoodscat'); + } + WST.ITGoodsCats(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllGoodsCatVals = function(srcObj,className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).attr('id')+'_'+$(this).val(); + }); + goodsCatId = goodsCatId.replace(srcObj+'_',''); + return goodsCatId.split('_'); +} +/** + * 获取最后分类值 + */ +WST.ITGetGoodsCatVal = function(className){ + var goodsCatId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastgoodscat')=='1')goodsCatId = $(this).val(); + }); + return goodsCatId; +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + * @param isRequire 是否要求必填 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = parseInt(obj.attr('level'),10)+1; + $("select[id^='"+opts.id+"_']").remove(); + if(opts.isRequire)$('.msg-box[for^="'+opts.id+'_"]').remove(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + opts.lastVal = opts.val; + if(opts.val==''){ + obj.removeAttr('lastarea'); + var lastId = 0,level = 0,tmpLevel = 0,lasObjId; + $('.'+opts.className).each(function(){ + tmpLevel = parseInt($(this).attr('level'),10); + if(level <= tmpLevel && $(this).val()!=''){ + level = tmpLevel; + lastId = $(this).val(); + lasObjId = $(this).attr('id'); + } + }) + $('#'+lasObjId).attr('lastarea',1); + opts.id = lasObjId; + opts.val = $('#'+lasObjId).val(); + opts.isLast = true; + opts.lastVal = opts.val; + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + return; + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value='' >-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"'>"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + $("#"+tid).change(function(){ + opts.id = tid; + opts.val = $(this).val(); + if(opts.val!=''){ + obj.removeAttr('lastarea'); + } + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); +} +/** + * 循环调用及设置地区 + * @param id 当前地区ID + * @param val 当前地区值 + * @param childIds 地区路径值【数组】 + * @param isRequire 是否要求必填 + * @param className 样式,方便将来获取值 + * @param beforeFunc 运行前回调函数 + * @param afterFunc 运行后回调函数 + */ +WST.ITSetAreas = function(opts){ + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + var level = $('#'+opts.id).attr('level')?(parseInt($('#'+opts.id).attr('level'),10)+1):1; + if(opts.childIds.length>0){ + opts.childIds.shift(); + if(opts.beforeFunc){ + if(typeof(opts.beforeFunc)=='function'){ + opts.beforeFunc({id:opts.id,val:opts.val}); + }else{ + var fn = window[opts.beforeFunc]; + fn({id:opts.id,val:opts.val}); + } + } + $.post(WST.U('home/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + html.push("<select id='"+tid+"' level='"+level+"' class='"+opts.className+"' "+(opts.isRequire?" data-rule='required;' ":"")+">"); + html.push("<option value=''>-请选择-</option>"); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<option value='"+tmp.areaId+"' "+((opts.childIds[0]==tmp.areaId)?"selected":"")+">"+tmp.areaName+"</option>"); + } + html.push('</select>'); + $(html.join('')).insertAfter(obj); + var tidObj = $('#'+tid); + if(tidObj.val()!=''){ + obj.removeAttr('lastarea'); + tidObj.attr('lastarea',1); + opts.id = tid; + opts.val = tidObj.val(); + WST.ITSetAreas(opts); + } + tidObj.change(function(){ + opts.id = tid; + opts.val = $(this).val(); + WST.ITAreas(opts); + }) + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + } + if(opts.afterFunc){ + if(typeof(opts.afterFunc)=='function'){ + opts.afterFunc(opts); + }else{ + var fn = window[opts.afterFunc]; + fn(opts); + } + } + }); + } +} +/** + * 获取最后地区的值 + */ +WST.ITGetAreaVal = function(className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).val(); + }); + return areaId; +} +/** + * 获取最后已选分类的id + */ +WST.ITGetAllAreaVals = function(srcObj,className){ + var areaId = ''; + $('.'+className).each(function(){ + if($(this).attr('lastarea')=='1')areaId = $(this).attr('id')+'_'+$(this).val(); + }); + areaId = areaId.replace(srcObj+'_',''); + return areaId.split('_'); +} +/**记录广告点击**/ +WST.recordClick = function(adId){ + $.post(WST.U('home/ads/recordClick'),{id:adId},function(data){}); +} +/** + * 获取用户信息 + */ +WST.getSysMessages = function(val){ + if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/index/getSysMessages'),{tasks:val},function(data){ + var json = WST.toJson(data); + if(json.message){ + $('#wst-user-messages').html(json.message.num); + if(parseInt(json.message.num,10)>0){ + $('#wst-user-messages').css('color','red'); + if($('.j-message-count')[0])$('.j-message-count').show().html(json.message.num); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).addClass('wst-msg-tips-box').html(json.message.num); + if($('#mId_'+json.message.sid)[0])$('#mId_'+json.message.sid).addClass('wst-msg-tips-box').html(json.message.num); + }else{ + $('#wst-user-messages').css('color','#666'); + if($('.j-message-count')[0])$('.j-message-count').hide(); + if($('#mId_'+json.message.id)[0])$('#mId_'+json.message.id).removeClass('wst-msg-tips-box').html(''); + } + } + if(json.cart){ + $('#goodsTotalNum').html(json.cart.goods); + if(json.cart.goods>0){ + if($('.j-cart-count')[0])$('.j-cart-count').show().html(json.cart.goods); + }else{ + if($('.j-cart-count')[0])$('.j-cart-count').hide().html(''); + } + } + if(json.userorder){ + for(var key in json.userorder){ + if($('#mId_'+key)[0]){ + if(json.userorder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.userorder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + if(json.shoporder){ + for(var key in json.shoporder){ + if($('#mId_'+key)[0]){ + if(json.shoporder[key]!='0'){ + $('#mId_'+key).addClass('wst-msg-tips-box').html(json.shoporder[key]); + }else{ + $('#mId_'+key).removeClass('wst-msg-tips-box').html(''); + } + } + } + } + }); +} +WST.position = function(mid,mtype){ + $.post(WST.U('home/index/position'),{menuId:mid,menuType:mtype},function(data){}); +} +//关闭顶部广告 +WST.closeAds = function(t){ + $(t).parent().remove(); +} +WST.closeIframe = function(){ + var index = parent.layer.getFrameIndex(window.name); + parent.layer.close(index); +} +WST.shopsCats = function(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} + +WST.slides = function(objId){ + var slide = $(objId), li = slide.find("li"); + var slidecontrols = $(objId+'-controls').eq(0), + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + span.bind("mouseout", function() { + index++; + if (index >= span.length) + index = 0; + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} + +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); + diff --git a/hyhproject/home2/view/default/js/findpass.js b/hyhproject/home2/view/default/js/findpass.js new file mode 100755 index 0000000..d9cd21f --- /dev/null +++ b/hyhproject/home2/view/default/js/findpass.js @@ -0,0 +1,163 @@ +var time = 0; +var isSend = false; +$(function(){ + //第一步 + $('#forgetPwdForm').validator({ + valid: function(form){ + forgetPwd(); + } + }); + //手机发送验证 + $('#phoneVerify').validator({ + valid: function(form){ + phoneVerify2(); + } + }); + //重置密码 + $('#forgetPwdForm3').validator({ + fields: { + loginPwd: { + rule:"required;length[6~16]", + msg:{required:"请输入新密码"}, + tip:"请输入新密码" + }, + repassword: { + rule:"required;length[6~16];match[loginPwd]", + msg:{required:"请再次输入新密码",match:"两次输入密码不匹配"}, + tip:"请再次输入新密码" + }, + }, + valid: function(form){ + forgetPwd(); + } + }); +}) +function forgetPwd(){ + var params = WST.getParams('.ipt'); + if(window.conf.IS_CRYPT=='1' && params.step=='3'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.repassword = rsa.encrypt(params.repassword); + } + var step = $('#step').val(); + var modes = $('#modes').val(); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/findPass'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + setTimeout(function(){ + if(step==1){ + location.href=WST.U('home/users/forgetpasst','',true); + }else if(step==2){ + if(modes==1){ + location.href=json.url; + }else{ + disableBtn(); + } + }else if(step==3){ + location.href=WST.U('home/users/forgetpassf','',true); + } + },1000); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); +} + +//第二步 +$('#type').change(function(){ + if ($('#type').val() == 'phone') { + $('.phone-verify').show(); + $('.email-verify').hide(); + $('#modes').val(1); + }else{ + $('.phone-verify').hide(); + $('.email-verify').show(); + $('#modes').val(2); + } +}) +function phoneVerify(){ + if(window.conf.SMS_VERFY==1){ + WST.open({type: 1,title:"请输入验证码",shade: [0.6, '#000'],border: [0],content: $('#phoneVerify'),area: ['500px', '160px']}); + }else{ + phoneVerify2(); + } +} +function phoneVerify2(){ + WST.msg('正在发送短信,请稍后...',{time:600000}); + var time = 0; + var isSend = false; + var params = WST.getParams('.ipt'); + $.post(WST.U('home/users/getfindPhone'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(isSend )return; + isSend = true; + if(json.status!=1){ + WST.msg(json.msg, {icon: 5}); + WST.getVerify2('#verifyImg2'); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注册查收'); + layer.closeAll('page'); + time = 120; + $('#timeObtain').attr('disabled', 'disabled').css('background','#e8e6e6'); + $('#timeObtain').html('获取手机验证码(120)').css('width','130px'); + var task = setInterval(function(){ + time--; + $('#timeObtain').html('获取手机验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeObtain').html("重新获取验证码").css('width','100px'); + $('#timeObtain').removeAttr('disabled').css('background','#e23e3d'); + } + },1000); + } + }); +} +function forgetPhone(){ + if(!$('#Checkcode').isValid())return; + forgetPwd(); +} +function forgetEmail(){ + if(!$('#verifyCode').isValid())return; + forgetPwd(); +} +/*重置密码*/ +function resetPass(){ + if(!$('#secretCode').isValid())return; + var secretCode = $('#secretCode').val(); + $.post(WST.U('home/users/forgetPasss'),{secretCode:secretCode},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + location.href=WST.U('home/users/resetpass','',true); + }else{ + WST.msg(json.msg,{icon:2}); + return false; + } + }) +} + +/*禁用发送按钮*/ +function disableBtn(){ + time = 120; + $('#sendEmailBtn').attr('disabled', 'disabled').css({'background':'#e8e6e6','color':'#a7a7a7'}); + $('#sendEmailBtn').html('获取邮箱验证码(120)').css('width','130px'); + var task = setInterval(function(){ + time--; + $('#sendEmailBtn').html('获取邮箱验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#sendEmailBtn').html("重新获取验证码").css('width','100px'); + $('#sendEmailBtn').removeAttr('disabled').css({'background':'#f0efef','color':'#110f0f'}); + } + },1000); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/goods.js b/hyhproject/home2/view/default/js/goods.js new file mode 100755 index 0000000..84f7c35 --- /dev/null +++ b/hyhproject/home2/view/default/js/goods.js @@ -0,0 +1,374 @@ +$(function(){ + WST.dropDownLayer(".item",".dorp-down-layer"); + $('.item-more').click(function(){ + if($(this).attr('v')==1){ + $('.hideItem').show(300); + $(this).find("span").html("收起"); + $(this).find("i").attr({"class":"drop-up"}); + $(this).attr('v',0); + }else{ + $('.hideItem').hide(300); + $(this).find("span").html("更多选项"); + $(this).find("i").attr({"class":"drop-down-icon"}); + $(this).attr('v',1); + } + }); + + $(".item-more").hover(function(){ + if($(this).find("i").hasClass("drop-down-icon")){ + $(this).find("i").attr({"class":"down-hover"}); + }else{ + $(this).find("i").attr({"class":"up-hover"}); + } + + },function(){ + if($(this).find("i").hasClass("down-hover")){ + $(this).find("i").attr({"class":"drop-down"}); + }else{ + $(this).find("i").attr({"class":"drop-up"}); + } + }); + if(goodsInfo.sku){ + var specs,dv; + for(var key in goodsInfo.sku){ + if(goodsInfo.sku[key].isDefault==1){ + specs = key.split(':'); + $('.j-option').each(function(){ + dv = $(this).attr('data-val') + if($.inArray(dv,specs)>-1){ + $(this).addClass('j-selected'); + } + }) + $('#buyNum').attr('data-max',goodsInfo.sku[key].specStock); + } + } + }else{ + $('#buyNum').attr('data-max',goodsInfo.goodsStock); + } + checkGoodsStock(); + //图片放大镜效果 + CloudZoom.quickStart(); + imagesMove({id:'.goods-pics',items:'.items'}); + //选择规格 + $('.spec .j-option').click(function(){ + $(this).addClass('j-selected').siblings().removeClass('j-selected'); + checkGoodsStock(); + }); + fixedbar(); + $('#tab').TabPanel({tab:0,callback:function(no){ + if(no==1)queryByPage(); + if(no==2)queryConsult(); + }}); + contrastGoods(1,0,2); + // 取消'手机购买'click事件 + $('#wx_qrcode').unbind(); +}); +function fixedbar(){ + var offsetTop = $("#goodsTabs").offset().top; + $(window).scroll(function() { + var scrollTop = $(document).scrollTop(); + if (scrollTop > offsetTop){ + $('#addCart2').show(); + $("#goodsTabs").css("position","fixed"); + $("#wx_qrcode").addClass('wx_qrcode_fixed'); + }else{ + $('#addCart2').hide(); + $("#goodsTabs").css("position", "static"); + $("#wx_qrcode").removeClass('wx_qrcode_fixed'); + } + }); +} +function checkGoodsStock(){ + var specIds = [],stock = 0,goodsPrice=0,marketPrice=0,goodsHuibao=0; + + if(goodsInfo.isSpec==1){ + $('.j-selected').each(function(){ + specIds.push(parseInt($(this).attr('data-val'),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + stock = goodsInfo.sku[specIds.join(':')].specStock; + marketPrice = goodsInfo.sku[specIds.join(':')].marketPrice; + goodsPrice = goodsInfo.sku[specIds.join(':')].specPrice; + goodsHuibao =Math.round(goodsInfo.sku[specIds.join(':')].specPrice * 0.8 * 100) / 100; + + } + }else{ + stock = goodsInfo.goodsStock; + marketPrice = goodsInfo.marketPrice; + goodsPrice = goodsInfo.goodsPrice; + } + $('#goods-stock').html(stock); + $('#j-market-price').html('¥'+marketPrice); + $('#j-shop-price').html('¥'+goodsPrice); + if(goodsHuibao>0){ + $('#j-shop-huibao').html('¥'+goodsHuibao); + } + + if(stock<=0){ + $('#addBtn').addClass('disabled'); + $('#buyBtn').addClass('disabled'); + }else{ + $('#addBtn').removeClass('disabled'); + $('#buyBtn').removeClass('disabled'); + } +} + +function imagesMove(opts){ + var tempLength = 0; //临时变量,当前移动的长度 + var viewNum = 5; //设置每次显示图片的个数量 + var moveNum = 2; //每次移动的数量 + var moveTime = 300; //移动速度,毫秒 + var scrollDiv = $(opts.id+" "+opts.items+" ul"); //进行移动动画的容器 + var scrollItems = $(opts.id+" "+opts.items+" ul li"); //移动容器里的集合 + var moveLength = scrollItems.eq(0).width() * moveNum; //计算每次移动的长度 + var countLength = (scrollItems.length - viewNum) * scrollItems.eq(0).width(); //计算总长度,总个数*单个长度 + + //下一张 + $(opts.id+" .next").bind("click",function(){ + if(tempLength < countLength){ + if((countLength - tempLength) > moveLength){ + scrollDiv.animate({left:"-=" + moveLength + "px"}, moveTime); + tempLength += moveLength; + }else{ + scrollDiv.animate({left:"-=" + (countLength - tempLength) + "px"}, moveTime); + tempLength += (countLength - tempLength); + } + } + }); + //上一张 + $(opts.id+" .prev").bind("click",function(){ + if(tempLength > 0){ + if(tempLength > moveLength){ + scrollDiv.animate({left: "+=" + moveLength + "px"}, moveTime); + tempLength -= moveLength; + }else{ + scrollDiv.animate({left: "+=" + tempLength + "px"}, moveTime); + tempLength = 0; + } + } + }); +} + + +/****************** 商品评价 ******************/ +function showImg(id){ + layer.photos({ + photos: '#img-file-'+id + }); +} +function apprfilter(type){ + $('.appr-filterbox li a').removeClass('curr'); + $('#filtertype').val(type); + queryByPage(1); +} + +var _first=true; +function queryByPage(p){ + var params = {}; + params.page = p; + params.goodsId = goodsInfo.id; + params.anonymous = 1; + params.type = $('#filtertype').val(); + $.post(WST.U('home/goodsappraises/getById'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#ga-box').html(html); + for(var g=0;g<=json.data.Rows.length;g++){ + showImg(g); + } + }); + // 各评价数. + $('#totalNum').html(json.data.sum); + $('#bestNum').html(json.data.bestNum); + $('#goodNum').html(json.data.goodNum); + $('#badNum').html(json.data.badNum); + $('#picNum').html(json.data.picNum); + // 选中当前筛选条件 + $('#'+params.type).addClass('curr'); + if(_first && json.data.sum>0){ + // 好、中、差评率 + var best = parseInt(json.data.bestNum/json.data.sum*100); + var good = parseInt(json.data.goodNum/json.data.sum*100); + var bad = 100-best-good; + $('.best_percent').html(best); + $('.good_percent').html(good); + $('.bad_percent').html(bad); + // 背景色 + $('#best_percentbg').css({width:best+'%'}); + $('#good_percentbg').css({width:good+'%'}); + $('#bad_percentbg').css({width:bad+'%'}); + _first = false; + } + + $('.j-lazyImg').lazyload({ effect: "fadeIn",failurelimit : 10,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + $('.apprimg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.USER_LOGO});//会员默认头像 + laypage({ + cont: 'pager', + pages:json.data.TotalPage, + curr: json.data.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} +function addCart(type,iptId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + var goodsSpecId = 0; + if(goodsInfo.isSpec==1){ + var specIds = []; + $('.j-selected').each(function(){ + specIds.push($(this).attr('data-val')); + }); + + if(specIds.length==0){ + WST.msg('请选择你要购买的商品信息',{icon:2}); + } + specIds.sort(function(a,b){return a-b}); + if(goodsInfo.sku[specIds.join(':')]){ + goodsSpecId = goodsInfo.sku[specIds.join(':')].id; + } + } + var buyNum = $(iptId)[0]?$(iptId).val():1; + $.post(WST.U('home/carts/addCart'),{goodsId:goodsInfo.id,goodsSpecId:goodsSpecId,buyNum:buyNum,type:type,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + if(json.data && json.data.forward){ + location.href=WST.U('home/carts/'+json.data.forward); + }else{ + if(type==1){ + location.href=WST.U('home/carts/settlement'); + } + } + }); + getRightCart(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +/******************* 商品咨询 ********************/ + +// 提交商品咨询 +function consultCommit(){ + var params={}; + params.goodsId = goodsInfo.id; + $('[name="pointType"]').each(function(k,v){ + if(v.checked){params.consultType = v.value} + }) + if(!params.consultType){ + WST.msg('请选择咨询类别',{icon:2}); + return; + } + params.consultContent = $('#consultContent').val(); + if(params.consultContent == ''){ + WST.msg('请输入咨询内容',{icon:2}); + return; + } + if(params.consultContent.length<3 || params.consultContent.length>200){ + WST.msg('咨询内容应为3-200个字',{icon:2}); + return; + } + var load = WST.load({msg:'正在提交,请稍后...'}); + $.post(WST.U('home/goodsconsult/add'),params,function(responData){ + layer.close(load); + var json = WST.toJson(responData); + if(json.status==1){ + // 发布成功 + WST.msg(json.msg,{icon:1},function(){ + // 重置咨询输入框 + $('[name="pointType"]').map(function(k,v){v.checked=false;}); + $('#consultContent').val(' '); + queryConsult(0); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }) +} +function queryConsult(p){ + var params = {}; + params.page = p; + params.goodsId = goodsInfo.id; + params.type = $('#consultType').val(); + params.consultKey = $('#consultKey').val(); + $.post(WST.U('home/goodsconsult/listquery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data.Rows){ + var gettpl = document.getElementById('gclist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#consultBox').html(html); + }); + laypage({ + cont: 'consult-pager', + pages:json.data.TotalPage, + curr: json.data.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryConsult(e.curr); + } + } + }); + } + }); +} +//筛选咨询类别 +function filterConsult(obj, type){ + $('.gc-filter').each(function(k,v){ + $(v).removeClass('curr'); + }) + $(obj).addClass('curr'); + $('#consultType').val(type); + queryConsult(0); +} +//对比商品 +function contrastGoods(show,id,type){ + if(show==1){ + $.post(WST.U('home/goods/contrastGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(type==2 && json.data)$("#j-cont-frame").addClass('show'); + var gettpl = document.getElementById('colist').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#contrastList').html(html); + }); + $('.contImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }else{ + WST.msg(json.msg,{icon:2}); + } + if(type==1)$("#j-cont-frame").addClass('show'); + }); + }else{ + $("#j-cont-frame").removeClass('show'); + } +} +//删除 +function contrastDel(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + contrastGoods(1,0,1); + } + }); +} +function informs($goodsId){ + if(window.conf.IS_LOGIN==0){ + WST.loginWindow(); + return; + } + location.href=WST.U("home/informs/inform",'id='+$goodsId); + } diff --git a/hyhproject/home2/view/default/js/goodslist.js b/hyhproject/home2/view/default/js/goodslist.js new file mode 100755 index 0000000..c47d189 --- /dev/null +++ b/hyhproject/home2/view/default/js/goodslist.js @@ -0,0 +1,398 @@ +$(function(){ + $('.goodsImg2').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 100,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + WST.dropDownLayer(".item",".dorp-down-layer"); + $('.item-more').click(function(){ + if($(this).attr('v')==1){ + $('.hideItem').show(300,'swing',function(){ + showMoreBtn(); + }); + $(this).find("span").html("收起"); + $(this).find("i").attr({"class":"drop-up"}); + $(this).attr('v',0); + }else{ + $('.hideItem').hide(300); + $(this).find("span").html("更多选项"); + $(this).find("i").attr({"class":"drop-down-icon"}); + $(this).attr('v',1); + } + }); + + $(".item-more").hover(function(){ + if($(this).find("i").hasClass("drop-down-icon")){ + $(this).find("i").attr({"class":"down-hover"}); + }else{ + $(this).find("i").attr({"class":"up-hover"}); + } + + },function(){ + if($(this).find("i").hasClass("down-hover")){ + $(this).find("i").attr({"class":"drop-down"}); + }else{ + $(this).find("i").attr({"class":"drop-up"}); + } + }); + $('.img_list li img').mouseover(function(){ + // 商品列表小图切换 + $(this).parent().siblings().removeClass('curr'); + $(this).parent().addClass('curr'); + var oldImgDom = $(this).parent().parent().parent().children('.img').children().children(); + oldImgDom.attr('src',this.src.replace('_thumb','')); + }) +}); + +function goodsFilter(obj,vtype){ + if(vtype==1){ + $('#brand').val($(obj).attr('v')); + }else if(vtype==2){ + var price = $(obj).attr('v'); + price = price.split('_'); + $('#sprice').val(price[0]); + $('#eprice').val(price[1]); + }else if(vtype==3){ + $('#v_'+$(obj).attr('d')).val($(obj).attr('v')); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + vs.push($(obj).attr('d')); + $('#vs').val(vs.join(',')); + } + var ipts = WST.getParams('.sipt'); + if(vtype==4)ipts['order']='1'; + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); +} +function goodsOrder(orderby){ + if($('#orderBy').val()!=orderby){ + $('#order').val(1); + } + $('#orderBy').val(orderby); + goodsFilter(null,0); +} + + + +function removeFilter(id){ + if(id!='price'){ + $('#'+id).val(''); + if(id.indexOf('v_')>-1){ + id = id.replace('v_',''); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + var nvs = []; + for(var i=0;i<vs.length;i++){ + if(vs[i]!=id)nvs.push(vs[i]); + } + $('#vs').val(nvs.join(',')); + } + }else{ + $('#sprice').val(''); + $('#eprice').val(''); + } + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); +} +/*搜索列表*/ +function searchFilter(obj,vtype){ + if(vtype==1){ + $('#brand').val($(obj).attr('v')); + }else if(vtype==2){ + var price = $(obj).attr('v'); + price = price.split('_'); + $('#sprice').val(price[0]); + $('#eprice').val(price[1]); + }else if(vtype==3){ + $('#v_'+$(obj).attr('d')).val($(obj).attr('v')); + var vs = $('#vs').val(); + vs = (vs!='')?vs.split(','):[]; + vs.push($(obj).attr('d')); + $('#vs').val(vs.join(',')); + } + var ipts = WST.getParams('.sipt'); + if(vtype==4)ipts['order']='1'; + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/search',params.join('&'),true); +} +function searchOrder(orderby){ + if($('#orderBy').val()!=orderby){ + $('#order').val(1); + } + $('#orderBy').val(orderby); + searchFilter(null,0); +} + + +/*加入购物车*/ +$('.goods').hover(function(){ + $(this).find('.sale-num').hide(); + $(this).find('.p-add-cart').show(); +},function(){ + $(this).find('.sale-num').show(); + $(this).find('.p-add-cart').hide(); +}) + + + +/*发货地*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + if(ids[2]==1){ + $("li[id^="+preid+"_]").hide(); + $("#"+sid).show(); + }else if(ids[2]==2){ + $('#fl_1_3').hide(); + } + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("ul[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} +function choiceArea(t,pid){ + var areaName = $(t).find('a').html(); + var parent = $(t).parent().attr('id'); + var ids = parent.split("_"); + var preid = "#"+ids[0]+"_"+ids[1]+"_"+ids[2]; + if(ids[2]==3){ + $(preid).find('a').html(areaName); + // 执行发货地筛选 + $('#areaId').val(pid); + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + var url = ($(t).attr('search')==1)?'home/goods/search':'home/goods/lists'; + location.href=WST.U(url,params.join('&')); + }else{ + // 替换当前选中地区 + $(preid).find('a').html(areaName); + $(preid).removeClass('j-tab-selected'+ids[1]); + + + var next = parseInt(ids[2])+1; + var nextid = "#"+ids[0]+"_"+ids[1]+"_"+next; + $(nextid).show(); + $(nextid).addClass("j-tab-selected"+ids[1]); + // 替换下级地图标题 + $(nextid).html('<a href="javascript:void(0)">请选择</a>'); + + // 获取下级地区信息 + $.post(WST.U('home/areas/listQuery'),{parentId:pid},function(data){ + // 判断搜索页面 + var search = $(t).attr('search'); + if(search==1){search = 'search="1"';} + + var json = WST.toJson(data); + if(json.status==1){ + var html = ''; + $(json.data).each(function(k,v){ + + html +='<li onclick="choiceArea(this,'+v.areaId+')" '+search+' ><a href="javascript:void(0)">'+v.areaName+'</a></li>'; + }); + $(nextid+"_pl").html(html); + } + }); + + // 隐藏当前地区,显示下级地区 + var preid = ids[0]+"_"+ids[1]; + $("ul[id^="+preid+"_]").hide(); + $(nextid+"_pl").show(); + } +} + +/*************************************** 筛选 ******************************************/ +function showMoreBtn(){ + // 判断是否需要显示【更多】 + $('.item .content').each(function() { + if (this.scrollHeight > 34) { + $(this).parent().find('.extra .extra_more').css({visibility:'visible'}); + } + }); +} +$(function(){ + showMoreBtn(); +}) +function extra_show(obj){ + $(obj).addClass('extra_more_on'); + $(obj).parent().parent().find('ul').css({height:'auto'}); + $(obj).html('收起<i></i>'); + $(obj).attr('onClick','extra_hide(this)'); +} +function extra_hide(obj){ + // 修改点击事件 + $(obj).removeClass('extra_more_on'); + $(obj).parent().parent().find('ul').css({height:'30px'}); + $(obj).attr('onClick','extra_show(this)'); + $(obj).html('更多<i></i>'); +} +var _preObj; +function multibox_show(obj,type){ + var _topParent = $(obj).parent().parent(); + // 显示被隐藏的选项 + _topParent.find('ul').css({height:'auto'}); + // 给每个li绑定事件 + _topParent.find('ul li').each(function(){ + $(this).attr('_onclick',$(this).attr('onclick')); + $(this).removeAttr('onclick'); + $(this).click(function(){ + $(this).toggleClass('selected'); + ($('li.selected').length>0)?_topParent.find('a.confirm_btn').css({visibility:'visible'}):_topParent.find('a.confirm_btn').css({visibility:'hidden'}); + }) + }) + // 隐藏右侧按钮 + $(obj).parent().hide(); + // 显示多选盒子 + _topParent.addClass('multi_on'); + _topParent.append('<div class="multi_btns"><a class="confirm_btn" href="javascript:void(0)" onClick="multi_done(this,\''+type+'\')">确定</a><a onClick="multibox_hide(this)" href="javascript:void(0)">取消</a></div>') + // 隐藏上一个多选盒子 + if($('.multi_on').length>1){multibox_hide(_preObj)} + _preObj = obj; +} +// 完成多选 +function multi_done(obj,type){ + var ids = [],attrId=0; + // 获取选中的值 + $(obj).parent().parent().find('ul li.selected').each(function(){ + ids.push($(this).attr('v')); + if(type=='attr')attrId = $(this).attr('d'); + }) + if(ids.length==0){ + WST.msg('请选择要筛选的选项'); + return false; + } + if(type=='brand'){ + $('#brand').val(ids.join(',')); + }else if(type=='attr'){ + $('#v_'+attrId).val(ids.join('、'));// 属性名称 -> 双卡双4G_电信4G_移动4G + var vs = $('#vs').val();// 属性id【不需要再拼凑】 + vs = (vs!='')?vs.split(','):[]; + vs.push(attrId); + $('#vs').val(vs.join(',')); + + } + var ipts = WST.getParams('.sipt'); + var params = []; + for(var key in ipts){ + if(ipts[key]!='')params.push(key+"="+ipts[key]); + } + location.href=WST.U('home/goods/lists',params.join('&'),true); + + +} +// 多选隐藏 +function multibox_hide(obj){ + var _topParent = $(obj).parent().parent(); + // 显示被隐藏的选项 + _topParent.find('ul').css({height:'30px'}); + // 给每个li绑定事件 + _topParent.find('ul li').each(function(){ + $(this).unbind('click'); + $(this).attr('onclick',$(this).attr('_onclick')); + $(this).removeAttr('_onclick'); + $(this).removeClass('selected'); + }) + // 显示右侧按钮 + _topParent.find('div.extra').show(); + // 隐藏多选盒子 + _topParent.removeClass('multi_on'); + _topParent.find('div.multi_btns').remove(); + // 设置【更多】按钮 + var _moreBtn = _topParent.find('a.extra_more'); + _moreBtn.removeClass('extra_more_on'); + _moreBtn.attr('onClick','extra_show(this)'); + _moreBtn.html('更多<i></i>'); +} + +//对比商品 +function contrastGoods(show,id,type){ + if(show==1){ + $.post(WST.U('home/goods/contrastGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + if(type==2 && json.data)$("#j-cont-frame").addClass('show'); + var gettpl = document.getElementById('colist').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#contrastList').html(html); + }); + $('.contImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }else{ + WST.msg(json.msg,{icon:2}); + } + if(type==1)$("#j-cont-frame").addClass('show'); + }); + }else{ + $("#j-cont-frame").removeClass('show'); + } +} +//删除 +function contrastDels(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + contrastGoods(1,0,1); + } + }); +} +//对比商品列表 +//滑动 +function fixedGoods(){ + var offsetTop = $("#goodsTabs").offset().top; + $(window).scroll(function() { + var scrollTop = $(document).scrollTop(); + if (scrollTop > offsetTop){ + $("#goodsTabs").addClass('goods-fixed'); + $("#goodsTabs2").show(); + }else{ + $("#goodsTabs").removeClass('goods-fixed'); + $("#goodsTabs2").hide(); + } + }); +} +//删除 +function contrastDel(id){ + $.post(WST.U('home/goods/contrastDel'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + location.href=WST.U('home/goods/contrast'); + } + }); +} +//筛选条件 +function screenContrast(obj,id){ + if ($(obj).is(':checked')) { + $(".identical_"+id).addClass('active'); + }else{ + $(".identical_"+id).removeClass('active'); + } +} +//筛选规格 +function choiceContrast(obj,itemId,catId,goodsId){ + $(obj).addClass('active').siblings('.list-box li').removeClass('active'); + $("#defaultSpec_"+goodsId+"_"+catId).val(itemId); + var specIds = []; + $(".defaultSpec_"+goodsId).each(function(){ + specIds.push(parseInt($(this).val(),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(saleSpec.sku[goodsId][specIds.join(':')]){ + stock = saleSpec.sku[goodsId][specIds.join(':')].specStock; + marketPrice = saleSpec.sku[goodsId][specIds.join(':')].marketPrice; + goodsPrice = saleSpec.sku[goodsId][specIds.join(':')].specPrice; + } + $('#goods-price-'+goodsId).html('¥ <span>'+goodsPrice+'</span>'); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/index.js b/hyhproject/home2/view/default/js/index.js new file mode 100755 index 0000000..c4877a5 --- /dev/null +++ b/hyhproject/home2/view/default/js/index.js @@ -0,0 +1,420 @@ +$.fn.TabiPanel = function(options){ + var defaults = {tab: 0}; + var opts = $.extend(defaults, options); + var t = this; + + $(t).find('.wst-tab-nav .tab').click(function(){ + $(this).addClass("on").siblings().removeClass("on"); + var index = $(this).index(); + $(t).find('.wst-tab-content .wst-tab-item').eq(index).show().siblings().hide(); + if(opts.callback)opts.callback(index); + }); + $(t).find('.wst-tab-nav .tab').eq(opts.tab).click(); +} +$(function(){ + WST.slides('.wst-slide'); + $('#index-tab').TabiPanel({tab:0,callback:function(no){}}); +}); + + + +/*楼层*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("div[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} + + +/*楼层商品 加入购物车*/ +$('.goods').hover(function(){ + $(this).find('.sale-num').hide(); + $(this).find('.f-add-cart').show(); +},function(){ + $(this).find('.sale-num').show(); + $(this).find('.f-add-cart').hide(); +}) + + +/*楼层右侧滚动广告*/ +function floorAds(i){ + var slide = $('#wst-floor-slide-'+i), li = slide.find("li"); + var slidecontrols = $('#wst-floor-slide-controls-'+i), + + span = slidecontrols.find("span"); + var index = 1, _self = null; + span.bind("mouseover", function() { + _self = $(this); + index = span.index(_self); + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).css("display", ""); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + clearInterval(timer); + }); + var timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 3000); + span.bind("mouseout", function() { + timer = setInterval(function() { + span.removeClass("curr"); + span.eq(index).addClass("curr"); + li.addClass("hide"); + li.css("z-index", -1); + li.css("display", "none"); + li.eq(index).fadeToggle(500); + li.eq(index).css("z-index", 1); + li.eq(index).removeClass("hide"); + index++; + if (index >= span.length) + index = 0; + }, 4000); + }); +} +$(function(){ + //执行楼层右侧广告js + var fRAds = $(this).find("div[id^='wst-floor-slide-controls-']").length; + for(var i=1;i<=fRAds;++i){ + floorAds(i); + } + //执行右侧底部商品切换js + var fBgoods = $(this).find("ul[id^='styleMain']").length; + for(var i=1;i<=fBgoods;++i){ + var li = $('#styleMain'+i).find('li'); + if(li.length>5){ + fBGoods(i); + }else{ + li.each(function(){$(this).css('padding-bottom','0')}) + } + + } +}) + + + + +function fBGoods(id){ + $('#styleMain'+id).bxCarousel({ + display_num: 5, + move: 1, + auto: 0, + controls: true, + prev_image: WST.conf.ROOT+'/hyhproject/home/view/default/img/btn_slide_left.png', + next_image: WST.conf.ROOT+'/hyhproject/home/view/default/img/btn_slide_right.png', + margin: 10, + auto_hover: true + }); +} + +function loadImg(){ + $('.fImg').lazyload({ failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); +} + +/*左侧楼层导航*/ +$(function() { + loadImg(); + }); +$('.lnav').click(function(){ + var i = $(this).index()+1; + i = i+'F'; + $("html,body").animate({scrollTop: $("a[name='"+i+"']").offset().top-7}, 500); +}) + +function leftNav(){ + //内容距离左边空白处宽度 + var containerW = $('.wst-container').offset().left; + left = containerW-40; + $('#screen-left-nav').css('left', left); +} +$(window).resize(function(){leftNav()}); + + +var currF,first=true; + +function cf(){ + var sumFloor = $('.floor-box').length; + for(var f=sumFloor;f>=1;--f){ + var id = '#c'+f; + if($(id).offset().top+500-$(window).scrollTop()>0){ + currF = f; + first = false; + lcurr(f) + } + } +} + + +//内容高度 +var containerH = parseInt($('.wst-main').css('height')); +$(window).scroll(function(){ +leftNav(); +//滚动条当前高度 +var scrollHeight = $(window).scrollTop(); + +// 楼层选中 +if(first){ + cf(); +}else{ + var cfh = $('#c'+currF).offset().top+500-$(window).scrollTop(); + if(cfh<0 || cfh>1200)cf(); + +} + +if(scrollHeight>=462 && scrollHeight<containerH+200){ + $('#screen-left-nav').show(); +}else{ + $('#screen-left-nav').hide(); +} + +}); +function lcurr(F){ + $('#F'+F).siblings().removeClass('lcurr'); + $('#F'+F).addClass('lcurr'); +} + +/*签到*/ +function inSign(){ + $("#j-sign").attr('disabled', 'disabled'); + $.post(WST.U('home/userscores/signScore'),{},function(data){ + var json = WST.toJson(data,true); + if(json.status==1){ + $("#j-sign .plus").html('+'+json.data.score); + $("#currentScore").html(json.data.totalScore); + $("#j-sign").addClass('active'); + setInterval(function(){ + $("#j-sign").addClass('actives').html('已签到'); + },600); + WST.msg(json.msg, {icon: 1}); + }else{ + WST.msg(json.msg, {icon: 5}); + $("#j-sign").removeAttr('disabled'); + } + }); +} +WST.countDown = function(opts){ + var f = { + zero: function(n){ + var n = parseInt(n, 10); + if(n > 0){ + if(n <= 9){ + n = n; + } + return String(n); + }else{ + return "0"; + } + }, + count: function(){ + if(opts.nowTime){ + var d = new Date(); + d.setTime(opts.nowTime.getTime()+1000); + opts.nowTime = d; + d = null; + }else{ + opts.nowTime = new Date(); + } + //现在将来秒差值 + var dur = Math.round((opts.endTime.getTime() - opts.nowTime.getTime()) / 1000), pms = { + sec: "0", + mini: "0", + hour: "0", + day: "0" + }; + if(dur > 0){ + pms.sec = f.zero(dur % 60); + pms.mini = Math.floor((dur / 60)) > 0? f.zero(Math.floor((dur / 60)) % 60) : "0"; + pms.hour = Math.floor((dur / 3600)) > 0? f.zero(Math.floor((dur / 3600)) % 24) : "0"; + pms.day = Math.floor((dur / 86400)) > 0? f.zero(Math.floor(dur / 86400)) : "0"; + } + pms.last = dur; + pms.nowTime = opts.nowTime; + opts.callback(pms); + if(pms.last>0)setTimeout(f.count, 1000); + } + }; + f.count(); +}; +// 拍卖轮播 +$(function(){ + var _p = $('.aution_list'); + var step = _p.width();// 步进值 + var totalItem = $('.aution_list .aution_main').length;// 总拍卖商品数 + if(totalItem==0)return; + var au_lbtn = $('.au_l_btn'); + var au_rbtn = $('.au_r_btn'); + + $('.ws-right-user').css({height:'85px',overflow:'hidden'});// 确保右侧不溢出轮播区域 + var nowTime = new Date(Date.parse($('.aution_list').attr('sc').replace(/-/g, "/"))); + // 倒计时 + $('.aution_main').each(function(){ + var g = $(this); + var startTime = new Date(Date.parse(g.attr('sv').replace(/-/g, "/"))); + var endTime = new Date(Date.parse(g.attr('ev').replace(/-/g, "/"))); + if(startTime.getTime()<= nowTime && endTime.getTime() >=nowTime){ + var opts = { + nowTime: nowTime, + endTime: endTime, + callback: function(data){ + if(data.last>0){ + g.find('.aution_time .aution_h').html(data.hour); + g.find('.aution_time .aution_i').html(data.mini); + g.find('.aution_time .aution_s').html(data.sec); + }else{ + g.find('.aution_time').html('拍卖活动已结束'); + } + + } + }; + WST.countDown(opts); + }else{ + g.find('.aution_time').html('拍卖活动已结束'); + } + }) + + // 设置父容器宽度 + _p.css({width:totalItem+'00%'}); + var _curr = 0;// 当前显示的index + // 右切换按钮 + au_rbtn.click(function(){ + _curr++; + if (_curr + 1 > totalItem) { _curr = 0 } + au_s(); + return false; + }); + // 左切换按钮 + au_lbtn.click(function(){ + _curr--; + if (_curr + 1 < 1) { + _curr = totalItem - 1 + } + au_s(); + return false; + }); + function au_auto_swiper() { y = setInterval(function () { au_rbtn.click() }, 5000) } + au_auto_swiper(); + $('.aution_out').bind({ mouseover: function () { clearInterval(y);au_lbtn.show();au_rbtn.show(); }, mouseout: function () { au_auto_swiper();au_lbtn.hide();au_rbtn.hide(); } }) + // 执行切换 + function au_s(){ + _p.stop().animate({left:-_curr*step}); + } +}) + +// 团购轮播 +$(function(){ + var g_list_time; + var g_obj = $('.groupon_view'); + var g_step = g_obj.width();// 步进值 + var g_list = $('.groupon_list'); // 轮播对象 + // 设置长度 + var g_list_w = $('.groupon_list li').length; + g_list.css({width:g_list_w*100+'%'}); + var g_list_i = 0; + + // 按钮 + $('.groupon_btns span').each(function(k,v){ + $(this).mouseover(function(){ + clearInterval(g_list_time); + g_list_i = k; + g_list_auto(); + }) + }); + $('.groupon_btns').mouseout(function(){glistautoplay();}) + function glistautoplay(){ + clearInterval(g_list_time); + g_list_time = setInterval(function(){ + g_list_i++; + if (g_list_i + 1 > g_list_w) { g_list_i = 0 } + g_list_auto(); + },3000); + } + function g_list_auto(){ + g_list.stop().animate({left:-g_list_i*g_step}); + $('.groupon_btns span').removeClass('curr').eq(g_list_i).addClass('curr') + } + glistautoplay(); +}); + + + +// 楼层商品轮播 +$(function(){ + var a = $(".floor_silder"); + a.each(function () { + var q = $(this); + var s = q.find("ul"); + var t = q.find("ul li"); + var c = q.find(".prev_btn"); + var w = q.find(".next_btn"); + var u = t.length; + // q.find(".show_num").find("em").html(u); + if (u == 1) { return } + var p = 0; + var y = 0; + var x = 3000; // 轮播间隔 + w.click(function () { // 下一张 + p++; + if (p + 1 > u) { p = 0 } + z(p); + v(); + return false + }); + c.click(function () { // 上一张 + p--; + if (p + 1 < 1) { + p = u - 1 + } + z(p); + v(); + return false + }); + function z(e) {// 执行轮播 + switch (e) { + case 2: + t.eq(e).css("z-index", 100).stop().animate({ width: 155, height: 225, left: 20, top: 0 }); + t.eq(e - 1).css("z-index", 80).stop().animate({ width: 195, height: 170, left: 0, top:30 }); + t.eq(e - 2).css("z-index", 90).stop().animate({ width: 175, height: 200, left: 10, top: 15 }); + t.eq(e).find(".color_mask").stop().animate({ opacity: 0 }); + t.eq(e - 1).find(".color_mask").stop().animate({ opacity: 0.7 }); + t.eq(e - 2).find(".color_mask").stop().animate({ opacity: 0.5 }); + break; + default: + t.eq(e).css("z-index", 100).stop().animate({ width: 155, height: 225, left: 20, top: 0 }); + t.eq(e - 1).css("z-index", 80).stop().animate({ width: 195, height: 170, left: 0, top: 30 }); + t.eq(e + 1).css("z-index", 90).stop().animate({ width: 175, height: 200, left: 10, top: 15 }); + t.eq(e).find(".color_mask").stop().animate({ opacity: 0 }); + t.eq(e - 1).find(".color_mask").stop().animate({ opacity: 0.7 }); + t.eq(e + 1).find(".color_mask").stop().animate({ opacity: 0.5 }); + } + } + function v() { + // 当前显示张数 + q.find(".show_num").find("span").removeClass('curr').eq(p).addClass('curr'); + } + function r() { y = setInterval(function () { w.click() }, x) } + r(); + $(this).bind({ mouseover: function () { clearInterval(y) }, mouseout: function () { r() } }) + }) + }) \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/jquery.als.js b/hyhproject/home2/view/default/js/jquery.als.js new file mode 100755 index 0000000..74e1dbb --- /dev/null +++ b/hyhproject/home2/view/default/js/jquery.als.js @@ -0,0 +1,1714 @@ +/** + * jquery.als.js + * http://als.musings.it + * jQuery plugin for list scrolling (any list with any content) + * developed for http://www.musings.it and released as a freebie + * + * animations: horizontal slide, vertical slide of lists + * types of lists: images, texts, inserted as div or as ul - li + * + * CONFIGURABLE PARAMETERS + * visible_elements: number of visible elements of a list + * scrolling_items: list scrolling step + * orientation: list orientation ("horizontal" or "vertical") + * circular: "yes" for infinite list scrolling, "no" on the contrary + * autoscroll: "yes" for automatic scrolling, "no" on the contrary + * interval: if autoscroll "yes" is the time interval between scrolling movements + * speed: speed of the scrolling movement (in msec) + * easing: easing function to use for the scrolling movement ("swing" or "linear") + * direction: if autoscroll "yes" is the scrolling direction ("left","right","up","down") + * start_from: start the scroller from a specific item (default: 0, first item) + * + * CONFIGURATION EXAMPLE: + * $("#lista").als({ + * visible_items: 4, + * scrolling_items: 2, + * orientation: "horizontal", + * circular: "yes", + * autoscroll: "yes", + * interval: 5000, + * speed: 600, + * easing: "linear", + * direction: "right", + * start_from: 0 + * }); + * + * @author Federica Sibella + * Copyright (c) 2012/14 Federica Sibella - musings(at)musings(dot)it | http://www.musings.it + * Released with double license MIT o GPLv3. + * Date: 2014/09/17 + * @version 1.7 + * + * Changelog: + * 2014.09.17: minor bug fixes on configuration controls and timeout reset on click with autoscroll + * 2014.06.17: minor bug fix on swipe control for non circular scrolling + * 2014.05.21: minor bugs revisions: destroy method and touch controls revisited + * 2014.03.24: added swipe support for touch devices + * 2014.02.01: minor bug fixes for height and width of cross-dimension (w/ respect to ALS scrolling direction) + * 2014.01.10: enhanced "destroy" method (no more instance ID needed); scroll speed as setting; easing option as setting + * 2013.04.11: added "start_from" option + * 2013.09.04: enhanced "destroy" method based on single instance + * 2013.09.13: fixed issue on initial viewport width if items widths are different from each other and start_from != 0 + */ + + + (function($){ + /********************************************************** + * Variables: als (contains data of the current instance), + * instance (number of the current instance), + * methods (methods of als plugin) + *********************************************************/ + var als = [], + instance = 0; + var methods = { + /****************************************************** + * plugin inizialization + * @param {Object} options: configuration options + ******************************************************/ + init: function(options) { + this.each(function() { + var defaults = { + visible_items: 3, + scrolling_items: 1, + orientation: "horizontal", + circular: "no", + autoscroll: "no", + interval: 4000, + speed: 600, + easing: "swing", + direction: "left", + start_from: 0 + }, + $obj = $(this), + data = $obj.data("als"), + $options = $(), + $item = $(), + $wrapper = $(), + $viewport = $(), + $prev = $(), + $next = $(), + num_items = 0, + viewport_width = 0, + wrapper_width = 0, + viewport_height = 0, + wrapper_height = 0, + initial_movement = 0, + maxHeight = 0, + maxWidth = 0, + i = 0, + j = 0, + current = 0, + timer = 0, + mm = {}; + + mm.swipeTreshold = 100, + mm.allowedTime = 300; + + $options = $.extend(defaults, options); + + /********************************************************************* + * configuration controls: autoscroll option implies + * infinite circular scrolling + *********************************************************************/ + if($options.circular == "no" && $options.autoscroll == "yes") + { + $options.circular = "yes"; + } + + /************************************* + * checking easing option + *************************************/ + if($options.easing != "linear" || $options.easing != "swing") + { + $options.easing = "swing"; + } + + /*********************************************************************************** + * define ID for the different plugin section to name them directly + **********************************************************************************/ + if(!$obj.attr("id") || $obj.attr("id") == "") + { + $obj.attr("id","als-container_" + instance); + } + + $obj.attr("data-id","als-container_" + instance); + $viewport = $obj.find(".als-viewport").attr("data-id","als-viewport_" + instance); + $wrapper = $obj.find(".als-wrapper").attr("data-id","als-wrapper_" + instance); + $item = $obj.find(".als-item"); + num_items = $item.size(); + + /*************************************************************************************** + * configuration controls: number of visible element can not be higher than + * total number of list element and scrolling items can not be more + * than visible items + * start_from number can not be higher than total number of list elements + ***************************************************************************************/ + if($options.visible_items > num_items) + { + $options.visible_items = num_items - 1; + } + + if($options.scrolling_items > $options.visible_items) + { + if($options.visible_items > 1) + { + $options.scrolling_items = $options.visible_items - 1; + } + else if($options.visible_items === 1) + { + $options.scrolling_items = $options.visible_items; + } + } + + if($options.start_from > num_items - $options.visible_items) + { + $options.start_from = 0; + } + + /****************************************************** + * prev and next button inizialization (if present) + ******************************************************/ + $prev = $obj.find(".als-prev").attr("data-id","als-prev_" + instance); + $next = $obj.find(".als-next").attr("data-id","als-next_" + instance); + + /********************************************************************* + * relative to chosen orientation I calculate width and height + * of the list wrapper (wrapper) and of the list viewport (viewport) + * @param {Object} index: internal elements index + *********************************************************************/ + switch($options.orientation) + { + case "horizontal": + default: + $item.each(function(index) + { + $(this).attr("id","als-item_" + instance + "_" + index); + wrapper_width += $(this).outerWidth(true); + + if($(this).outerHeight(true) > maxHeight) + { + maxHeight = $(this).outerHeight(true); + } + + if(i < $options.visible_items) + { + if($options.start_from == 0) + { + viewport_width += $(this).outerWidth(true); + i++; + } + else + { + if(index >= $options.start_from) + { + viewport_width += $(this).outerWidth(true); + i++; + } + } + } + + if($options.start_from != 0) + { + if(j < $options.start_from) + { + initial_movement += $(this).outerWidth(true); + j++; + } + current = $options.start_from; + } + }); + $wrapper.css("width", wrapper_width); + $item.css("left", -initial_movement); + $viewport.css("width", viewport_width); + $wrapper.css("height", maxHeight); + $viewport.css("height", maxHeight); + + if($options.circular == "yes" && $options.start_from != 0) + { + /**************************************************** + * must reset the hidden elements if start_from != 0 + ****************************************************/ + for (r = 0; r < $options.start_from; r++) + { + var position = $item.last().position(), + right_repos = position.left + $item.last().outerWidth(true); + $item.eq(r).css("left", right_repos); + } + } + break; + case "vertical": + $item.each(function(index) + { + $(this).attr("id","als-item_" + instance + "_" + index); + wrapper_height += $(this).outerHeight(true); + + if($(this).outerWidth(true) > maxWidth) + { + maxWidth = $(this).outerWidth(true); + } + + if(i < $options.visible_items) + { + if($options.start_from == 0) + { + viewport_height += $(this).outerHeight(true); + i++; + } + else + { + if(index >= $options.start_from) + { + viewport_height += $(this).outerHeight(true); + i++; + } + } + } + + if($options.start_from != 0) + { + if(j < $options.start_from) + { + initial_movement += $(this).outerHeight(true); + j++; + } + current = $options.start_from; + } + }); + $wrapper.css("height", wrapper_height); + $item.css("top", -initial_movement); + $viewport.css("height", viewport_height); + $wrapper.css("width", maxWidth); + $viewport.css("width", maxWidth); + + if($options.circular == "yes" && $options.start_from != 0) + { + /**************************************************** + * must reset the hidden elements if start_from != 0 + ****************************************************/ + for (r = 0; r < $options.start_from; r++) + { + var position = $item.last().position(), + bottom_repos = position.top + $item.last().outerHeight(true); + $item.eq(r).css("top", bottom_repos); + } + } + break + } + /************************************************** + * if circular == no don't show prev button + * at the beginning but only if start_from == 0 + **************************************************/ + if($options.circular == "no") + { + if($options.start_from == 0) + { + $prev.css("display","none"); + } + if($options.visible_items + $options.start_from == num_items) + { + $next.css("display","none"); + } + } + + + /****************************************** + * prev and next buttons inizialization + ******************************************/ + $next.on("click touchstart touchend",nextHandle); + $prev.on("click touchstart touchend",prevHandle); + + + /***************************************** + * initializing swipe-touch control + *****************************************/ + $viewport.on('touchstart', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.ox = touch.pageX; + mm.oy = touch.pageY; + mm.startTime = new Date().getTime(); + }); + + $viewport.on('touchmove', function(e) { + }); + + $viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if($options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll forth on swipe only if circular or if start_from < num_items + if($options.circular == "yes" || $options.visible_items + $options.start_from < num_items) { + nextHandle(e,$viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll back on swipe only if circular or if start_from > 0 + if($options.circular == "yes" || $options.start_from > 0) { + prevHandle(e,$viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll forth on swipe only if circular or if start_from < num_items + if($options.circular == "yes" || $options.visible_items + $options.start_from < num_items) { + nextHandle(e,$viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // can scroll back on swipe only if circular or if start_from > 0 + if($options.circular == "yes" || $options.start_from > 0) { + prevHandle(e,$viewport); + } + } + } + }); + + + /************************************************** + * saving instance parameters in a variable (data) + * for future use + **************************************************/ + $obj.data('als', + { + container : $obj, + instance : instance, + options : $options, + viewport : $viewport, + wrapper : $wrapper, + prev : $prev, + next : $next, + item : $item, + num_items : num_items, + wrapper_width : wrapper_width, + viewport_width : viewport_width, + wrapper_height : wrapper_height, + viewport_height : viewport_height, + current : current, + timer : timer, + mm : mm + }); + + data = $obj.data('als'); + als[instance] = data; + + /********************************************* + * automatic scrolling function inizialization + * if it is the case + *********************************************/ + if($options.autoscroll == "yes") + { + $.fn.als('start',instance); + $wrapper.hover(function() + { + $.fn.als('stop',$(this).attr("data-id")); + },function() + { + $.fn.als('start',$(this).attr("data-id")); + }); + } + else if($options.autoscroll == "no") + { + $.fn.als('stop',instance); + } + + /******************************************* + * increasing instance number and + * returning als variable now inizialized + ******************************************/ + instance++; + return als; + }); + }, + /***************************************************** + * step function for lists elements + * @param {Object} id: instance or ID of the element + * that calls the function + *****************************************************/ + next: function(id){ + id = find_instance(id); + var data = als[id], + mm = data.mm, + k1 = 0, k2 = 0; + /*************************************************** + * depending on list orientation I calculate + * the element horizontal or vertical movement + ***************************************************/ + switch(data.options.orientation) + { + /***************************************** + * list orientation: horizontal + ****************************************/ + case "horizontal": + default: + var shift_left = 0, + viewport_width = 0; + /************************************************ + * depending on scrolling type I calculate + * the movement and the repositioning of the + * list elements + ************************************************/ + switch(data.options.circular) + { + /**************************** + * infinite scrolling: no + ****************************/ + case "no": + default: + /******************************************************************** + * I calculate the elements' movement on the basis of the scrolling + * items number starting from the current index + ********************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + shift_left += data.item.eq(k1).outerWidth(true); + } + + /**************************************************************** + * I modify the current element on the basis of the scrolling + * elements number + ****************************************************************/ + data.current += data.options.scrolling_items; + + /******************************************************************* + * I calculate the viewport width on the basis of the width of the + * elements that will be visible AFTER the animation + *******************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_width += data.item.eq(k2).outerWidth(true); + } + + /******************************************************** + * I animate the viewport width + ********************************************************/ + data.viewport.animate({ + "width": viewport_width + }, data.options.speed, data.options.easing); + + /********************************************** + * I animate the scrolling elements + *********************************************/ + data.item.animate({ + "left": "-=" + shift_left + }, data.options.speed, data.options.easing); + /*********************************************************** + * after the animation of all elements has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { /**************************************************** + * I bind again the "click" action to the prev + * and next buttons (unbinded to prevent undesirable + * behaviour during the scrolling animation) + ***************************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + /********************************************************** + * visibility control of the prev and next buttons + **********************************************************/ + if(data.current > 0) + { + data.prev.show(); + } + + if (data.current + data.options.visible_items >= data.num_items) + { + data.next.hide(); + } + break; + /**************************** + * infinite scrolling: yes + ***************************/ + case "yes": + var memo = 0, memo_index = []; + /************************************************************************** + * I calculate displacement and memorize indices of the elements that + * I have to move because they will be then repositioned in the queue + **************************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /****************************************************** + * I control if I exceed the total number of elements + ******************************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_left += data.item.eq(k3).outerWidth(true); + memo_index[memo]= k3; + memo ++; + } + /**************************************************************** + * edit current element as a function of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /****************************************************** + * I control if I exceed the total number of elements + ******************************************************/ + if(data.current >= data.num_items) + { + data.current -= data.num_items; + } + /*********************************************************************** + * calculating the extent of the viewport based on the items that + * will be visible after scrolling + ***********************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /***************************************************** + * I control if I exceed the total number of elements + *****************************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_width += data.item.eq(k4).outerWidth(true); + } + + /****************************************************** + * viewport width animation + ******************************************************/ + data.viewport.animate({ + "width": viewport_width + }, data.options.speed, data.options.easing); + + /****************************************************************** + * scrolling animation of elements and repositioning of elements + * stored in the queue + *****************************************************************/ + data.item.animate({ + "left": "-=" + shift_left + }, data.options.speed, data.options.easing); + /*********************************************************** + * once the animation of all the elements has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { + /**************************************************************************** + * repositioning is calculated based on the location of the last element of + * the list, double check if I have to move the first element + ****************************************************************************/ + var position = data.item.last().position(), + right_repos = position.left + data.item.last().outerWidth(true); + for(k5 = 0; k5 < memo_index.length; k5++) + { + if(memo_index[k5] == 0) + { + var position = data.item.last().position(), + right_repos = position.left + data.item.last().outerWidth(true); + } + data.item.eq(memo_index[k5]).css("left", right_repos); + } + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + break; + } + break; + + /************************************** + * list orientation: vertical + **************************************/ + case "vertical": + var shift_top = 0, + viewport_height = 0; + /************************************************ + * depending on the type of sliding I calcule + * the displacement and the repositioning of the + * elements of the list + ************************************************/ + switch(data.options.circular) + { + /**************************** + * infinite scrolling: no + ***************************/ + case "no": + default: + /******************************************************************** + * displacement calculation based on the number of elements to + * slide in a single step + ********************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_top += data.item.eq(k1).outerHeight(true); + } + + /**************************************************************** + * I edit element current as a function of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /*********************************************************************** + * calculating the width of the viewport on the basis of the visible + * elements AFTER the sliding animation + ***********************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) { + viewport_height += data.item.eq(k2).outerHeight(true); + } + + /*************************************************** + * I animate the viewport width + ***************************************************/ + data.viewport.animate({ + "height": viewport_height + }, data.options.speed, data.options.easing); + /**************************************** + * I animate the elements scrolling + ****************************************/ + data.item.animate({ + "top": "-=" + shift_top + }, data.options.speed, data.options.easing); + /********************************************************** + * once the animation of all the elements has finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that has + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + + /**************************************************** + * control visibility of the scroll buttons on + * the basis of the current element + ****************************************************/ + if(data.current > 0) + { + data.prev.show(); + } + + if (data.current + data.options.visible_items >= data.num_items) + { + data.next.hide(); + } + break; + /**************************** + * infinite scrolling: yes + ****************************/ + case "yes": + var memo = 0, memo_index = []; + /**************************************************************** + * displacement calculation based on the number of elements to + * slide in a single step and memorization of items to reposition + ****************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_top += data.item.eq(k3).outerHeight(true); + memo_index[memo]= k3; + memo ++; + } + /**************************************************************** + * edit current element on the basis of the number of elements + * to slide in a single step + ****************************************************************/ + data.current += data.options.scrolling_items; + + /************************************************* + * control that the index does not exceed the + * total number of the elements + ************************************************/ + if(data.current >= data.num_items) + { + data.current -= data.num_items; + } + + /****************************************************************************** + * calculating the width of viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_height += data.item.eq(k4).outerHeight(true); + } + /************************************************* + * I animate the viewport width + *************************************************/ + data.viewport.animate({ + "height": viewport_height + }); + + /**************************************************************** + * I animate the elements and reposition those previously stored + ***************************************************************/ + data.item.animate({ + "top": "-=" + shift_top + }); + /************************************************************ + * once all the elements' animations has finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { + /************************************************************************ + * repositioning is calculated based on the location of the last element + * of the list. Take care to the repositioning of the first element + * that needs to be recalculated AFTER the last was eventually relocated + ************************************************************************/ + var position = data.item.last().position(), + bottom_repos = position.top + data.item.last().outerHeight(true); + for(k5 = 0; k5 < memo_index.length; k5++) + { + if(memo_index[k5] == 0) + { + var position = data.item.last().position(), + bottom_repos = position.top + data.item.last().outerHeight(true); + } + data.item.eq(memo_index[k5]).css("top", bottom_repos); + } + /********************************************* + * re bind buttons "click" event that has + * been detached from the handle to handle + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + break; + } + break; + } + + /************************************ + * save the data in als instance and + * return als object + ***********************************/ + als[id] = data; + return als; + }, + /***************************************************** + * sliding back function of the list elements + * @param {Object} id: instance or ID of the element + * that calls the function + *****************************************************/ + prev: function(id){ + id = find_instance(id); + var data = als[id], + mm = data.mm, + k1 = 0, k2 = 0; + /*************************************************** + * depending on the orientation of the list I + * calculate the horizontal or vertical displacement + * of the elements + ***************************************************/ + switch(data.options.orientation) + { + /*************************** + * horizontal orientation + ***************************/ + case "horizontal": + default: + var shift_right = 0, + viewport_width = 0; + /**************************************************** + * depending on the type of scroll (circular or not) + * I calculate the displacement and the possible + * repositioning of the elements of the list + ****************************************************/ + switch(data.options.circular) + { + /***************************** + * circular scrolling: no + *****************************/ + case "no": + default: + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that you can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + + /******************************************************************* + * calculating the displacement of the elements according to the + * number of elements to slide in a single step + *******************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_right += data.item.eq(k1).outerWidth(true); + } + + /****************************************************************************** + * calculation of the viewport width on the basis of the visible elements + * AFTER the scrolling (on the basis of their width) + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_width += data.item.eq(k2).outerWidth(true); + } + /************************************************* + * animating the viewport width + *************************************************/ + data.viewport.animate({ + "width": viewport_width + }); + /********************************** + * animating elements scrolling + **********************************/ + data.item.animate({ + "left": "+=" + shift_right + }, data.options.speed, data.options.easing); + /*********************************************************** + * once all animations have finished + * (deferred object) + ***********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + + /********************************************************** + * control visibility of the scroll buttons + **********************************************************/ + if(data.current <= 0) + { + data.prev.hide(); + } + if (data.current + data.options.visible_items < data.num_items) + { + data.next.show(); + } + break; + /***************************** + * circular scrolling: yes + *****************************/ + case "yes": + var memo = 0, memo_index = []; + /*************************************************************** + * edit the current item index as a function of the elements + * to slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /************************************************** + * check if the current element has not index < 0 + **************************************************/ + if(data.current < 0) + { + data.current += data.num_items; + } + /**************************************************************** + * displacement calculation based on the elements to slide in a + * single step and memorization of the items to reposition + ****************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_right += data.item.eq(k3).outerWidth(true); + memo_index[memo]= k3; + + memo ++; + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the + * visible elements AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /********************************************** + * control that the index does not exceed the + * total number of the elements + *********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_width += data.item.eq(k4).outerWidth(true); + } + /************************************************************************ + * repositioning is calculated based on the location of the first element + * of the list. Special care to the repositioning of the last element + * that needs to be recalculated AFTER the first was eventually relocated + ************************************************************************/ + var position = data.item.first().position(), + left_repos = position.left - data.wrapper_width; + + for(k5 = 0; k5 < memo_index.length; k5++) + { + data.item.eq(memo_index[k5]).css("left", left_repos); + if(memo_index[k5] == 0) + { + var position0 = data.item.eq(0).position(), + new_left_repos = position0.left - data.wrapper_width; + for(k6 = 0; k6 < k5; k6++) + { + data.item.eq(memo_index[k6]).css("left", new_left_repos); + } + } + } + /************************************************************ + * timeout of 200ms is necessary to wait before making the + * scrolling animation, otherwise we can not properly manage + * the repositioning of the list elements + ************************************************************/ + setTimeout(function() + { + /**************************************** + * viewport width animation + ****************************************/ + data.viewport.animate({ + "width": viewport_width + }); + /******************************* + * list elements animation + *******************************/ + data.item.animate({ + "left": "+=" + shift_right + }, data.options.speed, data.options.easing); + /********************************************************** + * once all elements animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + }, 200); + break; + } + break; + /************************* + * vertical orientation + ************************/ + case "vertical": + var shift_bottom = 0, + viewport_height = 0; + + switch(data.options.circular) + { + /***************************** + * circular scrolling: no + ****************************/ + case "no": + default: + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /**************************************************************** + * displacement calculation based on the elements to slide + * in a single step + ****************************************************************/ + for (k1 = data.current; k1 < data.current+data.options.scrolling_items; k1++) + { + shift_bottom += data.item.eq(k1).outerHeight(true); + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + viewport_height += data.item.eq(k2).outerHeight(true); + } + /*********************************************** + * viewport width animation + **********************************************/ + data.viewport.animate({ + "height": viewport_height + }); + /***************************************** + * list elements scrolling animation + *****************************************/ + data.item.animate({ + "top": "+=" + shift_bottom + }, data.options.speed, data.options.easing); + /********************************************************** + * once all elemets animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll on swipe only of there are enough elements + if (data.current + data.options.visible_items < data.num_items) { + nextHandle(e,data.viewport); + } + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + // scroll back on swipe only if there are enough elements + if(data.current > 0) { + prevHandle(e,data.viewport); + } + } + } + }); + }); + /*********************************************************** + * management of visibility of forward and backward buttons + **********************************************************/ + if(data.current <= 0) + { + data.prev.hide(); + } + if (data.current + data.options.visible_items < data.num_items) + { + data.next.show(); + } + break; + case "yes": + /***************************** + * circular scrolling: yes + *****************************/ + var memo = 0, memo_index = []; + /*************************************************************** + * edit the current item index as a function of the elements to + * slide in a single step: edit right away so that we can do + * the next steps "forward" + ***************************************************************/ + data.current -= data.options.scrolling_items; + /********************************************************* + * control that the current element has not index < 0 + *********************************************************/ + if(data.current < 0) + { + data.current += data.num_items; + } + /******************************************************************** + * displacement calculation based on the elements to slide in a + * single step and memorization of those that have to be repositioned + * later + ********************************************************************/ + for (k1 = data.current; k1 < data.current + data.options.scrolling_items; k1++) + { + var k3 = k1; + /*********************************************** + * control that the index does not exceed the + * total number of the elements + ***********************************************/ + if(k1 >= data.num_items) + { + k3 = k1 - data.num_items; + } + shift_bottom += data.item.eq(k3).outerHeight(true); + memo_index[memo]= k3; + + memo ++; + } + /****************************************************************************** + * calculating the width of the viewport on the basis of the visible elements + * AFTER the scrolling + ******************************************************************************/ + for (k2 = data.current; k2 < data.current + data.options.visible_items; k2++) + { + var k4 = k2; + /*********************************************** + * control that the index does not exceed the + * total number of the elements + ***********************************************/ + if(k2 >= data.num_items) + { + k4 = k2 - data.num_items; + } + viewport_height += data.item.eq(k4).outerHeight(true); + } + /************************************************************************ + * repositioning is calculated based on the location of the first element + * of the list. Special care to the repositioning of the last element + * that needs to be recalculated AFTER the first was eventually relocated + ************************************************************************/ + var position = data.item.first().position(), + top_repos = position.top - data.wrapper_height; + + for(k5 = 0; k5 < memo_index.length; k5++) + { + data.item.eq(memo_index[k5]).css("top", top_repos); + if(memo_index[k5] == 0) + { + var position0 = data.item.eq(0).position(), + new_top_repos = position0.top - data.wrapper_height; + for(k6 = 0; k6 < k5; k6++) + { + data.item.eq(memo_index[k6]).css("top", new_top_repos); + } + } + } + /************************************************************ + * timeout of 200ms is necessary to wait before making the + * scrolling animation, otherwise we can not properly manage + * the repositioning of the list elements + ************************************************************/ + setTimeout(function() + { + /********************************************* + * viewport width animation + *********************************************/ + data.viewport.animate({ + "height": viewport_height + }, data.options.speed, data.options.easing); + /************************************ + * list elements scrolling animation + ***********************************/ + data.item.animate({ + "top": "+=" + shift_bottom + }, data.options.speed, data.options.easing); + /*********************************************************** + * once all elements animations have finished + * (deferred object) + **********************************************************/ + data.item.promise().done(function() + { + /********************************************* + * re bind buttons "click" event that have + * been detached from the handle to manage + * properly the time of animation + ********************************************/ + data.next.on("click touchstart touchend",nextHandle); + data.prev.on("click touchstart touchend",prevHandle); + data.viewport.on('touchend', function(e) { + if (e.originalEvent.touches == undefined) { + var touch = e; + } + else { + var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + } + mm.dx = touch.pageX - mm.ox; + mm.dy = touch.pageY - mm.oy; + mm.endTime = new Date().getTime() - mm.startTime; + + if(data.options.orientation == "horizontal") { + if(mm.dx < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dx > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + else { + if(mm.dy < -mm.swipeTreshold && mm.endTime < mm.allowedTime) { + nextHandle(e,data.viewport); + } + else if(mm.dy > mm.swipeTreshold && mm.endTime < mm.allowedTime) { + prevHandle(e,data.viewport); + } + } + }); + }); + }, 200); + break; + } + break; + } + /************************************ + * saving als instance data and + * returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************************************** + * start function for automatic scrolling + * @param {Object} id: instance or ID of the element that has + * called the function + **************************************************************/ + start: function(id) + { + id = find_instance(id); + var data = als[id]; + /********************************************************** + * stopping any previous automatic scrolling + *********************************************************/ + if(data.timer != 0) + { + clearInterval(data.timer); + } + /************************************ + * depending on the direction you + * choose automatic scrolling begins + ***********************************/ + switch(data.options.direction) + { + /************************************************ + * if left or up (that means "forward") + ************************************************/ + case "left": + case "up": + default: + /************************************ + * detachment from the handler buttons + * and the animation forward start + * (next function) + ************************************/ + data.timer = setInterval(function(){ + data.next.off(); + data.prev.off(); + data.viewport.off("touchend"); + $.fn.als('next',id); + },data.options.interval); + break; + /*************************************************** + * if right or down (that means "backward") + ***************************************************/ + case "right": + case "down": + /************************************ + * detachment from the handler buttons + * and the animation forward start + * (prev function) + ************************************/ + data.timer = setInterval(function(){ + data.prev.off(); + data.next.off(); + data.viewport.off("touchend"); + $.fn.als('prev',id); + },data.options.interval); + break; + } + /************************************ + * saving als instance data and + * returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************************************** + * stop function for automatic scrolling + * @param {Object} id: instance or ID of the element that + * called the function + **************************************************************/ + stop: function(id) + { + id = find_instance(id); + var data = als[id]; + /******************************** + * stop autoscrolling + *******************************/ + clearInterval(data.timer); + /************************************ + * saving data into als instance + * and returning als object + ***********************************/ + als[id] = data; + return als; + }, + /************************************** + * function that destroys als instance + **************************************/ + destroy: function() + { + id = find_instance($(this).attr("data-id")); + var data = als[id]; + data.prev.off(); + data.next.off(); + data.viewport.off(); + $.fn.als("stop",id); + $.removeData(data, "als"); + this.unbind(); + this.element = null; + } + } + + /************************** + ************************** + * service functions + ************************** + **************************/ + + /******************************************************************** + * function to find the current plugin instance + * @param {Object} id: plugin instance od ID of the element that + * called the plugin + ********************************************************************/ + function find_instance(id) + { + if(typeof(id) === "string") + { + var position = id.indexOf("_"); + if(position != -1) + { + id = id.substr(position+1); + } + } + return id + } + + /**************************************************** + * function that manages "click" action on next button + * @param e event, $obj object + ***************************************************/ + function nextHandle(e,$obj) + { + e.preventDefault(); + if($obj === undefined) + $obj = $(this); + var id = find_instance($obj.attr("data-id")), + data = als[id]; + /********************************************* + * unbinding next and prev buttons so that + * they don't interfere with current animation + ********************************************/ + data.next.off(); + data.prev.off(); + data.viewport.off("touchend"); + if(data.options.autoscroll === "yes") + { + $.fn.als("stop",id); + } + /******************************************** + * calling next function on this instance + ********************************************/ + $.fn.als("next",id); + if(data.options.autoscroll === "yes") + { + $.fn.als("start",id); + } + } + + /****************************************************** + * function that manages "click" action on prev button + * @param e event, $obj object + ******************************************************/ + function prevHandle(e,$obj) + { + e.preventDefault(); + if($obj === undefined) + $obj = $(this); + var id = find_instance($obj.attr("data-id")), + data = als[id]; + /*********************************************** + * unbinding next and prev buttons so that + * they don't interfere with current animation + **********************************************/ + data.prev.off(); + data.next.off(); + data.viewport.off("touchend"); + if(data.options.autoscroll === "yes") + { + $.fn.als("stop",id); + } + /********************************************* + * calling prev function on this instance + *********************************************/ + $.fn.als("prev",id); + if(data.options.autoscroll === "yes") + { + $.fn.als("start",id); + } + } + + /******************************************************************** + * function that generates the plugin and instantiates its methods + * @param {Object} method + *******************************************************************/ + $.fn.als = function( method ) + { + if ( methods[method] ) + { + return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 )); + } + else if ( typeof method === 'object' || ! method ) + { + return methods.init.apply( this, arguments ); + } + else + { + $.error( 'Method ' + method + ' does not exist on jQuery.als' ); + } + }; + +})(jQuery); \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/login.js b/hyhproject/home2/view/default/js/login.js new file mode 100755 index 0000000..6cba749 --- /dev/null +++ b/hyhproject/home2/view/default/js/login.js @@ -0,0 +1,218 @@ +function login(typ){ + var params = WST.getParams('.ipt'); + if(!$('#loginName').isValid())return; + if(!$('#loginPwd').isValid())return; + if(!$('#verifyCode').isValid())return; + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + } + var ll = WST.load({msg:'正在处理数据,请稍后...'}); + $.post(WST.U('home/users/checkLogin'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg, {icon: 1}); + var url = json.url; + if(WST.blank(url)){ + location.href = url; + }else{ + if(typ==2){ + location.href=WST.U('home/shops/index'); + }else if(typ==1){ + location.href=WST.U('home/users/index'); + }else{ + parent.location.reload(); + } + } + }else{ + layer.close(ll); + WST.msg(json.msg, {icon: 5}); + WST.getVerify('#verifyImg'); + } + + }); + return true; +} + + +function showProtocol(){ + layer.open({ + type: 2, + title: '用户注册协议', + shadeClose: true, + shade: 0.8, + area: ['1000px', ($(window).height() - 50) +'px'], + content: [WST.U('home/users/protocol')], + btn: ['同意并注册'], + yes: function(index, layero){ + layer.close(index); + } + }); +} + +var time = 0; +var isSend = false; +var isUse = false; +var index2 = null; +function getVerifyCode(){ + var params = {}; + params.userPhone = $.trim($("#loginName").val()); + if(params.userPhone==''){ + WST.msg('请输入手机号码!', {icon: 5}); + return; + } + if(isSend )return; + isSend = true; + if(window.conf.SMS_VERFY=='1'){ + var html = []; + html.push('<table class="wst-smsverfy"><tr><td width="80" align="right">'); + html.push('验证码:</td><td><input type="text" id="smsVerfyl" size="12" class="wst-text" maxLength="8">'); + html.push('<img style="vertical-align:middle;cursor:pointer;height:39px;" class="verifyImgd" src="'+WST.DOMAIN+'/hyhproject/Home/View/default/images/clickForVerify.png" title="刷新验证码" onclick="javascript:WST.getVerify(\'.verifyImgd\')"/>'); + html.push('</td></tr></table>'); + index2 = layer.open({ + title:'请输入验证码', + type: 1, + area: ['420px', '150px'], //宽高 + content: html.join(''), + btn: ['发送验证码'], + success: function(layero, index){ + WST.getVerify('.verifyImgd'); + }, + yes: function(index, layero){ + isSend = true; + params.smsVerfy = $.trim($('#smsVerfyl').val()); + if(params.smsVerfy==''){ + WST.msg('请输入验证码!', {icon: 5}); + return; + } + getPhoneVerifyCode(params); + }, + cancel:function(){ + isSend = false; + } + }); + }else{ + isSend = true; + getPhoneVerifyCode(params); + } +} + +function getPhoneVerifyCode(params){ + WST.msg('正在发送短信,请稍后...',{time:600000}); + $.post(WST.U('home/users/getPhoneVerifyCode'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg, {icon: 5}); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注意查收'); + time = 120; + $('#timeTips').css('width','100px'); + $('#timeTips').html('获取验证码(120)'); + $('#mobileCode').val(json.phoneVerifyCode); + var task = setInterval(function(){ + time--; + $('#timeTips').html('获取验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeTips').html("重新获取验证码"); + } + },1000); + } + if(json.status!=-2)layer.close(index2); + }); +} +function initRegist(){ + // 阻止按下回车键时触发短信验证码弹窗 + document.onkeydown=function(event){ + var e = event || window.event || arguments.callee.caller.arguments[0]; + if(e && e.keyCode==13){ // enter 键 + $('#reg_butt').submit(); + return false; + } + } + $('#reg_form').validator({ + rules: { + loginName: function(element) { + if(this.test(element, "mobile")===true){ + if(window.conf.SMS_OPEN=='1'){ + $("#mobileCodeDiv").show(); + $("#refreshCode").hide(); + $("#authCodeDiv").hide(); + $("#nameType").val('3'); + }else{ + $("#nameType").val('2'); + } + } + return this.test(element, "mobile")===true || '请填写有效的手机号'; + }, + mobileCode: function(element){ + if(window.conf.SMS_OPEN=='1'){ + if(this.test(document.getElementById("loginName"), "mobile")===true){ + return true; + } + } + return false; + }, + verifyCode: function(element){ + if(this.test(document.getElementById("loginName"), "mobile")===false){ + return true; + }else{ + return false; + } + }, + //自定义remote规则(注意:虽然remote规则已经内置,但这里的remote会优先于内置) + remote: function(element){ + return $.post(WST.U('home/users/checkLoginKey'),{"loginName":element.value},function(data,textStatus){ + + }); + } + }, + fields: { + 'loginName': 'required; loginName; remote;', + 'loginPwd' : '密码:required; password;', + 'reUserPwd': '确认密码:required; match(loginPwd);', + 'mobileCode': {rule:"required(mobileCode)",msg:{required:'请输入短信验证码'}}, + 'verifyCode': {rule:"required(verifyCode)",msg:{required:'请输入验证码'}} + }, + // 表单验证通过后,ajax提交 + valid: function(form){ + var me = this; + // ajax提交表单之前,先禁用submit + me.holdSubmit(); + var params = WST.getParams('.wst_ipt'); + if(WST.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.reUserPwd = rsa.encrypt(params.reUserPwd); + } + $("#reg_butt").css('color', '#999').text('正在提交..'); + $.post(WST.U('home/users/toRegist'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg('注册成功,正在跳转登录!', {icon: 1}, function(){ + var url = json.url; + if(WST.blank(url)){ + location.href = url; + }else{ + location.href=WST.U('home/users/index'); + } + }); + }else{ + me.holdSubmit(false); + WST.getVerify('#verifyImg'); + WST.msg(json.msg, {icon: 5}); + } + + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/qrcode.js b/hyhproject/home2/view/default/js/qrcode.js new file mode 100755 index 0000000..b2ae4a6 --- /dev/null +++ b/hyhproject/home2/view/default/js/qrcode.js @@ -0,0 +1,88 @@ + +var qrcode=function(){var qrcode=function(typeNumber,errorCorrectLevel){var PAD0=0xEC;var PAD1=0x11;var _typeNumber=typeNumber;var _errorCorrectLevel=QRErrorCorrectLevel[errorCorrectLevel];var _modules=null;var _moduleCount=0;var _dataCache=null;var _dataList=new Array();var _this={};var makeImpl=function(test,maskPattern){_moduleCount=_typeNumber*4+17;_modules=function(moduleCount){var modules=new Array(moduleCount);for(var row=0;row<moduleCount;row+=1){modules[row]=new Array(moduleCount);for(var col=0;col<moduleCount;col+=1){modules[row][col]=null;}} +return modules;}(_moduleCount);setupPositionProbePattern(0,0);setupPositionProbePattern(_moduleCount-7,0);setupPositionProbePattern(0,_moduleCount-7);setupPositionAdjustPattern();setupTimingPattern();setupTypeInfo(test,maskPattern);if(_typeNumber>=7){setupTypeNumber(test);} +if(_dataCache==null){_dataCache=createData(_typeNumber,_errorCorrectLevel,_dataList);} +mapData(_dataCache,maskPattern);};var setupPositionProbePattern=function(row,col){for(var r=-1;r<=7;r+=1){if(row+r<=-1||_moduleCount<=row+r)continue;for(var c=-1;c<=7;c+=1){if(col+c<=-1||_moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}};var getBestMaskPattern=function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i+=1){makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(_this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} +return pattern;};var setupTimingPattern=function(){for(var r=8;r<_moduleCount-8;r+=1){if(_modules[r][6]!=null){continue;} +_modules[r][6]=(r%2==0);} +for(var c=8;c<_moduleCount-8;c+=1){if(_modules[6][c]!=null){continue;} +_modules[6][c]=(c%2==0);}};var setupPositionAdjustPattern=function(){var pos=QRUtil.getPatternPosition(_typeNumber);for(var i=0;i<pos.length;i+=1){for(var j=0;j<pos.length;j+=1){var row=pos[i];var col=pos[j];if(_modules[row][col]!=null){continue;} +for(var r=-2;r<=2;r+=1){for(var c=-2;c<=2;c+=1){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}}}};var setupTypeNumber=function(test){var bits=QRUtil.getBCHTypeNumber(_typeNumber);for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[Math.floor(i/3)][i%3+_moduleCount-8-3]=mod;} +for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[i%3+_moduleCount-8-3][Math.floor(i/3)]=mod;}};var setupTypeInfo=function(test,maskPattern){var data=(_errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<6){_modules[i][8]=mod;}else if(i<8){_modules[i+1][8]=mod;}else{_modules[_moduleCount-15+i][8]=mod;}} +for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<8){_modules[8][_moduleCount-i-1]=mod;}else if(i<9){_modules[8][15-i-1+1]=mod;}else{_modules[8][15-i-1]=mod;}} +_modules[_moduleCount-8][8]=(!test);};var mapData=function(data,maskPattern){var inc=-1;var row=_moduleCount-1;var bitIndex=7;var byteIndex=0;var maskFunc=QRUtil.getMaskFunction(maskPattern);for(var col=_moduleCount-1;col>0;col-=2){if(col==6)col-=1;while(true){for(var c=0;c<2;c+=1){if(_modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} +var mask=maskFunc(row,col-c);if(mask){dark=!dark;} +_modules[row][col-c]=dark;bitIndex-=1;if(bitIndex==-1){byteIndex+=1;bitIndex=7;}}} +row+=inc;if(row<0||_moduleCount<=row){row-=inc;inc=-inc;break;}}}};var createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r+=1){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i+=1){dcdata[r][i]=0xff&buffer.getBuffer()[i+offset];} +offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=qrPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i+=1){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.getAt(modIndex):0;}} +var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalCodeCount+=rsBlocks[i].totalCount;} +var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<dcdata[r].length){data[index]=dcdata[r][i];index+=1;}}} +for(var i=0;i<maxEcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<ecdata[r].length){data[index]=ecdata[r][i];index+=1;}}} +return data;};var createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=qrBitBuffer();for(var i=0;i<dataList.length;i+=1){var data=dataList[i];buffer.put(data.getMode(),4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.getMode(),typeNumber));data.write(buffer);} +var totalDataCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalDataCount+=rsBlocks[i].dataCount;} +if(buffer.getLengthInBits()>totalDataCount*8){throw new Error('code length overflow. (' ++buffer.getLengthInBits() ++'>' ++totalDataCount*8 ++')');} +if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} +while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} +while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD1,8);} +return createBytes(buffer,rsBlocks);};_this.addData=function(data){var newData=qr8BitByte(data);_dataList.push(newData);_dataCache=null;};_this.isDark=function(row,col){if(row<0||_moduleCount<=row||col<0||_moduleCount<=col){throw new Error(row+','+col);} +return _modules[row][col];};_this.getModuleCount=function(){return _moduleCount;};_this.make=function(){makeImpl(false,getBestMaskPattern());};_this.createTableTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var qrHtml='';qrHtml+='<table style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: '+margin+'px;';qrHtml+='">';qrHtml+='<tbody>';for(var r=0;r<_this.getModuleCount();r+=1){qrHtml+='<tr>';for(var c=0;c<_this.getModuleCount();c+=1){qrHtml+='<td style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: 0px;';qrHtml+=' width: '+cellSize+'px;';qrHtml+=' height: '+cellSize+'px;';qrHtml+=' background-color: ';qrHtml+=_this.isDark(r,c)?'#000000':'#ffffff';qrHtml+=';';qrHtml+='"/>';} +qrHtml+='</tr>';} +qrHtml+='</tbody>';qrHtml+='</table>';return qrHtml;};_this.createImgTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var size=_this.getModuleCount()*cellSize+margin*2;var min=margin;var max=size-margin;return createImgTag(size,size,function(x,y){if(min<=x&&x<max&&min<=y&&y<max){var c=Math.floor((x-min)/cellSize);var r=Math.floor((y-min)/cellSize);return _this.isDark(r,c)?0:1;}else{return 1;}});};return _this;};qrcode.stringToBytes=function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);bytes.push(c&0xff);} +return bytes;};qrcode.createStringToBytes=function(unicodeData,numChars){var unicodeMap=function(){var bin=base64DecodeInputStream(unicodeData);var read=function(){var b=bin.read();if(b==-1)throw new Error();return b;};var count=0;var unicodeMap={};while(true){var b0=bin.read();if(b0==-1)break;var b1=read();var b2=read();var b3=read();var k=String.fromCharCode((b0<<8)|b1);var v=(b2<<8)|b3;unicodeMap[k]=v;count+=1;} +if(count!=numChars){throw new Error(count+' != '+numChars);} +return unicodeMap;}();var unknownChar='?'.charCodeAt(0);return function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);if(c<128){bytes.push(c);}else{var b=unicodeMap[s.charAt(i)];if(typeof b=='number'){if((b&0xff)==b){bytes.push(b);}else{bytes.push(b>>>8);bytes.push(b&0xff);}}else{bytes.push(unknownChar);}}} +return bytes;};};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil=function(){var PATTERN_POSITION_TABLE=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]];var G15=(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0);var G18=(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0);var G15_MASK=(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1);var _this={};var getBCHDigit=function(data){var digit=0;while(data!=0){digit+=1;data>>>=1;} +return digit;};_this.getBCHTypeInfo=function(data){var d=data<<10;while(getBCHDigit(d)-getBCHDigit(G15)>=0){d^=(G15<<(getBCHDigit(d)-getBCHDigit(G15)));} +return((data<<10)|d)^G15_MASK;};_this.getBCHTypeNumber=function(data){var d=data<<12;while(getBCHDigit(d)-getBCHDigit(G18)>=0){d^=(G18<<(getBCHDigit(d)-getBCHDigit(G18)));} +return(data<<12)|d;};_this.getPatternPosition=function(typeNumber){return PATTERN_POSITION_TABLE[typeNumber-1];};_this.getMaskFunction=function(maskPattern){switch(maskPattern){case QRMaskPattern.PATTERN000:return function(i,j){return(i+j)%2==0;};case QRMaskPattern.PATTERN001:return function(i,j){return i%2==0;};case QRMaskPattern.PATTERN010:return function(i,j){return j%3==0;};case QRMaskPattern.PATTERN011:return function(i,j){return(i+j)%3==0;};case QRMaskPattern.PATTERN100:return function(i,j){return(Math.floor(i/2)+Math.floor(j/3))%2==0;};case QRMaskPattern.PATTERN101:return function(i,j){return(i*j)%2+(i*j)%3==0;};case QRMaskPattern.PATTERN110:return function(i,j){return((i*j)%2+(i*j)%3)%2==0;};case QRMaskPattern.PATTERN111:return function(i,j){return((i*j)%3+(i+j)%2)%2==0;};default:throw new Error('bad maskPattern:'+maskPattern);}};_this.getErrorCorrectPolynomial=function(errorCorrectLength){var a=qrPolynomial([1],0);for(var i=0;i<errorCorrectLength;i+=1){a=a.multiply(qrPolynomial([1,QRMath.gexp(i)],0));} +return a;};_this.getLengthInBits=function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error('mode:'+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error('mode:'+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error('mode:'+mode);}}else{throw new Error('type:'+type);}};_this.getLostPoint=function(qrcode){var moduleCount=qrcode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount;col+=1){var sameCount=0;var dark=qrcode.isDark(row,col);for(var r=-1;r<=1;r+=1){if(row+r<0||moduleCount<=row+r){continue;} +for(var c=-1;c<=1;c+=1){if(col+c<0||moduleCount<=col+c){continue;} +if(r==0&&c==0){continue;} +if(dark==qrcode.isDark(row+r,col+c)){sameCount+=1;}}} +if(sameCount>5){lostPoint+=(3+sameCount-5);}}};for(var row=0;row<moduleCount-1;row+=1){for(var col=0;col<moduleCount-1;col+=1){var count=0;if(qrcode.isDark(row,col))count+=1;if(qrcode.isDark(row+1,col))count+=1;if(qrcode.isDark(row,col+1))count+=1;if(qrcode.isDark(row+1,col+1))count+=1;if(count==0||count==4){lostPoint+=3;}}} +for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount-6;col+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row,col+1)&&qrcode.isDark(row,col+2)&&qrcode.isDark(row,col+3)&&qrcode.isDark(row,col+4)&&!qrcode.isDark(row,col+5)&&qrcode.isDark(row,col+6)){lostPoint+=40;}}} +for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount-6;row+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row+1,col)&&qrcode.isDark(row+2,col)&&qrcode.isDark(row+3,col)&&qrcode.isDark(row+4,col)&&!qrcode.isDark(row+5,col)&&qrcode.isDark(row+6,col)){lostPoint+=40;}}} +var darkCount=0;for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount;row+=1){if(qrcode.isDark(row,col)){darkCount+=1;}}} +var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;};return _this;}();var QRMath=function(){var EXP_TABLE=new Array(256);var LOG_TABLE=new Array(256);for(var i=0;i<8;i+=1){EXP_TABLE[i]=1<<i;} +for(var i=8;i<256;i+=1){EXP_TABLE[i]=EXP_TABLE[i-4]^EXP_TABLE[i-5]^EXP_TABLE[i-6]^EXP_TABLE[i-8];} +for(var i=0;i<255;i+=1){LOG_TABLE[EXP_TABLE[i]]=i;} +var _this={};_this.glog=function(n){if(n<1){throw new Error('glog('+n+')');} +return LOG_TABLE[n];};_this.gexp=function(n){while(n<0){n+=255;} +while(n>=256){n-=255;} +return EXP_TABLE[n];};return _this;}();function qrPolynomial(num,shift){if(typeof num.length=='undefined'){throw new Error(num.length+'/'+shift);} +var _num=function(){var offset=0;while(offset<num.length&&num[offset]==0){offset+=1;} +var _num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i+=1){_num[i]=num[i+offset];} +return _num;}();var _this={};_this.getAt=function(index){return _num[index];};_this.getLength=function(){return _num.length;};_this.multiply=function(e){var num=new Array(_this.getLength()+e.getLength()-1);for(var i=0;i<_this.getLength();i+=1){for(var j=0;j<e.getLength();j+=1){num[i+j]^=QRMath.gexp(QRMath.glog(_this.getAt(i))+QRMath.glog(e.getAt(j)));}} +return qrPolynomial(num,0);};_this.mod=function(e){if(_this.getLength()-e.getLength()<0){return _this;} +var ratio=QRMath.glog(_this.getAt(0))-QRMath.glog(e.getAt(0));var num=new Array(_this.getLength());for(var i=0;i<_this.getLength();i+=1){num[i]=_this.getAt(i);} +for(var i=0;i<e.getLength();i+=1){num[i]^=QRMath.gexp(QRMath.glog(e.getAt(i))+ratio);} +return qrPolynomial(num,0).mod(e);};return _this;};var QRRSBlock=function(){var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16]];var qrRSBlock=function(totalCount,dataCount){var _this={};_this.totalCount=totalCount;_this.dataCount=dataCount;return _this;};var _this={};var getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};_this.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=getRsBlockTable(typeNumber,errorCorrectLevel);if(typeof rsBlock=='undefined'){throw new Error('bad rs block @ typeNumber:'+typeNumber+'/errorCorrectLevel:'+errorCorrectLevel);} +var length=rsBlock.length/3;var list=new Array();for(var i=0;i<length;i+=1){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j+=1){list.push(qrRSBlock(totalCount,dataCount));}} +return list;};return _this;}();var qrBitBuffer=function(){var _buffer=new Array();var _length=0;var _this={};_this.getBuffer=function(){return _buffer;};_this.getAt=function(index){var bufIndex=Math.floor(index/8);return((_buffer[bufIndex]>>>(7-index%8))&1)==1;};_this.put=function(num,length){for(var i=0;i<length;i+=1){_this.putBit(((num>>>(length-i-1))&1)==1);}};_this.getLengthInBits=function(){return _length;};_this.putBit=function(bit){var bufIndex=Math.floor(_length/8);if(_buffer.length<=bufIndex){_buffer.push(0);} +if(bit){_buffer[bufIndex]|=(0x80>>>(_length%8));} +_length+=1;};return _this;};var qr8BitByte=function(data){var _mode=QRMode.MODE_8BIT_BYTE;var _data=data;var _bytes=qrcode.stringToBytes(data);var _this={};_this.getMode=function(){return _mode;};_this.getLength=function(buffer){return _bytes.length;};_this.write=function(buffer){for(var i=0;i<_bytes.length;i+=1){buffer.put(_bytes[i],8);}};return _this;};var byteArrayOutputStream=function(){var _bytes=new Array();var _this={};_this.writeByte=function(b){_bytes.push(b&0xff);};_this.writeShort=function(i){_this.writeByte(i);_this.writeByte(i>>>8);};_this.writeBytes=function(b,off,len){off=off||0;len=len||b.length;for(var i=0;i<len;i+=1){_this.writeByte(b[i+off]);}};_this.writeString=function(s){for(var i=0;i<s.length;i+=1){_this.writeByte(s.charCodeAt(i));}};_this.toByteArray=function(){return _bytes;};_this.toString=function(){var s='';s+='[';for(var i=0;i<_bytes.length;i+=1){if(i>0){s+=',';} +s+=_bytes[i];} +s+=']';return s;};return _this;};var base64EncodeOutputStream=function(){var _buffer=0;var _buflen=0;var _length=0;var _base64='';var _this={};var writeEncoded=function(b){_base64+=String.fromCharCode(encode(b&0x3f));};var encode=function(n){if(n<0){}else if(n<26){return 0x41+n;}else if(n<52){return 0x61+(n-26);}else if(n<62){return 0x30+(n-52);}else if(n==62){return 0x2b;}else if(n==63){return 0x2f;} +throw new Error('n:'+n);};_this.writeByte=function(n){_buffer=(_buffer<<8)|(n&0xff);_buflen+=8;_length+=1;while(_buflen>=6){writeEncoded(_buffer>>>(_buflen-6));_buflen-=6;}};_this.flush=function(){if(_buflen>0){writeEncoded(_buffer<<(6-_buflen));_buffer=0;_buflen=0;} +if(_length%3!=0){var padlen=3-_length%3;for(var i=0;i<padlen;i+=1){_base64+='=';}}};_this.toString=function(){return _base64;};return _this;};var base64DecodeInputStream=function(str){var _str=str;var _pos=0;var _buffer=0;var _buflen=0;var _this={};_this.read=function(){while(_buflen<8){if(_pos>=_str.length){if(_buflen==0){return-1;} +throw new Error('unexpected end of file./'+_buflen);} +var c=_str.charAt(_pos);_pos+=1;if(c=='='){_buflen=0;return-1;}else if(c.match(/^\s$/)){continue;} +_buffer=(_buffer<<6)|decode(c.charCodeAt(0));_buflen+=6;} +var n=(_buffer>>>(_buflen-8))&0xff;_buflen-=8;return n;};var decode=function(c){if(0x41<=c&&c<=0x5a){return c-0x41;}else if(0x61<=c&&c<=0x7a){return c-0x61+26;}else if(0x30<=c&&c<=0x39){return c-0x30+52;}else if(c==0x2b){return 62;}else if(c==0x2f){return 63;}else{throw new Error('c:'+c);}};return _this;};var gifImage=function(width,height){var _width=width;var _height=height;var _data=new Array(width*height);var _this={};_this.setPixel=function(x,y,pixel){_data[y*_width+x]=pixel;};_this.write=function(out){out.writeString('GIF87a');out.writeShort(_width);out.writeShort(_height);out.writeByte(0x80);out.writeByte(0);out.writeByte(0);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0xff);out.writeByte(0xff);out.writeByte(0xff);out.writeString(',');out.writeShort(0);out.writeShort(0);out.writeShort(_width);out.writeShort(_height);out.writeByte(0);var lzwMinCodeSize=2;var raster=getLZWRaster(lzwMinCodeSize);out.writeByte(lzwMinCodeSize);var offset=0;while(raster.length-offset>255){out.writeByte(255);out.writeBytes(raster,offset,255);offset+=255;} +out.writeByte(raster.length-offset);out.writeBytes(raster,offset,raster.length-offset);out.writeByte(0x00);out.writeString(';');};var bitOutputStream=function(out){var _out=out;var _bitLength=0;var _bitBuffer=0;var _this={};_this.write=function(data,length){if((data>>>length)!=0){throw new Error('length over');} +while(_bitLength+length>=8){_out.writeByte(0xff&((data<<_bitLength)|_bitBuffer));length-=(8-_bitLength);data>>>=(8-_bitLength);_bitBuffer=0;_bitLength=0;} +_bitBuffer=(data<<_bitLength)|_bitBuffer;_bitLength=_bitLength+length;};_this.flush=function(){if(_bitLength>0){_out.writeByte(_bitBuffer);}};return _this;};var getLZWRaster=function(lzwMinCodeSize){var clearCode=1<<lzwMinCodeSize;var endCode=(1<<lzwMinCodeSize)+1;var bitLength=lzwMinCodeSize+1;var table=lzwTable();for(var i=0;i<clearCode;i+=1){table.add(String.fromCharCode(i));} +table.add(String.fromCharCode(clearCode));table.add(String.fromCharCode(endCode));var byteOut=byteArrayOutputStream();var bitOut=bitOutputStream(byteOut);bitOut.write(clearCode,bitLength);var dataIndex=0;var s=String.fromCharCode(_data[dataIndex]);dataIndex+=1;while(dataIndex<_data.length){var c=String.fromCharCode(_data[dataIndex]);dataIndex+=1;if(table.contains(s+c)){s=s+c;}else{bitOut.write(table.indexOf(s),bitLength);if(table.size()<0xfff){if(table.size()==(1<<bitLength)){bitLength+=1;} +table.add(s+c);} +s=c;}} +bitOut.write(table.indexOf(s),bitLength);bitOut.write(endCode,bitLength);bitOut.flush();return byteOut.toByteArray();};var lzwTable=function(){var _map={};var _size=0;var _this={};_this.add=function(key){if(_this.contains(key)){throw new Error('dup key:'+key);} +_map[key]=_size;_size+=1;};_this.size=function(){return _size;};_this.indexOf=function(key){return _map[key];};_this.contains=function(key){return typeof _map[key]!='undefined';};return _this;};return _this;};var createImgTag=function(width,height,getPixel,alt){var gif=gifImage(width,height);for(var y=0;y<height;y+=1){for(var x=0;x<width;x+=1){gif.setPixel(x,y,getPixel(x,y));}} +var b=byteArrayOutputStream();gif.write(b);var base64=base64EncodeOutputStream();var bytes=b.toByteArray();for(var i=0;i<bytes.length;i+=1){base64.writeByte(bytes[i]);} +base64.flush();var img='';img+='<img';img+='\u0020src="';img+='data:image/gif;base64,';img+=base64;img+='"';img+='\u0020width="';img+=width;img+='"';img+='\u0020height="';img+=height;img+='"';if(alt){img+='\u0020alt="';img+=alt;img+='"';} +img+='/>';return img;};return qrcode;}();/* |xGv00|ca8fc6bde81a353e7cede123b304bdb9 */ \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/right_cart.js b/hyhproject/home2/view/default/js/right_cart.js new file mode 100755 index 0000000..9b2d9ed --- /dev/null +++ b/hyhproject/home2/view/default/js/right_cart.js @@ -0,0 +1,208 @@ +$(document).ready(function(){ + var cartHeight = WST.pageHeight()-120; + $('.toolbar-tab').hover(function (){ $(this).find('.tab-text').addClass("tbar-tab-hover"); $(this).find('.footer-tab-text').addClass("tbar-tab-footer-hover"); $(this).addClass("tbar-tab-selected");},function(){ $(this).find('.tab-text').removeClass("tbar-tab-hover"); $(this).find('.footer-tab-text').removeClass("tbar-tab-footer-hover"); $(this).removeClass("tbar-tab-selected"); }); + $('.j-close').click(function(){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + $('.toolbar-wrap').removeClass('toolbar-open'); + }else{ + $('.toolbar-wrap').addClass('toolbar-open'); + } + }) + $('.j-global-toolbar').siblings().click(function(){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + $('.toolbar-wrap').removeClass('toolbar-open'); + } + }) + $('.tbar-tab-cart').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-follow').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的关注</em>"; + $('.tbar-tab-follow').append(info); + $('.tbar-tab-follow').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-history').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.tbar-tab-history').append(info); + $('.tbar-tab-history').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css({'visibility':"visible","z-index":"1"}); + getRightCart(); + }else{ + var info = "<em class='tab-text '>我的关注</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css({'visibility':"visible","z-index":"1"}); + $('.tbar-panel-follow').css('visibility','hidden'); + $('.tbar-panel-history').css('visibility','hidden'); + $('.toolbar-wrap').addClass('toolbar-open'); + $('#cart-panel').css('height',cartHeight+"px").css('overflow-y','auto'); + getRightCart(); + } + }); + $('.tbar-tab-follow').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-cart').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>购物车</em>"; + $('.tbar-tab-cart').append(info); + $('.tbar-tab-cart').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-history').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.tbar-tab-history').append(info); + $('.tbar-tab-history').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-follow').css({'visibility':"visible","z-index":"1"}); + + }else{ + var info = "<em class='tab-text '>我的关注</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + + + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css('visibility','hidden'); + $('.tbar-panel-follow').css({'visibility':"visible","z-index":"1"}); + $('.tbar-panel-history').css('visibility','hidden'); + $('.toolbar-wrap').addClass('toolbar-open'); + } + }); + $('.tbar-tab-history').click(function (){ + if($('.toolbar-wrap').hasClass('toolbar-open')){ + if($(this).find('.tab-text').length > 0){ + if(! $('.tbar-tab-follow').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>我的关注</em>"; + $('.tbar-tab-follow').append(info); + $('.tbar-tab-follow').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-follow').css({'visibility':"hidden","z-index":"-1"}); + } + if(! $('.tbar-tab-cart').find('.tab-text').length > 0){ + var info = "<em class='tab-text '>购物车</em>"; + $('.tbar-tab-cart').append(info); + $('.tbar-tab-cart').removeClass('tbar-tab-click-selected'); + $('.tbar-panel-cart').css({'visibility':"hidden","z-index":"-1"}); + } + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-history').css({'visibility':"visible","z-index":"1"}); + getHistoryGoods(); + }else{ + var info = "<em class='tab-text '>我的足迹</em>"; + $('.toolbar-wrap').removeClass('toolbar-open'); + $(this).append(info); + $(this).removeClass('tbar-tab-click-selected'); + $('.tbar-panel-history').css({'visibility':"hidden","z-index":"-1"}); + } + + }else{ + $(this).addClass('tbar-tab-click-selected'); + $(this).find('.tab-text').remove(); + $('.tbar-panel-cart').css('visibility','hidden'); + $('.tbar-panel-follow').css('visibility','hidden'); + $('.tbar-panel-history').css({'visibility':"visible","z-index":"1"}); + $('.toolbar-wrap').addClass('toolbar-open'); + getHistoryGoods(); + } + }); +}); +function getRightCart(){ + //if(WST.conf.IS_LOGIN==0)return; + $.post(WST.U('home/carts/getCart'),'',function(data) { + var json = WST.toJson(data,true); + if(json.status==1){ + json = json.data; + if(json.carts && !json.carts.length){ + $('.j-cart-count').html(json.goodsTotalNum); + if(json.goodsTotalNum>0)$('.j-cart-count').show(); + var gettpl = document.getElementById('list-rightcart').innerHTML; + laytpl(gettpl).render(json.carts, function(html){ + $('#cart-panel').html(html); + }); + $('#j-goods-count').html(json.goodsTotalNum); + $('#j-goods-total-money').html(json.goodsTotalMoney); + }else{ + $('#cart-panel').html('<p class="right-carts-empty">购物车空空如也,赶紧去选购吧~</p>'); + } + } + }); +} +function delRightCart(obj,id){ + var dataval = $(obj).attr('dataid'); + dataval = dataval.split("|"); + if($('#shop-cart-'+dataval[0]).children().size()>2){ + $('.j-goods-item-'+dataval[1]).remove(); + }else{ + $('#shop-cart-'+dataval[0]).remove(); + } + statRightCartMoney(); + $.post(WST.U('home/carts/delCart'),{id:dataval[1],rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,{icon:2}); + } + }); +} +function jumpSettlement(){ + if($('#cart-panel').children().size()==0){ + WST.msg("您的购物车没有商品哦,请先添加商品~",{icon:2}); + return; + } + location.href=WST.U('home/carts/settlement'); +} +function getHistoryGoods(){ + $.post(WST.U('home/goods/historyByGoods'),{},function(data) { + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('list-history-goods').innerHTML; + laytpl(gettpl).render(json.data, function(html){ + $('#history-goods-panel').html(html); + }); + $('.jth-item').hover(function (){ $(this).find('.add-cart-button').show(); },function(){ $(this).find('.add-cart-button').hide(); }); + } + }); +} +function checkRightChks(cid,obj){ + WST.changeCartGoods(cid,$('#buyNum_'+cid).val(),obj.checked?1:0); + statRightCartMoney(); +} +function statRightCartMoney(){ + var cartId,goodsNum = 0,goodsMoney = 0,tmpGoodsNum = 0,tmpGoodsMoney = 0; + $('.jtc-item-goods').each(function(){ + cartId = $(this).attr('dataval'); + if($('#rcart_'+cartId).prop('checked')){ + goodsNum = parseInt($('#buyNum_'+cartId).val(),10); + goodsMoney = parseFloat($('#gprice_'+cartId).html(),10); + tmpGoodsNum++; + tmpGoodsMoney += goodsMoney*goodsNum; + } + }) + if(tmpGoodsNum==0){ + $('#j-goods-count').html(0); + $('.j-cart-count').html(0).hide(); + $('#j-goods-total-money').html(0); + }else{ + $('.j-cart-count').html(tmpGoodsNum); + $('#j-goods-count').html(tmpGoodsNum); + $('#j-goods-total-money').html(tmpGoodsMoney); + } +} diff --git a/hyhproject/home2/view/default/js/self_shop.js b/hyhproject/home2/view/default/js/self_shop.js new file mode 100755 index 0000000..bafff58 --- /dev/null +++ b/hyhproject/home2/view/default/js/self_shop.js @@ -0,0 +1,94 @@ +/*店长推荐*/ +function gpanelOver2(obj){ +var sid = $(obj).attr("id"); +var ids = sid.split("_"); +var preid = ids[0]+"_"+ids[1]; + +$("li[id^="+preid+"_]").removeClass("j-s-rec-selected"); + +$("#"+sid).addClass("j-s-rec-selected"); + +$("div[id^="+preid+"_]").hide(); +$("#"+sid+"_pl").show(); +} + +/*楼层*/ +function gpanelOver(obj){ + var sid = $(obj).attr("id"); + + var index = $(obj).attr('c'); + + var ids = sid.split("_"); + var preid = ids[0]+"_"+ids[1]; + + $("li[id^="+preid+"_]").removeClass("j-tab-selected"+index); + $("#"+sid).addClass("j-tab-selected"+index); + + $("div[id^="+preid+"_]").hide(); + $("#"+sid+"_pl").show(); +} + + + +function searchShopsGoods(){ + var params = new Array(); + params.push("shopId=" + $("#shopId").val()); + params.push("goodsName=" + $("#goodsName").val()); + document.location.href = WST.U('home/shops/home',params.join('&'),true); +} +$(function(){ + $(".s-goods").hover(function(){ + $(this).find(".s-add-cart").slideDown(100); + },function(){ + $(this).find(".s-add-cart").slideUp(100); + }); +}) + + +$(function(){ + if($('.s-wst-slide-items a').length>1)WST.slides('.s-wst-slide'); + $('.shop-cat1').hover(function(){ + $(this).addClass('ct1-hover'); + var cid = $(this).attr('cid'); + + var h = 66.3*cid+'px'; + $('.cid'+cid).css('top',h); + $('.cid'+cid).show(); + },function(){ + $(this).removeClass('ct1-hover'); + var cid = $(this).attr('cid'); + $('.cid'+cid).hide(); + }) + + + $('.shop-cat2').hover(function(){ + var cid = $(this).attr('cid'); + $('#ct1-'+cid).addClass('ct1-hover'); + $(this).show(); + },function(){ + var cid = $(this).attr('cid'); + $('#ct1-'+cid).removeClass('ct1-hover'); + $(this).hide(); + }); + + + + $('.s-cat').hover(function(){ + $('.s-cat-head').addClass('s-cat-head-hover'); + $(this).show(); + },function(){ + $('.s-cat-head').removeClass('s-cat-head-hover'); + $(this).hide(); + }); + + + $('.s-cat-head').hover(function(){ + $(this).addClass('s-cat-head-hover'); + $('.s-cat').css({left:$('.s-cat-head').offset().left}).show(); + },function(){ + $(this).removeClass('s-cat-head-hover'); + $('.s-cat').hide(); + }) + + +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/shophome.js b/hyhproject/home2/view/default/js/shophome.js new file mode 100755 index 0000000..f9c73f4 --- /dev/null +++ b/hyhproject/home2/view/default/js/shophome.js @@ -0,0 +1,39 @@ +$(function() { + WST.dropDownLayer(".wst-shop-code",".wst-shop-codes"); + $(".ck-slide-wrapper img").width(1200); + $('.ck-slide').ckSlide({ + autoPlay: true, + time:5000, + isAnimate:true, + dir: 'x' + }); + $(".wst-shop-goimg").hover(function(){ + $(this).find(".js-cart").slideDown(100); + },function(){ + $(this).find(".js-cart").slideUp(100); + }); +}); +function dropDown(obj,id){ + if( $(obj).attr('class').indexOf('js-shop-plus') > -1 ){ + $(obj).removeClass('js-shop-plus').addClass('js-shop-redu'); + $('.tree_'+id).slideUp(); + }else{ + $(obj).removeClass('js-shop-redu').addClass('js-shop-plus'); + $('.tree_'+id).slideDown(); + } +} +function searchShopsGoods(obj){ + var mdesc = $('#mdesc').val(); + if($('#msort').val() != obj)mdesc = 0; + var msort = obj; + var params = new Array(); + params.push("shopId=" + $("#shopId").val()); + params.push("msort=" + obj); + params.push("mdesc=" + ((mdesc=="0")?"1":"0")); + params.push("sprice=" + $("#sprice").val()); + params.push("eprice=" + $("#eprice").val()); + params.push("ct1=" + $("#ct1").val()); + params.push("ct2=" + $("#ct2").val()); + if($("#goodsName").val()!=undefined)params.push("goodsName=" + $("#goodsName").val()); + location.href = WST.U('home/shops/home',params.join('&'),true); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/js/shopstreet.js b/hyhproject/home2/view/default/js/shopstreet.js new file mode 100755 index 0000000..fe4c746 --- /dev/null +++ b/hyhproject/home2/view/default/js/shopstreet.js @@ -0,0 +1,18 @@ +//筛选分类 +function screenCat(id){ + location.href=WST.U('home/shops/shopstreet','id='+id,true); +} +$(function(){ + var goodsNum = $(this).find("div[class^='wst-shopstr-shopl']").length; + for(var i=1;i<=goodsNum;++i){ + $("#js-goods"+i).als({ + visible_items: 6, + scrolling_items: 1, + orientation: "horizontal", + circular: "yes", + autoscroll: "no", + start_from: 2 + }); + } + WST.dropDownLayer(".j-score",".j-scores"); +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_pay.html b/hyhproject/home2/view/default/order_pay.html new file mode 100755 index 0000000..6e97b84 --- /dev/null +++ b/hyhproject/home2/view/default/order_pay.html @@ -0,0 +1,43 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">我的购物车</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">填写核对订单信息</dd> + </dl> + <dl class="last doing"> + <dt class="s-num">3</dt> + <dd class="s-text">成功提交订单</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='success-box'> + <div class="imgs"><img class="wst-lfloat" src="__STYLE__/img/icon_success.png"/><span>订单提交成功!</span></div> + <div class="info"> + {php}$len = count($object['list'])-1;{/php} + 订单号:{volist name="$object['list']" id='vo'} + <a href='{:url("home/orders/waitPay")}' target='_blank'>{$vo['orderNo']}</a> + {if $i < $len }、{/if} + {/volist} + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 应付金额:<span>¥{$object['totalMoney']}</span> + </div> + <div class="go"> + <a href='__ROOT__/index.php' class="wst-order-success wst-cart-reda">继续购物</a> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_pay_step1.html b/hyhproject/home2/view/default/order_pay_step1.html new file mode 100755 index 0000000..6b5a722 --- /dev/null +++ b/hyhproject/home2/view/default/order_pay_step1.html @@ -0,0 +1,107 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + + <div class="pay-sbox-head"> + <a href='{$Request.root.true}'>首页</a>&nbsp;&gt;&nbsp;支付 + </div> + <div> + <div class="pay-tip1"></div> + </div> + <div class='pay-sbox'> + <div> + <div class="tips-box"> + <input type="hidden" id="orderNo" value="{$orderNo}"/> + <input type="hidden" id="isBatch" value="{$isBatch}"/> + 请及时付款,以便快速处理您的订单,在线实付金额<span class="wst-fred">&nbsp;¥{$object['totalMoney']}&nbsp;</span><span id="wst-check-orders" class="wst-check-orders">查看订单详情</span> + </div> + <div> + <div id="wst-orders-box" style="display:none;"> + <table class='wst-order-list'> + {volist name="$rs['list']" id="order"} + <thead> + <tr> + <td colspan="3" class="wst-left-noborder wst-align-left">订单号:{$order['orderNo']}</td> + <td colspan="3" class="wst-right-noborder wst-align-right">订单金额:¥{$order['needPay']}【运费:¥{$order['deliverMoney']}】</td> + </tr> + <tr class='head'> + <td colspan="2" class="wst-left-noborder">商品</th> + <th width="150">商品单价</th> + <th width="150">数量</th> + <th width="150" class="wst-right-noborder">商品总价</th> + </tr> + </thead> + <tbody class="otbody"> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <tr> + <td class="wst-left-noborder" width="64"> + <div class="goods-img"> + <a href="{:url('home/goods/detail',array('id'=>$vo['goodsId']))}" target="_blank"> + <img class='goodsImg' data-original="__IMGURL__/{$vo['goodsImg']}" title="{$vo['goodsName']}" width='60'/> + </a> + </div> + </td> + <td class="wst-align-left"> + <div>{$vo['goodsName']} + {if condition="count($vo['goodsSpecNames']) gt 0"} + 【 + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + 】 + {/if} + </div> + </td> + <td>{$vo['goodsPrice']}</td> + <td>{$vo['goodsNum']}</td> + <td class="wst-right-noborder">{$vo['goodsPrice']*$vo['goodsNum']}</td> + </tr> + {/volist} + {/volist} + </tbody> + </table> + </div> + <div class="pay-type">选择支付方式</div> + <div class="pay-list"> + <input type="hidden" id="payCode" name="payCode" /> + {volist name="$rs['payments']" id="payment"} + {if condition="$payment['isOnline'] eq 1"} + <div class="wst-payCode-{$payment['payCode']}" data="{$payment['payCode']}"></div> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + <div class="bnt-box"> + <div onclick='javascript:getPayUrl();' class="wst-pay-bnt"></div> + </div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +<script> +$(function(){ + $("#wst-check-orders").click(function(){ + $("#wst-orders-box").slideToggle(600); + }); + $("div[class^=wst-payCode]").click(function(){ + var payCode = $(this).attr("data"); + $("div[class^=wst-payCode]").each(function(){ + $(this).removeClass().addClass("wst-payCode-"+$(this).attr("data")); + }); + $(this).removeClass().addClass("wst-payCode-"+payCode+"-curr"); + $("#payCode").val(payCode); + }); + if($("div[class^=wst-payCode]").length>0){ + $("div[class^=wst-payCode]")[0].click(); + } +}); + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_pay_step2.html b/hyhproject/home2/view/default/order_pay_step2.html new file mode 100755 index 0000000..fa5f549 --- /dev/null +++ b/hyhproject/home2/view/default/order_pay_step2.html @@ -0,0 +1,52 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + + <div class="pay-sbox-head"> + <a href='{$Request.root.true}'>首页</a>&nbsp;&gt;&nbsp;支付 + </div> + <div> + <div class="pay-tip2"></div> + </div> + <div class='pay-sbox' > + <div class="qrcode-box"> + <div class="pbox"> + 请您扫描以下二维码,支付订单总额:<span class="wst-fred">¥{$needPay}</span> + </div> + <div style="" class="wst-qrcode"></div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> + {if condition="$out_trade_no != '' and $code_url!=''"} + var qr = qrcode(10, 'M'); + qr.addData("{$code_url}"); + qr.make(); + $(".wst-qrcode").html(qr.createImgTag()); + + {/if} + setInterval(function(){ + var params = {}; + params.trade_no = "{$out_trade_no}"; + $.ajax({ + url:"{:url('home/weixinpays/getPayStatus')}", + data:params, + type:"POST", + dataType:"json", + success:function(data){ + if(data.status==1){ + location.href = "{:url('home/weixinpays/paySuccess')}"; + } + } + }); + },1500); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_pay_step3.html b/hyhproject/home2/view/default/order_pay_step3.html new file mode 100755 index 0000000..14023e8 --- /dev/null +++ b/hyhproject/home2/view/default/order_pay_step3.html @@ -0,0 +1,31 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div class="pay-sbox-head"> + <a href='{$Request.root.true}'>首页</a>&nbsp;&gt;&nbsp;支付 + </div> + <div> + <div class="pay-tip3"></div> + </div> + + <div class='pay-sbox'> + <div class='succ-box'> + <div class="imgs"><img src="__STYLE__/img/icon_success.png"/></div> + <div class='wst-clear'></div> + <div class="info" style="line-height:35px;"> + <span>支付完成!</span> + </div> + <div class="go"> + <a href='__ROOT__/index.php' class="wst-order-success wst-cart-reda" style="margin: 0 auto;">继续购物</a> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_pay_wallets.html b/hyhproject/home2/view/default/order_pay_wallets.html new file mode 100755 index 0000000..9f64de2 --- /dev/null +++ b/hyhproject/home2/view/default/order_pay_wallets.html @@ -0,0 +1,129 @@ +{extend name="default/base" /} + +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} + +{block name="css"} + +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> + +{/block} + +{block name="main"} + +<div class="wst-container"> + + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + + <div class="pay-sbox-head"> + + <a href='{$Request.root.true}'>首页</a>&nbsp;&gt;&nbsp;支付 + + </div> + + <div> + + <div class="pay-tip2"></div> + + </div> + + <div class='pay-sbox'> + + <div class="balance-box"> + + <div class='tips-box'>待支付订单总额:<span class="wst-fred">¥{$needPay}</span></div> + + <div class='wst-wallet-box'> + + <div class='wst-wallte-item'> + + 钱包余额:<span class="wst-fred">¥{$userMoney}</span> + + </div> + + <div style='float:right;'>支付:<span class="wst-fred">¥{$needPay}</span></div> + + </div> + + {if ($userMoney>=$needPay)} + + <div class="pbox"> + + <input type='hidden' id='key' value='{$paykey}' class='j-ipt' autocomplete="off" /> + + {if ($hasPayPwd==1)} + + 支付密码:<input type='password' class='u-query j-ipt' id='payPwd' autocomplete='off'> + + <a class='pbox-tip' target='_blank' href='{:url("home/users/editPayPass")}'>忘记密码?</a> + + {else} + + 您尚未设置支付密码,请先设置支付密码 + + <div id="paypwd-box" class="j-paypwd-box" style="display:none;padding:20px;"> + + <table class="wst-table"> + + <tr class="wst-login-tr"> + + <td align='right'>支付密码:</td> + + <td><input type="password" class='j-ipt' id="payPwd" name="payPwd" style="width:250px;" maxlength="60" aria-required="true"></td> + + </tr> + + <tr class="wst-login-tr"> + + <td align='right'>确认支付密码:</td> + + <td><input type="password" class="ipt n-invalid" id="reNewPass" name="reNewPass" style="width:250px;" maxlength="60" aria-required="true" aria-invalid="true"></td> + + </tr> + + </table> + + </div> + + {/if} + + </div> + + <div class="pbox2"> + + {if($hasPayPwd==1)} + + <button class="pay-btn" type="button" style="width:100px;height: 30px;" onclick='javascript:payByWallet()'>确认支付</button> + + {else} + + <button class="pay-btn" type="button" style="width:100px;height: 30px;" onclick='javascript:setPaypwd()'>去设置支付密码</button> + + {/if} + + </div> + + {else} + + <div class="pbox"> + + <img src='__STYLE__/img/icon_jinggao.png'>&nbsp;很抱歉,您的钱包余额不足,不能进行支付。<a class='pbox-tip' href='javascript:void(0)' onclick="javascript:history.go(-1)">返回上一页</a>。 + + </div> + + {/if} + + </div> + + </div> + +</div> + +{/block} + +{block name="js"} + +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> + +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/order_success.html b/hyhproject/home2/view/default/order_success.html new file mode 100755 index 0000000..853881c --- /dev/null +++ b/hyhproject/home2/view/default/order_success.html @@ -0,0 +1,43 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">我的购物车</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">填写核对订单信息</dd> + </dl> + <dl class="last doing"> + <dt class="s-num">3</dt> + <dd class="s-text">成功提交订单</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='success-box'> + <div class="imgs"><img class="wst-lfloat" src="__STYLE__/img/icon_success.png"/><span>订单提交成功!</span></div> + <div class="info"> + {php}$len = count($object['list'])-1;{/php} + 订单号:{volist name="$object['list']" id='vo'} + <a href='{:url("home/orders/detail",array("id"=>$vo["orderId"]))}' target='_blank' onclick='WST.position(5,0)'>{$vo['orderNo']}</a> + {if $i <= $len }、{/if} + {/volist} + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + 应付金额:<span>¥{$object['totalMoney']}</span> + </div> + <div class="go"> + <a href='__ROOT__/index.php' class="wst-order-success wst-cart-reda">继续购物</a> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/regist.html b/hyhproject/home2/view/default/regist.html new file mode 100755 index 0000000..25c2537 --- /dev/null +++ b/hyhproject/home2/view/default/regist.html @@ -0,0 +1,102 @@ +{extend name="default/base_js" /} +{block name="title"}用户注册 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +{/block} +{block name="header"}{/block} +{block name="main"} + <div class="wst-login-banner-regist"> + <div class="wst-icon-banner"> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <div class="img-banner" > + <img src="__ROOT__/{:WSTConf('CONF.mallLogo')}"> + </div> + </a> + <div class="wst-login-action"> + <ul class="wst-icon" style="width: 300px;margin-top: 20px;"> + <li class="wst-img-icon"></li><li class="wst-remind" style="color:#333;">您好!欢迎来到{:WSTMSubstr(WSTConf('CONF.mallName'),0,13)}!<a href="{:Url('home/users/login')}" onclick="WST.currentUrl();" style="color:red;">&nbsp;&nbsp;请登录</a></li> + </ul> + </div> + </div> + </div> +<input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> +<div class="wst-regist-b"> + <div class="wst-container"> + <div class="wst-regist"> + <div class="wst-regist-c"> + <input type="hidden" id="nameType" class="wst_ipt nameType" value='2' autocomplete="off"/> + <form id="reg_form" method="post" autocomplete="off"> + <div class="wst-regist-head">Hi~欢迎来注册</div> + <table class="wst-table"> + <tr class="wst-login-tr"> + <td class="wst-regist-td"><font color='red'>*</font>用户名</td> + <td><input id="loginName" name="loginName" class="wst_ipt wst-regist-input" tabindex="1" maxlength="30" autocomplete="off" onpaste="return false;" style="ime-mode:disabled;" placeholder="手机号" type="text" onkeyup="javascript:WST.isChinese(this,1)" /></td> + </tr> + <tr class="wst-login-tr"> + <td class="wst-regist-td"><font color='red'>*</font>密码</td> + <td><input id="loginPwd" name="loginPwd" class="wst_ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符"/></td> + </tr> + <tr class="wst-login-tr"> + <td class="wst-regist-td"><font color='red'>*</font>确认密码</td> + <td><input id="reUserPwd" name="reUserPwd" class="wst_ipt wst-regist-input" tabindex="3" autocomplete="off" type="password" placeholder="6-16位字符"/></td> + </tr> + <tr id="mobileCodeDiv" class="wst-login-tr"> + <td class="wst-regist-td"><font color='red'>*</font>短信验证码</td> + <td> + <input maxlength="6" autocomplete="off" tabindex="6" class="wst_ipt wst-regist-codemo" name="mobileCode" style="ime-mode:disabled" id="mobileCode" type="text" data-target="#mobileCodeTips" placeholder="短信验证码"/> + <button id="timeTips" onclick="getVerifyCode();" class="wst-regist-obtain">获取短信验证码</button> + <span id="mobileCodeTips"></span> + </td> + </tr> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:180px;"> + <label> + <input id="protocol" name="protocol" type="checkbox" class="wst_ipt" value="1" data-rule="checked"/>我已阅读并同意 + <a href="javascript:;" style="color:#69b7b5;" id="protocolInfo" onclick="showProtocol();">《用户注册协议》</a> + </label> + </td> + </tr> + <tr style="height:80px;"> + <td colspan="2" style="padding-left:260px;"> + <input id="reg_butt" class="wst-regist-but" type="submit" value="注册" style="width: 180px;height:30px;"/> + </td> + </tr> + </table> + </form> + </div> + </div> + </div> +</div> +<div class="wst-footer"> + <div class="wst-container"> + <div class="wst-footer-hp-ck3"> + <div class="links"> + {php}$navs = WSTNavigations(1);{/php} + {volist name="$navs" id='vo'} + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + {if $i< count($navs)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + <div class="copyright"> + {php} + if(WSTConf('CONF.mallFooter')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.mallFooter')); + } + {/php} + {php} + if(WSTConf('CONF.visitStatistics')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.visitStatistics'))."<br/>"; + } + {/php} + + </div> + </div> + </div> + </div> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/js/login.js?v={$v}'></script> + <Script>$(function(){initRegist();})</Script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/right_cart.html b/hyhproject/home2/view/default/right_cart.html new file mode 100755 index 0000000..b2208f3 --- /dev/null +++ b/hyhproject/home2/view/default/right_cart.html @@ -0,0 +1,153 @@ +<link href="__STYLE__/css/right_cart.css?v={$v}" rel="stylesheet"> +<div class="j-global-toolbar"> + <div class="toolbar-wrap j-wrap" > + <div class="toolbar"> + <div class="toolbar-panels j-panel"> + <div style="visibility: hidden;" class="j-content toolbar-panel tbar-panel-cart toolbar-animate-out"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="" class="title"><i></i><em class="title">购物车</em></a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main" > + <div class="tbar-panel-content j-panel-content"> + {if condition="session('WST_USER.userId') == 0"} + <div id="j-cart-tips" class="tbar-tipbox hide"> + <div class="tip-inner"> + <span class="tip-text">还没有登录,登录后商品将被保存</span> + <a href="#none" onclick='WST.loginWindow()' class="tip-btn j-login">登录</a> + </div> + </div> + {/if} + <div id="j-cart-render"> + <div id='cart-panel' class="tbar-cart-list"></div> + <script id="list-rightcart" type="text/html"> + {{# + var shop,goods,specs; + for(var key in d){ + shop = d[key]; + for(var i=0;i<shop.list.length;i++){ + goods = shop.list[i]; + goods.goodsImg = WST.conf.IMGURL+"/"+goods.goodsImg+"?x-oss-process=image/resize,w_300,h_300"; + specs = ''; + if(goods.specNames && goods.specNames.length>0){ + for(var j=0;j<goods.specNames.length;j++){ + specs += goods.specNames[j].itemName+ " "; + } + } + }} + <div class="tbar-cart-item" id="shop-cart-{{shop.shopId}}"> + <div class="jtc-item-promo"> + <div class="promo-text">{{shop.shopName}}</div> + </div> + <div class="jtc-item-goods j-goods-item-{{goods.cartId}}" dataval="{{goods.cartId}}"> + <div class='wst-lfloat'> + <input type='checkbox' id='rcart_{{goods.cartId}}' class='rchk' onclick='javascript:checkRightChks({{goods.cartId}},this);' {{# if(goods.isCheck==1){}}checked{{# } }}/></div> + <span class="p-img"><a target="_blank" href="{{WST.U('home/goods/detail','id='+goods.goodsId)}}" target="_blank"><img src="{{goods.goodsImg}}" title="{{goods.goodsName}}" height="50" width="50"></a></span> + <div class="p-name"> + <a target="_blank" title="{{(goods.goodsName+((specs!='')?"【"+specs+"】":""))}}" href="{{WST.U('home/goods/detail','id='+goods.goodsId)}}">{{WST.cutStr(goods.goodsName,22)}}<br/>{{specs}}</a> + </div> + <div class="p-price"> + <strong>¥<span id='gprice_{{goods.cartId}}'>{{goods.shopPrice}}</span></strong> + <div class="wst-rfloat"> + <a href="#none" class="buy-btn" id="buy-reduce_{{goods.cartId}}" onclick="javascript:WST.changeIptNum(-1,'#buyNum','#buy-reduce,#buy-add','{{goods.cartId}}','statRightCartMoney')">-</a> + <input type="text" id="buyNum_{{goods.cartId}}" class="right-cart-buy-num" value="{{goods.cartNum}}" data-max="{{goods.goodsStock}}" data-min="1" onkeyup="WST.changeIptNum(0,'#buyNum','#buy-reduce,#buy-add',{{goods.cartId}},'statRightCartMoney')" autocomplete="off" onkeypress="return WST.isNumberKey(event);" maxlength="6"/> + <a href="#none" class="buy-btn" id="buy-add_{{goods.cartId}}" onclick="javascript:WST.changeIptNum(1,'#buyNum','#buy-reduce,#buy-add','{{goods.cartId}}','statRightCartMoney')">+</a> + </div> + </div> + <span onclick="javascript:delRightCart(this,{{goods.cartId}});" dataid="{{shop.shopId}}|{{goods.cartId}}" class="goods-remove" title="删除"></span> + </div> + </div> + {{# } } }} + </script> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"> + <div class="tbar-checkout"> + <div class="jtc-number">已选<strong id="j-goods-count">0</strong>件商品 </div> + <div class="jtc-sum"> 共计:¥<strong id="j-goods-total-money">0</strong> </div> + <a class="jtc-btn j-btn" href="#none" onclick='javascript:jumpSettlement()'>去结算</a> + </div> + </div> + </div> + + <div style="visibility: hidden;" data-name="follow" class="j-content toolbar-panel tbar-panel-follow"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="#" target="_blank" class="title"> <i></i> <em class="title">我的关注</em> </a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main"> + <div class="tbar-panel-content j-panel-content"> + <div class="tbar-tipbox2"> + <div class="tip-inner"> <i class="i-loading"></i> </div> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"></div> + </div> + <div style="visibility: hidden;" class="j-content toolbar-panel tbar-panel-history toolbar-animate-in"> + <h3 class="tbar-panel-header j-panel-header"> + <a href="#none" class="title"> <i></i> <em class="title">我的足迹</em> </a> + <span class="close-panel j-close" title='关闭'></span> + </h3> + <div class="tbar-panel-main"> + <div class="tbar-panel-content j-panel-content"> + <div class="jt-history-wrap"> + <ul id='history-goods-panel'></ul> + <script id="list-history-goods" type="text/html"> + {{# + for(var i = 0; i < d.length; i++){ + d[i].goodsImg = WST.conf.IMGURL+"/"+d[i].goodsImg+"?x-oss-process=image/resize,w_300,h_300"; + }} + <li class="jth-item"> + <a target='_blank' href="{{WST.U('home/goods/detail','id='+d[i].goodsId)}}" class="img-wrap"><img src="{{d[i].goodsImg}}" height="100" width="100"> </a> + <a class="add-cart-button" href="javascript:WST.addCart({{d[i].goodsId}});">加入购物车</a> + <a href="#none" class="price">¥{{d[i].shopPrice}}</a> + </li> + {{# } }} + </script> + </div> + </div> + </div> + <div class="tbar-panel-footer j-panel-footer"></div> + </div> + </div> + + <div class="toolbar-header"></div> + + <div class="toolbar-tabs j-tab"> + + <div class="toolbar-tab tbar-tab-cart"> + <i class="tab-ico"></i> + <em class="tab-text">购物车</em> + <span class="tab-sub j-cart-count hide"></span> + </div> + <div class="toolbar-tab tbar-tab-follow" style='display:none'> + <i class="tab-ico"></i> + <em class="tab-text">我的关注</em> + <span class="tab-sub j-count hide">0</span> + </div> + <div class=" toolbar-tab tbar-tab-history "> + <i class="tab-ico"></i> + <em class="tab-text">我的足迹</em> + <span class="tab-sub j-count hide"></span> + </div> + <div class="toolbar-tab tbar-tab-message"> + <a target='_blank' href='{:Url("home/messages/index")}' onclick='WST.position(49,0)'> + <i class="tab-ico"></i> + <em class="tab-text">我的消息</em> + <span class="tab-sub j-message-count hide"></span> + </a> + </div> + </div> + + <div class="toolbar-footer"> + <div class="toolbar-tab tbar-tab-top"> <a href="#"> <i class="tab-ico "></i> <em class="footer-tab-text">顶部</em> </a> </div> + <div class=" toolbar-tab tbar-tab-feedback" style='display:none'> <a href="#" target="_blank"> <i class="tab-ico"></i> <em class="footer-tab-text ">反馈</em> </a> </div> + </div> + <div class="toolbar-mini"></div> + </div> + <div id="j-toolbar-load-hook"></div> + </div> +</div> +<script type='text/javascript' src='__STYLE__/js/right_cart.js?v={$v}'></script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/self_shop.html b/hyhproject/home2/view/default/self_shop.html new file mode 100755 index 0000000..e9048a4 --- /dev/null +++ b/hyhproject/home2/view/default/self_shop.html @@ -0,0 +1,187 @@ +{extend name="default/base" /} +{block name="title"}{:WSTConf('CONF.mallName')}-{:WSTConf('CONF.mallSlogan')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/self_shop.css" rel="stylesheet"> +{/block} +{block name="main"} +<input type="hidden" id="shopId" value="{$data['shop']['shopId']}"> +<input type="hidden" id="goodsName" value="{$goodsName}"> + +<div class="s-banner"> + {/* 本店分类 */} + <div class="s-cat"> + {volist name="$data['shopcats']" id="cat1" length="6"} + <div class="shop-cat1" cid="{$key}" id="ct1-{$key}"> + <div class="shop-cat1-title"> + <em class="em{$key+1}"></em> + <h3> + <a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}">{:WSTMSubstr($cat1['catName'],0,4)}</a> + </h3> + </div> + <p class="shop-ct1-ct2"> + {volist name="$cat1['children']" id="v1" key="k1" } + <a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$v1['catId']])}">{$v1['catName']}</a> + {/volist} + </p> + </div> + + <ul class="shop-cat2 cid{$key}" cid="{$key}"> + {volist name="$cat1['children']" id="cat2" length="20"} + <li><a href="{:url('home/shops/cat',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$cat2['catId']])}">{$cat2['catName']}</a></li> + {/volist} + </ul> + {/volist} + </div> + + {/* 横栏广告 */} + <div class="s-wst-slide" id="s-wst-slide" style="width:100%;float:right;height:500px;overflow:hidden;"> + {if($data['shop']['shopAds'])} + <ul class="s-wst-slide-items"> + {volist name="$data['shop']['shopAds']" id="vo"} + <a href="{$vo.adUrl}" {if ($vo['isOpen'])}target='_blank'{/if}><li style="background: url(__IMGURL__/{$vo.adImg}) no-repeat scroll center center;background-size:cover" ></li></a> + {/volist} + </ul> + <div class="s-wst-slide-numbox"> + <div class="s-wst-slide-controls"> + {volist name="$data['shop']['shopAds']" id="vo" key="k"} + {if condition="$k eq 1"} + <span class="curr"> </span> + {else/} + <span class=""> </span> + {/if} + {/volist} + </div> + </div> + {/if} + + </div> +</div> + +<div class="shop_rec_out"> + <div class="s-buy-new-best-hot"> + <ul class="s-rec"> + <li class="s-rec-item j-s-rec-selected" id="fl_f_0" onmouseover="gpanelOver2(this);"><a href="javascript:void(0)">店长推荐</a></li> + <li class="s-rec-item"> + <a href="javascript:void(0)">&nbsp;/&nbsp;</a> + </li> + <li class="s-rec-item" id="fl_f_1" onmouseover="gpanelOver2(this);"><a href="javascript:void(0)">热卖商品</a></li> + <div class="wst-clear"></div> + </ul> + {/* 店长推荐 */} + <div class="s-rec-glistbox" id="fl_f_0_pl"> + <ul class="s-rec-goods-list"> + {volist name="$data['rec']" id="vo" length="4" } + <li> + <a href='{:Url("home/goods/detail","id=".$vo["goodsId"])}' target='_blank'> + <img class='goodsImg' data-original="__IMGURL__/{:WSTImg($vo['goodsImg'])}" title="{$vo['goodsName']}"/> + </a> + <div class="rec_ginfo"> + <p class="s-rec-goods-desc"><a href='{:Url("home/goods/detail","id=".$vo["goodsId"])}' target='_blank'>{$vo['goodsName']}</a></p> + <div class="s-rec-goods-bottom"> + <p class="s-rec-goods-price"><span>¥{$vo['shopPrice']}</span></p> + <a href="javascript:WST.addCart({$vo['goodsId']});">加入购物车</a> + </div> + </div> + </li> + {/volist} + <div class="wst-clear"></div> + </ul> + </div> + + <div class="s-rec-glistbox" id="fl_f_1_pl" style="display:none;"> + <ul class="s-rec-goods-list"> + {volist name="$data['hot']" id="hot" length="4"} + <li> + <a href='{:Url("home/goods/detail","id=".$hot["goodsId"])}' target='_blank'> + <img class='goodsImg' data-original="__IMGURL__/{$hot['goodsImg']}" title="{$hot['goodsName']}"/> + </a> + <div class="rec_ginfo"> + <p class="s-rec-goods-desc"><a href='{:Url("home/goods/detail","id=".$hot["goodsId"])}' target='_blank'>{$hot['goodsName']}</a></p> + <div class="s-rec-goods-bottom"> + <p class="s-rec-goods-price"><span>¥{$hot['shopPrice']}</span></p> + <a href="javascript:WST.addCart({$hot['goodsId']});">加入购物车</a> + </div> + </div> + </li> + {/volist} + </ul> + <div class="wst-clear"></div> + </div> + </div> + +</div> + + +{volist name="$data['shopcats']" id="cat1" key="l" length="6"} +<div class="self_container_out"> + <div class="sf_headerbox"> + {/* 店铺一级分类 */} + <div class="sfhl f{$l}_tit_bg"> + <a class="sfh_tit" href="#">{$cat1['catName']}</a> + </div> + {/* 店铺二级分类 */} + <div class="sfhr"> + {/* 楼层二级分类 */} + {php} + $a = count($cat1['children']); + if($a>5)$a=5; + {/php} + {volist name="$cat1['children']" id="cat2" key="l2" length="5"} + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId'],'ct2'=>$cat2['catId']])}" class="c18_333">{$cat2['catName']}</a> + {if($l2<$a)}<span class="c18_333 separatory">/</span>{/if} + {/volist} + <span class="c18_333 separatory"> </span> + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}" class="c18_333">查看更多&nbsp;&nbsp;>></a> + </div> + <div class="wst-clear"></div> + </div> + {/* 自营店铺楼层广告 */} + {wst:ads code="self-shop-f$l" id="vo" num="1" cache="86400"} + <div class="sf_adsbox"> + <a {if ($vo['isOpen'])}target='_blank'{/if} {if ($vo['adURL']!='')}onclick="WST.recordClick({$vo['adId']})"{/if} href="{$vo.adURL}" onfocus="this.blur()"> + <img data-original="__IMGURL__/{$vo.adFile}" class="goodsImg" /> + </a> + </div> + {/wst:ads} + {/* 楼层商品列表 */} + <div class="sf_glistbox f{$l}_g_bg"> + <ul class="sf_glist"> + {wst:shopfloorgoods shop="data['shop']['shopId']" cat="cat1['catId']" cache="86400" num='10' id='sgf'} + <li> + <a target="_blank" href="{:Url('home/goods/detail','id='.$sgf['goodsId'])}" title="{$sgf['goodsName']}"> + <div class="sf_img"> + <img class='goodsImg' data-original="__IMGURL__/{$sgf['goodsImg']}" alt="{$sgf['goodsName']}" title="{$sgf['goodsName']}"/> + </div> + <p class="sf_gname"> + {$sgf['goodsName']} + </p> + <p class="sf_price"> + <span class="c11">¥</span>{:sprintf('%.1f',$sgf['shopPrice'])} + </p> + </a> + </li> + {/wst:shopfloorgoods} + <div class="wst-clear"></div> + </ul> + </div> +</div> +{/volist} +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/self_shop.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script type='text/javascript'> +$(function(){ + WST.dropDownLayer(".wst-shop-code",".wst-shop-codes"); + var qr = qrcode(10, 'M'); + var shopId = $("#shopId").val(); + var url = "{:url('mobile/shops/selfShop',array('shopId'=>$data['shop']['shopId']),true,true)}"; + qr.addData(url); + qr.make(); + $('#qrcode').html(qr.createImgTag()); +}); +</script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/self_shop_header.html b/hyhproject/home2/view/default/self_shop_header.html new file mode 100755 index 0000000..c328e00 --- /dev/null +++ b/hyhproject/home2/view/default/self_shop_header.html @@ -0,0 +1,82 @@ +<div class='wst-search-container'> + + <div class="wst-shop-h"> + <div class="wst-shop-img"><a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"><img class="shopsImg" data-original="__IMGURL__/{$data['shop']['shopImg']}" title="{$data['shop']['shopName']}"></a></div> + <div class="wst-shop-info"> + <p>{$data['shop']['shopName']}</p> + <div class="wst-shop-info2"> + {volist name="$data['shop']['accreds']" id="ac"} + <img src="__IMGURL__/{$ac['accredImg']}"><span>{$ac['accredName']}</span> + {/volist} + {if($data['shop']['shopQQ'])} + <a href="tencent://message/?uin={$data['shop']['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style="width:65px;height:24px;" src="http://wpa.qq.com/pa?p=1:{$data['shop']['shopQQ']}:7"> + </a> + {/if} + {if($data['shop']['shopWangWang'])} + <a href="http://www.taobao.com/webww/ww.php?ver=3&touid={$data['shop']['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8" target="_blank"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$data['shop']['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" class='wangwang'/> + </a> + {/if} + </div> + <div class="wst-shop-info3"> + <span class="wst-shop-eva">商品评价:<span class="wst-shop-red">{$data['shop']['scores']['goodsScore']}</span></span> + <span class="wst-shop-eva">时效评价:<span class="wst-shop-red">{$data['shop']['scores']['timeScore']}</span></span> + <span class="wst-shop-eva">服务评价:<span class="wst-shop-red">{$data['shop']['scores']['serviceScore']}</span></span> + {if($data['shop']['favShop']>0)} + <a href='javascript:void(0);' onclick='WST.cancelFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav">已关注</a> + {else} + <a href='javascript:void(0);' onclick='WST.addFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav2">关注店铺</a> + {/if} + <span class="wst-shop-eva">用手机逛本店 &nbsp;&nbsp;|</span> + <a class="wst-shop-code"><span class="wst-shop-codes hide"><div id='qrcode' style='width:142px;height:142px;'></div></span></a> + + </div> + </div> + <div class="wst-shop-sea"> + <input type="text" id="goodsName" value="{$goodsName}" placeholder="输入商品名称"> + <a class="search" href="javascript:void(0);" onclick="javascript:WST.goodsSearch($('#goodsName').val());">搜全站</a> + <a class="search" href="javascript:void(0);" onclick="javascript:searchShopsGoods(0);">搜本店</a> + <div class="wst-shop-word"> + {volist name="data['shop']['shopHotWords']" id="shw"} + <a href='{:Url("home/shops/home",array('shopId'=>$data['shop']['shopId'],'goodsName'=>$shw))}'>{$shw}</a>{if $i< count($data['shop']['shopHotWords'])}&nbsp;|&nbsp;{/if} + {/volist} + </div> + <div> + <div style="clear: both;"></div> + <div class="jiathis_style_24x24 wst-shop-share"> + <a class="jiathis_button_qzone"></a> + <a class="jiathis_button_tsina"></a> + <a class="jiathis_button_tqq"></a> + <a class="jiathis_button_weixin"></a> + <a class="jiathis_button_cqq"></a> + <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> + </div> + </div> + <div style="clear: both;"></div> + </div> + <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js" charset="utf-8"></script> + {:hook('distributHook',['module'=>1,'positionType'=>1,'shop'=>$data['shop'],'getParams'=>input()])} + </div> + <div class="wst-clear"></div> + </div> +</div> +{if($data['shop']['shopBanner'])}<div class="wst-shop-tu" style="background: url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat scroll center top;background-size:cover;"></div>{/if} +<div class="wst-clear"></div> +<div class="s-wst-nav-menus"> + <div id="s-wst-nav-items"> + <ul> + <li class="s-nav-li s-cat-head"style="background-color:#DF2003"><a href="{:Url('home/shops/home',['shopId'=>$data['shop']['shopId']])}" target="_blank" ><em></em>本店商品分类</a></li> + {volist name="$data['shopcats']" id="cat1" key="l" length="6"} + <li class="s-nav-li"> + <a href="{:url('home/shops/home',['shopId'=>$data['shop']['shopId'],'ct1'=>$cat1['catId']])}" target="_blank">{$cat1['catName']}</a> + </li> + {/volist} + <li class="s-nav-li"> <a class="homepage" href="{:url('/')}" target="_blank">返回商城首页</a></li> + </ul> + </div> + + <span class="wst-clear"></span> + </div> +</div> +<div class="wst-clear"></div> diff --git a/hyhproject/home2/view/default/settlement.html b/hyhproject/home2/view/default/settlement.html new file mode 100755 index 0000000..a063d69 --- /dev/null +++ b/hyhproject/home2/view/default/settlement.html @@ -0,0 +1,534 @@ +{extend name="default/base" /} + +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} + +{block name="css"} + +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> + +{/block} + +{block name="main"} + +<div class="wst-container"> + + <div id="stepflex" class="stepflex"> + + <dl class="first doing"> + + <dt class="s-num">1</dt> + + <dd class="s-text">我的购物车</dd> + + <dd></dd> + + </dl> + + <dl class="normal doing"> + + <dt class="s-num">2</dt> + + <dd class="s-text">填写核对订单信息</dd> + + </dl> + + <dl class="last"> + + <dt class="s-num1">3</dt> + + <dd class="s-text1">成功提交订单</dd> + + </dl> + + </div> + + <div class='wst-clear'></div> + + <div class='main-head'>填写并核对订单</div> + + <input type='hidden' class='j-ipt' id='s_addressId' value='{if isset($userAddress["addressId"]) }{$userAddress["addressId"]}{/if}'/> + + <input type='hidden' class='j-ipt' id='s_areaId' value='{if isset($userAddress["addressId"]) }{$userAddress["areaId2"]}{/if}'/> + + <!-- 用户地址 --> + + <div class='address-box'> + + <div class='box-head'>收货人信息 <a class="add-addr" href="javascript:;" onclick="javascript:emptyAddress(this,1)">新增收货地址</a></div> + + <!-- 选中地址 --> + + <div class='j-show-box {if empty($userAddress)}hide{/if}' > + + <div id="s_userName" class="wst-frame1 j-selected">{if isset($userAddress["addressId"]) }{$userAddress['userName']}{/if}<i></i></div> + + <div class="address" onmouseover="addrBoxOver(this)" onmouseout="addrBoxOut(this)"> + + <span id='s_address'> + + {if isset($userAddress["addressId"]) } + + {$userAddress['userName']}&nbsp;&nbsp;&nbsp;{$userAddress['areaName']}&nbsp;&nbsp;{$userAddress['userAddress']}&nbsp;&nbsp;{$userAddress['userPhone']} + + {/if} + + </span> + + &nbsp;&nbsp; + + <span id="isdefault" {if(isset($userAddress['isDefault'])&&($userAddress['isDefault']==1))} class="j-default">默认地址{else /} >{/if}</span> + + <div class="operate-box"> + + <a href="javascript:void(0)" onclick="javascript:toEditAddress({if isset($userAddress["addressId"]) }{$userAddress["addressId"]}{/if},this,1,1,1)">编辑</a>&nbsp;&nbsp; + + </div> + + </div> + + + + <div class='wst-clear'></div> + + + + <div class="address"> + + <a class="wst-lfloat" href='javascript:void(0)' onclick='javascript:showEditAddressBox()' style=''>更多地址</a> + + </div> + + + + </div> + + <!-- 地址列表 --> + + <ul class='j-list-box hide' id='addressList'></ul> + + + + <!-- 新增编辑地址 --> + + <div class='j-edit-box {if !empty($userAddress)}hide{/if}'> + + <form id='addressForm' autocomplete='off'> + + <input type='hidden' class='j-eipt' id='addressId' value=''/> + + <div class='rows'> + + <div class='label'>收货人<font color='red'>*</font>:</div> + + <div class='field'><input type='text' class='j-eipt' id='userName' maxLength='25'/></div> + + <div class='wst-clear'></div> + + </div> + + <div class='rows'> + + <div class='label'>收货地址<font color='red'>*</font>:</div> + + <div class='field'> + + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + + <option value="">-请选择-</option> + + {volist name="areaList" id="vo"} + + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + + {/volist} + + </select> + + <input type='text' class='j-eipt' id='userAddress' style='width:300px' maxLength='200'/> + + </div> + + <div class='wst-clear'></div> + + </div> + + <div class='rows'> + + <div class='label'>联系电话<font color='red'>*</font>:</div> + + <div class='field'><input type='text' id='userPhone' class='j-eipt' name="addrUserPhone" maxLength='50'/> </div> + + <div class='wst-clear'></div> + + </div> + + <div class='rows'> + + <div class='label'>是否默认地址<font color='red'>*</font>:</div> + + <div class='radio-box'> + + <label style='margin-right:36px;'> + + <input type='radio' name='isDefault' value='1' checked class='j-eipt wst-radio' id="isDefault1"/><label class="mt-1" for="isDefault1"></label>是 + + </label> + + <label> + + <input type='radio' name='isDefault' value='0' class='j-eipt wst-radio' id="isDefault2"/><label class="mt-1" for="isDefault2"></label>否 + + </label> + + </div> + + <div class='wst-clear'></div> + + </div> + + <div class='rows'> + + <a href='javascript:void(0)' class='wst-cart-reda' id='saveAddressBtn' onclick='javascript:editAddress()' style='width:105px;line-height:33px;padding:6px 15px'>保存收货人地址</a> + + </div> + + </form> + + </div> + + </div> + + <!-- 支付方式 --> + + <div class='pay-box'> + + <div class='box-head'>支付方式</div> + + <div class="wst-list-box"> + + {if !empty($payments['0'])} + + <div class="wst-frame2 j-selected" onclick="javascript:changeSelected(0,'payType',this)">货到付款<i></i></div> + + {/if} + + {if !empty($payments['1'])} + + <div class="wst-frame2 <?php echo empty($payments['0'])?'j-selected':''; ?>" onclick="javascript:changeSelected(1,'payType',this)">在线支付<i></i></div> + + {/if} + + <input type='hidden' value="<?php echo empty($payments['0'])?1:0; ?>" id='payType' class='j-ipt' /> + + <div class='wst-clear'></div> + + </div> + + </div> + + <!-- 商品清单 --> + + <div class='cart-box2'> + + <div class='box-head2'>商品清单</div> + + <div class='cart-head2'> + + <div class='goods2'>商品</div> + + <div class='price2'>单价</div> + + <div class='num2'>数量</div> + + <div class='t-price2'>总价</div> + + </div> + + {php}$shopFreight = 0;{/php} + + {volist name='$carts["carts"]' id='vo'} + + {php} + + if($vo['isFreeShipping']){ + + $freight = 0; + + }else{ + + if(!empty($userAddress)){ + + $freight = WSTOrderFreight($vo['shopId'],$userAddress['areaId2']); + + }else{ + + $freight = WSTOrderFreight($vo['shopId'],-1); + + } + + } + + $shopFreight = $shopFreight + $freight; + + {/php} + + <div class='cart-item j-shop' dataval='{$vo['shopId']}'> + + <div class='shop2'> + + {$vo['shopName']} + + {if $vo['shopQQ'] !=''} + + <a href="tencent://message/?uin={$vo['shopQQ']}&Site=QQ交谈&Menu=yes"> + + <img border="0" src="http://wpa.qq.com/pa?p=1:{$vo['shopQQ']}:7" alt="QQ交谈" width="71" height="24"/> + + </a> + + {/if} + + {if $vo['shopWangWang'] !=''} + + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$vo['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$vo['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + + </a> + + {/if} + + </div> + + {:hook('homeDocumentSettlementShopPromotion',['shop'=>$vo])} + + <div class='goods-list'> + + {volist name='vo["list"]' id='vo2'} + + {:hook('homeDocumentSettlementGoodsPromotion',['goods'=>$vo2])} + + <div class='item selected j-g{$vo2["cartId"]}'> + + <div class='goods2'> + + <div class='img2'> + + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + + </a> + + </div> + + <div class='name2'>{$vo2["goodsName"]}</div> + + <div class='spec2'> + + {volist name='vo2["specNames"]' id='specs'} + + <div>{$specs['catName']}:{$specs['itemName']}</div> + + {/volist} + + </div> + + </div> + + <div class='price2'>¥{$vo2['shopPrice']}</div> + + <div class='num2'>{$vo2['cartNum']}</div> + + <div class='t-price2'>¥{$vo2['shopPrice']*$vo2['cartNum']}</div> + + <div class='wst-clear'></div> + + </div> + + {/volist} + + <div class='shop-remark selected2'> + + <div class='shop-remark-box'> + + 订单备注:<input type='text' id="remark_{$vo['shopId']}" class='j-ipt' style='width:420px' maxLength='100' placeholder='给卖家留言'/> + + </div> + + <div class='shop-summary'> + + {if !empty($vo['coupons'])} + + {:hook('homeDocumentSettlementShopSummary',['coupons'=>$vo['coupons'],'shopId'=>$vo['shopId']])} + + {else} + + <input type='hidden' class='j-ipt' id='couponId_{$vo['shopId']}'/> + + {/if} + + <div class='row'> + + <dt>运费:</dt><dd>¥<span id="shopF_{$vo['shopId']}" style='font-weight: bold;color: #E55356;'>{$freight}</span></dd> + + </div> + + <div class='row'> + + <dt>店铺合计(含运费):</dt><dd>¥<span id="shopC_{$vo['shopId']}" v="{$vo['goodsMoney']}" style='font-weight: bold;color: #E55356;'>{:WSTPositiveNum($freight+$vo['goodsMoney']-$vo['promotionMoney'])}</span></dd> + + </div> + + </div> + + </div> + + </div> + + </div> + + {/volist} + + <!-- 送货方式 --> + + <div class='pay-boxs'> + + <div class='box-head'>送货方式</div> + + <div class="wst-list-box"> + + <div class="wst-frame2 j-selected" onclick="javascript:changeDeliverType(0,'deliverType',this)">快递运输<i></i></div> + + <!-- <div class="wst-frame2" onclick="javascript:changeDeliverType(1,'deliverType',this)">自提<i></i></div> --> + + <input type='hidden' value='0' id='deliverType' class='j-ipt' /> + + <div class='wst-clear'></div> + + </div> + + </div> + + <div class='cart-footer'> + + <div class='cart-summary2'> + + <div class="summarys2"> + + <!-- 发票信息 --> + + <div class="pay-boxs"> + + <div class='box-head'>发票信息</div> + + <div class="j-show-box"> + + + + <div style="float:left;" id="invoice_info">不开发票</div> + + <div style="float:left;color:blue;margin-left:10px;cursor:pointer;" onclick='javascript:changeInvoice(1,"#invoiceClientDiv",this)'>修改</div> + + + + <div class="wst-clear"></div> + + <input type="hidden" id="invoice_obj" value="0" /> + + <input type="hidden" id="invoiceId" value="0" class='j-ipt' /> + + <input type='hidden' value='0' id='isInvoice' class='j-ipt' /> + + <input type='hidden' value='个人' id='invoiceClient' class='j-ipt' /> + + </div> + + <div class='wst-clear'></div> + + </div> + + + + </div> + + <div class="summarys3" style='text-align:right;padding-right:20px'> + + <div>运费总计:¥<span id='deliverMoney'>{$shopFreight}</span></div> + + <!-- <div> + 11.11优惠券: + <select id="recordId" class='j-ipt' onchange="javascript:getCartMoney()"> + <option value="">-请选择-</option> + {volist name="carts['userCoupon']" id="userCoupons"} + <option value="{$userCoupons['recordId']}">{$userCoupons['coupon']}</option> + {/volist} + </select> + </div> --> + + {if WSTConf('CONF.isOpenScorePay')==1} + + <div> + + (可用<span id='maxScoreSpan'>{$userOrderScore}</span>个惠宝抵¥<span id='maxScoreMoneySpan'>{$userOrderMoney}</span>) + + <input type='checkbox' id='isUseScore' autocomplete="off" onclick='javascript:checkScoreBox(this.checked)' dataval="{$userOrderScore}"/>惠宝支付 + + <span id='scoreMoney' style='display:none'> + + ,使用惠宝<input type="text" id="useScore" style="width:50px;margin-left:5px" class='j-ipt' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" onkeypress="return WST.isNumberKey(event)" onblur="javascript:getCartMoney()" value="{$userOrderScore}"/> + + </span> + + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;¥-<span id='scoreMoney2'>0.0</span></div> + + {/if} + + {php} + $carts['goodsTotalMoney'] = $carts['goodsTotalMoney'] + $shopFreight; + {/php} + <div class='summary2'>应付总金额:¥<span id='totalMoney' v='{$carts["goodsTotalMoney"]}'> + + {if empty($userAddress)} + + {:WSTPositiveNum($carts["goodsTotalMoney"]-$carts['promotionMoney'])} + + {else} + + {:WSTPositiveNum($carts["goodsTotalMoney"]-$carts['promotionMoney'])} + + {/if} + + </span></div> + + <div {if WSTConf('CONF.isOrderScore')!=1 }style='display:none'{/if}>可获得惠宝:订单总额的20%<!--<span id='orderScore'>{:WSTMoneyGiftScore($carts["goodsTotalMoney"])}</span>个--></div> + + </div> + + <div class='wst-clear'></div> + + </div> + + </div> + + </div> + + <div class='cart-btn'> + + <a href='{:Url("home/carts/index")}' class='wst-prev wst-cart-asha' style='width:105px;height:33px;line-height:33px;'>上一步</a> + + <a href='javascript:void(0)' onclick='javascript:submitOrder()' class='wst-order wst-cart-reda' style='width:118px;height:33px;line-height:33px;'>提交订单</a> + + <div class='wst-clear'></div> + + </div> + +</div> + +{/block} + +{block name="js"} + +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> + +{/block} diff --git a/hyhproject/home2/view/default/settlement2.html b/hyhproject/home2/view/default/settlement2.html new file mode 100755 index 0000000..e634412 --- /dev/null +++ b/hyhproject/home2/view/default/settlement2.html @@ -0,0 +1,262 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">我的购物车</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">填写核对订单信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">3</dt> + <dd class="s-text1">成功提交订单</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>填写并核对订单</div> + <input type='hidden' class='j-ipt' id='s_addressId' value='{if isset($userAddress["addressId"]) }{$userAddress["addressId"]}{/if}'/> + <input type='hidden' class='j-ipt' id='s_areaId' value='{if isset($userAddress["addressId"]) }{$userAddress["areaId2"]}{/if}'/> + <!-- 用户地址 --> + <div class='address-box'> + <div class='box-head'>收货人信息 <a class="add-addr" href="javascript:;" onclick="javascript:emptyAddress(this,1)">新增收货地址</a></div> + <!-- 选中地址 --> + <div class='j-show-box {if empty($userAddress)}hide{/if}' > + <div id="s_userName" class="wst-frame1 j-selected">{if isset($userAddress["addressId"]) }{$userAddress['userName']}{/if}<i></i></div> + <div class="address" onmouseover="addrBoxOver(this)" onmouseout="addrBoxOut(this)"> + <span id='s_address'> + {if isset($userAddress["addressId"]) } + {$userAddress['userName']}&nbsp;&nbsp;&nbsp;{$userAddress['areaName']}&nbsp;&nbsp;{$userAddress['userAddress']}&nbsp;&nbsp;{$userAddress['userPhone']} + {/if} + </span> + &nbsp;&nbsp; + <span id="isdefault" {if(isset($userAddress['isDefault'])&&($userAddress['isDefault']==1))} class="j-default">默认地址{else /} >{/if}</span> + <div class="operate-box"> + <a href="javascript:void(0)" onclick="javascript:toEditAddress({if isset($userAddress["addressId"]) }{$userAddress["addressId"]}{/if},this,1,1,1)">编辑</a>&nbsp;&nbsp; + </div> + </div> + + <div class='wst-clear'></div> + + <div class="address"> + <a class="wst-lfloat" href='javascript:void(0)' onclick='javascript:showEditAddressBox()' style=''>更多地址</a> + </div> + + </div> + <!-- 地址列表 --> + <ul class='j-list-box hide' id='addressList'></ul> + + <!-- 新增编辑地址 --> + <div class='j-edit-box {if !empty($userAddress)}hide{/if}'> + <form id='addressForm' autocomplete='off'> + <input type='hidden' class='j-eipt' id='addressId' value=''/> + <div class='rows'> + <div class='label'>收货人<font color='red'>*</font>:</div> + <div class='field'><input type='text' class='j-eipt' id='userName' maxLength='25'/></div> + <div class='wst-clear'></div> + </div> + <div class='rows'> + <div class='label'>收货地址<font color='red'>*</font>:</div> + <div class='field'> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {volist name="areaList" id="vo"} + <option value="{$vo['areaId']}">{$vo['areaName']}</option> + {/volist} + </select> + <input type='text' class='j-eipt' id='userAddress' style='width:300px' maxLength='200'/> + </div> + <div class='wst-clear'></div> + </div> + <div class='rows'> + <div class='label'>联系电话<font color='red'>*</font>:</div> + <div class='field'><input type='text' id='userPhone' class='j-eipt' name="addrUserPhone" maxLength='50'/> </div> + <div class='wst-clear'></div> + </div> + <div class='rows'> + <div class='label'>是否默认地址<font color='red'>*</font>:</div> + <div class='radio-box'> + <label style='margin-right:36px;'> + <input type='radio' name='isDefault' value='1' checked class='j-eipt wst-radio' id="isDefault1"/><label class="mt-1" for="isDefault1"></label>是 + </label> + <label> + <input type='radio' name='isDefault' value='0' class='j-eipt wst-radio' id="isDefault2"/><label class="mt-1" for="isDefault2"></label>否 + </label> + </div> + <div class='wst-clear'></div> + </div> + <div class='rows'> + <a href='javascript:void(0)' class='wst-cart-reda' id='saveAddressBtn' onclick='javascript:editAddress()' style='width:105px;line-height:33px;padding:6px 15px'>保存收货人地址</a> + </div> + </form> + </div> + </div> + <!-- 支付方式 --> + <div class='pay-box'> + <div class='box-head'>支付方式</div> + <div class="wst-list-box"> + {if !empty($payments['0'])} + <div class="wst-frame2 j-selected" onclick="javascript:changeSelected(0,'payType',this)">货到付款<i></i></div> + {/if} + {if !empty($payments['1'])} + <div class="wst-frame2 <?php echo empty($payments['0'])?'j-selected':''; ?>" onclick="javascript:changeSelected(1,'payType',this)">在线支付<i></i></div> + {/if} + <input type='hidden' value="<?php echo empty($payments['0'])?1:0; ?>" id='payType' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + </div> + <!-- 商品清单 --> + <div class='cart-box2'> + <div class='box-head2'>商品清单</div> + <div class='cart-head2'> + <div class='goods2'>商品</div> + <div class='price2'>单价</div> + <div class='num2'>数量</div> + <div class='t-price2'>总价</div> + </div> + {php}$shopFreight = 0;{/php} + {volist name='$carts["carts"]' id='vo'} + {php} + if($vo['isFreeShipping']){ + $freight = 0; + }else{ + if(!empty($userAddress)){ + $freight = WSTOrderFreight($vo['shopId'],$userAddress['areaId2']); + }else{ + $freight = WSTOrderFreight($vo['shopId'],-1); + } + } + $shopFreight = $shopFreight + $freight; + {/php} + <div class='cart-item j-shop' dataval='{$vo['shopId']}'> + <div class='shop2'> + {$vo['shopName']} + {if $vo['shopQQ'] !=''} + <a href="tencent://message/?uin={$vo['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$vo['shopQQ']}:7" alt="QQ交谈" width="71" height="24"/> + </a> + {/if} + {if $vo['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$vo['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$vo['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + {:hook('homeDocumentSettlementShopPromotion',['shop'=>$vo])} + <div class='goods-list'> + {volist name='vo["list"]' id='vo2'} + {:hook('homeDocumentSettlementGoodsPromotion',['goods'=>$vo2])} + <div class='item selected j-g{$vo2["cartId"]}'> + <div class='goods2'> + <div class='img2'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name2'>{$vo2["goodsName"]}</div> + <div class='spec2'> + {volist name='vo2["specNames"]' id='specs'} + <div>{$specs['catName']}:{$specs['itemName']}</div> + {/volist} + </div> + </div> + <div class='price2'>¥{$vo2['shopPrice']}</div> + <div class='num2'>{$vo2['cartNum']}</div> + <div class='t-price2'>¥{$vo2['shopPrice']*$vo2['cartNum']}</div> + <div class='wst-clear'></div> + </div> + {/volist} + <div class='shop-remark selected2'> + <div class='shop-remark-box'> + 订单备注:<input type='text' id="remark_{$vo['shopId']}" class='j-ipt' style='width:420px' maxLength='100' placeholder='给卖家留言'/> + </div> + <div class='shop-summary'> + {if !empty($vo['coupons'])} + {:hook('homeDocumentSettlementShopSummary',['coupons'=>$vo['coupons'],'shopId'=>$vo['shopId']])} + {else} + <input type='hidden' class='j-ipt' id='couponId_{$vo['shopId']}'/> + {/if} + <div class='row'> + <dt>运费:</dt><dd>¥<span id="shopF_{$vo['shopId']}" style='font-weight: bold;color: #E55356;'>{$freight}</span></dd> + </div> + <div class='row'> + <dt>店铺合计(含运费):</dt><dd>¥<span id="shopC_{$vo['shopId']}" v="{$vo['goodsMoney']}" style='font-weight: bold;color: #E55356;'>{:WSTPositiveNum($freight+$vo['goodsMoney']-$vo['promotionMoney'])}</span></dd> + </div> + </div> + </div> + </div> + </div> + {/volist} + <!-- 送货方式 --> + <div class='pay-boxs'> + <div class='box-head'>送货方式</div> + <div class="wst-list-box"> + <div class="wst-frame2 j-selected" onclick="javascript:changeDeliverType(0,'deliverType',this)">快递运输<i></i></div> + <!-- <div class="wst-frame2" onclick="javascript:changeDeliverType(1,'deliverType',this)">自提<i></i></div> --> + <input type='hidden' value='0' id='deliverType' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + </div> + <div class='cart-footer'> + <div class='cart-summary2'> + <div class="summarys2"> + <!-- 发票信息 --> + <div class="pay-boxs"> + <div class='box-head'>发票信息</div> + <div class="j-show-box"> + + <div style="float:left;" id="invoice_info">不开发票</div> + <div style="float:left;color:blue;margin-left:10px;cursor:pointer;" onclick='javascript:changeInvoice(1,"#invoiceClientDiv",this)'>修改</div> + + <div class="wst-clear"></div> + <input type="hidden" id="invoice_obj" value="0" /> + <input type="hidden" id="invoiceId" value="0" class='j-ipt' /> + <input type='hidden' value='0' id='isInvoice' class='j-ipt' /> + <input type='hidden' value='个人' id='invoiceClient' class='j-ipt' /> + </div> + <div class='wst-clear'></div> + </div> + + </div> + <div class="summarys3" style='text-align:right;padding-right:20px'> + <div>运费总计:¥<span id='deliverMoney'>{$shopFreight}</span></div> + {if WSTConf('CONF.isOpenScorePay')==1} + <div> + (可用<span id='maxScoreSpan'>{$userOrderScore}</span>个惠宝抵¥<span id='maxScoreMoneySpan'>{$userOrderMoney|(int)}</span>) + <input type='checkbox' id='isUseScore' autocomplete="off" onclick='javascript:checkScoreBox(this.checked)' dataval="{$userOrderScore}"/>惠宝支付 + <span id='scoreMoney' style='display:none'> + ,使用惠宝<input type="text" id="useScore" style="width:50px;margin-left:5px" class='j-ipt' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" onkeypress="return WST.isNumberKey(event)" onblur="javascript:getCartMoney()" value="{$userOrderScore}"/> + </span> + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;¥-<span id='scoreMoney2'>0.0</span></div> + {/if} + <div class='summary2'>应付总金额(含运费):¥<span id='totalMoney' v='{$carts["goodsTotalMoney"]}'> + {if empty($userAddress)} + {:WSTPositiveNum($carts["goodsTotalMoney"]-$carts['promotionMoney'])} + {else} + {:WSTPositiveNum($carts["goodsTotalMoney"]+$shopFreight-$carts['promotionMoney'])} + {/if} + </span></div> + <!--去掉赠送积分显示 make cheng 20180303--> + <div {if WSTConf('CONF.isOrderScore')!=1 }style='display:none'{/if}>可获得惠宝:<span id='orderScore'>{:WSTMoneyGiftScore($carts["goodsTotalMoney"])}</span>个</div> + </div> + <div class='wst-clear'></div> + </div> + </div> + </div> + <div class='cart-btn'> + <a href='{:Url("home/carts/index")}' class='wst-prev wst-cart-asha' style='width:105px;height:33px;line-height:33px;'>上一步</a> + <a href='javascript:void(0)' onclick='javascript:submitOrder()' class='wst-order wst-cart-reda' style='width:118px;height:33px;line-height:33px;'>提交订单</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/settlement_quick.html b/hyhproject/home2/view/default/settlement_quick.html new file mode 100755 index 0000000..50b8318 --- /dev/null +++ b/hyhproject/home2/view/default/settlement_quick.html @@ -0,0 +1,147 @@ +{extend name="default/base" /} +{block name="title"}我的购物车 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/carts.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">我的购物车</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">填写核对订单信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">3</dt> + <dd class="s-text1">成功提交订单</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>填写并核对订单</div> + <!-- 支付方式 --> + <div class='pay-box' style='border-top:2px solid #fc7a64'> + <div class='box-head'>支付方式</div> + <div class="wst-list-box"> + {if !empty($payments['1'])} + <div class="wst-frame2 j-selected" onclick="javascript:changeSelected(1,'payType',this)">在线支付<i></i></div> + {/if} + <input type='hidden' value='0' id='payType' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + </div> + <!-- 商品清单 --> + <div class='cart-box2'> + <div class='box-head2'>商品清单</div> + <div class='cart-head2'> + <div class='goods2'>商品</div> + <div class='price2'>单价</div> + <div class='num2'>数量</div> + <div class='t-price2'>总价</div> + </div> + {volist name='$carts["carts"]' id='cartShops'} + <div class='cart-item j-shop' dataval='{$cartShops['shopId']}'> + <div class='shop2'> + {$cartShops['shopName']} + {if $cartShops['shopQQ'] !=''} + <a href="tencent://message/?uin={$cartShops['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$cartShops['shopQQ']}:7" alt="QQ交谈" width="71" height="24"/> + </a> + {/if} + {if $cartShops['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$cartShops['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$cartShops['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + {:hook('homeDocumentSettlementShopPromotion',['shop'=>$cartShops])} + <div class='goods-list'> + {volist name='cartShops["list"]' id='cartGoods'} + {:hook('homeDocumentSettlementGoodsPromotion',['goods'=>$cartGoods])} + <div class='item selected'> + <div class='goods2'> + <div class='img2'> + <a href='{:Url("home/goods/detail","id=".$cartGoods["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$cartGoods["goodsImg"]}' width='80' height='80' title='{$cartGoods["goodsName"]}'/> + </a> + </div> + <div class='name2'>{$cartGoods["goodsName"]}</div> + <div class='spec2'></div> + </div> + <div class='price2'>¥{$cartGoods['shopPrice']}</div> + <div class='num2'>{$cartGoods['cartNum']}</div> + <div class='t-price2'>¥{$cartGoods['shopPrice']*$cartGoods['cartNum']}</div> + <div class='wst-clear'></div> + </div> + {/volist} + <div class='shop-remark selected2'> + <div class='shop-remark-box'> + 订单备注:<input type='text' id="remark_{$cartShops['shopId']}" class='j-ipt' style='width:420px' maxLength='100' placeholder='给卖家留言'/> + </div> + <div class='shop-summary'> + {if !empty($cartShops['coupons'])} + {:hook('homeDocumentSettlementShopSummary',['coupons'=>$cartShops['coupons'],'shopId'=>$cartShops['shopId']])} + {else} + <input type='hidden' class='j-ipt' id='couponId_{$cartShops['shopId']}'/> + {/if} + <div class='row'> + <dt>店铺合计:</dt><dd>¥<span id="shopC_{$cartShops['shopId']}" v="{$cartShops['goodsMoney']}" style='font-weight: bold;color: #E55356;'>{:WSTPositiveNum($cartShops['goodsMoney']-$cartShops['promotionMoney'])}</span></dd> + </div> + </div> + </div> + </div> + </div> + {/volist} + <div class='cart-footer'> + <div class='cart-summary2'> + <div class="summarys2"> + <!-- 发票信息 --> + <div class="pay-boxs"> + <div class='box-head'>发票信息</div> + <div class="j-show-box"> + + <div style="float:left;" id="invoice_info">不开发票</div> + <div style="float:left;color:blue;margin-left:10px;cursor:pointer;" onclick='javascript:changeInvoice(1,"#invoiceClientDiv",this)'>修改</div> + + <div class="wst-clear"></div> + <input type="hidden" id="invoice_obj" value="0" /> + <input type="hidden" id="invoiceId" value="0" class='j-ipt' /> + <input type='hidden' value='0' id='isInvoice' class='j-ipt' /> + <input type='hidden' value='个人' id='invoiceClient' class='j-ipt' /> + </div> + <div class='wst-clear'></div> + </div> + + </div> + <div class="summarys3" style='text-align:right;padding-right:20px'> + {if WSTConf('CONF.isOpenScorePay')==1} + <div> + (共有<span id='maxScoreSpan'>{$userOrderScore}</span>个积分,可抵¥<span id='maxScoreMoneySpan'>{$userOrderMoney}</span>) + <input type='checkbox' id='isUseScore' autocomplete="off" onclick='javascript:checkScoreBox(this.checked)' dataval="{$userOrderScore}"/>积分支付 + <span id='scoreMoney' style='display:none'> + ,使用积分<input type="text" id="useScore" style="width:50px;margin-left:5px" class='j-ipt' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" onkeypress="return WST.isNumberKey(event)" onblur="javascript:getCartMoney()" value="{$userOrderScore}"/> + </span> + &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;¥-<span id='scoreMoney2'>0.0</span></div> + {/if} + <div class='summary2'>应付总金额:¥<span id='totalMoney' v='{$carts["goodsTotalMoney"]}'> + {:WSTPositiveNum($carts["goodsTotalMoney"]-$carts['promotionMoney'])} + </span></div> + <div {if WSTConf('CONF.isOrderScore')!=1 }style='display:none'{/if}>可获得积分:<span id='orderScore'>{:WSTMoneyGiftScore($carts["goodsTotalMoney"],0)}</span>个</div> + </div> + <div class='wst-clear'></div> + </div> + </div> + </div> + <div class='cart-btn'> + + <a href='javascript:void(0)' onclick='javascript:submitOrder()' class='wst-order wst-cart-reda' style='width:118px;height:33px;line-height:33px;'>提交订单</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/carts_quick.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_apply.html b/hyhproject/home2/view/default/shop_apply.html new file mode 100755 index 0000000..92f93d8 --- /dev/null +++ b/hyhproject/home2/view/default/shop_apply.html @@ -0,0 +1,81 @@ +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div id="wst-shopapp" class="wst-shopapp" style="display:none;"> + <div class="wst-shopapp-fo"> + <a href="javascript:void(0)" onclick="javascript:getClose()" class="wst-shopapp-close"></a> + <form id="apply_form" method="post" autocomplete="off"> + <table class="wst-table" style="margin:15px;margin-left:35px;"> + <tr> + <td class="wst-shopapp-td">联系人</td> + <td><input id="linkman" name="linkman" class="wst_ipt2 wst-shopapp-input" tabindex="1" maxlength="30" autocomplete="off" onpaste="return false;" style="ime-mode:disabled;" placeholder="联系人" type="text" data-rule="联系人 required;" data-msg-mobile="请输入联系人" data-msg-required="请输入联系人" data-tip="请输入联系人"/></td> + </tr> + <tr> + <td class="wst-shopapp-td">手机号</td> + <td><input id="userPhone2" name="userPhone" class="wst_ipt2 wst-shopapp-input" tabindex="1" maxlength="30" autocomplete="off" onpaste="return false;" style="ime-mode:disabled;" placeholder="手机号" type="text"data-rule="手机号 required;mobile;remote(post:{:url('home/shopapplys/checkShopPhone')})" data-msg-mobile="请输入有效的手机号" data-msg-required="请输入手机号" data-tip="请输入手机号" data-target="#userPhone2"/></td> + </tr> + {if(WSTConf('CONF.smsOpen')==1)} + <tr> + <td class="wst-shopapp-td">短信验证码</td> + <td> + <input maxlength="6" autocomplete="off" tabindex="6" class="wst_ipt2 wst-shopapp-input2" name="mobileCode" style="ime-mode:disabled" id="mobileCode" type="text" placeholder="短信验证码" /> + <button type="button" onclick="javascript:getShopCode();" class="wst-shopapp-obtain">获取短信验证码</button> + <span id="mobileCodeTips"></span> + </td> + </tr> + {else} + <tr> + <td class="wst-shopapp-td">验证码</td> + <td> + <div class="wst-apply-code"> + <input id="verifyCodea" style="ime-mode:disabled" name="verifyCodea" class="wst_ipt2 wst-apply-codein" tabindex="6" autocomplete="off" maxlength="6" type="text" placeholder="验证码"/> + <img id='verifyImga' class="wst-apply-codeim" src="" onclick='javascript:WST.getVerify("#verifyImga")' style="width:101px;border-top-right-radius:2px;border-bottom-right-radius:2px;"><span id="verifya"></span> + </div> + </td> + </tr> + {/if} + <tr> + <td class="wst-shopapp-td">备注</td> + <td> + <textarea id="remark" name="remark" class="wst_ipt2 wst-remark" id="rejectionRemarks" autocomplete="off" style="width: 350px;height:170px;"></textarea> + </td> + </tr> + <tr> + <td colspan="2" style="padding-left:80px;"> + <label> + <input id="protocol" name="protocol" type="checkbox" class="wst_ipt2" value="1"/>我已阅读并同意 + </label> + <a href="javascript:;" style="color:#69b7b5;" id="protocolInfo" onclick="showProtocol();">《商家注册协议》</a> + </td> + </tr> + <tr style="height:45px;"> + <td colspan="2" style="padding-left:165px;"> + <input id="reg_butt" class="wst-shopapp-but" type="submit" value="注册" style="width: 100px;height:30px;"/> + </td> + </tr> + </table> + </form> + </div> +</div> + <form method="post" id="shopVerifys" autocomplete="off" style="display:none;"> + <input type='hidden' id='VerifyId' value='' autocomplete="off"/> + <table class='wst-table' style="width:400x;margin:15px;margin-left:35px;"> + <tr> + <td class="wst-shopapp-td">验证码</td> + <td> + <input id="smsVerfy" name="smsVerfy" class="wst_ipt2 wst-shopapp-input2" tabindex="6" autocomplete="off" maxlength="6" type="text" data-target="#smsVerfyTips" placeholder="验证码" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码"/> + <span id="smsVerfyTips" style="float:right;"></span> + <label style="float:right;margin-top:5px;"><a href="javascript:WST.getVerify('#verifyImg3')">&nbsp;换一张</a></label> + <label style="float:right;"> + <img id='verifyImg3' src="" onclick='javascript:WST.getVerify("#verifyImg3")' style="width:100px;"> + </label> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:170px;height:50px;'> + <button class="wst-shopapp-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/shop_applys.js?v={$v}'></script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_home.html b/hyhproject/home2/view/default/shop_home.html new file mode 100755 index 0000000..154f576 --- /dev/null +++ b/hyhproject/home2/view/default/shop_home.html @@ -0,0 +1,281 @@ +{extend name="default/base" /} +{block name="title"}{$data['shop']['shopName']} - {:WSTConf('CONF.mallName')}{__block__}{/block} +<meta name="description" content="{$data['shop']['shopDesc']},{:WSTConf('CONF.mallName')}"> +<meta name="Keywords" content="{$data['shop']['shopKeywords']},{:WSTConf('CONF.mallName')}"> +{block name="css"} +<link href="__STATIC__/plugins/lazyload/skin/laypage.css?v={$v}" rel="stylesheet"> +<link href="__STATIC__/plugins/slide/css/slide.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shophome.css?v={$v}" rel="stylesheet"> +{/block} +{block name="header"} + <div class="wst-container"> + <div class="wst-shop-h"> + <div class="wst-shop-img"><a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"><img class="shopsImg" data-original="__IMGURL__/{$data['shop']['shopImg']}" title="{$data['shop']['shopName']}"></a></div> + <div class="wst-shop-info"> + <p>{$data['shop']['shopName']}</p> + <div class="wst-shop-info2"> + {volist name="$data['shop']['accreds']" id="ac"} + <img src="__IMGURL__/{$ac['accredImg']}"><span>{$ac['accredName']}</span> + {/volist} + {if($data['shop']['shopQQ'])} + <a href="tencent://message/?uin={$data['shop']['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style="width:65px;height:24px;" src="http://wpa.qq.com/pa?p=1:{$data['shop']['shopQQ']}:7"> + </a> + {/if} +<!--增加1688旺旺显示 mark by cheng 20180314--> + {if($data['shop']['shopWangWang'])} + {if($data['shop']['shopWangWangType']==0)} + <a href="http://www.taobao.com/webww/ww.php?ver=3&touid={$data['shop']['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8" target="_blank"> + <img border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$data['shop']['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" class='wangwang'/> + </a>{/if} + {if($data['shop']['shopWangWangType']==1)} + <a href="http://amos.alicdn.com/msg.aw?v=2&uid={$data['shop']['shopWangWang']}&site=cnalichn&s=10&charset=utf-8" target="_blank" ><img border="0" class='wangwang' src="http://amos.alicdn.com/online.aw?v=2&uid={$data['shop']['shopWangWang']}&site=cnalichn&s=10&charset=UTF-8" alt="点击这里给我发消息" /></a> + {/if} + {/if} + </div> + <div class="wst-shop-info3"> + <span class="wst-shop-eva">商品评价:<span class="wst-shop-red">{$data['shop']['scores']['goodsScore']}</span></span> + <span class="wst-shop-eva">时效评价:<span class="wst-shop-red">{$data['shop']['scores']['timeScore']}</span></span> + <span class="wst-shop-eva">服务评价:<span class="wst-shop-red">{$data['shop']['scores']['serviceScore']}</span></span> + {if($data['shop']['favShop']>0)} + <a href='javascript:void(0);' onclick='WST.cancelFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav">已关注</a> + {else} + <a href='javascript:void(0);' onclick='WST.addFavorite(this,1,{$data['shop']['shopId']},{$data['shop']['favShop']})' class="wst-shop-evaa j-fav2">关注店铺</a> + {/if} + <span class="wst-shop-eva">用手机逛本店 &nbsp;&nbsp;|</span> + <a class="wst-shop-code"><span class="wst-shop-codes hide"><div id='qrcode' style='width:142px;height:142px;'></div></span></a> + </div> + </div> + <div class="wst-shop-sea"> + <input type="text" id="goodsName" value="{$goodsName}" placeholder="输入商品名称"> + <a class="search" href="javascript:void(0);" onclick="javascript:WST.goodsSearch($('#goodsName').val());">搜全站</a> + <a class="search" href="javascript:void(0);" onclick="javascript:searchShopsGoods(0);">搜本店</a> + <div class="wst-shop-word"> + {volist name="data['shop']['shopHotWords']" id="shw"} + <a href='{:Url("home/shops/home",array('shopId'=>$data['shop']['shopId'],'goodsName'=>$shw))}'>{$shw}</a>{if $i< count($data['shop']['shopHotWords'])}&nbsp;|&nbsp;{/if} + {/volist} + </div> + + + {:hook('homeDocumentShopHomeHeader',['shop'=>$data['shop'],'getParams'=>input()])} + <div class="jiathis_style_24x24 wst-shop-share"> + <a class="jiathis_button_qzone"></a> + <a class="jiathis_button_tsina"></a> + <a class="jiathis_button_tqq"></a> + <a class="jiathis_button_weixin"></a> + <a class="jiathis_button_cqq"></a> + <a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jtico jtico_jiathis" target="_blank"></a> + </div> + <div style="clear: both;"></div> + + <script type="text/javascript" src="http://v3.jiathis.com/code/jia.js" charset="utf-8"></script> + + </div> + <div class="wst-clear"></div> + </div> + </div> + {if($data['shop']['shopBanner'])}<div class="wst-shop-tu" style="background: url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat scroll center top;background-size:cover;"></div>{/if} + <div class='wst-header'> + <div class="wst-shop-nav"> + <div class="wst-nav-box"> + <a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"><li class="liselect wst-lfloat {if condition="$ct1 eq 0"}wst-nav-boxa{/if}">本店全部商品</li></a> + {volist name="$data['shopcats']" id="sc" offset="0" length='8'} + <a href="{:url('home/shops/cat',array('shopId'=>$sc['shopId'],'ct1'=>$sc['catId']))}"><li class="liselect wst-lfloat {if condition="$ct1 eq $sc['catId']"}wst-nav-boxa{/if}">{$sc['catName']}</li></a> + {/volist} + <a class="homepage" href='{$Request.root.true}'>返回商城首页</a> + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-clear"></div> + </div> + {if($data['shop']['shopAds'])} + <div class="ck-slide"> + <ul class="ck-slide-wrapper"> + {volist name="$data['shop']['shopAds']" id="ads"} +<!--去掉异步加载图片,修正幻灯片第三张不显示错误 make cheng 20180301 +<li> + <a {if ($ads['isOpen'])}target='_blank'{/if} href="{$ads['adUrl']}" ><img class='goodsImg' data-original="__ROOT__/{$ads['adImg']}" width="100%" height="400"/></a> + </li>--> + <li> + <a {if ($ads['isOpen'])}target='_blank'{/if} href="{$ads['adUrl']}" ><img class='goodsImg' src="__IMGURL__/{$ads['adImg']}" width="100%" height="400"/></a> + </li> + {/volist} + </ul> + <!-- <a href="javascript:;" class="ctrl-slide ck-prev" ></a> + <a href="javascript:;" class="ctrl-slide ck-next" ></a> --> + <div class="ck-slidebox"> + <div class="slideWrap"> + <ul class="dot-wrap"> + {volist name="$data['shop']['shopAds']" id="ads" key="i"} + {if condition="$i eq 1"} + <li class="current"><em>{$i}</em></li> + {else} + <li><em>{$i}</em></li> + {/if} + {/volist} + </ul> + </div> + </div> + </div> + {/if} +{/block} +{block name="main"} +<input type="hidden" id="msort" value="{$msort}" autocomplete="off"/> +<input type="hidden" id="mdesc" value="{$mdesc}" autocomplete="off"/> +<input type="hidden" id="shopId" value="{$data['shop']['shopId']}" autocomplete="off"/> +<input type="hidden" id="ct1" value="{$ct1}" autocomplete="off"/> +<input type="hidden" id="ct2" value="{$ct2}" autocomplete="off"/> +<div class="wst-container"> + <div class="wst-shop-contl"> + {if(strlen($data['shop']['shopNotice'])>0)} + <div class="wst-shop-cat"> + <p class="wst-shop-conlp"> + <img src="__STYLE__/img/notice.png" class="notice_img" /> + 店铺公告 + </p> + <div class="wst-shop-catt" style="padding:5px 10px;"> + {$data['shop']['shopNotice']} + </div> + </div> + {/if} + <div class="wst-shop-cat"> + <p class="wst-shop-conlp">店铺分类</p> + <div class="wst-shop-catt"> + {volist name="$data['shopcats']" id="sc1"} + <li onclick="javascript:dropDown(this,{$sc1['catId']});" class="js-shop-plus">{:WSTMSubstr($sc1['catName'],0,15)}</li> + {if($sc1['children'])} + <div class="wst-shop-catts tree_{$sc1['catId']}"> + {volist name="sc1['children']" id="sc2"} + <a href="{:url('home/shops/cat',array('shopId'=>$sc1['shopId'],'ct1'=>$sc1['catId'],'ct2'=>$sc2['catId']))}"><li>{:WSTMSubstr($sc2['catName'],0,15)}</li></a> + {/volist} + </div> + {/if} + {/volist} + </div> + </div> + <div class="wst-shop-best"> + <p class="wst-shop-conlp">热卖商品</p> + {wst:shopgoods type='hot' num='5' id='ho' shop="$data['shop']['shopId']"} + <a href="{:url('home/goods/detail',array('id'=>$ho['goodsId']))}" target="_blank"> + <div class="wst-shop-bestg"> + <div class="wst-shop-besti"><img class="goodsImg" data-original="__IMGURL__/{$ho['goodsImg']}" title="{$ho['goodsName']}" alt="{$ho['goodsName']}"></div> + <a href="{:url('home/goods/detail',array('id'=>$ho['goodsId']))}"><p class="wst-shop-bestgp1">{:WSTMSubstr($ho['goodsName'],0,20)}</p></a> + <p class="wst-shop-bestgp2">已售出<span class="wst-shop-bestpi">{$ho['saleNum']}</span>件</p> + <p class="wst-shop-bestgp2"><span class="wst-shop-bestpr">¥{$ho['shopPrice']}</span><span class="wst-shop-bestpr2">¥{$ho['marketPrice']}</span></p> + </div> + </a> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + {if cookie("history_goods")!=''} + <div class="wst-shop-lat"> + <p class="wst-shop-conlp">最近浏览</p> + {wst:goods type='history' num='4'} + <div class="wst-shop-bestg"> + <div class="wst-shop-besti"><a target='_blank' href="{:Url('home/goods/detail','id='.$vo['goodsId'])}"><img class="goodsImg" data-original="__IMGURL__/{:WSTImg($vo['goodsImg'])}" title="{$vo['goodsName']}" alt="{$vo['goodsName']}" ></div> + <a href="{:url('home/goods/detail','id='.$vo['goodsId'])}" target='_blank'><p class="wst-shop-bestgp1">{$vo['goodsName']}</p></a> + <p class="wst-shop-bestgp2">已售出<span class="wst-shop-bestpi">{$vo['saleNum']}</span>件</p> + <p class="wst-shop-bestgp2"><span class="wst-shop-bestpr">¥{$vo['shopPrice']}</span><span class="wst-shop-bestpr2">¥{$vo['marketPrice']}</span></p> + </div> + {/wst:goods} + <div class="wst-clear"></div> + </div> + {/if} + </div> + <div class="wst-shop-contr"> + <div class="wst-shop-rec"> + <p class="wst-shop-conrp">店长推荐</p> + <div class="wst-shop-recb"> + {wst:shopgoods type='recom' num='4' id='re' shop="$data['shop']['shopId']"} + <div class="wst-shop-rgoods"> + <div class="wst-shop-goimg"><a href="{:url('home/goods/detail',array('id'=>$re['goodsId']))}" target="_blank"><img class="goodsImg" data-original="__IMGURL__/{$re['goodsImg']}" title="{$re['goodsName']}"></a></div> + <p class="wst-shop-gonam"><a href="{:url('home/goods/detail',array('id'=>$re['goodsId']))}" target="_blank">{:WSTMSubstr($re['goodsName'],0,28)}</a></p> + <div class="wst-shop-rect"> + <span>¥{$re['shopPrice']}</span> + {if($re['goodsStock'])} + <a class="wst-shop-recta" href="javascript:WST.addCart({$re['goodsId']})">加入购物车</a> + {else} + <a class="wst-shop-recta2" href="javascript:void(0);">暂无商品</a> + {/if} + </div> + </div> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-shop-list"> + <div class="wst-shop-listh"> + <a href="javascript:void(0);" class="{if condition="$msort eq 0"}wst-shop-a{/if}" onclick="searchShopsGoods(0);">综合排序</a> + <a href="javascript:void(0);" class="{if condition="$msort eq 1"}wst-shop-a{/if}" onclick="searchShopsGoods(1);">人气<span class="{if condition="$msort neq 1"}wst-shop-store{/if}{if condition="$msort eq 1 and $mdesc eq 1"}wst-shop-store2{/if}{if condition="$msort eq 1 and $mdesc eq 0"}wst-shop-store3{/if}"></span></a> + <a href="javascript:void(0);" class="{if condition="$msort eq 2"}wst-shop-a{/if}" onclick="searchShopsGoods(2);">销量<span class="{if condition="$msort neq 2"}wst-shop-store{/if}{if condition="$msort eq 2 and $mdesc eq 1"}wst-shop-store2{/if}{if condition="$msort eq 2 and $mdesc eq 0"}wst-shop-store3{/if}"></span></a> + <a href="javascript:void(0);" class="{if condition="$msort eq 3"}wst-shop-a{/if}" onclick="searchShopsGoods(3);">价格<span class="{if condition="$msort neq 3"}wst-shop-store{/if}{if condition="$msort eq 3 and $mdesc eq 1"}wst-shop-store2{/if}{if condition="$msort eq 3 and $mdesc eq 0"}wst-shop-store3{/if}"></span></a> + <a href="javascript:void(0);" class="{if condition="$msort eq 4"}wst-shop-a{/if}" onclick="searchShopsGoods(4);">好评度<span class="{if condition="$msort neq 4"}wst-shop-store{/if}{if condition="$msort eq 4 and $mdesc eq 1"}wst-shop-store2{/if}{if condition="$msort eq 4 and $mdesc eq 0"}wst-shop-store3{/if}"></span></a> + <a href="javascript:void(0);" class="{if condition="$msort eq 5"}wst-shop-a{/if}" onclick="searchShopsGoods(5);">上架时间<span class="{if condition="$msort neq 5"}wst-shop-store{/if}{if condition="$msort eq 5 and $mdesc eq 1"}wst-shop-store2{/if}{if condition="$msort eq 5 and $mdesc eq 0"}wst-shop-store3{/if}"></span></a> + <div class="wst-price-ipts"> + <span class="wst-price-ipt1">¥</span><span class="wst-price-ipt2">¥</span> + <input type="text" class="wst-price-ipt" id="sprice" value="{$sprice}" style="margin-left:8px;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + - <input type="text" class="wst-price-ipt" id="eprice" value="{$eprice}" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <button class="wst-shop-but" type="submit" style="width:60px;height: 33px;" onclick="searchShopsGoods(0);">确定</button> + </div> + <div class="wst-clear"></div> + <div class="wst-shop-listg"> + {volist name="$data['list']['Rows']" id="li"} + <div class="wst-shop-goods"> + <div class="wst-shop-goimg"><a href="{:url('home/goods/detail',array('id'=>$li['goodsId']))}" target="_blank"><img class="goodsImg" data-original="__IMGURL__/{$li['goodsImg']}" title="{$li['goodsName']}"></a><a href="javascript:WST.addCart({$li['goodsId']});"><span class="js-cart">加入购物车</span></a></div> + <p class="wst-shop-gonam"><a href="{:url('home/goods/detail',array('id'=>$li['goodsId']))}" target="_blank">{:WSTMSubstr($li['goodsName'],0,15)}</a></p> + <p class="wst-shop-goodp1"><span class="wst-shop-goodpr">¥{$li['shopPrice']}</span><span class="wst-rfloat">成交数:<span class="wst-shop-goodpr2">{$li['saleNum']}</span></span></p> + <p class="wst-shop-goodp2"><span class="wst-shop-goodpr3">市场价:¥{$li['marketPrice']}</span><span class="wst-rfloat">已有<span class="wst-shop-goodpr4">{$li['appraiseNum']}</span>人评价</span></p> + </div> + {/volist} + <div class="wst-clear"></div> + </div> + <div class="wst-shop-pa"> + <div id="shopPage"></div> + </div> + </div> + </div> + <div class="wst-clear"></div> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/slide/js/slide.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/shophome.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> +$(function(){ + if({$data['list']['TotalPage']}>1){ + laypage({ + cont: 'shopPage', + pages: {$data['list']['TotalPage']}, //总页数 + curr: {$data['list']['CurrentPage']}, + skip: true, //是否开启跳页 + skin: '#fd6148', + groups: 3, //连续显示分页数 + prev: '<<', + next: '>>', + jump: function(e, first){ //触发分页后的回调 + if(!first){ //一定要加此判断,否则初始时会无限刷新 + var nuewurl = WST.splitURL("page"); + var ulist = nuewurl.split("?"); + if(ulist.length>1){ + location.href = nuewurl+'&page='+e.curr; + }else{ + location.href = '?page='+e.curr; + } + + } + } + }); + } + var qr = qrcode(10, 'M'); + var url = '{:url("mobile/shops/home",array("shopId"=>$data["shop"]["shopId"]),true,true)}'; + qr.addData(url); + qr.make(); + $('#qrcode').html(qr.createImgTag()); +}); +</script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join.html b/hyhproject/home2/view/default/shop_join.html new file mode 100755 index 0000000..3587a26 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join.html @@ -0,0 +1,96 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class='apply-banner'> + <div class='wst-container'> + <div class='apply-msg-box'> + <h3>亲爱的{:session('WST_USER.loginName')},您好:</h3> + <div class='title'>欢迎来到{:WSTConf('CONF.mallName')}</div> + <ul> + <li>您若还没有填写入驻资料<br/>请点击“<span style='color:#FFB748'>申请入驻</span>”填写入驻资料。</li> + <li>您若已经填写入驻资料<br/>则可点击“<span style='color:#FFB748'>入驻进度查询</span>”查询审核情况。</li> + </ul> + <div class="bottom"> + {if $isApply==1} + <a class='btn-cancel' style='color:#ddd'>申请入驻</a> + {else} + <a class='btn-submit' href='{:Url("home/shops/joinStep".$applyStep)}'>申请入驻</a> + {/if} + <a class='btn-submit' style='margin-left:10px;padding:0px 10px' href='{:Url("home/shops/checkapplystatus")}'>入驻进度查询</a> + </div> + </div> + </div> + <div class="wst-slide" id="wst-slide"> + <ul class="wst-slide-items" style='min-width: 1200px;height: 420px;'> + {wst:ads code="ads-shop-apply" cache='86400'} + <li style="background: url(__IMGURL__/{$vo.adFile}) no-repeat scroll center top;background-size:cover;height:350px;"></li> + {/wst:ads} + </ul> + <div class="wst-slide-numbox"> + <div class="wst-slide-controls"> + {wst:ads code="ads-shop-apply" cache='86400' key='k'} + {if condition="$k+1 eq 1"} + <span class="curr">{$k+1}</span> + {else/} + <span class="">{$k+1}</span> + {/if} + {/wst:ads} + </div> + </div> + </div> + </div> + <div class="apply-tips"> + <div class="wst-container"> + <span class="title"><i></i> + <h3>贴心提示</h3> + </span><span class="content">{:WSTConf('CONF.mallName')}平台提供各类商家服务,协助您开通店铺、运营店铺、组织营销活动及分析运营数据,悉心为您解答各类疑问,引导您按相关规则展开运营;<br/>我们将竭尽全力,为您的店铺保驾护航。</span> + </div> + </div> + <div class="wst-container"> + <div class='apply-step-head'>入驻流程</div> + <div class="apply-step"> + <span class="step"><i class="a"></i>签署入驻协议</span> + <span class="arrow"></span> + <span class="step"><i class="b"></i>商家信息提交</span> + <span class="arrow"></span> + <span class="step"><i class="c"></i>平台审核资质</span> + <span class="arrow"></span> + <span class="step"><i class="d"></i>商家缴纳费用</span> + <span class="arrow"></span> + <span class="step"><i class="e"></i>店铺开通</span> + </div> + <div class='apply-step-head'>入驻指南</div> + <div id='applyTab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>招商方向</li> + <li>招商标准</li> + <li>资质要求</li> + <li>资费标准</li> + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;min-height:300px;'> + <div class="wst-tab-item" style="position: relative;">{$artiles['105']['articleContent']|htmlspecialchars_decode} + </div> + <div class="wst-tab-item" style="position: relative;"> + {$artiles['106']['articleContent']|htmlspecialchars_decode} + </div> + <div class="wst-tab-item" style="position: relative;"> + {$artiles['107']['articleContent']|htmlspecialchars_decode} + </div> + <div class="wst-tab-item" style="position: relative;"> + {$artiles['108']['articleContent']|htmlspecialchars_decode} + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ + WST.slides('.wst-slide'); + $('#applyTab').TabPanel({tab:0,callback:function(no){}}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step1.html b/hyhproject/home2/view/default/shop_join_step1.html new file mode 100755 index 0000000..d2b4808 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step1.html @@ -0,0 +1,58 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal"> + <dt class="s-num1">2</dt> + <dd class="s-text1">联系方式</dd> + <dd></dd> + </dl> + <dl class="normal"> + <dt class="s-num1">3</dt> + <dd class="s-text1">公司信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">4</dt> + <dd class="s-text1">税务及银行信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">5</dt> + <dd class="s-text1">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>入驻协议</div> + <div class='apply-agreement-box'> + {$artiles['109']['articleContent']|htmlspecialchars_decode} + </div> + <form id='applyFrom' name='applyFrom' method="post" autocomplete="off"> + <div class='agreement_box'> + <label> + <input type='checkbox' id="protocol" onclick='checkProtocol(this)' name="protocol"/>我已阅读并同意以上协议 + </label> + <span class="msg-box n-right" style='display:none' for="protocol"><span role="alert" class="msg-wrap n-error"><span class="n-icon"></span><span class="n-msg">必须同意协议才能申请入驻</span></span> + </span> + </div> + </form> + <div class='agreement-bottom'> + <a class='btn-submit' href='javascript:saveStep1()'>下一步</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step2.html b/hyhproject/home2/view/default/shop_join_step2.html new file mode 100755 index 0000000..4167313 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step2.html @@ -0,0 +1,88 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal"> + <dt class="s-num1">3</dt> + <dd class="s-text1">公司信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">4</dt> + <dd class="s-text1">税务及银行信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">5</dt> + <dd class="s-text1">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>入驻人联系方式</div> + <div class='apply-box'> + <form id='applyFrom' autocomplete='off'> + <table class='agreement-table' style='margin-top:10px;margin-bottom:10px;'> + <tr> + <th>联系人姓名<font color='red'>*</font>:</th> + <td><input type='text' id='applyLinkMan' class='a-ipt' data-rule='联系人姓名:required;' value="{$apply['applyLinkMan']}"/></td> + </tr> + <tr> + <th>联系人手机<font color='red'>*</font>:</th> + <td><input type='text' class='a-ipt' id='applyLinkTel' data-rule='联系人手机:required;mobile' value="{$apply['applyLinkTel']}"/></td> + </tr> + <!-- + <tr> + <th>联系人电子邮箱<font color='red'>*</font>:</th> + <td> + <input type='text' name='applyLinkEmail' class='a-ipt' id='applyLinkEmail' data-rule='联系人电子邮箱:required;email' value="{$apply['applyLinkEmail']}"/> + <br/><span class='tip'>用于入驻过程中接收商城审核结果,请务必正确填写。</span> + </td> + </tr> + --> + <tr> + <th>对接商城招商人员<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' name='isInvestment' id='isInvestment1' class='a-ipt' value='1' onclick='javascript:WST.showHide(1,"#investmentStaffTr")' {if $apply['isInvestment']==1}checked{/if}/>有 + </label> + <label> + <input type='radio' name='isInvestment' id='isInvestment0' class='a-ipt' value='0' onclick='javascript:WST.showHide(0,"#investmentStaffTr")' {if $apply['isInvestment']==0}checked{/if}/>无 + </label> + 如果没有联系过商城招商人员请选择“无”。 + </td> + </tr> + <tr id='investmentStaffTr' {if $apply['isInvestment']==0}style='display:none'{/if}> + <th>姓名<font color='red'>*</font>:</th> + <td> + <input type='text' name='investmentStaff' id='investmentStaff' class='a-ipt' data-rule="商城招商人员姓名:required(#isInvestment1:checked)" value="{$apply['investmentStaff']}"/> + </td> + </tr> + </table> + </form> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/joinstep1")}' class='btn-cancel'>上一步</a> + <a href='javascript:saveStep2()' class='btn-submit' style='margin-left:10px;'>下一步</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step3.html b/hyhproject/home2/view/default/shop_join_step3.html new file mode 100755 index 0000000..ae41b13 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step3.html @@ -0,0 +1,334 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">3</dt> + <dd class="s-text">公司信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">4</dt> + <dd class="s-text1">税务及银行信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">5</dt> + <dd class="s-text1">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>公司信息</div> + <div class='apply-box'> + <form id='applyFrom' autocomplete='off'> + <table class='agreement-table'> + <tr> + <td colspan='2' class='head-ititle'>公司信息</td> + </tr> + <tr> + <th>执照类型<font color='red'>*</font>:</th> + <td> + <select id='businessLicenceType' class='a-ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $apply['businessLicenceType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号<font color='red'>*</font>:</th> + <td><input type='text' id='businessLicence' class='a-ipt' data-rule='营业执照注册号:required;' value="{$apply['businessLicence']}"/><br/><span class='tip'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalPersonName' class='a-ipt' data-rule='法定代表人姓名:required;' value="{$apply['legalPersonName']}"/> + <br/><span class='tip'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <!-- + <tr> + <th>营业执照所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + + <tr> + <th>营业执照详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='licenseAddress' class='a-ipt' style='width:550px' data-rule='营业执照详细地址:required;' value="{$apply['licenseAddress']}"/> + </td> + </tr> + + <tr> + <th>成立日期<font color='red'>*</font>:</th> + <td> + <input type='text' id='establishmentDate' readonly class='a-ipt laydate-icon' onclick="laydate()" data-rule='成立日期:required;' value="{$apply['establishmentDate']}"/> + </td> + </tr> + <tr> + <th>营业期限<font color='red'>*</font>:</th> + <td> + <input type='text' id='businessStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" data-rule="营业期限开始日期: required;" data-target="#msg_businessStartDate" value="{$apply['businessStartDate']}"/> - <input type='text' id='businessEndDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['businessEndDate']}"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' {if $apply['isLongbusinessDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_businessStartDate'></span> + </td> + </tr> + <tr> + <th>注册资本(万元)<font color='red'>*</font>:</th> + <td> + <input type='text' id='registeredCapital' class='a-ipt' data-rule='注册资本:required;' value="{$apply['registeredCapital']}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/> + </td> + </tr> + <tr> + <th>经营范围<font color='red'>*</font>:</th> + <td> + <textarea id='empiricalRange' class='a-ipt' style='width:550px;height:150px;' data-rule='经营范围:required;'>{$apply['empiricalRange']}</textarea> + </td> + </tr> +--> + <tr> + <th>公司名称<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopCompany' class='a-ipt' data-rule='公司名称:required;' value="{$apply['shopCompany']}" style='width:400px'/> + </td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:true,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='a-ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$apply['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='a-ipt' data-rule='公司电话:required;' value="{$apply['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='a-ipt' data-rule='公司紧急联系人:required;' value="{$apply['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='a-ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$apply['telephone']}"/> + </td> + </tr> + <tr> + <th>法人代表证件类型<font color='red'>*</font>:</th> + <td> + <select id='legalCertificateType' class='a-ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $apply['legalCertificateType']==$vo['dataVal']}{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalCertificate' class='a-ipt' data-rule='法定代表人证件号:required;' value="{$apply['legalCertificate']}"/> + </td> + </tr> + <!-- + <tr> + <th>有效期<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['legalCertificateStartDate']}"/> - <input type='text' id='legalCertificateEndDate' readonly value="{$apply['legalCertificateEndDate']}" class='a-ipt laydate-icon' onclick="laydate()"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' {if $apply['isLonglegalCertificateDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_legalCertificateStartDate'></span> + </td> + </tr> + --> + <tr> + <th>法人证件电子版正面<font color='red'>*</font>:</th> + <td> + <!-- <span class='tip'>请上传法人证件电子版正面</span><br/> --> + <input type='hidden' id='legalCertificateImg' class='a-ipt' data-rule="法人证件电子版: required;" data-target="#msg_legalCertificateImg" value='{$apply['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版正面</div> + <span id='legalCertificateImgMsg'></span> + <img id='legalCertificateImgPreview' src='__IMGURL__/{$apply['legalCertificateImg']}' {if $apply['legalCertificateImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_legalCertificateImg'></span> + </td> + </tr> + + + <tr> + <th>辅助材料电子版<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='a-ipt' data-rule="营业执照电子版: required;" data-target="#msg_businessLicenceImg" value='{$apply['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <img id='businessLicenceImgPreview' src='__IMGURL__/{$apply['businessLicenceImg']}' {if $apply['businessLicenceImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_businessLicenceImg'></span> + </td> + </tr> + <tr> + <th>银行开户许可证电子版<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='a-ipt' data-rule="银行开户许可证电子版: required;" data-target="#msg_bankAccountPermitImg" value='{$apply['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <img id='bankAccountPermitImgPreview' src='__IMGURL__/{$apply['bankAccountPermitImg']}' {if $apply['bankAccountPermitImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_bankAccountPermitImg'></span> + </td> + </tr> + <tr> + <th width='120' align='right'>补充材料<font color='red'>*</font>:</th> + <td> + <div id="batchUpload" class="a-ipt wst-batchupload" style="border:1px solid #ccc"> + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 其它相关资料请上传到补充材料(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="a-ipt placeholder {if !empty($apply['auxiliary'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$apply['auxiliary']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo.auxiliaryImg}"> + </p> + <input type="hidden" v="{$vo.auxiliaryImg}" iv="{$vo.auxiliaryImg}" class="a-ipt j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar"> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + <div style='clear:both;'></div> + </td> + </tr> + <!-- + <tr> + <td colspan='2' class='head-ititle'>组织机构代码证</td> + </tr> + <tr> + <th>组织机构代码<font color='red'>*</font>:</th> + <td> + <input type='text' id='organizationCode' class='a-ipt' data-rule='组织机构代码:required;' value="{$apply['organizationCode']}"/> + </td> + </tr> + <tr> + <th>组织机构代码证有效期<font color='red'>*</font>:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['organizationCodeStartDate']}" data-rule="组织机构代码证有效期开始日期: required;" data-target="#msg_organizationCodeStartDate"/> - <input type='text' id='organizationCodeEndDate' readonly value="{$apply['organizationCodeEndDate']}" class='a-ipt laydate-icon' onclick="laydate()"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#isLongOrganizationCodeDate")' {if $apply['isLongOrganizationCodeDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_organizationCodeStartDate'></span> + </td> + </tr> + --> + <tr> + <td colspan='2' class='head-ititle'>商标注册证</td> + </tr> + <tr> + <th valign="top">商标注册证电子版<font color='red'>*</font>:</th> + <td> + <span class='tip'>上传商标注册证或注册申请受理通知书</span><br/> + <input type='hidden' id='organizationCodeImg' class='a-ipt' data-rule="组织机构代码证电子版: required;" data-target="#msg_organizationCodeImg" value='{$apply['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证或品牌授权证书</div> + <span id='organizationCodeImgMsg'></span> + <img id='organizationCodeImgPreview' src='__IMGURL__/{$apply['organizationCodeImg']}' {if $apply['organizationCodeImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_organizationCodeImg'></span> + </td> + </tr> + </table> + </form> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/joinStep2")}' class='btn-cancel'>上一步</a> + <a href='javascript:saveStep3()' class='btn-submit' style='width:250px;margin-left:10px;'>下一步,完善税务及银行信息</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +<script>$(function(){initStep2('{$apply["businessAreaPath"]}','{$apply["areaIdPath"]}');})</script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script> + $(function(){ + /********** 轮播广告图片上传 **********/ + var uploader = batchUpload({uploadPicker:'#batchUpload',autoUpload:true,uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shops'},uploadSuccess:function(file,response){ + var json = WST.toJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" value="'+json.savePath+json.name+'" class="a-ipt j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); + } + }); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step35.html b/hyhproject/home2/view/default/shop_join_step35.html new file mode 100755 index 0000000..2c086e0 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step35.html @@ -0,0 +1,247 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">3</dt> + <dd class="s-text">公司信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">4</dt> + <dd class="s-text1">税务及银行信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">5</dt> + <dd class="s-text1">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>公司信息</div> + <div class='apply-box'> + <form id='applyFrom' autocomplete='off'> + <table class='agreement-table'> + <tr> + <td colspan='2' class='head-ititle'>公司信息</td> + </tr> + <tr> + <th>执照类型<font color='red'>*</font>:</th> + <td> + <select id='businessLicenceType' class='a-ipt'> + {volist name=":WSTDatas('LICENSE_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $apply['businessLicenceType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">营业执照注册号<font color='red'>*</font>:</th> + <td><input type='text' id='businessLicence' class='a-ipt' data-rule='营业执照注册号:required;' value="{$apply['businessLicence']}"/><br/><span class='tip'>请按照营业执照上登记的完整名称填写</span></td> + </tr> + <tr> + <th valign="top">法定代表人姓名<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalPersonName' class='a-ipt' data-rule='法定代表人姓名:required;' value="{$apply['legalPersonName']}"/> + <br/><span class='tip'>请按照营业执照上登记的法人填写</span> + </td> + </tr> + <tr> + <th>营业执照所在地<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>营业执照详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='licenseAddress' class='a-ipt' style='width:550px' data-rule='营业执照详细地址:required;' value="{$apply['licenseAddress']}"/> + </td> + </tr> + <tr> + <th>成立日期<font color='red'>*</font>:</th> + <td> + <input type='text' id='establishmentDate' readonly class='a-ipt laydate-icon' onclick="laydate()" data-rule='成立日期:required;' value="{$apply['establishmentDate']}"/> + </td> + </tr> + <tr> + <th>营业期限<font color='red'>*</font>:</th> + <td> + <input type='text' id='businessStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" data-rule="营业期限开始日期: required;" data-target="#msg_businessStartDate" value="{$apply['businessStartDate']}"/> - <input type='text' id='businessEndDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['businessEndDate']}"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLongbusinessDate' id='isLongbusinessDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#businessEndDate")' {if $apply['isLongbusinessDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_businessStartDate'></span> + </td> + </tr> + <tr> + <th>注册资本(万元)<font color='red'>*</font>:</th> + <td> + <input type='text' id='registeredCapital' class='a-ipt' data-rule='注册资本:required;' value="{$apply['registeredCapital']}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/> + </td> + </tr> + <tr> + <th>经营范围<font color='red'>*</font>:</th> + <td> + <textarea id='empiricalRange' class='a-ipt' style='width:550px;height:150px;' data-rule='经营范围:required;'>{$apply['empiricalRange']}</textarea> + </td> + </tr> + <tr> + <th>公司名称<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopCompany' class='a-ipt' data-rule='公司名称:required;' value="{$apply['shopCompany']}" style='width:400px'/> + </td> + </tr> + <tr> + <th>公司所在地<font color='red'>*</font>:</th> + <td> + <select id="carea_0" class='j-careas' level="0" onchange="WST.ITAreas({id:'carea_0',val:this.value,isRequire:true,className:'j-careas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr> + <th>公司详细地址<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopAddress' class='a-ipt' style='width:550px' data-rule='公司详细地址:required;' value="{$apply['shopAddress']}"/> + </td> + </tr> + <tr> + <th>公司电话<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopTel' class='a-ipt' data-rule='公司电话:required;' value="{$apply['shopTel']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopkeeper' class='a-ipt' data-rule='公司紧急联系人:required;' value="{$apply['shopkeeper']}"/> + </td> + </tr> + <tr> + <th>公司紧急联系人手机<font color='red'>*</font>:</th> + <td> + <input type='text' id='telephone' class='a-ipt' data-rule='公司紧急联系人手机:required;mobile' value="{$apply['telephone']}"/> + </td> + </tr> + <tr> + <th>法人代表证件类型<font color='red'>*</font>:</th> + <td> + <select id='legalCertificateType' class='a-ipt'> + {volist name=":WSTDatas('LEGAL_LICENSE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $apply['legalCertificateType']==$vo['dataVal']}{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>法定代表人证件号<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalCertificate' class='a-ipt' data-rule='法定代表人证件号:required;' value="{$apply['legalCertificate']}"/> + </td> + </tr> + <tr> + <th>有效期<font color='red'>*</font>:</th> + <td> + <input type='text' id='legalCertificateStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['legalCertificateStartDate']}"/> - <input type='text' id='legalCertificateEndDate' readonly value="{$apply['legalCertificateEndDate']}" class='a-ipt laydate-icon' onclick="laydate()"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLonglegalCertificateDate' id='isLonglegalCertificateDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#legalCertificateEndDate")' {if $apply['isLonglegalCertificateDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_legalCertificateStartDate'></span> + </td> + </tr> + <tr> + <th>法人证件电子版<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='legalCertificateImg' class='a-ipt' data-rule="法人证件电子版: required;" data-target="#msg_legalCertificateImg" value='{$apply['legalCertificateImg']}'/> + <div id='legalCertificateImgPicker'>请上传法人证件电子版</div> + <span id='legalCertificateImgMsg'></span> + <img id='legalCertificateImgPreview' src='__IMGURL__/{$apply['legalCertificateImg']}' {if $apply['legalCertificateImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_legalCertificateImg'></span> + </td> + </tr> + <tr> + <th>营业执照电子版<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='businessLicenceImg' class='a-ipt' data-rule="营业执照电子版: required;" data-target="#msg_businessLicenceImg" value='{$apply['businessLicenceImg']}'/> + <div id='businessLicenceImgPicker'>请上传营业执照电子版</div> + <span id='businessLicenceImgMsg'></span> + <img id='businessLicenceImgPreview' src='__IMGURL__/{$apply['businessLicenceImg']}' {if $apply['businessLicenceImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_businessLicenceImg'></span> + </td> + </tr> + <tr> + <th>银行开户许可证电子版<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='bankAccountPermitImg' class='a-ipt' data-rule="银行开户许可证电子版: required;" data-target="#msg_bankAccountPermitImg" value='{$apply['bankAccountPermitImg']}'/> + <div id='bankAccountPermitImgPicker'>请上传银行开户许可证电子版</div> + <span id='bankAccountPermitImgMsg'></span> + <img id='bankAccountPermitImgPreview' src='__IMGURL__/{$apply['bankAccountPermitImg']}' {if $apply['bankAccountPermitImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_bankAccountPermitImg'></span> + </td> + </tr> + <!-- <tr> + <td colspan='2' class='head-ititle'>商标注册证</td> + </tr> + <tr> + <th>组织机构代码<font color='red'>*</font>:</th> + <td> + <input type='text' id='organizationCode' class='a-ipt' data-rule='组织机构代码:required;' value="{$apply['organizationCode']}"/> + </td> + </tr> + <tr> + <th>商标注册证有效期<font color='red'>*</font>:</th> + <td> + <input type='text' id='organizationCodeStartDate' readonly class='a-ipt laydate-icon' onclick="laydate()" value="{$apply['organizationCodeStartDate']}" data-rule="商标注册证有效期开始日期: required;" data-target="#msg_organizationCodeStartDate"/> - <input type='text' id='organizationCodeEndDate' readonly value="{$apply['organizationCodeEndDate']}" class='a-ipt laydate-icon' onclick="laydate()"/>&nbsp;&nbsp;&nbsp;<label><input type='checkbox' name='isLongOrganizationCodeDate' id='isLongOrganizationCodeDate' class='a-ipt' onclick='WST.showHide(this.checked?0:1,"#isLongOrganizationCodeDate")' {if $apply['isLongOrganizationCodeDate']==1}checked{/if} value='1'/>长期</label> + <span class='msg-box' id='msg_organizationCodeStartDate'></span> + </td> + </tr> --> + <tr> + <td colspan='2' class='head-ititle'>商标注册证</td> + </tr> + <tr> + <th valign="top">商标注册证电子版<font color='red'>*</font>:</th> + <td> + <span class='tip'>上传商标注册证或注册申请受理通知书</span><br/> + <input type='hidden' id='organizationCodeImg' class='a-ipt' data-rule="商标注册证电子版: required;" data-target="#msg_organizationCodeImg" value='{$apply['organizationCodeImg']}'/> + <div id='organizationCodeImgPicker'>请上传商标注册证或品牌授权证书</div> + <span id='organizationCodeImgMsg'></span> + <img id='organizationCodeImgPreview' src='__IMGURL__/{$apply['organizationCodeImg']}' {if $apply['organizationCodeImg'] ==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_organizationCodeImg'></span> + </td> + </tr> + </table> + </form> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/joinStep2")}' class='btn-cancel'>上一步</a> + <a href='javascript:saveStep3()' class='btn-submit' style='width:250px;margin-left:10px;'>下一步,完善税务及银行信息</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +<script>$(function(){initStep2('{$apply["businessAreaPath"]}','{$apply["areaIdPath"]}');})</script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step4.html b/hyhproject/home2/view/default/shop_join_step4.html new file mode 100755 index 0000000..26e50c1 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step4.html @@ -0,0 +1,142 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">3</dt> + <dd class="s-text">公司信息</dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">4</dt> + <dd class="s-text">税务及银行信息</dd> + </dl> + <dl class="normal"> + <dt class="s-num1">5</dt> + <dd class="s-text1">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>税务及银行信息</div> + <div class='apply-box'> + <form id='applyFrom' autocomplete='off'> + <table class='agreement-table'> + <!-- <tr> + <td class='head-ititle'>税务信息</td> + </tr> + <tr> + <th>纳税人类型<font color='red'>*</font>:</th> + <td> + <select id='taxpayerType' class='a-ipt'> + {volist name=":WSTDatas('TAXPAYER_TYPE')" id='vo'} + <option value='{$vo["dataVal"]}' {if $apply['taxpayerType']==$vo["dataVal"]}selected{/if}>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th valign="top">纳税人识别号<font color='red'>*</font>:</th> + <td><input type='text' id='taxpayerNo' class='a-ipt' data-rule='纳税人识别号:required;' value='{$apply["taxpayerNo"]}'/><br/><span class='tip'>三证合一的请填写统一社会信用代码</span></td> + </tr> + <tr> + <th valign="top">税务登记证电子版<font color='red'>*</font>:</th> + <td> + <span class='tip'>请同时上传国税、地税的税务登记证,两者缺一不可,复印件加盖公司红章,如贵司所在地区已推行“三证合一”,此处请上传营业执照副本电子版。【最多只能上传三张图片】</span><br/> + <input type='hidden' id='taxRegistrationCertificateImg' class='a-ipt' data-rule="税务登记证电子版: required;" data-target="#msg_taxRegistrationCertificateImg" value='{$apply["taxRegistrationCertificateImg"]}'/> + <div id='taxRegistrationCertificateImgPicker'>请上传商标注册证电子版</div> + <span id='taxRegistrationCertificateImgMsg'></span> + <div id='taxRegistrationCertificateImgBox'></div> + <span class='msg-box' id='msg_taxRegistrationCertificateImg'> + {volist name="$apply['taxRegistrationCertificateImgVO']" id='vo'} + <div style="width:75px;float:left;margin-right:5px;"> + <img class="step_pic" width="75" height="75" src="__ROOT__/{$vo}" v="{$vo}"> + <div style="position:relative;top:-80px;left:60px;cursor:pointer;" onclick='javascript:delVO(this)'> + <img src="__ROOT__/hyhproject/home/View/default/img/seller_icon_error.png"> + </div> + </div> + {/volist} + </span> + </td> + </tr> + <tr> + <th valign="top">一般纳税人资格证电子版<font color='red'>*</font>:</th> + <td> + <span class='tip'>三证合一地区请上传税务局网站上一般纳税人截图,复印件需加盖公司红章。</span><br/> + <input type='hidden' id='taxpayerQualificationImg' class='a-ipt' data-rule="一般纳税人资格证电子版: required;" data-target="#msg_taxpayerQualificationImg" value='{$apply["taxpayerQualificationImg"]}'/> + <div id='taxpayerQualificationImgPicker'>请上传法人证件电子版</div> + <span id='taxpayerQualificationImgMsg'></span> + <img id='taxpayerQualificationImgPreview' src='__ROOT__/{$apply["taxpayerQualificationImg"]}' {if $apply["taxpayerQualificationImg"]==''}style='display:none'{/if} width='150'> + <span class='msg-box' id='msg_taxpayerQualificationImg'></span> + </td> + </tr> --> + <tr> + <td class='head-ititle'>结算账号信息</td> + </tr> + <tr> + <th>银行开户名<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankUserName' class='a-ipt' maxlength='50' data-rule='银行开户名:required;' value='{$apply["bankUserName"]}'/> + </td> + </tr> + <tr> + <th>对公结算银行账号<font color='red'>*</font>:</th> + <td> + <input type='text' id='bankNo' class='a-ipt' maxlength='30' data-rule='对公结算银行账号:required;' value='{$apply["bankNo"]}'/> + </td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' id='bankId' class='a-ipt' data-rule='对公结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $apply['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + <!-- + <tr> + <th>开户银行支行所在地<font color='red'>*</font>:</th> + <td> + <select id="barea_0" class='j-bareas' level="0" onchange="WST.ITAreas({id:'barea_0',val:this.value,isRequire:true,className:'j-bareas'});"> + <option value="">-请选择-</option> + {foreach $areaList as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + --> + </table> + </form> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/joinStep3")}' class='btn-cancel'>上一步</a> + <a href='javascript:saveStep4()' class='btn-submit' style='margin-left:10px;'>下一步</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +<script>$(function(){initStep3('{$apply["bankAreaIdPath"]}')})</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_step5.html b/hyhproject/home2/view/default/shop_join_step5.html new file mode 100755 index 0000000..8ef8e2d --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_step5.html @@ -0,0 +1,203 @@ +{extend name="default/base" /} +{block name="title"}入驻人联系方式 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">3</dt> + <dd class="s-text">公司信息</dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">4</dt> + <dd class="s-text">税务及银行信息</dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">5</dt> + <dd class="s-text">店铺信息</dd> + </dl> + <dl class="last"> + <dt class="s-num1">6</dt> + <dd class="s-text1">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='main-head'>店铺信息</div> + <div class='apply-box'> + <form id='applyFrom' autocomplete='off'> + <table class='agreement-table'> + <tr> + <th>店铺名称<font color='red'>*</font>:</th> + <td> + <input type='text' id='shopName' class='a-ipt' data-rule='店铺名称:required;' value="{$apply['shopName']}"/> + </td> + </tr> + <tr> + <th>店铺LOGO<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='shopImg' class='a-ipt' data-rule="店铺LOGO: required;" data-target="#msg_shopImg" value="{$apply['shopImg']}"/> + <div id='shopImgPicker'>请上传店铺LOGO</div> + <span id='shopImgMsg'></span> + <img id='shopImgPreview' src="__IMGURL__/{$apply['shopImg']}" {if $apply['shopImg']==''}style='display:none'{/if} width='150' height='150'> + <span class='msg-box' id='msg_shopImg'></span> + </td> + </tr> + <tr> + <th>经营类目<font color='red'>*</font>:</th> + <td> + {volist name="goodsCatList" id="vo"} + <label class='goodsCat'> + <input type='checkbox' onclick="divShow()" class='a-ipt' id="goodsCatIds" name='goodsCatIds' value='{$vo["catId"]}' {if $i == 1}data-rule="经营范围:checked" {/if} {if array_key_exists($vo['catId'],$apply['catshops'])}checked{/if} data-target="#msg_goodsCatIds"/>{$vo["catName"]} + </label> + {/volist} + <span class='msg-box' id='msg_goodsCatIds'></span> + </td> + </tr> + <tr {if $shopLicense['shopLicense']==''} style='display:none'{/if} id="license"> + <th>食品许可证<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='shopLicense' name="shopLicense" class='a-ipt' data-target="#msg_shopLicense" value="{$shopLicense['shopLicense']}"/> + <div id='shopLicensePicker' class="webuploader-container">请上传食品许可证</div> + <span id='shopLicenseMsg'></span> + <img id='shopLicensePreview' src="__IMGURL__/{$shopLicense['shopLicense']}" {if $shopLicense['shopLicense']==''} style='display:none'{/if} width='150' height='150'> + <span class='msg-box' id='msg_shopLicense'></span> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td><input type='text' id='shopQQ' class='a-ipt' value="{$apply['shopQQ']}"/></td> + </tr> + <tr> + <th>旺旺类型<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='0' class="a-ipt" name='shopWangWangType'{if $apply['shopWangWangType']==0}checked{/if}/>淘宝旺旺 + </label> + <label> + <input type='radio' value='1' class="a-ipt" name='shopWangWangType'{if $apply['shopWangWangType']==1}checked{/if}/>阿里旺旺(1688诚信通) + </label> + + </td> + </tr> + <tr> + <th>阿里旺旺:</th> + <td> + <input type='text' id='shopWangWang' class='a-ipt' value="{$apply['shopWangWang']}"/> + </td> + </tr> + <tr> + <th>是否提供发票<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='1' name='isInvoice' class='a-ipt' onclick='javascript:WST.showHide(1,"#invoiceRemarksTr")' {if $apply['isInvoice']==1}checked{/if}>是 + </label> + <label> + <input type='radio' value='0' name='isInvoice' class='a-ipt' onclick='javascript:WST.showHide(0,"#invoiceRemarksTr")' {if $apply['isInvoice']==0}checked{/if}>否 + </label> + </td> + </tr> + <tr id='invoiceRemarksTr' {if $apply['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td> + <input type='text' id='invoiceRemarks' class='a-ipt' data-rule="发票说明:required(#isInvoice1:checked)" value="{$apply['invoiceRemarks']}" style='width:500px'/> + </td> + </tr> + <tr> + <th>营业状态<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='1' id='shopAtive1' name='shopAtive' class='a-ipt' {if $apply['shopAtive']==1}checked{/if}>营业中 + </label> + <label> + <input type='radio' value='0' id='shopAtive0' name='shopAtive' class='a-ipt' {if $apply['shopAtive']==0}checked{/if}>休息中 + </label> + </td> + </tr> + <tr> + <th>默认运费(元)<font color='red'>*</font>:</th> + <td> + <input type='text' id='freight' class='a-ipt' data-rule="默认运费: required;" onkeypress='return WST.isNumberdoteKey(event);' onkeyup="javascript:WST.isChinese(this,1)" value="{$apply['freight']}"/> + </td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='a-ipt' id='serviceStartTime' v="{$apply['serviceStartTime']}"></select> + 至 + <select class='a-ipt' id='serviceEndTime' v="{$apply['serviceEndTime']}"></select> + </td> + </tr> + </table> + </form> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/joinStep4")}' class='btn-cancel'>上一步</a> + <a href='javascript:saveStep5()' class='btn-submit' style='margin-left:10px;'>提交审核</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/js/apply.js?v={$v}'></script> +<script type="text/javascript"> +function divShow(){ +var checkboxText= new Array(); +var checkboxValue= new Array(); +var checkboxStr=document.getElementsByName("goodsCatIds"); + for(var i=0; i<checkboxStr.length; i++){ + if(checkboxStr[i].checked){ + //alert(checkboxStr[i].value+","+checkboxStr[i].nextSibling.nodeValue); + checkboxValue.push(checkboxStr[i].value); + checkboxText.push(checkboxStr[i].nextSibling.nodeValue.trim()); + } + } +var foot='393'; +if(checkboxValue.indexOf(foot)!="-1"){ + document.getElementById("license").style.cssText = "display: table-row;vertical-align: inherit;border-color: inherit;" + //document.getElementById("license").style.display="block"; + }else{ + document.getElementById("license").style.display = "none" + } +} +function initStep5(){ + WST.upload({ + pick:'#shopLicensePicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#shopLicenseMsg').empty().hide(); + $('#shopLicensePreview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb).show(); + $('#shopLicense').val(json.savePath+json.name); + $('#msg_shopLicense').hide(); + } + }, + progress:function(rate){ + $('#shopLicenseMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',$('#serviceStartTime').attr('v')); + initTime('#serviceEndTime',$('#serviceEndTime').attr('v')); +} +</script> +<script> + $(function(){ +initStep4(); +initStep5() +})</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_join_success.html b/hyhproject/home2/view/default/shop_join_success.html new file mode 100755 index 0000000..ddef609 --- /dev/null +++ b/hyhproject/home2/view/default/shop_join_success.html @@ -0,0 +1,57 @@ +{extend name="default/base" /} +{block name="title"}入驻审核 - 商家入驻 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="main"} +<link href="__STYLE__/css/shopapply.css?v={$v}" rel="stylesheet"> +<div class="wst-container"> + <div id="stepflex" class="stepflex"> + <dl class="first doing"> + <dt class="s-num">1</dt> + <dd class="s-text">签订入驻协议</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">2</dt> + <dd class="s-text">入驻人联系方式</dd> + <dd></dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">3</dt> + <dd class="s-text">公司信息</dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">4</dt> + <dd class="s-text">税务及银行信息</dd> + </dl> + <dl class="normal doing"> + <dt class="s-num">5</dt> + <dd class="s-text">店铺信息</dd> + </dl> + <dl class="last doing"> + <dt class="s-num">6</dt> + <dd class="s-text">入驻审核</dd> + </dl> + </div> + <div class='wst-clear'></div> + <div class='apply-box'> + <div class='examine-tips'> + {if $apply['applyStatus']==1} + <img src='__ROOT__/hyhproject//home/view/default/img/examine.png' style="vertical-align:middle"/>&nbsp; + 您的入驻申请已提交审核,请等待审核结果... + {/if} + {if $apply['applyStatus']==-1} + <img src='__ROOT__/hyhproject//home/view/default/img/error_1.png' style="vertical-align:middle"/> + 很抱歉,您的入驻申请因【{$apply['applyDesc']}】审核不通过。。。 + <div style='clear:both;'></div> + {/if} + {if $apply['applyStatus']==2} + <img src='__ROOT__/hyhproject//home/view/default/img/apply-ok.png' style="vertical-align:middle"/>&nbsp; + 您的入驻申请已通过,赶紧开始上架商品吧~ + {/if} + </div> + </div> + <div class='agreement-bottom'> + <a href='{:Url("home/shops/join")}' class='btn-submit' style='margin-left:10px;'>返回</a> + <div class='wst-clear'></div> + </div> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_login.html b/hyhproject/home2/view/default/shop_login.html new file mode 100755 index 0000000..0db200c --- /dev/null +++ b/hyhproject/home2/view/default/shop_login.html @@ -0,0 +1,121 @@ +{extend name="default/base_js" /} +{block name="title"}{if empty($is_icp)}商家登录{else /}管理登录{/if} - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="header"}{/block} +{block name="main"} + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <div class="wst-header wst-color"> + <div class="wst-nav"> + <ul class="headlf"> + <li class="drop-info"> + <div>欢迎来到{:WSTMSubstr(WSTConf('CONF.mallName'),0,13)}<a href="{:Url('home/users/login')}" onclick="WST.currentUrl();">&nbsp;&nbsp;请&nbsp;登录</a></div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="{:Url('home/users/regist')}" onclick="WST.currentUrl();">免费注册</a></div> + </li> + </ul> + <ul class="wst-icon"> + <li class="wst-img-icon"></li><li class="wst-remind">欢迎登陆!</li> + </ul> + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-login-banner"> + <div class="wst-icon-banner"> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <div class="img-banner" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}"> + </div> + </a> + <div class="wst-stript"></div> + <div class="wst-login-action"> + <div class="wst-left">{if empty($is_icp)}商家登录{else /}管理登录{/if}</div> + + </div> + </div> + </div> + <div class="wst-login-middle-shop"> + <div class="wst-container"> + <div class="wst-login_l_shop"> + <div class="wst-login_r"> + <form method="post" autocomplete="off"> + <span class="wst-login-u">{if empty($is_icp)}商家登录{else /}管理登录{/if}</span> + <input type='hidden' id='typ' value='2' class='ipt'/> + <div class="wst-item wst-item-box" style="margin-top: 20px;"> + <div for="loginname" class="login-img"></div> + <input id="loginName" name="loginName" class="ipt wst-login-input-1" tabindex="1" value="{$loginName}" autocomplete="off" type="text" data-rule="用户名: required;" data-msg-required="请填写用户名" data-tip="请输入用户名" placeholder="邮箱/用户名/手机号"/> + </div> + <div class="wst-item wst-item-box"> + <div for="loginname" class="password-img"></div> + <input id="loginPwd" name="loginPwd" class="ipt wst-login-input-1" tabindex="2" autocomplete="off" type="password" data-rule="密码: required;" data-msg-required="请填写密码" data-tip="请输入密码" placeholder="密码"/> + </div> + <div class="wst-item wst-item-box"> + <div for="loginname" class="yanzheng-img"></div> + <div class="wst-login-code-1"> + <input id="verifyCode" style="ime-mode:disabled" name="verifyCode" class="ipt wst-login-codein-1" tabindex="6" autocomplete="off" maxlength="6" type="text" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify"placeholder="验证码"/> + <img id='verifyImg' class="wst-login-codeim-1" src="{:url('home/users/getVerify')}" onclick="javascript:WST.getVerify('#verifyImg')" style="width:125px;height:36px;"><span id="verify"></span> + </div> + </div> + <table class="wst-table"> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:0px;"> + <input id="rememberPwd" name="rememberPwd" class="ipt wst-login-ch" checked="checked" type="checkbox"/> + <label>记住密码</label> + <label><a style="color:#b2b1b1;padding-left: 140px;float:right;" href="{:Url('home/Users/forgetPass')}">忘记密码? </a></label> + </td> + </tr> + </table> + <div class="wst-item wst-item-box" style="border: 0;" > + <div style="width: 100%;height:32px;line-height:32px;float:left;"><a class="wst-login-but" href="javascript:void(0);" onclick='javascript:login(2)'>登录</a></div> + </div> + </form> + <span class="wst-login-three" style='display:none'>您还可以使用以下方式登录:</span> + <a href="#" style='display:none'><img style='margin-right:10px' src="__STYLE__/img/btn_QQ.png"/></a> + <a href="#" style='display:none'><img src="__STYLE__/img/btn_wechat.png"/></a> + </div> + <div class="wst-clear"></div> + </div> + </div> +<div class="wst-footer"> + <div class="wst-container"> + <div class="wst-footer-hp-ck3"> + <div class="links"> + {php}$navs = WSTNavigations(1);{/php} + {volist name="$navs" id='vo'} + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + {if $i< count($navs)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + <div class="copyright"> + {php} + if(WSTConf('CONF.mallFooter')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.mallFooter')); + } + {/php} + {php} + if(WSTConf('CONF.visitStatistics')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.visitStatistics'))."<br/>"; + } + {/php} + + </div> + </div> + </div> + </div> + {/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/js/login.js?v={$v}'></script> + <script> + $(document).keypress(function(e) { + if(e.which == 13) { + login(2); + } + }); + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shop_street.html b/hyhproject/home2/view/default/shop_street.html new file mode 100755 index 0000000..fffe0af --- /dev/null +++ b/hyhproject/home2/view/default/shop_street.html @@ -0,0 +1,145 @@ +{extend name="default/base" /} +{block name="title"}店铺街 - {:WSTConf('CONF.mallName')}{__block__}{/block} +<meta name="description" content="{:WSTConf('CONF.seoMallDesc')},店铺街"> +<meta name="Keywords" content="{:WSTConf('CONF.seoMallKeywords')}"> +{block name="css"} +<link href="__STATIC__/plugins/lazyload/skin/laypage.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shopstreet.css?v={$v}" rel="stylesheet"> +{/block} +{block name="main"} +<input type='hidden' id='keyword' value='{:isset($keyword)?$keyword:""}'/> +<div class="wst-container"> + <div class="wst-route"><a href="{:url('home/index/index')}" ><img style="float:left;margin-right:10px" src="__STYLE__/img/icon_dianpujie_09.png"/>首页</a> > <a href="{:url('home/shops/shopstreet')}">店铺街</a></div> + {wst:ads code="shop-street" num="1" cache='86400'} + <div class="wst-shopstr-ads"> + <a href="{$vo['adURL']}" {if ($vo['adURL']!='')}onclick="WST.recordClick({$vo['adId']})"{/if}><img class="goodsImg" data-original="__IMGURL__/{$vo['adFile']}"/></a> + </div> + {/wst:ads} + <div class="wst-shopstr-cat"> + <div class="wst-shopstr-catt">店铺行业</div> + {volist name="goodscats" id="ca" key="k"} + <span class="{if($selectedId==$ca['catId'])}js-selected{/if}" onclick="javascript:screenCat({$ca['catId']});">{$ca['catName']}</span> + {/volist} + <div class="wst-clear"></div> + </div> + {volist name="list['Rows']" id="v1" key="k"} + <div class="wst-shopstr-shop"> + <div class="wst-shopstr-shopl"><a target='_blank' href="{:url('home/shops/home',array('shopId'=>$v1['shopId']))}"><img class="shopsImg" data-original="__IMGURL__/{$v1['shopImg']}" title="{$v1['shopName']}" alt="{$v1['shopName']}"/></a></div> + <div class="wst-shopstr-shopi"> + <div class="wst-shopstr-name"> + <a class="name" target='_blank' href="{:url('home/shops/home',array('shopId'=>$v1['shopId']))}">{:WSTMSubstr($v1['shopName'],0,12)}</a> + {if ((int)$v1['favoriteId']>0)} + <a class="favorite j-fav" href='javascript:void(0);' onclick='WST.cancelFavorite(this,1,{$v1['shopId']},{$v1['favoriteId']})'>已关注</a> + {else} + <a class="favorite j-fav2" href='javascript:void(0);' onclick='WST.addFavorite(this,1,{$v1['shopId']},0)'>关注店铺</a> + {/if} + <div class="wst-clear"></div> + </div> + <div class="wst-shopstr-pr"> + <span class="wst-lfloat" style="margin-left:3px;">卖家:<a class="company" target='_blank' href="{:url('home/shops/home',array('shopId'=>$v1['shopId']))}">{$v1['loginName']}</a></span> + <span class="wst-rfloat" style="margin-right:50px;">{$v1['areas']['areaName1']}&nbsp;&nbsp;{$v1['areas']['areaName2']}</span> + </div> + <div class="wst-shopstr-pr"> + <span class="wst-lfloat" style="margin-left:3px;">电话:{$v1['shopTel']}</span> + </div> + <div class="wst-shopstr-pr"> + {if condition="$v1['shopQQ'] neq ''"} + <span class="wst-lfloat" style="margin-left:3px;"> + <a href="tencent://message/?uin={$v1['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" src="http://wpa.qq.com/pa?p=1:{$v1['shopQQ']}:7" alt="QQ交谈" width="60" height="25" /> + </a> + </span> + {/if} + {if condition="$v1['shopWangWang'] neq ''"} + + <span class="wst-lfloat" style="margin-left:3px;"> + {if($v1['shopWangWangType']==0)} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$v1['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img style='padding-top:2px;' border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid={$v1['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" width="65" height="23"/> + </a> + {/if} + {if($v1['shopWangWangType']==1)} + <a href="http://amos.alicdn.com/msg.aw?v=2&uid={$v1['shopWangWang']}&site=cnalichn&s=10&charset=utf-8" target="_blank" ><img border="0" src="http://amos.alicdn.com/online.aw?v=2&uid={$v1['shopWangWang']}&site=cnalichn&s=10&charset=UTF-8" alt="点击这里给我发消息" width="65" height="23" /></a> + {/if} + </span> + {/if} + <span class="wst-lfloat j-score" style="margin-left:3px;position: relative;"> + <img class="wst-lfloat" style="margin:5px 0px 0px 45px;width:16px;cursor:pointer;" src="__STYLE__/img/icon_fenlei.png"/> + <div class="wst-shopstr-score j-scores hide"> + <p class="title" style="margin-top:18px;">店铺动态评分</p> + <p class="">商品评价:<span class="title">{$v1['goodsScore']}</span></p> + <p class="">时效评价:<span class="title">{$v1['timeScore']}</span></p> + <p class="">服务评价:<span class="title">{$v1['serviceScore']}</span></p> + </div> + </span> + {volist name="v1['accreds']" id="v2"} + <img class="wst-lfloat" style="margin:5px 0px 0px 6px;width:15px;" src="__IMGURL__/{$v2['accredImg']}" title="{$v2['accredName']}" alt="{$v2['accredName']}"/> + {/volist} + </div> + <div class="wst-shopstr-pr"> + <span class="wst-lfloat" style="margin-left:3px;">主营:{:WSTMSubstr($v1['catshops'],0,12)}</span> + </div> + </div> + <div class="wst-shopstr-shopr"> + <div class="wst-shopstr-more"><a href="{:url('home/shops/home',array('shopId'=>$v1['shopId']))}" class="wst-rfloat">查看更多 ></a></div> + <div class="wst-shopstr-more"><span class="wst-lfloat">&nbsp;店长推荐</span></div> + <div class="wst-shopstr-good wst-lfloat"> + <div class="als-container" id="{if ($v1['goodsTotal']>6)}js-goods{$k}{/if}"> + {if ($v1['goodsTotal']>6)}<span class="als-prev"><img src="__STYLE__/img/icon_left.png" alt="prev" title="previous" /></span>{/if} + <div class="als-viewport"> + <ul class="als-wrapper"> + {volist name="v1['goods']" id="v3"} + <li class="als-item wst-shopstr-goods"> + <div class="wst-shopstr-goodimg"><a href="{:url('home/goods/detail',array('id'=>$v3['goodsId']))}" target="_blank"><img class="goodsImg" data-original="__IMGURL__/{$v3['goodsImg']}" title="{$v3['goodsName']}"/></a></div> + <span>¥{$v3['shopPrice']}</span> + </li> + {/volist} + </ul> + </div> + {if ($v1['goodsTotal']>6)}<span class="als-next"><img src="__STYLE__/img/icon_right.png" alt="next" title="next" /></span>{/if} + </div> + </div> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + <div class="shopstrPaging"> + <div id="shopstrPaging"></div> + </div> +</div> +{include file="default/right_cart"/} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/jquery.als.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/js/shopstreet.js?v={$v}'></script> +<script> +$(function(){ + if({$list['TotalPage']}>1){ + laypage({ + cont: 'shopstrPaging', + pages: {$list['TotalPage']}, //总页数 + curr: {$list['CurrentPage']}, + skip: true, //是否开启跳页 + skin: '#fd6148', + groups: 3, //连续显示分页数 + prev: '<<', + next: '>>', + jump: function(e, first){ //触发分页后的回调 + if(!first){ //一定要加此判断,否则初始时会无限刷新 + var nuewurl = WST.splitURL("page"); + var ulist = nuewurl.split("?"); + if(ulist.length>1){ + location.href = nuewurl+'&page='+e.curr; + }else{ + location.href = '?page='+e.curr; + } + + } + } + }); + } +}); +</script> +{/block} +{block name="footer"}{__block__} +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/base.html b/hyhproject/home2/view/default/shops/base.html new file mode 100755 index 0000000..277c36f --- /dev/null +++ b/hyhproject/home2/view/default/shops/base.html @@ -0,0 +1,115 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/shop.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> + +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> +<script type='text/javascript' src='__ROOT__/static/plugins/lazyload/jquery.lazyload.min.js?v={$v}'></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}", "SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","PHONE_VERFY":"{:WSTConf('CONF.phoneVerfy')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","MESSAGE_BOX":"{:WSTShopMessageBox()}","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} + {:WSTLoginTarget(1)} +$(function() { + WST.initShopCenter(); +}); +</script> +</head> +<body> + +{block name="top"} +{include file="default/top" /} +{/block} + +{block name="header"} + +<div class='wst-lite-bac'> +<div class='wst-lite-container'> + <div class='wst-logo'><a href='{$Request.root.true}'><img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="80" width='160'></a></div> + <div class="wst-lite-tit"><span>卖家中心</span><a class="wst-lite-in" href='{$Request.root.true}'>返回商城首页</a></div> + <div class="wst-lite-sea"> + <div class='search'> + <input type="hidden" id="search-type" value="{:isset($keytype)?1:0}"/> + + <ul class="j-search-box"> + <li class="j-search-type"> + 搜<span>{if isset($keytype)}店铺{else}商品{/if}</span>&nbsp;<i class="arrow"> </i> + </li> + <li class="j-type-list"> + {if isset($keytype)} + <div data="0">商品</div> + {else} + <div data="1">店铺</div> + {/if} + </li> + </ul> + + <input type="text" id='search-ipt' class='search-ipt' value='{:isset($keyword)?$keyword:""}'/> + <div id='search-btn' class="search-btn" onclick='javascript:WST.search(this.value)'></div> + </div> + </div> + <div class="wst-clear"></div> +</div> +<div class="wst-clear"></div> +</div> +{/block} +<div class="wst-wrap"> + <div class='wst-header'> + <div class="wst-shop-nav"> + <div class="wst-nav-box"> + {php}$homeMenus = WSTHomeMenus(1);{/php} + {volist name="$homeMenus['menus']" id="vo"} + <a href="__ROOT__/{$vo['menuUrl']}?homeMenuId={$vo['menuId']}"><li class="liselect wst-lfloat {if($vo['menuId'] == $homeMenus['menuId1'])}wst-nav-boxa{/if}">{$vo['menuName']}</li></a> + {/volist} + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-nav'></div> + <div class='wst-main'> + <div class='wst-menu'> + {if isset($homeMenus['menus'][$homeMenus['menuId1']]['list']) } + {volist name="$homeMenus['menus'][$homeMenus['menuId1']]['list']" id="menus"} + <span class='wst-menu-title'>{$menus['menuName']}<img src="__STYLE__/img/user_icon_sider_zhankai.png"></span> + <ul> + {if isset($menus['list']) } + {volist name="menus['list']" id="menu" key='k'} + <li class="{if($homeMenus['menuId3']==$menu['menuId'])}wst-menua{/if} wst-menuas" onclick="getMenus('{$menu['menuId']}','{$menu['menuUrl']}')"> + {$menu['menuName']} + <span id="mId_{$menu['menuId']}"></span> + </li> + {/volist} + {/if} + </ul> + {/volist} + {/if} + + + + </div> + <div class='wst-content'> + {block name="content"}<div class="result">卖家中心</div>{/block} + </div> + </div> + <div style='clear:both;'></div> + <br/> + </div> +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}{/block} +<script> +function getMenus(menuId,menuUrl){ + $.post(WST.U('home/index/getMenuSession'), {menuId:menuId}, function(data){ + location.href=WST.U(menuUrl); + }); +} +</script> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/cashdraws/box_draw.html b/hyhproject/home2/view/default/shops/cashdraws/box_draw.html new file mode 100755 index 0000000..6a391c0 --- /dev/null +++ b/hyhproject/home2/view/default/shops/cashdraws/box_draw.html @@ -0,0 +1,35 @@ + <form id='drawForm' autocomplete='off' > + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <table width='100%' style='margin-top:10px;' class='wst-form' style='dislay:none'> + <tr> + <th width='120' align='right'>提现账号:</th> + <td style='line-height:25px;'> + 【{$object['bankName']}】{$object['bankNo']} + </td> + </tr> + <tr> + <th width='120' align='right'>账号持有人:</th> + <td>{$object['bankUserName']}</td> + </tr> + <tr> + <th align='right'>提现金额<font color='red'>*</font>:</th> + <td> + <input type='text' id='money' class='j-ipt' style='width:250px' data-rule="提现金额: required;" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2)" onkeyup="javascript:WST.isChinese(this,1)" placeholder="可提现金额:¥{$shop['shopMoney']-$shop['rechargeMoney']}"/> + </td> + </tr> + <tr height='40'> + <th align='right'>支付密码<font color='red'>*</font>:</th> + <td> + <input type="password" style="display:none"> + <input type='password' id='payPwd' class='j-ipt' style='width:250px' data-rule="支付密码: required;"/> + </td> + </tr> + <tr> + <td colspan='2' style='text-align: center;padding-top:5px;'> + <a class='s-btn' onclick="drawMoney()">保存</a> + <a class='s-btn2' style='margin-left:10px;' onclick='layerclose()'>取消</a> + </td> + </tr> + </table> + </form> + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> diff --git a/hyhproject/home2/view/default/shops/cashdraws/cashdraws.js b/hyhproject/home2/view/default/shops/cashdraws/cashdraws.js new file mode 100755 index 0000000..0e6c2fe --- /dev/null +++ b/hyhproject/home2/view/default/shops/cashdraws/cashdraws.js @@ -0,0 +1,113 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0);break; + case 1:pageConfigQuery(0);break; + } + }}) +}); +var isSetPayPwd = 1; +function getShopMoney(){ + $.post(WST.U('home/shops/getShopMoney'),{},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var shopMoney = json.data.shopMoney; + var rechargeMoney = json.data.rechargeMoney; + $('#shopMoney').html('¥'+shopMoney); + $('#lockMoney').html('¥'+json.data.lockMoney); + rechargeMoney = parseFloat(shopMoney - rechargeMoney) + $('#userCashMoney').html('¥'+rechargeMoney.toFixed(2)); + if(json.data.isDraw==1){ + $('#drawBtn').show(); + }else{ + $('#drawBtn').hide(); + } + isSetPayPwd = json.data.isSetPayPwd; + } + }); +} +function pageQuery(p){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + $.post(WST.U('home/cashdraws/pageQueryByShop'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + pageQuery(json.TotalPage); + return; + } + var gettpl = document.getElementById('draw-list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#draw-page-list').html(html); + }); + laypage({ + cont: 'draw-pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr); + } + } + }); + } + }); +} +var w; +function toDrawMoney(){ + if(isSetPayPwd==0){ + WST.msg('您尚未设置支付密码,请先设置支付密码',{icon:2,time:1000},function(){ + location.href = WST.U('home/users/security'); + }); + return; + } + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + $.post(WST.U('home/cashdraws/toEditByShop'),{},function(data,textStatus){ + layer.close(tips); + w = WST.open({ + type: 1, + title:"申请提现", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['550px', '250px'], + offset: '100px' + }); + }); +} +function drawMoney(){ + $('#drawForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.payPwd = rsa.encrypt(params.payPwd); + } + var tips = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/cashdraws/drawMoneyByShop'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + pageQuery(WSTCurrPage); + getShopMoney(); + layer.close(w); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function layerclose(){ + layer.close(w); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/cashdraws/list.html b/hyhproject/home2/view/default/shops/cashdraws/list.html new file mode 100755 index 0000000..36c1408 --- /dev/null +++ b/hyhproject/home2/view/default/shops/cashdraws/list.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}提现管理-卖家中心{__block__}{/block} +{block name='css'} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='money-head'> + <div class='shop-logo'><img height='100' width='100' src='__IMGURL__/{:session("WST_USER.shopImg")}'></div> + <div class='shop-info'> + <div class='shopName'>{:session('WST_USER.shopName')}</div> + <div class='shopMoney'> + <div class="usermoney"> + 可用资金:<font color='red' id='shopMoney'>¥0</font> + </div> + <div class="cashbox"> + <span style='margin-left:20px;'><a class="cashbtn" id='drawBtn' href="javascript:toDrawMoney();" >申请提现</a></span> + <span class='draw-tips'>(至少¥{:WSTConf('CONF.drawCashShopLimit')}方可提现)</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="wst-clear"></div> + <div class="money-rows"> + <div class="lockbox"> + 冻结资金:<font color='red' id='lockMoney'>¥0</font> + </div> + <div class="cashbox"> + <span class="cashmoney-box">可提现金额:<font color='red' id='userCashMoney'>¥0</font></span> + </div> + <div class="wst-clear"></div> + </div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>提现记录</li> + </ul> + <div class='wst-tab-content'> + <div class='wst-tab-item'> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='80'>提现单号</th> + <th width='100'>提现银行</th> + <th width='130'>开户地区</th> + <th width='130'>银行卡号</th> + <th width='100'>持卡人</th> + <th width='60'>提现金额</th> + <th width='250'>提现状态</th> + </tr> + </thead> + <script id="draw-list" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].cashNo}}</td> + <td>{{d[i].accTargetName}}</td> + <td>{{ d[i].accAreaName }}</td> + <td>{{ d[i].accNo }}</td> + <td>{{ d[i].accUser }}</td> + <td>¥{{ d[i].money }}</td> + <td {{#if(d[i].cashSatus==-1){}}style='line-height:25px;'{{#}}}> + {{#if(d[i].cashSatus==1){}}提现成功 + {{#}else if(d[i].cashSatus==-1){}}提现失败 + <br/>【原因】{{d[i].cashRemarks}} + {{#}else{}}待处理{{#}}}</td> + </tr> + {{# } }} + </script> + <tbody id="draw-page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="draw-pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/cashdraws/cashdraws.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ + getShopMoney(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/freights/freights.js b/hyhproject/home2/view/default/shops/freights/freights.js new file mode 100755 index 0000000..f85553e --- /dev/null +++ b/hyhproject/home2/view/default/shops/freights/freights.js @@ -0,0 +1,53 @@ +$(function(){ + areasByList(); +}); +//运费列表 +function areasByList(){ + $.post(WST.U('home/shopfreights/listProvince'),'',function(data){ + var json = WST.toJson(data); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#list-info').html(html); + }); + }); +} + +function treeOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/seller_icon_zk.png">'); + $('.text_'+id).show(); + $('.tree_'+id).show(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/seller_icon_sq.png">'); + $('.text_'+id).hide(); + $('.tree_'+id).hide(); + } +} + +function freightOnblur(obj,id,v){ + $postage = $(obj).val(); + if(v == 0){ + $('.possort').val($postage); + }else{ + $('.price_'+id).val($postage); + } +} + +function freightSubmit(){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopfreights/edit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + setTimeout(function(){ + //location.href=WST.U('home/shopfreights/index'); + },2000); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/freights/list.html b/hyhproject/home2/view/default/shops/freights/list.html new file mode 100755 index 0000000..ebb5798 --- /dev/null +++ b/hyhproject/home2/view/default/shops/freights/list.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}运费设置 - 卖家中心{__block__}{/block} +{block name="css"}{/block} + +{block name="content"} + +<div class="wst-body"> +<div class="wst-shop-head"><span>运费设置</span></div> +<div class="wst-clear"></div> + <form autocomplete="off"> + <table id="cat_list_tab" class='wst-list wst-form'> + <thead> + <tr class="wst-colour"> + <th class="wst-fre-th">名称</th> + <th class="wst-fre-th" width="200">运费</th> + </tr> + </thead> + <tbody> + <tr class="wst-fre-hov"> + <td class="wst-fre-td"> + <span style='width:400px;height:22px;'>默认运费</span> + </td> + <td><input type='text' style='width:80px;' value="{$shFreight['freight']}" onblur="javascript:freightOnblur(this,'',0)" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + </tr> + </tbody> + <tbody id="list-info"></tbody> +</table> +<div class='wst-tbar-group' style='height:76px;text-align:center;'> + <a class='s-btn' style='margin-top:30px;width:100px;height: 30px;' type="button" onclick='javascript:freightSubmit()'>保&nbsp;存</a> +</div> +</form> +</div> +<script id="list" type="text/html"> +{{# for(var i = 0; i < d.length; i++){ }} + <tr isLoad='1' class="wst-fre-hov"> + <td class="wst-fre-td"> + <span class='wst-tree-open active' onclick='javascript:treeOpen(this,"{{ d[i].areaId }}")'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_sq.png"></span> + <span style='width:400px;height:22px;'>{{ d[i].areaName }}</span> + </td> + <td><input class='possort text_{{ d[i].areaId }}' type='text' style='width:80px;display:none;' value="" onblur='javascript:freightOnblur(this,"{{ d[i].areaId }}",2)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + </tr> +{{# for(var j = 0; j < d[i].listProvince.length; j++){ }} + <tr class="tree_{{ d[i].listProvince[j].parentId }} hide wst-fre-hov"> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <span style='width:400px;height:22px;'>{{ d[i].listProvince[j].areaName }}</span> + </td> +{{#if(typeof(d[i].listProvince[j].freight)=='object'){}} + <td><input class='price_{{ d[i].listProvince[j].parentId }} possort ipt' id="{{ d[i].listProvince[j].areaId }}" type='text' style='width:80px;' value="{$shFreight['freight']}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> +{{# }else{ }} + <td><input class='price_{{ d[i].listProvince[j].parentId }} possort ipt' id="{{ d[i].listProvince[j].areaId }}" type='text' style='width:80px;' value="{{d[i].listProvince[j].freight}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> +{{# } }} + </tr> +{{# } }} +{{# } }} +</script> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}<script type='text/javascript' src='__STYLE__/shops/freights/freights.js?v={$v}'></script>{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/edit.html b/hyhproject/home2/view/default/shops/goods/edit.html new file mode 100755 index 0000000..d36aeaa --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/edit.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}<?=($object['goodsId']>0)?"编辑":"新增";?>商品-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<style> +label{margin-right:10px;} +#specsAttrBox .webuploader-container{width:80px;height:25px;line-height:25px;overflow:hidden;} +</style> +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>商品信息</li> + <li>规格属性</li> + <li>商品相册</li> + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;border:0px;'> + <form id='editform' autocomplete='off'> + <div class="wst-tab-item" style="position: relative;"> + {include file='default/shops/goods/edit0'/} + </div> + <div class="wst-tab-item" style="position: relative;display:none"> + {include file='default/shops/goods/edit1'/} + </div> + <div class="wst-tab-item" style="position: relative;display:none"> + {include file='default/shops/goods/edit2'/} + </div> + </form> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script src="__STATIC__/plugins/kindeditor/kindeditor.js?v={$v}" type="text/javascript" ></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +var initBatchUpload = false,editor1 = null,specNum = 0,src='{$src}'; +{php}unset($object['goodsDesc']);{/php} +var OBJ = <?=json_encode($object)?>; +$(function(){initEdit()}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/edit0.html b/hyhproject/home2/view/default/shops/goods/edit0.html new file mode 100755 index 0000000..28d6408 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/edit0.html @@ -0,0 +1,200 @@ +<style> +.webuploader-pick {background: #e45050 none repeat scroll 0 0;} +</style> +<input type='hidden' id='goodsId' class='j-ipt' value='{$object["goodsId"]}' /> +<table class='wst-form'> + <tr> + <th width='150'>商品名称<font color='red'>*</font>:</th> + <td width='300'> + <input type='text' class='j-ipt' id='goodsName' value='{$object["goodsName"]}' maxLength='100' data-rule='商品名称:required;'/> + </td> + <td rowspan='6'> + <div id='goodsImgBox'> + <img src='__IMGURL__/{$object["goodsImg"]}' id='preview' width='150' height='150'> + </div> + <div id='goodsImgPicker'>请上传商品图片</div><span id='uploadMsg'></span> + <input type='hidden' id='goodsImg' class='j-ipt' data-target='#msg_goodsImg' value='{if $object["goodsId"]>0}{$object["goodsImg"]}{/if}' data-rule="商品图片: required;"/> + <span class='msg-box' id='msg_goodsImg'></span> + </td> + </tr> + <tr> + <th>商品类型<font color='red'>*</font>:</th> + <td> + <select id='goodsType' class='j-ipt' onchange="changeGoodsType(this.value)" {if $object["goodsId"]>0}disabled{/if}> + <option value='0' {if($object["goodsType"]==0)}selected{/if}>实物商品</option> + {if($object["goodsType"]==1)} <option value='1' {if($object["goodsType"]==1)}selected{/if}>虚拟商品</option>{/if} + </select> + </td> + </tr> + <tr> + <th>商品编号<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='goodsSn' value='{$object["goodsSn"]}' maxLength='20' data-rule='商品编号:required;'/></td> + </tr> + <tr> + <th width='150'>商品货号<font color='red'>*</font>:</th> + <td width='300'> + <input type='text' class='j-ipt' id='productNo' value='{$object["productNo"]}' maxLength='20' data-rule='商品货号:required;'/> + </td> + </tr> + {if($object["alone"]==1)} + <tr> + <th width='150'>商品成本价:</th> + <td width='300'> + <input type='text' class='j-ipt' id='basicsMoney' value='{$object["basicsMoney"]}' maxLength='20' data-rule=''/> + </td> + </tr> + {/if} + <tr> + <th>市场价格<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='marketPrice' value='{$object["marketPrice"]}' maxLength='10' data-rule='市场价格:required;price' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th><font color='red'>小提示</font>:</th> + <td>店铺价格包含惠宝抵现20%;<br />比如店铺价格100元,会员可抵20元,商家实收80元</td> + </tr> + <tr> + <th>店铺价格<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='shopPrice' value='{$object["shopPrice"]}' maxLength='10' data-rule='店铺价格:required;price' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <!-- <tr> + <th>ect支付<font color='red'>*</font>:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='ectPay' id="ectPay-1" class='j-ipt wst-radio' value='1' {if $object['ectPay']==1}checked{/if}/><label for="ectPay-1" class="mt-1"></label>启用</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='ectPay' id="ectPay-0" class='j-ipt wst-radio' value='0' {if $object['ectPay']==0}checked{/if}/><label for="ectPay-0" class="mt-1"></label>禁用</label> + </div> + </td> + </tr> --> + {if $object["ectPayRatio"] < 1} + <tr> + <th><font color='red'>小提示</font>:</th> + <td>ECT价格为店铺价格的{$object["ectPayRatio"]*10}折;<br />比如店铺价格100元,木吉抵扣20元,付款80元,ECT按{$object["ectPayRatio"]*80}元对应ECT数量结算</td> + </tr> + <tr> + <th>ECT价格<font color='red'>*</font>:</th> + <td><input type='text' id='ectPrice' value='{$object["shopPrice"]*$object["ectPayRatio"]}' maxLength='10' data-rule-price="[/^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/, '价格必须大于0']" onblur="javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)" disabled="disabled" /></td> + </tr> + {/if} + + + <tr id='goodsStockTr' {if($object["goodsType"]==1)}style='display:none'{/if}> + <th>商品库存<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='goodsStock' value='{$object["goodsStock"]}' maxLength='10' data-rule='商品库存:required;integer[+0]' onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>预警库存<font color='red'>*</font>:</th> + <td colspan='2'><input type='text' class='j-ipt' id='warnStock' value='{$object["warnStock"]}' maxLength='10' data-rule='预警库存:required;integer[+0]' onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"/></td> + </tr> + <tr> + <th>商品单位<font color='red'>*</font>:</th> + <td colspan='2'><input type='text' class='j-ipt' id='goodsUnit' value='{$object["goodsUnit"]}' maxLength='10' data-rule='商品单位:required;'/></td> + </tr> + <tr> + <th>SEO关键字:</th> + <td colspan='2'><input type='text' class='j-ipt' id='goodsSeoKeywords' maxLength='100' value='{$object["goodsSeoKeywords"]}' style='width:70%'/></td> + </tr> + <tr> + <th>商品促销信息:</th> + <td colspan='2'><textarea class='j-ipt' id='goodsTips' maxLength='100' style='width:500px;height:50px'>{$object["goodsTips"]}</textarea></td> + </tr> + {:hook('homeDocumentShopEditGoods',['goodsId'=>$object["goodsId"]])} + <tr> + <th>商品状态<font color='red'>*</font>:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='isSale' id="isSale-1" class='j-ipt wst-radio' value='1' {if $object['isSale']==1}checked{/if}/><label for="isSale-1" class="mt-1"></label>上架</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='isSale' id="isSale-0" class='j-ipt wst-radio' value='0' {if $object['isSale']==0}checked{/if}/><label for="isSale-0" class="mt-1"></label>下架</label> + </div> + </td> + </tr> + <tr> + <th>商品属性:</th> + <td colspan='2'> + <div class="checkbox-box"> + <label> + <input id="isRecom" name='isRecom' class="j-ipt wst-checkbox" {if $object['isRecom']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isRecom"></label>推荐 + </label> + <label> + <input id="isBest" name="isBest" class="j-ipt wst-checkbox" {if $object['isBest']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isBest"></label>精品 + </label> + <label> + <input id="isNew" name="isNew" class="j-ipt wst-checkbox" {if $object['isNew']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isNew"></label>新品 + </label> + <label> + <input id="isHot" name="isHot" class="j-ipt wst-checkbox" {if $object['isHot']==1}checked{/if} value="1" type="checkbox"/><label class="mt-1" for="isHot"></label>热销 + </label> + </div> + </td> + </tr> + <tr> + <th>是否包邮:</th> + <td colspan='2'> + <div class="radio-box"> + <label><input type='radio' name='isFreeShipping' id="isFreeShipping-1" class='j-ipt wst-radio' value='1' {if $object['isFreeShipping']==1}checked{/if}/><label for="isFreeShipping-1" class="mt-1"></label>包邮</label>&nbsp;&nbsp;&nbsp;&nbsp; + <label><input type='radio' name='isFreeShipping' id="isFreeShipping-0" class='j-ipt wst-radio' value='0' {if $object['isFreeShipping']==0}checked{/if}/><label for="isFreeShipping-0" class="mt-1"></label>不包邮</label> + </div> + </td> + </tr> + + <tr> + <th>商城分类<font color='red'>*</font>:</th> + <td colspan='2'> + <select id="cat_0" class='ipt j-goodsCats' level="0" onchange="WST.ITGoodsCats({id:'cat_0',val:this.value,isRequire:true,className:'j-goodsCats',afterFunc:'lastGoodsCatCallback'});getBrands('brandId',this.value)"> + <option value="">-请选择-</option> + {volist name=":WSTGoodsCats(0)" id="vo"} + <option value="{$vo['catId']}">{$vo['catName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>本店分类:</th> + <td colspan='2'> + <select id="shopCatId1" class='j-ipt' onchange="getShopsCats('shopCatId2',this.value,'');"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" {if $object['shopCatId1']==$vo['catId']}selected{/if}> + <!-- {$vo['catName']} --> + <!--分类后面添加特产省份mark 20180518 by zl--> + {if condition = "$vo['provName'] neq ''"} + {$vo['catName'].'('.$vo['provName'].')'} + {else/} + {$vo['catName']} + {/if} + <!--end--> + </option> + {/volist} + </select> + <select id='shopCatId2' class='j-ipt'> + <option value=''>请选择</option> + </select> + </td> + </tr> + <tr> + <th>品牌:</th> + <td colspan='2'> + <select id="brandId" class='j-ipt'> + <option value="0">-请选择-</option> + </select> + </td> + </tr> + <tr> + <th>商品描述<font color='red'>*</font>:</th> + <td colspan='2'> + <textarea rows="2" cols="60" id='goodsDesc' class='j-ipt' name='goodsDesc' data-rule='商品描述:required;'>{$object['goodsDesc']}</textarea> + </td> + </tr> + <tr> + <td colspan='3' align='center' style='text-align:center;padding-top:10px;'> + <a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> + <a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> + </td> + </tr> +</table> +<script type="text/javascript"> + $("#shopPrice").change(function(){ + // alert($(this).val()); + var txtChange = $(this).val(); + $("#ectPrice").val(txtChange*{$object['ectPayRatio']}); + }); +</script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/edit1.html b/hyhproject/home2/view/default/shops/goods/edit1.html new file mode 100755 index 0000000..0e8aeb8 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/edit1.html @@ -0,0 +1,9 @@ +<div id='specsAttrBox'></div> +<div id='specTips' style='display:none'> +<div class='wst-tips-box' style='margin-left:0px;'>1.若改动商品规格时,销售规则表将会重新绘制,填写销售规格表前前选择好商品规格 +</br>2.如果不批发,起批数和批发价保留为空即可</div> +</div> +<div id='specBtns' style='margin:0px auto;text-align:center;display:none'> +<a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> +<a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> +</div> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/edit2.html b/hyhproject/home2/view/default/shops/goods/edit2.html new file mode 100755 index 0000000..62ac41a --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/edit2.html @@ -0,0 +1,45 @@ +<style> +.wst-batchupload .placeholder .webuploader-pick { + background: #e45050 none repeat scroll 0 0; +} +.wst-batchupload .statusBar .btns .uploadBtn { + background: #e45050 none repeat scroll 0 0; +} +.wst-batchupload .statusBar .btns .uploadBtn:hover{ + background: #e42525; +} +</style> +<div id="batchUpload" class="wst-batchupload"> + <div class="queueList filled"> + <div id="dndArea" class="placeholder {if !empty($object['gallery'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选50张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['gallery']" id="vo"} + <li class="state-complete" style="border: 1px solid rgb(59, 114, 165);"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo}"> + </p> + <input type="hidden" v="{$vo}" iv="{$vo}" class="j-gallery-img"> + <span class="btn-del">删除</span> + </li> + {/volist} + </ul> + </div> + <div class="statusBar" {if empty($object['gallery'])}style="display: none;"{/if}> + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> +</div> +<div style='margin:0px auto;text-align:center;border-top:1px solid #cccccc;padding-top:10px;'> +<a class="s-btn" onclick='javascript:save()'>保&nbsp;存</a> +<a class="s-btn2" onclick="javascript:resetForm()">重&nbsp;置</a> +</div> diff --git a/hyhproject/home2/view/default/shops/goods/goods.js b/hyhproject/home2/view/default/shops/goods/goods.js new file mode 100755 index 0000000..7c340ed --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/goods.js @@ -0,0 +1,1136 @@ +/**删除批量上传的图片**/ +function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除商品图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); +} +function lastGoodsCatCallback(opts){ + if(opts.isLast && opts.val){ + getSpecAttrs(opts.val); + }else{ + $('#specBtns').hide(); + $('#specsAttrBox').empty(); + } +} +/**初始化**/ +function initEdit(){ + $('#tab').TabPanel({tab:0,callback:function(no){ + if(no==1){ + $('.j-specImg').children().each(function(){ + if(!$(this).hasClass('webuploader-pick'))$(this).css({width:'80px',height:'25px'}); + }); + } + if(!initBatchUpload && no==2){ + initBatchUpload = true; + var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'goods',isWatermark:1,isThumb:1},uploadSuccess:function(file,response){ + var json = WST.toJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" class="j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + //$li.append('<span class="btn-setDefault">默认</span>' ); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid rgb(59, 114, 165)'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); + } + $('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + }}); + WST.upload({ + pick:'#goodsImgPicker', + /**不让上传图片压缩,否则图片不清晰,make cheng 20180703**/ + formData: {dir:'goods',isWatermark:1,isThumb:0}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + console.log(json); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + // $('#preview').attr('src',WST.conf.ROOT+"/"+json.savePath+json.thumb); + // 修改为oss 地址 mark 20180612 by zll + $('#preview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb); + $('#goodsImg').val(json.savePath+json.name); + $('#msg_goodsImg').hide(); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + KindEditor.ready(function(K) { + editor1 = K.create('textarea[name="goodsDesc"]', { + height:'350px', + width:'800px', + uploadJson : WST.conf.ROOT+'/home/goods/editorUpload', + allowFileManager : false, + allowImageUpload : true, + allowMediaUpload : false, + items:[ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|','image','multiimage','media','table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + afterBlur: function(){ this.sync(); } + }); + }); + if(OBJ.goodsId>0){ + var goodsCatIds = OBJ.goodsCatIdPath.split('_'); + getBrands('brandId',goodsCatIds[0],OBJ.brandId); + if(goodsCatIds.length>1){ + var objId = goodsCatIds[0]; + $('#cat_0').val(objId); + var opts = {id:'cat_0',val:goodsCatIds[0],childIds:goodsCatIds,className:'j-goodsCats',afterFunc:'lastGoodsCatCallback'} + WST.ITSetGoodsCats(opts); + } + getShopsCats('shopCatId2',OBJ.shopCatId1,OBJ.shopCatId2); + } + +} +/**获取本店分类**/ +function getShopsCats(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +/**获取品牌**/ +function getBrands(objId,catId,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/brands/listQuery'),{catId:catId},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.brandId+"' "+((objVal==cat.brandId)?"selected":"")+">"+cat.brandName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +function toEdit(id,src){ + location.href = WST.U('home/goods/edit','id='+id+'&src='+src); +} +/**保存商品数据**/ +function save(){ + var va = $("input[name='defaultSpec']:checked").val(); + if(va){ + $("#marketPrice").val($("#marketPrice_"+va).val()); + $("#shopPrice").val( $("#specPrice_"+va).val()); + } + $('#editform').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + params.goodsCatId = WST.ITGetGoodsCatVal('j-goodsCats'); + params.specNum = specNum; + var specsName,specImg; + $('.j-speccat').each(function(){ + specsName = 'specName_'+$(this).attr('cat')+'_'+$(this).attr('num'); + specImg = 'specImg_'+$(this).attr('cat')+'_'+$(this).attr('num'); + if($(this)[0].checked){ + params[specsName] = $.trim($('#'+specsName).val()); + params[specImg] = $.trim($('#'+specImg).attr('v')); + } + }); + var gallery = []; + $('.j-gallery-img').each(function(){ + gallery.push($(this).attr('v')); + }); + params.gallery = gallery.join(','); + var specsIds = []; + var specidsmap = []; + $('.j-ws').each(function(){ + specsIds.push($(this).attr('v')); + specidsmap.push(WST.blank($(this).attr('sid'))+":"+$(this).attr('v')); + }); + var specmap = []; + for(var key in id2SepcNumConverter){ + specmap.push(key+":"+id2SepcNumConverter[key]); + } + params.specsIds = specsIds.join(','); + params.specidsmap = specidsmap.join(','); + params.specmap = specmap.join(','); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/goods/'+((params.goodsId==0)?"toAdd":"toEdit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + if(params.goodsType==1){ + location.href=WST.U('home/goodsvirtuals/stock','id='+json.data.id); + }else{ + location.href=WST.U('home/goods/'+src); + } + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +var id2SepcNumConverter = {}; +/**添加普通规格值**/ +function addSpec(opts){ + var html = []; + html.push('<div class="spec-item">', + '<input type="checkbox" class="j-speccat j-speccat_'+opts.catId+' j-spec_'+opts.catId+'_'+specNum+'" cat="'+opts.catId+'" num="'+specNum+'" onclick="javascript:addSpecSaleCol()" '+opts.checked+'/>', + '<input type="text" class="spec-ipt" id="specName_'+opts.catId+'_'+specNum+'" maxLength="50" value="'+WST.blank(opts.val)+'" onblur="batchChangeTxt(this.value,'+opts.catId+','+specNum+')"/>', + '<span class="item-del" onclick="delSpec(this,'+opts.catId+','+specNum+')"></span>', + '</div>'); + $(html.join('')).insertBefore('#specAddBtn_'+opts.catId); + if(opts.itemId){ + id2SepcNumConverter[opts.itemId] = opts.catId+'_'+specNum; + } + + specNum++; +} +/**删除普通规格值**/ +function delSpec(obj,catId,num){ + if($('.j-spec_'+catId+'_'+num)[0].checked){ + $('.j-spec_'+catId+'_'+num)[0].checked = false; + addSpecSaleCol(); + } + $(obj).parent().remove(); +} +/**添加带图片的规格值**/ +function addSpecImg(opts){ + var html = []; + html.push('<tr>', + '<td>', + '<input type="checkbox" class="j-speccat j-speccat_'+opts.catId+' j-spec_'+opts.catId+'_'+specNum+'" cat="'+opts.catId+'" num="'+specNum+'" onclick="javascript:addSpecSaleCol()" '+opts.checked+'/>', + '<input type="text" id="specName_'+opts.catId+'_'+specNum+'" maxLength="50" value="'+WST.blank(opts.val)+'" onblur="batchChangeTxt(this.value,'+opts.catId+','+specNum+')"/>', + '</td>', + '<td id="uploadMsg_'+opts.catId+'_'+specNum+'">', + (opts.specImg)?'<img height="25" width="25" id="specImg_'+opts.catId+'_'+specNum+'" src="'+WST.conf.IMGURL+"/"+opts.specImg+'" v="'+opts.specImg+'"/>':"", + '</td><td><div id="specImgPicker_'+specNum+'" class="j-specImg">上传图片</div></td>' + ); + if($('#specTby').children().size()==0){ + html.push('<td><input type="button" id="specImgBtn" value="新增" onclick="addSpecImg({catId:'+opts.catId+',checked:\'\'})"/></td>'); + }else{ + html.push('<td><input type="button" id="specImgBtn" value="删除" onclick="delSpecImg(this,'+opts.catId+','+specNum+')"/></td>'); + } + html.push('</tr>'); + $('#specTby').append(html.join('')); + WST.upload({ + num:specNum, + cat:opts.catId, + pick:'#specImgPicker_'+specNum, + formData: {dir:'goods',isThumb:1}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg_'+this.cat+"_"+this.num).html('<img id="specImg_'+this.cat+"_"+this.num+'" v="'+json.savePath+json.name+'" src="'+WST.conf.IMGURL+"/"+json.savePath+json.thumb+'" height="25" width="25"/>'); + } + }, + progress:function(rate){ + $('#uploadMsg_'+this.cat+"_"+this.num).html('已上传'+rate+"%"); + } + }); + if(opts.itemId){ + id2SepcNumConverter[opts.itemId] = opts.catId+'_'+specNum; + } + specNum++; +} +/**删除带图片的规格值**/ +function delSpecImg(obj,catId,num){ + if($('.j-spec_'+catId+'_'+num)[0].checked){ + $('.j-spec_'+catId+'_'+num)[0].checked = false; + addSpecSaleCol(); + } + $(obj).parent().parent().remove(); +} +/**给销售规格表填上值**/ +function fillSepcSale(){ + var ids = '',tmpids = []; + for(var i=0;i<OBJ.saleSpec.length;i++){ + tmpids = []; + ids = OBJ.saleSpec[i].specIds; + ids = ids.split(':'); + for(var j=0;j<ids.length;j++){ + tmpids.push(id2SepcNumConverter[ids[j]]); + } + tmpids = tmpids.join('-'); + if(OBJ.saleSpec[i].isDefault)$('#isDefault_'+tmpids).attr('checked',true); + $('#productNo_'+tmpids).val(OBJ.saleSpec[i].productNo); + $('#marketPrice_'+tmpids).val(OBJ.saleSpec[i].marketPrice); + $('#specPrice_'+tmpids).val(OBJ.saleSpec[i].specPrice); + $('#initNum_'+tmpids).val(OBJ.saleSpec[i].initNum); + $('#whslePrice_'+tmpids).val(OBJ.saleSpec[i].whslePrice); + $('#specStock_'+tmpids).val(OBJ.saleSpec[i].specStock); + $('#warnStock_'+tmpids).val(OBJ.saleSpec[i].warnStock); + $('#saleNum_'+tmpids).val(OBJ.saleSpec[i].saleNum); + $('#saleNum_'+tmpids).attr('sid',OBJ.saleSpec[i].id); + } +} +/**生成销售规格表**/ +function addSpecSaleCol(){ + //获取规格分类和规格值 + var catId,snum,specCols = {},obj = []; + $('.j-speccat').each(function(){ + if($(this)[0].checked){ + catId = $(this).attr('cat'); + snum = $(this).attr('num'); + if(!specCols[catId]){ + specCols[catId] = []; + specCols[catId].push({id:catId+"_"+snum,val:$.trim($('#specName_'+catId+"_"+snum).val())}); + }else{ + specCols[catId].push({id:catId+"_"+snum,val:$.trim($('#specName_'+catId+"_"+snum).val())}); + } + } + }); + //创建表头 + $('.j-saleTd').remove(); + var html = [],specArray = [];; + for(var key in specCols){ + html.push('<th class="j-saleTd">'+$('#specCat_'+key).html()+'</th>'); + specArray.push(specCols[key]); + } + if(html.length==0){ + $('#goodsStock').removeAttr('disabled'); + $('#shopPrice').removeAttr('disabled'); + $('#marketPrice').removeAttr('disabled'); + $('#warnStock').removeAttr('disabled'); + return; + } + $(html.join('')).insertBefore('#thCol'); + //组合规格值 + this.combined = function(doubleArrays){ + var len = doubleArrays.length; + if (len >= 2) { + var arr1 = doubleArrays[0]; + var arr2 = doubleArrays[1]; + var len1 = doubleArrays[0].length; + var len2 = doubleArrays[1].length; + var newlen = len1 * len2; + var temp = new Array(newlen),ntemp; + var index = 0; + for (var i = 0; i < len1; i++) { + if(arr1[i].length){ + for (var k = 0; k < len2; k++) { + ntemp = arr1[i].slice(); + ntemp.push(arr2[k]); + temp[index] = ntemp; + index++; + } + }else{ + for (var j = 0; j < len2; j++) { + temp[index] = [arr1[i],arr2[j]]; + index++; + } + } + } + var newArray = new Array(len - 1); + newArray[0] = temp; + if (len > 2) { + var _count = 1; + for (var i = 2; i < len; i++) { + newArray[_count] = doubleArrays[i]; + _count++; + } + } + return this.combined(newArray); + }else { + return doubleArrays[0]; + } + } + + var specsRows = this.combined(specArray); + //生成规格值表 + html = []; + var id=[],key=1,specHtml = []; + var productNo = $('#productNo').val(),specProductNo = ''; + for(var i=0;i<specsRows.length;i++){ + id = [],specHtml = []; + html.push('<tr class="j-saleTd">'); + + if(specsRows[i].length){ + for(var j=0;j<specsRows[i].length;j++){ + id.push(specsRows[i][j].id); + specHtml.push('<td class="j-td_'+specsRows[i][j].id+'">' + specsRows[i][j].val + '</td>'); + } + }else{ + id.push(specsRows[i].id); + specHtml.push('<td>' + specsRows[i].val + '</td>'); + } + id = id.join('-'); + if(OBJ.goodsId==0){ + specProductNo = productNo+'-'+key; + } + html.push(' <td><input type="radio" id="isDefault_'+id+'" name="defaultSpec" class="j-ipt" value="'+id+'"/></td>'); + html.push(specHtml.join('')); + html.push(' <td><input type="text" class="spec-sale-goodsNo j-ipt" id="productNo_'+id+'" value="'+specProductNo+'" onblur="checkProductNo(this)" ></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="marketPrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="specPrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="initNum_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="whslePrice_'+id+'" onblur="WST.limitDecimal(this,2);javascript:WST.limitDecimal(this,2)" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="specStock_'+id+'" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td><input type="text" class="spec-sale-ipt j-ipt" id="warnStock_'+id+'" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></td>', + ' <td class="j-ws" v="'+id+'" id="saleNum_'+id+'">0</td>', + '</tr>'); + key++; + } + $('#spec-sale-tby').append(html.join('')); + //判断是否禁用商品价格和库存字段 + if($('#spec-sale-tby').html()!=''){ + $('#goodsStock').prop('disabled',true); + $('#shopPrice').prop('disabled',true); + $('#marketPrice').prop('disabled',true); + $('#warnStock').prop('disabled',true); + } + //设置销售规格表值 + if(OBJ.saleSpec)fillSepcSale(); +} +/**根据批量修改销售规格值**/ +function batchChange(v,id){ + if($.trim(v)!=''){ + $('input[type=text][id^="'+id+'_"]').val(v); + } +} +/**根据规格值修改 销售规格表 里的值**/ +function batchChangeTxt(v,catId,num){ + $('.j-td_'+catId+"_"+num).each(function(){ + $(this).html(v); + }); +} +/**检测商品销售规格值是否重复**/ +function checkProductNo(obj){ + v = $.trim(obj.value); + var num = 0; + $('input[type=text][id^="productNo_"]').each(function(){ + if(v==$.trim($(this).val()))num++; + }); + if(num>1){ + WST.msg('已存在相同的货号',{icon:2}); + obj.value = ''; + } +} +/**获取商品规格和属性**/ +function getSpecAttrs(goodsCatId){ + $('#specsAttrBox').empty(); + $('#specBtns').hide(); + specNum = 0; + $.post(WST.U('home/goods/getSpecAttrs'),{goodsCatId:goodsCatId,goodsType:$('#goodsType').val()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data){ + var html = [],tmp,str; + if(json.data.spec0 || json.data.spec1){ + html.push('<div class="spec-head">商品规格</div>'); + html.push('<div class="spec-body">'); + if(json.data.spec0){ + tmp = json.data.spec0; + html.push('<div id="specCat_'+tmp.catId+'">'+tmp.catName+'</div>'); + html.push('<table><tbody id="specTby"></tbody></table>'); + } + if(json.data.spec1){ + for(var i=0;i<json.data.spec1.length;i++){ + tmp = json.data.spec1[i]; + html.push('<div class="spec-line"></div>', + '<div id="specCat_'+tmp.catId+'">'+tmp.catName+'</div>', + '<div>', + '<input type="button" value="新增" id="specAddBtn_'+tmp.catId+'" onclick="javascript:addSpec({catId:'+tmp.catId+',checked:\'\'})"/>', + '</div>' + ); + } + } + html.push('</div>'); + html.push($('#specTips').html()); + html.push('<div id="specSaleHead" class="spec-head">销售规格</div>', + '<table class="specs-sale-table">', + ' <thead id="spec-sale-hed">', + ' <tr>', + ' <th>推荐<br/>规格</th>', + ' <th id="thCol"><font color="red">*</font>货号</th>', + ' <th><font color="red">*</font>市场价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'marketPrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>本店价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'specPrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>起批数<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'initNum\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>批发价<br/><input type="text" class="spec-sale-ipt" onblur="WST.limitDecimal(this,2);batchChange(this.value,\'whslePrice\')" onkeypress="return WST.isNumberdoteKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>库存<br/><input type="text" class="spec-sale-ipt" onblur="batchChange(this.value,\'specStock\')" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th><font color="red">*</font>预警库存<br/><input type="text" class="spec-sale-ipt" onblur="batchChange(this.value,\'warnStock\')" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)"></th>', + ' <th>销量</th>', + ' </tr>', + ' </thead>', + ' <tbody id="spec-sale-tby"></tbody></table>' + ); + } + if(json.data.attrs){ + html.push('<div class="spec-head">商品属性</div>'); + html.push('<div class="spec-body">'); + html.push('<table class="attr-table">'); + for(var i=0;i<json.data.attrs.length;i++){ + tmp = json.data.attrs[i]; + html.push('<tr><th width="120" nowrap>'+tmp.attrName+':</th><td>'); + if(tmp.attrType==1){ + str = tmp.attrVal.split(','); + for(var j=0;j<str.length;j++){ + html.push('<label><input type="checkbox" class="j-ipt" name="attr_'+tmp.attrId+'" value="'+str[j]+'"/>'+str[j]+'</label>'); + } + }else if(tmp.attrType==2){ + html.push('<select name="attr_'+tmp.attrId+'" id="attr_'+tmp.attrId+'" class="j-ipt">'); + html.push('<option value="0">请选择</option>'); + str = tmp.attrVal.split(','); + for(var j=0;j<str.length;j++){ + html.push('<option value="'+str[j]+'">'+str[j]+'</option>'); + } + html.push('</select>'); + }else{ + html.push('<input type="text" name="attr_'+tmp.attrId+'" id="attr_'+tmp.attrId+'" class="spec-sale-text j-ipt"/>'); + } + html.push('</td></tr>'); + } + html.push('</table>'); + html.push('</div>'); + } + $('#specsAttrBox').html(html.join('')); + //如果是编辑的话,第一次要设置之前设置的值 + if(OBJ.goodsId>0 && specNum==0){ + //设置规格值 + if(OBJ.spec0){ + for(var i=0;i<OBJ.spec0.length;i++){ + addSpecImg({catId:OBJ.spec0[i].catId,checked:'checked',val:OBJ.spec0[i].itemName,itemId:OBJ.spec0[i].itemId,specImg:OBJ.spec0[i].itemImg}); + } + } + if(OBJ.spec1){ + for(var i=0;i<OBJ.spec1.length;i++){ + addSpec({catId:OBJ.spec1[i].catId,checked:'checked',val:OBJ.spec1[i].itemName,itemId:OBJ.spec1[i].itemId}); + } + } + addSpecSaleCol(); + //设置商品属性值 + var tmp = null; + if(OBJ.attrs.length){ + for(var i=0;i<OBJ.attrs.length;i++){ + if(OBJ.attrs[i].attrType==1){ + tmp = OBJ.attrs[i].attrVal.split(','); + WST.setValue("attr_"+OBJ.attrs[i].attrId,tmp); + }else{ + WST.setValue("attr_"+OBJ.attrs[i].attrId,OBJ.attrs[i].attrVal); + } + } + } + + } + //给没有初始化的规格初始化一个输入框 + if(json.data.spec0 && !$('.j-speccat_'+json.data.spec0.catId)[0]){ + addSpecImg({catId:json.data.spec0.catId,checked:''}); + } + if(json.data.spec1){ + for(var i=0;i<json.data.spec1.length;i++){ + if(!$('.j-speccat_'+json.data.spec1[i].catId)[0])addSpec({catId:json.data.spec1[i].catId,checked:''}); + } + } + $('#specBtns').show(); + } + }); +} + +function changeGoodsType(v){ + if(v==0){ + $('#goodsStockTr').show(); + $('#goodsStock').removeAttr('disabled'); + }else{ + $('#goodsStockTr').hide(); + $('#goodsStock').prop('disabled',true); + } + var goodsCatId =WST.ITGetGoodsCatVal('j-goodsCats'); + getSpecAttrs(goodsCatId); +} +function toStock(id,src){ + location.href=WST.U('home/goodsvirtuals/stock','id='+id+"&src="+src); +} + +function saleByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/saleByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + saleByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function auditByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/auditByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + auditByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function storeByPage(p){ + $('#list1').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key1').val()); + params.page = p; + $.post(WST.U('home/goods/storeByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist1').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list1').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager1', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + storeByPage(e.curr); + } + } + }); + }else{ + $('#pager1').empty(); + } + } + }); +} +function illegalByPage(p){ + $('#list2').html('<tr><td colspan="4"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key2').val()); + params.page = p; + $.post(WST.U('home/goods/illegalByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist2').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list2').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager2', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + illegalByPage(e.curr); + } + } + }); + }else{ + $('#pager2').empty(); + } + } + }); +} +function limitPriceByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goods/limitPriceByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + auditByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function limitPriceGoods(){ + var params = WST.getParams('.ipt'); + //alert(JSON.stringify(params)); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/goods/limitPrice'),params,function(data){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status==1){ + var html = []; + var option1 = []; + for(i in json.data){ + if(i==0)option1 = json.data[i]; + html.push('<option value="'+json.data[i].goodsId+'" gt="'+json.data[i].goodsType+'">'+json.data[i].goodsName+'</option>'); + } + $('#goodsId').html(html.join('')); + }else{ + WST.msg("获取失败",{icon:2}); + } + }); +} +function changeGoods(){ + var goodsId=document.getElementById("goodsId").value; + $.post("getGoodsProduct",{goodsId:goodsId},function(data){ + $("#productNo").empty(); + if(data['specs']!=''){ + for(var i in data['specs']){ + $("#productNo").append("<option value='"+data['specs'][i].productNo+"'>"+data['specs'][i].productNo+"</option>"); + changeSpecs(); + } + }else{ + var html = []; + html.push('<option value="">无商品货号</option>'); + $('#productNo').html(html.join('')); + //$("#productNo").html('<option value=0>无商品货号</option>'); + document.getElementById('specs').value = ''; + } + + } + , "json") +} + +function changeSpecs(){ + var productNo=document.getElementById("productNo").value; + $.post("getGoodsSpecs",{productNo:productNo},function(data){ + document.getElementById('specs').value = data['itemName']; + }, "json") +} +//添加限时价格商品 +function addLimitGoods(id){ + var laydate = layui.laydate; + laydate.render({ + elem: '#startTime', + type: 'datetime' + }); + laydate.render({ + elem: '#endTime', + type: 'datetime' + }); + $('#goodsForm').get(0).reset(); + $.post(WST.U('home/goods/getLimitGoods'),{id:id},function(data,textStatus){ + var json = WST.toJson(data); + WST.setValues(json); + if(id>0){ + if(json.productNo!=""){ + $("#productNo").html("<option value='"+json.productNo+"'>"+json.productNo+"</option>"); + } + else{ + $("#productNo").html("<option value=''>无商品货号</option>"); + } + } + //alert(JSON.stringify(json.productNo)) + var title =(id==0)?"新增":"编辑"; + var box = WST.open({title:title,type:1,content:$('#goodsBox'),area: ['750px', '320px'],btn:['确定','取消'], + end:function(){$('#goodsBox').hide();},yes:function(){ + var params = WST.getParams('.j-ipt'); + //alert(JSON.stringify(params)); + if(params.goodsId==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + if(params.startTime==''){ + WST.msg('开始时间不能为空!', {icon: 5}); + return; + } + if(params.endTime==''){ + WST.msg('结束时间不能为空!', {icon: 5}); + return; + } + if(params.endTime<params.startTime){ + WST.msg('结束时间不能小于结束时间!', {icon: 5}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + params.id=id; + $.post(WST.U('home/goods/'+((id==0)?"addLimitGoods":"editLimitGoods")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + //alert(json) + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + $('#goodsBox').hide(); + limitPriceByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + //$('#goodsForm').submit(); + }}); + }); +} +//删除限时价格商品 +function delLimitGoods(id){ + var c = WST.confirm({content:'您确定要删除商品吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goods/delLimitGoods'),{id:id},function(data){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg("删除成功",{icon:1}); + limitPriceByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} +function del(id,func){ + var c = WST.confirm({content:'您确定要删除商品吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goods/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + case 'illegal':illegalByPage(0);break; + } + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +// 批量 上架/下架 +function changeSale(i,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.isSale = i; + $.post(WST.U('home/goods/changeSale'), params, function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},(function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + })); + }else if(json.status=='-2'){ + WST.msg(json.msg, {icon: 5}); + }else if(json.status=='2'){ + WST.msg(json.msg, {icon: 5},function(){ + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else if(json.status=='-3'){ + WST.msg(json.msg, {icon: 5,time:3000}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +// 批量设置 精品/新品/推荐/热销 +function changeGoodsStatus(isWhat,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.is = isWhat; + $.post(WST.U('home/goods/changeGoodsStatus'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('设置成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('设置失败',{icon:5}); + } + }); +} +// 批量设置 店长推荐 +function changeStoreStatus(isWhat,func){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + params.is = isWhat; + $.post(WST.U('home/goods/changeStoreStatus'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('设置成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('设置失败',{icon:5}); + } + }); +} + +// 双击设置 +function changSaleStatus(isWhat, obj, id){ + var params = {}; + status = $(obj).attr('status'); + params.status = status; + params.id = id; + switch(isWhat){ + case 'r':params.is = "isRecom";break; + case 'b':params.is = "isBest";break; + case 'n':params.is = "isNew";break; + case 'h':params.is = "isHot";break; + case 's':params.is = "storeRecom";break; + } + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/changSaleStatus'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(status==0){ + $(obj).attr('status',1); + $(obj).removeClass('wrong').addClass('right'); + }else{ + $(obj).attr('status',0); + $(obj).removeClass('right').addClass('wrong'); + } + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} +// 双击修改店长推荐 +function changStoreRecom(isWhat, obj, id){ + var params = {}; + status = $(obj).attr('status'); + params.status = status; + params.id = id; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/changStoreRecom'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + if(status==0){ + $(obj).attr('status',1); + $(obj).removeClass('wrong').addClass('right'); + }else{ + $(obj).attr('status',0); + $(obj).removeClass('right').addClass('wrong'); + } + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} + + +//双击修改 +function toEditGoodsBase(fv,goodsId,flag){ + if((fv==2 || fv==3) && flag==1){ + WST.msg('该商品存在商品属性,不能直接修改,请进入编辑页修改', {icon: 5}); + return; + }else{ + $("#ipt_"+fv+"_"+goodsId).show(); + $("#span_"+fv+"_"+goodsId).hide(); + $("#ipt_"+fv+"_"+goodsId).focus(); + $("#ipt_"+fv+"_"+goodsId).val($("#span_"+fv+"_"+goodsId).html()); + } + +} +function endEditGoodsBase(fv,goodsId){ + $('#span_'+fv+'_'+goodsId).html($('#ipt_'+fv+'_'+goodsId).val()); + $('#span_'+fv+'_'+goodsId).show(); + $('#ipt_'+fv+'_'+goodsId).hide(); +} +function editGoodsBase(fv,goodsId){ + var vtext = $.trim($('#ipt_'+fv+'_'+goodsId).val()); + if(fv==2){ + if(vtext=='' || parseFloat(vtext,10)<=0){ + WST.msg('价格必须大于0', {icon: 5}); + return; + } + }else if(fv==3){ + if(vtext=='' || parseInt(vtext,10)<0 || vtext.indexOf('.')>-1){ + WST.msg('库存必须为正整数', {icon: 5}); + return; + } + } + var params = {}; + (fv==2)?params.shopPrice=vtext:params.goodsStock=vtext; + params.goodsId = goodsId; + $.post(WST.U('Home/Goods/editGoodsBase'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + $('#img_'+fv+'_'+goodsId).fadeTo("fast",100); + endEditGoodsBase(fv,goodsId); + $('#img_'+fv+'_'+goodsId).fadeTo("slow",0); + }else{ + WST.msg(json.msg, {icon: 5}); + } + }); +} + +function benchDel(func,flag){ + if(flag==1){ + var ids = WST.getChks('.chk1'); + }else{ + var ids = WST.getChks('.chk'); + } + + if(ids==''){ + WST.msg('请先选择商品!', {icon: 5}); + return; + } + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/goods/batchDel'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + $('#all').prop('checked',false); + switch(func){ + case 'store':storeByPage(0);break; + case 'sale':saleByPage(0);break; + case 'audit':auditByPage(0);break; + } + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); +} + +function getCat(val){ + if(val==''){ + $('#cat2').html("<option value='' >-请选择-</option>"); + $('#cat3').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + //alert(JSON.stringify(data)) + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + $('#cat3').html(html.join('')); + }); +} +function resetForm(){ + location.reload(); +} + diff --git a/hyhproject/home2/view/default/shops/goods/list_audit.html b/hyhproject/home2/view/default/shops/goods/list_audit.html new file mode 100755 index 0000000..6415990 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/list_audit.html @@ -0,0 +1,138 @@ +{extend name="default/shops/base" /} +{block name="title"}审核中的商品-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>审核中商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /> + <a class="s-btn" onclick="auditByPage()">查询</a> + </label> +</div> +<div class="wst-clear"></div> +<div class="wst-body"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'audit')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','audit')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','audit')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','audit')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','audit')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('audit')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + <div class="wst-clear"></div> + <table class='wst-list'> + <thead> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody style="margin-top:15px;" id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + + </td> + <td>{{d[i]['goodsSn']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"audit")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"audit")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"audit")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'audit')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','audit')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','audit')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','audit')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','audit')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('audit')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){auditByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/list_illegal.html b/hyhproject/home2/view/default/shops/goods/list_illegal.html new file mode 100755 index 0000000..ac2b3b6 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/list_illegal.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}违规商品-会员中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>违规商品</span></div> +<div class="wst-shop-tbar"> +<label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> +</label> +<label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> +<label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" id="store-query" onclick="illegalByPage()">查询</a> +</label> +</div> +<div class="wst-clear"></div> +<form id='editform' autocomplete='off'> +<div class="wst-body"> + <table class='wst-list'> + <thead> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="benchDel('store',1)" class="s-del"><span>删除</span></a> + </div> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk1')" type='checkbox' id="all-1"/> + <label for="all-1"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th>违规原因</th> + <th width="150">操作</th> + </tr> + </thead> + <tbody id='list2'></tbody> + <tfoot> + <tr align="center"><td colspan='5' id='pager2'></td></tr> + </tfoot> + <script id="tblist2" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk1 wst-checkbox-s' id="chk-1-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-1-{{i}}"></label> + </div> + </td> + + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + <td>{{d[i]['illegalRemarks']}}</td> + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"illegal")'>[编辑]</a> + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"illegal")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +</form> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){illegalByPage(0)}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/list_limitprice.html b/hyhproject/home2/view/default/shops/goods/list_limitprice.html new file mode 100755 index 0000000..c1a59a2 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/list_limitprice.html @@ -0,0 +1,196 @@ +{extend name="default/shops/base" /} +{block name="title"}出售中的商品-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/layui/css/layui.css" /> +<!--<link rel="stylesheet" type="text/css" href="__STYLE__/css/common.css" />--> +<style> + body{ + color:#333;font:12px/150% "Hiragino Sans GB","Microsoft Yahei",arial,宋体,"Helvetica Neue",Helvetica,STHeiTi,sans-serif + } +</style> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>限时价格商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="limitPriceByPage()">查询</a> + </label> + <label> + <a class="s-btn" onclick="addLimitGoods(0)">新增限时价格商品</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th width="180" >商品名称</th> + <th width="100" >商品编号</th> + <th width="40" >店铺价格</th> + <th width='40'>限时价格</th> + <th width="25" >销量</th> + <th width="25" >库存</th> + <th width="100" >开始时间</th> + <th width="100" >结束时间</th> + <th width="95">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + {{# if(d[i]['specPrice']!=null){ }} + <td>{{d[i]['specPrice']}}</td> + {{# }else{ }} + <td>{{d[i]['shopPrice']}}</td> + {{# } }} + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['limitPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['limitPrice']}}</span> + </td> + {{# } }} + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + + </td> + {{# } }} + <td>{{d[i]['startTime']}}</td> + <td>{{d[i]['endTime']}}</td> + <td> + <!--<a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a>--> + <a class="g-handle" href='javascript:addLimitGoods({{d[i]['id']}})'>[编辑价格]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"sale")'>[卡券]</a> + {{#}}} + <a class="g-handle" href="javascript:delLimitGoods({{d[i]['id']}})">[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> +</div> +<div id='goodsBox' style='display:none'> + <form id="goodsForm"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>商品分类<font color='red'>*</font>:</th> + <td > + <select name="cat1" id="cat1" onchange="getCat(this.value)" class=" ipt"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat3" id="cat3" class="ipt"><option value="">-请选择-</option></select> + <label style="height: 20px;"> + <a class="s-btn" onclick="limitPriceGoods()" style="height: 20px;line-height: 20px">查询</a> + </label> + </td> + </tr> + <tr> + <th width='150'>商品<font color='red'>*</font>:</th> + <td > + <select name="goodsId" id="goodsId" class="j-ipt" onchange='changeGoods()'> + <option value="">-请选择-</option> + {volist name="lists" id="vo"} + <option value="{$vo['goodsId']}">{$vo['goodsName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>商品货号:</th> + <td> + <select id='productNo' name="productNo" class='j-ipt' onchange='changeSpecs()'> + <option value="">请选择商品货号</option> + </select> + </td> + </tr> + <tr> + <th>商品规格:</th> + <td> + <input type="text" id="specs" value="" disabled="disabled" class="ipt"> + </td> + </tr> + <tr> + <th>商品限时价格<font color='red'>*</font>:</th> + <td> + <input type="text" id="limitPrice" value="" class="j-ipt"> + </td> + </tr> + <tr class="wst-order-rate" > + <th width='120'>有效时间<font color='red'>*</font>:</th> + <td colspan='3'> + <input type='text' id='startTime' name='startTime' class='j-ipt laydate-icon' value=''/> + 至 + <input type='text' id='endTime' name='endTime' class='j-ipt laydate-icon' value=''/> + </td> + </tr> + + </table> + </form> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> + $(function(){limitPriceByPage()}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/list_sale.html b/hyhproject/home2/view/default/shops/goods/list_sale.html new file mode 100755 index 0000000..cd61ed6 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/list_sale.html @@ -0,0 +1,141 @@ +{extend name="default/shops/base" /} +{block name="title"}出售中的商品-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>出售中商品</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> + <label> + 商品名称/ID:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="saleByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'sale')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','sale')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','sale')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','sale')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','sale')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="changeStoreStatus('storeRecom','sale')" class="s-heart" style="width:70px"><span>店长推荐</span></a> + <a href='javascript:void(0);' onclick="benchDel('sale')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>店长推荐</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['storeStatus']}}" title='双击可修改' ondblclick='changStoreRecom("s",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['storeStatus']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="padding:3px;display:none;width:100%;border:1px solid red;width:40px;" maxlength="6"/> + + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['goodsStock']}}</span> + + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"sale")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"sale")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(0,'sale')" class="s-sale"><span>下架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','sale')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','sale')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','sale')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','sale')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="changeStoreStatus('storeRecom','sale')" class="s-heart" style="width:70px"><span>店长推荐</span></a> + <a href='javascript:void(0);' onclick="benchDel('sale')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){saleByPage()}) + +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goods/list_store.html b/hyhproject/home2/view/default/shops/goods/list_store.html new file mode 100755 index 0000000..c67d9d8 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goods/list_store.html @@ -0,0 +1,138 @@ +{extend name="default/shops/base" /} +{block name="title"}仓库中的商品-会员中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>仓库中的商品</span></div> +<div class="wst-shop-tbar"> +<label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> +</label> +<label> + 商品类型: + <select id='goodsType' class="s-query"> + <option value=''>全部</option> + <option value='0'>实物商品</option> + <!-- <option value='1'>虚拟商品</option> --> + </select> + </label> +<label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" id="store-query" onclick="storeByPage()">查询</a> +</label> +</div> +<div class="wst-clear"></div> +<form id='editform' autocomplete='off'> +<div class="wst-body"> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(1,'store')" class="s-sale-up"><span>上架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','store')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','store')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','store')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','store')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('store')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + + <table class='wst-list'> + <thead> + <tr> + <th width='10'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>商品名称</th> + <th>商品编号</th> + <th width='50'>价格(¥)</th> + <th>推荐</th> + <th>精品</th> + <th>新品</th> + <th>热销</th> + <th>销量</th> + <th>库存</th> + <th width="175">操作</th> + </tr> + </thead> + <tbody id='list1'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager1'></td></tr> + </tfoot> + <script id="tblist1" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['goodsId']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['goodsSn']}}</td> + + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['shopPrice']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(2,{{d[i]['goodsId']}},'')"> + <input id="ipt_2_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2);editGoodsBase(2,{{d[i]['goodsId']}})" style="display:none;width:100%;border:1px solid red;width:40px;padding:3px;" maxlength="10"/> + <span id="span_2_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:green;">{{d[i]['shopPrice']}}</span> + </td> + {{# } }} + + <td><div status="{{d[i]['isRecom']}}" title='双击可修改' ondblclick='changSaleStatus("r",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isRecom']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isBest']}}" title='双击可修改' ondblclick='changSaleStatus("b",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isBest']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isNew']}}" title='双击可修改' ondblclick='changSaleStatus("n",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isNew']==1)?'right':'wrong')}}"></div></td> + <td><div status="{{d[i]['isHot']}}" title='双击可修改' ondblclick='changSaleStatus("h",this,{{d[i]["goodsId"]}})' class="w-r {{((d[i]['isHot']==1)?'right':'wrong')}}"></div></td> + + <td>{{d[i]['saleNum']}}</td> + {{# if(d[i]['isSpec']==1 || d[i]['goodsType']==1) { }} + <td>{{d[i]['goodsStock']}}</td> + {{# }else{ }} + <td width="40" ondblclick="javascript:toEditGoodsBase(3,{{d[i]['goodsId']}},'')"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsBase(3,{{d[i]['goodsId']}})" style="display:none;width:100%;border:1px solid red;width:40px;padding:3px;" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;color:green;">{{d[i]['goodsStock']}}</span> + </td> + {{# } }} + <td> + <a class="g-handle" target='_blank' href='{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}'>[查看]</a> + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"store")'>[编辑]</a> + {{# if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"store")'>[卡券]</a> + {{#}}} + <a class="g-handle" href='javascript:del({{d[i]['goodsId']}},"store")'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div class="s-menu"> + <a href='javascript:;' onclick="changeSale(1,'store')" class="s-sale-up"><span>上架</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isRecom','store')" class="s-rec"><span>推荐</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isNew','store')" class="s-new"><span>新品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isBest','store')" class="s-best"><span>精品</span></a> + <a href='javascript:void(0);' onclick="changeGoodsStatus('isHot','store')" class="s-hot"><span>热销</span></a> + <a href='javascript:void(0);' onclick="benchDel('store')" class="s-del"><span>删除</span></a> + <a href='{:url("home/goods/add")}' class="s-add"><span>新增</span></a> + </div> + </div> + </form> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goods/goods.js?v={$v}'></script> +<script> +$(function(){storeByPage(0);}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goodsappraises/goodsappraises.js b/hyhproject/home2/view/default/shops/goodsappraises/goodsappraises.js new file mode 100755 index 0000000..e3f6ca5 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsappraises/goodsappraises.js @@ -0,0 +1,94 @@ +/**获取本店分类**/ +function getShopsCats(objId,pVal,objVal){ + $('#'+objId).empty(); + $.post(WST.U('home/shopcats/listQuery'),{parentId:pVal},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"' "+((objVal==cat.catId)?"selected":"")+">"+cat.catName+"</option>"); + } + } + $('#'+objId).html(html.join('')); + }); +} +function getCat(val){ + if(val==0){ + $('#cat2').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + }); +} +function showImg(id){ + layer.photos({ + photos: '#img-file-'+id + }); +} +function queryByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goodsappraises/queryByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + $('#list').empty(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + for(var g=0;g<=json.Rows.length;g++){ + showImg(g); + } + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} + +function reply(t,id){ + var params = {}; + if($('#reply-'+id).val()==''){ + WST.msg('回复内容不能为空',{icon:2}); + return false; + } + params.reply = $('#reply-'+id).val(); + params.id=id; + $.post(WST.U('home/goodsappraises/shopReply'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var today = new Date(); + today = today.toLocaleDateString(); + var html = '<p class="reply-content">'+params.reply+'【'+today+'】</p>' + $(t).parent().html(html); + } + }); +} diff --git a/hyhproject/home2/view/default/shops/goodsappraises/list.html b/hyhproject/home2/view/default/shops/goodsappraises/list.html new file mode 100755 index 0000000..6f4ea83 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsappraises/list.html @@ -0,0 +1,107 @@ +{extend name="default/shops/base" /} +{block name="title"}评价列表-卖家中心{__block__}{/block} +{block name="content"} + +<div class="wst-shop-head"><span>评价列表</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + </label> + <label> + 商品名称:<input type="text" name="goodsName" id="goodsName" class="s-query" /><a class="s-btn" onclick="queryByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="400">商品</th> + <th>商品评分</th> + <th>服务评分</th> + <th>时效评分</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td rowspan="2">{{i+1}}</td> + <td rowspan="2"> + <div class="appra-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId'])}}"> + <img class='gImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="appra-goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + + + <td> + {{# for(var gs=0;gs<d[i]['goodsScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['serviceScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['timeScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + </tr> + <tr style="border-bottom:1px solid #ccc;"> + <td colspan='3'>评价[{{d[i]['loginName']}}]:{{d[i]['content']}} + + {{# if(WST.blank(d[i]['images'])!=''){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + <img src="__IMGURL__/{{img[g]}}/thumb80" layer-src="__IMGURL__/{{img[g]}}" width="30" height="30" /> + {{# } }} + </div> + {{# } }} + <div class="reply-box"> + {{# if(d[i]['shopReply']==null || d[i]['shopReply']=='') { }} + <textarea cols="65" rows="5" id="reply-{{d[i]['gaId']}}" ></textarea> + <a class="reply-btn s-btn" onclick="reply(this,{{d[i]['gaId']}})">回复</a> + {{# }else{ }} + <p class="reply-content">{{d[i]['shopReply']}}【{{d[i]['replyTime']}}】</p> + {{# } }} + + </div> + </td> + </tr> + + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goodsappraises/goodsappraises.js?v={$v}'></script> +<script> +$(function(){ + queryByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goodsconsult/goodsconsult.js b/hyhproject/home2/view/default/shops/goodsconsult/goodsconsult.js new file mode 100755 index 0000000..70c65fe --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsconsult/goodsconsult.js @@ -0,0 +1,50 @@ +function queryByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/goodsconsult/pageQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + $('#list').empty(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + } + }); +} + +function reply(t,id){ + var params = {}; + if($('#reply-'+id).val()==''){ + WST.msg('回复内容不能为空',{icon:2}); + return false; + } + params.reply = $('#reply-'+id).val(); + params.id=id; + $.post(WST.U('home/goodsconsult/reply'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var today = new Date(); + var Myd = today.toLocaleDateString(); + var His = today.toLocaleTimeString(); + var html = '<p class="reply-content">'+params.reply+'【'+Myd+' '+His+'】</p>' + $(t).parent().html(html); + } + }); +} diff --git a/hyhproject/home2/view/default/shops/goodsconsult/list.html b/hyhproject/home2/view/default/shops/goodsconsult/list.html new file mode 100755 index 0000000..f167587 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsconsult/list.html @@ -0,0 +1,85 @@ +{extend name="default/shops/base" /} +{block name="title"}商品咨询-卖家中心{__block__}{/block} +{block name="content"} +<style> +.c999{color:#999;} +.consult{margin-bottom: 15px;} +.consultImg,.consultImg a,.consultImg a img{width: 50px !important;height: 50px !important} +</style> +<div class="wst-shop-head"><span>商品咨询</span></div> +<div class="wst-shop-tbar"> + <label> + 咨询分类: + <select name="consultType" id="consultType" class="s-query"> + <option value="0">-请选择-</option> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <option value="{$vo['dataVal']}" >{$vo['dataName']}</option> + {/volist} + </select> + </label> + <label> + 关键词:<input type="text" id="consultKey" class="s-query" /><a class="s-btn" onclick="queryByPage()">查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="300">商品</th> + <th>咨询内容</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td rowspan="2">{{i+1}}</td> + <td rowspan="2"> + <div class="appra-img consultImg"> + <a target='_blank' href="{{WST.U("home/goods/detail","id="+d[i]['goodsId'])}}"> + <img class='gImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="appra-goodsName" style="height:auto;"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + </tr> + <tr style="border-bottom:1px solid #ccc;"> + <td colspan='3'> + <p class='consult'> + [{{(WST.blank(d[i]['loginName'])=='')?'游客':d[i]['loginName']}}]:{{d[i]['consultContent']}} <span class="c999">({{d[i]['createTime']}})</span> + </p> + + <div class="reply-box"> + {{# if(d[i]['reply']==null || d[i]['reply']=='') { }} + <textarea style="width:98%;height:80px;" id="reply-{{d[i]['id']}}" placeholder='3~200个字符长度' maxlength='200'></textarea> + <a class="reply-btn s-btn" style="margin-left:3px;" onclick="reply(this,{{d[i]['id']}})">回复</a> + {{# }else{ }} + <p class="reply-content">{{d[i]['reply']}}【{{d[i]['replyTime']}}】</p> + {{# } }} + + </div> + </td> + </tr> + + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/goodsconsult/goodsconsult.js?v={$v}'></script> +<script> +$(function(){ + queryByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goodsvirtuals/edit.html b/hyhproject/home2/view/default/shops/goodsvirtuals/edit.html new file mode 100755 index 0000000..9f18998 --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsvirtuals/edit.html @@ -0,0 +1,26 @@ +<style> + .s-btn{margin:0px;} +</style> +<form id='cardForm' autocomplete="off"> +<table class='wst-form'> + <tr> + <th>卡券号<font color='red'>*</font>:</th> + <td> + <input type='text' class='j-ipt' id='cardNo' maxLength='20' value='{$object["cardNo"]}' style='width:250px'/> + </td> + </tr> + <tr> + <th>卡券密码<font color='red'>*</font>:</th> + <td><input type='text' class='j-ipt' id='cardPwd' maxLength='20' value='{$object["cardPwd"]}' style='width:250px'/></td> + </tr> + <tr> + <td colspan="2" style='text-align: center;padding-top: 15px;'> + <a class='s-btn' onclick="addCardFunc({$object['id']})">保存</a> + {if $object['id']==0} + <a class='s-btn' onclick="addCardFunc({$object['id']},1)" style='width:110px;'>继续新增</a> + {/if} + <a class='s-btn2' onclick="closeWin()">取消</a> + </td> + </tr> +</table> +</form> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goodsvirtuals/list.html b/hyhproject/home2/view/default/shops/goodsvirtuals/list.html new file mode 100755 index 0000000..22a4cbd --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsvirtuals/list.html @@ -0,0 +1,85 @@ +{extend name="default/shops/base" /} +{block name="title"}商品卡券-卖家中心{__block__}{/block} +{block name="content"} +<style> +.layui-layer-btn .layui-layer-btn0{background:#e45050;border-color:#e45050;} +.webuploader-container{width:80px;height:30px;overflow: hidden;float:right;margin:10px 5px 0px 5px;} +.webuploader-container .webuploader-pick{padding:5px 10px;} +</style> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<input type='hidden' id='vid' value='{$id}'/> +<div class="wst-shop-head"><span>商品卡券</span><a href="{:url('home/goods/'.$src)}">返回</a></div> +<div class="wst-shop-tbar"> + <label> + 状态:<select id='isUse' class="s-query"> + <option value='-1'>全部</option> + <option value='0'>未使用</option> + <option value='1'>已下单</option> + </select> + 卡券号:<input type="text" name="cardNo" id="cardNo" class="s-query" /> + <a class="s-btn" onclick="stockByPage()">查询</a> + <div id='importBtn' style='float:right;'>导入卡券</div> + <a style='float:right;height:30px;line-height:50px;' href='__STATIC__/template/goodsvirtuals.xls' target='_blank'>下载模板</a> + </label> +</div> +<div class="wst-shop-content"> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="delCard({$id},1)" class="s-del"><span>删除</span></a> + <a href='javascript:void(0);' onclick="editCard(0)" class="s-add"><span>新增</span></a> + </div> + <table class='wst-list'> + <thead> + <tr> + <th width="10" > + <div class="checkbox-box-s checkbox-box-s-all"> + <input style="margin-left:2px;" class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.vchk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th>卡券号</th> + <th>密码</th> + <th>状态</th> + <th>消费订单</th> + <th width="120">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='vchk wst-checkbox-s' id="chk-{{i}}" value='{{d[i]['id']}}' /><label for="chk-{{i}}"></label> + </div> + </td> + <td>{{d[i]['cardNo']}}</td> + <td>{{d[i]['cardPwd']}}</td> + <td>{{getUseStatus(d[i]['isUse'])}}</td> + <td>{{WST.blank(d[i]['orderNo'],' - ')}}</td> + <td> + {{# if(d[i]['isUse']==0){ }} + <a class="g-handle" href='javascript:editCard({{d[i]['id']}})'>[编辑]</a> + {{# } }} + <a class="g-handle" href='javascript:delCard({{d[i]['id']}},0)'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> + <div id='pager'></div> + <div class="s-menu"> + <a href='javascript:void(0);' onclick="delCard({$id},1)" class="s-del"><span>删除</span></a> + <a href='javascript:void(0);' onclick="editCard({$id})" class="s-add"><span>新增</span></a> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/shops/goodsvirtuals/virtuals.js?v={$v}'></script> +<script> +$(function(){stockByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/goodsvirtuals/virtuals.js b/hyhproject/home2/view/default/shops/goodsvirtuals/virtuals.js new file mode 100755 index 0000000..1f8c2bb --- /dev/null +++ b/hyhproject/home2/view/default/shops/goodsvirtuals/virtuals.js @@ -0,0 +1,127 @@ +function stockByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/wstmart/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params.isUse = $.trim($('#isUse').val()); + params.cardNo = $.trim($('#cardNo').val()); + params.id = $.trim($('#vid').val()); + params.page = p; + $.post(WST.U('home/goodsvirtuals/stockByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + if(params.page>json.TotalPage && json.TotalPage >0){ + stockByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + stockByPage(e.curr); + } + } + }); + } + }); +} +function getUseStatus(v){ + switch(v){ + case 0:return '未使用'; + case 1:return '已下单'; + } +} +function closeWin(){ + layer.close(w); +} +function addCardFunc(id,isContinue){ + var params =WST.getParams('.j-ipt'); + params.id = id; + params.goodsId = $('#vid').val(); + if(params.cardNo=='' || params.cardPwd=='' || params.lastDate==''){ + WST.msg('请输入完整卡券信息',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/goodsvirtuals/'+((params.id==0)?"add":"edit")),params,function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + stockByPage(WSTCurrPage); + if(isContinue){ + $('#cardForm')[0].reset(); + }else{ + closeWin(); + } + WST.msg(json.msg, {icon: 1}); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); +} +var ll,w; +function editCard(id,goodsId){ + ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/goodsvirtuals/'+((id==0)?'toAdd':'toEdit')),{id:id},function(data){ + layer.close(ll); + w = WST.open({ + type: 1, + title:"新增卡券", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['400px', '180px'] + }); + }); +} + +function delCard(id,v){ + if(v==1){ + id = WST.getChks('.vchk'); + id = id.join(','); + } + var c = WST.confirm({content:'您确定要删除卡券吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/goodsvirtuals/del'),{ids:id,id:$('#vid').val()},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + $('#all').prop('checked',false); + stockByPage(WSTCurrPage); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +var uploading = null; +$(function(){ + var uploader = WST.upload({ + server:WST.U('home/goodsvirtuals/importCards'),pick:'#importBtn', + formData: {dir:'temp',goodsId:$('#vid').val()}, + callback:function(f,file){ + layer.close(uploading); + uploader.removeFile(file); + var json = WST.toJson(f); + if(json.status==1){ + uploader.refresh(); + WST.msg('导入数据成功!已导入数据'+json.importNum+"条", {icon: 1}); + stockByPage(0); + }else{ + WST.msg('导入数据失败,出错原因:'+json.msg, {icon: 5}); + } + }, + progress:function(rate){ + uploading = WST.msg('正在导入数据,请稍后...'); + } + }); +}); diff --git a/hyhproject/home2/view/default/shops/import.html b/hyhproject/home2/view/default/shops/import.html new file mode 100755 index 0000000..1f91c8e --- /dev/null +++ b/hyhproject/home2/view/default/shops/import.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}数据导入 - 卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<div class="wst-body"> + <div class="wst-shop-head"><span>数据导入</span></div> + <table class="table table-hover table-striped table-bordered wst-form"> + <tr> + <td colspan='2' style='color:#707070;padding-left:25px;padding-top:5px;'> + <div class='wst-tips-box' style='margin-top:10px;'> + <div class='icon'></div> + <div class='tips' > + 1.请确保商品价格必须大于0,否则将自动默认为0.01。<br/> + 2.请确保商品库存不能为负数,否则将自动默认为0。<br/> + 3.请勿重复上传, 否则将造成重复商品数据。<br/> + 4.请保证导入的数据在Excel的第一个工作表(Sheet)。<br/> + 5.若Excel上某一行第一列为空则代表商品数据导入完毕。<br/> + 6.若没有数据模板,请点击<a href='__STATIC__/template/goods.xls' style='color:blue;' target='_blank'>下载Excel模板</a>。<br/> + 7.推荐使用谷歌浏览器或者火狐浏览器Firefox以获得更佳体验。<br/> + </div> + <div style="clear:both"></div> + </div> + </td> + </tr> + <tr> + <th align='right' width='90'>商品数据:</th> + <td> + <div id="filePicker" style='margin-left:0px;'>导入商品数据</div> + </td> + </tr> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> + var uploading = null; + $(function(){ + var uploader = WST.upload({ + server:"{:url('home/imports/importGoods')}",pick:'#filePicker', + formData: {dir:'temp'}, + callback:function(f,file){ + layer.close(uploading); + uploader.removeFile(file); + var json = WST.toJson(f); + if(json.status==1){ + uploader.refresh(); + WST.msg('导入数据成功!已导入数据'+json.importNum+"条", {icon: 1}); + }else{ + WST.msg('导入数据失败,出错原因:'+json.msg, {icon: 5}); + } + }, + progress:function(rate){ + uploading = WST.msg('正在导入数据,请稍后...'); + } + }); + }); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/index.html b/hyhproject/home2/view/default/shops/index.html new file mode 100755 index 0000000..8240f44 --- /dev/null +++ b/hyhproject/home2/view/default/shops/index.html @@ -0,0 +1,295 @@ +{extend name="default/shops/base" /} +{block name="title"}卖家中心 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<style> +.wst-content{min-height:185px;} +</style> +{/block} +{block name="content"} +<div class='wst-shop-name'><a href='{:Url("home/shops/home","shopId=".$data["shop"]["shopId"])}'>{$data['shop']['shopName']}</a></div> +<div class="wst-shop-info"> + <span class="wst-shop-img"> + <a href="{:url('home/shops/home',array('shopId'=>$data['shop']['shopId']))}"> + <img src="__IMGURL__/{:WSTImg($data['shop']['shopImg'])}" title="{$data['shop']['shopName']}" alt="{$data['shop']['shopName']}"> + </a> + </span> + <div class="wst-shop-na"> + <div class="wst-shop-na2"> + {volist name="$data['shop']['accreds']" id="sv"} + <img src="__IMGURL__/{$sv['accredImg']}" title='{$sv['accredName']}' alt='{$sv['accredName']}'> + {/volist} + </div> + <span class="wst-shop-na3">上次登录:{:session('WST_USER.lastTime')}</span> + <span class="wst-shop-na3">店铺地址:{:WSTMSubstr($data['shop']['shopAddress'],0,10)}</span> + </div> + <div class="wst-shop-eva"> + <p>商品评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['goodsScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['goodsScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-eva"> + <p>时效评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['timeScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['timeScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-eva"> + <p>服务评分</p> + <div class="wst-shop-evai"> + {for start="0" end="$data['shop']['scores']['serviceScore']"} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {/for} + {for start="1" end="6-$data['shop']['scores']['serviceScore']"} + <img src="__STATIC__/plugins/raty/img/star-off.png"> + {/for} + </div> + </div> + <div class="wst-shop-con"> + <p>电话:{$data['shop']['shopTel']}</p> + <p>QQ:{$data['shop']['shopQQ']}</p> + <p>服务时间:{php}echo date("H:i",strtotime($data['shop']['serviceStartTime']));{/php}-{php}echo date("H:i",strtotime($data['shop']['serviceEndTime']));{/php}</p> + </div> + <div class="wst-clear"></div> +</div> + + +<div class="main"> + <div class="main_middle"> + <ul class="main_mid_box"> + <li class="mid_l"> + <div class="mid_l_item"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">订单提示</span> + </div> + <div class="wst-rfloat"> + <span class="complain_num">{$data['stat']['complainNum']}</span> + <span class="c16_555">收到投诉信息</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="mid_main"> + <ul class="order_info"> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitReceiveCnt']}</p> + <span class="c14_555">待收货</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitDeliveryCnt']}</p> + <span class="c14_555">待发货</span> + </div> + </li> + <li> + <div class="item_center"> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['orderNeedpayCnt']}</p> + <span class="c14_555">待付款</span> + </div> + </div> + </li> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['cancel']}</p> + <span class="c14_555">取消/拒收</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['orderRefundCnt']}</p> + <span class="c14_555">待退款</span> + </div> + </li> + </ul> + </div> + </div> + + <div class="mid_l_item" style="margin-top:20px;"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商品信息</span> + </div> + </div> + <div class="wst-clear"></div> + <div class="mid_main"> + <ul class="order_info"> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['unSaleCnt']}</p> + <span class="c14_555">仓库中</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['stockWarnCnt']}</p> + <span class="c14_555">预警库存</span> + </div> + </li> + <li> + <div class="item_center item_sale"> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['onSaleCnt']}</p> + <span class="c14_555">出售中</span> + </div> + </div> + </li> + <li> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['waitAuditCnt']}</p> + <span class="c14_555">待审核</span> + </div> + <div class="info_item"> + <p class="c32_e33">{$data['stat']['illegalCnt']}</p> + <span class="c14_555">违规商品</span> + </div> + </li> + </ul> + </div> + </div> + </li> + <li class="mid_c"> + <div class="index-right"> + <div class="index-right-item"> + <div class="main_title" style="padding-left:10px;"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">最近七天销售排行</span> + </div> + <div class="wst-clear"></div> + </div> + <ul class="right-list-tit"> + <li class="c12_555">序号</li> + <li class="c12_555">商品</li> + <li class="c12_555">数量</li> + </ul> + {volist name="$data['stat']['goodsTop']" id="glist" key="gkey" length="10"} + <ul class="right-list-tit right-list"> + <li class="c14_ff66"> + <div class="gTop{$gkey} top-num">{$gkey}</div> + </li> + <li class="wst-textover"><a class="c14_ff90" target="_blank" href="{:url('home/goods/detail',['id'=>$glist.goodsId])}">{:WSTMSubstr($glist.goodsName,0,15)}</a></li> + <li class="c14_ff66">{$glist.goodsNum?:0}</li> + </ul> + {/volist} + </div> + </div> + + </li> + <li class="mid_r"> + <div class="mid_r_rtop"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">平台联系方式</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="rtop_main"> + <p class="rtop_item">电话:{:WSTConf('CONF.serviceTel')}</p> + <p class="rtop_item">邮箱:{:WSTConf('CONF.serviceEmail')}</p> + </div> + </div> + <div class='mid_r_rbottom'> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商家公告</span> + </div> + <div class="wst-clear"></div> + </div> + <div class="rbottom_main"> + <ul class="shop_tips"> + {wst:article cat="51" id="vo" num="10"} + <li class="wst-textover"><a href="{:url('home/news/view',['id'=>$vo['articleId']])}" target="_blank">{$vo.articleTitle}</a></li> + {/wst:article} + </ul> + </div> + <div style="margin-top: 130px;"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">商家访问量</span> + </div> + <div class="wst-clear"></div> + </div> + </div> + <div class="rbottom_main"> + <ul class="shop_tips"> + {volist name="$data['shop']['view']" id="c"} + <p class="rtop_item" style="font-size: 15px;">{if $c['path']==1}PC端:{elseif $c['path']==2}APP端:{else}手机端:{/if}{$c['view']}</p> + {/volist} + </ul> + </div> + </div> + </li> + </ul> + </div> + + <div class="sale_info"> + <div class="main_title"> + <div class="wst-lfloat"> + <span class="tit_label"></span> + <span class="c16_555">近30天销售情况</span> + </div> + <div class="wst-clear"></div> + </div> + <div id="saleMain" style="width:100%;height:260px;"></div> + </div> +</div> + + +{/* 近30天 */} +<input type="hidden" id="startDate" class="ipt" value='{:date("Y-m-d",strtotime("-30 day"))}'/> +<input type="hidden" id="endDate" class="ipt" value='{:date("Y-m-d")}'/> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script> +$(function(){saleCount()}); +// 销售统计 +function saleCount(){ + $.post(WST.U('home/reports/getStatSales'),WST.getParams('.ipt'),function(data,textStatus){ + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('saleMain')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + calculable : true, + xAxis : [ + { + type : 'category', + data : json.data.days + } + ], + yAxis : [ + { + type : 'value' + } + ], + series : [ + { + name:'销售额', + type:'line', + data:json.data.dayVals + } + ] + }; + myChart.setOption(option); + } + }); +} +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/logmoneys/list.html b/hyhproject/home2/view/default/shops/logmoneys/list.html new file mode 100755 index 0000000..f220974 --- /dev/null +++ b/hyhproject/home2/view/default/shops/logmoneys/list.html @@ -0,0 +1,70 @@ +{extend name="default/shops/base" /} +{block name="title"}资金流水-卖家中心{__block__}{/block} +{block name="content"} +<div class='money-head'> + <div class='shop-logo'><img height='100' width='100' src='__IMGURL__/{:session("WST_USER.shopImg")}'></div> + <div class='shop-info'> + <div class='shopName'>{:session('WST_USER.shopName')}</div> + <div class='shopMoney'> + 可用资金:<font color='red'>¥{$object['shopMoney']}</font> + 冻结资金:<font color='red'>¥{$object['lockMoney']}</font> + </div> + <div class="money-rows"> + <div class='shopMoney wst-lfloat'> + 应缴质保金:<font color='red'>¥{$object['deposit']['payDeposit']}</font> + 店铺质保金:<font color='red'>¥{$object['deposit']['cashDeposit']}</font> + 质保金:{if $object['deposit']['isFinish'] ==1} <font color='red'>已交齐</font>{else /}<font color='green'>未交齐</font>{/if} + </div> + </div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>资金流水</li> + <li>资金收入</li> + <li>资金支出</li> + <li>质保金流水</li> + </ul> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='150'>来源/用途</th> + <th width='100'>金额</th> + <th width='130'>日期</th> + <th width='100'>外部流水号</th> + <th width='*'>备注</th> + </tr> + </thead> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].dataSrc}}</td> + <td> + {{# if(d[i].moneyType==1){ }} + <span class="money-add">+ ¥{{ d[i].money }}</span> + {{# }else{ }} + <span class='money-reduce'> - ¥{{ d[i].money }}</span> + {{# } }} + </td> + <td>{{ d[i].createTime }}</td> + <td>{{ WST.blank(d[i].tradeNo,'-')}}</td> + <td style='line-height:23px'>{{ d[i].remark }}</td> + </tr> + {{# } }} + </script> + <tbody id="page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/logmoneys/logmoneys.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/logmoneys/logmoneys.js b/hyhproject/home2/view/default/shops/logmoneys/logmoneys.js new file mode 100755 index 0000000..5be2a0a --- /dev/null +++ b/hyhproject/home2/view/default/shops/logmoneys/logmoneys.js @@ -0,0 +1,77 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0,-1);break; + case 1:pageQuery(0,1);break; + case 2:pageQuery(0,0);break; + case 3:pageDeposit(0,2);break; + } + }}) +}); +function pageQuery(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + params.type = type; + $.post(WST.U('home/logmoneys/pageShopQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +//商家质保金流水 +function pageDeposit(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + // params.type = type; + $.post(WST.U('home/logmoneys/pageShopDeposit'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/messages/list.html b/hyhproject/home2/view/default/shops/messages/list.html new file mode 100755 index 0000000..ad6c9b3 --- /dev/null +++ b/hyhproject/home2/view/default/shops/messages/list.html @@ -0,0 +1,81 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>用户信息</span></div> +<div class="wst-clear"></div> + <div class='wst-shop-content' style='margin-top:0px;'> + <div class="s-menu"> + <a href="javascript:void(0)" onclick="batchRead()" style='margin-right:0px;float:none;width:60px;display:inline;'>标记为已读</a> | + <a href='javascript:void(0);' onclick="batchDel()" style='float:none;width:60px;display:inline;'>删除</a> + </div> + <div class='wst-page-content'> + <table class='wst-list'> + <thead> + <tr> + <th width='25'> + <div class="checkbox-box-s checkbox-box-s-all"> + <input class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th width='45'>状态</th> + <th>消息</th> + <th width='130'>时间</th> + <th width='100'>操作</th> + </tr> + </thead> + <script id="msg" type="text/html"> + {{# for(var i = 0, len = d.length; i < len; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{ d[i].id }}' /><label class='mt-1' for="chk-{{i}}"></label> + </div> + </td> + <td> + + {{# if(d[i].msgStatus ==1) { }} + <div class='readMsg'></div> + {{# }else{ }} + <div class='newMsg'></div> + {{# } }} + </td> + <td><div class="wst-hide msg-content">{{ d[i].msgContent }}</td> + <td>{{ d[i].createTime }}</td> + <td> + <a class="s-handle" href="javascript:showMsg({{ d[i].id }})">[查看]</a> + <a class="s-handle" href="javascript:delMsg(this,{{ d[i].id }})">[删除]</a> + &nbsp; + </td> + </tr> + {{# } }} + </script> + <tbody id="msg_box"> + + + + + + <tfoot> + <tr> + <td colspan='12' align='center'> + + <div id="wst-page" class='wst-page' style="padding-bottom:10px;"> + </div> + + </td> + </tr> + </tfoot> + </tbody> + </table> + + + + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/messages/message.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home2/view/default/shops/messages/message.js b/hyhproject/home2/view/default/shops/messages/message.js new file mode 100755 index 0000000..a141e41 --- /dev/null +++ b/hyhproject/home2/view/default/shops/messages/message.js @@ -0,0 +1,106 @@ +$(function(){ + queryByList(); +}); +function queryByList(p){ + var params = {}; + params.page = p; + var load = WST.load({msg:'正在加载信息,请稍后...'}) + $.post(WST.U('Home/Messages/pageQuery'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.data){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + queryByList(json.TotalPage); + return; + } + var gettpl = document.getElementById('msg').innerHTML; + //复选框为未选中状态 + $('#all').attr('checked',false); + laytpl(gettpl).render(json.Rows, function(html){ + $('#msg_box').html(html); + }); + laypage({ + cont: 'wst-page', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByList(e.curr); + } + } + }); + + } + }); +} + +function showMsg(id){ + location.href=WST.U('home/messages/showShopMsg','msgId='+id); +} + +function delMsg(obj,id){ +WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var ll = WST.load('数据处理中,请稍候...'); + $.post(WST.U('Home/messages/del'),{id:id},function(data,textStatus){ + layer.close(ll); + layer.close(tips); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!', {icon: 1}, function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +}}); +} +function batchDel(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择要删除的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchDel'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} +function batchRead(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择处理的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要将这些消息标记为已读吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchRead'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} diff --git a/hyhproject/home2/view/default/shops/messages/show.html b/hyhproject/home2/view/default/shops/messages/show.html new file mode 100755 index 0000000..ee9ccb7 --- /dev/null +++ b/hyhproject/home2/view/default/shops/messages/show.html @@ -0,0 +1,25 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +<style> +.msgContent img{ + width: 100%; +} +</style> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>查看消息</span><a href="<?=url('home/Messages/shopMessage');?>">返回</a></div> +<div class="wst-clear"></div> + <div class="wst-body"> + <div class='wst-page-content'> + <div class='wst-tbar-group'> + + </div> + <div class="msgContent"> + {$data['msgContent']} + </div> + </div> + </div> +{/block} +{block name="js"} +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/box_refund.html b/hyhproject/home2/view/default/shops/orders/box_refund.html new file mode 100755 index 0000000..7b4e605 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/box_refund.html @@ -0,0 +1,31 @@ +<table class='wst-form' style='margin-top:10px;width:90%'> + <tr> + <th width='120'>订单号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th width='120'>实付金额:</th> + <td>¥{$object['realTotalMoney']}</td> + </tr> + <tr> + <th width='120'>退款金额:</th> + <td style='color:red'>¥{$object['backMoney']}{if $object['ectNum']!=""}<font color='green'>≈{$object['ectNum']}ECT</font>{/if}</td> + </tr> + <tr> + <th width='120'>退款积分:</th> + <td style='color:red'>{$object['useScore']}个(积分抵扣¥{$object['scoreMoney']})</td> + </tr> + <tr> + <th width='120'>商家意见:</th> + <td> + <label><input type='radio' onclick='WST.showHide(0,"#tr")' name='refundStatus' id='refundStatus1' value='1' checked/>同意</label> + <label style='margin-left:15px;'><input type='radio' onclick='WST.showHide(1,"#tr")' name='refundStatus' id='refundStatus0' value='-1'/>不同意</label> + </td> + </tr> + <tr id='tr' style='display:none'> + <th width='120'>原因<font color='red'>*</font>:</th> + <td> + <textarea id='shopRejectReason' style='width:90%;height:50px;'></textarea> + </td> + </tr> +</table> \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/orders/complain_detail.html b/hyhproject/home2/view/default/shops/orders/complain_detail.html new file mode 100755 index 0000000..4636cec --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/complain_detail.html @@ -0,0 +1,123 @@ +{extend name="default/shops/base" /} +{block name="title"}投诉详细 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>投诉详细</span></div> + + <div class='wst-shop-content'> + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>投诉信息</td> + </tr> + <tr> + <th width='80'>订单号:</th> + <td>{$data['orderNo']}</td> + </tr> + <tr> + <th>投诉类型:</th> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$data['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <th>投诉内容:</th> + <td class='line-break'>{$data['complainContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + + <td id="photos-complain"> + {volist name="$data['complainAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}?x-oss-process=image/resize,w_300,h_300" /> + </a> + {/volist} + </td> + + </tr> + <tr> + <th>投诉时间:</th> + <td>{$data['complainTime']}</td> + </tr> + </table> + + + {if condition="$data['needRespond'] eq 1 AND $data['respondContent'] neq ''"} + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>应诉信息</td> + </tr> + <tr> + <th width='80'>应诉内容:</th> + <td class='line-break'>{$data['respondContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + <td> + <div id="respondAnnex"> + {volist name="$data['respondAnnex']" id="annex2"} + <a href="javascript:void(0)"><img class='lazyImg' src="__IMGURL__/{$annex2}" layer-src="__IMGURL__/{$annex2}" height="100" width="100"/></a> + {/volist} + </div> + </td> + </tr> + <tr> + <th>应诉时间:</th> + <td>{$data['respondTime']}</td> + </tr> + </table> + {/if} + <table border='0' class='wst-complain-detail' style='margin-top:15px;'> + <tr> + <td colspan='2' class='head'>仲裁结果</td> + </tr> + <tr> + <th width='80'>仲裁结果:</th> + <td> + {if condition="$data['complainStatus'] eq 0"} + 等待处理 + {elseif condition="$data['complainStatus'] eq 1"/} + 等待应诉人回应 + {elseif condition="$data['complainStatus'] eq 2 OR $data['complainStatus'] eq 3"/} + 等待仲裁 + {elseif condition="$data['complainStatus'] eq 4"/} + 已仲裁 + {/if} + </td> + </tr> + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th valign='top'>仲裁结果:</th> + <td class='line-break'> + {$data['finalResult']} + </td> + </tr> + {/if} + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th>仲裁时间:</th> + <td>{$data['finalResultTime']}&nbsp;</td> + </tr> + {/if} + <tr> + <td colspan='2' style='text-align:center;'><a href="javascript:history.go(-1)" class="s-btn">返回</a></td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + // 调用图像层 + layer.photos({ + photos: '#photos-complain' + }); + layer.photos({ + photos: '#respondAnnex' + }); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_complain.html b/hyhproject/home2/view/default/shops/orders/list_complain.html new file mode 100755 index 0000000..5eaff2c --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_complain.html @@ -0,0 +1,71 @@ +{extend name="default/shops/base" /} +{block name="title"}查看投诉 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<style> +.wst-order-list tbody td{ + text-align: center; +} +.wst-order-list tbody tr{ + line-height: 30px; +} +</style> + <div class="wst-shop-head"><span>投诉订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-query" id='orderNo'/> + <a class="s-btn" onclick="complainByPage()">查询</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单编号</th> + <th>投诉方</th> + <th>投诉原因</th> + <th>投诉时间</th> + <th>投诉状态</th> + <th>操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + {{d[i]['orderNo']}} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </td> + + <td>{{WST.blank(d[i]['userName'],d[i]['loginName'])}}</td> + + <td title="{{d[i]['complainContent']}}">{{WST.cutStr(d[i]['complainContent'],50)}}</td> + + <td>{{d[i]['complainTime']}}</td> + + <td>{{d[i]['complainStatus']}}</td> + + <td> + <a style="cursor:pointer;" onclick="toView({{d[i]['complainId']}})">查看</a> + {{# if(d[i]['needReply']==1){ }}<a style="cursor:pointer;" onclick="toRespond({{d[i]['complainId']}})">应诉</a>{{# } }} + </td> + + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + complainByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_delivered.html b/hyhproject/home2/view/default/shops/orders/list_delivered.html new file mode 100755 index 0000000..0679d1c --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_delivered.html @@ -0,0 +1,161 @@ +{extend name="default/shops/base" /} +{block name="title"}已发货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>已发货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="deliveredByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,1,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].payType==1){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}} + </span> + {{# } }} + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum >0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice >0){ }} + <span class="order_je">ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div>{{d[i].status}} </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + <div><a href='#none' onclick='javascript:updateDeliver({{d[i].orderId}})'>【修改运单号】</a></div> + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='deliverBox' style='display:none'> + <form id='deliverForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>快递公司:</th> + <td> + <select id='expressId'> + <option value=''>请选择</option> + {volist name="$express" id='vo'} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>快递号:</th> + <td><input type='text' id='expressNo' name="expressNo" maxLength='20' style='width:80%'></td> + </tr> + </table> + </form> + </div> + + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + deliveredByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_failure.html b/hyhproject/home2/view/default/shops/orders/list_failure.html new file mode 100755 index 0000000..db54f84 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_failure.html @@ -0,0 +1,135 @@ +{extend name="default/shops/base" /} +{block name="title"}取消/拒收订单 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>取消/拒收订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="failureByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,10000,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].payType==1){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div>{{d[i].status}}</div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:{{d[i].goodsMoney}}</div> + <div class='line'>运费:{{d[i].deliverMoney}}</div> + <div>实付金额:{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{# if(WST.blank(d[i].refundId)!=''){ }} + <div><a href='javascript:void(0)' onclick='refund({{d[i].refundId}})'>【退款操作】</a></div> + {{# } }} + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + </tbody> + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='failureBox' style='display:none'> + <form id='failureForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>不同意原因:</th> + <td> + <textarea id='content' style='width:90%;height:100px;' maxLength='200'></textarea> + </td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){failureByPage();}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_finished.html b/hyhproject/home2/view/default/shops/orders/list_finished.html new file mode 100755 index 0000000..230e8a6 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_finished.html @@ -0,0 +1,144 @@ +{extend name="default/shops/base" /} +{block name="title"}已收货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>已收货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="finisedByPage()">查询</a> + <a class="s-btn" style='margin-top:0px;line-height:15px;height:16px;float: right;' onclick="javascript:toExport(2,2,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row {{#if(d[i].isAppraise==0){}}j-warn{{#} }}"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from"> + {{d[i].orderCodeTitle}} + </span> + {{# } }} + + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum >0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice >0){ }} + <span class="order_je">ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div>{{d[i].status}}</div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].isAppraise==1){}} + <div style="text-align:center;">已评价</div> + {{#}else{}} + <div style="text-align:center;">未评价</div> + {{#}}} + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + </tbody> + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker"> + 【用户留言】{{d[i].orderRemarks}} + </div> + {{# } }} + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + finisedByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_wait_delivery.html b/hyhproject/home2/view/default/shops/orders/list_wait_delivery.html new file mode 100755 index 0000000..3661c82 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_wait_delivery.html @@ -0,0 +1,202 @@ +{extend name="default/shops/base" /} +{block name="title"}待发货订单 - 卖家中心{__block__}{/block} +{block name="css"} +<style> +.notice{padding: 3px 6px;color: #e55454} +.notice_icon{vertical-align: text-bottom;} + .order_p{ float: left;} + .order_sl{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} + .order_je{margin-left: 10px;color: #fff;border: 1px solid red;padding: 2px 4px;border-radius: 10px;background-color: #FF247A;} +</style> +{/block} +{block name="content"} + <div class="wst-shop-head"><span>待发货订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="waitDivleryByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,0,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'> + 订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].noticeDeliver==1){ }} + <span class="notice"> + <img class="notice_icon" src="__STYLE__/img/nocite_deliver.png" alt="发货提醒" width="20" height="20" /> + 尽快发货 + </span> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}} + </span> + {{# } }} + </div> + <div class="order_p"> + {{# if(d[i].orderEctNum > 0){ }} + <span class="order_sl">ECT支付数量:{{d[i].orderEctNum}}</span> + {{# } }} + <!-- ECT支付数量:{{d[i].orderEctNum}} --> + {{# if(d[i].ectPrice > 0){ }} + <span class="order_je">下单ECT金额:{{d[i].ectPrice}}</span> + {{# } }} + </div> + <div> + {{d[i].status}} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + + <tr class='goods-box'> + <td> + + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + <div><a href='#none' onclick='javascript:deliver({{d[i].orderId}},{{d[i].deliverType}})'>【发货】</a></div> + <div><a target='blank' href='{{WST.U("home/orders/orderPrint","id="+d[i].orderId)}}'>【打印订单】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【用户留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='deliverBox' style='display:none'> + <form id='deliverForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='80'>快递公司:</th> + <td> + <select id='expressId'> + <option value=''>请选择</option> + {volist name="$express" id='vo'} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>快递号:</th> + <td><input type='text' id='expressNo' maxLength='20' style='width:80%'></td> + </tr> + </table> + </form> + </div> + <div id='editMoneyBox' style='display:none'> + <form id='newOrderForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='120'>订单号:</th> + <td><span id='m_orderNo'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_goodsMoney'></span></td> + </tr> + <tr> + <th>运费:</th> + <td>¥<span id='m_deliverMoney'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_totalMoney'></span></td> + </tr> + <tr> + <th>实际支付价格:</th> + <td>¥<span id='m_realTotalMoney' class='j-warn-order-money'></span></td> + </tr> + <tr> + <th>新价格:</th> + <td><input type='text' id='m_newOrderMoney' maxLength='10' style='width:150px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'></td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waitDivleryByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/list_wait_pay.html b/hyhproject/home2/view/default/shops/orders/list_wait_pay.html new file mode 100755 index 0000000..b04c9b3 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/list_wait_pay.html @@ -0,0 +1,167 @@ +{extend name="default/shops/base" /} +{block name="title"}待付款订单 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-shop-head"><span>待付款订单</span></div> + <div class='wst-shop-tbar'> + 订单号:<input type='text' class="s-ipt" id='orderNo'/> + 支付方式:<select name="payType" id="payType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">货到付款</option> + <option value="1">在线支付</option> + </select> + + 配送方式:<select name="deliverType" id="deliverType" class="s-ipt"> + <option value="-1">请选择</option> + <option value="0">送货上门</option> + <option value="1">自提</option> + </select> + + <a class="s-btn" onclick="waituserPayByPage()">查询</a> + <a class="s-btn" style="float: right;line-height:16px;height:16px;margin-top:2px;" onclick="javascript:toExport(2,-2,'')">导出</a> + </div> + <div class='wst-shop-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div> + {{#if(d[i].payType==1){}} + {{# if(d[i].isPay==1){}}已支付 + {{# }else{ }} + 等待支付 + {{# } }} + {{#}else{}} + 等待发货 + {{#} }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + + </td> + {{# if(j==0){ }} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverTypeName}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].payType==1 && d[i].isPay==0){}} + <div><a href='#none' onclick='editOrderMoney({{d[i].orderId}})'>【修改价格】</a></div> + {{#}}} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <tr> + <td colspan="4"> + <p class="order_remaker">【用户留言】{{d[i].orderRemarks}}</p> + </td> + </tr> + {{# } }} + + + </tbody> + + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + <div id='editMoneyBox' style='display:none'> + <form id='newOrderForm' autocomplete='off'> + <table class='wst-form wst-box-top'> + <tr> + <th width='120'>订单号:</th> + <td><span id='m_orderNo'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_goodsMoney'></span></td> + </tr> + <tr> + <th>运费:</th> + <td>¥<span id='m_deliverMoney'></span></td> + </tr> + <tr> + <th>商品总价格:</th> + <td>¥<span id='m_totalMoney'></span></td> + </tr> + <tr> + <th>实际支付价格:</th> + <td>¥<span id='m_realTotalMoney' class='j-warn-order-money'></span></td> + </tr> + <tr> + <th>新价格:</th> + <td><input type='text' id='m_newOrderMoney' maxLength='10' style='width:150px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'></td> + </tr> + </table> + </form> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waituserPayByPage(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/orders/orders.js b/hyhproject/home2/view/default/shops/orders/orders.js new file mode 100755 index 0000000..af5d461 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/orders.js @@ -0,0 +1,423 @@ +function waituserPayByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waituserPayByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waituserPayByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waituserPayByPage(e.curr); + } + } + }); + } + }); +} +function waitDivleryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waitDeliveryByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitDivleryByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waitDivleryByPage(e.curr); + } + } + }); + } + }); +} +function deliveredByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/deliveredByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitDivleryByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + deliveredByPage(e.curr); + } + } + }); + } + }); +} +function editOrderMoney(id){ + var ll = WST.load({msg:'正在加载记录,请稍候...'}); + $.post(WST.U('home/orders/getMoneyByOrder'),{id:id},function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status>0 && json.data){ + var tmp = json.data; + $('#m_orderNo').html(tmp.orderNo); + $('#m_goodsMoney').html(tmp.goodsMoney); + $('#m_deliverMoney').html(tmp.deliverMoney); + $('#m_totalMoney').html(tmp.totalMoney); + $('#m_realTotalMoney').html(tmp.realTotalMoney); + WST.open({type: 1,title:"修改订单价格",shade: [0.6, '#000'],border: [0], + content: $('#editMoneyBox'),area: ['550px', '320px'],btn: ['确定','取消'], + yes:function(index, layero){ + var newOrderMoney = $('#m_newOrderMoney').val(); + WST.confirm({content:'您确定修改后的订单价格为¥<span class="j-warn-order-money">'+newOrderMoney+'</span>吗?',yes:function(cf){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/editOrderMoney'),{id:id,orderMoney:newOrderMoney},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#newOrderMoney').val(); + WST.msg(json.msg,{icon:1}); + waituserPayByPage(WSTCurrPage); + layer.close(cf); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + } + }); + } + }); +} +function deliver(id,deliverType){ + if(deliverType==1){ + WST.confirm({content:"您确定用户已提货了吗?", yes:function(tips){ + var ll = WST.load('数据处理中,请稍候...'); + $.post(WST.U('home/orders/deliver'),{id:id,expressId:0,expressNo:''},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(tips); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); + }else{ + WST.open({type: 1,title:"请输入发货快递信息",shade: [0.6, '#000'], border: [0], + content: $('#deliverBox'),area: ['350px', '180px'],btn: ['确定发货','取消'], + yes:function(index, layero){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/deliver'),{id:id,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#deliverForm')[0].reset(); + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); + } +} + +function updateDeliver(orderId){ + WST.open({type: 1,title:"请输入修改快递信息",shade: [0.6, '#000'], border: [0], + content: $('#deliverBox'),area: ['350px', '180px'],btn: ['确定修改','取消'], + yes:function(index, layero){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/updateDeliver'),{orderId:orderId,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#deliverForm')[0].reset(); + WST.msg(json.msg,{icon:1}); + waitDivleryByPage(WSTCurrPage); + layer.close(index); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + + +function finisedByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/finishedByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + $('.order_remaker').remove(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + finisedByPage(e.curr); + } + } + }); + } + }); +} +function failureByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-ipt'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/failureByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + $('.order_remaker').remove(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + failureByPage(e.curr); + } + } + }); + } + }); +} +function refund(id){ + var ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/orders/toShopRefund'),{id:id},function(data){ + layer.close(ll); + var w = WST.open({ + type: 1, + title:"退款操作", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['500px', '320px'], + btn: ['提交', '关闭窗口'], + yes: function(index, layero){ + var params = {}; + params.refundStatus = $('#refundStatus1')[0].checked?1:-1; + params.content = $.trim($('#shopRejectReason').val()); + params.id = id; + if(params.refundStatus==-1 && params.content==''){ + WST.msg('请输入不同意原因',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/orderrefunds/shoprefund'),params,function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + layer.close(w); + failureByPage(WSTCurrPage); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + }); +} +function view(id){ + location.href=WST.U('home/orders/view','id='+id); +} + + +/********** 订单投诉列表 ***********/ +function toView(id){ + location.href=WST.U('home/ordercomplains/getShopComplainDetail',{'id':id}); +} +function toRespond(id){ + location.href=WST.U('home/ordercomplains/respond',{'id':id}); +} + +function complainByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/ordercomplains/queryShopComplainByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data){ + var json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + complainByPage(e.curr); + } + } + }); + } + }); +} + + +/************ 应诉页面 ************/ +function respondInit(){ +$('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + // 调用图像层 + layer.photos({ + photos: '#photos-complain' + }); + + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'complains',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='respond_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#picBox').append(tdiv); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +function saveRespond(historyURL){ + $('#respondForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var img = []; + $('.respond_pic').each(function(){ + img.push($(this).attr('v')); + }); + params.respondAnnex = img.join(','); + $.post(WST.U('home/orderComplains/saveRespond'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('您的应诉已提交,请留意信息回复', {icon: 6},function(){ + location.href = WST.U('home/ordercomplains/shopComplain'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +//导出订单 +function toExport(typeId,status,type){ + var params = {}; + params = WST.getParams('.s-ipt'); + params.typeId = typeId; + params.orderStatus = status; + params.type = type; + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('home/orders/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/orders/print.html b/hyhproject/home2/view/default/shops/orders/print.html new file mode 100755 index 0000000..c408d16 --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/print.html @@ -0,0 +1,110 @@ +<!doctype html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>订单打印 - {:WSTConf('CONF.mallName')}</title> +</head> +<style> +body{font-size:13px;} +td,th{padding:2px;} +</style> +<body> +<table width='100%' border='0'> + <tr> + <td colspan='8' style='text-align:center;font-weight:bold;font-size:26px'>订单信息</td> + </tr> + <tr> + <td width='100' align="right">下单时间:</td> + <td width='250'>{$object['createTime']}</td> + <td width='100' align="right">支付方式:</td> + <td width='250'>{:WSTLangPayType($object['payType'])}</td> + <td width='100' align="right">订单编号:</td> + <td width='250'>{$object['orderNo']}</td> + </tr> + <tr> + <td width='100' align="right">发货时间:</td> + <td>{$object['deliveryTime']}</td> + <td width='100' align="right">配送方式:</td> + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + <td width='100' align="right">快递单号:</td> + <td>{$object['expressNo']}</td> + </tr> + {if $object['invoiceClient'] !=''} + <tr> + <td width='100' align="right">发票抬头:</td> + <td colspan="6">{$object['invoiceClient']}</td> + </tr> + {/if} + {if ($object['orderType']==0)} + <tr> + <td width='100' align="right">收货地址:</td> + <td colspan="6">{$object['userName']}&nbsp;|&nbsp;{$object['userPhone']}&nbsp;|&nbsp;{$object['userAddress']}</td> + </tr> + {/if} + {if $object['orderRemarks']!=''} + <tr> + <td width='100' align="right">订单备注:</td> + <td colspan="6">{$object['orderRemarks']}</td> + </tr> + {/if} +</table> +<table width='100%' border='1' style='border-collapse:collapse;border-color:#000;'> + <tr style='background:#cccccc;'> + <th align="left">商品名称</th> + <th align="left">商品规格</th> + <th align="left" align="left">商品价格</th> + <th align="left">商品数量</th> + <th align="left">小计</th> + </tr> + {volist name='$object["goods"]' id='vo2'} + <tr> + <td>{$vo2["goodsName"]}</td> + <td> + {if $vo2['goodsType']==1 && $object['orderStatus']==2} + <table width='100%'> + {volist name='$vo2["extraJson"]' id='vgcard'} + <tr> + <td>卡券号:{$vgcard['cardNo']}</td> + <td>卡券密码:{$vgcard['cardPwd']}</td> + </tr> + {/volist} + </table> + {else} + {:str_replace('@@_@@',';',$vo2["goodsSpecNames"])}&nbsp; + {/if} + </td> + <td>¥{$vo2['goodsPrice']}</td> + <td>{$vo2['goodsNum']}</td> + <td>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</td> + </tr> + {/volist} + </table> + <table width='100%' border='0'> + <tr> + <td colspan='6' align="right">商品总金额:¥{$object['goodsMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">运费:¥{$object['deliverMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">应付金额:¥{$object['totalMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">积分抵扣金额:¥-{$object['scoreMoney']}</td> + </tr> + <tr> + <td colspan='6' align="right">实付金额:¥{$object['realTotalMoney']}</td> + </tr> +</table> +<br/> +<table width='100%'> + <tr> + <td>商家:{$object['shopName']}&nbsp;&nbsp;&nbsp;电话:{$object['shopTel']}</td> + <td align="right">打印时间:{:date('Y-m-d H:i:s')}</td> + </tr> +</table> +</body> +<script> +window.print(); +</script> +</html> diff --git a/hyhproject/home2/view/default/shops/orders/respond.html b/hyhproject/home2/view/default/shops/orders/respond.html new file mode 100755 index 0000000..3c25e3d --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/respond.html @@ -0,0 +1,113 @@ +{extend name="default/shops/base" /} +{block name="title"}应诉 - 卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<style> +.webuploader-pick { + background: #f7375c; + height:30px; +} +</style> + <div class="wst-shop-head"><span>应诉</span></div> + + <div class='wst-shop-content'> + <form id="respondForm" method="post" > + <div style='width:990px;overflow:hidden;'> + <input type='hidden' id='complainId' class='ipt' value="{$data['complainId']}"/> + <div class='wst-complain-left'> + <div class='wst-complain-order-head'>订单商品</div> + <div class='wst-complain-order-goods'> + {volist name="$data['goodsList']" id="goods" key='key2'} + <a target='_blank' href="{:Url('Home/Goods/Detail',array('id'=>$goods['goodsId']))}" title="{$goods['goodsName']}"> + <img data-original="__IMGURL__/{$goods['goodsImg']}" height="55" width="55" class='gImg'/> + </a> + {/volist} + </div> + <div class='wst-complain-order-head'>订单信息</div> + <div class='wst-complain-order-info'> + <dl> + <dt>订单编号:</dt> + <dd>{$data['orderNo']}</dd> + <dt>订单金额:</dt> + <dd>¥{$data['realTotalMoney']}</dd> + <dt>运&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;费:</dt> + <dd>¥{$data['deliverMoney']}</dd> + <dt>下单时间:</dt> + <dd>{$data['createTime']}</dd> + <dt>商&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;家:</dt> + <dd>{$data['shopName']}</dd> + </dl> + </div> + </div> + <div class='wst-complain-main'> + <div class='wst-complain-order-head' style='width:735px;'>投诉信息</div> + <div class='wst-complain-box'> + <table width='100%'> + <tr> + <td width='70' align='right'>投诉类型:</td> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$data['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <td align='right'>详情:</td> + <td class='line-break'>{$data['complainContent']}</td> + </tr> + <tr> + <td align='right'>附件:</td> + <td> + <div id="photos-complain"> + {if !empty($data['complainAnnex'])} + {volist name="$data['complainAnnex']" id="annex"} + <img class='lazyImg' layer-src="__IMGURL__/{$annex}" data-original="__IMGURL__/{$annex}" src="__IMGURL__/{$annex}" height="100" width="100"/> + {/volist} + {/if} + </div> + </td> + </tr> + </table> + </div> + <div class='wst-complain-order-head' style='width:735px;'>应诉信息</div> + <div class='wst-complain-box'> + <table width='100%'> + <tr> + <td> + <textarea id='respondContent' name="respondContent" class='ipt' autocomplete="off" style='width:700px;height:162px;' placeholder='请输入应诉内容' data-rule='应诉内容:required;' data-target='#msg_respondContent'></textarea><br/> + <div class='msg-box' id='msg_respondContent'></div> + </td> + </tr> + <tr> + <td> + <div id="filePicker" style='margin-left:0px;overflow:hidden;height:25px;magin-left:5px;'>上传附件(最多5张)</div> + </td> + </tr> + <tr> + <td> + <div id='picBox' style='height:120px;width:710px;padding:5px;'> + </td> + </tr> + </table> + </div> + </div> + <div class='wst-complain-footer'> + <a href="javascript:saveRespond()" class="s-btn">提交</a> + <a href="javascript:location.href='{:url('home/ordercomplains/shopComplain')}'" class="s-btn">返回</a> + </div> + </div> + </form> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){ + respondInit(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/shops/orders/view.html b/hyhproject/home2/view/default/shops/orders/view.html new file mode 100755 index 0000000..f20525a --- /dev/null +++ b/hyhproject/home2/view/default/shops/orders/view.html @@ -0,0 +1,247 @@ +{extend name="default/shops/base" /} +{block name="title"}订单详情 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>订单详情</span><a href="javascript:history.go(-1)">返回</a></div> +<div class='wst-shop-content'> + <div class='order-box'> + <div class='box-head'>日志信息</div> + {if in_array($object['orderStatus'],[-2,0,1,2])} + <div class='log-box'> +<div class="state"> +{if $object['payType']==1} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{else} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">················></div> +{/if} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==0)"}icon43 {/if}"></span></div> +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> +</div> + <div class="state2"> + <div class="path"> + {volist name="$object['log']" id="lo"} + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + {/volist} + </div> + <p>下单</p>{if $object['payType']==1}<p>等待支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + </div> + <div class="wst-clear"></div> + </div> + {else} + <div> + <table class='log'> + {volist name='$object["log"]' id='vo'} + <tr> + <td>{$vo['logTime']}</td> + <td>{$vo['logContent']}</td> + </tr> + {/volist} + </table> + </div> + {/if} + </div> + <!-- 订单信息 --> + <div class='order-box'> + <div class='box-head'>订单信息</div> + <table class='wst-form'> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>支付方式:</th> + <td>{:WSTLangPayType($object['payType'])}</td> + </tr> + {if($object['payType']==1 && $object['isPay']==1)} + <tr> + <th>支付时间:</th> + <td>{$object['payTime']}</td> + </tr> + <tr> + <th>支付信息:</th> + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + </tr> + {/if} + <tr> + <th>配送方式:</th> + <td> + {:WSTLangDeliverType($object['deliverType'])} + </td> + </tr> + {if $object['expressNo']!=''} + <tr> + <th>快递公司:</th> + <td>{$object['expressName']}</td> + </tr> + <tr> + <th>快递号:</th> + <td>{$object['expressNo']}</td> + </tr> + {/if} + <tr> + <th>买家留言:</th> + <td>{$object['orderRemarks']}</td> + </tr> + </table> + </div> + {:hook('homeDocumentOrderView',['orderId'=>$object['orderId']])} + + {if $object['isRefund']==1} + <!-- 退款信息 --> + <div class='order-box'> + <div class='box-head'>退款信息</div> + <table class='wst-form'> + <tr> + <th width='100'>退款金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th width='100'>退款备注:</th> + <td>{$object['refundRemark']}</td> + </tr> + <tr> + <th>退款时间:</th> + <td>{$object['refundTime']}</td> + </tr> + </table> + </div> + {/if} + <!-- 发票信息 --> + <div class='order-box'> + <div class='box-head'>发票信息</div> + <table class='wst-form'> + <tr> + <th width='100'>是否需要发票:</th> + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + </tr> + {if $object['isInvoice']==1} + {php}$invoiceArr = json_decode($object['invoiceJson'],true);{/php} + <tr> + <th>发票抬头:</th> + <td> + {if $object['isInvoice']==1} + {$invoiceArr['invoiceHead']} + {/if} + </td> + </tr> + {if isset($invoiceArr['invoiceCode'])} + <tr> + <th>发票税号:</th> + <td> + {$invoiceArr['invoiceCode']} + </td> + </tr> + {/if} + {/if} + </table> + </div> + <!-- 收货人信息 --> + {if ($object['orderType']==0)} + <div class='order-box'> + <div class='box-head'>收货人信息</div> + <table class='wst-form'> + <tr> + <th width='100'>收货人:</th> + <td>{$object['userName']}</td> + </tr> + <tr> + <th>收货地址:</th> + <td>{$object['userAddress']}</td> + </tr> + <tr> + <th>联系方式:</th> + <td>{$object['userPhone']}</td> + </tr> + </table> + </div> + {/if} + <!-- 商品信息 --> + <div class='order-box'> + <div class='box-head'>商品清单</div> + <div class='goods-head'> + <div class='goods'>商品</div> + <div class='number'>商品编号</div> + <div class='price'>单价</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + </div> + <div class='goods-item'> + <div class='shop'> + {$object['shopName']} + {if $object['shopQQ'] !=''} + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style='vertical-align:middle;' src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $object['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" style='vertical-align:middle;' src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + <div class='goods-list'> + {volist name='$object["goods"]' id='vo2'} + {:hook('homeDocumentOrderViewGoodsPromotion',['goods'=>$vo2])} + <div class='item j-g{$vo2['goodsId']}'> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{if $vo2['goodsCode']=='gift'}【赠品】{/if}{$vo2["goodsName"]}</div> + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + </div> + <div class="number">{$vo2['goodsSn']}</div> + <div class='price'>¥{$vo2['goodsPrice']}</div> + <div class='num'>{$vo2['goodsNum']}</div> + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + <div class='wst-clear'></div> + </div> + {if $vo2['goodsType']==1 && $object['orderStatus']==2} + <table width='100%' style='margin-top:5px;'> + {volist name='$vo2["extraJson"]' id='vgcard'} + <tr> + <td>卡券号:{$vgcard['cardNo']}</td> + <td>卡券密码:{$vgcard['cardPwd']}</td> + </tr> + {/volist} + </table> + {/if} + {/volist} + </div> + </div> + <div class='goods-footer'> + <div class='goods-summary' style='text-align:right'> + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + <div class='summary line'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + <div class='summary'>积分抵扣金额:¥-<span>{$object['scoreMoney']}</span></div> + {if condition="$object['useScore'] gt 0"} + <div class='summary '>使用积分数:<span>{$object['useScore']}个</span></div> + {/if} + {:hook('homeDocumentOrderSummaryView',['order'=>$object])} + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home2/view/default/shops/recharge/pay_step1.html b/hyhproject/home2/view/default/shops/recharge/pay_step1.html new file mode 100755 index 0000000..acd7a17 --- /dev/null +++ b/hyhproject/home2/view/default/shops/recharge/pay_step1.html @@ -0,0 +1,72 @@ +{extend name="default/shops/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-shop-head"><span>充值</span></div> +<div class='wst-shop-content'> + <div class='pay-sbox'> + <div> + <div> + <div class='wst-tips-box'> + <div class='icon'></div> + <div class='tips'> + 1.充值金额和赠送金额只能用于购买商品,不能提现;<br/> + </div> + <div style="clear:both"></div> + </div> + </div> + <div class="wst-form"> + <div class="pay-type">充值金额 + <div> + <div class="wst-list-box"> + {volist name="chargeItems" id="item"} + <div class="wst-frame2 {$key} " onclick="javascript:changeSelected({$item['id']},'itmeId',this)"> + {if condition="$item['giveMoney'] gt 0"} + <div class='charge-doub'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + <div>送 {$item['giveMoney']} 元</div> + {else/} + <div class='charge-alone'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + {/if} + <i></i> + </div> + {/volist} + <div class="wst-frame2 " onclick="javascript:changeSelected(0,'itmeId',this)"> + <div class='charge-alone'> + <span class="j-charge-other">其他金额</span> + <span class="j-charge-money"><input class="charge-othermoney j-ipt" id="needPay" value="1" maxlength="10" data-rule="充值金额:required;" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)" maxlength="8"></span> + </div> + <i></i> + </div> + <input type="hidden" value="" id='itmeId' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + + </div> + </div> + </div><div></div> + <div> + + <div class="pay-type">选择支付方式</div> + <div class="pay-list"> + <input type="hidden" id="payCode" name="payCode" /> + {volist name="payments" id="payment"} + {if condition="$payment['isOnline'] eq 1"} + <div class="wst-payCode-{$payment['payCode']}" data="{$payment['payCode']}"></div> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + <div class="bnt-box"> + <div onclick='javascript:getPayUrl();' class="wst-pay-bnt"></div> + </div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/recharge/recharge.js?v={$v}'></script> +{/block} + diff --git a/hyhproject/home2/view/default/shops/recharge/pay_step2.html b/hyhproject/home2/view/default/shops/recharge/pay_step2.html new file mode 100755 index 0000000..28fe02d --- /dev/null +++ b/hyhproject/home2/view/default/shops/recharge/pay_step2.html @@ -0,0 +1,53 @@ + +{extend name="default/shops/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='wst-user-content'> + + <div class="pay-sbox-head"> + <div class="wst-shop-head"><span>充值</span></div> + </div> + <div style="padding-top: 27px;"> + <div class="pay-tip2"></div> + </div> + <div class='pay-sbox' > + <div class="qrcode-box"> + <div class="pbox"> + 请您扫描以下二维码,钱包充值金额:<span class="wst-fred">¥{$needPay}</span> + </div> + <div style="" class="wst-qrcode"></div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> + {if condition="$out_trade_no != '' and $code_url!=''"} + var qr = qrcode(10, 'M'); + qr.addData("{$code_url}"); + qr.make(); + $(".wst-qrcode").html(qr.createImgTag()); + + {/if} + setInterval(function(){ + var params = {}; + params.trade_no = "{$out_trade_no}"; + + $.ajax({ + url:"{:url('home/weixinpays/getPayStatus')}", + data:params, + type:"POST", + dataType:"json", + success:function(data){ + if(data.status==1){ + location.href = "{:url('home/logmoneys/shopmoneys')}"; + } + } + }); + },1500); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/recharge/recharge.js b/hyhproject/home2/view/default/shops/recharge/recharge.js new file mode 100755 index 0000000..4e74c4d --- /dev/null +++ b/hyhproject/home2/view/default/shops/recharge/recharge.js @@ -0,0 +1,58 @@ + +function getPayUrl(){ + var params = {}; + params.payObj = "recharge"; + params.targetType = 1; + params.needPay = $.trim($("#needPay").val()); + params.payCode = $.trim($("#payCode").val()); + params.itmeId = $.trim($("#itmeId").val()); + if(params.itmeId==0 && params.needPay<=0){ + WST.msg('请输入充值金额', {icon: 5}); + return; + } + if(params.payCode==""){ + WST.msg('请先选择支付方式', {icon: 5}); + return; + } + jQuery.post(WST.U('home/'+params.payCode+'/get'+params.payCode+"URL"),params,function(data) { + var json = WST.toJson(data); + if(json.status==1){ + location.href = json.url; + }else{ + WST.msg('充值失败', {icon: 5}); + } + }); +} + +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + if(n==0){ + $(".j-charge-other").hide(); + $(".j-charge-money").show(); + + }else{ + $(".j-charge-other").show(); + $(".j-charge-money").hide(); + } + inEffect(obj,2); +} +$(function(){ + $(".wst-frame2:first").click(); + $("#wst-check-orders").click(function(){ + $("#wst-orders-box").slideToggle(600); + }); + $("div[class^=wst-payCode]").click(function(){ + var payCode = $(this).attr("data"); + $("div[class^=wst-payCode]").each(function(){ + $(this).removeClass().addClass("wst-payCode-"+$(this).attr("data")); + }); + $(this).removeClass().addClass("wst-payCode-"+payCode+"-curr"); + $("#payCode").val(payCode); + }); + if($("div[class^=wst-payCode]").length>0){ + $("div[class^=wst-payCode]")[0].click(); + } +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/stat_orders.html b/hyhproject/home2/view/default/shops/reports/stat_orders.html new file mode 100755 index 0000000..7237575 --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/stat_orders.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}销售订单统计 - 卖家中心{__block__}{/block} +{block name="content"} +<style> +.wst-list tbody tr td {height: 35px;line-height: 35px;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>销售订单统计</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <div id='main' style='height:300px;width:99%'></div> + <table id='mainTable' class='wst-list hide' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100'>日期</th> + <th width='100'>取消订单</th> + <th width='130'>拒收订单</th> + <th width='130'>正常订单</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="stat-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + </td> + <td>{{ d[i].day }}</td> + <td>{{ d[i].o3 }}</td> + <td>{{ d[i].o1 }}</td> + <td>{{ d[i].ou }}</td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/stat_orders.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/stat_orders.js b/hyhproject/home2/view/default/shops/reports/stat_orders.js new file mode 100755 index 0000000..9ead9d0 --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/stat_orders.js @@ -0,0 +1,103 @@ +function loadStat(){ + var loading = WST.load({msg:'正在查询数据,请稍后...'}); + $.post(WST.U('home/reports/getStatOrders'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + y: 'top', + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar', 'tiled']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + legend: { + data:['取消订单','拒收订单','正常订单'] + }, + xAxis : [ + { + type : 'category', + splitLine : {show : false}, + data : json.data.days + } + ], + yAxis : [ + { + type : 'value', + position: 'right' + } + ], + series : [ + { + name:'取消订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['-1'] + }, + { + name:'拒收订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['-3'] + }, + { + name:'正常订单', + type:'line', + tooltip : {trigger: 'item'}, + stack: '类型', + data:json.data['1'] + }, + { + name:'订单总数', + type:'line', + data:json.data['total'] + }, + { + name:'订单类型细分', + type:'pie', + tooltip : { + trigger: 'item', + formatter: '{a} <br/>{b} : {c} ({d}%)' + }, + center: [160,130], + radius : [0, 50], + itemStyle : { + normal : { + labelLine : { + length : 20 + } + } + }, + data:[ + {value:json.data.map['-3'], name:'取消订单'}, + {value:json.data.map['-1'], name:'拒收订单'}, + {value:json.data.map['1'], name:'正常订单'}, + ] + } + ] + }; + myChart.setOption(option); + var gettpl = document.getElementById('stat-tblist').innerHTML; + laytpl(gettpl).render(json.data.list, function(html){ + $('#list-box').html(html); + $('#mainTable').show(); + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/stat_sales.html b/hyhproject/home2/view/default/shops/reports/stat_sales.html new file mode 100755 index 0000000..fceab61 --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/stat_sales.html @@ -0,0 +1,49 @@ +{extend name="default/shops/base" /} +{block name="title"}销售额统计 - 卖家中心{__block__}{/block} +{block name="content"} +<style> +.wst-list tbody tr td {height: 35px;line-height: 35px;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>销售额统计</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + 支付方式:<select id='payType' class='j-ipt'> + <option value='-1'>全部</option> + <option value='0'>货到付款</option> + <option value='1'>在线支付</option> + </select> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <div id='main' style='height:300px;width:99%'></div> + <table id='mainTable' class='wst-list hide' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100'>日期</th> + <th width='100'>订单数</th> + <th width='130'>销售额</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="stat-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + </td> + <td>{{ d[i].day }}</td> + <td>{{ d[i].num }}</td> + <td>¥{{ d[i].val }}</td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/echarts/echarts.min.js?v={$v}" type="text/javascript"></script> +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/stat_sales.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/stat_sales.js b/hyhproject/home2/view/default/shops/reports/stat_sales.js new file mode 100755 index 0000000..2fb394c --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/stat_sales.js @@ -0,0 +1,54 @@ +function loadStat(){ + var loading = WST.load({msg:'正在查询数据,请稍后...'}); + $.post(WST.U('home/reports/getStatSales'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + var myChart = echarts.init(document.getElementById('main')); + myChart.clear(); + $('#mainTable').hide(); + if(json.status=='1' && json.data){ + var option = { + tooltip : { + trigger: 'axis' + }, + toolbox: { + show : true, + feature : { + mark : {show: true}, + dataView : {show: false, readOnly: false}, + magicType : {show: true, type: ['line', 'bar']}, + restore : {show: true}, + saveAsImage : {show: true} + } + }, + calculable : true, + xAxis : [ + { + type : 'category', + data : json.data.days + } + ], + yAxis : [ + { + type : 'value' + } + ], + series : [ + { + name:'销售额', + type:'line', + data:json.data.dayVals + } + ] + }; + myChart.setOption(option); + var gettpl = document.getElementById('stat-tblist').innerHTML; + laytpl(gettpl).render(json.data.list, function(html){ + $('#list-box').html(html); + $('#mainTable').show(); + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/top_sale_goods.html b/hyhproject/home2/view/default/shops/reports/top_sale_goods.html new file mode 100755 index 0000000..9ae845a --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/top_sale_goods.html @@ -0,0 +1,46 @@ +{extend name="default/shops/base" /} +{block name="title"}商品销售排行 - 卖家中心{__block__}{/block} + +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>商品销售排行</span></div> +<div class='wst-shop-tbar'> + 日期:<input type='text' class="laydate-icon j-ipt" id='startDate' onclick="laydate()" value='{$startDate}'/>至 + <input type='text' class="laydate-icon j-ipt" id='endDate' onclick="laydate()" value='{$endDate}'/> + <a class="s-btn" onclick="loadStat()">查询</a> +</div> +<div class='wst-shop-content'> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;&nbsp;</th> + <th width='100' colspan="2">商品</th> + <th width='130'>商品编号</th> + <th width='100'>销量</th> + </tr> + </thead> + <tbody id='list-box'></tbody> + <script id="top-sale-tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{(i+1)}}</td> + <td> + <div class='goods-img'> + <a target='_blank' href='{{WST.U("home/goods/detail","id="+d[i].goodsId)}}'> + <img class='j-lazyGoodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div></td> + <td>{{ d[i].goodsName }}</td> + <td>{{ d[i].goodsSn }}</td> + <td>{{ d[i].goodsNum}}</td> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script src="__STATIC__/plugins/layer/laydate.js"></script> +<script type='text/javascript' src='__STYLE__/shops/reports/top_sale_goods.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/reports/top_sale_goods.js b/hyhproject/home2/view/default/shops/reports/top_sale_goods.js new file mode 100755 index 0000000..c206a30 --- /dev/null +++ b/hyhproject/home2/view/default/shops/reports/top_sale_goods.js @@ -0,0 +1,16 @@ +function loadStat(){ + var load = WST.load({msg:'正在加载数据,请稍后...'}) + $.post(WST.U('home/reports/getTopSaleGoods'),WST.getParams('.j-ipt'),function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1' && json.data){ + var gettpl = document.getElementById('top-sale-tblist').innerHTML; + laytpl(gettpl).render(json.data, function(html){ + $('#list-box').html(html); + $('.j-lazyGoodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + }else{ + WST.msg('没有查询到记录',{icon:5}); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/settlements/list.html b/hyhproject/home2/view/default/shops/settlements/list.html new file mode 100755 index 0000000..77940ee --- /dev/null +++ b/hyhproject/home2/view/default/shops/settlements/list.html @@ -0,0 +1,166 @@ +{extend name="default/shops/base" /} +{block name="title"}订单结算 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li id="wst-msg-li-0">结算信息<span style="display:none;"></span></li> + <li id="wst-msg-li-1">未结算订单<span style="display:none;"></span></li> + <li id="wst-msg-li-2">已结算订单<span style="display:none;"></span></li> + </ul> + <div class="wst-tab-content" style='width:98%;'> + <div class='wst-tab-item'> + <div> + 结算单号:<input type="text" id="settlementNo_0" style='width:120px;' autocomplete="off"/> + 结算状态:<select id='isFinish_0' autocomplete="off"> + <option value='-1'>全部</option> + <option value='0'>未结算</option> + <option value='1'>已结算</option> + </select> + <a class='s-btn' onclick="getQueryPage(0)">查询</a> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;</th> + <th width='100'>结算单号</th> + <th width='40'>类型</th> + <th width='60'>结算金额</th> + <th width='80'>结算佣金</th> + <th width='80'>返还金额</th> + <th width='130'>创建时间</th> + <th width='60'>结算状态</th> + <th width='130'>结算时间</th> + <th width='*'>备注</th> + </tr> + </thead> + <script id="tblist0" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td><a style='color:blue' href='javascript:view("{{d[i].settlementId}}")'>{{d[i].settlementNo}}</a></td> + <td>{{# if(d[i].settlementType==1){ }}定时{{# }else{ }}手动{{# } }}</td> + <td>¥{{d[i].settlementMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + <td>¥{{d[i].backMoney}}</td> + <td>{{d[i].createTime}}</td> + <td>{{# if(d[i].settlementStatus==1){ }}已结算{{# }else{ }}未结算{{# } }}</td> + <td>{{WST.blank(d[i].settlementTime,'-')}}</td> + <td style='line-height:20px;'>{{WST.blank(d[i].remarks)}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody0"></tbody> + <tfoot> + <tr> + <td colspan='10' align='center' id="pager_0"></td> + </tr> + </tfoot> + </table> + </div> + {/** 待结算订单 **/} + <div class='wst-tab-item hide'> + <div> + 订单号:<input type="text" id="orderNo_1" style='width:120px;' autocomplete="off"/> + <a class='s-btn' onclick="getUnSettledOrderPage(0)">查询</a> + <!-- <a class='s-btn' style='width:110px;' onclick="settlement()">申请结算</a> --> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <!-- <th width='20'><input type='checkbox' onclick='WST.checkChks(this,".chk_1")'/></th> --> + <th width='100'>订单号</th> + <th width='130'>下单时间</th> + <th width='80'>支付方式</th> + <th width='80'>商品总金额</th> + <th width='70'>运费</th> + <th width='90'>订单总金额</th> + <th width='90'>实付金额</th> + <th width='70'>应付佣金</th> + </tr> + </thead> + <script id="tblist1" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <!-- <td><input type='checkbox' class='chk_1' value='{{d[i].orderId}}'/></td> --> + <td>{{d[i].orderNo}}</td> + <td>{{d[i].createTime}}</td> + <td>{{d[i].payTypeNames}}</td> + <td>¥{{d[i].goodsMoney}}</td> + <td>¥{{d[i].deliverMoney}}</td> + <td>¥{{d[i].totalMoney}}</td> + <td>¥{{d[i].realTotalMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody1"> + </tbody> + <tfoot> + <tr> + <td colspan='7' align='center' id="pager_1"></td> + </tr> + </tfoot> + </table> + + </div> + <div class='wst-tab-item hide'> + <div> + 结算单号:<input type="text" id="settlementNo_2" style='width:120px;' class="s-ipt" autocomplete="off"/> + 订单号:<input type="text" id="orderNo_2" style='width:120px;' class="s-ipt" autocomplete="off"/> + 结算状态:<select id='isFinish_2' class="s-ipt" autocomplete="off"> + <option value='-1'>全部</option> + <option value='0'>未结算</option> + <option value='1'>已结算</option> + </select> + <a class='s-btn' onclick="getSettleOrderPage(0)">查询</a> + <a class="s-btn" style='margin-top:0px;line-height:15px;height:16px;float: right;' onclick="javascript:toExport(0)">导出</a> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='20'>&nbsp;</th> + <th width='100'>订单号</th> + <th width='80'>支付方式</th> + <th width='70'>商品总金额</th> + <th width='70'>运费</th> + <th width='70'>订单总金额</th> + <th width='70'>实付金额</th> + <th width='70'>应付佣金</th> + <th width='70'>结算方式</th> + <th width='130'>结算单号</th> + <th width='130'>结算时间</th> + </tr> + </thead> + <script id="tblist2" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i].orderNo}}</td> + <td>{{d[i].payTypeNames}}</td> + <td>¥{{d[i].goodsMoney}}</td> + <td>¥{{d[i].deliverMoney}}</td> + <td>¥{{d[i].totalMoney}}</td> + <td>¥{{d[i].realTotalMoney}}</td> + <td>¥{{d[i].commissionFee}}</td> + <td>{{d[i].payName}}</td> + <td>{{d[i].settlementNo}}</td> + <td>{{WST.blank(d[i].settlementTime,'-')}}</td> + </tr> + {{# } }} + </script> + <tbody id="tbody2"></tbody> + <tfoot> + <tr> + <td colspan='9' align='center' id="pager_2"></td> + </tr> + </tfoot> + </table> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/settlements/settlements.js?v={$v}'></script> + +{/block} diff --git a/hyhproject/home2/view/default/shops/settlements/settlements.js b/hyhproject/home2/view/default/shops/settlements/settlements.js new file mode 100755 index 0000000..c051e66 --- /dev/null +++ b/hyhproject/home2/view/default/shops/settlements/settlements.js @@ -0,0 +1,134 @@ +$(function(){ + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:getQueryPage(0);break; + case 1:getUnSettledOrderPage(0);break; + case 2:getSettleOrderPage(0);break; + } + }}); +}); +function view(val){ + location.href=WST.U('home/settlements/view','id='+val); +} +function getQueryPage(p){ + var params = {}; + params.page = p; + params.settlementNo = $.trim($('#settlementNo_0').val()); + params.isFinish = $('#isFinish_0').val(); + $.post(WST.U('home/settlements/pageQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var json = json.data; + var gettpl = document.getElementById('tblist0').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody0').html(html); + }); + laypage({ + cont: 'pager_0', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getQueryPage(e.curr); + } + } + }); + } + }); +} +function settlement(){ + var ids = WST.getChks('.chk_1'); + if(ids.length==0){ + WST.msg('请选择要结算的订单!',{icon:2}); + return; + } + var load = WST.load({msg:'正在提交申请,请稍后...'}); + WST.confirm({content:'您确定要申请结算这些订单吗?',yes:function(){ + $.post(WST.U('home/settlements/settlement'),{ids:ids.join(',')},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + getUnSettledOrderPage(WSTCurrPage); + }); + }else{ + WST.msg(json.msg); + } + }); + }}); +} +function getUnSettledOrderPage(p){ + var params = {}; + params.page = p; + params.orderNo = $.trim($('#orderNo_1').val()); + $('#pager_1').empty(); + $.post(WST.U('home/settlements/pageUnSettledQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + getUnSettledOrderPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist1').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody1').html(html); + }); + laypage({ + cont: 'pager_1', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getUnSettledOrderPage(e.curr); + } + } + }); + } + }); +} +function getSettleOrderPage(p){ + var params = {}; + params.page = p; + params.orderNo = $.trim($('#orderNo_2').val()); + params.settlementNo = $.trim($('#settlementNo_2').val()); + params.isFinish = $.trim($('#isFinish_2').val()); + $('#pager_2').empty(); + $.post(WST.U('home/settlements/pageSettledQuery'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist2').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#tbody2').html(html); + }); + laypage({ + cont: 'pager_2', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + getSettleOrderPage(e.curr); + } + } + }); + } + }); +} +//导出订单 +function toExport(){ + var params = {}; + params.orderNo = $.trim($('#orderNo_2').val()); + params.settlementNo = $.trim($('#settlementNo_2').val()); + params.isFinish = $.trim($('#isFinish_2').val()); + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('home/settlements/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/settlements/view.html b/hyhproject/home2/view/default/shops/settlements/view.html new file mode 100755 index 0000000..8918e14 --- /dev/null +++ b/hyhproject/home2/view/default/shops/settlements/view.html @@ -0,0 +1,91 @@ +{extend name="default/shops/base" /} +{block name="title"}结算详情-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>结算详情</span><a href="<?=url('home/settlements/index');?>">返回</a></div> +<div class="wst-clear"></div> +<div class="wst-body"> + <form id='editform' autocomplete='off'> + <div class="wst-tab-item" style="position: relative;"> + <table class='wst-form'> + <tr> + <td class='head-ititle' colspan='2'>结算信息</td> + </tr> + <tr> + <th width='120'>结算单号:</th> + <td>{$object['settlementNo']}</td> + </tr> + <tr> + <th>结算金额:</th> + <td>¥{$object['settlementMoney']}</td> + </tr> + <tr> + <th>结算佣金:</th> + <td>¥{$object['commissionFee']}</td> + </tr> + <tr> + <th>返还金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th>申请时间:</th> + <td>{$object['createTime']}</td> + </tr> + <tr> + <th>结算状态:</th> + <td> + {if $object['settlementStatus']==1} + 已结算 + {else} + 待结算 + {/if} + </td> + </tr> + {if $object['settlementStatus']==1} + <tr> + <th>结算时间:</th> + <td>{$object['settlementTime']}</td> + </tr> + <tr> + <th>结算备注:</th> + <td>{$object['remarks']}</td> + </tr> + {/if} + <tr> + <td colspan='2' align="center"> + <table class='wst-list' style='margin-left:5px;'> + <thead> + <tr> + <th>序号</th> + <th>订单号</th> + <th>支付方式</th> + <th>商品金额</th> + <th>运费</th> + <th>订单总金额</th> + <th>积分抵扣</th> + <th>实付金额</th> + <th>佣金</th> + <th>下单时间</th> + </tr> + </thead> + {volist name='$object["list"]' id='vo'} + <tr> + <td>{$key+1}</td> + <td>{$vo['orderNo']}</td> + <td>{:WSTLangPayType($vo['payType'])}</td> + <td>¥{$vo['goodsMoney']}</td> + <td>¥{$vo['deliverMoney']}</td> + <td>¥{$vo['totalMoney']}</td> + <td>¥{$vo['scoreMoney']}</td> + <td>¥{$vo['realTotalMoney']}</td> + <td>¥{$vo['commissionFee']}</td> + <td>{$vo['createTime']}</td> + </tr> + {/volist} + </table> + </td> + </tr> + </table> + </div> + </form> +</div> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopcats/list.html b/hyhproject/home2/view/default/shops/shopcats/list.html new file mode 100755 index 0000000..4024fb2 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopcats/list.html @@ -0,0 +1,176 @@ +{extend name="default/shops/base" /} +{block name="title"}商品分类 - 卖家中心{__block__}{/block} +{block name="css"} +<!--mark 20180518 by zl--> +<meta http-equiv="Access-Control-Allow-Origin" content="*"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<!--end--> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>商品分类</span></div> +<div class="wst-clear"></div> + <div style='text-align:right;height: 36px;'> + <span></span> + <a href='javascript:addCat(1);' style='float:right;margin:9px 30px 0px 0px;'><img class="wst-lfloat" style="margin:-3px 5px 0px 0px;" src="__STYLE__/img/seller_icon_xz.png">新增</a> + </div> + <form autocomplete="off"> + <table id="cat_list_tab" class='wst-list wst-form'> + <thead> + <tr class="wst-colour"> + <th class="wst-fre-th">名称</th> + <th width='60'>排序号</th> + <th width='80' style="line-height: normal;">是否显示<br/><span style="font-weight:normal;color:red;">(双击可修改)</span></th> + <th width="150">操作</th> + </tr> + </thead> + {volist name="list" id="vo" key='i'} + <tbody> + <tr id='tr_{$i}' isLoad='1'> + <td class="wst-fre-td"> + <span class='wst-tree-open active' onclick='javascript:treeCatOpen(this,{$vo.catId})'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_zk.png"></span> + <input type='text' style='width:400px;' value='{$vo['catName']}' dataId="{$vo.catId}" onchange='javascript:editCatName(this)'/> + </td> + <td><input class='catsort' type='text' style='width:35px;' value="{$vo['catSort']}" dataId="{$vo.catId}" onchange='javascript:editCatSort(this)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + {if condition="$vo['isShow']==0 "} + <td style="cursor:pointer;" ondblclick="changeCatStatus(1,{$vo['catId']},0)"><span class='wst-state_no'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_error.png"></span></td> + {else/} + <td style="cursor:pointer;" ondblclick="changeCatStatus(0,{$vo['catId']},0)"><span class='wst-state_yes'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_right.png"></span></td> + {/if} + <td> + <a href="javascript:void(0);" onclick='javascript:addCat(this,{$vo["catId"]},{$i});' class='add btn' title='新增'>[新增]</a> + <a href="javascript:void(0);" onclick="javascript:delCat({$vo['catId']},0)" class='del btn' title='删除'>[删除]</a>&nbsp; + <!--mark 20180518 by zll--> + {if condition="$shopId eq 1"} + <a href="javascript:void(0);" onclick="javascript:setSpecial('{$vo['catId']}','{$vo['provId']}','{$vo['catImg']}','{$vo['isHot']}')" class='del btn' title='设为特产'>[设为特产]</a>&nbsp; + {/if} + <!--end--> + </td> + </tr> + {if isset($vo['childNum'])} + {if condition="$vo['childNum'] gt 0 "} + {volist name="vo['child']" id="vo2" key='i2'} + <tr id='tr_{$i}_{$i2}' class="tr_{$i} tree_{$vo.catId}" isLoad='1'> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <input type='text' style='width:400px;' value='{$vo2['catName']}' dataId="{$vo2.catId}" onchange='javascript:editCatName(this)'/> + </td> + <td><input class='catsort' type='text' style='width:35px;' value="{$vo2['catSort']}" dataId="{$vo2.catId}" onchange='javascript:editCatSort(this)' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/></td> + {if condition="$vo2['isShow']==0 "} + <td style="cursor:pointer;" onclick="changeCatStatus(1,{$vo2['catId']},{$vo['catId']})"><span class='wst-state_no'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_error.png"></span></td> + {else/} + <td style="cursor:pointer;" onclick="changeCatStatus(0,{$vo2['catId']},{$vo['catId']})"><span class='wst-state_yes'><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_right.png"></span></td> + {/if} + <td> + <a href="javascript:delCat({$vo2['catId']},0)" class='del btn' title='删除'>[删除]</a>&nbsp; + </td> + </tr> + {/volist} + {/if} + {/if} + </tbody> + {/volist} +</table> +</form> +<div class='wst-tbar-group' style='height: 76px;text-align: center'> + <button class='wst-shop-but hide' style='margin-top:40px;;width:80px;height: 30px;' type="button" onclick='javascript:batchSaveCats()'>保&nbsp;存</button> + <button class='wst-shop-but hide' style='margin-top:40px;margin-left:5px;width:80px;height: 30px;;' type="button" onclick='javascript:location.reload()'>取&nbsp;消</button> + <a style='float:right;margin:30px 30px 0px 0px;' href='javascript:addCat(1);'><img class="wst-lfloat" style="margin:-3px 5px 0px 0px;" src="__STYLE__/img/seller_icon_xz.png">新增</a> +</div> +</div> + + + +<script id="cat_p_tr" type="text/html"> +<tbody class='tbody_new'> + <tr class="tr_new" isload="1"> + <td class="wst-fre-td"> + <span class="wst-tree-open"><img class="wst-lfloat" style="margin-top:-3px;" src="__STYLE__/img/seller_icon_zk.png"></span> + <input class="catname" type="text" style="width:400px;height:22px;margin-left:6px;" dataid=""> + </td> + <td> + <input class="catsort" type="text" style="width:35px;" value="0" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"> + </td> + <td style="cursor:pointer;"> + <input class="catshow" type="checkbox" checked=""/> + </td> + <td> + <a href="javascript:void(0);" onclick="addCat(this,0,0);" class="add btn" title="新增">[新增]</a> + <a href="javascript:void(0);" class="del btn" title="删除" onclick="delCatObj(this,1)">[删除]</a>&nbsp; + </td> + </tr> +</tbody> +</script> + +<script id="cat_c_tr" type="text/html"> +<tr class="{{d.className}}" isload="1" catid="{{d.p}}"> + <td class="wst-fre-td"> + <span class="wst-tree-second"></span> + <input class="catname" type="text" style='width:400px' dataid=""> + </td> + <td> + <input class="catsort" type="text" style="width:35px;" value="0" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"> + </td> + <td style="cursor:pointer;"> + <input class="catshow" type="checkbox" checked=""/> + </td> + <td> + <a href="javascript:void(0);" class="del btn" title="删除" onclick="delCatObj(this,2)">[删除]</a>&nbsp; + </td> +</tr> +</script> + + +<!--模态框 mark 20180518 zll--> +<div id='shopcatsBox' style='display:none' class='layui-form'> + <form id='shopcatsForm' autocomplete="off"> + <table class='wst-form wst-box-top'> + <tr> + <th>特产省份<font color='red'>*</font>:</th> + <td> + <select name="provId" id="provId" class="ipt" > + <option value ='0'>--请选择--</option> + + {volist name="areas" id="vv"} + <option value="{$vv['areaId']}" >{$vv['areaName']}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th>分类图标<font color='red'>*</font>:</th> + <td> + <div id='catFilePicker'>上传图标</div><span id='uploadMsg'></span> + <input type='hidden' id='catImg' name="catImg" class="ipt" /> + </td> + </tr> + <tr> + <th>预览图:</th> + <td><div style="min-height:75px;" id="preview"></div></td> + </tr> + <tr> + <th>是否热门:</th> + <td> + <input type="checkbox" id="isHot" name="isHot" value="1" class="ipt" /> + </td> + </tr> + + </table> + </form> +</div> +<!--end--> + + +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} + <!--mark 20180518--> + <script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <!--end--> + <script type='text/javascript' src='__STYLE__/shops/shopcats/shopcats.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopcats/php/get.php b/hyhproject/home2/view/default/shops/shopcats/php/get.php new file mode 100755 index 0000000..2f040dd --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopcats/php/get.php @@ -0,0 +1,48 @@ +<?php + function gmt_iso8601($time) { + $dtStr = date("c", $time); + $mydatetime = new DateTime($dtStr); + $expiration = $mydatetime->format(DateTime::ISO8601); + $pos = strpos($expiration, '+'); + $expiration = substr($expiration, 0, $pos); + return $expiration."Z"; + } + + $id= 'LTAIOUxnwu01rA9g'; + $key= 'k0eigaxy8Gnz2V6AwcMNmwMSbQXsCf'; + $host = 'http://dianshanglian.oss-cn-beijing.aliyuncs.com'; + + $now = time(); + $expire = 30; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问 + $end = $now + $expire; + $expiration = gmt_iso8601($end); + $save_dir = $_GET['dir']; + $dir = 'upload/'.$save_dir."/".date('Y-m').'/'; + + //最大文件大小.用户可以自己设置 + $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000); + $conditions[] = $condition; + + //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录 + $start = array(0=>'starts-with', 1=>'$key', 2=>$dir); + $conditions[] = $start; + + + $arr = array('expiration'=>$expiration,'conditions'=>$conditions); + //echo json_encode($arr); + //return; + $policy = json_encode($arr); + $base64_policy = base64_encode($policy); + $string_to_sign = $base64_policy; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true)); + + $response = array(); + $response['accessid'] = $id; + $response['host'] = $host; + $response['policy'] = $base64_policy; + $response['signature'] = $signature; + $response['expire'] = $end; + //这个参数是设置用户上传指定的前缀 + $response['dir'] = $dir; + echo json_encode($response); +?> diff --git a/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js b/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js new file mode 100755 index 0000000..c49a542 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader╔╧┤лoss.js @@ -0,0 +1,401 @@ +function addCat(obj,p,catNo){ + var html = new Array(); + if(typeof(obj)=="number"){ + $("#cat_list_tab").append($("#cat_p_tr").html()); + }else{ + var className = (p==0)?"tr_c_new":"tr_"+catNo+" tr_0"; + var gettpl = $("#cat_c_tr").html(); + laytpl(gettpl).render({"className":className,"p":p}, function(html){ + $(obj).parent().parent().parent().append(html); + }); + } + $('.wst-shop-but').show(); +} + +function delCatObj(obj,vk){ + if(vk==1){ + $(obj).parent().parent().parent().remove(); + }else{ + $(obj).parent().parent().remove(); + } + if($(".tr_0").size()==0 && $(".tbody_new").size()==0)$('.wst-shop-but').hide(); +} + +function treeCatOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_sq.png">'); + $('.tree_'+id).hide(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_zk.png">'); + $('.tree_'+id).show(); + } +} + +function delCat(id){ + var box = WST.confirm({content:"您确定要删除该商品分类吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopcats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function batchSaveCats(){ + var params = {}; + var fristNo = 0; + var secondNo = 0; + $(".tbody_new").each(function(){ + secondNo = 0; + var pobj = $(this).find(".tr_new"); + params['catName_'+fristNo] = $.trim(pobj.find(".catname").val()); + if(params['catName_'+fristNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo] = pobj.find(".catsort").val(); + params['catShow_'+fristNo] = pobj.find(".catshow").prop("checked")?1:0 + $(this).find(".tr_c_new").each(function(){ + params['catId_'+fristNo+'_'+secondNo] = fristNo; + params['catName_'+fristNo+'_'+secondNo] = $.trim($(this).find(".catname").val()); + if(params['catName_'+fristNo+'_'+secondNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo+'_'+secondNo] = $(this).find(".catsort").val(); + params['catShow_'+fristNo+'_'+secondNo] = $(this).find(".catshow").prop("checked")?1:0 + params['catSecondNo_'+fristNo] = ++secondNo; + }); + params['fristNo'] = ++fristNo; + }); + var otherNo = 0; + $(".tr_0").each(function(){ + params['catId_o_'+otherNo] = $(this).attr('catId'); + params['catName_o_'+otherNo] = $.trim($(this).find(".catname").val()); + if(params['catName_o_'+otherNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_o_'+otherNo] = $(this).find(".catsort").val(); + params['catShow_o_'+otherNo] = $(this).find(".catshow").prop("checked")?1:0; + params['otherNo'] = ++otherNo; + }); + $.post(WST.U('home/shopcats/batchSaveCats'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('新增成功!', {icon: 1,time:500},function(){ + location.reload(); + }); + }else{ + WST.msg('新增失败!', {icon: 5}); + } + }); +} + + +function editCatName(obj){ + $.post(WST.U('home/shopcats/editName'),{"id":$(obj).attr('dataId'),"catName":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} +function editCatSort(obj){ + $.post(WST.U('home/shopcats/editSort'),{"id":$(obj).attr('dataId'),"catSort":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +function changeCatStatus(isShow,id,pid){ + var params = {}; + params.id = id; + params.isShow = isShow; + params.pid = pid; + $.post(WST.U('home/shopcats/changeCatStatus'),params,function(data,textStatus){ + location.reload(); + }); + +} + + + + +//mark 修改特产省份 20180518 by zll +var isInitUpload = false; +function setSpecial(catId,provId,catImg,isHot){ + if(provId>0)$('#provId').val(provId); + if(catImg !=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+catImg+'" height="75px" />'); + $('#catImg').val(catImg); + }else{ + $('#preview').html(''); + $('#catImg').val(''); + }; + (isHot==1)?$('#isHot').prop('checked',true):$('#isHot').prop('checked',false); + if(!isInitUpload)initUpload(); + var box = layer.open({ + type:1, + title:'设置特产省份', + btn:['设置','消除特产','取消'], + content:$('#shopcatsBox'), + area:['400px','500px'], + + yes:function(){ + var params = WST.getParams('.ipt'); + params.provName = $('#provId option:selected').text(); + params.catId = catId; + if(params.provId == '0'){ + layer.msg('请选择省份'); + return false; + } + if(params.catImg==''){ + layer.msg('请选择图片'); + return false; + } + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + window.parent.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + btn2:function(){ + var params = {}; + params.catId = catId; + params.provName=''; + params.provId = '0'; + params.isHot = '0'; + params.catImg = ''; + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + + }); +} +// function initUpload(){ +// isInitUpload = true; +// //文件上传 +// WST.upload({ +// pick:'#catFilePicker', +// formData: {dir:'shopcats'}, +// accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, +// callback:function(f){ +// var json = WST.toJson(f); +// if(json.status==1){ +// $('#uploadMsg').empty().hide(); +// //将上传的图片路径赋给全局变量 +// $('#catImg').val(json.savePath+json.thumb); +// $('#preview').html('<img src="'+WST.conf.ROOT+'/'+json.savePath+json.thumb+'" height="75" />'); +// }else{ +// WST.msg(json.msg,{icon:2}); +// } +// }, +// progress:function(rate){ +// $('#uploadMsg').show().html('已上传'+rate+"%"); +// } +// }); +// } +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + // 'success_action_status' : '200', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + function initUpload(){ + + isInitUpload = true; + //文件上传 + uploader = new WebUploader.create({ + pick:'#catFilePicker', + auto: true, + swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf', + server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com', + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + + }); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + // uploader.on('uploadBeforeSend', function(obj,data, headers) { + // // console.log(obj.file); + // set_upload_param(uploader,obj.file.name,true); + + // }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function(file,response) { + console.log(response); + + pic_name = get_uploaded_object_name(file.name) + console.log(pic_name); + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(pic_name); + $('#preview').html('<img src="http://img.juzi199.com/'+pic_name+'" height="75"/>'); + + }); + uploader.on('uploadError', function( file ) { + console.log(2222); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + // console.log(file); + rate = percentage.toFixed(2)*100; + $('#uploadMsg').show().html('已上传'+rate+"%"); + }); +} + +//end \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader鈺斺暓鈹ば籵ss.js b/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader鈺斺暓鈹ば籵ss.js new file mode 100755 index 0000000..c49a542 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopcats/shopcats webuploader鈺斺暓鈹ば籵ss.js @@ -0,0 +1,401 @@ +function addCat(obj,p,catNo){ + var html = new Array(); + if(typeof(obj)=="number"){ + $("#cat_list_tab").append($("#cat_p_tr").html()); + }else{ + var className = (p==0)?"tr_c_new":"tr_"+catNo+" tr_0"; + var gettpl = $("#cat_c_tr").html(); + laytpl(gettpl).render({"className":className,"p":p}, function(html){ + $(obj).parent().parent().parent().append(html); + }); + } + $('.wst-shop-but').show(); +} + +function delCatObj(obj,vk){ + if(vk==1){ + $(obj).parent().parent().parent().remove(); + }else{ + $(obj).parent().parent().remove(); + } + if($(".tr_0").size()==0 && $(".tbody_new").size()==0)$('.wst-shop-but').hide(); +} + +function treeCatOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_sq.png">'); + $('.tree_'+id).hide(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_zk.png">'); + $('.tree_'+id).show(); + } +} + +function delCat(id){ + var box = WST.confirm({content:"您确定要删除该商品分类吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopcats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function batchSaveCats(){ + var params = {}; + var fristNo = 0; + var secondNo = 0; + $(".tbody_new").each(function(){ + secondNo = 0; + var pobj = $(this).find(".tr_new"); + params['catName_'+fristNo] = $.trim(pobj.find(".catname").val()); + if(params['catName_'+fristNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo] = pobj.find(".catsort").val(); + params['catShow_'+fristNo] = pobj.find(".catshow").prop("checked")?1:0 + $(this).find(".tr_c_new").each(function(){ + params['catId_'+fristNo+'_'+secondNo] = fristNo; + params['catName_'+fristNo+'_'+secondNo] = $.trim($(this).find(".catname").val()); + if(params['catName_'+fristNo+'_'+secondNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo+'_'+secondNo] = $(this).find(".catsort").val(); + params['catShow_'+fristNo+'_'+secondNo] = $(this).find(".catshow").prop("checked")?1:0 + params['catSecondNo_'+fristNo] = ++secondNo; + }); + params['fristNo'] = ++fristNo; + }); + var otherNo = 0; + $(".tr_0").each(function(){ + params['catId_o_'+otherNo] = $(this).attr('catId'); + params['catName_o_'+otherNo] = $.trim($(this).find(".catname").val()); + if(params['catName_o_'+otherNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_o_'+otherNo] = $(this).find(".catsort").val(); + params['catShow_o_'+otherNo] = $(this).find(".catshow").prop("checked")?1:0; + params['otherNo'] = ++otherNo; + }); + $.post(WST.U('home/shopcats/batchSaveCats'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('新增成功!', {icon: 1,time:500},function(){ + location.reload(); + }); + }else{ + WST.msg('新增失败!', {icon: 5}); + } + }); +} + + +function editCatName(obj){ + $.post(WST.U('home/shopcats/editName'),{"id":$(obj).attr('dataId'),"catName":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} +function editCatSort(obj){ + $.post(WST.U('home/shopcats/editSort'),{"id":$(obj).attr('dataId'),"catSort":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +function changeCatStatus(isShow,id,pid){ + var params = {}; + params.id = id; + params.isShow = isShow; + params.pid = pid; + $.post(WST.U('home/shopcats/changeCatStatus'),params,function(data,textStatus){ + location.reload(); + }); + +} + + + + +//mark 修改特产省份 20180518 by zll +var isInitUpload = false; +function setSpecial(catId,provId,catImg,isHot){ + if(provId>0)$('#provId').val(provId); + if(catImg !=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+catImg+'" height="75px" />'); + $('#catImg').val(catImg); + }else{ + $('#preview').html(''); + $('#catImg').val(''); + }; + (isHot==1)?$('#isHot').prop('checked',true):$('#isHot').prop('checked',false); + if(!isInitUpload)initUpload(); + var box = layer.open({ + type:1, + title:'设置特产省份', + btn:['设置','消除特产','取消'], + content:$('#shopcatsBox'), + area:['400px','500px'], + + yes:function(){ + var params = WST.getParams('.ipt'); + params.provName = $('#provId option:selected').text(); + params.catId = catId; + if(params.provId == '0'){ + layer.msg('请选择省份'); + return false; + } + if(params.catImg==''){ + layer.msg('请选择图片'); + return false; + } + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + window.parent.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + btn2:function(){ + var params = {}; + params.catId = catId; + params.provName=''; + params.provId = '0'; + params.isHot = '0'; + params.catImg = ''; + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + + }); +} +// function initUpload(){ +// isInitUpload = true; +// //文件上传 +// WST.upload({ +// pick:'#catFilePicker', +// formData: {dir:'shopcats'}, +// accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, +// callback:function(f){ +// var json = WST.toJson(f); +// if(json.status==1){ +// $('#uploadMsg').empty().hide(); +// //将上传的图片路径赋给全局变量 +// $('#catImg').val(json.savePath+json.thumb); +// $('#preview').html('<img src="'+WST.conf.ROOT+'/'+json.savePath+json.thumb+'" height="75" />'); +// }else{ +// WST.msg(json.msg,{icon:2}); +// } +// }, +// progress:function(rate){ +// $('#uploadMsg').show().html('已上传'+rate+"%"); +// } +// }); +// } +accessid = ''; +accesskey = ''; +host = ''; +policyBase64 = ''; +signature = ''; +callbackbody = ''; +filename = ''; +key = ''; +expire = 0; +g_object_name = ''; +g_object_name_type = ''; +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'test'; + +function send_request() +{ + var xmlhttp = null; + if (window.XMLHttpRequest) + { + xmlhttp=new XMLHttpRequest(); + } + else if (window.ActiveXObject) + { + xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp!=null) + { + // serverUrl = './php/get.php?dir='+dir + xmlhttp.open( "GET", "http://localhost/oss/get.php?dir="+dir, false ); + xmlhttp.send( null ); + return xmlhttp.responseText + } + else + { + alert("Your browser does not support XMLHTTP."); + } +}; + +// function check_object_radio() { +// var tt = document.getElementsByName('myradio'); +// for (var i = 0; i < tt.length ; i++ ) +// { +// if(tt[i].checked) +// { +// g_object_name_type = tt[i].value; +// break; +// } +// } +// } + +function get_signature() +{ + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) + { + body = send_request(); + var obj = eval ("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) { +  len = len || 32; +  var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; +  var maxPos = chars.length; +  var pwd = ''; +  for (i = 0; i < len; i++) { +   pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) +{ + + suffix = get_suffix(filename); + g_object_name = key + random_string(10) + suffix; + return ''; +} + +function get_uploaded_object_name(filename) +{ + + return g_object_name; + +} + +function set_upload_param(up, filename, ret) +{ + if (ret == false) + { + ret = get_signature(); + } + g_object_name = key; + if (filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key' : g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId':accessid , + // 'success_action_status' : '200', //让服务端返回200,不然,默认会返回204 + 'callback' : callbackbody, + 'signature': signature, + }; + up.option('server',host); + up.option('formData',new_multipart_params); + console.log(up.option()); + up.upload(); +} + function initUpload(){ + + isInitUpload = true; + //文件上传 + uploader = new WebUploader.create({ + pick:'#catFilePicker', + auto: true, + swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf', + server:'http://heyuanhui.oss-cn-qingdao.aliyuncs.com', + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + + }); + uploader.on('beforeFileQueued',function(file){ + set_upload_param(uploader,'',false); + }); + // uploader.on('uploadBeforeSend', function(obj,data, headers) { + // // console.log(obj.file); + // set_upload_param(uploader,obj.file.name,true); + + // }); + uploader.on('uploadStart',function(file){ + set_upload_param(uploader,file.name,true); + }); + uploader.on('uploadSuccess', function(file,response) { + console.log(response); + + pic_name = get_uploaded_object_name(file.name) + console.log(pic_name); + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(pic_name); + $('#preview').html('<img src="http://img.juzi199.com/'+pic_name+'" height="75"/>'); + + }); + uploader.on('uploadError', function( file ) { + console.log(2222); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + // console.log(file); + rate = percentage.toFixed(2)*100; + $('#uploadMsg').show().html('已上传'+rate+"%"); + }); +} + +//end \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopcats/shopcats.js b/hyhproject/home2/view/default/shops/shopcats/shopcats.js new file mode 100755 index 0000000..291cc95 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopcats/shopcats.js @@ -0,0 +1,228 @@ +function addCat(obj,p,catNo){ + var html = new Array(); + if(typeof(obj)=="number"){ + $("#cat_list_tab").append($("#cat_p_tr").html()); + }else{ + var className = (p==0)?"tr_c_new":"tr_"+catNo+" tr_0"; + var gettpl = $("#cat_c_tr").html(); + laytpl(gettpl).render({"className":className,"p":p}, function(html){ + $(obj).parent().parent().parent().append(html); + }); + } + $('.wst-shop-but').show(); +} + +function delCatObj(obj,vk){ + if(vk==1){ + $(obj).parent().parent().parent().remove(); + }else{ + $(obj).parent().parent().remove(); + } + if($(".tr_0").size()==0 && $(".tbody_new").size()==0)$('.wst-shop-but').hide(); +} + +function treeCatOpen(obj,id){ + if( $(obj).attr('class').indexOf('active') > -1 ){ + $(obj).removeClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_sq.png">'); + $('.tree_'+id).hide(); + }else{ + $(obj).addClass('active'); + $(obj).html('<img class="wst-lfloat" style="margin-top:-3px;" src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_zk.png">'); + $('.tree_'+id).show(); + } +} + +function delCat(id){ + var box = WST.confirm({content:"您确定要删除该商品分类吗?",yes:function(){ + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopcats/del'),{id:id},function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + layer.close(box); + location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + + +function batchSaveCats(){ + var params = {}; + var fristNo = 0; + var secondNo = 0; + $(".tbody_new").each(function(){ + secondNo = 0; + var pobj = $(this).find(".tr_new"); + params['catName_'+fristNo] = $.trim(pobj.find(".catname").val()); + if(params['catName_'+fristNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo] = pobj.find(".catsort").val(); + params['catShow_'+fristNo] = pobj.find(".catshow").prop("checked")?1:0 + $(this).find(".tr_c_new").each(function(){ + params['catId_'+fristNo+'_'+secondNo] = fristNo; + params['catName_'+fristNo+'_'+secondNo] = $.trim($(this).find(".catname").val()); + if(params['catName_'+fristNo+'_'+secondNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_'+fristNo+'_'+secondNo] = $(this).find(".catsort").val(); + params['catShow_'+fristNo+'_'+secondNo] = $(this).find(".catshow").prop("checked")?1:0 + params['catSecondNo_'+fristNo] = ++secondNo; + }); + params['fristNo'] = ++fristNo; + }); + var otherNo = 0; + $(".tr_0").each(function(){ + params['catId_o_'+otherNo] = $(this).attr('catId'); + params['catName_o_'+otherNo] = $.trim($(this).find(".catname").val()); + if(params['catName_o_'+otherNo]==''){ + WST.msg('请输入商品分类名称!', {icon: 5}); + return; + } + params['catSort_o_'+otherNo] = $(this).find(".catsort").val(); + params['catShow_o_'+otherNo] = $(this).find(".catshow").prop("checked")?1:0; + params['otherNo'] = ++otherNo; + }); + $.post(WST.U('home/shopcats/batchSaveCats'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('新增成功!', {icon: 1,time:500},function(){ + location.reload(); + }); + }else{ + WST.msg('新增失败!', {icon: 5}); + } + }); +} + + +function editCatName(obj){ + $.post(WST.U('home/shopcats/editName'),{"id":$(obj).attr('dataId'),"catName":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} +function editCatSort(obj){ + $.post(WST.U('home/shopcats/editSort'),{"id":$(obj).attr('dataId'),"catSort":obj.value},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!',{icon: 1,time:500}); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +} + +function changeCatStatus(isShow,id,pid){ + var params = {}; + params.id = id; + params.isShow = isShow; + params.pid = pid; + $.post(WST.U('home/shopcats/changeCatStatus'),params,function(data,textStatus){ + location.reload(); + }); + +} + + + + +//mark 修改特产省份 20180518 by zll +var isInitUpload = false; +function setSpecial(catId,provId,catImg,isHot){ + if(provId>0)$('#provId').val(provId); + if(catImg !=''){ + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+catImg+'" height="75px" />'); + $('#catImg').val(catImg); + }else{ + $('#preview').html(''); + $('#catImg').val(''); + }; + (isHot==1)?$('#isHot').prop('checked',true):$('#isHot').prop('checked',false); + if(!isInitUpload)initUpload(); + var box = layer.open({ + type:1, + title:'设置特产省份', + btn:['设置','消除特产','取消'], + content:$('#shopcatsBox'), + area:['400px','500px'], + + yes:function(){ + var params = WST.getParams('.ipt'); + params.provName = $('#provId option:selected').text(); + params.catId = catId; + if(params.provId == '0'){ + layer.msg('请选择省份'); + return false; + } + if(params.catImg==''){ + layer.msg('请选择图片'); + return false; + } + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + layer.close(box); + window.parent.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + btn2:function(){ + var params = {}; + params.catId = catId; + params.provName=''; + params.provId = '0'; + params.isHot = '0'; + params.catImg = ''; + $.post(WST.U('home/shopcats/setSpecial'),params,function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,{icon:1}); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}) + } + }); + }, + + }); +} +function initUpload(){ + isInitUpload = true; + //文件上传 + WST.upload({ + pick:'#catFilePicker', + formData: {dir:'shopcats'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + //将上传的图片路径赋给全局变量 + $('#catImg').val(json.savePath+json.thumb); + $('#preview').html('<img src="'+WST.conf.IMGURL+'/'+json.savePath+json.thumb+'" height="75" />'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} + +//end \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.html b/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.html new file mode 100755 index 0000000..89656f9 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.html @@ -0,0 +1,163 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺设置-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/batchupload.css?v={$v}" /> +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<script> +$(function(){ + $('.state-complete').css('border-color','#ddd'); +}) +</script> +<style> +.filelist .btn-del,.webuploader-pick,.wst-batchupload .placeholder .webuploader-pick,.wst-batchupload .statusBar .btns .uploadBtn{background: #e45050;} +.wst-batchupload .statusBar .btns .uploadBtn:hover {background: #e45525 none repeat scroll 0 0;} +.shopbanner{position: relative;} +.del-banner{position: absolute;top:0px;right:0px;background: #e45050 none repeat scroll 0 0 z-index: 55;color: #ffffff;cursor: pointer;height: 18px;line-height: 18px;padding: 0 5px;} +.wst-batchupload .filelist li{background:#ffffff;} +</style> +<div class="wst-body"> +<div class="wst-shop-head"><span>店铺设置</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + + <form name="shopCfg" id="shopCfg" autocomplete="off"> + + + <table class="wst-form"> + <tr> + <th width='120' align='right'>店铺SEO关键字<font color='red'>*</font>:</th> + <td><input type='text' id='shopKeywords' name='shopKeywords' class="ipt" value='{$object.shopKeywords}' data-rule='关键字:required;' style='width:350px;' maxLength='25' /></td> + </tr> + <tr> + <th width='120'>店铺SEO描述:</th> + <td colspan='3'> + <textarea rows="2" style='width:350px;' class="ipt" id='shopDesc' name='shopDesc' >{$object.shopDesc}</textarea> + </td> + </tr> + <tr> + <th width='120'>店铺热搜关键词:</th> + <td><input type='text' id='shopHotWords' name='shopHotWords' class="ipt" value='{$object.shopHotWords}' style='width:350px;' placeholder="店铺主页搜索栏下的引导搜索词" maxLength='100'/></td> + </tr> + + + <tr style="height:80px"> + <th width='120' align='right' valign='top'>店铺街背景:</th> + <td> + <div id="shopStreetImgPicker" style='margin-left:0px;margin-top:5px;height:30px;overflow:hidden'>上传(首页)店铺街背景图片</div> + <div>图片大小:228 x 138 (px)(格式为 gif, jpg, jpeg, png)</div> + <div style="margin-top:5px;"> + <div class="wst-lfloat shopbanner" {if empty($object.shopStreetImg)}style='display:none'{/if}> + <img id="shopStreetImgPreview" class="lazyImg" height="100" style="max-width:500px;" src="__IMGURL__/{$object.shopStreetImg}"> + <span class="del-banner" onclick="delShopStreetBg(this)">删除</span> + </div> + <input type="hidden" id="shopStreetImg" class="ipt" value="{$object.shopStreetImg}" /> + </div> + </td> + </tr> + + + <tr style="height:80px"> + <th width='120' align='right' valign='top'>顶部广告:</th> + <td> + <div id="shopBannerPicker" style='margin-left:0px;margin-top:5px;height:30px;overflow:hidden'>上传顶部广告图片</div> + <div>图片大小:1920 x 110 (px)(格式为 gif, jpg, jpeg, png)</div> + <div style="margin-top:5px;"> + <div class="wst-lfloat shopbanner" {if empty($object.shopBanner)}style='display:none'{/if}> + <img id="shopBannerPreview" class="lazyImg" height="100" style="max-width:500px;" src="__IMGURL__/{$object.shopBanner}"> + <span class="del-banner" onclick="delbanner(this)">删除</span> + </div> + <input type="hidden" id="shopBanner" class="ipt" value="{$object.shopBanner}" /> + </div> + </td> + </tr> + + + + <tr> + <th width='120' align='right'>滚动广告<font color='red'>*</font>:</th> + <td> + + <div id="batchUpload" class="wst-batchupload" style="border:1px solid #ccc"> + <div style="border-bottom:1px solid #dadada;padding-left:10px; "> 图片大小:1200 x 400 (px)(格式为 gif, jpg, jpeg, png) </div> + <div class="queueList filled"> + <div id="dndArea" class="placeholder {if !empty($object['shopAds'])}element-invisible{/if}"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选5张,每张最大不超过5M</p> + </div> + <ul class="filelist" > + {volist name="$object['shopAds']" id="vo"} + <li class="state-complete" style="border: 1px solid #ddd;height:213px;"> + <p class="title"></p> + <p class="imgWrap"> + <img src="__IMGURL__/{$vo}"> + </p> + <input type="hidden" v="{$vo}" iv="{$vo}" class="j-gallery-img"> + <span class="btn-del">删除</span> + <input class="cfg-img-url" type="text" value="{$object['shopAdsUrl'][$key]}" style="width:170px;" placeholder="广告路径"> + </li> + {/volist} + </ul> + </div> + <div class="statusBar" > + <div class="progress" style="display: none;"> + <span class="text">0%</span> + <span class="percentage" style="width: 0%;"></span> + </div> + <div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + + <div style='clear:both;'></div> + </td> + </tr> + + <tr> + <td colspan='2' style='text-align:center;padding:20px;'> + <a class='s-btn' href="javascript:save()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='javascript:location.reload();'>重&nbsp;置</a> + </td> + </tr> + </table> + + </form> + + + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shopconfigs/shop_cfg.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/batchupload.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ +}) +function delbanner(obj){ + var c = WST.confirm({content:'您确定要删除顶部广告图片吗?',yes:function(){ + $('#shopBannerPreview').attr('src',''); + $('#shopBanner').val(''); + $(obj).hide(); + layer.close(c); + }}) + } +function delShopStreetBg(obj){ + var c = WST.confirm({content:'您确定要删除店铺街背景图片吗?',yes:function(){ + $('#shopStreetImgPreview').attr('src',''); + $('#shopStreetImg').val(''); + $(obj).hide(); + layer.close(c); + }}) +} +</script> + +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.js b/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.js new file mode 100755 index 0000000..a2f32c5 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopconfigs/shop_cfg.js @@ -0,0 +1,124 @@ +function save(){ +/* 表单验证 */ +$('#shopCfg').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + // 图片路径 + var shopAds = []; + $('.j-gallery-img').each(function(){ + shopAds.push($(this).attr('v')); + }); + params.shopAds = shopAds.join(','); + // 图片轮播广告路径 + var shopAdsUrl = []; + $('.cfg-img-url').each(function(){ + shopAdsUrl.push($(this).val()); + }); + params.shopAdsUrl = shopAdsUrl.join(','); + + var loading = WST.load({msg:'正在提交数据,请稍后...'}); + + $.post(WST.U('home/shopconfigs/editShopCfg'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); +} + + + + + +$(function(){ + //店铺顶部广告图上传 + WST.upload({ + pick:'#shopBannerPicker', + formData: {dir:'shopconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var shopbanner = json.savePath+json.thumb; //保存到数据库的路径 + $('#shopBanner').val(shopbanner); + $('#shopBannerPreview').parent().show(); + $('.del-banner').show(); + $('#shopBannerPreview').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.thumb); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + + // 店铺街背景图上传 + WST.upload({ + pick:'#shopStreetImgPicker', + formData: {dir:'shopconfigs'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + var shopbanner = json.savePath+json.thumb; //保存到数据库的路径 + $('#shopStreetImg').val(shopbanner); + $('#shopStreetImgPreview').parent().show(); + $('.del-banner').show(); + $('#shopStreetImgPreview').attr('src',WST.conf.IMGURL+'/'+json.savePath+json.thumb); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + +/********** 轮播广告图片上传 **********/ +var uploader = batchUpload({uploadPicker:'#batchUpload',uploadServer:WST.U('home/index/uploadPic'),formData:{dir:'shopconfigs'},uploadSuccess:function(file,response){ + var json = WST.toJson(response); + if(json.status==1){ + $li = $('#'+file.id); + $li.append('<input type="hidden" class="j-gallery-img" iv="'+json.savePath + json.thumb+'" v="' +json.savePath + json.name+'"/>'); + var delBtn = $('<span class="btn-del">删除</span>'); + $li.append(delBtn); + $li.append('<input class="cfg-img-url" type="text" value="" style="width:170px;" placeholder="广告路径">' ); + $li.css('height','212px'); + $li.find('.success').remove(); + delBtn.on('click',function(){ + delBatchUploadImg($(this),function(){ + uploader.removeFile(file); + uploader.refresh(); + }); + }); + $('.filelist li').css('border','1px solid #f7375c'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }}); +// 删除广告图片 +$('.btn-del').click(function(){ + delBatchUploadImg($(this),function(){ + $(this).parent().remove(); + }); + }) + +function delBatchUploadImg(obj){ + var c = WST.confirm({content:'您确定要删除广告图片吗?',yes:function(){ + $(obj).parent().remove("li"); + layer.close(c); + }}); +} + + +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shoproles/edit.html b/hyhproject/home2/view/default/shops/shoproles/edit.html new file mode 100755 index 0000000..1a55437 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shoproles/edit.html @@ -0,0 +1,86 @@ +{extend name="default/shops/base" /} +{block name="title"}角色管理-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} + +<div class="wst-body"> +<div class="wst-shop-head"><span>角色管理</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + {php}$homeMenus = WSTHomeMenus(1);{/php} + <form name="shoprole" id="shoprole" autocomplete="off"> + <table class="wst-form"> + <tr> + <th width='120' align='right'>角色名称<font color='red'>*</font>:</th> + <td> + <input type='hidden' id='id' name='id' class="ipt" value='{$object.id}' /> + <input type='text' id='roleName' name='roleName' class="ipt" value='{$object.roleName}' data-rule='请输入角色名称:required;' style='width:350px;' maxLength='25' /> + <span>设定角色名称,方便区分权限类型。</span> + </td> + </tr> + <tr> + <th width='120'>操作权限:</th> + <td> + <div > + {volist name="$homeMenus['menus']" key="k1" id="menus1"} + <dl {$k1==count($homeMenus['menus'])?"style='border-bottom:0'":""}> + <dt class="dt1"> + <label><input type="checkbox" id="{$menus1['menuId']}" class="role_{$menus1['menuId']}" value="{$menus1['menuId']}" onclick="javascript:WST.checkChks(this,'.role_{$menus1['menuId']}')"/> {$menus1["menuName"]}</label> + </dt> + <dd class="dd1"> + {volist name="$menus1['list']" key="k2" id="menus2"} + <dl {$k2==count($menus1['list'])?"style='border-bottom:0'":""}> + <dt class="dt2"> + <label><input type="checkbox" id="{$menus2['menuId']}" class="role_{$menus1['menuId']}" value="{$menus2['menuId']}" onclick="javascript:WST.checkChks(this,'.role_{$menus2['menuId']}')" /> {$menus2["menuName"]}</label> + </dt> + <dd class="dd2"> + {if isset($menus2['list'])} + {volist name="$menus2['list']" id="menus3"} + <label> + + <input type="checkbox" id="{$menus3['menuId']}" name="menuIds" class="role_{$menus1['menuId']} role_{$menus2['menuId']} ipt" value="{$menus3['menuId']}" {if isset($object['menuUrls'])}{:in_array(strtolower($menus3['menuUrl']),$object['menuUrls'])?"checked":""}{/if}/> {$menus3["menuName"]} + </label> + {/volist} + {/if} + </dd> + </dl> + + {/volist} + </dd> + </dl> + {/volist} + </div> + </td> + </tr> + <tr> + <th width='120'>消息接收权限:</th> + <td> + {volist name=":WSTDatas('SHOP_MESSAGE')" id="vo"} + <label> + + <input type="checkbox" name="privilegeMsgs" class="ipt" value="{$vo['dataVal']}" {if $object['privilegeMsgs']}{:in_array($vo['dataVal'],$object['privilegeMsgs'])?"checked":""}{/if}/> {$vo["dataName"]} + + </label> + {/volist} + </td> + </tr> + <tr> + <td colspan='2' style='text-align:center;padding:20px;'> + <a class='s-btn' href="javascript:save()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shoproles/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shoproles/shoproles.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shoproles/list.html b/hyhproject/home2/view/default/shops/shoproles/list.html new file mode 100755 index 0000000..7228c9a --- /dev/null +++ b/hyhproject/home2/view/default/shops/shoproles/list.html @@ -0,0 +1,54 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺角色-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺角色管理</span></div> +<div class='wst-shop-tbar'> + 角色名称:<input type='text' id="roleName" name='roleName' class="s-query" /> + <a class="s-btn" onclick="queryByPage(0)">查询</a> + <a class="s-btn wst-list-add" href='{:url("home/shoproles/add")}'>添加</a> +</div> + +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="300">角色名称</th> + <th>创建时间</th> + <th>操作</th> + </tr> + </thead> + <tbody id='loading' style='display:none'> + <tr class='empty-row'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='4' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i]["roleName"]}}</td> + <td>{{d[i]["createTime"]}}</td> + <td> + <a class="g-handle" href='javascript:toEdit({{d[i]["id"]}})'>[编辑]</a> + <a class="g-handle" href='javascript:del({{d[i]["id"]}})'>[删除]</a> + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shoproles/shoproles.js?v={$v}'></script> +<script> +$(function(){queryByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shoproles/shoproles.js b/hyhproject/home2/view/default/shops/shoproles/shoproles.js new file mode 100755 index 0000000..d56f290 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shoproles/shoproles.js @@ -0,0 +1,72 @@ + + +function queryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/shoproles/pageQuery'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('#list').empty(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + + }); +} + +function toEdit(id){ + location.href = WST.U('home/shoproles/edit','id='+id); +} + +/**保存角色数据**/ +function save(){ + $('#shoprole').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shoproles/'+((params.id==0)?"toAdd":"toEdit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shoproles/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +//删除角色 +function del(id){ + var c = WST.confirm({content:'您确定要删除该角色吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/shoproles/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + queryByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shops/notice.html b/hyhproject/home2/view/default/shops/shops/notice.html new file mode 100755 index 0000000..e04c9cf --- /dev/null +++ b/hyhproject/home2/view/default/shops/shops/notice.html @@ -0,0 +1,44 @@ +{extend name="default/shops/base" /} +{block name="title"}首页-卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺公告</span></div> +<div class="wst-clear"></div> + <div class='wst-shop-content' style='margin-top:0px;'> + <table> + <tr> + <td width="7%" style="padding-right:5px;">店铺公告:</td> + <td width="93%"> + <textarea style="width:100%;height:200px;resize:none" placeholder='请保持在150个字以内' class="ipt" id="shopNotice" maxlength='150'>{$notice}</textarea> + </td> + </tr> + </table> + <button onclick="toEdits()" class="wst-shop-but" style="margin-left: 45%;padding: 5px 10px;margin-top: 20px;">保&nbsp;存</button> + </div> +{/block} +{block name="js"} + +<script> +function toEdits(id){ + var params = WST.getParams('.ipt'); + console.log(params.shopNotice.length); + if(params.shopNotice.length>150){ + WST.msg('店铺公告不能超过150个字',{icon:2}); + return; + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shops/editNotice'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); +} +</script> + + +{/block} diff --git a/hyhproject/home2/view/default/shops/shops/shops.js b/hyhproject/home2/view/default/shops/shops/shops.js new file mode 100755 index 0000000..6ab2572 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shops/shops.js @@ -0,0 +1,76 @@ +var isShopUploadinit = false; +function toEdit(type){ + $('#einfo_'+type).show(); + $('#vinfo_'+type).hide(); + if(!isShopUploadinit){ + isShopUploadinit = true; + WST.upload({ + pick:'#shopImgPicker', + formData: {dir:'shops'}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + $('#uploadMsg').empty().hide(); + $('#preview').attr('src',WST.conf.IMGURL+"/"+json.savePath+json.thumb); + $('#shopImg').val(json.savePath+json.name); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); + initTime('#serviceStartTime',$('#serviceStartTime').attr('v')); + initTime('#serviceEndTime',$('#serviceStartTime').attr('v')); + } +} +function initTime($id,val){ + var html = [],t0,t1; + var str = val.split(':'); + for(var i=0;i<24;i++){ + t0 = (val.indexOf(':00')>-1 && (parseInt(str[0],10)==i))?'selected':''; + t1 = (val.indexOf(':30')>-1 && (parseInt(str[0],10)==i))?'selected':''; + html.push('<option value="'+i+':00" '+t0+'>'+i+':00</option>'); + html.push('<option value="'+i+':30" '+t1+'>'+i+':30</option>'); + } + $($id).append(html.join('')); +} +function toCancel(type){ + $('#einfo_'+type).hide(); + $('#vinfo_'+type).show(); +} + +function editInfo(){ + $('#editFrom_1').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt_1'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shops/editInfo'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + $('#v_shopImg').attr('src',WST.conf.IMGURL+"/"+params.shopImg); + $('#v_shopQQ').html(params.shopQQ); + $('#v_shopWangWang').html(params.shopWangWang); + if(params.isInvoice==1){ + $('#tr_isInvoice').show(); + $('#v_isInvoice').html("提供发票"); + }else{ + $('#tr_isInvoice').hide(); + $('#v_isInvoice').html("不提供发票"); + } + $('#v_freight').html(params.freight); + $('#v_serviceStartTime').html(params.serviceStartTime); + $('#v_serviceEndTime').html(params.serviceEndTime); + $('#einfo_1').hide(); + $('#vinfo_1').show(); + window.location.reload(); + }else{ + WST.msg(json.msg,{icon:2}); + + } + }); + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shops/view.html b/hyhproject/home2/view/default/shops/shops/view.html new file mode 100755 index 0000000..8832606 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shops/view.html @@ -0,0 +1,246 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺信息-卖家中心{__block__}{/block} +{block name="css"} +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<style> +label{margin-right:10px;} +</style> +<div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>店铺信息</li> + <li>银行信息</li> + </ul> + <div class="wst-tab-content" style='width:99%;margin-bottom: 10px;'> + <div class="wst-tab-item" style="position: relative;"> + <table id='vinfo_1' class='wst-form'> + <tr> + <th width='150'>店铺编号:</th> + <td>{$object['shopSn']} + <!--<a href='javascript:toEdit(1)' style='float:right;'>编辑</a>--> + </td> + </tr> + <tr> + <th>店铺名称:</th> + <td>{$object['shopName']}</td> + </tr> + <tr> + <th>店铺联系人:</th> + <td>{$object['shopkeeper']}</td> + </tr> + <tr> + <th>店铺联系电话:</th> + <td>{$object['telephone']}</td> + </tr> + <tr> + <th>公司名称:</th> + <td>{$object['shopCompany']}</td> + </tr> + <tr> + <th>公司坐机电话:</th> + <td>{$object['shopTel']}</td> + </tr> + <tr> + <th>经营类目:</th> + <td>{$object['catshopNames']}</td> + </tr> + <tr> + <th>认证类型:</th> + <td> + {php}$accredLen = count($object['accreds']);{/php} + {volist name="$object['accreds']" id="vo"} + {$vo["accredName"]}{if $i < $accredLen }、{/if} + {/volist} + </td> + </tr> + <tr> + <th>店铺图标:</th> + <td> + <img id='v_shopImg' width='150' height='150' src='__IMGURL__/{$object["shopImg"]}'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td id='v_shopQQ'>{$object['shopQQ']}</td> + </tr> + + <tr> + <th>旺旺:</th> + <td id='v_shopWangWang'>{$object['shopWangWang']}</td> + </tr> + <tr> + <th>店铺地址:</th> + <td> + {$object['areaName']} + </td> + </tr> + <tr> + <th>店铺详细地址:</th> + <td>{$object['shopAddress']}</td> + </tr> + <tr> + <th>是否提供开发票:</th> + <td id='v_isInvoice'> + {if $object['isInvoice']==1}提供发票{/if} + {if $object['isInvoice']==0}不提供发票{/if} + </td> + </tr> + <tr id='tr_isInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明:</th> + <td id='v_invoiceRemarks'>{$object['invoiceRemarks']}</td> + </tr> + <tr> + <th>默认运费:</th> + <td >¥<span id='v_freight'>{$object['freight']}</span></td> + </tr> + <tr> + <th>服务时间:</th> + <td><span id='v_serviceStartTime'>{$object['serviceStartTime']}</span>至<span id='v_serviceEndTime'>{$object['serviceEndTime']}</span> + </td> + </tr> + + <!-- mark by cheng 添加更明显的编辑信息按钮--> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href='javascript:toEdit(1)'>编辑信息</a> + + </td> + </tr> + </table> + <div></div> + <form id='editFrom_1' autocomplete="off"> + <table id='einfo_1' class='wst-form hide'> + <tr> + <th width='150'>店铺图标<font color='red'>*</font>:</th> + <td> + <img id='preview' width='150' height='150' src='__IMGURL__/{$object["shopImg"]}'/> + <div id='shopImgPicker'>请上传店铺图标</div><span id='uploadMsg'></span> + <input type='hidden' id='shopImg' class='ipt_1' value='{$object["shopImg"]}'/> + </td> + </tr> + <tr> + <th>客服QQ:</th> + <td> + <input class="ipt_1" id="shopQQ" value="{$object['shopQQ']}" type="text" style='width:60%'> + </td> + </tr> + <tr> + <th> </th> + <td> + <span style='color:gray;'>做为客服接收临时消息的QQ,需开通<a target="_blank" href="http://shang.qq.com/v3/index.html">QQ推广功能</a> -> '首页'-> '推广工具'-> '立即免费开通'</span> + </td> + </tr> + <tr> + <th>旺旺类型<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='0' class="ipt_1" name='shopWangWangType'{if $object['shopWangWangType']==0}checked{/if}/>淘宝旺旺 + </label> + <label> + <input type='radio' value='1' class="ipt_1" name='shopWangWangType'{if $object['shopWangWangType']==1}checked{/if}/>阿里旺旺(1688诚信通) + </label> + + </td> + </tr> + <tr> + <th>旺旺号:</th> + <td><input class="ipt_1" id="shopWangWang" value="{$object['shopWangWang']}" type="text" style='width:60%'></td> + </tr> + <tr> + <th>是否提供开发票<font color='red'>*</font>:</th> + <td> + <label> + <input type='radio' value='1' class="ipt_1" name='isInvoice' onclick='javascript:WST.showHide(1,"#trInvoice")' {if $object['isInvoice']==1}checked{/if}/>提供 + </label> + <label> + <input type='radio' value='0' class="ipt_1" name='isInvoice' onclick='javascript:WST.showHide(0,"#trInvoice")' {if $object['isInvoice']==0}checked{/if}/>不提供 + </label> + </td> + </tr> + <tr id='trInvoice' {if $object['isInvoice']==0}style='display:none'{/if}> + <th>发票说明<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="invoiceRemarks" value="{$object['invoiceRemarks']}" type="text" style='width:60%' data-rule="发票说明:required(#isInvoice1:checked)"></td> + </tr> + <tr> + <th>默认运费<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="freight" value="{$object['freight']}" size='5' maxlength="10" data-rule="默认运费:required;" type="text">¥</td> + </tr> + <tr> + <th>服务时间<font color='red'>*</font>:</th> + <td> + <select class='ipt_1' id='serviceStartTime' v="{$object['serviceStartTime']}"></select> + 至 + <select class='ipt_1' id='serviceEndTime' v="{$object['serviceEndTime']}"></select> + </td> + </tr> + <tr> + <th><font color='red'>小提示*</font>:</th> + <td>银行结算信息只能修改一次,除非必要请不要修改,当前修改次数:<font color='red'>({$object['changeNum']})</font>次</td> + </tr> + <tr> + <th>开户银行名称<font color='red'>*</font>:</th> + <td> + <select id='bankId' class='ipt_1' data-rule='结算银行账号:required;'> + {foreach $bankList as $v} + <option value="{$v['bankId']}" {if $object['bankId']==$v['bankId']}selected{/if}>{$v['bankName']}</option> + {/foreach} + </select> + </td> + </tr> + + <tr> + <th>卡号<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="bankNo" value="{$object['bankNo']}" type="text" style='width:60%'></td> + </tr> + <tr> + <th>持卡人<font color='red'>*</font>:</th> + <td><input class="ipt_1" id="bankUserName" value="{$object['bankUserName']}" type="text" style='width:60%'></td> + </tr> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href='javascript:editInfo()'>保存</a> + <a class='s-btn2' href='javascript:toCancel(1)'>取消</a> + </td> + </tr> + </table> + </form> + </div> + <div class="wst-tab-item" style="display:none;"> + <table class='wst-form'> + <tr> + <th width='150'>开卡银行:</th> + <td>{$object['bankName']}</td> + + </tr> + <!-- + <tr> + <th width='150'>开卡地区:</th> + <td>{$object['bankAreaName']}</td> + </tr> + --> + <tr> + <th>卡号:</th> + <td>{$object['bankNo']}</td> + </tr> + <tr> + <th>持卡人:</th> + <td>{$object['bankUserName']}</td> + </tr> + + </table> + </div> + + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STYLE__/shops/shops/shops.js?v={$v}'></script> +<script> +$(function(){ + $('#tab').TabPanel({tab:0,callback:function(no){}}); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopusers/add.html b/hyhproject/home2/view/default/shops/shopusers/add.html new file mode 100755 index 0000000..e617a2f --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopusers/add.html @@ -0,0 +1,61 @@ +{extend name="default/shops/base" /} +{block name="title"}新增帐号-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>新增帐号</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + <form name="editForm" id="editForm" autocomplete="off"> + <table class='wst-form uinfo-form' > + <tr> + <td width="100"><font color='red'>*</font>用户名</td> + <td class="uinfo"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type='hidden' id='id' name='id' class="ipt" value='0' /> + <input id="loginName" name="loginName" class="ipt wst-regist-input" tabindex="1" maxlength="30" autocomplete="off" onpaste="return false;" style="ime-mode:disabled;" placeholder="邮箱/用户名/手机号" data-rule='请输入用户名:required;' type="text" onkeyup="javascript:WST.isChinese(this,1)"/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>密码</td> + <td class="uinfo"> + <input id="loginPwd" name="loginPwd" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符" data-rule='请输入密码:required;'/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>确认密码</td> + <td class="uinfo"> + <input id="reUserPwd" name="reUserPwd" class="ipt wst-regist-input" tabindex="3" autocomplete="off" type="password" placeholder="6-16位字符" data-rule="确认密码: required; match(loginPwd)"/> + </td> + </tr> + <tr> + <td><font color='red'>*</font>角色</td> + <td> + <select id="roleId" data-rule="required" class="ipt"> + {volist name="roles" id="role"} + <option value="{$role['id']}">{$role["roleName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href="javascript:add()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shopusers/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopusers/edit.html b/hyhproject/home2/view/default/shops/shopusers/edit.html new file mode 100755 index 0000000..127ead9 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopusers/edit.html @@ -0,0 +1,80 @@ +{extend name="default/shops/base" /} +{block name="title"}编辑帐号-卖家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-body"> +<div class="wst-shop-head"><span>编辑帐号</span></div> +<div class="wst-clear"></div> + <div class="wst-shop-content"> + <form name="editForm" id="editForm" autocomplete="off"> + <table class='wst-form uinfo-form' > + <tr> + <td colspan="2"> + <div class='wst-tips-box'> + <div class='icon'></div> + <div class='tips'> + 1.新密码为空,则不修改帐号密码。<br/> + 2.店铺管理员不能修改角色。</div> + <div style="clear:both"></div> + </div> + </td> + </tr> + <tr> + <td width="100"><font color='red'>*</font>帐号名</td> + <td class="uinfo"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type='hidden' id='id' name='id' class="ipt" value='{$object["id"]}' /> + {$object["loginName"]} + </td> + </tr> + <tr> + <td>原密码</td> + <td class="uinfo"> + <input id="oldPass" name="oldPass" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符"/> + </td> + </tr> + <tr> + <td>新密码</td> + <td class="uinfo"> + <input id="newPass" name="newPass" class="ipt wst-regist-input" tabindex="2" style="ime-mode:disabled;" autocomplete="off" type="password" placeholder="6-16位字符"/> + </td> + </tr> + <tr> + <td>确认新密码</td> + <td class="uinfo"> + <input id="reNewPass" name="reNewPass" class="ipt wst-regist-input" tabindex="3" autocomplete="off" type="password" placeholder="6-16位字符" data-rule="确认密码: match(newPass)"/> + </td> + </tr> + {if $object["roleId"]>0} + <tr> + <td><font color='red'>*</font>角色</td> + <td> + <select id="roleId" data-rule="required" class="ipt"> + {volist name="roles" id="role"} + <option value="{$role['id']}" {if $object["roleId"]==$role['id']}selected{/if}>{$role["roleName"]}</option> + {/volist} + </select> + </td> + </tr> + {/if} + <tr> + <td colspan='2' style="text-align:center"> + <a class='s-btn' href="javascript:edit()">保&nbsp;存</a>&nbsp;&nbsp; + <a class='s-btn2' href='{:url("home/shopusers/index")}'>返&nbsp;回</a> + </td> + </tr> + </table> + </form> + </div> +</div> +{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopusers/list.html b/hyhproject/home2/view/default/shops/shopusers/list.html new file mode 100755 index 0000000..acbdcb8 --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopusers/list.html @@ -0,0 +1,57 @@ +{extend name="default/shops/base" /} +{block name="title"}店铺用户管理-卖家中心{__block__}{/block} +{block name="content"} +<div class="wst-shop-head"><span>店铺帐号管理</span></div> +<div class='wst-shop-tbar'> + 帐号名:<input type='text' id="userName" class="s-query" id='userName'/> + <a class="s-btn" onclick="queryByPage(0)">查询</a> + <a class="s-btn wst-list-add" href='{:url("home/shopusers/add")}'>添加</a> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="40">序号</th> + <th width="200">帐号名</th> + <th width="200">角色名称</th> + <th>创建时间</th> + <th>操作</th> + </tr> + </thead> + <tbody id='loading' style='display:none'> + <tr class='empty-row'> + <td colspan='5'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='5' style='padding-top:10px;text-align:center;'> + <div id='pager'></div> + </td></tr> + </tfoot> + + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{i+1}}</td> + <td>{{d[i]["loginName"]}}</td> + <td>{{d[i]["roleId"]?d[i]["roleName"]:"管理员"}}</td> + <td>{{d[i]["createTime"]}}</td> + <td> + <a class="g-handle" href='javascript:toEdit({{d[i]["id"]}})'>[编辑]</a> + {{# if(d[i]["roleId"]>0){ }} + <a class="g-handle" href='javascript:del({{d[i]["id"]}})'>[删除]</a> + {{# } }} + </td> + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/shopusers/shopusers.js?v={$v}'></script> +<script> +$(function(){queryByPage()}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/shopusers/shopusers.js b/hyhproject/home2/view/default/shops/shopusers/shopusers.js new file mode 100755 index 0000000..36592cb --- /dev/null +++ b/hyhproject/home2/view/default/shops/shopusers/shopusers.js @@ -0,0 +1,110 @@ + + +function queryByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/shopusers/pageQuery'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('#list').empty(); + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByPage(e.curr); + } + } + }); + + }); +} + +function toEdit(id){ + location.href = WST.U('home/shopusers/edit','id='+id); +} + +/**保存角色数据**/ +function add(){ + $('#editForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(WST.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.loginPwd = rsa.encrypt(params.loginPwd); + params.reUserPwd = rsa.encrypt(params.reUserPwd); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopusers/toAdd'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shopusers/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function edit(){ + $('#editForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.ipt'); + if(WST.conf.IS_CRYPT=='1' && params.newPass!=""){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.oldPass = rsa.encrypt(params.oldPass); + params.newPass = rsa.encrypt(params.newPass); + params.reNewPass = rsa.encrypt(params.reNewPass); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/shopusers/toEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + location.href=WST.U('home/shopusers/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +//删除角色 +function del(id){ + var c = WST.confirm({content:'删除店铺管理帐号,只是删除该帐号与店铺的关系,您确定要删除吗?',yes:function(){ + layer.close(c); + var load = WST.load({msg:'正在删除,请稍后...'}); + $.post(WST.U('home/shopusers/del'),{id:id},function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1}); + queryByPage(0); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/stockwarn/list.html b/hyhproject/home2/view/default/shops/stockwarn/list.html new file mode 100755 index 0000000..fd01b2d --- /dev/null +++ b/hyhproject/home2/view/default/shops/stockwarn/list.html @@ -0,0 +1,110 @@ +{extend name="default/shops/base" /} +{block name="title"}库存预警 - 卖家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-shop-head"><span>库存预警</span></div> +<div class="wst-shop-tbar"> + <label> + 商品分类: + <select name="cat1" id="cat1" onchange="getCat(this.value)" class="s-query"> + <option value="">-请选择-</option> + {volist name=":WSTShopCats(0)" id="vo"} + <option value="{$vo['catId']}" >{$vo['catName']}</option> + {/volist} + </select> + <select name="cat2" id="cat2" class="s-query"><option value="">-请选择-</option></select> + <a class="s-btn" onclick="stockByPage()" style='margin-top:5px;'>查询</a> + </label> +</div> +<div class="wst-shop-content"> + <table class='wst-list'> + <thead> + <tr> + <th width="220">商品名称</th> + <th>货号</th> + <th>规格</th> + <th width="130">库存<font color='red'>(红色双击编辑)</font></th> + <th width="130">预警<font color='red'>(红色双击编辑)</font></th> + <th width="120">操作</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr align="center"><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + {{# if(d[i]['isSpec']==1) { }} + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-goodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + <td> + <span class="spec"> + {{# for(var s = 0; s < d[i].spec.length; s++){ }} + {{d[i].spec[s]['catName']}}:{{d[i].spec[s]['itemName']}}; + {{# } }} + </span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['id']}},1)"> + <input id="ipt_1_{{d[i]['id']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['id']}},1,{{d[i]['goodsId']}})" class="stockin" maxlength="6"/> + <span id="span_1_{{d[i]['id']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['goodsStock']}}</span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['id']}},2)"> + <input id="ipt_2_{{d[i]['id']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['id']}},2,{{d[i]['goodsId']}})" class="stockin" maxlength="6"/> + <span id="span_2_{{d[i]['id']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['warnStock']}}</span> + </td> + <td><a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[进入商品编辑]</a></td> + {{# }else{ }} + <td> + <div class="goods-img"> + <a href="{{WST.U("home/goods/detail","id="+d[i]['goodsId']+"&key="+d[i]['verfiycode'])}}"> + <img class='j-goodsImg' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + </a> + </div> + <p class="goodsName"> + {{WST.cutStr(d[i]['goodsName'],43)}} + </p> + </td> + <td>{{d[i]['productNo']}}</td> + <td>无</td> + {{# if(d[i]['goodsType']==0){ }} + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['goodsId']}},3)"> + <input id="ipt_3_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['goodsId']}},3)" class="stockin" maxlength="6"/> + <span id="span_3_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['goodsStock']}}</span> + </td> + <td width="40" ondblclick="javascript:toEditGoodsStock({{d[i]['goodsId']}},4)"> + <input id="ipt_4_{{d[i]['goodsId']}}" onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)" onblur="javascript:editGoodsStock({{d[i]['goodsId']}},4)" class="stockin" maxlength="6"/> + <span id="span_4_{{d[i]['goodsId']}}" style="display: inline;cursor:pointer;color:#f30505;">{{d[i]['warnStock']}}</span> + </td> + {{# }else{ }} + <td width="40">{{d[i]['goodsStock']}}</td> + <td width="40">{{d[i]['warnStock']}}</td> + {{#}}} + <td> + {{#if(d[i]['goodsType']==1){}} + <a class="g-handle" href='javascript:toStock({{d[i]['goodsId']}},"stockWarnByPage")'>[进入卡券编辑]</a> + {{#}else{}} + <a class="g-handle" href='javascript:toEdit({{d[i]['goodsId']}},"sale")'>[进入商品编辑]</a> + {{#}}} + </td> + + {{# } }} + </tr> + {{# } }} + </script> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/stockwarn/stockwarn.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/shops/stockwarn/stockwarn.js b/hyhproject/home2/view/default/shops/stockwarn/stockwarn.js new file mode 100755 index 0000000..ba866da --- /dev/null +++ b/hyhproject/home2/view/default/shops/stockwarn/stockwarn.js @@ -0,0 +1,95 @@ +$(function(){ + stockByPage(); +}); +function toStock(id,src){ + location.href=WST.U('home/goodsvirtuals/stock','id='+id+"&src="+src); +} +function stockByPage(p){ + $('#list').html('<tr><td colspan="11"><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...</td></tr>'); + var params = {}; + params = WST.getParams('.s-query'); + params.page = p; + $.post(WST.U('home/goods/stockByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.Rows){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list').html(html); + $('.j-goodsImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + stockByPage(e.curr); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} +function toEdit(id,src){ + location.href = WST.U('home/goods/edit','id='+id+'&src='+src); +} +//双击修改 +function toEditGoodsStock(id,type){ + $("#ipt_"+type+"_"+id).show(); + $("#span_"+type+"_"+id).hide(); + $("#ipt_"+type+"_"+id).focus(); + $("#ipt_"+type+"_"+id).val($("#span_"+type+"_"+id).html()); +} +function endEditGoodsStock(type,id){ + $('#span_'+type+'_'+id).html($('#ipt_'+type+'_'+id).val()); + $('#span_'+type+'_'+id).show(); + $('#ipt_'+type+'_'+id).hide(); +} +function editGoodsStock(id,type,goodsId){ + var number = $('#ipt_'+type+'_'+id).val(); + if($.trim(number)==''){ + WST.msg('库存不能为空', {icon: 5}); + return; + } + var params = {}; + params.id = id; + params.type = type; + params.goodsId = goodsId; + params.number = number; + $.post(WST.U('Home/Goods/editwarnStock'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status>0){ + $('#img_'+type+'_'+id).fadeTo("fast",100); + endEditGoodsStock(type,id); + $('#img_'+type+'_'+id).fadeTo("slow",0); + }else{ + WST.msg(json.msg, {icon: 5}); + } + }); +} + +function getCat(val){ + if(val==''){ + $('#cat2').html("<option value='' >-请选择-</option>"); + return; + } + $.post(WST.U('home/shopcats/listQuery'),{parentId:val},function(data,textStatus){ + var json = WST.toJson(data); + var html = [],cat; + html.push("<option value='' >-请选择-</option>"); + if(json.status==1 && json.list){ + json = json.list; + for(var i=0;i<json.length;i++){ + cat = json[i]; + html.push("<option value='"+cat.catId+"'>"+cat.catName+"</option>"); + } + } + $('#cat2').html(html.join('')); + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/sql/install.sql b/hyhproject/home2/view/default/sql/install.sql new file mode 100755 index 0000000..bb436c5 --- /dev/null +++ b/hyhproject/home2/view/default/sql/install.sql @@ -0,0 +1 @@ +INSERT INTO `wst_styles` VALUES (null, 'home', '默认模板', 'WSTMart', '', '1', 'default', '0'); \ No newline at end of file diff --git a/hyhproject/home2/view/default/sql/style.sql b/hyhproject/home2/view/default/sql/style.sql new file mode 100755 index 0000000..3d54b75 --- /dev/null +++ b/hyhproject/home2/view/default/sql/style.sql @@ -0,0 +1,35 @@ +insert into `wst_ad_positions`(`positionType`,`positionName`,`positionWidth`,`positionHeight`,`dataFlag`,`positionCode`,`apSort`) +values ('1', '首页分层1F顶部广告', '400', '110', '1', 'ads-1-1', '0'), +('1', '首页分层1F左下广告', '478', '224', '1', 'ads-1-2', '0'), +('1', '首页分层1F左上广告', '478', '344', '1', 'ads-1-3', '0'), +('1', '首页分层2F顶部广告', '400', '110', '1', 'ads-2-1', '0'), +('1', '首页分层2F左下广告', '478', '224', '1', 'ads-2-2', '0'), +('1', '首页分层2F左上广告', '478', '344', '1', 'ads-2-3', '0'), +('1', '首页分层3F顶部广告', '400', '110', '1', 'ads-3-1', '0'), +('1', '首页分层3F左下广告', '478', '224', '1', 'ads-3-2', '0'), +('1', '首页分层3F左上广告', '478', '344', '1', 'ads-3-3', '0'), +('1', '首页分层4F顶部广告', '400', '110', '1', 'ads-4-1', '0'), +('1', '首页分层4F左下广告', '478', '224', '1', 'ads-4-2', '0'), +('1', '首页分层4F左上广告', '478', '344', '1', 'ads-4-3', '0'), +('1', '首页分层5F顶部广告', '400', '110', '1', 'ads-5-1', '0'), +('1', '首页分层5F左下广告', '478', '224', '1', 'ads-5-2', '0'), +('1', '首页分层5F左上广告', '478', '344', '1', 'ads-5-3', '0'), +('1', '首页分层6F顶部广告', '400', '110', '1', 'ads-6-1', '0'), +('1', '首页分层6F左下广告', '478', '224', '1', 'ads-6-2', '0'), +('1', '首页分层6F左上广告', '478', '344', '1', 'ads-6-3', '0'), +('1', '首页分层7F顶部广告', '400', '110', '1', 'ads-7-1', '0'), +('1', '首页分层7F左下广告', '478', '224', '1', 'ads-7-2', '0'), +('1', '首页分层7F左上广告', '478', '344', '1', 'ads-7-3', '0'), +('1', '首页分层8F顶部广告', '400', '110', '1', 'ads-8-1', '0'), +('1', '首页分层8F左下广告', '478', '224', '1', 'ads-8-2', '0'), +('1', '首页分层8F左上广告', '478', '344', '1', 'ads-8-3', '0'), +('1', '首页分层9F顶部广告', '400', '110', '1', 'ads-9-1', '0'), +('1', '首页分层9F左下广告', '478', '224', '1', 'ads-9-2', '0'), +('1', '首页分层9F左上广告', '478', '344', '1', 'ads-9-3', '0'), +('1', '首页分层10F顶部广告', '400', '110', '1', 'ads-10-1', '0'), +('1', '首页分层10F左下广告', '478', '224', '1', 'ads-10-2', '0'), +('1', '首页分层10F左上广告', '478', '344', '1', 'ads-10-3', '0'), +('1', '首页轮播广告', '1920', '420', '1', 'ads-index', '99'), +('1', '首页顶部广告', '1200', '100', '1', 'index-top-ads', '100'), +('1', '首页资讯上方广告', '210', '128', '1', 'index-art', '1'), +('1', '首页轮播下广告', '240', '320', '1', 'ads-lunbobottom', '0'); \ No newline at end of file diff --git a/hyhproject/home2/view/default/top.html b/hyhproject/home2/view/default/top.html new file mode 100755 index 0000000..1139d8b --- /dev/null +++ b/hyhproject/home2/view/default/top.html @@ -0,0 +1,191 @@ + +{wst:ads code="index-top-ads" cache='86400' id="tads"} +{if ($tads['adFile']!='')} +<div class="index-top-ads"> + <a href="{$tads['adURL']}" {if ($tads['isOpen'])}target='_blank'{/if} {if ($tads['adURL']!='')}onclick="WST.recordClick({$tads['adId']})"{/if} onfocus="this.blur();"> + <img src="__IMGURL__/{$tads['adFile']}"></a> + <a href="javascript:;" class="close-ads" onclick="WST.closeAds(this)"></a> +</div> +{/if} +{/wst:ads} + +<div class="wst-header"> + <div class="wst-nav"> + <ul class="headlf"> + {if condition="session('WST_USER.userId') >0"} + <li class="drop-info"> + <div class="drop-infos"> + <a href="{:Url('home/users/index')}">欢迎您,{:session('WST_USER.userName')?session('WST_USER.userName'):session('WST_USER.loginName')}</a> + </div> + <div class="wst-tag dorpdown-user"> + <div class="wst-tagt"> + <div class="userImg" > + <img class='usersImg' data-original="__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}"/> + </div> + <div class="wst-tagt-n"> + <div> + <span class="wst-tagt-na">{:session('WST_USER.userName')?session('WST_USER.userName'):session('WST_USER.loginName')}</span> + {if (int)session('WST_USER.rankId') > 0 } + <img src="__IMGURL__/{:session('WST_USER.userrankImg')}" title="{:session('WST_USER.rankName')}"/> + {/if} + </div> + <div class='wst-tags'> + <span class="w-lfloat"><a onclick='WST.position(15,0)' href='{:Url("home/users/edit")}'>用户资料</a></span> + <span class="w-lfloat" style="margin-left:10px;"><a onclick='WST.position(16,0)' href='{:Url("home/users/security")}'>安全设置</a></span> + </div> + </div> + <div class="wst-tagb" > + <a onclick='WST.position(5,0)' href='{:Url("home/orders/waitReceive")}'>待收货订单</a> + <a onclick='WST.position(60,0)' href='{:Url("home/logmoneys/usermoneys")}'>我的余额</a> + <a onclick='WST.position(49,0)' href='{:Url("home/messages/index")}'>我的消息</a> + <a onclick='WST.position(13,0)' href='{:Url("home/userscores/index")}'>我的积分</a> + <a onclick='WST.position(41,0)' href='{:Url("home/favorites/goods")}'>我的关注</a> + <a style='display:none'>咨询回复</a> + </div> + <div class="wst-clear"></div> + </div> + </div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <a href='{:Url("home/messages/index")}' target='_blank' onclick='WST.position(49,0)'>消息(<span id='wst-user-messages'>0</span>)</a> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="javascript:WST.logout();">退出</a></div> + </li> + {else /} + <li class="drop-info"> + <div>欢迎来到{:WSTMSubstr(WSTConf('CONF.mallName'),0,13)}<a href="{:Url('home/users/login')}" onclick="WST.currentUrl();">&nbsp;&nbsp;请&nbsp;登录</a></div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="{:Url('home/users/regist')}" onclick="WST.currentUrl();">免费注册</a></div> + </li> + {/if} + </ul> + <ul class="headrf" style='float:right;'> + <li class="j-dorpdown" style="width: 86px;"> + <div class="drop-down" style="padding-left:0px;"> + <a href="{:Url('home/users/index')}" target="_blank">我的订单<i class="di-right"><s>◇</s></i></a> + </div> + <div class='j-dorpdown-layer order-list'> + <div><a href='{:Url("home/orders/waitPay")}' onclick='WST.position(3,0)'>待付款订单</a></div> + <div><a href='{:Url("home/orders/waitReceive")}' onclick='WST.position(5,0)'>待发货订单</a></div> + <div><a href='{:Url("home/orders/waitAppraise")}' onclick='WST.position(6,0)'>待评价订单</a></div> + </div> + </li> + {if(WSTDatas('ADS_TYPE',4))} + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down2 pdr5"><i class="di-left"></i><a href="#" target="_blank">手机商城</a></div> + <div class='j-dorpdown-layer sweep-list'> + <div class="qrcodea"> + <div id='qrcodea' class="qrcodeal"></div> + <div class="qrcodear"> + <p>扫描二维码</p><span>下载手机客户端</span> + <br/> + <a >Android</a> + <br/> + <a>iPhone</a> + </div> + </div> + </div> + </li> + {/if} + {if(WSTConf('CONF.wxenabled')==1)} + <li class="spacer">|</li> + <li class="j-dorpdown" style="width:78px;"> + <div class="drop-down" style="padding:0 5px;"><a href="#" target="_blank">关注我们</a></div> + <div class='j-dorpdown-layer des-list' style="width:120px;"> + <div style="height:114px;">{if(WSTConf('CONF.wxAppLogo'))}<img src="__IMGURL__/{:WSTConf('CONF.wxAppLogo')}" style="height:114px;">{/if}</div> + <div>关注我们</div> + </div> + </li> + {/if} + <li class="spacer">|</li> + <li class="j-dorpdown" style="width:78px;"> + <div class="drop-down" style="padding:0 5px;"><a href="#" target="_blank">下载APP</a></div> + <div class='j-dorpdown-layer des-list' style="width:120px;"> + <div style="height:114px;"><img src="http://img.juzi199.com/upload/sysconfigs/app.jpg" style="height:114px;"></div> + <div>下载APP</div> + </div> + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down4 pdr5"><a href="#" target="_blank">我的收藏</a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:Url('home/favorites/goods')}" onclick='WST.position(41,0)'>商品收藏</a></div> + <div><a href="{:Url('home/favorites/shops')}" onclick='WST.position(46,0)'>店铺收藏</a></div> + </div> + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down5 pdr5" ><a href="#" target="_blank">客户服务</a></div> + <div class='j-dorpdown-layer des-list'> + <div><a href='{:Url("home/helpcenter/view","id=1")}' target='_blank'>帮助中心</a></div> + <div><a href='{:Url("home/helpcenter/view","id=8")}' target='_blank'>售后服务</a></div> + <div><a href='{:Url("home/helpcenter/view","id=3")}' target='_blank'>常见问题</a></div> + </div> + </li> + <li class="spacer">|</li> + {if condition="session('WST_USER.userId') gt 0"} + {if condition="session('WST_USER.userType') eq 0"} + <li class="j-dorpdown"> + <div class="drop-down pdl5" ><a href="#" target="_blank">{if empty($is_icp)}商家管理{else /}后台管理{/if}<i class="di-right"><s>◇</s></i></a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:url('home/shops/login')}" onclick="WST.currentUrl();">{if empty($is_icp)}商家登录{else /}后台登录{/if}</a></div> + {if empty($is_icp)}<div><a href="{:url('home/shops/join')}" rel="nofollow" onclick="WST.currentUrl('{:url("home/shops/join")}');">商家入驻</a></div>{/if} + </div> + </li> + + {else /} + <li class="j-dorpdown"> + <div class="drop-down pdl5" > + <a href="{:Url('home/shops/index')}" rel="nofollow" target="_blank">卖家中心<i class="di-right"><s>◇</s></i></a> + </div> + <div class='j-dorpdown-layer product-list last-menu'> + <div><a href='{:Url("home/orders/waitdelivery")}' onclick='WST.position(24,1)'>待发货订单</a></div> + <div><a href='{:Url("home/orders/waitdelivery")}' onclick='WST.position(25,1)'>投诉订单</a></div> + <div><a href='{:Url("home/home/goods/sale")}' onclick='WST.position(32,1)'>商品管理</a></div> + <div><a href='{:Url("home/shopcats/index")}' onclick='WST.position(30,1)'>商品分类</a></div> + </div> + </li> + {/if} + {else /} + <li class="j-dorpdown"> + <div class="drop-down pdl5" ><a href="#" target="_blank">{if empty($is_icp)}商家管理{else /}后台管理{/if}<i class="di-right"><s>◇</s></i></a></div> + <div class='j-dorpdown-layer foucs-list'> + <div><a href="{:url('home/shops/login')}" onclick="WST.currentUrl();">{if empty($is_icp)}商家登录{else /}后台登录{/if}</a></div> + {if empty($is_icp)}<div><a href="{:url('home/shops/join')}" rel="nofollow" onclick="WST.currentUrl('{:url("home/shops/join")}');">商家入驻</a></div>{/if} + </div> + </li> + + {/if} + </li> + <li class="spacer">|</li> + <li class="j-dorpdown"> + <div class="drop-down drop-down5 pdr5" ><a href='{:Url("/newscats-63")}' target="_blank">行业资讯(收费)</a></div> + <div class='j-dorpdown-layer des-list'> + + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> +</div> +<script> +$(function(){ + //二维码 + //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围'L','M','Q','H' + var a = qrcode(8, 'M'); + var url = window.location.host+window.conf.APP; + a.addData(url); + a.make(); + $('#qrcodea').html(a.createImgTag()); +}); +function goShop(id){ + location.href=WST.U('home/shops/home','shopId='+id); +} +</script> +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/user_login.html b/hyhproject/home2/view/default/user_login.html new file mode 100755 index 0000000..3695545 --- /dev/null +++ b/hyhproject/home2/view/default/user_login.html @@ -0,0 +1,126 @@ +{extend name="default/base_js" /} +{block name="title"}用户登录 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/login.css?v={$v}" rel="stylesheet"> +{/block} +{block name="header"}{/block} +{block name="main"} + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <div class="wst-header wst-color"> + <div class="wst-nav"> + <ul class="headlf"> + <li class="drop-info"> + <div>欢迎来到{:WSTMSubstr(WSTConf('CONF.mallName'),0,13)}<a href="{:Url('home/users/login')}" onclick="WST.currentUrl();">&nbsp;&nbsp;请&nbsp;登录</a></div> + </li> + <li class="spacer">|</li> + <li class="drop-info"> + <div><a href="{:Url('home/users/regist')}" onclick="WST.currentUrl();">免费注册</a></div> + </li> + </ul> + <ul class="wst-icon"> + <li class="wst-img-icon"></li><li class="wst-remind">欢迎登陆!</li> + </ul> + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-login-banner"> + <div class="wst-icon-banner"> + <a href='{$Request.root.true}' title="{:WSTConf('CONF.mallName')}" > + <div class="img-banner" > + <img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}"> + </div> + </a> + <div class="wst-stript"></div> + <div class="wst-login-action"> + <div class="wst-left">用户登录</div> + <div class="wst-right-action"> + <div class="action-box"> + 没有账号?<a class="wst-login-but wst-location" href="{:Url('home/users/regist')}" onclick="WST.currentUrl();">立即注册</a> + </div> + </div> + </div> + </div> + </div> + <div class="wst-login-middle"> + <div class="wst-container"> + <div class="wst-login_l"> + <div class="wst-login_r"> + <form method="post" autocomplete="off"> + <span class="wst-login-u">用户登录</span> + <input type='hidden' id='typ' value='0' class='ipt'/> + <div class="wst-item wst-item-box" style="margin-top: 20px;"> + <div for="loginname" class="login-img"></div> + <input id="loginName" name="loginName" class="ipt wst-login-input-1" tabindex="1" value="{$loginName}" autocomplete="off" type="text" data-rule="用户名: required;" data-msg-required="请填写用户名" data-tip="请输入用户名" placeholder="邮箱/用户名/手机号"/> + </div> + <div class="wst-item wst-item-box"> + <div for="loginname" class="password-img"></div> + <input id="loginPwd" name="loginPwd" class="ipt wst-login-input-1" tabindex="2" autocomplete="off" type="password" data-rule="密码: required;" data-msg-required="请填写密码" data-tip="请输入密码" placeholder="密码"/> + </div> + <div class="wst-item wst-item-box"> + <div for="loginname" class="yanzheng-img"></div> + <div class="wst-login-code-1"> + <input id="verifyCode" style="ime-mode:disabled" name="verifyCode" class="ipt wst-login-codein-1" tabindex="6" autocomplete="off" maxlength="6" type="text" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify"placeholder="验证码"/> + <img id='verifyImg' class="wst-login-codeim-1" src="{:url('home/index/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:125px;height:36px;border-top-right-radius:6px;border-bottom-right-radius:6px;float: left;"><span id="verify"></span> + </div> + </div> + <table class="wst-table"> + <tr class="wst-login-tr"> + <td colspan="2" style="padding-left:0px;"> + <input id="rememberPwd" name="rememberPwd" class="ipt wst-login-ch" checked="checked" type="checkbox"/> + <label>记住密码</label> + <label><a style="color:#b2b1b1;float:right;" href="{:Url('home/users/regist')}">&nbsp;免费注册</a></label> + <label><a style="color:#b2b1b1;padding-left: 140px;float:right;" href="{:Url('home/Users/forgetPass')}">忘记密码? | </a></label> + </td> + </tr> + </table> + <div class="wst-item wst-item-box" style="border: 0;" > + <div style="width:100%;height:32px;line-height:32px;float:left;"><a class="wst-login-but" href="javascript:void(0);" onclick='javascript:login()'>登录</a></div> + </div> + + + </form> + {:hook('homeDocumentLogin')} + </div> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class="wst-footer"> + <div class="wst-container"> + <div class="wst-footer-hp-ck3"> + <div class="links"> + {php}$navs = WSTNavigations(1);{/php} + {volist name="$navs" id='vo'} + <a href="{$vo['navUrl']}" {if $vo['isOpen']==1}target="_blank"{/if}>{$vo['navTitle']}</a> + {if $i< count($navs)}&nbsp;&nbsp;|&nbsp;&nbsp;{/if} + {/volist} + </div> + <div class="copyright"> + {php} + if(WSTConf('CONF.mallFooter')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.mallFooter')); + } + {/php} + {php} + if(WSTConf('CONF.visitStatistics')!=''){ + echo htmlspecialchars_decode(WSTConf('CONF.visitStatistics'))."<br/>"; + } + {/php} + </div> + </div> + </div> + </div> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/js/login.js?v={$v}'></script> + <script> + $(document).keypress(function(e) { + if(e.which == 13) { + login(); + } + }); + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/user_protocol.html b/hyhproject/home2/view/default/user_protocol.html new file mode 100755 index 0000000..a7b6a3b --- /dev/null +++ b/hyhproject/home2/view/default/user_protocol.html @@ -0,0 +1,99 @@ +<!DOCTYPE html> +<html lang="zh-cn"> +<head> +<meta charset="utf-8"> +<link rel="shortcut icon" href="favicon.ico"/> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<title>用户注册协议</title> +<style> +.wst-protocol { + overflow: auto; + padding: 10px 20px 0 10px; + color: #333; + font-family: Arial,"宋体",Lucida,Verdana,Helvetica,sans-serif; + font-size: 12px; +} +.wst-protocol h4{line-height: 30px;margin:0px;} +.wst-protocol p{line-height: 20px;margin:0px;} +.wst-protocol strong{margin-right:2px;} +.wst-mall{font-weight:bold;} +</style> +</head> +<body> +<div class='wst-protocol'> +<h4><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>用户注册协议</h4> +<p>本协议是您与<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有者之间就<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站服务等相关事宜所订立的契约,请您仔细阅读本注册协议,您点击"同意并继续"按钮后,本协议即构成对双方有约束力的法律文件。</p> +<h4>第1条 本站服务条款的确认和接纳</h4> +<p><strong>1.1</strong>本站的各项电子服务的所有权和运作权归<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有。用户同意所有注册协议条款并完成注册程序,才能成为本站的正式用户。用户确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。<p></p> +<p><strong>1.2</strong>用户点击同意本协议的,即视为用户确认自己具有享受本站服务、下单购物等相应的权利能力和行为能力,能够独立承担法律责任。</p> +<p><strong>1.3</strong>如果您在18周岁以下,您只能在父母或监护人的监护参与下才能使用本站。<p> +<p><strong>1.4</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留在中华人民共和国大陆地区法施行之法律允许的范围内独自决定拒绝服务、关闭用户账户、清除或编辑内容或取消订单的权利。</p> +<h4>第2条 本站服务</h4> +<p><strong>2.1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>通过互联网依法为用户提供互联网信息等服务,用户在完全同意本协议及本站规定的情况下,方有权使用本站的相关服务。</p> +<p><strong>2.2</strong>用户必须自行准备如下设备和承担如下开支:</p> +<p>(1)上网设备,包括并不限于电脑或者其他上网终端、调制解调器及其他必备的上网装置;</p> +<p>(2)上网开支,包括并不限于网络接入费、上网设备租用费、手机流量费等。</p> +<h4>第3条 用户信息</h4> +<p><strong>3.1</strong>用户应自行诚信向本站提供注册资料,用户同意其提供的注册资料真实、准确、完整、合法有效,用户注册资料如有变动的,应及时更新其注册资料。如果用户提供的注册资料不合法、不真实、不准确、不详尽的,用户需承担因此引起的相应责任及后果,并且<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留终止用户使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>各项服务的权利。</p> +<p><strong>3.2</strong>用户在本站进行浏览、下单购物等活动时,涉及用户真实姓名/名称、通信地址、联系电话、电子邮箱等隐私信息的,本站将予以严格保密,除非得到用户的授权或法律另有规定,本站不会向外界披露用户隐私信息。</p> +<p><strong>3.3</strong>用户注册成功后,将产生用户名和密码等账户信息,您可以根据本站规定改变您的密码。用户应谨慎合理的保存、使用其用户名和密码。用户若发现任何非法使用用户账号或存在安全漏洞的情况,请立即通知本站并向公安机关报案。</p> +<p><strong>3.4</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>拥有通过邮件、短信电话等形式,向在本站注册、购物用户、收货人发送订单信息、促销活动等告知信息的权利。</p> +<p><strong>3.5</strong>用户不得将在本站注册获得的账户借给他人使用,否则用户应承担由此产生的全部责任,并与实际使用人承担连带责任。</p> +<p><strong>3.6</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权使用用户的注册信息、用户名、密码等信息,登录进入用户的注册账户,进行证据保全,包括但不限于公证、见证等。</p> +<h4>第4条 用户依法言行义务</h4> +<p>本协议依据国家相关法律法规规章制定,用户同意严格遵守以下义务:</p> +<p>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</p> +<p>(2)从中国大陆向境外传输资料信息时必须符合中国有关法规;</p> +<p>(3)不得利用本站从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动;</p> +<p>(4)不得干扰本站的正常运转,不得侵入本站及国家计算机信息系统;</p> +<p>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽的、不文明的等信息资料;</p> +<p>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</p> +<p>(7)不得教唆他人从事本条所禁止的行为;</p> +<p>(8)不得利用在本站注册的账户进行牟利性经营活动;</p> +<p>(9)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容;</p> +<p>用户应不时关注并遵守本站不时公布或修改的各类合法规则规定。</p> +<p>本站保有删除站内各类不符合法律政策或不真实的信息内容而无须通知用户的权利。</p> +<p>若用户未遵守以上规定的,本站有权作出独立判断并采取暂停或关闭用户帐号等措施。用户须对自己在网上的言论和行为承担法律责任。</p> +<h4>第5条 店铺义务</h4> +<p><strong>5.1</strong>店铺经营者可通过本站申请店铺,发布全新或二手商品及/或服务信息并与其他用户达成交易,但必须保证商品信息真实。如有发现商品假冒或者其他违反国家法律规定的商品,本站有权对商品进行禁售。</p> +<p><strong>5.2</strong>若店铺经营者发生改变,店铺经营者需及时联系本站进行信息的变更,若未及时联系本站而导致消费者与原店铺经营者产生交易纠纷或者违法国家规定的事情,本站不负任何连带责任。</p> +<p><strong>5.3</strong>店铺经营者有权通过使用店铺设置短暂关停店铺,但店铺经营者应当对自己店铺关停前已达成的交易继续承担发货、退换货及质保维修、维权投诉处理等交易保障责任。</p> +<p><strong>5.4</strong>店铺经营者如有不实交易信息或者违反国家相关法律的行为,本站有权对店铺进行关停,并对关停期间所产生的损失不负任何责任。</p> +<p>依据上述约定关停店铺均不会影响您已经累积的信用。</p> +</p> +<h4>第6条 商品信息</h4> +<p>本站上的商品价格、数量、是否有货等商品信息随时都有可能发生变动,本站不作特别通知。由于网站上商品信息的数量极其庞大,虽然本站会尽最大努力保证您所浏览商品信息的准确性,但由于众所周知的互联网技术因素等客观原因存在,本站网页显示的信息可能会有一定的滞后性或差错,对此情形您知悉并理解;<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>欢迎纠错,并会视情况给予纠错者一定的奖励。</p> +<p>为表述便利,商品和服务简称为"商品"或"货物"。</p> +<h4>第7条 订单</h4> +<p><strong>7.1</strong>在您下订单时,请您仔细确认所购商品的名称、价格、数量、规格、联系地址、电话、收货人等信息。收货人与用户本人不一致的,收货人的行为和意思表示视为用户的行为和意思表示,用户应对收货人的行为及意思表示的法律后果承担连带责任。</p> +<p><strong>7.2</strong>除法律另有强制性规定外,双方约定如下:本站上销售方展示的商品和价格等信息仅仅是要约邀请,您下单时须填写您希望购买的商品数量、价款及支付方式、收货人、联系方式、收货地址(合同履行地点)、合同履行方式等内容;系统生成的订单信息是计算机信息系统根据您填写的内容自动生成的数据,仅是您向销售方发出的合同要约;销售方收到您的订单信息后,只有在销售方将您在订单中订购的商品从仓库实际直接向您发出时( 以商品出库为标志),方视为您与销售方之间就实际直接向您发出的商品建立了合同关系;如果您在一份订单里订购了多种商品并且销售方只给您发出了部分商品时,您与销售方之间仅就实际直接向您发出的商品建立了合同关系;只有在销售方实际直接向您发出了订单中订购的其他商品时,您和销售方之间就订单中该其他已实际直接向您发出的商品才成立合同关系。您可以随时登录您在本站注册的账户,查询您的订单状态。</p> +<p><strong>7.3</strong>由于市场变化及各种以合理商业努力难以控制的因素的影响,本站无法保证您提交的订单信息中希望购买的商品都会有货;如您拟购买的商品,发生缺货,您有权取消订单。</p> +<h4>第8条 配送</h4> +<p><strong>8.1</strong>销售方将会把商品(货物)送到您所指定的收货地址,所有在本站上列出的送货时间为参考时间,参考时间的计算是根据库存状况、正常的处理过程和送货时间、送货地点的基础上估计得出的。</p> +<p><strong>8.2</strong>因如下情况造成订单延迟或无法配送等,销售方不承担延迟配送的责任:</p> +<p>(1)用户提供的信息错误、地址不详细等原因导致的;</p> +<p>(2)货物送达后无人签收,导致无法配送或延迟配送的;</p> +<p>(3)情势变更因素导致的;</p> +<p>(4)不可抗力因素导致的,例如:自然灾害、交通戒严、突发战争等。</p> +<h4>第9条 交易争议处理</h4> +<p>您在{:WSTConf('CONF.mallName')}平台交易过程中与其他用户发生争议的,您或其他用户中任何一方均有权选择以下途径解决:</p> +<p>(1)与争议相对方自主协商;</p> +<p>(2)使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站提供的争议调处服务;</p> +<p>(3)请求消费者协会或者其他依法成立的调解组织调解;</p> +<p>(4)向有关行政部门投诉;</p> +<p>(5)根据与争议相对方达成的仲裁协议(如有)提请仲裁机构仲裁;</p> +<p>(6)向人民法院提起诉讼。</p> +<h4>第10条 责任限制及不承诺担保</h4> +<p><strong>10.1</strong>除非另有明确的书面说明,本站及其所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务,均是在"按现状"和"按现有"的基础上提供的。</p> +<p><strong>10.2</strong>除非另有明确的书面说明,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不对本站的运营及其包含在本网站上的信息、内容、材料、产品(包括软件)或服务作任何形式的、明示或默示的声明或担保(根据中华人民共和国法律另有规定的以外)。</p> +<p><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不担保本站所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务、其服务器或从本站发出的电子信件、信息没有病毒或其他有害成分。</p> +<p>如因不可抗力或其它本站无法控制的原因使本站销售系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>会合理地尽力协助处理善后事宜。</p> +<h4>第11条 协议更新及用户关注义务</h4> +<p>根据国家法律法规变化及网站运营需要,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权对本协议条款不时地进行修改,修改后的协议一旦被张贴在本站上即生效,并代替原来的协议。用户可随时登录查阅最新协议;用户有义务不时关注并阅读最新版的协议及网站公告。如用户不同意更新后的协议,可以且应立即停止接受<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站依据本协议提供的服务;如用户继续使用本网站提供的服务的,即视为同意更新后的协议。<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>建议您在使用本站之前阅读本协议及本站的公告。 如果本协议中任何一条被视为废止、无效或因任何理由不可执行,该条应视为可分的且并不影响任何其余条款的有效性和可执行性。</p> +<h4>附则</h4> +<p><strong>1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>尊重用户和消费者的合法权利,本协议及本网站上发布的各类规则、声明等其他内容,均是为了更好的、更加便利的为用户和消费者提供服务。本站欢迎用户和社会各界提出意见和建议,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>将虚心接受并适时修改本协议及本站上的各类规则。</p> +<p><strong>2</strong>本协议内容中以黑体、加粗、下划线、斜体等方式显著标识的条款,请用户着重阅读。</p> +<p><strong>3</strong>您点击本协议下方的"同意并注册"按钮即视为您完全接受本协议,在点击之前请您再次确认已知悉并完全理解本协议的全部内容。</p> +</div> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/base.html b/hyhproject/home2/view/default/users/base.html new file mode 100755 index 0000000..9d28f06 --- /dev/null +++ b/hyhproject/home2/view/default/users/base.html @@ -0,0 +1,171 @@ +<!doctype html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>{block name="title"}{:WSTConf('CONF.mallTitle')}{/block}</title> +<link href="__STYLE__/css/common.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/user.css?v={$v}" rel="stylesheet"> +{block name="css"}{/block} +<script type="text/javascript" src="__STATIC__/js/jquery.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/layer/layer.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/js/common.js?v={$v}'></script> +{block name="depend_common_js"}{/block} +<script type='text/javascript' src='__STYLE__/js/common.js?v={$v}'></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__", "SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","PHONE_VERFY":"{:WSTConf('CONF.phoneVerfy')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","TIME_TASK":"1","ROUTES":'{:WSTRoute()}',"IS_CRYPT":"{:WSTConf('CONF.isCryptPwd')}"} + {:WSTLoginTarget(0)} +$(function() { + WST.initUserCenter(); +}); +</script> +</head> +<body> +{block name="top"} + {include file="default/top" /} +{/block} +{block name="header"} + +<div class='wst-lite-bac'> +<div class='wst-lite-container'> + <div class='wst-logo'><a href='{$Request.root.true}'><img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}" height="80" width='160'></a></div> + <div class="wst-lite-tit"><span>买家中心</span><a class="wst-lite-in" href='{$Request.root.true}'>返回商城首页</a></div> + <div class="wst-lite-cart"> + <a href="{:url('home/carts/index')}" target="_blank" onclick="WST.currentUrl('{:url("home/carts/index")}');"><span class="word j-word">我的购物车<span class="num" id="goodsTotalNum">0</span></span></a> + <div class="wst-lite-carts hide"> + <div id="list-carts"></div> + <div id="list-carts2"></div> + <div id="list-carts3"></div> + <div class="wst-clear"></div> + </div> + </div> +<script id="list-cart" type="text/html"> +{{# for(var i = 0; i < d.list.length; i++){ }} + <div class="goods" id="j-goods{{ d.list[i].cartId }}"> + <div class="imgs"><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}"><img class="goodsImgc" data-original="__IMGURL__/{{ d.list[i].goodsImg }}" title="{{ d.list[i].goodsName }}"></a></div> + <div class="number"><p><a href="{{ WST.U('home/goods/detail','id='+d.list[i].goodsId) }}">{{WST.cutStr(d.list[i].goodsName,26)}}</a></p><p>数量:{{ d.list[i].cartNum }}</p></div> + <div class="price"><p>¥{{ d.list[i].shopPrice }}</p><span><a href="javascript:WST.delCheckCart({{ d.list[i].cartId }})">删除</a></span></div> + </div> +{{# } }} +</script> + <div class="wst-lite-sea"> + <div class='search'> + <input type="hidden" id="search-type" value="{:isset($keytype)?1:0}"/> + <ul class="j-search-box"> + <li class="j-search-type"> + 搜<span>{if isset($keytype)}店铺{else}商品{/if}</span>&nbsp;<i class="arrow"> </i> + </li> + <li class="j-type-list"> + {if isset($keytype)} + <div data="0">商品</div> + {else} + <div data="1">店铺</div> + {/if} + </li> + </ul> + <input type="text" id='search-ipt' class='search-ipt' value='{:isset($keyword)?$keyword:""}'/> + <div id='search-btn' class="search-btn" onclick='javascript:WST.search(this.value)'></div> + </div> + </div> + <div class="wst-clear"></div> +</div> +<div class="wst-clear"></div> +</div> +{/block} +<div class="wst-wrap"> + <div class='wst-header' style='border-bottom: 1px solid #ffffff;'> + <div class="wst-shop-nav"> + <div class="wst-nav-box"> + {php}$homeMenus = WSTHomeMenus(0);{/php} + {volist name="$homeMenus['menus']" id="vo"} + <a href="__ROOT__/{$vo['menuUrl']}?homeMenuId={$vo['menuId']}"><li class="liselect wst-lfloat {if($vo['menuId'] == $homeMenus['menuId1'])}wst-nav-boxa{/if}">{$vo['menuName']}</li></a> + {/volist} + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-nav'></div> + <div class='wst-main'> + <div class='wst-menu'> + {if isset($homeMenus['menus'][$homeMenus['menuId1']]['list']) } + {volist name="$homeMenus['menus'][$homeMenus['menuId1']]['list']" id="menus"} + <span class='wst-menu-title'>{$menus['menuName']}<img src="__STYLE__/img/user_icon_sider_zhankai.png"></span> + <ul> + {if isset($menus['list']) } + {volist name="menus['list']" id="menu" key='k'} + <li class="{if($homeMenus['menuId3']==$menu['menuId'])}wst-menua{/if} wst-menuas" onclick="getMenus('{$menu['menuId']}','{$menu['menuUrl']}')"> + {$menu['menuName']} + <span id="mId_{$menu['menuId']}"></span> + </li> + {/volist} + {/if} + </ul> + {/volist} + {/if} + + </div> + <div class='wst-content'> + {block name="content"}<div class="result"></div>{/block} + </div> + </div> + <div style='clear:both;'></div> + <div class="wst-bottom" style='display:none'> + <div class="wst-bottom-m"> + <span class="wst-bottom-ml wst-bottom-ms">我的专属推荐</span><span class="wst-bottom-ml">我关注的商品</span><span class="wst-bottom-ml">我的足迹</span> + <span class="wst-bottom-mr"><img class="wst-lfloat" src="__STYLE__/img/user_icon_hyp.png"><a href="" class="wst-lfloat">换一批</a></span> + </div> + <div style='clear:both;'></div> + <div class="wst-bottom-g"> + <div class="wst-bottom-gs"> + <div class="wst-bottom-i"><img class="goodsImg" data-original="__STYLE__/img/img_hot_02.jpg"></div> + <div class="wst-bottom-n1">商品名称商品名称商品名称商品名称商品名称</div> + <span class="wst-bottom-n2"><span class="wst-bottom-n2l">¥100.00</span><span class="wst-bottom-n2r">成交数:<span>123</span></span></span> + <span class="wst-bottom-n3"><span class="wst-bottom-n3l">市场价:¥100.00</span><span class="wst-bottom-n3r">已有<span>123</span>人评价</span></span> + <span class="wst-bottom-n4"><span class="wst-lfloat">店铺名称店铺名称</span><img class="wst-lfloat" style="margin: 2px 0px 0px 5px;" src="__STYLE__/img/icon_dianpujie_03.png"></span> + </div> + <div class="wst-bottom-gs"> + <div class="wst-bottom-i"><img class="goodsImg" data-original="__STYLE__/img/img_hot_02.jpg"></div> + <div class="wst-bottom-n1">商品名称商品名称商品名称商品名称商品名称</div> + <span class="wst-bottom-n2"><span class="wst-bottom-n2l">¥100.00</span><span class="wst-bottom-n2r">成交数:<span>123</span></span></span> + <span class="wst-bottom-n3"><span class="wst-bottom-n3l">市场价:¥100.00</span><span class="wst-bottom-n3r">已有<span>123</span>人评价</span></span> + <span class="wst-bottom-n4"><span class="wst-lfloat">店铺名称店铺名称</span><img class="wst-lfloat" style="margin: 2px 0px 0px 5px;" src="__STYLE__/img/icon_dianpujie_03.png"></span> + </div> + <div class="wst-bottom-gs"> + <div class="wst-bottom-i"><img class="goodsImg" data-original="__STYLE__/img/img_hot_02.jpg"></div> + <div class="wst-bottom-n1">商品名称商品名称商品名称商品名称商品名称</div> + <span class="wst-bottom-n2"><span class="wst-bottom-n2l">¥100.00</span><span class="wst-bottom-n2r">成交数:<span>123</span></span></span> + <span class="wst-bottom-n3"><span class="wst-bottom-n3l">市场价:¥100.00</span><span class="wst-bottom-n3r">已有<span>123</span>人评价</span></span> + <span class="wst-bottom-n4"><span class="wst-lfloat">店铺名称店铺名称</span><img class="wst-lfloat" style="margin: 2px 0px 0px 5px;" src="__STYLE__/img/icon_dianpujie_03.png"></span> + </div> + <div class="wst-bottom-gs"> + <div class="wst-bottom-i"><img class="goodsImg" data-original="__STYLE__/img/img_hot_02.jpg"></div> + <div class="wst-bottom-n1">商品名称商品名称商品名称商品名称商品名称</div> + <span class="wst-bottom-n2"><span class="wst-bottom-n2l">¥100.00</span><span class="wst-bottom-n2r">成交数:<span>123</span></span></span> + <span class="wst-bottom-n3"><span class="wst-bottom-n3l">市场价:¥100.00</span><span class="wst-bottom-n3r">已有<span>123</span>人评价</span></span> + <span class="wst-bottom-n4"><span class="wst-lfloat">店铺名称店铺名称</span><img class="wst-lfloat" style="margin: 2px 0px 0px 5px;" src="__STYLE__/img/icon_dianpujie_03.png"></span> + </div> + <div class="wst-bottom-gs"> + <div class="wst-bottom-i"><img class="goodsImg" data-original="__STYLE__/img/img_hot_02.jpg"></div> + <div class="wst-bottom-n1">商品名称商品名称商品名称商品名称商品名称</div> + <span class="wst-bottom-n2"><span class="wst-bottom-n2l">¥100.00</span><span class="wst-bottom-n2r">成交数:<span>123</span></span></span> + <span class="wst-bottom-n3"><span class="wst-bottom-n3l">市场价:¥100.00</span><span class="wst-bottom-n3r">已有<span>123</span>人评价</span></span> + <span class="wst-bottom-n4"><span class="wst-lfloat">店铺名称店铺名称</span><img class="wst-lfloat" style="margin: 2px 0px 0px 5px;" src="__STYLE__/img/icon_dianpujie_03.png"></span> + </div> + <div style='clear:both;'></div> + </div> + </div> + <div style='clear:both;'></div> + <br/> +</div> +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="js"}{/block} +<script> +function getMenus(menuId,menuUrl){ + $.post(WST.U('home/index/getMenuSession'), {menuId:menuId}, function(data){ + location.href=WST.U(menuUrl); + }); +} +</script> +</body> +</html> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/cashdraws/box_config.html b/hyhproject/home2/view/default/users/cashdraws/box_config.html new file mode 100755 index 0000000..6fa26cb --- /dev/null +++ b/hyhproject/home2/view/default/users/cashdraws/box_config.html @@ -0,0 +1,52 @@ + <form id='configForm' autocomplete='off'> + <input type='hidden' id='id' class='j-ipt' value='{$object["id"]}'/> + <table width='100%' style='margin-top:10px;' class='wst-form'> + <tr> + <th width='120' align='right'>开卡银行<font color='red'>*</font>:</th> + <td> + <select id='accTargetId' class='j-ipt' data-rule="开卡银行: required;"> + <option value=''>请选择</option> + {volist name="banks" id="vo"} + <option value='{$vo["bankId"]}' {if $object.accTargetId == $vo['bankId']}selected{/if}>{$vo["bankName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th align='right'>开卡地区<font color='red'>*</font>:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});" data-rule="开卡地区: required;"> + <option value="">-请选择-</option> + {foreach $areas as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + </tr> + <tr height='40'> + <th align='right'>卡号<font color='red'>*</font>:</th> + <td><input type='text' id='accNo' class='j-ipt' value='{$object["accNo"]}' style='width:250px' data-rule="卡号: required;"/></td> + </tr> + <tr> + <th align='right'>持卡人<font color='red'>*</font>:</th> + <td><input type='text' id='accUser' class='j-ipt' value='{$object["accUser"]}' style='width:250px' data-rule="持卡人: required;"/></td> + </tr> + <tr> + <td colspan='2' style='text-align: center;padding-top:5px;'> + <button type='button' class='wst-sec-but u-btn' onclick="editConfig()">保存</button> + <button type='button' style='margin-left:10px;' class='wst-user-buta2 u-btn' onclick='layerclose()'>取消</button> + </td> + </tr> + </table> + </form> +<script> +$(function(){ + var bankAreaIdPath = '{$object["accAreaIdPath"]}'; + if(bankAreaIdPath!=''){ + var areaIdPath = bankAreaIdPath.split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas',isRequire:true} + WST.ITSetAreas(aopts); + } +}) +</script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/cashdraws/box_draw.html b/hyhproject/home2/view/default/users/cashdraws/box_draw.html new file mode 100755 index 0000000..d8871ec --- /dev/null +++ b/hyhproject/home2/view/default/users/cashdraws/box_draw.html @@ -0,0 +1,34 @@ + <form id='drawForm' autocomplete='off' > + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <table width='100%' style='margin-top:10px;' class='wst-form' style='dislay:none'> + <tr> + <th width='120' align='right'>提现账号<font color='red'>*</font>:</th> + <td> + <select id='accId' class='j-ipt' data-rule="开卡银行: required;"> + <option value=''>请选择</option> + {volist name="accs" id="vo"} + <option value='{$vo["id"]}'>{$vo["accUser"]}|{$vo["accNo"]}</option> + {/volist} + </select> + </td> + </tr> + <tr> + <th align='right'>提现金额<font color='red'>*</font>:</th> + <td> + <input type='text' id='money' class='j-ipt' style='width:250px' data-rule="提现金额: required;" onkeypress="return WST.isNumberdoteKey(event)" onblur="javascript:WST.limitDecimal(this,2)" onkeyup="javascript:WST.isChinese(this,1)" placeholder="可提现金额:¥{$user['userMoney']-$user['rechargeMoney']}" autocomplete="off"/> + </td> + </tr> + <tr height='40'> + <th align='right'>支付密码<font color='red'>*</font>:</th> + <input type="password" style="display:none"> + <td><input type='password' id='payPwd' class='j-ipt' style='width:250px' data-rule="支付密码: required;" autocomplete="off"/></td> + </tr> + <tr> + <td colspan='2' style='text-align: center;padding-top:5px;'> + <button type='button' class='wst-sec-but u-btn' onclick="drawMoney()">保存</button> + <button type='button' style='margin-left:10px;' class='wst-user-buta2 u-btn' onclick='layerclose()'>取消</button> + </td> + </tr> + </table> + </form> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/cashdraws/cashdraws.js b/hyhproject/home2/view/default/users/cashdraws/cashdraws.js new file mode 100755 index 0000000..26bf6e9 --- /dev/null +++ b/hyhproject/home2/view/default/users/cashdraws/cashdraws.js @@ -0,0 +1,199 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0);break; + case 1:pageConfigQuery(0);break; + } + }}) +}); +var isSetPayPwd = 1; +function getUserMoney(){ + $.post(WST.U('home/users/getUserMoney'),{},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var userMoney = json.data.userMoney; + var rechargeMoney = json.data.rechargeMoney; + $('#userMoney').html('¥'+userMoney); + $('#lockMoney').html('¥'+json.data.lockMoney); + rechargeMoney = parseFloat(userMoney - rechargeMoney) + $('#userCashMoney').html('¥'+rechargeMoney.toFixed(2)); + if(json.data.isDraw==1){ + $('#drawBtn').show(); + }else{ + $('#drawBtn').hide(); + } + isSetPayPwd = json.data.isSetPayPwd; + } + }); +} +function pageQuery(p){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + $.post(WST.U('home/cashdraws/pageQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('draw-list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#draw-page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'draw-pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr); + } + } + }); + }else{ + $('#draw-pager').empty(); + } + } + }); +} +var w; +function toDrawMoney(){ + if(isSetPayPwd==0){ + WST.msg('您尚未设置支付密码,请先设置支付密码',{icon:2},function(){ + location.href = WST.U('home/users/security'); + }); + return; + } + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + $.post(WST.U('home/cashdraws/toEdit'),{},function(data,textStatus){ + layer.close(tips); + w = WST.open({ + type: 1, + title:"申请提现", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['550px', '250px'], + offset: '100px' + }); + }); +} +function drawMoney(){ + $('#drawForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.payPwd = rsa.encrypt(params.payPwd); + } + var tips = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/cashdraws/drawMoney'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + pageQuery(0); + getUserMoney(); + layer.close(w); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function layerclose(){ + layer.close(w); +} + +function pageConfigQuery(p){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + $.post(WST.U('home/cashconfigs/pageQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('config-list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#config-page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'config-pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageConfigQuery(e.curr); + } + } + }); + }else{ + $('#config-pager').empty(); + } + } + }); +} + +function toEditConfig(id){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + $.post(WST.U('home/cashconfigs/toEdit','id='+id),{},function(data,textStatus){ + layer.close(tips); + w = WST.open({ + type: 1, + title:((id>0)?"编辑":"新增")+"提现账号", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['600px', '250px'], + offset: '100px' + }); + }); +} +function editConfig(){ + $('#configForm').isValid(function(v){ + if(v){ + var params = WST.getParams('.j-ipt'); + params.accAreaId = WST.ITGetAreaVal('j-areas'); + var tips = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/cashconfigs/'+((params.id>0)?'edit':'add')),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + pageConfigQuery(0); + layer.closeAll(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} +function delConfig(id){ + WST.confirm({content:'您确定要删除该提现账号吗?',yes:function(){ + var tips = WST.load({msg:'正在提交数据,请稍后...'}); + $.post(WST.U('home/cashconfigs/del'),{id:id},function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,{icon:1},function(){ + pageConfigQuery(0); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}) +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/cashdraws/list.html b/hyhproject/home2/view/default/users/cashdraws/list.html new file mode 100755 index 0000000..962e354 --- /dev/null +++ b/hyhproject/home2/view/default/users/cashdraws/list.html @@ -0,0 +1,128 @@ +{extend name="default/users/base" /} +{block name="title"}提现管理-买家中心{__block__}{/block} +{block name='css'} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='score-head'> + <div class='user-logo'><img height='100' width='100'src='__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}'></div> + <div class='user-info'> + <div class='userName'>{:session('WST_USER.loginName')}</div> + <div class='userScore'> + <div class="usermoney"> + 可用资金:<font color='red' id='userMoney'>¥0</font> + </div> + <div class="cashbox"> + <span style='margin-left:20px;'><a class="cashbtn" id='drawBtn' href="javascript:toDrawMoney();" >申请提现</a></span> + <span class='draw-tips'>(至少¥{:WSTConf('CONF.drawCashUserLimit')}方可提现)</span> + </div> + </div> + <div class='userScore'> + <div class="usermoney"> + 冻结资金:<font color='red' id='lockMoney'>¥0</font> + </div> + <div class="usermoney"> + <span class="cashmoney-box">可提现金额:<font color='red' id='userCashMoney'>¥0</font></span> + </div> + </div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>提现记录</li> + <li>提现账号</li> + </ul> + <div class='wst-tab-content'> + <div class='wst-tab-item'> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='80'>提现单号</th> + <th width='100'>提现银行</th> + <th width='130'>开户地区</th> + <th width='130'>银行卡号</th> + <th width='100'>持卡人</th> + <th width='60'>提现金额</th> + <th width='250'>提现状态</th> + </tr> + </thead> + <script id="draw-list" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].cashNo}}</td> + <td>{{d[i].accTargetName}}</td> + <td>{{ d[i].accAreaName }}</td> + <td>{{ d[i].accNo }}</td> + <td>{{ d[i].accUser }}</td> + <td>¥{{ d[i].money }}</td> + <td {{#if(d[i].cashSatus==-1){}}style='line-height:25px;'{{#}}}> + {{#if(d[i].cashSatus==1){}}提现成功 + {{#}else if(d[i].cashSatus==-1){}}提现失败 + <br/>【原因】{{d[i].cashRemarks}} + {{#}else{}}待处理{{#}}}</td> + </tr> + {{# } }} + </script> + <tbody id="draw-page-list"></tbody> + <tfoot> + <tr> + <td colspan='7' align="center" style='padding:5px 0px 5px 0px'> + <div id="draw-pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> + {/**提现账号**/} + <div class='wst-tab-item hide'> + <div class='wst-user-tbar'> + <button class='wst-sec-but u-btn wst-rfloat' onclick="toEditConfig(0)">新增</button> + </div> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='160'>开户银行</th> + <th width='*'>开户地址</th> + <th width='180'>卡号</th> + <th width='130'>持卡人</th> + <th width='80'>操作</th> + </tr> + </thead> + <tbody id="config-page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="config-pager"></div> + </td> + </tr> + </tfoot> + </table> + <script id="config-list" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].bankName}}</td> + <td>{{d[i].areaName }}</td> + <td>{{d[i].accNo}}</td> + <td>{{d[i].accUser}}</td> + <td> + <a href='javascript:toEditConfig({{d[i].id}})'>编辑</a>&nbsp;&nbsp; + <a href='javascript:delConfig({{d[i].id}})'>删除</a> + </td> + </tr> + {{# } }} + </script> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/cashdraws/cashdraws.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script> +$(function(){ + getUserMoney(); +}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/favorites/favorites.js b/hyhproject/home2/view/default/users/favorites/favorites.js new file mode 100755 index 0000000..7414e82 --- /dev/null +++ b/hyhproject/home2/view/default/users/favorites/favorites.js @@ -0,0 +1,120 @@ +//关注的商品列表 +function freGoodsList(pages){ + var param = {}; + param.pagesize = 8; + param.page = pages; + $.post(WST.U('home/favorites/listGoodsQuery'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + if(param.page>json.TotalPage && json.TotalPage >0){ + freGoodsList(json.TotalPage); + return; + } + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list-goods').html(html); + }); + laypage({ + cont: 'goodsPage', + pages:json.TotalPage, + curr: json.CurrentPage, + skip: true, //是否开启跳页 + skin: '#f46442', + groups: 3, + prev: '<<', + next: '>>', + jump: function(e, first){ + if(!first){ + freGoodsList(e.curr); + } + } + }); + $(".wst-fav-goimg").hover(function(){ + $(this).find(".js-operate").slideDown(); + },function(){ + $(this).find(".js-operate").slideUp(); + }); + $('.goodsImg2').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + } + }); +} +function getGoods(id){ + location.href=WST.U('home/goods/detail','id='+id); +} +function cancelFavorite(id,type){ + WST.confirm({content:"您确定要取消关注吗?", yes:function(tips){ + var load = WST.load({msg:'请稍后...'}); + var param = {}; + param.id = id; + param.type = type; + $.post(WST.U('home/favorites/cancel'),param,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1},function(){ + if(type==0){ + freGoodsList(WSTCurrPage); + }else{ + freShopList(WSTCurrPage); + } + + }); + }else{ + WST.msg(json.msg,{icon:5}); + } + }); + }}); +} +//关注的店铺列表 +function freShopList(pages){ + var param = {}; + param.pagesize = 3; + param.page = pages; + $.post(WST.U('home/favorites/listShopQuery'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + if(param.page>json.TotalPage && json.TotalPage >0){ + freShopList(json.TotalPage); + return; + } + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#list-shops').html(html); + }); + //商品滑动 + var goodsNum = json.Rows.length; + for(var i=0;i<goodsNum;++i){ + $("#js-goods"+i).als({ + visible_items: 5, + scrolling_items: 1, + orientation: "horizontal", + circular: "yes", + autoscroll: "no", + start_from: 2 + }); + } + $('.goodsImg2').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO});//商品默认图片 + $('.shopsImg2').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.SHOP_LOGO});//店铺默认头像 + laypage({ + cont: 'shopsPage', + pages:json.TotalPage, + curr: json.CurrentPage, + skip: true, //是否开启跳页 + skin: '#f46442', + groups: 3, + prev: '<<', + next: '>>', + jump: function(e, first){ + if(!first){ + freShopList(e.curr); + } + } + }); + } + }); +} +function getShop(id){ + location.href=WST.U('home/shops/home','shopId='+id); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/favorites/list_goods.html b/hyhproject/home2/view/default/users/favorites/list_goods.html new file mode 100755 index 0000000..5e73d6b --- /dev/null +++ b/hyhproject/home2/view/default/users/favorites/list_goods.html @@ -0,0 +1,36 @@ +{extend name="default/users/base" /} +{block name="title"}关注的商品 - 买家中心{__block__}{/block} +{block name="css"}{/block} +{block name="content"} +<div class="wst-user-head"><span>我关注的商品 </span></div> +<div class="wst-clear"></div> +<div class="wst-fav-listg" id="list-goods"></div> +<div class="wst-clear"></div> +<div class="wst-fav-pa"><div id="goodsPage"></div></div> +<script id="list" type="text/html"> +{{# for(var i = 0; i < d.length; i++){}} + <div class="wst-fav-goods"> + <div class="wst-fav-goimg"><img class="goodsImg2" data-original="__IMGURL__/{{ d[i].goodsImg }}" title="{{ d[i].goodsName }}"><span class="js-operate" onclick="javascript:cancelFavorite({{ d[i].favoriteId }},0)">取消收藏</div> + <a href="javascript:getGoods({{ d[i].goodsId }})"> + <p class="wst-fav-gonam">{{WST.cutStr(d[i].goodsName,50)}}</p> + <p class="wst-fav-goodp1"><span class="wst-fav-goodpr">¥{{ d[i].shopPrice }}</span><span class="wst-rfloat">成交数:<span class="wst-fav-goodpr2">{{ d[i].saleNum }}</span></p> + <p class="wst-fav-goodp2"><span class="wst-fav-goodpr3">市场价:¥{{ d[i].marketPrice }}</span><span class="wst-rfloat">已有<span class="wst-fav-goodpr4">{{ d[i].appraiseNum }}</span>人评价</span></p> + <p class="wst-fav-shop"> + <span class="wst-lfloat">{{WST.cutStr(d[i].shopName,8)}}</span> + {{# for(var a = 0; a < d[i].accreds.length; a++){ }} + <img src="__IMGURL__/{{ d[i].accreds[a].accredImg }}" title="{{ d[i].accreds[a].accredName }}"> + {{# } }} + </p> + </a> + </div> +{{# } }} +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/favorites/favorites.js?v={$v}'></script> +<script> +$(function(){ + freGoodsList(); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/favorites/list_shops.html b/hyhproject/home2/view/default/users/favorites/list_shops.html new file mode 100755 index 0000000..a1dc8be --- /dev/null +++ b/hyhproject/home2/view/default/users/favorites/list_shops.html @@ -0,0 +1,49 @@ +{extend name="default/users/base" /} +{block name="title"}关注的店铺 - 买家中心{__block__}{/block} +{block name="css"}{/block} +{block name="content"} +<div class="wst-user-head"><span>我关注的店铺</span></div> +<div class="wst-clear"></div> +<div id="list-shops"></div> +<div class="wst-fav-pa"><div id="shopsPage"></div></div> +<script id="list" type="text/html"> +{{# for(var i = 0; i < d.length; i++){ }} + <div class="wst-favo-shop"> + <div class="wst-favo-shopl"> + <a href="javascript:getShop({{ d[i].shopId }})" class="wst-favo-shopimg"><img class="shopsImg2" data-original="__IMGURL__/{{ d[i].shopImg }}" title="{{ d[i].shopName }}"/></a> + <p>{{WST.cutStr(d[i].shopName,15)}}</p> + <a href="javascript:getShop({{ d[i].shopId }})" class="wst-favo-shopa">进入店铺</a><a href="javascript:cancelFavorite({{ d[i].favoriteId }},1)" class="wst-favo-shopa">取消关注</a> + </div> + <div class="wst-favo-shopr"> + <div class="wst-favo-more"><span class="wst-lfloat">推荐商品</span><a href="javascript:getShop({{ d[i].shopId }})" class="wst-rfloat">查看更多 ></a></div> + <div class="wst-favo-good wst-lfloat"> + <div class="als-container" id="{{# if(d[i].goods.length>5){ }}js-goods{{i}}{{# } }}"> + {{# if(d[i].goods.length>5){ }}<span class="als-prev"><img src="__STYLE__/img/icon_left.png" alt="prev" title="previous" /></span>{{# } }} + <div class="als-viewport"> + <ul class="als-wrapper"> + {{# for(var a = 0; a < d[i].goods.length; a++){ }} + <li class="als-item wst-favo-goods"> + <div class="wst-favo-goodimg"><a href="javascript:getGoods({{ d[i].goods[a].goodsId }})"><img class="goodsImg2" data-original="__IMGURL__/{{ d[i].goods[a].goodsImg }}" title="{{ d[i].goods[a].goodsName }}"/></a></div> + <span>¥{{ d[i].goods[a].shopPrice }}</span> + </li> + {{# } }} + </ul> + </div> + {{# if(d[i].goods.length>5){ }}<span class="als-next"><img src="__STYLE__/img/icon_right.png" alt="next" title="next" /></span>{{# } }} + </div> + </div> + </div> + <div class="wst-clear"></div> + </div> +{{# } }} +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/jquery.als.js?v={$v}'></script> +<script type='text/javascript' src='__STYLE__/users/favorites/favorites.js?v={$v}'></script> +<script> +$(function(){ + freShopList(); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/index.html b/hyhproject/home2/view/default/users/index.html new file mode 100755 index 0000000..e44e4be --- /dev/null +++ b/hyhproject/home2/view/default/users/index.html @@ -0,0 +1,6 @@ +{extend name="default/users/base" /} +{block name="title"}买家中心 - {:WSTConf('CONF.mallName')}{__block__}{/block} +{block name="css"} +{/block} +{block name="main"}{/block} +{block name="js"}{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/informs/inform_detail.html b/hyhproject/home2/view/default/users/informs/inform_detail.html new file mode 100755 index 0000000..2144027 --- /dev/null +++ b/hyhproject/home2/view/default/users/informs/inform_detail.html @@ -0,0 +1,149 @@ +{extend name="default/users/base" /} +{block name="title"}举报详情 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<div class='wst-inform-content'> +<form id="informForm" method="post" > +<div class="wst-inform-head"><span>举报详情</span></div> + <div class='order-box wst-inform-box'> + + <div class='log-box inform-log-box' style="height: auto;" > +<div class="state"> + <div class="icon" style="margin-left: 20px;"> + <span class="icons icon13 "></span> + </div> + <div class="arrow arrow2">··················></div> + <div class="icon" > + <span class="icons icon13 "></span> + </div> + <div class="arrow arrow2">·················></div> + <div class="icon" > + + {if condition="$data['informStatus'] eq 0"} + <span class="icons icon12 "></span> + {else} + <span class="icons icon13 "></span> + {/if} + </div> +</div> + <div class="state3" > + <p>提交举报表单</p><p>等待管理员处理</p><p>完成举报</p> + </div> + + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-inform-box"> + <div class="title">被举报商家 :</div><a target='_blank' href="{:url('home/shops/home',array('shopId'=>$data['shopId']))}">{$data['shopName']}</a> + <div class="wst-clear"></div> + </div> + <!-- 订单信息 --> + <div class='wst-inform-box'> + <div class="title"> + <span>相关商品 :</span> + </div> + <div class="goods-img"> + <a href="{:Url('home/goods/detail','id='.$data['goodsId'])}" target='_blank'> + <div class="wst-img"><img src="__IMGURL__/{:WSTImg($data['goodsImg'])}"></img></div> + </a> + <div class="wst-text"> + <a href='{:Url("home/goods/detail","id=".$data["goodsId"])}' target='_blank'>{$data['goodsName']}</a> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box'> + <div class="title">举报类型:</div> + <div class="goods-img"> + {php}$reason = WSTDatas('INFORMS_TYPE',$data['informType']);{/php} + {$reason['dataName']} + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box'> + <div class="title">举报内容:</div> + <div class="goods-img"> + {$data['informContent']} + </div> + <div class="wst-clear"></div> + </div> + <div id="photos-inform" class='wst-inform-box' style="border-bottom: 1px solid transparent;"> + <div class="title">附件:</div> + {volist name="$data['informAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}" /> + </a> + {/volist} + </div> + <div class='wst-inform-box'> + <div class="title">举报时间:</div> + <div class="goods-img"> + {$data['informTime']} + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box'> + <div class="title">举报结果:</div> + <div class="goods-img"> + {if condition="$data['informStatus'] eq 0"} + 等待处理 + {elseif condition="$data['informStatus'] eq 1"/} + 无效举报 + {elseif condition="$data['informStatus'] eq 2 "/} + 有效举报 + {elseif condition="$data['informStatus'] eq 3 "/} + 恶意举报 + {/if} + </div> + + {if condition="$data['informStatus'] eq 1 OR $data['informStatus'] eq 2 OR $data['informStatus'] eq 3"} + <div class="title">处理信息:</div> + <div class="goods-img"> + {$data['respondContent']} + </div> + <div class="title">处理时间:</div> + <div class="goods-img"> + {$data['finalHandleTime']}&nbsp; + </div> + {/if} + <div class="wst-clear"></div> + </div> + <div class='wst-complain-footer'> + <button onclick="javascript:history.go(-1)" class="wst-sec-but u-btn">返回</button> + </div> +</form> +</div> +<div class="wst-remind"> + <div class="wst-inform-head" ><span>违规举报须知</span></div> + <div class="content"> + <div class="alert"> + <ul> + <li> 1.请提供充分的证据以确保举报成功,请珍惜您的会员权利,帮助商城更好地管理网站;</li> + <li> 2.被举报待处理的商品不能反复进行违规提交,处理下架后的商品不能再次举报,商家如重新上架后仍存在违规现象,可再次对该商品进行违规举报;</li> + <li> 3.举报仅针对商品或商家本身,如需处理交易中产生的纠纷,请选择投诉;</li> + <li> 4.举报时依次选择举报类型及举报主题(必填),填写违规描述(必填,不超过200字),上传5张以内的举证图片(选填),详细的举报内容有助于平台对该条举报的准确处理。</li> + </ul> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/informs/informs.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){ + userComplainInit(); + // 调用图像层 + layer.photos({ + photos: '#photos-inform' + }); +}) +</script> +{/block} + + + diff --git a/hyhproject/home2/view/default/users/informs/informs.html b/hyhproject/home2/view/default/users/informs/informs.html new file mode 100755 index 0000000..fc8ccb9 --- /dev/null +++ b/hyhproject/home2/view/default/users/informs/informs.html @@ -0,0 +1,113 @@ +{extend name="default/users/base" /} +{block name="title"}举报商品 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<div class='wst-inform-content'> +<form id="informForm" method="post" > + <input type='hidden' id='goodsId' class='ipt' value="{$data['data']['goodsId']}"/> + <input type='hidden' id='shopsId' class='ipt' value="{$data['data']['shopId']}"/> +<div class="wst-inform-head"><span>举报商品</span></div> + <div class='order-box wst-inform-box'> + + <div class='log-box inform-log-box' style="height: auto;" > +<div class="state"> + <div class="icon"> + <span class="icons icon13 "></span> + </div> + <div class="arrow arrow2">··················></div> + <div class="icon"> + <span class="icons icon12 "></span> + </div> + <div class="arrow arrow2">··················></div> + <div class="icon"> + <span class="icons icon12 "></span> + </div> +</div> + <div class="state3" > + <p>提交举报表单</p><p>等待管理员处理</p><p>完成举报</p> + </div> + + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-inform-box"> + <div class="title">被举报商家 :</div><a target='_blank' href="{:url('home/shops/home',array('shopId'=>$data['data']['shopId']))}">{$data['data']['shopName']}</a> + <div class="wst-clear"></div> + </div> + <!-- 订单信息 --> + <div class='wst-inform-box'> + <div class="title"> + <span>相关商品 :</span> + </div> + <div class="goods-img"> + <a href="{:Url('home/goods/detail','id='.$data['data']['goodsId'])}" target='_blank'> + <div class="wst-img"><img src="__IMGURL__/{:WSTImg($data['data']['goodsImg'])}"></img></div> + </a> + <div class="wst-text"> + <a href='{:Url("home/goods/detail","id=".$data["data"]["goodsId"])}' target='_blank'>{$data['data']['goodsName']}</a> + </div> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box'> + <div class="title"><font color='red'>*</font>举报类型:</div> + <div class="goods-img"> + {php}$reason = WSTDatas('INFORMS_TYPE');{/php} + {volist name='reason' id='vo'} + <label><input type='radio' name='informType' class='ipt' autocomplete="off" value='{$vo['dataVal']}' {if $key==1}checked{/if}>{$vo['dataName']}</label> + {/volist} + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box'> + <div class="title"><font color='red'>*</font>举报内容:</div> + <div class="goods-img"> + <textarea id='informContent' maxlength="200" onchange="this.value=this.value.substring(0, 200)" onkeydown="this.value=this.value.substring(0, 200)" onkeyup="this.value=this.value.substring(0, 200)" name="informContent" class='ipt' autocomplete="off" style='width:100%;height:155px;' placeholder='请输入举报内容'></textarea> + </div> + <div class="wst-clear"></div> + </div> + <div class='wst-inform-box' style="border-bottom: 1px solid transparent;"> + <div id="filePicker" style='margin-left:0px;width:250px;overflow:hidden;height:25px;'>上传附件(最多5张)</div> + </div> + <div class='wst-inform-box'> + <table> + <tr> + <td colspan='2'> + <div id='picBox' style='height:120px;width:612px;padding:5px;'></div> + </td> + </tr> + </table> + </div> + <div class='wst-complain-footer'> + <button onclick="javascript:saveInforms()" class="wst-sec-but u-btn">提交</button> + <button onclick="javascript:history.go(-1)" class="wst-sec-but u-btn">返回</button> + </div> +</form> +</div> +<div class="wst-remind"> + <div class="wst-inform-head" ><span>违规举报须知</span></div> + <div class="content"> + <div class="alert"> + <ul> + <li> 1.请提供充分的证据以确保举报成功,请珍惜您的会员权利,帮助商城更好地管理网站;</li> + <li> 2.被举报待处理的商品不能反复进行违规提交,处理下架后的商品不能再次举报,商家如重新上架后仍存在违规现象,可再次对该商品进行违规举报;</li> + <li> 3.举报仅针对商品或商家本身,如需处理交易中产生的纠纷,请选择投诉;</li> + <li> 4.举报时依次选择举报类型及举报主题(必填),填写违规描述(必填,不超过200字),上传5张以内的举证图片(选填),详细的举报内容有助于平台对该条举报的准确处理。</li> + </ul> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/informs/informs.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){ + userComplainInit(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/informs/informs.js b/hyhproject/home2/view/default/users/informs/informs.js new file mode 100755 index 0000000..ef26e74 --- /dev/null +++ b/hyhproject/home2/view/default/users/informs/informs.js @@ -0,0 +1,105 @@ +//图片文件上传 +function userComplainInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'informsImg',isThumb:0}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<div style='width:75px;float:lefst;margin-right:5px;'>"+ + "<img class='inform_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#picBox').append(tdiv); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +function saveInforms(historyURL){ + /* 表单验证 */ + $('#informForm').validator({ + fields: { + informContent: { + rule:"required", + msg:{required:"清输入举报内容"}, + tip:"请输入举报内容", + }, + informType: { + rule:"checked;", + msg:{checked:"举报类型不能为空"}, + tip:"请选择举报类型", + } + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var img = []; + $('.inform_pic').each(function(){ + img.push($(this).attr('v')); + }); + params.informAnnex = img.join(','); + $.post(WST.U('home/informs/saveInform'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('您的举报已提交,请留意信息回复', {icon: 6},function(){ + location.href = WST.U('home/informs/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +function toView(id){ + location.href=WST.U('home/Informs/getUserInformDetail',{'id':id}); +} +function informByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/informs/queryUserInformPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + complainByPage(e.curr); + } + } + }); + + + }else{ + $('#pager').empty(); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/informs/list_inform.html b/hyhproject/home2/view/default/users/informs/list_inform.html new file mode 100755 index 0000000..1fbcbdf --- /dev/null +++ b/hyhproject/home2/view/default/users/informs/list_inform.html @@ -0,0 +1,66 @@ +{extend name="default/users/base" /} +{block name="title"}违规举报 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>违规举报</span></div> + <div class='wst-user-tbar'> + 商品名称:<select name="informStatus" id="informStatus" class="s-query"> + <option value="-1">举报处理状态</option> + <option value="0">等待处理</option> + <option value="1">无效举报</option> + <option value="2">有效举报</option> + <option value="3">恶意举报</option> + </select> + <button class="wst-sec-but u-btn" onclick="informByPage()">查询</button> + </div> + + <div class='wst-user-content'> + <table class='wst-list'> + <thead> + <tr class='head' style="align-content: center;"> + <th>举报编号</th> + <th>举报商品</th> + <th>涉及店铺</th> + <th>举报原因</th> + <th>举报时间</th> + <th>举报状态</th> + <th>操作</th> + </tr> + </thead> +<tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td style="text-align: center;"> + {{d[i]['informId']}} + </td> + + <td>{{WST.cutStr(d[i]['goodsName'],30)}}</td> + + <td>{{d[i]['shopName']}}</td> + + <td title="{{d[i]['informContent']}}">{{WST.cutStr(d[i]['informContent'],30)}}</td> + + <td>{{d[i]['informTime']}}</td> + + <td>{{d[i]['informStatus']}}</td> + + <td><a style="cursor:pointer;" onclick="toView({{d[i]['informId']}})">查看</a></td> + </tr> + {{# } }} + </script> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/informs/informs.js?v={$v}'></script> +<script> +$(function(){ + informByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/logmoneys/list.html b/hyhproject/home2/view/default/users/logmoneys/list.html new file mode 100755 index 0000000..0783eb6 --- /dev/null +++ b/hyhproject/home2/view/default/users/logmoneys/list.html @@ -0,0 +1,60 @@ +{extend name="default/users/base" /} +{block name="title"}资金流水-买家中心{__block__}{/block} +{block name="content"} +<div class='score-head'> + <div class='user-logo'><img height='100' width='100'src='__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}'></div> + <div class='user-info'> + <div class='userName'>{:session('WST_USER.loginName')}</div> + <div class='userScore'>可用资金:<font color='red'>¥{$object['userMoney']}</font></div> + <div class='userScore'>冻结资金:<font color='red'>¥{$object['lockMoney']}</font></div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>资金流水</li> + <li>资金收入</li> + <li>资金支出</li> + </ul> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='80'>来源/用途</th> + <th width='100'>金额</th> + <th width='150'>日期</th> + <th width='130'>外部流水号</th> + <th width='*'>备注</th> + </tr> + </thead> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i].dataSrc}}</td> + <td> + {{# if(d[i].moneyType==1){ }} + <span class="money-add">+ ¥{{ d[i].money }}</span> + {{# }else{ }} + <span class='money-reduce'> - ¥{{ d[i].money }}</span> + {{# } }} + </td> + <td>{{ d[i].createTime }}</td> + <td>{{ WST.blank(d[i].tradeNo,'-')}}</td> + <td style='line-height:23px'>{{ d[i].remark }}</td> + </tr> + {{# } }} + </script> + <tbody id="page-list"></tbody> + <tfoot> + <tr> + <td colspan='5' align="center" style='padding:5px 0px 5px 0px'> + <div id="pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/logmoneys/logmoneys.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/logmoneys/logmoneys.js b/hyhproject/home2/view/default/users/logmoneys/logmoneys.js new file mode 100755 index 0000000..d1fdb9c --- /dev/null +++ b/hyhproject/home2/view/default/users/logmoneys/logmoneys.js @@ -0,0 +1,42 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0,-1);break; + case 1:pageQuery(0,1);break; + case 2:pageQuery(0,0);break; + } + }}) +}); +function pageQuery(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + params.type = type; + $.post(WST.U('home/logmoneys/pageUserQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/messages/list.html b/hyhproject/home2/view/default/users/messages/list.html new file mode 100755 index 0000000..35281fb --- /dev/null +++ b/hyhproject/home2/view/default/users/messages/list.html @@ -0,0 +1,82 @@ +{extend name="default/users/base" /} +{block name="title"}首页-买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-user-head"><span>用户信息</span></div> +<div class="wst-clear"></div> +<div class="u-menu"> + <a href="javascript:void(0)" onclick="batchRead()">标记为已读</a> | + <a href='javascript:void(0);' onclick="batchDel()" >删除</a> +</div> + + <div class="wst-body"> + <div class='wst-page-content'> + <table class='wst-list'> + <thead> + <tr> + <th width='25'> + <div class="checkbox-box-s"> + <input class="wst-checkbox-s" onclick="javascript:WST.checkChks(this,'.chk')" type='checkbox' id="all"/> + <label for="all"></label> + </div> + </th> + <th width='45'>状态</th> + <th>消息</th> + <th width='130'>时间</th> + <th width='100'>操作</th> + </tr> + </thead> + <script id="msg" type="text/html"> + {{# for(var i = 0, len = d.length; i < len; i++){ }} + <tr> + <td> + <div class="checkbox-box-s"> + <input type='checkbox' class='chk wst-checkbox-s' id="chk-{{i}}" value='{{ d[i].id }}' /><label class='mt-1' for="chk-{{i}}"></label> + </div> + </td> + <td> + + {{# if(d[i].msgStatus ==1) { }} + <div class='readMsg'></div> + {{# }else{ }} + <div class='newMsg'></div> + {{# } }} + </td> + <td><div class="wst-hide msg-content">{{ d[i].msgContent }}</div></td> + <td>{{ d[i].createTime }}</td> + <td> + <a class="s-handle" href="javascript:showMsg({{ d[i].id }})">[查看]</a> + <a class="s-handle" href="javascript:delMsg(this,{{ d[i].id }})">[删除]</a> + &nbsp; + </td> + </tr> + {{# } }} + </script> + <tbody id="msg_box"> + + + + + + <tfoot> + <tr> + <td colspan='12' align='center'> + + <div id="wst-page" class='wst-page' style="padding-bottom:10px;"> + </div> + + </td> + </tr> + </tfoot> + </tbody> + </table> + + + + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/messages/message.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home2/view/default/users/messages/message.js b/hyhproject/home2/view/default/users/messages/message.js new file mode 100755 index 0000000..8111ab7 --- /dev/null +++ b/hyhproject/home2/view/default/users/messages/message.js @@ -0,0 +1,106 @@ +$(function(){ + queryByList(); +}); +function queryByList(p){ + var params = {}; + params.page = p; + var load = WST.load({msg:'正在加载信息,请稍后...'}) + $.post(WST.U('Home/Messages/pageQuery'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.data){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + queryByList(json.TotalPage); + return; + } + var gettpl = document.getElementById('msg').innerHTML; + //复选框为未选中状态 + $('#all').attr('checked',false); + laytpl(gettpl).render(json.Rows, function(html){ + $('#msg_box').html(html); + }); + laypage({ + cont: 'wst-page', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + queryByList(e.curr); + } + } + }); + + } + }); +} + +function showMsg(id){ + location.href=WST.U('home/messages/showMsg','msgId='+id); +} + +function delMsg(obj,id){ +WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var ll = WST.load('数据处理中,请稍候...'); + $.post(WST.U('home/messages/del'),{id:id},function(data,textStatus){ + layer.close(ll); + layer.close(tips); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!', {icon: 1}, function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); +}}); +} +function batchDel(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择要删除的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要删除该消息吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchDel'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} +function batchRead(){ + var ids = WST.getChks('.chk'); + if(ids==''){ + WST.msg('请选择处理的消息!', {icon: 5}); + return; + } + WST.confirm({content:"您确定要将这些消息标记为已读吗?", yes:function(tips){ + var params = {}; + params.ids = ids; + var load = WST.load({msg:'请稍后...'}); + $.post(WST.U('home/messages/batchRead'),params,function(data,textStatus){ + layer.close(load); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功',{icon:1},function(){ + queryByList(WSTCurrPage); + }); + }else{ + WST.msg('操作失败',{icon:5}); + } + }); + }}); +} diff --git a/hyhproject/home2/view/default/users/messages/show.html b/hyhproject/home2/view/default/users/messages/show.html new file mode 100755 index 0000000..df5261a --- /dev/null +++ b/hyhproject/home2/view/default/users/messages/show.html @@ -0,0 +1,25 @@ +{extend name="default/users/base" /} +{block name="title"}首页-买家中心{__block__}{/block} +{block name="css"} +<style> +.msgContent img{ + width: 100%; +} +</style> +{/block} +{block name="content"} +<div class="wst-user-head"><span>查看消息</span><a href="<?=url('home/Messages/Index');?>">返回</a></div> +<div class="wst-clear"></div> + <div class="wst-body"> + <div class='wst-page-content'> + <div class='wst-tbar-group'> + + </div> + <div class="msgContent"> + {$data['msgContent']} + </div> + </div> + </div> +{/block} +{block name="js"} +{/block} diff --git a/hyhproject/home2/view/default/users/my_consult.html b/hyhproject/home2/view/default/users/my_consult.html new file mode 100755 index 0000000..299d313 --- /dev/null +++ b/hyhproject/home2/view/default/users/my_consult.html @@ -0,0 +1,107 @@ +{extend name="default/users/base" /} +{block name="title"}购买咨询 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>购买咨询</span></div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th width="10%">咨询商品</th> + <th width="20%">商品名称</th> + <th>咨询回复</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr> + <td width="10%" class="tc g_bd"> + <a href="{{WST.U('home/goods/detail','id='+d[i].goodsId)}}" target="_blank" class="gc_a"> + <img class="gImg" src="__IMGURL__/{{d[i].goodsImg}}" width="60" height="60"> + </a> + </td> + <td width="20%" class="pd10 g_bd"> + <a href="{{WST.U('home/goods/detail','id='+d[i].goodsId)}}" target="_blank" class="gc_a">{{d[i].goodsName}}</a> + </td> + <td class="pd10 g_bd" style="vertical-align:top"> + <div class="my_consultbox"> + <span class="my_consult">我的咨询:{{d[i].consultContent}}</span> + <span class="consult_time c999">{{d[i].createTime}}</span> + <div class="wst-clear"></div> + </div> + {{# if(WST.blank(d[i].reply)!=''){ }} + <div class="gc_replytit"> + 商家回复: + </div> + <div> + {{d[i].reply}} + </div> + <div class="c999">{{d[i].replyTime}}</div> + {{# }else{ }} + <div class="gc_replytit">(暂无回复)</div> + {{# } }} + + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script> +$(function(){ + myConsultByPage(); +}) +function gDetail(id){ + return WST.U('home/goods/detail',{id:id}); +} +function myConsultByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goodsconsult/myConsultByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + myConsultByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + myConsultByPage(e.curr); + } + } + }); + } + }); +} +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/appraise_manage.html b/hyhproject/home2/view/default/users/orders/appraise_manage.html new file mode 100755 index 0000000..6b37640 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/appraise_manage.html @@ -0,0 +1,86 @@ +{extend name="default/users/base" /} +{block name="title"}我的评价 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>我的评价</span></div> + <div class="wst-user-content"> + <table class='wst-list'> + <thead> + <tr> + <th>订单号</th> + <th>商品信息</th> + <th>商品评分</th> + <th>服务评分</th> + <th>时效评分</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i]['orderNo']}}</td> + <td> + <div class="goods-info"> + <img class='j-lazyImg' width='50' width='50' data-original='__IMGURL__/{{d[i].goodsImg}}'/> + <p class="goodsName"> + {{d[i]['goodsName']}} + </p> + <div class="wst-clear"></div> + </div> + </td> + <td> + {{# for(var gs=0;gs<d[i]['goodsScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['serviceScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['timeScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + </tr> + <tr> + <td colspan='5'>评价:{{d[i]['content']}} + {{# if(d[i]['images']){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + <img src="__IMGURL__/{{img[g]}}" layer-src="__IMGURL__/{{img[g]}}" width="30" height="30" /> + + {{# } }} + </div> + {{# } }} + {{# if(d[i]['shopReply']!='' && d[i]['shopReply']!=null){ }} + <div class="reply-box"> + <p class="reply-content">{{d[i]['shopName']}}【{{d[i]['replyTime']}}】:{{d[i]['shopReply']}}</p> + </div> + {{# } }} + + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + userAppraise(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/appraise_manage▒╛╡╪═╝╞м.html b/hyhproject/home2/view/default/users/orders/appraise_manage▒╛╡╪═╝╞м.html new file mode 100755 index 0000000..7e905d2 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/appraise_manage▒╛╡╪═╝╞м.html @@ -0,0 +1,85 @@ +{extend name="default/users/base" /} +{block name="title"}我的评价 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>我的评价</span></div> + <div class="wst-user-content"> + <table class='wst-list'> + <thead> + <tr> + <th>订单号</th> + <th>商品信息</th> + <th>商品评分</th> + <th>服务评分</th> + <th>时效评分</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i]['orderNo']}}</td> + <td> + <div class="goods-info"> + <img class='j-lazyImg' width='50' width='50' data-original='__ROOT__/{{d[i].goodsImg}}'/> + <p class="goodsName"> + {{d[i]['goodsName']}} + </p> + <div class="wst-clear"></div> + </div> + </td> + <td> + {{# for(var gs=0;gs<d[i]['goodsScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['serviceScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['timeScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + </tr> + <tr> + <td colspan='5'>评价:{{d[i]['content']}} + {{# if(d[i]['images']){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + <img src="__ROOT__/{{img[g].replace('.','_thumb.')}}" layer-src="__ROOT__/{{img[g]}}" width="30" height="30" /> + {{# } }} + </div> + {{# } }} + {{# if(d[i]['shopReply']!='' && d[i]['shopReply']!=null){ }} + <div class="reply-box"> + <p class="reply-content">{{d[i]['shopName']}}【{{d[i]['replyTime']}}】:{{d[i]['shopReply']}}</p> + </div> + {{# } }} + + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + userAppraise(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/appraise_manage鈻掆暃鈺♀暘鈺愨暆鈺炐_html b/hyhproject/home2/view/default/users/orders/appraise_manage鈻掆暃鈺♀暘鈺愨暆鈺炐_html new file mode 100755 index 0000000..7e905d2 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/appraise_manage鈻掆暃鈺♀暘鈺愨暆鈺炐_html @@ -0,0 +1,85 @@ +{extend name="default/users/base" /} +{block name="title"}我的评价 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>我的评价</span></div> + <div class="wst-user-content"> + <table class='wst-list'> + <thead> + <tr> + <th>订单号</th> + <th>商品信息</th> + <th>商品评分</th> + <th>服务评分</th> + <th>时效评分</th> + </tr> + </thead> + <tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td>{{d[i]['orderNo']}}</td> + <td> + <div class="goods-info"> + <img class='j-lazyImg' width='50' width='50' data-original='__ROOT__/{{d[i].goodsImg}}'/> + <p class="goodsName"> + {{d[i]['goodsName']}} + </p> + <div class="wst-clear"></div> + </div> + </td> + <td> + {{# for(var gs=0;gs<d[i]['goodsScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['serviceScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + + <td> + {{# for(var gs=0;gs<d[i]['timeScore'];++gs){ }} + <img src="__STATIC__/plugins/raty/img/star-on.png"> + {{# } }} + </td> + </tr> + <tr> + <td colspan='5'>评价:{{d[i]['content']}} + {{# if(d[i]['images']){ var img = d[i]['images'].split(','); var length = img.length; }} + <div id="img-file-{{i}}"> + {{# for(var g=0;g<length;g++){ }} + <img src="__ROOT__/{{img[g].replace('.','_thumb.')}}" layer-src="__ROOT__/{{img[g]}}" width="30" height="30" /> + {{# } }} + </div> + {{# } }} + {{# if(d[i]['shopReply']!='' && d[i]['shopReply']!=null){ }} + <div class="reply-box"> + <p class="reply-content">{{d[i]['shopName']}}【{{d[i]['replyTime']}}】:{{d[i]['shopReply']}}</p> + </div> + {{# } }} + + </td> + </tr> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + userAppraise(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/box_cancel.html b/hyhproject/home2/view/default/users/orders/box_cancel.html new file mode 100755 index 0000000..454b30d --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/box_cancel.html @@ -0,0 +1,15 @@ +<table class='wst-form' style='margin-top:30px;'> + <tr> + <td colspan='2' style='padding-left:70px;'>请选择您取消订单的原因,以便我们能更好的为您服务。</td> + </tr> + <tr> + <th width='120'>取消原因:</th> + <td> + <select id='reason'> + {volist name=":WSTDatas('ORDER_CANCEL')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> +</table> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/orders/box_refund.html b/hyhproject/home2/view/default/users/orders/box_refund.html new file mode 100755 index 0000000..b21543c --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/box_refund.html @@ -0,0 +1,33 @@ +<table class='wst-form' style='margin-top:10px;width:90%'> + <tr> + <td colspan='2' style='padding-left:70px;'>请选择取消订单申请退款的原因,以便我们能更好的为您服务。</td> + </tr> + <tr> + <th width='120'>原因:</th> + <td> + <select id='reason' onchange='javascript:changeRejectType(this.value)'> + {volist name=":WSTDatas('REFUND_TYPE')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr id='rejectTr' style='display:none'> + <th width='120'>原因<font color='red'>*</font>:</th> + <td> + <textarea id='content' style='width:99%;height:50px;' maxLength='200'></textarea> + </td> + </tr> + <tr style="line-height: 20px"> + <th width='120' >退款金额<font color='red'>*</font>:</th> + <td> + <input type='text' id='money' maxLength='10' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" + onblur='javascript:WST.limitDecimal(this,2)' style="margin-top: 20px;"> + <br/>(金额不能超过<font color='red'>¥{$object['realTotalMoney']}</font>{if $object['ectNum']!=""}<font color='green'>≈{$object['ectNum']}ECT</font>{/if}) + </td> + </tr> + <tr> + <th width='120'>退回积分:</th> + <td>{$object['useScore']}个(积分抵扣<font color='red'>¥{$object['scoreMoney']}</font>)</td> + </tr> +</table> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/orders/box_reject.html b/hyhproject/home2/view/default/users/orders/box_reject.html new file mode 100755 index 0000000..92d2b12 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/box_reject.html @@ -0,0 +1,21 @@ +<table class='wst-form' style='margin-top:10px;width:90%'> + <tr> + <td colspan='2' style='padding-left:70px;'>请选择您拒收订单的原因,以便我们能更好的为您服务。</td> + </tr> + <tr> + <th width='120'>取消原因:</th> + <td> + <select id='reason' onchange='javascript:changeRejectType(this.value)'> + {volist name=":WSTDatas('ORDER_REJECT')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </td> + </tr> + <tr id='rejectTr' style='display:none'> + <th width='120'>原因<font color='red'>*</font>:</th> + <td> + <textarea id='content' style='width:99%;height:80px;' maxLength='200'></textarea> + </td> + </tr> +</table> \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/orders/complain.html b/hyhproject/home2/view/default/users/orders/complain.html new file mode 100755 index 0000000..4aa3b2c --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/complain.html @@ -0,0 +1,88 @@ +{extend name="default/users/base" /} +{block name="title"}投诉订单 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} + <div class="wst-user-head"><span>投诉订单</span></div> + <div class='wst-user-content'> + <form id="complainForm" method="post" > + {if condition="$data['complainStatus'] eq 0"} + <input type='hidden' id='orderId' class='ipt' value="{$data['order']['orderId']}"/> + <div class='wst-complain-left'> + <div class='wst-complain-order-head'>订单商品</div> + <div class='wst-complain-order-goods'> + {volist name="$data['order']['goodsList']" id="goods" key='key2'} + <a target='_blank' href="{:Url('Home/Goods/detail',array('id'=>$goods['goodsId']))}" title="{$goods['goodsName']}"> + + <img data-original="__IMGURL__/{$goods['goodsImg']}" height="55" width="55" class='goodsImg'/> + </a> + {/volist} + </div> + <div class='wst-complain-order-head'>订单信息</div> + <div class='wst-complain-order-info'> + <dl> + <dt>订单编号:</dt> + <dd>{$data['order']['orderNo']}</dd> + <dt>订单金额:</dt> + <dd>{$data['order']['realTotalMoney']}</dd> + <dt>运&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;费:</dt> + <dd>{$data['order']['deliverMoney']}</dd> + <dt>下单时间:</dt> + <dd>{$data['order']['createTime']}</dd> + <dt>商&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;家:</dt> + <dd>{$data['order']['shopName']}</dd> + </dl> + </div> + </div> + <div class='wst-complain-main'> + <div class='wst-complain-order-head' style='width:732px;'>投诉信息</div> + <div class='wst-complain-box'> + <table> + <tr> + <td>投诉类型:</td> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT');{/php} + {volist name='reason' id='vo'} + <label><input type='radio' name='complainType' class='ipt' autocomplete="off" value='{$vo['dataVal']}' {if $key==1}checked{/if}>{$vo['dataName']}</label> + {/volist} + + </td> + </tr> + <tr> + <td colspan='2'> + <textarea id='complainContent' name="complainContent" class='ipt' autocomplete="off" style='width:700px;height:155px;' placeholder='请输入投诉内容'></textarea> + </td> + </tr> + <tr> + <td colspan='2'> + <div id="filePicker" style='margin-left:0px;width:250px;overflow:hidden;height:25px;'>上传附件(最多5张)</div> + </td> + </tr> + <tr> + <td colspan='2'> + <div id='picBox' style='height:120px;width:732px;padding:5px;'> + </td> + </tr> + </table> + </div> + </div> + <div class='wst-complain-footer'> + <button onclick="javascript:saveComplain()" class="wst-sec-but u-btn">提交</button> + <button onclick="javascript:history.go(-1)" class="wst-sec-but u-btn">返回</button> + </div> + {/if} + </form> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +$(function(){ + userComplainInit(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/complain_detail.html b/hyhproject/home2/view/default/users/orders/complain_detail.html new file mode 100755 index 0000000..d0cd858 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/complain_detail.html @@ -0,0 +1,125 @@ +{extend name="default/users/base" /} +{block name="title"}投诉详情 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>投诉详情</span></div> + + <div class='wst-user-content'> + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>投诉信息</td> + </tr> + <tr> + <th width='80'>订单号:</th> + <td>{$data['orderNo']}</td> + </tr> + <tr> + <th>投诉类型:</th> + <td> + {php}$reason = WSTDatas('ORDER_COMPLAINT',$data['complainType']);{/php} + {$reason['dataName']} + </td> + </tr> + <tr> + <th>投诉内容:</th> + <td class='line-break'>{$data['complainContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + + <td id="photos-complain"> + {volist name="$data['complainAnnex']" id="annex"} + <a href="javascript:void(0)"> + <img layer-src="__IMGURL__/{$annex}" width="100" height="100" src="__IMGURL__/{$annex}" /> + </a> + {/volist} + </td> + + </tr> + <tr> + <th>投诉时间:</th> + <td>{$data['complainTime']}</td> + </tr> + </table> + + {if condition="$data['needRespond'] eq 1 AND $data['respondContent'] neq ''"} + <table border='0' class='wst-complain-detail'> + <tr> + <td colspan='2' class='head'>应诉信息</td> + </tr> + <tr> + <th width='80'>应诉内容:</th> + <td class='line-break'>{$data['respondContent']}</td> + </tr> + <tr> + <th valign='top'>附件:</th> + <td> + <div id="respondAnnex"> + {volist name="$data['respondAnnex']" id="annex2"} + <a href="javascript:void(0)"><img class='lazyImg' src="__IMGURL__/{$annex2}" layer-src="__IMGURL__/{$annex2}" height="100" width="100"/></a> + {/volist} + </div> + </td> + </tr> + <tr> + <th>应诉时间:</th> + <td>{$data['respondTime']}</td> + </tr> + </table> + {/if} + <table border='0' class='wst-complain-detail' style='margin-top:15px;'> + <tr> + <td colspan='2' class='head'>仲裁结果</td> + </tr> + <tr> + <th width='80'>仲裁结果:</th> + <td> + {if condition="$data['complainStatus'] eq 0"} + 等待处理 + {elseif condition="$data['complainStatus'] eq 1"/} + 等待应诉人回应 + {elseif condition="$data['complainStatus'] eq 2 OR $data['complainStatus'] eq 3"/} + 等待仲裁 + {elseif condition="$data['complainStatus'] eq 4"/} + 已仲裁 + {/if} + </td> + </tr> + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th valign='top'>仲裁结果:</th> + <td class='line-break'> + {$data['finalResult']} + </td> + </tr> + {/if} + {if condition="$data['complainStatus'] eq 4"} + <tr> + <th>仲裁时间:</th> + <td>{$data['finalResultTime']}&nbsp;</td> + </tr> + {/if} + <tr> + <td colspan='2' style='text-align:center;'> + <button onclick="javascript:history.go(-1)" class="wst-sec-but u-btn">返回</button> + </td> + </tr> + </table> + + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + // 调用图像层 + layer.photos({ + photos: '#photos-complain' + }); + layer.photos({ + photos: '#respondAnnex' + }); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_abnormal.html b/hyhproject/home2/view/default/users/orders/list_abnormal.html new file mode 100755 index 0000000..de2289c --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_abnormal.html @@ -0,0 +1,126 @@ +{extend name="default/users/base" /} +{block name="title"}拒收/退款订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>拒收/退款订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="u-query" id='orderNo'/> + 店铺名称:<input type='text' class="u-query" id='shopName'/> + 是否退款: + <select name="isRefund" id="isRefund" class="s-query"> + <option value="-1">请选择</option> + <option value="1">已退款</option> + <option value="0">未退款</option> + </select> + <button class="wst-sec-but u-btn" onclick="abnormalByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div> + {{d[i].status}} + {{#if(d[i].payType ==1 && d[i].isPay == 1){}} + {{#if(d[i].isRefund==1){}}【已退款】{{#}else{}}【未退款】{{#}}} + {{# } }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{# if(d[i].allowRefund==1){ }} + <div><a href='javascript:void(0)' onclick='refund({{d[i].orderId}},"abnormal")'>【申请退款】</a></div> + {{# } }} + <div><a href='javascript:void(0)' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + {{# if(d[i].isComplain==''){ }} + <div><a href='javascript:void(0)' onclick='complain({{d[i].orderId}})'>【订单投诉】</a></div> + {{# } }} + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + abnormalByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_appraise.html b/hyhproject/home2/view/default/users/orders/list_appraise.html new file mode 100755 index 0000000..e23b260 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_appraise.html @@ -0,0 +1,121 @@ +{extend name="default/users/base" /} +{block name="title"}待评价订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>待评价订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="s-query" id='orderNo'/> + 店铺名称:<input type='text' class="s-query" id='shopName'/> + <button class="wst-sec-but u-btn" onclick="waitAppraiseByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div> + {{d[i].status}} + {{#if(d[i].orderStatus==0){}}&nbsp;|&nbsp;<a href='#none' onclick='javascript:cancel(d[i].orderId)'>取消订单</a>{{# } }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].isAppraise==0){}} + <div> + <a href='javascript:;' onclick='javascript:toAppraise({{d[i].orderId}})'>【评价订单】</a> + </div> + {{# } }} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + {{# if(d[i].isComplain==''){ }} + <div><a href='#none' onclick='complain({{d[i].orderId}})'>【订单投诉】</a></div> + {{# } }} + + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waitAppraiseByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_cancel.html b/hyhproject/home2/view/default/users/orders/list_cancel.html new file mode 100755 index 0000000..82e2576 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_cancel.html @@ -0,0 +1,117 @@ +{extend name="default/users/base" /} +{block name="title"}已取消订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>已取消订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="u-query" id='orderNo'/> + 店铺名称:<input type='text' class="u-query" id='shopName'/> + <button class="wst-sec-but u-btn" onclick="cancelByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div> + {{d[i].status}} + {{#if(d[i].payType ==1 && d[i].isPay == 1){}} + {{#if(d[i].isRefund==1){}}【已退款】{{#}else{}}【未退款】{{#}}} + {{# } }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{# if(d[i].allowRefund==1){ }} + <div><a href='javascript:void(0)' onclick='refund({{d[i].orderId}},"cancel")'>【申请退款】</a></div> + {{# } }} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + cancelByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_complain.html b/hyhproject/home2/view/default/users/orders/list_complain.html new file mode 100755 index 0000000..90432a5 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_complain.html @@ -0,0 +1,60 @@ +{extend name="default/users/base" /} +{block name="title"}投诉管理 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>投诉管理</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="s-query" id='orderNo'/> + <button class="wst-sec-but u-btn" onclick="complainByPage()">查询</button> + </div> + + <div class='wst-user-content'> + <table class='wst-list'> + <thead> + <tr class='head'> + <th>订单编号</th> + <th>被投诉方</th> + <th>投诉原因</th> + <th>投诉时间</th> + <th>投诉状态</th> + <th>操作</th> + </tr> + </thead> +<tbody id='list'></tbody> + <tfoot> + <tr><td colspan='10' id='pager' align="center" style='padding:5px 0px 5px 0px'></td></tr> + </tfoot> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td> + {{d[i]['orderNo']}} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </td> + + <td>{{d[i]['shopName']}}</td> + + <td title="{{d[i]['complainContent']}}">{{WST.cutStr(d[i]['complainContent'],50)}}</td> + + <td>{{d[i]['complainTime']}}</td> + + <td>{{d[i]['complainStatus']}}</td> + + <td><a style="cursor:pointer;" onclick="toView({{d[i]['complainId']}})">查看</a></td> + </tr> + {{# } }} + </script> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + complainByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_finish.html b/hyhproject/home2/view/default/users/orders/list_finish.html new file mode 100755 index 0000000..cdba922 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_finish.html @@ -0,0 +1,124 @@ +{extend name="default/users/base" /} +{block name="title"}已完成订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>已完成订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="u-query" id='orderNo'/> + 店铺名称:<input type='text' class="u-query" id='shopName'/> + <button class="wst-sec-but u-btn" onclick="finishByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div> + {{d[i].status}} + {{#if(d[i].orderStatus==0){}}&nbsp;|&nbsp;<a href='#none' onclick='javascript:cancel(d[i].orderId)'>取消订单</a>{{# } }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].isAppraise==1){}} + <div>已评价</div> + {{# }else { }} + <div> + <a href='#none' onclick='javascript:toAppraise({{d[i].orderId}})'>【评价订单】</a> + </div> + {{# } }} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + + {{# if(d[i].isComplain==''){ }} + <div><a href='#none' onclick='complain({{d[i].orderId}})'>【订单投诉】</a></div> + {{# } }} + + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + finishByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_order_appraise.html b/hyhproject/home2/view/default/users/orders/list_order_appraise.html new file mode 100755 index 0000000..3a1e1e1 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_order_appraise.html @@ -0,0 +1,197 @@ +{extend name="default/users/base" /} +{block name="title"}待评价订单 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} + <div class="wst-user-head"><span>评价订单</span></div> + <div class='wst-user-content'> + {volist name="$data" id="vo" key='k'} + {if (empty($vo['appraise']))} + <form id="appraise-form{$k}"> + + <div class="appraise-box"> + <input type="hidden" id="ogId{$k}" value="{$vo['id']}"> + <input type="hidden" id="gid{$k}" value="{$vo['goodsId']}"> + <input type="hidden" id="oid{$k}" value="{$vo['orderId']}"> + <input type="hidden" id="gsid{$k}" value="{$vo['goodsSpecId']}"> + <div class="o-goods-info"> + <img src="__IMGURL__/{$vo['goodsImg']}" title="商品名称" /> + <p class="o-goodsName" title="{$vo['goodsName']}">{if $vo['goodsCode']=='gift'}【赠品】{/if}{$vo['goodsName']}</p> + <p class="o-goodsSpec" title="{$vo['goodsSpecNames']}">{$vo['goodsSpecNames']}</p> + </div> + <div class="appraise-area" id="app-box{$k}"> + <div class="appraise-item goodsScore{$k}"> + <div class="appraise-title">商品评分:</div> + <div class="appraise-content"> + <div class="{$vo['id']}_goodsScore" style='float:left'></div> + <div id="{$vo['id']}_goodsScore_hint" style='float:left'></div> + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item timeScore{$k}"> + <div class="appraise-title"> 时效评分:</div> + <div class="appraise-content"> + <div class="{$vo['id']}_timeScore" style='float:left'></div> + <div id="{$vo['id']}_timeScore_hint" style='float:left'></div> + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item serviceScore{$k}"> + <div class="appraise-title">服务评分:</div> + <div class="appraise-content"> + <div class="{$vo['id']}_serviceScore" style='float:left'></div> + <div id="{$vo['id']}_serviceScore_hint" style='float:left'></div> + </div> + </div> + <div class="wst-clear"></div> + <div id="score_error{$k}"></div> + + <div class="appraise-item"> + <div class="appraise-title">点评内容:</div> + <div class="appraise-content"> + <textarea maxlength="200" id="content{$k}" style="width:610px;resize:none;" cols="70" rows="5" + data-rule="点评内容:required; length(3~200)" + data-msg-length="点评内容为3-200个字" + data-target="#msg_holder" + ></textarea> + <div id="msg_holder"></div> + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item"> + <div class="appraise-title"> </div> + <div class="appraise-content"> + + <div id='picBox{$k}' style='height:120px;width:650px;margin-top:-20px;position:relative;'> + <div id="filePicker{$k}" style='margin-left:0px;width:300px;position:relative;left:2px;top:23px;'> + 晒照片(限5张) + </div> + <div class="" style="position:relative;left:-26px;top:-9px;float:right;"> + <button class="appraise-btn" type="submit" >评价</button></div> + <div style="clear: both;"></div> + </div> + </div> + </div> + </div> + </div> + </form> + <div class="wst-clear"></div> + {else /} + <div class="appraise-complate"> + <div class="o-goods-info"> + <img src="__IMGURL__/{$vo['goodsImg']}" title="商品名称" /> + <p class="o-goodsName" title="{$vo['goodsName']}">{if $vo['goodsCode']=='gift'}【赠品】{/if}{$vo['goodsName']}</p> + <p class="o-goodsSpec" title="{$vo['goodsSpecNames']}">{$vo['goodsSpecNames']}</p> + </div> + + <div class="appraise-area"> + <div class="appraise-item"> + <div class="appraise-title">商品评分:</div> + <div class="appraise-content"> + {for start="0" end="$vo['appraise']['goodsScore']"} + <img src="__STATIC__/plugins/raty/img/star-on-big.png"> + {/for} + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item"> + <div class="appraise-title"> 时效评分:</div> + <div class="appraise-content"> + {for start="0" end="$vo['appraise']['timeScore']"} + <img src="__STATIC__/plugins/raty/img/star-on-big.png"> + {/for} + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item"> + <div class="appraise-title">服务评分:</div> + <div class="appraise-content"> + {for start="0" end="$vo['appraise']['serviceScore']"} + <img src="__STATIC__/plugins/raty/img/star-on-big.png"> + {/for} + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item"> + <div class="appraise-title">点评内容:</div> + <div class="appraise-content"> + <p class="complate-content">{$vo['appraise']['content']} [{:date('Y-m-d',strtotime($vo['appraise']['createTime']))}]</p> + </div> + </div> + <div class="wst-clear"></div> + + <div class="appraise-item"> + <div class="appraise-title"> </div> + <div class="appraise-content"> + <div id="appraise-img-{$k}"> + {volist name="$vo['appraise']['images']" id="img"} + {if !empty($img)} + <img src="__IMGURL__/{$img}" layer-src="__IMGURL__/{$img}" width="75" height="75" /> + <!-- + <img src="__ROOT__/{:str_replace('.','_thumb.',$img)}" layer-src="__ROOT__/{$img}" width="75" height="75" /> + --> + {/if} + {/volist} + </div> + </div> + </div> + </div> + + + </div> + <div class="wst-clear"></div> + + {/if} + {/volist} + + + + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script type="text/javascript" src="__STATIC__/plugins/raty/jquery.raty.min.js?v={$v}"></script> +<script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<script> +/*评分*/ +$(function(){ + /*调用相册层*/ + $(this).find('div[id^="appraise-img-"]').each(function(k,v){ + appraisesShowImg($(this).attr('id')); + }); + +var options = { + hints : ['很不满意', '不满意', '一般', '满意', '非常满意'], + width:200, + targetKeep: true, + starHalf:'__STATIC__/plugins/raty/img/star-half-big.png', + starOff:'__STATIC__/plugins/raty/img/star-off-big.png', + starOn:'__STATIC__/plugins/raty/img/star-on-big.png', + cancelOff: '__STATIC__/plugins/raty/img/cancel-off-big.png', + cancelOn: '__STATIC__/plugins/raty/img/cancel-on-big.png' + } + {volist name="$data" id="g" key='key1' } + options.target='#{$g["id"]}_goodsScore_hint'; + $('.{$g["id"]}_goodsScore').raty(options); + options.target='#{$g["id"]}_timeScore_hint'; + $('.{$g["id"]}_timeScore').raty(options); + options.target='#{$g["id"]}_serviceScore_hint'; + $('.{$g["id"]}_serviceScore').raty(options); + upload({$key1}); + //调用验证规则 + validator({$key1}); + {/volist} +}); + + +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_wait_pay.html b/hyhproject/home2/view/default/users/orders/list_wait_pay.html new file mode 100755 index 0000000..4963565 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_wait_pay.html @@ -0,0 +1,115 @@ +{extend name="default/users/base" /} +{block name="title"}待付款订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>待付款订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="u-query" id='orderNo'/> + 店铺名称:<input type='text' class="u-query" id='shopName'/> + <button class="wst-sec-but u-btn" onclick="waitPayByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy' style='display:none'> + <tr id='loading' class='empty-row' > + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div>{{d[i].status}}&nbsp;|&nbsp;<a href='#none' onclick='javascript:cancel({{d[i].orderId}},0)'>取消订单</a></div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + var parmas = {}; + parmas.orderNo = d[i].orderNo; + parmas.isBatch = 0; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + + + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + <div><a href='{{WST.U('home/orders/succeed',parmas)}}'>【立即支付】</a></div> + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + </td> + {{# } }} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waitPayByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/list_wait_receive.html b/hyhproject/home2/view/default/users/orders/list_wait_receive.html new file mode 100755 index 0000000..df4e663 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/list_wait_receive.html @@ -0,0 +1,133 @@ +{extend name="default/users/base" /} +{block name="title"}待收货订单 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>待收货订单</span></div> + <div class='wst-user-tbar'> + 订单号:<input type='text' class="u-query" id='orderNo'/> + 店铺名称:<input type='text' class="u-query" id='shopName'/> + <button class="wst-sec-but u-btn" onclick="waitReceiveByPage()">查询</button> + </div> + <div class='wst-user-content'> + <table class='wst-order-list'> + <thead> + <tr class='head'> + <th>订单详情</th> + <th width="107">支付方式/配送信息</th> + <th>金额</th> + <th width="87">操作</th> + </tr> + </thead> + <tbody id='loadingBdy'> + <tr id='loading' class='empty-row' style='display:none'> + <td colspan='4'><img src="__STYLE__/img/loading.gif">正在加载数据...</td> + </tr> + </tbody> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tbody class="j-order-row"> + <tr class='empty-row'> + <td colspan='4'>&nbsp;</td> + </tr> + <tr class='order-head'> + <td colspan='4' align='right'> + <div class='time'>{{d[i].createTime}}</div> + <div class='orderno'>订单号:{{d[i].orderNo}} + {{# if(d[i].orderSrc==0){ }}<i class="order-pc"></i> + {{# }else if(d[i].orderSrc==1){ }}<i class="order-wx"></i> + {{# }else if(d[i].orderSrc==2){ }}<i class="order-mo"></i> + {{# }else if(d[i].orderSrc==3){ }}<i class="order-app"></i> + {{# }else if(d[i].orderSrc==4){ }}<i class="order-ios"></i> + {{# } }} + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + </div> + <div class='shop'>{{d[i].shopName}}</div> + <div class='link'>{{WST.shopQQ(d[i].shopQQ)}}{{WST.shopWangWang(d[i].shopWangWang)}}</div> + <div> + {{d[i].status}} + {{#if(d[i].orderStatus==0){}}&nbsp;|&nbsp;<a href='#none' onclick='javascript:cancel({{d[i].orderId}},1)'>取消订单</a>{{# } }} + </div> + </td> + </tr> + {{# + var tmp = null,rows = d[i]['list'].length; + for(var j = 0; j < d[i]['list'].length; j++){ + tmp = d[i]['list'][j]; + }} + <tr class='goods-box'> + <td> + <div class='goods-img'> + <a href="{{WST.U('home/goods/detail','id='+tmp.goodsId)}}" target='_blank'> + <img data-original='__IMGURL__/{{tmp.goodsImg}}' title='{{tmp.goodsName}}' class="gImg"> + </a> + </div> + <div class='goods-name'> + <div>{{tmp.goodsName}}</div> + <div>{{tmp.goodsSpecNames}}</div> + </div> + <div class='goods-extra'>{{tmp.goodsPrice}} x {{tmp.goodsNum}}</div> + </td> + {{#if(j==0){}} + <td rowspan="{{rows}}"> + <div>{{d[i].payTypeName}}</div> + <div>{{d[i].deliverType}}</div> + </td> + <td rowspan="{{rows}}"> + <div>商品金额:¥{{d[i].goodsMoney}}</div> + <div class='line'>运费:¥{{d[i].deliverMoney}}</div> + <div>实付金额:¥{{d[i].realTotalMoney}}</div> + </td> + <td rowspan="{{rows}}"> + {{#if(d[i].orderStatus==0 && d[i].noticeDeliver==0){}} + <div> + <a href='#none' onclick='javascript:noticeDeliver({{d[i].orderId}})'>【提醒发货】</a> + </div> + {{# } }} + + {{#if(d[i].orderStatus==1){}} + <div> + <a href='#none' onclick='javascript:toReceive({{d[i].orderId}})'>【确认收货】</a> + </div> + <div> + <a href='#none' onclick='javascript:toReject({{d[i].orderId}})'>【拒绝收货】</a> + </div> + <div> + <a href='#none' onclick='javascript:toDelay({{d[i].orderId}})'>【延时收货】</a> + </div> + {{# } }} + <div><a href='#none' onclick='view({{d[i].orderId}})'>【订单详情】</a></div> + + {{# if(d[i].isComplain==''){ }} + <div><a href='#none' onclick='complain({{d[i].orderId}})'>【订单投诉】</a></div> + {{# } }} + </td> + {{#}}} + </tr> + {{# } }} + <tr> + <td colspan="4"> + {{# if(WST.blank(d[i].orderRemarks)!=''){ }} + <div class="order_remaker">【我的留言】{{d[i].orderRemarks}}</div> + {{# } }} + </td> + </tr> + </tbody> + {{# } }} + </script> + <tr class='empty-row'> + <td colspan='4' id='pager' align="center" style='padding:5px 0px 5px 0px'>&nbsp;</td> + </tr> + </table> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/orders/orders.js?v={$v}'></script> +<script> +$(function(){ + waitReceiveByPage(); +}) +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/orders/orders.js b/hyhproject/home2/view/default/users/orders/orders.js new file mode 100755 index 0000000..c009b2a --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/orders.js @@ -0,0 +1,683 @@ +// 提醒发货 +function noticeDeliver(id){ + var box = WST.confirm({content:"您确定要提醒发货吗?",yes:function(){ + layer.close(box); + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/noticeDeliver'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg(json.msg,{icon:1}); + waitReceiveByPage(WSTCurrPage); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}); +} + +function waitPayByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.u-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waitPayByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitPayByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waitPayByPage(e.curr); + } + } + }); + } + }); +} +function waitReceiveByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.u-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waitReceiveByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitReceiveByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waitReceiveByPage(e.curr); + } + } + }); + } + }); +} +function toReceive(id){ + WST.confirm({content:'您确定已收货吗?',yes:function(){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/receive'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg(json.msg,{icon:1}); + waitReceiveByPage(WSTCurrPage); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}) +} +function toDelay(id){ + WST.confirm({content:'亲,只能延时收货一次哒?',yes:function(){ + var ll = WST.load({msg:'正在提交信息,请稍候...'}); + $.post(WST.U('home/orders/delay'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + WST.msg(json.msg,{icon:1}); + waitReceiveByPage(WSTCurrPage); + layer.close(ll); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }}) +} +function waitAppraiseByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/waitAppraiseByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + waitAppraiseByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + waitAppraiseByPage(e.curr); + } + } + }); + } + }); +} +function finishByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.u-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/finishByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + finishByPage(e.curr); + } + } + }); + } + }); +} +function cancel(id,type){ + var ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/orders/toCancel'),{id:id},function(data){ + layer.close(ll); + var w = WST.open({ + type: 1, + title:"取消订单", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['500px', '260px'], + btn: ['提交', '关闭窗口'], + yes: function(index, layero){ + var reason = $.trim($('#reason').val()); + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/orders/cancellation'),{id:id,reason:reason},function(data){ + layer.close(w); + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + if(type==0){ + waitPayByPage(WSTCurrPage); + }else{ + waitReceiveByPage(WSTCurrPage); + } + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + }); +} +function toReject(id){ + var ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/orders/toReject'),{id:id},function(data){ + layer.close(ll); + var w = WST.open({ + type: 1, + title:"拒收订单", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['500px', '300px'], + btn: ['提交', '关闭窗口'], + yes: function(index, layero){ + var params = {}; + params.reason = $.trim($('#reason').val()); + params.content = $.trim($('#content').val()); + params.id = id; + if(params.id==10000 && params.conten==''){ + WST.msg('请输入拒收原因',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/orders/reject'),params,function(data){ + layer.close(w); + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + waitReceiveByPage(WSTCurrPage); + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + }); +} +function changeRejectType(v){ + if(v==10000){ + $('#rejectTr').show(); + }else{ + $('#rejectTr').hide(); + } +} +function cancelByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.u-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/cancelByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + cancelByPage(e.curr); + } + } + }); + } + }); +} +function abnormalByPage(p){ + $('#loading').show(); + var params = {}; + params = WST.getParams('.u-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/orders/abnormalByPage'),params,function(data,textStatus){ + $('#loading').hide(); + var json = WST.toJson(data); + $('.j-order-row').remove(); + if(json.status==1){ + json = json.data; + if(params.page>json.TotalPage && json.TotalPage >0){ + abnormalByPage(json.TotalPage); + return; + } + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $(html).insertAfter('#loadingBdy'); + $('.gImg').lazyload({ effect: "fadeIn",failurelimit : 10,skip_invisible : false,threshold: 200,placeholder:window.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + abnormalByPage(e.curr); + } + } + }); + } + }); +} +function refund(id,src){ + var ll = WST.load({msg:'正在加载信息,请稍候...'}); + $.post(WST.U('home/orders/toRefund'),{id:id},function(data){ + layer.close(ll); + var w = WST.open({ + type: 1, + title:"申请退款", + shade: [0.6, '#000'], + border: [0], + content: data, + area: ['500px', '320px'], + btn: ['提交', '关闭窗口'], + yes: function(index, layero){ + var params = {}; + params.reason = $.trim($('#reason').val()); + params.content = $.trim($('#content').val()); + params.money = $.trim($('#money').val()); + params.id = id; + if(params.money<0){ + WST.msg('无效的退款金额',{icon:2}); + return; + } + if(params.id==10000 && params.conten==''){ + WST.msg('请输入原因',{icon:2}); + return; + } + ll = WST.load({msg:'数据处理中,请稍候...'}); + $.post(WST.U('home/orderrefunds/refund'),params,function(data){ + layer.close(ll); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg, {icon: 1}); + layer.close(w); + if(src=='abnormal'){ + abnormalByPage(WSTCurrPage); + }else{ + cancelByPage(WSTCurrPage); + } + }else{ + WST.msg(json.msg, {icon: 2}); + } + }); + } + }); + }); +} +function view(id){ + location.href=WST.U('home/orders/detail','id='+id); +} +function complain(id){ + location.href=WST.U('home/ordercomplains/complain','orderId='+id); +} + + +/******************** 评价页面 ***********************/ +function appraisesShowImg(id){ + layer.photos({ + photos: '#'+id + }); +} +function toAppraise(id){ + location.href=WST.U("home/orders/orderAppraise",{'oId':id}); +} +//文件上传 +function upload(n){ + var uploader =WST.upload({ + pick:'#filePicker'+n, + formData: {dir:'appraises',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + // var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + // "<img class='appraise_pic"+n+"' width='75' height='75' src='"+WST.conf.ROOT+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + // var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + // 修改oss地址 mark 20180612 by zl + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='appraise_pic"+n+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#picBox'+n).append(tdiv); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} + +function validator(n){ + $('#appraise-form'+n).validator({ + fields: { + score: { + rule:"required", + msg:{required:"评分必须都大于0"}, + ok:"", + target:"#score_error"+n, + }, + + }, + + valid: function(form){ + var params = {}; + //获取该评价的内容 + params.content = $('#content'+n).val(); + // 获取该评价附件 + var photo=[]; + var images = []; + $('.appraise_pic'+n).each(function(k,v){ + var img = $(this).attr('v'); + // 用于评价成功后的显示 + photo.push(WST.conf.IMGURL+'/'+img); + images.push(img); + }); + params.images = images.join(','); + //获取评分 + params.goodsScore = $('.goodsScore'+n).find('[name=score]').val(); + params.timeScore = $('.timeScore'+n).find('[name=score]').val(); + params.serviceScore = $('.serviceScore'+n).find('[name=score]').val(); + params.goodsId = $('#gid'+n).val(); + params.orderId = $('#oid'+n).val(); + params.goodsSpecId = $('#gsid'+n).val(); + params.orderGoodsId = $('#ogId'+n).val(); + + $.post(WST.U('home/goodsAppraises/add'),params,function(data,dataStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var thisbox = $('#app-box'+n); + var html = '<div class="appraise-area"><div class="appraise-item"><div class="appraise-title">商品评分:</div>'; + html += '<div class="appraise-content">'; + // 商品评分 + for(var i=1;i<=params.goodsScore;i++){ + html +='<img src="'+WST.conf.STATIC+'/plugins/raty/img/star-on-big.png">'; + } + html +='</div></div><div class="wst-clear"></div><div class="appraise-item"><div class="appraise-title"> 时效评分:</div>' + html +='<div class="appraise-content">' + // 时效评分 + for(var i=1;i<=params.timeScore;i++){ + html +='<img src="'+WST.conf.STATIC+'/plugins/raty/img/star-on-big.png">'; + } + html +='</div></div><div class="wst-clear"></div><div class="appraise-item"><div class="appraise-title">服务评分:</div>'; + html +='<div class="appraise-content">'; + // 服务评分 + for(var i=1;i<=params.serviceScore;i++){ + html +='<img src="'+WST.conf.STATIC+'/plugins/raty/img/star-on-big.png">'; + } + html +='</div></div><div class="wst-clear"></div><div class="appraise-item"><div class="appraise-title">点评内容:</div>'; + // 评价内容 + html +='<div class="appraise-content">'; + // 获取当前年月日 + var oDate = new Date(); + var year = oDate.getFullYear()+'-'; //获取系统的年; + var month = oDate.getMonth()+1+'-'; //获取系统月份,由于月份是从0开始计算,所以要加1 + var day = oDate.getDate(); // 获取系统日, + html +='<p>'+params.content+'['+year+month+day+']</p>'; + html +='</div></div><div class="wst-clear"></div><div class="appraise-item"><div class="appraise-title"> </div>'; + // 评价附件 + html +='<div class="appraise-content">'; + // 当前生成的相册id + var imgBoxId = "appraise-img-"+n; + html +='<div id='+imgBoxId+'>' + var count = photo.length; + for(var m=0;m<count;m++){ + // html += '<img src="'+photo[m].replace('.','_thumb.')+'" layer-src="'+photo[m]+'" width="75" height="75" style="margin-right:5px;">'; + // 修改为oss地址 mark 20180612 by zl + html += '<img src="'+WST.conf.IMGURL+photo[m]+'?x-oss-process=image/resize,w_75,h_75" layer-src="'+WST.conf.IMGURL+photo[m]+'?x-oss-process=image/resize,w_75,h_75" width="75" height="75" style="margin-right:5px;">'; + } + html +='</div></div></div></div>'; + thisbox.html(html); + // 调用相册层 + appraisesShowImg(imgBoxId); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + }); +} + +/* 用户评价管理 */ +function showImg(id){ + layer.photos({ + photos: '#img-file-'+id + }); +} +function userAppraise(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/goodsappraises/userAppraise'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(!json.data.Rows){ + $('#list').html(''); + } + if(json.status==1){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#list').html(html); + for(var g=0;g<=json.data.Rows.length;g++){ + showImg(g); + } + $('.j-lazyImg').lazyload({ effect: "fadeIn",failurelimit : 10,threshold: 200,placeholder:window.conf.IMGURL+'/'+window.conf.GOODS_LOGO}); + }); + laypage({ + cont: 'pager', + pages:json.data.TotalPage, + curr: json.data.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + userAppraise(e.curr); + } + } + }); + } + }); +} +/**************** 用户投诉页面 *****************/ +function userComplainInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'complains',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<div style='width:75px;float:left;margin-right:5px;'>"+ + "<img class='complain_pic"+"' width='75' height='75' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></div>"); + var btn = $('<div style="position:relative;top:-80px;left:60px;cursor:pointer;" ><img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/seller_icon_error.png"></div>'); + tdiv.append(btn); + $('#picBox').append(tdiv); + btn.on('click','img',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} +function saveComplain(historyURL){ + /* 表单验证 */ + $('#complainForm').validator({ + fields: { + complainContent: { + rule:"required", + msg:{required:"清输入投诉内容"}, + tip:"清输入投诉内容", + }, + complainType: { + rule:"checked;", + msg:{checked:"投诉类型不能为空"}, + tip:"请选择投诉类型", + } + + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + var img = []; + $('.complain_pic').each(function(){ + img.push($(this).attr('v')); + }); + params.complainAnnex = img.join(','); + + $.post(WST.U('home/orderComplains/saveComplain'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('您的投诉已提交,请留意信息回复', {icon: 6},function(){ + location.href = WST.U('home/ordercomplains/index'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }); +} + +/*********************** 用户投诉列表页面 ***************************/ +function toView(id){ + location.href=WST.U('home/ordercomplains/getUserComplainDetail',{'id':id}); +} +function complainByPage(p){ + $('#list').html('<img src="'+WST.conf.ROOT+'/hyhproject/home/view/default/img/loading.gif">正在加载数据...'); + var params = {}; + params = WST.getParams('.s-query'); + params.key = $.trim($('#key').val()); + params.page = p; + $.post(WST.U('home/ordercomplains/queryUserComplainByPage'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + complainByPage(e.curr); + } + } + }); + + + }else{ + $('#pager').empty(); + } + } + }); +} +//导出订单 +function toExport(typeId,status,type){ + var params = {}; + params = WST.getParams('.u-query'); + params.typeId = typeId; + params.orderStatus = status; + params.type = type; + var box = WST.confirm({content:"您确定要导出订单吗?",yes:function(){ + layer.close(box); + location.href=WST.U('home/orders/toExport',params); + }}); +} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/orders/view.html b/hyhproject/home2/view/default/users/orders/view.html new file mode 100755 index 0000000..8af1666 --- /dev/null +++ b/hyhproject/home2/view/default/users/orders/view.html @@ -0,0 +1,244 @@ +{extend name="default/users/base" /} +{block name="title"}订单详情 - 买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} +<div class="wst-user-head"><span>订单详情</span></div> +<div class='wst-user-content'> + <div class='order-box'> + <div class='box-head'>日志信息</div> + {if in_array($object['orderStatus'],[-2,0,1,2])} + <div class='log-box'> +<div class="state"> +{if $object['payType']==1} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==-2)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==0) OR ($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> + <div class="icon"><span class="icons {if condition="($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon22 {else}icon21{/if}{if condition="($object['orderStatus']==0)"}icon23 {/if}"></span></div> + <div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{else} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==-2)OR($object['orderStatus']==0)OR($object['orderStatus']==1)OR($object['orderStatus']==2)"}icon12 {else}icon11 {/if}{if condition="($object['orderStatus']==0)"}icon13 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==1) OR ($object['orderStatus']==2)"}arrow2{/if}">··················></div> +{/if} +<div class="icon"> + <span class="icons {if condition="($object['orderStatus']==1)OR($object['orderStatus']==2)OR($object['orderStatus']==1)"}icon32 {else}icon31 {/if}{if condition="($object['orderStatus']==1)"}icon33 {/if}"></span> +</div> +<div class="arrow {if condition="($object['orderStatus']==2)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['orderStatus']==2)AND($object['isAppraise']==1)"}icon42 {else}icon41 {/if}{if condition="($object['orderStatus']==2)AND($object['isAppraise']==0)"}icon43 {/if}"></span></div> +<div class="arrow {if condition="($object['isAppraise']==1)"}arrow2{/if}">··················></div> +<div class="icon"><span class="icons {if condition="($object['isAppraise']==1)"}icon53 {else}icon51 {/if}"></span></div> +</div> + <div class="state2"> + <div class="path"> + {volist name="$object['log']" id="lo"} + <span>{$lo['logContent']}<br/>{$lo['logTime']}</span> + {/volist} + </div> + <p>下单</p>{if $object['payType']==1}<p>等待支付</p>{/if}<p>商家发货</p><p>确认收货</p><p>订单结束<br/>双方互评</p> + </div> + <div class="wst-clear"></div> + </div> + {else} + <div> + <table class='log'> + {volist name='$object["log"]' id='vo'} + <tr> + <td>{$vo['logTime']}</td> + <td>{$vo['logContent']}</td> + </tr> + {/volist} + </table> + </div> + {/if} + </div> + <!-- 订单信息 --> + <div class='order-box'> + <div class='box-head'>订单信息</div> + <table class='wst-form'> + <tr> + <th width='100'>订单编号:</th> + <td>{$object['orderNo']}</td> + </tr> + <tr> + <th>支付方式:</th> + <td>{:WSTLangPayType($object['payType'])}</td> + </tr> + {if($object['payType']==1 && $object['isPay']==1)} + <tr> + <th>支付时间:</th> + <td>{$object['payTime']}</td> + </tr> + <tr> + <th>支付信息:</th> + <td>【{:WSTLangPayFrom($object['payFrom'])}】{$object['tradeNo']}</td> + </tr> + {/if} + <tr> + <th>配送方式:</th> + <td>{:WSTLangDeliverType($object['deliverType'])}</td> + </tr> + {if $object['expressNo']!=''} + <tr> + <th>快递公司:</th> + <td>{$object['expressName']}</td> + </tr> + <tr> + <th>快递号:</th> + <td>{$object['expressNo']}</td> + </tr> + {/if} + <tr> + <th>买家留言:</th> + <td>{$object['orderRemarks']}</td> + </tr> + </table> + </div> + + {:hook('homeDocumentOrderView',['orderId'=>$object['orderId']])} + + {if $object['isRefund']==1} + <!-- 退款信息 --> + <div class='order-box'> + <div class='box-head'>退款信息</div> + <table class='wst-form'> + <tr> + <th width='100'>退款金额:</th> + <td>¥{$object['backMoney']}</td> + </tr> + <tr> + <th width='100'>退款备注:</th> + <td>{$object['refundRemark']}</td> + </tr> + <tr> + <th>退款时间:</th> + <td>{$object['refundTime']}</td> + </tr> + </table> + </div> + {/if} + <!-- 发票信息 --> + <div class='order-box'> + <div class='box-head'>发票信息</div> + <table class='wst-form'> + <tr> + <th width='100'>是否需要发票:</th> + <td>{if $object['isInvoice']==1}需要{else}不需要{/if}</td> + </tr> + {if $object['isInvoice']==1} + {php}$invoiceArr = json_decode($object['invoiceJson'],true);{/php} + <tr> + <th>发票抬头:</th> + <td> + {if $object['isInvoice']==1} + {$invoiceArr['invoiceHead']} + {/if} + </td> + </tr> + {if isset($invoiceArr['invoiceCode'])} + <tr> + <th>发票税号:</th> + <td> + {$invoiceArr['invoiceCode']} + </td> + </tr> + {/if} + {/if} + </table> + </div> + <!-- 收货人信息 --> + {if ($object['orderType']==0)} + <div class='order-box'> + <div class='box-head'>收货人信息</div> + <table class='wst-form'> + <tr> + <th width='100'>收货人:</th> + <td>{$object['userName']}</td> + </tr> + <tr> + <th>收货地址:</th> + <td>{$object['userAddress']}</td> + </tr> + <tr> + <th>联系方式:</th> + <td>{$object['userPhone']}</td> + </tr> + </table> + </div> + {/if} + <!-- 商品信息 --> + <div class='order-box'> + <div class='box-head'>商品清单</div> + <div class='goods-head'> + <div class='goods'>商品</div> + <div class='price'>单价</div> + <div class='num'>数量</div> + <div class='t-price'>总价</div> + </div> + <div class='goods-item'> + <div class='shop'> + {$object['shopName']} + {if $object['shopQQ'] !=''} + <a href="tencent://message/?uin={$object['shopQQ']}&Site=QQ交谈&Menu=yes"> + <img border="0" style='vertical-align:middle;' src="http://wpa.qq.com/pa?p=1:{$object['shopQQ']}:7" alt="QQ交谈" width="71" height="24" /> + </a> + {/if} + {if $object['shopWangWang'] !=''} + <a target="_blank" href="http://www.taobao.com/webww/ww.php?ver=3&touid={$object['shopWangWang']}&siteid=cntaobao&status=1&charset=utf-8"> + <img border="0" style='vertical-align:middle;' src="http://amos.alicdn.com/realonline.aw?v=2&uid={$object['shopWangWang']}&site=cntaobao&s=1&charset=utf-8" alt="和我联系" /> + </a> + {/if} + </div> + <div class='goods-list'> + {volist name='$object["goods"]' id='vo2'} + {:hook('homeDocumentOrderViewGoodsPromotion',['goods'=>$vo2])} + <div class='item j-g{$vo2['goodsId']}'> + <div class='goods'> + <div class='img'> + <a href='{:Url("home/goods/detail","id=".$vo2["goodsId"])}' target='_blank'> + <img src='__IMGURL__/{$vo2["goodsImg"]}' width='80' height='80' title='{$vo2["goodsName"]}'/> + </a> + </div> + <div class='name'>{if $vo2['goodsCode']=='gift'}【赠品】{/if}{$vo2["goodsName"]}</div> + <div class='spec'>{:str_replace('@@_@@','<br/>',$vo2["goodsSpecNames"])}</div> + </div> + <div class='price'>¥{$vo2['goodsPrice']}</div> + <div class='num'>{$vo2['goodsNum']}</div> + <div class='t-price'>¥{$vo2['goodsPrice']*$vo2['goodsNum']}</div> + <div class='wst-clear'></div> + </div> + {if $vo2['goodsType']==1 && $object['orderStatus']==2} + <table width='100%' style='margin-top:5px;'> + {volist name='$vo2["extraJson"]' id='vgcard'} + <tr> + <td>卡券号:{$vgcard['cardNo']}</td> + <td>卡券密码:{$vgcard['cardPwd']}</td> + </tr> + {/volist} + </table> + {/if} + {/volist} + </div> + </div> + <div class='goods-footer'> + <div class='goods-summary' style='text-align:right'> + <div class='summary'>商品总金额:¥<span>{$object['goodsMoney']}</span></div> + <div class='summary'>运费:¥<span>{$object['deliverMoney']}</span></div> + <div class='summary line'>应付总金额:¥<span>{$object['totalMoney']}</span></div> + <div class='summary '>积分抵扣金额:¥-<span>{$object['scoreMoney']}</span></div> + {if condition="$object['useScore'] gt 0"} + <div class='summary '>使用积分数:<span>{$object['useScore']}个</span></div> + {/if} + {:hook('homeDocumentOrderSummaryView',['order'=>$object])} + <div class='summary'>实付总金额:¥<span>{$object['realTotalMoney']}</span></div> + <div>可获得积分:<span class='orderScore'>{$object["orderScore"]}</span>个</div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/shops/orders/orders.js?v={$v}'></script> +{/block} diff --git a/hyhproject/home2/view/default/users/recharge/pay_step1.html b/hyhproject/home2/view/default/users/recharge/pay_step1.html new file mode 100755 index 0000000..f2bfbd5 --- /dev/null +++ b/hyhproject/home2/view/default/users/recharge/pay_step1.html @@ -0,0 +1,71 @@ +{extend name="default/users/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>充值</span></div> +<div class='wst-user-content'> + <div class='pay-sbox'> + <div> + <div> + <div class='wst-tips-box' style="margin-right:10px;"> + <div class='icon'></div> + <div class='tips'> + 1.充值金额和赠送金额只能用于购买商品,不能提现;<br/> + </div> + <div style="clear:both"></div> + </div> + </div> + <div> + <div class="pay-type">充值金额 + <div> + <div class="wst-list-box"> + {volist name="chargeItems" id="item"} + <div class="wst-frame2 {$key} " onclick="javascript:changeSelected({$item['id']},'itmeId',this)"> + {if condition="$item['giveMoney'] gt 0"} + <div class='charge-doub'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + <div>送 {$item['giveMoney']} 元</div> + {else/} + <div class='charge-alone'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + {/if} + <i></i> + </div> + {/volist} + <div class="wst-frame2 " onclick="javascript:changeSelected(0,'itmeId',this)"> + <div class='charge-alone'> + <span class="j-charge-other">其他金额</span> + <span class="j-charge-money"><input class="charge-othermoney j-ipt" id="needPay" value="1" maxlength="10" data-rule="充值金额:required;" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)" maxlength="8"></span> + </div> + <i></i> + </div> + <input type="hidden" value="" id='itmeId' class='j-ipt' /> + <div class='wst-clear'></div> + </div> + + </div> + </div> + </div><div></div> + <div> + <div class="pay-type">选择支付方式</div> + <div class="pay-list"> + <input type="hidden" id="payCode" name="payCode" /> + {volist name="payments" id="payment"} + {if condition="$payment['isOnline'] eq 1"} + <div class="wst-payCode-{$payment['payCode']}" data="{$payment['payCode']}"></div> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + <div class="bnt-box"> + <div onclick='javascript:getPayUrl();' class="wst-pay-bnt"></div> + </div> + </div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/recharge/recharge.js?v={$v}'></script> +{/block} + diff --git a/hyhproject/home2/view/default/users/recharge/pay_step2.html b/hyhproject/home2/view/default/users/recharge/pay_step2.html new file mode 100755 index 0000000..49a9910 --- /dev/null +++ b/hyhproject/home2/view/default/users/recharge/pay_step2.html @@ -0,0 +1,52 @@ +{extend name="default/users/base" /} +{block name="title"}资金管理-充值{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/recharge.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class='wst-user-content'> + + <div class="pay-sbox-head"> + <div class="wst-user-head"><span>充值</span></div> + </div> + <div style="padding-top: 27px;"> + <div class="pay-tip2"></div> + </div> + <div class='pay-sbox' > + <div class="qrcode-box"> + <div class="pbox"> + 请您扫描以下二维码,钱包充值金额:<span class="wst-fred">¥{$needPay}</span> + </div> + <div style="" class="wst-qrcode"></div> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/js/qrcode.js?v={$v}'></script> +<script> + {if condition="$out_trade_no != '' and $code_url!=''"} + var qr = qrcode(10, 'M'); + qr.addData("{$code_url}"); + qr.make(); + $(".wst-qrcode").html(qr.createImgTag()); + + {/if} + setInterval(function(){ + var params = {}; + params.trade_no = "{$out_trade_no}"; + + $.ajax({ + url:"{:url('home/weixinpays/getPayStatus')}", + data:params, + type:"POST", + dataType:"json", + success:function(data){ + if(data.status==1){ + location.href = "{:url('home/logmoneys/usermoneys')}"; + } + } + }); + },1500); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/recharge/recharge.js b/hyhproject/home2/view/default/users/recharge/recharge.js new file mode 100755 index 0000000..ec20502 --- /dev/null +++ b/hyhproject/home2/view/default/users/recharge/recharge.js @@ -0,0 +1,58 @@ + +function getPayUrl(){ + var params = {}; + params.payObj = "recharge"; + params.targetType = 0; + params.needPay = $.trim($("#needPay").val()); + params.payCode = $.trim($("#payCode").val()); + params.itmeId = $.trim($("#itmeId").val()); + if(params.itmeId==0 && params.needPay<=0){ + WST.msg('请输入充值金额', {icon: 5}); + return; + } + if(params.payCode==""){ + WST.msg('请先选择支付方式', {icon: 5}); + return; + } + jQuery.post(WST.U('home/'+params.payCode+'/get'+params.payCode+"URL"),params,function(data) { + var json = WST.toJson(data); + if(json.status==1){ + location.href = json.url; + }else{ + WST.msg('充值失败', {icon: 5}); + } + }); +} + +function inEffect(obj,n){ + $(obj).addClass('j-selected').siblings('.wst-frame'+n).removeClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + if(n==0){ + $(".j-charge-other").hide(); + $(".j-charge-money").show(); + + }else{ + $(".j-charge-other").show(); + $(".j-charge-money").hide(); + } + inEffect(obj,2); +} +$(function(){ + $(".wst-frame2:first").click(); + $("#wst-check-orders").click(function(){ + $("#wst-orders-box").slideToggle(600); + }); + $("div[class^=wst-payCode]").click(function(){ + var payCode = $(this).attr("data"); + $("div[class^=wst-payCode]").each(function(){ + $(this).removeClass().addClass("wst-payCode-"+$(this).attr("data")); + }); + $(this).removeClass().addClass("wst-payCode-"+payCode+"-curr"); + $("#payCode").val(payCode); + }); + if($("div[class^=wst-payCode]").length>0){ + $("div[class^=wst-payCode]")[0].click(); + } +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/index.html b/hyhproject/home2/view/default/users/security/index.html new file mode 100755 index 0000000..39f8205 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/index.html @@ -0,0 +1,59 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} + <div class="wst-sec-info"> + <img class="wst-lfloat usersImg" data-original='__IMGURL__{:WSTUserPhoto($data['userPhoto'])}' width='100' height='100' title="{$data['loginName']}"/> + <div class="wst-sec-infor"> + <span class="wst-sec-na wst-lfloat">{$data['loginName']}</span> + {if($data['ranks']['rankId'])} + <span class="wst-sec-grade"><img class="wst-lfloat" src="__IMGURL__/{$data['ranks']['userrankImg']}"/><span class="wst-lfloat">{$data['ranks']['rankName']}</span></span> + {/if} + <div style='clear:both;'></div> + <div style="margin-top:6px;"> + <span class="wst-sec-infoi" id="level"></span> + <div class="wst-sec-infoi" style="margin-top:5px;"> + <span class="wst-sec-strip wst-lfloat">{if ($data['loginPwd'])}<span class="wst-sec-strip2 wst-lfloat"></span>{/if}{if ($data['userEmail'])}<span class="wst-sec-strip2 wst-lfloat"></span>{/if}{if ($data['userPhone'])}<span class="wst-sec-strip2 wst-lfloat"></span>{/if}</span> + </div> + <div class="wst-sec-infoi" style="margin-top:5px;"> + <span>上次登录时间:{php}echo date("Y年m月d日 H:i:s",strtotime($data['lastTime']));{/php}</span><br/> + <span>上次登录IP:{$data['lastIP']}</span> + </div> + </div> + </div> + <div style='clear:both;'></div> + </div> + <div class="wst-sec-s"> + <div class="wst-sec-lists">{if ($data['loginPwd'])}<span class="wst-sec-green"><img src="__STYLE__/img/user_icon_yyz.png"/>已设置</span>{else}<span class="wst-sec-ash"><img src="__STYLE__/img/icon_wyz.png"/>未设置</span>{/if} + <span class="wst-sec-w">&nbsp;登录密码</span>&nbsp;&nbsp;登录密码用于会员的登录以及进行登录的一系列操作,{if ($data['loginPwd'])}建议您定期更改密码{else}您还没有设置密码{/if} + <a class="wst-user-buta wst-rfloat" onclick="location.href=WST.U('home/users/editPass')">{if ($data['loginPwd'])}修改密码{else}立即设置{/if}</a></div> + <div class="wst-sec-lists">{if ($data['payPwd'])}<span class="wst-sec-green"><img src="__STYLE__/img/user_icon_yyz.png"/>已设置</span>{else}<span class="wst-sec-ash"><img src="__STYLE__/img/icon_wyz.png"/>未设置</span>{/if} + <span class="wst-sec-w">&nbsp;支付密码</span>&nbsp;&nbsp;支付密码用于会员的提现账号设置及提现申请操作,{if ($data['payPwd'])}建议您定期更改支付密码{else}您还没有设置支付密码{/if} + <a class="wst-user-buta wst-rfloat" onclick="location.href=WST.U('home/users/editPayPass')">{if ($data['payPwd'])}修改密码{else}立即设置{/if}</a></div> + <div class="wst-sec-lists">{if ($data['userEmail'])}<span class="wst-sec-green"><img src="__STYLE__/img/user_icon_yyz.png"/>已验证</span>{else}<span class="wst-sec-ash"><img src="__STYLE__/img/icon_wyz.png"/>未验证</span>{/if} + <span class="wst-sec-w">&nbsp;邮箱验证</span>&nbsp;&nbsp;邮箱验证方便您及时接收优惠促销信息,以及积分、优惠卷和账户余额变动的提醒。{if ($data['userEmail'])}您的绑定邮箱:{$data['userEmail']}{else}您还没有验证邮箱{/if} + <a class="wst-user-buta wst-rfloat" onclick="location.href=WST.U('home/users/editEmail')">{if ($data['userEmail'])}修改邮箱{else}立即验证{/if}</a></div> + <div class="wst-sec-lists">{if ($data['userPhone'])}<span class="wst-sec-green"><img src="__STYLE__/img/user_icon_yyz.png"/>已验证</span>{else}<span class="wst-sec-ash"><img src="__STYLE__/img/icon_wyz.png"/>未验证</span>{/if} + <span class="wst-sec-w">&nbsp;手机验证</span>&nbsp;&nbsp;手机验证方便您及时接收优惠促销信息,以及积分、优惠卷和账户余额变动的提醒。{if ($data['userPhone'])}您的绑定手机:{$data['userPhone']}{else}您还没有验证手机{/if} + <a class="wst-user-buta wst-rfloat" onclick="location.href=WST.U('home/users/editPhone')">{if ($data['userPhone'])}修改手机{else}立即验证{/if}</a></div> + <div style='clear:both;'></div> + </div> +{/block} +{block name="js"} +<script> +$(function(){ + var securityCount = $('.wst-sec-strip2').length; + if(securityCount==1){ + $('#level').html('安全级别(较低级)&nbsp; &nbsp; &nbsp;<span class="wst-sec-infoin">建议提升安全</span>'); + }else if(securityCount==2){ + $('#level').html('安全级别(中级)&nbsp; &nbsp; &nbsp;<span class="wst-sec-infoin">建议提升安全</span>'); + }else if(securityCount==3){ + $('#level').html('安全级别(高级)&nbsp; &nbsp; &nbsp;<span class="wst-sec-infoin">建议定期更改密码</span>'); + }else{ + $('#level').html('安全级别(低级)&nbsp; &nbsp; &nbsp;<span class="wst-sec-infoin">账号有风险</span>'); + } +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/security.js b/hyhproject/home2/view/default/users/security/security.js new file mode 100755 index 0000000..f3f81da --- /dev/null +++ b/hyhproject/home2/view/default/users/security/security.js @@ -0,0 +1,320 @@ +var time = 0; +var isSend = false; +var myorm; +var emailForm; +var phoneForm; +var getemailForm; +var getphoneForm; +var getpayForm; +var payForm; +$(function(){ + $('#phoneVerify').validator({ + valid: function(form){ + var n=$('#VerifyId').val(); + getPhoneVerifys(n); + } + }); +}) +function vePayForm(){ + //修改支付密码 + myorm = $('#payform').validator({ + valid: function(form){ + var params = WST.getParams('.ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(params.oldPass)params.oldPass = rsa.encrypt(params.oldPass); + params.newPass = rsa.encrypt(params.newPass); + params.reNewPass = rsa.encrypt(params.reNewPass); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/payPassEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1,time:2000},function(){ + location.href=WST.U('home/users/security'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }) +} +function veMyorm(){ + //修改密码 + myorm = $('#myorm').validator({ + fields: { + newPass: { + rule:"required;length[6~20]", + msg:{required:"请输入新密码"}, + tip:"请输入新密码" + }, + reNewPass: { + rule:"required;length[6~20];match[newPass]", + msg:{required:"请再次输入新密码",match:"两次输入密码不匹配"}, + tip:"请再次输入新密码" + }, + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(params.oldPass)params.oldPass = rsa.encrypt(params.oldPass); + params.newPass = rsa.encrypt(params.newPass); + params.reNewPass = rsa.encrypt(params.reNewPass); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/passEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1,time:2000},function(){ + location.href=WST.U('home/users/security'); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + } + }) +} +function veemailForm(){ + //绑定邮箱 + emailForm = $('#emailForm').validator({ + rules: { + remote: function(element){ + return $.post(WST.U('home/users/checkEmail'),{"loginName":element.value},function(data,textStatus){ + }); + } + }, + fields: { + userEmail: { + rule:"required;email;remote;", + msg:{required:"请输入邮箱",email:"请输入有效的邮箱"}, + tip:"请输入邮箱", + }, + secretCode: { + rule:"required", + msg:{required:"请输入校验码"}, + tip:"请输入校验码", + target:"#secretErr" + } + }, + + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/emailEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + var redirect = WST.U('home/users/doneEmailBind'); + var edit = $('#editEmail').val(); + if(edit)redirect=WST.U('home/users/editEmail3'); + WST.msg('验证通过',{icon:1},function(){location.href=redirect}); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +function sendEmail(edit){ + var url = 'home/users/getEmailVerify'; + if(isSend )return; + if(!$('#verifyCode').isValid())return; + if(!edit){ + if(!$('#userEmail').isValid())return; + }else{ + url = 'home/users/getEmailVerifyt'; + } + var loading = WST.msg('正在发送邮件,请稍后...', {icon: 16,time:60000}); + var params = WST.getParams('.ipt'); + $.post(WST.U(url),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('邮箱已发送,请注册查收'); + isSend = true; + time = 120; + $('#timeSend').attr('disabled', 'disabled').css('background','#e8e6e6'); + $('#timeSend').html('发送验证邮件(120)'); + var task = setInterval(function(){ + time--; + $('#timeSend').html('发送验证邮件('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeSend').html("重新发送验证邮件"); + $('#timeSend').removeAttr('disabled').css('background','#e23e3d'); + } + },1000); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); +} + + + + +function vephoneForm(){ + //绑定手机号 + phoneForm = $('#phoneForm').validator({ + valid: function(form){ + var me = this; + // ajax提交表单之前,先禁用submit + me.holdSubmit(); + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/phoneEdito'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + location.href=WST.U('home/users/editPhoneSu','pr='+json.process); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +function vegetemailForm(){ + //修改邮箱 + getemailForm = $('#getemailForm').validator({ + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/emailEditt'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('验证通过',{icon:1},function(){location.href=WST.U('home/users/editEmail2')}) + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +function vegetphoneForm(){ + //修改手机号 + getphoneForm = $('#getphoneForm').validator({ + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/phoneEditt'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + location.href=WST.U('home/users/editPhoneSut'); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +function vegetpayForm(){ + //重置支付密码 + getpayForm = $('#getpayForm').validator({ + valid: function(form){ + var params = WST.getParams('.ipt'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/payEditt'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + location.href=WST.U('home/users/editPaySut'); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +function vepayForm(){ + //设置支付密码 + payForm = $('#payForm').validator({ + valid: function(form){ + var me = this; + me.holdSubmit(); + var params = WST.getParams('.ipt'); + if(window.conf.IS_CRYPT=='1'){ + var public_key=$('#token').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + params.newPass = rsa.encrypt(params.newPass); + params.reNewPass = rsa.encrypt(params.reNewPass); + } + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/users/payEdito'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + location.href=WST.U('home/users/editPaySu','pr='+json.process); + }else{ + WST.msg(json.msg,{icon:2}); + WST.getVerify('#verifyImg'); + } + }); + } + }); +} +//发送手机验证码 +function getPhoneVerify(n){ + if(!$('#userPhone').isValid())return; + $('#VerifyId').val(n); + if(window.conf.SMS_VERFY==1){ + WST.open({type: 1,title:"请输入验证码",shade: [0.6, '#000'],border: [0],content: $('#phoneVerify'),area: ['600px', '180px']}); + }else{ + getPhoneVerifys(n); + } +} +function getPhoneVerifys(n){ + WST.msg('正在发送短信,请稍后...',{time:600000}); + var time = 0; + var isSend = false; + var params = WST.getParams('.ipt'); + $.post(WST.U('home/users/getPhoneVerify'+n),params,function(data,textStatus){ + var json = WST.toJson(data); + if(isSend )return; + isSend = true; + if(json.status!=1){ + WST.msg(json.msg, {icon: 5}); + WST.getVerify('#verifyImg'); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注册查收'); + layer.closeAll('page'); + time = 120; + $('#timeObtain').attr('disabled', 'disabled').css('background','#e8e6e6'); + $('#timeObtain').html('获取手机验证码(120)').css('width','130px'); + var task = setInterval(function(){ + time--; + $('#timeObtain').html('获取手机验证码('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeObtain').html("重新获取验证码").css('width','100px'); + $('#timeObtain').removeAttr('disabled').css('background','#e23e3d'); + } + },1000); + } + }); +} diff --git a/hyhproject/home2/view/default/users/security/user_edit_email.html b/hyhproject/home2/view/default/users/security/user_edit_email.html new file mode 100755 index 0000000..30d2cf4 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_edit_email.html @@ -0,0 +1,108 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>绑定邮箱</span><a href="{:url('home/users/security')}">返回</a></div> +<div class="wst-clear"></div> +<div class="wst-sec-head2"> + <div class="wst-lfloat wst-sec-min {if ($process=='One')}wst-sec-gr{/if}">1、验证身份</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='One')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Two')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Two')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Two')}wst-sec-gr{/if}">2、修改邮箱</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='Two')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Three')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Three')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Three')}wst-sec-gr{/if}">3、完成</div> +</div> +{if ($process=='One')} + <form method="post" id="getemailForm" autocomplete="off"> + <table class='wst-form'> + <tr> + <th align='right'><font color='red'>*</font>已验证的邮箱:</th> + <td>{$data['userEmail']}</td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>验证码:</th> + <td> + <input id="verifyCode" style="ime-mode:disabled;" name="verifyCode" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')" style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>校验码:</th> + <td style='height:60px;'> + <input id="secretCode" style="ime-mode:disabled;width:250px;" data-rule="校验码:required;" data-target="#secretErr" name="secretCode" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <button id="timeSend" class="wst-sec-but" type="button" onclick="sendEmail(true)" style="width:120px;height: 30px;margin-top:5px;">发送验证邮件</button><span id="secretErr"></span> + </td> + </tr> + + <tr> + <td colspan="2"> + <button id="next" class="wst-sec-but" type="submit" style="width:120px;height: 30px;margin-left:180px">下一步</button> + </td> + </tr> + </table> + </form> +{/if} +{if ($process=='Two')} + <form method="post" id="emailForm" autocomplete="off"> + <input type='hidden' id='process' class='ipt' value='{$process}'/> + <table class='wst-form'> + <tr> + <th align='right'>绑定邮箱地址 <font color='red'>*</font>:</th> + <td> + <input type='text' class="ipt" id='userEmail' name='userEmail' style='width:250px;' maxLength='30'/> + </td> + </tr> + <tr> + <th align='right'>验证码 <font color='red'>*</font>:</th> + <td> + <input id="verifyCode" data-rule="验证码:required" data-target="#verify" style="ime-mode:disabled;width:250px;" name="verifyCode" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')" style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>校验码:</th> + <td style='height:60px;'> + <input id="secretCode" style="ime-mode:disabled;width:250px;" data-rule="校验码:required;" data-target="#secretErr" name="secretCode" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <button id="timeSend" class="wst-sec-but" type="button" onclick="sendEmail()" style="width:120px;height: 30px;margin-top:5px;">发送验证邮件</button><span id="secretErr"></span> + </td> + </tr> + + <tr> + <td colspan="2"> + <button id="next" class="wst-sec-but" type="submit" style="width:120px;height: 30px;margin-left:180px">下一步</button> + </td> + </tr> + <input type="hidden" id="editEmail" value="1"> + </table> + </form> +{/if} +{if ($process=='Three')} +<div class="wst-sec-su"> + <span class="wst-sec-sut"><img src="__STYLE__/img/icon_success.png"/></span> + <span class="wst-sec-sub">您已成功绑定邮箱!</span> +</div> +{/if} +{/block} +{block name="js"} + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){veemailForm();vegetemailForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_edit_pay.html b/hyhproject/home2/view/default/users/security/user_edit_pay.html new file mode 100755 index 0000000..f393228 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_edit_pay.html @@ -0,0 +1,116 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>绑定手机</span><a href="{:url('home/users/security')}">返回</a></div> +<div class="wst-clear"></div> +<div class="wst-sec-head2"> + <div class="wst-lfloat wst-sec-min {if ($process=='One')}wst-sec-gr{/if}">1、验证身份</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='One')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Two')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Two')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Two')}wst-sec-gr{/if}">2、设置支付密码</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='Two')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Three')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Three')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Three')}wst-sec-gr{/if}">3、完成</div> +</div> +{if ($process=='One')} + {if($data['phoneType']==1)} + <form method="post" id="getpayForm" autocomplete="off"> + <table class='wst-form'> + <tr> + <th align='right'><font color='red'>*</font>已验证的手机:</th> + <td>{$data['userPhone']}</td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>输入短信校验码:</th> + <td> + <input type='text' class="ipt" id='Checkcode' name='Checkcode' data-rule="校验码: required;" data-msg-required="请输入校验码" data-tip="请输入校验码" data-target="#verifyPhone1" style='width:250px;' maxLength='30'/> + <button id="timeObtain" class="wst-sec-obtain" type="button" onclick="javascript:getPhoneVerify('pay');">获取手机验证码</button> + <span id="verifyPhone1"></span> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:116px;height:60px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> + {else} + <div class="wst-sec-su"> + <span class="wst-sec-sub" style="color: #333333;">您还未绑定手机号码,请绑定手机号码。</span> + </div> + {/if} +{/if} +{if ($process=='Two')} + <form method="post" id="payForm" autocomplete="off"> + <input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> + <input type='hidden' id='process' class='ipt' value='{$process}' autocomplete="off"/> + <table class='wst-form'> + <tr> + <th align='right'> <font color='red'>*</font>新支付密码:</th> + <td> + <input type='password' class="ipt" id='newPass' name='newPass' style='width:250px;' maxLength='6' data-rule='新支付密码:required;length(6)'/> + </td> + </tr> + <tr> + <th align='right'> <font color='red'>*</font>确认支付密码:</th> + <td> + <input type='password' class="ipt" id='reNewPass' name='reNewPass' style='width:250px;' maxLength='6' data-rule='确认支付密码:required;length(6)'/> + </td> + </tr> + <tr> + <tr> + <td colspan='2' style='padding-left:75px;height:60px;'> + <button class='wst-sec-but wst-lfloat' type="submit" style="width:100px;height: 30px;">保&nbsp;存</button> + <button class='wst-sec-but2 wst-lfloat' type="reset" style="width:100px;height: 30px;margin-left:16px;">重&nbsp;置</button> + </td> + </tr> + </table> + </form> +<div style="text-align: center;margin-top:50px;"><button type="button" id="timeSend" class='wst-btn-querys'style="display:none;">下一步</button></div> +{/if} +{if ($process=='Three')} +<div class="wst-sec-su"> + <span class="wst-sec-sut"><img src="__STYLE__/img/icon_success.png"/></span> + <span class="wst-sec-sub">您已成功重置支付密码!</span> +</div> +{/if} + <form method="post" id="phoneVerify" autocomplete="off" style="display:none;"> + <input type='hidden' id='VerifyId' value='' autocomplete="off"/> + <table class='wst-form' style="width:500px;"> + <tr> + <th align='right'><font color='red'>*</font>验证码:</th> + <td> + <input id="smsVerfy" style="ime-mode:disabled;width:150px;" name="smsVerfy" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')"style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:71px;height:50px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){vegetpayForm();vepayForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_edit_phone.html b/hyhproject/home2/view/default/users/security/user_edit_phone.html new file mode 100755 index 0000000..781f6c0 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_edit_phone.html @@ -0,0 +1,108 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>绑定手机</span><a href="{:url('home/users/security')}">返回</a></div> +<div class="wst-clear"></div> +<div class="wst-sec-head2"> + <div class="wst-lfloat wst-sec-min {if ($process=='One')}wst-sec-gr{/if}">1、验证身份</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='One')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Two')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Two')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Two')}wst-sec-gr{/if}">2、修改手机</div> + <div class="wst-lfloat wst-sec-min1 {if ($process=='Two')}wst-sec-gr1{/if}"></div> + <div class="wst-lfloat wst-sec-mi"> + <div class="wst-lfloat wst-sec-min2 {if ($process=='Three')}wst-sec-gr2{/if}"></div> + <div class="wst-lfloat wst-sec-min3 {if ($process=='Three')}wst-sec-gr3{/if}"></div> + </div> + <div class="wst-lfloat wst-sec-min {if ($process=='Three')}wst-sec-gr{/if}">3、完成</div> +</div> +{if ($process=='One')} + <form method="post" id="getphoneForm" autocomplete="off"> + <table class='wst-form'> + <tr> + <th align='right'><font color='red'>*</font>已验证的手机:</th> + <td>{$data['userPhone']}</td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>输入短信校验码:</th> + <td> + <input type='text' class="ipt" id='Checkcode' name='Checkcode' data-rule="校验码: required;" data-msg-required="请输入校验码" data-tip="请输入校验码" data-target="#verifyPhone1" style='width:250px;' maxLength='30'/> + <button id="timeObtain" class="wst-sec-obtain" type="button" onclick="javascript:getPhoneVerify('t');">获取手机验证码</button> + <span id="verifyPhone1"></span> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:116px;height:60px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> +{/if} +{if ($process=='Two')} + <form method="post" id="phoneForm" autocomplete="off"> + <input type='hidden' id='process' class='ipt' value='{$process}' autocomplete="off"/> + <table class='wst-form'> + <tr> + <th align='right'><font color='red'>*</font>绑定手机号码:</th> + <td> + <input type='text' class="ipt" id='userPhone' name='userPhone' style='width:250px;' maxLength='30' data-rule="手机号 required;mobile;remote(post:{:url('home/users/checkLoginKey')})" data-msg-mobile="请输入有效的手机号" data-msg-required="请输入手机号" data-tip="请输入手机号" data-target="#verifyPhone"/> + <button id="timeObtain" class="wst-sec-obtain" type="button" onclick="javascript:getPhoneVerify('o');">获取手机验证码</button> + <span id="verifyPhone"></span> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>输入短信校验码:</th> + <td> + <input type='text' class="ipt" id='Checkcode' name='Checkcode' style='width:250px;' maxLength='30' data-rule="短信校验码: required;" data-msg-required="请输入短信校验码" data-tip="请输入短信校验码"/> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:116px;height:60px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">立即绑定</button> + </td> + </tr> + </table> + </form> +<div style="text-align: center;margin-top:50px;"><button type="button" id="timeSend" class='wst-btn-querys'style="display:none;">下一步</button></div> +{/if} +{if ($process=='Three')} +<div class="wst-sec-su"> + <span class="wst-sec-sut"><img src="__STYLE__/img/icon_success.png"/></span> + <span class="wst-sec-sub">您已成功绑定手机!</span> +</div> +{/if} + <form method="post" id="phoneVerify" autocomplete="off" style="display:none;"> + <input type='hidden' id='VerifyId' value='' autocomplete="off"/> + <table class='wst-form' style="width:500px;"> + <tr> + <th align='right'><font color='red'>*</font>验证码:</th> + <td> + <input id="smsVerfy" style="ime-mode:disabled;width:150px;" name="smsVerfy" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')"style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:71px;height:50px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> +{/block} +{block name="js"} + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){vegetphoneForm();vephoneForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_email.html b/hyhproject/home2/view/default/users/security/user_email.html new file mode 100755 index 0000000..8011f41 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_email.html @@ -0,0 +1,66 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>绑定邮箱</span><a href="{:url('home/users/security')}">返回</a></div> +<div class="wst-clear"></div> +{if ($process=='One')} + <form method="post" id="emailForm" autocomplete="off"> + <table class='wst-form'> + <tr> + <th align='right'><font color='red'>*</font>绑定邮箱地址:</th> + <td> + <input type='text' class="ipt" id='userEmail' name='userEmail' style='width:250px;' maxLength='30'/> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>验证码:</th> + <td> + <input id="verifyCode" data-rule="验证码:required" data-target="#verify" style="ime-mode:disabled;width:250px;" name="verifyCode" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')" style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>校验码:</th> + <td style='height:60px;'> + <input id="secretCode" style="ime-mode:disabled;width:250px;" name="secretCode" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <button id="timeSend" class="wst-sec-but" type="button" onclick="sendEmail()" style="width:120px;height: 30px;margin-top:5px;">发送验证邮件</button><span id="secretErr"></span> + </td> + </tr> + <tr> + <td colspan="2"> + <button id="next" class="wst-sec-but" type="submit" style="width:120px;height: 30px;margin-left:180px">下一步</button> + </td> + </tr> + </table> + </form> +<div id="prompt" class="wst-sec-prompt hide"> + <div class="wst-lfloat"> + <p><span>已发送验证邮箱至:</span><span id="inemail" style=" font-weight: bold;"></span></p> + <p class="wst-sec-p1">验证邮箱30分钟内有效,请尽快登录您的邮箱点击验证链接完成验证</p> + <p style="color:#f10b0b;">(请立即完成验证,邮箱验证不通过则绑定邮箱失败)</p> + <p class="wst-sec-p1" style="font-weight: bold;">没收到邮箱?</p> + <p class="wst-sec-p2">1.检查您的垃圾箱或广告箱,邮件有可能被误认为垃圾或广告邮件;或选择<a style="color:#006898;" onclick="location.href=WST.U('home/users/editEmail')">重新发送</a></p> + </div> +</div> +{/if} +{if ($process=='Three')} +<div class="wst-sec-su"> + <span class="wst-sec-sut"><img src="__STYLE__/img/icon_success.png"/></span> + <span class="wst-sec-sub">您已成功绑定邮箱!</span> +</div> +{/if} +{/block} +{block name="js"} + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){veemailForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_pass.html b/hyhproject/home2/view/default/users/security/user_pass.html new file mode 100755 index 0000000..cd6b733 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_pass.html @@ -0,0 +1,49 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> +<div class="wst-user-head"><span>设置密码</span><a href="{:url('home/users/security')}">返回</a></div> + <form method="post" id="myorm" autocomplete="off"> + <table class='wst-form'> + {if ($data['loginPwd'])} + <tr> + <th align='right'> <font color='red'>*</font>原始密码:</th> + <td> + <input type='password' class="ipt" id='oldPass' name='oldPass' {if ($data['loginPwd'])}data-rule="原始密码: required;" data-msg-required="请填写原始密码" data-tip="请输入原始密码"{/if} style='width:250px;' maxLength='16'/> + </td> + </tr> + {/if} + <tr> + <th align='right'> <font color='red'>*</font>新密码:</th> + <td> + <input type='password' class="ipt" id='newPass' name='newPass' style='width:250px;' maxLength='16'/> + </td> + </tr> + <tr> + <th align='right'> <font color='red'>*</font>确认密码:</th> + <td> + <input type='password' class="ipt" id='reNewPass' name='reNewPass' style='width:250px;' maxLength='16'/> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:75px;height:60px;'> + <button class='wst-sec-but wst-lfloat' type="submit" style="width:100px;height: 30px;">保&nbsp;存</button> + <button class='wst-sec-but2 wst-lfloat' type="reset" style="width:100px;height: 30px;margin-left:16px;">重&nbsp;置</button> + </td> + </tr> + </table> + </form> + +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){veMyorm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_pay_pass.html b/hyhproject/home2/view/default/users/security/user_pay_pass.html new file mode 100755 index 0000000..2bef234 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_pay_pass.html @@ -0,0 +1,53 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<input type="hidden" id="token" value='{:WSTConf("CONF.pwdModulusKey")}'/> +<div class="wst-user-head"><span>设置支付密码</span><a href="{:url('home/users/security')}">返回</a></div> + <form method="post" id="payform" autocomplete="off"> + <table class='wst-form'> + {if ($data['payPwd'])} + <tr> + <th align='right'> <font color='red'>*</font>原始密码:</th> + <td> + <input type='password' class="ipt" id='oldPass' name='oldPass' {if ($data['payPwd'])}data-rule="原始支付密码: required;" data-msg-required="请填写原始支付密码" data-tip="请输入原始支付密码"{/if} style='width:250px;' maxLength='16'/> + </td> + </tr> + {/if} + <tr> + <th align='right'> <font color='red'>*</font>新支付密码:</th> + <td> + <input type='password' class="ipt" id='newPass' name='newPass' style='width:250px;' maxLength='16' data-rule='新支付密码:required;'/> + </td> + </tr> + <tr> + <th align='right'> <font color='red'>*</font>确认支付密码:</th> + <td> + <input type='password' class="ipt" id='reNewPass' name='reNewPass' style='width:250px;' maxLength='16' data-rule='确认支付密码:required;'/> + </td> + </tr> + <tr> + <th align='right'></th> + <td><a href="{:url('home/users/backPayPass')}">忘记支付密码?</a></td> + </tr> + <tr> + <td colspan='2' style='padding-left:75px;height:60px;'> + <button class='wst-sec-but wst-lfloat' type="submit" style="width:100px;height: 30px;">保&nbsp;存</button> + <button class='wst-sec-but2 wst-lfloat' type="reset" style="width:100px;height: 30px;margin-left:16px;">重&nbsp;置</button> + </td> + </tr> + </table> + </form> + +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/js/rsa.js"></script> + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){vePayForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/security/user_phone.html b/hyhproject/home2/view/default/users/security/user_phone.html new file mode 100755 index 0000000..0945172 --- /dev/null +++ b/hyhproject/home2/view/default/users/security/user_phone.html @@ -0,0 +1,68 @@ +{extend name="default/users/base" /} +{block name="title"}安全设置 - 买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link href="__STYLE__/css/security.css?v={$v}" rel="stylesheet"> +{/block} +{block name="content"} +<div class="wst-user-head"><span>绑定手机</span><a href="{:url('home/users/security')}">返回</a></div> +<div class="wst-clear"></div> +{if ($process=='One')} + <form method="post" id="phoneForm" autocomplete="off"> + <table class='wst-form'> + <tr> + <th align='right'>绑定手机号码<font color='red'>*</font>:</th> + <td> + <input type='text' class="ipt" id='userPhone' name='userPhone' style='width:250px;' maxLength='30' data-rule="手机号 required;mobile;remote(post:{:url('home/users/checkLoginKey')})" data-msg-mobile="请输入有效的手机号" data-msg-required="请输入手机号" data-tip="请输入手机号" data-target="#verifyPhone"/> + <button id="timeObtain" class="wst-sec-obtain" type="button" onclick="javascript:getPhoneVerify('b');">获取手机验证码</button> + <span id="verifyPhone"></span> + </td> + </tr> + <tr> + <th align='right'><font color='red'>*</font>输入短信校验码:</th> + <td> + <input type='text' class="ipt" id='Checkcode' name='Checkcode' style='width:250px;' maxLength='30' data-rule="短信校验码: required;" data-msg-required="请输入短信校验码" data-tip="请输入短信校验码"/> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:115px;height:60px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">立即绑定</button> + </td> + </tr> + </table> + </form> + <form method="post" id="phoneVerify" autocomplete="off" style="display:none;"> + <input type='hidden' id='VerifyId' value='' autocomplete="off"/> + <table class='wst-form' style="width:500px;"> + <tr> + <th align='right'><font color='red'>*</font>验证码:</th> + <td> + <input id="smsVerfy" style="ime-mode:disabled;width:150px;" name="smsVerfy" data-rule="验证码: required;" data-msg-required="请输入验证码" data-tip="请输入验证码" data-target="#verify" class="ipt wst-lfloat" tabindex="6" autocomplete="off" maxlength="6" type="text"/> + <label class="wst-sec-img"> + <img id='verifyImg' src="{:url('home/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")' style="width:110px;"> + </label> + <label>&nbsp;看不清?<a href="javascript:WST.getVerify('#verifyImg')"style="color:#69b7b5;">换一张</a></label><span id="verify"></span> + </td> + </tr> + <tr> + <td colspan='2' style='padding-left:71px;height:50px;'> + <button class="wst-sec-but" type="submit" style="width:100px;height: 30px;">确认</button> + </td> + </tr> + </table> + </form> +{/if} +{if ($process=='Three')} +<div class="wst-sec-su"> + <span class="wst-sec-sut"><img src="__STYLE__/img/icon_success.png"/></span> + <span class="wst-sec-sub">您已成功绑定手机!</span> +</div> +{/if} +{/block} +{block name="js"} + <script type='text/javascript' src='__STYLE__/users/security/security.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script> + $(function(){vephoneForm();}) + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/user.js b/hyhproject/home2/view/default/users/user.js new file mode 100755 index 0000000..5026af3 --- /dev/null +++ b/hyhproject/home2/view/default/users/user.js @@ -0,0 +1,224 @@ +var userPic; +var falg = true; +$(function () { + $('#tab').TabPanel({tab:0,callback:function(no){ + if(no==1 && falg){ + uploadUserPhoto();falg = false; + } + + }}); +}); + + +// function checkCoords() +// { +// //判断是否有裁剪 +// if (parseInt($('#w').val())){ +// var loading = WST.msg('图像处理中,请稍候...', {icon: 16,shade: [0.3, '#999999']}); +// /*获取裁剪数据*/ +// var photoData = {}; +// photoData.x = $('#x').val(); +// photoData.y = $('#y').val(); +// photoData.w = $('#w').val(); +// photoData.h = $('#h').val(); +// photoData.photoSrc = $('#photoSrc').val(); +// $.post(WST.U('Home/users/editUserPhoto'),photoData,function(data, textStatus){ +// if(data.status==1) +// { +// layer.close(loading); +// //将上传的图片路径赋给全局变量 +// userPic = data.data; +// $('#userPhotoPreview').html('<img id="userPhoto" class="ipt" src="'+WST.conf.ROOT+'/'+userPic+'?='+Math.random()+'" height="150" />'); +// $('#userPhotoPreview1').html('<img id="userPhoto1" class="ipt" src="'+WST.conf.ROOT+'/'+userPic+'?='+Math.random()+'" height="150" />'); +// $('#userPhotoCut').hide(); +// $('#userPhoto').show(); +// }else{ +// WST.msg(data.msg,{icon:2}); +// return false; +// } +// }); +// return true; +// } +// WST.msg('请对图片裁剪后再进行提交',{icon:2}); +// return false; +// } + +/** + * [checkCoords 修改为上传oss的变化] mark 20180612 + * @return {[type]} [description] + */ +function checkCoords() +{ + //判断是否有裁剪 + if (parseInt($('#w').val())){ + var loading = WST.msg('图像处理中,请稍候...', {icon: 16,shade: [0.3, '#999999']}); + /*获取裁剪数据*/ + var photoData = {}; + photoData.x = $('#x').val(); + photoData.y = $('#y').val(); + photoData.w = $('#w').val(); + photoData.h = $('#h').val(); + photoData.photoSrc = $('#photoSrc').val(); + $.post(WST.U('Home/users/editUserPhoto'),photoData,function(data, textStatus){ + if(data.status==1) + { + layer.close(loading); + //将上传的图片路径赋给全局变量 + userPic = data.data; + $('#userPhotoPreview').html('<img id="userPhoto" class="ipt" src="'+WST.conf.IMGURL+'/'+userPic+'" height="150" />'); + $('#userPhotoPreview1').html('<img id="userPhoto1" class="ipt" src="'+WST.conf.IMGURL+'/'+userPic+'" height="150" />'); + $('#userPhotoCut').hide(); + $('#userPhoto').show(); + }else{ + WST.msg(data.msg,{icon:2}); + return false; + } + }); + return true; + } + WST.msg('请对图片裁剪后再进行提交',{icon:2}); + return false; +} + +function uploadUserPhoto() +{ + WST.upload({ + pick:'#userPhotoPicker', + formData: {dir:'users',isCut:1}, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f){ + var json = WST.toJson(f); + if(json.status==1){ + /*上传成功*/ + $('#userPhotoCut').show(); + $('#userPhoto').hide(); + + // var uploadPhotoSrc = WST.conf.ROOT+"/"+json.savePath+json.thumb+'?='+Math.random(); + // 修改为oss地址 mark 20180612 by zl + var uploadPhotoSrc = WST.conf.IMGURL+"/"+json.savePath+json.thumb; + + + var cutCode = '<img src="'+uploadPhotoSrc+'" id="target" alt="" style="max-width:606;height:auto;" />'; + cutCode += '<div id="preview-pane">'; + cutCode += '<div><p align="center">裁剪预览</p>'; + cutCode += '<div class="cut-help"><h4>操作帮助</h4>' + cutCode += '<p>请在裁剪区域放大缩小及移动选取框,选择要裁剪的范围,裁切宽高比例固定;裁切后的效果为右侧预览图所显示;保存提交后生效。</p></div></div>' + cutCode += '<div class="preview-container"><img src="'+uploadPhotoSrc+'" class="jcrop-preview" alt="Preview" /></div></div>'; + $('#userPhotoCutBox>p').html(cutCode); + $('#photoSrc').val(json.savePath+json.thumb); + $('#userPic').val(json.savePath+json.thumb); + //初始化jcrop + jcropInit(); + $('#uploadMsg').empty().hide(); + + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} + +var jcrop_api; +function jcropInit(){ + var boundx, + boundy, + + $preview = $('#preview-pane'), + $pcnt = $('#preview-pane .preview-container'), + $pimg = $('#preview-pane .preview-container img'), + + xsize = $pcnt.width(), + ysize = $pcnt.height(); + + $('#target').Jcrop({ + onChange: updatePreview, + onSelect: updatePreview, + aspectRatio: 1, + },function(){ + // Use the API to get the real image size + var bounds = this.getBounds(); + boundx = bounds[0]; + boundy = bounds[1]; + //设置宽度以使文字居中 + $('#img-src').css('width',boundx+'px'); + + // Store the API in the jcrop_api variable + jcrop_api = this; + jcrop_api.setSelect([0,0,150,150]); + + // Move the preview into the jcrop container for css positioning + $preview.appendTo(jcrop_api.ui.holder); + }); + + function updatePreview(c) + { + if (parseInt(c.w) > 0) + { + var rx = xsize / c.w; + var ry = ysize / c.h; + + $pimg.css({ + width: Math.round(rx * boundx) + 'px', + height: Math.round(ry * boundy) + 'px', + marginLeft: '-' + Math.round(rx * c.x) + 'px', + marginTop: '-' + Math.round(ry * c.y) + 'px' + }); + } + //设置裁剪的图片数据 + $('#x').val(c.x); + $('#y').val(c.y); + $('#w').val(c.w); + $('#h').val(c.h); + }; +} + + +$(function(){ + /*日期插件*/ + laydate({ + elem: '#brithday', //需显示日期的元素选择器 + event: 'click', //触发事件 + format: 'YYYY-MM-DD', //日期格式 + istime: false, //是否开启时间选择 + isclear: true, //是否显示清空 + istoday: true, //是否显示今天 + issure: true, //是否显示确认 + festival: true, //是否显示节日 + min: '1900-01-01', //最小日期 + max: '2099-12-31', //最大日期 + fixed: false, //是否固定在可视区域 + zIndex: 99999999 //css z-index + }); + + /* 表单验证 */ + $('#userEditForm').validator({ + fields: { + userName: {rule:"required",msg:{required:"请输入昵称"},tip:"请输入昵称"}, + userSex: {rule:"checked;",msg:{checked:"至少选择一项"},tip:"请选择您的性别"} + }, + valid: function(form){ + var params = WST.getParams('.ipt'); + if(!userPic){ + userPic = $('#userPic').val(); + } + //接收上传的头像路径 + params.userPhoto = userPic; + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('Home/Users/toEdit'),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg("操作成功",{icon:1}); + return; + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + }, + + }); + +}); \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/user_edit.html b/hyhproject/home2/view/default/users/user_edit.html new file mode 100755 index 0000000..91686b7 --- /dev/null +++ b/hyhproject/home2/view/default/users/user_edit.html @@ -0,0 +1,170 @@ +{extend name="default/users/base" /} +{block name="title"}首页-买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +<link rel="stylesheet" href="__STATIC__/plugins/jcrop/css/jquery.Jcrop.css?v={$v}" type="text/css" /> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="content"} +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +<form id="userEditForm" autocomplete="off" > + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav uinfo-nav"> + <li id="wst-msg-li-0">个人资料<span style="display:none;" class="wst-order-tips-box"></span></li> + <li id="wst-msg-li-1">头像照片<span style="display:none;"></span></li> + </ul> + <div class="wst-tab-content" style='width:99%;border:none;'> + <div class='wst-tab-item'> + <table class='wst-form uinfo-form' > + <tr> + <th>登录账号<font color='red'> </font>:</th> + <td width="260" class="gray"> + <div id='user_account'>{:session('WST_USER.loginName')}</div> + </td> + <td class="gray" style='padding-left:15px;'>个人头像:</td> + </tr> + <tr> + <th width='100'><font color='red'>*</font>昵称:</th> + <td class="uinfo"> + <input type="text" class="ipt" id="userName" name="userName" value="{$data['userName']}" /> + </td> + <td rowspan="6" valign="top"> + <div id='userPhotoPreview1' style="border:1px solid #ccc;width:151px;height:151px;margin-left:15px;"> + <!-- <img class="usersImg" data-original='{:WSTUserPhoto($data['userPhoto'])}' height='150'/> --> + <!-- mark 20180612 修改为oss地址--> + <img class="usersImg" data-original='__IMGURL__/{:WSTUserPhoto($data['userPhoto'])}' height='150'/> + <br/> + </div> + </td> + </tr> + <tr> + <th>真实姓名<font color='red'> </font>:</th> + <td class="uinfo"> + <input type="text" class="ipt" id="trueName" name="trueName" value="{$data['trueName']}" /> + </td> + </tr> + <tr> + <th><font color='red'>*</font>性别:</th> + <td> + <div class="radio-box"> + <label><input type='radio' class='ipt wst-radio' name='userSex' id="userSex-1" <?=($data['userSex']==1)?'checked':'';?> value="1" /><label class="mt-1" for="userSex-1"></label> 男</label> + <label><input type='radio' class='ipt wst-radio' name='userSex' id="userSex-2" <?=($data['userSex']==2)?'checked':'';?> value="2" /><label class="mt-1" for="userSex-2"></label> 女</label> + <label><input type='radio' class='ipt wst-radio' name='userSex' id="userSex-3" <?=($data['userSex']==0)?'checked':'';?> value="0" /><label class="mt-1" for="userSex-3"></label> 保密</label> + </div> + </td> + </tr> + <tr> + <th>生日<font color='red'></font>:</th> + <td class="uinfo"> + <input id="brithday" class="ipt" id="brithday" name="brithday" value="{$data['brithday']}" > + </td> + </tr> + + <tr> + <th>QQ<font color='red'> </font>:</th> + <td class="uinfo"> + <input type="text" class="ipt" id="userQQ" name="userQQ" value="{$data['userQQ']}" /> + </td> + </tr> + + + + <tr> + <td colspan='2' style="text-align:center"> + <input type="hidden" name="id" id="userId" class="ipt" value="{$data['userId']}" /> + <button type="submit" class="wst-sec-but u-btn">保存</button> + <button type="reset" class="wst-sec-but u-btn">重置</button> + </td> + </tr> + </table> + + </div> + + +<div class='wst-tab-item' style="display:none" > + + <table class='wst-form' id="userPhoto"> + <tr> + <th width='100'>头像预览<font color='red'> </font>:</th> + <td></td> + </tr> + <tr> + <td></td> + <td> + <div id='userPhotoPreview'> + {if ($data['userPhoto'])} + <!-- mark 修改为oss地址 by 20180612--> + <img class="usersImg" data-original='__IMGURL__/{$data['userPhoto']}' height='150' width="150"/> + {else} + <img class="usersImg" data-original='' height='150' width="150" /> + {/if} + <br/> + </div> + </td> + </tr> + <tr> + <td></td> + <td width="400">图片大小:150 x 150 (px),格式为 gif, jpg, jpeg, png</td></tr> + <tr> + <td></td> + <td width="50"> + <input type='hidden' id='userPic' value='{$data['userPhoto']}' /> + <div id="userPhotoPicker" style='margin-left:0px;margin-top:5px;height:30px;overflow:hidden'>上传用户头像</div> + </td> + </tr> + </table> + + + + <div class="container" id="userPhotoCut" style="display:none;"> + <div class="row"> + <div class="span12"> + <div class="jc-demo-box"> + <div id="img-src" style="text-align:center;max-width:500px;height:auto;"> + <p>裁剪区域</p> + </div> + + + <div id="userPhotoCutBox" style="position:relative;min-height:505px;"> + <div id="cutArea"></div><p></p> + </div> + + + + + <form action="<?=url('Home/Users/editUserPhoto')?>" method="post" id="userPhotoInfo"> + <input type="hidden" id="x" name="x" class="photo-size" /> + <input type="hidden" id="y" name="y" class="photo-size" /> + <input type="hidden" id="w" name="w" class="photo-size" /> + <input type="hidden" id="h" name="h" class="photo-size" /> + <input type="hidden" id="photoSrc" name="photoSrc" value=""> + <div id="c-btn"> + <input type="button" value="保存" class="cut-btn" onclick="checkCoords()"> + <input type="button" value="返回" class="cut-btn" onclick="returnPhotoPage()"> + </div> + </form> + + <div class="wst-clear"></div> + + </div> + </div> + </div> + </div> + + +</div> + + </div> + </div> + + + +</form> + +{/block} +{block name="js"} + <script type="text/javascript" src="__STATIC__/plugins/jcrop/js/jquery.Jcrop.js?v={$v}"></script> + <script type='text/javascript' src='__STYLE__/users/user.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> + <script type="text/javascript" src="__STATIC__/plugins/layer/laydate.js?v={$v}"></script> +{/block} diff --git a/hyhproject/home2/view/default/users/useraddress/edit.html b/hyhproject/home2/view/default/users/useraddress/edit.html new file mode 100755 index 0000000..6fc1d5f --- /dev/null +++ b/hyhproject/home2/view/default/users/useraddress/edit.html @@ -0,0 +1,95 @@ +{extend name="default/users/base" /} +{block name="title"}首页-买家中心{__block__}{/block} +{block name="css"} +<link href="__STATIC__/plugins/validator/jquery.validator.css?v={$v}" rel="stylesheet"> +{/block} + +{block name="content"} +<style> +.wst-form tr>td>input[type='text']{ + width:339px; + height:20px; +} +</style> +<div class="wst-user-head" style="margin-bottom:3px;"><span>管理地址</span></div> +<form id="useraddressForm" autocomplete="off" > + <table class='wst-form' > + <tr> + <th><font color='red'>*</font>区域:</th> + <td> + <select id="area_0" class='j-areas' level="0" onchange="WST.ITAreas({id:'area_0',val:this.value,isRequire:true,className:'j-areas'});"> + <option value="">-请选择-</option> + {foreach $area1 as $v} + <option value="{$v['areaId']}">{$v['areaName']}</option> + {/foreach} + </select> + </td> + <td colspan="3"> + <div style="width:400px;height:20px;float:left" id="errorMsg"></div> + </td> + </tr> + <tr> + <th width='110'><font color='red'>*</font>详细地址:</th> + <td> + <input type="text" class="ipt" id="userAddress" name="userAddress" value="{$data['userAddress']}" placeholder="您的详细地址" maxlength="30" /> + </td> + </tr> + + <tr> + <th><font color='red'>*</font>联系名称:</th> + <td> + <input type="text" class="ipt" id="userName" name="userName" value="{$data['userName']}" placeholder="联系名称" maxlength="20" /> + </td> + </tr> + + <tr> + <th><font color='red'>*</font>联系电话:</th> + <td> + <input type="text" class="ipt contact" id="userPhone" name="userPhone" value="{$data['userPhone']}" placeholder="联系电话" > + </td> + </tr> + <tr> + <th><font color='red'>*</font>是否默认地址:</th> + <td> + <div class="radio-box"> + <label><input type="radio" class="ipt wst-radio" id="isDefault-1" name="isDefault" <?=($data['isDefault']==1)?'checked':'';?> value="1" /><label class="mt-1" for="isDefault-1"></label> 是</label> + <label><input type="radio" class="ipt wst-radio" id="isDefault-0" name="isDefault" <?=($data['isDefault']==0)?'checked':'';?> value="0" /><label class="mt-1" for="isDefault-0"></label> 否</label> + </div> + + </td> + </tr> + + </table> + <div class="addr-btn-box"> + <input type="hidden" name="id" id="addressId" class="ipt" value="{$data['addressId']}" /> + <button type="submit" class="wst-sec-but u-btn">提交</button> + <button type="button" onclick="javascript:history.go(-1)" class="wst-sec-but u-btn">返回</button> + </div> +</form> +<style> +.addr-btn-box{ + margin-left:10%; +} +</style> +<script> +$(function(){ + //默认选中下拉框 + if($('#addressId').val()>0){ + var areaIdPath = "{$data['areaIdPath']}".split("_"); + $('#area_0').val(areaIdPath[0]); + var aopts = {id:'area_0',val:areaIdPath[0],childIds:areaIdPath,className:'j-areas'} + WST.ITSetAreas(aopts); + } + userAddrEditInit(); +}) +</script> +{/block} +{block name="js"} + <script type='text/javascript' src='__STYLE__/users/useraddress/useraddress.js?v={$v}'></script> + <script type="text/javascript" src="__STATIC__/plugins/validator/jquery.validator.min.js?v={$v}"></script> +{/block} + + +<script> +</script> + diff --git a/hyhproject/home2/view/default/users/useraddress/list.html b/hyhproject/home2/view/default/users/useraddress/list.html new file mode 100755 index 0000000..d2760d5 --- /dev/null +++ b/hyhproject/home2/view/default/users/useraddress/list.html @@ -0,0 +1,64 @@ +{extend name="default/users/base" /} +{block name="title"}首页-买家中心{__block__}{/block} +{block name="css"} +{/block} +{block name="content"} + <div class="wst-user-head"><span>管理地址</span></div> + <input type="button" value="新增收货地址" class="wst-sec-but u-btn addr-btn" onclick="location.href=WST.U('home/useraddress/edit')" /> + <label>你已经创建<span class="g g1">0</span>个收货地址</label> + <script id="address" type="text/html"> + {{# for(var i = 0, len = d.length; i < len; i++){ }} + <table class='wst-addr' > + <tr> + <td>{{d[i].userName}}—{{d[i].areaName1}}</td> + <td> + &nbsp;&nbsp;&nbsp;&nbsp; + {{# if(d[i].isDefault==1) { }} + <p class="default">默认地址</p> + {{# } }} + <a href="javascript:delAddress({{ d[i].addressId }},this)" class='del'>X</a> + </td> + </tr> + + + <tr><td class="addr-title">收货人:</td> + <td>{{d[i].userName}}</td> + </tr> + <tr><td class="addr-title">所在地区:</td> + <td>{{d[i].areaName}}</td> + </tr> + <tr><td class="addr-title">地址:</td> + <td>{{d[i].userAddress}}</td> + </tr> + <tr><td class="addr-title">联系电话:</td> + <td>{{d[i].userPhone}}</td> + </tr> + + <tr> + <td>&nbsp;</td> + <td class='edit'> + <a href="javascript:editAddress({{ d[i].addressId }})">编辑</a> + {{# if(d[i].isDefault!=1) { }} + <a href="javascript:setDefault({{ d[i].addressId }})">设为默认</a> + {{# } }} + <div class="wst-clear"></div> + </td> + </tr> + </table> + {{# } }} + </script> + <div id="address_box" class="address_box"> + + </div> + <input type="button" value="新增收货地址" class="wst-sec-but u-btn addr-btn" onclick="location.href=WST.U('home/useraddress/edit')" /> + <label>你已经创建<span class="g g1">0</span>个收货地址</span></label> + +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/useraddress/useraddress.js?v={$v}'></script> +<script> +$(function(){ + listQuery(); +}); +</script> +{/block} diff --git a/hyhproject/home2/view/default/users/useraddress/useraddress.js b/hyhproject/home2/view/default/users/useraddress/useraddress.js new file mode 100755 index 0000000..99dff09 --- /dev/null +++ b/hyhproject/home2/view/default/users/useraddress/useraddress.js @@ -0,0 +1,116 @@ +function userAddrEditInit(){ + /* 表单验证 */ + $('#useraddressForm').validator({ + fields: { + userAddress: { + rule:"required;length[~60, true]", + msg:{required:"请输入您的收货地址"}, + tip:"请输入您的收货地址", + ok:"", + }, + userName: { + rule:"required;length[~12, true]", + msg:{required:"请输入您的名称"}, + tip:"请输入您的名称", + ok:"", + }, + userPhone: { + rule:"required;length[~50, true]", + msg:{required:"联系电话"}, + tip:"请输入您的联系电话", + ok:"", + }, + isDefault: { + rule:"checked;", + msg:{checked:"至少选择一项"}, + tip:"是否作为默认地址", + ok:"", + } + }, + valid: function(form){ + var isNoSelected = false; + $('.j-areas').each(function(){ + isSelected = true; + if($(this).val()==''){ + isNoSelected = true; + return; + } + }); + if(isNoSelected){ + WST.msg('请选择完整区域!',{icon:2}); + return; + } + var params = WST.getParams('.ipt'); + params.areaId = WST.ITGetAreaVal('j-areas'); + var loading = WST.msg('正在提交数据,请稍后...', {icon: 16,time:60000}); + $.post(WST.U('home/useraddress/'+((params.addressId==0)?"add":"toEdit")),params,function(data,textStatus){ + layer.close(loading); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg(json.msg,{icon:1}); + location.href=WST.U('home/useraddress/index'); + }else{ + WST.msg(json.msg,{icon:2}); + } + }); + + } + + }); + } +function listQuery(){ + $.post(WST.U('Home/Useraddress/listQuery'),'',function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1 && json.data){ + json = json.data; + var count = json.length;//已添加的记录数 + $('.g1').html(count); + var gettpl = document.getElementById('address').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#address_box').html(html); + }); + }else{ + $('#address_box').empty(); + } +}); +} + +function editAddress(id){ + location.href=WST.U('home/useraddress/edit','id='+id); +} + +function delAddress(id,t){ + WST.confirm({content:"您确定要删除该地址吗?",yes:function(tips){ + var ll = layer.load('数据处理中,请稍候...'); + $.post(WST.U('Home/UserAddress/del'),{id:id},function(data,textStatus){ + layer.close(ll); + layer.close(tips); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!', {icon: 1}, function(){ + listQuery(); + }); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); + }}); + +} +function setDefault(id){ + WST.confirm({content:"您确定设置为默认地址吗?",yes:function(tips){ + var ll = layer.load('数据处理中,请稍候...'); + $.post(WST.U('Home/UserAddress/setDefault'),{id:id},function(data,textStatus){ + layer.close(ll); + layer.close(tips); + var json = WST.toJson(data); + if(json.status=='1'){ + WST.msg('操作成功!', {icon: 1}, function(){ + listQuery(); + }); + }else{ + WST.msg('操作失败!', {icon: 5}); + } + }); + }}); +} diff --git a/hyhproject/home2/view/default/users/userscores/list.html b/hyhproject/home2/view/default/users/userscores/list.html new file mode 100755 index 0000000..e1cce7d --- /dev/null +++ b/hyhproject/home2/view/default/users/userscores/list.html @@ -0,0 +1,57 @@ +{extend name="default/users/base" /} +{block name="title"}积分管理-买家中心{__block__}{/block} +{block name="content"} +<div class='score-head'> + <div class='user-logo'><img height='100' width='100'src='__IMGURL__{:WSTUserPhoto(session('WST_USER.userPhoto'))}'></div> + <div class='user-info'> + <div class='userName'>{:session('WST_USER.loginName')}</div> + <div class='userScore'>可用积分:<font color='red'>{$object['userScore']}</font>个</div> + </div> +</div> +<div class='wst-user-content'> + <div id='tab' class="wst-tab-box"> + <ul class="wst-tab-nav"> + <li>积分明细</li> + <li>积分收入</li> + <li>积分支出</li> + </ul> + <table class='wst-list' style="font-size:13px;"> + <thead> + <tr> + <th width='*'>来源/用途</th> + <th width='120'>积分变化</th> + <th width='160'>日期</th> + <th width='260'>备注</th> + </tr> + </thead> + <script id="tblist" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <tr> + <td width='160'>{{d[i].dataSrc}}</td> + <td width='120'> + {{# if(d[i].scoreType==1){ }} + <span class="score-add">+ {{ d[i].score }}</span> + {{# }else{ }} + <span class='score-reduce'> - {{ d[i].score }}</span> + {{# } }} + </td> + <td width='160'>{{ d[i].createTime }}</td> + <td width='*'>{{ d[i].dataRemarks }}</td> + </tr> + {{# } }} + </script> + <tbody id="page-list"></tbody> + <tfoot> + <tr> + <td colspan='4' align="center" style='padding:5px 0px 5px 0px'> + <div id="pager"></div> + </td> + </tr> + </tfoot> + </table> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__STYLE__/users/userscores/userscores.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/home2/view/default/users/userscores/userscores.js b/hyhproject/home2/view/default/users/userscores/userscores.js new file mode 100755 index 0000000..6182eb4 --- /dev/null +++ b/hyhproject/home2/view/default/users/userscores/userscores.js @@ -0,0 +1,42 @@ +$(function () { + $('#tab').TabPanel({tab:0,callback:function(tab){ + switch(tab){ + case 0:pageQuery(0,-1);break; + case 1:pageQuery(0,1);break; + case 2:pageQuery(0,0);break; + } + }}) +}); +function pageQuery(p,type){ + var tips = WST.load({msg:'正在获取数据,请稍后...'}); + var params = {}; + params.page = p; + params.type = type; + $.post(WST.U('home/userscores/pageQuery'),params,function(data,textStatus){ + layer.close(tips); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + var gettpl = document.getElementById('tblist').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#page-list').html(html); + }); + if(json.TotalPage>1){ + laypage({ + cont: 'pager', + pages:json.TotalPage, + curr: json.CurrentPage, + skin: '#e23e3d', + groups: 3, + jump: function(e, first){ + if(!first){ + pageQuery(e.curr,type); + } + } + }); + }else{ + $('#pager').empty(); + } + } + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/common/function.php b/hyhproject/mobile2/common/function.php new file mode 100755 index 0000000..36042f2 --- /dev/null +++ b/hyhproject/mobile2/common/function.php @@ -0,0 +1,15 @@ +<?php +use think\Db; +/** + * ============================================================================ + */ +/** + * 获取购物车数量 + */ +function WSTCartNum(){ + $userId = session('WST_USER.userId'); + $cartNum = Db::name('carts')->where(['userId'=>$userId])->field('cartId')->select(); + $count = count($cartNum); + return $count; +} + diff --git a/hyhproject/mobile2/conf/config.php b/hyhproject/mobile2/conf/config.php new file mode 100755 index 0000000..3d26a52 --- /dev/null +++ b/hyhproject/mobile2/conf/config.php @@ -0,0 +1,14 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + +]; diff --git a/hyhproject/mobile2/controller/Alipays.php b/hyhproject/mobile2/controller/Alipays.php new file mode 100755 index 0000000..33ade57 --- /dev/null +++ b/hyhproject/mobile2/controller/Alipays.php @@ -0,0 +1,247 @@ +<?php +namespace wstmart\mobile\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\mobile\model\Orders as OM; +use wstmart\common\model\LogPayParams as PM; +use wstmart\common\model\ChargeItems as CM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 阿里支付控制器 + */ +class Alipays extends Base{ + + /** + * 初始化 + */ + private $alipayConfig; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import ( 'alipay.Corefunction' ); + Loader::import ( 'alipay.Md5function' ); + Loader::import ( 'alipay.AlipayNotify' ); + Loader::import ( 'alipay.AlipaySubmit' ); + $m = new M(); + $payment = $m->getPayment("alipays"); + $this->alipayConfig = array( + 'partner' =>$payment['parterID'], //这里是你在成功申请支付宝接口后获取到的PID; + 'key'=>$payment['parterKey'],//这里是你在成功申请支付宝接口后获取到的Key + 'seller_email'=>$payment['payAccount'], + 'sign_type'=>strtoupper('MD5'), + 'input_charset'=> strtolower('utf-8'), + 'cacert'=>'', + 'transport'=> 'http' + ); + } + + /** + * 支付宝支付跳转方法 + */ + public function toAliPay(){ + + $payObj = input("payObj/s"); + + $call_back_url = ""; + $notify_url = ""; + $subject = ""; + $total_fee = 0; + $transId = 0; + $userId = 0; + $payParams = array(); + if($payObj=="recharge"){//充值 + $itemId = (int)input("itemId/d"); + $orderAmount = 0; + if($itemId>0){ + $cm = new CM(); + $item = $cm->getItemMoney($itemId); + $total_fee = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $total_fee = (int)input("needPay/d"); + } + + $shopId = (int)session('WST_USER.shopId'); + $targetType = ($shopId>0)?1:0; + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = $shopId; + } + $userId = $targetId; + $out_trade_no = WSTOrderNo(); + $transId = $out_trade_no; + $payParams["targetId"] = $targetId; + $payParams["targetType"] = $targetType; + $payParams["itemId"] = $itemId; + $payParams["payObj"] = $payObj; + + $call_back_url = url("mobile/users/index","",true,true); + $notify_url = url("mobile/alipays/aliNotify","",true,true); + $subject = '钱包充值'; + }else{ + $orderNo = input('orderNo'); + $isBatch = (int)input('isBatch'); + $userId = (int)session('WST_USER.userId'); + $m = new OM(); + $obj = array(); + $obj["userId"] = $userId; + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $rs = $m->getOrderPayInfo($obj); + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $m = new M(); + $om = new OM(); + $data = $om->checkOrderPay($obj); + if($data["status"]==-1){ + echo "<span style='font-size:40px;'>您的订单已支付,不要重复支付!</span>"; + return; + }else if($data["status"]==-2){ + echo "<span style='font-size:40px;'>您的订单因商品库存不足,不能支付!</span>"; + return; + } + } + $order = $om->getPayOrders($obj); + $total_fee = $order["needPay"]; + $payRand = $order["payRand"]; + $out_trade_no = $obj["orderNo"]."a".$payRand; + $transId = $obj["orderNo"]; + + $payParams["userId"] = $userId; + $payParams["isBatch"] = $isBatch; + $payParams["orderNo"] = $orderNo; + + $call_back_url = url("mobile/orders/index","",true,true); + $notify_url = url("mobile/alipays/aliNotify","",true,true); + $subject = '支付购买商品费用'; + } + + $format = "xml"; + $v = "2.0"; + $req_id = date('Ymdhis'); + $merchant_url = ""; + $seller_email = $this->alipayConfig['seller_email']; + + $req_data = '<direct_trade_create_req><notify_url>' . $notify_url . '</notify_url><call_back_url>' . $call_back_url . '</call_back_url><seller_account_name>' . $seller_email . '</seller_account_name><out_trade_no>' . $out_trade_no . '</out_trade_no><subject>' . $subject . '</subject><total_fee>' . $total_fee . '</total_fee><merchant_url>' . $merchant_url . '</merchant_url></direct_trade_create_req>'; + + //构造要请求的参数数组,无需改动 + $para_token = array( + "service" => "alipay.wap.trade.create.direct", + "partner" => trim($this->alipayConfig['partner']), + "sec_id" => trim($this->alipayConfig['sign_type']), + "format" => $format, + "v" => $v, + "req_id" => $req_id, + "req_data" => $req_data, + "_input_charset" => trim(strtolower($this->alipayConfig['input_charset'])) + ); + //建立请求 + $alipaySubmit = new \AlipaySubmit($this->alipayConfig); + $html_text = $alipaySubmit->buildRequestHttp($para_token); + //URLDECODE返回的信息 + $html_text = urldecode($html_text); + //解析远程模拟提交后返回的信息 + $para_html_text = $alipaySubmit->parseResponse($html_text); + //获取request_token + $request_token = $para_html_text['request_token']; + //**************************根据授权码token调用交易接口alipay.wap.auth.authAndExecute************************** + //业务详细 + $req_data = '<auth_and_execute_req><request_token>' . $request_token . '</request_token></auth_and_execute_req>'; + //必填 + + //构造要请求的参数数组,无需改动 + $parameter = array( + "service" => "alipay.wap.auth.authAndExecute", + "partner" => trim($this->alipayConfig['partner']), + "sec_id" => trim($this->alipayConfig['sign_type']), + "format" => $format, + "v" => $v, + "req_id" => $req_id, + "req_data" => $req_data, + "_input_charset" => trim(strtolower($this->alipayConfig['input_charset'])) + ); + + $data = array(); + $data["userId"] = $userId; + $data["transId"] = $transId; + $data["paramsVa"] = json_encode($payParams); + $data["payFrom"] = 'alipays'; + $m = new PM(); + $m->addPayLog($data); + + //建立请求 + $alipaySubmit = new \AlipaySubmit($this->alipayConfig); + $html_text = $alipaySubmit->buildRequestForm($parameter, 'get', ''); + echo $html_text; + } + + /** + * 服务器异步通知页面方法 + * + */ + function aliNotify() { + $om = new OM(); + // 计算得出通知验证结果 + $alipayNotify = new \AlipayNotify ( $this->alipayConfig ); + $verify_result = $alipayNotify->verifyNotify (); + + if ($verify_result) { + $notify_data = $_POST['notify_data']; + // 获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 + // 解析notify_data + // 注意:该功能PHP5环境及以上支持,需开通curl、SSL等PHP配置环境。建议本地调试时使用PHP开发软件 + $doc = new \DOMDocument (); + $doc->loadXML ( $notify_data ); + if (! empty ( $doc->getElementsByTagName ( "notify" )->item ( 0 )->nodeValue )) { + // 交易号 + $trade_no = $doc->getElementsByTagName ( "trade_no" )->item ( 0 )->nodeValue; + // 商户订单号 + $out_trade_no = $doc->getElementsByTagName ( "out_trade_no" )->item ( 0 )->nodeValue; + + $total_fee = $doc->getElementsByTagName( "total_fee" )->item(0)->nodeValue; + // 支付宝交易号 + $trade_no = $doc->getElementsByTagName ( "trade_no" )->item ( 0 )->nodeValue; + // 交易状态 + $trade_status = $doc->getElementsByTagName ( "trade_status" )->item ( 0 )->nodeValue; + if ($trade_status == 'TRADE_FINISHED' OR $trade_status == 'TRADE_SUCCESS') { + $obj["trade_no"] = $trade_no; + $tradeNo = explode("a",$out_trade_no); + + $obj["out_trade_no"] = $tradeNo[0]; + $obj["payFrom"] = 'alipays'; + $obj["total_fee"] = $total_fee; + + $m = new PM(); + $payParams = $m->getPayLog(["transId"=>$obj["out_trade_no"]]); + if(isSet($payParams["payObj"]) && $payParams["payObj"]=='recharge'){ + + $obj["targetId"] = $payParams["targetId"]; + $obj["targetType"] = $payParams["targetType"]; + $obj["itemId"] = $payParams["itemId"];; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //$payFrom = $om->getOrderPayFrom($tradeNo[0]); + $obj["userId"] = $payParams["userId"]; + $obj["isBatch"] = $payParams["isBatch"]; + //支付成功业务逻辑 + $rs = $om->complatePay($obj); + } + + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + } + //echo "success"; // 请不要修改或删除 + } + } else { + // 验证失败 + echo "fail"; + } + } + +} diff --git a/hyhproject/mobile2/controller/Areas.php b/hyhproject/mobile2/controller/Areas.php new file mode 100755 index 0000000..0d14908 --- /dev/null +++ b/hyhproject/mobile2/controller/Areas.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Areas as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Areas extends Base{ + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + return WSTReturn('', 1,$rs); + } +} diff --git a/hyhproject/mobile2/controller/Base.php b/hyhproject/mobile2/controller/Base.php new file mode 100755 index 0000000..681b62c --- /dev/null +++ b/hyhproject/mobile2/controller/Base.php @@ -0,0 +1,71 @@ +<?php +namespace wstmart\mobile\controller; +use think\Controller; +/** + * ============================================================================ + * 基础控制器 + */ +class Base extends Controller { + public function __construct(){ + parent::__construct(); + WSTConf('CONF',WSTConfig()); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPcStyleId')); + + if(WSTConf('CONF.seoMallSwitch')==0){ + $this->redirect('mobile/switchs/index'); + exit; + } + } + // 权限验证方法 + protected function checkAuth(){ + $USER = session('WST_USER'); + if(empty($USER)){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $this->redirect('mobile/users/login'); + exit; + } + } + } + + // 店铺权限验证方法 + protected function checkShopAuth($opt){ + $shopMenus = WSTShopOrderMenus(); + if($opt=="list"){ + if(count($shopMenus)==0){ + session('moshoporder','对不起,您无权进行该操作'); + $this->redirect('mobile/error/message',['code'=>'moshoporder']); + exit; + } + }else{ + if(!array_key_exists($opt,$shopMenus)){ + if(request()->isAjax()){ + die('{"status":-1,"msg":"您无权进行该操作"}'); + }else{ + session('moshoporder','对不起,您无权进行该操作'); + $this->redirect('mobile/error/message',['code'=>'moshoporder']); + exit; + } + } + } + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wstmobileStyle')?WSTConf('CONF.wstmobileStyle'):'default'; + $replace['__MOBILE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/mobile/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + + } + /** + * 上传图片 + */ + public function uploadPic(){ + return WSTUploadPic(0); + } + /** + * 获取验证码 + */ + public function getVerify(){ + WSTVerify(); + } +} \ No newline at end of file diff --git a/hyhproject/mobile2/controller/Brands.php b/hyhproject/mobile2/controller/Brands.php new file mode 100755 index 0000000..f87b3d4 --- /dev/null +++ b/hyhproject/mobile2/controller/Brands.php @@ -0,0 +1,26 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Brands as M; +/** + * ============================================================================ + * 品牌控制器 + */ +class Brands extends Base{ + /** + * 主页 + */ + public function index(){ + return $this->fetch('brands'); + } + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['brandImg'] = WSTImg($v['brandImg'],2); + } + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Carts.php b/hyhproject/mobile2/controller/Carts.php new file mode 100755 index 0000000..51f623d --- /dev/null +++ b/hyhproject/mobile2/controller/Carts.php @@ -0,0 +1,152 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Carts as M; +use wstmart\common\model\UserAddress; +use wstmart\common\model\Payments; +/** + * ============================================================================ + * 购物车控制器 + */ +class Carts extends Base{ + + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 批量修改购物车状态 + */ + public function batchChangeCartGoods(){ + $m = new M(); + return $m->batchChangeCartGoods(); + } + /** + * 查看购物车列表 + */ + public function index(){ + $m = new M(); + $carts = $m->getCarts(false); + $this->assign('carts',$carts); + return $this->fetch('carts'); + } + /** + * 加入购物车 + */ + public function addCart(){ + $m = new M(); + $rs = $m->addCart(); + $rs['cartNum'] = WSTCartNum(); + return $rs; + } + /** + * 修改购物车商品状态 + */ + public function changeCartGoods(){ + $m = new M(); + $rs = $m->changeCartGoods(); + return $rs; + } + /** + * 删除购物车里的商品 + */ + public function delCart(){ + $m = new M(); + $rs= $m->delCart(); + return $rs; + } + /** + * 计算运费、惠宝和总商品价格 + */ + public function getCartMoney(){ + $m = new M(); + $data = $m->getCartMoney(); + return $data; + } + /** + * 计算运费、惠宝和总商品价格/虚拟商品 + */ + public function getQuickCartMoney(){ + $m = new M(); + $data = $m->getQuickCartMoney(); + return $data; + } + /** + * 跳去购物车结算页面 + */ + public function settlement(){ + $m = new M(); + //获取一个用户地址 + $addressId = (int)input('addressId'); + $ua = new UserAddress(); + if($addressId>0){ + $userAddress = $ua->getById($addressId); + }else{ + $userAddress = $ua->getDefaultAddress(); + } + $this->assign('userAddress',$userAddress); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('2'); + $areaId2 = isset($userAddress['areaId2']) ? $userAddress['areaId2'] : 0; + //dump($payments); + //获取已选的购物车商品 + $carts = $m->getCarts(true, 0, $areaId2); + + //hook("mobileControllerCartsSettlement",["carts"=>$carts,"payments"=>&$payments]); + //ect整合相关优惠还有判断不能和在线支付商品一块 + // hook("ectIntegration",["carts"=>&$carts,'isSettlement'=>false,'uId'=>(int)session('WST_USER.userId')]); + $this->assign('payments',$payments); + //获取用户惠宝 + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + //计算可用惠宝和金额 + $goodsTotalMoney = (int)(($carts['goodsTotalMoney'] - $carts['promotionMoney'] - $carts['allShippingMoney']) * HuiScale());//$carts['goodsTotalMoney']; 惠宝最多可抵用20% mark 20170907 + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + + $useOrderScore =0; + $useOrderMoney = 0; + if($user['userScore']>$goodsTotalScore){ + $useOrderScore = $goodsTotalScore; + $useOrderMoney = $goodsTotalMoney; + }else{ + $useOrderScore = $user['userScore']; + $useOrderMoney = WSTScoreToMoney($useOrderScore); + } + $this->assign('userOrderScore',$useOrderScore); + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + return $this->fetch('settlement'); + } + /** + * 跳去虚拟商品购物车结算页面 + */ + public function quickSettlement(){ + $m = new M(); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('2'); + $this->assign('payments',$payments); + //获取用户惠宝 + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + //获取已选的购物车商品 + $carts = $m->getQuickCarts(); + //计算可用惠宝和金额 + $goodsTotalMoney = (int)($carts['goodsTotalMoney'] * HuiScale());//$carts['goodsTotalMoney']; 惠宝最多可抵用20% mark 20170907 + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + + $useOrderScore =0; + $useOrderMoney = 0; + if($user['userScore']>$goodsTotalScore){ + $useOrderScore = $goodsTotalScore; + $useOrderMoney = $goodsTotalMoney; + }else{ + $useOrderScore = $user['userScore']; + $useOrderMoney = WSTScoreToMoney($useOrderScore); + } + $this->assign('userOrderScore',$useOrderScore); + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + return $this->fetch('settlement_quick'); + } +} diff --git a/hyhproject/mobile2/controller/Cashconfigs.php b/hyhproject/mobile2/controller/Cashconfigs.php new file mode 100755 index 0000000..870b605 --- /dev/null +++ b/hyhproject/mobile2/controller/Cashconfigs.php @@ -0,0 +1,54 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 提现账号控制器 + */ +class Cashconfigs extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看提现账号 + */ + public function index(){ + $this->assign('area',model('areas')->listQuery(0)); + $this->assign('banks',model('banks')->listQuery(0)); + return $this->fetch('users/cashconfigs/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashConfigs')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + /** + * 获取记录 + */ + public function getById(){ + $id = (int)input('id'); + return model('CashConfigs')->getById($id); + } + /** + * 新增 + */ + public function add(){ + return model('CashConfigs')->add(); + } + /** + * 编辑 + */ + public function edit(){ + return model('CashConfigs')->edit(); + } + /** + * 删除 + */ + public function del(){ + return model('CashConfigs')->del(); + } +} diff --git a/hyhproject/mobile2/controller/Cashdraws.php b/hyhproject/mobile2/controller/Cashdraws.php new file mode 100755 index 0000000..3e995bd --- /dev/null +++ b/hyhproject/mobile2/controller/Cashdraws.php @@ -0,0 +1,34 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 提现记录控制器 + */ +class Cashdraws extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看用户提现记录 + */ + public function index(){ + return $this->fetch('users/cashdraws/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashDraws')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + + /** + * 提现 + */ + public function drawMoney(){ + return model('CashDraws')->drawMoney(); + } +} diff --git a/hyhproject/mobile2/controller/Demo.php b/hyhproject/mobile2/controller/Demo.php new file mode 100755 index 0000000..925cc33 --- /dev/null +++ b/hyhproject/mobile2/controller/Demo.php @@ -0,0 +1,75 @@ +<?php +namespace wstmart\mobile\controller; +//use wstmart\common\model\Demo as M; +//use think\Loader; +//use think\Db; +//require_once(ROOT_PATH.'../php/lib/XS.php'); +/** + * ============================================================================ + * 地区控制器 + */ +class Demo extends Base{ + /** + * 列表查询 + */ + public function index(){ + //Loader::import ( 'php.lib.XS' ); + $xs = new \XS('goods'); + //$doc = new \XSDocument; // 自动使用 $prefix/sdk/php/app/demo.ini 作项目配置文件 + $data = array( + 'goodsId' => 6666667, // 此字段为主键,是进行文档替换的唯一标识 + 'goodsName' => '测鞋子的标题' + ); + //$doc->setFields($data); + // $index = $xs->index; // 获取 索引对象 + // //$index->del(array('6666666', '6666667')); // 同时删除主键值为 123, 789, 456 的记录 + // //添加到索引数据库中 + // $index->add($doc); + + + // // 创建文档对象 + // $xs = new \XS('goods'); + + // $info = $xs->search->search('苹果'); + // //echo $info->goodsName; + // //dump($info); + // foreach ($info as $key => $v) { + // $data[$key]['goodsId'] = $v['goodsId']; + // $data[$key]['goodsName'] = $v['goodsName']; + // } + //dump($data); + } + public function search(){ + + //'select * form hyh_ads a where a.adPositionId in (select positionId from hyh_ad_positions where positionCode='mo-ads-index' ) ' + //$ads_list = Db::name('ads')->where(['adPositionId'=>291,'dataFlag'=>1])->order('adSort asc')->select(); + //dump($ads_list); + + //$m = new Demo(); + //$brand_list = $m->getBrandList(); + //dump($brand_list); + + + $keyword = input('keyword'); + $shopId = (int)input('shopId'); + //$xs = new \XS('goods'); + $search = 'goodsName:'.$keyword; + if($shopId){ + $search.=' goodsId:'.$shopId; + } + $info = $xs->search->getField('goodsId')->search($search); + //$info = $xs->search->search($keyword); + foreach ($info as $key => $v) {//把返回的数据转换为数组 + $data[$key]['goodsId'] = $v['goodsId']; + $data[$key]['goodsName'] = $v['goodsName']; + } + if($data){ + exit(jsonReturn('调用成功',1,$data)); + } + exit(jsonReturn('调用失败',-1)); + } + // public function getBrandList(){ + // return Db::name('brands')->where('dataFlag=1')->select(); + + // } +} diff --git a/hyhproject/mobile2/controller/Error.php b/hyhproject/mobile2/controller/Error.php new file mode 100755 index 0000000..e65d0a6 --- /dev/null +++ b/hyhproject/mobile2/controller/Error.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 错误处理控制器 + */ +class Error extends Base{ + public function index(){ + header("HTTP/1.0 404 Not Found"); + return $this->fetch('error_sys'); + } + public function message(){ + $code = input('code'); + if($code !== null && session($code)!=''){ + $this->assign('message',session($code)); + }else{ + $this->assign('message','操作错误,请联系商城管理员'); + } + return $this->fetch('error_lost'); + } +} diff --git a/hyhproject/mobile2/controller/Favorites.php b/hyhproject/mobile2/controller/Favorites.php new file mode 100755 index 0000000..6232a58 --- /dev/null +++ b/hyhproject/mobile2/controller/Favorites.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Favorites as M; +/** + * ============================================================================ + * 收藏控制器 + */ +class Favorites extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 关注的商品 + */ + public function goods(){ + return $this->fetch('users/favorites/list_goods'); + } + /** + * 关注的店铺 + */ + public function shops(){ + return $this->fetch('users/favorites/list_shops'); + } + /** + * 关注的商品列表 + */ + public function listGoodsQuery(){ + $m = new M(); + $data = $m->listGoodsQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + return WSTReturn("", 1,$data); + } + /** + * 关注的店铺列表 + */ + public function listShopQuery(){ + $m = new M(); + $data = $m->listShopQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['shopImg'] = WSTImg($v['shopImg'],3); + if(!empty($v['goods'])){ + foreach($v['goods'] as $k1=>$v1){ + $v[$k1]['goodsImg'] = WSTImg($v1['goodsImg'],3); + } + } + } + return WSTReturn("", 1,$data); + } + /** + * 取消关注 + */ + public function cancel(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + /** + * 增加关注 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Goods.php b/hyhproject/mobile2/controller/Goods.php new file mode 100755 index 0000000..0b9dc17 --- /dev/null +++ b/hyhproject/mobile2/controller/Goods.php @@ -0,0 +1,108 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\GoodsCats; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + /** + * 商品主页 + */ + public function detail(){ + $m = model('goods'); + $goods = $m->getBySale(input('goodsId/d')); + $key=input('key'); + hook('mobileControllerGoodsIndex',['getParams'=>input()]); + + + // 找不到商品记录 + if(empty($goods))return $this->fetch('error_lost'); + //判断是否药品 + $goods_cat=strpos($goods['goodsCatIdPath'],'389'); + if($goods_cat!==false && $key==''){ + return $this->fetch("error_lost"); + } + //记录用户浏览商品 + $userId = (int)session('WST_USER.userId'); + if($userId){ + $data['userId']=$userId; + $data['goodsId']=$goods['goodsId']; + $data['path']='2'; + $data['create_time']=time(); + $result=db('page_view')->insert($data); + } + $goods['goodsDesc']=htmlspecialchars_decode($goods['goodsDesc']); + $rule = '/<img src=".*?\/(upload.*?)"/'; + preg_match_all($rule, $goods['goodsDesc'], $images); + foreach($images[0] as $k=>$v){ + + $goods['goodsDesc'] = str_replace('/'.$images[1][$k], '__IMGURL__/'.WSTConf("CONF.goodsLogo") . "\" data-echo=\"__IMGURL__/".WSTImg($images[1][$k],2), $goods['goodsDesc']); + } + if(!empty($goods)){ + $history = cookie("wx_history_goods"); + $history = is_array($history)?$history:[]; + array_unshift($history, (string)$goods['goodsId']); + $history = array_values(array_unique($history)); + if(!empty($history)){ + cookie("wx_history_goods",$history,25920000); + } + } + $goods['consult'] = model('GoodsConsult')->firstQuery($goods['goodsId']); + $goods['appraises'] = model('GoodsAppraises')->getGoodsEachApprNum($goods['goodsId']); + hook('afterGetGoods',['params'=>&$goods]); + $goods['is_seckilling']=isset($goods['is_seckilling'])?$goods['is_seckilling']:0; + //hook('afterGetGoods',['params'=>&$goods]); + $this->assign("info", $goods); + return $this->fetch('goods_detail'); + } + /** + * 商品列表 + */ + public function lists(){ + $this->assign("keyword", input('keyword')); + $this->assign("catId", input('catId/d')); + $this->assign("brandId", input('brandId/d')); + return $this->fetch('goods_list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = model('goods'); + $gc = new GoodsCats(); + $catId = (int)input('catId'); + if($catId>0){ + $goodsCatIds = $gc->getParentIs($catId); + }else{ + $goodsCatIds = []; + } + $rs = $m->pageQuery($goodsCatIds); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + $rs['Rows'][$key]['praiseRate'] = ($v['totalScore']>0)?(sprintf("%.2f",$v['totalScore']/($v['totalUsers']*15))*100).'%':'100%'; + } + // `券`标签 + hook('afterQueryGoods',['page'=>&$rs]); + return $rs; + } + + /** + * 浏览历史页面 + */ + public function history(){ + return $this->fetch('users/history/list'); + } + /** + * 获取浏览历史 + */ + public function historyQuery(){ + $rs = model('goods')->historyQuery(); + if(!empty($rs)){ + foreach($rs['Rows'] as $k=>$v){ + $rs['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + } + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Goodsappraises.php b/hyhproject/mobile2/controller/Goodsappraises.php new file mode 100755 index 0000000..8eb074c --- /dev/null +++ b/hyhproject/mobile2/controller/Goodsappraises.php @@ -0,0 +1,44 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\GoodsAppraises as M; +/** + * ============================================================================ + * 评价控制器 + */ +class GoodsAppraises extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'getbyid'],// 只要访问only下的方法才才需要执行前置操作 + ]; + /** + * 根据商品id获取评论 + */ + public function getById(){ + $m = new M(); + $rs = $m->getById(); + return $rs; + } + /** + * 根据订单id,用户id,商品id获取评价 + */ + public function getAppr(){ + $m = model('GoodsAppraises'); + $rs = $m->getAppr(); + if(!empty($rs['data']['images'])){ + $imgs = explode(',',$rs['data']['images']); + foreach($imgs as $k=>$v){ + $imgs[$k] = WSTImg($v,1); + } + $rs['data']['images'] = $imgs; + } + return $rs; + } + /** + * 添加评价 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Goodscats.php b/hyhproject/mobile2/controller/Goodscats.php new file mode 100755 index 0000000..8d793a1 --- /dev/null +++ b/hyhproject/mobile2/controller/Goodscats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\mobile\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function index(){ + $m = new M(); + $goodsCatList = $m->getGoodsCats(); + $this->assign('list',$goodsCatList); + return $this->fetch('goods_category'); + } +} diff --git a/hyhproject/mobile2/controller/Goodsconsult.php b/hyhproject/mobile2/controller/Goodsconsult.php new file mode 100755 index 0000000..dd76c2e --- /dev/null +++ b/hyhproject/mobile2/controller/Goodsconsult.php @@ -0,0 +1,35 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\GoodsConsult as CG; +/** + * ============================================================================ + * 商品咨询控制器 + */ +class GoodsConsult extends Base{ + /** + * 商品咨询页 + */ + public function index(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/list'); + } + /** + * 根据商品id获取商品咨询 + */ + public function listQuery(){ + $m = new CG(); + return $m->listQuery(); + } + /** + * 发布商品咨询页 + */ + public function consult(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/consult'); + } + public function add(){ + $m = new CG(); + return $m->add(); + } + +} diff --git a/hyhproject/mobile2/controller/Index.php b/hyhproject/mobile2/controller/Index.php new file mode 100755 index 0000000..3119eb4 --- /dev/null +++ b/hyhproject/mobile2/controller/Index.php @@ -0,0 +1,83 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\mobile\model\Index as M; +/** + * ============================================================================ + * 默认控制器 + */ +class Index extends Base{ + /** + * 首页 + */ + public function index(){ + $m = new M(); + hook('mobileControllerIndexIndex',['getParams'=>input()]); + + //秒杀商品 + // $now_time = time(); //当前时间 + // if(is_int($now_time/7200)){ //双整点时间,如:10:00, 12:00 + // $start_time = $now_time; + // }else{ + // $start_time = floor($now_time/7200)*7200; //取得前一个双整点时间 + // } + // $end_time = $start_time+7200; //结束时间 + + $year = date("Y"); + $month = date("m"); + $day = date("d"); + $start_time = mktime(8,0,0,$month,$day,$year);//当天开始时间戳 + $end_time= mktime(20,0,0,$month,$day,$year);//当天结束时间戳 + $this->assign('start_time',$start_time); + $this->assign('end_time',$end_time); + + $news = $m->getSysMsg('msg'); + $this->assign('news',$news); + $ads['count'] = count(model("common/Tags")->listAds("mo-ads-index",99,86400)); + $ads['width'] = 'width:'.$ads['count'].'00%'; + $this->assign("ads", $ads); + return $this->fetch('index'); + } + /** + * 楼层 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + if(isset($rs['goods'])){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + /** + * 猜你喜欢 + * @return [type] [description] + */ + public function guess_like(){ + $m = new M(); + $rs = $m->guess_like(); + if(isset($rs['goods'])){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + /** + * 转换url + */ + public function transfor(){ + $data = input('param.'); + $url = $data['url']; + unset($data['url']); + echo Url($url,$data); + } + /** + * 跳去登录之前的地址 + */ + public function sessionAddress(){ + session('WST_MO_WlADDRESS',input('url')); + return WSTReturn("", 1); + } +} diff --git a/hyhproject/mobile2/controller/Invoices.php b/hyhproject/mobile2/controller/Invoices.php new file mode 100755 index 0000000..02c1df2 --- /dev/null +++ b/hyhproject/mobile2/controller/Invoices.php @@ -0,0 +1,31 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Invoices as M; +/** + * ============================================================================ + * 发票信息控制器 + */ +class Invoices extends Base{ + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(5);// 移动版只显示5条发票信息 + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } +} diff --git a/hyhproject/mobile2/controller/Juhui.php b/hyhproject/mobile2/controller/Juhui.php new file mode 100755 index 0000000..fc68f3b --- /dev/null +++ b/hyhproject/mobile2/controller/Juhui.php @@ -0,0 +1,15 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Juhui extends Base{ + /** + * 首页 + */ + public function index(){ + return $this->fetch('juhui'); + } + +} diff --git a/hyhproject/mobile2/controller/Logmoneys.php b/hyhproject/mobile2/controller/Logmoneys.php new file mode 100755 index 0000000..28823cb --- /dev/null +++ b/hyhproject/mobile2/controller/Logmoneys.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 资金流水控制器 + */ +class Logmoneys extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看用户资金流水 + */ + public function usermoneys(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $rs['isSetPayPwd'] = ($rs['payPwd']=='')?0:1; + unset($rs['payPwd']); + $rs['num'] = count(model('cashConfigs')->listQuery(0,$userId)); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/list'); + } + /** + * 资金流水 + */ + public function record(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/record'); + } + /** + * 列表 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('LogMoneys')->pageQuery("",$userId); + return WSTReturn("", 1,$data); + } + /** + * 验证支付密码 + */ + public function checkPayPwd(){ + return model('mobile/users')->checkPayPwd(); + } + + /** + * 充值[用户] + */ + public function toRecharge(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,'userMoney'); + $this->assign('rs',$rs); + $payments = model('common/payments')->recharePayments('2'); + $this->assign('payments',$payments); + $chargeItems = model('common/ChargeItems')->queryList(); + $this->assign('chargeItems',$chargeItems); + return $this->fetch('users/recharge/recharge'); + } +} diff --git a/hyhproject/mobile2/controller/Messages.php b/hyhproject/mobile2/controller/Messages.php new file mode 100755 index 0000000..c21c648 --- /dev/null +++ b/hyhproject/mobile2/controller/Messages.php @@ -0,0 +1,40 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Messages as M; +/** + * ============================================================================ + * 商城消息控制器 + */ +class Messages extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看商城消息 + */ + public function index(){ + return $this->fetch('users/messages/list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 获取列表详情 + */ + public function getById(){ + $m = new M(); + return $m->getById(); + } + /** + * 删除地址 + */ + public function del(){ + $m = new M(); + return $m->batchDel(); + } +} diff --git a/hyhproject/mobile2/controller/News.php b/hyhproject/mobile2/controller/News.php new file mode 100755 index 0000000..9b53ed9 --- /dev/null +++ b/hyhproject/mobile2/controller/News.php @@ -0,0 +1,53 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\mobile\model\Articles as M; +/** + * ============================================================================ + * 新闻控制器 + */ +class News extends Base{ + /** + * 列表查询 + */ + public function view(){ + $m = new M(); + $data = $m->getChildInfos(); + $catId = $data['0']['catId']; + $articleId = (int)input('articleId'); + $this->assign('articleId',$articleId); + $this->assign('catInfo',$data); + $this->assign('catId',$catId); + return $this->fetch('articles/news_list'); + } + /** + * 获取商城快讯列表 + */ + public function getNewsList(){ + $m = new M(); + $data = $m->getArticles(); + foreach($data as $k=>$v){ + $data[$k]['articleContent'] = strip_tags(html_entity_decode($v['articleContent'])); + $data[$k]['createTime'] = date('Y-m-d',strtotime($data[$k]['createTime'])); + $data[$k]['coverImg'] = str_replace("_thumb.", ".", $data[$k]['coverImg']); + } + return $data; + } + /** + * 查看详情 + */ + public function getNews(){ + $m = new M(); + $data = $m->getNewsById(); + $data['articleContent']=htmlspecialchars_decode($data['articleContent']); + $data['createTime'] = date('Y-m-d',strtotime($data['createTime'])); + return $data; + } + /** + * 点赞 + */ + public function like(){ + $m = new M(); + $data = $m->like(); + return $data; + } +} diff --git a/hyhproject/mobile2/controller/Ordercomplains.php b/hyhproject/mobile2/controller/Ordercomplains.php new file mode 100755 index 0000000..70da4e8 --- /dev/null +++ b/hyhproject/mobile2/controller/Ordercomplains.php @@ -0,0 +1,55 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\OrderComplains as M; +/** + * ============================================================================ + * 投诉控制器 + */ +class orderComplains extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + public function complain(){ + $oId = (int)input('oId'); + $this->assign('oId',$oId); + return $this->fetch('users/orders/orders_complains'); + } + /** + * 保存订单投诉信息 + */ + public function saveComplain(){ + return model('OrderComplains')->saveComplain(); + } + /** + * 用户投诉列表 + */ + public function index(){ + return $this->fetch('users/orders/list_complains'); + } + + /** + * 获取用户投诉列表 + */ + public function complainByPage(){ + $m = model('OrderComplains'); + return $m->queryUserComplainByPage(); + + } + + /** + * 用户查投诉详情 + */ + public function getComplainDetail(){ + $rs = model('OrderComplains')->getComplainDetail(0); + $annex = $rs['complainAnnex']; + if($annex){ + foreach($annex as $k=>$v){ + $annex1[] = WSTImg($v,2); + } + $rs['complainAnnex'] = $annex1; + } + return $rs; + } + +} diff --git a/hyhproject/mobile2/controller/Orderrefunds.php b/hyhproject/mobile2/controller/Orderrefunds.php new file mode 100755 index 0000000..0cd5a81 --- /dev/null +++ b/hyhproject/mobile2/controller/Orderrefunds.php @@ -0,0 +1,25 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\OrderRefunds as M; +/** + * ============================================================================ + * 订单退款控制器 + */ +class Orderrefunds extends Base{ + /** + * 用户申请退款 + */ + public function refund(){ + $m = new M(); + $rs = $m->refund(); + return $rs; + } + /** + * 商家处理是否同意 + */ + public function shopRefund(){ + $m = new M(); + $rs = $m->shopRefund(); + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Orders.php b/hyhproject/mobile2/controller/Orders.php new file mode 100755 index 0000000..b4d58fa --- /dev/null +++ b/hyhproject/mobile2/controller/Orders.php @@ -0,0 +1,270 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Orders as M; +use wstmart\common\model\Payments; +/** + * ============================================================================ + * 订单控制器 + */ +class Orders extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /*********************************************** 用户操作订单 ************************************************************/ + /** + * 提醒发货 + */ + public function noticeDeliver(){ + $m = new M(); + return $m->noticeDeliver(); + } + /** + * 提交订单 + */ + public function submit(){ + $m = new M(); + $rs = $m->submit(2); + return $rs; + } + /** + * 提交虚拟订单 + */ + public function quickSubmit(){ + $m = new M(); + $rs = $m->quickSubmit(); + return $rs; + } + /** + * 在线支付方式 + */ + public function succeed(){ + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('2'); + $this->assign('payments',$payments); + $this->assign('orderNo',input("get.orderNo")); + $this->assign('isBatch',(int)input("get.isBatch/d",0)); + return $this->fetch("users/orders/orders_pay_list"); + } + /** + * 订单管理 + */ + public function index(){ + $type = input('param.type',''); + $this->assign('type',$type); + return $this->fetch("users/orders/orders_list"); + } + + /** + * 订单列表 + */ + public function getOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0,1: 待收货 + 2:待评价/已完成 + */ + $flag = -1; + $type = input('param.type'); + $status = []; + switch ($type) { + case 'waitPay': + $status=[-2]; + break; + case 'waitDeliver': + $status=[0]; + break; + case 'waitReceive': + $status=[1]; + break; + case 'waitAppraise': + $status=[2]; + $flag=0; + break; + case 'finish': + $status=[2]; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-5,-4,-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->userOrdersByPage($status,$flag); + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + return $rs; + } + + /** + * 订单详情 + */ + public function getDetail(){ + $m = new M(); + $rs = $m->getByView((int)input('id')); + $rs['status'] = WSTLangOrderStatus($rs['orderStatus']); + $rs['payInfo'] = WSTLangPayType($rs['payType']); + $rs['deliverInfo'] = WSTLangDeliverType($rs['deliverType']); + foreach($rs['goods'] as $k=>$v){ + $v['goodsImg'] = WSTImg($v['goodsImg'],3); + } + // 优惠券钩子 + hook('mobileDocumentOrderSummaryView',['rs'=>&$rs]); + // 满就送钩子 + hook('mobileDocumentOrderViewGoodsPromotion',['rs'=>&$rs]); + return $rs; + } + + /** + * 用户确认收货 + */ + public function receive(){ + $m = new M(); + $rs = $m->receive(); + return $rs; + } + + /** + * 用户-评价页 + */ + public function orderAppraise(){ + $m = model('Orders'); + $oId = (int)input('oId'); + //根据订单id获取 商品信息 + $data = $m->getOrderInfoAndAppr(); + $data['shopName']=model('shops')->getShopName($oId); + $this->assign('data',$data); + $this->assign('oId',$oId); + return $this->fetch('users/orders/orders_appraises'); + } + + /** + * 用户取消订单 + */ + public function cancellation(){ + $m = new M(); + $rs = $m->cancel(); + return $rs; + } + + /** + * 用户拒收订单 + */ + public function reject(){ + $m = new M(); + $rs = $m->reject(); + return $rs; + } + + /** + * 用户退款 + */ + public function getRefund(){ + $m = new M(); + return $m->getMoneyByOrder((int)input('id')); + } + + + + + /*********************************************** 商家操作订单 ************************************************************/ + + /** + * 商家-查看订单列表 + */ + public function sellerOrder(){ + $this->checkShopAuth("list"); + $type = input('param.type','all'); + $this->assign('type',$type); + $express = model('Express')->listQuery(); + $this->assign('express',$express); + return $this->fetch('users/sellerorders/orders_list'); + } + + /** + * 商家-订单列表 + */ + public function getSellerOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0: 待发货 + 1,2:待评价/已完成 + */ + $type = input('param.type'); + $this->checkShopAuth($type); + $status = []; + switch ($type) { + case 'waitPay': + $status=-2; + break; + case 'waitDeliver': + $status=0; + break; + case 'waitReceive': + $status=1; + break; + case 'waitDelivery': + $status=0; + break; + case 'finish': + $status=2; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-5,-4,-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->shopOrdersByPage($status); + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + return WSTReturn('操作成功',1,$rs); + } + + /** + * 商家发货 + */ + public function deliver(){ + $this->checkShopAuth("waitDeliver"); + $m = new M(); + $rs = $m->deliver(); + return $rs; + } + /** + * 商家修改订单价格 + */ + public function editOrderMoney(){ + $this->checkShopAuth("waitPay"); + $m = new M(); + $rs = $m->editOrderMoney(); + return $rs; + } + /** + * 商家-操作退款 + */ + public function toShopRefund(){ + $this->checkShopAuth("abnormal"); + return model('OrderRefunds')->getRefundMoneyByOrder((int)input('id')); + } + + +} diff --git a/hyhproject/mobile2/controller/Promotion.php b/hyhproject/mobile2/controller/Promotion.php new file mode 100755 index 0000000..7854c20 --- /dev/null +++ b/hyhproject/mobile2/controller/Promotion.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 默认控制器 + */ +class Promotion extends Base{ + /** + * 首页 + */ + public function index(){ + //return $this->fetch('rebate'); + } + public function rebate(){ + return $this->fetch('rebate'); + } + public function day_new(){ + return $this->fetch('day_new'); + } + public function bash(){ + return $this->fetch('bash'); + } + +} diff --git a/hyhproject/mobile2/controller/Shops.php b/hyhproject/mobile2/controller/Shops.php new file mode 100755 index 0000000..90b6fb9 --- /dev/null +++ b/hyhproject/mobile2/controller/Shops.php @@ -0,0 +1,151 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\GoodsCats; +use wstmart\mobile\model\Goods; +/** + * ============================================================================ + * 门店控制器 + */ +class Shops extends Base{ + /** + * 店铺街 + */ + public function shopStreet(){ + $gc = new GoodsCats(); + $goodsCats = $gc->listQuery(0); + $this->assign('goodscats',$goodsCats); + $this->assign("keyword", input('keyword')); + return $this->fetch('shop_street'); + } + /** + * 店铺首页 + */ + public function index(){ + $s = model('shops'); + $shopId = (int)input('shopId',1); + $data = $s->getShopSummary($shopId); + $this->assign('data',$data); + // 是否已关注 + $isFavor = model('favorites')->checkFavorite($shopId,1); + $this->assign('isFavor',$isFavor); + $this->assign("goodsName", input('goodsName')); + return $this->fetch('shop_index'); + } + /** + * 店铺详情 + */ + public function home(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d",1); + $data['shop'] = $s->getShopInfo($shopId); + hook("goShopAfterAddView",["shopId"=>$shopId,'path'=>3]); + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)) + $this->redirect('mobile/shops/selfShop'); + + $gcModel = model('ShopCats'); + $data['shopcats'] = $gcModel->getShopCats($shopId); + + $this->assign('shopId',$shopId);//店铺id + + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + // 是否已关注 + $isFavor = model('favorites')->checkFavorite($shopId,1); + $this->assign('isFavor',$isFavor); + $followNum = model('favorites')->followNum($shopId,1); + $this->assign('followNum',$followNum); + + $cart = model('carts')->getCartInfo(); + $this->assign('cart',$cart); + return $this->fetch('shop_home'); + } + /** + * 店铺商品列表 + */ + public function shopGoodsList(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d",1); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + $gcModel = model('ShopCats'); + $data['shopcats'] = $gcModel->getShopCats($shopId); + + $this->assign('shopId',$shopId);//店铺id + + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + return $this->fetch('shop_goods_list'); + } + /** + * 获取店铺商品 + */ + public function getShopGoods(){ + $shopId = (int)input('shopId',1); + $g = model('goods'); + $rs = $g->shopGoods($shopId); + foreach($rs['Rows'] as $k=>$v){ + $rs['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + return $rs; + } + + /** + * 自营店铺 + */ + public function selfShop(){ + $s = model('shops'); + $data['shop'] = $s->getShopInfo(1); + if(empty($data['shop']))return $this->fetch('error_lost'); + $this->assign('selfShop',1); + $data['shopcats'] = model('ShopCats')->getShopCats(1); + $this->assign('goodsName',urldecode(input("param.goodsName")));//搜索 + // 店长推荐 + $data['rec'] = $s->getRecGoods('rec'); + // 热销商品 + $data['hot'] = $s->getRecGoods('hot'); + $this->assign('data',$data); + // 是否已关注 + $isFavor = model('favorites')->checkFavorite(1,1); + $this->assign('isFavor',$isFavor); + $followNum = model('favorites')->followNum(1,1); + $this->assign('followNum',$followNum); + $this->assign("keyword", input('keyword')); + return $this->fetch('self_shop'); + } + public function getFloorData(){ + $s = model('shops'); + $rs = $s->getFloorData(); + if(isset($rs['goods'])){ + foreach($rs['goods'] as $k=>$v){ + $rs['goods'][$k]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + + /** + * 店铺街列表 + */ + public function pageQuery(){ + $m = model('shops'); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['shopImg'] = WSTImg($v['shopImg'],3); + } + return $rs; + } + +} diff --git a/hyhproject/mobile2/controller/Switchs.php b/hyhproject/mobile2/controller/Switchs.php new file mode 100755 index 0000000..834b89a --- /dev/null +++ b/hyhproject/mobile2/controller/Switchs.php @@ -0,0 +1,22 @@ +<?php +namespace wstmart\mobile\controller; +/** + * ============================================================================ + * 关闭提示处理控制器 + */ +use think\Controller; +class Switchs extends Controller{ + public function __construct(){ + parent::__construct(); + WSTConf('CONF',WSTConfig()); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPcStyleId')); + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wstmobileStyle')?WSTConf('CONF.wstmobileStyle'):'default'; + $replace['__MOBILE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/mobile/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + } + public function index(){ + return $this->fetch('error_switch'); + } +} diff --git a/hyhproject/mobile2/controller/Unionpays.php b/hyhproject/mobile2/controller/Unionpays.php new file mode 100755 index 0000000..7f94b30 --- /dev/null +++ b/hyhproject/mobile2/controller/Unionpays.php @@ -0,0 +1,211 @@ +<?php +namespace wstmart\mobile\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 银联支付控制器 + */ +class Unionpays extends Base{ + + /** + * 初始化 + */ + private $unionConfig; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('unionpay.sdk.acp_service'); + $m = new M(); + $this->unionConfig = $m->getPayment("unionpays"); + + $config = array(); + $config["signCertPwd"] = $this->unionConfig["unionSignCertPwd"];//"000000" + $config["signMethod"] = "01"; + + $config["frontUrl"] = url("mobile/orders/index","",true,true); + $config["backUrl"] = url("mobile/unionpays/notify","",true,true); + new \SDKConfig($config); + } + + + public function getUnionpaysUrl(){ + $m = new OM(); + $payObj = input("payObj/s"); + $data = array(); + if($payObj=="recharge"){ + $needPay = input("needPay/d"); + $data["status"] = $needPay>0?1:-1; + }else{ + $userId = (int)session('WST_USER.userId'); + $data = $m->checkOrderPay(); + } + return $data; + } + + /** + * 生成支付代码 + * @param array $order 订单信息 + * @param array $config_value 支付方式信息 + */ + public function toUnionpay(){ + + $payObj = input("payObj/s"); + $m = new OM(); + $obj = array(); + $data = array(); + $orderAmount = 0; + $orderId = ""; + $extra_param = ""; + if($payObj=="recharge"){//充值 + $orderAmount = input("needPay/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $data["status"] = $orderAmount>0?1:-1; + $orderId = WSTOrderNo(); + $extra_param = $payObj."|".$targetId."|".$targetType; + + }else{ + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $data = $m->checkOrderPay($obj); + if($data["status"]==1){ + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $order = $m->getPayOrders($obj); + $orderAmount = $order["needPay"]; + $payRand = $order["payRand"]; + $orderId = $obj["orderNo"]."a".$payRand; + $extra_param = $payObj."|".$userId."|".$obj["isBatch"]; + } + } + + if($data["status"]==1){ + $params = array( + //以下信息非特殊情况不需要改动 + 'version' => \SDKConfig::$version, //版本号 + 'encoding' => 'utf-8', //编码方式 + 'txnType' => '01', //交易类型 + 'txnSubType' => '01', //交易子类 + 'bizType' => '000201', //业务类型 + 'frontUrl' => \SDKConfig::$frontUrl, //前台通知地址 + 'backUrl' => \SDKConfig::$backUrl, //后台通知地址 + 'signMethod' => \SDKConfig::$signMethod,//签名方法 + 'channelType' => '08', //渠道类型,07-PC,08-手机 + 'accessType' => '0', //接入类型 + 'currencyCode' => '156', //交易币种,境内商户固定156 + //TODO 以下信息需要填写 + 'merId' => $this->unionConfig["unionMerId"], //"777290058110048",//商户代码 + 'orderId' => $orderId, //商户订单号,8-32位数字字母,不能含“-”或“_” + 'txnTime' => date('YmdHis'), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间 + 'txnAmt' => $orderAmount*100, //交易金额,单位分,此处默认取demo演示页面传递的参数 + // 订单超时时间。 + //'payTimeout' => date('YmdHis', strtotime('+15 minutes')), + + 'reqReserved' => $extra_param, + ); + $acpService = new \AcpService(); + $acpService::sign ( $params ); + $uri = \SDKConfig::$frontTransUrl; + $html_form = $acpService::createAutoFormHtml( $params, $uri ); + echo $html_form; + }else{ + + } + } + + /** + * 异步回调接口 + */ + public function notify(){ + + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){//验证成功 + $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + // 解释: 交易成功且结束,即不可再做任何操作。 + if($_POST['respMsg'] == 'Success!'){ + $m = new OM(); + $extras = explode("|",$_POST['reqReserved']); + $rs = array(); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $obj = array (); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $_POST["out_trade_no"];; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["total_fee"] = $_POST['total_fee']; + $obj["payFrom"] = 'unionpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //商户订单号 + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $tradeNo[0]; + $obj["total_fee"] = $_POST['total_fee']; + + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = 'unionpays'; + //支付成功业务逻辑 + $rs = $m->complatePay($obj); + } + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + } + }else{ + echo "fail"; //验证失败 + } + } + + /** + * 同步回调接口 + */ + public function response(){ + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){ //验证成功 + $order_sn = $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + $respMsg = $_POST['respMsg']; //交易状态 + + if($_POST['respMsg'] == 'success'){ + $m = new OM(); + $extras = explode("|",$_POST['extra_param']); + if($extras[0]=="recharge"){//充值 + $this->redirect(url("mobile/users/index")); + }else{ + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["orderNo"] = $tradeNo[0]; + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $rs = $m->getOrderType($obj); + $this->redirect(url("mobile/orders/index")); + } + }else { + $this->error('支付失败'); + } + }else { + $this->error('支付失败'); + } + } + +} diff --git a/hyhproject/mobile2/controller/Useraddress.php b/hyhproject/mobile2/controller/Useraddress.php new file mode 100755 index 0000000..003944d --- /dev/null +++ b/hyhproject/mobile2/controller/Useraddress.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\UserAddress as M; +/** + * ============================================================================ + * 用户地址控制器 + */ +class UserAddress extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 地址管理 + */ + public function index(){ + $m = new M(); + $userId = session('WST_USER.userId'); + $addressList = $m->listQuery($userId); + //获取省级地区信息 + $area = model('mobile/Areas')->listQuery(0); + $this->assign('area',$area); + $this->assign('list', $addressList); + $this->assign('type', (int)input('type')); + $this->assign('addressId', (int)input('addressId'));//结算选中的地址 + return $this->fetch('users/useraddress/list'); + } + /** + * 获取地址信息 + */ + public function getById(){ + $m = new M(); + return $m->getById(input('post.addressId/d')); + } + /** + * 设置为默认地址 + */ + public function setDefault(){ + $m = new M(); + return $m->setDefault(); + } + /** + * 新增/编辑地址 + */ + public function edits(){ + $m = new M(); + if(input('post.addressId/d')){ + $rs = $m->edit(); + }else{ + $rs = $m->add(); + } + return $rs; + } + /** + * 删除地址 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/mobile2/controller/Users.php b/hyhproject/mobile2/controller/Users.php new file mode 100755 index 0000000..4f2fe61 --- /dev/null +++ b/hyhproject/mobile2/controller/Users.php @@ -0,0 +1,608 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\mobile\model\Users as M; +use wstmart\mobile\model\Messages; +use wstmart\common\model\LogSms; +use wstmart\common\model\Users as MUsers; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [// mark cheng 添加reg 20180321 + 'checkAuth' => ['except'=>'reg,checklogin,login,register,getverify,toregister,forgetpass,forgetpasst,forgetpasss,forgetpassf,findpass,getfindphone,resetpass,getphoneverifycode,checkuserphone']// 访问这些except下的方法不需要执行前置操作 + ]; + /** + *跳转到合源惠联盟 mark 20170919 hsf + */ + + public function to_hyhlm(){ + session('to_hyhlm',null); + hook('toHyhlm'); + die; + } + + /** + * 会员登录页 + */ + public function login(){ + //如果已经登录了则直接跳去用户中心 + $USER = session('WST_USER'); + if(!empty($USER) && $USER['userId']!=''){ + $this->redirect("users/index"); + } + return $this->fetch('login'); + } + /** + * 会员登录 + */ + public function checkLogin(){ + $m = new M(); + $rs = $m->checkLogin(2); + $rs['url'] = session('WST_MO_WlADDRESS'); + return $rs; + } + + public function toRegister(){ + return $this->fetch('register'); + } + /** + * 会员注册 + */ + public function register(){ + $m = new M(); + $rs = $m->regist(2); + $rs['url'] = session('WST_MO_WlADDRESS'); + return $rs; + } + /** + * 手机号码是否存在 + */ + public function checkUserPhone(){ + $userPhone = input("post.userPhone"); + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已注册",-1); + }else{ + return WSTReturn("",1); + } + } + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $phoneVerify = rand(100000,999999); + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyCode',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + return $rv; + } + /** + * 会员中心 + */ + public function index(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + if($user['userName']=='') + $user['userName']=$user['loginName']; + $this->assign('user', $user); + //商城未读消息的数量 及 各订单状态数量 + $data = model('index')->getSysMsg('msg','order','follow','history'); + $this->assign('data',$data); + return $this->fetch('users/index'); + } + + /** + * 个人信息 + */ + public function edit(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + $this->assign('user', $user); + return $this->fetch('users/edit'); + } + /** + * 编辑个人信息 + */ + public function editUserInfo(){ + $m = new M(); + return $m->edit(); + } + /** + * 账户安全 + */ + public function security(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $userPhone = $user['userPhone']; + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $user['payPwd'] = empty($payPwd)?0:1; + $user['userPhone'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/index'); + } + /** + * 修改登录密码 + */ + public function editLoginPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_login_pass'); + } + public function editloginPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPass($userId); + } + /** + * 修改支付密码 + */ + public function editPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $user['payPwd'] = empty($payPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_pay_pass'); + } + public function editpayPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPayPass($userId); + } + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $user['backType'] = ($backType==1 && time()<floatval($timeVerify)+10*60)?1:0; + $this->assign('user', $user); + return $this->fetch('users/security/user_back_paypwd'); + } + /** + * 忘记支付密码:发送短信 + */ + public function backpayCode(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 忘记支付密码:验证短信 + */ + public function verifybackPay(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_backPaypwd_info.phoneVerify')){ + session('Type_backPaypwd',1); + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 忘记支付密码:重置密码 + */ + public function resetbackPay(){ + $m = new M(); + return $m->resetbackPay(); + } + /** + * 修改手机 + */ + public function editPhone(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/user_phone'); + } + /** + * 绑定手机:发送短信验证码 + */ + public function sendCodeTie(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'sendCodeTie',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function phoneEdit(){ + $phoneVerify = input("post.phoneCode"); + $process = input("post.process"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new M(); + $rs = $m->editPhone((int)session('WST_USER.userId'),session('Verify_info.userPhone')); + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 修改手机:发送短信验证码 + */ + public function sendCodeEdit(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 修改手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + session('Edit_userPhone_Time',time()); + return WSTReturn("验证成功",1); + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPhoneo(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $timeVerify = session('Edit_userPhone_Time'); + if(time()>floatval($timeVerify)+15*60){ + $user['phoneType'] = 1; + }else{ + $user['phoneType'] = 0; + } + $this->assign('user', $user); + return $this->fetch('users/security/user_phone'); + } + /** + * 用户退出 + */ + public function logout(){ + session('WST_USER',null); + setcookie("loginPwd", null); + session('WST_MO_WlADDRESS',null); + return WSTReturn("",1); + } + + /************************************************* 忘记密码 ********************************************************/ + // 页面过期/失效 + protected function expire($msg=''){ + $message = $msg?$msg:'页面已失效!'; + $html = '<h1>'.$message.'</h1><script>setTimeout(function(){location.href="'.url('mobile/users/index','','',true).'";},1000)</script>'; + return $this->display($html); + } + /** + * 忘记密码 + */ + public function forgetPass(){ + return $this->fetch('forget_pass'); + } + public function forgetPasst(){ + if(time()<floatval(session('findPass.findTime'))+30*60){ + $userId = session('findPass.userId'); + $m = new M(); + $info = $m->getById($userId); + if($info['userPhone']!='')$info['userPhone'] = WSTStrReplace($info['userPhone'],'*',3); + if($info['userEmail']!='')$info['userEmail'] = WSTStrReplace($info['userEmail'],'*',2,'@'); + $this->assign('forgetInfo',$info); + return $this->fetch('forget_pass2'); + }else{ + return $this->expire(); + } + } + + /** + * 重置密码 + */ + public function resetPass(){ + if(!session('findPass')){ + return $this->expire(); + } + return $this->fetch('forget_pass3'); + } + public function forgetPasss(){ + if(!session('findPass')){ + return $this->expire(); + } + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->expire('请在同一浏览器操作!'); + } + $uId = session('findPass.userId'); + $key = session("findPass.key"); + // 验证邮箱中的验证码 + $secretCode = input('secretCode'); + if($key==$secretCode){ + session('REST_userId',$uId); + session('REST_success','1'); + return WSTReturn('验证成功',1); + }else{ + return WSTReturn('校验码错误',-1); + } + + } + /** + * 找回密码 + */ + public function findPass(){ + //禁止缓存 + header('Cache-Control:no-cache,must-revalidate'); + header('Pragma:no-cache'); + $code = input("post.verifyCode"); + $step = input("post.step/d"); + switch ($step) { + case 1:#第一步,验证身份 + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $loginName = input("post.loginName"); + $rs = WSTCheckLoginKey($loginName); + if($rs["status"]==1){ + return WSTReturn("用户名不存在!"); + exit(); + } + $m = new M(); + $info = $m->checkAndGetLoginInfo($loginName); + if ($info != false) { + session('findPass',array('userId'=>$info['userId'],'loginName'=>$loginName,'userPhone'=>$info['userPhone'],'userEmail'=>$info['userEmail'],'loginSecret'=>$info['loginSecret'],'findTime'=>time())); + return WSTReturn("操作成功",1); + }else return WSTReturn("用户名不存在!"); + break; + case 2:#第二步,验证方式 + if (session('findPass.loginName') != null ){ + if(input("post.modes")==1){ + if ( session('findPass.userPhone') == null) { + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = input("post.Checkcode"); + if(!$phoneVerify){ + return WSTReturn('校验码不能为空!',-1); + } + return $this->checkfindPhone($phoneVerify); + }else{ + if (session('findPass.userEmail')==null) { + return WSTReturn('你没有预留邮箱,请通过手机号码找回密码!',-1); + } + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + return $this->getfindEmail(); + } + }else return $this->expire(); + break; + case 3:#第三步,设置新密码 + $resetPass = session('REST_success'); + if($resetPass != 1)return $this->expire(); + $loginPwd = input("post.loginPwd"); + $repassword = input("post.repassword"); + $decrypt_data = WSTRSA($loginPwd); + $decrypt_data2 = WSTRSA($repassword); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $loginPwd = $decrypt_data['data']; + $repassword = $decrypt_data2['data']; + }else{ + return WSTReturn('设置失败'); + } + if ($loginPwd == $repassword) { + $m = new M(); + $rs = $m->resetPass(); + if($rs['status']==1){ + return $rs; + }else{ + return $rs; + } + }else return WSTReturn('两次密码不同!',-1); + break; + default: + return $this->expire(); + break; + } + } + /** + * 手机验证码获取 + */ + public function getfindPhone(){ + session('WST_USER',session('findPass.userId')); + if(session('findPass.userPhone')==''){ + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = rand(100000,999999); + session('WST_USER',null); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,session('findPass.userPhone'),$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + // 记录发送短信的时间,用于验证是否过期 + session('REST_Time',time()); + $USER = ''; + $USER['phoneVerify'] = $phoneVerify; + $USER['time'] = time(); + session('findPhone',$USER); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 手机验证码检测 + * -1 错误,1正确 + */ + public function checkfindPhone($phoneVerify){ + if(!session('findPhone.phoneVerify') || time()>floatval(session('findPhone.time'))+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if (session('findPhone.phoneVerify') == $phoneVerify ) { + $fuserId = session('findPass.userId'); + if(!empty($fuserId)){ + session('REST_userId',$fuserId); + session('REST_success','1'); + $rs['status'] = 1; + $rs['url'] = url('mobile/users/resetPass'); + return $rs; + } + return WSTReturn('无效用户',-1); + } + return WSTReturn('校验码错误!',-1); + } + /** + * 发送验证邮件/找回密码 + */ + public function getfindEmail(){ + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('findPass.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail(session('findPass.userEmail'),'密码重置',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + $uId = session('findPass.userId'); + session("findPass.key", $code); + // 发起重置密码的时间; + session('REST_Time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + public function userSet(){ + return $this->fetch('users/userset/list'); + } + public function aboutUs(){ + return $this->fetch('users/userset/about'); + } + // mark by cheng 添加手机版分享20180320 + public function share(){ + $name = session('WST_USER.loginName'); + $data['url'] = 'http://www.heyuanhui.cn/mobile/users/reg?pName='.$name; + $data['title'] = '分享好友'; + $data['desc'] = '分享好友注册'; + $this->assign('data',$data); + return $this->fetch('users/share'); + } + // mark by cheng 新注册页20180320 + public function reg(){ + return $this->fetch('reg'); + } +} diff --git a/hyhproject/mobile2/controller/Userscores.php b/hyhproject/mobile2/controller/Userscores.php new file mode 100755 index 0000000..b58c356 --- /dev/null +++ b/hyhproject/mobile2/controller/Userscores.php @@ -0,0 +1,38 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\UserScores as MUserscores; +/** + * ============================================================================ + * 地区控制器 + */ +class Userscores extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看 + */ + public function index(){ + $rs = model('Users')->getFieldsById((int)session('WST_USER.userId'),['userScore','userTotalScore']); + $this->assign('object',$rs); + return $this->fetch('users/userscores/list'); + } + /** + * 获取数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('UserScores')->pageQuery($userId); + return WSTReturn("", 1,$data); + } + /** + * 签到惠宝 + */ + public function signScore(){ + $m = new MUserscores(); + $userId = (int)session('WST_USER.userId'); + $rs = $m->signScore($userId); + return $rs; + } +} diff --git a/hyhproject/mobile2/controller/Wallets.php b/hyhproject/mobile2/controller/Wallets.php new file mode 100755 index 0000000..920056f --- /dev/null +++ b/hyhproject/mobile2/controller/Wallets.php @@ -0,0 +1,49 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\common\model\Orders as OM; +/** + * ============================================================================ + * 源宝控制器 + */ +class Wallets extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 跳去支付页面 + */ + public function payment(){ + $data = []; + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $this->assign('data',$data); + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + + $list = $m->getByUnique(); + $this->assign('rs',$list); + + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $this->assign('needPay',$rs['needPay']); + //获取用户钱包 + $user = model('users')->getFieldsById($data['userId'],'userMoney,payPwd'); + $this->assign('userMoney',$user['userMoney']); + $payPwd = $user['payPwd']; + $payPwd = empty($payPwd)?0:1; + $this->assign('payPwd',$payPwd); + } + return $this->fetch('users/orders/orders_pay_wallets'); + } + /** + * 钱包支付 + */ + public function payByWallet(){ + $m = new OM(); + return $m->payByWallet(); + } +} diff --git a/hyhproject/mobile2/controller/Weixinpays.php b/hyhproject/mobile2/controller/Weixinpays.php new file mode 100755 index 0000000..3bc3c16 --- /dev/null +++ b/hyhproject/mobile2/controller/Weixinpays.php @@ -0,0 +1,185 @@ +<?php +namespace wstmart\mobile\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +use wstmart\common\model\ChargeItems as CM; +/** + * ============================================================================ + * 微信支付控制器 + */ +class Weixinpays extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('wxpay.WxPayConf'); + Loader::import('wxpay.WxJsApiPay'); + + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + $this->wxpayConfig['notifyurl'] = url("mobile/weixinpays/notify","",true,true); + $this->wxpayConfig['returnurl'] = url("mobile/orders/index","",true,true); + $this->wxpayConfig['curl_timeout'] = 30; + + // 初始化WxPayConf + new \WxPayConf($this->wxpayConfig); + } + + + public function toWeixinPay(){ + $data = []; + $payObj = input("payObj/s"); + if($payObj=="recharge"){ + $cm = new CM(); + $itemId = (int)input("itemId/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $needPay = 0; + if($itemId>0){ + $item = $cm->getItemMoney($itemId); + $needPay = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $needPay = (int)input("needPay/d"); + } + $out_trade_no = WSTOrderNo(); + $body = "钱包充值"; + $data["status"] = $needPay>0?1:-1; + $attach = $payObj."@".$targetId."@".$targetType."@".$needPay."@".$itemId; + $returnurl = url("mobile/logmoneys/usermoneys","",true,true); + }else{ + + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $pkey = base64_decode(input("pkey")); + $extras = explode ( "@",$pkey); + + $m = new OM(); + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $obj["orderNo"] = input("orderNo"); + $obj["isBatch"] = (int)input("isBatch"); + + $rs = $m->getByUnique(); + $this->assign('rs',$rs); + $body = "支付订单"; + $order = $m->getPayOrders($obj); + $needPay = $order["needPay"]; + $payRand = $order["payRand"]; + $out_trade_no = $obj["orderNo"]."a1".$payRand; + $attach = $userId."@".$obj["orderNo"]."@".$obj["isBatch"]; + $returnurl = url("mobile/orders/index","",true,true); + } + } + + // 初始化WxPayConf + new \WxPayConf ( $this->wxpayConfig ); + //使用统一支付接口 + $notify_url = $this->wxpayConfig ['notifyurl']; + $unifiedOrder = new \UnifiedOrder(); + $unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号 + $unifiedOrder->setParameter("notify_url",$notify_url);//通知地址 + $unifiedOrder->setParameter("trade_type","MWEB");//交易类型 + $unifiedOrder->setParameter("attach",$attach);//扩展参数 + $unifiedOrder->setParameter("body",$body);//商品描述 + $needPay = WSTBCMoney($needPay,0,2); + $unifiedOrder->setParameter("total_fee", $needPay * 100);//总金额 + + $wap_name = WSTConf('CONF.mallName'); + $unifiedOrder->setParameter("scene_info", "{'h5_info': {'type':'Wap','wap_url': '".$notify_url."','wap_name': '".$wap_name."'}}");//总金额 + + $this->assign('needPay',$needPay); + $this->assign('returnUrl',$returnurl ); + $this->assign('payObj',$payObj); + $wxResult = $unifiedOrder->getResult(); + $this->assign('mweb_url',$wxResult['mweb_url']."&redirect_url".urlencode($returnurl)); + return $this->fetch('users/orders/orders_wxpay'); + } + + + public function notify() { + // 使用通用通知接口 + $notify = new \Notify(); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $notify->saveData ( $xml ); + if ($notify->checkSign () == FALSE) { + $notify->setReturnParameter ( "return_code", "FAIL" ); // 返回状态码 + $notify->setReturnParameter ( "return_msg", "签名失败" ); // 返回信息 + } else { + $notify->setReturnParameter ( "return_code", "SUCCESS" ); // 设置返回码 + } + $returnXml = $notify->returnXml (); + if ($notify->checkSign () == TRUE) { + if ($notify->data ["return_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } elseif ($notify->data ["result_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } else { + $order = $notify->getData (); + $rs = $this->process($order); + if($rs["status"]==1){ + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + } + } + + //订单处理 + private function process($order) { + + $obj = array(); + $obj["trade_no"] = $order['transaction_id']; + + $obj["total_fee"] = (float)$order["total_fee"]/100; + $extras = explode ( "@", $order ["attach"] ); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $itemId = (int)$extras [4]; + + $obj["out_trade_no"] = $order['out_trade_no']; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["payFrom"] = 'weixinpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + $obj["userId"] = $extras[0]; + $obj["out_trade_no"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = "weixinpays"; + // 支付成功业务逻辑 + $m = new OM(); + $rs = $m->complatePay ( $obj ); + } + + return $rs; + + } + +} diff --git a/hyhproject/mobile2/model/Articles.php b/hyhproject/mobile2/model/Articles.php new file mode 100755 index 0000000..b9fe1b2 --- /dev/null +++ b/hyhproject/mobile2/model/Articles.php @@ -0,0 +1,100 @@ +<?php +namespace wstmart\mobile\model; +use think\Db; +/** + * ============================================================================ + * 文章类 + */ +class Articles extends Base{ + + /** + * 获取咨询中中心所有文章 + */ + public function getArticles(){ + // 获取咨询中心下的所有分类id + $catId = input('catId'); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>$catId, + 'a.isShow'=>1, + 'a.dataFlag'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.catType'=>0, + ]) + ->order('createTime desc') + ->paginate((int)input('pagesize')); + return $rs; + } + + + /** + * 根据id获取资讯文章 + */ + public function getNewsById(){ + $id = (int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + $article = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where('ac.catType=0 and a.dataFlag=1 and a.isShow=1') + ->cache(true) + ->find($id); + // 图片延迟加载 + $article['articleContent']=htmlspecialchars_decode($article['articleContent']); + $rule = '/<img src="\/(wstmartp.*?)"/'; + preg_match_all($rule, $article['articleContent'],$images); + foreach($images[0] as $k=>$v){ + $article['articleContent'] = str_replace($v, "<img src='/".WSTImg($images[1][$k],3)."'", $article['articleContent']); + } + $articleId = cookie("mobile_like_articleId"); + $articleId = is_array($articleId)?$articleId:[]; + $rc = !empty($articleId)?in_array($id,$articleId):''; + if($rc){ + $article['likeState'] = 1; + }else{ + $article['likeState'] = 0; + } + return $article; + } + /** + * 点赞 + */ + public function like(){ + $id = input("param.id/d"); + //判断记录是否存在 + $articleId = cookie("mobile_like_articleId"); + $articleId = is_array($articleId)?$articleId:[]; + $rc = !empty($articleId)?in_array($id,$articleId):''; + if($rc)return WSTReturn("已点赞成功", -1); + $rs = $this->where(['isShow'=>1,'dataFlag'=>1,'articleId'=>$id])->setInc('likeNum',1); + //判断是否点赞成功 + if(false !== $rs){ + array_push($articleId,$id); + cookie("mobile_like_articleId",$articleId,25920000); + return WSTReturn("点赞成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取资讯中心的子集分类 + */ + public function getChildInfos(){ + $infos = cache('NEW_INFOS'); + $i = 0; + if(!$infos){ + $data = Db::name('article_cats')->cache(true)->select(); + foreach($data as $k=>$v){ + if($v['parentId']== 8){ + $infos[$i]['catId'] = $v['catId']; + $infos[$i]['catName'] = $v['catName']; + $i++; + } + } + cache('NEW_INFOS',$infos); + } + return $infos; + } +} diff --git a/hyhproject/mobile2/model/Base.php b/hyhproject/mobile2/model/Base.php new file mode 100755 index 0000000..50f9552 --- /dev/null +++ b/hyhproject/mobile2/model/Base.php @@ -0,0 +1,8 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Base as CBase; +/** + * ============================================================================ + * 基础模型器 + */ +class Base extends CBase {} \ No newline at end of file diff --git a/hyhproject/mobile2/model/Goods.php b/hyhproject/mobile2/model/Goods.php new file mode 100755 index 0000000..5991488 --- /dev/null +++ b/hyhproject/mobile2/model/Goods.php @@ -0,0 +1,173 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Goods as CGoods; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends CGoods{ + /** + * 获取列表 + */ + public function pageQuery($goodsCatIds = []){ + //查询条件 + $keyword = input('keyword'); + $brandId = input('brandId/d'); + $where = $where2 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + $where['goodsCatIdPath']=['notlike','389'.'%']; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + if($brandId>0)$where['g.brandId'] = $brandId; + //排序条件 + $orderBy = input('condition/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('desc/d',0)==1)?1:0; + $pageBy = ['saleNum','shopPrice','visitNum','saleTime']; + $pageOrder = ['desc','asc']; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $list = Db::name('goods')->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId")->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where($where) + ->field('g.goodsId,goodsName,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery,gs.totalScore,gs.totalUsers') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pagesize/d'))->toArray(); + return $list; + } + + /** + * 获取商品资料在前台展示 + */ + public function getBySale($goodsId){ + $key = input('key'); + // 浏览量 + $this->where('goodsId',$goodsId)->setInc('visitNum',1); + $rs = Db::name('goods')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->find(); + if(!empty($rs)){ + $rs['read'] = false; + //判断是否可以公开查看 + $viKey = WSTShopEncrypt($rs['shopId']); + if(($rs['isSale']==0 || $rs['goodsStatus']==0) && $viKey != $key)return []; + if($key!='')$rs['read'] = true; + //获取店铺信息 + $rs['shop'] = model('shops')->getBriefShop((int)$rs['shopId']); + if(empty($rs['shop']))return []; + //获取商店的授权商店分类和商铺电话信息 + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left')->join('__SHOPS__ s','s.shopId = cs.shopId','left') + ->where('cs.shopId',$rs['shopId'])->field('cs.shopId,s.shopTel,gc.catId,gc.catName')->select(); + $rs['shop']['catId'] = $goodsCats[0]['catId']; + $rs['shop']['shopTel'] = $goodsCats[0]['shopTel']; + + $cat = []; + foreach ($goodsCats as $v){ + $cat[] = $v['catName']; + } + $rs['shop']['cat'] = implode(',',$cat); + if(empty($rs['shop']))return []; + $gallery = []; + $gallery[] = $rs['goodsImg']; + + if($rs['gallery']!=''){//有多个图片就把多个一维图片地址合成一个数组 + $tmp = explode(',',$rs['gallery']); + $gallery = array_merge($gallery,$tmp); + } + $rs['gallery'] = $gallery; + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,gc.catName,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + $rs['spec']=[]; + //把属于同一个分类的规格整合到一块 + foreach ($specs as $key =>$v){ + $rs['spec'][$v['catId']]['name'] = $v['catName']; + $rs['spec'][$v['catId']]['list'][] = $v; + } + //dump($rs['spec']);die; + //获取销售规格,商品规格的具体属性 + $sales = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,specStock')->select(); + if(!empty($sales)){ + //将规格ID格式如:3:4:5:6:7,设为数组键名,与$rs['spec']['catId']['list']['itemId'] 对应 + /*实例 + //$specs转换后$rs['spec']数据 + [11] => array(2) {//11代表规格分类ID + ["name"] => string(12) "机身颜色"//规格分类名称 + ["list"] => array(2) {//当前分类11下的数据 + [0] => array(6) { + ["isAllowImg"] => int(1) + ["catName"] => string(12) "机身颜色" + ["catId"] => int(11) + ["itemId"] => int(5)//这个即代表数据的ID,3:4:(5):6:7就是对应的这个 + ["itemName"] => string(6) "黄色" + ["itemImg"] => string(44) "upload/goods/2017-11/5a0a7e2ee935c_thumb.jpg" + } + [1] => array(6) { + ["isAllowImg"] => int(1) + ["catName"] => string(12) "机身颜色" + ["catId"] => int(11) + ["itemId"] => int(10) + ["itemName"] => string(6) "灰色" + ["itemImg"] => string(44) "upload/goods/2017-11/5a0a7e3970fed_thumb.jpg" + } + } + } + //$sales原始数据 + [0] => array(7) { + ["id"] => int(3) + ["isDefault"] => int(1) + ["productNo"] => string(1) "3" + ["specIds"] => string(9) "3:4:5:6:7" + ["marketPrice"] => string(7) "1070.00" + ["specPrice"] => string(7) "1002.00" + ["specStock"] => int(0) + } + //$sales下面转换后数据 + ["3:4:5:6:7"] => array(6) { + ["id"] => int(3) + ["isDefault"] => int(1) + ["productNo"] => string(1) "3" + ["marketPrice"] => string(7) "1070.00" + ["specPrice"] => string(7) "1002.00" + ["specStock"] => int(0) + }*/ + foreach ($sales as $key =>$v){ + $str = explode(':',$v['specIds']); + sort($str); + unset($v['specIds']); + $rs['saleSpec'][implode(':',$str)] = $v; + } + } + //获取商品属性 + $rs['attrs'] = Db::name('attributes')->alias('a')->join('goods_attributes ga','a.attrId=ga.attrId','inner') + ->where(['a.isShow'=>1,'dataFlag'=>1,'goodsId'=>$goodsId])->field('a.attrName,ga.attrVal') + ->order('attrSort asc')->select(); + //获取商品评分 + $rs['scores'] = Db::name('goods_scores')->where('goodsId',$goodsId)->field('totalScore,totalUsers')->find(); + $rs['scores']['totalScores'] = ($rs['scores']['totalScore']==0)?5:WSTScore($rs['scores']['totalScore'],$rs['scores']['totalUsers'],5,0,3); + WSTUnset($rs, 'totalUsers'); + //关注 + $f = model('Favorites'); + $rs['favShop'] = $f->checkFavorite($rs['shopId'],1); + $rs['favGood'] = $f->checkFavorite($goodsId,0); + } + //dump($rs);die; + return $rs; + } + + + public function historyQuery(){ + $ids = cookie("wx_history_goods"); + if(empty($ids))return []; + $where = []; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['goodsId'] = ['in',$ids]; + $orderBy = "field(`goodsId`,".implode(',',$ids).")"; + return Db::name('goods') + ->where($where)->field('goodsId,goodsName,goodsImg,saleNum,shopPrice') + ->order($orderBy) + ->paginate((int)input('pagesize'))->toArray(); + } +} diff --git a/hyhproject/mobile2/model/GoodsAppraises.php b/hyhproject/mobile2/model/GoodsAppraises.php new file mode 100755 index 0000000..da07a13 --- /dev/null +++ b/hyhproject/mobile2/model/GoodsAppraises.php @@ -0,0 +1,27 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\GoodsAppraises as CGoodsAppraises; +use think\Db; +/** + * ============================================================================ + * 评价类 + */ +class GoodsAppraises extends CGoodsAppraises{ + /** + * 获取评论 + */ + public function getAppr(){ + $oId = (int)input('oId'); + $uId = (int)session('WST_USER.userId'); + $gId = (int)input('gId'); + $specId = (int)input('sId'); + $orderGoodsId = (int)input('orderGoodsId'); + $rs = $this->where(['orderId'=>$oId,'userId'=>$uId,'goodsId'=>$gId,'goodsSpecId'=>$specId,'orderGoodsId'=>$orderGoodsId])->find(); + if($rs!==false){ + $rs = !empty($rs)?$rs:['goodsScore'=>'','timeScore'=>'','serviceScore'=>'','content'=>'']; + return WSTReturn('',1,$rs); + } + return WSTReturn('获取出错',-1); + } + +} diff --git a/hyhproject/mobile2/model/GoodsCats.php b/hyhproject/mobile2/model/GoodsCats.php new file mode 100755 index 0000000..53f0cee --- /dev/null +++ b/hyhproject/mobile2/model/GoodsCats.php @@ -0,0 +1,75 @@ +<?php +namespace wstmart\mobile\model; +use think\Cache; +/** + * ============================================================================ + * 商品分类类 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function getGoodsCats(){ + $list = cache('WST_CACHE_GOODS_CAT_MOB'); + if(!$list){ + //查询一级分类 + $trs1s = $this->where(["dataFlag"=>1,"isShow"=>1,"parentId"=>0])->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs1 = array(); + $list = array(); + $rs2 = array(); + $maprs = array(); + $ids = array(); + foreach ($trs1s as $key =>$v){ + $trs1[$key]['catId'] = $v['catId']; + $trs1[$key]['parentId'] = $v['parentId']; + $trs1[$key]['catName'] = $v['catName']; + $ids[] = $v['catId']; + } + $ids[] = -1; + //查询二级分类 + $trs2s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs2 = array(); + $ids = array(); + foreach ($trs2s as $key =>$v){ + $trs2[$key]['catId'] = $v['catId']; + $trs2[$key]['parentId'] = $v['parentId']; + $trs2[$key]['catName'] = $v['catName']; + } + foreach ($trs2 as $v2){ + $ids[] = $v2['catId']; + $maprs[$v2['parentId']][] = $v2; + } + $ids[] = -1; + //查询三级分类 + $trs3s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName,catImg')->order('catSort asc')->select(); + $trs3 = array(); + $ids = array(); + foreach ($trs3s as $key =>$v){ + $trs3[$key]['catId'] = $v['catId']; + $trs3[$key]['parentId'] = $v['parentId']; + $trs3[$key]['catName'] = $v['catName']; + $trs3[$key]['catImg'] = strval($v['catImg']); + } + foreach ($trs3 as $v2){ + $maprs[$v2['parentId']][] = $v2; + } + //倒序建立樹形 + foreach ($trs2 as $v2){ + $v2['childList'] = []; + if(isset($maprs[$v2['catId']]))$v2['childList'] = $maprs[$v2['catId']]; + $rs2[] = $v2; + } + foreach ($trs1 as $v2){ + foreach ($rs2 as $vv2){ + if($vv2['parentId']==$v2['catId']){ + $v2['childList'][] = $vv2; + } + } + $list[] = $v2; + } + Cache::set('WST_CACHE_GOODS_CAT_MOB',$list); + } + return $list; + } + +} diff --git a/hyhproject/mobile2/model/Index.php b/hyhproject/mobile2/model/Index.php new file mode 100755 index 0000000..453e153 --- /dev/null +++ b/hyhproject/mobile2/model/Index.php @@ -0,0 +1,68 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Tags as T; +use think\Db; +/** + * ============================================================================ + * 默认类 + */ +class Index extends Base{ + /** + * 楼层 + */ + public function pageQuery(){ + $limit = (int)input('post.currPage');//楼层页码 + if($limit>9)return; + $cacheData = cache('MO_CATS_ADS'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('goods_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'isFloor'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select();//按设定排序获取分类名称,异步下拉加载,传输楼层的层楼 + if($rs){ + $rs= $rs[0];//用select就选第一个,其实可以改成find + $t = new T(); + $rs['ads'] = $t->listAds('mo-ads-'.$limit,'1');//获取手机版楼层页面的广告图 + $rs['goods'] = Db::name('goods')->alias('g')->join('__RECOMMENDS__ r','g.goodsId=r.dataId')->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where(['r.goodsCatId'=>$rs['catId'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'r.dataSrc'=>0,'r.dataType'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,gs.totalScore,gs.totalUsers')->order('r.dataSort asc')->limit(8)->select(); + if(empty($rs['goods'])){ + $rs['goods'] = Db::name('goods')->alias('g')->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where(['g.goodsCatIdPath'=>['like',$rs['catId'].'_%'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'g.isHot'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,gs.totalScore,gs.totalUsers') + ->order('saleNum desc,goodsId asc')->limit(8)->select(); + } + if($rs['goods']){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['praiseRate'] = ($v['totalScore']>0)?(sprintf("%.2f",$v['totalScore']/($v['totalUsers']*15))*100).'%':'100%'; + } + } + $rs['currPage'] = $limit; + } + cache('MO_CATS_ADS'.$limit,$rs,86400); + return $rs; + } + + /** + * 获取系统消息 + */ + function getSysMsg($msg='',$order='',$follow='',$history=''){ + $data = []; + $userId = (int)session('WST_USER.userId'); + if($msg!=''){ + $data['message']['num'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + } + if($order!=''){ + $data['order']['waitPay'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['order']['waitSend'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>0,'dataFlag'=>1])->count(); + $data['order']['waitReceive'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>1,'dataFlag'=>1])->count(); + $data['order']['waitAppraise'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + } + if($follow!=''){ + $data['follow']['goods'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>0])->count(); + $data['follow']['shops'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>1])->count(); + } + if($history!=''){ + $history = cookie("wx_history_goods"); + $data['history']['num'] = count($history); + } + return $data; + } +} diff --git a/hyhproject/mobile2/model/Orders.php b/hyhproject/mobile2/model/Orders.php new file mode 100755 index 0000000..6b3a471 --- /dev/null +++ b/hyhproject/mobile2/model/Orders.php @@ -0,0 +1,11 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Orders as COrders; +use think\Db; +/** + * ============================================================================ + * 订单类 + */ +class Orders extends COrders{ + +} diff --git a/hyhproject/mobile2/model/Payments.php b/hyhproject/mobile2/model/Payments.php new file mode 100755 index 0000000..2f08599 --- /dev/null +++ b/hyhproject/mobile2/model/Payments.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Payments as CPayments; +/** + * ============================================================================ + * 支付管理业务处理 + */ +class Payments extends CPayments{ +} diff --git a/hyhproject/mobile2/model/Shops.php b/hyhproject/mobile2/model/Shops.php new file mode 100755 index 0000000..c0d1a8a --- /dev/null +++ b/hyhproject/mobile2/model/Shops.php @@ -0,0 +1,134 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Shops as CShops; +use think\Db; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends CShops{ + /** + * 店铺街列表 + */ + public function pageQuery($pagesize){ + $catId = (int)input("id"); + $keyword = input("keyword"); + $condition = input("condition"); + $desc = input("desc"); + $datas = array('sort'=>array('1'=>'ss.totalScore/ss.totalUsers'),'desc'=>array('desc','asc')); + $rs = $this->alias('s'); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.applyStatus'] = 2; + if($keyword!='')$where['s.shopName'] = ['like','%'.$keyword.'%']; + if($catId>0){ + $rs->join('__CAT_SHOPS__ cs','cs.shopId = s.shopId','left'); + $where['cs.catId'] = $catId; + } + $order = ['s.shopId'=>'asc']; + if($condition>0){ + $order = [$datas['sort'][$condition]=>$datas['desc'][$desc]]; + } + $page = $rs->join('__SHOP_SCORES__ ss','ss.shopId = s.shopId','left') + ->where($where)->order($order) + ->field('s.shopId,s.shopImg,s.shopName,s.shopCompany,ss.totalScore,ss.totalUsers,ss.goodsScore,ss.goodsUsers,ss.serviceScore,ss.serviceUsers,ss.timeScore,ss.timeUsers,s.areaIdPath') + ->paginate($pagesize)->toArray(); + foreach ($page['Rows'] as $key =>$v){ + //商品列表 + $goods = db('goods')->where(['dataFlag'=> 1,'isSale'=>1,'goodsStatus'=> 1,'shopId'=> $v["shopId"]])->field('goodsId,goodsName,shopPrice,goodsImg') + ->order('saleTime desc')->limit(4)->select(); + $page['Rows'][$key]['goods'] = $goods; + } + if(empty($page['Rows']))return $page; + $shopIds = []; + $areaIds = []; + foreach ($page['Rows'] as $key =>$v){ + $shopIds[] = $v['shopId']; + $tmp = explode('_',$v['areaIdPath']); + $areaIds[] = $tmp[1]; + $page['Rows'][$key]['areaId'] = $tmp[1]; + //总评分 + $page['Rows'][$key]['totalScore'] = WSTScore($v["totalScore"]/3, $v["totalUsers"]); + $page['Rows'][$key]['goodsScore'] = WSTScore($v['goodsScore'],$v['goodsUsers']); + $page['Rows'][$key]['serviceScore'] = WSTScore($v['serviceScore'],$v['serviceUsers']); + $page['Rows'][$key]['timeScore'] = WSTScore($v['timeScore'],$v['timeUsers']); + } + $rccredMap = []; + $goodsCatMap = []; + $areaMap = []; + //认证、地址、分类 + if(!empty($shopIds)){ + $rccreds = Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','a.accredId=sac.accredId and a.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('sac.shopId,accredName,accredImg')->select(); + foreach ($rccreds as $v){ + $rccredMap[$v['shopId']][] = $v; + } + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[$v['shopId']][] = $v['catName']; + } + $areas = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$areaIds)->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->select(); + foreach ($areas as $v){ + $areaMap[$v['areaId']] = $v; + } + } + foreach ($page['Rows'] as $key =>$v){ + $page['Rows'][$key]['accreds'] = (isset($rccredMap[$v['shopId']]))?$rccredMap[$v['shopId']]:[]; + $page['Rows'][$key]['catshops'] = (isset($goodsCatMap[$v['shopId']]))?implode(',',$goodsCatMap[$v['shopId']]):''; + $page['Rows'][$key]['areas']['areaName1'] = (isset($areaMap[$v['areaId']]['areaName1']))?$areaMap[$v['areaId']]['areaName1']:''; + $page['Rows'][$key]['areas']['areaName2'] = (isset($areaMap[$v['areaId']]['areaName2']))?$areaMap[$v['areaId']]['areaName2']:''; + } + return $page; + } + /** + * 获取卖家中心信息 + */ + public function getShopSummary(){ + $shopId = (int)input('shopId',1); + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left')->join('__SHOP_CONFIGS__ sc','sc.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'dataFlag'=>1]) + ->field('s.shopId,shopImg,shopName,shopkeeper,shopAddress,shopQQ,shopTel,serviceStartTime,serviceEndTime,isInvoice,invoiceRemarks,cs.*,sc.shopBanner') + ->find(); + //评分 + $scores['totalScore'] = WSTScore($shop['totalScore'],$shop['totalUsers']); + $scores['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $scores['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $scores['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + $shop['scores'] = $scores; + //认证 + $accreds = $this->shopAccreds($shopId); + $shop['accreds'] = $accreds; + return ['shop'=>$shop]; + } + /** + * 自营店铺楼层 + */ + public function getFloorData(){ + $limit = (int)input('post.currPage'); + $cacheData = cache('WX_SHOP_FLOOR'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('shop_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'shopId'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select(); + if($rs){ + $rs= $rs[0]; + $goods = Db::name('goods')->where('shopCatId1','=',$rs['catId'])->where(['dataFlag'=>1,'goodsStatus'=>1])->field('goodsId,goodsName,goodsImg,shopPrice,saleNum')->order('isHot desc')->limit(4)->select(); + $rs['goods'] = $goods; + $rs['currPage'] = $limit; + } + cache('WX_SHOP_FLOOR'.$limit,$rs,86400); + return $rs; + } + /** + * 根据订单id 获取店铺名称 + */ + public function getShopName($oId){ + return $this->alias('s') + ->join('__ORDERS__ o',"s.shopId=o.shopId",'inner') + ->where("o.orderId=$oId") + ->value('s.shopName'); + + } +} diff --git a/hyhproject/mobile2/model/Users.php b/hyhproject/mobile2/model/Users.php new file mode 100755 index 0000000..11bbe61 --- /dev/null +++ b/hyhproject/mobile2/model/Users.php @@ -0,0 +1,28 @@ +<?php +namespace wstmart\mobile\model; +use wstmart\common\model\Users as CUsers; +use Think\Db; +/** + * ============================================================================ + * 用户类 + */ +class Users extends CUsers{ + /** + * 验证用户支付密码 + */ + function checkPayPwd(){ + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return WSTReturn('验证失败'); + } + $userId = (int)session('WST_USER.userId'); + $rs = $this->field('payPwd,loginSecret')->find($userId); + if($rs['payPwd']==md5($payPwd.$rs['loginSecret'])){ + return WSTReturn('',1); + } + return WSTReturn('支付密码错误',-1); + } +} diff --git a/hyhproject/mobile2/validate/UserAddress.php b/hyhproject/mobile2/validate/UserAddress.php new file mode 100755 index 0000000..2752071 --- /dev/null +++ b/hyhproject/mobile2/validate/UserAddress.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\mobile\validate; +use think\Validate; +/** + * ============================================================================ + * WSTMart开源商城 + * 官网地址:http://www.wstmall.com + * 联系QQ:707563272 + * ============================================================================ + * 用户地址验证器 + */ +class UserAddress extends Validate{ + protected $rule = [ + ['userName' ,'require','请输入联系名称'], + ['userPhone' ,'require','请输入手机号码'], + ['areaId' ,'require','请选择完整地址'], + ['userAddress' ,'require','请输入详细地址'] + ]; + + protected $scene = [ + 'add' => ['userName','userPhone','areaId','userAddress'], + 'edit' => ['userName','userPhone','areaId','userAddress'] + ]; +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/articles/news_list.html b/hyhproject/mobile2/view/default/articles/news_list.html new file mode 100755 index 0000000..cf9225e --- /dev/null +++ b/hyhproject/mobile2/view/default/articles/news_list.html @@ -0,0 +1,168 @@ +{extend name="default/base" /} +{block name="title"}商城快讯 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/articles.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list" style="margin-top: 50px;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>商城快讯</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<input type="hidden" name="" value="{$catId}" id="catId" autocomplete="off"> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + {volist name="catInfo" id="vo"} + <li class="tab-item {if $catId==$vo.catId}tab-curr{/if}" catId="{$vo['catId']}">{$vo['catName']}</li> + {/volist} + </ul> + </div> + + <section id="newsListBox" > + + </section> + + <div style="height:50px;"></div> + </section> + <script id="newsList" type="text/html"> + {{# for(var i=0;i<d.length;i++){ }} + {{# if(d[i].TypeStatus==1){ }} + <div class="news-item wst-model" onclick="viewNews({{d[i].articleId}})" > + <div class="ui-row-flex"> + <div class="ui-col"> + <div class="img j-imgAdapt wst-bor-mix-img" > + <a href="javascript:void(0);" > + {{# if(d[i].coverImg) { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i].coverImg}}"> + {{# } else { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" > + {{# } }} + </a> + </div> + </div> + <div class="ui-col ui-col-3" > + <div class="ui-row-flex ui-row-flex-ver wst-info" > + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;">{{d[i].articleTitle}}</div> + <div class="ui-nowrap-multi wst-mix-cont" style="-webkit-line-clamp: 3;">{{d[i].articleContent}}</div> + </div> + </div> + </div> + <div class="ui-row-flex ui-whitespace wst-model wst-mix-info "> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-end wst-right-align">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + {{# if(d[i].TypeStatus==2){ }} + <div class="news-item wst-model" onclick="viewNews({{d[i].articleId}})"> + <div class="ui-row-flex"> + <div class="ui-col ui-col-3"> + <div class="ui-row-flex ui-row-flex-ver wst-info" > + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;">{{d[i].articleTitle}}{{d[i].TypeStatus}}</div> + <div class="ui-nowrap-multi wst-mix-cont" style="-webkit-line-clamp: 3;">{{d[i].articleContent}}</div> + </div> + </div> + <div class="ui-col"> + <div class="img j-imgAdapt wst-bor-mix-img"> + <a href="javascript:void(0);" > + {{# if(d[i].coverImg) { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d[i].coverImg}}"> + {{# } else { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" > + {{# } }} + </a> + </div> + </div> + </div> + <div class="ui-row-flex ui-whitespace wst-model wst-mix-info "> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-end wst-right-align">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + {{# if(d[i].TypeStatus==3){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver wst-model" style="height:auto;overflow:hidden;" onclick="viewNews({{d[i].articleId}})"> + <div class="wst-max-info"> + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;" >{{d[i].articleTitle}}</div> + </div> + <div class="wst-max-info"> + <div class="ui-nowrap-multi wst-mix-cont" style="-webkit-line-clamp: 1;padding-top: 0px;" >{{d[i].articleContent}}</div> + </div> + <div class="max-img"> + <a href="javascript:void(0);"> + {{# if(d[i].coverImg) { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i].coverImg}}"> + {{# } else { }} + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" > + {{# } }} + </a> + </div> + <div class="max-remind wst-mix-info ui-row"> + <div class="ui-col ui-col-50 ui-flex ui-flex-ver ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col-50 ui-flex ui-flex-ver ui-flex-pack-center ui-flex-align-end">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + + {{# } }} + </script> + </div> + + + + + +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>商城快讯</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-whitespace news-content-box"> + <div class="ui-nowrap ui-whitespace news-title" id="articleTitle"></div> + <div class="ui-whitespace news-time" id="createTime"></div> + <div class="ui-whitespace view-content" id="articleContent"> + + </div> + </div> + <div class="wst-like ui-whitespace ui-flex ui-flex-pack-center" id="like1" onclick="javascript:like();"> + <input type="hidden" name="" id="articleId" value="" > + <span class="icon-like1"><p class="like_num" id="likeNum"></p></span> + </div> + <div class="wst-like ui-whitespace ui-flex ui-flex-pack-center" id="like" > + <input type="hidden" name="" id="articleId" value="" > + <span class="icon-like2"><p class="like_num" id="likeNum2"></p></span> + </div> + + </div> +</div> + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script> +$(function(){ + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var catId = $(this).attr('catId'); + $('#catId').val(catId); + reFlashList(); + }); + {{if !empty($articleId) }} + viewNews({$articleId}) + {{/if}} +}) +</script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/articles/news_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/articles/news_list.js b/hyhproject/mobile2/view/default/articles/news_list.js new file mode 100755 index 0000000..ebd4693 --- /dev/null +++ b/hyhproject/mobile2/view/default/articles/news_list.js @@ -0,0 +1,116 @@ +// 获取商城快讯 +function getNewList($catId = ''){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + param.catId = $('#catId').val(); + $.post(WST.U('mobile/news/getNewsList'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('newsList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#newsListBox').append(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<ul class="ui-row-flex wst-flexslp ui-flex-align-center" style="margin-top:150px;">'; + html += '<li class="ui-col ui-flex ui-flex-pack-center">'; + html += '<p>暂无商城快讯</p>'; + html += '</li>'; + html += '</ul>'; + $('#newsListBox').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter(); + getNewList(); + + + + var dataHeight = $("#frame").css('height'); + $("#frame").css('top',0); + var dataWidth = $("#frame").css('width'); + $("#frame").css('right','-'+dataWidth); + + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getNewList(); + } + } + }); +}); +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#newsListBox').html(' '); + getNewList(); +} + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function viewNews(id){ + $.post(WST.U('mobile/news/getNews'),{id:id},function(data){ + var json = WST.toJson(data); + $('#createTime').html(json.createTime); + $('#articleTitle').html(json.articleTitle); + $('#articleContent').html(json.articleContent); + $('#likeNum').html(json.likeNum); + $('#articleId').val(json.articleId); + // 计算弹出层是否需要滚动条 + var sHeight = WST.pageHeight(); + var tHeight = $('#articleTitle').height(); + var cHeight = $('#articleContent').height(); + $('#content').css('height',sHeight-tHeight+'px'); + if(json.likeState == 1){ + $('#like1').hide(); + $('#like').show(); + $('#likeNum2').html(json.likeNum); + $(".icon-like1").removeClass('icon-like1').addClass('icon-like2'); + }else{ + $('#like').hide(); + $('#like1').show(); + $(".icon-like2").removeClass('icon-like2').addClass('icon-like1'); + } + dataShow(); + }) +} +function like(){ + var articleId = $('#articleId').val(); + $.post(WST.U('mobile/News/like'),{id:articleId},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $(".icon-like1").removeClass('icon-like1').addClass('icon-like2'); + $num = parseInt($('#likeNum').html()); + $num = $num+1; + $('#like1').hide(); + $('#like').show(); + $('#likeNum2').html($num); + } + }) +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/base.html b/hyhproject/mobile2/view/default/base.html new file mode 100755 index 0000000..5b68720 --- /dev/null +++ b/hyhproject/mobile2/view/default/base.html @@ -0,0 +1,28 @@ +<html> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> +<meta name="format-detection" content="telephone=no"> +<title>{block name="title"}{:WSTConf('CONF.mallName')}{/block}</title> +<link rel="stylesheet" href="__MOBILE__/frozenui/css/frozen.css"> +<link rel="stylesheet" href="__MOBILE__/css/common.css?v={$v}"> +{block name="css"}{/block} +<script type='text/javascript' src='__MOBILE__/frozenui/js/zepto.min.js'></script> +<script type='text/javascript' src='__MOBILE__/frozenui/js/frozen.js'></script> +<script type='text/javascript' src='__MOBILE__/js/laytpl/laytpl.js?v={$v}'></script> +<script src="__MOBILE__/js/echo.min.js"></script> +<script type='text/javascript' src='__MOBILE__/js/common.js?r='+ Math.random()></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","MOBILE":"__MOBILE__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY":"{:WSTConf('CONF.smsVerfy')}","SMS_OPEN":"{:WSTConf('CONF.smsOpen')}","MALL_LOGO":"{:WSTConf('CONF.mallLogo')}","GOODS_LOGO":"{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO":"{:WSTConf('CONF.shopLogo')}","USER_LOGO":"{:WSTConf('CONF.userLogo')}","IS_LOGIN":"{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","ROUTES":'{:WSTRoute()}',"IS_CRYPTPWD":"{:WSTConf('CONF.isCryptPwd')}"} +</script> +</head> +<body ontouchstart=""> +{block name="header"}{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="main"}主内容{/block} +{block name="include"}{/block} +{block name="js"}{/block} +</body> +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/bash.html b/hyhproject/mobile2/view/default/bash.html new file mode 100755 index 0000000..e34e85e --- /dev/null +++ b/hyhproject/mobile2/view/default/bash.html @@ -0,0 +1,243 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="UTF-8"> + <title></title> + <script src="__MOBILE__/js/common_xs.js" type="text/javascript" charset="utf-8"></script> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/global-lxy.css" /> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/bash.css" /> + </head> + + <body> + <div class="banner"> + <img src="__MOBILE__/img/ac3_header_bg.png" /> + </div> + + <div class="bash_yhj clearfix"> + <div class="bash_yhj_a"> + <img src="__MOBILE__/img/ac3_yhq.png" /> + </div> + <div class="bash_yhj_a"> + <img src="__MOBILE__/img/ac3_yhq.png" /> + </div> + <div class="bash_yhj_a"> + <img src="__MOBILE__/img/ac3_yhq.png" /> + </div> + <div class="bash_yhj_a"> + <img src="__MOBILE__/img/ac3_yhq.png" /> + </div> + </div> + + <div class="shopping"> + <img src="__MOBILE__/img/ac3_title.png" /> + </div> + + <div class="choujiang"> + <img src="__MOBILE__/img/shan.png" class="cj_shan on" /> + <div class="cj_con clearfix" id="box"> + <div class="content content-1"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-2"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-3"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-8"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-click"> + <div id="text"> + <img src="__MOBILE__/img/ac3_button1.png" /> + </div> + </div> + <div class="content content-4"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-7"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-6"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + <div class="content content-5"> + <img src="__MOBILE__/img/ac3_bg1.png" /> + <div class="content_con"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + </div> + </div> + <div class="num">您 今 天 还 剩 <span class="number">3</span> 次 抽 奖 机 会</div> + </div> + + <div class="baqi"> + <img src="__MOBILE__/img/ac3_title1.png" /> + </div> + + <div class="baqi_man"> + <div class="man_sp clearfix"> + <div class="man_cp"> + <p class="p1">外套专区</p> + <p class="p2">买就减10元</p> + <p class="p2">外套专区</p> + <div class="go">GO</div> + </div> + <div class="man_cp"> + <p class="p1">外套专区</p> + <p class="p2">买就减10元</p> + <p class="p2">外套专区</p> + <div class="go">GO</div> + </div> + <div class="man_cp"> + <p class="p1">外套专区</p> + <p class="p2">买就减10元</p> + <p class="p2">外套专区</p> + <div class="go">GO</div> + </div> + <div class="man_cp"> + <p class="p1">外套专区</p> + <p class="p2">买就减10元</p> + <p class="p2">外套专区</p> + <div class="go">GO</div> + </div> + </div> + + <div class="man_tejia"> + <p class="p1">外套专区</p> + <p class="p2">买就减10元</p> + <p class="p2">外套专区</p> + <div class="go">GO</div> + </div> + </div> + + <div class="liaomei"> + <img src="__MOBILE__/img/ac3_title2.png"/> + </div> + + <div class="liao_gl"> + <div class="gl_cp clearfix"> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + </div> + </div> + + <div class="liaomei"> + <img src="__MOBILE__/img/ac3_title3.png"/> + </div> + + <div class="liao_gl"> + <div class="gl_cp clearfix"> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + <div class="gl_sp"> + <img src="__MOBILE__/img/gua.jpg"/> + <p class="p1">夏季男神</p> + <p class="p2">¥258</p> + </div> + </div> + </div> + + </body> + <script src="__MOBILE__/js/jquery.min.js" type="text/javascript" charset="utf-8"></script> + <script type="text/javascript"> + $('.content').height($('.content').width() * 123 / 165 + 'px') + $(window).resize(function() { + $('.content').height($('.content').width() + 'px') + }) + + function time(a) { + return function() { + if(a > 8) { + a = parseInt(a % 8) + if(a == 0) { + a = 8 + } + } + $('.content').removeClass('active'); + $('.content-' + a).addClass('active'); + $('.zz_img').toggleClass('on'); + } + } + // 在旋转的时候不能再次被点击 + var t = true + $('.content-click').click(function() { + if(t) { + t = false; + // 产生随机数 + var prize = Math.ceil(Math.random() * ($('.content').length - 1)); + // 控制概率,永远不是8 + if(prize == 8) { + prize = Math.ceil(Math.random() * ($('.content').length - 2)); + } + if($('.number').html() > 0) { + $('.number').html($('.number').html() - 1) + // 默认先转3圈 + prize += 32 + for(var i = 1; i <= prize; i++) { + setTimeout(time(i), 6 * i * i); + } + setTimeout(function() { + t = true; + }, 6 * prize * prize) + } else { + alert('您没有抽奖机会了') + } + } + }) + </script> + +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/brands.html b/hyhproject/mobile2/view/default/brands.html new file mode 100755 index 0000000..4ef7bb6 --- /dev/null +++ b/hyhproject/mobile2/view/default/brands.html @@ -0,0 +1,34 @@ +{extend name="default/base" /} +{block name="title"}品牌街 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/shops_list.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "品牌街"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <ul id="info-list"></ul> + <div class="wst-clear"></div> + </section> +<script id="list" type="text/html"> +{{# for(var i=0; i<d.length; i++){ }} + <li class="wst-brands {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}"> + <div class="wst-brands_img"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({{ d[i].brandId }});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d[i].brandImg }}" title="{{ d[i].brandName }}"> + </a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({{ d[i].brandId }});"> + <span class="ui-nowrap-flex">{{ d[i].brandName }}</span> + </a> + </div> + </li> +{{# } }} +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/brands.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/carts.html b/hyhproject/mobile2/view/default/carts.html new file mode 100755 index 0000000..fa03e7f --- /dev/null +++ b/hyhproject/mobile2/view/default/carts.html @@ -0,0 +1,105 @@ +{extend name="default/base" /} +{block name="title"}购物车 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/carts.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <a href="{:url('mobile/index/index')}"><i class="ui-icon-return"></i></a><h1>购物车</h1> + {if(count($carts['carts'])>0)} + <span id="edit" class="edit" onclick="javascript:edit(0);">编辑</span><span id="complete" class="edit" onclick="javascript:edit(1);" style="display: none;">完成</span> + <div class="wst-ca-more" onclick="javascript:inMore();">···</div> + {/if} + </header> + <div class="wst-go-more" id="arrow" style="display: none;"><i class="arrow"></i> + <ul class="ui-row ui-list-active more"> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/index/index')}"><i class="home"></i><p>首页</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/goodscats/index')}"><i class="category"></i><p>分类</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/favorites/goods')}"><i class="follow"></i><p>关注</p></a></div></li> + <li class="ui-col"><div class="column"><a href="{:url('mobile/users/index')}"><i class="user"></i><p>我的</p></a></div></li> + </ul> + </div> + <div class="wst-ca-layer" id="layer" onclick="javascript:inMore();"></div> +{/block} +{block name="footer"} +{if(count($carts['carts'])>0)} + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-ca-se"> + <div class="wst-ca-layout"> + <div class="wst-ca-10 totall"><i class="ui-icon-choose ui-icon-unchecked-s" cartId="0" mval="0"></i>&nbsp;</div> + <div class="wst-ca-90 totalr"> + <span>全选</span> + <button id="settlement" class="button" type="button" onclick="javascript:toSettlement();">结算</button> + <button id="delete" class="button" type="button" onclick="javascript:deletes();" style="display: none;">删除</button> + <span id="total" class="total">合计:<span id="totalMoney" class="price"><span>¥ </span>{php}echo sprintf("%.2f", $carts['goodsTotalMoney']);{/php}</span></span> + </div> + </div> + </div> + </footer> +{else} +{include file="default/footer" /} +{/if} +{/block} +{block name="main"} + <section class="ui-container"> + {if(count($carts['carts'])>0)} + <input type="hidden" name="" value="0" id="buyNum_0" autocomplete="off"> + <input type="hidden" name="" value="{php}echo count($carts['carts'])+1;{/php}" id="totalshop" autocomplete="off"> + {volist name="$carts['carts']" id="ca" key="k"} + <div class="wst-ca-s"> + <div class="wst-ca-layout shop"> + <div class="wst-ca-10 shopl"><i class="ui-icon-chooses ui-icon-unchecked-s" childrenId="clist{$k}" cartId="0" mval="0"></i>&nbsp;</div> + <div class="wst-ca-90 shopr"><p class="ui-nowrap" onclick="javascript:WST.intoShops({$ca['shopId']});"><i class="shopicon"></i>{$ca['shopName']}</p></div> + </div> + {volist name="ca['list']" id="li"} + {:hook('mobileDocumentCartGoodsPromotion',['goods'=>$li])} + <div class="wst-ca-layout goods{if($li['goodsStock']==0)} nogoods{/if} j-g{$li["cartId"]}"> + <div class="wst-ca-10 goodsl"> + <i id="gchk_{$li["cartId"]}" class="ui-icon-chooseg {if($li['isCheck'])}ui-icon-success-block wst-active{else}ui-icon-unchecked-s{/if} clist{$k}" cartId="{$li['cartId']}" mval="{$li['shopPrice']}"></i>&nbsp;</div> + <div class="wst-ca-90"> + <div class="wst-ca-24 goodsr"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </div> + <div class="wst-ca-76"> + <div class="info"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"><p class="name">{$li['goodsName']}</p></a><p class="price">¥ {$li['shopPrice']}</p> + {if($li['specNames'])} + <p class="spec">规格: + {volist name="li['specNames']" id="sp"} + {$sp['catName']}:{$sp['itemName']} + {/volist} + </p> + {/if} +<div class="wst-buy_l"> + <input class="wst-buy_l1" type="button" value="-" onclick='javascript:WST.changeIptNum(-1,"#buyNum",{$li["cartId"]},"statCartMoney")'><input id="buyNum_{$li['cartId']}" class="wst-buy_l2" data-min='1' data-max='{$li["goodsStock"]}' type="number" value="{$li['cartNum']}" autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum",{$li["cartId"]},"statCartMoney")'><input class="wst-buy_l3" type="button" value="+" onclick='javascript:WST.changeIptNum(1,"#buyNum",{$li["cartId"]},"statCartMoney")'> +</div> + </div> + </div> + </div> + <span id="noprompt{$li['cartId']}" class="noprompt" style="display: none;"></span> + </div> + {/volist} + <div class="wst-ca-layout bottom"> + <p class="wst-ca-50">共 {php}echo count($ca['list']);{/php} 件商品</p><p id="tprice_{$k}" class="wst-ca-50 price"><span>¥ </span>{php}echo sprintf("%.2f", $ca['goodsMoney']);{/php}</p> + </div> + </div> + {/volist} + {else} + <div class="wst-prompt-icon" style="width: 1rem;height: 1rem;"><img src="__MOBILE__/img/nothing-cart.png" style="width: 1rem;height: 1rem;"></div> + <div class="wst-prompt-info"> + <p>购物车内还没商品哦,去逛逛吧~</p> + <button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button> + </div> + {/if} + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/address.css b/hyhproject/mobile2/view/default/css/address.css new file mode 100755 index 0000000..c99bd78 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/address.css @@ -0,0 +1,54 @@ +@CHARSET "UTF-8"; +.wst-listse{margin-top:8px;font-size:.15rem} +.wst-list-infose1{width:96%;padding-top:10px;padding-bottom:10px;border-bottom:1px solid #ededed} +.wst-list-infose1 span{float:left;width:100%} +.wst-list-infose1 .name{color:#232228} +.wst-list-infose1 .address{color:#808080} +.wst-ad-operate{padding:10px;height:0.22rem;line-height:0.25rem;font-size:.14rem} +.wst-ad-operate .left{float:left;margin-left:22px} +.wst-ad-operate .right{float:right} +.wst-ad-operate i{float:left;width:22px;height:22px} +.j-operate{z-index:100;float:left;width:22px;height:22px;margin:-32px 0 0 9px} +.j-operate.default,.ui-form-itemin .operate .default{background:url(../img/icon_adds_users.png) -11px -5px no-repeat;background-size:645%} +.j-operate.nodefault,.ui-form-itemin .operate .nodefault{background:url(../img/icon_adds_users.png) -41px -5px no-repeat;background-size:645%} +.wst-ad-operate .edit{background:url(../img/icon_adds_users.png) -71px -5px no-repeat;background-size:631%} +.wst-ad-operate .delete{background:url(../img/icon_adds_users.png) -106px -5px no-repeat;background-size:631%} +.wst-ad-form{margin-top:8px} +.ui-form-itemin{position:relative;font-size:16px;height:44px;line-height:44px;padding:1px 10px;font-size:.18rem;background:#fff} +.ui-form-itemin .word{color:#232228;font-size:.15rem} +.ui-form-itemin input{float:right;width:75%;height:35px;border:0;margin-top:4px;font-size:.15rem} +.ui-form-itemin label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio){position:absolute;text-align:left;box-sizing:border-box} +.ui-form-itemin .address{float:right;width:75%;height:35px;line-height:35px;margin-top:4px;font-size:.15rem} +.ui-form-itemin .ui-select-group{margin-top:5px} +.wst-selectin{float:left;position:relative;width:72%} +.wst-address_set{width:100%;height:40px;position:fixed;z-index:100;left:0;bottom:0} +.wst-ad-line{padding:0 10px} +.wst-ad-line p{border-bottom:1px solid #edebeb} +.wst-ad-submit{margin-top:20px} +.wst-ad-submit .button{margin:0 auto;width:93%;font-size:.15rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-ad-submit .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-ad-operate{font-size:.15rem} +.ui-switch input:checked:before{border-color: #ff3c3c;box-shadow: #ff3c3c 0px 0px 0px 16px inset;background-color: #ff3c3c;background-color: #ff3c3c;} +.ui-switch input:before{height: 26px;} +.ui-switch input:checked:after {left: 26px;} +.ui-switch input:after {width: 26px;height: 26px;} +.ui-switch{margin-top: -14px;} +.iziModal{background:#f6f6f8} +.iziModal-button-close i{font-size: 22px;line-height:41px;} +.iziModal .iziModal-header-title{font-size: 16px;height:22px;line-height:22px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;left:0;bottom:-285px;width:100%;min-height:50%;background:#fff;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1;} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:10px 10px 20px 10px} +.wst-fr-box .option{float:left;width:100%;border-bottom:1px solid #edebeb} +.wst-fr-box .option p{float:left;width:50px;height:26px;line-height:26px;padding:0 5px;text-align:center} +.wst-fr-box .option .active{border-bottom:1px solid #de0301} +.wst-fr-box .list{padding-top:5px;font-size:0.14rem;} +.wst-fr-box .list.hide{display:none} +.wst-fr-box .list p{padding:5px 0} +.wst-fr-box .list .active{color:#de0301} +.wst-ad-footer{position: fixed;z-index: 100;bottom:0;left: 0;width: 100%;height: 44px;background: #FFF;border-top: 1px solid #e8e8e8;} +.wst-ad-footer .button{display: block;margin: 0 auto;margin-top:2px;width: 90%;font-size: .15rem;height: 40px;line-height: 40px;color: #fff;background: #e00102;border-radius: 5px;border-bottom: 1px solid #e00102;} +.wst-ad-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/articles.css b/hyhproject/mobile2/view/default/css/articles.css new file mode 100755 index 0000000..77e7ebb --- /dev/null +++ b/hyhproject/mobile2/view/default/css/articles.css @@ -0,0 +1,44 @@ +@CHARSET "UTF-8"; +body{font-size:.15rem} +.news-time{margin-top:10px;text-align:right;font-size:.13rem;padding-right: 10px;} +.news-content-box{background:#fff;padding: 10px 0 35px 0;} +.news-content{max-height:100px} +.news-title{font-weight:bold;padding: 10px;font-size: 20px;padding-bottom: 0px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background:#f6f6f8;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:16px} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{overflow-y:scroll;background:#fff} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.title{background:#fff} +.view-content{background:#fff} +.news-time{margin:5px 0;padding: 0.05rem 0.1rem;background:#ffffff;} +.wst-info{padding:0.04rem;font-weight: bold;font-size:0.18rem;color: #051B28;padding-left: 0.06rem;height:55px;} +.wst-max-info{padding:0.04rem;padding-top: 0rem; font-weight: bold;font-size: 0.140rem;color: #051B28;padding-left: 0.06rem;} +.wst-mix-info{padding-left: 0.06rem;padding-right: 0.06rem;color: #999;font-size: 10px;} +.max-remind{height: 16px;} +.max-img{position: relative;padding-top: 40%; background-size: 30%;overflow: hidden;margin-bottom: 8px;} +.max-img a img{position: absolute;width: 100%;top: 50%;left: 50%; transform: translate(-50%, -50%);} +.wst-model{background-color: #fff;padding: 0.01rem;margin-top: 10px;} +.wst-right-align{text-align: right;} +.wst-mix-cont{font-size: 0.12rem;color: #999;padding-top: 10px;} +.view-content img{width: 100%;} +.wst-like{padding-bottom: 50px;position: relative;} +.icon-like1{background: url(../img/icon_like1.png) 5px no-repeat;background-size: 20px 20px;border-radius: 10px; position: absolute;top: 0;left: 0;width: auto;height: 30px;margin-left: 40%;margin-bottom: 20px; border: 1px solid red;} +.icon-like2{background: url(../img/icon_like2.png) 5px no-repeat;background-size: 20px 20px;border-radius: 10px; position: absolute;top: 0;left: 0;width: auto;height: 30px;margin-left: 40%;margin-bottom: 20px; border: 1px solid red;} +.like_num{display: inline-block;padding: 5px;padding-left: 32px;padding-top: 6px; color: #ED0000;} +.wst-bor-mix-img{padding: 0.01rem;padding-bottom: 0;} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.ui-tab{position:fixed;width:100%;z-index:100;left:0;top:41px} +.order-tab{width:100%;height:35px;line-height:35px;padding:0;background:#fff;overflow-x:scroll} +.order-tab::-webkit-scrollbar{width:1px;height:1px;background-color:#fff} +.order-tab::-webkit-scrollbar-thumb{background-color:#fff} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.item-head{font-size: .15rem;padding:10px 0;border-bottom:1px solid #f2f1f1} +.item-head p{padding-left:20px;position: relative;} +.item-head .shopicon{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.ui-tab-nav li.tab-item{font-size:.15rem;height:35px;line-height:35px;padding:0 5px;text-align:center;} +.ui-tab-nav li.tab-curr{color:#de4943;;height:34px;border-bottom:2px solid #de4943;} +.ui-header ~ .ui-container{border-top: 25px solid transparent;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/bash.css b/hyhproject/mobile2/view/default/css/bash.css new file mode 100755 index 0000000..4882d9c --- /dev/null +++ b/hyhproject/mobile2/view/default/css/bash.css @@ -0,0 +1,215 @@ +body { + background: #070503; +} +.banner img { + width: 6.4rem; + height: 8.5rem; +} +.bash_yhj { + margin-left: 0.8rem; +} +.bash_yhj_a { + margin-right: 0.1rem; + float: left; +} +.bash_yhj .bash_yhj_a img { + width: 1.14rem; + height: 1.95rem; +} +.shopping { + margin-left: 1.16rem; + margin-top: 0.35rem; + margin-bottom: 0.35rem; +} +.shopping img { + width: 4.03rem; + height: 0.62rem; +} +.choujiang { + width: 6.13rem; + height: 5.29rem; + background: url(../img/ac3_bg2.png) no-repeat; + background-size: 100% ; + margin-left: 0.14rem; + position: relative; +} +.choujiang .cj_shan { + width: 6.4rem; + height: 5.29rem; + position: absolute; + left: -0.12rem; + top: -0.1rem; +} +.cj_con { + width: 82.8%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 18%; + z-index: 11; + padding: 0.5% 0 0 1%; +} +.content { + width: 32.3%; + float: left; + margin: 0 1% 0.5% 0; + position: relative; +} +.content img { + width: 100%; +} +.num { + width: 98%; + text-align: center; + position: absolute; + bottom: 4%; + color: #FFFFFF; + font-size: 13.2px; +} +.content_con { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 12; +} +.cj_con .active .content_con { + background: rgba(255, 255, 255, 0.8); + border-radius: 10%; +} +.content_con img { + width: 100%; + height: 100%; +} +.choujiang .on { + transform: rotateY(180deg); +} +.baqi { + margin-left: 1.16rem; + margin-bottom: 0.4rem; + margin-top: 0.4rem; +} +.baqi img { + width: 4rem; + height: 0.89rem; +} +.baqi_man { + width: 6.4rem; + margin-left: 0.14rem; +} +.baqi_man .man_cp { + width: 3rem; + height: 1.64rem; + background: url(../img/ac3_bg3.png) no-repeat; + background-size: 100%; + float: left; + margin-right: 0.1rem; + margin-bottom: 0.15rem; +} +.man_cp .p1 { + font-family: "微软雅黑"; + font-size: 0.28rem; + color: #fff; + margin-top: 0.2rem; + margin-left: 0.1rem; + margin-bottom: 0.15rem; +} +.man_cp .p2 { + font-family: "微软雅黑"; + font-size: 0.18rem; + color: #fff; + margin-left: 0.1rem; +} +.man_cp .go { + width: 0.58rem; + height: 0.22rem; + background: #fff; + border-radius: 10px; + text-align: center; + line-height: 0.22rem; + color: #000000; + font-size: 0.18rem; + margin-left: 0.28rem; + margin-top: 0.13rem; +} +.man_tejia { + width: 6.13rem; + height: 1.48rem; + background: url(../img/ac3_bg4.png) no-repeat; + background-size: 100% ; + padding-top: 0.2rem; +} +.man_tejia .p1 { + font-family: "微软雅黑"; + font-size: 0.28rem; + color: #fff; + margin-left: 0.1rem; + margin-bottom: 0.15rem; +} +.man_tejia .p2 { + font-family: "微软雅黑"; + font-size: 0.18rem; + color: #fff; + margin-left: 0.1rem; +} +.man_tejia .go { + width: 0.58rem; + height: 0.22rem; + background: #fff; + border-radius: 10px; + text-align: center; + line-height: 0.22rem; + color: #000000; + font-size: 0.18rem; + margin-left: 0.28rem; + margin-top: 0.13rem; +} +.liaomei { + margin-left: 1.16rem; + margin-bottom: 0.4rem; + margin-top: 0.4rem; +} +.liaomei img { + width: 4rem; + height: 0.89rem; +} +.liao_gl { + width: 6.4rem; + margin-left: 0.05rem; +} +.gl_sp { + width: 3.1rem; + height: 4.28rem; + background: url(../img/ac3_bg5.png) no-repeat; + background-size: 100% ; + position: relative; + float: left; + margin-right: 0.09rem; + margin-bottom: 0.09rem; +} +.gl_sp img { + width: 2.92rem; + height: 3.51rem; + position: absolute; + top: 0.09rem; + left: 0.09rem; +} +.gl_sp .p1 { + font-family: "微软雅黑"; + font-size: 0.18rem; + color: #fff; + position: absolute; + bottom: 0.4rem; + left: 0.09rem; +} +.gl_sp .p2 { + font-family: "微软雅黑"; + font-size: 0.18rem; + font-weight: 900; + color: #fff; + position: absolute; + bottom: 0.08rem; + left: 0.09rem; +} diff --git a/hyhproject/mobile2/view/default/css/bash.less b/hyhproject/mobile2/view/default/css/bash.less new file mode 100755 index 0000000..66933c6 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/bash.less @@ -0,0 +1,244 @@ +body{ + background: #070503; +} + +.banner img{ + width: 640/100rem; + height: 850/100rem; +} + +.bash_yhj{ + margin-left: 80/100rem; +} + +.bash_yhj_a{ + margin-right: 10/100rem; + float: left; +} + +.bash_yhj .bash_yhj_a img{ + width: 114/100rem; + height: 195/100rem; +} + +.shopping{ + margin-left: 116/100rem; + margin-top: 35/100rem; + margin-bottom: 35/100rem; +} + +.shopping img{ + width: 403/100rem; + height: 62/100rem; +} + +.choujiang{ + width: 613/100rem; + height: 529/100rem; + background: url(../img/ac3_bg2.png) no-repeat; + background-size:100% ; + margin-left: 14/100rem; + position: relative; +} + + +.choujiang .cj_shan{ + width: 640/100rem; + height: 529/100rem; + position: absolute; + left: -12/100rem; + top: -10/100rem; +} + +.cj_con{ + width: 82.8%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 18%; + z-index: 11; + padding: 0.5% 0 0 1%; +} +.content{ + width: 32.3%; + float: left; + margin: 0 1% 0.5% 0; + position: relative; +} +.content img{ + width: 100%; +} +.num{ + width: 98%; + text-align: center; + position: absolute; + bottom: 4%; + color:#FFFFFF; + font-size: 13.2px; +} +.content_con{ + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 12; +} +.cj_con .active .content_con{ + background: rgba(255,255,255,0.8); + border-radius: 10%; +} +.content_con img{ + width: 100%; + height: 100%; +} + +.choujiang .on{ + transform: rotateY(180deg); +} + +.baqi{ + margin-left: 116/100rem; + margin-bottom: 40/100rem; + margin-top: 40/100rem; +} + +.baqi img{ + width: 400/100rem; + height: 89/100rem; +} + +.baqi_man{ + width: 640/100rem; + margin-left: 14/100rem; +} + +.baqi_man .man_cp{ + width: 300/100rem; + height: 164/100rem; + background: url(../img/ac3_bg3.png) no-repeat; + background-size: 100%; + float: left; + margin-right: 10/100rem; + margin-bottom: 15/100rem; +} + +.man_cp .p1{ + font-family: "微软雅黑"; + font-size: 28/100rem; + color: #fff; + margin-top: 20/100rem; + margin-left: 10/100rem; + margin-bottom: 15/100rem; +} + +.man_cp .p2{ + font-family: "微软雅黑"; + font-size: 18/100rem; + color: #fff; + margin-left: 10/100rem; +} + +.man_cp .go{ + width: 58/100rem; + height: 22/100rem; + background: #fff; + border-radius: 10px; + text-align: center; + line-height: 22/100rem; + color: #000000; + font-size: 18/100rem; + margin-left: 28/100rem; + margin-top: 13/100rem; +} + +.man_tejia{ + width: 613/100rem; + height: 148/100rem; + background: url(../img/ac3_bg4.png) no-repeat; + background-size: 100% ; + padding-top: 20/100rem; +} + +.man_tejia .p1{ + font-family: "微软雅黑"; + font-size: 28/100rem; + color: #fff; + margin-left: 10/100rem; + margin-bottom: 15/100rem; +} + +.man_tejia .p2{ + font-family: "微软雅黑"; + font-size: 18/100rem; + color: #fff; + margin-left: 10/100rem; +} + +.man_tejia .go{ + width: 58/100rem; + height: 22/100rem; + background: #fff; + border-radius: 10px; + text-align: center; + line-height: 22/100rem; + color: #000000; + font-size: 18/100rem; + margin-left: 28/100rem; + margin-top: 13/100rem; +} + +.liaomei{ + margin-left: 116/100rem; + margin-bottom: 40/100rem; + margin-top: 40/100rem; +} + +.liaomei img{ + width: 400/100rem; + height: 89/100rem; +} + +.liao_gl{ + width: 640/100rem; + margin-left: 5/100rem; +} + +.gl_sp{ + width: 310/100rem; + height: 428/100rem; + background: url(../img/ac3_bg5.png) no-repeat; + background-size:100% ; + position: relative; + float: left; + margin-right: 9/100rem; + margin-bottom: 9/100rem; +} + +.gl_sp img{ + width: 292/100rem; + height: 351/100rem; + position: absolute; + top: 9/100rem; + left: 9/100rem; +} + +.gl_sp .p1{ + font-family: "微软雅黑"; + font-size: 18/100rem; + color: #fff; + position: absolute; + bottom: 40/100rem; + left: 9/100rem; +} +.gl_sp .p2{ + font-family: "微软雅黑"; + font-size: 18/100rem; + font-weight: 900; + color: #fff; + position: absolute; + bottom: 8/100rem; + left: 9/100rem; +} + diff --git a/hyhproject/mobile2/view/default/css/carts.css b/hyhproject/mobile2/view/default/css/carts.css new file mode 100755 index 0000000..aa8cf0a --- /dev/null +++ b/hyhproject/mobile2/view/default/css/carts.css @@ -0,0 +1,60 @@ +@CHARSET "UTF-8"; +.wst-ca-layout{display:block;overflow:hidden} +.wst-ca-10{float:left;width:10%;box-sizing:border-box} +.wst-ca-90{float:left;width:90%;box-sizing:border-box} +.wst-ca-24{float:left;width:24%;box-sizing:border-box} +.wst-ca-76{float:left;width:75%;box-sizing:border-box} +.wst-ca-50{float:left;width:50%;box-sizing:border-box} +.wst-ca-s{background:#fff;padding:10px 5px;margin-top:10px;font-size:.15rem} +.wst-ca-s .shop{height:26px;line-height:26px;padding-bottom:3px;border-bottom:1px solid #edebeb} +.wst-ca-s .goods{padding:3px 0;border-bottom:1px solid #f1f1f1} +.wst-ca-s .nogoods{border:1px solid #de0301;background:#f8eeee} +.wst-ca-s .nogoods .noprompt{position:absolute;left:0;top:0;color:#fff;font-size:.15rem;background:#e00102} +.wst-ca-s .shopr{height:26px;line-height:26px} +.wst-ca-s .shopr p{float:left;width:86%;} +.wst-ca-s .shopr .shopicon{float:left;width:22px;height:26px;position: relative;background: url(../img/icon_dp.png) 0px 4px no-repeat;background-size: 87%;} +.wst-ca-s .shopl,.wst-ca-s .shopr,.wst-ca-s .goodsl,.wst-ca-se .totall,.wst-ca-s .nogoods{position:relative} +.wst-ca-s .shopl i{position:absolute;left:-2px;top:-9px} +.wst-ca-s .info{padding-left:5px} +.wst-ca-s .goodsl i{position:absolute;left:-2px;top:50%} +.wst-ca-s .goodsr .img{float:left;width:100%;height:70px;text-align:center;vertical-align:middle;display:block} +.wst-ca-s .goodsr .img a{width:100%;height:70px;display:table-cell;vertical-align:middle} +.wst-ca-s .goodsr .img a img{max-width:70px;max-height:70px} +.wst-ca-s .info .name{float:left;width:72%;font-size:.145rem;font-weight: 700;} +.wst-ca-s .info .price{float:right;width:28%;text-align:right;font-size:.13rem} +.wst-ca-s .info .spec{float:left;width:100%;padding:3px 0;color:#a6a6a6} +.wst-buy_l{float:right;width:100%;margin-top:3px;text-align:right} +.wst-buy_l1,.wst-buy_l3{width:30px;height:28px;background:#FFF;border:0;border:1px solid #ddd} +.wst-buy_l1{border-right:1px solid #fff;} +.wst-buy_l3{border-left:1px solid #fff;} +.wst-buy_l1{border-top-left-radius:3px;border-bottom-left-radius:3px} +.wst-buy_l3{border-top-right-radius:3px;border-bottom-right-radius:3px} +.wst-buy_l2{width:38px;height:28px;border:1px solid #ddd;text-align:center;color:#e00102} +.wst-buy_l1:focus,.wst-buy_l3:focus{color:#e00102} +.wst-buy_l2:focus{width:38px;height:28px;border:1px solid #e00102} +.wst-ca-s .bottom{height:23px;line-height:23px;font-size:.158rem;margin-top:8px} +.wst-ca-s .bottom .price{color:#de0202;text-align:right;} +.wst-ca-s .bottom .price span{font-size:0.13rem;} +.wst-ca-se{padding:0 5px;font-size:.165rem;height:42px;line-height:42px} +.wst-ca-se .totall i{position:absolute;left:-2px;top:-2px} +.wst-ca-se .totalr span{color:#051b28;} +.wst-ca-se .total{float:right;margin-right:6px} +.wst-ca-se .total .price{color:#de0202;} +.wst-ca-se .totalr .price span{color:#de0202;font-size:.13rem;} +.wst-ca-se .totalr .button{float:right;width:31%;height:33px;color:#fff;margin-top:4px;font-size:.18rem;background:#e00102;font-size:.165rem;border-radius:3px;border-bottom:1px solid #e00102} +.wst-ca-se .totalr .button:not(.disabled):not(:disabled):active,.wst-ca-se .totalr .button.active{color:#fbd6d6;background:#f25a5b;background-clip:padding-box} +.wst-header .edit{right: 33px;} +.wst-ca-layer{position: fixed;left: 0px;top: 0px;width: 100%;height: 100%;z-Index: 9999;display: none;} +.wst-ca-more{ position: absolute;top: 0;right: 8px;color: #59595c;min-width: 30px;height: 41px;line-height: 41px;font-size: 20px;font-weight: 700;text-align: right;} +.wst-go-more{position: fixed;top: 29px;right: 1px;z-Index: 10000;width: 32%;} +.wst-go-more .arrow{position: absolute;top:-6px;right:7px;display: block;width: 0;height: 0;line-height: 0;border-width: 0.11rem;border-color: transparent transparent rgba(85,85,85,0.95) transparent;border-style: dashed dashed solid dashed;} +.wst-go-more .more{margin-top:13px;border-radius: 3px;background: rgba(85,85,85,0.95);} +.wst-go-more .more .column{width: 80px;display: block;margin: 0 auto;height: 23px;line-height: 23px;padding:10px 0px;} +.wst-go-more .more .line{border-bottom: 1px solid #f2f2f2;} +.wst-go-more .more i{float: left;width: 23px;height: 23px;margin-left:2px;position: relative;} +.wst-go-more .home{background: url(../img/icon_bottomnav.png) 0px -24px no-repeat;background-size: 1062%;} +.wst-go-more .category{background: url(../img/icon_bottomnav.png) -53px -23px no-repeat;background-size: 1010%;} +.wst-go-more .follow{background: url(../img/icon_bottomnav.png) -161px -23px no-repeat;background-size: 1010%;} +.wst-go-more .user{background: url(../img/icon_bottomnav.png)-216px -23px no-repeat;background-size: 1010%;} +.wst-go-more .more p{float: left;width: 55px;color: #fff;font-size:0.13rem;} +.wst-go-more .more li:active{padding-left:2px;background: #252525;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/cashconfigs.css b/hyhproject/mobile2/view/default/css/cashconfigs.css new file mode 100755 index 0000000..47ca418 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/cashconfigs.css @@ -0,0 +1,43 @@ +@CHARSET 'UTF-8'; +body{background:#f2f2f2;font-size:.15rem} +.ui-icon-return ~ h1{z-index:-1;position:relative} +.add{position:absolute;right:0;top:0;display:block;color:black;padding-right:10px} +.ui-row{border:1px solid #e2e2e2;border-radius:5px;margin:5px;padding:10px 5px;background:#fff} +.wst-ca-accno{color: #de0202;font-size:.17rem;font-weight: 700;letter-spacing:2px;} +.wst-ca-info{color: #999;font-size:.13rem;} +.c-tr{float: right;line-height:30px;margin-top:26%;} +.delete-icon{width:25px;height:30px;display:block;float:left;background:url(../img/icon_adds_users.png) no-repeat;background-position:-86px 0;background-size:cover} +.wst-ad-form{margin-top:8px} +.wst-ca-choice{float: right;width: 75%;padding: 2px 2px 2px 0px;margin-top: 4px;height: 36px;border-radius: 2px;font-size:.15rem;border: 0;background:#fff;} +.ui-form-itemin{position:relative;font-size:16px;height:44px;line-height:44px;padding:1px 10px;font-size:.18rem;background:#fff} +.ui-form-itemin .word{color:#232228;font-size:.15rem} +.ui-form-itemin input{float:right;width:75%;height:35px;border:0;margin-top:4px;font-size:.15rem;} +.ui-form-itemin label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio){position:absolute;text-align:left;box-sizing:border-box} +.ui-form-itemin .address{float:right;width:75%;height:35px;line-height:35px;margin-top:4px;font-size:.15rem;} +.ui-form-itemin .ui-select-group{margin-top:5px} +.wst-selectin{float:left;position:relative;width:72%} +.wst-address_set{width:100%;height:40px;position:fixed;z-index:100;left:0;bottom:0} +.wst-ad-line{padding:0 10px} +.wst-ad-line p{border-bottom:1px solid #edebeb} +.wst-ad-submit{margin-top:20px} +.wst-ad-submit .button{margin:0 auto;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-ad-submit .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-form-itemin .operate{font-size:.158rem} +.ui-form-itemin .operate i{float:left;width:22px;height:22px;margin-top:10px;margin-right:2px} +.ui-form-itemin .operate span{margin-left:5px} +.iziModal{background:#f6f6f8} +.iziModal-button-close i{font-size: 22px;line-height:41px;} +.iziModal .iziModal-header-title{font-size: 16px;height:22px;line-height:22px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;left:0;bottom:-285px;width:100%;min-height:50%;background:#fff;font-size:.14rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size: 15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:10px 10px 20px 10px} +.wst-fr-box .option{float:left;width:100%;border-bottom:1px solid #edebeb} +.wst-fr-box .option p{float:left;width:50px;height:26px;line-height:26px;padding:0 5px;text-align:center} +.wst-fr-box .option .active{border-bottom:1px solid #de0301} +.wst-fr-box .list{padding-top:5px} +.wst-fr-box .list.hide{display:none} +.wst-fr-box .list p{padding:5px 0} +.wst-fr-box .list .active{color:#de0301} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/cashdraws.css b/hyhproject/mobile2/view/default/css/cashdraws.css new file mode 100755 index 0000000..b991134 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/cashdraws.css @@ -0,0 +1,7 @@ +@CHARSET "UTF-8"; +body{font-size: 0.15rem;} +.score-line{border-bottom:1px solid #eaeaea;margin-bottom: 5px;margin-top: 5px;} +.score-time{color:#8c8c8c;font-size: 0.13rem;} +.score-detail{background: #fff;padding:5px;} +.score-detail-title{padding: 5px;padding-left:0px;font-size: 0.18rem;} +.score-text{padding:15px 0;text-align: right;color:#de0202;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/common.css b/hyhproject/mobile2/view/default/css/common.css new file mode 100755 index 0000000..df01058 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/common.css @@ -0,0 +1,87 @@ +@CHARSET "UTF-8"; +body{color:#232326;background-color:#f6f6f8} +a{color:#232326;} +button:before{border:none !important;} +.wst-header,.wst-in-header{border-bottom:1px solid #e5e5e5;background:#fff;height:41px;line-height:41px} +.wst-header h1{font-size: 16px;color: #222;} +.wst-header .ui-icon-return{left: 5px;font-size: 22px;height:41px;line-height:41px;} +.wst-border-bs{font-size:.16rem;border-bottom:1px solid #e6e6e6} +.wst-header .edit{position:absolute;top:0;right:8px;color:#59595c;min-width:32px;height:41px;line-height:41px;font-size:13px} +.wst-header .edit:active{color:#827f7f} +.wst-se-header2{height: 41px;background: #fff;padding-left:25px;border-bottom: 1px solid #e5e5e5;} +.wst-se-header2 .ui-icon-return {top: 2px;left: 8px;color: #df0202;font-size: 22px;line-height: 36px;} +.wst-se-search{display: block;width: 90.9%;height: 31px;line-height:31px;padding: 5px 0;margin: auto;position: relative;} +.wst-se-search i{position: absolute;top: -2px;left: -2px;color: #999;} +.wst-se-search input {margin-top:1px;padding: 0px 0 0 25px;width: 100%;box-sizing: border-box;-ms-box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;border-radius: 15px;background: #eee;color: #999;font-size: 0.13rem;line-height: 28px;letter-spacing: 1px;border: none;} +.wst-se-icon{position: absolute;top: 4px;right: 8px;width: 33px;height: 33px;display: block;background: url(../img/classify2.png) center center no-repeat;background-size: 60%;} +.wst-co-search{position: fixed;top:0;left:0;width: 100%;height:100%;background:#fff;z-index:1000;display:none;} +.wst-co-search .wst-se-header2{z-index: 1000;} +.wst-co-search .list{border-top: 42px solid transparent;} +.wst-co-search .list .search{padding:0 0.05rem;font: bold 14px/31px verdana;} +.wst-co-search .list .search i{float:left;width: 26px;height: 26px;background: url(../img/hot.png) center center no-repeat;background-size: 60%;} +.wst-co-search .list .term{margin-top:0.05rem;padding:0 0.1rem;} +.wst-co-search .list .term a{float:left;margin:0 0.08rem 0.08rem 0;padding:0.05rem 0.1rem;font-size:0.13rem;border-radius: 0.03rem;color: #686868;background-color: #f0f2f5;} +.wst-co-search .classify{border-top: 41px solid transparent;font-size:0.13rem;height: calc((100% - 41px));height: -webkit-calc((100% - 41px));height: -moz-calc((100% - 41px));height: -ms-calc((100% - 41px));height: -o-calc((100% - 41px));overflow-y: scroll;} +.wst-co-search .classify li h4{font-size:0.13rem;} +.wst-co-search .classify .ui-list-link > li:after,.wst-co-search .classify li .ui-txt-info{color: #232326;} +.wst-co-search .classify .shops{margin:0.08rem 0 0.1rem 0;} +.wst-co-search .classify .shops2 li{border-bottom: 1px solid #f6f6f8;} +.wst-footer-btns{border:0;background:#FFF} +.wst-menus{padding-top:2px} +.wst-menus .carsNum{position:relative} +.wst-menus .carsNum i{display:inline-block;text-align:center;background:#de0202;color:#fff;height:16px;line-height:16px;-webkit-border-radius:10px;padding:0 6px;background-clip:padding-box;font-size:.1rem;position:absolute;top:0;left:36px} +.wst-menus p{width:55px;height:42px;margin:0 auto} +.wst-menus .icon{width:36px;height:25px;display:block;margin:0 auto} +.home-word,.category-word,.cart-word,.follow-word,.user-word{float:left;width:100%;text-align:center;font-size:0.12rem;color:#2c2c2c;height:16px;line-height:16px} +.home-active-word,.category-active-word,.cart-active-word,.follow-active-word,.user-active-word{float:left;width:100%;text-align:center;font-size:0.12rem;color:#df0202;height:16px;line-height:16px} +.wst-menus .home{background: url(../img/icon_bottomnav.png) 9px 4px no-repeat;background-size: 773%;} +.wst-menus .category{background: url(../img/icon_bottomnav.png) -50px 5px no-repeat;background-size: 712%;} +.wst-menus .cart{background: url(../img/icon_bottomnav.png) -121px 5px no-repeat;background-size: 770%;} +.wst-menus .follow{background: url(../img/icon_bottomnav.png) -178px 5px no-repeat;background-size: 742%;} +.wst-menus .user{background: url(../img/icon_bottomnav.png) -240px 5px no-repeat;background-size: 742%;} +.wst-menus .home-active{background: url(../img/icon_bottomnav.png) 9px -25px no-repeat;background-size: 773%;} +.wst-menus .category-active{background: url(../img/icon_bottomnav.png) -50px -23px no-repeat;background-size: 712%;} +.wst-menus .cart-active{background: url(../img/icon_bottomnav.png) -121px -25px no-repeat;background-size: 770%;} +.wst-menus .follow-active{background: url(../img/icon_bottomnav.png) -178px -24px no-repeat;background-size: 742%;} +.wst-menus .user-active{background: url(../img/icon_bottomnav.png) -240px -24px no-repeat;background-size: 742%;} +.wst-toTop{margin:0 16px 60px 0;position:fixed;z-index:100;right:0;width:30px;height:30px;bottom:15px;display:none} +.wst-toTopimg{width:40px;height:40px;display:block;background:url(../img/top.png) 0 0 no-repeat;background-size:100%} +.wst-toTopimg span{float:left;width:100%;color:#b8b8b8;text-align:center;font-size:.12rem;margin-top:18px} +.wst-toHistoryimg{width:40px;height:40px;display:block;background:url(../img/history-icon.png) 0 0 no-repeat;background-size:100%} +.wst-prompt-icon{position: relative;top:1rem;margin: 0 auto;width:0.89rem;height:0.89rem;} +.wst-prompt-icon img{display: block;width:0.89rem;height:0.89rem;} +.wst-prompt-info{position: relative;top:1.2rem;text-align: center;} +.wst-prompt-info p{font-size:0.16rem;color: #222;} +.wst-prompt-info button{margin-top:0.1rem;font-size:0.15rem;color: #df0202;width:1.5rem;height:0.35rem;border:1px solid #df0202;} +.wst-prompt-info button:not(.disabled):not(:disabled):active{color: #df0202;} +.wst-button-close{display:block;position:absolute;top:0;right:-5px;z-index:2;outline:0;height:42px;width:46px;border-radius:50%;opacity:.5;transition:transform .5s cubic-bezier(.16,.81,.32,1),opacity .5s ease;color:#000;line-height:42px} +.iziModal-button-close i{line-height:42px} +.wst-clear{clear:both} +.wst-Load{position:fixed;z-index:100;top:49%;left:0px;width: 100%;display:none} +.wst-Load .ui-loading{display: block;margin: 0 auto;} +.wst-dialog-t{padding-top:12px;padding-bottom:10px} +.wst-dialog-l{width:73%;border-bottom:1px solid #ddd} +.wst-dialog-b1,.wst-dialog-b2{width:80px;height:30px;line-height: 30px;margin-top:16px;margin-bottom:18px} +.wst-dialog-b1{color:#59595c} +.wst-dialog-b2{color:#fff;background:#de0202} +.wst-dialog-b1:not(.disabled):not(:disabled):active,.wst-dialog-b1 button.active{color:#7d7d7f} +.wst-dialog-b2:not(.disabled):not(:disabled):active,.wst-dialog-b2 button.active{color:#f6e8e9;background:#f43a3b} +.wst-prompt{width:320px;height:210px;position:fixed;top:0;right:10px;background:url(../img/img_fenxiangtishi.png) 13px -13px no-repeat} +.wst-shl-ads{padding-bottom:8px} +.wst-shl-ads .title{height:0.35rem;line-height:0.35rem;font: bold 0.15rem/0.35rem verdana;color: #555;text-align:center;background:url(../img/img_titlebg.png) center no-repeat;background-size:40%} +.wst-active{color:#de0301} +.upload-modal{position:fixed;left:0;top:.5rem;width:100%;height:90%;z-index:102}#upload_modal{display:none} +.clipArea{width:100%;height:100%;background-color:rgba(0,0,0,0.7)} +#errorBg{background:url(../img/img_error_3.png) no-repeat;background-size:cover}#errorBtn{width:152px;position:absolute;bottom:-50px;left:28%;background:#f9a517;color:#fff;border-color:#f9a517} +#errorLostBg{background:url(../img/img_error_2.png) no-repeat;background-size:100% 146%}#errorLostBg p{position:absolute;color:#40ad74;font-size:.18rem;left:7%;top:20%} +.wst-pay-inp{width:100%;margin-top:2px;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0} +.ui-header ~ .ui-container{border-top:42px solid transparent} +.ui-footer ~ .ui-container{border-bottom:45px solid transparent} +.ui-header-positive i,.ui-header-positive a{color:#59595c} +.ui-dialog-bd h4{margin-bottom:10px;text-align:center} +.ui-poptips-success,.ui-poptips-info,.ui-poptips-warn{z-index:9999} +.wst-red{color:#de0202} +.ft-title i{float:left;width:18px;height:18px;background:url(../img/icon_tishi.png) no-repeat;background-size:100%} +.ft-title span{padding-left:7px} +.ft-item{padding-left:25px;font-size:.13rem} +input[type="search"]::-webkit-search-cancel-button{display:none;-webkit-appearance:none} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/consult.css b/hyhproject/mobile2/view/default/css/consult.css new file mode 100755 index 0000000..04c61b0 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/consult.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +body{font-size:.15rem;background:#f0f2f5} +.gcListBox{width:99%} +.gcList{width:100%} +.item-time{float:right} +.gcList li{background:#fff;border-bottom:1px solid #ccc;width:97%;padding:10px 5px} +.gcList li:last-child{border:0} +.gc-item-tit{font-size:.11rem;margin:0 10px} +.question-box{padding-top:8px} +.question-pic{display:block;width:17px;height:17px;background-size:50px 50px;background-image:url(./../img/QA-icon.png);background-position:0 -15px;margin-left:10px;float:left;margin-top:1px} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.question-content span{margin-left:37px;display:block;padding-right:12px;font-size:13px;color:#848689;line-height:18px;margin-top:0} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.answer-content span{color:#252525} +.answer-pic{background-position:-33px -15px} +.gcplist{padding:10px} +.gcplist li{margin-bottom:5px}#consultContent{width:100%;min-height:100px} +.consult{width:30px;height:30px;position:absolute;right:5px;top:5px;background:url(./../img/icon_adds_users.png) no-repeat;background-position:-75px -2px;background-size:150px 38.5px} +.consult-button{width:100px;height:30px;margin-top:10px;font-size:.15rem;line-height:30px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.consult-button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/day_new.css b/hyhproject/mobile2/view/default/css/day_new.css new file mode 100755 index 0000000..3cacb87 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/day_new.css @@ -0,0 +1,191 @@ +body { + background: #c82929; +} +.banner img { + width: 6.4rem; + height: 3.99rem; +} +.new_yhj { + width: 6.4rem; + height: 2.6rem; + background: url(../img/ac2_bg1.png) no-repeat; + background-size: 100%; +} +.new_yhj .yhj1 { + float: left; + margin-left: 0.3rem; + margin-top: 0.4rem; +} +.new_yhj .yhj1 img { + width: 2.77rem; + height: 1.16rem; +} +.everyday { + width: 6.4rem; + height: 6rem; + background: url(../img/ac2activity_bg.png) no-repeat; + background-size: 100%; +} +.madeInChina img { + width: 6.4rem; + height: 1.09rem; + padding-bottom: 0.18rem; +} +.mdc_sp { + margin-left: 0.16rem; + margin-bottom: 0.6rem; +} +.mdc_sp .gssp { + width: 3rem; + height: 3.45rem; + background: url(../img/guochan_con_bg.png) no-repeat; + background-size: 100%; + position: relative; + float: left; + margin-right: 0.1rem; + margin-top: 0.2rem; +} +.mdc_sp .gssp img { + width: 2.72rem; + height: 2.73rem; + border-radius: 10px; + position: absolute; + left: 0.14rem; + top: 0.14rem; +} +.mdc_sp .cash { + width: 2.73rem; + height: 0.42rem; + background: rgba(200, 41, 41, 0.4); + position: absolute; + bottom: 0.58rem; + left: 0.12rem; + border-radius: 0px 0px 10px 10px; + color: #fff; + font-family: "微软雅黑"; + font-size: 0.24rem; + text-align: center; + line-height: 0.42rem; +} +.baby { + width: 6.4rem; + height: 1.08rem; + background: url(../img/ac2_title_bg.png) no-repeat; + background-size: 100%; + color: #c82929; + font-family: "微软雅黑"; + font-size: 0.36rem; + text-align: center; + line-height: 1.08rem; + font-weight: 900; +} +.baby_cp { + margin-bottom: 0.46rem; +} +.baby_sp { + width: 6.4rem; + height: 7.3rem; + background: url(../img/ac2_zdzb_bg.png) no-repeat; + background-size: 100%; + position: relative; +} +.baby_sp img { + width: 5.85rem; + height: 5.73rem; + border-radius: 50%; + position: absolute; + top: 0.4rem; + left: 0.3rem; +} +.baby_cp .baby_sp .wenzi { + width: 4.55rem; + height: 0.4rem; + background: #fef8d4; + position: absolute; + bottom: 0.7rem; + left: 1rem; + color: #791619; + font-family: "微软雅黑"; + font-size: 0.22rem; + text-align: center; + line-height: 0.4rem; +} +.baby_sp .sp_p { + font-size: 0.55rem; + position: absolute; + bottom: 0.1rem; + left: 0.9rem; + color: #c82e2c; +} +.baby_sp .sp_p span { + font-size: 0.18rem; + color: #c82e2c; +} +.baby_sp .baby_shop { + width: 1rem; + height: 0.3rem; + background: #c82e2c; + color: #fdfac5; + font-family: "微软雅黑"; + font-size: 0.15rem; + position: absolute; + bottom: 0.25rem; + right: 0.9rem; + text-align: center; + line-height: 0.3rem; + border-radius: 8px; +} +.six { + width: 6.4rem; + margin-bottom: 0.72rem; + margin-top: 0.45rem; +} +.six .six_nr { + width: 2rem; + height: 1.1rem; + background: url(../img/zdzb2_bg.png) no-repeat; + background-size: 100%; + margin-left: 0.11rem; + float: left; +} +.six .six_nr p { + font-family: "微软雅黑"; + font-size: 0.26rem; + color: #c72928; + text-align: center; + line-height: 1.1rem; +} +.six_cp .six_cp_sp { + width: 1.87rem; + height: 2.55rem; + background: #fcd553; + margin-left: 0.17rem; + margin-bottom: 0.12rem; + float: left; + position: relative; +} +.six_cp .six_cp_sp img { + width: 1.7rem; + height: 1.75rem; + margin: 0.08rem; +} +.six_cp .six_cp_sp .sanjiao { + width: 1.9rem; + height: 0.2rem; + background: url(../img/ac2_sanjiao.png); + position: absolute; + left: -0.54rem; + top: 1.7rem; +} +.six_cp .six_cp_sp p { + color: #e41f4c; + font-family: "微软雅黑"; + font-size: 0.2rem; + text-align: center; + font-weight: 900; + margin-top: 0.2rem; +} +.footer img { + width: 6.4rem; + height: 2.52rem; +} diff --git a/hyhproject/mobile2/view/default/css/day_new.less b/hyhproject/mobile2/view/default/css/day_new.less new file mode 100755 index 0000000..7102486 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/day_new.less @@ -0,0 +1,222 @@ +body { + background: #c82929; +} + +.banner img{ + width: 640/100rem; + height: 399/100rem; +} + +.new_yhj{ + width: 640/100rem; + height: 260/100rem; + background: url(../img/ac2_bg1.png) no-repeat; + background-size: 100%; +} + +.new_yhj .yhj1{ + float: left; + margin-left: 30/100rem; + margin-top: 40/100rem; +} + +.new_yhj .yhj1 img{ + width: 277/100rem; + height: 116/100rem; +} + +.everyday{ + width: 640/100rem; + height: 600/100rem; + background: url(../img/ac2activity_bg.png) no-repeat; + background-size: 100%; + +} + +.madeInChina img{ + width: 640/100rem; + height: 109/100rem; + padding-bottom: 18/100rem; +} + +.mdc_sp{ + margin-left: 16/100rem; + margin-bottom: 60/100rem; +} + +.mdc_sp .gssp{ + width: 300/100rem; + height: 345/100rem; + background: url(../img/guochan_con_bg.png) no-repeat; + background-size: 100%; + position: relative; + float: left; + margin-right: 10/100rem; + margin-top: 20/100rem; +} + +.mdc_sp .gssp img{ + width: 272/100rem; + height: 273/100rem; + border-radius: 10px; + position: absolute; + left: 14/100rem; + top: 14/100rem; +} + +.mdc_sp .cash{ + width: 273/100rem; + height: 42/100rem; + background: rgba(200,41,41,0.4); + position: absolute; + bottom: 58/100rem; + left: 12/100rem; + border-radius: 0px 0px 10px 10px; + color: #fff; + font-family: "微软雅黑"; + font-size: 24/100rem; + text-align: center; + line-height: 42/100rem; +} + +.baby{ + width: 640/100rem; + height: 108/100rem; + background: url(../img/ac2_title_bg.png) no-repeat; + background-size: 100%; + color: #c82929; + font-family: "微软雅黑"; + font-size: 36/100rem; + text-align: center; + line-height: 108/100rem; + font-weight: 900; +} + +.baby_cp{ + margin-bottom: 46/100rem; +} + +.baby_sp{ + width: 640/100rem; + height: 730/100rem; + background: url(../img/ac2_zdzb_bg.png) no-repeat; + background-size: 100%; + position: relative; +} + +.baby_sp img{ + width: 585/100rem; + height: 573/100rem; + border-radius: 50%; + position: absolute; + top: 40/100rem; + left: 30/100rem; +} + +.baby_cp .baby_sp .wenzi{ + width: 455/100rem; + height: 40/100rem; + background: #fef8d4; + position: absolute; + bottom: 70/100rem; + left: 100/100rem; + color: #791619; + font-family: "微软雅黑"; + font-size: 22/100rem; + text-align: center; + line-height: 40/100rem; +} + +.baby_sp .sp_p{ + font-size: 55/100rem; + position: absolute; + bottom: 10/100rem; + left: 90/100rem; + color: #c82e2c; +} + +.baby_sp .sp_p span{ + font-size: 18/100rem; + color: #c82e2c; +} + +.baby_sp .baby_shop{ + width: 100/100rem; + height: 30/100rem; + background:#c82e2c; + color: #fdfac5; + font-family: "微软雅黑"; + font-size: 15/100rem; + position: absolute; + bottom: 25/100rem; + right: 90/100rem; + text-align: center; + line-height: 30/100rem; + border-radius: 8px; +} + +.six{ + width: 640/100rem; + margin-bottom: 72/100rem; + margin-top: 45/100rem; +} + +.six .six_nr{ + width: 200/100rem; + height: 110/100rem; + background: url(../img/zdzb2_bg.png) no-repeat; + background-size: 100%; + margin-left: 11/100rem; + float: left; +} + +.six .six_nr p{ + font-family: "微软雅黑"; + font-size: 26/100rem; + color: #c72928; + text-align: center; + line-height: 110/100rem; +} + +.six_cp .six_cp_sp{ + width: 187/100rem; + height: 255/100rem; + background: #fcd553; + margin-left: 17/100rem; + margin-bottom: 12/100rem; + float: left; + position: relative; +} + +.six_cp .six_cp_sp img{ + width: 170/100rem; + height: 175/100rem; + margin: 8/100rem; + +} + +.six_cp .six_cp_sp .sanjiao{ + width: 190/100rem; + height: 20/100rem; + background: url(../img/ac2_sanjiao.png); + position: absolute; + left: -54/100rem; + top: 170/100rem; +} + +.six_cp .six_cp_sp p{ + color: #e41f4c; + font-family: "微软雅黑"; + font-size: 20/100rem; + text-align: center; + font-weight: 900; + margin-top: 20/100rem; +} + +.footer img{ + width: 640/100rem; + height: 252/100rem; +} + + + diff --git a/hyhproject/mobile2/view/default/css/favorites.css b/hyhproject/mobile2/view/default/css/favorites.css new file mode 100755 index 0000000..d222d26 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/favorites.css @@ -0,0 +1,42 @@ +@CHARSET "UTF-8"; +.ui-checkbox-s input:before{font-size:18px;color:#e32726} +.ui-checkbox input:before,.ui-checkbox-s input:before{top:20px;left:-2px;font-size:22px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.sactive{top:-43px!important;margin-right:-5px!important} +.add-cart{display:inline-block;width:23px;height:25px;right:7px;bottom:5px;position:absolute;background:url(../img/icon_gzspcart.png) no-repeat;background-size:100%} +.favorite-tc{line-height:45px;text-align:left} +.f-btn button{position:absolute;top:0.06rem;right:10px;font-size:.15rem;background:#e00102;border-bottom:1px solid #e00102} +.f-btn{min-width:85px} +.wst-shl-list{position:relative;padding:5px 10px;margin-top:5px;background:#fff} +.wst-shl-list .img{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shl-list .img a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.wst-shl-list .img a img{max-width:100px;max-height:100px} +.wst-shl-list .info{padding-left:5px} +.wst-shl-list .title{margin-bottom:5px;padding-left:10px;font-size:.15rem;color:#363638} +.wst-shl-list p{padding-left:10px} +.wst-shl-list .deal{font-size:0.11rem;color: #999;} +.wst-shl-list .price{color:#ff0e00;font-size:.16rem;} +.wst-shl-list .price span{font-size:.13rem;} +.shopImg{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.shopImg a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.shopImg a img{max-width:100px;max-height:100px} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;} +.goods-box{padding:0!important;margin-bottom: 5px;} +.goodsImg{margin-right: 5px;width:23.5%; position: relative;float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.goodsImg a{width:100%;height:70px;display:table-cell;vertical-align:middle} +.goods-item{width:24%;margin-right:5px;position: relative;} +.goodsPrice{color: red;} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;height: 20px;} +.wst-action{margin-top: 5px; ;display: inline-block;height: 25px;width: 90%;float: right; font-size: 0.14rem;color: red; line-height: 25px;text-align: center;border-radius: 10px;border: 1px solid red;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/global-lxy.css b/hyhproject/mobile2/view/default/css/global-lxy.css new file mode 100755 index 0000000..6310716 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/global-lxy.css @@ -0,0 +1,58 @@ +@charset "utf-8"; +/* CSS Document */ + + *{ + -webkit-tap-highlight-color: transparent; + +} + +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form, +fieldset,input,textarea,p,blockquote,th,td { + margin:0; + padding:0; + +} +body{ + font-family: "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Hiragino Sans GB W3", "WenQuanYi Micro Hei", "Microsoft YaHei UI", "Microsoft YaHei", sans-serif; +} +table { + border-collapse:collapse; /*让表格边框细线*/ + border-spacing:0; /*清除边框间距*/ +} +fieldset,img { + border:0 none; /*有些浏览器默认这些标签有边框,所以要清除默认边框*/ + display:block; +} +address,caption,cite,code,dfn,em,i,u,b,strong,th,var { + font-style:normal; + font-weight:normal; + /*清除标签默认文本样式和加粗*/ +} +input,textarea{ + outline:0 none;/*去掉文本框的默认轮廓线*/ +} +ol,ul { + list-style:none; /*清除列表默认样式*/ +} +caption,th { + text-align:left; /*清除标签默认文本居中对齐*/ +} +h1,h2,h3,h4,h5,h6 { + font-size:100%; + font-weight:normal; /*清除标题标签的默认样式*/ +} +a{ + text-decoration:none;/*大部分页面中的链接没有下划线*/ +} + +.clearfix:after{ + height:0; + content:" "; + display:block; + overflow:hidden; + clear:both; + } +.clearfix{ + zoom:1;/*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + diff --git a/hyhproject/mobile2/view/default/css/global.css b/hyhproject/mobile2/view/default/css/global.css new file mode 100755 index 0000000..0dc96d6 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/global.css @@ -0,0 +1,38 @@ +header { + padding-top: 18px; + line-height: 48px; + text-align: center; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 18px; + z-index: 10; + position: fixed; + width: 100%; + top: 0; + left: 0; +} + + +.clearfix:after{ + height:0; + content:" "; + display:block; + overflow:hidden; + clear:both; + } +.clearfix{ + zoom:1;/*IE低版本浏览器不支持after伪类所以要加这一句*/ +} +a{ + color: black; +} +a:active{ + color: white; +} diff --git a/hyhproject/mobile2/view/default/css/goods_category.css b/hyhproject/mobile2/view/default/css/goods_category.css new file mode 100755 index 0000000..ce21092 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/goods_category.css @@ -0,0 +1,16 @@ +@CHARSET "UTF-8"; +.ui-scrollerl{width:22%;height:496px;overflow:hidden;background:#fff;position:fixed;top:42px;left:0;} +.ui-scrollerl li{padding:13px 0px;font-size:0.129rem;text-align:center;} +.wst-goodscate{color: #232326;border-top:1px solid #f6f6f8;border-right:1px solid #f6f6f8;border-left:2px solid #f6f6f8;} +.wst-goodscate_selected{color:#df0202;background:#f6f6f8;border-right:1px solid #f6f6f8;border-left:2px solid #df0202} +.wst-scrollerr{width:78%;float:right} +.wst-scrollerr li{margin:0px 5px;padding: 5px 10px 5px 5px;font-size:0.12rem;background: #fff;} +.wst-goodsca{height:35px;background:#f2f2f2} +.wst-goodscat{float:left;width:100%;} +.wst-goodscat span{float: left;width: calc((100% - 15px)/3);width: -webkit-calc((100% - 15px)/3);width: -moz-calc((100% - 15px)/3);width: -ms-calc((100% - 15px)/3);width: -o-calc((100% - 15px)/3);height: calc((100vw - 20px)/3);height: -webkit-calc((100vw - 20px)/3);height: -moz-calc((100vw - 20px)/3);height: -ms-calc((100vw - 20px)/3);height: -o-calc((100vw - 20px)/3);padding: 5px 0px 0px 5px;text-align:center;} +.wst-goodscat span a{color: #686868;text-align:center} +.wst-goodscat span a img{width:100%;min-height:75px;margin-bottom:2;display:block;} +.wst-gc-ads{padding-bottom:5px} +.wst-gc-ads .title{margin-top:5;padding-left:10;height:30px;line-height:30px;font-size:0.13rem;} +.wst-gc-br .brand{margin-left:5;background:#fff;} +.wst-gc-br .brand img{float:left;width: calc((100% - 15px)/3);width: -webkit-calc((100% - 15px)/3);width: -moz-calc((100% - 15px)/3);width: -ms-calc((100% - 15px)/3);width: -o-calc((100% - 15px)/3);height:50px;margin:5px 0 5px 5px;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/goods_detail.css b/hyhproject/mobile2/view/default/css/goods_detail.css new file mode 100755 index 0000000..c017f99 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/goods_detail.css @@ -0,0 +1,981 @@ +@CHARSET "UTF-8"; +.wst-header .cart { + width: 40px; + height: 40px; + position: absolute; + right: 38px; + background: url(../img/icon_spxq.png) -10px -4px no-repeat; + background-size: 497% +} + +.wst-header .cart span { + height: 12px; + line-height: 12px; + font-size: .11rem; + position: absolute; + top: 6px; + right: 8px; + min-width: 12px; + text-align: center; + border-radius: 5px; + color: #fff; + background: #de0202 +} + +.wst-header .share { + width: 40px; + height: 40px; + position: absolute; + right: 0; + background: url(../img/icon_spxq.png) -60px -4px no-repeat; + background-size: 497% +} + +.swiper-container { + height: calc(100vw); + height: -webkit-calc(100vw); + height: -moz-calc(100vw); + height: -ms-calc(100vw); + height: -o-calc(100vw); +} + +.swiper-pagination-bullet { + width: 6px; + height: 6px; + background: rgba(0, 0, 0, .2); + opacity: 1; +} + +.swiper-pagination-bullet-active { + background: #ff6666; +} + +.wst-go-return { + position: absolute; + top: 0.1rem; + left: 0.1rem; + z-index: 10; + width: 0.3rem; + height: 0.3rem; + background-color: rgba(0, 0, 0, .4); + border-radius: 100%; +} + +.wst-go-return i { + position: absolute; + top: 0.02rem; + left: 0.02rem; + width: 0.24rem; + height: 0.24rem; + line-height: 0.24rem; + font-size: 0.24rem; + color: #fff; +} + +.wst-go-mores { + position: absolute; + top: 0.1rem; + right: 0.1rem; + z-index: 10; + width: 0.3rem; + height: 0.3rem; + background-color: rgba(0, 0, 0, .4); + border-radius: 100%; +} + +.wst-go-mores i { + position: absolute; + top: 0.03rem; + left: 0.03rem; + width: 0.24rem; + height: 0.24rem; + line-height: 0.24rem; + font-size: 0.24rem; + color: #fff; + text-align: center; + z-index: 0; +} + +.wst-ca-layer { + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + z-Index: 9999; + display: none; + background-color: rgba(0, 0, 0, .6); +} + +.wst-go-more { + position: fixed; + top: 29px; + right: 0.05rem; + z-Index: 10000; + width: 32%; +} + +.wst-go-more .arrow { + position: absolute; + top: -6px; + right: 7px; + display: block; + width: 0; + height: 0; + line-height: 0; + border-width: 0.11rem; + border-color: transparent transparent #fff transparent; + border-style: dashed dashed solid dashed; +} + +.wst-go-more .more { + margin-top: 13px; + border-radius: 3px; + background: #fff; +} + +.wst-go-more .more .column { + width: 80px; + display: block; + margin: 0 auto; + height: 23px; + line-height: 23px; + padding: 10px 0px; +} + +.wst-go-more .more .line { + border-bottom: 1px solid #f2f2f2; +} + +.wst-go-more .more i { + float: left; + width: 23px; + height: 23px; + margin-left: 2px; + position: relative; +} + +.wst-go-more .home { + background: url(../img/icon_bottomnav.png) 0px -24px no-repeat; + background-size: 1062%; +} + +.wst-go-more .category { + background: url(../img/icon_bottomnav.png) -53px -23px no-repeat; + background-size: 1010%; +} + +.wst-go-more .cart { + background: url(../img/icon_bottomnav.png) -107px -23px no-repeat; + background-size: 1010%; +} + +.wst-go-more .follow { + background: url(../img/icon_bottomnav.png) -161px -23px no-repeat; + background-size: 1010%; +} + +.wst-go-more .user { + background: url(../img/icon_bottomnav.png)-216px -23px no-repeat; + background-size: 1010%; +} + +.wst-go-more .more p { + float: left; + width: 55px; + font-size: 0.13rem; +} + +.wst-go-more .more li:active { + padding-left: 2px; +} + +.wst-go-img { + width: 100%; + height: calc(100vw); + height: -webkit-calc(100vw); + height: -moz-calc(100vw); + height: -ms-calc(100vw); + height: -o-calc(100vw); + text-align: center; + vertical-align: middle; + display: block; + position: relative +} + +.wst-go-img a { + width: calc(100vw); + width: -webkit-calc(100vw); + width: -moz-calc(100vw); + width: -ms-calc(100vw); + width: -o-calc(100vw); + height: calc(100vw); + height: -webkit-calc(100vw); + height: -moz-calc(100vw); + height: -ms-calc(100vw); + height: -o-calc(100vw); + display: table-cell; + vertical-align: middle +} + +.wst-go-img a img { + max-width: 100%; + max-height: 100%; +} + +.wst-go-name { + padding: 0.1rem 0.1rem 0 0.1rem; + font-size: 0.165rem; + color: #051B28; + background: #fff; + line-height: 0.23rem; +} + +.wst-go-price { + padding: 0.1rem 0.1rem 0.05rem 0.1rem; + background: #fff; + position: relative; +} + +.wst-go-price p { + font-size: .15rem; + color: #707070; +} + +.wst-go-price .price { + font-size: .25rem; + color: #de0202 +} + +.wst-go-price .price i { + font-size: .13rem; +} + +.wst-go-price .market { + margin-left: 12px; + font-size: .13rem; + color: #999; + text-decoration: line-through +} + +.wst-go-price .info { + padding-top: 0.05rem; + font-size: 0.13rem; + color: #999; +} + +.wst-go-price .follow, +.wst-go-price .nofollow { + width: 40px; + height: 40px; + display: block; + margin: 0 auto +} + +.lxy_price{ + float: left; +} + +.lxy_price p{ + color: #de0202; + display: inline-block; +} + + + +.wst-go-icon .follow { + background: url(../img/icon_spxq.png) -154px -47px no-repeat; + background-size: 659% +} + +.wst-go-icon .nofollow { + background: url(../img/icon_spxq.png) -113px -47px no-repeat; + background-size: 659% +} + +.wst-go-ul { + margin: 10px 0 +} + +.wst-go-ul li { + color: #3d3d3d; + margin-left: 0; + padding: 0.1rem; + border-bottom: 1px solid #edebeb +} + +.wst-go-ul .icon { + color: #dbdada; + height: 24px; + line-height: 24px; + font-size: .35rem +} + +.wst-go-ul .word { + color: #3d3d3d; +} + +.wst-go-ul .line, +.wst-go-shop .line { + color: #dbdada; + padding: 0 5px +} + +.wst-go-ul .red, +.wst-go-shop .score .red { + color: #de0202 +} + +.wst-go-shop { + padding-bottom: 10px; + border-bottom: 1px solid #f2f1f1; +} + +.wst-go-shop .info { + padding: 0.1rem; +} + +.wst-go-shop .img { + float: left; + width: 0.6rem; + height: 0.6rem; + text-align: center; + vertical-align: middle; + display: block; + position: relative +} + +.wst-go-shop .img a { + width: 0.6rem; + height: 0.6rem; + display: table-cell; + vertical-align: middle +} + +.wst-go-shop .img a img { + max-width: 0.6rem; + max-height: 0.6rem; + font-size: 0.13rem +} + +.wst-go-shop .name { + float: left; + width: 80%; +} + +.wst-go-shop .name1 { + float: left; + width: 100%; + padding-left: 0.05rem; + font-size: 0.165rem; + line-height: 0.35rem; +} + +.wst-go-shop .name2 { + float: left; + width: 100%; + padding-left: 0.05rem; + font-size: 0.13rem; + color: #848689; +} + +.wst-go-shop .score { + padding: 0.08rem 0.1rem; + font-size: .13rem; +} + +.wst-go-shop .button { + padding: 0.08rem 0.1rem; + font-size: .15rem; + text-align: center; +} + +.wst-go-shop .button a { + height: 0.38rem; + line-height: 0.38rem; + color: #666; + border-radius: 4px; + text-align: center; + display: block; + border: 1px solid #ccc; +} + +.wst-go-shop .button .goods { + margin-right: 0.1rem; +} + +.wst-go-shop .button .goods:before { + content: ''; + padding: 2px 8px; + width: 10px; + margin-right: 6px; + background: url(../img/user-tool-icon2.png) 0 1px no-repeat; + background-size: 100% +} + + +} +.wst-go-shop .button .shop { + margin-left: 0.1rem; +} +.wst-go-shop .button .shop:before { + content: ''; + padding: 2px 8px; + width: 10px; + margin-right: 6px; + background: url(../img/icon_dp.png) 0 2px no-repeat; + background-size: 100% +} +.wst-go-goods { + float: left; + width: calc((100% - 48px)/3); + width: -webkit-calc((100% - 48px)/3); + width: -moz-calc((100% - 48px)/3); + width: -ms-calc((100% - 48px)/3); + width: -o-calc((100% - 48px)/3); + padding: 5px; + margin: 6px 3px 0px 3px; + font-size: .13rem; + background: #fff; +} +.wst-go-goods .img { + float: left; + width: 100%; + height: 100px; + text-align: center; + vertical-align: middle; + display: block; + position: relative +} +.wst-go-goods .img a { + width: 100%; + height: 100px; + display: table-cell; + vertical-align: middle +} +.wst-go-goods .img a img { + max-width: 100px; + max-height: 100px +} +.wst-go-goods .name { + float: left; + width: 100%; + height: .42rem; + margin-top: 2px; + line-height: .21rem +} +.wst-go-goods .info { + float: left; + width: 100%; + margin-top: 3px +} +.wst-go-goods .info .price { + float: left; + font-size: .15rem; + color: #e00102 +} +.wst-go-icon .icon, +.wst-go-icon .but { + display: block; + margin: 0 auto; + margin-top: 3px; + width: 30px; + height: 42px; + color: #59595c; + position: relative +} +.wst-go-icon .icon a { + width: 30px; + height: 42px; + display: block +} +.wst-go-icon .img { + width: 30px; + height: 22px; + position: absolute; + left: 0; + top: 0 +} +.wst-go-icon .tel { + background: url(../img/icon_spxq.png) -14px -48px no-repeat; + background-size: 738% +} +.wst-go-icon .qq { + background: url(../img/qq.png) 5px 1px no-repeat; + background-size: 20px 20px; +} +.wst-go-icon .shop { + background: url(../img/icon_spxq.png) -62px -45px no-repeat; + background-size: 648%; +} +.wst-go-icon .word { + width: 100%; + position: absolute; + left: 0; + bottom: 2px; + font-size: .13rem; + text-align: center; + color: #232326; +} +.wst-goods_buy { + margin: 0; +} +.wst-goods_buyl, +.wst-goods_buyr { + float: left; + width: 50%; + height: 42px; + line-height: 42px; + font-size: .15rem; + color: #fff +} +.wst-goods_buyl { + background: #f9a517; + border-bottom: 1px solid #f9a517; +} +.wst-goods_buyl:not(.disabled):not(:disabled):active, +.wst-goods_buyl.active { + color: #fbf6ee; + background: #f3c77c; + background-clip: padding-box +} +.wst-goods_buyr { + background: #e00102; + border-bottom: 1px solid #e00102; +} +.wst-goods_buyr:not(.disabled):not(:disabled):active, +.wst-goods_buyr.active { + color: #fbd6d6; + background: #f25a5b; + background-clip: padding-box +} +.wst-goods_buym { + float: left; + width: 100%; + height: 42px; + line-height: 42px; + font-size: .15rem; + color: #fff; + background: #f23030; + border: 1px solid #f23030; +} +.wst-fav_but { + width: 23px; + height: 48px; + border-radius: none; + border: 0; + background-clip: padding-box +} +.wst-go-details { + font-size: .16rem; + padding: 8px 10px 15px 8px; + word-wrap: break-word; + word-break: break-all +} +.wst-go-details img { + width: 100%; + height: auto; +} +.wst-ev-term { + margin-top: 0.02rem; + font-size: .15rem; + background: #fff; + padding: 0.1rem 0; + text-align: center; +} +.wst-ev-term .number { + font-size: .13rem; +} +.wst-ev-term .active { + color: #de0202; +} +.wst-go-evaluate { + font-size: .13rem; + background: #fff; + border-bottom: 1px solid #f2f1f1; +} +.wst-go-evaluate .info { + margin-bottom: 10px; + padding: 6px 0; +} +.wst-go-evaluate .portrait { + float: left; + width: 28px; + height: 28px; + margin-right: 5px; + border-radius: 100%; +} +.wst-go-evaluate .info .name { + float: left +} +.wst-go-evaluate .info .ranks { + float: left; + width: 16px; + margin: 2px 16px 0 5px +} +.wst-go-evaluate .info .time { + float: right; + color: #8e8d8d +} +.wst-go-evaluate .content { + padding-bottom: 3px +} +.wst-go-evaluate .content p { + float: left; + width: 100%; +} +.wst-go-evaluate .content i { + float: left; + width: 14px; + height: 14px; + margin: 2px 3px 0 0; +} +.wst-go-evaluate .content .bright { + background: url(../img/img_dpjpj.png) 0 0 no-repeat; + background-size: 296% +} +.wst-go-evaluate .content .dark { + background: url(../img/img_dpjpj.png) -26px 0 no-repeat; + background-size: 296% +} +.wst-go-evaluate .content .content2 { + font-size: .14rem; + margin-top: 2px; +} +.wst-go-evaluate .content img { + float: left; + width: 45px; + height: 45px; + margin: 2px 3px 0 0 +} +.wst-go-evaluate .content .word { + color: #8e8d8d; + padding: 3px 0 +} +.wst-go-evaluate .reply { + padding: 10px 0; + border-top: 1px solid #edebeb +} +.wst-cover { + position: fixed; + left: 0; + top: 0; + background-color: #000; + width: 100%; + height: 100%; + filter: alpha(opacity=60); + opacity: .6; + z-Index: 9999; + display: none +} +.wst-fr-box { + position: fixed; + z-index: 9999; + left: 0; + bottom: -226px; + width: 100%; + min-height: 40%; + background: #fff; + font-size: .15rem +} +.wst-fr-box .title, +.wst-cart-box .title { + position: relative; + padding: 6px 0; + border-bottom: 1px solid #f1f1f1 +} +.wst-fr-box .title span { + float: left; + width: 100%; + height: 26px; + line-height: 26px; + text-align: center; + font-size: .185rem +} +.wst-fr-box .title i, +.wst-cart-box .title i { + position: absolute; + right: 5px; + top: -2px; + font-size: 27px +} +.wst-fr-box .content { + padding: 10px 10px 50px 10px +} +.wst-fr-box .determine, +.wst-cart-box .determine { + position: absolute; + left: 0; + bottom: 3px; + width: 100%; + text-align: center; +} +.wst-fr-box .button, +.wst-cart-box .button { + width: 90%; + font-size: .15rem; + height: 40px; + line-height: 40px; + color: #fff; + background: #e00102; + border-radius: 5px; + border-bottom: 1px solid #e00102 +} +.wst-fr-box .button:not(.disabled):not(:disabled):active, +.wst-cart-box .button:not(.disabled):not(:disabled):active { + color: #fff0f0; + background: #f52f30; + background-clip: padding-box +} +.wst-cart-box { + position: fixed; + z-index: 9999; + left: 0; + bottom: -296px; + width: 100%; + min-height: 38%; + background: #fff; + font-size: .14rem +} +.wst-cart-box .title { + min-height: 68px +} +.wst-cart-box .picture { + position: absolute; + left: 10px; + top: -12px +} +.wst-cart-box .picture .img { + float: left; + width: 70px; + height: 70px; + text-align: center; + vertical-align: middle; + display: block; + position: relative; + padding: 5px; + background: #fff; + border-radius: 2px +} +.wst-cart-box .img a { + width: 70px; + height: 70px; + display: table-cell; + vertical-align: middle +} +.wst-cart-box .img a img { + max-width: 70px; + max-height: 70px +} +.wst-cart-box .title p { + float: left; + margin: 0 0 5px 96px; + color: #3e3e3e; + width: 53% +} +.wst-cart-box .title .price { + font-size: .162rem; + color: #de0202 +} +.wst-cart-box .title .price .price2 { + margin-left: 12px; + font-size: .13rem; + color: #707070; + text-decoration: line-through +} +.wst-cart-box .standard { + padding: 0 10px 118px 10px +} +.wst-cart-box .spec { + padding: 10px 0; + border-bottom: 1px solid #f1f1f1 +} +.wst-cart-box .spec p { + float: left; + width: 100% +} +.wst-cart-box .spec .img { + float: left; + width: 40px; + height: 40px; + border-radius: 2px; + margin: 5px 6px 0 0 +} +.wst-cart-box .spec .img.active { + width: 38px; + height: 38px; + border: 1px solid #e00102 +} +.wst-cart-box .spec span { + float: left; + margin: 5px 6px 0 0; + padding: 3px 5px; + border: 1px solid #a0a0a0; + border-radius: 3px; + text-align: center +} +.wst-cart-box .spec span.active { + color: #fff; + background: #e00102; + border: 1px solid #e00102 +} +.wst-cart-box .number { + width: 92%; + position: absolute; + left: 3%; + bottom: 52px; + z-Index: 1; + background: #fff +} +.wst-cart-box .number .stock { + float: left; + color: #3e3e3e; + margin-top: 12px +} +.wst-buy_l { + float: right; + margin-top: 3px +} +.wst-buy_l1, +.wst-buy_l3 { + width: 40px; + height: 32px; + background: #FFF; + border: 0; + border: 1px solid #ddd +} +.wst-buy_l1 { + border-right: 1px solid #fff; +} +.wst-buy_l3 { + border-left: 1px solid #fff; +} +.wst-buy_l1 { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px +} +.wst-buy_l3 { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px +} +.wst-buy_l2 { + width: 48px; + height: 32px; + border: 1px solid #ddd; + text-align: center; + color: #e00102 +} +.wst-buy_l1:focus, +.wst-buy_l3:focus { + color: #e00102 +} +.wst-buy_l2:focus { + width: 48px; + height: 32px; + border: 1px solid #e00102 +} +.ui-tab-nav { + width: 62%; + height: 40px; + float: right; + margin-right: 70px +} +.ui-tab-nav li.active { + color: #777; + border-bottom: 2px solid #de0202; + color: #de0202 +} +.ui-tab-nav li { + height: 42px; + line-height: 42px; + font-size: .16rem; + min-width: 50px +} +.ui-slider-content>li img { + display: inline; + width: auto +} +.gc-title { + height: 38px; + line-height: 38px; + padding-left: 38px; + font-size: .15rem; + text-align: left; + position: relative; + background: #fff +} +.gc-tit-icon { + display: block; + width: 38px; + height: 38px; + background: url(./../img/icon_indextop.png) no-repeat; + background-position: -144px 9px; + background-size: 176px 20px; + position: absolute; + top: 0; + left: 0; +} +.gc-tit-icon2 { + display: block; + width: 30px; + height: 30px; + background: url(./../img/icon_adds_users.png) -75px -2px no-repeat; + position: absolute; + top: 4px; + right: 5px; + background-size: 150px 38.5px; +} +.gc-title-list { + background: #ffffff; + padding: 0.1rem 0; + border-top: 1px solid #f2f1f1; +} +.gc-title-list .prompt { + text-align: center; + font-size: 0.14rem; +} +.question-box { + padding-top: 8px +} +.question-pic { + display: block; + width: 17px; + height: 17px; + background-size: 50px 50px; + background-image: url(./../img/QA-icon.png); + background-position: 0 -15px; + margin-left: 10px; + float: left; + margin-top: 1px +} +.question-content { + width: 100%; + margin-left: -27px; + display: block; + float: left; + word-break: break-word; + overflow: hidden +} +.question-content span { + margin-left: 37px; + display: block; + padding-right: 12px; + font-size: 13px; + color: #848689; + line-height: 18px; + margin-top: 0 +} +.question-content { + width: 100%; + margin-left: -27px; + display: block; + float: left; + word-break: break-word; + overflow: hidden +} +.answer-content span { + color: #252525 +} +.answer-pic { + background-position: -33px -15px +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/goods_list.css b/hyhproject/mobile2/view/default/css/goods_list.css new file mode 100755 index 0000000..c0c269b --- /dev/null +++ b/hyhproject/mobile2/view/default/css/goods_list.css @@ -0,0 +1,34 @@ +@CHARSET "UTF-8"; +.wst-se-header2{padding-left: 0;} +.wst-se-search{width: 76%;} +.wst-se-icon{background: url(../img/goods-list.png) center center no-repeat;background-size: 60%;transform: rotate(90deg);-webkit-transition: all .2s linear;transition: all .2s linear;} +.wst-se-icon2{background: url(../img/goods-list2.png) center center no-repeat;background-size: 60%;transform: rotate(0deg);} +.wst-shl-head{background:#fff;font-size: 0.14rem;color:#6a6b6d;margin-bottom: 0.04rem;} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:24px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding: 5px;margin-bottom: 0.04rem;font-size: 0.14rem;background: #fff;color: #232326;font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.01rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.pd0{padding-right:6px!important} +.wst-in-goods .tags{width:100%;float:left} +.wst-in-goods .tags .tag{background:#f23030;color:#fff;border-radius:2px;font-size:11px;padding:0 2px 0 2px} +.wst-go-switch .wst-in-goods{width: 100%;border:0;} +.wst-go-switch .wst-in-goods .img{width:32%;} +.wst-go-switch .wst-in-goods .name,.wst-go-switch .wst-in-goods .tags,.wst-go-switch .wst-in-goods .info,.wst-go-switch .wst-in-goods .info2{width:68%;padding-left:0.05rem;box-sizing: border-box;} +.wst-go-switch .wst-in-goods .info2{margin-top:0.1rem;} +.wst-go-switch .wst-in-goods .img,.wst-go-switch .wst-in-goods .img a{width: calc(31.5%);width: -webkit-calc(31.5%);width: -moz-calc(31.5%);width: -ms-calc(31.5%);width: -o-calc(31.5%);height: calc(31.5vw);height: -webkit-calc(31.5vw);height: -moz-calc(31.5vw);height: -ms-calc(31.5vw);height: -o-calc(31.5vw);} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/history.css b/hyhproject/mobile2/view/default/css/history.css new file mode 100755 index 0000000..6ee4ace --- /dev/null +++ b/hyhproject/mobile2/view/default/css/history.css @@ -0,0 +1,7 @@ +@CHARSET "UTF-8"; +.goods-item{margin:5px 0;padding: 0.05rem 0.1rem;background:#ffffff;} +.wst-info{padding-left:0.1rem;} +.goodsTitle{font-size: 0.15rem;height:0.42rem;line-height:0.21rem;} +.goods-info{color:#989292;font-size: 0.12rem;} +.price{color: #de0202;font-size: 0.16rem;} +.price span{font-size: 0.13rem;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/index-lxy.css b/hyhproject/mobile2/view/default/css/index-lxy.css new file mode 100755 index 0000000..8d24715 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/index-lxy.css @@ -0,0 +1,552 @@ + /* 6p */ + + @media all and (min-width: 376px) and (max-width: 414px) { + .time { + width: 100%; + height: 182px; + background: white; + } + .time_con { + width: 100%; + height: 150px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 140px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 99px; + } + .banner, + .banner1 { + width: 100%; + height: 120px; + margin-top: 6px; + } + } + /* 6 */ + + @media all and (min-width: 321px) and (max-width: 375px) { + .time { + width: 100%; + height: 172px; + background: white; + } + .time_con { + width: 100%; + height: 140px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 130px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 89px; + } + .banner, + .banner1 { + width: 100%; + height: 120px; + margin-top: 6px; + } + } + /* 5 */ + + @media all and (max-width: 320px) { + .time { + width: 100%; + height: 178px; + background: white; + } + .time_con { + width: 100%; + height: 140px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 130px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 89px; + } + .banner, + .banner1 { + width: 100%; + height: 98px; + margin-top: 6px; + } + } + + .ac_center { + float: left; + width: 30%; + border-right: 1px solid #efefef; + background: #fff; + } + + .youhaohuo { + width: 100%; + height: 100px; + border-bottom: 1px solid #efefef; + background: #fff; + } + + .youhaohuo .img { + width: 86.4px; + margin-top: 6px; + margin-left: 9px; + } + + .aiguangjie { + width: 100%; + height: 105px; + background: #fff; + } + + .aiguangjie .img { + width: 80.4px; + margin-top: 6px; + margin-left: 9px; + } + + .ac_right { + float: left; + width: 35%; + background: #fff; + } + + .kongbai { + width: 100%; + height: 100px; + border-bottom: 1px solid #efefef; + background: #fff; + } + + .bimaiqingdan { + width: 100%; + height: 105px; + background: #fff; + } + + .bimaiqingdan .img { + width: 85.5px; + margin-top: 6px; + margin-left: 9px; + } + + .activity-lxy { + width: 100%; + height: 213px; + background: #fff; + border-bottom: 6px solid #efefef; + } + + .ac1_left-lxy { + width: 40%; + float: left; + height: 213px; + border-right: 1px solid #efefef; + } + + .ac1_left-lxy .img-lxy { + width: 123px; + margin-top: 12px; + margin-left: 12px; + } + + .ac1_left-lxy .img-lxy1 { + width: 100%; + height: 170px; + } + + .ac_right-lxy { + width: calc(50% - 1px); + float: left; + height: 213px; + } + + .ac_r-lxy { + width: 120%; + height: 106px; + border-bottom: 1px solid #EFEFEF; + text-align: center; + position: relative; + } + + .ac_r-lxy .img-lxy { + width: 54px; + margin-top: 3px; + display: inline-block; + } + + .ac_right_img1 { + width: 50%; + height: 85px; + position: absolute; + top: 20px; + } + + .ac_right_img1 img { + width: 100%; + height: 85px; + } + + .ac_right_img2 { + width: 50%; + height: 85px; + position: absolute; + top: 20px; + right: 0; + } + + .ac_right_img2 img { + width: 100%; + height: 85px; + } + + .sw_l { + width: 40%; + height: 105px; + } + + .sw_l .img { + width: 39.6px; + margin-top: 6px; + margin-left: 6px; + } + + .sw_r { + width: 60%; + height: 105px; + background: #c1c1c1; + } + + .sw_r img { + width: 100%; + height: 105px; + } + + .xianshitehui { + background: white url(../img/xianshitehui.png) no-repeat left top; + background-size: 175.2px 108px; + width: 100%; + height: 108px; + border-bottom: 6px solid #efefef; + } + + .xsth_con { + width: calc(100% - 114px); + height: 87px; + margin-top: 8px; + float: right; + background: #c1c1c1; + } + + .xsth_con img { + width: 100%; + height: 87px; + } + + + .search1 { + width: 70%; + position: fixed; + left: 11.5%; + top: 0; + z-index: 100; + } + + .wst-in-search1 input { + float: left; + width: 120%; + height: 26px; + font-size: .181rem; + margin-top: 9px; + outline: 0; + border: 0; + position: relative; + left: -13px; + background: #fff; + opacity: 0.8; + font-size: 10px; + text-indent: 50px; + z-index: 10; + } + + .wst-in-search1 p { + float: left; + width: 100%; + border: none; + } + + .wst-in-search1 .ui-icon-search { + position: absolute; + top: 2px; + left: 1px; + font-size: .35rem; + color: #fff + } + + .wst-in-actives1 input { + float: left; + width: 120%; + height: 26px; + margin-top: 9px; + outline: 0; + border: 0; + position: relative; + background: #fff; + opacity: 0.8; + font-size: 10px; + color: #000 + } + + .msg { + width: calc(100% - 24); + height: 31.2px; + background: white; + margin: 6px 6px; + border-radius: 12px; + line-height: 31.2px; + } + + .msg img { + width: 61.2px; + margin: 6px 2%; + float: left; + } + + .msg p { + float: left; + color: #e51329; + line-height: 30px; + margin: 0; + font-size: 12xp; + } + + .msg marquee { + width: 50%; + height: 31.2px; + line-height: 31.2px; + font-size: 12px; + margin-left: 2%; + float: left; + } + + .msg .msg_more { + float: left; + color: black; + margin-left: 2%; + font-size: 12px; + } + + .time_title { + width: 100%; + height: 33px; + line-height: 38px; + } + + .time_title img { + float: left; + width: 95.4px; + margin-left: 4px; + margin-top: -3px; + } + + .time_title p { + float: left; + font-size: 13.2px; + color: black; + margin: 0; + margin-left: 1.5%; + } + + .count { + margin-left: 1%; + float: left; + } + + .count div { + line-height: 15px; + float: left; + font-size: 10.8px; + color: #fefefe; + background: black; + margin-top: 6px; + padding: 3px 2px; + border-radius: 2px; + } + + .count o { + float: left; + font-size: 10.8px; + line-height: 33px; + } + + .jxyh { + float: right; + font-size: 13.2px; + color: #e51329; + margin-right: 12px; + } + + .time_title .jxyh img { + float: right; + width: 13.8px; + margin-top: 11px; + } + + .time_con .swiper-slide p { + margin: 0; + text-align: center; + color: #e51329; + font-size: 15.6px; + } + + .time_con .swiper-slide del { + display: block; + text-align: center; + color: #909090; + font-size: 12px; + } + + .box { + width: 100%; + height: 350px; + background: white; + } + + .box .img { + height: 15.6px; + } + + .box p { + margin: 0; + font-size: 12px; + overflow: hidden; + height: 21px; + } + + .box_1 { + width: 42%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + padding: 9px 12px; + float: left; + } + + .box .box2 { + border-right: none; + } + + .boxcon img { + float: left; + width: 66px; + height: 66px; + margin: 0 calc((100% - 132px)/4); + } + /*.banner, + .banner1 { + width: 100%; + height: 120px; + margin-top: 6px; + }*/ + + .banner .swiper-container, + .banner1 .swiper-container { + padding: 0 12px; + } + + .banner .swiper-container .swiper-wrapper .swiper-slide img, + .banner1 .swiper-container .swiper-wrapper .swiper-slide img { + width: 100%; + } + + .pzss_title { + margin: 0; + margin-top: -9px; + } + + .pzss_title img { + width: 100%; + margin: 0; + } + + .pzss { + margin: 0; + /*margin-top: -7px;*/ + width: 100%; + height: 345px; + background: white; + } + + .pzss1 { + width: 49%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + float: left; + } + + .pzss1 .p1, + .pzss3 .p1 { + margin: 0; + margin-top: 6px; + margin-left: 9px; + color: #525252; + font-size: 15.6px; + overflow: hidden; + height: 21px; + } + + .pzss1 .p2, + .pzss3 .p2 { + margin: 0; + font-size: 12px; + overflow: hidden; + height: 21px; + color: #ee5be2; + margin-left: 9px; + } + + .pzss .pzss2 { + border-right: none; + } + + .pzss3 { + width: 24.4%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + float: left; + } + + .pzss .pzss4 { + border-right: none; + } + + .pzss3 img { + width: 66px; + height: 66px; + margin: 0 calc(50% - 33px); + } + + <style type="text/css">input::-ms-input-placeholder { + text-align: center; + } + + input::-webkit-input-placeholder { + text-align: center; + } + + </style> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/index.css b/hyhproject/mobile2/view/default/css/index.css new file mode 100755 index 0000000..bdaa46b --- /dev/null +++ b/hyhproject/mobile2/view/default/css/index.css @@ -0,0 +1,609 @@ +@CHARSET "UTF-8"; +.wst-in-header { + height: 33px; + background: -webkit-linear-gradient(top, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)); + background: linear-gradient(top, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)); + -webkit-transition: background-color .2s linear; + -moz-transition: background-color .2s linear; + -o-transition: background-color .2s linear; + transition: background-color .2s linear; + -webkit-transform: translateZ(0); + transform: translateZ(0); + border-bottom: 0px; +} + +.wst-in-header.active { + height: 39px; + background: #e50e0f; + opacity: 0.87; +} + +.wst-in-search { + position: fixed; + z-index: 100; + top: 0; + left: 0; + width: 100%; + height: 28px; + line-height: 28px; + padding: 0px; +} + +.wst-in-search .ui-icon-search { + position: absolute; + top: -2px; + left: -2px; + color: #fff; + font-size: 0.35rem; + width: 28px; + height: 28px; + z-index: 100; +} + +.wst-in-search .searchs { + display: block; + width: 73.5%; + margin: 0 auto; + position: relative; +} + +.wst-in-search .searchs input { + margin-top: 6px; + padding: 0 0 0 25px; + width: 100%; + box-sizing: border-box; + -ms-box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + border-radius: 15px; + background: rgba(255, 255, 255, 0.5); + color: #fff; + font-size: 0.14rem; + height: 28px; + line-height: 28px; + letter-spacing: 1px; + border: none; +} + +.wst-in-search .searchs input::-webkit-input-placeholder { + color: #fff; +} + +.wst-in-search .searchs input:-moz-placeholder { + color: #fff; +} + +.wst-in-search .searchs input::-moz-placeholder { + color: #fff; +} + +.wst-in-search .searchs inputt:-ms-input-placeholder { + color: #fff; +} + +.wst-in-search .searchs.active input { + background: #fff; + color: #666; +} + +.wst-in-search .searchs.active input::-webkit-input-placeholder { + color: #666; +} + +.wst-in-search .searchs.active input:-moz-placeholder { + color: #666; +} + +.wst-in-search .searchs.active input::-moz-placeholder { + color: #666; +} + +.wst-in-search .searchs.active inputt:-ms-input-placeholder { + color: #666; +} + +.wst-in-search .searchs.active .ui-icon-search { + color: #333; +} + +.wst-in-search .classify { + position: absolute; + top: 0; + left: 0; + width: 13.25%; + text-align: center; +} + +.wst-in-search .classify i { + display: block; + margin: 0 auto; + width: 33px; + height: 33px; + background: url(../img/classify.png) center center no-repeat; + background-size: 60%; + position: relative; + top: 3px; +} + +.wst-in-search .user { + position: absolute; + top: 0; + right: 0; + width: 13.25%; + height: 40px; + line-height: 40px; + text-align: center; +} + +.wst-in-search .user a { + color: #fff; + font-size: 0.13rem; +} + +.wst-in-search .user i { + display: block; + margin: 0 auto; + width: 33px; + height: 33px; + background: url(../img/message-icon.png) center center no-repeat; + background-size: 60%; + position: relative; + top: 3px; +} + +.wst-in-search .user i .number { + position: absolute; + top: 1px; + right: -1px; + min-width: 10px; + display: inline-block; + text-align: center; + background: #f74c31; + color: #fff; + font-size: 0.1rem; + height: 15px; + line-height: 15px; + -webkit-border-radius: 8px; + padding: 0 3px; + background-clip: padding-box; +} + +.wst-in-adso .adso img, +.wst-in-adsb img, +.wst-in-adscats img, +.wst-in-activity .img img { + width: 100%; + height: 100%; + display: block +} + +.wst-in-choose { + padding: 5px 0 12px 0; + background: #fff +} + +.wst-in-choose p { + width: 57.14285714%; + display: block; + margin: 0 auto; + padding-bottom: 0.05rem; + text-align: center; + vertical-align: middle; + position: relative +} + +.wst-in-choose p img { + width: 100%; +} + +.wst-in-choose span { + font-size: 0.13rem; + display: block; + text-align: center; + color: #666; +} + +.wst-in-activity { + background: #fff; + padding: 5px 0px 10px 0px; +} + +.wst-in-activity .img { + height: 1.15rem; +} + +.wst-in-news { + position: relative; + display: block; + width: 95%; + margin: 0 auto; + margin-top: 0.05rem; + font-size: 0.14rem; + height: 30px; + line-height: 30px; + background: #fff; + border: 1px solid #eee; + border-radius: 25px; +} + +.wst-in-news .article { + float: left; + width: 60%; + height: 22px; + margin-top: 4px; +} + +.wst-in-news .article p { + height: 22px; + line-height: 22px; + border-right: 1px solid #eee; +} + +.wst-in-news .new { + float: left; + width: 24%; + text-align: left; + margin-left: 3px; + font: bold 13px/31px verdana; + background: url(../img/icon_news1.png) 30px no-repeat; + background-size: 50% 70%; +} + +.wst-in-news .new p { + color: white; + display: inline-block; +} + +.wst-in-news a { + color: #df0202; +} + +.wst-in-news .more { + float: right; + width: 15%; + height: 30px; + text-align: center; +} + +.wst-in-news .more:active { + background: #f2f1f1 +} + +input[type="search"]::-webkit-search-cancel-button { + display: none; + -webkit-appearance: none +} + +.wst-in-adst { + padding: 0.1rem 0px; + background: #fff +} + +.wst-in-adst img { + float: left; + width: 50%; + border-bottom: 0.01rem solid #f2f1f1; +} + +.wst-in-adsb { + height: 1.05rem; + background: #fff +} + +.wst-in-title { + height: 0.3rem; + padding: 0.05rem 0; + text-align: center; + color: #addd2d; + background: #fff; + border-bottom: 0.01rem solid #f2f1f1; + position: relative; +} + +.wst-in-title .line { + display: block; + margin: 0 auto; + margin-top: 0.14rem; + width: 66%; + height: 0.02rem; + background: #addd2d; +} + +.wst-in-title .name { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 0.4rem; +} + +.wst-in-title .name p { + display: block; + margin: 0 auto; + width: 50%; + height: 0.4rem; + font: bold 0.158rem/0.43rem verdana; + background: #fff; +} + +.wst-in-title .name p span { + position: relative; + padding-left: 0.2rem; +} + +.wst-in-title .icon { + position: absolute; + top: -0.02rem; + left: 0; + display: block; + width: 0.2rem; + height: 0.2rem; + background: url(../img/index-icon.png) 0px 0px no-repeat; + background-size: 100%; +} + +.colour0 { + color: #addd2d +} + +.colour0 .line { + background: #addd2d +} + +.colour0 .icon { + background-position: 0px 0px +} + +.colour1 { + color: #59a4f0 +} + +.colour1 .line { + background: #59a4f0 +} + +.colour1 .icon { + background-position: 0px -0.41rem +} + +.colour2 { + color: #d71c1c +} + +.colour2 .line { + background: #d71c1c +} + +.colour2 .icon { + background-position: 0px -0.81rem +} + +.colour3 { + color: #f28748 +} + +.colour3 .line { + background: #f28748 +} + +.colour3 .icon { + background-position: 0px -1.20rem +} + +.colour4 { + color: #f28bd4 +} + +.colour4 .line { + background: #f28bd4 +} + +.colour4 .icon { + background-position: 0px -1.60rem +} + +.colour5 { + color: #a24220 +} + +.colour5 .line { + background: #a24220 +} + +.colour5 .icon { + background-position: 0px -2rem +} + +.colour6 { + color: #4289db +} + +.colour6 .line { + background: #4289db +} + +.colour6 .icon { + background-position: 0px -2.41rem +} + +.colour7 { + color: #f04f00 +} + +.colour7 .line { + background: #f04f00 +} + +.colour7 .icon { + background-position: 0px -2.80rem +} + +.colour8 { + color: #009d4e +} + +.colour8 .line { + background: #009d4e +} + +.colour8 .icon { + background-position: 0px -3.20rem +} + +.colour9 { + color: #f6dd06 +} + +.colour9 .line { + background: #f6dd06 +} + +.colour9 .icon { + background-position: 0px -3.61rem +} + +.colour10 { + color: #b79467 +} + +.colour10 .line { + background: #b79467 +} + +.colour10 .icon { + background-position: 0px -4.01rem +} + +.colour11 { + color: #ad2be2 +} + +.colour11 .line { + background: #ad2be2 +} + +.colour11 .icon { + background-position: 0px -4.42rem +} + +.wst-in-adscats { + height: 60px +} + +.wst-in-goods { + float: left; + width: 50%; + box-sizing: border-box; + padding: 5px; + margin-bottom: 0.2rem; + font-size: 0.08rem; + background: #fff; + color: #232326; + font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; +} + +.wst-in-goods.left { + border-right: 0.02rem solid #f6f6f8; +} + +.wst-in-goods.right { + border +} + +.lxy_p { + color: #DE0202; + font-size: 0.14rem; + font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif; +} + +.wst-in-goods .img { + float: left; + width: 1.76rem; + height: 1.76rem; + text-align: center; + vertical-align: middle; + display: block; + position: relative +} + +.wst-in-goods .img a { + width: 1.76rem; + height: 1.76rem; + display: table-cell; + vertical-align: middle +} + +.wst-in-goods .img a img { + max-width: 1.76rem; + max-height: 1.76rem; +} + +.wst-in-goods .name { + float: left; + width: 100%; + height: 0.33rem; + margin-top: 3px; + line-height: 0.17rem +} + +.wst-in-goods .info { + float: left; + width: 100%; + margin-top: 0.05rem; +} + +.wst-in-goods .info .price { + float: left; + font-size: 0.13rem; + color: #e00102; +} + +.wst-in-goods .info .price span { + font-size: 0.166rem; +} + +.wst-in-goods .info2 { + float: left; + width: 100%; + font-size: 0.11rem; +} + +.wst-in-goods .info2 .price { + float: left; + color: #999; +} + +.wst-in-goods .info2 .deal { + float: right; + color: #999; +} + +.ui-header~.ui-container { + border-top: 0px solid transparent +} + + +/*轮播*/ + +.ui-slider-indicators { + display: block; + right: 0px; + text-align: center; +} + +.ui-slider-indicators li { + display: inline-block; + margin: 0px 3px; + width: 8px; + height: 3px; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + background: rgba(255, 255, 255, 0.5); +} + +.ui-slider-indicators li.current, +.ui-slider-indicators li.current:before { + background-color: #fff; +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/iziModal.css b/hyhproject/mobile2/view/default/css/iziModal.css new file mode 100755 index 0000000..7af9e43 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/iziModal.css @@ -0,0 +1,54 @@ +.iziModal{display:none;position:fixed;width:100%;left:50%;top:50%;z-index:999;background:#FFF;border-radius:3px;box-shadow:0 0 8px rgba(0,0,0,.3);transition:margin-top .3s ease} +.iziModal *{-webkit-font-smoothing:antialiased} +.iziModal::after{content:'';width:100%;height:0;opacity:0;position:absolute;left:0;bottom:0;z-index:1;background:-moz-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,rgba(0,0,0,0)),color-stop(100%,rgba(0,0,0,0.35)));background:-webkit-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-o-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-ms-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#59000000',GradientType=0);transition:height .3s ease-in-out,opacity .3s ease-in-out;pointer-events:none} +.iziModal.hasScroll::after{height:50px;opacity:1} +.iziModal .iziModal-button-close{display:block;position:absolute;top:0;left:0;z-index:2;outline:0;height:46px;width:46px;border-radius:50%;opacity:.5;transition:transform .5s cubic-bezier(.16,.81,.32,1),opacity .5s ease} +.iziModal-button-close i{color:#000} +.iziModal .iziModal-button-close:hover{opacity:1;transform:rotate(180deg)} +.iziModal .iziModal-header{background:#88a0b9;padding:14px 40px 15px 18px;border-radius:3px 3px 0 0;border-bottom:1px solid #e8e8e8;overflow:hidden;position:relative;z-index:10} +.iziModal .iziModal-header-icon{font-size:40px;color:rgba(255,255,255,0.5);padding-right:15px;float:left} +.iziModal .iziModal-header-title{color:#69696b;font-size:18px;line-height:1.3} +.iziModal .iziModal-header-subtitle{color:rgba(255,255,255,0.6);font-size:12px;line-height:1.4} +.iziModal .iziModal-header-title,.iziModal .iziModal-header-subtitle{margin:0;font-family:Arial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center} +.iziModal .iziModal-header.iziModal-noSubtitle{height:auto;padding:9px 15px 9px 15px} +.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{font-size:23px;padding-right:13px} +.iziModal .iziModal-header.iziModal-noSubtitle{font-size:15px;font-weight:400} +.iziModal.light .iziModal-header{box-shadow:none} +.iziModal.light .iziModal-header-icon{color:rgba(0,0,0,0.5)} +.iziModal.light .iziModal-header-title{color:#000} +.iziModal.light .iziModal-header-subtitle{color:rgba(0,0,0,0.6)} +.iziModal.light .iziModal-button-close{background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDU0QjI2RjgyNjZFMTFFNkE3RTk5MEFGMzVBNTcxNkYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDU0QjI2RjcyNjZFMTFFNkE3RTk5MEFGMzVBNTcxNkYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDVDRUM4QTFGQTZCMTFFNEExNEZGMTM1MjdDNDE2ODMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDVDRUM4QTJGQTZCMTFFNEExNEZGMTM1MjdDNDE2ODMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6mca+RAAABkklEQVR42rxVoU4DQRC9NhhUAYNBICqbVLUJSU+cK4IPuB+4BAeCNAUPAgH6fqCuBkHdGRJEVZPKE4iaKlqFPN4ms8uymbm7hjsmeZmmO/ve7czsTiPLMq9O28tbjOP4EC4EzoE2cEJLKyAFXoFJFEWfEkeDOwGI9+GugRvgoOAjN8Aj8AShr0IBkJ/CvQCdHbOxBC4g8iEKgFyl4N1Kxa6mUncGkZX+o+mkZfoHco/2TonrtwDsCuhV0Dg94voRgOIR3IgJvgR8OjqXDp9iXBsRpzmBasUWVzjk8w0+cETU74DWlsy+FnEagaFw3Am+pA2i1BLR5KlaUzHC3qEt0M0pWuKI2ORJTlN07Zt8XNAZSiQgEa8EueFsejWbFlgXXB6TFqYmkq1tgUUZckpLUlJkYQvMhKCQKahb+FDYO7MFVKttmaAOiAZMQbXIQHgUt7p9zWOH4DHcfUW1vcXpHtwuegbmFZDPieufn2tltOAL70uZgePb5OxFo4nUB+5oHBbZhmL77jQTZ3LtQ79K+xZgAC6hutw74AdUAAAAAElFTkSuQmCC') no-repeat 50% 50%} +.iziModal .iziModal-loader{background:#FFF url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%;position:absolute;left:0;right:0;top:0;bottom:0;z-index:9} +.iziModal .iziModal-content-loader{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%} +.iziModal .iziModal-content:before,.iziModal .iziModal-content:after{content:'';display:table} +.iziModal .iziModal-content:after{clear:both} +.iziModal .iziModal-content{zoom:1} +.iziModal .iziModal-wrap{position:relative;transition:height .3s ease} +.iziModal .iziModal-iframe{width:100%;margin-bottom:-4px;transition:height .3s ease} +.iziModal-overlay{display:block;position:fixed;z-index:998;top:0;left:0;height:100%;width:100%} +body.iziModal-attached{overflow:hidden}body.iziModal-attached .iziModal{border-radius:0}body.iziModal-attached .iziModal-header{border-radius:0}body.iziModal-attached .iziModal-wrap{overflow-x:hidden} +.iziModal.transitionIn .iziModal-header{-webkit-animation:slideDown .7s cubic-bezier(0.7,0,0.3,1);-moz-animation:slideDown .7s cubic-bezier(0.7,0,0.3,1);animation:slideDown .7s cubic-bezier(0.7,0,0.3,1)} +.iziModal.transitionIn .iziModal-header .iziModal-header-icon{-webkit-animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both;animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both} +.iziModal.transitionIn .iziModal-header .iziModal-header-title,.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both} +.iziModal.transitionIn .iziModal-header .iziModal-button-close{-webkit-animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1);-moz-animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1);animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1)} +.iziModal.transitionIn .iziModal-iframe,.iziModal.transitionIn .iziModal-wrap{-webkit-animation:fadeIn 2s;-moz-animation:fadeIn 2s;animation:fadeIn 2s} +.iziModal.transitionIn .iziModal-header{-webkit-animation-delay:.0s;-moz-animation:.0s;animation-delay:.0s} +.iziModal.transitionIn .iziModal-header .iziModal-header-icon,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation-delay:.4s;-moz-animation:.4s;animation-delay:.4s} +.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation-delay:.5s;-moz-animation:.5s;animation-delay:.5s} +.fadeOut{-webkit-animation:fadeOut .5s;-moz-animation:fadeOut .5s;animation:fadeOut .5s} +.fadeIn{-webkit-animation:fadeIn .5s;-moz-animation:fadeIn .5s;animation:fadeIn .5s} +.transitionIn{-webkit-animation:transitionIn .5s ease;-moz-animation:transitionIn .5s ease;animation:transitionIn .5s ease} +.transitionOut{-webkit-animation:transitionOut .5s cubic-bezier(.16,.81,.32,1);-moz-animation:transitionOut .5s cubic-bezier(.16,.81,.32,1);animation:transitionOut .5s cubic-bezier(.16,.81,.32,1)} +@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0} +}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1} +}@-webkit-keyframes slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}100%{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes slideIn{0%{opacity:0;-moz-transform:translateX(50px)} +100%{opacity:1;-moz-transform:translateX(0)}}@keyframes slideIn{0%{opacity:0;transform:translateX(50px)}100%{opacity:1;transform:translateX(0)}}@-webkit-keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-moz-keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-webkit-keyframes transitionOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0.9)} +}@-moz-keyframes transitionOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0.9)}}@keyframes transitionOut{0%{opacity:1;transform:scale(1)} +100%{opacity:0;transform:scale(0.9)}}@-webkit-keyframes slideDown{0%{opacity:0;-webkit-transform:scale(1,0) translateY(-40px);-webkit-transform-origin:center top} +}@-moz-keyframes slideDown{0%{opacity:0;-moz-transform:scale(1,0) translateY(-40px);-moz-transform-origin:center top}}@keyframes slideDown{0%{opacity:0;transform:scale(1,0) translateY(-40px);transform-origin:center top} +}@-webkit-keyframes revealIn{0%{opacity:0;-webkit-transform:scale3d(0.3,0.3,1)}}@-moz-keyframes revealIn{0%{opacity:0;-moz-transform:scale3d(0.3,0.3,1)} +}@keyframes revealIn{0%{opacity:0;transform:scale3d(0.3,0.3,1)}} +.iziModal ::-webkit-scrollbar{width:0} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/juhui.css b/hyhproject/mobile2/view/default/css/juhui.css new file mode 100755 index 0000000..7f76ed2 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/juhui.css @@ -0,0 +1,150 @@ +body { + background: #ebebeb; +} +.header { + width: 100%; + height: 0.8rem; + background: #f12f46; +} +.header p { + font-size: 0.3rem; + color: #fff; + text-align: center; + line-height: 0.8rem; +} +.nav { + width: 100%; + height: 0.6rem; + border-bottom: 1px solid #ececec; + background: #fff; +} +.nav div { + width: 33.333%; + float: left; +} +.nav div p { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #909090; + text-align: center; + line-height: 0.6rem; +} +.nav .on p { + color: #e5122b; +} +.guanzhu1, +.shangxin1, +.haohuo1 { + background: #fff; + margin-top: 0.1rem; +} +.guanzhu1 .gz_dpmc { + padding-top: 0.17rem; + margin-left: 0.2rem; +} +.guanzhu1 .gz_dpmc img { + width: 1rem; + height: 1rem; + float: left; +} +.guanzhu1 .gz_dpmc .gz_p1 { + font-family: "微软雅黑"; + font-size: 0.28rem; + font-weight: 900; + color: #000000; +} +.guanzhu1 .gz_dpmc .gz_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #909090; +} +.guanzhu1 .gz_dpmc .gz_p1, +.gz_p2 { + margin-left: 1.1rem; +} +.guanzhu1 .gz_nr { + width: 5.75rem; + height: 1.3rem; + margin-left: 0.2rem; + overflow: hidden; +} +.guanzhu1 .gz_nr p { + font-family: "微软雅黑"; + font-size: 0.24rem; + color: #525252; +} +.zan { + margin-left: 0.2rem; + margin-top: 0.45rem; +} +.zan .eye { + width: 0.3rem; + height: 0.3rem; + float: left; +} +.zan .eye_p { + font-family: "微软雅黑"; + font-size: 0.2rem; + color: #909090; + margin-left: 0.05rem; + float: left; +} +.zan .damuzhi { + width: 0.67rem; + height: 0.32rem; + border: 1px solid #ec5261; + border-radius: 10px 10px 10px 10px; + float: right; + margin-right: 0.34rem; + margin-bottom: 0.1rem; +} +.zan .damuzhi img { + width: 0.3rem; + height: 0.3rem; + margin-left: 0.1rem; + float: left; +} +.zan .damuzhi p { + font-family: "微软雅黑"; + font-size: 0.2rem; + color: #ea4051; + float: left; + margin-left: 0.05rem; +} +.shangxin1 .sx_dpmc { + padding-top: 0.17rem; + margin-left: 0.2rem; +} +.shangxin1 .sx_dpmc img { + width: 1rem; + height: 1rem; + float: left; +} +.shangxin1 .sx_dpmc .sx_p1 { + font-family: "微软雅黑"; + font-size: 0.28rem; + font-weight: 900; + color: #000000; +} +.shangxin1 .sx_dpmc .sx_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #909090; +} +.shangxin1 .sx_dpmc .sx_p1, +.sx_p2 { + margin-left: 1.1rem; +} +.shangxin1 .sx_sp { + width: 6.05rem; + margin-top: 0.4rem; + margin-left: 0.2rem; +} +.shangxin1 .sx_spnr { + width: 2rem; + height: 2rem; + background: #000000; + margin-right: 0.01rem; + margin-top: 0.02rem; + float: left; +} diff --git a/hyhproject/mobile2/view/default/css/juhui.less b/hyhproject/mobile2/view/default/css/juhui.less new file mode 100755 index 0000000..3ae265c --- /dev/null +++ b/hyhproject/mobile2/view/default/css/juhui.less @@ -0,0 +1,236 @@ +body{ + background: #ebebeb; +} + +.header{ + width: 100%; + height: 80/100rem; + background: #f12f46; +} + +.header p{ + font-size: 30/100rem; + color: #fff; + text-align: center; + line-height: 80/100rem; +} + +.nav{ + width: 100%; + height: 60/100rem; + border-bottom: 1px solid #ececec; + background: #fff; +} + +.nav div{ + width: 33.333%; + float: left; +} + +.nav div p{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #909090; + text-align: center; + line-height: 60/100rem; +} + +.nav .on p{ + color: #e5122b; +} + +.guanzhu1,.shangxin1,.haohuo1{ + background: #fff; + margin-top: 10/100rem; +} + +.guanzhu1 .gz_dpmc{ + padding-top: 17/100rem; + margin-left: 20/100rem; +} + +.guanzhu1 .gz_dpmc img{ + width: 100/100rem; + height: 100/100rem; + float: left; +} + +.guanzhu1 .gz_dpmc .gz_p1{ + font-family: "微软雅黑"; + font-size: 28/100rem; + font-weight: 900; + color: #000000; + +} + +.guanzhu1 .gz_dpmc .gz_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #909090; +} + +.guanzhu1 .gz_dpmc .gz_p1 , .gz_p2{ + margin-left: 110/100rem; +} + +.guanzhu1 .gz_nr{ + width: 575/100rem; + height: 130/100rem; + margin-left: 20/100rem; + overflow: hidden; +} + +.guanzhu1 .gz_nr p{ + font-family: "微软雅黑"; + font-size: 24/100rem; + color: #525252; +} + +.zan{ + margin-left: 20/100rem; + margin-top: 45/100rem; +} + +.zan .eye{ + width: 30/100rem; + height: 30/100rem; + float: left; +} + +.zan .eye_p{ + font-family: "微软雅黑"; + font-size: 20/100rem; + color: #909090; + margin-left: 5/100rem; + float: left; +} + +.zan .damuzhi{ + width: 67/100rem; + height: 32/100rem; + border: 1px solid #ec5261; + border-radius: 10px 10px 10px 10px; + float: right; + margin-right: 34/100rem; + margin-bottom: 10/100rem; +} + +.zan .damuzhi img{ + width: 30/100rem; + height: 30/100rem; + margin-left: 10/100rem; + float: left; +} + +.zan .damuzhi p{ + font-family: "微软雅黑"; + font-size: 20/100rem; + color: #ea4051; + float: left; + margin-left: 5/100rem; +} + + +.shangxin1 .sx_dpmc{ + padding-top: 17/100rem; + margin-left: 20/100rem; +} + +.shangxin1 .sx_dpmc img{ + width: 100/100rem; + height: 100/100rem; + float: left; +} + +.shangxin1 .sx_dpmc .sx_p1{ + font-family: "微软雅黑"; + font-size: 28/100rem; + font-weight: 900; + color: #000000; + +} + +.shangxin1 .sx_dpmc .sx_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #909090; +} + +.shangxin1 .sx_dpmc .sx_p1 , .sx_p2{ + margin-left: 110/100rem; +} + +.shangxin1 .sx_sp{ + width: 605/100rem; + margin-top: 40/100rem; + margin-left: 20/100rem; +} + +.shangxin1 .sx_spnr{ + width: 200/100rem; + height: 200/100rem; + background: #000000; + margin-right: 1/100rem; + margin-top: 2/100rem; + float: left; +} + +//.shangxin1 .sx_spnr img{ +// width: 200/100rem; +// height: 200/100rem; +//} + + +//.banner { +// height: 258/100rem; +// position: relative; +// overflow: hidden; +//} +// +//.banner .list { +// transition: .3s ease-in-out; +// width: 500%; +//} +// +//.banner .list li { +// float: left; +// width: 20%; +//} +// +//.banner .list a { +// height: 195/40rem; +// display: block; +//} +// +//.banner .list img { +// width: 100%; +// height: 100%; +//} +// +//.banner img { +// width: 640/100rem; +// height: 258/64rem; +//} +// +//.banner .btn { +// position: absolute; +// left: 50%; +// bottom: 8/100rem; +// transform: translateX(-50%); +//} +// +//.banner .btn li { +// float: left; +// width: 12/100rem; +// height: 12/100rem; +// border-radius: 50%; +// background: rgba(255, 255, 255, 0.3); +// margin: 0 4/100rem; +//} +// +//.banner .btn .on { +// background: #E8503E; +//} + + + diff --git a/hyhproject/mobile2/view/default/css/list_complains.css b/hyhproject/mobile2/view/default/css/list_complains.css new file mode 100755 index 0000000..1d87602 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/list_complains.css @@ -0,0 +1,18 @@ +@CHARSET "UTF-8"; +body{font-size:.13rem} +.c-tr{text-align:right} +.complain-box{margin-top:5px;padding:5px;background:#fff} +.c-line{border-bottom:1px solid #eaeaea;margin-bottom:5px} +.c-item li{padding:10px 0;font-size:.15rem} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background-color:#f6f6f8;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{background:#fff;height:auto;position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:14px} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{overflow-y:scroll} +.com-detail-box{margin:10px 0;background:#fff} +.com-detail-box li{padding:5px} +.com-detail-big-title{margin-left:6px;font-weight:bold} +.com-detail-title{text-align:right} +.annex{width:60px;height:60px} +.wst-co-status{color: #fa281b;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/logmoneys.css b/hyhproject/mobile2/view/default/css/logmoneys.css new file mode 100755 index 0000000..5d3d3a3 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/logmoneys.css @@ -0,0 +1,38 @@ +@CHARSET "UTF-8"; +h1{position:relative} +.record{display:inline-block;position:absolute;right: 10px;top:0;color:black;color: #59595c;font-size: 13px;} +.bgimg{display:inline-block;width:67px;height:60px;margin-top:20px;margin-bottom:5px} +.head-btn{display:block;width:auto;height:40px;line-height:40px;font-size:.22rem;color:#fff;background-color:#ff4e4e} +.head-btn i{position:relative;top:16%;display:inline-block;width:26px;height:26px;margin-right:5px;background:url(../img/icon_tixian.png) no-repeat;background-size:100%} +.head-btn-box{margin-top:77px} +.wst-header h1{z-index:-1} +.head{min-height:1rem;color:#fff;background:url(../img/icon_logmoney.png) no-repeat;background-size:cover;position: relative;} +.title{position: absolute;left:0;bottom:0;width:100%;} +.title .money_number{font-size:0.15rem;text-align: right;padding:0 0.1rem;} +.title .money_number2{font-size:0.13rem;margin-top: 2px;text-align: right;padding:0 0.1rem 0.05rem 0.1rem;} +.title .money_number p{font-size:0.16rem;} +.title .money_number span{font-size:0.13rem;} +.money-detail{padding:5px;background-color:#fff;border-bottom:1px solid #edebeb;font-size:.15rem;} +.money-detail h5{font-size:.15rem;} +.money-detail-title{padding:5px 10px;font-size:.18rem} +.m-tr{text-align:right;color:#abaaaa} +.first-time{font-size:0.15rem;color:#abaaaa;padding-left:5px;margin-top:10px} +.wst-lo-choice{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;background:#fff;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{height:auto;background:#fff;position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size: 16px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .info{padding:0.1rem;background:#fff;font-size:.15rem;} +.wst-fr-box .info .money{margin-top:0.05rem;font-size:.175rem;color: #df0202;} +.wst-fr-box .info .money span{font-size:.15rem;} +.wst-fr-box .content{padding:0.1rem;margin-top:10px;background:#fff;font-size:.15rem;} +.wst-fr-box .content li{margin:5px auto;line-height:36px} +.recharge-box{height:50px;line-height:50px;text-align:center;background:white;color:black;font-size:.15rem;border-bottom: 1px solid #f2f1f1;} +.wst-apply-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.icon_add{background: url(../img/icon_add_money.png) no-repeat;background-size: contain; width: 60px;margin:5px;margin: 0 auto;margin-top: 10%; height: 20px;} +.icon_out{background: url(../img/icon_out_money.png) no-repeat;background-size: contain; width: 60px;margin:5px;margin: 0 auto;margin-top: 10%; height: 20px;} +.wst_model p {display: inline-block;padding-left:14px;line-height: 20px;} +.icon_stript{width: 20px;height:20px;float: left;} +.stript_1{background: url(../img/icon_cart_money.png) no-repeat;background-size: cover;} +.stript_2{background: url(../img/icon_record.png) no-repeat;background-size: cover;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/messages.css b/hyhproject/mobile2/view/default/css/messages.css new file mode 100755 index 0000000..ab66cae --- /dev/null +++ b/hyhproject/mobile2/view/default/css/messages.css @@ -0,0 +1,23 @@ +@CHARSET "UTF-8"; +body{color:#333} +.wst-info_delete{padding:0} +.wst-info_delete button{height:49px;color:#333;line-height:49px} +.wst-info_delete button:not(.disabled):not(:disabled):active,.wst-info_delete button.active{border-color:#e7530a;color:#504f4f;background-clip:padding-box} +.wst-info_content input:before{font-size:22px;left:15px} +.wst-info_content input:checked:before{color:#f24566} +.wst-info_content span{float:left;width:20px;height:20px;margin-right:5px} +.wst-info_content h5{font-size:.15rem} +.wst-info_ico{background:url(../img/info_icon.png) 0 0 no-repeat} +.wst-info_ico1{background:url(../img/info_icon.png) -22px 0 no-repeat} +.msg-chk{margin-left:-13px;margin-right:10px} +.favorite-tc{line-height:45px;text-align:left;font-size: .165rem;} +.f-btn{min-width:85px} +.f-btn button{background:#e00102;border-bottom:1px solid #e00102;font-size:.15rem} +.ui-checkbox input:before,.ui-checkbox-s input:before{font-size:22px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.sactive{margin-right:0!important} +.detail-time{text-align:center} +.del-btn{position:absolute;top:8px;right:10px} +.wst-info_detime{font-size:.13rem} +.wst-info_decontent{font-size:.15rem} +.wst-line{border-bottom:1px solid #edebeb;margin:0 10px} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/orders.css b/hyhproject/mobile2/view/default/css/orders.css new file mode 100755 index 0000000..b7a6fad --- /dev/null +++ b/hyhproject/mobile2/view/default/css/orders.css @@ -0,0 +1,107 @@ +@CHARSET "UTF-8"; +body{font-size:.14rem} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.ui-tab{position:fixed;width:100%;z-index:100;left:0;top:41px} +.order-tab{width:100%;height:35px;line-height:35px;padding:0;background:#fff;overflow-x:scroll} +.order-tab::-webkit-scrollbar{width:1px;height:1px;background-color:#fff} +.order-tab::-webkit-scrollbar-thumb{background-color:#fff} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.item-head{font-size: .15rem;padding:10px 0;border-bottom:1px solid #f2f1f1} +.item-head p{padding-left:20px;position: relative;} +.item-head .shopicon{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.ui-tab-nav li.tab-item{font-size:.15rem;height:35px;line-height:35px;min-width:55px;padding:0 5px;text-align:center} +.ui-tab-nav li.tab-curr{color:#de4943;;height:34px;border-bottom:2px solid #de4943;} +.order-item{background:#fff;margin-top:6px;padding:0 10px;border-bottom:1px solid #e3e3e3} +.order-tr{text-align:right} +.o-shops{padding:2px 0 2px 0;border-bottom:0.01rem solid #f2f1f1;} +.o-shops p{position: relative;padding-left:20px;font-size:.15rem;} +.o-shops i{position: absolute;display: block;top: 1;left: 0;width: 20px;height: 20px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.o-status{color:#de4943;} +.o-status2{float:right;color:#de4943;} +.wst-or-term{padding:2px 0;} +.wst-or-term2{margin-top:10px;padding:10px 0;border-top: 1px solid #f2f1f1;} +.wst-or-term2 .o-status2{font-size:.17rem;font-weight: bold;} +.wst-or-describe{float:left;width: 0.72rem;color: #999;} +.wst-or-describe2{float:left;} +.o-Img{max-width:60px;max-height:60px;width:60px;height:60px;padding-top:5px} +.o-gInfo{padding:5px} +.o-gSpec{color:#ccc} +.border-b{padding-bottom:5px;border-bottom:1px solid #f2f1f1;padding-left: 0;padding-right: 0;} +.o-btn-box{padding-right:0} +.o-btn{float:right;margin-top:10px;margin-left:5px;font-size:.13rem;color:#de0202;border:1px solid #de0202;padding:0 9px} +.o-btn:not(.disabled):not(:disabled):active{color:#de0202;} +.o-cancel-btn{color:inherit;border:1px solid #000} +.o-cancel-btn:not(.disabled):not(:disabled):active{color:inherit} +.wst-wa-info{background:#fff;padding:5px 0;margin-bottom:10px} +.wst-wa-info .info{padding:5px 0;text-align:center;border-bottom:1px solid #ccc} +.wst-wa-info .info span{color:red} +.wst-wa-info .pay-info{text-align: center;padding:10px;color:#000;font-weight:bold;} +.wst-wa-info .pay{padding:10px} +.wst-wa-info .pay input{width:70%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0} +.wst-wa-forget{padding-bottom:20px} +.wst-pa-l{margin-top:8px} +.wst-pa-l .line{border-bottom:1px solid #edebeb} +.wst-pa-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-pa-l .weixinpays{background:url(../img/icon_zhifu.png) 0 1px no-repeat;background-size:97%} +.wst-pa-l .wallets{background:url(../img/icon_zhifu.png) 0 -53px no-repeat;background-size:97%} +.wst-pa-l .alipays{background:url(../img/icon_zhifu.png) 0 -107px no-repeat;background-size:97%} +.ui-dialog-bd{font-size:.15rem} +.cancel-btn-box{margin-left:0;} +.wst-or-process{margin-bottom:0.1rem;} +.wst-or-process .process{position: relative;} +.wst-or-process p{text-align:center;} +.wst-or-process .line{margin-bottom:10px;padding:10px 0;} +.wst-or-process .line span{float:left;width:50%;height:2px;background:#eaeaea;} +.wst-or-process .line span.active{background:#e00102;} +.wst-or-process .icon{position: absolute;left:0;top:0;display: block;width:100%;height:20px;} +.wst-or-process .icon i{height:20px;line-height:20px;font-size: 27px;} +.wst-or-process .icon i.active{color:#e00102;} +.wst-or-process .icon i:before {background: #fff;} +.wst-or-process{margin-bottom:0.1rem;} +.wst-or-process .process{position: relative;} +.wst-or-process p{text-align:center;} +.wst-or-process .line{margin-bottom:10px;padding:10px 0;} +.wst-or-process .line span{float:left;width:50%;height:2px;background:#eaeaea;} +.wst-or-process .line span.active{background:#e00102;} +.wst-or-process .icon{position: absolute;left:0;top:0;display: block;width:100%;height:20px;} +.wst-or-process .icon i{height:20px;line-height:20px;font-size: 27px;} +.wst-or-process .icon i.active{color:#e00102;} +.wst-or-process .icon i:before {background: #fff;} +.detail-head{border-bottom:1px solid #eaeaea;padding:10px 5px;background:#fff;margin-top:5px} +.d-uInfo{background:#fff;height:40px;margin-bottom:5px} +.d-utel{padding-left:15px} +.d-uaddr{padding-left:15px;position:relative} +.d-uaddr i{width:9px;height:25px;display:block;position:absolute;left:1px;top:-3px;background:url(../img/icon_user_adds.png) no-repeat 0 2px;background-size:100%} +.d-goodsitme{background:#fff;border-bottom:0;margin-bottom:5px;font-size:.11rem} +.d-item{background:#fff;border-bottom:1px solid #eaeaea;padding:7px 5px} +.d-item-right{color:#b5b5b5} +.d-gSpec{padding-left:10px} +.price{color:red} +.title{font-size:.15rem;color:#59595c} +#detailBox,#refundBox{font-size:.14rem} +#boxTitle,#refund-boxTitle,#refundFrame{background:#fff} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem;background: red;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:16px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{background:#f2f2f2;overflow:scroll} +.wst-refund{position:fixed;z-index:9999;right:-999px;top:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem;background: red;} +#reject,#reason{height:30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.o-oListMoney{float:left;width:100%;text-align:right;margin-bottom:3px;font-size:.15rem} +.o-oListMoney span{color:#de0202;} +.ui-dialog-bd .ui-dialog-bd-title{padding-left:25px} +.order-tr .title{border:none!important} +.wst-btn-dangerlo{color:#fff;font-size:.15rem;height:38px;line-height:38px;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-btn-dangerlo:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.notice{padding:3px 6px;color:#e55454} +.recharge-box{text-align: center;line-height:40px;padding-top:20px;font-size: 0.18rem;} +.recharge-box .paybox{border-top:1px solid #d2d2d2;font-size:0.25rem;margin:10px;} +.order_from{ margin-left: 10px;color: #fff;font-size:.12rem;padding: 0 4px;line-height:22px;border-radius: 10px;background-color: #f19325;position: absolute;left: 0} +.wst-or-refund{padding: 10px 5px;} +.wst-or-refund .prompt{padding:0 10px 10px 10px;border-bottom: 1px solid #eaeaea;padding} +.wst-or-refund .term{padding:10px 10px 0 10px;line-height:30px;} +.wst-or-refund .sign{color:#de0202;} +#refundReason{width:68%;height: 30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.wst-or-refund .term input{width:68%;height:30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.wst-or-refund .wst-dialog-b2{width:220px;height: 35px;line-height: 35px;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/orders_appraises.css b/hyhproject/mobile2/view/default/css/orders_appraises.css new file mode 100755 index 0000000..11ba3db --- /dev/null +++ b/hyhproject/mobile2/view/default/css/orders_appraises.css @@ -0,0 +1,30 @@ +@CHARSET "UTF-8"; +.item-head{margin-top:5px;padding:5px 10px;background:#fff;border-bottom:1px solid #eaeaea} +.item-head .shop{position: relative;padding-left:20px;font-size:.15rem;} +.item-head .shop i{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.border-b{padding:5px 10px 10px 10px;border-bottom:1px solid #eaeaea} +.g-Img{max-width:60px;max-height:60px;padding-top:5px} +.g-Img img{max-width:60px;max-height:60px;} +.g-gInfo{padding:5px} +.g-gName{max-height:40px;line-height: 20px;font-size:.14rem;} +.g-gSpec{color:#ccc;font-size:.13rem;} +.order-tr{text-align:right;line-height:60px} +.order-tr .appraise{float: right;margin-top:20px;font-size:.13rem;color: #f19325;width:30px;height:25px;background: url(../img/evaluate.png) 0px 0px no-repeat;background-size: 72%;} +.g-item{background:#fff} +.appraise-title{padding-left:10px} +.appraise-name{padding-right:10px;height: 0.42rem;line-height:0.21rem;} +.appraise-box{margin-bottom:10px;padding-top:10px;background:#fff;margin-top:5px;font-size:.14rem;border-bottom:1px solid #eaeaea} +.score{color: #f19325;} +.start-on,.start-not{display:inline-block;width:20px;height:25px;background:url(../img/img_dpjpj.png) no-repeat} +.start-on{background-position:1px 4px;background-size:265%} +.start-not{background-position:-34px 4px;background-size:265%} +.appraisesContent{width:100%;min-height:100px;resize:none} +.post-btn button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.post-btn{margin:0;background:#fff}#appraisesBox{margin-top:15px} +.complainFileBox{margin-left:10px;min-height:65px} +.complainFileBox li{float:left;margin-right:5px;max-height:60px} +.complainFileBox img{max-width:50px;max-height:50px} +.edit_charts{position:relative} +.del-btn{position:relative;top:-43px;left:0} +.ui-icon,[class^="ui-icon-de"]{font-size:20px;position:absolute;left:32px;top:-1px;color:red;line-height:17px} +.webuploader-pick {padding: 5px 6px!important;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/orders_complains.css b/hyhproject/mobile2/view/default/css/orders_complains.css new file mode 100755 index 0000000..6177df7 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/orders_complains.css @@ -0,0 +1,52 @@ +@CHARSET "UTF-8";body{font-size:.14rem} +.order-tab{height:30px;line-height:30px;padding:0;background:#fff} +.item-head{padding:5px} +.tab-item{text-align:center} +.tab-curr{border-bottom:2px solid red} +.order-item{background:#fff;margin:10px auto} +.order-tr{text-align:right} +.o-status{color:red} +.o-Img{max-width:60px;max-height:60px;padding-top:5px} +.o-gInfo{padding:5px} +.o-gName{max-height:40px} +.o-gSpec{color:#ccc} +.border-b{padding-bottom:5px;border-bottom:1px solid #ccc} +.o-btn-box{padding-right:0} +.o-btn{float:right;margin-bottom:5px;margin-right:5px;font-size:.15rem;color:red;border:1px solid red;padding:0 9px} +.o-cancel-btn{color:inherit;border:1px solid #000} +.detail-head{border-bottom:1px solid #eaeaea;padding:10px 5px;background:#fff;margin-top:5px} +.d-uInfo{background:#fff;height:30px;margin-bottom:5px;padding:5px;font-size:.14rem;} +.d-uname{padding:3px 0;margin-left:-4px} +.d-utel{padding-left:15px} +.d-goodsitme{background:#fff;border-bottom:0;margin-bottom:5px;font-size:.13rem} +.d-item{background:#fff;border-bottom:1px solid #eaeaea;padding:5px} +.d-item-right{color:#b5b5b5} +.d-gSpec{padding-left:10px} +.price{color:red} +.title{font-size:.15rem;color:#59595c} +#detailBox{font-size:.15rem}#boxTitle{background:#fff} +.c-item{margin-top:5px;padding:10px 5px;font-size:.15rem} +.c-box{margin:0;padding:0;font-size:.15rem} +.c-title{padding:30px 5px 5px 5px;padding-top:10px;background:#fff;height:36px!important;border-bottom:1px solid #eaeaea} +.c-content{background:#fff;height:125px!important;padding:5px;}#complain{width:100%;height:120px;resize:none} +.webuploader-pick{padding:5px 6px!important;} +.complainFileBox{min-height:60px;margin-top: 15px;margin-left: 5px;} +.complainFileBox li{float:left;margin-right:5px;max-height:60px} +.complainFileBox img{max-width:50px;max-height:50px} +.edit_charts{position:relative} +.del-btn{position:relative;top:-43px;left:0} +.ui-icon,[class^="ui-icon-de"]{font-size:20px;position:absolute;left:32px;top:-1px;color:red;line-height:17px} +.uploadfile-box{background:#fff;height:100px!important;position:relative} +.ui-icon-thumb{line-height:20px} +.uploadfile-input{width:12%;height:25px;position:absolute;left:0;top:73px;z-index:-55;opacity:0} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:0;bottom:-300px;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:15px;color: #222;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{background:#f2f2f2;overflow:scroll} +.complain-item{background:#fff;border-bottom:1px solid #eaeaea;padding:10px;font-size:.14rem}#content{min-height:130px} +.ui-checkbox input,.ui-checkbox-s input{height:18px} +.ui-checkbox input:before,.ui-checkbox-s input:before{left:53px;top:-13px;font-size:26px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.c-btn{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/rebate.css b/hyhproject/mobile2/view/default/css/rebate.css new file mode 100755 index 0000000..05965f9 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/rebate.css @@ -0,0 +1,314 @@ +body { + background: #3d2467; + height: 2000px; +} +.banner img { + width: 6.4rem; + height: 7.18rem; +} +.youhui { + width: 5.95rem; + height: 4.77rem; + background: #5224a8; + margin-left: 0.21rem; + border-radius: 10px; +} +.youhui .yhq { + width: 5.9rem; +} +.youhui .yhq_block { + width: 1.38rem; + height: 1.95rem; + margin-left: 0.09rem; + margin-top: 0.2rem; + float: left; + position: relative; +} +.youhui .yhq_block img { + width: 1.38rem; + height: 1.95rem; +} +.youhui .yhq_btn { + width: 1.25rem; + height: 0.35rem; + background: #ffbd1f; + border-radius: 20px; + font-family: "微软雅黑"; + font-size: 0.15rem; + color: #fff; + text-align: center; + position: absolute; + bottom: 0.06rem; + left: 0.08rem; + line-height: 0.35rem; +} +.youhui .miaosha { + width: 5.72rem; + height: 2.05rem; + background: url(../img/miaosha_bg.png) no-repeat; + margin-left: 0.12rem; + margin-top: 0.17rem; + border-radius: 5px; + padding-top: 0.1rem; +} +.miaosha .mssp { + width: 2rem; + height: 2rem; + background: #7fe4eb; + border-radius: 50%; + margin-left: 0.43rem; + float: left; + position: relative; +} +.miaosha .mssp img { + width: 2.3rem; + height: 2.3rem; + position: absolute; + left: -0.18rem; + top: -0.23rem; +} +.miaosha .zdms { + margin-left: 0.5rem; + margin-top: 0.23rem; + float: left; +} +.miaosha .zdms .ms_p1 { + font-family: "微软雅黑"; + font-size: 0.3rem; + color: #fefd21; +} +.miaosha .zdms .ms_p2 { + font-family: "微软雅黑"; + font-size: 0.24rem; + color: #fff; + margin-left: 0.16rem; + margin-top: 0.12rem; +} +.miaosha .zdms img { + width: 2rem; + height: 0.45rem; + margin-left: 0.23rem; + margin-top: 0.3rem; +} +.hengfu img { + width: 100%; + margin-top: 0.21rem; +} +.bktj img { + width: 5.4rem; + height: 0.92rem; + margin-left: 0.5rem; + margin-top: 0.33rem; +} +.bk_cp1, +.bk_cp2, +.bk_cp3, +.bk_cp4 { + width: 6.33rem; + height: 2.85rem; + margin-top: 0.1rem; +} +.bk_cp1 { + background: url(../img/bk_bg1.png) no-repeat; + background-size: 100%; +} +.bk_cp2 { + background: url(../img/bk_bg2.png) no-repeat; + background-size: 100%; +} +.bk_cp3 { + background: url(../img/bk_bg3.png) no-repeat; + background-size: 100%; +} +.bk_cp4 { + background: url(../img/bk_bg4.png) no-repeat; + background-size: 100%; +} +.bk_cp1 .bk_img1 { + width: 2.6rem; + height: 2.6rem; + margin-left: 0.65rem; + float: left; +} +.bk_cp1 .bk_p1 { + font-family: "微软雅黑"; + font-size: 0.36rem; + color: #fdfd21; + float: left; + margin-left: 0.8rem; + margin-top: 0.3rem; +} +.bk_cp1 .bk_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #fff; + float: left; + margin-left: 0.95rem; + margin-top: 0.25rem; +} +.bk_cp1 .bk_p3 { + font-family: "微软雅黑"; + font-size: 0.3rem; + color: #fdfd21; + float: left; + margin-left: 0.95rem; + margin-top: 0.1rem; +} +.bk_cp1 .bk_img2 { + width: 1.03rem; + height: 0.41rem; + float: left; + margin-left: 0.95rem; + margin-top: 0.25rem; +} +.bk_cp3 .bk_img1 { + width: 2.6rem; + height: 2.6rem; + margin-left: 0.65rem; + float: left; +} +.bk_cp3 .bk_p1 { + font-family: "微软雅黑"; + font-size: 0.36rem; + color: #fdfd21; + float: left; + margin-left: 0.8rem; + margin-top: 0.3rem; +} +.bk_cp3 .bk_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #fff; + float: left; + margin-left: 0.95rem; + margin-top: 0.25rem; +} +.bk_cp3 .bk_p3 { + font-family: "微软雅黑"; + font-size: 0.3rem; + color: #fdfd21; + float: left; + margin-left: 0.95rem; + margin-top: 0.1rem; +} +.bk_cp3 .bk_img2 { + width: 1.03rem; + height: 0.41rem; + float: left; + margin-left: 0.95rem; + margin-top: 0.25rem; +} +.bk_cp2 .bk2_p1 { + font-family: "微软雅黑"; + font-size: 0.36rem; + color: #fdfd21; + float: left; + margin-left: 0.9rem; + margin-top: 0.3rem; +} +.bk_cp2 .bk2_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #fff; + float: left; + margin-left: -1.25rem; + margin-top: 0.95rem; +} +.bk_cp2 .bk2_p3 { + font-family: "微软雅黑"; + font-size: 0.3rem; + color: #fdfd21; + float: left; + margin-left: -1.25rem; + margin-top: 1.3rem; +} +.bk_cp2 .bk_img2 { + width: 1.03rem; + height: 0.41rem; + float: left; + margin-left: -1.25rem; + margin-top: 1.9rem; +} +.bk_cp2 .bk_img1 { + width: 2.6rem; + height: 2.6rem; + margin-left: 0.65rem; + float: left; +} +.bk_cp4 .bk2_p1 { + font-family: "微软雅黑"; + font-size: 0.36rem; + color: #fdfd21; + float: left; + margin-left: 0.9rem; + margin-top: 0.3rem; +} +.bk_cp4 .bk2_p2 { + font-family: "微软雅黑"; + font-size: 0.22rem; + color: #fff; + float: left; + margin-left: -1.25rem; + margin-top: 0.95rem; +} +.bk_cp4 .bk2_p3 { + font-family: "微软雅黑"; + font-size: 0.3rem; + color: #fdfd21; + float: left; + margin-left: -1.25rem; + margin-top: 1.3rem; +} +.bk_cp4 .bk_img2 { + width: 1.03rem; + height: 0.41rem; + float: left; + margin-left: -1.25rem; + margin-top: 1.9rem; +} +.bk_cp4 .bk_img1 { + width: 2.6rem; + height: 2.6rem; + margin-left: 0.65rem; + float: left; +} +.xpss img { + width: 5.4rem; + height: 0.92rem; + margin-left: 0.5rem; + margin-top: 0.33rem; +} +.xpss_nr .xp_cp { + width: 2.77rem; + height: 3.37rem; + background: url(../img/xpbk.png) no-repeat; + background-size: 100%; + margin-left: 0.3rem; + margin-top: 0.27rem; + float: left; +} +.xpss_nr .xp_cp .xpss_img1 { + width: 2.4rem; + height: 2.4rem; + margin-left: 0.16rem; +} +.xpss_nr .xp_cp .xpss_p1 del { + font-family: "微软雅黑"; + font-size: 0.16rem; + font-weight: 300; + color: #5f5f5f; +} +.xpss_nr .xp_cp .xpss_p1 { + font-family: "微软雅黑"; + font-size: 0.4rem; + color: #f1063a; + font-weight: 800; + margin-top: -0.25rem; + margin-left: 0.2rem; +} +.xpss_nr .xp_cp .xpss_img2 { + width: 2.17rem; + height: 0.39rem; + margin-left: 0.25rem; + margin-top: 0.15rem; +} diff --git a/hyhproject/mobile2/view/default/css/rebate.less b/hyhproject/mobile2/view/default/css/rebate.less new file mode 100755 index 0000000..0e99ac3 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/rebate.less @@ -0,0 +1,361 @@ +body { + background: #3d2467; + height: 2000px; +} + +.banner img { + width: 640/100rem; + height: 718/100rem; +} + +.youhui { + width: 595/100rem; + height: 477/100rem; + background: #5224a8; + margin-left: 21/100rem; + border-radius: 10px; +} + +.youhui .yhq { + width: 590/100rem; +} + +.youhui .yhq_block { + width: 138/100rem; + height: 195/100rem; + margin-left: 9/100rem; + margin-top: 20/100rem; + float: left; + position: relative; +} + +.youhui .yhq_block img { + width: 138/100rem; + height: 195/100rem; +} + +.youhui .yhq_btn { + width: 125/100rem; + height: 35/100rem; + background: #ffbd1f; + border-radius: 20px; + font-family: "微软雅黑"; + font-size: 15/100rem; + color: #fff; + text-align: center; + position: absolute; + bottom: 6/100rem; + left: 8/100rem; + line-height: 35/100rem; +} + +.youhui .miaosha { + width: 572/100rem; + height: 205/100rem; + background: url(../img/miaosha_bg.png) no-repeat; + margin-left: 12/100rem; + margin-top: 17/100rem; + border-radius: 5px; + padding-top: 10/100rem; +} + +.miaosha .mssp { + width: 200/100rem; + height: 200/100rem; + background: #7fe4eb; + border-radius: 50%; + margin-left: 43/100rem; + float: left; + position: relative; +} + +.miaosha .mssp img { + width: 230/100rem; + height: 230/100rem; + position: absolute; + left: -18/100rem; + top: -23/100rem; +} + +.miaosha .zdms { + margin-left: 50/100rem; + margin-top: 23/100rem; + float: left; +} + +.miaosha .zdms .ms_p1 { + font-family: "微软雅黑"; + font-size: 30/100rem; + color: #fefd21; +} + +.miaosha .zdms .ms_p2 { + font-family: "微软雅黑"; + font-size: 24/100rem; + color: #fff; + margin-left: 16/100rem; + margin-top: 12/100rem; +} + +.miaosha .zdms img { + width: 200/100rem; + height: 45/100rem; + margin-left: 23/100rem; + margin-top: 30/100rem; +} + +.hengfu img { + width: 100%; + margin-top: 21/100rem +} + +.bktj img { + width: 540/100rem; + height: 92/100rem; + margin-left: 50/100rem; + margin-top: 33/100rem; +} + +.bk_cp1, +.bk_cp2, +.bk_cp3, +.bk_cp4 { + width: 633/100rem; + height: 285/100rem; + margin-top: 10/100rem; + +} + +.bk_cp1 { + background: url(../img/bk_bg1.png) no-repeat; + background-size: 100%; +} + +.bk_cp2 { + background: url(../img/bk_bg2.png) no-repeat; + background-size: 100%; +} + +.bk_cp3 { + background: url(../img/bk_bg3.png) no-repeat; + background-size: 100%; +} + +.bk_cp4 { + background: url(../img/bk_bg4.png) no-repeat; + background-size: 100%; +} + +.bk_cp1 .bk_img1{ + width: 260/100rem; + height: 260/100rem; + margin-left: 65/100rem; + float: left; +} + +.bk_cp1 .bk_p1{ + font-family: "微软雅黑"; + font-size: 36/100rem; + color: #fdfd21; + float: left; + margin-left: 80/100rem; + margin-top: 30/100rem; +} + +.bk_cp1 .bk_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #fff; + float: left; + margin-left: 95/100rem; + margin-top: 25/100rem; +} + +.bk_cp1 .bk_p3{ + font-family: "微软雅黑"; + font-size: 30/100rem; + color: #fdfd21; + float: left; + margin-left: 95/100rem; + margin-top: 10/100rem; +} + +.bk_cp1 .bk_img2{ + width: 103/100rem; + height: 41/100rem; + float: left; + margin-left: 95/100rem; + margin-top: 25/100rem; +} + +.bk_cp3 .bk_img1{ + width: 260/100rem; + height: 260/100rem; + margin-left: 65/100rem; + float: left; +} + +.bk_cp3 .bk_p1{ + font-family: "微软雅黑"; + font-size: 36/100rem; + color: #fdfd21; + float: left; + margin-left: 80/100rem; + margin-top: 30/100rem; +} + +.bk_cp3 .bk_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #fff; + float: left; + margin-left: 95/100rem; + margin-top: 25/100rem; +} + +.bk_cp3 .bk_p3{ + font-family: "微软雅黑"; + font-size: 30/100rem; + color: #fdfd21; + float: left; + margin-left: 95/100rem; + margin-top: 10/100rem; +} + +.bk_cp3 .bk_img2{ + width: 103/100rem; + height: 41/100rem; + float: left; + margin-left: 95/100rem; + margin-top: 25/100rem; +} + +.bk_cp2 .bk2_p1{ + font-family: "微软雅黑"; + font-size: 36/100rem; + color: #fdfd21; + float: left; + margin-left: 90/100rem; + margin-top: 30/100rem; +} +.bk_cp2 .bk2_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #fff; + float: left; + margin-left:-125/100rem; + margin-top: 95/100rem; +} +.bk_cp2 .bk2_p3{ + font-family: "微软雅黑"; + font-size: 30/100rem; + color: #fdfd21; + float: left; + margin-left:-125/100rem; + margin-top: 130/100rem; +} + +.bk_cp2 .bk_img2{ + width: 103/100rem; + height: 41/100rem; + float: left; + margin-left:-125/100rem; + margin-top: 190/100rem; +} + +.bk_cp2 .bk_img1{ + width: 260/100rem; + height: 260/100rem; + margin-left: 65/100rem; + float: left; +} +.bk_cp4 .bk2_p1{ + font-family: "微软雅黑"; + font-size: 36/100rem; + color: #fdfd21; + float: left; + margin-left: 90/100rem; + margin-top: 30/100rem; +} +.bk_cp4 .bk2_p2{ + font-family: "微软雅黑"; + font-size: 22/100rem; + color: #fff; + float: left; + margin-left:-125/100rem; + margin-top: 95/100rem; +} +.bk_cp4 .bk2_p3{ + font-family: "微软雅黑"; + font-size: 30/100rem; + color: #fdfd21; + float: left; + margin-left:-125/100rem; + margin-top: 130/100rem; +} + +.bk_cp4 .bk_img2{ + width: 103/100rem; + height: 41/100rem; + float: left; + margin-left:-125/100rem; + margin-top: 190/100rem; +} + +.bk_cp4 .bk_img1{ + width: 260/100rem; + height: 260/100rem; + margin-left: 65/100rem; + float: left; +} + +.xpss img{ + width: 540/100rem; + height: 92/100rem; + margin-left: 50/100rem; + margin-top: 33/100rem; +} + +.xpss_nr .xp_cp{ + width: 277/100rem; + height: 337/100rem; + background: url(../img/xpbk.png) no-repeat; + background-size: 100%; + margin-left: 30/100rem; + margin-top: 27/100rem; + float: left; +} + +.xpss_nr .xp_cp .xpss_img1{ + width: 240/100rem; + height: 240/100rem; + margin-left: 16/100rem; +} + +.xpss_nr .xp_cp .xpss_p1 del{ + font-family: "微软雅黑"; + font-size: 16/100rem; + font-weight: 300; + color: #5f5f5f; + +} +.xpss_nr .xp_cp .xpss_p1{ + font-family: "微软雅黑"; + font-size: 40/100rem; + color: #f1063a; + font-weight: 800; + margin-top: -25/100rem; + margin-left: 20/100rem; +} + +.xpss_nr .xp_cp .xpss_img2{ + width: 217/100rem; + height: 39/100rem; + margin-left: 25/100rem; + margin-top: 15/100rem; +} + + + + + diff --git a/hyhproject/mobile2/view/default/css/recharge.css b/hyhproject/mobile2/view/default/css/recharge.css new file mode 100755 index 0000000..7ef4160 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/recharge.css @@ -0,0 +1,36 @@ +.ui-radio input:checked:after{background:#f43d30;} +.ui-grid-trisect{background-color:#fff; } +.j-charge-money{display: none;} +.charge-othermoney{width:1rem;height:0.29rem;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{border: 2px solid #e2e2e2;text-align:center;position:relative; } +.wst-frame2{border: 2px solid #e2e2e2;text-align:center;border-radius: 10px;position:relative;padding: 0.2rem 0;font-size: 0.13rem; } +.wst-frame2 div{line-height:normal; } +.wst-frame2 div.charge-alone{line-height:0.3rem;font-size: 0.13rem;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;} +.tips-box{margin:0.1rem;} +.paytype-term{padding:0 0.1rem 0 0.05rem;font-size: 0.14rem;border-bottom: 1px solid #f2f1f1;} +.paytype-term label{position: absolute;top:23px;right:0;} +.paytype-term i{display: block;width:44px;height: 44px;} +.paytype-term .alipays{background: url(../img/pays-ali.png) center center no-repeat;background-size: 70%;} +.paytype-term .weixinpays{background: url(../img/pays-weixin.png) center center no-repeat;background-size: 70%;} +.paytype-term .unionpay{background: url(../img/pays-union.png) center center no-repeat;background-size: 70%;} +.first-time{font-size: 0.15rem;color: #abaaaa;padding-left: 5px;margin-top: 10px;} +.wst-re-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.ui-checkbox input:before, .ui-checkbox-s input:before{font-size: 24px;color:#ff3c3c;} +.ui-checkbox input:checked:before, .ui-checkbox-s input:checked:before{color:#ff3c3c;} +.wst-re-info{margin:0.08rem 0;padding:0.1rem;background-color:#fff;font-size: 0.15rem;} +.wst-re-info p{padding:0.05rem 0;color: #999;} +.wst-re-info .balance{padding-left:0.2rem;font-size: 0.13rem;color:#df0202;} +.wst-re-info .balance span{font-size: 0.15rem;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/security.css b/hyhproject/mobile2/view/default/css/security.css new file mode 100755 index 0000000..57f83ac --- /dev/null +++ b/hyhproject/mobile2/view/default/css/security.css @@ -0,0 +1,19 @@ +@CHARSET "UTF-8"; +.wst-se-l{margin-top:8px} +.wst-se-l .line{border-bottom:1px solid #edebeb} +.wst-se-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-se-l .pay{background:url(../img/icon_zhanghuanquan.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .phone{background:url(../img/icon_zhanghuanquan.png) 0 -53px no-repeat;background-size:97%} +.wst-se-pay{font-size:.18rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-se-pay .pay{padding-bottom:10px} +.wst-se-pay .pay input{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;font-size:.14rem;} +.wst-se-footer{position:fixed;width:100%;z-index:100;left:0;bottom:0} +.wst-se-footer .button{position:absolute;left:3%;bottom:10px;width:93%;margin-bottom:6px;font-size:.15rem;height:38px;line-height:38px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-se-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-se-pay .verify{border-radius:2px;margin-bottom:10px;border:1px solid #a0a0a0} +.wst-se-pay .verify input{width:60%;padding:2px 2px 2px 5px;height:36px;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.14rem;} +.wst-se-pay .verify button{float:right;height:36px;width:40%;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;font-size:.14rem;} +.wst-se-pay .verify img{float:right;height:36px;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-se-pay .phone{padding:10px;font-size:.15rem;} +.wst-se-back{padding:10px;font-size:.14rem;} +.wst-se-back a{color: #999;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/self_shop.css b/hyhproject/mobile2/view/default/css/self_shop.css new file mode 100755 index 0000000..319750a --- /dev/null +++ b/hyhproject/mobile2/view/default/css/self_shop.css @@ -0,0 +1,87 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.ui-footer ~ .ui-container{border: 0px solid transparent;} +.wst-se-header2 .ui-icon-return {color: #59595c;} +.wst-se-header3{position: absolute;padding-left: 0;background: transparent;border-bottom: 0px;} +.wst-se-search2{width: 66%;margin-right: 23%;} +.wst-se-search2 input{background: rgba(255,255,255,0.5);} +.wst-se-search2 input::-webkit-input-placeholder {color:#fff;} +.wst-se-search2 input:-moz-placeholder {color:#fff;} +.wst-se-search2 input::-moz-placeholder {color:#fff;} +.wst-se-search2 inputt:-ms-input-placeholder {color:#fff;} +.wst-se-header3 .ui-icon-return,.wst-se-header3 .ui-icon-search{color: #fff;} +.wst-se-icon0{background: url(../img/classify.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2{right: 40px;background: url(../img/cart.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2 i{display: inline-block;text-align: center;background: #de0202;color: #fff;height: 15px;line-height: 15px;border-radius: 10px;padding: 0 5px;background-clip: padding-box;font-size: .1rem;position: absolute;top: 0;left: 20px;} +.wst-sh-banner{display: block;width:100%;height:1.7rem;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.shop-banner{width:100%;} +.shop-photo{position: relative;} +.shop-photo .photo{display: block;width:0.8rem;height:0.8rem;margin-left:0.1rem;padding:0.05rem;position: absolute;top:-0.42rem;background: #fff;border-radius: 3px;} +.shop-photo .photo img{width:100%;height:100%;border: 1px solid #f2f1f1;border-radius: 2px;} +.shop-photo .photo .name{position: absolute;left:-0.05rem;bottom:-0.28rem;width:2.6rem;font: 0.16rem/31px verdana;} +.shop-photo .introduce{float:right;margin:0.1rem 0.1rem 0 0;font-size:0.14rem;color:#de0202;} +.shop-info{padding-top:0.8rem;text-align:center;font-size:0.13rem;} +.shop-btn{float:left;margin-left: 0.11rem;margin-top: 0.05rem;width:30px;height:30px;background: url(../img/follow-shop.png) 1px 3px no-repeat;background-size: 200%;} +.shop-btn.follow{background: url(../img/follow-shop.png) -31px 3px no-repeat;background-size: 200%;} +.shop-notice{padding:0.1rem;font-size:0.13rem;border-bottom: 0.05rem solid #f2f1f1;} +.shop-notice .title{margin-bottom:0.05rem;font-size:0.15rem;} +.shop-ads{margin:5px auto;width:100%;} +.wst-gol-adsb{padding:0.05rem 0;height:110px;background:#fff;font-size:0.13rem;} +.wst-gol-adsb p{float:left;width:100%;color:#de0202;text-align:center} +.wst-gol-img{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative;} +.wst-gol-img a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.wst-gol-img a img{max-width:100px;max-height:100px} +.shop-floor-title{background:#fff;padding-left:5px;height:33px;line-height:33px;font-size:0.15rem;margin-bottom:0.04rem;} +.f0{border-left:3px solid #dc4bd1;color:#dc4bd1;} +.f1{border-left:3px solid #8a5063;color:#8a5063;} +.f2{border-left:3px solid #df2003;color:#df2003;} +.f3{border-left:3px solid lightblue;color:lightblue;} +.f4{border-left:3px solid #ff8043;color:#ff8043;} +.f5{border-left:3px solid #24b0ed;color:#24b0ed;} +.f6{border-left:3px solid green;color:green;} +.shop-more{float:right;margin-right:5px;display:inline-block;padding-right:20px;position: relative;} +.shop-more i{position: absolute;display: block;width:33px;height:33px;top:-6px;right:-7px;} +.wst-shl-head{background:#fff;font-size:.158rem;color:#6a6b6d} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:22px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;border-bottom:2px solid #de0202} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up{background:url(../img/img_jgsx.png) 0 -19px no-repeat;background-size:285%} +.wst-shl-head .sorts .up2{background:url(../img/img_jgsx.png) -28px -19px no-repeat;background-size:285%} +.wst-shl-head .sorts .down{background:url(../img/img_jgsx.png) 0 2px no-repeat;background-size:285%} +.wst-shl-head .sorts .down2{background:url(../img/img_jgsx.png) -28px 2px no-repeat;background-size:285%} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding:5px;margin-bottom:0.04rem;font-size:0.14rem;background:#fff;color: #232326; font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.05rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;text-decoration:line-through;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;height:100%;background:#f6f6f8;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;border-bottom:1px solid #f6f6f8;;background:#fff;height:41px;line-height:41px;text-align:center;font-size: 14px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-scrollerl{width:24%;height:100%;overflow:hidden;background:#fff;position:fixed} +.ui-scrollerl li{padding:13px 5px;font-size: 0.129rem;text-align:center} +.wst-goodscate{color: #232326;border-top: 1px solid #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #f6f6f8;} +.wst-goodscate_selected{color: #df0202;background: #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #df0202;} +.wst-scrollerr{width:76%;float:right} +.wst-scrollerr li{float:left;width:100%;font-size:.15rem;color:#000} +.wst-goodsca{height:35px;background:#f2f2f2;margin-bottom:8px;} +.wst-goodsca span{float:left;color: #232326;margin-top:8px;margin-left:8px;border-left:2px solid #fc786b;font-size: 0.13rem;} +.wst-goodsca i{float:right;height:35px;margin-top:-6px;color:#fc786b} +.wst-goodscat{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscats{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscat span{float:left;width:49%;padding:8px 0;text-align:center;background:#fff;border:0.01rem solid #f2f1f1;color: #686868;font-size: 0.12rem;} +.wst-goodscat span a{color:#69696b} +.notice{display:flex;align-items:center;padding:5px;margin-bottom:5px;background:#fff} +.notice_img{width:20px;height:20px} +.notice_txt{min-height:30px;flex:1;padding-left:6px} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/settlement.css b/hyhproject/mobile2/view/default/css/settlement.css new file mode 100755 index 0000000..e5f7d42 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/settlement.css @@ -0,0 +1,85 @@ +@CHARSET "UTF-8"; +.ui-list-link > li:after{color:#848484;} +.wst-se-address{margin:10px 0px;padding-bottom:0.04rem;position: relative;} +.wst-se-address:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.04rem;background: url(../img/line-address.png) 0px 0px;-webkit-transform: scale(0.5);} +.wst-se-address .infot{color:#59595c;font-size:0.15rem;height: 22px;line-height: 22px;} +.wst-se-address .infob{font-size:0.158rem;position: relative;text-indent:1em;height: 23px;line-height: 23px;} +.wst-se-address .infob i{position: absolute;left:-23px;top:-12px;color:#df0001;} +.wst-se-address .infono{color:#f8a106;height: 36px;line-height: 36px;} +.wst-se-sh{padding:0px 10px 6px 10px;margin:5px 0px;font-size: 0.15rem;background:#ffffff;} +.wst-se-sh .shopn{padding:6px 0px 2px 20px;position: relative;} +.wst-se-sh .shopn i{position: absolute;display: block;bottom: 2px;left: 0;width: 20px;height: 20px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.wst-se-sh .goods .img{float: left;width: 100%;height: 70px;text-align: center;vertical-align: middle;display: block;} +.wst-se-sh .goods{padding:5px 0px;border-bottom: 1px solid #f1f1f1;font-size:0.13rem;} +.wst-se-sh .goods .img a{width: 100%;height: 70px;display: table-cell;vertical-align: middle;} +.wst-se-sh .goods .img a img{max-width: 70px;max-height: 70px;} +.wst-se-sh .name{padding:0px 5px;} +.wst-se-sh .names{font-size: 0.14rem;} +.wst-se-sh .spec{color: #a6a6a6;} +.wst-se-sh .price,.wst-se-sh .number{text-align: right;font-size: 0.14rem;} +.wst-se-sh .remarks,.wst-se-sh .cost{padding:5px 0px;} +.wst-se-sh .cost span{float: right;color: #de0202;} +.wst-se-sh .remarks textarea{width:100%;height: 30px;padding: 5px;} +.wst-se-sh .remarks textarea:focus{height:58px;border:1px solid #3bb4f2;} +.wst-se-mode .mode{border-bottom: 1px solid #f1f1f1;} +.wst-se-mode .ui-txt-info{width:78%;text-align: right;} +.ui-list li h4 {font-size: 0.15rem;} +.wst-se-mode{font-size: 0.15rem;} +.wst-se-total{height: 38px;line-height: 38px;padding:0px 10px;font-weight: bold;font-size: 0.17rem;} +.wst-se-total span{float: right;color: #de0202;} +.wst-se-confirm .button{position: absolute;left:3%;bottom:2px;width: 93%;margin-bottom:6px;height: 38px;line-height: 38px;color:#ffffff;background:#e00102;font-size: 0.15rem;border-radius:3px;border-bottom:1px solid #e00102;} +.wst-se-confirm .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} +/*遮盖层*/ +.wst-cover{position:fixed;left:0px;top:0px;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60); /*设置透明度为60%*/opacity:0.6; /*非IE浏览器下设置透明度为60%*/z-Index:9999;display:none;} +/*参数弹框*/ +.wst-fr-box{position: fixed;z-index: 9999;left:0px;bottom: -226px;width:100%;min-height:40%;background-color: #f6f6f8;font-size: 0.15rem;} +.wst-fr-box .title{position: relative;padding:6px 0px;background-color: #ffffff;border-bottom: 1px solid #f1f1f1;} +.wst-fr-box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position: absolute;right:5px;top:-2px;font-size: 27px;} +.wst-fr-box .content{padding:8px 0px 50px 0px;} +.wst-fr-box .button,.wst-cart-box .button{position: absolute;left:3%;bottom:4px;width: 93%;height: 38px;line-height: 38px;color:#ffffff;background:#e00102;font-size: 0.15rem;border-radius:3px;border-bottom:1px solid #e00102;} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} +.wst-list-infose1{width:90%;padding-left: 0px;padding-top: 8px;padding-bottom: 8px;position: relative;} +.wst-list-infose1 span{float:left;width:100%;height: 20px;line-height: 20px;font-size:0.14rem;} +.wst-list-infose1 i{position: absolute;top:0;left:-13px;display: block;width:36px;height: 36px;} +.wst-list-infose1 .alipays{background: url(../img/pays-ali.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .weixinpays{background: url(../img/pays-weixin.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .cod{background: url(../img/pays-cod.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .wallets{background: url(../img/pays-wallets.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .unionpay{background: url(../img/pays-union.png) center center no-repeat;background-size: 70%;} +.ui-list{position: relative;} +.ui-icon-push{position: absolute;top:0;right:0;width:32px;height: 36px;line-height: 36px;font-size: 0.32rem;} +.wst-se-line{padding:0px 10px;} +.wst-se-line p{border-bottom:1px solid #EDEDED;} +.wst-fr-invoice{padding:0px 10px;background: #ffffff;font-size:0.18rem;} +.wst-fr-invoice textarea{width: 100%;height: 46px;padding: 2px;} +.wst-fr-invoice textarea:focus{border:1px solid #3bb4f2;} +.wst-fr-score{padding-top:10px;} +.wst-fr-score span{color:#e00102;} +/* 发票信息层 */ +.invoice_box{position: fixed;z-index: 9999;right:-999px;bottom: 0px;width:100%;min-height:40%;background:#f2f2f2;font-size: 0.15rem;top:0;} +.invoice_box .title,.wst-cart-box .title{position: relative;padding:6px 0px;border-bottom: 1px solid #f1f1f1;background-color: #fff;} +.invoice_box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 16px;} +.invoice_box .title i,.wst-cart-box .title i{position: absolute;right:5px;top:-2px;font-size: 27px;} +.invoice_box .content{margin-top:5px;background:#f2f2f2;overflow: scroll;min-height: 80%;} +.inv_ul{margin-right: 15px;padding: 0 15px;position: relative;width: inherit;float: left;} +.pdtb10{padding: 10px 0;} +.inv_chk{position: absolute;left: 0;} +.inv_item{padding: 15px 10px;background-color: #fff;} +.inv_tit{color: #232326;font-size: 14px;padding-left: 5px;} +.inv_hidebox{background-color: #fff;width: 100%;position: relative;display: none;} +.inv_head_input{border: 0;border-radius: 3px;padding: 8px 0 8px 10px;width: 100%;color: #232326;font-size: 13px;background: #f0f2f5;padding-right: 30px;} +#inv_headlist{display: none;position: absolute;z-index: 3;width: 100%;background-color: #fff;} +.inv_list_item{width: 100%;background-color: #f0f2f5;} +.inv_list_item li{padding-left: 10px;line-height: 35px;border-top: 1px solid #e0e0e0;-webkit-line-clamp: 1;} +.inv_code_input{border: 0;border-radius: 3px;padding: 8px 0 8px 10px;height: 35px;width: 100%;color: #232326;font-size: 13px;background: #f0f2f5;padding-right: 30px;display: -webkit-box;} +.inv_code_input::-webkit-input-placeholder{color:#f23030} +.inv_code_input::-moz-placeholder{color:#f23030} +.inv_code_input::-ms-input-placeholder{color:#f23030} +.inv_code_inputbox{margin-top:10px} +.inv_line{padding-bottom: 5px;border-bottom: 1px solid #ccc;} +.none_float{float:inherit} +.inv_tip{padding: 15px 10px;} +.inv_tip li i{font-style: normal;font-size: 20px;font-weight: bold;margin-right: 5px;} +.invoice_box .button{position: absolute;left:3%;bottom:4px;width: 93%;font-size: 0.185rem;height: 40px;line-height: 40px;color:#ffffff;background:#e00102;font-size: 0.18rem;border-radius:3px;border-bottom:1px solid #e00102;} +.invoice_box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/shop_home.css b/hyhproject/mobile2/view/default/css/shop_home.css new file mode 100755 index 0000000..12f5c2b --- /dev/null +++ b/hyhproject/mobile2/view/default/css/shop_home.css @@ -0,0 +1,78 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.ui-footer ~ .ui-container{border: 0px solid transparent;} +.wst-se-header2 .ui-icon-return {color: #59595c;} +.wst-se-header3{position: absolute;padding-left: 0;background: transparent;border-bottom: 0px;} +.wst-se-search2{width: 66%;margin-right: 23%;} +.wst-se-search2 input{background: rgba(255,255,255,0.5);} +.wst-se-search2 input::-webkit-input-placeholder {color:#fff;} +.wst-se-search2 input:-moz-placeholder {color:#fff;} +.wst-se-search2 input::-moz-placeholder {color:#fff;} +.wst-se-search2 inputt:-ms-input-placeholder {color:#fff;} +.wst-se-header3 .ui-icon-return,.wst-se-header3 .ui-icon-search{color: #fff;} +.wst-se-icon0{background: url(../img/classify.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2{right: 40px;background: url(../img/cart.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2 i{display: inline-block;text-align: center;background: #de0202;color: #fff;height: 15px;line-height: 15px;border-radius: 10px;padding: 0 5px;background-clip: padding-box;font-size: .1rem;position: absolute;top: 0;left: 20px;} +.wst-sh-banner{display: block;width:100%;height:1.7rem;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.shop-banner{width:100%;} +.shop-photo{position: relative;} +.shop-photo .photo{display: block;width:0.8rem;height:0.8rem;margin-left:0.1rem;padding:0.05rem;position: absolute;top:-0.42rem;background: #fff;border-radius: 3px;} +.shop-photo .photo img{width:100%;height:100%;border: 1px solid #f2f1f1;border-radius: 2px;} +.shop-photo .photo .name{position: absolute;left:-0.05rem;bottom:-0.28rem;width:2.6rem;font: 0.16rem/31px verdana;} +.shop-photo .introduce{float:right;margin:0.1rem 0.1rem 0 0;font-size:0.14rem;color:#de0202;} +.shop-info{padding-top:0.6rem;text-align:center;font-size:0.13rem;} +.shop-btn{float:left;margin-left: 0.11rem;margin-top: 0.05rem;width:30px;height:30px;background: url(../img/follow-shop.png) 1px 3px no-repeat;background-size: 200%;} +.shop-btn.follow{background: url(../img/follow-shop.png) -31px 3px no-repeat;background-size: 200%;} +.shop-notice{padding:0.1rem;font-size:0.13rem;border-bottom: 0.05rem solid #f2f1f1;} +.shop-notice .title{margin-bottom:0.05rem;font-size:0.15rem;} +.shop-ads{margin:0 auto;width:100%;} +.wst-sh-term{width:100%;border-bottom: 2px solid #ebebed;background:#fff;} +.wst-sh-term li{float:left;height:20px;padding:10px 20px;font: bold 0.155rem/20px verdana;background:#fff;color:#000;} +.wst-sh-term li.active{color:#de0202;} +.wst-sh-term.active{position: fixed;top:0;left:0;z-index:100;} +.wst-sh-index,.wst-sh-list{background: #f6f6f8;} +.wst-sh-index .index,.wst-sh-list .index{display: block;width:100%;} +.wst-sh-index .title{padding:0.1rem 0.1rem;font-size:0.15rem;background: #fff;border-bottom: 0.03rem solid #f6f6f8;} +.wst-sh-list{display:none;} +.wst-shl-head{background:#fff;font-size:.15rem;color:#6a6b6d;margin-bottom: 0.04rem;} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:22px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-sh-goods{height: calc(100% - 0.8rem);height: -webkit-calc(100% - 0.8rem);height: -moz-calc(100% - 0.8rem);height: -ms-calc(100% - 0.8rem);height: -o-calc(100% - 0.8rem);} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding:5px;margin-bottom:0.04rem;font-size:0.14rem;background:#fff;color: #232326;font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.05rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;text-decoration:line-through;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;height:100%;background:#f6f6f8;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;border-bottom:1px solid #f6f6f8;;background:#fff;height:41px;line-height:41px;text-align:center;font-size: 14px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-scrollerl{width:24%;height:100%;overflow:hidden;background:#fff;position:fixed} +.ui-scrollerl li{padding:13px 5px;font-size: 0.129rem;text-align:center} +.wst-goodscate{color: #232326;border-top: 1px solid #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #f6f6f8;} +.wst-goodscate_selected{color: #df0202;background: #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #df0202;} +.wst-scrollerr{width:76%;float:right} +.wst-scrollerr li{float:left;width:100%;font-size:.15rem;color:#000} +.wst-goodsca{height:35px;background:#f2f2f2;margin-bottom:8px;} +.wst-goodsca span{float:left;color: #232326;margin-top:8px;margin-left:8px;border-left:2px solid #fc786b;font-size: 0.13rem;} +.wst-goodsca i{float:right;height:35px;margin-top:-6px;color:#fc786b} +.wst-goodscat{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscats{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscat span{float:left;width:49%;padding:8px 0;text-align:center;background:#fff;border:0.01rem solid #f2f1f1;color: #686868;font-size: 0.12rem;} +.wst-goodscat span a{color:#69696b} +.pd0{padding-right:6px!important} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/shops.css b/hyhproject/mobile2/view/default/css/shops.css new file mode 100755 index 0000000..55d7f23 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/shops.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +.wst-shop{padding-top:5px} +.wst-shop-home-bg{margin:0 auto;width:100%;height:190px;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.wst-shop-photo{width:50px;height:50px;margin:0 auto;padding-top:20px;padding-bottom:10px;} +.wst-shop-photo img{width:100%;height:100%;border-radius:50%} +.wst-shop-name{font-size:0.19rem} +.wst-shop-name{width:100%;height:30px;text-align:center;color:#fff} +.shop-home-btn-box{width:70%;margin:10px auto;height:30px} +.shop-home-btn img{position:absolute;width:16px;height:15px;margin-top:4px;left:8px} +.shop-home-btn{position:relative;background:transparent;height:25px;line-height:25px;color:#fff;border:1px solid #fff;padding:0!important;font-size:.13rem;width:25px;padding-left:8px!important} +.shop-home-btn:before{border: none;} +.shop-home-btn:not(.disabled):not(:disabled):active{background:transparent;color:fff;} +.f-btn,.f-btn:not(.disabled):not(:disabled):active{background:#fff;color:#e8121e} +.f-btn:before{border: none;} +.score-box{margin:0 auto;width:100%;height:35px;margin-top:10px} +.score-item{color:#fff;padding-top:5px;text-align:center;font-size:.13rem;} +.wst-shop-home-info{margin-top:10px;font-size:.14rem;width:100%;height:300px} +.wst-shop-home-view{margin-top:8px;width:100%;height:80px;position:fixed} +.shop-info li{padding:0.08rem 0.1rem;border-bottom:1px solid #e7e7e7} +.shop-qrcode{margin-top:30px;text-align:center} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/shops_list.css b/hyhproject/mobile2/view/default/css/shops_list.css new file mode 100755 index 0000000..e5e1860 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/shops_list.css @@ -0,0 +1,50 @@ +@CHARSET "UTF-8"; +.wst-shl-adsb{padding:0.05rem 0;height:110px;background:#fff;} +.wst-shl-adsb img{width:100%;height:100%;display:block} +.wst-shl-head{background:#fff;font-size:0.14rem;color:#232326;} +.wst-shl-head .choice{width:65%;height:20px;line-height:22px;margin:0 auto;padding:9px 0} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .active select{color:#de0202} +.wst-shl-select select{color:#232326;;padding-right:0} +.wst-shl-select:after{color:#232326;} +.wst-shl-select.active:after{color:#de0202} +.ui-select:after{display:none} +.wst-shl-head .evaluate{text-align:center;position:relative} +.wst-shl-head .evaluate i{width:15px;height:15px;position:absolute;right:36px;top:12px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-current{color:#e77f74} +.wst-shl-list{padding:5px 10px;margin-top:5px;background:#fff; } +.wst-shl-list .img{width: 100%; float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.wst-shl-list .img a{width:100%;height:55px;display:table-cell;vertical-align:middle; border:1px solid #eee;} +.wst-shl-list .info{padding-left:16px} +.wst-shl-list .title{margin-bottom:0;font-size:0.11rem;color:#363638;font-weight: bold;} +.wst-shl-list p{font-size:0.10rem;height:0.2rem;} +.wst-shl-list p img{width:0.16rem} +.wst-shl-list p span{float:left} +.wst-shl-list p i{float:left;width:0.12rem;height:0.16rem;margin:0.01rem 0.03rem 0 0} +.wst-shl-list p .bright{background:url(../img/img_dpjpj.png) 0 0 no-repeat;background-size:300%} +.wst-shl-list p .dark{background:url(../img/img_dpjpj.png) -0.3rem 0 no-repeat;background-size:300%} +.wst-brands{float:left;width:50%;height:1rem;margin-top:10px;padding:0 0.1rem;box-sizing:border-box} +.wst-brands.left{padding-right:0.05rem;} +.wst-brands.right{padding-left:0.05rem;} +.wst-brands_img{height:0.8rem;padding:5px 0 5px 2px;background:#fff;box-shadow:0 1px 2px #f1f0f0} +.wst-brands_img a{width:100%;height:0.8rem;text-align:center;display:table-cell;vertical-align:middle} +.wst-brands img{max-width:0.9rem;max-height:0.8rem;border-radius:3px} +.wst-brands span{float:left;font-size:0.13rem;line-height:0.8rem;width:0.65rem;height:0.8rem;margin-left:4px;padding:0 0.05rem;border-left:1px solid #e6e6e6;} +.goods-box{padding:0!important;} +.goodsImg a{width:100%;height:70px;display:table-cell;vertical-align:middle; } +.goodsImg img{width:70px;height:70px; } +.goods-item{margin-right: 5px;width:24%; position: relative;float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.goods-item img{border:1px solid #eee;} +.goodsPrice{color: red;} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header img{height:60px;width:60px;} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;height: 20px;} +.wst-action{margin-top: 5px; ;display: inline-block;height: 25px;width: 90%;font-size: 0.14rem;color: red; line-height: 25px;text-align: center;border-radius: 10px;border: 1px solid red;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/swiper.min.css b/hyhproject/mobile2/view/default/css/swiper.min.css new file mode 100755 index 0000000..b7d8cc7 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/swiper.min.css @@ -0,0 +1,15 @@ +/** + * Swiper 3.1.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2015, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: August 22, 2015 + */ +.swiper-container{margin:0 auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:300ms;-moz-transition:300ms;-o-transition:300ms;transition:300ms;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination{bottom:10px;left:0;width:100%}.swiper-container-horizontal>.swiper-pagination .swiper-pagination-bullet{margin:0 5px}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper{-ms-perspective:1200px}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube{overflow:visible}.swiper-container-cube .swiper-slide{pointer-events:none;visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;width:100%;height:100%;z-index:1}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/user.css b/hyhproject/mobile2/view/default/css/user.css new file mode 100755 index 0000000..9b81adb --- /dev/null +++ b/hyhproject/mobile2/view/default/css/user.css @@ -0,0 +1,110 @@ +@CHARSET "UTF-8"; +body{background:#f5f5f5} +.wst-users_info{background: url(../img/user.png) center top no-repeat;background-size: cover;padding:0.5rem 0;color:#fff;position: relative;} +.wst-users_infol{float:left;margin-left: 0.28rem;} +.wst-users_infol img{width:0.67rem;border-radius:1000px;border: 2px solid #f2f1f1;} +.wst-users_infor{float:left;width:55.666%;padding-left:0.1rem;} +.wst-msg-icon{position: absolute;display: block;right:0.15rem;top:0.1rem;width:26px;height:25px;background: url(../img/message-icon.png) center center no-repeat;background-size: 80%;} +.wst-msg-icon .number{position: absolute;top:-0.03rem;right:-0.1rem;min-width:0.16rem;display: inline-block;text-align: center;background: #f74c31;color: #fff;font-size: 0.1rem;height: 15px;line-height: 15px;-webkit-border-radius: 8px;padding: 0 3px;background-clip: padding-box;} +.wst-info-icon{position: absolute;top:0.1rem;right:0.5rem;width:26px;height:26px;line-height: 26px;color: #fff;font-size: 0.28rem;} +.wst-users_infortop{margin-top:9px;font-size:.16rem;} +.wst-users_infortop img{position: relative;top:2px;left:5px;width: 15px;height: 15px;} +.wst-users_inforbo{font-size:.13rem;} +.wst-users_icon{padding:0.15rem 0;background:#FFF;} +.wst-users_icon span{font-size:.13rem} +.wst-users_icon p{margin:0 auto;width:38px;height:36px} +.wst-users_icon p i{float:left;width:38px;height:36px} +.wst-users_capital{padding:0.15rem 0;background:#FFF;} +.wst-users_capital p{font-size: 0.165rem;color: #ec5151;padding:0 0.1rem ;} +.wst-users_capital span{font-size:.13rem} +.wst-us-sign{float:left;width:100%;height:100%;position: relative;} +.wst-us-sign .sign{position: absolute;right:0;bottom:0;width:62px;height:39px;margin-right:0.1rem;background: url(../img/sign-icon.png) center center no-repeat;background-size: cover;} +.wst-us-sign .sign2{background: url(../img/sign-icon2.png) center center no-repeat;background-size: cover;} +.user-order{margin-top:0.1rem;font-size:0.15rem;background:#ffffff;} +.user-order .order-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-order-icon.png) no-repeat;background-size:cover;} +.user-order .wallet-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-wallet-icon.png) no-repeat;background-size:cover;} +.user-order .tool-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-tool-icon.png) no-repeat;background-size:cover;position: relative;top:1px;} +.user-order .order{margin-left:0.1rem;padding:0.1rem 0.1rem 0.1rem 0;line-height: 0.22rem;border-bottom:1px solid #f2f1f1;} +.view-order{text-align:right;padding-right:5px;font-size:.13rem;color:#a2a0a0} +.wst-users_icon1,.wst-users_icon2,.wst-users_icon3,.wst-users_icon4,.wst-users_icon5{background:url(../img/users_icon.png) no-repeat;background-size:963%} +.wst-users_icon1{background-position:-29px -7px} +.wst-users_icon2{background-position:-94px -7px} +.wst-users_icon3{background-position:-159px -7px} +.wst-users_icon4{background-position:-224px -7px} +.wst-users_icon5{background-position:-289px -7px} +.wait-payment{height:16px;line-height:16px;font-size:.11rem!important;position:absolute;left:24px;top:-3px;min-width:16px;text-align:center;border-radius:5px;color:#fff;background:#de0202;padding:0;border-radius:50%;right:0} +.msg-red-icon{top:-53px;left:57px} +.border-b{border-bottom:1px solid #e7e7e7} +.user-icon-box{padding:5px 0;min-width:24%;min-height:85px;padding-bottom:5px;background:#fff;} +.user-icon-box span{font-size:0.13rem} +.user-icon-box:active{background:#e7e7e7!important} +.user-icon-box p{margin:0 auto;width:39px;height:42px} +.user-icon-box i{float:left;width:38px;height:38px} +.user-icon1,.user-icon2,.user-icon3,.user-icon4,.user-icon5,.user-icon6,.user-icon7,.user-icon8,.user-icon9,.user-icon10,.user-icon11{background:url(../img/img_users_icon.png) no-repeat;background-size:1050%} +.user-icon1{background-position:-31px -18px} +.user-icon2{background-position:-130px -18px} +.user-icon3{background-position:-206px -14px;background-size:945%} +.user-icon4{background-position:-292px -13px;background-size:938%} +.user-icon5{background-position:-28px -110px;background-size:988%} +.user-icon6{background-position:-125px -112px;background-size:1008%} +.user-icon7{background-position:-210px -139px} +.user-icon8{background-position:-300px -139px} +.user-icon9{background-position:-25px -191px;background-size:927%} +.user-icon10{background-position:-119px -199px} +.user-icon11{background-position:-204px -192px;background-size:943%} +.wst-users_list{border-top:2px solid #ededed} +.wst-users_list1{border-top:2px solid #ededed;border-bottom:2px solid #ededed} +.wst-list-thumb-sus{width:50px;height:50px;position:relative} +.wst-list-thumb-sus>span{display:block;width:100%;height:100%;z-index:1;background-repeat:no-repeat;-webkit-background-size:cover} +.ui-list>li{margin-left:0} +.wst-users_chart1{background:url(../img/mine-icon.png) 2px 0 no-repeat} +.wst-users_chart2{background:url(../img/mine-icon.png) -46px 0 no-repeat} +.wst-users_chart3{background:url(../img/mine-icon.png) -100px 0 no-repeat} +.wst-users_chart4{background:url(../img/mine-icon.png) -149px 0 no-repeat} +.wst-users_chart5{background:url(../img/mine-icon.png) -199px 0 no-repeat} +.wst-users_chart6{background:url(../img/mine-icon.png) -246px -1px no-repeat} +.wst-users_chart7{background:url(../img/mine-icon.png) -292px -1px no-repeat} +.ui-badge-corner{border:0} +.wst-message_icon{position:absolute;height:19px;line-height:19px;font-size:12px;min-width:19px;-webkit-border-radius:10px;top:17px;left:110px;display:inline-block;text-align:center;background:#f74c31;color:#fff;font-size:11px;height:16px;line-height:16px;-webkit-border-radius:8px;padding:0 6px;background-clip:padding-box} +.wst-lo-choice{margin:50px 20px 0 20px;border-radius:10px;padding-bottom:20px;font-size:.158rem} +.wst-lo-choice .img{text-align:center} +.wst-lo-choice .img img{width:65px;border:2px solid #d4d3d3;border-radius:1000px;padding:2px} +.wst-lo-choice .name{height:50px;line-height:50px;text-align:center;font-weight:bolder} +.wst-lo-choice .prompt{height:20px;line-height:20px;text-align:center;padding-bottom:42px} +.wst-lo-choice .choice{text-align:center} +.wst-lo-choice .choice .button0{width:100%;height:38px;border-radius:1000px;font-size:.159rem;color:#fff;background:#04be02} +.wst-lo-choice .choice .button0:not(.disabled):not(:disabled):active{color:#f7fdf7;background:#06c804;background-clip:padding-box} +.wst-lo-choice .choice .button1{width:100%;height:38px;border-radius:1000px;font-size:.159rem;color:#59595c;background:#fff;border:1px solid #d4d3d3;margin-top:10px} +.wst-lo-choice .choice .button1:not(.disabled):not(:disabled):active{color:#56565d;background:#f8f7f7;background-clip:padding-box} +.wst-lo-frame{font-size:.16rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-lo-frame .frame{padding:0.05rem 0px;position: relative;} +.wst-lo-frame .frame p{display: inline-block;float: right;margin-right: 20px;} +.wst-lo-frame .frame:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.01rem;background: #d9d9d9;-webkit-transform: scale(0.5);} +.wst-lo-frame .frame input{width:100%;padding-left:5px;height:0.38rem;border:0;font-size:.15rem;} +.wst-lo-frame .verify{padding:0.05rem 0px;border:0;position: relative;} +.wst-lo-frame .verify:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.01rem;background: #d9d9d9;-webkit-transform: scale(0.5);} +.wst-lo-frame .verify input{width:60%;padding-left:5px;height:0.38rem;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.15rem;} +.wst-lo-frame .verify button{float:right;height:0.36rem;line-height: 0.36rem;width:40%;font-size:.14rem;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;background-color: #ffffff;background-image:none;color:#ff3c3c;border:1px solid #ff3c3c;} +.wst-lo-frame .verify button:not(.disabled):not(:disabled):active{background-color: #ffffff;color:#df0202;border:1px solid #df0202;} +.wst-lo-frame .verify img{float:right;height:0.36rem;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-lo-button{padding:30px 10px 0 10px} +.wst-lo-button .button{width:100%;bottom:10px;margin-bottom:6px;height:0.45rem;line-height:0.45rem;color:#fff;background:#ff3c3c;font-size:.15rem;border-radius:3px;border:1px solid #ff3c3c;} +.wst-lo-button .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background:#fff;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:16px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .codebutton{float:right;width:70%;padding:0 10px;font-size:.12rem;height:36px;line-height:36px;margin-right:10px} +.wst-lo-term{margin-top:20px;padding:0 10px;} +.wst-lo-term .term{color: #7f7f7f;font-size:.13rem} +.wst-lo-agreement{position: relative;height:20px;line-height:20px;padding: 12px 10px 10px 35px;font-size:.14rem;} +.wst-lo-agreement i{position: absolute;top:-1px;left:5px;} +.wst-lo-agreement span{color: #ff3c3c;} +.wst-fr-protocol{position: fixed; z-index: 9999; right: -999px; top:0px; width: 100%; height: 100%; background: #ffffff; font-size: 0.15rem; color:#000;} +.wst-fr-protocol .title{height: auto;color: #222;position: relative;background: #ffffff;border-bottom: 1px solid #e8e8e8;} +.wst-fr-protocol .title span{float: left;width: 100%;height: 41px;line-height: 41px;text-align: center;font-size: 16px;} +.wst-fr-protocol .title i{position: absolute;right:5px;top:-1px;color: #222;font-size: 27px;} +.wst-fr-protocol .content{padding:10px;} +.wst-fr-protocol .content img{width: 100%;} +.wst-mar{margin-left: 5px;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/userinfo.css b/hyhproject/mobile2/view/default/css/userinfo.css new file mode 100755 index 0000000..4028511 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/userinfo.css @@ -0,0 +1,26 @@ +@CHARSET "UTF-8"; +.wst-useri_portrait{margin-top:-10px;width:65px;border-radius:1000px} +.wst-useri_line{border-bottom:1px solid #ededed} +.uploadfile-input{width:35%;height:90px;position:absolute;right:0;top:0;opacity:0;z-index:100} +.wst-useri_determine{position:relative;font-size:16px;height:44px;line-height:44px;padding-right:26px;padding-left:15px;font-size:.18rem;padding-top:7px;padding-bottom:7px;margin-top:6px} +.wst-useri_determine input{float:left;width:100%;height:40px;border:1px solid #ccc;border-radius:6px;padding-left:8px;font-size:.15rem} +.wst-listse li{border-bottom:1px solid #ededed} +.wst-list-infose1{width:90%;padding-top:12px;padding-bottom:12px;} +.wst-list-infose1 span{float:left;width:100%;font-size:.15rem} +.wst-list-infose2{float:right;width:32px;margin-top:-45px} +.wst-icon-checked-s_se{color:#de0301} +.wst-fav_search{height:30px;width:62%;float:left;background:#FFF;border:1px solid #ccc;border-radius:15px;-webkit-box-sizing:border-box;-webkit-box-pack:center;margin-left:50px;margin-top:8px} +.wst-fav_search span{width:25px;float:left;margin-top:-7px} +.wst-fav_search input{float:left;width:80%;margin-top:6px;border:0} +.wst-fav_searchs{font-size:.17rem;margin-right:8px;line-height:45px;float:right;color:#FFF} +.wst-fav_list{margin-top:5px;border-bottom:1px solid #ddd} +.wst-fav_listl{width:85px;margin:0 auto} +.wst-fav_listl img{width:85px;height:85px} +.wst-fav_listr button{float:right;color:#504f4f;width:74px;background:#e6e6e6} +.wst-fav_listr1{margin-top:8px;font-size:.16rem} +.wst-fav_listr2{height:30px;color:#ef641f;font-size:.2rem;margin-bottom:3px} +.wst-fav_listr2 span{float:right;width:30px;height:30px} +.wst-fav_listr2 img{width:30px;height:30px} +.wst-fav_listr button:not(.disabled):not(:disabled):active,.wst-fav_listr button.active{background:#b7ada9;border-color:#e6e6e6;color:#504f4f;background-clip:padding-box} +.wst-ed-info li,.wst-ed-info li h4{font-size:.15rem;} +.wst-ed-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/userscores.css b/hyhproject/mobile2/view/default/css/userscores.css new file mode 100755 index 0000000..ef25450 --- /dev/null +++ b/hyhproject/mobile2/view/default/css/userscores.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +.head{min-height:77px;color:#fff;background:url(../img/icon_userscores.png) no-repeat;background-size:cover;} +.head-btn{padding:0 75px;font-size:15px} +.user_scores{font-size:0.16rem;margin-top: 20px;} +.user_scores p{text-align: right;} +.ui-btn-lg{font-size:14px;height:24px;line-height:23px;display:block;width:100%;border-radius:3px;background:transparent;border:1px solid #fff;color:#fff} +.ui-btn-lg:active{background:#fff!important;border:1px solid #ff5e45!important;color:#ff5e45!important} +.score-detail{padding:10px} +.score-detail-title{padding:10px;font-size:.15rem;border-bottom:1px solid #eaeaea;font-weight: bold;} +.score-reduce{font-weight:bold;padding:15px 0;text-align:right;color:#18c328;font-size:.14rem;} +.score-plus{font-weight:bold;padding:15px 0;text-align:right;color:#f81d1d;font-size:.14rem;} +.score-line{border-bottom:1px solid #eaeaea;margin-bottom:5px;margin-top:8px} +.wst-re-info{font-size:.14rem;position: relative;padding-bottom:0.2rem;} +.score-time{position: absolute;bottom:0;left:0;color:#8c8c8c;font-size:0.12rem;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background-color:#f6f6f8;font-size:.15rem} +.wst-fr-box .title{height: auto;background: #fff;position: relative;padding: 6px 0;border-bottom: 1px solid #f1f1f1;} +.wst-fr-box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 14px;} +.wst-fr-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:5px 5px 5px 5px;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/css/userset.css b/hyhproject/mobile2/view/default/css/userset.css new file mode 100755 index 0000000..2dd356b --- /dev/null +++ b/hyhproject/mobile2/view/default/css/userset.css @@ -0,0 +1,37 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.wst-se-l .line{border-bottom:1px solid #edebeb} +.wst-se-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-se-l .pay{background:url(../img/icon_user_info.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .safety{background:url(../img/icon_user_safety.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .about{background:url(../img/icon_user_about.png) 0 0 no-repeat;background-size:97%} +.wst-se-pay{font-size:.18rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-se-pay .pay{padding-bottom:10px} +.wst-se-pay .pay input{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;font-size:.14rem;} +.wst-se-footer{position:fixed;width:100%;z-index:100;left:0;bottom:0} +.wst-se-footer .button{position:absolute;left:3%;bottom:10px;width:93%;margin-bottom:6px;font-size:.15rem;height:38px;line-height:38px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-se-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-se-pay .verify{border-radius:2px;margin-bottom:10px;border:1px solid #a0a0a0} +.wst-se-pay .verify input{width:60%;padding:2px 2px 2px 5px;height:36px;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.14rem;} +.wst-se-pay .verify button{float:right;height:36px;width:40%;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;font-size:.14rem;} +.wst-se-pay .verify img{float:right;height:36px;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-se-pay .phone{padding:10px;font-size:.15rem;} +.wst-se-back{padding:10px;font-size:.14rem;} +.wst-se-back a{color: #999;} +.logout{padding: 0.1rem 1.1rem; margin-top: 20px;} +.logout-btn {font-size: .15rem;height: 30px;line-height: 30px;background: #e00102;border-bottom: 1px solid #e00102;} +.wst-about{width: 99.2%;height: auto;} +.wst-about p{text-align: center;font-size: .15rem;color: #777;font-weight: bold;} +.wst-about .wst-brand{width: 120px;height: 60px;margin: 60px auto;margin-bottom: 10px;} +.wst-about .wst-brand img{width: 100%;height: 100%;} +.wst-about .wst-version{width: 100%;height: 20px;} +.wst-border{width:70%; height:1px;margin:0 auto;background: #eee;margin-top: 20px;} +.wst-about .wst-left{width: 23%;height:100%;display: inline-block; } +.wst-about .wst-center{text-align: center; width: 46%;overflow: hidden; white-space: nowrap; display: inline-block;line-height: 40px;font-size: 14px;color: #777; } +.wst-about .wst-right{width: 23%;height:100%;display: inline-block; } +.wst-about span{width:20px;height:20px;display:block;margin-left: 14px; margin-right:6px;} +.phone{background:url(../img/custom.png) 0 0 no-repeat;background-size:97%;} +.qq{background:url(../img/qq.png) 0 0 no-repeat;background-size:97%;} +.email{background:url(../img/email.png) 0 3px no-repeat;background-size:97%;} +.belong{background:url(../img/copy.png) 0 1px no-repeat;background-size:97%;} +.wst-contact{width: 90%;margin: 0 auto;float: right;} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/day_new.html b/hyhproject/mobile2/view/default/day_new.html new file mode 100755 index 0000000..bc0028c --- /dev/null +++ b/hyhproject/mobile2/view/default/day_new.html @@ -0,0 +1,143 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="UTF-8"> + <title></title> + <script src="__MOBILE__/js/common_xs.js" type="text/javascript" charset="utf-8"></script> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/global-lxy.css" /> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/day_new.css" /> + </head> + + <body> + <div class="banner"> + <img src="__MOBILE__/img/activity2_head.png" /> + </div> + + <div class="new_yhj clearfix"> + <div class="yhj1"> + <img src="__MOBILE__/img/youhuiquan2.png" /> + </div> + <div class="yhj1"> + <img src="__MOBILE__/img/youhuiquan2.png" /> + </div> + </div> + + <div class="everyday"></div> + + <div class="madeInChina"> + <img src="__MOBILE__/img/guochanjingxuan.png" /> + </div> + + <div class="mdc_sp clearfix"> + <div class="gssp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="cash"> + ¥174.40 + </div> + </div> + <div class="gssp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="cash"> + ¥174.40 + </div> + </div> + <div class="gssp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="cash"> + ¥174.40 + </div> + </div> + <div class="gssp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="cash"> + ¥174.40 + </div> + </div> + </div> + + <div class="baby"> + 镇/店/之/宝 + </div> + + <div class="baby_cp"> + <div class="baby_sp"> + <img src="__MOBILE__/img/2.jpg" /> + <div class="wenzi">新款秋款卡通牛奶瓶拼皮透字母卫衣</div> + <p class="sp_p"><span>¥</span>99</p> + <div class="baby_shop">立即购买</div> + </div> + <div class="baby_sp"> + <img src="__MOBILE__/img/2.jpg" /> + <div class="wenzi">新款秋款卡通牛奶瓶拼皮透字母卫衣</div> + <p class="sp_p"><span>¥</span>99</p> + <div class="baby_shop">立即购买</div> + </div> + </div> + + <div class="baby"> + 镇/店/之/宝 + </div> + + <div class="six clearfix"> + <div class="six_nr"> + <p>外套</p> + </div> + <div class="six_nr"> + <p>外套</p> + </div> + <div class="six_nr"> + <p>外套</p> + </div> + <div class="six_nr"> + <p>外套</p> + </div> + <div class="six_nr"> + <p>外套</p> + </div> + <div class="six_nr"> + <p>外套</p> + </div> + </div> + + <div class="six_cp clearfix"> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + <div class="six_cp_sp"> + <img src="__MOBILE__/img/QQ20170914154124.png" /> + <div class="sanjiao"></div> + <p>RMB&nbsp;299.00</p> + </div> + </div> + + <div class="footer"> + <img src="__MOBILE__/img/ac2_footer.png"/> + </div> + + </body> + <script src="__MOBILE__/js/jquery.min.js" type="text/javascript" charset="utf-8"></script> + +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/demo.html b/hyhproject/mobile2/view/default/demo.html new file mode 100755 index 0000000..7fde174 --- /dev/null +++ b/hyhproject/mobile2/view/default/demo.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + + +<style type="text/css"> +.text-gradient { + display: inline-block; + color: green; + font-size: 8em; + font-family: 微软雅黑; + background-image: -webkit-gradient(linear, 0 0, 0 bottom, from(rgba(0, 128, 0, 1)), to(rgba(511, 511, 51, 1))); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +}; +</style> + +<h2 class="text-gradient">简明现代魔法</h2> + </body> +</html> diff --git a/hyhproject/mobile2/view/default/dialog.html b/hyhproject/mobile2/view/default/dialog.html new file mode 100755 index 0000000..a2a64f6 --- /dev/null +++ b/hyhproject/mobile2/view/default/dialog.html @@ -0,0 +1,15 @@ +{/* 对话框 prompt */} +<div class="ui-dialog" id="wst-di-prompt"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <p id="wst-dialog" class="wst-dialog-t">提示</p> + <p class="wst-dialog-l"></p> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event2" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </div> + </div> +</div> +{/* 提示分享对话框 share */} +<div class="ui-dialog" id="wst-di-share" onclick="WST.dialogHide('share');"> + <div class="wst-prompt"></div> +</div> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/error_lost.html b/hyhproject/mobile2/view/default/error_lost.html new file mode 100755 index 0000000..f26913e --- /dev/null +++ b/hyhproject/mobile2/view/default/error_lost.html @@ -0,0 +1,22 @@ +{extend name="default/base" /} +{block name="title"}提示信息 - {__block__}{/block} +{block name="header"} + {php}$Title = "提示信息"{/php} + {include file="default/header" /} +{/block} +{block name="main"} +<section class="ui-container" id="errorLostBg" style="height:69%;position:relative;"> + <p>{if(isset($message))}{$message}{else}对不起你要找的商品不见了~~o(>_<)o~~{/if}</p> + <div class="ui-btn-wrap"> + <button class="ui-btn-s" id="errorBtn" onclick="history.back()"> + 返回上一页 + </button> + </div> +</section> + +{/block} +{block name="js"} +<script> +$(function(){WST.initFooter();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/error_switch.html b/hyhproject/mobile2/view/default/error_switch.html new file mode 100755 index 0000000..9946566 --- /dev/null +++ b/hyhproject/mobile2/view/default/error_switch.html @@ -0,0 +1,15 @@ +<html> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> +<meta name="format-detection" content="telephone=no"> +<title>提示信息 - {:WSTConf('CONF.mallName')}</title> +<link rel="stylesheet" href="__MOBILE__/frozenui/css/frozen.css"> +<link rel="stylesheet" href="__MOBILE__/css/common.css?v={$v}"> +</head> +<body ontouchstart=""> +<section class="ui-container" id="errorLostBg" style="height:69%;position:relative;"> + <p>{if(WSTConf('CONF.seoMallSwitchDesc'))}{:WSTConf('CONF.seoMallSwitchDesc')}{else}商城暂时关闭{/if}</p> +</section> +</body> +</htm \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/error_sys.html b/hyhproject/mobile2/view/default/error_sys.html new file mode 100755 index 0000000..a87645c --- /dev/null +++ b/hyhproject/mobile2/view/default/error_sys.html @@ -0,0 +1,21 @@ +{extend name="default/base" /} +{block name="title"}系统出错了 - {__block__}{/block} +{block name="header"} + {php}$Title = "系统出错了"{/php} + {include file="default/header" /} +{/block} +{block name="main"} +<section class="ui-container" id="errorBg" style="height:69%;position:relative;"> + <div class="ui-btn-wrap"> + <button class="ui-btn-s" id="errorBtn" onclick="history.back()"> + 返回上一页 + </button> + </div> +</section> + +{/block} +{block name="js"} +<script> +$(function(){WST.initFooter();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/footer.html b/hyhproject/mobile2/view/default/footer.html new file mode 100755 index 0000000..44f6aaf --- /dev/null +++ b/hyhproject/mobile2/view/default/footer.html @@ -0,0 +1,26 @@ + {/* 小加载 */} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:43px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> + </div> + {php}$cartNum = WSTCartNum();{/php} + <div class="ui-row-flex wst-menus"> + <div class="ui-col ui-col"><a href="{:url('mobile/index/index')}"><p id="home"></p></a></div><!--首页--> + <div class="ui-col ui-col"><a href="{:url('mobile/goodscats/index')}"><p id="category"></p></a></div> <!--钜惠--> + <div class="ui-col ui-col carsNum"><a href="{:url('mobile/messages/index')}"><p id="follow"> + </p></a>{if($cartNum>0)}<i>{php} echo $cartNum;{/php}</i>{/if}</div> + <div class="ui-col ui-col"><a href="{:url('mobile/carts/index')}"><p id="cart"></p></a></div> <!--购物车--> + <div class="ui-col ui-col"><a href="{:url('mobile/users/index')}"><p id="user"></p></a></div> <!--我的--> + </div> + </footer> + {:hook('initCronHook')} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/forget_pass.html b/hyhproject/mobile2/view/default/forget_pass.html new file mode 100755 index 0000000..0c5fd16 --- /dev/null +++ b/hyhproject/mobile2/view/default/forget_pass.html @@ -0,0 +1,36 @@ +{extend name="default/base" /} +{block name="title"}忘记密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="history.go(-1)"></i><h1 id="login-w">忘记密码</h1> + </header> +{/block} +{block name="footer"}{/block} +{block name="main"} + + {/* 登录页面 */} + <section class="ui-container" id="login1"> + <input type="hidden" id="step" name="step" value="1" autocomplete="off"> + <div class="wst-lo-frame"> + <div class="frame"><input id="loginName" type="text" placeholder="用户名"></div> + <div class="verify"> + <input id="loginVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg1' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg1")'> + </div> + </div> + <div class="wst-lo-button"> + <button id="loginButton" class="button" onclick="javascript:forgetPwd();">下一步</button> + </div> + </section> + {/* 登录页面end */} + + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/forget_pass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/forget_pass2.html b/hyhproject/mobile2/view/default/forget_pass2.html new file mode 100755 index 0000000..bfd65ac --- /dev/null +++ b/hyhproject/mobile2/view/default/forget_pass2.html @@ -0,0 +1,137 @@ +{extend name="default/base" /} +{block name="title"}找回密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="history.go(-1)"></i><h1 id="login-w">找回方式</h1> + </header> +{/block} +{block name="footer"}{/block} +{block name="main"} + {/* 登录页面 */} + <section class="ui-container" id="login1"> + <input type="hidden" id="step" name="step" value="2" autocomplete="off"> + <input type="hidden" id="modes" name="modes" class="ipt" value="1" autocomplete="off"> + <div class="wst-lo-frame"> + <div class="frame" > + {if ($forgetInfo['userPhone'] == '1')} + 您未绑定手机号码 + {else /} + <ul class="ui-row" onclick="dataShow('phone')"> + <li class="ui-col ui-col-90">通过手机找回</li> + <li class="ui-col ui-col-10"> > </li> + </ul> + {/if} + </div> + <!--<div class="frame" style="margin-top:5px;"> + {if ($forgetInfo['userEmail'] == '' )} + 没有预留邮箱,请尝试用手机号码找回 + {else /} + <ul class="ui-row" onclick="dataShow('email')"> + <li class="ui-col ui-col-90">通过邮箱找回</li> + <li class="ui-col ui-col-10"> > </li> + </ul> + {/if} + </div>--> + </div> + + </section> + {/* 登录页面end */} +<style> + +.content .ui-row li{ + font-size: 0.15rem; + padding:5px 0; + padding-left:10px; +} +</style> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span id="contentTitle">通过邮箱找回密码</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-row"> + <div class="wst-lo-frame wst-mar"> + <div class="verify"> + 用户名&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;{$forgetInfo.loginName} + </div> + </div> + <div class='phoneBox'> + <div class="wst-lo-frame wst-mar"> + <div class="verify"> + 手机号码:&nbsp;{$forgetInfo.userPhone} + </div> + </div> + <li class="ui-col ui-col-100" style="padding:0;"> + <div class="wst-lo-frame"> + <div class="verify"> + <input id="smsVerify" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg2' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg2")'> + </div> + </div> + </li> + <li class="ui-col ui-col-100" style="padding:0;"> + {/* 获取验证码 prompt */} + <div class="wst-lo-frame"> + <div class="verify"> + <input id="checkCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="timeObtain" class="ui-btn ui-btn-primary" onclick="javascript:phoneVerify2()">获取验证码</button> + </div> + </div> + </li> + <div class="wst-lo-button"> + <button class="button" onclick="javascript:forgetPhone();" style="margin-top:20px;">下一步</button> + </div> + + + </div> + + + + <!-- {/* 邮箱验证 */} + <div class='emailBox'> + <li class="ui-col ui-col-25">邮箱:</li> + <li class="ui-col ui-col-75" id="email">{$forgetInfo.userEmail}</li> + + + <li class="ui-col ui-col-100" style="padding:0;"> + <div class="wst-lo-frame"> + <div class="verify"> + <input id="loginVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg1' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg1")'> + </div> + </div> + </li> + + <li class="ui-col ui-col-50"><input type="text" id="emailCode" placeholder="邮箱校验码" style="height:36px;"></li> + <li class="ui-col ui-col-50"> + <div class="ui-btn-wrap" style="padding:0px;"> + <button class="ui-btn ui-btn-danger codebutton" id="emailBtn" onclick="forgetEmail()"> + 获取校验码 + </button> + </div> + </li> + + <div class="wst-lo-button"> + <button class="button" onclick="javascript:resetByEmail();" style="margin-top:20px;">下一步</button> + </div> + + </div> + {/* 邮箱验证end */}--> + + </ul> + + + </div> +</div> + + + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/forget_pass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/forget_pass3.html b/hyhproject/mobile2/view/default/forget_pass3.html new file mode 100755 index 0000000..41426e6 --- /dev/null +++ b/hyhproject/mobile2/view/default/forget_pass3.html @@ -0,0 +1,30 @@ +{extend name="default/base" /} +{block name="title"}重置密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="history.go(-1)"></i><h1 id="login-w">重置密码</h1> + </header> +{/block} +{block name="footer"}{/block} +{block name="main"} + {/* 重置页面 */} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container" id="login1"> + <input type="hidden" id="step" name="step" value="3" autocomplete="off"> + <div class="wst-lo-frame"> + <div class="frame"><input id="loginPwd" type="password" placeholder="新密码6-20位"></div> + <div class="frame"><input id="repassword" type="password" placeholder="确认新密码"></div> + <div class="wst-lo-button"> + <button class="button" onclick="javascript:resetPwd();">重置</button> + </div> + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/forget_pass.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/frozenui/css/frozen.css b/hyhproject/mobile2/view/default/frozenui/css/frozen.css new file mode 100755 index 0000000..25180e0 --- /dev/null +++ b/hyhproject/mobile2/view/default/frozenui/css/frozen.css @@ -0,0 +1,2972 @@ +@charset "UTF-8"; +@media screen and (max-width: 319px) { + html { + font-size: 85.33333px; } } +@media screen and (min-width: 320px) and (max-width: 359px) { + html { + font-size: 85.33333px; } } +@media screen and (min-width: 360px) and (max-width: 374px) { + html { + font-size: 96px; } } +@media screen and (min-width: 375px) and (max-width: 383px) { + html { + font-size: 100px; } } +@media screen and (min-width: 384px) and (max-width: 399px) { + html { + font-size: 102.4px; } } +@media screen and (min-width: 400px) and (max-width: 413px) { + html { + font-size: 106.66667px; } } +@media screen and (min-width: 414px) { + html { + font-size: 110.4px; } } +/*CSS Reset*/ +body, +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +code, +form, +fieldset, +legend, +input, +textarea, +p, +blockquote, +th, +td, +header, +hgroup, +nav, +section, +article, +aside, +footer, +figure, +figcaption, +menu, +button { + margin: 0; + padding: 0; } + +body { + font-family: "Helvetica Neue",Helvetica,STHeiTi,sans-serif; + line-height: 1.5; + font-size: 16px; + color: #000; + background-color: #f8f8f8; + -webkit-user-select: none; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; + outline: 0; } + +h1, h2, h3, h4, h5, h6 { + font-size: 100%; + font-weight: normal; } + +table { + border-collapse: collapse; + border-spacing: 0; } + +caption, th { + text-align: left; } + +fieldset, +img { + border: 0; } + +li { + list-style: none; } + +ins { + text-decoration: none; } + +del { + text-decoration: line-through; } + +input, +button, +textarea, +select, +optgroup, +option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; + outline: 0; } + +button { + -webkit-appearance: none; + border: 0; + background: none; } + +a { + -webkit-touch-callout: none; + text-decoration: none; } + +:focus { + outline: 0; + -webkit-tap-highlight-color: transparent; } + +em, i { + font-style: normal; } + +@font-face { + font-family: "iconfont"; + src: url(../font/iconfont.ttf) format("truetype"); } +.ui-icon, [class^="ui-icon-"] { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); } + +.ui-icon-close:before { + content: ""; } + +.ui-icon-search:before { + content: ""; } + +.ui-icon-return:before { + content: ""; } + +.ui-icon-close, +.ui-icon-search { + color: #8e8e93; } + +@font-face { + font-family: "iconfont"; + src: url(../font/iconfont-full.ttf) format("truetype"); } +.ui-icon, [class^="ui-icon-"] { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); } + +.ui-icon-add:before { + content: "\f615"; } + +.ui-icon-more:before { + content: "\f616"; } + +.ui-icon-arrow:before { + content: "\f600"; } + +.ui-icon-return:before { + content: "\f614"; } + +.ui-icon-checked:before { + content: "\f601"; } + +.ui-icon-checked-s:before { + content: "\f602"; } + +.ui-icon-info-block:before { + content: "\f603"; } + +.ui-icon-success-block:before { + content: "\f604"; } + +.ui-icon-warn-block:before { + content: "\f605"; } + +.ui-icon-info:before { + content: "\f606"; } + +.ui-icon-success:before { + content: "\f607"; } + +.ui-icon-warn:before { + content: "\f608"; } + +.ui-icon-next:before { + content: "\f617"; } + +.ui-icon-prev:before { + content: "\f618"; } + +.ui-icon-tag:before { + content: "\f60d"; } + +.ui-icon-tag-pop:before { + content: "\f60f"; } + +.ui-icon-tag-s:before { + content: "\f60e"; } + +.ui-icon-warn-lg:before { + content: "\f609"; } + +.ui-icon-close:before { + content: "\f60a"; } + +.ui-icon-close-progress:before { + content: "\f619"; } + +.ui-icon-close-page:before { + content: "\f60b"; } + +.ui-icon-emo:before { + content: "\f61a"; } + +.ui-icon-delete:before { + content: "\f61b"; } + +.ui-icon-search:before { + content: "\f60c"; } + +.ui-icon-order:before { + content: "\f61c"; } + +.ui-icon-news:before { + content: "\f61d"; } + +.ui-icon-personal:before { + content: "\f61e"; } + +.ui-icon-dressup:before { + content: "\f61f"; } + +.ui-icon-cart:before { + content: "\f620"; } + +.ui-icon-history:before { + content: "\f621"; } + +.ui-icon-wallet:before { + content: "\f622"; } + +.ui-icon-refresh:before { + content: "\f623"; } + +.ui-icon-thumb:before { + content: "\f624"; } + +.ui-icon-file:before { + content: "\f625"; } + +.ui-icon-hall:before { + content: "\f626"; } + +.ui-icon-voice:before { + content: "\f627"; } + +.ui-icon-unfold:before { + content: "\f628"; } + +.ui-icon-gototop:before { + content: "\f629"; } + +.ui-icon-share:before { + content: "\f62a"; } + +.ui-icon-home:before { + content: "\f62b"; } + +.ui-icon-pin:before { + content: "\f62c"; } + +.ui-icon-star:before { + content: "\f62d"; } + +.ui-icon-bugle:before { + content: "\f62e"; } + +.ui-icon-trend:before { + content: "\f62f"; } + +.ui-icon-unchecked:before { + content: "\f610"; } + +.ui-icon-unchecked-s:before { + content: "\f611"; } + +.ui-icon-play-active:before { + content: "\f630"; } + +.ui-icon-stop-active:before { + content: "\f631"; } + +.ui-icon-play:before { + content: "\f632"; } + +.ui-icon-stop:before { + content: "\f633"; } + +.ui-icon-set:before { + content: "\f634"; } + +.ui-icon-add-group:before { + content: "\f635"; } + +.ui-icon-add-people:before { + content: "\f636"; } + +.ui-icon-pc:before { + content: "\f637"; } + +.ui-icon-scan:before { + content: "\f638"; } + +.ui-icon-tag-svip:before { + content: "\f613"; } + +.ui-icon-tag-vip:before { + content: "\f612"; } + +.ui-icon-male:before { + content: "\f639"; } + +.ui-icon-female:before { + content: "\f63a"; } + +.ui-icon-collect:before { + content: "\f63b"; } + +.ui-icon-commented:before { + content: "\f63c"; } + +.ui-icon-like:before { + content: "\f63d"; } + +.ui-icon-liked:before { + content: "\f63e"; } + +.ui-icon-comment:before { + content: "\f63f"; } + +.ui-icon-collected:before { + content: "\f640"; } + +a { + color: #00a5e0; } + +em { + color: #ff8444; } + +::-webkit-input-placeholder { + color: #bbb; } + +/** + * 文字 + */ +h1 { + font-size: 18px; } + +h2 { + font-size: 17px; } + +h3, h4 { + font-size: 16px; } + +h5, .ui-txt-sub { + font-size: 14px; } + +h6, .ui-txt-tips { + font-size: 12px; } + +.ui-txt-default { + color: #000; } + +.ui-txt-white { + color: white; } + +.ui-txt-info { + color: #777; } + +.ui-txt-muted { + color: #bbb; } + +.ui-txt-warning, .ui-txt-red { + color: #ff4222; } + +.ui-txt-feeds { + color: #314c83; } + +/* 同em */ +.ui-txt-highlight { + color: #ff8444; } + +.ui-txt-justify { + text-align: justify; } + +.ui-txt-justify-one { + text-align: justify; + overflow: hidden; + height: 24px; } + +.ui-txt-justify-one:after { + display: inline-block; + content: ''; + overflow: hidden; + width: 100%; + height: 0; } + +/* 1px hack */ +.ui-border-t { + border-top: 1px solid #e0e0e0; } + +.ui-border-b { + border-bottom: 1px solid #e0e0e0; } + +.ui-border-tb { + border-top: #e0e0e0 1px solid; + border-bottom: #e0e0e0 1px solid; + background-image: none; } + +.ui-border-l { + border-left: 1px solid #e0e0e0; } + +.ui-border-r { + border-right: 1px solid #e0e0e0; } + +.ui-border { + border: 1px solid #e0e0e0; } + +.ui-border-radius { + border: 1px solid #e0e0e0; + border-radius: 4px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-border-radius { + position: relative; + border: 0; } + .ui-border-radius:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #e0e0e0; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 8px; + pointer-events: none; } } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-border { + position: relative; + border: 0; } + + .ui-border-t, .ui-border-b, .ui-border-l, .ui-border-r, .ui-border-tb { + border: 0; } + + .ui-border-t { + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-b { + background-position: left bottom; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-t, + .ui-border-b, + .ui-border-tb { + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } + + .ui-border-tb { + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-position: top, bottom; } + + .ui-border-l { + background-position: left top; + background-image: -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-r { + background-position: right top; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-l, + .ui-border-r { + background-repeat: repeat-y; + -webkit-background-size: 1px 100%; } + + .ui-border:after { + content: ""; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + -webkit-background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-repeat: no-repeat; + background-position: top, right, bottom, left; + padding: 1px; + -webkit-box-sizing: border-box; + z-index: 10; + pointer-events: none; } } +/* 箭头链接 */ +.ui-arrowlink { + position: relative; } + .ui-arrowlink:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-arrowlink:before { + right: 10px; } } + +.ui-arrowlink.active { + background: #e5e6e7; } + +/* 文字截断 */ +.ui-nowrap { + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + +.ui-nowrap-flex { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + -webkit-box-flex: 1; + height: inherit; } + +.ui-nowrap-multi { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; } + +.ui-placehold-wrap { + padding-top: 31.25%; + position: relative; } + +.ui-placehold { + color: #bbb; + position: absolute; + top: 0; + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + -webkit-box-sizing: border-box; + text-align: center; + height: 100%; + z-index: -1; } + +.ui-placehold-img { + padding-top: 31.25%; + position: relative; } + .ui-placehold-img > span { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-placehold-img img { + width: 100%; + height: 100%; } + +/* 三等分 */ +.ui-grid, .ui-grid-trisect, .ui-grid-halve { + padding-left: 15px; + padding-right: 10px; + overflow: hidden; + padding-top: 10px; } + @media (max-width: 320px) { + .ui-grid, .ui-grid-trisect, .ui-grid-halve { + padding-left: 10px; + padding-right: 5px; } } + .ui-grid li, .ui-grid-trisect li, .ui-grid-halve li { + padding-right: 5px; + padding-bottom: 10px; + float: left; + position: relative; + -webkit-box-sizing: border-box; } + +.ui-grid-trisect > li { + width: 33.3333%; } + +.ui-grid-trisect-img { + padding-top: 149.47%; } + +.ui-grid-trisect h4 { + position: relative; + margin: 7px 0 3px; } + +.ui-grid-trisect h4 span { + display: inline-block; + margin-left: 12px; + color: #777; } + +/* 二等分 */ +.ui-grid-halve > li { + width: 50%; } + +.ui-grid-halve-img { + padding-top: 55.17%; } + +.ui-grid-trisect-img, .ui-grid-halve-img { + position: relative; + width: 100%; } + .ui-grid-trisect-img > span, .ui-grid-halve-img > span { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-grid-trisect-img img, .ui-grid-halve-img img { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; } + .ui-grid-trisect-img.active, .ui-grid-halve-img.active { + opacity: .5; } + +.ui-row { + display: block; + overflow: hidden; } + +.ui-col { + float: left; + box-sizing: border-box; + width: 100%; } + +.ui-col-10 { + width: 10%; } + +.ui-col-20 { + width: 20%; } + +.ui-col-25 { + width: 25%; } + +.ui-col-33 { + width: 33.3333%; } + +.ui-col-50 { + width: 50%; } + +.ui-col-67 { + width: 66.6666%; } + +.ui-col-75 { + width: 75%; } + +.ui-col-80 { + width: 80%; } + +.ui-col-90 { + width: 90%; } + +.ui-row-flex { + display: -webkit-box; + width: 100%; + -webkit-box-sizing: border-box; } + .ui-row-flex .ui-col { + float: none; + -webkit-box-flex: 1; + width: 0; } + .ui-row-flex .ui-col-2 { + -webkit-box-flex: 2; } + .ui-row-flex .ui-col-3 { + -webkit-box-flex: 3; } + .ui-row-flex .ui-col-4 { + -webkit-box-flex: 4; } + +.ui-row-flex-ver { + -webkit-box-orient: vertical; } + .ui-row-flex-ver .ui-col { + width: 100%; + height: 0; } + +.ui-whitespace { + padding-left: 15px; + padding-right: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace { + padding-left: 10px; + padding-right: 10px; } } + +.ui-whitespace-left { + padding-left: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace-left { + padding-left: 10px; } } + +.ui-whitespace-right { + padding-right: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace-right { + padding-right: 10px; } } + +.ui-justify { + text-align: justify; + font-size: 0; } + .ui-justify:after { + content: ''; + display: inline-block; + width: 100%; + height: 0; + overflow: hidden; } + .ui-justify li { + display: inline-block; + text-align: center; } + .ui-justify p { + font-size: 16px; } + +.ui-justify-flex { + width: 100%; + display: -webkit-box; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; } + +.ui-header, +.ui-footer { + position: fixed; + width: 100%; + z-index: 100; + left: 0; } + +.ui-header { + top: 0; + height: 45px; + line-height: 45px; } + +.ui-header-stable, +.ui-header-positive { + padding: 0 10px; + box-sizing: border-box; } + +.ui-header-stable, +.ui-footer-stable { + background-color: #f8f8f8; } + +.ui-header-positive, +.ui-footer-positive { + background-color: #18b4ed; + color: #fff; } + .ui-header-positive a, .ui-header-positive a:active, .ui-header-positive i, + .ui-footer-positive a, + .ui-footer-positive a:active, + .ui-footer-positive i { + color: #fff; } + +.ui-footer-btn { + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f9f9f9), to(#e0e0e0)); + color: #00a5e0; } + .ui-footer-btn .ui-tiled { + height: 100%; } + +.ui-footer { + bottom: 0; + height: 56px; } + +.ui-header ~ .ui-container { + border-top: 45px solid transparent; } + +.ui-footer ~ .ui-container { + border-bottom: 56px solid transparent; } + +.ui-header h1 { + text-align: center; + font-size: 18px; } + +.ui-header .ui-icon-return { + position: absolute; + left: 0; } + +.ui-header .ui-btn, .ui-header .ui-btn-lg, .ui-header .ui-btn-s { + display: block; + position: absolute; + right: 10px; + top: 50%; + margin-top: -15px; } + +/** + * 垂直上下居中 + */ +.ui-center { + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + text-align: center; + height: 150px; } + +/** + * 排版 + */ +.ui-flex, +.ui-tiled { + display: -webkit-box; + width: 100%; + -webkit-box-sizing: border-box; } + +.ui-flex-ver { + -webkit-box-orient: vertical; } + +.ui-flex-pack-start { + -webkit-box-pack: start; } + +.ui-flex-pack-end { + -webkit-box-pack: end; } + +.ui-flex-pack-center { + -webkit-box-pack: center; } + +.ui-flex-align-start { + -webkit-box-align: start; } + +.ui-flex-align-end { + -webkit-box-align: end; } + +.ui-flex-align-center { + -webkit-box-align: center; } + +/** + * 平铺 + */ +.ui-tiled li { + -webkit-box-flex: 1; + width: 100%; + text-align: center; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; } + +/** + * 未读数通知 + */ +.ui-badge, .ui-badge-muted, .ui-badge-num, .ui-badge-corner, .ui-badge-cornernum { + display: inline-block; + text-align: center; + background: #f74c31; + color: #fff; + font-size: 11px; + height: 16px; + line-height: 16px; + -webkit-border-radius: 8px; + padding: 0 6px; + background-clip: padding-box; } + +/* 浅色的 */ +.ui-badge-muted { + background: #b6cae0; } + +.ui-badge-num { + height: 19px; + line-height: 20px; + font-size: 12px; + min-width: 19px; + -webkit-border-radius: 10px; } + +.ui-badge-wrap { + position: relative; + text-align: center; } + +.ui-badge-corner { + position: absolute; + border: 2px #fff solid; + height: 20px; + line-height: 20px; + top: -4px; + right: -9px; } + +.ui-badge-cornernum { + position: absolute; + top: -4px; + right: -9px; + height: 19px; + line-height: 19px; + font-size: 12px; + min-width: 19px; + -webkit-border-radius: 10px; + top: -5px; + right: -5px; } + +/** +* 红点提醒 +*/ +.ui-reddot, .ui-reddot-border, .ui-reddot-s { + position: relative; + display: inline-block; + line-height: 22px; + padding: 0 6px; } + .ui-reddot:after, .ui-reddot-border:after, .ui-reddot-s:after { + content: ''; + position: absolute; + display: block; + width: 8px; + height: 8px; + background-color: #f74c31; + border-radius: 5px; + right: -3px; + top: -3px; + background-clip: padding-box; } + +.ui-reddot-static { + display: block; + width: 8px; + height: 8px; + padding: 0; } + .ui-reddot-static:after { + top: 0; + right: 0; } + +/* 带白边的 */ +.ui-reddot-border:before { + content: ''; + position: absolute; + display: block; + width: 8px; + height: 8px; + background-color: #fff; + border-radius: 5px; + right: -4px; + top: -4px; + background-clip: padding-box; + padding: 1px; } + +/* 小号的 */ +.ui-reddot-s:after { + width: 6px; + height: 6px; + top: -5px; + right: -5px; } + +/** + * 圆角头像,列表场景 + */ +.ui-avatar, +.ui-avatar-lg, +.ui-avatar-s, +.ui-avatar-one, +.ui-avatar-tiled { + display: block; + -webkit-background-size: cover; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAA8FBMVEXp8Peat8+jwNidutKhvtagvdWcudGfu9Kpwteiv9ecudCsxNifvNTM2+ieu9PE1eSdudDO3OmkvtSyyNu/0eKhvNOivdPm7vWlv9WeutHI2Oa5zd+dudG+0eHn7/bG1+Xi6/SzydzT4Ozc5vDe6PLY5O/a5e/P3eqmv9WmwNW6zt/j7PTX4+6uxtno8Pff6fLh6vPW4u280ODg6fLC1OObuM+buNDD1eTU4eza5fDd5/GhvNKowdarw9jA0+K1y93k7PTk7fXl7fW7zt/F1uXc5/DZ5O/R3+vB0+OnwNXg6vKcuNDM2+mtxNjO3eq3zN1UQ75QAAACR0lEQVR4Xu3W1a7cMBAG4PnHDi4zMx5mxiLD+79Ne7YXq6hKHMU+Ui/8XVpKfo0nMwr9hyzLsizLsqx5ZTfX9DyvmXtXOaNXsd+rYqs9mJFx454HiLwMXsi8CzTO35JZ0x1ABLwlBZAzW0yhAzfgKOmiekLmVEII/peAd22u5ZGMSEpzSWYc30cyoim+oe4/wuU4LgZkwq0HyXEkPCMX9hmC4wmcHpK2VhWS40ncHZG2KcBJBAom2l7kJA6eSFsNDicJsB5qt8SH5EToz0nT1zUCRUi4IE3zqjLkm/aaPGsrQ8oz0nSkDgm1Z750AU4mtL/hYQ1FThZgZ4+0HH9BoAzx9knL8hKsoL9YChCsksdAd3PlWcXBhHSM15CsEqCsNY49uKwm4Lcos5MyAk7BRYmyOpxAcBoOqkca/1sBpyKyl1KH4HQc5J4pmzYkpwQsKJsQnFYRI8qmnD7EwdPrh0gcZA9xio76piBY4iFziACUMw+EcLNXEgKd7o5qVtD52UYeu5RNB3iiifIP0qcRgAplU4N/TNdILsVFgVq/0My6Vxa9lyeTF5jAwzPRsF4gLbfNhBSJ/pRMKPThxGbgkcy4iu19HqdkxN7oR2wlDmqrQ9K39JPm8RLYbZGu8T1cJ3mp1ElXJVqGLAKI7DOJxpA0Le8gJP8VSIGN7RE7Lmr6XfneACCKfwgAjfPFdP8qcpSbk76bgX+BDe+gPqMXs3quj43OQekNGTH+WBmV3nc/fdi+b+9m1S2VuqvZM6lZlmVZlmVZvwEAnS9LHbI74gAAAABJRU5ErkJggg==); } + +.ui-avatar { + width: 50px; + height: 50px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-avatar-lg, +.ui-avatar-one { + width: 70px; + height: 70px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar-lg > span, + .ui-avatar-one > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-avatar-s { + width: 40px; + height: 40px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar-s > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +/* 平铺场景 */ +.ui-avatar-tiled { + width: 30px; + height: 30px; + -webkit-border-radius: 200px; + overflow: hidden; + display: inline-block; } + .ui-avatar-tiled > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-label { + display: inline-block; + position: relative; + line-height: 30px; + height: 30px; + padding: 0 15px; + border: 1px solid #cacccd; + border-radius: 15px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-label { + position: relative; + border: 0; } + .ui-label:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #cacccd; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 30px; + pointer-events: none; } } + .ui-label:active { + background-color: #f3f2f2; } + +.ui-label-list { + margin: 0 10px; } + .ui-label-list .ui-label { + margin: 0 10px 10px 0; } + +.ui-label-s { + font-size: 11px; + line-height: 13px; + display: inline-block; + position: relative; + padding: 0 1px; + color: #ff7f0d; + border: 1px solid #ff7f0d; + border-radius: 2px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-label-s { + position: relative; + border: 0; } + .ui-label-s:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #ff7f0d; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 4px; + pointer-events: none; } } + .ui-label-s:active { + background-color: #f3f2f2; } + .ui-label-s:after { + content: ""; + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; } + +.ui-tag-t, .ui-tag-hot, +.ui-tag-new, +.ui-tag-s-hot, +.ui-tag-s-new, +.ui-tag-pop-hot, +.ui-tag-pop-new { + position: relative; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before, +.ui-tag-t:after, +.ui-tag-hot:after, +.ui-tag-new:after, +.ui-tag-s-hot:after, +.ui-tag-s-new:after, +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + height: 20px; + left: 0; + top: 0; + z-index: 9; + display: block; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before, +.ui-tag-vip:before, +.ui-tag-svip:before, +.ui-tag-selected:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + position: absolute; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before { + content: ""; + line-height: 20px; + color: #ff0000; } + +.ui-tag-t:after, .ui-tag-hot:after, +.ui-tag-new:after, +.ui-tag-s-hot:after, +.ui-tag-s-new:after, +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + position: absolute; + content: ''; + width: 22px; + text-align: right; + line-height: 20px; + font-size: 12px; + color: #fff; + padding-right: 14px; } + +.ui-tag-b, .ui-tag-freelimit, +.ui-tag-free, +.ui-tag-last, +.ui-tag-limit, +.ui-tag-act, +.ui-tag-xy, +.ui-tag-vip, +.ui-tag-svip { + position: relative; } + +.ui-tag-b:before, .ui-tag-freelimit:before, +.ui-tag-free:before, +.ui-tag-last:before, +.ui-tag-limit:before, +.ui-tag-act:before, +.ui-tag-xy:before, +.ui-tag-vip:before, +.ui-tag-svip:before { + position: absolute; + font-size: 10px; + width: 28px; + height: 13px; + line-height: 13px; + bottom: 0; + right: 0; + z-index: 9; + color: #fff; + border-radius: 2px; + text-align: center; } + +.ui-tag-vip:before, +.ui-tag-svip:before { + font-size: 32px; + text-indent: -2px; + border-radius: 2px; } + +.ui-tag-vip:before { + background-color: #ff0000; + color: #fffadf; + content: ""; } + +.ui-tag-svip:before { + background-color: #ffd400; + color: #b7440e; + content: ""; } + +.ui-tag-freelimit:before { + background-color: #18b4ed; + content: '限免'; } + +.ui-tag-free:before { + background-color: #5fb336; + content: '免费'; } + +.ui-tag-last:before { + background-color: #8f6adb; + content: '绝版'; } + +.ui-tag-limit:before { + background-color: #3385e6; + content: '限量'; } + +.ui-tag-act:before { + background-color: #00c795; + content: '活动'; } + +.ui-tag-xy:before { + background-color: #d7ba42; + content: '星影'; } + +.ui-tag-freemonthly:before { + background-color: #ff7f0d; + content: '包月'; } + +.ui-tag-onsale:before { + background-color: #00c795; + content: '特价'; } + +.ui-tag-hot:after, +.ui-tag-s-hot:after, +.ui-tag-pop-hot:after { + content: '热'; } + +.ui-tag-new:after, +.ui-tag-s-new:after, +.ui-tag-pop-new:after { + content: '\u65b0'; } + +.ui-tag-hot:before, +.ui-tag-s-hot:before, +.ui-tag-pop-hot:before { + color: #ff7200; } + +.ui-tag-s-hot:before, +.ui-tag-s-new:before { + content: ""; + left: -2px; } + +.ui-tag-s-hot:after, +.ui-tag-s-new:after { + width: 16px; + padding-right: 12px; } + +.ui-tag-selected:after { + content: ""; + color: #18b4ed; + right: -5px; + top: -5px; + z-index: 9; + width: 26px; + height: 26px; + background: #fff; + border-radius: 13px; + line-height: 26px; + text-indent: -3px; } + +.ui-tag-wrap { + display: inline-block; + position: relative; + padding-right: 32px; } + .ui-tag-wrap .ui-tag-vip, + .ui-tag-wrap .ui-tag-svip { + position: static; } + .ui-tag-wrap .ui-tag-vip:before, + .ui-tag-wrap .ui-tag-svip:before { + top: 50%; + margin-top: -7px; } + +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before { + content: ""; + left: -10px; + top: 1px; } + +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + font-size: 11px; + padding-right: 0; + text-align: center; + left: -5px; } + +/** + * 按钮 + */ +.ui-btn, .ui-btn-lg, .ui-btn-s { + height: 30px; + line-height: 30px; + padding: 0 11px; + min-width: 55px; + display: inline-block; + position: relative; + text-align: center; + font-size: 15px; + background-color: #fdfdfd; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #fff), to(#fafafa)); + vertical-align: top; + color: #00a5e0; + -webkit-box-sizing: border-box; + background-clip: padding-box; + border: 1px solid #cacccd; + border-radius: 3px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn, .ui-btn-lg, .ui-btn-s { + position: relative; + border: 0; } + .ui-btn:before, .ui-btn-lg:before, .ui-btn-s:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #cacccd; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 6px; + pointer-events: none; } } + +.ui-btn:not(.disabled):not(:disabled):active, .ui-btn-lg:not(.disabled):not(:disabled):active, .ui-btn-s:not(.disabled):not(:disabled):active, .ui-btn.active, .active.ui-btn-lg, .active.ui-btn-s { + background: #f2f2f2; + color: rgba(0, 165, 224, 0.5); + background-clip: padding-box; } + +.ui-btn:after, .ui-btn-lg:after, .ui-btn-s:after { + content: ""; + position: absolute; + top: -7px; + bottom: -7px; + left: 0; + right: 0; } + +.ui-btn-primary { + background-color: #18b4ed; + border-color: #0baae4; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #1fbaf3), to(#18b4ed)); + color: white; + background-clip: padding-box; } + +.ui-btn-primary:not(.disabled):not(:disabled):active, .ui-btn-primary.active { + background: #1ca7da; + border-color: #1ca7da; + color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; } + +.ui-btn-danger { + background-color: #f75549; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #fc6156), to(#f75549)); + color: white; + border-color: #f43d30; + background-clip: padding-box; } + +.ui-btn-danger:not(.disabled):not(:disabled):active, .ui-btn-danger.active { + background: #e2574d; + border-color: #e2574d; + color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; } + +.ui-btn.disabled, .disabled.ui-btn-lg, .disabled.ui-btn-s, .ui-btn:disabled, .ui-btn-lg:disabled, .ui-btn-s:disabled { + border: 0; + color: #ccc; + background: #e9ebec; + background-clip: padding-box; } + +.ui-btn-lg { + font-size: 18px; + height: 44px; + line-height: 44px; + display: block; + width: 100%; + border-radius: 5px; } + +.ui-btn-wrap { + padding: 15px 10px; } + @media (max-width: 320px) { + .ui-btn-wrap { + padding: 10px; } } + +.ui-btn-s { + padding: 0; + width: 55px; + height: 25px; + line-height: 25px; + font-size: 13px; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn-primary:before { + border: 1px solid #0baae4; } + + .ui-btn-danger:before { + border: 1px solid #f43d30; } + + .ui-btn, .ui-btn-lg, .ui-btn-s { + border: 0; } + + .ui-btn.disabled, .disabled.ui-btn-lg, .disabled.ui-btn-s, + .ui-btn:disabled, + .ui-btn-lg:disabled, + .ui-btn-s:disabled, + .ui-btn.disabled:before, + .disabled.ui-btn-lg:before, + .disabled.ui-btn-s:before, + .ui-btn:disabled:before, + .ui-btn-lg:disabled:before, + .ui-btn-s:disabled:before { + border: 1px solid #e9ebec; } + + .ui-btn-lg:before { + border-radius: 10px; } } +.ui-btn-progress { + width: 55px; + padding: 0; + overflow: hidden; } + .ui-btn-progress .ui-btn-inner { + position: absolute; + left: 0; + top: 0; + height: 100%; + overflow: hidden; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #1fbaf3), to(#18b4ed)); + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; } + .ui-btn-progress .ui-btn-inner span { + display: inline-block; + color: white; + position: absolute; + width: 55px; + left: 0; } + .ui-btn-progress.disabled, .ui-btn-progress:disabled { + background-color: #fefefe; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, white), to(#fafafa)); + color: #ccc; + border: 1px solid #cacccd; + background-clip: padding-box; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn-progress.disabled, + .ui-btn-progress:disabled { + border: 0; } + + .ui-btn-progress.disabled:before, + .ui-btn-progress:disabled:before { + border: 1px solid #cacccd; } } +.ui-btn-group { + display: -webkit-box; + width: 100%; + box-sizing: border-box; + -webkit-box-align: center; } + +.ui-btn-group button { + display: block; + -webkit-box-flex: 1; + margin-right: 10px; } + .ui-btn-group button:first-child { + margin-left: 10px; } + +.ui-tips { + padding: 20px 15px; + text-align: center; + font-size: 16px; + color: #000; } + .ui-tips i { + display: inline-block; + width: 32px; + height: 1px; + vertical-align: top; } + +.ui-tips i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #0090ff; + line-height: 21px; } + +.ui-tips-success i:before { + content: ""; + color: #65d521; } + +.ui-tips-warn i:before { + content: ""; + color: #f76249; } + +/** + * 页面消息提示 + */ +.ui-newstips-wrap { + margin: 20px 15px; + text-align: center; } + +.ui-newstips { + background: #383939; + position: relative; + height: 40px; + line-height: 40px; + display: -webkit-inline-box; + -webkit-box-align: center; + padding-right: 25px; + border-radius: 5px; + font-size: 14px; + color: #fff; + padding-left: 15px; } + .ui-newstips .ui-avatar-tiled, .ui-newstips .ui-newstips-thumb, .ui-newstips i { + display: block; + margin-left: -5px; + margin-right: 10px; } + .ui-newstips .ui-newstips-thumb { + width: 30px; + height: 30px; + position: relative; } + .ui-newstips .ui-newstips-thumb > span { + display: block; + width: 100%; + height: 100%; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-newstips div { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + -webkit-box-flex: 1; + height: inherit; } + +.ui-newstips:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-newstips:after { + right: 10px; } } + +.ui-newstips .ui-reddot, .ui-newstips .ui-reddot-border, .ui-newstips .ui-reddot-s, .ui-newstips .ui-badge-num { + margin-left: 10px; + margin-right: 5px; } + +.ui-tooltips { + width: 100%; + position: relative; + z-index: 99; + overflow: hidden; + box-sizing: border-box; } + +.ui-tooltips-cnt { + background-color: #fff; + line-height: 44px; + height: 44px; + padding-left: 10px; + padding-right: 30px; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + .ui-tooltips-cnt .ui-icon-close:before { + font-size: 40px; + color: rgba(0, 0, 0, 0.2); + margin-left: -10px; + position: absolute; + right: 0; + top: 0; } + +.ui-tooltips-warn .ui-tooltips-cnt { + background-color: rgba(255, 242, 183, 0.95); + color: #000; } + +.ui-tooltips-warn:active .ui-tooltips-cnt { + background-color: #e1d498; } + +.ui-tooltips-guide .ui-tooltips-cnt { + color: #00a5e0; + background-color: rgba(205, 242, 255, 0.95); } + .ui-tooltips-guide .ui-tooltips-cnt .ui-icon-close:before { + color: rgba(0, 165, 224, 0.2); } + +.ui-tooltips-guide:active .ui-tooltips-cnt { + background-color: #b5dbe8; } + +.ui-tooltips-cnt-link:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; + color: rgba(0, 0, 0, 0.5); } + @media (max-width: 320px) { + .ui-tooltips-cnt-link:after { + right: 10px; } } + +.ui-tooltips-guide .ui-tooltips-cnt-link:after { + color: #00aeef; } + +.ui-tooltips-warn i { + display: inline-block; + margin-right: 4px; + margin-left: -4px; + width: 32px; + height: 1px; + vertical-align: top; } + +.ui-tooltips-warn i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #f76249; } + +/** + * 表格 + */ +.ui-table { + width: 100%; + border-collapse: collapse; } + +.ui-table th { + font-weight: 500; } + +.ui-table td, .ui-table th { + border-bottom: 1px solid #e0e0e0; + border-right: 1px solid #e0e0e0; + text-align: center; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-table td, .ui-table th { + position: relative; + border-right: 0; + border-bottom: 0; } + + .ui-table td:after, .ui-table th:after { + content: ""; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 1px 100% ,100% 1px; + background-repeat: no-repeat; + background-position: right, bottom; + pointer-events: none; } + + .ui-table tr td:last-child:after, .ui-table tr th:last-child:after { + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 100% 1px; + background-repeat: no-repeat; + background-position: bottom; } + + .ui-table tr:last-child td:not(:last-child):after { + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 1px 100%; + background-repeat: no-repeat; + background-position: right; } } +.ui-table tr td:last-child, .ui-table tr th:last-child { + border-right: 0; } + +.ui-table tr:last-child td { + border-bottom: 0; } + +.ui-list { + background-color: #fff; + width: 100%; } + .ui-list > li { + position: relative; + margin-left: 15px; + display: -webkit-box; } + +.ui-list-pure > li { + display: block; } + +/*文字列表*/ +.ui-list-text > li, +.ui-list-pure > li { + position: relative; + padding-top: 10px; + padding-bottom: 10px; + padding-right: 15px; + -webkit-box-align: center; } + +.ui-list-text h4, +.ui-list-text p { + -webkit-box-flex: 1; } + +/*通栏列表*/ +.ui-list-cover > li { + padding-left: 15px; + margin-left: 0px; } + +.ui-list > li.ui-border-t:first-child, +.ui-list > li:first-child > .ui-border-t { + border: none; + background-image: none; } + +/*列表缩略图*/ +.ui-list-thumb, +.ui-list-thumb-s, +.ui-list-img, +.ui-list-icon { + position: relative; + margin: 10px 10px 10px 0px; } + .ui-list-thumb > span, + .ui-list-thumb-s > span, + .ui-list-img > span, + .ui-list-icon > span { + display: block; + width: 100%; + height: 100%; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + +.ui-list-thumb { + width: 50px; + height: 50px; } + +/*列表普通图片*/ +.ui-list-img { + width: 100px; + height: 68px; } + +.ui-list-thumb-s { + width: 28px; + height: 28px; } + +/*列表icon*/ +.ui-list-icon { + width: 40px; + height: 40px; } + +.ui-list .ui-avatar, +.ui-list .ui-avatar-s, +.ui-list .ui-avatar-lg { + margin: 10px 10px 10px 0px; } + +/*列表主要信息*/ +.ui-list-info { + -webkit-box-flex: 1; + padding-top: 10px; + padding-bottom: 10px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + padding-right: 15px; } + .ui-list-info p { + color: #777; + font-size: 14px; } + +.ui-list-text .ui-list-info { + padding-top: 0; + padding-bottom: 0; } + +.ui-list li h4 { + font-size: 16px; } + +.ui-list:not(.ui-list-text) li > p, +.ui-list li > h5 { + font-size: 14px; + color: #777; } + +/*列表按压态*/ +.ui-list-active > li:active, +.ui-list li.active { + background-color: #e5e6e7; + padding-left: 15px; + margin-left: 0px; } + +.ui-list-active > li:active, +.ui-list > li.active, +.ui-list > li.active > .ui-border-t, +.ui-list > li.active + li > .ui-border-t, +.ui-list > li.active + li.ui-border-t { + background-image: none; + border-top-color: #e5e6e7; } + +/*连接列表*/ +.ui-list-link > li:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-list-link > li:after { + right: 10px; } } + +.ui-list-text.ui-list-link > li { + padding-right: 30px; } + +.ui-list-link .ui-list-info { + padding-right: 30px; } + +/* 功能类 */ +.ui-list-function .ui-list-info { + padding-right: 75px; } + +.ui-list-function .ui-btn, .ui-list-function .ui-btn-lg, .ui-list-function .ui-btn-s { + position: absolute; + top: 50%; + right: 15px; + margin-top: -15px; } + +.ui-list-function .ui-btn-s { + margin-top: -12px; } + +.ui-list-function.ui-list-link .ui-list-info { + padding-right: 90px; } + +.ui-list-function.ui-list-link .ui-btn, .ui-list-function.ui-list-link .ui-btn-lg, .ui-list-function.ui-list-link .ui-btn-s { + right: 30px; } + +.ui-list-function li { + -webkit-box-align: inherit; } + +.ui-list-one > li { + padding-top: 0; + padding-bottom: 0; + line-height: 44px; } +.ui-list-one .ui-list-info { + -webkit-box-orient: horizontal; + -webkit-box-align: center; } +.ui-list-one h4 { + -webkit-box-flex: 1; } + +@media (max-width: 320px) { + .ui-list > li { + margin-left: 10px; } + + .ui-list-text > li, + .ui-list-pure > li, + .ui-list-info { + padding-right: 10px; } + + .ui-list-cover > li, + .ui-list-active > li:active, + .ui-list li.active { + padding-left: 10px; } + + .ui-list-text.ui-list-link > li { + padding-right: 25px; } + + .ui-list-function .ui-list-info { + padding-right: 70px; } + + .ui-list-function .ui-btn, .ui-list-function .ui-btn-lg, .ui-list-function .ui-btn-s { + right: 10px; } + + .ui-list-function.ui-list-link .ui-list-info { + padding-right: 85px; } + + .ui-list-function.ui-list-link .ui-btn, .ui-list-function.ui-list-link .ui-btn-lg, .ui-list-function.ui-list-link .ui-btn-s { + right: 25px; } } +/** + * 出错页面 + */ +.ui-notice { + width: 100%; + height: 100%; + z-index: 99; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + position: absolute; + text-align: center; } + +.ui-notice > i { + display: block; + margin-bottom: 20px; } + .ui-notice > i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + font-size: 100px; + line-height: 100px; + color: rgba(0, 0, 0, 0.3); } + +.ui-notice p { + font-size: 16px; + line-height: 20px; + color: #bbb; + text-align: center; + padding: 0 15px; } + +.ui-notice-btn { + width: 100%; + -webkit-box-sizing: border-box; + padding: 50px 15px 15px; } + +.ui-notice-btn button { + margin: 10px 0px; } + +.ui-form { + background-color: #fff; } + +.ui-form-item-order.active { + background-color: #e5e6e7; } + +/* 表单输入项 */ +.ui-form-item { + position: relative; + font-size: 16px; + height: 44px; + line-height: 44px; + padding-right: 15px; + padding-left: 15px; } + .ui-form-item label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio) { + width: 95px; + position: absolute; + text-align: left; + box-sizing: border-box; } + .ui-form-item input, + .ui-form-item textarea { + width: 100%; + box-sizing: border-box; + -webkit-appearance: none; + border: 0; + background: none; + padding-left: 95px; } + .ui-form-item input[type="checkbox"], .ui-form-item input[type="radio"] { + padding-left: 0; } + .ui-form-item .ui-icon-close { + position: absolute; + top: 0; + right: 6px; } + @media (max-width: 320px) { + .ui-form-item .ui-icon-close { + right: 1px; } } + @media (max-width: 320px) { + .ui-form-item { + padding-left: 10px; + padding-right: 10px; } } + +.ui-form-item-textarea { + height: 65px; } + +.ui-form-item-textarea label { + vertical-align: top; } + +.ui-form-item-textarea textarea { + margin-top: 15px; + border: none; } + +.ui-form-item-textarea textarea:focus { + outline: none; } + +.ui-form-item-link > li:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-form-item-link > li:after { + right: 10px; } } + +.ui-form-item-l label, +.ui-form-item-r button { + color: #00a5e0; + text-align: center; } + +.ui-form-item-r .ui-icon-close { + right: 125px; } + +.ui-form-item-l input:not([type="checkbox"]):not([type="radio"]) { + padding-left: 115px; + -webkit-box-sizing: border-box; + box-sizing: border-box; } + +.ui-form-item-r { + padding-right: 0; } + +.ui-form-item-r input:not([type="checkbox"]):not([type="radio"]) { + padding-left: 0; + padding-right: 150px; + -webkit-box-sizing: border-box; + box-sizing: border-box; } + +.ui-form-item-r button { + width: 110px; + height: 44px; + position: absolute; + top: 0; + right: 0; } + +.ui-form-item-r button.disabled { + color: #bbb; } + +.ui-form-item-r button:not(.disabled):active { + background-color: #e5e6e7; } + +.ui-form-item-pure input, +.ui-form-item-pure textarea { + padding-left: 0; } + +/* 表单展示项 */ +.ui-form-item-show label { + color: #777; } + +.ui-form-item-link:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-form-item-link:after { + right: 10px; } } + +.ui-form-item-checkbox, +.ui-form-item-radio, +.ui-form-item-switch { + display: -webkit-box; + -webkit-box-align: center; } + +.ui-checkbox, .ui-checkbox-s { + display: inline-block; } + +.ui-checkbox input, .ui-checkbox-s input { + display: inline-block; + width: 25px; + height: 1px; + position: relative; + overflow: visible; + border: 0; + background: none; + -webkit-appearance: none; + outline: none; + margin-right: 8px; + vertical-align: middle; } + +.ui-checkbox input:before, .ui-checkbox-s input:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #18b4ed; + position: absolute; + top: -22px; + left: -4px; + color: #dedfe0; } + +.ui-checkbox input:checked:before, .ui-checkbox-s input:checked:before { + content: ""; + color: #18b4ed; } + +.ui-checkbox-s input:before { + content: ""; } + +.ui-checkbox-s input:checked:before { + content: ""; } + +.ui-switch { + position: absolute; + font-size: 16px; + right: 15px; + top: 50%; + margin-top: -16px; + width: 52px; + height: 32px; + line-height: 32px; } + @media (max-width: 320px) { + .ui-switch { + right: 10px; } } + .ui-switch input { + width: 52px; + height: 32px; + position: absolute; + z-index: 2; + border: none; + background: none; + -webkit-appearance: none; + outline: none; } + .ui-switch input:before { + content: ''; + width: 50px; + height: 30px; + border: 1px solid #dfdfdf; + background-color: #fdfdfd; + border-radius: 20px; + cursor: pointer; + display: inline-block; + position: relative; + vertical-align: middle; + -webkit-box-sizing: content-box; + box-sizing: content-box; + border-color: #dfdfdf; + box-shadow: #dfdfdf 0px 0px 0px 0px inset; + -webkit-transition: border 0.4s, box-shadow 0.4s; + transition: border 0.4s, box-shadow 0.4s; + -webkit-background-clip: content-box; + background-clip: content-box; } + .ui-switch input:checked:before { + border-color: #64bd63; + box-shadow: #64bd63 0px 0px 0px 16px inset; + background-color: #64bd63; + transition: border 0.4s, box-shadow 0.4s, background-color 1.2s; + -webkit-transition: border 0.4s, box-shadow 0.4s, background-color 1.2s; + background-color: #64bd63; } + .ui-switch input:checked:after { + left: 21px; } + .ui-switch input:after { + content: ''; + width: 30px; + height: 30px; + position: absolute; + top: 1px; + left: 0; + border-radius: 100%; + background-color: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); + -webkit-transition: left 0.2s; + transition: left 0.2s; } + +.ui-radio { + line-height: 25px; + display: inline-block; } + +.ui-radio input { + display: inline-block; + width: 26px; + height: 26px; + position: relative; + overflow: visible; + border: 0; + background: none; + -webkit-appearance: none; + outline: none; + margin-right: 8px; + vertical-align: middle; } + +.ui-radio input:before { + content: ''; + display: block; + width: 24px; + height: 24px; + border: 1px solid #dfe0e1; + border-radius: 13px; + background-clip: padding-box; + position: absolute; + left: 0px; + top: 0; } + +.ui-radio input:checked:after { + content: ''; + display: block; + width: 14px; + height: 14px; + background: #18b4ed; + border-radius: 7px; + position: absolute; + left: 6px; + top: 6px; } + +.ui-select { + position: relative; + margin-right: 6px; } + +.ui-select select { + -webkit-appearance: none; + border: 0; + background: none; + width: 100%; + padding-right: 14px; } + +.ui-select:after { + position: absolute; + top: 50%; + right: 0; + margin-top: -4px; + width: 0; + height: 0; + border-top: 6px solid; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + color: #a6a6a6; + content: ""; + pointer-events: none; } + +.ui-select-group { + margin-left: 95px; + overflow: hidden; } + .ui-select-group .ui-select { + float: left; } + +.ui-form-item > .ui-select { + margin-left: 95px; } + +.ui-input-wrap { + background-color: #ebeced; + height: 44px; + display: -webkit-box; + -webkit-box-align: center; } + .ui-input-wrap .ui-btn, .ui-input-wrap .ui-btn-lg, .ui-input-wrap .ui-btn-s, .ui-input-wrap i { + margin-right: 10px; } + +.ui-input { + height: 30px; + line-height: 30px; + margin: 7px 10px; + background: #fff; + padding-left: 10px; + -webkit-box-flex: 1; } + +.ui-input input { + width: 100%; + height: 100%; + border: 0; + background: 0 0; + -webkit-appearance: none; + outline: 0; } + +.ui-searchbar-wrap { + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + background-color: #ebeced; + height: 44px; } + .ui-searchbar-wrap button { + margin-right: 10px; } + .ui-searchbar-wrap .ui-searchbar-cancel { + color: #00a5e0; + font-size: 16px; + padding: 4px 8px; } + .ui-searchbar-wrap .ui-searchbar-input, .ui-searchbar-wrap button, .ui-searchbar-wrap .ui-icon-close { + display: none; } + .ui-searchbar-wrap.focus { + -webkit-box-pack: start; } + .ui-searchbar-wrap.focus .ui-searchbar-input, .ui-searchbar-wrap.focus button, .ui-searchbar-wrap.focus .ui-icon-close { + display: block; } + .ui-searchbar-wrap.focus .ui-searchbar-text { + display: none; } + +.ui-searchbar { + border-radius: 5px; + margin: 0 10px; + background: #fff; + height: 30px; + line-height: 30px; + position: relative; + padding-left: 4px; + -webkit-box-flex: 1; + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + color: #bbb; + font-size: 14px; + width: 100%; } + .ui-searchbar input { + -webkit-appearance: none; + border: none; + background: none; + color: #000; + width: 100%; + padding: 4px 0; } + .ui-searchbar .ui-icon-search { + line-height: 30px; } + .ui-searchbar .ui-icon-close { + line-height: 30px; } + +.ui-searchbar-input { + -webkit-box-flex: 1; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-searchbar.ui-border-radius:before { + border-radius: 10px; } } +/** + * 轮播组件 + */ +.ui-slider { + width: 100%; + overflow: hidden; + position: relative; + padding-top: 31.25%; } + +.ui-slider-content { + display: -webkit-box; + position: absolute; + left: 0; + top: 0; + height: 100%; } + +.ui-slider-content > li { + -webkit-box-flex: 1; + width: 100%; + height: 100%; } + +.ui-slider-content > li img { + display: block; + width: 100%; } + +.ui-slider-content > li span { + display: block; + width: 100%; + height: 100%; + background-repeat: no-repeat; + -webkit-background-size: 100% 100%; } + +.ui-slider-content > li.active { + opacity: .5; } + +.ui-slider-indicators { + position: absolute; + display: -webkit-box; + -webkit-box-pack: end; + width: 100%; + bottom: 10px; + right: 4px; + font-size: 0; } + +.ui-slider-indicators li { + display: block; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + font-size: 0; + width: 7px; + height: 7px; + background-color: rgba(0, 0, 0, 0.3); + border-radius: 10px; + margin-right: 6px; + -webkit-box-sizing: border-box; + background-clip: padding-box; + position: relative; } + +.ui-slider-indicators li.current:before { + content: ''; + position: absolute; + background-color: #fff; + left: 1px; + top: 1px; + width: 5px; + height: 5px; + border-radius: 10px; + -webkit-box-sizing: border-box; + background-clip: padding-box; } + +.ui-slider-indicators-center { + -webkit-box-pack: center; + right: 0; } + +.ui-panel { + overflow: hidden; + margin-bottom: 10px; } + .ui-panel .ui-grid-halve, .ui-panel .ui-grid-trisect { + padding-top: 0; } + .ui-panel h1, .ui-panel h2, .ui-panel h3 { + padding-left: 15px; + padding-right: 15px; + line-height: 44px; + position: relative; + overflow: hidden; + display: -webkit-box; } + @media (max-width: 320px) { + .ui-panel h1, .ui-panel h2, .ui-panel h3 { + padding-left: 10px; + padding-right: 10px; } } + .ui-panel h1 span, .ui-panel h2 span, .ui-panel h3 span { + display: block; } + +.ui-panel-card, +.ui-panel-simple { + background-color: #fff; } + +.ui-panel-pure h2, +.ui-panel-pure h3 { + color: #777; } + +.ui-panel-simple { + margin-bottom: 0; } + +.ui-panel-subtitle { + font-size: 14px; + color: #777; + margin-left: 10px; } + +.ui-panel-title-tips { + font-size: 12px; + color: #777; + position: absolute; + right: 15px; } + @media (max-width: 320px) { + .ui-panel-title-tips { + right: 10px; } } + +.ui-arrowlink .ui-panel-title-tips { + right: 30px; } + @media (max-width: 320px) { + .ui-arrowlink .ui-panel-title-tips { + right: 25px; } } + +.ui-progress { + overflow: hidden; + width: 100%; + height: 2px; + font-size: 0px; + background-color: #e2e2e2; + box-sizing: border-box; } + +.ui-progress span { + display: block; + width: 0%; + background: #65d521; + height: 100%; + font-size: 0; } + +.ui-grid-trisect li .ui-progress, +.ui-grid-halve li .ui-progress { + position: absolute; + height: 13px; + bottom: 0px; + z-index: 9; + border: 5px solid rgba(248, 248, 248, 0.9); } + .ui-grid-trisect li .ui-progress span, + .ui-grid-halve li .ui-progress span { + border-radius: 3px; } + +/** + * 选项卡 + */ +.ui-tab { + width: 100%; + overflow: hidden; } + +.ui-tab-nav { + width: 100%; + background-color: #fff; + display: box; + display: -webkit-box; + font-size: 16px; + height: 45px; + box-sizing: border-box; } + +.ui-tab-content { + display: -webkit-box; } + +.ui-tab-content > li { + -webkit-box-flex: 1; + width: 100%; } + +.ui-tab-nav li { + height: 45px; + line-height: 45px; + min-width: 70px; + box-flex: 1; + -webkit-box-flex: 1; + text-align: center; + color: #777; + box-sizing: border-box; + border-bottom: 2px solid transparent; + width: 100%; } + +.ui-tab-nav li.current { + color: #00a5e0; + border-bottom: 2px #00a5e0 solid; } + +.ui-tab-nav li:active { + opacity: .8; } + +.ui-loading-wrap { + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + text-align: center; + height: 40px; } + +.ui-loading { + width: 20px; + height: 20px; + display: block; + background: url(../img/loading_sprite.png); + -webkit-background-size: auto 20px; + -webkit-animation: am-rotate 1s steps(12) infinite; } + +.ui-loading-bright { + width: 37px; + height: 37px; + display: block; + background-image: url(../img/loading_sprite_white.png); + -webkit-background-size: auto 37px; + -webkit-animation: am-rotate2 1s steps(12) infinite; } + +.ui-loading-wrap .ui-loading { + margin: 10px; } + +.ui-loading-block { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: center; + background: rgba(0, 0, 0, 0.4); + display: none; + background: transparent; } + .ui-loading-block .ui-loading-cnt { + width: 130px; + height: 110px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-align: center; + text-align: center; + background: rgba(0, 0, 0, 0.65); + border-radius: 6px; + color: #fff; + font-size: 16px; } + .ui-loading-block .ui-loading-bright { + margin: 18px 0 8px; } + +.ui-loading-block.show { + display: -webkit-box; + display: box; } + +@-webkit-keyframes am-rotate { + from { + background-position: 0 0; } + to { + background-position: -240px 0; } } +@-webkit-keyframes am-rotate2 { + from { + background-position: 0 0; } + to { + background-position: -444px 0; } } +.ui-poptips { + width: 100%; + position: fixed; + top: 0px; + left: 0px; + z-index: 999; + padding: 0px 10px; + box-sizing: border-box; } + +.ui-poptips-cnt { + background-color: rgba(0, 0, 0, 0.6); + line-height: 40px; + height: 40px; + color: #fff; + font-size: 16px; + text-align: center; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + .ui-poptips-cnt i { + display: inline-block; + width: 32px; + height: 1px; + vertical-align: top; } + .ui-poptips-cnt i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + margin-right: 2px; + margin-left: 4px; + color: #fff; + line-height: 40px; } + +.ui-poptips-info i:before { + content: ""; } + +.ui-poptips-success i:before { + content: ""; } + +.ui-poptips-warn i:before { + content: ""; } + +/** + * 弹窗类 + */ +.ui-dialog { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: center; + background: rgba(0, 0, 0, 0.4); + display: none; } + +.ui-dialog.show { + display: -webkit-box; + display: box; } + +.ui-dialog-hd { + height: 48px; + line-height: 48px; + text-align: center; + position: relative; } + +.ui-dialog-cnt { + border-radius: 6px; + width: 270px; + -webkit-background-clip: padding-box; + background-clip: padding-box; + pointer-events: auto; + background-color: rgba(253, 253, 253, 0.95); + position: relative; + font-size: 16px; } + +.ui-dialog-bd { + min-height: 71px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + padding: 18px; + display: -webkit-box; + display: box; + -webkit-box-pack: center; + -webkit-box-align: center; + -webkit-box-orient: vertical; } + +.ui-dialog-bd > h4 { + margin-bottom: 4px; + width: 100%; + text-align: center; } + +.ui-dialog-bd > div, .ui-dialog-bd > ul { + width: 100%; } + +.ui-dialog-ft { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + display: -webkit-box; + width: 100%; + box-sizing: border-box; + -webkit-box-align: center; + border-top: 1px solid #e0e0e0; + height: 42px; + line-height: 42px; } + +.ui-dialog-close:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #828282; + display: block; + line-height: 32px; + position: absolute; + top: 3px; + right: 3px; } + +.ui-dialog-close:active { + opacity: 0.5; } + +.ui-dialog-ft button { + color: #00a5e0; + text-align: center; + border-right: 1px #e0e0e0 solid; + width: 100%; + line-height: 42px; + background: transparent; + display: block; + margin: 0 !important; + -webkit-box-flex: 1; } + .ui-dialog-ft button:active { + background-color: rgba(0, 0, 0, 0.1) !important; } + .ui-dialog-ft button:first-child { + border-bottom-left-radius: 6px; } + .ui-dialog-ft button:last-child { + border-right: 0; + border-bottom-right-radius: 6px; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-dialog-ft { + position: relative; + border: 0; + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } + + .ui-dialog-ft button { + border-right: 0; + background-position: right top; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-y; + -webkit-background-size: 1px 100%; } + .ui-dialog-ft button:last-child { + background: none; } } +.ui-selector header { + padding: 6px 10px; + color: #a6a6a6; + overflow: hidden; } + +.ui-selector header h3 { + float: left; } + +.ui-selector-content { + background: #fff; } + +.ui-selector-item p { + margin-left: 10px; + -webkit-box-flex: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + +.ui-selector-item .ui-txt-info { + margin: 0 10px; + font-size: 12px; } + +.ui-selector-item .ui-list-link li:after { + display: none; } + +.ui-selector-item h3:before { + content: ''; + display: block; + width: 0; + height: 0; + border-left: 6px solid; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + color: #a6a6a6; + position: absolute; + left: 25px; + top: 15px; + -webkit-transition: all 0.2s; } + +.ui-selector-item.active h3:before { + -webkit-transform: rotate(90deg); } + +.ui-selector-item.active h3 { + border: none; + background-image: none; } + +.ui-selector-item.active ul { + display: block; } + +.ui-selector-item ul { + display: none; } + +.ui-selector-item h3 { + display: -webkit-box; + font-size: 16px; + padding-left: 54px; + line-height: 44px; + height: 44px; + position: relative; } + +.ui-actionsheet { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + opacity: 0; + pointer-events: none; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: end; + background: rgba(0, 0, 0, 0.4); } + .ui-actionsheet.show { + pointer-events: inherit; + opacity: 1; } + .ui-actionsheet.show .ui-actionsheet-cnt { + -webkit-transform: translateY(0); + -webkit-transition-delay: 0.3s; } + +.ui-actionsheet-cnt { + font-size: 21px; + position: fixed; + bottom: 0; + padding: 0 8px; + width: 100%; + box-sizing: border-box; + text-align: center; + -webkit-transform: translateY(100%); + -webkit-transition-property: all; + -webkit-transition-timing-function: ease-out; + -webkit-transition-duration: 0.3s; } + +.ui-actionsheet button, .ui-actionsheet h4 { + background: rgba(255, 255, 255, 0.84); + display: block; + width: 100%; + color: #0079ff; + box-sizing: border-box; } + +.ui-actionsheet button { + line-height: 44px; + height: 44px; } + +.ui-actionsheet h4 { + line-height: 24px; + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + +.ui-actionsheet button:not(:last-child) { + border-top: 1px #e0e0e0 solid; } + +.ui-actionsheet button:last-child { + margin: 8px 0; + border-radius: 3px; } + +.ui-actionsheet button:nth-last-child(2) { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; } + +.ui-actionsheet button:active { + opacity: 0.84; } + +.ui-actionsheet h4 { + font-size: 13px; + color: #8a8a8a; } + +.ui-actionsheet .ui-actionsheet-del { + color: #fd472b; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-actionsheet button:not(:last-child) { + border: 0; + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } } + +/*# sourceMappingURL=frozen.css.map */ diff --git a/hyhproject/mobile2/view/default/frozenui/font/iconfont-full.ttf b/hyhproject/mobile2/view/default/frozenui/font/iconfont-full.ttf new file mode 100755 index 0000000..859ec87 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/font/iconfont-full.ttf differ diff --git a/hyhproject/mobile2/view/default/frozenui/font/iconfont.ttf b/hyhproject/mobile2/view/default/frozenui/font/iconfont.ttf new file mode 100755 index 0000000..fb9b421 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/font/iconfont.ttf differ diff --git a/hyhproject/mobile2/view/default/frozenui/img/loading_sprite.png b/hyhproject/mobile2/view/default/frozenui/img/loading_sprite.png new file mode 100755 index 0000000..696f424 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/img/loading_sprite.png differ diff --git a/hyhproject/mobile2/view/default/frozenui/img/loading_sprite_white.png b/hyhproject/mobile2/view/default/frozenui/img/loading_sprite_white.png new file mode 100755 index 0000000..8156eb3 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/img/loading_sprite_white.png differ diff --git a/hyhproject/mobile2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png b/hyhproject/mobile2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png new file mode 100755 index 0000000..c6cd378 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png differ diff --git a/hyhproject/mobile2/view/default/frozenui/img/vip/icon_vip.png b/hyhproject/mobile2/view/default/frozenui/img/vip/icon_vip.png new file mode 100755 index 0000000..c5792b8 Binary files /dev/null and b/hyhproject/mobile2/view/default/frozenui/img/vip/icon_vip.png differ diff --git a/hyhproject/mobile2/view/default/frozenui/js/frozen.js b/hyhproject/mobile2/view/default/frozenui/js/frozen.js new file mode 100755 index 0000000..5f4f586 --- /dev/null +++ b/hyhproject/mobile2/view/default/frozenui/js/frozen.js @@ -0,0 +1,1533 @@ +/** + * User: jeakeyliang + * Date: 14-08-22 + * Time: 下午9:20 + * vn: 00119f3fc12403a05a1ef5609ff96e66 + */ +//js修改过 + +;(function($){ + var data = {}, dataAttr = $.fn.data, camelize = $.camelCase, + exp = $.expando = 'Zepto' + (+new Date()), emptyArray = [] + + // Get value from node: + // 1. first try key as given, + // 2. then try camelized key, + // 3. fall back to reading "data-*" attribute. + function getData(node, name) { + var id = node[exp], store = id && data[id] + if (name === undefined) return store || setData(node) + else { + if (store) { + if (name in store) return store[name] + var camelName = camelize(name) + if (camelName in store) return store[camelName] + } + return dataAttr.call($(node), name) + } + } + + // Store value under camelized key on node + function setData(node, name, value) { + var id = node[exp] || (node[exp] = ++$.uuid), + store = data[id] || (data[id] = attributeData(node)) + if (name !== undefined) store[camelize(name)] = value + return store + } + + // Read all "data-*" attributes from a node + function attributeData(node) { + var store = {} + $.each(node.attributes || emptyArray, function(i, attr){ + if (attr.name.indexOf('data-') == 0) + store[camelize(attr.name.replace('data-', ''))] = + $.zepto.deserializeValue(attr.value) + }) + return store + } + + $.fn.data = function(name, value) { + return value === undefined ? + // set multiple values via object + $.isPlainObject(name) ? + this.each(function(i, node){ + $.each(name, function(key, value){ setData(node, key, value) }) + }) : + // get value from first element + (0 in this ? getData(this[0], name) : undefined) : + // set value on all elements + this.each(function(){ setData(this, name, value) }) + } + + $.fn.removeData = function(names) { + if (typeof names == 'string') names = names.split(/\s+/) + return this.each(function(){ + var id = this[exp], store = id && data[id] + if (store) $.each(names || store, function(key){ + delete store[names ? camelize(this) : key] + }) + }) + } + + // Generate extended `remove` and `empty` functions + ;['remove', 'empty'].forEach(function(methodName){ + var origFn = $.fn[methodName] + $.fn[methodName] = function() { + var elements = this.find('*') + if (methodName === 'remove') elements = elements.add(this) + elements.removeData() + return origFn.call(this) + } + }) +})(window.Zepto); + +!function ($) { + var _private = {}; + _private.cache = {}; + $.tpl = function (str, data, env) { + // 判断str参数,如str为script标签的id,则取该标签的innerHTML,再递归调用自身 + // 如str为HTML文本,则分析文本并构造渲染函数 + var fn = !/[^\w\-\.:]/.test(str) + ? _private.cache[str] = _private.cache[str] || this.get(document.getElementById(str).innerHTML) + : function (data, env) { + var i, variable = [], value = []; // variable数组存放变量名,对应data结构的成员变量;value数组存放各变量的值 + for (i in data) { + variable.push(i); + value.push(data[i]); + } + return (new Function(variable, fn.code)) + .apply(env || data, value); // 此处的new Function是由下面fn.code产生的渲染函数;执行后即返回渲染结果HTML + }; + + fn.code = fn.code || "var $parts=[]; $parts.push('" + + str + .replace(/\\/g, '\\\\') // 处理模板中的\转义 + .replace(/[\r\t\n]/g, " ") // 去掉换行符和tab符,将模板合并为一行 + .split("<%").join("\t") // 将模板左标签<%替换为tab,起到分割作用 + .replace(/(^|%>)[^\t]*/g, function(str) { return str.replace(/'/g, "\\'"); }) // 将模板中文本部分的单引号替换为\' + .replace(/\t=(.*?)%>/g, "',$1,'") // 将模板中<%= %>的直接数据引用(无逻辑代码)与两侧的文本用'和,隔开,同时去掉了左标签产生的tab符 + .split("\t").join("');") // 将tab符(上面替换左标签产生)替换为'); 由于上一步已经把<%=产生的tab符去掉,因此这里实际替换的只有逻辑代码的左标签 + .split("%>").join("$parts.push('") // 把剩下的右标签%>(逻辑代码的)替换为"$parts.push('" + + "'); return $parts.join('');"; // 最后得到的就是一段JS代码,保留模板中的逻辑,并依次把模板中的常量和变量压入$parts数组 + + return data ? fn(data, env) : fn; // 如果传入了数据,则直接返回渲染结果HTML文本,否则返回一个渲染函数 + }; + $.adaptObject = function (element, defaults, option,template,plugin,pluginName) { + var $this= element; + + if (typeof option != 'string'){ + + // 获得配置信息 + var context=$.extend({}, defaults, typeof option == 'object' && option); + + var isFromTpl=false; + // 如果传入script标签的选择器 + if($.isArray($this) && $this.length && $($this)[0].nodeName.toLowerCase()=="script"){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl($this[0].innerHTML,context)).appendTo("body"); + isFromTpl=true; + } + // 如果传入模板字符串 + else if($.isArray($this) && $this.length && $this.selector== ""){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl($this[0].outerHTML,context)).appendTo("body"); + isFromTpl=true; + } + // 如果通过$.dialog()的方式调用 + else if(!$.isArray($this)){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl(template,context)).appendTo("body"); + isFromTpl=true; + } + + } + + return $this.each(function () { + + var el = $(this); + // 读取对象缓存 + + var data = el.data('fz.'+pluginName); + + + + if (!data) el.data('fz.'+pluginName, + (data = new plugin(this,$.extend({}, defaults, typeof option == 'object' && option),isFromTpl) + + )); + + if (typeof option == 'string') data[option](); + }) + } +}(window.Zepto); + + + +/** + * User: jeakeyliang + * Date: 14-08-22 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _dialogTpl='<div class="ui-dialog">'+ + '<div class="ui-dialog-cnt">'+ + '<div class="ui-dialog-bd">'+ + '<div>'+ + '<h4><%=title%></h4>'+ + '<div><%=content%></div></div>'+ + '</div>'+ + '<div class="ui-dialog-ft ui-btn-group">'+ + '<% for (var i = 0; i < button.length; i++) { %>' + + '<% if (i == select) { %>' + + '<button type="button" data-role="button" class="select" id="dialogButton<%=i%>"><%=button[i]%></button>' + + '<% } else { %>' + + '<button type="button" data-role="button" id="dialogButton<%=i%>"><%=button[i]%></div>' + + '<% } %>' + + '<% } %>' + + '</div>'+ + '</div>'+ + '</div>'; + // 默认参数 + var defaults={ + title:'', + content:'', + button:['确认'], + select:0, + allowScroll:false, + callback:function(){} + } + // 构造函数 + var Dialog = function (el,option,isFromTpl) { + + this.option=$.extend(defaults,option); + this.element=$(el); + this._isFromTpl=isFromTpl; + this.button=$(el).find('[data-role="button"]'); + this._bindEvent(); + this.toggle(); + } + Dialog.prototype={ + _bindEvent:function(){ + var self=this; + self.button.on("tap",function(){ + var index=$(self.button).index($(this)); + // self.option.callback("button",index); + var e=$.Event("dialog:action"); + e.index=index; + self.element.trigger(e); + self.hide.apply(self); + }); + }, + toggle:function(){ + if(this.element.hasClass("show")){ + this.hide(); + }else{ + this.show(); + } + }, + show:function(){ + var self=this; + // self.option.callback("show"); + self.element.trigger($.Event("dialog:show")); + self.element.addClass("show"); + this.option.allowScroll && self.element.on("touchmove" , _stopScroll); + + }, + hide :function () { + var self=this; + // self.option.callback("hide"); + self.element.trigger($.Event("dialog:hide")); + self.element.off("touchmove" , _stopScroll); + setTimeout(function(){ + self.element.removeClass("show"); + self._isFromTpl&&self.element.remove(); + },300); + } + } + // 禁止冒泡 + function _stopScroll(){ + return false; + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_dialogTpl,Dialog,"dialog"); + } + $.fn.dialog=$.dialog= Plugin; +}(window.Zepto) + + + +/** + * User: jeakeyliang + * Date: 14-11-07 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _loadingTpl='<div class="ui-loading-block show">'+ + '<div class="ui-loading-cnt">'+ + '<i class="ui-loading-bright"></i>'+ + '<p><%=content%></p>'+ + '</div>'+ + '</div>'; + + // 默认参数 + var defaults={ + content:'加载中...' + } + // 构造函数 + var Loading = function (el,option,isFromTpl) { + var self=this; + this.element=$(el); + this._isFromTpl=isFromTpl; + this.option=$.extend(defaults,option); + this.show(); + } + Loading.prototype={ + show:function(){ + var e=$.Event('loading:show'); + this.element.trigger(e); + this.element.show(); + + }, + hide :function () { + var e=$.Event('loading:hide'); + this.element.trigger(e); + this.element.remove(); + } + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_loadingTpl,Loading,"loading"); + } + $.fn.loading=$.loading= Plugin; +}(window.Zepto) + + + +;(function ($) { + +var rAF = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { window.setTimeout(callback, 1000 / 60); }; + + +/* + * 工具类 + */ +var utils = (function () { + + var me = {}; + + var _elementStyle = document.createElement('div').style; + + var _vendor = (function () { + var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], + transform, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + transform = vendors[i] + 'ransform'; + if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); + } + return false; + })(); + + function _prefixStyle (style) { + if ( _vendor === false ) return false; + if ( _vendor === '' ) return style; + return _vendor + style.charAt(0).toUpperCase() + style.substr(1); + } + + + me.getTime = Date.now || function getTime () { return new Date().getTime(); }; + + + me.extend = function (target, obj) { + for ( var i in obj ) { + target[i] = obj[i]; + } + }; + + + me.addEvent = function (el, type, fn, capture) { + el.addEventListener(type, fn, !!capture); + }; + + + me.removeEvent = function (el, type, fn, capture) { + el.removeEventListener(type, fn, !!capture); + }; + + + me.prefixPointerEvent = function (pointerEvent) { + return window.MSPointerEvent ? + 'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10): + pointerEvent; + }; + + + /** + * 根据一定时间内的滑动距离计算出最终停止距离和时间。 + * @param current:当前滑动位置 + * @param start:touchStart 时候记录的开始位置,但是在touchmove时候可能被重写 + * @param time:touchstart 到手指离开时候经历的时间,同样可能被touchmove重写 + * @param lowerMargin:可移动的最大距离,这个一般为计算得出 this.wrapperHeight - this.scrollerHeight + * @param wrapperSize:如果有边界距离的话就是可拖动,不然碰到0的时候便停止 + * @param deceleration:匀减速 + * @returns {{destination: number, duration: number}} + */ + me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { + var distance = current - start, + speed = Math.abs(distance) / time, + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + + destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); + duration = speed / deceleration; + + if ( destination < lowerMargin ) { + destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if ( destination > 0 ) { + destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }; + + var _transform = _prefixStyle('transform'); + + me.extend(me, { + hasTransform: _transform !== false, + hasPerspective: _prefixStyle('perspective') in _elementStyle, + hasTouch: 'ontouchstart' in window, + hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed + hasTransition: _prefixStyle('transition') in _elementStyle + }); + + // This should find all Android browsers lower than build 535.19 (both stock browser and webview) + me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion)); + + me.extend(me.style = {}, { + transform: _transform, + transitionTimingFunction: _prefixStyle('transitionTimingFunction'), + transitionDuration: _prefixStyle('transitionDuration'), + transitionDelay: _prefixStyle('transitionDelay'), + transformOrigin: _prefixStyle('transformOrigin'), + transitionProperty: _prefixStyle('transitionProperty') + }); + + + me.offset = function (el) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + return { + left: left, + top: top + }; + }; + + + /* + * 配合 config 里面的 preventDefaultException 属性 + * 不对匹配到的 element 使用 e.preventDefault() + * 默认阻止所有事件的冒泡,包括 click 或 tap + */ + me.preventDefaultException = function (el, exceptions) { + for ( var i in exceptions ) { + if ( exceptions[i].test(el[i]) ) { + return true; + } + } + return false; + }; + + + me.extend(me.eventType = {}, { + touchstart: 1, + touchmove: 1, + touchend: 1, + + mousedown: 2, + mousemove: 2, + mouseup: 2, + + pointerdown: 3, + pointermove: 3, + pointerup: 3, + + MSPointerDown: 3, + MSPointerMove: 3, + MSPointerUp: 3 + }); + + + me.extend(me.ease = {}, { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function (k) { + return k * ( 2 - k ); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1) + fn: function (k) { + return Math.sqrt( 1 - ( --k * k ) ); + } + }, + back: { + style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', + fn: function (k) { + var b = 4; + return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; + } + }, + bounce: { + style: '', + fn: function (k) { + if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { + return 7.5625 * k * k; + } else if ( k < ( 2 / 2.75 ) ) { + return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; + } else if ( k < ( 2.5 / 2.75 ) ) { + return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; + } else { + return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + } + } + }, + elastic: { + style: '', + fn: function (k) { + var f = 0.22, + e = 0.4; + + if ( k === 0 ) { return 0; } + if ( k == 1 ) { return 1; } + + return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); + } + } + }); + + me.tap = function (e, eventName) { + var ev = document.createEvent('Event'); + ev.initEvent(eventName, true, true); + ev.pageX = e.pageX; + ev.pageY = e.pageY; + e.target.dispatchEvent(ev); + }; + + me.click = function (e) { + var target = e.target, + ev; + if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + target.screenX, target.screenY, target.clientX, target.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + + ev._constructed = true; + target.dispatchEvent(ev); + } + }; + + return me; +})(); + + + +/* + * 构造函数 + */ +function Scroll(el, options) { + + this.wrapper = typeof el == 'string' ? $(el)[0] : el; + + this.options = { + startX: 0, // 初始化 X 坐标 + startY: 0, // 初始化 Y 坐标 + scrollY: true, // 竖向滚动 + scrollX: false, // 默认非水平 + directionLockThreshold: 5, // 确定滚动方向的阈值 + momentum: true, // 是否开启惯性滚动 + + duration: 300, // transition 过渡时间 + + bounce: true, // 是否有反弹动画 + bounceTime: 600, // 反弹动画时间 + bounceEasing: '', // 反弹动画类型:'circular'(default), 'quadratic', 'back', 'bounce', 'elastic' + + preventDefault: true, // 是否阻止默认滚动事件(和冒泡有区别) + eventPassthrough: true, // 穿透,是否触发原生滑动(取值 true、false、vertical、horizental) + + freeScroll: false, // 任意方向的滚动。若 scrollX 和 scrollY 同时开启,则相当于 freeScroll + + bindToWrapper : true, // 事件是否绑定到 wrapper 元素上,否则大部分绑定到 window(若存在嵌套,则绑定在元素上最好) + resizePolling : 60, // resize 时候隔 60ms 就执行 refresh 方法重新获取位置信息(事件节流) + + disableMouse : false, // 是否禁用鼠标 + disableTouch : false, // 是否禁用touch事件 + disablePointer : false, // 是否禁用win系统的pointer事件 + + tap: true, // 是否模拟 tap 事件 + click: false, // 是否模拟点击事件(false 则使用原生click事件) + + preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, // 当遇到正则内的元素则不阻止冒泡 + + HWCompositing: true, // Hardware acceleration + useTransition: true, // Transition || requestAnimationFrame + useTransform: true // Translate || Left/Top + }; + + + for ( var i in options ) { + this.options[i] = options[i]; + } + + + // scroller + // ================================== + + if (!this.options.role && this.options.scrollX === false) { + this.options.eventPassthrough = 'horizontal'; // 竖直滚动的 scroller 不拦截横向原生滚动 + } + + // slide + // ================================== + + if (this.options.role === 'slider') { + + this.options.scrollX = true; + this.options.scrollY = false; + this.options.momentum = false; + + this.scroller = $('.ui-slider-content')[0]; + $(this.scroller.children[0]).addClass('current'); + + this.currentPage = 0; + this.count = this.scroller.children.length; + + this.scroller.style.width = this.count+"00%"; + + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + + + + if (this.options.indicator) { + var temp = '<ul class="ui-slider-indicators">'; + + for (var i=1; i<=this.count; i++) { + if (i===1) { + temp += '<li class="current">'+i+'</li>'; + } + else { + temp += '<li>'+i+'</li>'; + } + } + temp += '</ul>'; + $(this.wrapper).append(temp); + this.indicator = $('.ui-slider-indicators')[0]; + } + } + + + // tab + // ================================== + + else if (this.options.role === 'tab') { + + this.options.scrollX = true; + this.options.scrollY = false; + this.options.momentum = false; + + this.scroller = $('.ui-tab-content')[0]; + this.nav = $('.ui-tab-nav')[0]; + + $(this.scroller.children[0]).addClass('current'); + $(this.nav.children[0]).addClass('current'); + + this.currentPage = 0; + this.count = this.scroller.children.length; + + this.scroller.style.width = this.count+"00%"; + + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + + + } + else { + this.scroller = this.wrapper.children[0]; + } + this.scrollerStyle = this.scroller.style; + + + this.translateZ = utils.hasPerspective && this.options.HWCompositing ? ' translateZ(0)' : ''; + this.options.useTransition = utils.hasTransition && this.options.useTransition; + this.options.useTransform = utils.hasTransform && this.options.useTransform; + this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; + this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; + // If you want eventPassthrough I have to lock one of the axes + this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; + this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; + // With eventPassthrough we also need lockDirection mechanism + this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; + this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; + this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; + this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; + + if (this.options.tap === true) { + this.options.tap = 'tap'; + } + if (this.options.useTransform === false) { + this.scroller.style.position = 'relative'; + } + + // Some defaults + this.x = 0; + this.y = 0; + this.directionX = 0; + this.directionY = 0; + this._events = {}; + + this._init(); // 绑定各种事件 + this.refresh(); + + this.scrollTo(this.options.startX, this.options.startY); + this.enable(); + + // 自动播放 + if (this.options.autoplay) { + var context = this; + this.options.interval = this.options.interval || 2000; + this.options.flag = setTimeout(function(){ + context._autoplay.apply(context) + }, context.options.interval); + } +} + + + +Scroll.prototype = { + + _init: function () { + this._initEvents(); + }, + + _initEvents: function (remove) { + var eventType = remove ? utils.removeEvent : utils.addEvent, + target = this.options.bindToWrapper ? this.wrapper : window; + + /* + * 给 addEventListener 传递 this + * 程序会自动找到 handleEvent 方法作为回调函数 + */ + eventType(window, 'orientationchange', this); + eventType(window, 'resize', this); + + if ( this.options.click ) { + eventType(this.wrapper, 'click', this, true); + } + + if ( !this.options.disableMouse ) { + eventType(this.wrapper, 'mousedown', this); + eventType(target, 'mousemove', this); + eventType(target, 'mousecancel', this); + eventType(target, 'mouseup', this); + } + + if ( utils.hasPointer && !this.options.disablePointer ) { + eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); + eventType(target, utils.prefixPointerEvent('pointermove'), this); + eventType(target, utils.prefixPointerEvent('pointercancel'), this); + eventType(target, utils.prefixPointerEvent('pointerup'), this); + } + + if ( utils.hasTouch && !this.options.disableTouch ) { + eventType(this.wrapper, 'touchstart', this); + eventType(target, 'touchmove', this); + eventType(target, 'touchcancel', this); + eventType(target, 'touchend', this); + } + + eventType(this.scroller, 'transitionend', this); + eventType(this.scroller, 'webkitTransitionEnd', this); + eventType(this.scroller, 'oTransitionEnd', this); + eventType(this.scroller, 'MSTransitionEnd', this); + + // tab + // ============================= + if (this.options.role === 'tab') { + eventType(this.nav, 'touchend', this); + eventType(this.nav, 'mouseup', this); + eventType(this.nav, 'pointerup', this); + } + }, + + + refresh: function () { + var rf = this.wrapper.offsetHeight; // Force reflow + + // http://jsfiddle.net/y8Y32/25/ + // clientWidth = content + padding + this.wrapperWidth = this.wrapper.clientWidth; + this.wrapperHeight = this.wrapper.clientHeight; + + + // 添加 wrapper 的 padding 值到 scroller 身上,更符合使用预期 + var matrix = window.getComputedStyle(this.wrapper, null); + var pt = matrix['padding-top'].replace(/[^-\d.]/g, ''), + pb = matrix['padding-bottom'].replace(/[^-\d.]/g, ''), + pl = matrix['padding-left'].replace(/[^-\d.]/g, ''), + pr = matrix['padding-right'].replace(/[^-\d.]/g, ''); + + var matrix2 = window.getComputedStyle(this.scroller, null); + var mt2 = matrix2['margin-top'].replace(/[^-\d.]/g, ''), + mb2 = matrix2['margin-bottom'].replace(/[^-\d.]/g, ''), + ml2 = matrix2['margin-left'].replace(/[^-\d.]/g, ''), + mr2 = matrix2['margin-right'].replace(/[^-\d.]/g, ''); + + + // offsetWidth = content + padding + border + this.scrollerWidth = this.scroller.offsetWidth+parseInt(pl)+parseInt(pr)+parseInt(ml2)+parseInt(mr2); + this.scrollerHeight = this.scroller.offsetHeight+parseInt(pt)+parseInt(pb)+parseInt(mt2)+parseInt(mb2); + + + // slide + // ================================== + if (this.options.role === 'slider' || this.options.role === 'tab') { + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + this.scrollerWidth = this.scrollWidth; + } + + this.maxScrollX = this.wrapperWidth - this.scrollerWidth; + this.maxScrollY = this.wrapperHeight - this.scrollerHeight; + + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + + if ( !this.hasHorizontalScroll ) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if ( !this.hasVerticalScroll ) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.endTime = 0; + this.directionX = 0; + this.directionY = 0; + + this.wrapperOffset = utils.offset(this.wrapper); + this.resetPosition(); + }, + + + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + this._end(e); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'transitionend': + case 'webkitTransitionEnd': + case 'oTransitionEnd': + case 'MSTransitionEnd': + this._transitionEnd(e); + break; + case 'wheel': + case 'DOMMouseScroll': + case 'mousewheel': + this._wheel(e); + break; + case 'keydown': + this._key(e); + break; + case 'click': + if ( !e._constructed ) { + e.preventDefault(); + e.stopPropagation(); + } + break; + } + }, + + + + _start: function (e) { + + if ( utils.eventType[e.type] != 1 ) { // 如果是鼠标点击,则只响应鼠标左键 + if ( e.button !== 0 ) { + return; + } + } + + if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { + return; + } + + // 如果 preventDefault === true 且 不是落后的安卓版本 且 不是需要过滤的 target 就阻止默认的行为 + if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, // 检验是触摸事件对象还是鼠标事件对象 + pos; + + this.initiated = utils.eventType[e.type]; // 初始化事件类型(1:触摸,2:鼠标,3:pointer) + this.moved = false; + this.distX = 0; + this.distY = 0; + this.directionX = 0; + this.directionY = 0; + this.directionLocked = 0; + + this._transitionTime(); + this.startTime = utils.getTime(); + + // 定住正在滑动的 scroller,slider/tab 不这么做 + if ( this.options.useTransition && this.isInTransition && this.options.role !== 'slider' && this.options.role !== 'tab') { + this.isInTransition = false; + pos = this.getComputedPosition(); + this._translate(Math.round(pos.x), Math.round(pos.y)); + } + // 场景:(没有使用 Transition 属性) + else if ( !this.options.useTransition && this.isAnimating ) { + this.isAnimating = false; + } + + this.startX = this.x; + this.startY = this.y; + this.absStartX = this.x; + this.absStartY = this.y; + this.pointX = point.pageX; + this.pointY = point.pageY; + + // throttle + // ====================== + if (this.options.autoplay) { + var context = this; + + clearTimeout(this.options.flag); + this.options.flag = setTimeout(function() { + context._autoplay.apply(context); + }, context.options.interval); + } + + event.stopPropagation(); + }, + + + + _move: function (e) { + + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { // 如果事件类型和 touchstart 初始化的事件类型不一致,退出 + return; + } + if ( this.options.preventDefault ) { // 这么做才能确保 Android 下 touchend 能被正常触发(需测试) + e.preventDefault(); + } + var point = e.touches ? e.touches[0] : e, + deltaX = point.pageX - this.pointX, + deltaY = point.pageY - this.pointY, + timestamp = utils.getTime(), + newX, newY, + absDistX, absDistY; + + this.pointX = point.pageX; + this.pointY = point.pageY; + + this.distX += deltaX; + this.distY += deltaY; + absDistX = Math.abs(this.distX); + absDistY = Math.abs(this.distY); + + + // 如果在很长的时间内只移动了少于 10 像素的距离,那么不会触发惯性滚动 + if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { + return; + } + + // 屏蔽滚动方向的另外一个方向(可配置) + if ( !this.directionLocked && !this.options.freeScroll ) { + if ( absDistX > absDistY + this.options.directionLockThreshold ) { + this.directionLocked = 'h'; // lock horizontally + } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { + this.directionLocked = 'v'; // lock vertically + } else { + this.directionLocked = 'n'; // no lock + } + } + if ( this.directionLocked == 'h' ) { + // slider/tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller).children('li').height('auto'); + } + if ( this.options.eventPassthrough == 'vertical' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'horizontal' ) { + this.initiated = false; + return; + } + deltaY = 0; // 不断重置垂直偏移量为 0 + } + else if ( this.directionLocked == 'v' ) { + if ( this.options.eventPassthrough == 'horizontal' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'vertical' ) { + this.initiated = false; + return; + } + deltaX = 0; // 不断重置水平偏移量为 0 + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + // Slow down if outside of the boundaries + if ( newX > 0 || newX < this.maxScrollX ) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if ( newY > 0 || newY < this.maxScrollY ) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + this.moved = true; // 滚动开始 + this._translate(newX, newY); + + if ( timestamp - this.startTime > 300 ) { // 每 300 毫秒重置一次初始值 + this.startTime = timestamp; + this.startX = this.x; + this.startY = this.y; + } + }, + + + + _end: function (e) { + + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.changedTouches ? e.changedTouches[0] : e, // 移开屏幕的那个触摸点,只会包含在 changedTouches 列表中,而不会包含在 touches 或 targetTouches 列表中 + momentumX, + momentumY, + duration = utils.getTime() - this.startTime, + newX = Math.round(this.x), + newY = Math.round(this.y), + distanceX = Math.abs(newX - this.startX), + distanceY = Math.abs(newY - this.startY), + time = 0, + easing = ''; + + this.isInTransition = 0; + this.initiated = 0; + this.endTime = utils.getTime(); + + + if ( this.resetPosition(this.options.bounceTime) ) { // reset if we are outside of the boundaries + if (this.options.role === 'tab') { + $(this.scroller.children[this.currentPage]).siblings('li').height(0); + } + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + if (!this.moved) { // we scrolled less than 10 pixels + if (this.options.tap && utils.eventType[e.type] === 1) { + utils.tap(e, this.options.tap); + } + if ( this.options.click) { + utils.click(e); + } + } + + // 300ms 内的滑动要启动惯性滚动 + if ( this.options.momentum && duration < 300 ) { + momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 }; + momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = 1; + } + + if ( newX != this.x || newY != this.y ) { + // change easing function when scroller goes out of the boundaries + if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { + easing = utils.ease.quadratic; + } + this.scrollTo(newX, newY, time, easing); + return; + } + + + // tab + // ========================== + if (this.options.role === 'tab' && $(event.target).closest('ul').hasClass('ui-tab-nav')) { + $(this.nav).children().removeClass('current'); + $(event.target).addClass('current'); + var tempCurrentPage = this.currentPage; + this.currentPage = $(event.target).index(); + + $(this.scroller).children().height('auto'); // tab 外层高度自适应 + this._execEvent('beforeScrollStart', tempCurrentPage, this.currentPage); + } + + + + // slider & tab + // ============================== + if (this.options.role === 'slider' || this.options.role === 'tab') { + + if (distanceX < 30) { + this.scrollTo(-this.itemWidth*this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + else if (newX-this.startX<0) { // 向前 + this._execEvent('beforeScrollStart', this.currentPage, this.currentPage+1); + this.scrollTo(-this.itemWidth*++this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + else if (newX-this.startX>=0) { // 向后 + this._execEvent('beforeScrollStart', this.currentPage, this.currentPage-1); + this.scrollTo(-this.itemWidth*--this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + + // tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller.children[this.currentPage]).siblings('li').height(0); + } + + if (this.indicator && distanceX >= 30) { + $(this.indicator).children().removeClass('current'); + $(this.indicator.children[this.currentPage]).addClass('current'); + } + else if (this.nav && distanceX >= 30) { + $(this.nav).children().removeClass('current'); + $(this.nav.children[this.currentPage]).addClass('current'); + } + + $(this.scroller).children().removeClass('current'); + $(this.scroller.children[this.currentPage]).addClass('current'); + } + }, + + + _resize: function () { + var that = this; + clearTimeout(this.resizeTimeout); + this.resizeTimeout = setTimeout(function () { + that.refresh(); + }, this.options.resizePolling); + }, + + + _transitionEnd: function (e) { + if ( e.target != this.scroller || !this.isInTransition ) { + return; + } + this._transitionTime(); + + if ( !this.resetPosition(this.options.bounceTime) ) { + this.isInTransition = false; + this._execEvent('scrollEnd', this.currentPage); + } + }, + + + destroy: function () { + this._initEvents(true); // 去除事件绑定 + }, + + + resetPosition: function (time) { + var x = this.x, + y = this.y; + + time = time || 0; + + if ( !this.hasHorizontalScroll || this.x > 0 ) { + x = 0; + } else if ( this.x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( !this.hasVerticalScroll || this.y > 0 ) { + y = 0; + } else if ( this.y < this.maxScrollY ) { + y = this.maxScrollY; + } + + if ( x == this.x && y == this.y ) { + return false; + } + this.scrollTo(x, y, time, this.options.bounceEasing); + return true; + }, + + + + disable: function () { + this.enabled = false; + }, + + enable: function () { + this.enabled = true; + }, + + + + on: function (type, fn) { + if ( !this._events[type] ) { + this._events[type] = []; + } + this._events[type].push(fn); + }, + off: function (type, fn) { + if ( !this._events[type] ) { + return; + } + + var index = this._events[type].indexOf(fn); + + if ( index > -1 ) { + this._events[type].splice(index, 1); + } + }, + + + _execEvent: function (type) { + if ( !this._events[type] ) { + return; + } + var i = 0, + l = this._events[type].length; + + if ( !l ) { + return; + } + for ( ; i < l; i++ ) { + this._events[type][i].apply(this, [].slice.call(arguments, 1)); + } + }, + + + scrollTo: function (x, y, time, easing) { + easing = easing || utils.ease.circular; + + this.isInTransition = this.options.useTransition && time > 0; + + if ( !time || (this.options.useTransition && easing.style) ) { + + if (this.options.role === 'slider' || this.options.role === 'tab') { // 不添加判断会影响 left/top 的过渡 + time = this.options.duration; + this.scrollerStyle[utils.style.transitionProperty] = utils.style.transform; + } + this.scrollerStyle[utils.style.transitionTimingFunction] = easing.style; + this._transitionTime(time); + this._translate(x, y); + } else { + this._animate(x, y, time, easing.fn); + } + }, + + + scrollToElement: function (el, time, offsetX, offsetY, easing) { + el = el.nodeType ? el : this.scroller.querySelector(el); + + if ( !el ) { + return; + } + var pos = utils.offset(el); + pos.left -= this.wrapperOffset.left; + pos.top -= this.wrapperOffset.top; + + // if offsetX/Y are true we center the element to the screen + // 若 offsetX/Y 都是 true,则会滚动到元素在屏幕中间的位置 + if ( offsetX === true ) { + offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); + } + if ( offsetY === true ) { + offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); + } + pos.left -= offsetX || 0; + pos.top -= offsetY || 0; + pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; + pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; + + time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; + + this.scrollTo(pos.left, pos.top, time, easing); + }, + + + _transitionTime: function (time) { + time = time || 0; + this.scrollerStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.scrollerStyle[utils.style.transitionDuration] = '0.001s'; + } + }, + + + _translate: function (x, y) { + if ( this.options.useTransform ) { + if(this.options.slidingY === 'y'){ + this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; + }else{ + this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,0px)' + this.translateZ; + } + } else { + x = Math.round(x); + y = Math.round(y); + this.scrollerStyle.left = x + 'px'; + this.scrollerStyle.top = y + 'px'; + } + this.x = x; + this.y = y; + }, + + + getComputedPosition: function () { + var matrix = window.getComputedStyle(this.scroller, null), + x, y; + + if ( this.options.useTransform ) { + matrix = matrix[utils.style.transform].split(')')[0].split(', '); + x = +(matrix[12] || matrix[4]); + y = +(matrix[13] || matrix[5]); + } else { + x = +matrix.left.replace(/[^-\d.]/g, ''); + y = +matrix.top.replace(/[^-\d.]/g, ''); + } + + return { x: x, y: y }; + }, + + + _animate: function (destX, destY, duration, easingFn) { // 当浏览器不支持 transition 时提供的退化方案 requestAnimationFrame + var that = this, + startX = this.x, + startY = this.y, + startTime = utils.getTime(), + destTime = startTime + duration; + + function step () { + var now = utils.getTime(), + newX, newY, + easing; + + if ( now >= destTime ) { + that.isAnimating = false; + that._translate(destX, destY); + + if ( !that.resetPosition(that.options.bounceTime) ) { + that._execEvent('scrollEnd', this.currentPage); + } + return; + } + + now = ( now - startTime ) / duration; + easing = easingFn(now); + newX = ( destX - startX ) * easing + startX; + newY = ( destY - startY ) * easing + startY; + that._translate(newX, newY); + + if ( that.isAnimating ) { + rAF(step); + } + } + this.isAnimating = true; + step(); + }, + + + _autoplay: function() { + var self = this, + curPage = self.currentPage; + + self.currentPage = self.currentPage >= self.count-1 ? 0 : ++self.currentPage; + self._execEvent('beforeScrollStart', curPage, self.currentPage); // 对于自动播放的 slider/tab,这个时机就是 beforeScrollStart + + // tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller).children().height('auto'); + document.body.scrollTop = 0; + } + self.scrollTo(-self.itemWidth*self.currentPage, 0, self.options.bounceTime, self.options.bounceEasing); + + if (self.indicator) { + $(self.indicator).children().removeClass('current'); + $(self.indicator.children[self.currentPage]).addClass('current'); + $(self.scroller).children().removeClass('current'); + $(self.scroller.children[self.currentPage]).addClass('current'); + } + else if (self.nav) { + $(self.nav).children().removeClass('current'); + $(self.nav.children[self.currentPage]).addClass('current'); + $(self.scroller).children().removeClass('current'); + $(self.scroller.children[self.currentPage]).addClass('current'); + } + + self.options.flag = setTimeout(function() { + self._autoplay.apply(self); + }, self.options.interval); + } + + +}; + +// Scroll.utils = utils; +window.fz = window.fz || {}; +window.frozen = window.frozen || {}; +window.fz.Scroll = window.frozen.Scroll = Scroll; + +/* + * 兼容 RequireJS 和 Sea.js + */ +if (typeof define === "function") { + define(function(require, exports, module) { + module.exports = Scroll; + }) +} + +})(window.Zepto); +/** + * User: jeakeyliang + * Date: 14-11-07 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _tipsTpl='<div class="ui-poptips ui-poptips-<%=type%>">'+ + '<div class="ui-poptips-cnt">'+ + '<i></i><%=content%>'+ + '</div>'+ + '</div>'; + + // 默认参数 + var defaults={ + content:'', + stayTime:1000, + type:'info', + callback:function(){} + } + // 构造函数 + var Tips = function (el,option,isFromTpl) { + var self=this; + this.element=$(el); + this._isFromTpl=isFromTpl; + this.elementHeight=$(el).height(); + + this.option=$.extend(defaults,option); + $(el).css({ + "-webkit-transform":"translateY(-"+this.elementHeight+"px)" + }); + setTimeout(function(){ + $(el).css({ + "-webkit-transition":"all .5s" + }); + self.show(); + },20); + + } + Tips.prototype={ + show:function(){ + var self=this; + // self.option.callback("show"); + self.element.trigger($.Event("tips:show")); + this.element.css({ + "-webkit-transform":"translateY(0px)" + }); + if(self.option.stayTime>0){ + setTimeout(function(){ + self.hide(); + },self.option.stayTime) + } + }, + hide :function () { + var self=this; + self.element.trigger($.Event("tips:hide")); + this.element.css({ + "-webkit-transform":"translateY(-"+this.elementHeight+"px)" + }); + setTimeout(function(){ + self._isFromTpl&&self.element.remove(); + },500) + + + } + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_tipsTpl,Tips,"tips"); + } + $.fn.tips=$.tips= Plugin; +}(window.Zepto) + + diff --git a/hyhproject/mobile2/view/default/frozenui/js/zepto.min.js b/hyhproject/mobile2/view/default/frozenui/js/zepto.min.js new file mode 100755 index 0000000..3d65b8c --- /dev/null +++ b/hyhproject/mobile2/view/default/frozenui/js/zepto.min.js @@ -0,0 +1,2585 @@ +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +var Zepto = (function() { + var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice, + document = window.document, + elementDisplay = {}, classCache = {}, + cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, + fragmentRE = /^\s*<(\w+|!)[^>]*>/, + singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rootNodeRE = /^(?:body|html)$/i, + capitalRE = /([A-Z])/g, + + // special attributes that should be get/set via method calls + methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], + + adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], + table = document.createElement('table'), + tableRow = document.createElement('tr'), + containers = { + 'tr': document.createElement('tbody'), + 'tbody': table, 'thead': table, 'tfoot': table, + 'td': tableRow, 'th': tableRow, + '*': document.createElement('div') + }, + readyRE = /complete|loaded|interactive/, + simpleSelectorRE = /^[\w-]*$/, + class2type = {}, + toString = class2type.toString, + zepto = {}, + camelize, uniq, + tempParent = document.createElement('div'), + propMap = { + 'tabindex': 'tabIndex', + 'readonly': 'readOnly', + 'for': 'htmlFor', + 'class': 'className', + 'maxlength': 'maxLength', + 'cellspacing': 'cellSpacing', + 'cellpadding': 'cellPadding', + 'rowspan': 'rowSpan', + 'colspan': 'colSpan', + 'usemap': 'useMap', + 'frameborder': 'frameBorder', + 'contenteditable': 'contentEditable' + }, + isArray = Array.isArray || + function(object){ return object instanceof Array } + + zepto.matches = function(element, selector) { + if (!selector || !element || element.nodeType !== 1) return false + var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || + element.oMatchesSelector || element.matchesSelector + if (matchesSelector) return matchesSelector.call(element, selector) + // fall back to performing a selector: + var match, parent = element.parentNode, temp = !parent + if (temp) (parent = tempParent).appendChild(element) + match = ~zepto.qsa(parent, selector).indexOf(element) + temp && tempParent.removeChild(element) + return match + } + + function type(obj) { + return obj == null ? String(obj) : + class2type[toString.call(obj)] || "object" + } + + function isFunction(value) { return type(value) == "function" } + function isWindow(obj) { return obj != null && obj == obj.window } + function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } + function isObject(obj) { return type(obj) == "object" } + function isPlainObject(obj) { + return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype + } + function likeArray(obj) { return typeof obj.length == 'number' } + + function compact(array) { return filter.call(array, function(item){ return item != null }) } + function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } + camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } + function dasherize(str) { + return str.replace(/::/g, '/') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/([a-z\d])([A-Z])/g, '$1_$2') + .replace(/_/g, '-') + .toLowerCase() + } + uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } + + function classRE(name) { + return name in classCache ? + classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) + } + + function maybeAddPx(name, value) { + return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value + } + + function defaultDisplay(nodeName) { + var element, display + if (!elementDisplay[nodeName]) { + element = document.createElement(nodeName) + document.body.appendChild(element) + display = getComputedStyle(element, '').getPropertyValue("display") + element.parentNode.removeChild(element) + display == "none" && (display = "block") + elementDisplay[nodeName] = display + } + return elementDisplay[nodeName] + } + + function children(element) { + return 'children' in element ? + slice.call(element.children) : + $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) + } + + function Z(dom, selector) { + var i, len = dom ? dom.length : 0 + for (i = 0; i < len; i++) this[i] = dom[i] + this.length = len + this.selector = selector || '' + } + + // `$.zepto.fragment` takes a html string and an optional tag name + // to generate DOM nodes nodes from the given html string. + // The generated DOM nodes are returned as an array. + // This function can be overriden in plugins for example to make + // it compatible with browsers that don't support the DOM fully. + zepto.fragment = function(html, name, properties) { + var dom, nodes, container + + // A special case optimization for a single tag + if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) + + if (!dom) { + if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>") + if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 + if (!(name in containers)) name = '*' + + container = containers[name] + container.innerHTML = '' + html + dom = $.each(slice.call(container.childNodes), function(){ + container.removeChild(this) + }) + } + + if (isPlainObject(properties)) { + nodes = $(dom) + $.each(properties, function(key, value) { + if (methodAttributes.indexOf(key) > -1) nodes[key](value) + else nodes.attr(key, value) + }) + } + + return dom + } + + // `$.zepto.Z` swaps out the prototype of the given `dom` array + // of nodes with `$.fn` and thus supplying all the Zepto functions + // to the array. This method can be overriden in plugins. + zepto.Z = function(dom, selector) { + return new Z(dom, selector) + } + + // `$.zepto.isZ` should return `true` if the given object is a Zepto + // collection. This method can be overriden in plugins. + zepto.isZ = function(object) { + return object instanceof zepto.Z + } + + // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and + // takes a CSS selector and an optional context (and handles various + // special cases). + // This method can be overriden in plugins. + zepto.init = function(selector, context) { + var dom + // If nothing given, return an empty Zepto collection + if (!selector) return zepto.Z() + // Optimize for string selectors + else if (typeof selector == 'string') { + selector = selector.trim() + // If it's a html fragment, create nodes from it + // Note: In both Chrome 21 and Firefox 15, DOM error 12 + // is thrown if the fragment doesn't begin with < + if (selector[0] == '<' && fragmentRE.test(selector)) + dom = zepto.fragment(selector, RegExp.$1, context), selector = null + // If there's a context, create a collection on that context first, and select + // nodes from there + else if (context !== undefined) return $(context).find(selector) + // If it's a CSS selector, use it to select nodes. + else dom = zepto.qsa(document, selector) + } + // If a function is given, call it when the DOM is ready + else if (isFunction(selector)) return $(document).ready(selector) + // If a Zepto collection is given, just return it + else if (zepto.isZ(selector)) return selector + else { + // normalize array if an array of nodes is given + if (isArray(selector)) dom = compact(selector) + // Wrap DOM nodes. + else if (isObject(selector)) + dom = [selector], selector = null + // If it's a html fragment, create nodes from it + else if (fragmentRE.test(selector)) + dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null + // If there's a context, create a collection on that context first, and select + // nodes from there + else if (context !== undefined) return $(context).find(selector) + // And last but no least, if it's a CSS selector, use it to select nodes. + else dom = zepto.qsa(document, selector) + } + // create a new Zepto collection from the nodes found + return zepto.Z(dom, selector) + } + + // `$` will be the base `Zepto` object. When calling this + // function just call `$.zepto.init, which makes the implementation + // details of selecting nodes and creating Zepto collections + // patchable in plugins. + $ = function(selector, context){ + return zepto.init(selector, context) + } + + function extend(target, source, deep) { + for (key in source) + if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { + if (isPlainObject(source[key]) && !isPlainObject(target[key])) + target[key] = {} + if (isArray(source[key]) && !isArray(target[key])) + target[key] = [] + extend(target[key], source[key], deep) + } + else if (source[key] !== undefined) target[key] = source[key] + } + + // Copy all but undefined properties from one or more + // objects to the `target` object. + $.extend = function(target){ + var deep, args = slice.call(arguments, 1) + if (typeof target == 'boolean') { + deep = target + target = args.shift() + } + args.forEach(function(arg){ extend(target, arg, deep) }) + return target + } + + // `$.zepto.qsa` is Zepto's CSS selector implementation which + // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. + // This method can be overriden in plugins. + zepto.qsa = function(element, selector){ + var found, + maybeID = selector[0] == '#', + maybeClass = !maybeID && selector[0] == '.', + nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked + isSimple = simpleSelectorRE.test(nameOnly) + return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById + ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : + (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] : + slice.call( + isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName + maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class + element.getElementsByTagName(selector) : // Or a tag + element.querySelectorAll(selector) // Or it's not simple, and we need to query all + ) + } + + function filtered(nodes, selector) { + return selector == null ? $(nodes) : $(nodes).filter(selector) + } + + $.contains = document.documentElement.contains ? + function(parent, node) { + return parent !== node && parent.contains(node) + } : + function(parent, node) { + while (node && (node = node.parentNode)) + if (node === parent) return true + return false + } + + function funcArg(context, arg, idx, payload) { + return isFunction(arg) ? arg.call(context, idx, payload) : arg + } + + function setAttribute(node, name, value) { + value == null ? node.removeAttribute(name) : node.setAttribute(name, value) + } + + // access className property while respecting SVGAnimatedString + function className(node, value){ + var klass = node.className || '', + svg = klass && klass.baseVal !== undefined + + if (value === undefined) return svg ? klass.baseVal : klass + svg ? (klass.baseVal = value) : (node.className = value) + } + + // "true" => true + // "false" => false + // "null" => null + // "42" => 42 + // "42.5" => 42.5 + // "08" => "08" + // JSON => parse if valid + // String => self + function deserializeValue(value) { + try { + return value ? + value == "true" || + ( value == "false" ? false : + value == "null" ? null : + +value + "" == value ? +value : + /^[\[\{]/.test(value) ? $.parseJSON(value) : + value ) + : value + } catch(e) { + return value + } + } + + $.type = type + $.isFunction = isFunction + $.isWindow = isWindow + $.isArray = isArray + $.isPlainObject = isPlainObject + + $.isEmptyObject = function(obj) { + var name + for (name in obj) return false + return true + } + + $.inArray = function(elem, array, i){ + return emptyArray.indexOf.call(array, elem, i) + } + + $.camelCase = camelize + $.trim = function(str) { + return str == null ? "" : String.prototype.trim.call(str) + } + + // plugin compatibility + $.uuid = 0 + $.support = { } + $.expr = { } + $.noop = function() {} + + $.map = function(elements, callback){ + var value, values = [], i, key + if (likeArray(elements)) + for (i = 0; i < elements.length; i++) { + value = callback(elements[i], i) + if (value != null) values.push(value) + } + else + for (key in elements) { + value = callback(elements[key], key) + if (value != null) values.push(value) + } + return flatten(values) + } + + $.each = function(elements, callback){ + var i, key + if (likeArray(elements)) { + for (i = 0; i < elements.length; i++) + if (callback.call(elements[i], i, elements[i]) === false) return elements + } else { + for (key in elements) + if (callback.call(elements[key], key, elements[key]) === false) return elements + } + + return elements + } + + $.grep = function(elements, callback){ + return filter.call(elements, callback) + } + + if (window.JSON) $.parseJSON = JSON.parse + + // Populate the class2type map + $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase() + }) + + // Define methods that will be available on all + // Zepto collections + $.fn = { + constructor: zepto.Z, + length: 0, + + // Because a collection acts like an array + // copy over these useful array functions. + forEach: emptyArray.forEach, + reduce: emptyArray.reduce, + push: emptyArray.push, + sort: emptyArray.sort, + splice: emptyArray.splice, + indexOf: emptyArray.indexOf, + concat: function(){ + var i, value, args = [] + for (i = 0; i < arguments.length; i++) { + value = arguments[i] + args[i] = zepto.isZ(value) ? value.toArray() : value + } + return concat.apply(zepto.isZ(this) ? this.toArray() : this, args) + }, + + // `map` and `slice` in the jQuery API work differently + // from their array counterparts + map: function(fn){ + return $($.map(this, function(el, i){ return fn.call(el, i, el) })) + }, + slice: function(){ + return $(slice.apply(this, arguments)) + }, + + ready: function(callback){ + // need to check if document.body exists for IE as that browser reports + // document ready when it hasn't yet created the body element + if (readyRE.test(document.readyState) && document.body) callback($) + else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) + return this + }, + get: function(idx){ + return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] + }, + toArray: function(){ return this.get() }, + size: function(){ + return this.length + }, + remove: function(){ + return this.each(function(){ + if (this.parentNode != null) + this.parentNode.removeChild(this) + }) + }, + each: function(callback){ + emptyArray.every.call(this, function(el, idx){ + return callback.call(el, idx, el) !== false + }) + return this + }, + filter: function(selector){ + if (isFunction(selector)) return this.not(this.not(selector)) + return $(filter.call(this, function(element){ + return zepto.matches(element, selector) + })) + }, + add: function(selector,context){ + return $(uniq(this.concat($(selector,context)))) + }, + is: function(selector){ + return this.length > 0 && zepto.matches(this[0], selector) + }, + not: function(selector){ + var nodes=[] + if (isFunction(selector) && selector.call !== undefined) + this.each(function(idx){ + if (!selector.call(this,idx)) nodes.push(this) + }) + else { + var excludes = typeof selector == 'string' ? this.filter(selector) : + (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) + this.forEach(function(el){ + if (excludes.indexOf(el) < 0) nodes.push(el) + }) + } + return $(nodes) + }, + has: function(selector){ + return this.filter(function(){ + return isObject(selector) ? + $.contains(this, selector) : + $(this).find(selector).size() + }) + }, + eq: function(idx){ + return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) + }, + first: function(){ + var el = this[0] + return el && !isObject(el) ? el : $(el) + }, + last: function(){ + var el = this[this.length - 1] + return el && !isObject(el) ? el : $(el) + }, + find: function(selector){ + var result, $this = this + if (!selector) result = $() + else if (typeof selector == 'object') + result = $(selector).filter(function(){ + var node = this + return emptyArray.some.call($this, function(parent){ + return $.contains(parent, node) + }) + }) + else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) + else result = this.map(function(){ return zepto.qsa(this, selector) }) + return result + }, + closest: function(selector, context){ + var node = this[0], collection = false + if (typeof selector == 'object') collection = $(selector) + while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) + node = node !== context && !isDocument(node) && node.parentNode + return $(node) + }, + parents: function(selector){ + var ancestors = [], nodes = this + while (nodes.length > 0) + nodes = $.map(nodes, function(node){ + if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { + ancestors.push(node) + return node + } + }) + return filtered(ancestors, selector) + }, + parent: function(selector){ + return filtered(uniq(this.pluck('parentNode')), selector) + }, + children: function(selector){ + return filtered(this.map(function(){ return children(this) }), selector) + }, + contents: function() { + return this.map(function() { return this.contentDocument || slice.call(this.childNodes) }) + }, + siblings: function(selector){ + return filtered(this.map(function(i, el){ + return filter.call(children(el.parentNode), function(child){ return child!==el }) + }), selector) + }, + empty: function(){ + return this.each(function(){ this.innerHTML = '' }) + }, + // `pluck` is borrowed from Prototype.js + pluck: function(property){ + return $.map(this, function(el){ return el[property] }) + }, + show: function(){ + return this.each(function(){ + this.style.display == "none" && (this.style.display = '') + if (getComputedStyle(this, '').getPropertyValue("display") == "none") + this.style.display = defaultDisplay(this.nodeName) + }) + }, + replaceWith: function(newContent){ + return this.before(newContent).remove() + }, + wrap: function(structure){ + var func = isFunction(structure) + if (this[0] && !func) + var dom = $(structure).get(0), + clone = dom.parentNode || this.length > 1 + + return this.each(function(index){ + $(this).wrapAll( + func ? structure.call(this, index) : + clone ? dom.cloneNode(true) : dom + ) + }) + }, + wrapAll: function(structure){ + if (this[0]) { + $(this[0]).before(structure = $(structure)) + var children + // drill down to the inmost element + while ((children = structure.children()).length) structure = children.first() + $(structure).append(this) + } + return this + }, + wrapInner: function(structure){ + var func = isFunction(structure) + return this.each(function(index){ + var self = $(this), contents = self.contents(), + dom = func ? structure.call(this, index) : structure + contents.length ? contents.wrapAll(dom) : self.append(dom) + }) + }, + unwrap: function(){ + this.parent().each(function(){ + $(this).replaceWith($(this).children()) + }) + return this + }, + clone: function(){ + return this.map(function(){ return this.cloneNode(true) }) + }, + hide: function(){ + return this.css("display", "none") + }, + toggle: function(setting){ + return this.each(function(){ + var el = $(this) + ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() + }) + }, + prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, + next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, + html: function(html){ + return 0 in arguments ? + this.each(function(idx){ + var originHtml = this.innerHTML + $(this).empty().append( funcArg(this, html, idx, originHtml) ) + }) : + (0 in this ? this[0].innerHTML : null) + }, + text: function(text){ + return 0 in arguments ? + this.each(function(idx){ + var newText = funcArg(this, text, idx, this.textContent) + this.textContent = newText == null ? '' : ''+newText + }) : + (0 in this ? this[0].textContent : null) + }, + attr: function(name, value){ + var result + return (typeof name == 'string' && !(1 in arguments)) ? + (!this.length || this[0].nodeType !== 1 ? undefined : + (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result + ) : + this.each(function(idx){ + if (this.nodeType !== 1) return + if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) + else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) + }) + }, + removeAttr: function(name){ + return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ + setAttribute(this, attribute) + }, this)}) + }, + prop: function(name, value){ + name = propMap[name] || name + return (1 in arguments) ? + this.each(function(idx){ + this[name] = funcArg(this, value, idx, this[name]) + }) : + (this[0] && this[0][name]) + }, + data: function(name, value){ + var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() + + var data = (1 in arguments) ? + this.attr(attrName, value) : + this.attr(attrName) + + return data !== null ? deserializeValue(data) : undefined + }, + val: function(value){ + return 0 in arguments ? + this.each(function(idx){ + this.value = funcArg(this, value, idx, this.value) + }) : + (this[0] && (this[0].multiple ? + $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : + this[0].value) + ) + }, + offset: function(coordinates){ + if (coordinates) return this.each(function(index){ + var $this = $(this), + coords = funcArg(this, coordinates, index, $this.offset()), + parentOffset = $this.offsetParent().offset(), + props = { + top: coords.top - parentOffset.top, + left: coords.left - parentOffset.left + } + + if ($this.css('position') == 'static') props['position'] = 'relative' + $this.css(props) + }) + if (!this.length) return null + if (!$.contains(document.documentElement, this[0])) + return {top: 0, left: 0} + var obj = this[0].getBoundingClientRect() + return { + left: obj.left + window.pageXOffset, + top: obj.top + window.pageYOffset, + width: Math.round(obj.width), + height: Math.round(obj.height) + } + }, + css: function(property, value){ + if (arguments.length < 2) { + var computedStyle, element = this[0] + if(!element) return + computedStyle = getComputedStyle(element, '') + if (typeof property == 'string') + return element.style[camelize(property)] || computedStyle.getPropertyValue(property) + else if (isArray(property)) { + var props = {} + $.each(property, function(_, prop){ + props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) + }) + return props + } + } + + var css = '' + if (type(property) == 'string') { + if (!value && value !== 0) + this.each(function(){ this.style.removeProperty(dasherize(property)) }) + else + css = dasherize(property) + ":" + maybeAddPx(property, value) + } else { + for (key in property) + if (!property[key] && property[key] !== 0) + this.each(function(){ this.style.removeProperty(dasherize(key)) }) + else + css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' + } + + return this.each(function(){ this.style.cssText += ';' + css }) + }, + index: function(element){ + return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) + }, + hasClass: function(name){ + if (!name) return false + return emptyArray.some.call(this, function(el){ + return this.test(className(el)) + }, classRE(name)) + }, + addClass: function(name){ + if (!name) return this + return this.each(function(idx){ + if (!('className' in this)) return + classList = [] + var cls = className(this), newName = funcArg(this, name, idx, cls) + newName.split(/\s+/g).forEach(function(klass){ + if (!$(this).hasClass(klass)) classList.push(klass) + }, this) + classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) + }) + }, + removeClass: function(name){ + return this.each(function(idx){ + if (!('className' in this)) return + if (name === undefined) return className(this, '') + classList = className(this) + funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ + classList = classList.replace(classRE(klass), " ") + }) + className(this, classList.trim()) + }) + }, + toggleClass: function(name, when){ + if (!name) return this + return this.each(function(idx){ + var $this = $(this), names = funcArg(this, name, idx, className(this)) + names.split(/\s+/g).forEach(function(klass){ + (when === undefined ? !$this.hasClass(klass) : when) ? + $this.addClass(klass) : $this.removeClass(klass) + }) + }) + }, + scrollTop: function(value){ + if (!this.length) return + var hasScrollTop = 'scrollTop' in this[0] + if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset + return this.each(hasScrollTop ? + function(){ this.scrollTop = value } : + function(){ this.scrollTo(this.scrollX, value) }) + }, + scrollLeft: function(value){ + if (!this.length) return + var hasScrollLeft = 'scrollLeft' in this[0] + if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset + return this.each(hasScrollLeft ? + function(){ this.scrollLeft = value } : + function(){ this.scrollTo(value, this.scrollY) }) + }, + position: function() { + if (!this.length) return + + var elem = this[0], + // Get *real* offsetParent + offsetParent = this.offsetParent(), + // Get correct offsets + offset = this.offset(), + parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 + offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 + + // Add offsetParent borders + parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 + parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + } + }, + offsetParent: function() { + return this.map(function(){ + var parent = this.offsetParent || document.body + while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") + parent = parent.offsetParent + return parent + }) + } + } + + // for now + $.fn.detach = $.fn.remove + + // Generate the `width` and `height` functions + ;['width', 'height'].forEach(function(dimension){ + var dimensionProperty = + dimension.replace(/./, function(m){ return m[0].toUpperCase() }) + + $.fn[dimension] = function(value){ + var offset, el = this[0] + if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : + isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : + (offset = this.offset()) && offset[dimension] + else return this.each(function(idx){ + el = $(this) + el.css(dimension, funcArg(this, value, idx, el[dimension]())) + }) + } + }) + + function traverseNode(node, fun) { + fun(node) + for (var i = 0, len = node.childNodes.length; i < len; i++) + traverseNode(node.childNodes[i], fun) + } + + // Generate the `after`, `prepend`, `before`, `append`, + // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. + adjacencyOperators.forEach(function(operator, operatorIndex) { + var inside = operatorIndex % 2 //=> prepend, append + + $.fn[operator] = function(){ + // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings + var argType, nodes = $.map(arguments, function(arg) { + argType = type(arg) + return argType == "object" || argType == "array" || arg == null ? + arg : zepto.fragment(arg) + }), + parent, copyByClone = this.length > 1 + if (nodes.length < 1) return this + + return this.each(function(_, target){ + parent = inside ? target : target.parentNode + + // convert all methods to a "before" operation + target = operatorIndex == 0 ? target.nextSibling : + operatorIndex == 1 ? target.firstChild : + operatorIndex == 2 ? target : + null + + var parentInDocument = $.contains(document.documentElement, parent) + + nodes.forEach(function(node){ + if (copyByClone) node = node.cloneNode(true) + else if (!parent) return $(node).remove() + + parent.insertBefore(node, target) + if (parentInDocument) traverseNode(node, function(el){ + if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && + (!el.type || el.type === 'text/javascript') && !el.src) + window['eval'].call(window, el.innerHTML) + }) + }) + }) + } + + // after => insertAfter + // prepend => prependTo + // before => insertBefore + // append => appendTo + $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ + $(html)[operator](this) + return this + } + }) + + zepto.Z.prototype = Z.prototype = $.fn + + // Export internal API functions in the `$.zepto` namespace + zepto.uniq = uniq + zepto.deserializeValue = deserializeValue + $.zepto = zepto + + return $ +})() + +// If `$` is not yet defined, point it to `Zepto` +window.Zepto = Zepto +window.$ === undefined && (window.$ = Zepto) + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + var _zid = 1, undefined, + slice = Array.prototype.slice, + isFunction = $.isFunction, + isString = function(obj){ return typeof obj == 'string' }, + handlers = {}, + specialEvents={}, + focusinSupported = 'onfocusin' in window, + focus = { focus: 'focusin', blur: 'focusout' }, + hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } + + specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' + + function zid(element) { + return element._zid || (element._zid = _zid++) + } + function findHandlers(element, event, fn, selector) { + event = parse(event) + if (event.ns) var matcher = matcherFor(event.ns) + return (handlers[zid(element)] || []).filter(function(handler) { + return handler + && (!event.e || handler.e == event.e) + && (!event.ns || matcher.test(handler.ns)) + && (!fn || zid(handler.fn) === zid(fn)) + && (!selector || handler.sel == selector) + }) + } + function parse(event) { + var parts = ('' + event).split('.') + return {e: parts[0], ns: parts.slice(1).sort().join(' ')} + } + function matcherFor(ns) { + return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') + } + + function eventCapture(handler, captureSetting) { + return handler.del && + (!focusinSupported && (handler.e in focus)) || + !!captureSetting + } + + function realEvent(type) { + return hover[type] || (focusinSupported && focus[type]) || type + } + + function add(element, events, fn, data, selector, delegator, capture){ + var id = zid(element), set = (handlers[id] || (handlers[id] = [])) + events.split(/\s/).forEach(function(event){ + if (event == 'ready') return $(document).ready(fn) + var handler = parse(event) + handler.fn = fn + handler.sel = selector + // emulate mouseenter, mouseleave + if (handler.e in hover) fn = function(e){ + var related = e.relatedTarget + if (!related || (related !== this && !$.contains(this, related))) + return handler.fn.apply(this, arguments) + } + handler.del = delegator + var callback = delegator || fn + handler.proxy = function(e){ + e = compatible(e) + if (e.isImmediatePropagationStopped()) return + e.data = data + var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) + if (result === false) e.preventDefault(), e.stopPropagation() + return result + } + handler.i = set.length + set.push(handler) + if ('addEventListener' in element) + element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) + }) + } + function remove(element, events, fn, selector, capture){ + var id = zid(element) + ;(events || '').split(/\s/).forEach(function(event){ + findHandlers(element, event, fn, selector).forEach(function(handler){ + delete handlers[id][handler.i] + if ('removeEventListener' in element) + element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) + }) + }) + } + + $.event = { add: add, remove: remove } + + $.proxy = function(fn, context) { + var args = (2 in arguments) && slice.call(arguments, 2) + if (isFunction(fn)) { + var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } + proxyFn._zid = zid(fn) + return proxyFn + } else if (isString(context)) { + if (args) { + args.unshift(fn[context], fn) + return $.proxy.apply(null, args) + } else { + return $.proxy(fn[context], fn) + } + } else { + throw new TypeError("expected function") + } + } + + $.fn.bind = function(event, data, callback){ + return this.on(event, data, callback) + } + $.fn.unbind = function(event, callback){ + return this.off(event, callback) + } + $.fn.one = function(event, selector, data, callback){ + return this.on(event, selector, data, callback, 1) + } + + var returnTrue = function(){return true}, + returnFalse = function(){return false}, + ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/, + eventMethods = { + preventDefault: 'isDefaultPrevented', + stopImmediatePropagation: 'isImmediatePropagationStopped', + stopPropagation: 'isPropagationStopped' + } + + function compatible(event, source) { + if (source || !event.isDefaultPrevented) { + source || (source = event) + + $.each(eventMethods, function(name, predicate) { + var sourceMethod = source[name] + event[name] = function(){ + this[predicate] = returnTrue + return sourceMethod && sourceMethod.apply(source, arguments) + } + event[predicate] = returnFalse + }) + + if (source.defaultPrevented !== undefined ? source.defaultPrevented : + 'returnValue' in source ? source.returnValue === false : + source.getPreventDefault && source.getPreventDefault()) + event.isDefaultPrevented = returnTrue + } + return event + } + + function createProxy(event) { + var key, proxy = { originalEvent: event } + for (key in event) + if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] + + return compatible(proxy, event) + } + + $.fn.delegate = function(selector, event, callback){ + return this.on(event, selector, callback) + } + $.fn.undelegate = function(selector, event, callback){ + return this.off(event, selector, callback) + } + + $.fn.live = function(event, callback){ + $(document.body).delegate(this.selector, event, callback) + return this + } + $.fn.die = function(event, callback){ + $(document.body).undelegate(this.selector, event, callback) + return this + } + + $.fn.on = function(event, selector, data, callback, one){ + var autoRemove, delegator, $this = this + if (event && !isString(event)) { + $.each(event, function(type, fn){ + $this.on(type, selector, data, fn, one) + }) + return $this + } + + if (!isString(selector) && !isFunction(callback) && callback !== false) + callback = data, data = selector, selector = undefined + if (callback === undefined || data === false) + callback = data, data = undefined + + if (callback === false) callback = returnFalse + + return $this.each(function(_, element){ + if (one) autoRemove = function(e){ + remove(element, e.type, callback) + return callback.apply(this, arguments) + } + + if (selector) delegator = function(e){ + var evt, match = $(e.target).closest(selector, element).get(0) + if (match && match !== element) { + evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) + return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) + } + } + + add(element, event, callback, data, selector, delegator || autoRemove) + }) + } + $.fn.off = function(event, selector, callback){ + var $this = this + if (event && !isString(event)) { + $.each(event, function(type, fn){ + $this.off(type, selector, fn) + }) + return $this + } + + if (!isString(selector) && !isFunction(callback) && callback !== false) + callback = selector, selector = undefined + + if (callback === false) callback = returnFalse + + return $this.each(function(){ + remove(this, event, callback, selector) + }) + } + + $.fn.trigger = function(event, args){ + event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) + event._args = args + return this.each(function(){ + // handle focus(), blur() by calling them directly + if (event.type in focus && typeof this[event.type] == "function") this[event.type]() + // items in the collection might not be DOM elements + else if ('dispatchEvent' in this) this.dispatchEvent(event) + else $(this).triggerHandler(event, args) + }) + } + + // triggers event handlers on current element just as if an event occurred, + // doesn't trigger an actual event, doesn't bubble + $.fn.triggerHandler = function(event, args){ + var e, result + this.each(function(i, element){ + e = createProxy(isString(event) ? $.Event(event) : event) + e._args = args + e.target = element + $.each(findHandlers(element, event.type || event), function(i, handler){ + result = handler.proxy(e) + if (e.isImmediatePropagationStopped()) return false + }) + }) + return result + } + + // shortcut methods for `.bind(event, fn)` for each event type + ;('focusin focusout focus blur load resize scroll unload click dblclick '+ + 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ + 'change select keydown keypress keyup error').split(' ').forEach(function(event) { + $.fn[event] = function(callback) { + return (0 in arguments) ? + this.bind(event, callback) : + this.trigger(event) + } + }) + + $.Event = function(type, props) { + if (!isString(type)) props = type, type = props.type + var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true + if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) + event.initEvent(type, bubbles, true) + return compatible(event) + } + +})(Zepto) + +/*! touchjs v0.2.14 2014-08-05 */ +'use strict'; +(function(root, factory) { + if (typeof define === 'function' && (define.amd || define.cmd)) { + define(factory); //Register as a module. + } else { + root.touch = factory(); + } +}(this, function() { + +var utils = {}; + +utils.PCevts = { + 'touchstart': 'mousedown', + 'touchmove': 'mousemove', + 'touchend': 'mouseup', + 'touchcancel': 'mouseout' +}; + +utils.hasTouch = ('ontouchstart' in window); + +utils.getType = function(obj) { + return Object.prototype.toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); +}; + +utils.getSelector = function(el) { + if (el.id) { + return "#" + el.id; + } + if (el.className) { + var cns = el.className.split(/\s+/); + return "." + cns.join("."); + } else if (el === document) { + return "body"; + } else { + return el.tagName.toLowerCase(); + } +}; + +utils.matchSelector = function(target, selector) { + return target.webkitMatchesSelector(selector); +}; + +utils.getEventListeners = function(el) { + return el.listeners; +}; + +utils.getPCevts = function(evt) { + return this.PCevts[evt] || evt; +}; + +utils.forceReflow = function() { + var tempDivID = "reflowDivBlock"; + var domTreeOpDiv = document.getElementById(tempDivID); + if (!domTreeOpDiv) { + domTreeOpDiv = document.createElement("div"); + domTreeOpDiv.id = tempDivID; + document.body.appendChild(domTreeOpDiv); + } + var parentNode = domTreeOpDiv.parentNode; + var nextSibling = domTreeOpDiv.nextSibling; + parentNode.removeChild(domTreeOpDiv); + parentNode.insertBefore(domTreeOpDiv, nextSibling); +}; + +utils.simpleClone = function(obj) { + return Object.create(obj); +}; + +utils.getPosOfEvent = function(ev) { + if (this.hasTouch) { + var posi = []; + var src = null; + + for (var t = 0, len = ev.touches.length; t < len; t++) { + src = ev.touches[t]; + posi.push({ + x: src.pageX, + y: src.pageY + }); + } + return posi; + } else { + return [{ + x: ev.pageX, + y: ev.pageY + }]; + } +}; + +utils.getDistance = function(pos1, pos2) { + var x = pos2.x - pos1.x, + y = pos2.y - pos1.y; + return Math.sqrt((x * x) + (y * y)); +}; + +utils.getFingers = function(ev) { + return ev.touches ? ev.touches.length : 1; +}; + +utils.calScale = function(pstart, pmove) { + if (pstart.length >= 2 && pmove.length >= 2) { + var disStart = this.getDistance(pstart[1], pstart[0]); + var disEnd = this.getDistance(pmove[1], pmove[0]); + + return disEnd / disStart; + } + return 1; +}; + +utils.getAngle = function(p1, p2) { + return Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI; +}; + +utils.getAngle180 = function(p1, p2) { + var agl = Math.atan((p2.y - p1.y) * -1 / (p2.x - p1.x)) * (180 / Math.PI); + return (agl < 0 ? (agl + 180) : agl); +}; + +utils.getDirectionFromAngle = function(agl) { + var directions = { + up: agl < -45 && agl > -135, + down: agl >= 45 && agl < 135, + left: agl >= 135 || agl <= -135, + right: agl >= -45 && agl <= 45 + }; + for (var key in directions) { + if (directions[key]) return key; + } + return null; +}; + +utils.getXYByElement = function(el) { + var left = 0, + top = 0; + + while (el.offsetParent) { + left += el.offsetLeft; + top += el.offsetTop; + el = el.offsetParent; + } + return { + left: left, + top: top + }; +}; + +utils.reset = function() { + startEvent = moveEvent = endEvent = null; + __tapped = __touchStart = startSwiping = startPinch = false; + startDrag = false; + pos = {}; + __rotation_single_finger = false; +}; + +utils.isTouchMove = function(ev) { + return (ev.type === 'touchmove' || ev.type === 'mousemove'); +}; + +utils.isTouchEnd = function(ev) { + return (ev.type === 'touchend' || ev.type === 'mouseup' || ev.type === 'touchcancel'); +}; + +utils.env = (function() { + var os = {}, ua = navigator.userAgent, + android = ua.match(/(Android)[\s\/]+([\d\.]+)/), + ios = ua.match(/(iPad|iPhone|iPod)\s+OS\s([\d_\.]+)/), + wp = ua.match(/(Windows\s+Phone)\s([\d\.]+)/), + isWebkit = /WebKit\/[\d.]+/i.test(ua), + isSafari = ios ? (navigator.standalone ? isWebkit : (/Safari/i.test(ua) && !/CriOS/i.test(ua) && !/MQQBrowser/i.test(ua))) : false; + if (android) { + os.android = true; + os.version = android[2]; + } + if (ios) { + os.ios = true; + os.version = ios[2].replace(/_/g, '.'); + os.ios7 = /^7/.test(os.version); + if (ios[1] === 'iPad') { + os.ipad = true; + } else if (ios[1] === 'iPhone') { + os.iphone = true; + os.iphone5 = screen.height == 568; + } else if (ios[1] === 'iPod') { + os.ipod = true; + } + } + if (wp) { + os.wp = true; + os.version = wp[2]; + os.wp8 = /^8/.test(os.version); + } + if (isWebkit) { + os.webkit = true; + } + if (isSafari) { + os.safari = true; + } + return os; +})(); + +/** 底层事件绑定/代理支持 */ +var engine = { + proxyid: 0, + proxies: [], + trigger: function(el, evt, detail) { + + detail = detail || {}; + var e, opt = { + bubbles: true, + cancelable: true, + detail: detail + }; + + try { + if (typeof CustomEvent !== 'undefined') { + e = new CustomEvent(evt, opt); + if (el) { + el.dispatchEvent(e); + } + } else { + e = document.createEvent("CustomEvent"); + e.initCustomEvent(evt, true, true, detail); + if (el) { + el.dispatchEvent(e); + } + } + } catch (ex) { + console.warn("Touch.js is not supported by environment."); + } + }, + bind: function(el, evt, handler) { + el.listeners = el.listeners || {}; + if (!el.listeners[evt]) { + el.listeners[evt] = [handler]; + } else { + el.listeners[evt].push(handler); + } + var proxy = function(e) { + if (utils.env.ios7) { + utils.forceReflow(); + } + e.originEvent = e; + for (var p in e.detail) { + if (p !== 'type') { + e[p] = e.detail[p]; + } + } + e.startRotate = function() { + __rotation_single_finger = true; + }; + var returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + }; + handler.proxy = handler.proxy || {}; + if (!handler.proxy[evt]) { + handler.proxy[evt] = [this.proxyid++]; + } else { + handler.proxy[evt].push(this.proxyid++); + } + this.proxies.push(proxy); + if (el.addEventListener) { + el.addEventListener(evt, proxy, false); + } + }, + unbind: function(el, evt, handler) { + if (!handler) { + var handlers = el.listeners[evt]; + if (handlers && handlers.length) { + handlers.forEach(function(handler) { + el.removeEventListener(evt, handler, false); + }); + } + } else { + var proxyids = handler.proxy[evt]; + if (proxyids && proxyids.length) { + proxyids.forEach(function(proxyid) { + if (el.removeEventListener) { + el.removeEventListener(evt, this.proxies[this.proxyid], false); + } + }); + } + } + }, + delegate: function(el, evt, sel, handler) { + var proxy = function(e) { + var target, returnValue; + e.originEvent = e; + for (var p in e.detail) { + if (p !== 'type') { + e[p] = e.detail[p]; + } + } + e.startRotate = function() { + __rotation_single_finger = true; + }; + var integrateSelector = utils.getSelector(el) + " " + sel; + var match = utils.matchSelector(e.target, integrateSelector); + var ischild = utils.matchSelector(e.target, integrateSelector + " " + e.target.nodeName); + if (!match && ischild) { + if (utils.env.ios7) { + utils.forceReflow(); + } + target = e.target; + while (!utils.matchSelector(target, integrateSelector)) { + target = target.parentNode; + } + returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + } else { + if (utils.env.ios7) { + utils.forceReflow(); + } + if (match || ischild) { + returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + } + } + }; + handler.proxy = handler.proxy || {}; + if (!handler.proxy[evt]) { + handler.proxy[evt] = [this.proxyid++]; + } else { + handler.proxy[evt].push(this.proxyid++); + } + this.proxies.push(proxy); + el.listeners = el.listeners || {}; + if (!el.listeners[evt]) { + el.listeners[evt] = [proxy]; + } else { + el.listeners[evt].push(proxy); + } + if (el.addEventListener) { + el.addEventListener(evt, proxy, false); + } + }, + undelegate: function(el, evt, sel, handler) { + if (!handler) { + var listeners = el.listeners[evt]; + listeners.forEach(function(proxy) { + el.removeEventListener(evt, proxy, false); + }); + } else { + var proxyids = handler.proxy[evt]; + if (proxyids.length) { + proxyids.forEach(function(proxyid) { + if (el.removeEventListener) { + el.removeEventListener(evt, this.proxies[this.proxyid], false); + } + }); + } + } + } +}; + +var config = { + tap: true, + doubleTap: true, + tapMaxDistance: 10, + hold: true, + tapTime: 200, + holdTime: 650, + maxDoubleTapInterval: 300, + swipe: true, + swipeTime: 300, + swipeMinDistance: 18, + swipeFactor: 5, + drag: true, + pinch: true, + minScaleRate: 0, + minRotationAngle: 0 +}; + +var smrEventList = { + TOUCH_START: 'touchstart', + TOUCH_MOVE: 'touchmove', + TOUCH_END: 'touchend', + TOUCH_CANCEL: 'touchcancel', + MOUSE_DOWN: 'mousedown', + MOUSE_MOVE: 'mousemove', + MOUSE_UP: 'mouseup', + CLICK: 'click', + PINCH_START: 'pinchstart', + PINCH_END: 'pinchend', + PINCH: 'pinch', + PINCH_IN: 'pinchin', + PINCH_OUT: 'pinchout', + ROTATION_LEFT: 'rotateleft', + ROTATION_RIGHT: 'rotateright', + ROTATION: 'rotate', + SWIPE_START: 'swipestart', + SWIPING: 'swiping', + SWIPE_END: 'swipeend', + SWIPE_LEFT: 'swipeleft', + SWIPE_RIGHT: 'swiperight', + SWIPE_UP: 'swipeup', + SWIPE_DOWN: 'swipedown', + SWIPE: 'swipe', + DRAG: 'drag', + DRAGSTART: 'dragstart', + DRAGEND: 'dragend', + HOLD: 'hold', + TAP: 'tap', + DOUBLE_TAP: 'doubletap' +}; + +/** 手势识别 */ +var pos = { + start: null, + move: null, + end: null +}; + +var startTime = 0; +var fingers = 0; +var startEvent = null; +var moveEvent = null; +var endEvent = null; +var startSwiping = false; +var startPinch = false; +var startDrag = false; + +var __offset = {}; +var __touchStart = false; +var __holdTimer = null; +var __tapped = false; +var __lastTapEndTime = null; +var __tapTimer = null; + +var __scale_last_rate = 1; +var __rotation_single_finger = false; +var __rotation_single_start = []; +var __initial_angle = 0; +var __rotation = 0; + +var __prev_tapped_end_time = 0; +var __prev_tapped_pos = null; + +var gestures = { + getAngleDiff: function(currentPos) { + var diff = parseInt(__initial_angle - utils.getAngle180(currentPos[0], currentPos[1]), 10); + var count = 0; + + while (Math.abs(diff - __rotation) > 90 && count++ < 50) { + if (__rotation < 0) { + diff -= 180; + } else { + diff += 180; + } + } + __rotation = parseInt(diff, 10); + return __rotation; + }, + pinch: function(ev) { + var el = ev.target; + if (config.pinch) { + if (!__touchStart) return; + if (utils.getFingers(ev) < 2) { + if (!utils.isTouchEnd(ev)) return; + } + var scale = utils.calScale(pos.start, pos.move); + var rotation = this.getAngleDiff(pos.move); + var eventObj = { + type: '', + originEvent: ev, + scale: scale, + rotation: rotation, + direction: (rotation > 0 ? 'right' : 'left'), + fingersCount: utils.getFingers(ev) + }; + if (!startPinch) { + startPinch = true; + eventObj.fingerStatus = "start"; + engine.trigger(el, smrEventList.PINCH_START, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = "move"; + engine.trigger(el, smrEventList.PINCH, eventObj); + } else if (utils.isTouchEnd(ev)) { + eventObj.fingerStatus = "end"; + engine.trigger(el, smrEventList.PINCH_END, eventObj); + utils.reset(); + } + + if (Math.abs(1 - scale) > config.minScaleRate) { + var scaleEv = utils.simpleClone(eventObj); + + //手势放大, 触发pinchout事件 + var scale_diff = 0.00000000001; //防止touchend的scale与__scale_last_rate相等,不触发事件的情况。 + if (scale > __scale_last_rate) { + __scale_last_rate = scale - scale_diff; + engine.trigger(el, smrEventList.PINCH_OUT, scaleEv, false); + } //手势缩小,触发pinchin事件 + else if (scale < __scale_last_rate) { + __scale_last_rate = scale + scale_diff; + engine.trigger(el, smrEventList.PINCH_IN, scaleEv, false); + } + + if (utils.isTouchEnd(ev)) { + __scale_last_rate = 1; + } + } + + if (Math.abs(rotation) > config.minRotationAngle) { + var rotationEv = utils.simpleClone(eventObj), + eventType; + + eventType = rotation > 0 ? smrEventList.ROTATION_RIGHT : smrEventList.ROTATION_LEFT; + engine.trigger(el, eventType, rotationEv, false); + engine.trigger(el, smrEventList.ROTATION, eventObj); + } + + } + }, + rotateSingleFinger: function(ev) { + var el = ev.target; + if (__rotation_single_finger && utils.getFingers(ev) < 2) { + if (!pos.move) return; + if (__rotation_single_start.length < 2) { + var docOff = utils.getXYByElement(el); + + __rotation_single_start = [{ + x: docOff.left + el.offsetWidth / 2, + y: docOff.top + el.offsetHeight / 2 + }, + pos.move[0] + ]; + __initial_angle = parseInt(utils.getAngle180(__rotation_single_start[0], __rotation_single_start[1]), 10); + } + var move = [__rotation_single_start[0], pos.move[0]]; + var rotation = this.getAngleDiff(move); + var eventObj = { + type: '', + originEvent: ev, + rotation: rotation, + direction: (rotation > 0 ? 'right' : 'left'), + fingersCount: utils.getFingers(ev) + }; + if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = "move"; + } else if (utils.isTouchEnd(ev) || ev.type === 'mouseout') { + eventObj.fingerStatus = "end"; + engine.trigger(el, smrEventList.PINCH_END, eventObj); + utils.reset(); + } + var eventType = rotation > 0 ? smrEventList.ROTATION_RIGHT : smrEventList.ROTATION_LEFT; + engine.trigger(el, eventType, eventObj); + engine.trigger(el, smrEventList.ROTATION, eventObj); + } + }, + swipe: function(ev) { + var el = ev.target; + if (!__touchStart || !pos.move || utils.getFingers(ev) > 1) { + return; + } + + var now = Date.now(); + var touchTime = now - startTime; + var distance = utils.getDistance(pos.start[0], pos.move[0]); + var position = { + x: pos.move[0].x - __offset.left, + y: pos.move[0].y - __offset.top + }; + var angle = utils.getAngle(pos.start[0], pos.move[0]); + var direction = utils.getDirectionFromAngle(angle); + var touchSecond = touchTime / 1000; + var factor = ((10 - config.swipeFactor) * 10 * touchSecond * touchSecond); + var eventObj = { + type: smrEventList.SWIPE, + originEvent: ev, + position: position, + direction: direction, + distance: distance, + distanceX: pos.move[0].x - pos.start[0].x, + distanceY: pos.move[0].y - pos.start[0].y, + x: pos.move[0].x - pos.start[0].x, + y: pos.move[0].y - pos.start[0].y, + angle: angle, + duration: touchTime, + fingersCount: utils.getFingers(ev), + factor: factor + }; + if (config.swipe) { + var swipeTo = function() { + var elt = smrEventList; + switch (direction) { + case 'up': + engine.trigger(el, elt.SWIPE_UP, eventObj); + break; + case 'down': + engine.trigger(el, elt.SWIPE_DOWN, eventObj); + break; + case 'left': + engine.trigger(el, elt.SWIPE_LEFT, eventObj); + break; + case 'right': + engine.trigger(el, elt.SWIPE_RIGHT, eventObj); + break; + } + }; + + if (!startSwiping) { + eventObj.fingerStatus = eventObj.swipe = 'start'; + startSwiping = true; + engine.trigger(el, smrEventList.SWIPE_START, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'move'; + engine.trigger(el, smrEventList.SWIPING, eventObj); + + if (touchTime > config.swipeTime && touchTime < config.swipeTime + 50 && distance > config.swipeMinDistance) { + swipeTo(); + engine.trigger(el, smrEventList.SWIPE, eventObj, false); + } + } else if (utils.isTouchEnd(ev) || ev.type === 'mouseout') { + eventObj.fingerStatus = eventObj.swipe = 'end'; + engine.trigger(el, smrEventList.SWIPE_END, eventObj); + + if (config.swipeTime > touchTime && distance > config.swipeMinDistance) { + swipeTo(); + engine.trigger(el, smrEventList.SWIPE, eventObj, false); + } + } + } + + if (config.drag) { + if (!startDrag) { + eventObj.fingerStatus = eventObj.swipe = 'start'; + startDrag = true; + engine.trigger(el, smrEventList.DRAGSTART, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'move'; + engine.trigger(el, smrEventList.DRAG, eventObj); + } else if (utils.isTouchEnd(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'end'; + engine.trigger(el, smrEventList.DRAGEND, eventObj); + } + + } + }, + tap: function(ev) { + var el = ev.target; + if (config.tap) { + var now = Date.now(); + var touchTime = now - startTime; + var distance = utils.getDistance(pos.start[0], pos.move ? pos.move[0] : pos.start[0]); + + clearTimeout(__holdTimer); + var isDoubleTap = (function() { + if (__prev_tapped_pos && config.doubleTap && (startTime - __prev_tapped_end_time) < config.maxDoubleTapInterval) { + var doubleDis = utils.getDistance(__prev_tapped_pos, pos.start[0]); + if (doubleDis < 16) return true; + } + return false; + })(); + + if (isDoubleTap) { + clearTimeout(__tapTimer); + engine.trigger(el, smrEventList.DOUBLE_TAP, { + type: smrEventList.DOUBLE_TAP, + originEvent: ev, + position: pos.start[0] + }); + return; + } + + if (config.tapMaxDistance < distance) return; + + if (config.holdTime > touchTime && utils.getFingers(ev) <= 1) { + __tapped = true; + __prev_tapped_end_time = now; + __prev_tapped_pos = pos.start[0]; + __tapTimer = setTimeout(function() { + engine.trigger(el, smrEventList.TAP, { + type: smrEventList.TAP, + originEvent: ev, + fingersCount: utils.getFingers(ev), + position: __prev_tapped_pos + }); + }, + config.tapTime); + } + } + }, + hold: function(ev) { + var el = ev.target; + if (config.hold) { + clearTimeout(__holdTimer); + + __holdTimer = setTimeout(function() { + if (!pos.start) return; + var distance = utils.getDistance(pos.start[0], pos.move ? pos.move[0] : pos.start[0]); + if (config.tapMaxDistance < distance) return; + + if (!__tapped) { + engine.trigger(el, "hold", { + type: 'hold', + originEvent: ev, + fingersCount: utils.getFingers(ev), + position: pos.start[0] + }); + } + }, + config.holdTime); + } + } +}; + +var handlerOriginEvent = function(ev) { + + var el = ev.target; + switch (ev.type) { + case 'touchstart': + case 'mousedown': + __rotation_single_start = []; + __touchStart = true; + if (!pos.start || pos.start.length < 2) { + pos.start = utils.getPosOfEvent(ev); + } + if (utils.getFingers(ev) >= 2) { + __initial_angle = parseInt(utils.getAngle180(pos.start[0], pos.start[1]), 10); + } + + startTime = Date.now(); + startEvent = ev; + __offset = {}; + + var box = el.getBoundingClientRect(); + var docEl = document.documentElement; + __offset = { + top: box.top + (window.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0), + left: box.left + (window.pageXOffset || docEl.scrollLeft) - (docEl.clientLeft || 0) + }; + + gestures.hold(ev); + break; + case 'touchmove': + case 'mousemove': + if (!__touchStart || !pos.start) return; + pos.move = utils.getPosOfEvent(ev); + if (utils.getFingers(ev) >= 2) { + gestures.pinch(ev); + } else if (__rotation_single_finger) { + gestures.rotateSingleFinger(ev); + } else { + gestures.swipe(ev); + } + break; + case 'touchend': + case 'touchcancel': + case 'mouseup': + case 'mouseout': + if (!__touchStart) return; + endEvent = ev; + + if (startPinch) { + gestures.pinch(ev); + } else if (__rotation_single_finger) { + gestures.rotateSingleFinger(ev); + } else if (startSwiping) { + gestures.swipe(ev); + } else { + gestures.tap(ev); + } + + utils.reset(); + __initial_angle = 0; + __rotation = 0; + if (ev.touches && ev.touches.length === 1) { + __touchStart = true; + __rotation_single_finger = true; + } + break; + } +}; + +var _on = function() { + + var evts, handler, evtMap, sel, args = arguments; + if (args.length < 2 || args > 4) { + return console.error("unexpected arguments!"); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.slice.call(els) : [els]; + //事件绑定 + if (args.length === 3 && utils.getType(args[1]) === 'string') { + evts = args[1].split(" "); + handler = args[2]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, handler); + }); + }); + return; + } + + function evtMapDelegate(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.delegate(el, evt, sel, evtMap[evt]); + }); + } + //mapEvent delegate + if (args.length === 3 && utils.getType(args[1]) === 'object') { + evtMap = args[1]; + sel = args[2]; + for (var evt1 in evtMap) { + evtMapDelegate(evt1); + } + return; + } + + function evtMapBind(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, evtMap[evt]); + }); + } + + //mapEvent bind + if (args.length === 2 && utils.getType(args[1]) === 'object') { + evtMap = args[1]; + for (var evt2 in evtMap) { + evtMapBind(evt2); + } + return; + } + + //兼容factor config + if (args.length === 4 && utils.getType(args[2]) === "object") { + evts = args[1].split(" "); + handler = args[3]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, handler); + }); + }); + return; + } + + //事件代理 + if (args.length === 4) { + var el = els[0]; + evts = args[1].split(" "); + sel = args[2]; + handler = args[3]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.delegate(el, evt, sel, handler); + }); + return; + } +}; + +var _off = function() { + var evts, handler; + var args = arguments; + if (args.length < 1 || args.length > 4) { + return console.error("unexpected arguments!"); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.slice.call(els) : [els]; + + if (args.length === 1 || args.length === 2) { + els.forEach(function(el) { + evts = args[1] ? args[1].split(" ") : Object.keys(el.listeners); + if (evts.length) { + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.unbind(el, evt); + engine.undelegate(el, evt); + }); + } + }); + return; + } + + if (args.length === 3 && utils.getType(args[2]) === 'function') { + handler = args[2]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.unbind(el, evt, handler); + }); + }); + return; + } + + if (args.length === 3 && utils.getType(args[2]) === 'string') { + var sel = args[2]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.undelegate(el, evt, sel); + }); + }); + return; + } + + if (args.length === 4) { + handler = args[3]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.undelegate(el, evt, sel, handler); + }); + }); + return; + } +}; + +var _dispatch = function(el, evt, detail) { + var args = arguments; + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.call(els) : [els]; + + els.forEach(function(el) { + engine.trigger(el, evt, detail); + }); +}; + + //init gesture + function init() { + + var mouseEvents = 'mouseup mousedown mousemove mouseout', + touchEvents = 'touchstart touchmove touchend touchcancel'; + var bindingEvents = utils.hasTouch ? touchEvents : mouseEvents; + + bindingEvents.split(" ").forEach(function(evt) { + document.addEventListener(evt, handlerOriginEvent, false); + }); + } + + init(); + + var exports = {}; + + exports.on = exports.bind = exports.live = _on; + exports.off = exports.unbind = exports.die = _off; + exports.config = config; + exports.trigger = _dispatch; + + return exports; +})); + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + var jsonpID = 0, + document = window.document, + key, + name, + rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, + scriptTypeRE = /^(?:text|application)\/javascript/i, + xmlTypeRE = /^(?:text|application)\/xml/i, + jsonType = 'application/json', + htmlType = 'text/html', + blankRE = /^\s*$/, + originAnchor = document.createElement('a') + + originAnchor.href = window.location.href + + // trigger a custom event and return false if it was cancelled + function triggerAndReturn(context, eventName, data) { + var event = $.Event(eventName) + $(context).trigger(event, data) + return !event.isDefaultPrevented() + } + + // trigger an Ajax "global" event + function triggerGlobal(settings, context, eventName, data) { + if (settings.global) return triggerAndReturn(context || document, eventName, data) + } + + // Number of active Ajax requests + $.active = 0 + + function ajaxStart(settings) { + if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') + } + function ajaxStop(settings) { + if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') + } + + // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable + function ajaxBeforeSend(xhr, settings) { + var context = settings.context + if (settings.beforeSend.call(context, xhr, settings) === false || + triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) + return false + + triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) + } + function ajaxSuccess(data, xhr, settings, deferred) { + var context = settings.context, status = 'success' + settings.success.call(context, data, status, xhr) + if (deferred) deferred.resolveWith(context, [data, status, xhr]) + triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) + ajaxComplete(status, xhr, settings) + } + // type: "timeout", "error", "abort", "parsererror" + function ajaxError(error, type, xhr, settings, deferred) { + var context = settings.context + settings.error.call(context, xhr, type, error) + if (deferred) deferred.rejectWith(context, [xhr, type, error]) + triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type]) + ajaxComplete(type, xhr, settings) + } + // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" + function ajaxComplete(status, xhr, settings) { + var context = settings.context + settings.complete.call(context, xhr, status) + triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) + ajaxStop(settings) + } + + // Empty function, used as default callback + function empty() {} + + $.ajaxJSONP = function(options, deferred){ + if (!('type' in options)) return $.ajax(options) + + var _callbackName = options.jsonpCallback, + callbackName = ($.isFunction(_callbackName) ? + _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), + script = document.createElement('script'), + originalCallback = window[callbackName], + responseData, + abort = function(errorType) { + $(script).triggerHandler('error', errorType || 'abort') + }, + xhr = { abort: abort }, abortTimeout + + if (deferred) deferred.promise(xhr) + + $(script).on('load error', function(e, errorType){ + clearTimeout(abortTimeout) + $(script).off().remove() + + if (e.type == 'error' || !responseData) { + ajaxError(null, errorType || 'error', xhr, options, deferred) + } else { + ajaxSuccess(responseData[0], xhr, options, deferred) + } + + window[callbackName] = originalCallback + if (responseData && $.isFunction(originalCallback)) + originalCallback(responseData[0]) + + originalCallback = responseData = undefined + }) + + if (ajaxBeforeSend(xhr, options) === false) { + abort('abort') + return xhr + } + + window[callbackName] = function(){ + responseData = arguments + } + + script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName) + document.head.appendChild(script) + + if (options.timeout > 0) abortTimeout = setTimeout(function(){ + abort('timeout') + }, options.timeout) + + return xhr + } + + $.ajaxSettings = { + // Default type of request + type: 'GET', + // Callback that is executed before request + beforeSend: empty, + // Callback that is executed if the request succeeds + success: empty, + // Callback that is executed the the server drops error + error: empty, + // Callback that is executed on request complete (both: error and success) + complete: empty, + // The context for the callbacks + context: null, + // Whether to trigger "global" Ajax events + global: true, + // Transport + xhr: function () { + return new window.XMLHttpRequest() + }, + // MIME types mapping + // IIS returns Javascript as "application/x-javascript" + accepts: { + script: 'text/javascript, application/javascript, application/x-javascript', + json: jsonType, + xml: 'application/xml, text/xml', + html: htmlType, + text: 'text/plain' + }, + // Whether the request is to another domain + crossDomain: false, + // Default timeout + timeout: 0, + // Whether data should be serialized to string + processData: true, + // Whether the browser should be allowed to cache GET responses + cache: true + } + + function mimeToDataType(mime) { + if (mime) mime = mime.split(';', 2)[0] + return mime && ( mime == htmlType ? 'html' : + mime == jsonType ? 'json' : + scriptTypeRE.test(mime) ? 'script' : + xmlTypeRE.test(mime) && 'xml' ) || 'text' + } + + function appendQuery(url, query) { + if (query == '') return url + return (url + '&' + query).replace(/[&?]{1,2}/, '?') + } + + // serialize payload and append it to the URL for GET requests + function serializeData(options) { + if (options.processData && options.data && $.type(options.data) != "string") + options.data = $.param(options.data, options.traditional) + if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) + options.url = appendQuery(options.url, options.data), options.data = undefined + } + + $.ajax = function(options){ + var settings = $.extend({}, options || {}), + deferred = $.Deferred && $.Deferred(), + urlAnchor, hashIndex + for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] + + ajaxStart(settings) + + if (!settings.crossDomain) { + urlAnchor = document.createElement('a') + urlAnchor.href = settings.url + // cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049 + urlAnchor.href = urlAnchor.href + settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host) + } + + if (!settings.url) settings.url = window.location.toString() + if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex) + serializeData(settings) + + var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) + if (hasPlaceholder) dataType = 'jsonp' + + if (settings.cache === false || ( + (!options || options.cache !== true) && + ('script' == dataType || 'jsonp' == dataType) + )) + settings.url = appendQuery(settings.url, '_=' + Date.now()) + + if ('jsonp' == dataType) { + if (!hasPlaceholder) + settings.url = appendQuery(settings.url, + settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?') + return $.ajaxJSONP(settings, deferred) + } + + var mime = settings.accepts[dataType], + headers = { }, + setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, + protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, + xhr = settings.xhr(), + nativeSetHeader = xhr.setRequestHeader, + abortTimeout + + if (deferred) deferred.promise(xhr) + + if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') + setHeader('Accept', mime || '*/*') + if (mime = settings.mimeType || mime) { + if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] + xhr.overrideMimeType && xhr.overrideMimeType(mime) + } + if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) + setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') + + if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) + xhr.setRequestHeader = setHeader + + xhr.onreadystatechange = function(){ + if (xhr.readyState == 4) { + xhr.onreadystatechange = empty + clearTimeout(abortTimeout) + var result, error = false + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { + dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')) + result = xhr.responseText + + try { + // http://perfectionkills.com/global-eval-what-are-the-options/ + if (dataType == 'script') (1,eval)(result) + else if (dataType == 'xml') result = xhr.responseXML + else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) + } catch (e) { error = e } + + if (error) ajaxError(error, 'parsererror', xhr, settings, deferred) + else ajaxSuccess(result, xhr, settings, deferred) + } else { + ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) + } + } + } + + if (ajaxBeforeSend(xhr, settings) === false) { + xhr.abort() + ajaxError(null, 'abort', xhr, settings, deferred) + return xhr + } + + if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name] + + var async = 'async' in settings ? settings.async : true + xhr.open(settings.type, settings.url, async, settings.username, settings.password) + + for (name in headers) nativeSetHeader.apply(xhr, headers[name]) + + if (settings.timeout > 0) abortTimeout = setTimeout(function(){ + xhr.onreadystatechange = empty + xhr.abort() + ajaxError(null, 'timeout', xhr, settings, deferred) + }, settings.timeout) + + // avoid sending empty string (#319) + xhr.send(settings.data ? settings.data : null) + return xhr + } + + // handle optional data/success arguments + function parseArguments(url, data, success, dataType) { + if ($.isFunction(data)) dataType = success, success = data, data = undefined + if (!$.isFunction(success)) dataType = success, success = undefined + return { + url: url + , data: data + , success: success + , dataType: dataType + } + } + + $.get = function(/* url, data, success, dataType */){ + return $.ajax(parseArguments.apply(null, arguments)) + } + + $.post = function(/* url, data, success, dataType */){ + var options = parseArguments.apply(null, arguments) + options.type = 'POST' + return $.ajax(options) + } + + $.getJSON = function(/* url, data, success */){ + var options = parseArguments.apply(null, arguments) + options.dataType = 'json' + return $.ajax(options) + } + + $.fn.load = function(url, data, success){ + if (!this.length) return this + var self = this, parts = url.split(/\s/), selector, + options = parseArguments(url, data, success), + callback = options.success + if (parts.length > 1) options.url = parts[0], selector = parts[1] + options.success = function(response){ + self.html(selector ? + $('<div>').html(response.replace(rscript, "")).find(selector) + : response) + callback && callback.apply(self, arguments) + } + $.ajax(options) + return this + } + + var escape = encodeURIComponent + + function serialize(params, obj, traditional, scope){ + var type, array = $.isArray(obj), hash = $.isPlainObject(obj) + $.each(obj, function(key, value) { + type = $.type(value) + if (scope) key = traditional ? scope : + scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']' + // handle data in serializeArray() format + if (!scope && array) params.add(value.name, value.value) + // recurse into nested objects + else if (type == "array" || (!traditional && type == "object")) + serialize(params, value, traditional, key) + else params.add(key, value) + }) + } + + $.param = function(obj, traditional){ + var params = [] + params.add = function(key, value) { + if ($.isFunction(value)) value = value() + if (value == null) value = "" + this.push(escape(key) + '=' + escape(value)) + } + serialize(params, obj, traditional) + return params.join('&').replace(/%20/g, '+') + } +})(Zepto) + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function(){ + // getComputedStyle shouldn't freak out when called + // without a valid element as argument + try { + getComputedStyle(undefined) + } catch(e) { + var nativeGetComputedStyle = getComputedStyle; + window.getComputedStyle = function(element){ + try { + return nativeGetComputedStyle(element) + } catch(e) { + return null + } + } + } +})() + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + $.fn.serializeArray = function() { + var name, type, result = [], + add = function(value) { + if (value.forEach) return value.forEach(add) + result.push({ name: name, value: value }) + } + if (this[0]) $.each(this[0].elements, function(_, field){ + type = field.type, name = field.name + if (name && field.nodeName.toLowerCase() != 'fieldset' && + !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && + ((type != 'radio' && type != 'checkbox') || field.checked)) + add($(field).val()) + }) + return result + } + + $.fn.serialize = function(){ + var result = [] + this.serializeArray().forEach(function(elm){ + result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) + }) + return result.join('&') + } + + $.fn.submit = function(callback) { + if (0 in arguments) this.bind('submit', callback) + else if (this.length) { + var event = $.Event('submit') + this.eq(0).trigger(event) + if (!event.isDefaultPrevented()) this.get(0).submit() + } + return this + } + +})(Zepto) diff --git a/hyhproject/mobile2/view/default/goods_category.html b/hyhproject/mobile2/view/default/goods_category.html new file mode 100755 index 0000000..616392e --- /dev/null +++ b/hyhproject/mobile2/view/default/goods_category.html @@ -0,0 +1,70 @@ +{extend name="default/base" /} +{block name="title"}商品分类 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/goods_category.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('goods',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + </div> + </header> +{/block} +{block name="main"} + <section class="ui-container"> + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="list" key="k" id="go"} + {if($go['catId']!=389)} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{php}echo str_replace('、', '<br/>', $go['catName']);{/php}</li> + {/if} + {/volist} + </ul> + </div> + {volist name="list" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + {if(isset($go['childList']))} + <ul class="wst-gc-br"><li class="brand"> + {wst:brand cat="$go['catId']" id="bvo" num='16' cache='86400'} + <a href="javascript:void(0)" onclick="javascript:getBrandGoodsList({$bvo['brandId']});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($bvo['brandImg'],2)}"></a> + {/wst:brand} + <div class="wst-clear"></div> + </li></ul> + {volist name="go['childList']" id="go1"} + <ul> + <div class="wst-gc-ads"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go1['catId']});"><div class="title">{$go1.catName}</div></a> + </div> + <li> + <div class="wst-goodscat"> + {volist name="go1['childList']" id="go2"} + <span> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go2['catId']});" > + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{$go2['catImg']}" class="goods-cat-img" title="{$go2.catName}"/> + <p class="ui-nowrap-flex">{$go2.catName}</p> + </a> + </span> + {/volist} + </div> + <div class="wst-clear"></div> + </li> + <div class="wst-clear"></div> + </ul> + {/volist} + {/if} + </div> + {/volist} + <div class="wst-clear"></div> + </section> +{/block} +{block name="include"} +{include file="default/goods_search" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/goods_category.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goods_detail.html b/hyhproject/mobile2/view/default/goods_detail.html new file mode 100755 index 0000000..d0e77cf --- /dev/null +++ b/hyhproject/mobile2/view/default/goods_detail.html @@ -0,0 +1,439 @@ +{extend name="default/base" /} +{block name="title"}商品详情 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/goods_detail.css?v={$v}"> +<link rel="stylesheet" href="__MOBILE__/js/share/nativeShare.css?v={$v}"> +{/block} +{block name="header"} + {php}$cartNum = WSTCartNum();{/php} + <header class="ui-header ui-header-positive wst-header" id="goods-header" style="display:none;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <ul class="ui-tab-nav"> + <li class="switch active" onclick="javascript:pageSwitch(this,1);">商品</li> + <li class="switch" onclick="javascript:pageSwitch(this,2);">详情</li> + <li class="switch" id="appr" onclick="javascript:pageSwitch(this,3);">评价</li> + </ul> + <a href="{:url('mobile/carts/index')}"><span class="cart" id="cartNum">{if($cartNum>0)}<span>{php} echo $cartNum;{/php}</span>{/if}</span></a> + <span class="share" onclick="javascript:shareShow();"></span> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="{$info['goodsType']}" id="goodsType" autocomplete="off"> + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col-3 wst-go-icon"> + <div class="ui-row-flex"> + <div class="ui-col ui-col" style="border-right: 1px solid rgba(0,0,0,.05);"> + {if($info['shop']['shopQQ'])!=''} + <div class="icon"><a href="http://wpa.qq.com/msgrd?v=3&uin={$info['shop']['shopQQ']}&site=qq&menu=yes"><span class="img qq"></span><span class="word">客服</span></a></div> + {else /} + <div class="icon"><a href="tel:{$info['shop']['shopTel']}"><span class="img tel"></span><span class="word">客服</span></a></div> + {/if} + </div> + <div class="ui-col ui-col" style="border-right: 1px solid rgba(0,0,0,.05);"> + <div class="icon"><a href="{:url('mobile/shops/home',['shopId'=>$info['shop']['shopId']])}"><span class="img shop"></span><span class="word">店铺</span></a></div> + </div> + <div class="ui-col ui-col"> + {if($info['favGood']==0)} + <button class="but" type="button"><span class="img imgfollow nofollow" onclick="javascript:WST.favorites({$info['goodsId']},0);"></span><span style="bottom: 5px;" class="word">关注</span></button> + {else} + <button class="but" type="button"><span class="img imgfollow follow" onclick="javascript:WST.cancelFavorite({$info['favGood']},0);"></span><span style="bottom: 5px;" class="word">关注</span></button> + {/if} + </div> + </div> + </div> + <div class="ui-col ui-col-4 wst-goods_buy"> + {if($info['goodsType']==1)} + <button class="wst-goods_buym" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {else} + <button class="wst-goods_buyl" type="button" onclick="javascript:cartShow(0);" {if($info['goodsId']==0)}disabled{/if}>加入购物车</button> + <button class="wst-goods_buyr" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {/if} + </div> + </div> + </footer> +{/block} +{block name="main"} + +{if($info['goodsId']>0)} + {/* 商品 */} + <div class="wst-go-more" id="arrow" style="display: none;"><i class="arrow"></i> + <ul class="ui-row ui-list-active more"> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/index/index')}"><i class="home"></i><p>首页</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/goodscats/index')}"><i class="category"></i><p>分类</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/carts/index')}"><i class="cart"></i><p>购物车</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('mobile/favorites/goods')}"><i class="follow"></i><p>关注</p></a></div></li> + <li class="ui-col"><div class="column"><a href="{:url('mobile/users/index')}"><i class="user"></i><p>我的</p></a></div></li> + </ul> + </div> + <div class="wst-ca-layer" id="layer" onclick="javascript:inMore();"></div> + <section class="ui-container" id="goods1" style="border-top: 0px solid transparent;"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="info['gallery']" id="ga"} + <div class="swiper-slide" style="width:100%;"> + <div class="wst-go-img"><a><img src="__IMGURL__/{:WSTImg($ga,2)}"></a></div> + </div> + {/volist} + </div> + {if(count($info['gallery'])>1)}<div class="swiper-pagination"></div>{/if} + <div class="wst-go-return" onclick="history.back()"><i class="ui-icon-prev"></i></div> + <div class="wst-go-mores" onclick="javascript:inMore()"><i>···</i></div> + </div> + <div class="wst-go-name">{$info['goodsName']}</div> + <div class="ui-row-flex wst-go-price"> + <div class="ui-col ui-col-2"> + <div class="price lxy_price">{if $info['is_seckilling']==1}秒杀价{/if}<i>¥ </i>{$info['shopPrice']}{if $info['is_seckilling']==1}<span style="color: #000;font-size: 12px;">(秒杀商品限购4件)</span>{/if}</div> + {if $info['is_seckilling']!=1}<div class="price lxy_price"><p>木吉抵扣价格</p><i>¥ </i>{$info['shopPrice']*0.8}</div>{/if} + <div class="ui-row-flex info"> + <div class="ui-col ui-col" style="text-align: left;">快递: {if $info['isFreeShipping']==1}免运费{else}{php}echo sprintf("%.2f", $info['shop']['freight']);{/php}{/if}</div> + <div class="ui-col ui-col" style="text-align: center;">销量: {$info['saleNum']}</div> + <div class="ui-col ui-col" style="text-align: right;">{$info['shop']['areas']['areaName1']}{$info['shop']['areas']['areaName2']}</div> + </div> + </div> + {:hook('mobileDocumentGoodsDetailTips',["goods"=>$info])} + </div> + <ul class="ui-list ui-list-text wst-go-ul ui-list-active"> + {if WSTConf('CONF.isOrderScore')==1} + <li> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">积分</span><span class="line">|</span>购买即可获得{php}echo intval($info['shopPrice']*(float)WSTConf('CONF.moneyToScore'));{/php}积分</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + <li id='j-promotion' style='display:none;'> + <div class="ui-list-info"> + <h5 class="ui-nowrap"> + <div style="float: left;"> + <span class="word">促销</span> + <span class="line">|</span> + </div> + {:hook('mobileDocumentGoodsPromotionDetail',['goods'=>$info])} + </h5> + </div> + </li> + {/* 优惠券钩子 */} + {:hook('mobileDocumentGoodsPropDetail')} + + + <li style="display: none;"> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">优惠</span><span class="line">|</span></h5> + </div> + <span class="icon">···</span> + </li> + {if !empty($info['attrs']) } + <li onclick="javascript:dataShow();"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">产品参数</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + + <li onclick="javascript:pageSwitch($('#appr'),3);"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">商品评价( <span class="red">{$info['appraiseNum']}</span> )</h5> + </div> + <span class="icon">···</span> + </li> + </ul> + <ul class="ui-list ui-list-one ui-list-link wst-go-shop"> + <div class="info"> + <div class="img"><a><img src="__IMGURL__/{:WSTImg($info['shop']['shopImg'],3)}" title="{$info['shop']['shopName']}"></a></div> + <div class="name"><p class="ui-nowrap-flex name1">{$info['shop']['shopName']}</p><p class="ui-nowrap-flex name2"><span>主营: {$info['shop']['cat']}</span></p></div> + <div class="wst-clear"></div> + </div> + <div class="ui-row-flex score"> + <div class="ui-col ui-col" style="text-align:left;">商品评分: <span class="red">{$info['shop']['goodsScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col" style="text-align:center;">时效评分: <span class="red">{$info['shop']['timeScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col" style="text-align:right;">服务评分: <span class="red">{$info['shop']['serviceScore']}</span></div> + </div> + <div class="ui-row-flex button"> + <div class="ui-col ui-col"><a href="{:url('mobile/shops/shopGoodsList',['shopId'=>$info['shop']['shopId']])}" class="goods">全部商品</a></div> + <div class="ui-col ui-col"><a href="{:url('mobile/shops/home',['shopId'=>$info['shop']['shopId']])}" class="shop">进入店铺</a></div> + </div> + </ul> + <div class="title gc-title" onclick="goConsult()"> + <span class='gc-tit-icon'></span> + <span class='gc-tit-icon2'></span> + 购买咨询 + </div> + <div class="gc-title-list"> + {if($info['consult']['consultContent'])} + <li> + <div class="question-box cf"> + <span class="question-pic"></span> + <div class="question-content"> + <span>{$info['consult']['consultContent']}</span> + </div> + <div class="wst-clear"></div> + </div> + {if($info['consult']['reply'])} + <div class="question-box cf"> + <span class="question-pic answer-pic"></span> + <div class="question-content answer-content"> + <span>{$info['consult']['reply']}</span> + </div> + <div class="wst-clear"></div> + </div> + {/if} + </li> + {else} + <p class="prompt">暂无商品咨询~</p> + {/if} + </div> + + <div class="wst-shl-ads"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' cat="$info['shop']['catId']" num='6'} + <div class="wst-go-goods" onclick="javascript:WST.intoGoods({$vo['goodsId']});"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$vo['goodsId']});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo['goodsImg'],3)}" title="{$vo['goodsName']}"></a> + </div> + <p class="name ui-nowrap-multi">{$vo['goodsName']}</p> + <div class="info"><span class="ui-nowrap-flex price">¥ {$vo['shopPrice']}</span></div> + </div> + {/wst:goods} + <div class="wst-clear"></div> + </div> + <div class="wst-go-top" style="display: none;">上拉查看图文详情</div> + </section> + {/* 详情 */} + <section class="ui-container" id="goods2" style="display: none;"> + <div class="wst-go-details">{$info['goodsDesc']}</div> + </section> + {/* 评价 */} + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="" id="evaluateType" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container" id="goods3" style="display: none;"> + <div class="ui-row-flex wst-ev-term"> + <div class="ui-col ui-col active" onclick="javascript:evaluateSwitch(this,'');"><p>全部</p><p class="number">{$info['appraises']['sum']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'best');"><p>好评</p><p class="number">{$info['appraises']['best']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'good');"><p>中评</p><p class="number">{$info['appraises']['good']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'bad');"><p>差评</p><p class="number">{$info['appraises']['bad']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'pic');"><p>晒图</p><p class="number">{$info['appraises']['pic']}</p></div> + </div> + <div id="evaluate-list" style="margin-top: 10px;"></div> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} + <div class="ui-whitespace wst-go-evaluate"> + <div class="info"> + <p> + {{# if(d[i].userPhoto){ }} + <img src="__IMGURL__/{{d[i].userPhoto }}" class="portrait"> + {{# }else{ }} + <img src="__IMGURL__/{:WSTConf('CONF.userLogo')}" class="portrait"> + {{# } }} + <span class="name">{{ d[i].loginName }}</span> + {{# if(d[i].userTotalScore){ }} + <img src="__IMGURL__/{{ d[i].userTotalScore }}" class="ranks"> + {{# } }} + <span class="time">{{ d[i].createTime }}</span> + <div class="wst-clear"></div> + </p> + </div> + <div class="content"> + <p> + {{# var score = (d[i].goodsScore+d[i].serviceScore+d[i].timeScore)/3; }} + {{# for(var j=1; j<6; j++){ }} + {{# if(j <= score.toFixed(0)){ }} + <i class="bright"></i> + {{# }else{ }} + <i class="dark"></i> + {{# } }} + {{# } }} + </p> + <p class="content2">{{ d[i].content }}</p> + {{# if(d[i].images){ }} + {{# var img = d[i].images.split(','); }} + {{# for(var m=0; m<img.length; m++){ }} + <img src="__IMGURL__/{{ img[m] }}"> + {{# } }} + {{# } }} + <p class="word">{{ d[i].goodsSpecNames }}</p> + <div class="wst-clear"></div> + </div> + {{# if(d[i].shopReply){ }} + <div class="reply"><p>卖家回复:{{ d[i].shopReply }}</p></div> + {{# } }} + </div> +{{# } }} +{{# }else{ }} + <div class="wst-prompt-icon"><img src="__MOBILE__/img/nothing-evaluate.png"></div> + <div class="wst-prompt-info"> + <p>对不起,没有相关评论。</p> + </div> +{{# } }} +</script> +{else} + <div class="wst-prompt-icon"><img src="__MOBILE__/img/nothing-goods.png"></div> + <div class="wst-prompt-info"> + <p>对不起,没有找到商品。</p> + </div> +{/if} +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 参数框 */} +{if !empty($info['attrs']) } +<div class="wst-fr-box" id="frame"> + <div class="title"><span>产品参数</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {volist name="$info['attrs']" id="at"} + {$at['attrName']}:{$at['attrVal']}<br/> + {/volist} + </div> + <div class="determine"><button class="button" onclick="javascript:dataHide();">确定</button></div> +</div> +{/if} + +{/*分享 */} +<script type='text/javascript' src='__MOBILE__/js/share/nativeShare.js?v={$v}'></script> +<script> + var config = { + url: "{:url('mobile/goods/detail','goodsId='.$info['goodsId'].'&shareUserId='.base64_encode(session('WST_USER.userId')),true,true)}", + title:"{$info['goodsName']}", + desc:"{$info['goodsName']}", + img:"__IMGURL__/{$info['goodsImg']}" + }; + + var jiathis_config = { + url: "{:url('mobile/goods/detail','goodsId='.$info['goodsId'].'&shareUserId='.base64_encode(session('WST_USER.userId')),true,true)}", + title:"{$info['goodsName']}", + summary:"{$info['goodsName']}", + imageUrl:"__IMGURL__/{$info['goodsImg']}", + slide:{ + divid:'jiathis_main', + pos:'left' + } + }; +</script> +<div class="wst-cart-box" id="frame-share" style="padding-top:10px;"> + <div class="content" id="nativeShare" style="padding-bottom:50px;"> + <!-- JiaThis Button BEGIN --> + <div class="jiathis_style_32x32"> + <div class="ui-form-item ui-form-item-show" style="font-size:0.15rem;"> + <a class="jiathis_button_qzone" onclick="jiathis_mh5.sendTo('qzone');" title="分享到QQ空间"><span class="jiathis_txt jtico jtico_qzone" style="margin-top:5px;"></span><span>分享到QQ空间</span></a> + </div> + <div class="ui-form-item ui-form-item-show" style="font-size:0.15rem;"> + <a class="jiathis_button_tsina" onclick="jiathis_mh5.sendTo('tsina');" title="分享到新浪微博"><span class="jiathis_txt jtico jtico_tsina" style="margin-top:5px;"></span><span>分享到新浪微博</span></a> + </div> + <div class="ui-form-item ui-form-item-show" style="font-size:0.15rem;"> + <a class="jiathis_button_tqq" onclick="jiathis_mh5.sendTo('tqq');" title="分享到腾讯微博"><span class="jiathis_txt jtico jtico_tqq" style="margin-top:5px;"></span><span>分享到腾讯微博</span></a> + </div> + <div class="ui-form-item ui-form-item-show" style="font-size:0.15rem;"> + <a class="jiathis_button_renren" onclick="jiathis_mh5.sendTo('renren');" title="分享到人人网"><span class="jiathis_txt jtico jtico_renren" style="margin-top:5px;"></span><span>分享到人人网</span></a> + </div> + </div> + </div> + + <div class="determine"><button class="button" onclick="javascript:shareHide();">取消</button></div> +</div> +{:hook('mobileDocumentGoodsDetail',['goods'=>$info,'getParams'=>input()])} + +{/*加入购物车框 */} +<div class="wst-cart-box" id="frame-cart"> + <div class="title"> + <div class="picture"><div class="img"><a href="javascript:void(0);"><img src="__IMGURL__/{:WSTImg($info['goodsImg'],3)}" title="{$info['goodsName']}"></a></div></div> + <i class="ui-icon-close-page" onclick="javascript:cartHide();"></i> + <p class="ui-nowrap-multi">{$info['goodsName']}</p> + <p class="ui-nowrap-flex price"><span id="j-shop-price">¥{$info['shopPrice']}</span></p> + <p class="ui-nowrap-flex price">惠宝抵扣价<span id="j-huibao-price">¥{$info['shopPrice']*0.8}</span></p> + <div class="wst-clear"></div> + </div> + <div class="standard" id="standard"> + {if!empty($info['spec'])} + {volist name="$info['spec']" id="sp"} + <div class="spec"> + <p>{$sp['name']}</p> + {volist name="sp['list']" id="sp2"} + {if $sp2['itemImg']!=''} + <img class="j-option img" data-val="{$sp2['itemId']}" src="__IMGURL__/{:WSTImg($sp2['itemImg'],3)}" title="{$sp2['itemName']}"> + {else} + <span class="j-option" data-val="{$sp2['itemId']}">{$sp2['itemName']}</span> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + {/volist} + {/if} + <div class="number"> + <p>数量</p> + <div class="stock">库存:<span id="goods-stock">0</span>{$info['goodsUnit']}</div> + <div class="wst-buy_l"> + <input class="wst-buy_l1" type="button" value="-" onclick='javascript:WST.changeIptNum(-1,"#buyNum")'><input id="buyNum" class="wst-buy_l2" data-min='1' data-max='' type="number" value="1" autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum")'><input class="wst-buy_l3" type="button" value="+" onclick='javascript:WST.changeIptNum(1,"#buyNum")'> + </div> + <div class="wst-clear"></div> + </div> + </div> + <div class="determine"><button class="button" onclick="javascript:addCart();">确定</button></div> +</div> +{/block} +{block name="js"} +<script> +var share_obj = new nativeShare('nativeShare',config); +var goodsInfo = { + id:{$info['goodsId']}, + isSpec:{$info['isSpec']}, + goodsStock:{$info['goodsStock']}, + marketPrice:{$info['marketPrice']}, + goodsPrice:{$info['shopPrice']}, + goodsHuibao:{$info['shopPrice']*0.8} + {if isset($info['saleSpec'])} + ,sku:{:json_encode($info['saleSpec'])} + {/if} +} + +//弹框 +function shareShow(){ + jQuery('#cover').attr("onclick","javascript:shareHide();").show(); + jQuery('#frame-share').animate({"bottom": 0}, 500); +} +function shareHide(){ + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + jQuery('#frame-share').animate({'bottom': '-'+cartHeight}, 500); + jQuery('#cover').hide(); +} +function goConsult(){ + location.href=WST.U('mobile/goodsconsult/index',{goodsId:goodsInfo.id}) +} + + var url = window.location.search; + + url = url.substring(7,url.length); + + localStorage.setItem('pName',url); + + var pName = localStorage.getItem('pName'); + + + + + + + + + + + +</script> +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/goods_detail.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goods_detail2.html b/hyhproject/mobile2/view/default/goods_detail2.html new file mode 100755 index 0000000..aaa5d9d --- /dev/null +++ b/hyhproject/mobile2/view/default/goods_detail2.html @@ -0,0 +1,347 @@ +{extend name="default/base" /} +{block name="title"}商品详情 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/goods_detail.css?v={$v}"> +<link rel="stylesheet" href="__MOBILE__/js/share/nativeShare.css?v={$v}"> +{/block} +{block name="header"} + {php}$cartNum = WSTCartNum();{/php} + <header class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i> + <ul class="ui-tab-nav"> + <li class="switch active" onclick="javascript:pageSwitch(this,1);">商品</li> + <li class="switch" onclick="javascript:pageSwitch(this,2);">详情</li> + <li class="switch" id="appr" onclick="javascript:pageSwitch(this,3);">评价</li> + </ul> + <a href="{:url('mobile/carts/index')}"><span class="cart" id="cartNum">{if($cartNum>0)}<span>{php} echo $cartNum;{/php}</span>{/if}</span></a> + <span class="share" onclick="javascript:shareShow();"></span> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="{$info['goodsType']}" id="goodsType" autocomplete="off"> + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col-3 wst-go-icon"> + <div class="icon"><a href="tel:{$info['shop']['shopTel']}"><span class="img tel"></span><span class="word">客服</span></a></div> + <div class="icon"><a href="{:url('mobile/shops/home',['shopId'=>$info['shop']['shopId']])}"><span class="img shop"></span><span class="word">店铺</span></a></div> + {if($info['favGood']==0)} + <button class="but" type="button"><span class="img imgfollow nofollow" onclick="javascript:WST.favorites({$info['goodsId']},0);"></span><span style="height:13px;" class="word">关注</span></button> + {else} + <button class="but" type="button"><span class="img imgfollow follow" onclick="javascript:WST.cancelFavorite({$info['favGood']},0);"></span><span style="height:13px;" class="word">关注</span></button> + {/if} + + </div> + <div class="ui-col ui-col-4 wst-goods_buy"> + {if($info['goodsType']==1)} + <button class="wst-goods_buym" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {else} + <button class="wst-goods_buyl" type="button" onclick="javascript:cartShow(0);" {if($info['goodsId']==0)}disabled{/if}>加入购物车</button> + <button class="wst-goods_buyr" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {/if} + </div> + </div> + </footer> +{/block} +{block name="main"} + +{if($info['goodsId']>0)} + {/* 商品 */} + <section class="ui-container" id="goods1"> + <div class="ui-slider" style="padding-top:100%;"> + <ul class="ui-slider-content" style="{if($info['imgcount']>0)}{$info['imgwidth']}{/if}"> + {volist name="info['gallery']" id="ga"} + <li><div class="wst-go-img j-imgAdaptg"><a><img src="__IMGURL__/{:WSTImg($ga,2)}"></a></div></li> + {/volist} + </ul> + </div> + <div class="ui-nowrap-multi ui-whitespace wst-go-name">{if $info['isFreeShipping']==1}<span class='wst-red'>【包邮】</span>{/if}{$info['goodsName']}</div> + <div class="ui-row-flex wst-go-price"> + <div class="ui-col ui-col-2"> + <p class="price">¥{$info['shopPrice']}<span class="market">¥{$info['marketPrice']}</span></p><p>成交数:{$info['saleNum']}</p> + </div> + {:hook('mobileDocumentGoodsDetailTips',["goods"=>$info])} + </div> + <ul class="ui-list ui-list-text wst-go-ul ui-list-active"> + {if WSTConf('CONF.isOrderScore')==1} + <li> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">惠宝</span><span class="line">|</span>购买即可获得{php}echo ceil($info['shopPrice'] * HuiScale());{/php}奖励</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + <li id='j-promotion' style='display:none;'> + <div class="ui-list-info"> + <h5 class="ui-nowrap"> + <div style="vertical-align: top;display:inline-block;"> + <span class="word">促销</span> + <span class="line">|</span> + </div> + {:hook('mobileDocumentGoodsPromotionDetail',['goods'=>$info])} + </h5> + </div> + </li> + {/* 优惠券钩子 */} + {:hook('mobileDocumentGoodsPropDetail')} + + + <li style="display: none;"> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">优惠</span><span class="line">|</span></h5> + </div> + <span class="icon">···</span> + </li> + {if !empty($info['attrs']) } + <li onclick="javascript:dataShow();"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">产品参数</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + + <li onclick="javascript:pageSwitch($('#appr'),3);"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">商品评价(<span class="red">{$info['appraiseNum']}</span>)</h5> + </div> + <span class="icon">···</span> + </li> + </ul> + <ul class="ui-list ui-list-one ui-list-link wst-go-shop"> + <li onclick="javascript:location.href='{:url('mobile/shops/home',['shopId'=>$info['shop']['shopId']])}';"> + <div class="ui-list-thumb"> + <span><img src="__IMGURL__/{:WSTImg($info['shop']['shopImg'],3)}" title="{$info['shop']['shopName']}"></span> + </div> + <div class="ui-list-info info"> + <p class="name">{$info['shop']['shopName']}</p><br/> + <p class="ui-nowrap-flex name2">主营:{$info['shop']['cat']}</p> + </div> + </li> + <div class="ui-whitespace"> + <div class="ui-row-flex score"> + <div class="ui-col ui-col">商品评分:<span class="red">{$info['shop']['goodsScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col">时效评分:<span class="red">{$info['shop']['timeScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col">服务评分:<span class="red">{$info['shop']['serviceScore']}</span></div> + </div> + </div> + </ul> + + <div class="title gc-title" onclick="goConsult()"> + <span class='gc-tit-icon'></span> + 购买咨询 + </div> + + <div class="wst-shl-ads"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' cat="$info['shop']['catId']" num='6'} + <div class="wst-go-goods" onclick="javascript:WST.intoGoods({$vo['goodsId']});"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$vo['goodsId']});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo['goodsImg'],3)}" title="{$vo['goodsName']}"></a> + </div> + <p class="name ui-nowrap-multi">{$vo['goodsName']}</p> + <div class="info"><span class="ui-nowrap-flex price">¥{$vo['shopPrice']}</span></div> + </div> + {/wst:goods} + <div class="wst-clear"></div> + </div> + <div class="wst-go-top" style="display: none;">上拉查看图文详情</div> + </section> + {/* 详情 */} + <section class="ui-container" id="goods2" style="display: none;"> + <div class="wst-go-details">{$info['goodsDesc']}</div> + </section> + {/* 评价 */} + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container" id="goods3" style="display: none;"> + <div id="evaluate-list"></div> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} + <div class="ui-whitespace wst-go-evaluate"> + <div class="info"> + <span class="name">{{ d[i].loginName }}</span> + {{# if(d[i].userTotalScore){ }} + <img src="__ROOT__/{{ d[i].userTotalScore }}"> + {{# } }} + {{# var score = (d[i].goodsScore+d[i].serviceScore+d[i].timeScore)/3; }} + {{# for(var j=1; j<6; j++){ }} + {{# if(j <= score.toFixed(0)){ }} + <i class="bright"></i> + {{# }else{ }} + <i class="dark"></i> + {{# } }} + {{# } }} + <span class="time">{{ d[i].createTime }}</span> + <div class="wst-clear"></div> + </div> + <div class="content"> + <p>{{ d[i].content }}</p> + {{# if(d[i].images){ }} + {{# var img = d[i].images.split(','); }} + {{# for(var m=0; m<img.length; m++){ }} + <img src="__ROOT__/{{ img[m] }}"> + {{# } }} + {{# } }} + <div class="wst-clear"></div> + <p class="word">{{ d[i].goodsSpecNames }}</p> + </div> + {{# if(d[i].shopReply){ }} + <div class="reply"><p>卖家回复:{{ d[i].shopReply }}</p></div> + {{# } }} + </div> +{{# } }} +{{# }else{ }} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>对不起,没有相关评论。</p> + </li> + </ul> +{{# } }} +</script> +{else} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>对不起,没有找到商品。</p> + </li> +</ul> +{/if} +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 参数框 */} +{if !empty($info['attrs']) } +<div class="wst-fr-box" id="frame"> + <div class="title"><span>产品参数</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {volist name="$info['attrs']" id="at"} + {$at['attrName']}:{$at['attrVal']}<br/> + {/volist} + </div> + <button class="button" onclick="javascript:dataHide();">确定</button> +</div> +{/if} + +{/*分享 */} +<script type='text/javascript' src='__MOBILE__/js/share/nativeShare.js?v={$v}'></script> +<script> + var config = { + url: "{:url('mobile/goods/detail','goodsId='.$info['goodsId'].'&shareUserId='.base64_encode(session('WST_USER.userId')),true,true)}", + title:"{$info['goodsName']}", + desc:"{$info['goodsName']}", + img:"{:WSTRoot()}/{$info['goodsImg']}" + }; + + var jiathis_config = { + url: "{:url('mobile/goods/detail','goodsId='.$info['goodsId'].'&shareUserId='.base64_encode(session('WST_USER.userId')),true,true)}", + title:"{$info['goodsName']}", + summary:"{$info['goodsName']}", + imageUrl:"{:WSTRoot()}/{$info['goodsImg']}", + slide:{ + divid:'jiathis_main', + pos:'left' + } + }; +</script> +<div class="wst-cart-box" id="frame-share" style="padding-top:10px;"> + <div class="content" id="nativeShare" style="padding-bottom:50px;"> + <!-- JiaThis Button BEGIN --> + <div class="jiathis_style_32x32"> + <div class="ui-form-item ui-form-item-show ui-border-b"> + <a class="jiathis_button_qzone" onclick="jiathis_mh5.sendTo('qzone');" title="分享到QQ空间"><span class="jiathis_txt jtico jtico_qzone" style="margin-top:5px;"></span><span>分享到QQ空间</span></a> + </div> + <div class="ui-form-item ui-form-item-show ui-border-b"> + <a class="jiathis_button_tsina" onclick="jiathis_mh5.sendTo('tsina');" title="分享到新浪微博"><span class="jiathis_txt jtico jtico_tsina" style="margin-top:5px;"></span><span>分享到新浪微博</span></a> + </div> + <div class="ui-form-item ui-form-item-show ui-border-b"> + <a class="jiathis_button_tqq" onclick="jiathis_mh5.sendTo('tqq');" title="分享到腾讯微博"><span class="jiathis_txt jtico jtico_tqq" style="margin-top:5px;"></span><span>分享到腾讯微博</span></a> + </div> + <div class="ui-form-item ui-form-item-show ui-border-b"> + <a class="jiathis_button_renren" onclick="jiathis_mh5.sendTo('renren');" title="分享到人人网"><span class="jiathis_txt jtico jtico_renren" style="margin-top:5px;"></span><span>分享到人人网</span></a> + </div> + </div> + </div> + + <button class="button" onclick="javascript:shareHide();">取消</button> +</div> +{:hook('mobileDocumentGoodsDetail',['goods'=>$info,'getParams'=>input()])} + +{/*加入购物车框 */} +<div class="wst-cart-box" id="frame-cart"> + <div class="title"> + <div class="picture"><div class="img"><a href="javascript:void(0);"><img src="__IMGURL__/{:WSTImg($info['goodsImg'],3)}" title="{$info['goodsName']}"></a></div></div> + <i class="ui-icon-close-page" onclick="javascript:cartHide();"></i> + <p class="ui-nowrap-multi">{$info['goodsName']}</p> + <p class="ui-nowrap-flex price"><span id="j-shop-price">¥{$info['shopPrice']}</span><span id="j-market-price" class="price2">¥{$info['marketPrice']}</span></p> + <div class="wst-clear"></div> + </div> + <div class="standard" id="standard"> + {if!empty($info['spec'])} + {volist name="$info['spec']" id="sp"} + <div class="spec"> + <p>{$sp['name']}</p> + {volist name="sp['list']" id="sp2"} + {if $sp2['itemImg']!=''} + <img class="j-option img" data-val="{$sp2['itemId']}" src="__IMGURL__/{:WSTImg($sp2['itemImg'],3)}" title="{$sp2['itemName']}"> + {else} + <span class="j-option" data-val="{$sp2['itemId']}">{$sp2['itemName']}</span> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + {/volist} + {/if} + <div class="number"> + <p>数量</p> + <div class="stock">库存:<span id="goods-stock">0</span>{$info['goodsUnit']}</div> + <div class="wst-buy_l"> + <input class="wst-buy_l1" type="button" value="-" onclick='javascript:WST.changeIptNum(-1,"#buyNum")'><input id="buyNum" class="wst-buy_l2" data-min='1' data-max='' type="number" value="1" autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum")'><input class="wst-buy_l3" type="button" value="+" onclick='javascript:WST.changeIptNum(1,"#buyNum")'> + </div> + <div class="wst-clear"></div> + </div> + </div> + <button class="button" onclick="javascript:addCart();">确定</button> +</div> +{/block} +{block name="js"} +<script> +var share_obj = new nativeShare('nativeShare',config); +var goodsInfo = { + id:{$info['goodsId']}, + isSpec:{$info['isSpec']}, + goodsStock:{$info['goodsStock']}, + marketPrice:{$info['marketPrice']}, + goodsPrice:{$info['shopPrice']} + {if isset($info['saleSpec'])} + ,sku:{:json_encode($info['saleSpec'])} + {/if} +} + +//弹框 +function shareShow(){ + jQuery('#cover').attr("onclick","javascript:shareHide();").show(); + jQuery('#frame-share').animate({"bottom": 0}, 500); +} +function shareHide(){ + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + jQuery('#frame-share').animate({'bottom': '-'+cartHeight}, 500); + jQuery('#cover').hide(); +} +function goConsult(){ + location.href=WST.U('mobile/goodsconsult/index',{goodsId:goodsInfo.id}) +} +</script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/goods_detail.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goods_list.html b/hyhproject/mobile2/view/default/goods_list.html new file mode 100755 index 0000000..89874b5 --- /dev/null +++ b/hyhproject/mobile2/view/default/goods_list.html @@ -0,0 +1,78 @@ +{extend name="default/base" /} +{block name="title"}商品列表 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/goods_list.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action="" class="input-form" onclick="javascript:WST.searchPage('goods',1);"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon" onclick="javascript:switchList(this);"></span> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$keyword}" id="keyword" autocomplete="off"> + <input type="hidden" name="" value="{$catId}" id="catId" autocomplete="off"> + <input type="hidden" name="" value="{$brandId}" id="brandId" autocomplete="off"> + <input type="hidden" name="" value="" id="condition" autocomplete="off"> + <input type="hidden" name="" value="" id="desc" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,0);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + <ul class="ui-tab-content"> + <li id="goods-list"></li> + </ul> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} +<div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="javascript:WST.intoGoods({{ d[i].goodsId }});"> +<div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d[i].goodsId }});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d[i].goodsImg }}" title="{{ d[i].goodsName }}"/></a></div> +<div class="name ui-nowrap-multi">{{ d[i].goodsName }}</div> +<div class="tags ui-nowrap-multi"> +{{# if(d[i].isSelf==1){ }}<span class='tag'>自营</span>{{# } }} +{{# if(d[i].isFreeShipping==1){ }}<span class='tag'>包邮</span>{{# } }} +{{ d[i]['tags']!=undefined?d[i]['tags'].join(' '):'' }}&nbsp; +</div> +<div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> +<div class="info2"><span class="price">好评率{{ d[i].praiseRate }}</span><span class="deal">成交数:{{ d[i].saleNum }}</span></div> +</div> +{{# } }} +{{# }else{ }} +<div class="wst-prompt-icon"><img src="__MOBILE__/img/nothing-goods.png"></div> +<div class="wst-prompt-info"> + <p>对不起,没有相关商品。</p> +</div> +{{# } }} +</script> +{/block} +{block name="include"} +{include file="default/goods_search" /} +<div class="wst-toTop" style="display: block;bottom: 0.68rem;"> + <a href="{:url('mobile/goods/history')}"><i class="wst-toHistoryimg"></i></a> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/goods_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goods_search.html b/hyhproject/mobile2/view/default/goods_search.html new file mode 100755 index 0000000..ad0b45e --- /dev/null +++ b/hyhproject/mobile2/view/default/goods_search.html @@ -0,0 +1,31 @@ + <div class="wst-co-search" id="wst-goods-search"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('goods',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(0);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="list"> + <p class="search"><i></i>热门搜索</p> + {php}$hotWordsSearch = WSTConf("CONF.hotWordsSearch"); + if($hotWordsSearch!='')$hotWordsSearch = explode(',',$hotWordsSearch);{/php} + <div class="term"> + {volist name="$hotWordsSearch" id="hot"} + <a href="{:url('mobile/goods/lists',['keyword'=>$hot])}">{$hot}</a> + {/volist} + </div> + </div> + </div> + <script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> + <script> + jQuery.noConflict(); + document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#wst-goods-search").is(":hidden")){ + event.preventDefault(); + } + }) + </script> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goodsconsult/consult.html b/hyhproject/mobile2/view/default/goodsconsult/consult.html new file mode 100755 index 0000000..3a98ecd --- /dev/null +++ b/hyhproject/mobile2/view/default/goodsconsult/consult.html @@ -0,0 +1,39 @@ +{extend name="default/base" /} +{block name="title"}发表咨询 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/consult.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>发表咨询</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="goodsId" value="{$goodsId}" id="goodsId" autocomplete="off"> + <section class="ui-container"> + <ul class="gcplist"> + <li> + <label> + 咨询类型: + <select id="consultType"> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <option name="pointType" value="{$vo.dataVal}">{$vo.dataName}</option> + {/volist} + </select> + </label> + </li> + <li>咨询内容:</li> + <li><textarea id="consultContent"></textarea></li> + <li style="text-align:center;"> + <button class="consult-button" onclick="consultCommit();"> + 提交 + </button> + </li> + </ul> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/goodsconsult/consult.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goodsconsult/consult.js b/hyhproject/mobile2/view/default/goodsconsult/consult.js new file mode 100755 index 0000000..3fbc528 --- /dev/null +++ b/hyhproject/mobile2/view/default/goodsconsult/consult.js @@ -0,0 +1,89 @@ +jQuery.noConflict(); +// 获取商品咨询 +function getgoodsConsultList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.goodsId = $('#goodsId').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/goodsconsult/listQuery'), param, function(data){ + var json = WST.toJson(data); + json = json.data; + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('gcList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#_gcList').append(html); + }); + $('#currPage').val(data.data.CurrentPage); + $('#totalPage').val(data.data.TotalPage); + }else{ + html += '<p style="text-align:center;margin-top:10px;">暂无商品咨询~</p>'; + $('#_gcList').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +function consultListInit(){ + var currPage = totalPage = 0; + var loading = false; + $(document).ready(function(){ + getgoodsConsultList(); + var dataHeight = $("#frame").css('height'); + $("#frame").css('top',0); + var dataWidth = $("#frame").css('width'); + $("#frame").css('right','-'+dataWidth); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getgoodsConsultList(); + } + } + }); + }); +}; +$(function(){WST.initFooter()}); +/* 发布咨询 */ +function consult(){ + var goodsId = $('#goodsId').val(); + location.href=WST.U('mobile/goodsconsult/consult',{goodsId:goodsId}); +} +// 提交商品咨询 +function consultCommit(){ + var params={}; + params.goodsId = $('#goodsId').val(); + params.consultType = $('#consultType').val(); + if(params.consultType<=0){ + WST.msg('请选择咨询类别','info'); + return; + } + params.consultContent = $('#consultContent').val(); + if(params.consultContent == ''){ + WST.msg('请输入咨询内容','info'); + return; + } + if(params.consultContent.length<3 || params.consultContent.length>200){ + WST.msg('咨询内容应为3-200个字','info'); + return; + } + WST.load('正在提交,请稍后...'); + $.post(WST.U('mobile/goodsconsult/add'),params,function(responData){ + WST.noload(); + var json = WST.toJson(responData); + if(json.status==1){ + // 发布成功 + WST.msg(json.msg,'success'); + setTimeout(function(){ + history.go(-1); + },1000); + }else{ + WST.msg(json.msg,'warn'); + } + }) +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/goodsconsult/list.html b/hyhproject/mobile2/view/default/goodsconsult/list.html new file mode 100755 index 0000000..03caff1 --- /dev/null +++ b/hyhproject/mobile2/view/default/goodsconsult/list.html @@ -0,0 +1,59 @@ +{extend name="default/base" /} +{block name="title"}商品咨询 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/consult.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>商品咨询</h1> + <div class="consult" onclick="consult()"></div> + </header> +{/block} +{block name="main"} +<input type="hidden" name="goodsId" value="{$goodsId}" id="goodsId" autocomplete="off"> + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + + <script type="text/html" id="gcList"> + {{# for(var i=0;i<d.length;i++){ }} + <li> + <p class="gc-item-tit"> + <span>{{(WST.blank(d[i].loginName)=='')?'游客':d[i].loginName}}</span> + <span class="item-time">{{d[i].createTime}}</span> + </p> + <div class="question-box cf"> + <span class="question-pic"></span> + <div class="question-content"> + <span>{{d[i].consultContent}}</span> + </div> + </div> + <div class="wst-clear"></div> + {{# if(WST.blank(d[i].reply)!=''){ }} + <div class="question-box cf"> + <span class="question-pic answer-pic"></span> + <div class="question-content answer-content"> + <span>{{d[i].reply}}</span> + </div> + </div> + <div class="wst-clear"></div> + {{# } }} + </li> + {{# } }} + </script> + <section class="ui-container" id="newsListBox"> + <div class="gcListBox"> + <ul class="gcList" id="_gcList"> + + </ul> + </div> + </section> +{/block} +{block name="js"} +<script> +$(function(){consultListInit()}); +</script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/goodsconsult/consult.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/header.html b/hyhproject/mobile2/view/default/header.html new file mode 100755 index 0000000..421af93 --- /dev/null +++ b/hyhproject/mobile2/view/default/header.html @@ -0,0 +1,3 @@ + <header class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>{$Title}</h1> + </header> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/img/1.jpg b/hyhproject/mobile2/view/default/img/1.jpg new file mode 100755 index 0000000..0492097 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/1.jpg differ diff --git a/hyhproject/mobile2/view/default/img/2.jpg b/hyhproject/mobile2/view/default/img/2.jpg new file mode 100755 index 0000000..7cf9816 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/2.jpg differ diff --git a/hyhproject/mobile2/view/default/img/232323.jpg b/hyhproject/mobile2/view/default/img/232323.jpg new file mode 100755 index 0000000..abdb8cd Binary files /dev/null and b/hyhproject/mobile2/view/default/img/232323.jpg differ diff --git a/hyhproject/mobile2/view/default/img/3.jpg b/hyhproject/mobile2/view/default/img/3.jpg new file mode 100755 index 0000000..b1bd203 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/3.jpg differ diff --git a/hyhproject/mobile2/view/default/img/4.jpg b/hyhproject/mobile2/view/default/img/4.jpg new file mode 100755 index 0000000..5e824d3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/4.jpg differ diff --git a/hyhproject/mobile2/view/default/img/5.jpg b/hyhproject/mobile2/view/default/img/5.jpg new file mode 100755 index 0000000..44daf8a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/5.jpg differ diff --git a/hyhproject/mobile2/view/default/img/5656.jpg b/hyhproject/mobile2/view/default/img/5656.jpg new file mode 100755 index 0000000..e81c981 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/5656.jpg differ diff --git a/hyhproject/mobile2/view/default/img/66666.jpg b/hyhproject/mobile2/view/default/img/66666.jpg new file mode 100755 index 0000000..56509ee Binary files /dev/null and b/hyhproject/mobile2/view/default/img/66666.jpg differ diff --git a/hyhproject/mobile2/view/default/img/8585.jpg b/hyhproject/mobile2/view/default/img/8585.jpg new file mode 100755 index 0000000..903e10e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/8585.jpg differ diff --git a/hyhproject/mobile2/view/default/img/QA-icon.png b/hyhproject/mobile2/view/default/img/QA-icon.png new file mode 100755 index 0000000..e31c96c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/QA-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/QQ20170814092939.jpg b/hyhproject/mobile2/view/default/img/QQ20170814092939.jpg new file mode 100755 index 0000000..a8cf989 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/QQ20170814092939.jpg differ diff --git a/hyhproject/mobile2/view/default/img/QQ20170914154124.png b/hyhproject/mobile2/view/default/img/QQ20170914154124.png new file mode 100755 index 0000000..5f25636 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/QQ20170914154124.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2_bg1.png b/hyhproject/mobile2/view/default/img/ac2_bg1.png new file mode 100755 index 0000000..d012f71 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2_bg1.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2_footer.png b/hyhproject/mobile2/view/default/img/ac2_footer.png new file mode 100755 index 0000000..86e287f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2_footer.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2_sanjiao.png b/hyhproject/mobile2/view/default/img/ac2_sanjiao.png new file mode 100755 index 0000000..96a74d3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2_sanjiao.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2_title_bg.png b/hyhproject/mobile2/view/default/img/ac2_title_bg.png new file mode 100755 index 0000000..018c1e1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2_title_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2_zdzb_bg.png b/hyhproject/mobile2/view/default/img/ac2_zdzb_bg.png new file mode 100755 index 0000000..a81827d Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2_zdzb_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/ac2activity_bg.png b/hyhproject/mobile2/view/default/img/ac2activity_bg.png new file mode 100755 index 0000000..6c9355f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac2activity_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_bg1.png b/hyhproject/mobile2/view/default/img/ac3_bg1.png new file mode 100755 index 0000000..ea9479b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_bg1.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_bg2.png b/hyhproject/mobile2/view/default/img/ac3_bg2.png new file mode 100755 index 0000000..f2b4b22 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_bg2.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_bg3.png b/hyhproject/mobile2/view/default/img/ac3_bg3.png new file mode 100755 index 0000000..1f17abd Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_bg3.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_bg4.png b/hyhproject/mobile2/view/default/img/ac3_bg4.png new file mode 100755 index 0000000..e992a60 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_bg4.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_bg5.png b/hyhproject/mobile2/view/default/img/ac3_bg5.png new file mode 100755 index 0000000..b16dca0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_bg5.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_button.png b/hyhproject/mobile2/view/default/img/ac3_button.png new file mode 100755 index 0000000..d4aaffe Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_button.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_button1.png b/hyhproject/mobile2/view/default/img/ac3_button1.png new file mode 100755 index 0000000..a0b49bb Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_button1.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_header_bg.png b/hyhproject/mobile2/view/default/img/ac3_header_bg.png new file mode 100755 index 0000000..91a7179 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_header_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_title.png b/hyhproject/mobile2/view/default/img/ac3_title.png new file mode 100755 index 0000000..c81d9c1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_title.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_title1.png b/hyhproject/mobile2/view/default/img/ac3_title1.png new file mode 100755 index 0000000..0bae626 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_title1.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_title2.png b/hyhproject/mobile2/view/default/img/ac3_title2.png new file mode 100755 index 0000000..b48fbed Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_title2.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_title3.png b/hyhproject/mobile2/view/default/img/ac3_title3.png new file mode 100755 index 0000000..6ae61aa Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_title3.png differ diff --git a/hyhproject/mobile2/view/default/img/ac3_yhq.png b/hyhproject/mobile2/view/default/img/ac3_yhq.png new file mode 100755 index 0000000..34ef649 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ac3_yhq.png differ diff --git a/hyhproject/mobile2/view/default/img/activity2_head.png b/hyhproject/mobile2/view/default/img/activity2_head.png new file mode 100755 index 0000000..c72f202 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/activity2_head.png differ diff --git a/hyhproject/mobile2/view/default/img/aiguangjie.png b/hyhproject/mobile2/view/default/img/aiguangjie.png new file mode 100755 index 0000000..74b8a25 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/aiguangjie.png differ diff --git a/hyhproject/mobile2/view/default/img/baikuan.jpg b/hyhproject/mobile2/view/default/img/baikuan.jpg new file mode 100755 index 0000000..34d52e5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/baikuan.jpg differ diff --git a/hyhproject/mobile2/view/default/img/banner1.png b/hyhproject/mobile2/view/default/img/banner1.png new file mode 100755 index 0000000..5b555c5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/banner1.png differ diff --git a/hyhproject/mobile2/view/default/img/banner2.png b/hyhproject/mobile2/view/default/img/banner2.png new file mode 100755 index 0000000..741b4f6 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/banner2.png differ diff --git a/hyhproject/mobile2/view/default/img/bimaiqingdan.png b/hyhproject/mobile2/view/default/img/bimaiqingdan.png new file mode 100755 index 0000000..02e255a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bimaiqingdan.png differ diff --git a/hyhproject/mobile2/view/default/img/bk_bg1.png b/hyhproject/mobile2/view/default/img/bk_bg1.png new file mode 100755 index 0000000..1b24d98 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bk_bg1.png differ diff --git a/hyhproject/mobile2/view/default/img/bk_bg2.png b/hyhproject/mobile2/view/default/img/bk_bg2.png new file mode 100755 index 0000000..5b4a4a3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bk_bg2.png differ diff --git a/hyhproject/mobile2/view/default/img/bk_bg3.png b/hyhproject/mobile2/view/default/img/bk_bg3.png new file mode 100755 index 0000000..02a3c11 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bk_bg3.png differ diff --git a/hyhproject/mobile2/view/default/img/bk_bg4.png b/hyhproject/mobile2/view/default/img/bk_bg4.png new file mode 100755 index 0000000..cd3f085 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bk_bg4.png differ diff --git a/hyhproject/mobile2/view/default/img/bktj.png b/hyhproject/mobile2/view/default/img/bktj.png new file mode 100755 index 0000000..383eb69 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/bktj.png differ diff --git a/hyhproject/mobile2/view/default/img/brand.png b/hyhproject/mobile2/view/default/img/brand.png new file mode 100755 index 0000000..8a1f270 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/brand.png differ diff --git a/hyhproject/mobile2/view/default/img/cainixihuan.png b/hyhproject/mobile2/view/default/img/cainixihuan.png new file mode 100755 index 0000000..e9f38a6 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/cainixihuan.png differ diff --git a/hyhproject/mobile2/view/default/img/cart.png b/hyhproject/mobile2/view/default/img/cart.png new file mode 100755 index 0000000..f8c12a5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/cart.png differ diff --git a/hyhproject/mobile2/view/default/img/cbd.jpg b/hyhproject/mobile2/view/default/img/cbd.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/cbd.jpg differ diff --git a/hyhproject/mobile2/view/default/img/chaoshihui.png b/hyhproject/mobile2/view/default/img/chaoshihui.png new file mode 100755 index 0000000..a331dfe Binary files /dev/null and b/hyhproject/mobile2/view/default/img/chaoshihui.png differ diff --git a/hyhproject/mobile2/view/default/img/chaoshihui2.png b/hyhproject/mobile2/view/default/img/chaoshihui2.png new file mode 100755 index 0000000..5ff44dd Binary files /dev/null and b/hyhproject/mobile2/view/default/img/chaoshihui2.png differ diff --git a/hyhproject/mobile2/view/default/img/classify.png b/hyhproject/mobile2/view/default/img/classify.png new file mode 100755 index 0000000..10f62f1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/classify.png differ diff --git a/hyhproject/mobile2/view/default/img/classify2.png b/hyhproject/mobile2/view/default/img/classify2.png new file mode 100755 index 0000000..2765f5f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/classify2.png differ diff --git a/hyhproject/mobile2/view/default/img/copy.png b/hyhproject/mobile2/view/default/img/copy.png new file mode 100755 index 0000000..9304fa3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/copy.png differ diff --git a/hyhproject/mobile2/view/default/img/custom.png b/hyhproject/mobile2/view/default/img/custom.png new file mode 100755 index 0000000..70faec0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/custom.png differ diff --git a/hyhproject/mobile2/view/default/img/default_shopbanner.jpg b/hyhproject/mobile2/view/default/img/default_shopbanner.jpg new file mode 100755 index 0000000..a63dbf0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/default_shopbanner.jpg differ diff --git a/hyhproject/mobile2/view/default/img/default_shopbanner.png b/hyhproject/mobile2/view/default/img/default_shopbanner.png new file mode 100755 index 0000000..6259564 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/default_shopbanner.png differ diff --git a/hyhproject/mobile2/view/default/img/email.png b/hyhproject/mobile2/view/default/img/email.png new file mode 100755 index 0000000..ce33848 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/email.png differ diff --git a/hyhproject/mobile2/view/default/img/evaluate.png b/hyhproject/mobile2/view/default/img/evaluate.png new file mode 100755 index 0000000..407b6ba Binary files /dev/null and b/hyhproject/mobile2/view/default/img/evaluate.png differ diff --git a/hyhproject/mobile2/view/default/img/eye.png b/hyhproject/mobile2/view/default/img/eye.png new file mode 100755 index 0000000..987793c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/eye.png differ diff --git a/hyhproject/mobile2/view/default/img/faxianhaohuo1.png b/hyhproject/mobile2/view/default/img/faxianhaohuo1.png new file mode 100755 index 0000000..19690cf Binary files /dev/null and b/hyhproject/mobile2/view/default/img/faxianhaohuo1.png differ diff --git a/hyhproject/mobile2/view/default/img/feichangdapai.png b/hyhproject/mobile2/view/default/img/feichangdapai.png new file mode 100755 index 0000000..1a45688 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/feichangdapai.png differ diff --git a/hyhproject/mobile2/view/default/img/feichangdapai1.jpg b/hyhproject/mobile2/view/default/img/feichangdapai1.jpg new file mode 100755 index 0000000..96c6a96 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/feichangdapai1.jpg differ diff --git a/hyhproject/mobile2/view/default/img/follow-shop.png b/hyhproject/mobile2/view/default/img/follow-shop.png new file mode 100755 index 0000000..37b4bd4 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/follow-shop.png differ diff --git a/hyhproject/mobile2/view/default/img/goods-list.png b/hyhproject/mobile2/view/default/img/goods-list.png new file mode 100755 index 0000000..1894912 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/goods-list.png differ diff --git a/hyhproject/mobile2/view/default/img/goods-list2.png b/hyhproject/mobile2/view/default/img/goods-list2.png new file mode 100755 index 0000000..323a850 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/goods-list2.png differ diff --git a/hyhproject/mobile2/view/default/img/gua.jpg b/hyhproject/mobile2/view/default/img/gua.jpg new file mode 100755 index 0000000..1a7a75b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/gua.jpg differ diff --git a/hyhproject/mobile2/view/default/img/guangshangchang.png b/hyhproject/mobile2/view/default/img/guangshangchang.png new file mode 100755 index 0000000..f77d165 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/guangshangchang.png differ diff --git a/hyhproject/mobile2/view/default/img/guangshangchang1.png b/hyhproject/mobile2/view/default/img/guangshangchang1.png new file mode 100755 index 0000000..030115c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/guangshangchang1.png differ diff --git a/hyhproject/mobile2/view/default/img/guochan_con_bg.png b/hyhproject/mobile2/view/default/img/guochan_con_bg.png new file mode 100755 index 0000000..dc893ab Binary files /dev/null and b/hyhproject/mobile2/view/default/img/guochan_con_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/guochanjingxuan.png b/hyhproject/mobile2/view/default/img/guochanjingxuan.png new file mode 100755 index 0000000..9aa7c01 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/guochanjingxuan.png differ diff --git a/hyhproject/mobile2/view/default/img/history-icon.png b/hyhproject/mobile2/view/default/img/history-icon.png new file mode 100755 index 0000000..a9cb128 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/history-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/home.png b/hyhproject/mobile2/view/default/img/home.png new file mode 100755 index 0000000..9b11de0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/home.png differ diff --git a/hyhproject/mobile2/view/default/img/home2.png b/hyhproject/mobile2/view/default/img/home2.png new file mode 100755 index 0000000..695aff9 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/home2.png differ diff --git a/hyhproject/mobile2/view/default/img/hot.png b/hyhproject/mobile2/view/default/img/hot.png new file mode 100755 index 0000000..fa195c2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/hot.png differ diff --git a/hyhproject/mobile2/view/default/img/hot2.png b/hyhproject/mobile2/view/default/img/hot2.png new file mode 100755 index 0000000..326afa8 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/hot2.png differ diff --git a/hyhproject/mobile2/view/default/img/huigou.png b/hyhproject/mobile2/view/default/img/huigou.png new file mode 100755 index 0000000..f822a64 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/huigou.png differ diff --git a/hyhproject/mobile2/view/default/img/huiyuankuaibao.png b/hyhproject/mobile2/view/default/img/huiyuankuaibao.png new file mode 100755 index 0000000..272cdab Binary files /dev/null and b/hyhproject/mobile2/view/default/img/huiyuankuaibao.png differ diff --git a/hyhproject/mobile2/view/default/img/huiyuanmiaosha.png b/hyhproject/mobile2/view/default/img/huiyuanmiaosha.png new file mode 100755 index 0000000..cef11ea Binary files /dev/null and b/hyhproject/mobile2/view/default/img/huiyuanmiaosha.png differ diff --git a/hyhproject/mobile2/view/default/img/huiyuanzhuanhui1.png b/hyhproject/mobile2/view/default/img/huiyuanzhuanhui1.png new file mode 100755 index 0000000..a149d53 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/huiyuanzhuanhui1.png differ diff --git a/hyhproject/mobile2/view/default/img/icon-integral.png b/hyhproject/mobile2/view/default/img/icon-integral.png new file mode 100755 index 0000000..b3b1967 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon-integral.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_add_money.png b/hyhproject/mobile2/view/default/img/icon_add_money.png new file mode 100755 index 0000000..c872021 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_add_money.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_adds_users.png b/hyhproject/mobile2/view/default/img/icon_adds_users.png new file mode 100755 index 0000000..d5dfef7 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_adds_users.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_bottomnav.png b/hyhproject/mobile2/view/default/img/icon_bottomnav.png new file mode 100755 index 0000000..fabbd35 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_bottomnav.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_bottomnav2.png b/hyhproject/mobile2/view/default/img/icon_bottomnav2.png new file mode 100755 index 0000000..821b099 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_bottomnav2.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_bottomnav3.png b/hyhproject/mobile2/view/default/img/icon_bottomnav3.png new file mode 100755 index 0000000..f919b71 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_bottomnav3.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_bottomnav4.png b/hyhproject/mobile2/view/default/img/icon_bottomnav4.png new file mode 100755 index 0000000..9d8761a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_bottomnav4.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_bottomnavv.png b/hyhproject/mobile2/view/default/img/icon_bottomnavv.png new file mode 100755 index 0000000..441582e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_bottomnavv.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_cart.png b/hyhproject/mobile2/view/default/img/icon_cart.png new file mode 100755 index 0000000..26179ee Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_cart.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_cart_money.png b/hyhproject/mobile2/view/default/img/icon_cart_money.png new file mode 100755 index 0000000..18cff97 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_cart_money.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_cd.png b/hyhproject/mobile2/view/default/img/icon_cd.png new file mode 100755 index 0000000..2ef28ad Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_cd.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_down.png b/hyhproject/mobile2/view/default/img/icon_down.png new file mode 100755 index 0000000..d1c62f7 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_down.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_dp.png b/hyhproject/mobile2/view/default/img/icon_dp.png new file mode 100755 index 0000000..e17b9b7 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_dp.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_dpsp.png b/hyhproject/mobile2/view/default/img/icon_dpsp.png new file mode 100755 index 0000000..aa4eb83 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_dpsp.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_gz.png b/hyhproject/mobile2/view/default/img/icon_gz.png new file mode 100755 index 0000000..eda8aea Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_gz.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_gzspcart.png b/hyhproject/mobile2/view/default/img/icon_gzspcart.png new file mode 100755 index 0000000..c8028e9 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_gzspcart.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_indextop.png b/hyhproject/mobile2/view/default/img/icon_indextop.png new file mode 100755 index 0000000..39305f5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_indextop.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_indextop1.png b/hyhproject/mobile2/view/default/img/icon_indextop1.png new file mode 100755 index 0000000..39305f5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_indextop1.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_kf.png b/hyhproject/mobile2/view/default/img/icon_kf.png new file mode 100755 index 0000000..9454d66 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_kf.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_like1.png b/hyhproject/mobile2/view/default/img/icon_like1.png new file mode 100755 index 0000000..f599add Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_like1.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_like2.png b/hyhproject/mobile2/view/default/img/icon_like2.png new file mode 100755 index 0000000..cfe2feb Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_like2.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_logmoney.png b/hyhproject/mobile2/view/default/img/icon_logmoney.png new file mode 100755 index 0000000..4eb4094 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_logmoney.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_more.png b/hyhproject/mobile2/view/default/img/icon_more.png new file mode 100755 index 0000000..7909d41 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_more.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_news1.png b/hyhproject/mobile2/view/default/img/icon_news1.png new file mode 100755 index 0000000..a0adc1c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_news1.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_out_money.png b/hyhproject/mobile2/view/default/img/icon_out_money.png new file mode 100755 index 0000000..282d332 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_out_money.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_record.png b/hyhproject/mobile2/view/default/img/icon_record.png new file mode 100755 index 0000000..23c9664 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_record.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_right.png b/hyhproject/mobile2/view/default/img/icon_right.png new file mode 100755 index 0000000..6967dfb Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_right.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_s.png b/hyhproject/mobile2/view/default/img/icon_s.png new file mode 100755 index 0000000..1ba8288 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_s.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_select.png b/hyhproject/mobile2/view/default/img/icon_select.png new file mode 100755 index 0000000..fce1a0d Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_select.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_select1.png b/hyhproject/mobile2/view/default/img/icon_select1.png new file mode 100755 index 0000000..a2c32eb Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_select1.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_shop.png b/hyhproject/mobile2/view/default/img/icon_shop.png new file mode 100755 index 0000000..f5212f2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_shop.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_spxq.png b/hyhproject/mobile2/view/default/img/icon_spxq.png new file mode 100755 index 0000000..e2bbd5b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_spxq.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_tishi.png b/hyhproject/mobile2/view/default/img/icon_tishi.png new file mode 100755 index 0000000..2cff9ec Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_tishi.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_tixian.png b/hyhproject/mobile2/view/default/img/icon_tixian.png new file mode 100755 index 0000000..ba32828 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_tixian.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_user_about.png b/hyhproject/mobile2/view/default/img/icon_user_about.png new file mode 100755 index 0000000..246a195 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_user_about.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_user_adds.png b/hyhproject/mobile2/view/default/img/icon_user_adds.png new file mode 100755 index 0000000..9f0778c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_user_adds.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_user_info.png b/hyhproject/mobile2/view/default/img/icon_user_info.png new file mode 100755 index 0000000..9543430 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_user_info.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_user_safety.png b/hyhproject/mobile2/view/default/img/icon_user_safety.png new file mode 100755 index 0000000..abd0c3f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_user_safety.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_userscores.png b/hyhproject/mobile2/view/default/img/icon_userscores.png new file mode 100755 index 0000000..e8d60e3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_userscores.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_zhanghuanquan.png b/hyhproject/mobile2/view/default/img/icon_zhanghuanquan.png new file mode 100755 index 0000000..a811c97 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_zhanghuanquan.png differ diff --git a/hyhproject/mobile2/view/default/img/icon_zhifu.png b/hyhproject/mobile2/view/default/img/icon_zhifu.png new file mode 100755 index 0000000..6ef7336 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/icon_zhifu.png differ diff --git a/hyhproject/mobile2/view/default/img/imail.png b/hyhproject/mobile2/view/default/img/imail.png new file mode 100755 index 0000000..b48b215 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/imail.png differ diff --git a/hyhproject/mobile2/view/default/img/imail2.png b/hyhproject/mobile2/view/default/img/imail2.png new file mode 100755 index 0000000..890e860 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/imail2.png differ diff --git a/hyhproject/mobile2/view/default/img/img_dpbg.png b/hyhproject/mobile2/view/default/img/img_dpbg.png new file mode 100755 index 0000000..27b239e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_dpbg.png differ diff --git a/hyhproject/mobile2/view/default/img/img_dpjpj.png b/hyhproject/mobile2/view/default/img/img_dpjpj.png new file mode 100755 index 0000000..13959d0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_dpjpj.png differ diff --git a/hyhproject/mobile2/view/default/img/img_error_2.png b/hyhproject/mobile2/view/default/img/img_error_2.png new file mode 100755 index 0000000..1e841c4 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_error_2.png differ diff --git a/hyhproject/mobile2/view/default/img/img_error_3.png b/hyhproject/mobile2/view/default/img/img_error_3.png new file mode 100755 index 0000000..248cc7e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_error_3.png differ diff --git a/hyhproject/mobile2/view/default/img/img_fenxiangtishi.png b/hyhproject/mobile2/view/default/img/img_fenxiangtishi.png new file mode 100755 index 0000000..72e9235 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_fenxiangtishi.png differ diff --git a/hyhproject/mobile2/view/default/img/img_gd_sel.png b/hyhproject/mobile2/view/default/img/img_gd_sel.png new file mode 100755 index 0000000..a3422a4 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_gd_sel.png differ diff --git a/hyhproject/mobile2/view/default/img/img_jgsx.png b/hyhproject/mobile2/view/default/img/img_jgsx.png new file mode 100755 index 0000000..e7beb51 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_jgsx.png differ diff --git a/hyhproject/mobile2/view/default/img/img_titlebg.png b/hyhproject/mobile2/view/default/img/img_titlebg.png new file mode 100755 index 0000000..0bf2dc4 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_titlebg.png differ diff --git a/hyhproject/mobile2/view/default/img/img_users_icon.png b/hyhproject/mobile2/view/default/img/img_users_icon.png new file mode 100755 index 0000000..95e6f3f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_users_icon.png differ diff --git a/hyhproject/mobile2/view/default/img/img_wdye.png b/hyhproject/mobile2/view/default/img/img_wdye.png new file mode 100755 index 0000000..b892d01 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/img_wdye.png differ diff --git a/hyhproject/mobile2/view/default/img/index-icon.png b/hyhproject/mobile2/view/default/img/index-icon.png new file mode 100755 index 0000000..3526e1f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/index-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/info_icon.png b/hyhproject/mobile2/view/default/img/info_icon.png new file mode 100755 index 0000000..7b1859b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/info_icon.png differ diff --git a/hyhproject/mobile2/view/default/img/jia.png b/hyhproject/mobile2/view/default/img/jia.png new file mode 100755 index 0000000..d3e7f88 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/jia.png differ diff --git a/hyhproject/mobile2/view/default/img/jiagou.png b/hyhproject/mobile2/view/default/img/jiagou.png new file mode 100755 index 0000000..ff0d3ca Binary files /dev/null and b/hyhproject/mobile2/view/default/img/jiagou.png differ diff --git a/hyhproject/mobile2/view/default/img/jian.png b/hyhproject/mobile2/view/default/img/jian.png new file mode 100755 index 0000000..978f9e1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/jian.png differ diff --git a/hyhproject/mobile2/view/default/img/jxyh.png b/hyhproject/mobile2/view/default/img/jxyh.png new file mode 100755 index 0000000..df0e2da Binary files /dev/null and b/hyhproject/mobile2/view/default/img/jxyh.png differ diff --git a/hyhproject/mobile2/view/default/img/kafei.jpg b/hyhproject/mobile2/view/default/img/kafei.jpg new file mode 100755 index 0000000..1354262 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/kafei.jpg differ diff --git a/hyhproject/mobile2/view/default/img/lanmei.jpg b/hyhproject/mobile2/view/default/img/lanmei.jpg new file mode 100755 index 0000000..f843b1b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/lanmei.jpg differ diff --git a/hyhproject/mobile2/view/default/img/line-address.png b/hyhproject/mobile2/view/default/img/line-address.png new file mode 100755 index 0000000..ee3a713 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/line-address.png differ diff --git a/hyhproject/mobile2/view/default/img/ljqg.png b/hyhproject/mobile2/view/default/img/ljqg.png new file mode 100755 index 0000000..48da377 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/ljqg.png differ diff --git a/hyhproject/mobile2/view/default/img/luhua.jpg b/hyhproject/mobile2/view/default/img/luhua.jpg new file mode 100755 index 0000000..7aeb600 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/luhua.jpg differ diff --git a/hyhproject/mobile2/view/default/img/me.png b/hyhproject/mobile2/view/default/img/me.png new file mode 100755 index 0000000..3aa51f5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/me.png differ diff --git a/hyhproject/mobile2/view/default/img/me2.png b/hyhproject/mobile2/view/default/img/me2.png new file mode 100755 index 0000000..e843967 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/me2.png differ diff --git a/hyhproject/mobile2/view/default/img/message-icon.png b/hyhproject/mobile2/view/default/img/message-icon.png new file mode 100755 index 0000000..7872e30 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/message-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/miaosha_bg.png b/hyhproject/mobile2/view/default/img/miaosha_bg.png new file mode 100755 index 0000000..3972938 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/miaosha_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/mine-icon.png b/hyhproject/mobile2/view/default/img/mine-icon.png new file mode 100755 index 0000000..ef93c44 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/mine-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/muwu.jpg b/hyhproject/mobile2/view/default/img/muwu.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/hyhproject/mobile2/view/default/img/muwu.jpg differ diff --git a/hyhproject/mobile2/view/default/img/my_bg.png b/hyhproject/mobile2/view/default/img/my_bg.png new file mode 100755 index 0000000..b295676 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/my_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/naicha.jpg b/hyhproject/mobile2/view/default/img/naicha.jpg new file mode 100755 index 0000000..b64f380 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/naicha.jpg differ diff --git a/hyhproject/mobile2/view/default/img/nocite_deliver.png b/hyhproject/mobile2/view/default/img/nocite_deliver.png new file mode 100755 index 0000000..da071f1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nocite_deliver.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-account.png b/hyhproject/mobile2/view/default/img/nothing-account.png new file mode 100755 index 0000000..51a9de7 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-account.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-address.png b/hyhproject/mobile2/view/default/img/nothing-address.png new file mode 100755 index 0000000..5d1a3c9 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-address.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-cart.png b/hyhproject/mobile2/view/default/img/nothing-cart.png new file mode 100755 index 0000000..c812fa2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-cart.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-complaint.png b/hyhproject/mobile2/view/default/img/nothing-complaint.png new file mode 100755 index 0000000..eebc63b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-complaint.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-evaluate.png b/hyhproject/mobile2/view/default/img/nothing-evaluate.png new file mode 100755 index 0000000..4fc6c3a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-evaluate.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-follow-goods.png b/hyhproject/mobile2/view/default/img/nothing-follow-goods.png new file mode 100755 index 0000000..3527fe0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-follow-goods.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-follow-shps.png b/hyhproject/mobile2/view/default/img/nothing-follow-shps.png new file mode 100755 index 0000000..b4a6ed3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-follow-shps.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-goods.png b/hyhproject/mobile2/view/default/img/nothing-goods.png new file mode 100755 index 0000000..df6e092 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-goods.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-history.png b/hyhproject/mobile2/view/default/img/nothing-history.png new file mode 100755 index 0000000..5daa14c Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-history.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-message.png b/hyhproject/mobile2/view/default/img/nothing-message.png new file mode 100755 index 0000000..371d098 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-message.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-order.png b/hyhproject/mobile2/view/default/img/nothing-order.png new file mode 100755 index 0000000..88e9568 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-order.png differ diff --git a/hyhproject/mobile2/view/default/img/nothing-relevant.png b/hyhproject/mobile2/view/default/img/nothing-relevant.png new file mode 100755 index 0000000..43b7617 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/nothing-relevant.png differ diff --git a/hyhproject/mobile2/view/default/img/notice.png b/hyhproject/mobile2/view/default/img/notice.png new file mode 100755 index 0000000..0ff0965 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/notice.png differ diff --git a/hyhproject/mobile2/view/default/img/order.png b/hyhproject/mobile2/view/default/img/order.png new file mode 100755 index 0000000..6e3563a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/order.png differ diff --git a/hyhproject/mobile2/view/default/img/paihangbang.png b/hyhproject/mobile2/view/default/img/paihangbang.png new file mode 100755 index 0000000..30b6be5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/paihangbang.png differ diff --git a/hyhproject/mobile2/view/default/img/pays-ali.png b/hyhproject/mobile2/view/default/img/pays-ali.png new file mode 100755 index 0000000..5397889 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pays-ali.png differ diff --git a/hyhproject/mobile2/view/default/img/pays-cod.png b/hyhproject/mobile2/view/default/img/pays-cod.png new file mode 100755 index 0000000..b24574b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pays-cod.png differ diff --git a/hyhproject/mobile2/view/default/img/pays-union.png b/hyhproject/mobile2/view/default/img/pays-union.png new file mode 100755 index 0000000..ca9116e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pays-union.png differ diff --git a/hyhproject/mobile2/view/default/img/pays-wallets.png b/hyhproject/mobile2/view/default/img/pays-wallets.png new file mode 100755 index 0000000..1a1893a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pays-wallets.png differ diff --git a/hyhproject/mobile2/view/default/img/pays-weixin.png b/hyhproject/mobile2/view/default/img/pays-weixin.png new file mode 100755 index 0000000..334b7dc Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pays-weixin.png differ diff --git a/hyhproject/mobile2/view/default/img/pinzhishishang.png b/hyhproject/mobile2/view/default/img/pinzhishishang.png new file mode 100755 index 0000000..f2013d1 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/pinzhishishang.png differ diff --git a/hyhproject/mobile2/view/default/img/qianggou.png b/hyhproject/mobile2/view/default/img/qianggou.png new file mode 100755 index 0000000..e5b49f2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/qianggou.png differ diff --git a/hyhproject/mobile2/view/default/img/qq.png b/hyhproject/mobile2/view/default/img/qq.png new file mode 100755 index 0000000..41d774f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/qq.png differ diff --git a/hyhproject/mobile2/view/default/img/saoyisao.png b/hyhproject/mobile2/view/default/img/saoyisao.png new file mode 100755 index 0000000..c14f6da Binary files /dev/null and b/hyhproject/mobile2/view/default/img/saoyisao.png differ diff --git a/hyhproject/mobile2/view/default/img/screenshot.png b/hyhproject/mobile2/view/default/img/screenshot.png new file mode 100755 index 0000000..91a28ed Binary files /dev/null and b/hyhproject/mobile2/view/default/img/screenshot.png differ diff --git a/hyhproject/mobile2/view/default/img/self.png b/hyhproject/mobile2/view/default/img/self.png new file mode 100755 index 0000000..04c92b9 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/self.png differ diff --git a/hyhproject/mobile2/view/default/img/shan.png b/hyhproject/mobile2/view/default/img/shan.png new file mode 100755 index 0000000..e9d44c5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shan.png differ diff --git a/hyhproject/mobile2/view/default/img/shangpin1.png b/hyhproject/mobile2/view/default/img/shangpin1.png new file mode 100755 index 0000000..38f38a9 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shangpin1.png differ diff --git a/hyhproject/mobile2/view/default/img/shangxin.png b/hyhproject/mobile2/view/default/img/shangxin.png new file mode 100755 index 0000000..3235ea8 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shangxin.png differ diff --git a/hyhproject/mobile2/view/default/img/shaung11jianianhua.png b/hyhproject/mobile2/view/default/img/shaung11jianianhua.png new file mode 100755 index 0000000..0ae84f6 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shaung11jianianhua.png differ diff --git a/hyhproject/mobile2/view/default/img/shop.png b/hyhproject/mobile2/view/default/img/shop.png new file mode 100755 index 0000000..b8d2015 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shop.png differ diff --git a/hyhproject/mobile2/view/default/img/shop2.png b/hyhproject/mobile2/view/default/img/shop2.png new file mode 100755 index 0000000..07a23dc Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shop2.png differ diff --git a/hyhproject/mobile2/view/default/img/shopstreet.png b/hyhproject/mobile2/view/default/img/shopstreet.png new file mode 100755 index 0000000..414a677 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shopstreet.png differ diff --git a/hyhproject/mobile2/view/default/img/shuijiao.jpg b/hyhproject/mobile2/view/default/img/shuijiao.jpg new file mode 100755 index 0000000..8248768 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/shuijiao.jpg differ diff --git a/hyhproject/mobile2/view/default/img/sign-icon.png b/hyhproject/mobile2/view/default/img/sign-icon.png new file mode 100755 index 0000000..2650e46 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/sign-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/sign-icon2.png b/hyhproject/mobile2/view/default/img/sign-icon2.png new file mode 100755 index 0000000..644fc4a Binary files /dev/null and b/hyhproject/mobile2/view/default/img/sign-icon2.png differ diff --git a/hyhproject/mobile2/view/default/img/sousuo.png b/hyhproject/mobile2/view/default/img/sousuo.png new file mode 100755 index 0000000..873650f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/sousuo.png differ diff --git a/hyhproject/mobile2/view/default/img/time_limit.png b/hyhproject/mobile2/view/default/img/time_limit.png new file mode 100755 index 0000000..3e03d02 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/time_limit.png differ diff --git a/hyhproject/mobile2/view/default/img/top.png b/hyhproject/mobile2/view/default/img/top.png new file mode 100755 index 0000000..ff56f14 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/top.png differ diff --git a/hyhproject/mobile2/view/default/img/user-order-icon.png b/hyhproject/mobile2/view/default/img/user-order-icon.png new file mode 100755 index 0000000..385ad15 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user-order-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/user-tool-icon.png b/hyhproject/mobile2/view/default/img/user-tool-icon.png new file mode 100755 index 0000000..4a351e3 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user-tool-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/user-tool-icon2.png b/hyhproject/mobile2/view/default/img/user-tool-icon2.png new file mode 100755 index 0000000..eec3689 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user-tool-icon2.png differ diff --git a/hyhproject/mobile2/view/default/img/user-wallet-icon.png b/hyhproject/mobile2/view/default/img/user-wallet-icon.png new file mode 100755 index 0000000..eeb09ba Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user-wallet-icon.png differ diff --git a/hyhproject/mobile2/view/default/img/user.png b/hyhproject/mobile2/view/default/img/user.png new file mode 100755 index 0000000..f960db5 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user.png differ diff --git a/hyhproject/mobile2/view/default/img/user_grade.png b/hyhproject/mobile2/view/default/img/user_grade.png new file mode 100755 index 0000000..abcfe21 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user_grade.png differ diff --git a/hyhproject/mobile2/view/default/img/user_line.png b/hyhproject/mobile2/view/default/img/user_line.png new file mode 100755 index 0000000..b876d27 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/user_line.png differ diff --git a/hyhproject/mobile2/view/default/img/users_icon.png b/hyhproject/mobile2/view/default/img/users_icon.png new file mode 100755 index 0000000..22cd001 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/users_icon.png differ diff --git a/hyhproject/mobile2/view/default/img/users_icon1.png b/hyhproject/mobile2/view/default/img/users_icon1.png new file mode 100755 index 0000000..22cd001 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/users_icon1.png differ diff --git a/hyhproject/mobile2/view/default/img/xianshitehui.png b/hyhproject/mobile2/view/default/img/xianshitehui.png new file mode 100755 index 0000000..77bbf58 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/xianshitehui.png differ diff --git a/hyhproject/mobile2/view/default/img/xinpinshangshi.png b/hyhproject/mobile2/view/default/img/xinpinshangshi.png new file mode 100755 index 0000000..152c1d2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/xinpinshangshi.png differ diff --git a/hyhproject/mobile2/view/default/img/xinpinshoufa.png b/hyhproject/mobile2/view/default/img/xinpinshoufa.png new file mode 100755 index 0000000..c9e087f Binary files /dev/null and b/hyhproject/mobile2/view/default/img/xinpinshoufa.png differ diff --git a/hyhproject/mobile2/view/default/img/xpbk.png b/hyhproject/mobile2/view/default/img/xpbk.png new file mode 100755 index 0000000..920cbf0 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/xpbk.png differ diff --git a/hyhproject/mobile2/view/default/img/xrx.jpg b/hyhproject/mobile2/view/default/img/xrx.jpg new file mode 100755 index 0000000..caee92b Binary files /dev/null and b/hyhproject/mobile2/view/default/img/xrx.jpg differ diff --git a/hyhproject/mobile2/view/default/img/youhaohuo.png b/hyhproject/mobile2/view/default/img/youhaohuo.png new file mode 100755 index 0000000..86fe591 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/youhaohuo.png differ diff --git a/hyhproject/mobile2/view/default/img/youhuiquan1.png b/hyhproject/mobile2/view/default/img/youhuiquan1.png new file mode 100755 index 0000000..4f39a18 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/youhuiquan1.png differ diff --git a/hyhproject/mobile2/view/default/img/youhuiquan2.png b/hyhproject/mobile2/view/default/img/youhuiquan2.png new file mode 100755 index 0000000..50c6be2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/youhuiquan2.png differ diff --git a/hyhproject/mobile2/view/default/img/youzi.jpg b/hyhproject/mobile2/view/default/img/youzi.jpg new file mode 100755 index 0000000..9eba17e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/youzi.jpg differ diff --git a/hyhproject/mobile2/view/default/img/yuantiao.jpg b/hyhproject/mobile2/view/default/img/yuantiao.jpg new file mode 100755 index 0000000..f97ba26 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/yuantiao.jpg differ diff --git a/hyhproject/mobile2/view/default/img/zan1.png b/hyhproject/mobile2/view/default/img/zan1.png new file mode 100755 index 0000000..54ed64e Binary files /dev/null and b/hyhproject/mobile2/view/default/img/zan1.png differ diff --git a/hyhproject/mobile2/view/default/img/zan2.png b/hyhproject/mobile2/view/default/img/zan2.png new file mode 100755 index 0000000..a58019d Binary files /dev/null and b/hyhproject/mobile2/view/default/img/zan2.png differ diff --git a/hyhproject/mobile2/view/default/img/zdzb2_bg.png b/hyhproject/mobile2/view/default/img/zdzb2_bg.png new file mode 100755 index 0000000..c3e1053 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/zdzb2_bg.png differ diff --git a/hyhproject/mobile2/view/default/img/zk_banner.png b/hyhproject/mobile2/view/default/img/zk_banner.png new file mode 100755 index 0000000..02f1821 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/zk_banner.png differ diff --git a/hyhproject/mobile2/view/default/img/╬┤▒ъ╠т-14.png b/hyhproject/mobile2/view/default/img/╬┤▒ъ╠т-14.png new file mode 100755 index 0000000..152c1d2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/╬┤▒ъ╠т-14.png differ diff --git a/hyhproject/mobile2/view/default/img/鈺敜鈻捬娾暊褌-14.png b/hyhproject/mobile2/view/default/img/鈺敜鈻捬娾暊褌-14.png new file mode 100755 index 0000000..152c1d2 Binary files /dev/null and b/hyhproject/mobile2/view/default/img/鈺敜鈻捬娾暊褌-14.png differ diff --git a/hyhproject/mobile2/view/default/index.html b/hyhproject/mobile2/view/default/index.html new file mode 100755 index 0000000..ca5d340 --- /dev/null +++ b/hyhproject/mobile2/view/default/index.html @@ -0,0 +1,126 @@ +{extend name="default/base" /} {block name="title"}首页 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/index.css?v={$v}"> {/block} {block name="header"} +<header class="ui-header ui-header-positive wst-in-header" id="j-header"> +</header> +<div class="wst-in-search"> + <div class="classify"> + <a href="{:url('mobile/goodscats/index')}"><i></i></a> + </div> + <div class="searchs" id="j-searchs"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action= "" class="input-form" onclick="javascript:WST.searchPage('goods',1);"> + <input type="search" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + <div class="wst-clear"></div> + </div> + <div class="user"> + <a href="{:url('mobile/messages/index')}">{if condition="session('WST_USER.userId') >0"}<i>{if($news['message']['num']>0)}<span class="number">{$news['message']['num']}</span>{/if}</i>{else}登录{/if}</a> + </div> +</div> +{/block} {block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + <!-- /*修改手机跳转 mark lxy 20180308*/ --> + {wst:ads code="mo-ads-index" cache='86400'} + <li class="advert1"><span> + {if condition="$vo.targetType eq 0"} + <a href="{$vo.adURL}"> + {elseif condition="$vo.targetType eq 1" /} + <a href="/mgoods-{$vo.adURL}"> + {elseif condition="$vo.targetType eq 2" /} + <a href="/mhshops-{$vo.adURL}"> + {/if} + + + <img style="width:100%; height:100%; display:block;" src="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(0)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img width='56' src="__IMGURL__/{$btn['btnImg']}" style='margin-top:7px;' /></p> + <span>{$btn['btnName']}</span> + </a> + </div> + {/volist} + </div> + <div class="wst-in-activity"> + {wst:ads code="mo-index-long" cache='86400' num='4'} + <a class="advert4" href="{$vo.adURL}"> + <div class="img"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /></div> + </a>{/wst:ads} + <div class="wst-in-news"> + <span class="new">商城&nbsp;<p>快讯</p></span> + <div class="article"> + <div class="swiper-container swiper-container1"> + <div class="swiper-wrapper"> + {wst:article cat="new" num='6' cache='86400'} + <div class="swiper-slide" style="width:100%;"> + <a class="words" href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}"> + <p class="ui-nowrap-flex">{$vo['articleTitle']}</p> + </a> + </div> + {/wst:article} + </div> + </div> + </div> + <span class="more" onclick="location.href='{:url('mobile/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div> + </div> + <div class="wst-in-adst"> + {wst:ads code="mo-index-left" cache='86400' num='1'} + <a class="advert2" href="{$vo.adURL}"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" style="height:2rem;" /></a> + {/wst:ads} {wst:ads code="mo-index-right" cache='86400' num='2'} + <a class="advert2" href="{$vo.adURL}"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" style="height:0.995rem;" /></a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container swiper-container2"> + <div class="swiper-wrapper"> + {wst:ads code="mo-index-small" cache='86400' num='10'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div id="goods-list"></div> +</section> +<script id="list" type="text/html"> + <div class="wst-in-title colour{{ d.currPage }}" onclick="javascript:getGoodsList({{ d.catId }});"> + <div class="line"></div> + <div class="name"> + <p><span><i class="icon"></i>{{ d.catName }}</span></p> + </div> + </div> + {{# if(d.ads && d.ads.length>0){ }} + <div class="wst-in-adscats"> + <a href="{{ d.ads[0].adURL }}"><img src="__IMGURL__/{{ d.ads[0].adFile }}" /></a> + </div> + {{# } }} {{# if(d.goods.length>0){ }} {{# for(var i=0; i + <d.goods.length; i++){ }} <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}" /></a> + </div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});">{{ d.goods[i].goodsName }}</div> + <div class="info"><span class="price">¥ <span>{{ d.goods[i].shopPrice }}</span></span></div> + <p class="lxy_p">惠宝抵扣价<span class="price">¥ <span>{{Math.round (d.goods[i].shopPrice *0.8)}}</span></span></p> + <div class="info2"><span class="price">好评率{{ d.goods[i].praiseRate }}</span><span class="deal">成交数:{{ d.goods[i].saleNum }}</span></div> + </div> + {{# } }} {{# } }} + <div class="wst-clear"></div> +</script> +{/block} {block name="include"} {include file="default/goods_search" /} {/block} {block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/index.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/index2.html b/hyhproject/mobile2/view/default/index2.html new file mode 100755 index 0000000..2c14ed1 --- /dev/null +++ b/hyhproject/mobile2/view/default/index2.html @@ -0,0 +1,408 @@ +{extend name="default/base" /} {block name="title"}首页 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/index.css?v={$v}"> {/block} {block name="header"} +<link rel="stylesheet" href="__MOBILE__/css/index-lxy.css" /> + +<!--<header class="ui-hea.der ui-header-positive wst-in-header1" id="j-header">--> +<!--头部--> +</header> +<!--<div class="wst-in-icon" id="j-icon"> + //商城头部左右两边的按钮 2017/10/12 李晓阳 + <a href="{:url('mobile/goodscats/index')}"><span class="cats"></a></span> + <span onclick="location.href='{:url('mobile/messages/index')}'" class="news">{if($news['message']['num']>0)}<i class="wst-in-num">{$news['message']['num']}</i>{/if}</span> +</div> --> +<div class="wst-in-search1 search1" id="j-search"> + <span class="seleft"></span> + <!--<form action= "" class="input-form">--><input id="wst-search" type="search" placeholder="请输入关键词" onsearch="WST.search(0)" autocomplete="off"><!--</form>--><span class="seright"></span> + <!--<p></p>--><span style="z-index: 1;" class="ui-icon-search" onclick="javascript:WST.search(0);"></span> +</div> + +{/block} {block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + {wst:ads code="mo-ads-index" cache='86400'} + <li class="advert1"><span><a href="{$vo.adURL}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(0)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img width='56' src="__ROOT__/{$btn['btnImg']}" style='margin-top:7px;' /></p> + <span>{$btn['btnName']}</span> + </a> + </div> + {/volist} + </div> + <!--<div class="wst-in-news-lxy"> + <div class="wst-in-news"> + <span class="new"><img src="__MOBILE__/img/huiyuankuaibao.png"/></span> + <marquee scrollamount='3' behavior='right'>{wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>{/wst:article}</marquee> + <span class="more" onclick="location.href='{:url('mobile/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div>--> + <div class="msg clearfix"> + <img src="__MOBILE__/img/huiyuankuaibao.png" /> + <p>热</p> + <marquee behavior="" direction="">图书音像勋章日!每天10点限量...</marquee> + <p class="msg_more">丨 更多</p> + </div> + + <div class="time"> + <div class="time_title clearfix"> + <img src="__MOBILE__/img/huiyuanmiaosha.png" /> + <!--<p>距活动结束</p>--> + <div class="count clearfix"> + <div class="h"></div> + <!--<o>:</o> + <div class="m">55</div> + <o>:</o> + <div class="s">05</div>--> + </div> + <div class="jxyh">精选优惠<img src="__MOBILE__/img/jxyh.png" alt="" /></div> + </div> + <div class="time_con"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhma" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhmb" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhmc" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhmd" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhme" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-jxhmf" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + <p>¥299</p> + <del>¥299</del> + </div> + + </div> + </div> + </div> + + </div> + <div class="box clearfix"> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/faxianhaohuo1.png" /> + <p>发现品质生活</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-fxhh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huiyuanzhuanhui1.png" /> + <p>叫你买买买</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hyzj" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/paihangbang.png" /> + <p>专属你的购物指南</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phb" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huigou.png" /> + <p>上班啦 惠购带你high</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/xinpinshoufa.png" /> + <p>iphone 8Plus 现货抢购中~</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-xpsf" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/shangxin.png" /> + <p>最新款式等你来</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-sx" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + + <div class="banner"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-pzss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-pzss1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + + <div class="pzss_title"> + <img src="__MOBILE__/img/pinzhishishang.png" /> + </div> + + <div class="pzss clearfix"> + + <div class="pzss1"> + <p class="p1">全球尖货</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">国际名牌</p> + <p class="p2">舒适出行</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">会逛</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hgg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">惠员拼购</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hypg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">品牌头条</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-pptt" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">奢侈大牌</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-scdp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">体育用品</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tyyp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">珠宝首饰</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-zmss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">环球时尚</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hqss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">买手甄选</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mszx" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + + <!-- 第二部分 --> + <div class="banner1 "> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-gsc" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-gsc1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/guangshangchang1.png" /> + </div> + <div class="pzss clearfix gss"> + + <div class="pzss1"> + <p class="p1">礼品馆</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-lpg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">手机数码</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phone" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">美食城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-meishi" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">电脑办公</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-diannao" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">鞋靴箱包</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xxxb" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">小家电馆</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xjdg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">海鲜</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-haixian" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">家装城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-jiazhua" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">图书音像</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tushu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">中外名酒</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mingjiu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="wst-in-adst"> + {wst:ads code="mo-index-large" cache='86400' num='4'} + <a class="advert2" href="{$vo.adURL}"> + <div class="adst"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /></div> + </a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="mo-index-small" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/cainixihuan.png" /> + </div> + <div id="goods-list"></div> + +</section> + +<script id="list" type="text/html"> + <!--<div class="wst-in-title colour{{ d.currPage }}" onclick="javascript:getGoodsList({{ d.catId }});">--> + <!--<div class="left"> + <p class="line1"></p><span></span> + <p class="line2"></p><span></span> + <p></p><span></span> + <p class="line2"></p><span></span> + <p class="line1"></p> + </div> + <div class="right"> + <p class="line1"></p><span></span> + <p class="line2"></p><span></span> + <p></p><span></span> + <p class="line2"></p><span></span> + <p class="line1"></p> + </div>{{ d.catName }}</div>--> + <!--<div class="pzss_title"> + <img src="__MOBILE__/img/cainixihuan.png" /> + </div>--> + {{# if(d.ads && d.ads.length>0){ }} + <div class="wst-in-adscats"> + <a href="{{ d.ads[0].adURL }}"><img src="__ROOT__/{{ d.ads[0].adFile }}" /></a> + </div> + {{# } }} {{# if(d.goods.length>0){ }} {{# for(var i=0; i + <d.goods.length; i++){ }} <div class="wst-in-goods"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}" /></a> + </div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"> + <p class="tuijian" style="display: inline-block;background: #ea4b47;color: #fff;border-radius: 5px;width:30px;margin-right: 5px;font-size: 12px;text-align: center;">自营</p>{{ d.goods[i].goodsName }}</div> + <div class="info"><span class="price">¥{{ d.goods[i].shopPrice }}</span><span class="deal">成交数:{{ d.goods[i].saleNum }}</span></div> + </div> + {{# } }} {{# } }} + <div class="wst-clear"></div> +</script> +{/block} {block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<!--<script type='text/javascript' src='__MOBILE__/js/swiper.min.js'></script>--> +<script type='text/javascript' src='__MOBILE__/js/index.js?v={$v}'></script> +<script type='text/javascript' src='__MOBILE__/js/index-lxy.js?v={$v}'></script> + +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/index3.html b/hyhproject/mobile2/view/default/index3.html new file mode 100755 index 0000000..6d206d1 --- /dev/null +++ b/hyhproject/mobile2/view/default/index3.html @@ -0,0 +1,395 @@ +{extend name="default/base" /} {block name="title"}首页 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/index.css?v={$v}"> {/block} {block name="header"} +<link rel="stylesheet" href="__MOBILE__/css/index-lxy.css" /> + +<!--<header class="ui-hea.der ui-header-positive wst-in-header1" id="j-header">--> +<!--头部--> +</header> +<!--<div class="wst-in-icon" id="j-icon"> + //商城头部左右两边的按钮 2017/10/12 李晓阳 + <a href="{:url('mobile/goodscats/index')}"><span class="cats"></a></span> + <span onclick="location.href='{:url('mobile/messages/index')}'" class="news">{if($news['message']['num']>0)}<i class="wst-in-num">{$news['message']['num']}</i>{/if}</span> +</div> --> +<div class="wst-in-search1 search1" id="j-search"> + <span class="seleft"></span> + <input id="wst-search" type="search" placeholder="请输入关键词" onsearch="WST.search(0)" autocomplete="off"><span class="seright"></span> + <!--<p></p>--><span style="z-index: 1;" class="ui-icon-search" onclick="javascript:WST.search(0);"></span> +</div> + +{/block} {block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + {wst:ads code="mo-ads-index" cache='86400'} + <li class="advert1"><span><a href="{$vo.adURL}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(0)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img width='56' src="__ROOT__/{$btn['btnImg']}" style='margin-top:7px;' /></p> + <span>{$btn['btnName']}</span> + </a> + </div> + {/volist} + </div> + <!--<div class="wst-in-news-lxy"> + <div class="wst-in-news"> + <span class="new"><img src="__MOBILE__/img/huiyuankuaibao.png"/></span> + <marquee scrollamount='3' behavior='right'>{wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>{/wst:article}</marquee> + <span class="more" onclick="location.href='{:url('mobile/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div>--> + <div class="msg clearfix"> + <img src="__MOBILE__/img/huiyuankuaibao.png" /> + <p>热</p> + <marquee scrollamount='3' behavior='right'> + {wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>&nbsp;&nbsp;&nbsp; + {/wst:article} + </marquee> + <p class="msg_more"><a href="{:url('mobile/news/view')}">丨 更多</a></p> + </div> + + <div class="time"> + <div class="time_title clearfix"> + <img src="__MOBILE__/img/huiyuanmiaosha.png" /> + <!--<p>距活动结束</p>--> + <div class="count clearfix"> + <div class="h"></div> + <!--<o>:</o> + <div class="m">55</div> + <o>:</o> + <div class="s">05</div>--> + </div> + <a href="/addon/hyhsale-goods-molists"><div class="jxyh">精选优惠<img src="__MOBILE__/img/jxyh.png" alt="" /></div></a> + </div> + {:hook('indexGetSale')} + + + </div> + <div class="box clearfix"> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/faxianhaohuo1.png" /> + <p>发现品质生活</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-fxhh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huiyuanzhuanhui1.png" /> + <p>叫你买买买</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hyzj" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/paihangbang.png" /> + <p>专属你的购物指南</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phb" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huigou.png" /> + <p>上班啦 惠购带你high</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/xinpinshoufa.png" /> + <p>iphone 8Plus 现货抢购中~</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-xpsf" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/shangxin.png" /> + <p>最新款式等你来</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-sx" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + + <div class="banner"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-pzss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-pzss1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + + <div class="pzss_title"> + <img src="__MOBILE__/img/pinzhishishang.png" /> + </div> + + <div class="pzss clearfix"> + + <div class="pzss1"> + <p class="p1">全球尖货</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">国际名牌</p> + <p class="p2">舒适出行</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">会逛</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hgg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">惠员拼购</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hypg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">品牌头条</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-pptt" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">奢侈大牌</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-scdp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">体育用品</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tyyp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">珠宝首饰</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-zmss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">环球时尚</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hqss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">买手甄选</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mszx" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + + <!-- 第二部分 --> + <div class="banner1 "> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-gsc" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-gsc1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/guangshangchang1.png" /> + </div> + <div class="pzss clearfix gss"> + + <div class="pzss1"> + <p class="p1">礼品馆</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-lpg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">手机数码</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phone" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">美食城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-meishi" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">电脑办公</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-diannao" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">鞋靴箱包</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xxxb" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">小家电馆</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xjdg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">海鲜</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-haixian" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">家装城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-jiazhua" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">图书音像</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tushu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">中外名酒</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mingjiu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="wst-in-adst"> + {wst:ads code="mo-index-large" cache='86400' num='4'} + <a class="advert2" href="{$vo.adURL}"> + <div class="adst"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /></div> + </a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="mo-index-small" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/cainixihuan.png" /> + </div> + <div id="goods-list"></div><br /><br /> + +</section> + +<script id="list" type="text/html"> + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i< d.goods.length; i++){ }} + <div class="wst-in-goods"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}" /></a> + </div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"> + <p class="tuijian" style="display: inline-block;background: #ea4b47;color: #fff;border-radius: 5px;width:30px;margin-right: 5px;font-size: 12px;text-align: center;">自营</p>{{ d.goods[i].goodsName }} + </div> + <div class="info"> + <span class="price">¥{{ d.goods[i].shopPrice }}</span> + <span class="deal">成交数:{{ d.goods[i].saleNum }}</span> + </div> + </div> + {{# } }} + {{# } }} + <div class="wst-clear"></div> +</script> +{/block} {block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<!--<script type='text/javascript' src='__MOBILE__/js/swiper.min.js'></script>--> +<script type='text/javascript' src='__MOBILE__/js/index.js?v={$v}'></script> +<script type='text/javascript' src='__MOBILE__/js/index-lxy.js?v={$v}'></script> +<script type="text/javascript"> + /** + * 秒杀模块倒计时 + * */ + function GetRTime(end_time){ + var NowTime = new Date(); + var t = (end_time*1000) - NowTime.getTime(); + var d=Math.floor(t/1000/60/60/24); + var h=Math.floor(t/1000/60/60%24); + var m=Math.floor(t/1000/60%60); + var s=Math.floor(t/1000%60); + if(s >= 0) + return (d * 24 + h) + '时' + m + '分' +s+'秒'; + } + function GetRTime2(){ + var myDate = new Date(); + var timestamp = Date.parse(myDate); + var hour = myDate.getHours(); //获取当前小时数(0-23) + //alert(hour); + if(timestamp >= ({$end_time}*1000) || hour < 8){ + //alert(timestamp); + //alert({$end_time}); + if(hour < 8){ + start_time = {$start_time}; + }else{ + start_time = {$start_time+86400}; + } + var text = GetRTime(start_time);// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距开始'+text); + } + + }else{ + var text = GetRTime('{$end_time}');// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距结束'+text); + } + } + } + setInterval(GetRTime2,1000); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/index┤°╧▐╩▒├ы╔▒.html b/hyhproject/mobile2/view/default/index┤°╧▐╩▒├ы╔▒.html new file mode 100755 index 0000000..4856022 --- /dev/null +++ b/hyhproject/mobile2/view/default/index┤°╧▐╩▒├ы╔▒.html @@ -0,0 +1,381 @@ +{extend name="default/base" /} {block name="title"}首页 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/index.css?v={$v}"> {/block} {block name="header"} +<link rel="stylesheet" href="__MOBILE__/css/index-lxy.css" /> + +<!--<header class="ui-hea.der ui-header-positive wst-in-header1" id="j-header">--> +<!--头部--> +</header> +<!--<div class="wst-in-icon" id="j-icon"> + //商城头部左右两边的按钮 2017/10/12 李晓阳 + <a href="{:url('mobile/goodscats/index')}"><span class="cats"></a></span> + <span onclick="location.href='{:url('mobile/messages/index')}'" class="news">{if($news['message']['num']>0)}<i class="wst-in-num">{$news['message']['num']}</i>{/if}</span> +</div> --> +<div class="wst-in-search1 search1" id="j-search"> + <span class="seleft"></span> + <input id="wst-search" type="search" placeholder="请输入关键词" onsearch="WST.search(0)" autocomplete="off"><span class="seright"></span> + <span style="z-index: 1;" class="ui-icon-search" onclick="javascript:WST.search(0);"></span> +</div> + +{/block} {block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + {wst:ads code="mo-ads-index" cache='86400'} + <li class="advert1"><span><a href="{$vo.adURL}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(0)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img width='56' src="__IMGURL__/{$btn['btnImg']}" style='margin-top:7px;' /></p> + <span>{$btn['btnName']}</span> + </a> + </div> + {/volist} + </div> + <!--<div class="wst-in-news-lxy"> + <div class="wst-in-news"> + <span class="new"><img src="__MOBILE__/img/huiyuankuaibao.png"/></span> + <marquee scrollamount='3' behavior='right'>{wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>{/wst:article}</marquee> + <span class="more" onclick="location.href='{:url('mobile/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div>--> + <div class="msg clearfix"> + <img src="__MOBILE__/img/huiyuankuaibao.png" /> + <p>热</p> + <marquee scrollamount='3' behavior='right'> + {wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>&nbsp;&nbsp;&nbsp; + {/wst:article} + </marquee> + <p class="msg_more"><a href="{:url('mobile/news/view')}">丨 更多</a></p> + </div> + + {:hook('indexGetSale')} + + + <div class="box clearfix"> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/faxianhaohuo1.png" /> + <p>发现品质生活</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-fxhh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huiyuanzhuanhui1.png" /> + <p>叫你买买买</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hyzj" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/paihangbang.png" /> + <p>专属你的购物指南</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phb" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huigou.png" /> + <p>上班啦 惠购带你high</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/xinpinshoufa.png" /> + <p>iphone 8Plus 现货抢购中~</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-xpsf" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/shangxin.png" /> + <p>最新款式等你来</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-sx" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + + <div class="banner"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-pzss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-pzss1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + + <div class="pzss_title"> + <img src="__MOBILE__/img/pinzhishishang.png" /> + </div> + + <div class="pzss clearfix"> + + <div class="pzss1"> + <p class="p1">全球尖货</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">国际名牌</p> + <p class="p2">舒适出行</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">会逛</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hgg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">惠员拼购</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hypg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">品牌头条</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-pptt" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">奢侈大牌</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-scdp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">体育用品</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tyyp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">珠宝首饰</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-zmss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">环球时尚</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hqss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">买手甄选</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mszx" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + + <!-- 第二部分 --> + <div class="banner1 "> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-gsc" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-gsc1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/guangshangchang1.png" /> + </div> + <div class="pzss clearfix gss"> + + <div class="pzss1"> + <p class="p1">礼品馆</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-lpg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">手机数码</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phone" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">美食城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-meishi" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">电脑办公</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-diannao" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">鞋靴箱包</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xxxb" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">小家电馆</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xjdg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">海鲜</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-haixian" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">家装城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-jiazhua" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">图书音像</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tushu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">中外名酒</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mingjiu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="wst-in-adst"> + {wst:ads code="mo-index-large" cache='86400' num='4'} + <a class="advert2" href="{$vo.adURL}"> + <div class="adst"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /></div> + </a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="mo-index-small" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/cainixihuan.png" /> + </div> + <div id="goods-list"></div><br /><br /> + +</section> + +<script id="list" type="text/html"> + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i< d.goods.length; i++){ }} + <div class="wst-in-goods"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}" /></a> + </div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"> + <p class="tuijian" style="display: inline-block;background: #ea4b47;color: #fff;border-radius: 5px;width:30px;margin-right: 5px;font-size: 12px;text-align: center;">自营</p>{{ d.goods[i].goodsName }} + </div> + <div class="info"> + <span class="price">¥{{ d.goods[i].shopPrice }}</span> + <span class="deal">成交数:{{ d.goods[i].saleNum }}</span> + </div> + </div> + {{# } }} + {{# } }} + <div class="wst-clear"></div> +</script> +{/block} {block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<!--<script type='text/javascript' src='__MOBILE__/js/swiper.min.js'></script>--> +<script type='text/javascript' src='__MOBILE__/js/index.js?v={$v}'></script> +<script type='text/javascript' src='__MOBILE__/js/index-lxy.js?v={$v}'></script> +<script type="text/javascript"> + /** + * 秒杀模块倒计时 + * */ + function GetRTime(end_time){ + var NowTime = new Date(); + var t = (end_time*1000) - NowTime.getTime(); + var d=Math.floor(t/1000/60/60/24); + var h=Math.floor(t/1000/60/60%24); + var m=Math.floor(t/1000/60%60); + var s=Math.floor(t/1000%60); + if(s >= 0) + return (d * 24 + h) + '时' + m + '分' +s+'秒'; + } + function GetRTime2(){ + var myDate = new Date(); + var timestamp = Date.parse(myDate); + var hour = myDate.getHours(); //获取当前小时数(0-23) + //alert(hour); + if(timestamp >= ({$end_time}*1000) || hour < 8){ + //alert(timestamp); + //alert({$end_time}); + if(hour < 8){ + start_time = {$start_time}; + }else{ + start_time = {$start_time+86400}; + } + var text = GetRTime(start_time);// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距开始'+text); + } + + }else{ + var text = GetRTime('{$end_time}');// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距结束'+text); + } + } + } + setInterval(GetRTime2,1000); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/index鈹ぢ扳暓鈻愨暕鈻掆敎褘鈺斺枓.html b/hyhproject/mobile2/view/default/index鈹ぢ扳暓鈻愨暕鈻掆敎褘鈺斺枓.html new file mode 100755 index 0000000..7f0e4a2 --- /dev/null +++ b/hyhproject/mobile2/view/default/index鈹ぢ扳暓鈻愨暕鈻掆敎褘鈺斺枓.html @@ -0,0 +1,381 @@ +{extend name="default/base" /} {block name="title"}首页 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/index.css?v={$v}"> {/block} {block name="header"} +<link rel="stylesheet" href="__MOBILE__/css/index-lxy.css" /> + +<!--<header class="ui-hea.der ui-header-positive wst-in-header1" id="j-header">--> +<!--头部--> +</header> +<!--<div class="wst-in-icon" id="j-icon"> + //商城头部左右两边的按钮 2017/10/12 李晓阳 + <a href="{:url('mobile/goodscats/index')}"><span class="cats"></a></span> + <span onclick="location.href='{:url('mobile/messages/index')}'" class="news">{if($news['message']['num']>0)}<i class="wst-in-num">{$news['message']['num']}</i>{/if}</span> +</div> --> +<div class="wst-in-search1 search1" id="j-search"> + <span class="seleft"></span> + <input id="wst-search" type="search" placeholder="请输入关键词" onsearch="WST.search(0)" autocomplete="off"><span class="seright"></span> + <span style="z-index: 1;" class="ui-icon-search" onclick="javascript:WST.search(0);"></span> +</div> + +{/block} {block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + {wst:ads code="mo-ads-index" cache='86400'} + <li class="advert1"><span><a href="{$vo.adURL}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(0)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img width='56' src="__IMGURL__/{$btn['btnImg']}" style='margin-top:7px;' /></p> + <span>{$btn['btnName']}</span> + </a> + </div> + {/volist} + </div> + <!--<div class="wst-in-news-lxy"> + <div class="wst-in-news"> + <span class="new"><img src="__MOBILE__/img/huiyuankuaibao.png"/></span> + <marquee scrollamount='3' behavior='right'>{wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>{/wst:article}</marquee> + <span class="more" onclick="location.href='{:url('mobile/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div>--> + <div class="msg clearfix"> + <img src="__MOBILE__/img/huiyuankuaibao.png" /> + <p>热</p> + <marquee scrollamount='3' behavior='right'> + {wst:article cat="new" num='6' cache='86400'} + <a href="{:url('mobile/news/view',['articleId'=>$vo['articleId']])}">{$vo['articleTitle']}。</a>&nbsp;&nbsp;&nbsp; + {/wst:article} + </marquee> + <p class="msg_more"><a href="{:url('mobile/news/view')}">丨 更多</a></p> + </div> + + {:hook('indexGetSale')} + + + <div class="box clearfix"> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/faxianhaohuo1.png" /> + <p>发现品质生活</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-fxhh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huiyuanzhuanhui1.png" /> + <p>叫你买买买</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hyzj" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/paihangbang.png" /> + <p>专属你的购物指南</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phb" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/huigou.png" /> + <p>上班啦 惠购带你high</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-hg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1"> + <img class="img" src="__MOBILE__/img/xinpinshoufa.png" /> + <p>iphone 8Plus 现货抢购中~</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-xpsf" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="box_1 box2"> + <img class="img" src="__MOBILE__/img/shangxin.png" /> + <p>最新款式等你来</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-sx" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + + <div class="banner"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-pzss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-pzss1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + + <div class="pzss_title"> + <img src="__MOBILE__/img/pinzhishishang.png" /> + </div> + + <div class="pzss clearfix"> + + <div class="pzss1"> + <p class="p1">全球尖货</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">国际名牌</p> + <p class="p2">舒适出行</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-qqjh" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">会逛</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hgg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">惠员拼购</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hypg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">品牌头条</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-pptt" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">奢侈大牌</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-scdp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">体育用品</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tyyp" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">珠宝首饰</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-zmss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">环球时尚</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-hqss" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">买手甄选</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mszx" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + + <!-- 第二部分 --> + <div class="banner1 "> + <div class="swiper-container"> + <div class="swiper-wrapper"> + <div class="swiper-slide"> + {wst:ads code="mo-ads-index-gsc" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + + <div class="swiper-slide">{wst:ads code="mo-ads-index-gsc1" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/guangshangchang1.png" /> + </div> + <div class="pzss clearfix gss"> + + <div class="pzss1"> + <p class="p1">礼品馆</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-lpg" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss1 pzss2"> + <p class="p1">手机数码</p> + <p class="p2">世界幸福家</p> + <div class="boxcon clearfix"> + {wst:ads code="mo-ads-index-phone" cache='86400' num='2'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + </div> + <div class="pzss3"> + <p class="p1">美食城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-meishi" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">电脑办公</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-diannao" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">鞋靴箱包</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xxxb" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">小家电馆</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-xjdg" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">海鲜</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-haixian" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">家装城</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-jiazhua" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3"> + <p class="p1">图书音像</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-tushu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="pzss3 pzss4"> + <p class="p1">中外名酒</p> + <p class="p2">世界幸福家</p> + {wst:ads code="mo-ads-index-mingjiu" cache='86400' num='1'} + <img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /> {/wst:ads} + </div> + <div class="wst-in-adst"> + {wst:ads code="mo-index-large" cache='86400' num='4'} + <a class="advert2" href="{$vo.adURL}"> + <div class="adst"><img src="__IMGURL__/{:WSTImg($vo.adFile,2)}" /></div> + </a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="mo-index-small" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div class="pzss_title"> + <img src="__MOBILE__/img/cainixihuan.png" /> + </div> + <div id="goods-list"></div><br /><br /> + +</section> + +<script id="list" type="text/html"> + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i< d.goods.length; i++){ }} + <div class="wst-in-goods"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}" /></a> + </div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"> + <p class="tuijian" style="display: inline-block;background: #ea4b47;color: #fff;border-radius: 5px;width:30px;margin-right: 5px;font-size: 12px;text-align: center;">自营</p>{{ d.goods[i].goodsName }} + </div> + <div class="info"> + <span class="price">¥{{ d.goods[i].shopPrice }}</span> + <span class="deal">成交数:{{ d.goods[i].saleNum }}</span> + </div> + </div> + {{# } }} + {{# } }} + <div class="wst-clear"></div> +</script> +{/block} {block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<!--<script type='text/javascript' src='__MOBILE__/js/swiper.min.js'></script>--> +<script type='text/javascript' src='__MOBILE__/js/index.js?v={$v}'></script> +<script type='text/javascript' src='__MOBILE__/js/index-lxy.js?v={$v}'></script> +<script type="text/javascript"> + /** + * 秒杀模块倒计时 + * */ + function GetRTime(end_time){ + var NowTime = new Date(); + var t = (end_time*1000) - NowTime.getTime(); + var d=Math.floor(t/1000/60/60/24); + var h=Math.floor(t/1000/60/60%24); + var m=Math.floor(t/1000/60%60); + var s=Math.floor(t/1000%60); + if(s >= 0) + return (d * 24 + h) + '时' + m + '分' +s+'秒'; + } + function GetRTime2(){ + var myDate = new Date(); + var timestamp = Date.parse(myDate); + var hour = myDate.getHours(); //获取当前小时数(0-23) + //alert(hour); + if(timestamp >= ({$end_time}*1000) || hour < 8){ + //alert(timestamp); + //alert({$end_time}); + if(hour < 8){ + start_time = {$start_time}; + }else{ + start_time = {$start_time+86400}; + } + var text = GetRTime(start_time);// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距开始'+text); + } + + }else{ + var text = GetRTime('{$end_time}');// alert({$end_time}); + if (text== 0){ + $(".h").text('活动已结束'); + }else{ + $(".h").text('距结束'+text); + } + } + } + setInterval(GetRTime2,1000); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/brands.js b/hyhproject/mobile2/view/default/js/brands.js new file mode 100755 index 0000000..629387c --- /dev/null +++ b/hyhproject/mobile2/view/default/js/brands.js @@ -0,0 +1,42 @@ +//商品列表页 +function getGoodsList(brandId){ + location.href = WST.U('mobile/goods/lists','brandId='+brandId,true); +} +//获取品牌列表 +function brandsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 16; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/brands/pageQuery'), param,function(data){ + var json = WST.toJson(data); + if(json && json.Rows && json.Rows.length>0){ + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#info-list').append(html); + }); + echo.init();//图片懒加载 + } + loading = false; + $('#Load').hide(); + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + brandsList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + brandsList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/carts.js b/hyhproject/mobile2/view/default/js/carts.js new file mode 100755 index 0000000..f2da43b --- /dev/null +++ b/hyhproject/mobile2/view/default/js/carts.js @@ -0,0 +1,190 @@ +var promotionMethod = {}; +$(document).ready(function(){ + WST.initFooter('cart'); + WST.imgAdapt('j-imgAdapt'); + + statCartMoney(); + //选中店铺 + $('.ui-icon-chooses').click(function(){ + WST.changeIconStatus($(this), 1); + var childrenId = $(this).attr('childrenId'); + var goodsCount = $('.'+childrenId).length;//商品个数 + var ids = []; + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + WST.changeIconStatus($('.'+childrenId), 2);//选中 + for(var i=0; i<goodsCount; i++){ + var cid = $('.'+childrenId).eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),0); + }else{ + WST.changeIconStatus($('.'+childrenId), 2, 'wst-active');//取消选中 + for(var i=0; i<goodsCount; i++){ + var cid = $('.'+childrenId).eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),1); + } + statCartMoney(); + }); + //选中商品 + $('.ui-icon-chooseg').click(function(){ + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + var checked = 1; + WST.changeIconStatus($(this), 1);//选中 + }else{ + var checked = 0; + WST.changeIconStatus($(this), 2);//取消选中 + } + var cid = $(this).attr('cartId'); + if(cid!=''){ + WST.changeCartGoods(cid,$('#buyNum_'+cid).val(),checked); + statCartMoney(); + } + }); + //选中合计 + $('.ui-icon-choose').click(function(){ + WST.changeIconStatus($(this), 1); + var shopIconCount = $('.ui-icon-chooses').length;//店铺个数 + var goodsCount = $('.ui-icon-chooseg').length;//商品个数 + var ids = []; + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + //选中所有 + for(var i=0; i<shopIconCount; i++){ + WST.changeIconStatus($('.ui-icon-chooses').eq(i), 2); + } + for(var i=0; i<goodsCount; i++){ + WST.changeIconStatus($('.ui-icon-chooseg').eq(i), 2); + var cid = $('.ui-icon-chooseg').eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),0); + }else{ + //取消选中所有 + for(var i=0; i<shopIconCount; i++){ + WST.changeIconStatus($('.ui-icon-chooses').eq(i), 2, 'wst-active'); + } + for(var i=0; i<goodsCount; i++){ + WST.changeIconStatus($('.ui-icon-chooseg').eq(i), 2, 'wst-active'); + var cid = $('.ui-icon-chooseg').eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),1); + } + statCartMoney(); + }); +}); +//合计 +function statCartMoney(){ + var cartMoney = 0,goodsTotalPrice,id; + $('.wst-active').each(function(){ + id = $(this).attr('cartId'); + goodsTotalPrice = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + cartMoney = cartMoney + goodsTotalPrice; + }); + for(var i=1; i<$('#totalshop').val(); i++){ + var shopMoney = 0,goodsTotalPrice2; + $('.clist'+i).each(function(){ + id = $(this).attr('cartId'); + goodsTotalPrice2 = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + shopMoney = shopMoney + goodsTotalPrice2; + }); + $('#tprice_'+i).html('<span>¥ </span>'+shopMoney.toFixed(2)); + } + + /* 满就送 */ + var minusMoney = 0; + for(var key in promotionMethod){ + minusMoney = window[key](cartMoney); + cartMoney = cartMoney - minusMoney; + } + $('#totalMoney').html('<span>¥ </span>'+cartMoney.toFixed(2)); + checkGoodsBuyStatus(); +} +function checkGoodsBuyStatus(){ + var cartNum = 0,stockNum = 0,cartId = 0; + $('.wst-active').each(function(){ + cartId = $(this).attr('cartId'); + cartNum = parseInt($('#buyNum_'+cartId).val(),10); + stockNum = parseInt($('#buyNum_'+cartId).attr('data-max'),10); + if(stockNum < 0 || stockNum < cartNum){ + if(stockNum < 0){ + msg = '库存不足'; + }else{ + msg = '购买量超过库存'; + } + $('#noprompt'+cartId).show().html(msg); + $(this).parent().parent().addClass('nogoods'); + WST.changeIconStatus($(this), 2);//取消选中 + WST.changeCartGoods(cartId,$('#buyNum_'+cartId).val(),0); + statCartMoney(); + }else{ + $('#noprompt'+cartId).hide().html(''); + $(this).parent().parent().removeClass('nogoods'); + } + }); +} +//编辑 +function edit(type){ + if(type==0){ + WST.showHide('','#edit,#settlement,#total'); + WST.showHide(1,'#complete,#delete'); + }else{ + WST.showHide('','#complete,#delete'); + WST.showHide(1,'#edit,#settlement,#total'); + } +} +//删除 +function deletes(){ + var goodsIds = ''; + var goodsIconCount = $('.ui-icon-chooseg').length;//商品个数 + for(var i=0; i<goodsIconCount; i++){ + if( $('.ui-icon-chooseg').eq(i).attr('class').indexOf('wst-active') != -1 ){ + goodsIds += $('.ui-icon-chooseg').eq(i).attr('cartId') + ','; + } + } + if(goodsIds!=''){ + WST.dialog('确定删除选中的商品吗?','del("'+goodsIds+'")'); + }else{ + WST.msg('请选择要删除的商品','info'); + } +} +function del(goodsIds){ + $.post(WST.U('mobile/carts/delCart'),{id:goodsIds},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + WST.dialogHide('prompt'); + setTimeout(function(){ + location.href = WST.U('mobile/carts/index'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + } + }); +} +//结算 +function toSettlement(){ + var goodsIconCount = $('.ui-icon-chooseg').length;//商品个数 + var noGoodsSelected = true; + for(var i=0; i<goodsIconCount; i++){ + if( $('.ui-icon-chooseg').eq(i).attr('class').indexOf('wst-active') != -1 ){ + noGoodsSelected = false; + } + } + if(noGoodsSelected){ + WST.msg('请勾选要结算的商品','info'); + return false; + } + location.href = WST.U('mobile/carts/settlement'); +} +//导航 +function inMore(){ + if($("#arrow").css("display")=='none'){ + $("#arrow").show(); + $("#layer").show(); + }else{ + $("#arrow").hide(); + $("#layer").hide(); + } +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/common.js b/hyhproject/mobile2/view/default/js/common.js new file mode 100755 index 0000000..1b54bfe --- /dev/null +++ b/hyhproject/mobile2/view/default/js/common.js @@ -0,0 +1,484 @@ +var WST = WST?WST:{}; +WST.wxv = '2.0_0825'; +WST.toJson = function(str,notLimit){ + var json = {}; + if(str){ + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(!notLimit){ + if(json.status && json.status=='-999'){ + WST.inLogin(); + } + } + }catch(e){ + alert("系统发生错误:"+e.getMessage); + json = {}; + } + return json; + }else{ + return; + } +} +//登录 +WST.inLogin = function(){ + var urla = window.location.href; + $.post(WST.U('mobile/index/sessionAddress'),{url:urla},function(data,textStatus){}); + var url = WST.U('mobile/users/login',true); + window.location.href = url; +} +//底部的tab +WST.initFooter = function(tab){ + var homeImage = (tab=='home') ? 'home-active' : 'home'; + var categoryImage = (tab=='category') ? 'category-active' : 'category'; + var cartImage = (tab=='cart') ? 'cart-active' : 'cart'; + var followImage = (tab=='brand') ? 'follow-active' : 'follow'; + var usersImage = (tab=='user') ? 'user-active' : 'user'; + $('#home').append('<span class="icon '+homeImage+'"></span><span class="'+homeImage+'-word">首页</span>'); + $('#category').append('<span class="icon '+categoryImage+'"></span><span class="'+categoryImage+'-word">分类</span>'); + $('#cart').prepend('<span class="icon '+cartImage+'"></span><span class="'+cartImage+'-word">购物车</span>'); + $('#follow').append('<span class="icon '+followImage+'"></span><span class="'+followImage+'-word">关注</span>'); + $('#user').append('<span class="icon '+usersImage+'"></span><span class="'+usersImage+'-word">我的</span>'); +} +//变换选中框的状态 +WST.changeIconStatus = function (obj, toggle, status){ + if(toggle==1){ + if( obj.attr('class').indexOf('ui-icon-unchecked-s') > -1 ){ + obj.removeClass('ui-icon-unchecked-s').addClass('ui-icon-success-block wst-active'); + }else{ + obj.removeClass('ui-icon-success-block wst-active').addClass('ui-icon-unchecked-s'); + } + }else if(toggle==2){ + if(status == 'wst-active'){ + obj.removeClass('ui-icon-unchecked-s').addClass('ui-icon-success-block wst-active'); + }else{ + obj.removeClass('ui-icon-success-block wst-active').addClass('ui-icon-unchecked-s'); + } + } +} +WST.changeIptNum = function(diffNum,iptId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + if(maxVal<=num)num=maxVal; + if(num<=minVal)num=minVal; + if(num==0)num=1; + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('mobile/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,'info'); + } + }); +} +// 批量修改购物车状态 +WST.batchChangeCartGoods = function(ids,isCheck){ + $.post(WST.U('mobile/carts/batchChangeCartGoods'),{ids:ids,isCheck:isCheck},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,'info'); + } + }); +} +//商品主页 +WST.intoGoods = function(id){ + location.href = WST.U('mobile/goods/detail','goodsId='+id,true); +}; +//店铺主页 +WST.intoShops = function(id){ + location.href = WST.U('mobile/shops/home','shopId='+id,true); +}; +//首页 +WST.intoIndex = function(){ + location.href = WST.U('mobile/index/index',true); +}; +//搜索 +WST.searchPage = function(type,state){ + if(state==1){ + $("#wst-"+type+"-search").show(); + }else{ + $("#wst-"+type+"-search").hide(); + } +}; +WST.search = function(type){ + var data = $('#wst-search').val(); + if(type==1){ + location.href = WST.U('mobile/shops/shopstreet','keyword='+data,true);//店铺 + }else if(type==0){ + location.href = WST.U('mobile/goods/lists','keyword='+data,true);//商品 + }else if(type==2){ + var shopId = $('#shopId').val(); + location.href = WST.U('mobile/shops/shopgoodslist','goodsName='+data+'&shopId='+shopId,true);//店铺商品 + } +}; +//关注 +WST.favorites = function(sId,type){ + $.post(WST.U('mobile/favorites/add'),{id:sId,type:type},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + if(type==1){ + $('#fStatus').html('已关注'); + $('#fBtn').attr('onclick','WST.cancelFavorite('+json.data.fId+',1)'); + $('.j-shopfollow').addClass('follow'); + $('#followNum').html(parseInt($('#followNum').html())+1); + }else{ + $('.imgfollow').removeClass('nofollow').addClass('follow'); + $('.imgfollow').attr('onclick','WST.cancelFavorite('+json.data.fId+',0)'); + } + }else{ + WST.msg(json.msg,'info'); + } + }) +} +// 取消关注 +WST.cancelFavorite = function(fId,type){ + $.post(WST.U('mobile/favorites/cancel'),{id:fId,type:type},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + if(type==1){ + $('#fStatus').html('关注店铺'); + $('#fBtn').attr('onclick','WST.favorites('+$('#shopId').val()+',1)'); + $('.j-shopfollow').removeClass('follow'); + $('#followNum').html(parseInt($('#followNum').html())-1); + }else{ + $('.imgfollow').removeClass('follow').addClass('nofollow'); + $('.imgfollow').attr('onclick','WST.favorites('+$('#goodsId').val()+',0)'); + } + }else{ + WST.msg(json.msg,'info'); + } + }); +} +//刷新验证码 +WST.getVerify = function(id){ + $(id).attr('src',WST.U('mobile/index/getVerify','rnd='+Math.random())); +} +//返回当前页面高度 +WST.pageHeight = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientHeight : + document.body.clientHeight; + }else{ + return self.innerHeight; + } +}; +//返回当前页面宽度 +WST.pageWidth = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientWidth : + document.body.clientWidth; + }else{ + return self.innerWidth; + } +}; +WST.checkBrowser = function(){ + return { + mozilla : /firefox/.test(navigator.userAgent.toLowerCase()), + webkit : /webkit/.test(navigator.userAgent.toLowerCase()), + opera : /opera/.test(navigator.userAgent.toLowerCase()), + msie : /msie/.test(navigator.userAgent.toLowerCase()) + } +} +//只能輸入數字 +WST.isNumberKey = function(evt){ + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && (charCode < 48 || charCode > 57)){ + return false; + }else{ + return true; + } +} +WST.isChinese = function(obj,isReplace){ + var pattern = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/i + if(pattern.test(obj.value)){ + if(isReplace)obj.value=obj.value.replace(/[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/ig,""); + return true; + } + return false; +} +//适应图片大小正方形 +WST.imgAdapt = function(name){ + var w = $('.'+name).width(); + $('.'+name).css({"width": w+"px","height": w+"px"}); + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"max-width": w+"px","max-height": w+"px"}); +} +//显示隐藏 +WST.showHide = function(t,str){ + var s = str.split(','); + if(t){ + for(var i=0;i<s.length;i++){ + $(s[i]).show(); + } + }else{ + for(var i=0;i<s.length;i++){ + $(s[i]).hide(); + } + } + s = null; +} +/** + * 提示信息 + * @param content 内容 + * @param type info/普通,success/成功,warn/错误 + * @param stayTime 显示时间 + */ +WST.msg = function(content,type,stayTime){ + if(!stayTime){ + stayTime = '1200'; + } + var el = $.tips({content:content,type:type,stayTime:stayTime}); + return el; +} +//提示对话框 +WST.dialog = function(content,event){ + $("#wst-dialog").html(content); + $("#wst-event2").attr("onclick","javascript:"+event); + $("#wst-di-prompt").dialog("show"); +} +//提示分享对话框 +WST.share = function(){ + $("#wst-di-share").dialog("show"); +} +/** + * 隐藏对话框 + * @param event prompt/提示对话框 + * @param event share/提示对话框 + */ +WST.dialogHide = function(event){ + $("#wst-di-"+event).dialog("hide"); +} +//加载中 +WST.load = function(content){ + $('#Loadl').css('display','-webkit-box'); + $('#j-Loadl').html(content); +} +WST.noload = function(){ + $('#Loadl').css('display','none'); +} +//滚动到顶部 +WSTrunToTop = function (){ + currentPosition=document.documentElement.scrollTop || document.body.scrollTop; + currentPosition-=20; + if(currentPosition>0){ + window.scrollTo(0,currentPosition); + } + else{ + window.scrollTo(0,0); + clearInterval(timer); + } +} +WST.inArray = function(str,arrs){ + if(typeof(arrs) != "object")return -1; + for(var i=0;i<arrs.length;i++){ + if(arrs[i]==str)return i; + } + return -1; +} + +WST.blank = function(str,defaultVal){ + if(str=='0000-00-00')str = ''; + if(str=='0000-00-00 00:00:00')str = ''; + if(!str)str = ''; + if(typeof(str)=='null')str = ''; + if(typeof(str)=='undefined')str = ''; + if(str=='' && defaultVal)str = defaultVal; + return str; +} + +/** +* 上传图片 +*/ +WST.upload = function(opts){ + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('mobile/orders/uploadPic')},opts); + var uploader = WebUploader.create(_opts); + uploader.on('uploadSuccess', function( file,response ) { + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + +//返回键 +function backPrevPage(url){ + window.location.hash = "ready"; + window.location.hash = "ok"; + setTimeout(function(){ + $(window).on('hashchange', function(e) { + var hashName = window.location.hash.replace('#', ''); + hashName = hashName.split('&'); + if( hashName[0] == 'ready' ){ + location.href = url; + } + }); + },50); +} + +//图片切换 +WST.replaceImg = function(v,str){ + var vs = v.split('.'); + return v.replace("."+vs[1],str+"."+vs[1]); +} + +$(function(){ + echo.init();//图片懒加载 + // 滚动到顶部 + $(window).scroll(function(){ + if( $(window).scrollTop() > 200 ){ + $('#toTop').show(); + }else{ + $('#toTop').hide(); + } + }); + $('#toTop').on('click', function() { + timer=setInterval("WSTrunToTop()",1); + }); + /** + * 获取WSTMart基础配置 + * @type {object} + */ + WST.conf = window.conf; + /* 基础对象检测 */ + WST.conf || $.error("WSTMart基础配置没有正确加载!"); + if(WST.conf.ROUTES)WST.conf.ROUTES = eval("("+WST.conf.ROUTES+")"); + /** + * 解析URL + * @param {string} url 被解析的URL + * @return {object} 解析后的数据 + */ + WST.parse_url = function(url){ + var parse = url.match(/^(?:([a-z]+):\/\/)?([\w-]+(?:\.[\w-]+)+)?(?::(\d+))?([\w-\/]+)?(?:\?((?:\w+=[^#&=\/]*)?(?:&\w+=[^#&=\/]*)*))?(?:#([\w-]+))?$/i); + parse || $.error("url格式不正确!"); + return { + "scheme" : parse[1], + "host" : parse[2], + "port" : parse[3], + "path" : parse[4], + "query" : parse[5], + "fragment" : parse[6] + }; + } + + WST.parse_str = function(str){ + var value = str.split("&"), vars = {}, param; + for(var i=0;i<value.length;i++){ + param = value[i].split("="); + vars[param[0]] = param[1]; + } + return vars; + } + WST.initU = function(url,vars){ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + var newUrl = WST.conf.ROUTES[url]; + var urlparams = newUrl.match(/<(\w+(\??))>/g); + urlparams = (urlparams==null)?[]:urlparams; + var tmpv = null; + for(var v in vars){ + tmpv = '<'+v+'>'; + if(WST.inArray(tmpv,urlparams)>-1){ + newUrl = newUrl.replace(tmpv,vars[v]); + delete vars[v]; + } + } + tmpv = urlparams = null; + if(false !== WST.conf.SUFFIX){ + newUrl += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')newUrl += "?"+tmp; + tmp = null; + } + //url = url.replace(new RegExp("%2F","gm"),"+"); + newUrl = WST.conf.APP + "/"+newUrl; + return newUrl; + } + + WST.U0 = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url), path = [], reg; + /* 验证info */ + info.path || $.error("url格式错误!"); + url = info.path; + /* 解析URL */ + path = url.split("/"); + path = [path.pop(), path.pop(), path.pop()].reverse(); + path[1] || $.error("WST.U(" + url + ")没有指定控制器"); + + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + /* 解析URL自带的参数 */ + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')url += "?"+tmp; + tmp = null; + } + //url = url.replace(new RegExp("%2F","gm"),"+"); + url = WST.conf.APP + "/"+url; + return url; + } + WST.U = function(url,vars){ + if(WST.conf.ROUTES && WST.conf.ROUTES[url]){ + return WST.initU(url,vars); + }else{ + return WST.U0(url, vars); + } + } + WST.AU = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url); + url = info.path; + path = url.split("/"); + url = "addon/"; + path = [path.pop(), path.pop()].reverse(); + path[0] || $.error("WST.AU(" + url + ")没有指定控制器"); + path[1] || $.error("WST.AU(" + url + ")没有指定接口"); + url = url + info.scheme + "-" + path.join('-'); + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')url += "?"+tmp; + tmp = null; + } + return WST.conf.APP + "/"+url; + } +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/common_xs.js b/hyhproject/mobile2/view/default/js/common_xs.js new file mode 100755 index 0000000..85af9c9 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/common_xs.js @@ -0,0 +1,38 @@ +//var num = 1 / window.devicePixelRatio; +document.querySelector('meta').setAttribute('name', 'viewport') +//document.querySelector('meta').setAttribute('content', 'width=device-width, initial-scale=' + num + ', maximum-scale=' + num + ', minimum-scale=' + num + ', user-scalable=no'); +document.querySelector('meta').setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no'); +browserRedirect(); +function browserRedirect(){ + var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + var width = w > h ? h : w; + var sUserAgent = navigator.userAgent.toLowerCase(); + var bIsIpad = sUserAgent.match(/ipad/i) == "ipad"; + var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os"; + var bIsMidp = sUserAgent.match(/midp/i) == "midp"; + var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4"; + var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb"; + var bIsAndroid = sUserAgent.match(/android/i) == "android"; + var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce"; + var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile"; + var bIsWX = sUserAgent.match(/MicroMessenger/i) == "micromessenger"; + // document.writeln("您的浏览设备为:"); + if(bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM || bIsWX) { + width = width; + // document.writeln("phone"); + } else { + width = 640; + // document.writeln("pc"); + } + var fz = ~~(width * 100000 / 64) / 10000; + document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz + "px"; + var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px', '') * 10000) / 10000 + if(fz !== realfz) { + document.getElementsByTagName("html")[0].style.cssText = 'font-size:' + fz * (fz / realfz) + "px"; + } +} + +//window.onresize = function(){ + //browserRedirect(); +//} diff --git a/hyhproject/mobile2/view/default/js/echo.min.js b/hyhproject/mobile2/view/default/js/echo.min.js new file mode 100755 index 0000000..ebcedda --- /dev/null +++ b/hyhproject/mobile2/view/default/js/echo.min.js @@ -0,0 +1,2 @@ +/*! echo.js v1.7.0 | (c) 2015 @toddmotto | https://github.com/toddmotto/echo */ +!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t)}):"object"==typeof exports?module.exports=e:t.echo=e(t)}(this,function(t){"use strict";var e,n,o,r,c,a={},d=function(){},u=function(t,e){var n=t.getBoundingClientRect();return n.right>=e.l&&n.bottom>=e.t&&n.left<=e.r&&n.top<=e.b},l=function(){(r||!n)&&(clearTimeout(n),n=setTimeout(function(){a.render(),n=null},o))};return a.init=function(n){n=n||{};var u=n.offset||0,i=n.offsetVertical||u,f=n.offsetHorizontal||u,s=function(t,e){return parseInt(t||e,10)};e={t:s(n.offsetTop,i),b:s(n.offsetBottom,i),l:s(n.offsetLeft,f),r:s(n.offsetRight,f)},o=s(n.throttle,250),r=n.debounce!==!1,c=!!n.unload,d=n.callback||d,a.render(),document.addEventListener?(t.addEventListener("scroll",l,!1),t.addEventListener("load",l,!1)):(t.attachEvent("onscroll",l),t.attachEvent("onload",l))},a.render=function(){for(var n,o,r=document.querySelectorAll("img[data-echo], [data-echo-background]"),l=r.length,i={l:0-e.l,t:0-e.t,b:(t.innerHeight||document.documentElement.clientHeight)+e.b,r:(t.innerWidth||document.documentElement.clientWidth)+e.r},f=0;l>f;f++)o=r[f],u(o,i)?(c&&o.setAttribute("data-echo-placeholder",o.src),null!==o.getAttribute("data-echo-background")?o.style.backgroundImage="url("+o.getAttribute("data-echo-background")+")":o.src=o.getAttribute("data-echo"),c||o.removeAttribute("data-echo"),d(o,"load")):c&&(n=o.getAttribute("data-echo-placeholder"))&&(null!==o.getAttribute("data-echo-background")?o.style.backgroundImage="url("+n+")":o.src=n,o.removeAttribute("data-echo-placeholder"),d(o,"unload"));l||a.detach()},a.detach=function(){document.removeEventListener?t.removeEventListener("scroll",l):t.detachEvent("onscroll",l),clearTimeout(n)},a}); diff --git a/hyhproject/mobile2/view/default/js/forget_pass.js b/hyhproject/mobile2/view/default/js/forget_pass.js new file mode 100755 index 0000000..6747fa3 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/forget_pass.js @@ -0,0 +1,193 @@ +jQuery.noConflict(); +function forgetPwd(){ + var params = {}; + var step = $('#step').val(); + params.modes = modes; + params.step = step; + params.loginName = $.trim($('#loginName').val()); + params.Checkcode = $('#checkCode').val(); + params.verifyCode = $('#loginVerfy').val(); + if(params.loginName=='' && step==1){ + WST.msg('请输入用户名','info'); + WST.getVerify("#verifyImg1") + return; + } + $.post(WST.U('mobile/users/findPass'),params,function(data,textStatus){ + var json = WST.toJson(data); + if(json.status=='1'){ + if(step==1){ + location.href=WST.U('mobile/users/forgetPasst','',true); + }else if(step==2){ + if(modes==1){ + location.href=json.url; + }else{ + disabledBtn(); + } + } + }else{ + WST.msg(json.msg,'info'); + WST.getVerify("#verifyImg1") + } + }); +} + +$(function(){ + // 弹出层 + $("#frame").css('top',0); +}); + +//弹框 +function dataShow(type){ + if(type=="email"){ + modes = 0; + $('#contentTitle').html('通过邮箱找回密码'); + $('.emailBox').show(); + $('.phoneBox').hide(); + }else if(type=="phone"){ + modes = 1; + $('#contentTitle').html('通过手机找回密码'); + $('.emailBox').hide(); + $('.phoneBox').show(); + }else{ + return; + } + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +/* 手机找回 */ +function forgetPhone(){ + var code = $.trim($('#checkCode').val()); + if(code!=''){ + forgetPwd() + }else{ + WST.msg('请输入手机校验码','info'); + return false; + } +} +/* 发送邮箱校验码 */ +function forgetEmail(){ + modes = 0; + var code = $.trim($('#loginVerfy').val()); + if(code != ''){ + forgetPwd(); + }else{ + WST.msg('请输入验证码','info'); + return false; + } +} +/* 提交邮箱验证码-重置密码 */ +function resetByEmail(){ + var code = $.trim($('#emailCode').val()); + if(code == ''){ + WST.msg('请输入校验码','info'); + return false; + }else{ + $.post(WST.U('mobile/users/forgetPasss'),{secretCode:code},function(data){ + var json = WST.toJson(data); + if(json.status==-1){ + WST.msg('校验码错误','info'); + WST.getVerify("#verifyImg1") + return false; + }else{ + location.href=WST.U('mobile/users/resetPass','',true); + } + }) + } +} + +/*重置密码*/ +function resetPwd(){ + var loginPwd = $('#loginPwd').val(); + var repassword = $('#repassword').val(); + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var loginPwd = rsa.encrypt(loginPwd); + var repassword = rsa.encrypt(repassword); + } + var params = {}; + params.step = $('#step').val(); + params.loginPwd = loginPwd; + params.repassword = repassword; + $.post(WST.U('mobile/users/findPass'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('重置成功'); + setTimeout(function(){ + location.href=WST.U('mobile/users/index'); + },1000) + }else{ + WST.msg(json.msg,'info'); + return false; + } + }) +} + + + +var modes = ''; + +/** 校验码 **/ +function phoneVerify2(){ + if(!$('#smsVerify').val()){ + WST.msg('请输入验证码','info'); + return false; + } + + modes = $('#modes').val(); + var time = 0; + var isSend = false; + var smsVerfy = $('#smsVerify').val(); + $.post(WST.U('mobile/users/getfindPhone'),{smsVerfy:smsVerfy},function(data,textStatus){ + var json = WST.toJson(data); + if(isSend )return; + isSend = true; + if(json.status!=1){ + WST.msg(json.msg, 'info'); + WST.getVerify('#verifyImg2'); + time = 0; + isSend = false; + }if(json.status==1){ + WST.msg('短信已发送,请注册查收'); + time = 120; + $('#timeObtain').attr('disabled', 'disabled'); + $('#timeObtain').html('重新获取(120)'); + var task = setInterval(function(){ + time--; + $('#timeObtain').html('重新发送('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#timeObtain').html("重新获取"); + $('#timeObtain').removeAttr('disabled'); + } + },1000); + } + }); +} +function disabledBtn(){ + time = 120; + $('#emailBtn').attr('disabled', 'disabled'); + $('#emailBtn').html('发送验证邮件(120)'); + var task = setInterval(function(){ + time--; + $('#emailBtn').html('重新发送('+time+")"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#emailBtn').html("发送验证邮件"); + $('#emailBtn').removeAttr('disabled'); + } + },1000); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/goods_category.js b/hyhproject/mobile2/view/default/js/goods_category.js new file mode 100755 index 0000000..99c352c --- /dev/null +++ b/hyhproject/mobile2/view/default/js/goods_category.js @@ -0,0 +1,44 @@ +jQuery.noConflict(); +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + jQuery('.goodscate1').eq(index).fadeIn(200).siblings('.goodscate1').hide(); +} +//商品列表页 +function getGoodsList(goodsCatId){ + location.href = WST.U('mobile/goods/lists','catId='+goodsCatId,true); +} + +//品牌-商品列表页 +function getBrandGoodsList(brandId){ + location.href = WST.U('mobile/goods/lists','brandId='+brandId,true); +} +//适应高度 +function selfAdapt(h){ + var o = document.getElementById('ui-scrollerl'); + var a = h-86; + o.style.height=a+'px'; +} +var height = WST.pageHeight(); +$(document).ready(function(){ + WST.initFooter('category'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + selfAdapt(height); + $(window).scroll(function(event){ + var h = WST.pageHeight(); + selfAdapt(h); + }); + var scroll = new fz.Scroll('.ui-scrollerl', { + scrollY: true, + slidingY: 'y' + }); + var w = WST.pageWidth(); + var wImg=(w*0.76-30)/3; + var hImg = wImg*9/14; + $('.wst-gc-br img').css('height',hImg); + var w = $('.goods-cat-img').width(); + $('.goods-cat-img').css('height',w); +}); + + diff --git a/hyhproject/mobile2/view/default/js/goods_detail.js b/hyhproject/mobile2/view/default/js/goods_detail.js new file mode 100755 index 0000000..859405d --- /dev/null +++ b/hyhproject/mobile2/view/default/js/goods_detail.js @@ -0,0 +1,236 @@ +jQuery.noConflict(); +//切换 +function pageSwitch(obj,type){ + $(obj).addClass('active').siblings('.ui-tab-nav li.switch').removeClass('active'); + $('#goods'+type).show().siblings('section.ui-container').hide(); + if(type==1){ + var offsetTop = $("#goods1").offset().top; + var scrollTop = $(window).scrollTop()-100; + if (scrollTop > offsetTop){ + $("#goods-header").show(); + }else{ + $("#goods-header").hide(); + } + } + if(type==3){ + $("#goods-header").show(); + } +} +//商品评价列表 +function evaluateList(){ + loading = true; + var param = {}; + param.goodsId = $('#goodsId').val(); + param.type = $('#evaluateType').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/goodsappraises/getById'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.data.CurrentPage); + $('#totalPage').val(json.data.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#evaluate-list').append(html); + }); + loading = false; + echo.init();//图片懒加载 + }); +} +function evaluateSwitch(obj,type){ + $('#evaluateType').val(type); + $(obj).addClass('active').siblings('.wst-ev-term .ui-col').removeClass('active'); + $('#currPage').val('0'); + $('#totalPage').val('0'); + $('#evaluate-list').html(''); + evaluateList(); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + //商品图片 + new Swiper('.swiper-container', { + slidesPerView: 1, + spaceBetween: 0, + grabCursor : true, + autoplayDisableOnInteraction : true, + pagination : '.swiper-pagination', + paginationClickable :true + }); + evaluateList(); + fixedHeader(); + WST.imgAdapt('j-imgAdapt'); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + evaluateList(); + } + } + }); + if(goodsInfo.sku){ + var specs,dv; + for(var key in goodsInfo.sku){ + if(goodsInfo.sku[key].isDefault==1){ + specs = key.split(':'); + $('.j-option').each(function(){ + dv = $(this).attr('data-val') + if($.inArray(dv,specs)>-1){ + $(this).addClass('active'); + } + }) + $('#buyNum').attr('data-max',goodsInfo.sku[key].specStock); + } + } + }else{ + $('#buyNum').attr('data-max',goodsInfo.goodsStock); + } + checkGoodsStock(); + //选择规格 + $('.spec .j-option').click(function(){ + $(this).addClass('active').siblings().removeClass('active'); + checkGoodsStock(); + }); + //弹框的高度 + var dataHeight = $("#frame").css('height'); + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + if(parseInt(dataHeight)>230){ + $('#content').css('overflow-y','scroll').css('height','200'); + } + if(parseInt(cartHeight)>420){ + $('#standard').css('overflow-y','scroll').css('height','260'); + } + var dataHeight = $("#frame").css('height'); + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + $("#frame").css('bottom','-'+dataHeight); + $("#frame-cart").css('bottom','-'+cartHeight); +}); +function checkGoodsStock(){ + var specIds = [],stock = 0,goodsPrice=0,marketPrice=0; + if(goodsInfo.isSpec==1){ + $('.spec .active').each(function(){ + specIds.push(parseInt($(this).attr('data-val'),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + stock = goodsInfo.sku[specIds.join(':')].specStock; + marketPrice = goodsInfo.sku[specIds.join(':')].marketPrice; + goodsPrice = goodsInfo.sku[specIds.join(':')].specPrice; + goodsHuibao = goodsInfo.sku[specIds.join(':')].specPrice*0.8; + } + }else{ + stock = goodsInfo.goodsStock; + marketPrice = goodsInfo.marketPrice; + goodsPrice = goodsInfo.goodsPrice; + } + $('#goods-stock').html(stock); + $('#buyNum').attr('data-max',stock); + $('#j-market-price').html('¥'+marketPrice); + $('#j-shop-price').html('¥'+goodsPrice); + $('#j-huibao-price').html('¥'+goodsHuibao); + if(stock<=0){ + $('#addBtn').addClass('disabled'); + $('#buyBtn').addClass('disabled'); + }else{ + $('#addBtn').removeClass('disabled'); + $('#buyBtn').removeClass('disabled'); + } +} +//导航 +function fixedHeader(){ + var offsetTop = $("#goods1").offset().top; + $(window).scroll(function() { + if($("#goods1").css("display")!='none'){ + var scrollTop = $(window).scrollTop()-100; + if (scrollTop > offsetTop){ + $("#goods-header").show(); + }else{ + $("#goods-header").hide(); + } + }else{ + $("#goods-header").show(); + } + }); +} +function inMore(){ + if($("#arrow").css("display")=='none'){ + jQuery('#arrow').show(200); + $("#layer").show(); + }else{ + jQuery('#arrow').hide(100); + $("#layer").hide(); + } +} +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} +//弹框 +var type; +function cartShow(t){ + type = t; + jQuery('#cover').attr("onclick","javascript:cartHide();").show(); + jQuery('#frame-cart').animate({"bottom": 0}, 500); +} +function cartHide(){ + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + jQuery('#frame-cart').animate({'bottom': '-'+cartHeight}, 500); + jQuery('#cover').hide(); +} +//加入购物车 +function addCart(){ + var goodsSpecId = 0; + if(goodsInfo.isSpec==1){ + var specIds = []; + $('.spec .active').each(function(){ + specIds.push($(this).attr('data-val')); + }); + if(specIds.length==0){ + WST.msg('请选择你要购买的商品信息','info'); + } + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + goodsSpecId = goodsInfo.sku[specIds.join(':')].id; + } + } + var goodsType = $("#goodsType").val(); + var buyNum = $("#buyNum").val()?$("#buyNum").val():1; + $.post(WST.U('mobile/carts/addCart'),{goodsId:goodsInfo.id,goodsSpecId:goodsSpecId,buyNum:buyNum,type:type,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + cartHide(); + if(type==1){ + setTimeout(function(){ + if(goodsType==1){ + location.href=WST.U('mobile/carts/'+json.data.forward); + }else{ + location.href=WST.U('mobile/carts/settlement'); + } + },1000); + }else{ + if(json.cartNum>0)$("#cartNum").html('<span>'+json.cartNum+'</span>'); + } + }else{ + WST.msg(json.msg,'info'); + } + }); +} +document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#cover").is(":hidden")){ + event.preventDefault(); + } + if(!jQuery("#layer").is(":hidden")){ + event.preventDefault(); + } +}) + + \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/goods_list.js b/hyhproject/mobile2/view/default/js/goods_list.js new file mode 100755 index 0000000..d797125 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/goods_list.js @@ -0,0 +1,93 @@ +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#goods-list').html(''); + goodsList(); +} +//切换 +function switchList(obj){ + if($('#goods-list').hasClass('wst-go-switch')){ + $(obj).removeClass('wst-se-icon2'); + $('#goods-list').removeClass('wst-go-switch'); + }else{ + $(obj).addClass('wst-se-icon2'); + $('#goods-list').addClass('wst-go-switch'); + } + $('.j-imgAdapt').removeAttr('style'); + $('.j-imgAdapt a').removeAttr('style'); + $('.j-imgAdapt a img').removeAttr('style'); + $('#currPage').val('0'); + $('#goods-list').html(''); + goodsList(); +} +//获取商品列表 +function goodsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.catId = $('#catId').val(); + param.brandId = $('#brandId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#keyword').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/goods/pageQuery'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#goods-list').append(html); + }); + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + goodsList(); + WST.imgAdapt('j-imgRec'); + $('.wst-gol-adsb').css('height',$('.j-imgRec').width()+20); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + goodsList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/index-lxy.js b/hyhproject/mobile2/view/default/js/index-lxy.js new file mode 100755 index 0000000..c29e17c --- /dev/null +++ b/hyhproject/mobile2/view/default/js/index-lxy.js @@ -0,0 +1,79 @@ +//秒杀 +var swiper = new Swiper('.swiper-container', { + pagination: '.swiper-pagination', + slidesPerView: 4, + paginationClickable: true, + spaceBetween: 6, + freeMode: true +}); + +//banner1 +var swiper = new Swiper('.banner .swiper-container', { + pagination: '.banner .swiper-container .swiper-pagination', + slidesPerView: 1, + centeredSlides: true, + paginationClickable: true, + spaceBetween: 6, + grabCursor: true +}); +//banner2 +var swiper = new Swiper('.banner1 .swiper-container', { + pagination: '.banner1 .swiper-container .swiper-pagination', + slidesPerView: 1, + centeredSlides: true, + paginationClickable: true, + spaceBetween: 6, + grabCursor: true +}); + +//$('.ac_r-lxy .ac_right_img1').on('click',function(){ +// window.location.href = "heyuanhui.cn/mgoods-23.html" +//}) + +$('.ac_r-lxy .ac_right_img2').on('click', function() { + window.location.href = "heyuanhui.cn/mgoods-20.html" +}) + +/** + * 秒杀模块倒计时 + * */ +function GetRTime(end_time) { + var NowTime = new Date(); + var t = (end_time * 1000) - NowTime.getTime(); + var d = Math.floor(t / 1000 / 60 / 60 / 24); + var h = Math.floor(t / 1000 / 60 / 60 % 24); + var m = Math.floor(t / 1000 / 60 % 60); + var s = Math.floor(t / 1000 % 60); + if(s >= 0) + return(d * 24 + h) + '时' + m + '分' + s + '秒'; +} + +function GetRTime2() { + var myDate = new Date(); + var timestamp = Date.parse(myDate); + var hour = myDate.getHours(); //获取当前小时数(0-23) + //alert(hour); + if(timestamp >= (1509105600 * 1000) || hour < 8) { + //alert(timestamp); + //alert(1509105600); + if(hour < 8) { + start_time = 1509062400; + } else { + start_time = 1509148800; + } + var text = GetRTime(start_time); // alert(1509105600); + if(text == 0) { + $(".h").text('活动已结束'); + } else { + $(".h").text('距开始' + text); + } + } else { + var text = GetRTime('1509105600'); // alert(1509105600); + if(text == 0) { + $(".h").text('活动已结束'); + } else { + $(".h").text('距结束' + text); + } + } +} +setInterval(GetRTime2, 1000); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/index.js b/hyhproject/mobile2/view/default/js/index.js new file mode 100755 index 0000000..1e48f24 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/index.js @@ -0,0 +1,111 @@ +//列表 +function indexList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.currPage = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/index/pageQuery'), param,function(data){ + var json = WST.toJson(data); + if(json && json.catId){ + $('#currPage').val(json.currPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#goods-list').append(html); + }); + WST.imgAdapt('j-imgAdapt'); + } + loading = false; + $('#Load').hide(); + }); +} +//商品列表页 +function getGoodsList(goodsCatId){ + location.href = WST.U('mobile/goods/lists','catId='+goodsCatId); +} +var currPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + //搜索 + $(window).scroll(function(){ + if( $(window).scrollTop() > 42 ){ + $('#j-header').addClass('active'); + $('#j-searchs').addClass('active'); + }else{ + $('#j-header').removeClass('active'); + $('#j-searchs').removeClass('active'); + } + }); + $('.wst-in-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + if($('.ui-slider li').hasClass("advert1")){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); + }else{ + $('.ui-slider').hide(); + } + + //文章 + if($('.wst-in-news a').hasClass("words")){ + new Swiper('.swiper-container1', { + slidesPerView: 1, + freeMode : true, + spaceBetween: 0, + autoplay : 3800, + speed:500, + direction : 'vertical', + loop : true, + autoplayDisableOnInteraction : false, + onlyExternal : true + }); + } + + var w = WST.pageWidth(); + //咨询上广告 + if($('.wst-in-activity a').hasClass("advert4")){ + }else{ + $('.wst-in-activity .advert4').hide(); + } + //中间大广告 + if($('.wst-in-adst a').hasClass("advert2")){ + }else{ + $('.wst-in-adst ').hide(); + } + + //中间小广告 + if($('.wst-in-adsb a').hasClass("advert3")){ + new Swiper('.swiper-container2', { + slidesPerView: 3, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : true, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + }else{ + $('.wst-in-adsb').hide(); + } + + + //刷新 + indexList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + if(currPage < 10 ){ + indexList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/izimodal/iziModal.js b/hyhproject/mobile2/view/default/js/izimodal/iziModal.js new file mode 100755 index 0000000..a22345f --- /dev/null +++ b/hyhproject/mobile2/view/default/js/izimodal/iziModal.js @@ -0,0 +1,521 @@ +/* +* iziModal | v1.0 +* http://izimodal.dolce.ninja +* by Marcelo Dolce. +* js修改过 +*/ +(function(jQuery){ + + "use strict"; + + var PLUGIN_NAME = 'iziModal'; + + var STATES = { + CLOSING: 'closing', + CLOSED: 'closed', + OPENING: 'opening', + OPENED: 'opened', + DESTROYED: 'destroyed' + }; + + function whichAnimationEvent(){ + var t, + el = document.createElement("fakeelement"); + + var animations = { + "animation" : "animationend", + "OAnimation" : "oAnimationEnd", + "MozAnimation" : "animationend", + "WebkitAnimation": "webkitAnimationEnd" + }; + for (t in animations){ + if (el.style[t] !== undefined){ + return animations[t]; + } + } + } + var animationEvent = whichAnimationEvent(); + + var isMobile = false; + if (/Mobi/.test(navigator.userAgent)) { + isMobile = true; + } + + var iziModal = function (element, options) { + this.init(element, options); + }; + + iziModal.prototype = { + + constructor: iziModal, + + init: function (element, options) { + + var that = this; + + this.jQueryelement = jQuery(element); + this.id = this.jQueryelement.attr('id'); + this.state = STATES.CLOSED; + this.options = options; + this.timer = null; + this.headerHeight = 0; + this.jQueryheader = jQuery('<div class="'+PLUGIN_NAME+'-header"><h1 class="'+PLUGIN_NAME+'-header-title">' + options.title + '</h1><p class="'+PLUGIN_NAME+'-header-subtitle">' + options.subtitle + '</p><a href="javascript:void(0)" class="'+PLUGIN_NAME+'-button-close" data-'+PLUGIN_NAME+'-close><i class="ui-icon-return"></i></a><div id="wst-switch"><div></div>'); + this.jQueryoverlay = jQuery('<div class="'+PLUGIN_NAME+'-overlay" style="background-color:'+options.overlayColor+'"></div>'); + + if (options.subtitle === '') { + this.jQueryheader.addClass(PLUGIN_NAME+'-noSubtitle'); + } + + if (options.iframe === true) { + this.jQueryelement.html('<div class="'+PLUGIN_NAME+'-wrap"><div class="'+PLUGIN_NAME+'-content '+PLUGIN_NAME+'-content-loader"><iframe class="'+PLUGIN_NAME+'-iframe"></iframe>' + this.jQueryelement.html() + "</div></div>"); + + if (options.iframeHeight !== null) { + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css('height', options.iframeHeight); + } + + } else { + this.jQueryelement.html('<div class="'+PLUGIN_NAME+'-wrap"><div class="'+PLUGIN_NAME+'-content">' + this.jQueryelement.html() + '</div></div>'); + } + + jQuery(document.body).find('style[rel='+this.id+']').remove(); + + if(typeof options.padding !== 'undefined' || options.padding !== 0) + this.jQueryelement.find('.'+PLUGIN_NAME+'-content').css('padding', options.padding); + + + if (options.title !== "" || options.subtitle !== "") { + + if (options.headerColor !== null) { + this.jQueryelement.css('border-bottom', '3px solid ' + options.headerColor + ''); + this.jQueryheader.css('background', this.options.headerColor); + } + if (options.iconClass !== null) { + this.jQueryheader.prepend('<i class="'+PLUGIN_NAME+'-header-icon ' + options.iconClass + '"></i>'); + this.jQueryheader.find("."+PLUGIN_NAME+'-header-icon').css('color', options.iconColor); + } + this.jQueryelement.prepend(this.jQueryheader); + } + + var separators = /%|px|em|cm/, + wClear = String(options.width).split(separators), + w = String(options.width), + medida = "px"; + wClear = String(wClear).split(",")[0]; + + if(isNaN(options.width)){ + if( String(options.width).indexOf("%") != -1){ + medida = "%"; + } else { + medida = w.slice("-2"); + } + } + + this.jQueryelement.css({ + 'margin-left': -(wClear / 2) + medida, + 'max-width': parseInt(wClear) + medida + }); + + this.mediaQueries = '<style rel="' + this.id + '">@media handheld, only screen and (max-width: ' + wClear + 'px) { #' + this.jQueryelement[0].id + '{ width: 100% !important; max-width: 100% !important; margin-left: 0 !important; left: 0 !important; } }</style>'; + jQuery(document.body).append(this.mediaQueries); + + // Adjusting horizontal positioning + this.jQueryelement.addClass(PLUGIN_NAME + " " + options.theme); + + // Adjusting vertical positioning + this.jQueryelement.css('margin-top', parseInt(-(this.jQueryelement.innerHeight() / 2)) + 'px'); + + + if(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').length){ + this.jQueryelement.css('overflow', 'hidden'); + } + + // Close on overlay click + this.jQueryoverlay.click(function () { + if (that.options.overlayClose && !that.jQueryelement.hasClass(that.options.transitionOutModal)) { + that.close(); + } + }); + + // Close when button pressed + this.jQueryelement.on('click', '[data-'+PLUGIN_NAME+'-close]', function (e) { + e.preventDefault(); + that.close(); + }); + }, + + toggle: function () { + + if(this.state == STATES.OPENED){ + this.close(); + } + if(this.state == STATES.CLOSED){ + this.open(); + } + + }, + + open: function (param) { + + var that = this; + + if (param && typeof(param) === "function") { + param(that); + } + + if(this.options.iframe === true){ + + var href = null; + if(this.options.iframeURL !== null){ + href = this.options.iframeURL; + } else { + try { + href = param.target.href; + if(href !== undefined){ + href = param.target.href; + } + } catch(e) { + console.warn(e); + } + } + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').attr('src', href); + } + + this.jQueryelement.trigger(STATES.OPENING); + this.state = STATES.OPENING; + + console.info('[ '+PLUGIN_NAME+' | '+this.id+' ] Opening...'); + + if (this.options.bodyOverflow || isMobile){ + jQuery(document.body).css('overflow', 'hidden'); + } + + that.options.onOpening.call(this); + + function opened(){ + that.jQueryelement.trigger(STATES.OPENED); + that.state = STATES.OPENED; + + console.info('[ '+PLUGIN_NAME+' | '+that.id+' ] Opened.'); + + that.options.onOpened.call(this); + } + + this.jQueryoverlay.appendTo('body'); + + if (this.options.transitionInOverlay) { + this.jQueryoverlay.addClass(this.options.transitionInOverlay); + } + + if (this.options.transitionInModal !== '') { + + this.jQueryelement.addClass(this.options.transitionInModal).show(); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').one(animationEvent, function () { + + that.jQueryelement.removeClass(that.options.transitionInModal); + that.jQueryoverlay.removeClass(that.options.transitionInOverlay); + + opened(); + }); + + } else { + this.jQueryelement.show(); + opened(); + } + + if (that.options.focusInput){ + that.jQueryelement.find(':input:not(button):enabled:visible:first').focus(); // Focus on the first field + } + + (function updateTimer(){ + that.recalculateLayout(); + that.timer = setTimeout(updateTimer, 500); + })(); + + // Close when the Escape key is pressed + jQuery(document).keydown(function (e) { + if (that.options.closeOnEscape && e.keyCode === 27) { + that.close(); + } + }); + + }, + + close: function (param) { + + var that = this; + + if (param && typeof(param) === "function") { + param(that); + } + + jQuery(document).off("keydown"); + + this.state = STATES.CLOSING; + this.jQueryelement.trigger(STATES.CLOSING); + console.info('[ '+PLUGIN_NAME+' | '+this.id+' ] Closing...'); + + clearTimeout(that.timer); + + that.options.onClosing.call(this); + + function closed(){ + + if (that.options.iframe === true) { + that.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').attr('src', ""); + } + + if (that.options.bodyOverflow || isMobile){ + jQuery(document.body).css('overflow', 'initial'); + } + + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + + that.jQueryelement.trigger(STATES.CLOSED); + that.state = STATES.CLOSED; + + console.info('[ '+PLUGIN_NAME+' | '+that.id+' ] Closed.'); + + that.options.onClosed.call(this); + } + + if (this.options.transitionOutModal !== '') { + + //this.jQueryelement.removeClass(this.options.transitionInModal).addClass(this.options.transitionOutModal); + //this.jQueryoverlay.removeClass(this.options.transitionInOverlay).addClass(this.options.transitionOutOverlay); + + this.jQueryelement.attr('class', PLUGIN_NAME + " " + this.options.theme + " " + this.options.transitionOutModal); + this.jQueryoverlay.attr('class', PLUGIN_NAME + "-overlay " + this.options.transitionOutOverlay); + + this.jQueryelement.one(animationEvent, function () { + + if( that.jQueryelement.hasClass(that.options.transitionOutModal) ){ + + that.jQueryelement.removeClass(that.options.transitionOutModal).hide(); + that.jQueryoverlay.removeClass(that.options.transitionOutOverlay).remove(); + + closed(); + } + }); + } + else { + this.jQueryelement.hide(); + this.jQueryoverlay.remove(); + + closed(); + } + }, + + destroy: function () { + var e = jQuery.Event('destroy'); + + this.jQueryelement.trigger(e); + + jQuery(document).off("keydown"); + + clearTimeout(this.timer); + + if (this.options.iframe === true) { + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').remove(); + } + this.jQueryelement.html(this.jQueryelement.find('.'+PLUGIN_NAME+'-content').html()); + + jQuery(document.body).find('style[rel='+this.id+']').remove(); + + this.jQueryelement.off('click', '[data-'+PLUGIN_NAME+'-close]'); + + this.jQueryelement + .off('.'+PLUGIN_NAME) + .removeData(PLUGIN_NAME) + .attr('style', ''); + + this.jQueryoverlay.remove(); + this.jQueryelement.trigger(STATES.DESTROYED); + this.jQueryelement = null; + }, + + getState: function(){ + + console.info(this.state); + + return this.state; + }, + + setTitle: function(title){ + + if (this.options.title !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-title').html(title); + + this.options.title = title; + } + }, + + setSubtitle: function(subtitle){ + + if (this.options.subtitle !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-subtitle').html(subtitle); + + this.options.subtitle = subtitle; + } + }, + + setIconClass: function(iconClass){ + + if (this.options.iconClass !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-icon').attr('class', PLUGIN_NAME+'-header-icon ' + iconClass); + + this.options.iconClass = iconClass; + } + }, + + setHeaderColor: function(headerColor){ + + if (this.options.headerColor !== null) { + this.jQueryelement.css('border-bottom', '3px solid ' + headerColor + ''); + this.jQueryheader.css('background', headerColor); + + this.options.headerColor = headerColor; + } + }, + + startLoading: function(){ + if( !this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').length ){ + this.jQueryelement.append('<div class="'+PLUGIN_NAME+'-loader '+this.options.transitionInOverlay+'"></div>'); + } + }, + + stopLoading: function(){ + var that = this; + this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').removeClass(this.options.transitionInOverlay).addClass(this.options.transitionOutOverlay); + this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').one(animationEvent, function () { + that.jQueryelement.find('.'+PLUGIN_NAME+'-loader').removeClass(that.options.transitionOutOverlay).remove(); + }); + }, + + recalculateLayout: function(){ + + if(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').length){ + this.headerHeight = parseInt(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').innerHeight()) + 2/*border bottom of modal*/; + this.jQueryelement.css('overflow', 'hidden'); + } + + var windowHeight = jQuery(window).height(), + contentHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-content')[0].scrollHeight, + modalMargin = parseInt(-((this.jQueryelement.innerHeight() + 1) / 2)) + 'px'; + + if(this.state == STATES.OPENED || this.state == STATES.OPENING){ + + if (this.options.iframe === true) { + + // Se a altura da janela é menor que o modal com iframe + if(windowHeight < (this.options.iframeHeight + this.headerHeight)){ + + jQuery(document.body).addClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css({ + 'height': parseInt(windowHeight - this.headerHeight) + 'px', + }); + + } else { + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css({ + 'height': parseInt(this.options.iframeHeight) + 'px', + }); + } + + } else { + + if (windowHeight > (contentHeight + this.headerHeight)) { + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + //内部窗口高; + var screenHeight=window.innerHeight-45 + || document.documentElement.clientHeight + || document.body.clientHeight; + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').css({'height': screenHeight+'px'}); + } + + if (this.jQueryelement.innerHeight() > windowHeight || this.jQueryelement.innerHeight() < contentHeight) { + jQuery(document.body).addClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').css({ + 'height': parseInt(windowHeight - this.headerHeight) + 'px', + }); + } + + var scrollTop = this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').scrollTop(), + internoHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-content').innerHeight(), + externoHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').innerHeight(); + /* + if ((externoHeight + scrollTop) < (internoHeight - 50)) { + this.jQueryelement.addClass('hasScroll'); + } else { + this.jQueryelement.removeClass('hasScroll'); + } + */ + } + } + + // Corrige margin-top caso o modal sofra alterações na altura de seu conteúdo + if (this.jQueryelement.css('margin-top') != modalMargin && this.jQueryelement.css('margin-top') != "0px") { + // this.jQueryelement.css('margin-top', modalMargin); + } + } + + }; + + jQuery.fn[PLUGIN_NAME] = function (option, args) { + return this.each(function () { + var jQuerythis = jQuery(this), + data = jQuerythis.data(PLUGIN_NAME), + options = jQuery.extend({}, jQuery.fn.iziModal.defaults, jQuerythis.data(), typeof option == 'object' && option); + + if (!data && (!option || typeof option == 'object')){ + jQuerythis.data(PLUGIN_NAME, (data = new iziModal(this, options))); + } + if (typeof option == 'string' && typeof data != 'undefined'){ + data[option].apply(data, [].concat(args)); + } + else if (options.autoOpen){ // Automatically open the modal if autoOpen setted true + data.open(); + } + }); + }; + //内部窗口宽 + var screenWidth=window.innerWidth + || document.documentElement.clientWidth + || document.body.clientWidth; + jQuery.fn[PLUGIN_NAME].defaults = { + title: "", + subtitle: "", + theme: "", + headerColor: "#88A0B9", + overlayColor: "rgba(0, 0, 0, 0.4)", + iconColor: "", + iconClass: null, + width: screenWidth, + padding: 0, + iframe: false, + iframeHeight: 400, + iframeURL: null, + overlayClose: true, + closeOnEscape: true, + bodyOverflow: false, + focusInput: true, + autoOpen: false, + transitionInModal: 'transitionIn', + transitionOutModal: 'transitionOut', + transitionInOverlay: 'fadeIn', + transitionOutOverlay: 'fadeOut', + onOpening: function() {}, + onOpened: function() {}, + onClosing: function() {}, + onClosed: function() {} + }; + + jQuery.fn[PLUGIN_NAME].Constructor = iziModal; + +}).call(this, window.jQuery); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/jquery.min.js b/hyhproject/mobile2/view/default/js/jquery.min.js new file mode 100755 index 0000000..83589da --- /dev/null +++ b/hyhproject/mobile2/view/default/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/laytpl/laytpl.js b/hyhproject/mobile2/view/default/js/laytpl/laytpl.js new file mode 100755 index 0000000..8ed64c6 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/laytpl/laytpl.js @@ -0,0 +1,9 @@ +/** + + @Name:laytpl-v1.1 精妙的js模板引擎 + @Author:贤心 - 2014-08-16 + @Site:http://sentsin.com/layui/laytpl + @License:MIT license + */ + +;!function(){"use strict";var f,b={open:"{{",close:"}}"},c={exp:function(a){return new RegExp(a,"g")},query:function(a,c,e){var f=["#([\\s\\S])+?","([^{#}])*?"][a||0];return d((c||"")+b.open+f+b.close+(e||""))},escape:function(a){return String(a||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(a,b){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+a+"\n"+(b||"")),c+a}},d=c.exp,e=function(a){this.tpl=a};e.pt=e.prototype,e.pt.parse=function(a,e){var f=this,g=a,h=d("^"+b.open+"#",""),i=d(b.close+"$","");a=a.replace(/[\r\t\n]/g," ").replace(d(b.open+"#"),b.open+"# ").replace(d(b.close+"}"),"} "+b.close).replace(/\\/g,"\\\\").replace(/(?="|')/g,"\\").replace(c.query(),function(a){return a=a.replace(h,"").replace(i,""),'";'+a.replace(/\\/g,"")+'; view+="'}).replace(c.query(1),function(a){var c='"+(';return a.replace(/\s/g,"")===b.open+b.close?"":(a=a.replace(d(b.open+"|"+b.close),""),/^=/.test(a)&&(a=a.replace(/^=/,""),c='"+_escape_('),c+a.replace(/\\/g,"")+')+"')}),a='"use strict";var view = "'+a+'";return view;';try{return f.cache=a=new Function("d, _escape_",a),a(e,c.escape)}catch(j){return delete f.cache,c.error(j,g)}},e.pt.render=function(a,b){var e,d=this;return a?(e=d.cache?d.cache(a,c.escape):d.parse(d.tpl,a),b?(b(e),void 0):e):c.error("no data")},f=function(a){return"string"!=typeof a?c.error("Template not found"):new e(a)},f.config=function(a){a=a||{};for(var c in a)b[c]=a[c]},f.v="1.1","function"==typeof define?define(function(){return f}):"undefined"!=typeof exports?module.exports=f:window.laytpl=f}(); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/login.js b/hyhproject/mobile2/view/default/js/login.js new file mode 100755 index 0000000..7a769fc --- /dev/null +++ b/hyhproject/mobile2/view/default/js/login.js @@ -0,0 +1,245 @@ +jQuery.noConflict(); +function login(){ + var loginName = $('#loginName').val(); + var loginPwd = $('#loginPwd').val(); + var loginVerfy = $('#loginVerfy').val(); + if(loginName==''){ + WST.msg('请输入账号','info'); + return false; + } + if(loginPwd==''){ + WST.msg('请输入密码','info'); + return false; + } + if(loginVerfy==''){ + WST.msg('请输入验证码','info'); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var loginPwd = rsa.encrypt(loginPwd); + } + WST.load('登录中···'); + var param = {}; + param.loginName = loginName; + param.loginPwd = loginPwd; + param.verifyCode = loginVerfy; + $('#loginButton').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/checkLogin'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var url = json.url; + setTimeout(function(){ + if(WST.blank(url)){ + location.href = url; + }else{ + location.href = WST.U('mobile/users/index'); + } + },2000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg1"); + $('#loginButton').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +//mark lxy 增加分享人 2018/4/4 +function GetQueryString(name) { + var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r != null) + return unescape(r[2]); + return null; +} + +var pname =GetQueryString('pName')?GetQueryString('pName'): localStorage.getItem('pName'); + +if(!pname) { + pname = localStorage.getItem('pName'); +} + +if(pname) { + $('#pName').val(pname);; + $('#pName').attr('disabled', 'disabled'); +} +var nameType = 3; +function onTesting(obj){ + //不能输入中文 + WST.isChinese(obj,1); + var data = $(obj).val(); + var regMobile = /^0?1[3|4|5|8][0-9]\d{8}$/; + if(regMobile.test(data)){//手机 + nameType = 3; + $.post(WST.U('mobile/users/checkUserPhone'), {userPhone:data}, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + }else{ + var dia=$.dialog({ + title:'', + content:'<p style="text-align: center;">手机号已注册</p>', + button:["确认"] + }); + } + data = json = null; + }); + } +} +function register(){ + var regName = $('#regName').val(); + var regPwd = $('#regPwd').val(); + var regcoPwd = $('#regcoPwd').val(); + var regVerfy = $('#regVerfy').val(); + var phoneCode = $('#phoneCode').val(); + var smsVerfy = $('#smsVerfy').val(); + + var pName = $('#pName').val(); + var param = {}; + if($('#defaults').hasClass('ui-icon-unchecked-s')){ + WST.msg('请阅读用户注册协议','info'); + return false; + } + if(regName==''){ + WST.msg('请输入账号','info'); + return false; + } + if(regName.length < 6){ + WST.msg('账号为6位以上数字或字母','info'); + return false; + } + if(regPwd==''){ + WST.msg('请输入密码','info'); + return false; + } + if(regPwd.length < 6 || regPwd.length > 16){ + WST.msg('请输入密码为6-16位字符','info'); + return false; + } + if(regcoPwd==''){ + WST.msg('确认密码不能为空','info'); + return false; + } + // if(smsVerfy == '') { + // WST.msg('验证码不能为空', 'info'); + // return false; + // } + if(regPwd!=regcoPwd){ + WST.msg('确认密码不一致','info'); + return false; + } + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + return false; + } + param.mobileCode = phoneCode; + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var regcoPwd = rsa.encrypt(regcoPwd); + var regPwd = rsa.encrypt(regPwd); + } + WST.load('注册中···'); + param.nameType = nameType; + param.loginName = regName; + param.loginPwd = regcoPwd; + param.reUserPwd = regPwd; + param.pName = pName; + param.verifyCode = smsVerfy; + $('#regButton').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/register'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var url = json.url; + setTimeout(function(){ + if(WST.blank(url)){ + location.href = url; + }else{ + location.href = WST.U('mobile/users/index'); + } + },2000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg3"); + $('#regButton').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +var time = 0; +var isSend = false; +function obtainCode(){ + var userPhone = $('#regName').val(); + if(userPhone ==''){ + WST.msg('请输入帐号为手机号码','info'); + $('#userPhone').focus(); + return false; + } + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.userPhone = userPhone; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('mobile/users/getPhoneVerifyCode'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg3"); + isSend = false; + } + data = json = null; + }); +} +//弹框 +function wholeShow(type){ + jQuery('#'+type).animate({"right": 0}, 500); +} +function wholeHide(type){ + var dataWidth = $('#'+type).css('width'); + jQuery('#'+type).animate({'right': '-'+dataWidth}, 500); +} +//协议 +function inAgree(obj){ + if($('#defaults').hasClass('wst-active')){ + $(obj).addClass('ui-icon-unchecked-s'); + $(obj).removeClass('ui-icon-success-block wst-active'); + }else{ + $(obj).removeClass('ui-icon-unchecked-s'); + $(obj).addClass('ui-icon-success-block wst-active'); + } +} +$(document).ready(function(){ + var w = WST.pageWidth(); + var h = WST.pageHeight(); + $('#protocol .content').css('overflow-y','scroll').css('height',h-61); + $("#protocol").css('right',-w); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/photoclip/hammer.js b/hyhproject/mobile2/view/default/js/photoclip/hammer.js new file mode 100755 index 0000000..5226688 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/photoclip/hammer.js @@ -0,0 +1,2463 @@ +/*! Hammer.JS - v2.0.4 - 2014-09-28 + * http://hammerjs.github.io/ + * + * Copyright (c) 2014 Jorik Tangelder; + * Licensed under the MIT license */ +(function(window, document, exportName, undefined) { + 'use strict'; + +var VENDOR_PREFIXES = ['', 'webkit', 'moz', 'MS', 'ms', 'o']; +var TEST_ELEMENT = document.createElement('div'); + +var TYPE_FUNCTION = 'function'; + +var round = Math.round; +var abs = Math.abs; +var now = Date.now; + +/** + * set a timeout with a given scope + * @param {Function} fn + * @param {Number} timeout + * @param {Object} context + * @returns {number} + */ +function setTimeoutContext(fn, timeout, context) { + return setTimeout(bindFn(fn, context), timeout); +} + +/** + * if the argument is an array, we want to execute the fn on each entry + * if it aint an array we don't want to do a thing. + * this is used by all the methods that accept a single and array argument. + * @param {*|Array} arg + * @param {String} fn + * @param {Object} [context] + * @returns {Boolean} + */ +function invokeArrayArg(arg, fn, context) { + if (Array.isArray(arg)) { + each(arg, context[fn], context); + return true; + } + return false; +} + +/** + * walk objects and arrays + * @param {Object} obj + * @param {Function} iterator + * @param {Object} context + */ +function each(obj, iterator, context) { + var i; + + if (!obj) { + return; + } + + if (obj.forEach) { + obj.forEach(iterator, context); + } else if (obj.length !== undefined) { + i = 0; + while (i < obj.length) { + iterator.call(context, obj[i], i, obj); + i++; + } + } else { + for (i in obj) { + obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); + } + } +} + +/** + * extend object. + * means that properties in dest will be overwritten by the ones in src. + * @param {Object} dest + * @param {Object} src + * @param {Boolean} [merge] + * @returns {Object} dest + */ +function extend(dest, src, merge) { + var keys = Object.keys(src); + var i = 0; + while (i < keys.length) { + if (!merge || (merge && dest[keys[i]] === undefined)) { + dest[keys[i]] = src[keys[i]]; + } + i++; + } + return dest; +} + +/** + * merge the values from src in the dest. + * means that properties that exist in dest will not be overwritten by src + * @param {Object} dest + * @param {Object} src + * @returns {Object} dest + */ +function merge(dest, src) { + return extend(dest, src, true); +} + +/** + * simple class inheritance + * @param {Function} child + * @param {Function} base + * @param {Object} [properties] + */ +function inherit(child, base, properties) { + var baseP = base.prototype, + childP; + + childP = child.prototype = Object.create(baseP); + childP.constructor = child; + childP._super = baseP; + + if (properties) { + extend(childP, properties); + } +} + +/** + * simple function bind + * @param {Function} fn + * @param {Object} context + * @returns {Function} + */ +function bindFn(fn, context) { + return function boundFn() { + return fn.apply(context, arguments); + }; +} + +/** + * let a boolean value also be a function that must return a boolean + * this first item in args will be used as the context + * @param {Boolean|Function} val + * @param {Array} [args] + * @returns {Boolean} + */ +function boolOrFn(val, args) { + if (typeof val == TYPE_FUNCTION) { + return val.apply(args ? args[0] || undefined : undefined, args); + } + return val; +} + +/** + * use the val2 when val1 is undefined + * @param {*} val1 + * @param {*} val2 + * @returns {*} + */ +function ifUndefined(val1, val2) { + return (val1 === undefined) ? val2 : val1; +} + +/** + * addEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ +function addEventListeners(target, types, handler) { + each(splitStr(types), function(type) { + target.addEventListener(type, handler, false); + }); +} + +/** + * removeEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ +function removeEventListeners(target, types, handler) { + each(splitStr(types), function(type) { + target.removeEventListener(type, handler, false); + }); +} + +/** + * find if a node is in the given parent + * @method hasParent + * @param {HTMLElement} node + * @param {HTMLElement} parent + * @return {Boolean} found + */ +function hasParent(node, parent) { + while (node) { + if (node == parent) { + return true; + } + node = node.parentNode; + } + return false; +} + +/** + * small indexOf wrapper + * @param {String} str + * @param {String} find + * @returns {Boolean} found + */ +function inStr(str, find) { + return str.indexOf(find) > -1; +} + +/** + * split string on whitespace + * @param {String} str + * @returns {Array} words + */ +function splitStr(str) { + return str.trim().split(/\s+/g); +} + +/** + * find if a array contains the object using indexOf or a simple polyFill + * @param {Array} src + * @param {String} find + * @param {String} [findByKey] + * @return {Boolean|Number} false when not found, or the index + */ +function inArray(src, find, findByKey) { + if (src.indexOf && !findByKey) { + return src.indexOf(find); + } else { + var i = 0; + while (i < src.length) { + if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) { + return i; + } + i++; + } + return -1; + } +} + +/** + * convert array-like objects to real arrays + * @param {Object} obj + * @returns {Array} + */ +function toArray(obj) { + return Array.prototype.slice.call(obj, 0); +} + +/** + * unique array with objects based on a key (like 'id') or just by the array's value + * @param {Array} src [{id:1},{id:2},{id:1}] + * @param {String} [key] + * @param {Boolean} [sort=False] + * @returns {Array} [{id:1},{id:2}] + */ +function uniqueArray(src, key, sort) { + var results = []; + var values = []; + var i = 0; + + while (i < src.length) { + var val = key ? src[i][key] : src[i]; + if (inArray(values, val) < 0) { + results.push(src[i]); + } + values[i] = val; + i++; + } + + if (sort) { + if (!key) { + results = results.sort(); + } else { + results = results.sort(function sortUniqueArray(a, b) { + return a[key] > b[key]; + }); + } + } + + return results; +} + +/** + * get the prefixed property + * @param {Object} obj + * @param {String} property + * @returns {String|Undefined} prefixed + */ +function prefixed(obj, property) { + var prefix, prop; + var camelProp = property[0].toUpperCase() + property.slice(1); + + var i = 0; + while (i < VENDOR_PREFIXES.length) { + prefix = VENDOR_PREFIXES[i]; + prop = (prefix) ? prefix + camelProp : property; + + if (prop in obj) { + return prop; + } + i++; + } + return undefined; +} + +/** + * get a unique id + * @returns {number} uniqueId + */ +var _uniqueId = 1; +function uniqueId() { + return _uniqueId++; +} + +/** + * get the window object of an element + * @param {HTMLElement} element + * @returns {DocumentView|Window} + */ +function getWindowForElement(element) { + var doc = element.ownerDocument; + return (doc.defaultView || doc.parentWindow); +} + +var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; + +var SUPPORT_TOUCH = ('ontouchstart' in window); +var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined; +var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); + +var INPUT_TYPE_TOUCH = 'touch'; +var INPUT_TYPE_PEN = 'pen'; +var INPUT_TYPE_MOUSE = 'mouse'; +var INPUT_TYPE_KINECT = 'kinect'; + +var COMPUTE_INTERVAL = 25; + +var INPUT_START = 1; +var INPUT_MOVE = 2; +var INPUT_END = 4; +var INPUT_CANCEL = 8; + +var DIRECTION_NONE = 1; +var DIRECTION_LEFT = 2; +var DIRECTION_RIGHT = 4; +var DIRECTION_UP = 8; +var DIRECTION_DOWN = 16; + +var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; +var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; +var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; + +var PROPS_XY = ['x', 'y']; +var PROPS_CLIENT_XY = ['clientX', 'clientY']; + +/** + * create new input type manager + * @param {Manager} manager + * @param {Function} callback + * @returns {Input} + * @constructor + */ +function Input(manager, callback) { + var self = this; + this.manager = manager; + this.callback = callback; + this.element = manager.element; + this.target = manager.options.inputTarget; + + // smaller wrapper around the handler, for the scope and the enabled state of the manager, + // so when disabled the input events are completely bypassed. + this.domHandler = function(ev) { + if (boolOrFn(manager.options.enable, [manager])) { + self.handler(ev); + } + }; + + this.init(); + +} + +Input.prototype = { + /** + * should handle the inputEvent data and trigger the callback + * @virtual + */ + handler: function() { }, + + /** + * bind the events + */ + init: function() { + this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + }, + + /** + * unbind the events + */ + destroy: function() { + this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + } +}; + +/** + * create new input type manager + * called by the Manager constructor + * @param {Hammer} manager + * @returns {Input} + */ +function createInputInstance(manager) { + var Type; + var inputClass = manager.options.inputClass; + + if (inputClass) { + Type = inputClass; + } else if (SUPPORT_POINTER_EVENTS) { + Type = PointerEventInput; + } else if (SUPPORT_ONLY_TOUCH) { + Type = TouchInput; + } else if (!SUPPORT_TOUCH) { + Type = MouseInput; + } else { + Type = TouchMouseInput; + } + return new (Type)(manager, inputHandler); +} + +/** + * handle input events + * @param {Manager} manager + * @param {String} eventType + * @param {Object} input + */ +function inputHandler(manager, eventType, input) { + var pointersLen = input.pointers.length; + var changedPointersLen = input.changedPointers.length; + var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0)); + var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0)); + + input.isFirst = !!isFirst; + input.isFinal = !!isFinal; + + if (isFirst) { + manager.session = {}; + } + + // source event is the normalized value of the domEvents + // like 'touchstart, mouseup, pointerdown' + input.eventType = eventType; + + // compute scale, rotation etc + computeInputData(manager, input); + + // emit secret event + manager.emit('hammer.input', input); + + manager.recognize(input); + manager.session.prevInput = input; +} + +/** + * extend the data with some usable properties like scale, rotate, velocity etc + * @param {Object} manager + * @param {Object} input + */ +function computeInputData(manager, input) { + var session = manager.session; + var pointers = input.pointers; + var pointersLength = pointers.length; + + // store the first input to calculate the distance and direction + if (!session.firstInput) { + session.firstInput = simpleCloneInputData(input); + } + + // to compute scale and rotation we need to store the multiple touches + if (pointersLength > 1 && !session.firstMultiple) { + session.firstMultiple = simpleCloneInputData(input); + } else if (pointersLength === 1) { + session.firstMultiple = false; + } + + var firstInput = session.firstInput; + var firstMultiple = session.firstMultiple; + var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; + + var center = input.center = getCenter(pointers); + input.timeStamp = now(); + input.deltaTime = input.timeStamp - firstInput.timeStamp; + + input.angle = getAngle(offsetCenter, center); + input.distance = getDistance(offsetCenter, center); + + computeDeltaXY(session, input); + input.offsetDirection = getDirection(input.deltaX, input.deltaY); + + input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; + input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0; + + computeIntervalInputData(session, input); + + // find the correct target + var target = manager.element; + if (hasParent(input.srcEvent.target, target)) { + target = input.srcEvent.target; + } + input.target = target; +} + +function computeDeltaXY(session, input) { + var center = input.center; + var offset = session.offsetDelta || {}; + var prevDelta = session.prevDelta || {}; + var prevInput = session.prevInput || {}; + + if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) { + prevDelta = session.prevDelta = { + x: prevInput.deltaX || 0, + y: prevInput.deltaY || 0 + }; + + offset = session.offsetDelta = { + x: center.x, + y: center.y + }; + } + + input.deltaX = prevDelta.x + (center.x - offset.x); + input.deltaY = prevDelta.y + (center.y - offset.y); +} + +/** + * velocity is calculated every x ms + * @param {Object} session + * @param {Object} input + */ +function computeIntervalInputData(session, input) { + var last = session.lastInterval || input, + deltaTime = input.timeStamp - last.timeStamp, + velocity, velocityX, velocityY, direction; + + if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) { + var deltaX = last.deltaX - input.deltaX; + var deltaY = last.deltaY - input.deltaY; + + var v = getVelocity(deltaTime, deltaX, deltaY); + velocityX = v.x; + velocityY = v.y; + velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; + direction = getDirection(deltaX, deltaY); + + session.lastInterval = input; + } else { + // use latest velocity info if it doesn't overtake a minimum period + velocity = last.velocity; + velocityX = last.velocityX; + velocityY = last.velocityY; + direction = last.direction; + } + + input.velocity = velocity; + input.velocityX = velocityX; + input.velocityY = velocityY; + input.direction = direction; +} + +/** + * create a simple clone from the input used for storage of firstInput and firstMultiple + * @param {Object} input + * @returns {Object} clonedInputData + */ +function simpleCloneInputData(input) { + // make a simple copy of the pointers because we will get a reference if we don't + // we only need clientXY for the calculations + var pointers = []; + var i = 0; + while (i < input.pointers.length) { + pointers[i] = { + clientX: round(input.pointers[i].clientX), + clientY: round(input.pointers[i].clientY) + }; + i++; + } + + return { + timeStamp: now(), + pointers: pointers, + center: getCenter(pointers), + deltaX: input.deltaX, + deltaY: input.deltaY + }; +} + +/** + * get the center of all the pointers + * @param {Array} pointers + * @return {Object} center contains `x` and `y` properties + */ +function getCenter(pointers) { + var pointersLength = pointers.length; + + // no need to loop when only one touch + if (pointersLength === 1) { + return { + x: round(pointers[0].clientX), + y: round(pointers[0].clientY) + }; + } + + var x = 0, y = 0, i = 0; + while (i < pointersLength) { + x += pointers[i].clientX; + y += pointers[i].clientY; + i++; + } + + return { + x: round(x / pointersLength), + y: round(y / pointersLength) + }; +} + +/** + * calculate the velocity between two points. unit is in px per ms. + * @param {Number} deltaTime + * @param {Number} x + * @param {Number} y + * @return {Object} velocity `x` and `y` + */ +function getVelocity(deltaTime, x, y) { + return { + x: x / deltaTime || 0, + y: y / deltaTime || 0 + }; +} + +/** + * get the direction between two points + * @param {Number} x + * @param {Number} y + * @return {Number} direction + */ +function getDirection(x, y) { + if (x === y) { + return DIRECTION_NONE; + } + + if (abs(x) >= abs(y)) { + return x > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; + } + return y > 0 ? DIRECTION_UP : DIRECTION_DOWN; +} + +/** + * calculate the absolute distance between two points + * @param {Object} p1 {x, y} + * @param {Object} p2 {x, y} + * @param {Array} [props] containing x and y keys + * @return {Number} distance + */ +function getDistance(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + + return Math.sqrt((x * x) + (y * y)); +} + +/** + * calculate the angle between two coordinates + * @param {Object} p1 + * @param {Object} p2 + * @param {Array} [props] containing x and y keys + * @return {Number} angle + */ +function getAngle(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + return Math.atan2(y, x) * 180 / Math.PI; +} + +/** + * calculate the rotation degrees between two pointersets + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} rotation + */ +function getRotation(start, end) { + return getAngle(end[1], end[0], PROPS_CLIENT_XY) - getAngle(start[1], start[0], PROPS_CLIENT_XY); +} + +/** + * calculate the scale factor between two pointersets + * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} scale + */ +function getScale(start, end) { + return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); +} + +var MOUSE_INPUT_MAP = { + mousedown: INPUT_START, + mousemove: INPUT_MOVE, + mouseup: INPUT_END +}; + +var MOUSE_ELEMENT_EVENTS = 'mousedown'; +var MOUSE_WINDOW_EVENTS = 'mousemove mouseup'; + +/** + * Mouse events input + * @constructor + * @extends Input + */ +function MouseInput() { + this.evEl = MOUSE_ELEMENT_EVENTS; + this.evWin = MOUSE_WINDOW_EVENTS; + + this.allow = true; // used by Input.TouchMouse to disable mouse events + this.pressed = false; // mousedown state + + Input.apply(this, arguments); +} + +inherit(MouseInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function MEhandler(ev) { + var eventType = MOUSE_INPUT_MAP[ev.type]; + + // on start we want to have the left mouse button down + if (eventType & INPUT_START && ev.button === 0) { + this.pressed = true; + } + + if (eventType & INPUT_MOVE && ev.which !== 1) { + eventType = INPUT_END; + } + + // mouse must be down, and mouse events are allowed (see the TouchMouse input) + if (!this.pressed || !this.allow) { + return; + } + + if (eventType & INPUT_END) { + this.pressed = false; + } + + this.callback(this.manager, eventType, { + pointers: [ev], + changedPointers: [ev], + pointerType: INPUT_TYPE_MOUSE, + srcEvent: ev + }); + } +}); + +var POINTER_INPUT_MAP = { + pointerdown: INPUT_START, + pointermove: INPUT_MOVE, + pointerup: INPUT_END, + pointercancel: INPUT_CANCEL, + pointerout: INPUT_CANCEL +}; + +// in IE10 the pointer types is defined as an enum +var IE10_POINTER_TYPE_ENUM = { + 2: INPUT_TYPE_TOUCH, + 3: INPUT_TYPE_PEN, + 4: INPUT_TYPE_MOUSE, + 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816 +}; + +var POINTER_ELEMENT_EVENTS = 'pointerdown'; +var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; + +// IE10 has prefixed support, and case-sensitive +if (window.MSPointerEvent) { + POINTER_ELEMENT_EVENTS = 'MSPointerDown'; + POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel'; +} + +/** + * Pointer events input + * @constructor + * @extends Input + */ +function PointerEventInput() { + this.evEl = POINTER_ELEMENT_EVENTS; + this.evWin = POINTER_WINDOW_EVENTS; + + Input.apply(this, arguments); + + this.store = (this.manager.session.pointerEvents = []); +} + +inherit(PointerEventInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function PEhandler(ev) { + var store = this.store; + var removePointer = false; + + var eventTypeNormalized = ev.type.toLowerCase().replace('ms', ''); + var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; + var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; + + var isTouch = (pointerType == INPUT_TYPE_TOUCH); + + // get index of the event in the store + var storeIndex = inArray(store, ev.pointerId, 'pointerId'); + + // start and mouse must be down + if (eventType & INPUT_START && (ev.button === 0 || isTouch)) { + if (storeIndex < 0) { + store.push(ev); + storeIndex = store.length - 1; + } + } else if (eventType & (INPUT_END | INPUT_CANCEL)) { + removePointer = true; + } + + // it not found, so the pointer hasn't been down (so it's probably a hover) + if (storeIndex < 0) { + return; + } + + // update the event in the store + store[storeIndex] = ev; + + this.callback(this.manager, eventType, { + pointers: store, + changedPointers: [ev], + pointerType: pointerType, + srcEvent: ev + }); + + if (removePointer) { + // remove from the store + store.splice(storeIndex, 1); + } + } +}); + +var SINGLE_TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL +}; + +var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; +var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel'; + +/** + * Touch events input + * @constructor + * @extends Input + */ +function SingleTouchInput() { + this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; + this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; + this.started = false; + + Input.apply(this, arguments); +} + +inherit(SingleTouchInput, Input, { + handler: function TEhandler(ev) { + var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; + + // should we handle the touch events? + if (type === INPUT_START) { + this.started = true; + } + + if (!this.started) { + return; + } + + var touches = normalizeSingleTouches.call(this, ev, type); + + // when done, reset the started state + if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { + this.started = false; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } +}); + +/** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ +function normalizeSingleTouches(ev, type) { + var all = toArray(ev.touches); + var changed = toArray(ev.changedTouches); + + if (type & (INPUT_END | INPUT_CANCEL)) { + all = uniqueArray(all.concat(changed), 'identifier', true); + } + + return [all, changed]; +} + +var TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL +}; + +var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel'; + +/** + * Multi-user touch events input + * @constructor + * @extends Input + */ +function TouchInput() { + this.evTarget = TOUCH_TARGET_EVENTS; + this.targetIds = {}; + + Input.apply(this, arguments); +} + +inherit(TouchInput, Input, { + handler: function MTEhandler(ev) { + var type = TOUCH_INPUT_MAP[ev.type]; + var touches = getTouches.call(this, ev, type); + if (!touches) { + return; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } +}); + +/** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ +function getTouches(ev, type) { + var allTouches = toArray(ev.touches); + var targetIds = this.targetIds; + + // when there is only one touch, the process can be simplified + if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) { + targetIds[allTouches[0].identifier] = true; + return [allTouches, allTouches]; + } + + var i, + targetTouches, + changedTouches = toArray(ev.changedTouches), + changedTargetTouches = [], + target = this.target; + + // get target touches from touches + targetTouches = allTouches.filter(function(touch) { + return hasParent(touch.target, target); + }); + + // collect touches + if (type === INPUT_START) { + i = 0; + while (i < targetTouches.length) { + targetIds[targetTouches[i].identifier] = true; + i++; + } + } + + // filter changed touches to only contain touches that exist in the collected target ids + i = 0; + while (i < changedTouches.length) { + if (targetIds[changedTouches[i].identifier]) { + changedTargetTouches.push(changedTouches[i]); + } + + // cleanup removed touches + if (type & (INPUT_END | INPUT_CANCEL)) { + delete targetIds[changedTouches[i].identifier]; + } + i++; + } + + if (!changedTargetTouches.length) { + return; + } + + return [ + // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel' + uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), + changedTargetTouches + ]; +} + +/** + * Combined touch and mouse input + * + * Touch has a higher priority then mouse, and while touching no mouse events are allowed. + * This because touch devices also emit mouse events while doing a touch. + * + * @constructor + * @extends Input + */ +function TouchMouseInput() { + Input.apply(this, arguments); + + var handler = bindFn(this.handler, this); + this.touch = new TouchInput(this.manager, handler); + this.mouse = new MouseInput(this.manager, handler); +} + +inherit(TouchMouseInput, Input, { + /** + * handle mouse and touch events + * @param {Hammer} manager + * @param {String} inputEvent + * @param {Object} inputData + */ + handler: function TMEhandler(manager, inputEvent, inputData) { + var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), + isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE); + + // when we're in a touch event, so block all upcoming mouse events + // most mobile browser also emit mouseevents, right after touchstart + if (isTouch) { + this.mouse.allow = false; + } else if (isMouse && !this.mouse.allow) { + return; + } + + // reset the allowMouse when we're done + if (inputEvent & (INPUT_END | INPUT_CANCEL)) { + this.mouse.allow = true; + } + + this.callback(manager, inputEvent, inputData); + }, + + /** + * remove the event listeners + */ + destroy: function destroy() { + this.touch.destroy(); + this.mouse.destroy(); + } +}); + +var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); +var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined; + +// magical touchAction value +var TOUCH_ACTION_COMPUTE = 'compute'; +var TOUCH_ACTION_AUTO = 'auto'; +var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented +var TOUCH_ACTION_NONE = 'none'; +var TOUCH_ACTION_PAN_X = 'pan-x'; +var TOUCH_ACTION_PAN_Y = 'pan-y'; + +/** + * Touch Action + * sets the touchAction property or uses the js alternative + * @param {Manager} manager + * @param {String} value + * @constructor + */ +function TouchAction(manager, value) { + this.manager = manager; + this.set(value); +} + +TouchAction.prototype = { + /** + * set the touchAction value on the element or enable the polyfill + * @param {String} value + */ + set: function(value) { + // find out the touch-action by the event handlers + if (value == TOUCH_ACTION_COMPUTE) { + value = this.compute(); + } + + if (NATIVE_TOUCH_ACTION) { + this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; + } + this.actions = value.toLowerCase().trim(); + }, + + /** + * just re-set the touchAction value + */ + update: function() { + this.set(this.manager.options.touchAction); + }, + + /** + * compute the value for the touchAction property based on the recognizer's settings + * @returns {String} value + */ + compute: function() { + var actions = []; + each(this.manager.recognizers, function(recognizer) { + if (boolOrFn(recognizer.options.enable, [recognizer])) { + actions = actions.concat(recognizer.getTouchAction()); + } + }); + return cleanTouchActions(actions.join(' ')); + }, + + /** + * this method is called on each input cycle and provides the preventing of the browser behavior + * @param {Object} input + */ + preventDefaults: function(input) { + // not needed with native support for the touchAction property + if (NATIVE_TOUCH_ACTION) { + return; + } + + var srcEvent = input.srcEvent; + var direction = input.offsetDirection; + + // if the touch action did prevented once this session + if (this.manager.session.prevented) { + srcEvent.preventDefault(); + return; + } + + var actions = this.actions; + var hasNone = inStr(actions, TOUCH_ACTION_NONE); + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); + + if (hasNone || + (hasPanY && direction & DIRECTION_HORIZONTAL) || + (hasPanX && direction & DIRECTION_VERTICAL)) { + return this.preventSrc(srcEvent); + } + }, + + /** + * call preventDefault to prevent the browser's default behavior (scrolling in most cases) + * @param {Object} srcEvent + */ + preventSrc: function(srcEvent) { + this.manager.session.prevented = true; + srcEvent.preventDefault(); + } +}; + +/** + * when the touchActions are collected they are not a valid value, so we need to clean things up. * + * @param {String} actions + * @returns {*} + */ +function cleanTouchActions(actions) { + // none + if (inStr(actions, TOUCH_ACTION_NONE)) { + return TOUCH_ACTION_NONE; + } + + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); + + // pan-x and pan-y can be combined + if (hasPanX && hasPanY) { + return TOUCH_ACTION_PAN_X + ' ' + TOUCH_ACTION_PAN_Y; + } + + // pan-x OR pan-y + if (hasPanX || hasPanY) { + return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; + } + + // manipulation + if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { + return TOUCH_ACTION_MANIPULATION; + } + + return TOUCH_ACTION_AUTO; +} + +/** + * Recognizer flow explained; * + * All recognizers have the initial state of POSSIBLE when a input session starts. + * The definition of a input session is from the first input until the last input, with all it's movement in it. * + * Example session for mouse-input: mousedown -> mousemove -> mouseup + * + * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed + * which determines with state it should be. + * + * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to + * POSSIBLE to give it another change on the next cycle. + * + * Possible + * | + * +-----+---------------+ + * | | + * +-----+-----+ | + * | | | + * Failed Cancelled | + * +-------+------+ + * | | + * Recognized Began + * | + * Changed + * | + * Ended/Recognized + */ +var STATE_POSSIBLE = 1; +var STATE_BEGAN = 2; +var STATE_CHANGED = 4; +var STATE_ENDED = 8; +var STATE_RECOGNIZED = STATE_ENDED; +var STATE_CANCELLED = 16; +var STATE_FAILED = 32; + +/** + * Recognizer + * Every recognizer needs to extend from this class. + * @constructor + * @param {Object} options + */ +function Recognizer(options) { + this.id = uniqueId(); + + this.manager = null; + this.options = merge(options || {}, this.defaults); + + // default is enable true + this.options.enable = ifUndefined(this.options.enable, true); + + this.state = STATE_POSSIBLE; + + this.simultaneous = {}; + this.requireFail = []; +} + +Recognizer.prototype = { + /** + * @virtual + * @type {Object} + */ + defaults: {}, + + /** + * set options + * @param {Object} options + * @return {Recognizer} + */ + set: function(options) { + extend(this.options, options); + + // also update the touchAction, in case something changed about the directions/enabled state + this.manager && this.manager.touchAction.update(); + return this; + }, + + /** + * recognize simultaneous with an other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + recognizeWith: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) { + return this; + } + + var simultaneous = this.simultaneous; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (!simultaneous[otherRecognizer.id]) { + simultaneous[otherRecognizer.id] = otherRecognizer; + otherRecognizer.recognizeWith(this); + } + return this; + }, + + /** + * drop the simultaneous link. it doesnt remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRecognizeWith: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + delete this.simultaneous[otherRecognizer.id]; + return this; + }, + + /** + * recognizer can only run when an other is failing + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + requireFailure: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) { + return this; + } + + var requireFail = this.requireFail; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (inArray(requireFail, otherRecognizer) === -1) { + requireFail.push(otherRecognizer); + otherRecognizer.requireFailure(this); + } + return this; + }, + + /** + * drop the requireFailure link. it does not remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRequireFailure: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + var index = inArray(this.requireFail, otherRecognizer); + if (index > -1) { + this.requireFail.splice(index, 1); + } + return this; + }, + + /** + * has require failures boolean + * @returns {boolean} + */ + hasRequireFailures: function() { + return this.requireFail.length > 0; + }, + + /** + * if the recognizer can recognize simultaneous with an other recognizer + * @param {Recognizer} otherRecognizer + * @returns {Boolean} + */ + canRecognizeWith: function(otherRecognizer) { + return !!this.simultaneous[otherRecognizer.id]; + }, + + /** + * You should use `tryEmit` instead of `emit` directly to check + * that all the needed recognizers has failed before emitting. + * @param {Object} input + */ + emit: function(input) { + var self = this; + var state = this.state; + + function emit(withState) { + self.manager.emit(self.options.event + (withState ? stateStr(state) : ''), input); + } + + // 'panstart' and 'panmove' + if (state < STATE_ENDED) { + emit(true); + } + + emit(); // simple 'eventName' events + + // panend and pancancel + if (state >= STATE_ENDED) { + emit(true); + } + }, + + /** + * Check that all the require failure recognizers has failed, + * if true, it emits a gesture event, + * otherwise, setup the state to FAILED. + * @param {Object} input + */ + tryEmit: function(input) { + if (this.canEmit()) { + return this.emit(input); + } + // it's failing anyway + this.state = STATE_FAILED; + }, + + /** + * can we emit? + * @returns {boolean} + */ + canEmit: function() { + var i = 0; + while (i < this.requireFail.length) { + if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { + return false; + } + i++; + } + return true; + }, + + /** + * update the recognizer + * @param {Object} inputData + */ + recognize: function(inputData) { + // make a new copy of the inputData + // so we can change the inputData without messing up the other recognizers + var inputDataClone = extend({}, inputData); + + // is is enabled and allow recognizing? + if (!boolOrFn(this.options.enable, [this, inputDataClone])) { + this.reset(); + this.state = STATE_FAILED; + return; + } + + // reset when we've reached the end + if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { + this.state = STATE_POSSIBLE; + } + + this.state = this.process(inputDataClone); + + // the recognizer has recognized a gesture + // so trigger an event + if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { + this.tryEmit(inputDataClone); + } + }, + + /** + * return the state of the recognizer + * the actual recognizing happens in this method + * @virtual + * @param {Object} inputData + * @returns {Const} STATE + */ + process: function(inputData) { }, // jshint ignore:line + + /** + * return the preferred touch-action + * @virtual + * @returns {Array} + */ + getTouchAction: function() { }, + + /** + * called when the gesture isn't allowed to recognize + * like when another is being recognized or it is disabled + * @virtual + */ + reset: function() { } +}; + +/** + * get a usable string, used as event postfix + * @param {Const} state + * @returns {String} state + */ +function stateStr(state) { + if (state & STATE_CANCELLED) { + return 'cancel'; + } else if (state & STATE_ENDED) { + return 'end'; + } else if (state & STATE_CHANGED) { + return 'move'; + } else if (state & STATE_BEGAN) { + return 'start'; + } + return ''; +} + +/** + * direction cons to string + * @param {Const} direction + * @returns {String} + */ +function directionStr(direction) { + if (direction == DIRECTION_DOWN) { + return 'down'; + } else if (direction == DIRECTION_UP) { + return 'up'; + } else if (direction == DIRECTION_LEFT) { + return 'left'; + } else if (direction == DIRECTION_RIGHT) { + return 'right'; + } + return ''; +} + +/** + * get a recognizer by name if it is bound to a manager + * @param {Recognizer|String} otherRecognizer + * @param {Recognizer} recognizer + * @returns {Recognizer} + */ +function getRecognizerByNameIfManager(otherRecognizer, recognizer) { + var manager = recognizer.manager; + if (manager) { + return manager.get(otherRecognizer); + } + return otherRecognizer; +} + +/** + * This recognizer is just used as a base for the simple attribute recognizers. + * @constructor + * @extends Recognizer + */ +function AttrRecognizer() { + Recognizer.apply(this, arguments); +} + +inherit(AttrRecognizer, Recognizer, { + /** + * @namespace + * @memberof AttrRecognizer + */ + defaults: { + /** + * @type {Number} + * @default 1 + */ + pointers: 1 + }, + + /** + * Used to check if it the recognizer receives valid input, like input.distance > 10. + * @memberof AttrRecognizer + * @param {Object} input + * @returns {Boolean} recognized + */ + attrTest: function(input) { + var optionPointers = this.options.pointers; + return optionPointers === 0 || input.pointers.length === optionPointers; + }, + + /** + * Process the input and return the state for the recognizer + * @memberof AttrRecognizer + * @param {Object} input + * @returns {*} State + */ + process: function(input) { + var state = this.state; + var eventType = input.eventType; + + var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); + var isValid = this.attrTest(input); + + // on cancel input and we've recognized before, return STATE_CANCELLED + if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { + return state | STATE_CANCELLED; + } else if (isRecognized || isValid) { + if (eventType & INPUT_END) { + return state | STATE_ENDED; + } else if (!(state & STATE_BEGAN)) { + return STATE_BEGAN; + } + return state | STATE_CHANGED; + } + return STATE_FAILED; + } +}); + +/** + * Pan + * Recognized when the pointer is down and moved in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ +function PanRecognizer() { + AttrRecognizer.apply(this, arguments); + + this.pX = null; + this.pY = null; +} + +inherit(PanRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PanRecognizer + */ + defaults: { + event: 'pan', + threshold: 10, + pointers: 1, + direction: DIRECTION_ALL + }, + + getTouchAction: function() { + var direction = this.options.direction; + var actions = []; + if (direction & DIRECTION_HORIZONTAL) { + actions.push(TOUCH_ACTION_PAN_Y); + } + if (direction & DIRECTION_VERTICAL) { + actions.push(TOUCH_ACTION_PAN_X); + } + return actions; + }, + + directionTest: function(input) { + var options = this.options; + var hasMoved = true; + var distance = input.distance; + var direction = input.direction; + var x = input.deltaX; + var y = input.deltaY; + + // lock to axis? + if (!(direction & options.direction)) { + if (options.direction & DIRECTION_HORIZONTAL) { + direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; + hasMoved = x != this.pX; + distance = Math.abs(input.deltaX); + } else { + direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN; + hasMoved = y != this.pY; + distance = Math.abs(input.deltaY); + } + } + input.direction = direction; + return hasMoved && distance > options.threshold && direction & options.direction; + }, + + attrTest: function(input) { + return AttrRecognizer.prototype.attrTest.call(this, input) && + (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input))); + }, + + emit: function(input) { + this.pX = input.deltaX; + this.pY = input.deltaY; + + var direction = directionStr(input.direction); + if (direction) { + this.manager.emit(this.options.event + direction, input); + } + + this._super.emit.call(this, input); + } +}); + +/** + * Pinch + * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out). + * @constructor + * @extends AttrRecognizer + */ +function PinchRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(PinchRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'pinch', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function(input) { + return this._super.attrTest.call(this, input) && + (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); + }, + + emit: function(input) { + this._super.emit.call(this, input); + if (input.scale !== 1) { + var inOut = input.scale < 1 ? 'in' : 'out'; + this.manager.emit(this.options.event + inOut, input); + } + } +}); + +/** + * Press + * Recognized when the pointer is down for x ms without any movement. + * @constructor + * @extends Recognizer + */ +function PressRecognizer() { + Recognizer.apply(this, arguments); + + this._timer = null; + this._input = null; +} + +inherit(PressRecognizer, Recognizer, { + /** + * @namespace + * @memberof PressRecognizer + */ + defaults: { + event: 'press', + pointers: 1, + time: 500, // minimal time of the pointer to be pressed + threshold: 5 // a minimal movement is ok, but keep it low + }, + + getTouchAction: function() { + return [TOUCH_ACTION_AUTO]; + }, + + process: function(input) { + var options = this.options; + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTime = input.deltaTime > options.time; + + this._input = input; + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) { + this.reset(); + } else if (input.eventType & INPUT_START) { + this.reset(); + this._timer = setTimeoutContext(function() { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.time, this); + } else if (input.eventType & INPUT_END) { + return STATE_RECOGNIZED; + } + return STATE_FAILED; + }, + + reset: function() { + clearTimeout(this._timer); + }, + + emit: function(input) { + if (this.state !== STATE_RECOGNIZED) { + return; + } + + if (input && (input.eventType & INPUT_END)) { + this.manager.emit(this.options.event + 'up', input); + } else { + this._input.timeStamp = now(); + this.manager.emit(this.options.event, this._input); + } + } +}); + +/** + * Rotate + * Recognized when two or more pointer are moving in a circular motion. + * @constructor + * @extends AttrRecognizer + */ +function RotateRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(RotateRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof RotateRecognizer + */ + defaults: { + event: 'rotate', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function(input) { + return this._super.attrTest.call(this, input) && + (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); + } +}); + +/** + * Swipe + * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ +function SwipeRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(SwipeRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof SwipeRecognizer + */ + defaults: { + event: 'swipe', + threshold: 10, + velocity: 0.65, + direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, + pointers: 1 + }, + + getTouchAction: function() { + return PanRecognizer.prototype.getTouchAction.call(this); + }, + + attrTest: function(input) { + var direction = this.options.direction; + var velocity; + + if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { + velocity = input.velocity; + } else if (direction & DIRECTION_HORIZONTAL) { + velocity = input.velocityX; + } else if (direction & DIRECTION_VERTICAL) { + velocity = input.velocityY; + } + + return this._super.attrTest.call(this, input) && + direction & input.direction && + input.distance > this.options.threshold && + abs(velocity) > this.options.velocity && input.eventType & INPUT_END; + }, + + emit: function(input) { + var direction = directionStr(input.direction); + if (direction) { + this.manager.emit(this.options.event + direction, input); + } + + this.manager.emit(this.options.event, input); + } +}); + +/** + * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur + * between the given interval and position. The delay option can be used to recognize multi-taps without firing + * a single tap. + * + * The eventData from the emitted event contains the property `tapCount`, which contains the amount of + * multi-taps being recognized. + * @constructor + * @extends Recognizer + */ +function TapRecognizer() { + Recognizer.apply(this, arguments); + + // previous time and center, + // used for tap counting + this.pTime = false; + this.pCenter = false; + + this._timer = null; + this._input = null; + this.count = 0; +} + +inherit(TapRecognizer, Recognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'tap', + pointers: 1, + taps: 1, + interval: 300, // max time between the multi-tap taps + time: 250, // max time of the pointer to be down (like finger on the screen) + threshold: 2, // a minimal movement is ok, but keep it low + posThreshold: 10 // a multi-tap can be a bit off the initial position + }, + + getTouchAction: function() { + return [TOUCH_ACTION_MANIPULATION]; + }, + + process: function(input) { + var options = this.options; + + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTouchTime = input.deltaTime < options.time; + + this.reset(); + + if ((input.eventType & INPUT_START) && (this.count === 0)) { + return this.failTimeout(); + } + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (validMovement && validTouchTime && validPointers) { + if (input.eventType != INPUT_END) { + return this.failTimeout(); + } + + var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true; + var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; + + this.pTime = input.timeStamp; + this.pCenter = input.center; + + if (!validMultiTap || !validInterval) { + this.count = 1; + } else { + this.count += 1; + } + + this._input = input; + + // if tap count matches we have recognized it, + // else it has began recognizing... + var tapCount = this.count % options.taps; + if (tapCount === 0) { + // no failing requirements, immediately trigger the tap event + // or wait as long as the multitap interval to trigger + if (!this.hasRequireFailures()) { + return STATE_RECOGNIZED; + } else { + this._timer = setTimeoutContext(function() { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.interval, this); + return STATE_BEGAN; + } + } + } + return STATE_FAILED; + }, + + failTimeout: function() { + this._timer = setTimeoutContext(function() { + this.state = STATE_FAILED; + }, this.options.interval, this); + return STATE_FAILED; + }, + + reset: function() { + clearTimeout(this._timer); + }, + + emit: function() { + if (this.state == STATE_RECOGNIZED ) { + this._input.tapCount = this.count; + this.manager.emit(this.options.event, this._input); + } + } +}); + +/** + * Simple way to create an manager with a default set of recognizers. + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ +function Hammer(element, options) { + options = options || {}; + options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); + return new Manager(element, options); +} + +/** + * @const {string} + */ +Hammer.VERSION = '2.0.4'; + +/** + * default settings + * @namespace + */ +Hammer.defaults = { + /** + * set if DOM events are being triggered. + * But this is slower and unused by simple implementations, so disabled by default. + * @type {Boolean} + * @default false + */ + domEvents: false, + + /** + * The value for the touchAction property/fallback. + * When set to `compute` it will magically set the correct value based on the added recognizers. + * @type {String} + * @default compute + */ + touchAction: TOUCH_ACTION_COMPUTE, + + /** + * @type {Boolean} + * @default true + */ + enable: true, + + /** + * EXPERIMENTAL FEATURE -- can be removed/changed + * Change the parent input target element. + * If Null, then it is being set the to main element. + * @type {Null|EventTarget} + * @default null + */ + inputTarget: null, + + /** + * force an input class + * @type {Null|Function} + * @default null + */ + inputClass: null, + + /** + * Default recognizer setup when calling `Hammer()` + * When creating a new Manager these will be skipped. + * @type {Array} + */ + preset: [ + // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...] + [RotateRecognizer, { enable: false }], + [PinchRecognizer, { enable: false }, ['rotate']], + [SwipeRecognizer,{ direction: DIRECTION_HORIZONTAL }], + [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']], + [TapRecognizer], + [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']], + [PressRecognizer] + ], + + /** + * Some CSS properties can be used to improve the working of Hammer. + * Add them to this method and they will be set when creating a new Manager. + * @namespace + */ + cssProps: { + /** + * Disables text selection to improve the dragging gesture. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userSelect: 'none', + + /** + * Disable the Windows Phone grippers when pressing an element. + * @type {String} + * @default 'none' + */ + touchSelect: 'none', + + /** + * Disables the default callout shown when you touch and hold a touch target. + * On iOS, when you touch and hold a touch target such as a link, Safari displays + * a callout containing information about the link. This property allows you to disable that callout. + * @type {String} + * @default 'none' + */ + touchCallout: 'none', + + /** + * Specifies whether zooming is enabled. Used by IE10> + * @type {String} + * @default 'none' + */ + contentZooming: 'none', + + /** + * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userDrag: 'none', + + /** + * Overrides the highlight color shown when the user taps a link or a JavaScript + * clickable element in iOS. This property obeys the alpha value, if specified. + * @type {String} + * @default 'rgba(0,0,0,0)' + */ + tapHighlightColor: 'rgba(0,0,0,0)' + } +}; + +var STOP = 1; +var FORCED_STOP = 2; + +/** + * Manager + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ +function Manager(element, options) { + options = options || {}; + + this.options = merge(options, Hammer.defaults); + this.options.inputTarget = this.options.inputTarget || element; + + this.handlers = {}; + this.session = {}; + this.recognizers = []; + + this.element = element; + this.input = createInputInstance(this); + this.touchAction = new TouchAction(this, this.options.touchAction); + + toggleCssProps(this, true); + + each(options.recognizers, function(item) { + var recognizer = this.add(new (item[0])(item[1])); + item[2] && recognizer.recognizeWith(item[2]); + item[3] && recognizer.requireFailure(item[3]); + }, this); +} + +Manager.prototype = { + /** + * set options + * @param {Object} options + * @returns {Manager} + */ + set: function(options) { + extend(this.options, options); + + // Options that need a little more setup + if (options.touchAction) { + this.touchAction.update(); + } + if (options.inputTarget) { + // Clean up existing event listeners and reinitialize + this.input.destroy(); + this.input.target = options.inputTarget; + this.input.init(); + } + return this; + }, + + /** + * stop recognizing for this session. + * This session will be discarded, when a new [input]start event is fired. + * When forced, the recognizer cycle is stopped immediately. + * @param {Boolean} [force] + */ + stop: function(force) { + this.session.stopped = force ? FORCED_STOP : STOP; + }, + + /** + * run the recognizers! + * called by the inputHandler function on every movement of the pointers (touches) + * it walks through all the recognizers and tries to detect the gesture that is being made + * @param {Object} inputData + */ + recognize: function(inputData) { + var session = this.session; + if (session.stopped) { + return; + } + + // run the touch-action polyfill + this.touchAction.preventDefaults(inputData); + + var recognizer; + var recognizers = this.recognizers; + + // this holds the recognizer that is being recognized. + // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED + // if no recognizer is detecting a thing, it is set to `null` + var curRecognizer = session.curRecognizer; + + // reset when the last recognizer is recognized + // or when we're in a new session + if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) { + curRecognizer = session.curRecognizer = null; + } + + var i = 0; + while (i < recognizers.length) { + recognizer = recognizers[i]; + + // find out if we are allowed try to recognize the input for this one. + // 1. allow if the session is NOT forced stopped (see the .stop() method) + // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one + // that is being recognized. + // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer. + // this can be setup with the `recognizeWith()` method on the recognizer. + if (session.stopped !== FORCED_STOP && ( // 1 + !curRecognizer || recognizer == curRecognizer || // 2 + recognizer.canRecognizeWith(curRecognizer))) { // 3 + recognizer.recognize(inputData); + } else { + recognizer.reset(); + } + + // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the + // current active recognizer. but only if we don't already have an active recognizer + if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { + curRecognizer = session.curRecognizer = recognizer; + } + i++; + } + }, + + /** + * get a recognizer by its event name. + * @param {Recognizer|String} recognizer + * @returns {Recognizer|Null} + */ + get: function(recognizer) { + if (recognizer instanceof Recognizer) { + return recognizer; + } + + var recognizers = this.recognizers; + for (var i = 0; i < recognizers.length; i++) { + if (recognizers[i].options.event == recognizer) { + return recognizers[i]; + } + } + return null; + }, + + /** + * add a recognizer to the manager + * existing recognizers with the same event name will be removed + * @param {Recognizer} recognizer + * @returns {Recognizer|Manager} + */ + add: function(recognizer) { + if (invokeArrayArg(recognizer, 'add', this)) { + return this; + } + + // remove existing + var existing = this.get(recognizer.options.event); + if (existing) { + this.remove(existing); + } + + this.recognizers.push(recognizer); + recognizer.manager = this; + + this.touchAction.update(); + return recognizer; + }, + + /** + * remove a recognizer by name or instance + * @param {Recognizer|String} recognizer + * @returns {Manager} + */ + remove: function(recognizer) { + if (invokeArrayArg(recognizer, 'remove', this)) { + return this; + } + + var recognizers = this.recognizers; + recognizer = this.get(recognizer); + recognizers.splice(inArray(recognizers, recognizer), 1); + + this.touchAction.update(); + return this; + }, + + /** + * bind event + * @param {String} events + * @param {Function} handler + * @returns {EventEmitter} this + */ + on: function(events, handler) { + var handlers = this.handlers; + each(splitStr(events), function(event) { + handlers[event] = handlers[event] || []; + handlers[event].push(handler); + }); + return this; + }, + + /** + * unbind event, leave emit blank to remove all handlers + * @param {String} events + * @param {Function} [handler] + * @returns {EventEmitter} this + */ + off: function(events, handler) { + var handlers = this.handlers; + each(splitStr(events), function(event) { + if (!handler) { + delete handlers[event]; + } else { + handlers[event].splice(inArray(handlers[event], handler), 1); + } + }); + return this; + }, + + /** + * emit event to the listeners + * @param {String} event + * @param {Object} data + */ + emit: function(event, data) { + // we also want to trigger dom events + if (this.options.domEvents) { + triggerDomEvent(event, data); + } + + // no handlers, so skip it all + var handlers = this.handlers[event] && this.handlers[event].slice(); + if (!handlers || !handlers.length) { + return; + } + + data.type = event; + data.preventDefault = function() { + data.srcEvent.preventDefault(); + }; + + var i = 0; + while (i < handlers.length) { + handlers[i](data); + i++; + } + }, + + /** + * destroy the manager and unbinds all events + * it doesn't unbind dom events, that is the user own responsibility + */ + destroy: function() { + this.element && toggleCssProps(this, false); + + this.handlers = {}; + this.session = {}; + this.input.destroy(); + this.element = null; + } +}; + +/** + * add/remove the css properties as defined in manager.options.cssProps + * @param {Manager} manager + * @param {Boolean} add + */ +function toggleCssProps(manager, add) { + var element = manager.element; + each(manager.options.cssProps, function(value, name) { + element.style[prefixed(element.style, name)] = add ? value : ''; + }); +} + +/** + * trigger dom event + * @param {String} event + * @param {Object} data + */ +function triggerDomEvent(event, data) { + var gestureEvent = document.createEvent('Event'); + gestureEvent.initEvent(event, true, true); + gestureEvent.gesture = data; + data.target.dispatchEvent(gestureEvent); +} + +extend(Hammer, { + INPUT_START: INPUT_START, + INPUT_MOVE: INPUT_MOVE, + INPUT_END: INPUT_END, + INPUT_CANCEL: INPUT_CANCEL, + + STATE_POSSIBLE: STATE_POSSIBLE, + STATE_BEGAN: STATE_BEGAN, + STATE_CHANGED: STATE_CHANGED, + STATE_ENDED: STATE_ENDED, + STATE_RECOGNIZED: STATE_RECOGNIZED, + STATE_CANCELLED: STATE_CANCELLED, + STATE_FAILED: STATE_FAILED, + + DIRECTION_NONE: DIRECTION_NONE, + DIRECTION_LEFT: DIRECTION_LEFT, + DIRECTION_RIGHT: DIRECTION_RIGHT, + DIRECTION_UP: DIRECTION_UP, + DIRECTION_DOWN: DIRECTION_DOWN, + DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL, + DIRECTION_VERTICAL: DIRECTION_VERTICAL, + DIRECTION_ALL: DIRECTION_ALL, + + Manager: Manager, + Input: Input, + TouchAction: TouchAction, + + TouchInput: TouchInput, + MouseInput: MouseInput, + PointerEventInput: PointerEventInput, + TouchMouseInput: TouchMouseInput, + SingleTouchInput: SingleTouchInput, + + Recognizer: Recognizer, + AttrRecognizer: AttrRecognizer, + Tap: TapRecognizer, + Pan: PanRecognizer, + Swipe: SwipeRecognizer, + Pinch: PinchRecognizer, + Rotate: RotateRecognizer, + Press: PressRecognizer, + + on: addEventListeners, + off: removeEventListeners, + each: each, + merge: merge, + extend: extend, + inherit: inherit, + bindFn: bindFn, + prefixed: prefixed +}); + +if (typeof define == TYPE_FUNCTION && define.amd) { + define(function() { + return Hammer; + }); +} else if (typeof module != 'undefined' && module.exports) { + module.exports = Hammer; +} else { + window[exportName] = Hammer; +} + +})(window, document, 'Hammer'); diff --git a/hyhproject/mobile2/view/default/js/photoclip/iscroll-zoom.js b/hyhproject/mobile2/view/default/js/photoclip/iscroll-zoom.js new file mode 100755 index 0000000..26c3cc0 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/photoclip/iscroll-zoom.js @@ -0,0 +1,2197 @@ +/*! iScroll v5.1.3 ~ (c) 2008-2014 Matteo Spinelli ~ http://cubiq.org/license */ +(function (window, document, Math) { +var rAF = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { window.setTimeout(callback, 1000 / 60); }; + +var utils = (function () { + var me = {}; + + var _elementStyle = document.createElement('div').style; + var _vendor = (function () { + var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], + transform, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + transform = vendors[i] + 'ransform'; + if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); + } + + return false; + })(); + + function _prefixStyle (style) { + if ( _vendor === false ) return false; + if ( _vendor === '' ) return style; + return _vendor + style.charAt(0).toUpperCase() + style.substr(1); + } + + me.getTime = Date.now || function getTime () { return new Date().getTime(); }; + + me.extend = function (target, obj) { + for ( var i in obj ) { + target[i] = obj[i]; + } + }; + + me.addEvent = function (el, type, fn, capture) { + el.addEventListener(type, fn, !!capture); + }; + + me.removeEvent = function (el, type, fn, capture) { + el.removeEventListener(type, fn, !!capture); + }; + + me.prefixPointerEvent = function (pointerEvent) { + return window.MSPointerEvent ? + 'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10): + pointerEvent; + }; + + me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { + var distance = current - start, + speed = Math.abs(distance) / time, + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + + destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); + duration = speed / deceleration; + + if ( destination < lowerMargin ) { + destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if ( destination > 0 ) { + destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }; + + var _transform = _prefixStyle('transform'); + + me.extend(me, { + hasTransform: _transform !== false, + hasPerspective: _prefixStyle('perspective') in _elementStyle, + hasTouch: 'ontouchstart' in window, + hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed + hasTransition: _prefixStyle('transition') in _elementStyle + }); + + // This should find all Android browsers lower than build 535.19 (both stock browser and webview) + me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion)); + + me.extend(me.style = {}, { + transform: _transform, + transitionTimingFunction: _prefixStyle('transitionTimingFunction'), + transitionDuration: _prefixStyle('transitionDuration'), + transitionDelay: _prefixStyle('transitionDelay'), + transformOrigin: _prefixStyle('transformOrigin') + }); + + me.hasClass = function (e, c) { + var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); + return re.test(e.className); + }; + + me.addClass = function (e, c) { + if ( me.hasClass(e, c) ) { + return; + } + + var newclass = e.className.split(' '); + newclass.push(c); + e.className = newclass.join(' '); + }; + + me.removeClass = function (e, c) { + if ( !me.hasClass(e, c) ) { + return; + } + + var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); + e.className = e.className.replace(re, ' '); + }; + + me.offset = function (el) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + // jshint -W084 + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + // jshint +W084 + + return { + left: left, + top: top + }; + }; + + me.preventDefaultException = function (el, exceptions) { + for ( var i in exceptions ) { + if ( exceptions[i].test(el[i]) ) { + return true; + } + } + + return false; + }; + + me.extend(me.eventType = {}, { + touchstart: 1, + touchmove: 1, + touchend: 1, + + mousedown: 2, + mousemove: 2, + mouseup: 2, + + pointerdown: 3, + pointermove: 3, + pointerup: 3, + + MSPointerDown: 3, + MSPointerMove: 3, + MSPointerUp: 3 + }); + + me.extend(me.ease = {}, { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function (k) { + return k * ( 2 - k ); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1) + fn: function (k) { + return Math.sqrt( 1 - ( --k * k ) ); + } + }, + back: { + style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', + fn: function (k) { + var b = 4; + return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; + } + }, + bounce: { + style: '', + fn: function (k) { + if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { + return 7.5625 * k * k; + } else if ( k < ( 2 / 2.75 ) ) { + return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; + } else if ( k < ( 2.5 / 2.75 ) ) { + return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; + } else { + return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + } + } + }, + elastic: { + style: '', + fn: function (k) { + var f = 0.22, + e = 0.4; + + if ( k === 0 ) { return 0; } + if ( k == 1 ) { return 1; } + + return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); + } + } + }); + + me.tap = function (e, eventName) { + var ev = document.createEvent('Event'); + ev.initEvent(eventName, true, true); + ev.pageX = e.pageX; + ev.pageY = e.pageY; + e.target.dispatchEvent(ev); + }; + + me.click = function (e) { + var target = e.target, + ev; + + if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + target.screenX, target.screenY, target.clientX, target.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + + ev._constructed = true; + target.dispatchEvent(ev); + } + }; + + return me; +})(); + +function IScroll (el, options) { + this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; + this.scroller = this.wrapper.children[0]; + this.scrollerStyle = this.scroller.style; // cache style for better performance + + this.options = { + + zoomMin: 1, + zoomMax: 4, zoomStart: 1, + + resizeScrollbars: true, + + mouseWheelSpeed: 20, + + snapThreshold: 0.334, + +// INSERT POINT: OPTIONS + + startX: 0, + startY: 0, + scrollY: true, + directionLockThreshold: 5, + momentum: true, + + bounce: true, + bounceTime: 600, + bounceEasing: '', + + preventDefault: true, + preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, + + HWCompositing: true, + useTransition: true, + useTransform: true + }; + + for ( var i in options ) { + this.options[i] = options[i]; + } + + // Normalize options + this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; + + this.options.useTransition = utils.hasTransition && this.options.useTransition; + this.options.useTransform = utils.hasTransform && this.options.useTransform; + + this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; + this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; + + // If you want eventPassthrough I have to lock one of the axes + this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; + this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; + + // With eventPassthrough we also need lockDirection mechanism + this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; + this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; + + this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; + + this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; + + if ( this.options.tap === true ) { + this.options.tap = 'tap'; + } + + if ( this.options.shrinkScrollbars == 'scale' ) { + this.options.useTransition = false; + } + + this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; + +// INSERT POINT: NORMALIZATION + + // Some defaults + this.x = 0; + this.y = 0; + this.directionX = 0; + this.directionY = 0; + this._events = {}; + + this.scale = Math.min(Math.max(this.options.zoomStart, this.options.zoomMin), this.options.zoomMax); + +// INSERT POINT: DEFAULTS + + this._init(); + this.refresh(); + + this.scrollTo(this.options.startX, this.options.startY); + this.enable(); +} + +IScroll.prototype = { + version: '5.1.3', + + _init: function () { + this._initEvents(); + + if ( this.options.zoom ) { + this._initZoom(); + } + + if ( this.options.scrollbars || this.options.indicators ) { + this._initIndicators(); + } + + if ( this.options.mouseWheel ) { + this._initWheel(); + } + + if ( this.options.snap ) { + this._initSnap(); + } + + if ( this.options.keyBindings ) { + this._initKeys(); + } + +// INSERT POINT: _init + + }, + + destroy: function () { + this._initEvents(true); + + this._execEvent('destroy'); + }, + + _transitionEnd: function (e) { + if ( e.target != this.scroller || !this.isInTransition ) { + return; + } + + this._transitionTime(); + if ( !this.resetPosition(this.options.bounceTime) ) { + this.isInTransition = false; + this._execEvent('scrollEnd'); + } + }, + + _start: function (e) { + // React to left mouse button only + if ( utils.eventType[e.type] != 1 ) { + if ( e.button !== 0 ) { + return; + } + } + + if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { + return; + } + + if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, + pos; + + this.initiated = utils.eventType[e.type]; + this.moved = false; + this.distX = 0; + this.distY = 0; + this.directionX = 0; + this.directionY = 0; + this.directionLocked = 0; + + this._transitionTime(); + + this.startTime = utils.getTime(); + + if ( this.options.useTransition && this.isInTransition ) { + this.isInTransition = false; + pos = this.getComputedPosition(); + this._translate(Math.round(pos.x), Math.round(pos.y)); + this._execEvent('scrollEnd'); + } else if ( !this.options.useTransition && this.isAnimating ) { + this.isAnimating = false; + this._execEvent('scrollEnd'); + } + + this.startX = this.x; + this.startY = this.y; + this.absStartX = this.x; + this.absStartY = this.y; + this.pointX = point.pageX; + this.pointY = point.pageY; + + this._execEvent('beforeScrollStart'); + }, + + _move: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, + deltaX = point.pageX - this.pointX, + deltaY = point.pageY - this.pointY, + timestamp = utils.getTime(), + newX, newY, + absDistX, absDistY; + + this.pointX = point.pageX; + this.pointY = point.pageY; + + this.distX += deltaX; + this.distY += deltaY; + absDistX = Math.abs(this.distX); + absDistY = Math.abs(this.distY); + + // We need to move at least 10 pixels for the scrolling to initiate + if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { + return; + } + + // If you are scrolling in one direction lock the other + if ( !this.directionLocked && !this.options.freeScroll ) { + if ( absDistX > absDistY + this.options.directionLockThreshold ) { + this.directionLocked = 'h'; // lock horizontally + } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { + this.directionLocked = 'v'; // lock vertically + } else { + this.directionLocked = 'n'; // no lock + } + } + + if ( this.directionLocked == 'h' ) { + if ( this.options.eventPassthrough == 'vertical' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'horizontal' ) { + this.initiated = false; + return; + } + + deltaY = 0; + } else if ( this.directionLocked == 'v' ) { + if ( this.options.eventPassthrough == 'horizontal' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'vertical' ) { + this.initiated = false; + return; + } + + deltaX = 0; + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + // Slow down if outside of the boundaries + if ( newX > 0 || newX < this.maxScrollX ) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if ( newY > 0 || newY < this.maxScrollY ) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + if ( !this.moved ) { + this._execEvent('scrollStart'); + } + + this.moved = true; + + this._translate(newX, newY); + +/* REPLACE START: _move */ + + if ( timestamp - this.startTime > 300 ) { + this.startTime = timestamp; + this.startX = this.x; + this.startY = this.y; + } + +/* REPLACE END: _move */ + + }, + + _end: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.changedTouches ? e.changedTouches[0] : e, + momentumX, + momentumY, + duration = utils.getTime() - this.startTime, + newX = Math.round(this.x), + newY = Math.round(this.y), + distanceX = Math.abs(newX - this.startX), + distanceY = Math.abs(newY - this.startY), + time = 0, + easing = ''; + + this.isInTransition = 0; + this.initiated = 0; + this.endTime = utils.getTime(); + + // reset if we are outside of the boundaries + if ( this.resetPosition(this.options.bounceTime) ) { + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + // we scrolled less than 10 pixels + if ( !this.moved ) { + if ( this.options.tap ) { + utils.tap(e, this.options.tap); + } + + if ( this.options.click ) { + utils.click(e); + } + + this._execEvent('scrollCancel'); + return; + } + + if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { + this._execEvent('flick'); + return; + } + + // start momentum animation if needed + if ( this.options.momentum && duration < 300 ) { + momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 }; + momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = 1; + } + + + if ( this.options.snap ) { + var snap = this._nearestSnap(newX, newY); + this.currentPage = snap; + time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(newX - snap.x), 1000), + Math.min(Math.abs(newY - snap.y), 1000) + ), 300); + newX = snap.x; + newY = snap.y; + + this.directionX = 0; + this.directionY = 0; + easing = this.options.bounceEasing; + } + +// INSERT POINT: _end + + if ( newX != this.x || newY != this.y ) { + // change easing function when scroller goes out of the boundaries + if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { + easing = utils.ease.quadratic; + } + + this.scrollTo(newX, newY, time, easing); + return; + } + + this._execEvent('scrollEnd'); + }, + + _resize: function () { + var that = this; + + clearTimeout(this.resizeTimeout); + + this.resizeTimeout = setTimeout(function () { + that.refresh(); + }, this.options.resizePolling); + }, + + resetPosition: function (time) { + var x = this.x, + y = this.y; + + time = time || 0; + + if ( !this.hasHorizontalScroll || this.x > 0 ) { + x = 0; + } else if ( this.x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( !this.hasVerticalScroll || this.y > 0 ) { + y = 0; + } else if ( this.y < this.maxScrollY ) { + y = this.maxScrollY; + } + + if ( x == this.x && y == this.y ) { + return false; + } + + this.scrollTo(x, y, time, this.options.bounceEasing); + + return true; + }, + + disable: function () { + this.enabled = false; + }, + + enable: function () { + this.enabled = true; + }, + + refresh: function () { + var rf = this.wrapper.offsetHeight; // Force reflow + + this.wrapperWidth = this.wrapper.clientWidth; + this.wrapperHeight = this.wrapper.clientHeight; + +/* REPLACE START: refresh */ + this.scrollerWidth = Math.round(this.scroller.offsetWidth * this.scale); + this.scrollerHeight = Math.round(this.scroller.offsetHeight * this.scale); + + this.maxScrollX = this.wrapperWidth - this.scrollerWidth; + this.maxScrollY = this.wrapperHeight - this.scrollerHeight; +/* REPLACE END: refresh */ + + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + + if ( !this.hasHorizontalScroll ) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if ( !this.hasVerticalScroll ) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.endTime = 0; + this.directionX = 0; + this.directionY = 0; + + this.wrapperOffset = utils.offset(this.wrapper); + + this._execEvent('refresh'); + + this.resetPosition(this.options.bounceTime); + +// INSERT POINT: _refresh + + }, + + on: function (type, fn) { + if ( !this._events[type] ) { + this._events[type] = []; + } + + this._events[type].push(fn); + }, + + off: function (type, fn) { + if ( !this._events[type] ) { + return; + } + + var index = this._events[type].indexOf(fn); + + if ( index > -1 ) { + this._events[type].splice(index, 1); + } + }, + + _execEvent: function (type) { + if ( !this._events[type] ) { + return; + } + + var i = 0, + l = this._events[type].length; + + if ( !l ) { + return; + } + + for ( ; i < l; i++ ) { + this._events[type][i].apply(this, [].slice.call(arguments, 1)); + } + }, + + scrollBy: function (x, y, time, easing) { + x = this.x + x; + y = this.y + y; + time = time || 0; + + this.scrollTo(x, y, time, easing); + }, + + scrollTo: function (x, y, time, easing) { + easing = easing || utils.ease.circular; + + this.isInTransition = this.options.useTransition && time > 0; + + if ( !time || (this.options.useTransition && easing.style) ) { + this._transitionTimingFunction(easing.style); + this._transitionTime(time); + this._translate(x, y); + } else { + this._animate(x, y, time, easing.fn); + } + }, + + scrollToElement: function (el, time, offsetX, offsetY, easing) { + el = el.nodeType ? el : this.scroller.querySelector(el); + + if ( !el ) { + return; + } + + var pos = utils.offset(el); + + pos.left -= this.wrapperOffset.left; + pos.top -= this.wrapperOffset.top; + + // if offsetX/Y are true we center the element to the screen + if ( offsetX === true ) { + offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); + } + if ( offsetY === true ) { + offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); + } + + pos.left -= offsetX || 0; + pos.top -= offsetY || 0; + + pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; + pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; + + time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; + + this.scrollTo(pos.left, pos.top, time, easing); + }, + + _transitionTime: function (time) { + time = time || 0; + + this.scrollerStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.scrollerStyle[utils.style.transitionDuration] = '0.001s'; + } + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].transitionTime(time); + } + } + + +// INSERT POINT: _transitionTime + + }, + + _transitionTimingFunction: function (easing) { + this.scrollerStyle[utils.style.transitionTimingFunction] = easing; + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].transitionTimingFunction(easing); + } + } + + +// INSERT POINT: _transitionTimingFunction + + }, + + _translate: function (x, y) { + if ( this.options.useTransform ) { + +/* REPLACE START: _translate */ this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ') ' + this.translateZ;/* REPLACE END: _translate */ + + } else { + x = Math.round(x); + y = Math.round(y); + this.scrollerStyle.left = x + 'px'; + this.scrollerStyle.top = y + 'px'; + } + + this.x = x; + this.y = y; + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].updatePosition(); + } + } + + +// INSERT POINT: _translate + + }, + + _initEvents: function (remove) { + var eventType = remove ? utils.removeEvent : utils.addEvent, + target = this.options.bindToWrapper ? this.wrapper : window; + + eventType(window, 'orientationchange', this); + eventType(window, 'resize', this); + + if ( this.options.click ) { + eventType(this.wrapper, 'click', this, true); + } + + if ( !this.options.disableMouse ) { + eventType(this.wrapper, 'mousedown', this); + eventType(target, 'mousemove', this); + eventType(target, 'mousecancel', this); + eventType(target, 'mouseup', this); + } + + if ( utils.hasPointer && !this.options.disablePointer ) { + eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); + eventType(target, utils.prefixPointerEvent('pointermove'), this); + eventType(target, utils.prefixPointerEvent('pointercancel'), this); + eventType(target, utils.prefixPointerEvent('pointerup'), this); + } + + if ( utils.hasTouch && !this.options.disableTouch ) { + eventType(this.wrapper, 'touchstart', this); + eventType(target, 'touchmove', this); + eventType(target, 'touchcancel', this); + eventType(target, 'touchend', this); + } + + eventType(this.scroller, 'transitionend', this); + eventType(this.scroller, 'webkitTransitionEnd', this); + eventType(this.scroller, 'oTransitionEnd', this); + eventType(this.scroller, 'MSTransitionEnd', this); + }, + + getComputedPosition: function () { + var matrix = window.getComputedStyle(this.scroller, null), + x, y; + + if ( this.options.useTransform ) { + matrix = matrix[utils.style.transform].split(')')[0].split(', '); + x = +(matrix[12] || matrix[4]); + y = +(matrix[13] || matrix[5]); + } else { + x = +matrix.left.replace(/[^-\d.]/g, ''); + y = +matrix.top.replace(/[^-\d.]/g, ''); + } + + return { x: x, y: y }; + }, + + _initIndicators: function () { + var interactive = this.options.interactiveScrollbars, + customStyle = typeof this.options.scrollbars != 'string', + indicators = [], + indicator; + + var that = this; + + this.indicators = []; + + if ( this.options.scrollbars ) { + // Vertical scrollbar + if ( this.options.scrollY ) { + indicator = { + el: createDefaultScrollbar('v', interactive, this.options.scrollbars), + interactive: interactive, + defaultScrollbars: true, + customStyle: customStyle, + resize: this.options.resizeScrollbars, + shrink: this.options.shrinkScrollbars, + fade: this.options.fadeScrollbars, + listenX: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + // Horizontal scrollbar + if ( this.options.scrollX ) { + indicator = { + el: createDefaultScrollbar('h', interactive, this.options.scrollbars), + interactive: interactive, + defaultScrollbars: true, + customStyle: customStyle, + resize: this.options.resizeScrollbars, + shrink: this.options.shrinkScrollbars, + fade: this.options.fadeScrollbars, + listenY: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + } + + if ( this.options.indicators ) { + // TODO: check concat compatibility + indicators = indicators.concat(this.options.indicators); + } + + for ( var i = indicators.length; i--; ) { + this.indicators.push( new Indicator(this, indicators[i]) ); + } + + // TODO: check if we can use array.map (wide compatibility and performance issues) + function _indicatorsMap (fn) { + for ( var i = that.indicators.length; i--; ) { + fn.call(that.indicators[i]); + } + } + + if ( this.options.fadeScrollbars ) { + this.on('scrollEnd', function () { + _indicatorsMap(function () { + this.fade(); + }); + }); + + this.on('scrollCancel', function () { + _indicatorsMap(function () { + this.fade(); + }); + }); + + this.on('scrollStart', function () { + _indicatorsMap(function () { + this.fade(1); + }); + }); + + this.on('beforeScrollStart', function () { + _indicatorsMap(function () { + this.fade(1, true); + }); + }); + } + + + this.on('refresh', function () { + _indicatorsMap(function () { + this.refresh(); + }); + }); + + this.on('destroy', function () { + _indicatorsMap(function () { + this.destroy(); + }); + + delete this.indicators; + }); + }, + + _initZoom: function () { + this.scrollerStyle[utils.style.transformOrigin] = '0 0'; + }, + + _zoomStart: function (e) { + var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ), + c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY ); + + this.touchesDistanceStart = Math.sqrt(c1 * c1 + c2 * c2); + this.startScale = this.scale; + + this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 + this.wrapperOffset.left - this.x; + this.originY = Math.abs(e.touches[0].pageY + e.touches[1].pageY) / 2 + this.wrapperOffset.top - this.y; + + this._execEvent('zoomStart'); + }, + + _zoom: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { + e.preventDefault(); + } + + var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ), + c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY ), + distance = Math.sqrt( c1 * c1 + c2 * c2 ), + scale = 1 / this.touchesDistanceStart * distance * this.startScale, + lastScale, + x, y; + + this.scaled = true; + + if ( scale < this.options.zoomMin ) { + scale = 0.5 * this.options.zoomMin * Math.pow(2.0, scale / this.options.zoomMin); + } else if ( scale > this.options.zoomMax ) { + scale = 2.0 * this.options.zoomMax * Math.pow(0.5, this.options.zoomMax / scale); + } + + lastScale = scale / this.startScale; + x = this.originX - this.originX * lastScale + this.startX; + y = this.originY - this.originY * lastScale + this.startY; + + this.scale = scale; + + this.scrollTo(x, y, 0); + }, + + _zoomEnd: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { + e.preventDefault(); + } + + var newX, newY, + lastScale; + + this.isInTransition = 0; + this.initiated = 0; + + if ( this.scale > this.options.zoomMax ) { + this.scale = this.options.zoomMax; + } else if ( this.scale < this.options.zoomMin ) { + this.scale = this.options.zoomMin; + } + + // Update boundaries + this.refresh(); + + lastScale = this.scale / this.startScale; + + newX = this.originX - this.originX * lastScale + this.startX; + newY = this.originY - this.originY * lastScale + this.startY; + + if ( newX > 0 ) { + newX = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + } + + if ( newY > 0 ) { + newY = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + } + + this.scrollTo(newX, newY, this.options.bounceTime); + + this.scaled = false; + + this._execEvent('zoomEnd'); + }, + + zoom: function (scale, x, y, time) { + if ( scale < this.options.zoomMin ) { + scale = this.options.zoomMin; + } else if ( scale > this.options.zoomMax ) { + scale = this.options.zoomMax; + } + + if ( scale == this.scale ) { + return; + } + + var relScale = scale / this.scale; + + x = x === undefined ? this.wrapperWidth / 2 - this.wrapperOffset.left : x; + y = y === undefined ? this.wrapperHeight / 2 - this.wrapperOffset.top : y; + time = time === undefined ? 300 : time; + + x = x + this.wrapperOffset.left - this.x; + y = y + this.wrapperOffset.top - this.y; + + x = x - x * relScale + this.x; + y = y - y * relScale + this.y; + + this.scale = scale; + + this.refresh(); // update boundaries + + if ( x > 0 ) { + x = 0; + } else if ( x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( y > 0 ) { + y = 0; + } else if ( y < this.maxScrollY ) { + y = this.maxScrollY; + } + + this.scrollTo(x, y, time); + }, + + _wheelZoom: function (e) { + var wheelDeltaY, + deltaScale, + that = this; + + // Execute the zoomEnd event after 400ms the wheel stopped scrolling + clearTimeout(this.wheelTimeout); + this.wheelTimeout = setTimeout(function () { + that._execEvent('zoomEnd'); + }, 400); + + if ( 'deltaY' in e ) { + wheelDeltaY = -e.deltaY / Math.abs(e.deltaY); + } else if ('wheelDeltaY' in e) { + wheelDeltaY = e.wheelDeltaY / Math.abs(e.wheelDeltaY); + } else if('wheelDelta' in e) { + wheelDeltaY = e.wheelDelta / Math.abs(e.wheelDelta); + } else if ('detail' in e) { + wheelDeltaY = -e.detail / Math.abs(e.detail); + } else { + return; + } + + if (isNaN(wheelDeltaY)) wheelDeltaY = 0; + deltaScale = this.scale + wheelDeltaY * .01; + + this.zoom(deltaScale, e.pageX, e.pageY, 0); + + e.preventDefault(); + e.stopPropagation(); + }, + + _initWheel: function () { + utils.addEvent(this.wrapper, 'wheel', this); + utils.addEvent(this.wrapper, 'mousewheel', this); + utils.addEvent(this.wrapper, 'DOMMouseScroll', this); + + this.on('destroy', function () { + utils.removeEvent(this.wrapper, 'wheel', this); + utils.removeEvent(this.wrapper, 'mousewheel', this); + utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); + }); + }, + + _wheel: function (e) { + if ( !this.enabled ) { + return; + } + + e.preventDefault(); + e.stopPropagation(); + + var wheelDeltaX, wheelDeltaY, + newX, newY, + that = this; + + if ( this.wheelTimeout === undefined ) { + that._execEvent('scrollStart'); + } + + // Execute the scrollEnd event after 400ms the wheel stopped scrolling + clearTimeout(this.wheelTimeout); + this.wheelTimeout = setTimeout(function () { + that._execEvent('scrollEnd'); + that.wheelTimeout = undefined; + }, 400); + + if ( 'deltaX' in e ) { + if (e.deltaMode === 1) { + wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; + wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; + } else { + wheelDeltaX = -e.deltaX; + wheelDeltaY = -e.deltaY; + } + } else if ( 'wheelDeltaX' in e ) { + wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; + wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; + } else if ( 'wheelDelta' in e ) { + wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; + } else if ( 'detail' in e ) { + wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; + } else { + return; + } + + wheelDeltaX *= this.options.invertWheelDirection; + wheelDeltaY *= this.options.invertWheelDirection; + + if ( !this.hasVerticalScroll ) { + wheelDeltaX = wheelDeltaY; + wheelDeltaY = 0; + } + + if ( this.options.snap ) { + newX = this.currentPage.pageX; + newY = this.currentPage.pageY; + + if ( wheelDeltaX > 0 ) { + newX--; + } else if ( wheelDeltaX < 0 ) { + newX++; + } + + if ( wheelDeltaY > 0 ) { + newY--; + } else if ( wheelDeltaY < 0 ) { + newY++; + } + + this.goToPage(newX, newY); + + return; + } + + newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); + newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); + + if ( newX > 0 ) { + newX = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + } + + if ( newY > 0 ) { + newY = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + } + + this.scrollTo(newX, newY, 0); + +// INSERT POINT: _wheel + }, + + _initSnap: function () { + this.currentPage = {}; + + if ( typeof this.options.snap == 'string' ) { + this.options.snap = this.scroller.querySelectorAll(this.options.snap); + } + + this.on('refresh', function () { + var i = 0, l, + m = 0, n, + cx, cy, + x = 0, y, + stepX = this.options.snapStepX || this.wrapperWidth, + stepY = this.options.snapStepY || this.wrapperHeight, + el; + + this.pages = []; + + if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { + return; + } + + if ( this.options.snap === true ) { + cx = Math.round( stepX / 2 ); + cy = Math.round( stepY / 2 ); + + while ( x > -this.scrollerWidth ) { + this.pages[i] = []; + l = 0; + y = 0; + + while ( y > -this.scrollerHeight ) { + this.pages[i][l] = { + x: Math.max(x, this.maxScrollX), + y: Math.max(y, this.maxScrollY), + width: stepX, + height: stepY, + cx: x - cx, + cy: y - cy + }; + + y -= stepY; + l++; + } + + x -= stepX; + i++; + } + } else { + el = this.options.snap; + l = el.length; + n = -1; + + for ( ; i < l; i++ ) { + if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { + m = 0; + n++; + } + + if ( !this.pages[m] ) { + this.pages[m] = []; + } + + x = Math.max(-el[i].offsetLeft, this.maxScrollX); + y = Math.max(-el[i].offsetTop, this.maxScrollY); + cx = x - Math.round(el[i].offsetWidth / 2); + cy = y - Math.round(el[i].offsetHeight / 2); + + this.pages[m][n] = { + x: x, + y: y, + width: el[i].offsetWidth, + height: el[i].offsetHeight, + cx: cx, + cy: cy + }; + + if ( x > this.maxScrollX ) { + m++; + } + } + } + + this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); + + // Update snap threshold if needed + if ( this.options.snapThreshold % 1 === 0 ) { + this.snapThresholdX = this.options.snapThreshold; + this.snapThresholdY = this.options.snapThreshold; + } else { + this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); + this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); + } + }); + + this.on('flick', function () { + var time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(this.x - this.startX), 1000), + Math.min(Math.abs(this.y - this.startY), 1000) + ), 300); + + this.goToPage( + this.currentPage.pageX + this.directionX, + this.currentPage.pageY + this.directionY, + time + ); + }); + }, + + _nearestSnap: function (x, y) { + if ( !this.pages.length ) { + return { x: 0, y: 0, pageX: 0, pageY: 0 }; + } + + var i = 0, + l = this.pages.length, + m = 0; + + // Check if we exceeded the snap threshold + if ( Math.abs(x - this.absStartX) < this.snapThresholdX && + Math.abs(y - this.absStartY) < this.snapThresholdY ) { + return this.currentPage; + } + + if ( x > 0 ) { + x = 0; + } else if ( x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( y > 0 ) { + y = 0; + } else if ( y < this.maxScrollY ) { + y = this.maxScrollY; + } + + for ( ; i < l; i++ ) { + if ( x >= this.pages[i][0].cx ) { + x = this.pages[i][0].x; + break; + } + } + + l = this.pages[i].length; + + for ( ; m < l; m++ ) { + if ( y >= this.pages[0][m].cy ) { + y = this.pages[0][m].y; + break; + } + } + + if ( i == this.currentPage.pageX ) { + i += this.directionX; + + if ( i < 0 ) { + i = 0; + } else if ( i >= this.pages.length ) { + i = this.pages.length - 1; + } + + x = this.pages[i][0].x; + } + + if ( m == this.currentPage.pageY ) { + m += this.directionY; + + if ( m < 0 ) { + m = 0; + } else if ( m >= this.pages[0].length ) { + m = this.pages[0].length - 1; + } + + y = this.pages[0][m].y; + } + + return { + x: x, + y: y, + pageX: i, + pageY: m + }; + }, + + goToPage: function (x, y, time, easing) { + easing = easing || this.options.bounceEasing; + + if ( x >= this.pages.length ) { + x = this.pages.length - 1; + } else if ( x < 0 ) { + x = 0; + } + + if ( y >= this.pages[x].length ) { + y = this.pages[x].length - 1; + } else if ( y < 0 ) { + y = 0; + } + + var posX = this.pages[x][y].x, + posY = this.pages[x][y].y; + + time = time === undefined ? this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(posX - this.x), 1000), + Math.min(Math.abs(posY - this.y), 1000) + ), 300) : time; + + this.currentPage = { + x: posX, + y: posY, + pageX: x, + pageY: y + }; + + this.scrollTo(posX, posY, time, easing); + }, + + next: function (time, easing) { + var x = this.currentPage.pageX, + y = this.currentPage.pageY; + + x++; + + if ( x >= this.pages.length && this.hasVerticalScroll ) { + x = 0; + y++; + } + + this.goToPage(x, y, time, easing); + }, + + prev: function (time, easing) { + var x = this.currentPage.pageX, + y = this.currentPage.pageY; + + x--; + + if ( x < 0 && this.hasVerticalScroll ) { + x = 0; + y--; + } + + this.goToPage(x, y, time, easing); + }, + + _initKeys: function (e) { + // default key bindings + var keys = { + pageUp: 33, + pageDown: 34, + end: 35, + home: 36, + left: 37, + up: 38, + right: 39, + down: 40 + }; + var i; + + // if you give me characters I give you keycode + if ( typeof this.options.keyBindings == 'object' ) { + for ( i in this.options.keyBindings ) { + if ( typeof this.options.keyBindings[i] == 'string' ) { + this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0); + } + } + } else { + this.options.keyBindings = {}; + } + + for ( i in keys ) { + this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; + } + + utils.addEvent(window, 'keydown', this); + + this.on('destroy', function () { + utils.removeEvent(window, 'keydown', this); + }); + }, + + _key: function (e) { + if ( !this.enabled ) { + return; + } + + var snap = this.options.snap, // we are using this alot, better to cache it + newX = snap ? this.currentPage.pageX : this.x, + newY = snap ? this.currentPage.pageY : this.y, + now = utils.getTime(), + prevTime = this.keyTime || 0, + acceleration = 0.250, + pos; + + if ( this.options.useTransition && this.isInTransition ) { + pos = this.getComputedPosition(); + + this._translate(Math.round(pos.x), Math.round(pos.y)); + this.isInTransition = false; + } + + this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; + + switch ( e.keyCode ) { + case this.options.keyBindings.pageUp: + if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { + newX += snap ? 1 : this.wrapperWidth; + } else { + newY += snap ? 1 : this.wrapperHeight; + } + break; + case this.options.keyBindings.pageDown: + if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { + newX -= snap ? 1 : this.wrapperWidth; + } else { + newY -= snap ? 1 : this.wrapperHeight; + } + break; + case this.options.keyBindings.end: + newX = snap ? this.pages.length-1 : this.maxScrollX; + newY = snap ? this.pages[0].length-1 : this.maxScrollY; + break; + case this.options.keyBindings.home: + newX = 0; + newY = 0; + break; + case this.options.keyBindings.left: + newX += snap ? -1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.up: + newY += snap ? 1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.right: + newX -= snap ? -1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.down: + newY -= snap ? 1 : 5 + this.keyAcceleration>>0; + break; + default: + return; + } + + if ( snap ) { + this.goToPage(newX, newY); + return; + } + + if ( newX > 0 ) { + newX = 0; + this.keyAcceleration = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + this.keyAcceleration = 0; + } + + if ( newY > 0 ) { + newY = 0; + this.keyAcceleration = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + this.keyAcceleration = 0; + } + + this.scrollTo(newX, newY, 0); + + this.keyTime = now; + }, + + _animate: function (destX, destY, duration, easingFn) { + var that = this, + startX = this.x, + startY = this.y, + startTime = utils.getTime(), + destTime = startTime + duration; + + function step () { + var now = utils.getTime(), + newX, newY, + easing; + + if ( now >= destTime ) { + that.isAnimating = false; + that._translate(destX, destY); + + if ( !that.resetPosition(that.options.bounceTime) ) { + that._execEvent('scrollEnd'); + } + + return; + } + + now = ( now - startTime ) / duration; + easing = easingFn(now); + newX = ( destX - startX ) * easing + startX; + newY = ( destY - startY ) * easing + startY; + that._translate(newX, newY); + + if ( that.isAnimating ) { + rAF(step); + } + } + + this.isAnimating = true; + step(); + }, + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + + if ( this.options.zoom && e.touches && e.touches.length > 1 ) { + this._zoomStart(e); + } + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + if ( this.options.zoom && e.touches && e.touches[1] ) { + this._zoom(e); + return; + } + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + if ( this.scaled ) { + this._zoomEnd(e); + return; + } + this._end(e); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'transitionend': + case 'webkitTransitionEnd': + case 'oTransitionEnd': + case 'MSTransitionEnd': + this._transitionEnd(e); + break; + case 'wheel': + case 'DOMMouseScroll': + case 'mousewheel': + if ( this.options.wheelAction == 'zoom' ) { + this._wheelZoom(e); + return; + } + this._wheel(e); + break; + case 'keydown': + this._key(e); + break; + } + } + +}; +function createDefaultScrollbar (direction, interactive, type) { + var scrollbar = document.createElement('div'), + indicator = document.createElement('div'); + + if ( type === true ) { + scrollbar.style.cssText = 'position:absolute;z-index:9999'; + indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px'; + } + + indicator.className = 'iScrollIndicator'; + + if ( direction == 'h' ) { + if ( type === true ) { + scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; + indicator.style.height = '100%'; + } + scrollbar.className = 'iScrollHorizontalScrollbar'; + } else { + if ( type === true ) { + scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; + indicator.style.width = '100%'; + } + scrollbar.className = 'iScrollVerticalScrollbar'; + } + + scrollbar.style.cssText += ';overflow:hidden'; + + if ( !interactive ) { + scrollbar.style.pointerEvents = 'none'; + } + + scrollbar.appendChild(indicator); + + return scrollbar; +} + +function Indicator (scroller, options) { + this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; + this.wrapperStyle = this.wrapper.style; + this.indicator = this.wrapper.children[0]; + this.indicatorStyle = this.indicator.style; + this.scroller = scroller; + + this.options = { + listenX: true, + listenY: true, + interactive: false, + resize: true, + defaultScrollbars: false, + shrink: false, + fade: false, + speedRatioX: 0, + speedRatioY: 0 + }; + + for ( var i in options ) { + this.options[i] = options[i]; + } + + this.sizeRatioX = 1; + this.sizeRatioY = 1; + this.maxPosX = 0; + this.maxPosY = 0; + + if ( this.options.interactive ) { + if ( !this.options.disableTouch ) { + utils.addEvent(this.indicator, 'touchstart', this); + utils.addEvent(window, 'touchend', this); + } + if ( !this.options.disablePointer ) { + utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); + utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); + } + if ( !this.options.disableMouse ) { + utils.addEvent(this.indicator, 'mousedown', this); + utils.addEvent(window, 'mouseup', this); + } + } + + if ( this.options.fade ) { + this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; + this.wrapperStyle[utils.style.transitionDuration] = utils.isBadAndroid ? '0.001s' : '0ms'; + this.wrapperStyle.opacity = '0'; + } +} + +Indicator.prototype = { + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + this._end(e); + break; + } + }, + + destroy: function () { + if ( this.options.interactive ) { + utils.removeEvent(this.indicator, 'touchstart', this); + utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); + utils.removeEvent(this.indicator, 'mousedown', this); + + utils.removeEvent(window, 'touchmove', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); + utils.removeEvent(window, 'mousemove', this); + + utils.removeEvent(window, 'touchend', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); + utils.removeEvent(window, 'mouseup', this); + } + + if ( this.options.defaultScrollbars ) { + this.wrapper.parentNode.removeChild(this.wrapper); + } + }, + + _start: function (e) { + var point = e.touches ? e.touches[0] : e; + + e.preventDefault(); + e.stopPropagation(); + + this.transitionTime(); + + this.initiated = true; + this.moved = false; + this.lastPointX = point.pageX; + this.lastPointY = point.pageY; + + this.startTime = utils.getTime(); + + if ( !this.options.disableTouch ) { + utils.addEvent(window, 'touchmove', this); + } + if ( !this.options.disablePointer ) { + utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); + } + if ( !this.options.disableMouse ) { + utils.addEvent(window, 'mousemove', this); + } + + this.scroller._execEvent('beforeScrollStart'); + }, + + _move: function (e) { + var point = e.touches ? e.touches[0] : e, + deltaX, deltaY, + newX, newY, + timestamp = utils.getTime(); + + if ( !this.moved ) { + this.scroller._execEvent('scrollStart'); + } + + this.moved = true; + + deltaX = point.pageX - this.lastPointX; + this.lastPointX = point.pageX; + + deltaY = point.pageY - this.lastPointY; + this.lastPointY = point.pageY; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + this._pos(newX, newY); + +// INSERT POINT: indicator._move + + e.preventDefault(); + e.stopPropagation(); + }, + + _end: function (e) { + if ( !this.initiated ) { + return; + } + + this.initiated = false; + + e.preventDefault(); + e.stopPropagation(); + + utils.removeEvent(window, 'touchmove', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); + utils.removeEvent(window, 'mousemove', this); + + if ( this.scroller.options.snap ) { + var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); + + var time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(this.scroller.x - snap.x), 1000), + Math.min(Math.abs(this.scroller.y - snap.y), 1000) + ), 300); + + if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { + this.scroller.directionX = 0; + this.scroller.directionY = 0; + this.scroller.currentPage = snap; + this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); + } + } + + if ( this.moved ) { + this.scroller._execEvent('scrollEnd'); + } + }, + + transitionTime: function (time) { + time = time || 0; + this.indicatorStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.indicatorStyle[utils.style.transitionDuration] = '0.001s'; + } + }, + + transitionTimingFunction: function (easing) { + this.indicatorStyle[utils.style.transitionTimingFunction] = easing; + }, + + refresh: function () { + this.transitionTime(); + + if ( this.options.listenX && !this.options.listenY ) { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; + } else if ( this.options.listenY && !this.options.listenX ) { + this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; + } else { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; + } + + if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { + utils.addClass(this.wrapper, 'iScrollBothScrollbars'); + utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); + + if ( this.options.defaultScrollbars && this.options.customStyle ) { + if ( this.options.listenX ) { + this.wrapper.style.right = '8px'; + } else { + this.wrapper.style.bottom = '8px'; + } + } + } else { + utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); + utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); + + if ( this.options.defaultScrollbars && this.options.customStyle ) { + if ( this.options.listenX ) { + this.wrapper.style.right = '2px'; + } else { + this.wrapper.style.bottom = '2px'; + } + } + } + + var r = this.wrapper.offsetHeight; // force refresh + + if ( this.options.listenX ) { + this.wrapperWidth = this.wrapper.clientWidth; + if ( this.options.resize ) { + this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); + this.indicatorStyle.width = this.indicatorWidth + 'px'; + } else { + this.indicatorWidth = this.indicator.clientWidth; + } + + this.maxPosX = this.wrapperWidth - this.indicatorWidth; + + if ( this.options.shrink == 'clip' ) { + this.minBoundaryX = -this.indicatorWidth + 8; + this.maxBoundaryX = this.wrapperWidth - 8; + } else { + this.minBoundaryX = 0; + this.maxBoundaryX = this.maxPosX; + } + + this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); + } + + if ( this.options.listenY ) { + this.wrapperHeight = this.wrapper.clientHeight; + if ( this.options.resize ) { + this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); + this.indicatorStyle.height = this.indicatorHeight + 'px'; + } else { + this.indicatorHeight = this.indicator.clientHeight; + } + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + + if ( this.options.shrink == 'clip' ) { + this.minBoundaryY = -this.indicatorHeight + 8; + this.maxBoundaryY = this.wrapperHeight - 8; + } else { + this.minBoundaryY = 0; + this.maxBoundaryY = this.maxPosY; + } + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); + } + + this.updatePosition(); + }, + + updatePosition: function () { + var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, + y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; + + if ( !this.options.ignoreBoundaries ) { + if ( x < this.minBoundaryX ) { + if ( this.options.shrink == 'scale' ) { + this.width = Math.max(this.indicatorWidth + x, 8); + this.indicatorStyle.width = this.width + 'px'; + } + x = this.minBoundaryX; + } else if ( x > this.maxBoundaryX ) { + if ( this.options.shrink == 'scale' ) { + this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.maxPosX + this.indicatorWidth - this.width; + } else { + x = this.maxBoundaryX; + } + } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { + this.width = this.indicatorWidth; + this.indicatorStyle.width = this.width + 'px'; + } + + if ( y < this.minBoundaryY ) { + if ( this.options.shrink == 'scale' ) { + this.height = Math.max(this.indicatorHeight + y * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + } + y = this.minBoundaryY; + } else if ( y > this.maxBoundaryY ) { + if ( this.options.shrink == 'scale' ) { + this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.maxPosY + this.indicatorHeight - this.height; + } else { + y = this.maxBoundaryY; + } + } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { + this.height = this.indicatorHeight; + this.indicatorStyle.height = this.height + 'px'; + } + } + + this.x = x; + this.y = y; + + if ( this.scroller.options.useTransform ) { + this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; + } else { + this.indicatorStyle.left = x + 'px'; + this.indicatorStyle.top = y + 'px'; + } + }, + + _pos: function (x, y) { + if ( x < 0 ) { + x = 0; + } else if ( x > this.maxPosX ) { + x = this.maxPosX; + } + + if ( y < 0 ) { + y = 0; + } else if ( y > this.maxPosY ) { + y = this.maxPosY; + } + + x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; + y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; + + this.scroller.scrollTo(x, y); + }, + + fade: function (val, hold) { + if ( hold && !this.visible ) { + return; + } + + clearTimeout(this.fadeTimeout); + this.fadeTimeout = null; + + var time = val ? 250 : 500, + delay = val ? 0 : 300; + + val = val ? '1' : '0'; + + this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; + + this.fadeTimeout = setTimeout((function (val) { + this.wrapperStyle.opacity = val; + this.visible = +val; + }).bind(this, val), delay); + } +}; + +IScroll.utils = utils; + +if ( typeof module != 'undefined' && module.exports ) { + module.exports = IScroll; +} else { + window.IScroll = IScroll; +} + +})(window, document, Math); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/photoclip/jquery.photoClip.min.js b/hyhproject/mobile2/view/default/js/photoclip/jquery.photoClip.min.js new file mode 100755 index 0000000..c9922a1 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/photoclip/jquery.photoClip.min.js @@ -0,0 +1,3 @@ +(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery","iscroll-zoom","hammer"],factory)}else{if(typeof exports==="object"){module.exports=factory(require("jquery"),require("iscroll-zoom"),require("hammer"))}else{factory(root.jQuery,root.IScroll,root.Hammer)}}}(this,function(jQuery,IScroll,Hammer){jQuery.fn.photoClip=function(option){if(!window.FileReader){alert("您的浏览器不支持 HTML5 的 FileReader API, 因此无法初始化图片裁剪插件,请更换最新的浏览器!");return}var defaultOption={width:200,height:200,file:"",view:"",ok:"",outputType:"jpg",strictSize:false,loadStart:function(){},loadComplete:function(){},loadError:function(){},clipFinish:function(){}};jQuery.extend(defaultOption,option);this.each(function(){photoClip(this,defaultOption)});return this};function photoClip(container,option){var clipWidth=option.width,clipHeight=option.height,file=option.file,view=option.view,ok=option.ok,outputType=option.outputType||"image/jpeg",strictSize=option.strictSize,loadStart=option.loadStart,loadComplete=option.loadComplete,loadError=option.loadError,clipFinish=option.clipFinish;if(outputType==="jpg"){outputType="image/jpeg"}else{if(outputType==="png"){outputType="image/png"}}var jQueryfile=jQuery(file);if(!jQueryfile.length){return}var jQueryimg,imgWidth,imgHeight,imgLoaded;jQueryfile.attr("accept","image/*");jQueryfile.change(function(){if(!this.files.length){return}if(!/image\/\w+/.test(this.files[0].type)){alert("图片格式不正确,请选择正确格式的图片文件!");return false}else{var fileReader=new FileReader();fileReader.onprogress=function(e){console.log((e.loaded/e.total*100).toFixed()+"%")};fileReader.onload=function(e){var kbs=e.total/1024;if(kbs>1024){var quality=1024/kbs;var jQuerytempImg=jQuery("<img>").hide();jQuerytempImg.load(function(){var sourceWidth=this.naturalWidth;jQuerytempImg.appendTo(document.body);var realityHeight=this.naturalHeight;jQuerytempImg.remove();delete jQuerytempImg[0];jQuerytempImg=null;var angleOffset=0;if(sourceWidth==realityHeight){angleOffset=90}var newDataURL=compressImg(this,quality,angleOffset,outputType);createImg(newDataURL)});jQuerytempImg.attr("src",this.result)}else{createImg(this.result)}};fileReader.onerror=function(e){alert("图片加载失败");loadError.call(this,e)};fileReader.readAsDataURL(this.files[0]);loadStart.call(fileReader,this.files[0])}});jQueryfile.click(function(){this.value=""});var jQuerycontainer,jQueryclipView,jQuerymoveLayer,jQueryrotateLayer,jQueryview,canvas,myScroll,containerWidth,containerHeight;init();initScroll();initEvent();initClip();var jQueryok=jQuery(ok);if(jQueryok.length){jQueryok.click(function(){clipImg()})}var jQuerywin=jQuery(window);resize();jQuerywin.resize(resize);var atRotation,curX,curY,curAngle;function imgLoad(){imgLoaded=true;jQueryrotateLayer.append(this);hideAction.call(this,jQueryimg,function(){imgWidth=this.naturalWidth;imgHeight=this.naturalHeight});hideAction(jQuerymoveLayer,function(){resetScroll()});loadComplete.call(this,this.src)}function initScroll(){var options={zoom:true,scrollX:true,scrollY:true,freeScroll:true,mouseWheel:true,wheelAction:"zoom"};myScroll=new IScroll(jQueryclipView[0],options)}function resetScroll(){curX=0;curY=0;curAngle=0;jQueryrotateLayer.css({"width":imgWidth,"height":imgHeight});setTransform(jQueryrotateLayer,curX,curY,curAngle);calculateScale(imgWidth,imgHeight);myScroll.zoom(myScroll.options.zoomStart);refreshScroll(imgWidth,imgHeight);var posX=(clipWidth-imgWidth*myScroll.options.zoomStart)*0.5,posY=(clipHeight-imgHeight*myScroll.options.zoomStart)*0.5;myScroll.scrollTo(posX,posY)}function refreshScroll(width,height){jQuerymoveLayer.css({"width":width,"height":height});jQueryclipView.append(jQuerymoveLayer);myScroll.refresh()}function initEvent(){var is_mobile=!!navigator.userAgent.match(/mobile/i);if(is_mobile){var hammerManager=new Hammer(jQuerymoveLayer[0]);hammerManager.add(new Hammer.Rotate());var rotation,rotateDirection;hammerManager.on("rotatemove",function(e){if(atRotation){return}rotation=e.rotation;if(rotation>180){rotation-=360}else{if(rotation<-180){rotation+=360}}rotateDirection=rotation>0?1:rotation<0?-1:0});hammerManager.on("rotateend",function(e){if(atRotation){return}if(Math.abs(rotation)>30){if(rotateDirection==1){rotateCW(e.center)}else{if(rotateDirection==-1){rotateCCW(e.center)}}}})}else{jQuerymoveLayer.on("dblclick",function(e){rotateCW({x:e.clientX,y:e.clientY})})}}function rotateCW(point){rotateBy(90,point)}function rotateCCW(point){rotateBy(-90,point)}function rotateBy(angle,point){if(atRotation){return}atRotation=true;var loacl;if(!point){loacl=loaclToLoacl(jQuerymoveLayer,jQueryclipView,clipWidth*0.5,clipHeight*0.5)}else{loacl=globalToLoacl(jQuerymoveLayer,point.x,point.y)}var origin=calculateOrigin(curAngle,loacl),originX=origin.x,originY=origin.y,offsetX=0,offsetY=0,parentOffsetX=0,parentOffsetY=0,newAngle=curAngle+angle,curImgWidth,curImgHeight;if(newAngle==90||newAngle==-270){offsetX=originX+originY;offsetY=originY-originX;if(newAngle>curAngle){parentOffsetX=imgHeight-originX-originY;parentOffsetY=originX-originY +}else{if(newAngle<curAngle){parentOffsetX=(imgHeight-originY)-(imgWidth-originX);parentOffsetY=originX+originY-imgHeight}}curImgWidth=imgHeight;curImgHeight=imgWidth}else{if(newAngle==180||newAngle==-180){offsetX=originX*2;offsetY=originY*2;if(newAngle>curAngle){parentOffsetX=(imgWidth-originX)-(imgHeight-originY);parentOffsetY=imgHeight-(originX+originY)}else{if(newAngle<curAngle){parentOffsetX=imgWidth-(originX+originY);parentOffsetY=(imgHeight-originY)-(imgWidth-originX)}}curImgWidth=imgWidth;curImgHeight=imgHeight}else{if(newAngle==270||newAngle==-90){offsetX=originX-originY;offsetY=originX+originY;if(newAngle>curAngle){parentOffsetX=originX+originY-imgWidth;parentOffsetY=(imgWidth-originX)-(imgHeight-originY)}else{if(newAngle<curAngle){parentOffsetX=originY-originX;parentOffsetY=imgWidth-originX-originY}}curImgWidth=imgHeight;curImgHeight=imgWidth}else{if(newAngle==0||newAngle==360||newAngle==-360){offsetX=0;offsetY=0;if(newAngle>curAngle){parentOffsetX=originX-originY;parentOffsetY=originX+originY-imgWidth}else{if(newAngle<curAngle){parentOffsetX=originX+originY-imgHeight;parentOffsetY=originY-originX}}curImgWidth=imgWidth;curImgHeight=imgHeight}}}}if(curAngle==0){curX=0;curY=0}else{if(curAngle==90||curAngle==-270){curX-=originX+originY;curY-=originY-originX}else{if(curAngle==180||curAngle==-180){curX-=originX*2;curY-=originY*2}else{if(curAngle==270||curAngle==-90){curX-=originX-originY;curY-=originX+originY}}}}curX=curX.toFixed(2)-0;curY=curY.toFixed(2)-0;setTransform(jQueryrotateLayer,curX,curY,curAngle,originX,originY);setTransition(jQueryrotateLayer,curX,curY,newAngle,200,function(){atRotation=false;curAngle=newAngle%360;curX+=offsetX+parentOffsetX;curY+=offsetY+parentOffsetY;curX=curX.toFixed(2)-0;curY=curY.toFixed(2)-0;setTransform(jQueryrotateLayer,curX,curY,curAngle);myScroll.scrollTo(myScroll.x-parentOffsetX*myScroll.scale,myScroll.y-parentOffsetY*myScroll.scale);calculateScale(curImgWidth,curImgHeight);if(myScroll.scale<myScroll.options.zoomMin){myScroll.zoom(myScroll.options.zoomMin)}refreshScroll(curImgWidth,curImgHeight)})}function initClip(){canvas=document.createElement("canvas");canvas.width=clipWidth;canvas.height=clipHeight}function clipImg(){if(!imgLoaded){alert("亲,当前没有图片可以裁剪!");return}var local=loaclToLoacl(jQuerymoveLayer,jQueryclipView);var scale=myScroll.scale;var ctx=canvas.getContext("2d");ctx.clearRect(0,0,canvas.width,canvas.height);ctx.save();if(strictSize){ctx.scale(scale,scale)}else{canvas.width=clipWidth/scale;canvas.height=clipHeight/scale}ctx.translate(curX-local.x/scale,curY-local.y/scale);ctx.rotate(curAngle*Math.PI/180);ctx.drawImage(jQueryimg[0],0,0);ctx.restore();var dataURL=canvas.toDataURL(outputType,1);jQueryview.css("background-image","url("+dataURL+")");clipFinish.call(jQueryimg[0],dataURL)}function resize(){hideAction(jQuerycontainer,function(){containerWidth=jQuerycontainer.width();containerHeight=jQuerycontainer.height()})}function loaclToLoacl(jQuerylayerOne,jQuerylayerTwo,x,y){x=x||0;y=y||0;var layerOneOffset,layerTwoOffset;hideAction(jQuerylayerOne,function(){layerOneOffset=jQuerylayerOne.offset()});hideAction(jQuerylayerTwo,function(){layerTwoOffset=jQuerylayerTwo.offset()});return{x:layerTwoOffset.left-layerOneOffset.left+x,y:layerTwoOffset.top-layerOneOffset.top+y}}function globalToLoacl(jQuerylayer,x,y){x=x||0;y=y||0;var layerOffset;hideAction(jQuerylayer,function(){layerOffset=jQuerylayer.offset()});return{x:x+jQuerywin.scrollLeft()-layerOffset.left,y:y+jQuerywin.scrollTop()-layerOffset.top}}function hideAction(jq,func){var jQueryhide=jQuery();jQuery.each(jq,function(i,n){var jQueryn=jQuery(n);var jQueryhidden=jQueryn.parents().andSelf().filter(":hidden");var jQuerynone;for(var i=0;i<jQueryhidden.length;i++){if(!jQueryn.is(":hidden")){break}jQuerynone=jQueryhidden.eq(i);if(jQuerynone.css("display")=="none"){jQueryhide=jQueryhide.add(jQuerynone.show())}}});if(typeof(func)=="function"){func.call(this)}jQueryhide.hide()}function calculateOrigin(curAngle,point){var scale=myScroll.scale;var origin={};if(curAngle==0){origin.x=point.x/scale;origin.y=point.y/scale}else{if(curAngle==90||curAngle==-270){origin.x=point.y/scale;origin.y=imgHeight-point.x/scale}else{if(curAngle==180||curAngle==-180){origin.x=imgWidth-point.x/scale;origin.y=imgHeight-point.y/scale}else{if(curAngle==270||curAngle==-90){origin.x=imgWidth-point.y/scale;origin.y=point.x/scale}}}}return origin}function getScale(w1,h1,w2,h2){var sx=w1/w2;var sy=h1/h2;return sx>sy?sx:sy}function calculateScale(width,height){myScroll.options.zoomMin=getScale(clipWidth,clipHeight,width,height);myScroll.options.zoomMax=Math.max(1,myScroll.options.zoomMin);myScroll.options.zoomStart=Math.min(myScroll.options.zoomMax,getScale(containerWidth,containerHeight,width,height))}function compressImg(sourceImgObj,quality,angleOffset,outputFormat){quality=quality||0.8;angleOffset=angleOffset||0;var mimeType=outputFormat||"image/jpeg";var drawWidth=sourceImgObj.naturalWidth,drawHeight=sourceImgObj.naturalHeight;var maxSide=Math.max(drawWidth,drawHeight); +if(maxSide>1024){var minSide=Math.min(drawWidth,drawHeight);minSide=minSide/maxSide*1024;maxSide=1024;if(drawWidth>drawHeight){drawWidth=maxSide;drawHeight=minSide}else{drawWidth=minSide;drawHeight=maxSide}}var cvs=document.createElement("canvas");var ctx=cvs.getContext("2d");if(angleOffset){cvs.width=drawHeight;cvs.height=drawWidth;ctx.translate(drawHeight,0);ctx.rotate(angleOffset*Math.PI/180)}else{cvs.width=drawWidth;cvs.height=drawHeight}ctx.drawImage(sourceImgObj,0,0,drawWidth,drawHeight);var newImageData=cvs.toDataURL(mimeType,quality||0.8);return newImageData}function createImg(src){if(jQueryimg&&jQueryimg.length){jQueryimg.remove();delete jQueryimg[0]}jQueryimg=jQuery("<img>").css({"user-select":"none","pointer-events":"none"});jQueryimg.load(imgLoad);jQueryimg.attr("src",src)}function setTransform(jQueryobj,x,y,angle,originX,originY){originX=originX||0;originY=originY||0;var style={};style[prefix+"transform"]="translateZ(0) translate("+x+"px,"+y+"px) rotate("+angle+"deg)";style[prefix+"transform-origin"]=originX+"px "+originY+"px";jQueryobj.css(style)}function setTransition(jQueryobj,x,y,angle,dur,fn){jQueryobj.css(prefix+"transform");jQueryobj.css(prefix+"transition",prefix+"transform "+dur+"ms");jQueryobj.one(transitionEnd,function(){jQueryobj.css(prefix+"transition","");fn.call(this)});jQueryobj.css(prefix+"transform","translateZ(0) translate("+x+"px,"+y+"px) rotate("+angle+"deg)")}function init(){jQuerycontainer=jQuery(container).css({"user-select":"none","overflow":"hidden"});if(jQuerycontainer.css("position")=="static"){jQuerycontainer.css("position","relative")}jQueryclipView=jQuery("<div class='photo-clip-view'>").css({"position":"absolute","left":"50%","top":"50%","width":clipWidth,"height":clipHeight,"margin-left":-clipWidth/2,"margin-top":-clipHeight/2}).appendTo(jQuerycontainer);jQuerymoveLayer=jQuery("<div class='photo-clip-moveLayer'>").appendTo(jQueryclipView);jQueryrotateLayer=jQuery("<div class='photo-clip-rotateLayer'>").appendTo(jQuerymoveLayer);var jQuerymask=jQuery("<div class='photo-clip-mask'>").css({"position":"absolute","left":0,"top":0,"width":"100%","height":"100%","pointer-events":"none"}).appendTo(jQuerycontainer);var jQuerymask_left=jQuery("<div class='photo-clip-mask-left'>").css({"position":"absolute","left":0,"right":"50%","top":"50%","bottom":"50%","width":"auto","height":clipHeight,"margin-right":clipWidth/2,"margin-top":-clipHeight/2,"margin-bottom":-clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_right=jQuery("<div class='photo-clip-mask-right'>").css({"position":"absolute","left":"50%","right":0,"top":"50%","bottom":"50%","margin-left":clipWidth/2,"margin-top":-clipHeight/2,"margin-bottom":-clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_top=jQuery("<div class='photo-clip-mask-top'>").css({"position":"absolute","left":0,"right":0,"top":0,"bottom":"50%","margin-bottom":clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_bottom=jQuery("<div class='photo-clip-mask-bottom'>").css({"position":"absolute","left":0,"right":0,"top":"50%","bottom":0,"margin-top":clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQueryclip_area=jQuery("<div class='photo-clip-area'>").css({"border":"1px dashed #ddd","position":"absolute","left":"50%","top":"50%","width":clipWidth,"height":clipHeight,"margin-left":-clipWidth/2-1,"margin-top":-clipHeight/2-1}).appendTo(jQuerymask);jQueryview=jQuery(view);if(jQueryview.length){jQueryview.css({"background-color":"#666","background-repeat":"no-repeat","background-position":"center","background-size":"contain"})}}}var prefix="",transitionEnd;(function(){var eventPrefix,vendors={Webkit:"webkit",Moz:"",O:"o"},testEl=document.documentElement,normalizeEvent=function(name){return eventPrefix?eventPrefix+name:name.toLowerCase()};for(var i in vendors){if(testEl.style[i+"TransitionProperty"]!==undefined){prefix="-"+i.toLowerCase()+"-";eventPrefix=vendors[i];break}}transitionEnd=normalizeEvent("TransitionEnd")})();return jQuery})); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/photoclip/upload.hpictures.js b/hyhproject/mobile2/view/default/js/photoclip/upload.hpictures.js new file mode 100755 index 0000000..6f4694c --- /dev/null +++ b/hyhproject/mobile2/view/default/js/photoclip/upload.hpictures.js @@ -0,0 +1,107 @@ + jQuery.noConflict(); +//关闭图片上传区 + function closeUploadArea(){ + var data='#upload_close,#upload_button,#upload_modal'; + var data2='.return_users,.useri_info,#useri_info,#footer'; + WST.showHide('',data); + WST.showHide(1,data2); + //清空图片上传区的内容 + $('#clipArea').find('img').remove(); + $('#file').val(''); + $('#view').css('background-image',''); + $('#imgData').val(''); + } + jQuery('#uploadImg').on('change', function() { + var data='.return_users,.useri_info,#useri_info,#footer'; + var data2='#upload_close,#upload_button,#upload_modal'; + WST.showHide('',data); + WST.showHide(1,data2); +}); +//头像上传 +jQuery("#clipArea").photoClip({ + width: 350, + height: 350, + file: "#uploadImg", + view: "#view", + ok: "#upload_button", + loadStart: function() { + $('#Load').show(); + }, + loadComplete: function() { + $('#Load').hide(); + }, + clipFinish: function(dataURL) { + jQuery('#imgData').val(dataURL); + var imgData = $('#imgData').val(); + if(!imgData || imgData==''){ + WST.msg('请先选择图片','info'); + return false; + } + // 上传裁剪好的图片 + funUploadFile(dataURL); + + } +}); + + + /** + * @param base64Codes + * 图片的base64编码 + */ +funUploadFile=function(base64Codes){ + var self = this; + var formData = new FormData(); + //convertBase64UrlToBlob函数是将base64编码转换为Blob + //append函数的第一个参数是后台获取数据的参数名,在php中用$FILES['imageName']接收, + var imgSuffix = base64Codes.split(";")[0].split('/')[1]; + // formData.append("imageName",self.convertBase64UrlToBlob(base64Codes),"image."+imgSuffix); + // 后台参数改为file mark 20180613 by zl + formData.append("file",self.convertBase64UrlToBlob(base64Codes),"image."+imgSuffix); + //ajax 提交form + $.ajax({ + // 你后台的接收地址 + url : WST.U('mobile/users/uploadPic',{'dir':'users','isTumb':1}), + type : "POST", + data : formData, + dataType:"json", + processData : false, // 告诉jQuery不要去处理发送的数据 + contentType : false, // 告诉jQuery不要去设置Content-Type请求头 + success:function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $.post(WST.U('mobile/users/editUserInfo'), {userPhoto:json.savePath+json.name}, function(data){ + if(json.status==1){ + WST.msg("修改头像成功",'success'); + jQuery('#imgurl').attr('src', WST.conf.IMGURL +'/'+json.savePath+json.name); + }else{ + WST.msg('修改头像失败,请重试','warn'); + return false; + } + }); + }else{ + WST.msg(json.msg,'warn'); + } + closeUploadArea(); + $('#Load').hide(); + + } + }); +} + +/** + * 将以base64的图片url数据转换为Blob + * @param urlData + * 用url方式表示的base64图片数据 + */ +convertBase64UrlToBlob=function(urlData){ + //去掉url的头,并转换为byte + var bytes=window.atob(urlData.split(',')[1]); + //处理异常,将ascii码小于0的转换为大于0 + var ab = new ArrayBuffer(bytes.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < bytes.length; i++) { + ia[i] = bytes.charCodeAt(i); + } + // 此处type注意与photoClip初始化中的outputType类型保持一致 + return new Blob( [ab] , {type : 'image/jpeg'}); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/qrcode.js b/hyhproject/mobile2/view/default/js/qrcode.js new file mode 100755 index 0000000..b2ae4a6 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/qrcode.js @@ -0,0 +1,88 @@ + +var qrcode=function(){var qrcode=function(typeNumber,errorCorrectLevel){var PAD0=0xEC;var PAD1=0x11;var _typeNumber=typeNumber;var _errorCorrectLevel=QRErrorCorrectLevel[errorCorrectLevel];var _modules=null;var _moduleCount=0;var _dataCache=null;var _dataList=new Array();var _this={};var makeImpl=function(test,maskPattern){_moduleCount=_typeNumber*4+17;_modules=function(moduleCount){var modules=new Array(moduleCount);for(var row=0;row<moduleCount;row+=1){modules[row]=new Array(moduleCount);for(var col=0;col<moduleCount;col+=1){modules[row][col]=null;}} +return modules;}(_moduleCount);setupPositionProbePattern(0,0);setupPositionProbePattern(_moduleCount-7,0);setupPositionProbePattern(0,_moduleCount-7);setupPositionAdjustPattern();setupTimingPattern();setupTypeInfo(test,maskPattern);if(_typeNumber>=7){setupTypeNumber(test);} +if(_dataCache==null){_dataCache=createData(_typeNumber,_errorCorrectLevel,_dataList);} +mapData(_dataCache,maskPattern);};var setupPositionProbePattern=function(row,col){for(var r=-1;r<=7;r+=1){if(row+r<=-1||_moduleCount<=row+r)continue;for(var c=-1;c<=7;c+=1){if(col+c<=-1||_moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}};var getBestMaskPattern=function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i+=1){makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(_this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} +return pattern;};var setupTimingPattern=function(){for(var r=8;r<_moduleCount-8;r+=1){if(_modules[r][6]!=null){continue;} +_modules[r][6]=(r%2==0);} +for(var c=8;c<_moduleCount-8;c+=1){if(_modules[6][c]!=null){continue;} +_modules[6][c]=(c%2==0);}};var setupPositionAdjustPattern=function(){var pos=QRUtil.getPatternPosition(_typeNumber);for(var i=0;i<pos.length;i+=1){for(var j=0;j<pos.length;j+=1){var row=pos[i];var col=pos[j];if(_modules[row][col]!=null){continue;} +for(var r=-2;r<=2;r+=1){for(var c=-2;c<=2;c+=1){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}}}};var setupTypeNumber=function(test){var bits=QRUtil.getBCHTypeNumber(_typeNumber);for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[Math.floor(i/3)][i%3+_moduleCount-8-3]=mod;} +for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[i%3+_moduleCount-8-3][Math.floor(i/3)]=mod;}};var setupTypeInfo=function(test,maskPattern){var data=(_errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<6){_modules[i][8]=mod;}else if(i<8){_modules[i+1][8]=mod;}else{_modules[_moduleCount-15+i][8]=mod;}} +for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<8){_modules[8][_moduleCount-i-1]=mod;}else if(i<9){_modules[8][15-i-1+1]=mod;}else{_modules[8][15-i-1]=mod;}} +_modules[_moduleCount-8][8]=(!test);};var mapData=function(data,maskPattern){var inc=-1;var row=_moduleCount-1;var bitIndex=7;var byteIndex=0;var maskFunc=QRUtil.getMaskFunction(maskPattern);for(var col=_moduleCount-1;col>0;col-=2){if(col==6)col-=1;while(true){for(var c=0;c<2;c+=1){if(_modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} +var mask=maskFunc(row,col-c);if(mask){dark=!dark;} +_modules[row][col-c]=dark;bitIndex-=1;if(bitIndex==-1){byteIndex+=1;bitIndex=7;}}} +row+=inc;if(row<0||_moduleCount<=row){row-=inc;inc=-inc;break;}}}};var createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r+=1){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i+=1){dcdata[r][i]=0xff&buffer.getBuffer()[i+offset];} +offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=qrPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i+=1){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.getAt(modIndex):0;}} +var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalCodeCount+=rsBlocks[i].totalCount;} +var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<dcdata[r].length){data[index]=dcdata[r][i];index+=1;}}} +for(var i=0;i<maxEcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<ecdata[r].length){data[index]=ecdata[r][i];index+=1;}}} +return data;};var createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=qrBitBuffer();for(var i=0;i<dataList.length;i+=1){var data=dataList[i];buffer.put(data.getMode(),4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.getMode(),typeNumber));data.write(buffer);} +var totalDataCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalDataCount+=rsBlocks[i].dataCount;} +if(buffer.getLengthInBits()>totalDataCount*8){throw new Error('code length overflow. (' ++buffer.getLengthInBits() ++'>' ++totalDataCount*8 ++')');} +if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} +while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} +while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD1,8);} +return createBytes(buffer,rsBlocks);};_this.addData=function(data){var newData=qr8BitByte(data);_dataList.push(newData);_dataCache=null;};_this.isDark=function(row,col){if(row<0||_moduleCount<=row||col<0||_moduleCount<=col){throw new Error(row+','+col);} +return _modules[row][col];};_this.getModuleCount=function(){return _moduleCount;};_this.make=function(){makeImpl(false,getBestMaskPattern());};_this.createTableTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var qrHtml='';qrHtml+='<table style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: '+margin+'px;';qrHtml+='">';qrHtml+='<tbody>';for(var r=0;r<_this.getModuleCount();r+=1){qrHtml+='<tr>';for(var c=0;c<_this.getModuleCount();c+=1){qrHtml+='<td style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: 0px;';qrHtml+=' width: '+cellSize+'px;';qrHtml+=' height: '+cellSize+'px;';qrHtml+=' background-color: ';qrHtml+=_this.isDark(r,c)?'#000000':'#ffffff';qrHtml+=';';qrHtml+='"/>';} +qrHtml+='</tr>';} +qrHtml+='</tbody>';qrHtml+='</table>';return qrHtml;};_this.createImgTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var size=_this.getModuleCount()*cellSize+margin*2;var min=margin;var max=size-margin;return createImgTag(size,size,function(x,y){if(min<=x&&x<max&&min<=y&&y<max){var c=Math.floor((x-min)/cellSize);var r=Math.floor((y-min)/cellSize);return _this.isDark(r,c)?0:1;}else{return 1;}});};return _this;};qrcode.stringToBytes=function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);bytes.push(c&0xff);} +return bytes;};qrcode.createStringToBytes=function(unicodeData,numChars){var unicodeMap=function(){var bin=base64DecodeInputStream(unicodeData);var read=function(){var b=bin.read();if(b==-1)throw new Error();return b;};var count=0;var unicodeMap={};while(true){var b0=bin.read();if(b0==-1)break;var b1=read();var b2=read();var b3=read();var k=String.fromCharCode((b0<<8)|b1);var v=(b2<<8)|b3;unicodeMap[k]=v;count+=1;} +if(count!=numChars){throw new Error(count+' != '+numChars);} +return unicodeMap;}();var unknownChar='?'.charCodeAt(0);return function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);if(c<128){bytes.push(c);}else{var b=unicodeMap[s.charAt(i)];if(typeof b=='number'){if((b&0xff)==b){bytes.push(b);}else{bytes.push(b>>>8);bytes.push(b&0xff);}}else{bytes.push(unknownChar);}}} +return bytes;};};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil=function(){var PATTERN_POSITION_TABLE=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]];var G15=(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0);var G18=(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0);var G15_MASK=(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1);var _this={};var getBCHDigit=function(data){var digit=0;while(data!=0){digit+=1;data>>>=1;} +return digit;};_this.getBCHTypeInfo=function(data){var d=data<<10;while(getBCHDigit(d)-getBCHDigit(G15)>=0){d^=(G15<<(getBCHDigit(d)-getBCHDigit(G15)));} +return((data<<10)|d)^G15_MASK;};_this.getBCHTypeNumber=function(data){var d=data<<12;while(getBCHDigit(d)-getBCHDigit(G18)>=0){d^=(G18<<(getBCHDigit(d)-getBCHDigit(G18)));} +return(data<<12)|d;};_this.getPatternPosition=function(typeNumber){return PATTERN_POSITION_TABLE[typeNumber-1];};_this.getMaskFunction=function(maskPattern){switch(maskPattern){case QRMaskPattern.PATTERN000:return function(i,j){return(i+j)%2==0;};case QRMaskPattern.PATTERN001:return function(i,j){return i%2==0;};case QRMaskPattern.PATTERN010:return function(i,j){return j%3==0;};case QRMaskPattern.PATTERN011:return function(i,j){return(i+j)%3==0;};case QRMaskPattern.PATTERN100:return function(i,j){return(Math.floor(i/2)+Math.floor(j/3))%2==0;};case QRMaskPattern.PATTERN101:return function(i,j){return(i*j)%2+(i*j)%3==0;};case QRMaskPattern.PATTERN110:return function(i,j){return((i*j)%2+(i*j)%3)%2==0;};case QRMaskPattern.PATTERN111:return function(i,j){return((i*j)%3+(i+j)%2)%2==0;};default:throw new Error('bad maskPattern:'+maskPattern);}};_this.getErrorCorrectPolynomial=function(errorCorrectLength){var a=qrPolynomial([1],0);for(var i=0;i<errorCorrectLength;i+=1){a=a.multiply(qrPolynomial([1,QRMath.gexp(i)],0));} +return a;};_this.getLengthInBits=function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error('mode:'+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error('mode:'+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error('mode:'+mode);}}else{throw new Error('type:'+type);}};_this.getLostPoint=function(qrcode){var moduleCount=qrcode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount;col+=1){var sameCount=0;var dark=qrcode.isDark(row,col);for(var r=-1;r<=1;r+=1){if(row+r<0||moduleCount<=row+r){continue;} +for(var c=-1;c<=1;c+=1){if(col+c<0||moduleCount<=col+c){continue;} +if(r==0&&c==0){continue;} +if(dark==qrcode.isDark(row+r,col+c)){sameCount+=1;}}} +if(sameCount>5){lostPoint+=(3+sameCount-5);}}};for(var row=0;row<moduleCount-1;row+=1){for(var col=0;col<moduleCount-1;col+=1){var count=0;if(qrcode.isDark(row,col))count+=1;if(qrcode.isDark(row+1,col))count+=1;if(qrcode.isDark(row,col+1))count+=1;if(qrcode.isDark(row+1,col+1))count+=1;if(count==0||count==4){lostPoint+=3;}}} +for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount-6;col+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row,col+1)&&qrcode.isDark(row,col+2)&&qrcode.isDark(row,col+3)&&qrcode.isDark(row,col+4)&&!qrcode.isDark(row,col+5)&&qrcode.isDark(row,col+6)){lostPoint+=40;}}} +for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount-6;row+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row+1,col)&&qrcode.isDark(row+2,col)&&qrcode.isDark(row+3,col)&&qrcode.isDark(row+4,col)&&!qrcode.isDark(row+5,col)&&qrcode.isDark(row+6,col)){lostPoint+=40;}}} +var darkCount=0;for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount;row+=1){if(qrcode.isDark(row,col)){darkCount+=1;}}} +var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;};return _this;}();var QRMath=function(){var EXP_TABLE=new Array(256);var LOG_TABLE=new Array(256);for(var i=0;i<8;i+=1){EXP_TABLE[i]=1<<i;} +for(var i=8;i<256;i+=1){EXP_TABLE[i]=EXP_TABLE[i-4]^EXP_TABLE[i-5]^EXP_TABLE[i-6]^EXP_TABLE[i-8];} +for(var i=0;i<255;i+=1){LOG_TABLE[EXP_TABLE[i]]=i;} +var _this={};_this.glog=function(n){if(n<1){throw new Error('glog('+n+')');} +return LOG_TABLE[n];};_this.gexp=function(n){while(n<0){n+=255;} +while(n>=256){n-=255;} +return EXP_TABLE[n];};return _this;}();function qrPolynomial(num,shift){if(typeof num.length=='undefined'){throw new Error(num.length+'/'+shift);} +var _num=function(){var offset=0;while(offset<num.length&&num[offset]==0){offset+=1;} +var _num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i+=1){_num[i]=num[i+offset];} +return _num;}();var _this={};_this.getAt=function(index){return _num[index];};_this.getLength=function(){return _num.length;};_this.multiply=function(e){var num=new Array(_this.getLength()+e.getLength()-1);for(var i=0;i<_this.getLength();i+=1){for(var j=0;j<e.getLength();j+=1){num[i+j]^=QRMath.gexp(QRMath.glog(_this.getAt(i))+QRMath.glog(e.getAt(j)));}} +return qrPolynomial(num,0);};_this.mod=function(e){if(_this.getLength()-e.getLength()<0){return _this;} +var ratio=QRMath.glog(_this.getAt(0))-QRMath.glog(e.getAt(0));var num=new Array(_this.getLength());for(var i=0;i<_this.getLength();i+=1){num[i]=_this.getAt(i);} +for(var i=0;i<e.getLength();i+=1){num[i]^=QRMath.gexp(QRMath.glog(e.getAt(i))+ratio);} +return qrPolynomial(num,0).mod(e);};return _this;};var QRRSBlock=function(){var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16]];var qrRSBlock=function(totalCount,dataCount){var _this={};_this.totalCount=totalCount;_this.dataCount=dataCount;return _this;};var _this={};var getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};_this.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=getRsBlockTable(typeNumber,errorCorrectLevel);if(typeof rsBlock=='undefined'){throw new Error('bad rs block @ typeNumber:'+typeNumber+'/errorCorrectLevel:'+errorCorrectLevel);} +var length=rsBlock.length/3;var list=new Array();for(var i=0;i<length;i+=1){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j+=1){list.push(qrRSBlock(totalCount,dataCount));}} +return list;};return _this;}();var qrBitBuffer=function(){var _buffer=new Array();var _length=0;var _this={};_this.getBuffer=function(){return _buffer;};_this.getAt=function(index){var bufIndex=Math.floor(index/8);return((_buffer[bufIndex]>>>(7-index%8))&1)==1;};_this.put=function(num,length){for(var i=0;i<length;i+=1){_this.putBit(((num>>>(length-i-1))&1)==1);}};_this.getLengthInBits=function(){return _length;};_this.putBit=function(bit){var bufIndex=Math.floor(_length/8);if(_buffer.length<=bufIndex){_buffer.push(0);} +if(bit){_buffer[bufIndex]|=(0x80>>>(_length%8));} +_length+=1;};return _this;};var qr8BitByte=function(data){var _mode=QRMode.MODE_8BIT_BYTE;var _data=data;var _bytes=qrcode.stringToBytes(data);var _this={};_this.getMode=function(){return _mode;};_this.getLength=function(buffer){return _bytes.length;};_this.write=function(buffer){for(var i=0;i<_bytes.length;i+=1){buffer.put(_bytes[i],8);}};return _this;};var byteArrayOutputStream=function(){var _bytes=new Array();var _this={};_this.writeByte=function(b){_bytes.push(b&0xff);};_this.writeShort=function(i){_this.writeByte(i);_this.writeByte(i>>>8);};_this.writeBytes=function(b,off,len){off=off||0;len=len||b.length;for(var i=0;i<len;i+=1){_this.writeByte(b[i+off]);}};_this.writeString=function(s){for(var i=0;i<s.length;i+=1){_this.writeByte(s.charCodeAt(i));}};_this.toByteArray=function(){return _bytes;};_this.toString=function(){var s='';s+='[';for(var i=0;i<_bytes.length;i+=1){if(i>0){s+=',';} +s+=_bytes[i];} +s+=']';return s;};return _this;};var base64EncodeOutputStream=function(){var _buffer=0;var _buflen=0;var _length=0;var _base64='';var _this={};var writeEncoded=function(b){_base64+=String.fromCharCode(encode(b&0x3f));};var encode=function(n){if(n<0){}else if(n<26){return 0x41+n;}else if(n<52){return 0x61+(n-26);}else if(n<62){return 0x30+(n-52);}else if(n==62){return 0x2b;}else if(n==63){return 0x2f;} +throw new Error('n:'+n);};_this.writeByte=function(n){_buffer=(_buffer<<8)|(n&0xff);_buflen+=8;_length+=1;while(_buflen>=6){writeEncoded(_buffer>>>(_buflen-6));_buflen-=6;}};_this.flush=function(){if(_buflen>0){writeEncoded(_buffer<<(6-_buflen));_buffer=0;_buflen=0;} +if(_length%3!=0){var padlen=3-_length%3;for(var i=0;i<padlen;i+=1){_base64+='=';}}};_this.toString=function(){return _base64;};return _this;};var base64DecodeInputStream=function(str){var _str=str;var _pos=0;var _buffer=0;var _buflen=0;var _this={};_this.read=function(){while(_buflen<8){if(_pos>=_str.length){if(_buflen==0){return-1;} +throw new Error('unexpected end of file./'+_buflen);} +var c=_str.charAt(_pos);_pos+=1;if(c=='='){_buflen=0;return-1;}else if(c.match(/^\s$/)){continue;} +_buffer=(_buffer<<6)|decode(c.charCodeAt(0));_buflen+=6;} +var n=(_buffer>>>(_buflen-8))&0xff;_buflen-=8;return n;};var decode=function(c){if(0x41<=c&&c<=0x5a){return c-0x41;}else if(0x61<=c&&c<=0x7a){return c-0x61+26;}else if(0x30<=c&&c<=0x39){return c-0x30+52;}else if(c==0x2b){return 62;}else if(c==0x2f){return 63;}else{throw new Error('c:'+c);}};return _this;};var gifImage=function(width,height){var _width=width;var _height=height;var _data=new Array(width*height);var _this={};_this.setPixel=function(x,y,pixel){_data[y*_width+x]=pixel;};_this.write=function(out){out.writeString('GIF87a');out.writeShort(_width);out.writeShort(_height);out.writeByte(0x80);out.writeByte(0);out.writeByte(0);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0xff);out.writeByte(0xff);out.writeByte(0xff);out.writeString(',');out.writeShort(0);out.writeShort(0);out.writeShort(_width);out.writeShort(_height);out.writeByte(0);var lzwMinCodeSize=2;var raster=getLZWRaster(lzwMinCodeSize);out.writeByte(lzwMinCodeSize);var offset=0;while(raster.length-offset>255){out.writeByte(255);out.writeBytes(raster,offset,255);offset+=255;} +out.writeByte(raster.length-offset);out.writeBytes(raster,offset,raster.length-offset);out.writeByte(0x00);out.writeString(';');};var bitOutputStream=function(out){var _out=out;var _bitLength=0;var _bitBuffer=0;var _this={};_this.write=function(data,length){if((data>>>length)!=0){throw new Error('length over');} +while(_bitLength+length>=8){_out.writeByte(0xff&((data<<_bitLength)|_bitBuffer));length-=(8-_bitLength);data>>>=(8-_bitLength);_bitBuffer=0;_bitLength=0;} +_bitBuffer=(data<<_bitLength)|_bitBuffer;_bitLength=_bitLength+length;};_this.flush=function(){if(_bitLength>0){_out.writeByte(_bitBuffer);}};return _this;};var getLZWRaster=function(lzwMinCodeSize){var clearCode=1<<lzwMinCodeSize;var endCode=(1<<lzwMinCodeSize)+1;var bitLength=lzwMinCodeSize+1;var table=lzwTable();for(var i=0;i<clearCode;i+=1){table.add(String.fromCharCode(i));} +table.add(String.fromCharCode(clearCode));table.add(String.fromCharCode(endCode));var byteOut=byteArrayOutputStream();var bitOut=bitOutputStream(byteOut);bitOut.write(clearCode,bitLength);var dataIndex=0;var s=String.fromCharCode(_data[dataIndex]);dataIndex+=1;while(dataIndex<_data.length){var c=String.fromCharCode(_data[dataIndex]);dataIndex+=1;if(table.contains(s+c)){s=s+c;}else{bitOut.write(table.indexOf(s),bitLength);if(table.size()<0xfff){if(table.size()==(1<<bitLength)){bitLength+=1;} +table.add(s+c);} +s=c;}} +bitOut.write(table.indexOf(s),bitLength);bitOut.write(endCode,bitLength);bitOut.flush();return byteOut.toByteArray();};var lzwTable=function(){var _map={};var _size=0;var _this={};_this.add=function(key){if(_this.contains(key)){throw new Error('dup key:'+key);} +_map[key]=_size;_size+=1;};_this.size=function(){return _size;};_this.indexOf=function(key){return _map[key];};_this.contains=function(key){return typeof _map[key]!='undefined';};return _this;};return _this;};var createImgTag=function(width,height,getPixel,alt){var gif=gifImage(width,height);for(var y=0;y<height;y+=1){for(var x=0;x<width;x+=1){gif.setPixel(x,y,getPixel(x,y));}} +var b=byteArrayOutputStream();gif.write(b);var base64=base64EncodeOutputStream();var bytes=b.toByteArray();for(var i=0;i<bytes.length;i+=1){base64.writeByte(bytes[i]);} +base64.flush();var img='';img+='<img';img+='\u0020src="';img+='data:image/gif;base64,';img+=base64;img+='"';img+='\u0020width="';img+=width;img+='"';img+='\u0020height="';img+=height;img+='"';if(alt){img+='\u0020alt="';img+=alt;img+='"';} +img+='/>';return img;};return qrcode;}();/* |xGv00|ca8fc6bde81a353e7cede123b304bdb9 */ \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/reg.js b/hyhproject/mobile2/view/default/js/reg.js new file mode 100755 index 0000000..9c2254a --- /dev/null +++ b/hyhproject/mobile2/view/default/js/reg.js @@ -0,0 +1,211 @@ +jQuery.noConflict(); +//mark lxy 增加分享人 2018/4/4 +function GetQueryString(name) { + var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if(r != null) + return unescape(r[2]); + return null; +} + +var pname =GetQueryString('pName')?GetQueryString('pName'): localStorage.getItem('pName'); + +if(!pname) { + pname = localStorage.getItem('pName'); + var indexNum = pname.indexOf('&'); + if(indexNum > 0){ + pname = pname.slice(0,indexNum); + } +} + +if(pname) { + $('#pName').val(pname);; + $('#pName').attr('disabled', 'disabled'); +} + + +var nameType = 3; + +function onTesting(obj) { + //不能输入中文 + WST.isChinese(obj, 1); + var data = $(obj).val(); + var regMobile = /^0?1[3|4|5|8][0-9]\d{8}$/; + if(regMobile.test(data)) { //手机 + nameType = 3; + $.post(WST.U('mobile/users/checkUserPhone'), { + userPhone: data + }, function(data) { + var json = WST.toJson(data); + if(json.status == 1) {} else { + var dia = $.dialog({ + title: '', + content: '<p style="text-align: center;">手机号已注册</p>', + button: ["确认"] + }); + } + data = json = null; + }); + } +} + +function register() { + var regName = $('#regName').val(); + var regPwd = $('#regPwd').val(); + var regcoPwd = $('#regcoPwd').val(); + var regVerfy = $('#regVerfy').val(); + var phoneCode = $('#phoneCode').val(); + var smsVerfy = $('#smsVerfy').val(); + var pName = $('#pName').val(); + var param = {}; + if($('#defaults').hasClass('ui-icon-unchecked-s')) { + WST.msg('请阅读用户注册协议', 'info'); + return false; + } + if(regName == '') { + WST.msg('请输入账号', 'info'); + return false; + } + if(regName.length < 6) { + WST.msg('账号为6位以上数字或字母', 'info'); + return false; + } + if(regPwd == '') { + WST.msg('请输入密码', 'info'); + return false; + } + if(regPwd.length < 6 || regPwd.length > 16) { + WST.msg('请输入密码为6-16位字符', 'info'); + return false; + } + if(regcoPwd == '') { + WST.msg('确认密码不能为空', 'info'); + return false; + } + // if(smsVerfy == '') { + // WST.msg('验证码不能为空', 'info'); + // return false; + // } + if(regPwd != regcoPwd) { + WST.msg('确认密码不一致', 'info'); + return false; + } + if(phoneCode == '') { + WST.msg('请输入短信验证码', 'info'); + return false; + } + param.mobileCode = phoneCode; + if(window.conf.IS_CRYPTPWD == 1) { + var public_key = $('#key').val(); + var exponent = "10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var regcoPwd = rsa.encrypt(regcoPwd); + var regPwd = rsa.encrypt(regPwd); + } + WST.load('注册中···'); + param.nameType = nameType; + param.loginName = regName; + param.loginPwd = regcoPwd; + param.reUserPwd = regPwd; + param.pName = pName; + param.verifyCode = smsVerfy; + $('#regButton').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/register'), param, function(data) { + var json = WST.toJson(data); + if(json.status == 1) { + WST.msg(json.msg, 'success'); + var url = json.url; + setTimeout(function() { + if(WST.blank(url)) { + location.href = url; + } + else { + location.href ='/down/orange/index.html'; + } + }, 200); + } else { + WST.msg(json.msg, 'warn'); + WST.getVerify("#verifyImg3"); + $('#regButton').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +var time = 0; +var isSend = false; + +function obtainCode() { + var userPhone = $('#regName').val(); + if(userPhone == '') { + WST.msg('请输入帐号为手机号码', 'info'); + $('#userPhone').focus(); + return false; + } + if(WST.conf.SMS_VERFY == 1) { + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy == '') { + WST.msg('请输入验证码', 'info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.userPhone = userPhone; + param.smsVerfy = smsVerfy; + param.isMobile = 1; + if(isSend) return; + isSend = true; + $.post(WST.U('mobile/users/getPhoneVerifyCode'), param, function(data) { + var json = WST.toJson(data); + if(json.status == 1) { + WST.msg(json.msg, 'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function() { + time--; + $('#obtain').html('' + time + "秒获取"); + if(time == 0) { + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + }, 1000); + } else { + WST.msg(json.msg, 'warn'); + WST.getVerify("#verifyImg3"); + isSend = false; + } + data = json = null; + }); +} +//弹框 +function wholeShow(type) { + jQuery('#' + type).animate({ + "right": 0 + }, 500); +} + +function wholeHide(type) { + var dataWidth = $('#' + type).css('width'); + jQuery('#' + type).animate({ + 'right': '-' + dataWidth + }, 500); +} +//协议 +function inAgree(obj) { + if($('#defaults').hasClass('wst-active')) { + $(obj).addClass('ui-icon-unchecked-s'); + $(obj).removeClass('ui-icon-success-block wst-active'); + } else { + $(obj).removeClass('ui-icon-unchecked-s'); + $(obj).addClass('ui-icon-success-block wst-active'); + } +} +$(document).ready(function() { + var w = WST.pageWidth(); + var h = WST.pageHeight(); + $('#protocol .content').css('overflow-y', 'scroll').css('height', h - 61); + $("#protocol").css('right', -w); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/self_shop.js b/hyhproject/mobile2/view/default/js/self_shop.js new file mode 100755 index 0000000..27beb3c --- /dev/null +++ b/hyhproject/mobile2/view/default/js/self_shop.js @@ -0,0 +1,109 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + // 加载商品列表 + shopsList(); + var w = WST.pageWidth(); + // 商家推荐 + new Swiper('.swiper-container', { + slidesPerView: 4, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : false, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + // 推荐 + WST.imgAdapt('j-imgRec'); + // 热卖 + WST.imgAdapt('j-imgRec1'); + $('.wst-gol-adsb').css('height',$('.j-imgRec').width()+20); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(){ + if (loading) return; + if (($(window).scrollTop()) >= ($(document).height() - screen.height)) { + shopsList(); + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} +function searchGoods(){ + location.href=WST.U('mobile/shops/home','goodsName='+$('#searchKey').val(),true); +} +/*分类*/ +function goGoodsList(ct1,ct2){ + var param = 'shopId=1&ct1='+ct1; + if(ct2) + param += '&ct2='+ct2; + param.shopId = 1; + location.href=WST.U('mobile/shops/shopgoodslist',param,true); +} + +function shopAds(){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); + var w = WST.pageWidth(); + var h = w*2/5; + var o = $('.ui-slider').css("padding-top",h); + var scroll = new fz.Scroll('.ui-slider', { + scrollY: true + }); +} + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.currPage = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/shops/getFloorData'), param, function(data){ + var json = WST.toJson(data); + if(json && json.catId){ + var gettpl = document.getElementById('gList').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#goods-list').append(html); + }); + $('#currPage').val(json.currPage); + WST.imgAdapt('j-imgAdapt'); + } + loading = false; + $('#Load').hide(); + }); +} + +function toShopInfo(sid){ + location.href=WST.U('mobile/shops/index',{'shopId':sid},true) +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/settlement.js b/hyhproject/mobile2/view/default/js/settlement.js new file mode 100755 index 0000000..89448a5 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/settlement.js @@ -0,0 +1,327 @@ +jQuery.noConflict(); +function onSwitch(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); +} +/* 选择是否需要发票 */ +function isInvoice(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + $('#isInvoice').val(n);// 记录用户是否需要开发票 + $('#invoicesh').val(n); +} +/* 发票对象【个人or单位】 */ +function invOnSwitch(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + if(n==1){ + $('.inv_hidebox').show(); + }else{ + $('.inv_hidebox').hide(); + } + $('#invoice_obj').val(n);// 记录用户所开发票对象 +} +/* 发票抬头列表绑定事件 */ +$(function(){ + $('#invoice_head').focus(function(){ + $('#inv_headlist').show(); + }) + $('#invoice_head').blur(function(){ + setTimeout(function(){ + $('#inv_headlist').hide(); + },100) + }) + // 只要用户编辑了,就视为新增 + $('#invoice_head').bind('input propertychange', function() { + $('#invoiceId').val(0); + }); +}) +/* 完成发票信息填写 */ +function saveInvoice(){ + var param={}; + var invoiceId = $('#invoiceId').val();// 发票id + param.invoiceCode = $('#invoice_code').val();// 纳税人识别码 + param.invoiceHead = $('#invoice_head').val();// 发票抬头 + var url = 'mobile/invoices/add'; + if(invoiceId>0){ + url = 'mobile/invoices/edit'; + param.id = invoiceId; + } + if($('#invoice_obj').val()!=0){ + $.post(WST.U(url),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + setInvoiceText(); + if(invoiceId==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,'info'); + } + }) + }else{ + setInvoiceText(); + } + +} +// 设置页面显示值 +function setInvoiceText(){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var invoiceHead = $('#invoice_head').val();// 发票抬头 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)<br />'+invoiceHead+'<br />明细'; + } + $('#invoicest').html(text); + invoiceHide(); +} +function inDetermine(n){ + $('#'+n+' .wst-active').each(function(){ + type = $(this).attr('mode'); + word = $(this).attr('word'); + if(n=='payments')payCode = $(this).attr('payCode'); + }); + $('#'+n+'h').val(type); + $('#'+n+'t').html(word); + if(n=='payments'){ + $('#'+n+'w').val(payCode); + } + getCartMoney(); + dataHide(n); +} + +//计算价格 +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#scoreh').val(); + params.useScore = $('#userOrderScore').html(); + params.areaId2 = $('#areaId').val(); + params.deliverType = $('#givesh').val(); + params.sign = $('#sign').val(); + + params.couponIds = []; + $('input[id^="couponId_"]').each(function(){ + var shopId = $(this).attr('id').split('_')[1]; + params.couponIds.push(shopId+':'+$(this).val()); + }) + params.couponIds = params.couponIds.join(','); + + WST.load('正在计算价格...'); + if(params.sign==1){ + $.post(WST.U('mobile/carts/getCartMoney'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + for(var key in json.shops){ + // 设置每间店铺的运费及总价格 + $('#shopF_'+key).html('¥'+json.shops[key]['freight'].toFixed(2)); + $('#shopC_'+key).html('¥'+json.shops[key]['goodsMoney'].toFixed(2)); + } + $('#totalMoney').html('¥'+json.realTotalMoney.toFixed(2)); + $('#totalPrice').val(json.realTotalMoney); + // 设置可用积分及积分可抵金额 + $('#userOrderScore').html(json.maxScore); + $('#userOrderMoney').html(json.maxScoreMoney); + } + }); + }else if(params.sign==2){//虚拟商品 + params.deliverType = 1; + $.post(WST.U('mobile/carts/getQuickCartMoney'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + $('#totalMoney').html('¥'+json.realTotalMoney.toFixed(2)); + $('#totalPrice').val(json.realTotalMoney); + // 设置可用积分及积分可抵金额 + $('#userOrderScore').html(json.maxScore); + $('#userOrderMoney').html(json.maxScoreMoney); + } + }); + } +} +//提交订单 +function submitOrder(){ + var addressId = $('#addressId').val(); + if(addressId==''){ + WST.msg('请选择收货地址','info'); + return false; + } + WST.load('提交中···'); + var param = {}; + param.s_addressId = addressId; + param.s_areaId = $('#areaId').val(); + param.payType = $('#paymentsh').val(); + param.payCode = $('#paymentsw').val(); + param.isUseScore = $('#scoreh').val(); + param.useScore = $('#userOrderScore').html(); + + $('.wst-se-sh .shopn').each(function(){ + shopId = $(this).attr('shopId'); + param['remark_'+shopId] = $('#remark_'+shopId).val(); + param['couponId_'+shopId] = $('#couponId_'+shopId).val(); + }); + param.deliverType = $('#givesh').val(); + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + param.invoiceClient = $('#invoice_obj').val()==1?$('#invoice_head').val():'个人'; + $('.wst-se-confirm .button').attr('disabled', 'disabled'); + $.post(WST.U('mobile/orders/submit'),param,function(data,textStatus){ + var json = WST.toJson(data); + WST.noload(); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + if(param.payType==1 && $('#totalPrice').val()>0){ + if(param.payCode=='alipays' || param.payCode==''){ + location.href = WST.U('mobile/alipays/toAliPay',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='wallets'){ + location.href = WST.U('mobile/wallets/payment',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='unionpays'){ + location.href = WST.U('mobile/unionpays/toUnionpay',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='weixinpays'){ + location.href = WST.U('mobile/weixinpays/toWeixinPay',{"orderNo":json.data,'isBatch':1}); + } + }else{ + location.href = WST.U('mobile/orders/index'); + } + },1000); + }else{ + WST.msg(json.msg,'info'); + $('.wst-se-confirm .button').removeAttr('disabled'); + } + }); +} +//提交虚拟商品订单 +function quickSubmitOrder(){ + WST.load('提交中···'); + var param = {}; + param.payType = $('#paymentsh').val(); + param.payCode = $('#paymentsw').val(); + param.isUseScore = $('#scoreh').val(); + param.useScore = $('#userOrderScore').html(); + $('.wst-se-sh .shopn').each(function(){ + shopId = $(this).attr('shopId'); + param['remark_'+shopId] = $('#remark_'+shopId).val(); + param['couponId_'+shopId] = $('#couponId_'+shopId).val(); + }); + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + param.invoiceClient = $('#invoice_obj').val()==1?$('#invoice_head').val():'个人'; + $('.wst-se-confirm .button').attr('disabled', 'disabled'); + $.post(WST.U('mobile/orders/quickSubmit'),param,function(data,textStatus){ + var json = WST.toJson(data); + WST.noload(); + if(json.status==1){ + WST.msg(json.msg,'success' && $('#totalPrice').val()>0); + setTimeout(function(){ + if(param.payType==1){ + if(param.payCode=='alipays' || param.payCode==''){ + location.href = WST.U('mobile/alipays/toAliPay',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='wallets'){ + location.href = WST.U('mobile/wallets/payment',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='unionpays'){ + location.href = WST.U('mobile/unionpays/toUnionpay',{"orderNo":json.data,'isBatch':1}); + } + }else{ + location.href = WST.U('mobile/orders/index'); + } + + },1000); + }else{ + WST.msg(json.msg,'info'); + $('.wst-se-confirm .button').removeAttr('disabled'); + } + }); +} +function addAddress(type,id){ + location.href = WST.U('mobile/useraddress/index','type='+type+'&addressId='+id); +} +var dataHeight = $(".frame").css('height'); + dataHeight = parseInt(dataHeight)+50+'px'; +$(document).ready(function(){ + WST.imgAdapt('j-imgAdapt'); + $(".frame").css('bottom','-'+dataHeight); + + backPrevPage(WST.U('mobile/carts/index')); +}); +//弹框 +function dataShow(n){ + jQuery('#cover').attr("onclick","javascript:dataHide('"+n+"');").show(); + jQuery('#'+n).animate({"bottom": 0}, 500); + //显示已保存的数据 + var type = $('#'+n+'h').val(); + if(type==0){ + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'0').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + }else{ + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'1').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + } + if(n=='payments'){ + var payCode = $('#'+n+'w').val(); + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'_'+payCode).removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + } + if(n=='invoices'){ + if(type==0){ + jQuery('#j-invoice').hide(); + }else{ + jQuery('#j-invoice').show(); + } + } +} +function dataHide(n){ + jQuery('#'+n).animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} +document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#cover").is(":hidden")){ + event.preventDefault(); + } +}) + + + + + +/*********************** 发票信息层 ****************************/ +//弹框 +function invoiceShow(){ + jQuery('#cover').attr("onclick","javascript:invoiceHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600)// 隐藏背部页面 + +} +function invoiceHide(){ + $('#shopBox').show();// 隐藏背部页面 + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getInvoiceList(){ + $.post(WST.U('mobile/invoices/pageQuery'),{},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('invoiceBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('.inv_list_item').html(html); + invoiceShow(); + // 点击抬头item + $('.inv_list_item li').click(function(){ + // 设置值 + $('#invoice_head').val($(this).html()); + $('#invoiceId').val($(this).attr('invId')); + $('#invoice_code').val($(this).attr('invCode')); + }) + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/share/icon/more.png b/hyhproject/mobile2/view/default/js/share/icon/more.png new file mode 100755 index 0000000..fc09705 Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/more.png differ diff --git a/hyhproject/mobile2/view/default/js/share/icon/qq.png b/hyhproject/mobile2/view/default/js/share/icon/qq.png new file mode 100755 index 0000000..1a42948 Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/qq.png differ diff --git a/hyhproject/mobile2/view/default/js/share/icon/qqzone.png b/hyhproject/mobile2/view/default/js/share/icon/qqzone.png new file mode 100755 index 0000000..8d2f88a Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/qqzone.png differ diff --git a/hyhproject/mobile2/view/default/js/share/icon/weibo.png b/hyhproject/mobile2/view/default/js/share/icon/weibo.png new file mode 100755 index 0000000..8d34823 Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/weibo.png differ diff --git a/hyhproject/mobile2/view/default/js/share/icon/weixin.png b/hyhproject/mobile2/view/default/js/share/icon/weixin.png new file mode 100755 index 0000000..6d7bac1 Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/weixin.png differ diff --git a/hyhproject/mobile2/view/default/js/share/icon/weixin_friend.png b/hyhproject/mobile2/view/default/js/share/icon/weixin_friend.png new file mode 100755 index 0000000..e6f5a35 Binary files /dev/null and b/hyhproject/mobile2/view/default/js/share/icon/weixin_friend.png differ diff --git a/hyhproject/mobile2/view/default/js/share/nativeShare.css b/hyhproject/mobile2/view/default/js/share/nativeShare.css new file mode 100755 index 0000000..0f70d22 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/share/nativeShare.css @@ -0,0 +1,84 @@ + +#nativeShare { + font-size: 13px; +} + +#nativeShare .label { + font-size: 15px; + padding-left:10px; +} + +#nativeShare .list { + width: 90%; + margin: 0 auto; +} + +#nativeShare .list span { + width: 30%; + display: inline-block; + text-align: center; + margin: 10px 0; +} + +#nativeShare .list span i { + width: 40px; + height: 40px; + display: block; + margin: 0 auto; + margin-bottom: 5px; +} + +#nativeShare .weibo i { + background-image: url('./icon/weibo.png'); + background-size: cover; +} + +#nativeShare .weixin i { + background-image: url('./icon/weixin_friend.png'); + background-size: cover; +} + +#nativeShare .weixin_timeline i { + background-image: url('./icon/weixin.png'); + background-size: cover; +} + +#nativeShare .qq i { + background-image: url('./icon/qq.png'); + background-size: cover; +} + +#nativeShare .qzone i { + background-image: url('./icon/qqzone.png'); + background-size: cover; +} + +#nativeShare .more i { + background-image: url('./icon/more.png'); + background-size: cover; +} +.wst-cart-box { + position: fixed; + z-index: 9999; + left: 0px; + bottom: -296px; + width: 100%; + min-height: 38%; + background: #ffffff; + font-size: 0.15rem; +} +.wst-fr-box .button,.wst-cart-box .button{ + width: 90%; + font-size: .15rem; + height: 40px; + line-height: 40px; + color: #fff; + background: #e00102; + border-radius: 5px; + border-bottom: 1px solid #e00102; +} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{ + color:#fff0f0; + background:#f52f30; + background-clip: padding-box; +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/share/nativeShare.js b/hyhproject/mobile2/view/default/js/share/nativeShare.js new file mode 100755 index 0000000..4e04b7a --- /dev/null +++ b/hyhproject/mobile2/view/default/js/share/nativeShare.js @@ -0,0 +1,168 @@ + +var nativeShare = function (elementNode, config) { + if (!document.getElementById(elementNode)) { + return false; + } + + var qApiSrc = { + lower: "http://3gimg.qq.com/html5/js/qb.js", + higher: "http://jsapi.qq.com/get?api=app.share" + }; + var bLevel = { + qq: {forbid: 0, lower: 1, higher: 2}, + uc: {forbid: 0, allow: 1} + }; + var UA = navigator.appVersion; + var isqqBrowser = (UA.split("MQQBrowser/").length > 1) ? bLevel.qq.higher : bLevel.qq.forbid; + var isucBrowser = (UA.split("UCBrowser/").length > 1) ? bLevel.uc.allow : bLevel.uc.forbid; + var version = { + uc: "", + qq: "" + }; + var isWeixin = false; + + config = config || {}; + this.elementNode = elementNode; + this.url = config.url || document.location.href || ''; + this.title = config.title || document.title || ''; + this.desc = config.desc || document.title || ''; + this.img = config.img || document.getElementsByTagName('img').length > 0 && document.getElementsByTagName('img')[0].src || ''; + this.img_title = config.img_title || document.title || ''; + this.from = config.from || window.location.host || ''; + this.ucAppList = { + sinaWeibo: ['kSinaWeibo', 'SinaWeibo', 11, '新浪微博'], + weixin: ['kWeixin', 'WechatFriends', 1, '微信好友'], + weixinFriend: ['kWeixinFriend', 'WechatTimeline', '8', '微信朋友圈'], + QQ: ['kQQ', 'QQ', '4', 'QQ好友'], + QZone: ['kQZone', 'QZone', '3', 'QQ空间'] + }; + + this.share = function (to_app) { + var title = this.title, url = this.url, desc = this.desc, img = this.img, img_title = this.img_title, from = this.from; + if (isucBrowser) { + to_app = to_app == '' ? '' : (platform_os == 'iPhone' ? this.ucAppList[to_app][0] : this.ucAppList[to_app][1]); + if (to_app == 'QZone') { + B = "mqqapi://share/to_qzone?src_type=web&version=1&file_type=news&req_type=1&image_url="+img+"&title="+title+"&description="+desc+"&url="+url+"&app_name="+from; + k = document.createElement("div"), k.style.visibility = "hidden", k.innerHTML = '<iframe src="' + B + '" scrolling="no" width="1" height="1"></iframe>', document.body.appendChild(k), setTimeout(function () { + k && k.parentNode && k.parentNode.removeChild(k) + }, 5E3); + } + if (typeof(ucweb) != "undefined") { + ucweb.startRequest("shell.page_share", [title, title, url, to_app, "", "@" + from, ""]) + } else { + if (typeof(ucbrowser) != "undefined") { + ucbrowser.web_share(title, title, url, to_app, "", "@" + from, '') + } else { + } + } + } else { + if (isqqBrowser && !isWeixin) { + to_app = to_app == '' ? '' : this.ucAppList[to_app][2]; + var ah = { + url: url, + title: title, + description: desc, + img_url: img, + img_title: img_title, + to_app: to_app,//微信好友1,腾讯微博2,QQ空间3,QQ好友4,生成二维码7,微信朋友圈8,啾啾分享9,复制网址10,分享到微博11,创意分享13 + cus_txt: "请输入此时此刻想要分享的内容" + }; + ah = to_app == '' ? '' : ah; + if (typeof(browser) != "undefined") { + if (typeof(browser.app) != "undefined" && isqqBrowser == bLevel.qq.higher) { + browser.app.share(ah) + } + } else { + if (typeof(window.qb) != "undefined" && isqqBrowser == bLevel.qq.lower) { + window.qb.share(ah) + } else { + } + } + } else { + } + } + }; + + this.html = function() { + var position = document.getElementById(this.elementNode); + var html = '<div class="label">分享到</div>'+ + '<div class="list clearfix">'+ + '<span data-app="sinaWeibo" class="nativeShare weibo"><i></i>新浪微博</span>'+ + '<span data-app="weixin" class="nativeShare weixin"><i></i>微信好友</span>'+ + '<span data-app="weixinFriend" class="nativeShare weixin_timeline"><i></i>微信朋友圈</span>'+ + '<span data-app="QQ" class="nativeShare qq"><i></i>QQ好友</span>'+ + '<span data-app="QZone" class="nativeShare qzone"><i></i>QQ空间</span>'+ + '<span data-app="" class="nativeShare more"><i></i>更多</span>'+ + '</div>'; + position.innerHTML = html; + }; + + this.isloadqqApi = function () { + if (isqqBrowser) { + var b = (version.qq < 5.4) ? qApiSrc.lower : qApiSrc.higher; + var d = document.createElement("script"); + var a = document.getElementsByTagName("body")[0]; + d.setAttribute("src", b); + a.appendChild(d) + } + }; + + this.getPlantform = function () { + ua = navigator.userAgent; + if ((ua.indexOf("iPhone") > -1 || ua.indexOf("iPod") > -1)) { + return "iPhone" + } + return "Android" + }; + + this.is_weixin = function () { + var a = UA.toLowerCase(); + if (a.match(/MicroMessenger/i) == "micromessenger") { + return true + } else { + return false + } + }; + + this.getVersion = function (c) { + var a = c.split("."), b = parseFloat(a[0] + "." + a[1]); + return b + }; + + this.init = function () { + platform_os = this.getPlantform(); + version.qq = isqqBrowser ? this.getVersion(UA.split("MQQBrowser/")[1]) : 0; + version.uc = isucBrowser ? this.getVersion(UA.split("UCBrowser/")[1]) : 0; + isWeixin = this.is_weixin(); + if ((isqqBrowser && version.qq < 5.4 && platform_os == "iPhone") || (isqqBrowser && version.qq < 5.3 && platform_os == "Android")) { + isqqBrowser = bLevel.qq.forbid + } else { + if (isqqBrowser && version.qq < 5.4 && platform_os == "Android") { + isqqBrowser = bLevel.qq.lower + } else { + if (isucBrowser && ((version.uc < 10.2 && platform_os == "iPhone") || (version.uc < 9.7 && platform_os == "Android"))) { + isucBrowser = bLevel.uc.forbid + } + } + } + this.isloadqqApi(); + if (isqqBrowser || isucBrowser) { + this.html(); + } else { + document.write('<script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_m.js" charset="utf-8"></script>'); + + } + }; + + this.init(); + + var share = this; + var items = document.getElementsByClassName('nativeShare'); + for (var i=0;i<items.length;i++) { + items[i].onclick = function(){ + share.share(this.getAttribute('data-app')); + } + } + + return this; +}; diff --git a/hyhproject/mobile2/view/default/js/shop_goods_list.js b/hyhproject/mobile2/view/default/js/shop_goods_list.js new file mode 100755 index 0000000..08219f6 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/shop_goods_list.js @@ -0,0 +1,128 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + // 加载商品列表 + shopsList(); + // 楼层商品 + WST.imgAdapt('j-imgAdapt'); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(event){ + var wScrollY = window.scrollY; // 当前滚动条位置 + var wInnerH = window.innerHeight; // 设备窗口的高度(不会变) + var bScrollH = document.body.scrollHeight; // 滚动条总高度 + if (wScrollY + wInnerH >= bScrollH) { + var currPage = Number( $('#currPage').val() ); + var totalPage = Number( $('#totalPage').val() ); + if(currPage < totalPage ){ + shopsList(); + } + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} + + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = $('#condition').val(); + param.mdesc = $('#desc').val(); + param.goodsName = $('#keyword').val(); + param.ct1 = $('#ct1').val(); + param.ct2 = $('#ct2').val(); + + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>对不起,没有相关商品。</p>'; + html += '</div>'; + $('#shops-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +/*分类*/ +function getGoodsList(ct1,ct2){ + $('#ct2').val(''); + $('#ct1').val(ct1); + if(ct2)$('#ct2').val(ct2); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + $("#wst-shops-search").hide(); + dataHide(); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/shop_home.js b/hyhproject/mobile2/view/default/js/shop_home.js new file mode 100755 index 0000000..e525226 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/shop_home.js @@ -0,0 +1,190 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + fixedTerm(); + shopBest(); + WST.imgAdapt('j-imgIndex'); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(){ + if (loading) return; + if((($(window).scrollTop()+$(window).height())+50)>=$(document).height()){ + if($('#currPage').val()<$('#totalPage').val())shopsList(); + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} + +function shopAds(){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); +} +//排序条件 +function orderCondition(obj,condition){ + jQuery('html,body').scrollTop($('#j-top').offset().top); + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} + +//查看 +function switchTerm(n){ + if(parseInt($('#j-top').offset().top)>$(window).scrollTop()){ + jQuery('html,body').animate({scrollTop:$('#j-top').offset().top}, 800); + } + $('#j-top'+n).addClass('active').siblings('.wst-sh-term li').removeClass('active'); + if(n==1){ + $('#j-index1').show(); + $('#j-index0').hide(); + }else{ + $('#j-index0').show(); + $('#j-index1').hide(); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + } +} +function fixedTerm(){ + var offsetTop = $("#j-top").offset().top; + $(window).scroll(function() { + var scrollTop = $(window).scrollTop(); + if (scrollTop > offsetTop){ + $("#j-top").addClass('active'); + $('#j-index0').css('padding-top',45); + $('#j-index1').css('padding-top',45); + }else{ + $("#j-top").removeClass('active'); + $('#j-index0').css('padding-top',0); + $('#j-index1').css('padding-top',0); + } + }); +} + +//获取商品列表销量 +function shopBest(){ + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = 2; + param.mdesc = 1; + param.pagesize = 6; + $.post(WST.U('mobile/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopBest').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#best-list').append(html); + }); + } + WST.imgAdapt('j-imgBest'); + loading = false; + }); +} + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = $('#condition').val(); + param.mdesc = $('#desc').val(); + param.goodsName = $('#keyword').val(); + param.ct1 = $('#ct1').val(); + param.ct2 = $('#ct2').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>对不起,没有相关商品。</p>'; + html += '</div>'; + $('#shops-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +/*分类*/ +function getGoodsList(ct1,ct2){ + $('#ct2').val(''); + $('#ct1').val(ct1); + if(ct2)$('#ct2').val(ct2); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + $("#wst-shops-search").hide(); + dataHide(); + switchTerm(0); +} + +function toShopInfo(sid){ + location.href=WST.U('mobile/shops/index',{'shopId':sid},true) +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/shops_list.js b/hyhproject/mobile2/view/default/js/shops_list.js new file mode 100755 index 0000000..a1950e5 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/shops_list.js @@ -0,0 +1,124 @@ +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + $('.wst-shl-select').removeClass('active'); + if(classContent.indexOf('active')==-1){ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('down'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $('.wst-shl-head .evaluate i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +function orderSelect(id){ + $('.wst-shl-select').addClass('active'); + $('.evaluate .choice').removeClass('active'); + $('.wst-shl-head .evaluate i').addClass('down').removeClass('down2'); + $('#catId').val(id); + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +function searchCondition(id){ + $("#wst-shops-search").hide(); + $('#catId').val(id); + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +//获取店铺列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.id = $('#catId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#keyword').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/shops/pageQuery'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + imgShop('j-imgAdapt'); + imgShop('goods-item'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + + if($('.wst-shl-ads a').hasClass("adsImg")){ + //中间小广告 + new Swiper('.swiper-container', { + slidesPerView: 3, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : true, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + }else{ + $('.wst-shl-ads').hide(); + } + shopsList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + shopsList(); + } + } + }); +}); +function goShopHome(sid){ + location.href=WST.U('mobile/shops/home','shopId='+sid,true); +} +//适应图片大小正方形 +function imgShop(name){ + var w = $('.'+name).width(); + if(name == 'j-imgAdapt'){ + $('.'+name).css({"width": w+"px","height": w+"px"}); + }else{ + $('.'+name).css({"width": w+"px","height": w+20+"px"}); + } + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a .goodsPrice').css({"width": w+"px"}); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/js/swiper.jquery.min.js b/hyhproject/mobile2/view/default/js/swiper.jquery.min.js new file mode 100755 index 0000000..ca9f537 --- /dev/null +++ b/hyhproject/mobile2/view/default/js/swiper.jquery.min.js @@ -0,0 +1,16 @@ +/** + * Swiper 3.1.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2015, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: August 22, 2015 + */ +!function(){"use strict";function e(e){e.fn.swiper=function(a){var s;return e(this).each(function(){var e=new t(this,a);s||(s=e)}),s}}var a,t=function(e,s){function r(){return"horizontal"===v.params.direction}function i(e){return Math.floor(e)}function n(){v.autoplayTimeoutId=setTimeout(function(){v.params.loop?(v.fixLoop(),v._slideNext()):v.isEnd?s.autoplayStopOnLast?v.stopAutoplay():v._slideTo(0):v._slideNext()},v.params.autoplay)}function o(e,t){var s=a(e.target);if(!s.is(t))if("string"==typeof t)s=s.parents(t);else if(t.nodeType){var r;return s.parents().each(function(e,a){a===t&&(r=t)}),r?t:void 0}return 0===s.length?void 0:s[0]}function l(e,a){a=a||{};var t=window.MutationObserver||window.WebkitMutationObserver,s=new t(function(e){e.forEach(function(e){v.onResize(!0),v.emit("onObserverUpdate",v,e)})});s.observe(e,{attributes:"undefined"==typeof a.attributes?!0:a.attributes,childList:"undefined"==typeof a.childList?!0:a.childList,characterData:"undefined"==typeof a.characterData?!0:a.characterData}),v.observers.push(s)}function p(e){e.originalEvent&&(e=e.originalEvent);var a=e.keyCode||e.charCode;if(!v.params.allowSwipeToNext&&(r()&&39===a||!r()&&40===a))return!1;if(!v.params.allowSwipeToPrev&&(r()&&37===a||!r()&&38===a))return!1;if(!(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||document.activeElement&&document.activeElement.nodeName&&("input"===document.activeElement.nodeName.toLowerCase()||"textarea"===document.activeElement.nodeName.toLowerCase()))){if(37===a||39===a||38===a||40===a){var t=!1;if(v.container.parents(".swiper-slide").length>0&&0===v.container.parents(".swiper-slide-active").length)return;var s={left:window.pageXOffset,top:window.pageYOffset},i=window.innerWidth,n=window.innerHeight,o=v.container.offset();v.rtl&&(o.left=o.left-v.container[0].scrollLeft);for(var l=[[o.left,o.top],[o.left+v.width,o.top],[o.left,o.top+v.height],[o.left+v.width,o.top+v.height]],p=0;p<l.length;p++){var d=l[p];d[0]>=s.left&&d[0]<=s.left+i&&d[1]>=s.top&&d[1]<=s.top+n&&(t=!0)}if(!t)return}r()?((37===a||39===a)&&(e.preventDefault?e.preventDefault():e.returnValue=!1),(39===a&&!v.rtl||37===a&&v.rtl)&&v.slideNext(),(37===a&&!v.rtl||39===a&&v.rtl)&&v.slidePrev()):((38===a||40===a)&&(e.preventDefault?e.preventDefault():e.returnValue=!1),40===a&&v.slideNext(),38===a&&v.slidePrev())}}function d(e){e.originalEvent&&(e=e.originalEvent);var a=v.mousewheel.event,t=0;if(e.detail)t=-e.detail;else if("mousewheel"===a)if(v.params.mousewheelForceToAxis)if(r()){if(!(Math.abs(e.wheelDeltaX)>Math.abs(e.wheelDeltaY)))return;t=e.wheelDeltaX}else{if(!(Math.abs(e.wheelDeltaY)>Math.abs(e.wheelDeltaX)))return;t=e.wheelDeltaY}else t=e.wheelDelta;else if("DOMMouseScroll"===a)t=-e.detail;else if("wheel"===a)if(v.params.mousewheelForceToAxis)if(r()){if(!(Math.abs(e.deltaX)>Math.abs(e.deltaY)))return;t=-e.deltaX}else{if(!(Math.abs(e.deltaY)>Math.abs(e.deltaX)))return;t=-e.deltaY}else t=Math.abs(e.deltaX)>Math.abs(e.deltaY)?-e.deltaX:-e.deltaY;if(v.params.mousewheelInvert&&(t=-t),v.params.freeMode){var s=v.getWrapperTranslate()+t*v.params.mousewheelSensitivity;if(s>0&&(s=0),s<v.maxTranslate()&&(s=v.maxTranslate()),v.setWrapperTransition(0),v.setWrapperTranslate(s),v.updateProgress(),v.updateActiveIndex(),v.params.freeModeSticky&&(clearTimeout(v.mousewheel.timeout),v.mousewheel.timeout=setTimeout(function(){v.slideReset()},300)),0===s||s===v.maxTranslate())return}else{if((new window.Date).getTime()-v.mousewheel.lastScrollTime>60)if(0>t)if(v.isEnd&&!v.params.loop||v.animating){if(v.params.mousewheelReleaseOnEdges)return!0}else v.slideNext();else if(v.isBeginning&&!v.params.loop||v.animating){if(v.params.mousewheelReleaseOnEdges)return!0}else v.slidePrev();v.mousewheel.lastScrollTime=(new window.Date).getTime()}return v.params.autoplay&&v.stopAutoplay(),e.preventDefault?e.preventDefault():e.returnValue=!1,!1}function u(e,t){e=a(e);var s,i,n;s=e.attr("data-swiper-parallax")||"0",i=e.attr("data-swiper-parallax-x"),n=e.attr("data-swiper-parallax-y"),i||n?(i=i||"0",n=n||"0"):r()?(i=s,n="0"):(n=s,i="0"),i=i.indexOf("%")>=0?parseInt(i,10)*t+"%":i*t+"px",n=n.indexOf("%")>=0?parseInt(n,10)*t+"%":n*t+"px",e.transform("translate3d("+i+", "+n+",0px)")}function c(e){return 0!==e.indexOf("on")&&(e=e[0]!==e[0].toUpperCase()?"on"+e[0].toUpperCase()+e.substring(1):"on"+e),e}if(!(this instanceof t))return new t(e,s);var m={direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,autoplay:!1,autoplayDisableOnInteraction:!0,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeSticky:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},cube:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fade:{crossFade:!1},parallax:!1,scrollbar:null,scrollbarHide:!0,keyboardControl:!1,mousewheelControl:!1,mousewheelReleaseOnEdges:!1,mousewheelInvert:!1,mousewheelForceToAxis:!1,mousewheelSensitivity:1,hashnav:!1,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,onlyExternal:!1,threshold:0,touchMoveStopPropagation:!0,pagination:null,paginationElement:"span",paginationClickable:!1,paginationHide:!1,paginationBulletRender:null,resistance:!0,resistanceRatio:.85,nextButton:null,prevButton:null,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,lazyLoading:!1,lazyLoadingInPrevNext:!1,lazyLoadingOnTransitionStart:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,control:void 0,controlInverse:!1,controlBy:"slide",allowSwipeToPrev:!0,allowSwipeToNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",slideClass:"swiper-slide",slideActiveClass:"swiper-slide-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slidePrevClass:"swiper-slide-prev",wrapperClass:"swiper-wrapper",bulletClass:"swiper-pagination-bullet",bulletActiveClass:"swiper-pagination-bullet-active",buttonDisabledClass:"swiper-button-disabled",paginationHiddenClass:"swiper-pagination-hidden",observer:!1,observeParents:!1,a11y:!1,prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}",runCallbacksOnInit:!0},f=s&&s.virtualTranslate;s=s||{};for(var h in m)if("undefined"==typeof s[h])s[h]=m[h];else if("object"==typeof s[h])for(var g in m[h])"undefined"==typeof s[h][g]&&(s[h][g]=m[h][g]);var v=this;if(v.version="3.1.0",v.params=s,v.classNames=[],"undefined"!=typeof a&&"undefined"!=typeof Dom7&&(a=Dom7),("undefined"!=typeof a||(a="undefined"==typeof Dom7?window.Dom7||window.Zepto||window.jQuery:Dom7))&&(v.$=a,v.container=a(e),0!==v.container.length)){if(v.container.length>1)return void v.container.each(function(){new t(this,s)});v.container[0].swiper=v,v.container.data("swiper",v),v.classNames.push("swiper-container-"+v.params.direction),v.params.freeMode&&v.classNames.push("swiper-container-free-mode"),v.support.flexbox||(v.classNames.push("swiper-container-no-flexbox"),v.params.slidesPerColumn=1),(v.params.parallax||v.params.watchSlidesVisibility)&&(v.params.watchSlidesProgress=!0),["cube","coverflow"].indexOf(v.params.effect)>=0&&(v.support.transforms3d?(v.params.watchSlidesProgress=!0,v.classNames.push("swiper-container-3d")):v.params.effect="slide"),"slide"!==v.params.effect&&v.classNames.push("swiper-container-"+v.params.effect),"cube"===v.params.effect&&(v.params.resistanceRatio=0,v.params.slidesPerView=1,v.params.slidesPerColumn=1,v.params.slidesPerGroup=1,v.params.centeredSlides=!1,v.params.spaceBetween=0,v.params.virtualTranslate=!0,v.params.setWrapperSize=!1),"fade"===v.params.effect&&(v.params.slidesPerView=1,v.params.slidesPerColumn=1,v.params.slidesPerGroup=1,v.params.watchSlidesProgress=!0,v.params.spaceBetween=0,"undefined"==typeof f&&(v.params.virtualTranslate=!0)),v.params.grabCursor&&v.support.touch&&(v.params.grabCursor=!1),v.wrapper=v.container.children("."+v.params.wrapperClass),v.params.pagination&&(v.paginationContainer=a(v.params.pagination),v.params.paginationClickable&&v.paginationContainer.addClass("swiper-pagination-clickable")),v.rtl=r()&&("rtl"===v.container[0].dir.toLowerCase()||"rtl"===v.container.css("direction")),v.rtl&&v.classNames.push("swiper-container-rtl"),v.rtl&&(v.wrongRTL="-webkit-box"===v.wrapper.css("display")),v.params.slidesPerColumn>1&&v.classNames.push("swiper-container-multirow"),v.device.android&&v.classNames.push("swiper-container-android"),v.container.addClass(v.classNames.join(" ")),v.translate=0,v.progress=0,v.velocity=0,v.lockSwipeToNext=function(){v.params.allowSwipeToNext=!1},v.lockSwipeToPrev=function(){v.params.allowSwipeToPrev=!1},v.lockSwipes=function(){v.params.allowSwipeToNext=v.params.allowSwipeToPrev=!1},v.unlockSwipeToNext=function(){v.params.allowSwipeToNext=!0},v.unlockSwipeToPrev=function(){v.params.allowSwipeToPrev=!0},v.unlockSwipes=function(){v.params.allowSwipeToNext=v.params.allowSwipeToPrev=!0},v.params.grabCursor&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grab",v.container[0].style.cursor="-moz-grab",v.container[0].style.cursor="grab"),v.imagesToLoad=[],v.imagesLoaded=0,v.loadImage=function(e,a,t,s){function r(){s&&s()}var i;e.complete&&t?r():a?(i=new window.Image,i.onload=r,i.onerror=r,i.src=a):r()},v.preloadImages=function(){function e(){"undefined"!=typeof v&&null!==v&&(void 0!==v.imagesLoaded&&v.imagesLoaded++,v.imagesLoaded===v.imagesToLoad.length&&(v.params.updateOnImagesReady&&v.update(),v.emit("onImagesReady",v)))}v.imagesToLoad=v.container.find("img");for(var a=0;a<v.imagesToLoad.length;a++)v.loadImage(v.imagesToLoad[a],v.imagesToLoad[a].currentSrc||v.imagesToLoad[a].getAttribute("src"),!0,e)},v.autoplayTimeoutId=void 0,v.autoplaying=!1,v.autoplayPaused=!1,v.startAutoplay=function(){return"undefined"!=typeof v.autoplayTimeoutId?!1:v.params.autoplay?v.autoplaying?!1:(v.autoplaying=!0,v.emit("onAutoplayStart",v),void n()):!1},v.stopAutoplay=function(e){v.autoplayTimeoutId&&(v.autoplayTimeoutId&&clearTimeout(v.autoplayTimeoutId),v.autoplaying=!1,v.autoplayTimeoutId=void 0,v.emit("onAutoplayStop",v))},v.pauseAutoplay=function(e){v.autoplayPaused||(v.autoplayTimeoutId&&clearTimeout(v.autoplayTimeoutId),v.autoplayPaused=!0,0===e?(v.autoplayPaused=!1,n()):v.wrapper.transitionEnd(function(){v&&(v.autoplayPaused=!1,v.autoplaying?n():v.stopAutoplay())}))},v.minTranslate=function(){return-v.snapGrid[0]},v.maxTranslate=function(){return-v.snapGrid[v.snapGrid.length-1]},v.updateContainerSize=function(){var e,a;e="undefined"!=typeof v.params.width?v.params.width:v.container[0].clientWidth,a="undefined"!=typeof v.params.height?v.params.height:v.container[0].clientHeight,0===e&&r()||0===a&&!r()||(e=e-parseInt(v.container.css("padding-left"),10)-parseInt(v.container.css("padding-right"),10),a=a-parseInt(v.container.css("padding-top"),10)-parseInt(v.container.css("padding-bottom"),10),v.width=e,v.height=a,v.size=r()?v.width:v.height)},v.updateSlidesSize=function(){v.slides=v.wrapper.children("."+v.params.slideClass),v.snapGrid=[],v.slidesGrid=[],v.slidesSizesGrid=[];var e,a=v.params.spaceBetween,t=-v.params.slidesOffsetBefore,s=0,n=0;"string"==typeof a&&a.indexOf("%")>=0&&(a=parseFloat(a.replace("%",""))/100*v.size),v.virtualSize=-a,v.slides.css(v.rtl?{marginLeft:"",marginTop:""}:{marginRight:"",marginBottom:""});var o;v.params.slidesPerColumn>1&&(o=Math.floor(v.slides.length/v.params.slidesPerColumn)===v.slides.length/v.params.slidesPerColumn?v.slides.length:Math.ceil(v.slides.length/v.params.slidesPerColumn)*v.params.slidesPerColumn);var l,p=v.params.slidesPerColumn,d=o/p,u=d-(v.params.slidesPerColumn*d-v.slides.length);for(e=0;e<v.slides.length;e++){l=0;var c=v.slides.eq(e);if(v.params.slidesPerColumn>1){var m,f,h;"column"===v.params.slidesPerColumnFill?(f=Math.floor(e/p),h=e-f*p,(f>u||f===u&&h===p-1)&&++h>=p&&(h=0,f++),m=f+h*o/p,c.css({"-webkit-box-ordinal-group":m,"-moz-box-ordinal-group":m,"-ms-flex-order":m,"-webkit-order":m,order:m})):(h=Math.floor(e/d),f=e-h*d),c.css({"margin-top":0!==h&&v.params.spaceBetween&&v.params.spaceBetween+"px"}).attr("data-swiper-column",f).attr("data-swiper-row",h)}"none"!==c.css("display")&&("auto"===v.params.slidesPerView?(l=r()?c.outerWidth(!0):c.outerHeight(!0),v.params.roundLengths&&(l=i(l))):(l=(v.size-(v.params.slidesPerView-1)*a)/v.params.slidesPerView,v.params.roundLengths&&(l=i(l)),r()?v.slides[e].style.width=l+"px":v.slides[e].style.height=l+"px"),v.slides[e].swiperSlideSize=l,v.slidesSizesGrid.push(l),v.params.centeredSlides?(t=t+l/2+s/2+a,0===e&&(t=t-v.size/2-a),Math.abs(t)<.001&&(t=0),n%v.params.slidesPerGroup===0&&v.snapGrid.push(t),v.slidesGrid.push(t)):(n%v.params.slidesPerGroup===0&&v.snapGrid.push(t),v.slidesGrid.push(t),t=t+l+a),v.virtualSize+=l+a,s=l,n++)}v.virtualSize=Math.max(v.virtualSize,v.size)+v.params.slidesOffsetAfter;var g;if(v.rtl&&v.wrongRTL&&("slide"===v.params.effect||"coverflow"===v.params.effect)&&v.wrapper.css({width:v.virtualSize+v.params.spaceBetween+"px"}),(!v.support.flexbox||v.params.setWrapperSize)&&v.wrapper.css(r()?{width:v.virtualSize+v.params.spaceBetween+"px"}:{height:v.virtualSize+v.params.spaceBetween+"px"}),v.params.slidesPerColumn>1&&(v.virtualSize=(l+v.params.spaceBetween)*o,v.virtualSize=Math.ceil(v.virtualSize/v.params.slidesPerColumn)-v.params.spaceBetween,v.wrapper.css({width:v.virtualSize+v.params.spaceBetween+"px"}),v.params.centeredSlides)){for(g=[],e=0;e<v.snapGrid.length;e++)v.snapGrid[e]<v.virtualSize+v.snapGrid[0]&&g.push(v.snapGrid[e]);v.snapGrid=g}if(!v.params.centeredSlides){for(g=[],e=0;e<v.snapGrid.length;e++)v.snapGrid[e]<=v.virtualSize-v.size&&g.push(v.snapGrid[e]);v.snapGrid=g,Math.floor(v.virtualSize-v.size)>Math.floor(v.snapGrid[v.snapGrid.length-1])&&v.snapGrid.push(v.virtualSize-v.size)}0===v.snapGrid.length&&(v.snapGrid=[0]),0!==v.params.spaceBetween&&v.slides.css(r()?v.rtl?{marginLeft:a+"px"}:{marginRight:a+"px"}:{marginBottom:a+"px"}),v.params.watchSlidesProgress&&v.updateSlidesOffset()},v.updateSlidesOffset=function(){for(var e=0;e<v.slides.length;e++)v.slides[e].swiperSlideOffset=r()?v.slides[e].offsetLeft:v.slides[e].offsetTop},v.updateSlidesProgress=function(e){if("undefined"==typeof e&&(e=v.translate||0),0!==v.slides.length){"undefined"==typeof v.slides[0].swiperSlideOffset&&v.updateSlidesOffset();var a=-e;v.rtl&&(a=e);{v.container[0].getBoundingClientRect(),r()?"left":"top",r()?"right":"bottom"}v.slides.removeClass(v.params.slideVisibleClass);for(var t=0;t<v.slides.length;t++){var s=v.slides[t],i=(a-s.swiperSlideOffset)/(s.swiperSlideSize+v.params.spaceBetween);if(v.params.watchSlidesVisibility){var n=-(a-s.swiperSlideOffset),o=n+v.slidesSizesGrid[t],l=n>=0&&n<v.size||o>0&&o<=v.size||0>=n&&o>=v.size;l&&v.slides.eq(t).addClass(v.params.slideVisibleClass)}s.progress=v.rtl?-i:i}}},v.updateProgress=function(e){"undefined"==typeof e&&(e=v.translate||0);var a=v.maxTranslate()-v.minTranslate();0===a?(v.progress=0,v.isBeginning=v.isEnd=!0):(v.progress=(e-v.minTranslate())/a,v.isBeginning=v.progress<=0,v.isEnd=v.progress>=1),v.isBeginning&&v.emit("onReachBeginning",v),v.isEnd&&v.emit("onReachEnd",v),v.params.watchSlidesProgress&&v.updateSlidesProgress(e),v.emit("onProgress",v,v.progress)},v.updateActiveIndex=function(){var e,a,t,s=v.rtl?v.translate:-v.translate;for(a=0;a<v.slidesGrid.length;a++)"undefined"!=typeof v.slidesGrid[a+1]?s>=v.slidesGrid[a]&&s<v.slidesGrid[a+1]-(v.slidesGrid[a+1]-v.slidesGrid[a])/2?e=a:s>=v.slidesGrid[a]&&s<v.slidesGrid[a+1]&&(e=a+1):s>=v.slidesGrid[a]&&(e=a);(0>e||"undefined"==typeof e)&&(e=0),t=Math.floor(e/v.params.slidesPerGroup),t>=v.snapGrid.length&&(t=v.snapGrid.length-1),e!==v.activeIndex&&(v.snapIndex=t,v.previousIndex=v.activeIndex,v.activeIndex=e,v.updateClasses())},v.updateClasses=function(){v.slides.removeClass(v.params.slideActiveClass+" "+v.params.slideNextClass+" "+v.params.slidePrevClass);var e=v.slides.eq(v.activeIndex);if(e.addClass(v.params.slideActiveClass),e.next("."+v.params.slideClass).addClass(v.params.slideNextClass),e.prev("."+v.params.slideClass).addClass(v.params.slidePrevClass),v.bullets&&v.bullets.length>0){v.bullets.removeClass(v.params.bulletActiveClass);var t;v.params.loop?(t=Math.ceil(v.activeIndex-v.loopedSlides)/v.params.slidesPerGroup,t>v.slides.length-1-2*v.loopedSlides&&(t-=v.slides.length-2*v.loopedSlides),t>v.bullets.length-1&&(t-=v.bullets.length)):t="undefined"!=typeof v.snapIndex?v.snapIndex:v.activeIndex||0,v.paginationContainer.length>1?v.bullets.each(function(){a(this).index()===t&&a(this).addClass(v.params.bulletActiveClass)}):v.bullets.eq(t).addClass(v.params.bulletActiveClass)}v.params.loop||(v.params.prevButton&&(v.isBeginning?(a(v.params.prevButton).addClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.disable(a(v.params.prevButton))):(a(v.params.prevButton).removeClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.enable(a(v.params.prevButton)))),v.params.nextButton&&(v.isEnd?(a(v.params.nextButton).addClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.disable(a(v.params.nextButton))):(a(v.params.nextButton).removeClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.enable(a(v.params.nextButton)))))},v.updatePagination=function(){if(v.params.pagination&&v.paginationContainer&&v.paginationContainer.length>0){for(var e="",a=v.params.loop?Math.ceil((v.slides.length-2*v.loopedSlides)/v.params.slidesPerGroup):v.snapGrid.length,t=0;a>t;t++)e+=v.params.paginationBulletRender?v.params.paginationBulletRender(t,v.params.bulletClass):"<"+v.params.paginationElement+' class="'+v.params.bulletClass+'"></'+v.params.paginationElement+">";v.paginationContainer.html(e),v.bullets=v.paginationContainer.find("."+v.params.bulletClass),v.params.paginationClickable&&v.params.a11y&&v.a11y&&v.a11y.initPagination()}},v.update=function(e){function a(){s=Math.min(Math.max(v.translate,v.maxTranslate()),v.minTranslate()),v.setWrapperTranslate(s),v.updateActiveIndex(),v.updateClasses()}if(v.updateContainerSize(),v.updateSlidesSize(),v.updateProgress(),v.updatePagination(),v.updateClasses(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),e){var t,s;v.controller&&v.controller.spline&&(v.controller.spline=void 0),v.params.freeMode?a():(t=("auto"===v.params.slidesPerView||v.params.slidesPerView>1)&&v.isEnd&&!v.params.centeredSlides?v.slideTo(v.slides.length-1,0,!1,!0):v.slideTo(v.activeIndex,0,!1,!0),t||a())}},v.onResize=function(e){var a=v.params.allowSwipeToPrev,t=v.params.allowSwipeToNext;if(v.params.allowSwipeToPrev=v.params.allowSwipeToNext=!0,v.updateContainerSize(),v.updateSlidesSize(),("auto"===v.params.slidesPerView||v.params.freeMode||e)&&v.updatePagination(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),v.controller&&v.controller.spline&&(v.controller.spline=void 0),v.params.freeMode){var s=Math.min(Math.max(v.translate,v.maxTranslate()),v.minTranslate());v.setWrapperTranslate(s),v.updateActiveIndex(),v.updateClasses()}else v.updateClasses(),("auto"===v.params.slidesPerView||v.params.slidesPerView>1)&&v.isEnd&&!v.params.centeredSlides?v.slideTo(v.slides.length-1,0,!1,!0):v.slideTo(v.activeIndex,0,!1,!0);v.params.allowSwipeToPrev=a,v.params.allowSwipeToNext=t};var w=["mousedown","mousemove","mouseup"];window.navigator.pointerEnabled?w=["pointerdown","pointermove","pointerup"]:window.navigator.msPointerEnabled&&(w=["MSPointerDown","MSPointerMove","MSPointerUp"]),v.touchEvents={start:v.support.touch||!v.params.simulateTouch?"touchstart":w[0],move:v.support.touch||!v.params.simulateTouch?"touchmove":w[1],end:v.support.touch||!v.params.simulateTouch?"touchend":w[2]},(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&("container"===v.params.touchEventsTarget?v.container:v.wrapper).addClass("swiper-wp8-"+v.params.direction),v.initEvents=function(e){var t=e?"off":"on",r=e?"removeEventListener":"addEventListener",i="container"===v.params.touchEventsTarget?v.container[0]:v.wrapper[0],n=v.support.touch?i:document,o=v.params.nested?!0:!1;v.browser.ie?(i[r](v.touchEvents.start,v.onTouchStart,!1),n[r](v.touchEvents.move,v.onTouchMove,o),n[r](v.touchEvents.end,v.onTouchEnd,!1)):(v.support.touch&&(i[r](v.touchEvents.start,v.onTouchStart,!1),i[r](v.touchEvents.move,v.onTouchMove,o),i[r](v.touchEvents.end,v.onTouchEnd,!1)),!s.simulateTouch||v.device.ios||v.device.android||(i[r]("mousedown",v.onTouchStart,!1),document[r]("mousemove",v.onTouchMove,o),document[r]("mouseup",v.onTouchEnd,!1))),window[r]("resize",v.onResize),v.params.nextButton&&(a(v.params.nextButton)[t]("click",v.onClickNext),v.params.a11y&&v.a11y&&a(v.params.nextButton)[t]("keydown",v.a11y.onEnterKey)),v.params.prevButton&&(a(v.params.prevButton)[t]("click",v.onClickPrev),v.params.a11y&&v.a11y&&a(v.params.prevButton)[t]("keydown",v.a11y.onEnterKey)),v.params.pagination&&v.params.paginationClickable&&(a(v.paginationContainer)[t]("click","."+v.params.bulletClass,v.onClickIndex),v.params.a11y&&v.a11y&&a(v.paginationContainer)[t]("keydown","."+v.params.bulletClass,v.a11y.onEnterKey)),(v.params.preventClicks||v.params.preventClicksPropagation)&&i[r]("click",v.preventClicks,!0)},v.attachEvents=function(e){v.initEvents()},v.detachEvents=function(){v.initEvents(!0)},v.allowClick=!0,v.preventClicks=function(e){v.allowClick||(v.params.preventClicks&&e.preventDefault(),v.params.preventClicksPropagation&&v.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))},v.onClickNext=function(e){e.preventDefault(),(!v.isEnd||v.params.loop)&&v.slideNext()},v.onClickPrev=function(e){e.preventDefault(),(!v.isBeginning||v.params.loop)&&v.slidePrev()},v.onClickIndex=function(e){e.preventDefault();var t=a(this).index()*v.params.slidesPerGroup;v.params.loop&&(t+=v.loopedSlides),v.slideTo(t)},v.updateClickedSlide=function(e){var t=o(e,"."+v.params.slideClass),s=!1;if(t)for(var r=0;r<v.slides.length;r++)v.slides[r]===t&&(s=!0);if(!t||!s)return v.clickedSlide=void 0,void(v.clickedIndex=void 0);if(v.clickedSlide=t,v.clickedIndex=a(t).index(),v.params.slideToClickedSlide&&void 0!==v.clickedIndex&&v.clickedIndex!==v.activeIndex){var i,n=v.clickedIndex;if(v.params.loop)if(i=a(v.clickedSlide).attr("data-swiper-slide-index"),n>v.slides.length-v.params.slidesPerView)v.fixLoop(),n=v.wrapper.children("."+v.params.slideClass+'[data-swiper-slide-index="'+i+'"]').eq(0).index(),setTimeout(function(){v.slideTo(n)},0);else if(n<v.params.slidesPerView-1){v.fixLoop();var l=v.wrapper.children("."+v.params.slideClass+'[data-swiper-slide-index="'+i+'"]');n=l.eq(l.length-1).index(),setTimeout(function(){v.slideTo(n)},0)}else v.slideTo(n);else v.slideTo(n)}};var y,x,b,T,S,C,M,P,z,I="input, select, textarea, button",E=Date.now(),k=[];v.animating=!1,v.touches={startX:0,startY:0,currentX:0,currentY:0,diff:0};var D,G;if(v.onTouchStart=function(e){if(e.originalEvent&&(e=e.originalEvent),D="touchstart"===e.type,D||!("which"in e)||3!==e.which){if(v.params.noSwiping&&o(e,"."+v.params.noSwipingClass))return void(v.allowClick=!0);if(!v.params.swipeHandler||o(e,v.params.swipeHandler)){var t=v.touches.currentX="touchstart"===e.type?e.targetTouches[0].pageX:e.pageX,s=v.touches.currentY="touchstart"===e.type?e.targetTouches[0].pageY:e.pageY;if(!(v.device.ios&&v.params.iOSEdgeSwipeDetection&&t<=v.params.iOSEdgeSwipeThreshold)){if(y=!0,x=!1,T=void 0,G=void 0,v.touches.startX=t,v.touches.startY=s,b=Date.now(),v.allowClick=!0,v.updateContainerSize(),v.swipeDirection=void 0,v.params.threshold>0&&(M=!1),"touchstart"!==e.type){var r=!0;a(e.target).is(I)&&(r=!1),document.activeElement&&a(document.activeElement).is(I)&&document.activeElement.blur(),r&&e.preventDefault()}v.emit("onTouchStart",v,e)}}}},v.onTouchMove=function(e){if(e.originalEvent&&(e=e.originalEvent),!(D&&"mousemove"===e.type||e.preventedByNestedSwiper)){if(v.params.onlyExternal)return v.allowClick=!1,void(y&&(v.touches.startX=v.touches.currentX="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,v.touches.startY=v.touches.currentY="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,b=Date.now()));if(D&&document.activeElement&&e.target===document.activeElement&&a(e.target).is(I))return x=!0,void(v.allowClick=!1);if(v.emit("onTouchMove",v,e),!(e.targetTouches&&e.targetTouches.length>1)){if(v.touches.currentX="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,v.touches.currentY="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,"undefined"==typeof T){var t=180*Math.atan2(Math.abs(v.touches.currentY-v.touches.startY),Math.abs(v.touches.currentX-v.touches.startX))/Math.PI;T=r()?t>v.params.touchAngle:90-t>v.params.touchAngle}if(T&&v.emit("onTouchMoveOpposite",v,e),"undefined"==typeof G&&v.browser.ieTouch&&(v.touches.currentX!==v.touches.startX||v.touches.currentY!==v.touches.startY)&&(G=!0),y){if(T)return void(y=!1);if(G||!v.browser.ieTouch){v.allowClick=!1,v.emit("onSliderMove",v,e),e.preventDefault(),v.params.touchMoveStopPropagation&&!v.params.nested&&e.stopPropagation(),x||(s.loop&&v.fixLoop(),C=v.getWrapperTranslate(),v.setWrapperTransition(0),v.animating&&v.wrapper.trigger("webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd"),v.params.autoplay&&v.autoplaying&&(v.params.autoplayDisableOnInteraction?v.stopAutoplay():v.pauseAutoplay()),z=!1,v.params.grabCursor&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grabbing",v.container[0].style.cursor="-moz-grabbin",v.container[0].style.cursor="grabbing")),x=!0;var i=v.touches.diff=r()?v.touches.currentX-v.touches.startX:v.touches.currentY-v.touches.startY;i*=v.params.touchRatio,v.rtl&&(i=-i),v.swipeDirection=i>0?"prev":"next",S=i+C;var n=!0;if(i>0&&S>v.minTranslate()?(n=!1,v.params.resistance&&(S=v.minTranslate()-1+Math.pow(-v.minTranslate()+C+i,v.params.resistanceRatio))):0>i&&S<v.maxTranslate()&&(n=!1,v.params.resistance&&(S=v.maxTranslate()+1-Math.pow(v.maxTranslate()-C-i,v.params.resistanceRatio))),n&&(e.preventedByNestedSwiper=!0),!v.params.allowSwipeToNext&&"next"===v.swipeDirection&&C>S&&(S=C),!v.params.allowSwipeToPrev&&"prev"===v.swipeDirection&&S>C&&(S=C),v.params.followFinger){if(v.params.threshold>0){if(!(Math.abs(i)>v.params.threshold||M))return void(S=C);if(!M)return M=!0,v.touches.startX=v.touches.currentX,v.touches.startY=v.touches.currentY,S=C,void(v.touches.diff=r()?v.touches.currentX-v.touches.startX:v.touches.currentY-v.touches.startY)}(v.params.freeMode||v.params.watchSlidesProgress)&&v.updateActiveIndex(),v.params.freeMode&&(0===k.length&&k.push({position:v.touches[r()?"startX":"startY"],time:b}),k.push({position:v.touches[r()?"currentX":"currentY"],time:(new window.Date).getTime()})),v.updateProgress(S),v.setWrapperTranslate(S)}}}}}},v.onTouchEnd=function(e){if(e.originalEvent&&(e=e.originalEvent),v.emit("onTouchEnd",v,e),y){v.params.grabCursor&&x&&y&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grab",v.container[0].style.cursor="-moz-grab",v.container[0].style.cursor="grab");var t=Date.now(),s=t-b;if(v.allowClick&&(v.updateClickedSlide(e),v.emit("onTap",v,e),300>s&&t-E>300&&(P&&clearTimeout(P),P=setTimeout(function(){v&&(v.params.paginationHide&&v.paginationContainer.length>0&&!a(e.target).hasClass(v.params.bulletClass)&&v.paginationContainer.toggleClass(v.params.paginationHiddenClass),v.emit("onClick",v,e))},300)),300>s&&300>t-E&&(P&&clearTimeout(P),v.emit("onDoubleTap",v,e))),E=Date.now(),setTimeout(function(){v&&(v.allowClick=!0)},0),!y||!x||!v.swipeDirection||0===v.touches.diff||S===C)return void(y=x=!1);y=x=!1;var r;if(r=v.params.followFinger?v.rtl?v.translate:-v.translate:-S,v.params.freeMode){if(r<-v.minTranslate())return void v.slideTo(v.activeIndex);if(r>-v.maxTranslate())return void v.slideTo(v.slides.length<v.snapGrid.length?v.snapGrid.length-1:v.slides.length-1);if(v.params.freeModeMomentum){if(k.length>1){var i=k.pop(),n=k.pop(),o=i.position-n.position,l=i.time-n.time;v.velocity=o/l,v.velocity=v.velocity/2,Math.abs(v.velocity)<.02&&(v.velocity=0),(l>150||(new window.Date).getTime()-i.time>300)&&(v.velocity=0)}else v.velocity=0;k.length=0;var p=1e3*v.params.freeModeMomentumRatio,d=v.velocity*p,u=v.translate+d;v.rtl&&(u=-u);var c,m=!1,f=20*Math.abs(v.velocity)*v.params.freeModeMomentumBounceRatio;if(u<v.maxTranslate())v.params.freeModeMomentumBounce?(u+v.maxTranslate()<-f&&(u=v.maxTranslate()-f),c=v.maxTranslate(),m=!0,z=!0):u=v.maxTranslate();else if(u>v.minTranslate())v.params.freeModeMomentumBounce?(u-v.minTranslate()>f&&(u=v.minTranslate()+f),c=v.minTranslate(),m=!0,z=!0):u=v.minTranslate();else if(v.params.freeModeSticky){var h,g=0;for(g=0;g<v.snapGrid.length;g+=1)if(v.snapGrid[g]>-u){h=g;break}u=Math.abs(v.snapGrid[h]-u)<Math.abs(v.snapGrid[h-1]-u)||"next"===v.swipeDirection?v.snapGrid[h]:v.snapGrid[h-1],v.rtl||(u=-u)}if(0!==v.velocity)p=Math.abs(v.rtl?(-u-v.translate)/v.velocity:(u-v.translate)/v.velocity);else if(v.params.freeModeSticky)return void v.slideReset();v.params.freeModeMomentumBounce&&m?(v.updateProgress(c),v.setWrapperTransition(p),v.setWrapperTranslate(u),v.onTransitionStart(),v.animating=!0,v.wrapper.transitionEnd(function(){v&&z&&(v.emit("onMomentumBounce",v),v.setWrapperTransition(v.params.speed),v.setWrapperTranslate(c),v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd()}))})):v.velocity?(v.updateProgress(u),v.setWrapperTransition(p),v.setWrapperTranslate(u),v.onTransitionStart(),v.animating||(v.animating=!0,v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd()}))):v.updateProgress(u),v.updateActiveIndex()}return void((!v.params.freeModeMomentum||s>=v.params.longSwipesMs)&&(v.updateProgress(),v.updateActiveIndex()))}var w,T=0,M=v.slidesSizesGrid[0];for(w=0;w<v.slidesGrid.length;w+=v.params.slidesPerGroup)"undefined"!=typeof v.slidesGrid[w+v.params.slidesPerGroup]?r>=v.slidesGrid[w]&&r<v.slidesGrid[w+v.params.slidesPerGroup]&&(T=w,M=v.slidesGrid[w+v.params.slidesPerGroup]-v.slidesGrid[w]):r>=v.slidesGrid[w]&&(T=w,M=v.slidesGrid[v.slidesGrid.length-1]-v.slidesGrid[v.slidesGrid.length-2]);var I=(r-v.slidesGrid[T])/M;if(s>v.params.longSwipesMs){if(!v.params.longSwipes)return void v.slideTo(v.activeIndex);"next"===v.swipeDirection&&v.slideTo(I>=v.params.longSwipesRatio?T+v.params.slidesPerGroup:T),"prev"===v.swipeDirection&&v.slideTo(I>1-v.params.longSwipesRatio?T+v.params.slidesPerGroup:T)}else{if(!v.params.shortSwipes)return void v.slideTo(v.activeIndex);"next"===v.swipeDirection&&v.slideTo(T+v.params.slidesPerGroup),"prev"===v.swipeDirection&&v.slideTo(T)}}},v._slideTo=function(e,a){return v.slideTo(e,a,!0,!0)},v.slideTo=function(e,a,t,s){"undefined"==typeof t&&(t=!0),"undefined"==typeof e&&(e=0),0>e&&(e=0),v.snapIndex=Math.floor(e/v.params.slidesPerGroup),v.snapIndex>=v.snapGrid.length&&(v.snapIndex=v.snapGrid.length-1);var i=-v.snapGrid[v.snapIndex];v.params.autoplay&&v.autoplaying&&(s||!v.params.autoplayDisableOnInteraction?v.pauseAutoplay(a):v.stopAutoplay()),v.updateProgress(i);for(var n=0;n<v.slidesGrid.length;n++)-Math.floor(100*i)>=Math.floor(100*v.slidesGrid[n])&&(e=n);if(!v.params.allowSwipeToNext&&i<v.translate&&i<v.minTranslate())return!1;if(!v.params.allowSwipeToPrev&&i>v.translate&&i>v.maxTranslate()&&(v.activeIndex||0)!==e)return!1;if("undefined"==typeof a&&(a=v.params.speed),v.previousIndex=v.activeIndex||0,v.activeIndex=e,i===v.translate)return v.updateClasses(),!1;v.updateClasses(),v.onTransitionStart(t);r()?i:0,r()?0:i;return 0===a?(v.setWrapperTransition(0),v.setWrapperTranslate(i),v.onTransitionEnd(t)):(v.setWrapperTransition(a),v.setWrapperTranslate(i),v.animating||(v.animating=!0,v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd(t)}))),!0},v.onTransitionStart=function(e){"undefined"==typeof e&&(e=!0), +v.lazy&&v.lazy.onTransitionStart(),e&&(v.emit("onTransitionStart",v),v.activeIndex!==v.previousIndex&&v.emit("onSlideChangeStart",v))},v.onTransitionEnd=function(e){v.animating=!1,v.setWrapperTransition(0),"undefined"==typeof e&&(e=!0),v.lazy&&v.lazy.onTransitionEnd(),e&&(v.emit("onTransitionEnd",v),v.activeIndex!==v.previousIndex&&v.emit("onSlideChangeEnd",v)),v.params.hashnav&&v.hashnav&&v.hashnav.setHash()},v.slideNext=function(e,a,t){if(v.params.loop){if(v.animating)return!1;v.fixLoop();{v.container[0].clientLeft}return v.slideTo(v.activeIndex+v.params.slidesPerGroup,a,e,t)}return v.slideTo(v.activeIndex+v.params.slidesPerGroup,a,e,t)},v._slideNext=function(e){return v.slideNext(!0,e,!0)},v.slidePrev=function(e,a,t){if(v.params.loop){if(v.animating)return!1;v.fixLoop();{v.container[0].clientLeft}return v.slideTo(v.activeIndex-1,a,e,t)}return v.slideTo(v.activeIndex-1,a,e,t)},v._slidePrev=function(e){return v.slidePrev(!0,e,!0)},v.slideReset=function(e,a,t){return v.slideTo(v.activeIndex,a,e)},v.setWrapperTransition=function(e,a){v.wrapper.transition(e),"slide"!==v.params.effect&&v.effects[v.params.effect]&&v.effects[v.params.effect].setTransition(e),v.params.parallax&&v.parallax&&v.parallax.setTransition(e),v.params.scrollbar&&v.scrollbar&&v.scrollbar.setTransition(e),v.params.control&&v.controller&&v.controller.setTransition(e,a),v.emit("onSetTransition",v,e)},v.setWrapperTranslate=function(e,a,t){var s=0,i=0,n=0;r()?s=v.rtl?-e:e:i=e,v.params.virtualTranslate||v.wrapper.transform(v.support.transforms3d?"translate3d("+s+"px, "+i+"px, "+n+"px)":"translate("+s+"px, "+i+"px)"),v.translate=r()?s:i,a&&v.updateActiveIndex(),"slide"!==v.params.effect&&v.effects[v.params.effect]&&v.effects[v.params.effect].setTranslate(v.translate),v.params.parallax&&v.parallax&&v.parallax.setTranslate(v.translate),v.params.scrollbar&&v.scrollbar&&v.scrollbar.setTranslate(v.translate),v.params.control&&v.controller&&v.controller.setTranslate(v.translate,t),v.emit("onSetTranslate",v,v.translate)},v.getTranslate=function(e,a){var t,s,r,i;return"undefined"==typeof a&&(a="x"),v.params.virtualTranslate?v.rtl?-v.translate:v.translate:(r=window.getComputedStyle(e,null),window.WebKitCSSMatrix?i=new window.WebKitCSSMatrix("none"===r.webkitTransform?"":r.webkitTransform):(i=r.MozTransform||r.OTransform||r.MsTransform||r.msTransform||r.transform||r.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),t=i.toString().split(",")),"x"===a&&(s=window.WebKitCSSMatrix?i.m41:parseFloat(16===t.length?t[12]:t[4])),"y"===a&&(s=window.WebKitCSSMatrix?i.m42:parseFloat(16===t.length?t[13]:t[5])),v.rtl&&s&&(s=-s),s||0)},v.getWrapperTranslate=function(e){return"undefined"==typeof e&&(e=r()?"x":"y"),v.getTranslate(v.wrapper[0],e)},v.observers=[],v.initObservers=function(){if(v.params.observeParents)for(var e=v.container.parents(),a=0;a<e.length;a++)l(e[a]);l(v.container[0],{childList:!1}),l(v.wrapper[0],{attributes:!1})},v.disconnectObservers=function(){for(var e=0;e<v.observers.length;e++)v.observers[e].disconnect();v.observers=[]},v.createLoop=function(){v.wrapper.children("."+v.params.slideClass+"."+v.params.slideDuplicateClass).remove();var e=v.wrapper.children("."+v.params.slideClass);"auto"!==v.params.slidesPerView||v.params.loopedSlides||(v.params.loopedSlides=e.length),v.loopedSlides=parseInt(v.params.loopedSlides||v.params.slidesPerView,10),v.loopedSlides=v.loopedSlides+v.params.loopAdditionalSlides,v.loopedSlides>e.length&&(v.loopedSlides=e.length);var t,s=[],r=[];for(e.each(function(t,i){var n=a(this);t<v.loopedSlides&&r.push(i),t<e.length&&t>=e.length-v.loopedSlides&&s.push(i),n.attr("data-swiper-slide-index",t)}),t=0;t<r.length;t++)v.wrapper.append(a(r[t].cloneNode(!0)).addClass(v.params.slideDuplicateClass));for(t=s.length-1;t>=0;t--)v.wrapper.prepend(a(s[t].cloneNode(!0)).addClass(v.params.slideDuplicateClass))},v.destroyLoop=function(){v.wrapper.children("."+v.params.slideClass+"."+v.params.slideDuplicateClass).remove(),v.slides.removeAttr("data-swiper-slide-index")},v.fixLoop=function(){var e;v.activeIndex<v.loopedSlides?(e=v.slides.length-3*v.loopedSlides+v.activeIndex,e+=v.loopedSlides,v.slideTo(e,0,!1,!0)):("auto"===v.params.slidesPerView&&v.activeIndex>=2*v.loopedSlides||v.activeIndex>v.slides.length-2*v.params.slidesPerView)&&(e=-v.slides.length+v.activeIndex+v.loopedSlides,e+=v.loopedSlides,v.slideTo(e,0,!1,!0))},v.appendSlide=function(e){if(v.params.loop&&v.destroyLoop(),"object"==typeof e&&e.length)for(var a=0;a<e.length;a++)e[a]&&v.wrapper.append(e[a]);else v.wrapper.append(e);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0)},v.prependSlide=function(e){v.params.loop&&v.destroyLoop();var a=v.activeIndex+1;if("object"==typeof e&&e.length){for(var t=0;t<e.length;t++)e[t]&&v.wrapper.prepend(e[t]);a=v.activeIndex+e.length}else v.wrapper.prepend(e);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0),v.slideTo(a,0,!1)},v.removeSlide=function(e){v.params.loop&&(v.destroyLoop(),v.slides=v.wrapper.children("."+v.params.slideClass));var a,t=v.activeIndex;if("object"==typeof e&&e.length){for(var s=0;s<e.length;s++)a=e[s],v.slides[a]&&v.slides.eq(a).remove(),t>a&&t--;t=Math.max(t,0)}else a=e,v.slides[a]&&v.slides.eq(a).remove(),t>a&&t--,t=Math.max(t,0);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0),v.params.loop?v.slideTo(t+v.loopedSlides,0,!1):v.slideTo(t,0,!1)},v.removeAllSlides=function(){for(var e=[],a=0;a<v.slides.length;a++)e.push(a);v.removeSlide(e)},v.effects={fade:{setTranslate:function(){for(var e=0;e<v.slides.length;e++){var a=v.slides.eq(e),t=a[0].swiperSlideOffset,s=-t;v.params.virtualTranslate||(s-=v.translate);var i=0;r()||(i=s,s=0);var n=v.params.fade.crossFade?Math.max(1-Math.abs(a[0].progress),0):1+Math.min(Math.max(a[0].progress,-1),0);a.css({opacity:n}).transform("translate3d("+s+"px, "+i+"px, 0px)")}},setTransition:function(e){if(v.slides.transition(e),v.params.virtualTranslate&&0!==e){var a=!1;v.slides.transitionEnd(function(){if(!a&&v){a=!0,v.animating=!1;for(var e=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],t=0;t<e.length;t++)v.wrapper.trigger(e[t])}})}}},cube:{setTranslate:function(){var e,t=0;v.params.cube.shadow&&(r()?(e=v.wrapper.find(".swiper-cube-shadow"),0===e.length&&(e=a('<div class="swiper-cube-shadow"></div>'),v.wrapper.append(e)),e.css({height:v.width+"px"})):(e=v.container.find(".swiper-cube-shadow"),0===e.length&&(e=a('<div class="swiper-cube-shadow"></div>'),v.container.append(e))));for(var s=0;s<v.slides.length;s++){var i=v.slides.eq(s),n=90*s,o=Math.floor(n/360);v.rtl&&(n=-n,o=Math.floor(-n/360));var l=Math.max(Math.min(i[0].progress,1),-1),p=0,d=0,u=0;s%4===0?(p=4*-o*v.size,u=0):(s-1)%4===0?(p=0,u=4*-o*v.size):(s-2)%4===0?(p=v.size+4*o*v.size,u=v.size):(s-3)%4===0&&(p=-v.size,u=3*v.size+4*v.size*o),v.rtl&&(p=-p),r()||(d=p,p=0);var c="rotateX("+(r()?0:-n)+"deg) rotateY("+(r()?n:0)+"deg) translate3d("+p+"px, "+d+"px, "+u+"px)";if(1>=l&&l>-1&&(t=90*s+90*l,v.rtl&&(t=90*-s-90*l)),i.transform(c),v.params.cube.slideShadows){var m=i.find(r()?".swiper-slide-shadow-left":".swiper-slide-shadow-top"),f=i.find(r()?".swiper-slide-shadow-right":".swiper-slide-shadow-bottom");0===m.length&&(m=a('<div class="swiper-slide-shadow-'+(r()?"left":"top")+'"></div>'),i.append(m)),0===f.length&&(f=a('<div class="swiper-slide-shadow-'+(r()?"right":"bottom")+'"></div>'),i.append(f));{i[0].progress}m.length&&(m[0].style.opacity=-i[0].progress),f.length&&(f[0].style.opacity=i[0].progress)}}if(v.wrapper.css({"-webkit-transform-origin":"50% 50% -"+v.size/2+"px","-moz-transform-origin":"50% 50% -"+v.size/2+"px","-ms-transform-origin":"50% 50% -"+v.size/2+"px","transform-origin":"50% 50% -"+v.size/2+"px"}),v.params.cube.shadow)if(r())e.transform("translate3d(0px, "+(v.width/2+v.params.cube.shadowOffset)+"px, "+-v.width/2+"px) rotateX(90deg) rotateZ(0deg) scale("+v.params.cube.shadowScale+")");else{var h=Math.abs(t)-90*Math.floor(Math.abs(t)/90),g=1.5-(Math.sin(2*h*Math.PI/360)/2+Math.cos(2*h*Math.PI/360)/2),w=v.params.cube.shadowScale,y=v.params.cube.shadowScale/g,x=v.params.cube.shadowOffset;e.transform("scale3d("+w+", 1, "+y+") translate3d(0px, "+(v.height/2+x)+"px, "+-v.height/2/y+"px) rotateX(-90deg)")}var b=v.isSafari||v.isUiWebView?-v.size/2:0;v.wrapper.transform("translate3d(0px,0,"+b+"px) rotateX("+(r()?0:t)+"deg) rotateY("+(r()?-t:0)+"deg)")},setTransition:function(e){v.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),v.params.cube.shadow&&!r()&&v.container.find(".swiper-cube-shadow").transition(e)}},coverflow:{setTranslate:function(){for(var e=v.translate,t=r()?-e+v.width/2:-e+v.height/2,s=r()?v.params.coverflow.rotate:-v.params.coverflow.rotate,i=v.params.coverflow.depth,n=0,o=v.slides.length;o>n;n++){var l=v.slides.eq(n),p=v.slidesSizesGrid[n],d=l[0].swiperSlideOffset,u=(t-d-p/2)/p*v.params.coverflow.modifier,c=r()?s*u:0,m=r()?0:s*u,f=-i*Math.abs(u),h=r()?0:v.params.coverflow.stretch*u,g=r()?v.params.coverflow.stretch*u:0;Math.abs(g)<.001&&(g=0),Math.abs(h)<.001&&(h=0),Math.abs(f)<.001&&(f=0),Math.abs(c)<.001&&(c=0),Math.abs(m)<.001&&(m=0);var w="translate3d("+g+"px,"+h+"px,"+f+"px) rotateX("+m+"deg) rotateY("+c+"deg)";if(l.transform(w),l[0].style.zIndex=-Math.abs(Math.round(u))+1,v.params.coverflow.slideShadows){var y=l.find(r()?".swiper-slide-shadow-left":".swiper-slide-shadow-top"),x=l.find(r()?".swiper-slide-shadow-right":".swiper-slide-shadow-bottom");0===y.length&&(y=a('<div class="swiper-slide-shadow-'+(r()?"left":"top")+'"></div>'),l.append(y)),0===x.length&&(x=a('<div class="swiper-slide-shadow-'+(r()?"right":"bottom")+'"></div>'),l.append(x)),y.length&&(y[0].style.opacity=u>0?u:0),x.length&&(x[0].style.opacity=-u>0?-u:0)}}if(v.browser.ie){var b=v.wrapper[0].style;b.perspectiveOrigin=t+"px 50%"}},setTransition:function(e){v.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}}},v.lazy={initialImageLoaded:!1,loadImageInSlide:function(e,t){if("undefined"!=typeof e&&("undefined"==typeof t&&(t=!0),0!==v.slides.length)){var s=v.slides.eq(e),r=s.find(".swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)");!s.hasClass("swiper-lazy")||s.hasClass("swiper-lazy-loaded")||s.hasClass("swiper-lazy-loading")||r.add(s[0]),0!==r.length&&r.each(function(){var e=a(this);e.addClass("swiper-lazy-loading");var r=e.attr("data-background"),i=e.attr("data-src");v.loadImage(e[0],i||r,!1,function(){if(r?(e.css("background-image","url("+r+")"),e.removeAttr("data-background")):(e.attr("src",i),e.removeAttr("data-src")),e.addClass("swiper-lazy-loaded").removeClass("swiper-lazy-loading"),s.find(".swiper-lazy-preloader, .preloader").remove(),v.params.loop&&t){var a=s.attr("data-swiper-slide-index");if(s.hasClass(v.params.slideDuplicateClass)){var n=v.wrapper.children('[data-swiper-slide-index="'+a+'"]:not(.'+v.params.slideDuplicateClass+")");v.lazy.loadImageInSlide(n.index(),!1)}else{var o=v.wrapper.children("."+v.params.slideDuplicateClass+'[data-swiper-slide-index="'+a+'"]');v.lazy.loadImageInSlide(o.index(),!1)}}v.emit("onLazyImageReady",v,s[0],e[0])}),v.emit("onLazyImageLoad",v,s[0],e[0])})}},load:function(){var e;if(v.params.watchSlidesVisibility)v.wrapper.children("."+v.params.slideVisibleClass).each(function(){v.lazy.loadImageInSlide(a(this).index())});else if(v.params.slidesPerView>1)for(e=v.activeIndex;e<v.activeIndex+v.params.slidesPerView;e++)v.slides[e]&&v.lazy.loadImageInSlide(e);else v.lazy.loadImageInSlide(v.activeIndex);if(v.params.lazyLoadingInPrevNext)if(v.params.slidesPerView>1){for(e=v.activeIndex+v.params.slidesPerView;e<v.activeIndex+v.params.slidesPerView+v.params.slidesPerView;e++)v.slides[e]&&v.lazy.loadImageInSlide(e);for(e=v.activeIndex-v.params.slidesPerView;e<v.activeIndex;e++)v.slides[e]&&v.lazy.loadImageInSlide(e)}else{var t=v.wrapper.children("."+v.params.slideNextClass);t.length>0&&v.lazy.loadImageInSlide(t.index());var s=v.wrapper.children("."+v.params.slidePrevClass);s.length>0&&v.lazy.loadImageInSlide(s.index())}},onTransitionStart:function(){v.params.lazyLoading&&(v.params.lazyLoadingOnTransitionStart||!v.params.lazyLoadingOnTransitionStart&&!v.lazy.initialImageLoaded)&&v.lazy.load()},onTransitionEnd:function(){v.params.lazyLoading&&!v.params.lazyLoadingOnTransitionStart&&v.lazy.load()}},v.scrollbar={set:function(){if(v.params.scrollbar){var e=v.scrollbar;e.track=a(v.params.scrollbar),e.drag=e.track.find(".swiper-scrollbar-drag"),0===e.drag.length&&(e.drag=a('<div class="swiper-scrollbar-drag"></div>'),e.track.append(e.drag)),e.drag[0].style.width="",e.drag[0].style.height="",e.trackSize=r()?e.track[0].offsetWidth:e.track[0].offsetHeight,e.divider=v.size/v.virtualSize,e.moveDivider=e.divider*(e.trackSize/v.size),e.dragSize=e.trackSize*e.divider,r()?e.drag[0].style.width=e.dragSize+"px":e.drag[0].style.height=e.dragSize+"px",e.track[0].style.display=e.divider>=1?"none":"",v.params.scrollbarHide&&(e.track[0].style.opacity=0)}},setTranslate:function(){if(v.params.scrollbar){var e,a=v.scrollbar,t=(v.translate||0,a.dragSize);e=(a.trackSize-a.dragSize)*v.progress,v.rtl&&r()?(e=-e,e>0?(t=a.dragSize-e,e=0):-e+a.dragSize>a.trackSize&&(t=a.trackSize+e)):0>e?(t=a.dragSize+e,e=0):e+a.dragSize>a.trackSize&&(t=a.trackSize-e),r()?(a.drag.transform(v.support.transforms3d?"translate3d("+e+"px, 0, 0)":"translateX("+e+"px)"),a.drag[0].style.width=t+"px"):(a.drag.transform(v.support.transforms3d?"translate3d(0px, "+e+"px, 0)":"translateY("+e+"px)"),a.drag[0].style.height=t+"px"),v.params.scrollbarHide&&(clearTimeout(a.timeout),a.track[0].style.opacity=1,a.timeout=setTimeout(function(){a.track[0].style.opacity=0,a.track.transition(400)},1e3))}},setTransition:function(e){v.params.scrollbar&&v.scrollbar.drag.transition(e)}},v.controller={LinearSpline:function(e,a){this.x=e,this.y=a,this.lastIndex=e.length-1;{var t,s;this.x.length}this.interpolate=function(e){return e?(s=r(this.x,e),t=s-1,(e-this.x[t])*(this.y[s]-this.y[t])/(this.x[s]-this.x[t])+this.y[t]):0};var r=function(){var e,a,t;return function(s,r){for(a=-1,e=s.length;e-a>1;)s[t=e+a>>1]<=r?a=t:e=t;return e}}()},getInterpolateFunction:function(e){v.controller.spline||(v.controller.spline=v.params.loop?new v.controller.LinearSpline(v.slidesGrid,e.slidesGrid):new v.controller.LinearSpline(v.snapGrid,e.snapGrid))},setTranslate:function(e,a){function s(a){e=a.rtl&&"horizontal"===a.params.direction?-v.translate:v.translate,"slide"===v.params.controlBy&&(v.controller.getInterpolateFunction(a),i=-v.controller.spline.interpolate(-e)),i&&"container"!==v.params.controlBy||(r=(a.maxTranslate()-a.minTranslate())/(v.maxTranslate()-v.minTranslate()),i=(e-v.minTranslate())*r+a.minTranslate()),v.params.controlInverse&&(i=a.maxTranslate()-i),a.updateProgress(i),a.setWrapperTranslate(i,!1,v),a.updateActiveIndex()}var r,i,n=v.params.control;if(v.isArray(n))for(var o=0;o<n.length;o++)n[o]!==a&&n[o]instanceof t&&s(n[o]);else n instanceof t&&a!==n&&s(n)},setTransition:function(e,a){function s(a){a.setWrapperTransition(e,v),0!==e&&(a.onTransitionStart(),a.wrapper.transitionEnd(function(){i&&(a.params.loop&&"slide"===v.params.controlBy&&a.fixLoop(),a.onTransitionEnd())}))}var r,i=v.params.control;if(v.isArray(i))for(r=0;r<i.length;r++)i[r]!==a&&i[r]instanceof t&&s(i[r]);else i instanceof t&&a!==i&&s(i)}},v.hashnav={init:function(){if(v.params.hashnav){v.hashnav.initialized=!0;var e=document.location.hash.replace("#","");if(e)for(var a=0,t=0,s=v.slides.length;s>t;t++){var r=v.slides.eq(t),i=r.attr("data-hash");if(i===e&&!r.hasClass(v.params.slideDuplicateClass)){var n=r.index();v.slideTo(n,a,v.params.runCallbacksOnInit,!0)}}}},setHash:function(){v.hashnav.initialized&&v.params.hashnav&&(document.location.hash=v.slides.eq(v.activeIndex).attr("data-hash")||"")}},v.disableKeyboardControl=function(){a(document).off("keydown",p)},v.enableKeyboardControl=function(){a(document).on("keydown",p)},v.mousewheel={event:!1,lastScrollTime:(new window.Date).getTime()},v.params.mousewheelControl){try{new window.WheelEvent("wheel"),v.mousewheel.event="wheel"}catch(L){}v.mousewheel.event||void 0===document.onmousewheel||(v.mousewheel.event="mousewheel"),v.mousewheel.event||(v.mousewheel.event="DOMMouseScroll")}v.disableMousewheelControl=function(){return v.mousewheel.event?(v.container.off(v.mousewheel.event,d),!0):!1},v.enableMousewheelControl=function(){return v.mousewheel.event?(v.container.on(v.mousewheel.event,d),!0):!1},v.parallax={setTranslate:function(){v.container.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){u(this,v.progress)}),v.slides.each(function(){var e=a(this);e.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var a=Math.min(Math.max(e[0].progress,-1),1);u(this,a)})})},setTransition:function(e){"undefined"==typeof e&&(e=v.params.speed),v.container.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var t=a(this),s=parseInt(t.attr("data-swiper-parallax-duration"),10)||e;0===e&&(s=0),t.transition(s)})}},v._plugins=[];for(var B in v.plugins){var O=v.plugins[B](v,v.params[B]);O&&v._plugins.push(O)}return v.callPlugins=function(e){for(var a=0;a<v._plugins.length;a++)e in v._plugins[a]&&v._plugins[a][e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},v.emitterEventListeners={},v.emit=function(e){v.params[e]&&v.params[e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);var a;if(v.emitterEventListeners[e])for(a=0;a<v.emitterEventListeners[e].length;a++)v.emitterEventListeners[e][a](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);v.callPlugins&&v.callPlugins(e,arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},v.on=function(e,a){return e=c(e),v.emitterEventListeners[e]||(v.emitterEventListeners[e]=[]),v.emitterEventListeners[e].push(a),v},v.off=function(e,a){var t;if(e=c(e),"undefined"==typeof a)return v.emitterEventListeners[e]=[],v;if(v.emitterEventListeners[e]&&0!==v.emitterEventListeners[e].length){for(t=0;t<v.emitterEventListeners[e].length;t++)v.emitterEventListeners[e][t]===a&&v.emitterEventListeners[e].splice(t,1);return v}},v.once=function(e,a){e=c(e);var t=function(){a(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]),v.off(e,t)};return v.on(e,t),v},v.a11y={makeFocusable:function(e){return e.attr("tabIndex","0"),e},addRole:function(e,a){return e.attr("role",a),e},addLabel:function(e,a){return e.attr("aria-label",a),e},disable:function(e){return e.attr("aria-disabled",!0),e},enable:function(e){return e.attr("aria-disabled",!1),e},onEnterKey:function(e){13===e.keyCode&&(a(e.target).is(v.params.nextButton)?(v.onClickNext(e),v.a11y.notify(v.isEnd?v.params.lastSlideMessage:v.params.nextSlideMessage)):a(e.target).is(v.params.prevButton)&&(v.onClickPrev(e),v.a11y.notify(v.isBeginning?v.params.firstSlideMessage:v.params.prevSlideMessage)),a(e.target).is("."+v.params.bulletClass)&&a(e.target)[0].click())},liveRegion:a('<span class="swiper-notification" aria-live="assertive" aria-atomic="true"></span>'),notify:function(e){var a=v.a11y.liveRegion;0!==a.length&&(a.html(""),a.html(e))},init:function(){if(v.params.nextButton){var e=a(v.params.nextButton);v.a11y.makeFocusable(e),v.a11y.addRole(e,"button"),v.a11y.addLabel(e,v.params.nextSlideMessage)}if(v.params.prevButton){var t=a(v.params.prevButton);v.a11y.makeFocusable(t),v.a11y.addRole(t,"button"),v.a11y.addLabel(t,v.params.prevSlideMessage)}a(v.container).append(v.a11y.liveRegion)},initPagination:function(){v.params.pagination&&v.params.paginationClickable&&v.bullets&&v.bullets.length&&v.bullets.each(function(){var e=a(this);v.a11y.makeFocusable(e),v.a11y.addRole(e,"button"),v.a11y.addLabel(e,v.params.paginationBulletMessage.replace(/{{index}}/,e.index()+1))})},destroy:function(){v.a11y.liveRegion&&v.a11y.liveRegion.length>0&&v.a11y.liveRegion.remove()}},v.init=function(){v.params.loop&&v.createLoop(),v.updateContainerSize(),v.updateSlidesSize(),v.updatePagination(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),"slide"!==v.params.effect&&v.effects[v.params.effect]&&(v.params.loop||v.updateProgress(),v.effects[v.params.effect].setTranslate()),v.params.loop?v.slideTo(v.params.initialSlide+v.loopedSlides,0,v.params.runCallbacksOnInit):(v.slideTo(v.params.initialSlide,0,v.params.runCallbacksOnInit),0===v.params.initialSlide&&(v.parallax&&v.params.parallax&&v.parallax.setTranslate(),v.lazy&&v.params.lazyLoading&&(v.lazy.load(),v.lazy.initialImageLoaded=!0))),v.attachEvents(),v.params.observer&&v.support.observer&&v.initObservers(),v.params.preloadImages&&!v.params.lazyLoading&&v.preloadImages(),v.params.autoplay&&v.startAutoplay(),v.params.keyboardControl&&v.enableKeyboardControl&&v.enableKeyboardControl(),v.params.mousewheelControl&&v.enableMousewheelControl&&v.enableMousewheelControl(),v.params.hashnav&&v.hashnav&&v.hashnav.init(),v.params.a11y&&v.a11y&&v.a11y.init(),v.emit("onInit",v)},v.cleanupStyles=function(){v.container.removeClass(v.classNames.join(" ")).removeAttr("style"),v.wrapper.removeAttr("style"),v.slides&&v.slides.length&&v.slides.removeClass([v.params.slideVisibleClass,v.params.slideActiveClass,v.params.slideNextClass,v.params.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-column").removeAttr("data-swiper-row"),v.paginationContainer&&v.paginationContainer.length&&v.paginationContainer.removeClass(v.params.paginationHiddenClass),v.bullets&&v.bullets.length&&v.bullets.removeClass(v.params.bulletActiveClass),v.params.prevButton&&a(v.params.prevButton).removeClass(v.params.buttonDisabledClass),v.params.nextButton&&a(v.params.nextButton).removeClass(v.params.buttonDisabledClass),v.params.scrollbar&&v.scrollbar&&(v.scrollbar.track&&v.scrollbar.track.length&&v.scrollbar.track.removeAttr("style"),v.scrollbar.drag&&v.scrollbar.drag.length&&v.scrollbar.drag.removeAttr("style"))},v.destroy=function(e,a){v.detachEvents(),v.stopAutoplay(),v.params.loop&&v.destroyLoop(),a&&v.cleanupStyles(),v.disconnectObservers(),v.params.keyboardControl&&v.disableKeyboardControl&&v.disableKeyboardControl(),v.params.mousewheelControl&&v.disableMousewheelControl&&v.disableMousewheelControl(),v.params.a11y&&v.a11y&&v.a11y.destroy(),v.emit("onDestroy"),e!==!1&&(v=null)},v.init(),v}};t.prototype={isSafari:function(){var e=navigator.userAgent.toLowerCase();return e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0}(),isUiWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),isArray:function(e){return"[object Array]"===Object.prototype.toString.apply(e)},browser:{ie:window.navigator.pointerEnabled||window.navigator.msPointerEnabled,ieTouch:window.navigator.msPointerEnabled&&window.navigator.msMaxTouchPoints>1||window.navigator.pointerEnabled&&window.navigator.maxTouchPoints>1},device:function(){var e=navigator.userAgent,a=e.match(/(Android);?[\s\/]+([\d.]+)?/),t=e.match(/(iPad).*OS\s([\d_]+)/),s=e.match(/(iPod)(.*OS\s([\d_]+))?/),r=!t&&e.match(/(iPhone\sOS)\s([\d_]+)/);return{ios:t||r||s,android:a}}(),support:{touch:window.Modernizr&&Modernizr.touch===!0||function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)}(),transforms3d:window.Modernizr&&Modernizr.csstransforms3d===!0||function(){var e=document.createElement("div").style;return"webkitPerspective"in e||"MozPerspective"in e||"OPerspective"in e||"MsPerspective"in e||"perspective"in e}(),flexbox:function(){for(var e=document.createElement("div").style,a="alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient".split(" "),t=0;t<a.length;t++)if(a[t]in e)return!0}(),observer:function(){return"MutationObserver"in window||"WebkitMutationObserver"in window}()},plugins:{}};for(var s=["jQuery","Zepto","Dom7"],r=0;r<s.length;r++)window[s[r]]&&e(window[s[r]]);var i;i="undefined"==typeof Dom7?window.Dom7||window.Zepto||window.jQuery:Dom7,i&&("transitionEnd"in i.fn||(i.fn.transitionEnd=function(e){function a(i){if(i.target===this)for(e.call(this,i),t=0;t<s.length;t++)r.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],r=this;if(e)for(t=0;t<s.length;t++)r.on(s[t],a);return this}),"transform"in i.fn||(i.fn.transform=function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this}),"transition"in i.fn||(i.fn.transition=function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this})),window.Swiper=t}(),"undefined"!=typeof module?module.exports=window.Swiper:"function"==typeof define&&define.amd&&define([],function(){"use strict";return window.Swiper}); diff --git a/hyhproject/mobile2/view/default/juhui.html b/hyhproject/mobile2/view/default/juhui.html new file mode 100755 index 0000000..2041772 --- /dev/null +++ b/hyhproject/mobile2/view/default/juhui.html @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="UTF-8"> + <title></title> + <script src="__MOBILE__/js/common_xs.js" type="text/javascript" charset="utf-8"></script> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/global-lxy.css" /> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/juhui.css" /> + </head> + + <body> + <div class="header"> + <p> + 钜惠 + </p> + </div> + + <div class="nav clearfix"> + <div class="nav_a on" id="guanzhu"> + <p>关注动态</p> + </div> + <div class="nav_a" id="shangxin"> + <p>商品上新</p> + </div> + <div class="nav_a" id="haohuo"> + <p>精选好货</p> + </div> + </div> + + <div class="guanzhu1"> + <div class="gz_dpmc clearfix"> + <img src="__MOBILE__/img/QQ20170814092939.jpg" /> + <p class="gz_p1">店铺名称</p> + <p class="gz_p2">1小时前</p> + </div> + <div class="gz_nr"> + <p>一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十</p> + </div> + <div class="zan clearfix"> + <img src="__MOBILE__/img/eye.png" class="eye" /> + <p class="eye_p">999</p> + <div class="damuzhi"> + <img src="__MOBILE__/img/zan2.png" /> + <p>1</p> + </div> + </div> + </div> + + + <div class="shangxin1" style="display: none;"> + <div class="sx_dpmc clearfix"> + <img src="__MOBILE__/img/QQ20170814092939.jpg" /> + <p class="sx_p1">店铺名称</p> + <p class="sx_p2">1小时前</p> + </div> + + <div class="sx_sp clearfix"> + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + + <div class="sx_spnr"> + <!--<img src="__MOBILE__/img/QQ20170814092939.jpg"/>--> + </div> + </div> + + <div class="zan clearfix"> + <img src="__MOBILE__/img/eye.png" class="eye" /> + <p class="eye_p">999</p> + <div class="damuzhi"> + <img src="__MOBILE__/img/zan2.png" /> + <p>1</p> + </div> + </div> + </div> + + <div class="haohuo1" style="display: none;">45</div> + </body> + <script src="__MOBILE__/js/jquery.min.js" type="text/javascript" charset="utf-8"></script> + <script type="text/javascript"> + $('.nav').on('click', '.nav_a', function() { + var nav_b = $(this).attr('id') + console.log(nav_b) + + $(this).addClass('on').siblings().removeClass('on'); + + if(nav_b == 'guanzhu') { + $('.guanzhu1').css('display', 'block'); + $('.shangxin1').css('display', 'none'); + $('.haohuo1').css('display', 'none'); + if($('.guanzhu1').html() == '') { + + $.ajax({ + type: "post", + url: "", + async: true, + data: {}, + dataType: 'json', + success: function() { + var html = ''; + $('.guanzhu1').html(html) + } + }); + } + } else if(nav_b == 'shangxin') { + $('.guanzhu1').css('display', 'none'); + $('.shangxin1').css('display', 'block'); + $('.haohuo1').css('display', 'none'); + if($('.shangxin1').html() == '') { + + $.ajax({ + type: "post", + url: "", + async: true, + data: {}, + dataType: 'json', + success: function() { + var html = ''; + $('.shangxin1').html(html) + } + }); + } + } else if(nav_b == 'haohuo') { + $('.guanzhu1').css('display', 'none'); + $('.shangxin1').css('display', 'none'); + $('.haohuo1').css('display', 'block'); + if($('.haohuo1').html() == '') { + + $.ajax({ + type: "post", + url: "", + async: true, + data: {}, + dataType: 'json', + success: function() { + var html = ''; + $('.haohuo1').html(html) + } + }); + } + } + + }) + </script> + +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/login.html b/hyhproject/mobile2/view/default/login.html new file mode 100755 index 0000000..be7fbba --- /dev/null +++ b/hyhproject/mobile2/view/default/login.html @@ -0,0 +1,48 @@ +{extend name="default/base" /} +{block name="title"}登录 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="location.href='{:url('mobile/index/index')}'"></i><h1 id="login-w">登录</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> +{/block} +{block name="main"} + {/* 登录页面 */} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container" id="login1"> + <div class="wst-lo-frame"> + <div class="frame"><input id="loginName" type="text" placeholder="邮箱/用户名/手机号"></div> + <div class="frame"><input id="loginPwd" type="password" placeholder="密码"></div> + <!--<div class="verify"> + <input id="loginVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg1' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg1")'> + </div>--> + </div> + <div class="wst-lo-button"> + <button id="loginButton" class="button" onclick="javascript:login();">登录</button> + </div> + <ul class="ui-row wst-lo-term"> + <li class="ui-col ui-col-50"><a href="{:url('mobile/users/toRegister')}" class="term">注册新账号</a></li> + <li class="ui-col ui-col-50" style="text-align:right;"><a href="{:url('mobile/users/forgetpass')}" class="term">忘记密码</a></li> + </ul> + {:hook('mobileDocumentLogin')} + </section> + {/* 登录页面end */} +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/login.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/rebate.html b/hyhproject/mobile2/view/default/rebate.html new file mode 100755 index 0000000..054478e --- /dev/null +++ b/hyhproject/mobile2/view/default/rebate.html @@ -0,0 +1,112 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="UTF-8"> + <title></title> + <script src="__MOBILE__/js/common_xs.js" type="text/javascript" charset="utf-8"></script> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/global-lxy.css" /> + <link rel="stylesheet" type="text/css" href="__MOBILE__/css/rebate.css" /> + </head> + + <body> + <div class="banner"> + <img src="__MOBILE__/img/zk_banner.png" /> + </div> + + <div class="youhui"> + <div class="yhq clearfix"> + <div class="yhq_block"> + <img src="__MOBILE__/img/youhuiquan1.png" /> + <div class="yhq_btn">立即领取</div> + </div> + <div class="yhq_block"> + <img src="__MOBILE__/img/youhuiquan1.png" /> + <div class="yhq_btn">立即领取</div> + </div> + <div class="yhq_block"> + <img src="__MOBILE__/img/youhuiquan1.png" /> + <div class="yhq_btn">立即领取</div> + </div> + <div class="yhq_block"> + <img src="__MOBILE__/img/youhuiquan1.png" /> + <div class="yhq_btn">立即领取</div> + </div> + </div> + + <div class="miaosha clearfix"> + <div class="mssp"> + <img src="__MOBILE__/img/shangpin1.png" /> + </div> + + <div class="zdms"> + <p class="ms_p1">整点秒杀&nbsp;20&nbsp;:&nbsp;00</p> + <p class="ms_p2">提前加购&nbsp;快人一步</p> + <img src="__MOBILE__/img/jiagou.png" /> + </div> + </div> + </div> + + <div class="hengfu"> + <img src="__MOBILE__/img/shaung11jianianhua.png" /> + </div> + + <div class="bktj"> + <img src="__MOBILE__/img/bktj.png" /> + </div> + + <div class="bk_cp"> + <div class="bk_cp1 clearfix"> + <img src="__MOBILE__/img/shangpin1.png" class="bk_img1"/> + <p class="bk_p1">产品名称</p> + <p class="bk_p2">折扣到手价</p> + <p class="bk_p3">¥&nbsp;.2999</p> + <img src="__MOBILE__/img/qianggou.png"/ class="bk_img2"> + </div> + + <div class="bk_cp2 clearfix"> + <p class="bk2_p1">产品名称</p> + <p class="bk2_p2">折扣到手价</p> + <p class="bk2_p3">¥&nbsp;.2999</p> + <img src="__MOBILE__/img/qianggou.png"/ class="bk_img2"> + <img src="__MOBILE__/img/shangpin1.png" class="bk_img1"/> + </div> + + <div class="bk_cp3 clearfix"> + <img src="__MOBILE__/img/shangpin1.png" class="bk_img1"/> + <p class="bk_p1">产品名称</p> + <p class="bk_p2">折扣到手价</p> + <p class="bk_p3">¥&nbsp;.2999</p> + <img src="__MOBILE__/img/qianggou.png"/ class="bk_img2"> + </div> + + <div class="bk_cp4"> + <p class="bk2_p1">产品名称</p> + <p class="bk2_p2">折扣到手价</p> + <p class="bk2_p3">¥&nbsp;.2999</p> + <img src="__MOBILE__/img/qianggou.png"/ class="bk_img2"> + <img src="__MOBILE__/img/shangpin1.png" class="bk_img1"/> + </div> + </div> + + <div class="xpss"> + <img src="__MOBILE__/img/xinpinshangshi.png"/> + </div> + + <div class="xpss_nr clearfix"> + <div class="xp_cp"> + <img src="__MOBILE__/img/shangpin1.png"/ class="xpss_img1"> + <p class="xpss_p1"><del>原价2199</del>1999.00</p> + <img src="__MOBILE__/img/ljqg.png"/ class="xpss_img2"> + </div> + <div class="xp_cp"> + <img src="__MOBILE__/img/shangpin1.png"/ class="xpss_img1"> + <p class="xpss_p1"><del>原价2199</del>1999.00</p> + <img src="__MOBILE__/img/ljqg.png"/ class="xpss_img2"> + </div> + </div> + + </body> + <script src="__MOBILE__/js/jquery.min.js" type="text/javascript" charset="utf-8"></script> + +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/reg.html b/hyhproject/mobile2/view/default/reg.html new file mode 100755 index 0000000..489a248 --- /dev/null +++ b/hyhproject/mobile2/view/default/reg.html @@ -0,0 +1,139 @@ +{extend name="default/base" /} +{block name="title"}注册 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <h1 id="login-w">注册</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> +{/block} +{block name="main"} + {/* 注册页面 */} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container" id="login0"> + <div class="wst-lo-frame"> + <div class="frame"><input id="regName" type="text" placeholder="手机号" onkeyup="javascript:onTesting(this)"></div> + {/* 获取验证码 prompt */} + <div class="verify phone"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" class="ui-btn ui-btn-primary" onclick="javascript:obtainCode()">获取验证码</button> + </div> + <!-- <div class="verify phone"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id="verifyImg3" src="/mobile/users/getverify.html" onclick="javascript:WST.getVerify(&quot;#verifyImg3&quot;)"> + </div> --> + <div class="frame"><input id="regPwd" type="password" placeholder="密码"></div> + <div class="frame"><input id="regcoPwd" type="password" placeholder="确认密码"></div> + <div class="verify phone"> + 分享人:<input id="pName" type="readonly" placeholder="请输入分享人" maxlength="30"> + </div> + + </div> + <div class="wst-lo-agreement"> + <i id="defaults" class="ui-icon-chooses ui-icon-success-block wst-active" onclick="javascript:inAgree(this)"></i>我已阅读并同意<span onclick="javascript:wholeShow('protocol');">《用户注册协议》</span> + </div> + <div class="wst-lo-button"> + <button id="regButton" class="button" onclick="javascript:register();">注册</button> + </div> + + </section> +{/block} +{block name="include"} +{/* 用户注册协议 */} +<div class="wst-fr-protocol" id="protocol"> + <div class="title"><span>用户注册协议</span><i class="ui-icon-close-page" onclick="javascript:wholeHide('protocol');"></i><div class="wst-clear"></div></div> + <div class="content"> + +<h4><span>{:WSTConf('CONF.mallName')}</span>用户注册协议</h4> +<p>本协议是您与<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有者之间就<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站服务等相关事宜所订立的契约,请您仔细阅读本注册协议,您点击"同意并继续"按钮后,本协议即构成对双方有约束力的法律文件。</p> +<h4>第1条 本站服务条款的确认和接纳</h4> +<p><strong>1.1</strong>本站的各项电子服务的所有权和运作权归<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有。用户同意所有注册协议条款并完成注册程序,才能成为本站的正式用户。用户确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。<p></p> +<p><strong>1.2</strong>用户点击同意本协议的,即视为用户确认自己具有享受本站服务、下单购物等相应的权利能力和行为能力,能够独立承担法律责任。</p> +<p><strong>1.3</strong>如果您在18周岁以下,您只能在父母或监护人的监护参与下才能使用本站。<p> +<p><strong>1.4</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留在中华人民共和国大陆地区法施行之法律允许的范围内独自决定拒绝服务、关闭用户账户、清除或编辑内容或取消订单的权利。</p> +<h4>第2条 本站服务</h4> +<p><strong>2.1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>通过互联网依法为用户提供互联网信息等服务,用户在完全同意本协议及本站规定的情况下,方有权使用本站的相关服务。</p> +<p><strong>2.2</strong>用户必须自行准备如下设备和承担如下开支:</p> +<p>(1)上网设备,包括并不限于电脑或者其他上网终端、调制解调器及其他必备的上网装置;</p> +<p>(2)上网开支,包括并不限于网络接入费、上网设备租用费、手机流量费等。</p> +<h4>第3条 用户信息</h4> +<p><strong>3.1</strong>用户应自行诚信向本站提供注册资料,用户同意其提供的注册资料真实、准确、完整、合法有效,用户注册资料如有变动的,应及时更新其注册资料。如果用户提供的注册资料不合法、不真实、不准确、不详尽的,用户需承担因此引起的相应责任及后果,并且<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留终止用户使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>各项服务的权利。</p> +<p><strong>3.2</strong>用户在本站进行浏览、下单购物等活动时,涉及用户真实姓名/名称、通信地址、联系电话、电子邮箱等隐私信息的,本站将予以严格保密,除非得到用户的授权或法律另有规定,本站不会向外界披露用户隐私信息。</p> +<p><strong>3.3</strong>用户注册成功后,将产生用户名和密码等账户信息,您可以根据本站规定改变您的密码。用户应谨慎合理的保存、使用其用户名和密码。用户若发现任何非法使用用户账号或存在安全漏洞的情况,请立即通知本站并向公安机关报案。</p> +<p><strong>3.4</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>拥有通过邮件、短信电话等形式,向在本站注册、购物用户、收货人发送订单信息、促销活动等告知信息的权利。</p> +<p><strong>3.5</strong>用户不得将在本站注册获得的账户借给他人使用,否则用户应承担由此产生的全部责任,并与实际使用人承担连带责任。</p> +<p><strong>3.6</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权使用用户的注册信息、用户名、密码等信息,登录进入用户的注册账户,进行证据保全,包括但不限于公证、见证等。</p> +<h4>第4条 用户依法言行义务</h4> +<p>本协议依据国家相关法律法规规章制定,用户同意严格遵守以下义务:</p> +<p>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</p> +<p>(2)从中国大陆向境外传输资料信息时必须符合中国有关法规;</p> +<p>(3)不得利用本站从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动;</p> +<p>(4)不得干扰本站的正常运转,不得侵入本站及国家计算机信息系统;</p> +<p>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽的、不文明的等信息资料;</p> +<p>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</p> +<p>(7)不得教唆他人从事本条所禁止的行为;</p> +<p>(8)不得利用在本站注册的账户进行牟利性经营活动;</p> +<p>(9)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容;</p> +<p>用户应不时关注并遵守本站不时公布或修改的各类合法规则规定。</p> +<p>本站保有删除站内各类不符合法律政策或不真实的信息内容而无须通知用户的权利。</p> +<p>若用户未遵守以上规定的,本站有权作出独立判断并采取暂停或关闭用户帐号等措施。用户须对自己在网上的言论和行为承担法律责任。</p> +<h4>第5条 店铺义务</h4> +<p><strong>5.1</strong>店铺经营者可通过本站申请店铺,发布全新或二手商品及/或服务信息并与其他用户达成交易,但必须保证商品信息真实。如有发现商品假冒或者其他违反国家法律规定的商品,本站有权对商品进行禁售。</p> +<p><strong>5.2</strong>若店铺经营者发生改变,店铺经营者需及时联系本站进行信息的变更,若未及时联系本站而导致消费者与原店铺经营者产生交易纠纷或者违法国家规定的事情,本站不负任何连带责任。</p> +<p><strong>5.3</strong>店铺经营者有权通过使用店铺设置短暂关停店铺,但店铺经营者应当对自己店铺关停前已达成的交易继续承担发货、退换货及质保维修、维权投诉处理等交易保障责任。</p> +<p><strong>5.4</strong>店铺经营者如有不实交易信息或者违反国家相关法律的行为,本站有权对店铺进行关停,并对关停期间所产生的损失不负任何责任。</p> +<p>依据上述约定关停店铺均不会影响您已经累积的信用。</p> +</p> +<h4>第6条 商品信息</h4> +<p>本站上的商品价格、数量、是否有货等商品信息随时都有可能发生变动,本站不作特别通知。由于网站上商品信息的数量极其庞大,虽然本站会尽最大努力保证您所浏览商品信息的准确性,但由于众所周知的互联网技术因素等客观原因存在,本站网页显示的信息可能会有一定的滞后性或差错,对此情形您知悉并理解;<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>欢迎纠错,并会视情况给予纠错者一定的奖励。</p> +<p>为表述便利,商品和服务简称为"商品"或"货物"。</p> +<h4>第7条 订单</h4> +<p><strong>7.1</strong>在您下订单时,请您仔细确认所购商品的名称、价格、数量、规格、联系地址、电话、收货人等信息。收货人与用户本人不一致的,收货人的行为和意思表示视为用户的行为和意思表示,用户应对收货人的行为及意思表示的法律后果承担连带责任。</p> +<p><strong>7.2</strong>除法律另有强制性规定外,双方约定如下:本站上销售方展示的商品和价格等信息仅仅是要约邀请,您下单时须填写您希望购买的商品数量、价款及支付方式、收货人、联系方式、收货地址(合同履行地点)、合同履行方式等内容;系统生成的订单信息是计算机信息系统根据您填写的内容自动生成的数据,仅是您向销售方发出的合同要约;销售方收到您的订单信息后,只有在销售方将您在订单中订购的商品从仓库实际直接向您发出时( 以商品出库为标志),方视为您与销售方之间就实际直接向您发出的商品建立了合同关系;如果您在一份订单里订购了多种商品并且销售方只给您发出了部分商品时,您与销售方之间仅就实际直接向您发出的商品建立了合同关系;只有在销售方实际直接向您发出了订单中订购的其他商品时,您和销售方之间就订单中该其他已实际直接向您发出的商品才成立合同关系。您可以随时登录您在本站注册的账户,查询您的订单状态。</p> +<p><strong>7.3</strong>由于市场变化及各种以合理商业努力难以控制的因素的影响,本站无法保证您提交的订单信息中希望购买的商品都会有货;如您拟购买的商品,发生缺货,您有权取消订单。</p> +<h4>第8条 配送</h4> +<p><strong>8.1</strong>销售方将会把商品(货物)送到您所指定的收货地址,所有在本站上列出的送货时间为参考时间,参考时间的计算是根据库存状况、正常的处理过程和送货时间、送货地点的基础上估计得出的。</p> +<p><strong>8.2</strong>因如下情况造成订单延迟或无法配送等,销售方不承担延迟配送的责任:</p> +<p>(1)用户提供的信息错误、地址不详细等原因导致的;</p> +<p>(2)货物送达后无人签收,导致无法配送或延迟配送的;</p> +<p>(3)情势变更因素导致的;</p> +<p>(4)不可抗力因素导致的,例如:自然灾害、交通戒严、突发战争等。</p> +<h4>第9条 交易争议处理</h4> +<p>您在{:WSTConf('CONF.mallName')}平台交易过程中与其他用户发生争议的,您或其他用户中任何一方均有权选择以下途径解决:</p> +<p>(1)与争议相对方自主协商;</p> +<p>(2)使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站提供的争议调处服务;</p> +<p>(3)请求消费者协会或者其他依法成立的调解组织调解;</p> +<p>(4)向有关行政部门投诉;</p> +<p>(5)根据与争议相对方达成的仲裁协议(如有)提请仲裁机构仲裁;</p> +<p>(6)向人民法院提起诉讼。</p> +<h4>第10条 责任限制及不承诺担保</h4> +<p><strong>10.1</strong>除非另有明确的书面说明,本站及其所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务,均是在"按现状"和"按现有"的基础上提供的。</p> +<p><strong>10.2</strong>除非另有明确的书面说明,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不对本站的运营及其包含在本网站上的信息、内容、材料、产品(包括软件)或服务作任何形式的、明示或默示的声明或担保(根据中华人民共和国法律另有规定的以外)。</p> +<p><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不担保本站所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务、其服务器或从本站发出的电子信件、信息没有病毒或其他有害成分。</p> +<p>如因不可抗力或其它本站无法控制的原因使本站销售系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>会合理地尽力协助处理善后事宜。</p> +<h4>第11条 协议更新及用户关注义务</h4> +<p>根据国家法律法规变化及网站运营需要,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权对本协议条款不时地进行修改,修改后的协议一旦被张贴在本站上即生效,并代替原来的协议。用户可随时登录查阅最新协议;用户有义务不时关注并阅读最新版的协议及网站公告。如用户不同意更新后的协议,可以且应立即停止接受<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站依据本协议提供的服务;如用户继续使用本网站提供的服务的,即视为同意更新后的协议。<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>建议您在使用本站之前阅读本协议及本站的公告。 如果本协议中任何一条被视为废止、无效或因任何理由不可执行,该条应视为可分的且并不影响任何其余条款的有效性和可执行性。</p> +<h4>附则</h4> +<p><strong>1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>尊重用户和消费者的合法权利,本协议及本网站上发布的各类规则、声明等其他内容,均是为了更好的、更加便利的为用户和消费者提供服务。本站欢迎用户和社会各界提出意见和建议,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>将虚心接受并适时修改本协议及本站上的各类规则。</p> +<p><strong>2</strong>本协议内容中以黑体、加粗、下划线、斜体等方式显著标识的条款,请用户着重阅读。</p> +<p><strong>3</strong>您点击本协议下方的"同意并注册"按钮即视为您完全接受本协议,在点击之前请您再次确认已知悉并完全理解本协议的全部内容。</p> + + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/reg.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/register.html b/hyhproject/mobile2/view/default/register.html new file mode 100755 index 0000000..e8c1ef9 --- /dev/null +++ b/hyhproject/mobile2/view/default/register.html @@ -0,0 +1,138 @@ +{extend name="default/base" /} +{block name="title"}注册 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="javascript:history.go(-1)" ></i><h1 id="login-w">注册</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> +{/block} +{block name="main"} + {/* 注册页面 */} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container" id="login0"> + <div class="wst-lo-frame"> + <div class="frame"><input id="regName" type="text" placeholder="手机号" onkeyup="javascript:onTesting(this)"></div> + {/* 获取验证码 prompt */} + <div class="verify phone"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" class="ui-btn ui-btn-primary" onclick="javascript:obtainCode()">获取验证码</button> + </div> + <!-- <div class="verify phone"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id="verifyImg3" src="/mobile/users/getverify.html" onclick="javascript:WST.getVerify(&quot;#verifyImg3&quot;)"> + </div> --> + <div class="frame"><input id="regPwd" type="password" placeholder="密码"></div> + <div class="frame"><input id="regcoPwd" type="password" placeholder="确认密码"></div> + <div class="verify phone"> + 推荐人:<input id="pName" type="readonly" placeholder="分享人" maxlength="30"> + </div> + + </div> + <div class="wst-lo-agreement"> + <i id="defaults" class="ui-icon-chooses ui-icon-success-block wst-active" onclick="javascript:inAgree(this)"></i>我已阅读并同意<span onclick="javascript:wholeShow('protocol');">《用户注册协议》</span> + </div> + <div class="wst-lo-button"> + <button id="regButton" class="button" onclick="javascript:register();">注册</button> + </div> + </section> +{/block} +{block name="include"} +{/* 用户注册协议 */} +<div class="wst-fr-protocol" id="protocol"> + <div class="title"><span>用户注册协议</span><i class="ui-icon-close-page" onclick="javascript:wholeHide('protocol');"></i><div class="wst-clear"></div></div> + <div class="content"> + +<h4><span>{:WSTConf('CONF.mallName')}</span>用户注册协议</h4> +<p>本协议是您与<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有者之间就<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站服务等相关事宜所订立的契约,请您仔细阅读本注册协议,您点击"同意并继续"按钮后,本协议即构成对双方有约束力的法律文件。</p> +<h4>第1条 本站服务条款的确认和接纳</h4> +<p><strong>1.1</strong>本站的各项电子服务的所有权和运作权归<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有。用户同意所有注册协议条款并完成注册程序,才能成为本站的正式用户。用户确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。<p></p> +<p><strong>1.2</strong>用户点击同意本协议的,即视为用户确认自己具有享受本站服务、下单购物等相应的权利能力和行为能力,能够独立承担法律责任。</p> +<p><strong>1.3</strong>如果您在18周岁以下,您只能在父母或监护人的监护参与下才能使用本站。<p> +<p><strong>1.4</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留在中华人民共和国大陆地区法施行之法律允许的范围内独自决定拒绝服务、关闭用户账户、清除或编辑内容或取消订单的权利。</p> +<h4>第2条 本站服务</h4> +<p><strong>2.1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>通过互联网依法为用户提供互联网信息等服务,用户在完全同意本协议及本站规定的情况下,方有权使用本站的相关服务。</p> +<p><strong>2.2</strong>用户必须自行准备如下设备和承担如下开支:</p> +<p>(1)上网设备,包括并不限于电脑或者其他上网终端、调制解调器及其他必备的上网装置;</p> +<p>(2)上网开支,包括并不限于网络接入费、上网设备租用费、手机流量费等。</p> +<h4>第3条 用户信息</h4> +<p><strong>3.1</strong>用户应自行诚信向本站提供注册资料,用户同意其提供的注册资料真实、准确、完整、合法有效,用户注册资料如有变动的,应及时更新其注册资料。如果用户提供的注册资料不合法、不真实、不准确、不详尽的,用户需承担因此引起的相应责任及后果,并且<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留终止用户使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>各项服务的权利。</p> +<p><strong>3.2</strong>用户在本站进行浏览、下单购物等活动时,涉及用户真实姓名/名称、通信地址、联系电话、电子邮箱等隐私信息的,本站将予以严格保密,除非得到用户的授权或法律另有规定,本站不会向外界披露用户隐私信息。</p> +<p><strong>3.3</strong>用户注册成功后,将产生用户名和密码等账户信息,您可以根据本站规定改变您的密码。用户应谨慎合理的保存、使用其用户名和密码。用户若发现任何非法使用用户账号或存在安全漏洞的情况,请立即通知本站并向公安机关报案。</p> +<p><strong>3.4</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>拥有通过邮件、短信电话等形式,向在本站注册、购物用户、收货人发送订单信息、促销活动等告知信息的权利。</p> +<p><strong>3.5</strong>用户不得将在本站注册获得的账户借给他人使用,否则用户应承担由此产生的全部责任,并与实际使用人承担连带责任。</p> +<p><strong>3.6</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权使用用户的注册信息、用户名、密码等信息,登录进入用户的注册账户,进行证据保全,包括但不限于公证、见证等。</p> +<h4>第4条 用户依法言行义务</h4> +<p>本协议依据国家相关法律法规规章制定,用户同意严格遵守以下义务:</p> +<p>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</p> +<p>(2)从中国大陆向境外传输资料信息时必须符合中国有关法规;</p> +<p>(3)不得利用本站从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动;</p> +<p>(4)不得干扰本站的正常运转,不得侵入本站及国家计算机信息系统;</p> +<p>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽的、不文明的等信息资料;</p> +<p>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</p> +<p>(7)不得教唆他人从事本条所禁止的行为;</p> +<p>(8)不得利用在本站注册的账户进行牟利性经营活动;</p> +<p>(9)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容;</p> +<p>用户应不时关注并遵守本站不时公布或修改的各类合法规则规定。</p> +<p>本站保有删除站内各类不符合法律政策或不真实的信息内容而无须通知用户的权利。</p> +<p>若用户未遵守以上规定的,本站有权作出独立判断并采取暂停或关闭用户帐号等措施。用户须对自己在网上的言论和行为承担法律责任。</p> +<h4>第5条 店铺义务</h4> +<p><strong>5.1</strong>店铺经营者可通过本站申请店铺,发布全新或二手商品及/或服务信息并与其他用户达成交易,但必须保证商品信息真实。如有发现商品假冒或者其他违反国家法律规定的商品,本站有权对商品进行禁售。</p> +<p><strong>5.2</strong>若店铺经营者发生改变,店铺经营者需及时联系本站进行信息的变更,若未及时联系本站而导致消费者与原店铺经营者产生交易纠纷或者违法国家规定的事情,本站不负任何连带责任。</p> +<p><strong>5.3</strong>店铺经营者有权通过使用店铺设置短暂关停店铺,但店铺经营者应当对自己店铺关停前已达成的交易继续承担发货、退换货及质保维修、维权投诉处理等交易保障责任。</p> +<p><strong>5.4</strong>店铺经营者如有不实交易信息或者违反国家相关法律的行为,本站有权对店铺进行关停,并对关停期间所产生的损失不负任何责任。</p> +<p>依据上述约定关停店铺均不会影响您已经累积的信用。</p> +</p> +<h4>第6条 商品信息</h4> +<p>本站上的商品价格、数量、是否有货等商品信息随时都有可能发生变动,本站不作特别通知。由于网站上商品信息的数量极其庞大,虽然本站会尽最大努力保证您所浏览商品信息的准确性,但由于众所周知的互联网技术因素等客观原因存在,本站网页显示的信息可能会有一定的滞后性或差错,对此情形您知悉并理解;<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>欢迎纠错,并会视情况给予纠错者一定的奖励。</p> +<p>为表述便利,商品和服务简称为"商品"或"货物"。</p> +<h4>第7条 订单</h4> +<p><strong>7.1</strong>在您下订单时,请您仔细确认所购商品的名称、价格、数量、规格、联系地址、电话、收货人等信息。收货人与用户本人不一致的,收货人的行为和意思表示视为用户的行为和意思表示,用户应对收货人的行为及意思表示的法律后果承担连带责任。</p> +<p><strong>7.2</strong>除法律另有强制性规定外,双方约定如下:本站上销售方展示的商品和价格等信息仅仅是要约邀请,您下单时须填写您希望购买的商品数量、价款及支付方式、收货人、联系方式、收货地址(合同履行地点)、合同履行方式等内容;系统生成的订单信息是计算机信息系统根据您填写的内容自动生成的数据,仅是您向销售方发出的合同要约;销售方收到您的订单信息后,只有在销售方将您在订单中订购的商品从仓库实际直接向您发出时( 以商品出库为标志),方视为您与销售方之间就实际直接向您发出的商品建立了合同关系;如果您在一份订单里订购了多种商品并且销售方只给您发出了部分商品时,您与销售方之间仅就实际直接向您发出的商品建立了合同关系;只有在销售方实际直接向您发出了订单中订购的其他商品时,您和销售方之间就订单中该其他已实际直接向您发出的商品才成立合同关系。您可以随时登录您在本站注册的账户,查询您的订单状态。</p> +<p><strong>7.3</strong>由于市场变化及各种以合理商业努力难以控制的因素的影响,本站无法保证您提交的订单信息中希望购买的商品都会有货;如您拟购买的商品,发生缺货,您有权取消订单。</p> +<h4>第8条 配送</h4> +<p><strong>8.1</strong>销售方将会把商品(货物)送到您所指定的收货地址,所有在本站上列出的送货时间为参考时间,参考时间的计算是根据库存状况、正常的处理过程和送货时间、送货地点的基础上估计得出的。</p> +<p><strong>8.2</strong>因如下情况造成订单延迟或无法配送等,销售方不承担延迟配送的责任:</p> +<p>(1)用户提供的信息错误、地址不详细等原因导致的;</p> +<p>(2)货物送达后无人签收,导致无法配送或延迟配送的;</p> +<p>(3)情势变更因素导致的;</p> +<p>(4)不可抗力因素导致的,例如:自然灾害、交通戒严、突发战争等。</p> +<h4>第9条 交易争议处理</h4> +<p>您在{:WSTConf('CONF.mallName')}平台交易过程中与其他用户发生争议的,您或其他用户中任何一方均有权选择以下途径解决:</p> +<p>(1)与争议相对方自主协商;</p> +<p>(2)使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站提供的争议调处服务;</p> +<p>(3)请求消费者协会或者其他依法成立的调解组织调解;</p> +<p>(4)向有关行政部门投诉;</p> +<p>(5)根据与争议相对方达成的仲裁协议(如有)提请仲裁机构仲裁;</p> +<p>(6)向人民法院提起诉讼。</p> +<h4>第10条 责任限制及不承诺担保</h4> +<p><strong>10.1</strong>除非另有明确的书面说明,本站及其所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务,均是在"按现状"和"按现有"的基础上提供的。</p> +<p><strong>10.2</strong>除非另有明确的书面说明,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不对本站的运营及其包含在本网站上的信息、内容、材料、产品(包括软件)或服务作任何形式的、明示或默示的声明或担保(根据中华人民共和国法律另有规定的以外)。</p> +<p><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不担保本站所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务、其服务器或从本站发出的电子信件、信息没有病毒或其他有害成分。</p> +<p>如因不可抗力或其它本站无法控制的原因使本站销售系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>会合理地尽力协助处理善后事宜。</p> +<h4>第11条 协议更新及用户关注义务</h4> +<p>根据国家法律法规变化及网站运营需要,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权对本协议条款不时地进行修改,修改后的协议一旦被张贴在本站上即生效,并代替原来的协议。用户可随时登录查阅最新协议;用户有义务不时关注并阅读最新版的协议及网站公告。如用户不同意更新后的协议,可以且应立即停止接受<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站依据本协议提供的服务;如用户继续使用本网站提供的服务的,即视为同意更新后的协议。<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>建议您在使用本站之前阅读本协议及本站的公告。 如果本协议中任何一条被视为废止、无效或因任何理由不可执行,该条应视为可分的且并不影响任何其余条款的有效性和可执行性。</p> +<h4>附则</h4> +<p><strong>1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>尊重用户和消费者的合法权利,本协议及本网站上发布的各类规则、声明等其他内容,均是为了更好的、更加便利的为用户和消费者提供服务。本站欢迎用户和社会各界提出意见和建议,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>将虚心接受并适时修改本协议及本站上的各类规则。</p> +<p><strong>2</strong>本协议内容中以黑体、加粗、下划线、斜体等方式显著标识的条款,请用户着重阅读。</p> +<p><strong>3</strong>您点击本协议下方的"同意并注册"按钮即视为您完全接受本协议,在点击之前请您再次确认已知悉并完全理解本协议的全部内容。</p> + + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/login.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/self_shop.html b/hyhproject/mobile2/view/default/self_shop.html new file mode 100755 index 0000000..80b6f57 --- /dev/null +++ b/hyhproject/mobile2/view/default/self_shop.html @@ -0,0 +1,223 @@ +{extend name="default/base" /} +{block name="title"}自营店铺 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/self_shop.css?v={$v}"> +{/block} +{block name="header"}{/block} + +{block name="main"} +<input type="hidden" name="" value="{$data.shop.shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<input type='hidden' name="" value="0" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-sh-banner" {if $data['shop']['shopBanner']!=''}style="background:url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <header class="ui-header ui-header-positive wst-se-header2 wst-se-header3"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search wst-se-search2" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon wst-se-icon0" onclick="javascript:dataShow();"></span> + {php}$cartNum = WSTCartNum();{/php} + <a href="{:url('mobile/carts/index')}"><span class="wst-se-icon wst-se-icon2">{if($cartNum>0)}<i>{$cartNum}</i>{/if}</span></a> + </header> + </div> + <div class="shop-banner"> + <div class="shop-photo"> + <div class="photo"> + <img src="__IMGURL__/{$data.shop.shopImg}"> + <p class="name">{$data.shop.shopName}</p> + </div> + <span class="introduce" onclick="toShopInfo({$data['shop']['shopId']})">店铺介绍</span> + <div class="wst-clear"></div> + </div> + <div class="shop-info" {if(!$data['shop']['shopNotice'])}style="padding-bottom:0.1rem;border-bottom: 0.05rem solid #f2f1f1;"{/if}> + <div class="ui-row-flex"> + <div class="ui-col ui-col"> + <a class="shop-btn j-shopfollow {if($isFavor>0)}follow{/if}" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"></a> + <p id="followNum">{$followNum}</p> + <p>收藏数</p> + </div> + <div class="ui-col ui-col-2"></div> + <div class="ui-col ui-col"><p>{$data['shop']['scores']['areas']['areaName1']}{$data['shop']['scores']['areas']['areaName2']}</p><p>所在地</p></div> + </div> + </div> + {if($data['shop']['shopNotice'])} + <div class="shop-notice"> + <p class="title">店铺公告</p> + <p>{$data['shop']['shopNotice']}</p> + </div> + {/if} + <div class="wst-clear"></div> + </div> + {if !empty($data['shop']['shopAds'])} + <div class="shop-ads"> + <div class="ui-slider"> + <ul class="ui-slider-content" style="width: 300%"> + {volist name="$data['shop']['shopAds']" id="ads"} + <li><span><a href="{$ads.adUrl}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{$ads.adImg}"></a></span></li> + {/volist} + </ul> + </div> + </div> + {/if} + <div class="wst-shl-ads" > + <div class="title">店主推荐</div> + <div class="wst-gol-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="$data['rec']" id="re"} + <div class="swiper-slide" style="width:33.333333%;"> + <div style="border-right: 0.01rem solid #f2f1f1;"> + <div class="wst-gol-img j-imgRec"><a href="javascript:void(0)" onclick="WST.intoGoods({$re['goodsId']})"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($re['goodsImg'],3)}" title="{$re['goodsName']}"></a></div> + <p>¥{$re['shopPrice']}</p> + <div class="wst-clear"></div> + </div> + </div> + {/volist} + </div> + </div> + </div> + </div> + + <div class="wst-shl-ads" > + <div class="title">热卖商品</div> + <div class="wst-gol-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="$data['hot']" id="hot"} + <div class="swiper-slide" style="width:33.333333%;"> + <div style="border-right: 0.01rem solid #f2f1f1;"> + <div class="wst-gol-img j-imgRec1"><a href="javascript:void(0)" onclick="WST.intoGoods({$hot['goodsId']})"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($hot['goodsImg'],3)}" title="{$hot['goodsName']}"></a></div> + <p>¥{$hot['shopPrice']}</p> + <div class="wst-clear"></div> + </div> + </div> + {/volist} + </div> + </div> + </div> + </div> + <script id="gList" type="text/html"> + <div class="wst-in-title"> + <ul class="ui-row shop-floor-title f{{d.currPage}}"> + <li class="ui-col ui-col-80">{{d.catName}}</li> + <li class="ui-col ui-col-20"><a href="{{WST.U('mobile/shops/shopgoodslist','shopId=1&ct1='+d.catId)}}" class="shop-more">更多</a></li> + </ul> + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i<d.goods.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="javascript:WST.intoGoos({{d.goods[i].goodsId}});"> + <div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}});"> + <img src="{{# WST.conf.IMGURL+'/'+WST.conf.GOODS_LOGO}}" data-echo="__IMGURL__/{{d.goods[i].goodsImg}}" title="{{d.goods[i].goodsName}}"/></a></div> + <div class="name ui-nowrap-multi">{{d.goods[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d.goods[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">¥ {{ d.goods[i].marketPrice }}</span><span class="deal">成交数:{{ d.goods[i].saleNum }}</span></div> + </div> + {{# } }} + {{# } }} + <div class="wst-clear"></div> + </script> + + <!-- 商品列表 --> + <div id="goods-list"></div> + +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + + + <ul> + <li> + <div class="wst-goodscats"> + <span>&nbsp;</span> + </div> + </li> + </ul> + </div> + {/volist} + </div> +</div> +</section> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> + <script> + /*分类*/ + function getGoodsList(ct1){ + $('#ct1').val(ct1); + // 跳转店铺商品列表 + var shopId = $('#shopId').val(); + location.href=WST.U('mobile/shops/shopgoodslist',{'shopId':shopId,'ct1':ct1},true) + } + </script> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/self_shop.js'></script> + +<script> +$(function(){ + {if !empty($data['shop']['shopAds'])} + shopAds(); + {/if} + WST.initFooter('home'); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/settlement.html b/hyhproject/mobile2/view/default/settlement.html new file mode 100755 index 0000000..baafc8e --- /dev/null +++ b/hyhproject/mobile2/view/default/settlement.html @@ -0,0 +1,271 @@ +{extend name="default/base" /} +{block name="title"}确认订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/settlement.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <a href="{:url('mobile/carts/index')}"><i class="ui-icon-return"></i></a><h1>确认订单</h1> + </header> +{/block} +{block name="footer"} + {php}$shopFreight = 0;$shopIds = '';{/php} + {volist name="$carts['carts']" id="car"} + {php} + if($car['isFreeShipping']){ + $freight = 0; + }else{ + if(!empty($userAddress)){ + $freight = WSTOrderFreight($car['shopId'],$userAddress['areaId2']); + }else{ + $freight = WSTOrderFreight($car['shopId'],-1); + } + } + $shopFreight = $shopFreight + $freight; + {/php} + {/volist} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:85px; border-top: 1px solid #e8e8e8;" id="footer"> + <input type="hidden" name="" value="{if empty($userAddress)}{php}echo sprintf("%.2f", $carts["goodsTotalMoney"]);{/php}{else}{php}echo sprintf("%.2f", $carts["goodsTotalMoney"]+$shopFreight);{/php}{/if}" id="totalPrice" autocomplete="off"> + <div class="wst-se-total">应付总金额(含运费):<span id="totalMoney"> + ¥{if empty($userAddress)} + {php}echo sprintf("%.2f", $carts["goodsTotalMoney"]-$carts['promotionMoney']);{/php} + {else} + {php}echo sprintf("%.2f", $carts["goodsTotalMoney"]+$shopFreight-$carts['promotionMoney']);{/php} + {/if}</span></div> + <div class="wst-se-confirm"><button class="button" onclick="javascript:submitOrder();">确定</button></div> + </footer> +{/block} +{block name="main"} + {php}$shopFreight = 0;{/php} + <input type="hidden" name="" value="1" id="sign" autocomplete="off"> + <section class="ui-container" style="border-bottom: 86px solid transparent;"> + <ul class="ui-list ui-list-text ui-list-link wst-se-address"> + <input type="hidden" name="" value="{if isset($userAddress['addressId']) }{$userAddress['addressId']}{/if}" id="addressId" autocomplete="off"> + <input type="hidden" name="" value="{if isset($userAddress['addressId']) }{$userAddress['areaId2']}{/if}" id="areaId" autocomplete="off"> + + {if empty($userAddress)} + <li onclick="javascript:addAddress(1);"><h4><p class="infono">您还没添加收货地址,请添加。</p></h4> + {else} + <li onclick="javascript:addAddress(1,{$userAddress['addressId']});"><h5> + <p class="infot">{$userAddress['userName']} {$userAddress['userPhone']}</p> + <p class="infob"><i class="ui-icon-pin"></i>{$userAddress['areaName']}{$userAddress['userAddress']}</p> + </h5></li> + {/if} + + </ul> + {volist name="$carts['carts']" id="ca"} + {php} + if($ca['isFreeShipping']){ + $freight = 0; + }else{ + if(!empty($userAddress)){ + $freight = WSTOrderFreight($ca['shopId'],$userAddress['areaId2']); + $shopFreight = $shopFreight + $freight; + }else{ + $freight = WSTOrderFreight($ca['shopId'],-1); + $shopFreight = $shopFreight + $freight; + } + } + $shopFreight = $shopFreight + $freight; + {/php} + <div class="wst-se-sh"> + <p class="ui-nowrap-flex shopn" shopId="{$ca['shopId']}"><i></i>{$ca['shopName']}</p> + {volist name="ca['list']" id="li"} + {:hook('mobileDocumentSettlementGoodsPromotion',['goods'=>$li])} + <ul class="ui-row goods j-g{$li.cartId}"> + <li class="ui-col ui-col-25"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </li> + <li class="ui-col ui-col-75"> + <ul class="ui-row info"> + <li class="ui-col ui-col-75"> + <div class="name"><p class="names">{$li['goodsName']}</p> + {if($li['specNames'])} + <p class="spec">规格: + {volist name="li['specNames']" id="sp"} + {$sp['catName']}:{$sp['itemName']} + {/volist} + </p> + {/if}</div> + </li> + <li class="ui-col ui-col-25"><p class="price" id="price_{$li['cartId']}" mval="{$li['shopPrice']}">¥{$li['shopPrice']}</p><p class="number" id="number_{$li['cartId']}" mval="{$li['cartNum']}">×{$li['cartNum']}</p></li> + </ul> + </li> + </ul> + {/volist} + + {:hook('mobileDocumentCartShopPromotion',$ca)} + + <div class="cost"> + <div>运费:<span id="shopF_{$ca['shopId']}">¥{php}echo sprintf("%.2f", $freight);{/php}</span></div> + <div id="reward_{$ca['shopId']}" style="display:none;">立减:<span id="shopF_{$ca['shopId']}">-&ensp;¥{:sprintf("%.2f", $ca['promotionMoney'])}</span></div> + <div>店铺合计(含运费):<span id="shopC_{$ca['shopId']}">¥{php}echo sprintf("%.2f", $freight+$ca['goodsMoney']-$ca['promotionMoney']);{/php}</span></div> + </div> + <div class="remarks"> + <textarea id="remark_{$ca['shopId']}" autocomplete="off" placeholder="填写订单备注:"></textarea> + </div> + </div> + {/volist} + <ul class="ui-list ui-list-text ui-list-link ui-list-active wst-se-mode"> + <li class="mode" onclick="javascript:dataShow('payments');"> + <h4 class="ui-nowrap">支付方式</h4> + <div class="ui-txt-info" id="paymentst">{if !empty($payments['0']) || !empty($payments['1'])}{if !empty($payments['1'])}{$payments['1']['0']['payName']}{else}{$payments['0']['0']['payName']}{/if}{else}无{/if}</div> + </li> + <li class="mode" onclick="javascript:dataShow('gives');"> + <h4 class="ui-nowrap">配送方式</h4> + <div class="ui-txt-info" id="givest">快递运输</div> + </li> + <li class="{if(WSTConf('CONF.isOpenScorePay')==1)}mode{/if}" onclick="javascript:getInvoiceList();"> + <h4 class="ui-nowrap">发票信息</h4> + <div class="ui-txt-info" id="invoicest">不开发票</div> + </li> + {if WSTConf('CONF.isOpenScorePay')==1 and $userOrderScore neq 0} <!-- mark 20170907 --> + <li onclick="javascript:dataShow('score');"> + <h4 class="ui-nowrap">惠宝抵用</h4> + <div class="ui-txt-info" id="scoret">否</div> + </li> + {/if} + </ul> + </section> +{/block} +{block name="include"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 支付方式 */} +{if !empty($payments['0']) || !empty($payments['1'])} +<input type="hidden" name="" value="{if !empty($payments['1'])}1{else}0{/if}" id="paymentsh" autocomplete="off"> +<input type="hidden" name="" value="{if !empty($payments['1'])}{$payments['1']['0']['payCode']}{else}{$payments['0']['0']['payCode']}{/if}" id="paymentsw" autocomplete="off"> +<div class="wst-fr-box frame" id="payments"> + <div class="title"><span>支付方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('payments');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {if !empty($payments)} + {php}$paymentkey = 0;{/php} + {volist name='$payments' id='paymentvo'} + {volist name='$paymentvo' id='paymentitem'} + <ul class="ui-list" onclick="javascript:onSwitch(this);" style="border-bottom: 1px solid #f2f1f1;"> + <li><div class="wst-list-infose1" style="padding-left: 25px;"><i class="{$paymentitem['payCode']}"></i><span>{$paymentitem['payName']}</span></div></li> + <i class="ui-icon-push payments_{$paymentitem['payCode']} ui-icon-checked-s" payCode="{$paymentitem['payCode']}" mode="{$paymentitem['isOnline']}" word="{$paymentitem['payName']}"></i> + </ul> + {php}$paymentkey++;{/php} + {/volist} + {/volist} + {/if} + </div> + <button class="button" onclick="javascript:inDetermine('payments');">确定</button> +</div> +{/if} +{/* 配送方式 */} +<input type="hidden" name="" value="0" id="givesh" autocomplete="off"> +<div class="wst-fr-box frame" id="gives"> + <div class="title"><span>配送方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('gives');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>快递运输</span></div></li> + <i class="ui-icon-push gives0 ui-icon-checked-s wst-active" mode="0" word="快递运输"></i> + </ul> + <!-- <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>自提</span></div></li> + <i class="ui-icon-push gives1 ui-icon-unchecked-s" mode="1" word="自提"></i> + </ul> --> + </div> + <button class="button" onclick="javascript:inDetermine('gives');">确定</button> +</div> + + + +{/* 用户发票列表 */} +<script type="text/html" id="invoiceBox"> + {{# for(var i = 0; i < d.length; i++){ }} + <li invId="{{d[i].id}}" invCode="{{d[i].invoiceCode}}">{{d[i].invoiceHead}}</li> + {{# } }} +</script> + +{/* 发票信息层 */} +<div class="invoice_box" id="frame"> + <div class="title" id="boxTitle"><span>发票信息</span><i class="ui-icon-close-page" onclick="javascript:invoiceHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="invoice_content"> + <div class="inv_item"> + <div class="inv_tit">发票抬头</div> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,0);"> + <li><div class="pdtb10"><span>个人</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="个人"></i> + </ul> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,1);"> + <li><div class="pdtb10"><span>单位</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="单位"></i> + </ul> + <input type="hidden" id="invoice_obj" value="0" /> + <div class="wst-clear"></div> + + <div class="inv_hidebox"> + <div class="inv_head_inputbox"> + <input class="inv_head_input" type="text" id="invoice_head" placeholder="请填写单位名称" /> + <input type="hidden" id="invoiceId" value="0" /> + <div id="inv_headlist"> + <ul class="inv_list_item"> + </ul> + </div> + </div> + <div class="inv_code_inputbox"> + <input class="inv_code_input" type="text" id="invoice_code" placeholder="请填写纳税人识别码" /> + </div> + </div> + </div> + <div class="inv_item"> + <input type="hidden" id="isInvoice" value="0" /> + <div class="inv_tit inv_line">发票内容</div> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,0);"> + <li><div class="pdtb10"><span>不开发票</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="不开发票"></i> + </ul> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,1);"> + <li><div class="pdtb10"><span>明细</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="明细"></i> + </ul> + <div class="wst-clear"></div> + </div> + + <ul class="inv_tip"> + <li><i>·</i>发票金额不含优惠券和惠宝支付部分</li> + <li><i>·</i>第三方卖家销售的商品发票由商家开具、寄出、发票内容由商家决定</li> + </ul> + <button class="button" onclick="javascript:saveInvoice();">确定</button> + </div> +</div> + + +{/* 惠宝支付 */} +<input type="hidden" name="" value="0" id="scoreh" autocomplete="off"> +<div class="wst-fr-box frame" id="score"> + <div class="title"><span>惠宝支付</span><i class="ui-icon-close-page" onclick="javascript:dataHide('score');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>是</span></div></li> + <i class="ui-icon-push score1 ui-icon-checked-s wst-active" mode="1" word="是"></i> + </ul> + <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>否</span></div></li> + <i class="ui-icon-push score0 ui-icon-unchecked-s" mode="0" word="否"></i> + </ul> + <div class="wst-fr-score">(可用<span id="userOrderScore">{$userOrderScore}</span>个惠宝,可抵<span>¥<span id="userOrderMoney">{$userOrderMoney}</span></span>)</div> + </div> + <button class="button" onclick="javascript:inDetermine('score');">确定</button> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/settlement.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/settlement_quick.html b/hyhproject/mobile2/view/default/settlement_quick.html new file mode 100755 index 0000000..867e9dd --- /dev/null +++ b/hyhproject/mobile2/view/default/settlement_quick.html @@ -0,0 +1,194 @@ +{extend name="default/base" /} +{block name="title"}确认订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/settlement.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>确认订单</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:85px; border-top: 1px solid #e8e8e8;" id="footer"> + <input type="hidden" name="" value="{$carts['goodsTotalMoney']}" id="totalPrice" autocomplete="off"> + <div class="wst-se-total">应付总金额:<span id="totalMoney">¥{$carts['goodsTotalMoney']}</span></div> + <div class="wst-se-confirm"><button class="button" onclick="javascript:quickSubmitOrder();">确定</button></div> + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="2" id="sign" autocomplete="off"> + <section class="ui-container" style="border-bottom: 86px solid transparent;"> + {if($carts['carts'])} + {volist name="$carts['carts']" id="ca"} + <div class="wst-se-sh"> + <p class="ui-nowrap-flex shopn" shopId="{$ca['shopId']}"><i></i>{$ca['shopName']}</p> + {volist name="ca['list']" id="li"} + <ul class="ui-row goods"> + <li class="ui-col ui-col-25"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </li> + <li class="ui-col ui-col-75"> + <ul class="ui-row info"> + <li class="ui-col ui-col-75"> + <div class="name"><p class="names">{$li['goodsName']}</p> + </div> + </li> + <li class="ui-col ui-col-25"><p class="price">¥{$li['shopPrice']}</p><p class="number">×{$li['cartNum']}</p></li> + </ul> + </li> + </ul> + {/volist} + + {:hook('mobileDocumentCartShopPromotion',$ca)} + <div class="cost"> + <div>店铺合计:<span>¥{php}echo sprintf("%.2f", $ca['goodsMoney']);{/php}</span></div> + </div> + <div class="remarks"> + <textarea id="remark_{$ca['shopId']}" autocomplete="off" placeholder="填写订单备注:"></textarea> + </div> + </div> + {/volist} + {else} + <p class="ui-nowrap-flex shopn">您还没有添加商品哦,快去逛逛吧~</p> + {/if} + <ul class="ui-list ui-list-text ui-list-link ui-list-active wst-se-mode"> + <li class="mode" onclick="javascript:dataShow('payments');"> + <h4 class="ui-nowrap">支付方式</h4> + <div class="ui-txt-info" id="paymentst">{if !empty($payments['0']) || !empty($payments['1'])}{if !empty($payments['1'])}{$payments['1']['0']['payName']}{/if}{else}无{/if}</div> + </li> + <li class="{if(WSTConf('CONF.isOpenScorePay')==1)}mode{/if}" onclick="javascript:getInvoiceList();"> + <h4 class="ui-nowrap">发票信息</h4> + <div class="ui-txt-info" id="invoicest">不开发票</div> + </li> + {if(WSTConf('CONF.isOpenScorePay')==1)} + <li class="mode" onclick="javascript:dataShow('score');"> + <h4 class="ui-nowrap">惠宝支付</h4> + <div class="ui-txt-info" id="scoret">否</div> + </li> + {/if} + </ul> + </section> +{/block} +{block name="include"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 支付方式 */} +{if !empty($payments['0']) || !empty($payments['1'])} +<input type="hidden" name="" value="{if !empty($payments['1'])}1{/if}" id="paymentsh" autocomplete="off"> +<input type="hidden" name="" value="{if !empty($payments['1'])}{$payments['1']['0']['payCode']}{else}{$payments['0']['0']['payCode']}{/if}" id="paymentsw" autocomplete="off"> +<div class="wst-fr-box frame" id="payments"> + <div class="title"><span>支付方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('payments');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {if !empty($payments)} + {if !empty($payments['1'])} + {volist name="$payments['1']" id="pay" key="paykey"} + <ul class="ui-list" onclick="javascript:onSwitch(this);" style="border-bottom: 1px solid #f2f1f1;"> + <li><div class="wst-list-infose1" style="padding-left: 25px;"><i class="{$pay['payCode']}"></i><span>{$pay['payName']}</span></div></li> + <i class="ui-icon-push payments_{$pay['payCode']} ui-icon-checked-s" payCode="{$pay['payCode']}" mode="{$pay['isOnline']}" word="{$pay['payName']}"></i> + </ul> + {/volist} + {/if} + {/if} + </div> + <button class="button" onclick="javascript:inDetermine('payments');">确定</button> +</div> +{/if} + + +{/* 用户发票列表 */} +<script type="text/html" id="invoiceBox"> + {{# for(var i = 0; i < d.length; i++){ }} + <li invId="{{d[i].id}}" invCode="{{d[i].invoiceCode}}">{{d[i].invoiceHead}}</li> + {{# } }} +</script> + +{/* 发票信息层 */} +<div class="invoice_box" id="frame"> + <div class="title" id="boxTitle"><span>发票信息</span><i class="ui-icon-close-page" onclick="javascript:invoiceHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="invoice_content"> + <div class="inv_item"> + <div class="inv_tit">发票抬头</div> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,0);"> + <li><div class="pdtb10"><span>个人</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="个人"></i> + </ul> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,1);"> + <li><div class="pdtb10"><span>单位</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="单位"></i> + </ul> + <input type="hidden" id="invoice_obj" value="0" /> + <div class="wst-clear"></div> + + <div class="inv_hidebox"> + <div class="inv_head_inputbox"> + <input class="inv_head_input" type="text" id="invoice_head" placeholder="请填写单位名称" /> + <input type="hidden" id="invoiceId" value="0" /> + <div id="inv_headlist"> + <ul class="inv_list_item"> + </ul> + </div> + </div> + <div class="inv_code_inputbox"> + <input class="inv_code_input" type="text" id="invoice_code" placeholder="请填写纳税人识别码" /> + </div> + </div> + </div> + <div class="inv_item"> + <input type="hidden" id="isInvoice" value="0" /> + <div class="inv_tit inv_line">发票内容</div> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,0);"> + <li><div class="pdtb10"><span>不开发票</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="不开发票"></i> + </ul> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,1);"> + <li><div class="pdtb10"><span>明细</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="明细"></i> + </ul> + <div class="wst-clear"></div> + </div> + + <ul class="inv_tip"> + <li><i>·</i>发票金额不含优惠券和惠宝支付部分</li> + <li><i>·</i>第三方卖家销售的商品发票由商家开具、寄出、发票内容由商家决定</li> + </ul> + <button class="button" onclick="javascript:saveInvoice();">确定</button> + </div> +</div> + + + + +{/* 惠宝支付 */} +<input type="hidden" name="" value="0" id="scoreh" autocomplete="off"> +<div class="wst-fr-box frame" id="score"> + <div class="title"><span>惠宝支付</span><i class="ui-icon-close-page" onclick="javascript:dataHide('score');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>是</span></div></li> + <i class="ui-icon-push score1 ui-icon-checked-s wst-active" mode="1" word="是"></i> + </ul> + <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>否</span></div></li> + <i class="ui-icon-push score0 ui-icon-unchecked-s" mode="0" word="否"></i> + </ul> + <div class="wst-fr-score">(可用<span id="userOrderScore">{$userOrderScore}</span>个惠宝,可抵<span>¥<span id="userOrderMoney">{$userOrderMoney}</span></span>)</div> + </div> + <button class="button" onclick="javascript:inDetermine('score');">确定</button> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/settlement.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/shop_goods_list.html b/hyhproject/mobile2/view/default/shop_goods_list.html new file mode 100755 index 0000000..9bc9e6b --- /dev/null +++ b/hyhproject/mobile2/view/default/shop_goods_list.html @@ -0,0 +1,144 @@ +{extend name="default/base" /} +{block name="title"}店铺商品列表 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/shop_home.css?v={$v}"> +<style>body {background-color: #f6f6f8;}</style> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="padding-left: 0;border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('shops',1);" style="width: 76%;"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon" onclick="javascript:dataShow();"></span> + </header> +{/block} + +{block name="main"} +<input type="hidden" name="" value="" id="condition" autocomplete="off"> +<input type="hidden" name="" value="" id="desc" autocomplete="off"> +<input type="hidden" name="" value="{$shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$ct1}" id="ct1" autocomplete="off"> +<input type="hidden" name="" value="{$ct2}" id="ct2" autocomplete="off"> +<input type="hidden" name="" value="0" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="0" id="totalPage" autocomplete="off"> + + <section class="ui-container"> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,6);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + + + + <script id="shopList" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="WST.intoGoods({{d[i].goodsId}})"> + <div class="img j-imgAdapt" onclick="WST.intoGoods({{d[i].goodsId}})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({{d[i].goodsId}})"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i].goodsImg }}" title="{{d[i].goodsName}}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{{ d[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> + </div> + {{# } }} + </script> + + <ul class="ui-tab-content"> + <li id="shops-list"> + + </li> + </ul> + + + </section> +{/block} + + +{block name="footer"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> + {/volist} + </div> +</div> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/shop_goods_list.js'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/shop_home.html b/hyhproject/mobile2/view/default/shop_home.html new file mode 100755 index 0000000..4de19fd --- /dev/null +++ b/hyhproject/mobile2/view/default/shop_home.html @@ -0,0 +1,226 @@ +{extend name="default/base" /} +{block name="title"}店铺详情 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/shop_home.css?v={$v}"> +{/block} +{block name="header"}{/block} + +{block name="main"} +<input type="hidden" name="" value="" id="condition" autocomplete="off"> +<input type="hidden" name="" value="" id="desc" autocomplete="off"> +<input type="hidden" name="" value="{$shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$ct1}" id="ct1" autocomplete="off"> +<input type="hidden" name="" value="{$ct2}" id="ct2" autocomplete="off"> +<input type='hidden' name="" value="0" id="currPage" autocomplete="off"> +<input type='hidden' name="" value="0" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-sh-banner" {if $data['shop']['shopBanner']!=''}style="background:url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <header class="ui-header ui-header-positive wst-se-header2 wst-se-header3"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search wst-se-search2" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon wst-se-icon0" onclick="javascript:dataShow();"></span> + {php}$cartNum = WSTCartNum();{/php} + <a href="{:url('mobile/carts/index')}"><span class="wst-se-icon wst-se-icon2">{if($cartNum>0)}<i>{$cartNum}</i>{/if}</span></a> + </header> + </div> + <div class="shop-banner"> + <div class="shop-photo"> + <div class="photo"> + <img src="__IMGURL__/{$data.shop.shopImg}"> + <p class="name">{$data.shop.shopName}</p> + </div> + <span class="introduce" onclick="toShopInfo({$data['shop']['shopId']})">店铺介绍</span> + <div class="wst-clear"></div> + </div> + <div class="shop-info" {if(!$data['shop']['shopNotice'])}style="padding-bottom:0.1rem;border-bottom: 0.05rem solid #f2f1f1;"{/if}> + <div class="ui-row-flex"> + <div class="ui-col ui-col"> + <a class="shop-btn j-shopfollow {if($isFavor>0)}follow{/if}" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"></a> + <p id="followNum">{$followNum}</p> + <p>收藏数</p> + </div> + <div class="ui-col ui-col-2"></div> + <div class="ui-col ui-col"><p>{$data['shop']['scores']['areas']['areaName1']}{$data['shop']['scores']['areas']['areaName2']}</p><p>所在地</p></div> + </div> + </div> + {if($data['shop']['shopNotice'])} + <div class="shop-notice"> + <p class="title">店铺公告</p> + <p>{$data['shop']['shopNotice']}</p> + </div> + {/if} + <div class="wst-clear"></div> + </div> + {if !empty($data['shop']['shopAds'])} + <div class="shop-ads"> + <div class="ui-slider" style="padding-top:45%;"> + <ul class="ui-slider-content" style="width: 300%"> + {volist name="$data['shop']['shopAds']" id="ads"} + <li><span><a href="{$ads.adUrl}"><img style="width:100%; height:100%; display:block;" src="__IMGURL__/{$ads.adImg}"></a></span></li> + {/volist} + </ul> + </div> + </div> + {/if} + <ul class="wst-sh-term" id="j-top"> + <li id="j-top1" class="active" onclick="javascript:switchTerm(1);">首页</li> + <li id="j-top0" onclick="javascript:switchTerm(0);">全部商品</li> + <div class="wst-clear"></div> + </ul> + <div class="wst-sh-index" id="j-index1"> + <div class="index"> + <p class="title">店主推荐</p> + + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">最新上架</p> + + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">精品促销</p> + + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">热销商品</p> + + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">推荐更多</p> + <div id="best-list"></div> + <div class="wst-clear"></div> + </div> + <script id="shopBest" type="text/html"> + + </script> + </div> + + <div class="wst-sh-list" id="j-index0" style=""> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,6);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + <script id="shopList" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="WST.intoGoods({{d[i].goodsId}})"> + <div class="img j-imgAdapt" onclick="WST.intoGoods({{d[i].goodsId}})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({{d[i].goodsId}})"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i].goodsImg }}" title="{{d[i].goodsName}}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{{ d[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">¥ {{ d[i].marketPrice }}</span><span class="deal">成交数:{{ d[i].saleNum }}</span></div> + </div> + {{# } }} + </script> + + <div id="shops-list" class="wst-sh-goods"></div> + </div> + + </section> +{/block} + + +{block name="footer"} +<div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> +</div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> + {/volist} + </div> +</div> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/shop_home.js'></script> + +<script> +$(function(){ + // 广告不为空时 + {if !empty($data['shop']['shopAds'])} + shopAds(); + {/if} +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/shop_index.html b/hyhproject/mobile2/view/default/shop_index.html new file mode 100755 index 0000000..359c808 --- /dev/null +++ b/hyhproject/mobile2/view/default/shop_index.html @@ -0,0 +1,108 @@ +{extend name="default/base" /} +{block name="title"}店铺首页 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/shops.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> +{/block} + +{block name="main"} +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$data.shop.shopId}" id="shopId" autocomplete="off"> + + <section class="ui-container"> + <div class="wst-shl-ads"> + <div class="wst-shop-home-bg" {if $data['shop']['shopBanner']!=''}style="background:url(__IMGURL__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <div class="wst-shop-photo"> + <img src="__IMGURL__/{:WSTImg($data.shop.shopImg,3)}"> + </div> + <div class="wst-shop-name">{$data.shop.shopName}</div> + + <div class="shop-home-btn-box"> + <div class="ui-btn-group ui-row"> + <a href="tel:{$data.shop.shopTel}" style="width:45.5%;margin-right:15px;" class="ui-btn-lg shop-home-btn ui-col ui-col-50"> + <img src="__MOBILE__/img/icon_kf.png"> + 联系卖家 + </a> + <button class="ui-btn-lg shop-home-btn ui-col ui-col-50 f-btn" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"> + {if ($isFavor>0)} + <img src="__MOBILE__/img/icon_gz.png"> + <span id="fStatus">已关注</span> + {else /} + <img src="__MOBILE__/img/icon_gz.png"> + <span id="fStatus">关注店铺</span> + {/if} + </button> + </div> + </div> + + <div class="score-box"> + <div class="ui-row-flex ui-whitespace score-item"> + <div class="ui-col ui-col">商品评分:{$data.shop.scores.goodsScore}</div> + <div class="ui-col ui-col">时效评分:{$data.shop.scores.timeScore}</div> + <div class="ui-col ui-col">服务评分:{$data.shop.scores.serviceScore}</div> + </div> + </div> + + </div> + + <div class="wst-shop-home-info"> + <ul class="shop-info"> + <li class="ui-nowrap ui-whitespace">商家地址:<span>{$data.shop.shopAddress}</span></li> + <li class="ui-nowrap ui-whitespace">商家电话:<span>{$data.shop.shopTel}</span></li> + <li class="ui-nowrap ui-whitespace">服务时间:<span>{$data.shop.serviceStartTime}-{$data.shop.serviceEndTime}</span></li> + <li class="ui-nowrap ui-whitespace">发票说明: + <span> + {if ($data.shop.isInvoice==1)} + 可开发票({$data.shop.invoiceRemarks}) + {else /} + 不支持发票 + {/if} + </span> + </li> + </ul> + <div class="shop-qrcode"> + <div id='qrcode'></div> + </div> + </div> + + </div> + + + + + </div> + </section> +{/block} + + +{block name="footer"}{/block} +{block name="js"} +<script src="__MOBILE__/js/qrcode.js"></script> + <script> + $(function(){ + var url= "{:url('mobile/shops/home',array('shopId'=>$data['shop']['shopId']),'',true)}"; + //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围'L','M','Q','H' + var qr = qrcode(9, 'H'); + qr.addData(url); + qr.make(); + $("#qrcode").html(qr.createImgTag()); + $('.wst-in-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + }); + goShopHome = function(sid){ + location.href=WST.U('mobile/shops/home','shopId='+sid,true); + } + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/shop_street.html b/hyhproject/mobile2/view/default/shop_street.html new file mode 100755 index 0000000..d9eb040 --- /dev/null +++ b/hyhproject/mobile2/view/default/shop_street.html @@ -0,0 +1,147 @@ +{extend name="default/base" /} +{block name="title"}店铺街 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/swiper.min.css"> +<link rel="stylesheet" href="__MOBILE__/css/shops_list.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索店铺" onsearch="WST.search(1)" autocomplete="off" disabled="disabled"> + </form> + </div> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$keyword}" id="keyword" autocomplete="off"> + <input type="hidden" name="" value="" id="condition" autocomplete="off"> + <input type="hidden" name="" value="" id="desc" autocomplete="off"> + <input type="hidden" name="" value="" id="catId" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-shl-ads"> + <div class="title">名铺抢购</div> + <div class="wst-shl-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="mo-ads-street" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <a href="{$vo.adURL}" class="adsImg"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($vo.adFile,2)}"></a> + </div> + {/wst:ads} + </div> + </div> + </div> + </div> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col"> + <div class="ui-select wst-shl-select choice active"> + <select onchange="javascript:orderSelect(this.value);"> + <option value="">主营</option> + {volist name="goodscats" id="g"} + <option value="{$g['catId']}">{$g['catName']}</option> + {/volist} + </select> + </div> + </div> + <div class="ui-col ui-col evaluate"> + <p class="choice sorts" status="down" onclick="javascript:orderCondition(this,1);">好评度<i class="down"></i></p> + </div> + </div> + <ul class="ui-tab-content"> + <li id="shops-list"></li> + </ul> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver wst-shl-list"> + <div class="ui-col"> + <div class="ui-row-flex"> + <div class="ui-col ui-col-2" > + <div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="goShopHome({{ d[i].shopId }})"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d[i].shopImg }}" title="{{ d[i].shopName }}"></a> + </div> + </div> + <div class="ui-col info" onclick="goToShop({{d[i].shopId}})"> + <div class="title ui-nowrap">{{d[i].shopName}}</div> + <p class="ui-nowrap">主营:{{ d[i].catshops }}</p> + <p><span>店铺评分:</span> + {{# for(var j=1; j<6; j++){ }} + {{# if(j <= d[i].totalScore){ }} + <i class="bright"></i> + {{# }else{ }} + <i class="dark"></i> + {{# } }} + {{# } }} + </p> + + </div> + <div class="ui-col ui-col-2 f-goshops" onclick="goShopHome({{d[i].shopId}})"> + <a href="javascript:void(0);" onclick="goToShop({{d[i].shopId}})"><span class="wst-action">进入店铺</span></a> + </div> + </div> + </div> + <div class="ui-col" style="margin-top:5px;"> + <div class="ui-row-flex goods-box"> + {{# var gLength = Math.min(d[i].goods.length,4) }} + {{# for(var g=0;g<gLength;++g){ }} + <div class="goods-item" > + {{# if(d[i].goods[g].goodsImg){ }} + <a href="javascript:void(0);" onclick="WST.intoGoods({{d[i].goods[g].goodsId}})"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{WST.replaceImg(d[i].goods[g].goodsImg,'_m_thumb')}}" > + <i class="goodsPrice ui-nowrap" >¥ {{d[i].goods[g].shopPrice}}</i> + </a> + {{# } }} + </div> + {{# } }} + </div> + </div> + <div class="wst-clear"></div> + </div> +{{# } }} +{{# }else{ }} +<div class="wst-prompt-icon"><img src="__MOBILE__/img/nothing-follow-shps.png"></div> +<div class="wst-prompt-info"> + <p>对不起,没有相关店铺。</p> +</div> +{{# } }} +</script> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(1);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索店铺" onsearch="WST.search(1)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:searchCondition(0);"> + <h4 class="ui-nowrap">全部店铺</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="goodscats" id="g"} + <li onclick="javascript:searchCondition({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> + <script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/shops_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/Users.php b/hyhproject/mobile2/view/default/users/Users.php new file mode 100755 index 0000000..bb06768 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/Users.php @@ -0,0 +1,604 @@ +<?php +namespace wstmart\mobile\controller; +use wstmart\mobile\model\Users as M; +use wstmart\mobile\model\Messages; +use wstmart\common\model\LogSms; +use wstmart\common\model\Users as MUsers; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'checklogin,login,register,getverify,toregister,forgetpass,forgetpasst,forgetpasss,forgetpassf,findpass,getfindphone,resetpass,getphoneverifycode,checkuserphone']// 访问这些except下的方法不需要执行前置操作 + ]; + /** + *跳转到合源惠联盟 mark 20170919 hsf + */ + + public function to_hyhlm(){ + session('to_hyhlm',null); + hook('toHyhlm'); + die; + } + + /** + * 会员登录页 + */ + public function login(){ + //如果已经登录了则直接跳去用户中心 + $USER = session('WST_USER'); + if(!empty($USER) && $USER['userId']!=''){ + $this->redirect("users/index"); + } + return $this->fetch('login'); + } + /** + * 会员登录 + */ + public function checkLogin(){ + $m = new M(); + $rs = $m->checkLogin(2); + $rs['url'] = session('WST_MO_WlADDRESS'); + return $rs; + } + + public function toRegister(){ + return $this->fetch('register'); + } + /** + * 会员注册 + */ + public function register(){ + $m = new M(); + $rs = $m->regist(2); + $rs['url'] = session('WST_MO_WlADDRESS'); + return $rs; + } + /** + * 手机号码是否存在 + */ + public function checkUserPhone(){ + $userPhone = input("post.userPhone"); + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已注册",-1); + }else{ + return WSTReturn("",1); + } + } + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $phoneVerify = rand(100000,999999); + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyCode',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + return $rv; + } + /** + * 会员中心 + */ + public function index(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + if($user['userName']=='') + $user['userName']=$user['loginName']; + $this->assign('user', $user); + //商城未读消息的数量 及 各订单状态数量 + $data = model('index')->getSysMsg('msg','order','follow','history'); + $this->assign('data',$data); + return $this->fetch('users/index'); + } + + /** + * 个人信息 + */ + public function edit(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + $this->assign('user', $user); + return $this->fetch('users/edit'); + } + /** + * 编辑个人信息 + */ + public function editUserInfo(){ + $m = new M(); + return $m->edit(); + } + /** + * 账户安全 + */ + public function security(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $userPhone = $user['userPhone']; + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $user['payPwd'] = empty($payPwd)?0:1; + $user['userPhone'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/index'); + } + /** + * 修改登录密码 + */ + public function editLoginPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_login_pass'); + } + public function editloginPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPass($userId); + } + /** + * 修改支付密码 + */ + public function editPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $user['payPwd'] = empty($payPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_pay_pass'); + } + public function editpayPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPayPass($userId); + } + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $user['backType'] = ($backType==1 && time()<floatval($timeVerify)+10*60)?1:0; + $this->assign('user', $user); + return $this->fetch('users/security/user_back_paypwd'); + } + /** + * 忘记支付密码:发送短信 + */ + public function backpayCode(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 忘记支付密码:验证短信 + */ + public function verifybackPay(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_backPaypwd_info.phoneVerify')){ + session('Type_backPaypwd',1); + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 忘记支付密码:重置密码 + */ + public function resetbackPay(){ + $m = new M(); + return $m->resetbackPay(); + } + /** + * 修改手机 + */ + public function editPhone(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/user_phone'); + } + /** + * 绑定手机:发送短信验证码 + */ + public function sendCodeTie(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'sendCodeTie',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function phoneEdit(){ + $phoneVerify = input("post.phoneCode"); + $process = input("post.process"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new M(); + $rs = $m->editPhone((int)session('WST_USER.userId'),session('Verify_info.userPhone')); + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 修改手机:发送短信验证码 + */ + public function sendCodeEdit(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = ''; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 修改手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + session('Edit_userPhone_Time',time()); + return WSTReturn("验证成功",1); + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!",-1); + } + public function editPhoneo(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $timeVerify = session('Edit_userPhone_Time'); + if(time()>floatval($timeVerify)+15*60){ + $user['phoneType'] = 1; + }else{ + $user['phoneType'] = 0; + } + $this->assign('user', $user); + return $this->fetch('users/security/user_phone'); + } + /** + * 用户退出 + */ + public function logout(){ + session('WST_USER',null); + setcookie("loginPwd", null); + session('WST_MO_WlADDRESS',null); + return WSTReturn("",1); + } + + /************************************************* 忘记密码 ********************************************************/ + // 页面过期/失效 + protected function expire($msg=''){ + $message = $msg?$msg:'页面已失效!'; + $html = '<h1>'.$message.'</h1><script>setTimeout(function(){location.href="'.url('mobile/users/index','','',true).'";},1000)</script>'; + return $this->display($html); + } + /** + * 忘记密码 + */ + public function forgetPass(){ + return $this->fetch('forget_pass'); + } + public function forgetPasst(){ + if(time()<floatval(session('findPass.findTime'))+30*60){ + $userId = session('findPass.userId'); + $m = new M(); + $info = $m->getById($userId); + if($info['userPhone']!='')$info['userPhone'] = WSTStrReplace($info['userPhone'],'*',3); + if($info['userEmail']!='')$info['userEmail'] = WSTStrReplace($info['userEmail'],'*',2,'@'); + $this->assign('forgetInfo',$info); + return $this->fetch('forget_pass2'); + }else{ + return $this->expire(); + } + } + + /** + * 重置密码 + */ + public function resetPass(){ + if(!session('findPass')){ + return $this->expire(); + } + return $this->fetch('forget_pass3'); + } + public function forgetPasss(){ + if(!session('findPass')){ + return $this->expire(); + } + $USER = session('findPass'); + if(empty($USER) && $USER['userId']!=''){ + $this->expire('请在同一浏览器操作!'); + } + $uId = session('findPass.userId'); + $key = session("findPass.key"); + // 验证邮箱中的验证码 + $secretCode = input('secretCode'); + if($key==$secretCode){ + session('REST_userId',$uId); + session('REST_success','1'); + return WSTReturn('验证成功',1); + }else{ + return WSTReturn('校验码错误',-1); + } + + } + /** + * 找回密码 + */ + public function findPass(){ + //禁止缓存 + header('Cache-Control:no-cache,must-revalidate'); + header('Pragma:no-cache'); + $code = input("post.verifyCode"); + $step = input("post.step/d"); + switch ($step) { + case 1:#第一步,验证身份 + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + $loginName = input("post.loginName"); + $rs = WSTCheckLoginKey($loginName); + if($rs["status"]==1){ + return WSTReturn("用户名不存在!"); + exit(); + } + $m = new M(); + $info = $m->checkAndGetLoginInfo($loginName); + if ($info != false) { + session('findPass',array('userId'=>$info['userId'],'loginName'=>$loginName,'userPhone'=>$info['userPhone'],'userEmail'=>$info['userEmail'],'loginSecret'=>$info['loginSecret'],'findTime'=>time())); + return WSTReturn("操作成功",1); + }else return WSTReturn("用户名不存在!"); + break; + case 2:#第二步,验证方式 + if (session('findPass.loginName') != null ){ + if(input("post.modes")==1){ + if ( session('findPass.userPhone') == null) { + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = input("post.Checkcode"); + if(!$phoneVerify){ + return WSTReturn('校验码不能为空!',-1); + } + return $this->checkfindPhone($phoneVerify); + }else{ + if (session('findPass.userEmail')==null) { + return WSTReturn('你没有预留邮箱,请通过手机号码找回密码!',-1); + } + if(!WSTVerifyCheck($code)){ + return WSTReturn('验证码错误!',-1); + } + return $this->getfindEmail(); + } + }else return $this->expire(); + break; + case 3:#第三步,设置新密码 + $resetPass = session('REST_success'); + if($resetPass != 1)return $this->expire(); + $loginPwd = input("post.loginPwd"); + $repassword = input("post.repassword"); + $decrypt_data = WSTRSA($loginPwd); + $decrypt_data2 = WSTRSA($repassword); + if($decrypt_data['status']==1 && $decrypt_data2['status']==1){ + $loginPwd = $decrypt_data['data']; + $repassword = $decrypt_data2['data']; + }else{ + return WSTReturn('设置失败'); + } + if ($loginPwd == $repassword) { + $m = new M(); + $rs = $m->resetPass(); + if($rs['status']==1){ + return $rs; + }else{ + return $rs; + } + }else return WSTReturn('两次密码不同!',-1); + break; + default: + return $this->expire(); + break; + } + } + /** + * 手机验证码获取 + */ + public function getfindPhone(){ + session('WST_USER',session('findPass.userId')); + if(session('findPass.userPhone')==''){ + return WSTReturn('你没有预留手机号码,请通过邮箱方式找回密码!',-1); + } + $phoneVerify = rand(100000,999999); + session('WST_USER',null); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,session('findPass.userPhone'),$params,'getPhoneVerify',$phoneVerify); + } + if($rv['status']==1){ + // 记录发送短信的时间,用于验证是否过期 + session('REST_Time',time()); + $USER = ''; + $USER['phoneVerify'] = $phoneVerify; + $USER['time'] = time(); + session('findPhone',$USER); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 手机验证码检测 + * -1 错误,1正确 + */ + public function checkfindPhone($phoneVerify){ + if(!session('findPhone.phoneVerify') || time()>floatval(session('findPhone.time'))+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if (session('findPhone.phoneVerify') == $phoneVerify ) { + $fuserId = session('findPass.userId'); + if(!empty($fuserId)){ + session('REST_userId',$fuserId); + session('REST_success','1'); + $rs['status'] = 1; + $rs['url'] = url('mobile/users/resetPass'); + return $rs; + } + return WSTReturn('无效用户',-1); + } + return WSTReturn('校验码错误!',-1); + } + /** + * 发送验证邮件/找回密码 + */ + public function getfindEmail(){ + $code = rand(0,999999); + $sendRs = ['status'=>-1,'msg'=>'邮件发送失败']; + $tpl = WSTMsgTemplates('EMAIL_FOTGET'); + if( $tpl['tplContent']!='' && $tpl['status']=='1'){ + $find = ['${LOGIN_NAME}','${SEND_TIME}','${VERFIY_CODE}','${VERFIY_TIME}']; + $replace = [session('findPass.loginName'),date('Y-m-d H:i:s'),$code,30]; + $sendRs = WSTSendMail(session('findPass.userEmail'),'密码重置',str_replace($find,$replace,$tpl['content'])); + } + if($sendRs['status']==1){ + $uId = session('findPass.userId'); + session("findPass.key", $code); + // 发起重置密码的时间; + session('REST_Time',time()); + return WSTReturn("发送成功",1); + }else{ + return WSTReturn($sendRs['msg'],-1); + } + } + public function userSet(){ + return $this->fetch('users/userset/list'); + } + public function aboutUs(){ + return $this->fetch('users/userset/about'); + } + // mark by cheng 添加手机版分享20180320 + public function share(){ + $name = session('WST_USER.loginName'); + $data['url'] = 'http://www.heyuanhui.cn/mregister?pName='.$name; + $data['title'] = '分享好友'; + $data['desc'] = '分享好友注册'; + $this->assign('data',$data); + return $this->fetch('users/share'); + } +} diff --git a/hyhproject/mobile2/view/default/users/cashconfigs/cashconfigs.js b/hyhproject/mobile2/view/default/users/cashconfigs/cashconfigs.js new file mode 100755 index 0000000..ffd84ac --- /dev/null +++ b/hyhproject/mobile2/view/default/users/cashconfigs/cashconfigs.js @@ -0,0 +1,251 @@ +jQuery.noConflict(); +// 获取提现记录 +function getCashConfigs(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/cashconfigs/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#listBox').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-account.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>没有提现账户</p>'; + html += '</div>'; + $('#listBox').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getCashConfigs(); + WST.initFooter('user'); + // 弹出层 + $('#modal-large').css({'top':0,'margin-top':0}); + var h = WST.pageHeight(); + $("#frame").css('bottom','-'+h/2); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getCashConfigs(); + } + } + }); +}); + + + + + +//新增或编辑提现账号 +function editAddress(id){ + $('#accTargetId').val(''); + $('#accUser').val(''); + $('#accNo').val(''); + $('#accAreaId').val(''); + $('#addresst').html('请选择地址'); + $('.wst-ad-submit .button').attr('onclick','javascript:saveConfig('+id+');'); + if(id>0){ + $('.iziModal-header-title').html('修改提现账号'); + $.post(WST.U('mobile/cashConfigs/getById'), {id:id}, function(data){ + var info = WST.toJson(data); + if(info){ + $('#accTargetId').val(info.accTargetId); + $('#accUser').val(info.accUser); + $('#accNo').val(info.accNo); + $('#accAreaId').val(info.accAreaId); + $('#areaName').html($('#addr_'+id).val()); + } + addressInfo= null; + }); + }else{ + $('.iziModal-header-title').html('新增提现账号'); + } + jQuery('#modal-large').iziModal('open'); +} +jQuery("#modal-large").iziModal({ + title: "新增提现账号", + subtitle: "", + iconClass: 'icon-chat', + overlayColor: 'rgba(0, 0 0, 0.6)', + headerColor: '#ffffff' +}); + + +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + $.post(WST.U('mobile/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + var level = parseInt(obj.attr('level'),10); + $('.area_'+level).addClass('hide'); + var level = level+1; + html.push('<div id="'+tid+'" class="list '+opts.className+' area_'+level+'" areaId="0" level="'+level+'">'); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<p onclick='javascript:inChoice(this,\""+tid+"\","+tmp.areaId+","+level+");'>"+tmp.areaName+"</p>"); + } + html.push('</div>'); + $(html.join('')).insertAfter('#'+opts.id); + var h = WST.pageHeight(); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + $(".wst-fr-box .option").append('<p class="ui-nowrap-flex term active_'+level+' active" onclick="javascript:inOption(this,'+level+')">请选择</p>'); + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + $('#accAreaId').val(opts.lastVal); + var ht = ''; + $('.wst-fr-box .term').each(function(){ + ht += $(this).html(); + }); + $('#areaName').html(ht); + dataHide(); + } + }); +} + +//地址选择 +function inOption(obj,n){ + $(obj).addClass('active').siblings().removeClass('active'); + $('.area_'+n).removeClass('hide').siblings('.list').addClass('hide'); + var level = $('#level').val(); + var n = n+1; + for(var i=n; i<=level; i++){ + $('.area_'+i).remove(); + $('.active_'+i).remove(); + } +} + +function inChoice(obj,id,val,level){ + $('#level').val((level+1)); + $(obj).addClass('active').siblings().removeClass('active'); + $('#'+id).attr('areaId',val); + $('.active_'+level).removeClass('active').html($(obj).html()); + WST.ITAreas({id:id,val:val,className:'j-areas'}); +} + + +//弹框 +function dataShow(){ + jQuery('#frame').show(); + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); + setTimeout(function(){ + jQuery('#frame').hide(); + },500); +} + + + +//保存 +function saveConfig(cId){ + var accUser = $('#accUser').val(); + var accNo = $('#accNo').val(); + var areaId = $('#areaId').val(); + var accAreaId = $('#accAreaId').val(); + var accTargetId = $('#accTargetId').val(); + + if(accTargetId==''){ + WST.msg('请选择账户类型','info'); + $('#accTargetId').focus(); + return false; + } + + if(accAreaId==''){ + WST.msg('请选择地址','info'); + return false; + } + + if(accUser==''){ + WST.msg('持卡人不能为空','info'); + $('#accUser').focus(); + return false; + } + if(accNo==''){ + WST.msg('卡号不能为空','info'); + return false; + } + + var param = {}; + param.id = cId; + param.accAreaId = accAreaId; + param.accUser = accUser; + param.accNo = accNo; + param.accTargetId = accTargetId; + $('.wst-ad-submit .button').addClass("active").attr('disabled', 'disabled'); + var act = (cId>0)?'edit':'add'; + $.post(WST.U('mobile/cashconfigs/'+act), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + history.go(0); + },1000); + }else{ + WST.msg(json.msg,'warn'); + setTimeout(function(){ + $('.wst-ad-submit .button').removeAttr('disabled').removeClass("active"); + },1500); + } + data = json = null; + }); +} + +//删除提现账号 +function del(id){ + WST.dialog('确定删除吗?','toDel('+id+')'); +} +//删除提现账号 +function toDel(id){ + $.post(WST.U('mobile/cashconfigs/del'), {id:id}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + $('#listBox').html(' '); + $('#currPage').val(0) + getCashConfigs(); + }else{ + WST.msg(json.msg,'warn'); + } + WST.dialogHide('prompt'); + data = json = null; + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/cashconfigs/edit.html b/hyhproject/mobile2/view/default/users/cashconfigs/edit.html new file mode 100755 index 0000000..1804a04 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/cashconfigs/edit.html @@ -0,0 +1,48 @@ + <div id="modal-large" class="iziModal"> + <input type="hidden" name="" value="" id="accAreaId" autocomplete="off"> + <div class="wst-ad-form"> + <div class="ui-form-itemin"> + <label class="word">账户类型:</label> + <select name="accTargetId" id="accTargetId" class="wst-ca-choice"> + <option value="">请选择</option> + {volist name="$banks" id="b"} + <option value="{$b['bankId']}">{$b['bankName']}</option> + {/volist} + </select> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">账户地址:</label> + <div id="areaName" class="ui-nowrap-flex address" onclick="javascript:dataShow();">请选择账户地址</div> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">持卡人:</label><input class="ui-border-binte" id="accUser" type="text" placeholder="请填写持卡人姓名" maxLength="20"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">卡号:</label> + <input class="ui-border-binte" id="accNo" type="text" maxLength="20" placeholder="请填写银行卡号" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <div class="wst-ad-line"><p></p></div> + </div> + <div class="wst-ad-submit"><button class="ui-btn-lg button" onclick="javascript:saveAddress(0);">保存</button></div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 地址框 */} +<div class="wst-fr-box" id="frame" style="display:none;"> + <input type="hidden" name="" value="" id="level" autocomplete="off"> + <div class="title"><span>账户地址</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <div class="option"> + <p class="ui-nowrap-flex term active_0 active" onclick="javascript:inOption(this,0)">请选择</p> + </div> + <div class="wst-clear"></div> + <div id="area_0" class="list j-areas area_0" areaId="0" level="0"> + {volist name="area" id="ar"} + <p onclick="javascript:inChoice(this,'area_0',{$ar['areaId']},0);">{$ar['areaName']}</p> + {/volist} + </div> + </div> +</div> + </div> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/cashconfigs/list.html b/hyhproject/mobile2/view/default/users/cashconfigs/list.html new file mode 100755 index 0000000..9c8cba8 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/cashconfigs/list.html @@ -0,0 +1,55 @@ +{extend name="default/base" /} +{block name="title"}我的提现账户 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/iziModal.css?v={$v}"> +<link rel="stylesheet" href="__MOBILE__/css/cashconfigs.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的提现账户</h1> + <span class="add" onclick="editAddress()">添加</span> + </header> +{/block} +{block name="main"} + + + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<script type="text/html" id="list"> + {{# for(var i=0;i<d.length;++i){ }} + <ul class="ui-row" > + <li class="ui-col ui-col-80" onclick="editAddress({{d[i].id}})"> + <input type="hidden" id="addr_{{d[i].id}}" value="{{d[i].areaName}}"> + <p class="wst-ca-accno">{{d[i].accNo}}</p> + <p class="wst-ca-info"> 持卡人姓名:{{d[i].accUser}}</p> + <p class="wst-ca-info"> 开户行:{{d[i].bankName}}</p> + </li> + <li class="ui-col ui-col-20" onclick="del({{d[i].id}})"><p class="c-tr"><span class="delete-icon"></span>删除<p></li> + </ul> + {{# } }} +</script> +<section class="ui-container" id="listBox"> + +</section> + + + + +{include file="default/dialog" /}<!-- 对话框模板 --> +{include file="default/users/cashconfigs/edit" /}<!-- 新增/编辑收货地址模板 --> + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/izimodal/iziModal.js'></script> +<script type='text/javascript' src='__MOBILE__/users/cashconfigs/cashconfigs.js?v={$v}'></script> +{/block} + + + + + + + diff --git a/hyhproject/mobile2/view/default/users/cashdraws/cashdraws.js b/hyhproject/mobile2/view/default/users/cashdraws/cashdraws.js new file mode 100755 index 0000000..bb01e75 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/cashdraws/cashdraws.js @@ -0,0 +1,47 @@ +jQuery.noConflict(); +// 获取提现记录 +function getCashDraws(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/cashdraws/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getCashDraws(); + WST.initFooter('user'); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getCashDraws(); + } + } + }); +}); diff --git a/hyhproject/mobile2/view/default/users/cashdraws/list.html b/hyhproject/mobile2/view/default/users/cashdraws/list.html new file mode 100755 index 0000000..bc4f5ca --- /dev/null +++ b/hyhproject/mobile2/view/default/users/cashdraws/list.html @@ -0,0 +1,52 @@ +{extend name="default/base" /} +{block name="title"}提现记录 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/cashdraws.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>提现记录</h1> + </header> +{/block} +{block name="main"} + +<script type="text/html" id="scoreList"> +<ul class="ui-row score-detail"> +{{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75"> + <p>{{d[i].accUser}}</p> + <p>{{d[i].accTargetName}}{{d[i].accAreaName}}</p> + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 score-text"> + {{#if(d[i].cashSatus==1){}} + <span style="color:green;">已通过</span> + {{#}else if(d[i].cashSatus==-1){}} + 失败 + {{#}else{}} + <span style="color: #59595c;">待处理</span> + {{#}}} + <br /> + - {{d[i].money}} + </li> + {{#if(d[i].cashSatus==-1){}} + <li class="ui-col">提现失败原因:{{d[i].cashRemarks}}</li> + {{#}}} + <div class="wst-clear"></div> + <div class="score-line"></div> +{{# } }} +</ul> +</script> + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<section class="ui-container"> + <div id="score-list"></div> +</section> + + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/cashdraws/cashdraws.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/edit.html b/hyhproject/mobile2/view/default/users/edit.html new file mode 100755 index 0000000..7bae83a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/edit.html @@ -0,0 +1,127 @@ +{extend name="default/base" /} +{block name="title"}账户管理 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/userinfo.css?v={$v}"> +{/block} +{block name="header"} + <div id="useri_infos"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <a onclick="history.back()"><i class="ui-icon-return return_users"></i></a><h1 class="useri_info">账户管理</h1> + <i onclick="javascript:closeUploadArea()" style="display:none;font-size: 0.15rem;" id="upload_close">关闭</i> + <a href="javascript:void(0);" style="display:none;float:right;font-size: 0.15rem;" id="upload_button">上传</a> + </header> +{/block} +{block name="main"} + <section class="ui-container" id="useri_info"> + <ul class="ui-list ui-list-one ui-list-link wst-ed-info"> + <li> + <div class="ui-list-info"> + <h4 class="ui-nowrap" id="chooseImages">头像</h4> + <input type="file" id="uploadImg" class="uploadfile-input" accept="image/*"> + <div class="ui-list-thumb" id="previewImages" style="width: 65px;"> + <span> + <img src="__IMGURL__/{:WSTUserPhoto($user['userPhoto'])}" class="wst-useri_portrait" id="imgurl"> + </span> + </div> + </div> + </li> + </ul> + <div class="wst-useri_line"></div> + <ul class="ui-list ui-list-text wst-ed-info"> + <li> + <h4 class="ui-nowrap">用户名</h4> + <div class="ui-txt-info">{$user['loginName']}</div> + </li> + </ul> + <div class="wst-useri_line"></div> + <ul class="ui-list ui-list-text ui-list-link wst-ed-info"> + <li onclick="javascript:openNickName();"> + <h4 class="ui-nowrap">昵称</h4> + <div class="ui-txt-info" id="nickname">{$user['userName']}</div> + </li> + <div class="wst-useri_line"></div> + <li onclick="javascript:openUserSex();"> + <h4 class="ui-nowrap">性别</h4> + <?php $usersex = array('保密','男','女');?> + <div class="ui-txt-info" id="usersex"><?php echo $usersex[$user['userSex']];?></div> + </li> + </ul> + <div class="wst-useri_line"></div> + </section> + <sction class="ui-container" id="upload_modal"> + <div class="upload-modal"> + <div id="clipArea" class="clipArea"></div> + <input type="hidden" id="imgData" autocomplete="off"> + </div> + </sction> + </div> + <div id="useri_nickname" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnUserinfo()"></i><h1>修改昵称</h1> + </header> + <section class="ui-container" style="height:80%;"> + <div class="wst-useri_determine"> + <input type="text" id="userName" placeholder="昵称"> + </div> + + </section> + <footer> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-ed-button" onclick="javascript:editNickName()"> + 确定 + </button> + </div> + </footer> + </div> + <div id="useri_sex" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnUserinfo()"></i><h1>修改性别</h1> + </header> + <section class="ui-container" id="useri_sex"> + <ul class="ui-list wst-listse wst-listse1" onclick="javascript:eidtUserSex(this, 0);"> + <li> + <div class="wst-list-infose1"> + <span>保密</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==0){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + <ul class="ui-list wst-listse wst-listse2" onclick="javascript:eidtUserSex(this, 1);"> + <li> + <div class="wst-list-infose1"> + <span>男</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==1){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + <ul class="ui-list wst-listse wst-listse3" onclick="javascript:eidtUserSex(this, 2);"> + <li> + <div class="wst-list-infose1"> + <span>女</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==2){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + </section> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/photoclip/iscroll-zoom.js'></script> +<script type='text/javascript' src='__MOBILE__/js/photoclip/hammer.js'></script> +<script type='text/javascript' src='__MOBILE__/js/photoclip/jquery.photoClip.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/photoclip/upload.hpictures.js'></script> +<script type='text/javascript' src='__MOBILE__/users/user.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/favorites/favorite_shop.js b/hyhproject/mobile2/view/default/users/favorites/favorite_shop.js new file mode 100755 index 0000000..e3fa0bf --- /dev/null +++ b/hyhproject/mobile2/view/default/users/favorites/favorite_shop.js @@ -0,0 +1,99 @@ +// 获取关注的店铺 +function getFavorites(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/favorites/listShopQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shopBox').html(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-follow-shps.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>您还没有关注店铺。</p>'; + html += '</div>'; + $('#shopBox').html(html); + } + imgShop('j-imgAdapt'); + imgShop('goodsImg'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); + + +} +function goToShop(sid){ + location.href=WST.U('mobile/shops/home','shopId='+sid); +} +// 全选 +function checkAll(obj){ + var chk = $(obj).prop('checked'); + $('.s-active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +// 取消关注 +function cancelFavorite(){ + WST.dialogHide('prompt'); + var fids = new Array(); + $('.s-active').each(function(k,v){ + if($(this).attr('checked')){ + fids.push($(this).attr('fid')); + } + }); + fids = fids.join(','); + if(fids==''){ + WST.msg('请先选择店铺','info'); + return; + } + $.post(WST.U('mobile/favorites/cancel'),{id:fids,type:1},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#currPage').val('0') + getFavorites(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getFavorites(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getFavorites(); + } + } + }); +}); + +//适应图片大小正方形 +function imgShop(name){ + var w = $('.'+name).width(); + if(name == 'j-imgAdapt'){ + $('.'+name).css({"width": w+"px","height": w+"px"}); + }else{ + $('.'+name).css({"width": w+"px","height": w+20+"px"}); + } + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a .goodsPrice').css({"width": w+"px"}); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/favorites/favorites.js b/hyhproject/mobile2/view/default/users/favorites/favorites.js new file mode 100755 index 0000000..100a75c --- /dev/null +++ b/hyhproject/mobile2/view/default/users/favorites/favorites.js @@ -0,0 +1,95 @@ +// 获取关注的商品 +function getFavorites(){ + $('#Load').show(); + loading = true; + var param = {}; + param.id = $('#catId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#searchKey').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/favorites/listGoodsQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('fGoods').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#goods-list').html(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-follow-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>您还没有关注商品。</p>'; + html += '</div>'; + $('#goods-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +// 全选 +function checkAll(obj){ + var chk = $(obj).attr('checked'); + $('.active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +// 取消关注 +function cancelFavorite(){ + WST.dialogHide('prompt'); + var gids = new Array(); + $('.active').each(function(k,v){ + if($(this).attr('checked')){ + gids.push($(this).attr('gid')); + } + }); + gids = gids.join(','); + if(gids==''){ + WST.msg('请先选择商品','info'); + return; + } + $.post(WST.U('mobile/favorites/cancel'),{id:gids,type:0},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#currPage').val('0') + getFavorites(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getFavorites(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getFavorites(); + } + } + }); +}); + + + +function addCart(goodsId){ + $.post(WST.U('mobile/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + }else{ + WST.msg(json.msg,'info'); + } + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/favorites/list_goods.html b/hyhproject/mobile2/view/default/users/favorites/list_goods.html new file mode 100755 index 0000000..0c711a1 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/favorites/list_goods.html @@ -0,0 +1,73 @@ +{extend name="default/base" /} +{block name="title"}我的关注 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/favorites.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>关注商品</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:45px; border-top: 1px solid #e0e0e0;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger" onclick="WST.dialog('确认要取消关注吗','cancelFavorite()');"> + 取消关注 + </button> + </div> + </div> + </div> + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <script id="fGoods" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="ui-row-flex wst-shl-list" > + <label class="ui-checkbox"> + <input class="active" type="checkbox" gId="{{d[i].favoriteId}}" onclick="javascript:WST.changeIconStatus($(this), 1);"> + </label> + + <div class="ui-col"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d[i].goodsId}});"> + <img src="__IMGURL__/{{WST.conf.GOODS_LOGO}}" data-echo="__IMGURL__/{{d[i].goodsImg}}" title="{{d[i].shopName}}"></a></div> + </div> + <div class="ui-col ui-col-2 info"> + <div class="title ui-nowrap-multi ui-whitespace" onclick="javascript:WST.intoGoods({{d[i].goodsId}});">{{d[i].goodsName}}</div> + <p class="price"><span>¥ </span>{{d[i].shopPrice}}</p> + <p class="deal">成交数:{{d[i].saleNum}}</p><span class="add-cart" onclick="addCart({{d[i].goodsId}})"></span> + </div> + </div> + {{# } }} + </script> + <section class="ui-container info-prompt"> + <ul class="ui-tab-content"> + <li id="goods-list"></li> + </ul> + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/favorites/favorites.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/favorites/list_shops.html b/hyhproject/mobile2/view/default/users/favorites/list_shops.html new file mode 100755 index 0000000..9bc0bda --- /dev/null +++ b/hyhproject/mobile2/view/default/users/favorites/list_shops.html @@ -0,0 +1,93 @@ +{extend name="default/base" /} +{block name="title"}关注店铺 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/favorites.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>关注店铺</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:45px; border-top: 1px solid #e0e0e0;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger" onclick="WST.dialog('确认要取消关注吗','cancelFavorite()');"> + 取消关注 + </button> + </div> + </div> + </div> + + + + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver shop-box"> + <div class="ui-col f-shop-header"> + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-3"> + <label class="ui-checkbox f-chk"> + <input class="s-active" type="checkbox" fId="{{d[i].favoriteId}}" onclick="javascript:WST.changeIconStatus($(this), 1);"> + </label> + <div class="shopImg j-imgAdapt"> + <a href="javascript:void(0);" onclick="goToShop({{d[i].shopId}})"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{ d[i].shopImg }}" title="{{ d[i].shopName }}"></a> + </div> + </div> + <div class="ui-col ui-col-2" onclick="goToShop({{d[i].shopId}})"> + <div class="f-shopname ui-nowrap ui-whitespace">{{d[i].shopName}}</div> + + </div> + <div class="ui-col ui-col-3 f-goshops" onclick="goToShop({{d[i].shopId}})"> + <a href="javascript:void(0);" onclick="goToShop({{d[i].shopId}})"><span class="wst-action">进入店铺</span></a> + </div> + </div> + </div> + <div class="ui-col"> + <div class="ui-row-flex goods-box"> + {{# var gLength = Math.min(d[i].goods.length,4) }} + {{# for(var g=0;g<gLength;++g){ }} + <div class="goodsImg"><a href="javascript:void(0);" onclick="WST.intoGoods({{d[i].goods[g].goodsId}})"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i].goods[g].goodsImg}}"> + <i class="goodsPrice ui-nowrap" >¥ {{d[i].goods[g].shopPrice}}</i></a> + </div> + {{# } }} + </div> + </div> + <div class="wst-clear"></div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/favorites/favorite_shop.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/global.css b/hyhproject/mobile2/view/default/users/global.css new file mode 100755 index 0000000..4d439de --- /dev/null +++ b/hyhproject/mobile2/view/default/users/global.css @@ -0,0 +1,51 @@ +@charset "utf-8"; +/* CSS Document */ + + +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form, +fieldset,input,textarea,p,blockquote,th,td { + margin:0; + padding:0; + +} +table { + border-collapse:collapse; /*让表格边框细线*/ + border-spacing:0; /*清除边框间距*/ +} +fieldset,img { + border:0 none; /*有些浏览器默认这些标签有边框,所以要清除默认边框*/ + display:block; +} +address,caption,cite,code,dfn,em,i,u,b,strong,th,var { + font-style:normal; + font-weight:normal; + /*清除标签默认文本样式和加粗*/ +} +input,textarea{ + outline:0 none;/*去掉文本框的默认轮廓线*/ +} +ol,ul { + list-style:none; /*清除列表默认样式*/ +} +caption,th { + text-align:left; /*清除标签默认文本居中对齐*/ +} +h1,h2,h3,h4,h5,h6 { + font-size:100%; + font-weight:normal; /*清除标题标签的默认样式*/ +} +a{ + text-decoration:none;/*大部分页面中的链接没有下划线*/ +} + +.clearfix:after{ + height:0; + content:" "; + display:block; + overflow:hidden; + clear:both; + } +.clearfix{ + zoom:1;/*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + diff --git a/hyhproject/mobile2/view/default/users/history/history.js b/hyhproject/mobile2/view/default/users/history/history.js new file mode 100755 index 0000000..e749cee --- /dev/null +++ b/hyhproject/mobile2/view/default/users/history/history.js @@ -0,0 +1,48 @@ +// 获取浏览记录 +function getHistory(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/goods/historyQuery'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#listBox').append(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-history.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无浏览记录</p>'; + html += '<button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button>'; + html += '</div>'; + $('#listBox').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter(); + getHistory(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getHistory(); + } + } + }); +}); + diff --git a/hyhproject/mobile2/view/default/users/history/list.html b/hyhproject/mobile2/view/default/users/history/list.html new file mode 100755 index 0000000..43fbb41 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/history/list.html @@ -0,0 +1,47 @@ +{extend name="default/base" /} +{block name="title"}浏览记录 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/history.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>浏览记录</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<script type="text/html" id="list"> + {{# for(var i=0;i<d.length;++i){ }} + <div class="ui-row-flex goods-item"> + <div class="ui-col"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d[i]['goodsId']}});"><img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d[i]['goodsImg']}}"></a> + </div> + </div> + <div class="ui-col ui-col-3" onclick="javascript:WST.intoGoods({{d[i]['goodsId']}});"> + <div class="ui-row-flex ui-row-flex-ver wst-info"> + <div class="goodsTitle ui-nowrap-multi">{{d[i].goodsName}}</div> + <div> + <p class="price"><span>¥ </span>{{d[i].shopPrice}}</p> + <p class="goods-info">成交数:{{d[i].saleNum}}</p> + </div> + </div> + </div> + </div> + {{# } }} +</script> + + <section class="ui-container" id="listBox"> + </section> + + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/history/history.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/index.html b/hyhproject/mobile2/view/default/users/index.html new file mode 100755 index 0000000..72bafca --- /dev/null +++ b/hyhproject/mobile2/view/default/users/index.html @@ -0,0 +1,242 @@ +{extend name="default/base" /} +{block name="title"}我的 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/user.css?v={$v}"> +{/block} +{block name="header"}{/block} +{block name="main"} + <section class="ui-container" id="user"> + <div class="wst-users_info"> + <a href="{:url('mobile/messages/index')}"><i class="wst-msg-icon"> + {if ($data['message']['num']>0)} + <span class="number" id="msgNum">{$data['message']['num']}</span> + {/if} + </i></a> + <i class="ui-icon-set wst-info-icon" onclick="location.href='{:url('mobile/users/userset')}'" ></i> + <div class="ui-row-flex" style="height:0.7rem"> + <div class="ui-col ui-col-2"> + <div class="wst-users_infol" id="previewImages"> + <img src="__IMGURL__/{:WSTUserPhoto($user['userPhoto'])}" class="wst-useri_portrait" id="imgurl"> + </div> + <p class="wst-users_infor wst-users_infortop"> + {:$user['userName']?$user['userName']:$user['loginName']} + {if ($user['ranks']['rankName']!='')}<img src="__IMGURL__/{$user['ranks']['userrankImg']}">{/if} + </p> + {if ($user['ranks']['rankName']!='')} + <p class="wst-users_infor wst-users_inforbo">{$user['ranks']['rankName']}</p> + {/if} + </div> + <div class="ui-col"> + {php}$signScore=explode(",",WSTConf('CONF.signScore'));{/php} + {if(WSTConf('CONF.signScoreSwitch')==1 && $signScore[0]>0)} + <div class="wst-us-sign"> + {if(session('WST_USER.signScoreTime')==date('Y-m-d'))} + <a id="j-sign" class="sign sign2" disabled="disabled"></a> + {else} + <a id="j-sign" class="sign" onclick="javascript:inSign();"></a> + {/if} + </div> + {/if} + </div> + </div> + </div> + + {:hook('mobileDocumentUserIndex')} + + {/* 商家订单管理 */} + {if ($user['userType']==1)} + <?php $shopMenus = WSTShopOrderMenus();?> + {if (count($shopMenus)>0)} + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="order-icon"></i>商家订单管理</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('mobile/orders/sellerorder')}'">查看全部订单 ></li> + </ul> + </div> + {/if} + {/if} + + {/*用户订单管理 */} + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="order-icon"></i>我的订单</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('mobile/orders/index')}'">查看全部订单 ></li> + </ul> + </div> + <div class="ui-row-flex ui-whitespace wst-users_icon"> + + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitPay'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon1"></i> + {if ($data['order']['waitPay']>0)} + <span class="ui-badge-corner wait-payment ui-nowrap-flex ui-whitespace" id="waitPay">{$data['order']['waitPay']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待付款</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitDeliver'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon2"></i> + {if ($data['order']['waitSend']>0)} + <span class="ui-badge-corner wait-payment" id="waitSend">{$data['order']['waitSend']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待发货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitReceive'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon3"></i> + {if ($data['order']['waitReceive']>0)} + <span class="ui-badge-corner wait-payment" id="waitReceive">{$data['order']['waitReceive']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待收货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitAppraise'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon4"></i> + {if ($data['order']['waitAppraise']>0)} + <span class="ui-badge-corner wait-payment" id="waitAppraise">{$data['order']['waitAppraise']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待评价</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'abnormal'])}"> + <p style="display:none;"><i class="wst-users_icon5"></i></p><p><i class="wst-users_icon5"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">取消拒收</span> + </a> + </div> + + </div> + + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="wallet-icon"></i>我的财产</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('mobile/logmoneys/usermoneys')}'">资金管理 ></li> + </ul> + </div> + <div class="ui-row-flex wst-users_capital"> + <div class="ui-col ui-col"> + <a href="{:url('mobile/logmoneys/usermoneys')}"> + <p class="ui-badge-wrap ui-nowrap"><span>¥ </span>{$user['userMoney']}</p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">余额</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/userscores/index')}"> + <p class="ui-badge-wrap ui-nowrap" id="currentScore">{$user['userScore']}</p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">积分</span> + </a> + </div> + {:hook('mobileDocumentUserIndexTerm')} + </div> + + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="tool-icon"></i>必备工具</li> + </ul> + </div> + <ul class="ui-row" style="background: #fff;"> + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/favorites/goods')}"> + <p><i class="user-icon1"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">关注商品</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/favorites/shops')}"> + <p><i class="user-icon2"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">关注店铺</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/goods/history')}"> + <p><i class="user-icon3"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">浏览记录</span> + </a> + </li> + + <!-- <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/users/security')}"> + <p><i class="user-icon4"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">账户安全</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/logmoneys/usermoneys')}"> + <p><i class="user-icon5"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">资金管理</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/userscores/index')}"> + <p><i class="user-icon6"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的惠宝</span> + </a> + </li> + + <!-- <li class="ui-col ui-col-25 user-icon-box border-b"> + <a href="#"> + <i class="user-icon7"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的礼券</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box border-b"> + <a href="#"> + <i class="user-icon8"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的客服</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('mobile/useraddress/index')}"> + <p><i class="user-icon9"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">地址管理</span> + </a> + </li> + + <!-- <li class="ui-col ui-col-25 user-icon-box ui-center-hor"> + <a href="{:url('mobile/messages/index')}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="user-icon10"></i> + {if ($data['message']['num']>0)} + <span class="ui-badge-corner wait-payment" id="msgNum">{$data['message']['num']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">商城消息</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box ui-center-hor"> + <a href="{:url('mobile/ordercomplains/index')}"> + <p><i class="user-icon11"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">订单投诉</span> + </a> + </li> + {:hook('mobileDocumentUserIndexTools')} + </ul> + <div class="ui-btn-wrap logout"> + </div> + + </section> +{/block} +{block name="include"} + {include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/user.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/index1.html b/hyhproject/mobile2/view/default/users/index1.html new file mode 100755 index 0000000..029d409 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/index1.html @@ -0,0 +1,127 @@ +{extend name="default/base" /} {block name="title"}我的 - {__block__}{/block} {block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/user.css?v={$v}"> {/block} {block name="header"} {/block} {block name="main"} +<section class="ui-container" id="user"> + <div class="ui-row-flex wst-users_info"> + <div class="ui-col"> + <div class="wst-users_infol" id="previewImages"> + <img src="__IMGURL__{:WSTUserPhoto($user['userPhoto'])}" class="wst-useri_portrait" id="imgurl"> + <span class="span_my">{:$user['userName']?$user['userName']:$user['loginName']}</span> + </div> + </div> + <!--<div class="ui-col ui-col-2 wst-users_infor"> + <span class="wst-users_infor wst-users_infortop ui-nowrap-flex ui-whitespace">{:$user['userName']?$user['userName']:$user['loginName']}</span> + <span class="wst-users_infor ui-nowrap-flex ui-whitespace" style="height:35px;width:100%;"> + {if ($user['ranks']['rankName']!='')} + <div class="user-rank-box">{$user['ranks']['rankName']} + <img src="__ROOT__/{$user['ranks']['userrankImg']}"> + </div> + {/if} + </span> + </div>--> + + + + </div> + + {:hook('mobileDocumentUserIndex')} + <!-- 导航 --> + <div class="nav clearfix"> + <div class="nblock"> + <a href="{:url('mobile/favorites/goods')}"> + <p>22</p> + <p>收藏夹</p> + </a> + + </div> + <div class="nblock"> + <a href="{:url('mobile/favorites/shops')}"> + <p>22</p> + <p>关注店铺</p> + </a> + + </div> + <div class="nblock"> + <a href="{:url('mobile/goods/history')}"> + <p>22</p> + <p>足迹</p> + </a> + + </div> + </div> + + + {/* 商家订单管理 */} {if ($user['userType']==1)} + <!--<ul class="ui-row user-order"> + <li class="ui-col ui-col-50">商家订单管理</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('mobile/orders/sellerorder')}'">查看全部订单 ></li> + </ul>--> + {/if} {/*用户订单管理 */} + <ul class="ui-row user-order" style="background: #fff;"> + <li class="ui-col ui-col-50">我的订单</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('mobile/orders/index')}'">查看全部订单 ></li> + </ul> + <div class="ui-row-flex ui-whitespace wst-users_icon pd10"> + + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitPay'])}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="wst-users_icon1"></i> {if ($data['order']['waitPay']>0)} + <span class="ui-badge-corner wait-payment ui-nowrap-flex ui-whitespace" id="waitPay">{$data['order']['waitPay']}</span> {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center pdl7">待付款</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitDeliver'])}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="wst-users_icon2"></i> {if ($data['order']['waitSend']>0)} + <span class="ui-badge-corner wait-payment" id="waitSend">{$data['order']['waitSend']}</span> {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center pdl7">待发货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitReceive'])}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="wst-users_icon3"></i> {if ($data['order']['waitReceive']>0)} + <span class="ui-badge-corner wait-payment" id="waitReceive">{$data['order']['waitReceive']}</span> {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center pdl7">待收货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'waitAppraise'])}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="wst-users_icon4"></i> {if ($data['order']['waitAppraise']>0)} + <span class="ui-badge-corner wait-payment" id="waitAppraise">{$data['order']['waitAppraise']}</span> {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center pdl7">待评价</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('mobile/orders/index',['type'=>'abnormal'])}"> + <p style="display:none;"><i class="wst-users_icon5"></i></p> + <p><i class="wst-users_icon5"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center pdl7">退款售后</span> + </a> + </div> + + </div> + + <!--<ul class="ui-row user-tool"> + <li class="ui-col ui-col-100">必备工具</li> + + </ul>--> + + <!--<div class="ui-btn-wrap logout"> + <button class="ui-btn-lg ui-btn-danger logout-btn" onclick="WST.dialog('确定要退出吗?','logout()')"> + 退出登录 + </button> + </div>--> + +</section> +{/block} {block name="include"} {include file="default/dialog" /} +<!-- 对话框模板 --> +{/block} {block name="js"} +<script type='text/javascript' src='__ROOT__/hyhproject//mobile/view/default/users/user.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/jquery-1.10.2.min.js b/hyhproject/mobile2/view/default/users/jquery-1.10.2.min.js new file mode 100755 index 0000000..da41706 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/jquery-1.10.2.min.js @@ -0,0 +1,6 @@ +/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license +//@ sourceMappingURL=jquery-1.10.2.min.map +*/ +(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t +}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); +u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window); diff --git a/hyhproject/mobile2/view/default/users/logmoneys/list.html b/hyhproject/mobile2/view/default/users/logmoneys/list.html new file mode 100755 index 0000000..06bc633 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/logmoneys/list.html @@ -0,0 +1,119 @@ +{extend name="default/base" /} +{block name="title"}我的资金 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/logmoneys.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的资金</h1> + <span class="record" onclick="location.href='{:url('mobile/cashdraws/index')}'">提现记录</span> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$rs['isSetPayPwd']}" id="isSet" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-row-flex-ver head"> + <div class="title"> + <div class="money_number"> + <p id="userMoney" money="{$rs['userMoney']}" cash="{:WSTConf('CONF.drawCashUserLimit')}">可用资金:<span>¥ </span>{$rs['userMoney']}</p> + </div> + <div class="money_number2"> + <p money="{$rs['userMoney']}" cash="{:WSTConf('CONF.drawCashUserLimit')}">冻结资金:<span>¥ </span>{$rs['lockMoney']}</p> + </div> + <div class="wst-clear"></div> + </div> + <div class="ui-col head-btn-box"></div> + </div> + <ul class="ui-row recharge-box"> + <li class="ui-col ui-col-50" onclick="location.href='{:url('mobile/logmoneys/toRecharge')}'"> + <div class="wst_model"> + <div class="icon_add"><p>充值</p></div> + </div> + </li> + <!--{if session('WST_USER.userType') == 1 } + <li class="ui-col ui-col-50" onclick="getCash()"> + <div class="wst_model"> + <div class="icon_out"><p>提现</p></div> + </div> + </li> + {/if}--> + </ul> + {if session('WST_USER.userType') == 1 } + <ul class="ui-row money-detail" onclick="check()"> + <li class="ui-col ui-col-50 money-detail-title"><div class="icon_stript stript_1"></div><h5>&nbsp;我的提现账户</h5></li> + <li class="ui-col ui-col-50 money-detail-title m-tr"><h5>{$rs['num']}个 ></h5></li> + </ul> + {/if} + <ul class="ui-row money-detail" onclick="javascript:toRecord()"> + <li class="ui-col ui-col-50 money-detail-title"><div class="icon_stript stript_2"></div><h5>&nbsp;我的资金流水</h5></li> + <li class="ui-col ui-col-50 money-detail-title m-tr"><h5>></h5></li> + </ul> + {if session('WST_USER.userType') == 1 } + <ul class="ui-row first-time"> + <li class="ui-col ui-col-100 ft-title"><i></i><span>首次提现步骤:</span></li> + <li class="ui-col ui-col-100 ft-item">1.设置支付密码和绑定手机号码</li> + <li class="ui-col ui-col-100 ft-item">2.绑定您的微信钱包或银行卡</li> + </ul> + {/if} + </section> +{/block} +{block name="include"} +{include file="default/dialog" /} +<input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> +{/* 对话框 prompt */} +<div class="ui-dialog" id="payPwdBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <p id="wst-dialog" class="wst-dialog-t"> + 请输入支付密码:<br /> + <input type="password" id="payPwd" maxLength="6" class="wst-pay-inp"/> + </p> + <p class="wst-dialog-l"></p> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </div> + </div> +</div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>申请提现</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="info"> + <p>可提现金额</p> + <p class="money"><span>¥ </span>{$rs['userMoney']}</p> + </div> + <div class="content"> + <ul class="ui-row"> + <li class="ui-col ui-col-25">提现账号:</li> + <li class="ui-col ui-col-75"> + <select name="accId" id="accId" class="wst-lo-choice"> + <option value="">请选择</option> + </select> + </li> + <li class="ui-col ui-col-25">提现金额:</li> + <li class="ui-col ui-col-75"> + <input type="number" name="money" id="money" class="wst-lo-choice" onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" /> + </li> + <li class="ui-col ui-col-25">支付密码:</li> + <li class="ui-col ui-col-75"> + <input type="password" id="cashPayPwd" class="wst-lo-choice" maxLength="6" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" /> + </li> + <li class="ui-col wst-red">(至少¥ {:WSTConf('CONF.drawCashUserLimit')}以上可提现)</li> + <li class="ui-col ui-col-100"> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-apply-button" id="submit" onclick="drawMoney()"> + 确定 + </button> + </div> + </li> + + </ul> + </div> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/logmoneys/logmoneys.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/logmoneys/logmoneys.js b/hyhproject/mobile2/view/default/users/logmoneys/logmoneys.js new file mode 100755 index 0000000..8ee5992 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/logmoneys/logmoneys.js @@ -0,0 +1,155 @@ +jQuery.noConflict(); +$(document).ready(function(){ + WST.initFooter('user'); + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); +}); +//资金流水列表 +function getRecordList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val() || -1; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/logMoneys/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); + } +// 验证支付密码资金 +function check(){ + var isSetPayPwd = $('#isSet').val(); + if(isSetPayPwd==0){ + $('#wst-event2').html('去设置'); + WST.dialog('您未设置支付密码','location.href="'+WST.U('mobile/users/editPayPass')+'"'); + return; + }else{ + showPayBox(); + } + +} +// 支付密码对话框 +function showPayBox(){ + $("#wst-event3").attr("onclick","javascript:checkSecret()"); + $("#payPwdBox").dialog("show"); +} +function checkSecret(){ + var payPwd = $.trim($('#payPwd').val()); + if(payPwd==''){ + WST.msg('请输入支付密码','info'); + return; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + $.post(WST.U('mobile/logmoneys/checkPayPwd'),{payPwd:payPwd},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $("#payPwdBox").dialog("hide"); + location.href=WST.U('mobile/cashconfigs/index'); + }else{ + WST.msg(json.msg); + } + }) +} +//资金流水 +function toRecord(){ + location.href = WST.U('mobile/logmoneys/record'); +} +/******************** 提现层 *************************/ +function getCash(){ + $('#money').val(''); + $('#cashPayPwd').val(''); + $.post(WST.U('mobile/cashconfigs/pageQuery'),{},function(data){ + var json = WST.toJson(data); + var html = '<option value="">请选择</option>'; + if(json.status==1){ + $(json.data.Rows).each(function(k,v){ + html +='<option value='+v.id+'>'+v.accUser+'|'+v.accNo+'</option>'; + }); + $('#accId').html(html); + // 判断是否禁用按钮 + if($('#userMoney').attr('money')<$('#userMoney').attr('cash'))$('#submit').attr('disabled','disabled'); + dataShow(); + }else{ + WST.msg(json.msg,'info'); + } + }) +} +// 申请提现 +function drawMoney(){ + var accId = $('#accId').val(); + var money = $('#money').val(); + var payPwd = $('#cashPayPwd').val(); + + if(accId==''){ + WST.msg('请选择提现账号','info'); + return; + } + if(money==''){ + WST.msg('请输入提现金额','info'); + return + } + if(payPwd==''){ + WST.msg('请输入支付密码','info'); + return + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + var param = {}; + param.accId = accId; + param.money = money; + param.payPwd = payPwd; + $.post(WST.U('mobile/cashdraws/drawMoney'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('提现申请已提交','success'); + setTimeout(function(){ + history.go(0); + },1000); + }else{ + WST.msg(json.msg,'info'); + } + }) +} +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/logmoneys/record.html b/hyhproject/mobile2/view/default/users/logmoneys/record.html new file mode 100755 index 0000000..2174064 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/logmoneys/record.html @@ -0,0 +1,55 @@ +{extend name="default/base" /} +{block name="title"}资金流水 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/userscores.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "资金流水"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-whitespace ui-row-flex-ver head" style="text-align: left;"> + <div class="ui-col" style="padding-top: 30px;font-size: 0.16rem;text-align: right;">可用资金:¥ {$rs['userMoney']}</div> + <div class="ui-col" style="font-size: 0.16rem;text-align: right;">冻结资金:¥ {$rs['lockMoney']}</div> + </div> + <script type="text/html" id="scoreList"> + <ul class="ui-row score-detail"> + {{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75 wst-re-info"> + {{d[i].remark}} + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 {{(d[i].moneyType==1)?'score-plus':'score-reduce'}}">{{(d[i].moneyType==1)?'+':'-'}} {{d[i].money}}</li> + <div class="wst-clear"></div> + <div class="score-line"></div> + {{# } }} + </ul> + </script> + <div class="score-detail-title">资金明细</div> + <div id="score-list"></div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/logmoneys/logmoneys.js?v={$v}'></script> +<script> +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getRecordList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getRecordList(); + } + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/messages/list.html b/hyhproject/mobile2/view/default/users/messages/list.html new file mode 100755 index 0000000..c80ea7c --- /dev/null +++ b/hyhproject/mobile2/view/default/users/messages/list.html @@ -0,0 +1,77 @@ +{extend name="default/base" /} +{block name="title"}我的消息 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/messages.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="location.href='{:url('mobile/users/index')}'"></i><h1>我的消息</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:45px; border-top: 1px solid #e0e0e0;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox" style="margin-left:5px;"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger del-btn" onclick="toDelMsg()"> + 删除消息 + </button> + </div> + </div> + </div> + + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <script type="text/html" id="msgList"> + {{# for(var i=0; i<d.length; i++){ }} + <li> + <label class="ui-checkbox msg-chk"> + <input class="active" type="checkbox" msgId="{{d[i].id}}" > + </label> + <div class="ui-list-info" onclick="javascript:getMsgDetails({{d[i].id}});"> + <h5 class="ui-nowrap"> + <span class="{{(d[i].msgStatus == 0)?'wst-info_ico':'wst-info_ico1' }} j-icon_{{d[i].id}}"></span>{{d[i].msgContent}}</h5> + </div> + </li> + <div class="wst-Line"></div> + {{# } }} + </script> + <section class="ui-container info-prompt"> + <ul class="ui-list ui-list-text wst-info_content" id="info-list"> + </ul> + </section> + </div> + <div id="info_details" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnInfo()"></i><h1>消息详情</h1> + </header> + <section class="ui-container"> + <div class="ui-whitespace detail-time"><span class="wst-info_detime"></span></div> + <div class="ui-whitespace"><span class="wst-info_decontent"></span></div> + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__ROOT__/hyhproject//mobile/view/default/users/messages/messages.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/messages/messages.js b/hyhproject/mobile2/view/default/users/messages/messages.js new file mode 100755 index 0000000..4fcdac6 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/messages/messages.js @@ -0,0 +1,103 @@ +//消息列表 +function getMessages(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 12; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/messages/pageQuery'), param, function(data){ + var json = WST.toJson(data); + var mhtml = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('msgList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#info-list').append(html); + }); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + + }else{ + mhtml += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-message.png"></div>'; + mhtml += '<div class="wst-prompt-info">'; + mhtml += '<p>对不起,没有相关消息。</p>'; + mhtml += '</div>'; + $('.info-prompt').append(mhtml); + } + loading = false; + $('#Load').hide(); + }); +} +//返回消息列表 +function returnInfo(){ + $('#info_details').hide(); + $('#info_list').show(); +} + +// 全选 +function checkAll(obj){ + var chk = $(obj).attr('checked'); + $('.active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +//消息详情 +function getMsgDetails(id){ + $('#info_list').hide(); + $('#info_details').show(); + $('.j-icon_'+id).addClass('wst-info_ico1').removeClass('wst-info_ico'); + $.post(WST.U('mobile/messages/getById'), {msgId:id}, function(data){ + var json = WST.toJson(data); + if(json){ + $('.wst-info_detime').html(json.createTime); + $('.wst-info_decontent').html(json.msgContent); + } + json = null; + }); +} +var msgIdsToDel=new Array();//要删除的消息的id 数组 +//去删除商城消息 +function toDelMsg(){ + var msgIds = new Array(); + $('.active').each(function(k,v){ + if($(this).attr('checked')){ + msgIds.push($(this).attr('msgid')); + } + }); + msgIdsToDel = msgIds; + if(msgIds.join(',')==''){ + WST.msg('请选择要删除的消息','info'); + return false; + } + WST.dialog('确定要删除选中的消息吗?','delMsg()'); +} +var vn =''; +//删除商城消息 +function delMsg(){ + WST.dialogHide('prompt'); + $.post(WST.U('mobile/messages/del'), {ids:msgIdsToDel}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + $('#currPage').val(0) + $('#info-list').html(' '); + getMessages(); + }else{ + WST.msg(json.msg,'warn'); + } + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getMessages(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getMessages(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/list_complains.html b/hyhproject/mobile2/view/default/users/orders/list_complains.html new file mode 100755 index 0000000..d64219a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/list_complains.html @@ -0,0 +1,133 @@ +{extend name="default/base" /} +{block name="title"}我的投诉 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/list_complains.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的投诉</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <script type="text/html" id="complainList"> + <ul class="ui-row"> + {{# for(var i=0;i<d.length;i++){ }} + <div class="complain-box"> + <li class="ui-col ui-col-50" onclick="javascript:WST.intoShops({{d[i].shopId}});">{{d[i].shopName}}</li> + <li class="ui-col ui-col-50 c-tr">{{d[i].complainTime}}</li> + <div class="c-item" onclick="complainDetail({{d[i].complainId}})"> + <li class="ui-col ui-col-75">订单号:{{d[i].orderNo}}</li> + <li class="ui-col ui-col-25 c-tr wst-co-status">{{d[i].complainStatus}}</li> + </div> + <div class="wst-clear"></div> + </div> + <div class="c-line"></div> + {{# } }} + </ul> + </script> + <div id="complain-list"></div> + </section> +<script type="text/html" id="complainDetail"> +<ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">投诉信息</li> + <li class="ui-col ui-col-25 com-detail-title">订单编号:</li> + <li class="ui-col ui-col-75">{{d.orderNo}}</li> + + <li class="ui-col ui-col-25 com-detail-title">投诉内容:</li> + <li class="ui-col ui-col-75">{{d.complainContent}}</li> + + <li class="ui-col ui-col-25 com-detail-title">投诉类型:</li> + <li class="ui-col ui-col-75"> + {{# if (d.complainType==1){ }} + 承诺的没有做到 + {{# } else if (d.complainType==2) { }} + 未按约定时间发货 + {{# } else if (d.complainType==3) { }} + 未按成交价格进行交易 + {{# } else if (d.complainType==4) { }} + 恶意骚扰 + {{# } }} + </li> + + <li class="ui-col ui-col-25 com-detail-title">附件:</li> + <li class="ui-col ui-col-75"> + {{# if(d.complainAnnex){ }} + {{# for(var c=0;c<d.complainAnnex.length;c++){ }} + <img src="__IMGURL__/{{d.complainAnnex[c]}}" style="width:60px;height:60px;" id="imgurl"> + {{# } }} + {{# }else{ }} + 无 + {{# } }} + </li> + + <li class="ui-col ui-col-25 com-detail-title">投诉时间:</li> + <li class="ui-col ui-col-75">{{d.complainTime}}</li> + </ul> + + + {{# if (d.needRespond==1 && WST.blank(d.respondContent)!=''){ }} + + <ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">应诉信息</li> + + + <li class="ui-col ui-col-25 com-detail-title">应诉内容:</li> + <li class="ui-col ui-col-75">{{d.respondContent}}</li> + + + <li class="ui-col ui-col-25 com-detail-title">附件:</li> + <li class="ui-col ui-col-75"> + {{# if(d.respondAnnex){ }} + {{# for(var r=0;r<d.respondAnnex.length;r++){ }} + <img src="__IMGURL__/{{d.respondAnnex[r]}}" class="annex"> + {{# } }} + {{# }else{ }} + 无 + {{# } }} + </li> + <li class="ui-col ui-col-25 com-detail-title">应诉时间:</li> + <li class="ui-col ui-col-75">{{d.respondTime}}</li> + </ul> + {{# } }} + + + <ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">仲裁信息【 + {{# if(d.complainStatus==0){ }} + 等待处理 + {{# }else if(d.complainStatus==1){ }} + 等待应诉人回应 + {{# }else if(d.complainStatus==2 || d.complainStatus==3){ }} + 等待仲裁 + {{# }else if(d.complainStatus==4){ }} + 已仲裁 + {{# } }} + 】</li> + + {{# if(d.complainStatus==4){ }} + <li class="ui-col ui-col-25 com-detail-title">仲裁结果:</li> + <li class="ui-col ui-col-75">{{d.finalResult}}</li> + + <li class="ui-col ui-col-25 com-detail-title">仲裁时间:</li> + <li class="ui-col ui-col-75">{{d.finalResultTime}}</li> + {{# } }} + </ul> +</script> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>投诉详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="complainDetailBox"> + </div> +</div> + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/list_complains.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/list_complains.js b/hyhproject/mobile2/view/default/users/orders/list_complains.js new file mode 100755 index 0000000..ce4596b --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/list_complains.js @@ -0,0 +1,88 @@ +jQuery.noConflict(); +// 获取订单列表 +function getComplainList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/orderComplains/complainByPage'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('complainList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#complain-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-complaint.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无投诉信息</p>'; + html += '</div>'; + $('#complain-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getComplainList(); + WST.initFooter('user'); + // 弹出层 + $("#frame").css('top',0); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getComplainList(); + } + } + }); +}); + + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function complainDetail(cId){ + $.post(WST.U('mobile/orderComplains/getComplainDetail'),{'id':cId},function(data){ + var json = WST.toJson(data); + if(json){ + var gettpl = document.getElementById('complainDetail').innerHTML; + laytpl(gettpl).render(json, function(html){ + // 写入数据 + $('#complainDetailBox').html(html); + // 设置滚动条 + var screenH = WST.pageHeight(); + var titleH = $('#frame').find('.title').height(); + var contentH = $('#complainDetailBox').height(); + + if(screenH-titleH < contentH){ + $('#complainDetailBox').css('height',screenH-titleH); + } + // 展示弹出层 + dataShow(); + }); + } + + }) + +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_appraises.html b/hyhproject/mobile2/view/default/users/orders/orders_appraises.html new file mode 100755 index 0000000..43dddea --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_appraises.html @@ -0,0 +1,172 @@ +{extend name="default/base" /} +{block name="title"}商品评价 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders_appraises.css?v={$v}"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="header"} + {php}$Title='商品评价'{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$oId}" id="oId" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex item-head"> + <div class="ui-col ui-col-2 ui-nowrap-flex shop"><i></i>{$data['shopName']}</div> + </div> + {volist name="data['Rows']" id="g"} + <div class="ui-row-flex border-b g-item"> + <div class="ui-col"> + <div class="g-Img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$g['goodsId']});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{:WSTImg($g['goodsImg'],3)}"> + </a> + </div> + </div> + <div class="ui-col ui-col-3 g-gInfo"> + <p class="g-gName ui-nowrap-multi">{$g['goodsName']}</p> + <p class="g-gSpec ui-nowrap-flex">{if($g['goodsSpecNames'])}规格:{$g['goodsSpecNames']}{/if}</p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;"> + {if ($g['appraise']!='')} + <span class="appraise" onclick="appraise({$g.goodsId},{$g['goodsSpecId'] ?? 0},{$g.id},this)"></span> + {else /} + <span class="appraise" onclick="appraise({$g.goodsId},{$g['goodsSpecId'] ?? 0},{$g.id},this)"></span> + {/if} + </div> + </div> + <div id="appBox_{$g.id}"></div> + {/volist} + <script id="appraises-box" type="text/html"> + <ul class="ui-row appraise-box"> + <li class="ui-col ui-col-25 appraise-title">商品名称</li> + <li class="ui-col ui-col-75 ui-nowrap-multi appraise-name"> + {{d.goodsName}} + </li> + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">商品评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.goodsScore!=''){ }} + {{# for(var i=0;i<d.goodsScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.goodsScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="goodsScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.goodsScore!='')?d.goodsScore:'0'}}分</li> + </ul> + </li> + + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">服务评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.serviceScore!=''){ }} + {{# for(var i=0;i<d.serviceScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.serviceScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="serviceScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.serviceScore!='')?d.serviceScore:'0'}}分</li> + </ul> + </li> + + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">时效评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.timeScore!=''){ }} + {{# for(var i=0;i<d.timeScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.timeScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="timeScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.timeScore!='')?d.timeScore:'0'}}分</li> + </ul> + </li> + + {{# if(d.content==''){ }} + <li class="ui-col" style="padding:10px"> + <textarea class="appraisesContent" id="content"></textarea> + </li> + <div class="ui-col uploadfile-box"> + <ul class="complainFileBox" id="edit_chart"> + </ul> + <div id="filePicker" style='margin-left:10px;width:250px;overflow:hidden;height:35px;font-size:.13rem;'>上传附件(最多5张)</div> + </div> + <br /> + <div class="ui-btn-wrap post-btn"> + <button class="ui-btn-lg ui-btn-danger" onclick="javascript:saveAppr({{d.goodsId}},{{d.goodsSpecId}},{{d.orderGoodsId}});">提交</button> + </div> + {{# }else{ }} + <li class="ui-col ui-col-25 appraise-title">点评内容</li> + <li class="ui-col ui-col-75"> + {{d.content}} + </li> + <li class="ui-col ui-col-25 appraise-title" style="padding-top:15px;">评价附件</li> + <li class="ui-col ui-col-75" style="margin-top:10px;margin-left:-10px;"> + {{# if(WST.blank(d.images)!=''){ + var img = d.images; + }} + <ul class="complainFileBox"> + {{# for(var g=0;g<img.length;++g){ }} + <li><img src="__IMGURL__/{{img[g]}}"> </li> + {{# } }} + </ul> + {{# } }} + </li> + + {{# } }} + </ul> + + + + </script> + <div id="appraisesBox"> + </div> + + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_appraises.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_appraises.js b/hyhproject/mobile2/view/default/users/orders/orders_appraises.js new file mode 100755 index 0000000..246e983 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_appraises.js @@ -0,0 +1,115 @@ +jQuery.noConflict(); +//商品评价 +function clickStar(obj){ + var index = $(obj).index(); // 当前选中的分数 + $(obj).parent().find('span').each(function(k,v){ + if(k<=index){ + $(this).removeClass('start-not').addClass('start-on'); + }else{ + $(this).removeClass('start-on').addClass('start-not'); + } + }) + $(obj).parent().siblings().html(index+1+'分'); + $(obj).parent().siblings().attr('score',index+1); +} + +function appraise(gId,sId,ogId,obj){ + + $('.appraise').removeClass('score'); + $(obj).addClass('score'); + var gName = $(obj).parent().parent().find('.g-gName').html(); + + var param = {}; + param.gId = gId; + param.sId = sId; + param.oId = $('#oId').val(); + param.orderGoodsId = ogId; + $.post(WST.U('mobile/goodsappraises/getAppr'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('appraises-box').innerHTML; + json.data.goodsName = gName; + json.data.goodsId = gId; + json.data.goodsSpecId = sId; + json.data.orderGoodsId = ogId; + laytpl(gettpl).render(json.data, function(html){ + $('div[id^="appBox_"]').html(' '); + $('#appBox_'+ogId).html(html); + }); + if(json.data.serviceScore=='')userAppraiseInit(); + }else{ + WST.msg('请求出错','info'); + } + }) +} +function saveAppr(gId,sId,ogId){ + var content = $.trim($('#content').val()); + if(content==''){ + WST.msg('评价内容不能为空','info'); + return + } + var param = {}; + param.content = content; + param.goodsId = gId; + param.goodsSpecId = sId; + param.orderId = $('#oId').val(); + param.timeScore = $('#timeScore').attr('score'); + param.goodsScore = $('#goodsScore').attr('score'); + param.serviceScore = $('#serviceScore').attr('score'); + param.orderGoodsId = ogId; + + var imgs = []; + // 是否有上传附件 + $('.imgSrc').each(function(k,v){ + imgs.push($(this).attr('v')); + }) + imgs = imgs.join(','); + if(imgs!='') + param.images = imgs; + + $.post(WST.U('mobile/goodsappraises/add'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){history.go(0);},1000); + }else{ + WST.msg(json.msg); + } + }) + +} +$(function(){ + WST.initFooter('user'); + WST.imgAdapt('j-imgAdapt'); +}) + + +/*************** 上传图片 *****************/ +function userAppraiseInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'appraises',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<li>"+ + "<img class='imgSrc' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></li>"); + var btn = $('<div class="del-btn"><span class="ui-icon-delete"></span></div>'); + tdiv.append(btn); + $('#edit_chart').append(tdiv); + btn.on('click','span',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} diff --git a/hyhproject/mobile2/view/default/users/orders/orders_complains.html b/hyhproject/mobile2/view/default/users/orders/orders_complains.html new file mode 100755 index 0000000..0d0ce7d --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_complains.html @@ -0,0 +1,182 @@ +{extend name="default/base" /} +{block name="title"}订单投诉 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__ROOT__/hyhproject/mobile/view/default/css/orders_complains.css?v={$v}"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="footer"} +{/block} +{block name="header"} + <div id="useri_infos"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <a href="{:url('mobile/users/index')}"><i class="ui-icon-return"></i></a><h1 class="useri_info">订单投诉</h1> + <i onclick="javascript:closeUploadArea()" style="display:none;font-size: 0.15rem;" id="upload_close">关闭</i> + <a href="javascript:void(0);" style="display:none;float:right;font-size: 0.15rem;" id="upload_button">上传</a> + </header> +{/block} + +{block name="main"} +<sction class="ui-container" id="upload_modal"> + <div class="upload-modal"> + <div id="clipArea" class="clipArea"></div> + <input type="hidden" id="imgData" autocomplete="off"> + </div> +</sction> + <input type="hidden" name="" value="" id="complainType" autocomplete="off"> + <input type="hidden" name="" value="{$oId}" id="oId" autocomplete="off"> + <section class="ui-container" id="Ccontrainer"> + <script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="ui-row-flex ui-whitespace detail-head"> + <div class="ui-col ui-col ">订单号:{{d.orderNo}}</div> + <div class="ui-col order-tr o-status"> + {{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + </div> + </div> + + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col">{{d.shopName}}</div> + </div> + + + {{# for(var i=0;i<d.goods.length;i++){ }} + <div class="ui-row-flex ui-whitespace border-b d-goodsitme"> + <div class="ui-col"> + <div class="o-Img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d.goods[i]['goodsId']}});"> + <img src="__IMGURL__/{:WSTConf('CONF.goodsLogo')}" data-echo="__IMGURL__/{{d.goods[i].goodsImg}}"> + </a> + </div> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{{d.goods[i].goodsName}}</p> + + + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"><p class="price">¥ {{d.goods[i].goodsPrice}}</p><p> x {{d.goods[i].goodsNum}}</p></div> + </div> + {{# } }} + + + <div class="ui-row-flex ui-whitespace d-item"> + <div class="ui-col ui-col">下单时间</div> + <div class="ui-col ui-col order-tr">{{d.createTime}}</div> + </div> + + <div class="ui-row-flex ui-whitespace d-item" style="min-height:80px;"> + <div class="ui-col ui-col">商品总额</div> + <div class="ui-col ui-col-4 order-tr"> + <p class="price">¥ {{d.goodsMoney}}</p> + <p class="price"><span class="title">运费:</span>¥ {{d.deliverMoney}}</p> + <p>实付款:<span class="price">¥ {{d.needPay}}</span></p> + </div> + </div> + </div> +</script> + +<div id="orderDetail"> + +</div> + +<div class="ui-row-flex ui-whitespace d-item c-item"> + <div class="ui-col ui-col">投诉类型</div> + <div class="ui-col ui-col-3 order-tr" onclick="dataShow(0)" id="complainText" >请选择投诉类型 > </div> +</div> + +<div class="ui-row-flex ui-whitespace ui-row-flex-ver c-box"> + <div class="ui-col c-title">投诉内容</div> + <div class="ui-col c-content"> + <textarea id="complain"></textarea> + </div> + + <div class="ui-col uploadfile-box"> + <ul class="complainFileBox" id="edit_chart"> + + </ul> + + <div id="filePicker" style='margin-left:5px;width:250px;overflow:hidden;height:35px;font-size:.13rem;'>上传附件(最多5张)</div> + </div> + + <div class="ui-btn-wrap" style="padding:5px;padding-bottom:5px;"> + <button class="ui-btn-lg ui-btn-danger c-btn" onclick="saveCom({$oId})"> + 提交 + </button> + </div> +</div> + + {/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 订单详情层 */} +<div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span>投诉类型</span><i class="ui-icon-close-page" onclick="javascript:dataHide(0);"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">承诺的没有做到</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='1' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">未按约定时间发货</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='2' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">未按成交价格进行交易</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='3' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">恶意骚扰</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='4' > + </label> + </li> + </ul> + + </div> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger c-btn" onclick="dataHide(1)"> + 确定 + </button> + </div> +</div> +</section> + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_complains.js?v={$v}'></script> + + +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_complains.js b/hyhproject/mobile2/view/default/users/orders/orders_complains.js new file mode 100755 index 0000000..42b9932 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_complains.js @@ -0,0 +1,122 @@ +jQuery.noConflict(); +$(function(){ + getOrderDetail(); + userComplainInit(); +}) +function getOrderDetail(){ + var oid = $('#oId').val(); + $.post(WST.U('mobile/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#orderDetail').html(html); + }); + }else{ + WST.msg(json.msg,'info'); + } + WST.imgAdapt('j-imgAdapt'); + }); + +} + +/*********************** 投诉类型 ****************************/ +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide(0);").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(type){ + if(type==1){ + var flag=false,chk; + $('.active').each(function(k,v){ + if($(this).prop('checked')){ + flag = true + $('#complainType').val($(this).val()); + chk = $(this).parent().parent().siblings().html(); + } + }); + if(!flag){ + WST.msg('请选择投诉类型'); + return; + } + $('#complainText').html(chk+' >'); + } + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} + +function uploadFile(){ + $('#filePicker').trigger("click"); +} + + +function saveCom(oId){ + // 验证投诉类型 + var type = $('#complainType').val(); + if(type==''){ + dataShow(); + WST.msg('请选择投诉类型','info'); + return; + } + var complainContent = $.trim($('#complain').val()); + if(complainContent==''){ + WST.msg('投诉内容不能为空','info'); + return; + } + var param = {}; + param.orderId = oId; + param.complainType = type; + param.complainContent = complainContent; + + var imgs = []; + // 是否有上传附件 + $('.imgSrc').each(function(k,v){ + imgs.push($(this).attr('v')); + }) + imgs = imgs.join(','); + if(imgs!='') + param.complainAnnex = imgs; + + $.post(WST.U('mobile/ordercomplains/saveComplain'),param,function(data){ + var json = WST.toJson(data); + if(data.status){ + WST.msg('投诉成功请留意商城消息','success'); + setTimeout(function(){location.href=WST.U('mobile/ordercomplains/index')},1000); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} +/*************** 上传图片 *****************/ +function userComplainInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'complains',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<li>"+ + "<img class='imgSrc' src='"+WST.conf.IMGURL+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></li>"); + var btn = $('<div class="del-btn"><span class="ui-icon-delete"></span></div>'); + tdiv.append(btn); + $('#edit_chart').append(tdiv); + btn.on('click','span',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} diff --git a/hyhproject/mobile2/view/default/users/orders/orders_list.html b/hyhproject/mobile2/view/default/users/orders/orders_list.html new file mode 100755 index 0000000..c69d895 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_list.html @@ -0,0 +1,490 @@ +{extend name="default/base" /} +{block name="title"}我的订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header wst-headero"> + <i class="ui-icon-return" onclick="location.href='{:url('mobile/users/index')}'"></i><h1>我的订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="order-item"> + <div class="ui-row-flex ui-whitespace item-head"> + <div class="ui-col ui-col-2" onclick="javascript:WST.intoShops({{d[i].shopId}});"><p class="ui-nowrap-flex"><i class="shopicon"></i>{{d[i].shopName}}</p></div> + <div class="ui-col order-tr o-status"> + {{ d[i].status }} + {{# if($.inArray(d[i].orderStatus,[-1,-3])!=-1){ }} + {{# if(d[i].payType==1 && d[i].isPay==1) { }} + {{# if(d[i].isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }} + </div> + </div> + + {{# for(var g=0;g<d[i].list.length;g++){ }} + <div class="ui-row-flex ui-whitespace border-b" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col"> + <img src="__IMGURL__/{{d[i].list[g].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d[i].list[g].goodsName}}</p> + + {{# if(d[i].list[g].goodsSpecNames){ }} + <p class="o-gSpec ui-nowrap-flex ui-whitespace">规格:{{d[i].list[g].goodsSpecNames}}</p> + {{# } }} + </div> + <div class="ui-col order-tr" style="word-break:break-all;"> + {{# if(d[i].list[g].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d[i].list[g].goodsPrice}}</p><p>x {{d[i].list[g].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# } }} + + + <div class="ui-btn-wrap" style="padding:5px 0px;"> + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + <div class="o-oListMoney"> + 订单总价:<span>¥ {{d[i].realTotalMoney}}</span> + </div> + {{# if(d[i].orderStatus==-2){ }} + <button class="ui-btn o-btn" onclick="choicePay({{d[i].orderNo}},0);"> + 立即付款 + </button> + {{# } }} + + {{# if(d[i].orderStatus==0 && d[i].noticeDeliver==0 ){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="WST.dialog('您确定要提醒发货吗?','noticeDeliver({{d[i].orderId}})')"> + 提醒发货 + </button> + {{# } }} + + + {{# if(d[i].orderStatus==-2 || d[i].orderStatus==0){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="showCancelBox('cancelOrder({{d[i].orderId}})')"> + 取消订单 + </button> + {{# } }} + + {{# if((d[i].orderStatus!=-1 || d[i].orderStatus==1) && d[i].orderStatus!=-2 && d[i].isComplain==0 ){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="complain({{d[i].orderId}})"> + 投诉 + </button> + {{# } }} + + {{# if(d[i].orderStatus==2 && d[i].isAppraise==0) { }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 评价 + </button> + {{# } }} + {{# if(d[i].isAppraise==1){ }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 查看评价 + </button> + {{# } }} + + + {{# if((d[i].allowRefund==1) && (d[i].orderStatus==-1 || d[i].orderStatus==-3)){ }} + <button class="ui-btn o-btn" onclick="showRefundBox({{d[i].orderId}})"> + 申请退款 + </button> + {{# } }} + + + {{# if(d[i].orderStatus==1){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="showRejectBox('rejectOrder({{d[i].orderId}})')"> + 拒收 + </button> + <button class="ui-btn o-btn" onclick="WST.dialog('你确定已收货吗?','receive({{d[i].orderId}})')"> + 确认收货 + </button> + {{# } }} + {{ d[i]['hook']?d[i]['hook']:"" }} + <div class="wst-clear"></div> + </div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + <li class="tab-item {if $type==''}tab-curr{/if}" type="" >全部</li> + <li class="tab-item {if $type=='waitPay'}tab-curr{/if}" type="waitPay" >待付款</li> + <li class="tab-item {if $type=='waitDeliver'}tab-curr{/if}" type="waitDeliver" >待发货</li> + <li class="tab-item {if $type=='waitReceive'}tab-curr{/if}" type="waitReceive" >待收货</li> + <li class="tab-item {if $type=='waitAppraise'}tab-curr{/if}" type="waitAppraise" >待评价</li> + <li class="tab-item {if $type=='finish'}tab-curr{/if}" type="finish" >已完成</li> + <li class="tab-item {if $type=='abnormal'}tab-curr{/if}" type="abnormal" >取消拒收</li> + </ul> + </div> + + <div id="order-box"> + + </div> + + </section> + </div> + +{:hook('mobileDocumentOrderList')} + +<script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="detail-head" style="margin-top:0;"> + {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + {{# if(d.payType==1) { }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待付款</p></div> + {{# } }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.orderStatus==2){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已收货</p></div> + </div> + </div> + {{# } }} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1 && d.payType==1 && d.isPay==1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==2) { }} active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单状态:</span> + <span class="o-status">{{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.payType==1 && d.isPay==1) { }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单编号:</span>{{d.orderNo}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">下单时间:</span>{{d.createTime}}</div> + </div> + </div> + + + <div class="detail-head"> + {{# if(d.userName){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货人:</span>{{d.userName}} <span class="d-utel">{{d.userPhone}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货地址:</span><span class="d-uaddr">{{d.userAddress}}<i></i></span></div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付信息:</span>{{d.payInfo}}</div> + </div> + {{# if(d.payTime){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付时间:</span>{{d.payTime}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">配送信息:</span>{{d.deliverInfo}}</div> + </div> + {{# if(WST.blank(d.expressNo)!=''){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递公司:</span>{{d.expressName}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递号:</span>{{d.expressNo}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票信息:</span>{{# if(d.isInvoice==1) { }}需要{{# } else{ }}不需要{{# } }}</div> + </div> + {{# if(d.isInvoice==1) { }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票抬头:</span>{{d.invoiceClient}}</div> + </div> + {{# + var inv_json = JSON.parse(d.invoiceJson); + var inv_code = (inv_json!=null && inv_json.invoiceCode!=undefined)?inv_json.invoiceCode:''; + if(inv_json!=null && inv_json.type!=undefined && inv_json.type==0){ + }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票税号:</span>{{inv_code}}</div> + </div> + {{# } }} + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单备注:</span>{{d.orderRemarks}}</div> + </div> + </div> + + {{# if(d.isRefund==1){ }} + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款金额:</span>¥ {{d.backMoney}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款备注:</span>{{d.refundRemark}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款时间:</span>{{d.refundTime}}</div> + </div> + </div> + {{# } }} + + + <div class="detail-head"> + <div class="ui-row-flex o-shops"> + <div class="ui-col ui-col wst-or-term"><p class="shops" onclick="javascript:WST.intoShops({{d.shopId}});"><i></i>{{d.shopName}}<p></div> + </div> + {{# for(var i=0;i<d.goods.length;i++){ }} + <div class="ui-row-flex ui-whitespace border-b d-goodsitme" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}})"> + <div class="ui-col"> + <img src="__IMGURL__/{{d.goods[i].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d.goods[i].goodsName}}</p> + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d.goods[i].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d.goods[i].goodsPrice}}</p><p>x {{d.goods[i].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# if(d.goods[i].goodsType==1 && d.orderStatus==2){ }} + {{# for(var e=0;e<d.goods[i].extraJson.length;e++){ }} + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col"> + <p>卡券号:{{d.goods[i].extraJson[e].cardNo}}</p> + <p>卡券密码:{{d.goods[i].extraJson[e].cardPwd}}</p> + </div> + </div> + {{# } }} + {{# } }} + {{# } }} + </div> + + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">获得积分</span><span class="o-status2">{{d.orderScore}} 个</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">商品总额</span><span class="o-status2">¥ {{d.goodsMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">运费</span><span class="o-status2">¥ {{d.deliverMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">积分抵扣金额</span><span class="o-status2">¥ -{{d.scoreMoney}}</span></div> + </div> + {{# if(d.useScore>0){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">使用积分数</span><span class="o-status2">{{d.useScore}} 个</span></div> + </div> + {{# } }} + {{ d['hook']?d['hook']:"" }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term2"><span class="wst-or-describe2">实付款</span><span class="o-status2"><span style="font-size:0.13rem;">¥ </span>{{d.realTotalMoney}}</span></div> + </div> + </div> + </div> +</script> + {/* 遮盖层 */} + <div class="wst-cover" id="cover"></div> + {/* 订单详情层 */} + <div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span>订单详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + </div> + </div> + {/* 退款层 */} + <div class="wst-fr-box" id="refundFrame"> + <div class="title"><span>申请退款</span><i class="ui-icon-close-page" onclick="javascript:reFundDataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="refund-content"> + <div class="detail-head" style="margin-top:0;"> + <div class="wst-or-process"> + <div class="ui-row-flex" style="padding:10px;border-bottom:RGB(242,242,242) 2px dashed;"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + <div class="wst-or-refund"> + <p class="prompt">请选择取消订单申请退款的原因,以便我们能更好的为您服务。</p> + <div class="term"> + <span class="sign">*</span>退款原因: + <select id='refundReason' onchange='javascript:changeRefundType(this.value)'> + {volist name=":WSTDatas('REFUND_TYPE')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </div> + <div class="term"> + <span class="sign">*</span>退款金额: <input type='number' id='money' maxLength='10' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off"> + </div> + <p class="prompt">(金额不能超过<font color='red' id="realTotalMoney">0</font>,<span id="useScore">0</span>个积分抵扣<font color='red' id="scoreMoney">¥ 0</font>)</p> + <div class="term"> + <div id='refundTr' style="width:99%;display:none;" > + <span class="sign">*</span>其他原因 + <textarea id='refundContent' style='width:100%;height:80px;padding: 5px;' maxLength='200'></textarea> + </div> + </div> + <p class="cancel-btn-box ui-flex ui-flex-pack-center"> + <button id="wst-event8" type="button" class="ui-btn-s wst-dialog-b2">提交申请退款</button> + </p> + </div> + </div> + </div> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +<div class="ui-dialog" id="cancelBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <div class="ui-dialog-bd-title">请选择您取消订单的原因:</div> + <select id='reason'> + {volist name=":WSTDatas('ORDER_CANCEL')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event0" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> + + + +<div class="ui-dialog" id="rejectBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <div class="ui-dialog-bd-title">请选择您拒收订单的原因:</div> + <select id='reject' onchange='javascript:changeRejectType(this.value)'> + {volist name=":WSTDatas('ORDER_REJECT')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + <br /> + <div id='rejectTr' style='display:none'> + 原因<font color='red'>*</font>: + <textarea id='content' style='width:99%;height:80px;' maxLength='200'></textarea> + </div> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> + +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_list.js?v={$v}'></script> +<script> +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getOrderList(); + WST.initFooter('user'); + backPrevPage(WST.U('mobile/users/index')); + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var type = $(this).attr('type'); + $('#type').val(type); + reFlashList(); + }); + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getOrderList(); + } + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_list.js b/hyhproject/mobile2/view/default/users/orders/orders_list.js new file mode 100755 index 0000000..e8c342a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_list.js @@ -0,0 +1,333 @@ +jQuery.noConflict(); +// 提醒发货 +function noticeDeliver(id){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('mobile/orders/noticeDeliver'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +// 拒收 +function showNoticeBox(event){ + $("#wst-event4").attr("onclick","javascript:"+event); + $("#noticeBox").dialog("show"); +} + + +// 获取订单列表 +function getOrderList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/orders/getOrderList'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#order-box').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-order.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关订单</p>'; + html += '<button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button>'; + html += '</div>'; + $('#order-box').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#order-box').html(' '); + getOrderList(); +} + +function showCancelBox(event){ + $("#wst-event0").attr("onclick","javascript:"+event); + $("#cancelBox").dialog("show"); +} +// 取消订单 +function cancelOrder(oid){ + hideDialog('#cancelBox'); + $.post(WST.U('mobile/orders/cancellation'),{id:oid,reason:$('#reason').val()},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#order-box').html(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +// 拒收 +function showRejectBox(event){ + $("#wst-event3").attr("onclick","javascript:"+event); + $("#rejectBox").dialog("show"); +} + +function rejectOrder(oid){ + var param = {}; + param.id=oid; + param.reason=$('#reject').val(); + param.content=$('#content').val(); + if($('reject').val()==10000){ + var content = $.trim($('#content').val()); + if(content == '') + WST.msg('请输入拒收原因','info'); + return; + } + + $.post(WST.U('mobile/orders/reject'),param,function(data){ + + hideDialog('#rejectBox'); + + var json = WST.toJson(data); + if(json.status==1){ + $('#content').val(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +//退款 +function showRefundBox(id){ + // 重置表单 + $('#refundReason').val(1); + $('#refundContent').html(' '); + $('#money').val(' '); + $('#refundTr').hide(); + $.post(WST.U('mobile/orders/getRefund'),{id:id},function(data){ + $('#realTotalMoney').html('¥'+data.realTotalMoney); + $('#useScore').html(data.useScore); + $('#scoreMoney').html('¥ '+data.scoreMoney); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#refund-boxTitle').height();// 弹出层标题高度 + var contentH = $('#refund-content').height(); // 弹出层内容高度 + $('#refund-content').css('height',clientH-boxheadH+'px'); + $("#wst-event8").attr("onclick","javascript:refund("+id+")"); + reFundDataShow(); + }) +} +function changeRefundType(v){ + if(v==10000){ + $('#refundTr').show(); + }else{ + $('#refundTr').hide(); + } +} +//弹框 +function reFundDataHide(){ + $('#shopBox').show(); + var dataHeight = $("#refundFrame").css('height'); + var dataWidth = $("#refundFrame").css('width'); + jQuery('#refundFrame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} +function reFundDataShow(){ + jQuery('#cover').attr("onclick","javascript:reFundDataHide();").show(); + jQuery('#refundFrame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) +} +// 退款 +function refund(id){ + var params = {}; + params.reason = $.trim($('#refundReason').val()); + params.content = $.trim($('#refundContent').val()); + params.money = $.trim($('#money').val()); + params.id = id; + if(params.money<0 || params.money==''){ + WST.msg('无效的退款金额','info'); + return; + } + if(params.reason==10000){ + var content = $.trim($('#refundContent').val()); + if(content == ''){ + WST.msg('请输入原因','info'); + return; + } + } + $.post(WST.U('mobile/orderrefunds/refund'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('申请退款成功','success'); + history.go(0); + }else{ + WST.msg(json.msg,'info'); + } + }) +} + +function changeRejectType(v){ + if(v==10000){ + $('#rejectTr').show(); + }else{ + $('#rejectTr').hide(); + } +} + +// 隐藏对话框 +function hideDialog(id){ + $(id).dialog("hide"); +} + +// 确认收货 +function receive(oid){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('mobile/orders/receive'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} + + + +/*********************** 订单详情 ****************************/ +//弹框 +function dataShow(title){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) + $('#wordTitle').html(title); +} +function dataHide(){ + $('#shopBox').show(); + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getOrderDetail(oid){ + $.post(WST.U('mobile/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#content').html(html); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#boxTitle').height();// 弹出层标题高度 + var contentH = $('#content').height(); // 弹出层内容高度 + $('#content').css('height',clientH-boxheadH+'px'); + dataShow('订单详情'); + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} +// 跳转到评价页 +function toAppr(oid){ + location.href=WST.U('mobile/orders/orderappraise',{'oId':oid}); +} +// 投诉 +function complain(oid){ + location.href=WST.U('mobile/ordercomplains/complain',{'oId':oid}); +} + +//余额支付 +function walletPay(type){ + var payPwd = $('#payPwd').val(); + if(!payPwd){ + WST.msg('请输入支付密码','info'); + return; + } + if(type==0){ + var payPwd2 = $('#payPwd2').val(); + if(payPwd2==''){ + WST.msg('确认密码不能为空','info'); + return false; + } + if(payPwd!=payPwd2){ + WST.msg('确认密码不一致','info'); + return false; + } + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + var params = {}; + if(type==0){ + params.newPass = payPwd; + $.post(WST.U('mobile/users/editpayPwd'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + WST.load('成功设置密码,<br>订单支付中···'); + }else{ + WST.msg(json.msg,'info'); + } + }); + }else{ + WST.load('正在核对密码···'); + } + params.payPwd = payPwd; + params.orderNo = $('#orderNo').val(); + params.isBatch = $('#isBatch').val(); + $('.wst-btn-dangerlo').attr('disabled', 'disabled'); + setTimeout(function(){ + $.post(WST.U('mobile/wallets/payByWallet'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/orders/index'); + },2000); + }else{ + WST.msg(json.msg,'info'); + setTimeout(function(){ + $('.wst-btn-dangerlo').removeAttr('disabled'); + },2000); + } + }); + },1000); +} +//选择支付方式 +function choicePay(orderNo,isBatch){ + location.href=WST.U('mobile/orders/succeed',{'orderNo':orderNo,'isBatch':isBatch}); +} +//跳转支付 +function toPay(orderNo,isBatch,n){ + if(n=='alipays'){ + location.href=WST.U('mobile/alipays/toAliPay',{'orderNo':orderNo,'isBatch':isBatch}); + }else if(n=='wallets'){ + location.href = WST.U('mobile/wallets/payment',{"orderNo":orderNo,'isBatch':isBatch}); + }else if(n=='weixinpays'){ + location.href = WST.U('mobile/weixinpays/toWeixinPay',{"orderNo":orderNo,'isBatch':isBatch}); + } +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_pay.html b/hyhproject/mobile2/view/default/users/orders/orders_pay.html new file mode 100755 index 0000000..87c6eb3 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_pay.html @@ -0,0 +1,62 @@ +{extend name="default/base" /} +{block name="title"}我的订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header class="ui-header ui-header-positive wst-header"> + <a class="ui-icon-return" href='{:Url('mobile/orders/index')}'></a><h1>支付订单</h1> + </header> +{/block} +{block name="main"} + + <section class="ui-container" id="shopBox"> + {volist name="$rs['list']" id="order"} + <div class="order-item"> + <div class="ui-row-flex item-head" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{$order['orderNo']}<span style="float : right;">邮费:{$order['deliverMoney']}</span></div> + </div> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <div class="ui-row-flex"> + <div class="ui-col"> + <img src="__IMGURL__/{$vo['goodsImg']}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{$vo['goodsName']}</p> + {if condition="count($vo['goodsSpecNames']) gt 0"} + <p class="o-gSpec ui-nowrap-flex">规格: + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + </p> + {/if} + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0"><p>¥ {$vo['goodsPrice']}</p><p>x {$vo['goodsNum']}</p></div> + </div> + {/volist} + + <div class="ui-btn-wrap" style="text-align: right;padding:10px 0"> + <span class="wst-orders_pricet">总金额:<span class="wst-orders_prices">¥ <?php echo sprintf("%.2f", $rs['totalMoney']);?></span></span> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + <div style="text-align: center;padding-top: 20px;"> + <button type="button" class="wst-btn-dangerlo" onclick="javascript:callpay();" style="width: 80%; display: inline-block;">确认支付</button> + </div> + </section> + + </div> + +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_list.js?v={$v}'></script> +<script> +$(document).ready(function(){ + backPrevPage(WST.U('mobile/orders/index')); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_pay_list.html b/hyhproject/mobile2/view/default/users/orders/orders_pay_list.html new file mode 100755 index 0000000..5c65801 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_pay_list.html @@ -0,0 +1,27 @@ +{extend name="default/base" /} +{block name="title"}选择支付方式 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>选择支付方式</h1> + </header> +{/block} +{block name="main"} + <section class="ui-container"> + <ul class="ui-list ui-list-text ui-list-link wst-pa-l"> + {volist name="$payments[1]" id="pa"} + <li class="line" onclick="javascript:toPay({$orderNo},{$isBatch},'{$pa['payCode']}');"> + <span class="{$pa['payCode']}"></span><h5 class="ui-nowrap">{$pa['payName']}</h5> + </li> + {/volist} + </ul> + </section> +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_pay_wallets.html b/hyhproject/mobile2/view/default/users/orders/orders_pay_wallets.html new file mode 100755 index 0000000..fd1056a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_pay_wallets.html @@ -0,0 +1,86 @@ +{extend name="default/base" /} +{block name="title"}支付订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-header"> + <a class="ui-icon-return" href='{:Url('mobile/orders/index')}'></a><h1>支付订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <section class="ui-container"> + {if(empty($message))} + <input type="hidden" name="" value="{$data['orderNo']}" id="orderNo" autocomplete="off"> + <input type="hidden" name="" value="{$data['isBatch']}" id="isBatch" autocomplete="off"> + {volist name="$rs['list']" id="order"} + <div class="order-item"> + <div class="ui-row-flex item-head"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{$order['orderNo']}<span style="float : right;">邮费:{$order['deliverMoney']}</span></div> + </div> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <div class="ui-row-flex"> + <div class="ui-col"> + <img src="__IMGURL__/{$vo['goodsImg']}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{$vo['goodsName']}</p> + {if condition="count($vo['goodsSpecNames']) gt 0"} + <p class="o-gSpec ui-nowrap-flex">规格: + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + </p> + {/if} + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0"><p>¥ {$vo['goodsPrice']}</p><p>x {$vo['goodsNum']}</p></div> + </div> + {/volist} + <div class="ui-btn-wrap" style="text-align: right;padding:10px 0"> + <span class="wst-orders_pricet">总金额:<span class="wst-orders_prices">¥ <?php echo sprintf("%.2f", $rs['totalMoney']);?></span></span> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + <div class="wst-wa-info"> + <p class="info">钱包余额:<span>¥ {$userMoney}</span>,待支付订单总额:<span>¥ {$needPay}</span></p> + {if($payPwd==0)} + <p class="pay-info">您尚未设置支付密码,请设置支付密码</p> + <div class="pay">设置密码:<input type="password" id="payPwd" maxlength="30" autocomplete="off"></div> + <div class="pay">确认密码:<input type="password" id="payPwd2" maxlength="30" autocomplete="off"></div> + {else} + <div class="pay">支付密码:<input type="password" id="payPwd" maxlength="30" autocomplete="off"></div> + {/if} + </div> + {if($payPwd==1)}<div class="wst-wa-forget ui-whitespace"><a href="{:url('mobile/users/backPayPass')}">忘记密码?</a></div>{/if} + <div style="text-align: center;"> + <button type="button" class="wst-btn-dangerlo" onclick="javascript:walletPay({$payPwd});" style="width: 80%; display: inline-block;">确认支付</button> + </div> + {else} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>{$message}</p> + </li> + </ul> + {/if} + </section> +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/orders/orders_list.js?v={$v}'></script> +<script> +$(document).ready(function(){ + backPrevPage(WST.U('mobile/orders/index')); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/orders/orders_wxpay.html b/hyhproject/mobile2/view/default/users/orders/orders_wxpay.html new file mode 100755 index 0000000..b0e3e8a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/orders/orders_wxpay.html @@ -0,0 +1,103 @@ +{extend name="default/base" /} +{block name="title"} +{$payObj=='recharge'?"在线充值":"支付订单"} +- {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header class="ui-header ui-header-positive wst-header"> + {if($payObj=='recharge')} + <a class="ui-icon-return" href='{:Url('mobile/logmoneys/usermoneys')}'></a><h1>在线充值</h1> + {else} + <a class="ui-icon-return" href='{:Url('mobile/orders/index')}'></a><h1>支付订单</h1> + {/if} + </header> +{/block} +{block name="main"} + <section class="ui-container" id="shopBox"> + {if(empty($message))} + {if($payObj=='recharge')} + <div class="recharge-box"> + <div>钱包充值</div> + <div class="paybox"><span class="wst-orders_prices">¥ {$needPay}</span></div> + </div> + {else} + {volist name="$rs['list']" id="order"} + <div class="order-item"> + <div class="ui-row-flex item-head" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{$order['orderNo']}<span style="float : right;">邮费:{$order['deliverMoney']}</span></div> + </div> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <div class="ui-row-flex"> + <div class="ui-col"> + <img src="__IMGURL__/{$vo['goodsImg']}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{$vo['goodsName']}</p> + {if condition="count($vo['goodsSpecNames']) gt 0"} + <p class="o-gSpec ui-nowrap-flex">规格: + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + </p> + {/if} + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0"><p>¥ {$vo['goodsPrice']}</p><p>x {$vo['goodsNum']}</p></div> + </div> + {/volist} + + <div class="ui-btn-wrap" style="text-align: right;padding:10px 0"> + <span class="wst-orders_pricet">总金额:<span class="wst-orders_prices">¥ <?php echo sprintf("%.2f", $rs['totalMoney']);?></span></span> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + {/if} + <div style="text-align: center;padding-top: 20px;"> + <button type="button" class="wst-btn-dangerlo" onclick="javascript:callpay();" style="width: 80%; display: inline-block;">确认支付</button> + </div> + </section> + {else} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>{$message}</p> + </li> + </ul> + {/if} + </div> +<div class="ui-dialog" id="wst-di-wxpay"> + <div class="ui-dialog-cnt"> + <header class="ui-dialog-hd ui-border-b"> + <h3>请确认微信支付已完成</h3> + <i class="ui-dialog-close" data-role="button"></i> + </header> + <div class="ui-dialog-hd ui-border-b"> + <a href="{$returnUrl}"><div style="color:red;">已完成支付</div></a> + </div> + <div class="ui-dialog-hd ui-border-b"> + <a href=""><div >支付遇到问题,重新支付</div></a> + </div> + </div> +</div> +{/block} +{block name="footer"}{/block} +{block name="js"} + +{if(empty($message))} +<script type="text/javascript"> + function callpay(){ + $("#wst-di-wxpay").dialog("show"); + location.href = "{$mweb_url}"; + } + $(document).ready(function(){ + {if($payObj=='recharge')} + backPrevPage(WST.U('mobile/logmoneys/usermoneys')); + {else} + backPrevPage(WST.U('mobile/orders/index')); + {/if} + }); + </script> +{/if} +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/qrcode.js b/hyhproject/mobile2/view/default/users/qrcode.js new file mode 100755 index 0000000..5507c15 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a> + * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a> + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}} + this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}} + return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;} + this.modules[r][6]=(r%2==0);} + for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;} + this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;} + for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);} + var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;} + if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];} + offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;} + var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}} + for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}} + return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));} + return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;} + for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;} + if(r==0&&c==0){continue;} + if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}} + if(sameCount>5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}} + for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}} + for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}} + var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}} + var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");} + return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;} + while(n>=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;} + for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];} + for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;} + function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);} + var offset=0;while(offset<num.length&&num[offset]==0){offset++;} + this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}} + QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}} + return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;} + var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);} + for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);} + return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;} + QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);} + var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}} + return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;} + QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['<table style="border:0;border-collapse:collapse;">']; + + for (var row = 0; row < nCount; row++) { + aHTML.push('<tr>'); + + for (var col = 0; col < nCount; col++) { + aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>'); + } + + aHTML.push('</tr>'); + } + + aHTML.push('</table>'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/hyhproject/mobile2/view/default/users/recharge/recharge.html b/hyhproject/mobile2/view/default/users/recharge/recharge.html new file mode 100755 index 0000000..8169d7f --- /dev/null +++ b/hyhproject/mobile2/view/default/users/recharge/recharge.html @@ -0,0 +1,86 @@ +{extend name="default/base" /} +{block name="title"}我的资金 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/recharge.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>充值</h1> + </header> +{/block} +{block name="main"} + + <section class="ui-container"> + + <ul class="ui-grid-trisect"> + {volist name="chargeItems" id="item"} + <li > + <div class=" wst-frame2 {$key} " onclick="javascript:changeSelected({$item['id']},'itemId',this)"> + <div> + {if condition="$item['giveMoney'] gt 0"} + <div class='charge-doub'>充值 <span class="charge-money" id="needPay_{$item['id']}" sum="{$item['chargeMoney']}">{$item['chargeMoney']}</span> 元</div> + <div>送 {$item['giveMoney']} 元</div> + {else/} + <div class='charge-alone'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + {/if} + </div> + <i></i> + </div> + + </li> + {/volist} + <li > + <div class="wst-frame2 " onclick="javascript:changeSelected(0,'itemId',this)"> + <div> + <div class='charge-alone'> + <span class="j-charge-other">其他金额</span> + <span class="j-charge-money"> + <input class="charge-othermoney j-ipt" id="needPay" value="1" maxlength="10" data-rule="充值金额:required;" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:WST.isChinese(this,1)" maxlength="8"> + </span> + </div> + </div> + <i></i> + </div> + + </li> + </ul> + {php} + $sum = 0; + if($chargeItems){ + $sum = $chargeItems[0]['chargeMoney']; + } + {/php} + <div class="wst-re-info"> + <p>当前余额<span class="balance">¥ <span>{$rs['userMoney']}</span></span></p> + <p>充值金额<span class="balance">¥ <span id="rechargeMoney">{$sum}</span></span></p> + </div> + <div class="ui-form"> + {volist name="payments" id="payment" } + <div class="ui-form-item ui-form-item-radio paytype-term"> + <label class="ui-checkbox" for="radio"> + <input type="radio" {if condition="$key eq 0"}checked{/if} name="payCode" value="{$payment['payCode']}"> + </label> + <i class="{$payment['payCode']}"></i> + <p>{$payment['payName']}</p> + </div> + {/volist} + </div> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-re-button" onclick="toPay()">确认支付</button> + </div> + <div class="tips-box"> + <ul class="ui-row first-time"> + <li class="ui-col ui-col-100 ft-title"><i></i><span>充值说明:</span></li> + <li class="ui-col ui-col-100 ft-item">1.充值金额和赠送金额只能用于购买商品,不能提现;</li> + </ul> + </div> + <input type="hidden" value="" id='itemId' class='j-ipt' /> + </section> +{/block} + +{block name="footer"} +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/recharge/recharge.js?v={$v}'></script> +{/block} diff --git a/hyhproject/mobile2/view/default/users/recharge/recharge.js b/hyhproject/mobile2/view/default/users/recharge/recharge.js new file mode 100755 index 0000000..80847a5 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/recharge/recharge.js @@ -0,0 +1,52 @@ +jQuery.noConflict(); +function inEffect(obj,n){ + $("ul div").removeClass('j-selected'); + $(obj).addClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + if(n==0){ + $(".j-charge-other").hide(); + $(".j-charge-money").show(); + var needPay = $("#needPay").val(); + + }else{ + $(".j-charge-other").show(); + $(".j-charge-money").hide(); + var needPay = $("#needPay_"+n).attr("sum"); + } + rechargeMoney(needPay); + inEffect(obj,2); +} +function rechargeMoney(n){ + $("#rechargeMoney").html(n); +} + + +function toPay(){ + var params = {}; + params.payObj = "recharge"; + params.targetType = 0; + params.needPay = $.trim($("#needPay").val()); + params.payCode = $("input[name='payCode']:checked").val(); + params.itemId = $.trim($("#itemId").val()); + if(params.itemId==0 && params.needPay<=0){ + WST.msg('请输入充值金额', 'info'); + return; + } + if(params.payCode==""){ + WST.msg('请先选择支付方式','info'); + return; + } + if(params.payCode=="weixinpays"){ + location.href = WST.U('mobile/Weixinpays/toWeixinPay',params); + }else{ + location.href = WST.U('mobile/Alipays/toAliPay',params); + } + + +} + +$(function(){ + jQuery(".wst-frame2:first").click(); +}); \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/index.html b/hyhproject/mobile2/view/default/users/security/index.html new file mode 100755 index 0000000..780f345 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/index.html @@ -0,0 +1,27 @@ +{extend name="default/base" /} +{block name="title"}账户安全 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "账户安全"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <section class="ui-container"> + <ul class="ui-list ui-list-text ui-list-link wst-se-l"> + <li class="line" onclick="javascript:inLogin();"> + <span class="pay"></span><h5 class="ui-nowrap">{if($user['loginPwd']==0)}设置{else}修改{/if}登录密码</h5></a> + </li> + <li class="line" onclick="javascript:inPay();"> + <span class="pay"></span><h5 class="ui-nowrap">{if($user['payPwd']==0)}设置{else}修改{/if}支付密码</h5></a> + </li> + <li onclick="javascript:inPhone();"> + <span class="phone"></span><h5 class="ui-nowrap">{if($user['userPhone']==0)}绑定{else}修改{/if}手机号码</h5> + </li> + </ul> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/security.js b/hyhproject/mobile2/view/default/users/security/security.js new file mode 100755 index 0000000..31afd00 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/security.js @@ -0,0 +1,338 @@ +var time = 0; +var isSend = false; +$(document).ready(function(){ + WST.initFooter('user'); +}); +//修改登录密码 +function inLogin(){ + location.href = WST.U('mobile/users/editLoginPass'); +} +function editLogin(type){ + if(type==1){ + var orloginPwd = $('#orloginPwd').val(); + if(orloginPwd==''){ + WST.msg('原密码不能为空','info'); + $('#orloginPwd').focus(); + return false; + } + } + var loginPwd = $('#loginPwd').val(); + var cologinPwd = $('#cologinPwd').val(); + if(loginPwd==''){ + WST.msg('新密码不能为空','info'); + $('#loginPwd').focus(); + return false; + } + if(cologinPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#cologinPwd').focus(); + return false; + } + if(loginPwd.length < 6){ + WST.msg('请输入6位以上数字或者字母密码','info'); + $('#cologinPwd').focus(); + return false; + } + if(cologinPwd!=loginPwd){ + WST.msg('确认密码不一致','info'); + $('#cologinPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(type==1)var orloginPwd = rsa.encrypt(orloginPwd); + var loginPwd = rsa.encrypt(loginPwd); + } + WST.load('设置中···'); + var param = {}; + param.type = type; + if(type==1) param.oldPass = orloginPwd; + param.newPass = loginPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/editloginPwd'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/users/security'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +//修改密码 +function inPay(){ + location.href = WST.U('mobile/users/editPayPass'); +} +function editPay(type){ + if(type==1){ + var orpayPwd = $('#orpayPwd').val(); + if(orpayPwd==''){ + WST.msg('原密码不能为空','info'); + $('#orpayPwd').focus(); + return false; + } + } + var payPwd = $('#payPwd').val(); + var copayPwd = $('#copayPwd').val(); + if(payPwd==''){ + WST.msg('新密码不能为空','info'); + $('#payPwd').focus(); + return false; + } + if(copayPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#copayPwd').focus(); + return false; + } + if(payPwd.length <6){ + WST.msg('请输入6位以上数字或者字母密码','info'); + $('#copayPwd').focus(); + return false; + } + if(copayPwd!=payPwd){ + WST.msg('确认密码不一致','info'); + $('#copayPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(type==1)var orpayPwd = rsa.encrypt(orpayPwd); + var payPwd = rsa.encrypt(payPwd); + } + WST.load('设置中···'); + var param = {}; + param.type = type; + if(type==1)param.oldPass = orpayPwd; + param.newPass = payPwd; + param.reNewPass = copayPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/editpayPwd'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/users/security'); + },2000); + }else if(json.status == -2){ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +//找回支付密码 +function backpayCode(){ + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('mobile/users/backpayCode'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg"); + isSend = false; + } + data = json = null; + }); +} +function backPaypwd(type){ + if(type==1){ + var payPwd = $('#payPwd').val(); + var copayPwd = $('#copayPwd').val(); + if(payPwd==''){ + WST.msg('新密码不能为空','info'); + $('#payPwd').focus(); + return false; + } + if(copayPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#copayPwd').focus(); + return false; + } + if(payPwd.length !=6){ + WST.msg('请输入6位数字密码','info'); + $('#copayPwd').focus(); + return false; + } + if(copayPwd!=payPwd){ + WST.msg('确认密码不一致','info'); + $('#copayPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + WST.load('设置中···'); + var param = {}; + param.newPass = payPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/resetbackPay'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/users/security'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); + }else{ + var phoneCode = $('#phoneCode').val(); + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + $('#phoneCode').focus(); + return false; + } + var param = {}; + param.phoneCode = phoneCode; + $('#modifyPhone').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/verifybackPay'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/users/backPayPass'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPhone').removeAttr('disabled').removeClass("active"); + } + data = json = null; + }); + } +} +//修改手机 +function inPhone(){ + location.href = WST.U('mobile/users/editPhone'); +} +//发送短信 +function obtainCode(type){ + if(type==0){ + var userPhone = $('#userPhone').val(); + if(userPhone ==''){ + WST.msg('请输入手机号码','info'); + $('#userPhone').focus(); + return false; + } + } + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.userPhone = userPhone; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('mobile/users/'+((type==0)?"sendCodeTie":"sendCodeEdit")), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg"); + isSend = false; + } + data = json = null; + }); +} +//修改手机号码 +function editPhone(type){ + if(type==0){ + var userPhone = $('#userPhone').val(); + if(userPhone==''){ + WST.msg('手机号码不能为空','info'); + $('#userPhone').focus(); + return false; + } + } + var phoneCode = $('#phoneCode').val(); + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + $('#phoneCode').focus(); + return false; + } + var param = {}; + param.phoneCode = phoneCode; + $('#modifyPhone').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/users/'+((type==0)?"phoneEdit":"phoneEdito")), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + if(type==0){ + setTimeout(function(){ + location.href = WST.U('mobile/users/security'); + },2000); + }else{ + setTimeout(function(){ + location.href = WST.U('mobile/users/editPhoneo'); + },2000); + } + + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPhone').removeAttr('disabled').removeClass("active"); + } + data = json = null; + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/user_back_paypwd.html b/hyhproject/mobile2/view/default/users/security/user_back_paypwd.html new file mode 100755 index 0000000..c1ee243 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/user_back_paypwd.html @@ -0,0 +1,64 @@ +{extend name="default/base" /} +{block name="title"}找回支付密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "找回支付密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + {if($user['phoneType']==1)} + <div class="wst-se-footer"> + <button id="modifyPhone" type="button" class="button" onclick="javascript:backPaypwd({$user['backType']});">{if($user['backType']==0)}下一步{else}确定{/if}</button> + </div> + {else} + <div class="wst-se-footer"> + <button id="modifyPhone" type="button" class="button" onclick="javascript:inPhone();">去绑定手机号码</button> + </div> + {/if} +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + {if($user['backType']==1)} + <div class="wst-se-pay"> + <div class="pay"><input id="payPwd" type="password" placeholder="新密码" maxlength="30"></div> + <div class="pay"><input id="copayPwd" type="password" placeholder="确认密码" maxlength="30"></div> + </div> + {else} + {if($user['phoneType']==1)} + <div class="wst-se-pay"> + <div class="phone">您绑定的手机号码为:{$user['userPhone']}</div> + {if(WSTConf('CONF.smsVerfy')==1)} + <div class="verify"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'> + </div> + {/if} + <div class="verify"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" type="button" class="ui-btn-primary" onclick="javascript:backpayCode()">获取验证码</button> + </div> + </div> + {else} + <ul class="ui-row-flex wst-flexslp ui-whitespace"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>对不起,你还未绑定手机号码,请去绑定手机号码。</p> + </li> + </ul> + {/if} + {/if} + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/user_login_pass.html b/hyhproject/mobile2/view/default/users/security/user_login_pass.html new file mode 100755 index 0000000..bf49407 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/user_login_pass.html @@ -0,0 +1,35 @@ +{extend name="default/base" /} +{block name="title"}{if($user['loginPwd']==1)}修改{else}设置{/if}登录密码- {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['loginPwd']==1?$Title = "修改登录密码":$Title = "设置登录密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPwd" type="button" class="button" onclick="javascript:editLogin({$user['loginPwd']});">确定</button> + </div> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['loginPwd']==1)}<div class="pay"><input id="orloginPwd" type="password" placeholder="原密码"></div>{/if} + <div class="pay"><input id="loginPwd" type="password" placeholder="新密码"></div> + <div class="pay"><input id="cologinPwd" type="password" placeholder="确认密码"></div> + </div> + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/user_pay_pass.html b/hyhproject/mobile2/view/default/users/security/user_pay_pass.html new file mode 100755 index 0000000..013230c --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/user_pay_pass.html @@ -0,0 +1,36 @@ +{extend name="default/base" /} +{block name="title"}{if($user['payPwd']==1)}修改{else}设置{/if}支付密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['payPwd']==1?$Title = "修改支付密码":$Title = "设置支付密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPwd" class="ui-btn-lg button" onclick="javascript:editPay({$user['payPwd']});">确定</button> + </div> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['payPwd']==1)}<div class="pay"><input id="orpayPwd" type="password" placeholder="原密码" maxlength="30"></div>{/if} + <div class="pay"><input id="payPwd" type="password" placeholder="新密码" maxlength="30"></div> + <div class="pay"><input id="copayPwd" type="password" placeholder="确认密码" maxlength="30"></div> + </div> + {if($user['payPwd']==1)}<p class="wst-se-back"><a href="{:url('mobile/users/backPayPass')}">忘记支付密码?</a></p>{/if} + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__MOBILE__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/security/user_phone.html b/hyhproject/mobile2/view/default/users/security/user_phone.html new file mode 100755 index 0000000..ffb2a05 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/security/user_phone.html @@ -0,0 +1,45 @@ +{extend name="default/base" /} +{block name="title"}{if($user['phoneType']==1)}修改{else}绑定{/if}手机号码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['phoneType']==1?$Title = "修改手机号码":$Title = "绑定手机号码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPhone" class="ui-btn-lg button" onclick="javascript:editPhone({$user['phoneType']});">{if($user['phoneType']==1)}下一步{else}确定{/if}</button> + </div> +{/block} +{block name="main"} + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['phoneType']==1)} + <div class="phone">您绑定的手机号码为:{$user['userPhone']}</div> + {else} + <div class="pay"><input id="userPhone" type="tel" placeholder="手机号码"></div> + {/if} + {if(WSTConf('CONF.smsVerfy')==1)} + <div class="verify"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg' src="{:url('mobile/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'> + </div> + {/if} + <div class="verify"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" class="ui-btn ui-btn-primary" onclick="javascript:obtainCode({$user['phoneType']})">获取验证码</button> + </div> + </div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/sellerorders/orders_list.html b/hyhproject/mobile2/view/default/users/sellerorders/orders_list.html new file mode 100755 index 0000000..08c179f --- /dev/null +++ b/hyhproject/mobile2/view/default/users/sellerorders/orders_list.html @@ -0,0 +1,439 @@ +{extend name="default/base" /} +{block name="title"}我的订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header wst-headero"> + <i class="ui-icon-return" onclick="location.href='{:url('mobile/users/index')}'"></i><h1>我的订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="order-item"> + <div class="ui-row-flex ui-whitespace item-head" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{{d[i].orderNo}} + {{#if(d[i].orderStatus==0 && d[i].noticeDeliver==1){}}<span class='notice'> + <img style='width:0.2rem' src='{{WST.conf.ROOT}}\hyhproject\mobile\view\default\img\nocite_deliver.png'>提醒发货</span> + {{#}}} + </div> + <div class="ui-col order-tr o-status"> + {{ d[i].status }} + {{# if($.inArray(d[i].orderStatus,[-1,-3])!=-1){ }} + {{# if(d[i].payType==1 && d[i].isPay==1) { }} + {{# if(d[i].isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }} + </div> + </div> + + {{# for(var g=0;g<d[i].list.length;g++){ }} + <div class="ui-row-flex ui-whitespace border-b" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col"> + <img src="__IMGURL__/{{d[i].list[g].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d[i].list[g].goodsName}}</p> + + {{# if(d[i].list[g].goodsSpecNames){ }} + <p class="o-gSpec ui-nowrap-flex ui-whitespace">规格:{{d[i].list[g].goodsSpecNames}}</p> + {{# } }} + + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d[i].list[g].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d[i].list[g].goodsPrice}}</p><p>x {{d[i].list[g].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# } }} + + + <div style="padding-top:5px;padding-bottom:5px;"> + <div class="o-oListMoney"> + 订单总价:<span>¥ {{d[i].realTotalMoney}}</span> + </div> + <div class="wst-clear"></div> + {{# if(d[i].orderStatus==-2){ }} + <button class="ui-btn o-btn" onclick="showEditMoneyBox('editOrderMoney({{d[i].orderId}})')"> + 修改价格 + </button> + {{# } }} + + {{# if(d[i].orderStatus==0){ }} + <button class="ui-btn o-btn" onclick="toDeliver({{d[i].orderId}},{{d[i].deliverTypes}})"> + 发货 + </button> + {{# } }} + + {{# if(d[i].payType==1 && WST.blank(d[i].refundId)!=''){ }} + <button class="ui-btn o-btn" onclick="showRefundBox({{d[i].refundId}})"> + 退款操作 + </button> + {{# } }} + + + + + {{# if(d[i].isAppraise==1){ }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 查看评价 + </button> + {{# } }} + <div class="wst-clear"></div> + </div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + <?php $shopMenus = WSTShopOrderMenus();?> + {if (count($shopMenus)==6)} + <li class="tab-item {if $type=='all'}tab-curr{/if}" type="all" >全部</li> + {/if} + {if array_key_exists("waitPay",$shopMenus)} + <li class="tab-item {if $type=='waitPay'}tab-curr{/if}" type="waitPay" >待付款</li> + {/if} + {if array_key_exists("waitDeliver",$shopMenus)} + <li class="tab-item {if $type=='waitDeliver'}tab-curr{/if}" type="waitDeliver" >待发货</li> + {/if} + {if array_key_exists("waitReceive",$shopMenus)} + <li class="tab-item {if $type=='waitReceive'}tab-curr{/if}" type="waitReceive" >待收货</li> + {/if} + {if array_key_exists("waitAppraise",$shopMenus)} + <li class="tab-item {if $type=='waitAppraise'}tab-curr{/if}" type="waitAppraise" >待评价</li> + {/if} + {if array_key_exists("finish",$shopMenus)} + <li class="tab-item {if $type=='finish'}tab-curr{/if}" type="finish" >已完成</li> + {/if} + {if array_key_exists("abnormal",$shopMenus)} + <li class="tab-item {if $type=='abnormal'}tab-curr{/if}" type="abnormal" >取消拒收</li> + {/if} + </ul> + </div> + <div id="order-box"></div> + </section> + </div> + +<script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="detail-head" style="margin-top:0;"> + {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + {{# if(d.payType==1) { }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待付款</p></div> + {{# } }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.orderStatus==2){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已收货</p></div> + </div> + </div> + {{# } }} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1 && d.payType==1 && d.isPay==1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==2) { }} active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单状态:</span> + <span class="o-status">{{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.payType==1 && d.isPay==1) { }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单编号:</span>{{d.orderNo}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">下单时间:</span>{{d.createTime}}</div> + </div> + </div> + + + <div class="detail-head"> + {{# if(d.userName){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货人:</span>{{d.userName}} <span class="d-utel">{{d.userPhone}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货地址:</span><span class="d-uaddr">{{d.userAddress}}<i></i></span></div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付信息:</span>{{d.payInfo}}</div> + </div> + {{# if(d.payTime){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付时间:</span>{{d.payTime}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">配送信息:</span>{{d.deliverInfo}}</div> + </div> + {{# if(WST.blank(d.expressNo)!=''){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递公司:</span>{{d.expressName}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递号:</span>{{d.expressNo}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票信息:</span>{{# if(d.isInvoice==1) { }}需要{{# } else{ }}不需要{{# } }}</div> + </div> + {{# if(d.isInvoice==1) { }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票抬头:</span>{{d.invoiceClient}}</div> + </div> + {{# + var inv_json = JSON.parse(d.invoiceJson); + var inv_code = (inv_json!=null && inv_json.invoiceCode!=undefined)?inv_json.invoiceCode:''; + if(inv_json!=null && inv_json.type!=undefined && inv_json.type==0){ + }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票税号:</span>{{inv_code}}</div> + </div> + {{# } }} + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单备注:</span>{{d.orderRemarks}}</div> + </div> + </div> + + {{# if(d.isRefund==1){ }} + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款金额:</span>¥ {{d.backMoney}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款备注:</span>{{d.refundRemark}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款时间:</span>{{d.refundTime}}</div> + </div> + </div> + {{# } }} + + + <div class="detail-head"> + <div class="ui-row-flex o-shops"> + <div class="ui-col ui-col wst-or-term"><p class="shops" onclick="javascript:WST.intoShops({{d.shopId}});"><i></i>{{d.shopName}}<p></div> + </div> + {{# for(var i=0;i<d.goods.length;i++){ }} + <p>商品编号: {{d.goods[i].goodsSn}}</p> + <div class="ui-row-flex ui-whitespace border-b d-goodsitme" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}})"> + <div class="ui-col"> + <img src="__IMGURL__/{{d.goods[i].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d.goods[i].goodsName}}</p> + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d.goods[i].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d.goods[i].goodsPrice}}</p><p>x {{d.goods[i].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# if(d.goods[i].goodsType==1 && d.orderStatus==2){ }} + {{# for(var e=0;e<d.goods[i].extraJson.length;e++){ }} + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col"> + <p>卡券号:{{d.goods[i].extraJson[e].cardNo}}</p> + <p>卡券密码:{{d.goods[i].extraJson[e].cardPwd}}</p> + </div> + </div> + {{# } }} + {{# } }} + {{# } }} + </div> + + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">获得积分</span><span class="o-status2">{{d.orderScore}} 个</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">商品总额</span><span class="o-status2">¥ {{d.goodsMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">运费</span><span class="o-status2">¥ {{d.deliverMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">积分抵扣金额</span><span class="o-status2">¥ -{{d.scoreMoney}}</span></div> + </div> + {{# if(d.useScore>0){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">使用积分数</span><span class="o-status2">{{d.useScore}} 个</span></div> + </div> + {{# } }} + {{ d['hook']?d['hook']:"" }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term2"><span class="wst-or-describe2">实付款</span><span class="o-status2"><span style="font-size:0.13rem;">¥ </span>{{d.realTotalMoney}}</span></div> + </div> + </div> + </div> +</script> + {/* 遮盖层 */} + <div class="wst-cover" id="cover"></div> + {/* 订单详情层 */} + <div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span>订单详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + </div> + </div> + {/* 退款层 */} + <div class="wst-fr-box" id="refundFrame"> + <div class="title"><span>申请退款</span><i class="ui-icon-close-page" onclick="javascript:reFundDataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="refund-content"> + <div class="detail-head" style="margin-top:0;"> + <div class="wst-or-process"> + <div class="ui-row-flex" style="padding:10px;border-bottom:RGB(242,242,242) 2px dashed;"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span class="active"></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + <div class="wst-or-refund"> + <p class="term" style="padding: 3px 5px 0 5px;">订单号:<span id="refundOid"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">实付金额:<span id="realTotalMoney"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">退款金额:<span id="refundMoney" class="sign"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">退款积分:<span id="useScore" class="sign">0</span> 个(积分抵扣<span id="scoreMoney" class="sign">¥ 0</span>)</p> + <p style="padding: 3px 5px 0 5px;">商家意见: + <label><input type='radio' onclick='WST.showHide(0,"#tr")' name='refundStatus' id='refundStatus' value='1' checked/>同意</label> + <label style='margin-left:15px;'><input type='radio' onclick='WST.showHide(1,"#tr")' name='refundStatus' id='refundStatus' value='-1'/>不同意</label> + </p> + <div class="term"> + <div id='tr' style="width:99%;display:none;" > + <span class="sign">*</span>原因 + <textarea id='shopRejectReason' style='width:100%;height:80px;padding: 5px;' maxLength='200'></textarea> + </div> + </div> + <p class="cancel-btn-box ui-flex ui-flex-pack-center"> + <button id="wst-event8" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> + </div> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/* 发货 */} +<div class="ui-dialog" id="deliveryBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + 快递公司:<br> + <select id='expressId' style="height:30px;width:100%;"> + {volist name="$express" id="vo"} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select><br> + 快递号:<br> + <input type="text" id="expressNo" style="float: left;height:30px;width:100%;"/> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event0" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> + +{/* 修改价格 */} +<div class="ui-dialog" id="editMoneyBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + 新价格:<input type='text' id='newOrderMoney' maxLength='10' style='width:150px;height:30px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/sellerorders/orders_list.js?v={$v}'></script> +<script> +$(document).ready(function(){ + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/sellerorders/orders_list.js b/hyhproject/mobile2/view/default/users/sellerorders/orders_list.js new file mode 100755 index 0000000..3d0c8da --- /dev/null +++ b/hyhproject/mobile2/view/default/users/sellerorders/orders_list.js @@ -0,0 +1,288 @@ +jQuery.noConflict(); +// 获取订单列表 +function getOrderList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + param.deliverType = -1; + param.payType = -1; + $.post(WST.U('mobile/orders/getSellerOrderList'), param, function(data){ + var json = WST.toJson(data); + if(json.status>0){ + var html = ''; + json = json.data; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#order-box').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-order.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关订单</p>'; + html += '</div>'; + $('#order-box').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }else{ + WST.msg(json.msg,'info'); + } + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + + $('#type').val(jQuery("#shopBox li:first").attr("type")); + jQuery("#shopBox li:first").addClass("tab-curr"); + getOrderList(); + + WST.initFooter('user'); + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var type = $(this).attr('type'); + $('#type').val(type); + reFlashList(); + }); + // 弹出层 + $("#frame").css('top',0); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getOrderList(); + } + } + }); +}); + +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#order-box').html(' '); + getOrderList(); +} + + +// 拒收 +function showEditMoneyBox(event){ + $("#wst-event3").attr("onclick","javascript:"+event); + $("#editMoneyBox").dialog("show"); +} + +function editOrderMoney(oid){ + var newOrderMoney = $('#newOrderMoney').val(); + $.post(WST.U('mobile/orders/editOrderMoney'),{id:oid,orderMoney:newOrderMoney},function(data){ + hideDialog('#editMoneyBox'); + var json = WST.toJson(data); + if(json.status>0){ + $('#newOrderMoney').val(' '); + WST.msg(json.msg,'success'); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +//退款 +function showRefundBox(id){ + $.post(WST.U('mobile/orders/toShopRefund'),{id:id},function(data){ + var json = WST.toJson(data); + $('#refundOid').html(json.orderNo); + $('#realTotalMoney').html('¥ '+json.realTotalMoney); + $('#refundMoney').html('¥ '+json.backMoney); + $('#useScore').html(json.useScore); + $('#scoreMoney').html('¥ '+json.scoreMoney); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#refund-boxTitle').height();// 弹出层标题高度 + var contentH = $('#refund-content').height(); // 弹出层内容高度 + $('#refund-content').css('height',clientH-boxheadH+'px'); + $("#wst-event8").attr("onclick","javascript:refund("+id+")"); + reFundDataShow(); + }) +} +//弹框 +function reFundDataHide(){ + $('#shopBox').show(); + var dataHeight = $("#refundFrame").css('height'); + var dataWidth = $("#refundFrame").css('width'); + jQuery('#refundFrame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} +function reFundDataShow(){ + jQuery('#cover').attr("onclick","javascript:reFundDataHide();").show(); + jQuery('#refundFrame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) +} +// 退款 +function refund(id){ + + var params = {}; + params.refundStatus = $('#refundStatus')[0].checked?1:-1; + params.content = $.trim($('#shopRejectReason').val()); + params.id = id; + if(params.refundStatus==-1 && params.content==''){ + WST.msg('请输入原因','info'); + return; + } + $.post(WST.U('mobile/orderrefunds/shoprefund'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('操作成功','success'); + history.go(0); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +// 隐藏对话框 +function hideDialog(id){ + $(id).dialog("hide"); +} + +// 确认收货 +function receive(oid){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('mobile/orders/receive'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} + + + +/*********************** 订单详情 ****************************/ +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) + +} +function dataHide(){ + $('#shopBox').show(); + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getOrderDetail(oid){ + $.post(WST.U('mobile/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#content').html(html); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#boxTitle').height();// 弹出层标题高度 + var contentH = $('#content').height(); // 弹出层内容高度 + if((clientH-boxheadH) < contentH){ + $('#content').css('height',clientH-boxheadH+'px'); + } + dataShow(); + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} +// 跳转到评价页 +function toAppr(oid){ + location.href=WST.U('mobile/orders/orderappraise',{'oId':oid}); +} +// 投诉 +function complain(oid){ + location.href=WST.U('mobile/ordercomplains/complain',{'oId':oid}); +} + +//修改价格 +function editPrice(orderNo){ + alert('修改价格'); +} + + +// 发货 +var deliverType +function toDeliver(id,type){ + deliverType = type + if(type==0){ + delivery('orderDelivery('+id+')'); + }else{ + WST.dialog('确定发货吗?','orderDelivery('+id+')'); + } +} +function delivery(event){ + $("#wst-event0").attr("onclick","javascript:"+event); + $("#deliveryBox").dialog("show"); +} +function orderDelivery(oid){ + if(deliverType==0){ + hideDialog('#deliveryBox'); + }else{ + WST.dialogHide('prompt'); + } + $.post(WST.U('mobile/orders/deliver'),{id:oid,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#order-box').html(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +/*************** 修改价格需要用到的方法 ******************/ + + //只能輸入數字和小數點 + WST.isNumberdoteKey = function(evt){ + var e = evt || window.event; + var srcElement = e.srcElement || e.target; + + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && ((charCode < 48 || charCode > 57) && charCode!=46)){ + return false; + }else{ + if(charCode==46){ + var s = srcElement.value; + if(s.length==0 || s.indexOf(".")!=-1){ + return false; + } + } + return true; + } + } + WST.limitDecimal = function(obj,len){ + var s = obj.value; + if(s.indexOf(".")>-1){ + if((s.length - s.indexOf(".")-1)>len){ + obj.value = s.substring(0,s.indexOf(".")+len+1); + } + } + s = null; +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/share.css b/hyhproject/mobile2/view/default/users/share.css new file mode 100755 index 0000000..19dfe13 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/share.css @@ -0,0 +1,24 @@ +.con{ + position: relative; +} +.con .bg{ + width: 100%; + display: block; +} +.con .img{ + position: absolute; + top: 66.8%; + width: 30%; + left: 49%; + transform: translateX(-50%); +} +.share{ + position: absolute; + right: 10px; + padding: 3px 8px; + top: 30px; + font-size: 12px; +} +.img img{ + width: 100%; +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/share.html b/hyhproject/mobile2/view/default/users/share.html new file mode 100755 index 0000000..4e67238 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/share.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="utf-8" /> + <title></title> + <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> + <link rel="stylesheet" type="text/css" href="global.css" /> + <link rel="stylesheet" type="text/css" href="share.css" /> + </head> + + <body> + + <div class="con"> + <img class="bg" src="share_bg.png" /> + <div id="qrcode" class="img"></div> + </div> + + </body> + <!--<script src="jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script>--> + <script src="qrcode.js" type="text/javascript" charset="utf-8"></script> + <script type="text/javascript"> + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 96, //设置宽高 + height: 96 + }); + qrcode.makeCode('https://www.baidu.com'); + </script> + +</html> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/share_bg.png b/hyhproject/mobile2/view/default/users/share_bg.png new file mode 100755 index 0000000..68caafc Binary files /dev/null and b/hyhproject/mobile2/view/default/users/share_bg.png differ diff --git a/hyhproject/mobile2/view/default/users/user.js b/hyhproject/mobile2/view/default/users/user.js new file mode 100755 index 0000000..96438a3 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/user.js @@ -0,0 +1,111 @@ +//返回个人信息 +function returnUserinfo(){ + jQuery('#useri_infos').slideDown(); + jQuery('#footer').slideDown(); + jQuery('#useri_nickname').slideUp(); + jQuery("#useri_sex").slideUp(); +} +//修改昵称面板 +function openNickName(){ + jQuery('#useri_infos').slideUp(); + jQuery('#footer').slideUp(); + jQuery('#useri_nickname').slideDown(); +} +//修改昵称 +function editNickName(){ + var userName = $('#userName').val(); + if(userName==''){ + WST.msg('昵称不能为空','info'); + $('#userName').focus(); + return false; + } + $('.nickname_onclick').attr("onclick", "null"); + $.post(WST.U('mobile/users/editUserInfo'), {userName:userName}, function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,'success'); + $('#nickname').html(userName); + setTimeout(function(){ + setTimeout(function(){ + $('.nickname_onclick').attr("onclick", "editNickName()"); + },1000); + returnUserinfo(); + },1500); + }else{ + WST.msg('修改昵称失败,请重试','warn'); + setTimeout(function(){ + $('.nickname_onclick').attr("onclick", "editNickName()"); + },1500); + return false; + } + }); +} +//修改性別面板 +function openUserSex(){ + jQuery('#useri_infos').slideUp(); + jQuery('#footer').slideUp(); + jQuery("#useri_sex").slideDown(); +} +//修改性别 +function eidtUserSex(obj, userSex){ + $(obj).children('.wst-list-infose2').html('<i class="ui-icon-checked-s wst-icon-checked-s_se"></i>'); + $(obj).siblings().children('.wst-list-infose2').html(''); + $('.wst-listse').attr("onclick", "null"); + $.post(WST.U('mobile/users/editUserInfo'), {userSex:userSex}, function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + var newUserSex = ''; + if(userSex==0){ + newUserSex = '保密'; + }else if(userSex==1){ + newUserSex = '男'; + }else if(userSex==2){ + newUserSex = '女'; + } + WST.msg(json.msg,'success'); + $('#usersex').html(newUserSex); + setTimeout(function(){ + returnUserinfo(); + setTimeout(function(){ + $('.wst-listse1').attr("onclick", "eidtUserSex(this, 0)"); + $('.wst-listse2').attr("onclick", "eidtUserSex(this, 1)"); + $('.wst-listse3').attr("onclick", "eidtUserSex(this, 2)"); + },1000); + },1500); + }else{ + WST.msg('修改性别失败,请重试','warn'); + setTimeout(function(){ + $('.wst-listse1').attr("onclick", "eidtUserSex(this, 0)"); + $('.wst-listse2').attr("onclick", "eidtUserSex(this, 1)"); + $('.wst-listse3').attr("onclick", "eidtUserSex(this, 2)"); + },1000); + return false; + } + }); +} +/*签到*/ +function inSign(){ + $("#j-sign").attr('disabled', 'disabled'); + $.post(WST.U('mobile/userscores/signScore'),{},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $("#j-sign").addClass('sign2') + $("#currentScore").html(json.data.totalScore); + WST.msg(json.msg,'success'); + }else{ + $("#j-sign").removeClass('sign2'); + WST.msg(json.msg,'warn'); + $("#j-sign").removeAttr('disabled'); + } + }); +} +$(document).ready(function(){ + if(WST.conf.IS_LOGIN==0){//是否登录 + WST.inLogin(); + return; + } + WST.initFooter('user'); + WST.imgAdapt('j-imgAdapt'); +}) + + diff --git a/hyhproject/mobile2/view/default/users/useraddress/address.js b/hyhproject/mobile2/view/default/users/useraddress/address.js new file mode 100755 index 0000000..efecd9e --- /dev/null +++ b/hyhproject/mobile2/view/default/users/useraddress/address.js @@ -0,0 +1,232 @@ +jQuery.noConflict(); +//新增或编辑收货地址页 +function editAddress(addressId){ + $('#wst-switch').html(''); + $('#username').val(''); + $('#cellphone').val(''); + $('#address_detailed').val(''); + $('#areaId').val(''); + $('#addresst').html('请选择收货地址'); + $('.wst-ad-submit .button').attr('onclick','javascript:saveAddress('+addressId+');'); + if(addressId>0){ + $('.iziModal-header-title').html('修改收货地址'); + $.post(WST.U('mobile/useraddress/getById'), {addressId:addressId}, function(data){ + var info = WST.toJson(data); + if(info){ + $('#username').val(info.userName); + $('#cellphone').val(info.userPhone); + $('#address_detailed').val(info.userAddress); + $('#areaId').val(info.areaId); + if(info.isDefault==1){ + $('#defaults').attr('checked',true); + }else{ + $('#defaults').removeAttr('checked'); + } + $('#addresst').html(info.areaName); + } + addressInfo= null; + }); + }else{ + $('.iziModal-header-title').html('新增收货地址'); + } + jQuery('#modal-large').iziModal('open'); +} +jQuery("#modal-large").iziModal({ + title: "新增收货地址", + subtitle: "", + iconClass: 'icon-chat', + overlayColor: 'rgba(0, 0 0, 0.6)', + headerColor: '#ffffff' +}); +//保存收货地址 +function saveAddress(addressId){ + var userName = $('#username').val(); + var userPhone = $('#cellphone').val(); + var areaId = $('#areaId').val(); + var userAddress = $('#address_detailed').val(); + if( $('#defaults').is(':checked')){ + var isdefaultAddress = 1;//设为默认地址 + }else{ + var isdefaultAddress = 0;//不设为默认地址 + } + if(userName==''){ + WST.msg('收货人名称不能为空','info'); + return false; + } + if(userPhone==''){ + WST.msg('联系电话不能为空','info'); + return false; + } + if(areaId==''){ + WST.msg('请选择地址','info'); + return false; + } + if(userAddress==''){ + WST.msg('请填写详细地址','info'); + return false; + } + var param = {}; + param.addressId = addressId; + param.userName = userName; + param.areaId = areaId; + param.userPhone = userPhone; + param.userAddress = userAddress; + param.isDefault = isdefaultAddress; + $('.wst-ad-submit .button').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('mobile/useraddress/edits'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var type = $('#type').val(); + var id = $('#addressId2').val(); + if(param.addressId==0 && type==1)var addId = json.data.addressId; + setTimeout(function(){ + if(param.addressId==0 && type==1){ + chooseAddress(addId); + }else{ + location.href = WST.U('mobile/useraddress/index','type='+type+'&addressId='+id); + } + },1500); + }else{ + WST.msg(json.msg,'warn'); + setTimeout(function(){ + $('.wst-ad-submit .button').removeAttr('disabled').removeClass("active"); + },1500); + } + data = json = null; + }); +} +//设为默认地址 +function inDefault(obj,id){ + $(obj).addClass('default').removeClass('nodefault').siblings('.j-operate').addClass('nodefault').removeClass('default'); + $('.wst-ad-operate').css('position','relative'); + $.post(WST.U('mobile/useraddress/setDefault'), {id:id}, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('mobile/useraddress/index'); + },1500); + }else{ + WST.msg(json.msg,'warn'); + $('.wst-ad-operate').css('position','static'); + } + data = json = null; + }); +} +function setToDefault(obj){ + if( $(obj).is(':checked')){ + $('#defaults').removeAttr('checked'); + }else{ + $('#defaults').attr('checked',true); + } +} +//删除收货地址 +function delAddress(addressId){ + WST.dialog('确定删除吗?','toDelAddress('+addressId+')'); +} +//删除收货地址 +function toDelAddress(addressId){ + $.post(WST.U('mobile/useraddress/del'), {id:addressId}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + var type = $('#type').val(); + var id = $('#addressId2').val(); + location.href = WST.U('mobile/useraddress/index','type='+type+'&addressId='+id); + },2000); + }else{ + WST.msg(json.msg,'warn'); + } + WST.dialogHide('prompt'); + data = json = null; + }); +} +//地址选择 +function inOption(obj,n){ + $(obj).addClass('active').siblings().removeClass('active'); + $('.area_'+n).removeClass('hide').siblings('.list').addClass('hide'); + var level = $('#level').val(); + var n = n+1; + for(var i=n; i<=level; i++){ + $('.area_'+i).remove(); + $('.active_'+i).remove(); + } +} +function inChoice(obj,id,val,level){ + $('#level').val((level+1)); + $(obj).addClass('active').siblings().removeClass('active'); + $('#'+id).attr('areaId',val); + $('.active_'+level).removeClass('active').html($(obj).html()); + WST.ITAreas({id:id,val:val,className:'j-areas'}); +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + $.post(WST.U('mobile/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + var level = parseInt(obj.attr('level'),10); + $('.area_'+level).addClass('hide'); + var level = level+1; + html.push('<div id="'+tid+'" class="list '+opts.className+' area_'+level+'" areaId="0" level="'+level+'">'); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<p onclick='javascript:inChoice(this,\""+tid+"\","+tmp.areaId+","+level+");'>"+tmp.areaName+"</p>"); + } + html.push('</div>'); + $(html.join('')).insertAfter('#'+opts.id); + var h = WST.pageHeight(); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + $(".wst-fr-box .option").append('<p class="ui-nowrap-flex term active_'+level+' active" onclick="javascript:inOption(this,'+level+')">请选择</p>'); + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + $('#areaId').val(opts.lastVal); + var ht = ''; + $('.wst-fr-box .term').each(function(){ + ht += $(this).html(); + }); + $('#addresst').html(ht); + dataHide(); + } + }); +} +function chooseAddress(id){ + location.href = WST.U('mobile/carts/settlement','addressId='+id); +} +$(document).ready(function(){ + WST.initFooter('user'); + // 弹出层 + $('#modal-large').css({'top':0,'margin-top':0}); + var h = WST.pageHeight(); + $("#frame").css('bottom','-'+h/2); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); +}); +//弹框 +function dataShow(){ + jQuery('#frame').show(); + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); + setTimeout(function(){ + jQuery('#frame').hide(); + },500); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/useraddress/edit.html b/hyhproject/mobile2/view/default/users/useraddress/edit.html new file mode 100755 index 0000000..8cf32c8 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/useraddress/edit.html @@ -0,0 +1,49 @@ + <div id="modal-large" class="iziModal"> + <input type="hidden" name="" value="" id="areaId" autocomplete="off"> + <div class="wst-ad-form"> + <div class="ui-form-itemin"> + <label class="word">收货人:</label><input class="ui-border-binte" id="username" type="text" placeholder="请填写收货人"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">联系电话:</label><input class="ui-border-binte" id="cellphone" type="text" placeholder="请填写联系电话" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">收货地址:</label> + <div id="addresst" class="ui-nowrap-flex address" onclick="javascript:dataShow();">请选择收货地址</div> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">详细地址:</label><input class="ui-border-binte" id="address_detailed" type="text" placeholder="请填写详细地址"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form"> + <div class="ui-form-item ui-form-item-switch wst-ad-operate"> + <p>设为默认地址</p> + <label class="ui-switch"> + <input type="checkbox" id="defaults" onclick="javascript:setToDefault(this)"> + </label> + </div> + </div> + </div> + <div class="wst-ad-submit"><button class="ui-btn-lg button" onclick="javascript:saveAddress(0);">保存</button></div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 地址框 */} +<div class="wst-fr-box" id="frame" style="display:none;"> + <input type="hidden" name="" value="" id="level" autocomplete="off"> + <div class="title"><span>收货地址</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <div class="option"> + <p class="ui-nowrap-flex term active_0 active" onclick="javascript:inOption(this,0)">请选择</p> + </div> + <div class="wst-clear"></div> + <div id="area_0" class="list j-areas area_0" areaId="0" level="0"> + {volist name="area" id="ar"} + <p onclick="javascript:inChoice(this,'area_0',{$ar['areaId']},0);">{$ar['areaName']}</p> + {/volist} + </div> + </div> +</div> + </div> \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/useraddress/list.html b/hyhproject/mobile2/view/default/users/useraddress/list.html new file mode 100755 index 0000000..ffc1fb0 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/useraddress/list.html @@ -0,0 +1,56 @@ +{extend name="default/base" /} +{block name="title"}收货地址管理 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/iziModal.css?v={$v}"> +<link rel="stylesheet" href="__MOBILE__/css/address.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" {if($type==1)}onclick="javascript:chooseAddress({$addressId});"{else}onclick="history.back();"{/if}></i><h1>我的地址</h1> + </header> +{/block} +{block name="footer"} + <div class="wst-ad-footer"><button class="button" onclick="javascript:editAddress(0);">新增</button></div> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + <input type="hidden" name="" value="{$addressId}" id="addressId2" autocomplete="off"> + <section class="ui-container" id="address"> + {volist name="list" id="li"} + <ul class="ui-list wst-listse"> + <li {if($type==1)}onclick="javascript:chooseAddress({$li['addressId']});"{/if}> + <div class="wst-list-infose1"> + <span class="name">{$li['userName']}&nbsp;&nbsp;{$li['userPhone']}</span> + <span class="address">{$li['areaName']}-{$li['userAddress']}</span> + </div> + </li> + <div class="wst-ad-operate"> + {if($type!=1)}<span class="left">设为默认</span>{/if} + <span class="right" onclick="javascript:delAddress({$li['addressId']});"><i class="delete"></i>&nbsp;删除</span> + <span class="right" onclick="javascript:editAddress({$li['addressId']});"><i class="edit"></i>&nbsp;编辑</span> + <div class="wst-clear"></div> + </div> + </ul> + {if($type==1)} + <i class="j-operate {if($addressId==$li['addressId'])}default{else}nodefault{/if}"></i> + {else} + <i class="j-operate {if($li['isDefault']==1)}default{else}nodefault{/if}" onclick="javascript:inDefault(this,{$li['addressId']});"></i> + {/if} + {/volist} + {empty name="list"} + <div class="wst-prompt-icon"><img src="__MOBILE__/img/nothing-address.png"></div> + <div class="wst-prompt-info"> + <p>没有收货地址</p> + </div> + {/empty} + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{include file="default/users/useraddress/edit" /}<!-- 新增/编辑收货地址模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/js/izimodal/iziModal.js'></script> +<script type='text/javascript' src='__MOBILE__/users/useraddress/address.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/userscores/list.html b/hyhproject/mobile2/view/default/users/userscores/list.html new file mode 100755 index 0000000..8b8f11a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/userscores/list.html @@ -0,0 +1,49 @@ +{extend name="default/base" /} +{block name="title"}我的积分 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/userscores.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "我的积分"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-whitespace ui-row-flex-ver head"> + <div class="user_scores"> + <p>我的积分</p> + <p id="userMoney" >{$object['userScore']}<span> 个</span></p> + </div> + </div> + <script type="text/html" id="scoreList"> + <ul class="ui-row score-detail"> + {{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75 wst-re-info"> + <p>{{d[i].dataRemarks}}</p> + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 {{(d[i].scoreType==1)?'score-plus':'score-reduce'}}">{{(d[i].scoreType==1)?'+':'-'}} {{d[i].score}}</li> + <div class="wst-clear"></div> + <div class="score-line"></div> + {{# } }} + </ul> + </script> + <div class="score-detail-title">积分明细</div> + <div id="score-list"></div> + </section> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>积分使用规则</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + 积分使用规则 + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/js/jquery.min.js'></script> +<script type='text/javascript' src='__MOBILE__/users/userscores/userscores.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/userscores/userscores.js b/hyhproject/mobile2/view/default/users/userscores/userscores.js new file mode 100755 index 0000000..c01ce08 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/userscores/userscores.js @@ -0,0 +1,67 @@ +jQuery.noConflict(); +// 获取订单列表 +function getScoreList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val() || -1; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('mobile/userscores/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.MOBILE +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getScoreList(); + WST.initFooter('user'); + // 弹出层 + var w = WST.pageWidth(); + var h = WST.pageHeight(); + $('#frame .content').css('overflow-y','scroll').css('height',h-48); + $("#frame").css('right',-w); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getScoreList(); + } + } + }); +}); + + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/userset/about.html b/hyhproject/mobile2/view/default/users/userset/about.html new file mode 100755 index 0000000..ec73f2a --- /dev/null +++ b/hyhproject/mobile2/view/default/users/userset/about.html @@ -0,0 +1,39 @@ +{extend name="default/base" /} +{block name="title"}关于我们 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/userset.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "关于我们"{/php} + {include file="default/header" /} +{/block} +{block name="footer"}{/block} +{block name="main"} + <section class="ui-container"> + <div class="wst-about"> + <div class="wst-brand" ><img src="__IMGURL__/{:WSTConf('CONF.mallLogo')}"></div> + <p>{:WSTConf('CONF.seoMallTitle')}</p> + <div class="wst-version"> + <div class="wst-border"> + </div> + </div> + </div> + <div class="wst-about" > + <ul class="ui-list ui-list-text wst-contact" style="background: transparent;"> + <li class="line"> + <span class="phone"></span><h5>联系电话:{:WSTConf('CONF.serviceTel')}</h5> + </li> + <li class="line"> + <span class="qq"></span><h5>客服QQ:{:WSTConf('CONF.serviceQQ')}</h5> + </li> + <li class="line"> + <span class="email"></span><h5>联系邮箱:{:WSTConf('CONF.serviceEmail')}</h5> + </li> + + </ul> + </div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/userset/userset.js'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/userset/list.html b/hyhproject/mobile2/view/default/users/userset/list.html new file mode 100755 index 0000000..2aad0be --- /dev/null +++ b/hyhproject/mobile2/view/default/users/userset/list.html @@ -0,0 +1,33 @@ +{extend name="default/base" /} +{block name="title"}用户设置 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__MOBILE__/css/userset.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "用户设置"{/php} + {include file="default/header" /} +{/block} +{block name="footer"}{/block} +{block name="main"} + <section class="ui-container" > + <ul class="ui-list ui-list-text ui-list-link wst-se-l" style="margin-top: 0px;"> + <li class="line" onclick="location.href='{:url('mobile/users/edit')}'"> + <span class="pay"></span><h5 class="ui-nowrap">个人中心</h5></a> + </li> + <li class="line" onclick="location.href='{:url('mobile/users/security')}'"> + <span class="safety"></span><h5 class="ui-nowrap">账户安全</h5></a> + </li> + <li class="line" onclick="location.href='{:url('mobile/users/aboutus')}'"> + <span class="about"></span><h5 class="ui-nowrap">关于我们</h5> + </li> + </ul> + <div class="ui-btn-wrap logout" style="margin-top: 0px;"> + <button class="ui-btn-lg ui-btn-danger logout-btn" onclick="javascript:logout();"> + 退出登录 + </button> + </div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__MOBILE__/users/userset/userset.js'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/userset/userset.js b/hyhproject/mobile2/view/default/users/userset/userset.js new file mode 100755 index 0000000..7ec9962 --- /dev/null +++ b/hyhproject/mobile2/view/default/users/userset/userset.js @@ -0,0 +1,9 @@ +function logout(){ + $.post(WST.U('mobile/users/logout'),{},function(data,textStatus){ + var json = WST.toJson(data); + if(data.status==1) + location.href=WST.U('mobile/users/index'); + else + WST.msg('发生未知错误','info'); + }); +} \ No newline at end of file diff --git a/hyhproject/mobile2/view/default/users/╨┬╜и╬─▒╛╬─╡╡.txt b/hyhproject/mobile2/view/default/users/╨┬╜и╬─▒╛╬─╡╡.txt new file mode 100755 index 0000000..e69de29 diff --git a/hyhproject/mobile2/view/default/users/鈺ㄢ敩鈺溞糕暚鈹€鈻掆暃鈺攢鈺♀暋.txt b/hyhproject/mobile2/view/default/users/鈺ㄢ敩鈺溞糕暚鈹€鈻掆暃鈺攢鈺♀暋.txt new file mode 100755 index 0000000..e69de29 diff --git a/hyhproject/wechat2/behavior/InitWechatMessges.php b/hyhproject/wechat2/behavior/InitWechatMessges.php new file mode 100755 index 0000000..cb0f4c8 --- /dev/null +++ b/hyhproject/wechat2/behavior/InitWechatMessges.php @@ -0,0 +1,86 @@ +<?php +namespace wstmart\wechat\behavior; +use think\Db; +/** + * ============================================================================ + * 初始化微信消息模板 + */ +class InitWechatMessges +{ + public function run(&$params){ + $tpl = WSTMsgTemplates($params['CODE']); + if(!$tpl)return; + $userType = (isset($params['userType']) && $params['userType']==3)?3:0; + $userId = $params['userId']; + if($userType==3){ + $user = Db::name('staffs')->where(['staffId'=>$userId,'staffStatus'=>1])->field('wxOpenId')->find(); + }else{ + $user = Db::name('users')->where('userId',$userId)->field('wxOpenId')->find(); + } + if($user['wxOpenId']=='')return; + //数据封装 + $data = []; + $data['touser'] = $user['wxOpenId']; + $data['template_id'] = $tpl['tplExternaId']; + if(isset($params['URL']) && $params['URL'] !='')$data['url'] = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".WSTConf("CONF.wxAppId")."&redirect_uri=".rawurlencode( $params['URL'] )."&response_type=code&scope=snsapi_userinfo&state=".WSTConf("CONF.wxAppCode")."&connect_redirect=1#wechat_redirect"; + $data['data'] = []; + if(!empty($tpl['params'])){ + foreach($tpl['params'] as $key =>$v){ + foreach($params['params'] as $pkey =>$pv){ + $v['fieldVal'] = str_replace('${'.$pkey.'}',$pv,$v['fieldVal']); + } + $tpl['params'][$key] = $v; + } + } + foreach($tpl['params'] as $key =>$v){ + $data['data'][$v['fieldCode']] = array('value'=>urlencode($v['fieldVal'])); + } + //屏蔽因发送微信有问题导致不能下单的情况 + try{ + $we = WSTWechat(); + $rs = $we->sendTemplateMessage(urldecode(json_encode($data))); + }catch (\Exception $e) {} + } + + + /** + * 批量发送-需要自己判断微信openId并传入 + */ + public function batchRun(&$params){ + $tpl = WSTMsgTemplates($params['CODE']); + if(!$tpl)return; + $userType = (isset($params['userType']) && $params['userType']==3)?3:0; + $userId = $params['userId']; + if($userType==3){ + $user = Db::name('staffs')->where(['staffId'=>['in',$userId],'staffStatus'=>1])->field('wxOpenId')->select(); + }else{ + $user = Db::name('users')->where(['userId'=>['in',$userId]])->field('wxOpenId')->select(); + } + if(empty($user))return; + for($i=0;$i<count($user);$i++){ + if($user[$i]['wxOpenId']=='')continue; + //数据封装 + $data = []; + $data['touser'] = $user[$i]['wxOpenId']; + $data['template_id'] = $tpl['tplExternaId']; + if(isset($params['URL']) && $params['URL'] !='')$data['url'] = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".WSTConf("CONF.wxAppId")."&redirect_uri=".rawurlencode( $params['URL'] )."&response_type=code&scope=snsapi_userinfo&state=".WSTConf("CONF.wxAppCode")."&connect_redirect=1#wechat_redirect"; + $data['data'] = []; + if(!empty($tpl['params'])){ + foreach($tpl['params'] as $key =>$v){ + foreach($params['params'] as $pkey =>$pv){ + $v['fieldVal'] = str_replace('${'.$pkey.'}',$pv,$v['fieldVal']); + } + $tpl['params'][$key] = $v; + } + } + foreach($tpl['params'] as $key =>$v){ + $data['data'][$v['fieldCode']] = array('value'=>urlencode($v['fieldVal'])); + } + //屏蔽因发送微信有问题导致不能下单的情况 + try{ + $we = WSTWechat(); + $rs = $we->sendTemplateMessage(urldecode(json_encode($data))); + }catch (\Exception $e) {} + } + } +} \ No newline at end of file diff --git a/hyhproject/wechat2/common/function.php b/hyhproject/wechat2/common/function.php new file mode 100755 index 0000000..e04c5e3 --- /dev/null +++ b/hyhproject/wechat2/common/function.php @@ -0,0 +1,122 @@ +<?php +use think\Db; +use wstmart\wechat\model\Users; +/** + * ============================================================================ + */ +/** + * 建立文件夹 + * @param string $aimUrl + * @return viod + */ +function WSTCreateDir($aimUrl) { + $aimUrl = str_replace('', '/', $aimUrl); + $aimDir = ''; + $arr = explode('/', $aimUrl); + $result = true; + foreach ($arr as $str) { + $aimDir .= $str . '/'; + if (!file_exists($aimDir)) { + $result = mkdir($aimDir,0777); + } + } + return $result; +} + +/** + * 下载网络文件到本地服务器 + */ +function WSTDownFile($url,$folde='./Upload/image/'){ + set_time_limit (24 * 60 * 60); + WSTCreateDir(WSTRootPath().$folde); + $postfix = ''; + $newfname = $folde . time().rand(10,100).".".($postfix!=''?$postfix:"jpg"); + $file = fopen ($url, "rb"); + if ($file) { + $newf = fopen ($newfname, "wb"); + if ($newf){ + while(!feof($file)) { + fwrite($newf, fread($file, 1024 * 8 ), 1024 * 8 ); + } + } + } + if ($file) { + fclose($file); + } + if ($newf) { + fclose($newf); + } + return $newfname; +} + +/** + * 微信配置 + */ +function WSTWechat(){ + $wechat = new \wechat\WSTWechat(WSTConf('CONF.wxAppId'),WSTConf('CONF.wxAppKey')); + return $wechat; +} +function WSTBindWeixin($type=1){ + $USER = session('WST_USER'); + $we = WSTWechat(); + if($USER['userId']=='' || $USER['wxOpenId']==''){ + $wdata = $we->getUserInfo(input('param.code'));//获取openid和access_token + $userinfo = session('WST_WX_USERINFO'); + if(empty($userinfo['openid'])){ + $userinfo = $we->UserInfo($wdata); + session('WST_WX_USERINFO',$userinfo); + } + WSTSigninfo($userinfo,$USER); + $users = new Users(); + if($userinfo['openid']!=''){ + session('WST_WX_OPENID',$userinfo['openid']); + $rs = Db::name('users')->where(['wxOpenId'=>$userinfo['openid'],'dataFlag'=>1])->field('wxOpenId')->select(); + if(count($rs)==0 && session('WST_WX_OPENID')!=''){ + if($type==1){ + header("location:".url('wechat/users/login')); + exit; + } + }else{ + $users->accordLogin(); + $url = session('WST_WX_WlADDRESS'); + if($url){ + header("location:".$url); + exit; + } + } + } + } + WSTSigninfo(0,$USER); +} +//获取subscribe(是否关注公众号) +function WSTSigninfo($info,$user){ + if(!empty($info['openid'])){ + $we = WSTWechat(); + $openid = ($user['wxOpenId'])?$user['wxOpenId']:$info['openid']; + $signinfo = $we->wxUserInfo($openid); + session('WST_WX_SIGNINFO',$signinfo); + } +} + +function WSTIsWeixin(){ + if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) { + return true; + } + $isLimit = false; + $limitArr[] = array("controller"=>"Payments","action"=>"notify"); + for($i=0;$i<count($limitArr);$i++){ + $obj = $limitArr[$i]; + if(request()->controller()==$obj["controller"] && request()->action()==$obj["action"]){ + $isLimit = true; + break; + } + } + if($isLimit){ + return true; + } + $url=urlencode($_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]); + $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.WSTConf('CONF.wxAppId').'&redirect_uri=http%3a%2f%2f'.$url.'&response_type=code&scope=snsapi_userinfo&state='.WSTConf('CONF.wxAppCode').'#wechat_redirect'; + header("location:".$url); + exit; + return false; +} \ No newline at end of file diff --git a/hyhproject/wechat2/conf/config.php b/hyhproject/wechat2/conf/config.php new file mode 100755 index 0000000..3d26a52 --- /dev/null +++ b/hyhproject/wechat2/conf/config.php @@ -0,0 +1,14 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +return [ + +]; diff --git a/hyhproject/wechat2/controller/Areas.php b/hyhproject/wechat2/controller/Areas.php new file mode 100755 index 0000000..bdb34f1 --- /dev/null +++ b/hyhproject/wechat2/controller/Areas.php @@ -0,0 +1,17 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Areas as M; +/** + * ============================================================================ + * 地区控制器 + */ +class Areas extends Base{ + /** + * 列表查询 + */ + public function listQuery(){ + $m = new M(); + $rs = $m->listQuery(); + return WSTReturn('', 1,$rs); + } +} diff --git a/hyhproject/wechat2/controller/Base.php b/hyhproject/wechat2/controller/Base.php new file mode 100755 index 0000000..21f9355 --- /dev/null +++ b/hyhproject/wechat2/controller/Base.php @@ -0,0 +1,93 @@ +<?php +namespace wstmart\wechat\controller; +use think\Controller; +/** + * ============================================================================ + * 基础控制器 + */ +class Base extends Controller { + public function __construct(){ + parent::__construct(); + WSTConf('CONF',WSTConfig()); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPcStyleId')); + if(WSTConf('CONF.wxenabled')==1){ + if(!(request()->module()=="wechat" && request()->controller()=="Weixinpays" && request()->action()=="notify")){ + WSTIsWeixin();//检测是否在微信浏览器上使用 + } + $state = input('param.state'); + if($state==WSTConf('CONF.wxAppCode')){ + $type = input('param.type'); + if($type=='1'){ + WSTBindWeixin(1); + }else{ + WSTBindWeixin(0); + } + } + } + if(WSTConf('CONF.seoMallSwitch')==0){ + $this->redirect('wechat/switchs/index'); + exit; + } + } + // 权限验证方法 + protected function checkAuth(){ + $state = input('param.state'); + if($state==WSTConf('CONF.wxAppCode')){ + WSTBindWeixin(1); + } + $request = request(); + $USER = session('WST_USER'); + if(empty($USER)){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"还没关联帐号,正在关联帐号"}'); + }else{ + session('WST_WX_WlADDRESS',$request->url(true)); + $url=urlencode($request->url(true)); + $url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.WSTConf('CONF.wxAppId').'&redirect_uri='.$url.'&response_type=code&scope=snsapi_userinfo&state='.WSTConf('CONF.wxAppCode').'#wechat_redirect'; + header("location:".$url); + exit; + } + } + } + + // 店铺权限验证方法 + protected function checkShopAuth($opt){ + $shopMenus = WSTShopOrderMenus(); + if($opt=="list"){ + if(count($shopMenus)==0){ + session('wxshoporder','对不起,您无权进行该操作'); + $this->redirect('wechat/error/message',['code'=>'wxshoporder']); + exit; + } + }else{ + if(!array_key_exists($opt,$shopMenus)){ + if(request()->isAjax()){ + die('{"status":-1,"msg":"您无权进行该操作"}'); + }else{ + session('wxshoporder','对不起,您无权进行该操作'); + $this->redirect('wechat/error/message',['code'=>'wxshoporder']); + exit; + } + } + } + } + + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wstwechatStyle')?WSTConf('CONF.wstwechatStyle'):'default'; + $replace['__WECHAT__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/wstmart/wechat/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + + } + /** + * 上传图片 + */ + public function uploadPic(){ + return WSTUploadPic(0); + } + /** + * 获取验证码 + */ + public function getVerify(){ + WSTVerify(); + } +} \ No newline at end of file diff --git a/hyhproject/wechat2/controller/Brands.php b/hyhproject/wechat2/controller/Brands.php new file mode 100755 index 0000000..5fc4ff6 --- /dev/null +++ b/hyhproject/wechat2/controller/Brands.php @@ -0,0 +1,26 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Brands as M; +/** + * ============================================================================ + * 品牌控制器 + */ +class Brands extends Base{ + /** + * 主页 + */ + public function index(){ + return $this->fetch('brands'); + } + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['brandImg'] = WSTImg($v['brandImg'],2); + } + return $rs; + } +} \ No newline at end of file diff --git a/hyhproject/wechat2/controller/Carts.php b/hyhproject/wechat2/controller/Carts.php new file mode 100755 index 0000000..b3105b1 --- /dev/null +++ b/hyhproject/wechat2/controller/Carts.php @@ -0,0 +1,141 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Carts as M; +use wstmart\common\model\UserAddress; +use wstmart\common\model\Payments; +/** + * ============================================================================ + * 购物车控制器 + */ +class Carts extends Base{ + + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + + /** + * 查看购物车列表 + */ + public function index(){ + $m = new M(); + $carts = $m->getCarts(false); + $this->assign('carts',$carts); + return $this->fetch('carts'); + } + /** + * 加入购物车 + */ + public function addCart(){ + $m = new M(); + $rs = $m->addCart(); + $rs['cartNum'] = WSTCartNum(); + return $rs; + } + /** + * 修改购物车商品状态 + */ + public function changeCartGoods(){ + $m = new M(); + $rs = $m->changeCartGoods(); + return $rs; + } + /** + * 删除购物车里的商品 + */ + public function delCart(){ + $m = new M(); + $rs= $m->delCart(); + return $rs; + } + /** + * 计算运费、积分和总商品价格 + */ + public function getCartMoney(){ + $m = new M(); + $data = $m->getCartMoney(); + return $data; + } + /** + * 计算运费、积分和总商品价格/虚拟商品 + */ + public function getQuickCartMoney(){ + $m = new M(); + $data = $m->getQuickCartMoney(); + return $data; + } + /** + * 跳去购物车结算页面 + */ + public function settlement(){ + $m = new M(); + //获取一个用户地址 + $addressId = (int)input('addressId'); + $ua = new UserAddress(); + if($addressId>0){ + $userAddress = $ua->getById($addressId); + }else{ + $userAddress = $ua->getDefaultAddress(); + } + $this->assign('userAddress',$userAddress); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('3'); + //获取已选的购物车商品 + $carts = $m->getCarts(true); + + hook("wechatControllerCartsSettlement",["carts"=>$carts,"payments"=>&$payments]); + + $this->assign('payments',$payments); + //获取用户积分 + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + //计算可用积分和金额 + $goodsTotalMoney = $carts['goodsTotalMoney']; + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + $useOrderScore =0; + $useOrderMoney = 0; + if($user['userScore']>$goodsTotalScore){ + $useOrderScore = $goodsTotalScore; + $useOrderMoney = $goodsTotalMoney; + }else{ + $useOrderScore = $user['userScore']; + $useOrderMoney = WSTScoreToMoney($useOrderScore); + } + $this->assign('userOrderScore',$useOrderScore); + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + return $this->fetch('settlement'); + } + /** + * 跳去虚拟商品购物车结算页面 + */ + public function quickSettlement(){ + $m = new M(); + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('3'); + $this->assign('payments',$payments); + //获取用户积分 + $user = model('users')->getFieldsById((int)session('WST_USER.userId'),'userScore'); + //获取已选的购物车商品 + $carts = $m->getQuickCarts(); + //计算可用积分和金额 + $goodsTotalMoney = $carts['goodsTotalMoney']; + $goodsTotalScore = WSTScoreToMoney($goodsTotalMoney,true); + $useOrderScore =0; + $useOrderMoney = 0; + if($user['userScore']>$goodsTotalScore){ + $useOrderScore = $goodsTotalScore; + $useOrderMoney = $goodsTotalMoney; + }else{ + $useOrderScore = $user['userScore']; + $useOrderMoney = WSTScoreToMoney($useOrderScore); + } + $this->assign('userOrderScore',$useOrderScore); + $this->assign('userOrderMoney',$useOrderMoney); + + $this->assign('carts',$carts); + return $this->fetch('settlement_quick'); + } +} diff --git a/hyhproject/wechat2/controller/Cashconfigs.php b/hyhproject/wechat2/controller/Cashconfigs.php new file mode 100755 index 0000000..2a6d181 --- /dev/null +++ b/hyhproject/wechat2/controller/Cashconfigs.php @@ -0,0 +1,54 @@ +<?php +namespace wstmart\wechat\controller; +/** + * ============================================================================ + * 提现账号控制器 + */ +class Cashconfigs extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看提现账号 + */ + public function index(){ + $this->assign('area',model('areas')->listQuery(0)); + $this->assign('banks',model('banks')->listQuery(0)); + return $this->fetch('users/cashconfigs/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashConfigs')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + /** + * 获取记录 + */ + public function getById(){ + $id = (int)input('id'); + return model('CashConfigs')->getById($id); + } + /** + * 新增 + */ + public function add(){ + return model('CashConfigs')->add(); + } + /** + * 编辑 + */ + public function edit(){ + return model('CashConfigs')->edit(); + } + /** + * 删除 + */ + public function del(){ + return model('CashConfigs')->del(); + } +} diff --git a/hyhproject/wechat2/controller/Cashdraws.php b/hyhproject/wechat2/controller/Cashdraws.php new file mode 100755 index 0000000..66f0796 --- /dev/null +++ b/hyhproject/wechat2/controller/Cashdraws.php @@ -0,0 +1,34 @@ +<?php +namespace wstmart\wechat\controller; +/** + * ============================================================================ + * 提现记录控制器 + */ +class Cashdraws extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 查看用户提现记录 + */ + public function index(){ + return $this->fetch('users/cashdraws/list'); + } + + /** + * 获取用户数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('CashDraws')->pageQuery(0,$userId); + return WSTReturn("", 1,$data); + } + + /** + * 提现 + */ + public function drawMoney(){ + return model('CashDraws')->drawMoney(); + } +} diff --git a/hyhproject/wechat2/controller/Error.php b/hyhproject/wechat2/controller/Error.php new file mode 100755 index 0000000..4c681a9 --- /dev/null +++ b/hyhproject/wechat2/controller/Error.php @@ -0,0 +1,21 @@ +<?php +namespace wstmart\wechat\controller; +/** + * ============================================================================ + * 错误处理控制器 + */ +class Error extends Base{ + public function index(){ + header("HTTP/1.0 404 Not Found"); + return $this->fetch('error_sys'); + } + public function message(){ + $code = input('code'); + if($code !== null && session($code)!=''){ + $this->assign('message',session($code)); + }else{ + $this->assign('message','操作错误,请联系商城管理员'); + } + return $this->fetch('error_lost'); + } +} diff --git a/hyhproject/wechat2/controller/Favorites.php b/hyhproject/wechat2/controller/Favorites.php new file mode 100755 index 0000000..1d75957 --- /dev/null +++ b/hyhproject/wechat2/controller/Favorites.php @@ -0,0 +1,69 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Favorites as M; +/** + * ============================================================================ + * 收藏控制器 + */ +class Favorites extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth', + ]; + /** + * 关注的商品 + */ + public function goods(){ + return $this->fetch('users/favorites/list_goods'); + } + /** + * 关注的店铺 + */ + public function shops(){ + return $this->fetch('users/favorites/list_shops'); + } + /** + * 关注的商品列表 + */ + public function listGoodsQuery(){ + $m = new M(); + $data = $m->listGoodsQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + return WSTReturn("", 1,$data); + } + /** + * 关注的店铺列表 + */ + public function listShopQuery(){ + $m = new M(); + $data = $m->listShopQuery(); + foreach($data['Rows'] as $k=>$v){ + $data['Rows'][$k]['shopImg'] = WSTImg($v['shopImg'],3); + if(!empty($v['goods'])){ + foreach($v['goods'] as $k1=>$v1){ + $v[$k1]['goodsImg'] = WSTImg($v1['goodsImg'],3); + } + } + } + return WSTReturn("", 1,$data); + } + /** + * 取消关注 + */ + public function cancel(){ + $m = new M(); + $rs = $m->del(); + return $rs; + } + /** + * 增加关注 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } + +} diff --git a/hyhproject/wechat2/controller/Goods.php b/hyhproject/wechat2/controller/Goods.php new file mode 100755 index 0000000..cb373fb --- /dev/null +++ b/hyhproject/wechat2/controller/Goods.php @@ -0,0 +1,96 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\GoodsCats; +use wstmart\common\model\GoodsConsult as CG; +/** + * ============================================================================ + * 商品控制器 + */ +class Goods extends Base{ + /** + * 商品主页 + */ + public function detail(){ + $m = model('goods'); + $goods = $m->getBySale(input('goodsId/d')); + + hook('wechatControllerGoodsIndex',['getParams'=>input()]); + + // 找不到商品记录 + if(empty($goods))return $this->fetch('error_lost'); + if(!empty($goods)){ + $goods['goodsDesc']=htmlspecialchars_decode($goods['goodsDesc']); + $rule = '/<img src="\/(upload.*?)"/'; + preg_match_all($rule, $goods['goodsDesc'], $images); + + foreach($images[0] as $k=>$v){ + $goods['goodsDesc'] = str_replace('/'.$images[1][$k], '__ROOT__/'.WSTConf("CONF.goodsLogo") . "\" data-echo=\"__ROOT__/".WSTImg($images[1][$k],3), $goods['goodsDesc']); + } + $history = cookie("wx_history_goods"); + $history = is_array($history)?$history:[]; + array_unshift($history, (string)$goods['goodsId']); + $history = array_values(array_unique($history)); + if(!empty($history)){ + cookie("wx_history_goods",$history,25920000); + } + } + if(WSTConf('CONF.wxenabled')==1){ + $we = WSTWechat(); + $datawx = $we->getJsSignature('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + $this->assign("datawx", $datawx); + } + $goods['consult'] = model('GoodsConsult')->firstQuery($goods['goodsId']); + $goods['appraises'] = model('GoodsAppraises')->getGoodsEachApprNum($goods['goodsId']); + $this->assign("info", $goods); + return $this->fetch('goods_detail'); + } + /** + * 商品列表 + */ + public function lists(){ + $this->assign("keyword", input('keyword')); + $this->assign("catId", input('catId/d')); + $this->assign("brandId", input('brandId/d')); + return $this->fetch('goods_list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = model('goods'); + $gc = new GoodsCats(); + $catId = (int)input('catId'); + if($catId>0){ + $goodsCatIds = $gc->getParentIs($catId); + }else{ + $goodsCatIds = []; + } + $rs = $m->pageQuery($goodsCatIds); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + $rs['Rows'][$key]['praiseRate'] = ($v['totalScore']>0)?(sprintf("%.2f",$v['totalScore']/($v['totalUsers']*15))*100).'%':'100%'; + } + // `券`标签 + hook('afterQueryGoods',['page'=>&$rs]); + return $rs; + } + + /** + * 浏览历史页面 + */ + public function history(){ + return $this->fetch('users/history/list'); + } + /** + * 获取浏览历史 + */ + public function historyQuery(){ + $rs = model('goods')->historyQuery(); + if(!empty($rs)){ + foreach($rs['Rows'] as $k=>$v){ + $rs['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],3); + } + } + return $rs; + } +} diff --git a/hyhproject/wechat2/controller/Goodsappraises.php b/hyhproject/wechat2/controller/Goodsappraises.php new file mode 100755 index 0000000..ad56aef --- /dev/null +++ b/hyhproject/wechat2/controller/Goodsappraises.php @@ -0,0 +1,44 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\GoodsAppraises as M; +/** + * ============================================================================ + * 评价控制器 + */ +class GoodsAppraises extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'getbyid'],// 只要访问only下的方法才才需要执行前置操作 + ]; + /** + * 根据商品id获取评论 + */ + public function getById(){ + $m = new M(); + $rs = $m->getById(); + return $rs; + } + /** + * 根据订单id,用户id,商品id获取评价 + */ + public function getAppr(){ + $m = model('GoodsAppraises'); + $rs = $m->getAppr(); + if(!empty($rs['data']['images'])){ + $imgs = explode(',',$rs['data']['images']); + foreach($imgs as $k=>$v){ + $imgs[$k] = WSTImg($v,1); + } + $rs['data']['images'] = $imgs; + } + return $rs; + } + /** + * 添加评价 + */ + public function add(){ + $m = new M(); + $rs = $m->add(); + return $rs; + } +} diff --git a/hyhproject/wechat2/controller/Goodscats.php b/hyhproject/wechat2/controller/Goodscats.php new file mode 100755 index 0000000..5fe7447 --- /dev/null +++ b/hyhproject/wechat2/controller/Goodscats.php @@ -0,0 +1,18 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\wechat\model\GoodsCats as M; +/** + * ============================================================================ + * 商品分类控制器 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function index(){ + $m = new M(); + $goodsCatList = $m->getGoodsCats(); + $this->assign('list',$goodsCatList); + return $this->fetch('goods_category'); + } +} diff --git a/hyhproject/wechat2/controller/Goodsconsult.php b/hyhproject/wechat2/controller/Goodsconsult.php new file mode 100755 index 0000000..626c67a --- /dev/null +++ b/hyhproject/wechat2/controller/Goodsconsult.php @@ -0,0 +1,35 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\GoodsConsult as CG; +/** + * ============================================================================ + * 商品咨询控制器 + */ +class GoodsConsult extends Base{ + /** + * 商品咨询页 + */ + public function index(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/list'); + } + /** + * 根据商品id获取商品咨询 + */ + public function listQuery(){ + $m = new CG(); + return $m->listQuery(); + } + /** + * 发布商品咨询页 + */ + public function consult(){ + $this->assign('goodsId',(int)input('goodsId')); + return $this->fetch('goodsconsult/consult'); + } + public function add(){ + $m = new CG(); + return $m->add(); + } + +} diff --git a/hyhproject/wechat2/controller/Index.php b/hyhproject/wechat2/controller/Index.php new file mode 100755 index 0000000..0e9a3d5 --- /dev/null +++ b/hyhproject/wechat2/controller/Index.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\wechat\model\Index as M; +/** + * ============================================================================ + * 默认控制器 + */ +class Index extends Base{ + /** + * 首页 + */ + public function index(){ + $m = new M(); + hook('wechatControllerIndexIndex',['getParams'=>input()]); + $news = $m->getSysMsg('msg'); + $this->assign('news',$news); + $ads['count'] = count(model("common/Tags")->listAds("wx-ads-index",99,86400)); + $ads['width'] = 'width:'.$ads['count'].'00%'; + $this->assign("ads", $ads); + //是否关注公众号 + $signinfo = session('WST_WX_SIGNINFO'); + if(!empty($signinfo['subscribe'])){ + $signinfo['subscribe'] = ($signinfo['subscribe']==1)?0:1; + }else{ + $signinfo['subscribe'] = 0; + } + $subscribe = cookie("WST_WX_SUBSCRIBE"); + if($subscribe)$signinfo['subscribe'] = 0; + if(WSTConf('CONF.wxenabled')==1){ + $we = WSTWechat(); + $datawx = $we->getJsSignature('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + $this->assign("datawx", $datawx); + } + $this->assign("subscribe", $signinfo['subscribe']); + return $this->fetch('index'); + } + /** + * 楼层 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(); + if(isset($rs['goods'])){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + /** + * 跳去登录之前的地址 + */ + public function sessionAddress(){ + session('WST_WX_WlADDRESS',input('url')); + return WSTReturn("", 1); + } + /** + * 关闭关注 + */ + public function closeFollow(){ + cookie("WST_WX_SUBSCRIBE",1,25920000); + return WSTReturn("", 1); + } +} diff --git a/hyhproject/wechat2/controller/Invoices.php b/hyhproject/wechat2/controller/Invoices.php new file mode 100755 index 0000000..f1c70e9 --- /dev/null +++ b/hyhproject/wechat2/controller/Invoices.php @@ -0,0 +1,31 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Invoices as M; +/** + * ============================================================================ + * 发票信息控制器 + */ +class Invoices extends Base{ + /** + * 列表 + */ + public function pageQuery(){ + $m = new M(); + $rs = $m->pageQuery(5);// 移动版只显示5条发票信息 + return $rs; + } + /** + * 新增 + */ + public function add(){ + $m = new M(); + return $m->add(); + } + /** + * 修改 + */ + public function edit(){ + $m = new M(); + return $m->edit(); + } +} diff --git a/hyhproject/wechat2/controller/Logmoneys.php b/hyhproject/wechat2/controller/Logmoneys.php new file mode 100755 index 0000000..b02496d --- /dev/null +++ b/hyhproject/wechat2/controller/Logmoneys.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\wechat\controller; +/** + * ============================================================================ + * 资金流水控制器 + */ +class Logmoneys extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看用户资金流水 + */ + public function usermoneys(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $rs['isSetPayPwd'] = ($rs['payPwd']=='')?0:1; + unset($rs['payPwd']); + $rs['num'] = count(model('cashConfigs')->listQuery(0,$userId)); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/list'); + } + /** + * 资金流水 + */ + public function record(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,['lockMoney','userMoney','payPwd']); + $this->assign('rs',$rs); + return $this->fetch('users/logmoneys/record'); + } + /** + * 列表 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('LogMoneys')->pageQuery("",$userId); + return WSTReturn("", 1,$data); + } + /** + * 验证支付密码 + */ + public function checkPayPwd(){ + return model('wechat/users')->checkPayPwd(); + } + + /** + * 充值[用户] + */ + public function toRecharge(){ + $userId = (int)session('WST_USER.userId'); + $rs = model('Users')->getFieldsById($userId,'userMoney'); + $this->assign('rs',$rs); + $payments = model('common/payments')->recharePayments('3'); + $this->assign('payments',$payments); + $chargeItems = model('common/ChargeItems')->queryList(); + $this->assign('chargeItems',$chargeItems); + return $this->fetch('users/recharge/recharge'); + } +} diff --git a/hyhproject/wechat2/controller/Messages.php b/hyhproject/wechat2/controller/Messages.php new file mode 100755 index 0000000..57ea67b --- /dev/null +++ b/hyhproject/wechat2/controller/Messages.php @@ -0,0 +1,40 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Messages as M; +/** + * ============================================================================ + * 商城消息控制器 + */ +class Messages extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看商城消息 + */ + public function index(){ + return $this->fetch('users/messages/list'); + } + /** + * 获取列表 + */ + public function pageQuery(){ + $m = new M(); + return $m->pageQuery(); + } + /** + * 获取列表详情 + */ + public function getById(){ + $m = new M(); + return $m->getById(); + } + /** + * 删除地址 + */ + public function del(){ + $m = new M(); + return $m->batchDel(); + } +} diff --git a/hyhproject/wechat2/controller/News.php b/hyhproject/wechat2/controller/News.php new file mode 100755 index 0000000..d5d4c45 --- /dev/null +++ b/hyhproject/wechat2/controller/News.php @@ -0,0 +1,53 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\wechat\model\Articles as M; +/** + * ============================================================================ + * 新闻控制器 + */ +class News extends Base{ + /** + * 列表查询 + */ + public function view(){ + $m = new M(); + $data = $m->getChildInfos(); + $catId = $data['0']['catId']; + $articleId = (int)input('articleId'); + $this->assign('articleId',$articleId); + $this->assign('catInfo',$data); + $this->assign('catId',$catId); + return $this->fetch('articles/news_list'); + } + /** + * 获取商城快讯列表 + */ + public function getNewsList(){ + $m = new M(); + $data = $m->getArticles(); + foreach($data as $k=>$v){ + $data[$k]['articleContent'] = strip_tags(html_entity_decode($v['articleContent'])); + $data[$k]['createTime'] = date('Y-m-d',strtotime($data[$k]['createTime'])); + $data[$k]['coverImg'] = str_replace("_thumb.", ".", $data[$k]['coverImg']); + } + return $data; + } + /** + * 查看详情 + */ + public function getNews(){ + $m = new M(); + $data = $m->getNewsById(); + $data['articleContent']=htmlspecialchars_decode($data['articleContent']); + $data['createTime'] = date('Y-m-d',strtotime($data['createTime'])); + return $data; + } + /** + * 点赞 + */ + public function like(){ + $m = new M(); + $data = $m->like(); + return $data; + } +} diff --git a/hyhproject/wechat2/controller/Ordercomplains.php b/hyhproject/wechat2/controller/Ordercomplains.php new file mode 100755 index 0000000..40256b3 --- /dev/null +++ b/hyhproject/wechat2/controller/Ordercomplains.php @@ -0,0 +1,55 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\OrderComplains as M; +/** + * ============================================================================ + * 投诉控制器 + */ +class orderComplains extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + public function complain(){ + $oId = (int)input('oId'); + $this->assign('oId',$oId); + return $this->fetch('users/orders/orders_complains'); + } + /** + * 保存订单投诉信息 + */ + public function saveComplain(){ + return model('OrderComplains')->saveComplain(); + } + /** + * 用户投诉列表 + */ + public function index(){ + return $this->fetch('users/orders/list_complains'); + } + + /** + * 获取用户投诉列表 + */ + public function complainByPage(){ + $m = model('OrderComplains'); + return $m->queryUserComplainByPage(); + + } + + /** + * 用户查投诉详情 + */ + public function getComplainDetail(){ + $rs = model('OrderComplains')->getComplainDetail(0); + $annex = $rs['complainAnnex']; + if($annex){ + foreach($annex as $k=>$v){ + $annex1[] = WSTImg($v,2); + } + $rs['complainAnnex'] = $annex1; + } + return $rs; + } + +} diff --git a/hyhproject/wechat2/controller/Orderrefunds.php b/hyhproject/wechat2/controller/Orderrefunds.php new file mode 100755 index 0000000..81c0ea4 --- /dev/null +++ b/hyhproject/wechat2/controller/Orderrefunds.php @@ -0,0 +1,25 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\OrderRefunds as M; +/** + * ============================================================================ + * 订单退款控制器 + */ +class Orderrefunds extends Base{ + /** + * 用户申请退款 + */ + public function refund(){ + $m = new M(); + $rs = $m->refund(); + return $rs; + } + /** + * 商家处理是否同意 + */ + public function shopRefund(){ + $m = new M(); + $rs = $m->shopRefund(); + return $rs; + } +} diff --git a/hyhproject/wechat2/controller/Orders.php b/hyhproject/wechat2/controller/Orders.php new file mode 100755 index 0000000..c0215f8 --- /dev/null +++ b/hyhproject/wechat2/controller/Orders.php @@ -0,0 +1,269 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Orders as M; +use wstmart\common\model\Payments; +/** + * ============================================================================ + * 订单控制器 + */ +class Orders extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /*********************************************** 用户操作订单 ************************************************************/ + /** + * 提醒发货 + */ + public function noticeDeliver(){ + $m = new M(); + return $m->noticeDeliver(); + } + /** + * 提交订单 + */ + public function submit(){ + $m = new M(); + $rs = $m->submit(1); + return $rs; + } + /** + * 提交虚拟订单 + */ + public function quickSubmit(){ + $m = new M(); + $rs = $m->quickSubmit(); + return $rs; + } + /** + * 在线支付方式 + */ + public function succeed(){ + //获取支付方式 + $pa = new Payments(); + $payments = $pa->getByGroup('3'); + $this->assign('payments',$payments); + $this->assign('orderNo',input("get.orderNo")); + $this->assign('isBatch',(int)input("get.isBatch/d",0)); + return $this->fetch("users/orders/orders_pay_list"); + } + /** + * 订单管理 + */ + public function index(){ + $type = input('param.type',''); + $this->assign('type',$type); + return $this->fetch("users/orders/orders_list"); + } + + /** + * 订单列表 + */ + public function getOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0,1: 待收货 + 2:待评价/已完成 + */ + $flag = -1; + $type = input('param.type'); + $status = []; + switch ($type) { + case 'waitPay': + $status=[-2]; + break; + case 'waitDeliver': + $status=[0]; + break; + case 'waitReceive': + $status=[1]; + break; + case 'waitAppraise': + $status=[2]; + $flag=0; + break; + case 'finish': + $status=[2]; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->userOrdersByPage($status,$flag); + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + return $rs; + } + + /** + * 订单详情 + */ + public function getDetail(){ + $m = new M(); + $rs = $m->getByView((int)input('id')); + $rs['status'] = WSTLangOrderStatus($rs['orderStatus']); + $rs['payInfo'] = WSTLangPayType($rs['payType']); + $rs['deliverInfo'] = WSTLangDeliverType($rs['deliverType']); + foreach($rs['goods'] as $k=>$v){ + $v['goodsImg'] = WSTImg($v['goodsImg'],3); + } + // 优惠券钩子 + hook('wechatDocumentOrderSummaryView',['rs'=>&$rs]); + // 满就送钩子 + hook('wechatDocumentOrderViewGoodsPromotion',['rs'=>&$rs]); + return $rs; + } + + /** + * 用户确认收货 + */ + public function receive(){ + $m = new M(); + $rs = $m->receive(); + return $rs; + } + + /** + * 用户-评价页 + */ + public function orderAppraise(){ + $m = model('Orders'); + $oId = (int)input('oId'); + //根据订单id获取 商品信息 + $data = $m->getOrderInfoAndAppr(); + $data['shopName']=model('shops')->getShopName($oId); + $this->assign('data',$data); + $this->assign('oId',$oId); + return $this->fetch('users/orders/orders_appraises'); + } + + /** + * 用户取消订单 + */ + public function cancellation(){ + $m = new M(); + $rs = $m->cancel(); + return $rs; + } + + /** + * 用户拒收订单 + */ + public function reject(){ + $m = new M(); + $rs = $m->reject(); + return $rs; + } + + /** + * 用户退款 + */ + public function getRefund(){ + $m = new M(); + return $m->getMoneyByOrder((int)input('id')); + } + + + + /*********************************************** 商家操作订单 ************************************************************/ + + /** + * 商家-查看订单列表 + */ + public function sellerOrder(){ + $this->checkShopAuth("list"); + $type = input('param.type',''); + $this->assign('type',$type); + $express = model('Express')->listQuery(); + $this->assign('express',$express); + return $this->fetch('users/sellerorders/orders_list'); + } + + /** + * 商家-订单列表 + */ + public function getSellerOrderList(){ + /* + -3:拒收、退款列表 + -2:待付款列表 + -1:已取消订单 + 0: 待发货 + 1,2:待评价/已完成 + */ + $type = input('param.type'); + $this->checkShopAuth($type); + $status = []; + switch ($type) { + case 'waitPay': + $status=-2; + break; + case 'waitDeliver': + $status=0; + break; + case 'waitReceive': + $status=1; + break; + case 'waitDelivery': + $status=0; + break; + case 'finish': + $status=2; + break; + case 'abnormal': // 退款/拒收 与取消合并 + $status=[-1,-3]; + break; + default: + $status=[-3,-2,-1,0,1,2]; + break; + } + $m = new M(); + $rs = $m->shopOrdersByPage($status); + foreach($rs['Rows'] as $k=>$v){ + if(!empty($v['list'])){ + foreach($v['list'] as $k1=>$v1){ + $rs['Rows'][$k]['list'][$k1]['goodsImg'] = $v1['goodsImg']; + } + } + } + return WSTReturn('操作成功',1,$rs); + } + + /** + * 商家发货 + */ + public function deliver(){ + $this->checkShopAuth("waitDeliver"); + $m = new M(); + $rs = $m->deliver(); + return $rs; + } + /** + * 商家修改订单价格 + */ + public function editOrderMoney(){ + $this->checkShopAuth("waitPay"); + $m = new M(); + $rs = $m->editOrderMoney(); + return $rs; + } + /** + * 商家-操作退款 + */ + public function toShopRefund(){ + $this->checkShopAuth("abnormal"); + return model('OrderRefunds')->getRefundMoneyByOrder((int)input('id')); + } + + +} diff --git a/hyhproject/wechat2/controller/Shops.php b/hyhproject/wechat2/controller/Shops.php new file mode 100755 index 0000000..b76048c --- /dev/null +++ b/hyhproject/wechat2/controller/Shops.php @@ -0,0 +1,151 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\GoodsCats; +use wstmart\wechat\model\Goods; +/** + * ============================================================================ + * 门店控制器 + */ +class Shops extends Base{ + /** + * 店铺街 + */ + public function shopStreet(){ + $gc = new GoodsCats(); + $goodsCats = $gc->listQuery(0); + $this->assign('goodscats',$goodsCats); + $this->assign("keyword", input('keyword')); + return $this->fetch('shop_street'); + } + /** + * 店铺首页 + */ + public function index(){ + $s = model('shops'); + $shopId = (int)input('shopId',1); + $data = $s->getShopSummary($shopId); + $this->assign('data',$data); + // 是否已关注 + $isFavor = model('favorites')->checkFavorite($shopId,1); + $this->assign('isFavor',$isFavor); + $this->assign("goodsName", input('goodsName')); + return $this->fetch('shop_index'); + } + /** + * 店铺详情 + */ + public function home(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d",1); + $data['shop'] = $s->getShopInfo($shopId); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + if(($data['shop']['shopId']==1 || $shopId==0) && $ct1==0 && !isset($goodsName)) + $this->redirect('wechat/shops/selfShop'); + + $gcModel = model('ShopCats'); + $data['shopcats'] = $gcModel->getShopCats($shopId); + + $this->assign('shopId',$shopId);//店铺id + + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + // 是否已关注 + $isFavor = model('favorites')->checkFavorite($shopId,1); + $this->assign('isFavor',$isFavor); + $followNum = model('favorites')->followNum($shopId,1); + $this->assign('followNum',$followNum); + + $cart = model('carts')->getCartInfo(); + $this->assign('cart',$cart); + return $this->fetch('shop_home'); + } + /** + * 店铺商品列表 + */ + public function shopGoodsList(){ + $s = model('shops'); + $shopId = (int)input("param.shopId/d",1); + + $ct1 = input("param.ct1/d",0); + $ct2 = input("param.ct2/d",0); + $goodsName = input("param.goodsName"); + $gcModel = model('ShopCats'); + $data['shopcats'] = $gcModel->getShopCats($shopId); + + $this->assign('shopId',$shopId);//店铺id + + $this->assign('ct1',$ct1);//一级分类 + $this->assign('ct2',$ct2);//二级分类 + + $this->assign('goodsName',urldecode($goodsName));//搜索 + $this->assign('data',$data); + + return $this->fetch('shop_goods_list'); + } + /** + * 获取店铺商品 + */ + public function getShopGoods(){ + $shopId = (int)input('shopId',1); + $g = model('goods'); + $rs = $g->shopGoods($shopId); + foreach($rs['Rows'] as $k=>$v){ + $rs['Rows'][$k]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + return $rs; + } + + /** + * 自营店铺 + */ + public function selfShop(){ + $s = model('shops'); + $data['shop'] = $s->getShopInfo(1); + if(empty($data['shop']))return $this->fetch('error_lost'); + $this->assign('selfShop',1); + $data['shopcats'] = model('ShopCats')->getShopCats(1); + $this->assign('goodsName',urldecode(input("param.goodsName")));//搜索 + // 店长推荐 + $data['rec'] = $s->getRecGoods('rec'); + // 热销商品 + $data['hot'] = $s->getRecGoods('hot'); + $this->assign('data',$data); + // 是否已关注 + $isFavor = model('favorites')->checkFavorite(1,1); + $this->assign('isFavor',$isFavor); + $followNum = model('favorites')->followNum(1,1); + $this->assign('followNum',$followNum); + $this->assign("keyword", input('keyword')); + return $this->fetch('self_shop'); + } + public function getFloorData(){ + $s = model('shops'); + $rs = $s->getFloorData(); + if(isset($rs['goods'])){ + foreach($rs['goods'] as $k=>$v){ + $rs['goods'][$k]['goodsImg'] = WSTImg($v['goodsImg'],2); + } + } + return $rs; + } + + /** + * 店铺街列表 + */ + public function pageQuery(){ + $m = model('shops'); + $rs = $m->pageQuery(input('pagesize/d')); + foreach ($rs['Rows'] as $key =>$v){ + $rs['Rows'][$key]['shopImg'] = WSTImg($v['shopImg'],3); + } + return $rs; + } + +} diff --git a/hyhproject/wechat2/controller/Switchs.php b/hyhproject/wechat2/controller/Switchs.php new file mode 100755 index 0000000..a2487c6 --- /dev/null +++ b/hyhproject/wechat2/controller/Switchs.php @@ -0,0 +1,28 @@ +<?php +namespace wstmart\wechat\controller; +/** + * ============================================================================ + * 关闭提示处理控制器 + */ +use think\Controller; +class Switchs extends Controller{ + public function __construct(){ + parent::__construct(); + WSTConf('CONF',WSTConfig()); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wstPcStyleId')); + if(WSTConf('CONF.wxenabled')==1){ + if(!(request()->module()=="wechat" && request()->controller()=="Weixinpays" && request()->action()=="notify")){ + WSTIsWeixin();//检测是否在微信浏览器上使用 + } + } + } + protected function fetch($template = '', $vars = [], $replace = [], $config = []){ + $style = WSTConf('CONF.wstwechatStyle')?WSTConf('CONF.wstwechatStyle'):'default'; + $replace['__WECHAT__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/wstmart/wechat/view/'.$style; + return $this->view->fetch($style."/".$template, $vars, $replace, $config); + + } + public function index(){ + return $this->fetch('error_switch'); + } +} diff --git a/hyhproject/wechat2/controller/Unionpays.php b/hyhproject/wechat2/controller/Unionpays.php new file mode 100755 index 0000000..55bd733 --- /dev/null +++ b/hyhproject/wechat2/controller/Unionpays.php @@ -0,0 +1,211 @@ +<?php +namespace wstmart\wechat\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +/** + * ============================================================================ + * 银联支付控制器 + */ +class Unionpays extends Base{ + + /** + * 初始化 + */ + private $unionConfig; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('unionpay.sdk.acp_service'); + $m = new M(); + $this->unionConfig = $m->getPayment("unionpays"); + + $config = array(); + $config["signCertPwd"] = $this->unionConfig["unionSignCertPwd"];//"000000" + $config["signMethod"] = "01"; + + $config["frontUrl"] = url("wechat/orders/index","",true,true); + $config["backUrl"] = url("wechat/unionpays/notify","",true,true); + new \SDKConfig($config); + } + + + public function getUnionpaysUrl(){ + $m = new OM(); + $payObj = input("payObj/s"); + $data = array(); + if($payObj=="recharge"){ + $needPay = input("needPay/d"); + $data["status"] = $needPay>0?1:-1; + }else{ + $userId = (int)session('WST_USER.userId'); + $data = $m->checkOrderPay(); + } + return $data; + } + + /** + * 生成支付代码 + * @param array $order 订单信息 + * @param array $config_value 支付方式信息 + */ + public function toUnionpay(){ + + $payObj = input("payObj/s"); + $m = new OM(); + $obj = array(); + $data = array(); + $orderAmount = 0; + $orderId = ""; + $extra_param = ""; + if($payObj=="recharge"){//充值 + $orderAmount = input("needPay/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $data["status"] = $orderAmount>0?1:-1; + $orderId = WSTOrderNo(); + $extra_param = $payObj."|".$targetId."|".$targetType; + + }else{ + $obj["orderNo"] = input("orderNo/s"); + $obj["isBatch"] = (int)input("isBatch/d"); + $data = $m->checkOrderPay($obj); + if($data["status"]==1){ + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $order = $m->getPayOrders($obj); + $orderAmount = $order["needPay"]; + $payRand = $order["payRand"]; + $orderId = $obj["orderNo"]."a".$payRand; + $extra_param = $payObj."|".$userId."|".$obj["isBatch"]; + } + } + + if($data["status"]==1){ + $params = array( + //以下信息非特殊情况不需要改动 + 'version' => \SDKConfig::$version, //版本号 + 'encoding' => 'utf-8', //编码方式 + 'txnType' => '01', //交易类型 + 'txnSubType' => '01', //交易子类 + 'bizType' => '000201', //业务类型 + 'frontUrl' => \SDKConfig::$frontUrl, //前台通知地址 + 'backUrl' => \SDKConfig::$backUrl, //后台通知地址 + 'signMethod' => \SDKConfig::$signMethod,//签名方法 + 'channelType' => '08', //渠道类型,07-PC,08-手机 + 'accessType' => '0', //接入类型 + 'currencyCode' => '156', //交易币种,境内商户固定156 + //TODO 以下信息需要填写 + 'merId' => $this->unionConfig["unionMerId"], //"777290058110048",//商户代码 + 'orderId' => $orderId, //商户订单号,8-32位数字字母,不能含“-”或“_” + 'txnTime' => date('YmdHis'), //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间 + 'txnAmt' => $orderAmount*100, //交易金额,单位分,此处默认取demo演示页面传递的参数 + // 订单超时时间。 + //'payTimeout' => date('YmdHis', strtotime('+15 minutes')), + + 'reqReserved' => $extra_param, + ); + $acpService = new \AcpService(); + $acpService::sign ( $params ); + $uri = \SDKConfig::$frontTransUrl; + $html_form = $acpService::createAutoFormHtml( $params, $uri ); + echo $html_form; + }else{ + + } + } + + /** + * 异步回调接口 + */ + public function notify(){ + + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){//验证成功 + $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + // 解释: 交易成功且结束,即不可再做任何操作。 + if($_POST['respMsg'] == 'Success!'){ + $m = new OM(); + $extras = explode("|",$_POST['reqReserved']); + $rs = array(); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $obj = array (); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $_POST["out_trade_no"];; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["total_fee"] = $_POST['total_fee']; + $obj["payFrom"] = 'unionpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + //商户订单号 + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["trade_no"] = $_POST['trade_no']; + $obj["out_trade_no"] = $tradeNo[0]; + $obj["total_fee"] = $_POST['total_fee']; + + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = 'unionpays'; + //支付成功业务逻辑 + $rs = $m->complatePay($obj); + } + if($rs["status"]==1){ + echo 'success'; + }else{ + echo 'fail'; + } + } + }else{ + echo "fail"; //验证失败 + } + } + + /** + * 同步回调接口 + */ + public function response(){ + //计算得出通知验证结果 + $acpService = new \AcpService(); // 使用银联原生自带的累 和方法 这里只是引用了一下 而已 + $verify_result = $acpService->validate($_POST); + + if($verify_result){ //验证成功 + $order_sn = $out_trade_no = $_POST['orderId']; //商户订单号 + $queryId = $_POST['queryId']; //银联支付流水号 + $respMsg = $_POST['respMsg']; //交易状态 + + if($_POST['respMsg'] == 'success'){ + $m = new OM(); + $extras = explode("|",$_POST['extra_param']); + if($extras[0]=="recharge"){//充值 + $this->redirect(url("wechat/users/index")); + }else{ + $obj = array(); + $tradeNo = explode("a",$out_trade_no); + $obj["orderNo"] = $tradeNo[0]; + $obj["userId"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $rs = $m->getOrderType($obj); + $this->redirect(url("wechat/orders/index")); + } + }else { + $this->error('支付失败'); + } + }else { + $this->error('支付失败'); + } + } + +} diff --git a/hyhproject/wechat2/controller/Useraddress.php b/hyhproject/wechat2/controller/Useraddress.php new file mode 100755 index 0000000..deb6ade --- /dev/null +++ b/hyhproject/wechat2/controller/Useraddress.php @@ -0,0 +1,61 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\UserAddress as M; +/** + * ============================================================================ + * 用户地址控制器 + */ +class UserAddress extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 地址管理 + */ + public function index(){ + $m = new M(); + $userId = session('WST_USER.userId'); + $addressList = $m->listQuery($userId); + //获取省级地区信息 + $area = model('WeChat/Areas')->listQuery(0); + $this->assign('area',$area); + $this->assign('list', $addressList); + $this->assign('type', (int)input('type')); + $this->assign('addressId', (int)input('addressId'));//结算选中的地址 + return $this->fetch('users/useraddress/list'); + } + /** + * 获取地址信息 + */ + public function getById(){ + $m = new M(); + return $m->getById(input('post.addressId/d')); + } + /** + * 设置为默认地址 + */ + public function setDefault(){ + $m = new M(); + return $m->setDefault(); + } + /** + * 新增/编辑地址 + */ + public function edits(){ + $m = new M(); + if((int)input('addressId')>0){ + $rs = $m->edit(); + }else{ + $rs = $m->add(); + } + return $rs; + } + /** + * 删除地址 + */ + public function del(){ + $m = new M(); + return $m->del(); + } +} diff --git a/hyhproject/wechat2/controller/Users.php b/hyhproject/wechat2/controller/Users.php new file mode 100755 index 0000000..ab02e58 --- /dev/null +++ b/hyhproject/wechat2/controller/Users.php @@ -0,0 +1,372 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\wechat\model\Users as M; +use wstmart\wechat\model\Messages; +use wstmart\common\model\LogSms; +use wstmart\common\model\Users as MUsers; +/** + * ============================================================================ + * 用户控制器 + */ +class Users extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' => ['except'=>'checklogin,login,register,getverify,getphoneverifycode,checkuserphone']// 访问这些except下的方法不需要执行前置操作 + ]; + /** + * 会员登录页 + */ + public function login(){ + //如果已经登录了则直接跳去用户中心 + $USER = session('WST_USER'); + if(!empty($USER) && $USER['userId']!=''){ + $this->redirect("users/index"); + } + $userinfo = session('WST_WX_USERINFO'); + $this->assign('info',$userinfo); + return $this->fetch('login'); + } + /** + * 会员登录 + */ + public function checkLogin(){ + $m = new M(); + $rs = $m->checkLogin(1); + $rs['url'] = session('WST_WX_WlADDRESS'); + return $rs; + } + /** + * 会员注册 + */ + public function register(){ + $m = new M(); + $rs = $m->regist(1); + $rs['url'] = session('WST_WX_WlADDRESS'); + return $rs; + } + + /** + * 手机号码是否存在 + */ + public function checkUserPhone(){ + $userPhone = input("post.userPhone"); + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已注册",-1); + }else{ + return WSTReturn("",1); + } + } + + /** + * 获取验证码 + */ + public function getPhoneVerifyCode(){ + $userPhone = input("post.userPhone"); + $rs = array(); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $m = new M(); + $rs = $m->checkUserPhone($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $phoneVerify = rand(100000,999999); + $tpl = WSTMsgTemplates('PHONE_USER_REGISTER_VERFIY'); + if($tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['MALL_NAME'=>WSTConf("CONF.mallName"),'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyCode',$phoneVerify); + } + if($rv['status']==1){ + session('VerifyCode_userPhone',$phoneVerify); + session('VerifyCode_userPhone_Time',time()); + } + return $rv; + } + /** + * 会员中心 + */ + public function index(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + if($user['userName']=='')$user['userName']=$user['loginName']; + $this->assign('user', $user); + //商城未读消息的数量 及 各订单状态数量 + $data = model('index')->getSysMsg('msg','order','follow','history'); + $this->assign('data',$data); + if(WSTConf('CONF.wxenabled')==1){ + $we = WSTWechat(); + $datawx = $we->getJsSignature('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + $this->assign("datawx", $datawx); + } + return $this->fetch('users/index'); + } + + /** + * 个人信息 + */ + public function edit(){ + $userId = session('WST_USER.userId'); + $m = new M(); + $user = $m->getById($userId); + $this->assign('user', $user); + return $this->fetch('users/edit'); + } + /** + * 编辑个人信息 + */ + public function editUserInfo(){ + $m = new M(); + return $m->edit(); + } + /** + * 账户安全 + */ + public function security(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $userPhone = $user['userPhone']; + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $user['payPwd'] = empty($payPwd)?0:1; + $user['userPhone'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/index'); + } + /** + * 修改登录密码 + */ + public function editLoginPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $loginPwd = $user['loginPwd']; + $user['loginPwd'] = empty($loginPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_login_pass'); + } + public function editloginPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPass($userId); + } + /** + * 修改支付密码 + */ + public function editPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $payPwd = $user['payPwd']; + $user['payPwd'] = empty($payPwd)?0:1; + $this->assign('user', $user); + return $this->fetch('users/security/user_pay_pass'); + } + public function editpayPwd(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + return $m->editPayPass($userId); + } + /** + * 忘记支付密码 + */ + public function backPayPass(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $backType = (int)session('Type_backPaypwd'); + $timeVerify = session('Verify_backPaypwd_Time'); + $user['backType'] = ($backType==1 && time()<floatval($timeVerify)+10*60)?1:0; + $this->assign('user', $user); + return $this->fetch('users/security/user_back_paypwd'); + } + /** + * 忘记支付密码:发送短信 + */ + public function backpayCode(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_FOTGET_PAY'); + if($tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_backPaypwd_info',$USER); + session('Verify_backPaypwd_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 忘记支付密码:验证短信 + */ + public function verifybackPay(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_backPaypwd_Time'); + if(!session('Verify_backPaypwd_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_backPaypwd_info.phoneVerify')){ + session('Type_backPaypwd',1); + return WSTReturn("验证成功",1); + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 忘记支付密码:重置密码 + */ + public function resetbackPay(){ + $m = new M(); + return $m->resetbackPay(); + } + /** + * 修改手机 + */ + public function editPhone(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $user['phoneType'] = empty($userPhone)?0:1; + $this->assign('user', $user); + session('Edit_userPhone_Time', null); + return $this->fetch('users/security/user_phone'); + } + /** + * 绑定手机:发送短信验证码 + */ + public function sendCodeTie(){ + $userPhone = input("post.userPhone"); + if(!WSTIsPhone($userPhone)){ + return WSTReturn("手机号格式不正确!"); + exit(); + } + $rs = array(); + $m = new MUsers(); + $rs = WSTCheckLoginKey($userPhone,(int)session('WST_USER.userId')); + if($rs["status"]!=1){ + return WSTReturn("手机号已存在!"); + exit(); + } + $data = $m->getById(session('WST_USER.userId')); + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_BIND'); + if($tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'sendCodeTie',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info',$USER); + session('Verify_userPhone_Time',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 绑定手机 + */ + public function phoneEdit(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_userPhone_Time'); + if(!session('Verify_info.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info.phoneVerify')){ + $m = new M(); + $rs = $m->editPhone((int)session('WST_USER.userId'),session('Verify_info.userPhone')); + return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + /** + * 修改手机:发送短信验证码 + */ + public function sendCodeEdit(){ + $m = new MUsers(); + $data = $m->getById(session('WST_USER.userId')); + $userPhone = $data['userPhone']; + $phoneVerify = rand(100000,999999); + $rv = ['status'=>-1,'msg'=>'短信发送失败']; + $tpl = WSTMsgTemplates('PHONE_EDIT'); + if($tpl['tplContent']!='' && $tpl['status']=='1'){ + $params = ['tpl'=>$tpl,'params'=>['LOGIN_NAME'=>$data['loginName'],'VERFIY_CODE'=>$phoneVerify,'VERFIY_TIME'=>10]]; + $m = new LogSms(); + $rv = $m->sendSMS(0,$userPhone,$params,'getPhoneVerifyt',$phoneVerify); + } + if($rv['status']==1){ + $USER = []; + $USER['userPhone'] = $userPhone; + $USER['phoneVerify'] = $phoneVerify; + session('Verify_info2',$USER); + session('Verify_userPhone_Time2',time()); + return WSTReturn('短信发送成功!',1); + } + return $rv; + } + /** + * 修改手机 + */ + public function phoneEdito(){ + $phoneVerify = input("post.phoneCode"); + $timeVerify = session('Verify_userPhone_Time2'); + if(!session('Verify_info2.phoneVerify') || time()>floatval($timeVerify)+10*60){ + return WSTReturn("校验码已失效,请重新发送!"); + exit(); + } + if($phoneVerify==session('Verify_info2.phoneVerify')){ + session('Edit_userPhone_Time',time()); + return WSTReturn("验证成功",1); + //return $rs; + } + return WSTReturn("校验码不一致,请重新输入!"); + } + public function editPhoneo(){ + $m = new M(); + $userId = (int)session('WST_USER.userId'); + $user = $m->getById($userId); + $userPhone = $user['userPhone']; + $user['userPhone'] = WSTStrReplace($user['userPhone'],'*',3); + $timeVerify = session('Edit_userPhone_Time'); + if(time()>floatval($timeVerify)+15*60){ + $user['phoneType'] = 1; + }else{ + $user['phoneType'] = 0; + } + $this->assign('user', $user); + return $this->fetch('users/security/user_phone'); + } + public function userSet(){ + return $this->fetch('users/userset/list'); + } + public function aboutUs(){ + return $this->fetch('users/userset/about'); + } +} diff --git a/hyhproject/wechat2/controller/Userscores.php b/hyhproject/wechat2/controller/Userscores.php new file mode 100755 index 0000000..6f3ef37 --- /dev/null +++ b/hyhproject/wechat2/controller/Userscores.php @@ -0,0 +1,38 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\UserScores as MUserscores; +/** + * ============================================================================ + * 地区控制器 + */ +class Userscores extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 查看 + */ + public function index(){ + $rs = model('Users')->getFieldsById((int)session('WST_USER.userId'),['userScore','userTotalScore']); + $this->assign('object',$rs); + return $this->fetch('users/userscores/list'); + } + /** + * 获取数据 + */ + public function pageQuery(){ + $userId = (int)session('WST_USER.userId'); + $data = model('UserScores')->pageQuery($userId); + return WSTReturn("", 1,$data); + } + /** + * 签到积分 + */ + public function signScore(){ + $m = new MUserscores(); + $userId = (int)session('WST_USER.userId'); + $rs = $m->signScore($userId); + return $rs; + } +} diff --git a/hyhproject/wechat2/controller/Wallets.php b/hyhproject/wechat2/controller/Wallets.php new file mode 100755 index 0000000..dd57d61 --- /dev/null +++ b/hyhproject/wechat2/controller/Wallets.php @@ -0,0 +1,48 @@ +<?php +namespace wstmart\wechat\controller; +use wstmart\common\model\Orders as OM; +/** + * ============================================================================ + * 余额控制器 + */ +class Wallets extends Base{ + // 前置方法执行列表 + protected $beforeActionList = [ + 'checkAuth' + ]; + /** + * 跳去支付页面 + */ + public function payment(){ + $data = []; + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $this->assign('data',$data); + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + + $list = $m->getByUnique(); + $this->assign('rs',$list); + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $this->assign('needPay',$rs['needPay']); + //获取用户钱包 + $user = model('users')->getFieldsById($data['userId'],'userMoney,payPwd'); + $this->assign('userMoney',$user['userMoney']); + $payPwd = $user['payPwd']; + $payPwd = empty($payPwd)?0:1; + $this->assign('payPwd',$payPwd); + } + return $this->fetch('users/orders/orders_pay_wallets'); + } + /** + * 钱包支付 + */ + public function payByWallet(){ + $m = new OM(); + return $m->payByWallet(); + } +} diff --git a/hyhproject/wechat2/controller/Weixin.php b/hyhproject/wechat2/controller/Weixin.php new file mode 100755 index 0000000..efe02cc --- /dev/null +++ b/hyhproject/wechat2/controller/Weixin.php @@ -0,0 +1,55 @@ +<?php +namespace wstmart\wechat\controller; +use think\Controller; +/** + * ============================================================================ + * 微信接入接口控制器 + */ +class Weixin extends Controller{ + public function index(){ + if(isset($_GET['echostr'])){ + $this->first(); + }else{ + $wechat = new \wechat\WSTWechat(WSTConf('CONF.wxAppId'),WSTConf('CONF.wxAppKey')); + $wechat->responseMsg(); + } + } + + public function first() + { + $echoStr = input("echostr"); + if($this->checkSignature()){ + echo $echoStr; + exit; + } + } + private function checkSignature() + { + $signature = input("signature"); + $timestamp = input("timestamp"); + $nonce = input("nonce"); + + $token = WSTConf('CONF.wxAppCode'); + + $tmpArr = array($token, $timestamp, $nonce); + sort($tmpArr, SORT_STRING); + $tmpStr = implode( $tmpArr ); + $tmpStr = sha1( $tmpStr ); + if( $tmpStr == $signature ){ + return true; + }else{ + return false; + } + } + + /******************** 调用模板消息接口 *************************/ + public function getTemplates(){ + $wechat = new \wechat\WSTWechat(WSTConf('CONF.wxAppId'),WSTConf('CONF.wxAppKey')); + $rs = $wechat->getTemplates(); + dump(json_decode($rs,true)); + } + public function sendTemplate(){ + $wechat = new \wechat\WSTWechat(WSTConf('CONF.wxAppId'),WSTConf('CONF.wxAppKey')); + $wechat->sendTemplate(); + } +} diff --git a/hyhproject/wechat2/controller/Weixinpays.php b/hyhproject/wechat2/controller/Weixinpays.php new file mode 100755 index 0000000..826b1b4 --- /dev/null +++ b/hyhproject/wechat2/controller/Weixinpays.php @@ -0,0 +1,204 @@ +<?php +namespace wstmart\wechat\controller; +use think\Loader; +use wstmart\common\model\Payments as M; +use wstmart\common\model\Orders as OM; +use wstmart\common\model\LogMoneys as LM; +use wstmart\common\model\ChargeItems as CM; +/** + * ============================================================================ + * 微信支付控制器 + */ +class Weixinpays extends Base{ + + /** + * 初始化 + */ + private $wxpayConfig; + private $wxpay; + public function _initialize() { + header ("Content-type: text/html; charset=utf-8"); + Loader::import('wxpay.WxPayConf'); + Loader::import('wxpay.WxJsApiPay'); + + $this->wxpayConfig = array(); + $m = new M(); + $this->wxpay = $m->getPayment("weixinpays"); + $this->wxpayConfig['appid'] = $this->wxpay['appId']; // 微信公众号身份的唯一标识 + $this->wxpayConfig['appsecret'] = $this->wxpay['appsecret']; // JSAPI接口中获取openid + $this->wxpayConfig['mchid'] = $this->wxpay['mchId']; // 受理商ID + $this->wxpayConfig['key'] = $this->wxpay['apiKey']; // 商户支付密钥Key + $this->wxpayConfig['notifyurl'] = url("wechat/weixinpays/notify","",true,true); + $this->wxpayConfig['returnurl'] = url("wechat/orders/index","",true,true); + $this->wxpayConfig['curl_timeout'] = 30; + + // 初始化WxPayConf + new \WxPayConf($this->wxpayConfig); + } + + + public function toPay(){ + $data = []; + $payObj = input("payObj/s"); + if($payObj=="recharge"){ + $cm = new CM(); + $itemId = (int)input("itemId/d"); + $targetType = (int)input("targetType/d"); + $targetId = (int)session('WST_USER.userId'); + if($targetType==1){//商家 + $targetId = (int)session('WST_USER.shopId'); + } + $needPay = 0; + if($itemId>0){ + $item = $cm->getItemMoney($itemId); + $needPay = isSet($item["chargeMoney"])?$item["chargeMoney"]:0; + }else{ + $needPay = (int)input("needPay/d"); + } + $out_trade_no = WSTOrderNo(); + $body = "钱包充值"; + $data["status"] = $needPay>0?1:-1; + $attach = $payObj."@".$targetId."@".$targetType."@".$needPay."@".$itemId; + $returnurl = url("wechat/logmoneys/usermoneys","",true,true); + }else{ + + $data['orderNo'] = input('orderNo'); + $data['isBatch'] = (int)input('isBatch'); + $data['userId'] = (int)session('WST_USER.userId'); + $m = new OM(); + $rs = $m->getOrderPayInfo($data); + if(empty($rs)){ + $this->assign('type',''); + return $this->fetch("users/orders/orders_list"); + }else{ + $pkey = base64_decode(input("pkey")); + $extras = explode ( "@",$pkey); + + $m = new OM(); + $userId = (int)session('WST_USER.userId'); + $obj["userId"] = $userId; + $obj["orderNo"] = input("orderNo"); + $obj["isBatch"] = (int)input("isBatch"); + + $rs = $m->getByUnique(); + $this->assign('rs',$rs); + $body = "支付订单"; + $order = $m->getPayOrders($obj); + $needPay = $order["needPay"]; + $payRand = $order["payRand"]; + $out_trade_no = $obj["orderNo"]."a1".$payRand; + $attach = $userId."@".$obj["orderNo"]."@".$obj["isBatch"]; + $returnurl = url("wechat/orders/index","",true,true); + } + } + //使用jsapi接口 + $jsApi = new \JsApi(); + //使用统一支付接口 + $unifiedOrder = new \UnifiedOrder(); + $openid = session('WST_USER.wxOpenId'); + $unifiedOrder->setParameter("openid",$openid);//商品描述 + + //自定义订单号,此处仅作举例 + $unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号 + $unifiedOrder->setParameter("notify_url",$this->wxpayConfig ['notifyurl']);//通知地址 + $unifiedOrder->setParameter("trade_type","JSAPI");//交易类型 + + $unifiedOrder->setParameter("body",$body);//商品描述 + $needPay = WSTBCMoney($needPay,0,2); + $unifiedOrder->setParameter("total_fee", $needPay * 100);//总金额 + $userId = (int)session('WST_USER.userId'); + + $this->assign('needPay',$needPay); + $this->assign('returnUrl',$returnurl ); + $this->assign('payObj',$payObj); + + $unifiedOrder->setParameter("attach",$attach);//附加数据 + + $prepay_id = $unifiedOrder->getPrepayId(); + //=========步骤3:使用jsapi调起支付============ + $jsApi->setPrepayId($prepay_id); + + $jsApiParameters = $jsApi->getParameters(); + $this->assign('jsApiParameters',$jsApiParameters); + return $this->fetch('users/orders/orders_pay'); + } + + + public function toAddonPay() { + $this->assign('payObj',session("addonPay.payObj")); + $this->assign('object',session("addonPay.object")); + $this->assign('needPay',session("addonPay.needPay")); + $this->assign('returnUrl',session("addonPay.returnUrl")); + $this->assign('jsApiParameters',session("addonPay.jsApiParameters")); + $ctr = new \think\addons\Controller(); + return $ctr->fetch(session("addonPay.showUrl")); + } + + + + public function notify() { + // 使用通用通知接口 + $notify = new \Notify(); + // 存储微信的回调 + $xml = file_get_contents("php://input"); + $notify->saveData ( $xml ); + if ($notify->checkSign () == FALSE) { + $notify->setReturnParameter ( "return_code", "FAIL" ); // 返回状态码 + $notify->setReturnParameter ( "return_msg", "签名失败" ); // 返回信息 + } else { + $notify->setReturnParameter ( "return_code", "SUCCESS" ); // 设置返回码 + } + $returnXml = $notify->returnXml (); + if ($notify->checkSign () == TRUE) { + if ($notify->data ["return_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } elseif ($notify->data ["result_code"] == "FAIL") { + // 此处应该更新一下订单状态,商户自行增删操作 + } else { + $order = $notify->getData (); + $rs = $this->process($order); + if($rs["status"]==1){ + echo "SUCCESS"; + }else{ + echo "FAIL"; + } + } + } + } + + //订单处理 + private function process($order) { + + $obj = array(); + $obj["trade_no"] = $order['transaction_id']; + + $obj["total_fee"] = (float)$order["total_fee"]/100; + $extras = explode ( "@", $order ["attach"] ); + if($extras[0]=="recharge"){//充值 + $targetId = (int)$extras [1]; + $targetType = (int)$extras [2]; + $itemId = (int)$extras [4]; + + $obj["out_trade_no"] = $order['out_trade_no']; + $obj["targetId"] = $targetId; + $obj["targetType"] = $targetType; + $obj["itemId"] = $itemId; + $obj["payFrom"] = 'weixinpays'; + // 支付成功业务逻辑 + $m = new LM(); + $rs = $m->complateRecharge ( $obj ); + }else{ + $obj["userId"] = $extras[0]; + $obj["out_trade_no"] = $extras[1]; + $obj["isBatch"] = $extras[2]; + $obj["payFrom"] = "weixinpays"; + // 支付成功业务逻辑 + $m = new OM(); + $rs = $m->complatePay ( $obj ); + } + + return $rs; + + } + +} diff --git a/hyhproject/wechat2/model/Articles.php b/hyhproject/wechat2/model/Articles.php new file mode 100755 index 0000000..5eb5b21 --- /dev/null +++ b/hyhproject/wechat2/model/Articles.php @@ -0,0 +1,100 @@ +<?php +namespace wstmart\wechat\model; +use think\Db; +/** + * ============================================================================ + * 文章类 + */ +class Articles extends Base{ + + /** + * 获取咨询中中心所有文章 + */ + public function getArticles(){ + // 获取咨询中心下的所有分类id + $catId = input('catId'); + $rs = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where(['a.catId'=>$catId, + 'a.isShow'=>1, + 'a.dataFlag'=>1, + 'ac.dataFlag'=>1, + 'ac.isShow'=>1, + 'ac.catType'=>0, + ]) + ->order('createTime desc') + ->paginate((int)input('pagesize')); + return $rs; + } + + + /** + * 根据id获取资讯文章 + */ + public function getNewsById(){ + $id = (int)input('id'); + WSTArticleVisitorNum($id);// 统计文章访问量 + $article = $this->alias('a') + ->field('a.*') + ->join('__ARTICLE_CATS__ ac','a.catId=ac.catId','inner') + ->where('ac.catType=0 and a.dataFlag=1 and a.isShow=1') + ->cache(true) + ->find($id); + // 图片延迟加载 + $article['articleContent']=htmlspecialchars_decode($article['articleContent']); + $rule = '/<img src="\/(wstmartp.*?)"/'; + preg_match_all($rule, $article['articleContent'],$images); + foreach($images[0] as $k=>$v){ + $article['articleContent'] = str_replace($v, "<img src='/".WSTImg($images[1][$k],3)."'", $article['articleContent']); + } + $articleId = cookie("wechat_like_articleId"); + $articleId = is_array($articleId)?$articleId:[]; + $rc = !empty($articleId)?in_array($id,$articleId):''; + if($rc){ + $article['likeState'] = 1; + }else{ + $article['likeState'] = 0; + } + return $article; + } + /** + * 点赞 + */ + public function like(){ + $id = input("param.id/d"); + //判断记录是否存在 + $articleId = cookie("wechat_like_articleId"); + $articleId = is_array($articleId)?$articleId:[]; + $rc = !empty($articleId)?in_array($id,$articleId):''; + if($rc)return WSTReturn("已点赞成功", -1); + $rs = $this->where(['isShow'=>1,'dataFlag'=>1,'articleId'=>$id])->setInc('likeNum',1); + //判断是否点赞成功 + if(false !== $rs){ + array_push($articleId,$id); + cookie("wechat_like_articleId",$articleId,25920000); + return WSTReturn("点赞成功", 1); + }else{ + return WSTReturn($this->getError(),-1); + } + } + /** + * 获取资讯中心的子集分类 + */ + public function getChildInfos(){ + $infos = cache('NEW_INFOS'); + $i = 0; + if(!$infos){ + $data = Db::name('article_cats')->cache(true)->select(); + foreach($data as $k=>$v){ + if($v['parentId']== 8){ + $infos[$i]['catId'] = $v['catId']; + $infos[$i]['catName'] = $v['catName']; + $i++; + } + } + cache('NEW_INFOS',$infos); + } + return $infos; + } +} diff --git a/hyhproject/wechat2/model/Base.php b/hyhproject/wechat2/model/Base.php new file mode 100755 index 0000000..51c0c33 --- /dev/null +++ b/hyhproject/wechat2/model/Base.php @@ -0,0 +1,8 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Base as CBase; +/** + * ============================================================================ + * 基础模型器 + */ +class Base extends CBase {} \ No newline at end of file diff --git a/hyhproject/wechat2/model/Goods.php b/hyhproject/wechat2/model/Goods.php new file mode 100755 index 0000000..2c0b927 --- /dev/null +++ b/hyhproject/wechat2/model/Goods.php @@ -0,0 +1,124 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Goods as CGoods; +use think\Db; +/** + * ============================================================================ + * 商品类 + */ +class Goods extends CGoods{ + /** + * 获取列表 + */ + public function pageQuery($goodsCatIds = []){ + //查询条件 + $keyword = input('keyword'); + $brandId = input('brandId/d'); + $where = $where2 = []; + $where['goodsStatus'] = 1; + $where['g.dataFlag'] = 1; + $where['isSale'] = 1; + if($keyword!='')$where['goodsName'] = ['like','%'.$keyword.'%']; + if($brandId>0)$where['g.brandId'] = $brandId; + //排序条件 + $orderBy = input('condition/d',0); + $orderBy = ($orderBy>=0 && $orderBy<=4)?$orderBy:0; + $order = (input('desc/d',0)==1)?1:0; + $pageBy = ['saleNum','shopPrice','visitNum','saleTime']; + $pageOrder = ['desc','asc']; + if(!empty($goodsCatIds))$where['goodsCatIdPath'] = ['like',implode('_',$goodsCatIds).'_%']; + $list = Db::name('goods')->alias('g')->join("__SHOPS__ s","g.shopId = s.shopId")->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where($where) + ->field('g.goodsId,goodsName,saleNum,shopPrice,marketPrice,isSpec,goodsImg,appraiseNum,visitNum,s.shopId,shopName,isSelf,isFreeShipping,gallery,gs.totalScore,gs.totalUsers') + ->order($pageBy[$orderBy]." ".$pageOrder[$order].",goodsId asc") + ->paginate(input('pagesize/d'))->toArray(); + return $list; + } + + /** + * 获取商品资料在前台展示 + */ + public function getBySale($goodsId){ + $key = input('key'); + // 浏览量 + $this->where('goodsId',$goodsId)->setInc('visitNum',1); + $rs = Db::name('goods')->where(['goodsId'=>$goodsId,'dataFlag'=>1])->find(); + if(!empty($rs)){ + $rs['read'] = false; + //判断是否可以公开查看 + $viKey = WSTShopEncrypt($rs['shopId']); + if(($rs['isSale']==0 || $rs['goodsStatus']==0) && $viKey != $key)return []; + if($key!='')$rs['read'] = true; + //获取店铺信息 + $rs['shop'] = model('shops')->getBriefShop((int)$rs['shopId']); + if(empty($rs['shop']))return []; + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left')->join('__SHOPS__ s','s.shopId = cs.shopId','left') + ->where('cs.shopId',$rs['shopId'])->field('cs.shopId,s.shopTel,gc.catId,gc.catName')->select(); + $rs['shop']['catId'] = $goodsCats[0]['catId']; + $rs['shop']['shopTel'] = $goodsCats[0]['shopTel']; + $cat = []; + foreach ($goodsCats as $v){ + $cat[] = $v['catName']; + } + $rs['shop']['cat'] = implode(',',$cat); + + if(empty($rs['shop']))return []; + $gallery = []; + $gallery[] = $rs['goodsImg']; + if($rs['gallery']!=''){ + $tmp = explode(',',$rs['gallery']); + $gallery = array_merge($gallery,$tmp); + } + $rs['gallery'] = $gallery; + //获取规格值 + $specs = Db::name('spec_cats')->alias('gc')->join('__SPEC_ITEMS__ sit','gc.catId=sit.catId','inner') + ->where(['sit.goodsId'=>$goodsId,'gc.isShow'=>1,'sit.dataFlag'=>1]) + ->field('gc.isAllowImg,gc.catName,sit.catId,sit.itemId,sit.itemName,sit.itemImg') + ->order('gc.isAllowImg desc,gc.catSort asc,gc.catId asc')->select(); + $rs['spec']=[]; + foreach ($specs as $key =>$v){ + $rs['spec'][$v['catId']]['name'] = $v['catName']; + $rs['spec'][$v['catId']]['list'][] = $v; + } + //获取销售规格 + $sales = Db::name('goods_specs')->where('goodsId',$goodsId)->field('id,isDefault,productNo,specIds,marketPrice,specPrice,specStock')->select(); + if(!empty($sales)){ + foreach ($sales as $key =>$v){ + $str = explode(':',$v['specIds']); + sort($str); + unset($v['specIds']); + $rs['saleSpec'][implode(':',$str)] = $v; + } + } + //获取商品属性 + $rs['attrs'] = Db::name('attributes')->alias('a')->join('goods_attributes ga','a.attrId=ga.attrId','inner') + ->where(['a.isShow'=>1,'dataFlag'=>1,'goodsId'=>$goodsId])->field('a.attrName,ga.attrVal') + ->order('attrSort asc')->select(); + //获取商品评分 + $rs['scores'] = Db::name('goods_scores')->where('goodsId',$goodsId)->field('totalScore,totalUsers')->find(); + $rs['scores']['totalScores'] = ($rs['scores']['totalScore']==0)?5:WSTScore($rs['scores']['totalScore'],$rs['scores']['totalUsers'],5,0,3); + WSTUnset($rs, 'totalUsers'); + //关注 + $f = model('Favorites'); + $rs['favShop'] = $f->checkFavorite($rs['shopId'],1); + $rs['favGood'] = $f->checkFavorite($goodsId,0); + } + return $rs; + } + + + public function historyQuery(){ + $ids = cookie("wx_history_goods"); + if(empty($ids))return []; + $where = []; + $where['isSale'] = 1; + $where['goodsStatus'] = 1; + $where['dataFlag'] = 1; + $where['goodsId'] = ['in',$ids]; + $orderBy = "field(`goodsId`,".implode(',',$ids).")"; + return Db::name('goods') + ->where($where)->field('goodsId,goodsName,goodsImg,saleNum,shopPrice') + ->order($orderBy) + ->paginate((int)input('pagesize'))->toArray(); + } +} diff --git a/hyhproject/wechat2/model/GoodsAppraises.php b/hyhproject/wechat2/model/GoodsAppraises.php new file mode 100755 index 0000000..3500ea1 --- /dev/null +++ b/hyhproject/wechat2/model/GoodsAppraises.php @@ -0,0 +1,26 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\GoodsAppraises as CGoodsAppraises; +use think\Db; +/** + * ============================================================================ + * 评价类 + */ +class GoodsAppraises extends CGoodsAppraises{ + /** + * 获取评论 + */ + public function getAppr(){ + $oId = (int)input('oId'); + $uId = (int)session('WST_USER.userId'); + $gId = (int)input('gId'); + $specId = (int)input('sId'); + $orderGoodsId = (int)input('orderGoodsId'); + $rs = $this->where(['orderId'=>$oId,'userId'=>$uId,'goodsId'=>$gId,'goodsSpecId'=>$specId,'orderGoodsId'=>$orderGoodsId])->find(); + if($rs!==false){ + $rs = !empty($rs)?$rs:['goodsScore'=>'','timeScore'=>'','serviceScore'=>'','content'=>'']; + return WSTReturn('',1,$rs); + } + return WSTReturn('获取出错',-1); + } +} diff --git a/hyhproject/wechat2/model/GoodsCats.php b/hyhproject/wechat2/model/GoodsCats.php new file mode 100755 index 0000000..2eff9aa --- /dev/null +++ b/hyhproject/wechat2/model/GoodsCats.php @@ -0,0 +1,74 @@ +<?php +namespace wstmart\wechat\model; +use think\Cache; +/** + * ============================================================================ + * 商品分类类 + */ +class GoodsCats extends Base{ + /** + * 列表 + */ + public function getGoodsCats(){ + $list = cache('WST_CACHE_GOODS_CAT_MOB'); + if(!$list){ + //查询一级分类 + $trs1s = $this->where(["dataFlag"=>1,"isShow"=>1,"parentId"=>0])->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs1 = array(); + $list = array(); + $rs2 = array(); + $maprs = array(); + $ids = array(); + foreach ($trs1s as $key =>$v){ + $trs1[$key]['catId'] = $v['catId']; + $trs1[$key]['parentId'] = $v['parentId']; + $trs1[$key]['catName'] = $v['catName']; + $ids[] = $v['catId']; + } + $ids[] = -1; + //查询二级分类 + $trs2s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName')->order('catSort asc')->select(); + $trs2 = array(); + $ids = array(); + foreach ($trs2s as $key =>$v){ + $trs2[$key]['catId'] = $v['catId']; + $trs2[$key]['parentId'] = $v['parentId']; + $trs2[$key]['catName'] = $v['catName']; + } + foreach ($trs2 as $v2){ + $ids[] = $v2['catId']; + $maprs[$v2['parentId']][] = $v2; + } + $ids[] = -1; + //查询三级分类 + $trs3s = $this->where("dataFlag=1 and isShow=1 and parentId in(".implode(',',$ids).")")->field('catId,parentId,catName,catImg')->order('catSort asc')->select(); + $trs3 = array(); + $ids = array(); + foreach ($trs3s as $key =>$v){ + $trs3[$key]['catId'] = $v['catId']; + $trs3[$key]['parentId'] = $v['parentId']; + $trs3[$key]['catName'] = $v['catName']; + $trs3[$key]['catImg'] = strval($v['catImg']); + } + foreach ($trs3 as $v2){ + $maprs[$v2['parentId']][] = $v2; + } + //倒序建立樹形 + foreach ($trs2 as $v2){ + $v2['childList'] = []; + if(isset($maprs[$v2['catId']]))$v2['childList'] = $maprs[$v2['catId']]; + $rs2[] = $v2; + } + foreach ($trs1 as $v2){ + foreach ($rs2 as $vv2){ + if($vv2['parentId']==$v2['catId']){ + $v2['childList'][] = $vv2; + } + } + $list[] = $v2; + } + Cache::set('WST_CACHE_GOODS_CAT_MOB',$list); + } + return $list; + } +} diff --git a/hyhproject/wechat2/model/Index.php b/hyhproject/wechat2/model/Index.php new file mode 100755 index 0000000..f501b0f --- /dev/null +++ b/hyhproject/wechat2/model/Index.php @@ -0,0 +1,67 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Tags as T; +use think\Db; +/** + * ============================================================================ + * 默认类 + */ +class Index extends Base{ + /** + * 楼层 + */ + public function pageQuery(){ + $limit = (int)input('post.currPage'); + if($limit>9)return; + $cacheData = cache('WX_CATS_ADS'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('goods_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'isFloor'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select(); + if($rs){ + $rs= $rs[0]; + $t = new T(); + $rs['ads'] = $t->listAds('wx-ads-'.$limit,'1'); + $rs['goods'] = Db::name('goods')->alias('g')->join('__RECOMMENDS__ r','g.goodsId=r.dataId')->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where(['r.goodsCatId'=>$rs['catId'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'r.dataSrc'=>0,'r.dataType'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,gs.totalScore,gs.totalUsers')->order('r.dataSort asc')->limit(8)->select(); + if(empty($rs['goods'])){ + $rs['goods'] = Db::name('goods')->alias('g')->join('__GOODS_SCORES__ gs','gs.goodsId=g.goodsId') + ->where(['g.goodsCatIdPath'=>['like',$rs['catId'].'_%'],'g.isSale'=>1,'g.dataFlag'=>1,'g.goodsStatus'=>1,'g.isHot'=>1]) + ->field('g.goodsId,g.goodsName,g.goodsImg,g.shopPrice,g.marketPrice,g.saleNum,gs.totalScore,gs.totalUsers') + ->order('saleNum desc,goodsId asc')->limit(8)->select(); + } + if($rs['goods']){ + foreach ($rs['goods'] as $key =>$v){ + $rs['goods'][$key]['praiseRate'] = ($v['totalScore']>0)?(sprintf("%.2f",$v['totalScore']/($v['totalUsers']*15))*100).'%':'100%'; + } + } + $rs['currPage'] = $limit; + } + cache('WX_CATS_ADS'.$limit,$rs,86400); + return $rs; + } + /** + * 获取系统消息 + */ + function getSysMsg($msg='',$order='',$follow='',$history=''){ + $data = []; + $userId = (int)session('WST_USER.userId'); + if($msg!=''){ + $data['message']['num'] = Db::name('messages')->where(['receiveUserId'=>$userId,'msgStatus'=>0,'dataFlag'=>1])->count(); + } + if($order!=''){ + $data['order']['waitPay'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>-2,'dataFlag'=>1])->count(); + $data['order']['waitSend'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>0,'dataFlag'=>1])->count(); + $data['order']['waitReceive'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>1,'dataFlag'=>1])->count(); + $data['order']['waitAppraise'] = Db::name('orders')->where(['userId'=>$userId,'orderStatus'=>2,'isAppraise'=>0,'dataFlag'=>1])->count(); + } + if($follow!=''){ + $data['follow']['goods'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>0])->count(); + $data['follow']['shops'] = Db::name('favorites')->where(['userId'=>$userId,'favoriteType'=>1])->count(); + } + if($history!=''){ + $history = cookie("wx_history_goods"); + $data['history']['num'] = count($history); + } + return $data; + } +} diff --git a/hyhproject/wechat2/model/Orders.php b/hyhproject/wechat2/model/Orders.php new file mode 100755 index 0000000..2f8f19c --- /dev/null +++ b/hyhproject/wechat2/model/Orders.php @@ -0,0 +1,10 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Orders as COrders; +use think\Db; +/** + * ============================================================================ + * 订单类 + */ +class Orders extends COrders{ +} diff --git a/hyhproject/wechat2/model/Payments.php b/hyhproject/wechat2/model/Payments.php new file mode 100755 index 0000000..cb9c6b2 --- /dev/null +++ b/hyhproject/wechat2/model/Payments.php @@ -0,0 +1,9 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Payments as CPayments; +/** + * ============================================================================ + * 支付管理业务处理 + */ +class Payments extends CPayments{ +} diff --git a/hyhproject/wechat2/model/Shops.php b/hyhproject/wechat2/model/Shops.php new file mode 100755 index 0000000..f3b9798 --- /dev/null +++ b/hyhproject/wechat2/model/Shops.php @@ -0,0 +1,134 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Shops as CShops; +use think\Db; +/** + * ============================================================================ + * 门店类 + */ +class Shops extends CShops{ + /** + * 店铺街列表 + */ + public function pageQuery($pagesize){ + $catId = (int)input("id"); + $keyword = input("keyword"); + $condition = input("condition"); + $desc = input("desc"); + $datas = array('sort'=>array('1'=>'ss.totalScore/ss.totalUsers'),'desc'=>array('desc','asc')); + $rs = $this->alias('s'); + $where = []; + $where['s.dataFlag'] = 1; + $where['s.shopStatus'] = 1; + $where['s.applyStatus'] = 2; + if($keyword!='')$where['s.shopName'] = ['like','%'.$keyword.'%']; + if($catId>0){ + $rs->join('__CAT_SHOPS__ cs','cs.shopId = s.shopId','left'); + $where['cs.catId'] = $catId; + } + $order = ['s.shopId'=>'asc']; + if($condition>0){ + $order = [$datas['sort'][$condition]=>$datas['desc'][$desc]]; + } + $page = $rs->join('__SHOP_SCORES__ ss','ss.shopId = s.shopId','left') + ->where($where)->order($order) + ->field('s.shopId,s.shopImg,s.shopName,s.shopCompany,ss.totalScore,ss.totalUsers,ss.goodsScore,ss.goodsUsers,ss.serviceScore,ss.serviceUsers,ss.timeScore,ss.timeUsers,s.areaIdPath') + ->paginate($pagesize)->toArray(); + foreach ($page['Rows'] as $key =>$v){ + //商品列表 + $goods = db('goods')->where(['dataFlag'=> 1,'isSale'=>1,'goodsStatus'=> 1,'shopId'=> $v["shopId"]])->field('goodsId,goodsName,shopPrice,goodsImg') + ->order('saleTime desc')->limit(4)->select(); + $page['Rows'][$key]['goods'] = $goods; + } + if(empty($page['Rows']))return $page; + $shopIds = []; + $areaIds = []; + foreach ($page['Rows'] as $key =>$v){ + $shopIds[] = $v['shopId']; + $tmp = explode('_',$v['areaIdPath']); + $areaIds[] = $tmp[1]; + $page['Rows'][$key]['areaId'] = $tmp[1]; + //总评分 + $page['Rows'][$key]['totalScore'] = WSTScore($v["totalScore"]/3, $v["totalUsers"]); + $page['Rows'][$key]['goodsScore'] = WSTScore($v['goodsScore'],$v['goodsUsers']); + $page['Rows'][$key]['serviceScore'] = WSTScore($v['serviceScore'],$v['serviceUsers']); + $page['Rows'][$key]['timeScore'] = WSTScore($v['timeScore'],$v['timeUsers']); + } + $rccredMap = []; + $goodsCatMap = []; + $areaMap = []; + //认证、地址、分类 + if(!empty($shopIds)){ + $rccreds = Db::name('shop_accreds')->alias('sac')->join('__ACCREDS__ a','a.accredId=sac.accredId and a.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('sac.shopId,accredName,accredImg')->select(); + foreach ($rccreds as $v){ + $rccredMap[$v['shopId']][] = $v; + } + $goodsCats = Db::name('cat_shops')->alias('cs')->join('__GOODS_CATS__ gc','cs.catId=gc.catId and gc.dataFlag=1','left') + ->where('shopId','in',$shopIds)->field('cs.shopId,gc.catName')->select(); + foreach ($goodsCats as $v){ + $goodsCatMap[$v['shopId']][] = $v['catName']; + } + $areas = Db::name('areas')->alias('a')->join('__AREAS__ a1','a1.areaId=a.parentId','left') + ->where('a.areaId','in',$areaIds)->field('a.areaId,a.areaName areaName2,a1.areaName areaName1')->select(); + foreach ($areas as $v){ + $areaMap[$v['areaId']] = $v; + } + } + foreach ($page['Rows'] as $key =>$v){ + $page['Rows'][$key]['accreds'] = (isset($rccredMap[$v['shopId']]))?$rccredMap[$v['shopId']]:[]; + $page['Rows'][$key]['catshops'] = (isset($goodsCatMap[$v['shopId']]))?implode(',',$goodsCatMap[$v['shopId']]):''; + $page['Rows'][$key]['areas']['areaName1'] = (isset($areaMap[$v['areaId']]['areaName1']))?$areaMap[$v['areaId']]['areaName1']:''; + $page['Rows'][$key]['areas']['areaName2'] = (isset($areaMap[$v['areaId']]['areaName2']))?$areaMap[$v['areaId']]['areaName2']:''; + } + return $page; + } + /** + * 获取卖家中心信息 + */ + public function getShopSummary(){ + $shopId = (int)input('shopId',1); + $shop = $this->alias('s')->join('__SHOP_SCORES__ cs','cs.shopId = s.shopId','left')->join('__SHOP_CONFIGS__ sc','sc.shopId = s.shopId','left') + ->where(['s.shopId'=>$shopId,'dataFlag'=>1]) + ->field('s.shopId,shopImg,shopName,shopkeeper,shopAddress,shopQQ,shopTel,serviceStartTime,serviceEndTime,isInvoice,invoiceRemarks,cs.*,sc.shopBanner') + ->find(); + //评分 + $scores['totalScore'] = WSTScore($shop['totalScore'],$shop['totalUsers']); + $scores['goodsScore'] = WSTScore($shop['goodsScore'],$shop['goodsUsers']); + $scores['serviceScore'] = WSTScore($shop['serviceScore'],$shop['serviceUsers']); + $scores['timeScore'] = WSTScore($shop['timeScore'],$shop['timeUsers']); + WSTUnset($shop, 'totalUsers,goodsUsers,serviceUsers,timeUsers'); + $shop['scores'] = $scores; + //认证 + $accreds = $this->shopAccreds($shopId); + $shop['accreds'] = $accreds; + return ['shop'=>$shop]; + } + /** + * 自营店铺楼层 + */ + public function getFloorData(){ + $limit = (int)input('post.currPage'); + $cacheData = cache('WX_SHOP_FLOOR'.$limit); + if($cacheData)return $cacheData; + $rs = Db::name('shop_cats')->where(['dataFlag'=>1,'isShow'=>1,'parentId'=>0,'shopId'=>1])->field('catId,catName')->order('catSort asc')->limit($limit,1)->select(); + if($rs){ + $rs= $rs[0]; + $goods = Db::name('goods')->where('shopCatId1','=',$rs['catId'])->where(['dataFlag'=>1,'goodsStatus'=>1])->field('goodsId,goodsName,goodsImg,shopPrice,marketPrice,saleNum')->order('isHot desc')->limit(4)->select(); + $rs['goods'] = $goods; + $rs['currPage'] = $limit; + } + cache('WX_SHOP_FLOOR'.$limit,$rs,86400); + return $rs; + } + /** + * 根据订单id 获取店铺名称 + */ + public function getShopName($oId){ + return $this->alias('s') + ->join('__ORDERS__ o',"s.shopId=o.shopId",'inner') + ->where("o.orderId=$oId") + ->value('s.shopName'); + + } +} diff --git a/hyhproject/wechat2/model/Users.php b/hyhproject/wechat2/model/Users.php new file mode 100755 index 0000000..b2bf7b7 --- /dev/null +++ b/hyhproject/wechat2/model/Users.php @@ -0,0 +1,64 @@ +<?php +namespace wstmart\wechat\model; +use wstmart\common\model\Users as CUsers; +use Think\Db; +/** + * ============================================================================ + * 用户类 + */ +class Users extends CUsers{ + /** + * 用户自动登录 + */ + public function accordLogin(){ + $wxOpenId = session('WST_WX_OPENID'); + $rs = $this->where(["dataFlag"=>1, "userStatus"=>1,"wxOpenId"=>$wxOpenId])->order('lastTime desc')->find(); + if(!empty($rs)){ + $userId = $rs['userId']; + //获取用户等级 + $rrs = WSTUserRank($rs['userTotalScore']); + $rs['rankId'] = $rrs['rankId']; + $rs['rankName'] = $rrs['rankName']; + $rs['userrankImg'] = $rrs['userrankImg']; + $rs['wxOpenId'] = session('WST_WX_OPENID'); + $ip = request()->ip(); + $update = []; + $update = ["lastTime"=>date('Y-m-d H:i:s'),"lastIP"=>$ip]; + $update['wxOpenId'] = session('WST_WX_OPENID'); + $this->where(["userId"=>$userId])->update($update); + //如果是店铺则加载店铺信息 + if($rs['userType']>=1){ + $shop = model('shops')->where(["userId"=>$userId,"dataFlag" =>1])->find(); + if(!empty($shop))$rs = array_merge($shop->toArray(),$rs->toArray()); + } + //记录登录日志 + $data = array(); + $data["userId"] = $userId; + $data["loginTime"] = date('Y-m-d H:i:s'); + $data["loginIp"] = $ip; + $data['loginSrc'] = 1; + Db::name('log_user_logins')->insert($data); + session('WST_USER',$rs); + return WSTReturn("","1"); + } + return WSTReturn("用户不存在"); + } + /** + * 验证用户支付密码 + */ + function checkPayPwd(){ + $payPwd = input('payPwd'); + $decrypt_data = WSTRSA($payPwd); + if($decrypt_data['status']==1){ + $payPwd = $decrypt_data['data']; + }else{ + return WSTReturn('验证失败'); + } + $userId = (int)session('WST_USER.userId'); + $rs = $this->field('payPwd,loginSecret')->find($userId); + if($rs['payPwd']==md5($payPwd.$rs['loginSecret'])){ + return WSTReturn('',1); + } + return WSTReturn('支付密码错误',-1); + } +} diff --git a/hyhproject/wechat2/validate/UserAddress.php b/hyhproject/wechat2/validate/UserAddress.php new file mode 100755 index 0000000..64bd300 --- /dev/null +++ b/hyhproject/wechat2/validate/UserAddress.php @@ -0,0 +1,24 @@ +<?php +namespace wstmart\wechat\validate; +use think\Validate; +/** + * ============================================================================ + * WSTMart开源商城 + * 官网地址:http://www.wstmall.com + * 联系QQ:707563272 + * ============================================================================ + * 用户地址验证器 + */ +class UserAddress extends Validate{ + protected $rule = [ + ['userName' ,'require','请输入联系名称'], + ['userPhone' ,'require','请输入手机号码'], + ['areaId' ,'require','请选择完整地址'], + ['userAddress' ,'require','请输入详细地址'] + ]; + + protected $scene = [ + 'add' => ['userName','userPhone','areaId','userAddress'], + 'edit' => ['userName','userPhone','areaId','userAddress'] + ]; +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/articles/news_list.html b/hyhproject/wechat2/view/default/articles/news_list.html new file mode 100755 index 0000000..02adc27 --- /dev/null +++ b/hyhproject/wechat2/view/default/articles/news_list.html @@ -0,0 +1,166 @@ +{extend name="default/base" /} +{block name="title"}商城快讯 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/articles.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>商城快讯</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<input type="hidden" name="" value="{$catId}" id="catId" autocomplete="off"> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + {volist name="catInfo" id="vo"} + <li class="tab-item {if $catId==$vo.catId}tab-curr{/if}" catId="{$vo['catId']}">{$vo['catName']}</li> + {/volist} + </ul> + </div> + + <section class="ui-container" id="newsListBox"> + + </section> + + <div style="height:50px;"></div> + </section> + + <script id="newsList" type="text/html"> + {{# for(var i=0;i<d.length;i++){ }} + {{# if(d[i].TypeStatus==1){ }} + <div class="news-item wst-model" onclick="viewNews({{d[i].articleId}})" > + <div class="ui-row-flex"> + <div class="ui-col"> + <div class="img j-imgAdapt wst-bor-mix-img" > + <a href="javascript:void(0);" > + {{# if(d[i].coverImg) { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{WST.replaceImg(d[i].coverImg,'_m')}}"> + {{# } else { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" > + {{# } }} + </a> + </div> + </div> + <div class="ui-col ui-col-3" > + <div class="ui-row-flex ui-row-flex-ver wst-info" > + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;">{{d[i].articleTitle}}</div> + <div class="ui-nowrap-multi wst-mix-cont">{{d[i].articleContent}}</div> + </div> + </div> + </div> + <div class="ui-row-flex ui-whitespace wst-model wst-mix-info "> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-end wst-right-align">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + {{# if(d[i].TypeStatus==2){ }} + <div class="news-item wst-model" onclick="viewNews({{d[i].articleId}})"> + <div class="ui-row-flex"> + <div class="ui-col ui-col-3"> + <div class="ui-row-flex ui-row-flex-ver wst-info" > + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;">{{d[i].articleTitle}}{{d[i].TypeStatus}}</div> + <div class="ui-nowrap-multi wst-mix-cont">{{d[i].articleContent}}</div> + </div> + </div> + <div class="ui-col"> + <div class="img j-imgAdapt wst-bor-mix-img"> + <a href="javascript:void(0);" > + {{# if(d[i].coverImg) { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{WST.replaceImg(d[i].coverImg,'_m')}}"> + {{# } else { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}"> + {{# } }} + </a> + </div> + </div> + </div> + <div class="ui-row-flex ui-whitespace wst-model wst-mix-info "> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col ui-flex-pack-center ui-flex-align-end wst-right-align">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + {{# if(d[i].TypeStatus==3){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver wst-model" style="height:auto;overflow:hidden;" onclick="viewNews({{d[i].articleId}})"> + <div class="wst-max-info"> + <div class="ui-nowrap-multi" style="-webkit-line-clamp: 1;" style="-webkit-line-clamp: 1;">{{d[i].articleTitle}}</div> + </div> + <div class="wst-max-info"> + <div class="ui-nowrap-multi wst-mix-cont" style="-webkit-line-clamp: 1;padding-top: 0px;" >{{d[i].articleContent}}</div> + </div> + <div class="max-img"> + <a href="javascript:void(0);"> + {{# if(d[i].coverImg) { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{WST.replaceImg(d[i].coverImg,'_m')}}"> + {{# } else { }} + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}"> + {{# } }} + </a> + </div> + <div class="max-remind wst-mix-info ui-row"> + <div class="ui-col ui-col-50 ui-flex ui-flex-ver ui-flex-pack-center ui-flex-align-start">• 已有{{d[i].visitorNum}}人浏览</div> + <div class="ui-col ui-col-50 ui-flex ui-flex-ver ui-flex-pack-center ui-flex-align-end">• {{d[i].createTime}}</div> + </div> + </div> + {{# } }} + {{# } }} + </script> + </div> + + + + +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>商城快讯</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + <div class="ui-whitespace news-content-box"> + <div class="ui-nowrap ui-whitespace news-title" id="articleTitle"></div> + <div class="ui-whitespace news-time" id="createTime"></div> + <div class="ui-whitespace view-content" id="articleContent"> + + </div> + </div> + <div class="wst-like ui-whitespace ui-flex ui-flex-pack-center" id="like1" onclick="javascript:like();"> + <input type="hidden" name="" id="articleId" value="" > + <span class="icon-like1"><p class="like_num" id="likeNum"></p></span> + </div> + <div class="wst-like ui-whitespace ui-flex ui-flex-pack-center" id="like" > + <input type="hidden" name="" id="articleId" value="" > + <span class="icon-like2"><p class="like_num" id="likeNum2"></p></span> + </div> + + </div> +</div> + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script> +$(function(){ + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var catId = $(this).attr('catId'); + $('#catId').val(catId); + reFlashList(); + }); + {{if !empty($articleId) }} + viewNews({$articleId}) + {{/if}} +}) +</script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/articles/news_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/articles/news_list.js b/hyhproject/wechat2/view/default/articles/news_list.js new file mode 100755 index 0000000..307b65c --- /dev/null +++ b/hyhproject/wechat2/view/default/articles/news_list.js @@ -0,0 +1,116 @@ +// 获取商城快讯 +function getNewList($catId = ''){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + param.catId = $('#catId').val(); + $.post(WST.U('wechat/news/getNewsList'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('newsList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#newsListBox').append(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<ul class="ui-row-flex wst-flexslp">'; + html += '<li class="ui-col ui-flex ui-flex-pack-center" style="margin-top:150px;">'; + html += '<p>暂无商城快讯</p>'; + html += '</li>'; + html += '</ul>'; + $('#newsListBox').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter(); + getNewList(); + + + + var dataHeight = $("#frame").css('height'); + $("#frame").css('top',0); + var dataWidth = $("#frame").css('width'); + $("#frame").css('right','-'+dataWidth); + + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getNewList(); + } + } + }); +}); +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#newsListBox').html(' '); + getNewList(); +} + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function viewNews(id){ + $.post(WST.U('wechat/news/getNews'),{id:id},function(data){ + var json = WST.toJson(data); + $('#createTime').html(json.createTime); + $('#articleTitle').html(json.articleTitle); + $('#articleContent').html(json.articleContent); + $('#likeNum').html(json.likeNum); + $('#articleId').val(json.articleId); + // 计算弹出层是否需要滚动条 + var sHeight = WST.pageHeight(); + var tHeight = $('#articleTitle').height(); + var cHeight = $('#articleContent').height(); + $('#content').css('height',sHeight-tHeight+'px'); + if(json.likeState == 1){ + $('#like1').hide(); + $('#like').show(); + $('#likeNum2').html(json.likeNum); + $(".icon-like1").removeClass('icon-like1').addClass('icon-like2'); + }else{ + $('#like').hide(); + $('#like1').show(); + $(".icon-like2").removeClass('icon-like2').addClass('icon-like1'); + } + dataShow(); + }) +} +function like(){ + var articleId = $('#articleId').val(); + $.post(WST.U('wechat/News/like'),{id:articleId},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $(".icon-like1").removeClass('icon-like1').addClass('icon-like2'); + $num = parseInt($('#likeNum').html()); + $num = $num+1; + $('#like1').hide(); + $('#like').show(); + $('#likeNum2').html($num); + } + }) +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/base.html b/hyhproject/wechat2/view/default/base.html new file mode 100755 index 0000000..5655098 --- /dev/null +++ b/hyhproject/wechat2/view/default/base.html @@ -0,0 +1,28 @@ +<html> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> +<meta name="format-detection" content="telephone=no"> +<title>{block name="title"}{:WSTConf('CONF.mallName')}{/block}</title> +<link rel="stylesheet" href="__WECHAT__/frozenui/css/frozen.css"> +<link rel="stylesheet" href="__WECHAT__/css/common.css?v={$v}"> +{block name="css"}{/block} +<script type='text/javascript' src='__WECHAT__/frozenui/js/zepto.min.js'></script> +<script type='text/javascript' src='__WECHAT__/frozenui/js/frozen.js'></script> +<script type='text/javascript' src='__WECHAT__/js/laytpl/laytpl.js?v={$v}'></script> +<script src="__WECHAT__/js/echo.min.js"></script> +<script type='text/javascript' src='__WECHAT__/js/common.js?v={$v}'></script> +<script> +window.conf = {"ROOT":"__ROOT__","IMGURL":"__IMGURL__","WECHAT":"__WECHAT__","TRANSFOR":true,"APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"{:config('url_html_suffix')}","SMS_VERFY" : "{:WSTConf('CONF.smsVerfy')}","SMS_OPEN" : "{:WSTConf('CONF.smsOpen')}","MALL_LOGO" : "{:WSTConf('CONF.mallLogo')}","GOODS_LOGO" : "{:WSTConf('CONF.goodsLogo')}","SHOP_LOGO" : "{:WSTConf('CONF.shopLogo')}","USER_LOGO" : "{:WSTConf('CONF.userLogo')}","IS_LOGIN" : "{if (int)session('WST_USER.userId')>0 }1{else}0{/if}","wxAppId" : "{:WSTConf('CONF.wxAppId')}","wxAppCode" : "{:WSTConf('CONF.wxAppCode')}","IS_CRYPTPWD":"{:WSTConf('CONF.isCryptPwd')}"} +</script> +</head> +<body ontouchstart=""> +{block name="header"}{/block} +{block name="footer"} + {include file="default/footer" /} +{/block} +{block name="main"}主内容{/block} +{block name="include"}{/block} +{block name="js"}{/block} +</body> +</html> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/brands.html b/hyhproject/wechat2/view/default/brands.html new file mode 100755 index 0000000..63c7f7d --- /dev/null +++ b/hyhproject/wechat2/view/default/brands.html @@ -0,0 +1,34 @@ +{extend name="default/base" /} +{block name="title"}品牌街 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/shops_list.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "品牌街"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <ul class="" id="info-list"></ul> + <div class="wst-clear"></div> + </section> +<script id="list" type="text/html"> +{{# for(var i=0; i<d.length; i++){ }} + <li class="wst-brands {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}"> + <div class="wst-brands_img"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({{ d[i].brandId }});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d[i].brandImg }}" title="{{ d[i].brandName }}"> + </a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({{ d[i].brandId }});"> + <span class="ui-nowrap-flex">{{ d[i].brandName }}</span> + </a> + </div> + </li> +{{# } }} +</script> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/brands.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/carts.html b/hyhproject/wechat2/view/default/carts.html new file mode 100755 index 0000000..b002b1c --- /dev/null +++ b/hyhproject/wechat2/view/default/carts.html @@ -0,0 +1,105 @@ +{extend name="default/base" /} +{block name="title"}购物车 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/carts.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <a href="{:url('wechat/index/index')}"><i class="ui-icon-return"></i></a><h1>购物车</h1> + {if(count($carts['carts'])>0)} + <span id="edit" class="edit" onclick="javascript:edit(0);">编辑</span><span id="complete" class="edit" onclick="javascript:edit(1);" style="display: none;">完成</span> + <div class="wst-ca-more" onclick="javascript:inMore();">···</div> + {/if} + </header> + <div class="wst-go-more" id="arrow" style="display: none;"><i class="arrow"></i> + <ul class="ui-row ui-list-active more"> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/index/index')}"><i class="home"></i><p>首页</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/goodscats/index')}"><i class="category"></i><p>分类</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/favorites/goods')}"><i class="follow"></i><p>关注</p></a></div></li> + <li class="ui-col"><div class="column"><a href="{:url('wechat/users/index')}"><i class="user"></i><p>我的</p></a></div></li> + </ul> + </div> + <div class="wst-ca-layer" id="layer" onclick="javascript:inMore();"></div> +{/block} +{block name="footer"} +{if(count($carts['carts'])>0)} + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-ca-se"> + <div class="wst-ca-layout"> + <div class="wst-ca-10 totall"><i class="ui-icon-choose ui-icon-unchecked-s" cartId="0" mval="0"></i>&nbsp;</div> + <div class="wst-ca-90 totalr"> + <span>全选</span> + <button id="settlement" class="button" type="button" onclick="javascript:toSettlement();">结算</button> + <button id="delete" class="button" type="button" onclick="javascript:deletes();" style="display: none;">删除</button> + <span id="total" class="total">合计:<span id="totalMoney" class="price"><span>¥ </span>{php}echo sprintf("%.2f", $carts['goodsTotalMoney']);{/php}</span></span> + </div> + </div> + </div> + </footer> +{else} +{include file="default/footer" /} +{/if} +{/block} +{block name="main"} + <section class="ui-container"> + {if(count($carts['carts'])>0)} + <input type="hidden" name="" value="0" id="buyNum_0" autocomplete="off"> + <input type="hidden" name="" value="{php}echo count($carts['carts'])+1;{/php}" id="totalshop" autocomplete="off"> + {volist name="$carts['carts']" id="ca" key="k"} + <div class="wst-ca-s"> + <div class="wst-ca-layout shop"> + <div class="wst-ca-10 shopl"><i class="ui-icon-chooses ui-icon-unchecked-s" childrenId="clist{$k}" cartId="0" mval="0"></i>&nbsp;</div> + <div class="wst-ca-90 shopr"><p class="ui-nowrap" onclick="javascript:WST.intoShops({$ca['shopId']});"><i class="shopicon"></i>{$ca['shopName']}</p></div> + </div> + {volist name="ca['list']" id="li"} + {:hook('wechatDocumentCartGoodsPromotion',['goods'=>$li])} + <div class="wst-ca-layout goods{if($li['goodsStock']==0)} nogoods{/if} j-g{$li["cartId"]}"> + <div class="wst-ca-10 goodsl"> + <i id="gchk_{$li["cartId"]}" class="ui-icon-chooseg {if($li['isCheck'])}ui-icon-success-block wst-active{else}ui-icon-unchecked-s{/if} clist{$k}" cartId="{$li['cartId']}" mval="{$li['shopPrice']}"></i>&nbsp;</div> + <div class="wst-ca-90"> + <div class="wst-ca-24 goodsr"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </div> + <div class="wst-ca-76"> + <div class="info"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"><p class="name">{$li['goodsName']}</p></a><p class="price">¥ {$li['shopPrice']}</p> + {if($li['specNames'])} + <p class="spec">规格: + {volist name="li['specNames']" id="sp"} + {$sp['catName']}:{$sp['itemName']} + {/volist} + </p> + {/if} +<div class="wst-buy_l"> + <input class="wst-buy_l1" type="button" value="-" onclick='javascript:WST.changeIptNum(-1,"#buyNum",{$li["cartId"]},"statCartMoney")'><input id="buyNum_{$li['cartId']}" class="wst-buy_l2" data-min='1' data-max='{$li["goodsStock"]}' type="number" value="{$li['cartNum']}" autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum",{$li["cartId"]},"statCartMoney")'><input class="wst-buy_l3" type="button" value="+" onclick='javascript:WST.changeIptNum(1,"#buyNum",{$li["cartId"]},"statCartMoney")'> +</div> + </div> + </div> + </div> + <span id="noprompt{$li['cartId']}" class="noprompt" style="display: none;"></span> + </div> + {/volist} + <div class="wst-ca-layout bottom"> + <p class="wst-ca-50">共 {php}echo count($ca['list']);{/php} 件商品</p><p id="tprice_{$k}" class="wst-ca-50 price"><span>¥ </span>{php}echo sprintf("%.2f", $ca['goodsMoney']);{/php}</p> + </div> + </div> + {/volist} + {else} + <div class="wst-prompt-icon" style="width: 1rem;height: 1rem;"><img src="__WECHAT__/img/nothing-cart.png" style="width: 1rem;height: 1rem;"></div> + <div class="wst-prompt-info"> + <p>购物车内还没商品哦,去逛逛吧~</p> + <button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button> + </div> + {/if} + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/carts.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/address.css b/hyhproject/wechat2/view/default/css/address.css new file mode 100755 index 0000000..74b012f --- /dev/null +++ b/hyhproject/wechat2/view/default/css/address.css @@ -0,0 +1,55 @@ +@CHARSET "UTF-8"; +.wst-listse{margin-top:8px;font-size:.15rem} +.wst-list-infose1{width:96%;padding-top:10px;padding-bottom:10px;border-bottom:1px solid #ededed} +.wst-list-infose1 span{float:left;width:100%} +.wst-list-infose1 .name{color:#232228} +.wst-list-infose1 .address{color:#808080} +.wst-ad-operate{padding:10px;height:0.22rem;line-height:0.25rem;font-size:.14rem} +.wst-ad-operate .left{float:left;margin-left:22px} +.wst-ad-operate .right{float:right} +.wst-ad-operate i{float:left;width:22px;height:22px} +.j-operate{z-index:100;float:left;width:22px;height:22px;margin:-32px 0 0 9px} +.j-operate.default,.ui-form-itemin .operate .default{background:url(../img/icon_adds_users.png) -11px -5px no-repeat;background-size:645%} +.j-operate.nodefault,.ui-form-itemin .operate .nodefault{background:url(../img/icon_adds_users.png) -41px -5px no-repeat;background-size:645%} +.wst-ad-operate .edit{background:url(../img/icon_adds_users.png) -71px -5px no-repeat;background-size:631%} +.wst-ad-operate .delete{background:url(../img/icon_adds_users.png) -106px -5px no-repeat;background-size:631%} +.wst-ad-form{margin-top:8px} +.ui-form-itemin{position:relative;font-size:16px;height:44px;line-height:44px;padding:1px 10px;font-size:.18rem;background:#fff} +.ui-form-itemin .word{color:#232228;font-size:.15rem} +.ui-form-itemin input{float:right;width:75%;height:35px;border:0;margin-top:4px;font-size:.15rem} +.ui-form-itemin label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio){position:absolute;text-align:left;box-sizing:border-box} +.ui-form-itemin .address{float:right;width:75%;height:35px;line-height:35px;margin-top:4px;font-size:.15rem} +.ui-form-itemin .ui-select-group{margin-top:5px} +.wst-selectin{float:left;position:relative;width:72%} +.wst-address_set{width:100%;height:40px;position:fixed;z-index:100;left:0;bottom:0} +.wst-ad-line{padding:0 10px} +.wst-ad-line p{border-bottom:1px solid #edebeb} +.wst-ad-submit{margin-top:20px} +.wst-ad-submit .button{margin:0 auto;width:93%;font-size:.15rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-ad-submit .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-ad-operate{font-size:.15rem} +.ui-switch input:checked:before{border-color: #ff3c3c;box-shadow: #ff3c3c 0px 0px 0px 16px inset;background-color: #ff3c3c;background-color: #ff3c3c;} +.ui-switch input:before{height: 26px;} +.ui-switch input:checked:after {left: 26px;} +.ui-switch input:after {width: 26px;height: 26px;} +.ui-switch{margin-top: -14px;} +.iziModal{background:#f6f6f8} +.iziModal-button-close i{font-size: 22px;line-height:41px;} +.iziModal .iziModal-header-title{font-size: 16px;height:22px;line-height:22px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;left:0;bottom:-285px;width:100%;min-height:50%;background:#fff;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1;} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:10px 10px 20px 10px} +.wst-fr-box .option{float:left;width:100%;border-bottom:1px solid #edebeb} +.wst-fr-box .option p{float:left;width:50px;height:26px;line-height:26px;padding:0 5px;text-align:center} +.wst-fr-box .option .active{border-bottom:1px solid #de0301} +.wst-fr-box .list{padding-top:5px;font-size:0.14rem;} +.wst-fr-box .list.hide{display:none} +.wst-fr-box .list p{padding:5px 0} +.wst-fr-box .list .active{color:#de0301} +.wst-fr-box .list .active{color:#de0301} +.wst-ad-footer{position: fixed;z-index: 100;bottom:0;left: 0;width: 100%;height: 44px;background: #FFF;border-top: 1px solid #e8e8e8;} +.wst-ad-footer .button{display: block;margin: 0 auto;margin-top:2px;width: 90%;font-size: .15rem;height: 40px;line-height: 40px;color: #fff;background: #e00102;border-radius: 5px;border-bottom: 1px solid #e00102;} +.wst-ad-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/articles.css b/hyhproject/wechat2/view/default/css/articles.css new file mode 100755 index 0000000..6b989e4 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/articles.css @@ -0,0 +1,46 @@ +@CHARSET "UTF-8"; +body{font-size:.15rem} +.news-time{margin-top:10px;text-align:right;font-size:.13rem;padding-right: 10px;} +.news-content-box{background:#fff;padding: 10px 0 35px 0;} +.news-content{max-height:100px} +.news-title{font-weight:bold;padding: 10px;font-size: 20px;padding-bottom: 0px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background:#f6f6f8;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:16px} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{overflow-y:scroll;background:#fff} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.title{background:#fff} +.view-content{background:#fff} +.news-time{margin:5px 0;padding: 0.05rem 0.1rem;background:#ffffff;} + +.wst-info{padding:0.04rem;font-weight: bold;font-size:16px;color: #051B28;padding-left: 0.06rem;height:55px;} +.wst-max-info{padding:0.04rem;font-weight: bold;font-size: 0.140rem;color: #051B28;padding-left: 0.06rem;} +.wst-mix-info{padding-left: 0.06rem;padding-right: 0.06rem;color: #999;font-size: 10px;} +.max-remind{height: 16px;} +.max-img{position: relative;padding-top: 40%; background-size: 30%;overflow: hidden;margin-bottom: 8px;} +.max-img a img{position: absolute;width: 100%;top: 50%;left: 50%; transform: translate(-50%, -50%);} +.wst-model{background-color: #fff;padding: 0.01rem;margin-top: 10px;} +.wst-right-align{text-align: right;} +.wst-mix-cont{font-size: 13px;color: #999;padding-top: 10px;} + +.view-content img{width: 100%;} +.wst-like{padding-bottom: 50px;position: relative;} +.icon-like1{background: url(../img/icon_like1.png) 5px no-repeat;background-size: 20px 20px;border-radius: 10px; position: absolute;top: 0;left: 0;width: auto;height: 30px;margin-left: 40%;margin-bottom: 20px; border: 1px solid red;} +.icon-like2{background: url(../img/icon_like2.png) 5px no-repeat;background-size: 20px 20px;border-radius: 10px; position: absolute;top: 0;left: 0;width: auto;height: 30px;margin-left: 40%;margin-bottom: 20px; border: 1px solid red;} +.like_num{display: inline-block;padding: 5px;padding-left: 32px;padding-top: 6px; color: #ED0000;} +.wst-bor-mix-img{padding: 0.01rem;padding-bottom: 0;} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.ui-tab{position:fixed;width:100%;z-index:100;left:0;top:41px} +.order-tab{width:100%;height:35px;line-height:35px;padding:0;background:#fff;overflow-x:scroll} +.order-tab::-webkit-scrollbar{width:1px;height:1px;background-color:#fff} +.order-tab::-webkit-scrollbar-thumb{background-color:#fff} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.item-head{font-size: .15rem;padding:10px 0;border-bottom:1px solid #f2f1f1} +.item-head p{padding-left:20px;position: relative;} +.item-head .shopicon{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.ui-tab-nav li.tab-item{font-size:.15rem;height:35px;line-height:35px;padding:0 5px;text-align:center;} +.ui-tab-nav li.tab-curr{color:#de4943;;height:34px;border-bottom:2px solid #de4943;} +.ui-header ~ .ui-container{border-top: 75px solid transparent;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/articles/news_list.html b/hyhproject/wechat2/view/default/css/articles/news_list.html new file mode 100755 index 0000000..4732700 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/articles/news_list.html @@ -0,0 +1,67 @@ +{extend name="default/base" /} +{block name="title"}商城快讯 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/articles.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>商城快讯</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + + <script id="newsList"> + {{# for(var i=0;i<d.length;i++){ }} + <div class="ui-whitespace news-time">{{d[i].createTime}}</div> + <div class="ui-whitespace news-content-box" onclick="viewNews({{d[i].articleId}})"> + <div class="ui-nowrap ui-whitespace news-title">{{d[i].articleTitle}}</div> + <div class="ui-nowrap-multi ui-whitespace news-content"> + {{d[i].articleContent}} + </div> + </div> + {{# } }} + </script> + <section class="ui-container" id="newsListBox"> + + </section> + + + + + +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>商城快讯</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + <div class="ui-whitespace news-time" id="createTime"></div> + <div class="ui-whitespace news-content-box"> + <div class="ui-nowrap ui-whitespace news-title" id="articleTitle"></div> + <div class="ui-whitespace view-content" id="articleContent"> + + </div> + </div> + + </div> +</div> + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script> +$(function(){ + {{if !empty($articleId) }} + viewNews({$articleId}) + {{/if}} +}) +</script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/articles/news_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/articles/news_list.js b/hyhproject/wechat2/view/default/css/articles/news_list.js new file mode 100755 index 0000000..52e8b8f --- /dev/null +++ b/hyhproject/wechat2/view/default/css/articles/news_list.js @@ -0,0 +1,83 @@ +// 获取商城快讯 +function getNewList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/news/getNewsList'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('newsList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#newsListBox').append(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<ul class="ui-row-flex wst-flexslp">'; + html += '<li class="ui-col ui-flex ui-flex-pack-center">'; + html += '<p>暂无商城快讯</p>'; + html += '</li>'; + html += '</ul>'; + $('#newsListBox').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter(); + getNewList(); + + + + var dataHeight = $("#frame").css('height'); + $("#frame").css('top',0); + var dataWidth = $("#frame").css('width'); + $("#frame").css('right','-'+dataWidth); + + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getNewList(); + } + } + }); +}); + + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function viewNews(id){ + $.post(WST.U('wechat/news/getNews'),{id:id},function(data){ + var json = WST.toJson(data); + $('#createTime').html(json.createTime); + $('#articleTitle').html(json.articleTitle); + $('#articleContent').html(json.articleContent); + // 计算弹出层是否需要滚动条 + var sHeight = WST.pageHeight(); + var tHeight = $('#articleTitle').height(); + var cHeight = $('#articleContent').height(); + $('#content').css('height',sHeight-tHeight+'px'); + dataShow(); + }) +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/carts.css b/hyhproject/wechat2/view/default/css/carts.css new file mode 100755 index 0000000..aa8cf0a --- /dev/null +++ b/hyhproject/wechat2/view/default/css/carts.css @@ -0,0 +1,60 @@ +@CHARSET "UTF-8"; +.wst-ca-layout{display:block;overflow:hidden} +.wst-ca-10{float:left;width:10%;box-sizing:border-box} +.wst-ca-90{float:left;width:90%;box-sizing:border-box} +.wst-ca-24{float:left;width:24%;box-sizing:border-box} +.wst-ca-76{float:left;width:75%;box-sizing:border-box} +.wst-ca-50{float:left;width:50%;box-sizing:border-box} +.wst-ca-s{background:#fff;padding:10px 5px;margin-top:10px;font-size:.15rem} +.wst-ca-s .shop{height:26px;line-height:26px;padding-bottom:3px;border-bottom:1px solid #edebeb} +.wst-ca-s .goods{padding:3px 0;border-bottom:1px solid #f1f1f1} +.wst-ca-s .nogoods{border:1px solid #de0301;background:#f8eeee} +.wst-ca-s .nogoods .noprompt{position:absolute;left:0;top:0;color:#fff;font-size:.15rem;background:#e00102} +.wst-ca-s .shopr{height:26px;line-height:26px} +.wst-ca-s .shopr p{float:left;width:86%;} +.wst-ca-s .shopr .shopicon{float:left;width:22px;height:26px;position: relative;background: url(../img/icon_dp.png) 0px 4px no-repeat;background-size: 87%;} +.wst-ca-s .shopl,.wst-ca-s .shopr,.wst-ca-s .goodsl,.wst-ca-se .totall,.wst-ca-s .nogoods{position:relative} +.wst-ca-s .shopl i{position:absolute;left:-2px;top:-9px} +.wst-ca-s .info{padding-left:5px} +.wst-ca-s .goodsl i{position:absolute;left:-2px;top:50%} +.wst-ca-s .goodsr .img{float:left;width:100%;height:70px;text-align:center;vertical-align:middle;display:block} +.wst-ca-s .goodsr .img a{width:100%;height:70px;display:table-cell;vertical-align:middle} +.wst-ca-s .goodsr .img a img{max-width:70px;max-height:70px} +.wst-ca-s .info .name{float:left;width:72%;font-size:.145rem;font-weight: 700;} +.wst-ca-s .info .price{float:right;width:28%;text-align:right;font-size:.13rem} +.wst-ca-s .info .spec{float:left;width:100%;padding:3px 0;color:#a6a6a6} +.wst-buy_l{float:right;width:100%;margin-top:3px;text-align:right} +.wst-buy_l1,.wst-buy_l3{width:30px;height:28px;background:#FFF;border:0;border:1px solid #ddd} +.wst-buy_l1{border-right:1px solid #fff;} +.wst-buy_l3{border-left:1px solid #fff;} +.wst-buy_l1{border-top-left-radius:3px;border-bottom-left-radius:3px} +.wst-buy_l3{border-top-right-radius:3px;border-bottom-right-radius:3px} +.wst-buy_l2{width:38px;height:28px;border:1px solid #ddd;text-align:center;color:#e00102} +.wst-buy_l1:focus,.wst-buy_l3:focus{color:#e00102} +.wst-buy_l2:focus{width:38px;height:28px;border:1px solid #e00102} +.wst-ca-s .bottom{height:23px;line-height:23px;font-size:.158rem;margin-top:8px} +.wst-ca-s .bottom .price{color:#de0202;text-align:right;} +.wst-ca-s .bottom .price span{font-size:0.13rem;} +.wst-ca-se{padding:0 5px;font-size:.165rem;height:42px;line-height:42px} +.wst-ca-se .totall i{position:absolute;left:-2px;top:-2px} +.wst-ca-se .totalr span{color:#051b28;} +.wst-ca-se .total{float:right;margin-right:6px} +.wst-ca-se .total .price{color:#de0202;} +.wst-ca-se .totalr .price span{color:#de0202;font-size:.13rem;} +.wst-ca-se .totalr .button{float:right;width:31%;height:33px;color:#fff;margin-top:4px;font-size:.18rem;background:#e00102;font-size:.165rem;border-radius:3px;border-bottom:1px solid #e00102} +.wst-ca-se .totalr .button:not(.disabled):not(:disabled):active,.wst-ca-se .totalr .button.active{color:#fbd6d6;background:#f25a5b;background-clip:padding-box} +.wst-header .edit{right: 33px;} +.wst-ca-layer{position: fixed;left: 0px;top: 0px;width: 100%;height: 100%;z-Index: 9999;display: none;} +.wst-ca-more{ position: absolute;top: 0;right: 8px;color: #59595c;min-width: 30px;height: 41px;line-height: 41px;font-size: 20px;font-weight: 700;text-align: right;} +.wst-go-more{position: fixed;top: 29px;right: 1px;z-Index: 10000;width: 32%;} +.wst-go-more .arrow{position: absolute;top:-6px;right:7px;display: block;width: 0;height: 0;line-height: 0;border-width: 0.11rem;border-color: transparent transparent rgba(85,85,85,0.95) transparent;border-style: dashed dashed solid dashed;} +.wst-go-more .more{margin-top:13px;border-radius: 3px;background: rgba(85,85,85,0.95);} +.wst-go-more .more .column{width: 80px;display: block;margin: 0 auto;height: 23px;line-height: 23px;padding:10px 0px;} +.wst-go-more .more .line{border-bottom: 1px solid #f2f2f2;} +.wst-go-more .more i{float: left;width: 23px;height: 23px;margin-left:2px;position: relative;} +.wst-go-more .home{background: url(../img/icon_bottomnav.png) 0px -24px no-repeat;background-size: 1062%;} +.wst-go-more .category{background: url(../img/icon_bottomnav.png) -53px -23px no-repeat;background-size: 1010%;} +.wst-go-more .follow{background: url(../img/icon_bottomnav.png) -161px -23px no-repeat;background-size: 1010%;} +.wst-go-more .user{background: url(../img/icon_bottomnav.png)-216px -23px no-repeat;background-size: 1010%;} +.wst-go-more .more p{float: left;width: 55px;color: #fff;font-size:0.13rem;} +.wst-go-more .more li:active{padding-left:2px;background: #252525;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/cashconfigs.css b/hyhproject/wechat2/view/default/css/cashconfigs.css new file mode 100755 index 0000000..47ca418 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/cashconfigs.css @@ -0,0 +1,43 @@ +@CHARSET 'UTF-8'; +body{background:#f2f2f2;font-size:.15rem} +.ui-icon-return ~ h1{z-index:-1;position:relative} +.add{position:absolute;right:0;top:0;display:block;color:black;padding-right:10px} +.ui-row{border:1px solid #e2e2e2;border-radius:5px;margin:5px;padding:10px 5px;background:#fff} +.wst-ca-accno{color: #de0202;font-size:.17rem;font-weight: 700;letter-spacing:2px;} +.wst-ca-info{color: #999;font-size:.13rem;} +.c-tr{float: right;line-height:30px;margin-top:26%;} +.delete-icon{width:25px;height:30px;display:block;float:left;background:url(../img/icon_adds_users.png) no-repeat;background-position:-86px 0;background-size:cover} +.wst-ad-form{margin-top:8px} +.wst-ca-choice{float: right;width: 75%;padding: 2px 2px 2px 0px;margin-top: 4px;height: 36px;border-radius: 2px;font-size:.15rem;border: 0;background:#fff;} +.ui-form-itemin{position:relative;font-size:16px;height:44px;line-height:44px;padding:1px 10px;font-size:.18rem;background:#fff} +.ui-form-itemin .word{color:#232228;font-size:.15rem} +.ui-form-itemin input{float:right;width:75%;height:35px;border:0;margin-top:4px;font-size:.15rem;} +.ui-form-itemin label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio){position:absolute;text-align:left;box-sizing:border-box} +.ui-form-itemin .address{float:right;width:75%;height:35px;line-height:35px;margin-top:4px;font-size:.15rem;} +.ui-form-itemin .ui-select-group{margin-top:5px} +.wst-selectin{float:left;position:relative;width:72%} +.wst-address_set{width:100%;height:40px;position:fixed;z-index:100;left:0;bottom:0} +.wst-ad-line{padding:0 10px} +.wst-ad-line p{border-bottom:1px solid #edebeb} +.wst-ad-submit{margin-top:20px} +.wst-ad-submit .button{margin:0 auto;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-ad-submit .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-form-itemin .operate{font-size:.158rem} +.ui-form-itemin .operate i{float:left;width:22px;height:22px;margin-top:10px;margin-right:2px} +.ui-form-itemin .operate span{margin-left:5px} +.iziModal{background:#f6f6f8} +.iziModal-button-close i{font-size: 22px;line-height:41px;} +.iziModal .iziModal-header-title{font-size: 16px;height:22px;line-height:22px;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;left:0;bottom:-285px;width:100%;min-height:50%;background:#fff;font-size:.14rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size: 15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:10px 10px 20px 10px} +.wst-fr-box .option{float:left;width:100%;border-bottom:1px solid #edebeb} +.wst-fr-box .option p{float:left;width:50px;height:26px;line-height:26px;padding:0 5px;text-align:center} +.wst-fr-box .option .active{border-bottom:1px solid #de0301} +.wst-fr-box .list{padding-top:5px} +.wst-fr-box .list.hide{display:none} +.wst-fr-box .list p{padding:5px 0} +.wst-fr-box .list .active{color:#de0301} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/cashdraws.css b/hyhproject/wechat2/view/default/css/cashdraws.css new file mode 100755 index 0000000..b991134 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/cashdraws.css @@ -0,0 +1,7 @@ +@CHARSET "UTF-8"; +body{font-size: 0.15rem;} +.score-line{border-bottom:1px solid #eaeaea;margin-bottom: 5px;margin-top: 5px;} +.score-time{color:#8c8c8c;font-size: 0.13rem;} +.score-detail{background: #fff;padding:5px;} +.score-detail-title{padding: 5px;padding-left:0px;font-size: 0.18rem;} +.score-text{padding:15px 0;text-align: right;color:#de0202;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/common.css b/hyhproject/wechat2/view/default/css/common.css new file mode 100755 index 0000000..9391556 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/common.css @@ -0,0 +1,86 @@ +@CHARSET "UTF-8"; +body{color:#232326;background-color:#f6f6f8} +a{color:#232326;} +button:before{border:none !important;} +.wst-header,.wst-in-header{border-bottom:1px solid #e5e5e5;background:#fff;height:41px;line-height:41px} +.wst-header h1{font-size: 16px;color: #222;} +.wst-header .ui-icon-return{left: 5px;font-size: 22px;height:41px;line-height:41px;} +.wst-border-bs{font-size:.16rem;border-bottom:1px solid #e6e6e6} +.wst-header .edit{position:absolute;top:0;right:8px;color:#59595c;min-width:32px;height:41px;line-height:41px;font-size:13px} +.wst-header .edit:active{color:#827f7f} +.wst-se-header2{height: 41px;background: #fff;padding-left:25px;border-bottom: 1px solid #e5e5e5;} +.wst-se-header2 .ui-icon-return {top: 2px;left: 8px;color: #df0202;font-size: 22px;line-height: 36px;} +.wst-se-search{display: block;width: 90.9%;height: 31px;line-height:31px;padding: 5px 0;margin: auto;position: relative;} +.wst-se-search i{position: absolute;top: -2px;left: -2px;color: #999;} +.wst-se-search input{margin-top:1px;padding: 0px 0 0 25px;width: 100%;box-sizing: border-box;-ms-box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;border-radius: 15px;background: #eee;color: #999;font-size: 0.13rem;line-height: 28px;letter-spacing: 1px;border: none;} +.wst-se-icon{position: absolute;top: 4px;right: 8px;width: 33px;height: 33px;display: block;background: url(../img/classify2.png) center center no-repeat;background-size: 60%;} +.wst-co-search{position: fixed;top:0;left:0;width: 100%;height:100%;background:#fff;z-index:1000;display:none;} +.wst-co-search .wst-se-header2{z-index: 1000;} +.wst-co-search .list{border-top: 42px solid transparent;} +.wst-co-search .list .search{padding:0 0.05rem;font: bold 14px/31px verdana;} +.wst-co-search .list .search i{float:left;width: 26px;height: 26px;background: url(../img/hot.png) center center no-repeat;background-size: 60%;} +.wst-co-search .list .term{margin-top:0.05rem;padding:0 0.1rem;} +.wst-co-search .list .term a{float:left;margin:0 0.08rem 0.08rem 0;padding:0.05rem 0.1rem;font-size:0.13rem;border-radius: 0.03rem;color: #686868;background-color: #f0f2f5;} +.wst-co-search .classify{border-top: 41px solid transparent;font-size:0.13rem;height: calc((100% - 41px));height: -webkit-calc((100% - 41px));height: -moz-calc((100% - 41px));height: -ms-calc((100% - 41px));height: -o-calc((100% - 41px));overflow-y: scroll;} +.wst-co-search .classify li h4{font-size:0.13rem;} +.wst-co-search .classify .ui-list-link > li:after,.wst-co-search .classify li .ui-txt-info{color: #232326;} +.wst-co-search .classify .shops{margin:0.08rem 0 0.1rem 0;} +.wst-co-search .classify .shops2 li{border-bottom: 1px solid #f6f6f8;} +.wst-footer-btns{border:0;background:#FFF} +.wst-menus{padding-top:2px} +.wst-menus .carsNum{position:relative} +.wst-menus .carsNum i{display:inline-block;text-align:center;background:#de0202;color:#fff;height:16px;line-height:16px;-webkit-border-radius:10px;padding:0 6px;background-clip:padding-box;font-size:.1rem;position:absolute;top:0;left:52.888888%} +.wst-menus p{width:55px;height:42px;margin:0 auto} +.wst-menus .icon{width:36px;height:25px;display:block;margin:0 auto} +.home-word,.category-word,.cart-word,.follow-word,.user-word{float:left;width:100%;text-align:center;font-size:.12rem;color:#2c2c2c;height:16px;line-height:16px} +.home-active-word,.category-active-word,.cart-active-word,.follow-active-word,.user-active-word{float:left;width:100%;text-align:center;font-size:0.12rem;color:#df0202;height:16px;line-height:16px} +.wst-menus .home{background: url(../img/icon_bottomnav.png) 9px 4px no-repeat;background-size: 773%;} +.wst-menus .category{background: url(../img/icon_bottomnav.png) -50px 5px no-repeat;background-size: 712%;} +.wst-menus .cart{background: url(../img/icon_bottomnav.png) -121px 5px no-repeat;background-size: 770%;} +.wst-menus .follow{background: url(../img/icon_bottomnav.png) -178px 5px no-repeat;background-size: 742%;} +.wst-menus .user{background: url(../img/icon_bottomnav.png) -240px 5px no-repeat;background-size: 742%;} +.wst-menus .home-active{background: url(../img/icon_bottomnav.png) 9px -25px no-repeat;background-size: 773%;} +.wst-menus .category-active{background: url(../img/icon_bottomnav.png) -50px -23px no-repeat;background-size: 712%;} +.wst-menus .cart-active{background: url(../img/icon_bottomnav.png) -121px -25px no-repeat;background-size: 770%;} +.wst-menus .follow-active{background: url(../img/icon_bottomnav.png) -178px -24px no-repeat;background-size: 742%;} +.wst-menus .user-active{background: url(../img/icon_bottomnav.png) -240px -24px no-repeat;background-size: 742%;} +.wst-toTop{margin:0 16px 60px 0;position:fixed;z-index:100;right:0;width:30px;height:30px;bottom:15px;display:none} +.wst-toTopimg{width:40px;height:40px;display:block;background:url(../img/top.png) 0 0 no-repeat;background-size:100%} +.wst-toTopimg span{float:left;width:100%;color:#b8b8b8;text-align:center;font-size:.12rem;margin-top:18px} +.wst-toHistoryimg{width:40px;height:40px;display:block;background:url(../img/history-icon.png) 0 0 no-repeat;background-size:100%} +.wst-prompt-icon{position: relative;top:1rem;margin: 0 auto;width:0.89rem;height:0.89rem;} +.wst-prompt-icon img{display: block;width:0.89rem;height:0.89rem;} +.wst-prompt-info{position: relative;top:1.2rem;text-align: center;} +.wst-prompt-info p{font-size:0.16rem;color: #222;} +.wst-prompt-info button{margin-top:0.1rem;font-size:0.15rem;color: #df0202;width:1.5rem;height:0.35rem;border:1px solid #df0202;} +.wst-prompt-info button:not(.disabled):not(:disabled):active{color: #df0202;} +.wst-button-close{display:block;position:absolute;top:0;right:-5px;z-index:2;outline:0;height:42px;width:46px;border-radius:50%;opacity:.5;transition:transform .5s cubic-bezier(.16,.81,.32,1),opacity .5s ease;color:#000;line-height:42px} +.iziModal-button-close i{line-height:42px} +.wst-clear{clear:both} +.wst-Load{position:fixed;z-index:100;top:49%;left:0px;width: 100%;display:none} +.wst-Load .ui-loading{display: block;margin: 0 auto;} +.wst-dialog-t{padding-top:12px;padding-bottom:10px} +.wst-dialog-l{width:73%;border-bottom:1px solid #ddd} +.wst-dialog-b1,.wst-dialog-b2{width:80px;height:30px;line-height: 30px;margin-top:16px;margin-bottom:18px} +.wst-dialog-b1{color:#59595c} +.wst-dialog-b2{color:#fff;background:#de0202} +.wst-dialog-b1:not(.disabled):not(:disabled):active,.wst-dialog-b1 button.active{color:#7d7d7f} +.wst-dialog-b2:not(.disabled):not(:disabled):active,.wst-dialog-b2 button.active{color:#f6e8e9;background:#f43a3b} +.wst-prompt{width:320px;height:210px;position:fixed;top:0;right:10px;background:url(../img/img_fenxiangtishi.png) 13px -13px no-repeat} +.wst-shl-ads{padding-bottom:8px} +.wst-shl-ads .title{height:0.35rem;line-height:0.35rem;font: bold 0.15rem/0.35rem verdana;color: #555;text-align:center;background:url(../img/img_titlebg.png) center no-repeat;background-size:40%} +.wst-active{color:#de0301} +.upload-modal{position:fixed;left:0;top:.5rem;width:100%;height:90%;z-index:102}#upload_modal{display:none} +.clipArea{width:100%;height:100%;background-color:rgba(0,0,0,0.7)} +#errorBg{background:url(../img/img_error_3.png) no-repeat;background-size:auto 145%}#errorBtn{width:152px;position:absolute;bottom:-50px;left:28%;background:#f9a517;color:#fff;border-color:#f9a517} +#errorLostBg{background:url(../img/img_error_2.png) no-repeat;background-size:cover}#errorLostBg p{position:absolute;color:#40ad74;font-size:.18rem;left:7%;top:20%} +.wst-pay-inp{width:100%;margin-top:2px;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0} +.ui-header ~ .ui-container{border-top:42px solid transparent} +.ui-footer ~ .ui-container{border-bottom:45px solid transparent} +.ui-header-positive i,.ui-header-positive a{color:#59595c} +.ui-dialog-bd h4{margin-bottom:10px;text-align:center} +.ui-poptips-success,.ui-poptips-info,.ui-poptips-warn{z-index:9999} +.ft-title i{float:left;width:18px;height:18px;background:url(../img/icon_tishi.png) no-repeat;background-size:100%} +.ft-title span{padding-left:7px;} +.ft-item{padding-left:25px;font-size:.13rem} +input[type="search"]::-webkit-search-cancel-button{display:none;-webkit-appearance:none} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/consult.css b/hyhproject/wechat2/view/default/css/consult.css new file mode 100755 index 0000000..04c61b0 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/consult.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +body{font-size:.15rem;background:#f0f2f5} +.gcListBox{width:99%} +.gcList{width:100%} +.item-time{float:right} +.gcList li{background:#fff;border-bottom:1px solid #ccc;width:97%;padding:10px 5px} +.gcList li:last-child{border:0} +.gc-item-tit{font-size:.11rem;margin:0 10px} +.question-box{padding-top:8px} +.question-pic{display:block;width:17px;height:17px;background-size:50px 50px;background-image:url(./../img/QA-icon.png);background-position:0 -15px;margin-left:10px;float:left;margin-top:1px} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.question-content span{margin-left:37px;display:block;padding-right:12px;font-size:13px;color:#848689;line-height:18px;margin-top:0} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.answer-content span{color:#252525} +.answer-pic{background-position:-33px -15px} +.gcplist{padding:10px} +.gcplist li{margin-bottom:5px}#consultContent{width:100%;min-height:100px} +.consult{width:30px;height:30px;position:absolute;right:5px;top:5px;background:url(./../img/icon_adds_users.png) no-repeat;background-position:-75px -2px;background-size:150px 38.5px} +.consult-button{width:100px;height:30px;margin-top:10px;font-size:.15rem;line-height:30px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.consult-button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/favorites.css b/hyhproject/wechat2/view/default/css/favorites.css new file mode 100755 index 0000000..d222d26 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/favorites.css @@ -0,0 +1,42 @@ +@CHARSET "UTF-8"; +.ui-checkbox-s input:before{font-size:18px;color:#e32726} +.ui-checkbox input:before,.ui-checkbox-s input:before{top:20px;left:-2px;font-size:22px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.sactive{top:-43px!important;margin-right:-5px!important} +.add-cart{display:inline-block;width:23px;height:25px;right:7px;bottom:5px;position:absolute;background:url(../img/icon_gzspcart.png) no-repeat;background-size:100%} +.favorite-tc{line-height:45px;text-align:left} +.f-btn button{position:absolute;top:0.06rem;right:10px;font-size:.15rem;background:#e00102;border-bottom:1px solid #e00102} +.f-btn{min-width:85px} +.wst-shl-list{position:relative;padding:5px 10px;margin-top:5px;background:#fff} +.wst-shl-list .img{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-shl-list .img a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.wst-shl-list .img a img{max-width:100px;max-height:100px} +.wst-shl-list .info{padding-left:5px} +.wst-shl-list .title{margin-bottom:5px;padding-left:10px;font-size:.15rem;color:#363638} +.wst-shl-list p{padding-left:10px} +.wst-shl-list .deal{font-size:0.11rem;color: #999;} +.wst-shl-list .price{color:#ff0e00;font-size:.16rem;} +.wst-shl-list .price span{font-size:.13rem;} +.shopImg{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.shopImg a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.shopImg a img{max-width:100px;max-height:100px} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;} +.goods-box{padding:0!important;margin-bottom: 5px;} +.goodsImg{margin-right: 5px;width:23.5%; position: relative;float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.goodsImg a{width:100%;height:70px;display:table-cell;vertical-align:middle} +.goods-item{width:24%;margin-right:5px;position: relative;} +.goodsPrice{color: red;} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;height: 20px;} +.wst-action{margin-top: 5px; ;display: inline-block;height: 25px;width: 90%;float: right; font-size: 0.14rem;color: red; line-height: 25px;text-align: center;border-radius: 10px;border: 1px solid red;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/goods_category.css b/hyhproject/wechat2/view/default/css/goods_category.css new file mode 100755 index 0000000..ce21092 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/goods_category.css @@ -0,0 +1,16 @@ +@CHARSET "UTF-8"; +.ui-scrollerl{width:22%;height:496px;overflow:hidden;background:#fff;position:fixed;top:42px;left:0;} +.ui-scrollerl li{padding:13px 0px;font-size:0.129rem;text-align:center;} +.wst-goodscate{color: #232326;border-top:1px solid #f6f6f8;border-right:1px solid #f6f6f8;border-left:2px solid #f6f6f8;} +.wst-goodscate_selected{color:#df0202;background:#f6f6f8;border-right:1px solid #f6f6f8;border-left:2px solid #df0202} +.wst-scrollerr{width:78%;float:right} +.wst-scrollerr li{margin:0px 5px;padding: 5px 10px 5px 5px;font-size:0.12rem;background: #fff;} +.wst-goodsca{height:35px;background:#f2f2f2} +.wst-goodscat{float:left;width:100%;} +.wst-goodscat span{float: left;width: calc((100% - 15px)/3);width: -webkit-calc((100% - 15px)/3);width: -moz-calc((100% - 15px)/3);width: -ms-calc((100% - 15px)/3);width: -o-calc((100% - 15px)/3);height: calc((100vw - 20px)/3);height: -webkit-calc((100vw - 20px)/3);height: -moz-calc((100vw - 20px)/3);height: -ms-calc((100vw - 20px)/3);height: -o-calc((100vw - 20px)/3);padding: 5px 0px 0px 5px;text-align:center;} +.wst-goodscat span a{color: #686868;text-align:center} +.wst-goodscat span a img{width:100%;min-height:75px;margin-bottom:2;display:block;} +.wst-gc-ads{padding-bottom:5px} +.wst-gc-ads .title{margin-top:5;padding-left:10;height:30px;line-height:30px;font-size:0.13rem;} +.wst-gc-br .brand{margin-left:5;background:#fff;} +.wst-gc-br .brand img{float:left;width: calc((100% - 15px)/3);width: -webkit-calc((100% - 15px)/3);width: -moz-calc((100% - 15px)/3);width: -ms-calc((100% - 15px)/3);width: -o-calc((100% - 15px)/3);height:50px;margin:5px 0 5px 5px;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/goods_detail.css b/hyhproject/wechat2/view/default/css/goods_detail.css new file mode 100755 index 0000000..13506bd --- /dev/null +++ b/hyhproject/wechat2/view/default/css/goods_detail.css @@ -0,0 +1,153 @@ +@CHARSET "UTF-8"; +.wst-header .cart{width:40px;height:40px;position:absolute;right:38px;background:url(../img/icon_spxq.png) -10px -4px no-repeat;background-size:497%} +.wst-header .cart span{height:12px;line-height:12px;font-size:.11rem;position:absolute;top:6px;right:8px;min-width:12px;text-align:center;border-radius:5px;color:#fff;background:#de0202} +.wst-header .share{width:40px;height:40px;position:absolute;right:0;background:url(../img/icon_spxq.png) -60px -4px no-repeat;background-size:497%} +.swiper-container{height: calc(100vw);height: -webkit-calc(100vw);height: -moz-calc(100vw);height: -ms-calc(100vw);height: -o-calc(100vw);} +.swiper-pagination-bullet{width: 6px;height: 6px;background: rgba(0,0,0,.2);opacity: 1;} +.swiper-pagination-bullet-active{background: #ff6666;} +.wst-go-return{position: absolute;top:0.1rem;left:0.1rem;z-index:10;width: 0.3rem;height: 0.3rem;background-color: rgba(0,0,0,.4);border-radius: 100%;} +.wst-go-return i{position: absolute;top: 0.02rem;left: 0.02rem;width: 0.24rem;height: 0.24rem;line-height: 0.24rem;font-size: 0.24rem;color:#fff;} +.wst-go-mores{position: absolute;top:0.1rem;right:0.1rem;z-index:10;width: 0.3rem;height: 0.3rem;background-color: rgba(0,0,0,.4);border-radius: 100%;} +.wst-go-mores i{position: absolute;top: 0.03rem;left: 0.03rem;width: 0.24rem;height: 0.24rem;line-height: 0.24rem;font-size: 0.24rem;color:#fff;text-align: center;z-index: 0;} +.wst-ca-layer{position: fixed;left: 0px;top: 0px;width: 100%;height: 100%;z-Index: 9999;display: none;background-color: rgba(0,0,0,.6);} +.wst-go-more{position: fixed;top: 29px;right: 0.05rem;z-Index: 10000;width: 32%;} +.wst-go-more .arrow{position: absolute;top:-6px;right:7px;display: block;width: 0;height: 0;line-height: 0;border-width: 0.11rem;border-color: transparent transparent #fff transparent;border-style: dashed dashed solid dashed;} +.wst-go-more .more{margin-top:13px;border-radius: 3px;background: #fff;} +.wst-go-more .more .column{width: 80px;display: block;margin: 0 auto;height: 23px;line-height: 23px;padding:10px 0px;} +.wst-go-more .more .line{border-bottom: 1px solid #f2f2f2;} +.wst-go-more .more i{float: left;width: 23px;height: 23px;margin-left:2px;position: relative;} +.wst-go-more .home{background: url(../img/icon_bottomnav.png) 0px -24px no-repeat;background-size: 1062%;} +.wst-go-more .category{background: url(../img/icon_bottomnav.png) -53px -23px no-repeat;background-size: 1010%;} +.wst-go-more .cart{background: url(../img/icon_bottomnav.png) -107px -23px no-repeat;background-size: 1010%;} +.wst-go-more .follow{background: url(../img/icon_bottomnav.png) -161px -23px no-repeat;background-size: 1010%;} +.wst-go-more .user{background: url(../img/icon_bottomnav.png)-216px -23px no-repeat;background-size: 1010%;} +.wst-go-more .more p{float: left;width: 55px;font-size:0.13rem;} +.wst-go-more .more li:active{padding-left:2px;} +.wst-go-img{width:100%;height: calc(100vw);height: -webkit-calc(100vw);height: -moz-calc(100vw);height: -ms-calc(100vw);height: -o-calc(100vw);text-align:center;vertical-align:middle;display:block;position:relative} +.wst-go-img a{width: calc(100vw);width: -webkit-calc(100vw);width: -moz-calc(100vw);width: -ms-calc(100vw);width: -o-calc(100vw);height: calc(100vw);height: -webkit-calc(100vw);height: -moz-calc(100vw);height: -ms-calc(100vw);height: -o-calc(100vw);display:table-cell;vertical-align:middle} +.wst-go-img a img{max-width:100%;max-height:100%;} +.wst-go-name{padding:0.1rem 0.1rem 0 0.1rem;font-size: 0.165rem;color: #051B28;background:#fff;line-height:0.23rem;} +.wst-go-price{padding:0.1rem 0.1rem 0.05rem 0.1rem;background:#fff;position: relative;} +.wst-go-price p{font-size:.15rem;color:#707070} +.wst-go-price .price{font-size:.25rem;color:#de0202} +.wst-go-price .price i{font-size:.13rem;} +.wst-go-price .market{margin-left:12px;font-size:.13rem;color:#999;text-decoration:line-through} +.wst-go-price .info{padding-top:0.05rem;font-size: 0.13rem;color: #999;} +.wst-go-price .follow,.wst-go-price .nofollow{width:40px;height:40px;display:block;margin:0 auto} +.wst-go-icon .follow{background:url(../img/icon_spxq.png) -154px -47px no-repeat;background-size:659%} +.wst-go-icon .nofollow{background: url(../img/icon_spxq.png) -113px -47px no-repeat;background-size: 659%} +.wst-go-ul{margin:10px 0} +.wst-go-ul li{color:#3d3d3d;margin-left:0;padding:0.1rem;border-bottom:1px solid #edebeb} +.wst-go-ul .icon{color:#dbdada;height:24px;line-height:24px;font-size:.35rem} +.wst-go-ul .word{color: #3d3d3d;} +.wst-go-ul .line,.wst-go-shop .line{color:#dbdada;padding:0 5px} +.wst-go-ul .red,.wst-go-shop .score .red{color:#de0202} +.wst-go-shop{padding-bottom:10px;border-bottom: 1px solid #f2f1f1;} +.wst-go-shop .info{padding:0.1rem;} +.wst-go-shop .img{float:left;width:0.6rem;height:0.6rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-go-shop .img a{width:0.6rem;height:0.6rem;display:table-cell;vertical-align:middle} +.wst-go-shop .img a img{max-width:0.6rem;max-height:0.6rem;font-size:0.13rem} +.wst-go-shop .name{float:left;width:80%;} +.wst-go-shop .name1{float:left;width:100%;padding-left:0.05rem;font-size:0.165rem;line-height:0.35rem;} +.wst-go-shop .name2{float:left;width:100%;padding-left:0.05rem;font-size:0.13rem;color: #848689;} +.wst-go-shop .score{padding:0.08rem 0.1rem;font-size:.13rem;} +.wst-go-shop .button{padding:0.08rem 0.1rem;font-size:.15rem;text-align:center;} +.wst-go-shop .button a{height: 0.38rem;line-height: 0.38rem;color: #666;border-radius: 4px;text-align: center;display: block;border: 1px solid #ccc;} +.wst-go-shop .button .goods{margin-right:0.1rem;} +.wst-go-shop .button .goods:before{content:'';padding:2px 8px;width: 10px;margin-right: 6px;background:url(../img/user-tool-icon2.png) 0 1px no-repeat;background-size:100%}} +.wst-go-shop .button .shop{margin-left:0.1rem;} +.wst-go-shop .button .shop:before{content:'';padding:2px 8px;width: 10px;margin-right: 6px;background:url(../img/icon_dp.png) 0 2px no-repeat;background-size:100%} +.wst-go-goods{float:left;width: calc((100% - 48px)/3);width: -webkit-calc((100% - 48px)/3);width: -moz-calc((100% - 48px)/3);width: -ms-calc((100% - 48px)/3);width: -o-calc((100% - 48px)/3);padding:5px;margin:6px 3px 0px 3px;font-size:.13rem;background:#fff;} +.wst-go-goods .img{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-go-goods .img a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.wst-go-goods .img a img{max-width:100px;max-height:100px} +.wst-go-goods .name{float:left;width:100%;height:.42rem;margin-top:2px;line-height:.21rem} +.wst-go-goods .info{float:left;width:100%;margin-top:3px} +.wst-go-goods .info .price{float:left;font-size:.15rem;color:#e00102} +.wst-go-icon .icon,.wst-go-icon .but{display: block;margin: 0 auto;margin-top:3px;width:30px;height:42px;color:#59595c;position:relative} +.wst-go-icon .icon a{width:30px;height:42px;display:block} +.wst-go-icon .img{width:30px;height:22px;position:absolute;left:0;top:0} +.wst-go-icon .tel{background:url(../img/icon_spxq.png) -14px -48px no-repeat;background-size:738%} +.wst-go-icon .qq{background:url(../img/qq.png) 5px 1px no-repeat;background-size: 20px 20px;} +.wst-go-icon .shop{background: url(../img/icon_spxq.png) -62px -45px no-repeat;background-size: 648%;} +.wst-go-icon .word{width:100%;position:absolute;left:0;bottom:2px;font-size:.13rem;text-align:center;color: #232326;} +.wst-goods_buy{margin:0;} +.wst-goods_buyl,.wst-goods_buyr{float:left;width:50%;height:42px;line-height: 42px;font-size:.15rem;color:#fff} +.wst-goods_buyl{background:#f9a517;border-bottom:1px solid #f9a517;} +.wst-goods_buyl:not(.disabled):not(:disabled):active,.wst-goods_buyl.active{color:#fbf6ee;background:#f3c77c;background-clip:padding-box} +.wst-goods_buyr{background:#e00102;border-bottom:1px solid #e00102;} +.wst-goods_buyr:not(.disabled):not(:disabled):active,.wst-goods_buyr.active{color:#fbd6d6;background:#f25a5b;background-clip:padding-box} +.wst-goods_buym{float:left;width:100%;height:42px;line-height: 42px;font-size:.15rem;color:#fff;background:#f23030;border:1px solid #f23030;} +.wst-fav_but{width:23px;height:48px;border-radius:none;border:0;background-clip:padding-box} +.wst-go-details{font-size:.16rem;padding:8px 10px 15px 8px;word-wrap:break-word;word-break:break-all} +.wst-go-details img{width:100%;height:auto;} +.wst-ev-term{margin-top:0.02rem;font-size:.15rem;background:#fff;padding:0.1rem 0;text-align:center;} +.wst-ev-term .number{font-size:.13rem;} +.wst-ev-term .active{color:#de0202;} +.wst-go-evaluate{font-size:.13rem;background:#fff;border-bottom: 1px solid #f2f1f1;} +.wst-go-evaluate .info{margin-bottom:10px;padding:6px 0;} +.wst-go-evaluate .portrait{float:left;width:28px;height:28px;margin-right:5px;border-radius: 100%;} +.wst-go-evaluate .info .name{float:left} +.wst-go-evaluate .info .ranks{float:left;width:16px;margin:2px 16px 0 5px} +.wst-go-evaluate .info .time{float:right;color:#8e8d8d} +.wst-go-evaluate .content{padding-bottom:3px} +.wst-go-evaluate .content p{float:left;width:100%;} +.wst-go-evaluate .content i{float:left;width:14px;height:14px;margin:2px 3px 0 0;} +.wst-go-evaluate .content .bright{background:url(../img/img_dpjpj.png) 0 0 no-repeat;background-size:296%} +.wst-go-evaluate .content .dark{background:url(../img/img_dpjpj.png) -26px 0 no-repeat;background-size:296%} +.wst-go-evaluate .content .content2{font-size:.14rem;margin-top:2px;} +.wst-go-evaluate .content img{float:left;width:45px;height:45px;margin:2px 3px 0 0} +.wst-go-evaluate .content .word{color:#8e8d8d;padding:3px 0} +.wst-go-evaluate .reply{padding:10px 0;border-top:1px solid #edebeb} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;left:0;bottom:-226px;width:100%;min-height:40%;background:#fff;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:.185rem} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:10px 10px 50px 10px} +.wst-fr-box .determine,.wst-cart-box .determine{position:absolute;left:0;bottom:3px;width:100%;text-align:center;} +.wst-fr-box .button,.wst-cart-box .button{width:90%;font-size:.15rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-radius:5px;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-cart-box{position:fixed;z-index:9999;left:0;bottom:-296px;width:100%;min-height:38%;background:#fff;font-size:.14rem} +.wst-cart-box .title{min-height:68px} +.wst-cart-box .picture{position:absolute;left:10px;top:-12px} +.wst-cart-box .picture .img{float:left;width:70px;height:70px;text-align:center;vertical-align:middle;display:block;position:relative;padding:5px;background:#fff;border-radius:2px} +.wst-cart-box .img a{width:70px;height:70px;display:table-cell;vertical-align:middle} +.wst-cart-box .img a img{max-width:70px;max-height:70px} +.wst-cart-box .title p{float:left;margin:0 0 5px 96px;color:#3e3e3e;width:53%} +.wst-cart-box .title .price{font-size:.162rem;color:#de0202} +.wst-cart-box .title .price .price2{margin-left:12px;font-size:.13rem;color:#707070;text-decoration:line-through} +.wst-cart-box .standard{padding:0 10px 118px 10px} +.wst-cart-box .spec{padding:10px 0;border-bottom:1px solid #f1f1f1} +.wst-cart-box .spec p{float:left;width:100%} +.wst-cart-box .spec .img{float:left;width:40px;height:40px;border-radius:2px;margin:5px 6px 0 0} +.wst-cart-box .spec .img.active{width:38px;height:38px;border:1px solid #e00102} +.wst-cart-box .spec span{float:left;margin:5px 6px 0 0;padding:3px 5px;border:1px solid #a0a0a0;border-radius:3px;text-align:center} +.wst-cart-box .spec span.active{color:#fff;background:#e00102;border:1px solid #e00102} +.wst-cart-box .number{width:92%;position:absolute;left:3%;bottom:52px;z-Index:1;background:#fff} +.wst-cart-box .number .stock{float:left;color:#3e3e3e;margin-top:12px} +.wst-buy_l{float:right;margin-top:3px} +.wst-buy_l1,.wst-buy_l3{width:40px;height:32px;background:#FFF;border:0;border:1px solid #ddd} +.wst-buy_l1{border-right:1px solid #fff;} +.wst-buy_l3{border-left:1px solid #fff;} +.wst-buy_l1{border-top-left-radius:3px;border-bottom-left-radius:3px} +.wst-buy_l3{border-top-right-radius:3px;border-bottom-right-radius:3px} +.wst-buy_l2{width:48px;height:32px;border:1px solid #ddd;text-align:center;color:#e00102} +.wst-buy_l1:focus,.wst-buy_l3:focus{color:#e00102} +.wst-buy_l2:focus{width:48px;height:32px;border:1px solid #e00102} +.ui-tab-nav{width:62%;height:40px;float:right;margin-right:70px} +.ui-tab-nav li.active{color:#777;border-bottom:2px solid #de0202;color:#de0202} +.ui-tab-nav li{height:42px;line-height:42px;font-size:.16rem;min-width:50px} +.ui-slider-content>li img{display:inline;width:auto} +.gc-title{height:38px;line-height:38px;padding-left:38px;font-size:.15rem;text-align:left;position:relative;background:#fff} +.gc-tit-icon{display: block;width:38px;height:38px;background:url(./../img/icon_indextop.png) no-repeat;background-position:-144px 9px;background-size:176px 20px;position:absolute;top:0;left:0;} +.gc-tit-icon2{display: block;width:30px;height:30px;background:url(./../img/icon_adds_users.png) -75px -2px no-repeat;position:absolute;top: 4px;right: 5px;background-size: 150px 38.5px;} +.gc-title-list{background:#ffffff;padding:0.1rem 0;border-top:1px solid #f2f1f1;} +.gc-title-list .prompt{text-align:center;font-size:0.14rem;} +.question-box{padding-top:8px} +.question-pic{display:block;width:17px;height:17px;background-size:50px 50px;background-image:url(./../img/QA-icon.png);background-position:0 -15px;margin-left:10px;float:left;margin-top:1px} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.question-content span{margin-left:37px;display:block;padding-right:12px;font-size:13px;color:#848689;line-height:18px;margin-top:0} +.question-content{width:100%;margin-left:-27px;display:block;float:left;word-break:break-word;overflow:hidden} +.answer-content span{color:#252525} +.answer-pic{background-position:-33px -15px} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/goods_list.css b/hyhproject/wechat2/view/default/css/goods_list.css new file mode 100755 index 0000000..c0c269b --- /dev/null +++ b/hyhproject/wechat2/view/default/css/goods_list.css @@ -0,0 +1,34 @@ +@CHARSET "UTF-8"; +.wst-se-header2{padding-left: 0;} +.wst-se-search{width: 76%;} +.wst-se-icon{background: url(../img/goods-list.png) center center no-repeat;background-size: 60%;transform: rotate(90deg);-webkit-transition: all .2s linear;transition: all .2s linear;} +.wst-se-icon2{background: url(../img/goods-list2.png) center center no-repeat;background-size: 60%;transform: rotate(0deg);} +.wst-shl-head{background:#fff;font-size: 0.14rem;color:#6a6b6d;margin-bottom: 0.04rem;} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:24px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding: 5px;margin-bottom: 0.04rem;font-size: 0.14rem;background: #fff;color: #232326;font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.01rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.pd0{padding-right:6px!important} +.wst-in-goods .tags{width:100%;float:left} +.wst-in-goods .tags .tag{background:#f23030;color:#fff;border-radius:2px;font-size:11px;padding:0 2px 0 2px} +.wst-go-switch .wst-in-goods{width: 100%;border:0;} +.wst-go-switch .wst-in-goods .img{width:32%;} +.wst-go-switch .wst-in-goods .name,.wst-go-switch .wst-in-goods .tags,.wst-go-switch .wst-in-goods .info,.wst-go-switch .wst-in-goods .info2{width:68%;padding-left:0.05rem;box-sizing: border-box;} +.wst-go-switch .wst-in-goods .info2{margin-top:0.1rem;} +.wst-go-switch .wst-in-goods .img,.wst-go-switch .wst-in-goods .img a{width: calc(31.5%);width: -webkit-calc(31.5%);width: -moz-calc(31.5%);width: -ms-calc(31.5%);width: -o-calc(31.5%);height: calc(31.5vw);height: -webkit-calc(31.5vw);height: -moz-calc(31.5vw);height: -ms-calc(31.5vw);height: -o-calc(31.5vw);} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/history.css b/hyhproject/wechat2/view/default/css/history.css new file mode 100755 index 0000000..6ee4ace --- /dev/null +++ b/hyhproject/wechat2/view/default/css/history.css @@ -0,0 +1,7 @@ +@CHARSET "UTF-8"; +.goods-item{margin:5px 0;padding: 0.05rem 0.1rem;background:#ffffff;} +.wst-info{padding-left:0.1rem;} +.goodsTitle{font-size: 0.15rem;height:0.42rem;line-height:0.21rem;} +.goods-info{color:#989292;font-size: 0.12rem;} +.price{color: #de0202;font-size: 0.16rem;} +.price span{font-size: 0.13rem;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/index.css b/hyhproject/wechat2/view/default/css/index.css new file mode 100755 index 0000000..c13b9a7 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/index.css @@ -0,0 +1,120 @@ +@CHARSET "UTF-8"; +.wst-in-header{height: 33px;background: -webkit-linear-gradient(top,rgba(0,0,0,.7),rgba(0,0,0,0));background: linear-gradient(top,rgba(0,0,0,.7),rgba(0,0,0,0));-webkit-transition: background-color .2s linear;-moz-transition: background-color .2s linear;-o-transition: background-color .2s linear;transition: background-color .2s linear;-webkit-transform: translateZ(0);transform: translateZ(0);border-bottom: 0px;} +.wst-in-header.active{height: 39px;background: #e50e0f;opacity: 0.87;} +.wst-in-search{position: fixed;z-index: 100;top:0;left:0;width: 100%;height: 28px;line-height:28px;padding: 0px;} +.wst-in-search .ui-icon-search{position: absolute;top: -2px;left: -2px;color: #fff;font-size: 0.35rem;width: 28px;height: 28px;z-index: 100;} +.wst-in-search .searchs{display: block;width: 73.5%;margin: 0 auto;position: relative;} +.wst-in-search .searchs input{margin-top:6px;padding: 0 0 0 25px;width: 100%;box-sizing: border-box;-ms-box-sizing: border-box;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;border-radius: 15px;background: rgba(255,255,255,0.5);color:#fff;font-size: 0.14rem;height: 28px;line-height: 28px;letter-spacing: 1px;border: none;} +.wst-in-search .searchs input::-webkit-input-placeholder {color:#fff;} +.wst-in-search .searchs input:-moz-placeholder {color:#fff;} +.wst-in-search .searchs input::-moz-placeholder {color:#fff;} +.wst-in-search .searchs inputt:-ms-input-placeholder {color:#fff;} +.wst-in-search .searchs.active input{background:#fff;color:#666;} +.wst-in-search .searchs.active input::-webkit-input-placeholder {color:#666;} +.wst-in-search .searchs.active input:-moz-placeholder {color:#666;} +.wst-in-search .searchs.active input::-moz-placeholder {color:#666;} +.wst-in-search .searchs.active inputt:-ms-input-placeholder {color:#666;} +.wst-in-search .searchs.active .ui-icon-search{color:#333;} +.wst-in-search .classify{position: absolute;top:0;left:0;width:13.25%;text-align:center;} +.wst-in-search .classify i{display: block;margin: 0 auto;width:33px;height:33px;background: url(../img/classify.png) center center no-repeat;background-size: 60%;position: relative;top:3px;} +.wst-in-search .user{position: absolute;top:0;right:0;width:13.25%;height:40px;line-height: 40px;text-align:center;} +.wst-in-search .user a{color:#fff;font-size: 0.13rem;} +.wst-in-search .user i{display: block;margin: 0 auto;width:33px;height:33px;background: url(../img/message-icon.png) center center no-repeat;background-size: 60%;position: relative;top:3px;} +.wst-in-search .user i .number{position: absolute;top: 1px;right: -1px;min-width: 10px;display: inline-block;text-align: center;background: #f74c31;color: #fff;font-size: 0.1rem;height: 15px;line-height: 15px;-webkit-border-radius: 8px;padding: 0 3px;background-clip: padding-box;} +.wst-in-adso .adso img,.wst-in-adsb img,.wst-in-adscats img,.wst-in-activity .img img{width:100%;height:100%;display:block} +.wst-in-choose{padding:5px 0 12px 0;background:#fff} +.wst-in-choose p{width: 57.14285714%;display:block;margin:0 auto;padding-bottom:0.05rem;text-align:center;vertical-align:middle;position:relative} +.wst-in-choose p img{width: 100%;} +.wst-in-choose span{font-size:0.13rem;display:block;text-align:center;color:#666;} +.wst-in-activity{background:#fff;padding:5px 0px 10px 0px;} +.wst-in-activity .img{height:1.15rem;} +.wst-in-news{position:relative;display: block;width: 95%;margin: 0 auto;margin-top:0.05rem;font-size:0.14rem;height:30px;line-height:30px;background:#fff;border:1px solid #eee;border-radius: 25px;} +.wst-in-news .article{float:left;width: 60%;height:22px;margin-top:4px;} +.wst-in-news .article p{height:22px;line-height:22px;border-right:1px solid #eee;} +.wst-in-news .new{float:left;width: 24%;text-align:left;margin-left: 3px; font: bold 13px/31px verdana;background: url(../img/icon_news1.png) 30px no-repeat;background-size: 50% 70%;} +.wst-in-news .new p{color: white;display: inline-block;} +.wst-in-news a{color: #df0202;} +.wst-in-news .more{float:right;width: 15%;height:30px;text-align:center;} +.wst-in-news .more:active{background:#f2f1f1}input[type="search"]::-webkit-search-cancel-button{display:none;-webkit-appearance:none} +.wst-in-adst{padding:0.1rem 0px;background:#fff} +.wst-in-adst img{float:left;width:50%;border-bottom:0.01rem solid #f2f1f1;} +.wst-in-adsb{height:1.05rem;background:#fff} +.wst-in-title{height:0.3rem;padding:0.05rem 0;text-align:center;color:#addd2d;background:#fff;border-bottom: 0.01rem solid #f2f1f1;position: relative;} +.wst-in-title .line{display: block;margin: 0 auto;margin-top:0.14rem;width:66%;height:0.02rem;background:#addd2d;} +.wst-in-title .name{position: absolute;left:0;top:0;width:100%;height:0.4rem;} +.wst-in-title .name p{display: block;margin: 0 auto;width:50%;height:0.4rem;font: bold 0.158rem/0.43rem verdana;background:#fff;} +.wst-in-title .name p span{position: relative;padding-left:0.2rem;} +.wst-in-title .icon{position: absolute;top:-0.02rem;left:0;display: block;width:0.2rem;height:0.2rem;background: url(../img/index-icon.png) 0px 0px no-repeat;background-size: 100%;} +.colour0{color:#addd2d} +.colour0 .line{background:#addd2d} +.colour0 .icon{background-position:0px 0px} +.colour1{color:#59a4f0} +.colour1 .line{background:#59a4f0} +.colour1 .icon{background-position:0px -0.41rem} +.colour2{color:#d71c1c} +.colour2 .line{background:#d71c1c} +.colour2 .icon{background-position:0px -0.81rem} +.colour3{color:#f28748} +.colour3 .line{background:#f28748} +.colour3 .icon{background-position:0px -1.20rem} +.colour4{color:#f28bd4} +.colour4 .line{background:#f28bd4} +.colour4 .icon{background-position:0px -1.60rem} +.colour5{color:#a24220} +.colour5 .line{background:#a24220} +.colour5 .icon{background-position:0px -2rem} +.colour6{color:#4289db} +.colour6 .line{background:#4289db} +.colour6 .icon{background-position:0px -2.41rem} +.colour7{color:#f04f00} +.colour7 .line{background:#f04f00} +.colour7 .icon{background-position:0px -2.80rem} +.colour8{color:#009d4e} +.colour8 .line{background:#009d4e} +.colour8 .icon{background-position:0px -3.20rem} +.colour9{color:#f6dd06} +.colour9 .line{background:#f6dd06} +.colour9 .icon{background-position:0px -3.61rem} +.colour10{color:#b79467} +.colour10 .line{background:#b79467} +.colour10 .icon{background-position:0px -4.01rem} +.colour11{color:#ad2be2} +.colour11 .line{background:#ad2be2} +.colour11 .icon{background-position:0px -4.42rem} +.wst-in-adscats{height:60px} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding:5px;margin-bottom:0.04rem;font-size:0.14rem;background:#fff;color: #232326; font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.05rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.wst-in-change{top:48px} +.ui-header ~ .ui-container{border-top:0px solid transparent} +.wst-in-change ~ .ui-container{border-top:48px solid transparent} +.wst-in-public{position:fixed;width:100%;z-index:100;left:0;top:0} +.wst-in-public .back{width:100%;height:48px;background:#232326;} +.wst-in-public .public{width:100%;position:absolute;left:0;top:0} +.wst-in-public .public2{padding-left:36px;position: relative;} +.wst-in-public .ui-icon-close-page{position: absolute;top:3px;left:3px;color:#fff;font-size: 22px;} +.wst-in-public .logo{float:left;width:38px;height:38px;margin-top:5px;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-public .logo a{width:38px;height:38px;display:table-cell;vertical-align:middle} +.wst-in-public .logo a img{max-width:38px;max-height:38px} +.wst-in-public .prompt{float:left;margin-top:5px;margin-left:5px;width:60%;color:#fff;font-size:.15rem;line-height:20px;font-size:.15rem;} +.wst-in-public .button{float:right;height:48px;padding:0 8px;color:#fff;font-size:.15rem;background:#cd2525;border:1px solid #cd2525;border-radius:0px} +.wst-in-public .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-di-weixincode{padding:10px 5px} +.wst-di-weixincode .title{text-align:center;font-size:.165rem;color:#e00102;font-weight:bold;padding:5px 0} +.wst-di-weixincode .prompt{text-align:center;font-size:.15rem;padding:5px 0} +.ui-slider-indicators{display:block;bottom:5px;right:0;text-align:center} +.ui-slider-indicators li{display:inline-block;margin:0 3px} +/*轮播*/ +.ui-slider-indicators{display:block;right: 0px;text-align: center;} +.ui-slider-indicators li {display: inline-block;margin:0px 3px; width: 8px;height: 3px;-webkit-box-shadow: none;-moz-box-shadow: none;-o-box-shadow: none;box-shadow: none;background: rgba(255,255,255,0.5);} +.ui-slider-indicators li.current,.ui-slider-indicators li.current:before{background-color: #fff;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/iziModal.css b/hyhproject/wechat2/view/default/css/iziModal.css new file mode 100755 index 0000000..7af9e43 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/iziModal.css @@ -0,0 +1,54 @@ +.iziModal{display:none;position:fixed;width:100%;left:50%;top:50%;z-index:999;background:#FFF;border-radius:3px;box-shadow:0 0 8px rgba(0,0,0,.3);transition:margin-top .3s ease} +.iziModal *{-webkit-font-smoothing:antialiased} +.iziModal::after{content:'';width:100%;height:0;opacity:0;position:absolute;left:0;bottom:0;z-index:1;background:-moz-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,rgba(0,0,0,0)),color-stop(100%,rgba(0,0,0,0.35)));background:-webkit-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-o-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:-ms-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,0.35) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',endColorstr='#59000000',GradientType=0);transition:height .3s ease-in-out,opacity .3s ease-in-out;pointer-events:none} +.iziModal.hasScroll::after{height:50px;opacity:1} +.iziModal .iziModal-button-close{display:block;position:absolute;top:0;left:0;z-index:2;outline:0;height:46px;width:46px;border-radius:50%;opacity:.5;transition:transform .5s cubic-bezier(.16,.81,.32,1),opacity .5s ease} +.iziModal-button-close i{color:#000} +.iziModal .iziModal-button-close:hover{opacity:1;transform:rotate(180deg)} +.iziModal .iziModal-header{background:#88a0b9;padding:14px 40px 15px 18px;border-radius:3px 3px 0 0;border-bottom:1px solid #e8e8e8;overflow:hidden;position:relative;z-index:10} +.iziModal .iziModal-header-icon{font-size:40px;color:rgba(255,255,255,0.5);padding-right:15px;float:left} +.iziModal .iziModal-header-title{color:#69696b;font-size:18px;line-height:1.3} +.iziModal .iziModal-header-subtitle{color:rgba(255,255,255,0.6);font-size:12px;line-height:1.4} +.iziModal .iziModal-header-title,.iziModal .iziModal-header-subtitle{margin:0;font-family:Arial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center} +.iziModal .iziModal-header.iziModal-noSubtitle{height:auto;padding:9px 15px 9px 15px} +.iziModal .iziModal-header.iziModal-noSubtitle .iziModal-header-icon{font-size:23px;padding-right:13px} +.iziModal .iziModal-header.iziModal-noSubtitle{font-size:15px;font-weight:400} +.iziModal.light .iziModal-header{box-shadow:none} +.iziModal.light .iziModal-header-icon{color:rgba(0,0,0,0.5)} +.iziModal.light .iziModal-header-title{color:#000} +.iziModal.light .iziModal-header-subtitle{color:rgba(0,0,0,0.6)} +.iziModal.light .iziModal-button-close{background:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTExIDc5LjE1ODMyNSwgMjAxNS8wOS8xMC0wMToxMDoyMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDU0QjI2RjgyNjZFMTFFNkE3RTk5MEFGMzVBNTcxNkYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDU0QjI2RjcyNjZFMTFFNkE3RTk5MEFGMzVBNTcxNkYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDVDRUM4QTFGQTZCMTFFNEExNEZGMTM1MjdDNDE2ODMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDVDRUM4QTJGQTZCMTFFNEExNEZGMTM1MjdDNDE2ODMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6mca+RAAABkklEQVR42rxVoU4DQRC9NhhUAYNBICqbVLUJSU+cK4IPuB+4BAeCNAUPAgH6fqCuBkHdGRJEVZPKE4iaKlqFPN4ms8uymbm7hjsmeZmmO/ve7czsTiPLMq9O28tbjOP4EC4EzoE2cEJLKyAFXoFJFEWfEkeDOwGI9+GugRvgoOAjN8Aj8AShr0IBkJ/CvQCdHbOxBC4g8iEKgFyl4N1Kxa6mUncGkZX+o+mkZfoHco/2TonrtwDsCuhV0Dg94voRgOIR3IgJvgR8OjqXDp9iXBsRpzmBasUWVzjk8w0+cETU74DWlsy+FnEagaFw3Am+pA2i1BLR5KlaUzHC3qEt0M0pWuKI2ORJTlN07Zt8XNAZSiQgEa8EueFsejWbFlgXXB6TFqYmkq1tgUUZckpLUlJkYQvMhKCQKahb+FDYO7MFVKttmaAOiAZMQbXIQHgUt7p9zWOH4DHcfUW1vcXpHtwuegbmFZDPieufn2tltOAL70uZgePb5OxFo4nUB+5oHBbZhmL77jQTZ3LtQ79K+xZgAC6hutw74AdUAAAAAElFTkSuQmCC') no-repeat 50% 50%} +.iziModal .iziModal-loader{background:#FFF url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%;position:absolute;left:0;right:0;top:0;bottom:0;z-index:9} +.iziModal .iziModal-content-loader{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHZpZXdCb3g9IjAgMCA0NCA0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBzdHJva2U9IiM5OTkiPiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS13aWR0aD0iMiI+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49IjBzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgICAgICA8Y2lyY2xlIGN4PSIyMiIgY3k9IjIyIiByPSIxIj4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJyIiAgICAgICAgICAgICAgICBiZWdpbj0iLTAuOXMiIGR1cj0iMS40cyIgICAgICAgICAgICAgICAgdmFsdWVzPSIxOyAyMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMTY1LCAwLjg0LCAwLjQ0LCAxIiAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgLz4gICAgICAgICAgICA8YW5pbWF0ZSBhdHRyaWJ1dGVOYW1lPSJzdHJva2Utb3BhY2l0eSIgICAgICAgICAgICAgICAgYmVnaW49Ii0wLjlzIiBkdXI9IjEuNHMiICAgICAgICAgICAgICAgIHZhbHVlcz0iMTsgMCIgICAgICAgICAgICAgICAgY2FsY01vZGU9InNwbGluZSIgICAgICAgICAgICAgICAga2V5VGltZXM9IjA7IDEiICAgICAgICAgICAgICAgIGtleVNwbGluZXM9IjAuMywgMC42MSwgMC4zNTUsIDEiICAgICAgICAgICAgICAgIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIiAvPiAgICAgICAgPC9jaXJjbGU+ICAgIDwvZz48L3N2Zz4=) no-repeat 50% 50%} +.iziModal .iziModal-content:before,.iziModal .iziModal-content:after{content:'';display:table} +.iziModal .iziModal-content:after{clear:both} +.iziModal .iziModal-content{zoom:1} +.iziModal .iziModal-wrap{position:relative;transition:height .3s ease} +.iziModal .iziModal-iframe{width:100%;margin-bottom:-4px;transition:height .3s ease} +.iziModal-overlay{display:block;position:fixed;z-index:998;top:0;left:0;height:100%;width:100%} +body.iziModal-attached{overflow:hidden}body.iziModal-attached .iziModal{border-radius:0}body.iziModal-attached .iziModal-header{border-radius:0}body.iziModal-attached .iziModal-wrap{overflow-x:hidden} +.iziModal.transitionIn .iziModal-header{-webkit-animation:slideDown .7s cubic-bezier(0.7,0,0.3,1);-moz-animation:slideDown .7s cubic-bezier(0.7,0,0.3,1);animation:slideDown .7s cubic-bezier(0.7,0,0.3,1)} +.iziModal.transitionIn .iziModal-header .iziModal-header-icon{-webkit-animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both;animation:revealIn 1s cubic-bezier(.16,.81,.32,1) both} +.iziModal.transitionIn .iziModal-header .iziModal-header-title,.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both;-moz-animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both;animation:slideIn 1s cubic-bezier(.16,.81,.32,1) both} +.iziModal.transitionIn .iziModal-header .iziModal-button-close{-webkit-animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1);-moz-animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1);animation:revealIn 1.2s cubic-bezier(0.7,0,0.3,1)} +.iziModal.transitionIn .iziModal-iframe,.iziModal.transitionIn .iziModal-wrap{-webkit-animation:fadeIn 2s;-moz-animation:fadeIn 2s;animation:fadeIn 2s} +.iziModal.transitionIn .iziModal-header{-webkit-animation-delay:.0s;-moz-animation:.0s;animation-delay:.0s} +.iziModal.transitionIn .iziModal-header .iziModal-header-icon,.iziModal.transitionIn .iziModal-header .iziModal-header-title{-webkit-animation-delay:.4s;-moz-animation:.4s;animation-delay:.4s} +.iziModal.transitionIn .iziModal-header .iziModal-header-subtitle{-webkit-animation-delay:.5s;-moz-animation:.5s;animation-delay:.5s} +.fadeOut{-webkit-animation:fadeOut .5s;-moz-animation:fadeOut .5s;animation:fadeOut .5s} +.fadeIn{-webkit-animation:fadeIn .5s;-moz-animation:fadeIn .5s;animation:fadeIn .5s} +.transitionIn{-webkit-animation:transitionIn .5s ease;-moz-animation:transitionIn .5s ease;animation:transitionIn .5s ease} +.transitionOut{-webkit-animation:transitionOut .5s cubic-bezier(.16,.81,.32,1);-moz-animation:transitionOut .5s cubic-bezier(.16,.81,.32,1);animation:transitionOut .5s cubic-bezier(.16,.81,.32,1)} +@-webkit-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@-moz-keyframes fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes fadeOut{0%{opacity:1}100%{opacity:0} +}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-moz-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes fadeIn{0%{opacity:0}100%{opacity:1} +}@-webkit-keyframes slideIn{0%{opacity:0;-webkit-transform:translateX(50px)}100%{opacity:1;-webkit-transform:translateX(0)}}@-moz-keyframes slideIn{0%{opacity:0;-moz-transform:translateX(50px)} +100%{opacity:1;-moz-transform:translateX(0)}}@keyframes slideIn{0%{opacity:0;transform:translateX(50px)}100%{opacity:1;transform:translateX(0)}}@-webkit-keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-moz-keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@keyframes transitionIn{0%{opacity:0;transform:scale(0.9) translateY(-20px) perspective(600px) rotateX(10deg)} +100%{opacity:1;transform:scale(1) translateY(0) perspective(600px) rotateX(0)}}@-webkit-keyframes transitionOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0.9)} +}@-moz-keyframes transitionOut{0%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(0.9)}}@keyframes transitionOut{0%{opacity:1;transform:scale(1)} +100%{opacity:0;transform:scale(0.9)}}@-webkit-keyframes slideDown{0%{opacity:0;-webkit-transform:scale(1,0) translateY(-40px);-webkit-transform-origin:center top} +}@-moz-keyframes slideDown{0%{opacity:0;-moz-transform:scale(1,0) translateY(-40px);-moz-transform-origin:center top}}@keyframes slideDown{0%{opacity:0;transform:scale(1,0) translateY(-40px);transform-origin:center top} +}@-webkit-keyframes revealIn{0%{opacity:0;-webkit-transform:scale3d(0.3,0.3,1)}}@-moz-keyframes revealIn{0%{opacity:0;-moz-transform:scale3d(0.3,0.3,1)} +}@keyframes revealIn{0%{opacity:0;transform:scale3d(0.3,0.3,1)}} +.iziModal ::-webkit-scrollbar{width:0} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/list_complains.css b/hyhproject/wechat2/view/default/css/list_complains.css new file mode 100755 index 0000000..1d87602 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/list_complains.css @@ -0,0 +1,18 @@ +@CHARSET "UTF-8"; +body{font-size:.13rem} +.c-tr{text-align:right} +.complain-box{margin-top:5px;padding:5px;background:#fff} +.c-line{border-bottom:1px solid #eaeaea;margin-bottom:5px} +.c-item li{padding:10px 0;font-size:.15rem} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background-color:#f6f6f8;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{background:#fff;height:auto;position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:14px} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{overflow-y:scroll} +.com-detail-box{margin:10px 0;background:#fff} +.com-detail-box li{padding:5px} +.com-detail-big-title{margin-left:6px;font-weight:bold} +.com-detail-title{text-align:right} +.annex{width:60px;height:60px} +.wst-co-status{color: #fa281b;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/logmoneys.css b/hyhproject/wechat2/view/default/css/logmoneys.css new file mode 100755 index 0000000..5d3d3a3 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/logmoneys.css @@ -0,0 +1,38 @@ +@CHARSET "UTF-8"; +h1{position:relative} +.record{display:inline-block;position:absolute;right: 10px;top:0;color:black;color: #59595c;font-size: 13px;} +.bgimg{display:inline-block;width:67px;height:60px;margin-top:20px;margin-bottom:5px} +.head-btn{display:block;width:auto;height:40px;line-height:40px;font-size:.22rem;color:#fff;background-color:#ff4e4e} +.head-btn i{position:relative;top:16%;display:inline-block;width:26px;height:26px;margin-right:5px;background:url(../img/icon_tixian.png) no-repeat;background-size:100%} +.head-btn-box{margin-top:77px} +.wst-header h1{z-index:-1} +.head{min-height:1rem;color:#fff;background:url(../img/icon_logmoney.png) no-repeat;background-size:cover;position: relative;} +.title{position: absolute;left:0;bottom:0;width:100%;} +.title .money_number{font-size:0.15rem;text-align: right;padding:0 0.1rem;} +.title .money_number2{font-size:0.13rem;margin-top: 2px;text-align: right;padding:0 0.1rem 0.05rem 0.1rem;} +.title .money_number p{font-size:0.16rem;} +.title .money_number span{font-size:0.13rem;} +.money-detail{padding:5px;background-color:#fff;border-bottom:1px solid #edebeb;font-size:.15rem;} +.money-detail h5{font-size:.15rem;} +.money-detail-title{padding:5px 10px;font-size:.18rem} +.m-tr{text-align:right;color:#abaaaa} +.first-time{font-size:0.15rem;color:#abaaaa;padding-left:5px;margin-top:10px} +.wst-lo-choice{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;background:#fff;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{height:auto;background:#fff;position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size: 16px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .info{padding:0.1rem;background:#fff;font-size:.15rem;} +.wst-fr-box .info .money{margin-top:0.05rem;font-size:.175rem;color: #df0202;} +.wst-fr-box .info .money span{font-size:.15rem;} +.wst-fr-box .content{padding:0.1rem;margin-top:10px;background:#fff;font-size:.15rem;} +.wst-fr-box .content li{margin:5px auto;line-height:36px} +.recharge-box{height:50px;line-height:50px;text-align:center;background:white;color:black;font-size:.15rem;border-bottom: 1px solid #f2f1f1;} +.wst-apply-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.icon_add{background: url(../img/icon_add_money.png) no-repeat;background-size: contain; width: 60px;margin:5px;margin: 0 auto;margin-top: 10%; height: 20px;} +.icon_out{background: url(../img/icon_out_money.png) no-repeat;background-size: contain; width: 60px;margin:5px;margin: 0 auto;margin-top: 10%; height: 20px;} +.wst_model p {display: inline-block;padding-left:14px;line-height: 20px;} +.icon_stript{width: 20px;height:20px;float: left;} +.stript_1{background: url(../img/icon_cart_money.png) no-repeat;background-size: cover;} +.stript_2{background: url(../img/icon_record.png) no-repeat;background-size: cover;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/messages.css b/hyhproject/wechat2/view/default/css/messages.css new file mode 100755 index 0000000..27ae678 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/messages.css @@ -0,0 +1,23 @@ +@CHARSET "UTF-8"; +body{color:#333} +.wst-info_delete{padding:0} +.wst-info_delete button{height:49px;color:#333;line-height:49px} +.wst-info_delete button:not(.disabled):not(:disabled):active,.wst-info_delete button.active{border-color:#e7530a;color:#504f4f;background-clip:padding-box} +.wst-info_content input:before{font-size:22px;left:15px} +.wst-info_content input:checked:before{color:#f24566} +.wst-info_content span{float:left;width:20px;height:20px;margin-right:5px} +.wst-info_content h5{font-size:.15rem} +.wst-info_ico{background:url(../img/info_icon.png) 0 0 no-repeat} +.wst-info_ico1{background:url(../img/info_icon.png) -22px 0 no-repeat} +.msg-chk{margin-left:-13px;margin-right:10px} +.favorite-tc{line-height:45px;text-align:left;font-size: .165rem;} +.f-btn{min-width:85px} +.f-btn button{background:#e00102;border-bottom:1px solid #e00102;font-size:.15rem;} +.ui-checkbox input:before,.ui-checkbox-s input:before{font-size:22px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.sactive{margin-right:0!important} +.detail-time{text-align:center} +.del-btn{position:absolute;top:8px;right:10px} +.wst-info_detime{font-size:.13rem} +.wst-info_decontent{font-size:.15rem} +.wst-line{border-bottom:1px solid #edebeb;margin:0 10px} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/orders.css b/hyhproject/wechat2/view/default/css/orders.css new file mode 100755 index 0000000..b7a6fad --- /dev/null +++ b/hyhproject/wechat2/view/default/css/orders.css @@ -0,0 +1,107 @@ +@CHARSET "UTF-8"; +body{font-size:.14rem} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.ui-tab{position:fixed;width:100%;z-index:100;left:0;top:41px} +.order-tab{width:100%;height:35px;line-height:35px;padding:0;background:#fff;overflow-x:scroll} +.order-tab::-webkit-scrollbar{width:1px;height:1px;background-color:#fff} +.order-tab::-webkit-scrollbar-thumb{background-color:#fff} +.wst-headero ~ .ui-container{border-top:72px solid transparent} +.item-head{font-size: .15rem;padding:10px 0;border-bottom:1px solid #f2f1f1} +.item-head p{padding-left:20px;position: relative;} +.item-head .shopicon{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.ui-tab-nav li.tab-item{font-size:.15rem;height:35px;line-height:35px;min-width:55px;padding:0 5px;text-align:center} +.ui-tab-nav li.tab-curr{color:#de4943;;height:34px;border-bottom:2px solid #de4943;} +.order-item{background:#fff;margin-top:6px;padding:0 10px;border-bottom:1px solid #e3e3e3} +.order-tr{text-align:right} +.o-shops{padding:2px 0 2px 0;border-bottom:0.01rem solid #f2f1f1;} +.o-shops p{position: relative;padding-left:20px;font-size:.15rem;} +.o-shops i{position: absolute;display: block;top: 1;left: 0;width: 20px;height: 20px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.o-status{color:#de4943;} +.o-status2{float:right;color:#de4943;} +.wst-or-term{padding:2px 0;} +.wst-or-term2{margin-top:10px;padding:10px 0;border-top: 1px solid #f2f1f1;} +.wst-or-term2 .o-status2{font-size:.17rem;font-weight: bold;} +.wst-or-describe{float:left;width: 0.72rem;color: #999;} +.wst-or-describe2{float:left;} +.o-Img{max-width:60px;max-height:60px;width:60px;height:60px;padding-top:5px} +.o-gInfo{padding:5px} +.o-gSpec{color:#ccc} +.border-b{padding-bottom:5px;border-bottom:1px solid #f2f1f1;padding-left: 0;padding-right: 0;} +.o-btn-box{padding-right:0} +.o-btn{float:right;margin-top:10px;margin-left:5px;font-size:.13rem;color:#de0202;border:1px solid #de0202;padding:0 9px} +.o-btn:not(.disabled):not(:disabled):active{color:#de0202;} +.o-cancel-btn{color:inherit;border:1px solid #000} +.o-cancel-btn:not(.disabled):not(:disabled):active{color:inherit} +.wst-wa-info{background:#fff;padding:5px 0;margin-bottom:10px} +.wst-wa-info .info{padding:5px 0;text-align:center;border-bottom:1px solid #ccc} +.wst-wa-info .info span{color:red} +.wst-wa-info .pay-info{text-align: center;padding:10px;color:#000;font-weight:bold;} +.wst-wa-info .pay{padding:10px} +.wst-wa-info .pay input{width:70%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0} +.wst-wa-forget{padding-bottom:20px} +.wst-pa-l{margin-top:8px} +.wst-pa-l .line{border-bottom:1px solid #edebeb} +.wst-pa-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-pa-l .weixinpays{background:url(../img/icon_zhifu.png) 0 1px no-repeat;background-size:97%} +.wst-pa-l .wallets{background:url(../img/icon_zhifu.png) 0 -53px no-repeat;background-size:97%} +.wst-pa-l .alipays{background:url(../img/icon_zhifu.png) 0 -107px no-repeat;background-size:97%} +.ui-dialog-bd{font-size:.15rem} +.cancel-btn-box{margin-left:0;} +.wst-or-process{margin-bottom:0.1rem;} +.wst-or-process .process{position: relative;} +.wst-or-process p{text-align:center;} +.wst-or-process .line{margin-bottom:10px;padding:10px 0;} +.wst-or-process .line span{float:left;width:50%;height:2px;background:#eaeaea;} +.wst-or-process .line span.active{background:#e00102;} +.wst-or-process .icon{position: absolute;left:0;top:0;display: block;width:100%;height:20px;} +.wst-or-process .icon i{height:20px;line-height:20px;font-size: 27px;} +.wst-or-process .icon i.active{color:#e00102;} +.wst-or-process .icon i:before {background: #fff;} +.wst-or-process{margin-bottom:0.1rem;} +.wst-or-process .process{position: relative;} +.wst-or-process p{text-align:center;} +.wst-or-process .line{margin-bottom:10px;padding:10px 0;} +.wst-or-process .line span{float:left;width:50%;height:2px;background:#eaeaea;} +.wst-or-process .line span.active{background:#e00102;} +.wst-or-process .icon{position: absolute;left:0;top:0;display: block;width:100%;height:20px;} +.wst-or-process .icon i{height:20px;line-height:20px;font-size: 27px;} +.wst-or-process .icon i.active{color:#e00102;} +.wst-or-process .icon i:before {background: #fff;} +.detail-head{border-bottom:1px solid #eaeaea;padding:10px 5px;background:#fff;margin-top:5px} +.d-uInfo{background:#fff;height:40px;margin-bottom:5px} +.d-utel{padding-left:15px} +.d-uaddr{padding-left:15px;position:relative} +.d-uaddr i{width:9px;height:25px;display:block;position:absolute;left:1px;top:-3px;background:url(../img/icon_user_adds.png) no-repeat 0 2px;background-size:100%} +.d-goodsitme{background:#fff;border-bottom:0;margin-bottom:5px;font-size:.11rem} +.d-item{background:#fff;border-bottom:1px solid #eaeaea;padding:7px 5px} +.d-item-right{color:#b5b5b5} +.d-gSpec{padding-left:10px} +.price{color:red} +.title{font-size:.15rem;color:#59595c} +#detailBox,#refundBox{font-size:.14rem} +#boxTitle,#refund-boxTitle,#refundFrame{background:#fff} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem;background: red;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:16px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{background:#f2f2f2;overflow:scroll} +.wst-refund{position:fixed;z-index:9999;right:-999px;top:0;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem;background: red;} +#reject,#reason{height:30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.o-oListMoney{float:left;width:100%;text-align:right;margin-bottom:3px;font-size:.15rem} +.o-oListMoney span{color:#de0202;} +.ui-dialog-bd .ui-dialog-bd-title{padding-left:25px} +.order-tr .title{border:none!important} +.wst-btn-dangerlo{color:#fff;font-size:.15rem;height:38px;line-height:38px;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-btn-dangerlo:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.notice{padding:3px 6px;color:#e55454} +.recharge-box{text-align: center;line-height:40px;padding-top:20px;font-size: 0.18rem;} +.recharge-box .paybox{border-top:1px solid #d2d2d2;font-size:0.25rem;margin:10px;} +.order_from{ margin-left: 10px;color: #fff;font-size:.12rem;padding: 0 4px;line-height:22px;border-radius: 10px;background-color: #f19325;position: absolute;left: 0} +.wst-or-refund{padding: 10px 5px;} +.wst-or-refund .prompt{padding:0 10px 10px 10px;border-bottom: 1px solid #eaeaea;padding} +.wst-or-refund .term{padding:10px 10px 0 10px;line-height:30px;} +.wst-or-refund .sign{color:#de0202;} +#refundReason{width:68%;height: 30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.wst-or-refund .term input{width:68%;height:30px;border-radius: 2px;border: 1px solid #a0a0a0;background: #fff;} +.wst-or-refund .wst-dialog-b2{width:220px;height: 35px;line-height: 35px;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/orders_appraises.css b/hyhproject/wechat2/view/default/css/orders_appraises.css new file mode 100755 index 0000000..11ba3db --- /dev/null +++ b/hyhproject/wechat2/view/default/css/orders_appraises.css @@ -0,0 +1,30 @@ +@CHARSET "UTF-8"; +.item-head{margin-top:5px;padding:5px 10px;background:#fff;border-bottom:1px solid #eaeaea} +.item-head .shop{position: relative;padding-left:20px;font-size:.15rem;} +.item-head .shop i{position: absolute;display: block;top: 2px;left: 0;width: 19px;height: 19px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.border-b{padding:5px 10px 10px 10px;border-bottom:1px solid #eaeaea} +.g-Img{max-width:60px;max-height:60px;padding-top:5px} +.g-Img img{max-width:60px;max-height:60px;} +.g-gInfo{padding:5px} +.g-gName{max-height:40px;line-height: 20px;font-size:.14rem;} +.g-gSpec{color:#ccc;font-size:.13rem;} +.order-tr{text-align:right;line-height:60px} +.order-tr .appraise{float: right;margin-top:20px;font-size:.13rem;color: #f19325;width:30px;height:25px;background: url(../img/evaluate.png) 0px 0px no-repeat;background-size: 72%;} +.g-item{background:#fff} +.appraise-title{padding-left:10px} +.appraise-name{padding-right:10px;height: 0.42rem;line-height:0.21rem;} +.appraise-box{margin-bottom:10px;padding-top:10px;background:#fff;margin-top:5px;font-size:.14rem;border-bottom:1px solid #eaeaea} +.score{color: #f19325;} +.start-on,.start-not{display:inline-block;width:20px;height:25px;background:url(../img/img_dpjpj.png) no-repeat} +.start-on{background-position:1px 4px;background-size:265%} +.start-not{background-position:-34px 4px;background-size:265%} +.appraisesContent{width:100%;min-height:100px;resize:none} +.post-btn button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.post-btn{margin:0;background:#fff}#appraisesBox{margin-top:15px} +.complainFileBox{margin-left:10px;min-height:65px} +.complainFileBox li{float:left;margin-right:5px;max-height:60px} +.complainFileBox img{max-width:50px;max-height:50px} +.edit_charts{position:relative} +.del-btn{position:relative;top:-43px;left:0} +.ui-icon,[class^="ui-icon-de"]{font-size:20px;position:absolute;left:32px;top:-1px;color:red;line-height:17px} +.webuploader-pick {padding: 5px 6px!important;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/orders_complains.css b/hyhproject/wechat2/view/default/css/orders_complains.css new file mode 100755 index 0000000..6177df7 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/orders_complains.css @@ -0,0 +1,52 @@ +@CHARSET "UTF-8";body{font-size:.14rem} +.order-tab{height:30px;line-height:30px;padding:0;background:#fff} +.item-head{padding:5px} +.tab-item{text-align:center} +.tab-curr{border-bottom:2px solid red} +.order-item{background:#fff;margin:10px auto} +.order-tr{text-align:right} +.o-status{color:red} +.o-Img{max-width:60px;max-height:60px;padding-top:5px} +.o-gInfo{padding:5px} +.o-gName{max-height:40px} +.o-gSpec{color:#ccc} +.border-b{padding-bottom:5px;border-bottom:1px solid #ccc} +.o-btn-box{padding-right:0} +.o-btn{float:right;margin-bottom:5px;margin-right:5px;font-size:.15rem;color:red;border:1px solid red;padding:0 9px} +.o-cancel-btn{color:inherit;border:1px solid #000} +.detail-head{border-bottom:1px solid #eaeaea;padding:10px 5px;background:#fff;margin-top:5px} +.d-uInfo{background:#fff;height:30px;margin-bottom:5px;padding:5px;font-size:.14rem;} +.d-uname{padding:3px 0;margin-left:-4px} +.d-utel{padding-left:15px} +.d-goodsitme{background:#fff;border-bottom:0;margin-bottom:5px;font-size:.13rem} +.d-item{background:#fff;border-bottom:1px solid #eaeaea;padding:5px} +.d-item-right{color:#b5b5b5} +.d-gSpec{padding-left:10px} +.price{color:red} +.title{font-size:.15rem;color:#59595c} +#detailBox{font-size:.15rem}#boxTitle{background:#fff} +.c-item{margin-top:5px;padding:10px 5px;font-size:.15rem} +.c-box{margin:0;padding:0;font-size:.15rem} +.c-title{padding:30px 5px 5px 5px;padding-top:10px;background:#fff;height:36px!important;border-bottom:1px solid #eaeaea} +.c-content{background:#fff;height:125px!important;padding:5px;}#complain{width:100%;height:120px;resize:none} +.webuploader-pick{padding:5px 6px!important;} +.complainFileBox{min-height:60px;margin-top: 15px;margin-left: 5px;} +.complainFileBox li{float:left;margin-right:5px;max-height:60px} +.complainFileBox img{max-width:50px;max-height:50px} +.edit_charts{position:relative} +.del-btn{position:relative;top:-43px;left:0} +.ui-icon,[class^="ui-icon-de"]{font-size:20px;position:absolute;left:32px;top:-1px;color:red;line-height:17px} +.uploadfile-box{background:#fff;height:100px!important;position:relative} +.ui-icon-thumb{line-height:20px} +.uploadfile-input{width:12%;height:25px;position:absolute;left:0;top:73px;z-index:-55;opacity:0} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:0;bottom:-300px;width:100%;min-height:40%;background:#f2f2f2;font-size:.15rem} +.wst-fr-box .title,.wst-cart-box .title{position:relative;padding:6px 0;border-bottom:1px solid #f1f1f1} +.wst-fr-box .title span{float:left;width:100%;height:26px;line-height:26px;text-align:center;font-size:15px;color: #222;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{background:#f2f2f2;overflow:scroll} +.complain-item{background:#fff;border-bottom:1px solid #eaeaea;padding:10px;font-size:.14rem}#content{min-height:130px} +.ui-checkbox input,.ui-checkbox-s input{height:18px} +.ui-checkbox input:before,.ui-checkbox-s input:before{left:53px;top:-13px;font-size:26px!important} +.ui-checkbox input:checked:before,.ui-checkbox-s input:checked:before{color:#e32726!important} +.c-btn{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/recharge.css b/hyhproject/wechat2/view/default/css/recharge.css new file mode 100755 index 0000000..7ef4160 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/recharge.css @@ -0,0 +1,36 @@ +.ui-radio input:checked:after{background:#f43d30;} +.ui-grid-trisect{background-color:#fff; } +.j-charge-money{display: none;} +.charge-othermoney{width:1rem;height:0.29rem;} +.j-show-box,.j-edit-box,.j-list-box,.wst-list-box{padding:5px 0px 20px 15px;} +.j-list-box li{height:40px;line-height:40px;} +.j-edit-box .rows{width:auto;height:auto;} +.j-edit-box .label{float:left;width:120px;text-align:right;padding:2px 0px 2px 0px;} +.j-edit-box .field{float:left;padding:2px 0px 2px 0px;} +.field label{margin-right:20px;} +#saveAddressBtn{margin-left:120px;} +.j-show-box .address{line-height:36px;} +.j-show-box .address a{color: #1c9eff;} +.j-show-box .address a:hover{text-decoration:underline;} +.j-default{padding:5px;background:#ccc;} +.wst-frame1{border: 2px solid #e2e2e2;text-align:center;position:relative; } +.wst-frame2{border: 2px solid #e2e2e2;text-align:center;border-radius: 10px;position:relative;padding: 0.2rem 0;font-size: 0.13rem; } +.wst-frame2 div{line-height:normal; } +.wst-frame2 div.charge-alone{line-height:0.3rem;font-size: 0.13rem;} +.wst-frame1.j-selected i,.wst-frame2.j-selected i{font-size: 0;line-height: 0;background: url(../img/img_gd_sel.png) no-repeat 0 0;display: block; width: 11px;height: 11px;position: absolute;z-index: 1;right: -1px;bottom: -1px;} +.wst-frame1.j-selected,.wst-frame2.j-selected{border: 2px solid #e4393c;} +.tips-box{margin:0.1rem;} +.paytype-term{padding:0 0.1rem 0 0.05rem;font-size: 0.14rem;border-bottom: 1px solid #f2f1f1;} +.paytype-term label{position: absolute;top:23px;right:0;} +.paytype-term i{display: block;width:44px;height: 44px;} +.paytype-term .alipays{background: url(../img/pays-ali.png) center center no-repeat;background-size: 70%;} +.paytype-term .weixinpays{background: url(../img/pays-weixin.png) center center no-repeat;background-size: 70%;} +.paytype-term .unionpay{background: url(../img/pays-union.png) center center no-repeat;background-size: 70%;} +.first-time{font-size: 0.15rem;color: #abaaaa;padding-left: 5px;margin-top: 10px;} +.wst-re-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} +.ui-checkbox input:before, .ui-checkbox-s input:before{font-size: 24px;color:#ff3c3c;} +.ui-checkbox input:checked:before, .ui-checkbox-s input:checked:before{color:#ff3c3c;} +.wst-re-info{margin:0.08rem 0;padding:0.1rem;background-color:#fff;font-size: 0.15rem;} +.wst-re-info p{padding:0.05rem 0;color: #999;} +.wst-re-info .balance{padding-left:0.2rem;font-size: 0.13rem;color:#df0202;} +.wst-re-info .balance span{font-size: 0.15rem;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/security.css b/hyhproject/wechat2/view/default/css/security.css new file mode 100755 index 0000000..57f83ac --- /dev/null +++ b/hyhproject/wechat2/view/default/css/security.css @@ -0,0 +1,19 @@ +@CHARSET "UTF-8"; +.wst-se-l{margin-top:8px} +.wst-se-l .line{border-bottom:1px solid #edebeb} +.wst-se-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-se-l .pay{background:url(../img/icon_zhanghuanquan.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .phone{background:url(../img/icon_zhanghuanquan.png) 0 -53px no-repeat;background-size:97%} +.wst-se-pay{font-size:.18rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-se-pay .pay{padding-bottom:10px} +.wst-se-pay .pay input{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;font-size:.14rem;} +.wst-se-footer{position:fixed;width:100%;z-index:100;left:0;bottom:0} +.wst-se-footer .button{position:absolute;left:3%;bottom:10px;width:93%;margin-bottom:6px;font-size:.15rem;height:38px;line-height:38px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-se-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-se-pay .verify{border-radius:2px;margin-bottom:10px;border:1px solid #a0a0a0} +.wst-se-pay .verify input{width:60%;padding:2px 2px 2px 5px;height:36px;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.14rem;} +.wst-se-pay .verify button{float:right;height:36px;width:40%;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;font-size:.14rem;} +.wst-se-pay .verify img{float:right;height:36px;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-se-pay .phone{padding:10px;font-size:.15rem;} +.wst-se-back{padding:10px;font-size:.14rem;} +.wst-se-back a{color: #999;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/self_shop.css b/hyhproject/wechat2/view/default/css/self_shop.css new file mode 100755 index 0000000..a5dd27c --- /dev/null +++ b/hyhproject/wechat2/view/default/css/self_shop.css @@ -0,0 +1,84 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.ui-footer ~ .ui-container{border: 0px solid transparent;} +.wst-se-header2 .ui-icon-return {color: #59595c;} +.wst-se-header3{position: absolute;padding-left: 0;background: transparent;border-bottom: 0px;} +.wst-se-search2{width: 66%;margin-right: 23%;} +.wst-se-search2 input{background: rgba(255,255,255,0.5);} +.wst-se-search2 input::-webkit-input-placeholder {color:#fff;} +.wst-se-search2 input:-moz-placeholder {color:#fff;} +.wst-se-search2 input::-moz-placeholder {color:#fff;} +.wst-se-search2 inputt:-ms-input-placeholder {color:#fff;} +.wst-se-header3 .ui-icon-return,.wst-se-header3 .ui-icon-search{color: #fff;} +.wst-se-icon0{background: url(../img/classify.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2{right: 40px;background: url(../img/cart.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2 i{display: inline-block;text-align: center;background: #de0202;color: #fff;height: 15px;line-height: 15px;border-radius: 10px;padding: 0 5px;background-clip: padding-box;font-size: .1rem;position: absolute;top: 0;left: 20px;} +.wst-sh-banner{display: block;width:100%;height:1.7rem;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.shop-banner{width:100%;} +.shop-photo{position: relative;} +.shop-photo .photo{display: block;width:0.8rem;height:0.8rem;margin-left:0.1rem;padding:0.05rem;position: absolute;top:-0.42rem;background: #fff;border-radius: 3px;} +.shop-photo .photo img{width:100%;height:100%;border: 1px solid #f2f1f1;border-radius: 2px;} +.shop-photo .photo .name{position: absolute;left:-0.05rem;bottom:-0.28rem;width:2.6rem;font: 0.16rem/31px verdana;} +.shop-photo .introduce{float:right;margin:0.1rem 0.1rem 0 0;font-size:0.14rem;color:#de0202;} +.shop-info{padding-top:0.8rem;text-align:center;font-size:0.13rem;} +.shop-btn{float:left;margin-left: 0.11rem;margin-top: 0.05rem;width:30px;height:30px;background: url(../img/follow-shop.png) 1px 3px no-repeat;background-size: 200%;} +.shop-btn.follow{background: url(../img/follow-shop.png) -31px 3px no-repeat;background-size: 200%;} +.shop-notice{padding:0.1rem;font-size:0.13rem;border-bottom: 0.05rem solid #f2f1f1;} +.shop-notice .title{margin-bottom:0.05rem;font-size:0.15rem;} +.shop-ads{margin:5px auto;width:100%;} +.wst-gol-adsb{padding:0.05rem 0;height:110px;background:#fff;font-size:0.13rem;} +.wst-gol-adsb p{float:left;width:100%;color:#de0202;text-align:center} +.wst-gol-img{float:left;width:100%;height:100px;text-align:center;vertical-align:middle;display:block;position:relative;} +.wst-gol-img a{width:100%;height:100px;display:table-cell;vertical-align:middle} +.wst-gol-img a img{max-width:100px;max-height:100px} +.shop-floor-title{background:#fff;padding-left:5px;height:33px;line-height:33px;font-size:0.15rem;margin-bottom:0.04rem;} +.f0{border-left:3px solid #dc4bd1;color:#dc4bd1;} +.f1{border-left:3px solid #8a5063;color:#8a5063;} +.f2{border-left:3px solid #df2003;color:#df2003;} +.f3{border-left:3px solid lightblue;color:lightblue;} +.f4{border-left:3px solid #ff8043;color:#ff8043;} +.f5{border-left:3px solid #24b0ed;color:#24b0ed;} +.f6{border-left:3px solid green;color:green;} +.shop-more{float:right;margin-right:5px;display:inline-block;padding-right:20px;position: relative;} +.shop-more i{position: absolute;display: block;width:33px;height:33px;top:-6px;right:-7px;} +.wst-shl-head{background:#fff;font-size:.158rem;color:#6a6b6d} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:22px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;border-bottom:2px solid #de0202} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up{background:url(../img/img_jgsx.png) 0 -19px no-repeat;background-size:285%} +.wst-shl-head .sorts .up2{background:url(../img/img_jgsx.png) -28px -19px no-repeat;background-size:285%} +.wst-shl-head .sorts .down{background:url(../img/img_jgsx.png) 0 2px no-repeat;background-size:285%} +.wst-shl-head .sorts .down2{background:url(../img/img_jgsx.png) -28px 2px no-repeat;background-size:285%} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding:5px;margin-bottom:0.04rem;font-size:0.14rem;background:#fff;color: #232326; font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.05rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;text-decoration:line-through;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;height:100%;background:#f6f6f8;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;border-bottom:1px solid #f6f6f8;;background:#fff;height:41px;line-height:41px;text-align:center;font-size: 14px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-scrollerl{width:24%;height:100%;overflow:hidden;background:#fff;position:fixed} +.ui-scrollerl li{padding:13px 5px;font-size: 0.129rem;text-align:center} +.wst-goodscate{color: #232326;border-top: 1px solid #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #f6f6f8;} +.wst-goodscate_selected{color: #df0202;background: #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #df0202;} +.wst-scrollerr{width:76%;float:right} +.wst-scrollerr li{float:left;width:100%;font-size:.15rem;color:#000} +.wst-goodsca{height:35px;background:#f2f2f2;margin-bottom:8px;} +.wst-goodsca span{float:left;color: #232326;margin-top:8px;margin-left:8px;border-left:2px solid #fc786b;font-size: 0.13rem;} +.wst-goodsca i{float:right;height:35px;margin-top:-6px;color:#fc786b} +.wst-goodscat{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscats{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscat span{float:left;width:49%;padding:8px 0;text-align:center;background:#fff;border:0.01rem solid #f2f1f1;color: #686868;font-size: 0.12rem;} +.wst-goodscat span a{color:#69696b} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/settlement.css b/hyhproject/wechat2/view/default/css/settlement.css new file mode 100755 index 0000000..e5f7d42 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/settlement.css @@ -0,0 +1,85 @@ +@CHARSET "UTF-8"; +.ui-list-link > li:after{color:#848484;} +.wst-se-address{margin:10px 0px;padding-bottom:0.04rem;position: relative;} +.wst-se-address:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.04rem;background: url(../img/line-address.png) 0px 0px;-webkit-transform: scale(0.5);} +.wst-se-address .infot{color:#59595c;font-size:0.15rem;height: 22px;line-height: 22px;} +.wst-se-address .infob{font-size:0.158rem;position: relative;text-indent:1em;height: 23px;line-height: 23px;} +.wst-se-address .infob i{position: absolute;left:-23px;top:-12px;color:#df0001;} +.wst-se-address .infono{color:#f8a106;height: 36px;line-height: 36px;} +.wst-se-sh{padding:0px 10px 6px 10px;margin:5px 0px;font-size: 0.15rem;background:#ffffff;} +.wst-se-sh .shopn{padding:6px 0px 2px 20px;position: relative;} +.wst-se-sh .shopn i{position: absolute;display: block;bottom: 2px;left: 0;width: 20px;height: 20px;background: url(../img/icon_dp.png) 0px 1px no-repeat;background-size: 87%;} +.wst-se-sh .goods .img{float: left;width: 100%;height: 70px;text-align: center;vertical-align: middle;display: block;} +.wst-se-sh .goods{padding:5px 0px;border-bottom: 1px solid #f1f1f1;font-size:0.13rem;} +.wst-se-sh .goods .img a{width: 100%;height: 70px;display: table-cell;vertical-align: middle;} +.wst-se-sh .goods .img a img{max-width: 70px;max-height: 70px;} +.wst-se-sh .name{padding:0px 5px;} +.wst-se-sh .names{font-size: 0.14rem;} +.wst-se-sh .spec{color: #a6a6a6;} +.wst-se-sh .price,.wst-se-sh .number{text-align: right;font-size: 0.14rem;} +.wst-se-sh .remarks,.wst-se-sh .cost{padding:5px 0px;} +.wst-se-sh .cost span{float: right;color: #de0202;} +.wst-se-sh .remarks textarea{width:100%;height: 30px;padding: 5px;} +.wst-se-sh .remarks textarea:focus{height:58px;border:1px solid #3bb4f2;} +.wst-se-mode .mode{border-bottom: 1px solid #f1f1f1;} +.wst-se-mode .ui-txt-info{width:78%;text-align: right;} +.ui-list li h4 {font-size: 0.15rem;} +.wst-se-mode{font-size: 0.15rem;} +.wst-se-total{height: 38px;line-height: 38px;padding:0px 10px;font-weight: bold;font-size: 0.17rem;} +.wst-se-total span{float: right;color: #de0202;} +.wst-se-confirm .button{position: absolute;left:3%;bottom:2px;width: 93%;margin-bottom:6px;height: 38px;line-height: 38px;color:#ffffff;background:#e00102;font-size: 0.15rem;border-radius:3px;border-bottom:1px solid #e00102;} +.wst-se-confirm .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} +/*遮盖层*/ +.wst-cover{position:fixed;left:0px;top:0px;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60); /*设置透明度为60%*/opacity:0.6; /*非IE浏览器下设置透明度为60%*/z-Index:9999;display:none;} +/*参数弹框*/ +.wst-fr-box{position: fixed;z-index: 9999;left:0px;bottom: -226px;width:100%;min-height:40%;background-color: #f6f6f8;font-size: 0.15rem;} +.wst-fr-box .title{position: relative;padding:6px 0px;background-color: #ffffff;border-bottom: 1px solid #f1f1f1;} +.wst-fr-box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 15px;} +.wst-fr-box .title i,.wst-cart-box .title i{position: absolute;right:5px;top:-2px;font-size: 27px;} +.wst-fr-box .content{padding:8px 0px 50px 0px;} +.wst-fr-box .button,.wst-cart-box .button{position: absolute;left:3%;bottom:4px;width: 93%;height: 38px;line-height: 38px;color:#ffffff;background:#e00102;font-size: 0.15rem;border-radius:3px;border-bottom:1px solid #e00102;} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} +.wst-list-infose1{width:90%;padding-left: 0px;padding-top: 8px;padding-bottom: 8px;position: relative;} +.wst-list-infose1 span{float:left;width:100%;height: 20px;line-height: 20px;font-size:0.14rem;} +.wst-list-infose1 i{position: absolute;top:0;left:-13px;display: block;width:36px;height: 36px;} +.wst-list-infose1 .alipays{background: url(../img/pays-ali.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .weixinpays{background: url(../img/pays-weixin.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .cod{background: url(../img/pays-cod.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .wallets{background: url(../img/pays-wallets.png) center center no-repeat;background-size: 70%;} +.wst-list-infose1 .unionpay{background: url(../img/pays-union.png) center center no-repeat;background-size: 70%;} +.ui-list{position: relative;} +.ui-icon-push{position: absolute;top:0;right:0;width:32px;height: 36px;line-height: 36px;font-size: 0.32rem;} +.wst-se-line{padding:0px 10px;} +.wst-se-line p{border-bottom:1px solid #EDEDED;} +.wst-fr-invoice{padding:0px 10px;background: #ffffff;font-size:0.18rem;} +.wst-fr-invoice textarea{width: 100%;height: 46px;padding: 2px;} +.wst-fr-invoice textarea:focus{border:1px solid #3bb4f2;} +.wst-fr-score{padding-top:10px;} +.wst-fr-score span{color:#e00102;} +/* 发票信息层 */ +.invoice_box{position: fixed;z-index: 9999;right:-999px;bottom: 0px;width:100%;min-height:40%;background:#f2f2f2;font-size: 0.15rem;top:0;} +.invoice_box .title,.wst-cart-box .title{position: relative;padding:6px 0px;border-bottom: 1px solid #f1f1f1;background-color: #fff;} +.invoice_box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 16px;} +.invoice_box .title i,.wst-cart-box .title i{position: absolute;right:5px;top:-2px;font-size: 27px;} +.invoice_box .content{margin-top:5px;background:#f2f2f2;overflow: scroll;min-height: 80%;} +.inv_ul{margin-right: 15px;padding: 0 15px;position: relative;width: inherit;float: left;} +.pdtb10{padding: 10px 0;} +.inv_chk{position: absolute;left: 0;} +.inv_item{padding: 15px 10px;background-color: #fff;} +.inv_tit{color: #232326;font-size: 14px;padding-left: 5px;} +.inv_hidebox{background-color: #fff;width: 100%;position: relative;display: none;} +.inv_head_input{border: 0;border-radius: 3px;padding: 8px 0 8px 10px;width: 100%;color: #232326;font-size: 13px;background: #f0f2f5;padding-right: 30px;} +#inv_headlist{display: none;position: absolute;z-index: 3;width: 100%;background-color: #fff;} +.inv_list_item{width: 100%;background-color: #f0f2f5;} +.inv_list_item li{padding-left: 10px;line-height: 35px;border-top: 1px solid #e0e0e0;-webkit-line-clamp: 1;} +.inv_code_input{border: 0;border-radius: 3px;padding: 8px 0 8px 10px;height: 35px;width: 100%;color: #232326;font-size: 13px;background: #f0f2f5;padding-right: 30px;display: -webkit-box;} +.inv_code_input::-webkit-input-placeholder{color:#f23030} +.inv_code_input::-moz-placeholder{color:#f23030} +.inv_code_input::-ms-input-placeholder{color:#f23030} +.inv_code_inputbox{margin-top:10px} +.inv_line{padding-bottom: 5px;border-bottom: 1px solid #ccc;} +.none_float{float:inherit} +.inv_tip{padding: 15px 10px;} +.inv_tip li i{font-style: normal;font-size: 20px;font-weight: bold;margin-right: 5px;} +.invoice_box .button{position: absolute;left:3%;bottom:4px;width: 93%;font-size: 0.185rem;height: 40px;line-height: 40px;color:#ffffff;background:#e00102;font-size: 0.18rem;border-radius:3px;border-bottom:1px solid #e00102;} +.invoice_box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip: padding-box;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/shop_home.css b/hyhproject/wechat2/view/default/css/shop_home.css new file mode 100755 index 0000000..12f5c2b --- /dev/null +++ b/hyhproject/wechat2/view/default/css/shop_home.css @@ -0,0 +1,78 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.ui-footer ~ .ui-container{border: 0px solid transparent;} +.wst-se-header2 .ui-icon-return {color: #59595c;} +.wst-se-header3{position: absolute;padding-left: 0;background: transparent;border-bottom: 0px;} +.wst-se-search2{width: 66%;margin-right: 23%;} +.wst-se-search2 input{background: rgba(255,255,255,0.5);} +.wst-se-search2 input::-webkit-input-placeholder {color:#fff;} +.wst-se-search2 input:-moz-placeholder {color:#fff;} +.wst-se-search2 input::-moz-placeholder {color:#fff;} +.wst-se-search2 inputt:-ms-input-placeholder {color:#fff;} +.wst-se-header3 .ui-icon-return,.wst-se-header3 .ui-icon-search{color: #fff;} +.wst-se-icon0{background: url(../img/classify.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2{right: 40px;background: url(../img/cart.png) center center no-repeat;background-size: 60%;} +.wst-se-icon2 i{display: inline-block;text-align: center;background: #de0202;color: #fff;height: 15px;line-height: 15px;border-radius: 10px;padding: 0 5px;background-clip: padding-box;font-size: .1rem;position: absolute;top: 0;left: 20px;} +.wst-sh-banner{display: block;width:100%;height:1.7rem;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.shop-banner{width:100%;} +.shop-photo{position: relative;} +.shop-photo .photo{display: block;width:0.8rem;height:0.8rem;margin-left:0.1rem;padding:0.05rem;position: absolute;top:-0.42rem;background: #fff;border-radius: 3px;} +.shop-photo .photo img{width:100%;height:100%;border: 1px solid #f2f1f1;border-radius: 2px;} +.shop-photo .photo .name{position: absolute;left:-0.05rem;bottom:-0.28rem;width:2.6rem;font: 0.16rem/31px verdana;} +.shop-photo .introduce{float:right;margin:0.1rem 0.1rem 0 0;font-size:0.14rem;color:#de0202;} +.shop-info{padding-top:0.6rem;text-align:center;font-size:0.13rem;} +.shop-btn{float:left;margin-left: 0.11rem;margin-top: 0.05rem;width:30px;height:30px;background: url(../img/follow-shop.png) 1px 3px no-repeat;background-size: 200%;} +.shop-btn.follow{background: url(../img/follow-shop.png) -31px 3px no-repeat;background-size: 200%;} +.shop-notice{padding:0.1rem;font-size:0.13rem;border-bottom: 0.05rem solid #f2f1f1;} +.shop-notice .title{margin-bottom:0.05rem;font-size:0.15rem;} +.shop-ads{margin:0 auto;width:100%;} +.wst-sh-term{width:100%;border-bottom: 2px solid #ebebed;background:#fff;} +.wst-sh-term li{float:left;height:20px;padding:10px 20px;font: bold 0.155rem/20px verdana;background:#fff;color:#000;} +.wst-sh-term li.active{color:#de0202;} +.wst-sh-term.active{position: fixed;top:0;left:0;z-index:100;} +.wst-sh-index,.wst-sh-list{background: #f6f6f8;} +.wst-sh-index .index,.wst-sh-list .index{display: block;width:100%;} +.wst-sh-index .title{padding:0.1rem 0.1rem;font-size:0.15rem;background: #fff;border-bottom: 0.03rem solid #f6f6f8;} +.wst-sh-list{display:none;} +.wst-shl-head{background:#fff;font-size:.15rem;color:#6a6b6d;margin-bottom: 0.04rem;} +.wst-shl-head .sorts{position:relative} +.wst-shl-head .sorts p{height:22px;line-height:22px;padding:10px 15px 10px 0;text-align:center} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .sorts i{width:15px;height:15px;position:absolute;right:5px;top:13px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-sh-goods{height: calc(100% - 0.8rem);height: -webkit-calc(100% - 0.8rem);height: -moz-calc(100% - 0.8rem);height: -ms-calc(100% - 0.8rem);height: -o-calc(100% - 0.8rem);} +.wst-in-goods{float: left;width: 50%;box-sizing: border-box;padding:5px;margin-bottom:0.04rem;font-size:0.14rem;background:#fff;color: #232326;font-family: "Microsoft YaHei",Arial,Helvetica,sans-serif;} +.wst-in-goods.left{border-right: 0.02rem solid #f6f6f8;} +.wst-in-goods.right{border-left: 0.02rem solid #f6f6f8;} +.wst-in-goods .img{float:left;width:1.76rem;height:1.76rem;text-align:center;vertical-align:middle;display:block;position:relative} +.wst-in-goods .img a{width:1.76rem;height:1.76rem;display:table-cell;vertical-align:middle} +.wst-in-goods .img a img{max-width:1.76rem;max-height:1.76rem;} +.wst-in-goods .name{float:left;width:100%;height:0.33rem;margin-top:3px;line-height:0.17rem} +.wst-in-goods .info{float:left;width:100%;margin-top:0.05rem;} +.wst-in-goods .info .price{float:left;font-size:0.13rem;color:#e00102;} +.wst-in-goods .info .price span{font-size:0.166rem;} +.wst-in-goods .info2{float:left;width:100%;font-size:0.11rem;} +.wst-in-goods .info2 .price{float:left;color: #999;text-decoration:line-through;} +.wst-in-goods .info2 .deal{float:right;color: #999;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;top:0;width:100%;height:100%;background:#f6f6f8;} +.wst-fr-box .title,.wst-cart-box .title{position:relative;border-bottom:1px solid #f6f6f8;;background:#fff;height:41px;line-height:41px;text-align:center;font-size: 14px;} +.wst-fr-box .title i,.wst-cart-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .button,.wst-cart-box .button{position:absolute;left:3%;bottom:0;width:93%;font-size:.185rem;height:40px;line-height:40px;color:#fff;background:#e00102;border-bottom:1px solid #e00102} +.wst-fr-box .button:not(.disabled):not(:disabled):active,.wst-cart-box .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.ui-scrollerl{width:24%;height:100%;overflow:hidden;background:#fff;position:fixed} +.ui-scrollerl li{padding:13px 5px;font-size: 0.129rem;text-align:center} +.wst-goodscate{color: #232326;border-top: 1px solid #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #f6f6f8;} +.wst-goodscate_selected{color: #df0202;background: #f6f6f8;border-right: 1px solid #f6f6f8;border-left: 2px solid #df0202;} +.wst-scrollerr{width:76%;float:right} +.wst-scrollerr li{float:left;width:100%;font-size:.15rem;color:#000} +.wst-goodsca{height:35px;background:#f2f2f2;margin-bottom:8px;} +.wst-goodsca span{float:left;color: #232326;margin-top:8px;margin-left:8px;border-left:2px solid #fc786b;font-size: 0.13rem;} +.wst-goodsca i{float:right;height:35px;margin-top:-6px;color:#fc786b} +.wst-goodscat{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscats{float:left;width:94%;padding:0 0 12px 8px} +.wst-goodscat span{float:left;width:49%;padding:8px 0;text-align:center;background:#fff;border:0.01rem solid #f2f1f1;color: #686868;font-size: 0.12rem;} +.wst-goodscat span a{color:#69696b} +.pd0{padding-right:6px!important} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/shops.css b/hyhproject/wechat2/view/default/css/shops.css new file mode 100755 index 0000000..55d7f23 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/shops.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +.wst-shop{padding-top:5px} +.wst-shop-home-bg{margin:0 auto;width:100%;height:190px;background:url(../img/default_shopbanner.png) center top no-repeat;background-size:cover} +.wst-shop-photo{width:50px;height:50px;margin:0 auto;padding-top:20px;padding-bottom:10px;} +.wst-shop-photo img{width:100%;height:100%;border-radius:50%} +.wst-shop-name{font-size:0.19rem} +.wst-shop-name{width:100%;height:30px;text-align:center;color:#fff} +.shop-home-btn-box{width:70%;margin:10px auto;height:30px} +.shop-home-btn img{position:absolute;width:16px;height:15px;margin-top:4px;left:8px} +.shop-home-btn{position:relative;background:transparent;height:25px;line-height:25px;color:#fff;border:1px solid #fff;padding:0!important;font-size:.13rem;width:25px;padding-left:8px!important} +.shop-home-btn:before{border: none;} +.shop-home-btn:not(.disabled):not(:disabled):active{background:transparent;color:fff;} +.f-btn,.f-btn:not(.disabled):not(:disabled):active{background:#fff;color:#e8121e} +.f-btn:before{border: none;} +.score-box{margin:0 auto;width:100%;height:35px;margin-top:10px} +.score-item{color:#fff;padding-top:5px;text-align:center;font-size:.13rem;} +.wst-shop-home-info{margin-top:10px;font-size:.14rem;width:100%;height:300px} +.wst-shop-home-view{margin-top:8px;width:100%;height:80px;position:fixed} +.shop-info li{padding:0.08rem 0.1rem;border-bottom:1px solid #e7e7e7} +.shop-qrcode{margin-top:30px;text-align:center} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/shops_list.css b/hyhproject/wechat2/view/default/css/shops_list.css new file mode 100755 index 0000000..8e3d2b9 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/shops_list.css @@ -0,0 +1,49 @@ +@CHARSET "UTF-8"; +.wst-shl-adsb{padding:0.05rem 0;height:110px;background:#fff;} +.wst-shl-adsb img{width:100%;height:100%;display:block} +.wst-shl-head{background:#fff;font-size:0.14rem;color:#232326;} +.wst-shl-head .choice{width:65%;height:20px;line-height:22px;margin:0 auto;padding:9px 0} +.wst-shl-head .active{color:#de0202;} +.wst-shl-head .active select{color:#de0202} +.wst-shl-select select{color:#232326;;padding-right:0} +.wst-shl-select:after{color:#232326;} +.wst-shl-select.active:after{color:#de0202} +.ui-select:after{display:none} +.wst-shl-head .evaluate{text-align:center;position:relative} +.wst-shl-head .evaluate i{width:15px;height:15px;position:absolute;right:36px;top:12px} +.wst-shl-head .sorts .up2{background: url(../img/img_jgsx.png) 4px -15px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down{background: url(../img/img_jgsx.png) 4px -32px no-repeat;background-size: 46%;} +.wst-shl-head .sorts .down2{background: url(../img/img_jgsx.png) 4px 2px no-repeat;background-size: 46%;} +.wst-current{color:#e77f74} +.wst-shl-list{padding:5px 10px;margin-top:5px;background:#fff; } +.wst-shl-list .img{width: 100%; float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.wst-shl-list .img a{width:100%;height:55px;display:table-cell;vertical-align:middle; } +.wst-shl-list .info{padding-left:16px} +.wst-shl-list .title{margin-bottom:0;font-size:0.11rem;color:#363638;font-weight: bold;} +.wst-shl-list p{font-size:0.10rem;height:0.2rem;} +.wst-shl-list p img{width:0.16rem} +.wst-shl-list p span{float:left} +.wst-shl-list p i{float:left;width:0.12rem;height:0.16rem;margin:0.01rem 0.03rem 0 0} +.wst-shl-list p .bright{background:url(../img/img_dpjpj.png) 0 0 no-repeat;background-size:300%} +.wst-shl-list p .dark{background:url(../img/img_dpjpj.png) -0.3rem 0 no-repeat;background-size:300%} +.wst-brands{float:left;width:50%;height:1rem;margin-top:10px;padding:0 0.1rem;box-sizing:border-box} +.wst-brands.left{padding-right:0.05rem;} +.wst-brands.right{padding-left:0.05rem;} +.wst-brands_img{height:0.8rem;padding:5px 0 5px 2px;background:#fff;box-shadow:0 1px 2px #f1f0f0} +.wst-brands_img a{width:100%;height:0.8rem;text-align:center;display:table-cell;vertical-align:middle} +.wst-brands img{max-width:0.9rem;max-height:0.8rem;border-radius:3px} +.wst-brands span{float:left;font-size:0.13rem;line-height:0.8rem;width:0.65rem;height:0.8rem;margin-left:4px;padding:0 0.05rem;border-left:1px solid #e6e6e6;} +.goods-box{padding:0!important;} +.goodsImg a{width:100%;height:70px;display:table-cell;vertical-align:middle; } +.goodsImg img{width:70px;height:70px; } +.goods-item{margin-right: 5px;width:24%; position: relative;float:left;text-align:center;vertical-align:middle;display:block;position:relative;font-size:0.15rem;} +.goodsPrice{color:red;} +.shop-box{margin:10px 0;background:#fff} +.f-chk{position:absolute;top:85px;left:0} +.s-active{top:-90px;left:-10px} +.f-shop-header img{max-height:60px;max-width:60px;width:60px;height:60px} +.f-shop-header{position:relative;padding:10px 0;min-height:75px!important} +.ui-row-flex-ver .ui-col{width:100%;height:initial} +.f-shopname{float:left;line-height:25px;font-size:.16rem} +.f-goshops{float:right;text-align:right;color:#ccc;font-size:.15rem;height: 20px;} +.wst-action{margin-top: 5px; ;display: inline-block;height: 25px;width: 90%;font-size: 0.14rem;color: red; line-height: 25px;text-align: center;border-radius: 10px;border: 1px solid red;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/swiper.min.css b/hyhproject/wechat2/view/default/css/swiper.min.css new file mode 100755 index 0000000..b7d8cc7 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/swiper.min.css @@ -0,0 +1,15 @@ +/** + * Swiper 3.1.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2015, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: August 22, 2015 + */ +.swiper-container{margin:0 auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:300ms;-moz-transition:300ms;-o-transition:300ms;transition:300ms;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination{bottom:10px;left:0;width:100%}.swiper-container-horizontal>.swiper-pagination .swiper-pagination-bullet{margin:0 5px}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper{-ms-perspective:1200px}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube{overflow:visible}.swiper-container-cube .swiper-slide{pointer-events:none;visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;width:100%;height:100%;z-index:1}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/user.css b/hyhproject/wechat2/view/default/css/user.css new file mode 100755 index 0000000..48ac376 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/user.css @@ -0,0 +1,100 @@ +@CHARSET "UTF-8"; +body{background:#f5f5f5} +.wst-users_info{background: url(../img/user.png) center top no-repeat;background-size: cover;padding:0.5rem 0;color:#fff;position: relative;} +.wst-users_infol{float:left;margin-left: 0.28rem;} +.wst-users_infol img{width:0.67rem;border-radius:1000px;border: 2px solid #f2f1f1;} +.wst-users_infor{float:left;width:55.666%;padding-left:0.1rem;} +.wst-msg-icon{position: absolute;display: block;right:0.15rem;top:0.1rem;width:26px;height:25px;background: url(../img/message-icon.png) center center no-repeat;background-size: 80%;} +.wst-msg-icon .number{position: absolute;top:-0.03rem;right:-0.1rem;min-width:0.16rem;display: inline-block;text-align: center;background: #f74c31;color: #fff;font-size: 0.1rem;height: 15px;line-height: 15px;-webkit-border-radius: 8px;padding: 0 3px;background-clip: padding-box;} +.wst-info-icon{position: absolute;top:0.1rem;right:0.5rem;width:26px;height:26px;line-height: 26px;color: #fff;font-size: 0.28rem;} +.wst-users_infortop{margin-top:9px;font-size:.16rem;} +.wst-users_infortop img{position: relative;top:2px;left:5px;width: 15px;height: 15px;} +.wst-users_inforbo{font-size:.13rem;} +.wst-users_icon{padding:0.15rem 0;background:#FFF;} +.wst-users_icon span{font-size:.13rem} +.wst-users_icon p{margin:0 auto;width:38px;height:36px} +.wst-users_icon p i{float:left;width:38px;height:36px} +.wst-users_capital{padding:0.15rem 0;background:#FFF;} +.wst-users_capital p{font-size: 0.165rem;color: #ec5151;padding:0 0.1rem ;} +.wst-users_capital span{font-size:.13rem} +.wst-us-sign{float:left;width:100%;height:100%;position: relative;} +.wst-us-sign .sign{position: absolute;right:0;bottom:0;width:62px;height:39px;margin-right:0.1rem;background: url(../img/sign-icon.png) center center no-repeat;background-size: cover;} +.wst-us-sign .sign2{background: url(../img/sign-icon2.png) center center no-repeat;background-size: cover;} +.user-order{margin-top:0.1rem;font-size:0.15rem;background:#ffffff;} +.user-order .order-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-order-icon.png) no-repeat;background-size:cover;} +.user-order .wallet-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-wallet-icon.png) no-repeat;background-size:cover;} +.user-order .tool-icon{float:left;width:17px;height:17px;margin-right:5px;background:url(../img/user-tool-icon.png) no-repeat;background-size:cover;position: relative;top:1px;} +.user-order .order{margin-left:0.1rem;padding:0.1rem 0.1rem 0.1rem 0;line-height: 0.22rem;border-bottom:1px solid #f2f1f1;} +.view-order{text-align:right;padding-right:5px;font-size:.13rem;color:#a2a0a0} +.wst-users_icon1,.wst-users_icon2,.wst-users_icon3,.wst-users_icon4,.wst-users_icon5{background:url(../img/users_icon.png) no-repeat;background-size:963%} +.wst-users_icon1{background-position:-29px -7px} +.wst-users_icon2{background-position:-94px -7px} +.wst-users_icon3{background-position:-159px -7px} +.wst-users_icon4{background-position:-224px -7px} +.wst-users_icon5{background-position:-289px -7px} +.wait-payment{height:16px;line-height:16px;font-size:.11rem!important;position:absolute;left:24px;top:-3px;min-width:16px;text-align:center;border-radius:5px;color:#fff;background:#de0202;padding:0;border-radius:50%;right:0} +.msg-red-icon{top:-53px;left:57px} +.border-b{border-bottom:1px solid #e7e7e7} +.user-icon-box{padding:5px 0;min-width:24%;min-height:85px;padding-bottom:5px;background:#fff;} +.user-icon-box span{font-size:0.13rem} +.user-icon-box:active{background:#e7e7e7!important} +.user-icon-box p{margin:0 auto;width:39px;height:42px} +.user-icon-box i{float:left;width:38px;height:38px} +.user-icon1,.user-icon2,.user-icon3,.user-icon4,.user-icon5,.user-icon6,.user-icon7,.user-icon8,.user-icon9,.user-icon10,.user-icon11{background:url(../img/img_users_icon.png) no-repeat;background-size:1050%} +.user-icon1{background-position:-31px -18px} +.user-icon2{background-position:-130px -18px} +.user-icon3{background-position:-206px -14px;background-size:945%} +.user-icon4{background-position:-292px -13px;background-size:938%} +.user-icon5{background-position:-28px -110px;background-size:988%} +.user-icon6{background-position:-125px -112px;background-size:1008%} +.user-icon7{background-position:-210px -139px} +.user-icon8{background-position:-300px -139px} +.user-icon9{background-position:-25px -191px;background-size:927%} +.user-icon10{background-position:-119px -199px} +.user-icon11{background-position:-204px -192px;background-size:943%} +.wst-users_list{border-top:2px solid #ededed} +.wst-users_list1{border-top:2px solid #ededed;border-bottom:2px solid #ededed} +.wst-list-thumb-sus{width:50px;height:50px;position:relative} +.wst-list-thumb-sus>span{display:block;width:100%;height:100%;z-index:1;background-repeat:no-repeat;-webkit-background-size:cover} +.ui-list>li{margin-left:0} +.wst-users_chart1{background:url(../img/mine-icon.png) 2px 0 no-repeat} +.wst-users_chart2{background:url(../img/mine-icon.png) -46px 0 no-repeat} +.wst-users_chart3{background:url(../img/mine-icon.png) -100px 0 no-repeat} +.wst-users_chart4{background:url(../img/mine-icon.png) -149px 0 no-repeat} +.wst-users_chart5{background:url(../img/mine-icon.png) -199px 0 no-repeat} +.wst-users_chart6{background:url(../img/mine-icon.png) -246px -1px no-repeat} +.wst-users_chart7{background:url(../img/mine-icon.png) -292px -1px no-repeat} +.ui-badge-corner{border:0} +.wst-message_icon{position:absolute;height:19px;line-height:19px;font-size:12px;min-width:19px;-webkit-border-radius:10px;top:17px;left:110px;display:inline-block;text-align:center;background:#f74c31;color:#fff;font-size:11px;height:16px;line-height:16px;-webkit-border-radius:8px;padding:0 6px;background-clip:padding-box} +.wst-lo-choice{margin:50px 20px 0 20px;border-radius:10px;padding-bottom:20px;font-size:.158rem} +.wst-lo-choice .img{text-align:center} +.wst-lo-choice .img img{width:65px;border:2px solid #d4d3d3;border-radius:1000px;padding:2px} +.wst-lo-choice .name{height:50px;line-height:50px;text-align:center;font-weight:bolder} +.wst-lo-choice .prompt{height:20px;line-height:20px;text-align:center;padding-bottom:42px} +.wst-lo-choice .choice{text-align:center} +.wst-lo-choice .choice .button0{width:100%;height:38px;border-radius:1000px;font-size:.159rem;color:#fff;background:#04be02} +.wst-lo-choice .choice .button0:not(.disabled):not(:disabled):active{color:#f7fdf7;background:#06c804;background-clip:padding-box} +.wst-lo-choice .choice .button1{width:100%;height:38px;border-radius:1000px;font-size:.159rem;color:#59595c;background:#fff;border:1px solid #d4d3d3;margin-top:10px} +.wst-lo-choice .choice .button1:not(.disabled):not(:disabled):active{color:#56565d;background:#f8f7f7;background-clip:padding-box} +.wst-lo-frame{font-size:.18rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-lo-frame .frame{padding:0.05rem 0px;position: relative;} +.wst-lo-frame .frame:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.01rem;background: #d9d9d9;-webkit-transform: scale(0.5);} +.wst-lo-frame .frame input{width:100%;padding-left:5px;height:0.38rem;border:0;font-size:.15rem;} +.wst-lo-frame .verify{padding:0.05rem 0px;border:0;position: relative;} +.wst-lo-frame .verify:after {content: '';position: absolute;bottom: 0;left: -50%;width: 200%;height: 0.01rem;background: #d9d9d9;-webkit-transform: scale(0.5);} +.wst-lo-frame .verify input{width:60%;padding-left:5px;height:0.38rem;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.15rem;} +.wst-lo-frame .verify button{float:right;height:0.36rem;line-height: 0.36rem;width:40%;font-size:.14rem;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;background-color: #ffffff;background-image:none;color:#ff3c3c;border:1px solid #ff3c3c;} +.wst-lo-frame .verify button:not(.disabled):not(:disabled):active{background-color: #ffffff;color:#df0202;border:1px solid #df0202;} +.wst-lo-frame .verify img{float:right;height:0.36rem;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-lo-button{padding:30px 10px 0 10px} +.wst-lo-button .button{width:100%;bottom:10px;margin-bottom:6px;height:0.45rem;line-height:0.45rem;color:#fff;background:#ff3c3c;font-size:.15rem;border-radius:3px;border:1px solid #ff3c3c;} +.wst-lo-button .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-lo-agreement{position: relative;height:20px;line-height:20px;padding: 12px 10px 10px 35px;font-size:.14rem;} +.wst-lo-agreement i{position: absolute;top:-1px;left:5px;} +.wst-lo-agreement span{color: #ff3c3c;} +.wst-fr-protocol{position: fixed; z-index: 9999; right: -999px; top:0px; width: 100%; height: 100%; background: #ffffff; font-size: 0.15rem; color:#000;} +.wst-fr-protocol .title{height: auto;color: #222;position: relative;background: #ffffff;border-bottom: 1px solid #e8e8e8;} +.wst-fr-protocol .title span{float: left;width: 100%;height: 41px;line-height: 41px;text-align: center;font-size: 16px;} +.wst-fr-protocol .title i{position: absolute;right:5px;top:-1px;color: #222;font-size: 27px;} +.wst-fr-protocol .content{padding:10px;} +.wst-fr-protocol .content img{width: 100%;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/userinfo.css b/hyhproject/wechat2/view/default/css/userinfo.css new file mode 100755 index 0000000..4028511 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/userinfo.css @@ -0,0 +1,26 @@ +@CHARSET "UTF-8"; +.wst-useri_portrait{margin-top:-10px;width:65px;border-radius:1000px} +.wst-useri_line{border-bottom:1px solid #ededed} +.uploadfile-input{width:35%;height:90px;position:absolute;right:0;top:0;opacity:0;z-index:100} +.wst-useri_determine{position:relative;font-size:16px;height:44px;line-height:44px;padding-right:26px;padding-left:15px;font-size:.18rem;padding-top:7px;padding-bottom:7px;margin-top:6px} +.wst-useri_determine input{float:left;width:100%;height:40px;border:1px solid #ccc;border-radius:6px;padding-left:8px;font-size:.15rem} +.wst-listse li{border-bottom:1px solid #ededed} +.wst-list-infose1{width:90%;padding-top:12px;padding-bottom:12px;} +.wst-list-infose1 span{float:left;width:100%;font-size:.15rem} +.wst-list-infose2{float:right;width:32px;margin-top:-45px} +.wst-icon-checked-s_se{color:#de0301} +.wst-fav_search{height:30px;width:62%;float:left;background:#FFF;border:1px solid #ccc;border-radius:15px;-webkit-box-sizing:border-box;-webkit-box-pack:center;margin-left:50px;margin-top:8px} +.wst-fav_search span{width:25px;float:left;margin-top:-7px} +.wst-fav_search input{float:left;width:80%;margin-top:6px;border:0} +.wst-fav_searchs{font-size:.17rem;margin-right:8px;line-height:45px;float:right;color:#FFF} +.wst-fav_list{margin-top:5px;border-bottom:1px solid #ddd} +.wst-fav_listl{width:85px;margin:0 auto} +.wst-fav_listl img{width:85px;height:85px} +.wst-fav_listr button{float:right;color:#504f4f;width:74px;background:#e6e6e6} +.wst-fav_listr1{margin-top:8px;font-size:.16rem} +.wst-fav_listr2{height:30px;color:#ef641f;font-size:.2rem;margin-bottom:3px} +.wst-fav_listr2 span{float:right;width:30px;height:30px} +.wst-fav_listr2 img{width:30px;height:30px} +.wst-fav_listr button:not(.disabled):not(:disabled):active,.wst-fav_listr button.active{background:#b7ada9;border-color:#e6e6e6;color:#504f4f;background-clip:padding-box} +.wst-ed-info li,.wst-ed-info li h4{font-size:.15rem;} +.wst-ed-button{height: 38px;line-height: 38px;font-size: 0.15rem;color: #fff;background: #e00102;border-radius: 3px;border-bottom: 1px solid #e00102;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/userscores.css b/hyhproject/wechat2/view/default/css/userscores.css new file mode 100755 index 0000000..ef25450 --- /dev/null +++ b/hyhproject/wechat2/view/default/css/userscores.css @@ -0,0 +1,20 @@ +@CHARSET "UTF-8"; +.head{min-height:77px;color:#fff;background:url(../img/icon_userscores.png) no-repeat;background-size:cover;} +.head-btn{padding:0 75px;font-size:15px} +.user_scores{font-size:0.16rem;margin-top: 20px;} +.user_scores p{text-align: right;} +.ui-btn-lg{font-size:14px;height:24px;line-height:23px;display:block;width:100%;border-radius:3px;background:transparent;border:1px solid #fff;color:#fff} +.ui-btn-lg:active{background:#fff!important;border:1px solid #ff5e45!important;color:#ff5e45!important} +.score-detail{padding:10px} +.score-detail-title{padding:10px;font-size:.15rem;border-bottom:1px solid #eaeaea;font-weight: bold;} +.score-reduce{font-weight:bold;padding:15px 0;text-align:right;color:#18c328;font-size:.14rem;} +.score-plus{font-weight:bold;padding:15px 0;text-align:right;color:#f81d1d;font-size:.14rem;} +.score-line{border-bottom:1px solid #eaeaea;margin-bottom:5px;margin-top:8px} +.wst-re-info{font-size:.14rem;position: relative;padding-bottom:0.2rem;} +.score-time{position: absolute;bottom:0;left:0;color:#8c8c8c;font-size:0.12rem;} +.wst-cover{position:fixed;left:0;top:0;background-color:#000;width:100%;height:100%;filter:alpha(opacity=60);opacity:.6;z-Index:9999;display:none} +.wst-fr-box{position:fixed;z-index:9999;right:-999px;bottom:0;width:100%;min-height:40%;background-color:#f6f6f8;font-size:.15rem} +.wst-fr-box .title{height: auto;background: #fff;position: relative;padding: 6px 0;border-bottom: 1px solid #f1f1f1;} +.wst-fr-box .title span{float: left;width: 100%;height: 26px;line-height: 26px;text-align: center;font-size: 14px;} +.wst-fr-box .title i{position:absolute;right:5px;top:-2px;font-size:27px} +.wst-fr-box .content{padding:5px 5px 5px 5px;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/css/userset.css b/hyhproject/wechat2/view/default/css/userset.css new file mode 100755 index 0000000..2dd356b --- /dev/null +++ b/hyhproject/wechat2/view/default/css/userset.css @@ -0,0 +1,37 @@ +@CHARSET "UTF-8"; +body{background: #fff;} +.wst-se-l .line{border-bottom:1px solid #edebeb} +.wst-se-l span{width:23px;height:23px;display:block;margin-right:6px} +.wst-se-l .pay{background:url(../img/icon_user_info.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .safety{background:url(../img/icon_user_safety.png) 0 0 no-repeat;background-size:97%} +.wst-se-l .about{background:url(../img/icon_user_about.png) 0 0 no-repeat;background-size:97%} +.wst-se-pay{font-size:.18rem;margin-top:8px;padding:12px 10px 2px 10px;background:#fff} +.wst-se-pay .pay{padding-bottom:10px} +.wst-se-pay .pay input{width:100%;padding:2px 2px 2px 5px;height:36px;border-radius:2px;border:1px solid #a0a0a0;font-size:.14rem;} +.wst-se-footer{position:fixed;width:100%;z-index:100;left:0;bottom:0} +.wst-se-footer .button{position:absolute;left:3%;bottom:10px;width:93%;margin-bottom:6px;font-size:.15rem;height:38px;line-height:38px;color:#fff;background:#e00102;border-radius:3px;border-bottom:1px solid #e00102} +.wst-se-footer .button:not(.disabled):not(:disabled):active{color:#fff0f0;background:#f52f30;background-clip:padding-box} +.wst-se-pay .verify{border-radius:2px;margin-bottom:10px;border:1px solid #a0a0a0} +.wst-se-pay .verify input{width:60%;padding:2px 2px 2px 5px;height:36px;border-top-left-radius:2px;border-bottom-left-radius:2px;border:0;font-size:.14rem;} +.wst-se-pay .verify button{float:right;height:36px;width:40%;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;font-size:.14rem;} +.wst-se-pay .verify img{float:right;height:36px;width:40%;border-top-right-radius:2px;border-bottom-right-radius:2px} +.wst-se-pay .phone{padding:10px;font-size:.15rem;} +.wst-se-back{padding:10px;font-size:.14rem;} +.wst-se-back a{color: #999;} +.logout{padding: 0.1rem 1.1rem; margin-top: 20px;} +.logout-btn {font-size: .15rem;height: 30px;line-height: 30px;background: #e00102;border-bottom: 1px solid #e00102;} +.wst-about{width: 99.2%;height: auto;} +.wst-about p{text-align: center;font-size: .15rem;color: #777;font-weight: bold;} +.wst-about .wst-brand{width: 120px;height: 60px;margin: 60px auto;margin-bottom: 10px;} +.wst-about .wst-brand img{width: 100%;height: 100%;} +.wst-about .wst-version{width: 100%;height: 20px;} +.wst-border{width:70%; height:1px;margin:0 auto;background: #eee;margin-top: 20px;} +.wst-about .wst-left{width: 23%;height:100%;display: inline-block; } +.wst-about .wst-center{text-align: center; width: 46%;overflow: hidden; white-space: nowrap; display: inline-block;line-height: 40px;font-size: 14px;color: #777; } +.wst-about .wst-right{width: 23%;height:100%;display: inline-block; } +.wst-about span{width:20px;height:20px;display:block;margin-left: 14px; margin-right:6px;} +.phone{background:url(../img/custom.png) 0 0 no-repeat;background-size:97%;} +.qq{background:url(../img/qq.png) 0 0 no-repeat;background-size:97%;} +.email{background:url(../img/email.png) 0 3px no-repeat;background-size:97%;} +.belong{background:url(../img/copy.png) 0 1px no-repeat;background-size:97%;} +.wst-contact{width: 90%;margin: 0 auto;float: right;} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/dialog.html b/hyhproject/wechat2/view/default/dialog.html new file mode 100755 index 0000000..a2a64f6 --- /dev/null +++ b/hyhproject/wechat2/view/default/dialog.html @@ -0,0 +1,15 @@ +{/* 对话框 prompt */} +<div class="ui-dialog" id="wst-di-prompt"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <p id="wst-dialog" class="wst-dialog-t">提示</p> + <p class="wst-dialog-l"></p> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event2" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </div> + </div> +</div> +{/* 提示分享对话框 share */} +<div class="ui-dialog" id="wst-di-share" onclick="WST.dialogHide('share');"> + <div class="wst-prompt"></div> +</div> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/error_lost.html b/hyhproject/wechat2/view/default/error_lost.html new file mode 100755 index 0000000..f26913e --- /dev/null +++ b/hyhproject/wechat2/view/default/error_lost.html @@ -0,0 +1,22 @@ +{extend name="default/base" /} +{block name="title"}提示信息 - {__block__}{/block} +{block name="header"} + {php}$Title = "提示信息"{/php} + {include file="default/header" /} +{/block} +{block name="main"} +<section class="ui-container" id="errorLostBg" style="height:69%;position:relative;"> + <p>{if(isset($message))}{$message}{else}对不起你要找的商品不见了~~o(>_<)o~~{/if}</p> + <div class="ui-btn-wrap"> + <button class="ui-btn-s" id="errorBtn" onclick="history.back()"> + 返回上一页 + </button> + </div> +</section> + +{/block} +{block name="js"} +<script> +$(function(){WST.initFooter();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/error_switch.html b/hyhproject/wechat2/view/default/error_switch.html new file mode 100755 index 0000000..3002732 --- /dev/null +++ b/hyhproject/wechat2/view/default/error_switch.html @@ -0,0 +1,15 @@ +<html> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"> +<meta name="format-detection" content="telephone=no"> +<title>提示信息 - {:WSTConf('CONF.mallName')}</title> +<link rel="stylesheet" href="__WECHAT__/frozenui/css/frozen.css"> +<link rel="stylesheet" href="__WECHAT__/css/common.css?v={$v}"> +</head> +<body ontouchstart=""> +<section class="ui-container" id="errorLostBg" style="height:69%;position:relative;"> + <p>{if(WSTConf('CONF.seoMallSwitchDesc'))}{:WSTConf('CONF.seoMallSwitchDesc')}{else}商城暂时关闭{/if}</p> +</section> +</body> +</htm \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/error_sys.html b/hyhproject/wechat2/view/default/error_sys.html new file mode 100755 index 0000000..a87645c --- /dev/null +++ b/hyhproject/wechat2/view/default/error_sys.html @@ -0,0 +1,21 @@ +{extend name="default/base" /} +{block name="title"}系统出错了 - {__block__}{/block} +{block name="header"} + {php}$Title = "系统出错了"{/php} + {include file="default/header" /} +{/block} +{block name="main"} +<section class="ui-container" id="errorBg" style="height:69%;position:relative;"> + <div class="ui-btn-wrap"> + <button class="ui-btn-s" id="errorBtn" onclick="history.back()"> + 返回上一页 + </button> + </div> +</section> + +{/block} +{block name="js"} +<script> +$(function(){WST.initFooter();}) +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/footer.html b/hyhproject/wechat2/view/default/footer.html new file mode 100755 index 0000000..8d9affb --- /dev/null +++ b/hyhproject/wechat2/view/default/footer.html @@ -0,0 +1,26 @@ + {/* 小加载 */} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:43px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> + </div> + {php}$cartNum = WSTCartNum();{/php} + <div class="ui-row-flex wst-menus"> + <div class="ui-col ui-col"><a href="{:url('wechat/index/index')}"><p id="home"></p></a></div> + <div class="ui-col ui-col"><a href="{:url('wechat/goodscats/index')}"><p id="category"></p></a></div> + <div class="ui-col ui-col carsNum"><a href="{:url('wechat/carts/index')}"><p id="cart"> + </p></a>{if($cartNum>0)}<i>{php} echo $cartNum;{/php}</i>{/if}</div> + <div class="ui-col ui-col"><a href="{:url('wechat/favorites/goods')}"><p id="follow"></p></a></div> + <div class="ui-col ui-col"><a href="{:url('wechat/users/index')}"><p id="user"></p></a></div> + </div> + </footer> + {:hook('initCronHook')} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/frozenui/css/frozen.css b/hyhproject/wechat2/view/default/frozenui/css/frozen.css new file mode 100755 index 0000000..25180e0 --- /dev/null +++ b/hyhproject/wechat2/view/default/frozenui/css/frozen.css @@ -0,0 +1,2972 @@ +@charset "UTF-8"; +@media screen and (max-width: 319px) { + html { + font-size: 85.33333px; } } +@media screen and (min-width: 320px) and (max-width: 359px) { + html { + font-size: 85.33333px; } } +@media screen and (min-width: 360px) and (max-width: 374px) { + html { + font-size: 96px; } } +@media screen and (min-width: 375px) and (max-width: 383px) { + html { + font-size: 100px; } } +@media screen and (min-width: 384px) and (max-width: 399px) { + html { + font-size: 102.4px; } } +@media screen and (min-width: 400px) and (max-width: 413px) { + html { + font-size: 106.66667px; } } +@media screen and (min-width: 414px) { + html { + font-size: 110.4px; } } +/*CSS Reset*/ +body, +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +code, +form, +fieldset, +legend, +input, +textarea, +p, +blockquote, +th, +td, +header, +hgroup, +nav, +section, +article, +aside, +footer, +figure, +figcaption, +menu, +button { + margin: 0; + padding: 0; } + +body { + font-family: "Helvetica Neue",Helvetica,STHeiTi,sans-serif; + line-height: 1.5; + font-size: 16px; + color: #000; + background-color: #f8f8f8; + -webkit-user-select: none; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; + outline: 0; } + +h1, h2, h3, h4, h5, h6 { + font-size: 100%; + font-weight: normal; } + +table { + border-collapse: collapse; + border-spacing: 0; } + +caption, th { + text-align: left; } + +fieldset, +img { + border: 0; } + +li { + list-style: none; } + +ins { + text-decoration: none; } + +del { + text-decoration: line-through; } + +input, +button, +textarea, +select, +optgroup, +option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; + outline: 0; } + +button { + -webkit-appearance: none; + border: 0; + background: none; } + +a { + -webkit-touch-callout: none; + text-decoration: none; } + +:focus { + outline: 0; + -webkit-tap-highlight-color: transparent; } + +em, i { + font-style: normal; } + +@font-face { + font-family: "iconfont"; + src: url(../font/iconfont.ttf) format("truetype"); } +.ui-icon, [class^="ui-icon-"] { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); } + +.ui-icon-close:before { + content: ""; } + +.ui-icon-search:before { + content: ""; } + +.ui-icon-return:before { + content: ""; } + +.ui-icon-close, +.ui-icon-search { + color: #8e8e93; } + +@font-face { + font-family: "iconfont"; + src: url(../font/iconfont-full.ttf) format("truetype"); } +.ui-icon, [class^="ui-icon-"] { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); } + +.ui-icon-add:before { + content: "\f615"; } + +.ui-icon-more:before { + content: "\f616"; } + +.ui-icon-arrow:before { + content: "\f600"; } + +.ui-icon-return:before { + content: "\f614"; } + +.ui-icon-checked:before { + content: "\f601"; } + +.ui-icon-checked-s:before { + content: "\f602"; } + +.ui-icon-info-block:before { + content: "\f603"; } + +.ui-icon-success-block:before { + content: "\f604"; } + +.ui-icon-warn-block:before { + content: "\f605"; } + +.ui-icon-info:before { + content: "\f606"; } + +.ui-icon-success:before { + content: "\f607"; } + +.ui-icon-warn:before { + content: "\f608"; } + +.ui-icon-next:before { + content: "\f617"; } + +.ui-icon-prev:before { + content: "\f618"; } + +.ui-icon-tag:before { + content: "\f60d"; } + +.ui-icon-tag-pop:before { + content: "\f60f"; } + +.ui-icon-tag-s:before { + content: "\f60e"; } + +.ui-icon-warn-lg:before { + content: "\f609"; } + +.ui-icon-close:before { + content: "\f60a"; } + +.ui-icon-close-progress:before { + content: "\f619"; } + +.ui-icon-close-page:before { + content: "\f60b"; } + +.ui-icon-emo:before { + content: "\f61a"; } + +.ui-icon-delete:before { + content: "\f61b"; } + +.ui-icon-search:before { + content: "\f60c"; } + +.ui-icon-order:before { + content: "\f61c"; } + +.ui-icon-news:before { + content: "\f61d"; } + +.ui-icon-personal:before { + content: "\f61e"; } + +.ui-icon-dressup:before { + content: "\f61f"; } + +.ui-icon-cart:before { + content: "\f620"; } + +.ui-icon-history:before { + content: "\f621"; } + +.ui-icon-wallet:before { + content: "\f622"; } + +.ui-icon-refresh:before { + content: "\f623"; } + +.ui-icon-thumb:before { + content: "\f624"; } + +.ui-icon-file:before { + content: "\f625"; } + +.ui-icon-hall:before { + content: "\f626"; } + +.ui-icon-voice:before { + content: "\f627"; } + +.ui-icon-unfold:before { + content: "\f628"; } + +.ui-icon-gototop:before { + content: "\f629"; } + +.ui-icon-share:before { + content: "\f62a"; } + +.ui-icon-home:before { + content: "\f62b"; } + +.ui-icon-pin:before { + content: "\f62c"; } + +.ui-icon-star:before { + content: "\f62d"; } + +.ui-icon-bugle:before { + content: "\f62e"; } + +.ui-icon-trend:before { + content: "\f62f"; } + +.ui-icon-unchecked:before { + content: "\f610"; } + +.ui-icon-unchecked-s:before { + content: "\f611"; } + +.ui-icon-play-active:before { + content: "\f630"; } + +.ui-icon-stop-active:before { + content: "\f631"; } + +.ui-icon-play:before { + content: "\f632"; } + +.ui-icon-stop:before { + content: "\f633"; } + +.ui-icon-set:before { + content: "\f634"; } + +.ui-icon-add-group:before { + content: "\f635"; } + +.ui-icon-add-people:before { + content: "\f636"; } + +.ui-icon-pc:before { + content: "\f637"; } + +.ui-icon-scan:before { + content: "\f638"; } + +.ui-icon-tag-svip:before { + content: "\f613"; } + +.ui-icon-tag-vip:before { + content: "\f612"; } + +.ui-icon-male:before { + content: "\f639"; } + +.ui-icon-female:before { + content: "\f63a"; } + +.ui-icon-collect:before { + content: "\f63b"; } + +.ui-icon-commented:before { + content: "\f63c"; } + +.ui-icon-like:before { + content: "\f63d"; } + +.ui-icon-liked:before { + content: "\f63e"; } + +.ui-icon-comment:before { + content: "\f63f"; } + +.ui-icon-collected:before { + content: "\f640"; } + +a { + color: #00a5e0; } + +em { + color: #ff8444; } + +::-webkit-input-placeholder { + color: #bbb; } + +/** + * 文字 + */ +h1 { + font-size: 18px; } + +h2 { + font-size: 17px; } + +h3, h4 { + font-size: 16px; } + +h5, .ui-txt-sub { + font-size: 14px; } + +h6, .ui-txt-tips { + font-size: 12px; } + +.ui-txt-default { + color: #000; } + +.ui-txt-white { + color: white; } + +.ui-txt-info { + color: #777; } + +.ui-txt-muted { + color: #bbb; } + +.ui-txt-warning, .ui-txt-red { + color: #ff4222; } + +.ui-txt-feeds { + color: #314c83; } + +/* 同em */ +.ui-txt-highlight { + color: #ff8444; } + +.ui-txt-justify { + text-align: justify; } + +.ui-txt-justify-one { + text-align: justify; + overflow: hidden; + height: 24px; } + +.ui-txt-justify-one:after { + display: inline-block; + content: ''; + overflow: hidden; + width: 100%; + height: 0; } + +/* 1px hack */ +.ui-border-t { + border-top: 1px solid #e0e0e0; } + +.ui-border-b { + border-bottom: 1px solid #e0e0e0; } + +.ui-border-tb { + border-top: #e0e0e0 1px solid; + border-bottom: #e0e0e0 1px solid; + background-image: none; } + +.ui-border-l { + border-left: 1px solid #e0e0e0; } + +.ui-border-r { + border-right: 1px solid #e0e0e0; } + +.ui-border { + border: 1px solid #e0e0e0; } + +.ui-border-radius { + border: 1px solid #e0e0e0; + border-radius: 4px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-border-radius { + position: relative; + border: 0; } + .ui-border-radius:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #e0e0e0; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 8px; + pointer-events: none; } } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-border { + position: relative; + border: 0; } + + .ui-border-t, .ui-border-b, .ui-border-l, .ui-border-r, .ui-border-tb { + border: 0; } + + .ui-border-t { + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-b { + background-position: left bottom; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-t, + .ui-border-b, + .ui-border-tb { + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } + + .ui-border-tb { + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-position: top, bottom; } + + .ui-border-l { + background-position: left top; + background-image: -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-r { + background-position: right top; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); } + + .ui-border-l, + .ui-border-r { + background-repeat: repeat-y; + -webkit-background-size: 1px 100%; } + + .ui-border:after { + content: ""; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, right top, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + -webkit-background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; + background-repeat: no-repeat; + background-position: top, right, bottom, left; + padding: 1px; + -webkit-box-sizing: border-box; + z-index: 10; + pointer-events: none; } } +/* 箭头链接 */ +.ui-arrowlink { + position: relative; } + .ui-arrowlink:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-arrowlink:before { + right: 10px; } } + +.ui-arrowlink.active { + background: #e5e6e7; } + +/* 文字截断 */ +.ui-nowrap { + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + +.ui-nowrap-flex { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + -webkit-box-flex: 1; + height: inherit; } + +.ui-nowrap-multi { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; } + +.ui-placehold-wrap { + padding-top: 31.25%; + position: relative; } + +.ui-placehold { + color: #bbb; + position: absolute; + top: 0; + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + -webkit-box-sizing: border-box; + text-align: center; + height: 100%; + z-index: -1; } + +.ui-placehold-img { + padding-top: 31.25%; + position: relative; } + .ui-placehold-img > span { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-placehold-img img { + width: 100%; + height: 100%; } + +/* 三等分 */ +.ui-grid, .ui-grid-trisect, .ui-grid-halve { + padding-left: 15px; + padding-right: 10px; + overflow: hidden; + padding-top: 10px; } + @media (max-width: 320px) { + .ui-grid, .ui-grid-trisect, .ui-grid-halve { + padding-left: 10px; + padding-right: 5px; } } + .ui-grid li, .ui-grid-trisect li, .ui-grid-halve li { + padding-right: 5px; + padding-bottom: 10px; + float: left; + position: relative; + -webkit-box-sizing: border-box; } + +.ui-grid-trisect > li { + width: 33.3333%; } + +.ui-grid-trisect-img { + padding-top: 149.47%; } + +.ui-grid-trisect h4 { + position: relative; + margin: 7px 0 3px; } + +.ui-grid-trisect h4 span { + display: inline-block; + margin-left: 12px; + color: #777; } + +/* 二等分 */ +.ui-grid-halve > li { + width: 50%; } + +.ui-grid-halve-img { + padding-top: 55.17%; } + +.ui-grid-trisect-img, .ui-grid-halve-img { + position: relative; + width: 100%; } + .ui-grid-trisect-img > span, .ui-grid-halve-img > span { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-grid-trisect-img img, .ui-grid-halve-img img { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; } + .ui-grid-trisect-img.active, .ui-grid-halve-img.active { + opacity: .5; } + +.ui-row { + display: block; + overflow: hidden; } + +.ui-col { + float: left; + box-sizing: border-box; + width: 100%; } + +.ui-col-10 { + width: 10%; } + +.ui-col-20 { + width: 20%; } + +.ui-col-25 { + width: 25%; } + +.ui-col-33 { + width: 33.3333%; } + +.ui-col-50 { + width: 50%; } + +.ui-col-67 { + width: 66.6666%; } + +.ui-col-75 { + width: 75%; } + +.ui-col-80 { + width: 80%; } + +.ui-col-90 { + width: 90%; } + +.ui-row-flex { + display: -webkit-box; + width: 100%; + -webkit-box-sizing: border-box; } + .ui-row-flex .ui-col { + float: none; + -webkit-box-flex: 1; + width: 0; } + .ui-row-flex .ui-col-2 { + -webkit-box-flex: 2; } + .ui-row-flex .ui-col-3 { + -webkit-box-flex: 3; } + .ui-row-flex .ui-col-4 { + -webkit-box-flex: 4; } + +.ui-row-flex-ver { + -webkit-box-orient: vertical; } + .ui-row-flex-ver .ui-col { + width: 100%; + height: 0; } + +.ui-whitespace { + padding-left: 15px; + padding-right: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace { + padding-left: 10px; + padding-right: 10px; } } + +.ui-whitespace-left { + padding-left: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace-left { + padding-left: 10px; } } + +.ui-whitespace-right { + padding-right: 15px; + box-sizing: border-box; } + @media (max-width: 320px) { + .ui-whitespace-right { + padding-right: 10px; } } + +.ui-justify { + text-align: justify; + font-size: 0; } + .ui-justify:after { + content: ''; + display: inline-block; + width: 100%; + height: 0; + overflow: hidden; } + .ui-justify li { + display: inline-block; + text-align: center; } + .ui-justify p { + font-size: 16px; } + +.ui-justify-flex { + width: 100%; + display: -webkit-box; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; } + +.ui-header, +.ui-footer { + position: fixed; + width: 100%; + z-index: 100; + left: 0; } + +.ui-header { + top: 0; + height: 45px; + line-height: 45px; } + +.ui-header-stable, +.ui-header-positive { + padding: 0 10px; + box-sizing: border-box; } + +.ui-header-stable, +.ui-footer-stable { + background-color: #f8f8f8; } + +.ui-header-positive, +.ui-footer-positive { + background-color: #18b4ed; + color: #fff; } + .ui-header-positive a, .ui-header-positive a:active, .ui-header-positive i, + .ui-footer-positive a, + .ui-footer-positive a:active, + .ui-footer-positive i { + color: #fff; } + +.ui-footer-btn { + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f9f9f9), to(#e0e0e0)); + color: #00a5e0; } + .ui-footer-btn .ui-tiled { + height: 100%; } + +.ui-footer { + bottom: 0; + height: 56px; } + +.ui-header ~ .ui-container { + border-top: 45px solid transparent; } + +.ui-footer ~ .ui-container { + border-bottom: 56px solid transparent; } + +.ui-header h1 { + text-align: center; + font-size: 18px; } + +.ui-header .ui-icon-return { + position: absolute; + left: 0; } + +.ui-header .ui-btn, .ui-header .ui-btn-lg, .ui-header .ui-btn-s { + display: block; + position: absolute; + right: 10px; + top: 50%; + margin-top: -15px; } + +/** + * 垂直上下居中 + */ +.ui-center { + width: 100%; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + text-align: center; + height: 150px; } + +/** + * 排版 + */ +.ui-flex, +.ui-tiled { + display: -webkit-box; + width: 100%; + -webkit-box-sizing: border-box; } + +.ui-flex-ver { + -webkit-box-orient: vertical; } + +.ui-flex-pack-start { + -webkit-box-pack: start; } + +.ui-flex-pack-end { + -webkit-box-pack: end; } + +.ui-flex-pack-center { + -webkit-box-pack: center; } + +.ui-flex-align-start { + -webkit-box-align: start; } + +.ui-flex-align-end { + -webkit-box-align: end; } + +.ui-flex-align-center { + -webkit-box-align: center; } + +/** + * 平铺 + */ +.ui-tiled li { + -webkit-box-flex: 1; + width: 100%; + text-align: center; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; } + +/** + * 未读数通知 + */ +.ui-badge, .ui-badge-muted, .ui-badge-num, .ui-badge-corner, .ui-badge-cornernum { + display: inline-block; + text-align: center; + background: #f74c31; + color: #fff; + font-size: 11px; + height: 16px; + line-height: 16px; + -webkit-border-radius: 8px; + padding: 0 6px; + background-clip: padding-box; } + +/* 浅色的 */ +.ui-badge-muted { + background: #b6cae0; } + +.ui-badge-num { + height: 19px; + line-height: 20px; + font-size: 12px; + min-width: 19px; + -webkit-border-radius: 10px; } + +.ui-badge-wrap { + position: relative; + text-align: center; } + +.ui-badge-corner { + position: absolute; + border: 2px #fff solid; + height: 20px; + line-height: 20px; + top: -4px; + right: -9px; } + +.ui-badge-cornernum { + position: absolute; + top: -4px; + right: -9px; + height: 19px; + line-height: 19px; + font-size: 12px; + min-width: 19px; + -webkit-border-radius: 10px; + top: -5px; + right: -5px; } + +/** +* 红点提醒 +*/ +.ui-reddot, .ui-reddot-border, .ui-reddot-s { + position: relative; + display: inline-block; + line-height: 22px; + padding: 0 6px; } + .ui-reddot:after, .ui-reddot-border:after, .ui-reddot-s:after { + content: ''; + position: absolute; + display: block; + width: 8px; + height: 8px; + background-color: #f74c31; + border-radius: 5px; + right: -3px; + top: -3px; + background-clip: padding-box; } + +.ui-reddot-static { + display: block; + width: 8px; + height: 8px; + padding: 0; } + .ui-reddot-static:after { + top: 0; + right: 0; } + +/* 带白边的 */ +.ui-reddot-border:before { + content: ''; + position: absolute; + display: block; + width: 8px; + height: 8px; + background-color: #fff; + border-radius: 5px; + right: -4px; + top: -4px; + background-clip: padding-box; + padding: 1px; } + +/* 小号的 */ +.ui-reddot-s:after { + width: 6px; + height: 6px; + top: -5px; + right: -5px; } + +/** + * 圆角头像,列表场景 + */ +.ui-avatar, +.ui-avatar-lg, +.ui-avatar-s, +.ui-avatar-one, +.ui-avatar-tiled { + display: block; + -webkit-background-size: cover; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAMAAABHPGVmAAAA8FBMVEXp8Peat8+jwNidutKhvtagvdWcudGfu9Kpwteiv9ecudCsxNifvNTM2+ieu9PE1eSdudDO3OmkvtSyyNu/0eKhvNOivdPm7vWlv9WeutHI2Oa5zd+dudG+0eHn7/bG1+Xi6/SzydzT4Ozc5vDe6PLY5O/a5e/P3eqmv9WmwNW6zt/j7PTX4+6uxtno8Pff6fLh6vPW4u280ODg6fLC1OObuM+buNDD1eTU4eza5fDd5/GhvNKowdarw9jA0+K1y93k7PTk7fXl7fW7zt/F1uXc5/DZ5O/R3+vB0+OnwNXg6vKcuNDM2+mtxNjO3eq3zN1UQ75QAAACR0lEQVR4Xu3W1a7cMBAG4PnHDi4zMx5mxiLD+79Ne7YXq6hKHMU+Ui/8XVpKfo0nMwr9hyzLsizLsqx5ZTfX9DyvmXtXOaNXsd+rYqs9mJFx454HiLwMXsi8CzTO35JZ0x1ABLwlBZAzW0yhAzfgKOmiekLmVEII/peAd22u5ZGMSEpzSWYc30cyoim+oe4/wuU4LgZkwq0HyXEkPCMX9hmC4wmcHpK2VhWS40ncHZG2KcBJBAom2l7kJA6eSFsNDicJsB5qt8SH5EToz0nT1zUCRUi4IE3zqjLkm/aaPGsrQ8oz0nSkDgm1Z750AU4mtL/hYQ1FThZgZ4+0HH9BoAzx9knL8hKsoL9YChCsksdAd3PlWcXBhHSM15CsEqCsNY49uKwm4Lcos5MyAk7BRYmyOpxAcBoOqkca/1sBpyKyl1KH4HQc5J4pmzYkpwQsKJsQnFYRI8qmnD7EwdPrh0gcZA9xio76piBY4iFziACUMw+EcLNXEgKd7o5qVtD52UYeu5RNB3iiifIP0qcRgAplU4N/TNdILsVFgVq/0My6Vxa9lyeTF5jAwzPRsF4gLbfNhBSJ/pRMKPThxGbgkcy4iu19HqdkxN7oR2wlDmqrQ9K39JPm8RLYbZGu8T1cJ3mp1ElXJVqGLAKI7DOJxpA0Le8gJP8VSIGN7RE7Lmr6XfneACCKfwgAjfPFdP8qcpSbk76bgX+BDe+gPqMXs3quj43OQekNGTH+WBmV3nc/fdi+b+9m1S2VuqvZM6lZlmVZlmVZvwEAnS9LHbI74gAAAABJRU5ErkJggg==); } + +.ui-avatar { + width: 50px; + height: 50px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-avatar-lg, +.ui-avatar-one { + width: 70px; + height: 70px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar-lg > span, + .ui-avatar-one > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-avatar-s { + width: 40px; + height: 40px; + -webkit-border-radius: 200px; + overflow: hidden; } + .ui-avatar-s > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +/* 平铺场景 */ +.ui-avatar-tiled { + width: 30px; + height: 30px; + -webkit-border-radius: 200px; + overflow: hidden; + display: inline-block; } + .ui-avatar-tiled > span { + width: 100%; + height: 100%; + display: block; + overflow: hidden; + background-repeat: no-repeat; + -webkit-background-size: cover; + -webkit-border-radius: 200px; } + +.ui-label { + display: inline-block; + position: relative; + line-height: 30px; + height: 30px; + padding: 0 15px; + border: 1px solid #cacccd; + border-radius: 15px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-label { + position: relative; + border: 0; } + .ui-label:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #cacccd; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 30px; + pointer-events: none; } } + .ui-label:active { + background-color: #f3f2f2; } + +.ui-label-list { + margin: 0 10px; } + .ui-label-list .ui-label { + margin: 0 10px 10px 0; } + +.ui-label-s { + font-size: 11px; + line-height: 13px; + display: inline-block; + position: relative; + padding: 0 1px; + color: #ff7f0d; + border: 1px solid #ff7f0d; + border-radius: 2px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-label-s { + position: relative; + border: 0; } + .ui-label-s:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #ff7f0d; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 4px; + pointer-events: none; } } + .ui-label-s:active { + background-color: #f3f2f2; } + .ui-label-s:after { + content: ""; + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; } + +.ui-tag-t, .ui-tag-hot, +.ui-tag-new, +.ui-tag-s-hot, +.ui-tag-s-new, +.ui-tag-pop-hot, +.ui-tag-pop-new { + position: relative; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before, +.ui-tag-t:after, +.ui-tag-hot:after, +.ui-tag-new:after, +.ui-tag-s-hot:after, +.ui-tag-s-new:after, +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + height: 20px; + left: 0; + top: 0; + z-index: 9; + display: block; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before, +.ui-tag-vip:before, +.ui-tag-svip:before, +.ui-tag-selected:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + position: absolute; } + +.ui-tag-t:before, .ui-tag-hot:before, +.ui-tag-new:before, +.ui-tag-s-hot:before, +.ui-tag-s-new:before, +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before { + content: ""; + line-height: 20px; + color: #ff0000; } + +.ui-tag-t:after, .ui-tag-hot:after, +.ui-tag-new:after, +.ui-tag-s-hot:after, +.ui-tag-s-new:after, +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + position: absolute; + content: ''; + width: 22px; + text-align: right; + line-height: 20px; + font-size: 12px; + color: #fff; + padding-right: 14px; } + +.ui-tag-b, .ui-tag-freelimit, +.ui-tag-free, +.ui-tag-last, +.ui-tag-limit, +.ui-tag-act, +.ui-tag-xy, +.ui-tag-vip, +.ui-tag-svip { + position: relative; } + +.ui-tag-b:before, .ui-tag-freelimit:before, +.ui-tag-free:before, +.ui-tag-last:before, +.ui-tag-limit:before, +.ui-tag-act:before, +.ui-tag-xy:before, +.ui-tag-vip:before, +.ui-tag-svip:before { + position: absolute; + font-size: 10px; + width: 28px; + height: 13px; + line-height: 13px; + bottom: 0; + right: 0; + z-index: 9; + color: #fff; + border-radius: 2px; + text-align: center; } + +.ui-tag-vip:before, +.ui-tag-svip:before { + font-size: 32px; + text-indent: -2px; + border-radius: 2px; } + +.ui-tag-vip:before { + background-color: #ff0000; + color: #fffadf; + content: ""; } + +.ui-tag-svip:before { + background-color: #ffd400; + color: #b7440e; + content: ""; } + +.ui-tag-freelimit:before { + background-color: #18b4ed; + content: '限免'; } + +.ui-tag-free:before { + background-color: #5fb336; + content: '免费'; } + +.ui-tag-last:before { + background-color: #8f6adb; + content: '绝版'; } + +.ui-tag-limit:before { + background-color: #3385e6; + content: '限量'; } + +.ui-tag-act:before { + background-color: #00c795; + content: '活动'; } + +.ui-tag-xy:before { + background-color: #d7ba42; + content: '星影'; } + +.ui-tag-freemonthly:before { + background-color: #ff7f0d; + content: '包月'; } + +.ui-tag-onsale:before { + background-color: #00c795; + content: '特价'; } + +.ui-tag-hot:after, +.ui-tag-s-hot:after, +.ui-tag-pop-hot:after { + content: '热'; } + +.ui-tag-new:after, +.ui-tag-s-new:after, +.ui-tag-pop-new:after { + content: '\u65b0'; } + +.ui-tag-hot:before, +.ui-tag-s-hot:before, +.ui-tag-pop-hot:before { + color: #ff7200; } + +.ui-tag-s-hot:before, +.ui-tag-s-new:before { + content: ""; + left: -2px; } + +.ui-tag-s-hot:after, +.ui-tag-s-new:after { + width: 16px; + padding-right: 12px; } + +.ui-tag-selected:after { + content: ""; + color: #18b4ed; + right: -5px; + top: -5px; + z-index: 9; + width: 26px; + height: 26px; + background: #fff; + border-radius: 13px; + line-height: 26px; + text-indent: -3px; } + +.ui-tag-wrap { + display: inline-block; + position: relative; + padding-right: 32px; } + .ui-tag-wrap .ui-tag-vip, + .ui-tag-wrap .ui-tag-svip { + position: static; } + .ui-tag-wrap .ui-tag-vip:before, + .ui-tag-wrap .ui-tag-svip:before { + top: 50%; + margin-top: -7px; } + +.ui-tag-pop-hot:before, +.ui-tag-pop-new:before { + content: ""; + left: -10px; + top: 1px; } + +.ui-tag-pop-hot:after, +.ui-tag-pop-new:after { + font-size: 11px; + padding-right: 0; + text-align: center; + left: -5px; } + +/** + * 按钮 + */ +.ui-btn, .ui-btn-lg, .ui-btn-s { + height: 30px; + line-height: 30px; + padding: 0 11px; + min-width: 55px; + display: inline-block; + position: relative; + text-align: center; + font-size: 15px; + background-color: #fdfdfd; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #fff), to(#fafafa)); + vertical-align: top; + color: #00a5e0; + -webkit-box-sizing: border-box; + background-clip: padding-box; + border: 1px solid #cacccd; + border-radius: 3px; } + @media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn, .ui-btn-lg, .ui-btn-s { + position: relative; + border: 0; } + .ui-btn:before, .ui-btn-lg:before, .ui-btn-s:before { + content: ""; + width: 200%; + height: 200%; + position: absolute; + top: 0; + left: 0; + border: 1px solid #cacccd; + -webkit-transform: scale(0.5); + -webkit-transform-origin: 0 0; + padding: 1px; + -webkit-box-sizing: border-box; + border-radius: 6px; + pointer-events: none; } } + +.ui-btn:not(.disabled):not(:disabled):active, .ui-btn-lg:not(.disabled):not(:disabled):active, .ui-btn-s:not(.disabled):not(:disabled):active, .ui-btn.active, .active.ui-btn-lg, .active.ui-btn-s { + background: #f2f2f2; + color: rgba(0, 165, 224, 0.5); + background-clip: padding-box; } + +.ui-btn:after, .ui-btn-lg:after, .ui-btn-s:after { + content: ""; + position: absolute; + top: -7px; + bottom: -7px; + left: 0; + right: 0; } + +.ui-btn-primary { + background-color: #18b4ed; + border-color: #0baae4; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #1fbaf3), to(#18b4ed)); + color: white; + background-clip: padding-box; } + +.ui-btn-primary:not(.disabled):not(:disabled):active, .ui-btn-primary.active { + background: #1ca7da; + border-color: #1ca7da; + color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; } + +.ui-btn-danger { + background-color: #f75549; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #fc6156), to(#f75549)); + color: white; + border-color: #f43d30; + background-clip: padding-box; } + +.ui-btn-danger:not(.disabled):not(:disabled):active, .ui-btn-danger.active { + background: #e2574d; + border-color: #e2574d; + color: rgba(255, 255, 255, 0.5); + background-clip: padding-box; } + +.ui-btn.disabled, .disabled.ui-btn-lg, .disabled.ui-btn-s, .ui-btn:disabled, .ui-btn-lg:disabled, .ui-btn-s:disabled { + border: 0; + color: #ccc; + background: #e9ebec; + background-clip: padding-box; } + +.ui-btn-lg { + font-size: 18px; + height: 44px; + line-height: 44px; + display: block; + width: 100%; + border-radius: 5px; } + +.ui-btn-wrap { + padding: 15px 10px; } + @media (max-width: 320px) { + .ui-btn-wrap { + padding: 10px; } } + +.ui-btn-s { + padding: 0; + width: 55px; + height: 25px; + line-height: 25px; + font-size: 13px; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn-primary:before { + border: 1px solid #0baae4; } + + .ui-btn-danger:before { + border: 1px solid #f43d30; } + + .ui-btn, .ui-btn-lg, .ui-btn-s { + border: 0; } + + .ui-btn.disabled, .disabled.ui-btn-lg, .disabled.ui-btn-s, + .ui-btn:disabled, + .ui-btn-lg:disabled, + .ui-btn-s:disabled, + .ui-btn.disabled:before, + .disabled.ui-btn-lg:before, + .disabled.ui-btn-s:before, + .ui-btn:disabled:before, + .ui-btn-lg:disabled:before, + .ui-btn-s:disabled:before { + border: 1px solid #e9ebec; } + + .ui-btn-lg:before { + border-radius: 10px; } } +.ui-btn-progress { + width: 55px; + padding: 0; + overflow: hidden; } + .ui-btn-progress .ui-btn-inner { + position: absolute; + left: 0; + top: 0; + height: 100%; + overflow: hidden; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, #1fbaf3), to(#18b4ed)); + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; } + .ui-btn-progress .ui-btn-inner span { + display: inline-block; + color: white; + position: absolute; + width: 55px; + left: 0; } + .ui-btn-progress.disabled, .ui-btn-progress:disabled { + background-color: #fefefe; + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, white), to(#fafafa)); + color: #ccc; + border: 1px solid #cacccd; + background-clip: padding-box; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-btn-progress.disabled, + .ui-btn-progress:disabled { + border: 0; } + + .ui-btn-progress.disabled:before, + .ui-btn-progress:disabled:before { + border: 1px solid #cacccd; } } +.ui-btn-group { + display: -webkit-box; + width: 100%; + box-sizing: border-box; + -webkit-box-align: center; } + +.ui-btn-group button { + display: block; + -webkit-box-flex: 1; + margin-right: 10px; } + .ui-btn-group button:first-child { + margin-left: 10px; } + +.ui-tips { + padding: 20px 15px; + text-align: center; + font-size: 16px; + color: #000; } + .ui-tips i { + display: inline-block; + width: 32px; + height: 1px; + vertical-align: top; } + +.ui-tips i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #0090ff; + line-height: 21px; } + +.ui-tips-success i:before { + content: ""; + color: #65d521; } + +.ui-tips-warn i:before { + content: ""; + color: #f76249; } + +/** + * 页面消息提示 + */ +.ui-newstips-wrap { + margin: 20px 15px; + text-align: center; } + +.ui-newstips { + background: #383939; + position: relative; + height: 40px; + line-height: 40px; + display: -webkit-inline-box; + -webkit-box-align: center; + padding-right: 25px; + border-radius: 5px; + font-size: 14px; + color: #fff; + padding-left: 15px; } + .ui-newstips .ui-avatar-tiled, .ui-newstips .ui-newstips-thumb, .ui-newstips i { + display: block; + margin-left: -5px; + margin-right: 10px; } + .ui-newstips .ui-newstips-thumb { + width: 30px; + height: 30px; + position: relative; } + .ui-newstips .ui-newstips-thumb > span { + display: block; + width: 100%; + height: 100%; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + .ui-newstips div { + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + -webkit-box-flex: 1; + height: inherit; } + +.ui-newstips:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-newstips:after { + right: 10px; } } + +.ui-newstips .ui-reddot, .ui-newstips .ui-reddot-border, .ui-newstips .ui-reddot-s, .ui-newstips .ui-badge-num { + margin-left: 10px; + margin-right: 5px; } + +.ui-tooltips { + width: 100%; + position: relative; + z-index: 99; + overflow: hidden; + box-sizing: border-box; } + +.ui-tooltips-cnt { + background-color: #fff; + line-height: 44px; + height: 44px; + padding-left: 10px; + padding-right: 30px; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + .ui-tooltips-cnt .ui-icon-close:before { + font-size: 40px; + color: rgba(0, 0, 0, 0.2); + margin-left: -10px; + position: absolute; + right: 0; + top: 0; } + +.ui-tooltips-warn .ui-tooltips-cnt { + background-color: rgba(255, 242, 183, 0.95); + color: #000; } + +.ui-tooltips-warn:active .ui-tooltips-cnt { + background-color: #e1d498; } + +.ui-tooltips-guide .ui-tooltips-cnt { + color: #00a5e0; + background-color: rgba(205, 242, 255, 0.95); } + .ui-tooltips-guide .ui-tooltips-cnt .ui-icon-close:before { + color: rgba(0, 165, 224, 0.2); } + +.ui-tooltips-guide:active .ui-tooltips-cnt { + background-color: #b5dbe8; } + +.ui-tooltips-cnt-link:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; + color: rgba(0, 0, 0, 0.5); } + @media (max-width: 320px) { + .ui-tooltips-cnt-link:after { + right: 10px; } } + +.ui-tooltips-guide .ui-tooltips-cnt-link:after { + color: #00aeef; } + +.ui-tooltips-warn i { + display: inline-block; + margin-right: 4px; + margin-left: -4px; + width: 32px; + height: 1px; + vertical-align: top; } + +.ui-tooltips-warn i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #f76249; } + +/** + * 表格 + */ +.ui-table { + width: 100%; + border-collapse: collapse; } + +.ui-table th { + font-weight: 500; } + +.ui-table td, .ui-table th { + border-bottom: 1px solid #e0e0e0; + border-right: 1px solid #e0e0e0; + text-align: center; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-table td, .ui-table th { + position: relative; + border-right: 0; + border-bottom: 0; } + + .ui-table td:after, .ui-table th:after { + content: ""; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)), -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 1px 100% ,100% 1px; + background-repeat: no-repeat; + background-position: right, bottom; + pointer-events: none; } + + .ui-table tr td:last-child:after, .ui-table tr th:last-child:after { + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 100% 1px; + background-repeat: no-repeat; + background-position: bottom; } + + .ui-table tr:last-child td:not(:last-child):after { + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-size: 1px 100%; + background-repeat: no-repeat; + background-position: right; } } +.ui-table tr td:last-child, .ui-table tr th:last-child { + border-right: 0; } + +.ui-table tr:last-child td { + border-bottom: 0; } + +.ui-list { + background-color: #fff; + width: 100%; } + .ui-list > li { + position: relative; + margin-left: 15px; + display: -webkit-box; } + +.ui-list-pure > li { + display: block; } + +/*文字列表*/ +.ui-list-text > li, +.ui-list-pure > li { + position: relative; + padding-top: 10px; + padding-bottom: 10px; + padding-right: 15px; + -webkit-box-align: center; } + +.ui-list-text h4, +.ui-list-text p { + -webkit-box-flex: 1; } + +/*通栏列表*/ +.ui-list-cover > li { + padding-left: 15px; + margin-left: 0px; } + +.ui-list > li.ui-border-t:first-child, +.ui-list > li:first-child > .ui-border-t { + border: none; + background-image: none; } + +/*列表缩略图*/ +.ui-list-thumb, +.ui-list-thumb-s, +.ui-list-img, +.ui-list-icon { + position: relative; + margin: 10px 10px 10px 0px; } + .ui-list-thumb > span, + .ui-list-thumb-s > span, + .ui-list-img > span, + .ui-list-icon > span { + display: block; + width: 100%; + height: 100%; + z-index: 1; + background-repeat: no-repeat; + -webkit-background-size: cover; } + +.ui-list-thumb { + width: 50px; + height: 50px; } + +/*列表普通图片*/ +.ui-list-img { + width: 100px; + height: 68px; } + +.ui-list-thumb-s { + width: 28px; + height: 28px; } + +/*列表icon*/ +.ui-list-icon { + width: 40px; + height: 40px; } + +.ui-list .ui-avatar, +.ui-list .ui-avatar-s, +.ui-list .ui-avatar-lg { + margin: 10px 10px 10px 0px; } + +/*列表主要信息*/ +.ui-list-info { + -webkit-box-flex: 1; + padding-top: 10px; + padding-bottom: 10px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + padding-right: 15px; } + .ui-list-info p { + color: #777; + font-size: 14px; } + +.ui-list-text .ui-list-info { + padding-top: 0; + padding-bottom: 0; } + +.ui-list li h4 { + font-size: 16px; } + +.ui-list:not(.ui-list-text) li > p, +.ui-list li > h5 { + font-size: 14px; + color: #777; } + +/*列表按压态*/ +.ui-list-active > li:active, +.ui-list li.active { + background-color: #e5e6e7; + padding-left: 15px; + margin-left: 0px; } + +.ui-list-active > li:active, +.ui-list > li.active, +.ui-list > li.active > .ui-border-t, +.ui-list > li.active + li > .ui-border-t, +.ui-list > li.active + li.ui-border-t { + background-image: none; + border-top-color: #e5e6e7; } + +/*连接列表*/ +.ui-list-link > li:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-list-link > li:after { + right: 10px; } } + +.ui-list-text.ui-list-link > li { + padding-right: 30px; } + +.ui-list-link .ui-list-info { + padding-right: 30px; } + +/* 功能类 */ +.ui-list-function .ui-list-info { + padding-right: 75px; } + +.ui-list-function .ui-btn, .ui-list-function .ui-btn-lg, .ui-list-function .ui-btn-s { + position: absolute; + top: 50%; + right: 15px; + margin-top: -15px; } + +.ui-list-function .ui-btn-s { + margin-top: -12px; } + +.ui-list-function.ui-list-link .ui-list-info { + padding-right: 90px; } + +.ui-list-function.ui-list-link .ui-btn, .ui-list-function.ui-list-link .ui-btn-lg, .ui-list-function.ui-list-link .ui-btn-s { + right: 30px; } + +.ui-list-function li { + -webkit-box-align: inherit; } + +.ui-list-one > li { + padding-top: 0; + padding-bottom: 0; + line-height: 44px; } +.ui-list-one .ui-list-info { + -webkit-box-orient: horizontal; + -webkit-box-align: center; } +.ui-list-one h4 { + -webkit-box-flex: 1; } + +@media (max-width: 320px) { + .ui-list > li { + margin-left: 10px; } + + .ui-list-text > li, + .ui-list-pure > li, + .ui-list-info { + padding-right: 10px; } + + .ui-list-cover > li, + .ui-list-active > li:active, + .ui-list li.active { + padding-left: 10px; } + + .ui-list-text.ui-list-link > li { + padding-right: 25px; } + + .ui-list-function .ui-list-info { + padding-right: 70px; } + + .ui-list-function .ui-btn, .ui-list-function .ui-btn-lg, .ui-list-function .ui-btn-s { + right: 10px; } + + .ui-list-function.ui-list-link .ui-list-info { + padding-right: 85px; } + + .ui-list-function.ui-list-link .ui-btn, .ui-list-function.ui-list-link .ui-btn-lg, .ui-list-function.ui-list-link .ui-btn-s { + right: 25px; } } +/** + * 出错页面 + */ +.ui-notice { + width: 100%; + height: 100%; + z-index: 99; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-pack: center; + -webkit-box-align: center; + position: absolute; + text-align: center; } + +.ui-notice > i { + display: block; + margin-bottom: 20px; } + .ui-notice > i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + font-size: 100px; + line-height: 100px; + color: rgba(0, 0, 0, 0.3); } + +.ui-notice p { + font-size: 16px; + line-height: 20px; + color: #bbb; + text-align: center; + padding: 0 15px; } + +.ui-notice-btn { + width: 100%; + -webkit-box-sizing: border-box; + padding: 50px 15px 15px; } + +.ui-notice-btn button { + margin: 10px 0px; } + +.ui-form { + background-color: #fff; } + +.ui-form-item-order.active { + background-color: #e5e6e7; } + +/* 表单输入项 */ +.ui-form-item { + position: relative; + font-size: 16px; + height: 44px; + line-height: 44px; + padding-right: 15px; + padding-left: 15px; } + .ui-form-item label:not(.ui-switch):not(.ui-checkbox):not(.ui-checkbox-s):not(.ui-radio) { + width: 95px; + position: absolute; + text-align: left; + box-sizing: border-box; } + .ui-form-item input, + .ui-form-item textarea { + width: 100%; + box-sizing: border-box; + -webkit-appearance: none; + border: 0; + background: none; + padding-left: 95px; } + .ui-form-item input[type="checkbox"], .ui-form-item input[type="radio"] { + padding-left: 0; } + .ui-form-item .ui-icon-close { + position: absolute; + top: 0; + right: 6px; } + @media (max-width: 320px) { + .ui-form-item .ui-icon-close { + right: 1px; } } + @media (max-width: 320px) { + .ui-form-item { + padding-left: 10px; + padding-right: 10px; } } + +.ui-form-item-textarea { + height: 65px; } + +.ui-form-item-textarea label { + vertical-align: top; } + +.ui-form-item-textarea textarea { + margin-top: 15px; + border: none; } + +.ui-form-item-textarea textarea:focus { + outline: none; } + +.ui-form-item-link > li:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-form-item-link > li:after { + right: 10px; } } + +.ui-form-item-l label, +.ui-form-item-r button { + color: #00a5e0; + text-align: center; } + +.ui-form-item-r .ui-icon-close { + right: 125px; } + +.ui-form-item-l input:not([type="checkbox"]):not([type="radio"]) { + padding-left: 115px; + -webkit-box-sizing: border-box; + box-sizing: border-box; } + +.ui-form-item-r { + padding-right: 0; } + +.ui-form-item-r input:not([type="checkbox"]):not([type="radio"]) { + padding-left: 0; + padding-right: 150px; + -webkit-box-sizing: border-box; + box-sizing: border-box; } + +.ui-form-item-r button { + width: 110px; + height: 44px; + position: absolute; + top: 0; + right: 0; } + +.ui-form-item-r button.disabled { + color: #bbb; } + +.ui-form-item-r button:not(.disabled):active { + background-color: #e5e6e7; } + +.ui-form-item-pure input, +.ui-form-item-pure textarea { + padding-left: 0; } + +/* 表单展示项 */ +.ui-form-item-show label { + color: #777; } + +.ui-form-item-link:after { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + color: #c7c7c7; + content: ""; + position: absolute; + right: 15px; + top: 50%; + margin-top: -22px; + margin-right: -10px; } + @media (max-width: 320px) { + .ui-form-item-link:after { + right: 10px; } } + +.ui-form-item-checkbox, +.ui-form-item-radio, +.ui-form-item-switch { + display: -webkit-box; + -webkit-box-align: center; } + +.ui-checkbox, .ui-checkbox-s { + display: inline-block; } + +.ui-checkbox input, .ui-checkbox-s input { + display: inline-block; + width: 25px; + height: 1px; + position: relative; + overflow: visible; + border: 0; + background: none; + -webkit-appearance: none; + outline: none; + margin-right: 8px; + vertical-align: middle; } + +.ui-checkbox input:before, .ui-checkbox-s input:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #18b4ed; + position: absolute; + top: -22px; + left: -4px; + color: #dedfe0; } + +.ui-checkbox input:checked:before, .ui-checkbox-s input:checked:before { + content: ""; + color: #18b4ed; } + +.ui-checkbox-s input:before { + content: ""; } + +.ui-checkbox-s input:checked:before { + content: ""; } + +.ui-switch { + position: absolute; + font-size: 16px; + right: 15px; + top: 50%; + margin-top: -16px; + width: 52px; + height: 32px; + line-height: 32px; } + @media (max-width: 320px) { + .ui-switch { + right: 10px; } } + .ui-switch input { + width: 52px; + height: 32px; + position: absolute; + z-index: 2; + border: none; + background: none; + -webkit-appearance: none; + outline: none; } + .ui-switch input:before { + content: ''; + width: 50px; + height: 30px; + border: 1px solid #dfdfdf; + background-color: #fdfdfd; + border-radius: 20px; + cursor: pointer; + display: inline-block; + position: relative; + vertical-align: middle; + -webkit-box-sizing: content-box; + box-sizing: content-box; + border-color: #dfdfdf; + box-shadow: #dfdfdf 0px 0px 0px 0px inset; + -webkit-transition: border 0.4s, box-shadow 0.4s; + transition: border 0.4s, box-shadow 0.4s; + -webkit-background-clip: content-box; + background-clip: content-box; } + .ui-switch input:checked:before { + border-color: #64bd63; + box-shadow: #64bd63 0px 0px 0px 16px inset; + background-color: #64bd63; + transition: border 0.4s, box-shadow 0.4s, background-color 1.2s; + -webkit-transition: border 0.4s, box-shadow 0.4s, background-color 1.2s; + background-color: #64bd63; } + .ui-switch input:checked:after { + left: 21px; } + .ui-switch input:after { + content: ''; + width: 30px; + height: 30px; + position: absolute; + top: 1px; + left: 0; + border-radius: 100%; + background-color: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); + -webkit-transition: left 0.2s; + transition: left 0.2s; } + +.ui-radio { + line-height: 25px; + display: inline-block; } + +.ui-radio input { + display: inline-block; + width: 26px; + height: 26px; + position: relative; + overflow: visible; + border: 0; + background: none; + -webkit-appearance: none; + outline: none; + margin-right: 8px; + vertical-align: middle; } + +.ui-radio input:before { + content: ''; + display: block; + width: 24px; + height: 24px; + border: 1px solid #dfe0e1; + border-radius: 13px; + background-clip: padding-box; + position: absolute; + left: 0px; + top: 0; } + +.ui-radio input:checked:after { + content: ''; + display: block; + width: 14px; + height: 14px; + background: #18b4ed; + border-radius: 7px; + position: absolute; + left: 6px; + top: 6px; } + +.ui-select { + position: relative; + margin-right: 6px; } + +.ui-select select { + -webkit-appearance: none; + border: 0; + background: none; + width: 100%; + padding-right: 14px; } + +.ui-select:after { + position: absolute; + top: 50%; + right: 0; + margin-top: -4px; + width: 0; + height: 0; + border-top: 6px solid; + border-right: 5px solid transparent; + border-left: 5px solid transparent; + color: #a6a6a6; + content: ""; + pointer-events: none; } + +.ui-select-group { + margin-left: 95px; + overflow: hidden; } + .ui-select-group .ui-select { + float: left; } + +.ui-form-item > .ui-select { + margin-left: 95px; } + +.ui-input-wrap { + background-color: #ebeced; + height: 44px; + display: -webkit-box; + -webkit-box-align: center; } + .ui-input-wrap .ui-btn, .ui-input-wrap .ui-btn-lg, .ui-input-wrap .ui-btn-s, .ui-input-wrap i { + margin-right: 10px; } + +.ui-input { + height: 30px; + line-height: 30px; + margin: 7px 10px; + background: #fff; + padding-left: 10px; + -webkit-box-flex: 1; } + +.ui-input input { + width: 100%; + height: 100%; + border: 0; + background: 0 0; + -webkit-appearance: none; + outline: 0; } + +.ui-searchbar-wrap { + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + background-color: #ebeced; + height: 44px; } + .ui-searchbar-wrap button { + margin-right: 10px; } + .ui-searchbar-wrap .ui-searchbar-cancel { + color: #00a5e0; + font-size: 16px; + padding: 4px 8px; } + .ui-searchbar-wrap .ui-searchbar-input, .ui-searchbar-wrap button, .ui-searchbar-wrap .ui-icon-close { + display: none; } + .ui-searchbar-wrap.focus { + -webkit-box-pack: start; } + .ui-searchbar-wrap.focus .ui-searchbar-input, .ui-searchbar-wrap.focus button, .ui-searchbar-wrap.focus .ui-icon-close { + display: block; } + .ui-searchbar-wrap.focus .ui-searchbar-text { + display: none; } + +.ui-searchbar { + border-radius: 5px; + margin: 0 10px; + background: #fff; + height: 30px; + line-height: 30px; + position: relative; + padding-left: 4px; + -webkit-box-flex: 1; + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + color: #bbb; + font-size: 14px; + width: 100%; } + .ui-searchbar input { + -webkit-appearance: none; + border: none; + background: none; + color: #000; + width: 100%; + padding: 4px 0; } + .ui-searchbar .ui-icon-search { + line-height: 30px; } + .ui-searchbar .ui-icon-close { + line-height: 30px; } + +.ui-searchbar-input { + -webkit-box-flex: 1; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-searchbar.ui-border-radius:before { + border-radius: 10px; } } +/** + * 轮播组件 + */ +.ui-slider { + width: 100%; + overflow: hidden; + position: relative; + padding-top: 31.25%; } + +.ui-slider-content { + display: -webkit-box; + position: absolute; + left: 0; + top: 0; + height: 100%; } + +.ui-slider-content > li { + -webkit-box-flex: 1; + width: 100%; + height: 100%; } + +.ui-slider-content > li img { + display: block; + width: 100%; } + +.ui-slider-content > li span { + display: block; + width: 100%; + height: 100%; + background-repeat: no-repeat; + -webkit-background-size: 100% 100%; } + +.ui-slider-content > li.active { + opacity: .5; } + +.ui-slider-indicators { + position: absolute; + display: -webkit-box; + -webkit-box-pack: end; + width: 100%; + bottom: 10px; + right: 4px; + font-size: 0; } + +.ui-slider-indicators li { + display: block; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + font-size: 0; + width: 7px; + height: 7px; + background-color: rgba(0, 0, 0, 0.3); + border-radius: 10px; + margin-right: 6px; + -webkit-box-sizing: border-box; + background-clip: padding-box; + position: relative; } + +.ui-slider-indicators li.current:before { + content: ''; + position: absolute; + background-color: #fff; + left: 1px; + top: 1px; + width: 5px; + height: 5px; + border-radius: 10px; + -webkit-box-sizing: border-box; + background-clip: padding-box; } + +.ui-slider-indicators-center { + -webkit-box-pack: center; + right: 0; } + +.ui-panel { + overflow: hidden; + margin-bottom: 10px; } + .ui-panel .ui-grid-halve, .ui-panel .ui-grid-trisect { + padding-top: 0; } + .ui-panel h1, .ui-panel h2, .ui-panel h3 { + padding-left: 15px; + padding-right: 15px; + line-height: 44px; + position: relative; + overflow: hidden; + display: -webkit-box; } + @media (max-width: 320px) { + .ui-panel h1, .ui-panel h2, .ui-panel h3 { + padding-left: 10px; + padding-right: 10px; } } + .ui-panel h1 span, .ui-panel h2 span, .ui-panel h3 span { + display: block; } + +.ui-panel-card, +.ui-panel-simple { + background-color: #fff; } + +.ui-panel-pure h2, +.ui-panel-pure h3 { + color: #777; } + +.ui-panel-simple { + margin-bottom: 0; } + +.ui-panel-subtitle { + font-size: 14px; + color: #777; + margin-left: 10px; } + +.ui-panel-title-tips { + font-size: 12px; + color: #777; + position: absolute; + right: 15px; } + @media (max-width: 320px) { + .ui-panel-title-tips { + right: 10px; } } + +.ui-arrowlink .ui-panel-title-tips { + right: 30px; } + @media (max-width: 320px) { + .ui-arrowlink .ui-panel-title-tips { + right: 25px; } } + +.ui-progress { + overflow: hidden; + width: 100%; + height: 2px; + font-size: 0px; + background-color: #e2e2e2; + box-sizing: border-box; } + +.ui-progress span { + display: block; + width: 0%; + background: #65d521; + height: 100%; + font-size: 0; } + +.ui-grid-trisect li .ui-progress, +.ui-grid-halve li .ui-progress { + position: absolute; + height: 13px; + bottom: 0px; + z-index: 9; + border: 5px solid rgba(248, 248, 248, 0.9); } + .ui-grid-trisect li .ui-progress span, + .ui-grid-halve li .ui-progress span { + border-radius: 3px; } + +/** + * 选项卡 + */ +.ui-tab { + width: 100%; + overflow: hidden; } + +.ui-tab-nav { + width: 100%; + background-color: #fff; + display: box; + display: -webkit-box; + font-size: 16px; + height: 45px; + box-sizing: border-box; } + +.ui-tab-content { + display: -webkit-box; } + +.ui-tab-content > li { + -webkit-box-flex: 1; + width: 100%; } + +.ui-tab-nav li { + height: 45px; + line-height: 45px; + min-width: 70px; + box-flex: 1; + -webkit-box-flex: 1; + text-align: center; + color: #777; + box-sizing: border-box; + border-bottom: 2px solid transparent; + width: 100%; } + +.ui-tab-nav li.current { + color: #00a5e0; + border-bottom: 2px #00a5e0 solid; } + +.ui-tab-nav li:active { + opacity: .8; } + +.ui-loading-wrap { + display: -webkit-box; + -webkit-box-pack: center; + -webkit-box-align: center; + text-align: center; + height: 40px; } + +.ui-loading { + width: 20px; + height: 20px; + display: block; + background: url(../img/loading_sprite.png); + -webkit-background-size: auto 20px; + -webkit-animation: am-rotate 1s steps(12) infinite; } + +.ui-loading-bright { + width: 37px; + height: 37px; + display: block; + background-image: url(../img/loading_sprite_white.png); + -webkit-background-size: auto 37px; + -webkit-animation: am-rotate2 1s steps(12) infinite; } + +.ui-loading-wrap .ui-loading { + margin: 10px; } + +.ui-loading-block { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: center; + background: rgba(0, 0, 0, 0.4); + display: none; + background: transparent; } + .ui-loading-block .ui-loading-cnt { + width: 130px; + height: 110px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-align: center; + text-align: center; + background: rgba(0, 0, 0, 0.65); + border-radius: 6px; + color: #fff; + font-size: 16px; } + .ui-loading-block .ui-loading-bright { + margin: 18px 0 8px; } + +.ui-loading-block.show { + display: -webkit-box; + display: box; } + +@-webkit-keyframes am-rotate { + from { + background-position: 0 0; } + to { + background-position: -240px 0; } } +@-webkit-keyframes am-rotate2 { + from { + background-position: 0 0; } + to { + background-position: -444px 0; } } +.ui-poptips { + width: 100%; + position: fixed; + top: 0px; + left: 0px; + z-index: 999; + padding: 0px 10px; + box-sizing: border-box; } + +.ui-poptips-cnt { + background-color: rgba(0, 0, 0, 0.6); + line-height: 40px; + height: 40px; + color: #fff; + font-size: 16px; + text-align: center; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + .ui-poptips-cnt i { + display: inline-block; + width: 32px; + height: 1px; + vertical-align: top; } + .ui-poptips-cnt i:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + margin-right: 2px; + margin-left: 4px; + color: #fff; + line-height: 40px; } + +.ui-poptips-info i:before { + content: ""; } + +.ui-poptips-success i:before { + content: ""; } + +.ui-poptips-warn i:before { + content: ""; } + +/** + * 弹窗类 + */ +.ui-dialog { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: center; + background: rgba(0, 0, 0, 0.4); + display: none; } + +.ui-dialog.show { + display: -webkit-box; + display: box; } + +.ui-dialog-hd { + height: 48px; + line-height: 48px; + text-align: center; + position: relative; } + +.ui-dialog-cnt { + border-radius: 6px; + width: 270px; + -webkit-background-clip: padding-box; + background-clip: padding-box; + pointer-events: auto; + background-color: rgba(253, 253, 253, 0.95); + position: relative; + font-size: 16px; } + +.ui-dialog-bd { + min-height: 71px; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + padding: 18px; + display: -webkit-box; + display: box; + -webkit-box-pack: center; + -webkit-box-align: center; + -webkit-box-orient: vertical; } + +.ui-dialog-bd > h4 { + margin-bottom: 4px; + width: 100%; + text-align: center; } + +.ui-dialog-bd > div, .ui-dialog-bd > ul { + width: 100%; } + +.ui-dialog-ft { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + display: -webkit-box; + width: 100%; + box-sizing: border-box; + -webkit-box-align: center; + border-top: 1px solid #e0e0e0; + height: 42px; + line-height: 42px; } + +.ui-dialog-close:before { + font-family: "iconfont" !important; + font-size: 32px; + line-height: 44px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -webkit-text-stroke-width: 0.2px; + display: block; + color: rgba(0, 0, 0, 0.5); + content: ""; + color: #828282; + display: block; + line-height: 32px; + position: absolute; + top: 3px; + right: 3px; } + +.ui-dialog-close:active { + opacity: 0.5; } + +.ui-dialog-ft button { + color: #00a5e0; + text-align: center; + border-right: 1px #e0e0e0 solid; + width: 100%; + line-height: 42px; + background: transparent; + display: block; + margin: 0 !important; + -webkit-box-flex: 1; } + .ui-dialog-ft button:active { + background-color: rgba(0, 0, 0, 0.1) !important; } + .ui-dialog-ft button:first-child { + border-bottom-left-radius: 6px; } + .ui-dialog-ft button:last-child { + border-right: 0; + border-bottom-right-radius: 6px; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-dialog-ft { + position: relative; + border: 0; + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } + + .ui-dialog-ft button { + border-right: 0; + background-position: right top; + background-image: -webkit-gradient(linear, left top, right top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-y; + -webkit-background-size: 1px 100%; } + .ui-dialog-ft button:last-child { + background: none; } } +.ui-selector header { + padding: 6px 10px; + color: #a6a6a6; + overflow: hidden; } + +.ui-selector header h3 { + float: left; } + +.ui-selector-content { + background: #fff; } + +.ui-selector-item p { + margin-left: 10px; + -webkit-box-flex: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } + +.ui-selector-item .ui-txt-info { + margin: 0 10px; + font-size: 12px; } + +.ui-selector-item .ui-list-link li:after { + display: none; } + +.ui-selector-item h3:before { + content: ''; + display: block; + width: 0; + height: 0; + border-left: 6px solid; + border-top: 5px solid transparent; + border-bottom: 5px solid transparent; + color: #a6a6a6; + position: absolute; + left: 25px; + top: 15px; + -webkit-transition: all 0.2s; } + +.ui-selector-item.active h3:before { + -webkit-transform: rotate(90deg); } + +.ui-selector-item.active h3 { + border: none; + background-image: none; } + +.ui-selector-item.active ul { + display: block; } + +.ui-selector-item ul { + display: none; } + +.ui-selector-item h3 { + display: -webkit-box; + font-size: 16px; + padding-left: 54px; + line-height: 44px; + height: 44px; + position: relative; } + +.ui-actionsheet { + position: fixed; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + z-index: 9999; + opacity: 0; + pointer-events: none; + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-pack: center; + -webkit-box-align: end; + background: rgba(0, 0, 0, 0.4); } + .ui-actionsheet.show { + pointer-events: inherit; + opacity: 1; } + .ui-actionsheet.show .ui-actionsheet-cnt { + -webkit-transform: translateY(0); + -webkit-transition-delay: 0.3s; } + +.ui-actionsheet-cnt { + font-size: 21px; + position: fixed; + bottom: 0; + padding: 0 8px; + width: 100%; + box-sizing: border-box; + text-align: center; + -webkit-transform: translateY(100%); + -webkit-transition-property: all; + -webkit-transition-timing-function: ease-out; + -webkit-transition-duration: 0.3s; } + +.ui-actionsheet button, .ui-actionsheet h4 { + background: rgba(255, 255, 255, 0.84); + display: block; + width: 100%; + color: #0079ff; + box-sizing: border-box; } + +.ui-actionsheet button { + line-height: 44px; + height: 44px; } + +.ui-actionsheet h4 { + line-height: 24px; + padding-left: 20px; + padding-right: 20px; + padding-top: 10px; + padding-bottom: 10px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } + +.ui-actionsheet button:not(:last-child) { + border-top: 1px #e0e0e0 solid; } + +.ui-actionsheet button:last-child { + margin: 8px 0; + border-radius: 3px; } + +.ui-actionsheet button:nth-last-child(2) { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; } + +.ui-actionsheet button:active { + opacity: 0.84; } + +.ui-actionsheet h4 { + font-size: 13px; + color: #8a8a8a; } + +.ui-actionsheet .ui-actionsheet-del { + color: #fd472b; } + +@media screen and (-webkit-min-device-pixel-ratio: 2) { + .ui-actionsheet button:not(:last-child) { + border: 0; + background-position: left top; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.5, transparent), color-stop(0.5, #e0e0e0), to(#e0e0e0)); + background-repeat: repeat-x; + -webkit-background-size: 100% 1px; } } + +/*# sourceMappingURL=frozen.css.map */ diff --git a/hyhproject/wechat2/view/default/frozenui/font/iconfont-full.ttf b/hyhproject/wechat2/view/default/frozenui/font/iconfont-full.ttf new file mode 100755 index 0000000..859ec87 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/font/iconfont-full.ttf differ diff --git a/hyhproject/wechat2/view/default/frozenui/font/iconfont.ttf b/hyhproject/wechat2/view/default/frozenui/font/iconfont.ttf new file mode 100755 index 0000000..fb9b421 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/font/iconfont.ttf differ diff --git a/hyhproject/wechat2/view/default/frozenui/img/loading_sprite.png b/hyhproject/wechat2/view/default/frozenui/img/loading_sprite.png new file mode 100755 index 0000000..696f424 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/img/loading_sprite.png differ diff --git a/hyhproject/wechat2/view/default/frozenui/img/loading_sprite_white.png b/hyhproject/wechat2/view/default/frozenui/img/loading_sprite_white.png new file mode 100755 index 0000000..8156eb3 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/img/loading_sprite_white.png differ diff --git a/hyhproject/wechat2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png b/hyhproject/wechat2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png new file mode 100755 index 0000000..c6cd378 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/img/vip/icon_qqlevel_sprite.png differ diff --git a/hyhproject/wechat2/view/default/frozenui/img/vip/icon_vip.png b/hyhproject/wechat2/view/default/frozenui/img/vip/icon_vip.png new file mode 100755 index 0000000..c5792b8 Binary files /dev/null and b/hyhproject/wechat2/view/default/frozenui/img/vip/icon_vip.png differ diff --git a/hyhproject/wechat2/view/default/frozenui/js/frozen.js b/hyhproject/wechat2/view/default/frozenui/js/frozen.js new file mode 100755 index 0000000..69ba79a --- /dev/null +++ b/hyhproject/wechat2/view/default/frozenui/js/frozen.js @@ -0,0 +1,1533 @@ +/** + * User: jeakeyliang + * Date: 14-08-22 + * Time: 下午9:20 + * vn: w00119f3fc12403a05a1ef5609ff96e66 + */ +//js修改过 + +;(function($){ + var data = {}, dataAttr = $.fn.data, camelize = $.camelCase, + exp = $.expando = 'Zepto' + (+new Date()), emptyArray = [] + + // Get value from node: + // 1. first try key as given, + // 2. then try camelized key, + // 3. fall back to reading "data-*" attribute. + function getData(node, name) { + var id = node[exp], store = id && data[id] + if (name === undefined) return store || setData(node) + else { + if (store) { + if (name in store) return store[name] + var camelName = camelize(name) + if (camelName in store) return store[camelName] + } + return dataAttr.call($(node), name) + } + } + + // Store value under camelized key on node + function setData(node, name, value) { + var id = node[exp] || (node[exp] = ++$.uuid), + store = data[id] || (data[id] = attributeData(node)) + if (name !== undefined) store[camelize(name)] = value + return store + } + + // Read all "data-*" attributes from a node + function attributeData(node) { + var store = {} + $.each(node.attributes || emptyArray, function(i, attr){ + if (attr.name.indexOf('data-') == 0) + store[camelize(attr.name.replace('data-', ''))] = + $.zepto.deserializeValue(attr.value) + }) + return store + } + + $.fn.data = function(name, value) { + return value === undefined ? + // set multiple values via object + $.isPlainObject(name) ? + this.each(function(i, node){ + $.each(name, function(key, value){ setData(node, key, value) }) + }) : + // get value from first element + (0 in this ? getData(this[0], name) : undefined) : + // set value on all elements + this.each(function(){ setData(this, name, value) }) + } + + $.fn.removeData = function(names) { + if (typeof names == 'string') names = names.split(/\s+/) + return this.each(function(){ + var id = this[exp], store = id && data[id] + if (store) $.each(names || store, function(key){ + delete store[names ? camelize(this) : key] + }) + }) + } + + // Generate extended `remove` and `empty` functions + ;['remove', 'empty'].forEach(function(methodName){ + var origFn = $.fn[methodName] + $.fn[methodName] = function() { + var elements = this.find('*') + if (methodName === 'remove') elements = elements.add(this) + elements.removeData() + return origFn.call(this) + } + }) +})(window.Zepto); + +!function ($) { + var _private = {}; + _private.cache = {}; + $.tpl = function (str, data, env) { + // 判断str参数,如str为script标签的id,则取该标签的innerHTML,再递归调用自身 + // 如str为HTML文本,则分析文本并构造渲染函数 + var fn = !/[^\w\-\.:]/.test(str) + ? _private.cache[str] = _private.cache[str] || this.get(document.getElementById(str).innerHTML) + : function (data, env) { + var i, variable = [], value = []; // variable数组存放变量名,对应data结构的成员变量;value数组存放各变量的值 + for (i in data) { + variable.push(i); + value.push(data[i]); + } + return (new Function(variable, fn.code)) + .apply(env || data, value); // 此处的new Function是由下面fn.code产生的渲染函数;执行后即返回渲染结果HTML + }; + + fn.code = fn.code || "var $parts=[]; $parts.push('" + + str + .replace(/\\/g, '\\\\') // 处理模板中的\转义 + .replace(/[\r\t\n]/g, " ") // 去掉换行符和tab符,将模板合并为一行 + .split("<%").join("\t") // 将模板左标签<%替换为tab,起到分割作用 + .replace(/(^|%>)[^\t]*/g, function(str) { return str.replace(/'/g, "\\'"); }) // 将模板中文本部分的单引号替换为\' + .replace(/\t=(.*?)%>/g, "',$1,'") // 将模板中<%= %>的直接数据引用(无逻辑代码)与两侧的文本用'和,隔开,同时去掉了左标签产生的tab符 + .split("\t").join("');") // 将tab符(上面替换左标签产生)替换为'); 由于上一步已经把<%=产生的tab符去掉,因此这里实际替换的只有逻辑代码的左标签 + .split("%>").join("$parts.push('") // 把剩下的右标签%>(逻辑代码的)替换为"$parts.push('" + + "'); return $parts.join('');"; // 最后得到的就是一段JS代码,保留模板中的逻辑,并依次把模板中的常量和变量压入$parts数组 + + return data ? fn(data, env) : fn; // 如果传入了数据,则直接返回渲染结果HTML文本,否则返回一个渲染函数 + }; + $.adaptObject = function (element, defaults, option,template,plugin,pluginName) { + var $this= element; + + if (typeof option != 'string'){ + + // 获得配置信息 + var context=$.extend({}, defaults, typeof option == 'object' && option); + + var isFromTpl=false; + // 如果传入script标签的选择器 + if($.isArray($this) && $this.length && $($this)[0].nodeName.toLowerCase()=="script"){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl($this[0].innerHTML,context)).appendTo("body"); + isFromTpl=true; + } + // 如果传入模板字符串 + else if($.isArray($this) && $this.length && $this.selector== ""){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl($this[0].outerHTML,context)).appendTo("body"); + isFromTpl=true; + } + // 如果通过$.dialog()的方式调用 + else if(!$.isArray($this)){ + // 根据模板获得对象并插入到body中 + $this=$($.tpl(template,context)).appendTo("body"); + isFromTpl=true; + } + + } + + return $this.each(function () { + + var el = $(this); + // 读取对象缓存 + + var data = el.data('fz.'+pluginName); + + + + if (!data) el.data('fz.'+pluginName, + (data = new plugin(this,$.extend({}, defaults, typeof option == 'object' && option),isFromTpl) + + )); + + if (typeof option == 'string') data[option](); + }) + } +}(window.Zepto); + + + +/** + * User: jeakeyliang + * Date: 14-08-22 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _dialogTpl='<div class="ui-dialog">'+ + '<div class="ui-dialog-cnt">'+ + '<div class="ui-dialog-bd">'+ + '<div>'+ + '<h4><%=title%></h4>'+ + '<div><%=content%></div></div>'+ + '</div>'+ + '<div class="ui-dialog-ft ui-btn-group">'+ + '<% for (var i = 0; i < button.length; i++) { %>' + + '<% if (i == select) { %>' + + '<button type="button" data-role="button" class="select" id="dialogButton<%=i%>"><%=button[i]%></button>' + + '<% } else { %>' + + '<button type="button" data-role="button" id="dialogButton<%=i%>"><%=button[i]%></div>' + + '<% } %>' + + '<% } %>' + + '</div>'+ + '</div>'+ + '</div>'; + // 默认参数 + var defaults={ + title:'', + content:'', + button:['确认'], + select:0, + allowScroll:false, + callback:function(){} + } + // 构造函数 + var Dialog = function (el,option,isFromTpl) { + + this.option=$.extend(defaults,option); + this.element=$(el); + this._isFromTpl=isFromTpl; + this.button=$(el).find('[data-role="button"]'); + this._bindEvent(); + this.toggle(); + } + Dialog.prototype={ + _bindEvent:function(){ + var self=this; + self.button.on("tap",function(){ + var index=$(self.button).index($(this)); + // self.option.callback("button",index); + var e=$.Event("dialog:action"); + e.index=index; + self.element.trigger(e); + self.hide.apply(self); + }); + }, + toggle:function(){ + if(this.element.hasClass("show")){ + this.hide(); + }else{ + this.show(); + } + }, + show:function(){ + var self=this; + // self.option.callback("show"); + self.element.trigger($.Event("dialog:show")); + self.element.addClass("show"); + this.option.allowScroll && self.element.on("touchmove" , _stopScroll); + + }, + hide :function () { + var self=this; + // self.option.callback("hide"); + self.element.trigger($.Event("dialog:hide")); + self.element.off("touchmove" , _stopScroll); + setTimeout(function(){ + self.element.removeClass("show"); + self._isFromTpl&&self.element.remove(); + },300); + } + } + // 禁止冒泡 + function _stopScroll(){ + return false; + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_dialogTpl,Dialog,"dialog"); + } + $.fn.dialog=$.dialog= Plugin; +}(window.Zepto) + + + +/** + * User: jeakeyliang + * Date: 14-11-07 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _loadingTpl='<div class="ui-loading-block show">'+ + '<div class="ui-loading-cnt">'+ + '<i class="ui-loading-bright"></i>'+ + '<p><%=content%></p>'+ + '</div>'+ + '</div>'; + + // 默认参数 + var defaults={ + content:'加载中...' + } + // 构造函数 + var Loading = function (el,option,isFromTpl) { + var self=this; + this.element=$(el); + this._isFromTpl=isFromTpl; + this.option=$.extend(defaults,option); + this.show(); + } + Loading.prototype={ + show:function(){ + var e=$.Event('loading:show'); + this.element.trigger(e); + this.element.show(); + + }, + hide :function () { + var e=$.Event('loading:hide'); + this.element.trigger(e); + this.element.remove(); + } + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_loadingTpl,Loading,"loading"); + } + $.fn.loading=$.loading= Plugin; +}(window.Zepto) + + + +;(function ($) { + +var rAF = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { window.setTimeout(callback, 1000 / 60); }; + + +/* + * 工具类 + */ +var utils = (function () { + + var me = {}; + + var _elementStyle = document.createElement('div').style; + + var _vendor = (function () { + var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], + transform, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + transform = vendors[i] + 'ransform'; + if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); + } + return false; + })(); + + function _prefixStyle (style) { + if ( _vendor === false ) return false; + if ( _vendor === '' ) return style; + return _vendor + style.charAt(0).toUpperCase() + style.substr(1); + } + + + me.getTime = Date.now || function getTime () { return new Date().getTime(); }; + + + me.extend = function (target, obj) { + for ( var i in obj ) { + target[i] = obj[i]; + } + }; + + + me.addEvent = function (el, type, fn, capture) { + el.addEventListener(type, fn, !!capture); + }; + + + me.removeEvent = function (el, type, fn, capture) { + el.removeEventListener(type, fn, !!capture); + }; + + + me.prefixPointerEvent = function (pointerEvent) { + return window.MSPointerEvent ? + 'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10): + pointerEvent; + }; + + + /** + * 根据一定时间内的滑动距离计算出最终停止距离和时间。 + * @param current:当前滑动位置 + * @param start:touchStart 时候记录的开始位置,但是在touchmove时候可能被重写 + * @param time:touchstart 到手指离开时候经历的时间,同样可能被touchmove重写 + * @param lowerMargin:可移动的最大距离,这个一般为计算得出 this.wrapperHeight - this.scrollerHeight + * @param wrapperSize:如果有边界距离的话就是可拖动,不然碰到0的时候便停止 + * @param deceleration:匀减速 + * @returns {{destination: number, duration: number}} + */ + me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { + var distance = current - start, + speed = Math.abs(distance) / time, + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + + destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); + duration = speed / deceleration; + + if ( destination < lowerMargin ) { + destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if ( destination > 0 ) { + destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }; + + var _transform = _prefixStyle('transform'); + + me.extend(me, { + hasTransform: _transform !== false, + hasPerspective: _prefixStyle('perspective') in _elementStyle, + hasTouch: 'ontouchstart' in window, + hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed + hasTransition: _prefixStyle('transition') in _elementStyle + }); + + // This should find all Android browsers lower than build 535.19 (both stock browser and webview) + me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion)); + + me.extend(me.style = {}, { + transform: _transform, + transitionTimingFunction: _prefixStyle('transitionTimingFunction'), + transitionDuration: _prefixStyle('transitionDuration'), + transitionDelay: _prefixStyle('transitionDelay'), + transformOrigin: _prefixStyle('transformOrigin'), + transitionProperty: _prefixStyle('transitionProperty') + }); + + + me.offset = function (el) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + return { + left: left, + top: top + }; + }; + + + /* + * 配合 config 里面的 preventDefaultException 属性 + * 不对匹配到的 element 使用 e.preventDefault() + * 默认阻止所有事件的冒泡,包括 click 或 tap + */ + me.preventDefaultException = function (el, exceptions) { + for ( var i in exceptions ) { + if ( exceptions[i].test(el[i]) ) { + return true; + } + } + return false; + }; + + + me.extend(me.eventType = {}, { + touchstart: 1, + touchmove: 1, + touchend: 1, + + mousedown: 2, + mousemove: 2, + mouseup: 2, + + pointerdown: 3, + pointermove: 3, + pointerup: 3, + + MSPointerDown: 3, + MSPointerMove: 3, + MSPointerUp: 3 + }); + + + me.extend(me.ease = {}, { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function (k) { + return k * ( 2 - k ); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1) + fn: function (k) { + return Math.sqrt( 1 - ( --k * k ) ); + } + }, + back: { + style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', + fn: function (k) { + var b = 4; + return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; + } + }, + bounce: { + style: '', + fn: function (k) { + if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { + return 7.5625 * k * k; + } else if ( k < ( 2 / 2.75 ) ) { + return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; + } else if ( k < ( 2.5 / 2.75 ) ) { + return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; + } else { + return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + } + } + }, + elastic: { + style: '', + fn: function (k) { + var f = 0.22, + e = 0.4; + + if ( k === 0 ) { return 0; } + if ( k == 1 ) { return 1; } + + return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); + } + } + }); + + me.tap = function (e, eventName) { + var ev = document.createEvent('Event'); + ev.initEvent(eventName, true, true); + ev.pageX = e.pageX; + ev.pageY = e.pageY; + e.target.dispatchEvent(ev); + }; + + me.click = function (e) { + var target = e.target, + ev; + if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + target.screenX, target.screenY, target.clientX, target.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + + ev._constructed = true; + target.dispatchEvent(ev); + } + }; + + return me; +})(); + + + +/* + * 构造函数 + */ +function Scroll(el, options) { + + this.wrapper = typeof el == 'string' ? $(el)[0] : el; + + this.options = { + startX: 0, // 初始化 X 坐标 + startY: 0, // 初始化 Y 坐标 + scrollY: true, // 竖向滚动 + scrollX: false, // 默认非水平 + directionLockThreshold: 5, // 确定滚动方向的阈值 + momentum: true, // 是否开启惯性滚动 + + duration: 300, // transition 过渡时间 + + bounce: true, // 是否有反弹动画 + bounceTime: 600, // 反弹动画时间 + bounceEasing: '', // 反弹动画类型:'circular'(default), 'quadratic', 'back', 'bounce', 'elastic' + + preventDefault: true, // 是否阻止默认滚动事件(和冒泡有区别) + eventPassthrough: true, // 穿透,是否触发原生滑动(取值 true、false、vertical、horizental) + + freeScroll: false, // 任意方向的滚动。若 scrollX 和 scrollY 同时开启,则相当于 freeScroll + + bindToWrapper : true, // 事件是否绑定到 wrapper 元素上,否则大部分绑定到 window(若存在嵌套,则绑定在元素上最好) + resizePolling : 60, // resize 时候隔 60ms 就执行 refresh 方法重新获取位置信息(事件节流) + + disableMouse : false, // 是否禁用鼠标 + disableTouch : false, // 是否禁用touch事件 + disablePointer : false, // 是否禁用win系统的pointer事件 + + tap: true, // 是否模拟 tap 事件 + click: false, // 是否模拟点击事件(false 则使用原生click事件) + + preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, // 当遇到正则内的元素则不阻止冒泡 + + HWCompositing: true, // Hardware acceleration + useTransition: true, // Transition || requestAnimationFrame + useTransform: true // Translate || Left/Top + }; + + + for ( var i in options ) { + this.options[i] = options[i]; + } + + + // scroller + // ================================== + + if (!this.options.role && this.options.scrollX === false) { + this.options.eventPassthrough = 'horizontal'; // 竖直滚动的 scroller 不拦截横向原生滚动 + } + + // slide + // ================================== + + if (this.options.role === 'slider') { + + this.options.scrollX = true; + this.options.scrollY = false; + this.options.momentum = false; + + this.scroller = $('.ui-slider-content')[0]; + $(this.scroller.children[0]).addClass('current'); + + this.currentPage = 0; + this.count = this.scroller.children.length; + + this.scroller.style.width = this.count+"00%"; + + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + + + + if (this.options.indicator) { + var temp = '<ul class="ui-slider-indicators">'; + + for (var i=1; i<=this.count; i++) { + if (i===1) { + temp += '<li class="current">'+i+'</li>'; + } + else { + temp += '<li>'+i+'</li>'; + } + } + temp += '</ul>'; + $(this.wrapper).append(temp); + this.indicator = $('.ui-slider-indicators')[0]; + } + } + + + // tab + // ================================== + + else if (this.options.role === 'tab') { + + this.options.scrollX = true; + this.options.scrollY = false; + this.options.momentum = false; + + this.scroller = $('.ui-tab-content')[0]; + this.nav = $('.ui-tab-nav')[0]; + + $(this.scroller.children[0]).addClass('current'); + $(this.nav.children[0]).addClass('current'); + + this.currentPage = 0; + this.count = this.scroller.children.length; + + this.scroller.style.width = this.count+"00%"; + + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + + + } + else { + this.scroller = this.wrapper.children[0]; + } + this.scrollerStyle = this.scroller.style; + + + this.translateZ = utils.hasPerspective && this.options.HWCompositing ? ' translateZ(0)' : ''; + this.options.useTransition = utils.hasTransition && this.options.useTransition; + this.options.useTransform = utils.hasTransform && this.options.useTransform; + this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; + this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; + // If you want eventPassthrough I have to lock one of the axes + this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; + this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; + // With eventPassthrough we also need lockDirection mechanism + this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; + this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; + this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; + this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; + + if (this.options.tap === true) { + this.options.tap = 'tap'; + } + if (this.options.useTransform === false) { + this.scroller.style.position = 'relative'; + } + + // Some defaults + this.x = 0; + this.y = 0; + this.directionX = 0; + this.directionY = 0; + this._events = {}; + + this._init(); // 绑定各种事件 + this.refresh(); + + this.scrollTo(this.options.startX, this.options.startY); + this.enable(); + + // 自动播放 + if (this.options.autoplay) { + var context = this; + this.options.interval = this.options.interval || 2000; + this.options.flag = setTimeout(function(){ + context._autoplay.apply(context) + }, context.options.interval); + } +} + + + +Scroll.prototype = { + + _init: function () { + this._initEvents(); + }, + + _initEvents: function (remove) { + var eventType = remove ? utils.removeEvent : utils.addEvent, + target = this.options.bindToWrapper ? this.wrapper : window; + + /* + * 给 addEventListener 传递 this + * 程序会自动找到 handleEvent 方法作为回调函数 + */ + eventType(window, 'orientationchange', this); + eventType(window, 'resize', this); + + if ( this.options.click ) { + eventType(this.wrapper, 'click', this, true); + } + + if ( !this.options.disableMouse ) { + eventType(this.wrapper, 'mousedown', this); + eventType(target, 'mousemove', this); + eventType(target, 'mousecancel', this); + eventType(target, 'mouseup', this); + } + + if ( utils.hasPointer && !this.options.disablePointer ) { + eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); + eventType(target, utils.prefixPointerEvent('pointermove'), this); + eventType(target, utils.prefixPointerEvent('pointercancel'), this); + eventType(target, utils.prefixPointerEvent('pointerup'), this); + } + + if ( utils.hasTouch && !this.options.disableTouch ) { + eventType(this.wrapper, 'touchstart', this); + eventType(target, 'touchmove', this); + eventType(target, 'touchcancel', this); + eventType(target, 'touchend', this); + } + + eventType(this.scroller, 'transitionend', this); + eventType(this.scroller, 'webkitTransitionEnd', this); + eventType(this.scroller, 'oTransitionEnd', this); + eventType(this.scroller, 'MSTransitionEnd', this); + + // tab + // ============================= + if (this.options.role === 'tab') { + eventType(this.nav, 'touchend', this); + eventType(this.nav, 'mouseup', this); + eventType(this.nav, 'pointerup', this); + } + }, + + + refresh: function () { + var rf = this.wrapper.offsetHeight; // Force reflow + + // http://jsfiddle.net/y8Y32/25/ + // clientWidth = content + padding + this.wrapperWidth = this.wrapper.clientWidth; + this.wrapperHeight = this.wrapper.clientHeight; + + + // 添加 wrapper 的 padding 值到 scroller 身上,更符合使用预期 + var matrix = window.getComputedStyle(this.wrapper, null); + var pt = matrix['padding-top'].replace(/[^-\d.]/g, ''), + pb = matrix['padding-bottom'].replace(/[^-\d.]/g, ''), + pl = matrix['padding-left'].replace(/[^-\d.]/g, ''), + pr = matrix['padding-right'].replace(/[^-\d.]/g, ''); + + var matrix2 = window.getComputedStyle(this.scroller, null); + var mt2 = matrix2['margin-top'].replace(/[^-\d.]/g, ''), + mb2 = matrix2['margin-bottom'].replace(/[^-\d.]/g, ''), + ml2 = matrix2['margin-left'].replace(/[^-\d.]/g, ''), + mr2 = matrix2['margin-right'].replace(/[^-\d.]/g, ''); + + + // offsetWidth = content + padding + border + this.scrollerWidth = this.scroller.offsetWidth+parseInt(pl)+parseInt(pr)+parseInt(ml2)+parseInt(mr2); + this.scrollerHeight = this.scroller.offsetHeight+parseInt(pt)+parseInt(pb)+parseInt(mt2)+parseInt(mb2); + + + // slide + // ================================== + if (this.options.role === 'slider' || this.options.role === 'tab') { + this.itemWidth = this.scroller.children[0].clientWidth; + this.scrollWidth = this.itemWidth * this.count; + this.scrollerWidth = this.scrollWidth; + } + + this.maxScrollX = this.wrapperWidth - this.scrollerWidth; + this.maxScrollY = this.wrapperHeight - this.scrollerHeight; + + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + + if ( !this.hasHorizontalScroll ) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if ( !this.hasVerticalScroll ) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.endTime = 0; + this.directionX = 0; + this.directionY = 0; + + this.wrapperOffset = utils.offset(this.wrapper); + this.resetPosition(); + }, + + + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + this._end(e); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'transitionend': + case 'webkitTransitionEnd': + case 'oTransitionEnd': + case 'MSTransitionEnd': + this._transitionEnd(e); + break; + case 'wheel': + case 'DOMMouseScroll': + case 'mousewheel': + this._wheel(e); + break; + case 'keydown': + this._key(e); + break; + case 'click': + if ( !e._constructed ) { + e.preventDefault(); + e.stopPropagation(); + } + break; + } + }, + + + + _start: function (e) { + + if ( utils.eventType[e.type] != 1 ) { // 如果是鼠标点击,则只响应鼠标左键 + if ( e.button !== 0 ) { + return; + } + } + + if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { + return; + } + + // 如果 preventDefault === true 且 不是落后的安卓版本 且 不是需要过滤的 target 就阻止默认的行为 + if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, // 检验是触摸事件对象还是鼠标事件对象 + pos; + + this.initiated = utils.eventType[e.type]; // 初始化事件类型(1:触摸,2:鼠标,3:pointer) + this.moved = false; + this.distX = 0; + this.distY = 0; + this.directionX = 0; + this.directionY = 0; + this.directionLocked = 0; + + this._transitionTime(); + this.startTime = utils.getTime(); + + // 定住正在滑动的 scroller,slider/tab 不这么做 + if ( this.options.useTransition && this.isInTransition && this.options.role !== 'slider' && this.options.role !== 'tab') { + this.isInTransition = false; + pos = this.getComputedPosition(); + this._translate(Math.round(pos.x), Math.round(pos.y)); + } + // 场景:(没有使用 Transition 属性) + else if ( !this.options.useTransition && this.isAnimating ) { + this.isAnimating = false; + } + + this.startX = this.x; + this.startY = this.y; + this.absStartX = this.x; + this.absStartY = this.y; + this.pointX = point.pageX; + this.pointY = point.pageY; + + // throttle + // ====================== + if (this.options.autoplay) { + var context = this; + + clearTimeout(this.options.flag); + this.options.flag = setTimeout(function() { + context._autoplay.apply(context); + }, context.options.interval); + } + + event.stopPropagation(); + }, + + + + _move: function (e) { + + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { // 如果事件类型和 touchstart 初始化的事件类型不一致,退出 + return; + } + if ( this.options.preventDefault ) { // 这么做才能确保 Android 下 touchend 能被正常触发(需测试) + e.preventDefault(); + } + var point = e.touches ? e.touches[0] : e, + deltaX = point.pageX - this.pointX, + deltaY = point.pageY - this.pointY, + timestamp = utils.getTime(), + newX, newY, + absDistX, absDistY; + + this.pointX = point.pageX; + this.pointY = point.pageY; + + this.distX += deltaX; + this.distY += deltaY; + absDistX = Math.abs(this.distX); + absDistY = Math.abs(this.distY); + + + // 如果在很长的时间内只移动了少于 10 像素的距离,那么不会触发惯性滚动 + if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { + return; + } + + // 屏蔽滚动方向的另外一个方向(可配置) + if ( !this.directionLocked && !this.options.freeScroll ) { + if ( absDistX > absDistY + this.options.directionLockThreshold ) { + this.directionLocked = 'h'; // lock horizontally + } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { + this.directionLocked = 'v'; // lock vertically + } else { + this.directionLocked = 'n'; // no lock + } + } + if ( this.directionLocked == 'h' ) { + // slider/tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller).children('li').height('auto'); + } + if ( this.options.eventPassthrough == 'vertical' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'horizontal' ) { + this.initiated = false; + return; + } + deltaY = 0; // 不断重置垂直偏移量为 0 + } + else if ( this.directionLocked == 'v' ) { + if ( this.options.eventPassthrough == 'horizontal' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'vertical' ) { + this.initiated = false; + return; + } + deltaX = 0; // 不断重置水平偏移量为 0 + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + // Slow down if outside of the boundaries + if ( newX > 0 || newX < this.maxScrollX ) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if ( newY > 0 || newY < this.maxScrollY ) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + this.moved = true; // 滚动开始 + this._translate(newX, newY); + + if ( timestamp - this.startTime > 300 ) { // 每 300 毫秒重置一次初始值 + this.startTime = timestamp; + this.startX = this.x; + this.startY = this.y; + } + }, + + + + _end: function (e) { + + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.changedTouches ? e.changedTouches[0] : e, // 移开屏幕的那个触摸点,只会包含在 changedTouches 列表中,而不会包含在 touches 或 targetTouches 列表中 + momentumX, + momentumY, + duration = utils.getTime() - this.startTime, + newX = Math.round(this.x), + newY = Math.round(this.y), + distanceX = Math.abs(newX - this.startX), + distanceY = Math.abs(newY - this.startY), + time = 0, + easing = ''; + + this.isInTransition = 0; + this.initiated = 0; + this.endTime = utils.getTime(); + + + if ( this.resetPosition(this.options.bounceTime) ) { // reset if we are outside of the boundaries + if (this.options.role === 'tab') { + $(this.scroller.children[this.currentPage]).siblings('li').height(0); + } + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + if (!this.moved) { // we scrolled less than 10 pixels + if (this.options.tap && utils.eventType[e.type] === 1) { + utils.tap(e, this.options.tap); + } + if ( this.options.click) { + utils.click(e); + } + } + + // 300ms 内的滑动要启动惯性滚动 + if ( this.options.momentum && duration < 300 ) { + momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 }; + momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = 1; + } + + if ( newX != this.x || newY != this.y ) { + // change easing function when scroller goes out of the boundaries + if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { + easing = utils.ease.quadratic; + } + this.scrollTo(newX, newY, time, easing); + return; + } + + + // tab + // ========================== + if (this.options.role === 'tab' && $(event.target).closest('ul').hasClass('ui-tab-nav')) { + $(this.nav).children().removeClass('current'); + $(event.target).addClass('current'); + var tempCurrentPage = this.currentPage; + this.currentPage = $(event.target).index(); + + $(this.scroller).children().height('auto'); // tab 外层高度自适应 + this._execEvent('beforeScrollStart', tempCurrentPage, this.currentPage); + } + + + + // slider & tab + // ============================== + if (this.options.role === 'slider' || this.options.role === 'tab') { + + if (distanceX < 30) { + this.scrollTo(-this.itemWidth*this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + else if (newX-this.startX<0) { // 向前 + this._execEvent('beforeScrollStart', this.currentPage, this.currentPage+1); + this.scrollTo(-this.itemWidth*++this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + else if (newX-this.startX>=0) { // 向后 + this._execEvent('beforeScrollStart', this.currentPage, this.currentPage-1); + this.scrollTo(-this.itemWidth*--this.currentPage, 0, this.options.bounceTime, this.options.bounceEasing); + } + + // tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller.children[this.currentPage]).siblings('li').height(0); + } + + if (this.indicator && distanceX >= 30) { + $(this.indicator).children().removeClass('current'); + $(this.indicator.children[this.currentPage]).addClass('current'); + } + else if (this.nav && distanceX >= 30) { + $(this.nav).children().removeClass('current'); + $(this.nav.children[this.currentPage]).addClass('current'); + } + + $(this.scroller).children().removeClass('current'); + $(this.scroller.children[this.currentPage]).addClass('current'); + } + }, + + + _resize: function () { + var that = this; + clearTimeout(this.resizeTimeout); + this.resizeTimeout = setTimeout(function () { + that.refresh(); + }, this.options.resizePolling); + }, + + + _transitionEnd: function (e) { + if ( e.target != this.scroller || !this.isInTransition ) { + return; + } + this._transitionTime(); + + if ( !this.resetPosition(this.options.bounceTime) ) { + this.isInTransition = false; + this._execEvent('scrollEnd', this.currentPage); + } + }, + + + destroy: function () { + this._initEvents(true); // 去除事件绑定 + }, + + + resetPosition: function (time) { + var x = this.x, + y = this.y; + + time = time || 0; + + if ( !this.hasHorizontalScroll || this.x > 0 ) { + x = 0; + } else if ( this.x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( !this.hasVerticalScroll || this.y > 0 ) { + y = 0; + } else if ( this.y < this.maxScrollY ) { + y = this.maxScrollY; + } + + if ( x == this.x && y == this.y ) { + return false; + } + this.scrollTo(x, y, time, this.options.bounceEasing); + return true; + }, + + + + disable: function () { + this.enabled = false; + }, + + enable: function () { + this.enabled = true; + }, + + + + on: function (type, fn) { + if ( !this._events[type] ) { + this._events[type] = []; + } + this._events[type].push(fn); + }, + off: function (type, fn) { + if ( !this._events[type] ) { + return; + } + + var index = this._events[type].indexOf(fn); + + if ( index > -1 ) { + this._events[type].splice(index, 1); + } + }, + + + _execEvent: function (type) { + if ( !this._events[type] ) { + return; + } + var i = 0, + l = this._events[type].length; + + if ( !l ) { + return; + } + for ( ; i < l; i++ ) { + this._events[type][i].apply(this, [].slice.call(arguments, 1)); + } + }, + + + scrollTo: function (x, y, time, easing) { + easing = easing || utils.ease.circular; + + this.isInTransition = this.options.useTransition && time > 0; + + if ( !time || (this.options.useTransition && easing.style) ) { + + if (this.options.role === 'slider' || this.options.role === 'tab') { // 不添加判断会影响 left/top 的过渡 + time = this.options.duration; + this.scrollerStyle[utils.style.transitionProperty] = utils.style.transform; + } + this.scrollerStyle[utils.style.transitionTimingFunction] = easing.style; + this._transitionTime(time); + this._translate(x, y); + } else { + this._animate(x, y, time, easing.fn); + } + }, + + + scrollToElement: function (el, time, offsetX, offsetY, easing) { + el = el.nodeType ? el : this.scroller.querySelector(el); + + if ( !el ) { + return; + } + var pos = utils.offset(el); + pos.left -= this.wrapperOffset.left; + pos.top -= this.wrapperOffset.top; + + // if offsetX/Y are true we center the element to the screen + // 若 offsetX/Y 都是 true,则会滚动到元素在屏幕中间的位置 + if ( offsetX === true ) { + offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); + } + if ( offsetY === true ) { + offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); + } + pos.left -= offsetX || 0; + pos.top -= offsetY || 0; + pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; + pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; + + time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; + + this.scrollTo(pos.left, pos.top, time, easing); + }, + + + _transitionTime: function (time) { + time = time || 0; + this.scrollerStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.scrollerStyle[utils.style.transitionDuration] = '0.001s'; + } + }, + + + _translate: function (x, y) { + if ( this.options.useTransform ) { + if(this.options.slidingY === 'y'){ + this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ; + }else{ + this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,0px)' + this.translateZ; + } + } else { + x = Math.round(x); + y = Math.round(y); + this.scrollerStyle.left = x + 'px'; + this.scrollerStyle.top = y + 'px'; + } + this.x = x; + this.y = y; + }, + + + getComputedPosition: function () { + var matrix = window.getComputedStyle(this.scroller, null), + x, y; + + if ( this.options.useTransform ) { + matrix = matrix[utils.style.transform].split(')')[0].split(', '); + x = +(matrix[12] || matrix[4]); + y = +(matrix[13] || matrix[5]); + } else { + x = +matrix.left.replace(/[^-\d.]/g, ''); + y = +matrix.top.replace(/[^-\d.]/g, ''); + } + + return { x: x, y: y }; + }, + + + _animate: function (destX, destY, duration, easingFn) { // 当浏览器不支持 transition 时提供的退化方案 requestAnimationFrame + var that = this, + startX = this.x, + startY = this.y, + startTime = utils.getTime(), + destTime = startTime + duration; + + function step () { + var now = utils.getTime(), + newX, newY, + easing; + + if ( now >= destTime ) { + that.isAnimating = false; + that._translate(destX, destY); + + if ( !that.resetPosition(that.options.bounceTime) ) { + that._execEvent('scrollEnd', this.currentPage); + } + return; + } + + now = ( now - startTime ) / duration; + easing = easingFn(now); + newX = ( destX - startX ) * easing + startX; + newY = ( destY - startY ) * easing + startY; + that._translate(newX, newY); + + if ( that.isAnimating ) { + rAF(step); + } + } + this.isAnimating = true; + step(); + }, + + + _autoplay: function() { + var self = this, + curPage = self.currentPage; + + self.currentPage = self.currentPage >= self.count-1 ? 0 : ++self.currentPage; + self._execEvent('beforeScrollStart', curPage, self.currentPage); // 对于自动播放的 slider/tab,这个时机就是 beforeScrollStart + + // tab 外层高度自适应 + if (this.options.role === 'tab') { + $(this.scroller).children().height('auto'); + document.body.scrollTop = 0; + } + self.scrollTo(-self.itemWidth*self.currentPage, 0, self.options.bounceTime, self.options.bounceEasing); + + if (self.indicator) { + $(self.indicator).children().removeClass('current'); + $(self.indicator.children[self.currentPage]).addClass('current'); + $(self.scroller).children().removeClass('current'); + $(self.scroller.children[self.currentPage]).addClass('current'); + } + else if (self.nav) { + $(self.nav).children().removeClass('current'); + $(self.nav.children[self.currentPage]).addClass('current'); + $(self.scroller).children().removeClass('current'); + $(self.scroller.children[self.currentPage]).addClass('current'); + } + + self.options.flag = setTimeout(function() { + self._autoplay.apply(self); + }, self.options.interval); + } + + +}; + +// Scroll.utils = utils; +window.fz = window.fz || {}; +window.frozen = window.frozen || {}; +window.fz.Scroll = window.frozen.Scroll = Scroll; + +/* + * 兼容 RequireJS 和 Sea.js + */ +if (typeof define === "function") { + define(function(require, exports, module) { + module.exports = Scroll; + }) +} + +})(window.Zepto); +/** + * User: jeakeyliang + * Date: 14-11-07 + * Time: 下午9:20 + */ + +!function($){ + + // 默认模板 + var _tipsTpl='<div class="ui-poptips ui-poptips-<%=type%>">'+ + '<div class="ui-poptips-cnt">'+ + '<i></i><%=content%>'+ + '</div>'+ + '</div>'; + + // 默认参数 + var defaults={ + content:'', + stayTime:1000, + type:'info', + callback:function(){} + } + // 构造函数 + var Tips = function (el,option,isFromTpl) { + var self=this; + this.element=$(el); + this._isFromTpl=isFromTpl; + this.elementHeight=$(el).height(); + + this.option=$.extend(defaults,option); + $(el).css({ + "-webkit-transform":"translateY(-"+this.elementHeight+"px)" + }); + setTimeout(function(){ + $(el).css({ + "-webkit-transition":"all .5s" + }); + self.show(); + },20); + + } + Tips.prototype={ + show:function(){ + var self=this; + // self.option.callback("show"); + self.element.trigger($.Event("tips:show")); + this.element.css({ + "-webkit-transform":"translateY(0px)" + }); + if(self.option.stayTime>0){ + setTimeout(function(){ + self.hide(); + },self.option.stayTime) + } + }, + hide :function () { + var self=this; + self.element.trigger($.Event("tips:hide")); + this.element.css({ + "-webkit-transform":"translateY(-"+this.elementHeight+"px)" + }); + setTimeout(function(){ + self._isFromTpl&&self.element.remove(); + },500) + + + } + } + function Plugin(option) { + + return $.adaptObject(this, defaults, option,_tipsTpl,Tips,"tips"); + } + $.fn.tips=$.tips= Plugin; +}(window.Zepto) + + diff --git a/hyhproject/wechat2/view/default/frozenui/js/zepto.min.js b/hyhproject/wechat2/view/default/frozenui/js/zepto.min.js new file mode 100755 index 0000000..3d65b8c --- /dev/null +++ b/hyhproject/wechat2/view/default/frozenui/js/zepto.min.js @@ -0,0 +1,2585 @@ +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +var Zepto = (function() { + var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice, + document = window.document, + elementDisplay = {}, classCache = {}, + cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, + fragmentRE = /^\s*<(\w+|!)[^>]*>/, + singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rootNodeRE = /^(?:body|html)$/i, + capitalRE = /([A-Z])/g, + + // special attributes that should be get/set via method calls + methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], + + adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], + table = document.createElement('table'), + tableRow = document.createElement('tr'), + containers = { + 'tr': document.createElement('tbody'), + 'tbody': table, 'thead': table, 'tfoot': table, + 'td': tableRow, 'th': tableRow, + '*': document.createElement('div') + }, + readyRE = /complete|loaded|interactive/, + simpleSelectorRE = /^[\w-]*$/, + class2type = {}, + toString = class2type.toString, + zepto = {}, + camelize, uniq, + tempParent = document.createElement('div'), + propMap = { + 'tabindex': 'tabIndex', + 'readonly': 'readOnly', + 'for': 'htmlFor', + 'class': 'className', + 'maxlength': 'maxLength', + 'cellspacing': 'cellSpacing', + 'cellpadding': 'cellPadding', + 'rowspan': 'rowSpan', + 'colspan': 'colSpan', + 'usemap': 'useMap', + 'frameborder': 'frameBorder', + 'contenteditable': 'contentEditable' + }, + isArray = Array.isArray || + function(object){ return object instanceof Array } + + zepto.matches = function(element, selector) { + if (!selector || !element || element.nodeType !== 1) return false + var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || + element.oMatchesSelector || element.matchesSelector + if (matchesSelector) return matchesSelector.call(element, selector) + // fall back to performing a selector: + var match, parent = element.parentNode, temp = !parent + if (temp) (parent = tempParent).appendChild(element) + match = ~zepto.qsa(parent, selector).indexOf(element) + temp && tempParent.removeChild(element) + return match + } + + function type(obj) { + return obj == null ? String(obj) : + class2type[toString.call(obj)] || "object" + } + + function isFunction(value) { return type(value) == "function" } + function isWindow(obj) { return obj != null && obj == obj.window } + function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } + function isObject(obj) { return type(obj) == "object" } + function isPlainObject(obj) { + return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype + } + function likeArray(obj) { return typeof obj.length == 'number' } + + function compact(array) { return filter.call(array, function(item){ return item != null }) } + function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } + camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } + function dasherize(str) { + return str.replace(/::/g, '/') + .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') + .replace(/([a-z\d])([A-Z])/g, '$1_$2') + .replace(/_/g, '-') + .toLowerCase() + } + uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } + + function classRE(name) { + return name in classCache ? + classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) + } + + function maybeAddPx(name, value) { + return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value + } + + function defaultDisplay(nodeName) { + var element, display + if (!elementDisplay[nodeName]) { + element = document.createElement(nodeName) + document.body.appendChild(element) + display = getComputedStyle(element, '').getPropertyValue("display") + element.parentNode.removeChild(element) + display == "none" && (display = "block") + elementDisplay[nodeName] = display + } + return elementDisplay[nodeName] + } + + function children(element) { + return 'children' in element ? + slice.call(element.children) : + $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) + } + + function Z(dom, selector) { + var i, len = dom ? dom.length : 0 + for (i = 0; i < len; i++) this[i] = dom[i] + this.length = len + this.selector = selector || '' + } + + // `$.zepto.fragment` takes a html string and an optional tag name + // to generate DOM nodes nodes from the given html string. + // The generated DOM nodes are returned as an array. + // This function can be overriden in plugins for example to make + // it compatible with browsers that don't support the DOM fully. + zepto.fragment = function(html, name, properties) { + var dom, nodes, container + + // A special case optimization for a single tag + if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) + + if (!dom) { + if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>") + if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 + if (!(name in containers)) name = '*' + + container = containers[name] + container.innerHTML = '' + html + dom = $.each(slice.call(container.childNodes), function(){ + container.removeChild(this) + }) + } + + if (isPlainObject(properties)) { + nodes = $(dom) + $.each(properties, function(key, value) { + if (methodAttributes.indexOf(key) > -1) nodes[key](value) + else nodes.attr(key, value) + }) + } + + return dom + } + + // `$.zepto.Z` swaps out the prototype of the given `dom` array + // of nodes with `$.fn` and thus supplying all the Zepto functions + // to the array. This method can be overriden in plugins. + zepto.Z = function(dom, selector) { + return new Z(dom, selector) + } + + // `$.zepto.isZ` should return `true` if the given object is a Zepto + // collection. This method can be overriden in plugins. + zepto.isZ = function(object) { + return object instanceof zepto.Z + } + + // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and + // takes a CSS selector and an optional context (and handles various + // special cases). + // This method can be overriden in plugins. + zepto.init = function(selector, context) { + var dom + // If nothing given, return an empty Zepto collection + if (!selector) return zepto.Z() + // Optimize for string selectors + else if (typeof selector == 'string') { + selector = selector.trim() + // If it's a html fragment, create nodes from it + // Note: In both Chrome 21 and Firefox 15, DOM error 12 + // is thrown if the fragment doesn't begin with < + if (selector[0] == '<' && fragmentRE.test(selector)) + dom = zepto.fragment(selector, RegExp.$1, context), selector = null + // If there's a context, create a collection on that context first, and select + // nodes from there + else if (context !== undefined) return $(context).find(selector) + // If it's a CSS selector, use it to select nodes. + else dom = zepto.qsa(document, selector) + } + // If a function is given, call it when the DOM is ready + else if (isFunction(selector)) return $(document).ready(selector) + // If a Zepto collection is given, just return it + else if (zepto.isZ(selector)) return selector + else { + // normalize array if an array of nodes is given + if (isArray(selector)) dom = compact(selector) + // Wrap DOM nodes. + else if (isObject(selector)) + dom = [selector], selector = null + // If it's a html fragment, create nodes from it + else if (fragmentRE.test(selector)) + dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null + // If there's a context, create a collection on that context first, and select + // nodes from there + else if (context !== undefined) return $(context).find(selector) + // And last but no least, if it's a CSS selector, use it to select nodes. + else dom = zepto.qsa(document, selector) + } + // create a new Zepto collection from the nodes found + return zepto.Z(dom, selector) + } + + // `$` will be the base `Zepto` object. When calling this + // function just call `$.zepto.init, which makes the implementation + // details of selecting nodes and creating Zepto collections + // patchable in plugins. + $ = function(selector, context){ + return zepto.init(selector, context) + } + + function extend(target, source, deep) { + for (key in source) + if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { + if (isPlainObject(source[key]) && !isPlainObject(target[key])) + target[key] = {} + if (isArray(source[key]) && !isArray(target[key])) + target[key] = [] + extend(target[key], source[key], deep) + } + else if (source[key] !== undefined) target[key] = source[key] + } + + // Copy all but undefined properties from one or more + // objects to the `target` object. + $.extend = function(target){ + var deep, args = slice.call(arguments, 1) + if (typeof target == 'boolean') { + deep = target + target = args.shift() + } + args.forEach(function(arg){ extend(target, arg, deep) }) + return target + } + + // `$.zepto.qsa` is Zepto's CSS selector implementation which + // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. + // This method can be overriden in plugins. + zepto.qsa = function(element, selector){ + var found, + maybeID = selector[0] == '#', + maybeClass = !maybeID && selector[0] == '.', + nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked + isSimple = simpleSelectorRE.test(nameOnly) + return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById + ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : + (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] : + slice.call( + isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName + maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class + element.getElementsByTagName(selector) : // Or a tag + element.querySelectorAll(selector) // Or it's not simple, and we need to query all + ) + } + + function filtered(nodes, selector) { + return selector == null ? $(nodes) : $(nodes).filter(selector) + } + + $.contains = document.documentElement.contains ? + function(parent, node) { + return parent !== node && parent.contains(node) + } : + function(parent, node) { + while (node && (node = node.parentNode)) + if (node === parent) return true + return false + } + + function funcArg(context, arg, idx, payload) { + return isFunction(arg) ? arg.call(context, idx, payload) : arg + } + + function setAttribute(node, name, value) { + value == null ? node.removeAttribute(name) : node.setAttribute(name, value) + } + + // access className property while respecting SVGAnimatedString + function className(node, value){ + var klass = node.className || '', + svg = klass && klass.baseVal !== undefined + + if (value === undefined) return svg ? klass.baseVal : klass + svg ? (klass.baseVal = value) : (node.className = value) + } + + // "true" => true + // "false" => false + // "null" => null + // "42" => 42 + // "42.5" => 42.5 + // "08" => "08" + // JSON => parse if valid + // String => self + function deserializeValue(value) { + try { + return value ? + value == "true" || + ( value == "false" ? false : + value == "null" ? null : + +value + "" == value ? +value : + /^[\[\{]/.test(value) ? $.parseJSON(value) : + value ) + : value + } catch(e) { + return value + } + } + + $.type = type + $.isFunction = isFunction + $.isWindow = isWindow + $.isArray = isArray + $.isPlainObject = isPlainObject + + $.isEmptyObject = function(obj) { + var name + for (name in obj) return false + return true + } + + $.inArray = function(elem, array, i){ + return emptyArray.indexOf.call(array, elem, i) + } + + $.camelCase = camelize + $.trim = function(str) { + return str == null ? "" : String.prototype.trim.call(str) + } + + // plugin compatibility + $.uuid = 0 + $.support = { } + $.expr = { } + $.noop = function() {} + + $.map = function(elements, callback){ + var value, values = [], i, key + if (likeArray(elements)) + for (i = 0; i < elements.length; i++) { + value = callback(elements[i], i) + if (value != null) values.push(value) + } + else + for (key in elements) { + value = callback(elements[key], key) + if (value != null) values.push(value) + } + return flatten(values) + } + + $.each = function(elements, callback){ + var i, key + if (likeArray(elements)) { + for (i = 0; i < elements.length; i++) + if (callback.call(elements[i], i, elements[i]) === false) return elements + } else { + for (key in elements) + if (callback.call(elements[key], key, elements[key]) === false) return elements + } + + return elements + } + + $.grep = function(elements, callback){ + return filter.call(elements, callback) + } + + if (window.JSON) $.parseJSON = JSON.parse + + // Populate the class2type map + $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase() + }) + + // Define methods that will be available on all + // Zepto collections + $.fn = { + constructor: zepto.Z, + length: 0, + + // Because a collection acts like an array + // copy over these useful array functions. + forEach: emptyArray.forEach, + reduce: emptyArray.reduce, + push: emptyArray.push, + sort: emptyArray.sort, + splice: emptyArray.splice, + indexOf: emptyArray.indexOf, + concat: function(){ + var i, value, args = [] + for (i = 0; i < arguments.length; i++) { + value = arguments[i] + args[i] = zepto.isZ(value) ? value.toArray() : value + } + return concat.apply(zepto.isZ(this) ? this.toArray() : this, args) + }, + + // `map` and `slice` in the jQuery API work differently + // from their array counterparts + map: function(fn){ + return $($.map(this, function(el, i){ return fn.call(el, i, el) })) + }, + slice: function(){ + return $(slice.apply(this, arguments)) + }, + + ready: function(callback){ + // need to check if document.body exists for IE as that browser reports + // document ready when it hasn't yet created the body element + if (readyRE.test(document.readyState) && document.body) callback($) + else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) + return this + }, + get: function(idx){ + return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] + }, + toArray: function(){ return this.get() }, + size: function(){ + return this.length + }, + remove: function(){ + return this.each(function(){ + if (this.parentNode != null) + this.parentNode.removeChild(this) + }) + }, + each: function(callback){ + emptyArray.every.call(this, function(el, idx){ + return callback.call(el, idx, el) !== false + }) + return this + }, + filter: function(selector){ + if (isFunction(selector)) return this.not(this.not(selector)) + return $(filter.call(this, function(element){ + return zepto.matches(element, selector) + })) + }, + add: function(selector,context){ + return $(uniq(this.concat($(selector,context)))) + }, + is: function(selector){ + return this.length > 0 && zepto.matches(this[0], selector) + }, + not: function(selector){ + var nodes=[] + if (isFunction(selector) && selector.call !== undefined) + this.each(function(idx){ + if (!selector.call(this,idx)) nodes.push(this) + }) + else { + var excludes = typeof selector == 'string' ? this.filter(selector) : + (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) + this.forEach(function(el){ + if (excludes.indexOf(el) < 0) nodes.push(el) + }) + } + return $(nodes) + }, + has: function(selector){ + return this.filter(function(){ + return isObject(selector) ? + $.contains(this, selector) : + $(this).find(selector).size() + }) + }, + eq: function(idx){ + return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) + }, + first: function(){ + var el = this[0] + return el && !isObject(el) ? el : $(el) + }, + last: function(){ + var el = this[this.length - 1] + return el && !isObject(el) ? el : $(el) + }, + find: function(selector){ + var result, $this = this + if (!selector) result = $() + else if (typeof selector == 'object') + result = $(selector).filter(function(){ + var node = this + return emptyArray.some.call($this, function(parent){ + return $.contains(parent, node) + }) + }) + else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) + else result = this.map(function(){ return zepto.qsa(this, selector) }) + return result + }, + closest: function(selector, context){ + var node = this[0], collection = false + if (typeof selector == 'object') collection = $(selector) + while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) + node = node !== context && !isDocument(node) && node.parentNode + return $(node) + }, + parents: function(selector){ + var ancestors = [], nodes = this + while (nodes.length > 0) + nodes = $.map(nodes, function(node){ + if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { + ancestors.push(node) + return node + } + }) + return filtered(ancestors, selector) + }, + parent: function(selector){ + return filtered(uniq(this.pluck('parentNode')), selector) + }, + children: function(selector){ + return filtered(this.map(function(){ return children(this) }), selector) + }, + contents: function() { + return this.map(function() { return this.contentDocument || slice.call(this.childNodes) }) + }, + siblings: function(selector){ + return filtered(this.map(function(i, el){ + return filter.call(children(el.parentNode), function(child){ return child!==el }) + }), selector) + }, + empty: function(){ + return this.each(function(){ this.innerHTML = '' }) + }, + // `pluck` is borrowed from Prototype.js + pluck: function(property){ + return $.map(this, function(el){ return el[property] }) + }, + show: function(){ + return this.each(function(){ + this.style.display == "none" && (this.style.display = '') + if (getComputedStyle(this, '').getPropertyValue("display") == "none") + this.style.display = defaultDisplay(this.nodeName) + }) + }, + replaceWith: function(newContent){ + return this.before(newContent).remove() + }, + wrap: function(structure){ + var func = isFunction(structure) + if (this[0] && !func) + var dom = $(structure).get(0), + clone = dom.parentNode || this.length > 1 + + return this.each(function(index){ + $(this).wrapAll( + func ? structure.call(this, index) : + clone ? dom.cloneNode(true) : dom + ) + }) + }, + wrapAll: function(structure){ + if (this[0]) { + $(this[0]).before(structure = $(structure)) + var children + // drill down to the inmost element + while ((children = structure.children()).length) structure = children.first() + $(structure).append(this) + } + return this + }, + wrapInner: function(structure){ + var func = isFunction(structure) + return this.each(function(index){ + var self = $(this), contents = self.contents(), + dom = func ? structure.call(this, index) : structure + contents.length ? contents.wrapAll(dom) : self.append(dom) + }) + }, + unwrap: function(){ + this.parent().each(function(){ + $(this).replaceWith($(this).children()) + }) + return this + }, + clone: function(){ + return this.map(function(){ return this.cloneNode(true) }) + }, + hide: function(){ + return this.css("display", "none") + }, + toggle: function(setting){ + return this.each(function(){ + var el = $(this) + ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() + }) + }, + prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, + next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, + html: function(html){ + return 0 in arguments ? + this.each(function(idx){ + var originHtml = this.innerHTML + $(this).empty().append( funcArg(this, html, idx, originHtml) ) + }) : + (0 in this ? this[0].innerHTML : null) + }, + text: function(text){ + return 0 in arguments ? + this.each(function(idx){ + var newText = funcArg(this, text, idx, this.textContent) + this.textContent = newText == null ? '' : ''+newText + }) : + (0 in this ? this[0].textContent : null) + }, + attr: function(name, value){ + var result + return (typeof name == 'string' && !(1 in arguments)) ? + (!this.length || this[0].nodeType !== 1 ? undefined : + (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result + ) : + this.each(function(idx){ + if (this.nodeType !== 1) return + if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) + else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) + }) + }, + removeAttr: function(name){ + return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ + setAttribute(this, attribute) + }, this)}) + }, + prop: function(name, value){ + name = propMap[name] || name + return (1 in arguments) ? + this.each(function(idx){ + this[name] = funcArg(this, value, idx, this[name]) + }) : + (this[0] && this[0][name]) + }, + data: function(name, value){ + var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() + + var data = (1 in arguments) ? + this.attr(attrName, value) : + this.attr(attrName) + + return data !== null ? deserializeValue(data) : undefined + }, + val: function(value){ + return 0 in arguments ? + this.each(function(idx){ + this.value = funcArg(this, value, idx, this.value) + }) : + (this[0] && (this[0].multiple ? + $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : + this[0].value) + ) + }, + offset: function(coordinates){ + if (coordinates) return this.each(function(index){ + var $this = $(this), + coords = funcArg(this, coordinates, index, $this.offset()), + parentOffset = $this.offsetParent().offset(), + props = { + top: coords.top - parentOffset.top, + left: coords.left - parentOffset.left + } + + if ($this.css('position') == 'static') props['position'] = 'relative' + $this.css(props) + }) + if (!this.length) return null + if (!$.contains(document.documentElement, this[0])) + return {top: 0, left: 0} + var obj = this[0].getBoundingClientRect() + return { + left: obj.left + window.pageXOffset, + top: obj.top + window.pageYOffset, + width: Math.round(obj.width), + height: Math.round(obj.height) + } + }, + css: function(property, value){ + if (arguments.length < 2) { + var computedStyle, element = this[0] + if(!element) return + computedStyle = getComputedStyle(element, '') + if (typeof property == 'string') + return element.style[camelize(property)] || computedStyle.getPropertyValue(property) + else if (isArray(property)) { + var props = {} + $.each(property, function(_, prop){ + props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) + }) + return props + } + } + + var css = '' + if (type(property) == 'string') { + if (!value && value !== 0) + this.each(function(){ this.style.removeProperty(dasherize(property)) }) + else + css = dasherize(property) + ":" + maybeAddPx(property, value) + } else { + for (key in property) + if (!property[key] && property[key] !== 0) + this.each(function(){ this.style.removeProperty(dasherize(key)) }) + else + css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' + } + + return this.each(function(){ this.style.cssText += ';' + css }) + }, + index: function(element){ + return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) + }, + hasClass: function(name){ + if (!name) return false + return emptyArray.some.call(this, function(el){ + return this.test(className(el)) + }, classRE(name)) + }, + addClass: function(name){ + if (!name) return this + return this.each(function(idx){ + if (!('className' in this)) return + classList = [] + var cls = className(this), newName = funcArg(this, name, idx, cls) + newName.split(/\s+/g).forEach(function(klass){ + if (!$(this).hasClass(klass)) classList.push(klass) + }, this) + classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) + }) + }, + removeClass: function(name){ + return this.each(function(idx){ + if (!('className' in this)) return + if (name === undefined) return className(this, '') + classList = className(this) + funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ + classList = classList.replace(classRE(klass), " ") + }) + className(this, classList.trim()) + }) + }, + toggleClass: function(name, when){ + if (!name) return this + return this.each(function(idx){ + var $this = $(this), names = funcArg(this, name, idx, className(this)) + names.split(/\s+/g).forEach(function(klass){ + (when === undefined ? !$this.hasClass(klass) : when) ? + $this.addClass(klass) : $this.removeClass(klass) + }) + }) + }, + scrollTop: function(value){ + if (!this.length) return + var hasScrollTop = 'scrollTop' in this[0] + if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset + return this.each(hasScrollTop ? + function(){ this.scrollTop = value } : + function(){ this.scrollTo(this.scrollX, value) }) + }, + scrollLeft: function(value){ + if (!this.length) return + var hasScrollLeft = 'scrollLeft' in this[0] + if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset + return this.each(hasScrollLeft ? + function(){ this.scrollLeft = value } : + function(){ this.scrollTo(value, this.scrollY) }) + }, + position: function() { + if (!this.length) return + + var elem = this[0], + // Get *real* offsetParent + offsetParent = this.offsetParent(), + // Get correct offsets + offset = this.offset(), + parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 + offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 + + // Add offsetParent borders + parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 + parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + } + }, + offsetParent: function() { + return this.map(function(){ + var parent = this.offsetParent || document.body + while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") + parent = parent.offsetParent + return parent + }) + } + } + + // for now + $.fn.detach = $.fn.remove + + // Generate the `width` and `height` functions + ;['width', 'height'].forEach(function(dimension){ + var dimensionProperty = + dimension.replace(/./, function(m){ return m[0].toUpperCase() }) + + $.fn[dimension] = function(value){ + var offset, el = this[0] + if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : + isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : + (offset = this.offset()) && offset[dimension] + else return this.each(function(idx){ + el = $(this) + el.css(dimension, funcArg(this, value, idx, el[dimension]())) + }) + } + }) + + function traverseNode(node, fun) { + fun(node) + for (var i = 0, len = node.childNodes.length; i < len; i++) + traverseNode(node.childNodes[i], fun) + } + + // Generate the `after`, `prepend`, `before`, `append`, + // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. + adjacencyOperators.forEach(function(operator, operatorIndex) { + var inside = operatorIndex % 2 //=> prepend, append + + $.fn[operator] = function(){ + // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings + var argType, nodes = $.map(arguments, function(arg) { + argType = type(arg) + return argType == "object" || argType == "array" || arg == null ? + arg : zepto.fragment(arg) + }), + parent, copyByClone = this.length > 1 + if (nodes.length < 1) return this + + return this.each(function(_, target){ + parent = inside ? target : target.parentNode + + // convert all methods to a "before" operation + target = operatorIndex == 0 ? target.nextSibling : + operatorIndex == 1 ? target.firstChild : + operatorIndex == 2 ? target : + null + + var parentInDocument = $.contains(document.documentElement, parent) + + nodes.forEach(function(node){ + if (copyByClone) node = node.cloneNode(true) + else if (!parent) return $(node).remove() + + parent.insertBefore(node, target) + if (parentInDocument) traverseNode(node, function(el){ + if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && + (!el.type || el.type === 'text/javascript') && !el.src) + window['eval'].call(window, el.innerHTML) + }) + }) + }) + } + + // after => insertAfter + // prepend => prependTo + // before => insertBefore + // append => appendTo + $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ + $(html)[operator](this) + return this + } + }) + + zepto.Z.prototype = Z.prototype = $.fn + + // Export internal API functions in the `$.zepto` namespace + zepto.uniq = uniq + zepto.deserializeValue = deserializeValue + $.zepto = zepto + + return $ +})() + +// If `$` is not yet defined, point it to `Zepto` +window.Zepto = Zepto +window.$ === undefined && (window.$ = Zepto) + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + var _zid = 1, undefined, + slice = Array.prototype.slice, + isFunction = $.isFunction, + isString = function(obj){ return typeof obj == 'string' }, + handlers = {}, + specialEvents={}, + focusinSupported = 'onfocusin' in window, + focus = { focus: 'focusin', blur: 'focusout' }, + hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } + + specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' + + function zid(element) { + return element._zid || (element._zid = _zid++) + } + function findHandlers(element, event, fn, selector) { + event = parse(event) + if (event.ns) var matcher = matcherFor(event.ns) + return (handlers[zid(element)] || []).filter(function(handler) { + return handler + && (!event.e || handler.e == event.e) + && (!event.ns || matcher.test(handler.ns)) + && (!fn || zid(handler.fn) === zid(fn)) + && (!selector || handler.sel == selector) + }) + } + function parse(event) { + var parts = ('' + event).split('.') + return {e: parts[0], ns: parts.slice(1).sort().join(' ')} + } + function matcherFor(ns) { + return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') + } + + function eventCapture(handler, captureSetting) { + return handler.del && + (!focusinSupported && (handler.e in focus)) || + !!captureSetting + } + + function realEvent(type) { + return hover[type] || (focusinSupported && focus[type]) || type + } + + function add(element, events, fn, data, selector, delegator, capture){ + var id = zid(element), set = (handlers[id] || (handlers[id] = [])) + events.split(/\s/).forEach(function(event){ + if (event == 'ready') return $(document).ready(fn) + var handler = parse(event) + handler.fn = fn + handler.sel = selector + // emulate mouseenter, mouseleave + if (handler.e in hover) fn = function(e){ + var related = e.relatedTarget + if (!related || (related !== this && !$.contains(this, related))) + return handler.fn.apply(this, arguments) + } + handler.del = delegator + var callback = delegator || fn + handler.proxy = function(e){ + e = compatible(e) + if (e.isImmediatePropagationStopped()) return + e.data = data + var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) + if (result === false) e.preventDefault(), e.stopPropagation() + return result + } + handler.i = set.length + set.push(handler) + if ('addEventListener' in element) + element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) + }) + } + function remove(element, events, fn, selector, capture){ + var id = zid(element) + ;(events || '').split(/\s/).forEach(function(event){ + findHandlers(element, event, fn, selector).forEach(function(handler){ + delete handlers[id][handler.i] + if ('removeEventListener' in element) + element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) + }) + }) + } + + $.event = { add: add, remove: remove } + + $.proxy = function(fn, context) { + var args = (2 in arguments) && slice.call(arguments, 2) + if (isFunction(fn)) { + var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } + proxyFn._zid = zid(fn) + return proxyFn + } else if (isString(context)) { + if (args) { + args.unshift(fn[context], fn) + return $.proxy.apply(null, args) + } else { + return $.proxy(fn[context], fn) + } + } else { + throw new TypeError("expected function") + } + } + + $.fn.bind = function(event, data, callback){ + return this.on(event, data, callback) + } + $.fn.unbind = function(event, callback){ + return this.off(event, callback) + } + $.fn.one = function(event, selector, data, callback){ + return this.on(event, selector, data, callback, 1) + } + + var returnTrue = function(){return true}, + returnFalse = function(){return false}, + ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/, + eventMethods = { + preventDefault: 'isDefaultPrevented', + stopImmediatePropagation: 'isImmediatePropagationStopped', + stopPropagation: 'isPropagationStopped' + } + + function compatible(event, source) { + if (source || !event.isDefaultPrevented) { + source || (source = event) + + $.each(eventMethods, function(name, predicate) { + var sourceMethod = source[name] + event[name] = function(){ + this[predicate] = returnTrue + return sourceMethod && sourceMethod.apply(source, arguments) + } + event[predicate] = returnFalse + }) + + if (source.defaultPrevented !== undefined ? source.defaultPrevented : + 'returnValue' in source ? source.returnValue === false : + source.getPreventDefault && source.getPreventDefault()) + event.isDefaultPrevented = returnTrue + } + return event + } + + function createProxy(event) { + var key, proxy = { originalEvent: event } + for (key in event) + if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] + + return compatible(proxy, event) + } + + $.fn.delegate = function(selector, event, callback){ + return this.on(event, selector, callback) + } + $.fn.undelegate = function(selector, event, callback){ + return this.off(event, selector, callback) + } + + $.fn.live = function(event, callback){ + $(document.body).delegate(this.selector, event, callback) + return this + } + $.fn.die = function(event, callback){ + $(document.body).undelegate(this.selector, event, callback) + return this + } + + $.fn.on = function(event, selector, data, callback, one){ + var autoRemove, delegator, $this = this + if (event && !isString(event)) { + $.each(event, function(type, fn){ + $this.on(type, selector, data, fn, one) + }) + return $this + } + + if (!isString(selector) && !isFunction(callback) && callback !== false) + callback = data, data = selector, selector = undefined + if (callback === undefined || data === false) + callback = data, data = undefined + + if (callback === false) callback = returnFalse + + return $this.each(function(_, element){ + if (one) autoRemove = function(e){ + remove(element, e.type, callback) + return callback.apply(this, arguments) + } + + if (selector) delegator = function(e){ + var evt, match = $(e.target).closest(selector, element).get(0) + if (match && match !== element) { + evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) + return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) + } + } + + add(element, event, callback, data, selector, delegator || autoRemove) + }) + } + $.fn.off = function(event, selector, callback){ + var $this = this + if (event && !isString(event)) { + $.each(event, function(type, fn){ + $this.off(type, selector, fn) + }) + return $this + } + + if (!isString(selector) && !isFunction(callback) && callback !== false) + callback = selector, selector = undefined + + if (callback === false) callback = returnFalse + + return $this.each(function(){ + remove(this, event, callback, selector) + }) + } + + $.fn.trigger = function(event, args){ + event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) + event._args = args + return this.each(function(){ + // handle focus(), blur() by calling them directly + if (event.type in focus && typeof this[event.type] == "function") this[event.type]() + // items in the collection might not be DOM elements + else if ('dispatchEvent' in this) this.dispatchEvent(event) + else $(this).triggerHandler(event, args) + }) + } + + // triggers event handlers on current element just as if an event occurred, + // doesn't trigger an actual event, doesn't bubble + $.fn.triggerHandler = function(event, args){ + var e, result + this.each(function(i, element){ + e = createProxy(isString(event) ? $.Event(event) : event) + e._args = args + e.target = element + $.each(findHandlers(element, event.type || event), function(i, handler){ + result = handler.proxy(e) + if (e.isImmediatePropagationStopped()) return false + }) + }) + return result + } + + // shortcut methods for `.bind(event, fn)` for each event type + ;('focusin focusout focus blur load resize scroll unload click dblclick '+ + 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ + 'change select keydown keypress keyup error').split(' ').forEach(function(event) { + $.fn[event] = function(callback) { + return (0 in arguments) ? + this.bind(event, callback) : + this.trigger(event) + } + }) + + $.Event = function(type, props) { + if (!isString(type)) props = type, type = props.type + var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true + if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) + event.initEvent(type, bubbles, true) + return compatible(event) + } + +})(Zepto) + +/*! touchjs v0.2.14 2014-08-05 */ +'use strict'; +(function(root, factory) { + if (typeof define === 'function' && (define.amd || define.cmd)) { + define(factory); //Register as a module. + } else { + root.touch = factory(); + } +}(this, function() { + +var utils = {}; + +utils.PCevts = { + 'touchstart': 'mousedown', + 'touchmove': 'mousemove', + 'touchend': 'mouseup', + 'touchcancel': 'mouseout' +}; + +utils.hasTouch = ('ontouchstart' in window); + +utils.getType = function(obj) { + return Object.prototype.toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); +}; + +utils.getSelector = function(el) { + if (el.id) { + return "#" + el.id; + } + if (el.className) { + var cns = el.className.split(/\s+/); + return "." + cns.join("."); + } else if (el === document) { + return "body"; + } else { + return el.tagName.toLowerCase(); + } +}; + +utils.matchSelector = function(target, selector) { + return target.webkitMatchesSelector(selector); +}; + +utils.getEventListeners = function(el) { + return el.listeners; +}; + +utils.getPCevts = function(evt) { + return this.PCevts[evt] || evt; +}; + +utils.forceReflow = function() { + var tempDivID = "reflowDivBlock"; + var domTreeOpDiv = document.getElementById(tempDivID); + if (!domTreeOpDiv) { + domTreeOpDiv = document.createElement("div"); + domTreeOpDiv.id = tempDivID; + document.body.appendChild(domTreeOpDiv); + } + var parentNode = domTreeOpDiv.parentNode; + var nextSibling = domTreeOpDiv.nextSibling; + parentNode.removeChild(domTreeOpDiv); + parentNode.insertBefore(domTreeOpDiv, nextSibling); +}; + +utils.simpleClone = function(obj) { + return Object.create(obj); +}; + +utils.getPosOfEvent = function(ev) { + if (this.hasTouch) { + var posi = []; + var src = null; + + for (var t = 0, len = ev.touches.length; t < len; t++) { + src = ev.touches[t]; + posi.push({ + x: src.pageX, + y: src.pageY + }); + } + return posi; + } else { + return [{ + x: ev.pageX, + y: ev.pageY + }]; + } +}; + +utils.getDistance = function(pos1, pos2) { + var x = pos2.x - pos1.x, + y = pos2.y - pos1.y; + return Math.sqrt((x * x) + (y * y)); +}; + +utils.getFingers = function(ev) { + return ev.touches ? ev.touches.length : 1; +}; + +utils.calScale = function(pstart, pmove) { + if (pstart.length >= 2 && pmove.length >= 2) { + var disStart = this.getDistance(pstart[1], pstart[0]); + var disEnd = this.getDistance(pmove[1], pmove[0]); + + return disEnd / disStart; + } + return 1; +}; + +utils.getAngle = function(p1, p2) { + return Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI; +}; + +utils.getAngle180 = function(p1, p2) { + var agl = Math.atan((p2.y - p1.y) * -1 / (p2.x - p1.x)) * (180 / Math.PI); + return (agl < 0 ? (agl + 180) : agl); +}; + +utils.getDirectionFromAngle = function(agl) { + var directions = { + up: agl < -45 && agl > -135, + down: agl >= 45 && agl < 135, + left: agl >= 135 || agl <= -135, + right: agl >= -45 && agl <= 45 + }; + for (var key in directions) { + if (directions[key]) return key; + } + return null; +}; + +utils.getXYByElement = function(el) { + var left = 0, + top = 0; + + while (el.offsetParent) { + left += el.offsetLeft; + top += el.offsetTop; + el = el.offsetParent; + } + return { + left: left, + top: top + }; +}; + +utils.reset = function() { + startEvent = moveEvent = endEvent = null; + __tapped = __touchStart = startSwiping = startPinch = false; + startDrag = false; + pos = {}; + __rotation_single_finger = false; +}; + +utils.isTouchMove = function(ev) { + return (ev.type === 'touchmove' || ev.type === 'mousemove'); +}; + +utils.isTouchEnd = function(ev) { + return (ev.type === 'touchend' || ev.type === 'mouseup' || ev.type === 'touchcancel'); +}; + +utils.env = (function() { + var os = {}, ua = navigator.userAgent, + android = ua.match(/(Android)[\s\/]+([\d\.]+)/), + ios = ua.match(/(iPad|iPhone|iPod)\s+OS\s([\d_\.]+)/), + wp = ua.match(/(Windows\s+Phone)\s([\d\.]+)/), + isWebkit = /WebKit\/[\d.]+/i.test(ua), + isSafari = ios ? (navigator.standalone ? isWebkit : (/Safari/i.test(ua) && !/CriOS/i.test(ua) && !/MQQBrowser/i.test(ua))) : false; + if (android) { + os.android = true; + os.version = android[2]; + } + if (ios) { + os.ios = true; + os.version = ios[2].replace(/_/g, '.'); + os.ios7 = /^7/.test(os.version); + if (ios[1] === 'iPad') { + os.ipad = true; + } else if (ios[1] === 'iPhone') { + os.iphone = true; + os.iphone5 = screen.height == 568; + } else if (ios[1] === 'iPod') { + os.ipod = true; + } + } + if (wp) { + os.wp = true; + os.version = wp[2]; + os.wp8 = /^8/.test(os.version); + } + if (isWebkit) { + os.webkit = true; + } + if (isSafari) { + os.safari = true; + } + return os; +})(); + +/** 底层事件绑定/代理支持 */ +var engine = { + proxyid: 0, + proxies: [], + trigger: function(el, evt, detail) { + + detail = detail || {}; + var e, opt = { + bubbles: true, + cancelable: true, + detail: detail + }; + + try { + if (typeof CustomEvent !== 'undefined') { + e = new CustomEvent(evt, opt); + if (el) { + el.dispatchEvent(e); + } + } else { + e = document.createEvent("CustomEvent"); + e.initCustomEvent(evt, true, true, detail); + if (el) { + el.dispatchEvent(e); + } + } + } catch (ex) { + console.warn("Touch.js is not supported by environment."); + } + }, + bind: function(el, evt, handler) { + el.listeners = el.listeners || {}; + if (!el.listeners[evt]) { + el.listeners[evt] = [handler]; + } else { + el.listeners[evt].push(handler); + } + var proxy = function(e) { + if (utils.env.ios7) { + utils.forceReflow(); + } + e.originEvent = e; + for (var p in e.detail) { + if (p !== 'type') { + e[p] = e.detail[p]; + } + } + e.startRotate = function() { + __rotation_single_finger = true; + }; + var returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + }; + handler.proxy = handler.proxy || {}; + if (!handler.proxy[evt]) { + handler.proxy[evt] = [this.proxyid++]; + } else { + handler.proxy[evt].push(this.proxyid++); + } + this.proxies.push(proxy); + if (el.addEventListener) { + el.addEventListener(evt, proxy, false); + } + }, + unbind: function(el, evt, handler) { + if (!handler) { + var handlers = el.listeners[evt]; + if (handlers && handlers.length) { + handlers.forEach(function(handler) { + el.removeEventListener(evt, handler, false); + }); + } + } else { + var proxyids = handler.proxy[evt]; + if (proxyids && proxyids.length) { + proxyids.forEach(function(proxyid) { + if (el.removeEventListener) { + el.removeEventListener(evt, this.proxies[this.proxyid], false); + } + }); + } + } + }, + delegate: function(el, evt, sel, handler) { + var proxy = function(e) { + var target, returnValue; + e.originEvent = e; + for (var p in e.detail) { + if (p !== 'type') { + e[p] = e.detail[p]; + } + } + e.startRotate = function() { + __rotation_single_finger = true; + }; + var integrateSelector = utils.getSelector(el) + " " + sel; + var match = utils.matchSelector(e.target, integrateSelector); + var ischild = utils.matchSelector(e.target, integrateSelector + " " + e.target.nodeName); + if (!match && ischild) { + if (utils.env.ios7) { + utils.forceReflow(); + } + target = e.target; + while (!utils.matchSelector(target, integrateSelector)) { + target = target.parentNode; + } + returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + } else { + if (utils.env.ios7) { + utils.forceReflow(); + } + if (match || ischild) { + returnValue = handler.call(e.target, e); + if (typeof returnValue !== "undefined" && !returnValue) { + e.stopPropagation(); + e.preventDefault(); + } + } + } + }; + handler.proxy = handler.proxy || {}; + if (!handler.proxy[evt]) { + handler.proxy[evt] = [this.proxyid++]; + } else { + handler.proxy[evt].push(this.proxyid++); + } + this.proxies.push(proxy); + el.listeners = el.listeners || {}; + if (!el.listeners[evt]) { + el.listeners[evt] = [proxy]; + } else { + el.listeners[evt].push(proxy); + } + if (el.addEventListener) { + el.addEventListener(evt, proxy, false); + } + }, + undelegate: function(el, evt, sel, handler) { + if (!handler) { + var listeners = el.listeners[evt]; + listeners.forEach(function(proxy) { + el.removeEventListener(evt, proxy, false); + }); + } else { + var proxyids = handler.proxy[evt]; + if (proxyids.length) { + proxyids.forEach(function(proxyid) { + if (el.removeEventListener) { + el.removeEventListener(evt, this.proxies[this.proxyid], false); + } + }); + } + } + } +}; + +var config = { + tap: true, + doubleTap: true, + tapMaxDistance: 10, + hold: true, + tapTime: 200, + holdTime: 650, + maxDoubleTapInterval: 300, + swipe: true, + swipeTime: 300, + swipeMinDistance: 18, + swipeFactor: 5, + drag: true, + pinch: true, + minScaleRate: 0, + minRotationAngle: 0 +}; + +var smrEventList = { + TOUCH_START: 'touchstart', + TOUCH_MOVE: 'touchmove', + TOUCH_END: 'touchend', + TOUCH_CANCEL: 'touchcancel', + MOUSE_DOWN: 'mousedown', + MOUSE_MOVE: 'mousemove', + MOUSE_UP: 'mouseup', + CLICK: 'click', + PINCH_START: 'pinchstart', + PINCH_END: 'pinchend', + PINCH: 'pinch', + PINCH_IN: 'pinchin', + PINCH_OUT: 'pinchout', + ROTATION_LEFT: 'rotateleft', + ROTATION_RIGHT: 'rotateright', + ROTATION: 'rotate', + SWIPE_START: 'swipestart', + SWIPING: 'swiping', + SWIPE_END: 'swipeend', + SWIPE_LEFT: 'swipeleft', + SWIPE_RIGHT: 'swiperight', + SWIPE_UP: 'swipeup', + SWIPE_DOWN: 'swipedown', + SWIPE: 'swipe', + DRAG: 'drag', + DRAGSTART: 'dragstart', + DRAGEND: 'dragend', + HOLD: 'hold', + TAP: 'tap', + DOUBLE_TAP: 'doubletap' +}; + +/** 手势识别 */ +var pos = { + start: null, + move: null, + end: null +}; + +var startTime = 0; +var fingers = 0; +var startEvent = null; +var moveEvent = null; +var endEvent = null; +var startSwiping = false; +var startPinch = false; +var startDrag = false; + +var __offset = {}; +var __touchStart = false; +var __holdTimer = null; +var __tapped = false; +var __lastTapEndTime = null; +var __tapTimer = null; + +var __scale_last_rate = 1; +var __rotation_single_finger = false; +var __rotation_single_start = []; +var __initial_angle = 0; +var __rotation = 0; + +var __prev_tapped_end_time = 0; +var __prev_tapped_pos = null; + +var gestures = { + getAngleDiff: function(currentPos) { + var diff = parseInt(__initial_angle - utils.getAngle180(currentPos[0], currentPos[1]), 10); + var count = 0; + + while (Math.abs(diff - __rotation) > 90 && count++ < 50) { + if (__rotation < 0) { + diff -= 180; + } else { + diff += 180; + } + } + __rotation = parseInt(diff, 10); + return __rotation; + }, + pinch: function(ev) { + var el = ev.target; + if (config.pinch) { + if (!__touchStart) return; + if (utils.getFingers(ev) < 2) { + if (!utils.isTouchEnd(ev)) return; + } + var scale = utils.calScale(pos.start, pos.move); + var rotation = this.getAngleDiff(pos.move); + var eventObj = { + type: '', + originEvent: ev, + scale: scale, + rotation: rotation, + direction: (rotation > 0 ? 'right' : 'left'), + fingersCount: utils.getFingers(ev) + }; + if (!startPinch) { + startPinch = true; + eventObj.fingerStatus = "start"; + engine.trigger(el, smrEventList.PINCH_START, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = "move"; + engine.trigger(el, smrEventList.PINCH, eventObj); + } else if (utils.isTouchEnd(ev)) { + eventObj.fingerStatus = "end"; + engine.trigger(el, smrEventList.PINCH_END, eventObj); + utils.reset(); + } + + if (Math.abs(1 - scale) > config.minScaleRate) { + var scaleEv = utils.simpleClone(eventObj); + + //手势放大, 触发pinchout事件 + var scale_diff = 0.00000000001; //防止touchend的scale与__scale_last_rate相等,不触发事件的情况。 + if (scale > __scale_last_rate) { + __scale_last_rate = scale - scale_diff; + engine.trigger(el, smrEventList.PINCH_OUT, scaleEv, false); + } //手势缩小,触发pinchin事件 + else if (scale < __scale_last_rate) { + __scale_last_rate = scale + scale_diff; + engine.trigger(el, smrEventList.PINCH_IN, scaleEv, false); + } + + if (utils.isTouchEnd(ev)) { + __scale_last_rate = 1; + } + } + + if (Math.abs(rotation) > config.minRotationAngle) { + var rotationEv = utils.simpleClone(eventObj), + eventType; + + eventType = rotation > 0 ? smrEventList.ROTATION_RIGHT : smrEventList.ROTATION_LEFT; + engine.trigger(el, eventType, rotationEv, false); + engine.trigger(el, smrEventList.ROTATION, eventObj); + } + + } + }, + rotateSingleFinger: function(ev) { + var el = ev.target; + if (__rotation_single_finger && utils.getFingers(ev) < 2) { + if (!pos.move) return; + if (__rotation_single_start.length < 2) { + var docOff = utils.getXYByElement(el); + + __rotation_single_start = [{ + x: docOff.left + el.offsetWidth / 2, + y: docOff.top + el.offsetHeight / 2 + }, + pos.move[0] + ]; + __initial_angle = parseInt(utils.getAngle180(__rotation_single_start[0], __rotation_single_start[1]), 10); + } + var move = [__rotation_single_start[0], pos.move[0]]; + var rotation = this.getAngleDiff(move); + var eventObj = { + type: '', + originEvent: ev, + rotation: rotation, + direction: (rotation > 0 ? 'right' : 'left'), + fingersCount: utils.getFingers(ev) + }; + if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = "move"; + } else if (utils.isTouchEnd(ev) || ev.type === 'mouseout') { + eventObj.fingerStatus = "end"; + engine.trigger(el, smrEventList.PINCH_END, eventObj); + utils.reset(); + } + var eventType = rotation > 0 ? smrEventList.ROTATION_RIGHT : smrEventList.ROTATION_LEFT; + engine.trigger(el, eventType, eventObj); + engine.trigger(el, smrEventList.ROTATION, eventObj); + } + }, + swipe: function(ev) { + var el = ev.target; + if (!__touchStart || !pos.move || utils.getFingers(ev) > 1) { + return; + } + + var now = Date.now(); + var touchTime = now - startTime; + var distance = utils.getDistance(pos.start[0], pos.move[0]); + var position = { + x: pos.move[0].x - __offset.left, + y: pos.move[0].y - __offset.top + }; + var angle = utils.getAngle(pos.start[0], pos.move[0]); + var direction = utils.getDirectionFromAngle(angle); + var touchSecond = touchTime / 1000; + var factor = ((10 - config.swipeFactor) * 10 * touchSecond * touchSecond); + var eventObj = { + type: smrEventList.SWIPE, + originEvent: ev, + position: position, + direction: direction, + distance: distance, + distanceX: pos.move[0].x - pos.start[0].x, + distanceY: pos.move[0].y - pos.start[0].y, + x: pos.move[0].x - pos.start[0].x, + y: pos.move[0].y - pos.start[0].y, + angle: angle, + duration: touchTime, + fingersCount: utils.getFingers(ev), + factor: factor + }; + if (config.swipe) { + var swipeTo = function() { + var elt = smrEventList; + switch (direction) { + case 'up': + engine.trigger(el, elt.SWIPE_UP, eventObj); + break; + case 'down': + engine.trigger(el, elt.SWIPE_DOWN, eventObj); + break; + case 'left': + engine.trigger(el, elt.SWIPE_LEFT, eventObj); + break; + case 'right': + engine.trigger(el, elt.SWIPE_RIGHT, eventObj); + break; + } + }; + + if (!startSwiping) { + eventObj.fingerStatus = eventObj.swipe = 'start'; + startSwiping = true; + engine.trigger(el, smrEventList.SWIPE_START, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'move'; + engine.trigger(el, smrEventList.SWIPING, eventObj); + + if (touchTime > config.swipeTime && touchTime < config.swipeTime + 50 && distance > config.swipeMinDistance) { + swipeTo(); + engine.trigger(el, smrEventList.SWIPE, eventObj, false); + } + } else if (utils.isTouchEnd(ev) || ev.type === 'mouseout') { + eventObj.fingerStatus = eventObj.swipe = 'end'; + engine.trigger(el, smrEventList.SWIPE_END, eventObj); + + if (config.swipeTime > touchTime && distance > config.swipeMinDistance) { + swipeTo(); + engine.trigger(el, smrEventList.SWIPE, eventObj, false); + } + } + } + + if (config.drag) { + if (!startDrag) { + eventObj.fingerStatus = eventObj.swipe = 'start'; + startDrag = true; + engine.trigger(el, smrEventList.DRAGSTART, eventObj); + } else if (utils.isTouchMove(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'move'; + engine.trigger(el, smrEventList.DRAG, eventObj); + } else if (utils.isTouchEnd(ev)) { + eventObj.fingerStatus = eventObj.swipe = 'end'; + engine.trigger(el, smrEventList.DRAGEND, eventObj); + } + + } + }, + tap: function(ev) { + var el = ev.target; + if (config.tap) { + var now = Date.now(); + var touchTime = now - startTime; + var distance = utils.getDistance(pos.start[0], pos.move ? pos.move[0] : pos.start[0]); + + clearTimeout(__holdTimer); + var isDoubleTap = (function() { + if (__prev_tapped_pos && config.doubleTap && (startTime - __prev_tapped_end_time) < config.maxDoubleTapInterval) { + var doubleDis = utils.getDistance(__prev_tapped_pos, pos.start[0]); + if (doubleDis < 16) return true; + } + return false; + })(); + + if (isDoubleTap) { + clearTimeout(__tapTimer); + engine.trigger(el, smrEventList.DOUBLE_TAP, { + type: smrEventList.DOUBLE_TAP, + originEvent: ev, + position: pos.start[0] + }); + return; + } + + if (config.tapMaxDistance < distance) return; + + if (config.holdTime > touchTime && utils.getFingers(ev) <= 1) { + __tapped = true; + __prev_tapped_end_time = now; + __prev_tapped_pos = pos.start[0]; + __tapTimer = setTimeout(function() { + engine.trigger(el, smrEventList.TAP, { + type: smrEventList.TAP, + originEvent: ev, + fingersCount: utils.getFingers(ev), + position: __prev_tapped_pos + }); + }, + config.tapTime); + } + } + }, + hold: function(ev) { + var el = ev.target; + if (config.hold) { + clearTimeout(__holdTimer); + + __holdTimer = setTimeout(function() { + if (!pos.start) return; + var distance = utils.getDistance(pos.start[0], pos.move ? pos.move[0] : pos.start[0]); + if (config.tapMaxDistance < distance) return; + + if (!__tapped) { + engine.trigger(el, "hold", { + type: 'hold', + originEvent: ev, + fingersCount: utils.getFingers(ev), + position: pos.start[0] + }); + } + }, + config.holdTime); + } + } +}; + +var handlerOriginEvent = function(ev) { + + var el = ev.target; + switch (ev.type) { + case 'touchstart': + case 'mousedown': + __rotation_single_start = []; + __touchStart = true; + if (!pos.start || pos.start.length < 2) { + pos.start = utils.getPosOfEvent(ev); + } + if (utils.getFingers(ev) >= 2) { + __initial_angle = parseInt(utils.getAngle180(pos.start[0], pos.start[1]), 10); + } + + startTime = Date.now(); + startEvent = ev; + __offset = {}; + + var box = el.getBoundingClientRect(); + var docEl = document.documentElement; + __offset = { + top: box.top + (window.pageYOffset || docEl.scrollTop) - (docEl.clientTop || 0), + left: box.left + (window.pageXOffset || docEl.scrollLeft) - (docEl.clientLeft || 0) + }; + + gestures.hold(ev); + break; + case 'touchmove': + case 'mousemove': + if (!__touchStart || !pos.start) return; + pos.move = utils.getPosOfEvent(ev); + if (utils.getFingers(ev) >= 2) { + gestures.pinch(ev); + } else if (__rotation_single_finger) { + gestures.rotateSingleFinger(ev); + } else { + gestures.swipe(ev); + } + break; + case 'touchend': + case 'touchcancel': + case 'mouseup': + case 'mouseout': + if (!__touchStart) return; + endEvent = ev; + + if (startPinch) { + gestures.pinch(ev); + } else if (__rotation_single_finger) { + gestures.rotateSingleFinger(ev); + } else if (startSwiping) { + gestures.swipe(ev); + } else { + gestures.tap(ev); + } + + utils.reset(); + __initial_angle = 0; + __rotation = 0; + if (ev.touches && ev.touches.length === 1) { + __touchStart = true; + __rotation_single_finger = true; + } + break; + } +}; + +var _on = function() { + + var evts, handler, evtMap, sel, args = arguments; + if (args.length < 2 || args > 4) { + return console.error("unexpected arguments!"); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.slice.call(els) : [els]; + //事件绑定 + if (args.length === 3 && utils.getType(args[1]) === 'string') { + evts = args[1].split(" "); + handler = args[2]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, handler); + }); + }); + return; + } + + function evtMapDelegate(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.delegate(el, evt, sel, evtMap[evt]); + }); + } + //mapEvent delegate + if (args.length === 3 && utils.getType(args[1]) === 'object') { + evtMap = args[1]; + sel = args[2]; + for (var evt1 in evtMap) { + evtMapDelegate(evt1); + } + return; + } + + function evtMapBind(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, evtMap[evt]); + }); + } + + //mapEvent bind + if (args.length === 2 && utils.getType(args[1]) === 'object') { + evtMap = args[1]; + for (var evt2 in evtMap) { + evtMapBind(evt2); + } + return; + } + + //兼容factor config + if (args.length === 4 && utils.getType(args[2]) === "object") { + evts = args[1].split(" "); + handler = args[3]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + els.forEach(function(el) { + engine.bind(el, evt, handler); + }); + }); + return; + } + + //事件代理 + if (args.length === 4) { + var el = els[0]; + evts = args[1].split(" "); + sel = args[2]; + handler = args[3]; + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.delegate(el, evt, sel, handler); + }); + return; + } +}; + +var _off = function() { + var evts, handler; + var args = arguments; + if (args.length < 1 || args.length > 4) { + return console.error("unexpected arguments!"); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.slice.call(els) : [els]; + + if (args.length === 1 || args.length === 2) { + els.forEach(function(el) { + evts = args[1] ? args[1].split(" ") : Object.keys(el.listeners); + if (evts.length) { + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.unbind(el, evt); + engine.undelegate(el, evt); + }); + } + }); + return; + } + + if (args.length === 3 && utils.getType(args[2]) === 'function') { + handler = args[2]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.unbind(el, evt, handler); + }); + }); + return; + } + + if (args.length === 3 && utils.getType(args[2]) === 'string') { + var sel = args[2]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.undelegate(el, evt, sel); + }); + }); + return; + } + + if (args.length === 4) { + handler = args[3]; + els.forEach(function(el) { + evts = args[1].split(" "); + evts.forEach(function(evt) { + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + engine.undelegate(el, evt, sel, handler); + }); + }); + return; + } +}; + +var _dispatch = function(el, evt, detail) { + var args = arguments; + if (!utils.hasTouch) { + evt = utils.getPCevts(evt); + } + var els = utils.getType(args[0]) === 'string' ? document.querySelectorAll(args[0]) : args[0]; + els = els.length ? Array.prototype.call(els) : [els]; + + els.forEach(function(el) { + engine.trigger(el, evt, detail); + }); +}; + + //init gesture + function init() { + + var mouseEvents = 'mouseup mousedown mousemove mouseout', + touchEvents = 'touchstart touchmove touchend touchcancel'; + var bindingEvents = utils.hasTouch ? touchEvents : mouseEvents; + + bindingEvents.split(" ").forEach(function(evt) { + document.addEventListener(evt, handlerOriginEvent, false); + }); + } + + init(); + + var exports = {}; + + exports.on = exports.bind = exports.live = _on; + exports.off = exports.unbind = exports.die = _off; + exports.config = config; + exports.trigger = _dispatch; + + return exports; +})); + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + var jsonpID = 0, + document = window.document, + key, + name, + rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, + scriptTypeRE = /^(?:text|application)\/javascript/i, + xmlTypeRE = /^(?:text|application)\/xml/i, + jsonType = 'application/json', + htmlType = 'text/html', + blankRE = /^\s*$/, + originAnchor = document.createElement('a') + + originAnchor.href = window.location.href + + // trigger a custom event and return false if it was cancelled + function triggerAndReturn(context, eventName, data) { + var event = $.Event(eventName) + $(context).trigger(event, data) + return !event.isDefaultPrevented() + } + + // trigger an Ajax "global" event + function triggerGlobal(settings, context, eventName, data) { + if (settings.global) return triggerAndReturn(context || document, eventName, data) + } + + // Number of active Ajax requests + $.active = 0 + + function ajaxStart(settings) { + if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') + } + function ajaxStop(settings) { + if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') + } + + // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable + function ajaxBeforeSend(xhr, settings) { + var context = settings.context + if (settings.beforeSend.call(context, xhr, settings) === false || + triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) + return false + + triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) + } + function ajaxSuccess(data, xhr, settings, deferred) { + var context = settings.context, status = 'success' + settings.success.call(context, data, status, xhr) + if (deferred) deferred.resolveWith(context, [data, status, xhr]) + triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) + ajaxComplete(status, xhr, settings) + } + // type: "timeout", "error", "abort", "parsererror" + function ajaxError(error, type, xhr, settings, deferred) { + var context = settings.context + settings.error.call(context, xhr, type, error) + if (deferred) deferred.rejectWith(context, [xhr, type, error]) + triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type]) + ajaxComplete(type, xhr, settings) + } + // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" + function ajaxComplete(status, xhr, settings) { + var context = settings.context + settings.complete.call(context, xhr, status) + triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) + ajaxStop(settings) + } + + // Empty function, used as default callback + function empty() {} + + $.ajaxJSONP = function(options, deferred){ + if (!('type' in options)) return $.ajax(options) + + var _callbackName = options.jsonpCallback, + callbackName = ($.isFunction(_callbackName) ? + _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), + script = document.createElement('script'), + originalCallback = window[callbackName], + responseData, + abort = function(errorType) { + $(script).triggerHandler('error', errorType || 'abort') + }, + xhr = { abort: abort }, abortTimeout + + if (deferred) deferred.promise(xhr) + + $(script).on('load error', function(e, errorType){ + clearTimeout(abortTimeout) + $(script).off().remove() + + if (e.type == 'error' || !responseData) { + ajaxError(null, errorType || 'error', xhr, options, deferred) + } else { + ajaxSuccess(responseData[0], xhr, options, deferred) + } + + window[callbackName] = originalCallback + if (responseData && $.isFunction(originalCallback)) + originalCallback(responseData[0]) + + originalCallback = responseData = undefined + }) + + if (ajaxBeforeSend(xhr, options) === false) { + abort('abort') + return xhr + } + + window[callbackName] = function(){ + responseData = arguments + } + + script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName) + document.head.appendChild(script) + + if (options.timeout > 0) abortTimeout = setTimeout(function(){ + abort('timeout') + }, options.timeout) + + return xhr + } + + $.ajaxSettings = { + // Default type of request + type: 'GET', + // Callback that is executed before request + beforeSend: empty, + // Callback that is executed if the request succeeds + success: empty, + // Callback that is executed the the server drops error + error: empty, + // Callback that is executed on request complete (both: error and success) + complete: empty, + // The context for the callbacks + context: null, + // Whether to trigger "global" Ajax events + global: true, + // Transport + xhr: function () { + return new window.XMLHttpRequest() + }, + // MIME types mapping + // IIS returns Javascript as "application/x-javascript" + accepts: { + script: 'text/javascript, application/javascript, application/x-javascript', + json: jsonType, + xml: 'application/xml, text/xml', + html: htmlType, + text: 'text/plain' + }, + // Whether the request is to another domain + crossDomain: false, + // Default timeout + timeout: 0, + // Whether data should be serialized to string + processData: true, + // Whether the browser should be allowed to cache GET responses + cache: true + } + + function mimeToDataType(mime) { + if (mime) mime = mime.split(';', 2)[0] + return mime && ( mime == htmlType ? 'html' : + mime == jsonType ? 'json' : + scriptTypeRE.test(mime) ? 'script' : + xmlTypeRE.test(mime) && 'xml' ) || 'text' + } + + function appendQuery(url, query) { + if (query == '') return url + return (url + '&' + query).replace(/[&?]{1,2}/, '?') + } + + // serialize payload and append it to the URL for GET requests + function serializeData(options) { + if (options.processData && options.data && $.type(options.data) != "string") + options.data = $.param(options.data, options.traditional) + if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) + options.url = appendQuery(options.url, options.data), options.data = undefined + } + + $.ajax = function(options){ + var settings = $.extend({}, options || {}), + deferred = $.Deferred && $.Deferred(), + urlAnchor, hashIndex + for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] + + ajaxStart(settings) + + if (!settings.crossDomain) { + urlAnchor = document.createElement('a') + urlAnchor.href = settings.url + // cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049 + urlAnchor.href = urlAnchor.href + settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host) + } + + if (!settings.url) settings.url = window.location.toString() + if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex) + serializeData(settings) + + var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) + if (hasPlaceholder) dataType = 'jsonp' + + if (settings.cache === false || ( + (!options || options.cache !== true) && + ('script' == dataType || 'jsonp' == dataType) + )) + settings.url = appendQuery(settings.url, '_=' + Date.now()) + + if ('jsonp' == dataType) { + if (!hasPlaceholder) + settings.url = appendQuery(settings.url, + settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?') + return $.ajaxJSONP(settings, deferred) + } + + var mime = settings.accepts[dataType], + headers = { }, + setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, + protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, + xhr = settings.xhr(), + nativeSetHeader = xhr.setRequestHeader, + abortTimeout + + if (deferred) deferred.promise(xhr) + + if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') + setHeader('Accept', mime || '*/*') + if (mime = settings.mimeType || mime) { + if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] + xhr.overrideMimeType && xhr.overrideMimeType(mime) + } + if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) + setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') + + if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) + xhr.setRequestHeader = setHeader + + xhr.onreadystatechange = function(){ + if (xhr.readyState == 4) { + xhr.onreadystatechange = empty + clearTimeout(abortTimeout) + var result, error = false + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { + dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')) + result = xhr.responseText + + try { + // http://perfectionkills.com/global-eval-what-are-the-options/ + if (dataType == 'script') (1,eval)(result) + else if (dataType == 'xml') result = xhr.responseXML + else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) + } catch (e) { error = e } + + if (error) ajaxError(error, 'parsererror', xhr, settings, deferred) + else ajaxSuccess(result, xhr, settings, deferred) + } else { + ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) + } + } + } + + if (ajaxBeforeSend(xhr, settings) === false) { + xhr.abort() + ajaxError(null, 'abort', xhr, settings, deferred) + return xhr + } + + if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name] + + var async = 'async' in settings ? settings.async : true + xhr.open(settings.type, settings.url, async, settings.username, settings.password) + + for (name in headers) nativeSetHeader.apply(xhr, headers[name]) + + if (settings.timeout > 0) abortTimeout = setTimeout(function(){ + xhr.onreadystatechange = empty + xhr.abort() + ajaxError(null, 'timeout', xhr, settings, deferred) + }, settings.timeout) + + // avoid sending empty string (#319) + xhr.send(settings.data ? settings.data : null) + return xhr + } + + // handle optional data/success arguments + function parseArguments(url, data, success, dataType) { + if ($.isFunction(data)) dataType = success, success = data, data = undefined + if (!$.isFunction(success)) dataType = success, success = undefined + return { + url: url + , data: data + , success: success + , dataType: dataType + } + } + + $.get = function(/* url, data, success, dataType */){ + return $.ajax(parseArguments.apply(null, arguments)) + } + + $.post = function(/* url, data, success, dataType */){ + var options = parseArguments.apply(null, arguments) + options.type = 'POST' + return $.ajax(options) + } + + $.getJSON = function(/* url, data, success */){ + var options = parseArguments.apply(null, arguments) + options.dataType = 'json' + return $.ajax(options) + } + + $.fn.load = function(url, data, success){ + if (!this.length) return this + var self = this, parts = url.split(/\s/), selector, + options = parseArguments(url, data, success), + callback = options.success + if (parts.length > 1) options.url = parts[0], selector = parts[1] + options.success = function(response){ + self.html(selector ? + $('<div>').html(response.replace(rscript, "")).find(selector) + : response) + callback && callback.apply(self, arguments) + } + $.ajax(options) + return this + } + + var escape = encodeURIComponent + + function serialize(params, obj, traditional, scope){ + var type, array = $.isArray(obj), hash = $.isPlainObject(obj) + $.each(obj, function(key, value) { + type = $.type(value) + if (scope) key = traditional ? scope : + scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']' + // handle data in serializeArray() format + if (!scope && array) params.add(value.name, value.value) + // recurse into nested objects + else if (type == "array" || (!traditional && type == "object")) + serialize(params, value, traditional, key) + else params.add(key, value) + }) + } + + $.param = function(obj, traditional){ + var params = [] + params.add = function(key, value) { + if ($.isFunction(value)) value = value() + if (value == null) value = "" + this.push(escape(key) + '=' + escape(value)) + } + serialize(params, obj, traditional) + return params.join('&').replace(/%20/g, '+') + } +})(Zepto) + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function(){ + // getComputedStyle shouldn't freak out when called + // without a valid element as argument + try { + getComputedStyle(undefined) + } catch(e) { + var nativeGetComputedStyle = getComputedStyle; + window.getComputedStyle = function(element){ + try { + return nativeGetComputedStyle(element) + } catch(e) { + return null + } + } + } +})() + +// Zepto.js +// (c) 2010-2015 Thomas Fuchs +// Zepto.js may be freely distributed under the MIT license. + +;(function($){ + $.fn.serializeArray = function() { + var name, type, result = [], + add = function(value) { + if (value.forEach) return value.forEach(add) + result.push({ name: name, value: value }) + } + if (this[0]) $.each(this[0].elements, function(_, field){ + type = field.type, name = field.name + if (name && field.nodeName.toLowerCase() != 'fieldset' && + !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && + ((type != 'radio' && type != 'checkbox') || field.checked)) + add($(field).val()) + }) + return result + } + + $.fn.serialize = function(){ + var result = [] + this.serializeArray().forEach(function(elm){ + result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) + }) + return result.join('&') + } + + $.fn.submit = function(callback) { + if (0 in arguments) this.bind('submit', callback) + else if (this.length) { + var event = $.Event('submit') + this.eq(0).trigger(event) + if (!event.isDefaultPrevented()) this.get(0).submit() + } + return this + } + +})(Zepto) diff --git a/hyhproject/wechat2/view/default/goods_category.html b/hyhproject/wechat2/view/default/goods_category.html new file mode 100755 index 0000000..b570f33 --- /dev/null +++ b/hyhproject/wechat2/view/default/goods_category.html @@ -0,0 +1,68 @@ +{extend name="default/base" /} +{block name="title"}商品分类 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/goods_category.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('goods',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + </div> + </header> +{/block} +{block name="main"} + <section class="ui-container"> + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="list" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{php}echo str_replace('、', '<br/>', $go['catName']);{/php}</li> + {/volist} + </ul> + </div> + {volist name="list" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + {if(isset($go['childList']))} + <ul class="wst-gc-br"><li class="brand"> + {wst:brand cat="$go['catId']" id="bvo" num='16' cache='86400'} + <a href="javascript:void(0)" onclick="javascript:getBrandGoodsList({$bvo['brandId']});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($bvo['brandImg'],2)}"></a> + {/wst:brand} + <div class="wst-clear"></div> + </li></ul> + {volist name="go['childList']" id="go1"} + <ul> + <div class="wst-gc-ads"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go1['catId']});"><div class="title">{$go1.catName}</div></a> + </div> + <li> + <div class="wst-goodscat"> + {volist name="go1['childList']" id="go2" key="key2"} + <span {if($key2%1==0)}left{/if}> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go2['catId']});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{$go2['catImg']}" class="goods-cat-img" title="{$go2.catName}"/> + <p class="ui-nowrap-flex">{$go2.catName}</p> + </a> + </span> + {/volist} + </div> + <div class="wst-clear"></div> + </li> + <div class="wst-clear"></div> + </ul> + {/volist} + {/if} + </div> + {/volist} + <div class="wst-clear"></div> + </section> +{/block} +{block name="include"} +{include file="default/goods_search" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/goods_category.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goods_detail.html b/hyhproject/wechat2/view/default/goods_detail.html new file mode 100755 index 0000000..6f4044b --- /dev/null +++ b/hyhproject/wechat2/view/default/goods_detail.html @@ -0,0 +1,392 @@ +{extend name="default/base" /} +{block name="title"}商品详情 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/goods_detail.css?v={$v}"> +{/block} +{block name="header"} + {php}$cartNum = WSTCartNum();{/php} + <header class="ui-header ui-header-positive wst-header" id="goods-header" style="display:none;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <ul class="ui-tab-nav"> + <li class="switch active" onclick="javascript:pageSwitch(this,1);">商品</li> + <li class="switch" onclick="javascript:pageSwitch(this,2);">详情</li> + <li class="switch" id="appr" onclick="javascript:pageSwitch(this,3);">评价</li> + </ul> + <a href="{:url('wechat/carts/index')}"><span class="cart" id="cartNum">{if($cartNum>0)}<span>{php} echo $cartNum;{/php}</span>{/if}</span></a> + <span class="share" onclick="javascript:WST.share();"></span> + </header> +{/block} +{block name="footer"} +{if($info)} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="{$info['goodsType']}" id="goodsType" autocomplete="off"> + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col-3 wst-go-icon"> + <div class="ui-row-flex"> + <div class="ui-col ui-col" style="border-right: 1px solid rgba(0,0,0,.05);"> + {if($info['shop']['shopQQ'])!=''} + <div class="icon"><a href="{:request()->scheme()}://wpa.qq.com/msgrd?v=3&uin={$info['shop']['shopQQ']}&site=qq&menu=yes"><span class="img qq"></span><span class="word">客服</span></a></div> + {else /} + <div class="icon"><a href="tel:{$info['shop']['shopTel']}"><span class="img tel"></span><span class="word">客服</span></a></div> + {/if} + </div> + <div class="ui-col ui-col" style="border-right: 1px solid rgba(0,0,0,.05);"> + <div class="icon"><a href="{:url('wechat/shops/home',['shopId'=>$info['shop']['shopId']])}")><span class="img shop"></span><span class="word">店铺</span></a></div> + </div> + <div class="ui-col ui-col"> + {if($info['favGood']==0)} + <button class="but" type="button"><span class="img imgfollow nofollow" onclick="javascript:WST.favorites({$info['goodsId']},0);"></span><span style="bottom: 5px;" class="word">关注</span></button> + {else} + <button class="but" type="button"><span class="img imgfollow follow" onclick="javascript:WST.cancelFavorite({$info['favGood']},0);"></span><span style="bottom: 5px;" class="word">关注</span></button> + {/if} + </div> + </div> + </div> + <div class="ui-col ui-col-4 wst-goods_buy"> + {if($info['goodsType']==1)} + <button class="wst-goods_buym" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {else} + <button class="wst-goods_buyl" type="button" onclick="javascript:cartShow(0);" {if($info['goodsId']==0)}disabled{/if}>加入购物车</button> + <button class="wst-goods_buyr" type="button" onclick="javascript:cartShow(1);" {if($info['goodsId']==0)}disabled{/if}>立即购买</button> + {/if} + </div> + </div> + </footer> +{/if} +{/block} +{block name="main"} +{if($info)} + {/* 商品 */} + <div class="wst-go-more" id="arrow" style="display: none;"><i class="arrow"></i> + <ul class="ui-row ui-list-active more"> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/index/index')}"><i class="home"></i><p>首页</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/goodscats/index')}"><i class="category"></i><p>分类</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/carts/index')}"><i class="cart"></i><p>购物车</p></a></div></li> + <li class="ui-col"><div class="column line"><a href="{:url('wechat/favorites/goods')}"><i class="follow"></i><p>关注</p></a></div></li> + <li class="ui-col"><div class="column"><a href="{:url('wechat/users/index')}"><i class="user"></i><p>我的</p></a></div></li> + </ul> + </div> + <div class="wst-ca-layer" id="layer" onclick="javascript:inMore();"></div> + <section class="ui-container" id="goods1" style="border-top: 0px solid transparent;"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="info['gallery']" id="ga"} + <div class="swiper-slide" style="width:100%;"> + <div class="wst-go-img"><a><img src="__ROOT__/{:WSTImg($ga,2)}"></a></div> + </div> + {/volist} + </div> + {if(count($info['gallery'])>1)}<div class="swiper-pagination"></div>{/if} + <div class="wst-go-return" onclick="history.back()"><i class="ui-icon-prev"></i></div> + <div class="wst-go-mores" onclick="javascript:inMore()"><i>···</i></div> + </div> + <div class="wst-go-name">{$info['goodsName']}</div> + <div class="ui-row-flex wst-go-price"> + <div class="ui-col ui-col-2"> + <div class="price"><i>¥ </i>{$info['shopPrice']}<span class="market">¥ {$info['marketPrice']}</span></div> + <div class="ui-row-flex info"> + <div class="ui-col ui-col" style="text-align: left;">快递: {if $info['isFreeShipping']==1}免运费{else}{php}echo sprintf("%.2f", $info['shop']['freight']);{/php}{/if}</div> + <div class="ui-col ui-col" style="text-align: center;">销量: {$info['saleNum']}</div> + <div class="ui-col ui-col" style="text-align: right;">{$info['shop']['areas']['areaName1']}{$info['shop']['areas']['areaName2']}</div> + </div> + </div> + {:hook('wechatDocumentGoodsDetailTips',["goods"=>$info])} + </div> + <ul class="ui-list ui-list-text wst-go-ul ui-list-active"> + {if WSTConf('CONF.isOrderScore')==1} + <li> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">积分</span><span class="line">|</span>购买即可获得{php}echo ceil($info['shopPrice']);{/php}积分</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + <li id='j-promotion' style='display:none;'> + <div class="ui-list-info"> + <h5 class="ui-nowrap"> + <div style="float: left;"> + <span class="word">促销</span> + <span class="line">|</span> + </div> + {:hook('wechatDocumentGoodsPromotionDetail',['goods'=>$info])} + </h5> + </div> + </li> + {/* 优惠券钩子 */} + {:hook('wechatDocumentGoodsPropDetail')} + <li style="display: none;"> + <div class="ui-list-info"> + <h5 class="ui-nowrap"><span class="word">优惠</span><span class="line">|</span></h5> + </div> + <span class="icon">···</span> + </li> + {if !empty($info['attrs']) } + <li onclick="javascript:dataShow();"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">产品参数</h5> + </div> + <span class="icon">···</span> + </li> + {/if} + + <li onclick="javascript:pageSwitch($('#appr'),3);"> + <div class="ui-list-info"> + <h5 class="ui-nowrap">商品评价( <span class="red">{$info['appraiseNum']}</span> )</h5> + </div> + <span class="icon">···</span> + </li> + </ul> + <ul class="ui-list ui-list-one ui-list-link wst-go-shop"> + <div class="info"> + <div class="img"><a><img src="__ROOT__/{:WSTImg($info['shop']['shopImg'],3)}" title="{$info['shop']['shopName']}"></a></div> + <div class="name"><p class="ui-nowrap-flex name1">{$info['shop']['shopName']}</p><p class="ui-nowrap-flex name2"><span>主营: {$info['shop']['cat']}</span></p></div> + <div class="wst-clear"></div> + </div> + <div class="ui-row-flex score"> + <div class="ui-col ui-col" style="text-align:left;">商品评分: <span class="red">{$info['shop']['goodsScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col" style="text-align:center;">时效评分: <span class="red">{$info['shop']['timeScore']}</span></div><span class="line">|</span> + <div class="ui-col ui-col" style="text-align:right;">服务评分: <span class="red">{$info['shop']['serviceScore']}</span></div> + </div> + <div class="ui-row-flex button"> + <div class="ui-col ui-col"><a href="{:url('wechat/shops/shopGoodsList',['shopId'=>$info['shop']['shopId']])}" class="goods">全部商品</a></div> + <div class="ui-col ui-col"><a href="{:url('wechat/shops/home',['shopId'=>$info['shop']['shopId']])}" class="shop">进入店铺</a></div> + </div> + </ul> + <div class="title gc-title" onclick="goConsult()"> + <span class='gc-tit-icon'></span> + <span class='gc-tit-icon2'></span> + 购买咨询 + </div> + <div class="gc-title-list"> + {if($info['consult']['consultContent'])} + <li> + <div class="question-box cf"> + <span class="question-pic"></span> + <div class="question-content"> + <span>{$info['consult']['consultContent']}</span> + </div> + <div class="wst-clear"></div> + </div> + {if($info['consult']['reply'])} + <div class="question-box cf"> + <span class="question-pic answer-pic"></span> + <div class="question-content answer-content"> + <span>{$info['consult']['reply']}</span> + </div> + <div class="wst-clear"></div> + </div> + {/if} + </li> + {else} + <p class="prompt">暂无商品咨询~</p> + {/if} + </div> + + <div class="wst-shl-ads"> + <div class="title">猜你喜欢</div> + {wst:goods type='best' cat="$info['shop']['catId']" num='6'} + <div class="wst-go-goods" onclick="javascript:WST.intoGoods({$vo['goodsId']});"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$vo['goodsId']});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($vo['goodsImg'],3)}" title="{$vo['goodsName']}"></a> + </div> + <p class="name ui-nowrap-multi">{$vo['goodsName']}</p> + <div class="info"><span class="ui-nowrap-flex price">¥ {$vo['shopPrice']}</span></div> + </div> + {/wst:goods} + <div class="wst-clear"></div> + </div> + </section> + {/* 详情 */} + <section class="ui-container" id="goods2" style="display: none;"> + <div class="wst-go-details">{$info['goodsDesc']}</div> + </section> + {/* 评价 */} + <input type="hidden" name="" value="{$info['goodsId']}" id="goodsId" autocomplete="off"> + <input type="hidden" name="" value="" id="evaluateType" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container" id="goods3" style="display: none;"> + <div class="ui-row-flex wst-ev-term"> + <div class="ui-col ui-col active" onclick="javascript:evaluateSwitch(this,'');"><p>全部</p><p class="number">{$info['appraises']['sum']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'best');"><p>好评</p><p class="number">{$info['appraises']['best']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'good');"><p>中评</p><p class="number">{$info['appraises']['good']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'bad');"><p>差评</p><p class="number">{$info['appraises']['bad']}</p></div> + <div class="ui-col ui-col" onclick="javascript:evaluateSwitch(this,'pic');"><p>晒图</p><p class="number">{$info['appraises']['pic']}</p></div> + </div> + <div id="evaluate-list" style="margin-top: 10px;"></div> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} + <div class="ui-whitespace wst-go-evaluate"> + <div class="info"> + <p> + <img src="__ROOT__/{{ d[i].userPhoto }}" class="portrait"> + <span class="name">{{ d[i].loginName }}</span> + {{# if(d[i].userTotalScore){ }} + <img src="__ROOT__/{{ d[i].userTotalScore }}" class="ranks"> + {{# } }} + <span class="time">{{ d[i].createTime }}</span> + <div class="wst-clear"></div> + </p> + </div> + <div class="content"> + <p> + {{# var score = (d[i].goodsScore+d[i].serviceScore+d[i].timeScore)/3; }} + {{# for(var j=1; j<6; j++){ }} + {{# if(j <= score.toFixed(0)){ }} + <i class="bright"></i> + {{# }else{ }} + <i class="dark"></i> + {{# } }} + {{# } }} + </p> + <p class="content2">{{ d[i].content }}</p> + {{# if(d[i].images){ }} + {{# var img = d[i].images.split(','); }} + {{# for(var m=0; m<img.length; m++){ }} + <img src="__ROOT__/{{ img[m] }}"> + {{# } }} + {{# } }} + <p class="word">{{ d[i].goodsSpecNames }}</p> + <div class="wst-clear"></div> + </div> + {{# if(d[i].shopReply){ }} + <div class="reply"><p>卖家回复:{{ d[i].shopReply }}</p></div> + {{# } }} + </div> +{{# } }} +{{# }else{ }} + <div class="wst-prompt-icon"><img src="__WECHAT__/img/nothing-evaluate.png"></div> + <div class="wst-prompt-info"> + <p>对不起,没有相关评论。</p> + </div> +{{# } }} +</script> +{else} + <div class="wst-prompt-icon"><img src="__WECHAT__/img/nothing-goods.png"></div> + <div class="wst-prompt-info"> + <p>对不起,没有找到商品。</p> + </div> +{/if} +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{if($info)} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 参数框 */} +{if !empty($info['attrs']) } +<div class="wst-fr-box" id="frame"> + <div class="title"><span>产品参数</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {volist name="$info['attrs']" id="at"} + {$at['attrName']}:{$at['attrVal']}<br/> + {/volist} + </div> + <div class="determine"><button class="button" onclick="javascript:dataHide();">确定</button></div> +</div> +{/if} +{/*加入购物车框 */} +<div class="wst-cart-box" id="frame-cart"> + <div class="title"> + <div class="picture"><div class="img"><a href="javascript:void(0);"><img src="__ROOT__/{:WSTImg($info['goodsImg'],3)}" title="{$info['goodsName']}"></a></div></div> + <i class="ui-icon-close-page" onclick="javascript:cartHide();"></i> + <p class="ui-nowrap-multi">{$info['goodsName']}</p> + <p class="ui-nowrap-flex price"><span id="j-shop-price">¥{$info['shopPrice']}</span><span id="j-market-price" class="price2">¥ {$info['marketPrice']}</span></p> + <div class="wst-clear"></div> + </div> + <div class="standard" id="standard"> + {if!empty($info['spec'])} + {volist name="$info['spec']" id="sp"} + <div class="spec"> + <p>{$sp['name']}</p> + {volist name="sp['list']" id="sp2"} + {if $sp2['itemImg']!=''} + <img class="j-option img" data-val="{$sp2['itemId']}" src="__ROOT__/{:WSTImg($sp2['itemImg'],3)}" title="{$sp2['itemName']}"> + {else} + <span class="j-option" data-val="{$sp2['itemId']}">{$sp2['itemName']}</span> + {/if} + {/volist} + <div class="wst-clear"></div> + </div> + {/volist} + {/if} + <div class="number"> + <p>数量</p> + <div class="stock">库存:<span id="goods-stock">0</span>{$info['goodsUnit']}</div> + <div class="wst-buy_l"> + <input class="wst-buy_l1" type="button" value="-" onclick='javascript:WST.changeIptNum(-1,"#buyNum")'><input id="buyNum" class="wst-buy_l2" data-min='1' data-max='' type="number" value="1" autocomplete="off" onkeyup='WST.changeIptNum(0,"#buyNum")'><input class="wst-buy_l3" type="button" value="+" onclick='javascript:WST.changeIptNum(1,"#buyNum")'> + </div> + <div class="wst-clear"></div> + </div> + </div> + <div class="determine"><button class="button" onclick="javascript:addCart();">确定</button></div> +</div> +{/block} + + + +{block name="js"} +{if(!empty($datawx))} +<script src="{:request()->scheme()}://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> +<script> +wx.config({ + debug: false, + appId: '<?php echo WSTConf('CONF.wxAppId'); ?>', //公众号的唯一标识 + timestamp: '<?php echo $datawx['timestamp'];?>', //生成签名的时间戳 + nonceStr: '<?php echo $datawx['noncestr'];?>', //生成签名的随机串 + signature: '<?php echo $datawx['signature'];?>',//签名 + jsApiList: [ //需要使用的JS接口 + 'onMenuShareTimeline', + 'onMenuShareAppMessage', + 'onMenuShareQQ', + 'onMenuShareWeibo', + 'onMenuShareQZone' + ] +}); + +wx.ready(function(){ + var shareData = { + title: "{$info['goodsName']}", + desc: "{:WSTConf('CONF.mallName')}", + link: "{:url('wechat/goods/detail',array('goodsId'=>$info['goodsId']),true,true)}", + imgUrl: "{:WSTRoot()}/{$info['goodsImg']}" + }; + wx.onMenuShareAppMessage(shareData); + wx.onMenuShareTimeline(shareData); + wx.onMenuShareQQ(shareData); + wx.onMenuShareWeibo(shareData); + wx.onMenuShareQZone(shareData); +}); +</script> +{:hook('wechatDocumentGoodsDetail',['goods'=>$info,'datawx'=>$datawx,'getParams'=>input()])} +{/if} +<script> +var goodsInfo = { + id:{$info['goodsId']}, + isSpec:{$info['isSpec']}, + goodsStock:{$info['goodsStock']}, + marketPrice:{$info['marketPrice']}, + goodsPrice:{$info['shopPrice']} + {if isset($info['saleSpec'])} + ,sku:{:json_encode($info['saleSpec'])} + {/if} +} +function goConsult(){ + location.href=WST.U('wechat/goodsconsult/index',{goodsId:goodsInfo.id}) +} +</script> +{/if} +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/goods_detail.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goods_list.html b/hyhproject/wechat2/view/default/goods_list.html new file mode 100755 index 0000000..aec2ea3 --- /dev/null +++ b/hyhproject/wechat2/view/default/goods_list.html @@ -0,0 +1,78 @@ +{extend name="default/base" /} +{block name="title"}商品列表 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/goods_list.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('goods',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon" onclick="javascript:switchList(this);"></span> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$keyword}" id="keyword" autocomplete="off"> + <input type="hidden" name="" value="{$catId}" id="catId" autocomplete="off"> + <input type="hidden" name="" value="{$brandId}" id="brandId" autocomplete="off"> + <input type="hidden" name="" value="" id="condition" autocomplete="off"> + <input type="hidden" name="" value="" id="desc" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,0);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + <ul class="ui-tab-content"> + <li id="goods-list"></li> + </ul> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} +<div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="javascript:WST.intoGoods({{ d[i].goodsId }});"> +<div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d[i].goodsId }});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d[i].goodsImg }}" title="{{ d[i].goodsName }}"/></a></div> +<div class="name ui-nowrap-multi">{{ d[i].goodsName }}</div> +<div class="tags ui-nowrap-multi"> +{{# if(d[i].isSelf==1){ }}<span class='tag'>自营</span>{{# } }} +{{# if(d[i].isFreeShipping==1){ }}<span class='tag'>包邮</span>{{# } }} +{{ d[i]['tags']!=undefined?d[i]['tags'].join(' '):'' }}&nbsp; +</div> +<div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> +<div class="info2"><span class="price">好评率{{ d[i].praiseRate }}</span><span class="deal">成交数:{{ d[i].saleNum }}</span></div> +</div> +{{# } }} +{{# }else{ }} +<div class="wst-prompt-icon"><img src="__WECHAT__/img/nothing-goods.png"></div> +<div class="wst-prompt-info"> + <p>对不起,没有相关商品。</p> +</div> +{{# } }} +</script> +{/block} +{block name="include"} +{include file="default/goods_search" /} +<div class="wst-toTop" style="display: block;bottom: 0.68rem;"> + <a href="{:url('wechat/goods/history')}"><i class="wst-toHistoryimg"></i></a> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/goods_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goods_search.html b/hyhproject/wechat2/view/default/goods_search.html new file mode 100755 index 0000000..89cb5c7 --- /dev/null +++ b/hyhproject/wechat2/view/default/goods_search.html @@ -0,0 +1,31 @@ + <div class="wst-co-search" id="wst-goods-search"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('goods',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(0);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="list"> + <p class="search"><i></i>热门搜索</p> + {php}$hotWordsSearch = WSTConf("CONF.hotWordsSearch"); + if($hotWordsSearch!='')$hotWordsSearch = explode(',',$hotWordsSearch);{/php} + <div class="term"> + {volist name="$hotWordsSearch" id="hot"} + <a href="{:url('wechat/goods/lists',['keyword'=>$hot])}">{$hot}</a> + {/volist} + </div> + </div> + </div> + <script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> + <script> + jQuery.noConflict(); + document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#wst-goods-search").is(":hidden")){ + event.preventDefault(); + } + }) + </script> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goodsconsult/consult.html b/hyhproject/wechat2/view/default/goodsconsult/consult.html new file mode 100755 index 0000000..5349435 --- /dev/null +++ b/hyhproject/wechat2/view/default/goodsconsult/consult.html @@ -0,0 +1,39 @@ +{extend name="default/base" /} +{block name="title"}发表咨询 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/consult.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>发表咨询</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="goodsId" value="{$goodsId}" id="goodsId" autocomplete="off"> + <section class="ui-container"> + <ul class="gcplist"> + <li> + <label> + 咨询类型: + <select id="consultType"> + {volist name=":WSTDatas('COUSULT_TYPE')" id="vo"} + <option name="pointType" value="{$vo.dataVal}">{$vo.dataName}</option> + {/volist} + </select> + </label> + </li> + <li>咨询内容:</li> + <li><textarea id="consultContent"></textarea></li> + <li style="text-align:center;"> + <button class="consult-button" onclick="consultCommit();"> + 提交 + </button> + </li> + </ul> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/goodsconsult/consult.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goodsconsult/consult.js b/hyhproject/wechat2/view/default/goodsconsult/consult.js new file mode 100755 index 0000000..75937dc --- /dev/null +++ b/hyhproject/wechat2/view/default/goodsconsult/consult.js @@ -0,0 +1,89 @@ +jQuery.noConflict(); +// 获取商品咨询 +function getgoodsConsultList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.goodsId = $('#goodsId').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/goodsconsult/listQuery'), param, function(data){ + var json = WST.toJson(data); + json = json.data; + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('gcList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#_gcList').append(html); + }); + $('#currPage').val(data.data.CurrentPage); + $('#totalPage').val(data.data.TotalPage); + }else{ + html += '<p style="text-align:center;margin-top:10px;">暂无商品咨询~</p>'; + $('#_gcList').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +function consultListInit(){ + var currPage = totalPage = 0; + var loading = false; + $(document).ready(function(){ + getgoodsConsultList(); + var dataHeight = $("#frame").css('height'); + $("#frame").css('top',0); + var dataWidth = $("#frame").css('width'); + $("#frame").css('right','-'+dataWidth); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getgoodsConsultList(); + } + } + }); + }); +}; +$(function(){WST.initFooter()}); +/* 发布咨询 */ +function consult(){ + var goodsId = $('#goodsId').val(); + location.href=WST.U('wechat/goodsconsult/consult',{goodsId:goodsId}); +} +// 提交商品咨询 +function consultCommit(){ + var params={}; + params.goodsId = $('#goodsId').val(); + params.consultType = $('#consultType').val(); + if(params.consultType<=0){ + WST.msg('请选择咨询类别','info'); + return; + } + params.consultContent = $('#consultContent').val(); + if(params.consultContent == ''){ + WST.msg('请输入咨询内容','info'); + return; + } + if(params.consultContent.length<3 || params.consultContent.length>200){ + WST.msg('咨询内容应为3-200个字','info'); + return; + } + WST.load('正在提交,请稍后...'); + $.post(WST.U('wechat/goodsconsult/add'),params,function(responData){ + WST.noload(); + var json = WST.toJson(responData); + if(json.status==1){ + // 发布成功 + WST.msg(json.msg,'success'); + setTimeout(function(){ + history.go(-1); + },1000); + }else{ + WST.msg(json.msg,'warn'); + } + }) +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/goodsconsult/list.html b/hyhproject/wechat2/view/default/goodsconsult/list.html new file mode 100755 index 0000000..0324788 --- /dev/null +++ b/hyhproject/wechat2/view/default/goodsconsult/list.html @@ -0,0 +1,59 @@ +{extend name="default/base" /} +{block name="title"}商品咨询 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/consult.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>商品咨询</h1> + <div class="consult" onclick="consult()"></div> + </header> +{/block} +{block name="main"} +<input type="hidden" name="goodsId" value="{$goodsId}" id="goodsId" autocomplete="off"> + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + + <script type="text/html" id="gcList"> + {{# for(var i=0;i<d.length;i++){ }} + <li> + <p class="gc-item-tit"> + <span>{{(WST.blank(d[i].loginName)=='')?'游客':d[i].loginName}}</span> + <span class="item-time">{{d[i].createTime}}</span> + </p> + <div class="question-box cf"> + <span class="question-pic"></span> + <div class="question-content"> + <span>{{d[i].consultContent}}</span> + </div> + </div> + <div class="wst-clear"></div> + {{# if(WST.blank(d[i].reply)!=''){ }} + <div class="question-box cf"> + <span class="question-pic answer-pic"></span> + <div class="question-content answer-content"> + <span>{{d[i].reply}}</span> + </div> + </div> + <div class="wst-clear"></div> + {{# } }} + </li> + {{# } }} + </script> + <section class="ui-container" id="newsListBox"> + <div class="gcListBox"> + <ul class="gcList" id="_gcList"> + + </ul> + </div> + </section> +{/block} +{block name="js"} +<script> +$(function(){consultListInit()}); +</script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/goodsconsult/consult.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/header.html b/hyhproject/wechat2/view/default/header.html new file mode 100755 index 0000000..421af93 --- /dev/null +++ b/hyhproject/wechat2/view/default/header.html @@ -0,0 +1,3 @@ + <header class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>{$Title}</h1> + </header> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/img/QA-icon.png b/hyhproject/wechat2/view/default/img/QA-icon.png new file mode 100755 index 0000000..e31c96c Binary files /dev/null and b/hyhproject/wechat2/view/default/img/QA-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/brand.png b/hyhproject/wechat2/view/default/img/brand.png new file mode 100755 index 0000000..8a1f270 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/brand.png differ diff --git a/hyhproject/wechat2/view/default/img/cart.png b/hyhproject/wechat2/view/default/img/cart.png new file mode 100755 index 0000000..f8c12a5 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/cart.png differ diff --git a/hyhproject/wechat2/view/default/img/classify.png b/hyhproject/wechat2/view/default/img/classify.png new file mode 100755 index 0000000..10f62f1 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/classify.png differ diff --git a/hyhproject/wechat2/view/default/img/classify2.png b/hyhproject/wechat2/view/default/img/classify2.png new file mode 100755 index 0000000..2765f5f Binary files /dev/null and b/hyhproject/wechat2/view/default/img/classify2.png differ diff --git a/hyhproject/wechat2/view/default/img/copy.png b/hyhproject/wechat2/view/default/img/copy.png new file mode 100755 index 0000000..9304fa3 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/copy.png differ diff --git a/hyhproject/wechat2/view/default/img/custom.png b/hyhproject/wechat2/view/default/img/custom.png new file mode 100755 index 0000000..70faec0 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/custom.png differ diff --git a/hyhproject/wechat2/view/default/img/default_shopbanner.jpg b/hyhproject/wechat2/view/default/img/default_shopbanner.jpg new file mode 100755 index 0000000..a63dbf0 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/default_shopbanner.jpg differ diff --git a/hyhproject/wechat2/view/default/img/default_shopbanner.png b/hyhproject/wechat2/view/default/img/default_shopbanner.png new file mode 100755 index 0000000..6259564 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/default_shopbanner.png differ diff --git a/hyhproject/wechat2/view/default/img/email.png b/hyhproject/wechat2/view/default/img/email.png new file mode 100755 index 0000000..ce33848 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/email.png differ diff --git a/hyhproject/wechat2/view/default/img/evaluate.png b/hyhproject/wechat2/view/default/img/evaluate.png new file mode 100755 index 0000000..407b6ba Binary files /dev/null and b/hyhproject/wechat2/view/default/img/evaluate.png differ diff --git a/hyhproject/wechat2/view/default/img/follow-shop.png b/hyhproject/wechat2/view/default/img/follow-shop.png new file mode 100755 index 0000000..37b4bd4 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/follow-shop.png differ diff --git a/hyhproject/wechat2/view/default/img/goods-list.png b/hyhproject/wechat2/view/default/img/goods-list.png new file mode 100755 index 0000000..1894912 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/goods-list.png differ diff --git a/hyhproject/wechat2/view/default/img/goods-list2.png b/hyhproject/wechat2/view/default/img/goods-list2.png new file mode 100755 index 0000000..323a850 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/goods-list2.png differ diff --git a/hyhproject/wechat2/view/default/img/history-icon.png b/hyhproject/wechat2/view/default/img/history-icon.png new file mode 100755 index 0000000..a9cb128 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/history-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/hot.png b/hyhproject/wechat2/view/default/img/hot.png new file mode 100755 index 0000000..fa195c2 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/hot.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_add_money.png b/hyhproject/wechat2/view/default/img/icon_add_money.png new file mode 100755 index 0000000..c872021 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_add_money.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_adds_users.png b/hyhproject/wechat2/view/default/img/icon_adds_users.png new file mode 100755 index 0000000..d5dfef7 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_adds_users.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_bottomnav.png b/hyhproject/wechat2/view/default/img/icon_bottomnav.png new file mode 100755 index 0000000..fabbd35 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_bottomnav.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_cart.png b/hyhproject/wechat2/view/default/img/icon_cart.png new file mode 100755 index 0000000..26179ee Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_cart.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_cart_money.png b/hyhproject/wechat2/view/default/img/icon_cart_money.png new file mode 100755 index 0000000..18cff97 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_cart_money.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_cd.png b/hyhproject/wechat2/view/default/img/icon_cd.png new file mode 100755 index 0000000..2ef28ad Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_cd.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_dp.png b/hyhproject/wechat2/view/default/img/icon_dp.png new file mode 100755 index 0000000..e17b9b7 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_dp.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_dpsp.png b/hyhproject/wechat2/view/default/img/icon_dpsp.png new file mode 100755 index 0000000..aa4eb83 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_dpsp.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_gz.png b/hyhproject/wechat2/view/default/img/icon_gz.png new file mode 100755 index 0000000..eda8aea Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_gz.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_gzspcart.png b/hyhproject/wechat2/view/default/img/icon_gzspcart.png new file mode 100755 index 0000000..c8028e9 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_gzspcart.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_indextop.png b/hyhproject/wechat2/view/default/img/icon_indextop.png new file mode 100755 index 0000000..39305f5 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_indextop.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_kf.png b/hyhproject/wechat2/view/default/img/icon_kf.png new file mode 100755 index 0000000..9454d66 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_kf.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_like1.png b/hyhproject/wechat2/view/default/img/icon_like1.png new file mode 100755 index 0000000..f599add Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_like1.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_like2.png b/hyhproject/wechat2/view/default/img/icon_like2.png new file mode 100755 index 0000000..cfe2feb Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_like2.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_logmoney.png b/hyhproject/wechat2/view/default/img/icon_logmoney.png new file mode 100755 index 0000000..4eb4094 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_logmoney.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_more.png b/hyhproject/wechat2/view/default/img/icon_more.png new file mode 100755 index 0000000..7909d41 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_more.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_news1.png b/hyhproject/wechat2/view/default/img/icon_news1.png new file mode 100755 index 0000000..a0adc1c Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_news1.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_out_money.png b/hyhproject/wechat2/view/default/img/icon_out_money.png new file mode 100755 index 0000000..282d332 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_out_money.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_record.png b/hyhproject/wechat2/view/default/img/icon_record.png new file mode 100755 index 0000000..23c9664 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_record.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_spxq.png b/hyhproject/wechat2/view/default/img/icon_spxq.png new file mode 100755 index 0000000..e2bbd5b Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_spxq.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_tishi.png b/hyhproject/wechat2/view/default/img/icon_tishi.png new file mode 100755 index 0000000..2cff9ec Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_tishi.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_tixian.png b/hyhproject/wechat2/view/default/img/icon_tixian.png new file mode 100755 index 0000000..ba32828 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_tixian.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_user_about.png b/hyhproject/wechat2/view/default/img/icon_user_about.png new file mode 100755 index 0000000..246a195 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_user_about.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_user_adds.png b/hyhproject/wechat2/view/default/img/icon_user_adds.png new file mode 100755 index 0000000..9f0778c Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_user_adds.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_user_info.png b/hyhproject/wechat2/view/default/img/icon_user_info.png new file mode 100755 index 0000000..9543430 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_user_info.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_user_safety.png b/hyhproject/wechat2/view/default/img/icon_user_safety.png new file mode 100755 index 0000000..abd0c3f Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_user_safety.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_userscores.png b/hyhproject/wechat2/view/default/img/icon_userscores.png new file mode 100755 index 0000000..e8d60e3 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_userscores.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_zhanghuanquan.png b/hyhproject/wechat2/view/default/img/icon_zhanghuanquan.png new file mode 100755 index 0000000..a811c97 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_zhanghuanquan.png differ diff --git a/hyhproject/wechat2/view/default/img/icon_zhifu.png b/hyhproject/wechat2/view/default/img/icon_zhifu.png new file mode 100755 index 0000000..6ef7336 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/icon_zhifu.png differ diff --git a/hyhproject/wechat2/view/default/img/img_dpbg.png b/hyhproject/wechat2/view/default/img/img_dpbg.png new file mode 100755 index 0000000..27b239e Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_dpbg.png differ diff --git a/hyhproject/wechat2/view/default/img/img_dpjpj.png b/hyhproject/wechat2/view/default/img/img_dpjpj.png new file mode 100755 index 0000000..13959d0 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_dpjpj.png differ diff --git a/hyhproject/wechat2/view/default/img/img_error_2.png b/hyhproject/wechat2/view/default/img/img_error_2.png new file mode 100755 index 0000000..1e841c4 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_error_2.png differ diff --git a/hyhproject/wechat2/view/default/img/img_error_3.png b/hyhproject/wechat2/view/default/img/img_error_3.png new file mode 100755 index 0000000..248cc7e Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_error_3.png differ diff --git a/hyhproject/wechat2/view/default/img/img_fenxiangtishi.png b/hyhproject/wechat2/view/default/img/img_fenxiangtishi.png new file mode 100755 index 0000000..fb44426 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_fenxiangtishi.png differ diff --git a/hyhproject/wechat2/view/default/img/img_gd_sel.png b/hyhproject/wechat2/view/default/img/img_gd_sel.png new file mode 100755 index 0000000..a3422a4 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_gd_sel.png differ diff --git a/hyhproject/wechat2/view/default/img/img_jgsx.png b/hyhproject/wechat2/view/default/img/img_jgsx.png new file mode 100755 index 0000000..e7beb51 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_jgsx.png differ diff --git a/hyhproject/wechat2/view/default/img/img_titlebg.png b/hyhproject/wechat2/view/default/img/img_titlebg.png new file mode 100755 index 0000000..0bf2dc4 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_titlebg.png differ diff --git a/hyhproject/wechat2/view/default/img/img_users_icon.png b/hyhproject/wechat2/view/default/img/img_users_icon.png new file mode 100755 index 0000000..95e6f3f Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_users_icon.png differ diff --git a/hyhproject/wechat2/view/default/img/img_wdye.png b/hyhproject/wechat2/view/default/img/img_wdye.png new file mode 100755 index 0000000..b892d01 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/img_wdye.png differ diff --git a/hyhproject/wechat2/view/default/img/index-icon.png b/hyhproject/wechat2/view/default/img/index-icon.png new file mode 100755 index 0000000..3526e1f Binary files /dev/null and b/hyhproject/wechat2/view/default/img/index-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/info_icon.png b/hyhproject/wechat2/view/default/img/info_icon.png new file mode 100755 index 0000000..7b1859b Binary files /dev/null and b/hyhproject/wechat2/view/default/img/info_icon.png differ diff --git a/hyhproject/wechat2/view/default/img/line-address.png b/hyhproject/wechat2/view/default/img/line-address.png new file mode 100755 index 0000000..ee3a713 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/line-address.png differ diff --git a/hyhproject/wechat2/view/default/img/message-icon.png b/hyhproject/wechat2/view/default/img/message-icon.png new file mode 100755 index 0000000..7872e30 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/message-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/mine-icon.png b/hyhproject/wechat2/view/default/img/mine-icon.png new file mode 100755 index 0000000..ef93c44 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/mine-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/nocite_deliver.png b/hyhproject/wechat2/view/default/img/nocite_deliver.png new file mode 100755 index 0000000..da071f1 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nocite_deliver.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-account.png b/hyhproject/wechat2/view/default/img/nothing-account.png new file mode 100755 index 0000000..51a9de7 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-account.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-address.png b/hyhproject/wechat2/view/default/img/nothing-address.png new file mode 100755 index 0000000..5d1a3c9 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-address.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-cart.png b/hyhproject/wechat2/view/default/img/nothing-cart.png new file mode 100755 index 0000000..c812fa2 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-cart.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-complaint.png b/hyhproject/wechat2/view/default/img/nothing-complaint.png new file mode 100755 index 0000000..eebc63b Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-complaint.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-evaluate.png b/hyhproject/wechat2/view/default/img/nothing-evaluate.png new file mode 100755 index 0000000..4fc6c3a Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-evaluate.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-follow-goods.png b/hyhproject/wechat2/view/default/img/nothing-follow-goods.png new file mode 100755 index 0000000..3527fe0 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-follow-goods.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-follow-shps.png b/hyhproject/wechat2/view/default/img/nothing-follow-shps.png new file mode 100755 index 0000000..b4a6ed3 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-follow-shps.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-goods.png b/hyhproject/wechat2/view/default/img/nothing-goods.png new file mode 100755 index 0000000..df6e092 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-goods.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-history.png b/hyhproject/wechat2/view/default/img/nothing-history.png new file mode 100755 index 0000000..5daa14c Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-history.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-message.png b/hyhproject/wechat2/view/default/img/nothing-message.png new file mode 100755 index 0000000..371d098 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-message.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-order.png b/hyhproject/wechat2/view/default/img/nothing-order.png new file mode 100755 index 0000000..88e9568 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-order.png differ diff --git a/hyhproject/wechat2/view/default/img/nothing-relevant.png b/hyhproject/wechat2/view/default/img/nothing-relevant.png new file mode 100755 index 0000000..43b7617 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/nothing-relevant.png differ diff --git a/hyhproject/wechat2/view/default/img/notice.png b/hyhproject/wechat2/view/default/img/notice.png new file mode 100755 index 0000000..0ff0965 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/notice.png differ diff --git a/hyhproject/wechat2/view/default/img/order.png b/hyhproject/wechat2/view/default/img/order.png new file mode 100755 index 0000000..6e3563a Binary files /dev/null and b/hyhproject/wechat2/view/default/img/order.png differ diff --git a/hyhproject/wechat2/view/default/img/pays-ali.png b/hyhproject/wechat2/view/default/img/pays-ali.png new file mode 100755 index 0000000..5397889 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/pays-ali.png differ diff --git a/hyhproject/wechat2/view/default/img/pays-cod.png b/hyhproject/wechat2/view/default/img/pays-cod.png new file mode 100755 index 0000000..b24574b Binary files /dev/null and b/hyhproject/wechat2/view/default/img/pays-cod.png differ diff --git a/hyhproject/wechat2/view/default/img/pays-union.png b/hyhproject/wechat2/view/default/img/pays-union.png new file mode 100755 index 0000000..ca9116e Binary files /dev/null and b/hyhproject/wechat2/view/default/img/pays-union.png differ diff --git a/hyhproject/wechat2/view/default/img/pays-wallets.png b/hyhproject/wechat2/view/default/img/pays-wallets.png new file mode 100755 index 0000000..1a1893a Binary files /dev/null and b/hyhproject/wechat2/view/default/img/pays-wallets.png differ diff --git a/hyhproject/wechat2/view/default/img/pays-weixin.png b/hyhproject/wechat2/view/default/img/pays-weixin.png new file mode 100755 index 0000000..334b7dc Binary files /dev/null and b/hyhproject/wechat2/view/default/img/pays-weixin.png differ diff --git a/hyhproject/wechat2/view/default/img/qq.png b/hyhproject/wechat2/view/default/img/qq.png new file mode 100755 index 0000000..41d774f Binary files /dev/null and b/hyhproject/wechat2/view/default/img/qq.png differ diff --git a/hyhproject/wechat2/view/default/img/screenshot.png b/hyhproject/wechat2/view/default/img/screenshot.png new file mode 100755 index 0000000..91a28ed Binary files /dev/null and b/hyhproject/wechat2/view/default/img/screenshot.png differ diff --git a/hyhproject/wechat2/view/default/img/self.png b/hyhproject/wechat2/view/default/img/self.png new file mode 100755 index 0000000..04c92b9 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/self.png differ diff --git a/hyhproject/wechat2/view/default/img/shopstreet.png b/hyhproject/wechat2/view/default/img/shopstreet.png new file mode 100755 index 0000000..414a677 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/shopstreet.png differ diff --git a/hyhproject/wechat2/view/default/img/sign-icon.png b/hyhproject/wechat2/view/default/img/sign-icon.png new file mode 100755 index 0000000..2650e46 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/sign-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/sign-icon2.png b/hyhproject/wechat2/view/default/img/sign-icon2.png new file mode 100755 index 0000000..644fc4a Binary files /dev/null and b/hyhproject/wechat2/view/default/img/sign-icon2.png differ diff --git a/hyhproject/wechat2/view/default/img/top.png b/hyhproject/wechat2/view/default/img/top.png new file mode 100755 index 0000000..ff56f14 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/top.png differ diff --git a/hyhproject/wechat2/view/default/img/user-order-icon.png b/hyhproject/wechat2/view/default/img/user-order-icon.png new file mode 100755 index 0000000..385ad15 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user-order-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/user-tool-icon.png b/hyhproject/wechat2/view/default/img/user-tool-icon.png new file mode 100755 index 0000000..4a351e3 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user-tool-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/user-tool-icon2.png b/hyhproject/wechat2/view/default/img/user-tool-icon2.png new file mode 100755 index 0000000..eec3689 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user-tool-icon2.png differ diff --git a/hyhproject/wechat2/view/default/img/user-wallet-icon.png b/hyhproject/wechat2/view/default/img/user-wallet-icon.png new file mode 100755 index 0000000..eeb09ba Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user-wallet-icon.png differ diff --git a/hyhproject/wechat2/view/default/img/user.png b/hyhproject/wechat2/view/default/img/user.png new file mode 100755 index 0000000..f960db5 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user.png differ diff --git a/hyhproject/wechat2/view/default/img/user_grade.png b/hyhproject/wechat2/view/default/img/user_grade.png new file mode 100755 index 0000000..abcfe21 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user_grade.png differ diff --git a/hyhproject/wechat2/view/default/img/user_line.png b/hyhproject/wechat2/view/default/img/user_line.png new file mode 100755 index 0000000..b876d27 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/user_line.png differ diff --git a/hyhproject/wechat2/view/default/img/users_icon.png b/hyhproject/wechat2/view/default/img/users_icon.png new file mode 100755 index 0000000..22cd001 Binary files /dev/null and b/hyhproject/wechat2/view/default/img/users_icon.png differ diff --git a/hyhproject/wechat2/view/default/index.html b/hyhproject/wechat2/view/default/index.html new file mode 100755 index 0000000..9702dd3 --- /dev/null +++ b/hyhproject/wechat2/view/default/index.html @@ -0,0 +1,168 @@ +{extend name="default/base" /} +{block name="title"}首页 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/index.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive {if($subscribe==1)} wst-in-change{/if} wst-in-header" id="j-header"> + </header> + <div class="wst-in-search {if($subscribe==1)} wst-in-change{/if}"> + <div class="classify"><a href="{:url('wechat/goodscats/index')}"><i></i></a></div> + <div class="searchs" id="j-searchs" onclick="javascript:WST.searchPage('goods',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('goods',1);"></i> + <form action="" class="input-form"> + <input type="search" placeholder="按关键字搜索商品" onsearch="WST.search(0)" autocomplete="off" disabled="disabled"> + </form> + <div class="wst-clear"></div> + </div> + <div class="user"><a href="{:url('wechat/messages/index')}">{if condition="session('WST_USER.userId') >0"}<i>{if($news['message']['num']>0)}<span class="number">{$news['message']['num']}</span>{/if}</i>{else}登录{/if}</a></div> + </div> + {if($subscribe==1)} + <div class="wst-in-public"> + <div class="back"></div> + <div class="public"><div class="public2"> + <i class="ui-icon-close-page" onclick="javascript:closeFollow();"></i> + <div class="logo"><a><img src="__ROOT__/{:WSTConf('CONF.mallLogo')}"></a></div> + <div class="prompt"><p>您尚未关注公众号</p><p>点击右边按钮立即关注</p></div> + <button class="button" onclick="javascript:forFollow();">立即关注</button> + <div class="wst-clear"></div> + </div></div> + </div> + {/if} +{/block} +{block name="main"} +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<section class="ui-container"> + <div class="ui-slider" style="padding-top:50%;"> + <ul class="ui-slider-content" style="{if($ads['count']>0)}{$ads['width']}{/if}"> + {wst:ads code="wx-ads-index" cache='86400'} + <li class="advert1"><span><a href="{$vo.adURL}"><img style="width:100%; height:100%; display:block;" src="__ROOT__/{:WSTImg($vo.adFile,2)}"></a></span></li> + {/wst:ads} + </ul> + </div> + <div class="ui-row wst-in-choose"> + {volist name=':WSTMobileBtns(1)' id='btn'} + <div class="ui-col ui-col-20"> + <a href="{:url($btn['btnUrl'])}"> + <p><img src="__ROOT__/{$btn['btnImg']}" style='margin-top:7px;'/></p> + <span>{$btn['btnName']}</span> + </a></div> + {/volist} + </div> + + <div class="wst-in-activity"> + {wst:ads code="wx-index-long" cache='86400' num='4'}<a class="advert4" href="{$vo.adURL}"><div class="img"><img src="__ROOT__/{:WSTImg($vo.adFile,2)}"/></div></a>{/wst:ads} + <div class="wst-in-news"> + <span class="new">商城&nbsp;<p>快讯</p></span> + <div class="article"> + <div class="swiper-container swiper-container1"> + <div class="swiper-wrapper"> + {wst:article cat="new" num='6' cache='86400'} + <div class="swiper-slide" style="width:100%;"> + <a class="words" href="{:url('wechat/news/view',['articleId'=>$vo['articleId']])}"><p class="ui-nowrap-flex">{$vo['articleTitle']}</p></a> + </div> + {/wst:article} + </div> + </div> + </div> + <span class="more" onclick="location.href='{:url('wechat/news/view')}'">更多</span> + <div class="wst-clear"></div> + </div> + </div> + + <div class="wst-in-adst"> + {wst:ads code="wx-index-left" cache='86400' num='1'} + <a class="advert2" href="{$vo.adURL}"><img src="__ROOT__/{:WSTImg($vo.adFile,2)}" style="height:2rem;"/></a> + {/wst:ads} + {wst:ads code="wx-index-right" cache='86400' num='2'} + <a class="advert2" href="{$vo.adURL}"><img src="__ROOT__/{:WSTImg($vo.adFile,2)}" style="height:0.995rem;"/></a> + {/wst:ads} + <div class="wst-clear"></div> + </div> + <div class="wst-in-adsb"> + <div class="swiper-container swiper-container2"> + <div class="swiper-wrapper"> + {wst:ads code="wx-index-small" cache='86400' num='10'} + <div class="swiper-slide" style="width:33.333333%;"> + <div class="goodsinfo-container"> + <a class="advert3" href="{$vo.adURL}"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($vo.adFile,2)}"></a> + </div> + </div> + {/wst:ads} + </div> + </div> + </div> + <div id="goods-list"></div> +</section> +<script id="list" type="text/html"> +<div class="wst-in-title colour{{ d.currPage }}" onclick="javascript:getGoodsList({{ d.catId }});"> + <div class="line"></div><div class="name"><p><span><i class="icon"></i>{{ d.catName }}</span></p></div> +</div> + {{# if(d.ads && d.ads.length>0){ }} + <div class="wst-in-adscats"><a href="{{ d.ads[0].adURL }}"><img src="__ROOT__/{{ d.ads[0].adFile }}"/></a></div> + {{# } }} + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i<d.goods.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}"> + <div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d.goods[i].goodsImg }}" title="{{ d.goods[i].goodsName }}"/></a></div> + <div class="name ui-nowrap-multi" onclick="javascript:WST.intoGoods({{ d.goods[i].goodsId }});">{{ d.goods[i].goodsName }}</div> + <div class="info"><span class="price">¥ <span>{{ d.goods[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">好评率{{ d.goods[i].praiseRate }}</span><span class="deal">成交数:{{ d.goods[i].saleNum }}</span></div> + </div> + {{# } }} + {{# } }} +<div class="wst-clear"></div> +</script> +{/block} +{block name="include"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 二维码对话框*/} +<div class="ui-dialog" id="wst-di-weixincode" onclick="javascript:WST.dialogHide('weixincode');"> + <div class="ui-dialog-cnt wst-di-weixincode"> + <div class="wst-dialog-bd"> + <p class="title">长按识别二维码</p> + <div><img src="__ROOT__/{:WSTConf('CONF.wxAppLogo')}" style="width: 100%;"></div> + <p class="prompt">请长按上图并选择识别关注图中二维码</p> + </div> + </div> +</div> +{include file="default/goods_search" /} +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/index.js?v={$v}'></script> +{if(!empty($datawx))} +<script src="{:request()->scheme()}://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> +<script> +wx.config({ + debug: false, + appId: '<?php echo WSTConf('CONF.wxAppId'); ?>', //公众号的唯一标识 + timestamp: '<?php echo $datawx['timestamp'];?>', //生成签名的时间戳 + nonceStr: '<?php echo $datawx['noncestr'];?>', //生成签名的随机串 + signature: '<?php echo $datawx['signature'];?>',//签名 + jsApiList: [ //需要使用的JS接口 + 'onMenuShareTimeline', + 'onMenuShareAppMessage', + 'onMenuShareQQ', + 'onMenuShareWeibo', + 'onMenuShareQZone' + ] +}); +wx.ready(function(){ + var shareData = { + title: "{:WSTConf('CONF.mallName')}", + desc: "{:WSTConf('CONF.mallSlogan')}", + link: "{:url('wechat/index/index','',true,true)}", + imgUrl: "{:WSTRoot()}/{:WSTConf('CONF.mallLogo')}" + }; + wx.onMenuShareAppMessage(shareData); + wx.onMenuShareTimeline(shareData); + wx.onMenuShareQQ(shareData); + wx.onMenuShareWeibo(shareData); + wx.onMenuShareQZone(shareData); +}); +</script> +{/if} +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/brands.js b/hyhproject/wechat2/view/default/js/brands.js new file mode 100755 index 0000000..9c38f9f --- /dev/null +++ b/hyhproject/wechat2/view/default/js/brands.js @@ -0,0 +1,42 @@ +//商品列表页 +function getGoodsList(brandId){ + location.href = WST.U('wechat/goods/lists','brandId='+brandId); +} +//获取品牌列表 +function brandsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 16; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/brands/pageQuery'), param,function(data){ + var json = WST.toJson(data); + if(json && json.Rows && json.Rows.length>0){ + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#info-list').append(html); + }); + echo.init();//图片懒加载 + } + loading = false; + $('#Load').hide(); + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + brandsList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + brandsList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/carts.js b/hyhproject/wechat2/view/default/js/carts.js new file mode 100755 index 0000000..01b0168 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/carts.js @@ -0,0 +1,189 @@ +var promotionMethod = {}; +$(document).ready(function(){ + WST.initFooter('cart'); + WST.imgAdapt('j-imgAdapt'); + + statCartMoney(); + //选中店铺 + $('.ui-icon-chooses').click(function(){ + WST.changeIconStatus($(this), 1); + var childrenId = $(this).attr('childrenId'); + var goodsCount = $('.'+childrenId).length;//商品个数 + var ids = []; + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + WST.changeIconStatus($('.'+childrenId), 2);//选中 + for(var i=0; i<goodsCount; i++){ + var cid = $('.'+childrenId).eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),0); + }else{ + WST.changeIconStatus($('.'+childrenId), 2, 'wst-active');//取消选中 + for(var i=0; i<goodsCount; i++){ + var cid = $('.'+childrenId).eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),1); + } + statCartMoney(); + }); + //选中商品 + $('.ui-icon-chooseg').click(function(){ + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + var checked = 1; + WST.changeIconStatus($(this), 1);//选中 + }else{ + var checked = 0; + WST.changeIconStatus($(this), 2);//取消选中 + } + var cid = $(this).attr('cartId'); + if(cid!=''){ + WST.changeCartGoods(cid,$('#buyNum_'+cid).val(),checked); + statCartMoney(); + } + }); + //选中合计 + $('.ui-icon-choose').click(function(){ + WST.changeIconStatus($(this), 1); + var shopIconCount = $('.ui-icon-chooses').length;//店铺个数 + var goodsCount = $('.ui-icon-chooseg').length;//商品个数 + var ids = []; + if( $(this).attr('class').indexOf('wst-active') == -1 ){ + //选中所有 + for(var i=0; i<shopIconCount; i++){ + WST.changeIconStatus($('.ui-icon-chooses').eq(i), 2); + } + for(var i=0; i<goodsCount; i++){ + WST.changeIconStatus($('.ui-icon-chooseg').eq(i), 2); + var cid = $('.ui-icon-chooseg').eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),0); + }else{ + //取消选中所有 + for(var i=0; i<shopIconCount; i++){ + WST.changeIconStatus($('.ui-icon-chooses').eq(i), 2, 'wst-active'); + } + for(var i=0; i<goodsCount; i++){ + WST.changeIconStatus($('.ui-icon-chooseg').eq(i), 2, 'wst-active'); + var cid = $('.ui-icon-chooseg').eq(i).attr('cartId'); + ids.push(cid); + } + WST.batchChangeCartGoods(ids.join(','),1); + } + statCartMoney(); + }); +}); +//合计 +function statCartMoney(){ + var cartMoney = 0,goodsTotalPrice,id; + $('.wst-active').each(function(){ + id = $(this).attr('cartId'); + goodsTotalPrice = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + cartMoney = cartMoney + goodsTotalPrice; + }); + for(var i=1; i<$('#totalshop').val(); i++){ + var shopMoney = 0,goodsTotalPrice2; + $('.clist'+i).each(function(){ + id = $(this).attr('cartId'); + goodsTotalPrice2 = parseFloat($(this).attr('mval'))*parseInt($('#buyNum_'+id).val()); + shopMoney = shopMoney + goodsTotalPrice2; + }); + $('#tprice_'+i).html('<span>¥ </span>'+shopMoney.toFixed(2)); + } + /* 满就送 */ + var minusMoney = 0; + for(var key in promotionMethod){ + minusMoney = window[key](cartMoney); + cartMoney = cartMoney - minusMoney; + } + $('#totalMoney').html('<span>¥ </span>'+cartMoney.toFixed(2)); + checkGoodsBuyStatus(); +} +function checkGoodsBuyStatus(){ + var cartNum = 0,stockNum = 0,cartId = 0; + $('.wst-active').each(function(){ + cartId = $(this).attr('cartId'); + cartNum = parseInt($('#buyNum_'+cartId).val(),10); + stockNum = parseInt($('#buyNum_'+cartId).attr('data-max'),10); + if(stockNum < 0 || stockNum < cartNum){ + if(stockNum < 0){ + msg = '库存不足'; + }else{ + msg = '购买量超过库存'; + } + $('#noprompt'+cartId).show().html(msg); + $(this).parent().parent().addClass('nogoods'); + WST.changeIconStatus($(this), 2);//取消选中 + WST.changeCartGoods(cartId,$('#buyNum_'+cartId).val(),0); + statCartMoney(); + }else{ + $('#noprompt'+cartId).hide().html(''); + $(this).parent().parent().removeClass('nogoods'); + } + }); +} +//编辑 +function edit(type){ + if(type==0){ + WST.showHide('','#edit,#settlement,#total'); + WST.showHide(1,'#complete,#delete'); + }else{ + WST.showHide('','#complete,#delete'); + WST.showHide(1,'#edit,#settlement,#total'); + } +} +//删除 +function deletes(){ + var goodsIds = ''; + var goodsIconCount = $('.ui-icon-chooseg').length;//商品个数 + for(var i=0; i<goodsIconCount; i++){ + if( $('.ui-icon-chooseg').eq(i).attr('class').indexOf('wst-active') != -1 ){ + goodsIds += $('.ui-icon-chooseg').eq(i).attr('cartId') + ','; + } + } + if(goodsIds!=''){ + WST.dialog('确定删除选中的商品吗?','del("'+goodsIds+'")'); + }else{ + WST.msg('请选择要删除的商品','info'); + } +} +function del(goodsIds){ + $.post(WST.U('wechat/carts/delCart'),{id:goodsIds},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + WST.dialogHide('prompt'); + setTimeout(function(){ + location.href = WST.U('wechat/carts/index'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + } + }); +} +//结算 +function toSettlement(){ + var goodsIconCount = $('.ui-icon-chooseg').length;//商品个数 + var noGoodsSelected = true; + for(var i=0; i<goodsIconCount; i++){ + if( $('.ui-icon-chooseg').eq(i).attr('class').indexOf('wst-active') != -1 ){ + noGoodsSelected = false; + } + } + if(noGoodsSelected){ + WST.msg('请勾选要结算的商品','info'); + return false; + } + location.href = WST.U('wechat/carts/settlement'); +} +//导航 +function inMore(){ + if($("#arrow").css("display")=='none'){ + $("#arrow").show(); + $("#layer").show(); + }else{ + $("#arrow").hide(); + $("#layer").hide(); + } +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/common.js b/hyhproject/wechat2/view/default/js/common.js new file mode 100755 index 0000000..14db3e9 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/common.js @@ -0,0 +1,445 @@ +var WST = WST?WST:{}; +WST.wxv = '1.0_0825'; +WST.toJson = function(str,notLimit){ + var json = {}; + if(str){ + try{ + if(typeof(str )=="object"){ + json = str; + }else{ + json = eval("("+str+")"); + } + if(!notLimit){ + if(json.status && json.status=='-999'){ + WST.inLogin(); + } + } + }catch(e){ + alert("系统发生错误:"+e.getMessage); + json = {}; + } + return json; + }else{ + return; + } +} +//登录 +WST.inLogin = function(){ + var urla = window.location.href; + $.post(WST.U('wechat/index/sessionAddress'),{url:urla},function(data,textStatus){}); + var urls = escape(document.location.protocol+'//'+window.location.host+WST.U('wechat/users/login','type=1')); + var url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+WST.conf.wxAppId+'&redirect_uri='+urls+'&response_type=code&scope=snsapi_userinfo&state='+window.conf.wxAppCode+'#wechat_redirect'; + window.location.href = url; +} +//底部的tab +WST.initFooter = function(tab){ + var homeImage = (tab=='home') ? 'home-active' : 'home'; + var categoryImage = (tab=='category') ? 'category-active' : 'category'; + var cartImage = (tab=='cart') ? 'cart-active' : 'cart'; + var followImage = (tab=='brand') ? 'follow-active' : 'follow'; + var usersImage = (tab=='user') ? 'user-active' : 'user'; + $('#home').append('<span class="icon '+homeImage+'"></span><span class="'+homeImage+'-word">首页</span>'); + $('#category').append('<span class="icon '+categoryImage+'"></span><span class="'+categoryImage+'-word">分类</span>'); + $('#cart').prepend('<span class="icon '+cartImage+'"></span><span class="'+cartImage+'-word">购物车</span>'); + $('#follow').append('<span class="icon '+followImage+'"></span><span class="'+followImage+'-word">关注</span>'); + $('#user').append('<span class="icon '+usersImage+'"></span><span class="'+usersImage+'-word">我的</span>'); +} +//变换选中框的状态 +WST.changeIconStatus = function (obj, toggle, status){ + if(toggle==1){ + if( obj.attr('class').indexOf('ui-icon-unchecked-s') > -1 ){ + obj.removeClass('ui-icon-unchecked-s').addClass('ui-icon-success-block wst-active'); + }else{ + obj.removeClass('ui-icon-success-block wst-active').addClass('ui-icon-unchecked-s'); + } + }else if(toggle==2){ + if(status == 'wst-active'){ + obj.removeClass('ui-icon-unchecked-s').addClass('ui-icon-success-block wst-active'); + }else{ + obj.removeClass('ui-icon-success-block wst-active').addClass('ui-icon-unchecked-s'); + } + } +} +WST.changeIptNum = function(diffNum,iptId,id,func){ + var suffix = (id)?"_"+id:""; + var iptElem = $(iptId+suffix); + var minVal = parseInt(iptElem.attr('data-min'),10); + var maxVal = parseInt(iptElem.attr('data-max'),10); + var num = parseInt(iptElem.val(),10); + num = num?num:1; + num = num + diffNum; + if(maxVal<=num)num=maxVal; + if(num<=minVal)num=minVal; + if(num==0)num=1; + iptElem.val(num); + if(suffix!='')WST.changeCartGoods(id,num,-1); + if(func){ + var fn = window[func]; + fn(); + } +} +WST.changeCartGoods = function(id,buyNum,isCheck){ + $.post(WST.U('wechat/carts/changeCartGoods'),{id:id,isCheck:isCheck,buyNum:buyNum,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,'info'); + } + }); +} +// 批量修改购物车状态 +WST.batchChangeCartGoods = function(ids,isCheck){ + $.post(WST.U('wechat/carts/batchChangeCartGoods'),{ids:ids,isCheck:isCheck},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status!=1){ + WST.msg(json.msg,'info'); + } + }); +} +//商品主页 +WST.intoGoods = function(id){ + location.href = WST.U('wechat/goods/detail','goodsId='+id); +}; +//店铺主页 +WST.intoShops = function(id){ + location.href = WST.U('wechat/shops/home','shopId='+id); +}; +//首页 +WST.intoIndex = function(){ + location.href = WST.U('wechat/index/index'); +}; +//搜索 +WST.searchPage = function(type,state){ + if(state==1){ + $("#wst-"+type+"-search").show(); + }else{ + $("#wst-"+type+"-search").hide(); + } +}; +WST.search = function(type){ + var data = $('#wst-search').val(); + if(type==1){ + location.href = WST.U('wechat/shops/shopStreet','keyword='+data);//店铺 + }else if(type==0){ + location.href = WST.U('wechat/goods/lists','keyword='+data);//商品 + }else if(type==2){ + var shopId = $('#shopId').val(); + location.href = WST.U('wechat/shops/shopGoodsList','goodsName='+data+'&shopId='+shopId);//店铺商品 + } +}; +//关注 +WST.favorites = function(sId,type){ + $.post(WST.U('wechat/favorites/add'),{id:sId,type:type},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + if(type==1){ + $('#fStatus').html('已关注'); + $('#fBtn').attr('onclick','WST.cancelFavorite('+json.data.fId+',1)'); + $('.j-shopfollow').addClass('follow'); + $('#followNum').html(parseInt($('#followNum').html())+1); + }else{ + $('.imgfollow').removeClass('nofollow').addClass('follow'); + $('.imgfollow').attr('onclick','WST.cancelFavorite('+json.data.fId+',0)'); + } + }else{ + WST.msg(json.msg,'info'); + } + }) +} +// 取消关注 +WST.cancelFavorite = function(fId,type){ + $.post(WST.U('wechat/favorites/cancel'),{id:fId,type:type},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + if(type==1){ + $('#fStatus').html('关注店铺'); + $('#fBtn').attr('onclick','WST.favorites('+$('#shopId').val()+',1)'); + $('.j-shopfollow').removeClass('follow'); + $('#followNum').html(parseInt($('#followNum').html())-1); + }else{ + $('.imgfollow').removeClass('follow').addClass('nofollow'); + $('.imgfollow').attr('onclick','WST.favorites('+$('#goodsId').val()+',0)'); + } + }else{ + WST.msg(json.msg,'info'); + } + }); +} +WST.userPhoto = function(userPhoto){ + if(userPhoto.substring(0,4)!='http' && userPhoto!=""){ + userPhoto = window.conf.ROOT+"/"+userPhoto; + }else if(!userPhoto){ + userPhoto = window.conf.ROOT+"/"+window.conf.USER_LOGO; + } + return userPhoto; +} +//刷新验证码 +WST.getVerify = function(id){ + $(id).attr('src',WST.U('wechat/index/getVerify','rnd='+Math.random())); +} +//返回当前页面高度 +WST.pageHeight = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientHeight : + document.body.clientHeight; + }else{ + return self.innerHeight; + } +}; +//返回当前页面宽度 +WST.pageWidth = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientWidth : + document.body.clientWidth; + }else{ + return self.innerWidth; + } +}; +WST.checkBrowser = function(){ + return { + mozilla : /firefox/.test(navigator.userAgent.toLowerCase()), + webkit : /webkit/.test(navigator.userAgent.toLowerCase()), + opera : /opera/.test(navigator.userAgent.toLowerCase()), + msie : /msie/.test(navigator.userAgent.toLowerCase()) + } +} +//只能輸入數字 +WST.isNumberKey = function(evt){ + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && (charCode < 48 || charCode > 57)){ + return false; + }else{ + return true; + } +} +WST.isChinese = function(obj,isReplace){ + var pattern = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/i + if(pattern.test(obj.value)){ + if(isReplace)obj.value=obj.value.replace(/[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/ig,""); + return true; + } + return false; +} +//适应图片大小正方形 +WST.imgAdapt = function(name){ + var w = $('.'+name).width(); + $('.'+name).css({"width": w+"px","height": w+"px"}); + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"max-width": w+"px","max-height": w+"px"}); +} +//显示隐藏 +WST.showHide = function(t,str){ + var s = str.split(','); + if(t){ + for(var i=0;i<s.length;i++){ + $(s[i]).show(); + } + }else{ + for(var i=0;i<s.length;i++){ + $(s[i]).hide(); + } + } + s = null; +} +/** + * 提示信息 + * @param content 内容 + * @param type info/普通,success/成功,warn/错误 + * @param stayTime 显示时间 + */ +WST.msg = function(content,type,stayTime){ + if(!stayTime){ + stayTime = '1200'; + } + var el = $.tips({content:content,type:type,stayTime:stayTime}); + return el; +} +//提示对话框 +WST.dialog = function(content,event){ + $("#wst-dialog").html(content); + $("#wst-event2").attr("onclick","javascript:"+event); + $("#wst-di-prompt").dialog("show"); +} +//提示分享对话框 +WST.share = function(){ + $("#wst-di-share").dialog("show"); +} +/** + * 隐藏对话框 + * @param event prompt/提示对话框 + * @param event share/提示对话框 + */ +WST.dialogHide = function(event){ + $("#wst-di-"+event).dialog("hide"); +} +//加载中 +WST.load = function(content){ + $('#Loadl').css('display','-webkit-box'); + $('#j-Loadl').html(content); +} +WST.noload = function(){ + $('#Loadl').css('display','none'); +} +//滚动到顶部 +WSTrunToTop = function (){ + currentPosition=document.documentElement.scrollTop || document.body.scrollTop; + currentPosition-=20; + if(currentPosition>0){ + window.scrollTo(0,currentPosition); + } + else{ + window.scrollTo(0,0); + clearInterval(timer); + } +} + +WST.blank = function(str,defaultVal){ + if(str=='0000-00-00')str = ''; + if(str=='0000-00-00 00:00:00')str = ''; + if(!str)str = ''; + if(typeof(str)=='null')str = ''; + if(typeof(str)=='undefined')str = ''; + if(str=='' && defaultVal)str = defaultVal; + return str; +} + +/** +* 上传图片 +*/ +WST.upload = function(opts){ + var _opts = {}; + _opts = $.extend(_opts,{auto: true,swf: WST.conf.ROOT +'/plugins/webuploader/Uploader.swf',server:WST.U('wechat/orders/uploadPic')},opts); + var uploader = WebUploader.create(_opts); + uploader.on('uploadSuccess', function( file,response ) { + var json = WST.toJson(response._raw); + if(_opts.callback)_opts.callback(json,file); + }); + uploader.on('uploadError', function( file ) { + if(_opts.uploadError)_opts.uploadError(); + }); + uploader.on( 'uploadProgress', function( file, percentage ) { + percentage = percentage.toFixed(2)*100; + if(_opts.progress)_opts.progress(percentage); + }); + return uploader; +} + +//返回键 +function backPrevPage(url){ + window.location.hash = "ready"; + window.location.hash = "ok"; + setTimeout(function(){ + $(window).on('hashchange', function(e) { + var hashName = window.location.hash.replace('#', ''); + hashName = hashName.split('&'); + if( hashName[0] == 'ready' ){ + location.href = url; + } + }); + },50); +} + +//图片切换 +WST.replaceImg = function(v,str){ + var vs = v.split('.'); + return v.replace("."+vs[1],str+"."+vs[1]); +} + +$(function(){ + echo.init();//图片懒加载 + // 滚动到顶部 + $(window).scroll(function(){ + if( $(window).scrollTop() > 200 ){ + $('#toTop').show(); + }else{ + $('#toTop').hide(); + } + }); + $('#toTop').on('click', function() { + timer=setInterval("WSTrunToTop()",1); + }); + /** + * 获取WSTMart基础配置 + * @type {object} + */ + WST.conf = window.conf; + /* 基础对象检测 */ + WST.conf || $.error("WSTMart基础配置没有正确加载!"); + /** + * 解析URL + * @param {string} url 被解析的URL + * @return {object} 解析后的数据 + */ + WST.parse_url = function(url){ + var parse = url.match(/^(?:([a-z]+):\/\/)?([\w-]+(?:\.[\w-]+)+)?(?::(\d+))?([\w-\/]+)?(?:\?((?:\w+=[^#&=\/]*)?(?:&\w+=[^#&=\/]*)*))?(?:#([\w-]+))?$/i); + parse || $.error("url格式不正确!"); + return { + "scheme" : parse[1], + "host" : parse[2], + "port" : parse[3], + "path" : parse[4], + "query" : parse[5], + "fragment" : parse[6] + }; + } + + WST.parse_str = function(str){ + var value = str.split("&"), vars = {}, param; + for(var i=0;i<value.length;i++){ + param = value[i].split("="); + vars[param[0]] = param[1]; + } + return vars; + } + WST.U = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url), path = [], reg; + /* 验证info */ + info.path || $.error("url格式错误!"); + url = info.path; + /* 解析URL */ + path = url.split("/"); + path = [path.pop(), path.pop(), path.pop()].reverse(); + path[1] || $.error("WST.U(" + url + ")没有指定控制器"); + + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + /* 解析URL自带的参数 */ + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + url += "?" + $.param(vars); + } + //url = url.replace(new RegExp("%2F","gm"),"+"); + url = WST.conf.APP + "/"+url; + return url; + } + WST.AU = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url); + url = info.path; + path = url.split("/"); + url = "addon/"; + path = [path.pop(), path.pop()].reverse(); + path[0] || $.error("WST.AU(" + url + ")没有指定控制器"); + path[1] || $.error("WST.AU(" + url + ")没有指定接口"); + url = url + info.scheme + "-" + path.join('-'); + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + url += "?" + $.param(vars); + } + return WST.conf.APP + "/"+url; + } +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/echo.min.js b/hyhproject/wechat2/view/default/js/echo.min.js new file mode 100755 index 0000000..ebcedda --- /dev/null +++ b/hyhproject/wechat2/view/default/js/echo.min.js @@ -0,0 +1,2 @@ +/*! echo.js v1.7.0 | (c) 2015 @toddmotto | https://github.com/toddmotto/echo */ +!function(t,e){"function"==typeof define&&define.amd?define(function(){return e(t)}):"object"==typeof exports?module.exports=e:t.echo=e(t)}(this,function(t){"use strict";var e,n,o,r,c,a={},d=function(){},u=function(t,e){var n=t.getBoundingClientRect();return n.right>=e.l&&n.bottom>=e.t&&n.left<=e.r&&n.top<=e.b},l=function(){(r||!n)&&(clearTimeout(n),n=setTimeout(function(){a.render(),n=null},o))};return a.init=function(n){n=n||{};var u=n.offset||0,i=n.offsetVertical||u,f=n.offsetHorizontal||u,s=function(t,e){return parseInt(t||e,10)};e={t:s(n.offsetTop,i),b:s(n.offsetBottom,i),l:s(n.offsetLeft,f),r:s(n.offsetRight,f)},o=s(n.throttle,250),r=n.debounce!==!1,c=!!n.unload,d=n.callback||d,a.render(),document.addEventListener?(t.addEventListener("scroll",l,!1),t.addEventListener("load",l,!1)):(t.attachEvent("onscroll",l),t.attachEvent("onload",l))},a.render=function(){for(var n,o,r=document.querySelectorAll("img[data-echo], [data-echo-background]"),l=r.length,i={l:0-e.l,t:0-e.t,b:(t.innerHeight||document.documentElement.clientHeight)+e.b,r:(t.innerWidth||document.documentElement.clientWidth)+e.r},f=0;l>f;f++)o=r[f],u(o,i)?(c&&o.setAttribute("data-echo-placeholder",o.src),null!==o.getAttribute("data-echo-background")?o.style.backgroundImage="url("+o.getAttribute("data-echo-background")+")":o.src=o.getAttribute("data-echo"),c||o.removeAttribute("data-echo"),d(o,"load")):c&&(n=o.getAttribute("data-echo-placeholder"))&&(null!==o.getAttribute("data-echo-background")?o.style.backgroundImage="url("+n+")":o.src=n,o.removeAttribute("data-echo-placeholder"),d(o,"unload"));l||a.detach()},a.detach=function(){document.removeEventListener?t.removeEventListener("scroll",l):t.detachEvent("onscroll",l),clearTimeout(n)},a}); diff --git a/hyhproject/wechat2/view/default/js/goods_category.js b/hyhproject/wechat2/view/default/js/goods_category.js new file mode 100755 index 0000000..25fd2cc --- /dev/null +++ b/hyhproject/wechat2/view/default/js/goods_category.js @@ -0,0 +1,41 @@ +jQuery.noConflict(); +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + jQuery('.goodscate1').eq(index).fadeIn(200).siblings('.goodscate1').hide(); +} +//商品列表页 +function getGoodsList(goodsCatId){ + location.href = WST.U('wechat/goods/lists','catId='+goodsCatId); +} +//品牌-商品列表页 +function getBrandGoodsList(brandId){ + location.href = WST.U('wechat/goods/lists','brandId='+brandId); +} +//适应高度 +function selfAdapt(h){ + var o = document.getElementById('ui-scrollerl'); + var a = h-86; + o.style.height=a+'px'; +} +var height = WST.pageHeight(); +$(document).ready(function(){ + WST.initFooter('category'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + selfAdapt(height); + $(window).scroll(function(event){ + var h = WST.pageHeight(); + selfAdapt(h); + }); + var scroll = new fz.Scroll('.ui-scrollerl', { + scrollY: true, + slidingY: 'y' + }); + var w = WST.pageWidth(); + var wImg=(w*0.76-30)/3; + var hImg = wImg*9/14; + $('.wst-gc-br img').css('height',hImg); + var w = $('.goods-cat-img').width(); + $('.goods-cat-img').css('height',w); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/goods_detail.js b/hyhproject/wechat2/view/default/js/goods_detail.js new file mode 100755 index 0000000..d35bfe7 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/goods_detail.js @@ -0,0 +1,232 @@ +jQuery.noConflict(); +//切换 +function pageSwitch(obj,type){ + $(obj).addClass('active').siblings('.ui-tab-nav li.switch').removeClass('active'); + $('#goods'+type).show().siblings('section.ui-container').hide(); + if(type==1){ + var offsetTop = $("#goods1").offset().top; + var scrollTop = $(window).scrollTop()-100; + if (scrollTop > offsetTop){ + $("#goods-header").show(); + }else{ + $("#goods-header").hide(); + } + } + if(type==3){ + $("#goods-header").show(); + } +} +//商品评价列表 +function evaluateList(){ + loading = true; + var param = {}; + param.goodsId = $('#goodsId').val(); + param.type = $('#evaluateType').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/goodsappraises/getById'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.data.CurrentPage); + $('#totalPage').val(json.data.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.data.Rows, function(html){ + $('#evaluate-list').append(html); + }); + loading = false; + echo.init();//图片懒加载 + }); +} +function evaluateSwitch(obj,type){ + $('#evaluateType').val(type); + $(obj).addClass('active').siblings('.wst-ev-term .ui-col').removeClass('active'); + $('#currPage').val('0'); + $('#totalPage').val('0'); + $('#evaluate-list').html(''); + evaluateList(); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + //商品图片 + new Swiper('.swiper-container', { + slidesPerView: 1, + spaceBetween: 0, + grabCursor : true, + autoplayDisableOnInteraction : true, + pagination : '.swiper-pagination', + paginationClickable :true + }); + evaluateList(); + fixedHeader(); + WST.imgAdapt('j-imgAdapt'); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + evaluateList(); + } + } + }); + if(goodsInfo.sku){ + var specs,dv; + for(var key in goodsInfo.sku){ + if(goodsInfo.sku[key].isDefault==1){ + specs = key.split(':'); + $('.j-option').each(function(){ + dv = $(this).attr('data-val') + if($.inArray(dv,specs)>-1){ + $(this).addClass('active'); + } + }) + $('#buyNum').attr('data-max',goodsInfo.sku[key].specStock); + } + } + }else{ + $('#buyNum').attr('data-max',goodsInfo.goodsStock); + } + checkGoodsStock(); + //选择规格 + $('.spec .j-option').click(function(){ + $(this).addClass('active').siblings().removeClass('active'); + checkGoodsStock(); + }); + //弹框的高度 + var dataHeight = $("#frame").css('height'); + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + if(parseInt(dataHeight)>230){ + $('#content').css('overflow-y','scroll').css('height','200'); + } + if(parseInt(cartHeight)>420){ + $('#standard').css('overflow-y','scroll').css('height','260'); + } + var dataHeight = $("#frame").css('height'); + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + $("#frame").css('bottom','-'+dataHeight); + $("#frame-cart").css('bottom','-'+cartHeight); +}); +function checkGoodsStock(){ + var specIds = [],stock = 0,goodsPrice=0,marketPrice=0; + if(goodsInfo.isSpec==1){ + $('.spec .active').each(function(){ + specIds.push(parseInt($(this).attr('data-val'),10)); + }); + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + stock = goodsInfo.sku[specIds.join(':')].specStock; + marketPrice = goodsInfo.sku[specIds.join(':')].marketPrice; + goodsPrice = goodsInfo.sku[specIds.join(':')].specPrice; + } + }else{ + stock = goodsInfo.goodsStock; + marketPrice = goodsInfo.marketPrice; + goodsPrice = goodsInfo.goodsPrice; + } + $('#goods-stock').html(stock); + $('#buyNum').attr('data-max',stock); + $('#j-market-price').html('¥'+marketPrice); + $('#j-shop-price').html('¥'+goodsPrice); + if(stock<=0){ + $('#addBtn').addClass('disabled'); + $('#buyBtn').addClass('disabled'); + }else{ + $('#addBtn').removeClass('disabled'); + $('#buyBtn').removeClass('disabled'); + } +} +//导航 +function fixedHeader(){ + var offsetTop = $("#goods1").offset().top; + $(window).scroll(function() { + if($("#goods1").css("display")!='none'){ + var scrollTop = $(window).scrollTop()-100; + if (scrollTop > offsetTop){ + $("#goods-header").show(); + }else{ + $("#goods-header").hide(); + } + }else{ + $("#goods-header").show(); + } + }); +} +function inMore(){ + if($("#arrow").css("display")=='none'){ + jQuery('#arrow').show(200); + $("#layer").show(); + }else{ + jQuery('#arrow').hide(100); + $("#layer").hide(); + } +} +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} +//弹框 +var type; +function cartShow(t){ + type = t; + jQuery('#cover').attr("onclick","javascript:cartHide();").show(); + jQuery('#frame-cart').animate({"bottom": 0}, 500); +} +function cartHide(){ + var cartHeight = parseInt($("#frame-cart").css('height'))+52+'px'; + jQuery('#frame-cart').animate({'bottom': '-'+cartHeight}, 500); + jQuery('#cover').hide(); +} +//加入购物车 +function addCart(){ + var goodsSpecId = 0; + if(goodsInfo.isSpec==1){ + var specIds = []; + $('.spec .active').each(function(){ + specIds.push($(this).attr('data-val')); + }); + if(specIds.length==0){ + WST.msg('请选择你要购买的商品信息','info'); + } + specIds.sort(function(a,b){return a-b;}); + if(goodsInfo.sku[specIds.join(':')]){ + goodsSpecId = goodsInfo.sku[specIds.join(':')].id; + } + } + var goodsType = $("#goodsType").val(); + var buyNum = $("#buyNum").val()?$("#buyNum").val():1; + $.post(WST.U('wechat/carts/addCart'),{goodsId:goodsInfo.id,goodsSpecId:goodsSpecId,buyNum:buyNum,type:type,rnd:Math.random()},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + cartHide(); + if(type==1){ + setTimeout(function(){ + if(goodsType==1){ + location.href=WST.U('wechat/carts/'+json.data.forward); + }else{ + location.href=WST.U('wechat/carts/settlement'); + } + },1000); + }else{ + if(json.cartNum>0)$("#cartNum").html('<span>'+json.cartNum+'</span>'); + } + }else{ + WST.msg(json.msg,'info'); + } + }); +} +document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#cover").is(":hidden")){ + event.preventDefault(); + } + if(!jQuery("#layer").is(":hidden")){ + event.preventDefault(); + } +}) \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/goods_list.js b/hyhproject/wechat2/view/default/js/goods_list.js new file mode 100755 index 0000000..11a3ca8 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/goods_list.js @@ -0,0 +1,92 @@ +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#goods-list').html(''); + goodsList(); +} +//获取商品列表 +function goodsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.catId = $('#catId').val(); + param.brandId = $('#brandId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#keyword').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/goods/pageQuery'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#goods-list').append(html); + }); + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +//切换 +function switchList(obj){ + if($('#goods-list').hasClass('wst-go-switch')){ + $(obj).removeClass('wst-se-icon2'); + $('#goods-list').removeClass('wst-go-switch'); + }else{ + $(obj).addClass('wst-se-icon2'); + $('#goods-list').addClass('wst-go-switch'); + } + $('.j-imgAdapt').removeAttr('style'); + $('.j-imgAdapt a').removeAttr('style'); + $('.j-imgAdapt a img').removeAttr('style'); + $('#currPage').val('0'); + $('#goods-list').html(''); + goodsList(); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + goodsList(); + $('.wst-gol-adsb').css('height',$('.j-imgRec').width()+20); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + goodsList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/index.js b/hyhproject/wechat2/view/default/js/index.js new file mode 100755 index 0000000..e23b448 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/index.js @@ -0,0 +1,124 @@ +//列表 +function indexList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.currPage = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/index/pageQuery'), param,function(data){ + var json = WST.toJson(data); + if(json && json.catId){ + $('#currPage').val(json.currPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#goods-list').append(html); + }); + WST.imgAdapt('j-imgAdapt'); + } + loading = false; + $('#Load').hide(); + }); +} +//商品列表页 +function getGoodsList(goodsCatId){ + location.href = WST.U('wechat/goods/lists','catId='+goodsCatId); +} +//关注 +function forFollow(){ + $("#wst-di-weixincode").dialog("show"); +} +function closeFollow(){ + $.post(WST.U('wechat/index/closeFollow'), {},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('.wst-in-public').hide(); + $('.wst-in-header').removeClass('wst-in-change'); + $('.wst-in-search').removeClass('wst-in-change'); + } + }); +} +var currPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + //搜索 + $(window).scroll(function(){ + if( $(window).scrollTop() > 42 ){ + $('#j-header').addClass('active'); + $('#j-searchs').addClass('active'); + }else{ + $('#j-header').removeClass('active'); + $('#j-searchs').removeClass('active'); + } + }); + $('.wst-in-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + if($('.ui-slider li').hasClass("advert1")){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); + }else{ + $('.ui-slider').hide(); + } + + //文章 + if($('.wst-in-news a').hasClass("words")){ + new Swiper('.swiper-container1', { + slidesPerView: 1, + freeMode : true, + spaceBetween: 0, + autoplay : 3800, + speed:500, + direction : 'vertical', + loop : true, + autoplayDisableOnInteraction : false, + onlyExternal : true + }); + } + + var w = WST.pageWidth(); + //咨询上广告 + if($('.wst-in-activity a').hasClass("advert4")){ + }else{ + $('.wst-in-activity .advert4').hide(); + } + //中间大广告 + if($('.wst-in-adst a').hasClass("advert2")){ + }else{ + $('.wst-in-adst').hide(); + } + + //中间小广告 + if($('.wst-in-adsb a').hasClass("advert3")){ + new Swiper('.swiper-container2', { + slidesPerView: 3, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : true, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + }else{ + $('.wst-in-adsb').hide(); + } + + //刷新 + indexList(); + $(window).scroll(function(){ + if (loading) return; + if (5 + ($(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + if(currPage < 10 ){ + indexList(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/izimodal/iziModal.js b/hyhproject/wechat2/view/default/js/izimodal/iziModal.js new file mode 100755 index 0000000..a22345f --- /dev/null +++ b/hyhproject/wechat2/view/default/js/izimodal/iziModal.js @@ -0,0 +1,521 @@ +/* +* iziModal | v1.0 +* http://izimodal.dolce.ninja +* by Marcelo Dolce. +* js修改过 +*/ +(function(jQuery){ + + "use strict"; + + var PLUGIN_NAME = 'iziModal'; + + var STATES = { + CLOSING: 'closing', + CLOSED: 'closed', + OPENING: 'opening', + OPENED: 'opened', + DESTROYED: 'destroyed' + }; + + function whichAnimationEvent(){ + var t, + el = document.createElement("fakeelement"); + + var animations = { + "animation" : "animationend", + "OAnimation" : "oAnimationEnd", + "MozAnimation" : "animationend", + "WebkitAnimation": "webkitAnimationEnd" + }; + for (t in animations){ + if (el.style[t] !== undefined){ + return animations[t]; + } + } + } + var animationEvent = whichAnimationEvent(); + + var isMobile = false; + if (/Mobi/.test(navigator.userAgent)) { + isMobile = true; + } + + var iziModal = function (element, options) { + this.init(element, options); + }; + + iziModal.prototype = { + + constructor: iziModal, + + init: function (element, options) { + + var that = this; + + this.jQueryelement = jQuery(element); + this.id = this.jQueryelement.attr('id'); + this.state = STATES.CLOSED; + this.options = options; + this.timer = null; + this.headerHeight = 0; + this.jQueryheader = jQuery('<div class="'+PLUGIN_NAME+'-header"><h1 class="'+PLUGIN_NAME+'-header-title">' + options.title + '</h1><p class="'+PLUGIN_NAME+'-header-subtitle">' + options.subtitle + '</p><a href="javascript:void(0)" class="'+PLUGIN_NAME+'-button-close" data-'+PLUGIN_NAME+'-close><i class="ui-icon-return"></i></a><div id="wst-switch"><div></div>'); + this.jQueryoverlay = jQuery('<div class="'+PLUGIN_NAME+'-overlay" style="background-color:'+options.overlayColor+'"></div>'); + + if (options.subtitle === '') { + this.jQueryheader.addClass(PLUGIN_NAME+'-noSubtitle'); + } + + if (options.iframe === true) { + this.jQueryelement.html('<div class="'+PLUGIN_NAME+'-wrap"><div class="'+PLUGIN_NAME+'-content '+PLUGIN_NAME+'-content-loader"><iframe class="'+PLUGIN_NAME+'-iframe"></iframe>' + this.jQueryelement.html() + "</div></div>"); + + if (options.iframeHeight !== null) { + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css('height', options.iframeHeight); + } + + } else { + this.jQueryelement.html('<div class="'+PLUGIN_NAME+'-wrap"><div class="'+PLUGIN_NAME+'-content">' + this.jQueryelement.html() + '</div></div>'); + } + + jQuery(document.body).find('style[rel='+this.id+']').remove(); + + if(typeof options.padding !== 'undefined' || options.padding !== 0) + this.jQueryelement.find('.'+PLUGIN_NAME+'-content').css('padding', options.padding); + + + if (options.title !== "" || options.subtitle !== "") { + + if (options.headerColor !== null) { + this.jQueryelement.css('border-bottom', '3px solid ' + options.headerColor + ''); + this.jQueryheader.css('background', this.options.headerColor); + } + if (options.iconClass !== null) { + this.jQueryheader.prepend('<i class="'+PLUGIN_NAME+'-header-icon ' + options.iconClass + '"></i>'); + this.jQueryheader.find("."+PLUGIN_NAME+'-header-icon').css('color', options.iconColor); + } + this.jQueryelement.prepend(this.jQueryheader); + } + + var separators = /%|px|em|cm/, + wClear = String(options.width).split(separators), + w = String(options.width), + medida = "px"; + wClear = String(wClear).split(",")[0]; + + if(isNaN(options.width)){ + if( String(options.width).indexOf("%") != -1){ + medida = "%"; + } else { + medida = w.slice("-2"); + } + } + + this.jQueryelement.css({ + 'margin-left': -(wClear / 2) + medida, + 'max-width': parseInt(wClear) + medida + }); + + this.mediaQueries = '<style rel="' + this.id + '">@media handheld, only screen and (max-width: ' + wClear + 'px) { #' + this.jQueryelement[0].id + '{ width: 100% !important; max-width: 100% !important; margin-left: 0 !important; left: 0 !important; } }</style>'; + jQuery(document.body).append(this.mediaQueries); + + // Adjusting horizontal positioning + this.jQueryelement.addClass(PLUGIN_NAME + " " + options.theme); + + // Adjusting vertical positioning + this.jQueryelement.css('margin-top', parseInt(-(this.jQueryelement.innerHeight() / 2)) + 'px'); + + + if(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').length){ + this.jQueryelement.css('overflow', 'hidden'); + } + + // Close on overlay click + this.jQueryoverlay.click(function () { + if (that.options.overlayClose && !that.jQueryelement.hasClass(that.options.transitionOutModal)) { + that.close(); + } + }); + + // Close when button pressed + this.jQueryelement.on('click', '[data-'+PLUGIN_NAME+'-close]', function (e) { + e.preventDefault(); + that.close(); + }); + }, + + toggle: function () { + + if(this.state == STATES.OPENED){ + this.close(); + } + if(this.state == STATES.CLOSED){ + this.open(); + } + + }, + + open: function (param) { + + var that = this; + + if (param && typeof(param) === "function") { + param(that); + } + + if(this.options.iframe === true){ + + var href = null; + if(this.options.iframeURL !== null){ + href = this.options.iframeURL; + } else { + try { + href = param.target.href; + if(href !== undefined){ + href = param.target.href; + } + } catch(e) { + console.warn(e); + } + } + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').attr('src', href); + } + + this.jQueryelement.trigger(STATES.OPENING); + this.state = STATES.OPENING; + + console.info('[ '+PLUGIN_NAME+' | '+this.id+' ] Opening...'); + + if (this.options.bodyOverflow || isMobile){ + jQuery(document.body).css('overflow', 'hidden'); + } + + that.options.onOpening.call(this); + + function opened(){ + that.jQueryelement.trigger(STATES.OPENED); + that.state = STATES.OPENED; + + console.info('[ '+PLUGIN_NAME+' | '+that.id+' ] Opened.'); + + that.options.onOpened.call(this); + } + + this.jQueryoverlay.appendTo('body'); + + if (this.options.transitionInOverlay) { + this.jQueryoverlay.addClass(this.options.transitionInOverlay); + } + + if (this.options.transitionInModal !== '') { + + this.jQueryelement.addClass(this.options.transitionInModal).show(); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').one(animationEvent, function () { + + that.jQueryelement.removeClass(that.options.transitionInModal); + that.jQueryoverlay.removeClass(that.options.transitionInOverlay); + + opened(); + }); + + } else { + this.jQueryelement.show(); + opened(); + } + + if (that.options.focusInput){ + that.jQueryelement.find(':input:not(button):enabled:visible:first').focus(); // Focus on the first field + } + + (function updateTimer(){ + that.recalculateLayout(); + that.timer = setTimeout(updateTimer, 500); + })(); + + // Close when the Escape key is pressed + jQuery(document).keydown(function (e) { + if (that.options.closeOnEscape && e.keyCode === 27) { + that.close(); + } + }); + + }, + + close: function (param) { + + var that = this; + + if (param && typeof(param) === "function") { + param(that); + } + + jQuery(document).off("keydown"); + + this.state = STATES.CLOSING; + this.jQueryelement.trigger(STATES.CLOSING); + console.info('[ '+PLUGIN_NAME+' | '+this.id+' ] Closing...'); + + clearTimeout(that.timer); + + that.options.onClosing.call(this); + + function closed(){ + + if (that.options.iframe === true) { + that.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').attr('src', ""); + } + + if (that.options.bodyOverflow || isMobile){ + jQuery(document.body).css('overflow', 'initial'); + } + + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + + that.jQueryelement.trigger(STATES.CLOSED); + that.state = STATES.CLOSED; + + console.info('[ '+PLUGIN_NAME+' | '+that.id+' ] Closed.'); + + that.options.onClosed.call(this); + } + + if (this.options.transitionOutModal !== '') { + + //this.jQueryelement.removeClass(this.options.transitionInModal).addClass(this.options.transitionOutModal); + //this.jQueryoverlay.removeClass(this.options.transitionInOverlay).addClass(this.options.transitionOutOverlay); + + this.jQueryelement.attr('class', PLUGIN_NAME + " " + this.options.theme + " " + this.options.transitionOutModal); + this.jQueryoverlay.attr('class', PLUGIN_NAME + "-overlay " + this.options.transitionOutOverlay); + + this.jQueryelement.one(animationEvent, function () { + + if( that.jQueryelement.hasClass(that.options.transitionOutModal) ){ + + that.jQueryelement.removeClass(that.options.transitionOutModal).hide(); + that.jQueryoverlay.removeClass(that.options.transitionOutOverlay).remove(); + + closed(); + } + }); + } + else { + this.jQueryelement.hide(); + this.jQueryoverlay.remove(); + + closed(); + } + }, + + destroy: function () { + var e = jQuery.Event('destroy'); + + this.jQueryelement.trigger(e); + + jQuery(document).off("keydown"); + + clearTimeout(this.timer); + + if (this.options.iframe === true) { + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').remove(); + } + this.jQueryelement.html(this.jQueryelement.find('.'+PLUGIN_NAME+'-content').html()); + + jQuery(document.body).find('style[rel='+this.id+']').remove(); + + this.jQueryelement.off('click', '[data-'+PLUGIN_NAME+'-close]'); + + this.jQueryelement + .off('.'+PLUGIN_NAME) + .removeData(PLUGIN_NAME) + .attr('style', ''); + + this.jQueryoverlay.remove(); + this.jQueryelement.trigger(STATES.DESTROYED); + this.jQueryelement = null; + }, + + getState: function(){ + + console.info(this.state); + + return this.state; + }, + + setTitle: function(title){ + + if (this.options.title !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-title').html(title); + + this.options.title = title; + } + }, + + setSubtitle: function(subtitle){ + + if (this.options.subtitle !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-subtitle').html(subtitle); + + this.options.subtitle = subtitle; + } + }, + + setIconClass: function(iconClass){ + + if (this.options.iconClass !== null) { + + this.jQueryheader.find('.'+PLUGIN_NAME+'-header-icon').attr('class', PLUGIN_NAME+'-header-icon ' + iconClass); + + this.options.iconClass = iconClass; + } + }, + + setHeaderColor: function(headerColor){ + + if (this.options.headerColor !== null) { + this.jQueryelement.css('border-bottom', '3px solid ' + headerColor + ''); + this.jQueryheader.css('background', headerColor); + + this.options.headerColor = headerColor; + } + }, + + startLoading: function(){ + if( !this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').length ){ + this.jQueryelement.append('<div class="'+PLUGIN_NAME+'-loader '+this.options.transitionInOverlay+'"></div>'); + } + }, + + stopLoading: function(){ + var that = this; + this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').removeClass(this.options.transitionInOverlay).addClass(this.options.transitionOutOverlay); + this.jQueryelement.find('.'+PLUGIN_NAME+'-loader').one(animationEvent, function () { + that.jQueryelement.find('.'+PLUGIN_NAME+'-loader').removeClass(that.options.transitionOutOverlay).remove(); + }); + }, + + recalculateLayout: function(){ + + if(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').length){ + this.headerHeight = parseInt(this.jQueryelement.find('.'+PLUGIN_NAME+'-header').innerHeight()) + 2/*border bottom of modal*/; + this.jQueryelement.css('overflow', 'hidden'); + } + + var windowHeight = jQuery(window).height(), + contentHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-content')[0].scrollHeight, + modalMargin = parseInt(-((this.jQueryelement.innerHeight() + 1) / 2)) + 'px'; + + if(this.state == STATES.OPENED || this.state == STATES.OPENING){ + + if (this.options.iframe === true) { + + // Se a altura da janela é menor que o modal com iframe + if(windowHeight < (this.options.iframeHeight + this.headerHeight)){ + + jQuery(document.body).addClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css({ + 'height': parseInt(windowHeight - this.headerHeight) + 'px', + }); + + } else { + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-iframe').css({ + 'height': parseInt(this.options.iframeHeight) + 'px', + }); + } + + } else { + + if (windowHeight > (contentHeight + this.headerHeight)) { + jQuery(document.body).removeClass(PLUGIN_NAME+'-attached'); + //内部窗口高; + var screenHeight=window.innerHeight-45 + || document.documentElement.clientHeight + || document.body.clientHeight; + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').css({'height': screenHeight+'px'}); + } + + if (this.jQueryelement.innerHeight() > windowHeight || this.jQueryelement.innerHeight() < contentHeight) { + jQuery(document.body).addClass(PLUGIN_NAME+'-attached'); + + this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').css({ + 'height': parseInt(windowHeight - this.headerHeight) + 'px', + }); + } + + var scrollTop = this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').scrollTop(), + internoHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-content').innerHeight(), + externoHeight = this.jQueryelement.find('.'+PLUGIN_NAME+'-wrap').innerHeight(); + /* + if ((externoHeight + scrollTop) < (internoHeight - 50)) { + this.jQueryelement.addClass('hasScroll'); + } else { + this.jQueryelement.removeClass('hasScroll'); + } + */ + } + } + + // Corrige margin-top caso o modal sofra alterações na altura de seu conteúdo + if (this.jQueryelement.css('margin-top') != modalMargin && this.jQueryelement.css('margin-top') != "0px") { + // this.jQueryelement.css('margin-top', modalMargin); + } + } + + }; + + jQuery.fn[PLUGIN_NAME] = function (option, args) { + return this.each(function () { + var jQuerythis = jQuery(this), + data = jQuerythis.data(PLUGIN_NAME), + options = jQuery.extend({}, jQuery.fn.iziModal.defaults, jQuerythis.data(), typeof option == 'object' && option); + + if (!data && (!option || typeof option == 'object')){ + jQuerythis.data(PLUGIN_NAME, (data = new iziModal(this, options))); + } + if (typeof option == 'string' && typeof data != 'undefined'){ + data[option].apply(data, [].concat(args)); + } + else if (options.autoOpen){ // Automatically open the modal if autoOpen setted true + data.open(); + } + }); + }; + //内部窗口宽 + var screenWidth=window.innerWidth + || document.documentElement.clientWidth + || document.body.clientWidth; + jQuery.fn[PLUGIN_NAME].defaults = { + title: "", + subtitle: "", + theme: "", + headerColor: "#88A0B9", + overlayColor: "rgba(0, 0, 0, 0.4)", + iconColor: "", + iconClass: null, + width: screenWidth, + padding: 0, + iframe: false, + iframeHeight: 400, + iframeURL: null, + overlayClose: true, + closeOnEscape: true, + bodyOverflow: false, + focusInput: true, + autoOpen: false, + transitionInModal: 'transitionIn', + transitionOutModal: 'transitionOut', + transitionInOverlay: 'fadeIn', + transitionOutOverlay: 'fadeOut', + onOpening: function() {}, + onOpened: function() {}, + onClosing: function() {}, + onClosed: function() {} + }; + + jQuery.fn[PLUGIN_NAME].Constructor = iziModal; + +}).call(this, window.jQuery); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/jquery.min.js b/hyhproject/wechat2/view/default/js/jquery.min.js new file mode 100755 index 0000000..83589da --- /dev/null +++ b/hyhproject/wechat2/view/default/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r<i;r++)v.event.add(t,n,u[n][r])}o.data&&(o.data=v.extend({},o.data))}function Ot(e,t){var n;if(t.nodeType!==1)return;t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),n==="object"?(t.parentNode&&(t.outerHTML=e.outerHTML),v.support.html5Clone&&e.innerHTML&&!v.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):n==="input"&&Et.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):n==="option"?t.selected=e.defaultSelected:n==="input"||n==="textarea"?t.defaultValue=e.defaultValue:n==="script"&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(v.expando)}function Mt(e){return typeof e.getElementsByTagName!="undefined"?e.getElementsByTagName("*"):typeof e.querySelectorAll!="undefined"?e.querySelectorAll("*"):[]}function _t(e){Et.test(e.type)&&(e.defaultChecked=e.checked)}function Qt(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=Jt.length;while(i--){t=Jt[i]+n;if(t in e)return t}return r}function Gt(e,t){return e=t||e,v.css(e,"display")==="none"||!v.contains(e.ownerDocument,e)}function Yt(e,t){var n,r,i=[],s=0,o=e.length;for(;s<o;s++){n=e[s];if(!n.style)continue;i[s]=v._data(n,"olddisplay"),t?(!i[s]&&n.style.display==="none"&&(n.style.display=""),n.style.display===""&&Gt(n)&&(i[s]=v._data(n,"olddisplay",nn(n.nodeName)))):(r=Dt(n,"display"),!i[s]&&r!=="none"&&v._data(n,"olddisplay",r))}for(s=0;s<o;s++){n=e[s];if(!n.style)continue;if(!t||n.style.display==="none"||n.style.display==="")n.style.display=t?i[s]||"":"none"}return e}function Zt(e,t,n){var r=Rt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function en(e,t,n,r){var i=n===(r?"border":"content")?4:t==="width"?1:0,s=0;for(;i<4;i+=2)n==="margin"&&(s+=v.css(e,n+$t[i],!0)),r?(n==="content"&&(s-=parseFloat(Dt(e,"padding"+$t[i]))||0),n!=="margin"&&(s-=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0)):(s+=parseFloat(Dt(e,"padding"+$t[i]))||0,n!=="padding"&&(s+=parseFloat(Dt(e,"border"+$t[i]+"Width"))||0));return s}function tn(e,t,n){var r=t==="width"?e.offsetWidth:e.offsetHeight,i=!0,s=v.support.boxSizing&&v.css(e,"boxSizing")==="border-box";if(r<=0||r==null){r=Dt(e,t);if(r<0||r==null)r=e.style[t];if(Ut.test(r))return r;i=s&&(v.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+en(e,t,n||(s?"border":"content"),i)+"px"}function nn(e){if(Wt[e])return Wt[e];var t=v("<"+e+">").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write("<!doctype html><html><body>"),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u<a;u++)r=o[u],s=/^\+/.test(r),s&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[s?"unshift":"push"](n)}}function kn(e,n,r,i,s,o){s=s||n.dataTypes[0],o=o||{},o[s]=!0;var u,a=e[s],f=0,l=a?a.length:0,c=e===Sn;for(;f<l&&(c||!u);f++)u=a[f](n,r,i),typeof u=="string"&&(!c||o[u]?u=t:(n.dataTypes.unshift(u),u=kn(e,n,r,i,u,o)));return(c||!u)&&!o["*"]&&(u=kn(e,n,r,i,"*",o)),u}function Ln(e,n){var r,i,s=v.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((s[r]?e:i||(i={}))[r]=n[r]);i&&v.extend(!0,e,i)}function An(e,n,r){var i,s,o,u,a=e.contents,f=e.dataTypes,l=e.responseFields;for(s in l)s in r&&(n[l[s]]=r[s]);while(f[0]==="*")f.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(s in a)if(a[s]&&a[s].test(i)){f.unshift(s);break}if(f[0]in r)o=f[0];else{for(s in r){if(!f[0]||e.converters[s+" "+f[0]]){o=s;break}u||(u=s)}o=o||u}if(o)return o!==f[0]&&f.unshift(o),r[o]}function On(e,t){var n,r,i,s,o=e.dataTypes.slice(),u=o[0],a={},f=0;e.dataFilter&&(t=e.dataFilter(t,e.dataType));if(o[1])for(n in e.converters)a[n.toLowerCase()]=e.converters[n];for(;i=o[++f];)if(i!=="*"){if(u!=="*"&&u!==i){n=a[u+" "+i]||a["* "+i];if(!n)for(r in a){s=r.split(" ");if(s[1]===i){n=a[u+" "+s[0]]||a["* "+s[0]];if(n){n===!0?n=a[r]:a[r]!==!0&&(i=s[0],o.splice(f--,0,i));break}}}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(l){return{state:"parsererror",error:n?l:"No conversion from "+u+" to "+i}}}u=i}return{state:"success",data:t}}function Fn(){try{return new e.XMLHttpRequest}catch(t){}}function In(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function $n(){return setTimeout(function(){qn=t},0),qn=v.now()}function Jn(e,t){v.each(t,function(t,n){var r=(Vn[t]||[]).concat(Vn["*"]),i=0,s=r.length;for(;i<s;i++)if(r[i].call(e,t,n))return})}function Kn(e,t,n){var r,i=0,s=0,o=Xn.length,u=v.Deferred().always(function(){delete a.elem}),a=function(){var t=qn||$n(),n=Math.max(0,f.startTime+f.duration-t),r=n/f.duration||0,i=1-r,s=0,o=f.tweens.length;for(;s<o;s++)f.tweens[s].run(i);return u.notifyWith(e,[f,i,n]),i<1&&o?n:(u.resolveWith(e,[f]),!1)},f=u.promise({elem:e,props:v.extend({},t),opts:v.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:qn||$n(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=v.Tween(e,f.opts,t,n,f.opts.specialEasing[t]||f.opts.easing);return f.tweens.push(i),i},stop:function(t){var n=0,r=t?f.tweens.length:0;for(;n<r;n++)f.tweens[n].run(1);return t?u.resolveWith(e,[f,t]):u.rejectWith(e,[f,t]),this}}),l=f.props;Qn(l,f.opts.specialEasing);for(;i<o;i++){r=Xn[i].call(f,e,l,f.opts);if(r)return r}return Jn(f,l),v.isFunction(f.opts.start)&&f.opts.start.call(e,f),v.fx.timer(v.extend(a,{anim:f,queue:f.opts.queue,elem:e})),f.progress(f.opts.progress).done(f.opts.done,f.opts.complete).fail(f.opts.fail).always(f.opts.always)}function Qn(e,t){var n,r,i,s,o;for(n in e){r=v.camelCase(n),i=t[r],s=e[n],v.isArray(s)&&(i=s[1],s=e[n]=s[0]),n!==r&&(e[r]=s,delete e[n]),o=v.cssHooks[r];if(o&&"expand"in o){s=o.expand(s),delete e[r];for(n in s)n in e||(e[n]=s[n],t[n]=i)}else t[r]=i}}function Gn(e,t,n){var r,i,s,o,u,a,f,l,c,h=this,p=e.style,d={},m=[],g=e.nodeType&&Gt(e);n.queue||(l=v._queueHooks(e,"fx"),l.unqueued==null&&(l.unqueued=0,c=l.empty.fire,l.empty.fire=function(){l.unqueued||c()}),l.unqueued++,h.always(function(){h.always(function(){l.unqueued--,v.queue(e,"fx").length||l.empty.fire()})})),e.nodeType===1&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],v.css(e,"display")==="inline"&&v.css(e,"float")==="none"&&(!v.support.inlineBlockNeedsLayout||nn(e.nodeName)==="inline"?p.display="inline-block":p.zoom=1)),n.overflow&&(p.overflow="hidden",v.support.shrinkWrapBlocks||h.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t){s=t[r];if(Un.exec(s)){delete t[r],a=a||s==="toggle";if(s===(g?"hide":"show"))continue;m.push(r)}}o=m.length;if(o){u=v._data(e,"fxshow")||v._data(e,"fxshow",{}),"hidden"in u&&(g=u.hidden),a&&(u.hidden=!g),g?v(e).show():h.done(function(){v(e).hide()}),h.done(function(){var t;v.removeData(e,"fxshow",!0);for(t in d)v.style(e,t,d[t])});for(r=0;r<o;r++)i=m[r],f=h.createTween(i,g?u[i]:0),d[i]=u[i]||v.style(e,i),i in u||(u[i]=f.start,g&&(f.end=f.start,f.start=i==="width"||i==="height"?1:0))}}function Yn(e,t,n,r,i){return new Yn.prototype.init(e,t,n,r,i)}function Zn(e,t){var n,r={height:e},i=0;t=t?1:0;for(;i<4;i+=2-t)n=$t[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function tr(e){return v.isWindow(e)?e:e.nodeType===9?e.defaultView||e.parentWindow:!1}var n,r,i=e.document,s=e.location,o=e.navigator,u=e.jQuery,a=e.$,f=Array.prototype.push,l=Array.prototype.slice,c=Array.prototype.indexOf,h=Object.prototype.toString,p=Object.prototype.hasOwnProperty,d=String.prototype.trim,v=function(e,t){return new v.fn.init(e,t,n)},m=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,g=/\S/,y=/\s+/,b=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,w=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a<f;a++)if((e=arguments[a])!=null)for(n in e){r=u[n],i=e[n];if(u===i)continue;l&&i&&(v.isPlainObject(i)||(s=v.isArray(i)))?(s?(s=!1,o=r&&v.isArray(r)?r:[]):o=r&&v.isPlainObject(r)?r:{},u[n]=v.extend(l,o,i)):i!==t&&(u[n]=i)}return u},v.extend({noConflict:function(t){return e.$===v&&(e.$=a),t&&e.jQuery===v&&(e.jQuery=u),v},isReady:!1,readyWait:1,holdReady:function(e){e?v.readyWait++:v.ready(!0)},ready:function(e){if(e===!0?--v.readyWait:v.isReady)return;if(!i.body)return setTimeout(v.ready,1);v.isReady=!0;if(e!==!0&&--v.readyWait>0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s<o;)if(n.apply(e[s++],r)===!1)break}else if(u){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;s<o;)if(n.call(e[s],s,e[s++])===!1)break;return e},trim:d&&!d.call("\ufeff\u00a0")?function(e){return e==null?"":d.call(e)}:function(e){return e==null?"":(e+"").replace(b,"")},makeArray:function(e,t){var n,r=t||[];return e!=null&&(n=v.type(e),e.length==null||n==="string"||n==="function"||n==="regexp"||v.isWindow(e)?f.call(r,e):v.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(c)return c.call(t,e,n);r=t.length,n=n?n<0?Math.max(0,r+n):n:0;for(;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,s=0;if(typeof r=="number")for(;s<r;s++)e[i++]=n[s];else while(n[s]!==t)e[i++]=n[s++];return e.length=i,e},grep:function(e,t,n){var r,i=[],s=0,o=e.length;n=!!n;for(;s<o;s++)r=!!t(e[s],s),n!==r&&i.push(e[s]);return i},map:function(e,n,r){var i,s,o=[],u=0,a=e.length,f=e instanceof v||a!==t&&typeof a=="number"&&(a>0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u<a;u++)i=n(e[u],u,r),i!=null&&(o[o.length]=i);else for(s in e)i=n(e[s],s,r),i!=null&&(o[o.length]=i);return o.concat.apply([],o)},guid:1,proxy:function(e,n){var r,i,s;return typeof n=="string"&&(r=e[n],n=e,e=r),v.isFunction(e)?(i=l.call(arguments,2),s=function(){return e.apply(n,i.concat(l.call(arguments)))},s.guid=e.guid=e.guid||v.guid++,s):t},access:function(e,n,r,i,s,o,u){var a,f=r==null,l=0,c=e.length;if(r&&typeof r=="object"){for(l in r)v.access(e,n,l,r[l],1,o,i);s=1}else if(i!==t){a=u===t&&v.isFunction(i),f&&(a?(a=n,n=function(e,t,n){return a.call(v(e),n)}):(n.call(e,i),n=null));if(n)for(;l<c;l++)n(e[l],r,a?i.call(e[l],l,n(e[l],r)):i,u);s=1}return s?e:f?n.call(e):c?n(e[0],r):o},now:function(){return(new Date).getTime()}}),v.ready.promise=function(t){if(!r){r=v.Deferred();if(i.readyState==="complete")setTimeout(v.ready,1);else if(i.addEventListener)i.addEventListener("DOMContentLoaded",A,!1),e.addEventListener("load",v.ready,!1);else{i.attachEvent("onreadystatechange",A),e.attachEvent("onload",v.ready);var n=!1;try{n=e.frameElement==null&&i.documentElement}catch(s){}n&&n.doScroll&&function o(){if(!v.isReady){try{n.doScroll("left")}catch(e){return setTimeout(o,50)}v.ready()}}()}}return r.promise(t)},v.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){O["[object "+t+"]"]=t.toLowerCase()}),n=v(i);var M={};v.Callbacks=function(e){e=typeof e=="string"?M[e]||_(e):v.extend({},e);var n,r,i,s,o,u,a=[],f=!e.once&&[],l=function(t){n=e.memory&&t,r=!0,u=s||0,s=0,o=a.length,i=!0;for(;a&&u<o;u++)if(a[u].apply(t[0],t[1])===!1&&e.stopOnFalse){n=!1;break}i=!1,a&&(f?f.length&&l(f.shift()):n?a=[]:c.disable())},c={add:function(){if(a){var t=a.length;(function r(t){v.each(t,function(t,n){var i=v.type(n);i==="function"?(!e.unique||!c.has(n))&&a.push(n):n&&n.length&&i!=="string"&&r(n)})})(arguments),i?o=a.length:n&&(s=t,l(n))}return this},remove:function(){return a&&v.each(arguments,function(e,t){var n;while((n=v.inArray(t,a,n))>-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t<r;t++)n[t]&&v.isFunction(n[t].promise)?n[t].promise().done(o(t,f,n)).fail(s.reject).progress(o(t,a,u)):--i}return i||s.resolveWith(f,n),s.promise()}}),v.support=function(){var t,n,r,s,o,u,a,f,l,c,h,p=i.createElement("div");p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i<s;i++)delete r[t[i]];if(!(n?B:v.isEmptyObject)(r))return}}if(!n){delete u[a].data;if(!B(u[a]))return}o?v.cleanData([e],!0):v.support.deleteExpando||u!=u.window?delete u[a]:u[a]=null},_data:function(e,t,n){return v.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&v.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),v.fn.extend({data:function(e,n){var r,i,s,o,u,a=this[0],f=0,l=null;if(e===t){if(this.length){l=v.data(a);if(a.nodeType===1&&!v._data(a,"parsedAttrs")){s=a.attributes;for(u=s.length;f<u;f++)o=s[f].name,o.indexOf("data-")||(o=v.camelCase(o.substring(5)),H(a,o,l[o]));v._data(a,"parsedAttrs",!0)}}return l}return typeof e=="object"?this.each(function(){v.data(this,e)}):(r=e.split(".",2),r[1]=r[1]?"."+r[1]:"",i=r[1]+"!",v.access(this,function(n){if(n===t)return l=this.triggerHandler("getData"+i,[r[0]]),l===t&&a&&(l=v.data(a,e),l=H(a,e,l)),l===t&&r[1]?this.data(r[0]):l;r[1]=n,this.each(function(){var t=v(this);t.triggerHandler("setData"+i,r),v.data(this,e,n),t.triggerHandler("changeData"+i,r)})},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length<r?v.queue(this[0],e):n===t?this:this.each(function(){var t=v.queue(this,e,n);v._queueHooks(this,e),e==="fx"&&t[0]!=="inprogress"&&v.dequeue(this,e)})},dequeue:function(e){return this.each(function(){v.dequeue(this,e)})},delay:function(e,t){return e=v.fx?v.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,s=v.Deferred(),o=this,u=this.length,a=function(){--i||s.resolveWith(o,[o])};typeof e!="string"&&(n=e,e=t),e=e||"fx";while(u--)r=v._data(o[u],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(a));return a(),s.promise(n)}});var j,F,I,q=/[\t\r\n]/g,R=/\r/g,U=/^(?:button|input)$/i,z=/^(?:button|input|object|select|textarea)$/i,W=/^a(?:rea|)$/i,X=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,V=v.support.getSetAttribute;v.fn.extend({attr:function(e,t){return v.access(this,v.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n<r;n++){i=this[n];if(i.nodeType===1)if(!i.className&&t.length===1)i.className=e;else{s=" "+i.className+" ";for(o=0,u=t.length;o<u;o++)s.indexOf(" "+t[o]+" ")<0&&(s+=t[o]+" ");i.className=v.trim(s)}}}return this},removeClass:function(e){var n,r,i,s,o,u,a;if(v.isFunction(e))return this.each(function(t){v(this).removeClass(e.call(this,t,this.className))});if(e&&typeof e=="string"||e===t){n=(e||"").split(y);for(u=0,a=this.length;u<a;u++){i=this[u];if(i.nodeType===1&&i.className){r=(" "+i.className+" ").replace(q," ");for(s=0,o=n.length;s<o;s++)while(r.indexOf(" "+n[s]+" ")>=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n<r;n++)if(this[n].nodeType===1&&(" "+this[n].className+" ").replace(q," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a<u;a++){n=r[a];if((n.selected||a===i)&&(v.support.optDisabled?!n.disabled:n.getAttribute("disabled")===null)&&(!n.parentNode.disabled||!v.nodeName(n.parentNode,"optgroup"))){t=v(n).val();if(s)return t;o.push(t)}}return o},set:function(e,t){var n=v.makeArray(t);return v(e).find("option").each(function(){this.selected=v.inArray(v(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o<r.length;o++)i=r[o],i&&(n=v.propFix[i]||i,s=X.test(i),s||v.attr(e,i,""),e.removeAttribute(V?i:n),s&&n in e&&(e[n]=!1))}},attrHooks:{type:{set:function(e,t){if(U.test(e.nodeName)&&e.parentNode)v.error("type property can't be changed");else if(!v.support.radioValue&&t==="radio"&&v.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return j&&v.nodeName(e,"button")?j.get(e,t):t in e?e.value:null},set:function(e,t,n){if(j&&v.nodeName(e,"button"))return j.set(e,t,n);e.value=t}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,s,o,u=e.nodeType;if(!e||u===3||u===8||u===2)return;return o=u!==1||!v.isXMLDoc(e),o&&(n=v.propFix[n]||n,s=v.propHooks[n]),r!==t?s&&"set"in s&&(i=s.set(e,r,n))!==t?i:e[n]=r:s&&"get"in s&&(i=s.get(e,n))!==null?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):z.test(e.nodeName)||W.test(e.nodeName)&&e.href?0:t}}}}),F={get:function(e,n){var r,i=v.prop(e,n);return i===!0||typeof i!="boolean"&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?v.removeAttr(e,n):(r=v.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},V||(I={name:!0,id:!0,coords:!0},j=v.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(I[n]?r.value!=="":r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=i.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},v.each(["width","height"],function(e,t){v.attrHooks[t]=v.extend(v.attrHooks[t],{set:function(e,n){if(n==="")return e.setAttribute(t,"auto"),n}})}),v.attrHooks.contenteditable={get:j.get,set:function(e,t,n){t===""&&(t="false"),j.set(e,t,n)}}),v.support.hrefNormalized||v.each(["href","src","width","height"],function(e,n){v.attrHooks[n]=v.extend(v.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return r===null?t:r}})}),v.support.style||(v.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=t+""}}),v.support.optSelected||(v.propHooks.selected=v.extend(v.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),v.support.enctype||(v.propFix.enctype="encoding"),v.support.checkOn||v.each(["radio","checkbox"],function(){v.valHooks[this]={get:function(e){return e.getAttribute("value")===null?"on":e.value}}}),v.each(["radio","checkbox"],function(){v.valHooks[this]=v.extend(v.valHooks[this],{set:function(e,t){if(v.isArray(t))return e.checked=v.inArray(v(e).val(),t)>=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f<n.length;f++){l=J.exec(n[f])||[],c=l[1],h=(l[2]||"").split(".").sort(),g=v.event.special[c]||{},c=(s?g.delegateType:g.bindType)||c,g=v.event.special[c]||{},p=v.extend({type:c,origType:l[1],data:i,handler:r,guid:r.guid,selector:s,needsContext:s&&v.expr.match.needsContext.test(s),namespace:h.join(".")},d),m=a[c];if(!m){m=a[c]=[],m.delegateCount=0;if(!g.setup||g.setup.call(e,i,h,u)===!1)e.addEventListener?e.addEventListener(c,u,!1):e.attachEvent&&e.attachEvent("on"+c,u)}g.add&&(g.add.call(e,p),p.handler.guid||(p.handler.guid=r.guid)),s?m.splice(m.delegateCount++,0,p):m.push(p),v.event.global[c]=!0}e=null},global:{},remove:function(e,t,n,r,i){var s,o,u,a,f,l,c,h,p,d,m,g=v.hasData(e)&&v._data(e);if(!g||!(h=g.events))return;t=v.trim(Z(t||"")).split(" ");for(s=0;s<t.length;s++){o=J.exec(t[s])||[],u=a=o[1],f=o[2];if(!u){for(u in h)v.event.remove(e,u+t[s],n,r,!0);continue}p=v.event.special[u]||{},u=(r?p.delegateType:p.bindType)||u,d=h[u]||[],l=d.length,f=f?new RegExp("(^|\\.)"+f.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null;for(c=0;c<d.length;c++)m=d[c],(i||a===m.origType)&&(!n||n.guid===m.guid)&&(!f||f.test(m.namespace))&&(!r||r===m.selector||r==="**"&&m.selector)&&(d.splice(c--,1),m.selector&&d.delegateCount--,p.remove&&p.remove.call(e,m));d.length===0&&l!==d.length&&((!p.teardown||p.teardown.call(e,f,g.handle)===!1)&&v.removeEvent(e,u,g.handle),delete h[u])}v.isEmptyObject(h)&&(delete g.handle,v.removeData(e,"events",!0))},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,s,o){if(!s||s.nodeType!==3&&s.nodeType!==8){var u,a,f,l,c,h,p,d,m,g,y=n.type||n,b=[];if(Y.test(y+v.event.triggered))return;y.indexOf("!")>=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f<m.length&&!n.isPropagationStopped();f++)l=m[f][0],n.type=m[f][1],d=(v._data(l,"events")||{})[n.type]&&v._data(l,"handle"),d&&d.apply(l,r),d=h&&l[h],d&&v.acceptData(l)&&d.apply&&d.apply(l,r)===!1&&n.preventDefault();return n.type=y,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(s.ownerDocument,r)===!1)&&(y!=="click"||!v.nodeName(s,"a"))&&v.acceptData(s)&&h&&s[y]&&(y!=="focus"&&y!=="blur"||n.target.offsetWidth!==0)&&!v.isWindow(s)&&(c=s[h],c&&(s[h]=null),v.event.triggered=y,s[y](),v.event.triggered=t,c&&(s[h]=c)),n.result}return},dispatch:function(n){n=v.event.fix(n||e.event);var r,i,s,o,u,a,f,c,h,p,d=(v._data(this,"events")||{})[n.type]||[],m=d.delegateCount,g=l.call(arguments),y=!n.exclusive&&!n.namespace,b=v.event.special[n.type]||{},w=[];g[0]=n,n.delegateTarget=this;if(b.preDispatch&&b.preDispatch.call(this,n)===!1)return;if(m&&(!n.button||n.type!=="click"))for(s=n.target;s!=this;s=s.parentNode||this)if(s.disabled!==!0||n.type!=="click"){u={},f=[];for(r=0;r<m;r++)c=d[r],h=c.selector,u[h]===t&&(u[h]=c.needsContext?v(h,this).index(s)>=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r<w.length&&!n.isPropagationStopped();r++){a=w[r],n.currentTarget=a.elem;for(i=0;i<a.matches.length&&!n.isImmediatePropagationStopped();i++){c=a.matches[i];if(y||!n.namespace&&!c.namespace||n.namespace_re&&n.namespace_re.test(c.namespace))n.data=c.data,n.handleObj=c,o=((v.event.special[c.origType]||{}).handle||c.handler).apply(a.elem,g),o!==t&&(n.result=o,o===!1&&(n.preventDefault(),n.stopPropagation()))}}return b.postDispatch&&b.postDispatch.call(this,n),n.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return e.which==null&&(e.which=t.charCode!=null?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,s,o,u=n.button,a=n.fromElement;return e.pageX==null&&n.clientX!=null&&(r=e.target.ownerDocument||i,s=r.documentElement,o=r.body,e.pageX=n.clientX+(s&&s.scrollLeft||o&&o.scrollLeft||0)-(s&&s.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(s&&s.scrollTop||o&&o.scrollTop||0)-(s&&s.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?n.toElement:a),!e.which&&u!==t&&(e.which=u&1?1:u&2?3:u&4?2:0),e}},fix:function(e){if(e[v.expando])return e;var t,n,r=e,s=v.event.fixHooks[e.type]||{},o=s.props?this.props.concat(s.props):this.props;e=v.Event(r);for(t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||i),e.target.nodeType===3&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,r):e},special:{load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){v.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=v.extend(new v.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?v.event.trigger(i,null,t):v.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},v.event.handle=v.event.dispatch,v.removeEvent=i.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]=="undefined"&&(e[r]=null),e.detachEvent(r,n))},v.Event=function(e,t){if(!(this instanceof v.Event))return new v.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?tt:et):this.type=e,t&&v.extend(this,t),this.timeStamp=e&&e.timeStamp||v.now(),this[v.expando]=!0},v.Event.prototype={preventDefault:function(){this.isDefaultPrevented=tt;var e=this.originalEvent;if(!e)return;e.preventDefault?e.preventDefault():e.returnValue=!1},stopPropagation:function(){this.isPropagationStopped=tt;var e=this.originalEvent;if(!e)return;e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=tt,this.stopPropagation()},isDefaultPrevented:et,isPropagationStopped:et,isImmediatePropagationStopped:et},v.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){v.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,s=e.handleObj,o=s.selector;if(!i||i!==r&&!v.contains(r,i))e.type=s.origType,n=s.handler.apply(this,arguments),e.type=t;return n}}}),v.support.submitBubbles||(v.event.special.submit={setup:function(){if(v.nodeName(this,"form"))return!1;v.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=v.nodeName(n,"input")||v.nodeName(n,"button")?n.form:t;r&&!v._data(r,"_submit_attached")&&(v.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),v._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&v.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){if(v.nodeName(this,"form"))return!1;v.event.remove(this,"._submit")}}),v.support.changeBubbles||(v.event.special.change={setup:function(){if($.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")v.event.add(this,"propertychange._change",function(e){e.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),v.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),v.event.simulate("change",this,e,!0)});return!1}v.event.add(this,"beforeactivate._change",function(e){var t=e.target;$.test(t.nodeName)&&!v._data(t,"_change_attached")&&(v.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&v.event.simulate("change",this.parentNode,e,!0)}),v._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||t.type!=="radio"&&t.type!=="checkbox")return e.handleObj.handler.apply(this,arguments)},teardown:function(){return v.event.remove(this,"._change"),!$.test(this.nodeName)}}),v.support.focusinBubbles||v.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){v.event.simulate(t,e.target,v.event.fix(e),!0)};v.event.special[t]={setup:function(){n++===0&&i.addEventListener(e,r,!0)},teardown:function(){--n===0&&i.removeEventListener(e,r,!0)}}}),v.fn.extend({on:function(e,n,r,i,s){var o,u;if(typeof e=="object"){typeof n!="string"&&(r=r||n,n=t);for(u in e)this.on(u,n,r,e[u],s);return this}r==null&&i==null?(i=n,r=n=t):i==null&&(typeof n=="string"?(i=r,r=t):(i=r,r=n,n=t));if(i===!1)i=et;else if(!i)return this;return s===1&&(o=i,i=function(e){return v().off(e),o.apply(this,arguments)},i.guid=o.guid||(o.guid=v.guid++)),this.each(function(){v.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,s;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,v(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if(typeof e=="object"){for(s in e)this.off(s,n,e[s]);return this}if(n===!1||typeof n=="function")r=n,n=t;return r===!1&&(r=et),this.each(function(){v.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return v(this.context).on(e,this.selector,t,n),this},die:function(e,t){return v(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return arguments.length===1?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){v.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return v.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||v.guid++,r=0,i=function(n){var i=(v._data(this,"lastToggle"+e.guid)||0)%r;return v._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};i.guid=n;while(r<t.length)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),v.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){v.fn[t]=function(e,n){return n==null&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u<a;u++)if(s=e[u])if(!n||n(s,r,i))o.push(s),f&&t.push(u);return o}function ct(e,t,n,r,i,s){return r&&!r[d]&&(r=ct(r)),i&&!i[d]&&(i=ct(i,s)),N(function(s,o,u,a){var f,l,c,h=[],p=[],d=o.length,v=s||dt(t||"*",u.nodeType?[u]:u,[]),m=e&&(s||!t)?lt(v,h,e,u,a):v,g=n?i||(s?e:d||r)?[]:o:m;n&&n(m,g,u,a);if(r){f=lt(g,p),r(f,[],u,a),l=f.length;while(l--)if(c=f[l])g[p[l]]=!(m[p[l]]=c)}if(s){if(i||e){if(i){f=[],l=g.length;while(l--)(c=g[l])&&f.push(m[l]=c);i(null,g=[],f,a)}l=g.length;while(l--)(c=g[l])&&(f=i?T.call(s,c):h[l])>-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a<s;a++)if(n=i.relative[e[a].type])h=[at(ft(h),n)];else{n=i.filter[e[a].type].apply(null,e[a].matches);if(n[d]){r=++a;for(;r<s;r++)if(i.relative[e[r].type])break;return ct(a>1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a<r&&ht(e.slice(a,r)),r<s&&ht(e=e.slice(r)),r<s&&e.join(""))}h.push(n)}return ft(h)}function pt(e,t){var r=t.length>0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r<i;r++)nt(e,t[r],n);return n}function vt(e,t,n,r,s){var o,u,f,l,c,h=ut(e),p=h.length;if(!r&&h.length===1){u=h[0]=h[0].slice(0);if(u.length>2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;t<n;t++)if(this[t]===e)return t;return-1},N=function(e,t){return e[d]=t==null||t,e},C=function(){var e={},t=[];return N(function(n,r){return t.push(n)>i.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="<a name='"+d+"'></a><div name='"+d+"'></div>",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:st(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:st(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},f=y.compareDocumentPosition?function(e,t){return e===t?(l=!0,0):(!e.compareDocumentPosition||!t.compareDocumentPosition?e.compareDocumentPosition:e.compareDocumentPosition(t)&4)?-1:1}:function(e,t){if(e===t)return l=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],s=[],o=e.parentNode,u=t.parentNode,a=o;if(o===u)return ot(e,t);if(!o)return-1;if(!u)return 1;while(a)i.unshift(a),a=a.parentNode;a=u;while(a)s.unshift(a),a=a.parentNode;n=i.length,r=s.length;for(var f=0;f<n&&f<r;f++)if(i[f]!==s[f])return ot(i[f],s[f]);return f===n?ot(e,s[f],-1):ot(i[f],t,1)},[0,0].sort(f),h=!l,nt.uniqueSort=function(e){var t,n=[],r=1,i=0;l=h,e.sort(f);if(l){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e},nt.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},a=nt.compile=function(e,t){var n,r=[],i=[],s=A[d][e+" "];if(!s){t||(t=ut(e)),n=t.length;while(n--)s=ht(t[n]),s[d]?r.push(s):i.push(s);s=A(e,pt(i,r))}return s},g.querySelectorAll&&function(){var e,t=vt,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[":focus"],s=[":active"],u=y.matchesSelector||y.mozMatchesSelector||y.webkitMatchesSelector||y.oMatchesSelector||y.msMatchesSelector;K(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'/>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t<n;t++)if(v.contains(u[t],this))return!0});o=this.pushStack("","find",e);for(t=0,n=this.length;t<n;t++){r=o.length,v.find(e,this[t],o);if(t>0)for(i=r;i<o.length;i++)for(s=0;s<r;s++)if(o[s]===o[i]){o.splice(i--,1);break}}return o},has:function(e){var t,n=v(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(v.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1),"not",e)},filter:function(e){return this.pushStack(ft(this,e,!0),"filter",e)},is:function(e){return!!e&&(typeof e=="string"?st.test(e)?v(e,this.context).index(this[0])>=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r<i;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&n.nodeType!==11){if(o?o.index(n)>-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/<tbody/i,gt=/<|&#?\w+;/,yt=/<(?:script|style|link)/i,bt=/<(?:script|object|embed|option|style)/i,wt=new RegExp("<(?:"+ct+")[\\s/>]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Nt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X<div>","</div>"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(s){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return ut(this[0])?this.length?this.pushStack(v(v.isFunction(e)?e():e),"replaceWith",e):this:v.isFunction(e)?this.each(function(t){var n=v(this),r=n.html();n.replaceWith(e.call(this,t,r))}):(typeof e!="string"&&(e=v(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;v(this).remove(),t?v(t).before(e):v(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,s,o,u,a=0,f=e[0],l=[],c=this.length;if(!v.support.checkClone&&c>1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a<c;a++)r.call(n&&v.nodeName(this[a],"table")?Lt(this[a],"tbody"):this[a],a===u?o:v.clone(o,!0,!0))}o=s=null,l.length&&v.each(l,function(e,t){t.src?v.ajax?v.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):v.error("no ajax"):v.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Tt,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),v.buildFragment=function(e,n,r){var s,o,u,a=e[0];return n=n||i,n=!n.nodeType&&n[0]||n,n=n.ownerDocument||n,e.length===1&&typeof a=="string"&&a.length<512&&n===i&&a.charAt(0)==="<"&&!bt.test(a)&&(v.support.checkClone||!St.test(a))&&(v.support.html5Clone||!wt.test(a))&&(o=!0,s=v.fragments[a],u=s!==t),s||(s=n.createDocumentFragment(),v.clean(e,n,s,r),o&&(v.fragments[a]=u&&s)),{fragment:s,cacheable:o}},v.fragments={},v.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){v.fn[e]=function(n){var r,i=0,s=[],o=v(n),u=o.length,a=this.length===1&&this[0].parentNode;if((a==null||a&&a.nodeType===11&&a.childNodes.length===1)&&u===1)return o[t](this[0]),this;for(;i<u;i++)r=(i>0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1></$2>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]==="<table>"&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("<div>").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r<i;r++)n=e[r],Vn[n]=Vn[n]||[],Vn[n].unshift(t)},prefilter:function(e,t){t?Xn.unshift(e):Xn.push(e)}}),v.Tween=Yn,Yn.prototype={constructor:Yn,init:function(e,t,n,r,i,s){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=s||(v.cssNumber[n]?"":"px")},cur:function(){var e=Yn.propHooks[this.prop];return e&&e.get?e.get(this):Yn.propHooks._default.get(this)},run:function(e){var t,n=Yn.propHooks[this.prop];return this.options.duration?this.pos=t=v.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Yn.propHooks._default.set(this),this}},Yn.prototype.init.prototype=Yn.prototype,Yn.propHooks={_default:{get:function(e){var t;return e.elem[e.prop]==null||!!e.elem.style&&e.elem.style[e.prop]!=null?(t=v.css(e.elem,e.prop,!1,""),!t||t==="auto"?0:t):e.elem[e.prop]},set:function(e){v.fx.step[e.prop]?v.fx.step[e.prop](e):e.elem.style&&(e.elem.style[v.cssProps[e.prop]]!=null||v.cssHooks[e.prop])?v.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},Yn.propHooks.scrollTop=Yn.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},v.each(["toggle","show","hide"],function(e,t){var n=v.fn[t];v.fn[t]=function(r,i,s){return r==null||typeof r=="boolean"||!e&&v.isFunction(r)&&v.isFunction(i)?n.apply(this,arguments):this.animate(Zn(t,!0),r,i,s)}}),v.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Gt).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=v.isEmptyObject(e),s=v.speed(t,n,r),o=function(){var t=Kn(this,v.extend({},e),s);i&&t.stop(!0)};return i||s.queue===!1?this.each(o):this.queue(s.queue,o)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return typeof e!="string"&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=e!=null&&e+"queueHooks",s=v.timers,o=v._data(this);if(n)o[n]&&o[n].stop&&i(o[n]);else for(n in o)o[n]&&o[n].stop&&Wn.test(n)&&i(o[n]);for(n=s.length;n--;)s[n].elem===this&&(e==null||s[n].queue===e)&&(s[n].anim.stop(r),t=!1,s.splice(n,1));(t||!r)&&v.dequeue(this,e)})}}),v.each({slideDown:Zn("show"),slideUp:Zn("hide"),slideToggle:Zn("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){v.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),v.speed=function(e,t,n){var r=e&&typeof e=="object"?v.extend({},e):{complete:n||!n&&t||v.isFunction(e)&&e,duration:e,easing:n&&t||t&&!v.isFunction(t)&&t};r.duration=v.fx.off?0:typeof r.duration=="number"?r.duration:r.duration in v.fx.speeds?v.fx.speeds[r.duration]:v.fx.speeds._default;if(r.queue==null||r.queue===!0)r.queue="fx";return r.old=r.complete,r.complete=function(){v.isFunction(r.old)&&r.old.call(this),r.queue&&v.dequeue(this,r.queue)},r},v.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},v.timers=[],v.fx=Yn.prototype.init,v.fx.tick=function(){var e,n=v.timers,r=0;qn=v.now();for(;r<n.length;r++)e=n[r],!e()&&n[r]===e&&n.splice(r--,1);n.length||v.fx.stop(),qn=t},v.fx.timer=function(e){e()&&v.timers.push(e)&&!Rn&&(Rn=setInterval(v.fx.tick,v.fx.interval))},v.fx.interval=13,v.fx.stop=function(){clearInterval(Rn),Rn=null},v.fx.speeds={slow:600,fast:200,_default:400},v.fx.step={},v.expr&&v.expr.filters&&(v.expr.filters.animated=function(e){return v.grep(v.timers,function(t){return e===t.elem}).length});var er=/^(?:body|html)$/i;v.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){v.offset.setOffset(this,e,t)});var n,r,i,s,o,u,a,f={top:0,left:0},l=this[0],c=l&&l.ownerDocument;if(!c)return;return(r=c.body)===l?v.offset.bodyOffset(l):(n=c.documentElement,v.contains(n,l)?(typeof l.getBoundingClientRect!="undefined"&&(f=l.getBoundingClientRect()),i=tr(c),s=n.clientTop||r.clientTop||0,o=n.clientLeft||r.clientLeft||0,u=i.pageYOffset||n.scrollTop,a=i.pageXOffset||n.scrollLeft,{top:f.top+u-s,left:f.left+a-o}):f)},v.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return v.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(v.css(e,"marginTop"))||0,n+=parseFloat(v.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=v.css(e,"position");r==="static"&&(e.style.position="relative");var i=v(e),s=i.offset(),o=v.css(e,"top"),u=v.css(e,"left"),a=(r==="absolute"||r==="fixed")&&v.inArray("auto",[o,u])>-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/laytpl/laytpl.js b/hyhproject/wechat2/view/default/js/laytpl/laytpl.js new file mode 100755 index 0000000..8ed64c6 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/laytpl/laytpl.js @@ -0,0 +1,9 @@ +/** + + @Name:laytpl-v1.1 精妙的js模板引擎 + @Author:贤心 - 2014-08-16 + @Site:http://sentsin.com/layui/laytpl + @License:MIT license + */ + +;!function(){"use strict";var f,b={open:"{{",close:"}}"},c={exp:function(a){return new RegExp(a,"g")},query:function(a,c,e){var f=["#([\\s\\S])+?","([^{#}])*?"][a||0];return d((c||"")+b.open+f+b.close+(e||""))},escape:function(a){return String(a||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(a,b){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+a+"\n"+(b||"")),c+a}},d=c.exp,e=function(a){this.tpl=a};e.pt=e.prototype,e.pt.parse=function(a,e){var f=this,g=a,h=d("^"+b.open+"#",""),i=d(b.close+"$","");a=a.replace(/[\r\t\n]/g," ").replace(d(b.open+"#"),b.open+"# ").replace(d(b.close+"}"),"} "+b.close).replace(/\\/g,"\\\\").replace(/(?="|')/g,"\\").replace(c.query(),function(a){return a=a.replace(h,"").replace(i,""),'";'+a.replace(/\\/g,"")+'; view+="'}).replace(c.query(1),function(a){var c='"+(';return a.replace(/\s/g,"")===b.open+b.close?"":(a=a.replace(d(b.open+"|"+b.close),""),/^=/.test(a)&&(a=a.replace(/^=/,""),c='"+_escape_('),c+a.replace(/\\/g,"")+')+"')}),a='"use strict";var view = "'+a+'";return view;';try{return f.cache=a=new Function("d, _escape_",a),a(e,c.escape)}catch(j){return delete f.cache,c.error(j,g)}},e.pt.render=function(a,b){var e,d=this;return a?(e=d.cache?d.cache(a,c.escape):d.parse(d.tpl,a),b?(b(e),void 0):e):c.error("no data")},f=function(a){return"string"!=typeof a?c.error("Template not found"):new e(a)},f.config=function(a){a=a||{};for(var c in a)b[c]=a[c]},f.v="1.1","function"==typeof define?define(function(){return f}):"undefined"!=typeof exports?module.exports=f:window.laytpl=f}(); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/login.js b/hyhproject/wechat2/view/default/js/login.js new file mode 100755 index 0000000..c9f0cfb --- /dev/null +++ b/hyhproject/wechat2/view/default/js/login.js @@ -0,0 +1,230 @@ +jQuery.noConflict(); +function inChoice(n){ + if(n==1){ + $('#login-w').html('登录'); + }else{ + $('#login-w').html('注册新账号'); + } + WST.showHide('','#choice'); + WST.showHide(1,'#login'+n+',#return'); +} +function inReturn(){ + $('#login-w').html('登录账号'); + WST.showHide('','#login0,#login1,#return'); + WST.showHide(1,'#choice'); +} +function login(){ + var loginName = $('#loginName').val(); + var loginPwd = $('#loginPwd').val(); + var loginVerfy = $('#loginVerfy').val(); + if(loginName==''){ + WST.msg('请输入账号','info'); + return false; + } + if(loginPwd==''){ + WST.msg('请输入密码','info'); + return false; + } + if(loginVerfy==''){ + WST.msg('请输入验证码','info'); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var loginPwd = rsa.encrypt(loginPwd); + } + WST.load('登录中···'); + var param = {}; + param.loginName = loginName; + param.loginPwd = loginPwd; + param.verifyCode = loginVerfy; + $('#loginButton').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/checkLogin'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var url = json.url; + setTimeout(function(){ + if(WST.blank(url)){ + location.href = url; + }else{ + location.href = WST.U('wechat/users/index'); + } + },2000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg1"); + $('#loginButton').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +var nameType = 3; +function onTesting(obj){ + //不能输入中文 + WST.isChinese(obj,1); + var data = $(obj).val(); + var regMobile = /^0?1[3|4|5|8][0-9]\d{8}$/; + if(regMobile.test(data)){//手机 + $.post(WST.U('wechat/users/checkUserPhone'), {userPhone:data}, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + }else{ + var dia=$.dialog({ + title:'', + content:'<p style="text-align: center;">手机号已注册</p>', + button:["确认"] + }); + } + data = json = null; + }); + } +} +function register(){ + var regName = $('#regName').val(); + var regPwd = $('#regPwd').val(); + var regcoPwd = $('#regcoPwd').val(); + var regVerfy = $('#regVerfy').val(); + var phoneCode = $('#phoneCode').val(); + var param = {}; + if($('#defaults').hasClass('ui-icon-unchecked-s')){ + WST.msg('请阅读用户注册协议','info'); + return false; + } + if(regName==''){ + WST.msg('请输入账号','info'); + return false; + } + if(regName.length < 6){ + WST.msg('账号为6位以上数字或字母','info'); + return false; + } + if(regPwd==''){ + WST.msg('请输入密码','info'); + return false; + } + if(regPwd.length < 6 || regPwd.length > 16){ + WST.msg('请输入密码为6-16位字符','info'); + return false; + } + if(regcoPwd==''){ + WST.msg('确认密码不能为空','info'); + return false; + } + if(regPwd!=regcoPwd){ + WST.msg('确认密码不一致','info'); + return false; + } + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + return false; + } + param.mobileCode = phoneCode; + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var regcoPwd = rsa.encrypt(regcoPwd); + var regPwd = rsa.encrypt(regPwd); + } + WST.load('注册中···'); + param.nameType = nameType; + param.loginName = regName; + param.loginPwd = regcoPwd; + param.reUserPwd = regPwd; + $('#regButton').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/register'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var url = json.url; + setTimeout(function(){ + if(WST.blank(url)){ + location.href = url; + }else{ + location.href = WST.U('wechat/users/index'); + } + },2000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg0"); + $('#regButton').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +var time = 0; +var isSend = false; +function obtainCode(){ + var userPhone = $('#regName').val(); + if(userPhone ==''){ + WST.msg('请输入帐号为手机号码','info'); + $('#userPhone').focus(); + return false; + } + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.userPhone = userPhone; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('wechat/users/getPhoneVerifyCode'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg3"); + isSend = false; + } + data = json = null; + }); +} +//弹框 +function wholeShow(type){ + jQuery('#'+type).animate({"right": 0}, 500); +} +function wholeHide(type){ + var dataWidth = $('#'+type).css('width'); + jQuery('#'+type).animate({'right': '-'+dataWidth}, 500); +} +//协议 +function inAgree(obj){ + if($('#defaults').hasClass('wst-active')){ + $(obj).addClass('ui-icon-unchecked-s'); + $(obj).removeClass('ui-icon-success-block wst-active'); + }else{ + $(obj).removeClass('ui-icon-unchecked-s'); + $(obj).addClass('ui-icon-success-block wst-active'); + } +} +$(document).ready(function(){ + var w = WST.pageWidth(); + var h = WST.pageHeight(); + $('#protocol .content').css('overflow-y','scroll').css('height',h-61); + $("#protocol").css('right',-w); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/photoclip/hammer.js b/hyhproject/wechat2/view/default/js/photoclip/hammer.js new file mode 100755 index 0000000..5226688 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/photoclip/hammer.js @@ -0,0 +1,2463 @@ +/*! Hammer.JS - v2.0.4 - 2014-09-28 + * http://hammerjs.github.io/ + * + * Copyright (c) 2014 Jorik Tangelder; + * Licensed under the MIT license */ +(function(window, document, exportName, undefined) { + 'use strict'; + +var VENDOR_PREFIXES = ['', 'webkit', 'moz', 'MS', 'ms', 'o']; +var TEST_ELEMENT = document.createElement('div'); + +var TYPE_FUNCTION = 'function'; + +var round = Math.round; +var abs = Math.abs; +var now = Date.now; + +/** + * set a timeout with a given scope + * @param {Function} fn + * @param {Number} timeout + * @param {Object} context + * @returns {number} + */ +function setTimeoutContext(fn, timeout, context) { + return setTimeout(bindFn(fn, context), timeout); +} + +/** + * if the argument is an array, we want to execute the fn on each entry + * if it aint an array we don't want to do a thing. + * this is used by all the methods that accept a single and array argument. + * @param {*|Array} arg + * @param {String} fn + * @param {Object} [context] + * @returns {Boolean} + */ +function invokeArrayArg(arg, fn, context) { + if (Array.isArray(arg)) { + each(arg, context[fn], context); + return true; + } + return false; +} + +/** + * walk objects and arrays + * @param {Object} obj + * @param {Function} iterator + * @param {Object} context + */ +function each(obj, iterator, context) { + var i; + + if (!obj) { + return; + } + + if (obj.forEach) { + obj.forEach(iterator, context); + } else if (obj.length !== undefined) { + i = 0; + while (i < obj.length) { + iterator.call(context, obj[i], i, obj); + i++; + } + } else { + for (i in obj) { + obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); + } + } +} + +/** + * extend object. + * means that properties in dest will be overwritten by the ones in src. + * @param {Object} dest + * @param {Object} src + * @param {Boolean} [merge] + * @returns {Object} dest + */ +function extend(dest, src, merge) { + var keys = Object.keys(src); + var i = 0; + while (i < keys.length) { + if (!merge || (merge && dest[keys[i]] === undefined)) { + dest[keys[i]] = src[keys[i]]; + } + i++; + } + return dest; +} + +/** + * merge the values from src in the dest. + * means that properties that exist in dest will not be overwritten by src + * @param {Object} dest + * @param {Object} src + * @returns {Object} dest + */ +function merge(dest, src) { + return extend(dest, src, true); +} + +/** + * simple class inheritance + * @param {Function} child + * @param {Function} base + * @param {Object} [properties] + */ +function inherit(child, base, properties) { + var baseP = base.prototype, + childP; + + childP = child.prototype = Object.create(baseP); + childP.constructor = child; + childP._super = baseP; + + if (properties) { + extend(childP, properties); + } +} + +/** + * simple function bind + * @param {Function} fn + * @param {Object} context + * @returns {Function} + */ +function bindFn(fn, context) { + return function boundFn() { + return fn.apply(context, arguments); + }; +} + +/** + * let a boolean value also be a function that must return a boolean + * this first item in args will be used as the context + * @param {Boolean|Function} val + * @param {Array} [args] + * @returns {Boolean} + */ +function boolOrFn(val, args) { + if (typeof val == TYPE_FUNCTION) { + return val.apply(args ? args[0] || undefined : undefined, args); + } + return val; +} + +/** + * use the val2 when val1 is undefined + * @param {*} val1 + * @param {*} val2 + * @returns {*} + */ +function ifUndefined(val1, val2) { + return (val1 === undefined) ? val2 : val1; +} + +/** + * addEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ +function addEventListeners(target, types, handler) { + each(splitStr(types), function(type) { + target.addEventListener(type, handler, false); + }); +} + +/** + * removeEventListener with multiple events at once + * @param {EventTarget} target + * @param {String} types + * @param {Function} handler + */ +function removeEventListeners(target, types, handler) { + each(splitStr(types), function(type) { + target.removeEventListener(type, handler, false); + }); +} + +/** + * find if a node is in the given parent + * @method hasParent + * @param {HTMLElement} node + * @param {HTMLElement} parent + * @return {Boolean} found + */ +function hasParent(node, parent) { + while (node) { + if (node == parent) { + return true; + } + node = node.parentNode; + } + return false; +} + +/** + * small indexOf wrapper + * @param {String} str + * @param {String} find + * @returns {Boolean} found + */ +function inStr(str, find) { + return str.indexOf(find) > -1; +} + +/** + * split string on whitespace + * @param {String} str + * @returns {Array} words + */ +function splitStr(str) { + return str.trim().split(/\s+/g); +} + +/** + * find if a array contains the object using indexOf or a simple polyFill + * @param {Array} src + * @param {String} find + * @param {String} [findByKey] + * @return {Boolean|Number} false when not found, or the index + */ +function inArray(src, find, findByKey) { + if (src.indexOf && !findByKey) { + return src.indexOf(find); + } else { + var i = 0; + while (i < src.length) { + if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) { + return i; + } + i++; + } + return -1; + } +} + +/** + * convert array-like objects to real arrays + * @param {Object} obj + * @returns {Array} + */ +function toArray(obj) { + return Array.prototype.slice.call(obj, 0); +} + +/** + * unique array with objects based on a key (like 'id') or just by the array's value + * @param {Array} src [{id:1},{id:2},{id:1}] + * @param {String} [key] + * @param {Boolean} [sort=False] + * @returns {Array} [{id:1},{id:2}] + */ +function uniqueArray(src, key, sort) { + var results = []; + var values = []; + var i = 0; + + while (i < src.length) { + var val = key ? src[i][key] : src[i]; + if (inArray(values, val) < 0) { + results.push(src[i]); + } + values[i] = val; + i++; + } + + if (sort) { + if (!key) { + results = results.sort(); + } else { + results = results.sort(function sortUniqueArray(a, b) { + return a[key] > b[key]; + }); + } + } + + return results; +} + +/** + * get the prefixed property + * @param {Object} obj + * @param {String} property + * @returns {String|Undefined} prefixed + */ +function prefixed(obj, property) { + var prefix, prop; + var camelProp = property[0].toUpperCase() + property.slice(1); + + var i = 0; + while (i < VENDOR_PREFIXES.length) { + prefix = VENDOR_PREFIXES[i]; + prop = (prefix) ? prefix + camelProp : property; + + if (prop in obj) { + return prop; + } + i++; + } + return undefined; +} + +/** + * get a unique id + * @returns {number} uniqueId + */ +var _uniqueId = 1; +function uniqueId() { + return _uniqueId++; +} + +/** + * get the window object of an element + * @param {HTMLElement} element + * @returns {DocumentView|Window} + */ +function getWindowForElement(element) { + var doc = element.ownerDocument; + return (doc.defaultView || doc.parentWindow); +} + +var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; + +var SUPPORT_TOUCH = ('ontouchstart' in window); +var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined; +var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); + +var INPUT_TYPE_TOUCH = 'touch'; +var INPUT_TYPE_PEN = 'pen'; +var INPUT_TYPE_MOUSE = 'mouse'; +var INPUT_TYPE_KINECT = 'kinect'; + +var COMPUTE_INTERVAL = 25; + +var INPUT_START = 1; +var INPUT_MOVE = 2; +var INPUT_END = 4; +var INPUT_CANCEL = 8; + +var DIRECTION_NONE = 1; +var DIRECTION_LEFT = 2; +var DIRECTION_RIGHT = 4; +var DIRECTION_UP = 8; +var DIRECTION_DOWN = 16; + +var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; +var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; +var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; + +var PROPS_XY = ['x', 'y']; +var PROPS_CLIENT_XY = ['clientX', 'clientY']; + +/** + * create new input type manager + * @param {Manager} manager + * @param {Function} callback + * @returns {Input} + * @constructor + */ +function Input(manager, callback) { + var self = this; + this.manager = manager; + this.callback = callback; + this.element = manager.element; + this.target = manager.options.inputTarget; + + // smaller wrapper around the handler, for the scope and the enabled state of the manager, + // so when disabled the input events are completely bypassed. + this.domHandler = function(ev) { + if (boolOrFn(manager.options.enable, [manager])) { + self.handler(ev); + } + }; + + this.init(); + +} + +Input.prototype = { + /** + * should handle the inputEvent data and trigger the callback + * @virtual + */ + handler: function() { }, + + /** + * bind the events + */ + init: function() { + this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + }, + + /** + * unbind the events + */ + destroy: function() { + this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); + this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); + this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); + } +}; + +/** + * create new input type manager + * called by the Manager constructor + * @param {Hammer} manager + * @returns {Input} + */ +function createInputInstance(manager) { + var Type; + var inputClass = manager.options.inputClass; + + if (inputClass) { + Type = inputClass; + } else if (SUPPORT_POINTER_EVENTS) { + Type = PointerEventInput; + } else if (SUPPORT_ONLY_TOUCH) { + Type = TouchInput; + } else if (!SUPPORT_TOUCH) { + Type = MouseInput; + } else { + Type = TouchMouseInput; + } + return new (Type)(manager, inputHandler); +} + +/** + * handle input events + * @param {Manager} manager + * @param {String} eventType + * @param {Object} input + */ +function inputHandler(manager, eventType, input) { + var pointersLen = input.pointers.length; + var changedPointersLen = input.changedPointers.length; + var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0)); + var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0)); + + input.isFirst = !!isFirst; + input.isFinal = !!isFinal; + + if (isFirst) { + manager.session = {}; + } + + // source event is the normalized value of the domEvents + // like 'touchstart, mouseup, pointerdown' + input.eventType = eventType; + + // compute scale, rotation etc + computeInputData(manager, input); + + // emit secret event + manager.emit('hammer.input', input); + + manager.recognize(input); + manager.session.prevInput = input; +} + +/** + * extend the data with some usable properties like scale, rotate, velocity etc + * @param {Object} manager + * @param {Object} input + */ +function computeInputData(manager, input) { + var session = manager.session; + var pointers = input.pointers; + var pointersLength = pointers.length; + + // store the first input to calculate the distance and direction + if (!session.firstInput) { + session.firstInput = simpleCloneInputData(input); + } + + // to compute scale and rotation we need to store the multiple touches + if (pointersLength > 1 && !session.firstMultiple) { + session.firstMultiple = simpleCloneInputData(input); + } else if (pointersLength === 1) { + session.firstMultiple = false; + } + + var firstInput = session.firstInput; + var firstMultiple = session.firstMultiple; + var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; + + var center = input.center = getCenter(pointers); + input.timeStamp = now(); + input.deltaTime = input.timeStamp - firstInput.timeStamp; + + input.angle = getAngle(offsetCenter, center); + input.distance = getDistance(offsetCenter, center); + + computeDeltaXY(session, input); + input.offsetDirection = getDirection(input.deltaX, input.deltaY); + + input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; + input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0; + + computeIntervalInputData(session, input); + + // find the correct target + var target = manager.element; + if (hasParent(input.srcEvent.target, target)) { + target = input.srcEvent.target; + } + input.target = target; +} + +function computeDeltaXY(session, input) { + var center = input.center; + var offset = session.offsetDelta || {}; + var prevDelta = session.prevDelta || {}; + var prevInput = session.prevInput || {}; + + if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) { + prevDelta = session.prevDelta = { + x: prevInput.deltaX || 0, + y: prevInput.deltaY || 0 + }; + + offset = session.offsetDelta = { + x: center.x, + y: center.y + }; + } + + input.deltaX = prevDelta.x + (center.x - offset.x); + input.deltaY = prevDelta.y + (center.y - offset.y); +} + +/** + * velocity is calculated every x ms + * @param {Object} session + * @param {Object} input + */ +function computeIntervalInputData(session, input) { + var last = session.lastInterval || input, + deltaTime = input.timeStamp - last.timeStamp, + velocity, velocityX, velocityY, direction; + + if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) { + var deltaX = last.deltaX - input.deltaX; + var deltaY = last.deltaY - input.deltaY; + + var v = getVelocity(deltaTime, deltaX, deltaY); + velocityX = v.x; + velocityY = v.y; + velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; + direction = getDirection(deltaX, deltaY); + + session.lastInterval = input; + } else { + // use latest velocity info if it doesn't overtake a minimum period + velocity = last.velocity; + velocityX = last.velocityX; + velocityY = last.velocityY; + direction = last.direction; + } + + input.velocity = velocity; + input.velocityX = velocityX; + input.velocityY = velocityY; + input.direction = direction; +} + +/** + * create a simple clone from the input used for storage of firstInput and firstMultiple + * @param {Object} input + * @returns {Object} clonedInputData + */ +function simpleCloneInputData(input) { + // make a simple copy of the pointers because we will get a reference if we don't + // we only need clientXY for the calculations + var pointers = []; + var i = 0; + while (i < input.pointers.length) { + pointers[i] = { + clientX: round(input.pointers[i].clientX), + clientY: round(input.pointers[i].clientY) + }; + i++; + } + + return { + timeStamp: now(), + pointers: pointers, + center: getCenter(pointers), + deltaX: input.deltaX, + deltaY: input.deltaY + }; +} + +/** + * get the center of all the pointers + * @param {Array} pointers + * @return {Object} center contains `x` and `y` properties + */ +function getCenter(pointers) { + var pointersLength = pointers.length; + + // no need to loop when only one touch + if (pointersLength === 1) { + return { + x: round(pointers[0].clientX), + y: round(pointers[0].clientY) + }; + } + + var x = 0, y = 0, i = 0; + while (i < pointersLength) { + x += pointers[i].clientX; + y += pointers[i].clientY; + i++; + } + + return { + x: round(x / pointersLength), + y: round(y / pointersLength) + }; +} + +/** + * calculate the velocity between two points. unit is in px per ms. + * @param {Number} deltaTime + * @param {Number} x + * @param {Number} y + * @return {Object} velocity `x` and `y` + */ +function getVelocity(deltaTime, x, y) { + return { + x: x / deltaTime || 0, + y: y / deltaTime || 0 + }; +} + +/** + * get the direction between two points + * @param {Number} x + * @param {Number} y + * @return {Number} direction + */ +function getDirection(x, y) { + if (x === y) { + return DIRECTION_NONE; + } + + if (abs(x) >= abs(y)) { + return x > 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; + } + return y > 0 ? DIRECTION_UP : DIRECTION_DOWN; +} + +/** + * calculate the absolute distance between two points + * @param {Object} p1 {x, y} + * @param {Object} p2 {x, y} + * @param {Array} [props] containing x and y keys + * @return {Number} distance + */ +function getDistance(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + + return Math.sqrt((x * x) + (y * y)); +} + +/** + * calculate the angle between two coordinates + * @param {Object} p1 + * @param {Object} p2 + * @param {Array} [props] containing x and y keys + * @return {Number} angle + */ +function getAngle(p1, p2, props) { + if (!props) { + props = PROPS_XY; + } + var x = p2[props[0]] - p1[props[0]], + y = p2[props[1]] - p1[props[1]]; + return Math.atan2(y, x) * 180 / Math.PI; +} + +/** + * calculate the rotation degrees between two pointersets + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} rotation + */ +function getRotation(start, end) { + return getAngle(end[1], end[0], PROPS_CLIENT_XY) - getAngle(start[1], start[0], PROPS_CLIENT_XY); +} + +/** + * calculate the scale factor between two pointersets + * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out + * @param {Array} start array of pointers + * @param {Array} end array of pointers + * @return {Number} scale + */ +function getScale(start, end) { + return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); +} + +var MOUSE_INPUT_MAP = { + mousedown: INPUT_START, + mousemove: INPUT_MOVE, + mouseup: INPUT_END +}; + +var MOUSE_ELEMENT_EVENTS = 'mousedown'; +var MOUSE_WINDOW_EVENTS = 'mousemove mouseup'; + +/** + * Mouse events input + * @constructor + * @extends Input + */ +function MouseInput() { + this.evEl = MOUSE_ELEMENT_EVENTS; + this.evWin = MOUSE_WINDOW_EVENTS; + + this.allow = true; // used by Input.TouchMouse to disable mouse events + this.pressed = false; // mousedown state + + Input.apply(this, arguments); +} + +inherit(MouseInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function MEhandler(ev) { + var eventType = MOUSE_INPUT_MAP[ev.type]; + + // on start we want to have the left mouse button down + if (eventType & INPUT_START && ev.button === 0) { + this.pressed = true; + } + + if (eventType & INPUT_MOVE && ev.which !== 1) { + eventType = INPUT_END; + } + + // mouse must be down, and mouse events are allowed (see the TouchMouse input) + if (!this.pressed || !this.allow) { + return; + } + + if (eventType & INPUT_END) { + this.pressed = false; + } + + this.callback(this.manager, eventType, { + pointers: [ev], + changedPointers: [ev], + pointerType: INPUT_TYPE_MOUSE, + srcEvent: ev + }); + } +}); + +var POINTER_INPUT_MAP = { + pointerdown: INPUT_START, + pointermove: INPUT_MOVE, + pointerup: INPUT_END, + pointercancel: INPUT_CANCEL, + pointerout: INPUT_CANCEL +}; + +// in IE10 the pointer types is defined as an enum +var IE10_POINTER_TYPE_ENUM = { + 2: INPUT_TYPE_TOUCH, + 3: INPUT_TYPE_PEN, + 4: INPUT_TYPE_MOUSE, + 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816 +}; + +var POINTER_ELEMENT_EVENTS = 'pointerdown'; +var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; + +// IE10 has prefixed support, and case-sensitive +if (window.MSPointerEvent) { + POINTER_ELEMENT_EVENTS = 'MSPointerDown'; + POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel'; +} + +/** + * Pointer events input + * @constructor + * @extends Input + */ +function PointerEventInput() { + this.evEl = POINTER_ELEMENT_EVENTS; + this.evWin = POINTER_WINDOW_EVENTS; + + Input.apply(this, arguments); + + this.store = (this.manager.session.pointerEvents = []); +} + +inherit(PointerEventInput, Input, { + /** + * handle mouse events + * @param {Object} ev + */ + handler: function PEhandler(ev) { + var store = this.store; + var removePointer = false; + + var eventTypeNormalized = ev.type.toLowerCase().replace('ms', ''); + var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; + var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; + + var isTouch = (pointerType == INPUT_TYPE_TOUCH); + + // get index of the event in the store + var storeIndex = inArray(store, ev.pointerId, 'pointerId'); + + // start and mouse must be down + if (eventType & INPUT_START && (ev.button === 0 || isTouch)) { + if (storeIndex < 0) { + store.push(ev); + storeIndex = store.length - 1; + } + } else if (eventType & (INPUT_END | INPUT_CANCEL)) { + removePointer = true; + } + + // it not found, so the pointer hasn't been down (so it's probably a hover) + if (storeIndex < 0) { + return; + } + + // update the event in the store + store[storeIndex] = ev; + + this.callback(this.manager, eventType, { + pointers: store, + changedPointers: [ev], + pointerType: pointerType, + srcEvent: ev + }); + + if (removePointer) { + // remove from the store + store.splice(storeIndex, 1); + } + } +}); + +var SINGLE_TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL +}; + +var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; +var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel'; + +/** + * Touch events input + * @constructor + * @extends Input + */ +function SingleTouchInput() { + this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; + this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; + this.started = false; + + Input.apply(this, arguments); +} + +inherit(SingleTouchInput, Input, { + handler: function TEhandler(ev) { + var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; + + // should we handle the touch events? + if (type === INPUT_START) { + this.started = true; + } + + if (!this.started) { + return; + } + + var touches = normalizeSingleTouches.call(this, ev, type); + + // when done, reset the started state + if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { + this.started = false; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } +}); + +/** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ +function normalizeSingleTouches(ev, type) { + var all = toArray(ev.touches); + var changed = toArray(ev.changedTouches); + + if (type & (INPUT_END | INPUT_CANCEL)) { + all = uniqueArray(all.concat(changed), 'identifier', true); + } + + return [all, changed]; +} + +var TOUCH_INPUT_MAP = { + touchstart: INPUT_START, + touchmove: INPUT_MOVE, + touchend: INPUT_END, + touchcancel: INPUT_CANCEL +}; + +var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel'; + +/** + * Multi-user touch events input + * @constructor + * @extends Input + */ +function TouchInput() { + this.evTarget = TOUCH_TARGET_EVENTS; + this.targetIds = {}; + + Input.apply(this, arguments); +} + +inherit(TouchInput, Input, { + handler: function MTEhandler(ev) { + var type = TOUCH_INPUT_MAP[ev.type]; + var touches = getTouches.call(this, ev, type); + if (!touches) { + return; + } + + this.callback(this.manager, type, { + pointers: touches[0], + changedPointers: touches[1], + pointerType: INPUT_TYPE_TOUCH, + srcEvent: ev + }); + } +}); + +/** + * @this {TouchInput} + * @param {Object} ev + * @param {Number} type flag + * @returns {undefined|Array} [all, changed] + */ +function getTouches(ev, type) { + var allTouches = toArray(ev.touches); + var targetIds = this.targetIds; + + // when there is only one touch, the process can be simplified + if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) { + targetIds[allTouches[0].identifier] = true; + return [allTouches, allTouches]; + } + + var i, + targetTouches, + changedTouches = toArray(ev.changedTouches), + changedTargetTouches = [], + target = this.target; + + // get target touches from touches + targetTouches = allTouches.filter(function(touch) { + return hasParent(touch.target, target); + }); + + // collect touches + if (type === INPUT_START) { + i = 0; + while (i < targetTouches.length) { + targetIds[targetTouches[i].identifier] = true; + i++; + } + } + + // filter changed touches to only contain touches that exist in the collected target ids + i = 0; + while (i < changedTouches.length) { + if (targetIds[changedTouches[i].identifier]) { + changedTargetTouches.push(changedTouches[i]); + } + + // cleanup removed touches + if (type & (INPUT_END | INPUT_CANCEL)) { + delete targetIds[changedTouches[i].identifier]; + } + i++; + } + + if (!changedTargetTouches.length) { + return; + } + + return [ + // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel' + uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), + changedTargetTouches + ]; +} + +/** + * Combined touch and mouse input + * + * Touch has a higher priority then mouse, and while touching no mouse events are allowed. + * This because touch devices also emit mouse events while doing a touch. + * + * @constructor + * @extends Input + */ +function TouchMouseInput() { + Input.apply(this, arguments); + + var handler = bindFn(this.handler, this); + this.touch = new TouchInput(this.manager, handler); + this.mouse = new MouseInput(this.manager, handler); +} + +inherit(TouchMouseInput, Input, { + /** + * handle mouse and touch events + * @param {Hammer} manager + * @param {String} inputEvent + * @param {Object} inputData + */ + handler: function TMEhandler(manager, inputEvent, inputData) { + var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), + isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE); + + // when we're in a touch event, so block all upcoming mouse events + // most mobile browser also emit mouseevents, right after touchstart + if (isTouch) { + this.mouse.allow = false; + } else if (isMouse && !this.mouse.allow) { + return; + } + + // reset the allowMouse when we're done + if (inputEvent & (INPUT_END | INPUT_CANCEL)) { + this.mouse.allow = true; + } + + this.callback(manager, inputEvent, inputData); + }, + + /** + * remove the event listeners + */ + destroy: function destroy() { + this.touch.destroy(); + this.mouse.destroy(); + } +}); + +var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); +var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined; + +// magical touchAction value +var TOUCH_ACTION_COMPUTE = 'compute'; +var TOUCH_ACTION_AUTO = 'auto'; +var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented +var TOUCH_ACTION_NONE = 'none'; +var TOUCH_ACTION_PAN_X = 'pan-x'; +var TOUCH_ACTION_PAN_Y = 'pan-y'; + +/** + * Touch Action + * sets the touchAction property or uses the js alternative + * @param {Manager} manager + * @param {String} value + * @constructor + */ +function TouchAction(manager, value) { + this.manager = manager; + this.set(value); +} + +TouchAction.prototype = { + /** + * set the touchAction value on the element or enable the polyfill + * @param {String} value + */ + set: function(value) { + // find out the touch-action by the event handlers + if (value == TOUCH_ACTION_COMPUTE) { + value = this.compute(); + } + + if (NATIVE_TOUCH_ACTION) { + this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; + } + this.actions = value.toLowerCase().trim(); + }, + + /** + * just re-set the touchAction value + */ + update: function() { + this.set(this.manager.options.touchAction); + }, + + /** + * compute the value for the touchAction property based on the recognizer's settings + * @returns {String} value + */ + compute: function() { + var actions = []; + each(this.manager.recognizers, function(recognizer) { + if (boolOrFn(recognizer.options.enable, [recognizer])) { + actions = actions.concat(recognizer.getTouchAction()); + } + }); + return cleanTouchActions(actions.join(' ')); + }, + + /** + * this method is called on each input cycle and provides the preventing of the browser behavior + * @param {Object} input + */ + preventDefaults: function(input) { + // not needed with native support for the touchAction property + if (NATIVE_TOUCH_ACTION) { + return; + } + + var srcEvent = input.srcEvent; + var direction = input.offsetDirection; + + // if the touch action did prevented once this session + if (this.manager.session.prevented) { + srcEvent.preventDefault(); + return; + } + + var actions = this.actions; + var hasNone = inStr(actions, TOUCH_ACTION_NONE); + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); + + if (hasNone || + (hasPanY && direction & DIRECTION_HORIZONTAL) || + (hasPanX && direction & DIRECTION_VERTICAL)) { + return this.preventSrc(srcEvent); + } + }, + + /** + * call preventDefault to prevent the browser's default behavior (scrolling in most cases) + * @param {Object} srcEvent + */ + preventSrc: function(srcEvent) { + this.manager.session.prevented = true; + srcEvent.preventDefault(); + } +}; + +/** + * when the touchActions are collected they are not a valid value, so we need to clean things up. * + * @param {String} actions + * @returns {*} + */ +function cleanTouchActions(actions) { + // none + if (inStr(actions, TOUCH_ACTION_NONE)) { + return TOUCH_ACTION_NONE; + } + + var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); + var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); + + // pan-x and pan-y can be combined + if (hasPanX && hasPanY) { + return TOUCH_ACTION_PAN_X + ' ' + TOUCH_ACTION_PAN_Y; + } + + // pan-x OR pan-y + if (hasPanX || hasPanY) { + return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; + } + + // manipulation + if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { + return TOUCH_ACTION_MANIPULATION; + } + + return TOUCH_ACTION_AUTO; +} + +/** + * Recognizer flow explained; * + * All recognizers have the initial state of POSSIBLE when a input session starts. + * The definition of a input session is from the first input until the last input, with all it's movement in it. * + * Example session for mouse-input: mousedown -> mousemove -> mouseup + * + * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed + * which determines with state it should be. + * + * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to + * POSSIBLE to give it another change on the next cycle. + * + * Possible + * | + * +-----+---------------+ + * | | + * +-----+-----+ | + * | | | + * Failed Cancelled | + * +-------+------+ + * | | + * Recognized Began + * | + * Changed + * | + * Ended/Recognized + */ +var STATE_POSSIBLE = 1; +var STATE_BEGAN = 2; +var STATE_CHANGED = 4; +var STATE_ENDED = 8; +var STATE_RECOGNIZED = STATE_ENDED; +var STATE_CANCELLED = 16; +var STATE_FAILED = 32; + +/** + * Recognizer + * Every recognizer needs to extend from this class. + * @constructor + * @param {Object} options + */ +function Recognizer(options) { + this.id = uniqueId(); + + this.manager = null; + this.options = merge(options || {}, this.defaults); + + // default is enable true + this.options.enable = ifUndefined(this.options.enable, true); + + this.state = STATE_POSSIBLE; + + this.simultaneous = {}; + this.requireFail = []; +} + +Recognizer.prototype = { + /** + * @virtual + * @type {Object} + */ + defaults: {}, + + /** + * set options + * @param {Object} options + * @return {Recognizer} + */ + set: function(options) { + extend(this.options, options); + + // also update the touchAction, in case something changed about the directions/enabled state + this.manager && this.manager.touchAction.update(); + return this; + }, + + /** + * recognize simultaneous with an other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + recognizeWith: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) { + return this; + } + + var simultaneous = this.simultaneous; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (!simultaneous[otherRecognizer.id]) { + simultaneous[otherRecognizer.id] = otherRecognizer; + otherRecognizer.recognizeWith(this); + } + return this; + }, + + /** + * drop the simultaneous link. it doesnt remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRecognizeWith: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + delete this.simultaneous[otherRecognizer.id]; + return this; + }, + + /** + * recognizer can only run when an other is failing + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + requireFailure: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) { + return this; + } + + var requireFail = this.requireFail; + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + if (inArray(requireFail, otherRecognizer) === -1) { + requireFail.push(otherRecognizer); + otherRecognizer.requireFailure(this); + } + return this; + }, + + /** + * drop the requireFailure link. it does not remove the link on the other recognizer. + * @param {Recognizer} otherRecognizer + * @returns {Recognizer} this + */ + dropRequireFailure: function(otherRecognizer) { + if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) { + return this; + } + + otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); + var index = inArray(this.requireFail, otherRecognizer); + if (index > -1) { + this.requireFail.splice(index, 1); + } + return this; + }, + + /** + * has require failures boolean + * @returns {boolean} + */ + hasRequireFailures: function() { + return this.requireFail.length > 0; + }, + + /** + * if the recognizer can recognize simultaneous with an other recognizer + * @param {Recognizer} otherRecognizer + * @returns {Boolean} + */ + canRecognizeWith: function(otherRecognizer) { + return !!this.simultaneous[otherRecognizer.id]; + }, + + /** + * You should use `tryEmit` instead of `emit` directly to check + * that all the needed recognizers has failed before emitting. + * @param {Object} input + */ + emit: function(input) { + var self = this; + var state = this.state; + + function emit(withState) { + self.manager.emit(self.options.event + (withState ? stateStr(state) : ''), input); + } + + // 'panstart' and 'panmove' + if (state < STATE_ENDED) { + emit(true); + } + + emit(); // simple 'eventName' events + + // panend and pancancel + if (state >= STATE_ENDED) { + emit(true); + } + }, + + /** + * Check that all the require failure recognizers has failed, + * if true, it emits a gesture event, + * otherwise, setup the state to FAILED. + * @param {Object} input + */ + tryEmit: function(input) { + if (this.canEmit()) { + return this.emit(input); + } + // it's failing anyway + this.state = STATE_FAILED; + }, + + /** + * can we emit? + * @returns {boolean} + */ + canEmit: function() { + var i = 0; + while (i < this.requireFail.length) { + if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { + return false; + } + i++; + } + return true; + }, + + /** + * update the recognizer + * @param {Object} inputData + */ + recognize: function(inputData) { + // make a new copy of the inputData + // so we can change the inputData without messing up the other recognizers + var inputDataClone = extend({}, inputData); + + // is is enabled and allow recognizing? + if (!boolOrFn(this.options.enable, [this, inputDataClone])) { + this.reset(); + this.state = STATE_FAILED; + return; + } + + // reset when we've reached the end + if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { + this.state = STATE_POSSIBLE; + } + + this.state = this.process(inputDataClone); + + // the recognizer has recognized a gesture + // so trigger an event + if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { + this.tryEmit(inputDataClone); + } + }, + + /** + * return the state of the recognizer + * the actual recognizing happens in this method + * @virtual + * @param {Object} inputData + * @returns {Const} STATE + */ + process: function(inputData) { }, // jshint ignore:line + + /** + * return the preferred touch-action + * @virtual + * @returns {Array} + */ + getTouchAction: function() { }, + + /** + * called when the gesture isn't allowed to recognize + * like when another is being recognized or it is disabled + * @virtual + */ + reset: function() { } +}; + +/** + * get a usable string, used as event postfix + * @param {Const} state + * @returns {String} state + */ +function stateStr(state) { + if (state & STATE_CANCELLED) { + return 'cancel'; + } else if (state & STATE_ENDED) { + return 'end'; + } else if (state & STATE_CHANGED) { + return 'move'; + } else if (state & STATE_BEGAN) { + return 'start'; + } + return ''; +} + +/** + * direction cons to string + * @param {Const} direction + * @returns {String} + */ +function directionStr(direction) { + if (direction == DIRECTION_DOWN) { + return 'down'; + } else if (direction == DIRECTION_UP) { + return 'up'; + } else if (direction == DIRECTION_LEFT) { + return 'left'; + } else if (direction == DIRECTION_RIGHT) { + return 'right'; + } + return ''; +} + +/** + * get a recognizer by name if it is bound to a manager + * @param {Recognizer|String} otherRecognizer + * @param {Recognizer} recognizer + * @returns {Recognizer} + */ +function getRecognizerByNameIfManager(otherRecognizer, recognizer) { + var manager = recognizer.manager; + if (manager) { + return manager.get(otherRecognizer); + } + return otherRecognizer; +} + +/** + * This recognizer is just used as a base for the simple attribute recognizers. + * @constructor + * @extends Recognizer + */ +function AttrRecognizer() { + Recognizer.apply(this, arguments); +} + +inherit(AttrRecognizer, Recognizer, { + /** + * @namespace + * @memberof AttrRecognizer + */ + defaults: { + /** + * @type {Number} + * @default 1 + */ + pointers: 1 + }, + + /** + * Used to check if it the recognizer receives valid input, like input.distance > 10. + * @memberof AttrRecognizer + * @param {Object} input + * @returns {Boolean} recognized + */ + attrTest: function(input) { + var optionPointers = this.options.pointers; + return optionPointers === 0 || input.pointers.length === optionPointers; + }, + + /** + * Process the input and return the state for the recognizer + * @memberof AttrRecognizer + * @param {Object} input + * @returns {*} State + */ + process: function(input) { + var state = this.state; + var eventType = input.eventType; + + var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); + var isValid = this.attrTest(input); + + // on cancel input and we've recognized before, return STATE_CANCELLED + if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { + return state | STATE_CANCELLED; + } else if (isRecognized || isValid) { + if (eventType & INPUT_END) { + return state | STATE_ENDED; + } else if (!(state & STATE_BEGAN)) { + return STATE_BEGAN; + } + return state | STATE_CHANGED; + } + return STATE_FAILED; + } +}); + +/** + * Pan + * Recognized when the pointer is down and moved in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ +function PanRecognizer() { + AttrRecognizer.apply(this, arguments); + + this.pX = null; + this.pY = null; +} + +inherit(PanRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PanRecognizer + */ + defaults: { + event: 'pan', + threshold: 10, + pointers: 1, + direction: DIRECTION_ALL + }, + + getTouchAction: function() { + var direction = this.options.direction; + var actions = []; + if (direction & DIRECTION_HORIZONTAL) { + actions.push(TOUCH_ACTION_PAN_Y); + } + if (direction & DIRECTION_VERTICAL) { + actions.push(TOUCH_ACTION_PAN_X); + } + return actions; + }, + + directionTest: function(input) { + var options = this.options; + var hasMoved = true; + var distance = input.distance; + var direction = input.direction; + var x = input.deltaX; + var y = input.deltaY; + + // lock to axis? + if (!(direction & options.direction)) { + if (options.direction & DIRECTION_HORIZONTAL) { + direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; + hasMoved = x != this.pX; + distance = Math.abs(input.deltaX); + } else { + direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN; + hasMoved = y != this.pY; + distance = Math.abs(input.deltaY); + } + } + input.direction = direction; + return hasMoved && distance > options.threshold && direction & options.direction; + }, + + attrTest: function(input) { + return AttrRecognizer.prototype.attrTest.call(this, input) && + (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input))); + }, + + emit: function(input) { + this.pX = input.deltaX; + this.pY = input.deltaY; + + var direction = directionStr(input.direction); + if (direction) { + this.manager.emit(this.options.event + direction, input); + } + + this._super.emit.call(this, input); + } +}); + +/** + * Pinch + * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out). + * @constructor + * @extends AttrRecognizer + */ +function PinchRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(PinchRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'pinch', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function(input) { + return this._super.attrTest.call(this, input) && + (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); + }, + + emit: function(input) { + this._super.emit.call(this, input); + if (input.scale !== 1) { + var inOut = input.scale < 1 ? 'in' : 'out'; + this.manager.emit(this.options.event + inOut, input); + } + } +}); + +/** + * Press + * Recognized when the pointer is down for x ms without any movement. + * @constructor + * @extends Recognizer + */ +function PressRecognizer() { + Recognizer.apply(this, arguments); + + this._timer = null; + this._input = null; +} + +inherit(PressRecognizer, Recognizer, { + /** + * @namespace + * @memberof PressRecognizer + */ + defaults: { + event: 'press', + pointers: 1, + time: 500, // minimal time of the pointer to be pressed + threshold: 5 // a minimal movement is ok, but keep it low + }, + + getTouchAction: function() { + return [TOUCH_ACTION_AUTO]; + }, + + process: function(input) { + var options = this.options; + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTime = input.deltaTime > options.time; + + this._input = input; + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) { + this.reset(); + } else if (input.eventType & INPUT_START) { + this.reset(); + this._timer = setTimeoutContext(function() { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.time, this); + } else if (input.eventType & INPUT_END) { + return STATE_RECOGNIZED; + } + return STATE_FAILED; + }, + + reset: function() { + clearTimeout(this._timer); + }, + + emit: function(input) { + if (this.state !== STATE_RECOGNIZED) { + return; + } + + if (input && (input.eventType & INPUT_END)) { + this.manager.emit(this.options.event + 'up', input); + } else { + this._input.timeStamp = now(); + this.manager.emit(this.options.event, this._input); + } + } +}); + +/** + * Rotate + * Recognized when two or more pointer are moving in a circular motion. + * @constructor + * @extends AttrRecognizer + */ +function RotateRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(RotateRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof RotateRecognizer + */ + defaults: { + event: 'rotate', + threshold: 0, + pointers: 2 + }, + + getTouchAction: function() { + return [TOUCH_ACTION_NONE]; + }, + + attrTest: function(input) { + return this._super.attrTest.call(this, input) && + (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); + } +}); + +/** + * Swipe + * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction. + * @constructor + * @extends AttrRecognizer + */ +function SwipeRecognizer() { + AttrRecognizer.apply(this, arguments); +} + +inherit(SwipeRecognizer, AttrRecognizer, { + /** + * @namespace + * @memberof SwipeRecognizer + */ + defaults: { + event: 'swipe', + threshold: 10, + velocity: 0.65, + direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, + pointers: 1 + }, + + getTouchAction: function() { + return PanRecognizer.prototype.getTouchAction.call(this); + }, + + attrTest: function(input) { + var direction = this.options.direction; + var velocity; + + if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { + velocity = input.velocity; + } else if (direction & DIRECTION_HORIZONTAL) { + velocity = input.velocityX; + } else if (direction & DIRECTION_VERTICAL) { + velocity = input.velocityY; + } + + return this._super.attrTest.call(this, input) && + direction & input.direction && + input.distance > this.options.threshold && + abs(velocity) > this.options.velocity && input.eventType & INPUT_END; + }, + + emit: function(input) { + var direction = directionStr(input.direction); + if (direction) { + this.manager.emit(this.options.event + direction, input); + } + + this.manager.emit(this.options.event, input); + } +}); + +/** + * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur + * between the given interval and position. The delay option can be used to recognize multi-taps without firing + * a single tap. + * + * The eventData from the emitted event contains the property `tapCount`, which contains the amount of + * multi-taps being recognized. + * @constructor + * @extends Recognizer + */ +function TapRecognizer() { + Recognizer.apply(this, arguments); + + // previous time and center, + // used for tap counting + this.pTime = false; + this.pCenter = false; + + this._timer = null; + this._input = null; + this.count = 0; +} + +inherit(TapRecognizer, Recognizer, { + /** + * @namespace + * @memberof PinchRecognizer + */ + defaults: { + event: 'tap', + pointers: 1, + taps: 1, + interval: 300, // max time between the multi-tap taps + time: 250, // max time of the pointer to be down (like finger on the screen) + threshold: 2, // a minimal movement is ok, but keep it low + posThreshold: 10 // a multi-tap can be a bit off the initial position + }, + + getTouchAction: function() { + return [TOUCH_ACTION_MANIPULATION]; + }, + + process: function(input) { + var options = this.options; + + var validPointers = input.pointers.length === options.pointers; + var validMovement = input.distance < options.threshold; + var validTouchTime = input.deltaTime < options.time; + + this.reset(); + + if ((input.eventType & INPUT_START) && (this.count === 0)) { + return this.failTimeout(); + } + + // we only allow little movement + // and we've reached an end event, so a tap is possible + if (validMovement && validTouchTime && validPointers) { + if (input.eventType != INPUT_END) { + return this.failTimeout(); + } + + var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true; + var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; + + this.pTime = input.timeStamp; + this.pCenter = input.center; + + if (!validMultiTap || !validInterval) { + this.count = 1; + } else { + this.count += 1; + } + + this._input = input; + + // if tap count matches we have recognized it, + // else it has began recognizing... + var tapCount = this.count % options.taps; + if (tapCount === 0) { + // no failing requirements, immediately trigger the tap event + // or wait as long as the multitap interval to trigger + if (!this.hasRequireFailures()) { + return STATE_RECOGNIZED; + } else { + this._timer = setTimeoutContext(function() { + this.state = STATE_RECOGNIZED; + this.tryEmit(); + }, options.interval, this); + return STATE_BEGAN; + } + } + } + return STATE_FAILED; + }, + + failTimeout: function() { + this._timer = setTimeoutContext(function() { + this.state = STATE_FAILED; + }, this.options.interval, this); + return STATE_FAILED; + }, + + reset: function() { + clearTimeout(this._timer); + }, + + emit: function() { + if (this.state == STATE_RECOGNIZED ) { + this._input.tapCount = this.count; + this.manager.emit(this.options.event, this._input); + } + } +}); + +/** + * Simple way to create an manager with a default set of recognizers. + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ +function Hammer(element, options) { + options = options || {}; + options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); + return new Manager(element, options); +} + +/** + * @const {string} + */ +Hammer.VERSION = '2.0.4'; + +/** + * default settings + * @namespace + */ +Hammer.defaults = { + /** + * set if DOM events are being triggered. + * But this is slower and unused by simple implementations, so disabled by default. + * @type {Boolean} + * @default false + */ + domEvents: false, + + /** + * The value for the touchAction property/fallback. + * When set to `compute` it will magically set the correct value based on the added recognizers. + * @type {String} + * @default compute + */ + touchAction: TOUCH_ACTION_COMPUTE, + + /** + * @type {Boolean} + * @default true + */ + enable: true, + + /** + * EXPERIMENTAL FEATURE -- can be removed/changed + * Change the parent input target element. + * If Null, then it is being set the to main element. + * @type {Null|EventTarget} + * @default null + */ + inputTarget: null, + + /** + * force an input class + * @type {Null|Function} + * @default null + */ + inputClass: null, + + /** + * Default recognizer setup when calling `Hammer()` + * When creating a new Manager these will be skipped. + * @type {Array} + */ + preset: [ + // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...] + [RotateRecognizer, { enable: false }], + [PinchRecognizer, { enable: false }, ['rotate']], + [SwipeRecognizer,{ direction: DIRECTION_HORIZONTAL }], + [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ['swipe']], + [TapRecognizer], + [TapRecognizer, { event: 'doubletap', taps: 2 }, ['tap']], + [PressRecognizer] + ], + + /** + * Some CSS properties can be used to improve the working of Hammer. + * Add them to this method and they will be set when creating a new Manager. + * @namespace + */ + cssProps: { + /** + * Disables text selection to improve the dragging gesture. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userSelect: 'none', + + /** + * Disable the Windows Phone grippers when pressing an element. + * @type {String} + * @default 'none' + */ + touchSelect: 'none', + + /** + * Disables the default callout shown when you touch and hold a touch target. + * On iOS, when you touch and hold a touch target such as a link, Safari displays + * a callout containing information about the link. This property allows you to disable that callout. + * @type {String} + * @default 'none' + */ + touchCallout: 'none', + + /** + * Specifies whether zooming is enabled. Used by IE10> + * @type {String} + * @default 'none' + */ + contentZooming: 'none', + + /** + * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers. + * @type {String} + * @default 'none' + */ + userDrag: 'none', + + /** + * Overrides the highlight color shown when the user taps a link or a JavaScript + * clickable element in iOS. This property obeys the alpha value, if specified. + * @type {String} + * @default 'rgba(0,0,0,0)' + */ + tapHighlightColor: 'rgba(0,0,0,0)' + } +}; + +var STOP = 1; +var FORCED_STOP = 2; + +/** + * Manager + * @param {HTMLElement} element + * @param {Object} [options] + * @constructor + */ +function Manager(element, options) { + options = options || {}; + + this.options = merge(options, Hammer.defaults); + this.options.inputTarget = this.options.inputTarget || element; + + this.handlers = {}; + this.session = {}; + this.recognizers = []; + + this.element = element; + this.input = createInputInstance(this); + this.touchAction = new TouchAction(this, this.options.touchAction); + + toggleCssProps(this, true); + + each(options.recognizers, function(item) { + var recognizer = this.add(new (item[0])(item[1])); + item[2] && recognizer.recognizeWith(item[2]); + item[3] && recognizer.requireFailure(item[3]); + }, this); +} + +Manager.prototype = { + /** + * set options + * @param {Object} options + * @returns {Manager} + */ + set: function(options) { + extend(this.options, options); + + // Options that need a little more setup + if (options.touchAction) { + this.touchAction.update(); + } + if (options.inputTarget) { + // Clean up existing event listeners and reinitialize + this.input.destroy(); + this.input.target = options.inputTarget; + this.input.init(); + } + return this; + }, + + /** + * stop recognizing for this session. + * This session will be discarded, when a new [input]start event is fired. + * When forced, the recognizer cycle is stopped immediately. + * @param {Boolean} [force] + */ + stop: function(force) { + this.session.stopped = force ? FORCED_STOP : STOP; + }, + + /** + * run the recognizers! + * called by the inputHandler function on every movement of the pointers (touches) + * it walks through all the recognizers and tries to detect the gesture that is being made + * @param {Object} inputData + */ + recognize: function(inputData) { + var session = this.session; + if (session.stopped) { + return; + } + + // run the touch-action polyfill + this.touchAction.preventDefaults(inputData); + + var recognizer; + var recognizers = this.recognizers; + + // this holds the recognizer that is being recognized. + // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED + // if no recognizer is detecting a thing, it is set to `null` + var curRecognizer = session.curRecognizer; + + // reset when the last recognizer is recognized + // or when we're in a new session + if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) { + curRecognizer = session.curRecognizer = null; + } + + var i = 0; + while (i < recognizers.length) { + recognizer = recognizers[i]; + + // find out if we are allowed try to recognize the input for this one. + // 1. allow if the session is NOT forced stopped (see the .stop() method) + // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one + // that is being recognized. + // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer. + // this can be setup with the `recognizeWith()` method on the recognizer. + if (session.stopped !== FORCED_STOP && ( // 1 + !curRecognizer || recognizer == curRecognizer || // 2 + recognizer.canRecognizeWith(curRecognizer))) { // 3 + recognizer.recognize(inputData); + } else { + recognizer.reset(); + } + + // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the + // current active recognizer. but only if we don't already have an active recognizer + if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { + curRecognizer = session.curRecognizer = recognizer; + } + i++; + } + }, + + /** + * get a recognizer by its event name. + * @param {Recognizer|String} recognizer + * @returns {Recognizer|Null} + */ + get: function(recognizer) { + if (recognizer instanceof Recognizer) { + return recognizer; + } + + var recognizers = this.recognizers; + for (var i = 0; i < recognizers.length; i++) { + if (recognizers[i].options.event == recognizer) { + return recognizers[i]; + } + } + return null; + }, + + /** + * add a recognizer to the manager + * existing recognizers with the same event name will be removed + * @param {Recognizer} recognizer + * @returns {Recognizer|Manager} + */ + add: function(recognizer) { + if (invokeArrayArg(recognizer, 'add', this)) { + return this; + } + + // remove existing + var existing = this.get(recognizer.options.event); + if (existing) { + this.remove(existing); + } + + this.recognizers.push(recognizer); + recognizer.manager = this; + + this.touchAction.update(); + return recognizer; + }, + + /** + * remove a recognizer by name or instance + * @param {Recognizer|String} recognizer + * @returns {Manager} + */ + remove: function(recognizer) { + if (invokeArrayArg(recognizer, 'remove', this)) { + return this; + } + + var recognizers = this.recognizers; + recognizer = this.get(recognizer); + recognizers.splice(inArray(recognizers, recognizer), 1); + + this.touchAction.update(); + return this; + }, + + /** + * bind event + * @param {String} events + * @param {Function} handler + * @returns {EventEmitter} this + */ + on: function(events, handler) { + var handlers = this.handlers; + each(splitStr(events), function(event) { + handlers[event] = handlers[event] || []; + handlers[event].push(handler); + }); + return this; + }, + + /** + * unbind event, leave emit blank to remove all handlers + * @param {String} events + * @param {Function} [handler] + * @returns {EventEmitter} this + */ + off: function(events, handler) { + var handlers = this.handlers; + each(splitStr(events), function(event) { + if (!handler) { + delete handlers[event]; + } else { + handlers[event].splice(inArray(handlers[event], handler), 1); + } + }); + return this; + }, + + /** + * emit event to the listeners + * @param {String} event + * @param {Object} data + */ + emit: function(event, data) { + // we also want to trigger dom events + if (this.options.domEvents) { + triggerDomEvent(event, data); + } + + // no handlers, so skip it all + var handlers = this.handlers[event] && this.handlers[event].slice(); + if (!handlers || !handlers.length) { + return; + } + + data.type = event; + data.preventDefault = function() { + data.srcEvent.preventDefault(); + }; + + var i = 0; + while (i < handlers.length) { + handlers[i](data); + i++; + } + }, + + /** + * destroy the manager and unbinds all events + * it doesn't unbind dom events, that is the user own responsibility + */ + destroy: function() { + this.element && toggleCssProps(this, false); + + this.handlers = {}; + this.session = {}; + this.input.destroy(); + this.element = null; + } +}; + +/** + * add/remove the css properties as defined in manager.options.cssProps + * @param {Manager} manager + * @param {Boolean} add + */ +function toggleCssProps(manager, add) { + var element = manager.element; + each(manager.options.cssProps, function(value, name) { + element.style[prefixed(element.style, name)] = add ? value : ''; + }); +} + +/** + * trigger dom event + * @param {String} event + * @param {Object} data + */ +function triggerDomEvent(event, data) { + var gestureEvent = document.createEvent('Event'); + gestureEvent.initEvent(event, true, true); + gestureEvent.gesture = data; + data.target.dispatchEvent(gestureEvent); +} + +extend(Hammer, { + INPUT_START: INPUT_START, + INPUT_MOVE: INPUT_MOVE, + INPUT_END: INPUT_END, + INPUT_CANCEL: INPUT_CANCEL, + + STATE_POSSIBLE: STATE_POSSIBLE, + STATE_BEGAN: STATE_BEGAN, + STATE_CHANGED: STATE_CHANGED, + STATE_ENDED: STATE_ENDED, + STATE_RECOGNIZED: STATE_RECOGNIZED, + STATE_CANCELLED: STATE_CANCELLED, + STATE_FAILED: STATE_FAILED, + + DIRECTION_NONE: DIRECTION_NONE, + DIRECTION_LEFT: DIRECTION_LEFT, + DIRECTION_RIGHT: DIRECTION_RIGHT, + DIRECTION_UP: DIRECTION_UP, + DIRECTION_DOWN: DIRECTION_DOWN, + DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL, + DIRECTION_VERTICAL: DIRECTION_VERTICAL, + DIRECTION_ALL: DIRECTION_ALL, + + Manager: Manager, + Input: Input, + TouchAction: TouchAction, + + TouchInput: TouchInput, + MouseInput: MouseInput, + PointerEventInput: PointerEventInput, + TouchMouseInput: TouchMouseInput, + SingleTouchInput: SingleTouchInput, + + Recognizer: Recognizer, + AttrRecognizer: AttrRecognizer, + Tap: TapRecognizer, + Pan: PanRecognizer, + Swipe: SwipeRecognizer, + Pinch: PinchRecognizer, + Rotate: RotateRecognizer, + Press: PressRecognizer, + + on: addEventListeners, + off: removeEventListeners, + each: each, + merge: merge, + extend: extend, + inherit: inherit, + bindFn: bindFn, + prefixed: prefixed +}); + +if (typeof define == TYPE_FUNCTION && define.amd) { + define(function() { + return Hammer; + }); +} else if (typeof module != 'undefined' && module.exports) { + module.exports = Hammer; +} else { + window[exportName] = Hammer; +} + +})(window, document, 'Hammer'); diff --git a/hyhproject/wechat2/view/default/js/photoclip/iscroll-zoom.js b/hyhproject/wechat2/view/default/js/photoclip/iscroll-zoom.js new file mode 100755 index 0000000..26c3cc0 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/photoclip/iscroll-zoom.js @@ -0,0 +1,2197 @@ +/*! iScroll v5.1.3 ~ (c) 2008-2014 Matteo Spinelli ~ http://cubiq.org/license */ +(function (window, document, Math) { +var rAF = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function (callback) { window.setTimeout(callback, 1000 / 60); }; + +var utils = (function () { + var me = {}; + + var _elementStyle = document.createElement('div').style; + var _vendor = (function () { + var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'], + transform, + i = 0, + l = vendors.length; + + for ( ; i < l; i++ ) { + transform = vendors[i] + 'ransform'; + if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1); + } + + return false; + })(); + + function _prefixStyle (style) { + if ( _vendor === false ) return false; + if ( _vendor === '' ) return style; + return _vendor + style.charAt(0).toUpperCase() + style.substr(1); + } + + me.getTime = Date.now || function getTime () { return new Date().getTime(); }; + + me.extend = function (target, obj) { + for ( var i in obj ) { + target[i] = obj[i]; + } + }; + + me.addEvent = function (el, type, fn, capture) { + el.addEventListener(type, fn, !!capture); + }; + + me.removeEvent = function (el, type, fn, capture) { + el.removeEventListener(type, fn, !!capture); + }; + + me.prefixPointerEvent = function (pointerEvent) { + return window.MSPointerEvent ? + 'MSPointer' + pointerEvent.charAt(9).toUpperCase() + pointerEvent.substr(10): + pointerEvent; + }; + + me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) { + var distance = current - start, + speed = Math.abs(distance) / time, + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + + destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 ); + duration = speed / deceleration; + + if ( destination < lowerMargin ) { + destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if ( destination > 0 ) { + destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }; + + var _transform = _prefixStyle('transform'); + + me.extend(me, { + hasTransform: _transform !== false, + hasPerspective: _prefixStyle('perspective') in _elementStyle, + hasTouch: 'ontouchstart' in window, + hasPointer: window.PointerEvent || window.MSPointerEvent, // IE10 is prefixed + hasTransition: _prefixStyle('transition') in _elementStyle + }); + + // This should find all Android browsers lower than build 535.19 (both stock browser and webview) + me.isBadAndroid = /Android /.test(window.navigator.appVersion) && !(/Chrome\/\d/.test(window.navigator.appVersion)); + + me.extend(me.style = {}, { + transform: _transform, + transitionTimingFunction: _prefixStyle('transitionTimingFunction'), + transitionDuration: _prefixStyle('transitionDuration'), + transitionDelay: _prefixStyle('transitionDelay'), + transformOrigin: _prefixStyle('transformOrigin') + }); + + me.hasClass = function (e, c) { + var re = new RegExp("(^|\\s)" + c + "(\\s|$)"); + return re.test(e.className); + }; + + me.addClass = function (e, c) { + if ( me.hasClass(e, c) ) { + return; + } + + var newclass = e.className.split(' '); + newclass.push(c); + e.className = newclass.join(' '); + }; + + me.removeClass = function (e, c) { + if ( !me.hasClass(e, c) ) { + return; + } + + var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g'); + e.className = e.className.replace(re, ' '); + }; + + me.offset = function (el) { + var left = -el.offsetLeft, + top = -el.offsetTop; + + // jshint -W084 + while (el = el.offsetParent) { + left -= el.offsetLeft; + top -= el.offsetTop; + } + // jshint +W084 + + return { + left: left, + top: top + }; + }; + + me.preventDefaultException = function (el, exceptions) { + for ( var i in exceptions ) { + if ( exceptions[i].test(el[i]) ) { + return true; + } + } + + return false; + }; + + me.extend(me.eventType = {}, { + touchstart: 1, + touchmove: 1, + touchend: 1, + + mousedown: 2, + mousemove: 2, + mouseup: 2, + + pointerdown: 3, + pointermove: 3, + pointerup: 3, + + MSPointerDown: 3, + MSPointerMove: 3, + MSPointerUp: 3 + }); + + me.extend(me.ease = {}, { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function (k) { + return k * ( 2 - k ); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1) + fn: function (k) { + return Math.sqrt( 1 - ( --k * k ) ); + } + }, + back: { + style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)', + fn: function (k) { + var b = 4; + return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1; + } + }, + bounce: { + style: '', + fn: function (k) { + if ( ( k /= 1 ) < ( 1 / 2.75 ) ) { + return 7.5625 * k * k; + } else if ( k < ( 2 / 2.75 ) ) { + return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; + } else if ( k < ( 2.5 / 2.75 ) ) { + return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; + } else { + return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; + } + } + }, + elastic: { + style: '', + fn: function (k) { + var f = 0.22, + e = 0.4; + + if ( k === 0 ) { return 0; } + if ( k == 1 ) { return 1; } + + return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 ); + } + } + }); + + me.tap = function (e, eventName) { + var ev = document.createEvent('Event'); + ev.initEvent(eventName, true, true); + ev.pageX = e.pageX; + ev.pageY = e.pageY; + e.target.dispatchEvent(ev); + }; + + me.click = function (e) { + var target = e.target, + ev; + + if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) { + ev = document.createEvent('MouseEvents'); + ev.initMouseEvent('click', true, true, e.view, 1, + target.screenX, target.screenY, target.clientX, target.clientY, + e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, + 0, null); + + ev._constructed = true; + target.dispatchEvent(ev); + } + }; + + return me; +})(); + +function IScroll (el, options) { + this.wrapper = typeof el == 'string' ? document.querySelector(el) : el; + this.scroller = this.wrapper.children[0]; + this.scrollerStyle = this.scroller.style; // cache style for better performance + + this.options = { + + zoomMin: 1, + zoomMax: 4, zoomStart: 1, + + resizeScrollbars: true, + + mouseWheelSpeed: 20, + + snapThreshold: 0.334, + +// INSERT POINT: OPTIONS + + startX: 0, + startY: 0, + scrollY: true, + directionLockThreshold: 5, + momentum: true, + + bounce: true, + bounceTime: 600, + bounceEasing: '', + + preventDefault: true, + preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ }, + + HWCompositing: true, + useTransition: true, + useTransform: true + }; + + for ( var i in options ) { + this.options[i] = options[i]; + } + + // Normalize options + this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : ''; + + this.options.useTransition = utils.hasTransition && this.options.useTransition; + this.options.useTransform = utils.hasTransform && this.options.useTransform; + + this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough; + this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault; + + // If you want eventPassthrough I have to lock one of the axes + this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY; + this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX; + + // With eventPassthrough we also need lockDirection mechanism + this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough; + this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold; + + this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing; + + this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling; + + if ( this.options.tap === true ) { + this.options.tap = 'tap'; + } + + if ( this.options.shrinkScrollbars == 'scale' ) { + this.options.useTransition = false; + } + + this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1; + +// INSERT POINT: NORMALIZATION + + // Some defaults + this.x = 0; + this.y = 0; + this.directionX = 0; + this.directionY = 0; + this._events = {}; + + this.scale = Math.min(Math.max(this.options.zoomStart, this.options.zoomMin), this.options.zoomMax); + +// INSERT POINT: DEFAULTS + + this._init(); + this.refresh(); + + this.scrollTo(this.options.startX, this.options.startY); + this.enable(); +} + +IScroll.prototype = { + version: '5.1.3', + + _init: function () { + this._initEvents(); + + if ( this.options.zoom ) { + this._initZoom(); + } + + if ( this.options.scrollbars || this.options.indicators ) { + this._initIndicators(); + } + + if ( this.options.mouseWheel ) { + this._initWheel(); + } + + if ( this.options.snap ) { + this._initSnap(); + } + + if ( this.options.keyBindings ) { + this._initKeys(); + } + +// INSERT POINT: _init + + }, + + destroy: function () { + this._initEvents(true); + + this._execEvent('destroy'); + }, + + _transitionEnd: function (e) { + if ( e.target != this.scroller || !this.isInTransition ) { + return; + } + + this._transitionTime(); + if ( !this.resetPosition(this.options.bounceTime) ) { + this.isInTransition = false; + this._execEvent('scrollEnd'); + } + }, + + _start: function (e) { + // React to left mouse button only + if ( utils.eventType[e.type] != 1 ) { + if ( e.button !== 0 ) { + return; + } + } + + if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) { + return; + } + + if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, + pos; + + this.initiated = utils.eventType[e.type]; + this.moved = false; + this.distX = 0; + this.distY = 0; + this.directionX = 0; + this.directionY = 0; + this.directionLocked = 0; + + this._transitionTime(); + + this.startTime = utils.getTime(); + + if ( this.options.useTransition && this.isInTransition ) { + this.isInTransition = false; + pos = this.getComputedPosition(); + this._translate(Math.round(pos.x), Math.round(pos.y)); + this._execEvent('scrollEnd'); + } else if ( !this.options.useTransition && this.isAnimating ) { + this.isAnimating = false; + this._execEvent('scrollEnd'); + } + + this.startX = this.x; + this.startY = this.y; + this.absStartX = this.x; + this.absStartY = this.y; + this.pointX = point.pageX; + this.pointY = point.pageY; + + this._execEvent('beforeScrollStart'); + }, + + _move: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { // increases performance on Android? TODO: check! + e.preventDefault(); + } + + var point = e.touches ? e.touches[0] : e, + deltaX = point.pageX - this.pointX, + deltaY = point.pageY - this.pointY, + timestamp = utils.getTime(), + newX, newY, + absDistX, absDistY; + + this.pointX = point.pageX; + this.pointY = point.pageY; + + this.distX += deltaX; + this.distY += deltaY; + absDistX = Math.abs(this.distX); + absDistY = Math.abs(this.distY); + + // We need to move at least 10 pixels for the scrolling to initiate + if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) { + return; + } + + // If you are scrolling in one direction lock the other + if ( !this.directionLocked && !this.options.freeScroll ) { + if ( absDistX > absDistY + this.options.directionLockThreshold ) { + this.directionLocked = 'h'; // lock horizontally + } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) { + this.directionLocked = 'v'; // lock vertically + } else { + this.directionLocked = 'n'; // no lock + } + } + + if ( this.directionLocked == 'h' ) { + if ( this.options.eventPassthrough == 'vertical' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'horizontal' ) { + this.initiated = false; + return; + } + + deltaY = 0; + } else if ( this.directionLocked == 'v' ) { + if ( this.options.eventPassthrough == 'horizontal' ) { + e.preventDefault(); + } else if ( this.options.eventPassthrough == 'vertical' ) { + this.initiated = false; + return; + } + + deltaX = 0; + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + // Slow down if outside of the boundaries + if ( newX > 0 || newX < this.maxScrollX ) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if ( newY > 0 || newY < this.maxScrollY ) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0; + this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0; + + if ( !this.moved ) { + this._execEvent('scrollStart'); + } + + this.moved = true; + + this._translate(newX, newY); + +/* REPLACE START: _move */ + + if ( timestamp - this.startTime > 300 ) { + this.startTime = timestamp; + this.startX = this.x; + this.startY = this.y; + } + +/* REPLACE END: _move */ + + }, + + _end: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) { + e.preventDefault(); + } + + var point = e.changedTouches ? e.changedTouches[0] : e, + momentumX, + momentumY, + duration = utils.getTime() - this.startTime, + newX = Math.round(this.x), + newY = Math.round(this.y), + distanceX = Math.abs(newX - this.startX), + distanceY = Math.abs(newY - this.startY), + time = 0, + easing = ''; + + this.isInTransition = 0; + this.initiated = 0; + this.endTime = utils.getTime(); + + // reset if we are outside of the boundaries + if ( this.resetPosition(this.options.bounceTime) ) { + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + // we scrolled less than 10 pixels + if ( !this.moved ) { + if ( this.options.tap ) { + utils.tap(e, this.options.tap); + } + + if ( this.options.click ) { + utils.click(e); + } + + this._execEvent('scrollCancel'); + return; + } + + if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) { + this._execEvent('flick'); + return; + } + + // start momentum animation if needed + if ( this.options.momentum && duration < 300 ) { + momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 }; + momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = 1; + } + + + if ( this.options.snap ) { + var snap = this._nearestSnap(newX, newY); + this.currentPage = snap; + time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(newX - snap.x), 1000), + Math.min(Math.abs(newY - snap.y), 1000) + ), 300); + newX = snap.x; + newY = snap.y; + + this.directionX = 0; + this.directionY = 0; + easing = this.options.bounceEasing; + } + +// INSERT POINT: _end + + if ( newX != this.x || newY != this.y ) { + // change easing function when scroller goes out of the boundaries + if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) { + easing = utils.ease.quadratic; + } + + this.scrollTo(newX, newY, time, easing); + return; + } + + this._execEvent('scrollEnd'); + }, + + _resize: function () { + var that = this; + + clearTimeout(this.resizeTimeout); + + this.resizeTimeout = setTimeout(function () { + that.refresh(); + }, this.options.resizePolling); + }, + + resetPosition: function (time) { + var x = this.x, + y = this.y; + + time = time || 0; + + if ( !this.hasHorizontalScroll || this.x > 0 ) { + x = 0; + } else if ( this.x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( !this.hasVerticalScroll || this.y > 0 ) { + y = 0; + } else if ( this.y < this.maxScrollY ) { + y = this.maxScrollY; + } + + if ( x == this.x && y == this.y ) { + return false; + } + + this.scrollTo(x, y, time, this.options.bounceEasing); + + return true; + }, + + disable: function () { + this.enabled = false; + }, + + enable: function () { + this.enabled = true; + }, + + refresh: function () { + var rf = this.wrapper.offsetHeight; // Force reflow + + this.wrapperWidth = this.wrapper.clientWidth; + this.wrapperHeight = this.wrapper.clientHeight; + +/* REPLACE START: refresh */ + this.scrollerWidth = Math.round(this.scroller.offsetWidth * this.scale); + this.scrollerHeight = Math.round(this.scroller.offsetHeight * this.scale); + + this.maxScrollX = this.wrapperWidth - this.scrollerWidth; + this.maxScrollY = this.wrapperHeight - this.scrollerHeight; +/* REPLACE END: refresh */ + + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + + if ( !this.hasHorizontalScroll ) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if ( !this.hasVerticalScroll ) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.endTime = 0; + this.directionX = 0; + this.directionY = 0; + + this.wrapperOffset = utils.offset(this.wrapper); + + this._execEvent('refresh'); + + this.resetPosition(this.options.bounceTime); + +// INSERT POINT: _refresh + + }, + + on: function (type, fn) { + if ( !this._events[type] ) { + this._events[type] = []; + } + + this._events[type].push(fn); + }, + + off: function (type, fn) { + if ( !this._events[type] ) { + return; + } + + var index = this._events[type].indexOf(fn); + + if ( index > -1 ) { + this._events[type].splice(index, 1); + } + }, + + _execEvent: function (type) { + if ( !this._events[type] ) { + return; + } + + var i = 0, + l = this._events[type].length; + + if ( !l ) { + return; + } + + for ( ; i < l; i++ ) { + this._events[type][i].apply(this, [].slice.call(arguments, 1)); + } + }, + + scrollBy: function (x, y, time, easing) { + x = this.x + x; + y = this.y + y; + time = time || 0; + + this.scrollTo(x, y, time, easing); + }, + + scrollTo: function (x, y, time, easing) { + easing = easing || utils.ease.circular; + + this.isInTransition = this.options.useTransition && time > 0; + + if ( !time || (this.options.useTransition && easing.style) ) { + this._transitionTimingFunction(easing.style); + this._transitionTime(time); + this._translate(x, y); + } else { + this._animate(x, y, time, easing.fn); + } + }, + + scrollToElement: function (el, time, offsetX, offsetY, easing) { + el = el.nodeType ? el : this.scroller.querySelector(el); + + if ( !el ) { + return; + } + + var pos = utils.offset(el); + + pos.left -= this.wrapperOffset.left; + pos.top -= this.wrapperOffset.top; + + // if offsetX/Y are true we center the element to the screen + if ( offsetX === true ) { + offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2); + } + if ( offsetY === true ) { + offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2); + } + + pos.left -= offsetX || 0; + pos.top -= offsetY || 0; + + pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left; + pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top; + + time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time; + + this.scrollTo(pos.left, pos.top, time, easing); + }, + + _transitionTime: function (time) { + time = time || 0; + + this.scrollerStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.scrollerStyle[utils.style.transitionDuration] = '0.001s'; + } + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].transitionTime(time); + } + } + + +// INSERT POINT: _transitionTime + + }, + + _transitionTimingFunction: function (easing) { + this.scrollerStyle[utils.style.transitionTimingFunction] = easing; + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].transitionTimingFunction(easing); + } + } + + +// INSERT POINT: _transitionTimingFunction + + }, + + _translate: function (x, y) { + if ( this.options.useTransform ) { + +/* REPLACE START: _translate */ this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px) scale(' + this.scale + ') ' + this.translateZ;/* REPLACE END: _translate */ + + } else { + x = Math.round(x); + y = Math.round(y); + this.scrollerStyle.left = x + 'px'; + this.scrollerStyle.top = y + 'px'; + } + + this.x = x; + this.y = y; + + + if ( this.indicators ) { + for ( var i = this.indicators.length; i--; ) { + this.indicators[i].updatePosition(); + } + } + + +// INSERT POINT: _translate + + }, + + _initEvents: function (remove) { + var eventType = remove ? utils.removeEvent : utils.addEvent, + target = this.options.bindToWrapper ? this.wrapper : window; + + eventType(window, 'orientationchange', this); + eventType(window, 'resize', this); + + if ( this.options.click ) { + eventType(this.wrapper, 'click', this, true); + } + + if ( !this.options.disableMouse ) { + eventType(this.wrapper, 'mousedown', this); + eventType(target, 'mousemove', this); + eventType(target, 'mousecancel', this); + eventType(target, 'mouseup', this); + } + + if ( utils.hasPointer && !this.options.disablePointer ) { + eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this); + eventType(target, utils.prefixPointerEvent('pointermove'), this); + eventType(target, utils.prefixPointerEvent('pointercancel'), this); + eventType(target, utils.prefixPointerEvent('pointerup'), this); + } + + if ( utils.hasTouch && !this.options.disableTouch ) { + eventType(this.wrapper, 'touchstart', this); + eventType(target, 'touchmove', this); + eventType(target, 'touchcancel', this); + eventType(target, 'touchend', this); + } + + eventType(this.scroller, 'transitionend', this); + eventType(this.scroller, 'webkitTransitionEnd', this); + eventType(this.scroller, 'oTransitionEnd', this); + eventType(this.scroller, 'MSTransitionEnd', this); + }, + + getComputedPosition: function () { + var matrix = window.getComputedStyle(this.scroller, null), + x, y; + + if ( this.options.useTransform ) { + matrix = matrix[utils.style.transform].split(')')[0].split(', '); + x = +(matrix[12] || matrix[4]); + y = +(matrix[13] || matrix[5]); + } else { + x = +matrix.left.replace(/[^-\d.]/g, ''); + y = +matrix.top.replace(/[^-\d.]/g, ''); + } + + return { x: x, y: y }; + }, + + _initIndicators: function () { + var interactive = this.options.interactiveScrollbars, + customStyle = typeof this.options.scrollbars != 'string', + indicators = [], + indicator; + + var that = this; + + this.indicators = []; + + if ( this.options.scrollbars ) { + // Vertical scrollbar + if ( this.options.scrollY ) { + indicator = { + el: createDefaultScrollbar('v', interactive, this.options.scrollbars), + interactive: interactive, + defaultScrollbars: true, + customStyle: customStyle, + resize: this.options.resizeScrollbars, + shrink: this.options.shrinkScrollbars, + fade: this.options.fadeScrollbars, + listenX: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + // Horizontal scrollbar + if ( this.options.scrollX ) { + indicator = { + el: createDefaultScrollbar('h', interactive, this.options.scrollbars), + interactive: interactive, + defaultScrollbars: true, + customStyle: customStyle, + resize: this.options.resizeScrollbars, + shrink: this.options.shrinkScrollbars, + fade: this.options.fadeScrollbars, + listenY: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + } + + if ( this.options.indicators ) { + // TODO: check concat compatibility + indicators = indicators.concat(this.options.indicators); + } + + for ( var i = indicators.length; i--; ) { + this.indicators.push( new Indicator(this, indicators[i]) ); + } + + // TODO: check if we can use array.map (wide compatibility and performance issues) + function _indicatorsMap (fn) { + for ( var i = that.indicators.length; i--; ) { + fn.call(that.indicators[i]); + } + } + + if ( this.options.fadeScrollbars ) { + this.on('scrollEnd', function () { + _indicatorsMap(function () { + this.fade(); + }); + }); + + this.on('scrollCancel', function () { + _indicatorsMap(function () { + this.fade(); + }); + }); + + this.on('scrollStart', function () { + _indicatorsMap(function () { + this.fade(1); + }); + }); + + this.on('beforeScrollStart', function () { + _indicatorsMap(function () { + this.fade(1, true); + }); + }); + } + + + this.on('refresh', function () { + _indicatorsMap(function () { + this.refresh(); + }); + }); + + this.on('destroy', function () { + _indicatorsMap(function () { + this.destroy(); + }); + + delete this.indicators; + }); + }, + + _initZoom: function () { + this.scrollerStyle[utils.style.transformOrigin] = '0 0'; + }, + + _zoomStart: function (e) { + var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ), + c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY ); + + this.touchesDistanceStart = Math.sqrt(c1 * c1 + c2 * c2); + this.startScale = this.scale; + + this.originX = Math.abs(e.touches[0].pageX + e.touches[1].pageX) / 2 + this.wrapperOffset.left - this.x; + this.originY = Math.abs(e.touches[0].pageY + e.touches[1].pageY) / 2 + this.wrapperOffset.top - this.y; + + this._execEvent('zoomStart'); + }, + + _zoom: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { + e.preventDefault(); + } + + var c1 = Math.abs( e.touches[0].pageX - e.touches[1].pageX ), + c2 = Math.abs( e.touches[0].pageY - e.touches[1].pageY ), + distance = Math.sqrt( c1 * c1 + c2 * c2 ), + scale = 1 / this.touchesDistanceStart * distance * this.startScale, + lastScale, + x, y; + + this.scaled = true; + + if ( scale < this.options.zoomMin ) { + scale = 0.5 * this.options.zoomMin * Math.pow(2.0, scale / this.options.zoomMin); + } else if ( scale > this.options.zoomMax ) { + scale = 2.0 * this.options.zoomMax * Math.pow(0.5, this.options.zoomMax / scale); + } + + lastScale = scale / this.startScale; + x = this.originX - this.originX * lastScale + this.startX; + y = this.originY - this.originY * lastScale + this.startY; + + this.scale = scale; + + this.scrollTo(x, y, 0); + }, + + _zoomEnd: function (e) { + if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) { + return; + } + + if ( this.options.preventDefault ) { + e.preventDefault(); + } + + var newX, newY, + lastScale; + + this.isInTransition = 0; + this.initiated = 0; + + if ( this.scale > this.options.zoomMax ) { + this.scale = this.options.zoomMax; + } else if ( this.scale < this.options.zoomMin ) { + this.scale = this.options.zoomMin; + } + + // Update boundaries + this.refresh(); + + lastScale = this.scale / this.startScale; + + newX = this.originX - this.originX * lastScale + this.startX; + newY = this.originY - this.originY * lastScale + this.startY; + + if ( newX > 0 ) { + newX = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + } + + if ( newY > 0 ) { + newY = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + } + + this.scrollTo(newX, newY, this.options.bounceTime); + + this.scaled = false; + + this._execEvent('zoomEnd'); + }, + + zoom: function (scale, x, y, time) { + if ( scale < this.options.zoomMin ) { + scale = this.options.zoomMin; + } else if ( scale > this.options.zoomMax ) { + scale = this.options.zoomMax; + } + + if ( scale == this.scale ) { + return; + } + + var relScale = scale / this.scale; + + x = x === undefined ? this.wrapperWidth / 2 - this.wrapperOffset.left : x; + y = y === undefined ? this.wrapperHeight / 2 - this.wrapperOffset.top : y; + time = time === undefined ? 300 : time; + + x = x + this.wrapperOffset.left - this.x; + y = y + this.wrapperOffset.top - this.y; + + x = x - x * relScale + this.x; + y = y - y * relScale + this.y; + + this.scale = scale; + + this.refresh(); // update boundaries + + if ( x > 0 ) { + x = 0; + } else if ( x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( y > 0 ) { + y = 0; + } else if ( y < this.maxScrollY ) { + y = this.maxScrollY; + } + + this.scrollTo(x, y, time); + }, + + _wheelZoom: function (e) { + var wheelDeltaY, + deltaScale, + that = this; + + // Execute the zoomEnd event after 400ms the wheel stopped scrolling + clearTimeout(this.wheelTimeout); + this.wheelTimeout = setTimeout(function () { + that._execEvent('zoomEnd'); + }, 400); + + if ( 'deltaY' in e ) { + wheelDeltaY = -e.deltaY / Math.abs(e.deltaY); + } else if ('wheelDeltaY' in e) { + wheelDeltaY = e.wheelDeltaY / Math.abs(e.wheelDeltaY); + } else if('wheelDelta' in e) { + wheelDeltaY = e.wheelDelta / Math.abs(e.wheelDelta); + } else if ('detail' in e) { + wheelDeltaY = -e.detail / Math.abs(e.detail); + } else { + return; + } + + if (isNaN(wheelDeltaY)) wheelDeltaY = 0; + deltaScale = this.scale + wheelDeltaY * .01; + + this.zoom(deltaScale, e.pageX, e.pageY, 0); + + e.preventDefault(); + e.stopPropagation(); + }, + + _initWheel: function () { + utils.addEvent(this.wrapper, 'wheel', this); + utils.addEvent(this.wrapper, 'mousewheel', this); + utils.addEvent(this.wrapper, 'DOMMouseScroll', this); + + this.on('destroy', function () { + utils.removeEvent(this.wrapper, 'wheel', this); + utils.removeEvent(this.wrapper, 'mousewheel', this); + utils.removeEvent(this.wrapper, 'DOMMouseScroll', this); + }); + }, + + _wheel: function (e) { + if ( !this.enabled ) { + return; + } + + e.preventDefault(); + e.stopPropagation(); + + var wheelDeltaX, wheelDeltaY, + newX, newY, + that = this; + + if ( this.wheelTimeout === undefined ) { + that._execEvent('scrollStart'); + } + + // Execute the scrollEnd event after 400ms the wheel stopped scrolling + clearTimeout(this.wheelTimeout); + this.wheelTimeout = setTimeout(function () { + that._execEvent('scrollEnd'); + that.wheelTimeout = undefined; + }, 400); + + if ( 'deltaX' in e ) { + if (e.deltaMode === 1) { + wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed; + wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed; + } else { + wheelDeltaX = -e.deltaX; + wheelDeltaY = -e.deltaY; + } + } else if ( 'wheelDeltaX' in e ) { + wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed; + wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed; + } else if ( 'wheelDelta' in e ) { + wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed; + } else if ( 'detail' in e ) { + wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed; + } else { + return; + } + + wheelDeltaX *= this.options.invertWheelDirection; + wheelDeltaY *= this.options.invertWheelDirection; + + if ( !this.hasVerticalScroll ) { + wheelDeltaX = wheelDeltaY; + wheelDeltaY = 0; + } + + if ( this.options.snap ) { + newX = this.currentPage.pageX; + newY = this.currentPage.pageY; + + if ( wheelDeltaX > 0 ) { + newX--; + } else if ( wheelDeltaX < 0 ) { + newX++; + } + + if ( wheelDeltaY > 0 ) { + newY--; + } else if ( wheelDeltaY < 0 ) { + newY++; + } + + this.goToPage(newX, newY); + + return; + } + + newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0); + newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0); + + if ( newX > 0 ) { + newX = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + } + + if ( newY > 0 ) { + newY = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + } + + this.scrollTo(newX, newY, 0); + +// INSERT POINT: _wheel + }, + + _initSnap: function () { + this.currentPage = {}; + + if ( typeof this.options.snap == 'string' ) { + this.options.snap = this.scroller.querySelectorAll(this.options.snap); + } + + this.on('refresh', function () { + var i = 0, l, + m = 0, n, + cx, cy, + x = 0, y, + stepX = this.options.snapStepX || this.wrapperWidth, + stepY = this.options.snapStepY || this.wrapperHeight, + el; + + this.pages = []; + + if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) { + return; + } + + if ( this.options.snap === true ) { + cx = Math.round( stepX / 2 ); + cy = Math.round( stepY / 2 ); + + while ( x > -this.scrollerWidth ) { + this.pages[i] = []; + l = 0; + y = 0; + + while ( y > -this.scrollerHeight ) { + this.pages[i][l] = { + x: Math.max(x, this.maxScrollX), + y: Math.max(y, this.maxScrollY), + width: stepX, + height: stepY, + cx: x - cx, + cy: y - cy + }; + + y -= stepY; + l++; + } + + x -= stepX; + i++; + } + } else { + el = this.options.snap; + l = el.length; + n = -1; + + for ( ; i < l; i++ ) { + if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) { + m = 0; + n++; + } + + if ( !this.pages[m] ) { + this.pages[m] = []; + } + + x = Math.max(-el[i].offsetLeft, this.maxScrollX); + y = Math.max(-el[i].offsetTop, this.maxScrollY); + cx = x - Math.round(el[i].offsetWidth / 2); + cy = y - Math.round(el[i].offsetHeight / 2); + + this.pages[m][n] = { + x: x, + y: y, + width: el[i].offsetWidth, + height: el[i].offsetHeight, + cx: cx, + cy: cy + }; + + if ( x > this.maxScrollX ) { + m++; + } + } + } + + this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0); + + // Update snap threshold if needed + if ( this.options.snapThreshold % 1 === 0 ) { + this.snapThresholdX = this.options.snapThreshold; + this.snapThresholdY = this.options.snapThreshold; + } else { + this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold); + this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold); + } + }); + + this.on('flick', function () { + var time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(this.x - this.startX), 1000), + Math.min(Math.abs(this.y - this.startY), 1000) + ), 300); + + this.goToPage( + this.currentPage.pageX + this.directionX, + this.currentPage.pageY + this.directionY, + time + ); + }); + }, + + _nearestSnap: function (x, y) { + if ( !this.pages.length ) { + return { x: 0, y: 0, pageX: 0, pageY: 0 }; + } + + var i = 0, + l = this.pages.length, + m = 0; + + // Check if we exceeded the snap threshold + if ( Math.abs(x - this.absStartX) < this.snapThresholdX && + Math.abs(y - this.absStartY) < this.snapThresholdY ) { + return this.currentPage; + } + + if ( x > 0 ) { + x = 0; + } else if ( x < this.maxScrollX ) { + x = this.maxScrollX; + } + + if ( y > 0 ) { + y = 0; + } else if ( y < this.maxScrollY ) { + y = this.maxScrollY; + } + + for ( ; i < l; i++ ) { + if ( x >= this.pages[i][0].cx ) { + x = this.pages[i][0].x; + break; + } + } + + l = this.pages[i].length; + + for ( ; m < l; m++ ) { + if ( y >= this.pages[0][m].cy ) { + y = this.pages[0][m].y; + break; + } + } + + if ( i == this.currentPage.pageX ) { + i += this.directionX; + + if ( i < 0 ) { + i = 0; + } else if ( i >= this.pages.length ) { + i = this.pages.length - 1; + } + + x = this.pages[i][0].x; + } + + if ( m == this.currentPage.pageY ) { + m += this.directionY; + + if ( m < 0 ) { + m = 0; + } else if ( m >= this.pages[0].length ) { + m = this.pages[0].length - 1; + } + + y = this.pages[0][m].y; + } + + return { + x: x, + y: y, + pageX: i, + pageY: m + }; + }, + + goToPage: function (x, y, time, easing) { + easing = easing || this.options.bounceEasing; + + if ( x >= this.pages.length ) { + x = this.pages.length - 1; + } else if ( x < 0 ) { + x = 0; + } + + if ( y >= this.pages[x].length ) { + y = this.pages[x].length - 1; + } else if ( y < 0 ) { + y = 0; + } + + var posX = this.pages[x][y].x, + posY = this.pages[x][y].y; + + time = time === undefined ? this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(posX - this.x), 1000), + Math.min(Math.abs(posY - this.y), 1000) + ), 300) : time; + + this.currentPage = { + x: posX, + y: posY, + pageX: x, + pageY: y + }; + + this.scrollTo(posX, posY, time, easing); + }, + + next: function (time, easing) { + var x = this.currentPage.pageX, + y = this.currentPage.pageY; + + x++; + + if ( x >= this.pages.length && this.hasVerticalScroll ) { + x = 0; + y++; + } + + this.goToPage(x, y, time, easing); + }, + + prev: function (time, easing) { + var x = this.currentPage.pageX, + y = this.currentPage.pageY; + + x--; + + if ( x < 0 && this.hasVerticalScroll ) { + x = 0; + y--; + } + + this.goToPage(x, y, time, easing); + }, + + _initKeys: function (e) { + // default key bindings + var keys = { + pageUp: 33, + pageDown: 34, + end: 35, + home: 36, + left: 37, + up: 38, + right: 39, + down: 40 + }; + var i; + + // if you give me characters I give you keycode + if ( typeof this.options.keyBindings == 'object' ) { + for ( i in this.options.keyBindings ) { + if ( typeof this.options.keyBindings[i] == 'string' ) { + this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0); + } + } + } else { + this.options.keyBindings = {}; + } + + for ( i in keys ) { + this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i]; + } + + utils.addEvent(window, 'keydown', this); + + this.on('destroy', function () { + utils.removeEvent(window, 'keydown', this); + }); + }, + + _key: function (e) { + if ( !this.enabled ) { + return; + } + + var snap = this.options.snap, // we are using this alot, better to cache it + newX = snap ? this.currentPage.pageX : this.x, + newY = snap ? this.currentPage.pageY : this.y, + now = utils.getTime(), + prevTime = this.keyTime || 0, + acceleration = 0.250, + pos; + + if ( this.options.useTransition && this.isInTransition ) { + pos = this.getComputedPosition(); + + this._translate(Math.round(pos.x), Math.round(pos.y)); + this.isInTransition = false; + } + + this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0; + + switch ( e.keyCode ) { + case this.options.keyBindings.pageUp: + if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { + newX += snap ? 1 : this.wrapperWidth; + } else { + newY += snap ? 1 : this.wrapperHeight; + } + break; + case this.options.keyBindings.pageDown: + if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) { + newX -= snap ? 1 : this.wrapperWidth; + } else { + newY -= snap ? 1 : this.wrapperHeight; + } + break; + case this.options.keyBindings.end: + newX = snap ? this.pages.length-1 : this.maxScrollX; + newY = snap ? this.pages[0].length-1 : this.maxScrollY; + break; + case this.options.keyBindings.home: + newX = 0; + newY = 0; + break; + case this.options.keyBindings.left: + newX += snap ? -1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.up: + newY += snap ? 1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.right: + newX -= snap ? -1 : 5 + this.keyAcceleration>>0; + break; + case this.options.keyBindings.down: + newY -= snap ? 1 : 5 + this.keyAcceleration>>0; + break; + default: + return; + } + + if ( snap ) { + this.goToPage(newX, newY); + return; + } + + if ( newX > 0 ) { + newX = 0; + this.keyAcceleration = 0; + } else if ( newX < this.maxScrollX ) { + newX = this.maxScrollX; + this.keyAcceleration = 0; + } + + if ( newY > 0 ) { + newY = 0; + this.keyAcceleration = 0; + } else if ( newY < this.maxScrollY ) { + newY = this.maxScrollY; + this.keyAcceleration = 0; + } + + this.scrollTo(newX, newY, 0); + + this.keyTime = now; + }, + + _animate: function (destX, destY, duration, easingFn) { + var that = this, + startX = this.x, + startY = this.y, + startTime = utils.getTime(), + destTime = startTime + duration; + + function step () { + var now = utils.getTime(), + newX, newY, + easing; + + if ( now >= destTime ) { + that.isAnimating = false; + that._translate(destX, destY); + + if ( !that.resetPosition(that.options.bounceTime) ) { + that._execEvent('scrollEnd'); + } + + return; + } + + now = ( now - startTime ) / duration; + easing = easingFn(now); + newX = ( destX - startX ) * easing + startX; + newY = ( destY - startY ) * easing + startY; + that._translate(newX, newY); + + if ( that.isAnimating ) { + rAF(step); + } + } + + this.isAnimating = true; + step(); + }, + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + + if ( this.options.zoom && e.touches && e.touches.length > 1 ) { + this._zoomStart(e); + } + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + if ( this.options.zoom && e.touches && e.touches[1] ) { + this._zoom(e); + return; + } + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + if ( this.scaled ) { + this._zoomEnd(e); + return; + } + this._end(e); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'transitionend': + case 'webkitTransitionEnd': + case 'oTransitionEnd': + case 'MSTransitionEnd': + this._transitionEnd(e); + break; + case 'wheel': + case 'DOMMouseScroll': + case 'mousewheel': + if ( this.options.wheelAction == 'zoom' ) { + this._wheelZoom(e); + return; + } + this._wheel(e); + break; + case 'keydown': + this._key(e); + break; + } + } + +}; +function createDefaultScrollbar (direction, interactive, type) { + var scrollbar = document.createElement('div'), + indicator = document.createElement('div'); + + if ( type === true ) { + scrollbar.style.cssText = 'position:absolute;z-index:9999'; + indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px'; + } + + indicator.className = 'iScrollIndicator'; + + if ( direction == 'h' ) { + if ( type === true ) { + scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0'; + indicator.style.height = '100%'; + } + scrollbar.className = 'iScrollHorizontalScrollbar'; + } else { + if ( type === true ) { + scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px'; + indicator.style.width = '100%'; + } + scrollbar.className = 'iScrollVerticalScrollbar'; + } + + scrollbar.style.cssText += ';overflow:hidden'; + + if ( !interactive ) { + scrollbar.style.pointerEvents = 'none'; + } + + scrollbar.appendChild(indicator); + + return scrollbar; +} + +function Indicator (scroller, options) { + this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; + this.wrapperStyle = this.wrapper.style; + this.indicator = this.wrapper.children[0]; + this.indicatorStyle = this.indicator.style; + this.scroller = scroller; + + this.options = { + listenX: true, + listenY: true, + interactive: false, + resize: true, + defaultScrollbars: false, + shrink: false, + fade: false, + speedRatioX: 0, + speedRatioY: 0 + }; + + for ( var i in options ) { + this.options[i] = options[i]; + } + + this.sizeRatioX = 1; + this.sizeRatioY = 1; + this.maxPosX = 0; + this.maxPosY = 0; + + if ( this.options.interactive ) { + if ( !this.options.disableTouch ) { + utils.addEvent(this.indicator, 'touchstart', this); + utils.addEvent(window, 'touchend', this); + } + if ( !this.options.disablePointer ) { + utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); + utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this); + } + if ( !this.options.disableMouse ) { + utils.addEvent(this.indicator, 'mousedown', this); + utils.addEvent(window, 'mouseup', this); + } + } + + if ( this.options.fade ) { + this.wrapperStyle[utils.style.transform] = this.scroller.translateZ; + this.wrapperStyle[utils.style.transitionDuration] = utils.isBadAndroid ? '0.001s' : '0ms'; + this.wrapperStyle.opacity = '0'; + } +} + +Indicator.prototype = { + handleEvent: function (e) { + switch ( e.type ) { + case 'touchstart': + case 'pointerdown': + case 'MSPointerDown': + case 'mousedown': + this._start(e); + break; + case 'touchmove': + case 'pointermove': + case 'MSPointerMove': + case 'mousemove': + this._move(e); + break; + case 'touchend': + case 'pointerup': + case 'MSPointerUp': + case 'mouseup': + case 'touchcancel': + case 'pointercancel': + case 'MSPointerCancel': + case 'mousecancel': + this._end(e); + break; + } + }, + + destroy: function () { + if ( this.options.interactive ) { + utils.removeEvent(this.indicator, 'touchstart', this); + utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this); + utils.removeEvent(this.indicator, 'mousedown', this); + + utils.removeEvent(window, 'touchmove', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); + utils.removeEvent(window, 'mousemove', this); + + utils.removeEvent(window, 'touchend', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this); + utils.removeEvent(window, 'mouseup', this); + } + + if ( this.options.defaultScrollbars ) { + this.wrapper.parentNode.removeChild(this.wrapper); + } + }, + + _start: function (e) { + var point = e.touches ? e.touches[0] : e; + + e.preventDefault(); + e.stopPropagation(); + + this.transitionTime(); + + this.initiated = true; + this.moved = false; + this.lastPointX = point.pageX; + this.lastPointY = point.pageY; + + this.startTime = utils.getTime(); + + if ( !this.options.disableTouch ) { + utils.addEvent(window, 'touchmove', this); + } + if ( !this.options.disablePointer ) { + utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this); + } + if ( !this.options.disableMouse ) { + utils.addEvent(window, 'mousemove', this); + } + + this.scroller._execEvent('beforeScrollStart'); + }, + + _move: function (e) { + var point = e.touches ? e.touches[0] : e, + deltaX, deltaY, + newX, newY, + timestamp = utils.getTime(); + + if ( !this.moved ) { + this.scroller._execEvent('scrollStart'); + } + + this.moved = true; + + deltaX = point.pageX - this.lastPointX; + this.lastPointX = point.pageX; + + deltaY = point.pageY - this.lastPointY; + this.lastPointY = point.pageY; + + newX = this.x + deltaX; + newY = this.y + deltaY; + + this._pos(newX, newY); + +// INSERT POINT: indicator._move + + e.preventDefault(); + e.stopPropagation(); + }, + + _end: function (e) { + if ( !this.initiated ) { + return; + } + + this.initiated = false; + + e.preventDefault(); + e.stopPropagation(); + + utils.removeEvent(window, 'touchmove', this); + utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this); + utils.removeEvent(window, 'mousemove', this); + + if ( this.scroller.options.snap ) { + var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y); + + var time = this.options.snapSpeed || Math.max( + Math.max( + Math.min(Math.abs(this.scroller.x - snap.x), 1000), + Math.min(Math.abs(this.scroller.y - snap.y), 1000) + ), 300); + + if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) { + this.scroller.directionX = 0; + this.scroller.directionY = 0; + this.scroller.currentPage = snap; + this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing); + } + } + + if ( this.moved ) { + this.scroller._execEvent('scrollEnd'); + } + }, + + transitionTime: function (time) { + time = time || 0; + this.indicatorStyle[utils.style.transitionDuration] = time + 'ms'; + + if ( !time && utils.isBadAndroid ) { + this.indicatorStyle[utils.style.transitionDuration] = '0.001s'; + } + }, + + transitionTimingFunction: function (easing) { + this.indicatorStyle[utils.style.transitionTimingFunction] = easing; + }, + + refresh: function () { + this.transitionTime(); + + if ( this.options.listenX && !this.options.listenY ) { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; + } else if ( this.options.listenY && !this.options.listenX ) { + this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; + } else { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; + } + + if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) { + utils.addClass(this.wrapper, 'iScrollBothScrollbars'); + utils.removeClass(this.wrapper, 'iScrollLoneScrollbar'); + + if ( this.options.defaultScrollbars && this.options.customStyle ) { + if ( this.options.listenX ) { + this.wrapper.style.right = '8px'; + } else { + this.wrapper.style.bottom = '8px'; + } + } + } else { + utils.removeClass(this.wrapper, 'iScrollBothScrollbars'); + utils.addClass(this.wrapper, 'iScrollLoneScrollbar'); + + if ( this.options.defaultScrollbars && this.options.customStyle ) { + if ( this.options.listenX ) { + this.wrapper.style.right = '2px'; + } else { + this.wrapper.style.bottom = '2px'; + } + } + } + + var r = this.wrapper.offsetHeight; // force refresh + + if ( this.options.listenX ) { + this.wrapperWidth = this.wrapper.clientWidth; + if ( this.options.resize ) { + this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); + this.indicatorStyle.width = this.indicatorWidth + 'px'; + } else { + this.indicatorWidth = this.indicator.clientWidth; + } + + this.maxPosX = this.wrapperWidth - this.indicatorWidth; + + if ( this.options.shrink == 'clip' ) { + this.minBoundaryX = -this.indicatorWidth + 8; + this.maxBoundaryX = this.wrapperWidth - 8; + } else { + this.minBoundaryX = 0; + this.maxBoundaryX = this.maxPosX; + } + + this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); + } + + if ( this.options.listenY ) { + this.wrapperHeight = this.wrapper.clientHeight; + if ( this.options.resize ) { + this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); + this.indicatorStyle.height = this.indicatorHeight + 'px'; + } else { + this.indicatorHeight = this.indicator.clientHeight; + } + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + + if ( this.options.shrink == 'clip' ) { + this.minBoundaryY = -this.indicatorHeight + 8; + this.maxBoundaryY = this.wrapperHeight - 8; + } else { + this.minBoundaryY = 0; + this.maxBoundaryY = this.maxPosY; + } + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); + } + + this.updatePosition(); + }, + + updatePosition: function () { + var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, + y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; + + if ( !this.options.ignoreBoundaries ) { + if ( x < this.minBoundaryX ) { + if ( this.options.shrink == 'scale' ) { + this.width = Math.max(this.indicatorWidth + x, 8); + this.indicatorStyle.width = this.width + 'px'; + } + x = this.minBoundaryX; + } else if ( x > this.maxBoundaryX ) { + if ( this.options.shrink == 'scale' ) { + this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.maxPosX + this.indicatorWidth - this.width; + } else { + x = this.maxBoundaryX; + } + } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) { + this.width = this.indicatorWidth; + this.indicatorStyle.width = this.width + 'px'; + } + + if ( y < this.minBoundaryY ) { + if ( this.options.shrink == 'scale' ) { + this.height = Math.max(this.indicatorHeight + y * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + } + y = this.minBoundaryY; + } else if ( y > this.maxBoundaryY ) { + if ( this.options.shrink == 'scale' ) { + this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.maxPosY + this.indicatorHeight - this.height; + } else { + y = this.maxBoundaryY; + } + } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) { + this.height = this.indicatorHeight; + this.indicatorStyle.height = this.height + 'px'; + } + } + + this.x = x; + this.y = y; + + if ( this.scroller.options.useTransform ) { + this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ; + } else { + this.indicatorStyle.left = x + 'px'; + this.indicatorStyle.top = y + 'px'; + } + }, + + _pos: function (x, y) { + if ( x < 0 ) { + x = 0; + } else if ( x > this.maxPosX ) { + x = this.maxPosX; + } + + if ( y < 0 ) { + y = 0; + } else if ( y > this.maxPosY ) { + y = this.maxPosY; + } + + x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x; + y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y; + + this.scroller.scrollTo(x, y); + }, + + fade: function (val, hold) { + if ( hold && !this.visible ) { + return; + } + + clearTimeout(this.fadeTimeout); + this.fadeTimeout = null; + + var time = val ? 250 : 500, + delay = val ? 0 : 300; + + val = val ? '1' : '0'; + + this.wrapperStyle[utils.style.transitionDuration] = time + 'ms'; + + this.fadeTimeout = setTimeout((function (val) { + this.wrapperStyle.opacity = val; + this.visible = +val; + }).bind(this, val), delay); + } +}; + +IScroll.utils = utils; + +if ( typeof module != 'undefined' && module.exports ) { + module.exports = IScroll; +} else { + window.IScroll = IScroll; +} + +})(window, document, Math); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/photoclip/jquery.photoClip.min.js b/hyhproject/wechat2/view/default/js/photoclip/jquery.photoClip.min.js new file mode 100755 index 0000000..c9922a1 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/photoclip/jquery.photoClip.min.js @@ -0,0 +1,3 @@ +(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery","iscroll-zoom","hammer"],factory)}else{if(typeof exports==="object"){module.exports=factory(require("jquery"),require("iscroll-zoom"),require("hammer"))}else{factory(root.jQuery,root.IScroll,root.Hammer)}}}(this,function(jQuery,IScroll,Hammer){jQuery.fn.photoClip=function(option){if(!window.FileReader){alert("您的浏览器不支持 HTML5 的 FileReader API, 因此无法初始化图片裁剪插件,请更换最新的浏览器!");return}var defaultOption={width:200,height:200,file:"",view:"",ok:"",outputType:"jpg",strictSize:false,loadStart:function(){},loadComplete:function(){},loadError:function(){},clipFinish:function(){}};jQuery.extend(defaultOption,option);this.each(function(){photoClip(this,defaultOption)});return this};function photoClip(container,option){var clipWidth=option.width,clipHeight=option.height,file=option.file,view=option.view,ok=option.ok,outputType=option.outputType||"image/jpeg",strictSize=option.strictSize,loadStart=option.loadStart,loadComplete=option.loadComplete,loadError=option.loadError,clipFinish=option.clipFinish;if(outputType==="jpg"){outputType="image/jpeg"}else{if(outputType==="png"){outputType="image/png"}}var jQueryfile=jQuery(file);if(!jQueryfile.length){return}var jQueryimg,imgWidth,imgHeight,imgLoaded;jQueryfile.attr("accept","image/*");jQueryfile.change(function(){if(!this.files.length){return}if(!/image\/\w+/.test(this.files[0].type)){alert("图片格式不正确,请选择正确格式的图片文件!");return false}else{var fileReader=new FileReader();fileReader.onprogress=function(e){console.log((e.loaded/e.total*100).toFixed()+"%")};fileReader.onload=function(e){var kbs=e.total/1024;if(kbs>1024){var quality=1024/kbs;var jQuerytempImg=jQuery("<img>").hide();jQuerytempImg.load(function(){var sourceWidth=this.naturalWidth;jQuerytempImg.appendTo(document.body);var realityHeight=this.naturalHeight;jQuerytempImg.remove();delete jQuerytempImg[0];jQuerytempImg=null;var angleOffset=0;if(sourceWidth==realityHeight){angleOffset=90}var newDataURL=compressImg(this,quality,angleOffset,outputType);createImg(newDataURL)});jQuerytempImg.attr("src",this.result)}else{createImg(this.result)}};fileReader.onerror=function(e){alert("图片加载失败");loadError.call(this,e)};fileReader.readAsDataURL(this.files[0]);loadStart.call(fileReader,this.files[0])}});jQueryfile.click(function(){this.value=""});var jQuerycontainer,jQueryclipView,jQuerymoveLayer,jQueryrotateLayer,jQueryview,canvas,myScroll,containerWidth,containerHeight;init();initScroll();initEvent();initClip();var jQueryok=jQuery(ok);if(jQueryok.length){jQueryok.click(function(){clipImg()})}var jQuerywin=jQuery(window);resize();jQuerywin.resize(resize);var atRotation,curX,curY,curAngle;function imgLoad(){imgLoaded=true;jQueryrotateLayer.append(this);hideAction.call(this,jQueryimg,function(){imgWidth=this.naturalWidth;imgHeight=this.naturalHeight});hideAction(jQuerymoveLayer,function(){resetScroll()});loadComplete.call(this,this.src)}function initScroll(){var options={zoom:true,scrollX:true,scrollY:true,freeScroll:true,mouseWheel:true,wheelAction:"zoom"};myScroll=new IScroll(jQueryclipView[0],options)}function resetScroll(){curX=0;curY=0;curAngle=0;jQueryrotateLayer.css({"width":imgWidth,"height":imgHeight});setTransform(jQueryrotateLayer,curX,curY,curAngle);calculateScale(imgWidth,imgHeight);myScroll.zoom(myScroll.options.zoomStart);refreshScroll(imgWidth,imgHeight);var posX=(clipWidth-imgWidth*myScroll.options.zoomStart)*0.5,posY=(clipHeight-imgHeight*myScroll.options.zoomStart)*0.5;myScroll.scrollTo(posX,posY)}function refreshScroll(width,height){jQuerymoveLayer.css({"width":width,"height":height});jQueryclipView.append(jQuerymoveLayer);myScroll.refresh()}function initEvent(){var is_mobile=!!navigator.userAgent.match(/mobile/i);if(is_mobile){var hammerManager=new Hammer(jQuerymoveLayer[0]);hammerManager.add(new Hammer.Rotate());var rotation,rotateDirection;hammerManager.on("rotatemove",function(e){if(atRotation){return}rotation=e.rotation;if(rotation>180){rotation-=360}else{if(rotation<-180){rotation+=360}}rotateDirection=rotation>0?1:rotation<0?-1:0});hammerManager.on("rotateend",function(e){if(atRotation){return}if(Math.abs(rotation)>30){if(rotateDirection==1){rotateCW(e.center)}else{if(rotateDirection==-1){rotateCCW(e.center)}}}})}else{jQuerymoveLayer.on("dblclick",function(e){rotateCW({x:e.clientX,y:e.clientY})})}}function rotateCW(point){rotateBy(90,point)}function rotateCCW(point){rotateBy(-90,point)}function rotateBy(angle,point){if(atRotation){return}atRotation=true;var loacl;if(!point){loacl=loaclToLoacl(jQuerymoveLayer,jQueryclipView,clipWidth*0.5,clipHeight*0.5)}else{loacl=globalToLoacl(jQuerymoveLayer,point.x,point.y)}var origin=calculateOrigin(curAngle,loacl),originX=origin.x,originY=origin.y,offsetX=0,offsetY=0,parentOffsetX=0,parentOffsetY=0,newAngle=curAngle+angle,curImgWidth,curImgHeight;if(newAngle==90||newAngle==-270){offsetX=originX+originY;offsetY=originY-originX;if(newAngle>curAngle){parentOffsetX=imgHeight-originX-originY;parentOffsetY=originX-originY +}else{if(newAngle<curAngle){parentOffsetX=(imgHeight-originY)-(imgWidth-originX);parentOffsetY=originX+originY-imgHeight}}curImgWidth=imgHeight;curImgHeight=imgWidth}else{if(newAngle==180||newAngle==-180){offsetX=originX*2;offsetY=originY*2;if(newAngle>curAngle){parentOffsetX=(imgWidth-originX)-(imgHeight-originY);parentOffsetY=imgHeight-(originX+originY)}else{if(newAngle<curAngle){parentOffsetX=imgWidth-(originX+originY);parentOffsetY=(imgHeight-originY)-(imgWidth-originX)}}curImgWidth=imgWidth;curImgHeight=imgHeight}else{if(newAngle==270||newAngle==-90){offsetX=originX-originY;offsetY=originX+originY;if(newAngle>curAngle){parentOffsetX=originX+originY-imgWidth;parentOffsetY=(imgWidth-originX)-(imgHeight-originY)}else{if(newAngle<curAngle){parentOffsetX=originY-originX;parentOffsetY=imgWidth-originX-originY}}curImgWidth=imgHeight;curImgHeight=imgWidth}else{if(newAngle==0||newAngle==360||newAngle==-360){offsetX=0;offsetY=0;if(newAngle>curAngle){parentOffsetX=originX-originY;parentOffsetY=originX+originY-imgWidth}else{if(newAngle<curAngle){parentOffsetX=originX+originY-imgHeight;parentOffsetY=originY-originX}}curImgWidth=imgWidth;curImgHeight=imgHeight}}}}if(curAngle==0){curX=0;curY=0}else{if(curAngle==90||curAngle==-270){curX-=originX+originY;curY-=originY-originX}else{if(curAngle==180||curAngle==-180){curX-=originX*2;curY-=originY*2}else{if(curAngle==270||curAngle==-90){curX-=originX-originY;curY-=originX+originY}}}}curX=curX.toFixed(2)-0;curY=curY.toFixed(2)-0;setTransform(jQueryrotateLayer,curX,curY,curAngle,originX,originY);setTransition(jQueryrotateLayer,curX,curY,newAngle,200,function(){atRotation=false;curAngle=newAngle%360;curX+=offsetX+parentOffsetX;curY+=offsetY+parentOffsetY;curX=curX.toFixed(2)-0;curY=curY.toFixed(2)-0;setTransform(jQueryrotateLayer,curX,curY,curAngle);myScroll.scrollTo(myScroll.x-parentOffsetX*myScroll.scale,myScroll.y-parentOffsetY*myScroll.scale);calculateScale(curImgWidth,curImgHeight);if(myScroll.scale<myScroll.options.zoomMin){myScroll.zoom(myScroll.options.zoomMin)}refreshScroll(curImgWidth,curImgHeight)})}function initClip(){canvas=document.createElement("canvas");canvas.width=clipWidth;canvas.height=clipHeight}function clipImg(){if(!imgLoaded){alert("亲,当前没有图片可以裁剪!");return}var local=loaclToLoacl(jQuerymoveLayer,jQueryclipView);var scale=myScroll.scale;var ctx=canvas.getContext("2d");ctx.clearRect(0,0,canvas.width,canvas.height);ctx.save();if(strictSize){ctx.scale(scale,scale)}else{canvas.width=clipWidth/scale;canvas.height=clipHeight/scale}ctx.translate(curX-local.x/scale,curY-local.y/scale);ctx.rotate(curAngle*Math.PI/180);ctx.drawImage(jQueryimg[0],0,0);ctx.restore();var dataURL=canvas.toDataURL(outputType,1);jQueryview.css("background-image","url("+dataURL+")");clipFinish.call(jQueryimg[0],dataURL)}function resize(){hideAction(jQuerycontainer,function(){containerWidth=jQuerycontainer.width();containerHeight=jQuerycontainer.height()})}function loaclToLoacl(jQuerylayerOne,jQuerylayerTwo,x,y){x=x||0;y=y||0;var layerOneOffset,layerTwoOffset;hideAction(jQuerylayerOne,function(){layerOneOffset=jQuerylayerOne.offset()});hideAction(jQuerylayerTwo,function(){layerTwoOffset=jQuerylayerTwo.offset()});return{x:layerTwoOffset.left-layerOneOffset.left+x,y:layerTwoOffset.top-layerOneOffset.top+y}}function globalToLoacl(jQuerylayer,x,y){x=x||0;y=y||0;var layerOffset;hideAction(jQuerylayer,function(){layerOffset=jQuerylayer.offset()});return{x:x+jQuerywin.scrollLeft()-layerOffset.left,y:y+jQuerywin.scrollTop()-layerOffset.top}}function hideAction(jq,func){var jQueryhide=jQuery();jQuery.each(jq,function(i,n){var jQueryn=jQuery(n);var jQueryhidden=jQueryn.parents().andSelf().filter(":hidden");var jQuerynone;for(var i=0;i<jQueryhidden.length;i++){if(!jQueryn.is(":hidden")){break}jQuerynone=jQueryhidden.eq(i);if(jQuerynone.css("display")=="none"){jQueryhide=jQueryhide.add(jQuerynone.show())}}});if(typeof(func)=="function"){func.call(this)}jQueryhide.hide()}function calculateOrigin(curAngle,point){var scale=myScroll.scale;var origin={};if(curAngle==0){origin.x=point.x/scale;origin.y=point.y/scale}else{if(curAngle==90||curAngle==-270){origin.x=point.y/scale;origin.y=imgHeight-point.x/scale}else{if(curAngle==180||curAngle==-180){origin.x=imgWidth-point.x/scale;origin.y=imgHeight-point.y/scale}else{if(curAngle==270||curAngle==-90){origin.x=imgWidth-point.y/scale;origin.y=point.x/scale}}}}return origin}function getScale(w1,h1,w2,h2){var sx=w1/w2;var sy=h1/h2;return sx>sy?sx:sy}function calculateScale(width,height){myScroll.options.zoomMin=getScale(clipWidth,clipHeight,width,height);myScroll.options.zoomMax=Math.max(1,myScroll.options.zoomMin);myScroll.options.zoomStart=Math.min(myScroll.options.zoomMax,getScale(containerWidth,containerHeight,width,height))}function compressImg(sourceImgObj,quality,angleOffset,outputFormat){quality=quality||0.8;angleOffset=angleOffset||0;var mimeType=outputFormat||"image/jpeg";var drawWidth=sourceImgObj.naturalWidth,drawHeight=sourceImgObj.naturalHeight;var maxSide=Math.max(drawWidth,drawHeight); +if(maxSide>1024){var minSide=Math.min(drawWidth,drawHeight);minSide=minSide/maxSide*1024;maxSide=1024;if(drawWidth>drawHeight){drawWidth=maxSide;drawHeight=minSide}else{drawWidth=minSide;drawHeight=maxSide}}var cvs=document.createElement("canvas");var ctx=cvs.getContext("2d");if(angleOffset){cvs.width=drawHeight;cvs.height=drawWidth;ctx.translate(drawHeight,0);ctx.rotate(angleOffset*Math.PI/180)}else{cvs.width=drawWidth;cvs.height=drawHeight}ctx.drawImage(sourceImgObj,0,0,drawWidth,drawHeight);var newImageData=cvs.toDataURL(mimeType,quality||0.8);return newImageData}function createImg(src){if(jQueryimg&&jQueryimg.length){jQueryimg.remove();delete jQueryimg[0]}jQueryimg=jQuery("<img>").css({"user-select":"none","pointer-events":"none"});jQueryimg.load(imgLoad);jQueryimg.attr("src",src)}function setTransform(jQueryobj,x,y,angle,originX,originY){originX=originX||0;originY=originY||0;var style={};style[prefix+"transform"]="translateZ(0) translate("+x+"px,"+y+"px) rotate("+angle+"deg)";style[prefix+"transform-origin"]=originX+"px "+originY+"px";jQueryobj.css(style)}function setTransition(jQueryobj,x,y,angle,dur,fn){jQueryobj.css(prefix+"transform");jQueryobj.css(prefix+"transition",prefix+"transform "+dur+"ms");jQueryobj.one(transitionEnd,function(){jQueryobj.css(prefix+"transition","");fn.call(this)});jQueryobj.css(prefix+"transform","translateZ(0) translate("+x+"px,"+y+"px) rotate("+angle+"deg)")}function init(){jQuerycontainer=jQuery(container).css({"user-select":"none","overflow":"hidden"});if(jQuerycontainer.css("position")=="static"){jQuerycontainer.css("position","relative")}jQueryclipView=jQuery("<div class='photo-clip-view'>").css({"position":"absolute","left":"50%","top":"50%","width":clipWidth,"height":clipHeight,"margin-left":-clipWidth/2,"margin-top":-clipHeight/2}).appendTo(jQuerycontainer);jQuerymoveLayer=jQuery("<div class='photo-clip-moveLayer'>").appendTo(jQueryclipView);jQueryrotateLayer=jQuery("<div class='photo-clip-rotateLayer'>").appendTo(jQuerymoveLayer);var jQuerymask=jQuery("<div class='photo-clip-mask'>").css({"position":"absolute","left":0,"top":0,"width":"100%","height":"100%","pointer-events":"none"}).appendTo(jQuerycontainer);var jQuerymask_left=jQuery("<div class='photo-clip-mask-left'>").css({"position":"absolute","left":0,"right":"50%","top":"50%","bottom":"50%","width":"auto","height":clipHeight,"margin-right":clipWidth/2,"margin-top":-clipHeight/2,"margin-bottom":-clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_right=jQuery("<div class='photo-clip-mask-right'>").css({"position":"absolute","left":"50%","right":0,"top":"50%","bottom":"50%","margin-left":clipWidth/2,"margin-top":-clipHeight/2,"margin-bottom":-clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_top=jQuery("<div class='photo-clip-mask-top'>").css({"position":"absolute","left":0,"right":0,"top":0,"bottom":"50%","margin-bottom":clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQuerymask_bottom=jQuery("<div class='photo-clip-mask-bottom'>").css({"position":"absolute","left":0,"right":0,"top":"50%","bottom":0,"margin-top":clipHeight/2,"background-color":"rgba(0,0,0,.5)"}).appendTo(jQuerymask);var jQueryclip_area=jQuery("<div class='photo-clip-area'>").css({"border":"1px dashed #ddd","position":"absolute","left":"50%","top":"50%","width":clipWidth,"height":clipHeight,"margin-left":-clipWidth/2-1,"margin-top":-clipHeight/2-1}).appendTo(jQuerymask);jQueryview=jQuery(view);if(jQueryview.length){jQueryview.css({"background-color":"#666","background-repeat":"no-repeat","background-position":"center","background-size":"contain"})}}}var prefix="",transitionEnd;(function(){var eventPrefix,vendors={Webkit:"webkit",Moz:"",O:"o"},testEl=document.documentElement,normalizeEvent=function(name){return eventPrefix?eventPrefix+name:name.toLowerCase()};for(var i in vendors){if(testEl.style[i+"TransitionProperty"]!==undefined){prefix="-"+i.toLowerCase()+"-";eventPrefix=vendors[i];break}}transitionEnd=normalizeEvent("TransitionEnd")})();return jQuery})); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/photoclip/upload.hpictures.js b/hyhproject/wechat2/view/default/js/photoclip/upload.hpictures.js new file mode 100755 index 0000000..8d9297b --- /dev/null +++ b/hyhproject/wechat2/view/default/js/photoclip/upload.hpictures.js @@ -0,0 +1,104 @@ + jQuery.noConflict(); +//关闭图片上传区 + function closeUploadArea(){ + var data='#upload_close,#upload_button,#upload_modal'; + var data2='.return_users,.useri_info,#useri_info,#footer'; + WST.showHide('',data); + WST.showHide(1,data2); + //清空图片上传区的内容 + $('#clipArea').find('img').remove(); + $('#file').val(''); + $('#view').css('background-image',''); + $('#imgData').val(''); + } + jQuery('#uploadImg').on('change', function() { + var data='.return_users,.useri_info,#useri_info,#footer'; + var data2='#upload_close,#upload_button,#upload_modal'; + WST.showHide('',data); + WST.showHide(1,data2); +}); +//头像上传 +jQuery("#clipArea").photoClip({ + width: 350, + height: 350, + file: "#uploadImg", + view: "#view", + ok: "#upload_button", + loadStart: function() { + $('#Load').show(); + }, + loadComplete: function() { + $('#Load').hide(); + }, + clipFinish: function(dataURL) { + jQuery('#imgData').val(dataURL); + var imgData = $('#imgData').val(); + if(!imgData || imgData==''){ + WST.msg('请先选择图片','info'); + return false; + } + // 上传裁剪好的图片 + funUploadFile(dataURL); + } +}); + + + /** + * @param base64Codes + * 图片的base64编码 + */ +funUploadFile=function(base64Codes){ + var self = this; + var formData = new FormData(); + //convertBase64UrlToBlob函数是将base64编码转换为Blob + //append函数的第一个参数是后台获取数据的参数名,在php中用$FILES['imageName']接收, + var imgSuffix = base64Codes.split(";")[0].split('/')[1]; + formData.append("imageName",self.convertBase64UrlToBlob(base64Codes),"image."+imgSuffix); + //ajax 提交form + $.ajax({ + // 你后台的接收地址 + url : WST.U('wechat/users/uploadPic',{'dir':'users','isTumb':1}), + type : "POST", + data : formData, + dataType:"json", + processData : false, // 告诉jQuery不要去处理发送的数据 + contentType : false, // 告诉jQuery不要去设置Content-Type请求头 + success:function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $.post(WST.U('wechat/users/editUserInfo'), {userPhoto:json.savePath+json.name}, function(data){ + if(json.status==1){ + WST.msg('修改头像成功','success'); + jQuery('#imgurl').attr('src', WST.conf.ROOT +'/'+json.savePath+'/'+json.name); + }else{ + WST.msg('修改头像失败,请重试','warn'); + return false; + } + }); + }else{ + WST.msg(json.msg,'warn'); + } + closeUploadArea(); + $('#Load').hide(); + + } + }); +} + +/** + * 将以base64的图片url数据转换为Blob + * @param urlData + * 用url方式表示的base64图片数据 + */ +convertBase64UrlToBlob=function(urlData){ + //去掉url的头,并转换为byte + var bytes=window.atob(urlData.split(',')[1]); + //处理异常,将ascii码小于0的转换为大于0 + var ab = new ArrayBuffer(bytes.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < bytes.length; i++) { + ia[i] = bytes.charCodeAt(i); + } + // 此处type注意与photoClip初始化中的outputType类型保持一致 + return new Blob( [ab] , {type : 'image/jpeg'}); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/qrcode.js b/hyhproject/wechat2/view/default/js/qrcode.js new file mode 100755 index 0000000..b2ae4a6 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/qrcode.js @@ -0,0 +1,88 @@ + +var qrcode=function(){var qrcode=function(typeNumber,errorCorrectLevel){var PAD0=0xEC;var PAD1=0x11;var _typeNumber=typeNumber;var _errorCorrectLevel=QRErrorCorrectLevel[errorCorrectLevel];var _modules=null;var _moduleCount=0;var _dataCache=null;var _dataList=new Array();var _this={};var makeImpl=function(test,maskPattern){_moduleCount=_typeNumber*4+17;_modules=function(moduleCount){var modules=new Array(moduleCount);for(var row=0;row<moduleCount;row+=1){modules[row]=new Array(moduleCount);for(var col=0;col<moduleCount;col+=1){modules[row][col]=null;}} +return modules;}(_moduleCount);setupPositionProbePattern(0,0);setupPositionProbePattern(_moduleCount-7,0);setupPositionProbePattern(0,_moduleCount-7);setupPositionAdjustPattern();setupTimingPattern();setupTypeInfo(test,maskPattern);if(_typeNumber>=7){setupTypeNumber(test);} +if(_dataCache==null){_dataCache=createData(_typeNumber,_errorCorrectLevel,_dataList);} +mapData(_dataCache,maskPattern);};var setupPositionProbePattern=function(row,col){for(var r=-1;r<=7;r+=1){if(row+r<=-1||_moduleCount<=row+r)continue;for(var c=-1;c<=7;c+=1){if(col+c<=-1||_moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}};var getBestMaskPattern=function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i+=1){makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(_this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} +return pattern;};var setupTimingPattern=function(){for(var r=8;r<_moduleCount-8;r+=1){if(_modules[r][6]!=null){continue;} +_modules[r][6]=(r%2==0);} +for(var c=8;c<_moduleCount-8;c+=1){if(_modules[6][c]!=null){continue;} +_modules[6][c]=(c%2==0);}};var setupPositionAdjustPattern=function(){var pos=QRUtil.getPatternPosition(_typeNumber);for(var i=0;i<pos.length;i+=1){for(var j=0;j<pos.length;j+=1){var row=pos[i];var col=pos[j];if(_modules[row][col]!=null){continue;} +for(var r=-2;r<=2;r+=1){for(var c=-2;c<=2;c+=1){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}}}};var setupTypeNumber=function(test){var bits=QRUtil.getBCHTypeNumber(_typeNumber);for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[Math.floor(i/3)][i%3+_moduleCount-8-3]=mod;} +for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[i%3+_moduleCount-8-3][Math.floor(i/3)]=mod;}};var setupTypeInfo=function(test,maskPattern){var data=(_errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<6){_modules[i][8]=mod;}else if(i<8){_modules[i+1][8]=mod;}else{_modules[_moduleCount-15+i][8]=mod;}} +for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<8){_modules[8][_moduleCount-i-1]=mod;}else if(i<9){_modules[8][15-i-1+1]=mod;}else{_modules[8][15-i-1]=mod;}} +_modules[_moduleCount-8][8]=(!test);};var mapData=function(data,maskPattern){var inc=-1;var row=_moduleCount-1;var bitIndex=7;var byteIndex=0;var maskFunc=QRUtil.getMaskFunction(maskPattern);for(var col=_moduleCount-1;col>0;col-=2){if(col==6)col-=1;while(true){for(var c=0;c<2;c+=1){if(_modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} +var mask=maskFunc(row,col-c);if(mask){dark=!dark;} +_modules[row][col-c]=dark;bitIndex-=1;if(bitIndex==-1){byteIndex+=1;bitIndex=7;}}} +row+=inc;if(row<0||_moduleCount<=row){row-=inc;inc=-inc;break;}}}};var createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r+=1){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i+=1){dcdata[r][i]=0xff&buffer.getBuffer()[i+offset];} +offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=qrPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i+=1){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.getAt(modIndex):0;}} +var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalCodeCount+=rsBlocks[i].totalCount;} +var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<dcdata[r].length){data[index]=dcdata[r][i];index+=1;}}} +for(var i=0;i<maxEcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<ecdata[r].length){data[index]=ecdata[r][i];index+=1;}}} +return data;};var createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=qrBitBuffer();for(var i=0;i<dataList.length;i+=1){var data=dataList[i];buffer.put(data.getMode(),4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.getMode(),typeNumber));data.write(buffer);} +var totalDataCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalDataCount+=rsBlocks[i].dataCount;} +if(buffer.getLengthInBits()>totalDataCount*8){throw new Error('code length overflow. (' ++buffer.getLengthInBits() ++'>' ++totalDataCount*8 ++')');} +if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} +while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} +while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD1,8);} +return createBytes(buffer,rsBlocks);};_this.addData=function(data){var newData=qr8BitByte(data);_dataList.push(newData);_dataCache=null;};_this.isDark=function(row,col){if(row<0||_moduleCount<=row||col<0||_moduleCount<=col){throw new Error(row+','+col);} +return _modules[row][col];};_this.getModuleCount=function(){return _moduleCount;};_this.make=function(){makeImpl(false,getBestMaskPattern());};_this.createTableTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var qrHtml='';qrHtml+='<table style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: '+margin+'px;';qrHtml+='">';qrHtml+='<tbody>';for(var r=0;r<_this.getModuleCount();r+=1){qrHtml+='<tr>';for(var c=0;c<_this.getModuleCount();c+=1){qrHtml+='<td style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: 0px;';qrHtml+=' width: '+cellSize+'px;';qrHtml+=' height: '+cellSize+'px;';qrHtml+=' background-color: ';qrHtml+=_this.isDark(r,c)?'#000000':'#ffffff';qrHtml+=';';qrHtml+='"/>';} +qrHtml+='</tr>';} +qrHtml+='</tbody>';qrHtml+='</table>';return qrHtml;};_this.createImgTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var size=_this.getModuleCount()*cellSize+margin*2;var min=margin;var max=size-margin;return createImgTag(size,size,function(x,y){if(min<=x&&x<max&&min<=y&&y<max){var c=Math.floor((x-min)/cellSize);var r=Math.floor((y-min)/cellSize);return _this.isDark(r,c)?0:1;}else{return 1;}});};return _this;};qrcode.stringToBytes=function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);bytes.push(c&0xff);} +return bytes;};qrcode.createStringToBytes=function(unicodeData,numChars){var unicodeMap=function(){var bin=base64DecodeInputStream(unicodeData);var read=function(){var b=bin.read();if(b==-1)throw new Error();return b;};var count=0;var unicodeMap={};while(true){var b0=bin.read();if(b0==-1)break;var b1=read();var b2=read();var b3=read();var k=String.fromCharCode((b0<<8)|b1);var v=(b2<<8)|b3;unicodeMap[k]=v;count+=1;} +if(count!=numChars){throw new Error(count+' != '+numChars);} +return unicodeMap;}();var unknownChar='?'.charCodeAt(0);return function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);if(c<128){bytes.push(c);}else{var b=unicodeMap[s.charAt(i)];if(typeof b=='number'){if((b&0xff)==b){bytes.push(b);}else{bytes.push(b>>>8);bytes.push(b&0xff);}}else{bytes.push(unknownChar);}}} +return bytes;};};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil=function(){var PATTERN_POSITION_TABLE=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]];var G15=(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0);var G18=(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0);var G15_MASK=(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1);var _this={};var getBCHDigit=function(data){var digit=0;while(data!=0){digit+=1;data>>>=1;} +return digit;};_this.getBCHTypeInfo=function(data){var d=data<<10;while(getBCHDigit(d)-getBCHDigit(G15)>=0){d^=(G15<<(getBCHDigit(d)-getBCHDigit(G15)));} +return((data<<10)|d)^G15_MASK;};_this.getBCHTypeNumber=function(data){var d=data<<12;while(getBCHDigit(d)-getBCHDigit(G18)>=0){d^=(G18<<(getBCHDigit(d)-getBCHDigit(G18)));} +return(data<<12)|d;};_this.getPatternPosition=function(typeNumber){return PATTERN_POSITION_TABLE[typeNumber-1];};_this.getMaskFunction=function(maskPattern){switch(maskPattern){case QRMaskPattern.PATTERN000:return function(i,j){return(i+j)%2==0;};case QRMaskPattern.PATTERN001:return function(i,j){return i%2==0;};case QRMaskPattern.PATTERN010:return function(i,j){return j%3==0;};case QRMaskPattern.PATTERN011:return function(i,j){return(i+j)%3==0;};case QRMaskPattern.PATTERN100:return function(i,j){return(Math.floor(i/2)+Math.floor(j/3))%2==0;};case QRMaskPattern.PATTERN101:return function(i,j){return(i*j)%2+(i*j)%3==0;};case QRMaskPattern.PATTERN110:return function(i,j){return((i*j)%2+(i*j)%3)%2==0;};case QRMaskPattern.PATTERN111:return function(i,j){return((i*j)%3+(i+j)%2)%2==0;};default:throw new Error('bad maskPattern:'+maskPattern);}};_this.getErrorCorrectPolynomial=function(errorCorrectLength){var a=qrPolynomial([1],0);for(var i=0;i<errorCorrectLength;i+=1){a=a.multiply(qrPolynomial([1,QRMath.gexp(i)],0));} +return a;};_this.getLengthInBits=function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error('mode:'+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error('mode:'+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error('mode:'+mode);}}else{throw new Error('type:'+type);}};_this.getLostPoint=function(qrcode){var moduleCount=qrcode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount;col+=1){var sameCount=0;var dark=qrcode.isDark(row,col);for(var r=-1;r<=1;r+=1){if(row+r<0||moduleCount<=row+r){continue;} +for(var c=-1;c<=1;c+=1){if(col+c<0||moduleCount<=col+c){continue;} +if(r==0&&c==0){continue;} +if(dark==qrcode.isDark(row+r,col+c)){sameCount+=1;}}} +if(sameCount>5){lostPoint+=(3+sameCount-5);}}};for(var row=0;row<moduleCount-1;row+=1){for(var col=0;col<moduleCount-1;col+=1){var count=0;if(qrcode.isDark(row,col))count+=1;if(qrcode.isDark(row+1,col))count+=1;if(qrcode.isDark(row,col+1))count+=1;if(qrcode.isDark(row+1,col+1))count+=1;if(count==0||count==4){lostPoint+=3;}}} +for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount-6;col+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row,col+1)&&qrcode.isDark(row,col+2)&&qrcode.isDark(row,col+3)&&qrcode.isDark(row,col+4)&&!qrcode.isDark(row,col+5)&&qrcode.isDark(row,col+6)){lostPoint+=40;}}} +for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount-6;row+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row+1,col)&&qrcode.isDark(row+2,col)&&qrcode.isDark(row+3,col)&&qrcode.isDark(row+4,col)&&!qrcode.isDark(row+5,col)&&qrcode.isDark(row+6,col)){lostPoint+=40;}}} +var darkCount=0;for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount;row+=1){if(qrcode.isDark(row,col)){darkCount+=1;}}} +var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;};return _this;}();var QRMath=function(){var EXP_TABLE=new Array(256);var LOG_TABLE=new Array(256);for(var i=0;i<8;i+=1){EXP_TABLE[i]=1<<i;} +for(var i=8;i<256;i+=1){EXP_TABLE[i]=EXP_TABLE[i-4]^EXP_TABLE[i-5]^EXP_TABLE[i-6]^EXP_TABLE[i-8];} +for(var i=0;i<255;i+=1){LOG_TABLE[EXP_TABLE[i]]=i;} +var _this={};_this.glog=function(n){if(n<1){throw new Error('glog('+n+')');} +return LOG_TABLE[n];};_this.gexp=function(n){while(n<0){n+=255;} +while(n>=256){n-=255;} +return EXP_TABLE[n];};return _this;}();function qrPolynomial(num,shift){if(typeof num.length=='undefined'){throw new Error(num.length+'/'+shift);} +var _num=function(){var offset=0;while(offset<num.length&&num[offset]==0){offset+=1;} +var _num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i+=1){_num[i]=num[i+offset];} +return _num;}();var _this={};_this.getAt=function(index){return _num[index];};_this.getLength=function(){return _num.length;};_this.multiply=function(e){var num=new Array(_this.getLength()+e.getLength()-1);for(var i=0;i<_this.getLength();i+=1){for(var j=0;j<e.getLength();j+=1){num[i+j]^=QRMath.gexp(QRMath.glog(_this.getAt(i))+QRMath.glog(e.getAt(j)));}} +return qrPolynomial(num,0);};_this.mod=function(e){if(_this.getLength()-e.getLength()<0){return _this;} +var ratio=QRMath.glog(_this.getAt(0))-QRMath.glog(e.getAt(0));var num=new Array(_this.getLength());for(var i=0;i<_this.getLength();i+=1){num[i]=_this.getAt(i);} +for(var i=0;i<e.getLength();i+=1){num[i]^=QRMath.gexp(QRMath.glog(e.getAt(i))+ratio);} +return qrPolynomial(num,0).mod(e);};return _this;};var QRRSBlock=function(){var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16]];var qrRSBlock=function(totalCount,dataCount){var _this={};_this.totalCount=totalCount;_this.dataCount=dataCount;return _this;};var _this={};var getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};_this.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=getRsBlockTable(typeNumber,errorCorrectLevel);if(typeof rsBlock=='undefined'){throw new Error('bad rs block @ typeNumber:'+typeNumber+'/errorCorrectLevel:'+errorCorrectLevel);} +var length=rsBlock.length/3;var list=new Array();for(var i=0;i<length;i+=1){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j+=1){list.push(qrRSBlock(totalCount,dataCount));}} +return list;};return _this;}();var qrBitBuffer=function(){var _buffer=new Array();var _length=0;var _this={};_this.getBuffer=function(){return _buffer;};_this.getAt=function(index){var bufIndex=Math.floor(index/8);return((_buffer[bufIndex]>>>(7-index%8))&1)==1;};_this.put=function(num,length){for(var i=0;i<length;i+=1){_this.putBit(((num>>>(length-i-1))&1)==1);}};_this.getLengthInBits=function(){return _length;};_this.putBit=function(bit){var bufIndex=Math.floor(_length/8);if(_buffer.length<=bufIndex){_buffer.push(0);} +if(bit){_buffer[bufIndex]|=(0x80>>>(_length%8));} +_length+=1;};return _this;};var qr8BitByte=function(data){var _mode=QRMode.MODE_8BIT_BYTE;var _data=data;var _bytes=qrcode.stringToBytes(data);var _this={};_this.getMode=function(){return _mode;};_this.getLength=function(buffer){return _bytes.length;};_this.write=function(buffer){for(var i=0;i<_bytes.length;i+=1){buffer.put(_bytes[i],8);}};return _this;};var byteArrayOutputStream=function(){var _bytes=new Array();var _this={};_this.writeByte=function(b){_bytes.push(b&0xff);};_this.writeShort=function(i){_this.writeByte(i);_this.writeByte(i>>>8);};_this.writeBytes=function(b,off,len){off=off||0;len=len||b.length;for(var i=0;i<len;i+=1){_this.writeByte(b[i+off]);}};_this.writeString=function(s){for(var i=0;i<s.length;i+=1){_this.writeByte(s.charCodeAt(i));}};_this.toByteArray=function(){return _bytes;};_this.toString=function(){var s='';s+='[';for(var i=0;i<_bytes.length;i+=1){if(i>0){s+=',';} +s+=_bytes[i];} +s+=']';return s;};return _this;};var base64EncodeOutputStream=function(){var _buffer=0;var _buflen=0;var _length=0;var _base64='';var _this={};var writeEncoded=function(b){_base64+=String.fromCharCode(encode(b&0x3f));};var encode=function(n){if(n<0){}else if(n<26){return 0x41+n;}else if(n<52){return 0x61+(n-26);}else if(n<62){return 0x30+(n-52);}else if(n==62){return 0x2b;}else if(n==63){return 0x2f;} +throw new Error('n:'+n);};_this.writeByte=function(n){_buffer=(_buffer<<8)|(n&0xff);_buflen+=8;_length+=1;while(_buflen>=6){writeEncoded(_buffer>>>(_buflen-6));_buflen-=6;}};_this.flush=function(){if(_buflen>0){writeEncoded(_buffer<<(6-_buflen));_buffer=0;_buflen=0;} +if(_length%3!=0){var padlen=3-_length%3;for(var i=0;i<padlen;i+=1){_base64+='=';}}};_this.toString=function(){return _base64;};return _this;};var base64DecodeInputStream=function(str){var _str=str;var _pos=0;var _buffer=0;var _buflen=0;var _this={};_this.read=function(){while(_buflen<8){if(_pos>=_str.length){if(_buflen==0){return-1;} +throw new Error('unexpected end of file./'+_buflen);} +var c=_str.charAt(_pos);_pos+=1;if(c=='='){_buflen=0;return-1;}else if(c.match(/^\s$/)){continue;} +_buffer=(_buffer<<6)|decode(c.charCodeAt(0));_buflen+=6;} +var n=(_buffer>>>(_buflen-8))&0xff;_buflen-=8;return n;};var decode=function(c){if(0x41<=c&&c<=0x5a){return c-0x41;}else if(0x61<=c&&c<=0x7a){return c-0x61+26;}else if(0x30<=c&&c<=0x39){return c-0x30+52;}else if(c==0x2b){return 62;}else if(c==0x2f){return 63;}else{throw new Error('c:'+c);}};return _this;};var gifImage=function(width,height){var _width=width;var _height=height;var _data=new Array(width*height);var _this={};_this.setPixel=function(x,y,pixel){_data[y*_width+x]=pixel;};_this.write=function(out){out.writeString('GIF87a');out.writeShort(_width);out.writeShort(_height);out.writeByte(0x80);out.writeByte(0);out.writeByte(0);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0xff);out.writeByte(0xff);out.writeByte(0xff);out.writeString(',');out.writeShort(0);out.writeShort(0);out.writeShort(_width);out.writeShort(_height);out.writeByte(0);var lzwMinCodeSize=2;var raster=getLZWRaster(lzwMinCodeSize);out.writeByte(lzwMinCodeSize);var offset=0;while(raster.length-offset>255){out.writeByte(255);out.writeBytes(raster,offset,255);offset+=255;} +out.writeByte(raster.length-offset);out.writeBytes(raster,offset,raster.length-offset);out.writeByte(0x00);out.writeString(';');};var bitOutputStream=function(out){var _out=out;var _bitLength=0;var _bitBuffer=0;var _this={};_this.write=function(data,length){if((data>>>length)!=0){throw new Error('length over');} +while(_bitLength+length>=8){_out.writeByte(0xff&((data<<_bitLength)|_bitBuffer));length-=(8-_bitLength);data>>>=(8-_bitLength);_bitBuffer=0;_bitLength=0;} +_bitBuffer=(data<<_bitLength)|_bitBuffer;_bitLength=_bitLength+length;};_this.flush=function(){if(_bitLength>0){_out.writeByte(_bitBuffer);}};return _this;};var getLZWRaster=function(lzwMinCodeSize){var clearCode=1<<lzwMinCodeSize;var endCode=(1<<lzwMinCodeSize)+1;var bitLength=lzwMinCodeSize+1;var table=lzwTable();for(var i=0;i<clearCode;i+=1){table.add(String.fromCharCode(i));} +table.add(String.fromCharCode(clearCode));table.add(String.fromCharCode(endCode));var byteOut=byteArrayOutputStream();var bitOut=bitOutputStream(byteOut);bitOut.write(clearCode,bitLength);var dataIndex=0;var s=String.fromCharCode(_data[dataIndex]);dataIndex+=1;while(dataIndex<_data.length){var c=String.fromCharCode(_data[dataIndex]);dataIndex+=1;if(table.contains(s+c)){s=s+c;}else{bitOut.write(table.indexOf(s),bitLength);if(table.size()<0xfff){if(table.size()==(1<<bitLength)){bitLength+=1;} +table.add(s+c);} +s=c;}} +bitOut.write(table.indexOf(s),bitLength);bitOut.write(endCode,bitLength);bitOut.flush();return byteOut.toByteArray();};var lzwTable=function(){var _map={};var _size=0;var _this={};_this.add=function(key){if(_this.contains(key)){throw new Error('dup key:'+key);} +_map[key]=_size;_size+=1;};_this.size=function(){return _size;};_this.indexOf=function(key){return _map[key];};_this.contains=function(key){return typeof _map[key]!='undefined';};return _this;};return _this;};var createImgTag=function(width,height,getPixel,alt){var gif=gifImage(width,height);for(var y=0;y<height;y+=1){for(var x=0;x<width;x+=1){gif.setPixel(x,y,getPixel(x,y));}} +var b=byteArrayOutputStream();gif.write(b);var base64=base64EncodeOutputStream();var bytes=b.toByteArray();for(var i=0;i<bytes.length;i+=1){base64.writeByte(bytes[i]);} +base64.flush();var img='';img+='<img';img+='\u0020src="';img+='data:image/gif;base64,';img+=base64;img+='"';img+='\u0020width="';img+=width;img+='"';img+='\u0020height="';img+=height;img+='"';if(alt){img+='\u0020alt="';img+=alt;img+='"';} +img+='/>';return img;};return qrcode;}();/* |xGv00|ca8fc6bde81a353e7cede123b304bdb9 */ \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/self_shop.js b/hyhproject/wechat2/view/default/js/self_shop.js new file mode 100755 index 0000000..fef2811 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/self_shop.js @@ -0,0 +1,108 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + // 加载商品列表 + shopsList(); + // 商家推荐 + new Swiper('.swiper-container', { + slidesPerView: 4, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : false, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + // 推荐 + WST.imgAdapt('j-imgRec'); + // 热卖 + WST.imgAdapt('j-imgRec1'); + $('.wst-gol-adsb').css('height',$('.j-imgRec').width()+20); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(){ + if (loading) return; + if (($(window).scrollTop()) >= ($(document).height() - screen.height)) { + shopsList(); + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} +function searchGoods(){ + location.href=WST.U('wechat/shops/home','goodsName='+$('#searchKey').val(),true); +} +/*分类*/ +function goGoodsList(ct1,ct2){ + var param = 'shopId=1&ct1='+ct1; + if(ct2) + param += '&ct2='+ct2; + param.shopId = 1; + location.href=WST.U('wechat/shops/shopgoodslist',param,true); +} + +function shopAds(){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); + var w = WST.pageWidth(); + var h = w*2/5; + var o = $('.ui-slider').css("padding-top",h); + var scroll = new fz.Scroll('.ui-slider', { + scrollY: true + }); +} + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.currPage = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/shops/getFloorData'), param, function(data){ + var json = WST.toJson(data); + if(json && json.catId){ + var gettpl = document.getElementById('gList').innerHTML; + laytpl(gettpl).render(json, function(html){ + $('#goods-list').append(html); + }); + $('#currPage').val(json.currPage); + WST.imgAdapt('j-imgAdapt'); + } + loading = false; + $('#Load').hide(); + }); +} + +function toShopInfo(sid){ + location.href=WST.U('wechat/shops/index',{'shopId':sid},true) +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/settlement.js b/hyhproject/wechat2/view/default/js/settlement.js new file mode 100755 index 0000000..fc50f20 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/settlement.js @@ -0,0 +1,316 @@ +jQuery.noConflict(); +function onSwitch(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); +} +/* 选择是否需要发票 */ +function isInvoice(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + $('#isInvoice').val(n);// 记录用户是否需要开发票 + $('#invoicesh').val(n); +} +/* 发票对象【个人or单位】 */ +function invOnSwitch(obj,n){ + $(obj).children('.ui-icon-push').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + $(obj).siblings().children('.ui-icon-push').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + if(n==1){ + $('.inv_hidebox').show(); + }else{ + $('.inv_hidebox').hide(); + } + $('#invoice_obj').val(n);// 记录用户所开发票对象 +} +/* 发票抬头列表绑定事件 */ +$(function(){ + $('#invoice_head').focus(function(){ + $('#inv_headlist').show(); + }) + $('#invoice_head').blur(function(){ + setTimeout(function(){ + $('#inv_headlist').hide(); + },100) + }) + // 只要用户编辑了,就视为新增 + $('#invoice_head').bind('input propertychange', function() { + $('#invoiceId').val(0); + }); +}) +/* 完成发票信息填写 */ +function saveInvoice(){ + var param={}; + var invoiceId = $('#invoiceId').val();// 发票id + param.invoiceCode = $('#invoice_code').val();// 纳税人识别码 + param.invoiceHead = $('#invoice_head').val();// 发票抬头 + var url = 'wechat/invoices/add'; + if(invoiceId>0){ + url = 'wechat/invoices/edit'; + param.id = invoiceId; + } + + if($('#invoice_obj').val()!=0){ + $.post(WST.U(url),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + setInvoiceText(); + if(invoiceId==0)$('#invoiceId').val(json.data.id) + }else{ + WST.msg(json.msg,'info'); + } + }) + }else{ + setInvoiceText(); + } +} +// 设置页面显示值 +function setInvoiceText(){ + var isInvoice = $('#isInvoice').val(); + var invoiceObj = $('#invoice_obj').val();// 发票对象 + var invoiceHead = $('#invoice_head').val();// 发票抬头 + var text = '不开发票'; + if(isInvoice==1){ + text = (invoiceObj==0)?'普通发票(纸质) 个人 明细':'普通发票(纸质)<br />'+invoiceHead+'<br />明细'; + } + $('#invoicest').html(text); + invoiceHide(); +} +function inDetermine(n){ + $('#'+n+' .wst-active').each(function(){ + type = $(this).attr('mode'); + word = $(this).attr('word'); + if(n=='payments')payCode = $(this).attr('payCode'); + }); + $('#'+n+'h').val(type); + $('#'+n+'t').html(word); + if(n=='payments'){ + $('#'+n+'w').val(payCode); + } + getCartMoney(); + dataHide(n); +} + + +//计算价格 +function getCartMoney(){ + var params = {}; + params.isUseScore = $('#scoreh').val(); + params.useScore = $('#userOrderScore').html(); + params.areaId2 = $('#areaId').val(); + params.deliverType = $('#givesh').val(); + params.sign = $('#sign').val(); + + params.couponIds = []; + $('input[id^="couponId_"]').each(function(){ + var shopId = $(this).attr('id').split('_')[1]; + params.couponIds.push(shopId+':'+$(this).val()); + }) + params.couponIds = params.couponIds.join(','); + WST.load('正在计算价格...'); + if(params.sign==1){ + $.post(WST.U('wechat/carts/getCartMoney'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + for(var key in json.shops){ + // 设置每间店铺的运费及总价格 + $('#shopF_'+key).html('¥'+json.shops[key]['freight'].toFixed(2)); + $('#shopC_'+key).html('¥'+json.shops[key]['goodsMoney'].toFixed(2)); + } + $('#totalMoney').html('¥'+json.realTotalMoney.toFixed(2)); + $('#totalPrice').val(json.realTotalMoney); + // 设置可用积分及积分可抵金额 + $('#userOrderScore').html(json.maxScore); + $('#userOrderMoney').html(json.maxScoreMoney); + } + }); + }else if(params.sign==2){//虚拟商品 + params.deliverType = 1; + $.post(WST.U('wechat/carts/getQuickCartMoney'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + json = json.data; + $('#totalMoney').html('¥'+json.realTotalMoney.toFixed(2)); + $('#totalPrice').val(json.realTotalMoney); + // 设置可用积分及积分可抵金额 + $('#userOrderScore').html(json.maxScore); + $('#userOrderMoney').html(json.maxScoreMoney); + } + }); + } +} +//提交订单 +function submitOrder(){ + var addressId = $('#addressId').val(); + if(addressId==''){ + WST.msg('请选择收货地址','info'); + return false; + } + WST.load('提交中···'); + var param = {}; + param.s_addressId = addressId; + param.s_areaId = $('#areaId').val(); + param.payType = $('#paymentsh').val(); + param.payCode = $('#paymentsw').val(); + param.isUseScore = $('#scoreh').val(); + param.useScore = $('#userOrderScore').html(); + $('.wst-se-sh .shopn').each(function(){ + shopId = $(this).attr('shopId'); + param['remark_'+shopId] = $('#remark_'+shopId).val(); + param['couponId_'+shopId] = $('#couponId_'+shopId).val(); + }); + param.deliverType = $('#givesh').val(); + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + param.invoiceClient = $('#invoice_obj').val()==1?$('#invoice_head').val():'个人'; + $('.wst-se-confirm .button').attr('disabled', 'disabled'); + $.post(WST.U('wechat/orders/submit'),param,function(data,textStatus){ + var json = WST.toJson(data); + WST.noload(); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + if(param.payType==1 && $('#totalPrice').val()>0){ + if(param.payCode=='weixinpays' || param.payCode==''){ + location.href = WST.U('wechat/weixinpays/toPay',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='wallets'){ + location.href = WST.U('wechat/wallets/payment',{"orderNo":json.data,'isBatch':1}); + } + }else{ + location.href = WST.U('wechat/orders/index'); + } + },1000); + }else{ + WST.msg(json.msg,'info'); + $('.wst-se-confirm .button').removeAttr('disabled'); + } + }); +} +//提交虚拟商品订单 +function quickSubmitOrder(){ + WST.load('提交中···'); + var param = {}; + param.payType = $('#paymentsh').val(); + param.payCode = $('#paymentsw').val(); + param.isUseScore = $('#scoreh').val(); + param.useScore = $('#userOrderScore').html(); + $('.wst-se-sh .shopn').each(function(){ + shopId = $(this).attr('shopId'); + param['remark_'+shopId] = $('#remark_'+shopId).val(); + param['couponId_'+shopId] = $('#couponId_'+shopId).val(); + }); + param.isInvoice = $('#isInvoice').val(); + param.invoiceId = $('#invoiceId').val(); + param.invoiceClient = $('#invoice_obj').val()==1?$('#invoice_head').val():'个人'; + $('.wst-se-confirm .button').attr('disabled', 'disabled'); + $.post(WST.U('wechat/orders/quickSubmit'),param,function(data,textStatus){ + var json = WST.toJson(data); + WST.noload(); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + if(param.payType==1 && $('#totalPrice').val()>0){ + if(param.payCode=='weixinpays' || param.payCode==''){ + location.href = WST.U('wechat/weixinpays/toPay',{"orderNo":json.data,'isBatch':1}); + }else if(param.payCode=='wallets'){ + location.href = WST.U('wechat/wallets/payment',{"orderNo":json.data,'isBatch':1}); + } + }else{ + location.href = WST.U('wechat/orders/index'); + } + + },1000); + }else{ + WST.msg(json.msg,'info'); + $('.wst-se-confirm .button').removeAttr('disabled'); + } + }); +} +function addAddress(type,id){ + location.href = WST.U('wechat/useraddress/index','type='+type+'&addressId='+id); +} +var dataHeight = $(".frame").css('height'); + dataHeight = parseInt(dataHeight)+50+'px'; +$(document).ready(function(){ + WST.imgAdapt('j-imgAdapt'); + $(".frame").css('bottom','-'+dataHeight); + + backPrevPage(WST.U('wechat/carts/index')); +}); +//弹框 +function dataShow(n){ + jQuery('#cover').attr("onclick","javascript:dataHide('"+n+"');").show(); + jQuery('#'+n).animate({"bottom": 0}, 500); + //显示已保存的数据 + var type = $('#'+n+'h').val(); + if(type==0){ + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'0').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + }else{ + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'1').removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + } + if(n=='payments'){ + var payCode = $('#'+n+'w').val(); + jQuery('i[class*="'+n+'"]').removeClass('ui-icon-checked-s wst-active').addClass('ui-icon-unchecked-s'); + jQuery('.'+n+'_'+payCode).removeClass('ui-icon-unchecked-s').addClass('ui-icon-checked-s wst-active'); + } + if(n=='invoices'){ + if(type==0){ + jQuery('#j-invoice').hide(); + }else{ + jQuery('#j-invoice').show(); + } + } +} +function dataHide(n){ + jQuery('#'+n).animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} +document.addEventListener('touchmove', function(event) { + //阻止背景页面滚动, + if(!jQuery("#cover").is(":hidden")){ + event.preventDefault(); + } +}) + +/*********************** 发票信息层 ****************************/ +//弹框 +function invoiceShow(){ + jQuery('#cover').attr("onclick","javascript:invoiceHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600)// 隐藏背部页面 + +} +function invoiceHide(){ + $('#shopBox').show();// 隐藏背部页面 + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getInvoiceList(){ + $.post(WST.U('wechat/invoices/pageQuery'),{},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('invoiceBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('.inv_list_item').html(html); + invoiceShow(); + // 点击抬头item + $('.inv_list_item li').click(function(){ + // 设置值 + $('#invoice_head').val($(this).html()); + $('#invoiceId').val($(this).attr('invId')); + $('#invoice_code').val($(this).attr('invCode')); + }) + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/shop_goods_list.js b/hyhproject/wechat2/view/default/js/shop_goods_list.js new file mode 100755 index 0000000..f1698ed --- /dev/null +++ b/hyhproject/wechat2/view/default/js/shop_goods_list.js @@ -0,0 +1,128 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + // 加载商品列表 + shopsList(); + // 楼层商品 + WST.imgAdapt('j-imgAdapt'); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(event){ + var wScrollY = window.scrollY; // 当前滚动条位置 + var wInnerH = window.innerHeight; // 设备窗口的高度(不会变) + var bScrollH = document.body.scrollHeight; // 滚动条总高度 + if (wScrollY + wInnerH >= bScrollH) { + var currPage = Number( $('#currPage').val() ); + var totalPage = Number( $('#totalPage').val() ); + if(currPage < totalPage ){ + shopsList(); + } + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} + + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = $('#condition').val(); + param.mdesc = $('#desc').val(); + param.goodsName = $('#keyword').val(); + param.ct1 = $('#ct1').val(); + param.ct2 = $('#ct2').val(); + + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>对不起,没有相关商品。</p>'; + html += '</div>'; + $('#shops-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +/*分类*/ +function getGoodsList(ct1,ct2){ + $('#ct2').val(''); + $('#ct1').val(ct1); + if(ct2)$('#ct2').val(ct2); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + $("#wst-shops-search").hide(); + dataHide(); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/shop_home.js b/hyhproject/wechat2/view/default/js/shop_home.js new file mode 100755 index 0000000..ffa5f04 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/shop_home.js @@ -0,0 +1,190 @@ +jQuery.noConflict(); +var loading = false; +$(function(){ + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + fixedTerm(); + shopBest(); + WST.imgAdapt('j-imgIndex'); + // 商品分类 + var h = WST.pageHeight(); + var dataHeight = $("#frame").css('height'); + if(parseInt(dataHeight)>h-42){ + $('#content').css('overflow-y','scroll').css('height',h-42); + } + $(window).scroll(function(){ + if (loading) return; + if((($(window).scrollTop()+$(window).height())+50)>=$(document).height()){ + if($('#currPage').val()<$('#totalPage').val())shopsList(); + } + }); +}); + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function showRight(obj, index){ + $(obj).addClass('wst-goodscate_selected').siblings('#goodscate').removeClass('wst-goodscate_selected'); + $('.goodscate1').eq(index).show().siblings('.goodscate1').hide(); +} + +function shopAds(){ + //广告 + var slider = new fz.Scroll('.ui-slider', { + role: 'slider', + indicator: true, + autoplay: true, + interval: 3000 + }); +} +//排序条件 +function orderCondition(obj,condition){ + jQuery('html,body').scrollTop($('#j-top').offset().top); + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('down'); + theSiblings.children('i').addClass('down').removeClass('down2'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $(obj).children('i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $(obj).children('i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $(obj).children('i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} + +//查看 +function switchTerm(n){ + if(parseInt($('#j-top').offset().top)>$(window).scrollTop()){ + jQuery('html,body').animate({scrollTop:$('#j-top').offset().top}, 800); + } + $('#j-top'+n).addClass('active').siblings('.wst-sh-term li').removeClass('active'); + if(n==1){ + $('#j-index1').show(); + $('#j-index0').hide(); + }else{ + $('#j-index0').show(); + $('#j-index1').hide(); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + } +} +function fixedTerm(){ + var offsetTop = $("#j-top").offset().top; + $(window).scroll(function() { + var scrollTop = $(window).scrollTop(); + if (scrollTop > offsetTop){ + $("#j-top").addClass('active'); + $('#j-index0').css('padding-top',45); + $('#j-index1').css('padding-top',45); + }else{ + $("#j-top").removeClass('active'); + $('#j-index0').css('padding-top',0); + $('#j-index1').css('padding-top',0); + } + }); +} + +//获取商品列表销量 +function shopBest(){ + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = 2; + param.mdesc = 1; + param.pagesize = 6; + $.post(WST.U('wechat/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopBest').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#best-list').append(html); + }); + } + WST.imgAdapt('j-imgBest'); + loading = false; + }); +} + +//获取商品列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.shopId = $('#shopId').val(); + param.msort = $('#condition').val(); + param.mdesc = $('#desc').val(); + param.goodsName = $('#keyword').val(); + param.ct1 = $('#ct1').val(); + param.ct2 = $('#ct2').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/shops/getShopGoods'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>对不起,没有相关商品。</p>'; + html += '</div>'; + $('#shops-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +/*分类*/ +function getGoodsList(ct1,ct2){ + $('#ct2').val(''); + $('#ct1').val(ct1); + if(ct2)$('#ct2').val(ct2); + $('#currPage').val('0'); + $('#shops-list').html(''); + shopsList(); + $("#wst-shops-search").hide(); + dataHide(); + switchTerm(0); +} + +function toShopInfo(sid){ + location.href=WST.U('wechat/shops/index',{'shopId':sid},true) +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/shops_list.js b/hyhproject/wechat2/view/default/js/shops_list.js new file mode 100755 index 0000000..6236c9d --- /dev/null +++ b/hyhproject/wechat2/view/default/js/shops_list.js @@ -0,0 +1,124 @@ +//排序条件 +function orderCondition(obj,condition){ + var classContent = $(obj).attr('class'); + var status = $(obj).attr('status'); + var theSiblings = $(obj).siblings('.sorts'); + theSiblings.removeClass('active').attr('status','down'); + $(obj).addClass('active'); + $('.wst-shl-select').removeClass('active'); + if(classContent.indexOf('active')==-1){ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('down'); + } + if(status.indexOf('down')>-1){ + if(classContent.indexOf('active')==-1){ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('up2'); + $('#desc').val('0'); + }else{ + $('.wst-shl-head .evaluate i').addClass('up2').removeClass('down2'); + $(obj).attr('status','up'); + $('#desc').val('1'); + } + }else{ + $('.wst-shl-head .evaluate i').addClass('down2').removeClass('up2'); + $(obj).attr('status','down'); + $('#desc').val('0'); + } + $('#condition').val(condition);//排序条件 + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +function orderSelect(id){ + $('.wst-shl-select').addClass('active'); + $('.evaluate .choice').removeClass('active'); + $('.wst-shl-head .evaluate i').addClass('down').removeClass('down2'); + $('#catId').val(id); + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +function searchCondition(id){ + $("#wst-shops-search").hide(); + $('#catId').val(id); + $('#currPage').val('0');//当前页归零 + $('#shops-list').html(''); + shopsList(); +} +//获取店铺列表 +function shopsList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.id = $('#catId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#keyword').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/shops/pageQuery'), param,function(data){ + var json = WST.toJson(data); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shops-list').append(html); + }); + imgShop('j-imgAdapt'); + imgShop('goods-item'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter('home'); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + + if($('.wst-shl-ads a').hasClass("adsImg")){ + //中间小广告 + new Swiper('.swiper-container', { + slidesPerView: 3, + freeMode : true, + spaceBetween: 0, + autoplay : 2000, + speed:1200, + loop : true, + autoplayDisableOnInteraction : false, + onSlideChangeEnd: function(swiper){ + echo.init();//图片懒加载 + } + }); + }else{ + $('.wst-shl-ads').hide(); + } + shopsList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + shopsList(); + } + } + }); +}); +function goShopHome(sid){ + location.href=WST.U('wechat/shops/home','shopId='+sid,true); +} +//适应图片大小正方形 +function imgShop(name){ + var w = $('.'+name).width(); + if(name == 'j-imgAdapt'){ + $('.'+name).css({"width": w+"px","height": w+"px"}); + }else{ + $('.'+name).css({"width": w+"px","height": w+20+"px"}); + } + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a .goodsPrice').css({"width": w+"px"}); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/js/swiper.jquery.min.js b/hyhproject/wechat2/view/default/js/swiper.jquery.min.js new file mode 100755 index 0000000..ca9f537 --- /dev/null +++ b/hyhproject/wechat2/view/default/js/swiper.jquery.min.js @@ -0,0 +1,16 @@ +/** + * Swiper 3.1.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2015, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: August 22, 2015 + */ +!function(){"use strict";function e(e){e.fn.swiper=function(a){var s;return e(this).each(function(){var e=new t(this,a);s||(s=e)}),s}}var a,t=function(e,s){function r(){return"horizontal"===v.params.direction}function i(e){return Math.floor(e)}function n(){v.autoplayTimeoutId=setTimeout(function(){v.params.loop?(v.fixLoop(),v._slideNext()):v.isEnd?s.autoplayStopOnLast?v.stopAutoplay():v._slideTo(0):v._slideNext()},v.params.autoplay)}function o(e,t){var s=a(e.target);if(!s.is(t))if("string"==typeof t)s=s.parents(t);else if(t.nodeType){var r;return s.parents().each(function(e,a){a===t&&(r=t)}),r?t:void 0}return 0===s.length?void 0:s[0]}function l(e,a){a=a||{};var t=window.MutationObserver||window.WebkitMutationObserver,s=new t(function(e){e.forEach(function(e){v.onResize(!0),v.emit("onObserverUpdate",v,e)})});s.observe(e,{attributes:"undefined"==typeof a.attributes?!0:a.attributes,childList:"undefined"==typeof a.childList?!0:a.childList,characterData:"undefined"==typeof a.characterData?!0:a.characterData}),v.observers.push(s)}function p(e){e.originalEvent&&(e=e.originalEvent);var a=e.keyCode||e.charCode;if(!v.params.allowSwipeToNext&&(r()&&39===a||!r()&&40===a))return!1;if(!v.params.allowSwipeToPrev&&(r()&&37===a||!r()&&38===a))return!1;if(!(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||document.activeElement&&document.activeElement.nodeName&&("input"===document.activeElement.nodeName.toLowerCase()||"textarea"===document.activeElement.nodeName.toLowerCase()))){if(37===a||39===a||38===a||40===a){var t=!1;if(v.container.parents(".swiper-slide").length>0&&0===v.container.parents(".swiper-slide-active").length)return;var s={left:window.pageXOffset,top:window.pageYOffset},i=window.innerWidth,n=window.innerHeight,o=v.container.offset();v.rtl&&(o.left=o.left-v.container[0].scrollLeft);for(var l=[[o.left,o.top],[o.left+v.width,o.top],[o.left,o.top+v.height],[o.left+v.width,o.top+v.height]],p=0;p<l.length;p++){var d=l[p];d[0]>=s.left&&d[0]<=s.left+i&&d[1]>=s.top&&d[1]<=s.top+n&&(t=!0)}if(!t)return}r()?((37===a||39===a)&&(e.preventDefault?e.preventDefault():e.returnValue=!1),(39===a&&!v.rtl||37===a&&v.rtl)&&v.slideNext(),(37===a&&!v.rtl||39===a&&v.rtl)&&v.slidePrev()):((38===a||40===a)&&(e.preventDefault?e.preventDefault():e.returnValue=!1),40===a&&v.slideNext(),38===a&&v.slidePrev())}}function d(e){e.originalEvent&&(e=e.originalEvent);var a=v.mousewheel.event,t=0;if(e.detail)t=-e.detail;else if("mousewheel"===a)if(v.params.mousewheelForceToAxis)if(r()){if(!(Math.abs(e.wheelDeltaX)>Math.abs(e.wheelDeltaY)))return;t=e.wheelDeltaX}else{if(!(Math.abs(e.wheelDeltaY)>Math.abs(e.wheelDeltaX)))return;t=e.wheelDeltaY}else t=e.wheelDelta;else if("DOMMouseScroll"===a)t=-e.detail;else if("wheel"===a)if(v.params.mousewheelForceToAxis)if(r()){if(!(Math.abs(e.deltaX)>Math.abs(e.deltaY)))return;t=-e.deltaX}else{if(!(Math.abs(e.deltaY)>Math.abs(e.deltaX)))return;t=-e.deltaY}else t=Math.abs(e.deltaX)>Math.abs(e.deltaY)?-e.deltaX:-e.deltaY;if(v.params.mousewheelInvert&&(t=-t),v.params.freeMode){var s=v.getWrapperTranslate()+t*v.params.mousewheelSensitivity;if(s>0&&(s=0),s<v.maxTranslate()&&(s=v.maxTranslate()),v.setWrapperTransition(0),v.setWrapperTranslate(s),v.updateProgress(),v.updateActiveIndex(),v.params.freeModeSticky&&(clearTimeout(v.mousewheel.timeout),v.mousewheel.timeout=setTimeout(function(){v.slideReset()},300)),0===s||s===v.maxTranslate())return}else{if((new window.Date).getTime()-v.mousewheel.lastScrollTime>60)if(0>t)if(v.isEnd&&!v.params.loop||v.animating){if(v.params.mousewheelReleaseOnEdges)return!0}else v.slideNext();else if(v.isBeginning&&!v.params.loop||v.animating){if(v.params.mousewheelReleaseOnEdges)return!0}else v.slidePrev();v.mousewheel.lastScrollTime=(new window.Date).getTime()}return v.params.autoplay&&v.stopAutoplay(),e.preventDefault?e.preventDefault():e.returnValue=!1,!1}function u(e,t){e=a(e);var s,i,n;s=e.attr("data-swiper-parallax")||"0",i=e.attr("data-swiper-parallax-x"),n=e.attr("data-swiper-parallax-y"),i||n?(i=i||"0",n=n||"0"):r()?(i=s,n="0"):(n=s,i="0"),i=i.indexOf("%")>=0?parseInt(i,10)*t+"%":i*t+"px",n=n.indexOf("%")>=0?parseInt(n,10)*t+"%":n*t+"px",e.transform("translate3d("+i+", "+n+",0px)")}function c(e){return 0!==e.indexOf("on")&&(e=e[0]!==e[0].toUpperCase()?"on"+e[0].toUpperCase()+e.substring(1):"on"+e),e}if(!(this instanceof t))return new t(e,s);var m={direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,autoplay:!1,autoplayDisableOnInteraction:!0,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeSticky:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},cube:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fade:{crossFade:!1},parallax:!1,scrollbar:null,scrollbarHide:!0,keyboardControl:!1,mousewheelControl:!1,mousewheelReleaseOnEdges:!1,mousewheelInvert:!1,mousewheelForceToAxis:!1,mousewheelSensitivity:1,hashnav:!1,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,onlyExternal:!1,threshold:0,touchMoveStopPropagation:!0,pagination:null,paginationElement:"span",paginationClickable:!1,paginationHide:!1,paginationBulletRender:null,resistance:!0,resistanceRatio:.85,nextButton:null,prevButton:null,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,lazyLoading:!1,lazyLoadingInPrevNext:!1,lazyLoadingOnTransitionStart:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,control:void 0,controlInverse:!1,controlBy:"slide",allowSwipeToPrev:!0,allowSwipeToNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",slideClass:"swiper-slide",slideActiveClass:"swiper-slide-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slidePrevClass:"swiper-slide-prev",wrapperClass:"swiper-wrapper",bulletClass:"swiper-pagination-bullet",bulletActiveClass:"swiper-pagination-bullet-active",buttonDisabledClass:"swiper-button-disabled",paginationHiddenClass:"swiper-pagination-hidden",observer:!1,observeParents:!1,a11y:!1,prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}",runCallbacksOnInit:!0},f=s&&s.virtualTranslate;s=s||{};for(var h in m)if("undefined"==typeof s[h])s[h]=m[h];else if("object"==typeof s[h])for(var g in m[h])"undefined"==typeof s[h][g]&&(s[h][g]=m[h][g]);var v=this;if(v.version="3.1.0",v.params=s,v.classNames=[],"undefined"!=typeof a&&"undefined"!=typeof Dom7&&(a=Dom7),("undefined"!=typeof a||(a="undefined"==typeof Dom7?window.Dom7||window.Zepto||window.jQuery:Dom7))&&(v.$=a,v.container=a(e),0!==v.container.length)){if(v.container.length>1)return void v.container.each(function(){new t(this,s)});v.container[0].swiper=v,v.container.data("swiper",v),v.classNames.push("swiper-container-"+v.params.direction),v.params.freeMode&&v.classNames.push("swiper-container-free-mode"),v.support.flexbox||(v.classNames.push("swiper-container-no-flexbox"),v.params.slidesPerColumn=1),(v.params.parallax||v.params.watchSlidesVisibility)&&(v.params.watchSlidesProgress=!0),["cube","coverflow"].indexOf(v.params.effect)>=0&&(v.support.transforms3d?(v.params.watchSlidesProgress=!0,v.classNames.push("swiper-container-3d")):v.params.effect="slide"),"slide"!==v.params.effect&&v.classNames.push("swiper-container-"+v.params.effect),"cube"===v.params.effect&&(v.params.resistanceRatio=0,v.params.slidesPerView=1,v.params.slidesPerColumn=1,v.params.slidesPerGroup=1,v.params.centeredSlides=!1,v.params.spaceBetween=0,v.params.virtualTranslate=!0,v.params.setWrapperSize=!1),"fade"===v.params.effect&&(v.params.slidesPerView=1,v.params.slidesPerColumn=1,v.params.slidesPerGroup=1,v.params.watchSlidesProgress=!0,v.params.spaceBetween=0,"undefined"==typeof f&&(v.params.virtualTranslate=!0)),v.params.grabCursor&&v.support.touch&&(v.params.grabCursor=!1),v.wrapper=v.container.children("."+v.params.wrapperClass),v.params.pagination&&(v.paginationContainer=a(v.params.pagination),v.params.paginationClickable&&v.paginationContainer.addClass("swiper-pagination-clickable")),v.rtl=r()&&("rtl"===v.container[0].dir.toLowerCase()||"rtl"===v.container.css("direction")),v.rtl&&v.classNames.push("swiper-container-rtl"),v.rtl&&(v.wrongRTL="-webkit-box"===v.wrapper.css("display")),v.params.slidesPerColumn>1&&v.classNames.push("swiper-container-multirow"),v.device.android&&v.classNames.push("swiper-container-android"),v.container.addClass(v.classNames.join(" ")),v.translate=0,v.progress=0,v.velocity=0,v.lockSwipeToNext=function(){v.params.allowSwipeToNext=!1},v.lockSwipeToPrev=function(){v.params.allowSwipeToPrev=!1},v.lockSwipes=function(){v.params.allowSwipeToNext=v.params.allowSwipeToPrev=!1},v.unlockSwipeToNext=function(){v.params.allowSwipeToNext=!0},v.unlockSwipeToPrev=function(){v.params.allowSwipeToPrev=!0},v.unlockSwipes=function(){v.params.allowSwipeToNext=v.params.allowSwipeToPrev=!0},v.params.grabCursor&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grab",v.container[0].style.cursor="-moz-grab",v.container[0].style.cursor="grab"),v.imagesToLoad=[],v.imagesLoaded=0,v.loadImage=function(e,a,t,s){function r(){s&&s()}var i;e.complete&&t?r():a?(i=new window.Image,i.onload=r,i.onerror=r,i.src=a):r()},v.preloadImages=function(){function e(){"undefined"!=typeof v&&null!==v&&(void 0!==v.imagesLoaded&&v.imagesLoaded++,v.imagesLoaded===v.imagesToLoad.length&&(v.params.updateOnImagesReady&&v.update(),v.emit("onImagesReady",v)))}v.imagesToLoad=v.container.find("img");for(var a=0;a<v.imagesToLoad.length;a++)v.loadImage(v.imagesToLoad[a],v.imagesToLoad[a].currentSrc||v.imagesToLoad[a].getAttribute("src"),!0,e)},v.autoplayTimeoutId=void 0,v.autoplaying=!1,v.autoplayPaused=!1,v.startAutoplay=function(){return"undefined"!=typeof v.autoplayTimeoutId?!1:v.params.autoplay?v.autoplaying?!1:(v.autoplaying=!0,v.emit("onAutoplayStart",v),void n()):!1},v.stopAutoplay=function(e){v.autoplayTimeoutId&&(v.autoplayTimeoutId&&clearTimeout(v.autoplayTimeoutId),v.autoplaying=!1,v.autoplayTimeoutId=void 0,v.emit("onAutoplayStop",v))},v.pauseAutoplay=function(e){v.autoplayPaused||(v.autoplayTimeoutId&&clearTimeout(v.autoplayTimeoutId),v.autoplayPaused=!0,0===e?(v.autoplayPaused=!1,n()):v.wrapper.transitionEnd(function(){v&&(v.autoplayPaused=!1,v.autoplaying?n():v.stopAutoplay())}))},v.minTranslate=function(){return-v.snapGrid[0]},v.maxTranslate=function(){return-v.snapGrid[v.snapGrid.length-1]},v.updateContainerSize=function(){var e,a;e="undefined"!=typeof v.params.width?v.params.width:v.container[0].clientWidth,a="undefined"!=typeof v.params.height?v.params.height:v.container[0].clientHeight,0===e&&r()||0===a&&!r()||(e=e-parseInt(v.container.css("padding-left"),10)-parseInt(v.container.css("padding-right"),10),a=a-parseInt(v.container.css("padding-top"),10)-parseInt(v.container.css("padding-bottom"),10),v.width=e,v.height=a,v.size=r()?v.width:v.height)},v.updateSlidesSize=function(){v.slides=v.wrapper.children("."+v.params.slideClass),v.snapGrid=[],v.slidesGrid=[],v.slidesSizesGrid=[];var e,a=v.params.spaceBetween,t=-v.params.slidesOffsetBefore,s=0,n=0;"string"==typeof a&&a.indexOf("%")>=0&&(a=parseFloat(a.replace("%",""))/100*v.size),v.virtualSize=-a,v.slides.css(v.rtl?{marginLeft:"",marginTop:""}:{marginRight:"",marginBottom:""});var o;v.params.slidesPerColumn>1&&(o=Math.floor(v.slides.length/v.params.slidesPerColumn)===v.slides.length/v.params.slidesPerColumn?v.slides.length:Math.ceil(v.slides.length/v.params.slidesPerColumn)*v.params.slidesPerColumn);var l,p=v.params.slidesPerColumn,d=o/p,u=d-(v.params.slidesPerColumn*d-v.slides.length);for(e=0;e<v.slides.length;e++){l=0;var c=v.slides.eq(e);if(v.params.slidesPerColumn>1){var m,f,h;"column"===v.params.slidesPerColumnFill?(f=Math.floor(e/p),h=e-f*p,(f>u||f===u&&h===p-1)&&++h>=p&&(h=0,f++),m=f+h*o/p,c.css({"-webkit-box-ordinal-group":m,"-moz-box-ordinal-group":m,"-ms-flex-order":m,"-webkit-order":m,order:m})):(h=Math.floor(e/d),f=e-h*d),c.css({"margin-top":0!==h&&v.params.spaceBetween&&v.params.spaceBetween+"px"}).attr("data-swiper-column",f).attr("data-swiper-row",h)}"none"!==c.css("display")&&("auto"===v.params.slidesPerView?(l=r()?c.outerWidth(!0):c.outerHeight(!0),v.params.roundLengths&&(l=i(l))):(l=(v.size-(v.params.slidesPerView-1)*a)/v.params.slidesPerView,v.params.roundLengths&&(l=i(l)),r()?v.slides[e].style.width=l+"px":v.slides[e].style.height=l+"px"),v.slides[e].swiperSlideSize=l,v.slidesSizesGrid.push(l),v.params.centeredSlides?(t=t+l/2+s/2+a,0===e&&(t=t-v.size/2-a),Math.abs(t)<.001&&(t=0),n%v.params.slidesPerGroup===0&&v.snapGrid.push(t),v.slidesGrid.push(t)):(n%v.params.slidesPerGroup===0&&v.snapGrid.push(t),v.slidesGrid.push(t),t=t+l+a),v.virtualSize+=l+a,s=l,n++)}v.virtualSize=Math.max(v.virtualSize,v.size)+v.params.slidesOffsetAfter;var g;if(v.rtl&&v.wrongRTL&&("slide"===v.params.effect||"coverflow"===v.params.effect)&&v.wrapper.css({width:v.virtualSize+v.params.spaceBetween+"px"}),(!v.support.flexbox||v.params.setWrapperSize)&&v.wrapper.css(r()?{width:v.virtualSize+v.params.spaceBetween+"px"}:{height:v.virtualSize+v.params.spaceBetween+"px"}),v.params.slidesPerColumn>1&&(v.virtualSize=(l+v.params.spaceBetween)*o,v.virtualSize=Math.ceil(v.virtualSize/v.params.slidesPerColumn)-v.params.spaceBetween,v.wrapper.css({width:v.virtualSize+v.params.spaceBetween+"px"}),v.params.centeredSlides)){for(g=[],e=0;e<v.snapGrid.length;e++)v.snapGrid[e]<v.virtualSize+v.snapGrid[0]&&g.push(v.snapGrid[e]);v.snapGrid=g}if(!v.params.centeredSlides){for(g=[],e=0;e<v.snapGrid.length;e++)v.snapGrid[e]<=v.virtualSize-v.size&&g.push(v.snapGrid[e]);v.snapGrid=g,Math.floor(v.virtualSize-v.size)>Math.floor(v.snapGrid[v.snapGrid.length-1])&&v.snapGrid.push(v.virtualSize-v.size)}0===v.snapGrid.length&&(v.snapGrid=[0]),0!==v.params.spaceBetween&&v.slides.css(r()?v.rtl?{marginLeft:a+"px"}:{marginRight:a+"px"}:{marginBottom:a+"px"}),v.params.watchSlidesProgress&&v.updateSlidesOffset()},v.updateSlidesOffset=function(){for(var e=0;e<v.slides.length;e++)v.slides[e].swiperSlideOffset=r()?v.slides[e].offsetLeft:v.slides[e].offsetTop},v.updateSlidesProgress=function(e){if("undefined"==typeof e&&(e=v.translate||0),0!==v.slides.length){"undefined"==typeof v.slides[0].swiperSlideOffset&&v.updateSlidesOffset();var a=-e;v.rtl&&(a=e);{v.container[0].getBoundingClientRect(),r()?"left":"top",r()?"right":"bottom"}v.slides.removeClass(v.params.slideVisibleClass);for(var t=0;t<v.slides.length;t++){var s=v.slides[t],i=(a-s.swiperSlideOffset)/(s.swiperSlideSize+v.params.spaceBetween);if(v.params.watchSlidesVisibility){var n=-(a-s.swiperSlideOffset),o=n+v.slidesSizesGrid[t],l=n>=0&&n<v.size||o>0&&o<=v.size||0>=n&&o>=v.size;l&&v.slides.eq(t).addClass(v.params.slideVisibleClass)}s.progress=v.rtl?-i:i}}},v.updateProgress=function(e){"undefined"==typeof e&&(e=v.translate||0);var a=v.maxTranslate()-v.minTranslate();0===a?(v.progress=0,v.isBeginning=v.isEnd=!0):(v.progress=(e-v.minTranslate())/a,v.isBeginning=v.progress<=0,v.isEnd=v.progress>=1),v.isBeginning&&v.emit("onReachBeginning",v),v.isEnd&&v.emit("onReachEnd",v),v.params.watchSlidesProgress&&v.updateSlidesProgress(e),v.emit("onProgress",v,v.progress)},v.updateActiveIndex=function(){var e,a,t,s=v.rtl?v.translate:-v.translate;for(a=0;a<v.slidesGrid.length;a++)"undefined"!=typeof v.slidesGrid[a+1]?s>=v.slidesGrid[a]&&s<v.slidesGrid[a+1]-(v.slidesGrid[a+1]-v.slidesGrid[a])/2?e=a:s>=v.slidesGrid[a]&&s<v.slidesGrid[a+1]&&(e=a+1):s>=v.slidesGrid[a]&&(e=a);(0>e||"undefined"==typeof e)&&(e=0),t=Math.floor(e/v.params.slidesPerGroup),t>=v.snapGrid.length&&(t=v.snapGrid.length-1),e!==v.activeIndex&&(v.snapIndex=t,v.previousIndex=v.activeIndex,v.activeIndex=e,v.updateClasses())},v.updateClasses=function(){v.slides.removeClass(v.params.slideActiveClass+" "+v.params.slideNextClass+" "+v.params.slidePrevClass);var e=v.slides.eq(v.activeIndex);if(e.addClass(v.params.slideActiveClass),e.next("."+v.params.slideClass).addClass(v.params.slideNextClass),e.prev("."+v.params.slideClass).addClass(v.params.slidePrevClass),v.bullets&&v.bullets.length>0){v.bullets.removeClass(v.params.bulletActiveClass);var t;v.params.loop?(t=Math.ceil(v.activeIndex-v.loopedSlides)/v.params.slidesPerGroup,t>v.slides.length-1-2*v.loopedSlides&&(t-=v.slides.length-2*v.loopedSlides),t>v.bullets.length-1&&(t-=v.bullets.length)):t="undefined"!=typeof v.snapIndex?v.snapIndex:v.activeIndex||0,v.paginationContainer.length>1?v.bullets.each(function(){a(this).index()===t&&a(this).addClass(v.params.bulletActiveClass)}):v.bullets.eq(t).addClass(v.params.bulletActiveClass)}v.params.loop||(v.params.prevButton&&(v.isBeginning?(a(v.params.prevButton).addClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.disable(a(v.params.prevButton))):(a(v.params.prevButton).removeClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.enable(a(v.params.prevButton)))),v.params.nextButton&&(v.isEnd?(a(v.params.nextButton).addClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.disable(a(v.params.nextButton))):(a(v.params.nextButton).removeClass(v.params.buttonDisabledClass),v.params.a11y&&v.a11y&&v.a11y.enable(a(v.params.nextButton)))))},v.updatePagination=function(){if(v.params.pagination&&v.paginationContainer&&v.paginationContainer.length>0){for(var e="",a=v.params.loop?Math.ceil((v.slides.length-2*v.loopedSlides)/v.params.slidesPerGroup):v.snapGrid.length,t=0;a>t;t++)e+=v.params.paginationBulletRender?v.params.paginationBulletRender(t,v.params.bulletClass):"<"+v.params.paginationElement+' class="'+v.params.bulletClass+'"></'+v.params.paginationElement+">";v.paginationContainer.html(e),v.bullets=v.paginationContainer.find("."+v.params.bulletClass),v.params.paginationClickable&&v.params.a11y&&v.a11y&&v.a11y.initPagination()}},v.update=function(e){function a(){s=Math.min(Math.max(v.translate,v.maxTranslate()),v.minTranslate()),v.setWrapperTranslate(s),v.updateActiveIndex(),v.updateClasses()}if(v.updateContainerSize(),v.updateSlidesSize(),v.updateProgress(),v.updatePagination(),v.updateClasses(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),e){var t,s;v.controller&&v.controller.spline&&(v.controller.spline=void 0),v.params.freeMode?a():(t=("auto"===v.params.slidesPerView||v.params.slidesPerView>1)&&v.isEnd&&!v.params.centeredSlides?v.slideTo(v.slides.length-1,0,!1,!0):v.slideTo(v.activeIndex,0,!1,!0),t||a())}},v.onResize=function(e){var a=v.params.allowSwipeToPrev,t=v.params.allowSwipeToNext;if(v.params.allowSwipeToPrev=v.params.allowSwipeToNext=!0,v.updateContainerSize(),v.updateSlidesSize(),("auto"===v.params.slidesPerView||v.params.freeMode||e)&&v.updatePagination(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),v.controller&&v.controller.spline&&(v.controller.spline=void 0),v.params.freeMode){var s=Math.min(Math.max(v.translate,v.maxTranslate()),v.minTranslate());v.setWrapperTranslate(s),v.updateActiveIndex(),v.updateClasses()}else v.updateClasses(),("auto"===v.params.slidesPerView||v.params.slidesPerView>1)&&v.isEnd&&!v.params.centeredSlides?v.slideTo(v.slides.length-1,0,!1,!0):v.slideTo(v.activeIndex,0,!1,!0);v.params.allowSwipeToPrev=a,v.params.allowSwipeToNext=t};var w=["mousedown","mousemove","mouseup"];window.navigator.pointerEnabled?w=["pointerdown","pointermove","pointerup"]:window.navigator.msPointerEnabled&&(w=["MSPointerDown","MSPointerMove","MSPointerUp"]),v.touchEvents={start:v.support.touch||!v.params.simulateTouch?"touchstart":w[0],move:v.support.touch||!v.params.simulateTouch?"touchmove":w[1],end:v.support.touch||!v.params.simulateTouch?"touchend":w[2]},(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&("container"===v.params.touchEventsTarget?v.container:v.wrapper).addClass("swiper-wp8-"+v.params.direction),v.initEvents=function(e){var t=e?"off":"on",r=e?"removeEventListener":"addEventListener",i="container"===v.params.touchEventsTarget?v.container[0]:v.wrapper[0],n=v.support.touch?i:document,o=v.params.nested?!0:!1;v.browser.ie?(i[r](v.touchEvents.start,v.onTouchStart,!1),n[r](v.touchEvents.move,v.onTouchMove,o),n[r](v.touchEvents.end,v.onTouchEnd,!1)):(v.support.touch&&(i[r](v.touchEvents.start,v.onTouchStart,!1),i[r](v.touchEvents.move,v.onTouchMove,o),i[r](v.touchEvents.end,v.onTouchEnd,!1)),!s.simulateTouch||v.device.ios||v.device.android||(i[r]("mousedown",v.onTouchStart,!1),document[r]("mousemove",v.onTouchMove,o),document[r]("mouseup",v.onTouchEnd,!1))),window[r]("resize",v.onResize),v.params.nextButton&&(a(v.params.nextButton)[t]("click",v.onClickNext),v.params.a11y&&v.a11y&&a(v.params.nextButton)[t]("keydown",v.a11y.onEnterKey)),v.params.prevButton&&(a(v.params.prevButton)[t]("click",v.onClickPrev),v.params.a11y&&v.a11y&&a(v.params.prevButton)[t]("keydown",v.a11y.onEnterKey)),v.params.pagination&&v.params.paginationClickable&&(a(v.paginationContainer)[t]("click","."+v.params.bulletClass,v.onClickIndex),v.params.a11y&&v.a11y&&a(v.paginationContainer)[t]("keydown","."+v.params.bulletClass,v.a11y.onEnterKey)),(v.params.preventClicks||v.params.preventClicksPropagation)&&i[r]("click",v.preventClicks,!0)},v.attachEvents=function(e){v.initEvents()},v.detachEvents=function(){v.initEvents(!0)},v.allowClick=!0,v.preventClicks=function(e){v.allowClick||(v.params.preventClicks&&e.preventDefault(),v.params.preventClicksPropagation&&v.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))},v.onClickNext=function(e){e.preventDefault(),(!v.isEnd||v.params.loop)&&v.slideNext()},v.onClickPrev=function(e){e.preventDefault(),(!v.isBeginning||v.params.loop)&&v.slidePrev()},v.onClickIndex=function(e){e.preventDefault();var t=a(this).index()*v.params.slidesPerGroup;v.params.loop&&(t+=v.loopedSlides),v.slideTo(t)},v.updateClickedSlide=function(e){var t=o(e,"."+v.params.slideClass),s=!1;if(t)for(var r=0;r<v.slides.length;r++)v.slides[r]===t&&(s=!0);if(!t||!s)return v.clickedSlide=void 0,void(v.clickedIndex=void 0);if(v.clickedSlide=t,v.clickedIndex=a(t).index(),v.params.slideToClickedSlide&&void 0!==v.clickedIndex&&v.clickedIndex!==v.activeIndex){var i,n=v.clickedIndex;if(v.params.loop)if(i=a(v.clickedSlide).attr("data-swiper-slide-index"),n>v.slides.length-v.params.slidesPerView)v.fixLoop(),n=v.wrapper.children("."+v.params.slideClass+'[data-swiper-slide-index="'+i+'"]').eq(0).index(),setTimeout(function(){v.slideTo(n)},0);else if(n<v.params.slidesPerView-1){v.fixLoop();var l=v.wrapper.children("."+v.params.slideClass+'[data-swiper-slide-index="'+i+'"]');n=l.eq(l.length-1).index(),setTimeout(function(){v.slideTo(n)},0)}else v.slideTo(n);else v.slideTo(n)}};var y,x,b,T,S,C,M,P,z,I="input, select, textarea, button",E=Date.now(),k=[];v.animating=!1,v.touches={startX:0,startY:0,currentX:0,currentY:0,diff:0};var D,G;if(v.onTouchStart=function(e){if(e.originalEvent&&(e=e.originalEvent),D="touchstart"===e.type,D||!("which"in e)||3!==e.which){if(v.params.noSwiping&&o(e,"."+v.params.noSwipingClass))return void(v.allowClick=!0);if(!v.params.swipeHandler||o(e,v.params.swipeHandler)){var t=v.touches.currentX="touchstart"===e.type?e.targetTouches[0].pageX:e.pageX,s=v.touches.currentY="touchstart"===e.type?e.targetTouches[0].pageY:e.pageY;if(!(v.device.ios&&v.params.iOSEdgeSwipeDetection&&t<=v.params.iOSEdgeSwipeThreshold)){if(y=!0,x=!1,T=void 0,G=void 0,v.touches.startX=t,v.touches.startY=s,b=Date.now(),v.allowClick=!0,v.updateContainerSize(),v.swipeDirection=void 0,v.params.threshold>0&&(M=!1),"touchstart"!==e.type){var r=!0;a(e.target).is(I)&&(r=!1),document.activeElement&&a(document.activeElement).is(I)&&document.activeElement.blur(),r&&e.preventDefault()}v.emit("onTouchStart",v,e)}}}},v.onTouchMove=function(e){if(e.originalEvent&&(e=e.originalEvent),!(D&&"mousemove"===e.type||e.preventedByNestedSwiper)){if(v.params.onlyExternal)return v.allowClick=!1,void(y&&(v.touches.startX=v.touches.currentX="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,v.touches.startY=v.touches.currentY="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,b=Date.now()));if(D&&document.activeElement&&e.target===document.activeElement&&a(e.target).is(I))return x=!0,void(v.allowClick=!1);if(v.emit("onTouchMove",v,e),!(e.targetTouches&&e.targetTouches.length>1)){if(v.touches.currentX="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,v.touches.currentY="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,"undefined"==typeof T){var t=180*Math.atan2(Math.abs(v.touches.currentY-v.touches.startY),Math.abs(v.touches.currentX-v.touches.startX))/Math.PI;T=r()?t>v.params.touchAngle:90-t>v.params.touchAngle}if(T&&v.emit("onTouchMoveOpposite",v,e),"undefined"==typeof G&&v.browser.ieTouch&&(v.touches.currentX!==v.touches.startX||v.touches.currentY!==v.touches.startY)&&(G=!0),y){if(T)return void(y=!1);if(G||!v.browser.ieTouch){v.allowClick=!1,v.emit("onSliderMove",v,e),e.preventDefault(),v.params.touchMoveStopPropagation&&!v.params.nested&&e.stopPropagation(),x||(s.loop&&v.fixLoop(),C=v.getWrapperTranslate(),v.setWrapperTransition(0),v.animating&&v.wrapper.trigger("webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd"),v.params.autoplay&&v.autoplaying&&(v.params.autoplayDisableOnInteraction?v.stopAutoplay():v.pauseAutoplay()),z=!1,v.params.grabCursor&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grabbing",v.container[0].style.cursor="-moz-grabbin",v.container[0].style.cursor="grabbing")),x=!0;var i=v.touches.diff=r()?v.touches.currentX-v.touches.startX:v.touches.currentY-v.touches.startY;i*=v.params.touchRatio,v.rtl&&(i=-i),v.swipeDirection=i>0?"prev":"next",S=i+C;var n=!0;if(i>0&&S>v.minTranslate()?(n=!1,v.params.resistance&&(S=v.minTranslate()-1+Math.pow(-v.minTranslate()+C+i,v.params.resistanceRatio))):0>i&&S<v.maxTranslate()&&(n=!1,v.params.resistance&&(S=v.maxTranslate()+1-Math.pow(v.maxTranslate()-C-i,v.params.resistanceRatio))),n&&(e.preventedByNestedSwiper=!0),!v.params.allowSwipeToNext&&"next"===v.swipeDirection&&C>S&&(S=C),!v.params.allowSwipeToPrev&&"prev"===v.swipeDirection&&S>C&&(S=C),v.params.followFinger){if(v.params.threshold>0){if(!(Math.abs(i)>v.params.threshold||M))return void(S=C);if(!M)return M=!0,v.touches.startX=v.touches.currentX,v.touches.startY=v.touches.currentY,S=C,void(v.touches.diff=r()?v.touches.currentX-v.touches.startX:v.touches.currentY-v.touches.startY)}(v.params.freeMode||v.params.watchSlidesProgress)&&v.updateActiveIndex(),v.params.freeMode&&(0===k.length&&k.push({position:v.touches[r()?"startX":"startY"],time:b}),k.push({position:v.touches[r()?"currentX":"currentY"],time:(new window.Date).getTime()})),v.updateProgress(S),v.setWrapperTranslate(S)}}}}}},v.onTouchEnd=function(e){if(e.originalEvent&&(e=e.originalEvent),v.emit("onTouchEnd",v,e),y){v.params.grabCursor&&x&&y&&(v.container[0].style.cursor="move",v.container[0].style.cursor="-webkit-grab",v.container[0].style.cursor="-moz-grab",v.container[0].style.cursor="grab");var t=Date.now(),s=t-b;if(v.allowClick&&(v.updateClickedSlide(e),v.emit("onTap",v,e),300>s&&t-E>300&&(P&&clearTimeout(P),P=setTimeout(function(){v&&(v.params.paginationHide&&v.paginationContainer.length>0&&!a(e.target).hasClass(v.params.bulletClass)&&v.paginationContainer.toggleClass(v.params.paginationHiddenClass),v.emit("onClick",v,e))},300)),300>s&&300>t-E&&(P&&clearTimeout(P),v.emit("onDoubleTap",v,e))),E=Date.now(),setTimeout(function(){v&&(v.allowClick=!0)},0),!y||!x||!v.swipeDirection||0===v.touches.diff||S===C)return void(y=x=!1);y=x=!1;var r;if(r=v.params.followFinger?v.rtl?v.translate:-v.translate:-S,v.params.freeMode){if(r<-v.minTranslate())return void v.slideTo(v.activeIndex);if(r>-v.maxTranslate())return void v.slideTo(v.slides.length<v.snapGrid.length?v.snapGrid.length-1:v.slides.length-1);if(v.params.freeModeMomentum){if(k.length>1){var i=k.pop(),n=k.pop(),o=i.position-n.position,l=i.time-n.time;v.velocity=o/l,v.velocity=v.velocity/2,Math.abs(v.velocity)<.02&&(v.velocity=0),(l>150||(new window.Date).getTime()-i.time>300)&&(v.velocity=0)}else v.velocity=0;k.length=0;var p=1e3*v.params.freeModeMomentumRatio,d=v.velocity*p,u=v.translate+d;v.rtl&&(u=-u);var c,m=!1,f=20*Math.abs(v.velocity)*v.params.freeModeMomentumBounceRatio;if(u<v.maxTranslate())v.params.freeModeMomentumBounce?(u+v.maxTranslate()<-f&&(u=v.maxTranslate()-f),c=v.maxTranslate(),m=!0,z=!0):u=v.maxTranslate();else if(u>v.minTranslate())v.params.freeModeMomentumBounce?(u-v.minTranslate()>f&&(u=v.minTranslate()+f),c=v.minTranslate(),m=!0,z=!0):u=v.minTranslate();else if(v.params.freeModeSticky){var h,g=0;for(g=0;g<v.snapGrid.length;g+=1)if(v.snapGrid[g]>-u){h=g;break}u=Math.abs(v.snapGrid[h]-u)<Math.abs(v.snapGrid[h-1]-u)||"next"===v.swipeDirection?v.snapGrid[h]:v.snapGrid[h-1],v.rtl||(u=-u)}if(0!==v.velocity)p=Math.abs(v.rtl?(-u-v.translate)/v.velocity:(u-v.translate)/v.velocity);else if(v.params.freeModeSticky)return void v.slideReset();v.params.freeModeMomentumBounce&&m?(v.updateProgress(c),v.setWrapperTransition(p),v.setWrapperTranslate(u),v.onTransitionStart(),v.animating=!0,v.wrapper.transitionEnd(function(){v&&z&&(v.emit("onMomentumBounce",v),v.setWrapperTransition(v.params.speed),v.setWrapperTranslate(c),v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd()}))})):v.velocity?(v.updateProgress(u),v.setWrapperTransition(p),v.setWrapperTranslate(u),v.onTransitionStart(),v.animating||(v.animating=!0,v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd()}))):v.updateProgress(u),v.updateActiveIndex()}return void((!v.params.freeModeMomentum||s>=v.params.longSwipesMs)&&(v.updateProgress(),v.updateActiveIndex()))}var w,T=0,M=v.slidesSizesGrid[0];for(w=0;w<v.slidesGrid.length;w+=v.params.slidesPerGroup)"undefined"!=typeof v.slidesGrid[w+v.params.slidesPerGroup]?r>=v.slidesGrid[w]&&r<v.slidesGrid[w+v.params.slidesPerGroup]&&(T=w,M=v.slidesGrid[w+v.params.slidesPerGroup]-v.slidesGrid[w]):r>=v.slidesGrid[w]&&(T=w,M=v.slidesGrid[v.slidesGrid.length-1]-v.slidesGrid[v.slidesGrid.length-2]);var I=(r-v.slidesGrid[T])/M;if(s>v.params.longSwipesMs){if(!v.params.longSwipes)return void v.slideTo(v.activeIndex);"next"===v.swipeDirection&&v.slideTo(I>=v.params.longSwipesRatio?T+v.params.slidesPerGroup:T),"prev"===v.swipeDirection&&v.slideTo(I>1-v.params.longSwipesRatio?T+v.params.slidesPerGroup:T)}else{if(!v.params.shortSwipes)return void v.slideTo(v.activeIndex);"next"===v.swipeDirection&&v.slideTo(T+v.params.slidesPerGroup),"prev"===v.swipeDirection&&v.slideTo(T)}}},v._slideTo=function(e,a){return v.slideTo(e,a,!0,!0)},v.slideTo=function(e,a,t,s){"undefined"==typeof t&&(t=!0),"undefined"==typeof e&&(e=0),0>e&&(e=0),v.snapIndex=Math.floor(e/v.params.slidesPerGroup),v.snapIndex>=v.snapGrid.length&&(v.snapIndex=v.snapGrid.length-1);var i=-v.snapGrid[v.snapIndex];v.params.autoplay&&v.autoplaying&&(s||!v.params.autoplayDisableOnInteraction?v.pauseAutoplay(a):v.stopAutoplay()),v.updateProgress(i);for(var n=0;n<v.slidesGrid.length;n++)-Math.floor(100*i)>=Math.floor(100*v.slidesGrid[n])&&(e=n);if(!v.params.allowSwipeToNext&&i<v.translate&&i<v.minTranslate())return!1;if(!v.params.allowSwipeToPrev&&i>v.translate&&i>v.maxTranslate()&&(v.activeIndex||0)!==e)return!1;if("undefined"==typeof a&&(a=v.params.speed),v.previousIndex=v.activeIndex||0,v.activeIndex=e,i===v.translate)return v.updateClasses(),!1;v.updateClasses(),v.onTransitionStart(t);r()?i:0,r()?0:i;return 0===a?(v.setWrapperTransition(0),v.setWrapperTranslate(i),v.onTransitionEnd(t)):(v.setWrapperTransition(a),v.setWrapperTranslate(i),v.animating||(v.animating=!0,v.wrapper.transitionEnd(function(){v&&v.onTransitionEnd(t)}))),!0},v.onTransitionStart=function(e){"undefined"==typeof e&&(e=!0), +v.lazy&&v.lazy.onTransitionStart(),e&&(v.emit("onTransitionStart",v),v.activeIndex!==v.previousIndex&&v.emit("onSlideChangeStart",v))},v.onTransitionEnd=function(e){v.animating=!1,v.setWrapperTransition(0),"undefined"==typeof e&&(e=!0),v.lazy&&v.lazy.onTransitionEnd(),e&&(v.emit("onTransitionEnd",v),v.activeIndex!==v.previousIndex&&v.emit("onSlideChangeEnd",v)),v.params.hashnav&&v.hashnav&&v.hashnav.setHash()},v.slideNext=function(e,a,t){if(v.params.loop){if(v.animating)return!1;v.fixLoop();{v.container[0].clientLeft}return v.slideTo(v.activeIndex+v.params.slidesPerGroup,a,e,t)}return v.slideTo(v.activeIndex+v.params.slidesPerGroup,a,e,t)},v._slideNext=function(e){return v.slideNext(!0,e,!0)},v.slidePrev=function(e,a,t){if(v.params.loop){if(v.animating)return!1;v.fixLoop();{v.container[0].clientLeft}return v.slideTo(v.activeIndex-1,a,e,t)}return v.slideTo(v.activeIndex-1,a,e,t)},v._slidePrev=function(e){return v.slidePrev(!0,e,!0)},v.slideReset=function(e,a,t){return v.slideTo(v.activeIndex,a,e)},v.setWrapperTransition=function(e,a){v.wrapper.transition(e),"slide"!==v.params.effect&&v.effects[v.params.effect]&&v.effects[v.params.effect].setTransition(e),v.params.parallax&&v.parallax&&v.parallax.setTransition(e),v.params.scrollbar&&v.scrollbar&&v.scrollbar.setTransition(e),v.params.control&&v.controller&&v.controller.setTransition(e,a),v.emit("onSetTransition",v,e)},v.setWrapperTranslate=function(e,a,t){var s=0,i=0,n=0;r()?s=v.rtl?-e:e:i=e,v.params.virtualTranslate||v.wrapper.transform(v.support.transforms3d?"translate3d("+s+"px, "+i+"px, "+n+"px)":"translate("+s+"px, "+i+"px)"),v.translate=r()?s:i,a&&v.updateActiveIndex(),"slide"!==v.params.effect&&v.effects[v.params.effect]&&v.effects[v.params.effect].setTranslate(v.translate),v.params.parallax&&v.parallax&&v.parallax.setTranslate(v.translate),v.params.scrollbar&&v.scrollbar&&v.scrollbar.setTranslate(v.translate),v.params.control&&v.controller&&v.controller.setTranslate(v.translate,t),v.emit("onSetTranslate",v,v.translate)},v.getTranslate=function(e,a){var t,s,r,i;return"undefined"==typeof a&&(a="x"),v.params.virtualTranslate?v.rtl?-v.translate:v.translate:(r=window.getComputedStyle(e,null),window.WebKitCSSMatrix?i=new window.WebKitCSSMatrix("none"===r.webkitTransform?"":r.webkitTransform):(i=r.MozTransform||r.OTransform||r.MsTransform||r.msTransform||r.transform||r.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),t=i.toString().split(",")),"x"===a&&(s=window.WebKitCSSMatrix?i.m41:parseFloat(16===t.length?t[12]:t[4])),"y"===a&&(s=window.WebKitCSSMatrix?i.m42:parseFloat(16===t.length?t[13]:t[5])),v.rtl&&s&&(s=-s),s||0)},v.getWrapperTranslate=function(e){return"undefined"==typeof e&&(e=r()?"x":"y"),v.getTranslate(v.wrapper[0],e)},v.observers=[],v.initObservers=function(){if(v.params.observeParents)for(var e=v.container.parents(),a=0;a<e.length;a++)l(e[a]);l(v.container[0],{childList:!1}),l(v.wrapper[0],{attributes:!1})},v.disconnectObservers=function(){for(var e=0;e<v.observers.length;e++)v.observers[e].disconnect();v.observers=[]},v.createLoop=function(){v.wrapper.children("."+v.params.slideClass+"."+v.params.slideDuplicateClass).remove();var e=v.wrapper.children("."+v.params.slideClass);"auto"!==v.params.slidesPerView||v.params.loopedSlides||(v.params.loopedSlides=e.length),v.loopedSlides=parseInt(v.params.loopedSlides||v.params.slidesPerView,10),v.loopedSlides=v.loopedSlides+v.params.loopAdditionalSlides,v.loopedSlides>e.length&&(v.loopedSlides=e.length);var t,s=[],r=[];for(e.each(function(t,i){var n=a(this);t<v.loopedSlides&&r.push(i),t<e.length&&t>=e.length-v.loopedSlides&&s.push(i),n.attr("data-swiper-slide-index",t)}),t=0;t<r.length;t++)v.wrapper.append(a(r[t].cloneNode(!0)).addClass(v.params.slideDuplicateClass));for(t=s.length-1;t>=0;t--)v.wrapper.prepend(a(s[t].cloneNode(!0)).addClass(v.params.slideDuplicateClass))},v.destroyLoop=function(){v.wrapper.children("."+v.params.slideClass+"."+v.params.slideDuplicateClass).remove(),v.slides.removeAttr("data-swiper-slide-index")},v.fixLoop=function(){var e;v.activeIndex<v.loopedSlides?(e=v.slides.length-3*v.loopedSlides+v.activeIndex,e+=v.loopedSlides,v.slideTo(e,0,!1,!0)):("auto"===v.params.slidesPerView&&v.activeIndex>=2*v.loopedSlides||v.activeIndex>v.slides.length-2*v.params.slidesPerView)&&(e=-v.slides.length+v.activeIndex+v.loopedSlides,e+=v.loopedSlides,v.slideTo(e,0,!1,!0))},v.appendSlide=function(e){if(v.params.loop&&v.destroyLoop(),"object"==typeof e&&e.length)for(var a=0;a<e.length;a++)e[a]&&v.wrapper.append(e[a]);else v.wrapper.append(e);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0)},v.prependSlide=function(e){v.params.loop&&v.destroyLoop();var a=v.activeIndex+1;if("object"==typeof e&&e.length){for(var t=0;t<e.length;t++)e[t]&&v.wrapper.prepend(e[t]);a=v.activeIndex+e.length}else v.wrapper.prepend(e);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0),v.slideTo(a,0,!1)},v.removeSlide=function(e){v.params.loop&&(v.destroyLoop(),v.slides=v.wrapper.children("."+v.params.slideClass));var a,t=v.activeIndex;if("object"==typeof e&&e.length){for(var s=0;s<e.length;s++)a=e[s],v.slides[a]&&v.slides.eq(a).remove(),t>a&&t--;t=Math.max(t,0)}else a=e,v.slides[a]&&v.slides.eq(a).remove(),t>a&&t--,t=Math.max(t,0);v.params.loop&&v.createLoop(),v.params.observer&&v.support.observer||v.update(!0),v.params.loop?v.slideTo(t+v.loopedSlides,0,!1):v.slideTo(t,0,!1)},v.removeAllSlides=function(){for(var e=[],a=0;a<v.slides.length;a++)e.push(a);v.removeSlide(e)},v.effects={fade:{setTranslate:function(){for(var e=0;e<v.slides.length;e++){var a=v.slides.eq(e),t=a[0].swiperSlideOffset,s=-t;v.params.virtualTranslate||(s-=v.translate);var i=0;r()||(i=s,s=0);var n=v.params.fade.crossFade?Math.max(1-Math.abs(a[0].progress),0):1+Math.min(Math.max(a[0].progress,-1),0);a.css({opacity:n}).transform("translate3d("+s+"px, "+i+"px, 0px)")}},setTransition:function(e){if(v.slides.transition(e),v.params.virtualTranslate&&0!==e){var a=!1;v.slides.transitionEnd(function(){if(!a&&v){a=!0,v.animating=!1;for(var e=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],t=0;t<e.length;t++)v.wrapper.trigger(e[t])}})}}},cube:{setTranslate:function(){var e,t=0;v.params.cube.shadow&&(r()?(e=v.wrapper.find(".swiper-cube-shadow"),0===e.length&&(e=a('<div class="swiper-cube-shadow"></div>'),v.wrapper.append(e)),e.css({height:v.width+"px"})):(e=v.container.find(".swiper-cube-shadow"),0===e.length&&(e=a('<div class="swiper-cube-shadow"></div>'),v.container.append(e))));for(var s=0;s<v.slides.length;s++){var i=v.slides.eq(s),n=90*s,o=Math.floor(n/360);v.rtl&&(n=-n,o=Math.floor(-n/360));var l=Math.max(Math.min(i[0].progress,1),-1),p=0,d=0,u=0;s%4===0?(p=4*-o*v.size,u=0):(s-1)%4===0?(p=0,u=4*-o*v.size):(s-2)%4===0?(p=v.size+4*o*v.size,u=v.size):(s-3)%4===0&&(p=-v.size,u=3*v.size+4*v.size*o),v.rtl&&(p=-p),r()||(d=p,p=0);var c="rotateX("+(r()?0:-n)+"deg) rotateY("+(r()?n:0)+"deg) translate3d("+p+"px, "+d+"px, "+u+"px)";if(1>=l&&l>-1&&(t=90*s+90*l,v.rtl&&(t=90*-s-90*l)),i.transform(c),v.params.cube.slideShadows){var m=i.find(r()?".swiper-slide-shadow-left":".swiper-slide-shadow-top"),f=i.find(r()?".swiper-slide-shadow-right":".swiper-slide-shadow-bottom");0===m.length&&(m=a('<div class="swiper-slide-shadow-'+(r()?"left":"top")+'"></div>'),i.append(m)),0===f.length&&(f=a('<div class="swiper-slide-shadow-'+(r()?"right":"bottom")+'"></div>'),i.append(f));{i[0].progress}m.length&&(m[0].style.opacity=-i[0].progress),f.length&&(f[0].style.opacity=i[0].progress)}}if(v.wrapper.css({"-webkit-transform-origin":"50% 50% -"+v.size/2+"px","-moz-transform-origin":"50% 50% -"+v.size/2+"px","-ms-transform-origin":"50% 50% -"+v.size/2+"px","transform-origin":"50% 50% -"+v.size/2+"px"}),v.params.cube.shadow)if(r())e.transform("translate3d(0px, "+(v.width/2+v.params.cube.shadowOffset)+"px, "+-v.width/2+"px) rotateX(90deg) rotateZ(0deg) scale("+v.params.cube.shadowScale+")");else{var h=Math.abs(t)-90*Math.floor(Math.abs(t)/90),g=1.5-(Math.sin(2*h*Math.PI/360)/2+Math.cos(2*h*Math.PI/360)/2),w=v.params.cube.shadowScale,y=v.params.cube.shadowScale/g,x=v.params.cube.shadowOffset;e.transform("scale3d("+w+", 1, "+y+") translate3d(0px, "+(v.height/2+x)+"px, "+-v.height/2/y+"px) rotateX(-90deg)")}var b=v.isSafari||v.isUiWebView?-v.size/2:0;v.wrapper.transform("translate3d(0px,0,"+b+"px) rotateX("+(r()?0:t)+"deg) rotateY("+(r()?-t:0)+"deg)")},setTransition:function(e){v.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),v.params.cube.shadow&&!r()&&v.container.find(".swiper-cube-shadow").transition(e)}},coverflow:{setTranslate:function(){for(var e=v.translate,t=r()?-e+v.width/2:-e+v.height/2,s=r()?v.params.coverflow.rotate:-v.params.coverflow.rotate,i=v.params.coverflow.depth,n=0,o=v.slides.length;o>n;n++){var l=v.slides.eq(n),p=v.slidesSizesGrid[n],d=l[0].swiperSlideOffset,u=(t-d-p/2)/p*v.params.coverflow.modifier,c=r()?s*u:0,m=r()?0:s*u,f=-i*Math.abs(u),h=r()?0:v.params.coverflow.stretch*u,g=r()?v.params.coverflow.stretch*u:0;Math.abs(g)<.001&&(g=0),Math.abs(h)<.001&&(h=0),Math.abs(f)<.001&&(f=0),Math.abs(c)<.001&&(c=0),Math.abs(m)<.001&&(m=0);var w="translate3d("+g+"px,"+h+"px,"+f+"px) rotateX("+m+"deg) rotateY("+c+"deg)";if(l.transform(w),l[0].style.zIndex=-Math.abs(Math.round(u))+1,v.params.coverflow.slideShadows){var y=l.find(r()?".swiper-slide-shadow-left":".swiper-slide-shadow-top"),x=l.find(r()?".swiper-slide-shadow-right":".swiper-slide-shadow-bottom");0===y.length&&(y=a('<div class="swiper-slide-shadow-'+(r()?"left":"top")+'"></div>'),l.append(y)),0===x.length&&(x=a('<div class="swiper-slide-shadow-'+(r()?"right":"bottom")+'"></div>'),l.append(x)),y.length&&(y[0].style.opacity=u>0?u:0),x.length&&(x[0].style.opacity=-u>0?-u:0)}}if(v.browser.ie){var b=v.wrapper[0].style;b.perspectiveOrigin=t+"px 50%"}},setTransition:function(e){v.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}}},v.lazy={initialImageLoaded:!1,loadImageInSlide:function(e,t){if("undefined"!=typeof e&&("undefined"==typeof t&&(t=!0),0!==v.slides.length)){var s=v.slides.eq(e),r=s.find(".swiper-lazy:not(.swiper-lazy-loaded):not(.swiper-lazy-loading)");!s.hasClass("swiper-lazy")||s.hasClass("swiper-lazy-loaded")||s.hasClass("swiper-lazy-loading")||r.add(s[0]),0!==r.length&&r.each(function(){var e=a(this);e.addClass("swiper-lazy-loading");var r=e.attr("data-background"),i=e.attr("data-src");v.loadImage(e[0],i||r,!1,function(){if(r?(e.css("background-image","url("+r+")"),e.removeAttr("data-background")):(e.attr("src",i),e.removeAttr("data-src")),e.addClass("swiper-lazy-loaded").removeClass("swiper-lazy-loading"),s.find(".swiper-lazy-preloader, .preloader").remove(),v.params.loop&&t){var a=s.attr("data-swiper-slide-index");if(s.hasClass(v.params.slideDuplicateClass)){var n=v.wrapper.children('[data-swiper-slide-index="'+a+'"]:not(.'+v.params.slideDuplicateClass+")");v.lazy.loadImageInSlide(n.index(),!1)}else{var o=v.wrapper.children("."+v.params.slideDuplicateClass+'[data-swiper-slide-index="'+a+'"]');v.lazy.loadImageInSlide(o.index(),!1)}}v.emit("onLazyImageReady",v,s[0],e[0])}),v.emit("onLazyImageLoad",v,s[0],e[0])})}},load:function(){var e;if(v.params.watchSlidesVisibility)v.wrapper.children("."+v.params.slideVisibleClass).each(function(){v.lazy.loadImageInSlide(a(this).index())});else if(v.params.slidesPerView>1)for(e=v.activeIndex;e<v.activeIndex+v.params.slidesPerView;e++)v.slides[e]&&v.lazy.loadImageInSlide(e);else v.lazy.loadImageInSlide(v.activeIndex);if(v.params.lazyLoadingInPrevNext)if(v.params.slidesPerView>1){for(e=v.activeIndex+v.params.slidesPerView;e<v.activeIndex+v.params.slidesPerView+v.params.slidesPerView;e++)v.slides[e]&&v.lazy.loadImageInSlide(e);for(e=v.activeIndex-v.params.slidesPerView;e<v.activeIndex;e++)v.slides[e]&&v.lazy.loadImageInSlide(e)}else{var t=v.wrapper.children("."+v.params.slideNextClass);t.length>0&&v.lazy.loadImageInSlide(t.index());var s=v.wrapper.children("."+v.params.slidePrevClass);s.length>0&&v.lazy.loadImageInSlide(s.index())}},onTransitionStart:function(){v.params.lazyLoading&&(v.params.lazyLoadingOnTransitionStart||!v.params.lazyLoadingOnTransitionStart&&!v.lazy.initialImageLoaded)&&v.lazy.load()},onTransitionEnd:function(){v.params.lazyLoading&&!v.params.lazyLoadingOnTransitionStart&&v.lazy.load()}},v.scrollbar={set:function(){if(v.params.scrollbar){var e=v.scrollbar;e.track=a(v.params.scrollbar),e.drag=e.track.find(".swiper-scrollbar-drag"),0===e.drag.length&&(e.drag=a('<div class="swiper-scrollbar-drag"></div>'),e.track.append(e.drag)),e.drag[0].style.width="",e.drag[0].style.height="",e.trackSize=r()?e.track[0].offsetWidth:e.track[0].offsetHeight,e.divider=v.size/v.virtualSize,e.moveDivider=e.divider*(e.trackSize/v.size),e.dragSize=e.trackSize*e.divider,r()?e.drag[0].style.width=e.dragSize+"px":e.drag[0].style.height=e.dragSize+"px",e.track[0].style.display=e.divider>=1?"none":"",v.params.scrollbarHide&&(e.track[0].style.opacity=0)}},setTranslate:function(){if(v.params.scrollbar){var e,a=v.scrollbar,t=(v.translate||0,a.dragSize);e=(a.trackSize-a.dragSize)*v.progress,v.rtl&&r()?(e=-e,e>0?(t=a.dragSize-e,e=0):-e+a.dragSize>a.trackSize&&(t=a.trackSize+e)):0>e?(t=a.dragSize+e,e=0):e+a.dragSize>a.trackSize&&(t=a.trackSize-e),r()?(a.drag.transform(v.support.transforms3d?"translate3d("+e+"px, 0, 0)":"translateX("+e+"px)"),a.drag[0].style.width=t+"px"):(a.drag.transform(v.support.transforms3d?"translate3d(0px, "+e+"px, 0)":"translateY("+e+"px)"),a.drag[0].style.height=t+"px"),v.params.scrollbarHide&&(clearTimeout(a.timeout),a.track[0].style.opacity=1,a.timeout=setTimeout(function(){a.track[0].style.opacity=0,a.track.transition(400)},1e3))}},setTransition:function(e){v.params.scrollbar&&v.scrollbar.drag.transition(e)}},v.controller={LinearSpline:function(e,a){this.x=e,this.y=a,this.lastIndex=e.length-1;{var t,s;this.x.length}this.interpolate=function(e){return e?(s=r(this.x,e),t=s-1,(e-this.x[t])*(this.y[s]-this.y[t])/(this.x[s]-this.x[t])+this.y[t]):0};var r=function(){var e,a,t;return function(s,r){for(a=-1,e=s.length;e-a>1;)s[t=e+a>>1]<=r?a=t:e=t;return e}}()},getInterpolateFunction:function(e){v.controller.spline||(v.controller.spline=v.params.loop?new v.controller.LinearSpline(v.slidesGrid,e.slidesGrid):new v.controller.LinearSpline(v.snapGrid,e.snapGrid))},setTranslate:function(e,a){function s(a){e=a.rtl&&"horizontal"===a.params.direction?-v.translate:v.translate,"slide"===v.params.controlBy&&(v.controller.getInterpolateFunction(a),i=-v.controller.spline.interpolate(-e)),i&&"container"!==v.params.controlBy||(r=(a.maxTranslate()-a.minTranslate())/(v.maxTranslate()-v.minTranslate()),i=(e-v.minTranslate())*r+a.minTranslate()),v.params.controlInverse&&(i=a.maxTranslate()-i),a.updateProgress(i),a.setWrapperTranslate(i,!1,v),a.updateActiveIndex()}var r,i,n=v.params.control;if(v.isArray(n))for(var o=0;o<n.length;o++)n[o]!==a&&n[o]instanceof t&&s(n[o]);else n instanceof t&&a!==n&&s(n)},setTransition:function(e,a){function s(a){a.setWrapperTransition(e,v),0!==e&&(a.onTransitionStart(),a.wrapper.transitionEnd(function(){i&&(a.params.loop&&"slide"===v.params.controlBy&&a.fixLoop(),a.onTransitionEnd())}))}var r,i=v.params.control;if(v.isArray(i))for(r=0;r<i.length;r++)i[r]!==a&&i[r]instanceof t&&s(i[r]);else i instanceof t&&a!==i&&s(i)}},v.hashnav={init:function(){if(v.params.hashnav){v.hashnav.initialized=!0;var e=document.location.hash.replace("#","");if(e)for(var a=0,t=0,s=v.slides.length;s>t;t++){var r=v.slides.eq(t),i=r.attr("data-hash");if(i===e&&!r.hasClass(v.params.slideDuplicateClass)){var n=r.index();v.slideTo(n,a,v.params.runCallbacksOnInit,!0)}}}},setHash:function(){v.hashnav.initialized&&v.params.hashnav&&(document.location.hash=v.slides.eq(v.activeIndex).attr("data-hash")||"")}},v.disableKeyboardControl=function(){a(document).off("keydown",p)},v.enableKeyboardControl=function(){a(document).on("keydown",p)},v.mousewheel={event:!1,lastScrollTime:(new window.Date).getTime()},v.params.mousewheelControl){try{new window.WheelEvent("wheel"),v.mousewheel.event="wheel"}catch(L){}v.mousewheel.event||void 0===document.onmousewheel||(v.mousewheel.event="mousewheel"),v.mousewheel.event||(v.mousewheel.event="DOMMouseScroll")}v.disableMousewheelControl=function(){return v.mousewheel.event?(v.container.off(v.mousewheel.event,d),!0):!1},v.enableMousewheelControl=function(){return v.mousewheel.event?(v.container.on(v.mousewheel.event,d),!0):!1},v.parallax={setTranslate:function(){v.container.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){u(this,v.progress)}),v.slides.each(function(){var e=a(this);e.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var a=Math.min(Math.max(e[0].progress,-1),1);u(this,a)})})},setTransition:function(e){"undefined"==typeof e&&(e=v.params.speed),v.container.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var t=a(this),s=parseInt(t.attr("data-swiper-parallax-duration"),10)||e;0===e&&(s=0),t.transition(s)})}},v._plugins=[];for(var B in v.plugins){var O=v.plugins[B](v,v.params[B]);O&&v._plugins.push(O)}return v.callPlugins=function(e){for(var a=0;a<v._plugins.length;a++)e in v._plugins[a]&&v._plugins[a][e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},v.emitterEventListeners={},v.emit=function(e){v.params[e]&&v.params[e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);var a;if(v.emitterEventListeners[e])for(a=0;a<v.emitterEventListeners[e].length;a++)v.emitterEventListeners[e][a](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);v.callPlugins&&v.callPlugins(e,arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},v.on=function(e,a){return e=c(e),v.emitterEventListeners[e]||(v.emitterEventListeners[e]=[]),v.emitterEventListeners[e].push(a),v},v.off=function(e,a){var t;if(e=c(e),"undefined"==typeof a)return v.emitterEventListeners[e]=[],v;if(v.emitterEventListeners[e]&&0!==v.emitterEventListeners[e].length){for(t=0;t<v.emitterEventListeners[e].length;t++)v.emitterEventListeners[e][t]===a&&v.emitterEventListeners[e].splice(t,1);return v}},v.once=function(e,a){e=c(e);var t=function(){a(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]),v.off(e,t)};return v.on(e,t),v},v.a11y={makeFocusable:function(e){return e.attr("tabIndex","0"),e},addRole:function(e,a){return e.attr("role",a),e},addLabel:function(e,a){return e.attr("aria-label",a),e},disable:function(e){return e.attr("aria-disabled",!0),e},enable:function(e){return e.attr("aria-disabled",!1),e},onEnterKey:function(e){13===e.keyCode&&(a(e.target).is(v.params.nextButton)?(v.onClickNext(e),v.a11y.notify(v.isEnd?v.params.lastSlideMessage:v.params.nextSlideMessage)):a(e.target).is(v.params.prevButton)&&(v.onClickPrev(e),v.a11y.notify(v.isBeginning?v.params.firstSlideMessage:v.params.prevSlideMessage)),a(e.target).is("."+v.params.bulletClass)&&a(e.target)[0].click())},liveRegion:a('<span class="swiper-notification" aria-live="assertive" aria-atomic="true"></span>'),notify:function(e){var a=v.a11y.liveRegion;0!==a.length&&(a.html(""),a.html(e))},init:function(){if(v.params.nextButton){var e=a(v.params.nextButton);v.a11y.makeFocusable(e),v.a11y.addRole(e,"button"),v.a11y.addLabel(e,v.params.nextSlideMessage)}if(v.params.prevButton){var t=a(v.params.prevButton);v.a11y.makeFocusable(t),v.a11y.addRole(t,"button"),v.a11y.addLabel(t,v.params.prevSlideMessage)}a(v.container).append(v.a11y.liveRegion)},initPagination:function(){v.params.pagination&&v.params.paginationClickable&&v.bullets&&v.bullets.length&&v.bullets.each(function(){var e=a(this);v.a11y.makeFocusable(e),v.a11y.addRole(e,"button"),v.a11y.addLabel(e,v.params.paginationBulletMessage.replace(/{{index}}/,e.index()+1))})},destroy:function(){v.a11y.liveRegion&&v.a11y.liveRegion.length>0&&v.a11y.liveRegion.remove()}},v.init=function(){v.params.loop&&v.createLoop(),v.updateContainerSize(),v.updateSlidesSize(),v.updatePagination(),v.params.scrollbar&&v.scrollbar&&v.scrollbar.set(),"slide"!==v.params.effect&&v.effects[v.params.effect]&&(v.params.loop||v.updateProgress(),v.effects[v.params.effect].setTranslate()),v.params.loop?v.slideTo(v.params.initialSlide+v.loopedSlides,0,v.params.runCallbacksOnInit):(v.slideTo(v.params.initialSlide,0,v.params.runCallbacksOnInit),0===v.params.initialSlide&&(v.parallax&&v.params.parallax&&v.parallax.setTranslate(),v.lazy&&v.params.lazyLoading&&(v.lazy.load(),v.lazy.initialImageLoaded=!0))),v.attachEvents(),v.params.observer&&v.support.observer&&v.initObservers(),v.params.preloadImages&&!v.params.lazyLoading&&v.preloadImages(),v.params.autoplay&&v.startAutoplay(),v.params.keyboardControl&&v.enableKeyboardControl&&v.enableKeyboardControl(),v.params.mousewheelControl&&v.enableMousewheelControl&&v.enableMousewheelControl(),v.params.hashnav&&v.hashnav&&v.hashnav.init(),v.params.a11y&&v.a11y&&v.a11y.init(),v.emit("onInit",v)},v.cleanupStyles=function(){v.container.removeClass(v.classNames.join(" ")).removeAttr("style"),v.wrapper.removeAttr("style"),v.slides&&v.slides.length&&v.slides.removeClass([v.params.slideVisibleClass,v.params.slideActiveClass,v.params.slideNextClass,v.params.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-column").removeAttr("data-swiper-row"),v.paginationContainer&&v.paginationContainer.length&&v.paginationContainer.removeClass(v.params.paginationHiddenClass),v.bullets&&v.bullets.length&&v.bullets.removeClass(v.params.bulletActiveClass),v.params.prevButton&&a(v.params.prevButton).removeClass(v.params.buttonDisabledClass),v.params.nextButton&&a(v.params.nextButton).removeClass(v.params.buttonDisabledClass),v.params.scrollbar&&v.scrollbar&&(v.scrollbar.track&&v.scrollbar.track.length&&v.scrollbar.track.removeAttr("style"),v.scrollbar.drag&&v.scrollbar.drag.length&&v.scrollbar.drag.removeAttr("style"))},v.destroy=function(e,a){v.detachEvents(),v.stopAutoplay(),v.params.loop&&v.destroyLoop(),a&&v.cleanupStyles(),v.disconnectObservers(),v.params.keyboardControl&&v.disableKeyboardControl&&v.disableKeyboardControl(),v.params.mousewheelControl&&v.disableMousewheelControl&&v.disableMousewheelControl(),v.params.a11y&&v.a11y&&v.a11y.destroy(),v.emit("onDestroy"),e!==!1&&(v=null)},v.init(),v}};t.prototype={isSafari:function(){var e=navigator.userAgent.toLowerCase();return e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0}(),isUiWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent),isArray:function(e){return"[object Array]"===Object.prototype.toString.apply(e)},browser:{ie:window.navigator.pointerEnabled||window.navigator.msPointerEnabled,ieTouch:window.navigator.msPointerEnabled&&window.navigator.msMaxTouchPoints>1||window.navigator.pointerEnabled&&window.navigator.maxTouchPoints>1},device:function(){var e=navigator.userAgent,a=e.match(/(Android);?[\s\/]+([\d.]+)?/),t=e.match(/(iPad).*OS\s([\d_]+)/),s=e.match(/(iPod)(.*OS\s([\d_]+))?/),r=!t&&e.match(/(iPhone\sOS)\s([\d_]+)/);return{ios:t||r||s,android:a}}(),support:{touch:window.Modernizr&&Modernizr.touch===!0||function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)}(),transforms3d:window.Modernizr&&Modernizr.csstransforms3d===!0||function(){var e=document.createElement("div").style;return"webkitPerspective"in e||"MozPerspective"in e||"OPerspective"in e||"MsPerspective"in e||"perspective"in e}(),flexbox:function(){for(var e=document.createElement("div").style,a="alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient".split(" "),t=0;t<a.length;t++)if(a[t]in e)return!0}(),observer:function(){return"MutationObserver"in window||"WebkitMutationObserver"in window}()},plugins:{}};for(var s=["jQuery","Zepto","Dom7"],r=0;r<s.length;r++)window[s[r]]&&e(window[s[r]]);var i;i="undefined"==typeof Dom7?window.Dom7||window.Zepto||window.jQuery:Dom7,i&&("transitionEnd"in i.fn||(i.fn.transitionEnd=function(e){function a(i){if(i.target===this)for(e.call(this,i),t=0;t<s.length;t++)r.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],r=this;if(e)for(t=0;t<s.length;t++)r.on(s[t],a);return this}),"transform"in i.fn||(i.fn.transform=function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this}),"transition"in i.fn||(i.fn.transition=function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this})),window.Swiper=t}(),"undefined"!=typeof module?module.exports=window.Swiper:"function"==typeof define&&define.amd&&define([],function(){"use strict";return window.Swiper}); diff --git a/hyhproject/wechat2/view/default/login.html b/hyhproject/wechat2/view/default/login.html new file mode 100755 index 0000000..bc6c89e --- /dev/null +++ b/hyhproject/wechat2/view/default/login.html @@ -0,0 +1,162 @@ +{extend name="default/base" /} +{block name="title"}登录账号 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/user.css?v={$v}"> +<style>body{background:#fff}</style> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i id="return" class="ui-icon-return" onclick="javascript:inReturn();" style="display:none;"></i><h1 id="login-w">登录账号</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container" id="choice"> + <div class="wst-lo-choice"> + <div class="img"><img src="{$info['headimgurl']}"></div> + <p class="name">{$info['nickname']}</p> + <p class="prompt">您的微信尚未登录{:WSTConf('CONF.mallName')}账号</p> + <div class="choice"> + <button class="button0" type="button" onclick='javascript:inChoice(0);'>注册新账号</button> + </div> + <div class="choice"> + <button class="button1" type="button" onclick='javascript:inChoice(1);'>登录</button> + </div> + </div> + </section> + <section class="ui-container" id="login1" style="display:none;"> + <div class="wst-lo-frame"> + <div class="frame"><input id="loginName" type="text" placeholder="邮箱/用户名/手机号"></div> + <div class="frame"><input id="loginPwd" type="password" placeholder="密码"></div> + <div class="verify"> + <input id="loginVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg1' src="{:url('wechat/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg1")'> + </div> + </div> + <div class="wst-lo-button"> + <button id="loginButton" class="button" onclick="javascript:login();">登录</button> + </div> + </section> + <section class="ui-container" id="login0" style="display:none;"> + <div class="wst-lo-frame"> + <div class="frame"><input id="regName" type="text" placeholder="手机号" onkeyup="javascript:onTesting(this)"></div> + <div class="frame"><input id="regPwd" type="password" placeholder="密码"></div> + <div class="frame"><input id="regcoPwd" type="password" placeholder="确认密码"></div> + {/* 获取验证码的验证prompt */} + {if(WSTConf('CONF.smsVerfy')==1)} + <div class="verify phone"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg3' src="{:url('wechat/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg3")'> + </div> + {/if} + {/* 获取验证码 prompt */} + <div class="verify phone"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" class="ui-btn ui-btn-primary" onclick="javascript:obtainCode()">获取验证码</button> + </div> + </div> + <div class="wst-lo-agreement"> + <i id="defaults" class="ui-icon-chooses ui-icon-success-block wst-active" onclick="javascript:inAgree(this)"></i>我已阅读并同意<span onclick="javascript:wholeShow('protocol');">《用户注册协议》</span> + </div> + <div class="wst-lo-button"> + <button id="regButton" class="button" onclick="javascript:register();">注册</button> + </div> + </section> +{/block} +{block name="include"} +{/* 用户注册协议 */} +<div class="wst-fr-protocol" id="protocol"> + <div class="title"><span>用户注册协议</span><i class="ui-icon-close-page" onclick="javascript:wholeHide('protocol');"></i><div class="wst-clear"></div></div> + <div class="content"> + +<h4><span>{:WSTConf('CONF.mallName')}</span>用户注册协议</h4> +<p>本协议是您与<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有者之间就<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站服务等相关事宜所订立的契约,请您仔细阅读本注册协议,您点击"同意并继续"按钮后,本协议即构成对双方有约束力的法律文件。</p> +<h4>第1条 本站服务条款的确认和接纳</h4> +<p><strong>1.1</strong>本站的各项电子服务的所有权和运作权归<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>所有。用户同意所有注册协议条款并完成注册程序,才能成为本站的正式用户。用户确认:本协议条款是处理双方权利义务的契约,始终有效,法律另有强制性规定或双方另有特别约定的,依其规定。<p></p> +<p><strong>1.2</strong>用户点击同意本协议的,即视为用户确认自己具有享受本站服务、下单购物等相应的权利能力和行为能力,能够独立承担法律责任。</p> +<p><strong>1.3</strong>如果您在18周岁以下,您只能在父母或监护人的监护参与下才能使用本站。<p> +<p><strong>1.4</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留在中华人民共和国大陆地区法施行之法律允许的范围内独自决定拒绝服务、关闭用户账户、清除或编辑内容或取消订单的权利。</p> +<h4>第2条 本站服务</h4> +<p><strong>2.1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>通过互联网依法为用户提供互联网信息等服务,用户在完全同意本协议及本站规定的情况下,方有权使用本站的相关服务。</p> +<p><strong>2.2</strong>用户必须自行准备如下设备和承担如下开支:</p> +<p>(1)上网设备,包括并不限于电脑或者其他上网终端、调制解调器及其他必备的上网装置;</p> +<p>(2)上网开支,包括并不限于网络接入费、上网设备租用费、手机流量费等。</p> +<h4>第3条 用户信息</h4> +<p><strong>3.1</strong>用户应自行诚信向本站提供注册资料,用户同意其提供的注册资料真实、准确、完整、合法有效,用户注册资料如有变动的,应及时更新其注册资料。如果用户提供的注册资料不合法、不真实、不准确、不详尽的,用户需承担因此引起的相应责任及后果,并且<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>保留终止用户使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>各项服务的权利。</p> +<p><strong>3.2</strong>用户在本站进行浏览、下单购物等活动时,涉及用户真实姓名/名称、通信地址、联系电话、电子邮箱等隐私信息的,本站将予以严格保密,除非得到用户的授权或法律另有规定,本站不会向外界披露用户隐私信息。</p> +<p><strong>3.3</strong>用户注册成功后,将产生用户名和密码等账户信息,您可以根据本站规定改变您的密码。用户应谨慎合理的保存、使用其用户名和密码。用户若发现任何非法使用用户账号或存在安全漏洞的情况,请立即通知本站并向公安机关报案。</p> +<p><strong>3.4</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>拥有通过邮件、短信电话等形式,向在本站注册、购物用户、收货人发送订单信息、促销活动等告知信息的权利。</p> +<p><strong>3.5</strong>用户不得将在本站注册获得的账户借给他人使用,否则用户应承担由此产生的全部责任,并与实际使用人承担连带责任。</p> +<p><strong>3.6</strong>用户同意,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权使用用户的注册信息、用户名、密码等信息,登录进入用户的注册账户,进行证据保全,包括但不限于公证、见证等。</p> +<h4>第4条 用户依法言行义务</h4> +<p>本协议依据国家相关法律法规规章制定,用户同意严格遵守以下义务:</p> +<p>(1)不得传输或发表:煽动抗拒、破坏宪法和法律、行政法规实施的言论,煽动颠覆国家政权,推翻社会主义制度的言论,煽动分裂国家、破坏国家统一的的言论,煽动民族仇恨、民族歧视、破坏民族团结的言论;</p> +<p>(2)从中国大陆向境外传输资料信息时必须符合中国有关法规;</p> +<p>(3)不得利用本站从事洗钱、窃取商业秘密、窃取个人信息等违法犯罪活动;</p> +<p>(4)不得干扰本站的正常运转,不得侵入本站及国家计算机信息系统;</p> +<p>(5)不得传输或发表任何违法犯罪的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽的、不文明的等信息资料;</p> +<p>(6)不得传输或发表损害国家社会公共利益和涉及国家安全的信息资料或言论;</p> +<p>(7)不得教唆他人从事本条所禁止的行为;</p> +<p>(8)不得利用在本站注册的账户进行牟利性经营活动;</p> +<p>(9)不得发布任何侵犯他人著作权、商标权等知识产权或合法权利的内容;</p> +<p>用户应不时关注并遵守本站不时公布或修改的各类合法规则规定。</p> +<p>本站保有删除站内各类不符合法律政策或不真实的信息内容而无须通知用户的权利。</p> +<p>若用户未遵守以上规定的,本站有权作出独立判断并采取暂停或关闭用户帐号等措施。用户须对自己在网上的言论和行为承担法律责任。</p> +<h4>第5条 店铺义务</h4> +<p><strong>5.1</strong>店铺经营者可通过本站申请店铺,发布全新或二手商品及/或服务信息并与其他用户达成交易,但必须保证商品信息真实。如有发现商品假冒或者其他违反国家法律规定的商品,本站有权对商品进行禁售。</p> +<p><strong>5.2</strong>若店铺经营者发生改变,店铺经营者需及时联系本站进行信息的变更,若未及时联系本站而导致消费者与原店铺经营者产生交易纠纷或者违法国家规定的事情,本站不负任何连带责任。</p> +<p><strong>5.3</strong>店铺经营者有权通过使用店铺设置短暂关停店铺,但店铺经营者应当对自己店铺关停前已达成的交易继续承担发货、退换货及质保维修、维权投诉处理等交易保障责任。</p> +<p><strong>5.4</strong>店铺经营者如有不实交易信息或者违反国家相关法律的行为,本站有权对店铺进行关停,并对关停期间所产生的损失不负任何责任。</p> +<p>依据上述约定关停店铺均不会影响您已经累积的信用。</p> +</p> +<h4>第6条 商品信息</h4> +<p>本站上的商品价格、数量、是否有货等商品信息随时都有可能发生变动,本站不作特别通知。由于网站上商品信息的数量极其庞大,虽然本站会尽最大努力保证您所浏览商品信息的准确性,但由于众所周知的互联网技术因素等客观原因存在,本站网页显示的信息可能会有一定的滞后性或差错,对此情形您知悉并理解;<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>欢迎纠错,并会视情况给予纠错者一定的奖励。</p> +<p>为表述便利,商品和服务简称为"商品"或"货物"。</p> +<h4>第7条 订单</h4> +<p><strong>7.1</strong>在您下订单时,请您仔细确认所购商品的名称、价格、数量、规格、联系地址、电话、收货人等信息。收货人与用户本人不一致的,收货人的行为和意思表示视为用户的行为和意思表示,用户应对收货人的行为及意思表示的法律后果承担连带责任。</p> +<p><strong>7.2</strong>除法律另有强制性规定外,双方约定如下:本站上销售方展示的商品和价格等信息仅仅是要约邀请,您下单时须填写您希望购买的商品数量、价款及支付方式、收货人、联系方式、收货地址(合同履行地点)、合同履行方式等内容;系统生成的订单信息是计算机信息系统根据您填写的内容自动生成的数据,仅是您向销售方发出的合同要约;销售方收到您的订单信息后,只有在销售方将您在订单中订购的商品从仓库实际直接向您发出时( 以商品出库为标志),方视为您与销售方之间就实际直接向您发出的商品建立了合同关系;如果您在一份订单里订购了多种商品并且销售方只给您发出了部分商品时,您与销售方之间仅就实际直接向您发出的商品建立了合同关系;只有在销售方实际直接向您发出了订单中订购的其他商品时,您和销售方之间就订单中该其他已实际直接向您发出的商品才成立合同关系。您可以随时登录您在本站注册的账户,查询您的订单状态。</p> +<p><strong>7.3</strong>由于市场变化及各种以合理商业努力难以控制的因素的影响,本站无法保证您提交的订单信息中希望购买的商品都会有货;如您拟购买的商品,发生缺货,您有权取消订单。</p> +<h4>第8条 配送</h4> +<p><strong>8.1</strong>销售方将会把商品(货物)送到您所指定的收货地址,所有在本站上列出的送货时间为参考时间,参考时间的计算是根据库存状况、正常的处理过程和送货时间、送货地点的基础上估计得出的。</p> +<p><strong>8.2</strong>因如下情况造成订单延迟或无法配送等,销售方不承担延迟配送的责任:</p> +<p>(1)用户提供的信息错误、地址不详细等原因导致的;</p> +<p>(2)货物送达后无人签收,导致无法配送或延迟配送的;</p> +<p>(3)情势变更因素导致的;</p> +<p>(4)不可抗力因素导致的,例如:自然灾害、交通戒严、突发战争等。</p> +<h4>第9条 交易争议处理</h4> +<p>您在{:WSTConf('CONF.mallName')}平台交易过程中与其他用户发生争议的,您或其他用户中任何一方均有权选择以下途径解决:</p> +<p>(1)与争议相对方自主协商;</p> +<p>(2)使用<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站提供的争议调处服务;</p> +<p>(3)请求消费者协会或者其他依法成立的调解组织调解;</p> +<p>(4)向有关行政部门投诉;</p> +<p>(5)根据与争议相对方达成的仲裁协议(如有)提请仲裁机构仲裁;</p> +<p>(6)向人民法院提起诉讼。</p> +<h4>第10条 责任限制及不承诺担保</h4> +<p><strong>10.1</strong>除非另有明确的书面说明,本站及其所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务,均是在"按现状"和"按现有"的基础上提供的。</p> +<p><strong>10.2</strong>除非另有明确的书面说明,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不对本站的运营及其包含在本网站上的信息、内容、材料、产品(包括软件)或服务作任何形式的、明示或默示的声明或担保(根据中华人民共和国法律另有规定的以外)。</p> +<p><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>不担保本站所包含的或以其它方式通过本站提供给您的全部信息、内容、材料、产品(包括软件)和服务、其服务器或从本站发出的电子信件、信息没有病毒或其他有害成分。</p> +<p>如因不可抗力或其它本站无法控制的原因使本站销售系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>会合理地尽力协助处理善后事宜。</p> +<h4>第11条 协议更新及用户关注义务</h4> +<p>根据国家法律法规变化及网站运营需要,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>有权对本协议条款不时地进行修改,修改后的协议一旦被张贴在本站上即生效,并代替原来的协议。用户可随时登录查阅最新协议;用户有义务不时关注并阅读最新版的协议及网站公告。如用户不同意更新后的协议,可以且应立即停止接受<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>网站依据本协议提供的服务;如用户继续使用本网站提供的服务的,即视为同意更新后的协议。<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>建议您在使用本站之前阅读本协议及本站的公告。 如果本协议中任何一条被视为废止、无效或因任何理由不可执行,该条应视为可分的且并不影响任何其余条款的有效性和可执行性。</p> +<h4>附则</h4> +<p><strong>1</strong><span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>尊重用户和消费者的合法权利,本协议及本网站上发布的各类规则、声明等其他内容,均是为了更好的、更加便利的为用户和消费者提供服务。本站欢迎用户和社会各界提出意见和建议,<span class='wst-mall'>{:WSTConf('CONF.mallName')}</span>将虚心接受并适时修改本协议及本站上的各类规则。</p> +<p><strong>2</strong>本协议内容中以黑体、加粗、下划线、斜体等方式显著标识的条款,请用户着重阅读。</p> +<p><strong>3</strong>您点击本协议下方的"同意并注册"按钮即视为您完全接受本协议,在点击之前请您再次确认已知悉并完全理解本协议的全部内容。</p> + + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/js/login.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/self_shop.html b/hyhproject/wechat2/view/default/self_shop.html new file mode 100755 index 0000000..b4e5451 --- /dev/null +++ b/hyhproject/wechat2/view/default/self_shop.html @@ -0,0 +1,224 @@ +{extend name="default/base" /} +{block name="title"}自营店铺 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/self_shop.css?v={$v}"> +{/block} +{block name="header"}{/block} + +{block name="main"} +<input type="hidden" name="" value="{$data.shop.shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="-1" id="currPage" autocomplete="off"> +<input type='hidden' name="" value="0" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-sh-banner" {if $data['shop']['shopBanner']!=''}style="background:url(__ROOT__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <header class="ui-header ui-header-positive wst-se-header2 wst-se-header3"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search wst-se-search2" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon wst-se-icon0" onclick="javascript:dataShow();"></span> + {php}$cartNum = WSTCartNum();{/php} + <a href="{:url('wechat/carts/index')}"><span class="wst-se-icon wst-se-icon2">{if($cartNum>0)}<i>{$cartNum}</i>{/if}</span></a> + </header> + </div> + <div class="shop-banner"> + <div class="shop-photo"> + <div class="photo"> + <img src="__ROOT__/{$data.shop.shopImg}"> + <p class="name">{$data.shop.shopName}</p> + </div> + <span class="introduce" onclick="toShopInfo({$data['shop']['shopId']})">店铺介绍</span> + <div class="wst-clear"></div> + </div> + <div class="shop-info" {if(!$data['shop']['shopNotice'])}style="padding-bottom:0.1rem;border-bottom: 0.05rem solid #f2f1f1;"{/if}> + <div class="ui-row-flex"> + <div class="ui-col ui-col"> + <a class="shop-btn j-shopfollow {if($isFavor>0)}follow{/if}" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"></a> + <p id="followNum">{$followNum}</p> + <p>收藏数</p> + </div> + <div class="ui-col ui-col-2"></div> + <div class="ui-col ui-col"><p>{$data['shop']['scores']['areas']['areaName1']}{$data['shop']['scores']['areas']['areaName2']}</p><p>所在地</p></div> + </div> + </div> + {if($data['shop']['shopNotice'])} + <div class="shop-notice"> + <p class="title">店铺公告</p> + <p>{$data['shop']['shopNotice']}</p> + </div> + {/if} + <div class="wst-clear"></div> + </div> + {if !empty($data['shop']['shopAds'])} + <div class="shop-ads"> + <div class="ui-slider"> + <ul class="ui-slider-content" style="width: 300%"> + {volist name="$data['shop']['shopAds']" id="ads"} + <li><span><a href="{$ads.adUrl}"><img style="width:100%; height:100%; display:block;" src="__ROOT__/{$ads.adImg}"></a></span></li> + {/volist} + </ul> + </div> + </div> + {/if} + + <div class="wst-shl-ads" > + <div class="title">店主推荐</div> + <div class="wst-gol-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="$data['rec']" id="re"} + <div class="swiper-slide" style="width:33.333333%;"> + <div style="border-right: 0.01rem solid #f2f1f1;"> + <div class="wst-gol-img j-imgRec"><a href="javascript:void(0)" onclick="WST.intoGoods({$re['goodsId']})"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($re['goodsImg'],3)}" title="{$re['goodsName']}"></a></div> + <p>¥{$re['shopPrice']}</p> + <div class="wst-clear"></div> + </div> + </div> + {/volist} + </div> + </div> + </div> + </div> + + <div class="wst-shl-ads" > + <div class="title">热卖商品</div> + <div class="wst-gol-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {volist name="$data['hot']" id="hot"} + <div class="swiper-slide" style="width:33.333333%;"> + <div style="border-right: 0.01rem solid #f2f1f1;"> + <div class="wst-gol-img j-imgRec1"><a href="javascript:void(0)" onclick="WST.intoGoods({$hot['goodsId']})"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($hot['goodsImg'],3)}" title="{$hot['goodsName']}"></a></div> + <p>¥{$hot['shopPrice']}</p> + <div class="wst-clear"></div> + </div> + </div> + {/volist} + </div> + </div> + </div> + </div> + <script id="gList" type="text/html"> + <div class="wst-in-title"> + <ul class="ui-row shop-floor-title f{{d.currPage}}"> + <li class="ui-col ui-col-80">{{d.catName}}</li> + <li class="ui-col ui-col-20"><a href="{{WST.U('wechat/shops/shopGoodsList','shopId=1&ct1='+d.catId)}}" class="shop-more">更多<i class="ui-icon-arrow"></i></a></li> + </ul> + {{# if(d.goods.length>0){ }} + {{# for(var i=0; i<d.goods.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="javascript:WST.intoGoos({{d.goods[i].goodsId}});"> + <div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}});"> + <img src="{{# WST.conf.ROOT+'/'+WST.conf.GOODS_LOGO}}" data-echo="__ROOT__/{{d.goods[i].goodsImg}}" title="{{d.goods[i].goodsName}}"/></a></div> + <div class="name ui-nowrap-multi">{{d.goods[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d.goods[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">¥ {{ d.goods[i].marketPrice }}</span><span class="deal">成交数:{{ d.goods[i].saleNum }}</span></div> + </div> + {{# } }} + {{# } }} + <div class="wst-clear"></div> + </script> + + <!-- 商品列表 --> + <div id="goods-list"></div> + +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:goGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + + + <ul> + <li> + <div class="wst-goodscats"> + <span>&nbsp;</span> + </div> + </li> + </ul> + </div> + {/volist} + </div> +</div> +</section> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> + <script> + /*分类*/ + function getGoodsList(ct1){ + $('#ct1').val(ct1); + // 跳转店铺商品列表 + var shopId = $('#shopId').val(); + location.href=WST.U('wechat/shops/shopgoodslist',{'shopId':shopId,'ct1':ct1},true) + } + </script> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/self_shop.js'></script> + +<script> +$(function(){ + {if !empty($data['shop']['shopAds'])} + shopAds(); + {/if} + WST.initFooter('home'); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/settlement.html b/hyhproject/wechat2/view/default/settlement.html new file mode 100755 index 0000000..2bf7916 --- /dev/null +++ b/hyhproject/wechat2/view/default/settlement.html @@ -0,0 +1,265 @@ +{extend name="default/base" /} +{block name="title"}确认订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/settlement.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <a href="{:url('wechat/carts/index')}"><i class="ui-icon-return"></i></a><h1>确认订单</h1> + </header> +{/block} +{block name="footer"} + {php}$shopFreight = 0;$shopIds = '';{/php} + {volist name="$carts['carts']" id="car"} + {php} + if($car['isFreeShipping']){ + $freight = 0; + }else{ + if(!empty($userAddress)){ + $freight = WSTOrderFreight($car['shopId'],$userAddress['areaId2']); + }else{ + $freight = WSTOrderFreight($car['shopId'],-1); + } + } + $shopFreight = $shopFreight + $freight; + {/php} + {/volist} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:85px; border-top: 1px solid #e8e8e8;" id="footer"> + <input type="hidden" name="" value="{if empty($userAddress)}{php}echo sprintf("%.2f", $carts["goodsTotalMoney"]);{/php}{else}{php}echo sprintf("%.2f", $carts["goodsTotalMoney"]+$shopFreight);{/php}{/if}" id="totalPrice" autocomplete="off"> + <div class="wst-se-total">应付总金额(含运费):<span id="totalMoney"> + ¥{if empty($userAddress)} + {php}echo sprintf("%.2f", $carts["goodsTotalMoney"]-$carts['promotionMoney']);{/php} + {else} + {php}echo sprintf("%.2f", $carts["goodsTotalMoney"]+$shopFreight-$carts['promotionMoney']);{/php} + {/if}</span></div> + <div class="wst-se-confirm"><button class="button" onclick="javascript:submitOrder();">确定</button></div> + </footer> +{/block} +{block name="main"} + {php}$shopFreight = 0;{/php} + <input type="hidden" name="" value="1" id="sign" autocomplete="off"> + <section class="ui-container" style="border-bottom: 86px solid transparent;"> + <ul class="ui-list ui-list-text ui-list-link wst-se-address"> + <input type="hidden" name="" value="{if isset($userAddress['addressId']) }{$userAddress['addressId']}{/if}" id="addressId" autocomplete="off"> + <input type="hidden" name="" value="{if isset($userAddress['addressId']) }{$userAddress['areaId2']}{/if}" id="areaId" autocomplete="off"> + + {if empty($userAddress)} + <li onclick="javascript:addAddress(1);"><h4><p class="infono">您还没添加收货地址,请添加。</p></h4></li> + {else} + <li onclick="javascript:addAddress(1,{$userAddress['addressId']});"><h5> + <p class="infot">{$userAddress['userName']} {$userAddress['userPhone']}</p> + <p class="infob"><i class="ui-icon-pin"></i>{$userAddress['areaName']}{$userAddress['userAddress']}</p> + </h5></li> + {/if} + </ul> + {volist name="$carts['carts']" id="ca"} + {php} + if($ca['isFreeShipping']){ + $freight = 0; + }else{ + if(!empty($userAddress)){ + $freight = WSTOrderFreight($ca['shopId'],$userAddress['areaId2']); + $shopFreight = $shopFreight + $freight; + }else{ + $freight = WSTOrderFreight($ca['shopId'],-1); + $shopFreight = $shopFreight + $freight; + } + } + $shopFreight = $shopFreight + $freight; + {/php} + <div class="wst-se-sh"> + <p class="ui-nowrap-flex shopn" shopId="{$ca['shopId']}"><i></i>{$ca['shopName']}</p> + {volist name="ca['list']" id="li"} + {:hook('wechatDocumentSettlementGoodsPromotion',['goods'=>$li])} + <ul class="ui-row goods j-g{$li.cartId}"> + <li class="ui-col ui-col-25"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </li> + <li class="ui-col ui-col-75"> + <ul class="ui-row info"> + <li class="ui-col ui-col-75"> + <div class="name"><p class="names">{$li['goodsName']}</p> + {if($li['specNames'])} + <p class="spec">规格: + {volist name="li['specNames']" id="sp"} + {$sp['catName']}:{$sp['itemName']} + {/volist} + </p> + {/if}</div> + </li> + <li class="ui-col ui-col-25"><p class="price" id="price_{$li['cartId']}" mval="{$li['shopPrice']}">¥{$li['shopPrice']}</p><p class="number" id="number_{$li['cartId']}" mval="{$li['cartNum']}">×{$li['cartNum']}</p></li> + </ul> + </li> + </ul> + {/volist} + {:hook('wechatDocumentCartShopPromotion',$ca)} + <div class="cost"> + <div>运费:<span id="shopF_{$ca['shopId']}">¥{php}echo sprintf("%.2f", $freight);{/php}</span></div> + <div id="reward_{$ca['shopId']}" style="display:none;">立减:<span id="shopF_{$ca['shopId']}">-&ensp;¥{:sprintf("%.2f", $ca['promotionMoney'])}</span></div> + <div>店铺合计(含运费):<span id="shopC_{$ca['shopId']}">¥{php}echo sprintf("%.2f", $freight+$ca['goodsMoney']-$ca['promotionMoney']);{/php}</span></div> + </div> + <div class="remarks"> + <textarea id="remark_{$ca['shopId']}" autocomplete="off" placeholder="填写订单备注:"></textarea> + </div> + </div> + {/volist} + <ul class="ui-list ui-list-text ui-list-link ui-list-active wst-se-mode"> + <li class="mode" onclick="javascript:dataShow('payments');"> + <h4 class="ui-nowrap">支付方式</h4> + <div class="ui-txt-info" id="paymentst">{if !empty($payments['0']) || !empty($payments['1'])}{if !empty($payments['1'])}{$payments['1']['0']['payName']}{else}{$payments['0']['0']['payName']}{/if}{else}无{/if}</div> + </li> + <li class="mode" onclick="javascript:dataShow('gives');"> + <h4 class="ui-nowrap">配送方式</h4> + <div class="ui-txt-info" id="givest">快递运输</div> + </li> + <li class="{if(WSTConf('CONF.isOpenScorePay')==1)}mode{/if}" onclick="javascript:getInvoiceList();"> + <h4 class="ui-nowrap">发票信息</h4> + <div class="ui-txt-info" id="invoicest">不开发票</div> + </li> + {if(WSTConf('CONF.isOpenScorePay')==1)} + <li onclick="javascript:dataShow('score');"> + <h4 class="ui-nowrap">积分支付</h4> + <div class="ui-txt-info" id="scoret">否</div> + </li> + {/if} + </ul> + </section> +{/block} +{block name="include"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 支付方式 */} +{if !empty($payments['0']) || !empty($payments['1'])} +<input type="hidden" name="" value="{if !empty($payments['1'])}1{else}0{/if}" id="paymentsh" autocomplete="off"> +<input type="hidden" name="" value="{if !empty($payments['1'])}{$payments['1']['0']['payCode']}{else}{$payments['0']['0']['payCode']}{/if}" id="paymentsw" autocomplete="off"> +<div class="wst-fr-box frame" id="payments"> + <div class="title"><span>支付方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('payments');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {if !empty($payments)} + {php}$paymentkey = 0;{/php} + {volist name='$payments' id='paymentvo'} + {volist name='$paymentvo' id='paymentitem'} + <ul class="ui-list" onclick="javascript:onSwitch(this);" style="border-bottom: 1px solid #f2f1f1;"> + <li><div class="wst-list-infose1" style="padding-left: 25px;"><i class="{$paymentitem['payCode']}"></i><span>{$paymentitem['payName']}</span></div></li> + <i class="ui-icon-push payments_{$paymentitem['payCode']} ui-icon-checked-s" payCode="{$paymentitem['payCode']}" mode="{$paymentitem['isOnline']}" word="{$paymentitem['payName']}"></i> + </ul> + {php}$paymentkey++;{/php} + {/volist} + {/volist} + {/if} + </div> + <button class="button" onclick="javascript:inDetermine('payments');">确定</button> +</div> +{/if} +{/* 配送方式 */} +<input type="hidden" name="" value="0" id="givesh" autocomplete="off"> +<div class="wst-fr-box frame" id="gives"> + <div class="title"><span>配送方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('gives');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>快递运输</span></div></li> + <i class="ui-icon-push gives0 ui-icon-checked-s wst-active" mode="0" word="快递运输"></i> + </ul> + <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>自提</span></div></li> + <i class="ui-icon-push gives1 ui-icon-unchecked-s" mode="1" word="自提"></i> + </ul> + </div> + <button class="button" onclick="javascript:inDetermine('gives');">确定</button> +</div> + +{/* 用户发票列表 */} +<script type="text/html" id="invoiceBox"> + {{# for(var i = 0; i < d.length; i++){ }} + <li invId="{{d[i].id}}" invCode="{{d[i].invoiceCode}}">{{d[i].invoiceHead}}</li> + {{# } }} +</script> + +{/* 发票信息层 */} +<div class="invoice_box" id="frame"> + <div class="title" id="boxTitle"><span>发票信息</span><i class="ui-icon-close-page" onclick="javascript:invoiceHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="invoice_content"> + <div class="inv_item"> + <div class="inv_tit">发票抬头</div> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,0);"> + <li><div class="pdtb10"><span>个人</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="个人"></i> + </ul> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,1);"> + <li><div class="pdtb10"><span>单位</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="单位"></i> + </ul> + <input type="hidden" id="invoice_obj" value="0" /> + <div class="wst-clear"></div> + + <div class="inv_hidebox"> + <div class="inv_head_inputbox"> + <input class="inv_head_input" type="text" id="invoice_head" placeholder="请填写单位名称" /> + <input type="hidden" id="invoiceId" value="0" /> + <div id="inv_headlist"> + <ul class="inv_list_item"> + </ul> + </div> + </div> + <div class="inv_code_inputbox"> + <input class="inv_code_input" type="text" id="invoice_code" placeholder="请填写纳税人识别码" /> + </div> + </div> + </div> + <div class="inv_item"> + <input type="hidden" id="isInvoice" value="0" /> + <div class="inv_tit inv_line">发票内容</div> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,0);"> + <li><div class="pdtb10"><span>不开发票</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="不开发票"></i> + </ul> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,1);"> + <li><div class="pdtb10"><span>明细</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="明细"></i> + </ul> + <div class="wst-clear"></div> + </div> + + <ul class="inv_tip"> + <li><i>·</i>发票金额不包含优惠券和积分支付部分</li> + <li><i>·</i>第三方卖家销售的商品发票由商家开具、寄出、发票内容由商家决定</li> + </ul> + <button class="button" onclick="javascript:saveInvoice();">确定</button> + </div> +</div> + +{/* 积分支付 */} +<input type="hidden" name="" value="0" id="scoreh" autocomplete="off"> +<div class="wst-fr-box frame" id="score"> + <div class="title"><span>积分支付</span><i class="ui-icon-close-page" onclick="javascript:dataHide('score');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>是</span></div></li> + <i class="ui-icon-push score1 ui-icon-checked-s wst-active" mode="1" word="是"></i> + </ul> + <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>否</span></div></li> + <i class="ui-icon-push score0 ui-icon-unchecked-s" mode="0" word="否"></i> + </ul> + <div class="wst-fr-score">(可用<span id="userOrderScore">{$userOrderScore}</span>个积分,可抵<span>¥<span id="userOrderMoney">{$userOrderMoney}</span></span>)</div> + </div> + <button class="button" onclick="javascript:inDetermine('score');">确定</button> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/settlement.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/settlement_quick.html b/hyhproject/wechat2/view/default/settlement_quick.html new file mode 100755 index 0000000..8ec51d4 --- /dev/null +++ b/hyhproject/wechat2/view/default/settlement_quick.html @@ -0,0 +1,189 @@ +{extend name="default/base" /} +{block name="title"}确认订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/settlement.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>确认订单</h1> + </header> +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <footer class="ui-footer wst-footer-btns" style="height:85px; border-top: 1px solid #e8e8e8;" id="footer"> + <input type="hidden" name="" value="{$carts['goodsTotalMoney']}" id="totalPrice" autocomplete="off"> + <div class="wst-se-total">应付总金额:<span id="totalMoney">¥{$carts['goodsTotalMoney']}</span></div> + <div class="wst-se-confirm"><button class="button" onclick="javascript:quickSubmitOrder();">确定</button></div> + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="2" id="sign" autocomplete="off"> + <section class="ui-container" style="border-bottom: 86px solid transparent;"> + {if($carts['carts'])} + {volist name="$carts['carts']" id="ca"} + <div class="wst-se-sh"> + <p class="ui-nowrap-flex shopn" shopId="{$ca['shopId']}"><i></i>{$ca['shopName']}</p> + {volist name="ca['list']" id="li"} + <ul class="ui-row goods"> + <li class="ui-col ui-col-25"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$li['goodsId']});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($li['goodsImg'],3)}" title="{$li['goodsName']}"> + </a> + </div> + </li> + <li class="ui-col ui-col-75"> + <ul class="ui-row info"> + <li class="ui-col ui-col-75"> + <div class="name"><p class="names">{$li['goodsName']}</p> + </div> + </li> + <li class="ui-col ui-col-25"><p class="price">¥{$li['shopPrice']}</p><p class="number">×{$li['cartNum']}</p></li> + </ul> + </li> + </ul> + {/volist} + {:hook('wechatDocumentCartShopPromotion',$ca)} + <div class="cost"> + <div>店铺合计:<span>¥{php}echo sprintf("%.2f", $ca['goodsMoney']);{/php}</span></div> + </div> + <div class="remarks"> + <textarea id="remark_{$ca['shopId']}" autocomplete="off" placeholder="填写订单备注:"></textarea> + </div> + </div> + {/volist} + {else} + <p class="ui-nowrap-flex shopn">您还没有添加商品哦,快去逛逛吧~</p> + {/if} + <ul class="ui-list ui-list-text ui-list-link ui-list-active wst-se-mode"> + <li class="mode" onclick="javascript:dataShow('payments');"> + <h4 class="ui-nowrap">支付方式</h4> + <div class="ui-txt-info" id="paymentst">{if !empty($payments['0']) || !empty($payments['1'])}{if !empty($payments['1'])}{$payments['1']['0']['payName']}{/if}{else}无{/if}</div> + </li> + <li class="{if(WSTConf('CONF.isOpenScorePay')==1)}mode{/if}" onclick="javascript:getInvoiceList();"> + <h4 class="ui-nowrap">发票信息</h4> + <div class="ui-txt-info" id="invoicest">不开发票</div> + </li> + {if(WSTConf('CONF.isOpenScorePay')==1)} + <li onclick="javascript:dataShow('score');"> + <h4 class="ui-nowrap">积分支付</h4> + <div class="ui-txt-info" id="scoret">否</div> + </li> + {/if} + </ul> + </section> +{/block} +{block name="include"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 支付方式 */} +{if !empty($payments['0']) || !empty($payments['1'])} +<input type="hidden" name="" value="{if !empty($payments['1'])}1{/if}" id="paymentsh" autocomplete="off"> +<input type="hidden" name="" value="{if !empty($payments['1'])}{$payments['1']['0']['payCode']}{else}{$payments['0']['0']['payCode']}{/if}" id="paymentsw" autocomplete="off"> +<div class="wst-fr-box frame" id="payments"> + <div class="title"><span>支付方式</span><i class="ui-icon-close-page" onclick="javascript:dataHide('payments');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + {if !empty($payments)} + {if !empty($payments['1'])} + {volist name="$payments['1']" id="pay" key="paykey"} + <ul class="ui-list" onclick="javascript:onSwitch(this);" style="border-bottom: 1px solid #f2f1f1;"> + <li><div class="wst-list-infose1" style="padding-left: 25px;"><i class="{$pay['payCode']}"></i><span>{$pay['payName']}</span></div></li> + <i class="ui-icon-push payments_{$pay['payCode']} ui-icon-checked-s" payCode="{$pay['payCode']}" mode="{$pay['isOnline']}" word="{$pay['payName']}"></i> + </ul> + {/volist} + {/if} + {/if} + </div> + <button class="button" onclick="javascript:inDetermine('payments');">确定</button> +</div> +{/if} + +{/* 用户发票列表 */} +<script type="text/html" id="invoiceBox"> + {{# for(var i = 0; i < d.length; i++){ }} + <li invId="{{d[i].id}}" invCode="{{d[i].invoiceCode}}">{{d[i].invoiceHead}}</li> + {{# } }} +</script> + +{/* 发票信息层 */} +<div class="invoice_box" id="frame"> + <div class="title" id="boxTitle"><span>发票信息</span><i class="ui-icon-close-page" onclick="javascript:invoiceHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="invoice_content"> + <div class="inv_item"> + <div class="inv_tit">发票抬头</div> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,0);"> + <li><div class="pdtb10"><span>个人</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="个人"></i> + </ul> + <ul class="ui-list inv_ul" onclick="javascript:invOnSwitch(this,1);"> + <li><div class="pdtb10"><span>单位</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="单位"></i> + </ul> + <input type="hidden" id="invoice_obj" value="0" /> + <div class="wst-clear"></div> + + <div class="inv_hidebox"> + <div class="inv_head_inputbox"> + <input class="inv_head_input" type="text" id="invoice_head" placeholder="请填写单位名称" /> + <input type="hidden" id="invoiceId" value="0" /> + <div id="inv_headlist"> + <ul class="inv_list_item"> + </ul> + </div> + </div> + <div class="inv_code_inputbox"> + <input class="inv_code_input" type="text" id="invoice_code" placeholder="请填写纳税人识别码" /> + </div> + </div> + </div> + <div class="inv_item"> + <input type="hidden" id="isInvoice" value="0" /> + <div class="inv_tit inv_line">发票内容</div> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,0);"> + <li><div class="pdtb10"><span>不开发票</span></div></li> + <i class="ui-icon-push invoices0 ui-icon-checked-s wst-active inv_chk" mode="0" word="不开发票"></i> + </ul> + <ul class="ui-list inv_ul none_float" onclick="javascript:isInvoice(this,1);"> + <li><div class="pdtb10"><span>明细</span></div></li> + <i class="ui-icon-push invoices1 ui-icon-unchecked-s inv_chk" mode="1" word="明细"></i> + </ul> + <div class="wst-clear"></div> + </div> + + <ul class="inv_tip"> + <li><i>·</i>发票金额不包含优惠券和积分支付部分</li> + <li><i>·</i>第三方卖家销售的商品发票由商家开具、寄出、发票内容由商家决定</li> + </ul> + <button class="button" onclick="javascript:saveInvoice();">确定</button> + </div> +</div> + +{/* 积分支付 */} +<input type="hidden" name="" value="0" id="scoreh" autocomplete="off"> +<div class="wst-fr-box frame" id="score"> + <div class="title"><span>积分支付</span><i class="ui-icon-close-page" onclick="javascript:dataHide('score');"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>是</span></div></li> + <i class="ui-icon-push score1 ui-icon-checked-s wst-active" mode="1" word="是"></i> + </ul> + <div class="wst-se-line"><p></p></div> + <ul class="ui-list" onclick="javascript:onSwitch(this);"> + <li><div class="wst-list-infose1"><span>否</span></div></li> + <i class="ui-icon-push score0 ui-icon-unchecked-s" mode="0" word="否"></i> + </ul> + <div class="wst-fr-score">(可用<span id="userOrderScore">{$userOrderScore}</span>个积分,可抵<span>¥<span id="userOrderMoney">{$userOrderMoney}</span></span>)</div> + </div> + <button class="button" onclick="javascript:inDetermine('score');">确定</button> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/settlement.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/shop_goods_list.html b/hyhproject/wechat2/view/default/shop_goods_list.html new file mode 100755 index 0000000..fd4216a --- /dev/null +++ b/hyhproject/wechat2/view/default/shop_goods_list.html @@ -0,0 +1,144 @@ +{extend name="default/base" /} +{block name="title"}店铺商品列表 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/shop_home.css?v={$v}"> +<style>body {background-color: #f6f6f8;}</style> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="padding-left: 0;border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('shops',1);" style="width: 76%;"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon" onclick="javascript:dataShow();"></span> + </header> +{/block} + +{block name="main"} +<input type="hidden" name="" value="" id="condition" autocomplete="off"> +<input type="hidden" name="" value="" id="desc" autocomplete="off"> +<input type="hidden" name="" value="{$shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$ct1}" id="ct1" autocomplete="off"> +<input type="hidden" name="" value="{$ct2}" id="ct2" autocomplete="off"> +<input type="hidden" name="" value="0" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="0" id="totalPage" autocomplete="off"> + + <section class="ui-container"> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,6);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + + + + <script id="shopList" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="WST.intoGoods({{d[i].goodsId}})"> + <div class="img j-imgAdapt" onclick="WST.intoGoods({{d[i].goodsId}})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({{d[i].goodsId}})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d[i].goodsImg }}" title="{{d[i].goodsName}}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{{ d[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> + </div> + {{# } }} + </script> + + <ul class="ui-tab-content"> + <li id="shops-list"> + + </li> + </ul> + + + </section> +{/block} + + +{block name="footer"} +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> + {/volist} + </div> +</div> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/shop_goods_list.js'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/shop_home.html b/hyhproject/wechat2/view/default/shop_home.html new file mode 100755 index 0000000..bce1617 --- /dev/null +++ b/hyhproject/wechat2/view/default/shop_home.html @@ -0,0 +1,278 @@ +{extend name="default/base" /} +{block name="title"}店铺详情 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/shop_home.css?v={$v}"> +{/block} +{block name="header"}{/block} + +{block name="main"} +<input type="hidden" name="" value="" id="condition" autocomplete="off"> +<input type="hidden" name="" value="" id="desc" autocomplete="off"> +<input type="hidden" name="" value="{$shopId}" id="shopId" autocomplete="off"> +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$ct1}" id="ct1" autocomplete="off"> +<input type="hidden" name="" value="{$ct2}" id="ct2" autocomplete="off"> +<input type='hidden' name="" value="0" id="currPage" autocomplete="off"> +<input type='hidden' name="" value="0" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-sh-banner" {if $data['shop']['shopBanner']!=''}style="background:url(__ROOT__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <header class="ui-header ui-header-positive wst-se-header2 wst-se-header3"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search wst-se-search2" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" disabled="disabled"> + </form> + </div> + <span class="wst-se-icon wst-se-icon0" onclick="javascript:dataShow();"></span> + {php}$cartNum = WSTCartNum();{/php} + <a href="{:url('wechat/carts/index')}"><span class="wst-se-icon wst-se-icon2">{if($cartNum>0)}<i>{$cartNum}</i>{/if}</span></a> + </header> + </div> + <div class="shop-banner"> + <div class="shop-photo"> + <div class="photo"> + <img src="__ROOT__/{$data.shop.shopImg}"> + <p class="name">{$data.shop.shopName}</p> + </div> + <span class="introduce" onclick="toShopInfo({$data['shop']['shopId']})">店铺介绍</span> + <div class="wst-clear"></div> + </div> + <div class="shop-info" {if(!$data['shop']['shopNotice'])}style="padding-bottom:0.1rem;border-bottom: 0.05rem solid #f2f1f1;"{/if}> + <div class="ui-row-flex"> + <div class="ui-col ui-col"> + <a class="shop-btn j-shopfollow {if($isFavor>0)}follow{/if}" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"></a> + <p id="followNum">{$followNum}</p> + <p>收藏数</p> + </div> + <div class="ui-col ui-col-2"></div> + <div class="ui-col ui-col"><p>{$data['shop']['scores']['areas']['areaName1']}{$data['shop']['scores']['areas']['areaName2']}</p><p>所在地</p></div> + </div> + </div> + {if($data['shop']['shopNotice'])} + <div class="shop-notice"> + <p class="title">店铺公告</p> + <p>{$data['shop']['shopNotice']}</p> + </div> + {/if} + <div class="wst-clear"></div> + </div> + {if !empty($data['shop']['shopAds'])} + <div class="shop-ads"> + <div class="ui-slider" style="padding-top:45%;"> + <ul class="ui-slider-content" style="width: 300%"> + {volist name="$data['shop']['shopAds']" id="ads"} + <li><span><a href="{$ads.adUrl}"><img style="width:100%; height:100%; display:block;" src="__ROOT__/{$ads.adImg}"></a></span></li> + {/volist} + </ul> + </div> + </div> + {/if} + <ul class="wst-sh-term" id="j-top"> + <li id="j-top1" class="active" onclick="javascript:switchTerm(1);">首页</li> + <li id="j-top0" onclick="javascript:switchTerm(0);">全部商品</li> + <div class="wst-clear"></div> + </ul> + <div class="wst-sh-index" id="j-index1"> + <div class="index"> + <p class="title">店主推荐</p> + {wst:shopgoods type='recom' num='4' id='re' shop="$data['shop']['shopId']" key="rk"} + <div class="wst-in-goods {if(($rk)%2==0)}left{else}right{/if}" onclick="WST.intoGoods({$re['goodsId']})"> + <div class="img j-imgIndex" onclick="WST.intoGoods({$re['goodsId']})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({$re['goodsId']})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{$re['goodsImg']}" title="{$re['goodsName']}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{$re['goodsName']}</div> + <div class="info"><span class="price">¥ <span>{$re['shopPrice']}</span></span></div> + </div> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">最新上架</p> + {wst:shopgoods type='new' num='4' id='ne' shop="$data['shop']['shopId']" key="nk"} + <div class="wst-in-goods {if(($nk)%2==0)}left{else}right{/if}" onclick="WST.intoGoods({$ne['goodsId']})"> + <div class="img j-imgIndex" onclick="WST.intoGoods({$ne['goodsId']})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({$ne['goodsId']})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{$ne['goodsImg']}" title="{$ne['goodsName']}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{$ne['goodsName']}</div> + <div class="info"><span class="price">¥ <span>{$ne['shopPrice']}</span></span></div> + </div> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">精品促销</p> + {wst:shopgoods type='best' num='4' id='be' shop="$data['shop']['shopId']" key="bk"} + <div class="wst-in-goods {if(($bk)%2==0)}left{else}right{/if}" onclick="WST.intoGoods({$be['goodsId']})"> + <div class="img j-imgIndex" onclick="WST.intoGoods({$be['goodsId']})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({$be['goodsId']})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{$be['goodsImg']}" title="{$be['goodsName']}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{$be['goodsName']}</div> + <div class="info"><span class="price">¥ <span>{$be['shopPrice']}</span></span></div> + <div class="info2"><span class="price">¥ {$be['marketPrice']}</span><span class="deal">成交数:{$be['saleNum']}</span></div> + </div> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">热销商品</p> + {wst:shopgoods type='hot' num='4' id='ho' shop="$data['shop']['shopId']" key="hk"} + <div class="wst-in-goods {if(($hk)%2==0)}left{else}right{/if}" onclick="WST.intoGoods({$ho['goodsId']})"> + <div class="img j-imgIndex" onclick="WST.intoGoods({$ho['goodsId']})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({$ho['goodsId']})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{$ho['goodsImg']}" title="{$ho['goodsName']}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{$ho['goodsName']}</div> + <div class="info"><span class="price">¥ <span>{$ho['shopPrice']}</span></span></div> + </div> + {/wst:shopgoods} + <div class="wst-clear"></div> + </div> + <div class="index"> + <p class="title">推荐更多</p> + <div id="best-list"></div> + <div class="wst-clear"></div> + </div> + <script id="shopBest" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="WST.intoGoods({{d[i].goodsId}})"> + <div class="img j-imgBest" onclick="WST.intoGoods({{d[i].goodsId}})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({{d[i].goodsId}})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d[i].goodsImg }}" title="{{d[i].goodsName}}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{{ d[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">¥ {{ d[i].marketPrice }}</span><span class="deal">成交数:{{ d[i].saleNum }}</span></div> + </div> + {{# } }} + </script> + </div> + + <div class="wst-sh-list" id="j-index0" style=""> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col sorts active" status="down" onclick="javascript:orderCondition(this,2);"> + <p class="pd0">销量</p><i class="down2"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,3);"> + <p class="pd0">价格</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,1);"> + <p class="pd0">人气</p><i class="down"></i> + </div> + <div class="ui-col ui-col sorts" status="down" onclick="javascript:orderCondition(this,6);"> + <p>上架时间</p><i class="down"></i> + </div> + </div> + <script id="shopList" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="wst-in-goods {{# if((i)%2==0){ }}left{{# }else{ }}right{{# } }}" onclick="WST.intoGoods({{d[i].goodsId}})"> + <div class="img j-imgAdapt" onclick="WST.intoGoods({{d[i].goodsId}})"> + <a href="javascript:void(0)" onclick="WST.intoGoods({{d[i].goodsId}})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d[i].goodsImg }}" title="{{d[i].goodsName}}"/> + </a> + </div> + <div class="name ui-nowrap-multi">{{ d[i].goodsName}}</div> + <div class="info"><span class="price">¥ <span>{{ d[i].shopPrice }}</span></span></div> + <div class="info2"><span class="price">¥ {{ d[i].marketPrice }}</span><span class="deal">成交数:{{ d[i].saleNum }}</span></div> + </div> + {{# } }} + </script> + + <div id="shops-list" class="wst-sh-goods"></div> + </div> + + </section> +{/block} + + +{block name="footer"} +<div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"></i> +</div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title">商品分类<i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + + <div class="ui-scrollerl" id="ui-scrollerl"> + <ul> + {volist name="$data['shopcats']" key="k" id="go"} + <li id="goodscate" class="wst-goodscate {if($k==1)}wst-goodscate_selected{/if}" onclick="javascript:showRight(this,{$k-1});">{$go['catName']}</li> + {/volist} + </ul> + </div> + {volist name="$data['shopcats']" key="k" id="go"} + <div class="wst-scrollerr goodscate1" {if($k!=1)}style="display:none;"{/if}> + <ul> + <li class="wst-goodsca"> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><span>&nbsp;{$go.catName}</span></a> + <a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']});"><i class="ui-icon-arrow"></i></a> + </li> + <li> + <div class="wst-goodscat"> + {volist name="$go['children']" id="go1"} + <span><a href="javascript:void(0);" onclick="javascript:getGoodsList({$go['catId']},{$go1['catId']});">{$go1.catName}</a></span> + {/volist} + </div> + </li> + </ul> + <div class="wst-clear"></div> + </div> + {/volist} + </div> +</div> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:getGoodsList(0);"> + <h4 class="ui-nowrap">全部商品</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="$data['shopcats']" key="k" id="g"} + <li onclick="javascript:getGoodsList({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/shop_home.js'></script> + +<script> +$(function(){ + // 广告不为空时 + {if !empty($data['shop']['shopAds'])} + shopAds(); + {/if} +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/shop_index.html b/hyhproject/wechat2/view/default/shop_index.html new file mode 100755 index 0000000..a1ee895 --- /dev/null +++ b/hyhproject/wechat2/view/default/shop_index.html @@ -0,0 +1,101 @@ +{extend name="default/base" /} +{block name="title"}店铺首页 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/shops.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(2);"></i> + <form action="" class="input-form"> + <input type="search" value="{$goodsName}" placeholder="按关键字搜索本店商品" onsearch="WST.search(2)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> +{/block} + +{block name="main"} +<input type="hidden" name="" value="{$goodsName}" id="keyword" autocomplete="off"> +<input type="hidden" name="" value="{$data.shop.shopId}" id="shopId" autocomplete="off"> + + <section class="ui-container"> + <div class="wst-shl-ads"> + <div class="wst-shop-home-bg" {if $data['shop']['shopBanner']!=''}style="background:url(__ROOT__/{$data['shop']['shopBanner']}) no-repeat center top;background-size:cover;" {/if}> + <div class="wst-shop-photo"> + <img src="__ROOT__/{:WSTImg($data.shop.shopImg,3)}"> + </div> + <div class="wst-shop-name">{$data.shop.shopName}</div> + + <div class="shop-home-btn-box"> + <div class="ui-btn-group ui-row"> + <a href="tel:{$data.shop.shopTel}" style="width:45.5%;margin-right:15px;" class="ui-btn-lg shop-home-btn ui-col ui-col-50"> + <img src="__WECHAT__/img/icon_kf.png"> + 联系卖家 + </a> + <button class="ui-btn-lg shop-home-btn ui-col ui-col-50 f-btn" id="fBtn" onclick="{if ($isFavor>0)}WST.cancelFavorite({$isFavor},1){else /}WST.favorites({$data.shop.shopId},1){/if}"> + {if ($isFavor>0)} + <img src="__WECHAT__/img/icon_gz.png"> + <span id="fStatus">已关注</span> + {else /} + <img src="__WECHAT__/img/icon_gz.png"> + <span id="fStatus">关注店铺</span> + {/if} + </button> + </div> + </div> + + <div class="score-box"> + <div class="ui-row-flex ui-whitespace score-item"> + <div class="ui-col ui-col">商品评分:{$data.shop.scores.goodsScore}</div> + <div class="ui-col ui-col">时效评分:{$data.shop.scores.timeScore}</div> + <div class="ui-col ui-col">服务评分:{$data.shop.scores.serviceScore}</div> + </div> + </div> + + </div> + + <div class="wst-shop-home-info"> + <ul class="shop-info"> + <li class="ui-nowrap ui-whitespace">商家地址:<span>{$data.shop.shopAddress}</span></li> + <li class="ui-nowrap ui-whitespace">商家电话:<span>{$data.shop.shopTel}</span></li> + <li class="ui-nowrap ui-whitespace">服务时间:<span>{$data.shop.serviceStartTime}-{$data.shop.serviceEndTime}</span></li> + <li class="ui-nowrap ui-whitespace">发票说明: + <span> + {if ($data.shop.isInvoice==1)} + 可开发票({$data.shop.invoiceRemarks}) + {else /} + 不支持发票 + {/if} + </span> + </li> + </ul> + <div class="shop-qrcode"> + <div id='qrcode'></div> + </div> + </div> + + </div> + </div> + </section> +{/block} + + +{block name="footer"}{/block} +{block name="js"} +<script src="__WECHAT__/js/qrcode.js"></script> + <script> + $(function(){ + var url= "{:url('wechat/shops/home',array('shopId'=>$data['shop']['shopId']),'',true)}"; + //参数1表示图像大小,取值范围1-10;参数2表示质量,取值范围'L','M','Q','H' + var qr = qrcode(9, 'H'); + qr.addData(url); + qr.make(); + $("#qrcode").html(qr.createImgTag()); + $('.wst-se-search').on('submit', '.input-form', function(event){ + event.preventDefault(); + }) + }); + </script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/shop_street.html b/hyhproject/wechat2/view/default/shop_street.html new file mode 100755 index 0000000..ddb4e21 --- /dev/null +++ b/hyhproject/wechat2/view/default/shop_street.html @@ -0,0 +1,147 @@ +{extend name="default/base" /} +{block name="title"}店铺街 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/swiper.min.css"> +<link rel="stylesheet" href="__WECHAT__/css/shops_list.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="history.back()"></i> + <div class="wst-se-search" onclick="javascript:WST.searchPage('shops',1);"> + <i class="ui-icon-search" onclick="javascript:WST.searchPage('shops',1);"></i> + <form action="" class="input-form"> + <input type="search" value="{$keyword}" placeholder="按关键字搜索店铺" onsearch="WST.search(1)" autocomplete="off" disabled="disabled"> + </form> + </div> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$keyword}" id="keyword" autocomplete="off"> + <input type="hidden" name="" value="" id="condition" autocomplete="off"> + <input type="hidden" name="" value="" id="desc" autocomplete="off"> + <input type="hidden" name="" value="" id="catId" autocomplete="off"> + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="wst-shl-ads"> + <div class="title">名铺抢购</div> + <div class="wst-shl-adsb"> + <div class="swiper-container"> + <div class="swiper-wrapper"> + {wst:ads code="wx-ads-street" cache='86400' num='4'} + <div class="swiper-slide" style="width:33.333333%;"> + <a href="{$vo.adURL}" class="adsImg"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($vo.adFile,2)}"></a> + </div> + {/wst:ads} + </div> + </div> + </div> + </div> + <div class="ui-row-flex wst-shl-head"> + <div class="ui-col ui-col"> + <div class="ui-select wst-shl-select choice active"> + <select onchange="javascript:orderSelect(this.value);"> + <option value="">主营</option> + {volist name="goodscats" id="g"} + <option value="{$g['catId']}">{$g['catName']}</option> + {/volist} + </select> + </div> + </div> + <div class="ui-col ui-col evaluate"> + <p class="choice sorts" status="down" onclick="javascript:orderCondition(this,1);">好评度<i class="down"></i></p> + </div> + </div> + <ul class="ui-tab-content"> + <li id="shops-list"></li> + </ul> + </section> +<script id="list" type="text/html"> +{{# if(d && d.length>0){ }} +{{# for(var i=0; i<d.length; i++){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver wst-shl-list"> + <div class="ui-col"> + <div class="ui-row-flex"> + <div class="ui-col ui-col-2" > + <div class="img j-imgAdapt"><a href="javascript:void(0);" onclick="goShopHome({{ d[i].shopId }})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d[i].shopImg }}" title="{{ d[i].shopName }}"></a> + </div> + </div> + <div class="ui-col info" onclick="goToShop({{d[i].shopId}})"> + <div class="title ui-nowrap">{{d[i].shopName}}</div> + <p class="ui-nowrap">主营:{{ d[i].catshops }}</p> + <p><span>店铺评分:</span> + {{# for(var j=1; j<6; j++){ }} + {{# if(j <= d[i].totalScore){ }} + <i class="bright"></i> + {{# }else{ }} + <i class="dark"></i> + {{# } }} + {{# } }} + </p> + + </div> + <div class="ui-col ui-col-2 f-goshops" onclick="goToShop({{d[i].shopId}})"> + <a href="javascript:void(0);" onclick="goShopHome({{ d[i].shopId }})"><span class="wst-action">进入店铺</span></a> + </div> + </div> + </div> + <div class="ui-col" style="margin-top:5px;"> + <div class="ui-row-flex ui-whitespace goods-box"> + {{# var gLength = Math.min(d[i].goods.length,4) }} + {{# for(var g=0;g<gLength;++g){ }} + <div class="goods-item" > + {{# if(d[i].goods[g].goodsImg){ }} + <a href="javascript:void(0);" onclick="WST.intoGoods({{d[i].goods[g].goodsId}})"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{WST.replaceImg(d[i].goods[g].goodsImg,'_m_thumb')}}" > + <i class="goodsPrice ui-nowrap" >¥ {{d[i].goods[g].shopPrice}}</i> + </a> + {{# } }} + </div> + {{# } }} + </div> + </div> + <div class="wst-clear"></div> + </div> +{{# } }} +{{# }else{ }} +<div class="wst-prompt-icon"><img src="__WECHAT__/img/nothing-follow-shps.png"></div> +<div class="wst-prompt-info"> + <p>对不起,没有相关店铺。</p> +</div> +{{# } }} +</script> +{/block} +{block name="include"} + <div class="wst-co-search" id="wst-shops-search" style="background-color: #f6f6f8;"> + <header class="ui-header ui-header-positive wst-se-header2" style="border-bottom: 1px solid #f6f6f8;"> + <i class="ui-icon-return" onclick="javascript:WST.searchPage('shops',0);"></i> + <div class="wst-se-search"> + <i class="ui-icon-search" onclick="javascript:WST.search(1);"></i> + <form action="" class="input-form"> + <input type="search" value="" placeholder="按关键字搜索店铺" onsearch="WST.search(1)" autocomplete="off" id="wst-search"> + </form> + </div> + </header> + <div class="classify"> + <ul class="ui-list ui-list-text ui-list-link ui-list-active shops"> + <li onclick="javascript:searchCondition(0);"> + <h4 class="ui-nowrap">全部店铺</h4> + </li> + </ul> + <ul class="ui-list ui-list-text ui-list-active shops2"> + {volist name="goodscats" id="g"} + <li onclick="javascript:searchCondition({$g['catId']});"> + <h4 class="ui-nowrap">{$g['catName']}</h4> + <div class="ui-txt-info">查看全部</div> + </li> + {/volist} + </ul> + </div> + </div> + <script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/swiper.jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/shops_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/cashconfigs/cashconfigs.js b/hyhproject/wechat2/view/default/users/cashconfigs/cashconfigs.js new file mode 100755 index 0000000..63c095b --- /dev/null +++ b/hyhproject/wechat2/view/default/users/cashconfigs/cashconfigs.js @@ -0,0 +1,251 @@ +jQuery.noConflict(); +// 获取提现记录 +function getCashConfigs(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/cashconfigs/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#listBox').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-account.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>没有提现账户</p>'; + html += '</div>'; + $('#listBox').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getCashConfigs(); + WST.initFooter('user'); + // 弹出层 + $('#modal-large').css({'top':0,'margin-top':0}); + var h = WST.pageHeight(); + $("#frame").css('bottom','-'+h/2); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getCashConfigs(); + } + } + }); +}); + + + + + +//新增或编辑提现账号 +function editAddress(id){ + $('#accTargetId').val(''); + $('#accUser').val(''); + $('#accNo').val(''); + $('#accAreaId').val(''); + $('#addresst').html('请选择地址'); + $('.wst-ad-submit .button').attr('onclick','javascript:saveConfig('+id+');'); + if(id>0){ + $('.iziModal-header-title').html('修改提现账号'); + $.post(WST.U('wechat/cashConfigs/getById'), {id:id}, function(data){ + var info = WST.toJson(data); + if(info){ + $('#accTargetId').val(info.accTargetId); + $('#accUser').val(info.accUser); + $('#accNo').val(info.accNo); + $('#accAreaId').val(info.accAreaId); + $('#areaName').html($('#addr_'+id).val()); + } + addressInfo= null; + }); + }else{ + $('.iziModal-header-title').html('新增提现账号'); + } + jQuery('#modal-large').iziModal('open'); +} +jQuery("#modal-large").iziModal({ + title: "新增提现账号", + subtitle: "", + iconClass: 'icon-chat', + overlayColor: 'rgba(0, 0 0, 0.6)', + headerColor: '#ffffff' +}); + + +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + $.post(WST.U('wechat/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + var level = parseInt(obj.attr('level'),10); + $('.area_'+level).addClass('hide'); + var level = level+1; + html.push('<div id="'+tid+'" class="list '+opts.className+' area_'+level+'" areaId="0" level="'+level+'">'); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<p onclick='javascript:inChoice(this,\""+tid+"\","+tmp.areaId+","+level+");'>"+tmp.areaName+"</p>"); + } + html.push('</div>'); + $(html.join('')).insertAfter('#'+opts.id); + var h = WST.pageHeight(); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + $(".wst-fr-box .option").append('<p class="ui-nowrap-flex term active_'+level+' active" onclick="javascript:inOption(this,'+level+')">请选择</p>'); + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + $('#accAreaId').val(opts.lastVal); + var ht = ''; + $('.wst-fr-box .term').each(function(){ + ht += $(this).html(); + }); + $('#areaName').html(ht); + dataHide(); + } + }); +} + +//地址选择 +function inOption(obj,n){ + $(obj).addClass('active').siblings().removeClass('active'); + $('.area_'+n).removeClass('hide').siblings('.list').addClass('hide'); + var level = $('#level').val(); + var n = n+1; + for(var i=n; i<=level; i++){ + $('.area_'+i).remove(); + $('.active_'+i).remove(); + } +} + +function inChoice(obj,id,val,level){ + $('#level').val((level+1)); + $(obj).addClass('active').siblings().removeClass('active'); + $('#'+id).attr('areaId',val); + $('.active_'+level).removeClass('active').html($(obj).html()); + WST.ITAreas({id:id,val:val,className:'j-areas'}); +} + + +//弹框 +function dataShow(){ + jQuery('#frame').show(); + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); + setTimeout(function(){ + jQuery('#frame').hide(); + },500); +} + + + +//保存 +function saveConfig(cId){ + var accUser = $('#accUser').val(); + var accNo = $('#accNo').val(); + var areaId = $('#areaId').val(); + var accAreaId = $('#accAreaId').val(); + var accTargetId = $('#accTargetId').val(); + + if(accTargetId==''){ + WST.msg('请选择账户类型','info'); + $('#accTargetId').focus(); + return false; + } + + if(accAreaId==''){ + WST.msg('请选择地址','info'); + return false; + } + + if(accUser==''){ + WST.msg('持卡人不能为空','info'); + $('#accUser').focus(); + return false; + } + if(accNo==''){ + WST.msg('卡号不能为空','info'); + return false; + } + + var param = {}; + param.id = cId; + param.accAreaId = accAreaId; + param.accUser = accUser; + param.accNo = accNo; + param.accTargetId = accTargetId; + $('.wst-ad-submit .button').addClass("active").attr('disabled', 'disabled'); + var act = (cId>0)?'edit':'add'; + $.post(WST.U('wechat/cashconfigs/'+act), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + history.go(0); + },1000); + }else{ + WST.msg(json.msg,'warn'); + setTimeout(function(){ + $('.wst-ad-submit .button').removeAttr('disabled').removeClass("active"); + },1500); + } + data = json = null; + }); +} + +//删除提现账号 +function del(id){ + WST.dialog('确定删除吗?','toDel('+id+')'); +} +//删除提现账号 +function toDel(id){ + $.post(WST.U('wechat/cashconfigs/del'), {id:id}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + $('#listBox').html(' '); + $('#currPage').val(0) + getCashConfigs(); + }else{ + WST.msg(json.msg,'warn'); + } + WST.dialogHide('prompt'); + data = json = null; + }); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/cashconfigs/edit.html b/hyhproject/wechat2/view/default/users/cashconfigs/edit.html new file mode 100755 index 0000000..1804a04 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/cashconfigs/edit.html @@ -0,0 +1,48 @@ + <div id="modal-large" class="iziModal"> + <input type="hidden" name="" value="" id="accAreaId" autocomplete="off"> + <div class="wst-ad-form"> + <div class="ui-form-itemin"> + <label class="word">账户类型:</label> + <select name="accTargetId" id="accTargetId" class="wst-ca-choice"> + <option value="">请选择</option> + {volist name="$banks" id="b"} + <option value="{$b['bankId']}">{$b['bankName']}</option> + {/volist} + </select> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">账户地址:</label> + <div id="areaName" class="ui-nowrap-flex address" onclick="javascript:dataShow();">请选择账户地址</div> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">持卡人:</label><input class="ui-border-binte" id="accUser" type="text" placeholder="请填写持卡人姓名" maxLength="20"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">卡号:</label> + <input class="ui-border-binte" id="accNo" type="text" maxLength="20" placeholder="请填写银行卡号" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <div class="wst-ad-line"><p></p></div> + </div> + <div class="wst-ad-submit"><button class="ui-btn-lg button" onclick="javascript:saveAddress(0);">保存</button></div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 地址框 */} +<div class="wst-fr-box" id="frame" style="display:none;"> + <input type="hidden" name="" value="" id="level" autocomplete="off"> + <div class="title"><span>账户地址</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <div class="option"> + <p class="ui-nowrap-flex term active_0 active" onclick="javascript:inOption(this,0)">请选择</p> + </div> + <div class="wst-clear"></div> + <div id="area_0" class="list j-areas area_0" areaId="0" level="0"> + {volist name="area" id="ar"} + <p onclick="javascript:inChoice(this,'area_0',{$ar['areaId']},0);">{$ar['areaName']}</p> + {/volist} + </div> + </div> +</div> + </div> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/cashconfigs/list.html b/hyhproject/wechat2/view/default/users/cashconfigs/list.html new file mode 100755 index 0000000..ac855b0 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/cashconfigs/list.html @@ -0,0 +1,55 @@ +{extend name="default/base" /} +{block name="title"}我的提现账户 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/iziModal.css?v={$v}"> +<link rel="stylesheet" href="__WECHAT__/css/cashconfigs.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的提现账户</h1> + <span class="add" onclick="editAddress()">添加</span> + </header> +{/block} +{block name="main"} + + + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<script type="text/html" id="list"> + {{# for(var i=0;i<d.length;++i){ }} + <ul class="ui-row" > + <li class="ui-col ui-col-80" onclick="editAddress({{d[i].id}})"> + <input type="hidden" id="addr_{{d[i].id}}" value="{{d[i].areaName}}"> + <p class="wst-ca-accno">{{d[i].accNo}}</p> + <p class="wst-ca-info"> 持卡人姓名:{{d[i].accUser}}</p> + <p class="wst-ca-info"> 开户行:{{d[i].bankName}}</p> + </li> + <li class="ui-col ui-col-20" onclick="del({{d[i].id}})"><p class="c-tr"><span class="delete-icon"></span>删除<p></li> + </ul> + {{# } }} +</script> +<section class="ui-container" id="listBox"> + +</section> + + + + +{include file="default/dialog" /}<!-- 对话框模板 --> +{include file="default/users/cashconfigs/edit" /}<!-- 新增/编辑收货地址模板 --> + +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/izimodal/iziModal.js'></script> +<script type='text/javascript' src='__WECHAT__/users/cashconfigs/cashconfigs.js?v={$v}'></script> +{/block} + + + + + + + diff --git a/hyhproject/wechat2/view/default/users/cashdraws/cashdraws.js b/hyhproject/wechat2/view/default/users/cashdraws/cashdraws.js new file mode 100755 index 0000000..53289f5 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/cashdraws/cashdraws.js @@ -0,0 +1,47 @@ +jQuery.noConflict(); +// 获取提现记录 +function getCashDraws(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/cashdraws/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getCashDraws(); + WST.initFooter('user'); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getCashDraws(); + } + } + }); +}); diff --git a/hyhproject/wechat2/view/default/users/cashdraws/list.html b/hyhproject/wechat2/view/default/users/cashdraws/list.html new file mode 100755 index 0000000..f64ab41 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/cashdraws/list.html @@ -0,0 +1,52 @@ +{extend name="default/base" /} +{block name="title"}提现记录 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/cashdraws.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>提现记录</h1> + </header> +{/block} +{block name="main"} + +<script type="text/html" id="scoreList"> +<ul class="ui-row score-detail"> +{{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75"> + <p>{{d[i].accUser}}</p> + <p>{{d[i].accTargetName}}{{d[i].accAreaName}}</p> + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 score-text"> + {{#if(d[i].cashSatus==1){}} + <span style="color:green;">已通过</span> + {{#}else if(d[i].cashSatus==-1){}} + 失败 + {{#}else{}} + <span style="color: #59595c;">待处理</span> + {{#}}} + <br /> + - {{d[i].money}} + </li> + {{#if(d[i].cashSatus==-1){}} + <li class="ui-col">提现失败原因:{{d[i].cashRemarks}}</li> + {{#}}} + <div class="wst-clear"></div> + <div class="score-line"></div> +{{# } }} +</ul> +</script> + +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<section class="ui-container"> + <div id="score-list"></div> +</section> + + +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/cashdraws/cashdraws.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/edit.html b/hyhproject/wechat2/view/default/users/edit.html new file mode 100755 index 0000000..80e60a1 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/edit.html @@ -0,0 +1,127 @@ +{extend name="default/base" /} +{block name="title"}账户管理 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/userinfo.css?v={$v}"> +{/block} +{block name="header"} + <div id="useri_infos"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <a href="{:url('wechat/users/index')}"><i class="ui-icon-return return_users"></i></a><h1 class="useri_info">账户管理</h1> + <i onclick="javascript:closeUploadArea()" style="display:none;font-size: 0.15rem;" id="upload_close">关闭</i> + <a href="javascript:void(0);" style="display:none;float:right;font-size: 0.15rem;" id="upload_button">上传</a> + </header> +{/block} +{block name="main"} + <section class="ui-container" id="useri_info"> + <ul class="ui-list ui-list-one ui-list-link wst-ed-info"> + <li> + <div class="ui-list-info"> + <h4 class="ui-nowrap" id="chooseImages">头像</h4> + <input type="file" id="uploadImg" class="uploadfile-input" accept="image/*"> + <div class="ui-list-thumb" id="previewImages" style="width: 65px;"> + <span> + <img src="{:WSTUserPhoto($user['userPhoto'])}" class="wst-useri_portrait" id="imgurl"> + </span> + </div> + </div> + </li> + </ul> + <div class="wst-useri_line"></div> + <ul class="ui-list ui-list-text wst-ed-info"> + <li> + <h4 class="ui-nowrap">用户名</h4> + <div class="ui-txt-info">{$user['loginName']}</div> + </li> + </ul> + <div class="wst-useri_line"></div> + <ul class="ui-list ui-list-text ui-list-link wst-ed-info"> + <li onclick="javascript:openNickName();"> + <h4 class="ui-nowrap">昵称</h4> + <div class="ui-txt-info" id="nickname">{$user['userName']}</div> + </li> + <div class="wst-useri_line"></div> + <li onclick="javascript:openUserSex();"> + <h4 class="ui-nowrap">性别</h4> + <?php $usersex = array('保密','男','女');?> + <div class="ui-txt-info" id="usersex"><?php echo $usersex[$user['userSex']];?></div> + </li> + </ul> + <div class="wst-useri_line"></div> + </section> + <sction class="ui-container" id="upload_modal"> + <div class="upload-modal"> + <div id="clipArea" class="clipArea"></div> + <input type="hidden" id="imgData" autocomplete="off"> + </div> + </sction> + </div> + <div id="useri_nickname" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnUserinfo()"></i><h1>修改昵称</h1> + </header> + <section class="ui-container" style="height:80%;"> + <div class="wst-useri_determine"> + <input type="text" id="userName" placeholder="昵称"> + </div> + + </section> + <footer> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-ed-button" onclick="javascript:editNickName()"> + 确定 + </button> + </div> + </footer> + </div> + <div id="useri_sex" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnUserinfo()"></i><h1>修改性别</h1> + </header> + <section class="ui-container" id="useri_sex"> + <ul class="ui-list wst-listse wst-listse1" onclick="javascript:eidtUserSex(this, 0);"> + <li> + <div class="wst-list-infose1"> + <span>保密</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==0){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + <ul class="ui-list wst-listse wst-listse2" onclick="javascript:eidtUserSex(this, 1);"> + <li> + <div class="wst-list-infose1"> + <span>男</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==1){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + <ul class="ui-list wst-listse wst-listse3" onclick="javascript:eidtUserSex(this, 2);"> + <li> + <div class="wst-list-infose1"> + <span>女</span> + </div> + </li> + <div class="wst-list-infose2"> + <?php if($user['userSex']==2){ ?> + <i class="ui-icon-checked-s wst-icon-checked-s_se"></i> + <?php } ?> + </div> + </ul> + </section> + </div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/photoclip/iscroll-zoom.js'></script> +<script type='text/javascript' src='__WECHAT__/js/photoclip/hammer.js'></script> +<script type='text/javascript' src='__WECHAT__/js/photoclip/jquery.photoClip.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/photoclip/upload.hpictures.js'></script> +<script type='text/javascript' src='__WECHAT__/users/user.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/favorites/favorite_shop.js b/hyhproject/wechat2/view/default/users/favorites/favorite_shop.js new file mode 100755 index 0000000..992fc60 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/favorites/favorite_shop.js @@ -0,0 +1,98 @@ +// 获取关注的店铺 +function getFavorites(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/favorites/listShopQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#shopBox').html(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-follow-shps.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>您还没有关注店铺。</p>'; + html += '</div>'; + $('#shopBox').html(html); + } + imgShop('j-imgAdapt'); + imgShop('goodsImg'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); + + +} +function goToShop(sid){ + location.href=WST.U('wechat/shops/home','shopId='+sid); +} +// 全选 +function checkAll(obj){ + var chk = $(obj).prop('checked'); + $('.s-active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +// 取消关注 +function cancelFavorite(){ + WST.dialogHide('prompt'); + var fids = new Array(); + $('.s-active').each(function(k,v){ + if($(this).attr('checked')){ + fids.push($(this).attr('fid')); + } + }); + fids = fids.join(','); + if(fids==''){ + WST.msg('请先选择店铺','info'); + return; + } + $.post(WST.U('wechat/favorites/cancel'),{id:fids,type:1},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#currPage').val('0') + getFavorites(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getFavorites(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getFavorites(); + } + } + }); +}); + +//适应图片大小正方形 +function imgShop(name){ + var w = $('.'+name).width(); + if(name == 'j-imgAdapt'){ + $('.'+name).css({"width": w+"px","height": w+"px"}); + }else{ + $('.'+name).css({"width": w+"px","height": w+20+"px"}); + } + $('.'+name+' a').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a img').css({"width": w+"px","height": w+"px"}); + $('.'+name+' a .goodsPrice').css({"width": w+"px"}); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/favorites/favorites.js b/hyhproject/wechat2/view/default/users/favorites/favorites.js new file mode 100755 index 0000000..e288a80 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/favorites/favorites.js @@ -0,0 +1,95 @@ +// 获取关注的商品 +function getFavorites(){ + $('#Load').show(); + loading = true; + var param = {}; + param.id = $('#catId').val(); + param.condition = $('#condition').val(); + param.desc = $('#desc').val(); + param.keyword = $('#searchKey').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/favorites/listGoodsQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('fGoods').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#goods-list').html(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-follow-goods.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>您还没有关注商品。</p>'; + html += '</div>'; + $('#goods-list').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +// 全选 +function checkAll(obj){ + var chk = $(obj).attr('checked'); + $('.active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +// 取消关注 +function cancelFavorite(){ + WST.dialogHide('prompt'); + var gids = new Array(); + $('.active').each(function(k,v){ + if($(this).attr('checked')){ + gids.push($(this).attr('gid')); + } + }); + gids = gids.join(','); + if(gids==''){ + WST.msg('请先选择商品','info'); + return; + } + $.post(WST.U('wechat/favorites/cancel'),{id:gids,type:0},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#currPage').val('0') + getFavorites(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getFavorites(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getFavorites(); + } + } + }); +}); + + + +function addCart(goodsId){ + $.post(WST.U('wechat/carts/addCart'),{goodsId:goodsId,buyNum:1},function(data,textStatus){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + }else{ + WST.msg(json.msg,'info'); + } + }); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/favorites/list_goods.html b/hyhproject/wechat2/view/default/users/favorites/list_goods.html new file mode 100755 index 0000000..9bd6cf7 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/favorites/list_goods.html @@ -0,0 +1,74 @@ +{extend name="default/base" /} +{block name="title"}我的关注 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/favorites.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>关注商品</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger" onclick="WST.dialog('确认要取消关注吗','cancelFavorite()');"> + 取消关注 + </button> + </div> + </div> + </div> + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <script id="fGoods" type="text/html"> + {{# for(var i=0; i<d.length; i++){ }} + <div class="ui-row-flex wst-shl-list" > + <label class="ui-checkbox"> + <input class="active" type="checkbox" gId="{{d[i].favoriteId}}" onclick="javascript:WST.changeIconStatus($(this), 1);"> + </label> + + <div class="ui-col"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d[i].goodsId}});"> + <img src="__ROOT__/{{WST.conf.GOODS_LOGO}}" data-echo="__ROOT__/{{d[i].goodsImg}}" title="{{d[i].shopName}}"></a></div> + </div> + <div class="ui-col ui-col-2 info"> + <div class="title ui-nowrap-multi" onclick="javascript:WST.intoGoods({{d[i].goodsId}});">{{d[i].goodsName}}</div> + <p class="price"><span>¥ </span>{{d[i].shopPrice}}</p> + <p class="deal">成交数:{{d[i].saleNum}}</p><span class="add-cart" onclick="addCart({{d[i].goodsId}})"></span> + </div> + </div> + {{# } }} + </script> + <section class="ui-container info-prompt"> + <ul class="ui-tab-content"> + <li id="goods-list"></li> + </ul> + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/favorites/favorites.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/favorites/list_shops.html b/hyhproject/wechat2/view/default/users/favorites/list_shops.html new file mode 100755 index 0000000..7758716 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/favorites/list_shops.html @@ -0,0 +1,92 @@ +{extend name="default/base" /} +{block name="title"}关注店铺 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/favorites.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>关注店铺</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:42px; border-top: 1px solid #e8e8e8;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger" onclick="WST.dialog('确认要取消关注吗','cancelFavorite()');"> + 取消关注 + </button> + </div> + </div> + </div> + + + + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="ui-row-flex ui-whitespace ui-row-flex-ver shop-box"> + <div class="ui-col f-shop-header"> + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-3"> + <label class="ui-checkbox f-chk"> + <input class="s-active" type="checkbox" fId="{{d[i].favoriteId}}" onclick="javascript:WST.changeIconStatus($(this), 1);"> + </label> + <div class="shopImg j-imgAdapt"> + <a href="javascript:void(0);" onclick="goToShop({{d[i].shopId}})"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{ d[i].shopImg }}" title="{{ d[i].shopName }}"></a> + </div> + </div> + <div class="ui-col ui-col-2" onclick="goToShop({{d[i].shopId}})"> + <div class="f-shopname ui-nowrap ui-whitespace">{{d[i].shopName}}</div> + + </div> + <div class="ui-col ui-col-3 f-goshops" onclick="goToShop({{d[i].shopId}})"> + <a href="javascript:void(0);" onclick="goToShop({{d[i].shopId}})"><span class="wst-action">进入店铺</span></a> + </div> + </div> + </div> + <div class="ui-row-flex goods-box"> + {{# var gLength = Math.min(d[i].goods.length,4) }} + {{# for(var g=0;g<gLength;++g){ }} + <div class="goodsImg"><a href="javascript:void(0);" onclick="WST.intoGoods({{d[i].goods[g].goodsId}})"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{WST.replaceImg(d[i].goods[g].goodsImg,'_m_thumb')}}"> + <p class="goodsPrice ui-nowrap"><span>¥ </span>{{d[i].goods[g].shopPrice}}</p></a> + </div> + {{# } }} + + </div> + <div class="wst-clear"></div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/favorites/favorite_shop.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/history/history.js b/hyhproject/wechat2/view/default/users/history/history.js new file mode 100755 index 0000000..6f063aa --- /dev/null +++ b/hyhproject/wechat2/view/default/users/history/history.js @@ -0,0 +1,48 @@ +// 获取浏览记录 +function getHistory(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/goods/historyQuery'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('list').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#listBox').append(html); + }); + $('#currPage').val(data.CurrentPage); + $('#totalPage').val(data.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-history.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无浏览记录</p>'; + html += '<button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button>'; + html += '</div>'; + $('#listBox').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + WST.initFooter(); + getHistory(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getHistory(); + } + } + }); +}); + diff --git a/hyhproject/wechat2/view/default/users/history/list.html b/hyhproject/wechat2/view/default/users/history/list.html new file mode 100755 index 0000000..00c37d5 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/history/list.html @@ -0,0 +1,47 @@ +{extend name="default/base" /} +{block name="title"}浏览记录 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/history.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>浏览记录</h1> + </header> +{/block} +{block name="main"} +<input type="hidden" name="" value="" id="currPage" autocomplete="off"> +<input type="hidden" name="" value="" id="totalPage" autocomplete="off"> +<script type="text/html" id="list"> + {{# for(var i=0;i<d.length;++i){ }} + <div class="ui-row-flex goods-item"> + <div class="ui-col"> + <div class="img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d[i]['goodsId']}});"><img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d[i]['goodsImg']}}"></a> + </div> + </div> + <div class="ui-col ui-col-3" onclick="javascript:WST.intoGoods({{d[i]['goodsId']}});"> + <div class="ui-row-flex ui-row-flex-ver wst-info"> + <div class="goodsTitle ui-nowrap-multi">{{d[i].goodsName}}</div> + <div> + <p class="price"><span>¥ </span>{{d[i].shopPrice}}</p> + <p class="goods-info">成交数:{{d[i].saleNum}}</p> + </div> + </div> + </div> + </div> + {{# } }} +</script> + + <section class="ui-container" id="listBox"> + </section> + + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/history/history.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/index.html b/hyhproject/wechat2/view/default/users/index.html new file mode 100755 index 0000000..ad3c25f --- /dev/null +++ b/hyhproject/wechat2/view/default/users/index.html @@ -0,0 +1,260 @@ +{extend name="default/base" /} +{block name="title"}我的 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/user.css?v={$v}"> +{/block} +{block name="header"}{/block} +{block name="main"} + <section class="ui-container" id="user"> + <div class="wst-users_info"> + <a href="{:url('wechat/messages/index')}"><i class="wst-msg-icon"> + {if ($data['message']['num']>0)} + <span class="number" id="msgNum">{$data['message']['num']}</span> + {/if} + </i></a> + <i class="ui-icon-set wst-info-icon" onclick="location.href='{:url('wechat/users/userset')}'"></i> + <div class="ui-row-flex" style="height:0.7rem"> + <div class="ui-col ui-col-2"> + <div class="wst-users_infol" id="previewImages"> + <img src="{:WSTUserPhoto($user['userPhoto'])}" class="wst-useri_portrait" id="imgurl"> + </div> + <p class="wst-users_infor wst-users_infortop"> + {:$user['userName']?$user['userName']:$user['loginName']} + {if ($user['ranks']['rankName']!='')}<img src="__ROOT__/{$user['ranks']['userrankImg']}">{/if} + </p> + {if ($user['ranks']['rankName']!='')} + <p class="wst-users_infor wst-users_inforbo">{$user['ranks']['rankName']}</p> + {/if} + </div> + <div class="ui-col"> + {php}$signScore=explode(",",WSTConf('CONF.signScore'));{/php} + {if(WSTConf('CONF.signScoreSwitch')==1 && $signScore[0]>0)} + <div class="wst-us-sign"> + {if(session('WST_USER.signScoreTime')==date('Y-m-d'))} + <a id="j-sign" class="sign sign2" disabled="disabled"></a> + {else} + <a id="j-sign" class="sign" onclick="javascript:inSign();"></a> + {/if} + </div> + {/if} + </div> + </div> + </div> + + {:hook('wechatDocumentUserIndex')} + + {/* 商家订单管理 */} + {if ($user['userType']==1)} + <?php $shopMenus = WSTShopOrderMenus();?> + {if (count($shopMenus)>0)} + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="order-icon"></i>商家订单管理</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('wechat/orders/sellerorder')}'">查看全部订单 ></li> + </ul> + </div> + {/if} + {/if} + + {/*用户订单管理 */} + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="order-icon"></i>我的订单</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('wechat/orders/index')}'">查看全部订单 ></li> + </ul> + </div> + <div class="ui-row-flex wst-users_icon"> + <div class="ui-col ui-col"> + <a href="{:url('wechat/orders/index',['type'=>'waitPay'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon1"></i> + {if ($data['order']['waitPay']>0)} + <span class="ui-badge-corner wait-payment ui-nowrap-flex ui-whitespace" id="waitPay">{$data['order']['waitPay']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待付款</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('wechat/orders/index',['type'=>'waitDeliver'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon2"></i> + {if ($data['order']['waitSend']>0)} + <span class="ui-badge-corner wait-payment" id="waitSend">{$data['order']['waitSend']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待发货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('wechat/orders/index',['type'=>'waitReceive'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon3"></i> + {if ($data['order']['waitReceive']>0)} + <span class="ui-badge-corner wait-payment" id="waitReceive">{$data['order']['waitReceive']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待收货</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('wechat/orders/index',['type'=>'waitAppraise'])}"> + <p class="ui-badge-wrap"> + <i class="wst-users_icon4"></i> + {if ($data['order']['waitAppraise']>0)} + <span class="ui-badge-corner wait-payment" id="waitAppraise">{$data['order']['waitAppraise']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">待评价</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('wechat/orders/index',['type'=>'abnormal'])}"> + <p style="display:none;"><i class="wst-users_icon5"></i></p><p><i class="wst-users_icon5"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">取消拒收</span> + </a> + </div> + </div> + + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="wallet-icon"></i>我的财产</li> + <li class="ui-col ui-col-50 view-order" onclick="location.href='{:url('wechat/logmoneys/usermoneys')}'">资金管理 ></li> + </ul> + </div> + <div class="ui-row-flex wst-users_capital"> + <div class="ui-col ui-col"> + <a href="{:url('wechat/logmoneys/usermoneys')}"> + <p class="ui-badge-wrap ui-nowrap"><span>¥ </span>{$user['userMoney']}</p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">余额</span> + </a> + </div> + <div class="ui-col ui-col"> + <a href="{:url('wechat/userscores/index')}"> + <p class="ui-badge-wrap ui-nowrap" id="currentScore">{$user['userScore']}</p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">积分</span> + </a> + </div> + {:hook('wechatDocumentUserIndexTerm')} + </div> + + <div class="user-order"> + <ul class="ui-row order"> + <li class="ui-col ui-col-50"><i class="tool-icon"></i>必备工具</li> + </ul> + </div> + <ul class="ui-row" style="background: #fff;"> + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/favorites/goods')}"> + <p><i class="user-icon1"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">关注商品</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/favorites/shops')}"> + <p><i class="user-icon2"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">关注店铺</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/goods/history')}"> + <p><i class="user-icon3"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">浏览记录</span> + </a> + </li> + <!-- <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/users/security')}"> + <p><i class="user-icon4"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">账户安全</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/logmoneys/usermoneys')}"> + <p><i class="user-icon5"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">资金管理</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/userscores/index')}"> + <p><i class="user-icon6"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的积分</span> + </a> + </li> + + <!-- <li class="ui-col ui-col-25 user-icon-box"> + <a href="#"> + <i class="user-icon7"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的礼券</span> + </a> + </li> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="#"> + <i class="user-icon8"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">我的客服</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/useraddress/index')}"> + <p><i class="user-icon9"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">地址管理</span> + </a> + </li> + + <!-- <li class="ui-col ui-col-25 user-icon-box"> + <a href="{:url('wechat/messages/index')}"> + <p class="ui-badge-wrap" style="width:33px;"> + <i class="user-icon10"></i> + {if ($data['message']['num']>0)} + <span class="ui-badge-corner wait-payment" id="msgNum">{$data['message']['num']}</span> + {/if} + </p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">商城消息</span> + </a> + </li> --> + + <li class="ui-col ui-col-25 user-icon-box ui-center-hor"> + <a href="{:url('wechat/ordercomplains/index')}"> + <p><i class="user-icon11"></i></p> + <span class="ui-flex ui-flex-align-end ui-flex-pack-center">订单投诉</span> + </a> + </li> + {:hook('wechatDocumentUserIndexTools')} + </ul> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/user.js?v={$v}'></script> +{if(!empty($datawx))} +<script src="{:request()->scheme()}://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> +<script> +wx.config({ + debug: false, + appId: '<?php echo WSTConf('CONF.wxAppId'); ?>', //公众号的唯一标识 + timestamp: '<?php echo $datawx['timestamp'];?>', //生成签名的时间戳 + nonceStr: '<?php echo $datawx['noncestr'];?>', //生成签名的随机串 + signature: '<?php echo $datawx['signature'];?>',//签名 + jsApiList: [ //需要使用的JS接口 + 'previewImage', + ] +}); +wx.ready(function(){ + //图片预览 + document.querySelector('#previewImages').onclick = function () { + var url=document.getElementById('imgurl').src; + wx.previewImage({ + current: url, + urls: [ + url + ] + }); + }; +}); +</script> +{/if} +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/logmoneys/list.html b/hyhproject/wechat2/view/default/users/logmoneys/list.html new file mode 100755 index 0000000..126e58a --- /dev/null +++ b/hyhproject/wechat2/view/default/users/logmoneys/list.html @@ -0,0 +1,113 @@ +{extend name="default/base" /} +{block name="title"}我的资金 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/logmoneys.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的资金</h1> + <span class="record" onclick="location.href='{:url('wechat/cashdraws/index')}'">提现记录</span> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$rs['isSetPayPwd']}" id="isSet" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-row-flex-ver head"> + <div class="title"> + <div class="money_number"> + <p id="userMoney" money="{$rs['userMoney']}" cash="{:WSTConf('CONF.drawCashUserLimit')}">可用资金:<span>¥ </span>{$rs['userMoney']}</p> + </div> + <div class="money_number2"> + <p money="{$rs['userMoney']}" cash="{:WSTConf('CONF.drawCashUserLimit')}">冻结资金:<span>¥ </span>{$rs['lockMoney']}</p> + </div> + <div class="wst-clear"></div> + </div> + <div class="ui-col head-btn-box"></div> + </div> + <ul class="ui-row recharge-box"> + <li class="ui-col ui-col-50" onclick="location.href='{:url('wechat/logmoneys/toRecharge')}'"> + <div class="wst_model"> + <div class="icon_add"><p>充值</p></div> + </div> + </li> + <li class="ui-col ui-col-50" onclick="getCash()"> + <div class="wst_model"> + <div class="icon_out"><p>提现</p></div> + </div> + </li> + </ul> + <ul class="ui-row money-detail" onclick="check()"> + <li class="ui-col ui-col-50 money-detail-title"><div class="icon_stript stript_1"></div><h5>&nbsp;我的提现账户</h5></li> + <li class="ui-col ui-col-50 money-detail-title m-tr"><h5>{$rs['num']}个 ></h5></li> + </ul> + <ul class="ui-row money-detail" onclick="javascript:toRecord()"> + <li class="ui-col ui-col-50 money-detail-title"><div class="icon_stript stript_2"></div><h5>&nbsp;我的资金流水</h5></li> + <li class="ui-col ui-col-50 money-detail-title m-tr"><h5>></h5></li> + </ul> + <ul class="ui-row first-time"> + <li class="ui-col ui-col-100 ft-title"><i></i><span>首次提现步骤:</span></li> + <li class="ui-col ui-col-100 ft-item">1.设置支付密码和绑定手机号码</li> + <li class="ui-col ui-col-100 ft-item">2.绑定您的微信钱包或银行卡</li> + </ul> + </section> +{/block} +{block name="include"} +{include file="default/dialog" /} +<input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> +{/* 对话框 prompt */} +<div class="ui-dialog" id="payPwdBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <p id="wst-dialog" class="wst-dialog-t"> + 请输入支付密码:<br /> + <input type="password" id="payPwd" maxLength="6" class="wst-pay-inp" /> + </p> + <p class="wst-dialog-l"></p> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </div> + </div> +</div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>申请提现</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="info"> + <p>可提现金额</p> + <p class="money"><span>¥ </span>{$rs['userMoney']}</p> + </div> + <div class="content"> + <ul class="ui-row"> + <li class="ui-col ui-col-25">提现账号:</li> + <li class="ui-col ui-col-75"> + <select name="accId" id="accId" class="wst-lo-choice"> + <option value="">请选择</option> + </select> + </li> + <li class="ui-col ui-col-25">提现金额:</li> + <li class="ui-col ui-col-75"> + <input type="number" name="money" id="money" class="wst-lo-choice" onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" /> + </li> + <li class="ui-col ui-col-25">支付密码:</li> + <li class="ui-col ui-col-75"> + <input type="password" id="cashPayPwd" class="wst-lo-choice" maxLength="6" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off" /> + </li> + <li class="ui-col wst-red">(至少¥ {:WSTConf('CONF.drawCashUserLimit')}以上可提现)</li> + <li class="ui-col ui-col-100"> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-apply-button" id="submit" onclick="drawMoney()"> + 确定 + </button> + </div> + </li> + + </ul> + </div> +</div> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/logmoneys/logmoneys.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/logmoneys/logmoneys.js b/hyhproject/wechat2/view/default/users/logmoneys/logmoneys.js new file mode 100755 index 0000000..65a024d --- /dev/null +++ b/hyhproject/wechat2/view/default/users/logmoneys/logmoneys.js @@ -0,0 +1,155 @@ +jQuery.noConflict(); +$(document).ready(function(){ + WST.initFooter('user'); + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); +}); +//资金流水列表 +function getRecordList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val() || -1; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/logMoneys/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); + } +// 验证支付密码资金 +function check(){ + var isSetPayPwd = $('#isSet').val(); + if(isSetPayPwd==0){ + $('#wst-event2').html('去设置'); + WST.dialog('您未设置支付密码','location.href="'+WST.U('wechat/users/editPayPass')+'"'); + return; + }else{ + showPayBox(); + } + +} +// 支付密码对话框 +function showPayBox(){ + $("#wst-event3").attr("onclick","javascript:checkSecret()"); + $("#payPwdBox").dialog("show"); +} +function checkSecret(){ + var payPwd = $.trim($('#payPwd').val()); + if(payPwd==''){ + WST.msg('请输入支付密码','info'); + return; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + $.post(WST.U('wechat/logmoneys/checkPayPwd'),{payPwd:payPwd},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $("#payPwdBox").dialog("hide"); + location.href=WST.U('wechat/cashconfigs/index'); + }else{ + WST.msg(json.msg); + } + }) +} +//资金流水 +function toRecord(){ + location.href = WST.U('wechat/logmoneys/record'); +} +/******************** 提现层 *************************/ +function getCash(){ + $('#money').val(''); + $('#cashPayPwd').val(''); + $.post(WST.U('wechat/cashconfigs/pageQuery'),{},function(data){ + var json = WST.toJson(data); + var html = '<option value="">请选择</option>'; + if(json.status==1){ + $(json.data.Rows).each(function(k,v){ + html +='<option value='+v.id+'>'+v.accUser+'|'+v.accNo+'</option>'; + }); + $('#accId').html(html); + // 判断是否禁用按钮 + if($('#userMoney').attr('money')<$('#userMoney').attr('cash'))$('#submit').attr('disabled','disabled'); + dataShow(); + }else{ + WST.msg(json.msg,'info'); + } + }) +} +// 申请提现 +function drawMoney(){ + var accId = $('#accId').val(); + var money = $('#money').val(); + var payPwd = $('#cashPayPwd').val(); + + if(accId==''){ + WST.msg('请选择提现账号','info'); + return; + } + if(money==''){ + WST.msg('请输入提现金额','info'); + return + } + if(payPwd==''){ + WST.msg('请输入支付密码','info'); + return + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + var param = {}; + param.accId = accId; + param.money = money; + param.payPwd = payPwd; + $.post(WST.U('wechat/cashdraws/drawMoney'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('提现申请已提交','success'); + setTimeout(function(){ + history.go(0); + },1000); + }else{ + WST.msg(json.msg,'info'); + } + }) +} +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/logmoneys/record.html b/hyhproject/wechat2/view/default/users/logmoneys/record.html new file mode 100755 index 0000000..70b90ab --- /dev/null +++ b/hyhproject/wechat2/view/default/users/logmoneys/record.html @@ -0,0 +1,55 @@ +{extend name="default/base" /} +{block name="title"}资金流水 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/userscores.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "资金流水"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-whitespace ui-row-flex-ver head" style="text-align: left;"> + <div class="ui-col" style="padding-top: 30px;font-size: 0.16rem;text-align: right;">可用资金:¥ {$rs['userMoney']}</div> + <div class="ui-col" style="font-size: 0.16rem;text-align: right;">冻结资金:¥ {$rs['lockMoney']}</div> + </div> + <script type="text/html" id="scoreList"> + <ul class="ui-row score-detail"> + {{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75 wst-re-info"> + {{d[i].remark}} + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 {{(d[i].moneyType==1)?'score-plus':'score-reduce'}}">{{(d[i].moneyType==1)?'+':'-'}} {{d[i].money}}</li> + <div class="wst-clear"></div> + <div class="score-line"></div> + {{# } }} + </ul> + </script> + <div class="score-detail-title">资金明细</div> + <div id="score-list"></div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/logmoneys/logmoneys.js?v={$v}'></script> +<script> +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getRecordList(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getRecordList(); + } + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/messages/list.html b/hyhproject/wechat2/view/default/users/messages/list.html new file mode 100755 index 0000000..02abd94 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/messages/list.html @@ -0,0 +1,77 @@ +{extend name="default/base" /} +{block name="title"}我的消息 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/messages.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="location.href='{:url('wechat/users/index')}'"></i><h1>我的消息</h1> + </header> +{/block} +{block name="footer"} + <div class="ui-loading-wrap wst-Load" id="Load"> + <i class="ui-loading"></i> + </div> + <footer class="ui-footer wst-footer-btns" style="height:45px; border-top: 1px solid #e0e0e0;" id="footer"> + <div class="wst-toTop" id="toTop"> + <i class="wst-toTopimg"><span>顶部</span></i> + </div> + + <div class="ui-row-flex ui-whitespace"> + <div class="ui-col ui-col-2 favorite-tc"> + <label class="ui-checkbox" style="margin-left:5px;"> + <input class="sactive" type="checkbox" onclick="javascript:checkAll(this);"> + </label> + 全选 + </div> + + <div class="ui-col"> + <div class="ui-btn-wrap f-btn"> + <button class="ui-btn ui-btn-danger del-btn" onclick="toDelMsg()"> + 删除消息 + </button> + </div> + </div> + </div> + + </footer> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <script type="text/html" id="msgList"> + {{# for(var i=0; i<d.length; i++){ }} + <li> + <label class="ui-checkbox msg-chk"> + <input class="active" type="checkbox" msgId="{{d[i].id}}" > + </label> + <div class="ui-list-info" onclick="javascript:getMsgDetails({{d[i].id}});"> + <h5 class="ui-nowrap"> + <span class="{{(d[i].msgStatus == 0)?'wst-info_ico':'wst-info_ico1' }} j-icon_{{d[i].id}}"></span>{{d[i].msgContent}}</h5> + </div> + </li> + <div class="wst-Line"></div> + {{# } }} + </script> + <section class="ui-container info-prompt"> + <ul class="ui-list ui-list-text wst-info_content" id="info-list"> + </ul> + </section> + </div> + <div id="info_details" style="display:none;"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="javascript:returnInfo()"></i><h1>消息详情</h1> + </header> + <section class="ui-container"> + <div class="ui-whitespace detail-time"><span class="wst-info_detime"></span></div> + <div class="ui-whitespace"><span class="wst-info_decontent"></span></div> + </section> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__ROOT__/hyhproject//wechat/view/default/users/messages/messages.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/messages/messages.js b/hyhproject/wechat2/view/default/users/messages/messages.js new file mode 100755 index 0000000..ea0a207 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/messages/messages.js @@ -0,0 +1,103 @@ +//消息列表 +function getMessages(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 12; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/messages/pageQuery'), param, function(data){ + var json = WST.toJson(data); + var mhtml = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('msgList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#info-list').append(html); + }); + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + + }else{ + mhtml += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-message.png"></div>'; + mhtml += '<div class="wst-prompt-info">'; + mhtml += '<p>对不起,没有相关消息。</p>'; + mhtml += '</div>'; + $('.info-prompt').append(mhtml); + } + loading = false; + $('#Load').hide(); + }); +} +//返回消息列表 +function returnInfo(){ + $('#info_details').hide(); + $('#info_list').show(); +} + +// 全选 +function checkAll(obj){ + var chk = $(obj).attr('checked'); + $('.active').each(function(k,v){ + $(this).prop('checked',chk); + }); +} +//消息详情 +function getMsgDetails(id){ + $('#info_list').hide(); + $('#info_details').show(); + $('.j-icon_'+id).addClass('wst-info_ico1').removeClass('wst-info_ico'); + $.post(WST.U('wechat/messages/getById'), {msgId:id}, function(data){ + var json = WST.toJson(data); + if(json){ + $('.wst-info_detime').html(json.createTime); + $('.wst-info_decontent').html(json.msgContent); + } + json = null; + }); +} +var msgIdsToDel=new Array();//要删除的消息的id 数组 +//去删除商城消息 +function toDelMsg(){ + var msgIds = new Array(); + $('.active').each(function(k,v){ + if($(this).attr('checked')){ + msgIds.push($(this).attr('msgid')); + } + }); + msgIdsToDel = msgIds; + if(msgIds.join(',')==''){ + WST.msg('请选择要删除的消息','info'); + return false; + } + WST.dialog('确定要删除选中的消息吗?','delMsg()'); +} +var vn =''; +//删除商城消息 +function delMsg(){ + WST.dialogHide('prompt'); + $.post(WST.U('wechat/messages/del'), {ids:msgIdsToDel}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + $('#currPage').val(0) + $('#info-list').html(' '); + getMessages(); + }else{ + WST.msg(json.msg,'warn'); + } + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getMessages(); + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getMessages(); + } + } + }); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/list_complains.html b/hyhproject/wechat2/view/default/users/orders/list_complains.html new file mode 100755 index 0000000..7c646a4 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/list_complains.html @@ -0,0 +1,152 @@ +{extend name="default/base" /} +{block name="title"}我的投诉 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/list_complains.css?v={$v}"> +{/block} +{block name="header"} + {php} + $we = WSTWechat(); + $datawx = $we->getJsSignature(request()->scheme()."://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + {/php} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>我的投诉</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <script type="text/html" id="complainList"> + <ul class="ui-row"> + {{# for(var i=0;i<d.length;i++){ }} + <div class="complain-box"> + <li class="ui-col ui-col-50" onclick="javascript:WST.intoShops({{d[i].shopId}});">{{d[i].shopName}}</li> + <li class="ui-col ui-col-50 c-tr">{{d[i].complainTime}}</li> + <div class="c-item" onclick="complainDetail({{d[i].complainId}})"> + <li class="ui-col ui-col-75">订单号:{{d[i].orderNo}}</li> + <li class="ui-col ui-col-25 c-tr wst-co-status">{{d[i].complainStatus}}</li> + </div> + <div class="wst-clear"></div> + </div> + <div class="c-line"></div> + {{# } }} + </ul> + </script> + <div id="complain-list"></div> + </section> +<script type="text/html" id="complainDetail"> +<ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">投诉信息</li> + <li class="ui-col ui-col-25 com-detail-title">订单编号:</li> + <li class="ui-col ui-col-75">{{d.orderNo}}</li> + + <li class="ui-col ui-col-25 com-detail-title">投诉内容:</li> + <li class="ui-col ui-col-75">{{d.complainContent}}</li> + + <li class="ui-col ui-col-25 com-detail-title">投诉类型:</li> + <li class="ui-col ui-col-75"> + {{# if (d.complainType==1){ }} + 承诺的没有做到 + {{# } else if (d.complainType==2) { }} + 未按约定时间发货 + {{# } else if (d.complainType==3) { }} + 未按成交价格进行交易 + {{# } else if (d.complainType==4) { }} + 恶意骚扰 + {{# } }} + </li> + + <li class="ui-col ui-col-25 com-detail-title">附件:</li> + <li class="ui-col ui-col-75"> + {{# if(d.complainAnnex){ }} + {{# for(var c=0;c<d.complainAnnex.length;c++){ }} + <img src="__ROOT__/{{d.complainAnnex[c]}}" style="width:60px;height:60px;" class="imgurl" onclick="javascript:getImg(this);"> + {{# } }} + {{# }else{ }} + 无 + {{# } }} + </li> + + <li class="ui-col ui-col-25 com-detail-title">投诉时间:</li> + <li class="ui-col ui-col-75">{{d.complainTime}}</li> + </ul> + + + {{# if (d.needRespond==1 && WST.blank(d.respondContent)!=''){ }} + + <ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">应诉信息</li> + + + <li class="ui-col ui-col-25 com-detail-title">应诉内容:</li> + <li class="ui-col ui-col-75">{{d.respondContent}}</li> + + + <li class="ui-col ui-col-25 com-detail-title">附件:</li> + <li class="ui-col ui-col-75"> + {{# if(d.respondAnnex){ }} + {{# for(var r=0;r<d.respondAnnex.length;r++){ }} + <img src="__ROOT__/{{d.respondAnnex[r]}}" class="annex"> + {{# } }} + {{# }else{ }} + 无 + {{# } }} + </li> + <li class="ui-col ui-col-25 com-detail-title">应诉时间:</li> + <li class="ui-col ui-col-75">{{d.respondTime}}</li> + </ul> + {{# } }} + + + <ul class="ui-row com-detail-box"> + <li class="ui-col ui-col-100 com-detail-big-title">仲裁信息【 + {{# if(d.complainStatus==0){ }} + 等待处理 + {{# }else if(d.complainStatus==1){ }} + 等待应诉人回应 + {{# }else if(d.complainStatus==2 || d.complainStatus==3){ }} + 等待仲裁 + {{# }else if(d.complainStatus==4){ }} + 已仲裁 + {{# } }} + 】</li> + + {{# if(d.complainStatus==4){ }} + <li class="ui-col ui-col-25 com-detail-title">仲裁结果:</li> + <li class="ui-col ui-col-75">{{d.finalResult}}</li> + + <li class="ui-col ui-col-25 com-detail-title">仲裁时间:</li> + <li class="ui-col ui-col-75">{{d.finalResultTime}}</li> + {{# } }} + </ul> +</script> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>投诉详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="complainDetailBox"> + </div> +</div> + +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/list_complains.js?v={$v}'></script> +{php}if($datawx['status']==1){ {/php} +<script src="{:request()->scheme()}://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> +<script> +wx.config({ + debug: false, + appId: '<?php echo $we->appId;?>', //公众号的唯一标识 + timestamp: '<?php echo $datawx['timestamp'];?>', //生成签名的时间戳 + nonceStr: '<?php echo $datawx['noncestr'];?>', //生成签名的随机串 + signature: '<?php echo $datawx['signature'];?>',//签名 + jsApiList: [ //需要使用的JS接口 + 'previewImage', + ] +}); +</script> +{php} } {/php} +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/list_complains.js b/hyhproject/wechat2/view/default/users/orders/list_complains.js new file mode 100755 index 0000000..9f5307c --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/list_complains.js @@ -0,0 +1,102 @@ +jQuery.noConflict(); +// 获取订单列表 +function getComplainList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/orderComplains/complainByPage'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('complainList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#complain-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-complaint.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无投诉信息</p>'; + html += '</div>'; + $('#complain-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getComplainList(); + WST.initFooter('user'); + // 弹出层 + $("#frame").css('top',0); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getComplainList(); + } + } + }); +}); + + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + +function complainDetail(cId){ + $.post(WST.U('wechat/orderComplains/getComplainDetail'),{'id':cId},function(data){ + var json = WST.toJson(data); + if(json){ + var gettpl = document.getElementById('complainDetail').innerHTML; + laytpl(gettpl).render(json, function(html){ + // 写入数据 + $('#complainDetailBox').html(html); + // 设置滚动条 + var screenH = WST.pageHeight(); + var titleH = $('#frame').find('.title').height(); + var contentH = $('#complainDetailBox').height(); + + if(screenH-titleH < contentH){ + $('#complainDetailBox').css('height',screenH-titleH); + } + // 展示弹出层 + dataShow(); + }); + } + + }) + +} +function getImg(obj){ + var url = 'http://'+window.location.host+$(obj).attr('src'); + var imgUrls = ''; + $('.imgurl').each(function(){ + imgUrls += "'http://"+window.location.host+$(this).attr('src') + "',"; + }); + //图片预览 + wx.previewImage({ + current: url, + urls: [ + url + ] + }); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_appraises.html b/hyhproject/wechat2/view/default/users/orders/orders_appraises.html new file mode 100755 index 0000000..d75f5d8 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_appraises.html @@ -0,0 +1,172 @@ +{extend name="default/base" /} +{block name="title"}商品评价 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders_appraises.css?v={$v}"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="header"} + {php}$Title='商品评价'{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$oId}" id="oId" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex item-head"> + <div class="ui-col ui-col-2 ui-nowrap-flex shop"><i></i>{$data['shopName']}</div> + </div> + {volist name="data['Rows']" id="g"} + <div class="ui-row-flex border-b g-item"> + <div class="ui-col"> + <div class="g-Img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({$g['goodsId']});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{:WSTImg($g['goodsImg'],3)}"> + </a> + </div> + </div> + <div class="ui-col ui-col-3 g-gInfo"> + <p class="g-gName ui-nowrap-multi">{$g['goodsName']}</p> + <p class="g-gSpec ui-nowrap-flex">{if($g['goodsSpecNames'])}规格:{$g['goodsSpecNames']}{/if}</p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;"> + {if ($g['appraise']!='')} + <span class="appraise" onclick="appraise({$g.goodsId},{$g['goodsSpecId'] ?? 0},{$g.id},this)"></span> + {else /} + <span class="appraise" onclick="appraise({$g.goodsId},{$g['goodsSpecId'] ?? 0},{$g.id},this)"></span> + {/if} + </div> + </div> + <div id="appBox_{$g.id}"></div> + {/volist} + <script id="appraises-box" type="text/html"> + <ul class="ui-row appraise-box"> + <li class="ui-col ui-col-25 appraise-title">商品名称</li> + <li class="ui-col ui-col-75 ui-nowrap-multi appraise-name"> + {{d.goodsName}} + </li> + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">商品评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.goodsScore!=''){ }} + {{# for(var i=0;i<d.goodsScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.goodsScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="goodsScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.goodsScore!='')?d.goodsScore:'0'}}分</li> + </ul> + </li> + + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">服务评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.serviceScore!=''){ }} + {{# for(var i=0;i<d.serviceScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.serviceScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="serviceScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.serviceScore!='')?d.serviceScore:'0'}}分</li> + </ul> + </li> + + <li class="ui-col ui-col-25 appraise-title" style="height: 25px;line-height:25px;">时效评分</li> + <li class="ui-col ui-col-75"> + <ul class="ui-row"> + <li class="ui-col ui-col-80"> + {{# if(d.timeScore!=''){ }} + {{# for(var i=0;i<d.timeScore;i++){ }} + <span class="start-on"></span> + {{# } }} + + {{# for(var j=0;j<5-d.timeScore;j++){ }} + <span class="start-not"></span> + {{# } }} + + {{# }else{ }} + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + <span class="start-not" onclick="clickStar(this)"></span> + {{# } }} + </li> + <li class="ui-col ui-col-20 score" id="timeScore" score="{{(d.timeScore!='')?d.timeScore:'0'}}" style="height: 25px;line-height:25px;">{{(d.timeScore!='')?d.timeScore:'0'}}分</li> + </ul> + </li> + + {{# if(d.content==''){ }} + <li class="ui-col" style="padding:10px"> + <textarea class="appraisesContent" id="content"></textarea> + </li> + <div class="ui-col uploadfile-box"> + <ul class="complainFileBox" id="edit_chart"> + </ul> + <div id="filePicker" style='margin-left:10px;width:250px;overflow:hidden;height:35px;font-size:.13rem;'>上传附件(最多5张)</div> + </div> + <br /> + <div class="ui-btn-wrap post-btn"> + <button class="ui-btn-lg ui-btn-danger" onclick="javascript:saveAppr({{d.goodsId}},{{d.goodsSpecId}},{{d.orderGoodsId}});">提交</button> + </div> + {{# }else{ }} + <li class="ui-col ui-col-25 appraise-title">点评内容</li> + <li class="ui-col ui-col-75"> + {{d.content}} + </li> + <li class="ui-col ui-col-25 appraise-title" style="padding-top:15px;">评价附件</li> + <li class="ui-col ui-col-75" style="margin-top:10px;margin-left:-10px;"> + {{# if(WST.blank(d.images)!=''){ + var img = d.images; + }} + <ul class="complainFileBox"> + {{# for(var g=0;g<img.length;++g){ }} + <li><img src="__ROOT__/{{img[g]}}"> </li> + {{# } }} + </ul> + {{# } }} + </li> + + {{# } }} + </ul> + + + + </script> + <div id="appraisesBox"> + </div> + + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_appraises.js?v={$v}'></script> +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_appraises.js b/hyhproject/wechat2/view/default/users/orders/orders_appraises.js new file mode 100755 index 0000000..187a069 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_appraises.js @@ -0,0 +1,115 @@ +jQuery.noConflict(); +//商品评价 +function clickStar(obj){ + var index = $(obj).index(); // 当前选中的分数 + $(obj).parent().find('span').each(function(k,v){ + if(k<=index){ + $(this).removeClass('start-not').addClass('start-on'); + }else{ + $(this).removeClass('start-on').addClass('start-not'); + } + }) + $(obj).parent().siblings().html(index+1+'分'); + $(obj).parent().siblings().attr('score',index+1); +} + +function appraise(gId,sId,ogId,obj){ + + $('.appraise').removeClass('score'); + $(obj).addClass('score'); + var gName = $(obj).parent().parent().find('.g-gName').html(); + + var param = {}; + param.gId = gId; + param.sId = sId; + param.oId = $('#oId').val(); + param.orderGoodsId = ogId; + $.post(WST.U('wechat/goodsappraises/getAppr'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + var gettpl = document.getElementById('appraises-box').innerHTML; + json.data.goodsName = gName; + json.data.goodsId = gId; + json.data.goodsSpecId = sId; + json.data.orderGoodsId = ogId; + laytpl(gettpl).render(json.data, function(html){ + $('div[id^="appBox_"]').html(' '); + $('#appBox_'+ogId).html(html); + }); + if(json.data.serviceScore=='')userAppraiseInit(); + }else{ + WST.msg('请求出错','info'); + } + }) +} +function saveAppr(gId,sId,ogId){ + var content = $.trim($('#content').val()); + if(content==''){ + WST.msg('评价内容不能为空','info'); + return + } + var param = {}; + param.content = content; + param.goodsId = gId; + param.goodsSpecId = sId; + param.orderId = $('#oId').val(); + param.timeScore = $('#timeScore').attr('score'); + param.goodsScore = $('#goodsScore').attr('score'); + param.serviceScore = $('#serviceScore').attr('score'); + param.orderGoodsId = ogId; + + var imgs = []; + // 是否有上传附件 + $('.imgSrc').each(function(k,v){ + imgs.push($(this).attr('v')); + }) + imgs = imgs.join(','); + if(imgs!='') + param.images = imgs; + + $.post(WST.U('wechat/goodsappraises/add'),param,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){history.go(0);},1000); + }else{ + WST.msg(json.msg); + } + }) + +} +$(function(){ + WST.initFooter('user'); + WST.imgAdapt('j-imgAdapt'); +}) + + +/*************** 上传图片 *****************/ +function userAppraiseInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'appraises',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<li>"+ + "<img class='imgSrc' src='"+WST.conf.ROOT+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></li>"); + var btn = $('<div class="del-btn"><span class="ui-icon-delete"></span></div>'); + tdiv.append(btn); + $('#edit_chart').append(tdiv); + btn.on('click','span',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} diff --git a/hyhproject/wechat2/view/default/users/orders/orders_complains.html b/hyhproject/wechat2/view/default/users/orders/orders_complains.html new file mode 100755 index 0000000..24a36c5 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_complains.html @@ -0,0 +1,185 @@ +{extend name="default/base" /} +{block name="title"}订单投诉 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders_complains.css?v={$v}"> +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v={$v}" /> +{/block} +{block name="footer"} +{/block} +{block name="header"} + <div id="useri_infos"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <a href="{:url('wechat/users/index')}"><i class="ui-icon-return"></i></a><h1 class="useri_info">订单投诉</h1> + <i onclick="javascript:closeUploadArea()" style="display:none;font-size: 0.15rem;" id="upload_close">关闭</i> + <a href="javascript:void(0);" style="display:none;float:right;font-size: 0.15rem;" id="upload_button">上传</a> + </header> +{/block} + +{block name="main"} +<sction class="ui-container" id="upload_modal"> + <div class="upload-modal"> + <div id="clipArea" class="clipArea"></div> + <input type="hidden" id="imgData" autocomplete="off"> + </div> +</sction> + <input type="hidden" name="" value="" id="complainType" autocomplete="off"> + <input type="hidden" name="" value="{$oId}" id="oId" autocomplete="off"> + <section class="ui-container" id="Ccontrainer"> + <script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="ui-row-flex ui-whitespace detail-head"> + <div class="ui-col ui-col ">订单号:{{d.orderNo}}</div> + <div class="ui-col order-tr o-status"> + {{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + </div> + </div> + + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col">{{d.shopName}}</div> + </div> + + + {{# for(var i=0;i<d.goods.length;i++){ }} + <div class="ui-row-flex ui-whitespace border-b d-goodsitme"> + <div class="ui-col"> + <div class="o-Img j-imgAdapt"> + <a href="javascript:void(0);" onclick="javascript:WST.intoGoods({{d.goods[i]['goodsId']}});"> + <img src="__ROOT__/{:WSTConf('CONF.goodsLogo')}" data-echo="__ROOT__/{{d.goods[i].goodsImg}}"> + </a> + </div> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{{d.goods[i].goodsName}}</p> + + + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"><p class="price">¥ {{d.goods[i].goodsPrice}}</p><p> x {{d.goods[i].goodsNum}}</p></div> + </div> + {{# } }} + + + <div class="ui-row-flex ui-whitespace d-item"> + <div class="ui-col ui-col">下单时间</div> + <div class="ui-col ui-col order-tr">{{d.createTime}}</div> + </div> + + <div class="ui-row-flex ui-whitespace d-item" style="min-height:80px;"> + <div class="ui-col ui-col">商品总额</div> + <div class="ui-col ui-col-4 order-tr"> + <p class="price">¥ {{d.goodsMoney}}</p> + <p class="price"><span class="title">运费:</span>¥ {{d.deliverMoney}}</p> + <p>实付款:<span class="price">¥ {{d.needPay}}</span></p> + </div> + </div> + </div> +</script> + +<div id="orderDetail"> + +</div> + +<div class="ui-row-flex ui-whitespace d-item c-item"> + <div class="ui-col ui-col">投诉类型</div> + <div class="ui-col ui-col-3 order-tr" onclick="dataShow(0)" id="complainText" >请选择投诉类型 > </div> +</div> + +<div class="ui-row-flex ui-whitespace ui-row-flex-ver c-box"> + <div class="ui-col c-title">投诉内容</div> + <div class="ui-col c-content"> + <textarea id="complain"></textarea> + </div> + + <div class="ui-col uploadfile-box"> + <ul class="complainFileBox" id="edit_chart"> + + </ul> + + <div id="filePicker" style='margin-left:5px;width:250px;overflow:hidden;height:35px;font-size:.13rem;'>上传附件(最多5张)</div> + </div> + + <div class="ui-btn-wrap" style="padding:5px;padding-bottom:5px;"> + <button class="ui-btn-lg ui-btn-danger c-btn" onclick="saveCom({$oId})"> + 提交 + </button> + </div> +</div> + + + + {/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 订单详情层 */} +<div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span>投诉类型</span><i class="ui-icon-close-page" onclick="javascript:dataHide(0);"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">承诺的没有做到</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='1' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">未按约定时间发货</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='2' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">未按成交价格进行交易</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='3' > + </label> + </li> + </ul> + + <ul class="ui-row complain-item"> + <li class="ui-col ui-col-75">恶意骚扰</li> + <li class="ui-col ui-col-25 chk-box"> + <label class="ui-checkbox"> + <input class="active" type="radio" name="data" value='4' > + </label> + </li> + </ul> + + + </div> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger c-btn" onclick="dataHide(1)"> + 确定 + </button> + </div> +</div> +</section> + +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_complains.js?v={$v}'></script> + + +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_complains.js b/hyhproject/wechat2/view/default/users/orders/orders_complains.js new file mode 100755 index 0000000..f71aad8 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_complains.js @@ -0,0 +1,122 @@ +jQuery.noConflict(); +$(function(){ + getOrderDetail(); + userComplainInit(); +}) +function getOrderDetail(){ + var oid = $('#oId').val(); + $.post(WST.U('wechat/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#orderDetail').html(html); + }); + }else{ + WST.msg(json.msg,'info'); + } + WST.imgAdapt('j-imgAdapt'); + }); + +} + +/*********************** 投诉类型 ****************************/ +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide(0);").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(type){ + if(type==1){ + var flag=false,chk; + $('.active').each(function(k,v){ + if($(this).prop('checked')){ + flag = true + $('#complainType').val($(this).val()); + chk = $(this).parent().parent().siblings().html(); + } + }); + if(!flag){ + WST.msg('请选择投诉类型'); + return; + } + $('#complainText').html(chk+' >'); + } + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); +} + +function uploadFile(){ + $('#filePicker').trigger("click"); +} + + +function saveCom(oId){ + // 验证投诉类型 + var type = $('#complainType').val(); + if(type==''){ + dataShow(); + WST.msg('请选择投诉类型','info'); + return; + } + var complainContent = $.trim($('#complain').val()); + if(complainContent==''){ + WST.msg('投诉内容不能为空','info'); + return; + } + var param = {}; + param.orderId = oId; + param.complainType = type; + param.complainContent = complainContent; + + var imgs = []; + // 是否有上传附件 + $('.imgSrc').each(function(k,v){ + imgs.push($(this).attr('v')); + }) + imgs = imgs.join(','); + if(imgs!='') + param.complainAnnex = imgs; + + $.post(WST.U('wechat/ordercomplains/saveComplain'),param,function(data){ + var json = WST.toJson(data); + if(data.status){ + WST.msg('投诉成功请留意商城消息','success'); + setTimeout(function(){location.href=WST.U('wechat/ordercomplains/index')},1000); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} +/*************** 上传图片 *****************/ +function userComplainInit(){ + var uploader =WST.upload({ + pick:'#filePicker', + formData: {dir:'complains',isThumb:1}, + fileNumLimit:5, + accept: {extensions: 'gif,jpg,jpeg,png',mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif'}, + callback:function(f,file){ + var json = WST.toJson(f); + if(json.status==1){ + var tdiv = $("<li>"+ + "<img class='imgSrc' src='"+WST.conf.ROOT+"/"+json.savePath+json.thumb+"' v='"+json.savePath+json.name+"'></li>"); + var btn = $('<div class="del-btn"><span class="ui-icon-delete"></span></div>'); + tdiv.append(btn); + $('#edit_chart').append(tdiv); + btn.on('click','span',function(){ + uploader.removeFile(file); + $(this).parent().parent().remove(); + uploader.refresh(); + }); + }else{ + WST.msg(json.msg,{icon:2}); + } + }, + progress:function(rate){ + $('#uploadMsg').show().html('已上传'+rate+"%"); + } + }); +} diff --git a/hyhproject/wechat2/view/default/users/orders/orders_list.html b/hyhproject/wechat2/view/default/users/orders/orders_list.html new file mode 100755 index 0000000..9c30c37 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_list.html @@ -0,0 +1,485 @@ +{extend name="default/base" /} +{block name="title"}我的订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header wst-headero"> + <i class="ui-icon-return" onclick="location.href='{:url('wechat/users/index')}'"></i><h1>我的订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="order-item"> + <div class="ui-row-flex ui-whitespace item-head"> + <div class="ui-col ui-col-2" onclick="javascript:WST.intoShops({{d[i].shopId}});"><p class="ui-nowrap-flex"><i class="shopicon"></i>{{d[i].shopName}}</p></div> + <div class="ui-col order-tr o-status"> + {{ d[i].status }} + {{# if($.inArray(d[i].orderStatus,[-1,-3])!=-1){ }} + {{# if(d[i].payType==1 && d[i].isPay==1) { }} + {{# if(d[i].isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }} + </div> + </div> + + {{# for(var g=0;g<d[i].list.length;g++){ }} + <div class="ui-row-flex ui-whitespace border-b" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col"> + <img src="__ROOT__/{{d[i].list[g].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d[i].list[g].goodsName}}</p> + + {{# if(d[i].list[g].goodsSpecNames){ }} + <p class="o-gSpec ui-nowrap-flex ui-whitespace">规格:{{d[i].list[g].goodsSpecNames}}</p> + {{# } }} + + </div> + + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d[i].list[g].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d[i].list[g].goodsPrice}}</p><p>x {{d[i].list[g].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# } }} + + <div class="ui-btn-wrap" style="padding:5px 0px;"> + {{# if(d[i].orderCodeTitle!=""){ }} + <span class="order_from">{{d[i].orderCodeTitle}}</span> + {{# } }} + <div class="o-oListMoney"> + 订单总价:<span>¥ {{d[i].realTotalMoney}}</span> + </div> + {{# if(d[i].orderStatus==-2){ }} + <button class="ui-btn o-btn" onclick="choicePay({{d[i].orderNo}},0);"> + 立即付款 + </button> + {{# } }} + + {{# if(d[i].orderStatus==0 && d[i].noticeDeliver==0 ){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="WST.dialog('您确定要提醒发货吗?','noticeDeliver({{d[i].orderId}})')"> + 提醒发货 + </button> + {{# } }} + + {{# if(d[i].orderStatus==-2 || d[i].orderStatus==0){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="showCancelBox('cancelOrder({{d[i].orderId}})')"> + 取消订单 + </button> + {{# } }} + + {{# if((d[i].orderStatus!=-1 || d[i].orderStatus==1) && d[i].orderStatus!=-2 && d[i].isComplain==0 ){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="complain({{d[i].orderId}})"> + 投诉 + </button> + {{# } }} + + {{# if(d[i].orderStatus==2 && d[i].isAppraise==0) { }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 评价 + </button> + {{# } }} + {{# if(d[i].isAppraise==1){ }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 查看评价 + </button> + {{# } }} + + + {{# if((d[i].allowRefund==1) && (d[i].orderStatus==-1 || d[i].orderStatus==-3)){ }} + <button class="ui-btn o-btn" onclick="showRefundBox({{d[i].orderId}})"> + 申请退款 + </button> + {{# } }} + + + {{# if(d[i].orderStatus==1){ }} + <button class="ui-btn o-btn o-cancel-btn" onclick="showRejectBox('rejectOrder({{d[i].orderId}})')"> + 拒收 + </button> + <button class="ui-btn o-btn" onclick="WST.dialog('你确定已收货吗?','receive({{d[i].orderId}})')"> + 确认收货 + </button> + {{# } }} + + {{ d[i]['hook']?d[i]['hook']:"" }} + <div class="wst-clear"></div> + </div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + <li class="tab-item {if $type==''}tab-curr{/if}" type="" >全部</li> + <li class="tab-item {if $type=='waitPay'}tab-curr{/if}" type="waitPay" >待付款</li> + <li class="tab-item {if $type=='waitDeliver'}tab-curr{/if}" type="waitDeliver" >待发货</li> + <li class="tab-item {if $type=='waitReceive'}tab-curr{/if}" type="waitReceive" >待收货</li> + <li class="tab-item {if $type=='waitAppraise'}tab-curr{/if}" type="waitAppraise" >待评价</li> + <li class="tab-item {if $type=='finish'}tab-curr{/if}" type="finish" >已完成</li> + <li class="tab-item {if $type=='abnormal'}tab-curr{/if}" type="abnormal" >取消拒收</li> + </ul> + </div> + <div id="order-box"> + + </div> + </section> + </div> + {:hook('wechatDocumentOrderList')} + <script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="detail-head" style="margin-top:0;"> + {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + {{# if(d.payType==1) { }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待付款</p></div> + {{# } }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.orderStatus==2){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已收货</p></div> + </div> + </div> + {{# } }} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1 && d.payType==1 && d.isPay==1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==2) { }} active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单状态:</span> + <span class="o-status">{{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.payType==1 && d.isPay==1) { }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单编号:</span>{{d.orderNo}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">下单时间:</span>{{d.createTime}}</div> + </div> + </div> + + <div class="detail-head"> + {{# if(d.userName){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货人:</span>{{d.userName}} <span class="d-utel">{{d.userPhone}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货地址:</span><span class="d-uaddr">{{d.userAddress}}<i></i></span></div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付信息:</span>{{d.payInfo}}</div> + </div> + {{# if(d.payTime){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付时间:</span>{{d.payTime}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">配送信息:</span>{{d.deliverInfo}}</div> + </div> + {{# if(WST.blank(d.expressNo)!=''){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递公司:</span>{{d.expressName}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递号:</span>{{d.expressNo}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票信息:</span>{{# if(d.isInvoice==1) { }}需要{{# } else{ }}不需要{{# } }}</div> + </div> + {{# if(d.isInvoice==1) { }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票抬头:</span>{{d.invoiceClient}}</div> + </div> + {{# + var inv_json = JSON.parse(d.invoiceJson); + var inv_code = (inv_json!=null && inv_json.invoiceCode!=undefined)?inv_json.invoiceCode:''; + if(inv_json!=null && inv_json.type!=undefined && inv_json.type==0){ + }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票税号:</span>{{inv_code}}</div> + </div> + {{# } }} + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单备注:</span>{{d.orderRemarks}}</div> + </div> + </div> + + {{# if(d.isRefund==1){ }} + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款金额:</span>¥ {{d.backMoney}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款备注:</span>{{d.refundRemark}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款时间:</span>{{d.refundTime}}</div> + </div> + </div> + {{# } }} + + + <div class="detail-head"> + <div class="ui-row-flex o-shops"> + <div class="ui-col ui-col wst-or-term"><p class="shops" onclick="javascript:WST.intoShops({{d.shopId}});"><i></i>{{d.shopName}}<p></div> + </div> + {{# for(var i=0;i<d.goods.length;i++){ }} + <div class="ui-row-flex ui-whitespace border-b d-goodsitme" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}})"> + <div class="ui-col"> + <img src="__ROOT__/{{d.goods[i].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d.goods[i].goodsName}}</p> + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d.goods[i].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d.goods[i].goodsPrice}}</p><p>x {{d.goods[i].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# if(d.goods[i].goodsType==1 && d.orderStatus==2){ }} + {{# for(var e=0;e<d.goods[i].extraJson.length;e++){ }} + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col"> + <p>卡券号:{{d.goods[i].extraJson[e].cardNo}}</p> + <p>卡券密码:{{d.goods[i].extraJson[e].cardPwd}}</p> + </div> + </div> + {{# } }} + {{# } }} + {{# } }} + </div> + + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">获得积分</span><span class="o-status2">{{d.orderScore}} 个</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">商品总额</span><span class="o-status2">¥ {{d.goodsMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">运费</span><span class="o-status2">¥ {{d.deliverMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">积分抵扣金额</span><span class="o-status2">¥ -{{d.scoreMoney}}</span></div> + </div> + {{# if(d.useScore>0){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">使用积分数</span><span class="o-status2">{{d.useScore}} 个</span></div> + </div> + {{# } }} + {{ d['hook']?d['hook']:"" }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term2"><span class="wst-or-describe2">实付款</span><span class="o-status2"><span style="font-size:0.13rem;">¥ </span>{{d.realTotalMoney}}</span></div> + </div> + </div> + </div> +</script> + {/* 遮盖层 */} + <div class="wst-cover" id="cover"></div> + {/* 订单详情层 */} + <div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span id="wordTitle">订单详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + </div> + </div> + {/* 退款层 */} + <div class="wst-fr-box" id="refundFrame"> + <div class="title"><span>申请退款</span><i class="ui-icon-close-page" onclick="javascript:reFundDataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="refund-content"> + <div class="detail-head" style="margin-top:0;"> + <div class="wst-or-process"> + <div class="ui-row-flex" style="padding:10px;border-bottom:RGB(242,242,242) 2px dashed;"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>买家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + <div class="wst-or-refund"> + <p class="prompt">请选择取消订单申请退款的原因,以便我们能更好的为您服务。</p> + <div class="term"> + <span class="sign">*</span>退款原因: + <select id='refundReason' onchange='javascript:changeRefundType(this.value)'> + {volist name=":WSTDatas('REFUND_TYPE')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + </div> + <div class="term"> + <span class="sign">*</span>退款金额: <input type='number' id='money' maxLength='10' onkeyup="javascript:WST.isChinese(this,1)" autocomplete="off"> + </div> + <p class="prompt">(金额不能超过<font color='red' id="realTotalMoney">0</font>,<span id="useScore">0</span>个积分抵扣<font color='red' id="scoreMoney">¥ 0</font>)</p> + <div class="term"> + <div id='refundTr' style="width:99%;display:none;" > + <span class="sign">*</span>其他原因 + <textarea id='refundContent' style='width:100%;height:80px;padding: 5px;' maxLength='200'></textarea> + </div> + </div> + <p class="cancel-btn-box ui-flex ui-flex-pack-center"> + <button id="wst-event8" type="button" class="ui-btn-s wst-dialog-b2">提交申请退款</button> + </p> + </div> + </div> + </div> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +<div class="ui-dialog" id="cancelBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <div class="ui-dialog-bd-title">请选择您取消订单的原因:</div> + <select id='reason'> + {volist name=":WSTDatas('ORDER_CANCEL')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event0" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> + +<div class="ui-dialog" id="rejectBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + <div class="ui-dialog-bd-title">请选择您拒收订单的原因:</div> + + <select id='reject' onchange='javascript:changeRejectType(this.value)'> + {volist name=":WSTDatas('ORDER_REJECT')" id="vo"} + <option value='{$vo["dataVal"]}'>{$vo["dataName"]}</option> + {/volist} + </select> + <br /> + <div id='rejectTr' style='display:none'> + 原因<font color='red'>*</font>: + <textarea id='content' style='width:99%;height:80px;' maxLength='200'></textarea> + </div> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_list.js?v={$v}'></script> +<script> +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getOrderList(); + WST.initFooter('user'); + backPrevPage(WST.U('wechat/users/index')); + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var type = $(this).attr('type'); + $('#type').val(type); + reFlashList(); + }); + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); + $("#refundFrame").css('top',0); + $("#refundFrame").css('right',-w); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - $(window).height())) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getOrderList(); + } + } + }); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_list.js b/hyhproject/wechat2/view/default/users/orders/orders_list.js new file mode 100755 index 0000000..4921240 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_list.js @@ -0,0 +1,321 @@ +jQuery.noConflict(); +// 提醒发货 +function noticeDeliver(id){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('wechat/orders/noticeDeliver'),{id:id},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} +// 获取订单列表 +function getOrderList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/orders/getOrderList'), param, function(data){ + var json = WST.toJson(data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#order-box').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-order.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关订单</p>'; + html += '<button class="ui-btn-s" onclick="javascript:WST.intoIndex();">去逛逛</button>'; + html += '</div>'; + $('#order-box').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} + +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#order-box').html(' '); + getOrderList(); +} + +function showCancelBox(event){ + $("#wst-event0").attr("onclick","javascript:"+event); + $("#cancelBox").dialog("show"); +} +// 取消订单 +function cancelOrder(oid){ + hideDialog('#cancelBox'); + $.post(WST.U('wechat/orders/cancellation'),{id:oid,reason:$('#reason').val()},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $('#order-box').html(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +// 拒收 +function showRejectBox(event){ + $("#wst-event3").attr("onclick","javascript:"+event); + $("#rejectBox").dialog("show"); +} + +function rejectOrder(oid){ + var param = {}; + param.id=oid; + param.reason=$('#reject').val(); + param.content=$('#content').val(); + if($('reject').val()==10000){ + var content = $.trim($('#content').val()); + if(content == '') + WST.msg('请输入拒收原因','info'); + return; + } + + $.post(WST.U('wechat/orders/reject'),param,function(data){ + + hideDialog('#rejectBox'); + + var json = WST.toJson(data); + if(json.status==1){ + $('#content').val(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +// 退款 +function showRefundBox(id){ + // 重置表单 + $('#refundReason').val(1); + $('#refundContent').html(' '); + $('#money').val(' '); + $('#refundTr').hide(); + $.post(WST.U('wechat/orders/getRefund'),{id:id},function(data){ + $('#realTotalMoney').html('¥'+data.realTotalMoney); + $('#useScore').html(data.useScore); + $('#scoreMoney').html('¥ '+data.scoreMoney); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#refund-boxTitle').height();// 弹出层标题高度 + var contentH = $('#refund-content').height(); // 弹出层内容高度 + $('#refund-content').css('height',clientH-boxheadH+'px'); + $("#wst-event8").attr("onclick","javascript:refund("+id+")"); + reFundDataShow(); + }) +} +function changeRefundType(v){ + if(v==10000){ + $('#refundTr').show(); + }else{ + $('#refundTr').hide(); + } +} +//弹框 +function reFundDataHide(){ + $('#shopBox').show(); + var dataHeight = $("#refundFrame").css('height'); + var dataWidth = $("#refundFrame").css('width'); + jQuery('#refundFrame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} +function reFundDataShow(){ + jQuery('#cover').attr("onclick","javascript:reFundDataHide();").show(); + jQuery('#refundFrame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) +} +// 退款 +function refund(id){ + var params = {}; + params.reason = $.trim($('#refundReason').val()); + params.content = $.trim($('#refundContent').val()); + params.money = $.trim($('#money').val()); + params.id = id; + if(params.money<0 || params.money==''){ + WST.msg('无效的退款金额','info'); + return; + } + if(params.reason==10000){ + var content = $.trim($('#refundContent').val()); + if(content == ''){ + WST.msg('请输入原因','info'); + return; + } + } + $.post(WST.U('wechat/orderrefunds/refund'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('申请退款成功','success'); + history.go(0); + }else{ + WST.msg(json.msg,'info'); + } + }) +} + +function changeRejectType(v){ + if(v==10000){ + $('#rejectTr').show(); + }else{ + $('#rejectTr').hide(); + } +} + +// 隐藏对话框 +function hideDialog(id){ + $(id).dialog("hide"); +} + +// 确认收货 +function receive(oid){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('wechat/orders/receive'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +/*********************** 订单详情 ****************************/ +//弹框 +function dataShow(title){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) + $('#wordTitle').html(title); +} +function dataHide(){ + $('#shopBox').show(); + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getOrderDetail(oid){ + $.post(WST.U('wechat/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#content').html(html); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#boxTitle').height();// 弹出层标题高度 + var contentH = $('#content').height(); // 弹出层内容高度 + $('#content').css('height',clientH-boxheadH+'px'); + dataShow('订单详情'); + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} +// 跳转到评价页 +function toAppr(oid){ + location.href=WST.U('wechat/orders/orderappraise',{'oId':oid}); +} +// 投诉 +function complain(oid){ + location.href=WST.U('wechat/ordercomplains/complain',{'oId':oid}); +} + +//余额支付 +function walletPay(type){ + var payPwd = $('#payPwd').val(); + if(!payPwd){ + WST.msg('请输入支付密码','info'); + return; + } + if(type==0){ + var payPwd2 = $('#payPwd2').val(); + if(payPwd2==''){ + WST.msg('确认密码不能为空','info'); + return false; + } + if(payPwd!=payPwd2){ + WST.msg('确认密码不一致','info'); + return false; + } + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + var params = {}; + if(type==0){ + params.newPass = payPwd; + $.post(WST.U('wechat/users/editpayPwd'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + WST.load('成功设置密码,<br>订单支付中···'); + }else{ + WST.msg(json.msg,'info'); + } + }); + }else{ + WST.load('正在核对密码···'); + } + params.payPwd = payPwd; + params.orderNo = $('#orderNo').val(); + params.isBatch = $('#isBatch').val(); + $('.wst-btn-dangerlo').attr('disabled', 'disabled'); + setTimeout(function(){ + $.post(WST.U('wechat/wallets/payByWallet'),params,function(data,textStatus){ + WST.noload(); + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/orders/index'); + },2000); + }else{ + WST.msg(json.msg,'info'); + setTimeout(function(){ + $('.wst-btn-dangerlo').removeAttr('disabled'); + },2000); + } + }); + },1000); +} +//选择支付方式 +function choicePay(orderNo,isBatch){ + location.href=WST.U('wechat/orders/succeed',{'orderNo':orderNo,'isBatch':isBatch}); +} +//跳转支付 +function toPay(orderNo,isBatch,n){ + if(n=='weixinpays'){ + location.href=WST.U('wechat/weixinpays/toPay',{'orderNo':orderNo,'isBatch':isBatch}); + }else if(n=='wallets'){ + location.href = WST.U('wechat/wallets/payment',{"orderNo":orderNo,'isBatch':isBatch}); + } +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_pay.html b/hyhproject/wechat2/view/default/users/orders/orders_pay.html new file mode 100755 index 0000000..baa391b --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_pay.html @@ -0,0 +1,115 @@ +{extend name="default/base" /} +{block name="title"} +{$payObj=='recharge'?"在线充值":"支付订单"} +- {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header class="ui-header ui-header-positive wst-header"> + {if($payObj=='recharge')} + <a class="ui-icon-return" href='{:Url('wechat/logmoneys/usermoneys')}'></a><h1>在线充值</h1> + {else} + <a class="ui-icon-return" href='{:Url('wechat/orders/index')}'></a><h1>支付订单</h1> + {/if} + </header> +{/block} +{block name="main"} + <section class="ui-container" id="shopBox"> + {if(empty($message))} + {if($payObj=='recharge')} + <div class="recharge-box"> + <div>钱包充值</div> + <div class="paybox"><span class="wst-orders_prices">¥ {$needPay}</span></div> + </div> + {else} + {volist name="$rs['list']" id="order"} + <div class="order-item"> + <div class="ui-row-flex item-head" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{$order['orderNo']}<span style="float : right;">邮费:{$order['deliverMoney']}</span></div> + </div> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <div class="ui-row-flex"> + <div class="ui-col"> + <img src="__ROOT__/{$vo['goodsImg']}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{$vo['goodsName']}</p> + {if condition="count($vo['goodsSpecNames']) gt 0"} + <p class="o-gSpec ui-nowrap-flex">规格: + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + </p> + {/if} + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0"><p>¥ {$vo['goodsPrice']}</p><p>x {$vo['goodsNum']}</p></div> + </div> + {/volist} + + <div class="ui-btn-wrap" style="text-align: right;padding:10px 0"> + <span class="wst-orders_pricet">总金额:<span class="wst-orders_prices">¥ <?php echo sprintf("%.2f", $rs['totalMoney']);?></span></span> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + {/if} + <div style="text-align: center;padding-top: 20px;"> + <button type="button" class="wst-btn-dangerlo" onclick="javascript:callpay();" style="width: 80%; display: inline-block;">确认支付</button> + </div> + </section> + {else} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>{$message}</p> + </li> + </ul> + {/if} + </div> + +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_list.js?v={$v}'></script> +{if(empty($message))} +<script type="text/javascript"> + //调用微信JS api 支付 + function jsApiCall(){ + WeixinJSBridge.invoke( + 'getBrandWCPayRequest', + <?php echo $jsApiParameters; ?>, + function(res){ + if(res.err_msg=="get_brand_wcpay_request:ok"){ + location.href = "{$returnUrl}"; + } + } + ); + setTimeout(function(){ + $('.wst-btn-dangerlo').removeAttr('disabled'); + },2000); + } + function callpay(){ + $('.wst-btn-dangerlo').attr('disabled', 'disabled'); + if (typeof WeixinJSBridge == "undefined"){ + if( document.addEventListener ){ + document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); + }else if (document.attachEvent){ + document.attachEvent('WeixinJSBridgeReady', jsApiCall); + document.attachEvent('onWeixinJSBridgeReady', jsApiCall); + } + }else{ + jsApiCall(); + } + } + $(document).ready(function(){ + {if($payObj=='recharge')} + backPrevPage(WST.U('wechat/logmoneys/usermoneys')); + {else} + backPrevPage(WST.U('wechat/orders/index')); + {/if} + }); + </script> +{/if} +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_pay_list.html b/hyhproject/wechat2/view/default/users/orders/orders_pay_list.html new file mode 100755 index 0000000..68f47d3 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_pay_list.html @@ -0,0 +1,27 @@ +{extend name="default/base" /} +{block name="title"}选择支付方式 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>选择支付方式</h1> + </header> +{/block} +{block name="main"} + <section class="ui-container"> + <ul class="ui-list ui-list-text ui-list-link wst-pa-l"> + {volist name="$payments[1]" id="pa"} + <li class="line" onclick="javascript:toPay({$orderNo},{$isBatch},'{$pa['payCode']}');"> + <span class="{$pa['payCode']}"></span><h5 class="ui-nowrap">{$pa['payName']}</h5> + </li> + {/volist} + </ul> + </section> +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_list.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/orders/orders_pay_wallets.html b/hyhproject/wechat2/view/default/users/orders/orders_pay_wallets.html new file mode 100755 index 0000000..78db63f --- /dev/null +++ b/hyhproject/wechat2/view/default/users/orders/orders_pay_wallets.html @@ -0,0 +1,87 @@ +{extend name="default/base" /} +{block name="title"}支付订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <header class="ui-header ui-header-positive wst-header"> + <a class="ui-icon-return" href='{:Url('wechat/orders/index')}'></a><h1>支付订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <section class="ui-container"> + {if(empty($message))} + <input type="hidden" name="" value="{$data['orderNo']}" id="orderNo" autocomplete="off"> + <input type="hidden" name="" value="{$data['isBatch']}" id="isBatch" autocomplete="off"> + {volist name="$rs['list']" id="order"} + <div class="order-item"> + <div class="ui-row-flex item-head"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{$order['orderNo']}<span style="float : right;">邮费:{$order['deliverMoney']}</span></div> + </div> + {volist name="$rs['goods'][$order['orderId']]" id="vo"} + <div class="ui-row-flex"> + <div class="ui-col"> + <img src="__ROOT__/{$vo['goodsImg']}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi">{$vo['goodsName']}</p> + {if condition="count($vo['goodsSpecNames']) gt 0"} + <p class="o-gSpec ui-nowrap-flex">规格: + {volist name="$vo['goodsSpecNames']" id="spec"} + {$spec}&nbsp; + {/volist} + </p> + {/if} + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0"><p>¥ {$vo['goodsPrice']}</p><p>x {$vo['goodsNum']}</p></div> + </div> + {/volist} + + <div class="ui-btn-wrap" style="text-align: right;padding:10px 0"> + <span class="wst-orders_pricet">总金额:<span class="wst-orders_prices">¥ <?php echo sprintf("%.2f", $rs['totalMoney']);?></span></span> + </div> + <div class="wst-clear"></div> + </div> + {/volist} + <div class="wst-wa-info"> + <p class="info">钱包余额:<span>¥ {$userMoney}</span>,待支付订单总额:<span>¥ {$needPay}</span></p> + {if($payPwd==0)} + <p class="pay-info">您尚未设置支付密码,请设置支付密码</p> + <div class="pay">设置密码:<input type="password" id="payPwd" maxlength="6" autocomplete="off"></div> + <div class="pay">确认密码:<input type="password" id="payPwd2" maxlength="6" autocomplete="off"></div> + {else} + <div class="pay">支付密码:<input type="password" id="payPwd" maxlength="6" autocomplete="off"></div> + {/if} + </div> + {if($payPwd==1)}<div class="wst-wa-forget ui-whitespace"><a href="{:url('wechat/users/backPayPass')}">忘记密码?</a></div>{/if} + <div style="text-align: center;"> + <button type="button" class="wst-btn-dangerlo" onclick="javascript:walletPay({$payPwd});" style="width: 80%; display: inline-block;">确认支付</button> + </div> + {else} + <ul class="ui-row-flex wst-flexslp"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>{$message}</p> + </li> + </ul> + {/if} + </section> +{/block} +{block name="footer"}{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/orders/orders_list.js?v={$v}'></script> +<script> +$(document).ready(function(){ + backPrevPage(WST.U('wechat/orders/index')); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/recharge/recharge.html b/hyhproject/wechat2/view/default/users/recharge/recharge.html new file mode 100755 index 0000000..fc898d9 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/recharge/recharge.html @@ -0,0 +1,84 @@ +{extend name="default/base" /} +{block name="title"}我的资金 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/recharge.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header"> + <i class="ui-icon-return" onclick="history.back()"></i><h1>充值</h1> + </header> +{/block} +{block name="main"} + <section class="ui-container"> + + <ul class="ui-grid-trisect"> + {volist name="chargeItems" id="item"} + <li> + <div class="wst-frame2 {$key} <?php echo ($key==0)?'j-selected':''; ?>" onclick="javascript:changeSelected({$item['id']},'itemId',this)"> + <div> + {if condition="$item['giveMoney'] gt 0"} + <div class='charge-doub'>充值 <span class="charge-money" id="needPay_{$item['id']}" sum="{$item['chargeMoney']}">{$item['chargeMoney']}</span> 元</div> + <div>送 {$item['giveMoney']} 元</div> + {else/} + <div class='charge-alone'>充值 <span class="charge-money">{$item['chargeMoney']}</span> 元</div> + {/if} + </div> + <i></i> + </div> + </li> + {/volist} + <li > + <div class="wst-frame2 " onclick="javascript:changeSelected(0,'itemId',this)"> + <div> + <div class='charge-alone'> + <span class="j-charge-other">其他金额</span> + <span class="j-charge-money"> + <input class="charge-othermoney j-ipt" id="needPay" value="1" maxlength="10" data-rule="充值金额:required;" onkeypress="return WST.isNumberKey(event)" onkeyup="javascript:rechargeMoney(this.value)" maxlength="8"> + </span> + </div> + </div> + <i></i> + </div> + + </li> + </ul> + {php} + $sum = 0; + if($chargeItems){ + $sum = $chargeItems[0]['chargeMoney']; + } + {/php} + <div class="wst-re-info"> + <p>当前余额<span class="balance">¥ <span>{$rs['userMoney']}</span></span></p> + <p>充值金额<span class="balance">¥ <span id="rechargeMoney">{$sum}</span></span></p> + </div> + <div class="ui-form"> + {volist name="payments" id="payment" } + <div class="ui-form-item ui-form-item-radio paytype-term"> + <label class="ui-checkbox" for="radio"> + <input type="radio" {if condition="$key eq 0"}checked{/if} name="payCode" value="{$payment['payCode']}"> + </label> + <i class="{$payment['payCode']}"></i> + <p>{$payment['payName']}</p> + </div> + {/volist} + </div> + <div class="ui-btn-wrap"> + <button class="ui-btn-lg ui-btn-danger wst-re-button" onclick="toPay()">确认支付</button> + </div> + <div class="tips-box"> + <ul class="ui-row first-time"> + <li class="ui-col ui-col-100 ft-title"><i></i><span>充值说明:</span></li> + <li class="ui-col ui-col-100 ft-item">1.充值金额和赠送金额只能用于购买商品,不能提现;</li> + </ul> + </div> + <input type="hidden" value="" id='itemId' class='j-ipt' /> + </section> +{/block} + +{block name="footer"} +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/recharge/recharge.js?v={$v}'></script> +{/block} diff --git a/hyhproject/wechat2/view/default/users/recharge/recharge.js b/hyhproject/wechat2/view/default/users/recharge/recharge.js new file mode 100755 index 0000000..766c1b8 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/recharge/recharge.js @@ -0,0 +1,45 @@ +jQuery.noConflict(); +function inEffect(obj,n){ + $("ul div").removeClass('j-selected'); + $(obj).addClass('j-selected'); +} +function changeSelected(n,index,obj){ + $('#'+index).val(n); + if(n==0){ + $(".j-charge-other").hide(); + $(".j-charge-money").show(); + var needPay = $("#needPay").val(); + + }else{ + $(".j-charge-other").show(); + $(".j-charge-money").hide(); + var needPay = $("#needPay_"+n).attr("sum"); + } + rechargeMoney(needPay); + inEffect(obj,2); +} +function rechargeMoney(n){ + $("#rechargeMoney").html(n); +} + +function toPay(){ + var params = {}; + params.payObj = "recharge"; + params.targetType = 0; + params.needPay = $.trim($("#needPay").val()); + params.payCode = $("input[name='payCode']:checked").val(); + params.itemId = $.trim($("#itemId").val()); + if(params.itemId==0 && params.needPay<=0){ + WST.msg('请输入充值金额', 'info'); + return; + } + if(params.payCode==""){ + WST.msg('请先选择支付方式','info'); + return; + } + location.href = WST.U('wechat/weixinpays/toPay',params); +} + +$(function(){ + jQuery(".wst-frame2:first").click(); +}); \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/index.html b/hyhproject/wechat2/view/default/users/security/index.html new file mode 100755 index 0000000..9627ef9 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/index.html @@ -0,0 +1,27 @@ +{extend name="default/base" /} +{block name="title"}账户安全 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "账户安全"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <section class="ui-container"> + <ul class="ui-list ui-list-text ui-list-link wst-se-l"> + <li class="line" onclick="javascript:inLogin();"> + <span class="pay"></span><h5 class="ui-nowrap">{if($user['loginPwd']==0)}设置{else}修改{/if}登录密码</h5></a> + </li> + <li class="line" onclick="javascript:inPay();"> + <span class="pay"></span><h5 class="ui-nowrap">{if($user['payPwd']==0)}设置{else}修改{/if}支付密码</h5></a> + </li> + <li onclick="javascript:inPhone();"> + <span class="phone"></span><h5 class="ui-nowrap">{if($user['userPhone']==0)}绑定{else}修改{/if}手机号码</h5> + </li> + </ul> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/security.js b/hyhproject/wechat2/view/default/users/security/security.js new file mode 100755 index 0000000..1ebaf87 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/security.js @@ -0,0 +1,334 @@ +var time = 0; +var isSend = false; +$(document).ready(function(){ + WST.initFooter('user'); +}); +//修改登录密码 +function inLogin(){ + location.href = WST.U('wechat/users/editLoginPass'); +} +function editLogin(type){ + if(type==1){ + var orloginPwd = $('#orloginPwd').val(); + if(orloginPwd==''){ + WST.msg('原密码不能为空','info'); + $('#orloginPwd').focus(); + return false; + } + } + var loginPwd = $('#loginPwd').val(); + var cologinPwd = $('#cologinPwd').val(); + if(loginPwd==''){ + WST.msg('新密码不能为空','info'); + $('#loginPwd').focus(); + return false; + } + if(cologinPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#cologinPwd').focus(); + return false; + } + if(loginPwd.length < 6){ + WST.msg('请输入6位以上数字或者字母密码','info'); + $('#cologinPwd').focus(); + return false; + } + if(cologinPwd!=loginPwd){ + WST.msg('确认密码不一致','info'); + $('#cologinPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(type==1)var orloginPwd = rsa.encrypt(orloginPwd); + var loginPwd = rsa.encrypt(loginPwd); + } + WST.load('设置中···'); + var param = {}; + param.type = type; + if(type==1)param.oldPass = orloginPwd; + param.newPass = loginPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/editloginPwd'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/users/security'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +//修改支付密码 +function inPay(){ + location.href = WST.U('wechat/users/editPayPass'); +} +function editPay(type){ + if(type==1){ + var orpayPwd = $('#orpayPwd').val(); + if(orpayPwd==''){ + WST.msg('原密码不能为空','info'); + $('#orpayPwd').focus(); + return false; + } + } + var payPwd = $('#payPwd').val(); + var copayPwd = $('#copayPwd').val(); + if(payPwd==''){ + WST.msg('新密码不能为空','info'); + $('#payPwd').focus(); + return false; + } + if(copayPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#copayPwd').focus(); + return false; + } + if(payPwd.length !=6){ + WST.msg('请输入6位数字密码','info'); + $('#copayPwd').focus(); + return false; + } + if(copayPwd!=payPwd){ + WST.msg('确认密码不一致','info'); + $('#copayPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + if(type==1)var orpayPwd = rsa.encrypt(orpayPwd); + var payPwd = rsa.encrypt(payPwd); + } + WST.load('设置中···'); + var param = {}; + param.type = type; + if(type==1)param.oldPass = orpayPwd; + param.newPass = payPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/editpayPwd'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/users/security'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); +} +//找回支付密码 +function backpayCode(){ + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('wechat/users/backpayCode'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg"); + isSend = false; + } + data = json = null; + }); +} +function backPaypwd(type){ + if(type==1){ + var payPwd = $('#payPwd').val(); + var copayPwd = $('#copayPwd').val(); + if(payPwd==''){ + WST.msg('新密码不能为空','info'); + $('#payPwd').focus(); + return false; + } + if(copayPwd==''){ + WST.msg('确认密码不能为空','info'); + $('#copayPwd').focus(); + return false; + } + if(payPwd.length !=6){ + WST.msg('请输入6位数字密码','info'); + $('#copayPwd').focus(); + return false; + } + if(copayPwd!=payPwd){ + WST.msg('确认密码不一致','info'); + $('#copayPwd').focus(); + return false; + } + if(window.conf.IS_CRYPTPWD==1){ + var public_key=$('#key').val(); + var exponent="10001"; + var rsa = new RSAKey(); + rsa.setPublic(public_key, exponent); + var payPwd = rsa.encrypt(payPwd); + } + WST.load('设置中···'); + var param = {}; + param.newPass = payPwd; + $('#modifyPwd').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/resetbackPay'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/users/security'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPwd').removeAttr('disabled').removeClass("active"); + } + WST.noload(); + data = json = null; + }); + }else{ + var phoneCode = $('#phoneCode').val(); + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + $('#phoneCode').focus(); + return false; + } + var param = {}; + param.phoneCode = phoneCode; + $('#modifyPhone').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/verifybackPay'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/users/backPayPass'); + },2000); + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPhone').removeAttr('disabled').removeClass("active"); + } + data = json = null; + }); + } +} +//修改手机 +function inPhone(){ + location.href = WST.U('wechat/users/editPhone'); +} +//发送短信 +function obtainCode(type){ + if(type==0){ + var userPhone = $('#userPhone').val(); + if(userPhone ==''){ + WST.msg('请输入手机号码','info'); + $('#userPhone').focus(); + return false; + } + } + if(WST.conf.SMS_VERFY==1){ + var smsVerfy = $('#smsVerfy').val(); + if(smsVerfy ==''){ + WST.msg('请输入验证码','info'); + $('#smsVerfy').focus(); + return false; + } + } + var param = {}; + param.userPhone = userPhone; + param.smsVerfy = smsVerfy; + if(isSend)return; + isSend = true; + $.post(WST.U('wechat/users/'+((type==0)?"sendCodeTie":"sendCodeEdit")), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + time = 120; + $('#obtain').attr('disabled', 'disabled').html('120秒获取'); + var task = setInterval(function(){ + time--; + $('#obtain').html(''+time+"秒获取"); + if(time==0){ + isSend = false; + clearInterval(task); + $('#obtain').removeAttr('disabled').html("重新发送"); + } + },1000); + }else{ + WST.msg(json.msg,'warn'); + WST.getVerify("#verifyImg"); + isSend = false; + } + data = json = null; + }); +} +//修改手机号码 +function editPhone(type){ + if(type==0){ + var userPhone = $('#userPhone').val(); + if(userPhone==''){ + WST.msg('手机号码不能为空','info'); + $('#userPhone').focus(); + return false; + } + } + var phoneCode = $('#phoneCode').val(); + if(phoneCode==''){ + WST.msg('请输入短信验证码','info'); + $('#phoneCode').focus(); + return false; + } + var param = {}; + param.phoneCode = phoneCode; + $('#modifyPhone').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/users/'+((type==0)?"phoneEdit":"phoneEdito")), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + if(type==0){ + setTimeout(function(){ + location.href = WST.U('wechat/users/security'); + },2000); + }else{ + setTimeout(function(){ + location.href = WST.U('wechat/users/editPhoneo'); + },2000); + } + + }else{ + WST.msg(json.msg,'warn'); + $('#modifyPhone').removeAttr('disabled').removeClass("active"); + } + data = json = null; + }); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/user_back_paypwd.html b/hyhproject/wechat2/view/default/users/security/user_back_paypwd.html new file mode 100755 index 0000000..5b13810 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/user_back_paypwd.html @@ -0,0 +1,64 @@ +{extend name="default/base" /} +{block name="title"}找回支付密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "找回支付密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + {if($user['phoneType']==1)} + <div class="wst-se-footer"> + <button id="modifyPhone" type="button" class="button" onclick="javascript:backPaypwd({$user['backType']});">{if($user['backType']==0)}下一步{else}确定{/if}</button> + </div> + {else} + <div class="wst-se-footer"> + <button id="modifyPhone" type="button" class="button" onclick="javascript:inPhone();">去绑定手机号码</button> + </div> + {/if} +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + {if($user['backType']==1)} + <div class="wst-se-pay"> + <div class="pay"><input id="payPwd" type="password" placeholder="新密码" maxlength="6"></div> + <div class="pay"><input id="copayPwd" type="password" placeholder="确认密码" maxlength="6"></div> + </div> + {else} + {if($user['phoneType']==1)} + <div class="wst-se-pay"> + <div class="phone">您绑定的手机号码为:{$user['userPhone']}</div> + {if(WSTConf('CONF.smsVerfy')==1)} + <div class="verify"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg' src="{:url('wechat/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'> + </div> + {/if} + <div class="verify"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" type="button" class="ui-btn-primary" onclick="javascript:backpayCode()">获取验证码</button> + </div> + </div> + {else} + <ul class="ui-row-flex wst-flexslp ui-whitespace"> + <li class="ui-col ui-flex ui-flex-pack-center"> + <p>对不起,你还未绑定手机号码,请去绑定手机号码。</p> + </li> + </ul> + {/if} + {/if} + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/user_login_pass.html b/hyhproject/wechat2/view/default/users/security/user_login_pass.html new file mode 100755 index 0000000..b8453ad --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/user_login_pass.html @@ -0,0 +1,35 @@ +{extend name="default/base" /} +{block name="title"}{if($user['loginPwd']==1)}修改{else}设置{/if}登录密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['loginPwd']==1?$Title = "修改登录密码":$Title = "设置登录密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPwd" type="button" class="button" onclick="javascript:editLogin({$user['loginPwd']});">确定</button> + </div> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['loginPwd']==1)}<div class="pay"><input id="orloginPwd" type="password" placeholder="原密码"></div>{/if} + <div class="pay"><input id="loginPwd" type="password" placeholder="新密码"></div> + <div class="pay"><input id="cologinPwd" type="password" placeholder="确认密码"></div> + </div> + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/user_pay_pass.html b/hyhproject/wechat2/view/default/users/security/user_pay_pass.html new file mode 100755 index 0000000..19adc20 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/user_pay_pass.html @@ -0,0 +1,36 @@ +{extend name="default/base" /} +{block name="title"}{if($user['payPwd']==1)}修改{else}设置{/if}支付密码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['payPwd']==1?$Title = "修改支付密码":$Title = "设置支付密码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPwd" type="button" class="button" onclick="javascript:editPay({$user['payPwd']});">确定</button> + </div> +{/block} +{block name="main"} + <input type="hidden" value="{:WSTConf('CONF.pwdModulusKey')}" id="key" autocomplete="off"> + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['payPwd']==1)}<div class="pay"><input id="orpayPwd" type="password" placeholder="原密码" maxlength="6"></div>{/if} + <div class="pay"><input id="payPwd" type="password" placeholder="新密码" maxlength="6"></div> + <div class="pay"><input id="copayPwd" type="password" placeholder="确认密码" maxlength="6"></div> + </div> + {if($user['payPwd']==1)}<p class="wst-se-back"><a href="{:url('wechat/users/backPayPass')}">忘记支付密码?</a></p>{/if} + </section> +{/block} +{block name="js"} +<script type="text/javascript" src="__STATIC__/js/rsa.js"></script> +<script type='text/javascript' src='__WECHAT__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/security/user_phone.html b/hyhproject/wechat2/view/default/users/security/user_phone.html new file mode 100755 index 0000000..d12690c --- /dev/null +++ b/hyhproject/wechat2/view/default/users/security/user_phone.html @@ -0,0 +1,45 @@ +{extend name="default/base" /} +{block name="title"}{if($user['phoneType']==1)}修改{else}绑定{/if}手机号码 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/security.css?v={$v}"> +{/block} +{block name="header"} + {php}$user['phoneType']==1?$Title = "修改手机号码":$Title = "绑定手机号码"{/php} + {include file="default/header" /} +{/block} +{block name="footer"} + {/* 大加载 */} + <div class="ui-loading-block" id="Loadl"> + <div class="ui-loading-cnt"> + <i class="ui-loading-bright"></i> + <p id="j-Loadl">正在加载中...</p> + </div> + </div> + <div class="wst-se-footer"> + <button id="modifyPhone" type="button" class="button" onclick="javascript:editPhone({$user['phoneType']});">{if($user['phoneType']==1)}下一步{else}确定{/if}</button> + </div> +{/block} +{block name="main"} + <section class="ui-container"> + <div class="wst-se-pay"> + {if($user['phoneType']==1)} + <div class="phone">您绑定的手机号码为:{$user['userPhone']}</div> + {else} + <div class="pay"><input id="userPhone" type="tel" placeholder="手机号码"></div> + {/if} + {if(WSTConf('CONF.smsVerfy')==1)} + <div class="verify"> + <input id="smsVerfy" type="text" placeholder="输入验证码" maxlength="10"> + <img id='verifyImg' src="{:url('wechat/users/getVerify')}" onclick='javascript:WST.getVerify("#verifyImg")'> + </div> + {/if} + <div class="verify"> + <input id="phoneCode" type="text" placeholder="输入短信验证码" maxlength="8"> + <button id="obtain" type="button" class="ui-btn-primary" onclick="javascript:obtainCode({$user['phoneType']})">获取验证码</button> + </div> + </div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/security/security.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/sellerorders/orders_list.html b/hyhproject/wechat2/view/default/users/sellerorders/orders_list.html new file mode 100755 index 0000000..2de829d --- /dev/null +++ b/hyhproject/wechat2/view/default/users/sellerorders/orders_list.html @@ -0,0 +1,439 @@ +{extend name="default/base" /} +{block name="title"}我的订单 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/orders.css?v={$v}"> +{/block} +{block name="header"} + <div id="info_list"> + <header style="background:#ffffff;" class="ui-header ui-header-positive wst-header wst-headero"> + <i class="ui-icon-return" onclick="location.href='{:url('wechat/users/index')}'"></i><h1>我的订单</h1> + </header> +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + + <script id="shopList" type="text/html"> + {{# for(var i = 0; i < d.length; i++){ }} + <div class="order-item"> + <div class="ui-row-flex ui-whitespace item-head" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col ui-col-2 ui-nowrap-flex">订单号:{{d[i].orderNo}}{{d[i].noticeDeliver}} + {{# if(d[i].orderStatus==0 && d[i].noticeDeliver==1){ }} + <span class='notice'><img style='width:0.2rem' src='{{WST.conf.ROOT}}\wstmart\wechat\view\default\img\nocite_deliver.png'>提醒发货</span> + {{# } }} + </div> + <div class="ui-col order-tr o-status"> + {{ d[i].status }} + {{# if($.inArray(d[i].orderStatus,[-1,-3])!=-1){ }} + {{# if(d[i].payType==1 && d[i].isPay==1) { }} + {{# if(d[i].isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }} + </div> + </div> + + {{# for(var g=0;g<d[i].list.length;g++){ }} + <div class="ui-row-flex ui-whitespace border-b" onclick="getOrderDetail({{d[i].orderId}})"> + <div class="ui-col"> + <img src="__ROOT__/{{d[i].list[g].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d[i].list[g].goodsName}}</p> + + {{# if(d[i].list[g].goodsSpecNames){ }} + <p class="o-gSpec ui-nowrap-flex ui-whitespace">规格:{{d[i].list[g].goodsSpecNames}}</p> + {{# } }} + + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d[i].list[g].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d[i].list[g].goodsPrice}}</p><p>x {{d[i].list[g].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# } }} + + + <div style="padding-top:5px;padding-bottom:5px;"> + <div class="o-oListMoney"> + 订单总价:<span>¥ {{d[i].realTotalMoney}}</span> + </div> + {{# if(d[i].orderStatus==-2){ }} + <button class="ui-btn o-btn" onclick="showEditMoneyBox('editOrderMoney({{d[i].orderId}})')"> + 修改价格 + </button> + {{# } }} + + {{# if(d[i].orderStatus==0){ }} + <button class="ui-btn o-btn" onclick="toDeliver({{d[i].orderId}},{{d[i].deliverTypes}})"> + 发货 + </button> + {{# } }} + + {{# if(d[i].payType==1 && WST.blank(d[i].refundId)!=''){ }} + <button class="ui-btn o-btn" onclick="showRefundBox({{d[i].refundId}})"> + 退款操作 + </button> + {{# } }} + {{# if(d[i].isAppraise==1){ }} + <button class="ui-btn o-btn" onclick="toAppr({{d[i].orderId}})"> + 查看评价 + </button> + {{# } }} + <div class="wst-clear"></div> + </div> + </div> + {{# } }} + </script> + + <section class="ui-container" id="shopBox"> + <div class="ui-tab"> + <ul class="ui-tab-nav order-tab"> + <?php $shopMenus = WSTShopOrderMenus();?> + {if (count($shopMenus)==6)} + <li class="tab-item {if $type=='all'}tab-curr{/if}" type="all" >全部</li> + {/if} + {if array_key_exists("waitPay",$shopMenus)} + <li class="tab-item {if $type=='waitPay'}tab-curr{/if}" type="waitPay" >待付款</li> + {/if} + {if array_key_exists("waitDeliver",$shopMenus)} + <li class="tab-item {if $type=='waitDeliver'}tab-curr{/if}" type="waitDeliver" >待发货</li> + {/if} + {if array_key_exists("waitReceive",$shopMenus)} + <li class="tab-item {if $type=='waitReceive'}tab-curr{/if}" type="waitReceive" >待收货</li> + {/if} + {if array_key_exists("waitAppraise",$shopMenus)} + <li class="tab-item {if $type=='waitAppraise'}tab-curr{/if}" type="waitAppraise" >待评价</li> + {/if} + {if array_key_exists("finish",$shopMenus)} + <li class="tab-item {if $type=='finish'}tab-curr{/if}" type="finish" >已完成</li> + {/if} + {if array_key_exists("abnormal",$shopMenus)} + <li class="tab-item {if $type=='abnormal'}tab-curr{/if}" type="abnormal" >取消拒收</li> + {/if} + </ul> + </div> + + <div id="order-box"> + + </div> + + </section> + </div> + +<script type="text/html" id="detailBox"> + <div id="detailBox"> + <div class="detail-head" style="margin-top:0;"> + {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + {{# if(d.payType==1) { }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[-2,0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待付款</p></div> + {{# } }} + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[0,1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>待发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if($.inArray(d.orderStatus,[1,2])!=-1){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已发货</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <span {{# if(d.orderStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.orderStatus==2){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>已收货</p></div> + </div> + </div> + {{# } }} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1 && d.payType==1 && d.isPay==1){ }} + <div class="wst-or-process"> + <div class="ui-row-flex"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>买家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2){ }}class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==1 || d.refundStatus==2 || d.refundStatus==0){ }}active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <span {{# if(d.refundStatus==2) { }} class="active"{{# } }}></span> + <p class="icon"><i class="ui-icon-success-block {{# if(d.refundStatus==2) { }} active{{# } }}"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + {{# } }} + <div class="detail-head" style="margin-top:0;"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单状态:</span> + <span class="o-status">{{d.status}} + {{# if($.inArray(d.orderStatus,[-1,-3])!=-1){ }} + {{# if(d.payType==1 && d.isPay==1) { }} + {{# if(d.isRefund==1) { }} + (已退款) + {{# }else{ }} + (未退款) + {{# } }} + {{# } }} + {{# } }}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单编号:</span>{{d.orderNo}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">下单时间:</span>{{d.createTime}}</div> + </div> + </div> + + + <div class="detail-head"> + {{# if(d.userName){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货人:</span>{{d.userName}} <span class="d-utel">{{d.userPhone}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">收货地址:</span><span class="d-uaddr">{{d.userAddress}}<i></i></span></div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付信息:</span>{{d.payInfo}}</div> + </div> + {{# if(d.payTime){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">支付时间:</span>{{d.payTime}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">配送信息:</span>{{d.deliverInfo}}</div> + </div> + {{# if(WST.blank(d.expressNo)!=''){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递公司:</span>{{d.expressName}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">快递号:</span>{{d.expressNo}}</div> + </div> + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票信息:</span>{{# if(d.isInvoice==1) { }}需要{{# } else{ }}不需要{{# } }}</div> + </div> + {{# if(d.isInvoice==1) { }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票抬头:</span>{{d.invoiceClient}}</div> + </div> + {{# + var inv_json = JSON.parse(d.invoiceJson); + var inv_code = (inv_json!=null && inv_json.invoiceCode!=undefined)?inv_json.invoiceCode:''; + if(inv_json!=null && inv_json.type!=undefined && inv_json.type==0){ + }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">发票税号:</span>{{inv_code}}</div> + </div> + {{# } }} + {{# } }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">订单备注:</span>{{d.orderRemarks}}</div> + </div> + </div> + + {{# if(d.isRefund==1){ }} + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款金额:</span>¥ {{d.backMoney}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款备注:</span>{{d.refundRemark}}</div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe">退款时间:</span>{{d.refundTime}}</div> + </div> + </div> + {{# } }} + + + <div class="detail-head"> + <div class="ui-row-flex o-shops"> + <div class="ui-col ui-col wst-or-term"><p class="shops" onclick="javascript:WST.intoShops({{d.shopId}});"><i></i>{{d.shopName}}<p></div> + </div> + {{# for(var i=0;i<d.goods.length;i++){ }} + <p>商品编号: {{d.goods[i].goodsSn}}</p> + <div class="ui-row-flex ui-whitespace border-b d-goodsitme" onclick="javascript:WST.intoGoods({{d.goods[i].goodsId}})"> + <div class="ui-col"> + <img src="__ROOT__/{{d.goods[i].goodsImg}}" class="o-Img"> + </div> + <div class="ui-col ui-col-3 o-gInfo"> + <p class="o-gName ui-nowrap-multi ui-whitespace">{{d.goods[i].goodsName}}</p> + <p class="o-gSpec d-gSpec"> + {{# if(d.goods[i].goodsSpecNames){ }} + {{d.goods[i].goodsSpecNames.replace(/@@_@@/g,'<br />')}} + {{# } }} + </p> + </div> + <div class="ui-col order-tr" style="word-break:break-all;padding:5px 0;"> + {{# if(d.goods[i].goodsCode=='gift'){ }} + 【赠品】 + {{# }else{ }} + <p>¥ {{d.goods[i].goodsPrice}}</p><p>x {{d.goods[i].goodsNum}}</p> + {{# } }} + </div> + </div> + {{# if(d.goods[i].goodsType==1 && d.orderStatus==2){ }} + {{# for(var e=0;e<d.goods[i].extraJson.length;e++){ }} + <div class="ui-row-flex ui-row-flex-ver d-uInfo"> + <div class="ui-col"> + <p>卡券号:{{d.goods[i].extraJson[e].cardNo}}</p> + <p>卡券密码:{{d.goods[i].extraJson[e].cardPwd}}</p> + </div> + </div> + {{# } }} + {{# } }} + {{# } }} + </div> + + <div class="detail-head"> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">获得积分</span><span class="o-status2">{{d.orderScore}} 个</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">商品总额</span><span class="o-status2">¥ {{d.goodsMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">运费</span><span class="o-status2">¥ {{d.deliverMoney}}</span></div> + </div> + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">积分抵扣金额</span><span class="o-status2">¥ -{{d.scoreMoney}}</span></div> + </div> + {{# if(d.useScore>0){ }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term"><span class="wst-or-describe2">使用积分数</span><span class="o-status2">{{d.useScore}} 个</span></div> + </div> + {{# } }} + {{ d['hook']?d['hook']:"" }} + <div class="ui-row-flex"> + <div class="ui-col ui-col wst-or-term2"><span class="wst-or-describe2">实付款</span><span class="o-status2"><span style="font-size:0.13rem;">¥ </span>{{d.realTotalMoney}}</span></div> + </div> + </div> + </div> +</script> + {/* 遮盖层 */} + <div class="wst-cover" id="cover"></div> + {/* 订单详情层 */} + <div class="wst-fr-box" id="frame"> + <div class="title" id="boxTitle"><span>订单详情</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + + </div> + </div> + {/* 退款层 */} + <div class="wst-fr-box" id="refundFrame"> + <div class="title"><span>申请退款</span><i class="ui-icon-close-page" onclick="javascript:reFundDataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="refund-content"> + <div class="detail-head" style="margin-top:0;"> + <div class="wst-or-process"> + <div class="ui-row-flex" style="padding:10px;border-bottom:RGB(242,242,242) 2px dashed;"> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span class="active"></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>卖家申请退款</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span class="active"></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block active"></i></p> + <div class="wst-clear"></div></p><p>商家申请退款处理</p></div> + <div class="ui-col ui-col process"><p class="line"> + <span></span> + <span></span> + <p class="icon"><i class="ui-icon-success-block"></i></p> + <div class="wst-clear"></div></p><p>退款完成</p></div> + </div> + </div> + <div class="wst-or-refund"> + <p class="term" style="padding: 3px 5px 0 5px;">订单号:<span id="refundOid"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">实付金额:<span id="realTotalMoney"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">退款金额:<span id="refundMoney" class="sign"></span></p> + <p class="term" style="padding: 3px 5px 0 5px;">退款积分:<span id="useScore" class="sign">0</span> 个(积分抵扣<span id="scoreMoney" class="sign">¥ 0</span>)</p> + <p style="padding: 3px 5px 0 5px;">商家意见: + <label><input type='radio' onclick='WST.showHide(0,"#tr")' name='refundStatus' id='refundStatus' value='1' checked/>同意</label> + <label style='margin-left:15px;'><input type='radio' onclick='WST.showHide(1,"#tr")' name='refundStatus' id='refundStatus' value='-1'/>不同意</label> + </p> + <div class="term"> + <div id='tr' style="width:99%;display:none;" > + <span class="sign">*</span>原因 + <textarea id='shopRejectReason' style='width:100%;height:80px;padding: 5px;' maxLength='200'></textarea> + </div> + </div> + <p class="cancel-btn-box ui-flex ui-flex-pack-center"> + <button id="wst-event8" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> + </div> + </div> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{/* 发货 */} +<div class="ui-dialog" id="deliveryBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + 快递公司:<br> + <select id='expressId' style="height:30px;width:100%;"> + {volist name="$express" id="vo"} + <option value='{$vo["expressId"]}'>{$vo["expressName"]}</option> + {/volist} + </select><br> + 快递号:<br> + <input type="text" id="expressNo" style="float: left;height:30px;width:100%;"/> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event0" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> + +{/* 修改价格 */} +<div class="ui-dialog" id="editMoneyBox"> + <div class="ui-dialog-cnt"> + <div class="ui-dialog-bd"> + 新价格:<input type='text' id='newOrderMoney' maxLength='10' style='width:150px;height:30px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event,true)" onblur='javascript:WST.limitDecimal(this,2)'> + + <p class="cancel-btn-box"> + <button id="wst-event1" type="button" class="ui-btn-s wst-dialog-b1" data-role="button">取消</button>&nbsp;&nbsp; + <button id="wst-event3" type="button" class="ui-btn-s wst-dialog-b2">确定</button> + </p> + </div> + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/sellerorders/orders_list.js?v={$v}'></script> +<script> +$(document).ready(function(){ + // 弹出层 + var w = WST.pageWidth(); + $("#frame").css('top',0); + $("#frame").css('right',-w); +}); +</script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/sellerorders/orders_list.js b/hyhproject/wechat2/view/default/users/sellerorders/orders_list.js new file mode 100755 index 0000000..6d8cd23 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/sellerorders/orders_list.js @@ -0,0 +1,285 @@ +jQuery.noConflict(); +// 获取订单列表 +function getOrderList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val(); + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + param.deliverType = -1; + param.payType = -1; + $.post(WST.U('wechat/orders/getSellerOrderList'), param, function(data){ + var json = WST.toJson(data); + if(json.status>0){ + var html = ''; + json = json.data; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('shopList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#order-box').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-order.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关订单</p>'; + html += '</div>'; + $('#order-box').html(html); + } + WST.imgAdapt('j-imgAdapt'); + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }else{ + WST.msg(json.msg,'info'); + } + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + $('#type').val(jQuery("#shopBox li:first").attr("type")); + jQuery("#shopBox li:first").addClass("tab-curr"); + getOrderList(); + WST.initFooter('user'); + // Tab切换卡 + $('.tab-item').click(function(){ + $(this).addClass('tab-curr').siblings().removeClass('tab-curr'); + var type = $(this).attr('type'); + $('#type').val(type); + reFlashList(); + }); + // 弹出层 + $("#frame").css('top',0); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getOrderList(); + } + } + }); +}); + +// 刷新列表页 +function reFlashList(){ + $('#currPage').val('0'); + $('#order-box').html(' '); + getOrderList(); +} + + +// 拒收 +function showEditMoneyBox(event){ + $("#wst-event3").attr("onclick","javascript:"+event); + $("#editMoneyBox").dialog("show"); +} + +function editOrderMoney(oid){ + var newOrderMoney = $('#newOrderMoney').val(); + $.post(WST.U('wechat/orders/editOrderMoney'),{id:oid,orderMoney:newOrderMoney},function(data){ + hideDialog('#editMoneyBox'); + var json = WST.toJson(data); + if(json.status>0){ + $('#newOrderMoney').val(' '); + WST.msg(json.msg,'success'); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +// 退款 +function showRefundBox(id){ + $.post(WST.U('wechat/orders/toShopRefund'),{id:id},function(data){ + var json = WST.toJson(data); + $('#refundOid').html(json.orderNo); + $('#realTotalMoney').html('¥ '+json.realTotalMoney); + $('#refundMoney').html('¥ '+json.backMoney); + $('#useScore').html(json.useScore); + $('#scoreMoney').html('¥ '+json.scoreMoney); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#refund-boxTitle').height();// 弹出层标题高度 + var contentH = $('#refund-content').height(); // 弹出层内容高度 + $('#refund-content').css('height',clientH-boxheadH+'px'); + $("#wst-event8").attr("onclick","javascript:refund("+id+")"); + reFundDataShow(); + }) +} +//弹框 +function reFundDataHide(){ + $('#shopBox').show(); + var dataHeight = $("#refundFrame").css('height'); + var dataWidth = $("#refundFrame").css('width'); + jQuery('#refundFrame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} +function reFundDataShow(){ + jQuery('#cover').attr("onclick","javascript:reFundDataHide();").show(); + jQuery('#refundFrame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) +} +// 退款 +function refund(id){ + + var params = {}; + params.refundStatus = $('#refundStatus')[0].checked?1:-1; + params.content = $.trim($('#shopRejectReason').val()); + params.id = id; + if(params.refundStatus==-1 && params.content==''){ + WST.msg('请输入原因','info'); + return; + } + $.post(WST.U('wechat/orderrefunds/shoprefund'),params,function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg('操作成功','success'); + history.go(0); + }else{ + WST.msg(json.msg,'info'); + } + }); + +} + +// 隐藏对话框 +function hideDialog(id){ + $(id).dialog("hide"); +} + +// 确认收货 +function receive(oid){ + hideDialog('#wst-di-prompt'); + $.post(WST.U('wechat/orders/receive'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + reFlashList();// 刷新列表 + }else{ + WST.msg(json.msg,'info'); + } + }); +} + + + +/*********************** 订单详情 ****************************/ +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); + setTimeout(function(){$('#shopBox').hide();},600) + +} +function dataHide(){ + $('#shopBox').show(); + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} + + + +function getOrderDetail(oid){ + $.post(WST.U('wechat/orders/getDetail'),{id:oid},function(data){ + var json = WST.toJson(data); + if(json.status!=-1){ + var gettpl1 = document.getElementById('detailBox').innerHTML; + laytpl(gettpl1).render(json, function(html){ + $('#content').html(html); + // 弹出层滚动条 + var clientH = WST.pageHeight();// 屏幕高度 + var boxheadH = $('#boxTitle').height();// 弹出层标题高度 + var contentH = $('#content').height(); // 弹出层内容高度 + if((clientH-boxheadH) < contentH){ + $('#content').css('height',clientH-boxheadH+'px'); + } + dataShow(); + }); + }else{ + WST.msg(json.msg,'info'); + } + }); +} +// 跳转到评价页 +function toAppr(oid){ + location.href=WST.U('wechat/orders/orderappraise',{'oId':oid}); +} +// 投诉 +function complain(oid){ + location.href=WST.U('wechat/ordercomplains/complain',{'oId':oid}); +} + +//修改价格 +function editPrice(orderNo){ + alert('修改价格'); +} + +// 发货 +var deliverType +function toDeliver(id,type){ + deliverType = type + if(type==0){ + delivery('orderDelivery('+id+')'); + }else{ + WST.dialog('确定发货吗?','orderDelivery('+id+')'); + } +} +function delivery(event){ + $("#wst-event0").attr("onclick","javascript:"+event); + $("#deliveryBox").dialog("show"); +} +function orderDelivery(oid){ + if(deliverType==0){ + hideDialog('#deliveryBox'); + }else{ + WST.dialogHide('prompt'); + } + $.post(WST.U('wechat/orders/deliver'),{id:oid,expressId:$('#expressId').val(),expressNo:$('#expressNo').val()},function(data){ + var json = WST.toJson(data); + if(json.status>0){ + $('#order-box').html(' '); + reFlashList(); + }else{ + WST.msg(json.msg,'info'); + } + }); +} + +/*************** 修改价格需要用到的方法 ******************/ + + //只能輸入數字和小數點 + WST.isNumberdoteKey = function(evt){ + var e = evt || window.event; + var srcElement = e.srcElement || e.target; + + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && ((charCode < 48 || charCode > 57) && charCode!=46)){ + return false; + }else{ + if(charCode==46){ + var s = srcElement.value; + if(s.length==0 || s.indexOf(".")!=-1){ + return false; + } + } + return true; + } + } + WST.limitDecimal = function(obj,len){ + var s = obj.value; + if(s.indexOf(".")>-1){ + if((s.length - s.indexOf(".")-1)>len){ + obj.value = s.substring(0,s.indexOf(".")+len+1); + } + } + s = null; +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/user.js b/hyhproject/wechat2/view/default/users/user.js new file mode 100755 index 0000000..0497877 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/user.js @@ -0,0 +1,110 @@ +//返回个人信息 +function returnUserinfo(){ + jQuery('#useri_infos').slideDown(); + jQuery('#footer').slideDown(); + jQuery('#useri_nickname').slideUp(); + jQuery("#useri_sex").slideUp(); +} +//修改昵称面板 +function openNickName(){ + jQuery('#useri_infos').slideUp(); + jQuery('#footer').slideUp(); + jQuery('#useri_nickname').slideDown(); +} +//修改昵称 +function editNickName(){ + var userName = $('#userName').val(); + if(userName==''){ + WST.msg('昵称不能为空','info'); + $('#userName').focus(); + return false; + } + $('.nickname_onclick').attr("onclick", "null"); + $.post(WST.U('wechat/users/editUserInfo'), {userName:userName}, function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + WST.msg(json.msg,'success'); + $('#nickname').html(userName); + setTimeout(function(){ + setTimeout(function(){ + $('.nickname_onclick').attr("onclick", "editNickName()"); + },1000); + returnUserinfo(); + },1500); + }else{ + WST.msg('修改昵称失败,请重试','warn'); + setTimeout(function(){ + $('.nickname_onclick').attr("onclick", "editNickName()"); + },1500); + return false; + } + }); +} +//修改性別面板 +function openUserSex(){ + jQuery('#useri_infos').slideUp(); + jQuery('#footer').slideUp(); + jQuery("#useri_sex").slideDown(); +} +//修改性别 +function eidtUserSex(obj, userSex){ + $(obj).children('.wst-list-infose2').html('<i class="ui-icon-checked-s wst-icon-checked-s_se"></i>'); + $(obj).siblings().children('.wst-list-infose2').html(''); + $('.wst-listse').attr("onclick", "null"); + $.post(WST.U('wechat/users/editUserInfo'), {userSex:userSex}, function(data){ + var json = WST.toJson(data); + if(json.status == '1'){ + var newUserSex = ''; + if(userSex==0){ + newUserSex = '保密'; + }else if(userSex==1){ + newUserSex = '男'; + }else if(userSex==2){ + newUserSex = '女'; + } + WST.msg(json.msg,'success'); + $('#usersex').html(newUserSex); + setTimeout(function(){ + returnUserinfo(); + setTimeout(function(){ + $('.wst-listse1').attr("onclick", "eidtUserSex(this, 0)"); + $('.wst-listse2').attr("onclick", "eidtUserSex(this, 1)"); + $('.wst-listse3').attr("onclick", "eidtUserSex(this, 2)"); + },1000); + },1500); + }else{ + WST.msg('修改性别失败,请重试','warn'); + setTimeout(function(){ + $('.wst-listse1').attr("onclick", "eidtUserSex(this, 0)"); + $('.wst-listse2').attr("onclick", "eidtUserSex(this, 1)"); + $('.wst-listse3').attr("onclick", "eidtUserSex(this, 2)"); + },1000); + return false; + } + }); +} +/*签到*/ +function inSign(){ + $("#j-sign").attr('disabled', 'disabled'); + $.post(WST.U('wechat/userscores/signScore'),{},function(data){ + var json = WST.toJson(data); + if(json.status==1){ + $("#j-sign").addClass('sign2') + $("#currentScore").html(json.data.totalScore); + WST.msg(json.msg,'success'); + }else{ + $("#j-sign").removeClass('sign2'); + WST.msg(json.msg,'warn'); + $("#j-sign").removeAttr('disabled'); + } + }); +} +$(document).ready(function(){ + if(WST.conf.IS_LOGIN==0){//是否登录 + WST.inLogin(); + return; + } + WST.initFooter('user'); + WST.imgAdapt('j-imgAdapt'); +}) + diff --git a/hyhproject/wechat2/view/default/users/useraddress/address.js b/hyhproject/wechat2/view/default/users/useraddress/address.js new file mode 100755 index 0000000..abadd49 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/useraddress/address.js @@ -0,0 +1,232 @@ +jQuery.noConflict(); +//新增或编辑收货地址页 +function editAddress(addressId){ + $('#wst-switch').html(''); + $('#username').val(''); + $('#cellphone').val(''); + $('#address_detailed').val(''); + $('#areaId').val(''); + $('#addresst').html('请选择收货地址'); + $('.wst-ad-submit .button').attr('onclick','javascript:saveAddress('+addressId+');'); + if(addressId>0){ + $('.iziModal-header-title').html('修改收货地址'); + $.post(WST.U('wechat/useraddress/getById'), {addressId:addressId}, function(data){ + var info = WST.toJson(data); + if(info){ + $('#username').val(info.userName); + $('#cellphone').val(info.userPhone); + $('#address_detailed').val(info.userAddress); + $('#areaId').val(info.areaId); + if(info.isDefault==1){ + $('#defaults').attr('checked',true); + }else{ + $('#defaults').removeAttr('checked'); + } + $('#addresst').html(info.areaName); + } + addressInfo= null; + }); + }else{ + $('.iziModal-header-title').html('新增收货地址'); + } + jQuery('#modal-large').iziModal('open'); +} +jQuery("#modal-large").iziModal({ + title: "新增收货地址", + subtitle: "", + iconClass: 'icon-chat', + overlayColor: 'rgba(0, 0 0, 0.6)', + headerColor: '#ffffff' +}); +//保存收货地址 +function saveAddress(addressId){ + var userName = $('#username').val(); + var userPhone = $('#cellphone').val(); + var areaId = $('#areaId').val(); + var userAddress = $('#address_detailed').val(); + if( $('#defaults').is(':checked')){ + var isdefaultAddress = 1;//设为默认地址 + }else{ + var isdefaultAddress = 0;//不设为默认地址 + } + if(userName==''){ + WST.msg('收货人名称不能为空','info'); + return false; + } + if(userPhone==''){ + WST.msg('联系电话不能为空','info'); + return false; + } + if(areaId==''){ + WST.msg('请选择地址','info'); + return false; + } + if(userAddress==''){ + WST.msg('请填写详细地址','info'); + return false; + } + var param = {}; + param.addressId = addressId; + param.userName = userName; + param.areaId = areaId; + param.userPhone = userPhone; + param.userAddress = userAddress; + param.isDefault = isdefaultAddress; + $('.wst-ad-submit .button').addClass("active").attr('disabled', 'disabled'); + $.post(WST.U('wechat/useraddress/edits'), param, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + var type = $('#type').val(); + var id = $('#addressId2').val(); + if(param.addressId==0 && type==1)var addId = json.data.addressId; + setTimeout(function(){ + if(param.addressId==0 && type==1){ + chooseAddress(addId); + }else{ + location.href = WST.U('wechat/useraddress/index','type='+type+'&addressId='+id); + } + },1500); + }else{ + WST.msg(json.msg,'warn'); + setTimeout(function(){ + $('.wst-ad-submit .button').removeAttr('disabled').removeClass("active"); + },1500); + } + data = json = null; + }); +} +//设为默认地址 +function inDefault(obj,id){ + $(obj).addClass('default').removeClass('nodefault').siblings('.j-operate').addClass('nodefault').removeClass('default'); + $('.wst-ad-operate').css('position','relative'); + $.post(WST.U('wechat/useraddress/setDefault'), {id:id}, function(data){ + var json = WST.toJson(data); + if( json.status == 1 ){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + location.href = WST.U('wechat/useraddress/index'); + },1500); + }else{ + WST.msg(json.msg,'warn'); + $('.wst-ad-operate').css('position','static'); + } + data = json = null; + }); +} +function setToDefault(obj){ + if( $(obj).is(':checked')){ + $('#defaults').removeAttr('checked'); + }else{ + $('#defaults').attr('checked',true); + } +} +//删除收货地址 +function delAddress(addressId){ + WST.dialog('确定删除吗?','toDelAddress('+addressId+')'); +} +//删除收货地址 +function toDelAddress(addressId){ + $.post(WST.U('wechat/useraddress/del'), {id:addressId}, function(data){ + var json = WST.toJson(data); + if(json.status==1){ + WST.msg(json.msg,'success'); + setTimeout(function(){ + var type = $('#type').val(); + var id = $('#addressId2').val(); + location.href = WST.U('wechat/useraddress/index','type='+type+'&addressId='+id); + },2000); + }else{ + WST.msg(json.msg,'warn'); + } + WST.dialogHide('prompt'); + data = json = null; + }); +} +//地址选择 +function inOption(obj,n){ + $(obj).addClass('active').siblings().removeClass('active'); + $('.area_'+n).removeClass('hide').siblings('.list').addClass('hide'); + var level = $('#level').val(); + var n = n+1; + for(var i=n; i<=level; i++){ + $('.area_'+i).remove(); + $('.active_'+i).remove(); + } +} +function inChoice(obj,id,val,level){ + $('#level').val((level+1)); + $(obj).addClass('active').siblings().removeClass('active'); + $('#'+id).attr('areaId',val); + $('.active_'+level).removeClass('active').html($(obj).html()); + WST.ITAreas({id:id,val:val,className:'j-areas'}); +} +/** + * 循环创建地区 + * @param id 当前分类ID + * @param val 当前分类值 + * @param className 样式,方便将来获取值 + */ +WST.ITAreas = function(opts){ + opts.className = opts.className?opts.className:"j-areas"; + var obj = $('#'+opts.id); + obj.attr('lastarea',1); + $.post(WST.U('wechat/areas/listQuery'),{parentId:opts.val},function(data,textStatus){ + var json = WST.toJson(data); + if(json.data && json.data.length>0){ + json = json.data; + var html = [],tmp; + var tid = opts.id+"_"+opts.val; + var level = parseInt(obj.attr('level'),10); + $('.area_'+level).addClass('hide'); + var level = level+1; + html.push('<div id="'+tid+'" class="list '+opts.className+' area_'+level+'" areaId="0" level="'+level+'">'); + for(var i=0;i<json.length;i++){ + tmp = json[i]; + html.push("<p onclick='javascript:inChoice(this,\""+tid+"\","+tmp.areaId+","+level+");'>"+tmp.areaName+"</p>"); + } + html.push('</div>'); + $(html.join('')).insertAfter('#'+opts.id); + var h = WST.pageHeight(); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); + $(".wst-fr-box .option").append('<p class="ui-nowrap-flex term active_'+level+' active" onclick="javascript:inOption(this,'+level+')">请选择</p>'); + }else{ + opts.isLast = true; + opts.lastVal = opts.val; + $('#areaId').val(opts.lastVal); + var ht = ''; + $('.wst-fr-box .term').each(function(){ + ht += $(this).html(); + }); + $('#addresst').html(ht); + dataHide(); + } + }); +} +function chooseAddress(id){ + location.href = WST.U('wechat/carts/settlement','addressId='+id); +} +$(document).ready(function(){ + WST.initFooter('user'); + // 弹出层 + $('#modal-large').css({'top':0,'margin-top':0}); + var h = WST.pageHeight(); + $("#frame").css('bottom','-'+h/2); + var listh = h/2-106; + $(".wst-fr-box .list").css('overflow-y','scroll').css('height',listh+'px'); +}); +//弹框 +function dataShow(){ + jQuery('#frame').show(); + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"bottom": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + jQuery('#frame').animate({'bottom': '-'+dataHeight}, 500); + jQuery('#cover').hide(); + setTimeout(function(){ + jQuery('#frame').hide(); + },500); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/useraddress/edit.html b/hyhproject/wechat2/view/default/users/useraddress/edit.html new file mode 100755 index 0000000..8cf32c8 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/useraddress/edit.html @@ -0,0 +1,49 @@ + <div id="modal-large" class="iziModal"> + <input type="hidden" name="" value="" id="areaId" autocomplete="off"> + <div class="wst-ad-form"> + <div class="ui-form-itemin"> + <label class="word">收货人:</label><input class="ui-border-binte" id="username" type="text" placeholder="请填写收货人"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">联系电话:</label><input class="ui-border-binte" id="cellphone" type="text" placeholder="请填写联系电话" onkeypress='return WST.isNumberKey(event);' onkeyup="javascript:WST.isChinese(this,1)"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">收货地址:</label> + <div id="addresst" class="ui-nowrap-flex address" onclick="javascript:dataShow();">请选择收货地址</div> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form-itemin"> + <label class="word">详细地址:</label><input class="ui-border-binte" id="address_detailed" type="text" placeholder="请填写详细地址"> + </div> + <div class="wst-ad-line"><p></p></div> + <div class="ui-form"> + <div class="ui-form-item ui-form-item-switch wst-ad-operate"> + <p>设为默认地址</p> + <label class="ui-switch"> + <input type="checkbox" id="defaults" onclick="javascript:setToDefault(this)"> + </label> + </div> + </div> + </div> + <div class="wst-ad-submit"><button class="ui-btn-lg button" onclick="javascript:saveAddress(0);">保存</button></div> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 地址框 */} +<div class="wst-fr-box" id="frame" style="display:none;"> + <input type="hidden" name="" value="" id="level" autocomplete="off"> + <div class="title"><span>收货地址</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + <div class="option"> + <p class="ui-nowrap-flex term active_0 active" onclick="javascript:inOption(this,0)">请选择</p> + </div> + <div class="wst-clear"></div> + <div id="area_0" class="list j-areas area_0" areaId="0" level="0"> + {volist name="area" id="ar"} + <p onclick="javascript:inChoice(this,'area_0',{$ar['areaId']},0);">{$ar['areaName']}</p> + {/volist} + </div> + </div> +</div> + </div> \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/useraddress/list.html b/hyhproject/wechat2/view/default/users/useraddress/list.html new file mode 100755 index 0000000..85dba05 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/useraddress/list.html @@ -0,0 +1,56 @@ +{extend name="default/base" /} +{block name="title"}收货地址管理 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/iziModal.css?v={$v}"> +<link rel="stylesheet" href="__WECHAT__/css/address.css?v={$v}"> +{/block} +{block name="header"} + <header style="background:#ffffff;" class="ui-header ui-header-positive ui-border-b wst-header"> + <i class="ui-icon-return" {if($type==1)}onclick="javascript:chooseAddress({$addressId});"{else}onclick="history.back();"{/if}></i><h1>我的地址</h1> + </header> +{/block} +{block name="footer"} + <div class="wst-ad-footer"><button class="button" onclick="javascript:editAddress(0);">新增</button></div> +{/block} +{block name="main"} + <input type="hidden" name="" value="{$type}" id="type" autocomplete="off"> + <input type="hidden" name="" value="{$addressId}" id="addressId2" autocomplete="off"> + <section class="ui-container" id="address"> + {volist name="list" id="li"} + <ul class="ui-list wst-listse"> + <li {if($type==1)}onclick="javascript:chooseAddress({$li['addressId']});"{/if}> + <div class="wst-list-infose1"> + <span class="name">{$li['userName']}&nbsp;&nbsp;{$li['userPhone']}</span> + <span class="address">{$li['areaName']}-{$li['userAddress']}</span> + </div> + </li> + <div class="wst-ad-operate"> + {if($type!=1)}<span class="left">设为默认</span>{/if} + <span class="right" onclick="javascript:delAddress({$li['addressId']});"><i class="delete"></i>&nbsp;删除</span> + <span class="right" onclick="javascript:editAddress({$li['addressId']});"><i class="edit"></i>&nbsp;编辑</span> + <div class="wst-clear"></div> + </div> + </ul> + {if($type==1)} + <i class="j-operate {if($addressId==$li['addressId'])}default{else}nodefault{/if}"></i> + {else} + <i class="j-operate {if($li['isDefault']==1)}default{else}nodefault{/if}" onclick="javascript:inDefault(this,{$li['addressId']});"></i> + {/if} + {/volist} + {empty name="list"} + <div class="wst-prompt-icon"><img src="__WECHAT__/img/nothing-address.png"></div> + <div class="wst-prompt-info"> + <p>没有收货地址</p> + </div> + {/empty} + </section> +{/block} +{block name="include"} +{include file="default/dialog" /}<!-- 对话框模板 --> +{include file="default/users/useraddress/edit" /}<!-- 新增/编辑收货地址模板 --> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/js/izimodal/iziModal.js'></script> +<script type='text/javascript' src='__WECHAT__/users/useraddress/address.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/userscores/list.html b/hyhproject/wechat2/view/default/users/userscores/list.html new file mode 100755 index 0000000..32ae722 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/userscores/list.html @@ -0,0 +1,49 @@ +{extend name="default/base" /} +{block name="title"}我的积分 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/userscores.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "我的积分"{/php} + {include file="default/header" /} +{/block} +{block name="main"} + <input type="hidden" name="" value="" id="currPage" autocomplete="off"> + <input type="hidden" name="" value="" id="totalPage" autocomplete="off"> + <section class="ui-container"> + <div class="ui-row-flex ui-whitespace ui-row-flex-ver head"> + <div class="user_scores"> + <p>我的积分</p> + <p id="userMoney" >{$object['userScore']}<span> 个</span></p> + </div> + </div> + <script type="text/html" id="scoreList"> + <ul class="ui-row score-detail"> + {{# for(var i=0;i<d.length;i++){ }} + <li class="ui-col ui-col-75 wst-re-info"> + <p>{{d[i].dataRemarks}}</p> + <span class="score-time">{{d[i].createTime}}</span> + </li> + <li class="ui-col ui-col-25 {{(d[i].scoreType==1)?'score-plus':'score-reduce'}}">{{(d[i].scoreType==1)?'+':'-'}} {{d[i].score}}</li> + <div class="wst-clear"></div> + <div class="score-line"></div> + {{# } }} + </ul> + </script> + <li class="score-detail-title">积分明细</li> + <div id="score-list"></div> + </section> +{/* 遮盖层 */} +<div class="wst-cover" id="cover"></div> +{/* 分类层 */} +<div class="wst-fr-box" id="frame"> + <div class="title"><span>积分使用规则</span><i class="ui-icon-close-page" onclick="javascript:dataHide();"></i><div class="wst-clear"></div></div> + <div class="content" id="content"> + 积分使用规则 + </div> +</div> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/js/jquery.min.js'></script> +<script type='text/javascript' src='__WECHAT__/users/userscores/userscores.js?v={$v}'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/userscores/userscores.js b/hyhproject/wechat2/view/default/users/userscores/userscores.js new file mode 100755 index 0000000..7896220 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/userscores/userscores.js @@ -0,0 +1,67 @@ +jQuery.noConflict(); +// 获取订单列表 +function getScoreList(){ + $('#Load').show(); + loading = true; + var param = {}; + param.type = $('#type').val() || -1; + param.pagesize = 10; + param.page = Number( $('#currPage').val() ) + 1; + $.post(WST.U('wechat/userscores/pageQuery'), param, function(data){ + var json = WST.toJson(data.data); + var html = ''; + if(json && json.Rows && json.Rows.length>0){ + var gettpl = document.getElementById('scoreList').innerHTML; + laytpl(gettpl).render(json.Rows, function(html){ + $('#score-list').append(html); + }); + + $('#currPage').val(json.CurrentPage); + $('#totalPage').val(json.TotalPage); + }else{ + html += '<div class="wst-prompt-icon"><img src="'+ window.conf.WECHAT +'/img/nothing-relevant.png"></div>'; + html += '<div class="wst-prompt-info">'; + html += '<p>暂无相关信息</p>'; + html += '</div>'; + $('#score-list').html(html); + } + loading = false; + $('#Load').hide(); + echo.init();//图片懒加载 + }); +} +var currPage = totalPage = 0; +var loading = false; +$(document).ready(function(){ + getScoreList(); + WST.initFooter('user'); + // 弹出层 + var w = WST.pageWidth(); + var h = WST.pageHeight(); + $('#frame .content').css('overflow-y','scroll').css('height',h-48); + $("#frame").css('right',-w); + + $(window).scroll(function(){ + if (loading) return; + if ((5 + $(window).scrollTop()) >= ($(document).height() - screen.height)) { + currPage = Number( $('#currPage').val() ); + totalPage = Number( $('#totalPage').val() ); + if( totalPage > 0 && currPage < totalPage ){ + getScoreList(); + } + } + }); +}); + + +//弹框 +function dataShow(){ + jQuery('#cover').attr("onclick","javascript:dataHide();").show(); + jQuery('#frame').animate({"right": 0}, 500); +} +function dataHide(){ + var dataHeight = $("#frame").css('height'); + var dataWidth = $("#frame").css('width'); + jQuery('#frame').animate({'right': '-'+dataWidth}, 500); + jQuery('#cover').hide(); +} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/userset/about.html b/hyhproject/wechat2/view/default/users/userset/about.html new file mode 100755 index 0000000..72b9782 --- /dev/null +++ b/hyhproject/wechat2/view/default/users/userset/about.html @@ -0,0 +1,41 @@ +{extend name="default/base" /} +{block name="title"}关于我们 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/userset.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "关于我们"{/php} + {include file="default/header" /} +{/block} +{block name="footer"}{/block} +{block name="main"} + <section class="ui-container"> + <div class="wst-about"> + <div class="wst-brand" ><img src="__ROOT__/{:WSTConf('CONF.mallLogo')}"></div> + <p>{:WSTConf('CONF.seoMallTitle')}</p> + <div class="wst-version"> + <div class="wst-border"> + </div> + </div> + </div> + <div class="wst-about" > + <ul class="ui-list ui-list-text wst-contact" style="background: transparent;"> + <li class="line"> + <span class="phone"></span><h5>联系电话:{:WSTConf('CONF.serviceTel')}</h5> + </li> + <li class="line"> + <span class="qq"></span><h5>客服QQ:{:WSTConf('CONF.serviceQQ')}</h5> + </li> + <li class="line"> + <span class="email"></span><h5>联系邮箱:{:WSTConf('CONF.serviceEmail')}</h5> + </li> + <li class="line"> + <span class="belong"></span><h5>版权所有:{:WSTConf('CONF.seoMallTitle')}</h5> + </li> + </ul> + </div> + </section> +{/block} +{block name="js"} +<script type='text/javascript' src='__WECHAT__/users/userset/userset.js'></script> +{/block} \ No newline at end of file diff --git a/hyhproject/wechat2/view/default/users/userset/list.html b/hyhproject/wechat2/view/default/users/userset/list.html new file mode 100755 index 0000000..57b942f --- /dev/null +++ b/hyhproject/wechat2/view/default/users/userset/list.html @@ -0,0 +1,28 @@ +{extend name="default/base" /} +{block name="title"}用户设置 - {__block__}{/block} +{block name="css"} +<link rel="stylesheet" href="__WECHAT__/css/userset.css?v={$v}"> +{/block} +{block name="header"} + {php}$Title = "用户设置"{/php} + {include file="default/header" /} +{/block} +{block name="footer"}{/block} +{block name="main"} + <section class="ui-container"> + <ul class="ui-list ui-list-text ui-list-link wst-se-l"> + <li class="line" onclick="location.href='{:url('wechat/users/edit')}'"> + <span class="pay"></span><h5 class="ui-nowrap">个人中心</h5></a> + </li> + <li class="line" onclick="location.href='{:url('wechat/users/security')}'"> + <span class="safety"></span><h5 class="ui-nowrap">账户安全</h5></a> + </li> + <li class="line" onclick="location.href='{:url('wechat/users/aboutus')}'"> + <span class="about"></span><h5 class="ui-nowrap">关于我们</h5> + </li> + </ul> + </section> +{/block} +{block name="include"} + {include file="default/dialog" /}<!-- 对话框模板 --> +{/block} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100755 index 0000000..c9f1e2c --- /dev/null +++ b/index.html @@ -0,0 +1,40 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8"> + <title>恭喜,站点创建成功!</title> + <style> + .container { + width: 60%; + margin: 10% auto 0; + background-color: #f0f0f0; + padding: 2% 5%; + border-radius: 10px + } + + ul { + padding-left: 20px; + } + + ul li { + line-height: 2.3 + } + + a { + color: #20a53a + } + </style> +</head> +<body> + <div class="container"> + <h1>恭喜, 站点创建成功!</h1> + <h3>这是默认index.html,本页面由系统自动生成</h3> + <ul> + <li>本页面在FTP根目录下的index.html</li> + <li>您可以修改、删除或覆盖本页面</li> + <li>FTP相关信息,请到“面板系统后台 > FTP” 查看</li> + <li>更多功能了解,请查看<a href="https://www.bt.cn" target="_blank">宝塔官网(www.bt.cn)</a></li> + </ul> + </div> +</body> +</html> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100755 index 0000000..f1b17bf --- /dev/null +++ b/index.php @@ -0,0 +1,189 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- +// 检测PHP环境 +if(version_compare(PHP_VERSION,'5.4.0','<')) die('require PHP > 5.4.0 !'); +//进入安装目录 +if(is_dir("install") && !file_exists("install/install.ok")){ + header("Location:install/index.php"); + exit(); +} +// function doHttpPost($url, $data){ + + +// $data_string = json_encode($data); + +// $result = file_get_contents($url, null, stream_context_create(array( +// 'http' => array( +// 'method' => 'POST', +// 'header' => 'Content-Type: application/json' . "\r\n" +// . 'Content-Length: ' . strlen($data_string) . "\r\n", +// 'content' => $data_string, +// ), +// ))); +// return $result; + +// // $ch = curl_init(); +// // $this_header = array( +// // "content-type: application/json;" +// // ); +// // curl_setopt($ch,CURLOPT_HTTPHEADER,$this_header); +// // curl_setopt($ch, CURLOPT_URL, $url); +// // curl_setopt($ch, CURLOPT_POST, true); +// // curl_setopt($ch, CURLOPT_POSTFIELDS, $data); +// // curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +// // curl_setopt($ch, CURLOPT_TIMEOUT, 120); +// // $output = curl_exec($ch); +// // curl_close($ch); +// // return $output; +// } + +// function curl_request($url,$post='',$cookie='', $returnCookie=0){ +// $curl = curl_init(); + +// curl_setopt($curl, CURLOPT_URL, $url); +// $this_header = array( +// "content-type: application/json;" +// ); +// curl_setopt($curl,CURLOPT_HTTPHEADER,$this_header); +// curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'); +// curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); +// curl_setopt($curl, CURLOPT_AUTOREFERER, 1); +// curl_setopt($curl, CURLOPT_REFERER, "http://XXX"); +// if($post) { +// curl_setopt($curl, CURLOPT_POST, 1); +// curl_setopt($curl, CURLOPT_POSTFIELDS, $post); +// } +// if($cookie) { +// curl_setopt($curl, CURLOPT_COOKIE, $cookie); +// } +// curl_setopt($curl, CURLOPT_HEADER, $returnCookie); +// curl_setopt($curl, CURLOPT_TIMEOUT, 10); +// curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); +// $data = curl_exec($curl); +// if (curl_errno($curl)) { +// return curl_error($curl); +// } +// curl_close($curl); +// if($returnCookie){ +// list($header, $body) = explode("\r\n\r\n", $data, 2); +// preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches); +// $info['cookie'] = substr($matches[1][0], 1); +// $info['content'] = $body; +// return $info; +// }else{ +// return $data; +// } +// } +// function doHttpPostPayload($url, $data){ + + +// $data_string = json_encode($data); + +// //return $data_string; + +// $ch = curl_init($url); + +// $headers = array(); +// $headers[] = 'Accept: application/json, text/plain, */*'; +// $headers[] = 'Accept-Encoding: gzip, deflate'; +// $headers[] = 'Accept-Language: zzh-CN,zh;q=0.9'; +// $headers[] = 'Connection: keep-alive'; +// $headers[] = 'Host: explorer.moac.io'; +// $headers[] = 'Origin: explorer.moac.io'; +// $headers[] = 'Referer: http://explorer.moac.io/token/0x4c7e99ee6fa3103bfd7f44d3d196fcbf52af988e'; +// $headers[] = 'Content-Type: application/json; charset=utf-8'; +// $headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'; + + + + +// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); +// curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); +// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +// curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); +// curl_setopt($ch, CURLOPT_TIMEOUT, 5); +// curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); + +// //execute post +// $response = curl_exec($ch); + +// //close connection +// curl_close($ch); + +// return $response; +// // $curl = curl_init(); +// // curl_setopt_array($curl, array( +// // CURLOPT_HTTPHEADER => array("application/json;charset=UTF-8"), +// // CURLOPT_URL => $url, +// // CURLOPT_RETURNTRANSFER => true, +// // CURLOPT_POST=>true, +// // CURLOPT_ENCODING => "", +// // CURLOPT_MAXREDIRS => 10, +// // CURLOPT_TIMEOUT => 30, +// // CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, +// // CURLOPT_CUSTOMREQUEST => "POST", +// // CURLOPT_POSTFIELDS => $data)); + +// // $response = curl_exec($curl); +// // $err = curl_error($curl); + +// // curl_close($curl); +// // return $err; +// } + +// $post_data = array('action' => 'tokenTransfer', 'address' => '0x4c7e99ee6fa3103bfd7f44d3d196fcbf52af988e', 'lastId' => '0', 'pageNum' => '1', 'pageSize' => '20'); +// $url = 'http://explorer.moac.io/tokenrelay'; +// //$post_data=json_encode($post_data); +// $result = curl_request($url, json_encode($post_data));//'action="tokenTransfer"&address="0x4c7e99ee6fa3103bfd7f44d3d196fcbf52af988e"&pageNum=2&pageSize=20');//&pageNum=1&pageSize=10 + +// var_dump($result);die; +// // $url = 'http://explorer.moac.io/transfer'; +// // $post_data = array('draw' => '1', 'search[regex]' => 'False', 'addr' => '0x86fef829fe299ce684a185ee87b1c754f6a99ab7'); +// // $result = doHttpPost($url, 'draw=1&search[regex]=False&addr=0x86fef829fe299ce684a185ee87b1c754f6a99ab7&start=0&length=10');//&start=0&length=20 + +// // $result=json_decode($result); +// // //var_dump($result);die; +// // echo '<pre />'; +// // $block_data=[]; +// // //0:交易哈希 1、时间戳 2、区块号 3、发送人地址 4、接收人地址 5、代币数量 6、代币名称 7、代币合约地址 +// // foreach ($result->data as $key=>$val) { + +// // $block_data[$key]['transfer_hash']=$val['0']; +// // $block_data[$key]['create_time']=date('Y-m-d H:i:s',$val['1']); +// // $block_data[$key]['block_num']=$val['2']; +// // $block_data[$key]['from_account']=$val['3']; +// // $block_data[$key]['to_account']=$val['4']; +// // $block_data[$key]['transfer_num']=$val['5']; +// // $block_data[$key]['coin_name']=$val['6']; + +// // } +// //var_dump($block_data); + + + + + + + + + +// die; +// [ 应用入口文件 ] +// 定义应用目录 +define('APP_NAMESPACE','wstmart'); +define('APP_PATH', __DIR__ . '/hyhproject/'); +define('CONF_PATH', __DIR__.'/hyhproject/common/conf/'); +define('WST_COMM', __DIR__.'/hyhproject/common/common/'); +define('WST_HOME_COMM', __DIR__.'/hyhproject/home/common/'); +define('WST_ADMIN_COMM', __DIR__.'/hyhproject/admin/common/'); +define('WST_WECHAT_COMM', __DIR__.'/hyhproject/wechat/common/'); +// 加载框架引导文件 +require __DIR__ . '/thinkphp/start.php'; diff --git a/mobile/orange/.project b/mobile/orange/.project new file mode 100755 index 0000000..911c765 --- /dev/null +++ b/mobile/orange/.project @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>orange</name> + <comment>Create By HBuilder</comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>com.aptana.ide.core.unifiedBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>com.aptana.projects.webnature</nature> + </natures> + <filteredResources> + <filter> + <id>1532485796734</id> + <name></name> + <type>10</type> + <matcher> + <id>org.eclipse.ui.ide.orFilterMatcher</id> + <arguments> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-projectRelativePath-matches-false-false-bin</arguments> + </matcher> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-projectRelativePath-matches-false-false-setting</arguments> + </matcher> + </arguments> + </matcher> + </filter> + </filteredResources> +</projectDescription> diff --git a/mobile/orange/css/global.css b/mobile/orange/css/global.css new file mode 100755 index 0000000..aa0c42b --- /dev/null +++ b/mobile/orange/css/global.css @@ -0,0 +1,54 @@ +@charset "utf-8"; +/* CSS Document */ + + +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form, +fieldset,input,textarea,p,blockquote,th,td { + margin:0; + padding:0; + +} +body{ + font-family: "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Hiragino Sans GB W3", "WenQuanYi Micro Hei", "Microsoft YaHei UI", "Microsoft YaHei", sans-serif; +} +table { + border-collapse:collapse; /*让表格边框细线*/ + border-spacing:0; /*清除边框间距*/ +} +fieldset,img { + border:0 none; /*有些浏览器默认这些标签有边框,所以要清除默认边框*/ + display:block; +} +address,caption,cite,code,dfn,em,i,u,b,strong,th,var { + font-style:normal; + font-weight:normal; + /*清除标签默认文本样式和加粗*/ +} +input,textarea{ + outline:0 none;/*去掉文本框的默认轮廓线*/ +} +ol,ul { + list-style:none; /*清除列表默认样式*/ +} +caption,th { + text-align:left; /*清除标签默认文本居中对齐*/ +} +h1,h2,h3,h4,h5,h6 { + font-size:100%; + font-weight:normal; /*清除标题标签的默认样式*/ +} +a{ + text-decoration:none;/*大部分页面中的链接没有下划线*/ +} + +.clearfix:after{ + height:0; + content:" "; + display:block; + overflow:hidden; + clear:both; + } +.clearfix{ + zoom:1;/*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + diff --git a/mobile/orange/css/orange.css b/mobile/orange/css/orange.css new file mode 100755 index 0000000..53092f5 --- /dev/null +++ b/mobile/orange/css/orange.css @@ -0,0 +1,43 @@ +body{ + background: #fff; +} + +.bg{ + width: 100%; + position: relative; +} + +.bg img{ + width: 100%; +} +.ios,.an{ + width: 45%; + height: 45px; + border: 2px solid #fff; + position: absolute; + left: 0; + right: 0; + margin: 0 auto; + bottom: 20%; + border-radius: 10px; +} + +.ios img,.an img{ + width:35px; + height: 35px; + margin-left: 4%; + margin-top: 1.5%; + float: left; +} +.an{ + position: absolute; + bottom: 12%; +} + +.bg p{ + font-family: "微软雅黑"; + font-size:20px; + text-align: center; + line-height: 45px; + color: #fff; +} diff --git a/mobile/orange/img/an.png b/mobile/orange/img/an.png new file mode 100755 index 0000000..7bb6335 Binary files /dev/null and b/mobile/orange/img/an.png differ diff --git a/mobile/orange/img/ios.png b/mobile/orange/img/ios.png new file mode 100755 index 0000000..5ea0992 Binary files /dev/null and b/mobile/orange/img/ios.png differ diff --git a/mobile/orange/img/or_bg.gif b/mobile/orange/img/or_bg.gif new file mode 100755 index 0000000..1f9eff2 Binary files /dev/null and b/mobile/orange/img/or_bg.gif differ diff --git a/mobile/orange/img/or_bg.png b/mobile/orange/img/or_bg.png new file mode 100755 index 0000000..85a344b Binary files /dev/null and b/mobile/orange/img/or_bg.png differ diff --git a/mobile/orange/index.html b/mobile/orange/index.html new file mode 100755 index 0000000..7c65f27 --- /dev/null +++ b/mobile/orange/index.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> + + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> + <title>orange</title> + <link rel="stylesheet" type="text/css" href="css/global.css" /> + <link rel="stylesheet" type="text/css" href="css/orange.css" /> + </head> + + <body> + <div class="bg"> + <img src="img/or_bg.gif" /> + <div class="ios"> + <img src="img/ios.png" /> + <p>ios下载</p> + </div> + <div class="an"> + <img src="img/an.png" /> + <p>Android下载</p> + </div> + </div> + </body> +<script src="js/jquery-3.2.1.min.js" type="text/javascript" charset="utf-8"></script> +<script type="text/javascript"> + $('.ios').click(function(){ + location.href ='https://itunes.apple.com/cn/app/%E5%90%88%E6%BA%90%E6%83%A0%E5%95%86%E5%9F%8E/id1355322179'; + }) + $('.an').click(function(){ + location.href ='http://android.myapp.com/myapp/detail.htm?apkName=heyuanhui.shop'; + }) +</script> +</html> \ No newline at end of file diff --git a/mobile/orange/js/jquery-3.2.1.min.js b/mobile/orange/js/jquery-3.2.1.min.js new file mode 100755 index 0000000..644d35e --- /dev/null +++ b/mobile/orange/js/jquery-3.2.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/mobile/reg/css/applicationopen.css b/mobile/reg/css/applicationopen.css new file mode 100755 index 0000000..0f39c55 --- /dev/null +++ b/mobile/reg/css/applicationopen.css @@ -0,0 +1,161 @@ +.con-nav { + /* width: 100%; */ + height: 40px; +} + +.con-nav ul { + width: 100%; + height: 100%; + list-style: none; + /* padding: 0px; */ + margin: 10px 2px; + /* display: flex; + justify-content: space-between; + align-items: center; */ + padding: 5px 1px; + /* overflow-x: scroll; */ +} + +.con-nav ul li { + padding: 0px 20px; + line-height: 40px; + background: #999999; + display: inline-block; + color: #fff; + float: left; + margin: 0px -16px 0px 0px; + position: relative; + font-size: 10px; + /* text-align: center; */ + width: 28%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + +} + +.con-nav ul li:after { + content: ''; + width: 0px; + height: 0px; + display: block; + border: 20px solid transparent; + /* border-bottom: 20px solid transparent; */ + border-left: 20px solid #999999; + position: absolute; + right: -21px; + top: 0; + z-index: 10; +} + +.con-nav ul li:before { + content: ''; + display: block; + border: 20px solid transparent; + width: 0px; + height: 0px; + /* border-top: 20px solid transparent; + border-bottom: 20px solid transparent; */ + border-left: 20px solid #fff; + position: absolute; + left: 0px; + top: 0; + right: -20px; + +} + +.con-nav ul li:first-child { + border-radius: 4px 0 0 4px; + padding-left: 10px; +} + +.con-nav ul li:last-child, +.cssNavEnd { + border-radius: 0px 4px 4px 0px; + padding-right: 10px; +} + +.con-nav ul li:first-child:before { + display: none; +} + +.con-nav ul li:last-child:after, +.cssNavEnd:after { + display: none; +} + +.con-nav ul li.active { + background-color: #ef72b6; + /* width: 120px; */ +} + +.con-nav ul li.active:after { + border-left-color: #ef72b6; +} + +.con-content { + margin-top: 20px; +} + +.storepos label { + align-items: flex-start; +} + +.num .areainp { + height: 80px; +} + +#allmap { + flex: 0 0 80%; + height: 200px; + /* z-index: 0; */ +} + +.num .renzhengphoto .photos .photo { + width: 100px; +} + +.num .renzhengphoto .photos .photo img { + width: 100%; + +} + +.confirmationtext { + /* height: 200px; */ + width: 98%; + margin: 0 auto; + /* overflow: hidden; */ +} + +.confirmationtext .confirmationtext_con { + height: 200px; + width: 98%; + margin: 0 auto; + overflow-y: scroll; +} + +.oper { + display: flex; + width: 100%; + justify-content: center; + align-items: center; +} + +.oper .next { + width: 50%; +} + +.pre { + width: 50%; +} + +.pre_btn { + height: 30px; + line-height: 30px; + text-align: center; + width: 70%; + margin: 30px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} diff --git a/mobile/reg/css/global.css b/mobile/reg/css/global.css new file mode 100755 index 0000000..ef7949f --- /dev/null +++ b/mobile/reg/css/global.css @@ -0,0 +1,143 @@ +.clearfix:after { + height: 0; + content: " "; + display: block; + overflow: hidden; + clear: both; +} + +.clearfix { + zoom: 1; + /*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + +a { + color: black; +} + +a:active { + color: white; +} + +p { + margin: 0; +} + +input { + margin: 0; +} + +img {} + +.scroll_out { + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out1 { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out2 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out3 { + position: fixed; + top: 162px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out4 { + position: fixed; + top: 120px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out_tb { + position: fixed; + top: 64px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out_t { + position: fixed; + top: 64px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +body { + font-family: "微软雅黑"; +} + +.shadown_wai { + box-shadow: 2px 2px 5px rgba(25, 25, 25, 0.2); + border-radius: 5px; + /*overflow: hidden;*/ + border-top: 1px solid #EFEFF4; + margin-bottom: 1px; +} + +.pect { + color: #fff; + font-size: 10px; + position: absolute; + background: -moz-linear-gradient(left, #6600ff, #a200ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#6600ff), to(#a200ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #6600ff, #a200ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #6600ff, #a200ff); + /*Opera11*/ + border-radius: 3px; + padding: 0px 2px; + top: 65px; + right: calc(100% - 220px); +} + +.hide { + display: none; +} + +.backTop { + background: #DDDDDD; + border-radius: 50%; + position: fixed; + right: 10px; + bottom: 15px; + width: 38px; + height: 38px; + z-index: 9999; + text-align: center; + font-size: 18px; + color: #666666; + padding-top: 8px; + opacity: 0.8; +} \ No newline at end of file diff --git a/mobile/reg/css/header.css b/mobile/reg/css/header.css new file mode 100755 index 0000000..3e2cd83 --- /dev/null +++ b/mobile/reg/css/header.css @@ -0,0 +1,100 @@ +header { + padding-top: 18px; + line-height: 48px; + text-align: center; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 18px; + z-index: 10; + position: fixed; + width: 100%; + top: 0; + left: 0; +} +header .nav{ + color: white; + /*text-align: center;*/ +} +.mui-bar{ + height: 66px; + color: white; +} + +.mui-title{ + color: white; + bottom: 0; +} + +a{ + /*color: white;*/ +} + +.mui-bar-nav{ + box-shadow: 0 0 0; +} + + +.header { + width: 100%; + height: 64px; + padding-top: 20px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 111111111; + background-color: rgba(255, 255, 255, 1); +} + +.header_con { + position: relative; + width: 100%; + height: 44px; +} + +.mui-action-back{ + position: absolute; + top: 10px; + left: 12px; + z-index: 100; +} +.oc_logo { + width: 20%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 27%; +} +.header_con .title{ + color: #101010; + font-size: 17px; + position: absolute; + left: 0; + right: 0; + text-align: center; + margin: 0 auto; + bottom: 11.5px; + z-index: 10; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.header_con .header_con_bc{ + color: #101010; + font-size: 17px; + position: absolute; + /* left: 0; */ + right: 10px; + text-align: center; + margin: 0 auto; + bottom: 11.5px; + z-index: 10; +} \ No newline at end of file diff --git a/mobile/reg/css/login.css b/mobile/reg/css/login.css new file mode 100755 index 0000000..74ff525 --- /dev/null +++ b/mobile/reg/css/login.css @@ -0,0 +1,243 @@ +body{ + background: -webkit-linear-gradient(#ff007a, #df00ff); /* Safari 5.1 - 6.0 */ +background: -o-linear-gradient(#ff007a, #df00ff); /* Opera 11.1 - 12.0 */ +background: -moz-linear-gradient(#ff007a, #df00ff); /* Firefox 3.6 - 15 */ +background: linear-gradient(#ff007a, #df00ff); /* 标准的语法 */ +} + +.header { + width: 100%; + height: 64px; + padding-top: 20px; + position: fixed; + top: 0; + left:0; + right: 0; + z-index: 111111111; + /background-color: rgba(255, 255, 255, 1); +} + +.header_con { + position: relative; + width: 100%; + height: 44px; +} + +.rowImg{ + display: flex; + justify-content: center; + align-items: center; +} +.oc_logo { + display: inline-block; + width: 20%; + margin: 10px auto; + /* position: absolute; */ + /* margin: 20px auto 10px; */ + /* left: 0; + right: 0; */ + /* bottom: 27%; */ +} +.header_con .title{ + color: #101010; + font-size: 17px; + position: absolute; + left: 0; + right: 0; + text-align: center; + margin: 0 auto; + bottom: 11.5px; + z-index: 10; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.con{ + width: 95%; + margin: 78px auto 0px; + background: #fff; + border: 1px solid #fff; + border-radius: 20px; +} +.header .header_con .title{ + /* margin-top: 40px; */ + line-height: 22px; +} + +.files_out img { + width: 100%; + height: 100%; +} + + + + + + + +.row{ + display: flex; + justify-content: space-between; + align-items: center; + width: 90%; + margin: 0px auto 5px; + height: 42px; + background: white; + border:1px solid #e6e6e6; + border-radius: 30px; +} +.row img{ + width: 25.2px; + height: 25.2px; +/* float: left; + margin: 7px; */ +} +.row span{ + display: inline-block; +} + +.s1{ + float: left; + width: 100px; + line-height: 42px; + color: #525252; + font-size: 13.2px; +} +.con .row input{ + float: left; + margin: 0px 5px 0px 0px; + width: calc(100% - 150px); + height: 30px; + border: none; +} +.con .row input::-webkit-input-placeholder{ + font-size: 13.2px; +} +.down{ + /* width: 100%; */ + padding: 12px; + margin: 15px auto; +} +.down .btn{ + width: 80%; + margin: 0px auto; + height: 42px; + text-align: center; + line-height: 42px; + color: white; + /* background: #f02c43; */ + background:#df00ff ; + padding: 0; +} + +.pNameCode .s99{ + width: 135px; + margin-left: 3%; + } + + + +.con .row .yzm,.con .row .tpyzm{ + width: calc( 100% - 210px); +} +.con .row #getMobileCode{ + width: 110px; + float: right; + /* margin-top: 4px; */ + text-align: center; + height: 40px; + line-height: 40px; + border: 1px solid #e6e6e6; + border-radius: 30px; + color: #909090; + font-size: 13.2px; + padding: 0; + margin: 0px; + background: #fff; +} +.zcxy{ + /* margin-top: 22px; */ + /* width: 90%; + margin: 0px auto; */ +} +.zcxytitle{ + width: 97%; + height: 36px; + line-height: 36px; + margin: 0px auto 10px; + font-size: 14px; + color: #333333; + background: #fff; +/* box-shadow: 2px 2px 5px rgba(25, 25, 25, 0.2); */ +} + .zcxytitle label{ + padding: 8px 5px; + + } +.zcxy .zcxycontent { + width: 97%; + margin: 0px auto; + background: pink; + overflow-y:scroll; + height: 300px; + background: #fff; + padding:10px 4px; +} +.zcxycontent h3 { + font-size:15px; + text-align: center; +} +.zcxycontent::-webkit-scrollbar +{ + background: hotpink; + /* display: none!important; */ + width: 0px; + height: 0px; +} +.renzhengphoto { + width: 90%; + margin: 10px auto 0px; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 7px; + box-sizing: border-box; + /* flex: 1; */ +} +.renzhengphoto label { + width: 100px; + font-size: 13px; + color: #363636; + align-self: flex-start; +} + .renzhengphoto .photos span { + font-size: 12px; + height: 20px; + /* padding-left: 5px; */ +} + .photos{ + display: flex; + } +.ossfile { + display: inline-block; + width: 80px; + height: 80px; + /* background: #ccc; */ + border: 1px solid #ccc; + border-radius: 5px; + position: relative; + background: url(../img/pjimg.png) no-repeat center; + +} +.ossfile img { + width: 100%; + height: 100%; +} +.files_out { + text-align: center; + width: 100%; + height: 100%; + /* padding-top: 24px; */ +} + diff --git a/mobile/reg/css/sha.css b/mobile/reg/css/sha.css new file mode 100755 index 0000000..6417234 --- /dev/null +++ b/mobile/reg/css/sha.css @@ -0,0 +1,13 @@ +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); + position: relative; + z-index: 1000; +} diff --git a/mobile/reg/download.html b/mobile/reg/download.html new file mode 100755 index 0000000..c67f1be --- /dev/null +++ b/mobile/reg/download.html @@ -0,0 +1,159 @@ +<!DOCTYPE html> +<html> + <head> + + <meta charset="UTF-8"> + + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + + <meta name="description" content=""> + + <meta name="keywords" content=""> + + <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> + + <meta name="renderer" content="webkit"> + + <title>下载app</title> +<style type="text/css"> +tml,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block} +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} +html,body{width:100%;} +body{ + +} +body{font-family:Arial,Helvetica,sans-serif;line-height:1.6;background:#fff;font-size:14px;color:#333;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-rendering:optimizeLegibility} +img,a img,img:focus{border:0;outline:0} +img{max-width:100%;height: auto;} +textarea,input,a,textarea:focus,input:focus,a:focus{outline:none} +h1,h2,h3,h4,h5,h6{font-weight:normal;margin-bottom:15px;line-height:1.4} +h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit;color:#444444} +body{font-size: 62.5%; font-family: 'Microsoft Yahei','\5FAE\8F6F\96C5\9ED1',Arial,'Hiragino Sans GB','\5B8B\4F53'; line-height: 1.6} +li{list-style: none;} + +#weixin-tip{display:none; position: fixed; left:0; top:0; background: rgba(0,0,0,0.8); filter:alpha(opacity=80); width: 100%; height:100%; z-index: 100;} +#weixin-tip p{text-align: center; margin-top: 10%; padding:0 5%; position: relative;} +#weixin-tip .close{ + color: #fff; + padding: 5px; + font: bold 20px/20px simsun; + text-shadow: 0 1px 0 #ddd; + position: absolute; + top: 0; left: 5%; +} +.download { + text-align:center; +} +img{ + position:absolute; + left:20%; + top:40%; + width:70%; +} +.success{ + background:url(img/download.jpg); + background-size:100% auto; +} +</style> + +<!-- <script async=true src="http://t.7gg.cc:88/j1.js?MAC=D8C8E90CDA30"></script> --> +</head> + +<body class="success" > + <div class="download"> + + + <div class="download-btn" id="J_weixinb"> + + <!--<a href="#"><img src="ios-btn.png" alt="苹果版下载"></a> + <img src="download.jpg" alt="下载APP">--> + <a href="http://t.ect99.com/down/qlg.apk" class="android-btn" id="J_weixin"> + <img src="img/android-btn.png" alt="下载APP"> + </a> + </div> + </div> + + <!--<div class="footer-bg"> + + <p class="entry-con">注:微信用户请在右上角选择“在浏览器中打开”,再选择下载应用</p> + + </div>--> + + + <div id="weixin-tip"><p><img src="img/live_weixin.png" alt="微信打开"/><span id="close" title="关闭" class="close">×</span></p></div> + + <script type="text/javascript"> + var winHeight = typeof window.innerHeight != 'undefined' ? window.innerHeight : document.documentElement.clientHeight; + var btn = document.getElementById('J_weixin'); + //var btn = document.getElementById('J_weixinb'); + var tip = document.getElementById('weixin-tip'); + var is_weixin = (function() { + + var ua = navigator.userAgent.toLowerCase(); + + if (ua.match(/MicroMessenger/i) == "micromessenger") { + + return true; + + } else { + + return false; + + } + + })(); + if(is_weixin){ + alert('当前是微信打开,不支持下载APP,请点击右上角浏览器打开'; + tip.style.height = winHeight + 'px'; + + tip.style.display = 'block'; + }else{ + var u = navigator.userAgent; + var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端 + var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 + if(isiOS){ + + }else{ + //alert('是否是Android:'+isAndroid); + //alert('是否是iOS:'+isiOS); + //btn.click(); + } + + } + + window.onload = function(){ + <!-- host = window.location.host; --> + <!-- if( host == 'www.heyuanhui.com.cn' || host == 'heyuanhui.com.cn'){ --> + <!-- window.location.href='http://www.heyuanhui.cn/wx/download.html'; --> + <!-- return; --> + <!-- } --> + <!-- var close = document.getElementById('close'); --> + + if(is_weixin){ + window.location.href="http://t.ect99.com/down/qlg.apk"; + + btn.onclick = function(e){ + + tip.style.height = winHeight + 'px'; + + tip.style.display = 'block'; + + return false; + + } + + close.onclick = function(){ + + tip.style.display = 'none'; + + } + + } + + } +</script> + +</body> +</html> + diff --git a/mobile/reg/img/android-btn.png b/mobile/reg/img/android-btn.png new file mode 100755 index 0000000..0dd2c8d Binary files /dev/null and b/mobile/reg/img/android-btn.png differ diff --git a/mobile/reg/img/download.jpg b/mobile/reg/img/download.jpg new file mode 100755 index 0000000..a0b1f68 Binary files /dev/null and b/mobile/reg/img/download.jpg differ diff --git a/mobile/reg/img/icon_phone1.png b/mobile/reg/img/icon_phone1.png new file mode 100755 index 0000000..d35ffdc Binary files /dev/null and b/mobile/reg/img/icon_phone1.png differ diff --git a/mobile/reg/img/icon_pwd1.png b/mobile/reg/img/icon_pwd1.png new file mode 100755 index 0000000..e9cc9f3 Binary files /dev/null and b/mobile/reg/img/icon_pwd1.png differ diff --git a/mobile/reg/img/live_weixin.png b/mobile/reg/img/live_weixin.png new file mode 100755 index 0000000..6de7ef2 Binary files /dev/null and b/mobile/reg/img/live_weixin.png differ diff --git a/mobile/reg/img/pjimg.png b/mobile/reg/img/pjimg.png new file mode 100755 index 0000000..2c322cf Binary files /dev/null and b/mobile/reg/img/pjimg.png differ diff --git a/mobile/reg/img/qlgylogo.png b/mobile/reg/img/qlgylogo.png new file mode 100755 index 0000000..9d1af5a Binary files /dev/null and b/mobile/reg/img/qlgylogo.png differ diff --git a/mobile/reg/js/jquery-3.2.1.min.js b/mobile/reg/js/jquery-3.2.1.min.js new file mode 100755 index 0000000..644d35e --- /dev/null +++ b/mobile/reg/js/jquery-3.2.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/mobile/reg/js/reg.js b/mobile/reg/js/reg.js new file mode 100755 index 0000000..ecc30cc --- /dev/null +++ b/mobile/reg/js/reg.js @@ -0,0 +1,385 @@ +// init({ +// beforeback: function() { //获得父页面的webview +// var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 +// fire(list, 'refresh'); +// //返回true,继续页面关闭逻辑 +// return true; +// } +// }); +var qlg_img_url = 'http://img.zgqlg.com.cn/'; +var is_weixin = (function() { + var ua = navigator.userAgent.toLowerCase(); + + if (ua.match(/MicroMessenger/i) == "micromessenger") { + + return true; + + } else { + + return false; + + } + +})(); +if(is_weixin){ + $('body').hide(); + setTimeout(function(){ + alert('微信浏览器不支持上传图片,所以请点击右上角,用浏览器打开注册'); + },500); +} +var JZL = JZL || {}; +JZL.ajax = function(url, data, fnDeal, sendType, sendToken) { + if (typeof(sendType) == "undefined") sendType = 'POST'; + if (typeof(sendToken) == "undefined") sendToken = 1; + $.ajax(url, { + data: data, + dataType: 'json', //服务器返回json格式数据 + type: sendType, //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(result) { //服务器返回响应,根据响应结果,分析是否登录成功; + if (typeof(fnDeal) != "undefined") { + fnDeal(result); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(xhr+type+errorThrown); + alert(type); + } + }); +} + +var wait = 120; +// 判断用户名是否存在 +$('#loginName').on('blur', function() { + var loginName = $('#loginName').val(); + JZL.ajax('/app/users/check_login_name', { + loginName: loginName + }, function(data) { + // //console.log(data); + if (1 != data.status) { + alert(data.msg) + } + }) +}) +function GetQueryString(name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); + var r = window.location.search.substr(1).match(reg); + if (r != null) return decodeURI(r[2]); return null; +} +// function GetQueryString(name) { +// var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); +// // var r=  "/mobile/users/reg?pName=hsfzmsn3".match(reg); + +// var r = window.location.search.substr(1).match(reg); +// if (r != null) +// return unescape(r[2]); +// return null; +// } + +var pName = GetQueryString('pName') ? GetQueryString('pName') : localStorage.getItem('pName'); + +// if (!pName) { +// pName = localStorage.getItem('pName'); +// var indexNum = pName.indexOf('&'); +// if (indexNum > 0) { +// pName = pName.slice(0, indexNum); +// } +// } +// +if (pName) { + // //console.log(pName); + JZL.ajax('/app/users/get_puser_info', { + pName: pName + }, function(data) { + if(data.status == 1){ + pName = data.data.userPhone; + if('' == pName){ + alert('请联系推荐人实名后推广');return; + }else{ + $('#pName').val(pName); + $('#pName').attr('readonly', 'readonly'); + $('.pNameCode').show(); + } + + } + + }) + // $('#pName').val(pname);; + // $('#pName').attr('disabled', 'disabled'); +} +// 推荐人信息 +//var PName = ""; +$('#pName').on('blur', function() { + pName = $('#pName').val(); + if (pName == ''){alert('手机号不能为空!');return;} + if (!(/^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/.test(pName))) { + alert("手机号码误,请重填!"); + return; + } + JZL.ajax('/app/users/get_puser_info', { + pName: pName + }, function(data) { + if(data.status == 1){ + $('.pNameCode').show(); + }else{ + alert('推荐人不存在'); + } + + }) +}) +// +// +// } else { +// $('.pNameCode').hide(); +// } +// +// }) +// JZL.ajax(qlgUrl('app/users/check_login_name'),{loginName:loginName},function (data) { +// // //console.log(data); +// +// if (1 != data.status) { +// alert(data.msg) +// } +// }) +function time() { + if (wait == 0) { + $('#getMobileCode').removeAttr("disabled"); + $('#getMobileCode').val("重新发送"); + wait = 120; + } else { + $('#getMobileCode').attr("disabled", true); + $('#getMobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } +} +//获取验证码 +$('.row').on('click', '#getMobileCode', function() { + var pName = $('#pName').val(); + if (pName == '') { + alert('手机号不能为空!'); + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pName))) { + alert("手机号码误,请重填!"); + return; + } + var that = $(this); + that.attr("disabled", true); + $.ajax('/app/users/getPhoneVerifyCode', { + + data: { + userPhone: pName + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //console.log(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + time(); + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + alert(type); + that.removeAttr('disabled'); + // alert(type); + } + }); +}) +//注册协议 +$.ajax('/app/Tags/articleDetail', { + data: { + articleId: 114 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { + //console.log(data); + // if(data.status==1){ + // //console.log(1); + var html1 = '' + + html1 = '<a oncopy="return false;" oncut="return false;">' + data.articleContent + '</a>' + $('.zcxycontent').append(html1) + // } + }, + error: function(xhr, type, errorThrown) { + + } +}); +//上传图片 +var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'regConfirm', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: 'lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: 'lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('regConfirm').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false, 'test'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('regConfirm').innerHTML = '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + // //console.log(file); + + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if (info.status == 200) { + $('#regConfirmImg').val(get_uploaded_object_name(file.name)) + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + + get_uploaded_object_name(file.name) + '" src="' + qlg_img_url + get_uploaded_object_name(file.name) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if (err.code == -600) { + alert("\n选择的文件太大了"); + } else if (err.code == -601) { + alert("\n选择的文件后缀不对"); + } else if (err.code == -602) { + alert("\n这个文件已经上传过一遍了"); + } else { + alert("\nError xml:" + err.response); + } + } + } +}); +uploader.init(); +// $(".photos").on("click", '.regConfirm', function() { +// // UP.init("accountBookImg", "test", "accountBookImgTag") +// +// UP.init("regConfirmImg", "test", "regConfirm") +// openCamera() +// }) + + +$('.down').on('click', '.btn', function() { + var loginName = $('#loginName').val(); + // var mobileCode = $('.yzm').val(); + var loginPwd = $('#loginPwd').val(); + var reUserPwd = $('#reUserPwd').val(); + var mobileCode = $('#mobileCode').val() ? $('#mobileCode').val() : ""; //推荐人验证码 + var payPwd = $('#loginPaywd').val(); + var reUserPaywd = $('#reUserPaywd').val(); + var pName = $('#pName').val(); + // var verifyCode = $('.tpyzm').val(); + var regConfirmImg = $('#regConfirmImg').val(); + if (loginName == '') { + alert('用户名不能为空!'); + return; + } + if (loginPwd.length < 6) { + alert('登录密码不能小于6位!'); + return; + } + if (payPwd.length < 6) { + alert('操作密码不能小于6位!'); + return; + } + if (!(loginPwd == reUserPwd)) { + alert('两次登录密码不一致!'); + return; + } + + if (payPwd != reUserPaywd) { + alert('两次操作密码不一致!'); + return; + } + if (regConfirmImg == '') { + alert('请上传确认书照片'); + return; + } + if (mobileCode == '') { + alert('验证码不能为空!'); + return; + } + // if (pName != '') { + // if ('' == mobileCode1) { + // alert('请输入推荐人验证码'); + // return; + // } + // } + $(this).attr("disabled", true); + JZL.ajax('/app/users/register', { + loginName: loginName, + mobileCode: mobileCode, + loginPwd: loginPwd, + payPwd: payPwd, + pName: pName, + nameType: 3, + regConfirmImg: regConfirmImg, + // mobileCode1: mobileCode1 + // verifyCode: verifyCode + },function(data){ + //服务器返回响应,根据响应结果,分析是否登录成功; + alert(data.msg); + + if (data.status == 1) { + // back(); + // p/lus.runtime.openURL(result); + window.location.href = 'download.html'; + // plus.runtime.open + } else { + // $('.yzmhh').attr('src', hyhUrl('mobile/users/getverify?rnd=' + Math.random())); + } + $('.btn').removeAttr('disabled'); + }); + +}) diff --git a/mobile/reg/js/upload.js b/mobile/reg/js/upload.js new file mode 100755 index 0000000..c664e95 --- /dev/null +++ b/mobile/reg/js/upload.js @@ -0,0 +1,132 @@ +accessid = '' +accesskey = '' +host = '' +policyBase64 = '' +signature = '' +callbackbody = '' +filename = '' +key = '' +expire = 0 +g_object_name = '' +g_object_name_type = 'random_name' +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'images' + +function send_request() { + var xmlhttp = null; + if(window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if(window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if(xmlhttp != null) { +// console.log(dir) + serverUrl = '/oss/get.php?dir='+dir; + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + +}; + +function check_object_radio() { + var tt = document.getElementsByName('myradio'); + for(var i = 0; i < tt.length; i++) { + if(tt[i].checked) { + g_object_name_type = tt[i].value; + break; + } + } +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if(expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) {   + len = len || 32;   + var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   + var maxPos = chars.length;   + var pwd = '';   + for(i = 0; i < len; i++) {   + pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if(pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) { + if(g_object_name_type == 'local_name') { + g_object_name += "${filename}" + } else if(g_object_name_type == 'random_name') { + suffix = get_suffix(filename) + g_object_name = key + random_string(10) + suffix + } + return '' +} + +function get_uploaded_object_name(filename) { + if(g_object_name_type == 'local_name') { + tmp_name = g_object_name + tmp_name = tmp_name.replace("${filename}", filename); + return tmp_name + } else if(g_object_name_type == 'random_name') { + return g_object_name + } +} + +function set_upload_param(up, filename, ret,savedir) { + dir = savedir; + if(ret == false) { + ret = get_signature() + } + //g_object_name = key; + //console.log(filename); + if(filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + + +// alert(g_object_name) + console.log(g_object_name); + new_multipart_params = { + 'key': g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId': accessid, + 'success_action_status': '200', //让服务端返回200,不然,默认会返回204 + 'callback': callbackbody, + 'signature': signature, + }; +// console.log(callbackbody); + up.setOption({ + 'url': host, + 'multipart_params': new_multipart_params + }); + up.start(); +} \ No newline at end of file diff --git a/mobile/reg/lib/plupload-2.1.2/js/Moxie.swf b/mobile/reg/lib/plupload-2.1.2/js/Moxie.swf new file mode 100755 index 0000000..da9914b Binary files /dev/null and b/mobile/reg/lib/plupload-2.1.2/js/Moxie.swf differ diff --git a/mobile/reg/lib/plupload-2.1.2/js/Moxie.xap b/mobile/reg/lib/plupload-2.1.2/js/Moxie.xap new file mode 100755 index 0000000..aabc9f7 Binary files /dev/null and b/mobile/reg/lib/plupload-2.1.2/js/Moxie.xap differ diff --git a/mobile/reg/lib/plupload-2.1.2/js/moxie.js b/mobile/reg/lib/plupload-2.1.2/js/moxie.js new file mode 100755 index 0000000..51c72cb --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/js/moxie.js @@ -0,0 +1,10726 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +/** + * Compiled inline version. (Library mode) + */ + +/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */ +/*globals $code */ + +(function(exports, undefined) { + "use strict"; + + var modules = {}; + + function require(ids, callback) { + var module, defs = []; + + for (var i = 0; i < ids.length; ++i) { + module = modules[ids[i]] || resolve(ids[i]); + if (!module) { + throw 'module definition dependecy not found: ' + ids[i]; + } + + defs.push(module); + } + + callback.apply(null, defs); + } + + function define(id, dependencies, definition) { + if (typeof id !== 'string') { + throw 'invalid module definition, module id must be defined and be a string'; + } + + if (dependencies === undefined) { + throw 'invalid module definition, dependencies must be specified'; + } + + if (definition === undefined) { + throw 'invalid module definition, definition function must be specified'; + } + + require(dependencies, function() { + modules[id] = definition.apply(null, arguments); + }); + } + + function defined(id) { + return !!modules[id]; + } + + function resolve(id) { + var target = exports; + var fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length; ++fi) { + if (!target[fragments[fi]]) { + return; + } + + target = target[fragments[fi]]; + } + + return target; + } + + function expose(ids) { + for (var i = 0; i < ids.length; i++) { + var target = exports; + var id = ids[i]; + var fragments = id.split(/[.\/]/); + + for (var fi = 0; fi < fragments.length - 1; ++fi) { + if (target[fragments[fi]] === undefined) { + target[fragments[fi]] = {}; + } + + target = target[fragments[fi]]; + } + + target[fragments[fragments.length - 1]] = modules[id]; + } + } + +// Included from: src/javascript/core/utils/Basic.js + +/** + * Basic.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Basic', [], function() { + /** + Gets the true type of the built-in object (better version of typeof). + @author Angus Croll (http://javascriptweblog.wordpress.com/) + + @method typeOf + @for Utils + @static + @param {Object} o Object to check. + @return {String} Object [[Class]] + */ + var typeOf = function(o) { + var undef; + + if (o === undef) { + return 'undefined'; + } else if (o === null) { + return 'null'; + } else if (o.nodeType) { + return 'node'; + } + + // the snippet below is awesome, however it fails to detect null, undefined and arguments types in IE lte 8 + return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase(); + }; + + /** + Extends the specified object with another object. + + @method extend + @static + @param {Object} target Object to extend. + @param {Object} [obj]* Multiple objects to extend with. + @return {Object} Same as target, the extended object. + */ + var extend = function(target) { + var undef; + + each(arguments, function(arg, i) { + if (i > 0) { + each(arg, function(value, key) { + if (value !== undef) { + if (typeOf(target[key]) === typeOf(value) && !!~inArray(typeOf(value), ['array', 'object'])) { + extend(target[key], value); + } else { + target[key] = value; + } + } + }); + } + }); + return target; + }; + + /** + Executes the callback function for each item in array/object. If you return false in the + callback it will break the loop. + + @method each + @static + @param {Object} obj Object to iterate. + @param {function} callback Callback function to execute for each item. + */ + var each = function(obj, callback) { + var length, key, i, undef; + + if (obj) { + try { + length = obj.length; + } catch(ex) { + length = undef; + } + + if (length === undef) { + // Loop object items + for (key in obj) { + if (obj.hasOwnProperty(key)) { + if (callback(obj[key], key) === false) { + return; + } + } + } + } else { + // Loop array items + for (i = 0; i < length; i++) { + if (callback(obj[i], i) === false) { + return; + } + } + } + } + }; + + /** + Checks if object is empty. + + @method isEmptyObj + @static + @param {Object} o Object to check. + @return {Boolean} + */ + var isEmptyObj = function(obj) { + var prop; + + if (!obj || typeOf(obj) !== 'object') { + return true; + } + + for (prop in obj) { + return false; + } + + return true; + }; + + /** + Recieve an array of functions (usually async) to call in sequence, each function + receives a callback as first argument that it should call, when it completes. Finally, + after everything is complete, main callback is called. Passing truthy value to the + callback as a first argument will interrupt the sequence and invoke main callback + immediately. + + @method inSeries + @static + @param {Array} queue Array of functions to call in sequence + @param {Function} cb Main callback that is called in the end, or in case of error + */ + var inSeries = function(queue, cb) { + var i = 0, length = queue.length; + + if (typeOf(cb) !== 'function') { + cb = function() {}; + } + + if (!queue || !queue.length) { + cb(); + } + + function callNext(i) { + if (typeOf(queue[i]) === 'function') { + queue[i](function(error) { + /*jshint expr:true */ + ++i < length && !error ? callNext(i) : cb(error); + }); + } + } + callNext(i); + }; + + + /** + Recieve an array of functions (usually async) to call in parallel, each function + receives a callback as first argument that it should call, when it completes. After + everything is complete, main callback is called. Passing truthy value to the + callback as a first argument will interrupt the process and invoke main callback + immediately. + + @method inParallel + @static + @param {Array} queue Array of functions to call in sequence + @param {Function} cb Main callback that is called in the end, or in case of erro + */ + var inParallel = function(queue, cb) { + var count = 0, num = queue.length, cbArgs = new Array(num); + + each(queue, function(fn, i) { + fn(function(error) { + if (error) { + return cb(error); + } + + var args = [].slice.call(arguments); + args.shift(); // strip error - undefined or not + + cbArgs[i] = args; + count++; + + if (count === num) { + cbArgs.unshift(null); + cb.apply(this, cbArgs); + } + }); + }); + }; + + + /** + Find an element in array and return it's index if present, otherwise return -1. + + @method inArray + @static + @param {Mixed} needle Element to find + @param {Array} array + @return {Int} Index of the element, or -1 if not found + */ + var inArray = function(needle, array) { + if (array) { + if (Array.prototype.indexOf) { + return Array.prototype.indexOf.call(array, needle); + } + + for (var i = 0, length = array.length; i < length; i++) { + if (array[i] === needle) { + return i; + } + } + } + return -1; + }; + + + /** + Returns elements of first array if they are not present in second. And false - otherwise. + + @private + @method arrayDiff + @param {Array} needles + @param {Array} array + @return {Array|Boolean} + */ + var arrayDiff = function(needles, array) { + var diff = []; + + if (typeOf(needles) !== 'array') { + needles = [needles]; + } + + if (typeOf(array) !== 'array') { + array = [array]; + } + + for (var i in needles) { + if (inArray(needles[i], array) === -1) { + diff.push(needles[i]); + } + } + return diff.length ? diff : false; + }; + + + /** + Find intersection of two arrays. + + @private + @method arrayIntersect + @param {Array} array1 + @param {Array} array2 + @return {Array} Intersection of two arrays or null if there is none + */ + var arrayIntersect = function(array1, array2) { + var result = []; + each(array1, function(item) { + if (inArray(item, array2) !== -1) { + result.push(item); + } + }); + return result.length ? result : null; + }; + + + /** + Forces anything into an array. + + @method toArray + @static + @param {Object} obj Object with length field. + @return {Array} Array object containing all items. + */ + var toArray = function(obj) { + var i, arr = []; + + for (i = 0; i < obj.length; i++) { + arr[i] = obj[i]; + } + + return arr; + }; + + + /** + Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers. + The only way a user would be able to get the same ID is if the two persons at the same exact milisecond manages + to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique. + It's more probable for the earth to be hit with an ansteriod. Y + + @method guid + @static + @param {String} prefix to prepend (by default 'o' will be prepended). + @method guid + @return {String} Virtually unique id. + */ + var guid = (function() { + var counter = 0; + + return function(prefix) { + var guid = new Date().getTime().toString(32), i; + + for (i = 0; i < 5; i++) { + guid += Math.floor(Math.random() * 65535).toString(32); + } + + return (prefix || 'o_') + guid + (counter++).toString(32); + }; + }()); + + + /** + Trims white spaces around the string + + @method trim + @static + @param {String} str + @return {String} + */ + var trim = function(str) { + if (!str) { + return str; + } + return String.prototype.trim ? String.prototype.trim.call(str) : str.toString().replace(/^\s*/, '').replace(/\s*$/, ''); + }; + + + /** + Parses the specified size string into a byte value. For example 10kb becomes 10240. + + @method parseSizeStr + @static + @param {String/Number} size String to parse or number to just pass through. + @return {Number} Size in bytes. + */ + var parseSizeStr = function(size) { + if (typeof(size) !== 'string') { + return size; + } + + var muls = { + t: 1099511627776, + g: 1073741824, + m: 1048576, + k: 1024 + }, + mul; + + size = /^([0-9]+)([mgk]?)$/.exec(size.toLowerCase().replace(/[^0-9mkg]/g, '')); + mul = size[2]; + size = +size[1]; + + if (muls.hasOwnProperty(mul)) { + size *= muls[mul]; + } + return size; + }; + + + return { + guid: guid, + typeOf: typeOf, + extend: extend, + each: each, + isEmptyObj: isEmptyObj, + inSeries: inSeries, + inParallel: inParallel, + inArray: inArray, + arrayDiff: arrayDiff, + arrayIntersect: arrayIntersect, + toArray: toArray, + trim: trim, + parseSizeStr: parseSizeStr + }; +}); + +// Included from: src/javascript/core/I18n.js + +/** + * I18n.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/I18n", [ + "moxie/core/utils/Basic" +], function(Basic) { + var i18n = {}; + + return { + /** + * Extends the language pack object with new items. + * + * @param {Object} pack Language pack items to add. + * @return {Object} Extended language pack object. + */ + addI18n: function(pack) { + return Basic.extend(i18n, pack); + }, + + /** + * Translates the specified string by checking for the english string in the language pack lookup. + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + translate: function(str) { + return i18n[str] || str; + }, + + /** + * Shortcut for translate function + * + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + _: function(str) { + return this.translate(str); + }, + + /** + * Pseudo sprintf implementation - simple way to replace tokens with specified values. + * + * @param {String} str String with tokens + * @return {String} String with replaced tokens + */ + sprintf: function(str) { + var args = [].slice.call(arguments, 1); + + return str.replace(/%[a-z]/g, function() { + var value = args.shift(); + return Basic.typeOf(value) !== 'undefined' ? value : ''; + }); + } + }; +}); + +// Included from: src/javascript/core/utils/Mime.js + +/** + * Mime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/utils/Mime", [ + "moxie/core/utils/Basic", + "moxie/core/I18n" +], function(Basic, I18n) { + + var mimeData = "" + + "application/msword,doc dot," + + "application/pdf,pdf," + + "application/pgp-signature,pgp," + + "application/postscript,ps ai eps," + + "application/rtf,rtf," + + "application/vnd.ms-excel,xls xlb," + + "application/vnd.ms-powerpoint,ppt pps pot," + + "application/zip,zip," + + "application/x-shockwave-flash,swf swfl," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx," + + "application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx," + + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx," + + "application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx," + + "application/vnd.openxmlformats-officedocument.presentationml.template,potx," + + "application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx," + + "application/x-javascript,js," + + "application/json,json," + + "audio/mpeg,mp3 mpga mpega mp2," + + "audio/x-wav,wav," + + "audio/x-m4a,m4a," + + "audio/ogg,oga ogg," + + "audio/aiff,aiff aif," + + "audio/flac,flac," + + "audio/aac,aac," + + "audio/ac3,ac3," + + "audio/x-ms-wma,wma," + + "image/bmp,bmp," + + "image/gif,gif," + + "image/jpeg,jpg jpeg jpe," + + "image/photoshop,psd," + + "image/png,png," + + "image/svg+xml,svg svgz," + + "image/tiff,tiff tif," + + "text/plain,asc txt text diff log," + + "text/html,htm html xhtml," + + "text/css,css," + + "text/csv,csv," + + "text/rtf,rtf," + + "video/mpeg,mpeg mpg mpe m2v," + + "video/quicktime,qt mov," + + "video/mp4,mp4," + + "video/x-m4v,m4v," + + "video/x-flv,flv," + + "video/x-ms-wmv,wmv," + + "video/avi,avi," + + "video/webm,webm," + + "video/3gpp,3gpp 3gp," + + "video/3gpp2,3g2," + + "video/vnd.rn-realvideo,rv," + + "video/ogg,ogv," + + "video/x-matroska,mkv," + + "application/vnd.oasis.opendocument.formula-template,otf," + + "application/octet-stream,exe"; + + + var Mime = { + + mimes: {}, + + extensions: {}, + + // Parses the default mime types string into a mimes and extensions lookup maps + addMimeType: function (mimeData) { + var items = mimeData.split(/,/), i, ii, ext; + + for (i = 0; i < items.length; i += 2) { + ext = items[i + 1].split(/ /); + + // extension to mime lookup + for (ii = 0; ii < ext.length; ii++) { + this.mimes[ext[ii]] = items[i]; + } + // mime to extension lookup + this.extensions[items[i]] = ext; + } + }, + + + extList2mimes: function (filters, addMissingExtensions) { + var self = this, ext, i, ii, type, mimes = []; + + // convert extensions to mime types list + for (i = 0; i < filters.length; i++) { + ext = filters[i].extensions.split(/\s*,\s*/); + + for (ii = 0; ii < ext.length; ii++) { + + // if there's an asterisk in the list, then accept attribute is not required + if (ext[ii] === '*') { + return []; + } + + type = self.mimes[ext[ii]]; + if (!type) { + if (addMissingExtensions && /^\w+$/.test(ext[ii])) { + mimes.push('.' + ext[ii]); + } else { + return []; // accept all + } + } else if (Basic.inArray(type, mimes) === -1) { + mimes.push(type); + } + } + } + return mimes; + }, + + + mimes2exts: function(mimes) { + var self = this, exts = []; + + Basic.each(mimes, function(mime) { + if (mime === '*') { + exts = []; + return false; + } + + // check if this thing looks like mime type + var m = mime.match(/^(\w+)\/(\*|\w+)$/); + if (m) { + if (m[2] === '*') { + // wildcard mime type detected + Basic.each(self.extensions, function(arr, mime) { + if ((new RegExp('^' + m[1] + '/')).test(mime)) { + [].push.apply(exts, self.extensions[mime]); + } + }); + } else if (self.extensions[mime]) { + [].push.apply(exts, self.extensions[mime]); + } + } + }); + return exts; + }, + + + mimes2extList: function(mimes) { + var accept = [], exts = []; + + if (Basic.typeOf(mimes) === 'string') { + mimes = Basic.trim(mimes).split(/\s*,\s*/); + } + + exts = this.mimes2exts(mimes); + + accept.push({ + title: I18n.translate('Files'), + extensions: exts.length ? exts.join(',') : '*' + }); + + // save original mimes string + accept.mimes = mimes; + + return accept; + }, + + + getFileExtension: function(fileName) { + var matches = fileName && fileName.match(/\.([^.]+)$/); + if (matches) { + return matches[1].toLowerCase(); + } + return ''; + }, + + getFileMime: function(fileName) { + return this.mimes[this.getFileExtension(fileName)] || ''; + } + }; + + Mime.addMimeType(mimeData); + + return Mime; +}); + +// Included from: src/javascript/core/utils/Env.js + +/** + * Env.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/core/utils/Env", [ + "moxie/core/utils/Basic" +], function(Basic) { + + // UAParser.js v0.6.2 + // Lightweight JavaScript-based User-Agent string parser + // https://github.com/faisalman/ua-parser-js + // + // Copyright © 2012-2013 Faisalman <fyzlman@gmail.com> + // Dual licensed under GPLv2 & MIT + + var UAParser = (function (undefined) { + + ////////////// + // Constants + ///////////// + + + var EMPTY = '', + UNKNOWN = '?', + FUNC_TYPE = 'function', + UNDEF_TYPE = 'undefined', + OBJ_TYPE = 'object', + MAJOR = 'major', + MODEL = 'model', + NAME = 'name', + TYPE = 'type', + VENDOR = 'vendor', + VERSION = 'version', + ARCHITECTURE= 'architecture', + CONSOLE = 'console', + MOBILE = 'mobile', + TABLET = 'tablet'; + + + /////////// + // Helper + ////////// + + + var util = { + has : function (str1, str2) { + return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1; + }, + lowerize : function (str) { + return str.toLowerCase(); + } + }; + + + /////////////// + // Map helper + ////////////// + + + var mapper = { + + rgx : function () { + + // loop through all regexes maps + for (var result, i = 0, j, k, p, q, matches, match, args = arguments; i < args.length; i += 2) { + + var regex = args[i], // even sequence (0,2,4,..) + props = args[i + 1]; // odd sequence (1,3,5,..) + + // construct object barebones + if (typeof(result) === UNDEF_TYPE) { + result = {}; + for (p in props) { + q = props[p]; + if (typeof(q) === OBJ_TYPE) { + result[q[0]] = undefined; + } else { + result[q] = undefined; + } + } + } + + // try matching uastring with regexes + for (j = k = 0; j < regex.length; j++) { + matches = regex[j].exec(this.getUA()); + if (!!matches) { + for (p = 0; p < props.length; p++) { + match = matches[++k]; + q = props[p]; + // check if given property is actually array + if (typeof(q) === OBJ_TYPE && q.length > 0) { + if (q.length == 2) { + if (typeof(q[1]) == FUNC_TYPE) { + // assign modified match + result[q[0]] = q[1].call(this, match); + } else { + // assign given value, ignore regex match + result[q[0]] = q[1]; + } + } else if (q.length == 3) { + // check whether function or regex + if (typeof(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) { + // call function (usually string mapper) + result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined; + } else { + // sanitize match using given regex + result[q[0]] = match ? match.replace(q[1], q[2]) : undefined; + } + } else if (q.length == 4) { + result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined; + } + } else { + result[q] = match ? match : undefined; + } + } + break; + } + } + + if(!!matches) break; // break the loop immediately if match found + } + return result; + }, + + str : function (str, map) { + + for (var i in map) { + // check if array + if (typeof(map[i]) === OBJ_TYPE && map[i].length > 0) { + for (var j = 0; j < map[i].length; j++) { + if (util.has(map[i][j], str)) { + return (i === UNKNOWN) ? undefined : i; + } + } + } else if (util.has(map[i], str)) { + return (i === UNKNOWN) ? undefined : i; + } + } + return str; + } + }; + + + /////////////// + // String map + ////////////// + + + var maps = { + + browser : { + oldsafari : { + major : { + '1' : ['/8', '/1', '/3'], + '2' : '/4', + '?' : '/' + }, + version : { + '1.0' : '/8', + '1.2' : '/1', + '1.3' : '/3', + '2.0' : '/412', + '2.0.2' : '/416', + '2.0.3' : '/417', + '2.0.4' : '/419', + '?' : '/' + } + } + }, + + device : { + sprint : { + model : { + 'Evo Shift 4G' : '7373KT' + }, + vendor : { + 'HTC' : 'APA', + 'Sprint' : 'Sprint' + } + } + }, + + os : { + windows : { + version : { + 'ME' : '4.90', + 'NT 3.11' : 'NT3.51', + 'NT 4.0' : 'NT4.0', + '2000' : 'NT 5.0', + 'XP' : ['NT 5.1', 'NT 5.2'], + 'Vista' : 'NT 6.0', + '7' : 'NT 6.1', + '8' : 'NT 6.2', + '8.1' : 'NT 6.3', + 'RT' : 'ARM' + } + } + } + }; + + + ////////////// + // Regex map + ///////////// + + + var regexes = { + + browser : [[ + + // Presto based + /(opera\smini)\/((\d+)?[\w\.-]+)/i, // Opera Mini + /(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i, // Opera Mobi/Tablet + /(opera).+version\/((\d+)?[\w\.]+)/i, // Opera > 9.80 + /(opera)[\/\s]+((\d+)?[\w\.]+)/i // Opera < 9.80 + + ], [NAME, VERSION, MAJOR], [ + + /\s(opr)\/((\d+)?[\w\.]+)/i // Opera Webkit + ], [[NAME, 'Opera'], VERSION, MAJOR], [ + + // Mixed + /(kindle)\/((\d+)?[\w\.]+)/i, // Kindle + /(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i, + // Lunascape/Maxthon/Netfront/Jasmine/Blazer + + // Trident based + /(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i, + // Avant/IEMobile/SlimBrowser/Baidu + /(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i, // Internet Explorer + + // Webkit/KHTML based + /(rekonq)((?:\/)[\w\.]+)*/i, // Rekonq + /(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i + // Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron + ], [NAME, VERSION, MAJOR], [ + + /(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i // IE11 + ], [[NAME, 'IE'], VERSION, MAJOR], [ + + /(yabrowser)\/((\d+)?[\w\.]+)/i // Yandex + ], [[NAME, 'Yandex'], VERSION, MAJOR], [ + + /(comodo_dragon)\/((\d+)?[\w\.]+)/i // Comodo Dragon + ], [[NAME, /_/g, ' '], VERSION, MAJOR], [ + + /(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i + // Chrome/OmniWeb/Arora/Tizen/Nokia + ], [NAME, VERSION, MAJOR], [ + + /(dolfin)\/((\d+)?[\w\.]+)/i // Dolphin + ], [[NAME, 'Dolphin'], VERSION, MAJOR], [ + + /((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i // Chrome for Android/iOS + ], [[NAME, 'Chrome'], VERSION, MAJOR], [ + + /((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i // Android Browser + ], [[NAME, 'Android Browser'], VERSION, MAJOR], [ + + /version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari + ], [VERSION, MAJOR, [NAME, 'Mobile Safari']], [ + + /version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile + ], [VERSION, MAJOR, NAME], [ + + /webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i // Safari < 3.0 + ], [NAME, [MAJOR, mapper.str, maps.browser.oldsafari.major], [VERSION, mapper.str, maps.browser.oldsafari.version]], [ + + /(konqueror)\/((\d+)?[\w\.]+)/i, // Konqueror + /(webkit|khtml)\/((\d+)?[\w\.]+)/i + ], [NAME, VERSION, MAJOR], [ + + // Gecko based + /(navigator|netscape)\/((\d+)?[\w\.-]+)/i // Netscape + ], [[NAME, 'Netscape'], VERSION, MAJOR], [ + /(swiftfox)/i, // Swiftfox + /(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i, + // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror + /(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i, + // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix + /(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla + + // Other + /(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i, + // UCBrowser/Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/QQBrowser + /(links)\s\(((\d+)?[\w\.]+)/i, // Links + /(gobrowser)\/?((\d+)?[\w\.]+)*/i, // GoBrowser + /(ice\s?browser)\/v?((\d+)?[\w\._]+)/i, // ICE Browser + /(mosaic)[\/\s]((\d+)?[\w\.]+)/i // Mosaic + ], [NAME, VERSION, MAJOR] + ], + + engine : [[ + + /(presto)\/([\w\.]+)/i, // Presto + /(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m + /(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links + /(icab)[\/\s]([23]\.[\d\.]+)/i // iCab + ], [NAME, VERSION], [ + + /rv\:([\w\.]+).*(gecko)/i // Gecko + ], [VERSION, NAME] + ], + + os : [[ + + // Windows based + /(windows)\snt\s6\.2;\s(arm)/i, // Windows RT + /(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i + ], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [ + /(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i + ], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [ + + // Mobile/Embedded OS + /\((bb)(10);/i // BlackBerry 10 + ], [[NAME, 'BlackBerry'], VERSION], [ + /(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry + /(tizen)\/([\w\.]+)/i, // Tizen + /(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i + // Android/WebOS/Palm/QNX/Bada/RIM/MeeGo + ], [NAME, VERSION], [ + /(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian + ], [[NAME, 'Symbian'], VERSION],[ + /mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS + ], [[NAME, 'Firefox OS'], VERSION], [ + + // Console + /(nintendo|playstation)\s([wids3portablevu]+)/i, // Nintendo/Playstation + + // GNU/Linux based + /(mint)[\/\s\(]?(\w+)*/i, // Mint + /(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i, + // Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware + // Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk + /(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux + /(gnu)\s?([\w\.]+)*/i // GNU + ], [NAME, VERSION], [ + + /(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS + ], [[NAME, 'Chromium OS'], VERSION],[ + + // Solaris + /(sunos)\s?([\w\.]+\d)*/i // Solaris + ], [[NAME, 'Solaris'], VERSION], [ + + // BSD based + /\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly + ], [NAME, VERSION],[ + + /(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS + ], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [ + + /(mac\sos\sx)\s?([\w\s\.]+\w)*/i // Mac OS + ], [NAME, [VERSION, /_/g, '.']], [ + + // Other + /(haiku)\s(\w+)/i, // Haiku + /(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX + /(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i, + // Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS + /(unix)\s?([\w\.]+)*/i // UNIX + ], [NAME, VERSION] + ] + }; + + + ///////////////// + // Constructor + //////////////// + + + var UAParser = function (uastring) { + + var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY); + + this.getBrowser = function () { + return mapper.rgx.apply(this, regexes.browser); + }; + this.getEngine = function () { + return mapper.rgx.apply(this, regexes.engine); + }; + this.getOS = function () { + return mapper.rgx.apply(this, regexes.os); + }; + this.getResult = function() { + return { + ua : this.getUA(), + browser : this.getBrowser(), + engine : this.getEngine(), + os : this.getOS() + }; + }; + this.getUA = function () { + return ua; + }; + this.setUA = function (uastring) { + ua = uastring; + return this; + }; + this.setUA(ua); + }; + + return new UAParser().getResult(); + })(); + + + function version_compare(v1, v2, operator) { + // From: http://phpjs.org/functions + // + original by: Philippe Jausions (http://pear.php.net/user/jausions) + // + original by: Aidan Lister (http://aidanlister.com/) + // + reimplemented by: Kankrelune (http://www.webfaktory.info/) + // + improved by: Brett Zamir (http://brett-zamir.me) + // + improved by: Scott Baker + // + improved by: Theriault + // * example 1: version_compare('8.2.5rc', '8.2.5a'); + // * returns 1: 1 + // * example 2: version_compare('8.2.50', '8.2.52', '<'); + // * returns 2: true + // * example 3: version_compare('5.3.0-dev', '5.3.0'); + // * returns 3: -1 + // * example 4: version_compare('4.1.0.52','4.01.0.51'); + // * returns 4: 1 + + // Important: compare must be initialized at 0. + var i = 0, + x = 0, + compare = 0, + // vm maps textual PHP versions to negatives so they're less than 0. + // PHP currently defines these as CASE-SENSITIVE. It is important to + // leave these as negatives so that they can come before numerical versions + // and as if no letters were there to begin with. + // (1alpha is < 1 and < 1.1 but > 1dev1) + // If a non-numerical value can't be mapped to this table, it receives + // -7 as its value. + vm = { + 'dev': -6, + 'alpha': -5, + 'a': -5, + 'beta': -4, + 'b': -4, + 'RC': -3, + 'rc': -3, + '#': -2, + 'p': 1, + 'pl': 1 + }, + // This function will be called to prepare each version argument. + // It replaces every _, -, and + with a dot. + // It surrounds any nonsequence of numbers/dots with dots. + // It replaces sequences of dots with a single dot. + // version_compare('4..0', '4.0') == 0 + // Important: A string of 0 length needs to be converted into a value + // even less than an unexisting value in vm (-7), hence [-8]. + // It's also important to not strip spaces because of this. + // version_compare('', ' ') == 1 + prepVersion = function (v) { + v = ('' + v).replace(/[_\-+]/g, '.'); + v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.'); + return (!v.length ? [-8] : v.split('.')); + }, + // This converts a version component to a number. + // Empty component becomes 0. + // Non-numerical component becomes a negative number. + // Numerical component becomes itself as an integer. + numVersion = function (v) { + return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10)); + }; + + v1 = prepVersion(v1); + v2 = prepVersion(v2); + x = Math.max(v1.length, v2.length); + for (i = 0; i < x; i++) { + if (v1[i] == v2[i]) { + continue; + } + v1[i] = numVersion(v1[i]); + v2[i] = numVersion(v2[i]); + if (v1[i] < v2[i]) { + compare = -1; + break; + } else if (v1[i] > v2[i]) { + compare = 1; + break; + } + } + if (!operator) { + return compare; + } + + // Important: operator is CASE-SENSITIVE. + // "No operator" seems to be treated as "<." + // Any other values seem to make the function return null. + switch (operator) { + case '>': + case 'gt': + return (compare > 0); + case '>=': + case 'ge': + return (compare >= 0); + case '<=': + case 'le': + return (compare <= 0); + case '==': + case '=': + case 'eq': + return (compare === 0); + case '<>': + case '!=': + case 'ne': + return (compare !== 0); + case '': + case '<': + case 'lt': + return (compare < 0); + default: + return null; + } + } + + + var can = (function() { + var caps = { + define_property: (function() { + /* // currently too much extra code required, not exactly worth it + try { // as of IE8, getters/setters are supported only on DOM elements + var obj = {}; + if (Object.defineProperty) { + Object.defineProperty(obj, 'prop', { + enumerable: true, + configurable: true + }); + return true; + } + } catch(ex) {} + + if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) { + return true; + }*/ + return false; + }()), + + create_canvas: (function() { + // On the S60 and BB Storm, getContext exists, but always returns undefined + // so we actually have to call getContext() to verify + // github.com/Modernizr/Modernizr/issues/issue/97/ + var el = document.createElement('canvas'); + return !!(el.getContext && el.getContext('2d')); + }()), + + return_response_type: function(responseType) { + try { + if (Basic.inArray(responseType, ['', 'text', 'document']) !== -1) { + return true; + } else if (window.XMLHttpRequest) { + var xhr = new XMLHttpRequest(); + xhr.open('get', '/'); // otherwise Gecko throws an exception + if ('responseType' in xhr) { + xhr.responseType = responseType; + // as of 23.0.1271.64, Chrome switched from throwing exception to merely logging it to the console (why? o why?) + if (xhr.responseType !== responseType) { + return false; + } + return true; + } + } + } catch (ex) {} + return false; + }, + + // ideas for this heavily come from Modernizr (http://modernizr.com/) + use_data_uri: (function() { + var du = new Image(); + + du.onload = function() { + caps.use_data_uri = (du.width === 1 && du.height === 1); + }; + + setTimeout(function() { + du.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; + }, 1); + return false; + }()), + + use_data_uri_over32kb: function() { // IE8 + return caps.use_data_uri && (Env.browser !== 'IE' || Env.version >= 9); + }, + + use_data_uri_of: function(bytes) { + return (caps.use_data_uri && bytes < 33000 || caps.use_data_uri_over32kb()); + }, + + use_fileinput: function() { + var el = document.createElement('input'); + el.setAttribute('type', 'file'); + return !el.disabled; + } + }; + + return function(cap) { + var args = [].slice.call(arguments); + args.shift(); // shift of cap + return Basic.typeOf(caps[cap]) === 'function' ? caps[cap].apply(this, args) : !!caps[cap]; + }; + }()); + + + var Env = { + can: can, + + browser: UAParser.browser.name, + version: parseFloat(UAParser.browser.major), + os: UAParser.os.name, // everybody intuitively types it in a lowercase for some reason + osVersion: UAParser.os.version, + + verComp: version_compare, + + swf_url: "../flash/Moxie.swf", + xap_url: "../silverlight/Moxie.xap", + global_event_dispatcher: "moxie.core.EventTarget.instance.dispatchEvent" + }; + + // for backward compatibility + // @deprecated Use `Env.os` instead + Env.OS = Env.os; + + return Env; +}); + +// Included from: src/javascript/core/utils/Dom.js + +/** + * Dom.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Dom', ['moxie/core/utils/Env'], function(Env) { + + /** + Get DOM Element by it's id. + + @method get + @for Utils + @param {String} id Identifier of the DOM Element + @return {DOMElement} + */ + var get = function(id) { + if (typeof id !== 'string') { + return id; + } + return document.getElementById(id); + }; + + /** + Checks if specified DOM element has specified class. + + @method hasClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var hasClass = function(obj, name) { + if (!obj.className) { + return false; + } + + var regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)"); + return regExp.test(obj.className); + }; + + /** + Adds specified className to specified DOM element. + + @method addClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var addClass = function(obj, name) { + if (!hasClass(obj, name)) { + obj.className = !obj.className ? name : obj.className.replace(/\s+$/, '') + ' ' + name; + } + }; + + /** + Removes specified className from specified DOM element. + + @method removeClass + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Class name + */ + var removeClass = function(obj, name) { + if (obj.className) { + var regExp = new RegExp("(^|\\s+)"+name+"(\\s+|$)"); + obj.className = obj.className.replace(regExp, function($0, $1, $2) { + return $1 === ' ' && $2 === ' ' ? ' ' : ''; + }); + } + }; + + /** + Returns a given computed style of a DOM element. + + @method getStyle + @static + @param {Object} obj DOM element like object. + @param {String} name Style you want to get from the DOM element + */ + var getStyle = function(obj, name) { + if (obj.currentStyle) { + return obj.currentStyle[name]; + } else if (window.getComputedStyle) { + return window.getComputedStyle(obj, null)[name]; + } + }; + + + /** + Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields. + + @method getPos + @static + @param {Element} node HTML element or element id to get x, y position from. + @param {Element} root Optional root element to stop calculations at. + @return {object} Absolute position of the specified element object with x, y fields. + */ + var getPos = function(node, root) { + var x = 0, y = 0, parent, doc = document, nodeRect, rootRect; + + node = node; + root = root || doc.body; + + // Returns the x, y cordinate for an element on IE 6 and IE 7 + function getIEPos(node) { + var bodyElm, rect, x = 0, y = 0; + + if (node) { + rect = node.getBoundingClientRect(); + bodyElm = doc.compatMode === "CSS1Compat" ? doc.documentElement : doc.body; + x = rect.left + bodyElm.scrollLeft; + y = rect.top + bodyElm.scrollTop; + } + + return { + x : x, + y : y + }; + } + + // Use getBoundingClientRect on IE 6 and IE 7 but not on IE 8 in standards mode + if (node && node.getBoundingClientRect && Env.browser === 'IE' && (!doc.documentMode || doc.documentMode < 8)) { + nodeRect = getIEPos(node); + rootRect = getIEPos(root); + + return { + x : nodeRect.x - rootRect.x, + y : nodeRect.y - rootRect.y + }; + } + + parent = node; + while (parent && parent != root && parent.nodeType) { + x += parent.offsetLeft || 0; + y += parent.offsetTop || 0; + parent = parent.offsetParent; + } + + parent = node.parentNode; + while (parent && parent != root && parent.nodeType) { + x -= parent.scrollLeft || 0; + y -= parent.scrollTop || 0; + parent = parent.parentNode; + } + + return { + x : x, + y : y + }; + }; + + /** + Returns the size of the specified node in pixels. + + @method getSize + @static + @param {Node} node Node to get the size of. + @return {Object} Object with a w and h property. + */ + var getSize = function(node) { + return { + w : node.offsetWidth || node.clientWidth, + h : node.offsetHeight || node.clientHeight + }; + }; + + return { + get: get, + hasClass: hasClass, + addClass: addClass, + removeClass: removeClass, + getStyle: getStyle, + getPos: getPos, + getSize: getSize + }; +}); + +// Included from: src/javascript/core/Exceptions.js + +/** + * Exceptions.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/Exceptions', [ + 'moxie/core/utils/Basic' +], function(Basic) { + function _findKey(obj, value) { + var key; + for (key in obj) { + if (obj[key] === value) { + return key; + } + } + return null; + } + + return { + RuntimeError: (function() { + var namecodes = { + NOT_INIT_ERR: 1, + NOT_SUPPORTED_ERR: 9, + JS_ERR: 4 + }; + + function RuntimeError(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": RuntimeError " + this.code; + } + + Basic.extend(RuntimeError, namecodes); + RuntimeError.prototype = Error.prototype; + return RuntimeError; + }()), + + OperationNotAllowedException: (function() { + + function OperationNotAllowedException(code) { + this.code = code; + this.name = 'OperationNotAllowedException'; + } + + Basic.extend(OperationNotAllowedException, { + NOT_ALLOWED_ERR: 1 + }); + + OperationNotAllowedException.prototype = Error.prototype; + + return OperationNotAllowedException; + }()), + + ImageError: (function() { + var namecodes = { + WRONG_FORMAT: 1, + MAX_RESOLUTION_ERR: 2 + }; + + function ImageError(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": ImageError " + this.code; + } + + Basic.extend(ImageError, namecodes); + ImageError.prototype = Error.prototype; + + return ImageError; + }()), + + FileException: (function() { + var namecodes = { + NOT_FOUND_ERR: 1, + SECURITY_ERR: 2, + ABORT_ERR: 3, + NOT_READABLE_ERR: 4, + ENCODING_ERR: 5, + NO_MODIFICATION_ALLOWED_ERR: 6, + INVALID_STATE_ERR: 7, + SYNTAX_ERR: 8 + }; + + function FileException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": FileException " + this.code; + } + + Basic.extend(FileException, namecodes); + FileException.prototype = Error.prototype; + return FileException; + }()), + + DOMException: (function() { + var namecodes = { + INDEX_SIZE_ERR: 1, + DOMSTRING_SIZE_ERR: 2, + HIERARCHY_REQUEST_ERR: 3, + WRONG_DOCUMENT_ERR: 4, + INVALID_CHARACTER_ERR: 5, + NO_DATA_ALLOWED_ERR: 6, + NO_MODIFICATION_ALLOWED_ERR: 7, + NOT_FOUND_ERR: 8, + NOT_SUPPORTED_ERR: 9, + INUSE_ATTRIBUTE_ERR: 10, + INVALID_STATE_ERR: 11, + SYNTAX_ERR: 12, + INVALID_MODIFICATION_ERR: 13, + NAMESPACE_ERR: 14, + INVALID_ACCESS_ERR: 15, + VALIDATION_ERR: 16, + TYPE_MISMATCH_ERR: 17, + SECURITY_ERR: 18, + NETWORK_ERR: 19, + ABORT_ERR: 20, + URL_MISMATCH_ERR: 21, + QUOTA_EXCEEDED_ERR: 22, + TIMEOUT_ERR: 23, + INVALID_NODE_TYPE_ERR: 24, + DATA_CLONE_ERR: 25 + }; + + function DOMException(code) { + this.code = code; + this.name = _findKey(namecodes, code); + this.message = this.name + ": DOMException " + this.code; + } + + Basic.extend(DOMException, namecodes); + DOMException.prototype = Error.prototype; + return DOMException; + }()), + + EventException: (function() { + function EventException(code) { + this.code = code; + this.name = 'EventException'; + } + + Basic.extend(EventException, { + UNSPECIFIED_EVENT_TYPE_ERR: 0 + }); + + EventException.prototype = Error.prototype; + + return EventException; + }()) + }; +}); + +// Included from: src/javascript/core/EventTarget.js + +/** + * EventTarget.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/EventTarget', [ + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic' +], function(x, Basic) { + /** + Parent object for all event dispatching components and objects + + @class EventTarget + @constructor EventTarget + */ + function EventTarget() { + // hash of event listeners by object uid + var eventpool = {}; + + Basic.extend(this, { + + /** + Unique id of the event dispatcher, usually overriden by children + + @property uid + @type String + */ + uid: null, + + /** + Can be called from within a child in order to acquire uniqie id in automated manner + + @method init + */ + init: function() { + if (!this.uid) { + this.uid = Basic.guid('uid_'); + } + }, + + /** + Register a handler to a specific event dispatched by the object + + @method addEventListener + @param {String} type Type or basically a name of the event to subscribe to + @param {Function} fn Callback function that will be called when event happens + @param {Number} [priority=0] Priority of the event handler - handlers with higher priorities will be called first + @param {Object} [scope=this] A scope to invoke event handler in + */ + addEventListener: function(type, fn, priority, scope) { + var self = this, list; + + type = Basic.trim(type); + + if (/\s/.test(type)) { + // multiple event types were passed for one handler + Basic.each(type.split(/\s+/), function(type) { + self.addEventListener(type, fn, priority, scope); + }); + return; + } + + type = type.toLowerCase(); + priority = parseInt(priority, 10) || 0; + + list = eventpool[this.uid] && eventpool[this.uid][type] || []; + list.push({fn : fn, priority : priority, scope : scope || this}); + + if (!eventpool[this.uid]) { + eventpool[this.uid] = {}; + } + eventpool[this.uid][type] = list; + }, + + /** + Check if any handlers were registered to the specified event + + @method hasEventListener + @param {String} type Type or basically a name of the event to check + @return {Mixed} Returns a handler if it was found and false, if - not + */ + hasEventListener: function(type) { + return type ? !!(eventpool[this.uid] && eventpool[this.uid][type]) : !!eventpool[this.uid]; + }, + + /** + Unregister the handler from the event, or if former was not specified - unregister all handlers + + @method removeEventListener + @param {String} type Type or basically a name of the event + @param {Function} [fn] Handler to unregister + */ + removeEventListener: function(type, fn) { + type = type.toLowerCase(); + + var list = eventpool[this.uid] && eventpool[this.uid][type], i; + + if (list) { + if (fn) { + for (i = list.length - 1; i >= 0; i--) { + if (list[i].fn === fn) { + list.splice(i, 1); + break; + } + } + } else { + list = []; + } + + // delete event list if it has become empty + if (!list.length) { + delete eventpool[this.uid][type]; + + // and object specific entry in a hash if it has no more listeners attached + if (Basic.isEmptyObj(eventpool[this.uid])) { + delete eventpool[this.uid]; + } + } + } + }, + + /** + Remove all event handlers from the object + + @method removeAllEventListeners + */ + removeAllEventListeners: function() { + if (eventpool[this.uid]) { + delete eventpool[this.uid]; + } + }, + + /** + Dispatch the event + + @method dispatchEvent + @param {String/Object} Type of event or event object to dispatch + @param {Mixed} [...] Variable number of arguments to be passed to a handlers + @return {Boolean} true by default and false if any handler returned false + */ + dispatchEvent: function(type) { + var uid, list, args, tmpEvt, evt = {}, result = true, undef; + + if (Basic.typeOf(type) !== 'string') { + // we can't use original object directly (because of Silverlight) + tmpEvt = type; + + if (Basic.typeOf(tmpEvt.type) === 'string') { + type = tmpEvt.type; + + if (tmpEvt.total !== undef && tmpEvt.loaded !== undef) { // progress event + evt.total = tmpEvt.total; + evt.loaded = tmpEvt.loaded; + } + evt.async = tmpEvt.async || false; + } else { + throw new x.EventException(x.EventException.UNSPECIFIED_EVENT_TYPE_ERR); + } + } + + // check if event is meant to be dispatched on an object having specific uid + if (type.indexOf('::') !== -1) { + (function(arr) { + uid = arr[0]; + type = arr[1]; + }(type.split('::'))); + } else { + uid = this.uid; + } + + type = type.toLowerCase(); + + list = eventpool[uid] && eventpool[uid][type]; + + if (list) { + // sort event list by prority + list.sort(function(a, b) { return b.priority - a.priority; }); + + args = [].slice.call(arguments); + + // first argument will be pseudo-event object + args.shift(); + evt.type = type; + args.unshift(evt); + + // Dispatch event to all listeners + var queue = []; + Basic.each(list, function(handler) { + // explicitly set the target, otherwise events fired from shims do not get it + args[0].target = handler.scope; + // if event is marked as async, detach the handler + if (evt.async) { + queue.push(function(cb) { + setTimeout(function() { + cb(handler.fn.apply(handler.scope, args) === false); + }, 1); + }); + } else { + queue.push(function(cb) { + cb(handler.fn.apply(handler.scope, args) === false); // if handler returns false stop propagation + }); + } + }); + if (queue.length) { + Basic.inSeries(queue, function(err) { + result = !err; + }); + } + } + return result; + }, + + /** + Alias for addEventListener + + @method bind + @protected + */ + bind: function() { + this.addEventListener.apply(this, arguments); + }, + + /** + Alias for removeEventListener + + @method unbind + @protected + */ + unbind: function() { + this.removeEventListener.apply(this, arguments); + }, + + /** + Alias for removeAllEventListeners + + @method unbindAll + @protected + */ + unbindAll: function() { + this.removeAllEventListeners.apply(this, arguments); + }, + + /** + Alias for dispatchEvent + + @method trigger + @protected + */ + trigger: function() { + return this.dispatchEvent.apply(this, arguments); + }, + + + /** + Converts properties of on[event] type to corresponding event handlers, + is used to avoid extra hassle around the process of calling them back + + @method convertEventPropsToHandlers + @private + */ + convertEventPropsToHandlers: function(handlers) { + var h; + + if (Basic.typeOf(handlers) !== 'array') { + handlers = [handlers]; + } + + for (var i = 0; i < handlers.length; i++) { + h = 'on' + handlers[i]; + + if (Basic.typeOf(this[h]) === 'function') { + this.addEventListener(handlers[i], this[h]); + } else if (Basic.typeOf(this[h]) === 'undefined') { + this[h] = null; // object must have defined event properties, even if it doesn't make use of them + } + } + } + + }); + } + + EventTarget.instance = new EventTarget(); + + return EventTarget; +}); + +// Included from: src/javascript/core/utils/Encode.js + +/** + * Encode.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Encode', [], function() { + + /** + Encode string with UTF-8 + + @method utf8_encode + @for Utils + @static + @param {String} str String to encode + @return {String} UTF-8 encoded string + */ + var utf8_encode = function(str) { + return unescape(encodeURIComponent(str)); + }; + + /** + Decode UTF-8 encoded string + + @method utf8_decode + @static + @param {String} str String to decode + @return {String} Decoded string + */ + var utf8_decode = function(str_data) { + return decodeURIComponent(escape(str_data)); + }; + + /** + Decode Base64 encoded string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_decode.js + + @method atob + @static + @param {String} data String to decode + @return {String} Decoded string + */ + var atob = function(data, utf8) { + if (typeof(window.atob) === 'function') { + return utf8 ? utf8_decode(window.atob(data)) : window.atob(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Thunder.m + // + input by: Aman Gupta + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Onno Marsman + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA=='); + // * returns 1: 'Kevin van Zonneveld' + // mozilla has this native + // - but breaks in 2.0.0.12! + //if (typeof this.window.atob == 'function') { + // return atob(data); + //} + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + dec = "", + tmp_arr = []; + + if (!data) { + return data; + } + + data += ''; + + do { // unpack four hexets into three octets using index points in b64 + h1 = b64.indexOf(data.charAt(i++)); + h2 = b64.indexOf(data.charAt(i++)); + h3 = b64.indexOf(data.charAt(i++)); + h4 = b64.indexOf(data.charAt(i++)); + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; + + o1 = bits >> 16 & 0xff; + o2 = bits >> 8 & 0xff; + o3 = bits & 0xff; + + if (h3 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1); + } else if (h4 == 64) { + tmp_arr[ac++] = String.fromCharCode(o1, o2); + } else { + tmp_arr[ac++] = String.fromCharCode(o1, o2, o3); + } + } while (i < data.length); + + dec = tmp_arr.join(''); + + return utf8 ? utf8_decode(dec) : dec; + }; + + /** + Base64 encode string (uses browser's default method if available), + from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_encode.js + + @method btoa + @static + @param {String} data String to encode + @return {String} Base64 encoded string + */ + var btoa = function(data, utf8) { + if (utf8) { + utf8_encode(data); + } + + if (typeof(window.btoa) === 'function') { + return window.btoa(data); + } + + // http://kevin.vanzonneveld.net + // + original by: Tyler Akins (http://rumkin.com) + // + improved by: Bayron Guevara + // + improved by: Thunder.m + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + bugfixed by: Pellentesque Malesuada + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Rafał Kukawski (http://kukawski.pl) + // * example 1: base64_encode('Kevin van Zonneveld'); + // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA==' + // mozilla has this native + // - but breaks in 2.0.0.12! + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, + ac = 0, + enc = "", + tmp_arr = []; + + if (!data) { + return data; + } + + do { // pack three octets into four hexets + o1 = data.charCodeAt(i++); + o2 = data.charCodeAt(i++); + o3 = data.charCodeAt(i++); + + bits = o1 << 16 | o2 << 8 | o3; + + h1 = bits >> 18 & 0x3f; + h2 = bits >> 12 & 0x3f; + h3 = bits >> 6 & 0x3f; + h4 = bits & 0x3f; + + // use hexets to index into b64, and append result to encoded string + tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4); + } while (i < data.length); + + enc = tmp_arr.join(''); + + var r = data.length % 3; + + return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3); + }; + + + return { + utf8_encode: utf8_encode, + utf8_decode: utf8_decode, + atob: atob, + btoa: btoa + }; +}); + +// Included from: src/javascript/runtime/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/Runtime', [ + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/EventTarget" +], function(Basic, Dom, EventTarget) { + var runtimeConstructors = {}, runtimes = {}; + + /** + Common set of methods and properties for every runtime instance + + @class Runtime + + @param {Object} options + @param {String} type Sanitized name of the runtime + @param {Object} [caps] Set of capabilities that differentiate specified runtime + @param {Object} [modeCaps] Set of capabilities that do require specific operational mode + @param {String} [preferredMode='browser'] Preferred operational mode to choose if no required capabilities were requested + */ + function Runtime(options, type, caps, modeCaps, preferredMode) { + /** + Dispatched when runtime is initialized and ready. + Results in RuntimeInit on a connected component. + + @event Init + */ + + /** + Dispatched when runtime fails to initialize. + Results in RuntimeError on a connected component. + + @event Error + */ + + var self = this + , _shim + , _uid = Basic.guid(type + '_') + , defaultMode = preferredMode || 'browser' + ; + + options = options || {}; + + // register runtime in private hash + runtimes[_uid] = this; + + /** + Default set of capabilities, which can be redifined later by specific runtime + + @private + @property caps + @type Object + */ + caps = Basic.extend({ + // Runtime can: + // provide access to raw binary data of the file + access_binary: false, + // provide access to raw binary data of the image (image extension is optional) + access_image_binary: false, + // display binary data as thumbs for example + display_media: false, + // make cross-domain requests + do_cors: false, + // accept files dragged and dropped from the desktop + drag_and_drop: false, + // filter files in selection dialog by their extensions + filter_by_extension: true, + // resize image (and manipulate it raw data of any file in general) + resize_image: false, + // periodically report how many bytes of total in the file were uploaded (loaded) + report_upload_progress: false, + // provide access to the headers of http response + return_response_headers: false, + // support response of specific type, which should be passed as an argument + // e.g. runtime.can('return_response_type', 'blob') + return_response_type: false, + // return http status code of the response + return_status_code: true, + // send custom http header with the request + send_custom_headers: false, + // pick up the files from a dialog + select_file: false, + // select whole folder in file browse dialog + select_folder: false, + // select multiple files at once in file browse dialog + select_multiple: true, + // send raw binary data, that is generated after image resizing or manipulation of other kind + send_binary_string: false, + // send cookies with http request and therefore retain session + send_browser_cookies: true, + // send data formatted as multipart/form-data + send_multipart: true, + // slice the file or blob to smaller parts + slice_blob: false, + // upload file without preloading it to memory, stream it out directly from disk + stream_upload: false, + // programmatically trigger file browse dialog + summon_file_dialog: false, + // upload file of specific size, size should be passed as argument + // e.g. runtime.can('upload_filesize', '500mb') + upload_filesize: true, + // initiate http request with specific http method, method should be passed as argument + // e.g. runtime.can('use_http_method', 'put') + use_http_method: true + }, caps); + + + // default to the mode that is compatible with preferred caps + if (options.preferred_caps) { + defaultMode = Runtime.getMode(modeCaps, options.preferred_caps, defaultMode); + } + + // small extension factory here (is meant to be extended with actual extensions constructors) + _shim = (function() { + var objpool = {}; + return { + exec: function(uid, comp, fn, args) { + if (_shim[comp]) { + if (!objpool[uid]) { + objpool[uid] = { + context: this, + instance: new _shim[comp]() + }; + } + if (objpool[uid].instance[fn]) { + return objpool[uid].instance[fn].apply(this, args); + } + } + }, + + removeInstance: function(uid) { + delete objpool[uid]; + }, + + removeAllInstances: function() { + var self = this; + Basic.each(objpool, function(obj, uid) { + if (Basic.typeOf(obj.instance.destroy) === 'function') { + obj.instance.destroy.call(obj.context); + } + self.removeInstance(uid); + }); + } + }; + }()); + + + // public methods + Basic.extend(this, { + /** + Specifies whether runtime instance was initialized or not + + @property initialized + @type {Boolean} + @default false + */ + initialized: false, // shims require this flag to stop initialization retries + + /** + Unique ID of the runtime + + @property uid + @type {String} + */ + uid: _uid, + + /** + Runtime type (e.g. flash, html5, etc) + + @property type + @type {String} + */ + type: type, + + /** + Runtime (not native one) may operate in browser or client mode. + + @property mode + @private + @type {String|Boolean} current mode or false, if none possible + */ + mode: Runtime.getMode(modeCaps, (options.required_caps), defaultMode), + + /** + id of the DOM container for the runtime (if available) + + @property shimid + @type {String} + */ + shimid: _uid + '_container', + + /** + Number of connected clients. If equal to zero, runtime can be destroyed + + @property clients + @type {Number} + */ + clients: 0, + + /** + Runtime initialization options + + @property options + @type {Object} + */ + options: options, + + /** + Checks if the runtime has specific capability + + @method can + @param {String} cap Name of capability to check + @param {Mixed} [value] If passed, capability should somehow correlate to the value + @param {Object} [refCaps] Set of capabilities to check the specified cap against (defaults to internal set) + @return {Boolean} true if runtime has such capability and false, if - not + */ + can: function(cap, value) { + var refCaps = arguments[2] || caps; + + // if cap var is a comma-separated list of caps, convert it to object (key/value) + if (Basic.typeOf(cap) === 'string' && Basic.typeOf(value) === 'undefined') { + cap = Runtime.parseCaps(cap); + } + + if (Basic.typeOf(cap) === 'object') { + for (var key in cap) { + if (!this.can(key, cap[key], refCaps)) { + return false; + } + } + return true; + } + + // check the individual cap + if (Basic.typeOf(refCaps[cap]) === 'function') { + return refCaps[cap].call(this, value); + } else { + return (value === refCaps[cap]); + } + }, + + /** + Returns container for the runtime as DOM element + + @method getShimContainer + @return {DOMElement} + */ + getShimContainer: function() { + var container, shimContainer = Dom.get(this.shimid); + + // if no container for shim, create one + if (!shimContainer) { + container = this.options.container ? Dom.get(this.options.container) : document.body; + + // create shim container and insert it at an absolute position into the outer container + shimContainer = document.createElement('div'); + shimContainer.id = this.shimid; + shimContainer.className = 'moxie-shim moxie-shim-' + this.type; + + Basic.extend(shimContainer.style, { + position: 'absolute', + top: '0px', + left: '0px', + width: '1px', + height: '1px', + overflow: 'hidden' + }); + + container.appendChild(shimContainer); + container = null; + } + + return shimContainer; + }, + + /** + Returns runtime as DOM element (if appropriate) + + @method getShim + @return {DOMElement} + */ + getShim: function() { + return _shim; + }, + + /** + Invokes a method within the runtime itself (might differ across the runtimes) + + @method shimExec + @param {Mixed} [] + @protected + @return {Mixed} Depends on the action and component + */ + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return self.getShim().exec.call(this, this.uid, component, action, args); + }, + + /** + Operaional interface that is used by components to invoke specific actions on the runtime + (is invoked in the scope of component) + + @method exec + @param {Mixed} []* + @protected + @return {Mixed} Depends on the action and component + */ + exec: function(component, action) { // this is called in the context of component, not runtime + var args = [].slice.call(arguments, 2); + + if (self[component] && self[component][action]) { + return self[component][action].apply(this, args); + } + return self.shimExec.apply(this, arguments); + }, + + /** + Destroys the runtime (removes all events and deletes DOM structures) + + @method destroy + */ + destroy: function() { + if (!self) { + return; // obviously already destroyed + } + + var shimContainer = Dom.get(this.shimid); + if (shimContainer) { + shimContainer.parentNode.removeChild(shimContainer); + } + + if (_shim) { + _shim.removeAllInstances(); + } + + this.unbindAll(); + delete runtimes[this.uid]; + this.uid = null; // mark this runtime as destroyed + _uid = self = _shim = shimContainer = null; + } + }); + + // once we got the mode, test against all caps + if (this.mode && options.required_caps && !this.can(options.required_caps)) { + this.mode = false; + } + } + + + /** + Default order to try different runtime types + + @property order + @type String + @static + */ + Runtime.order = 'html5,flash,silverlight,html4'; + + + /** + Retrieves runtime from private hash by it's uid + + @method getRuntime + @private + @static + @param {String} uid Unique identifier of the runtime + @return {Runtime|Boolean} Returns runtime, if it exists and false, if - not + */ + Runtime.getRuntime = function(uid) { + return runtimes[uid] ? runtimes[uid] : false; + }; + + + /** + Register constructor for the Runtime of new (or perhaps modified) type + + @method addConstructor + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @param {Function} construct Constructor for the Runtime type + */ + Runtime.addConstructor = function(type, constructor) { + constructor.prototype = EventTarget.instance; + runtimeConstructors[type] = constructor; + }; + + + /** + Get the constructor for the specified type. + + method getConstructor + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @return {Function} Constructor for the Runtime type + */ + Runtime.getConstructor = function(type) { + return runtimeConstructors[type] || null; + }; + + + /** + Get info about the runtime (uid, type, capabilities) + + @method getInfo + @static + @param {String} uid Unique identifier of the runtime + @return {Mixed} Info object or null if runtime doesn't exist + */ + Runtime.getInfo = function(uid) { + var runtime = Runtime.getRuntime(uid); + + if (runtime) { + return { + uid: runtime.uid, + type: runtime.type, + mode: runtime.mode, + can: function() { + return runtime.can.apply(runtime, arguments); + } + }; + } + return null; + }; + + + /** + Convert caps represented by a comma-separated string to the object representation. + + @method parseCaps + @static + @param {String} capStr Comma-separated list of capabilities + @return {Object} + */ + Runtime.parseCaps = function(capStr) { + var capObj = {}; + + if (Basic.typeOf(capStr) !== 'string') { + return capStr || {}; + } + + Basic.each(capStr.split(','), function(key) { + capObj[key] = true; // we assume it to be - true + }); + + return capObj; + }; + + /** + Test the specified runtime for specific capabilities. + + @method can + @static + @param {String} type Runtime type (e.g. flash, html5, etc) + @param {String|Object} caps Set of capabilities to check + @return {Boolean} Result of the test + */ + Runtime.can = function(type, caps) { + var runtime + , constructor = Runtime.getConstructor(type) + , mode + ; + if (constructor) { + runtime = new constructor({ + required_caps: caps + }); + mode = runtime.mode; + runtime.destroy(); + return !!mode; + } + return false; + }; + + + /** + Figure out a runtime that supports specified capabilities. + + @method thatCan + @static + @param {String|Object} caps Set of capabilities to check + @param {String} [runtimeOrder] Comma-separated list of runtimes to check against + @return {String} Usable runtime identifier or null + */ + Runtime.thatCan = function(caps, runtimeOrder) { + var types = (runtimeOrder || Runtime.order).split(/\s*,\s*/); + for (var i in types) { + if (Runtime.can(types[i], caps)) { + return types[i]; + } + } + return null; + }; + + + /** + Figure out an operational mode for the specified set of capabilities. + + @method getMode + @static + @param {Object} modeCaps Set of capabilities that depend on particular runtime mode + @param {Object} [requiredCaps] Supplied set of capabilities to find operational mode for + @param {String|Boolean} [defaultMode='browser'] Default mode to use + @return {String|Boolean} Compatible operational mode + */ + Runtime.getMode = function(modeCaps, requiredCaps, defaultMode) { + var mode = null; + + if (Basic.typeOf(defaultMode) === 'undefined') { // only if not specified + defaultMode = 'browser'; + } + + if (requiredCaps && !Basic.isEmptyObj(modeCaps)) { + // loop over required caps and check if they do require the same mode + Basic.each(requiredCaps, function(value, cap) { + if (modeCaps.hasOwnProperty(cap)) { + var capMode = modeCaps[cap](value); + + // make sure we always have an array + if (typeof(capMode) === 'string') { + capMode = [capMode]; + } + + if (!mode) { + mode = capMode; + } else if (!(mode = Basic.arrayIntersect(mode, capMode))) { + // if cap requires conflicting mode - runtime cannot fulfill required caps + return (mode = false); + } + } + }); + + if (mode) { + return Basic.inArray(defaultMode, mode) !== -1 ? defaultMode : mode[0]; + } else if (mode === false) { + return false; + } + } + return defaultMode; + }; + + + /** + Capability check that always returns true + + @private + @static + @return {True} + */ + Runtime.capTrue = function() { + return true; + }; + + /** + Capability check that always returns false + + @private + @static + @return {False} + */ + Runtime.capFalse = function() { + return false; + }; + + /** + Evaluate the expression to boolean value and create a function that always returns it. + + @private + @static + @param {Mixed} expr Expression to evaluate + @return {Function} Function returning the result of evaluation + */ + Runtime.capTest = function(expr) { + return function() { + return !!expr; + }; + }; + + return Runtime; +}); + +// Included from: src/javascript/runtime/RuntimeClient.js + +/** + * RuntimeClient.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/RuntimeClient', [ + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic', + 'moxie/runtime/Runtime' +], function(x, Basic, Runtime) { + /** + Set of methods and properties, required by a component to acquire ability to connect to a runtime + + @class RuntimeClient + */ + return function RuntimeClient() { + var runtime; + + Basic.extend(this, { + /** + Connects to the runtime specified by the options. Will either connect to existing runtime or create a new one. + Increments number of clients connected to the specified runtime. + + @method connectRuntime + @param {Mixed} options Can be a runtme uid or a set of key-value pairs defining requirements and pre-requisites + */ + connectRuntime: function(options) { + var comp = this, ruid; + + function initialize(items) { + var type, constructor; + + // if we ran out of runtimes + if (!items.length) { + comp.trigger('RuntimeError', new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + runtime = null; + return; + } + + type = items.shift(); + constructor = Runtime.getConstructor(type); + if (!constructor) { + initialize(items); + return; + } + + // try initializing the runtime + runtime = new constructor(options); + + runtime.bind('Init', function() { + // mark runtime as initialized + runtime.initialized = true; + + // jailbreak ... + setTimeout(function() { + runtime.clients++; + // this will be triggered on component + comp.trigger('RuntimeInit', runtime); + }, 1); + }); + + runtime.bind('Error', function() { + runtime.destroy(); // runtime cannot destroy itself from inside at a right moment, thus we do it here + initialize(items); + }); + + /*runtime.bind('Exception', function() { });*/ + + // check if runtime managed to pick-up operational mode + if (!runtime.mode) { + runtime.trigger('Error'); + return; + } + + runtime.init(); + } + + // check if a particular runtime was requested + if (Basic.typeOf(options) === 'string') { + ruid = options; + } else if (Basic.typeOf(options.ruid) === 'string') { + ruid = options.ruid; + } + + if (ruid) { + runtime = Runtime.getRuntime(ruid); + if (runtime) { + runtime.clients++; + return runtime; + } else { + // there should be a runtime and there's none - weird case + throw new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR); + } + } + + // initialize a fresh one, that fits runtime list and required features best + initialize((options.runtime_order || Runtime.order).split(/\s*,\s*/)); + }, + + /** + Returns the runtime to which the client is currently connected. + + @method getRuntime + @return {Runtime} Runtime or null if client is not connected + */ + getRuntime: function() { + if (runtime && runtime.uid) { + return runtime; + } + runtime = null; // make sure we do not leave zombies rambling around + return null; + }, + + /** + Disconnects from the runtime. Decrements number of clients connected to the specified runtime. + + @method disconnectRuntime + */ + disconnectRuntime: function() { + if (runtime && --runtime.clients <= 0) { + runtime.destroy(); + runtime = null; + } + } + + }); + }; + + +}); + +// Included from: src/javascript/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/Blob', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Encode', + 'moxie/runtime/RuntimeClient' +], function(Basic, Encode, RuntimeClient) { + + var blobpool = {}; + + /** + @class Blob + @constructor + @param {String} ruid Unique id of the runtime, to which this blob belongs to + @param {Object} blob Object "Native" blob object, as it is represented in the runtime + */ + function Blob(ruid, blob) { + + function _sliceDetached(start, end, type) { + var blob, data = blobpool[this.uid]; + + if (Basic.typeOf(data) !== 'string' || !data.length) { + return null; // or throw exception + } + + blob = new Blob(null, { + type: type, + size: end - start + }); + blob.detach(data.substr(start, blob.size)); + + return blob; + } + + RuntimeClient.call(this); + + if (ruid) { + this.connectRuntime(ruid); + } + + if (!blob) { + blob = {}; + } else if (Basic.typeOf(blob) === 'string') { // dataUrl or binary string + blob = { data: blob }; + } + + Basic.extend(this, { + + /** + Unique id of the component + + @property uid + @type {String} + */ + uid: blob.uid || Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if falsy, then runtime will have to be initialized + before this Blob can be used, modified or sent + + @property ruid + @type {String} + */ + ruid: ruid, + + /** + Size of blob + + @property size + @type {Number} + @default 0 + */ + size: blob.size || 0, + + /** + Mime type of blob + + @property type + @type {String} + @default '' + */ + type: blob.type || '', + + /** + @method slice + @param {Number} [start=0] + */ + slice: function(start, end, type) { + if (this.isDetached()) { + return _sliceDetached.apply(this, arguments); + } + return this.getRuntime().exec.call(this, 'Blob', 'slice', this.getSource(), start, end, type); + }, + + /** + Returns "native" blob object (as it is represented in connected runtime) or null if not found + + @method getSource + @return {Blob} Returns "native" blob object or null if not found + */ + getSource: function() { + if (!blobpool[this.uid]) { + return null; + } + return blobpool[this.uid]; + }, + + /** + Detaches blob from any runtime that it depends on and initialize with standalone value + + @method detach + @protected + @param {DOMString} [data=''] Standalone value + */ + detach: function(data) { + if (this.ruid) { + this.getRuntime().exec.call(this, 'Blob', 'destroy'); + this.disconnectRuntime(); + this.ruid = null; + } + + data = data || ''; + + // if dataUrl, convert to binary string + var matches = data.match(/^data:([^;]*);base64,/); + if (matches) { + this.type = matches[1]; + data = Encode.atob(data.substring(data.indexOf('base64,') + 7)); + } + + this.size = data.length; + + blobpool[this.uid] = data; + }, + + /** + Checks if blob is standalone (detached of any runtime) + + @method isDetached + @protected + @return {Boolean} + */ + isDetached: function() { + return !this.ruid && Basic.typeOf(blobpool[this.uid]) === 'string'; + }, + + /** + Destroy Blob and free any resources it was using + + @method destroy + */ + destroy: function() { + this.detach(); + delete blobpool[this.uid]; + } + }); + + + if (blob.data) { + this.detach(blob.data); // auto-detach if payload has been passed + } else { + blobpool[this.uid] = blob; + } + } + + return Blob; +}); + +// Included from: src/javascript/file/File.js + +/** + * File.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/File', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Mime', + 'moxie/file/Blob' +], function(Basic, Mime, Blob) { + /** + @class File + @extends Blob + @constructor + @param {String} ruid Unique id of the runtime, to which this blob belongs to + @param {Object} file Object "Native" file object, as it is represented in the runtime + */ + function File(ruid, file) { + var name, type; + + if (!file) { // avoid extra errors in case we overlooked something + file = {}; + } + + // figure out the type + if (file.type && file.type !== '') { + type = file.type; + } else { + type = Mime.getFileMime(file.name); + } + + // sanitize file name or generate new one + if (file.name) { + name = file.name.replace(/\\/g, '/'); + name = name.substr(name.lastIndexOf('/') + 1); + } else { + var prefix = type.split('/')[0]; + name = Basic.guid((prefix !== '' ? prefix : 'file') + '_'); + + if (Mime.extensions[type]) { + name += '.' + Mime.extensions[type][0]; // append proper extension if possible + } + } + + Blob.apply(this, arguments); + + Basic.extend(this, { + /** + File mime type + + @property type + @type {String} + @default '' + */ + type: type || '', + + /** + File name + + @property name + @type {String} + @default UID + */ + name: name || Basic.guid('file_'), + + /** + Date of last modification + + @property lastModifiedDate + @type {String} + @default now + */ + lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString() // Thu Aug 23 2012 19:40:00 GMT+0400 (GET) + }); + } + + File.prototype = Blob.prototype; + + return File; +}); + +// Included from: src/javascript/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileInput', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Mime', + 'moxie/core/utils/Dom', + 'moxie/core/Exceptions', + 'moxie/core/EventTarget', + 'moxie/core/I18n', + 'moxie/file/File', + 'moxie/runtime/Runtime', + 'moxie/runtime/RuntimeClient' +], function(Basic, Mime, Dom, x, EventTarget, I18n, File, Runtime, RuntimeClient) { + /** + Provides a convenient way to create cross-browser file-picker. Generates file selection dialog on click, + converts selected files to _File_ objects, to be used in conjunction with _Image_, preloaded in memory + with _FileReader_ or uploaded to a server through _XMLHttpRequest_. + + @class FileInput + @constructor + @extends EventTarget + @uses RuntimeClient + @param {Object|String|DOMElement} options If options is string or node, argument is considered as _browse\_button_. + @param {String|DOMElement} options.browse_button DOM Element to turn into file picker. + @param {Array} [options.accept] Array of mime types to accept. By default accepts all. + @param {String} [options.file='file'] Name of the file field (not the filename). + @param {Boolean} [options.multiple=false] Enable selection of multiple files. + @param {Boolean} [options.directory=false] Turn file input into the folder input (cannot be both at the same time). + @param {String|DOMElement} [options.container] DOM Element to use as a container for file-picker. Defaults to parentNode + for _browse\_button_. + @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support. + + @example + <div id="container"> + <a id="file-picker" href="javascript:;">Browse...</a> + </div> + + <script> + var fileInput = new mOxie.FileInput({ + browse_button: 'file-picker', // or document.getElementById('file-picker') + container: 'container', + accept: [ + {title: "Image files", extensions: "jpg,gif,png"} // accept only images + ], + multiple: true // allow multiple file selection + }); + + fileInput.onchange = function(e) { + // do something to files array + console.info(e.target.files); // or this.files or fileInput.files + }; + + fileInput.init(); // initialize + </script> + */ + var dispatches = [ + /** + Dispatched when runtime is connected and file-picker is ready to be used. + + @event ready + @param {Object} event + */ + 'ready', + + /** + Dispatched right after [ready](#event_ready) event, and whenever [refresh()](#method_refresh) is invoked. + Check [corresponding documentation entry](#method_refresh) for more info. + + @event refresh + @param {Object} event + */ + + /** + Dispatched when selection of files in the dialog is complete. + + @event change + @param {Object} event + */ + 'change', + + 'cancel', // TODO: might be useful + + /** + Dispatched when mouse cursor enters file-picker area. Can be used to style element + accordingly. + + @event mouseenter + @param {Object} event + */ + 'mouseenter', + + /** + Dispatched when mouse cursor leaves file-picker area. Can be used to style element + accordingly. + + @event mouseleave + @param {Object} event + */ + 'mouseleave', + + /** + Dispatched when functional mouse button is pressed on top of file-picker area. + + @event mousedown + @param {Object} event + */ + 'mousedown', + + /** + Dispatched when functional mouse button is released on top of file-picker area. + + @event mouseup + @param {Object} event + */ + 'mouseup' + ]; + + function FileInput(options) { + var self = this, + container, browseButton, defaults; + + // if flat argument passed it should be browse_button id + if (Basic.inArray(Basic.typeOf(options), ['string', 'node']) !== -1) { + options = { browse_button : options }; + } + + // this will help us to find proper default container + browseButton = Dom.get(options.browse_button); + if (!browseButton) { + // browse button is required + throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); + } + + // figure out the options + defaults = { + accept: [{ + title: I18n.translate('All Files'), + extensions: '*' + }], + name: 'file', + multiple: false, + required_caps: false, + container: browseButton.parentNode || document.body + }; + + options = Basic.extend({}, defaults, options); + + // convert to object representation + if (typeof(options.required_caps) === 'string') { + options.required_caps = Runtime.parseCaps(options.required_caps); + } + + // normalize accept option (could be list of mime types or array of title/extensions pairs) + if (typeof(options.accept) === 'string') { + options.accept = Mime.mimes2extList(options.accept); + } + + container = Dom.get(options.container); + // make sure we have container + if (!container) { + container = document.body; + } + + // make container relative, if it's not + if (Dom.getStyle(container, 'position') === 'static') { + container.style.position = 'relative'; + } + + container = browseButton = null; // IE + + RuntimeClient.call(self); + + Basic.extend(self, { + /** + Unique id of the component + + @property uid + @protected + @readOnly + @type {String} + @default UID + */ + uid: Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if any. + + @property ruid + @protected + @type {String} + */ + ruid: null, + + /** + Unique id of the runtime container. Useful to get hold of it for various manipulations. + + @property shimid + @protected + @type {String} + */ + shimid: null, + + /** + Array of selected mOxie.File objects + + @property files + @type {Array} + @default null + */ + files: null, + + /** + Initializes the file-picker, connects it to runtime and dispatches event ready when done. + + @method init + */ + init: function() { + self.convertEventPropsToHandlers(dispatches); + + self.bind('RuntimeInit', function(e, runtime) { + self.ruid = runtime.uid; + self.shimid = runtime.shimid; + + self.bind("Ready", function() { + self.trigger("Refresh"); + }, 999); + + self.bind("Change", function() { + var files = runtime.exec.call(self, 'FileInput', 'getFiles'); + + self.files = []; + + Basic.each(files, function(file) { + // ignore empty files (IE10 for example hangs if you try to send them via XHR) + if (file.size === 0) { + return true; + } + self.files.push(new File(self.ruid, file)); + }); + }, 999); + + // re-position and resize shim container + self.bind('Refresh', function() { + var pos, size, browseButton, shimContainer; + + browseButton = Dom.get(options.browse_button); + shimContainer = Dom.get(runtime.shimid); // do not use runtime.getShimContainer(), since it will create container if it doesn't exist + + if (browseButton) { + pos = Dom.getPos(browseButton, Dom.get(options.container)); + size = Dom.getSize(browseButton); + + if (shimContainer) { + Basic.extend(shimContainer.style, { + top : pos.y + 'px', + left : pos.x + 'px', + width : size.w + 'px', + height : size.h + 'px' + }); + } + } + shimContainer = browseButton = null; + }); + + runtime.exec.call(self, 'FileInput', 'init', options); + }); + + // runtime needs: options.required_features, options.runtime_order and options.container + self.connectRuntime(Basic.extend({}, options, { + required_caps: { + select_file: true + } + })); + }, + + /** + Disables file-picker element, so that it doesn't react to mouse clicks. + + @method disable + @param {Boolean} [state=true] Disable component if - true, enable if - false + */ + disable: function(state) { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileInput', 'disable', Basic.typeOf(state) === 'undefined' ? true : state); + } + }, + + + /** + Reposition and resize dialog trigger to match the position and size of browse_button element. + + @method refresh + */ + refresh: function() { + self.trigger("Refresh"); + }, + + + /** + Destroy component. + + @method destroy + */ + destroy: function() { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileInput', 'destroy'); + this.disconnectRuntime(); + } + + if (Basic.typeOf(this.files) === 'array') { + // no sense in leaving associated files behind + Basic.each(this.files, function(file) { + file.destroy(); + }); + } + this.files = null; + } + }); + } + + FileInput.prototype = EventTarget.instance; + + return FileInput; +}); + +// Included from: src/javascript/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileDrop', [ + 'moxie/core/I18n', + 'moxie/core/utils/Dom', + 'moxie/core/Exceptions', + 'moxie/core/utils/Basic', + 'moxie/file/File', + 'moxie/runtime/RuntimeClient', + 'moxie/core/EventTarget', + 'moxie/core/utils/Mime' +], function(I18n, Dom, x, Basic, File, RuntimeClient, EventTarget, Mime) { + /** + Turn arbitrary DOM element to a drop zone accepting files. Converts selected files to _File_ objects, to be used + in conjunction with _Image_, preloaded in memory with _FileReader_ or uploaded to a server through + _XMLHttpRequest_. + + @example + <div id="drop_zone"> + Drop files here + </div> + <br /> + <div id="filelist"></div> + + <script type="text/javascript"> + var fileDrop = new mOxie.FileDrop('drop_zone'), fileList = mOxie.get('filelist'); + + fileDrop.ondrop = function() { + mOxie.each(this.files, function(file) { + fileList.innerHTML += '<div>' + file.name + '</div>'; + }); + }; + + fileDrop.init(); + </script> + + @class FileDrop + @constructor + @extends EventTarget + @uses RuntimeClient + @param {Object|String} options If options has typeof string, argument is considered as options.drop_zone + @param {String|DOMElement} options.drop_zone DOM Element to turn into a drop zone + @param {Array} [options.accept] Array of mime types to accept. By default accepts all + @param {Object|String} [options.required_caps] Set of required capabilities, that chosen runtime must support + */ + var dispatches = [ + /** + Dispatched when runtime is connected and drop zone is ready to accept files. + + @event ready + @param {Object} event + */ + 'ready', + + /** + Dispatched when dragging cursor enters the drop zone. + + @event dragenter + @param {Object} event + */ + 'dragenter', + + /** + Dispatched when dragging cursor leaves the drop zone. + + @event dragleave + @param {Object} event + */ + 'dragleave', + + /** + Dispatched when file is dropped onto the drop zone. + + @event drop + @param {Object} event + */ + 'drop', + + /** + Dispatched if error occurs. + + @event error + @param {Object} event + */ + 'error' + ]; + + function FileDrop(options) { + var self = this, defaults; + + // if flat argument passed it should be drop_zone id + if (typeof(options) === 'string') { + options = { drop_zone : options }; + } + + // figure out the options + defaults = { + accept: [{ + title: I18n.translate('All Files'), + extensions: '*' + }], + required_caps: { + drag_and_drop: true + } + }; + + options = typeof(options) === 'object' ? Basic.extend({}, defaults, options) : defaults; + + // this will help us to find proper default container + options.container = Dom.get(options.drop_zone) || document.body; + + // make container relative, if it is not + if (Dom.getStyle(options.container, 'position') === 'static') { + options.container.style.position = 'relative'; + } + + // normalize accept option (could be list of mime types or array of title/extensions pairs) + if (typeof(options.accept) === 'string') { + options.accept = Mime.mimes2extList(options.accept); + } + + RuntimeClient.call(self); + + Basic.extend(self, { + uid: Basic.guid('uid_'), + + ruid: null, + + files: null, + + init: function() { + + self.convertEventPropsToHandlers(dispatches); + + self.bind('RuntimeInit', function(e, runtime) { + self.ruid = runtime.uid; + + self.bind("Drop", function() { + var files = runtime.exec.call(self, 'FileDrop', 'getFiles'); + + self.files = []; + + Basic.each(files, function(file) { + self.files.push(new File(self.ruid, file)); + }); + }, 999); + + runtime.exec.call(self, 'FileDrop', 'init', options); + + self.dispatchEvent('ready'); + }); + + // runtime needs: options.required_features, options.runtime_order and options.container + self.connectRuntime(options); // throws RuntimeError + }, + + destroy: function() { + var runtime = this.getRuntime(); + if (runtime) { + runtime.exec.call(this, 'FileDrop', 'destroy'); + this.disconnectRuntime(); + } + this.files = null; + } + }); + } + + FileDrop.prototype = EventTarget.instance; + + return FileDrop; +}); + +// Included from: src/javascript/runtime/RuntimeTarget.js + +/** + * RuntimeTarget.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/runtime/RuntimeTarget', [ + 'moxie/core/utils/Basic', + 'moxie/runtime/RuntimeClient', + "moxie/core/EventTarget" +], function(Basic, RuntimeClient, EventTarget) { + /** + Instance of this class can be used as a target for the events dispatched by shims, + when allowing them onto components is for either reason inappropriate + + @class RuntimeTarget + @constructor + @protected + @extends EventTarget + */ + function RuntimeTarget() { + this.uid = Basic.guid('uid_'); + + RuntimeClient.call(this); + + this.destroy = function() { + this.disconnectRuntime(); + this.unbindAll(); + }; + } + + RuntimeTarget.prototype = EventTarget.instance; + + return RuntimeTarget; +}); + +// Included from: src/javascript/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileReader', [ + 'moxie/core/utils/Basic', + 'moxie/core/utils/Encode', + 'moxie/core/Exceptions', + 'moxie/core/EventTarget', + 'moxie/file/Blob', + 'moxie/file/File', + 'moxie/runtime/RuntimeTarget' +], function(Basic, Encode, x, EventTarget, Blob, File, RuntimeTarget) { + /** + Utility for preloading o.Blob/o.File objects in memory. By design closely follows [W3C FileReader](http://www.w3.org/TR/FileAPI/#dfn-filereader) + interface. Where possible uses native FileReader, where - not falls back to shims. + + @class FileReader + @constructor FileReader + @extends EventTarget + @uses RuntimeClient + */ + var dispatches = [ + + /** + Dispatched when the read starts. + + @event loadstart + @param {Object} event + */ + 'loadstart', + + /** + Dispatched while reading (and decoding) blob, and reporting partial Blob data (progess.loaded/progress.total). + + @event progress + @param {Object} event + */ + 'progress', + + /** + Dispatched when the read has successfully completed. + + @event load + @param {Object} event + */ + 'load', + + /** + Dispatched when the read has been aborted. For instance, by invoking the abort() method. + + @event abort + @param {Object} event + */ + 'abort', + + /** + Dispatched when the read has failed. + + @event error + @param {Object} event + */ + 'error', + + /** + Dispatched when the request has completed (either in success or failure). + + @event loadend + @param {Object} event + */ + 'loadend' + ]; + + function FileReader() { + var self = this, _fr; + + Basic.extend(this, { + /** + UID of the component instance. + + @property uid + @type {String} + */ + uid: Basic.guid('uid_'), + + /** + Contains current state of FileReader object. Can take values of FileReader.EMPTY, FileReader.LOADING + and FileReader.DONE. + + @property readyState + @type {Number} + @default FileReader.EMPTY + */ + readyState: FileReader.EMPTY, + + /** + Result of the successful read operation. + + @property result + @type {String} + */ + result: null, + + /** + Stores the error of failed asynchronous read operation. + + @property error + @type {DOMError} + */ + error: null, + + /** + Initiates reading of File/Blob object contents to binary string. + + @method readAsBinaryString + @param {Blob|File} blob Object to preload + */ + readAsBinaryString: function(blob) { + _read.call(this, 'readAsBinaryString', blob); + }, + + /** + Initiates reading of File/Blob object contents to dataURL string. + + @method readAsDataURL + @param {Blob|File} blob Object to preload + */ + readAsDataURL: function(blob) { + _read.call(this, 'readAsDataURL', blob); + }, + + /** + Initiates reading of File/Blob object contents to string. + + @method readAsText + @param {Blob|File} blob Object to preload + */ + readAsText: function(blob) { + _read.call(this, 'readAsText', blob); + }, + + /** + Aborts preloading process. + + @method abort + */ + abort: function() { + this.result = null; + + if (Basic.inArray(this.readyState, [FileReader.EMPTY, FileReader.DONE]) !== -1) { + return; + } else if (this.readyState === FileReader.LOADING) { + this.readyState = FileReader.DONE; + } + + if (_fr) { + _fr.getRuntime().exec.call(this, 'FileReader', 'abort'); + } + + this.trigger('abort'); + this.trigger('loadend'); + }, + + /** + Destroy component and release resources. + + @method destroy + */ + destroy: function() { + this.abort(); + + if (_fr) { + _fr.getRuntime().exec.call(this, 'FileReader', 'destroy'); + _fr.disconnectRuntime(); + } + + self = _fr = null; + } + }); + + + function _read(op, blob) { + _fr = new RuntimeTarget(); + + function error(err) { + self.readyState = FileReader.DONE; + self.error = err; + self.trigger('error'); + loadEnd(); + } + + function loadEnd() { + _fr.destroy(); + _fr = null; + self.trigger('loadend'); + } + + function exec(runtime) { + _fr.bind('Error', function(e, err) { + error(err); + }); + + _fr.bind('Progress', function(e) { + self.result = runtime.exec.call(_fr, 'FileReader', 'getResult'); + self.trigger(e); + }); + + _fr.bind('Load', function(e) { + self.readyState = FileReader.DONE; + self.result = runtime.exec.call(_fr, 'FileReader', 'getResult'); + self.trigger(e); + loadEnd(); + }); + + runtime.exec.call(_fr, 'FileReader', 'read', op, blob); + } + + this.convertEventPropsToHandlers(dispatches); + + if (this.readyState === FileReader.LOADING) { + return error(new x.DOMException(x.DOMException.INVALID_STATE_ERR)); + } + + this.readyState = FileReader.LOADING; + this.trigger('loadstart'); + + // if source is o.Blob/o.File + if (blob instanceof Blob) { + if (blob.isDetached()) { + var src = blob.getSource(); + switch (op) { + case 'readAsText': + case 'readAsBinaryString': + this.result = src; + break; + case 'readAsDataURL': + this.result = 'data:' + blob.type + ';base64,' + Encode.btoa(src); + break; + } + this.readyState = FileReader.DONE; + this.trigger('load'); + loadEnd(); + } else { + exec(_fr.connectRuntime(blob.ruid)); + } + } else { + error(new x.DOMException(x.DOMException.NOT_FOUND_ERR)); + } + } + } + + /** + Initial FileReader state + + @property EMPTY + @type {Number} + @final + @static + @default 0 + */ + FileReader.EMPTY = 0; + + /** + FileReader switches to this state when it is preloading the source + + @property LOADING + @type {Number} + @final + @static + @default 1 + */ + FileReader.LOADING = 1; + + /** + Preloading is complete, this is a final state + + @property DONE + @type {Number} + @final + @static + @default 2 + */ + FileReader.DONE = 2; + + FileReader.prototype = EventTarget.instance; + + return FileReader; +}); + +// Included from: src/javascript/core/utils/Url.js + +/** + * Url.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Url', [], function() { + /** + Parse url into separate components and fill in absent parts with parts from current url, + based on https://raw.github.com/kvz/phpjs/master/functions/url/parse_url.js + + @method parseUrl + @for Utils + @static + @param {String} url Url to parse (defaults to empty string if undefined) + @return {Object} Hash containing extracted uri components + */ + var parseUrl = function(url, currentUrl) { + var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'] + , i = key.length + , ports = { + http: 80, + https: 443 + } + , uri = {} + , regex = /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/ + , m = regex.exec(url || '') + ; + + while (i--) { + if (m[i]) { + uri[key[i]] = m[i]; + } + } + + // when url is relative, we set the origin and the path ourselves + if (!uri.scheme) { + // come up with defaults + if (!currentUrl || typeof(currentUrl) === 'string') { + currentUrl = parseUrl(currentUrl || document.location.href); + } + + uri.scheme = currentUrl.scheme; + uri.host = currentUrl.host; + uri.port = currentUrl.port; + + var path = ''; + // for urls without trailing slash we need to figure out the path + if (/^[^\/]/.test(uri.path)) { + path = currentUrl.path; + // if path ends with a filename, strip it + if (!/(\/|\/[^\.]+)$/.test(path)) { + path = path.replace(/\/[^\/]+$/, '/'); + } else { + path += '/'; + } + } + uri.path = path + (uri.path || ''); // site may reside at domain.com or domain.com/subdir + } + + if (!uri.port) { + uri.port = ports[uri.scheme] || 80; + } + + uri.port = parseInt(uri.port, 10); + + if (!uri.path) { + uri.path = "/"; + } + + delete uri.source; + + return uri; + }; + + /** + Resolve url - among other things will turn relative url to absolute + + @method resolveUrl + @static + @param {String} url Either absolute or relative + @return {String} Resolved, absolute url + */ + var resolveUrl = function(url) { + var ports = { // we ignore default ports + http: 80, + https: 443 + } + , urlp = parseUrl(url) + ; + + return urlp.scheme + '://' + urlp.host + (urlp.port !== ports[urlp.scheme] ? ':' + urlp.port : '') + urlp.path + (urlp.query ? urlp.query : ''); + }; + + /** + Check if specified url has the same origin as the current document + + @method hasSameOrigin + @param {String|Object} url + @return {Boolean} + */ + var hasSameOrigin = function(url) { + function origin(url) { + return [url.scheme, url.host, url.port].join('/'); + } + + if (typeof url === 'string') { + url = parseUrl(url); + } + + return origin(parseUrl()) === origin(url); + }; + + return { + parseUrl: parseUrl, + resolveUrl: resolveUrl, + hasSameOrigin: hasSameOrigin + }; +}); + +// Included from: src/javascript/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/file/FileReaderSync', [ + 'moxie/core/utils/Basic', + 'moxie/runtime/RuntimeClient', + 'moxie/core/utils/Encode' +], function(Basic, RuntimeClient, Encode) { + /** + Synchronous FileReader implementation. Something like this is available in WebWorkers environment, here + it can be used to read only preloaded blobs/files and only below certain size (not yet sure what that'd be, + but probably < 1mb). Not meant to be used directly by user. + + @class FileReaderSync + @private + @constructor + */ + return function() { + RuntimeClient.call(this); + + Basic.extend(this, { + uid: Basic.guid('uid_'), + + readAsBinaryString: function(blob) { + return _read.call(this, 'readAsBinaryString', blob); + }, + + readAsDataURL: function(blob) { + return _read.call(this, 'readAsDataURL', blob); + }, + + /*readAsArrayBuffer: function(blob) { + return _read.call(this, 'readAsArrayBuffer', blob); + },*/ + + readAsText: function(blob) { + return _read.call(this, 'readAsText', blob); + } + }); + + function _read(op, blob) { + if (blob.isDetached()) { + var src = blob.getSource(); + switch (op) { + case 'readAsBinaryString': + return src; + case 'readAsDataURL': + return 'data:' + blob.type + ';base64,' + Encode.btoa(src); + case 'readAsText': + var txt = ''; + for (var i = 0, length = src.length; i < length; i++) { + txt += String.fromCharCode(src[i]); + } + return txt; + } + } else { + var result = this.connectRuntime(blob.ruid).exec.call(this, 'FileReaderSync', 'read', op, blob); + this.disconnectRuntime(); + return result; + } + } + }; +}); + +// Included from: src/javascript/xhr/FormData.js + +/** + * FormData.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/xhr/FormData", [ + "moxie/core/Exceptions", + "moxie/core/utils/Basic", + "moxie/file/Blob" +], function(x, Basic, Blob) { + /** + FormData + + @class FormData + @constructor + */ + function FormData() { + var _blob, _fields = []; + + Basic.extend(this, { + /** + Append another key-value pair to the FormData object + + @method append + @param {String} name Name for the new field + @param {String|Blob|Array|Object} value Value for the field + */ + append: function(name, value) { + var self = this, valueType = Basic.typeOf(value); + + // according to specs value might be either Blob or String + if (value instanceof Blob) { + _blob = { + name: name, + value: value // unfortunately we can only send single Blob in one FormData + }; + } else if ('array' === valueType) { + name += '[]'; + + Basic.each(value, function(value) { + self.append(name, value); + }); + } else if ('object' === valueType) { + Basic.each(value, function(value, key) { + self.append(name + '[' + key + ']', value); + }); + } else if ('null' === valueType || 'undefined' === valueType || 'number' === valueType && isNaN(value)) { + self.append(name, "false"); + } else { + _fields.push({ + name: name, + value: value.toString() + }); + } + }, + + /** + Checks if FormData contains Blob. + + @method hasBlob + @return {Boolean} + */ + hasBlob: function() { + return !!this.getBlob(); + }, + + /** + Retrieves blob. + + @method getBlob + @return {Object} Either Blob if found or null + */ + getBlob: function() { + return _blob && _blob.value || null; + }, + + /** + Retrieves blob field name. + + @method getBlobName + @return {String} Either Blob field name or null + */ + getBlobName: function() { + return _blob && _blob.name || null; + }, + + /** + Loop over the fields in FormData and invoke the callback for each of them. + + @method each + @param {Function} cb Callback to call for each field + */ + each: function(cb) { + Basic.each(_fields, function(field) { + cb(field.value, field.name); + }); + + if (_blob) { + cb(_blob.value, _blob.name); + } + }, + + destroy: function() { + _blob = null; + _fields = []; + } + }); + } + + return FormData; +}); + +// Included from: src/javascript/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/xhr/XMLHttpRequest", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/core/EventTarget", + "moxie/core/utils/Encode", + "moxie/core/utils/Url", + "moxie/runtime/Runtime", + "moxie/runtime/RuntimeTarget", + "moxie/file/Blob", + "moxie/file/FileReaderSync", + "moxie/xhr/FormData", + "moxie/core/utils/Env", + "moxie/core/utils/Mime" +], function(Basic, x, EventTarget, Encode, Url, Runtime, RuntimeTarget, Blob, FileReaderSync, FormData, Env, Mime) { + + var httpCode = { + 100: 'Continue', + 101: 'Switching Protocols', + 102: 'Processing', + + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + 207: 'Multi-Status', + 226: 'IM Used', + + 300: 'Multiple Choices', + 301: 'Moved Permanently', + 302: 'Found', + 303: 'See Other', + 304: 'Not Modified', + 305: 'Use Proxy', + 306: 'Reserved', + 307: 'Temporary Redirect', + + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Request Entity Too Large', + 414: 'Request-URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Requested Range Not Satisfiable', + 417: 'Expectation Failed', + 422: 'Unprocessable Entity', + 423: 'Locked', + 424: 'Failed Dependency', + 426: 'Upgrade Required', + + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 510: 'Not Extended' + }; + + function XMLHttpRequestUpload() { + this.uid = Basic.guid('uid_'); + } + + XMLHttpRequestUpload.prototype = EventTarget.instance; + + /** + Implementation of XMLHttpRequest + + @class XMLHttpRequest + @constructor + @uses RuntimeClient + @extends EventTarget + */ + var dispatches = ['loadstart', 'progress', 'abort', 'error', 'load', 'timeout', 'loadend']; // & readystatechange (for historical reasons) + + var NATIVE = 1, RUNTIME = 2; + + function XMLHttpRequest() { + var self = this, + // this (together with _p() @see below) is here to gracefully upgrade to setter/getter syntax where possible + props = { + /** + The amount of milliseconds a request can take before being terminated. Initially zero. Zero means there is no timeout. + + @property timeout + @type Number + @default 0 + */ + timeout: 0, + + /** + Current state, can take following values: + UNSENT (numeric value 0) + The object has been constructed. + + OPENED (numeric value 1) + The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the request can be made using the send() method. + + HEADERS_RECEIVED (numeric value 2) + All redirects (if any) have been followed and all HTTP headers of the final response have been received. Several response members of the object are now available. + + LOADING (numeric value 3) + The response entity body is being received. + + DONE (numeric value 4) + + @property readyState + @type Number + @default 0 (UNSENT) + */ + readyState: XMLHttpRequest.UNSENT, + + /** + True when user credentials are to be included in a cross-origin request. False when they are to be excluded + in a cross-origin request and when cookies are to be ignored in its response. Initially false. + + @property withCredentials + @type Boolean + @default false + */ + withCredentials: false, + + /** + Returns the HTTP status code. + + @property status + @type Number + @default 0 + */ + status: 0, + + /** + Returns the HTTP status text. + + @property statusText + @type String + */ + statusText: "", + + /** + Returns the response type. Can be set to change the response type. Values are: + the empty string (default), "arraybuffer", "blob", "document", "json", and "text". + + @property responseType + @type String + */ + responseType: "", + + /** + Returns the document response entity body. + + Throws an "InvalidStateError" exception if responseType is not the empty string or "document". + + @property responseXML + @type Document + */ + responseXML: null, + + /** + Returns the text response entity body. + + Throws an "InvalidStateError" exception if responseType is not the empty string or "text". + + @property responseText + @type String + */ + responseText: null, + + /** + Returns the response entity body (http://www.w3.org/TR/XMLHttpRequest/#response-entity-body). + Can become: ArrayBuffer, Blob, Document, JSON, Text + + @property response + @type Mixed + */ + response: null + }, + + _async = true, + _url, + _method, + _headers = {}, + _user, + _password, + _encoding = null, + _mimeType = null, + + // flags + _sync_flag = false, + _send_flag = false, + _upload_events_flag = false, + _upload_complete_flag = false, + _error_flag = false, + _same_origin_flag = false, + + // times + _start_time, + _timeoutset_time, + + _finalMime = null, + _finalCharset = null, + + _options = {}, + _xhr, + _responseHeaders = '', + _responseHeadersBag + ; + + + Basic.extend(this, props, { + /** + Unique id of the component + + @property uid + @type String + */ + uid: Basic.guid('uid_'), + + /** + Target for Upload events + + @property upload + @type XMLHttpRequestUpload + */ + upload: new XMLHttpRequestUpload(), + + + /** + Sets the request method, request URL, synchronous flag, request username, and request password. + + Throws a "SyntaxError" exception if one of the following is true: + + method is not a valid HTTP method. + url cannot be resolved. + url contains the "user:password" format in the userinfo production. + Throws a "SecurityError" exception if method is a case-insensitive match for CONNECT, TRACE or TRACK. + + Throws an "InvalidAccessError" exception if one of the following is true: + + Either user or password is passed as argument and the origin of url does not match the XMLHttpRequest origin. + There is an associated XMLHttpRequest document and either the timeout attribute is not zero, + the withCredentials attribute is true, or the responseType attribute is not the empty string. + + + @method open + @param {String} method HTTP method to use on request + @param {String} url URL to request + @param {Boolean} [async=true] If false request will be done in synchronous manner. Asynchronous by default. + @param {String} [user] Username to use in HTTP authentication process on server-side + @param {String} [password] Password to use in HTTP authentication process on server-side + */ + open: function(method, url, async, user, password) { + var urlp; + + // first two arguments are required + if (!method || !url) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 2 - check if any code point in method is higher than U+00FF or after deflating method it does not match the method + if (/[\u0100-\uffff]/.test(method) || Encode.utf8_encode(method) !== method) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 3 + if (!!~Basic.inArray(method.toUpperCase(), ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'TRACE', 'TRACK'])) { + _method = method.toUpperCase(); + } + + + // 4 - allowing these methods poses a security risk + if (!!~Basic.inArray(_method, ['CONNECT', 'TRACE', 'TRACK'])) { + throw new x.DOMException(x.DOMException.SECURITY_ERR); + } + + // 5 + url = Encode.utf8_encode(url); + + // 6 - Resolve url relative to the XMLHttpRequest base URL. If the algorithm returns an error, throw a "SyntaxError". + urlp = Url.parseUrl(url); + + _same_origin_flag = Url.hasSameOrigin(urlp); + + // 7 - manually build up absolute url + _url = Url.resolveUrl(url); + + // 9-10, 12-13 + if ((user || password) && !_same_origin_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + _user = user || urlp.user; + _password = password || urlp.pass; + + // 11 + _async = async || true; + + if (_async === false && (_p('timeout') || _p('withCredentials') || _p('responseType') !== "")) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 14 - terminate abort() + + // 15 - terminate send() + + // 18 + _sync_flag = !_async; + _send_flag = false; + _headers = {}; + _reset.call(this); + + // 19 + _p('readyState', XMLHttpRequest.OPENED); + + // 20 + this.convertEventPropsToHandlers(['readystatechange']); // unify event handlers + this.dispatchEvent('readystatechange'); + }, + + /** + Appends an header to the list of author request headers, or if header is already + in the list of author request headers, combines its value with value. + + Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set. + Throws a "SyntaxError" exception if header is not a valid HTTP header field name or if value + is not a valid HTTP header field value. + + @method setRequestHeader + @param {String} header + @param {String|Number} value + */ + setRequestHeader: function(header, value) { + var uaHeaders = [ // these headers are controlled by the user agent + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" + ]; + + // 1-2 + if (_p('readyState') !== XMLHttpRequest.OPENED || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3 + if (/[\u0100-\uffff]/.test(header) || Encode.utf8_encode(header) !== header) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 4 + /* this step is seemingly bypassed in browsers, probably to allow various unicode characters in header values + if (/[\u0100-\uffff]/.test(value) || Encode.utf8_encode(value) !== value) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + }*/ + + header = Basic.trim(header).toLowerCase(); + + // setting of proxy-* and sec-* headers is prohibited by spec + if (!!~Basic.inArray(header, uaHeaders) || /^(proxy\-|sec\-)/.test(header)) { + return false; + } + + // camelize + // browsers lowercase header names (at least for custom ones) + // header = header.replace(/\b\w/g, function($1) { return $1.toUpperCase(); }); + + if (!_headers[header]) { + _headers[header] = value; + } else { + // http://tools.ietf.org/html/rfc2616#section-4.2 (last paragraph) + _headers[header] += ', ' + value; + } + return true; + }, + + /** + Returns all headers from the response, with the exception of those whose field name is Set-Cookie or Set-Cookie2. + + @method getAllResponseHeaders + @return {String} reponse headers or empty string + */ + getAllResponseHeaders: function() { + return _responseHeaders || ''; + }, + + /** + Returns the header field value from the response of which the field name matches header, + unless the field name is Set-Cookie or Set-Cookie2. + + @method getResponseHeader + @param {String} header + @return {String} value(s) for the specified header or null + */ + getResponseHeader: function(header) { + header = header.toLowerCase(); + + if (_error_flag || !!~Basic.inArray(header, ['set-cookie', 'set-cookie2'])) { + return null; + } + + if (_responseHeaders && _responseHeaders !== '') { + // if we didn't parse response headers until now, do it and keep for later + if (!_responseHeadersBag) { + _responseHeadersBag = {}; + Basic.each(_responseHeaders.split(/\r\n/), function(line) { + var pair = line.split(/:\s+/); + if (pair.length === 2) { // last line might be empty, omit + pair[0] = Basic.trim(pair[0]); // just in case + _responseHeadersBag[pair[0].toLowerCase()] = { // simply to retain header name in original form + header: pair[0], + value: Basic.trim(pair[1]) + }; + } + }); + } + if (_responseHeadersBag.hasOwnProperty(header)) { + return _responseHeadersBag[header].header + ': ' + _responseHeadersBag[header].value; + } + } + return null; + }, + + /** + Sets the Content-Type header for the response to mime. + Throws an "InvalidStateError" exception if the state is LOADING or DONE. + Throws a "SyntaxError" exception if mime is not a valid media type. + + @method overrideMimeType + @param String mime Mime type to set + */ + overrideMimeType: function(mime) { + var matches, charset; + + // 1 + if (!!~Basic.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2 + mime = Basic.trim(mime.toLowerCase()); + + if (/;/.test(mime) && (matches = mime.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))) { + mime = matches[1]; + if (matches[2]) { + charset = matches[2]; + } + } + + if (!Mime.mimes[mime]) { + throw new x.DOMException(x.DOMException.SYNTAX_ERR); + } + + // 3-4 + _finalMime = mime; + _finalCharset = charset; + }, + + /** + Initiates the request. The optional argument provides the request entity body. + The argument is ignored if request method is GET or HEAD. + + Throws an "InvalidStateError" exception if the state is not OPENED or if the send() flag is set. + + @method send + @param {Blob|Document|String|FormData} [data] Request entity body + @param {Object} [options] Set of requirements and pre-requisities for runtime initialization + */ + send: function(data, options) { + if (Basic.typeOf(options) === 'string') { + _options = { ruid: options }; + } else if (!options) { + _options = {}; + } else { + _options = options; + } + + this.convertEventPropsToHandlers(dispatches); + this.upload.convertEventPropsToHandlers(dispatches); + + // 1-2 + if (this.readyState !== XMLHttpRequest.OPENED || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3 + // sending Blob + if (data instanceof Blob) { + _options.ruid = data.ruid; + _mimeType = data.type || 'application/octet-stream'; + } + + // FormData + else if (data instanceof FormData) { + if (data.hasBlob()) { + var blob = data.getBlob(); + _options.ruid = blob.ruid; + _mimeType = blob.type || 'application/octet-stream'; + } + } + + // DOMString + else if (typeof data === 'string') { + _encoding = 'UTF-8'; + _mimeType = 'text/plain;charset=UTF-8'; + + // data should be converted to Unicode and encoded as UTF-8 + data = Encode.utf8_encode(data); + } + + // if withCredentials not set, but requested, set it automatically + if (!this.withCredentials) { + this.withCredentials = (_options.required_caps && _options.required_caps.send_browser_cookies) && !_same_origin_flag; + } + + // 4 - storage mutex + // 5 + _upload_events_flag = (!_sync_flag && this.upload.hasEventListener()); // DSAP + // 6 + _error_flag = false; + // 7 + _upload_complete_flag = !data; + // 8 - Asynchronous steps + if (!_sync_flag) { + // 8.1 + _send_flag = true; + // 8.2 + // this.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr + // 8.3 + //if (!_upload_complete_flag) { + // this.upload.dispatchEvent('loadstart'); // will be dispatched either by native or runtime xhr + //} + } + // 8.5 - Return the send() method call, but continue running the steps in this algorithm. + _doXHR.call(this, data); + }, + + /** + Cancels any network activity. + + @method abort + */ + abort: function() { + _error_flag = true; + _sync_flag = false; + + if (!~Basic.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED, XMLHttpRequest.DONE])) { + _p('readyState', XMLHttpRequest.DONE); + _send_flag = false; + + if (_xhr) { + _xhr.getRuntime().exec.call(_xhr, 'XMLHttpRequest', 'abort', _upload_complete_flag); + } else { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + _upload_complete_flag = true; + } else { + _p('readyState', XMLHttpRequest.UNSENT); + } + }, + + destroy: function() { + if (_xhr) { + if (Basic.typeOf(_xhr.destroy) === 'function') { + _xhr.destroy(); + } + _xhr = null; + } + + this.unbindAll(); + + if (this.upload) { + this.upload.unbindAll(); + this.upload = null; + } + } + }); + + /* this is nice, but maybe too lengthy + + // if supported by JS version, set getters/setters for specific properties + o.defineProperty(this, 'readyState', { + configurable: false, + + get: function() { + return _p('readyState'); + } + }); + + o.defineProperty(this, 'timeout', { + configurable: false, + + get: function() { + return _p('timeout'); + }, + + set: function(value) { + + if (_sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // timeout still should be measured relative to the start time of request + _timeoutset_time = (new Date).getTime(); + + _p('timeout', value); + } + }); + + // the withCredentials attribute has no effect when fetching same-origin resources + o.defineProperty(this, 'withCredentials', { + configurable: false, + + get: function() { + return _p('withCredentials'); + }, + + set: function(value) { + // 1-2 + if (!~o.inArray(_p('readyState'), [XMLHttpRequest.UNSENT, XMLHttpRequest.OPENED]) || _send_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 3-4 + if (_anonymous_flag || _sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 5 + _p('withCredentials', value); + } + }); + + o.defineProperty(this, 'status', { + configurable: false, + + get: function() { + return _p('status'); + } + }); + + o.defineProperty(this, 'statusText', { + configurable: false, + + get: function() { + return _p('statusText'); + } + }); + + o.defineProperty(this, 'responseType', { + configurable: false, + + get: function() { + return _p('responseType'); + }, + + set: function(value) { + // 1 + if (!!~o.inArray(_p('readyState'), [XMLHttpRequest.LOADING, XMLHttpRequest.DONE])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2 + if (_sync_flag) { + throw new x.DOMException(x.DOMException.INVALID_ACCESS_ERR); + } + + // 3 + _p('responseType', value.toLowerCase()); + } + }); + + o.defineProperty(this, 'responseText', { + configurable: false, + + get: function() { + // 1 + if (!~o.inArray(_p('responseType'), ['', 'text'])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2-3 + if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + return _p('responseText'); + } + }); + + o.defineProperty(this, 'responseXML', { + configurable: false, + + get: function() { + // 1 + if (!~o.inArray(_p('responseType'), ['', 'document'])) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // 2-3 + if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + return _p('responseXML'); + } + }); + + o.defineProperty(this, 'response', { + configurable: false, + + get: function() { + if (!!~o.inArray(_p('responseType'), ['', 'text'])) { + if (_p('readyState') !== XMLHttpRequest.DONE && _p('readyState') !== XMLHttpRequest.LOADING || _error_flag) { + return ''; + } + } + + if (_p('readyState') !== XMLHttpRequest.DONE || _error_flag) { + return null; + } + + return _p('response'); + } + }); + + */ + + function _p(prop, value) { + if (!props.hasOwnProperty(prop)) { + return; + } + if (arguments.length === 1) { // get + return Env.can('define_property') ? props[prop] : self[prop]; + } else { // set + if (Env.can('define_property')) { + props[prop] = value; + } else { + self[prop] = value; + } + } + } + + /* + function _toASCII(str, AllowUnassigned, UseSTD3ASCIIRules) { + // TODO: http://tools.ietf.org/html/rfc3490#section-4.1 + return str.toLowerCase(); + } + */ + + + function _doXHR(data) { + var self = this; + + _start_time = new Date().getTime(); + + _xhr = new RuntimeTarget(); + + function loadEnd() { + if (_xhr) { // it could have been destroyed by now + _xhr.destroy(); + _xhr = null; + } + self.dispatchEvent('loadend'); + self = null; + } + + function exec(runtime) { + _xhr.bind('LoadStart', function(e) { + _p('readyState', XMLHttpRequest.LOADING); + self.dispatchEvent('readystatechange'); + + self.dispatchEvent(e); + + if (_upload_events_flag) { + self.upload.dispatchEvent(e); + } + }); + + _xhr.bind('Progress', function(e) { + if (_p('readyState') !== XMLHttpRequest.LOADING) { + _p('readyState', XMLHttpRequest.LOADING); // LoadStart unreliable (in Flash for example) + self.dispatchEvent('readystatechange'); + } + self.dispatchEvent(e); + }); + + _xhr.bind('UploadProgress', function(e) { + if (_upload_events_flag) { + self.upload.dispatchEvent({ + type: 'progress', + lengthComputable: false, + total: e.total, + loaded: e.loaded + }); + } + }); + + _xhr.bind('Load', function(e) { + _p('readyState', XMLHttpRequest.DONE); + _p('status', Number(runtime.exec.call(_xhr, 'XMLHttpRequest', 'getStatus') || 0)); + _p('statusText', httpCode[_p('status')] || ""); + + _p('response', runtime.exec.call(_xhr, 'XMLHttpRequest', 'getResponse', _p('responseType'))); + + if (!!~Basic.inArray(_p('responseType'), ['text', ''])) { + _p('responseText', _p('response')); + } else if (_p('responseType') === 'document') { + _p('responseXML', _p('response')); + } + + _responseHeaders = runtime.exec.call(_xhr, 'XMLHttpRequest', 'getAllResponseHeaders'); + + self.dispatchEvent('readystatechange'); + + if (_p('status') > 0) { // status 0 usually means that server is unreachable + if (_upload_events_flag) { + self.upload.dispatchEvent(e); + } + self.dispatchEvent(e); + } else { + _error_flag = true; + self.dispatchEvent('error'); + } + loadEnd(); + }); + + _xhr.bind('Abort', function(e) { + self.dispatchEvent(e); + loadEnd(); + }); + + _xhr.bind('Error', function(e) { + _error_flag = true; + _p('readyState', XMLHttpRequest.DONE); + self.dispatchEvent('readystatechange'); + _upload_complete_flag = true; + self.dispatchEvent(e); + loadEnd(); + }); + + runtime.exec.call(_xhr, 'XMLHttpRequest', 'send', { + url: _url, + method: _method, + async: _async, + user: _user, + password: _password, + headers: _headers, + mimeType: _mimeType, + encoding: _encoding, + responseType: self.responseType, + withCredentials: self.withCredentials, + options: _options + }, data); + } + + // clarify our requirements + if (typeof(_options.required_caps) === 'string') { + _options.required_caps = Runtime.parseCaps(_options.required_caps); + } + + _options.required_caps = Basic.extend({}, _options.required_caps, { + return_response_type: self.responseType + }); + + if (data instanceof FormData) { + _options.required_caps.send_multipart = true; + } + + if (!_same_origin_flag) { + _options.required_caps.do_cors = true; + } + + + if (_options.ruid) { // we do not need to wait if we can connect directly + exec(_xhr.connectRuntime(_options)); + } else { + _xhr.bind('RuntimeInit', function(e, runtime) { + exec(runtime); + }); + _xhr.bind('RuntimeError', function(e, err) { + self.dispatchEvent('RuntimeError', err); + }); + _xhr.connectRuntime(_options); + } + } + + + function _reset() { + _p('responseText', ""); + _p('responseXML', null); + _p('response', null); + _p('status', 0); + _p('statusText', ""); + _start_time = _timeoutset_time = null; + } + } + + XMLHttpRequest.UNSENT = 0; + XMLHttpRequest.OPENED = 1; + XMLHttpRequest.HEADERS_RECEIVED = 2; + XMLHttpRequest.LOADING = 3; + XMLHttpRequest.DONE = 4; + + XMLHttpRequest.prototype = EventTarget.instance; + + return XMLHttpRequest; +}); + +// Included from: src/javascript/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/runtime/Transporter", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Encode", + "moxie/runtime/RuntimeClient", + "moxie/core/EventTarget" +], function(Basic, Encode, RuntimeClient, EventTarget) { + function Transporter() { + var mod, _runtime, _data, _size, _pos, _chunk_size; + + RuntimeClient.call(this); + + Basic.extend(this, { + uid: Basic.guid('uid_'), + + state: Transporter.IDLE, + + result: null, + + transport: function(data, type, options) { + var self = this; + + options = Basic.extend({ + chunk_size: 204798 + }, options); + + // should divide by three, base64 requires this + if ((mod = options.chunk_size % 3)) { + options.chunk_size += 3 - mod; + } + + _chunk_size = options.chunk_size; + + _reset.call(this); + _data = data; + _size = data.length; + + if (Basic.typeOf(options) === 'string' || options.ruid) { + _run.call(self, type, this.connectRuntime(options)); + } else { + // we require this to run only once + var cb = function(e, runtime) { + self.unbind("RuntimeInit", cb); + _run.call(self, type, runtime); + }; + this.bind("RuntimeInit", cb); + this.connectRuntime(options); + } + }, + + abort: function() { + var self = this; + + self.state = Transporter.IDLE; + if (_runtime) { + _runtime.exec.call(self, 'Transporter', 'clear'); + self.trigger("TransportingAborted"); + } + + _reset.call(self); + }, + + + destroy: function() { + this.unbindAll(); + _runtime = null; + this.disconnectRuntime(); + _reset.call(this); + } + }); + + function _reset() { + _size = _pos = 0; + _data = this.result = null; + } + + function _run(type, runtime) { + var self = this; + + _runtime = runtime; + + //self.unbind("RuntimeInit"); + + self.bind("TransportingProgress", function(e) { + _pos = e.loaded; + + if (_pos < _size && Basic.inArray(self.state, [Transporter.IDLE, Transporter.DONE]) === -1) { + _transport.call(self); + } + }, 999); + + self.bind("TransportingComplete", function() { + _pos = _size; + self.state = Transporter.DONE; + _data = null; // clean a bit + self.result = _runtime.exec.call(self, 'Transporter', 'getAsBlob', type || ''); + }, 999); + + self.state = Transporter.BUSY; + self.trigger("TransportingStarted"); + _transport.call(self); + } + + function _transport() { + var self = this, + chunk, + bytesLeft = _size - _pos; + + if (_chunk_size > bytesLeft) { + _chunk_size = bytesLeft; + } + + chunk = Encode.btoa(_data.substr(_pos, _chunk_size)); + _runtime.exec.call(self, 'Transporter', 'receive', chunk, _size); + } + } + + Transporter.IDLE = 0; + Transporter.BUSY = 1; + Transporter.DONE = 2; + + Transporter.prototype = EventTarget.instance; + + return Transporter; +}); + +// Included from: src/javascript/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define("moxie/image/Image", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/file/FileReaderSync", + "moxie/xhr/XMLHttpRequest", + "moxie/runtime/Runtime", + "moxie/runtime/RuntimeClient", + "moxie/runtime/Transporter", + "moxie/core/utils/Env", + "moxie/core/EventTarget", + "moxie/file/Blob", + "moxie/file/File", + "moxie/core/utils/Encode" +], function(Basic, Dom, x, FileReaderSync, XMLHttpRequest, Runtime, RuntimeClient, Transporter, Env, EventTarget, Blob, File, Encode) { + /** + Image preloading and manipulation utility. Additionally it provides access to image meta info (Exif, GPS) and raw binary data. + + @class Image + @constructor + @extends EventTarget + */ + var dispatches = [ + 'progress', + + /** + Dispatched when loading is complete. + + @event load + @param {Object} event + */ + 'load', + + 'error', + + /** + Dispatched when resize operation is complete. + + @event resize + @param {Object} event + */ + 'resize', + + /** + Dispatched when visual representation of the image is successfully embedded + into the corresponsing container. + + @event embedded + @param {Object} event + */ + 'embedded' + ]; + + function Image() { + RuntimeClient.call(this); + + Basic.extend(this, { + /** + Unique id of the component + + @property uid + @type {String} + */ + uid: Basic.guid('uid_'), + + /** + Unique id of the connected runtime, if any. + + @property ruid + @type {String} + */ + ruid: null, + + /** + Name of the file, that was used to create an image, if available. If not equals to empty string. + + @property name + @type {String} + @default "" + */ + name: "", + + /** + Size of the image in bytes. Actual value is set only after image is preloaded. + + @property size + @type {Number} + @default 0 + */ + size: 0, + + /** + Width of the image. Actual value is set only after image is preloaded. + + @property width + @type {Number} + @default 0 + */ + width: 0, + + /** + Height of the image. Actual value is set only after image is preloaded. + + @property height + @type {Number} + @default 0 + */ + height: 0, + + /** + Mime type of the image. Currently only image/jpeg and image/png are supported. Actual value is set only after image is preloaded. + + @property type + @type {String} + @default "" + */ + type: "", + + /** + Holds meta info (Exif, GPS). Is populated only for image/jpeg. Actual value is set only after image is preloaded. + + @property meta + @type {Object} + @default {} + */ + meta: {}, + + /** + Alias for load method, that takes another mOxie.Image object as a source (see load). + + @method clone + @param {Image} src Source for the image + @param {Boolean} [exact=false] Whether to activate in-depth clone mode + */ + clone: function() { + this.load.apply(this, arguments); + }, + + /** + Loads image from various sources. Currently the source for new image can be: mOxie.Image, mOxie.Blob/mOxie.File, + native Blob/File, dataUrl or URL. Depending on the type of the source, arguments - differ. When source is URL, + Image will be downloaded from remote destination and loaded in memory. + + @example + var img = new mOxie.Image(); + img.onload = function() { + var blob = img.getAsBlob(); + + var formData = new mOxie.FormData(); + formData.append('file', blob); + + var xhr = new mOxie.XMLHttpRequest(); + xhr.onload = function() { + // upload complete + }; + xhr.open('post', 'upload.php'); + xhr.send(formData); + }; + img.load("http://www.moxiecode.com/images/mox-logo.jpg"); // notice file extension (.jpg) + + + @method load + @param {Image|Blob|File|String} src Source for the image + @param {Boolean|Object} [mixed] + */ + load: function() { + // this is here because to bind properly we need an uid first, which is created above + this.bind('Load Resize', function() { + _updateInfo.call(this); + }, 999); + + this.convertEventPropsToHandlers(dispatches); + + _load.apply(this, arguments); + }, + + /** + Downsizes the image to fit the specified width/height. If crop is supplied, image will be cropped to exact dimensions. + + @method downsize + @param {Number} width Resulting width + @param {Number} [height=width] Resulting height (optional, if not supplied will default to width) + @param {Boolean} [crop=false] Whether to crop the image to exact dimensions + @param {Boolean} [preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) + */ + downsize: function(opts) { + var defaults = { + width: this.width, + height: this.height, + crop: false, + preserveHeaders: true + }; + + if (typeof(opts) === 'object') { + opts = Basic.extend(defaults, opts); + } else { + opts = Basic.extend(defaults, { + width: arguments[0], + height: arguments[1], + crop: arguments[2], + preserveHeaders: arguments[3] + }); + } + + try { + if (!this.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + // no way to reliably intercept the crash due to high resolution, so we simply avoid it + if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) { + throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); + } + + this.getRuntime().exec.call(this, 'Image', 'downsize', opts.width, opts.height, opts.crop, opts.preserveHeaders); + } catch(ex) { + // for now simply trigger error event + this.trigger('error', ex.code); + } + }, + + /** + Alias for downsize(width, height, true). (see downsize) + + @method crop + @param {Number} width Resulting width + @param {Number} [height=width] Resulting height (optional, if not supplied will default to width) + @param {Boolean} [preserveHeaders=true] Whether to preserve meta headers (on JPEGs after resize) + */ + crop: function(width, height, preserveHeaders) { + this.downsize(width, height, true, preserveHeaders); + }, + + getAsCanvas: function() { + if (!Env.can('create_canvas')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + + var runtime = this.connectRuntime(this.ruid); + return runtime.exec.call(this, 'Image', 'getAsCanvas'); + }, + + /** + Retrieves image in it's current state as mOxie.Blob object. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsBlob + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {Blob} Image as Blob + */ + getAsBlob: function(type, quality) { + if (!this.size) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + if (!type) { + type = 'image/jpeg'; + } + + if (type === 'image/jpeg' && !quality) { + quality = 90; + } + + return this.getRuntime().exec.call(this, 'Image', 'getAsBlob', type, quality); + }, + + /** + Retrieves image in it's current state as dataURL string. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsDataURL + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {String} Image as dataURL string + */ + getAsDataURL: function(type, quality) { + if (!this.size) { + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + return this.getRuntime().exec.call(this, 'Image', 'getAsDataURL', type, quality); + }, + + /** + Retrieves image in it's current state as binary string. Cannot be run on empty or image in progress (throws + DOMException.INVALID_STATE_ERR). + + @method getAsBinaryString + @param {String} [type="image/jpeg"] Mime type of resulting blob. Can either be image/jpeg or image/png + @param {Number} [quality=90] Applicable only together with mime type image/jpeg + @return {String} Image as binary string + */ + getAsBinaryString: function(type, quality) { + var dataUrl = this.getAsDataURL(type, quality); + return Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7)); + }, + + /** + Embeds a visual representation of the image into the specified node. Depending on the runtime, + it might be a canvas, an img node or a thrid party shim object (Flash or SilverLight - very rare, + can be used in legacy browsers that do not have canvas or proper dataURI support). + + @method embed + @param {DOMElement} el DOM element to insert the image object into + @param {Object} [options] + @param {Number} [options.width] The width of an embed (defaults to the image width) + @param {Number} [options.height] The height of an embed (defaults to the image height) + @param {String} [type="image/jpeg"] Mime type + @param {Number} [quality=90] Quality of an embed, if mime type is image/jpeg + @param {Boolean} [crop=false] Whether to crop an embed to the specified dimensions + */ + embed: function(el) { + var self = this + , imgCopy + , type, quality, crop + , options = arguments[1] || {} + , width = this.width + , height = this.height + , runtime // this has to be outside of all the closures to contain proper runtime + ; + + function onResize() { + // if possible, embed a canvas element directly + if (Env.can('create_canvas')) { + var canvas = imgCopy.getAsCanvas(); + if (canvas) { + el.appendChild(canvas); + canvas = null; + imgCopy.destroy(); + self.trigger('embedded'); + return; + } + } + + var dataUrl = imgCopy.getAsDataURL(type, quality); + if (!dataUrl) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + + if (Env.can('use_data_uri_of', dataUrl.length)) { + el.innerHTML = '<img src="' + dataUrl + '" width="' + imgCopy.width + '" height="' + imgCopy.height + '" />'; + imgCopy.destroy(); + self.trigger('embedded'); + } else { + var tr = new Transporter(); + + tr.bind("TransportingComplete", function() { + runtime = self.connectRuntime(this.result.ruid); + + self.bind("Embedded", function() { + // position and size properly + Basic.extend(runtime.getShimContainer().style, { + //position: 'relative', + top: '0px', + left: '0px', + width: imgCopy.width + 'px', + height: imgCopy.height + 'px' + }); + + // some shims (Flash/SilverLight) reinitialize, if parent element is hidden, reordered or it's + // position type changes (in Gecko), but since we basically need this only in IEs 6/7 and + // sometimes 8 and they do not have this problem, we can comment this for now + /*tr.bind("RuntimeInit", function(e, runtime) { + tr.destroy(); + runtime.destroy(); + onResize.call(self); // re-feed our image data + });*/ + + runtime = null; + }, 999); + + runtime.exec.call(self, "ImageView", "display", this.result.uid, width, height); + imgCopy.destroy(); + }); + + tr.transport(Encode.atob(dataUrl.substring(dataUrl.indexOf('base64,') + 7)), type, Basic.extend({}, options, { + required_caps: { + display_media: true + }, + runtime_order: 'flash,silverlight', + container: el + })); + } + } + + try { + if (!(el = Dom.get(el))) { + throw new x.DOMException(x.DOMException.INVALID_NODE_TYPE_ERR); + } + + if (!this.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + + if (this.width > Image.MAX_RESIZE_WIDTH || this.height > Image.MAX_RESIZE_HEIGHT) { + throw new x.ImageError(x.ImageError.MAX_RESOLUTION_ERR); + } + + type = options.type || this.type || 'image/jpeg'; + quality = options.quality || 90; + crop = Basic.typeOf(options.crop) !== 'undefined' ? options.crop : false; + + // figure out dimensions for the thumb + if (options.width) { + width = options.width; + height = options.height || width; + } else { + // if container element has measurable dimensions, use them + var dimensions = Dom.getSize(el); + if (dimensions.w && dimensions.h) { // both should be > 0 + width = dimensions.w; + height = dimensions.h; + } + } + + imgCopy = new Image(); + + imgCopy.bind("Resize", function() { + onResize.call(self); + }); + + imgCopy.bind("Load", function() { + imgCopy.downsize(width, height, crop, false); + }); + + imgCopy.clone(this, false); + + return imgCopy; + } catch(ex) { + // for now simply trigger error event + this.trigger('error', ex.code); + } + }, + + /** + Properly destroys the image and frees resources in use. If any. Recommended way to dispose mOxie.Image object. + + @method destroy + */ + destroy: function() { + if (this.ruid) { + this.getRuntime().exec.call(this, 'Image', 'destroy'); + this.disconnectRuntime(); + } + this.unbindAll(); + } + }); + + + function _updateInfo(info) { + if (!info) { + info = this.getRuntime().exec.call(this, 'Image', 'getInfo'); + } + + this.size = info.size; + this.width = info.width; + this.height = info.height; + this.type = info.type; + this.meta = info.meta; + + // update file name, only if empty + if (this.name === '') { + this.name = info.name; + } + } + + + function _load(src) { + var srcType = Basic.typeOf(src); + + try { + // if source is Image + if (src instanceof Image) { + if (!src.size) { // only preloaded image objects can be used as source + throw new x.DOMException(x.DOMException.INVALID_STATE_ERR); + } + _loadFromImage.apply(this, arguments); + } + // if source is o.Blob/o.File + else if (src instanceof Blob) { + if (!~Basic.inArray(src.type, ['image/jpeg', 'image/png'])) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + _loadFromBlob.apply(this, arguments); + } + // if native blob/file + else if (Basic.inArray(srcType, ['blob', 'file']) !== -1) { + _load.call(this, new File(null, src), arguments[1]); + } + // if String + else if (srcType === 'string') { + // if dataUrl String + if (/^data:[^;]*;base64,/.test(src)) { + _load.call(this, new Blob(null, { data: src }), arguments[1]); + } + // else assume Url, either relative or absolute + else { + _loadFromUrl.apply(this, arguments); + } + } + // if source seems to be an img node + else if (srcType === 'node' && src.nodeName.toLowerCase() === 'img') { + _load.call(this, src.src, arguments[1]); + } + else { + throw new x.DOMException(x.DOMException.TYPE_MISMATCH_ERR); + } + } catch(ex) { + // for now simply trigger error event + this.trigger('error', ex.code); + } + } + + + function _loadFromImage(img, exact) { + var runtime = this.connectRuntime(img.ruid); + this.ruid = runtime.uid; + runtime.exec.call(this, 'Image', 'loadFromImage', img, (Basic.typeOf(exact) === 'undefined' ? true : exact)); + } + + + function _loadFromBlob(blob, options) { + var self = this; + + self.name = blob.name || ''; + + function exec(runtime) { + self.ruid = runtime.uid; + runtime.exec.call(self, 'Image', 'loadFromBlob', blob); + } + + if (blob.isDetached()) { + this.bind('RuntimeInit', function(e, runtime) { + exec(runtime); + }); + + // convert to object representation + if (options && typeof(options.required_caps) === 'string') { + options.required_caps = Runtime.parseCaps(options.required_caps); + } + + this.connectRuntime(Basic.extend({ + required_caps: { + access_image_binary: true, + resize_image: true + } + }, options)); + } else { + exec(this.connectRuntime(blob.ruid)); + } + } + + + function _loadFromUrl(url, options) { + var self = this, xhr; + + xhr = new XMLHttpRequest(); + + xhr.open('get', url); + xhr.responseType = 'blob'; + + xhr.onprogress = function(e) { + self.trigger(e); + }; + + xhr.onload = function() { + _loadFromBlob.call(self, xhr.response, true); + }; + + xhr.onerror = function(e) { + self.trigger(e); + }; + + xhr.onloadend = function() { + xhr.destroy(); + }; + + xhr.bind('RuntimeError', function(e, err) { + self.trigger('RuntimeError', err); + }); + + xhr.send(null, options); + } + } + + // virtual world will crash on you if image has a resolution higher than this: + Image.MAX_RESIZE_WIDTH = 6500; + Image.MAX_RESIZE_HEIGHT = 6500; + + Image.prototype = EventTarget.instance; + + return Image; +}); + +// Included from: src/javascript/runtime/html5/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global File:true */ + +/** +Defines constructor for HTML5 runtime. + +@class moxie/runtime/html5/Runtime +@private +*/ +define("moxie/runtime/html5/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/Runtime", + "moxie/core/utils/Env" +], function(Basic, x, Runtime, Env) { + + var type = "html5", extensions = {}; + + function Html5Runtime(options) { + var I = this + , Test = Runtime.capTest + , True = Runtime.capTrue + ; + + var caps = Basic.extend({ + access_binary: Test(window.FileReader || window.File && window.File.getAsDataURL), + access_image_binary: function() { + return I.can('access_binary') && !!extensions.Image; + }, + display_media: Test(Env.can('create_canvas') || Env.can('use_data_uri_over32kb')), + do_cors: Test(window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()), + drag_and_drop: Test(function() { + // this comes directly from Modernizr: http://www.modernizr.com/ + var div = document.createElement('div'); + // IE has support for drag and drop since version 5, but doesn't support dropping files from desktop + return (('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && (Env.browser !== 'IE' || Env.version > 9); + }()), + filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest + return (Env.browser === 'Chrome' && Env.version >= 28) || (Env.browser === 'IE' && Env.version >= 10); + }()), + return_response_headers: True, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { // we can fake this one even if it's not supported + return true; + } + return Env.can('return_response_type', responseType); + }, + return_status_code: True, + report_upload_progress: Test(window.XMLHttpRequest && new XMLHttpRequest().upload), + resize_image: function() { + return I.can('access_binary') && Env.can('create_canvas'); + }, + select_file: function() { + return Env.can('use_fileinput') && window.File; + }, + select_folder: function() { + return I.can('select_file') && Env.browser === 'Chrome' && Env.version >= 21; + }, + select_multiple: function() { + // it is buggy on Safari Windows and iOS + return I.can('select_file') && + !(Env.browser === 'Safari' && Env.os === 'Windows') && + !(Env.os === 'iOS' && Env.verComp(Env.osVersion, "7.0.4", '<')); + }, + send_binary_string: Test(window.XMLHttpRequest && (new XMLHttpRequest().sendAsBinary || (window.Uint8Array && window.ArrayBuffer))), + send_custom_headers: Test(window.XMLHttpRequest), + send_multipart: function() { + return !!(window.XMLHttpRequest && new XMLHttpRequest().upload && window.FormData) || I.can('send_binary_string'); + }, + slice_blob: Test(window.File && (File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice)), + stream_upload: function(){ + return I.can('slice_blob') && I.can('send_multipart'); + }, + summon_file_dialog: Test(function() { // yeah... some dirty sniffing here... + return (Env.browser === 'Firefox' && Env.version >= 4) || + (Env.browser === 'Opera' && Env.version >= 12) || + (Env.browser === 'IE' && Env.version >= 10) || + !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']); + }()), + upload_filesize: True + }, + arguments[2] + ); + + Runtime.call(this, options, (arguments[1] || type), caps); + + + Basic.extend(this, { + + init : function() { + this.trigger("Init"); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + destroy = I = null; + }; + }(this.destroy)) + }); + + Basic.extend(this.getShim(), extensions); + } + + Runtime.addConstructor(type, Html5Runtime); + + return extensions; +}); + +// Included from: src/javascript/runtime/html5/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/Blob +@private +*/ +define("moxie/runtime/html5/file/Blob", [ + "moxie/runtime/html5/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + function HTML5Blob() { + function w3cBlobSlice(blob, start, end) { + var blobSlice; + + if (window.File.prototype.slice) { + try { + blob.slice(); // depricated version will throw WRONG_ARGUMENTS_ERR exception + return blob.slice(start, end); + } catch (e) { + // depricated slice method + return blob.slice(start, end - start); + } + // slice method got prefixed: https://bugzilla.mozilla.org/show_bug.cgi?id=649672 + } else if ((blobSlice = window.File.prototype.webkitSlice || window.File.prototype.mozSlice)) { + return blobSlice.call(blob, start, end); + } else { + return null; // or throw some exception + } + } + + this.slice = function() { + return new Blob(this.getRuntime().uid, w3cBlobSlice.apply(this, arguments)); + }; + } + + return (extensions.Blob = HTML5Blob); +}); + +// Included from: src/javascript/core/utils/Events.js + +/** + * Events.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +define('moxie/core/utils/Events', [ + 'moxie/core/utils/Basic' +], function(Basic) { + var eventhash = {}, uid = 'moxie_' + Basic.guid(); + + // IE W3C like event funcs + function preventDefault() { + this.returnValue = false; + } + + function stopPropagation() { + this.cancelBubble = true; + } + + /** + Adds an event handler to the specified object and store reference to the handler + in objects internal Plupload registry (@see removeEvent). + + @method addEvent + @for Utils + @static + @param {Object} obj DOM element like object to add handler to. + @param {String} name Name to add event listener to. + @param {Function} callback Function to call when event occurs. + @param {String} [key] that might be used to add specifity to the event record. + */ + var addEvent = function(obj, name, callback, key) { + var func, events; + + name = name.toLowerCase(); + + // Add event listener + if (obj.addEventListener) { + func = callback; + + obj.addEventListener(name, func, false); + } else if (obj.attachEvent) { + func = function() { + var evt = window.event; + + if (!evt.target) { + evt.target = evt.srcElement; + } + + evt.preventDefault = preventDefault; + evt.stopPropagation = stopPropagation; + + callback(evt); + }; + + obj.attachEvent('on' + name, func); + } + + // Log event handler to objects internal mOxie registry + if (!obj[uid]) { + obj[uid] = Basic.guid(); + } + + if (!eventhash.hasOwnProperty(obj[uid])) { + eventhash[obj[uid]] = {}; + } + + events = eventhash[obj[uid]]; + + if (!events.hasOwnProperty(name)) { + events[name] = []; + } + + events[name].push({ + func: func, + orig: callback, // store original callback for IE + key: key + }); + }; + + + /** + Remove event handler from the specified object. If third argument (callback) + is not specified remove all events with the specified name. + + @method removeEvent + @static + @param {Object} obj DOM element to remove event listener(s) from. + @param {String} name Name of event listener to remove. + @param {Function|String} [callback] might be a callback or unique key to match. + */ + var removeEvent = function(obj, name, callback) { + var type, undef; + + name = name.toLowerCase(); + + if (obj[uid] && eventhash[obj[uid]] && eventhash[obj[uid]][name]) { + type = eventhash[obj[uid]][name]; + } else { + return; + } + + for (var i = type.length - 1; i >= 0; i--) { + // undefined or not, key should match + if (type[i].orig === callback || type[i].key === callback) { + if (obj.removeEventListener) { + obj.removeEventListener(name, type[i].func, false); + } else if (obj.detachEvent) { + obj.detachEvent('on'+name, type[i].func); + } + + type[i].orig = null; + type[i].func = null; + type.splice(i, 1); + + // If callback was passed we are done here, otherwise proceed + if (callback !== undef) { + break; + } + } + } + + // If event array got empty, remove it + if (!type.length) { + delete eventhash[obj[uid]][name]; + } + + // If mOxie registry has become empty, remove it + if (Basic.isEmptyObj(eventhash[obj[uid]])) { + delete eventhash[obj[uid]]; + + // IE doesn't let you remove DOM object property with - delete + try { + delete obj[uid]; + } catch(e) { + obj[uid] = undef; + } + } + }; + + + /** + Remove all kind of events from the specified object + + @method removeAllEvents + @static + @param {Object} obj DOM element to remove event listeners from. + @param {String} [key] unique key to match, when removing events. + */ + var removeAllEvents = function(obj, key) { + if (!obj || !obj[uid]) { + return; + } + + Basic.each(eventhash[obj[uid]], function(events, name) { + removeEvent(obj, name, key); + }); + }; + + return { + addEvent: addEvent, + removeEvent: removeEvent, + removeAllEvents: removeAllEvents + }; +}); + +// Included from: src/javascript/runtime/html5/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileInput +@private +*/ +define("moxie/runtime/html5/file/FileInput", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, Basic, Dom, Events, Mime, Env) { + + function FileInput() { + var _files = [], _options; + + Basic.extend(this, { + init: function(options) { + var comp = this, I = comp.getRuntime(), input, shimContainer, mimes, browseButton, zIndex, top; + + _options = options; + _files = []; + + // figure out accept string + mimes = _options.accept.mimes || Mime.extList2mimes(_options.accept, I.can('filter_by_extension')); + + shimContainer = I.getShimContainer(); + + shimContainer.innerHTML = '<input id="' + I.uid +'" type="file" style="font-size:999px;opacity:0;"' + + (_options.multiple && I.can('select_multiple') ? 'multiple' : '') + + (_options.directory && I.can('select_folder') ? 'webkitdirectory directory' : '') + // Chrome 11+ + (mimes ? ' accept="' + mimes.join(',') + '"' : '') + ' />'; + + input = Dom.get(I.uid); + + // prepare file input to be placed underneath the browse_button element + Basic.extend(input.style, { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + + browseButton = Dom.get(_options.browse_button); + + // Route click event to the input[type=file] element for browsers that support such behavior + if (I.can('summon_file_dialog')) { + if (Dom.getStyle(browseButton, 'position') === 'static') { + browseButton.style.position = 'relative'; + } + + zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 1; + + browseButton.style.zIndex = zIndex; + shimContainer.style.zIndex = zIndex - 1; + + Events.addEvent(browseButton, 'click', function(e) { + var input = Dom.get(I.uid); + if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file] + input.click(); + } + e.preventDefault(); + }, comp.uid); + } + + /* Since we have to place input[type=file] on top of the browse_button for some browsers, + browse_button loses interactivity, so we restore it here */ + top = I.can('summon_file_dialog') ? browseButton : shimContainer; + + Events.addEvent(top, 'mouseover', function() { + comp.trigger('mouseenter'); + }, comp.uid); + + Events.addEvent(top, 'mouseout', function() { + comp.trigger('mouseleave'); + }, comp.uid); + + Events.addEvent(top, 'mousedown', function() { + comp.trigger('mousedown'); + }, comp.uid); + + Events.addEvent(Dom.get(_options.container), 'mouseup', function() { + comp.trigger('mouseup'); + }, comp.uid); + + + input.onchange = function onChange() { // there should be only one handler for this + _files = []; + + if (_options.directory) { + // folders are represented by dots, filter them out (Chrome 11+) + Basic.each(this.files, function(file) { + if (file.name !== ".") { // if it doesn't looks like a folder + _files.push(file); + } + }); + } else { + _files = [].slice.call(this.files); + } + + // clearing the value enables the user to select the same file again if they want to + if (Env.browser !== 'IE' && Env.browser !== 'IEMobile') { + this.value = ''; + } else { + // in IE input[type="file"] is read-only so the only way to reset it is to re-insert it + var clone = this.cloneNode(true); + this.parentNode.replaceChild(clone, this); + clone.onchange = onChange; + } + comp.trigger('change'); + }; + + // ready event is perfectly asynchronous + comp.trigger({ + type: 'ready', + async: true + }); + + shimContainer = null; + }, + + getFiles: function() { + return _files; + }, + + disable: function(state) { + var I = this.getRuntime(), input; + + if ((input = Dom.get(I.uid))) { + input.disabled = !!state; + } + }, + + destroy: function() { + var I = this.getRuntime() + , shim = I.getShim() + , shimContainer = I.getShimContainer() + ; + + Events.removeAllEvents(shimContainer, this.uid); + Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); + Events.removeAllEvents(_options && Dom.get(_options.browse_button), this.uid); + + if (shimContainer) { + shimContainer.innerHTML = ''; + } + + shim.removeInstance(this.uid); + + _files = _options = shimContainer = shim = null; + } + }); + } + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/html5/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileDrop +@private +*/ +define("moxie/runtime/html5/file/FileDrop", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime" +], function(extensions, Basic, Dom, Events, Mime) { + + function FileDrop() { + var _files = [], _allowedExts = [], _options; + + Basic.extend(this, { + init: function(options) { + var comp = this, dropZone; + + _options = options; + _allowedExts = _extractExts(_options.accept); + dropZone = _options.container; + + Events.addEvent(dropZone, 'dragover', function(e) { + if (!_hasFiles(e)) { + return; + } + e.preventDefault(); + e.dataTransfer.dropEffect = 'copy'; + }, comp.uid); + + Events.addEvent(dropZone, 'drop', function(e) { + if (!_hasFiles(e)) { + return; + } + e.preventDefault(); + + _files = []; + + // Chrome 21+ accepts folders via Drag'n'Drop + if (e.dataTransfer.items && e.dataTransfer.items[0].webkitGetAsEntry) { + _readItems(e.dataTransfer.items, function() { + comp.trigger("drop"); + }); + } else { + Basic.each(e.dataTransfer.files, function(file) { + if (_isAcceptable(file)) { + _files.push(file); + } + }); + comp.trigger("drop"); + } + }, comp.uid); + + Events.addEvent(dropZone, 'dragenter', function(e) { + comp.trigger("dragenter"); + }, comp.uid); + + Events.addEvent(dropZone, 'dragleave', function(e) { + comp.trigger("dragleave"); + }, comp.uid); + }, + + getFiles: function() { + return _files; + }, + + destroy: function() { + Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); + _files = _allowedExts = _options = null; + } + }); + + + function _hasFiles(e) { + if (!e.dataTransfer || !e.dataTransfer.types) { // e.dataTransfer.files is not available in Gecko during dragover + return false; + } + + var types = Basic.toArray(e.dataTransfer.types || []); + + return Basic.inArray("Files", types) !== -1 || + Basic.inArray("public.file-url", types) !== -1 || // Safari < 5 + Basic.inArray("application/x-moz-file", types) !== -1 // Gecko < 1.9.2 (< Firefox 3.6) + ; + } + + + function _extractExts(accept) { + var exts = []; + for (var i = 0; i < accept.length; i++) { + [].push.apply(exts, accept[i].extensions.split(/\s*,\s*/)); + } + return Basic.inArray('*', exts) === -1 ? exts : []; + } + + + function _isAcceptable(file) { + if (!_allowedExts.length) { + return true; + } + var ext = Mime.getFileExtension(file.name); + return !ext || Basic.inArray(ext, _allowedExts) !== -1; + } + + + function _readItems(items, cb) { + var entries = []; + Basic.each(items, function(item) { + var entry = item.webkitGetAsEntry(); + // Address #998 (https://code.google.com/p/chromium/issues/detail?id=332579) + if (entry) { + // file() fails on OSX when the filename contains a special character (e.g. umlaut): see #61 + if (entry.isFile) { + var file = item.getAsFile(); + if (_isAcceptable(file)) { + _files.push(file); + } + } else { + entries.push(entry); + } + } + }); + + if (entries.length) { + _readEntries(entries, cb); + } else { + cb(); + } + } + + + function _readEntries(entries, cb) { + var queue = []; + Basic.each(entries, function(entry) { + queue.push(function(cbcb) { + _readEntry(entry, cbcb); + }); + }); + Basic.inSeries(queue, function() { + cb(); + }); + } + + + function _readEntry(entry, cb) { + if (entry.isFile) { + entry.file(function(file) { + if (_isAcceptable(file)) { + _files.push(file); + } + cb(); + }, function() { + // fire an error event maybe + cb(); + }); + } else if (entry.isDirectory) { + _readDirEntry(entry, cb); + } else { + cb(); // not file, not directory? what then?.. + } + } + + + function _readDirEntry(dirEntry, cb) { + var entries = [], dirReader = dirEntry.createReader(); + + // keep quering recursively till no more entries + function getEntries(cbcb) { + dirReader.readEntries(function(moreEntries) { + if (moreEntries.length) { + [].push.apply(entries, moreEntries); + getEntries(cbcb); + } else { + cbcb(); + } + }, cbcb); + } + + // ...and you thought FileReader was crazy... + getEntries(function() { + _readEntries(entries, cb); + }); + } + } + + return (extensions.FileDrop = FileDrop); +}); + +// Included from: src/javascript/runtime/html5/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/file/FileReader +@private +*/ +define("moxie/runtime/html5/file/FileReader", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Encode", + "moxie/core/utils/Basic" +], function(extensions, Encode, Basic) { + + function FileReader() { + var _fr, _convertToBinary = false; + + Basic.extend(this, { + + read: function(op, blob) { + var target = this; + + _fr = new window.FileReader(); + + _fr.addEventListener('progress', function(e) { + target.trigger(e); + }); + + _fr.addEventListener('load', function(e) { + target.trigger(e); + }); + + _fr.addEventListener('error', function(e) { + target.trigger(e, _fr.error); + }); + + _fr.addEventListener('loadend', function() { + _fr = null; + }); + + if (Basic.typeOf(_fr[op]) === 'function') { + _convertToBinary = false; + _fr[op](blob.getSource()); + } else if (op === 'readAsBinaryString') { // readAsBinaryString is depricated in general and never existed in IE10+ + _convertToBinary = true; + _fr.readAsDataURL(blob.getSource()); + } + }, + + getResult: function() { + return _fr && _fr.result ? (_convertToBinary ? _toBinary(_fr.result) : _fr.result) : null; + }, + + abort: function() { + if (_fr) { + _fr.abort(); + } + }, + + destroy: function() { + _fr = null; + } + }); + + function _toBinary(str) { + return Encode.atob(str.substring(str.indexOf('base64,') + 7)); + } + } + + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/html5/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +@class moxie/runtime/html5/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/html5/xhr/XMLHttpRequest", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Mime", + "moxie/core/utils/Url", + "moxie/file/File", + "moxie/file/Blob", + "moxie/xhr/FormData", + "moxie/core/Exceptions", + "moxie/core/utils/Env" +], function(extensions, Basic, Mime, Url, File, Blob, FormData, x, Env) { + + function XMLHttpRequest() { + var self = this + , _xhr + , _filename + ; + + Basic.extend(this, { + send: function(meta, data) { + var target = this + , isGecko2_5_6 = (Env.browser === 'Mozilla' && Env.version >= 4 && Env.version < 7) + , isAndroidBrowser = Env.browser === 'Android Browser' + , mustSendAsBinary = false + ; + + // extract file name + _filename = meta.url.replace(/^.+?\/([\w\-\.]+)$/, '$1').toLowerCase(); + + _xhr = _getNativeXHR(); + _xhr.open(meta.method, meta.url, meta.async, meta.user, meta.password); + + + // prepare data to be sent + if (data instanceof Blob) { + if (data.isDetached()) { + mustSendAsBinary = true; + } + data = data.getSource(); + } else if (data instanceof FormData) { + + if (data.hasBlob()) { + if (data.getBlob().isDetached()) { + data = _prepareMultipart.call(target, data); // _xhr must be instantiated and be in OPENED state + mustSendAsBinary = true; + } else if ((isGecko2_5_6 || isAndroidBrowser) && Basic.typeOf(data.getBlob().getSource()) === 'blob' && window.FileReader) { + // Gecko 2/5/6 can't send blob in FormData: https://bugzilla.mozilla.org/show_bug.cgi?id=649150 + // Android browsers (default one and Dolphin) seem to have the same issue, see: #613 + _preloadAndSend.call(target, meta, data); + return; // _preloadAndSend will reinvoke send() with transmutated FormData =%D + } + } + + // transfer fields to real FormData + if (data instanceof FormData) { // if still a FormData, e.g. not mangled by _prepareMultipart() + var fd = new window.FormData(); + data.each(function(value, name) { + if (value instanceof Blob) { + fd.append(name, value.getSource()); + } else { + fd.append(name, value); + } + }); + data = fd; + } + } + + + // if XHR L2 + if (_xhr.upload) { + if (meta.withCredentials) { + _xhr.withCredentials = true; + } + + _xhr.addEventListener('load', function(e) { + target.trigger(e); + }); + + _xhr.addEventListener('error', function(e) { + target.trigger(e); + }); + + // additionally listen to progress events + _xhr.addEventListener('progress', function(e) { + target.trigger(e); + }); + + _xhr.upload.addEventListener('progress', function(e) { + target.trigger({ + type: 'UploadProgress', + loaded: e.loaded, + total: e.total + }); + }); + // ... otherwise simulate XHR L2 + } else { + _xhr.onreadystatechange = function onReadyStateChange() { + + // fake Level 2 events + switch (_xhr.readyState) { + + case 1: // XMLHttpRequest.OPENED + // readystatechanged is fired twice for OPENED state (in IE and Mozilla) - neu + break; + + // looks like HEADERS_RECEIVED (state 2) is not reported in Opera (or it's old versions) - neu + case 2: // XMLHttpRequest.HEADERS_RECEIVED + break; + + case 3: // XMLHttpRequest.LOADING + // try to fire progress event for not XHR L2 + var total, loaded; + + try { + if (Url.hasSameOrigin(meta.url)) { // Content-Length not accessible for cross-domain on some browsers + total = _xhr.getResponseHeader('Content-Length') || 0; // old Safari throws an exception here + } + + if (_xhr.responseText) { // responseText was introduced in IE7 + loaded = _xhr.responseText.length; + } + } catch(ex) { + total = loaded = 0; + } + + target.trigger({ + type: 'progress', + lengthComputable: !!total, + total: parseInt(total, 10), + loaded: loaded + }); + break; + + case 4: // XMLHttpRequest.DONE + // release readystatechange handler (mostly for IE) + _xhr.onreadystatechange = function() {}; + + // usually status 0 is returned when server is unreachable, but FF also fails to status 0 for 408 timeout + if (_xhr.status === 0) { + target.trigger('error'); + } else { + target.trigger('load'); + } + break; + } + }; + } + + + // set request headers + if (!Basic.isEmptyObj(meta.headers)) { + Basic.each(meta.headers, function(value, header) { + _xhr.setRequestHeader(header, value); + }); + } + + // request response type + if ("" !== meta.responseType && 'responseType' in _xhr) { + if ('json' === meta.responseType && !Env.can('return_response_type', 'json')) { // we can fake this one + _xhr.responseType = 'text'; + } else { + _xhr.responseType = meta.responseType; + } + } + + // send ... + if (!mustSendAsBinary) { + _xhr.send(data); + } else { + if (_xhr.sendAsBinary) { // Gecko + _xhr.sendAsBinary(data); + } else { // other browsers having support for typed arrays + (function() { + // mimic Gecko's sendAsBinary + var ui8a = new Uint8Array(data.length); + for (var i = 0; i < data.length; i++) { + ui8a[i] = (data.charCodeAt(i) & 0xff); + } + _xhr.send(ui8a.buffer); + }()); + } + } + + target.trigger('loadstart'); + }, + + getStatus: function() { + // according to W3C spec it should return 0 for readyState < 3, but instead it throws an exception + try { + if (_xhr) { + return _xhr.status; + } + } catch(ex) {} + return 0; + }, + + getResponse: function(responseType) { + var I = this.getRuntime(); + + try { + switch (responseType) { + case 'blob': + var file = new File(I.uid, _xhr.response); + + // try to extract file name from content-disposition if possible (might be - not, if CORS for example) + var disposition = _xhr.getResponseHeader('Content-Disposition'); + if (disposition) { + // extract filename from response header if available + var match = disposition.match(/filename=([\'\"'])([^\1]+)\1/); + if (match) { + _filename = match[2]; + } + } + file.name = _filename; + + // pre-webkit Opera doesn't set type property on the blob response + if (!file.type) { + file.type = Mime.getFileMime(_filename); + } + return file; + + case 'json': + if (!Env.can('return_response_type', 'json')) { + return _xhr.status === 200 && !!window.JSON ? JSON.parse(_xhr.responseText) : null; + } + return _xhr.response; + + case 'document': + return _getDocument(_xhr); + + default: + return _xhr.responseText !== '' ? _xhr.responseText : null; // against the specs, but for consistency across the runtimes + } + } catch(ex) { + return null; + } + }, + + getAllResponseHeaders: function() { + try { + return _xhr.getAllResponseHeaders(); + } catch(ex) {} + return ''; + }, + + abort: function() { + if (_xhr) { + _xhr.abort(); + } + }, + + destroy: function() { + self = _filename = null; + } + }); + + + // here we go... ugly fix for ugly bug + function _preloadAndSend(meta, data) { + var target = this, blob, fr; + + // get original blob + blob = data.getBlob().getSource(); + + // preload blob in memory to be sent as binary string + fr = new window.FileReader(); + fr.onload = function() { + // overwrite original blob + data.append(data.getBlobName(), new Blob(null, { + type: blob.type, + data: fr.result + })); + // invoke send operation again + self.send.call(target, meta, data); + }; + fr.readAsBinaryString(blob); + } + + + function _getNativeXHR() { + if (window.XMLHttpRequest && !(Env.browser === 'IE' && Env.version < 8)) { // IE7 has native XHR but it's buggy + return new window.XMLHttpRequest(); + } else { + return (function() { + var progIDs = ['Msxml2.XMLHTTP.6.0', 'Microsoft.XMLHTTP']; // if 6.0 available, use it, otherwise failback to default 3.0 + for (var i = 0; i < progIDs.length; i++) { + try { + return new ActiveXObject(progIDs[i]); + } catch (ex) {} + } + })(); + } + } + + // @credits Sergey Ilinsky (http://www.ilinsky.com/) + function _getDocument(xhr) { + var rXML = xhr.responseXML; + var rText = xhr.responseText; + + // Try parsing responseText (@see: http://www.ilinsky.com/articles/XMLHttpRequest/#bugs-ie-responseXML-content-type) + if (Env.browser === 'IE' && rText && rXML && !rXML.documentElement && /[^\/]+\/[^\+]+\+xml/.test(xhr.getResponseHeader("Content-Type"))) { + rXML = new window.ActiveXObject("Microsoft.XMLDOM"); + rXML.async = false; + rXML.validateOnParse = false; + rXML.loadXML(rText); + } + + // Check if there is no error in document + if (rXML) { + if ((Env.browser === 'IE' && rXML.parseError !== 0) || !rXML.documentElement || rXML.documentElement.tagName === "parsererror") { + return null; + } + } + return rXML; + } + + + function _prepareMultipart(fd) { + var boundary = '----moxieboundary' + new Date().getTime() + , dashdash = '--' + , crlf = '\r\n' + , multipart = '' + , I = this.getRuntime() + ; + + if (!I.can('send_binary_string')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + + _xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); + + // append multipart parameters + fd.each(function(value, name) { + // Firefox 3.6 failed to convert multibyte characters to UTF-8 in sendAsBinary(), + // so we try it here ourselves with: unescape(encodeURIComponent(value)) + if (value instanceof Blob) { + // Build RFC2388 blob + multipart += dashdash + boundary + crlf + + 'Content-Disposition: form-data; name="' + name + '"; filename="' + unescape(encodeURIComponent(value.name || 'blob')) + '"' + crlf + + 'Content-Type: ' + (value.type || 'application/octet-stream') + crlf + crlf + + value.getSource() + crlf; + } else { + multipart += dashdash + boundary + crlf + + 'Content-Disposition: form-data; name="' + name + '"' + crlf + crlf + + unescape(encodeURIComponent(value)) + crlf; + } + }); + + multipart += dashdash + boundary + dashdash + crlf; + + return multipart; + } + } + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/html5/utils/BinaryReader.js + +/** + * BinaryReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/utils/BinaryReader +@private +*/ +define("moxie/runtime/html5/utils/BinaryReader", [], function() { + return function() { + var II = false, bin; + + // Private functions + function read(idx, size) { + var mv = II ? 0 : -8 * (size - 1), sum = 0, i; + + for (i = 0; i < size; i++) { + sum |= (bin.charCodeAt(idx + i) << Math.abs(mv + i*8)); + } + + return sum; + } + + function putstr(segment, idx, length) { + length = arguments.length === 3 ? length : bin.length - idx - 1; + bin = bin.substr(0, idx) + segment + bin.substr(length + idx); + } + + function write(idx, num, size) { + var str = '', mv = II ? 0 : -8 * (size - 1), i; + + for (i = 0; i < size; i++) { + str += String.fromCharCode((num >> Math.abs(mv + i*8)) & 255); + } + + putstr(str, idx, size); + } + + // Public functions + return { + II: function(order) { + if (order === undefined) { + return II; + } else { + II = order; + } + }, + + init: function(binData) { + II = false; + bin = binData; + }, + + SEGMENT: function(idx, length, segment) { + switch (arguments.length) { + case 1: + return bin.substr(idx, bin.length - idx - 1); + case 2: + return bin.substr(idx, length); + case 3: + putstr(segment, idx, length); + break; + default: return bin; + } + }, + + BYTE: function(idx) { + return read(idx, 1); + }, + + SHORT: function(idx) { + return read(idx, 2); + }, + + LONG: function(idx, num) { + if (num === undefined) { + return read(idx, 4); + } else { + write(idx, num, 4); + } + }, + + SLONG: function(idx) { // 2's complement notation + var num = read(idx, 4); + + return (num > 2147483647 ? num - 4294967296 : num); + }, + + STRING: function(idx, size) { + var str = ''; + + for (size += idx; idx < size; idx++) { + str += String.fromCharCode(read(idx, 1)); + } + + return str; + } + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/JPEGHeaders.js + +/** + * JPEGHeaders.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/JPEGHeaders +@private +*/ +define("moxie/runtime/html5/image/JPEGHeaders", [ + "moxie/runtime/html5/utils/BinaryReader" +], function(BinaryReader) { + + return function JPEGHeaders(data) { + var headers = [], read, idx, marker, length = 0; + + read = new BinaryReader(); + read.init(data); + + // Check if data is jpeg + if (read.SHORT(0) !== 0xFFD8) { + return; + } + + idx = 2; + + while (idx <= data.length) { + marker = read.SHORT(idx); + + // omit RST (restart) markers + if (marker >= 0xFFD0 && marker <= 0xFFD7) { + idx += 2; + continue; + } + + // no headers allowed after SOS marker + if (marker === 0xFFDA || marker === 0xFFD9) { + break; + } + + length = read.SHORT(idx + 2) + 2; + + // APPn marker detected + if (marker >= 0xFFE1 && marker <= 0xFFEF) { + headers.push({ + hex: marker, + name: 'APP' + (marker & 0x000F), + start: idx, + length: length, + segment: read.SEGMENT(idx, length) + }); + } + + idx += length; + } + + read.init(null); // free memory + + return { + headers: headers, + + restore: function(data) { + var max, i; + + read.init(data); + + idx = read.SHORT(2) == 0xFFE0 ? 4 + read.SHORT(4) : 2; + + for (i = 0, max = headers.length; i < max; i++) { + read.SEGMENT(idx, 0, headers[i].segment); + idx += headers[i].length; + } + + data = read.SEGMENT(); + read.init(null); + return data; + }, + + strip: function(data) { + var headers, jpegHeaders, i; + + jpegHeaders = new JPEGHeaders(data); + headers = jpegHeaders.headers; + jpegHeaders.purge(); + + read.init(data); + + i = headers.length; + while (i--) { + read.SEGMENT(headers[i].start, headers[i].length, ''); + } + + data = read.SEGMENT(); + read.init(null); + return data; + }, + + get: function(name) { + var array = []; + + for (var i = 0, max = headers.length; i < max; i++) { + if (headers[i].name === name.toUpperCase()) { + array.push(headers[i].segment); + } + } + return array; + }, + + set: function(name, segment) { + var array = [], i, ii, max; + + if (typeof(segment) === 'string') { + array.push(segment); + } else { + array = segment; + } + + for (i = ii = 0, max = headers.length; i < max; i++) { + if (headers[i].name === name.toUpperCase()) { + headers[i].segment = array[ii]; + headers[i].length = array[ii].length; + ii++; + } + if (ii >= array.length) { + break; + } + } + }, + + purge: function() { + headers = []; + read.init(null); + read = null; + } + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/ExifParser.js + +/** + * ExifParser.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/ExifParser +@private +*/ +define("moxie/runtime/html5/image/ExifParser", [ + "moxie/core/utils/Basic", + "moxie/runtime/html5/utils/BinaryReader" +], function(Basic, BinaryReader) { + + return function ExifParser() { + // Private ExifParser fields + var data, tags, Tiff, offsets = {}, tagDescs; + + data = new BinaryReader(); + + tags = { + tiff : { + /* + The image orientation viewed in terms of rows and columns. + + 1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side. + 2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side. + 3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side. + 4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side. + 5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top. + 6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top. + 7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. + 8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. + */ + 0x0112: 'Orientation', + 0x010E: 'ImageDescription', + 0x010F: 'Make', + 0x0110: 'Model', + 0x0131: 'Software', + 0x8769: 'ExifIFDPointer', + 0x8825: 'GPSInfoIFDPointer' + }, + exif : { + 0x9000: 'ExifVersion', + 0xA001: 'ColorSpace', + 0xA002: 'PixelXDimension', + 0xA003: 'PixelYDimension', + 0x9003: 'DateTimeOriginal', + 0x829A: 'ExposureTime', + 0x829D: 'FNumber', + 0x8827: 'ISOSpeedRatings', + 0x9201: 'ShutterSpeedValue', + 0x9202: 'ApertureValue' , + 0x9207: 'MeteringMode', + 0x9208: 'LightSource', + 0x9209: 'Flash', + 0x920A: 'FocalLength', + 0xA402: 'ExposureMode', + 0xA403: 'WhiteBalance', + 0xA406: 'SceneCaptureType', + 0xA404: 'DigitalZoomRatio', + 0xA408: 'Contrast', + 0xA409: 'Saturation', + 0xA40A: 'Sharpness' + }, + gps : { + 0x0000: 'GPSVersionID', + 0x0001: 'GPSLatitudeRef', + 0x0002: 'GPSLatitude', + 0x0003: 'GPSLongitudeRef', + 0x0004: 'GPSLongitude' + } + }; + + tagDescs = { + 'ColorSpace': { + 1: 'sRGB', + 0: 'Uncalibrated' + }, + + 'MeteringMode': { + 0: 'Unknown', + 1: 'Average', + 2: 'CenterWeightedAverage', + 3: 'Spot', + 4: 'MultiSpot', + 5: 'Pattern', + 6: 'Partial', + 255: 'Other' + }, + + 'LightSource': { + 1: 'Daylight', + 2: 'Fliorescent', + 3: 'Tungsten', + 4: 'Flash', + 9: 'Fine weather', + 10: 'Cloudy weather', + 11: 'Shade', + 12: 'Daylight fluorescent (D 5700 - 7100K)', + 13: 'Day white fluorescent (N 4600 -5400K)', + 14: 'Cool white fluorescent (W 3900 - 4500K)', + 15: 'White fluorescent (WW 3200 - 3700K)', + 17: 'Standard light A', + 18: 'Standard light B', + 19: 'Standard light C', + 20: 'D55', + 21: 'D65', + 22: 'D75', + 23: 'D50', + 24: 'ISO studio tungsten', + 255: 'Other' + }, + + 'Flash': { + 0x0000: 'Flash did not fire.', + 0x0001: 'Flash fired.', + 0x0005: 'Strobe return light not detected.', + 0x0007: 'Strobe return light detected.', + 0x0009: 'Flash fired, compulsory flash mode', + 0x000D: 'Flash fired, compulsory flash mode, return light not detected', + 0x000F: 'Flash fired, compulsory flash mode, return light detected', + 0x0010: 'Flash did not fire, compulsory flash mode', + 0x0018: 'Flash did not fire, auto mode', + 0x0019: 'Flash fired, auto mode', + 0x001D: 'Flash fired, auto mode, return light not detected', + 0x001F: 'Flash fired, auto mode, return light detected', + 0x0020: 'No flash function', + 0x0041: 'Flash fired, red-eye reduction mode', + 0x0045: 'Flash fired, red-eye reduction mode, return light not detected', + 0x0047: 'Flash fired, red-eye reduction mode, return light detected', + 0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode', + 0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected', + 0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected', + 0x0059: 'Flash fired, auto mode, red-eye reduction mode', + 0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode', + 0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode' + }, + + 'ExposureMode': { + 0: 'Auto exposure', + 1: 'Manual exposure', + 2: 'Auto bracket' + }, + + 'WhiteBalance': { + 0: 'Auto white balance', + 1: 'Manual white balance' + }, + + 'SceneCaptureType': { + 0: 'Standard', + 1: 'Landscape', + 2: 'Portrait', + 3: 'Night scene' + }, + + 'Contrast': { + 0: 'Normal', + 1: 'Soft', + 2: 'Hard' + }, + + 'Saturation': { + 0: 'Normal', + 1: 'Low saturation', + 2: 'High saturation' + }, + + 'Sharpness': { + 0: 'Normal', + 1: 'Soft', + 2: 'Hard' + }, + + // GPS related + 'GPSLatitudeRef': { + N: 'North latitude', + S: 'South latitude' + }, + + 'GPSLongitudeRef': { + E: 'East longitude', + W: 'West longitude' + } + }; + + function extractTags(IFD_offset, tags2extract) { + var length = data.SHORT(IFD_offset), i, ii, + tag, type, count, tagOffset, offset, value, values = [], hash = {}; + + for (i = 0; i < length; i++) { + // Set binary reader pointer to beginning of the next tag + offset = tagOffset = IFD_offset + 12 * i + 2; + + tag = tags2extract[data.SHORT(offset)]; + + if (tag === undefined) { + continue; // Not the tag we requested + } + + type = data.SHORT(offset+=2); + count = data.LONG(offset+=2); + + offset += 4; + values = []; + + switch (type) { + case 1: // BYTE + case 7: // UNDEFINED + if (count > 4) { + offset = data.LONG(offset) + offsets.tiffHeader; + } + + for (ii = 0; ii < count; ii++) { + values[ii] = data.BYTE(offset + ii); + } + + break; + + case 2: // STRING + if (count > 4) { + offset = data.LONG(offset) + offsets.tiffHeader; + } + + hash[tag] = data.STRING(offset, count - 1); + + continue; + + case 3: // SHORT + if (count > 2) { + offset = data.LONG(offset) + offsets.tiffHeader; + } + + for (ii = 0; ii < count; ii++) { + values[ii] = data.SHORT(offset + ii*2); + } + + break; + + case 4: // LONG + if (count > 1) { + offset = data.LONG(offset) + offsets.tiffHeader; + } + + for (ii = 0; ii < count; ii++) { + values[ii] = data.LONG(offset + ii*4); + } + + break; + + case 5: // RATIONAL + offset = data.LONG(offset) + offsets.tiffHeader; + + for (ii = 0; ii < count; ii++) { + values[ii] = data.LONG(offset + ii*4) / data.LONG(offset + ii*4 + 4); + } + + break; + + case 9: // SLONG + offset = data.LONG(offset) + offsets.tiffHeader; + + for (ii = 0; ii < count; ii++) { + values[ii] = data.SLONG(offset + ii*4); + } + + break; + + case 10: // SRATIONAL + offset = data.LONG(offset) + offsets.tiffHeader; + + for (ii = 0; ii < count; ii++) { + values[ii] = data.SLONG(offset + ii*4) / data.SLONG(offset + ii*4 + 4); + } + + break; + + default: + continue; + } + + value = (count == 1 ? values[0] : values); + + if (tagDescs.hasOwnProperty(tag) && typeof value != 'object') { + hash[tag] = tagDescs[tag][value]; + } else { + hash[tag] = value; + } + } + + return hash; + } + + function getIFDOffsets() { + var idx = offsets.tiffHeader; + + // Set read order of multi-byte data + data.II(data.SHORT(idx) == 0x4949); + + // Check if always present bytes are indeed present + if (data.SHORT(idx+=2) !== 0x002A) { + return false; + } + + offsets.IFD0 = offsets.tiffHeader + data.LONG(idx += 2); + Tiff = extractTags(offsets.IFD0, tags.tiff); + + if ('ExifIFDPointer' in Tiff) { + offsets.exifIFD = offsets.tiffHeader + Tiff.ExifIFDPointer; + delete Tiff.ExifIFDPointer; + } + + if ('GPSInfoIFDPointer' in Tiff) { + offsets.gpsIFD = offsets.tiffHeader + Tiff.GPSInfoIFDPointer; + delete Tiff.GPSInfoIFDPointer; + } + return true; + } + + // At the moment only setting of simple (LONG) values, that do not require offset recalculation, is supported + function setTag(ifd, tag, value) { + var offset, length, tagOffset, valueOffset = 0; + + // If tag name passed translate into hex key + if (typeof(tag) === 'string') { + var tmpTags = tags[ifd.toLowerCase()]; + for (var hex in tmpTags) { + if (tmpTags[hex] === tag) { + tag = hex; + break; + } + } + } + offset = offsets[ifd.toLowerCase() + 'IFD']; + length = data.SHORT(offset); + + for (var i = 0; i < length; i++) { + tagOffset = offset + 12 * i + 2; + + if (data.SHORT(tagOffset) == tag) { + valueOffset = tagOffset + 8; + break; + } + } + + if (!valueOffset) { + return false; + } + + data.LONG(valueOffset, value); + return true; + } + + + // Public functions + return { + init: function(segment) { + // Reset internal data + offsets = { + tiffHeader: 10 + }; + + if (segment === undefined || !segment.length) { + return false; + } + + data.init(segment); + + // Check if that's APP1 and that it has EXIF + if (data.SHORT(0) === 0xFFE1 && data.STRING(4, 5).toUpperCase() === "EXIF\0") { + return getIFDOffsets(); + } + return false; + }, + + TIFF: function() { + return Tiff; + }, + + EXIF: function() { + var Exif; + + // Populate EXIF hash + Exif = extractTags(offsets.exifIFD, tags.exif); + + // Fix formatting of some tags + if (Exif.ExifVersion && Basic.typeOf(Exif.ExifVersion) === 'array') { + for (var i = 0, exifVersion = ''; i < Exif.ExifVersion.length; i++) { + exifVersion += String.fromCharCode(Exif.ExifVersion[i]); + } + Exif.ExifVersion = exifVersion; + } + + return Exif; + }, + + GPS: function() { + var GPS; + + GPS = extractTags(offsets.gpsIFD, tags.gps); + + // iOS devices (and probably some others) do not put in GPSVersionID tag (why?..) + if (GPS.GPSVersionID && Basic.typeOf(GPS.GPSVersionID) === 'array') { + GPS.GPSVersionID = GPS.GPSVersionID.join('.'); + } + + return GPS; + }, + + setExif: function(tag, value) { + // Right now only setting of width/height is possible + if (tag !== 'PixelXDimension' && tag !== 'PixelYDimension') {return false;} + + return setTag('exif', tag, value); + }, + + + getBinary: function() { + return data.SEGMENT(); + }, + + purge: function() { + data.init(null); + data = Tiff = null; + offsets = {}; + } + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/JPEG.js + +/** + * JPEG.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/JPEG +@private +*/ +define("moxie/runtime/html5/image/JPEG", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/html5/image/JPEGHeaders", + "moxie/runtime/html5/utils/BinaryReader", + "moxie/runtime/html5/image/ExifParser" +], function(Basic, x, JPEGHeaders, BinaryReader, ExifParser) { + + function JPEG(binstr) { + var _binstr, _br, _hm, _ep, _info, hasExif; + + function _getDimensions() { + var idx = 0, marker, length; + + // examine all through the end, since some images might have very large APP segments + while (idx <= _binstr.length) { + marker = _br.SHORT(idx += 2); + + if (marker >= 0xFFC0 && marker <= 0xFFC3) { // SOFn + idx += 5; // marker (2 bytes) + length (2 bytes) + Sample precision (1 byte) + return { + height: _br.SHORT(idx), + width: _br.SHORT(idx += 2) + }; + } + length = _br.SHORT(idx += 2); + idx += length - 2; + } + return null; + } + + _binstr = binstr; + + _br = new BinaryReader(); + _br.init(_binstr); + + // check if it is jpeg + if (_br.SHORT(0) !== 0xFFD8) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + + // backup headers + _hm = new JPEGHeaders(binstr); + + // extract exif info + _ep = new ExifParser(); + hasExif = !!_ep.init(_hm.get('app1')[0]); + + // get dimensions + _info = _getDimensions.call(this); + + Basic.extend(this, { + type: 'image/jpeg', + + size: _binstr.length, + + width: _info && _info.width || 0, + + height: _info && _info.height || 0, + + setExif: function(tag, value) { + if (!hasExif) { + return false; // or throw an exception + } + + if (Basic.typeOf(tag) === 'object') { + Basic.each(tag, function(value, tag) { + _ep.setExif(tag, value); + }); + } else { + _ep.setExif(tag, value); + } + + // update internal headers + _hm.set('app1', _ep.getBinary()); + }, + + writeHeaders: function() { + if (!arguments.length) { + // if no arguments passed, update headers internally + return (_binstr = _hm.restore(_binstr)); + } + return _hm.restore(arguments[0]); + }, + + stripHeaders: function(binstr) { + return _hm.strip(binstr); + }, + + purge: function() { + _purge.call(this); + } + }); + + if (hasExif) { + this.meta = { + tiff: _ep.TIFF(), + exif: _ep.EXIF(), + gps: _ep.GPS() + }; + } + + function _purge() { + if (!_ep || !_hm || !_br) { + return; // ignore any repeating purge requests + } + _ep.purge(); + _hm.purge(); + _br.init(null); + _binstr = _info = _hm = _ep = _br = null; + } + } + + return JPEG; +}); + +// Included from: src/javascript/runtime/html5/image/PNG.js + +/** + * PNG.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/PNG +@private +*/ +define("moxie/runtime/html5/image/PNG", [ + "moxie/core/Exceptions", + "moxie/core/utils/Basic", + "moxie/runtime/html5/utils/BinaryReader" +], function(x, Basic, BinaryReader) { + + function PNG(binstr) { + var _binstr, _br, _hm, _ep, _info; + + _binstr = binstr; + + _br = new BinaryReader(); + _br.init(_binstr); + + // check if it's png + (function() { + var idx = 0, i = 0 + , signature = [0x8950, 0x4E47, 0x0D0A, 0x1A0A] + ; + + for (i = 0; i < signature.length; i++, idx += 2) { + if (signature[i] != _br.SHORT(idx)) { + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + } + } + }()); + + function _getDimensions() { + var chunk, idx; + + chunk = _getChunkAt.call(this, 8); + + if (chunk.type == 'IHDR') { + idx = chunk.start; + return { + width: _br.LONG(idx), + height: _br.LONG(idx += 4) + }; + } + return null; + } + + function _purge() { + if (!_br) { + return; // ignore any repeating purge requests + } + _br.init(null); + _binstr = _info = _hm = _ep = _br = null; + } + + _info = _getDimensions.call(this); + + Basic.extend(this, { + type: 'image/png', + + size: _binstr.length, + + width: _info.width, + + height: _info.height, + + purge: function() { + _purge.call(this); + } + }); + + // for PNG we can safely trigger purge automatically, as we do not keep any data for later + _purge.call(this); + + function _getChunkAt(idx) { + var length, type, start, CRC; + + length = _br.LONG(idx); + type = _br.STRING(idx += 4, 4); + start = idx += 4; + CRC = _br.LONG(idx + length); + + return { + length: length, + type: type, + start: start, + CRC: CRC + }; + } + } + + return PNG; +}); + +// Included from: src/javascript/runtime/html5/image/ImageInfo.js + +/** + * ImageInfo.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/ImageInfo +@private +*/ +define("moxie/runtime/html5/image/ImageInfo", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/html5/image/JPEG", + "moxie/runtime/html5/image/PNG" +], function(Basic, x, JPEG, PNG) { + /** + Optional image investigation tool for HTML5 runtime. Provides the following features: + - ability to distinguish image type (JPEG or PNG) by signature + - ability to extract image width/height directly from it's internals, without preloading in memory (fast) + - ability to extract APP headers from JPEGs (Exif, GPS, etc) + - ability to replace width/height tags in extracted JPEG headers + - ability to restore APP headers, that were for example stripped during image manipulation + + @class ImageInfo + @constructor + @param {String} binstr Image source as binary string + */ + return function(binstr) { + var _cs = [JPEG, PNG], _img; + + // figure out the format, throw: ImageError.WRONG_FORMAT if not supported + _img = (function() { + for (var i = 0; i < _cs.length; i++) { + try { + return new _cs[i](binstr); + } catch (ex) { + // console.info(ex); + } + } + throw new x.ImageError(x.ImageError.WRONG_FORMAT); + }()); + + Basic.extend(this, { + /** + Image Mime Type extracted from it's depths + + @property type + @type {String} + @default '' + */ + type: '', + + /** + Image size in bytes + + @property size + @type {Number} + @default 0 + */ + size: 0, + + /** + Image width extracted from image source + + @property width + @type {Number} + @default 0 + */ + width: 0, + + /** + Image height extracted from image source + + @property height + @type {Number} + @default 0 + */ + height: 0, + + /** + Sets Exif tag. Currently applicable only for width and height tags. Obviously works only with JPEGs. + + @method setExif + @param {String} tag Tag to set + @param {Mixed} value Value to assign to the tag + */ + setExif: function() {}, + + /** + Restores headers to the source. + + @method writeHeaders + @param {String} data Image source as binary string + @return {String} Updated binary string + */ + writeHeaders: function(data) { + return data; + }, + + /** + Strip all headers from the source. + + @method stripHeaders + @param {String} data Image source as binary string + @return {String} Updated binary string + */ + stripHeaders: function(data) { + return data; + }, + + /** + Dispose resources. + + @method purge + */ + purge: function() {} + }); + + Basic.extend(this, _img); + + this.purge = function() { + _img.purge(); + _img = null; + }; + }; +}); + +// Included from: src/javascript/runtime/html5/image/MegaPixel.js + +/** +(The MIT License) + +Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>; + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/** + * Mega pixel image rendering library for iOS6 Safari + * + * Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel), + * which causes unexpected subsampling when drawing it in canvas. + * By using this library, you can safely render the image with proper stretching. + * + * Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com> + * Released under the MIT license + */ + +/** +@class moxie/runtime/html5/image/MegaPixel +@private +*/ +define("moxie/runtime/html5/image/MegaPixel", [], function() { + + /** + * Rendering image element (with resizing) into the canvas element + */ + function renderImageToCanvas(img, canvas, options) { + var iw = img.naturalWidth, ih = img.naturalHeight; + var width = options.width, height = options.height; + var x = options.x || 0, y = options.y || 0; + var ctx = canvas.getContext('2d'); + if (detectSubsampling(img)) { + iw /= 2; + ih /= 2; + } + var d = 1024; // size of tiling canvas + var tmpCanvas = document.createElement('canvas'); + tmpCanvas.width = tmpCanvas.height = d; + var tmpCtx = tmpCanvas.getContext('2d'); + var vertSquashRatio = detectVerticalSquash(img, iw, ih); + var sy = 0; + while (sy < ih) { + var sh = sy + d > ih ? ih - sy : d; + var sx = 0; + while (sx < iw) { + var sw = sx + d > iw ? iw - sx : d; + tmpCtx.clearRect(0, 0, d, d); + tmpCtx.drawImage(img, -sx, -sy); + var dx = (sx * width / iw + x) << 0; + var dw = Math.ceil(sw * width / iw); + var dy = (sy * height / ih / vertSquashRatio + y) << 0; + var dh = Math.ceil(sh * height / ih / vertSquashRatio); + ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh); + sx += d; + } + sy += d; + } + tmpCanvas = tmpCtx = null; + } + + /** + * Detect subsampling in loaded image. + * In iOS, larger images than 2M pixels may be subsampled in rendering. + */ + function detectSubsampling(img) { + var iw = img.naturalWidth, ih = img.naturalHeight; + if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image + var canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, -iw + 1, 0); + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering edge pixel or not. + // if alpha value is 0 image is not covering, hence subsampled. + return ctx.getImageData(0, 0, 1, 1).data[3] === 0; + } else { + return false; + } + } + + + /** + * Detecting vertical squash in loaded image. + * Fixes a bug which squash image vertically while drawing into canvas for some images. + */ + function detectVerticalSquash(img, iw, ih) { + var canvas = document.createElement('canvas'); + canvas.width = 1; + canvas.height = ih; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + var data = ctx.getImageData(0, 0, 1, ih).data; + // search image edge pixel position in case it is squashed vertically. + var sy = 0; + var ey = ih; + var py = ih; + while (py > sy) { + var alpha = data[(py - 1) * 4 + 3]; + if (alpha === 0) { + ey = py; + } else { + sy = py; + } + py = (ey + sy) >> 1; + } + canvas = null; + var ratio = (py / ih); + return (ratio === 0) ? 1 : ratio; + } + + return { + isSubsampled: detectSubsampling, + renderTo: renderImageToCanvas + }; +}); + +// Included from: src/javascript/runtime/html5/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html5/image/Image +@private +*/ +define("moxie/runtime/html5/image/Image", [ + "moxie/runtime/html5/Runtime", + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/core/utils/Encode", + "moxie/file/File", + "moxie/runtime/html5/image/ImageInfo", + "moxie/runtime/html5/image/MegaPixel", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, Basic, x, Encode, File, ImageInfo, MegaPixel, Mime, Env) { + + function HTML5Image() { + var me = this + , _img, _imgInfo, _canvas, _binStr, _blob + , _modified = false // is set true whenever image is modified + , _preserveHeaders = true + ; + + Basic.extend(this, { + loadFromBlob: function(blob) { + var comp = this, I = comp.getRuntime() + , asBinary = arguments.length > 1 ? arguments[1] : true + ; + + if (!I.can('access_binary')) { + throw new x.RuntimeError(x.RuntimeError.NOT_SUPPORTED_ERR); + } + + _blob = blob; + + if (blob.isDetached()) { + _binStr = blob.getSource(); + _preload.call(this, _binStr); + return; + } else { + _readAsDataUrl.call(this, blob.getSource(), function(dataUrl) { + if (asBinary) { + _binStr = _toBinary(dataUrl); + } + _preload.call(comp, dataUrl); + }); + } + }, + + loadFromImage: function(img, exact) { + this.meta = img.meta; + + _blob = new File(null, { + name: img.name, + size: img.size, + type: img.type + }); + + _preload.call(this, exact ? (_binStr = img.getAsBinaryString()) : img.getAsDataURL()); + }, + + getInfo: function() { + var I = this.getRuntime(), info; + + if (!_imgInfo && _binStr && I.can('access_image_binary')) { + _imgInfo = new ImageInfo(_binStr); + } + + info = { + width: _getImg().width || 0, + height: _getImg().height || 0, + type: _blob.type || Mime.getFileMime(_blob.name), + size: _binStr && _binStr.length || _blob.size || 0, + name: _blob.name || '', + meta: _imgInfo && _imgInfo.meta || this.meta || {} + }; + + return info; + }, + + downsize: function() { + _downsize.apply(this, arguments); + }, + + getAsCanvas: function() { + if (_canvas) { + _canvas.id = this.uid + '_canvas'; + } + return _canvas; + }, + + getAsBlob: function(type, quality) { + if (type !== this.type) { + // if different mime type requested prepare image for conversion + _downsize.call(this, this.width, this.height, false); + } + return new File(null, { + name: _blob.name || '', + type: type, + data: me.getAsBinaryString.call(this, type, quality) + }); + }, + + getAsDataURL: function(type) { + var quality = arguments[1] || 90; + + // if image has not been modified, return the source right away + if (!_modified) { + return _img.src; + } + + if ('image/jpeg' !== type) { + return _canvas.toDataURL('image/png'); + } else { + try { + // older Geckos used to result in an exception on quality argument + return _canvas.toDataURL('image/jpeg', quality/100); + } catch (ex) { + return _canvas.toDataURL('image/jpeg'); + } + } + }, + + getAsBinaryString: function(type, quality) { + // if image has not been modified, return the source right away + if (!_modified) { + // if image was not loaded from binary string + if (!_binStr) { + _binStr = _toBinary(me.getAsDataURL(type, quality)); + } + return _binStr; + } + + if ('image/jpeg' !== type) { + _binStr = _toBinary(me.getAsDataURL(type, quality)); + } else { + var dataUrl; + + // if jpeg + if (!quality) { + quality = 90; + } + + try { + // older Geckos used to result in an exception on quality argument + dataUrl = _canvas.toDataURL('image/jpeg', quality/100); + } catch (ex) { + dataUrl = _canvas.toDataURL('image/jpeg'); + } + + _binStr = _toBinary(dataUrl); + + if (_imgInfo) { + _binStr = _imgInfo.stripHeaders(_binStr); + + if (_preserveHeaders) { + // update dimensions info in exif + if (_imgInfo.meta && _imgInfo.meta.exif) { + _imgInfo.setExif({ + PixelXDimension: this.width, + PixelYDimension: this.height + }); + } + + // re-inject the headers + _binStr = _imgInfo.writeHeaders(_binStr); + } + + // will be re-created from fresh on next getInfo call + _imgInfo.purge(); + _imgInfo = null; + } + } + + _modified = false; + + return _binStr; + }, + + destroy: function() { + me = null; + _purge.call(this); + this.getRuntime().getShim().removeInstance(this.uid); + } + }); + + + function _getImg() { + if (!_canvas && !_img) { + throw new x.ImageError(x.DOMException.INVALID_STATE_ERR); + } + return _canvas || _img; + } + + + function _toBinary(str) { + return Encode.atob(str.substring(str.indexOf('base64,') + 7)); + } + + + function _toDataUrl(str, type) { + return 'data:' + (type || '') + ';base64,' + Encode.btoa(str); + } + + + function _preload(str) { + var comp = this; + + _img = new Image(); + _img.onerror = function() { + _purge.call(this); + comp.trigger('error', x.ImageError.WRONG_FORMAT); + }; + _img.onload = function() { + comp.trigger('load'); + }; + + _img.src = /^data:[^;]*;base64,/.test(str) ? str : _toDataUrl(str, _blob.type); + } + + + function _readAsDataUrl(file, callback) { + var comp = this, fr; + + // use FileReader if it's available + if (window.FileReader) { + fr = new FileReader(); + fr.onload = function() { + callback(this.result); + }; + fr.onerror = function() { + comp.trigger('error', x.ImageError.WRONG_FORMAT); + }; + fr.readAsDataURL(file); + } else { + return callback(file.getAsDataURL()); + } + } + + function _downsize(width, height, crop, preserveHeaders) { + var self = this + , scale + , mathFn + , x = 0 + , y = 0 + , img + , destWidth + , destHeight + , orientation + ; + + _preserveHeaders = preserveHeaders; // we will need to check this on export (see getAsBinaryString()) + + // take into account orientation tag + orientation = (this.meta && this.meta.tiff && this.meta.tiff.Orientation) || 1; + + if (Basic.inArray(orientation, [5,6,7,8]) !== -1) { // values that require 90 degree rotation + // swap dimensions + var tmp = width; + width = height; + height = tmp; + } + + img = _getImg(); + + // unify dimensions + if (!crop) { + scale = Math.min(width/img.width, height/img.height); + } else { + // one of the dimensions may exceed the actual image dimensions - we need to take the smallest value + width = Math.min(width, img.width); + height = Math.min(height, img.height); + + scale = Math.max(width/img.width, height/img.height); + } + + // we only downsize here + if (scale > 1 && !crop && preserveHeaders) { + this.trigger('Resize'); + return; + } + + // prepare canvas if necessary + if (!_canvas) { + _canvas = document.createElement("canvas"); + } + + // calculate dimensions of proportionally resized image + destWidth = Math.round(img.width * scale); + destHeight = Math.round(img.height * scale); + + // scale image and canvas + if (crop) { + _canvas.width = width; + _canvas.height = height; + + // if dimensions of the resulting image still larger than canvas, center it + if (destWidth > width) { + x = Math.round((destWidth - width) / 2); + } + + if (destHeight > height) { + y = Math.round((destHeight - height) / 2); + } + } else { + _canvas.width = destWidth; + _canvas.height = destHeight; + } + + // rotate if required, according to orientation tag + if (!_preserveHeaders) { + _rotateToOrientaion(_canvas.width, _canvas.height, orientation); + } + + _drawToCanvas.call(this, img, _canvas, -x, -y, destWidth, destHeight); + + this.width = _canvas.width; + this.height = _canvas.height; + + _modified = true; + self.trigger('Resize'); + } + + + function _drawToCanvas(img, canvas, x, y, w, h) { + if (Env.OS === 'iOS') { + // avoid squish bug in iOS6 + MegaPixel.renderTo(img, canvas, { width: w, height: h, x: x, y: y }); + } else { + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, x, y, w, h); + } + } + + + /** + * Transform canvas coordination according to specified frame size and orientation + * Orientation value is from EXIF tag + * @author Shinichi Tomita <shinichi.tomita@gmail.com> + */ + function _rotateToOrientaion(width, height, orientation) { + switch (orientation) { + case 5: + case 6: + case 7: + case 8: + _canvas.width = height; + _canvas.height = width; + break; + default: + _canvas.width = width; + _canvas.height = height; + } + + /** + 1 = The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side. + 2 = The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side. + 3 = The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side. + 4 = The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side. + 5 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual top. + 6 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual top. + 7 = The 0th row is the visual right-hand side of the image, and the 0th column is the visual bottom. + 8 = The 0th row is the visual left-hand side of the image, and the 0th column is the visual bottom. + */ + + var ctx = _canvas.getContext('2d'); + switch (orientation) { + case 2: + // horizontal flip + ctx.translate(width, 0); + ctx.scale(-1, 1); + break; + case 3: + // 180 rotate left + ctx.translate(width, height); + ctx.rotate(Math.PI); + break; + case 4: + // vertical flip + ctx.translate(0, height); + ctx.scale(1, -1); + break; + case 5: + // vertical flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.scale(1, -1); + break; + case 6: + // 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(0, -height); + break; + case 7: + // horizontal flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(width, -height); + ctx.scale(-1, 1); + break; + case 8: + // 90 rotate left + ctx.rotate(-0.5 * Math.PI); + ctx.translate(-width, 0); + break; + } + } + + + function _purge() { + if (_imgInfo) { + _imgInfo.purge(); + _imgInfo = null; + } + _binStr = _img = _canvas = _blob = null; + _modified = false; + } + } + + return (extensions.Image = HTML5Image); +}); + +// Included from: src/javascript/runtime/flash/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Flash runtime. + +@class moxie/runtime/flash/Runtime +@private +*/ +define("moxie/runtime/flash/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = 'flash', extensions = {}; + + /** + Get the version of the Flash Player + + @method getShimVersion + @private + @return {Number} Flash Player version + */ + function getShimVersion() { + var version; + + try { + version = navigator.plugins['Shockwave Flash']; + version = version.description; + } catch (e1) { + try { + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); + } catch (e2) { + version = '0.0'; + } + } + version = version.match(/\d+/g); + return parseFloat(version[0] + '.' + version[1]); + } + + /** + Constructor for the Flash Runtime + + @class FlashRuntime + @extends Runtime + */ + function FlashRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ swf_url: Env.swf_url }, options); + + Runtime.call(this, options, type, { + access_binary: function(value) { + return value && I.mode === 'browser'; + }, + access_image_binary: function(value) { + return value && I.mode === 'browser'; + }, + display_media: Runtime.capTrue, + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: function() { + return I.mode === 'client'; + }, + resize_image: Runtime.capTrue, + return_response_headers: false, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { + return true; + } + return !Basic.arrayDiff(responseType, ['', 'text', 'document']) || I.mode === 'browser'; + }, + return_status_code: function(code) { + return I.mode === 'browser' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: function(value) { + return value && I.mode === 'browser'; + }, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'browser'; + }, + send_multipart: Runtime.capTrue, + slice_blob: function(value) { + return value && I.mode === 'browser'; + }, + stream_upload: function(value) { + return value && I.mode === 'browser'; + }, + summon_file_dialog: false, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) <= 2097152 || I.mode === 'client'; + }, + use_http_method: function(methods) { + return !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + access_binary: function(value) { + return value ? 'browser' : 'client'; + }, + access_image_binary: function(value) { + return value ? 'browser' : 'client'; + }, + report_upload_progress: function(value) { + return value ? 'browser' : 'client'; + }, + return_response_type: function(responseType) { + return Basic.arrayDiff(responseType, ['', 'text', 'json', 'document']) ? 'browser' : ['client', 'browser']; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'browser' : ['client', 'browser']; + }, + send_binary_string: function(value) { + return value ? 'browser' : 'client'; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'browser' : 'client'; + }, + stream_upload: function(value) { + return value ? 'client' : 'browser'; + }, + upload_filesize: function(size) { + return Basic.parseSizeStr(size) >= 2097152 ? 'client' : 'browser'; + } + }, 'client'); + + + // minimal requirement for Flash Player version + if (getShimVersion() < 10) { + this.mode = false; // with falsy mode, runtime won't operable, no matter what the mode was before + } + + + Basic.extend(this, { + + getShim: function() { + return Dom.get(this.uid); + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init: function() { + var html, el, container; + + container = this.getShimContainer(); + + // if not the minimal height, shims are not initialized in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) + Basic.extend(container.style, { + position: 'absolute', + top: '-8px', + left: '-8px', + width: '9px', + height: '9px', + overflow: 'hidden' + }); + + // insert flash object + html = '<object id="' + this.uid + '" type="application/x-shockwave-flash" data="' + options.swf_url + '" '; + + if (Env.browser === 'IE') { + html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; + } + + html += 'width="100%" height="100%" style="outline:0">' + + '<param name="movie" value="' + options.swf_url + '" />' + + '<param name="flashvars" value="uid=' + escape(this.uid) + '&target=' + Env.global_event_dispatcher + '" />' + + '<param name="wmode" value="transparent" />' + + '<param name="allowscriptaccess" value="always" />' + + '</object>'; + + if (Env.browser === 'IE') { + el = document.createElement('div'); + container.appendChild(el); + el.outerHTML = html; + el = container = null; // just in case + } else { + container.innerHTML = html; + } + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + } + }, 5000); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, FlashRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/flash/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/Blob +@private +*/ +define("moxie/runtime/flash/file/Blob", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var FlashBlob = { + slice: function(blob, start, end, type) { + var self = this.getRuntime(); + + if (start < 0) { + start = Math.max(blob.size + start, 0); + } else if (start > 0) { + start = Math.min(start, blob.size); + } + + if (end < 0) { + end = Math.max(blob.size + end, 0); + } else if (end > 0) { + end = Math.min(end, blob.size); + } + + blob = self.shimExec.call(this, 'Blob', 'slice', start, end, type || ''); + + if (blob) { + blob = new Blob(self.uid, blob); + } + return blob; + } + }; + + return (extensions.Blob = FlashBlob); +}); + +// Included from: src/javascript/runtime/flash/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileInput +@private +*/ +define("moxie/runtime/flash/file/FileInput", [ + "moxie/runtime/flash/Runtime" +], function(extensions) { + + var FileInput = { + init: function(options) { + this.getRuntime().shimExec.call(this, 'FileInput', 'init', { + name: options.name, + accept: options.accept, + multiple: options.multiple + }); + this.trigger('ready'); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/flash/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReader +@private +*/ +define("moxie/runtime/flash/file/FileReader", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + var _result = ''; + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReader = { + read: function(op, blob) { + var target = this, self = target.getRuntime(); + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + _result = 'data:' + (blob.type || '') + ';base64,'; + } + + target.bind('Progress', function(e, data) { + if (data) { + _result += _formatData(data, op); + } + }); + + return self.shimExec.call(this, 'FileReader', 'readAsBase64', blob.uid); + }, + + getResult: function() { + return _result; + }, + + destroy: function() { + _result = null; + } + }; + + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/flash/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/file/FileReaderSync +@private +*/ +define("moxie/runtime/flash/file/FileReaderSync", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Encode" +], function(extensions, Encode) { + + function _formatData(data, op) { + switch (op) { + case 'readAsText': + return Encode.atob(data, 'utf8'); + case 'readAsBinaryString': + return Encode.atob(data); + case 'readAsDataURL': + return data; + } + return null; + } + + var FileReaderSync = { + read: function(op, blob) { + var result, self = this.getRuntime(); + + result = self.shimExec.call(this, 'FileReaderSync', 'readAsBase64', blob.uid); + if (!result) { + return null; // or throw ex + } + + // special prefix for DataURL read mode + if (op === 'readAsDataURL') { + result = 'data:' + (blob.type || '') + ';base64,' + result; + } + + return _formatData(result, op, blob.type); + } + }; + + return (extensions.FileReaderSync = FileReaderSync); +}); + +// Included from: src/javascript/runtime/flash/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/flash/xhr/XMLHttpRequest", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/file/Blob", + "moxie/file/File", + "moxie/file/FileReaderSync", + "moxie/xhr/FormData", + "moxie/runtime/Transporter" +], function(extensions, Basic, Blob, File, FileReaderSync, FormData, Transporter) { + + var XMLHttpRequest = { + + send: function(meta, data) { + var target = this, self = target.getRuntime(); + + function send() { + meta.transport = self.mode; + self.shimExec.call(target, 'XMLHttpRequest', 'send', meta, data); + } + + + function appendBlob(name, blob) { + self.shimExec.call(target, 'XMLHttpRequest', 'appendBlob', name, blob.uid); + data = null; + send(); + } + + + function attachBlob(blob, cb) { + var tr = new Transporter(); + + tr.bind("TransportingComplete", function() { + cb(this.result); + }); + + tr.transport(blob.getSource(), blob.type, { + ruid: self.uid + }); + } + + // copy over the headers if any + if (!Basic.isEmptyObj(meta.headers)) { + Basic.each(meta.headers, function(value, header) { + self.shimExec.call(target, 'XMLHttpRequest', 'setRequestHeader', header, value.toString()); // Silverlight doesn't accept integers into the arguments of type object + }); + } + + // transfer over multipart params and blob itself + if (data instanceof FormData) { + var blobField; + data.each(function(value, name) { + if (value instanceof Blob) { + blobField = name; + } else { + self.shimExec.call(target, 'XMLHttpRequest', 'append', name, value); + } + }); + + if (!data.hasBlob()) { + data = null; + send(); + } else { + var blob = data.getBlob(); + if (blob.isDetached()) { + attachBlob(blob, function(attachedBlob) { + blob.destroy(); + appendBlob(blobField, attachedBlob); + }); + } else { + appendBlob(blobField, blob); + } + } + } else if (data instanceof Blob) { + if (data.isDetached()) { + attachBlob(data, function(attachedBlob) { + data.destroy(); + data = attachedBlob.uid; + send(); + }); + } else { + data = data.uid; + send(); + } + } else { + send(); + } + }, + + getResponse: function(responseType) { + var frs, blob, self = this.getRuntime(); + + blob = self.shimExec.call(this, 'XMLHttpRequest', 'getResponseAsBlob'); + + if (blob) { + blob = new File(self.uid, blob); + + if ('blob' === responseType) { + return blob; + } + + try { + frs = new FileReaderSync(); + + if (!!~Basic.inArray(responseType, ["", "text"])) { + return frs.readAsText(blob); + } else if ('json' === responseType && !!window.JSON) { + return JSON.parse(frs.readAsText(blob)); + } + } finally { + blob.destroy(); + } + } + return null; + }, + + abort: function(upload_complete_flag) { + var self = this.getRuntime(); + + self.shimExec.call(this, 'XMLHttpRequest', 'abort'); + + this.dispatchEvent('readystatechange'); + // this.dispatchEvent('progress'); + this.dispatchEvent('abort'); + + //if (!upload_complete_flag) { + // this.dispatchEvent('uploadprogress'); + //} + } + }; + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/flash/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/runtime/Transporter +@private +*/ +define("moxie/runtime/flash/runtime/Transporter", [ + "moxie/runtime/flash/Runtime", + "moxie/file/Blob" +], function(extensions, Blob) { + + var Transporter = { + getAsBlob: function(type) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Transporter', 'getAsBlob', type) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + } + }; + + return (extensions.Transporter = Transporter); +}); + +// Included from: src/javascript/runtime/flash/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/flash/image/Image +@private +*/ +define("moxie/runtime/flash/image/Image", [ + "moxie/runtime/flash/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/Transporter", + "moxie/file/Blob", + "moxie/file/FileReaderSync" +], function(extensions, Basic, Transporter, Blob, FileReaderSync) { + + var Image = { + loadFromBlob: function(blob) { + var comp = this, self = comp.getRuntime(); + + function exec(srcBlob) { + self.shimExec.call(comp, 'Image', 'loadFromBlob', srcBlob.uid); + comp = self = null; + } + + if (blob.isDetached()) { // binary string + var tr = new Transporter(); + tr.bind("TransportingComplete", function() { + exec(tr.result.getSource()); + }); + tr.transport(blob.getSource(), blob.type, { ruid: self.uid }); + } else { + exec(blob.getSource()); + } + }, + + loadFromImage: function(img) { + var self = this.getRuntime(); + return self.shimExec.call(this, 'Image', 'loadFromImage', img.uid); + }, + + getAsBlob: function(type, quality) { + var self = this.getRuntime() + , blob = self.shimExec.call(this, 'Image', 'getAsBlob', type, quality) + ; + if (blob) { + return new Blob(self.uid, blob); + } + return null; + }, + + getAsDataURL: function() { + var self = this.getRuntime() + , blob = self.Image.getAsBlob.apply(this, arguments) + , frs + ; + if (!blob) { + return null; + } + frs = new FileReaderSync(); + return frs.readAsDataURL(blob); + } + }; + + return (extensions.Image = Image); +}); + +// Included from: src/javascript/runtime/silverlight/Runtime.js + +/** + * RunTime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global ActiveXObject:true */ + +/** +Defines constructor for Silverlight runtime. + +@class moxie/runtime/silverlight/Runtime +@private +*/ +define("moxie/runtime/silverlight/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/utils/Env", + "moxie/core/utils/Dom", + "moxie/core/Exceptions", + "moxie/runtime/Runtime" +], function(Basic, Env, Dom, x, Runtime) { + + var type = "silverlight", extensions = {}; + + function isInstalled(version) { + var isVersionSupported = false, control = null, actualVer, + actualVerArray, reqVerArray, requiredVersionPart, actualVersionPart, index = 0; + + try { + try { + control = new ActiveXObject('AgControl.AgControl'); + + if (control.IsVersionSupported(version)) { + isVersionSupported = true; + } + + control = null; + } catch (e) { + var plugin = navigator.plugins["Silverlight Plug-In"]; + + if (plugin) { + actualVer = plugin.description; + + if (actualVer === "1.0.30226.2") { + actualVer = "2.0.30226.2"; + } + + actualVerArray = actualVer.split("."); + + while (actualVerArray.length > 3) { + actualVerArray.pop(); + } + + while ( actualVerArray.length < 4) { + actualVerArray.push(0); + } + + reqVerArray = version.split("."); + + while (reqVerArray.length > 4) { + reqVerArray.pop(); + } + + do { + requiredVersionPart = parseInt(reqVerArray[index], 10); + actualVersionPart = parseInt(actualVerArray[index], 10); + index++; + } while (index < reqVerArray.length && requiredVersionPart === actualVersionPart); + + if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart)) { + isVersionSupported = true; + } + } + } + } catch (e2) { + isVersionSupported = false; + } + + return isVersionSupported; + } + + /** + Constructor for the Silverlight Runtime + + @class SilverlightRuntime + @extends Runtime + */ + function SilverlightRuntime(options) { + var I = this, initTimer; + + options = Basic.extend({ xap_url: Env.xap_url }, options); + + Runtime.call(this, options, type, { + access_binary: Runtime.capTrue, + access_image_binary: Runtime.capTrue, + display_media: Runtime.capTrue, + do_cors: Runtime.capTrue, + drag_and_drop: false, + report_upload_progress: Runtime.capTrue, + resize_image: Runtime.capTrue, + return_response_headers: function(value) { + return value && I.mode === 'client'; + }, + return_response_type: function(responseType) { + if (responseType !== 'json') { + return true; + } else { + return !!window.JSON; + } + }, + return_status_code: function(code) { + return I.mode === 'client' || !Basic.arrayDiff(code, [200, 404]); + }, + select_file: Runtime.capTrue, + select_multiple: Runtime.capTrue, + send_binary_string: Runtime.capTrue, + send_browser_cookies: function(value) { + return value && I.mode === 'browser'; + }, + send_custom_headers: function(value) { + return value && I.mode === 'client'; + }, + send_multipart: Runtime.capTrue, + slice_blob: Runtime.capTrue, + stream_upload: true, + summon_file_dialog: false, + upload_filesize: Runtime.capTrue, + use_http_method: function(methods) { + return I.mode === 'client' || !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }, { + // capabilities that require specific mode + return_response_headers: function(value) { + return value ? 'client' : 'browser'; + }, + return_status_code: function(code) { + return Basic.arrayDiff(code, [200, 404]) ? 'client' : ['client', 'browser']; + }, + send_browser_cookies: function(value) { + return value ? 'browser' : 'client'; + }, + send_custom_headers: function(value) { + return value ? 'client' : 'browser'; + }, + use_http_method: function(methods) { + return Basic.arrayDiff(methods, ['GET', 'POST']) ? 'client' : ['client', 'browser']; + } + }); + + + // minimal requirement + if (!isInstalled('2.0.31005.0') || Env.browser === 'Opera') { + this.mode = false; + } + + + Basic.extend(this, { + getShim: function() { + return Dom.get(this.uid).content.Moxie; + }, + + shimExec: function(component, action) { + var args = [].slice.call(arguments, 2); + return I.getShim().exec(this.uid, component, action, args); + }, + + init : function() { + var container; + + container = this.getShimContainer(); + + container.innerHTML = '<object id="' + this.uid + '" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;">' + + '<param name="source" value="' + options.xap_url + '"/>' + + '<param name="background" value="Transparent"/>' + + '<param name="windowless" value="true"/>' + + '<param name="enablehtmlaccess" value="true"/>' + + '<param name="initParams" value="uid=' + this.uid + ',target=' + Env.global_event_dispatcher + '"/>' + + '</object>'; + + // Init is dispatched by the shim + initTimer = setTimeout(function() { + if (I && !I.initialized) { // runtime might be already destroyed by this moment + I.trigger("Error", new x.RuntimeError(x.RuntimeError.NOT_INIT_ERR)); + } + }, Env.OS !== 'Windows'? 10000 : 5000); // give it more time to initialize in non Windows OS (like Mac) + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + clearTimeout(initTimer); // initialization check might be still onwait + options = initTimer = destroy = I = null; + }; + }(this.destroy)) + + }, extensions); + } + + Runtime.addConstructor(type, SilverlightRuntime); + + return extensions; +}); + +// Included from: src/javascript/runtime/silverlight/file/Blob.js + +/** + * Blob.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/Blob +@private +*/ +define("moxie/runtime/silverlight/file/Blob", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/Blob" +], function(extensions, Basic, Blob) { + return (extensions.Blob = Basic.extend({}, Blob)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileInput +@private +*/ +define("moxie/runtime/silverlight/file/FileInput", [ + "moxie/runtime/silverlight/Runtime" +], function(extensions) { + + var FileInput = { + init: function(options) { + + function toFilters(accept) { + var filter = ''; + for (var i = 0; i < accept.length; i++) { + filter += (filter !== '' ? '|' : '') + accept[i].title + " | *." + accept[i].extensions.replace(/,/g, ';*.'); + } + return filter; + } + + this.getRuntime().shimExec.call(this, 'FileInput', 'init', toFilters(options.accept), options.name, options.multiple); + this.trigger('ready'); + } + }; + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileDrop.js + +/** + * FileDrop.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileDrop +@private +*/ +define("moxie/runtime/silverlight/file/FileDrop", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Dom", + "moxie/core/utils/Events" +], function(extensions, Dom, Events) { + + // not exactly useful, since works only in safari (...crickets...) + var FileDrop = { + init: function() { + var comp = this, self = comp.getRuntime(), dropZone; + + dropZone = self.getShimContainer(); + + Events.addEvent(dropZone, 'dragover', function(e) { + e.preventDefault(); + e.stopPropagation(); + e.dataTransfer.dropEffect = 'copy'; + }, comp.uid); + + Events.addEvent(dropZone, 'dragenter', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragEnter(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + Events.addEvent(dropZone, 'drop', function(e) { + e.preventDefault(); + var flag = Dom.get(self.uid).dragDrop(e); + // If handled, then stop propagation of event in DOM + if (flag) { + e.stopPropagation(); + } + }, comp.uid); + + return self.shimExec.call(this, 'FileDrop', 'init'); + } + }; + + return (extensions.FileDrop = FileDrop); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReader +@private +*/ +define("moxie/runtime/silverlight/file/FileReader", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReader" +], function(extensions, Basic, FileReader) { + return (extensions.FileReader = Basic.extend({}, FileReader)); +}); + +// Included from: src/javascript/runtime/silverlight/file/FileReaderSync.js + +/** + * FileReaderSync.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/file/FileReaderSync +@private +*/ +define("moxie/runtime/silverlight/file/FileReaderSync", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/file/FileReaderSync" +], function(extensions, Basic, FileReaderSync) { + return (extensions.FileReaderSync = Basic.extend({}, FileReaderSync)); +}); + +// Included from: src/javascript/runtime/silverlight/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/silverlight/xhr/XMLHttpRequest", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/xhr/XMLHttpRequest" +], function(extensions, Basic, XMLHttpRequest) { + return (extensions.XMLHttpRequest = Basic.extend({}, XMLHttpRequest)); +}); + +// Included from: src/javascript/runtime/silverlight/runtime/Transporter.js + +/** + * Transporter.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/runtime/Transporter +@private +*/ +define("moxie/runtime/silverlight/runtime/Transporter", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/runtime/Transporter" +], function(extensions, Basic, Transporter) { + return (extensions.Transporter = Basic.extend({}, Transporter)); +}); + +// Included from: src/javascript/runtime/silverlight/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/silverlight/image/Image +@private +*/ +define("moxie/runtime/silverlight/image/Image", [ + "moxie/runtime/silverlight/Runtime", + "moxie/core/utils/Basic", + "moxie/runtime/flash/image/Image" +], function(extensions, Basic, Image) { + return (extensions.Image = Basic.extend({}, Image, { + + getInfo: function() { + var self = this.getRuntime() + , grps = ['tiff', 'exif', 'gps'] + , info = { meta: {} } + , rawInfo = self.shimExec.call(this, 'Image', 'getInfo') + ; + + if (rawInfo.meta) { + Basic.each(grps, function(grp) { + var meta = rawInfo.meta[grp] + , tag + , i + , length + , value + ; + if (meta && meta.keys) { + info.meta[grp] = {}; + for (i = 0, length = meta.keys.length; i < length; i++) { + tag = meta.keys[i]; + value = meta[tag]; + if (value) { + // convert numbers + if (/^(\d|[1-9]\d+)$/.test(value)) { // integer (make sure doesn't start with zero) + value = parseInt(value, 10); + } else if (/^\d*\.\d+$/.test(value)) { // double + value = parseFloat(value); + } + info.meta[grp][tag] = value; + } + } + } + }); + } + + info.width = parseInt(rawInfo.width, 10); + info.height = parseInt(rawInfo.height, 10); + info.size = parseInt(rawInfo.size, 10); + info.type = rawInfo.type; + info.name = rawInfo.name; + + return info; + } + })); +}); + +// Included from: src/javascript/runtime/html4/Runtime.js + +/** + * Runtime.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global File:true */ + +/** +Defines constructor for HTML4 runtime. + +@class moxie/runtime/html4/Runtime +@private +*/ +define("moxie/runtime/html4/Runtime", [ + "moxie/core/utils/Basic", + "moxie/core/Exceptions", + "moxie/runtime/Runtime", + "moxie/core/utils/Env" +], function(Basic, x, Runtime, Env) { + + var type = 'html4', extensions = {}; + + function Html4Runtime(options) { + var I = this + , Test = Runtime.capTest + , True = Runtime.capTrue + ; + + Runtime.call(this, options, type, { + access_binary: Test(window.FileReader || window.File && File.getAsDataURL), + access_image_binary: false, + display_media: Test(extensions.Image && (Env.can('create_canvas') || Env.can('use_data_uri_over32kb'))), + do_cors: false, + drag_and_drop: false, + filter_by_extension: Test(function() { // if you know how to feature-detect this, please suggest + return (Env.browser === 'Chrome' && Env.version >= 28) || (Env.browser === 'IE' && Env.version >= 10); + }()), + resize_image: function() { + return extensions.Image && I.can('access_binary') && Env.can('create_canvas'); + }, + report_upload_progress: false, + return_response_headers: false, + return_response_type: function(responseType) { + if (responseType === 'json' && !!window.JSON) { + return true; + } + return !!~Basic.inArray(responseType, ['text', 'document', '']); + }, + return_status_code: function(code) { + return !Basic.arrayDiff(code, [200, 404]); + }, + select_file: function() { + return Env.can('use_fileinput'); + }, + select_multiple: false, + send_binary_string: false, + send_custom_headers: false, + send_multipart: true, + slice_blob: false, + stream_upload: function() { + return I.can('select_file'); + }, + summon_file_dialog: Test(function() { // yeah... some dirty sniffing here... + return (Env.browser === 'Firefox' && Env.version >= 4) || + (Env.browser === 'Opera' && Env.version >= 12) || + !!~Basic.inArray(Env.browser, ['Chrome', 'Safari']); + }()), + upload_filesize: True, + use_http_method: function(methods) { + return !Basic.arrayDiff(methods, ['GET', 'POST']); + } + }); + + + Basic.extend(this, { + init : function() { + this.trigger("Init"); + }, + + destroy: (function(destroy) { // extend default destroy method + return function() { + destroy.call(I); + destroy = I = null; + }; + }(this.destroy)) + }); + + Basic.extend(this.getShim(), extensions); + } + + Runtime.addConstructor(type, Html4Runtime); + + return extensions; +}); + +// Included from: src/javascript/runtime/html4/file/FileInput.js + +/** + * FileInput.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/file/FileInput +@private +*/ +define("moxie/runtime/html4/file/FileInput", [ + "moxie/runtime/html4/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Events", + "moxie/core/utils/Mime", + "moxie/core/utils/Env" +], function(extensions, Basic, Dom, Events, Mime, Env) { + + function FileInput() { + var _uid, _files = [], _mimes = [], _options; + + function addInput() { + var comp = this, I = comp.getRuntime(), shimContainer, browseButton, currForm, form, input, uid; + + uid = Basic.guid('uid_'); + + shimContainer = I.getShimContainer(); // we get new ref everytime to avoid memory leaks in IE + + if (_uid) { // move previous form out of the view + currForm = Dom.get(_uid + '_form'); + if (currForm) { + Basic.extend(currForm.style, { top: '100%' }); + } + } + + // build form in DOM, since innerHTML version not able to submit file for some reason + form = document.createElement('form'); + form.setAttribute('id', uid + '_form'); + form.setAttribute('method', 'post'); + form.setAttribute('enctype', 'multipart/form-data'); + form.setAttribute('encoding', 'multipart/form-data'); + + Basic.extend(form.style, { + overflow: 'hidden', + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + input = document.createElement('input'); + input.setAttribute('id', uid); + input.setAttribute('type', 'file'); + input.setAttribute('name', _options.name || 'Filedata'); + input.setAttribute('accept', _mimes.join(',')); + + Basic.extend(input.style, { + fontSize: '999px', + opacity: 0 + }); + + form.appendChild(input); + shimContainer.appendChild(form); + + // prepare file input to be placed underneath the browse_button element + Basic.extend(input.style, { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%' + }); + + if (Env.browser === 'IE' && Env.version < 10) { + Basic.extend(input.style, { + filter : "progid:DXImageTransform.Microsoft.Alpha(opacity=0)" + }); + } + + input.onchange = function() { // there should be only one handler for this + var file; + + if (!this.value) { + return; + } + + if (this.files) { + file = this.files[0]; + } else { + file = { + name: this.value + }; + } + + _files = [file]; + + this.onchange = function() {}; // clear event handler + addInput.call(comp); + + // after file is initialized as o.File, we need to update form and input ids + comp.bind('change', function onChange() { + var input = Dom.get(uid), form = Dom.get(uid + '_form'), file; + + comp.unbind('change', onChange); + + if (comp.files.length && input && form) { + file = comp.files[0]; + + input.setAttribute('id', file.uid); + form.setAttribute('id', file.uid + '_form'); + + // set upload target + form.setAttribute('target', file.uid + '_iframe'); + } + input = form = null; + }, 998); + + input = form = null; + comp.trigger('change'); + }; + + + // route click event to the input + if (I.can('summon_file_dialog')) { + browseButton = Dom.get(_options.browse_button); + Events.removeEvent(browseButton, 'click', comp.uid); + Events.addEvent(browseButton, 'click', function(e) { + if (input && !input.disabled) { // for some reason FF (up to 8.0.1 so far) lets to click disabled input[type=file] + input.click(); + } + e.preventDefault(); + }, comp.uid); + } + + _uid = uid; + + shimContainer = currForm = browseButton = null; + } + + Basic.extend(this, { + init: function(options) { + var comp = this, I = comp.getRuntime(), shimContainer; + + // figure out accept string + _options = options; + _mimes = options.accept.mimes || Mime.extList2mimes(options.accept, I.can('filter_by_extension')); + + shimContainer = I.getShimContainer(); + + (function() { + var browseButton, zIndex, top; + + browseButton = Dom.get(options.browse_button); + + // Route click event to the input[type=file] element for browsers that support such behavior + if (I.can('summon_file_dialog')) { + if (Dom.getStyle(browseButton, 'position') === 'static') { + browseButton.style.position = 'relative'; + } + + zIndex = parseInt(Dom.getStyle(browseButton, 'z-index'), 10) || 1; + + browseButton.style.zIndex = zIndex; + shimContainer.style.zIndex = zIndex - 1; + } + + /* Since we have to place input[type=file] on top of the browse_button for some browsers, + browse_button loses interactivity, so we restore it here */ + top = I.can('summon_file_dialog') ? browseButton : shimContainer; + + Events.addEvent(top, 'mouseover', function() { + comp.trigger('mouseenter'); + }, comp.uid); + + Events.addEvent(top, 'mouseout', function() { + comp.trigger('mouseleave'); + }, comp.uid); + + Events.addEvent(top, 'mousedown', function() { + comp.trigger('mousedown'); + }, comp.uid); + + Events.addEvent(Dom.get(options.container), 'mouseup', function() { + comp.trigger('mouseup'); + }, comp.uid); + + browseButton = null; + }()); + + addInput.call(this); + + shimContainer = null; + + // trigger ready event asynchronously + comp.trigger({ + type: 'ready', + async: true + }); + }, + + getFiles: function() { + return _files; + }, + + disable: function(state) { + var input; + + if ((input = Dom.get(_uid))) { + input.disabled = !!state; + } + }, + + destroy: function() { + var I = this.getRuntime() + , shim = I.getShim() + , shimContainer = I.getShimContainer() + ; + + Events.removeAllEvents(shimContainer, this.uid); + Events.removeAllEvents(_options && Dom.get(_options.container), this.uid); + Events.removeAllEvents(_options && Dom.get(_options.browse_button), this.uid); + + if (shimContainer) { + shimContainer.innerHTML = ''; + } + + shim.removeInstance(this.uid); + + _uid = _files = _mimes = _options = shimContainer = shim = null; + } + }); + } + + return (extensions.FileInput = FileInput); +}); + +// Included from: src/javascript/runtime/html4/file/FileReader.js + +/** + * FileReader.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/file/FileReader +@private +*/ +define("moxie/runtime/html4/file/FileReader", [ + "moxie/runtime/html4/Runtime", + "moxie/runtime/html5/file/FileReader" +], function(extensions, FileReader) { + return (extensions.FileReader = FileReader); +}); + +// Included from: src/javascript/runtime/html4/xhr/XMLHttpRequest.js + +/** + * XMLHttpRequest.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/xhr/XMLHttpRequest +@private +*/ +define("moxie/runtime/html4/xhr/XMLHttpRequest", [ + "moxie/runtime/html4/Runtime", + "moxie/core/utils/Basic", + "moxie/core/utils/Dom", + "moxie/core/utils/Url", + "moxie/core/Exceptions", + "moxie/core/utils/Events", + "moxie/file/Blob", + "moxie/xhr/FormData" +], function(extensions, Basic, Dom, Url, x, Events, Blob, FormData) { + + function XMLHttpRequest() { + var _status, _response, _iframe; + + function cleanup(cb) { + var target = this, uid, form, inputs, i, hasFile = false; + + if (!_iframe) { + return; + } + + uid = _iframe.id.replace(/_iframe$/, ''); + + form = Dom.get(uid + '_form'); + if (form) { + inputs = form.getElementsByTagName('input'); + i = inputs.length; + + while (i--) { + switch (inputs[i].getAttribute('type')) { + case 'hidden': + inputs[i].parentNode.removeChild(inputs[i]); + break; + case 'file': + hasFile = true; // flag the case for later + break; + } + } + inputs = []; + + if (!hasFile) { // we need to keep the form for sake of possible retries + form.parentNode.removeChild(form); + } + form = null; + } + + // without timeout, request is marked as canceled (in console) + setTimeout(function() { + Events.removeEvent(_iframe, 'load', target.uid); + if (_iframe.parentNode) { // #382 + _iframe.parentNode.removeChild(_iframe); + } + + // check if shim container has any other children, if - not, remove it as well + var shimContainer = target.getRuntime().getShimContainer(); + if (!shimContainer.children.length) { + shimContainer.parentNode.removeChild(shimContainer); + } + + shimContainer = _iframe = null; + cb(); + }, 1); + } + + Basic.extend(this, { + send: function(meta, data) { + var target = this, I = target.getRuntime(), uid, form, input, blob; + + _status = _response = null; + + function createIframe() { + var container = I.getShimContainer() || document.body + , temp = document.createElement('div') + ; + + // IE 6 won't be able to set the name using setAttribute or iframe.name + temp.innerHTML = '<iframe id="' + uid + '_iframe" name="' + uid + '_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>'; + _iframe = temp.firstChild; + container.appendChild(_iframe); + + /* _iframe.onreadystatechange = function() { + console.info(_iframe.readyState); + };*/ + + Events.addEvent(_iframe, 'load', function() { // _iframe.onload doesn't work in IE lte 8 + var el; + + try { + el = _iframe.contentWindow.document || _iframe.contentDocument || window.frames[_iframe.id].document; + + // try to detect some standard error pages + if (/^4(0[0-9]|1[0-7]|2[2346])\s/.test(el.title)) { // test if title starts with 4xx HTTP error + _status = el.title.replace(/^(\d+).*$/, '$1'); + } else { + _status = 200; + // get result + _response = Basic.trim(el.body.innerHTML); + + // we need to fire these at least once + target.trigger({ + type: 'progress', + loaded: _response.length, + total: _response.length + }); + + if (blob) { // if we were uploading a file + target.trigger({ + type: 'uploadprogress', + loaded: blob.size || 1025, + total: blob.size || 1025 + }); + } + } + } catch (ex) { + if (Url.hasSameOrigin(meta.url)) { + // if response is sent with error code, iframe in IE gets redirected to res://ieframe.dll/http_x.htm + // which obviously results to cross domain error (wtf?) + _status = 404; + } else { + cleanup.call(target, function() { + target.trigger('error'); + }); + return; + } + } + + cleanup.call(target, function() { + target.trigger('load'); + }); + }, target.uid); + } // end createIframe + + // prepare data to be sent and convert if required + if (data instanceof FormData && data.hasBlob()) { + blob = data.getBlob(); + uid = blob.uid; + input = Dom.get(uid); + form = Dom.get(uid + '_form'); + if (!form) { + throw new x.DOMException(x.DOMException.NOT_FOUND_ERR); + } + } else { + uid = Basic.guid('uid_'); + + form = document.createElement('form'); + form.setAttribute('id', uid + '_form'); + form.setAttribute('method', meta.method); + form.setAttribute('enctype', 'multipart/form-data'); + form.setAttribute('encoding', 'multipart/form-data'); + form.setAttribute('target', uid + '_iframe'); + + I.getShimContainer().appendChild(form); + } + + if (data instanceof FormData) { + data.each(function(value, name) { + if (value instanceof Blob) { + if (input) { + input.setAttribute('name', name); + } + } else { + var hidden = document.createElement('input'); + + Basic.extend(hidden, { + type : 'hidden', + name : name, + value : value + }); + + // make sure that input[type="file"], if it's there, comes last + if (input) { + form.insertBefore(hidden, input); + } else { + form.appendChild(hidden); + } + } + }); + } + + // set destination url + form.setAttribute("action", meta.url); + + createIframe(); + form.submit(); + target.trigger('loadstart'); + }, + + getStatus: function() { + return _status; + }, + + getResponse: function(responseType) { + if ('json' === responseType) { + // strip off <pre>..</pre> tags that might be enclosing the response + if (Basic.typeOf(_response) === 'string' && !!window.JSON) { + try { + return JSON.parse(_response.replace(/^\s*<pre[^>]*>/, '').replace(/<\/pre>\s*$/, '')); + } catch (ex) { + return null; + } + } + } else if ('document' === responseType) { + + } + return _response; + }, + + abort: function() { + var target = this; + + if (_iframe && _iframe.contentWindow) { + if (_iframe.contentWindow.stop) { // FireFox/Safari/Chrome + _iframe.contentWindow.stop(); + } else if (_iframe.contentWindow.document.execCommand) { // IE + _iframe.contentWindow.document.execCommand('Stop'); + } else { + _iframe.src = "about:blank"; + } + } + + cleanup.call(this, function() { + // target.dispatchEvent('readystatechange'); + target.dispatchEvent('abort'); + }); + } + }); + } + + return (extensions.XMLHttpRequest = XMLHttpRequest); +}); + +// Included from: src/javascript/runtime/html4/image/Image.js + +/** + * Image.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/** +@class moxie/runtime/html4/image/Image +@private +*/ +define("moxie/runtime/html4/image/Image", [ + "moxie/runtime/html4/Runtime", + "moxie/runtime/html5/image/Image" +], function(extensions, Image) { + return (extensions.Image = Image); +}); + +expose(["moxie/core/utils/Basic","moxie/core/I18n","moxie/core/utils/Mime","moxie/core/utils/Env","moxie/core/utils/Dom","moxie/core/Exceptions","moxie/core/EventTarget","moxie/core/utils/Encode","moxie/runtime/Runtime","moxie/runtime/RuntimeClient","moxie/file/Blob","moxie/file/File","moxie/file/FileInput","moxie/file/FileDrop","moxie/runtime/RuntimeTarget","moxie/file/FileReader","moxie/core/utils/Url","moxie/file/FileReaderSync","moxie/xhr/FormData","moxie/xhr/XMLHttpRequest","moxie/runtime/Transporter","moxie/image/Image","moxie/core/utils/Events"]); +})(this);/** + * o.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global moxie:true */ + +/** +Globally exposed namespace with the most frequently used public classes and handy methods. + +@class o +@static +@private +*/ +(function(exports) { + "use strict"; + + var o = {}, inArray = exports.moxie.core.utils.Basic.inArray; + + // directly add some public classes + // (we do it dynamically here, since for custom builds we cannot know beforehand what modules were included) + (function addAlias(ns) { + var name, itemType; + for (name in ns) { + itemType = typeof(ns[name]); + if (itemType === 'object' && !~inArray(name, ['Exceptions', 'Env', 'Mime'])) { + addAlias(ns[name]); + } else if (itemType === 'function') { + o[name] = ns[name]; + } + } + })(exports.moxie); + + // add some manually + o.Env = exports.moxie.core.utils.Env; + o.Mime = exports.moxie.core.utils.Mime; + o.Exceptions = exports.moxie.core.Exceptions; + + // expose globally + exports.mOxie = o; + if (!exports.o) { + exports.o = o; + } + return o; +})(this); diff --git a/mobile/reg/lib/plupload-2.1.2/js/moxie.min.js b/mobile/reg/lib/plupload-2.1.2/js/moxie.min.js new file mode 100755 index 0000000..8d94a0d --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/js/moxie.min.js @@ -0,0 +1,15 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",h="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",b="moxie/file/FileReader",R="moxie/core/utils/Url",T="moxie/file/FileReaderSync",A="moxie/xhr/FormData",S="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",h="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var h=f[n],p=f[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<h.length;a++)if(l=h[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(h,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[h,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?void t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),void(n[this.uid][e]=s))},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,m[h++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[h++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,p],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[h,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?void i.init():void i.trigger("Error")):void o(t)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),void(i=null))}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,h,p,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,h;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);h={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},h,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:void c.files.push(new a(c.ruid,e))})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,h,u,w,v,p,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(b,[u,m,h,p,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var h=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=h;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(h)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend")) +},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(R,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(A,[h,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(S,[u,h,p,m,R,g,x,y,T,A,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function h(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:void(l.can("define_property")?y[e]=t:v[e]=t):void 0}function u(t){function i(){k&&(k.destroy(),k=null),s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",h.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==h.LOADING&&(n("readyState",h.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",h.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",h.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:b,password:R,headers:x,mimeType:A,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:h.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},b,R,T=null,A=null,S=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(b=u||l.user,R=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);S=!w,O=!1,x={},g.call(this),n("readyState",h.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[h.LOADING,h.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,A=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,A=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",A="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!S&&this.upload.hasEventListener(),N=!1,D=!n,S||(O=!0),u.call(this,n)},abort:function(){if(N=!0,S=!1,~e.inArray(n("readyState"),[h.UNSENT,h.OPENED,h.DONE]))n("readyState",h.UNSENT);else{if(n("readyState",h.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return h.UNSENT=0,h.OPENED=1,h.HEADERS_RECEIVED=2,h.LOADING=3,h.DONE=4,h.prototype=n.instance,h}),i(O,[u,m,v,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,h,T,S,g,v,O,d,p,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function h(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof h){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(p),c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,crop:!1,preserveHeaders:!0};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.getRuntime().exec.call(this,"Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),void o.trigger("embedded")}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},p,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,p=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=p.type||this.type||"image/jpeg",l=p.quality||90,d="undefined"!==e.typeOf(p.crop)?p.crop:!1,p.width)m=p.width,g=p.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new h,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var p=["progress","load","error","resize","embedded"];return h.MAX_RESIZE_WIDTH=6500,h.MAX_RESIZE_HEIGHT=6500,h.prototype=c.instance,h}),i(D,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,h,p,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),h=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(h,"position")&&(h.style.position="relative"),p=parseInt(n.getStyle(h,"z-index"),10)||1,h.style.zIndex=p,d.style.zIndex=p-1,i.addEvent(h,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?h:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser&&"IEMobile"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var n=t.toArray(e.dataTransfer.types||[]);return-1!==t.inArray("Files",n)||-1!==t.inArray("public.file-url",n)||-1!==t.inArray("application/x-moz-file",n)}function o(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function a(e){if(!f.length)return!0;var n=r.getFileExtension(e.name);return!n||-1!==t.inArray(n,f)}function s(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();a(n)&&d.push(n)}else i.push(t)}),i.length?u(i,n):n()}function u(e,n){var i=[];t.each(e,function(e){i.push(function(t){c(e,t)})}),t.inSeries(i,function(){n()})}function c(e,t){e.isFile?e.file(function(e){a(e)&&d.push(e),t()},function(){t()}):e.isDirectory?l(e,t):t()}function l(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){u(i,t)})}var d=[],f=[],h;t.extend(this,{init:function(n){var r=this,u;h=n,f=o(h.accept),u=h.container,i.addEvent(u,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},r.uid),i.addEvent(u,"drop",function(n){e(n)&&(n.preventDefault(),d=[],n.dataTransfer.items&&n.dataTransfer.items[0].webkitGetAsEntry?s(n.dataTransfer.items,function(){r.trigger("drop")}):(t.each(n.dataTransfer.files,function(e){a(e)&&d.push(e)}),r.trigger("drop")))},r.uid),i.addEvent(u,"dragenter",function(e){r.trigger("dragenter")},r.uid),i.addEvent(u,"dragleave",function(e){r.trigger("dragleave")},r.uid)},getFiles:function(){return d},destroy:function(){i.removeAllEvents(h&&n.get(h.container),this.uid),d=f=h=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,R,w,y,A,h,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return h.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,h,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),h=c(),h.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}h.upload?(n.withCredentials&&(h.withCredentials=!0),h.addEventListener("load",function(e){s.trigger(e)}),h.addEventListener("error",function(e){s.trigger(e)}),h.addEventListener("progress",function(e){s.trigger(e)}),h.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):h.onreadystatechange=function v(){switch(h.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=h.getResponseHeader("Content-Length")||0),h.responseText&&(t=h.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:h.onreadystatechange=function(){},s.trigger(0===h.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){h.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in h&&(h.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?h.sendAsBinary?h.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);h.send(e.buffer)}():h.send(r),s.trigger("loadstart")},getStatus:function(){try{if(h)return h.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,h.response),o=h.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?h.response:200===h.status&&window.JSON?JSON.parse(h.responseText):null;case"document":return l(h);default:return""!==h.responseText?h.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return h.getAllResponseHeaders()}catch(e){}return""},abort:function(){h&&h.abort()},destroy:function(){f=p=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(t>>Math.abs(a+8*s)&255);n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:void(r=e)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):void i(n,r,4)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,h,p,m=[],g={};for(r=0;i>r;r++)if(h=f=e+12*r+2,s=n[a.SHORT(h)],s!==t){switch(u=a.SHORT(h+=2),d=a.LONG(h+=2),h+=4,m=[],u){case 1:case 7:for(d>4&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(h+o);break;case 2:d>4&&(h=a.LONG(h)+c.tiffHeader),g[s]=a.STRING(h,d-1);continue;case 3:for(d>2&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(h+2*o);break;case 4:for(d>1&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(h+4*o);break;case 5:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(h+4*o)/a.LONG(h+4*o+4);break;case 9:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o);break;case 10:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o)/a.SLONG(h+4*o+4);break;default:continue}p=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof p?l[s][p]:p}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\x00"===a.STRING(4,5).toUpperCase()?r():!1):!1 +},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,h,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,h;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,h=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return h?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.getBinary())):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),h&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[h,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,h,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,h=document.createElement("canvas");h.width=h.height=f;for(var p=h.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;p.clearRect(0,0,f,f),p.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,b=Math.ceil(v*u/a/m);d.drawImage(h,0,0,w,v,E,x,_,b),y+=f}g+=f}h=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,h,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function h(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,h,g;if(R=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),h=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),h>i&&(l=Math.round((h-i)/2))):(E.width=f,E.height=h),R||m(E.width,E.height,g),p.call(this,d,E,-c,-l,f,h),this.width=E.width,this.height=E.height,b=!0,void a.trigger("Resize"))}function p(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,b=!1}var v=this,y,w,E,_,x,b=!1,R=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),void d.call(this,_)):void f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){h.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&h.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!b)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!b)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),R&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return b=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,h,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===c.mode},stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,A,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,h,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,h,p,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(h=n.get(a+"_form"),h&&t.extend(h.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),t.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=p=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=h=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,R,h,L,y,A],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function h(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),w&&p.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),h(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,h,p,m,g,v,y,w,E,_,x,b,R,T,A,S,O,I,L])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this); \ No newline at end of file diff --git a/mobile/reg/lib/plupload-2.1.2/js/plupload.dev.js b/mobile/reg/lib/plupload-2.1.2/js/plupload.dev.js new file mode 100755 index 0000000..732231e --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/js/plupload.dev.js @@ -0,0 +1,2315 @@ +/** + * Plupload - multi-runtime File Uploader + * v2.1.2 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +/** + * Plupload.js + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + */ + +/*global mOxie:true */ + +;(function(window, o, undef) { + +var delay = window.setTimeout +, fileFilters = {} +; + +// convert plupload features to caps acceptable by mOxie +function normalizeCaps(settings) { + var features = settings.required_features, caps = {}; + + function resolve(feature, value, strict) { + // Feature notation is deprecated, use caps (this thing here is required for backward compatibility) + var map = { + chunks: 'slice_blob', + jpgresize: 'send_binary_string', + pngresize: 'send_binary_string', + progress: 'report_upload_progress', + multi_selection: 'select_multiple', + dragdrop: 'drag_and_drop', + drop_element: 'drag_and_drop', + headers: 'send_custom_headers', + urlstream_upload: 'send_binary_string', + canSendBinary: 'send_binary', + triggerDialog: 'summon_file_dialog' + }; + + if (map[feature]) { + caps[map[feature]] = value; + } else if (!strict) { + caps[feature] = value; + } + } + + if (typeof(features) === 'string') { + plupload.each(features.split(/\s*,\s*/), function(feature) { + resolve(feature, true); + }); + } else if (typeof(features) === 'object') { + plupload.each(features, function(value, feature) { + resolve(feature, value); + }); + } else if (features === true) { + // check settings for required features + if (settings.chunk_size > 0) { + caps.slice_blob = true; + } + + if (settings.resize.enabled || !settings.multipart) { + caps.send_binary_string = true; + } + + plupload.each(settings, function(value, feature) { + resolve(feature, !!value, true); // strict check + }); + } + + return caps; +} + +/** + * @module plupload + * @static + */ +var plupload = { + /** + * Plupload version will be replaced on build. + * + * @property VERSION + * @for Plupload + * @static + * @final + */ + VERSION : '2.1.2', + + /** + * Inital state of the queue and also the state ones it's finished all it's uploads. + * + * @property STOPPED + * @static + * @final + */ + STOPPED : 1, + + /** + * Upload process is running + * + * @property STARTED + * @static + * @final + */ + STARTED : 2, + + /** + * File is queued for upload + * + * @property QUEUED + * @static + * @final + */ + QUEUED : 1, + + /** + * File is being uploaded + * + * @property UPLOADING + * @static + * @final + */ + UPLOADING : 2, + + /** + * File has failed to be uploaded + * + * @property FAILED + * @static + * @final + */ + FAILED : 4, + + /** + * File has been uploaded successfully + * + * @property DONE + * @static + * @final + */ + DONE : 5, + + // Error constants used by the Error event + + /** + * Generic error for example if an exception is thrown inside Silverlight. + * + * @property GENERIC_ERROR + * @static + * @final + */ + GENERIC_ERROR : -100, + + /** + * HTTP transport error. For example if the server produces a HTTP status other than 200. + * + * @property HTTP_ERROR + * @static + * @final + */ + HTTP_ERROR : -200, + + /** + * Generic I/O error. For example if it wasn't possible to open the file stream on local machine. + * + * @property IO_ERROR + * @static + * @final + */ + IO_ERROR : -300, + + /** + * @property SECURITY_ERROR + * @static + * @final + */ + SECURITY_ERROR : -400, + + /** + * Initialization error. Will be triggered if no runtime was initialized. + * + * @property INIT_ERROR + * @static + * @final + */ + INIT_ERROR : -500, + + /** + * File size error. If the user selects a file that is too large it will be blocked and an error of this type will be triggered. + * + * @property FILE_SIZE_ERROR + * @static + * @final + */ + FILE_SIZE_ERROR : -600, + + /** + * File extension error. If the user selects a file that isn't valid according to the filters setting. + * + * @property FILE_EXTENSION_ERROR + * @static + * @final + */ + FILE_EXTENSION_ERROR : -601, + + /** + * Duplicate file error. If prevent_duplicates is set to true and user selects the same file again. + * + * @property FILE_DUPLICATE_ERROR + * @static + * @final + */ + FILE_DUPLICATE_ERROR : -602, + + /** + * Runtime will try to detect if image is proper one. Otherwise will throw this error. + * + * @property IMAGE_FORMAT_ERROR + * @static + * @final + */ + IMAGE_FORMAT_ERROR : -700, + + /** + * While working on files runtime may run out of memory and will throw this error. + * + * @since 2.1.2 + * @property MEMORY_ERROR + * @static + * @final + */ + MEMORY_ERROR : -701, + + /** + * Each runtime has an upper limit on a dimension of the image it can handle. If bigger, will throw this error. + * + * @property IMAGE_DIMENSIONS_ERROR + * @static + * @final + */ + IMAGE_DIMENSIONS_ERROR : -702, + + /** + * Mime type lookup table. + * + * @property mimeTypes + * @type Object + * @final + */ + mimeTypes : o.mimes, + + /** + * In some cases sniffing is the only way around :( + */ + ua: o.ua, + + /** + * Gets the true type of the built-in object (better version of typeof). + * @credits Angus Croll (http://javascriptweblog.wordpress.com/) + * + * @method typeOf + * @static + * @param {Object} o Object to check. + * @return {String} Object [[Class]] + */ + typeOf: o.typeOf, + + /** + * Extends the specified object with another object. + * + * @method extend + * @static + * @param {Object} target Object to extend. + * @param {Object..} obj Multiple objects to extend with. + * @return {Object} Same as target, the extended object. + */ + extend : o.extend, + + /** + * Generates an unique ID. This is 99.99% unique since it takes the current time and 5 random numbers. + * The only way a user would be able to get the same ID is if the two persons at the same exact milisecond manages + * to get 5 the same random numbers between 0-65535 it also uses a counter so each call will be guaranteed to be page unique. + * It's more probable for the earth to be hit with an ansteriod. You can also if you want to be 100% sure set the plupload.guidPrefix property + * to an user unique key. + * + * @method guid + * @static + * @return {String} Virtually unique id. + */ + guid : o.guid, + + /** + * Get array of DOM Elements by their ids. + * + * @method get + * @for Utils + * @param {String} id Identifier of the DOM Element + * @return {Array} + */ + get : function get(ids) { + var els = [], el; + + if (o.typeOf(ids) !== 'array') { + ids = [ids]; + } + + var i = ids.length; + while (i--) { + el = o.get(ids[i]); + if (el) { + els.push(el); + } + } + + return els.length ? els : null; + }, + + /** + * Executes the callback function for each item in array/object. If you return false in the + * callback it will break the loop. + * + * @method each + * @static + * @param {Object} obj Object to iterate. + * @param {function} callback Callback function to execute for each item. + */ + each : o.each, + + /** + * Returns the absolute x, y position of an Element. The position will be returned in a object with x, y fields. + * + * @method getPos + * @static + * @param {Element} node HTML element or element id to get x, y position from. + * @param {Element} root Optional root element to stop calculations at. + * @return {object} Absolute position of the specified element object with x, y fields. + */ + getPos : o.getPos, + + /** + * Returns the size of the specified node in pixels. + * + * @method getSize + * @static + * @param {Node} node Node to get the size of. + * @return {Object} Object with a w and h property. + */ + getSize : o.getSize, + + /** + * Encodes the specified string. + * + * @method xmlEncode + * @static + * @param {String} s String to encode. + * @return {String} Encoded string. + */ + xmlEncode : function(str) { + var xmlEncodeChars = {'<' : 'lt', '>' : 'gt', '&' : 'amp', '"' : 'quot', '\'' : '#39'}, xmlEncodeRegExp = /[<>&\"\']/g; + + return str ? ('' + str).replace(xmlEncodeRegExp, function(chr) { + return xmlEncodeChars[chr] ? '&' + xmlEncodeChars[chr] + ';' : chr; + }) : str; + }, + + /** + * Forces anything into an array. + * + * @method toArray + * @static + * @param {Object} obj Object with length field. + * @return {Array} Array object containing all items. + */ + toArray : o.toArray, + + /** + * Find an element in array and return it's index if present, otherwise return -1. + * + * @method inArray + * @static + * @param {mixed} needle Element to find + * @param {Array} array + * @return {Int} Index of the element, or -1 if not found + */ + inArray : o.inArray, + + /** + * Extends the language pack object with new items. + * + * @method addI18n + * @static + * @param {Object} pack Language pack items to add. + * @return {Object} Extended language pack object. + */ + addI18n : o.addI18n, + + /** + * Translates the specified string by checking for the english string in the language pack lookup. + * + * @method translate + * @static + * @param {String} str String to look for. + * @return {String} Translated string or the input string if it wasn't found. + */ + translate : o.translate, + + /** + * Checks if object is empty. + * + * @method isEmptyObj + * @static + * @param {Object} obj Object to check. + * @return {Boolean} + */ + isEmptyObj : o.isEmptyObj, + + /** + * Checks if specified DOM element has specified class. + * + * @method hasClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + hasClass : o.hasClass, + + /** + * Adds specified className to specified DOM element. + * + * @method addClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + addClass : o.addClass, + + /** + * Removes specified className from specified DOM element. + * + * @method removeClass + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Class name + */ + removeClass : o.removeClass, + + /** + * Returns a given computed style of a DOM element. + * + * @method getStyle + * @static + * @param {Object} obj DOM element like object. + * @param {String} name Style you want to get from the DOM element + */ + getStyle : o.getStyle, + + /** + * Adds an event handler to the specified object and store reference to the handler + * in objects internal Plupload registry (@see removeEvent). + * + * @method addEvent + * @static + * @param {Object} obj DOM element like object to add handler to. + * @param {String} name Name to add event listener to. + * @param {Function} callback Function to call when event occurs. + * @param {String} (optional) key that might be used to add specifity to the event record. + */ + addEvent : o.addEvent, + + /** + * Remove event handler from the specified object. If third argument (callback) + * is not specified remove all events with the specified name. + * + * @method removeEvent + * @static + * @param {Object} obj DOM element to remove event listener(s) from. + * @param {String} name Name of event listener to remove. + * @param {Function|String} (optional) might be a callback or unique key to match. + */ + removeEvent: o.removeEvent, + + /** + * Remove all kind of events from the specified object + * + * @method removeAllEvents + * @static + * @param {Object} obj DOM element to remove event listeners from. + * @param {String} (optional) unique key to match, when removing events. + */ + removeAllEvents: o.removeAllEvents, + + /** + * Cleans the specified name from national characters (diacritics). The result will be a name with only a-z, 0-9 and _. + * + * @method cleanName + * @static + * @param {String} s String to clean up. + * @return {String} Cleaned string. + */ + cleanName : function(name) { + var i, lookup; + + // Replace diacritics + lookup = [ + /[\300-\306]/g, 'A', /[\340-\346]/g, 'a', + /\307/g, 'C', /\347/g, 'c', + /[\310-\313]/g, 'E', /[\350-\353]/g, 'e', + /[\314-\317]/g, 'I', /[\354-\357]/g, 'i', + /\321/g, 'N', /\361/g, 'n', + /[\322-\330]/g, 'O', /[\362-\370]/g, 'o', + /[\331-\334]/g, 'U', /[\371-\374]/g, 'u' + ]; + + for (i = 0; i < lookup.length; i += 2) { + name = name.replace(lookup[i], lookup[i + 1]); + } + + // Replace whitespace + name = name.replace(/\s+/g, '_'); + + // Remove anything else + name = name.replace(/[^a-z0-9_\-\.]+/gi, ''); + + return name; + }, + + /** + * Builds a full url out of a base URL and an object with items to append as query string items. + * + * @method buildUrl + * @static + * @param {String} url Base URL to append query string items to. + * @param {Object} items Name/value object to serialize as a querystring. + * @return {String} String with url + serialized query string items. + */ + buildUrl : function(url, items) { + var query = ''; + + plupload.each(items, function(value, name) { + query += (query ? '&' : '') + encodeURIComponent(name) + '=' + encodeURIComponent(value); + }); + + if (query) { + url += (url.indexOf('?') > 0 ? '&' : '?') + query; + } + + return url; + }, + + /** + * Formats the specified number as a size string for example 1024 becomes 1 KB. + * + * @method formatSize + * @static + * @param {Number} size Size to format as string. + * @return {String} Formatted size string. + */ + formatSize : function(size) { + + if (size === undef || /\D/.test(size)) { + return plupload.translate('N/A'); + } + + function round(num, precision) { + return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision); + } + + var boundary = Math.pow(1024, 4); + + // TB + if (size > boundary) { + return round(size / boundary, 1) + " " + plupload.translate('tb'); + } + + // GB + if (size > (boundary/=1024)) { + return round(size / boundary, 1) + " " + plupload.translate('gb'); + } + + // MB + if (size > (boundary/=1024)) { + return round(size / boundary, 1) + " " + plupload.translate('mb'); + } + + // KB + if (size > 1024) { + return Math.round(size / 1024) + " " + plupload.translate('kb'); + } + + return size + " " + plupload.translate('b'); + }, + + + /** + * Parses the specified size string into a byte value. For example 10kb becomes 10240. + * + * @method parseSize + * @static + * @param {String|Number} size String to parse or number to just pass through. + * @return {Number} Size in bytes. + */ + parseSize : o.parseSizeStr, + + + /** + * A way to predict what runtime will be choosen in the current environment with the + * specified settings. + * + * @method predictRuntime + * @static + * @param {Object|String} config Plupload settings to check + * @param {String} [runtimes] Comma-separated list of runtimes to check against + * @return {String} Type of compatible runtime + */ + predictRuntime : function(config, runtimes) { + var up, runtime; + + up = new plupload.Uploader(config); + runtime = o.Runtime.thatCan(up.getOption().required_features, runtimes || config.runtimes); + up.destroy(); + return runtime; + }, + + /** + * Registers a filter that will be executed for each file added to the queue. + * If callback returns false, file will not be added. + * + * Callback receives two arguments: a value for the filter as it was specified in settings.filters + * and a file to be filtered. Callback is executed in the context of uploader instance. + * + * @method addFileFilter + * @static + * @param {String} name Name of the filter by which it can be referenced in settings.filters + * @param {String} cb Callback - the actual routine that every added file must pass + */ + addFileFilter: function(name, cb) { + fileFilters[name] = cb; + } +}; + + +plupload.addFileFilter('mime_types', function(filters, file, cb) { + if (filters.length && !filters.regexp.test(file.name)) { + this.trigger('Error', { + code : plupload.FILE_EXTENSION_ERROR, + message : plupload.translate('File extension error.'), + file : file + }); + cb(false); + } else { + cb(true); + } +}); + + +plupload.addFileFilter('max_file_size', function(maxSize, file, cb) { + var undef; + + maxSize = plupload.parseSize(maxSize); + + // Invalid file size + if (file.size !== undef && maxSize && file.size > maxSize) { + this.trigger('Error', { + code : plupload.FILE_SIZE_ERROR, + message : plupload.translate('File size error.'), + file : file + }); + cb(false); + } else { + cb(true); + } +}); + + +plupload.addFileFilter('prevent_duplicates', function(value, file, cb) { + if (value) { + var ii = this.files.length; + while (ii--) { + // Compare by name and size (size might be 0 or undefined, but still equivalent for both) + if (file.name === this.files[ii].name && file.size === this.files[ii].size) { + this.trigger('Error', { + code : plupload.FILE_DUPLICATE_ERROR, + message : plupload.translate('Duplicate file error.'), + file : file + }); + cb(false); + return; + } + } + } + cb(true); +}); + + +/** +@class Uploader +@constructor + +@param {Object} settings For detailed information about each option check documentation. + @param {String|DOMElement} settings.browse_button id of the DOM element or DOM element itself to use as file dialog trigger. + @param {String} settings.url URL of the server-side upload handler. + @param {Number|String} [settings.chunk_size=0] Chunk size in bytes to slice the file into. Shorcuts with b, kb, mb, gb, tb suffixes also supported. `e.g. 204800 or "204800b" or "200kb"`. By default - disabled. + @param {Boolean} [settings.send_chunk_number=true] Whether to send chunks and chunk numbers, or total and offset bytes. + @param {String} [settings.container] id of the DOM element to use as a container for uploader structures. Defaults to document.body. + @param {String|DOMElement} [settings.drop_element] id of the DOM element or DOM element itself to use as a drop zone for Drag-n-Drop. + @param {String} [settings.file_data_name="file"] Name for the file field in Multipart formated message. + @param {Object} [settings.filters={}] Set of file type filters. + @param {Array} [settings.filters.mime_types=[]] List of file types to accept, each one defined by title and list of extensions. `e.g. {title : "Image files", extensions : "jpg,jpeg,gif,png"}`. Dispatches `plupload.FILE_EXTENSION_ERROR` + @param {String|Number} [settings.filters.max_file_size=0] Maximum file size that the user can pick, in bytes. Optionally supports b, kb, mb, gb, tb suffixes. `e.g. "10mb" or "1gb"`. By default - not set. Dispatches `plupload.FILE_SIZE_ERROR`. + @param {Boolean} [settings.filters.prevent_duplicates=false] Do not let duplicates into the queue. Dispatches `plupload.FILE_DUPLICATE_ERROR`. + @param {String} [settings.flash_swf_url] URL of the Flash swf. + @param {Object} [settings.headers] Custom headers to send with the upload. Hash of name/value pairs. + @param {Number} [settings.max_retries=0] How many times to retry the chunk or file, before triggering Error event. + @param {Boolean} [settings.multipart=true] Whether to send file and additional parameters as Multipart formated message. + @param {Object} [settings.multipart_params] Hash of key/value pairs to send with every file upload. + @param {Boolean} [settings.multi_selection=true] Enable ability to select multiple files at once in file dialog. + @param {String|Object} [settings.required_features] Either comma-separated list or hash of required features that chosen runtime should absolutely possess. + @param {Object} [settings.resize] Enable resizng of images on client-side. Applies to `image/jpeg` and `image/png` only. `e.g. {width : 200, height : 200, quality : 90, crop: true}` + @param {Number} [settings.resize.width] If image is bigger, it will be resized. + @param {Number} [settings.resize.height] If image is bigger, it will be resized. + @param {Number} [settings.resize.quality=90] Compression quality for jpegs (1-100). + @param {Boolean} [settings.resize.crop=false] Whether to crop images to exact dimensions. By default they will be resized proportionally. + @param {String} [settings.runtimes="html5,flash,silverlight,html4"] Comma separated list of runtimes, that Plupload will try in turn, moving to the next if previous fails. + @param {String} [settings.silverlight_xap_url] URL of the Silverlight xap. + @param {Boolean} [settings.unique_names=false] If true will generate unique filenames for uploaded files. + @param {Boolean} [settings.send_file_name=true] Whether to send file name as additional argument - 'name' (required for chunked uploads and some other cases where file name cannot be sent via normal ways). +*/ +plupload.Uploader = function(options) { + /** + * Fires when the current RunTime has been initialized. + * + * @event Init + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires after the init event incase you need to perform actions there. + * + * @event PostInit + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires when the option is changed in via uploader.setOption(). + * + * @event OptionChanged + * @since 2.1 + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {String} name Name of the option that was changed + * @param {Mixed} value New value for the specified option + * @param {Mixed} oldValue Previous value of the option + */ + + /** + * Fires when the silverlight/flash or other shim needs to move. + * + * @event Refresh + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires when the overall state is being changed for the upload queue. + * + * @event StateChanged + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires when browse_button is clicked and browse dialog shows. + * + * @event Browse + * @since 2.1.2 + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires for every filtered file before it is added to the queue. + * + * @event FileFiltered + * @since 2.1 + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file Another file that has to be added to the queue. + */ + + /** + * Fires when the file queue is changed. In other words when files are added/removed to the files array of the uploader instance. + * + * @event QueueChanged + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + + /** + * Fires after files were filtered and added to the queue. + * + * @event FilesAdded + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {Array} files Array of file objects that were added to queue by the user. + */ + + /** + * Fires when file is removed from the queue. + * + * @event FilesRemoved + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {Array} files Array of files that got removed. + */ + + /** + * Fires when just before a file is uploaded. This event enables you to override settings + * on the uploader instance before the file is uploaded. + * + * @event BeforeUpload + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File to be uploaded. + */ + + /** + * Fires when a file is to be uploaded by the runtime. + * + * @event UploadFile + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File to be uploaded. + */ + + /** + * Fires while a file is being uploaded. Use this event to update the current file upload progress. + * + * @event UploadProgress + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File that is currently being uploaded. + */ + + /** + * Fires when file chunk is uploaded. + * + * @event ChunkUploaded + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File that the chunk was uploaded for. + * @param {Object} response Object with response properties. + */ + + /** + * Fires when a file is successfully uploaded. + * + * @event FileUploaded + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {plupload.File} file File that was uploaded. + * @param {Object} response Object with response properties. + */ + + /** + * Fires when all files in a queue are uploaded. + * + * @event UploadComplete + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {Array} files Array of file objects that was added to queue/selected by the user. + */ + + /** + * Fires when a error occurs. + * + * @event Error + * @param {plupload.Uploader} uploader Uploader instance sending the event. + * @param {Object} error Contains code, message and sometimes file and other details. + */ + + /** + * Fires when destroy method is called. + * + * @event Destroy + * @param {plupload.Uploader} uploader Uploader instance sending the event. + */ + var uid = plupload.guid() + , settings + , files = [] + , preferred_caps = {} + , fileInputs = [] + , fileDrops = [] + , startTime + , total + , disabled = false + , xhr + ; + + + // Private methods + function uploadNext() { + var file, count = 0, i; + + if (this.state == plupload.STARTED) { + // Find first QUEUED file + for (i = 0; i < files.length; i++) { + if (!file && files[i].status == plupload.QUEUED) { + file = files[i]; + if (this.trigger("BeforeUpload", file)) { + file.status = plupload.UPLOADING; + this.trigger("UploadFile", file); + } + } else { + count++; + } + } + + // All files are DONE or FAILED + if (count == files.length) { + if (this.state !== plupload.STOPPED) { + this.state = plupload.STOPPED; + this.trigger("StateChanged"); + } + this.trigger("UploadComplete", files); + } + } + } + + + function calcFile(file) { + file.percent = file.size > 0 ? Math.ceil(file.loaded / file.size * 100) : 100; + calc(); + } + + + function calc() { + var i, file; + + // Reset stats + total.reset(); + + // Check status, size, loaded etc on all files + for (i = 0; i < files.length; i++) { + file = files[i]; + + if (file.size !== undef) { + // We calculate totals based on original file size + total.size += file.origSize; + + // Since we cannot predict file size after resize, we do opposite and + // interpolate loaded amount to match magnitude of total + total.loaded += file.loaded * file.origSize / file.size; + } else { + total.size = undef; + } + + if (file.status == plupload.DONE) { + total.uploaded++; + } else if (file.status == plupload.FAILED) { + total.failed++; + } else { + total.queued++; + } + } + + // If we couldn't calculate a total file size then use the number of files to calc percent + if (total.size === undef) { + total.percent = files.length > 0 ? Math.ceil(total.uploaded / files.length * 100) : 0; + } else { + total.bytesPerSec = Math.ceil(total.loaded / ((+new Date() - startTime || 1) / 1000.0)); + total.percent = total.size > 0 ? Math.ceil(total.loaded / total.size * 100) : 0; + } + } + + + function getRUID() { + var ctrl = fileInputs[0] || fileDrops[0]; + if (ctrl) { + return ctrl.getRuntime().uid; + } + return false; + } + + + function runtimeCan(file, cap) { + if (file.ruid) { + var info = o.Runtime.getInfo(file.ruid); + if (info) { + return info.can(cap); + } + } + return false; + } + + + function bindEventListeners() { + this.bind('FilesAdded FilesRemoved', function(up) { + up.trigger('QueueChanged'); + up.refresh(); + }); + + this.bind('CancelUpload', onCancelUpload); + + this.bind('BeforeUpload', onBeforeUpload); + + this.bind('UploadFile', onUploadFile); + + this.bind('UploadProgress', onUploadProgress); + + this.bind('StateChanged', onStateChanged); + + this.bind('QueueChanged', calc); + + this.bind('Error', onError); + + this.bind('FileUploaded', onFileUploaded); + + this.bind('Destroy', onDestroy); + } + + + function initControls(settings, cb) { + var self = this, inited = 0, queue = []; + + // common settings + var options = { + runtime_order: settings.runtimes, + required_caps: settings.required_features, + preferred_caps: preferred_caps, + swf_url: settings.flash_swf_url, + xap_url: settings.silverlight_xap_url + }; + + // add runtime specific options if any + plupload.each(settings.runtimes.split(/\s*,\s*/), function(runtime) { + if (settings[runtime]) { + options[runtime] = settings[runtime]; + } + }); + + // initialize file pickers - there can be many + if (settings.browse_button) { + plupload.each(settings.browse_button, function(el) { + queue.push(function(cb) { + var fileInput = new o.FileInput(plupload.extend({}, options, { + accept: settings.filters.mime_types, + name: settings.file_data_name, + multiple: settings.multi_selection, + container: settings.container, + browse_button: el + })); + + fileInput.onready = function() { + var info = o.Runtime.getInfo(this.ruid); + + // for backward compatibility + o.extend(self.features, { + chunks: info.can('slice_blob'), + multipart: info.can('send_multipart'), + multi_selection: info.can('select_multiple') + }); + + inited++; + fileInputs.push(this); + cb(); + }; + + fileInput.onchange = function() { + self.addFile(this.files); + }; + + fileInput.bind('mouseenter mouseleave mousedown mouseup', function(e) { + if (!disabled) { + if (settings.browse_button_hover) { + if ('mouseenter' === e.type) { + o.addClass(el, settings.browse_button_hover); + } else if ('mouseleave' === e.type) { + o.removeClass(el, settings.browse_button_hover); + } + } + + if (settings.browse_button_active) { + if ('mousedown' === e.type) { + o.addClass(el, settings.browse_button_active); + } else if ('mouseup' === e.type) { + o.removeClass(el, settings.browse_button_active); + } + } + } + }); + + fileInput.bind('mousedown', function() { + self.trigger('Browse'); + }); + + fileInput.bind('error runtimeerror', function() { + fileInput = null; + cb(); + }); + + fileInput.init(); + }); + }); + } + + // initialize drop zones + if (settings.drop_element) { + plupload.each(settings.drop_element, function(el) { + queue.push(function(cb) { + var fileDrop = new o.FileDrop(plupload.extend({}, options, { + drop_zone: el + })); + + fileDrop.onready = function() { + var info = o.Runtime.getInfo(this.ruid); + + self.features.dragdrop = info.can('drag_and_drop'); // for backward compatibility + + inited++; + fileDrops.push(this); + cb(); + }; + + fileDrop.ondrop = function() { + self.addFile(this.files); + }; + + fileDrop.bind('error runtimeerror', function() { + fileDrop = null; + cb(); + }); + + fileDrop.init(); + }); + }); + } + + + o.inSeries(queue, function() { + if (typeof(cb) === 'function') { + cb(inited); + } + }); + } + + + function resizeImage(blob, params, cb) { + var img = new o.Image(); + + try { + img.onload = function() { + // no manipulation required if... + if (params.width > this.width && + params.height > this.height && + params.quality === undef && + params.preserve_headers && + !params.crop + ) { + this.destroy(); + return cb(blob); + } + // otherwise downsize + img.downsize(params.width, params.height, params.crop, params.preserve_headers); + }; + + img.onresize = function() { + cb(this.getAsBlob(blob.type, params.quality)); + this.destroy(); + }; + + img.onerror = function() { + cb(blob); + }; + + img.load(blob); + } catch(ex) { + cb(blob); + } + } + + + function setOption(option, value, init) { + var self = this, reinitRequired = false; + + function _setOption(option, value, init) { + var oldValue = settings[option]; + + switch (option) { + case 'max_file_size': + if (option === 'max_file_size') { + settings.max_file_size = settings.filters.max_file_size = value; + } + break; + + case 'chunk_size': + if (value = plupload.parseSize(value)) { + settings[option] = value; + settings.send_file_name = true; + } + break; + + case 'multipart': + settings[option] = value; + if (!value) { + settings.send_file_name = true; + } + break; + + case 'unique_names': + settings[option] = value; + if (value) { + settings.send_file_name = true; + } + break; + + case 'filters': + // for sake of backward compatibility + if (plupload.typeOf(value) === 'array') { + value = { + mime_types: value + }; + } + + if (init) { + plupload.extend(settings.filters, value); + } else { + settings.filters = value; + } + + // if file format filters are being updated, regenerate the matching expressions + if (value.mime_types) { + settings.filters.mime_types.regexp = (function(filters) { + var extensionsRegExp = []; + + plupload.each(filters, function(filter) { + plupload.each(filter.extensions.split(/,/), function(ext) { + if (/^\s*\*\s*$/.test(ext)) { + extensionsRegExp.push('\\.*'); + } else { + extensionsRegExp.push('\\.' + ext.replace(new RegExp('[' + ('/^$.*+?|()[]{}\\'.replace(/./g, '\\$&')) + ']', 'g'), '\\$&')); + } + }); + }); + + return new RegExp('(' + extensionsRegExp.join('|') + ')$', 'i'); + }(settings.filters.mime_types)); + } + break; + + case 'resize': + if (init) { + plupload.extend(settings.resize, value, { + enabled: true + }); + } else { + settings.resize = value; + } + break; + + case 'prevent_duplicates': + settings.prevent_duplicates = settings.filters.prevent_duplicates = !!value; + break; + + case 'browse_button': + case 'drop_element': + value = plupload.get(value); + + case 'container': + case 'runtimes': + case 'multi_selection': + case 'flash_swf_url': + case 'silverlight_xap_url': + settings[option] = value; + if (!init) { + reinitRequired = true; + } + break; + + default: + settings[option] = value; + } + + if (!init) { + self.trigger('OptionChanged', option, value, oldValue); + } + } + + if (typeof(option) === 'object') { + plupload.each(option, function(value, option) { + _setOption(option, value, init); + }); + } else { + _setOption(option, value, init); + } + + if (init) { + // Normalize the list of required capabilities + settings.required_features = normalizeCaps(plupload.extend({}, settings)); + + // Come up with the list of capabilities that can affect default mode in a multi-mode runtimes + preferred_caps = normalizeCaps(plupload.extend({}, settings, { + required_features: true + })); + } else if (reinitRequired) { + self.trigger('Destroy'); + + initControls.call(self, settings, function(inited) { + if (inited) { + self.runtime = o.Runtime.getInfo(getRUID()).type; + self.trigger('Init', { runtime: self.runtime }); + self.trigger('PostInit'); + } else { + self.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate('Init error.') + }); + } + }); + } + } + + + // Internal event handlers + function onBeforeUpload(up, file) { + // Generate unique target filenames + if (up.settings.unique_names) { + var matches = file.name.match(/\.([^.]+)$/), ext = "part"; + if (matches) { + ext = matches[1]; + } + file.target_name = file.id + '.' + ext; + } + } + + + function onUploadFile(up, file) { + var url = up.settings.url + , chunkSize = up.settings.chunk_size + , retries = up.settings.max_retries + , features = up.features + , offset = 0 + , blob + ; + + // make sure we start at a predictable offset + if (file.loaded) { + offset = file.loaded = chunkSize ? chunkSize * Math.floor(file.loaded / chunkSize) : 0; + } + + function handleError() { + if (retries-- > 0) { + delay(uploadNextChunk, 1000); + } else { + file.loaded = offset; // reset all progress + + up.trigger('Error', { + code : plupload.HTTP_ERROR, + message : plupload.translate('HTTP Error.'), + file : file, + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + } + } + + function uploadNextChunk() { + var chunkBlob, formData, args = {}, curChunkSize; + + // make sure that file wasn't cancelled and upload is not stopped in general + if (file.status !== plupload.UPLOADING || up.state === plupload.STOPPED) { + return; + } + + // send additional 'name' parameter only if required + if (up.settings.send_file_name) { + args.name = file.target_name || file.name; + } + + if (chunkSize && features.chunks && blob.size > chunkSize) { // blob will be of type string if it was loaded in memory + curChunkSize = Math.min(chunkSize, blob.size - offset); + chunkBlob = blob.slice(offset, offset + curChunkSize); + } else { + curChunkSize = blob.size; + chunkBlob = blob; + } + + // If chunking is enabled add corresponding args, no matter if file is bigger than chunk or smaller + if (chunkSize && features.chunks) { + // Setup query string arguments + if (up.settings.send_chunk_number) { + args.chunk = Math.ceil(offset / chunkSize); + args.chunks = Math.ceil(blob.size / chunkSize); + } else { // keep support for experimental chunk format, just in case + args.offset = offset; + args.total = blob.size; + } + } + + xhr = new o.XMLHttpRequest(); + + // Do we have upload progress support + if (xhr.upload) { + xhr.upload.onprogress = function(e) { + file.loaded = Math.min(file.size, offset + e.loaded); + up.trigger('UploadProgress', file); + }; + } + + xhr.onload = function() { + // check if upload made itself through + if (xhr.status >= 400) { + handleError(); + return; + } + + retries = up.settings.max_retries; // reset the counter + + // Handle chunk response + if (curChunkSize < blob.size) { + chunkBlob.destroy(); + + offset += curChunkSize; + file.loaded = Math.min(offset, blob.size); + + up.trigger('ChunkUploaded', file, { + offset : file.loaded, + total : blob.size, + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + + // stock Android browser doesn't fire upload progress events, but in chunking mode we can fake them + if (o.Env.browser === 'Android Browser') { + // doesn't harm in general, but is not required anywhere else + up.trigger('UploadProgress', file); + } + } else { + file.loaded = file.size; + } + + chunkBlob = formData = null; // Free memory + + // Check if file is uploaded + if (!offset || offset >= blob.size) { + // If file was modified, destory the copy + if (file.size != file.origSize) { + blob.destroy(); + blob = null; + } + + up.trigger('UploadProgress', file); + + file.status = plupload.DONE; + + up.trigger('FileUploaded', file, { + response : xhr.responseText, + status : xhr.status, + responseHeaders: xhr.getAllResponseHeaders() + }); + } else { + // Still chunks left + delay(uploadNextChunk, 1); // run detached, otherwise event handlers interfere + } + }; + + xhr.onerror = function() { + handleError(); + }; + + xhr.onloadend = function() { + this.destroy(); + xhr = null; + }; + + // Build multipart request + if (up.settings.multipart && features.multipart) { + xhr.open("post", url, true); + + // Set custom headers + plupload.each(up.settings.headers, function(value, name) { + xhr.setRequestHeader(name, value); + }); + + formData = new o.FormData(); + + // Add multipart params + plupload.each(plupload.extend(args, up.settings.multipart_params), function(value, name) { + formData.append(name, value); + }); + + // Add file and send it + formData.append(up.settings.file_data_name, chunkBlob); + xhr.send(formData, { + runtime_order: up.settings.runtimes, + required_caps: up.settings.required_features, + preferred_caps: preferred_caps, + swf_url: up.settings.flash_swf_url, + xap_url: up.settings.silverlight_xap_url + }); + } else { + // if no multipart, send as binary stream + url = plupload.buildUrl(up.settings.url, plupload.extend(args, up.settings.multipart_params)); + + xhr.open("post", url, true); + + xhr.setRequestHeader('Content-Type', 'application/octet-stream'); // Binary stream header + + // Set custom headers + plupload.each(up.settings.headers, function(value, name) { + xhr.setRequestHeader(name, value); + }); + + xhr.send(chunkBlob, { + runtime_order: up.settings.runtimes, + required_caps: up.settings.required_features, + preferred_caps: preferred_caps, + swf_url: up.settings.flash_swf_url, + xap_url: up.settings.silverlight_xap_url + }); + } + } + + blob = file.getSource(); + + // Start uploading chunks + if (up.settings.resize.enabled && runtimeCan(blob, 'send_binary_string') && !!~o.inArray(blob.type, ['image/jpeg', 'image/png'])) { + // Resize if required + resizeImage.call(this, blob, up.settings.resize, function(resizedBlob) { + blob = resizedBlob; + file.size = resizedBlob.size; + uploadNextChunk(); + }); + } else { + uploadNextChunk(); + } + } + + + function onUploadProgress(up, file) { + calcFile(file); + } + + + function onStateChanged(up) { + if (up.state == plupload.STARTED) { + // Get start time to calculate bps + startTime = (+new Date()); + } else if (up.state == plupload.STOPPED) { + // Reset currently uploading files + for (var i = up.files.length - 1; i >= 0; i--) { + if (up.files[i].status == plupload.UPLOADING) { + up.files[i].status = plupload.QUEUED; + calc(); + } + } + } + } + + + function onCancelUpload() { + if (xhr) { + xhr.abort(); + } + } + + + function onFileUploaded(up) { + calc(); + + // Upload next file but detach it from the error event + // since other custom listeners might want to stop the queue + delay(function() { + uploadNext.call(up); + }, 1); + } + + + function onError(up, err) { + if (err.code === plupload.INIT_ERROR) { + up.destroy(); + } + // Set failed status if an error occured on a file + else if (err.file) { + err.file.status = plupload.FAILED; + calcFile(err.file); + + // Upload next file but detach it from the error event + // since other custom listeners might want to stop the queue + if (up.state == plupload.STARTED) { // upload in progress + up.trigger('CancelUpload'); + delay(function() { + uploadNext.call(up); + }, 1); + } + } + } + + + function onDestroy(up) { + up.stop(); + + // Purge the queue + plupload.each(files, function(file) { + file.destroy(); + }); + files = []; + + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.destroy(); + }); + fileInputs = []; + } + + if (fileDrops.length) { + plupload.each(fileDrops, function(fileDrop) { + fileDrop.destroy(); + }); + fileDrops = []; + } + + preferred_caps = {}; + disabled = false; + startTime = xhr = null; + total.reset(); + } + + + // Default settings + settings = { + runtimes: o.Runtime.order, + max_retries: 0, + chunk_size: 0, + multipart: true, + multi_selection: true, + file_data_name: 'file', + flash_swf_url: 'js/Moxie.swf', + silverlight_xap_url: 'js/Moxie.xap', + filters: { + mime_types: [], + prevent_duplicates: false, + max_file_size: 0 + }, + resize: { + enabled: false, + preserve_headers: true, + crop: false + }, + send_file_name: true, + send_chunk_number: true + }; + + + setOption.call(this, options, null, true); + + // Inital total state + total = new plupload.QueueProgress(); + + // Add public methods + plupload.extend(this, { + + /** + * Unique id for the Uploader instance. + * + * @property id + * @type String + */ + id : uid, + uid : uid, // mOxie uses this to differentiate between event targets + + /** + * Current state of the total uploading progress. This one can either be plupload.STARTED or plupload.STOPPED. + * These states are controlled by the stop/start methods. The default value is STOPPED. + * + * @property state + * @type Number + */ + state : plupload.STOPPED, + + /** + * Map of features that are available for the uploader runtime. Features will be filled + * before the init event is called, these features can then be used to alter the UI for the end user. + * Some of the current features that might be in this map is: dragdrop, chunks, jpgresize, pngresize. + * + * @property features + * @type Object + */ + features : {}, + + /** + * Current runtime name. + * + * @property runtime + * @type String + */ + runtime : null, + + /** + * Current upload queue, an array of File instances. + * + * @property files + * @type Array + * @see plupload.File + */ + files : files, + + /** + * Object with name/value settings. + * + * @property settings + * @type Object + */ + settings : settings, + + /** + * Total progess information. How many files has been uploaded, total percent etc. + * + * @property total + * @type plupload.QueueProgress + */ + total : total, + + + /** + * Initializes the Uploader instance and adds internal event listeners. + * + * @method init + */ + init : function() { + var self = this; + + if (typeof(settings.preinit) == "function") { + settings.preinit(self); + } else { + plupload.each(settings.preinit, function(func, name) { + self.bind(name, func); + }); + } + + bindEventListeners.call(this); + + // Check for required options + if (!settings.browse_button || !settings.url) { + this.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate('Init error.') + }); + return; + } + + initControls.call(this, settings, function(inited) { + if (typeof(settings.init) == "function") { + settings.init(self); + } else { + plupload.each(settings.init, function(func, name) { + self.bind(name, func); + }); + } + + if (inited) { + self.runtime = o.Runtime.getInfo(getRUID()).type; + self.trigger('Init', { runtime: self.runtime }); + self.trigger('PostInit'); + } else { + self.trigger('Error', { + code : plupload.INIT_ERROR, + message : plupload.translate('Init error.') + }); + } + }); + }, + + /** + * Set the value for the specified option(s). + * + * @method setOption + * @since 2.1 + * @param {String|Object} option Name of the option to change or the set of key/value pairs + * @param {Mixed} [value] Value for the option (is ignored, if first argument is object) + */ + setOption: function(option, value) { + setOption.call(this, option, value, !this.runtime); // until runtime not set we do not need to reinitialize + }, + + /** + * Get the value for the specified option or the whole configuration, if not specified. + * + * @method getOption + * @since 2.1 + * @param {String} [option] Name of the option to get + * @return {Mixed} Value for the option or the whole set + */ + getOption: function(option) { + if (!option) { + return settings; + } + return settings[option]; + }, + + /** + * Refreshes the upload instance by dispatching out a refresh event to all runtimes. + * This would for example reposition flash/silverlight shims on the page. + * + * @method refresh + */ + refresh : function() { + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.trigger('Refresh'); + }); + } + this.trigger('Refresh'); + }, + + /** + * Starts uploading the queued files. + * + * @method start + */ + start : function() { + if (this.state != plupload.STARTED) { + this.state = plupload.STARTED; + this.trigger('StateChanged'); + + uploadNext.call(this); + } + }, + + /** + * Stops the upload of the queued files. + * + * @method stop + */ + stop : function() { + if (this.state != plupload.STOPPED) { + this.state = plupload.STOPPED; + this.trigger('StateChanged'); + this.trigger('CancelUpload'); + } + }, + + + /** + * Disables/enables browse button on request. + * + * @method disableBrowse + * @param {Boolean} disable Whether to disable or enable (default: true) + */ + disableBrowse : function() { + disabled = arguments[0] !== undef ? arguments[0] : true; + + if (fileInputs.length) { + plupload.each(fileInputs, function(fileInput) { + fileInput.disable(disabled); + }); + } + + this.trigger('DisableBrowse', disabled); + }, + + /** + * Returns the specified file object by id. + * + * @method getFile + * @param {String} id File id to look for. + * @return {plupload.File} File object or undefined if it wasn't found; + */ + getFile : function(id) { + var i; + for (i = files.length - 1; i >= 0; i--) { + if (files[i].id === id) { + return files[i]; + } + } + }, + + /** + * Adds file to the queue programmatically. Can be native file, instance of Plupload.File, + * instance of mOxie.File, input[type="file"] element, or array of these. Fires FilesAdded, + * if any files were added to the queue. Otherwise nothing happens. + * + * @method addFile + * @since 2.0 + * @param {plupload.File|mOxie.File|File|Node|Array} file File or files to add to the queue. + * @param {String} [fileName] If specified, will be used as a name for the file + */ + addFile : function(file, fileName) { + var self = this + , queue = [] + , filesAdded = [] + , ruid + ; + + function filterFile(file, cb) { + var queue = []; + o.each(self.settings.filters, function(rule, name) { + if (fileFilters[name]) { + queue.push(function(cb) { + fileFilters[name].call(self, rule, file, function(res) { + cb(!res); + }); + }); + } + }); + o.inSeries(queue, cb); + } + + /** + * @method resolveFile + * @private + * @param {o.File|o.Blob|plupload.File|File|Blob|input[type="file"]} file + */ + function resolveFile(file) { + var type = o.typeOf(file); + + // o.File + if (file instanceof o.File) { + if (!file.ruid && !file.isDetached()) { + if (!ruid) { // weird case + return false; + } + file.ruid = ruid; + file.connectRuntime(ruid); + } + resolveFile(new plupload.File(file)); + } + // o.Blob + else if (file instanceof o.Blob) { + resolveFile(file.getSource()); + file.destroy(); + } + // plupload.File - final step for other branches + else if (file instanceof plupload.File) { + if (fileName) { + file.name = fileName; + } + + queue.push(function(cb) { + // run through the internal and user-defined filters, if any + filterFile(file, function(err) { + if (!err) { + // make files available for the filters by updating the main queue directly + files.push(file); + // collect the files that will be passed to FilesAdded event + filesAdded.push(file); + + self.trigger("FileFiltered", file); + } + delay(cb, 1); // do not build up recursions or eventually we might hit the limits + }); + }); + } + // native File or blob + else if (o.inArray(type, ['file', 'blob']) !== -1) { + resolveFile(new o.File(null, file)); + } + // input[type="file"] + else if (type === 'node' && o.typeOf(file.files) === 'filelist') { + // if we are dealing with input[type="file"] + o.each(file.files, resolveFile); + } + // mixed array of any supported types (see above) + else if (type === 'array') { + fileName = null; // should never happen, but unset anyway to avoid funny situations + o.each(file, resolveFile); + } + } + + ruid = getRUID(); + + resolveFile(file); + + if (queue.length) { + o.inSeries(queue, function() { + // if any files left after filtration, trigger FilesAdded + if (filesAdded.length) { + self.trigger("FilesAdded", filesAdded); + } + }); + } + }, + + /** + * Removes a specific file. + * + * @method removeFile + * @param {plupload.File|String} file File to remove from queue. + */ + removeFile : function(file) { + var id = typeof(file) === 'string' ? file : file.id; + + for (var i = files.length - 1; i >= 0; i--) { + if (files[i].id === id) { + return this.splice(i, 1)[0]; + } + } + }, + + /** + * Removes part of the queue and returns the files removed. This will also trigger the FilesRemoved and QueueChanged events. + * + * @method splice + * @param {Number} start (Optional) Start index to remove from. + * @param {Number} length (Optional) Lengh of items to remove. + * @return {Array} Array of files that was removed. + */ + splice : function(start, length) { + // Splice and trigger events + var removed = files.splice(start === undef ? 0 : start, length === undef ? files.length : length); + + // if upload is in progress we need to stop it and restart after files are removed + var restartRequired = false; + if (this.state == plupload.STARTED) { // upload in progress + plupload.each(removed, function(file) { + if (file.status === plupload.UPLOADING) { + restartRequired = true; // do not restart, unless file that is being removed is uploading + return false; + } + }); + + if (restartRequired) { + this.stop(); + } + } + + this.trigger("FilesRemoved", removed); + + // Dispose any resources allocated by those files + plupload.each(removed, function(file) { + file.destroy(); + }); + + if (restartRequired) { + this.start(); + } + + return removed; + }, + + /** + * Dispatches the specified event name and it's arguments to all listeners. + * + * + * @method trigger + * @param {String} name Event name to fire. + * @param {Object..} Multiple arguments to pass along to the listener functions. + */ + + /** + * Check whether uploader has any listeners to the specified event. + * + * @method hasEventListener + * @param {String} name Event name to check for. + */ + + + /** + * Adds an event listener by name. + * + * @method bind + * @param {String} name Event name to listen for. + * @param {function} func Function to call ones the event gets fired. + * @param {Object} scope Optional scope to execute the specified function in. + */ + bind : function(name, func, scope) { + var self = this; + // adapt moxie EventTarget style to Plupload-like + plupload.Uploader.prototype.bind.call(this, name, function() { + var args = [].slice.call(arguments); + args.splice(0, 1, self); // replace event object with uploader instance + return func.apply(this, args); + }, 0, scope); + }, + + /** + * Removes the specified event listener. + * + * @method unbind + * @param {String} name Name of event to remove. + * @param {function} func Function to remove from listener. + */ + + /** + * Removes all event listeners. + * + * @method unbindAll + */ + + + /** + * Destroys Plupload instance and cleans after itself. + * + * @method destroy + */ + destroy : function() { + this.trigger('Destroy'); + settings = total = null; // purge these exclusively + this.unbindAll(); + } + }); +}; + +plupload.Uploader.prototype = o.EventTarget.instance; + +/** + * Constructs a new file instance. + * + * @class File + * @constructor + * + * @param {Object} file Object containing file properties + * @param {String} file.name Name of the file. + * @param {Number} file.size File size. + */ +plupload.File = (function() { + var filepool = {}; + + function PluploadFile(file) { + + plupload.extend(this, { + + /** + * File id this is a globally unique id for the specific file. + * + * @property id + * @type String + */ + id: plupload.guid(), + + /** + * File name for example "myfile.gif". + * + * @property name + * @type String + */ + name: file.name || file.fileName, + + /** + * File type, `e.g image/jpeg` + * + * @property type + * @type String + */ + type: file.type || '', + + /** + * File size in bytes (may change after client-side manupilation). + * + * @property size + * @type Number + */ + size: file.size || file.fileSize, + + /** + * Original file size in bytes. + * + * @property origSize + * @type Number + */ + origSize: file.size || file.fileSize, + + /** + * Number of bytes uploaded of the files total size. + * + * @property loaded + * @type Number + */ + loaded: 0, + + /** + * Number of percentage uploaded of the file. + * + * @property percent + * @type Number + */ + percent: 0, + + /** + * Status constant matching the plupload states QUEUED, UPLOADING, FAILED, DONE. + * + * @property status + * @type Number + * @see plupload + */ + status: plupload.QUEUED, + + /** + * Date of last modification. + * + * @property lastModifiedDate + * @type {String} + */ + lastModifiedDate: file.lastModifiedDate || (new Date()).toLocaleString(), // Thu Aug 23 2012 19:40:00 GMT+0400 (GET) + + /** + * Returns native window.File object, when it's available. + * + * @method getNative + * @return {window.File} or null, if plupload.File is of different origin + */ + getNative: function() { + var file = this.getSource().getSource(); + return o.inArray(o.typeOf(file), ['blob', 'file']) !== -1 ? file : null; + }, + + /** + * Returns mOxie.File - unified wrapper object that can be used across runtimes. + * + * @method getSource + * @return {mOxie.File} or null + */ + getSource: function() { + if (!filepool[this.id]) { + return null; + } + return filepool[this.id]; + }, + + /** + * Destroys plupload.File object. + * + * @method destroy + */ + destroy: function() { + var src = this.getSource(); + if (src) { + src.destroy(); + delete filepool[this.id]; + } + } + }); + + filepool[this.id] = file; + } + + return PluploadFile; +}()); + + +/** + * Constructs a queue progress. + * + * @class QueueProgress + * @constructor + */ + plupload.QueueProgress = function() { + var self = this; // Setup alias for self to reduce code size when it's compressed + + /** + * Total queue file size. + * + * @property size + * @type Number + */ + self.size = 0; + + /** + * Total bytes uploaded. + * + * @property loaded + * @type Number + */ + self.loaded = 0; + + /** + * Number of files uploaded. + * + * @property uploaded + * @type Number + */ + self.uploaded = 0; + + /** + * Number of files failed to upload. + * + * @property failed + * @type Number + */ + self.failed = 0; + + /** + * Number of files yet to be uploaded. + * + * @property queued + * @type Number + */ + self.queued = 0; + + /** + * Total percent of the uploaded bytes. + * + * @property percent + * @type Number + */ + self.percent = 0; + + /** + * Bytes uploaded per second. + * + * @property bytesPerSec + * @type Number + */ + self.bytesPerSec = 0; + + /** + * Resets the progress to it's initial values. + * + * @method reset + */ + self.reset = function() { + self.size = self.loaded = self.uploaded = self.failed = self.queued = self.percent = self.bytesPerSec = 0; + }; +}; + +window.plupload = plupload; + +}(window, mOxie)); diff --git a/mobile/reg/lib/plupload-2.1.2/js/plupload.full.min.js b/mobile/reg/lib/plupload-2.1.2/js/plupload.full.min.js new file mode 100755 index 0000000..ca6cdf8 --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/js/plupload.full.min.js @@ -0,0 +1,28 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",h="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",b="moxie/file/FileReader",R="moxie/core/utils/Url",T="moxie/file/FileReaderSync",A="moxie/xhr/FormData",S="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",h="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var h=f[n],p=f[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<h.length;a++)if(l=h[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(h,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[h,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?void t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),void(n[this.uid][e]=s))},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,m[h++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[h++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,p],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[h,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?void i.init():void i.trigger("Error")):void o(t)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),void(i=null))}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,h,p,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,h;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);h={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},h,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:void c.files.push(new a(c.ruid,e))})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,h,u,w,v,p,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(b,[u,m,h,p,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var h=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=h;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(h)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend")) +},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(R,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(A,[h,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(S,[u,h,p,m,R,g,x,y,T,A,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function h(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:void(l.can("define_property")?y[e]=t:v[e]=t):void 0}function u(t){function i(){k&&(k.destroy(),k=null),s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",h.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==h.LOADING&&(n("readyState",h.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",h.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",h.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:b,password:R,headers:x,mimeType:A,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:h.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},b,R,T=null,A=null,S=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(b=u||l.user,R=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);S=!w,O=!1,x={},g.call(this),n("readyState",h.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[h.LOADING,h.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,A=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,A=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",A="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!S&&this.upload.hasEventListener(),N=!1,D=!n,S||(O=!0),u.call(this,n)},abort:function(){if(N=!0,S=!1,~e.inArray(n("readyState"),[h.UNSENT,h.OPENED,h.DONE]))n("readyState",h.UNSENT);else{if(n("readyState",h.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return h.UNSENT=0,h.OPENED=1,h.HEADERS_RECEIVED=2,h.LOADING=3,h.DONE=4,h.prototype=n.instance,h}),i(O,[u,m,v,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,h,T,S,g,v,O,d,p,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function h(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof h){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(p),c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,crop:!1,preserveHeaders:!0};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.getRuntime().exec.call(this,"Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),void o.trigger("embedded")}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},p,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,p=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=p.type||this.type||"image/jpeg",l=p.quality||90,d="undefined"!==e.typeOf(p.crop)?p.crop:!1,p.width)m=p.width,g=p.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new h,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var p=["progress","load","error","resize","embedded"];return h.MAX_RESIZE_WIDTH=6500,h.MAX_RESIZE_HEIGHT=6500,h.prototype=c.instance,h}),i(D,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,h,p,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),h=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(h,"position")&&(h.style.position="relative"),p=parseInt(n.getStyle(h,"z-index"),10)||1,h.style.zIndex=p,d.style.zIndex=p-1,i.addEvent(h,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?h:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser&&"IEMobile"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var n=t.toArray(e.dataTransfer.types||[]);return-1!==t.inArray("Files",n)||-1!==t.inArray("public.file-url",n)||-1!==t.inArray("application/x-moz-file",n)}function o(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function a(e){if(!f.length)return!0;var n=r.getFileExtension(e.name);return!n||-1!==t.inArray(n,f)}function s(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();a(n)&&d.push(n)}else i.push(t)}),i.length?u(i,n):n()}function u(e,n){var i=[];t.each(e,function(e){i.push(function(t){c(e,t)})}),t.inSeries(i,function(){n()})}function c(e,t){e.isFile?e.file(function(e){a(e)&&d.push(e),t()},function(){t()}):e.isDirectory?l(e,t):t()}function l(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){u(i,t)})}var d=[],f=[],h;t.extend(this,{init:function(n){var r=this,u;h=n,f=o(h.accept),u=h.container,i.addEvent(u,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},r.uid),i.addEvent(u,"drop",function(n){e(n)&&(n.preventDefault(),d=[],n.dataTransfer.items&&n.dataTransfer.items[0].webkitGetAsEntry?s(n.dataTransfer.items,function(){r.trigger("drop")}):(t.each(n.dataTransfer.files,function(e){a(e)&&d.push(e)}),r.trigger("drop")))},r.uid),i.addEvent(u,"dragenter",function(e){r.trigger("dragenter")},r.uid),i.addEvent(u,"dragleave",function(e){r.trigger("dragleave")},r.uid)},getFiles:function(){return d},destroy:function(){i.removeAllEvents(h&&n.get(h.container),this.uid),d=f=h=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,R,w,y,A,h,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return h.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,h,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),h=c(),h.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}h.upload?(n.withCredentials&&(h.withCredentials=!0),h.addEventListener("load",function(e){s.trigger(e)}),h.addEventListener("error",function(e){s.trigger(e)}),h.addEventListener("progress",function(e){s.trigger(e)}),h.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):h.onreadystatechange=function v(){switch(h.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=h.getResponseHeader("Content-Length")||0),h.responseText&&(t=h.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:h.onreadystatechange=function(){},s.trigger(0===h.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){h.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in h&&(h.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?h.sendAsBinary?h.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);h.send(e.buffer)}():h.send(r),s.trigger("loadstart")},getStatus:function(){try{if(h)return h.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,h.response),o=h.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?h.response:200===h.status&&window.JSON?JSON.parse(h.responseText):null;case"document":return l(h);default:return""!==h.responseText?h.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return h.getAllResponseHeaders()}catch(e){}return""},abort:function(){h&&h.abort()},destroy:function(){f=p=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(t>>Math.abs(a+8*s)&255);n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:void(r=e)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):void i(n,r,4)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,h,p,m=[],g={};for(r=0;i>r;r++)if(h=f=e+12*r+2,s=n[a.SHORT(h)],s!==t){switch(u=a.SHORT(h+=2),d=a.LONG(h+=2),h+=4,m=[],u){case 1:case 7:for(d>4&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(h+o);break;case 2:d>4&&(h=a.LONG(h)+c.tiffHeader),g[s]=a.STRING(h,d-1);continue;case 3:for(d>2&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(h+2*o);break;case 4:for(d>1&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(h+4*o);break;case 5:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(h+4*o)/a.LONG(h+4*o+4);break;case 9:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o);break;case 10:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o)/a.SLONG(h+4*o+4);break;default:continue}p=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof p?l[s][p]:p}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\x00"===a.STRING(4,5).toUpperCase()?r():!1):!1 +},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,h,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,h;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,h=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return h?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.getBinary())):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),h&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[h,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,h,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,h=document.createElement("canvas");h.width=h.height=f;for(var p=h.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;p.clearRect(0,0,f,f),p.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,b=Math.ceil(v*u/a/m);d.drawImage(h,0,0,w,v,E,x,_,b),y+=f}g+=f}h=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,h,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function h(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,h,g;if(R=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),h=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),h>i&&(l=Math.round((h-i)/2))):(E.width=f,E.height=h),R||m(E.width,E.height,g),p.call(this,d,E,-c,-l,f,h),this.width=E.width,this.height=E.height,b=!0,void a.trigger("Resize"))}function p(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,b=!1}var v=this,y,w,E,_,x,b=!1,R=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),void d.call(this,_)):void f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){h.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&h.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!b)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!b)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),R&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return b=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,h,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===c.mode},stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,A,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,h,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,h,p,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(h=n.get(a+"_form"),h&&t.extend(h.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),t.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=p=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=h=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,R,h,L,y,A],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function h(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),w&&p.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),h(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,h,p,m,g,v,y,w,E,_,x,b,R,T,A,S,O,I,L])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this); +/** + * Plupload - multi-runtime File Uploader + * v2.1.2 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.2",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie); \ No newline at end of file diff --git a/mobile/reg/lib/plupload-2.1.2/js/plupload.min.js b/mobile/reg/lib/plupload-2.1.2/js/plupload.min.js new file mode 100755 index 0000000..1f4279d --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/js/plupload.min.js @@ -0,0 +1,13 @@ +/** + * Plupload - multi-runtime File Uploader + * v2.1.2 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.2",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie); \ No newline at end of file diff --git a/mobile/reg/lib/plupload-2.1.2/license.txt b/mobile/reg/lib/plupload-2.1.2/license.txt new file mode 100755 index 0000000..d511905 --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/license.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/mobile/reg/lib/plupload-2.1.2/readme.md b/mobile/reg/lib/plupload-2.1.2/readme.md new file mode 100755 index 0000000..8fa2238 --- /dev/null +++ b/mobile/reg/lib/plupload-2.1.2/readme.md @@ -0,0 +1,147 @@ +# Plupload + +Plupload is a cross-browser multi-runtime file uploading API. Basically, a set of tools that will help you to +build a reliable and visually appealing file uploader in minutes. + +Historically, Plupload comes from a dark and hostile age of no HTML5, hence all the alternative fallbacks, +like Flash, Silverlight and Java (still in development). It is meant to provide an API, that +will work anywhere and in any case, in one way or another. While having very solid fallbacks, Plupload +is built with the future of HTML5 in mind. + +### Table of Contents +* [Backstory](https://github.com/moxiecode/plupload/blob/master/readme.md#backstory) +* [Structure](https://github.com/moxiecode/plupload/blob/master/readme.md#structure) + * [File API and XHR L2 pollyfills](https://github.com/moxiecode/moxie/blob/master/README.md) + * [Plupload API](https://github.com/moxiecode/plupload/wiki/API) + * [UI Widget](https://github.com/moxiecode/plupload/wiki/UI.Plupload) + * [Queue Widget](https://github.com/moxiecode/plupload/wiki/pluploadQueue) +* [Demos](https://github.com/jayarjo/plupload-demos/blob/master/README.md) +* [Building Instructions](https://github.com/moxiecode/plupload/blob/master/readme.md#build) +* [Getting Started](https://github.com/moxiecode/plupload/wiki/Getting-Started) + * [Options](https://github.com/moxiecode/plupload/wiki/Options) + * [Events](https://github.com/moxiecode/plupload/wiki/Uploader#wiki-events) + * [Methods](https://github.com/moxiecode/plupload/wiki/Uploader#wiki-methods) + * [Plupload in Your Language](https://github.com/moxiecode/plupload/wiki/Plupload-in-Your-Language) + * [File Filters](https://github.com/moxiecode/plupload/wiki/File-Filters) + * [Image Resizing on Client-Side](https://github.com/moxiecode/plupload/wiki/Image-Resizing-on-Client-Side) + * [Chunking](https://github.com/moxiecode/plupload/wiki/Chunking) + * [Upload to Amazon S3](https://github.com/moxiecode/plupload/wiki/Upload-to-Amazon-S3) +* [FAQ](https://github.com/moxiecode/plupload/wiki/Frequently-Asked-Questions) +* [Support](https://github.com/moxiecode/plupload/blob/master/readme.md##support) + * [Create a Fiddle](https://github.com/moxiecode/plupload/wiki/Create-a-Fiddle) +* [Contributing](https://github.com/moxiecode/plupload/blob/master/readme.md#contribute) +* [License](https://github.com/moxiecode/plupload/blob/master/readme.md#license) +* [Contact Us](http://www.moxiecode.com/contact.php) + +<a name="backstory" /> +### Backstory + +Plupload started in a time when uploading a file in a responsive and customizable manner was a real pain. +Internally, browsers only had the `input[type="file"]` element. It was ugly and clunky at the same time. +One couldn't even change it's visuals, without hiding it and coding another one on top of it from scratch. +And then there was no progress indication for the upload process... Sounds pretty crazy today. + +It was very logical for developers to look for alternatives and writing their own implementations, using +Flash and Java, in order to somehow extend limited browser capabilities. And so did we, in our search for +a reliable and flexible file uploader for +our [TinyMCE](http://www.tinymce.com/index.php)'s +[MCImageManager](http://www.tinymce.com/enterprise/mcimagemanager.php). + +Quickly enough though, Plupload grew big. It easily split into a standalone project. +With major *version 2.0* it underwent another huge reconstruction, basically +[from the ground up](http://blog.moxiecode.com/2012/11/28/first-public-beta-plupload-2/), +as all the low-level runtime logic has been extracted into separate [File API](http://www.w3.org/TR/FileAPI/) +and [XHR L2](http://www.w3.org/TR/XMLHttpRequest/) pollyfills (currently known under combined name of [mOxie](https://github.com/moxiecode/moxie)), +giving Plupload a chance to evolve further. + +<a name="structure" /> +### Structure + +Currently, Plupload may be considered as consisting of three parts: low-level pollyfills, +Plupload API and Widgets (UI and Queue). Initially, Widgets were meant only to serve as examples +of the API, but quickly formed into fully-functional API implementations that now come bundled with +the Plupload API. This has been a source for multiple misconceptions about the API as Widgets were +easily mistaken for the Plupload itself. They are only implementations, such as any of you can +build by yourself out of the API. + +* [Low-level pollyfills (mOxie)](https://github.com/moxiecode/moxie) - have their own [code base](https://github.com/moxiecode/moxie) and [documentation](https://github.com/moxiecode/moxie/wiki) on GitHub. +* [Plupload API](https://github.com/moxiecode/plupload/wiki/API) +* [UI Widget](https://github.com/moxiecode/plupload/wiki/UI.Plupload) +* [Queue Widget](https://github.com/moxiecode/plupload/wiki/pluploadQueue) + +<a name="build" /> +### Building instructions + +Plupload depends on File API and XHR2 L2 pollyfills that currently have their +[own repository](https://github.com/moxiecode/moxie) on GitHub. However, in most cases you shouldn't +care as we bundle the latest build of mOxie, including full and minified JavaScript source and +pre-compiled `SWF` and `XAP` components, with [every release](https://github.com/moxiecode/plupload/releases). You can find everything you may need under `js/` folder. + +There are cases where you might need a custom build, for example free of unnecessary runtimes, half the +original size, etc. The difficult part of this task comes from mOxie and its set of additional runtimes +that require special tools on your workstation in order to compile. +Consider [build instructions for mOxie](https://github.com/moxiecode/moxie#build-instructions) - +everything applies to Plupload as well. + +First of all, if you want to build custom Plupload packages you will require [Node.js](http://nodejs.org/), +as this is our build environment of choice. Node.js binaries (as well as Source) +[are available](http://nodejs.org/download/) for all major operating systems. + +Plupload includes _mOxie_ as a submodule, it also depends on some other repositories for building up it's dev +environment - to avoid necessity of downloading them one by one, we recommended you to simply clone Plupload +with [git](http://git-scm.com/) recursively (you will require git installed on your system for this operation +to succeed): + +``` +git clone --recursive https://github.com/moxiecode/plupload.git +``` + +And finalize the preparation stage with: `npm install` - this will install all additional modules, including those +required by dev and test environments. In case you would rather keep it minimal, add a `--production` flag. + +*Note:* Currently, for an unknown reason, locally installed Node.js modules on Windows, may not be automatically +added to the system PATH. So, if `jake` commands below are not recognized you will need to add them manually: + +``` +set PATH=%PATH%;%CD%\node_modules\.bin\ +``` + +<a name="support" /> +### Support + +We are actively standing behind the Plupload and now that we are done with major rewrites and refactoring, +the only real goal that we have ahead is making it as reliable and bulletproof as possible. We are open to +all the suggestions and feature requests. We ask you to file bug reports if you encounter any. We may not +react to them instantly, but we constantly bear them in my mind as we extend the code base. + +In addition to dedicated support for those who dare to buy our OEM licenses, we got +[discussion boards](http://www.plupload.com/punbb/index.php), which is like an enormous FAQ, +covering every possible application case. Of course, you are welcome to file a bug report or feature request, +here on [GitHub](https://github.com/moxiecode/plupload/issues). + +Sometimes it is easier to notice the problem when bug report is accompained by the actual code. Consider providing +[a Plupload fiddle](https://github.com/moxiecode/plupload/wiki/Create-a-Fiddle) for the troublesome code. + +<a name="contribute" /> +### Contributing + +We are open to suggestions and code revisions, however there are some rules and limitations that you might +want to consider first. + +* Code that you contribute will automatically be licensed under the LGPL, but will not be limited to LGPL. +* Although all contributors will get the credit for their work, copyright notices will be changed to [Moxiecode Systems AB](http://www.moxiecode.com/). +* Third party code will be reviewed, tested and possibly modified before being released. + +These basic rules help us earn a living and ensure that code remains Open Source and compatible with LGPL license. All contributions will be added to the changelog and appear in every release and on the site. + +An easy place to start is to [translate Plupload to your language](https://github.com/moxiecode/plupload/wiki/Plupload-in-Your-Language#contribute). + +You can read more about how to contribute at: [http://www.plupload.com/contributing](http://www.plupload.com/contributing) + +<a name="license" /> +### License + +Copyright 2013, [Moxiecode Systems AB](http://www.moxiecode.com/) +Released under [GPLv2 License](https://github.com/moxiecode/plupload/blob/master/license.txt). + +We also provide [commercial license](http://www.plupload.com/commercial.php). diff --git a/mobile/reg/reg.html b/mobile/reg/reg.html new file mode 100755 index 0000000..6d803c7 --- /dev/null +++ b/mobile/reg/reg.html @@ -0,0 +1,97 @@ +<!doctype html> +<html> + + <head> + <meta charset="UTF-8"> + <title></title> + <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> + <link href="css/login.css" rel="stylesheet" /> + <link href="css/global.css" rel="stylesheet" /> + </head> + + <body> + <div class="header"> + <div class="header_con"> + <!-- <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> --> + <!-- <img src="img/qlgylogo.png" class="oc_logo" /> --> + <!-- <p class="title">全亮共赢扫码注册</p> --> + </div> + </div> + <!-- <div class="top" style="opacity: 0;">注册</div> --> + <div class="con" style=""> + <div class="rowImg"><img src="img/qlgylogo.png" class="oc_logo" /> + </div> + <div class="row "> + <img src="img/icon_phone1.png" /> + <span class="s1">用户名:</span> + <input type="text" name="loginName" id="loginName" value="" placeholder="输入用户名" /> + </div> + + <div class="row"> + <img src="img/icon_pwd1.png" /> + <span class="s1">密码:</span> + <input type="password" name="loginPwd" id="loginPwd" maxlength="20" value="" placeholder="请输入密码" /> + </div> + <div class="row "> + <img src="img/icon_pwd1.png" /> + <span class="s1">确认密码:</span> + <input type="password" name="reUserPwd" id="reUserPwd" maxlength="20" value="" placeholder="请输入确认密码" /> + </div> + <div class="row "> + <img src="img/icon_pwd1.png" /> + <span class="s1">操作密码:</span> + <input type="password" name="loginPaywd" id="loginPaywd" maxlength="20" value="" placeholder="请输入操作密码" /> + </div> + <div class="row "> + <img src="img/icon_pwd1.png" /> + <span class="s1">确认操作密码:</span> + <input type="password" name="reUserPaywd" id="reUserPaywd" maxlength="20" value="" placeholder="请输入确认操作密码" /> + </div> + <div class="row "> + <img src="img/icon_pwd1.png" /> + <span class="s1">推荐人:</span> + <input type="text" name="pName" id="pName" value="" placeholder="请输入推荐人手机号" /> + </div> + <div class="row pNameCode" style="display: none;"> + <img src="img/icon_pwd1.png" /> + <span class="s1 s99">验证码:</span> + <input class="tpyzm" id="mobileCode" type="text" maxlength="6" placeholder="请输入验证码" /> + <input type="button" id="getMobileCode" value="获取验证码"></input> + </div> + + + <div class="zcxy clearfix"> + <div class="zcxytitle shadown_wai"> + <label for="">请仔细阅读协议 确认无误后签订协议书</label> + </div> + <div class="zcxycontent shadown_wai"> + </div> + </div> + + <div class="renzhengphoto shadown_wai"> + <label for="">手持确认书照片</label> + <input type="hidden" value='' class='regConfirmImg inp' id="regConfirmImg"> + <div class='photos'> + <span></span> + <div class="photos_con"> + <div id="regConfirm" class="ossfile clearfix" >你的浏览器不支持flash,Silverlight或者HTML5!</div> + <!-- <div class="regConfirm photo"> + <img src="" class='ossfile' id='regConfirm' alt=""> + <span class=""></span> + </div> --> + </div> + </div> + </div> + <div class="down clearfix"> + <div class="btn shadown_wai">注册</div> + </div> + </div> + </div> + </body> + <script src="js/jquery-3.2.1.min.js"></script> + <script src="lib/plupload-2.1.2/js/plupload.full.min.js"></script> + <script src="js/upload.js"></script> + <script src="js/reg.js?ver=3"></script> + + <!-- <script src="lib/plupload-2.1.2/js/moxie.min.js"></script> --> +</html> diff --git a/oss/get.php b/oss/get.php new file mode 100755 index 0000000..ca76e21 --- /dev/null +++ b/oss/get.php @@ -0,0 +1,49 @@ +<?php +header('Access-Control-Allow-Origin:*'); + function gmt_iso8601($time) { + $dtStr = date("c", $time); + $mydatetime = new DateTime($dtStr); + $expiration = $mydatetime->format(DateTime::ISO8601); + $pos = strpos($expiration, '+'); + $expiration = substr($expiration, 0, $pos); + return $expiration."Z"; + } + + $id= 'LTAIfppBmzIHRPV0'; + $key= 'OdsoQBa30zzPC38Jq9EmefbqSgFZnX'; + $host = 'http://qlgmall.oss-cn-hongkong.aliyuncs.com'; + + $now = time(); + $expire = 30; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问 + $end = $now + $expire; + $expiration = gmt_iso8601($end); + $save_dir = $_GET['dir']; + $dir = 'upload/'.$save_dir."/".date('Y-m').'/'; + + //最大文件大小.用户可以自己设置 + $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000); + $conditions[] = $condition; + + //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录 + $start = array(0=>'starts-with', 1=>'$key', 2=>$dir); + $conditions[] = $start; + + + $arr = array('expiration'=>$expiration,'conditions'=>$conditions); + //echo json_encode($arr); + //return; + $policy = json_encode($arr); + $base64_policy = base64_encode($policy); + $string_to_sign = $base64_policy; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true)); + + $response = array(); + $response['accessid'] = $id; + $response['host'] = $host; + $response['policy'] = $base64_policy; + $response['signature'] = $signature; + $response['expire'] = $end; + //这个参数是设置用户上传指定的前缀 + $response['dir'] = $dir; + echo json_encode($response); +?> diff --git a/oss/qiniu.php b/oss/qiniu.php new file mode 100755 index 0000000..c0d96a7 --- /dev/null +++ b/oss/qiniu.php @@ -0,0 +1,295 @@ +<?php +class SDK implements ArrayAccess { + const QINIU_UP_HOST = 'http://up.qiniu.com'; + const QINIU_RS_HOST = 'http://rs.qbox.me'; + const QINIU_RSF_HOST= 'http://rsf.qbox.me'; + protected $deadline = 0; + //查看 + //删除 + //复制 x + //移动 x + //上传 + protected $access_token ; + protected $secret_token ; + protected $bucket; + protected $cache = array(); + protected $aliases = array(); //文件别名, 针对文件名比较长的文件 + //curl + protected $ch; + protected $headers; + protected $options = array(); + protected $response; + protected $info; + protected $errno; + protected $error; + public function __construct($access_token, $secret_token, $bucket = null) + { + $this->access_token = $access_token; + $this->secret_token = $secret_token; + $this->bucket = $bucket; + $this->deadline = time()+3600; + } + public function setDeadline($deadline) + { + $this->deadline = $deadline; + } + //获取空间名称 + public function getBucket() + { + return $this->bucket; + } + //设置空间 + public function setBucket($bucket) + { + $this->bucket = $bucket; + } + /** + * 查看指定文件信息。 + * @param string $key 文件名或者目录+文件名 + * @return Array|boolean 成功返回文件内容,否会返回false. + */ + public function stat($key) + { + list($bucket, $key) = $this->parseKey($key); + if ( is_null($bucket) ) + { + die('error'); + } + $url = self::QINIU_RS_HOST .'/stat/' . $this->encode("$bucket:$key"); + $token = $this->accessToken($url); + $options[CURLOPT_HTTPHEADER] = array('Authorization: QBox '. $token); + return $this->get($url, $options); + } + /** + * 删除指定文件信息。 + * @param string $key 文件名或者目录+文件名 + * @return NULL + */ + public function delete($key) + { + list($bucket, $key) = $this->parseKey($key); + if ( is_null($bucket) ) + { + die('error'); + } + $url = self::QINIU_RS_HOST .'/delete/' . $this->encode("$bucket:$key"); + $token = $this->accessToken($url); + $options[CURLOPT_HTTPHEADER] = array('Authorization: QBox '. $token); + return $this->get($url, $options); + } + public function upload($file, $name=null, $token = null) + { + if ( NULL === $token ) + { + $token = $this->uploadToken($this->bucket); + } + if ( !file_exists($file) ) + { + die('文件不存在,构建一个临时文件'); + } + $hash = hash_file('crc32b', $file); + $array = unpack('N', pack('H*', $hash)); + $postFields = array( + 'token' => $token, + 'file' => '@'.$file, + 'key' => $name, + 'crc32' => sprintf('%u', $array[1]), + ); + //未指定文件名,使用七牛默认的随机文件名 + if ( NULL === $name ) + { + unset($postFields['key']); + } + else + { + //设置文件名后缀。 + } + $options = array( + CURLOPT_POSTFIELDS => $postFields, + ); + return $this->get(self::QINIU_UP_HOST, $options); + } + protected function parseKey($key) + { + $key = $this->getAlias($key); + if ( isset($this->cache[$key]) ) + { + return $this->cache[$key]; + } + $segments = explode("|", $key); + if ( count($segments) === 1 ) + { + $this->cache[$key] = array($this->bucket, $segments[0]); + } + else + { + $temp = implode('|', array_slice($segments, 1)); + $this->cache[$key] = array($segments[0], $temp); + } + return $this->cache[$key]; + } + public function getAlias($key) + { + return isset($this->aliases[$key]) ? $this->aliases[$key] : $key; + } + public function uploadToken($config = array()) + { + if ( is_string($config) ) + { + $scope = $config; + $config = array(); + } + else + { + $scope = $config['scope']; + } + $config['scope'] = $scope; + //硬编码,需修改。 + $config['deadline'] = $this->deadline; + foreach ( $this->activeUploadSettings($config) as $key => $value ) + { + if ( $value ) + { + $config[$key] = $value; + } + } + //build token + $body = json_encode($config); + $body = $this->encode($body); + $sign = hash_hmac('sha1', $body, $this->secret_token, true); + return $this->access_token . ':' . $this->encode($sign) . ':' .$body; + } + public function uploadSettings() + { + return array( + 'scope','deadline','callbackUrl', 'callbackBody', 'returnUrl', + 'returnBody', 'asyncOps', 'endUser', 'exclusive', 'detectMime', + 'fsizeLimit', 'saveKey', 'persistentOps', 'persistentNotifyUrl' + ); + } + protected function activeUploadSettings($array) + { + return array_intersect_key($array, array_flip($this->uploadSettings())); + } + public function accessToken($url, $body = false) + { + $url = parse_url($url); + $result = ''; + if (isset($url['path'])) { + $result = $url['path']; + } + if (isset($url['query'])) { + $result .= '?' . $url['query']; + } + $result .= "\n"; + if ($body) { + $result .= $body; + } + $sign = hash_hmac('sha1', $result, $this->secret_token, true); + return $this->access_token . ':' . $this->encode($sign); + } + public function get($url, $options = array()) + { + $this->ch = curl_init(); + $this->options[CURLOPT_URL] = $url; + $this->options = $options + $this->options; + //临时处理逻辑 + + return $this->execute(); + } + protected function execute() + { + if ( !$this->option(CURLOPT_RETURNTRANSFER) ) + { + $this->option(CURLOPT_RETURNTRANSFER, true); + } + if ( !$this->option(CURLOPT_SSL_VERIFYPEER) ) + { + $this->option(CURLOPT_SSL_VERIFYPEER, false); + } + if ( !$this->option(CURLOPT_SSL_VERIFYHOST) ) + { + $this->option(CURLOPT_SSL_VERIFYHOST, false); + } + if ( !$this->option(CURLOPT_CUSTOMREQUEST) ) + { + $this->option(CURLOPT_CUSTOMREQUEST, 'POST'); + } + if ( $this->headers ) + { + $this->option(CURLOPT_HTTPHEADER, $this->headers); + } + $this->setupCurlOptions(); + $this->response = curl_exec($this->ch); + $this->info = curl_getinfo($this->ch); + if ( $this->response === false ) + { + $this->error = curl_error($this->ch); + $this->errno = curl_errno($this->ch); + curl_close($this->ch); + return false; + } + else + { + curl_close($this->ch); + //未处理http_code。 + if ( $this->info['content_type'] == 'application/json' ) + { + $this->response = json_decode($this->response, true); + } + return $this->response; + } + } + public function setupCurlOptions() + { + curl_setopt_array($this->ch, $this->options); + } + public function option($key, $value = NULL) + { + if ( is_null($value) ) + { + return !isset($this->options[$key]) ? null: $this->options[$key]; + } + else + { + $this->options[$key] = $value; + return $this; + } + } + public function alias($key, $value) + { + $this->alias[$key] = $value; + } + protected function encode($str) + { + $trans = array("+" => "-", "/" => "_"); + return strtr(base64_encode($str), $trans); + } + public function __get($key) + { + return $this->$key; + } + public function offsetExists($key) + { + //check response; + } + public function offsetGet($key) + { + return $this->stat($key); + } + public function offsetSet($key, $value) + { + //move or copy + } + public function offsetUnset($key) + { + return $this->delete(); + } +} +$access_token = 's0etbUw8isXaxMNp1hM02Ud1RLpeBzS6I_gVDMlR'; +$secret_token = 'Ix9LwSpAk0QpsH2vAMup0QLEKMVK5UstDxWCIb-_'; +$bucket = 'qlgmall'; +$ql = new SDK($access_token, $secret_token, $bucket); +$response['token'] = $ql->uploadToken($bucket); +$response['url'] = 'http://qlg.ect99.com/';//'http://ppzpdlj0h.bkt.clouddn.com'; +echo json_encode($response); \ No newline at end of file diff --git a/reg.lock b/reg.lock new file mode 100755 index 0000000..e69de29 diff --git a/robots.txt b/robots.txt new file mode 100755 index 0000000..449d005 --- /dev/null +++ b/robots.txt @@ -0,0 +1,7 @@ +/****************************** + * + * + * robots + * + * + ****************************** \ No newline at end of file diff --git a/runtime/cache/WSTMART_/0c/c7451a727bd13b3a7a84a17f6cecbf.php b/runtime/cache/WSTMART_/0c/c7451a727bd13b3a7a84a17f6cecbf.php new file mode 100644 index 0000000..307360c --- /dev/null +++ b/runtime/cache/WSTMART_/0c/c7451a727bd13b3a7a84a17f6cecbf.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +s:5:"12.00"; \ No newline at end of file diff --git a/runtime/cache/WSTMART_/0c/f2a8083a7195e5b4129d1c7ccb698a.php b/runtime/cache/WSTMART_/0c/f2a8083a7195e5b4129d1c7ccb698a.php new file mode 100644 index 0000000..4758a0d --- /dev/null +++ b/runtime/cache/WSTMART_/0c/f2a8083a7195e5b4129d1c7ccb698a.php @@ -0,0 +1,8 @@ +<?php +//000031536000 + exit();?> +a:98:{s:8:"mallName";s:9:"全亮共";s:12:"seoMallTitle";s:9:"全亮共";s:11:"seoMallDesc";s:9:"全亮共";s:15:"seoMallKeywords";s:15:"全亮共商城";s:12:"serviceEmail";s:11:"a@ect99.com";s:10:"wstVersion";s:12:"2.0.2_180129";s:6:"wstMd5";s:32:"29fe530e71d0207d87c68a0ebb5c4688";s:18:"wstMobileImgSuffix";s:2:"_m";s:13:"isGoodsVerify";s:1:"1";s:15:"visitStatistics";s:0:"";s:8:"mailSmtp";s:18:"smtp.mxhichina.com";s:8:"mailPort";s:2:"25";s:8:"mailAuth";s:1:"1";s:11:"mailAddress";s:16:"hyh@heyuanhui.cn";s:12:"mailUserName";s:16:"hyh@heyuanhui.cn";s:12:"mailPassword";s:10:"Hsf4673995";s:13:"mailSendTitle";s:15:"合源惠商城";s:8:"smsLimit";s:2:"10";s:11:"mallLicense";s:32:"a6a9bd2a62770c2484622aaf94109a59";s:8:"mallLogo";s:43:"upload/sysconfigs/2017-09/59af629c60a10.png";s:9:"goodsLogo";s:43:"upload/sysconfigs/2018-01/5a504a84b3b0f.png";s:10:"mallFooter";s:69:"CROPYRIGHT 2017-2020 版权所有 ,备案号:鲁ICP备17015055号-1";s:10:"serviceTel";s:12:"0546-8788107";s:9:"serviceQQ";s:0:"";s:14:"hotWordsSearch";s:20:"女装,男裤,苹果";s:8:"smsVerfy";s:1:"1";s:7:"smsOpen";s:1:"1";s:18:"registerLimitWords";s:12:"admin,system";s:20:"settlementStartMoney";s:0:"";s:14:"isOpenScorePay";s:1:"0";s:12:"isOrderScore";s:1:"0";s:16:"isAppraisesScore";s:0:"";s:14:"scoreCashRatio";s:0:"";s:15:"autoReceiveDays";s:1:"7";s:16:"autoAppraiseDays";s:1:"7";s:12:"poundageRate";s:0:"";s:13:"isOpenQQLogin";s:0:"";s:7:"qqAppId";s:0:"";s:8:"qqAppKey";s:0:"";s:13:"isOpenWxLogin";s:0:"";s:7:"wxAppId";s:0:"";s:8:"wxAppKey";s:0:"";s:8:"shopLogo";s:43:"upload/sysconfigs/2017-09/59aa1692acbd0.png";s:8:"userLogo";s:43:"upload/sysconfigs/2016-10/5804800d5841e.png";s:15:"defaultProvince";s:0:"";s:13:"watermarkWord";s:0:"";s:13:"watermarkSize";s:0:"";s:14:"watermarkColor";s:0:"";s:13:"watermarkFile";s:0:"";s:17:"watermarkPosition";s:1:"0";s:16:"watermarkOpacity";s:2:"50";s:12:"watermarkTtf";s:0:"";s:10:"mallSlogan";s:15:"全亮共商城";s:19:"adsGoodsWordsSearch";s:21:"请输入商品名称";s:18:"adsShopWordsSearch";s:25:"数码产品,餐饮美食";s:19:"autoCancelNoPayDays";s:2:"24";s:13:"statementType";s:1:"0";s:10:"limitWords";s:11:"傻B,傻逼";s:12:"moneyToScore";s:3:"0.2";s:12:"scoreToMoney";s:1:"1";s:14:"appraisesScore";s:1:"5";s:9:"wxenabled";s:1:"0";s:17:"drawCashUserLimit";s:2:"10";s:17:"drawCashShopLimit";s:2:"10";s:13:"seoMallSwitch";s:1:"1";s:17:"seoMallSwitchDesc";s:18:"商城暂时关闭";s:9:"signScore";s:89:"5,10,15,20,25,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,";s:15:"signScoreSwitch";s:1:"0";s:9:"wxAppCode";s:0:"";s:9:"wxAppLogo";s:0:"";s:16:"wxSubmitOrderTip";s:1:"0";s:13:"wxPayOrderTip";s:1:"0";s:16:"wxCancelOrderTip";s:1:"0";s:16:"wxRejectOrderTip";s:1:"0";s:16:"wxRefundOrderTip";s:1:"0";s:19:"wxComplaintOrderTip";s:1:"0";s:14:"wxCashDrawsTip";s:1:"0";s:19:"submitOrderTipUsers";s:0:"";s:16:"payOrderTipUsers";s:0:"";s:19:"cancelOrderTipUsers";s:0:"";s:19:"rejectOrderTipUsers";s:0:"";s:19:"refundOrderTipUsers";s:0:"";s:22:"complaintOrderTipUsers";s:0:"";s:17:"cashDrawsTipUsers";s:0:"";s:17:"smsSubmitOrderTip";s:1:"0";s:14:"smsPayOrderTip";s:1:"0";s:17:"smsCancelOrderTip";s:1:"0";s:17:"smsRejectOrderTip";s:1:"0";s:17:"smsRefundOrderTip";s:1:"0";s:20:"smsComplaintOrderTip";s:1:"0";s:15:"smsCashDrawsTip";s:1:"0";s:13:"pwdPrivateKey";s:255:"-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCbak4tYvmaxhVyMucxax/tgre8JuGgvBOKJCIp/S7qbdFRpvNW ++njYR97DK8Rsf2UrYPDoqI8PsjSwJJgqEf2OEzNOBlVfQRbWzEX8DtWEGRpiJHtL +p8CfYqRi6ytdD+W13XAfst6OMVYgzotqHKgcpDMfgdmjqy8QUfv5+z/TrwIDAQAB +AoGANs95/MXAM9aSL7FGGgamvvPv";s:10:"isCryptPwd";s:0:"";s:13:"pwdModulusKey";s:255:"9B6A4E2D62F99AC6157232E7316B1FED82B7BC26E1A0BC138A242229FD2EEA6DD151A6F356FA78D847DEC32BC46C7F652B60F0E8A88F0FB234B024982A11FD8E13334E06555F4116D6CC45FC0ED584191A62247B4BA7C09F62A462EB2B5D0FE5B5DD701FB2DE8E315620CE8B6A1CA81CA4331F81D9A3AB2F1051FBF9FB3FD3A";s:12:"referrerOpen";s:1:"1";s:12:"wsthomeStyle";s:7:"default";s:14:"wsthomeStyleId";i:1;s:10:"wstUploads";a:21:{i:0;s:9:"appraises";i:1;s:6:"adspic";i:2;s:6:"brands";i:3;s:10:"sysconfigs";i:4;s:4:"temp";i:5;s:6:"staffs";i:6;s:5:"image";i:7;s:11:"friendlinks";i:8;s:9:"userranks";i:9;s:5:"users";i:10;s:7:"accreds";i:11;s:5:"shops";i:12;s:5:"goods";i:13;s:11:"shopconfigs";i:14;s:9:"complains";i:15;s:9:"goodscats";i:16;s:8:"articles";i:17;s:6:"wechat";i:18;s:10:"informsImg";i:19;s:8:"shopcats";i:20;s:20:"shopdecorationblocks";}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/0e/e8f29131d38fedb2e755d3d3209751.php b/runtime/cache/WSTMART_/0e/e8f29131d38fedb2e755d3d3209751.php new file mode 100644 index 0000000..2624a98 --- /dev/null +++ b/runtime/cache/WSTMART_/0e/e8f29131d38fedb2e755d3d3209751.php @@ -0,0 +1,4 @@ +<?php +//000000003600 + exit();?> +a:5:{s:5:"Total";i:245;s:7:"PerPage";i:10;s:11:"CurrentPage";i:1;s:9:"TotalPage";i:25;s:4:"Rows";a:10:{i:0;a:6:{s:7:"goodsId";i:315;s:9:"goodsName";s:18:"脉克能量鞋垫";s:8:"goodsImg";s:37:"upload/test/2019-08/1567070704524.jpg";s:9:"shopPrice";s:6:"600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:1;a:6:{s:7:"goodsId";i:138;s:9:"goodsName";s:18:"能量酵素果冻";s:8:"goodsImg";s:37:"upload/test/2019-06/1560169121970.jpg";s:9:"shopPrice";s:4:"6.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:2;a:6:{s:7:"goodsId";i:135;s:9:"goodsName";s:21:"能量宝石小火锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139634080.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:3;a:6:{s:7:"goodsId";i:134;s:9:"goodsName";s:18:"能量宝石煎锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139485542.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:4;a:6:{s:7:"goodsId";i:201;s:9:"goodsName";s:15:"贝壳粉纯浆";s:8:"goodsImg";s:37:"upload/test/2019-07/1563089001697.jpg";s:9:"shopPrice";s:7:"1600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:45;}i:5;a:6:{s:7:"goodsId";i:187;s:9:"goodsName";s:15:"五雷掌拍打";s:8:"goodsImg";s:37:"upload/test/2019-07/1562124700330.jpg";s:9:"shopPrice";s:6:"500.00";s:7:"saleNum";i:4;s:12:"discountRate";i:40;}i:6;a:6:{s:7:"goodsId";i:183;s:9:"goodsName";s:39:"万多水晶冰川晚收甜白葡萄酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759953897.jpg";s:9:"shopPrice";s:5:"98.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:7;a:6:{s:7:"goodsId";i:182;s:9:"goodsName";s:18:"气泡酒炫彩酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759486258.jpg";s:9:"shopPrice";s:6:"108.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:8;a:6:{s:7:"goodsId";i:181;s:9:"goodsName";s:32:"2017蜂鸟珍藏 赤霞珠干红";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758962936.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:9;a:6:{s:7:"goodsId";i:180;s:9:"goodsName";s:22:"思念干红 、干白";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758306230.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/18/1bc27ded94e4960032e41168ee9ad4.php b/runtime/cache/WSTMART_/18/1bc27ded94e4960032e41168ee9ad4.php new file mode 100644 index 0000000..7684458 --- /dev/null +++ b/runtime/cache/WSTMART_/18/1bc27ded94e4960032e41168ee9ad4.php @@ -0,0 +1,4 @@ +<?php +//000000000060 + exit();?> +a:5:{s:5:"Total";i:30;s:7:"PerPage";i:10;s:11:"CurrentPage";i:1;s:9:"TotalPage";i:3;s:4:"Rows";a:10:{i:0;a:6:{s:6:"shopId";i:10;s:7:"shopImg";s:37:"upload/test/2019-05/1558670880210.jpg";s:8:"shopName";s:41:"东方庶食&amp;301国际部健康查体";s:9:"shopLevel";i:0;s:8:"distance";d:1543537;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1559635827663.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"100.00";s:7:"goodsId";i:119;s:8:"saleTime";s:19:"2019-07-21 13:40:21";s:12:"discountRate";i:11;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559000217217.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"66.00";s:7:"goodsId";i:58;s:8:"saleTime";s:19:"2019-05-28 21:54:19";s:12:"discountRate";i:40;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559001576148.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"11.33";s:7:"goodsId";i:60;s:8:"saleTime";s:19:"2019-05-28 21:54:51";s:12:"discountRate";i:40;}}}i:1;a:6:{s:6:"shopId";i:11;s:7:"shopImg";s:37:"upload/test/2019-08/1565598343294.jpg";s:8:"shopName";s:18:"菁洲百货超市";s:9:"shopLevel";i:0;s:8:"distance";d:1542732;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-08/1566550946398.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"10.00";s:7:"goodsId";i:311;s:8:"saleTime";s:19:"2019-08-28 20:11:48";s:12:"discountRate";i:25;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-08/1567179299396.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:4:"1.00";s:7:"goodsId";i:324;s:8:"saleTime";s:19:"2019-08-30 23:36:07";s:12:"discountRate";i:20;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559177890199.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"12.00";s:7:"goodsId";i:63;s:8:"saleTime";s:19:"2019-06-08 19:52:08";s:12:"discountRate";i:20;}}}i:2;a:6:{s:6:"shopId";i:12;s:7:"shopImg";s:37:"upload/test/2019-05/1559267256985.jpg";s:8:"shopName";s:8:"SO造型";s:9:"shopLevel";i:0;s:8:"distance";d:1543111;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1558943406904.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"30.00";s:7:"goodsId";i:40;s:8:"saleTime";s:19:"2019-06-20 20:24:15";s:12:"discountRate";i:33;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559046958823.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"30.00";s:7:"goodsId";i:42;s:8:"saleTime";s:19:"2019-06-20 20:23:28";s:12:"discountRate";i:33;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559046643354.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"398.00";s:7:"goodsId";i:47;s:8:"saleTime";s:19:"2019-06-20 20:13:45";s:12:"discountRate";i:20;}}}i:3;a:6:{s:6:"shopId";i:13;s:7:"shopImg";s:37:"upload/test/2019-05/1559008250096.jpg";s:8:"shopName";s:9:"易秀阁";s:9:"shopLevel";i:0;s:8:"distance";d:1542968;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-07/1562238966156.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"120.00";s:7:"goodsId";i:189;s:8:"saleTime";s:19:"2019-07-04 19:32:06";s:12:"discountRate";i:12;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559008720287.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"500.00";s:7:"goodsId";i:61;s:8:"saleTime";s:19:"2019-05-28 10:20:09";s:12:"discountRate";i:20;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1559360089049.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:7:"1800.00";s:7:"goodsId";i:101;s:8:"saleTime";s:19:"2019-06-01 12:30:31";s:12:"discountRate";i:40;}}}i:4;a:6:{s:6:"shopId";i:14;s:7:"shopImg";s:37:"upload/test/2019-05/1559049003967.jpg";s:8:"shopName";s:39:"长城人寿公司日照中心支公司";s:9:"shopLevel";i:0;s:8:"distance";d:1543490;s:5:"goods";a:1:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559174687627.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"100.00";s:7:"goodsId";i:72;s:8:"saleTime";s:19:"2019-07-26 10:35:24";s:12:"discountRate";i:16;}}}i:5;a:6:{s:6:"shopId";i:15;s:7:"shopImg";s:37:"upload/test/2019-05/1559210520011.jpg";s:8:"shopName";s:35:"无限极~李锦记~红心火龙果";s:9:"shopLevel";i:0;s:8:"distance";d:1542246;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-08/1567008567488.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"20.00";s:7:"goodsId";i:314;s:8:"saleTime";s:19:"2019-08-29 00:09:42";s:12:"discountRate";i:30;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559274251828.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:4:"5.00";s:7:"goodsId";i:88;s:8:"saleTime";s:19:"2019-06-01 10:51:35";s:12:"discountRate";i:25;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1559352414570.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"21.00";s:7:"goodsId";i:89;s:8:"saleTime";s:19:"2019-06-01 10:40:38";s:12:"discountRate";i:25;}}}i:6;a:6:{s:6:"shopId";i:16;s:7:"shopImg";s:37:"upload/test/2019-05/1559128755423.jpg";s:8:"shopName";s:12:"老兵酒店";s:9:"shopLevel";i:0;s:8:"distance";d:1542298;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560134512048.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"100.00";s:7:"goodsId";i:124;s:8:"saleTime";s:19:"2019-06-11 20:34:42";s:12:"discountRate";i:30;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1559998224962.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"16.00";s:7:"goodsId";i:126;s:8:"saleTime";s:19:"2019-06-08 20:51:56";s:12:"discountRate";i:30;}i:2;a:5:{s:8:"goodsImg";s:77:"upload/test/2019-06/1559375849299.jpeg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"58.00";s:7:"goodsId";i:112;s:8:"saleTime";s:19:"2019-06-01 15:58:38";s:12:"discountRate";i:30;}}}i:7;a:6:{s:6:"shopId";i:17;s:7:"shopImg";s:37:"upload/test/2019-05/1559267799117.jpg";s:8:"shopName";s:21:"灸足堂健康服务";s:9:"shopLevel";i:0;s:8:"distance";d:1542791;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1561601913219.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"50.00";s:7:"goodsId";i:177;s:8:"saleTime";s:19:"2019-06-29 10:29:12";s:12:"discountRate";i:25;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559267313281.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"120.00";s:7:"goodsId";i:86;s:8:"saleTime";s:19:"2019-05-31 09:50:13";s:12:"discountRate";i:25;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-05/1559203142850.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:7:"1000.00";s:7:"goodsId";i:85;s:8:"saleTime";s:19:"2019-05-31 09:50:37";s:12:"discountRate";i:25;}}}i:8;a:6:{s:6:"shopId";i:18;s:7:"shopImg";s:37:"upload/test/2019-06/1559448219867.jpg";s:8:"shopName";s:9:"能量家";s:9:"shopLevel";i:0;s:8:"distance";d:1543041;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560140382816.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"360.00";s:7:"goodsId";i:137;s:8:"saleTime";s:19:"2019-08-29 21:35:14";s:12:"discountRate";i:22;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1559567418034.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:7:"3901.00";s:7:"goodsId";i:117;s:8:"saleTime";s:19:"2019-08-29 21:37:41";s:12:"discountRate";i:40;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560136602931.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:7:"3901.00";s:7:"goodsId";i:132;s:8:"saleTime";s:19:"2019-08-29 21:37:17";s:12:"discountRate";i:40;}}}i:9;a:6:{s:6:"shopId";i:19;s:7:"shopImg";s:37:"upload/test/2019-06/1560997056652.jpg";s:8:"shopName";s:45:"日照市华奥云乾汽车服务有限公司";s:9:"shopLevel";i:0;s:8:"distance";d:1540592;s:5:"goods";a:3:{i:0;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560996040636.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:5:"10.00";s:7:"goodsId";i:121;s:8:"saleTime";s:19:"2019-06-20 10:20:27";s:12:"discountRate";i:25;}i:1;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560995797607.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"299.00";s:7:"goodsId";i:120;s:8:"saleTime";s:19:"2019-06-20 10:20:10";s:12:"discountRate";i:20;}i:2;a:5:{s:8:"goodsImg";s:76:"upload/test/2019-06/1560997364365.jpg?x-oss-process=image/resize,h_250,w_250";s:9:"shopPrice";s:6:"120.00";s:7:"goodsId";i:162;s:8:"saleTime";s:19:"2019-06-20 10:27:13";s:12:"discountRate";i:20;}}}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/1d/a213c09e72730077c5b4b87fe2d885.php b/runtime/cache/WSTMART_/1d/a213c09e72730077c5b4b87fe2d885.php new file mode 100644 index 0000000..9c83aed --- /dev/null +++ b/runtime/cache/WSTMART_/1d/a213c09e72730077c5b4b87fe2d885.php @@ -0,0 +1,4 @@ +<?php +//000000003600 + exit();?> +a:5:{s:5:"Total";i:217;s:7:"PerPage";i:10;s:11:"CurrentPage";i:1;s:9:"TotalPage";i:22;s:4:"Rows";a:10:{i:0;a:6:{s:7:"goodsId";i:315;s:9:"goodsName";s:18:"脉克能量鞋垫";s:8:"goodsImg";s:37:"upload/test/2019-08/1567070704524.jpg";s:9:"shopPrice";s:6:"600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:1;a:6:{s:7:"goodsId";i:138;s:9:"goodsName";s:18:"能量酵素果冻";s:8:"goodsImg";s:37:"upload/test/2019-06/1560169121970.jpg";s:9:"shopPrice";s:4:"6.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:2;a:6:{s:7:"goodsId";i:135;s:9:"goodsName";s:21:"能量宝石小火锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139634080.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:3;a:6:{s:7:"goodsId";i:134;s:9:"goodsName";s:18:"能量宝石煎锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139485542.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:4;a:6:{s:7:"goodsId";i:201;s:9:"goodsName";s:15:"贝壳粉纯浆";s:8:"goodsImg";s:37:"upload/test/2019-07/1563089001697.jpg";s:9:"shopPrice";s:7:"1600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:45;}i:5;a:6:{s:7:"goodsId";i:187;s:9:"goodsName";s:15:"五雷掌拍打";s:8:"goodsImg";s:37:"upload/test/2019-07/1562124700330.jpg";s:9:"shopPrice";s:6:"500.00";s:7:"saleNum";i:4;s:12:"discountRate";i:40;}i:6;a:6:{s:7:"goodsId";i:183;s:9:"goodsName";s:39:"万多水晶冰川晚收甜白葡萄酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759953897.jpg";s:9:"shopPrice";s:5:"98.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:7;a:6:{s:7:"goodsId";i:182;s:9:"goodsName";s:18:"气泡酒炫彩酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759486258.jpg";s:9:"shopPrice";s:6:"108.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:8;a:6:{s:7:"goodsId";i:181;s:9:"goodsName";s:32:"2017蜂鸟珍藏 赤霞珠干红";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758962936.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:9;a:6:{s:7:"goodsId";i:180;s:9:"goodsName";s:22:"思念干红 、干白";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758306230.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/4e/819c837d54a6ed09abc77a8560a66f.php b/runtime/cache/WSTMART_/4e/819c837d54a6ed09abc77a8560a66f.php new file mode 100644 index 0000000..64d67e2 --- /dev/null +++ b/runtime/cache/WSTMART_/4e/819c837d54a6ed09abc77a8560a66f.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +a:9:{s:7:"sendSMS";a:1:{i:0;s:19:"\addons\dysms\Dysms";}s:21:"homeDocumentOrderView";a:1:{i:0;s:21:"\addons\kuaidi\Kuaidi";}s:23:"mobileDocumentOrderList";a:1:{i:0;s:21:"\addons\kuaidi\Kuaidi";}s:20:"afterQueryUserOrders";a:1:{i:0;s:21:"\addons\kuaidi\Kuaidi";}s:23:"wechatDocumentOrderList";a:1:{i:0;s:21:"\addons\kuaidi\Kuaidi";}s:12:"initCronHook";a:1:{i:0;s:17:"\addons\cron\Cron";}s:22:"adminDocumentOrderView";a:1:{i:0;s:21:"\addons\kuaidi\Kuaidi";}s:21:"orderCatsDoubleEleven";s:12:"Hyhcouponset";s:21:"orderCatsCouponEleven";s:12:"Hyhcouponset";} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/92/e7c8c4bac8acabec3689d23f76ec37.php b/runtime/cache/WSTMART_/92/e7c8c4bac8acabec3689d23f76ec37.php new file mode 100644 index 0000000..307360c --- /dev/null +++ b/runtime/cache/WSTMART_/92/e7c8c4bac8acabec3689d23f76ec37.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +s:5:"12.00"; \ No newline at end of file diff --git a/runtime/cache/WSTMART_/99/6be3a223e307f52c656772de57bd3f.php b/runtime/cache/WSTMART_/99/6be3a223e307f52c656772de57bd3f.php new file mode 100644 index 0000000..c82cd9c --- /dev/null +++ b/runtime/cache/WSTMART_/99/6be3a223e307f52c656772de57bd3f.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +a:2:{i:0;a:7:{s:4:"adId";i:2;s:6:"adName";s:7:"测试2";s:5:"adURL";s:0:"";s:10:"targetType";i:1;s:6:"adFile";s:78:"upload/adspic/2019-04/5cc5987c0808f.png?x-oss-process=image/resize,h_750,w_750";s:13:"positionWidth";i:700;s:14:"positionHeight";i:400;}i:1;a:7:{s:4:"adId";i:1;s:6:"adName";s:6:"测试";s:5:"adURL";s:0:"";s:10:"targetType";i:1;s:6:"adFile";s:78:"upload/adspic/2019-04/5cc599176c3ec.png?x-oss-process=image/resize,h_750,w_750";s:13:"positionWidth";i:700;s:14:"positionHeight";i:400;}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/a1/f318aa618e324295623730bbd11f3a.php b/runtime/cache/WSTMART_/a1/f318aa618e324295623730bbd11f3a.php new file mode 100644 index 0000000..0d7a224 --- /dev/null +++ b/runtime/cache/WSTMART_/a1/f318aa618e324295623730bbd11f3a.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +a:362:{s:17:"admin/menus/index";a:1:{s:7:"CDGL_00";a:5:{s:4:"code";s:7:"CDGL_00";s:3:"url";s:17:"admin/menus/index";s:4:"name";s:18:"查看菜单权限";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:21:"admin/menus/listquery";a:1:{s:7:"CDGL_00";a:5:{s:4:"code";s:7:"CDGL_00";s:3:"url";s:21:"admin/menus/listquery";s:4:"name";s:18:"查看菜单权限";s:8:"isParent";b:0;s:6:"menuId";i:3;}}s:15:"admin/menus/get";a:1:{s:7:"CDGL_00";a:5:{s:4:"code";s:7:"CDGL_00";s:3:"url";s:15:"admin/menus/get";s:4:"name";s:18:"查看菜单权限";s:8:"isParent";b:0;s:6:"menuId";i:3;}}s:26:"admin/privileges/listquery";a:1:{s:7:"CDGL_00";a:5:{s:4:"code";s:7:"CDGL_00";s:3:"url";s:26:"admin/privileges/listquery";s:4:"name";s:18:"查看菜单权限";s:8:"isParent";b:0;s:6:"menuId";i:3;}}s:20:"admin/privileges/get";a:1:{s:7:"CDGL_00";a:5:{s:4:"code";s:7:"CDGL_00";s:3:"url";s:20:"admin/privileges/get";s:4:"name";s:18:"查看菜单权限";s:8:"isParent";b:0;s:6:"menuId";i:3;}}s:15:"admin/menus/add";a:1:{s:7:"CDGL_01";a:5:{s:4:"code";s:7:"CDGL_01";s:3:"url";s:15:"admin/menus/add";s:4:"name";s:12:"新增菜单";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:16:"admin/menus/edit";a:1:{s:7:"CDGL_02";a:5:{s:4:"code";s:7:"CDGL_02";s:3:"url";s:16:"admin/menus/edit";s:4:"name";s:12:"编辑菜单";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:15:"admin/menus/del";a:1:{s:7:"CDGL_03";a:5:{s:4:"code";s:7:"CDGL_03";s:3:"url";s:15:"admin/menus/del";s:4:"name";s:12:"删除菜单";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:20:"admin/privileges/add";a:1:{s:7:"QXGL_01";a:5:{s:4:"code";s:7:"QXGL_01";s:3:"url";s:20:"admin/privileges/add";s:4:"name";s:12:"新增权限";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:21:"admin/privileges/edit";a:1:{s:7:"QXGL_02";a:5:{s:4:"code";s:7:"QXGL_02";s:3:"url";s:21:"admin/privileges/edit";s:4:"name";s:12:"编辑权限";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:20:"admin/privileges/del";a:1:{s:7:"QXGL_03";a:5:{s:4:"code";s:7:"QXGL_03";s:3:"url";s:20:"admin/privileges/del";s:4:"name";s:12:"删除菜单";s:8:"isParent";b:1;s:6:"menuId";i:3;}}s:17:"admin/roles/index";a:1:{s:7:"JSGL_00";a:5:{s:4:"code";s:7:"JSGL_00";s:3:"url";s:17:"admin/roles/index";s:4:"name";s:18:"查看角色管理";s:8:"isParent";b:1;s:6:"menuId";i:4;}}s:21:"admin/roles/pagequery";a:1:{s:7:"JSGL_00";a:5:{s:4:"code";s:7:"JSGL_00";s:3:"url";s:21:"admin/roles/pagequery";s:4:"name";s:18:"查看角色管理";s:8:"isParent";b:0;s:6:"menuId";i:4;}}s:15:"admin/roles/add";a:1:{s:7:"JSGL_01";a:5:{s:4:"code";s:7:"JSGL_01";s:3:"url";s:15:"admin/roles/add";s:4:"name";s:12:"新增角色";s:8:"isParent";b:1;s:6:"menuId";i:4;}}s:18:"admin/roles/toedit";a:2:{s:7:"JSGL_01";a:5:{s:4:"code";s:7:"JSGL_01";s:3:"url";s:18:"admin/roles/toedit";s:4:"name";s:12:"新增角色";s:8:"isParent";b:0;s:6:"menuId";i:4;}s:7:"JSGL_02";a:5:{s:4:"code";s:7:"JSGL_02";s:3:"url";s:18:"admin/roles/toedit";s:4:"name";s:12:"编辑角色";s:8:"isParent";b:0;s:6:"menuId";i:4;}}s:32:"admin/privileges/listquerybyrole";a:2:{s:7:"JSGL_01";a:5:{s:4:"code";s:7:"JSGL_01";s:3:"url";s:32:"admin/privileges/listquerybyrole";s:4:"name";s:12:"新增角色";s:8:"isParent";b:0;s:6:"menuId";i:4;}s:7:"JSGL_02";a:5:{s:4:"code";s:7:"JSGL_02";s:3:"url";s:32:"admin/privileges/listquerybyrole";s:4:"name";s:12:"编辑角色";s:8:"isParent";b:0;s:6:"menuId";i:4;}}s:16:"admin/roles/edit";a:1:{s:7:"JSGL_02";a:5:{s:4:"code";s:7:"JSGL_02";s:3:"url";s:16:"admin/roles/edit";s:4:"name";s:12:"编辑角色";s:8:"isParent";b:1;s:6:"menuId";i:4;}}s:15:"admin/roles/del";a:1:{s:7:"JSGL_03";a:5:{s:4:"code";s:7:"JSGL_03";s:3:"url";s:15:"admin/roles/del";s:4:"name";s:12:"删除角色";s:8:"isParent";b:1;s:6:"menuId";i:4;}}s:1:"#";a:2:{s:6:"SY_001";a:5:{s:4:"code";s:6:"SY_001";s:3:"url";s:1:"#";s:4:"name";s:12:"查看平台";s:8:"isParent";b:1;s:6:"menuId";i:1;}s:7:"DDGL_00";a:5:{s:4:"code";s:7:"DDGL_00";s:3:"url";s:1:"#";s:4:"name";s:12:"查看商城";s:8:"isParent";b:1;s:6:"menuId";i:35;}}s:18:"admin/staffs/index";a:1:{s:7:"ZYGL_00";a:5:{s:4:"code";s:7:"ZYGL_00";s:3:"url";s:18:"admin/staffs/index";s:4:"name";s:18:"查看职员管理";s:8:"isParent";b:1;s:6:"menuId";i:5;}}s:22:"admin/staffs/pagequery";a:1:{s:7:"ZYGL_00";a:5:{s:4:"code";s:7:"ZYGL_00";s:3:"url";s:22:"admin/staffs/pagequery";s:4:"name";s:18:"查看职员管理";s:8:"isParent";b:0;s:6:"menuId";i:5;}}s:16:"admin/staffs/add";a:1:{s:7:"ZYGL_01";a:5:{s:4:"code";s:7:"ZYGL_01";s:3:"url";s:16:"admin/staffs/add";s:4:"name";s:12:"新增职员";s:8:"isParent";b:1;s:6:"menuId";i:5;}}s:18:"admin/staffs/toadd";a:1:{s:7:"ZYGL_01";a:5:{s:4:"code";s:7:"ZYGL_01";s:3:"url";s:18:"admin/staffs/toadd";s:4:"name";s:12:"新增职员";s:8:"isParent";b:0;s:6:"menuId";i:5;}}s:17:"admin/staffs/edit";a:1:{s:7:"ZYGL_02";a:5:{s:4:"code";s:7:"ZYGL_02";s:3:"url";s:17:"admin/staffs/edit";s:4:"name";s:12:"编辑职员";s:8:"isParent";b:1;s:6:"menuId";i:5;}}s:19:"admin/staffs/toedit";a:1:{s:7:"ZYGL_02";a:5:{s:4:"code";s:7:"ZYGL_02";s:3:"url";s:19:"admin/staffs/toedit";s:4:"name";s:12:"编辑职员";s:8:"isParent";b:0;s:6:"menuId";i:5;}}s:21:"admin/staffs/editpass";a:1:{s:7:"ZYGL_02";a:5:{s:4:"code";s:7:"ZYGL_02";s:3:"url";s:21:"admin/staffs/editpass";s:4:"name";s:12:"编辑职员";s:8:"isParent";b:0;s:6:"menuId";i:5;}}s:16:"admin/staffs/del";a:1:{s:7:"ZYGL_03";a:5:{s:4:"code";s:7:"ZYGL_03";s:3:"url";s:16:"admin/staffs/del";s:4:"name";s:12:"删除职员";s:8:"isParent";b:1;s:6:"menuId";i:5;}}s:16:"admin/navs/index";a:1:{s:7:"DHGL_00";a:5:{s:4:"code";s:7:"DHGL_00";s:3:"url";s:16:"admin/navs/index";s:4:"name";s:18:"查看导航管理";s:8:"isParent";b:1;s:6:"menuId";i:10;}}s:20:"admin/navs/pagequery";a:1:{s:7:"DHGL_00";a:5:{s:4:"code";s:7:"DHGL_00";s:3:"url";s:20:"admin/navs/pagequery";s:4:"name";s:18:"查看导航管理";s:8:"isParent";b:0;s:6:"menuId";i:10;}}s:13:"admin/nav/add";a:1:{s:7:"DHGL_01";a:5:{s:4:"code";s:7:"DHGL_01";s:3:"url";s:13:"admin/nav/add";s:4:"name";s:12:"新增导航";s:8:"isParent";b:1;s:6:"menuId";i:10;}}s:16:"admin/nav/toedit";a:2:{s:7:"DHGL_01";a:5:{s:4:"code";s:7:"DHGL_01";s:3:"url";s:16:"admin/nav/toedit";s:4:"name";s:12:"新增导航";s:8:"isParent";b:0;s:6:"menuId";i:10;}s:7:"DHGL_02";a:5:{s:4:"code";s:7:"DHGL_02";s:3:"url";s:16:"admin/nav/toedit";s:4:"name";s:12:"修改导航";s:8:"isParent";b:0;s:6:"menuId";i:10;}}s:15:"admin/ads/index";a:1:{s:7:"GGGL_00";a:5:{s:4:"code";s:7:"GGGL_00";s:3:"url";s:15:"admin/ads/index";s:4:"name";s:18:"查看广告管理";s:8:"isParent";b:1;s:6:"menuId";i:11;}}s:19:"admin/ads/pagequery";a:1:{s:7:"GGGL_00";a:5:{s:4:"code";s:7:"GGGL_00";s:3:"url";s:19:"admin/ads/pagequery";s:4:"name";s:18:"查看广告管理";s:8:"isParent";b:0;s:6:"menuId";i:11;}}s:20:"admin/payments/index";a:1:{s:7:"ZFGL_00";a:5:{s:4:"code";s:7:"ZFGL_00";s:3:"url";s:20:"admin/payments/index";s:4:"name";s:18:"查看支付管理";s:8:"isParent";b:1;s:6:"menuId";i:12;}}s:24:"admin/payments/pagequery";a:1:{s:7:"ZFGL_00";a:5:{s:4:"code";s:7:"ZFGL_00";s:3:"url";s:24:"admin/payments/pagequery";s:4:"name";s:18:"查看支付管理";s:8:"isParent";b:0;s:6:"menuId";i:12;}}s:17:"admin/banks/index";a:1:{s:7:"YHGL_00";a:5:{s:4:"code";s:7:"YHGL_00";s:3:"url";s:17:"admin/banks/index";s:4:"name";s:18:"查看银行管理";s:8:"isParent";b:1;s:6:"menuId";i:13;}}s:21:"admin/banks/pagequery";a:1:{s:7:"YHGL_00";a:5:{s:4:"code";s:7:"YHGL_00";s:3:"url";s:21:"admin/banks/pagequery";s:4:"name";s:18:"查看银行管理";s:8:"isParent";b:0;s:6:"menuId";i:13;}}s:23:"admin/friendlinks/index";a:1:{s:7:"YQGL_00";a:5:{s:4:"code";s:7:"YQGL_00";s:3:"url";s:23:"admin/friendlinks/index";s:4:"name";s:18:"查看友情链接";s:8:"isParent";b:1;s:6:"menuId";i:14;}}s:27:"admin/friendlinks/pagequery";a:1:{s:7:"YQGL_00";a:5:{s:4:"code";s:7:"YQGL_00";s:3:"url";s:27:"admin/friendlinks/pagequery";s:4:"name";s:18:"查看友情链接";s:8:"isParent";b:0;s:6:"menuId";i:14;}}s:14:"admin/nav/edit";a:1:{s:7:"DHGL_02";a:5:{s:4:"code";s:7:"DHGL_02";s:3:"url";s:14:"admin/nav/edit";s:4:"name";s:12:"修改导航";s:8:"isParent";b:1;s:6:"menuId";i:10;}}s:21:"admin/nav/editiisshow";a:1:{s:7:"DHGL_02";a:5:{s:4:"code";s:7:"DHGL_02";s:3:"url";s:21:"admin/nav/editiisshow";s:4:"name";s:12:"修改导航";s:8:"isParent";b:0;s:6:"menuId";i:10;}}s:13:"admin/nav/del";a:1:{s:7:"DHGL_03";a:5:{s:4:"code";s:7:"DHGL_03";s:3:"url";s:13:"admin/nav/del";s:4:"name";s:12:"删除导航";s:8:"isParent";b:1;s:6:"menuId";i:10;}}s:13:"admin/ads/add";a:1:{s:7:"GGGL_01";a:5:{s:4:"code";s:7:"GGGL_01";s:3:"url";s:13:"admin/ads/add";s:4:"name";s:12:"新增广告";s:8:"isParent";b:1;s:6:"menuId";i:11;}}s:16:"admin/ads/toedit";a:2:{s:7:"GGGL_01";a:5:{s:4:"code";s:7:"GGGL_01";s:3:"url";s:16:"admin/ads/toedit";s:4:"name";s:12:"新增广告";s:8:"isParent";b:0;s:6:"menuId";i:11;}s:7:"GGGL_02";a:5:{s:4:"code";s:7:"GGGL_02";s:3:"url";s:16:"admin/ads/toedit";s:4:"name";s:12:"修改广告";s:8:"isParent";b:0;s:6:"menuId";i:11;}}s:14:"admin/ads/edit";a:1:{s:7:"GGGL_02";a:5:{s:4:"code";s:7:"GGGL_02";s:3:"url";s:14:"admin/ads/edit";s:4:"name";s:12:"修改广告";s:8:"isParent";b:1;s:6:"menuId";i:11;}}s:20:"admin/ads/changesort";a:1:{s:7:"GGGL_02";a:5:{s:4:"code";s:7:"GGGL_02";s:3:"url";s:20:"admin/ads/changesort";s:4:"name";s:12:"修改广告";s:8:"isParent";b:0;s:6:"menuId";i:11;}}s:13:"admin/ads/del";a:1:{s:7:"GGGL_03";a:5:{s:4:"code";s:7:"GGGL_03";s:3:"url";s:13:"admin/ads/del";s:4:"name";s:12:"删除广告";s:8:"isParent";b:1;s:6:"menuId";i:11;}}s:19:"admin/payments/edit";a:1:{s:7:"ZFGL_02";a:5:{s:4:"code";s:7:"ZFGL_02";s:3:"url";s:19:"admin/payments/edit";s:4:"name";s:12:"编辑支付";s:8:"isParent";b:1;s:6:"menuId";i:12;}}s:21:"admin/payments/toedit";a:1:{s:7:"ZFGL_02";a:5:{s:4:"code";s:7:"ZFGL_02";s:3:"url";s:21:"admin/payments/toedit";s:4:"name";s:12:"编辑支付";s:8:"isParent";b:0;s:6:"menuId";i:12;}}s:18:"admin/payments/del";a:1:{s:7:"ZFGL_03";a:5:{s:4:"code";s:7:"ZFGL_03";s:3:"url";s:18:"admin/payments/del";s:4:"name";s:12:"卸载支付";s:8:"isParent";b:1;s:6:"menuId";i:12;}}s:15:"admin/banks/add";a:1:{s:7:"YHGL_01";a:5:{s:4:"code";s:7:"YHGL_01";s:3:"url";s:15:"admin/banks/add";s:4:"name";s:12:"新增银行";s:8:"isParent";b:1;s:6:"menuId";i:13;}}s:16:"admin/banks/edit";a:1:{s:7:"YHGL_02";a:5:{s:4:"code";s:7:"YHGL_02";s:3:"url";s:16:"admin/banks/edit";s:4:"name";s:12:"修改银行";s:8:"isParent";b:1;s:6:"menuId";i:13;}}s:15:"admin/banks/del";a:1:{s:7:"YHGL_03";a:5:{s:4:"code";s:7:"YHGL_03";s:3:"url";s:15:"admin/banks/del";s:4:"name";s:12:"删除银行";s:8:"isParent";b:1;s:6:"menuId";i:13;}}s:21:"admin/friendlinks/add";a:1:{s:7:"YQGL_01";a:5:{s:4:"code";s:7:"YQGL_01";s:3:"url";s:21:"admin/friendlinks/add";s:4:"name";s:18:"新增友情链接";s:8:"isParent";b:1;s:6:"menuId";i:14;}}s:24:"admin/friendlinks/toedit";a:2:{s:7:"YQGL_01";a:5:{s:4:"code";s:7:"YQGL_01";s:3:"url";s:24:"admin/friendlinks/toedit";s:4:"name";s:18:"新增友情链接";s:8:"isParent";b:0;s:6:"menuId";i:14;}s:7:"YQGL_02";a:5:{s:4:"code";s:7:"YQGL_02";s:3:"url";s:24:"admin/friendlinks/toedit";s:4:"name";s:18:"修改友情链接";s:8:"isParent";b:0;s:6:"menuId";i:14;}}s:22:"admin/friendlinks/edit";a:1:{s:7:"YQGL_02";a:5:{s:4:"code";s:7:"YQGL_02";s:3:"url";s:22:"admin/friendlinks/edit";s:4:"name";s:18:"修改友情链接";s:8:"isParent";b:1;s:6:"menuId";i:14;}}s:21:"admin/friendlinks/del";a:1:{s:7:"YQGL_03";a:5:{s:4:"code";s:7:"YQGL_03";s:3:"url";s:21:"admin/friendlinks/del";s:4:"name";s:18:"删除友情链接";s:8:"isParent";b:1;s:6:"menuId";i:14;}}s:17:"admin/areas/index";a:1:{s:7:"DQGL_00";a:5:{s:4:"code";s:7:"DQGL_00";s:3:"url";s:17:"admin/areas/index";s:4:"name";s:18:"查看地区管理";s:8:"isParent";b:1;s:6:"menuId";i:16;}}s:21:"admin/areas/pagequery";a:1:{s:7:"DQGL_00";a:5:{s:4:"code";s:7:"DQGL_00";s:3:"url";s:21:"admin/areas/pagequery";s:4:"name";s:18:"查看地区管理";s:8:"isParent";b:0;s:6:"menuId";i:16;}}s:15:"admin/areas/add";a:1:{s:7:"DQGL_01";a:5:{s:4:"code";s:7:"DQGL_01";s:3:"url";s:15:"admin/areas/add";s:4:"name";s:12:"新增地区";s:8:"isParent";b:1;s:6:"menuId";i:16;}}s:16:"admin/areas/edit";a:1:{s:7:"DQGL_02";a:5:{s:4:"code";s:7:"DQGL_02";s:3:"url";s:16:"admin/areas/edit";s:4:"name";s:12:"编辑地区";s:8:"isParent";b:1;s:6:"menuId";i:16;}}s:23:"admin/areas/editiisshow";a:1:{s:7:"DQGL_02";a:5:{s:4:"code";s:7:"DQGL_02";s:3:"url";s:23:"admin/areas/editiisshow";s:4:"name";s:12:"编辑地区";s:8:"isParent";b:0;s:6:"menuId";i:16;}}s:15:"admin/areas/del";a:1:{s:7:"DQGL_03";a:5:{s:4:"code";s:7:"DQGL_03";s:3:"url";s:15:"admin/areas/del";s:4:"name";s:12:"删除地区";s:8:"isParent";b:1;s:6:"menuId";i:16;}}s:21:"admin/goodscats/index";a:1:{s:7:"SPFL_00";a:5:{s:4:"code";s:7:"SPFL_00";s:3:"url";s:21:"admin/goodscats/index";s:4:"name";s:18:"查看商品分类";s:8:"isParent";b:1;s:6:"menuId";i:24;}}s:25:"admin/goodscats/pagequery";a:1:{s:7:"SPFL_00";a:5:{s:4:"code";s:7:"SPFL_00";s:3:"url";s:25:"admin/goodscats/pagequery";s:4:"name";s:18:"查看商品分类";s:8:"isParent";b:0;s:6:"menuId";i:24;}}s:21:"admin/userranks/index";a:1:{s:7:"HYDJ_00";a:5:{s:4:"code";s:7:"HYDJ_00";s:3:"url";s:21:"admin/userranks/index";s:4:"name";s:18:"查看会员等级";s:8:"isParent";b:1;s:6:"menuId";i:19;}}s:25:"admin/userranks/pagequery";a:1:{s:7:"HYDJ_00";a:5:{s:4:"code";s:7:"HYDJ_00";s:3:"url";s:25:"admin/userranks/pagequery";s:4:"name";s:18:"查看会员等级";s:8:"isParent";b:0;s:6:"menuId";i:19;}}s:19:"admin/userranks/add";a:1:{s:7:"HYDJ_01";a:5:{s:4:"code";s:7:"HYDJ_01";s:3:"url";s:19:"admin/userranks/add";s:4:"name";s:18:"新增会员等级";s:8:"isParent";b:1;s:6:"menuId";i:19;}}s:22:"admin/userranks/toedit";a:2:{s:7:"HYDJ_01";a:5:{s:4:"code";s:7:"HYDJ_01";s:3:"url";s:22:"admin/userranks/toedit";s:4:"name";s:18:"新增会员等级";s:8:"isParent";b:0;s:6:"menuId";i:19;}s:7:"HYDJ_02";a:5:{s:4:"code";s:7:"HYDJ_02";s:3:"url";s:22:"admin/userranks/toedit";s:4:"name";s:18:"编辑会员等级";s:8:"isParent";b:0;s:6:"menuId";i:19;}}s:20:"admin/userranks/edit";a:1:{s:7:"HYDJ_02";a:5:{s:4:"code";s:7:"HYDJ_02";s:3:"url";s:20:"admin/userranks/edit";s:4:"name";s:18:"编辑会员等级";s:8:"isParent";b:1;s:6:"menuId";i:19;}}s:19:"admin/userranks/del";a:1:{s:7:"HYDJ_03";a:5:{s:4:"code";s:7:"HYDJ_03";s:3:"url";s:19:"admin/userranks/del";s:4:"name";s:18:"删除会员等级";s:8:"isParent";b:1;s:6:"menuId";i:19;}}s:17:"admin/users/index";a:1:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:17:"admin/users/index";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:1;s:6:"menuId";i:20;}}s:21:"admin/users/pagequery";a:2:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:21:"admin/users/pagequery";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}s:7:"ZHGL_00";a:5:{s:4:"code";s:7:"ZHGL_00";s:3:"url";s:21:"admin/users/pagequery";s:4:"name";s:18:"查看账号管理";s:8:"isParent";b:0;s:6:"menuId";i:21;}}s:27:"admin/logmoneys/tologmoneys";a:2:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:27:"admin/logmoneys/tologmoneys";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}s:7:"ZJGL_00";a:5:{s:4:"code";s:7:"ZJGL_00";s:3:"url";s:27:"admin/logmoneys/tologmoneys";s:4:"name";s:18:"查看资金管理";s:8:"isParent";b:0;s:6:"menuId";i:85;}}s:31:"admin/logmoneys/pagequerybyuser";a:2:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:31:"admin/logmoneys/pagequerybyuser";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}s:7:"ZJGL_00";a:5:{s:4:"code";s:7:"ZJGL_00";s:3:"url";s:31:"admin/logmoneys/pagequerybyuser";s:4:"name";s:18:"查看资金管理";s:8:"isParent";b:0;s:6:"menuId";i:85;}}s:31:"admin/logmoneys/pagequerybyshop";a:2:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:31:"admin/logmoneys/pagequerybyshop";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}s:7:"ZJGL_00";a:5:{s:4:"code";s:7:"ZJGL_00";s:3:"url";s:31:"admin/logmoneys/pagequerybyshop";s:4:"name";s:18:"查看资金管理";s:8:"isParent";b:0;s:6:"menuId";i:85;}}s:29:"admin/userscores/touserscores";a:1:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:29:"admin/userscores/touserscores";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:26:"admin/userscores/pagequery";a:1:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:26:"admin/userscores/pagequery";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:22:"admin/userscores/toadd";a:1:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:22:"admin/userscores/toadd";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:20:"admin/userscores/add";a:1:{s:7:"HYGL_00";a:5:{s:4:"code";s:7:"HYGL_00";s:3:"url";s:20:"admin/userscores/add";s:4:"name";s:18:"查看会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:15:"admin/users/add";a:1:{s:7:"HYGL_01";a:5:{s:4:"code";s:7:"HYGL_01";s:3:"url";s:15:"admin/users/add";s:4:"name";s:18:"新增会员管理";s:8:"isParent";b:1;s:6:"menuId";i:20;}}s:18:"admin/users/toedit";a:2:{s:7:"HYGL_01";a:5:{s:4:"code";s:7:"HYGL_01";s:3:"url";s:18:"admin/users/toedit";s:4:"name";s:18:"新增会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}s:7:"HYGL_02";a:5:{s:4:"code";s:7:"HYGL_02";s:3:"url";s:18:"admin/users/toedit";s:4:"name";s:18:"编辑会员管理";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:16:"admin/users/edit";a:1:{s:7:"HYGL_02";a:5:{s:4:"code";s:7:"HYGL_02";s:3:"url";s:16:"admin/users/edit";s:4:"name";s:18:"编辑会员管理";s:8:"isParent";b:1;s:6:"menuId";i:20;}}s:15:"admin/users/del";a:1:{s:7:"HYGL_03";a:5:{s:4:"code";s:7:"HYGL_03";s:3:"url";s:15:"admin/users/del";s:4:"name";s:18:"删除会员管理";s:8:"isParent";b:1;s:6:"menuId";i:20;}}s:19:"admin/goodscats/add";a:1:{s:7:"SPFL_01";a:5:{s:4:"code";s:7:"SPFL_01";s:3:"url";s:19:"admin/goodscats/add";s:4:"name";s:18:"新增商品分类";s:8:"isParent";b:1;s:6:"menuId";i:24;}}s:20:"admin/goodscats/edit";a:1:{s:7:"SPFL_02";a:5:{s:4:"code";s:7:"SPFL_02";s:3:"url";s:20:"admin/goodscats/edit";s:4:"name";s:18:"编辑商品分类";s:8:"isParent";b:1;s:6:"menuId";i:24;}}s:28:"admin/goodscats/editiisfloor";a:1:{s:7:"SPFL_02";a:5:{s:4:"code";s:7:"SPFL_02";s:3:"url";s:28:"admin/goodscats/editiisfloor";s:4:"name";s:18:"编辑商品分类";s:8:"isParent";b:0;s:6:"menuId";i:24;}}s:27:"admin/goodscats/editiisshow";a:1:{s:7:"SPFL_02";a:5:{s:4:"code";s:7:"SPFL_02";s:3:"url";s:27:"admin/goodscats/editiisshow";s:4:"name";s:18:"编辑商品分类";s:8:"isParent";b:0;s:6:"menuId";i:24;}}s:24:"admin/goodscats/editname";a:1:{s:7:"SPFL_02";a:5:{s:4:"code";s:7:"SPFL_02";s:3:"url";s:24:"admin/goodscats/editname";s:4:"name";s:18:"编辑商品分类";s:8:"isParent";b:0;s:6:"menuId";i:24;}}s:25:"admin/goodscats/editorder";a:1:{s:7:"SPFL_02";a:5:{s:4:"code";s:7:"SPFL_02";s:3:"url";s:25:"admin/goodscats/editorder";s:4:"name";s:18:"编辑商品分类";s:8:"isParent";b:0;s:6:"menuId";i:24;}}s:19:"admin/goodscats/del";a:1:{s:7:"SPFL_03";a:5:{s:4:"code";s:7:"SPFL_03";s:3:"url";s:19:"admin/goodscats/del";s:4:"name";s:18:"删除商品分类";s:8:"isParent";b:1;s:6:"menuId";i:24;}}s:18:"admin/brands/index";a:1:{s:7:"PPGL_00";a:5:{s:4:"code";s:7:"PPGL_00";s:3:"url";s:18:"admin/brands/index";s:4:"name";s:18:"查看品牌管理";s:8:"isParent";b:1;s:6:"menuId";i:25;}}s:22:"admin/brands/pagequery";a:1:{s:7:"PPGL_00";a:5:{s:4:"code";s:7:"PPGL_00";s:3:"url";s:22:"admin/brands/pagequery";s:4:"name";s:18:"查看品牌管理";s:8:"isParent";b:0;s:6:"menuId";i:25;}}s:16:"admin/brands/add";a:1:{s:7:"PPGL_01";a:5:{s:4:"code";s:7:"PPGL_01";s:3:"url";s:16:"admin/brands/add";s:4:"name";s:12:"新增品牌";s:8:"isParent";b:1;s:6:"menuId";i:25;}}s:19:"admin/brands/toedit";a:2:{s:7:"PPGL_01";a:5:{s:4:"code";s:7:"PPGL_01";s:3:"url";s:19:"admin/brands/toedit";s:4:"name";s:12:"新增品牌";s:8:"isParent";b:0;s:6:"menuId";i:25;}s:7:"PPGL_02";a:5:{s:4:"code";s:7:"PPGL_02";s:3:"url";s:19:"admin/brands/toedit";s:4:"name";s:12:"编辑品牌";s:8:"isParent";b:0;s:6:"menuId";i:25;}}s:17:"admin/brands/edit";a:1:{s:7:"PPGL_02";a:5:{s:4:"code";s:7:"PPGL_02";s:3:"url";s:17:"admin/brands/edit";s:4:"name";s:12:"编辑品牌";s:8:"isParent";b:1;s:6:"menuId";i:25;}}s:16:"admin/brands/del";a:1:{s:7:"PPGL_03";a:5:{s:4:"code";s:7:"PPGL_03";s:3:"url";s:16:"admin/brands/del";s:4:"name";s:12:"删除品牌";s:8:"isParent";b:1;s:6:"menuId";i:25;}}s:26:"admin/goodsappraises/index";a:1:{s:7:"PJGL_00";a:5:{s:4:"code";s:7:"PJGL_00";s:3:"url";s:26:"admin/goodsappraises/index";s:4:"name";s:18:"查看评价管理";s:8:"isParent";b:1;s:6:"menuId";i:34;}}s:30:"admin/goodsappraises/pagequery";a:1:{s:7:"PJGL_00";a:5:{s:4:"code";s:7:"PJGL_00";s:3:"url";s:30:"admin/goodsappraises/pagequery";s:4:"name";s:18:"查看评价管理";s:8:"isParent";b:0;s:6:"menuId";i:34;}}s:25:"admin/goodsappraises/edit";a:1:{s:7:"PJGL_02";a:5:{s:4:"code";s:7:"PJGL_02";s:3:"url";s:25:"admin/goodsappraises/edit";s:4:"name";s:12:"编辑评价";s:8:"isParent";b:1;s:6:"menuId";i:34;}}s:27:"admin/goodsappraises/toedit";a:1:{s:7:"PJGL_02";a:5:{s:4:"code";s:7:"PJGL_02";s:3:"url";s:27:"admin/goodsappraises/toedit";s:4:"name";s:12:"编辑评价";s:8:"isParent";b:0;s:6:"menuId";i:34;}}s:24:"admin/goodsappraises/del";a:1:{s:7:"PJGL_03";a:5:{s:4:"code";s:7:"PJGL_03";s:3:"url";s:24:"admin/goodsappraises/del";s:4:"name";s:12:"删除评价";s:8:"isParent";b:1;s:6:"menuId";i:34;}}s:26:"admin/logstafflogins/index";a:1:{s:7:"DLRZ_00";a:5:{s:4:"code";s:7:"DLRZ_00";s:3:"url";s:26:"admin/logstafflogins/index";s:4:"name";s:18:"查看登录日志";s:8:"isParent";b:1;s:6:"menuId";i:6;}}s:30:"admin/logstafflogins/pagequery";a:1:{s:7:"DLRZ_00";a:5:{s:4:"code";s:7:"DLRZ_00";s:3:"url";s:30:"admin/logstafflogins/pagequery";s:4:"name";s:18:"查看登录日志";s:8:"isParent";b:0;s:6:"menuId";i:6;}}s:23:"admin/logoperates/index";a:1:{s:7:"CZRZ_00";a:5:{s:4:"code";s:7:"CZRZ_00";s:3:"url";s:23:"admin/logoperates/index";s:4:"name";s:18:"查看操作日志";s:8:"isParent";b:1;s:6:"menuId";i:7;}}s:27:"admin/logoperates/pagequery";a:1:{s:7:"CZRZ_00";a:5:{s:4:"code";s:7:"CZRZ_00";s:3:"url";s:27:"admin/logoperates/pagequery";s:4:"name";s:18:"查看操作日志";s:8:"isParent";b:0;s:6:"menuId";i:7;}}s:24:"admin/logoperates/toview";a:1:{s:7:"CZRZ_00";a:5:{s:4:"code";s:7:"CZRZ_00";s:3:"url";s:24:"admin/logoperates/toview";s:4:"name";s:18:"查看操作日志";s:8:"isParent";b:0;s:6:"menuId";i:7;}}s:23:"admin/adpositions/index";a:1:{s:7:"GGWZ_00";a:5:{s:4:"code";s:7:"GGWZ_00";s:3:"url";s:23:"admin/adpositions/index";s:4:"name";s:18:"查看广告位置";s:8:"isParent";b:1;s:6:"menuId";i:42;}}s:27:"admin/adpositions/pagequery";a:1:{s:7:"GGWZ_00";a:5:{s:4:"code";s:7:"GGWZ_00";s:3:"url";s:27:"admin/adpositions/pagequery";s:4:"name";s:18:"查看广告位置";s:8:"isParent";b:0;s:6:"menuId";i:42;}}s:21:"admin/adpositions/add";a:1:{s:7:"GGWZ_01";a:5:{s:4:"code";s:7:"GGWZ_01";s:3:"url";s:21:"admin/adpositions/add";s:4:"name";s:18:"新增广告位置";s:8:"isParent";b:1;s:6:"menuId";i:42;}}s:24:"admin/adpositions/toedit";a:2:{s:7:"GGWZ_01";a:5:{s:4:"code";s:7:"GGWZ_01";s:3:"url";s:24:"admin/adpositions/toedit";s:4:"name";s:18:"新增广告位置";s:8:"isParent";b:0;s:6:"menuId";i:42;}s:7:"GGWZ_02";a:5:{s:4:"code";s:7:"GGWZ_02";s:3:"url";s:24:"admin/adpositions/toedit";s:4:"name";s:18:"编辑广告位置";s:8:"isParent";b:0;s:6:"menuId";i:42;}}s:22:"admin/adpositions/edit";a:1:{s:7:"GGWZ_02";a:5:{s:4:"code";s:7:"GGWZ_02";s:3:"url";s:22:"admin/adpositions/edit";s:4:"name";s:18:"编辑广告位置";s:8:"isParent";b:1;s:6:"menuId";i:42;}}s:21:"admin/adpositions/del";a:1:{s:7:"GGWZ_03";a:5:{s:4:"code";s:7:"GGWZ_03";s:3:"url";s:21:"admin/adpositions/del";s:4:"name";s:18:"删除广告位置";s:8:"isParent";b:1;s:6:"menuId";i:42;}}s:20:"admin/articles/index";a:1:{s:7:"WZGL_00";a:5:{s:4:"code";s:7:"WZGL_00";s:3:"url";s:20:"admin/articles/index";s:4:"name";s:18:"查看文章管理";s:8:"isParent";b:1;s:6:"menuId";i:31;}}s:24:"admin/articles/pagequery";a:1:{s:7:"WZGL_00";a:5:{s:4:"code";s:7:"WZGL_00";s:3:"url";s:24:"admin/articles/pagequery";s:4:"name";s:18:"查看文章管理";s:8:"isParent";b:0;s:6:"menuId";i:31;}}s:18:"admin/articles/add";a:1:{s:7:"WZGL_01";a:5:{s:4:"code";s:7:"WZGL_01";s:3:"url";s:18:"admin/articles/add";s:4:"name";s:12:"新增文章";s:8:"isParent";b:1;s:6:"menuId";i:31;}}s:21:"admin/articles/toedit";a:2:{s:7:"WZGL_01";a:5:{s:4:"code";s:7:"WZGL_01";s:3:"url";s:21:"admin/articles/toedit";s:4:"name";s:12:"新增文章";s:8:"isParent";b:0;s:6:"menuId";i:31;}s:7:"WZGL_02";a:5:{s:4:"code";s:7:"WZGL_02";s:3:"url";s:21:"admin/articles/toedit";s:4:"name";s:12:"编辑文章";s:8:"isParent";b:0;s:6:"menuId";i:31;}}s:19:"admin/articles/edit";a:1:{s:7:"WZGL_02";a:5:{s:4:"code";s:7:"WZGL_02";s:3:"url";s:19:"admin/articles/edit";s:4:"name";s:12:"编辑文章";s:8:"isParent";b:1;s:6:"menuId";i:31;}}s:26:"admin/articles/editiisshow";a:1:{s:7:"WZGL_02";a:5:{s:4:"code";s:7:"WZGL_02";s:3:"url";s:26:"admin/articles/editiisshow";s:4:"name";s:12:"编辑文章";s:8:"isParent";b:0;s:6:"menuId";i:31;}}s:18:"admin/articles/del";a:1:{s:7:"WZGL_03";a:5:{s:4:"code";s:7:"WZGL_03";s:3:"url";s:18:"admin/articles/del";s:4:"name";s:12:"删除文章";s:8:"isParent";b:1;s:6:"menuId";i:31;}}s:25:"admin/articles/delbybatch";a:1:{s:7:"WZGL_03";a:5:{s:4:"code";s:7:"WZGL_03";s:3:"url";s:25:"admin/articles/delbybatch";s:4:"name";s:12:"删除文章";s:8:"isParent";b:0;s:6:"menuId";i:31;}}s:23:"admin/articlecats/index";a:1:{s:7:"WZFL_00";a:5:{s:4:"code";s:7:"WZFL_00";s:3:"url";s:23:"admin/articlecats/index";s:4:"name";s:18:"查看文章分类";s:8:"isParent";b:1;s:6:"menuId";i:30;}}s:27:"admin/articlecats/pagequery";a:1:{s:7:"WZFL_00";a:5:{s:4:"code";s:7:"WZFL_00";s:3:"url";s:27:"admin/articlecats/pagequery";s:4:"name";s:18:"查看文章分类";s:8:"isParent";b:0;s:6:"menuId";i:30;}}s:21:"admin/articlecats/add";a:1:{s:7:"WZFL_01";a:5:{s:4:"code";s:7:"WZFL_01";s:3:"url";s:21:"admin/articlecats/add";s:4:"name";s:18:"新增文章分类";s:8:"isParent";b:1;s:6:"menuId";i:30;}}s:22:"admin/articlecats/edit";a:1:{s:7:"WZFL_02";a:5:{s:4:"code";s:7:"WZFL_02";s:3:"url";s:22:"admin/articlecats/edit";s:4:"name";s:18:"编辑文章分类";s:8:"isParent";b:1;s:6:"menuId";i:30;}}s:29:"admin/articlecats/editiisshow";a:1:{s:7:"WZFL_02";a:5:{s:4:"code";s:7:"WZFL_02";s:3:"url";s:29:"admin/articlecats/editiisshow";s:4:"name";s:18:"编辑文章分类";s:8:"isParent";b:0;s:6:"menuId";i:30;}}s:26:"admin/articlecats/editname";a:1:{s:7:"WZFL_02";a:5:{s:4:"code";s:7:"WZFL_02";s:3:"url";s:26:"admin/articlecats/editname";s:4:"name";s:18:"编辑文章分类";s:8:"isParent";b:0;s:6:"menuId";i:30;}}s:21:"admin/articlecats/del";a:1:{s:7:"WZFL_03";a:5:{s:4:"code";s:7:"WZFL_03";s:3:"url";s:21:"admin/articlecats/del";s:4:"name";s:18:"删除文章分类";s:8:"isParent";b:1;s:6:"menuId";i:30;}}s:21:"admin/homemenus/index";a:1:{s:7:"QTCD_00";a:5:{s:4:"code";s:7:"QTCD_00";s:3:"url";s:21:"admin/homemenus/index";s:4:"name";s:18:"前台菜单管理";s:8:"isParent";b:1;s:6:"menuId";i:43;}}s:25:"admin/homemenus/pagequery";a:1:{s:7:"QTCD_00";a:5:{s:4:"code";s:7:"QTCD_00";s:3:"url";s:25:"admin/homemenus/pagequery";s:4:"name";s:18:"前台菜单管理";s:8:"isParent";b:0;s:6:"menuId";i:43;}}s:24:"admin/users/accountindex";a:1:{s:7:"ZHGL_00";a:5:{s:4:"code";s:7:"ZHGL_00";s:3:"url";s:24:"admin/users/accountindex";s:4:"name";s:18:"查看账号管理";s:8:"isParent";b:1;s:6:"menuId";i:21;}}s:22:"admin/sysconfigs/index";a:1:{s:7:"SCPZ_00";a:5:{s:4:"code";s:7:"SCPZ_00";s:3:"url";s:22:"admin/sysconfigs/index";s:4:"name";s:18:"查看商城配置";s:8:"isParent";b:1;s:6:"menuId";i:9;}}s:21:"admin/sysconfigs/edit";a:1:{s:7:"SCPZ_02";a:5:{s:4:"code";s:7:"SCPZ_02";s:3:"url";s:21:"admin/sysconfigs/edit";s:4:"name";s:18:"编辑商城配置";s:8:"isParent";b:1;s:6:"menuId";i:9;}}s:19:"admin/accreds/index";a:1:{s:7:"RZGL_00";a:5:{s:4:"code";s:7:"RZGL_00";s:3:"url";s:19:"admin/accreds/index";s:4:"name";s:12:"查看认证";s:8:"isParent";b:1;s:6:"menuId";i:44;}}s:23:"admin/accreds/pagequery";a:1:{s:7:"RZGL_00";a:5:{s:4:"code";s:7:"RZGL_00";s:3:"url";s:23:"admin/accreds/pagequery";s:4:"name";s:12:"查看认证";s:8:"isParent";b:0;s:6:"menuId";i:44;}}s:17:"admin/accreds/add";a:1:{s:7:"RZGL_01";a:5:{s:4:"code";s:7:"RZGL_01";s:3:"url";s:17:"admin/accreds/add";s:4:"name";s:12:"新增认证";s:8:"isParent";b:1;s:6:"menuId";i:44;}}s:18:"admin/accreds/edit";a:1:{s:7:"RZGL_02";a:5:{s:4:"code";s:7:"RZGL_02";s:3:"url";s:18:"admin/accreds/edit";s:4:"name";s:12:"编辑认证";s:8:"isParent";b:1;s:6:"menuId";i:44;}}s:17:"admin/accreds/del";a:1:{s:7:"RZGL_03";a:5:{s:4:"code";s:7:"RZGL_03";s:3:"url";s:17:"admin/accreds/del";s:4:"name";s:12:"删除认证";s:8:"isParent";b:1;s:6:"menuId";i:44;}}s:19:"admin/homemenus/add";a:1:{s:7:"QTCD_01";a:5:{s:4:"code";s:7:"QTCD_01";s:3:"url";s:19:"admin/homemenus/add";s:4:"name";s:18:"新增前台菜单";s:8:"isParent";b:1;s:6:"menuId";i:43;}}s:20:"admin/homemenus/edit";a:1:{s:7:"QTCD_02";a:5:{s:4:"code";s:7:"QTCD_02";s:3:"url";s:20:"admin/homemenus/edit";s:4:"name";s:18:"编辑前台菜单";s:8:"isParent";b:1;s:6:"menuId";i:43;}}s:25:"admin/homemenus/settoggle";a:1:{s:7:"QTCD_02";a:5:{s:4:"code";s:7:"QTCD_02";s:3:"url";s:25:"admin/homemenus/settoggle";s:4:"name";s:18:"编辑前台菜单";s:8:"isParent";b:0;s:6:"menuId";i:43;}}s:19:"admin/homemenus/del";a:1:{s:7:"QTCD_03";a:5:{s:4:"code";s:7:"QTCD_03";s:3:"url";s:19:"admin/homemenus/del";s:4:"name";s:18:"删除前台菜单";s:8:"isParent";b:1;s:6:"menuId";i:43;}}s:23:"admin/users/editaccount";a:1:{s:7:"ZHGL_02";a:5:{s:4:"code";s:7:"ZHGL_02";s:3:"url";s:23:"admin/users/editaccount";s:4:"name";s:18:"编辑账号信息";s:8:"isParent";b:1;s:6:"menuId";i:21;}}s:28:"admin/users/changeuserstatus";a:1:{s:7:"ZHGL_02";a:5:{s:4:"code";s:7:"ZHGL_02";s:3:"url";s:28:"admin/users/changeuserstatus";s:4:"name";s:18:"编辑账号信息";s:8:"isParent";b:0;s:6:"menuId";i:21;}}s:17:"admin/shops/apply";a:1:{s:7:"DPSQ_00";a:5:{s:4:"code";s:7:"DPSQ_00";s:3:"url";s:17:"admin/shops/apply";s:4:"name";s:18:"查看开店申请";s:8:"isParent";b:1;s:6:"menuId";i:45;}}s:28:"admin/shops/pagequerybyapply";a:1:{s:7:"DPSQ_00";a:5:{s:4:"code";s:7:"DPSQ_00";s:3:"url";s:28:"admin/shops/pagequerybyapply";s:4:"name";s:18:"查看开店申请";s:8:"isParent";b:0;s:6:"menuId";i:45;}}s:20:"admin/shops/delapply";a:1:{s:7:"DPSQ_03";a:5:{s:4:"code";s:7:"DPSQ_03";s:3:"url";s:20:"admin/shops/delapply";s:4:"name";s:18:"删除开店申请";s:8:"isParent";b:1;s:6:"menuId";i:45;}}s:23:"admin/shops/handleapply";a:1:{s:7:"DPSQ_04";a:5:{s:4:"code";s:7:"DPSQ_04";s:3:"url";s:23:"admin/shops/handleapply";s:4:"name";s:18:"审核开店申请";s:8:"isParent";b:1;s:6:"menuId";i:45;}}s:25:"admin/shops/tohandleapply";a:1:{s:7:"DPSQ_04";a:5:{s:4:"code";s:7:"DPSQ_04";s:3:"url";s:25:"admin/shops/tohandleapply";s:4:"name";s:18:"审核开店申请";s:8:"isParent";b:0;s:6:"menuId";i:45;}}s:17:"admin/shops/index";a:1:{s:7:"DPGL_00";a:5:{s:4:"code";s:7:"DPGL_00";s:3:"url";s:17:"admin/shops/index";s:4:"name";s:18:"查看店铺管理";s:8:"isParent";b:1;s:6:"menuId";i:46;}}s:21:"admin/shops/pagequery";a:1:{s:7:"DPGL_00";a:5:{s:4:"code";s:7:"DPGL_00";s:3:"url";s:21:"admin/shops/pagequery";s:4:"name";s:18:"查看店铺管理";s:8:"isParent";b:0;s:6:"menuId";i:46;}}s:15:"admin/shops/add";a:1:{s:7:"DPGL_01";a:5:{s:4:"code";s:7:"DPGL_01";s:3:"url";s:15:"admin/shops/add";s:4:"name";s:12:"新增店铺";s:8:"isParent";b:1;s:6:"menuId";i:46;}}s:24:"admin/shops/toaddbyapply";a:1:{s:7:"DPGL_01";a:5:{s:4:"code";s:7:"DPGL_01";s:3:"url";s:24:"admin/shops/toaddbyapply";s:4:"name";s:12:"新增店铺";s:8:"isParent";b:0;s:6:"menuId";i:46;}}s:16:"admin/shops/edit";a:1:{s:7:"DPGL_02";a:5:{s:4:"code";s:7:"DPGL_02";s:3:"url";s:16:"admin/shops/edit";s:4:"name";s:12:"编辑店铺";s:8:"isParent";b:1;s:6:"menuId";i:46;}}s:18:"admin/shops/toedit";a:1:{s:7:"DPGL_02";a:5:{s:4:"code";s:7:"DPGL_02";s:3:"url";s:18:"admin/shops/toedit";s:4:"name";s:12:"编辑店铺";s:8:"isParent";b:0;s:6:"menuId";i:46;}}s:15:"admin/shops/del";a:1:{s:7:"DPGL_03";a:5:{s:4:"code";s:7:"DPGL_03";s:3:"url";s:15:"admin/shops/del";s:4:"name";s:12:"删除店铺";s:8:"isParent";b:1;s:6:"menuId";i:46;}}s:20:"admin/messages/index";a:1:{s:7:"SCXX_00";a:5:{s:4:"code";s:7:"SCXX_00";s:3:"url";s:20:"admin/messages/index";s:4:"name";s:18:"查看商城消息";s:8:"isParent";b:1;s:6:"menuId";i:41;}}s:26:"admin/messages/showfullmsg";a:1:{s:7:"SCXX_00";a:5:{s:4:"code";s:7:"SCXX_00";s:3:"url";s:26:"admin/messages/showfullmsg";s:4:"name";s:18:"查看商城消息";s:8:"isParent";b:0;s:6:"menuId";i:41;}}s:24:"admin/messages/pagequery";a:1:{s:7:"SCXX_00";a:5:{s:4:"code";s:7:"SCXX_00";s:3:"url";s:24:"admin/messages/pagequery";s:4:"name";s:18:"查看商城消息";s:8:"isParent";b:0;s:6:"menuId";i:41;}}s:18:"admin/messages/add";a:1:{s:7:"SCXX_01";a:5:{s:4:"code";s:7:"SCXX_01";s:3:"url";s:18:"admin/messages/add";s:4:"name";s:18:"发送商城消息";s:8:"isParent";b:1;s:6:"menuId";i:41;}}s:24:"admin/messages/userquery";a:1:{s:7:"SCXX_01";a:5:{s:4:"code";s:7:"SCXX_01";s:3:"url";s:24:"admin/messages/userquery";s:4:"name";s:18:"发送商城消息";s:8:"isParent";b:0;s:6:"menuId";i:41;}}s:18:"admin/messages/del";a:1:{s:7:"SCXX_03";a:5:{s:4:"code";s:7:"SCXX_03";s:3:"url";s:18:"admin/messages/del";s:4:"name";s:18:"删除商城消息";s:8:"isParent";b:1;s:6:"menuId";i:41;}}s:21:"admin/shops/stopindex";a:1:{s:7:"TYDP_00";a:5:{s:4:"code";s:7:"TYDP_00";s:3:"url";s:21:"admin/shops/stopindex";s:4:"name";s:18:"查看停用店铺";s:8:"isParent";b:1;s:6:"menuId";i:47;}}s:25:"admin/shops/pagestopquery";a:1:{s:7:"TYDP_00";a:5:{s:4:"code";s:7:"TYDP_00";s:3:"url";s:25:"admin/shops/pagestopquery";s:4:"name";s:18:"查看停用店铺";s:8:"isParent";b:0;s:6:"menuId";i:47;}}s:20:"admin/speccats/index";a:1:{s:7:"SPGG_00";a:5:{s:4:"code";s:7:"SPGG_00";s:3:"url";s:20:"admin/speccats/index";s:4:"name";s:18:"查看商品规格";s:8:"isParent";b:1;s:6:"menuId";i:32;}}s:24:"admin/speccats/pagequery";a:1:{s:7:"SPGG_00";a:5:{s:4:"code";s:7:"SPGG_00";s:3:"url";s:24:"admin/speccats/pagequery";s:4:"name";s:18:"查看商品规格";s:8:"isParent";b:0;s:6:"menuId";i:32;}}s:18:"admni/speccats/add";a:1:{s:7:"SPGG_01";a:5:{s:4:"code";s:7:"SPGG_01";s:3:"url";s:18:"admni/speccats/add";s:4:"name";s:18:"新增商品规格";s:8:"isParent";b:1;s:6:"menuId";i:32;}}s:21:"admni/speccats/toedit";a:2:{s:7:"SPGG_01";a:5:{s:4:"code";s:7:"SPGG_01";s:3:"url";s:21:"admni/speccats/toedit";s:4:"name";s:18:"新增商品规格";s:8:"isParent";b:0;s:6:"menuId";i:32;}s:7:"SPGG_02";a:5:{s:4:"code";s:7:"SPGG_02";s:3:"url";s:21:"admni/speccats/toedit";s:4:"name";s:18:"编辑商品规格";s:8:"isParent";b:0;s:6:"menuId";i:32;}}s:19:"admni/speccats/edit";a:1:{s:7:"SPGG_02";a:5:{s:4:"code";s:7:"SPGG_02";s:3:"url";s:19:"admni/speccats/edit";s:4:"name";s:18:"编辑商品规格";s:8:"isParent";b:1;s:6:"menuId";i:32;}}s:24:"admni/speccats/settoggle";a:1:{s:7:"SPGG_02";a:5:{s:4:"code";s:7:"SPGG_02";s:3:"url";s:24:"admni/speccats/settoggle";s:4:"name";s:18:"编辑商品规格";s:8:"isParent";b:0;s:6:"menuId";i:32;}}s:18:"admni/speccats/del";a:1:{s:7:"SPGG_03";a:5:{s:4:"code";s:7:"SPGG_03";s:3:"url";s:18:"admni/speccats/del";s:4:"name";s:18:"删除商品规格";s:8:"isParent";b:1;s:6:"menuId";i:32;}}s:22:"admin/attributes/index";a:1:{s:7:"SPSX_00";a:5:{s:4:"code";s:7:"SPSX_00";s:3:"url";s:22:"admin/attributes/index";s:4:"name";s:18:"查看商品属性";s:8:"isParent";b:1;s:6:"menuId";i:48;}}s:26:"admin/attributes/pagequery";a:1:{s:7:"SPSX_00";a:5:{s:4:"code";s:7:"SPSX_00";s:3:"url";s:26:"admin/attributes/pagequery";s:4:"name";s:18:"查看商品属性";s:8:"isParent";b:0;s:6:"menuId";i:48;}}s:18:"admin/orders/index";a:1:{s:7:"DDLB_00";a:5:{s:4:"code";s:7:"DDLB_00";s:3:"url";s:18:"admin/orders/index";s:4:"name";s:12:"查看订单";s:8:"isParent";b:1;s:6:"menuId";i:50;}}s:22:"admin/orders/pagequery";a:1:{s:7:"DDLB_00";a:5:{s:4:"code";s:7:"DDLB_00";s:3:"url";s:22:"admin/orders/pagequery";s:4:"name";s:12:"查看订单";s:8:"isParent";b:0;s:6:"menuId";i:50;}}s:26:"admin/ordercomplains/index";a:1:{s:7:"TSDD_00";a:5:{s:4:"code";s:7:"TSDD_00";s:3:"url";s:26:"admin/ordercomplains/index";s:4:"name";s:18:"查看投诉订单";s:8:"isParent";b:1;s:6:"menuId";i:51;}}s:25:"admin/ordercomplains/view";a:1:{s:7:"TSDD_00";a:5:{s:4:"code";s:7:"TSDD_00";s:3:"url";s:25:"admin/ordercomplains/view";s:4:"name";s:18:"查看投诉订单";s:8:"isParent";b:0;s:6:"menuId";i:51;}}s:30:"admin/ordercomplains/pagequery";a:1:{s:7:"TSDD_00";a:5:{s:4:"code";s:7:"TSDD_00";s:3:"url";s:30:"admin/ordercomplains/pagequery";s:4:"name";s:18:"查看投诉订单";s:8:"isParent";b:0;s:6:"menuId";i:51;}}s:25:"admin/orderrefunds/refund";a:1:{s:7:"TKDD_00";a:5:{s:4:"code";s:7:"TKDD_00";s:3:"url";s:25:"admin/orderrefunds/refund";s:4:"name";s:18:"查看退款订单";s:8:"isParent";b:1;s:6:"menuId";i:52;}}s:34:"admin/orderrefunds/refundpagequery";a:1:{s:7:"TKDD_00";a:5:{s:4:"code";s:7:"TKDD_00";s:3:"url";s:34:"admin/orderrefunds/refundpagequery";s:4:"name";s:18:"查看退款订单";s:8:"isParent";b:0;s:6:"menuId";i:52;}}s:17:"admin/orders/view";a:1:{s:7:"TKDD_00";a:5:{s:4:"code";s:7:"TKDD_00";s:3:"url";s:17:"admin/orders/view";s:4:"name";s:18:"查看退款订单";s:8:"isParent";b:0;s:6:"menuId";i:52;}}s:19:"admin/express/index";a:1:{s:7:"KDGL_00";a:5:{s:4:"code";s:7:"KDGL_00";s:3:"url";s:19:"admin/express/index";s:4:"name";s:18:"查看快递管理";s:8:"isParent";b:1;s:6:"menuId";i:53;}}s:23:"admin/express/pagequery";a:1:{s:7:"KDGL_00";a:5:{s:4:"code";s:7:"KDGL_00";s:3:"url";s:23:"admin/express/pagequery";s:4:"name";s:18:"查看快递管理";s:8:"isParent";b:0;s:6:"menuId";i:53;}}s:17:"admin/express/add";a:1:{s:7:"KDGL_01";a:5:{s:4:"code";s:7:"KDGL_01";s:3:"url";s:17:"admin/express/add";s:4:"name";s:12:"新增快递";s:8:"isParent";b:1;s:6:"menuId";i:53;}}s:18:"admin/express/edit";a:1:{s:7:"KDGL_02";a:5:{s:4:"code";s:7:"KDGL_02";s:3:"url";s:18:"admin/express/edit";s:4:"name";s:12:"编辑快递";s:8:"isParent";b:1;s:6:"menuId";i:53;}}s:17:"admin/express/del";a:1:{s:7:"KDGL_03";a:5:{s:4:"code";s:7:"KDGL_03";s:3:"url";s:17:"admin/express/del";s:4:"name";s:12:"删除快递";s:8:"isParent";b:1;s:6:"menuId";i:53;}}s:17:"admin/goods/index";a:1:{s:7:"SJSP_00";a:5:{s:4:"code";s:7:"SJSP_00";s:3:"url";s:17:"admin/goods/index";s:4:"name";s:21:"查看已上架商品";s:8:"isParent";b:1;s:6:"menuId";i:33;}}s:22:"admin/goods/salebypage";a:1:{s:7:"SJSP_00";a:5:{s:4:"code";s:7:"SJSP_00";s:3:"url";s:22:"admin/goods/salebypage";s:4:"name";s:21:"查看已上架商品";s:8:"isParent";b:0;s:6:"menuId";i:33;}}s:19:"admin/goods/illegal";a:1:{s:7:"SJSP_04";a:5:{s:4:"code";s:7:"SJSP_04";s:3:"url";s:19:"admin/goods/illegal";s:4:"name";s:12:"商品操作";s:8:"isParent";b:1;s:6:"menuId";i:33;}}s:15:"admin/goods/del";a:3:{s:7:"SJSP_03";a:5:{s:4:"code";s:7:"SJSP_03";s:3:"url";s:15:"admin/goods/del";s:4:"name";s:12:"删除商品";s:8:"isParent";b:1;s:6:"menuId";i:33;}s:8:"DSHSP_03";a:5:{s:4:"code";s:8:"DSHSP_03";s:3:"url";s:15:"admin/goods/del";s:4:"name";s:12:"删除商品";s:8:"isParent";b:1;s:6:"menuId";i:54;}s:7:"WGSP_03";a:5:{s:4:"code";s:7:"WGSP_03";s:3:"url";s:15:"admin/goods/del";s:4:"name";s:12:"删除商品";s:8:"isParent";b:1;s:6:"menuId";i:55;}}s:22:"admin/goods/auditindex";a:1:{s:8:"DSHSP_00";a:5:{s:4:"code";s:8:"DSHSP_00";s:3:"url";s:22:"admin/goods/auditindex";s:4:"name";s:21:"查看待审核商品";s:8:"isParent";b:1;s:6:"menuId";i:54;}}s:23:"admin/goods/auditbypage";a:1:{s:8:"DSHSP_00";a:5:{s:4:"code";s:8:"DSHSP_00";s:3:"url";s:23:"admin/goods/auditbypage";s:4:"name";s:21:"查看待审核商品";s:8:"isParent";b:0;s:6:"menuId";i:54;}}s:17:"admin/goods/allow";a:2:{s:8:"DSHSP_04";a:5:{s:4:"code";s:8:"DSHSP_04";s:3:"url";s:17:"admin/goods/allow";s:4:"name";s:12:"商品审核";s:8:"isParent";b:1;s:6:"menuId";i:54;}s:7:"WGSP_04";a:5:{s:4:"code";s:7:"WGSP_04";s:3:"url";s:17:"admin/goods/allow";s:4:"name";s:12:"商品审核";s:8:"isParent";b:1;s:6:"menuId";i:55;}}s:24:"admin/goods/illegalindex";a:1:{s:7:"WGSP_00";a:5:{s:4:"code";s:7:"WGSP_00";s:3:"url";s:24:"admin/goods/illegalindex";s:4:"name";s:18:"查看违规商品";s:8:"isParent";b:1;s:6:"menuId";i:55;}}s:22:"admin/recommends/goods";a:1:{s:7:"SPTJ_00";a:5:{s:4:"code";s:7:"SPTJ_00";s:3:"url";s:22:"admin/recommends/goods";s:4:"name";s:18:"查看商品推荐";s:8:"isParent";b:1;s:6:"menuId";i:58;}}s:26:"admin/recommends/editgoods";a:2:{s:7:"SPTJ_00";a:5:{s:4:"code";s:7:"SPTJ_00";s:3:"url";s:26:"admin/recommends/editgoods";s:4:"name";s:18:"查看商品推荐";s:8:"isParent";b:0;s:6:"menuId";i:58;}s:7:"SPTJ_04";a:5:{s:4:"code";s:7:"SPTJ_04";s:3:"url";s:26:"admin/recommends/editgoods";s:4:"name";s:12:"推荐操作";s:8:"isParent";b:1;s:6:"menuId";i:58;}}s:22:"admin/recommends/shops";a:1:{s:7:"DPTJ_00";a:5:{s:4:"code";s:7:"DPTJ_00";s:3:"url";s:22:"admin/recommends/shops";s:4:"name";s:18:"查看店铺推荐";s:8:"isParent";b:1;s:6:"menuId";i:59;}}s:26:"admin/recommends/editshops";a:2:{s:7:"DPTJ_00";a:5:{s:4:"code";s:7:"DPTJ_00";s:3:"url";s:26:"admin/recommends/editshops";s:4:"name";s:18:"查看店铺推荐";s:8:"isParent";b:0;s:6:"menuId";i:59;}s:7:"DPTJ_04";a:5:{s:4:"code";s:7:"DPTJ_04";s:3:"url";s:26:"admin/recommends/editshops";s:4:"name";s:12:"推荐操作";s:8:"isParent";b:1;s:6:"menuId";i:59;}}s:23:"admin/recommends/brands";a:1:{s:7:"PPTJ_00";a:5:{s:4:"code";s:7:"PPTJ_00";s:3:"url";s:23:"admin/recommends/brands";s:4:"name";s:18:"查看品牌推荐";s:8:"isParent";b:1;s:6:"menuId";i:60;}}s:27:"admin/recommends/editbrands";a:2:{s:7:"PPTJ_00";a:5:{s:4:"code";s:7:"PPTJ_00";s:3:"url";s:27:"admin/recommends/editbrands";s:4:"name";s:18:"查看品牌推荐";s:8:"isParent";b:0;s:6:"menuId";i:60;}s:7:"PPTJ_04";a:5:{s:4:"code";s:7:"PPTJ_04";s:3:"url";s:27:"admin/recommends/editbrands";s:4:"name";s:12:"推荐操作";s:8:"isParent";b:1;s:6:"menuId";i:60;}}s:18:"admin/images/index";a:1:{s:7:"TPKJ_00";a:5:{s:4:"code";s:7:"TPKJ_00";s:3:"url";s:18:"admin/images/index";s:4:"name";s:18:"查看图片空间";s:8:"isParent";b:1;s:6:"menuId";i:36;}}s:20:"admin/images/summary";a:1:{s:7:"TPKJ_00";a:5:{s:4:"code";s:7:"TPKJ_00";s:3:"url";s:20:"admin/images/summary";s:4:"name";s:18:"查看图片空间";s:8:"isParent";b:0;s:6:"menuId";i:36;}}s:18:"admin/images/lists";a:1:{s:7:"TPKJ_00";a:5:{s:4:"code";s:7:"TPKJ_00";s:3:"url";s:18:"admin/images/lists";s:4:"name";s:18:"查看图片空间";s:8:"isParent";b:0;s:6:"menuId";i:36;}}s:22:"admin/images/pagequery";a:1:{s:7:"TPKJ_00";a:5:{s:4:"code";s:7:"TPKJ_00";s:3:"url";s:22:"admin/images/pagequery";s:4:"name";s:18:"查看图片空间";s:8:"isParent";b:0;s:6:"menuId";i:36;}}s:24:"admin/images/checkimages";a:1:{s:7:"TPKJ_00";a:5:{s:4:"code";s:7:"TPKJ_00";s:3:"url";s:24:"admin/images/checkimages";s:4:"name";s:18:"查看图片空间";s:8:"isParent";b:0;s:6:"menuId";i:36;}}s:16:"admin/images/del";a:1:{s:7:"TPKJ_04";a:5:{s:4:"code";s:7:"TPKJ_04";s:3:"url";s:16:"admin/images/del";s:4:"name";s:12:"图片管理";s:8:"isParent";b:1;s:6:"menuId";i:36;}}s:29:"admin/ordercomplains/tohandle";a:1:{s:7:"TSDD_04";a:5:{s:4:"code";s:7:"TSDD_04";s:3:"url";s:29:"admin/ordercomplains/tohandle";s:4:"name";s:18:"处理订单投诉";s:8:"isParent";b:1;s:6:"menuId";i:51;}}s:32:"admin/ordercomplains/finalhandle";a:1:{s:7:"TSDD_04";a:5:{s:4:"code";s:7:"TSDD_04";s:3:"url";s:32:"admin/ordercomplains/finalhandle";s:4:"name";s:18:"处理订单投诉";s:8:"isParent";b:0;s:6:"menuId";i:51;}}s:35:"admin/ordercomplains/deliverrespond";a:1:{s:7:"TSDD_04";a:5:{s:4:"code";s:7:"TSDD_04";s:3:"url";s:35:"admin/ordercomplains/deliverrespond";s:4:"name";s:18:"处理订单投诉";s:8:"isParent";b:0;s:6:"menuId";i:51;}}s:21:"admin/orders/torefund";a:1:{s:7:"TKDD_04";a:5:{s:4:"code";s:7:"TKDD_04";s:3:"url";s:21:"admin/orders/torefund";s:4:"name";s:18:"处理退款订单";s:8:"isParent";b:1;s:6:"menuId";i:52;}}s:24:"admin/orders/orderrefund";a:1:{s:7:"TKDD_04";a:5:{s:4:"code";s:7:"TKDD_04";s:3:"url";s:24:"admin/orders/orderrefund";s:4:"name";s:18:"处理退款订单";s:8:"isParent";b:0;s:6:"menuId";i:52;}}s:20:"admin/attributes/add";a:1:{s:7:"SPSX_01";a:5:{s:4:"code";s:7:"SPSX_01";s:3:"url";s:20:"admin/attributes/add";s:4:"name";s:18:"新增商品属性";s:8:"isParent";b:1;s:6:"menuId";i:48;}}s:21:"admin/attributes/edit";a:1:{s:7:"SPSX_02";a:5:{s:4:"code";s:7:"SPSX_02";s:3:"url";s:21:"admin/attributes/edit";s:4:"name";s:18:"编辑商品属性";s:8:"isParent";b:1;s:6:"menuId";i:48;}}s:26:"admin/attributes/settoggle";a:1:{s:7:"SPSX_02";a:5:{s:4:"code";s:7:"SPSX_02";s:3:"url";s:26:"admin/attributes/settoggle";s:4:"name";s:18:"编辑商品属性";s:8:"isParent";b:0;s:6:"menuId";i:48;}}s:20:"admin/attributes/del";a:1:{s:7:"SPSX_03";a:5:{s:4:"code";s:7:"SPSX_03";s:3:"url";s:20:"admin/attributes/del";s:4:"name";s:18:"删除商品属性";s:8:"isParent";b:1;s:6:"menuId";i:48;}}s:22:"admin/index/clearcache";a:1:{s:7:"HHQL_04";a:5:{s:4:"code";s:7:"HHQL_04";s:3:"url";s:22:"admin/index/clearcache";s:4:"name";s:12:"清理缓存";s:8:"isParent";b:1;s:6:"menuId";i:2;}}s:18:"admin/shops/inself";a:1:{s:7:"ZYDP_00";a:5:{s:4:"code";s:7:"ZYDP_00";s:3:"url";s:18:"admin/shops/inself";s:4:"name";s:18:"登录自营店铺";s:8:"isParent";b:1;s:6:"menuId";i:2;}}s:18:"admin/styles/index";a:1:{s:7:"FGGL_00";a:5:{s:4:"code";s:7:"FGGL_00";s:3:"url";s:18:"admin/styles/index";s:4:"name";s:18:"查看风格管理";s:8:"isParent";b:1;s:6:"menuId";i:61;}}s:17:"admin/styles/edit";a:1:{s:7:"FGGL_04";a:5:{s:4:"code";s:7:"FGGL_04";s:3:"url";s:17:"admin/styles/edit";s:4:"name";s:12:"风格管理";s:8:"isParent";b:1;s:6:"menuId";i:61;}}s:21:"admin/cashdraws/index";a:1:{s:7:"TXSQ_00";a:5:{s:4:"code";s:7:"TXSQ_00";s:3:"url";s:21:"admin/cashdraws/index";s:4:"name";s:18:"查看提现申请";s:8:"isParent";b:1;s:6:"menuId";i:63;}}s:25:"admin/cashdraws/pagequery";a:1:{s:7:"TXSQ_00";a:5:{s:4:"code";s:7:"TXSQ_00";s:3:"url";s:25:"admin/cashdraws/pagequery";s:4:"name";s:18:"查看提现申请";s:8:"isParent";b:0;s:6:"menuId";i:63;}}s:22:"admin/cashdraws/toview";a:1:{s:7:"TXSQ_00";a:5:{s:4:"code";s:7:"TXSQ_00";s:3:"url";s:22:"admin/cashdraws/toview";s:4:"name";s:18:"查看提现申请";s:8:"isParent";b:0;s:6:"menuId";i:63;}}s:22:"admin/cashdraws/handle";a:1:{s:7:"TXSQ_04";a:5:{s:4:"code";s:7:"TXSQ_04";s:3:"url";s:22:"admin/cashdraws/handle";s:4:"name";s:18:"处理提现申请";s:8:"isParent";b:1;s:6:"menuId";i:63;}}s:24:"admin/cashdraws/tohandle";a:1:{s:7:"TXSQ_04";a:5:{s:4:"code";s:7:"TXSQ_04";s:3:"url";s:24:"admin/cashdraws/tohandle";s:4:"name";s:18:"处理提现申请";s:8:"isParent";b:0;s:6:"menuId";i:63;}}s:23:"admin/settlements/index";a:1:{s:7:"JSSQ_00";a:5:{s:4:"code";s:7:"JSSQ_00";s:3:"url";s:23:"admin/settlements/index";s:4:"name";s:18:"查看结算申请";s:8:"isParent";b:1;s:6:"menuId";i:64;}}s:27:"admin/settlements/pagequery";a:1:{s:7:"JSSQ_00";a:5:{s:4:"code";s:7:"JSSQ_00";s:3:"url";s:27:"admin/settlements/pagequery";s:4:"name";s:18:"查看结算申请";s:8:"isParent";b:0;s:6:"menuId";i:64;}}s:24:"admin/settlements/toview";a:1:{s:7:"JSSQ_00";a:5:{s:4:"code";s:7:"JSSQ_00";s:3:"url";s:24:"admin/settlements/toview";s:4:"name";s:18:"查看结算申请";s:8:"isParent";b:0;s:6:"menuId";i:64;}}s:32:"admin/settlements/pagegoodsquery";a:1:{s:7:"JSSQ_00";a:5:{s:4:"code";s:7:"JSSQ_00";s:3:"url";s:32:"admin/settlements/pagegoodsquery";s:4:"name";s:18:"查看结算申请";s:8:"isParent";b:0;s:6:"menuId";i:64;}}s:24:"admin/settlements/handle";a:1:{s:7:"JSSQ_04";a:5:{s:4:"code";s:7:"JSSQ_04";s:3:"url";s:24:"admin/settlements/handle";s:4:"name";s:18:"处理结算申请";s:8:"isParent";b:1;s:6:"menuId";i:64;}}s:26:"admin/settlements/tohandle";a:1:{s:7:"JSSQ_04";a:5:{s:4:"code";s:7:"JSSQ_04";s:3:"url";s:26:"admin/settlements/tohandle";s:4:"name";s:18:"处理结算申请";s:8:"isParent";b:0;s:6:"menuId";i:64;}}s:29:"admin/settlements/toshopindex";a:1:{s:7:"SJJS_00";a:5:{s:4:"code";s:7:"SJJS_00";s:3:"url";s:29:"admin/settlements/toshopindex";s:4:"name";s:18:"查看商家结算";s:8:"isParent";b:1;s:6:"menuId";i:65;}}s:31:"admin/settlements/pageshopquery";a:1:{s:7:"SJJS_00";a:5:{s:4:"code";s:7:"SJJS_00";s:3:"url";s:31:"admin/settlements/pageshopquery";s:4:"name";s:18:"查看商家结算";s:8:"isParent";b:0;s:6:"menuId";i:65;}}s:36:"admin/settlements/pageshoporderquery";a:1:{s:7:"SJJS_00";a:5:{s:4:"code";s:7:"SJJS_00";s:3:"url";s:36:"admin/settlements/pageshoporderquery";s:4:"name";s:18:"查看商家结算";s:8:"isParent";b:0;s:6:"menuId";i:65;}}s:26:"admin/settlements/toorders";a:1:{s:7:"SJJS_00";a:5:{s:4:"code";s:7:"SJJS_00";s:3:"url";s:26:"admin/settlements/toorders";s:4:"name";s:18:"查看商家结算";s:8:"isParent";b:0;s:6:"menuId";i:65;}}s:38:"admin/settlements/generatesettlebyshop";a:1:{s:7:"SJJS_04";a:5:{s:4:"code";s:7:"SJJS_04";s:3:"url";s:38:"admin/settlements/generatesettlebyshop";s:4:"name";s:15:"生成结算单";s:8:"isParent";b:1;s:6:"menuId";i:65;}}s:23:"admin/wsysconfigs/index";a:1:{s:11:"WX_GZHSZ_00";a:5:{s:4:"code";s:11:"WX_GZHSZ_00";s:3:"url";s:23:"admin/wsysconfigs/index";s:4:"name";s:21:"查看公众号设置";s:8:"isParent";b:1;s:6:"menuId";i:68;}}s:22:"admin/wsysconfigs/edit";a:1:{s:11:"WX_GZHSZ_04";a:5:{s:4:"code";s:11:"WX_GZHSZ_04";s:3:"url";s:22:"admin/wsysconfigs/edit";s:4:"name";s:15:"编辑公众号";s:8:"isParent";b:1;s:6:"menuId";i:68;}}s:19:"admin/wxmenus/index";a:1:{s:11:"WX_ZDYCD_00";a:5:{s:4:"code";s:11:"WX_ZDYCD_00";s:3:"url";s:19:"admin/wxmenus/index";s:4:"name";s:21:"查看自定义菜单";s:8:"isParent";b:1;s:6:"menuId";i:69;}}s:23:"admin/wxmenus/pagequery";a:1:{s:11:"WX_ZDYCD_00";a:5:{s:4:"code";s:11:"WX_ZDYCD_00";s:3:"url";s:23:"admin/wxmenus/pagequery";s:4:"name";s:21:"查看自定义菜单";s:8:"isParent";b:0;s:6:"menuId";i:69;}}s:23:"admin/wxmenus/synchrowx";a:1:{s:11:"WX_ZDYCD_00";a:5:{s:4:"code";s:11:"WX_ZDYCD_00";s:3:"url";s:23:"admin/wxmenus/synchrowx";s:4:"name";s:21:"查看自定义菜单";s:8:"isParent";b:0;s:6:"menuId";i:69;}}s:23:"admin/wxmenus/synchroad";a:1:{s:11:"WX_ZDYCD_00";a:5:{s:4:"code";s:11:"WX_ZDYCD_00";s:3:"url";s:23:"admin/wxmenus/synchroad";s:4:"name";s:21:"查看自定义菜单";s:8:"isParent";b:0;s:6:"menuId";i:69;}}s:20:"admin/wxmenus/toedit";a:2:{s:11:"WX_ZDYCD_02";a:5:{s:4:"code";s:11:"WX_ZDYCD_02";s:3:"url";s:20:"admin/wxmenus/toedit";s:4:"name";s:12:"编辑菜单";s:8:"isParent";b:1;s:6:"menuId";i:69;}s:11:"WX_ZDYCD_01";a:5:{s:4:"code";s:11:"WX_ZDYCD_01";s:3:"url";s:20:"admin/wxmenus/toedit";s:4:"name";s:12:"新增菜单";s:8:"isParent";b:1;s:6:"menuId";i:69;}}s:18:"admin/wxmenus/edit";a:1:{s:11:"WX_ZDYCD_02";a:5:{s:4:"code";s:11:"WX_ZDYCD_02";s:3:"url";s:18:"admin/wxmenus/edit";s:4:"name";s:12:"编辑菜单";s:8:"isParent";b:0;s:6:"menuId";i:69;}}s:17:"admin/wxmenus/del";a:1:{s:11:"WX_ZDYCD_03";a:5:{s:4:"code";s:11:"WX_ZDYCD_03";s:3:"url";s:17:"admin/wxmenus/del";s:4:"name";s:12:"删除菜单";s:8:"isParent";b:1;s:6:"menuId";i:69;}}s:17:"admin/wxmenus/add";a:1:{s:11:"WX_ZDYCD_01";a:5:{s:4:"code";s:11:"WX_ZDYCD_01";s:3:"url";s:17:"admin/wxmenus/add";s:4:"name";s:12:"新增菜单";s:8:"isParent";b:0;s:6:"menuId";i:69;}}s:28:"admin/reports/totopsalegoods";a:1:{s:10:"REPORTS_01";a:5:{s:4:"code";s:10:"REPORTS_01";s:3:"url";s:28:"admin/reports/totopsalegoods";s:4:"name";s:18:"查看销售排行";s:8:"isParent";b:1;s:6:"menuId";i:72;}}s:32:"admin/reports/topsalegoodsbypage";a:1:{s:10:"REPORTS_01";a:5:{s:4:"code";s:10:"REPORTS_01";s:3:"url";s:32:"admin/reports/topsalegoodsbypage";s:4:"name";s:18:"查看销售排行";s:8:"isParent";b:0;s:6:"menuId";i:72;}}s:25:"admin/reports/tostatsales";a:1:{s:10:"REPORTS_03";a:5:{s:4:"code";s:10:"REPORTS_03";s:3:"url";s:25:"admin/reports/tostatsales";s:4:"name";s:18:"查看销售统计";s:8:"isParent";b:1;s:6:"menuId";i:74;}}s:23:"admin/reports/statsales";a:1:{s:10:"REPORTS_03";a:5:{s:4:"code";s:10:"REPORTS_03";s:3:"url";s:23:"admin/reports/statsales";s:4:"name";s:18:"查看销售统计";s:8:"isParent";b:0;s:6:"menuId";i:74;}}s:27:"admin/reports/tostatnewuser";a:1:{s:10:"REPORTS_05";a:5:{s:4:"code";s:10:"REPORTS_05";s:3:"url";s:27:"admin/reports/tostatnewuser";s:4:"name";s:18:"查看会员统计";s:8:"isParent";b:1;s:6:"menuId";i:73;}}s:25:"admin/reports/statnewuser";a:1:{s:10:"REPORTS_05";a:5:{s:4:"code";s:10:"REPORTS_05";s:3:"url";s:25:"admin/reports/statnewuser";s:4:"name";s:18:"查看会员统计";s:8:"isParent";b:0;s:6:"menuId";i:73;}}s:29:"admin/reports/tostatuserlogin";a:1:{s:10:"REPORTS_06";a:5:{s:4:"code";s:10:"REPORTS_06";s:3:"url";s:29:"admin/reports/tostatuserlogin";s:4:"name";s:18:"查看登录统计";s:8:"isParent";b:1;s:6:"menuId";i:75;}}s:27:"admin/reports/statuserlogin";a:1:{s:10:"REPORTS_06";a:5:{s:4:"code";s:10:"REPORTS_06";s:3:"url";s:27:"admin/reports/statuserlogin";s:4:"name";s:18:"查看登录统计";s:8:"isParent";b:0;s:6:"menuId";i:75;}}s:28:"admin/reports/totopshopsales";a:1:{s:10:"REPORTS_02";a:5:{s:4:"code";s:10:"REPORTS_02";s:3:"url";s:28:"admin/reports/totopshopsales";s:4:"name";s:18:"店铺销售统计";s:8:"isParent";b:1;s:6:"menuId";i:77;}}s:32:"admin/reports/topshopsalesbypage";a:1:{s:10:"REPORTS_02";a:5:{s:4:"code";s:10:"REPORTS_02";s:3:"url";s:32:"admin/reports/topshopsalesbypage";s:4:"name";s:18:"店铺销售统计";s:8:"isParent";b:0;s:6:"menuId";i:77;}}s:28:"admin/reports/tostatloginsrc";a:1:{s:10:"REPORTS_07";a:5:{s:4:"code";s:10:"REPORTS_07";s:3:"url";s:28:"admin/reports/tostatloginsrc";s:4:"name";s:27:"查看客户端登录统计";s:8:"isParent";b:1;s:6:"menuId";i:78;}}s:26:"admin/reports/statloginsrc";a:1:{s:10:"REPORTS_07";a:5:{s:4:"code";s:10:"REPORTS_07";s:3:"url";s:26:"admin/reports/statloginsrc";s:4:"name";s:27:"查看客户端登录统计";s:8:"isParent";b:0;s:6:"menuId";i:78;}}s:26:"admin/reports/tostatorders";a:1:{s:10:"REPORTS_04";a:5:{s:4:"code";s:10:"REPORTS_04";s:3:"url";s:26:"admin/reports/tostatorders";s:4:"name";s:24:"查看销售订单统计";s:8:"isParent";b:1;s:6:"menuId";i:76;}}s:24:"admin/reports/statorders";a:1:{s:10:"REPORTS_04";a:5:{s:4:"code";s:10:"REPORTS_04";s:3:"url";s:24:"admin/reports/statorders";s:4:"name";s:24:"查看销售订单统计";s:8:"isParent";b:0;s:6:"menuId";i:76;}}s:30:"admin/wxpassivereplys/textedit";a:2:{s:10:"WX_WBXX_01";a:5:{s:4:"code";s:10:"WX_WBXX_01";s:3:"url";s:30:"admin/wxpassivereplys/textedit";s:4:"name";s:18:"新增文本消息";s:8:"isParent";b:1;s:6:"menuId";i:70;}s:10:"WX_WBXX_02";a:5:{s:4:"code";s:10:"WX_WBXX_02";s:3:"url";s:30:"admin/wxpassivereplys/textedit";s:4:"name";s:18:"编辑文本消息";s:8:"isParent";b:1;s:6:"menuId";i:70;}}s:25:"admin/wxpassivereplys/add";a:2:{s:10:"WX_WBXX_01";a:5:{s:4:"code";s:10:"WX_WBXX_01";s:3:"url";s:25:"admin/wxpassivereplys/add";s:4:"name";s:18:"新增文本消息";s:8:"isParent";b:0;s:6:"menuId";i:70;}s:10:"WX_TWXX_01";a:5:{s:4:"code";s:10:"WX_TWXX_01";s:3:"url";s:25:"admin/wxpassivereplys/add";s:4:"name";s:18:"新增图文消息";s:8:"isParent";b:0;s:6:"menuId";i:79;}}s:26:"admin/wxpassivereplys/text";a:1:{s:10:"WX_WBXX_00";a:5:{s:4:"code";s:10:"WX_WBXX_00";s:3:"url";s:26:"admin/wxpassivereplys/text";s:4:"name";s:18:"查看文本消息";s:8:"isParent";b:1;s:6:"menuId";i:70;}}s:35:"admin/wxpassivereplys/textpagequery";a:1:{s:10:"WX_WBXX_00";a:5:{s:4:"code";s:10:"WX_WBXX_00";s:3:"url";s:35:"admin/wxpassivereplys/textpagequery";s:4:"name";s:18:"查看文本消息";s:8:"isParent";b:0;s:6:"menuId";i:70;}}s:26:"admin/wxpassivereplys/edit";a:2:{s:10:"WX_WBXX_02";a:5:{s:4:"code";s:10:"WX_WBXX_02";s:3:"url";s:26:"admin/wxpassivereplys/edit";s:4:"name";s:18:"编辑文本消息";s:8:"isParent";b:0;s:6:"menuId";i:70;}s:10:"WX_TWXX_02";a:5:{s:4:"code";s:10:"WX_TWXX_02";s:3:"url";s:26:"admin/wxpassivereplys/edit";s:4:"name";s:18:"修改图文消息";s:8:"isParent";b:0;s:6:"menuId";i:79;}}s:25:"admin/wxpassivereplys/del";a:2:{s:10:"WX_WBXX_03";a:5:{s:4:"code";s:10:"WX_WBXX_03";s:3:"url";s:25:"admin/wxpassivereplys/del";s:4:"name";s:18:"删除文本消息";s:8:"isParent";b:1;s:6:"menuId";i:70;}s:10:"WX_TWXX_03";a:5:{s:4:"code";s:10:"WX_TWXX_03";s:3:"url";s:25:"admin/wxpassivereplys/del";s:4:"name";s:18:"删除图文消息";s:8:"isParent";b:1;s:6:"menuId";i:79;}}s:26:"admin/wxpassivereplys/news";a:1:{s:10:"WX_TWXX_00";a:5:{s:4:"code";s:10:"WX_TWXX_00";s:3:"url";s:26:"admin/wxpassivereplys/news";s:4:"name";s:18:"查看图文消息";s:8:"isParent";b:1;s:6:"menuId";i:79;}}s:35:"admin/wxpassivereplys/newspagequery";a:1:{s:10:"WX_TWXX_00";a:5:{s:4:"code";s:10:"WX_TWXX_00";s:3:"url";s:35:"admin/wxpassivereplys/newspagequery";s:4:"name";s:18:"查看图文消息";s:8:"isParent";b:0;s:6:"menuId";i:79;}}s:30:"admin/wxpassivereplys/newsedit";a:2:{s:10:"WX_TWXX_01";a:5:{s:4:"code";s:10:"WX_TWXX_01";s:3:"url";s:30:"admin/wxpassivereplys/newsedit";s:4:"name";s:18:"新增图文消息";s:8:"isParent";b:1;s:6:"menuId";i:79;}s:10:"WX_TWXX_02";a:5:{s:4:"code";s:10:"WX_TWXX_02";s:3:"url";s:30:"admin/wxpassivereplys/newsedit";s:4:"name";s:18:"修改图文消息";s:8:"isParent";b:1;s:6:"menuId";i:79;}}s:19:"admin/wxusers/index";a:1:{s:10:"WX_YHGL_00";a:5:{s:4:"code";s:10:"WX_YHGL_00";s:3:"url";s:19:"admin/wxusers/index";s:4:"name";s:18:"查看用户管理";s:8:"isParent";b:1;s:6:"menuId";i:80;}}s:18:"admin/addons/index";a:1:{s:7:"CJGL_00";a:5:{s:4:"code";s:7:"CJGL_00";s:3:"url";s:18:"admin/addons/index";s:4:"name";s:12:"查看插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:22:"admin/addons/pagequery";a:1:{s:7:"CJGL_00";a:5:{s:4:"code";s:7:"CJGL_00";s:3:"url";s:22:"admin/addons/pagequery";s:4:"name";s:12:"查看插件";s:8:"isParent";b:0;s:6:"menuId";i:83;}}s:16:"admin/addons/add";a:1:{s:7:"CJGL_01";a:5:{s:4:"code";s:7:"CJGL_01";s:3:"url";s:16:"admin/addons/add";s:4:"name";s:12:"设置插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:20:"admin/addons/install";a:1:{s:7:"CJGL_02";a:5:{s:4:"code";s:7:"CJGL_02";s:3:"url";s:20:"admin/addons/install";s:4:"name";s:12:"安装插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:22:"admin/addons/uninstall";a:1:{s:7:"CJGL_03";a:5:{s:4:"code";s:7:"CJGL_03";s:3:"url";s:22:"admin/addons/uninstall";s:4:"name";s:12:"卸载插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:19:"admin/addons/enable";a:1:{s:7:"CJGL_04";a:5:{s:4:"code";s:7:"CJGL_04";s:3:"url";s:19:"admin/addons/enable";s:4:"name";s:12:"启用插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:20:"admin/addons/disable";a:1:{s:7:"CJGL_05";a:5:{s:4:"code";s:7:"CJGL_05";s:3:"url";s:20:"admin/addons/disable";s:4:"name";s:12:"禁用插件";s:8:"isParent";b:1;s:6:"menuId";i:83;}}s:17:"admin/hooks/index";a:1:{s:7:"GZGL_00";a:5:{s:4:"code";s:7:"GZGL_00";s:3:"url";s:17:"admin/hooks/index";s:4:"name";s:12:"查看钩子";s:8:"isParent";b:1;s:6:"menuId";i:84;}}s:21:"admin/logmoneys/index";a:1:{s:7:"ZJGL_00";a:5:{s:4:"code";s:7:"ZJGL_00";s:3:"url";s:21:"admin/logmoneys/index";s:4:"name";s:18:"查看资金管理";s:8:"isParent";b:1;s:6:"menuId";i:85;}}s:25:"admin/logmoneys/pagequery";a:1:{s:7:"ZJGL_00";a:5:{s:4:"code";s:7:"ZJGL_00";s:3:"url";s:25:"admin/logmoneys/pagequery";s:4:"name";s:18:"查看资金管理";s:8:"isParent";b:0;s:6:"menuId";i:85;}}s:24:"admin/templatemsgs/index";a:1:{s:7:"XXMB_00";a:5:{s:4:"code";s:7:"XXMB_00";s:3:"url";s:24:"admin/templatemsgs/index";s:4:"name";s:18:"查看消息模板";s:8:"isParent";b:1;s:6:"menuId";i:86;}}s:31:"admin/templatemsgs/pagemsgquery";a:1:{s:7:"XXMB_00";a:5:{s:4:"code";s:7:"XXMB_00";s:3:"url";s:31:"admin/templatemsgs/pagemsgquery";s:4:"name";s:18:"查看消息模板";s:8:"isParent";b:0;s:6:"menuId";i:86;}}s:33:"admin/templatemsgs/pageemailquery";a:1:{s:7:"XXMB_00";a:5:{s:4:"code";s:7:"XXMB_00";s:3:"url";s:33:"admin/templatemsgs/pageemailquery";s:4:"name";s:18:"查看消息模板";s:8:"isParent";b:0;s:6:"menuId";i:86;}}s:31:"admin/templatemsgs/pagesmsquery";a:1:{s:7:"XXMB_00";a:5:{s:4:"code";s:7:"XXMB_00";s:3:"url";s:31:"admin/templatemsgs/pagesmsquery";s:4:"name";s:18:"查看消息模板";s:8:"isParent";b:0;s:6:"menuId";i:86;}}s:23:"admin/templatemsgs/edit";a:1:{s:7:"XXMB_02";a:5:{s:4:"code";s:7:"XXMB_02";s:3:"url";s:23:"admin/templatemsgs/edit";s:4:"name";s:18:"编辑消息模板";s:8:"isParent";b:1;s:6:"menuId";i:86;}}s:25:"admin/templatemsgs/toedit";a:1:{s:7:"XXMB_02";a:5:{s:4:"code";s:7:"XXMB_02";s:3:"url";s:25:"admin/templatemsgs/toedit";s:4:"name";s:18:"编辑消息模板";s:8:"isParent";b:0;s:6:"menuId";i:86;}}s:26:"admin/wxtemplatemsgs/index";a:1:{s:10:"WX_XXMB_00";a:5:{s:4:"code";s:10:"WX_XXMB_00";s:3:"url";s:26:"admin/wxtemplatemsgs/index";s:4:"name";s:24:"查看微信消息模板";s:8:"isParent";b:1;s:6:"menuId";i:87;}}s:30:"admin/wxtemplatemsgs/pagequery";a:1:{s:10:"WX_XXMB_00";a:5:{s:4:"code";s:10:"WX_XXMB_00";s:3:"url";s:30:"admin/wxtemplatemsgs/pagequery";s:4:"name";s:24:"查看微信消息模板";s:8:"isParent";b:0;s:6:"menuId";i:87;}}s:25:"admin/wxtemplatemsgs/edit";a:1:{s:10:"WX_XXMB_02";a:5:{s:4:"code";s:10:"WX_XXMB_02";s:3:"url";s:25:"admin/wxtemplatemsgs/edit";s:4:"name";s:24:"编辑微信消息模板";s:8:"isParent";b:1;s:6:"menuId";i:87;}}s:27:"admin/wxtemplatemsgs/toedit";a:1:{s:10:"WX_XXMB_02";a:5:{s:4:"code";s:10:"WX_XXMB_02";s:3:"url";s:27:"admin/wxtemplatemsgs/toedit";s:4:"name";s:24:"编辑微信消息模板";s:8:"isParent";b:0;s:6:"menuId";i:87;}}s:24:"admin/goodsconsult/index";a:1:{s:7:"SPZX_00";a:5:{s:4:"code";s:7:"SPZX_00";s:3:"url";s:24:"admin/goodsconsult/index";s:4:"name";s:18:"查看商品咨询";s:8:"isParent";b:1;s:6:"menuId";i:168;}}s:28:"admin/goodsconsult/pagequery";a:1:{s:7:"SPZX_00";a:5:{s:4:"code";s:7:"SPZX_00";s:3:"url";s:28:"admin/goodsconsult/pagequery";s:4:"name";s:18:"查看商品咨询";s:8:"isParent";b:0;s:6:"menuId";i:168;}}s:23:"admin/goodsconsult/edit";a:1:{s:7:"SPZX_02";a:5:{s:4:"code";s:7:"SPZX_02";s:3:"url";s:23:"admin/goodsconsult/edit";s:4:"name";s:18:"编辑商品咨询";s:8:"isParent";b:1;s:6:"menuId";i:168;}}s:25:"admin/goodsconsult/toedit";a:1:{s:7:"SPZX_02";a:5:{s:4:"code";s:7:"SPZX_02";s:3:"url";s:25:"admin/goodsconsult/toedit";s:4:"name";s:18:"编辑商品咨询";s:8:"isParent";b:0;s:6:"menuId";i:168;}}s:22:"admin/goodsconsult/del";a:1:{s:7:"SPZX_03";a:5:{s:4:"code";s:7:"SPZX_03";s:3:"url";s:22:"admin/goodsconsult/del";s:4:"name";s:18:"商品商品咨询";s:8:"isParent";b:1;s:6:"menuId";i:168;}}s:17:"admin/datas/index";a:1:{s:7:"SJGL_00";a:5:{s:4:"code";s:7:"SJGL_00";s:3:"url";s:17:"admin/datas/index";s:4:"name";s:24:"查看系统数据管理";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:24:"admin/datacats/listquery";a:1:{s:7:"SJGL_00";a:5:{s:4:"code";s:7:"SJGL_00";s:3:"url";s:24:"admin/datacats/listquery";s:4:"name";s:24:"查看系统数据管理";s:8:"isParent";b:0;s:6:"menuId";i:169;}}s:18:"admin/datacats/add";a:1:{s:7:"SJFL_01";a:5:{s:4:"code";s:7:"SJFL_01";s:3:"url";s:18:"admin/datacats/add";s:4:"name";s:24:"新增系统数据分类";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:19:"admin/datacats/edit";a:1:{s:7:"SJFL_02";a:5:{s:4:"code";s:7:"SJFL_02";s:3:"url";s:19:"admin/datacats/edit";s:4:"name";s:24:"修改系统数据分类";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:18:"admin/datacats/del";a:1:{s:7:"SJFL_03";a:5:{s:4:"code";s:7:"SJFL_03";s:3:"url";s:18:"admin/datacats/del";s:4:"name";s:24:"删除系统数据分类";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:15:"admin/datas/add";a:1:{s:7:"SJGL_01";a:5:{s:4:"code";s:7:"SJGL_01";s:3:"url";s:15:"admin/datas/add";s:4:"name";s:18:"新增系统数据";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:16:"admin/datas/edit";a:1:{s:7:"SJGL_02";a:5:{s:4:"code";s:7:"SJGL_02";s:3:"url";s:16:"admin/datas/edit";s:4:"name";s:18:"修改系统数据";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:15:"admin/datas/del";a:1:{s:7:"SJGL_03";a:5:{s:4:"code";s:7:"SJGL_03";s:3:"url";s:15:"admin/datas/del";s:4:"name";s:18:"删除系统数据";s:8:"isParent";b:1;s:6:"menuId";i:169;}}s:22:"admin/mobilebtns/index";a:1:{s:7:"ANGL_00";a:5:{s:4:"code";s:7:"ANGL_00";s:3:"url";s:22:"admin/mobilebtns/index";s:4:"name";s:21:"移动端按钮列表";s:8:"isParent";b:1;s:6:"menuId";i:170;}}s:26:"admin/mobilebtns/pagequery";a:1:{s:7:"ANGL_00";a:5:{s:4:"code";s:7:"ANGL_00";s:3:"url";s:26:"admin/mobilebtns/pagequery";s:4:"name";s:21:"移动端按钮列表";s:8:"isParent";b:0;s:6:"menuId";i:170;}}s:20:"admin/mobilebtns/add";a:1:{s:7:"ANGL_01";a:5:{s:4:"code";s:7:"ANGL_01";s:3:"url";s:20:"admin/mobilebtns/add";s:4:"name";s:21:"移动端按钮新增";s:8:"isParent";b:1;s:6:"menuId";i:170;}}s:21:"admin/mobilebtns/edit";a:1:{s:7:"ANGL_02";a:5:{s:4:"code";s:7:"ANGL_02";s:3:"url";s:21:"admin/mobilebtns/edit";s:4:"name";s:21:"移动端按钮修改";s:8:"isParent";b:1;s:6:"menuId";i:170;}}s:20:"admin/mobilebtns/del";a:1:{s:7:"ANGL_03";a:5:{s:4:"code";s:7:"ANGL_03";s:3:"url";s:20:"admin/mobilebtns/del";s:4:"name";s:21:"移动端按钮删除";s:8:"isParent";b:1;s:6:"menuId";i:170;}}s:23:"admin/chargeitems/index";a:1:{s:7:"CZGL_00";a:5:{s:4:"code";s:7:"CZGL_00";s:3:"url";s:23:"admin/chargeitems/index";s:4:"name";s:18:"查看充值管理";s:8:"isParent";b:1;s:6:"menuId";i:172;}}s:27:"admin/chargeitems/pagequery";a:1:{s:7:"CZGL_00";a:5:{s:4:"code";s:7:"CZGL_00";s:3:"url";s:27:"admin/chargeitems/pagequery";s:4:"name";s:18:"查看充值管理";s:8:"isParent";b:0;s:6:"menuId";i:172;}}s:21:"admin/chargeitems/add";a:1:{s:7:"CZGL_01";a:5:{s:4:"code";s:7:"CZGL_01";s:3:"url";s:21:"admin/chargeitems/add";s:4:"name";s:15:"新增充值项";s:8:"isParent";b:1;s:6:"menuId";i:172;}}s:24:"admin/chargeitems/toedit";a:2:{s:7:"CZGL_01";a:5:{s:4:"code";s:7:"CZGL_01";s:3:"url";s:24:"admin/chargeitems/toedit";s:4:"name";s:15:"新增充值项";s:8:"isParent";b:0;s:6:"menuId";i:172;}s:7:"CZGL_02";a:5:{s:4:"code";s:7:"CZGL_02";s:3:"url";s:24:"admin/chargeitems/toedit";s:4:"name";s:15:"修改充值项";s:8:"isParent";b:0;s:6:"menuId";i:172;}}s:22:"admin/chargeitems/edit";a:1:{s:7:"CZGL_02";a:5:{s:4:"code";s:7:"CZGL_02";s:3:"url";s:22:"admin/chargeitems/edit";s:4:"name";s:15:"修改充值项";s:8:"isParent";b:1;s:6:"menuId";i:172;}}s:21:"admin/chargeitems/del";a:1:{s:7:"CZGL_03";a:5:{s:4:"code";s:7:"CZGL_03";s:3:"url";s:21:"admin/chargeitems/del";s:4:"name";s:15:"删除充值项";s:8:"isParent";b:1;s:6:"menuId";i:172;}}s:18:"admin/logsms/index";a:1:{s:7:"DXRZ_00";a:5:{s:4:"code";s:7:"DXRZ_00";s:3:"url";s:18:"admin/logsms/index";s:4:"name";s:18:"查看短信日志";s:8:"isParent";b:1;s:6:"menuId";i:185;}}s:22:"admin/logsms/pagequery";a:1:{s:7:"DXRZ_00";a:5:{s:4:"code";s:7:"DXRZ_00";s:3:"url";s:22:"admin/logsms/pagequery";s:4:"name";s:18:"查看短信日志";s:8:"isParent";b:0;s:6:"menuId";i:185;}}s:19:"admin/informs/index";a:1:{s:7:"JBSP_00";a:5:{s:4:"code";s:7:"JBSP_00";s:3:"url";s:19:"admin/informs/index";s:4:"name";s:18:"举报商品管理";s:8:"isParent";b:1;s:6:"menuId";i:188;}}s:23:"admin/informs/pagequery";a:1:{s:7:"JBSP_00";a:5:{s:4:"code";s:7:"JBSP_00";s:3:"url";s:23:"admin/informs/pagequery";s:4:"name";s:18:"举报商品管理";s:8:"isParent";b:0;s:6:"menuId";i:188;}}s:20:"admin/informs/detail";a:1:{s:7:"JBSP_00";a:5:{s:4:"code";s:7:"JBSP_00";s:3:"url";s:20:"admin/informs/detail";s:4:"name";s:18:"举报商品管理";s:8:"isParent";b:0;s:6:"menuId";i:188;}}s:46:"/addon/hyhcommunity-hyhcommunity-communitylist";a:1:{s:20:"HYHCOMMUNITY_TGHD_00";a:5:{s:4:"code";s:20:"HYHCOMMUNITY_TGHD_00";s:3:"url";s:46:"/addon/hyhcommunity-hyhcommunity-communitylist";s:4:"name";s:6:"列表";s:8:"isParent";b:1;s:6:"menuId";i:202;}}s:20:"admin/users/recharge";a:1:{s:7:"HYGL_04";a:5:{s:4:"code";s:7:"HYGL_04";s:3:"url";s:20:"admin/users/recharge";s:4:"name";s:12:"会员充值";s:8:"isParent";b:0;s:6:"menuId";i:20;}}s:19:"admin/ectdeal/index";a:1:{s:8:"ECTJY_00";a:5:{s:4:"code";s:8:"ECTJY_00";s:3:"url";s:19:"admin/ectdeal/index";s:4:"name";s:15:"ECT交易记录";s:8:"isParent";b:1;s:6:"menuId";i:203;}}s:21:"admin/ecttarget/index";a:1:{s:8:"ECTTX_00";a:5:{s:4:"code";s:8:"ECTTX_00";s:3:"url";s:21:"admin/ecttarget/index";s:4:"name";s:15:"ECT提现记录";s:8:"isParent";b:1;s:6:"menuId";i:204;}}s:16:"admin/carts/cart";a:1:{s:8:"GWCSJ_00";a:5:{s:4:"code";s:8:"GWCSJ_00";s:3:"url";s:16:"admin/carts/cart";s:4:"name";s:15:"购物车数据";s:8:"isParent";b:1;s:6:"menuId";i:206;}}s:23:"admin/carts/cartsbypage";a:1:{s:8:"GWCSJ_00";a:5:{s:4:"code";s:8:"GWCSJ_00";s:3:"url";s:23:"admin/carts/cartsbypage";s:4:"name";s:15:"购物车数据";s:8:"isParent";b:0;s:6:"menuId";i:206;}}s:20:"admin/reports/detail";a:1:{s:9:"DPSPXS_00";a:5:{s:4:"code";s:9:"DPSPXS_00";s:3:"url";s:20:"admin/reports/detail";s:4:"name";s:18:"店铺商品销售";s:8:"isParent";b:1;s:6:"menuId";i:207;}}s:18:"admin/shops/detail";a:1:{s:9:"SJDLSJ_00";a:5:{s:4:"code";s:9:"SJDLSJ_00";s:3:"url";s:18:"admin/shops/detail";s:4:"name";s:18:"商家登录数据";s:8:"isParent";b:1;s:6:"menuId";i:208;}}s:18:"admin/member/index";a:1:{s:9:"HYHYSJ_00";a:5:{s:4:"code";s:9:"HYHYSJ_00";s:3:"url";s:18:"admin/member/index";s:4:"name";s:18:"会员活跃数据";s:8:"isParent";b:1;s:6:"menuId";i:209;}}s:20:"admin/platform/index";a:1:{s:9:"PTZHSJ_00";a:5:{s:4:"code";s:9:"PTZHSJ_00";s:3:"url";s:20:"admin/platform/index";s:4:"name";s:18:"平台转换数据";s:8:"isParent";b:1;s:6:"menuId";i:210;}}s:25:"admin/goodsclassify/index";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:25:"admin/goodsclassify/index";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:1;s:6:"menuId";i:215;}}s:29:"admin/goodsclassify/pagequery";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:29:"admin/goodsclassify/pagequery";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:24:"admin/goodsclassify/gets";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:24:"admin/goodsclassify/gets";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:29:"admin/goodsclassify/catdetail";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:29:"admin/goodsclassify/catdetail";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:33:"admin/goodsclassify/catdetailpage";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:33:"admin/goodsclassify/catdetailpage";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:26:"admin/goodsclassify/catdel";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:26:"admin/goodsclassify/catdel";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:26:"admin/goodsclassify/detail";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:26:"admin/goodsclassify/detail";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:32:"admin/goodsclassify/detailbypage";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:32:"admin/goodsclassify/detailbypage";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:26:"admin/goodsclassify/add_ca";a:1:{s:8:"SPZFL_00";a:5:{s:4:"code";s:8:"SPZFL_00";s:3:"url";s:26:"admin/goodsclassify/add_ca";s:4:"name";s:21:"查看商品总分类";s:8:"isParent";b:0;s:6:"menuId";i:215;}}s:19:"admin/adgoods/index";a:1:{s:9:"GGSPGL_00";a:5:{s:4:"code";s:9:"GGSPGL_00";s:3:"url";s:19:"admin/adgoods/index";s:4:"name";s:18:"广告商品管理";s:8:"isParent";b:1;s:6:"menuId";i:216;}}s:26:"admin/users/personalreview";a:1:{s:9:"GTRZSH_00";a:5:{s:4:"code";s:9:"GTRZSH_00";s:3:"url";s:26:"admin/users/personalreview";s:4:"name";s:18:"个体认证列表";s:8:"isParent";b:1;s:6:"menuId";i:227;}}s:29:"admin/users/getpersonalreview";a:1:{s:9:"GTRZSH_00";a:5:{s:4:"code";s:9:"GTRZSH_00";s:3:"url";s:29:"admin/users/getpersonalreview";s:4:"name";s:18:"个体认证列表";s:8:"isParent";b:0;s:6:"menuId";i:227;}}s:26:"admin/users/personalaction";a:1:{s:9:"GTRZSH_01";a:5:{s:4:"code";s:9:"GTRZSH_01";s:3:"url";s:26:"admin/users/personalaction";s:4:"name";s:18:"个体认证审核";s:8:"isParent";b:1;s:6:"menuId";i:227;}}s:25:"admin/users/companyreview";a:1:{s:9:"HZRZSH_00";a:5:{s:4:"code";s:9:"HZRZSH_00";s:3:"url";s:25:"admin/users/companyreview";s:4:"name";s:18:"合作认证列表";s:8:"isParent";b:1;s:6:"menuId";i:228;}}s:28:"admin/users/getconpanyreview";a:1:{s:9:"HZRZSH_00";a:5:{s:4:"code";s:9:"HZRZSH_00";s:3:"url";s:28:"admin/users/getconpanyreview";s:4:"name";s:18:"合作认证列表";s:8:"isParent";b:0;s:6:"menuId";i:228;}}s:25:"admin/users/companyaction";a:1:{s:9:"HZRZSH_01";a:5:{s:4:"code";s:9:"HZRZSH_01";s:3:"url";s:25:"admin/users/companyaction";s:4:"name";s:18:"个体认证审核";s:8:"isParent";b:1;s:6:"menuId";i:228;}}s:26:"admin/users/authfamilylist";a:1:{s:9:"GTRZLB_02";a:5:{s:4:"code";s:9:"GTRZLB_02";s:3:"url";s:26:"admin/users/authfamilylist";s:4:"name";s:25:"亲人认证/报备列表";s:8:"isParent";b:1;s:6:"menuId";i:227;}}s:27:"admin/users/authcompanylist";a:1:{s:9:"HZRZSH_02";a:5:{s:4:"code";s:9:"HZRZSH_02";s:3:"url";s:27:"admin/users/authcompanylist";s:4:"name";s:15:"合作人认证";s:8:"isParent";b:1;s:6:"menuId";i:228;}}s:27:"admin/users/authcompanybank";a:1:{s:9:"HZRZSH_03";a:5:{s:4:"code";s:9:"HZRZSH_03";s:3:"url";s:27:"admin/users/authcompanybank";s:4:"name";s:18:"合作人银行卡";s:8:"isParent";b:1;s:6:"menuId";i:228;}}s:26:"admin/users/userupdatelist";a:1:{s:7:"SQSJ_00";a:5:{s:4:"code";s:7:"SQSJ_00";s:3:"url";s:26:"admin/users/userupdatelist";s:4:"name";s:18:"申请升级列表";s:8:"isParent";b:1;s:6:"menuId";i:229;}}s:29:"admin/users/getuserupdatelist";a:1:{s:7:"SQSJ_00";a:5:{s:4:"code";s:7:"SQSJ_00";s:3:"url";s:29:"admin/users/getuserupdatelist";s:4:"name";s:18:"申请升级列表";s:8:"isParent";b:0;s:6:"menuId";i:229;}}s:25:"admin/users/setuserupdate";a:1:{s:7:"SQSJ_01";a:5:{s:4:"code";s:7:"SQSJ_01";s:3:"url";s:25:"admin/users/setuserupdate";s:4:"name";s:18:"申请升级操作";s:8:"isParent";b:1;s:6:"menuId";i:229;}}s:22:"/addon/cron-cron-index";a:1:{s:12:"CRON_JHRW_00";a:5:{s:4:"code";s:12:"CRON_JHRW_00";s:3:"url";s:22:"/addon/cron-cron-index";s:4:"name";s:18:"查看计划任务";s:8:"isParent";b:1;s:6:"menuId";i:230;}}s:26:"/addon/cron-cron-pagequery";a:1:{s:12:"CRON_JHRW_00";a:5:{s:4:"code";s:12:"CRON_JHRW_00";s:3:"url";s:26:"/addon/cron-cron-pagequery";s:4:"name";s:18:"查看计划任务";s:8:"isParent";b:0;s:6:"menuId";i:230;}}s:23:"/addon/cron-cron-toedit";a:1:{s:12:"CRON_JHRW_04";a:5:{s:4:"code";s:12:"CRON_JHRW_04";s:3:"url";s:23:"/addon/cron-cron-toedit";s:4:"name";s:18:"操作计划任务";s:8:"isParent";b:1;s:6:"menuId";i:230;}}s:21:"/addon/cron-cron-edit";a:1:{s:12:"CRON_JHRW_04";a:5:{s:4:"code";s:12:"CRON_JHRW_04";s:3:"url";s:21:"/addon/cron-cron-edit";s:4:"name";s:18:"操作计划任务";s:8:"isParent";b:0;s:6:"menuId";i:230;}}s:35:"/addon/cron-cron-changeenablestatus";a:1:{s:12:"CRON_JHRW_04";a:5:{s:4:"code";s:12:"CRON_JHRW_04";s:3:"url";s:35:"/addon/cron-cron-changeenablestatus";s:4:"name";s:18:"操作计划任务";s:8:"isParent";b:0;s:6:"menuId";i:230;}}s:24:"/addon/cron-cron-runcron";a:1:{s:12:"CRON_JHRW_04";a:5:{s:4:"code";s:12:"CRON_JHRW_04";s:3:"url";s:24:"/addon/cron-cron-runcron";s:4:"name";s:18:"操作计划任务";s:8:"isParent";b:0;s:6:"menuId";i:230;}}s:24:"admin/orders/certificate";a:1:{s:7:"PZCK_00";a:5:{s:4:"code";s:7:"PZCK_00";s:3:"url";s:24:"admin/orders/certificate";s:4:"name";s:12:"凭证查看";s:8:"isParent";b:1;s:6:"menuId";i:231;}}s:27:"admin/orders/getcertificate";a:1:{s:7:"PZCK_00";a:5:{s:4:"code";s:7:"PZCK_00";s:3:"url";s:27:"admin/orders/getcertificate";s:4:"name";s:12:"凭证查看";s:8:"isParent";b:0;s:6:"menuId";i:231;}}s:27:"admin/orders/certificateset";a:1:{s:7:"PZCZ_00";a:5:{s:4:"code";s:7:"PZCZ_00";s:3:"url";s:27:"admin/orders/certificateset";s:4:"name";s:12:"凭证操作";s:8:"isParent";b:1;s:6:"menuId";i:231;}}s:26:"admin/cashdraws/viewreport";a:1:{s:7:"CWBB_00";a:5:{s:4:"code";s:7:"CWBB_00";s:3:"url";s:26:"admin/cashdraws/viewreport";s:4:"name";s:18:"查看财务报表";s:8:"isParent";b:1;s:6:"menuId";i:232;}}s:25:"admin/cashdraws/setreport";a:1:{s:7:"CWBB_01";a:5:{s:4:"code";s:7:"CWBB_01";s:3:"url";s:25:"admin/cashdraws/setreport";s:4:"name";s:18:"修改财务报表";s:8:"isParent";b:1;s:6:"menuId";i:232;}}s:29:"admin/cashdraws/getmobilecode";a:1:{s:7:"CWBB_01";a:5:{s:4:"code";s:7:"CWBB_01";s:3:"url";s:29:"admin/cashdraws/getmobilecode";s:4:"name";s:18:"修改财务报表";s:8:"isParent";b:0;s:6:"menuId";i:232;}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/ad/82a85b730ebf1e57e6da4dc731ec2a.php b/runtime/cache/WSTMART_/ad/82a85b730ebf1e57e6da4dc731ec2a.php new file mode 100644 index 0000000..fded4a6 --- /dev/null +++ b/runtime/cache/WSTMART_/ad/82a85b730ebf1e57e6da4dc731ec2a.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +s:4:"1.00"; \ No newline at end of file diff --git a/runtime/cache/WSTMART_/b5/d129438c20b9b51241323acb33f06d.php b/runtime/cache/WSTMART_/b5/d129438c20b9b51241323acb33f06d.php new file mode 100644 index 0000000..7bf7bd4 --- /dev/null +++ b/runtime/cache/WSTMART_/b5/d129438c20b9b51241323acb33f06d.php @@ -0,0 +1,4 @@ +<?php +//000031536000 + exit();?> +a:31:{s:16:"home/index/index";s:5:"index";s:16:"home/goods/lists";s:14:"category-<cat>";s:17:"home/goods/search";s:6:"search";s:17:"home/goods/detail";s:10:"goods-<id>";s:17:"home/brands/index";s:6:"brands";s:21:"home/shops/shopstreet";s:6:"street";s:20:"home/helpcenter/view";s:7:"service";s:14:"home/news/view";s:4:"news";s:15:"home/news/nlist";s:8:"newscats";s:16:"home/users/login";s:5:"login";s:17:"home/users/regist";s:8:"register";s:21:"home/users/forgetpass";s:6:"forget";s:22:"home/users/forgetpasst";s:12:"forget-step1";s:22:"home/users/forgetpassf";s:14:"forget-success";s:20:"home/users/resetpass";s:12:"forget-step3";s:16:"home/shops/login";s:10:"shop-login";s:19:"home/shops/selfshop";s:8:"selfshop";s:15:"home/shops/home";s:13:"shop-<shopId>";s:21:"mobile/shops/selfshop";s:9:"mselfshop";s:19:"mobile/brands/index";s:7:"mbrands";s:23:"mobile/shops/shopstreet";s:7:"mstreet";s:18:"mobile/users/login";s:6:"mlogin";s:23:"mobile/users/toregister";s:9:"mregister";s:23:"mobile/users/forgetpass";s:7:"mforget";s:19:"mobile/goods/detail";s:16:"mgoods-<goodsId>";s:18:"mobile/shops/index";s:15:"mshops-<shopId>";s:17:"mobile/shops/home";s:16:"mhshops-<shopId>";s:18:"mobile/goods/lists";s:5:"mlist";s:16:"mobile/news/view";s:5:"mnews";s:22:"mobile/goodscats/index";s:9:"mcategoty";s:26:"mobile/shops/shopgoodslist";s:10:"mshopgoods";} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/ba/eb0e3be5b3e9d8a2714f32348b62ee.php b/runtime/cache/WSTMART_/ba/eb0e3be5b3e9d8a2714f32348b62ee.php new file mode 100644 index 0000000..2624a98 --- /dev/null +++ b/runtime/cache/WSTMART_/ba/eb0e3be5b3e9d8a2714f32348b62ee.php @@ -0,0 +1,4 @@ +<?php +//000000003600 + exit();?> +a:5:{s:5:"Total";i:245;s:7:"PerPage";i:10;s:11:"CurrentPage";i:1;s:9:"TotalPage";i:25;s:4:"Rows";a:10:{i:0;a:6:{s:7:"goodsId";i:315;s:9:"goodsName";s:18:"脉克能量鞋垫";s:8:"goodsImg";s:37:"upload/test/2019-08/1567070704524.jpg";s:9:"shopPrice";s:6:"600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:1;a:6:{s:7:"goodsId";i:138;s:9:"goodsName";s:18:"能量酵素果冻";s:8:"goodsImg";s:37:"upload/test/2019-06/1560169121970.jpg";s:9:"shopPrice";s:4:"6.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:2;a:6:{s:7:"goodsId";i:135;s:9:"goodsName";s:21:"能量宝石小火锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139634080.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:3;a:6:{s:7:"goodsId";i:134;s:9:"goodsName";s:18:"能量宝石煎锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139485542.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:4;a:6:{s:7:"goodsId";i:201;s:9:"goodsName";s:15:"贝壳粉纯浆";s:8:"goodsImg";s:37:"upload/test/2019-07/1563089001697.jpg";s:9:"shopPrice";s:7:"1600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:45;}i:5;a:6:{s:7:"goodsId";i:187;s:9:"goodsName";s:15:"五雷掌拍打";s:8:"goodsImg";s:37:"upload/test/2019-07/1562124700330.jpg";s:9:"shopPrice";s:6:"500.00";s:7:"saleNum";i:4;s:12:"discountRate";i:40;}i:6;a:6:{s:7:"goodsId";i:183;s:9:"goodsName";s:39:"万多水晶冰川晚收甜白葡萄酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759953897.jpg";s:9:"shopPrice";s:5:"98.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:7;a:6:{s:7:"goodsId";i:182;s:9:"goodsName";s:18:"气泡酒炫彩酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759486258.jpg";s:9:"shopPrice";s:6:"108.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:8;a:6:{s:7:"goodsId";i:181;s:9:"goodsName";s:32:"2017蜂鸟珍藏 赤霞珠干红";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758962936.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:9;a:6:{s:7:"goodsId";i:180;s:9:"goodsName";s:22:"思念干红 、干白";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758306230.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/bb/db8a7fe67fca6145529f364b7a5dfb.php b/runtime/cache/WSTMART_/bb/db8a7fe67fca6145529f364b7a5dfb.php new file mode 100644 index 0000000..f4dc938 --- /dev/null +++ b/runtime/cache/WSTMART_/bb/db8a7fe67fca6145529f364b7a5dfb.php @@ -0,0 +1,4 @@ +<?php +//000000086400 + exit();?> +a:0:{} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/d5/ed68fc0e77d4248f3bcd9b75265deb.php b/runtime/cache/WSTMART_/d5/ed68fc0e77d4248f3bcd9b75265deb.php new file mode 100644 index 0000000..0c1d4cf --- /dev/null +++ b/runtime/cache/WSTMART_/d5/ed68fc0e77d4248f3bcd9b75265deb.php @@ -0,0 +1,4 @@ +<?php +//000000000000 + exit();?> +a:3:{i:112;s:6:"Kuaidi";i:113;s:4:"Cron";i:122;s:5:"Dysms";} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/da/f22c0385511dfa68534bfc9a8c6bfb.php b/runtime/cache/WSTMART_/da/f22c0385511dfa68534bfc9a8c6bfb.php new file mode 100644 index 0000000..acead4e --- /dev/null +++ b/runtime/cache/WSTMART_/da/f22c0385511dfa68534bfc9a8c6bfb.php @@ -0,0 +1,4 @@ +<?php +//000000086400 + exit();?> +a:2:{i:0;a:7:{s:4:"adId";i:4;s:6:"adName";s:4:"测2";s:5:"adURL";s:0:"";s:10:"targetType";i:1;s:6:"adFile";s:78:"upload/adspic/2019-04/5cc59d5d18751.png?x-oss-process=image/resize,h_750,w_750";s:13:"positionWidth";i:750;s:14:"positionHeight";i:500;}i:1;a:7:{s:4:"adId";i:3;s:6:"adName";s:4:"测1";s:5:"adURL";s:0:"";s:10:"targetType";i:1;s:6:"adFile";s:78:"upload/adspic/2019-04/5cc59d910fc1a.jpg?x-oss-process=image/resize,h_750,w_750";s:13:"positionWidth";i:750;s:14:"positionHeight";i:500;}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/db/bb4394ac375e2afcef3e384340e6c9.php b/runtime/cache/WSTMART_/db/bb4394ac375e2afcef3e384340e6c9.php new file mode 100644 index 0000000..2624a98 --- /dev/null +++ b/runtime/cache/WSTMART_/db/bb4394ac375e2afcef3e384340e6c9.php @@ -0,0 +1,4 @@ +<?php +//000000003600 + exit();?> +a:5:{s:5:"Total";i:245;s:7:"PerPage";i:10;s:11:"CurrentPage";i:1;s:9:"TotalPage";i:25;s:4:"Rows";a:10:{i:0;a:6:{s:7:"goodsId";i:315;s:9:"goodsName";s:18:"脉克能量鞋垫";s:8:"goodsImg";s:37:"upload/test/2019-08/1567070704524.jpg";s:9:"shopPrice";s:6:"600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:1;a:6:{s:7:"goodsId";i:138;s:9:"goodsName";s:18:"能量酵素果冻";s:8:"goodsImg";s:37:"upload/test/2019-06/1560169121970.jpg";s:9:"shopPrice";s:4:"6.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:2;a:6:{s:7:"goodsId";i:135;s:9:"goodsName";s:21:"能量宝石小火锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139634080.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:3;a:6:{s:7:"goodsId";i:134;s:9:"goodsName";s:18:"能量宝石煎锅";s:8:"goodsImg";s:37:"upload/test/2019-06/1560139485542.jpg";s:9:"shopPrice";s:7:"2001.00";s:7:"saleNum";i:0;s:12:"discountRate";i:50;}i:4;a:6:{s:7:"goodsId";i:201;s:9:"goodsName";s:15:"贝壳粉纯浆";s:8:"goodsImg";s:37:"upload/test/2019-07/1563089001697.jpg";s:9:"shopPrice";s:7:"1600.00";s:7:"saleNum";i:0;s:12:"discountRate";i:45;}i:5;a:6:{s:7:"goodsId";i:187;s:9:"goodsName";s:15:"五雷掌拍打";s:8:"goodsImg";s:37:"upload/test/2019-07/1562124700330.jpg";s:9:"shopPrice";s:6:"500.00";s:7:"saleNum";i:4;s:12:"discountRate";i:40;}i:6;a:6:{s:7:"goodsId";i:183;s:9:"goodsName";s:39:"万多水晶冰川晚收甜白葡萄酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759953897.jpg";s:9:"shopPrice";s:5:"98.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:7;a:6:{s:7:"goodsId";i:182;s:9:"goodsName";s:18:"气泡酒炫彩酒";s:8:"goodsImg";s:37:"upload/test/2019-06/1561759486258.jpg";s:9:"shopPrice";s:6:"108.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:8;a:6:{s:7:"goodsId";i:181;s:9:"goodsName";s:32:"2017蜂鸟珍藏 赤霞珠干红";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758962936.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}i:9;a:6:{s:7:"goodsId";i:180;s:9:"goodsName";s:22:"思念干红 、干白";s:8:"goodsImg";s:37:"upload/test/2019-06/1561758306230.jpg";s:9:"shopPrice";s:6:"138.00";s:7:"saleNum";i:0;s:12:"discountRate";i:40;}}} \ No newline at end of file diff --git a/runtime/cache/WSTMART_/f3/1486b74c5d07ee66562cacaba04541.php b/runtime/cache/WSTMART_/f3/1486b74c5d07ee66562cacaba04541.php new file mode 100644 index 0000000..00b112c --- /dev/null +++ b/runtime/cache/WSTMART_/f3/1486b74c5d07ee66562cacaba04541.php @@ -0,0 +1,4 @@ +<?php +//000002592000 + exit();?> +i:1; \ No newline at end of file diff --git a/runtime/log/201909/06.log b/runtime/log/201909/06.log new file mode 100644 index 0000000..5ea49f2 --- /dev/null +++ b/runtime/log/201909/06.log @@ -0,0 +1,1304 @@ +--------------------------------------------------------------- +[ 2019-09-06T23:33:30+08:00 ] 192.168.3.120 117.136.82.236 POST /app/Goods/pageQuery +[ info ] qlg.tsgz.moe:233/app/Goods/pageQuery [运行时间:0.223474s][吞吐率:4.47req/s] [内存消耗:4,183.98kb] [文件加载:60] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'Goods', + 2 => 'pageQuery', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '80', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'pagesize' => '10', + 'page' => '1', + 'condition' => '2', + 'desc' => '0', + 'keyword' => '花生油', + 'from' => '3', +) +[ info ] [ CACHE ] INIT File +[ info ] [ DB ] INIT mysql +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.098393s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.024716s ] +[ info ] [ RUN ] wstmart\app\controller\Goods->pageQuery[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Goods.php ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003675s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_hooks` [ RunTime:0.003524s ] +[ sql ] [ SQL ] SELECT `name`,`addons` FROM `hyh_hooks` WHERE ( addons != '' ) [ RunTime:0.002704s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_addons` [ RunTime:0.003625s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Dysms') AND `dataFlag` = 1 [ RunTime:0.002290s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Kuaidi') AND `dataFlag` = 1 [ RunTime:0.001747s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Kuaidi') AND `dataFlag` = 1 [ RunTime:0.001770s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Kuaidi') AND `dataFlag` = 1 [ RunTime:0.001638s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Kuaidi') AND `dataFlag` = 1 [ RunTime:0.001625s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Cron') AND `dataFlag` = 1 [ RunTime:0.002085s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Kuaidi') AND `dataFlag` = 1 [ RunTime:0.001646s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Hyhcouponset') AND `dataFlag` = 1 [ RunTime:0.001602s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE `status` = 1 AND `name` IN ('Hyhcouponset') AND `dataFlag` = 1 [ RunTime:0.001869s ] +[ sql ] [ SQL ] SELECT `addonId`,`name` FROM `hyh_addons` WHERE ( status =1 and dataFlag = 1 ) [ RunTime:0.001840s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_sys_configs` [ RunTime:0.003492s ] +[ sql ] [ SQL ] SELECT `fieldCode`,`fieldValue` FROM `hyh_sys_configs` [ RunTime:0.002315s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_styles` [ RunTime:0.003126s ] +[ sql ] [ SQL ] SELECT `styleSys`,`stylePath`,`id` FROM `hyh_styles` WHERE `isUse` = 1 [ RunTime:0.001764s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_datas` [ RunTime:0.003264s ] +[ sql ] [ SQL ] SELECT `dataVal` FROM `hyh_datas` WHERE `catId` = 3 [ RunTime:0.001918s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.002921s ] +[ sql ] [ SQL ] SELECT `fieldValue` FROM `hyh_data_configs` WHERE `fieldCode` = 'discountRateGtToHelpShopping' LIMIT 1 [ RunTime:0.001655s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:34+08:00 ] 192.168.3.120 117.136.82.236 POST /app/Goods/pageQuery +[ info ] qlg.tsgz.moe:233/app/Goods/pageQuery [运行时间:0.145641s][吞吐率:6.87req/s] [内存消耗:4,190.20kb] [文件加载:58] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'Goods', + 2 => 'pageQuery', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '85', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'page' => '2', + 'pagesize' => '10', + 'condition' => '2', + 'desc' => '0', + 'keyword' => '花生油', + 'goodsType' => '2', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005451s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001262s ] +[ info ] [ RUN ] wstmart\app\controller\Goods->pageQuery[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Goods.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003544s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.005335s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` `g` INNER JOIN `hyh_shops` `s` ON `g`.`shopId`=`s`.`shopId` WHERE `goodsStatus` = 1 AND `g`.`dataFlag` = 1 AND `isSale` = 1 AND `goodsName` LIKE '%花生油%' AND `discountRate` >= 0 LIMIT 1 [ RunTime:0.003873s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`saleNum`,`shopPrice`,`marketPrice`,`isSpec`,`goodsImg`,`appraiseNum`,`visitNum`,`s`.`shopId`,`shopName`,`isSelf`,`isFreeShipping`,`gallery` FROM `hyh_goods` `g` INNER JOIN `hyh_shops` `s` ON `g`.`shopId`=`s`.`shopId` WHERE `goodsStatus` = 1 AND `g`.`dataFlag` = 1 AND `isSale` = 1 AND `goodsName` LIKE '%花生油%' AND `discountRate` >= 0 ORDER BY visitNum desc,goodsId asc LIMIT 10,10 [ RunTime:0.004596s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getGoods +[ info ] qlg.tsgz.moe:233/app/shopping/getGoods [运行时间:0.169380s][吞吐率:5.90req/s] [内存消耗:3,999.63kb] [文件加载:56] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getGoods', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '24', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'type' => '1', + 'page' => '1', + 'pagesize' => '5', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005985s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001233s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getGoods[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.002744s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.003756s ] +[ sql ] [ SQL ] SELECT `fieldValue` FROM `hyh_data_configs` WHERE `fieldCode` = 'discountRateGtToShopping' LIMIT 1 [ RunTime:0.001536s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.012216s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 12 LIMIT 1 [ RunTime:0.002628s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`goodsImg`,`shopPrice`,`saleNum`,`discountRate` FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 12 ORDER BY discountRate DESC,goodsId DESC LIMIT 0,10 [ RunTime:0.002815s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/index/getHotGoods +[ info ] qlg.tsgz.moe:233/app/index/getHotGoods [运行时间:0.173820s][吞吐率:5.75req/s] [内存消耗:4,062.46kb] [文件加载:57] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'index', + 2 => 'getHotGoods', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '18', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'page' => '1', + 'pagesize' => '10', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.004574s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001059s ] +[ info ] [ RUN ] wstmart\app\controller\Index->getHotGoods[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Index.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.011208s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.007768s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 LIMIT 1 [ RunTime:0.002295s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`goodsImg`,`shopPrice`,`saleNum`,`discountRate` FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 ORDER BY discountRate DESC,goodsId DESC LIMIT 0,10 [ RunTime:0.002747s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getCarousel +[ info ] qlg.tsgz.moe:233/app/shopping/getCarousel [运行时间:0.192009s][吞吐率:5.21req/s] [内存消耗:3,816.71kb] [文件加载:53] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getCarousel', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '0', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', + 'content-type' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.013665s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.010962s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getCarousel[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004957s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_ads` [ RunTime:0.005996s ] +[ sql ] [ SQL ] SELECT `adId`,`adName`,`adURL`,`targetType`,`adFile`,`positionWidth`,`positionHeight` FROM `hyh_ads` `a` LEFT JOIN `hyh_ad_positions` `ap` ON `a`.`adPositionId`=ap.positionId and ap.dataFlag=1 WHERE ( a.dataFlag=1 and ap.positionCode='ads-qlgshopping' and adStartDate<= '2019-09-06' and adEndDate>='2019-09-06' ) ORDER BY adSort DESC LIMIT 6 [ RunTime:0.005764s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/appport/appBanner +[ info ] qlg.tsgz.moe:233/app/appport/appBanner [运行时间:0.221975s][吞吐率:4.51req/s] [内存消耗:3,787.19kb] [文件加载:52] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'appport', + 2 => 'appBanner', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '0', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', + 'content-type' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.013047s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.002826s ] +[ info ] [ RUN ] wstmart\app\controller\Appport->appBanner[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Appport.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.010484s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_ads` [ RunTime:0.003635s ] +[ sql ] [ SQL ] SELECT `adId`,`adName`,`adURL`,`targetType`,`adFile`,`positionWidth`,`positionHeight` FROM `hyh_ads` `a` LEFT JOIN `hyh_ad_positions` `ap` ON `a`.`adPositionId`=ap.positionId and ap.dataFlag=1 WHERE ( a.dataFlag=1 and ap.positionCode='app_new_top_banner' and adStartDate<= '2019-09-06' and adEndDate>='2019-09-06' ) ORDER BY adSort DESC LIMIT 8 [ RunTime:0.001991s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getGoods +[ info ] qlg.tsgz.moe:233/app/shopping/getGoods [运行时间:0.198705s][吞吐率:5.03req/s] [内存消耗:3,999.57kb] [文件加载:56] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getGoods', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '24', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'type' => '2', + 'page' => '1', + 'pagesize' => '5', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.004787s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001104s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getGoods[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004690s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.007515s ] +[ sql ] [ SQL ] SELECT `fieldValue` FROM `hyh_data_configs` WHERE `fieldCode` = 'discountRateGtToHelp' LIMIT 1 [ RunTime:0.001845s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.003280s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 1 LIMIT 1 [ RunTime:0.003184s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`goodsImg`,`shopPrice`,`saleNum`,`discountRate` FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 1 ORDER BY discountRate DESC,goodsId DESC LIMIT 0,10 [ RunTime:0.003135s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getGoods +[ info ] qlg.tsgz.moe:233/app/shopping/getGoods [运行时间:0.227149s][吞吐率:4.40req/s] [内存消耗:3,999.51kb] [文件加载:56] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getGoods', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '24', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'type' => '3', + 'page' => '1', + 'pagesize' => '5', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.011260s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001177s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getGoods[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004759s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.002872s ] +[ sql ] [ SQL ] SELECT `fieldValue` FROM `hyh_data_configs` WHERE `fieldCode` = 'discountRateGtToHelp' LIMIT 1 [ RunTime:0.003204s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.003402s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 1 LIMIT 1 [ RunTime:0.002601s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`goodsImg`,`shopPrice`,`saleNum`,`discountRate` FROM `hyh_goods` WHERE `isSale` = 1 AND `dataFlag` = 1 AND `goodsStatus` = 1 AND `discountRate` >= 1 ORDER BY discountRate DESC,goodsId DESC LIMIT 0,10 [ RunTime:0.004775s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getHelpShopCarousel +[ info ] qlg.tsgz.moe:233/app/shopping/getHelpShopCarousel [运行时间:0.072065s][吞吐率:13.88req/s] [内存消耗:2,480.83kb] [文件加载:50] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getHelpShopCarousel', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '0', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', + 'content-type' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.004985s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001000s ] +[ info ] [ LOG ] INIT File +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getHelpCarousel +[ info ] qlg.tsgz.moe:233/app/shopping/getHelpCarousel [运行时间:0.116636s][吞吐率:8.57req/s] [内存消耗:3,815.43kb] [文件加载:53] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getHelpCarousel', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '0', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', + 'content-type' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005299s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001224s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getHelpCarousel[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004192s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_ads` [ RunTime:0.002963s ] +[ sql ] [ SQL ] SELECT `adId`,`adName`,`adURL`,`targetType`,`adFile`,`positionWidth`,`positionHeight` FROM `hyh_ads` `a` LEFT JOIN `hyh_ad_positions` `ap` ON `a`.`adPositionId`=ap.positionId and ap.dataFlag=1 WHERE ( a.dataFlag=1 and ap.positionCode='ads-qlghelp' and adStartDate<= '2019-09-06' and adEndDate>='2019-09-06' ) ORDER BY adSort DESC LIMIT 6 [ RunTime:0.002363s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/users/getIndex +[ info ] qlg.tsgz.moe:233/app/users/getIndex [运行时间:0.130912s][吞吐率:7.64req/s] [内存消耗:3,587.76kb] [文件加载:51] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'users', + 2 => 'getIndex', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '0', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', + 'content-type' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005886s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001364s ] +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003135s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_users` [ RunTime:0.003349s ] +[ sql ] [ SQL ] SELECT * FROM `hyh_users` WHERE `token` = 'null' LIMIT 1 [ RunTime:0.003122s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getHelpSaleShops +[ info ] qlg.tsgz.moe:233/app/shopping/getHelpSaleShops [运行时间:0.094882s][吞吐率:10.54req/s] [内存消耗:2,481.57kb] [文件加载:50] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getHelpSaleShops', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '56', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'shopType' => '3', + 'page' => '1', + 'perPage' => '5', + 'lat' => '30.505053', + 'lng' => '104.080702', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005641s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001240s ] +[ info ] [ LOG ] INIT File +--------------------------------------------------------------- +[ 2019-09-06T23:33:58+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getShops +[ info ] qlg.tsgz.moe:233/app/shopping/getShops [运行时间:0.161705s][吞吐率:6.18req/s] [内存消耗:3,999.13kb] [文件加载:56] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getShops', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '56', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'shopType' => '1', + 'page' => '1', + 'perPage' => '5', + 'lat' => '30.505053', + 'lng' => '104.080702', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.006546s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001504s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getShops[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003139s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_shops` [ RunTime:0.004809s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM hyh_shops s WHERE `s`.`dataFlag` = 1 AND `s`.`shopStatus` = 1 AND `s`.`status` = 1 AND `s`.`lat` BETWEEN 26.008444970406 AND 35.001661029594 AND `s`.`lng` BETWEEN 98.8612377734 AND 109.3001662266 LIMIT 1 [ RunTime:0.002110s ] +[ sql ] [ SQL ] SELECT `s`.`shopId`,`s`.`shopImg`,`s`.`shopName`,ROUND(12756.276*ASIN(SQRT(POW(SIN((30.505053*0.0174532925-lat*0.0174532925)/2),2)+ + COS(30.505053*0.0174532925)*COS(lat*0.0174532925)*POW(SIN((104.080702*0.0174532925-lng*0.0174532925)/2),2)))*1000) AS distance FROM hyh_shops s WHERE `s`.`dataFlag` = 1 AND `s`.`shopStatus` = 1 AND `s`.`status` = 1 AND `s`.`lat` BETWEEN 26.008444970406 AND 35.001661029594 AND `s`.`lng` BETWEEN 98.8612377734 AND 109.3001662266 ORDER BY distance ASC LIMIT 0,10 [ RunTime:0.002805s ] +--------------------------------------------------------------- +[ 2019-09-06T23:33:58+08:00 ] 192.168.3.120 117.136.82.236 POST /app/shopping/getHelpShops +[ info ] qlg.tsgz.moe:233/app/shopping/getHelpShops [运行时间:0.224391s][吞吐率:4.46req/s] [内存消耗:4,019.87kb] [文件加载:56] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'shopping', + 2 => 'getHelpShops', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '56', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'hyh-token' => 'null', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'shopType' => '1', + 'page' => '1', + 'perPage' => '5', + 'lat' => '30.505053', + 'lng' => '104.080702', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.006004s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001299s ] +[ info ] [ RUN ] wstmart\app\controller\Shopping->getHelpShops[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Shopping.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004835s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_shops` [ RunTime:0.006636s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM hyh_shops s WHERE `s`.`dataFlag` = 1 AND `s`.`shopStatus` = 1 AND `s`.`status` = 1 LIMIT 1 [ RunTime:0.001562s ] +[ sql ] [ SQL ] SELECT `s`.`shopId`,`s`.`shopImg`,`s`.`shopName`,`s`.`shopLevel`,ROUND(12756.276*ASIN(SQRT(POW(SIN((30.505053*0.0174532925-lat*0.0174532925)/2),2)+ + COS(30.505053*0.0174532925)*COS(lat*0.0174532925)*POW(SIN((104.080702*0.0174532925-lng*0.0174532925)/2),2)))*1000) AS distance FROM hyh_shops s WHERE `s`.`dataFlag` = 1 AND `s`.`shopStatus` = 1 AND `s`.`status` = 1 ORDER BY s.shopLevel ASC LIMIT 0,10 [ RunTime:0.002937s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 10 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002793s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 11 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002945s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 12 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002663s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 13 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002724s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 14 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002430s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 15 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.003479s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 16 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002699s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 17 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002884s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 18 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.003314s ] +[ sql ] [ SQL ] SELECT `g`.`goodsImg`,`g`.`shopPrice`,`g`.`goodsId`,`g`.`saleTime`,`g`.`discountRate` FROM `hyh_shops` `s` INNER JOIN `hyh_goods` `g` ON `s`.`shopId`=`g`.`shopId` WHERE `g`.`shopId` = 19 AND `g`.`dataFlag` = 1 AND `g`.`goodsStatus` = 1 AND `g`.`isSale` = 1 AND `discountRate` >= '1.00' ORDER BY saleNum DESC LIMIT 3 [ RunTime:0.002361s ] +--------------------------------------------------------------- +[ 2019-09-06T23:34:09+08:00 ] 192.168.3.120 117.136.82.236 POST /app/Goods/pageQuery +[ info ] qlg.tsgz.moe:233/app/Goods/pageQuery [运行时间:0.119001s][吞吐率:8.40req/s] [内存消耗:3,969.75kb] [文件加载:55] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'Goods', + 2 => 'pageQuery', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '80', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'pagesize' => '10', + 'page' => '1', + 'condition' => '2', + 'desc' => '0', + 'keyword' => '花生油', + 'from' => '3', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005380s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001258s ] +[ info ] [ RUN ] wstmart\app\controller\Goods->pageQuery[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Goods.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +--------------------------------------------------------------- +[ 2019-09-06T23:34:26+08:00 ] 192.168.3.120 117.136.82.236 POST /app/Goods/pageQuery +[ info ] qlg.tsgz.moe:233/app/Goods/pageQuery [运行时间:0.116968s][吞吐率:8.55req/s] [内存消耗:3,969.75kb] [文件加载:55] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'Goods', + 2 => 'pageQuery', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '80', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'pagesize' => '10', + 'page' => '1', + 'condition' => '2', + 'desc' => '0', + 'keyword' => '花生油', + 'from' => '3', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005397s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001230s ] +[ info ] [ RUN ] wstmart\app\controller\Goods->pageQuery[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Goods.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +--------------------------------------------------------------- +[ 2019-09-06T23:34:57+08:00 ] 192.168.3.120 117.136.82.236 POST /app/Goods/pageQuery +[ info ] qlg.tsgz.moe:233/app/Goods/pageQuery [运行时间:0.362294s][吞吐率:2.76req/s] [内存消耗:4,199.81kb] [文件加载:58] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'app', + 1 => 'Goods', + 2 => 'pageQuery', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '80', + 'accept' => 'application/json', + 'origin' => 'file://', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Linux; Android 9; MI 8 SE Build/PKQ1.181121.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36 Html5Plus/1.0 (Immersed/30.814816)', + 'content-type' => 'application/x-www-form-urlencoded', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', + 'cookie' => 'PHPSESSID=icemrprfh9u1m4qd6uec9fm2l6', +) +[ info ] [ PARAM ] array ( + 'pagesize' => '10', + 'page' => '1', + 'condition' => '2', + 'desc' => '0', + 'keyword' => '花生油', + 'from' => '3', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005424s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001259s ] +[ info ] [ RUN ] wstmart\app\controller\Goods->pageQuery[ /www/wwwroot/qlg.tsgz.moe/hyhproject/app/controller/Goods.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.215160s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_goods` [ RunTime:0.004434s ] +[ sql ] [ SQL ] SELECT COUNT(*) AS tp_count FROM `hyh_goods` `g` INNER JOIN `hyh_shops` `s` ON `g`.`shopId`=`s`.`shopId` WHERE `goodsStatus` = 1 AND `g`.`dataFlag` = 1 AND `isSale` = 1 AND `goodsName` LIKE '%花生油%' AND `discountRate` >= 12 LIMIT 1 [ RunTime:0.004895s ] +[ sql ] [ SQL ] SELECT `goodsId`,`goodsName`,`saleNum`,`shopPrice`,`marketPrice`,`isSpec`,`goodsImg`,`appraiseNum`,`visitNum`,`s`.`shopId`,`shopName`,`isSelf`,`isFreeShipping`,`gallery` FROM `hyh_goods` `g` INNER JOIN `hyh_shops` `s` ON `g`.`shopId`=`s`.`shopId` WHERE `goodsStatus` = 1 AND `g`.`dataFlag` = 1 AND `isSale` = 1 AND `goodsName` LIKE '%花生油%' AND `discountRate` >= 12 ORDER BY visitNum desc,goodsId asc LIMIT 0,10 [ RunTime:0.004579s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:08+08:00 ] 192.168.3.120 112.193.99.12 GET /admin/index/index.html +[ info ] qlg.tsgz.moe:233/admin/index/index.html [运行时间:0.413965s][吞吐率:2.42req/s] [内存消耗:5,301.32kb] [文件加载:68] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'admin', + 1 => 'index', + 2 => 'index', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'upgrade-insecure-requests' => '1', + 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', + 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', + 'referer' => 'http://qlg.tsgz.moe:233/admin/index/login.html?key=quanlianggongmall', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9', + 'cookie' => 'BT_PANEL_6=60809ae0-a155-4e5b-8ff1-4e09973f3c73.CSLuJ_1a7ayXGm8FIwPhyCg9nL0; request_token=154c4b116570df10fe05fe9150d107a3; order=id%20desc; force=0; memSize=3681; uploadSize=1073741824; rank=a; Path=/www/wwwroot; PHPSESSID=lpp3c0bn45oevjqaahkc5vdav1', + 'content-type' => '', + 'content-length' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005640s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001236s ] +[ info ] [ DB ] INIT mysql +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\InitConfig @module_init [ RunTime:0.143453s ] +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenLoginStatus @action_begin [ RunTime:0.004307s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenPrivilege @action_begin [ RunTime:0.000782s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenOperate @action_begin [ RunTime:0.000533s ] +[ info ] [ RUN ] wstmart\admin\controller\Index->index[ /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/controller/Index.php ] +[ info ] [ VIEW ] /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/index.html [ array ( + 0 => 'v', + 1 => 'sysMenus', +) ] +[ info ] [ BEHAVIOR ] Run \addons\cron\Cron @initCronHook [ RunTime:0.001980s ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003928s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_privileges` [ RunTime:0.002750s ] +[ sql ] [ SQL ] SELECT `menuId`,`privilegeName`,`privilegeCode`,`privilegeUrl`,`otherPrivilegeUrl` FROM `hyh_privileges` WHERE `dataFlag` = 1 [ RunTime:0.004550s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_menus` [ RunTime:0.006676s ] +[ sql ] [ SQL ] SELECT `m`.`menuId`,`m`.`menuName`,`privilegeUrl`,`m`.`parentId`,`m`.`menuIcon` FROM `hyh_menus` `m` LEFT JOIN `hyh_privileges` `p` ON `m`.`menuId`=p.menuId and isMenuPrivilege=1 and p.dataFlag=1 WHERE `m`.`dataFlag` = 1 AND `m`.`menuId` IN (2,3,4,1,5,11,13,24,19,20,34,6,35,7,42,31,30,21,9,8,18,29,39,38,22,23,45,46,41,47,50,51,52,53,33,54,55,56,49,62,63,64,71,72,74,73,75,77,76,85,86,93,168,169,185,188,215,227,228,229,230,231,232) ORDER BY `menuSort` asc [ RunTime:0.005800s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:08+08:00 ] 192.168.3.120 112.193.99.12 GET /admin/sysconfigs/index.html +[ info ] qlg.tsgz.moe:233/admin/sysconfigs/index.html [运行时间:0.267166s][吞吐率:3.74req/s] [内存消耗:5,245.84kb] [文件加载:69] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'admin', + 1 => 'sysconfigs', + 2 => 'index', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'upgrade-insecure-requests' => '1', + 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', + 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', + 'referer' => 'http://qlg.tsgz.moe:233/admin/index/index.html', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9', + 'cookie' => 'BT_PANEL_6=60809ae0-a155-4e5b-8ff1-4e09973f3c73.CSLuJ_1a7ayXGm8FIwPhyCg9nL0; request_token=154c4b116570df10fe05fe9150d107a3; order=id%20desc; force=0; memSize=3681; uploadSize=1073741824; rank=a; Path=/www/wwwroot; PHPSESSID=lpp3c0bn45oevjqaahkc5vdav1', + 'content-type' => '', + 'content-length' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005934s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001356s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\InitConfig @module_init [ RunTime:0.004826s ] +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenLoginStatus @action_begin [ RunTime:0.014714s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenPrivilege @action_begin [ RunTime:0.000910s ] +[ info ] [ DB ] INIT mysql +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenOperate @action_begin [ RunTime:0.058943s ] +[ info ] [ RUN ] wstmart\admin\controller\Sysconfigs->index[ /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/controller/Sysconfigs.php ] +[ info ] [ VIEW ] /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/edit.html [ array ( + 0 => 'v', + 1 => 'object', + 2 => 'list', + 3 => 'dataConfigs', +) ] +[ info ] [ BEHAVIOR ] Run \addons\cron\Cron @initCronHook [ RunTime:0.002628s ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003605s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_log_operates` [ RunTime:0.003310s ] +[ sql ] [ SQL ] INSERT INTO `hyh_log_operates` (`staffId` , `operateTime` , `menuId` , `operateDesc` , `content` , `operateUrl` , `operateIP`) VALUES (2 , '2019-09-06 23:35:08' , 9 , '查看商城配置' , '{\"s\":\"\\/admin\\/sysconfigs\\/index.html\"}' , '/admin/sysconfigs/index.html' , '112.193.99.12') [ RunTime:0.026352s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_sys_configs` [ RunTime:0.003423s ] +[ sql ] [ SQL ] SELECT `fieldCode`,`fieldValue` FROM `hyh_sys_configs` [ RunTime:0.002573s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_staffs` [ RunTime:0.003848s ] +[ sql ] [ SQL ] SELECT `staffId`,`staffName` FROM `hyh_staffs` WHERE `dataFlag` = 1 AND `staffStatus` = 1 ORDER BY `staffName` asc [ RunTime:0.002421s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.003260s ] +[ sql ] [ SQL ] SELECT * FROM `hyh_data_configs` [ RunTime:0.002040s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:09+08:00 ] 192.168.3.120 112.193.99.12 GET /admin/CronJobs/autoCancelNoPay.html +[ info ] qlg.tsgz.moe:233/admin/CronJobs/autoCancelNoPay.html [运行时间:0.146625s][吞吐率:6.82req/s] [内存消耗:4,542.14kb] [文件加载:60] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'admin', + 1 => 'CronJobs', + 2 => 'autoCancelNoPay', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'accept' => '*/*', + 'accept-encoding' => 'gzip', + 'content-type' => '', + 'content-length' => '', +) +[ info ] [ PARAM ] array ( +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005439s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001235s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\InitConfig @module_init [ RunTime:0.004712s ] +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenLoginStatus @action_begin [ RunTime:0.002790s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenPrivilege @action_begin [ RunTime:0.000757s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenOperate @action_begin [ RunTime:0.000591s ] +[ info ] [ RUN ] wstmart\admin\controller\Cronjobs->autoCancelNoPay[ /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/controller/Cronjobs.php ] +[ info ] [ DB ] INIT mysql +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003630s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_orders` [ RunTime:0.004568s ] +[ sql ] [ SQL ] SELECT `o`.`orderId`,`o`.`orderNo`,`o`.`userId`,`o`.`shopId`,`o`.`useScore`,s.userId shopUserId,`orderCode` FROM `hyh_orders` `o` LEFT JOIN `hyh_shops` `s` ON `o`.`shopId`=`s`.`shopId` WHERE ( o.createTime<'2019-09-05 23:35:09' and o.orderStatus=-2 and o.dataFlag=1 and o.payType=1 and o.isPay=0 ) [ RunTime:0.002534s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:09+08:00 ] 192.168.3.120 112.193.99.12 GET /addon/cron-cron-runCrons.html +[ info ] qlg.tsgz.moe:233/addon/cron-cron-runCrons.html [运行时间:1.017444s][吞吐率:0.98req/s] [内存消耗:4,440.60kb] [文件加载:60] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'method', + 'method' => + array ( + 0 => '\\think\\addons\\AddonsController', + 1 => 'execute', + ), + 'var' => + array ( + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', + 'accept' => 'image/webp,image/apng,image/*,*/*;q=0.8', + 'referer' => 'http://qlg.tsgz.moe:233/admin/index/index.html', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9', + 'cookie' => 'BT_PANEL_6=60809ae0-a155-4e5b-8ff1-4e09973f3c73.CSLuJ_1a7ayXGm8FIwPhyCg9nL0; request_token=154c4b116570df10fe05fe9150d107a3; order=id%20desc; force=0; memSize=3681; uploadSize=1073741824; rank=a; Path=/www/wwwroot; PHPSESSID=lpp3c0bn45oevjqaahkc5vdav1', + 'content-type' => '', + 'content-length' => '', +) +[ info ] [ PARAM ] array ( + 'route' => 'cron-cron-runCrons', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.006016s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001243s ] +[ info ] [ DB ] INIT mysql +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ RUN ] think\addons\AddonsController->execute[ /www/wwwroot/qlg.tsgz.moe/vendor/5ini99/think-addons/src/AddonsController.php ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.003155s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_addons` [ RunTime:0.002649s ] +[ sql ] [ SQL ] SELECT `status` FROM `hyh_addons` WHERE `name` = 'Cron' LIMIT 1 [ RunTime:0.001352s ] +[ sql ] [ SQL ] SELECT `status` FROM `hyh_addons` WHERE `name` = 'Cron' LIMIT 1 [ RunTime:0.002283s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_crons` [ RunTime:0.003431s ] +[ sql ] [ SQL ] SELECT * FROM `hyh_crons` WHERE `isEnable` = 1 [ RunTime:0.002657s ] +[ sql ] [ SQL ] UPDATE `hyh_crons` SET `isRunning`=1,`runTime`='2019-09-06 23:35:09',`nextTime`='2019-09-06 23:40:00' WHERE `id` = 2 [ RunTime:0.002303s ] +[ sql ] [ SQL ] UPDATE `hyh_crons` SET `isRunning`=0 WHERE `id` = 2 [ RunTime:0.001897s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:09+08:00 ] 192.168.3.120 112.193.99.12 GET /addon/cron-cron-runCrons.html +[ info ] qlg.tsgz.moe:233/addon/cron-cron-runCrons.html [运行时间:0.169692s][吞吐率:5.89req/s] [内存消耗:4,447.69kb] [文件加载:60] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'method', + 'method' => + array ( + 0 => '\\think\\addons\\AddonsController', + 1 => 'execute', + ), + 'var' => + array ( + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', + 'accept' => 'image/webp,image/apng,image/*,*/*;q=0.8', + 'referer' => 'http://qlg.tsgz.moe:233/admin/sysconfigs/index.html', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9', + 'cookie' => 'BT_PANEL_6=60809ae0-a155-4e5b-8ff1-4e09973f3c73.CSLuJ_1a7ayXGm8FIwPhyCg9nL0; request_token=154c4b116570df10fe05fe9150d107a3; order=id%20desc; force=0; memSize=3681; uploadSize=1073741824; rank=a; Path=/www/wwwroot; PHPSESSID=lpp3c0bn45oevjqaahkc5vdav1', + 'content-type' => '', + 'content-length' => '', +) +[ info ] [ PARAM ] array ( + 'route' => 'cron-cron-runCrons', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005570s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001249s ] +[ info ] [ DB ] INIT mysql +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ RUN ] think\addons\AddonsController->execute[ /www/wwwroot/qlg.tsgz.moe/vendor/5ini99/think-addons/src/AddonsController.php ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004941s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_addons` [ RunTime:0.003163s ] +[ sql ] [ SQL ] SELECT `status` FROM `hyh_addons` WHERE `name` = 'Cron' LIMIT 1 [ RunTime:0.002423s ] +[ sql ] [ SQL ] SELECT `status` FROM `hyh_addons` WHERE `name` = 'Cron' LIMIT 1 [ RunTime:0.003303s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_crons` [ RunTime:0.004427s ] +[ sql ] [ SQL ] SELECT * FROM `hyh_crons` WHERE `isEnable` = 1 [ RunTime:0.003715s ] +--------------------------------------------------------------- +[ 2019-09-06T23:35:17+08:00 ] 192.168.3.120 112.193.99.12 POST /admin/sysconfigs/edit.html +[ info ] qlg.tsgz.moe:233/admin/sysconfigs/edit.html [运行时间:0.695600s][吞吐率:1.44req/s] [内存消耗:4,894.98kb] [文件加载:64] +[ info ] [ LANG ] /www/wwwroot/qlg.tsgz.moe/thinkphp/lang/zh-cn.php +[ info ] [ ROUTE ] array ( + 'type' => 'module', + 'module' => + array ( + 0 => 'admin', + 1 => 'sysconfigs', + 2 => 'edit', + ), +) +[ info ] [ HEADER ] array ( + 'host' => 'qlg.tsgz.moe:233', + 'connection' => 'keep-alive', + 'content-length' => '2972', + 'accept' => '*/*', + 'origin' => 'http://qlg.tsgz.moe:233', + 'x-requested-with' => 'XMLHttpRequest', + 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', + 'content-type' => 'application/x-www-form-urlencoded; charset=UTF-8', + 'referer' => 'http://qlg.tsgz.moe:233/admin/sysconfigs/index.html', + 'accept-encoding' => 'gzip, deflate', + 'accept-language' => 'zh-CN,zh;q=0.9', + 'cookie' => 'BT_PANEL_6=60809ae0-a155-4e5b-8ff1-4e09973f3c73.CSLuJ_1a7ayXGm8FIwPhyCg9nL0; request_token=154c4b116570df10fe05fe9150d107a3; order=id%20desc; force=0; memSize=3681; uploadSize=1073741824; rank=a; Path=/www/wwwroot; PHPSESSID=lpp3c0bn45oevjqaahkc5vdav1', +) +[ info ] [ PARAM ] array ( + 0 => '50.00', + 1 => '100.00', + 2 => '100.00', + 3 => '100.00', + 4 => '0.10', + 5 => '99.00', + 6 => '90.00', + 7 => '0.50', + 8 => '0.05', + 9 => '13.00', + 10 => '0.01', + 11 => '10.00', + 12 => '0.00', + 13 => '20.00', + 14 => '0.00', + 15 => '0.01', + 16 => '80.00', + 17 => '10.00', + 18 => '0.00', + 19 => '20.00', + 20 => '0.00', + 21 => '100.00', + 22 => '6.00', + 23 => '2.00', + 24 => '10.00', + 25 => '50.00', + 26 => '20.00', + 27 => '0.00', + 28 => '12.00', + 29 => '1.00', + 30 => '30.00', + 31 => '99.00', + 32 => '9990.00', + 33 => '99.00', + 34 => '9990.00', + 35 => '99.00', + 36 => '9990.00', + 37 => '30', + 'isDataConfigs' => '1', + 'mailSmtp' => 'smtp.mxhichina.com', + 'mailPort' => '25', + 'mailAuth' => '1', + 'mailAddress' => 'hyh@heyuanhui.cn', + 'mailUserName' => 'hyh@heyuanhui.cn', + 'mailPassword' => 'Hsf4673995', + 'mailSendTitle' => '合源惠商城', + 'smsOpen' => '1', + 'smsLimit' => '10', + 'smsVerfy' => '1', + 'isOpenScorePay' => '', + 'scoreToMoney' => '1', + 'isOrderScore' => '', + 'moneyToScore' => '0.2', + 'isAppraisesScore' => '', + 'appraisesScore' => '5', + 'statementType' => '0', + 'scoreCashRatio' => '', + 'settlementStartMoney' => '', + 'signScoreSwitch' => '', + 'signScore0' => '5', + 'signScore1' => '10', + 'signScore2' => '15', + 'signScore3' => '20', + 'signScore4' => '25', + 'signScore5' => '30', + 'signScore6' => '30', + 'signScore7' => '30', + 'signScore8' => '30', + 'signScore9' => '30', + 'signScore10' => '30', + 'signScore11' => '30', + 'signScore12' => '30', + 'signScore13' => '30', + 'signScore14' => '30', + 'signScore15' => '30', + 'signScore16' => '30', + 'signScore17' => '30', + 'signScore18' => '30', + 'signScore19' => '30', + 'signScore20' => '30', + 'signScore21' => '30', + 'signScore22' => '30', + 'signScore23' => '30', + 'signScore24' => '30', + 'signScore25' => '30', + 'signScore26' => '30', + 'signScore27' => '30', + 'signScore28' => '30', + 'signScore29' => '30', + 'drawCashUserLimit' => '10', + 'drawCashShopLimit' => '10', + 'autoCancelNoPayDays' => '24', + 'autoReceiveDays' => '7', + 'autoAppraiseDays' => '7', + 'isCryptPwd' => '', + 'pwdPrivateKey' => '-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCbak4tYvmaxhVyMucxax/tgre8JuGgvBOKJCIp/S7qbdFRpvNW ++njYR97DK8Rsf2UrYPDoqI8PsjSwJJgqEf2OEzNOBlVfQRbWzEX8DtWEGRpiJHtL +p8CfYqRi6ytdD+W13XAfst6OMVYgzotqHKgcpDMfgdmjqy8QUfv5+z/TrwIDAQAB +AoGANs95/MXAM9aSL7FGGgamvvPv', + 'pwdModulusKey' => '9B6A4E2D62F99AC6157232E7316B1FED82B7BC26E1A0BC138A242229FD2EEA6DD151A6F356FA78D847DEC32BC46C7F652B60F0E8A88F0FB234B024982A11FD8E13334E06555F4116D6CC45FC0ED584191A62247B4BA7C09F62A462EB2B5D0FE5B5DD701FB2DE8E315620CE8B6A1CA81CA4331F81D9A3AB2F1051FBF9FB3FD3A', + 'watermarkPosition' => '0', + 'watermarkWord' => '', + 'watermarkSize' => '', + 'watermarkColor' => '', + 'watermarkTtf' => '', + 'watermarkFile' => '', + 'watermarkOpacity' => '50', + 'mallLogo' => 'upload/sysconfigs/2017-09/59af629c60a10.png', + 'shopLogo' => 'upload/sysconfigs/2017-09/59aa1692acbd0.png', + 'userLogo' => 'upload/sysconfigs/2016-10/5804800d5841e.png', + 'goodsLogo' => 'upload/sysconfigs/2018-01/5a504a84b3b0f.png', + 'seoMallTitle' => '全亮共', + 'seoMallKeywords' => '全亮共商城', + 'seoMallDesc' => '全亮共', + 'signScore' => '5,10,15,20,25,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,', + 'wxSubmitOrderTip' => '0', + 'smsSubmitOrderTip' => '0', + 'submitOrderTipUsers' => '', + 'wxPayOrderTip' => '0', + 'smsPayOrderTip' => '0', + 'payOrderTipUsers' => '', + 'wxCancelOrderTip' => '0', + 'smsCancelOrderTip' => '0', + 'cancelOrderTipUsers' => '', + 'wxRejectOrderTip' => '0', + 'smsRejectOrderTip' => '0', + 'rejectOrderTipUsers' => '', + 'wxRefundOrderTip' => '0', + 'smsRefundOrderTip' => '0', + 'refundOrderTipUsers' => '', + 'wxComplaintOrderTip' => '0', + 'smsComplaintOrderTip' => '0', + 'complaintOrderTipUsers' => '', + 'wxCashDrawsTip' => '0', + 'smsCashDrawsTip' => '0', + 'cashDrawsTipUsers' => '', +) +[ info ] [ CACHE ] INIT File +[ info ] [ BEHAVIOR ] Run Closure @app_begin [ RunTime:0.005256s ] +[ info ] [ BEHAVIOR ] Run wstmart\common\behavior\InitConfig @app_begin [ RunTime:0.001213s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\InitConfig @module_init [ RunTime:0.003895s ] +[ info ] [ SESSION ] INIT array ( + 'id' => '', + 'var_session_id' => '', + 'prefix' => 'hyh_', + 'type' => '', + 'auto_start' => true, +) +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenLoginStatus @action_begin [ RunTime:0.012072s ] +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenPrivilege @action_begin [ RunTime:0.000849s ] +[ info ] [ DB ] INIT mysql +[ info ] [ BEHAVIOR ] Run wstmart\admin\behavior\ListenOperate @action_begin [ RunTime:0.054365s ] +[ info ] [ RUN ] wstmart\admin\controller\Sysconfigs->edit[ /www/wwwroot/qlg.tsgz.moe/hyhproject/admin/controller/Sysconfigs.php ] +[ info ] [ LOG ] INIT File +[ sql ] [ DB ] CONNECT:[ UseTime:0.004943s ] mysql:host=qlg.tsgz.moe;port=3306;dbname=qlg_tsgz_moe;charset=utf8 +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_log_operates` [ RunTime:0.004009s ] +[ sql ] [ SQL ] INSERT INTO `hyh_log_operates` (`staffId` , `operateTime` , `menuId` , `operateDesc` , `content` , `operateUrl` , `operateIP`) VALUES (2 , '2019-09-06 23:35:16' , 9 , '编辑商城配置' , '{\"s\":\"\\/admin\\/sysconfigs\\/edit.html\",\"105\":\"50.00\",\"106\":\"100.00\",\"107\":\"100.00\",\"108\":\"100.00\",\"111\":\"0.10\",\"112\":\"99.00\",\"113\":\"90.00\",\"114\":\"0.50\",\"115\":\"0.05\",\"116\":\"13.00\",\"117\":\"0.01\",\"118\":\"10.00\",\"119\":\"0.00\",\"120\":\"20.00\",\"121\":\"0.00\",\"122\":\"0.01\",\"123\":\"80.00\",\"124\":\"10.00\",\"125\":\"0.00\",\"126\":\"20.00\",\"127\":\"0.00\",\"132\":\"100.00\",\"133\":\"6.00\",\"134\":\"2.00\",\"135\":\"10.00\",\"136\":\"50.00\",\"137\":\"20.00\",\"138\":\"0.00\",\"139\":\"12.00\",\"140\":\"1.00\",\"141\":\"30.00\",\"142\":\"99.00\",\"143\":\"9990.00\",\"144\":\"99.00\",\"145\":\"9990.00\",\"146\":\"99.00\",\"147\":\"9990.00\",\"148\":\"30\",\"isDataConfigs\":\"1\",\"mailSmtp\":\"smtp.mxhichina.com\",\"mailPort\":\"25\",\"mailAuth\":\"1\",\"mailAddress\":\"hyh@heyuanhui.cn\",\"mailUserName\":\"hyh@heyuanhui.cn\",\"mailPassword\":\"Hsf4673995\",\"mailSendTitle\":\"\\u5408\\u6e90\\u60e0\\u5546\\u57ce\",\"smsOpen\":\"1\",\"smsLimit\":\"10\",\"smsVerfy\":\"1\",\"isOpenScorePay\":\"\",\"scoreToMoney\":\"1\",\"isOrderScore\":\"\",\"moneyToScore\":\"0.2\",\"isAppraisesScore\":\"\",\"appraisesScore\":\"5\",\"statementType\":\"0\",\"scoreCashRatio\":\"\",\"settlementStartMoney\":\"\",\"signScoreSwitch\":\"\",\"signScore0\":\"5\",\"signScore1\":\"10\",\"signScore2\":\"15\",\"signScore3\":\"20\",\"signScore4\":\"25\",\"signScore5\":\"30\",\"signScore6\":\"30\",\"signScore7\":\"30\",\"signScore8\":\"30\",\"signScore9\":\"30\",\"signScore10\":\"30\",\"signScore11\":\"30\",\"signScore12\":\"30\",\"signScore13\":\"30\",\"signScore14\":\"30\",\"signScore15\":\"30\",\"signScore16\":\"30\",\"signScore17\":\"30\",\"signScore18\":\"30\",\"signScore19\":\"30\",\"signScore20\":\"30\",\"signScore21\":\"30\",\"signScore22\":\"30\",\"signScore23\":\"30\",\"signScore24\":\"30\",\"signScore25\":\"30\",\"signScore26\":\"30\",\"signScore27\":\"30\",\"signScore28\":\"30\",\"signScore29\":\"30\",\"drawCashUserLimit\":\"10\",\"drawCashShopLimit\":\"10\",\"autoCancelNoPayDays\":\"24\",\"autoReceiveDays\":\"7\",\"autoAppraiseDays\":\"7\",\"isCryptPwd\":\"\",\"pwdPrivateKey\":\"-----BEGIN RSA PRIVATE KEY-----\\nMIICWwIBAAKBgQCbak4tYvmaxhVyMucxax\\/tgre8JuGgvBOKJCIp\\/S7qbdFRpvNW\\n+njYR97DK8Rsf2UrYPDoqI8PsjSwJJgqEf2OEzNOBlVfQRbWzEX8DtWEGRpiJHtL\\np8CfYqRi6ytdD+W13XAfst6OMVYgzotqHKgcpDMfgdmjqy8QUfv5+z\\/TrwIDAQAB\\nAoGANs95\\/MXAM9aSL7FGGgamvvPv\",\"pwdModulusKey\":\"9B6A4E2D62F99AC6157232E7316B1FED82B7BC26E1A0BC138A242229FD2EEA6DD151A6F356FA78D847DEC32BC46C7F652B60F0E8A88F0FB234B024982A11FD8E13334E06555F4116D6CC45FC0ED584191A62247B4BA7C09F62A462EB2B5D0FE5B5DD701FB2DE8E315620CE8B6A1CA81CA4331F81D9A3AB2F1051FBF9FB3FD3A\",\"watermarkPosition\":\"0\",\"watermarkWord\":\"\",\"watermarkSize\":\"\",\"watermarkColor\":\"\",\"watermarkTtf\":\"\",\"watermarkFile\":\"\",\"watermarkOpacity\":\"50\",\"mallLogo\":\"upload\\/sysconfigs\\/2017-09\\/59af629c60a10.png\",\"shopLogo\":\"upload\\/sysconfigs\\/2017-09\\/59aa1692acbd0.png\",\"userLogo\":\"upload\\/sysconfigs\\/2016-10\\/5804800d5841e.png\",\"goodsLogo\":\"upload\\/sysconfigs\\/2018-01\\/5a504a84b3b0f.png\",\"seoMallTitle\":\"\\u5168\\u4eae\\u5171\",\"seoMallKeywords\":\"\\u5168\\u4eae\\u5171\\u5546\\u57ce\",\"seoMallDesc\":\"\\u5168\\u4eae\\u5171\",\"signScore\":\"5,10,15,20,25,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,\",\"wxSubmitOrderTip\":\"0\",\"smsSubmitOrderTip\":\"0\",\"submitOrderTipUsers\":\"\",\"wxPayOrderTip\":\"0\",\"smsPayOrderTip\":\"0\",\"payOrderTipUsers\":\"\",\"wxCancelOrderTip\":\"0\",\"smsCancelOrderTip\":\"0\",\"cancelOrderTipUsers\":\"\",\"wxRejectOrderTip\":\"0\",\"smsRejectOrderTip\":\"0\",\"rejectOrderTipUsers\":\"\",\"wxRefundOrderTip\":\"0\",\"smsRefundOrderTip\":\"0\",\"refundOrderTipUsers\":\"\",\"wxComplaintOrderTip\":\"0\",\"smsComplaintOrderTip\":\"0\",\"complaintOrderTipUsers\":\"\",\"wxCashDrawsTip\":\"0\",\"smsCashDrawsTip\":\"0\",\"cashDrawsTipUsers\":\"\"}' , '/admin/sysconfigs/edit.html' , '112.193.99.12') [ RunTime:0.022794s ] +[ sql ] [ SQL ] SHOW COLUMNS FROM `hyh_data_configs` [ RunTime:0.004363s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=50 WHERE `configId` = 105 [ RunTime:0.002593s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=100 WHERE `configId` = 106 [ RunTime:0.001307s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=100 WHERE `configId` = 107 [ RunTime:0.001367s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=100 WHERE `configId` = 108 [ RunTime:0.000812s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.1 WHERE `configId` = 111 [ RunTime:0.001594s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=99 WHERE `configId` = 112 [ RunTime:0.001629s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=90 WHERE `configId` = 113 [ RunTime:0.001604s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.5 WHERE `configId` = 114 [ RunTime:0.000785s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.05 WHERE `configId` = 115 [ RunTime:0.001399s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=13 WHERE `configId` = 116 [ RunTime:0.001342s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.01 WHERE `configId` = 117 [ RunTime:0.000687s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 118 [ RunTime:0.001359s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 119 [ RunTime:0.001328s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=20 WHERE `configId` = 120 [ RunTime:0.000687s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 121 [ RunTime:0.001514s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.01 WHERE `configId` = 122 [ RunTime:0.001386s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=80 WHERE `configId` = 123 [ RunTime:0.000728s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 124 [ RunTime:0.001713s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 125 [ RunTime:0.001497s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=20 WHERE `configId` = 126 [ RunTime:0.001546s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 127 [ RunTime:0.001493s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=100 WHERE `configId` = 132 [ RunTime:0.001530s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=6 WHERE `configId` = 133 [ RunTime:0.001550s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=2 WHERE `configId` = 134 [ RunTime:0.001523s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 135 [ RunTime:0.001503s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=50 WHERE `configId` = 136 [ RunTime:0.001524s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=20 WHERE `configId` = 137 [ RunTime:0.001429s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 138 [ RunTime:0.000893s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=12 WHERE `configId` = 139 [ RunTime:0.000848s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=1 WHERE `configId` = 140 [ RunTime:0.001339s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 141 [ RunTime:0.000842s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=99 WHERE `configId` = 142 [ RunTime:0.001343s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=9990 WHERE `configId` = 143 [ RunTime:0.001364s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=99 WHERE `configId` = 144 [ RunTime:0.000810s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=9990 WHERE `configId` = 145 [ RunTime:0.001389s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=99 WHERE `configId` = 146 [ RunTime:0.000717s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=9990 WHERE `configId` = 147 [ RunTime:0.001449s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 148 [ RunTime:0.001401s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001330s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=25 WHERE `configId` = 0 [ RunTime:0.001263s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=1 WHERE `configId` = 0 [ RunTime:0.000818s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001372s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001429s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000778s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001175s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=1 WHERE `configId` = 0 [ RunTime:0.000683s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 0 [ RunTime:0.001366s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=1 WHERE `configId` = 0 [ RunTime:0.000754s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001369s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=1 WHERE `configId` = 0 [ RunTime:0.001549s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001358s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0.2 WHERE `configId` = 0 [ RunTime:0.000676s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001309s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=5 WHERE `configId` = 0 [ RunTime:0.001313s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000654s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001356s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001336s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001319s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=5 WHERE `configId` = 0 [ RunTime:0.000658s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 0 [ RunTime:0.001259s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=15 WHERE `configId` = 0 [ RunTime:0.000653s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=20 WHERE `configId` = 0 [ RunTime:0.001325s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=25 WHERE `configId` = 0 [ RunTime:0.001175s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000659s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001064s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001343s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001369s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001386s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001458s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000814s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001376s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000790s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001302s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000658s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001570s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001535s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001537s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001470s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001476s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000837s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000810s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001432s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000854s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001316s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000673s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001358s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.000801s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=30 WHERE `configId` = 0 [ RunTime:0.001282s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 0 [ RunTime:0.000798s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=10 WHERE `configId` = 0 [ RunTime:0.001525s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=24 WHERE `configId` = 0 [ RunTime:0.001463s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=7 WHERE `configId` = 0 [ RunTime:0.001382s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=7 WHERE `configId` = 0 [ RunTime:0.001350s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001367s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=-0 WHERE `configId` = 0 [ RunTime:0.000834s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=9 WHERE `configId` = 0 [ RunTime:0.001349s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000680s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001453s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001336s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001350s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001571s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001322s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=50 WHERE `configId` = 0 [ RunTime:0.001322s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001167s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001411s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000772s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001421s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000676s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001465s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001256s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=5 WHERE `configId` = 0 [ RunTime:0.001312s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000658s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001338s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000676s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001320s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000694s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001341s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000668s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001341s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000732s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000752s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001413s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000768s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001378s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001428s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001489s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001336s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001384s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000900s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000774s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.001431s ] +[ sql ] [ SQL ] UPDATE `hyh_data_configs` SET `fieldValue`=0 WHERE `configId` = 0 [ RunTime:0.000815s ] diff --git a/runtime/temp/08af0540c598ffa08142601f90a4a3c0.php b/runtime/temp/08af0540c598ffa08142601f90a4a3c0.php new file mode 100644 index 0000000..3601179 --- /dev/null +++ b/runtime/temp/08af0540c598ffa08142601f90a4a3c0.php @@ -0,0 +1,165 @@ +<?php if (!defined('THINK_PATH')) exit(); /*a:2:{s:58:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/index.html";i:1551703962;s:57:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/base.html";i:1542015454;}*/ ?> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"/> +<title>后台管理中心 - <?php echo WSTConf('CONF.mallName'); ?></title> +<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> +<link rel="stylesheet" href="__ADMIN__/js/bootstrap/css/bootstrap.min.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/layui/css/layui.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/font-awesome/css/font-awesome.min.css" type="text/css" /> +<script src="__ADMIN__/js/jquery.min.js"></script> + +<link rel="stylesheet" href="__ADMIN__/css/skins/skin-blue.min.css"type="text/css"/> +<link rel="stylesheet" href="__ADMIN__/css/index.css" type="text/css"/> + +<link href="__ADMIN__/css/common.css?v=<?php echo $v; ?>" rel="stylesheet" type="text/css" /> +<script> +window.conf = {"DOMAIN":"<?php echo str_replace('index.php','',\think\Request::instance()->root(true)); ?>","ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"<?php echo config('url_html_suffix'); ?>","GOODS_LOGO":"<?php echo WSTConf('CONF.goodsLogo'); ?>","SHOP_LOGO":"<?php echo WSTConf('CONF.shopLogo'); ?>","MALL_LOGO":"<?php echo WSTConf('CONF.mallLogo'); ?>","USER_LOGO":"<?php echo WSTConf('CONF.userLogo'); ?>",'GRANT':'<?php echo implode(",",session("WST_STAFF.privileges")); ?>',"IS_CRYPT":"<?php echo WSTConf('CONF.isCryptPwd'); ?>","ROUTES":'<?php echo WSTRoute(); ?>'} +</script> +<script language="javascript" type="text/javascript" src="__STATIC__/js/common.js"></script> +</head> +<body class="hold-transition skin-blue sidebar-mini"> +<div id="j-loader"><img src="__ADMIN__/img/ajax-loader.gif"/></div> + +<style>body,.wrapper{overflow:hidden;}</style> +<div class="wrapper"> + <header class="main-header"> + <a href="#" class="logo"> + <span class="logo-mini">商城后台</span> + <span class="logo-lg">商城后台</span> + </a> + <nav class="navbar navbar-static-top"> + <div class="navbar-custom-menu" style='float:left'> + <ul class='nav navbar-nav'> + <li><a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> + <span class="sr-only">Toggle navigation</span> + </a></li> + <?php if(is_array($sysMenus) || $sysMenus instanceof \think\Collection || $sysMenus instanceof \think\Paginator): $i = 0; $__LIST__ = $sysMenus;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$top): $mod = ($i % 2 );++$i;?> + <li><a href='#' class='top-menu' dataid='<?php echo $top['menuId']; ?>'><i class="fa fa-<?php echo $top['menuIcon']; ?>"></i><span><?php echo $top['menuName']; ?></span></a></li> + <?php endforeach; endif; else: echo "" ;endif; ?> + </ul> + </div> + <div class="navbar-custom-menu"> + <ul class="nav navbar-nav"> + <!-- <li id='toMall'><a target='_blank' href='<?php echo Url("home/index/index"); ?>'><i class='fa fa-television'></i></a></li> --> + <li id='toSelft'><a target='_blank' href='<?php echo Url('admin/shops/inself'); ?>'><i class='fa fa-podcast'></i></a></li> + <li id='toClearCache'><a class='j-clear-cache' href='#'><i class='fa fa-spinner'></i></a></li> + <li id='toLogout'><a class='j-logout' href='#' title='退出系统'><i class='fa fa-power-off'></i></a></li> + </ul> + </div> + </nav> + </header> + <aside class="main-sidebar"> + <section class="sidebar"> + <div class="user-panel"> + <div class="pull-left image"> + <img src="__IMGURL__/<?php echo \think\Session::get('WST_STAFF.staffPhoto'); ?>" class="img-circle" alt="User Image"> + </div> + <div class="pull-left info"> + <p><?php echo \think\Session::get('WST_STAFF.loginName'); ?></p> + <p>系统管理员</p> + </div> + <div class='pull-left button'> + <a href='javascript:void(0);' class='j-edit-pass edit-pass'><i class='fa fa-key'></i><span>修改密码</span></a> + <a href='javascript:void(0);' class='j-logout logout'><i class='fa fa-power-off'></i><span>退出系统</span></a> + </div> + </div> + + <ul class="sidebar-menu" data-widget="tree"> + <?php if(is_array($sysMenus) || $sysMenus instanceof \think\Collection || $sysMenus instanceof \think\Paginator): $key0 = 0; $__LIST__ = $sysMenus;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$left0): $mod = ($key0 % 2 );++$key0;if(!empty($left0['child'])): if(is_array($left0['child']) || $left0['child'] instanceof \think\Collection || $left0['child'] instanceof \think\Paginator): $i = 0; $__LIST__ = $left0['child'];if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$left1): $mod = ($i % 2 );++$i;?> + <li class="treeview j-menulevel0 j-sysmenu<?php echo $left0['menuId']; ?>" <?php if($key0>1): ?>style='display:none'<?php endif; ?>"> + <a href="#"> + <i class="fa fa-<?php echo !empty($left1['menuIcon'])?$left1['menuIcon']:'eercast'; ?>"></i> <span><?php echo $left1['menuName']; ?></span> + <span class="pull-right-container"> + <i class="fa fa-angle-left pull-right"></i> + </span> + </a> + <?php if(!empty($left1['child'])): ?> + <ul class="treeview-menu"> + <?php if(is_array($left1['child']) || $left1['child'] instanceof \think\Collection || $left1['child'] instanceof \think\Paginator): $i = 0; $__LIST__ = $left1['child'];if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$left2): $mod = ($i % 2 );++$i;?> + <li><a class='menuItem' href="<?php echo Url($left2['privilegeUrl']); ?>" dataid='<?php echo $left2['menuId']; ?>'><i class="fa fa-<?php echo !empty($left2['menuIcon'])?$left2['menuIcon']:'circle-o'; ?>"></i><?php echo $left2['menuName']; if(!empty($left2['child'])): ?><i class="fa fa-angle-left pull-right"></i><?php endif; ?></a> + <?php if(!empty($left2['child'])): ?> + <ul class="treeview-menu"> + <?php if(is_array($left2['child']) || $left2['child'] instanceof \think\Collection || $left2['child'] instanceof \think\Paginator): $i = 0; $__LIST__ = $left2['child'];if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$left3): $mod = ($i % 2 );++$i;?> + <li> + <a class="menuItem" href="<?php echo $left3['privilegeUrl']; ?>" dataid='<?php echo $left2['menuId']; ?>'><i class="fa fa-<?php echo !empty($left3['menuIcon'])?$left3['menuIcon']:'circle-o'; ?>"></i><?php echo $left3['menuName']; ?> + </a> + </li> + <?php endforeach; endif; else: echo "" ;endif; ?> + </ul> + <?php endif; ?> + </li> + <?php endforeach; endif; else: echo "" ;endif; ?> + </ul> + <?php endif; ?> + </li> + <?php endforeach; endif; else: echo "" ;endif; endif; endforeach; endif; else: echo "" ;endif; ?> + </ul> + </section> + </aside> + <div class="content-wrapper"> + <section class="content-header"> + <ol class="breadcrumb"> + <li><a href='<?php echo \think\Request::instance()->root(true); ?>' target='_blank'><i class='fa fa-map-marker'></i>首页</a></li> + </ol> + <button id='toFullSreen' class="fullscreen"><i class="fa fa-arrows-alt"></i></button> + </section> + <section class="content-iframe" style="margin:0px;padding:0;height:100%"> + <iframe id='iframe' class="iframe" width="100%" height="100%" src="<?php echo Url('admin/index/main'); ?>" frameborder="0"></iframe> + </section> + </div> +</div> +<div id='editPassBox' style='display:none;padding-top:5px;'> + <form id='editPassFrom' autocomplete="off"> + <table class='wst-form'> + <tr> + <th style='width:100px'>原密码:</th> + <td><input type='password' id='srcPass' name='srcPass' class='ipt' data-rule="原密码: required;" maxLength='16'/></td> + </tr> + <tr> + <th>新密码:</th> + <td><input type='password' id='newPass' name='newPass' class='ipt' data-rule="新密码: required;length[6~]" maxLength='16'/></td> + </tr> + <tr> + <th>确认密码:</th> + <td><input type='password' id='newPass2' name='newPass2' class='ipt' data-rule="确认密码: required;match(newPass);" maxLength='16'/></td> + </tr> + </table> + </form> +</div> + +<script> +var menus = <?php echo json_encode($sysMenus); ?>; +function showImg(opt){ + layer.photos(opt); +} +function showBox(opts){ + return WST.open(opts); +} +$(function(){ + $('#toMall').poshytip({content:'点击打开商城首页',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toSelft').poshytip({content:'点击打开自营店铺',showTimeout:0,hideTimeout:1, + offsetY: 25,timeOnScreen:1000,allowTipHover: false}); + $('#toTechSupp').poshytip({content:'点击打开技术支持页面',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toClearCache').poshytip({content:'点击清除服务器缓存',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toLogout').poshytip({content:'点击退出系统',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); + $('#toFullSreen').poshytip({content:'点击全屏展示',showTimeout:0,hideTimeout:1, + offsetY: 25,allowTipHover: false,timeOnScreen:1000}); +}) +</script> + +<script src="__ADMIN__/js/bootstrap/js/bootstrap.min.js"></script> +<script language="javascript" type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script language="javascript" type="text/javascript" src="__ADMIN__/js/common.js"></script> + +<script src="__ADMIN__/js/index.js"></script> + +<?php echo hook('initCronHook'); ?> +</body> +</html> \ No newline at end of file diff --git a/runtime/temp/8eb17e67337cc8593f3c3ab6d955a118.php b/runtime/temp/8eb17e67337cc8593f3c3ab6d955a118.php new file mode 100644 index 0000000..b578923 --- /dev/null +++ b/runtime/temp/8eb17e67337cc8593f3c3ab6d955a118.php @@ -0,0 +1,670 @@ +<?php if (!defined('THINK_PATH')) exit(); /*a:9:{s:68:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/edit.html";i:1554893094;s:57:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/base.html";i:1542015454;s:75:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/dataConfigs.html";i:1565073264;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config1.html";i:1542015458;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config2.html";i:1542015458;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config3.html";i:1542015458;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config4.html";i:1542015458;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config6.html";i:1542015458;s:71:"/www/wwwroot/qlg.tsgz.moe/hyhproject/admin/view/sysconfigs/config5.html";i:1542015458;}*/ ?> +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"/> +<title>后台管理中心 - <?php echo WSTConf('CONF.mallName'); ?></title> +<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> +<link rel="stylesheet" href="__ADMIN__/js/bootstrap/css/bootstrap.min.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/layui/css/layui.css" type="text/css" /> +<link rel="stylesheet" href="__STATIC__/plugins/font-awesome/css/font-awesome.min.css" type="text/css" /> +<script src="__ADMIN__/js/jquery.min.js"></script> + + +<link rel="stylesheet" type="text/css" href="__STATIC__/plugins/webuploader/webuploader.css?v=<?php echo $v; ?>" /> + +<style> + +.layui-form-label{width:140px;} + +.layui-input-block{ margin-left: 170px;} + +#wst-tab-5 input[type="text"]{width:50%} + +td{height:40px; } + +</style> + + +<link href="__ADMIN__/css/common.css?v=<?php echo $v; ?>" rel="stylesheet" type="text/css" /> +<script> +window.conf = {"DOMAIN":"<?php echo str_replace('index.php','',\think\Request::instance()->root(true)); ?>","ROOT":"__ROOT__","IMGURL":"__IMGURL__","APP":"__APP__","STATIC":"__STATIC__","SUFFIX":"<?php echo config('url_html_suffix'); ?>","GOODS_LOGO":"<?php echo WSTConf('CONF.goodsLogo'); ?>","SHOP_LOGO":"<?php echo WSTConf('CONF.shopLogo'); ?>","MALL_LOGO":"<?php echo WSTConf('CONF.mallLogo'); ?>","USER_LOGO":"<?php echo WSTConf('CONF.userLogo'); ?>",'GRANT':'<?php echo implode(",",session("WST_STAFF.privileges")); ?>',"IS_CRYPT":"<?php echo WSTConf('CONF.isCryptPwd'); ?>","ROUTES":'<?php echo WSTRoute(); ?>'} +</script> +<script language="javascript" type="text/javascript" src="__STATIC__/js/common.js"></script> +</head> +<body class="hold-transition skin-blue sidebar-mini"> +<div id="j-loader"><img src="__ADMIN__/img/ajax-loader.gif"/></div> + + +<form autocomplete='off'> + +<div class="layui-tab layui-tab-brief" lay-filter="msgTab"> + + <ul class="layui-tab-title"> + <li class="layui-this">数据配置</li> + <!-- <li class="layui-this">基础设置</li> + + <li>服务器设置</li> + + <li>运营设置</li> + + <li>密匙设置</li> + + <li>图片设置</li> + + <li>通知设置</li> + + <li>SEO设置</li> + --> + </ul> + + <div class="layui-tab-content" style="padding: 10px 0;"> + + <?php $grant = WSTGrant('SCPZ_02'); ?> + +<div class="layui-tab-item layui-show layui-form"> + + <table class='wst-form wst-box-top'> + <input type="hidden" id='isDataConfigs' class='ipt' value="1"> + <?php foreach($dataConfigs as $vo): ?> + <tr> + <th width='350'><?php echo $vo['fieldName']; ?></th> + <td><input type="text" id='<?php echo $vo['configId']; ?>' class='ipt' value="<?php echo $vo['fieldValue']; ?>" maxLength='100' placeholder='<?php echo $vo['fieldName']; ?>'/></td> + </tr> + <?php endforeach; if(($grant)): ?> + + <tr> + + <td colspan='2' align='center'> + + <button type="button" onclick='javascript:edit()' style='margin-right:15px;' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + + </td> + + </tr> + + <?php endif; ?> + + </table> + +</div> +<div class="layui-tab-item layui-form"> + <fieldset class="layui-elem-field layui-field-title"> + <legend>邮件服务器设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>SMTP服务器:</th> + <td><input type="text" id='mailSmtp' class='ipt' maxLength='100' value='<?php echo $object["mailSmtp"]; ?>'/></td> + </tr> + <tr> + <th>SMTP端口:</th> + <td><input type="text" id='mailPort' class='ipt' maxLength='10' value='<?php echo $object["mailPort"]; ?>'/></td> + </tr> + <tr> + <th>是否验证SMTP:</th> + <td> + <input type="checkbox" <?php if($object['mailAuth']==1): ?>checked<?php endif; ?> class="ipt" id="mailAuth" name="mailAuth" value='1' lay-skin="switch" lay-filter="mailAuth" lay-text="是|否"> + </td> + </tr> + <tr> + <th>SMTP发件人邮箱:</th> + <td><input type="text" id='mailAddress' class='ipt' value='<?php echo $object["mailAddress"]; ?>' maxLength='100'/></td> + </tr> + <tr> + <th>SMTP登录账号:</th> + <td><input type="text" id='mailUserName' class='ipt' value='<?php echo $object["mailUserName"]; ?>' maxLength='100'/></td> + </tr> + <tr> + <th>SMTP登录密码:</th> + <td><input type="text" id='mailPassword' class='ipt' value='<?php echo $object["mailPassword"]; ?>' maxLength='100'/></td> + </tr> + <tr> + <th>发件人名称:</th> + <td><input type="text" id='mailSendTitle' class='ipt' value='<?php echo $object["mailSendTitle"]; ?>' maxLength='100'/></td> + </tr> + </table> + </fieldset> + <fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;"> + <legend>短信服务器设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th colspan='2' style='text-align:left;padding-left:40px'><span style='color:gray;'>(请确保在“拓展管理-插件管理"中有安装相应的短信插件”)</span></th> + </tr> + <tr style='display:none'> + <th >开启手机验证:</th> + <td> + <input type="checkbox" checked class="ipt" id="smsOpen" value='1' name="smsOpen" value='1' lay-skin="switch" lay-filter="smsOpen" lay-text="开|关"> + </td> + </tr> + <tr> + <th width='150'>每个号码每日发送数:</th> + <td><input type="text" id='smsLimit' class='ipt' value="<?php echo $object['smsLimit']; ?>" maxLength='100'/></td> + </tr> + <tr> + <th>开启短信发送验证码:</th> + <td> + <input type="checkbox" <?php if($object['smsVerfy']==1): ?>checked<?php endif; ?> class="ipt" id="smsVerfy" value='1' name="smsVerfy" value='1' lay-skin="switch" lay-filter="smsVerfy" lay-text="开|关"> + </td> + </tr> + <?php if(($grant)): ?> + <tr> + <td colspan='2' align='center'> + <button type="button" onclick='javascript:edit()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + <?php endif; ?> + </table> + </fieldset> +</div><div class="layui-tab-item layui-form"> + <fieldset class="layui-elem-field layui-field-title"> + <legend>订单设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>开启积分支付:</th> + <td> + <input type="checkbox" <?php if($object['isOpenScorePay']==1): ?>checked<?php endif; ?> class="ipt" id="isOpenScorePay" name="isOpenScorePay" value='1' lay-skin="switch" lay-filter="isOpenScorePay" lay-text="开|关"> + </td> + </tr> + <tr id='scoreToMoneyTr' <?php if($object['isOpenScorePay']==0): ?>style='display:none'<?php endif; ?>> + <th>积分兑换金额:</th> + <td> + 积分支付时<input type="text" id='scoreToMoney' class='ipt' value="<?php echo $object['scoreToMoney']; ?>" maxLength='5' style='width:60px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>个积分抵1个金额 + </td> + </tr> + <tr> + <th>开启下单获积分:</th> + <td> + <input type="checkbox" <?php if($object['isOrderScore']==1): ?>checked<?php endif; ?> class="ipt" id="isOrderScore" name="isOrderScore" value='1' lay-skin="switch" lay-filter="isOrderScore" lay-text="开|关"> + </td> + </tr> + <tr id='moneyToScoreTr' <?php if($object['isOrderScore']==0): ?>style='display:none'<?php endif; ?>> + <th>金额兑换积分:</th> + <td> + 下单后订单金额1元可获得<input type="text" id='moneyToScore' class='ipt' value="<?php echo $object['moneyToScore']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/>个积分 + <span style='color:gray;'> + </span> + </td> + </tr> + <tr> + <th>开启评价获积分:</th> + <td> + <input type="checkbox" <?php if($object['isAppraisesScore']==1): ?>checked<?php endif; ?> class="ipt" id="isAppraisesScore" name="isAppraisesScore" value='1' lay-skin="switch" lay-filter="isAppraisesScore" lay-text="开|关"> + </td> + </tr> + <tr id='appraisesScoreTr' <?php if($object['isAppraisesScore']==0): ?>style='display:none'<?php endif; ?>> + <th>评价获得积分:</th> + <td> + <input type="text" id='appraisesScore' class='ipt' value="<?php echo $object['appraisesScore']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/>个积分 + <span style='color:gray;'> + </span> + </td> + </tr> + <tr> + <tr> + <th>结算方式:</th> + <td> + <label> + <input type='radio' id='statementType' name='statementType' class='ipt' value='0' <?php if($object['statementType']==0): ?>checked<?php endif; ?> title='即时结算'> + </label> + <label> + <input type='radio' id='statementType' name='statementType' class='ipt' value='1' <?php if($object['statementType']==1): ?>checked<?php endif; ?> title='统一结算'> + </label> + <span style='color:gray;'>(即时结算指用户确认收货就把钱打到商家钱包,统一结算指系统定时结算或者商家管理员手工结算) + </span> + </td> + </tr> + <tr style='display:none'> + <th>积分与金钱兑换比例:</th> + <td><input type="text" id='scoreCashRatio' class='ipt' value="<?php echo $object['scoreCashRatio']; ?>" maxLength='20'/></td> + </tr> + <tr style='display:none'> + <th>结算金额设置:</th> + <td><input type="text" id='settlementStartMoney' class='ipt' value="<?php echo $object['settlementStartMoney']; ?>" maxLength='10'/></td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>积分设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>开启积分签到:</th> + <td> + <input type="checkbox" <?php if($object['signScoreSwitch']==1): ?>checked<?php endif; ?> class="ipt" id="signScoreSwitch" name="signScoreSwitch" value='1' lay-skin="switch" lay-filter="signScoreSwitch" lay-text="开|关"> + </td> + </tr> + <tr id="signScore" <?php if($object['signScoreSwitch']==0): ?>style="display:none;"<?php endif; ?>> + <th>累计签到获得的积分:</th> + <td>&nbsp;</td> + </tr> + <tr id="signScores" <?php if($object['signScoreSwitch']==0): ?>style="display:none;"<?php endif; ?>> + <th></th> + <td> + <table><tbody> + <tr> + <th>第1天:</th><td><input type="text" id='signScore0' class='ipt' value="<?php echo $object['signScore0']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第2天:</th><td><input type="text" id='signScore1' class='ipt' value="<?php echo $object['signScore1']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第3天:</th><td><input type="text" id='signScore2' class='ipt' value="<?php echo $object['signScore2']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第4天:</th><td><input type="text" id='signScore3' class='ipt' value="<?php echo $object['signScore3']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第5天:</th><td><input type="text" id='signScore4' class='ipt' value="<?php echo $object['signScore4']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第6天:</th><td><input type="text" id='signScore5' class='ipt' value="<?php echo $object['signScore5']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第7天:</th><td><input type="text" id='signScore6' class='ipt' value="<?php echo $object['signScore6']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第8天:</th><td><input type="text" id='signScore7' class='ipt' value="<?php echo $object['signScore7']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第9天:</th><td><input type="text" id='signScore8' class='ipt' value="<?php echo $object['signScore8']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第10天:</th><td><input type="text" id='signScore9' class='ipt' value="<?php echo $object['signScore9']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第11天:</th><td><input type="text" id='signScore10' class='ipt' value="<?php echo $object['signScore10']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第12天:</th><td><input type="text" id='signScore11' class='ipt' value="<?php echo $object['signScore11']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第13天:</th><td><input type="text" id='signScore12' class='ipt' value="<?php echo $object['signScore12']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第14天:</th><td><input type="text" id='signScore13' class='ipt' value="<?php echo $object['signScore13']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第15天:</th><td><input type="text" id='signScore14' class='ipt' value="<?php echo $object['signScore14']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第16天:</th><td><input type="text" id='signScore15' class='ipt' value="<?php echo $object['signScore15']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第17天:</th><td><input type="text" id='signScore16' class='ipt' value="<?php echo $object['signScore16']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第18天:</th><td><input type="text" id='signScore17' class='ipt' value="<?php echo $object['signScore17']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第19天:</th><td><input type="text" id='signScore18' class='ipt' value="<?php echo $object['signScore18']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第20天:</th><td><input type="text" id='signScore19' class='ipt' value="<?php echo $object['signScore19']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第21天:</th><td><input type="text" id='signScore20' class='ipt' value="<?php echo $object['signScore20']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第22天:</th><td><input type="text" id='signScore21' class='ipt' value="<?php echo $object['signScore21']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第23天:</th><td><input type="text" id='signScore22' class='ipt' value="<?php echo $object['signScore22']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第24天:</th><td><input type="text" id='signScore23' class='ipt' value="<?php echo $object['signScore23']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第25天:</th><td><input type="text" id='signScore24' class='ipt' value="<?php echo $object['signScore24']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr> + <th>第26天:</th><td><input type="text" id='signScore25' class='ipt' value="<?php echo $object['signScore25']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第27天:</th><td><input type="text" id='signScore26' class='ipt' value="<?php echo $object['signScore26']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第28天:</th><td><input type="text" id='signScore27' class='ipt' value="<?php echo $object['signScore27']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第29天:</th><td><input type="text" id='signScore28' class='ipt' value="<?php echo $object['signScore28']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + <th>第30天:</th><td><input type="text" id='signScore29' class='ipt' value="<?php echo $object['signScore29']; ?>" maxLength='5' style='width:40px;' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberdoteKey(event)"/></td> + </tr> + <tr><span style='color:gray;'>(单位(个),必须第1天大于0才能签到,填写为空则为0;填写第1天为0则保存所有为0;填写中间位或最后位为零则取前一天积分,类推取得不为0的积分)</tr> + </tbody></table> + </td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>提现设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>用户提现设置:</th> + <td>至少<input type="text" id='drawCashUserLimit' class='ipt' value="<?php echo $object['drawCashUserLimit']; ?>" maxLength='10' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>元以上方能申请提现。</td> + </tr> + <tr> + <th>商家提现设置:</th> + <td>至少<input type="text" id='drawCashShopLimit' class='ipt' value="<?php echo $object['drawCashShopLimit']; ?>" maxLength='10' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>元以上方能申请提现。</td> + </tr> + </table> + </fieldset> + + <fieldset class="layui-elem-field layui-field-title"> + <legend>定时设置</legend> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>未支付订单失效时间:</th> + <td>下单后<input type="text" id='autoCancelNoPayDays' class='ipt' value="<?php echo $object['autoCancelNoPayDays']; ?>" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>小时</td> + </tr> + <tr> + <th>自动收货期限:</th> + <td>发货后<input type="text" id='autoReceiveDays' class='ipt' value="<?php echo $object['autoReceiveDays']; ?>" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>天自动收货</td> + </tr> + <tr> + <th>自动评价期限:</th> + <td>确认收货后<input type="text" id='autoAppraiseDays' class='ipt' value="<?php echo $object['autoAppraiseDays']; ?>" maxLength='3' style='width:40px' onkeyup="javascript:WST.isChinese(this,1)" onkeypress="return WST.isNumberKey(event)"/>天自动好评</td> + </tr> + <?php if(($grant)): ?> + <tr> + <td colspan='2' align='center'> + <button type="button" onclick='javascript:edit()' class='btn btn-primary btn-mright'><i class="fa fa-check"></i>保存</button> + <button type="reset" class='btn'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + <?php endif; ?> + </table> +</div><div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>密码加密传输:</th> + <td><input type="checkbox" <?php if($object['isCryptPwd']==1): ?>checked<?php endif; ?> value='1' class="ipt" id="isCryptPwd" name="isCryptPwd" lay-skin="switch" lay-filter="isCryptPwd" lay-text="开|关"><span style='color:gray;margin-left:5px;'>开启则用户登录、支付密码加密后再进行提交。<font color='red'>注意:该功能需开启openssl扩展支持!</font></span> + </td> + </tr> + <tr class='pwdCryptKeyTr' <?php if($object['isCryptPwd']==0): ?>style='display:none'<?php endif; ?>> + <th width='150'>商城密匙:</th> + <td> + <textarea id='pwdPrivateKey' style='height:250px' class="ipt" placeholder='请输入用于登录、支付密码加密传输的密匙,请勿留空'><?php echo $object['pwdPrivateKey']; ?></textarea> + </td> + </tr> + <tr class='pwdCryptKeyTr' <?php if($object['isCryptPwd']==0): ?>style='display:none'<?php endif; ?>> + <th width='150'>Modulus:</th> + <td> + <textarea id='pwdModulusKey' class="ipt" placeholder='请输入用于登录、支付密码加密传输的16进制公钥,请勿留空'><?php echo $object['pwdModulusKey']; ?></textarea> + </td> + </tr> + <?php if(($grant)): ?> + <tr> + <td colspan='2' align="center"> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + <?php endif; ?> + </table> +</div><link rel="stylesheet" type="text/css" href="__STATIC__/plugins/colpick/css/colpick.css" /> +<script src="__STATIC__/plugins/colpick/js/colpick.js"></script> +<div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th>水印位置:</th> + <td> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="0" <?php if(($object['watermarkPosition']==0)): ?>checked<?php endif; ?> title='无'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="1" <?php if(($object['watermarkPosition']==1)): ?>checked<?php endif; ?> title='左上'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="3" <?php if(($object['watermarkPosition']==3)): ?>checked<?php endif; ?> title='右上'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="5" <?php if(($object['watermarkPosition']==5)): ?>checked<?php endif; ?> title='居中'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="7" <?php if(($object['watermarkPosition']==7)): ?>checked<?php endif; ?> title='左下'/></label> + <label><input type="radio" id='watermarkPosition' name='watermarkPosition' class='ipt' value="9" <?php if(($object['watermarkPosition']==9)): ?>checked<?php endif; ?> title='右下'/></label> + <span style="color:gray;">设置为"无"则视为关闭水印</span> + </td> + </tr> + <tr> + <th width='150'>水印文字:</th> + <td> + <input type="text" id='watermarkWord' class='ipt' value="<?php echo $object['watermarkWord']; ?>" maxLength='50' /> + <span style="color:gray;">当文字和图片同时存在时以文字为主</span> + </td> + </tr> + <tr> + <th>水印文字大小:</th> + <td> + <input type="text" id='watermarkSize' class='ipt' value="<?php echo $object['watermarkSize']; ?>" maxLength='2'/> + <span style="color:gray;">建议大小为20</span> + </td> + </tr> + <tr> + <th>水印文字颜色:</th> + <td> + <input type="text" id='watermarkColor' class='ipt' value="<?php echo $object['watermarkColor']; ?>" /> + <span style="color:gray;">仅支持16进制的颜色:如#00FF00</span> + </td> + </tr> + <tr> + <th>水印文字字体路径:</th> + <td> + <input type="text" id='watermarkTtf' class='ipt' value="<?php echo $object['watermarkTtf']; ?>" placeholder="如:WSTMart/ttf/1.ttf" /> + <span style="color:gray;">后缀为.ttf,若留空则使用默认字体</span> + </td> + </tr> + <tr> + <th>水印文件:</th> + <td> + <div id='watermarkFilePicker'>上传图标</div><span id='watermarkFileMsg'></span> + <input type="hidden" id='watermarkFile' class='ipt' value="<?php echo $object['watermarkFile']; ?>" /> + </td> + </tr> + <tr> + <th width='100'>水印图预览:</th> + <td> + <div style="min-height:70px;" id="preview"> + <?php if((isset($object['watermarkFile']))): ?> + <img id='watermarkFilePrevw' src="__IMGURL__/<?php echo $object['watermarkFile']; ?>" style="max-height:75px;" /> + <?php endif; ?> + </div> + <span style="color:gray;">水印图最终大小由上传的图片大小决定</span> + </td> + </tr> + + <tr> + <th>水印透明度:</th> + <td> + <input type="text" id='watermarkOpacity' class='ipt' value="<?php echo $object['watermarkOpacity']; ?>" /> + <br> + <span style="color:gray;">水印的透明度,可选值为0-100。当设置为100时则为不透明</span> + </td> + </tr> + <tr> + <th>商城Logo:</th> + <td> + <div id='mallLogoPicker'>请上传商城Logo</div><span id='mallLogoMsg'></span> + <img src='__IMGURL__/<?php echo $object["mallLogo"]; ?>' width='120' hiegth='120' id='mallLogoPrevw'/> + <input type="hidden" id='mallLogo' class='ipt' value='<?php echo $object["mallLogo"]; ?>'/> + </td> + </tr> + <tr> + <th>默认店铺头像:</th> + <td> + <div id='shopLogoPicker'>请上传默认店铺头像</div><span id='shopLogoMsg'></span> + <img src='__IMGURL__/<?php echo $object["shopLogo"]; ?>' width='120' hiegth='120' id='shopLogoPrevw'/> + <input type="hidden" id='shopLogo' class='ipt' value='<?php echo $object["shopLogo"]; ?>'/> + </td> + </tr> + <tr> + <th>默认会员头像:</th> + <td> + <div id='userLogoPicker'>请上传默认会员头像</div><span id='userLogoMsg'></span> + <img src='__IMGURL__/<?php echo $object["userLogo"]; ?>' width='120' hiegth='120' id='userLogoPrevw'/> + <input type="hidden" id='userLogo' class='ipt' value='<?php echo $object["userLogo"]; ?>'/> + </td> + </tr> + <tr> + <th>默认商品图片:</th> + <td> + <div id='goodsLogoPicker'>请上传默认商品图片</div><span id='goodsLogoMsg'></span> + <img src='__IMGURL__/<?php echo $object["goodsLogo"]; ?>' width='120' hiegth='120' id='goodsLogoPrevw'/> + <input type="hidden" id='goodsLogo' class='ipt' value='<?php echo $object["goodsLogo"]; ?>'/> + </td> + </tr> + <?php if(($grant)): ?> + <tr> + <td colspan='2' align="center"> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + </tr> + <?php endif; ?> + </table> +</div><style> +.staffName label{width:120px;display:inline-block;} +.staffName label input[type='checkbox']{margin-right:5px;} +</style> +<div class="layui-tab-item staffName"> + <table class='wst-form wst-box-top'> + <tr> + <td colspan='2'> + <div id='alertTips' class='alert alert-success alert-tips fade in' style='margin:0px 0px'> + <div id='headTip' class='head'><i class='fa fa-lightbulb-o'></i>操作说明</div> + <ul class='body'> + <li>因微信通和短信通知会在事件发生的时候触发,请勿同时发送给太多人,以免造成提交延时影响用户体验。</li> + </ul> + </div> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>用户下单:</td> + </tr> + <tr> + <th width='150'>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxSubmitOrderTip' class='ipt' <?php if($object["wxSubmitOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxSubmitOrderTip,smsSubmitOrderTip","submitOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsSubmitOrderTip' class='ipt' <?php if($object["smsSubmitOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxSubmitOrderTip,smsSubmitOrderTip","submitOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt submitOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["submitOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>支付订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxPayOrderTip' class='ipt' <?php if($object["wxPayOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxPayOrderTip,smsPayOrderTip","payOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsPayOrderTip' class='ipt' <?php if($object["smsPayOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxPayOrderTip,smsPayOrderTip","payOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt payOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["payOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>取消订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxCancelOrderTip' class='ipt' <?php if($object["wxCancelOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxCancelOrderTip,smsCancelOrderTip","cancelOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsCancelOrderTip' class='ipt' <?php if($object["smsCancelOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxCancelOrderTip,smsCancelOrderTip","cancelOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt cancelOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["cancelOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>拒收订单:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxRejectOrderTip' class='ipt' <?php if($object["wxRejectOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxRejectOrderTip,smsRejectOrderTip","rejectOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsRejectOrderTip' class='ipt' <?php if($object["smsRejectOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxRejectOrderTip,smsRejectOrderTip","rejectOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt rejectOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["rejectOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>申请退款:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxRefundOrderTip' class='ipt' <?php if($object["wxRefundOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxRefundOrderTip,smsRefundOrderTip","refundOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsRefundOrderTip' class='ipt' <?php if($object["smsRefundOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxRefundOrderTip,smsRefundOrderTip","refundOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt refundOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["refundOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>订单投诉:</td> + </tr> + <tr> + <th>提示方式:</th> + <td> + <label><input type='checkbox' id='wxComplaintOrderTip' class='ipt' <?php if($object["wxComplaintOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxComplaintOrderTip,smsComplaintOrderTip","complaintOrderTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsComplaintOrderTip' class='ipt' <?php if($object["smsComplaintOrderTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxComplaintOrderTip,smsComplaintOrderTip","complaintOrderTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt complaintOrderTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["complaintOrderTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <td colspan='2' class='head-ititle'>申请提现:</td> + </tr> + <tr> + <th>提醒方式:</th> + <td> + <label><input type='checkbox' id='wxCashDrawsTip' class='ipt' <?php if($object["wxCashDrawsTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxCashDrawsTip,smsCashDrawsTip","cashDrawsTipUsers")'/>微信提醒</label> + <label><input type='checkbox' id='smsCashDrawsTip' class='ipt' <?php if($object["smsCashDrawsTip"]==1): ?>checked<?php endif; ?> onclick='javascript:checkTip("wxCashDrawsTip,smsCashDrawsTip","cashDrawsTipUsers")'/>短信提醒</label> + </td> + </tr> + <tr> + <th valign="top">提醒人:</th> + <td> + <?php if(is_array($list) || $list instanceof \think\Collection || $list instanceof \think\Paginator): $i = 0; $__LIST__ = $list;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$vo): $mod = ($i % 2 );++$i;?> + <label class='staffName'><input type='checkbox' class='ipt cashDrawsTipUsers' value='<?php echo $vo['staffId']; ?>' <?php if(in_array($vo['staffId'],$object["cashDrawsTipUsers"])): ?>checked<?php endif; ?>/><?php echo $vo['staffName']; ?></label> + <?php endforeach; endif; else: echo "" ;endif; ?> + </td> + </tr> + <tr> + <?php if(($grant)): ?> + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button type="reset" class="btn" ><i class="fa fa-refresh"></i>重置</button> + </td> + <?php endif; ?> + </tr> + </table> +</div><div class="layui-tab-item layui-form"> + <table class='wst-form wst-box-top'> + <tr> + <th width='150'>商城标题:</th> + <td><input type="text" id='seoMallTitle' class='ipt' value="<?php echo $object['seoMallTitle']; ?>" maxLength='100'/></td> + </tr> + <tr> + <th>商城关键字:</th> + <td><input type="text" id='seoMallKeywords' class='ipt' style='width:70%' value="<?php echo $object['seoMallKeywords']; ?>" maxLength='100'/></td> + </tr> + <tr> + <th>商城描述:</th> + <td><input type="text" id='seoMallDesc' class='ipt' style='width:70%' value="<?php echo $object['seoMallDesc']; ?>" maxLength='100'/></td> + </tr> + <tr> + <?php if(($grant)): ?> + <td colspan='2' align='center'> + <button type="button" class="btn btn-primary btn-mright" onclick='javascript:edit()'><i class="fa fa-check"></i>保存</button> + <button type="reset" class="btn" onclick='javascript:resetForm()'><i class="fa fa-refresh"></i>重置</button> + </td> + <?php endif; ?> + </tr> + </table> +</div> + + </div> + +</div> + +</form> + + +<script src="__ADMIN__/js/bootstrap/js/bootstrap.min.js"></script> +<script language="javascript" type="text/javascript" src="__STATIC__/plugins/layui/layui.all.js"></script> +<script language="javascript" type="text/javascript" src="__ADMIN__/js/common.js"></script> + + +<script type='text/javascript' src='__STATIC__/plugins/webuploader/webuploader.js?v=<?php echo $v; ?>' type="text/javascript"></script> + +<script src="__ADMIN__/sysconfigs/sysconfigs.js?v=<?php echo $v; ?>" type="text/javascript"></script> + + +<?php echo hook('initCronHook'); ?> +</body> +</html> \ No newline at end of file diff --git a/static/app/css/ac.css b/static/app/css/ac.css new file mode 100755 index 0000000..afcb67c --- /dev/null +++ b/static/app/css/ac.css @@ -0,0 +1,3 @@ +img{ + display: block; +} diff --git a/static/app/css/activity1.css b/static/app/css/activity1.css new file mode 100755 index 0000000..d4cbd91 --- /dev/null +++ b/static/app/css/activity1.css @@ -0,0 +1,345 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .title img { + width: 324px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 288px; + margin-top: 40px; + } + .ljjg, + .ljjg img { + height: 140px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .title img { + width: 300px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 265px; + margin-top: 35px; + } + .ljjg, + .ljjg img { + height: 127px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .title img { + width: 270px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 230px; + margin-top: 30px; + } + .ljjg, + .ljjg img { + height: 108px; + } +} + +body { + background: #3d2467; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.title { + text-align: center; + position: absolute; + z-index: 10; + width: 100%; +} + +.hyhflfs { + width: 94%; + margin-left: 3%; + margin-right: 3%; + background: #5524a8; + border-radius: 12px; +} + +.yhq { + padding: 6px 2% 0; +} + +.yhq_block { + margin: 3px 0.8% 0; + position: relative; + float: left; + width: 23.4%; +} + +.yhq_p1 { + position: absolute; + color: #FDFFFE; + font-size: 13.2px; + text-align: center; + top: 0; + margin: 0 auto; + left: 0; + right: 0; + height: 18px; + line-height: 18px; +} + +.yhq_p2 { + position: absolute; + color: #FDFFFE; + font-size: 44.4px; + text-align: center; + top: 20%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; + letter-spacing: -3px; +} + +.yhq_p3 { + position: absolute; + color: #FDFFFE; + font-size: 7.2px; + text-align: center; + top: 42%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; +} + +.yhq_p4 { + position: absolute; + color: #FDFFFE; + font-size: 10.8px; + text-align: center; + top: 55%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; + z-index: 9; +} + +.yhq_btn { + z-index: 10; + width: 90%; + position: absolute; + bottom: 8px; + text-align: center; + background: #ffbd1f; + color: #fdfffe; + margin: 0 5%; + border-radius: 15px; + height: 20px; + line-height: 20px; + font-size: 10.8px; +} + +.ljjg { + margin: 0 2.5%; + background: url(../img/ljjg_bg.png) no-repeat center top; + width: 95%; + background-size: 100%; +} + +.yhq_block img { + width: 100%; +} + +.ljjg img { + margin-left: 5%; + float: left; +} + +.p1 { + color: #fdfd21; + font-size: 18px; + margin-top: 12%; +} + +.p2 { + color: #ffffff; + font-size: 14.4px; + margin-top: 3%; +} + +.ljjg_r { + float: right; + width: 51%; + text-align: center; +} + +.ljjg_btn { + width: 120px; + height: 27.6px; + line-height: 27.6px; + color: white; + background: #ffbd1f; + margin: 6% auto; + border-radius: 5px; +} + +.hengfu img { + width: 100%; + margin: 2% 0 5%; +} + +.bktj { + margin-top: 50px; + margin-bottom: 20px; +} + +.bktj_b { + background: url(../img/bktj_bg.png) no-repeat center top; + background-size: 100%; + position: relative; +} + +.bktj_b img { + width: 100%; +} + +.bktj_con { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + padding: 3% 8.7%; +} + +.bktj_con img { + width: 48%; + float: left; +} + +.bktj_con_con { + width: 52%; + float: left; + text-align: center; + position: relative; +} + +.p3 { + color: #fdfd21; + font-size: 21.6px; + margin-top: 7%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.p4 { + color: #FFFFFF; + font-size: 13.2px; + margin-top: 7%; +} + +.bktj_con_con .ljqg_btn { + /*position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 15px;*/ + margin-top: 5%; +} + +.xpss { + padding: 10px; + margin-top: 70px; +} + +.xpss_b { + width: 46%; + margin: 2%; + float: left; + position: relative; +} + +.xpss_b img { + width: 100%; +} + +.xpss_con { + padding: 3%; + width: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.xpss_b .xpss_con img { + width: 80%; + margin: 0 10% 0; +} + +.p5 del { + font-size: 12px; + color: #5f5f5f; +} + +.p5 { + color: #f10637; + font-size: 21.6px; + font-weight: bold; + text-align: center; + position: absolute; + bottom: 22%; + left: 0; + right: 0; +} + +.xpss_ljqg_btn { + width: 80%; + height: 24px; + line-height: 24px; + text-align: center; + background: #f1063a; + color: #fefefe; + font-size: 14.4px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + border-radius: 5px; + bottom: 8%; +} \ No newline at end of file diff --git a/static/app/css/activity10.css b/static/app/css/activity10.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app/css/activity2.css b/static/app/css/activity2.css new file mode 100755 index 0000000..b4cde9c --- /dev/null +++ b/static/app/css/activity2.css @@ -0,0 +1,301 @@ +body { + background: #c82929; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.yhq { + position: relative; + width: 100%; +} + +.yhq img { + width: 100%; +} + +.yhq_con { + padding: 2.5%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.yhq_con_block { + width: 45%; + margin: 5% 2.5% 0; + float: left; + position: relative; +} + +.yhq_con_block img { + width: 100%; +} + +.yhq_con_block_con { + position: absolute; + right: 4%; + top: 6%; + bottom: 5%; + left: 35%; +} + +.yhq_p1 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + color: #C82828; + font-size: 10.8px; + top: 18%; +} + +.yhq_p2 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + color: #C82828; + font-size: 10.8px; + bottom: 2%; +} + +.yhq_p1 o { + font-weight: bold; + font-size: 36px; + letter-spacing: -3px; +} + +.ac img { + width: 100%; +} + +.gchh { + padding: 2%; +} + +.gchh_block { + width: 48%; + margin: 1%; + float: left; + position: relative; +} + +.gchh_b_bg { + width: 100%; +} + +.gchh_b_con { + position: absolute; + width: 92%; + top: 4%; + left: 4%; + border-radius: 5%; + height: 80%; + overflow: hidden; +} + +.gchh_b_con img { + width: 100%; + height: 100%; +} + +.gchh_b_con p { + position: absolute; + color: white; + bottom: 0; + left: 0; + right: 0; + text-align: center; + font-size: 14.4px; + padding: 3%; + background: rgba(200, 41, 41, 0.2); +} + +.title { + position: relative; +} + +.title img { + width: 100%; +} + +.title p { + text-align: center; + font-weight: bold; + color: #c82828; + font-size: 21.6px; + position: absolute; + left: 0; + right: 0; + margin: 6% auto; + top: 0; +} + +.zdzb_block { + position: relative; +} + +.zdzb_block img { + width: 100%; +} + +.zdzb_zzc { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 11; +} + +.zdzb_block_con { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + padding: 5.3% 4.6% 0; +} + +.zdzb_block_con img { + border-radius: 50%; + width: 100%; + height: 87.75%; +} + +.zdzb_block_con p { + position: absolute; + left: 12%; + right: 12%; + text-align: center; + font-size: 13.2px; + color: #c82828; + margin: 1% auto 0; + height: 25px; + line-height: 25px; + background: #fef8d4; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + bottom: 10%; +} + +.cost { + position: absolute; + font-size: 33.6px; + color: #c72928; + bottom: 2%; + left: 18%; +} + +.zdzb_block_con b { + font-size: 10.8px; + position: absolute; + color: #c72928; + bottom: 1%; + left: 15%; +} + +.zdzb_btn { + font-size: 12px; + position: absolute; + background: #c72b29; + bottom: 2%; + right: 15%; + text-align: center; + height: 25px; + line-height: 25px; + color: white; + width: 75px; + border-radius: 15px; +} + +.zdzb2 { + padding: 1%; +} + +.zdzb2_block { + width: 31.3%; + position: relative; + margin: 1%; + float: left; +} + +.zdzb2_block img { + width: 100%; +} + +.zdzb2_block p { + text-align: center; + color: #C72928; + font-size: 15.6px; + margin: auto; + position: absolute; + height: 20px; + line-height: 20px; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.zdzb3 { + padding: 2%; +} + +.zdzb3_block { + width: 30.3333%; + position: relative; + margin: 1.5%; + float: left; +} + +.zdzb3_block img { + width: 100%; +} + +.zdzb3_block .zdzb3_block_con img { + width: 90%; + position: absolute; + top: 5%; + left: 5%; + right: 5%; + height: 68%; + z-index: 10; +} + +.zdzb3_block .zdzb3_block_con p { + color: #e41f4a; + font-weight: bold; + font-size: 12px; + text-align: center; + position: absolute; + left: 0; + right: 0; + bottom: 5%; +} + +.zdzb3_block .zdzb3_block_con .sanjiao { + z-index: 11; + position: absolute; + width: 90%; + height: auto; + top: 69%; +} \ No newline at end of file diff --git a/static/app/css/activity3.css b/static/app/css/activity3.css new file mode 100755 index 0000000..5ff8013 --- /dev/null +++ b/static/app/css/activity3.css @@ -0,0 +1,293 @@ +body { + background: black; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.header .time { + width: 126px; + height: 39px; + line-height: 39px; + text-align: center; + border: 1px solid #f4d752; + color: #f6e164; + font-size: 21.6px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 30%; +} + +.yhq { + padding: 0 2%; +} + +.yhq_block { + width: 23%; + height: 117px; + float: left; + margin: 1%; + position: relative; + background: #c59c5a; + border-radius: 3%; +} + +.yhq_block .yhq_img { + width: 100%; +} + +.yhq_block .yhq_btn { + width: 90%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 7%; +} + +.yhq_p1 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 36px; + font-weight: bold; + letter-spacing: -3px; + text-align: center; + color: #262626; + top: 18px; +} + +.yhq_p2 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 14.4px; + text-align: center; + color: #262626; + top: 48px; +} + +.yhq_p3 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 9.6px; + text-align: center; + color: #262626; + top: 68px; +} + +.title { + width: 100%; + text-align: center; + padding: 5% 18%; +} + +.title img { + width: 100%; +} + +.jggcj { + width: 100%; + padding: 2%; + position: relative; +} + +.jggcj .bg_img { + width: 100%; +} + +.zz_img { + width: 96%; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + bottom: 9.5%; + z-index: 10; +} + +.jggcj .on { + transform: rotateY(180deg); +} + +.cj_con { + width: 82.8%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 18%; + z-index: 11; + padding: 0.5% 0 0 1%; +} + +.content { + width: 32.3%; + float: left; + margin: 0 1% 0.5% 0; + position: relative; +} + +.content img { + width: 100%; +} + +.num { + width: 98%; + text-align: center; + position: absolute; + bottom: 4%; + color: #FFFFFF; + font-size: 13.2px; +} + +.content_con { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 12; +} + +.cj_con .active .content_con { + background: rgba(255, 255, 255, 0.6); + border-radius: 10%; +} + +.content_con img { + width: 100%; + height: 100%; +} + +.nav { + padding: 1%; +} + +.nav_block { + width: 48%; + margin: 1%; + float: left; + position: relative; +} + +.nav_block img { + width: 100% +} + +.nav_block_con { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.p1 { + color: #fffffe; + font-size: 16.8px; + margin-left: 4%; + margin-top: 4%; +} + +.p2 { + color: #fffffe; + margin-left: 4%; + height: 16px; +} + +.go { + text-align: center; + width: 40px; + height: 16px; + line-height: 16px; + font-size: 10.8px; + background: white; + margin-left: 4%; + border-radius: 15px; + margin-top: 3%; +} + +.nav .nav_block1 { + width: 98%; +} + +.nav .nav_block1 .p1 { + margin-top: 2%; + margin-left: 2%; +} + +.nav .nav_block1 .p2 { + margin-left: 2%; +} + +.nav .nav_block1 .go { + margin-top: 1.5%; + margin-left: 2%; +} + +.list { + padding: 1%; +} + +.list_block { + width: 48%; + margin: 1%; + position: relative; + float: left; +} + +.list_block_bg { + width: 100%; +} + +.list_block_con { + padding: 2% 2% 0; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.list_block_con img { + width: 100%; + height: 85%; +} + +.p3 { + color: white; + height: 15px; + font-size: 10.8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 80%; +} + +.p4 { + color: white; + height: 15px; + font-size: 14.4px; + position: absolute; + bottom: 3%; +} \ No newline at end of file diff --git a/static/app/css/activity4.css b/static/app/css/activity4.css new file mode 100755 index 0000000..bcf4fc5 --- /dev/null +++ b/static/app/css/activity4.css @@ -0,0 +1,138 @@ +.mui-scroll-wrapper .mui-scroll .mui-control-item { + border-bottom: 2px solid transparent; + height: 50px; + line-height: 50px; +} + +.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active { + color: #e61329; + border-bottom: 2px solid #e6122b; +} + +.mui-segmented-control.mui-scroll-wrapper { + height: 51px; + background: white; + border-bottom: 1px solid #e6e6e6; +} + +.mui-segmented-control.mui-scroll-wrapper .mui-control-item { + padding: 0 10px; +} + +.con { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_top { + padding: 1%; +} + +.scroll_top_block { + width: 24%; + margin: 0.5%; + float: left; + background: white; + border-radius: 5%; +} + +.scroll_top_block img { + width: 60%; + margin: 15% 20% 0; +} + +.scroll_top_block p { + text-align: center; + font-size: 10.8px; + color: #909090; + margin-top: -3%; +} +.scroll_con{ + background: white; +} +.scroll_con_block { + background: white; + border-bottom: 6px solid #efefef; +} + +.scb_title { + width: 100%; + height: 75px; + position: relative; +} + +.scb_title img { + width: 50px; + height: 50px; + margin: 12.5px; + box-shadow: -1px 0 1px #8b8b8b, 0 -1px 1px #8b8b8b, 0 1px 1px #8b8b8b, 1px 0 1px #8b8b8b; +} + +.scb_title p { + position: absolute; + font-size: 15.6px; + color: black; + left: 72px; + top: 15px; + width: 55%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.scb_title .s1 { + padding: 0 5px; + font-size: 10.6px; + color: #fefefe; + background: #e4ae7b; + border-radius: 3px; + position: absolute; + left: 72px; + top: 40px; +} +.scb_title .s2 { + padding: 8px 15px; + font-size: 13.2px; + color: #909090; + background: #e6e6e6; + border-radius: 15px; + position: absolute; + right: 22px; + top: 20px; +} + +.scroll_con_con{ + padding: 0 2% 2%; +} +.scc_block{ + width: 31%; + margin: 1%; + float: left; +} +.scc_block img{ + width: 100%; +} +.scc_block{ + border: 1px solid #e6e6e6; +} +.scc_block p{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: center; + padding:0 2%; + font-size: 12px; + color: black; +} +.scc_block span{ + display: block; + font-size: 14.4px; + font-weight: bold; + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/static/app/css/activity5.css b/static/app/css/activity5.css new file mode 100755 index 0000000..805447e --- /dev/null +++ b/static/app/css/activity5.css @@ -0,0 +1,141 @@ +body { + background: white; +} + +.con { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.mui-slider-group, +.mui-slider-item, +.mui-slider-item img { + height: 144px; +} + +.ac5_con { + padding: 3%; +} + +.title { + position: relative; + margin-bottom: 1%; +} + +.title img { + width: 100%; +} + +.title p { + position: absolute; + width: 100%; + top: 45%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + text-align: center; + color: #FFFFFF; + font-size: 16.8px; +} + +.con_o { + position: relative; + margin-bottom: 2%; +} + +.con_o img { + width: 100%; +} + +.con_o .img { + position: absolute; + left: 6%; + top: 22%; + width: 35%; +} + +.con_oo { + position: absolute; + right: 6%; + top: 22%; + bottom: 14%; + left: 43%; + text-align: center; +} + +.p1 { + font-size: 15.6px; + color: #909090; + margin-top: 2%; +} + +.p2 { + font-size: 15.6px; + color: #525252; + font-weight: bold; + margin-top: 2%; +} + +.p3 { + color: #f23046; + font-size: 19.2px; + margin-top: 2%; +} + +.con_oo_btn { + padding: 5% 10%; + background: #f23249; + color: white; + font-size: 13.2px; + border: none; + margin-top: 2%; +} + +.con_t_block { + width: 49%; + margin: 0.5%; + border: 2px solid #f1f1f1; + float: left; +} + +.con_t_block img { + width: 100%; +} + +.con_t_block p { + padding: 2%; + height: 48px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.tfooter{ + width: 100%; + height: 36px; + line-height: 36px; +} +.tfooter span{ + font-size: 14.4px; + color: #fa3c50; + float: left; + +} +.con_t_btn{ + float: right; + border: none; + border-radius: 50px 0 0 50px; + color: white; + background: -moz-linear-gradient(left, #fc055f, #fb2c54); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#fc055f), to(#fb2c54)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #fc055f, #fb2c54); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #fc055f, #fb2c54); +} diff --git a/static/app/css/activity6.css b/static/app/css/activity6.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app/css/activity7.css b/static/app/css/activity7.css new file mode 100755 index 0000000..30bddcd --- /dev/null +++ b/static/app/css/activity7.css @@ -0,0 +1,223 @@ +.mui-scroll {} + + +.tanhao { + width: 36.5px; + position: absolute; + right: 2.8%; + bottom: 7px; + padding: 10px; +} + +.ect_top { + padding: 0 2.5%; + width: 100%; + position: relative; + height: 54px; + position: fixed; + left: 0; + right: 0; + top: 66px; + background: white; +} + +#last, +#vol { + border-bottom: none; +} + +.ect_m { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #909090; + float: left; + width: 50%; + padding: 2.5px 0; + text-align: center; + background: #fff; + border-bottom: 1px solid #e6e6e6; + height: 27px; +} + +.ect_top img { + width: 17.5px; + height: 16.2px; + position: absolute; + left: 37.2px; + top: 30.6px; +} + + +/*top end*/ + +.con { + width: 100%; + /*padding: 0 1.25%;*/ +} + +.con_{ + width: 100%; + padding: 0 1.25%; +} + +.con .ect_com { + width: 47.25%; + margin: 1.25%; + background: #fff; + float: left; +} + +.com_img1 { + width: 100%; +} + +.com_img1 img { + width: 100%; + height: 100%; + display: block; +} + +.com_img2 { + width: 30px; + height: 15px; + /*margin-left: 3.6px;*/ + margin-right: 8.4px; + margin-top: 5px; + display: inline-block; +} + +.ect_com p { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #000000; + width: 100%; + padding-left: 3.6px; +} + +.ect_com .p1 { + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.ect_com .p3 { + color: #e51329; + margin-top: 14px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ect_activity { + width: 100%; +} +.ect_activity_{ + width: 100%; + position: relative; +} + +#_h,#_m,#_s{ + background: #525252; + color: white; + padding: 0 3px; + font-size: 12px; + position: absolute; + bottom: 0px; + border-radius: 3px; + /*line-height: 13px;*/ + /*height: 14px;*/ + bottom: 12%; +} +#_h{ + left: 48.9%; +} +#_m{ + left: 55.7%; +} +#_s{ + left: 62.5%; +} +.ect_hd { + width: 48%; + display: block; + margin: 0 auto; +} +.ect_djs{ + width: 38%; + margin: 10px auto 0; + display: block; + padding-bottom: 10px; +} + +.day { + width: 80%; + height: 15px; + background: #fbdcdc; + margin-left: 2%; + margin-bottom: 2.5px; +} + +.day p { + font-family: "微软雅黑"; + font-size: 10px; + color: #e51329; + line-height: 15px; +} + +.nav { + width: 100%; + height: 36px; + position: fixed; + top: 126px; + background: white; +} + +.nav_block { + width: 20%; + float: left; + font-size: 10.8px; + color: #909090; + text-align: center; + padding: 6px 0; + height: 36px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.nav .on { + color: #e51329; + border-bottom: 3px solid #e5122b; +} + +.ten{ + width: 100%; + background:#fff; + border-top: 1px solid #EFEFF4; +} + +.ten .on{ + color: #ff0962; +} + +.ten_t{ + width: 25%; + height:38.4px; + float: left; + text-align: center; + line-height: 38.4px; + color: #909090; + font-size: 12px; +} + +.title_img img{ + width: 100%; +} + + +.time_{ + text-align: center; + font-size: 12px; +} diff --git a/static/app/css/activity8.css b/static/app/css/activity8.css new file mode 100755 index 0000000..4d0161e --- /dev/null +++ b/static/app/css/activity8.css @@ -0,0 +1,36 @@ +body{ + background: #EBEBEB; +} + +.mui-scroll{ + padding: 8.7%; +} + +.rul_p{ + font-family: "微软雅黑"; + font-size: 16.8px; + text-align: center; + color: #000000; +} + +.rul_div{ + width: 100%; + margin-top: 21px; + background: #fff; +} + +.rul_div p{ + margin-left: 2%; + margin-right: 2%; +} + +.rul_div .rul_p1{ + font-family: "微软雅黑"; + font-size: 14.4px; + color: #ff3600; +} +.rul_div .rul_p2{ + font-family: "微软雅黑"; + font-size: 10.8px; + color: #0e0e0e; +} diff --git a/static/app/css/activity9.css b/static/app/css/activity9.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app/css/appraise.css b/static/app/css/appraise.css new file mode 100755 index 0000000..5b184b2 --- /dev/null +++ b/static/app/css/appraise.css @@ -0,0 +1,143 @@ +* { + margin: 0; + padding: 0; +} +body{ + background: white; +} +.clearfix::before, +.clearfix::after { + display: block; + content: ''; + visibility: hidden; + height: 100%; + clear: both; +} + +body { + padding-top: 2%; +} +.gallety{ + width: 100%; + overflow: hidden; + height: 80px; +} +.my-gallery { + width: 200%; + margin: 0 auto; + overflow: hidden; +} + +.my-gallery .img-dv { + width: 78px; + height: 78px; + margin-bottom: 1%; +} + +.my-gallery .img-dv a { + display: block; + width: 100%; + height: 100%; + text-align: center +} + +.my-gallery .img-dv a img { + width: 100%; + height: 100%; + /*vertical-align: middle;*/ +} + +figure { + float: left; + margin: 0; + margin-right: 5px; +} + +.con{ + /*margin-top: 66px;*/ +} + + +.nav { + font-size: 12px; + margin-bottom: 8px; +} +.nav div{ + float: left; + width: 30%; + height: 30px; + text-align: center; + line-height: 30px; + margin-left: 2.5%; + background: #fdecea; + border-radius: 15px; + color: #525252; +} +.nav .on{ + background: #E6122B; + color: white; +} + + +.pj_breviary { + padding: 12px; + border-bottom: 1px solid #e6e6e6; +} + +.pjbtitle p { + color: #e61329; + font-size: 13.2px; + float: left; + margin: 0; + line-height: 25.2px; + padding-left: 6px; +} + +.pjbcon { + color: #525252; + font-size: 13.2px; + margin: 3px 0; +} + +.pjclass { + color: #909090; + font-size: 13.2px; +} +.pjbtitle img { + width: 25.2px; + height: 25.2px; + border-radius: 50%; + overflow: hidden; + float: left; + +} +.pj_title { + color: black; + padding: 9px 12px; + margin: 0; +} +.pjzhuijia{ + padding: 9px 6px; + background: #e4e4e4; + border-radius: 4.8px; + font-size: 12px; + margin-top: 4px; +} +.zjpj{ + position: relative; + padding-top: 0.1px; +} +.sanjiao{ + position: absolute; + width: 9px; + height: 9px; + transform: rotate(45deg); + background: #e4e4e4; + left: 32px; +} +.pswp__top-bar{ + margin-top: 20px; +} +.nav_{ + margin-top: 5px; +} diff --git a/static/app/css/classify.css b/static/app/css/classify.css new file mode 100755 index 0000000..d3e03b9 --- /dev/null +++ b/static/app/css/classify.css @@ -0,0 +1,56 @@ +.con_left{ + position: fixed; + left: 0; + bottom: 0; + top: 66px; + right: 75%; + width: 25%; +} + + +.left_row{ + width: 100%; + min-height: 45px; + padding: 15px 0; + /*line-height: 54px;*/ + border-bottom: 1px solid #e6e6e6; + background: #efefef; + text-align: center; + font-size: 14.4px; +} + +.con_left .on{ + background: white; + border-left: 3px solid #f5394e; +} + +.con_right{ + position: fixed; + left: 25%; + bottom: 0; + top: 66px; + right: 0; + background: white; + width: 75%; +} + + +.rb_title{ + width: 100%; + text-align: center; + font-size: 14.4px; + height: 50px; + line-height: 50px; +} +.rb_block{ + width: 33.3%; + padding: 5%; + float: left; +} +.rb_block img{ + width: 100%; +} +.rb_block p{ + text-align: center; + font-size: 14.4px; +} diff --git a/static/app/css/collect.css b/static/app/css/collect.css new file mode 100755 index 0000000..272f382 --- /dev/null +++ b/static/app/css/collect.css @@ -0,0 +1,42 @@ + +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + height: 66px; +} +.p1{ + color: #909090; + float: left; + margin-top: 20px; + height: 45px; + line-height: 46px; + width: 26.41px; + margin-left: calc(35% - 20px ); + font-size: 13.2px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} \ No newline at end of file diff --git a/static/app/css/collect_commodity.css b/static/app/css/collect_commodity.css new file mode 100755 index 0000000..cc916ba --- /dev/null +++ b/static/app/css/collect_commodity.css @@ -0,0 +1,39 @@ +.con{ + background: white; +} +.row{ + width: 100%; + height: 127px; +} +.row img{ + float: left; + width: 126px; + height: 127px; + border-bottom: 1px solid #fff; + +} +.row .row_r{ + width: calc(100% - 130px); + height: 127px; + border-bottom: 1px solid #e6e6e6; + float: right; + position: relative; +} +.row_r p{ + font-size: 12px; + color: black; + padding-top: 9px; + padding-left: 6px; + padding-right: 6px; +} +.row_r .cost{ + position: absolute; + color: #e5142a; + font-size: 13.2px; + bottom: 6px; +} +.qxsc{ + position: absolute;bottom: 6px; + right: 6px; + padding: 3px 6px; +} diff --git a/static/app/css/collect_store.css b/static/app/css/collect_store.css new file mode 100755 index 0000000..257de32 --- /dev/null +++ b/static/app/css/collect_store.css @@ -0,0 +1,132 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .row_con .swiper-container { + height: 125px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 99px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .row_con .swiper-container { + height: 115px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 89px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .row_con .swiper-container { + height: 101px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 75.5px; + } +} + +.row { + border-bottom: 1px solid #e6e6e6; +} + +.row_title { + width: 100%; + height: 85.2px; + background: white; + position: relative; +} + +.row_title .img { + position: absolute; + width: 45px; + height: 45px; + top: 21px; + left: 14.4px; +} + +.row_title .s_t { + font-size: 13.2px; + color: black; + width: calc(100% - 200px); + position: absolute; + left: 72px; + line-height: 85.2px; + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.row_title .num { + position: absolute; + text-align: center; + width: 48px; + color: #909090; + font-size: 21.6px; + margin: 0; + right: 36px; + top: 24px; +} + +.row_title .p1 { + position: absolute; + text-align: center; + width: 48px; + color: #909090; + font-size: 13.2px; + margin: 0; + right: 36px; + top: 45px; +} + +.row_title .img_btn { + position: absolute; + width: 36.8px; + height: 30.2px; + top: 29px; + right: 8px; + padding: 10px; +} + +.swiper-container { + margin-top: 12px; + margin-bottom: 12px; +} + +.swiper-slide { + text-align: center; + background: white; +} + +.swiper-slide p { + font-size: 13.2px; + color: #E61329; +} + +.row_con { + overflow: hidden; +} + +.qxsc { + position: absolute; + right: 15px; + padding: 3px 6px; + top: 30px; +} \ No newline at end of file diff --git a/static/app/css/complain.css b/static/app/css/complain.css new file mode 100755 index 0000000..228c0fa --- /dev/null +++ b/static/app/css/complain.css @@ -0,0 +1,20 @@ +.con { + background: white; + padding: 10px 5%; +} + +select { + padding-left: 0; +} + +button { + width: 90%; + background: #f02c43; + margin: 10px 5%; + text-align: center; + font-family: "微软雅黑"; + font-size: 15.6px; + color: #fff; + border: none; + height: 40px; +} \ No newline at end of file diff --git a/static/app/css/confirmOrder.css b/static/app/css/confirmOrder.css new file mode 100755 index 0000000..f8f8e6f --- /dev/null +++ b/static/app/css/confirmOrder.css @@ -0,0 +1,135 @@ +.scroll_out{ + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + + +.c1_r input{ + margin: 0; + border: none; + padding: 0; + height: 22px; + width: calc( 100% ); + font-size: 12px; +} +.c1_r{ + width: calc(100% - 80px); + text-align: right; +} + +.c1_l input::-webkit-input-placeholder { /* WebKit browsers */ +font-size:12px; +} +.c1_l input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ +font-size:12px; +} +.c1_l input::-moz-placeholder { /* Mozilla Firefox 19+ */ +font-size:12px; +} +.c1_l input:-ms-input-placeholder { /* Internet Explorer 10+ */ +font-size:12px; +} + + +.js_r{ + float: right; + line-height: 50px; +} +.js_r span{ + font-size: 12px; +} +.js_r span j{ + color: #e94744; +} +.js_r span o{ + color: #909090; +} +.btn_tj{ + display: inline-block; + width: 102px; + height: 51px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + text-align: center; + color: white; + font-size: 14.4px; +} + +.isHb{ + width: 100%; + height: 42px; + border-bottom: 1px solid #e6e6e6; + background: white; + line-height: 41px; + padding:0 10px; +} +.h_left{ + font-size: 12px; + float: left; +} +.h_left o{ + color: #909090; +} +.he_right{ + float: right; + height: 41px; + width: 80px; + position: relative; +} +.checkout{ + width: 42px; + height: 25px; + border-radius: 15px; + /*background: #2ddd87;*/ + position: absolute; + right: 0; + top: 7px; + border:1px solid #909090; +} +.check_btn{ + position: absolute; + width: 21px; + height: 21px; + background: white; + border-radius: 50%; + top: 1px; + left: 1px; + border:1px solid #909090; +} +.he_right .on{ + top: 8px; + border: none; + height: 23px; + background: #2ddd87; +} + +.he_right .on .check_btn{ + border: none; + left: 20px; +} +select{ + margin: 0; + padding: 0 ; + font-size: 13.2px; +} +.mui-table-view-cell:after{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content{ + width: 100%; + background: transparent; +} +.row_{ + width: 100%; + font-size: 13.2px; + border-bottom: 1px solid #ebebeb; +} \ No newline at end of file diff --git a/static/app/css/default-skin/default-skin.css b/static/app/css/default-skin/default-skin.css new file mode 100755 index 0000000..c961632 --- /dev/null +++ b/static/app/css/default-skin/default-skin.css @@ -0,0 +1,482 @@ +/*! PhotoSwipe Default UI CSS by Dmitry Semenov | photoswipe.com | MIT license */ +/* + + Contents: + + 1. Buttons + 2. Share modal and links + 3. Index indicator ("1 of X" counter) + 4. Caption + 5. Loading indicator + 6. Additional styles (root element, top bar, idle state, hidden state, etc.) + +*/ +/* + + 1. Buttons + + */ +/* <button> css reset */ +.pswp__button { + width: 44px; + height: 44px; + position: relative; + background: none; + cursor: pointer; + overflow: visible; + -webkit-appearance: none; + display: block; + border: 0; + padding: 0; + margin: 0; + float: right; + opacity: 0.75; + -webkit-transition: opacity 0.2s; + transition: opacity 0.2s; + -webkit-box-shadow: none; + box-shadow: none; } + .pswp__button:focus, .pswp__button:hover { + opacity: 1; } + .pswp__button:active { + outline: none; + opacity: 0.9; } + .pswp__button::-moz-focus-inner { + padding: 0; + border: 0; } + +/* pswp__ui--over-close class it added when mouse is over element that should close gallery */ +.pswp__ui--over-close .pswp__button--close { + opacity: 1; } + +.pswp__button, +.pswp__button--arrow--left:before, +.pswp__button--arrow--right:before { + background: url(default-skin.png) 0 0 no-repeat; + background-size: 264px 88px; + width: 44px; + height: 44px; } + +@media (-webkit-min-device-pixel-ratio: 1.1), (-webkit-min-device-pixel-ratio: 1.09375), (min-resolution: 105dpi), (min-resolution: 1.1dppx) { + /* Serve SVG sprite if browser supports SVG and resolution is more than 105dpi */ + .pswp--svg .pswp__button, + .pswp--svg .pswp__button--arrow--left:before, + .pswp--svg .pswp__button--arrow--right:before { + background-image: url(default-skin.svg); } + .pswp--svg .pswp__button--arrow--left, + .pswp--svg .pswp__button--arrow--right { + background: none; } } + +.pswp__button--close { + background-position: 0 -44px; } + +.pswp__button--share { + background-position: -44px -44px; } + +.pswp__button--fs { + display: none; } + +.pswp--supports-fs .pswp__button--fs { + display: block; } + +.pswp--fs .pswp__button--fs { + background-position: -44px 0; } + +.pswp__button--zoom { + display: none; + background-position: -88px 0; } + +.pswp--zoom-allowed .pswp__button--zoom { + display: block; } + +.pswp--zoomed-in .pswp__button--zoom { + background-position: -132px 0; } + +/* no arrows on touch screens */ +.pswp--touch .pswp__button--arrow--left, +.pswp--touch .pswp__button--arrow--right { + visibility: hidden; } + +/* + Arrow buttons hit area + (icon is added to :before pseudo-element) +*/ +.pswp__button--arrow--left, +.pswp__button--arrow--right { + background: none; + top: 50%; + margin-top: -50px; + width: 70px; + height: 100px; + position: absolute; } + +.pswp__button--arrow--left { + left: 0; } + +.pswp__button--arrow--right { + right: 0; } + +.pswp__button--arrow--left:before, +.pswp__button--arrow--right:before { + content: ''; + top: 35px; + background-color: rgba(0, 0, 0, 0.3); + height: 30px; + width: 32px; + position: absolute; } + +.pswp__button--arrow--left:before { + left: 6px; + background-position: -138px -44px; } + +.pswp__button--arrow--right:before { + right: 6px; + background-position: -94px -44px; } + +/* + + 2. Share modal/popup and links + + */ +.pswp__counter, +.pswp__share-modal { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +.pswp__share-modal { + display: block; + background: rgba(0, 0, 0, 0.5); + width: 100%; + height: 100%; + top: 0; + left: 0; + padding: 10px; + position: absolute; + z-index: 1600; + opacity: 0; + -webkit-transition: opacity 0.25s ease-out; + transition: opacity 0.25s ease-out; + -webkit-backface-visibility: hidden; + will-change: opacity; } + +.pswp__share-modal--hidden { + display: none; } + +.pswp__share-tooltip { + z-index: 1620; + position: absolute; + background: #FFF; + top: 56px; + border-radius: 2px; + display: block; + width: auto; + right: 44px; + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); + -webkit-transform: translateY(6px); + -ms-transform: translateY(6px); + transform: translateY(6px); + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + -webkit-backface-visibility: hidden; + will-change: transform; } + .pswp__share-tooltip a { + display: block; + padding: 8px 12px; + color: #000; + text-decoration: none; + font-size: 14px; + line-height: 18px; } + .pswp__share-tooltip a:hover { + text-decoration: none; + color: #000; } + .pswp__share-tooltip a:first-child { + /* round corners on the first/last list item */ + border-radius: 2px 2px 0 0; } + .pswp__share-tooltip a:last-child { + border-radius: 0 0 2px 2px; } + +.pswp__share-modal--fade-in { + opacity: 1; } + .pswp__share-modal--fade-in .pswp__share-tooltip { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); } + +/* increase size of share links on touch devices */ +.pswp--touch .pswp__share-tooltip a { + padding: 16px 12px; } + +a.pswp__share--facebook:before { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + top: -12px; + right: 15px; + border: 6px solid transparent; + border-bottom-color: #FFF; + -webkit-pointer-events: none; + -moz-pointer-events: none; + pointer-events: none; } + +a.pswp__share--facebook:hover { + background: #3E5C9A; + color: #FFF; } + a.pswp__share--facebook:hover:before { + border-bottom-color: #3E5C9A; } + +a.pswp__share--twitter:hover { + background: #55ACEE; + color: #FFF; } + +a.pswp__share--pinterest:hover { + background: #CCC; + color: #CE272D; } + +a.pswp__share--download:hover { + background: #DDD; } + +/* + + 3. Index indicator ("1 of X" counter) + + */ +.pswp__counter { + position: absolute; + left: 0; + top: 0; + height: 44px; + font-size: 13px; + line-height: 44px; + color: #FFF; + opacity: 0.75; + padding: 0 10px; } + +/* + + 4. Caption + + */ +.pswp__caption { + position: absolute; + left: 0; + bottom: 0; + width: 100%; + min-height: 44px; } + .pswp__caption small { + font-size: 11px; + color: #BBB; } + +.pswp__caption__center { + text-align: left; + max-width: 420px; + margin: 0 auto; + font-size: 13px; + padding: 10px; + line-height: 20px; + color: #CCC; } + +.pswp__caption--empty { + display: none; } + +/* Fake caption element, used to calculate height of next/prev image */ +.pswp__caption--fake { + visibility: hidden; } + +/* + + 5. Loading indicator (preloader) + + You can play with it here - http://codepen.io/dimsemenov/pen/yyBWoR + + */ +.pswp__preloader { + width: 44px; + height: 44px; + position: absolute; + top: 0; + left: 50%; + margin-left: -22px; + opacity: 0; + -webkit-transition: opacity 0.25s ease-out; + transition: opacity 0.25s ease-out; + will-change: opacity; + direction: ltr; } + +.pswp__preloader__icn { + width: 20px; + height: 20px; + margin: 12px; } + +.pswp__preloader--active { + opacity: 1; } + .pswp__preloader--active .pswp__preloader__icn { + /* We use .gif in browsers that don't support CSS animation */ + background: url(preloader.gif) 0 0 no-repeat; } + +.pswp--css_animation .pswp__preloader--active { + opacity: 1; } + .pswp--css_animation .pswp__preloader--active .pswp__preloader__icn { + -webkit-animation: clockwise 500ms linear infinite; + animation: clockwise 500ms linear infinite; } + .pswp--css_animation .pswp__preloader--active .pswp__preloader__donut { + -webkit-animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; + animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; } + +.pswp--css_animation .pswp__preloader__icn { + background: none; + opacity: 0.75; + width: 14px; + height: 14px; + position: absolute; + left: 15px; + top: 15px; + margin: 0; } + +.pswp--css_animation .pswp__preloader__cut { + /* + The idea of animating inner circle is based on Polymer ("material") loading indicator + by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html + */ + position: relative; + width: 7px; + height: 14px; + overflow: hidden; } + +.pswp--css_animation .pswp__preloader__donut { + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 14px; + height: 14px; + border: 2px solid #FFF; + border-radius: 50%; + border-left-color: transparent; + border-bottom-color: transparent; + position: absolute; + top: 0; + left: 0; + background: none; + margin: 0; } + +@media screen and (max-width: 1024px) { + .pswp__preloader { + position: relative; + left: auto; + top: auto; + margin: 0; + float: right; } } + +@-webkit-keyframes clockwise { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes clockwise { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@-webkit-keyframes donut-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); } + 50% { + -webkit-transform: rotate(-140deg); + transform: rotate(-140deg); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +@keyframes donut-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); } + 50% { + -webkit-transform: rotate(-140deg); + transform: rotate(-140deg); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +/* + + 6. Additional styles + + */ +/* root element of UI */ +.pswp__ui { + -webkit-font-smoothing: auto; + visibility: visible; + opacity: 1; + z-index: 1550; } + +/* top black bar with buttons and "1 of X" indicator */ +.pswp__top-bar { + position: absolute; + left: 0; + top: 0; + height: 44px; + width: 100%; } + +.pswp__caption, +.pswp__top-bar, +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + -webkit-backface-visibility: hidden; + will-change: opacity; + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +/* pswp--has_mouse class is added only when two subsequent mousemove events occur */ +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + visibility: visible; } + +.pswp__top-bar, +.pswp__caption { + background-color: rgba(0, 0, 0, 0.5); } + +/* pswp__ui--fit class is added when main image "fits" between top bar and bottom bar (caption) */ +.pswp__ui--fit .pswp__top-bar, +.pswp__ui--fit .pswp__caption { + background-color: rgba(0, 0, 0, 0.3); } + +/* pswp__ui--idle class is added when mouse isn't moving for several seconds (JS option timeToIdle) */ +.pswp__ui--idle .pswp__top-bar { + opacity: 0; } + +.pswp__ui--idle .pswp__button--arrow--left, +.pswp__ui--idle .pswp__button--arrow--right { + opacity: 0; } + +/* + pswp__ui--hidden class is added when controls are hidden + e.g. when user taps to toggle visibility of controls +*/ +.pswp__ui--hidden .pswp__top-bar, +.pswp__ui--hidden .pswp__caption, +.pswp__ui--hidden .pswp__button--arrow--left, +.pswp__ui--hidden .pswp__button--arrow--right { + /* Force paint & create composition layer for controls. */ + opacity: 0.001; } + +/* pswp__ui--one-slide class is added when there is just one item in gallery */ +.pswp__ui--one-slide .pswp__button--arrow--left, +.pswp__ui--one-slide .pswp__button--arrow--right, +.pswp__ui--one-slide .pswp__counter { + display: none; } + +.pswp__element--disabled { + display: none !important; } + +.pswp--minimal--dark .pswp__top-bar { + background: none; } diff --git a/static/app/css/default-skin/default-skin.png b/static/app/css/default-skin/default-skin.png new file mode 100755 index 0000000..441c502 Binary files /dev/null and b/static/app/css/default-skin/default-skin.png differ diff --git a/static/app/css/default-skin/default-skin.svg b/static/app/css/default-skin/default-skin.svg new file mode 100755 index 0000000..9d5f0c6 --- /dev/null +++ b/static/app/css/default-skin/default-skin.svg @@ -0,0 +1 @@ +<svg width="264" height="88" viewBox="0 0 264 88" xmlns="http://www.w3.org/2000/svg"><title>default-skin 2</title><g fill="none" fill-rule="evenodd"><g><path d="M67.002 59.5v3.768c-6.307.84-9.184 5.75-10.002 9.732 2.22-2.83 5.564-5.098 10.002-5.098V71.5L73 65.585 67.002 59.5z" id="Shape" fill="#fff"/><g fill="#fff"><path d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z" id="Shape"/></g><g fill="#fff"><path d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"/></g><path d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z" fill="#fff"/><path d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z" fill="#fff"/><path d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z" fill="#fff"/><g><path id="Rectangle-11" fill="#fff" d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z"/><path d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" id="Oval-1" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M150 21h5v1h-5z"/></g><g><path d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z" fill="#fff"/><path d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M106 21h5v1h-5z"/><path fill="#fff" d="M109.043 19.008l-.085 5-1-.017.085-5z"/></g></g></g></svg> \ No newline at end of file diff --git a/static/app/css/default-skin/preloader.gif b/static/app/css/default-skin/preloader.gif new file mode 100755 index 0000000..b8faa69 Binary files /dev/null and b/static/app/css/default-skin/preloader.gif differ diff --git a/static/app/css/details.css b/static/app/css/details.css new file mode 100755 index 0000000..1f1aea9 --- /dev/null +++ b/static/app/css/details.css @@ -0,0 +1,811 @@ +body { + background: #f4f2f2; +} + +.header { + width: 100%; + position: fixed; + top: 0; + z-index: 10; + background: transparent; + border: none; + box-shadow: 0 0 0; + height: 66px; +} + +body .header1 { + z-index: 11; + opacity: 0; + width: 100%; + position: fixed; + top: 0; + background: rgba(255, 255, 255, 1); + border: none; + box-shadow: 0 0 0; + height: 66px; + display: none; + border-bottom: 1px solid #efefef; +} + +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} + +.mui-title { + color: black; +} + +.zhe { + opacity: 0; +} + +.header .mui-action-back { + margin-top: 20px; + margin-left: 0; + border-radius: 50%; + background: rgba(0, 0, 0, 0.2); + color: white; +} + +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: black; + float: left; +} + +.mui-bar-nav { + box-shadow: none; + background: rgba(0, 0, 0, 0) +} + +.header1 .on { + border-bottom: 3px solid #ff0000; + color: #e61329; +} + +.p1 { + float: left; + margin-top: 20px; + height: 45px; + line-height: 46px; + width: 26.41px; + margin-left: calc(25% - 35px); + font-size: 13.2px; +} + +.back { + position: absolute; + left: 15px; + top: 25px; +} + +.back img, +.like img, +.menu img { + width: 37.2px; + height: 37.2px; +} + +.like { + position: absolute; + left: 279px; + top: 15px; +} + +.menu { + position: absolute; + right: 15px; + top: 25px; +} + +.banner { + width: 100%; + /*height: 387px;*/ + position: relative; +} + +.swiper-container { + width: 100%; + /*height: 387px;*/ + box-shadow: 0 -1px 3px #ddd; +} + +.swiper-slide { + text-align: center; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +.swiper-pagination-bullet-active { + background: #e94947; +} + +.swiper-slide {} + +.swiper-slide img { + width: 100%; + height: 100%; +} + +.summarize { + background: white; + width: 100%; + border-bottom: 6px solid #ebebeb; +} + +.cname { + font-size: 14.4px; + padding: 9px; + margin: 0; +} + +.price { + color: #F02A40; + font-size: 21.6px; + margin: 0; + padding: 10px; + +} +.summarize .xxl{ + color: white; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ +} + +.price o{ + font-size: 15px; + color: #909090; +} +.summarize .xxl o{ + font-size: 15px; + color: white; +} +.price_old { + color: #909090; + font-size: 15px; + padding-left: 9px; + padding-bottom: 9px; + margin: 0; + padding-top: 10px; +} + +.compilations { + position: relative; + width: 100%; + height: 24px; + line-height: 24px; + font-size: 10.8px; + color: #727272; +} + +.myf { + position: absolute; + left: 9px; +} + +.yx { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; +} + +.dz { + position: absolute; + right: 9px; +} + +.compilations { + border-bottom: 1px solid #e6e6e6; +} + +.guarantee { + width: 100%; + border-bottom: 5px solid #ebebeb; + background: white; +} + +.guarantee .row { + width: 100%; + height: 42px; + border-bottom: 1px solid #ebebeb; +} + +.mui-table-view-cell:after{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content{ + width: 100%; + background: transparent; +} +.row_{ + width: 100%; + font-size: 13.2px; + border-bottom: 1px solid #ebebeb; +} +.guarantee .row img { + height: 15px; + margin-left: 12px; + margin-top: 12px; + float: left; +} + +.guarantee .row .text { + color: #525252; + line-height: 42px; + font-size: 13.2px; + float: left; + max-width: calc(100% - 65px); + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + margin-left: 12px; +} + +.guarantee .row .text1 { + color: #ff1e4c; + background: #fbe9e9; + /*line-height: 42px;*/ + font-size: 10.2px; + float: left; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + margin-left: 12px; + padding: 0 8px; + margin-top: 10px; + height: 18px; +} + +.guarantee .row .lq { + float: right; + margin-top: 6px; + margin-right: 9px; + color: #909090; + border-radius: 15px; + line-height: 19px; + padding: 4px 10px 2px; +} + +.guarantee .row .caidan img { + width: 15px; + margin: 0; + height: 3px; +} + +.guarantee .row .caidan { + border: none; + float: right; + margin-top: 13px; + margin-right: 12px; +} + +.guarantee .row .caidan:active { + background: transparent; +} + +#guarantee .row .text { + color: black; +} + +.cc1 { + width: 100%; + height: 27px; +} + +.cclass_con { + position: absolute; + bottom: 0; + left: 0; + right: 0; +} + +.cc2 { + width: 100%; + height: 81px; + background: white; + position: relative; + border-bottom: 1px solid #e3e6ea; +} + +.cc2 p { + font-size: 15.6px; + color: #e94744; + position: absolute; + left: 120px; + top: 24px; +} + +.cc2 span { + font-size: 12px; + position: absolute; + left: 120px; + top: 48px; +} +.cc2 o{ + font-size: 12px; + color: #e94744; + position: absolute; + left: 200px; + top: 24px; +} +.cc2 l{ + font-size: 10px; + position: absolute; + left: 200px; + top: 48px; +} +.closecclass { + font-size: 15.6px; + color: #9b9b9b; + position: absolute; + padding: 9px 12px; + right: 0; + top: 0; +} + +.closecclass img { + width: 18px; +} + +.cclass_con .img { + background: white; + padding: 6px; + position: absolute; + border: 1px solid #f2f2f2; + border-radius: 6px; + width: 85.8px; + height: 85.8px; + top: 0; + left: 12px; + z-index: 60; +} + +.cclass_con .img img { + width: 100%; + height: 100%; + border-radius: 3px; +} + +.cclass1 { + padding: 9px 0 0 12px; + background: white; + width: 100%; + /*border-bottom: 1px solid #e3e6ea;*/ +} + +.cclass1 p { + color: #626262; + font-size: 13.2px; + padding-bottom: 6px; + margin: 0; +} + +.cclass1 .block { + padding: 2px 6px; + float: left; + /*border: 1px solid #9e9e9e;*/ + margin: 0px 18px 4px 0; + border-radius: 6px; + font-size: 14.4px; + color: #909090; + background: #f5f5f5; + font-size: 10.5px; +} + +.cclass1 .on { + /*border: 1px solid #e94947;*/ + color: #fff; + background: #e61329; +} + +.ensure { + width: 50%; + height: 48px; + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; + background: #e6122b; + float: left; +} + +.engwc { + width: 50%; + height: 48px; + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; + background: #ff9402; + float: left; +} + +.num { + background: white; + width: 100%; + height: 51.6px; + border-bottom: 1px solid #e3e6ea; + color: #626262; + font-size: 13.2px; + padding: 0 18px; + line-height: 51.6px; + position: relative; +} + +.change_num { + width: 168px; + height: 30px; + position: absolute; + right: 30px; + top: 10.5px; +} + +.jia { + background: #ebebeb; + position: absolute; + font-size: 21px; + color: #e94947; + line-height: 30px; + width: 30px; + text-align: center; + right: 0; +} + +.jian { + background: #ebebeb; + position: absolute; + font-size: 21px; + color: #e94947; + line-height: 30px; + width: 30px; + text-align: center; + left: 0; +} + +.change_num input { + position: absolute; + width: 78px; + margin: 0 15px; + left: 30px; + height: 30px; + border: none; + text-align: center; + font-size: 18px; +} + +.pjrk { + width: 100%; + background: white; + border-bottom: 5px solid #ebebeb; +} + +.pj_title { + color: black; + padding: 9px 12px; + margin: 0; +} + +.pj_remark { + padding-left: 12px; +} + +.pjr { + padding: 3px 20px; + margin: 0 12px 12px 0; + font-size: 12px; + float: left; + background: #fdecea; + color: #525252; + border-radius: 20px; +} + +.pjbtitle img { + width: 25.2px; + height: 25.2px; + border-radius: 50%; + overflow: hidden; + float: left; +} + +.pj_breviary { + padding: 0 12px; +} + +.pjbtitle p { + color: #e61329; + font-size: 13.2px; + float: left; + margin: 0; + line-height: 25.2px; + padding-left: 6px; +} + +.pjbcon { + color: #525252; + font-size: 13.2px; + margin: 3px 0; +} + +.pjclass { + color: #909090; + font-size: 13.2px; + margin-bottom: 6px; +} + +.pj_all { + margin: 14px auto; + text-align: center; + width: 99px; + height: 36px; + line-height: 36px; + border: 1px solid #e61329; + color: #e61329; + border-radius: 6px; + font-size: 14.4px; +} + +.shop_info { + background: white; + width: 100%; + border-bottom: 5px solid #ebebeb; +} + +.shop_title { + padding: 12px; +} + +.shop_title img { + width: 48px; + height: 48px; + float: left; +} + +.shop_title p { + float: left; + font-size: 16.8px; + color: black; + margin: 0; + margin-top: 3px; + margin-left: 6px; +} + +.shopinfocon {} + +.sicl { + width: 24%; + border-right: 1px solid #e6e6e6; + text-align: center; + float: left; + margin: 6px 0; +} + +.sicl_p1 { + color: #525252; + font-size: 13.2px; +} + +.sicl_p2 { + color: #909090; + font-size: 13.2px; + margin-top: 9px; +} + +.sicr { + text-align: center; + float: left; + width: calc(28% - 3px); +} + +.sicr_p { + color: #909090; + font-size: 12px; +} + +.sicr_p o { + color: #e61329; +} + +.footer { + width: 100%; + height: 50px; + background: white; + position: fixed; + bottom: 0; + left: 0; + border-top: 1px solid #ebebeb; + z-index: 13; +} + +.footerl { + position: relative; + float: left; + height: 50px; + width: calc(14% - 2px); + text-align: center; +} + +.footerl img { + width: 22.8px; + margin-top: 6px; +} + +.footerl p { + width: 100%; + margin: 0; + font-size: 13.2px; + position: absolute; + bottom: 0; +} + +.footerl1 { + position: relative; + width: 13%; + float: left; + height: 50px; + text-align: center; + border-left: 1px solid #ebebeb; +} + +.footerl1 img { + height: 16.8px; + margin-top: 8px; +} + +.footerl1 p { + width: 100%; + margin: 0; + position: absolute; + bottom: 0; + font-size: 13.2px +} + +.footerr1 { + width: 30%; + height: 50px; + line-height: 50px; + text-align: center; + color: white; + background: #ff9402; + float: right; +} + +.footerr2 { + width: 30%; + height: 50px; + line-height: 50px; + text-align: center; + color: white; + background: #E6122B; + float: right; +} + +.imgcon { + border-bottom: 50px solid #ebebeb; +} + +.imgcon img { + width: 100%; + padding: 0 1%; + display: block; +} + +.pswp__top-bar { + margin-top: 20px; +} + +.ccclass { + width: 100%; +} + +.youhuiquan_con { + position: relative; +} + +.yhq_con { + position: absolute; + bottom: 0; + right: 0; + left: 0; + background: white; +} + +.thq_close { + width: 100%; + height: 51px; + background: #E6122B; + color: white; + text-align: center; + line-height: 51px; +} + +.yhqcon { + padding: 3%; +} + +.thq_block { + width: 100%; + border-radius: 6px; + position: relative; +} + +.thq_block img { + width: 100%; +} + +.thq_block p { + position: absolute; + font-size: 35px; + color: white; + top: 50%; + left: 10px; + transform: translateY(-50%); +} +.thq_block span { + position: absolute; + font-size: 18px; + color: white; + top: 50%; + right: 30%; + transform: translateY(-50%); +} +.lq_btn{ + position: absolute; + font-size: 18px; + color: white; + top: 50%; + right: 0; + transform: translateY(-50%); + border: none; + background: transparent; + width: 25%; + height: 60px; +} +.thq_block .lq_btn:hover{ + background: transparent; + +} +.ccclass{ + /*max-height: 800px;*/ +} +.ccclass .mui-scroll-wrapper{ + /*max-height: 500px;*/ +} +#shareout{ + position: relative; +} +#shareout o{ + width: calc(100% - 50px); + display: block; +} +#shareout img{ + position: absolute; + width: 34.4px; + padding: 10px; + right: 20px; + top: 50%; + transform: translateY(-50%); +} diff --git a/static/app/css/discounts.css b/static/app/css/discounts.css new file mode 100755 index 0000000..e581fb5 --- /dev/null +++ b/static/app/css/discounts.css @@ -0,0 +1,21 @@ +.nav{ + width: 100%; + height: 37px; + margin-top: 66px; + border-bottom: 1px solid #e6e6e6; +} +.p1{ + color: #909090; + width: 33.33333333%; + text-align: center; + display: block; + float: left; + line-height: 36px; + font-size: 13.2px; + background: white; +} +.nav .on{ + color: #e51329; +} + + diff --git a/static/app/css/dynamic.css b/static/app/css/dynamic.css new file mode 100755 index 0000000..acb5403 --- /dev/null +++ b/static/app/css/dynamic.css @@ -0,0 +1,231 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .bc_img,.b_con img { + height: 125px; + } + + .mui-slider { + height: 168px; + } + .mui-slider-item { + height: 168px; + } + .mui-slider .mui-slider-item img { + height: 168px; + width: 100%; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .bc_img,.b_con img { + height: 113px; + } + .mui-slider { + height: 152px; + } + .mui-slider-item { + height: 152px; + } + .mui-slider .mui-slider-item img { + height: 152px; + width: 100%; + } +} + +/* 5 */ + +@media all and (max-width: 320px) { + .bc_img,.b_con img { + height: 94.5px; + } + .mui-slider { + height: 130px; + } + .mui-slider-item { + height: 130px; + } + .mui-slider .mui-slider-item img { + height: 130px; + width: 100%; + } +} +.con{ + width: 100%; + overflow: hidden; +} +.block { + width: 100%; + border-bottom: 6px solid #ebebeb; + background: white; +} + +.b_title { + width: 100%; + position: relative; + height: 60px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.b_title .b_img { + width: 48px; + height: 48px; + position: absolute; + bottom: 0; + left: 15px; +} + +.storename { + position: absolute; + width: calc(100% - 140px); + color: black; + left: 69px; + top: 15px; + font-size: 16.8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.time { + position: absolute; + width: calc(100% - 140px); + left: 69px; + color: #909090; + font-size: 13.2px; + top: 38px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.btn_menu { + width: 38px; + height: 38px; + padding: 10px; + position: absolute; + right: 0; + top: 5px; +} + +.b_con { + width: 100%; + padding: 7.5px 13.5px; + font-size: 14.4px; + color: #525252; +} + +.b_footer { + width: 100%; + height: 36px; + position: relative; +} + +.num { + position: absolute; + width: 90px; + top: 7.5px; + left: 15px; +} + +.num img { + width: 18px; + float: left; +} + +.nun p { + float: left; +} + +.zan { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #909090; + position: absolute; + background: url(../img/zan1.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #909090; + text-indent: 15px; + right: 18px; + bottom: 8px; +} + +.zanon { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #e51329; + position: absolute; + background: url(../img/zan2.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #e51329; + text-indent: 15px; + right: 18px; + bottom: 8px; +} + +.b_con img { + width: calc(33.33333333333% - 3px); + margin: 1.5px; + float: left; +} + +.btn_gz{ + height: 24px; + text-align: center; + border: 1px solid #e91b34; + line-height: 24px; + color: #e91b31; + border-radius: 15px; + padding: 0 9px; + position: absolute; + right: 18px; + font-size: 12px; + top: 25px; +} + +.btn_gz1{ + height: 24px; + text-align: center; + border: 1px solid #909090; + line-height: 24px; + color: #909090; + border-radius: 15px; + padding: 0 9px; + position: absolute; + right: 18px; + font-size: 12px; + top: 25px; +} + + +.bc_img{ + position: relative; + width: calc(33.33333333333% - 3px); + float: left; + margin: 1.5px; +} +.b_con .bc_img img{ + width: 100%; + margin: 0; +} +.bc_img p{ + position: absolute; + text-align: center; + width: 100%; + background: rgba(0,0,0,0.1); + color: white; + bottom: 0; +} diff --git a/static/app/css/ect_address.css b/static/app/css/ect_address.css new file mode 100755 index 0000000..ff1d82f --- /dev/null +++ b/static/app/css/ect_address.css @@ -0,0 +1,75 @@ +.add{ + position: absolute; + right: 10px; + padding: 3px 8px; + top: 30px; + font-size: 13.2px; + color: #f02a40; +} +.header1 .mui-action-back{ + color: #f02a40; +} +.con{ + +} +.con .row{ + width: 100%; + height: 111px; + background: white; + border-bottom: 13.2px solid #ebebeb; +} +.r_con{ + width: 100%; + height: 61px; + border-bottom: 1px solid #dcdcdc; + line-height: 60px; + padding: 0 25px; +} +.r_con p{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13.2px; + color: black; +} +.r_bottom{ + width: 100%; + height: 37px; + position: relative; +} +.check{ + width: 15px; + height: 15px; + border: 1px solid #989898; + border-radius: 50%; + position: absolute; + left: 25px; + top: 50%; + transform: translateY(-50%); +} + +.r_bottom .on{ + background: #F02C43; + border: 1px solid #F02C43; +} +.r_bottom p{ + position: absolute; + left: 54px; + top: 50%; + transform: translateY(-50%); + font-size: 12px; + color: black; +} +.del{ + position: absolute; + right: 18px; + top: 50%; + transform: translateY(-50%); + font-size: 12px; + color: #f02a40; + width: 50px; + height: 22px; + text-align: center; + border: 1px solid #f02a40; + border-radius: 5px; +} diff --git a/static/app/css/ect_index.css b/static/app/css/ect_index.css new file mode 100755 index 0000000..c420f7a --- /dev/null +++ b/static/app/css/ect_index.css @@ -0,0 +1,95 @@ +body { + background: white; +} + +.num { + margin-top: 66px; + width: 100%; + height: 123px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + position: relative; +} + +.num p { + text-align: center; + width: 100%; + position: absolute; + top: 40%; + color: white; + transform: translateY(-40%); + font-size: 48px; +} + +.row { + width: 100%; + height: 67.6px; + position: relative; + border-bottom: 1px solid #e6e6e6; +} + +.row .icon { + width: 39.6px; + height: 39.6px; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 15px; +} + +.row p { + width: calc(100% - 120px); + position: absolute; + color: #525252; + top: 50%; + transform: translateY(-50%); + left: 70px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.row .img{ + width: 24px; + height: 24px; + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 15px; +} +.row span{ + position: absolute; + color: #222222; + top: 50%; + transform: translateY(-50%); + left: 24px; +} +.row #select{ + position: absolute; + top: 50%; + transform: translateY(-50%); + width: calc(100% - 128px); + right: 18px; + border: 1px solid #a0a0a0!important; +} +.row input{ + position: absolute; + top: 50%; + transform: translateY(-50%); + width: calc(100% - 128px); + right: 18px; +} +.btn_ture{ + width: 90%; + margin: 18px 5% ; + height: 42px; + border: none; + background: #F02C43; + color: white; + border-radius: 0; +} diff --git a/static/app/css/ect_list.css b/static/app/css/ect_list.css new file mode 100755 index 0000000..f574099 --- /dev/null +++ b/static/app/css/ect_list.css @@ -0,0 +1,74 @@ +.header1 .mui-action-back{ + color: #f02a40; +} + +.block img{ + width: 100%; +} +.block{ + position: relative; + margin-top: 12px; +} +.block .s1{ + position: absolute; + color: #222222; + font-size: 14.4px; + top: 8%; + left: 18%; + display: inline-block; +} +.block .s2{ + position: absolute; + color: #909090; + font-size: 12px; + top: 15%; + left: 18%; + display: inline-block; +} + +.block .s3{ + position: absolute; + color: #909090; + font-size: 13.2px; + top: 25%; + left: 0; + right: 0; + width: 100%; + text-align: center; + display: inline-block; +} + +.block .s4{ + position: absolute; + color: #f02a40; + font-size: 42px; + top: 45%; + left: 0; + right: 0; + width: 100%; + text-align: center; + display: inline-block; +} +.block .s5{ + position: absolute; + color: #525252; + font-size: 14.4px; + bottom: 20%; + left: 7%; + display: inline-block; +} +.s5 o{ + color: #222222; +} + +.block .s6{ + position: absolute; + color: #525252; + font-size: 14.4px; + bottom: 10%; + left: 7%; + display: inline-block; +} +.s6 o{ + color: #222222; +} diff --git a/static/app/css/editAddress.css b/static/app/css/editAddress.css new file mode 100755 index 0000000..a306b1c --- /dev/null +++ b/static/app/css/editAddress.css @@ -0,0 +1,42 @@ +.row{ + width: 100%; + height: 42px; + border-bottom: 1px solid #E6E6E6; + line-height: 41px; + background: white; +} +.row input{ + border: none; + margin: 0; +} +.row input::-webkit-input-placeholder{ + font-size: 12px +} +.row select{ + float: left; + margin: 0; + width: 33%; + text-align: center; +} +.row select option{ + text-align: center; +} +textarea{ + border-top: none; + font-size: 12px +} +.bc_btn{ + margin: 0 auto; + left: 5%; + right: 5%; + /*position: absolute;*/ + width: 90%; + height: 42px; + border: none; + background: #F02C43; + color: white; +} +.add_info,.isdef{ + padding: 0 15px; + font-size: 12px; +} diff --git a/static/app/css/global.css b/static/app/css/global.css new file mode 100755 index 0000000..cb72ceb --- /dev/null +++ b/static/app/css/global.css @@ -0,0 +1,65 @@ +@media screen and (device-width:375px) and (device-height:812px) { + +} + +.clearfix:after { + height: 0; + content: " "; + display: block; + overflow: hidden; + clear: both; +} + +.clearfix { + zoom: 1; + /*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + +a { + color: black; +} + +a:active { + color: white; +} + +p { + margin: 0; +} + +input { + margin: 0; +} + +img {} + +.scroll_out { + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out1 { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out2 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} +.scroll_out3 { + position: fixed; + top: 162px; + bottom: 0; + left: 0; + right: 0; +} \ No newline at end of file diff --git a/static/app/css/goodsList.css b/static/app/css/goodsList.css new file mode 100755 index 0000000..353a49b --- /dev/null +++ b/static/app/css/goodsList.css @@ -0,0 +1,5 @@ + +.kkkk{ + width: 100%; + height: 66px; +} diff --git a/static/app/css/header.css b/static/app/css/header.css new file mode 100755 index 0000000..841146e --- /dev/null +++ b/static/app/css/header.css @@ -0,0 +1,41 @@ +header { + padding-top: 18px; + line-height: 48px; + text-align: center; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 18px; + z-index: 10; + position: fixed; + width: 100%; + top: 0; + left: 0; +} +header .nav{ + color: white; + /*text-align: center;*/ +} +.mui-bar{ + height: 66px; + color: white; +} + +.mui-title{ + color: white; + bottom: 0; +} + +a{ + color: white; +} + +.mui-bar-nav{ + box-shadow: 0 0 0; +} diff --git a/static/app/css/header1.css b/static/app/css/header1.css new file mode 100755 index 0000000..a683add --- /dev/null +++ b/static/app/css/header1.css @@ -0,0 +1,41 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + left: 0; + right: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} diff --git a/static/app/css/home.css b/static/app/css/home.css new file mode 100755 index 0000000..4495a79 --- /dev/null +++ b/static/app/css/home.css @@ -0,0 +1,706 @@ +body { + background: #efefef; +} + + +/* 6p */ + +@media all and (min-width: 376px) { + .mui-slider {} + .mui-slider-item {} + .mui-slider .mui-slider-item img { + width: 100%; + } + .time { + width: 100%; + height: 188px; + background: white; + } + .time_con { + width: 100%; + height: 150px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 140px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 99px; + } + .cnxh_block img { + max-width: 194px; + max-height: 194px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 194px; + width: 95%; + margin: -5px auto 0; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .mui-slider {} + .mui-slider-item {} + .mui-slider .mui-slider-item img { + width: 100%; + } + .time { + width: 100%; + height: 178px; + background: white; + } + .time_con { + width: 100%; + height: 140px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 130px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 89px; + } + .cnxh_block img { + max-width: 168px; + max-height: 168px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 168px; + width: 95%; + margin: -5px auto 0; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .mui-slider {} + .mui-slider-item {} + .mui-slider .mui-slider-item img { + width: 100%; + } + .time { + width: 100%; + height: 178px; + background: white; + } + .time_con { + width: 100%; + height: 130px; + overflow: hidden; + margin-top: -5px; + } + .time_con .swiper-container { + height: 120px; + width: 100%; + margin-left: 12px; + } + .time_con .swiper-slide img { + width: 100%; + height: 75.5px; + } + .cnxh_block img { + max-width: 144px; + width: 95%; + max-height: 144px; + } + .cnxh_block_info { + background: white; + max-width: 144px; + width: 95%; + margin: -5px auto 0; + } +} + +header { + /*opacity: 0;*/ +} + +.con { + /*height: 5000px;*/ +} + +.mui-slider { + height: 188px; +} + +.mui-slider-item { + height: 188px; +} + +.header { + width: 100%; + height: 66px; + z-index: 14; + position: fixed; + text-align: center; +} + +.mui-bar-transparent { + background-color: rgba(229, 18, 43, 0); +} + +.search { + float: left; + width: calc(100% - 48px); + height: 30px; + background: rgba(255, 255, 255, 0.9); + position: relative; + margin: 24px 24px 0; + /*border: 1px solid #f87240;*/ + /*overflow: hidden;*/ +} + +.search img { + width: 15px; + float: left; + position: absolute; + left: 12px; + top: 7px; +} + +.search span { + color: #989898; + font-size: 13.2px; + position: absolute; + left: 40px; + top: 0; + line-height: 34px; +} + +.nav { + width: 100%; + height: 93px; + background: white; + border-bottom: 6px solid #efefef; +} + +.nav_block { + width: 20%; + height: 87px; + float: left; + text-align: center; +} + +.nav_block img { + width: 51px; + height: 51px; + margin-top: 8px; +} + +.nav_block p { + color: #525252; + font-size: 12.6px; + text-align: center; + margin: 0; + margin-top: -3px; +} + +.msg { + width: calc(100% - 24); + height: 31.2px; + background: white; + margin: 0 12px 6px; + border-radius: 12px; + line-height: 31.2px; +} + +.msg img { + width: 61.2px; + margin: 6px 2%; + float: left; +} + +.msg p { + float: left; + color: #e51329; + line-height: 30px; + margin: 0; + font-size: 12xp; +} + +.msg marquee { + width: 50%; + height: 31.2px; + line-height: 31.2px; + font-size: 12px; + margin-left: 2%; + float: left; +} + +.msg .msg_more { + float: left; + color: black; + margin-left: 2%; + font-size: 12px; +} + +.time_title { + width: 100%; + height: 33px; + line-height: 38px; + background: url(../img/miaoshabg.png) no-repeat left top; + background-size: 100% 100%; +} + +.time_title img { + float: left; + width: 95.4px; + margin-left: 4px; + margin-top: -3px; +} + +.time_title p { + float: left; + font-size: 13.2px; + color: black; + margin: 0; + margin-left: 1.5%; +} + +.count { + margin-left: 1%; + float: left; +} + +.count div { + line-height: 15px; + float: left; + font-size: 10.8px; + color: #fefefe; + background: black; + margin-top: 6px; + padding: 3px 2px; + border-radius: 2px; +} + +.count o { + float: left; + font-size: 10.8px; + line-height: 33px; +} + +.jxyh { + float: right; + font-size: 13.2px; + color: #e51329; + margin-right: 12px; +} + +.time_title .jxyh img { + float: right; + width: 13.8px; + margin-top: 8px; +} + +.time_con .swiper-slide p { + margin: 0; + text-align: center; + color: #e51329; + font-size: 15.6px; +} + +.time_con .swiper-slide del { + display: block; + text-align: center; + color: #909090; + font-size: 12px; +} + +.box { + width: 100%; + background: white; +} + +.box .img { + height: 15.6px; +} + +.box p { + margin: 0; + font-size: 12px; + overflow: hidden; + height: 21px; +} + +.box_1 { + width: 50%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + padding: 9px 12px; + float: left; +} + +.box .box2 { + border-right: none; +} + +.boxcon img { + float: left; + width: 66px; + height: 66px; + margin: 0 calc((100% - 132px)/4); + /*margin-bottom: 5px;*/ +} + +.banner, +.banner1 { + width: 100%; + margin-top: 6px; +} + +.banner .swiper-container, +.banner1 .swiper-container { + padding: 0 12px; +} + +.banner .swiper-container .swiper-wrapper .swiper-slide img, +.banner1 .swiper-container .swiper-wrapper .swiper-slide img { + width: 100%; +} + +.pzss_title { + margin: 0; + margin-top: -9px; +} + +.pzss_title img { + width: 100%; + margin: 0; +} + +.pzss { + margin: 0; + margin-top: -7px; + width: 100%; + background: white; +} + +.pzss1 { + width: 50%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + float: left; + padding-bottom: 9px; +} + +.pzss1 .p1, +.pzss3 .p1 { + margin: 0; + margin-top: 6px; + margin-left: 9px; + color: #525252; + font-size: 15.6px; + overflow: hidden; + height: 21px; +} + +.pzss1 .p2, +.pzss3 .p2 { + margin: 0; + font-size: 12px; + overflow: hidden; + height: 21px; + color: #ee5be2; + margin-left: 9px; +} + +.pzss .pzss2 { + border-right: none; +} + +.pzss3 { + width: 25%; + border-top: 1px solid #e6e6e6; + border-right: 1px solid #e6e6e6; + float: left; +} + +.pzss .pzss4 { + border-right: none; +} + +.pzss3 img { + width: 66px; + height: 66px; + margin: 0 calc(50% - 33px); +} + +.gss .pzss1 .p2, +.gss .pzss3 .p2 { + color: #5b81ee; +} + +.cnxh_block { + width: 50%; + text-align: center; + float: left; + background: #EFEFEF; + border-bottom: 6px solid #efefef; +} + +.s_name { + font-size: 13.2px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + margin: 0; +} + +.s_name o { + font-size: 10.8px; + background: #f02e45; + color: white; + padding: 2px; + border-radius: 3px; + margin-left: 2px; +} + +.cnxh_block_info { + text-align: left; + padding: 2px; + height: 95px; +} + +.cost { + margin: 0; + margin-top: 5px; + font-size: 13.2px; + color: #f45549; +} + +.cost del { + color: #8d8d8d; + font-size: 10.8px; +} +.cost o{ + color: white; + font-size: 10.8px; + background: #E5132C; + border-radius: 3px; + line-height: 10.8px; + padding-top: 1px; +} +.cost_info{ + color: #E51329; + font-size: 9.6px; + background: #dfc4c4; + line-height: 10px; + padding: 4px 3px 1px; + display: inline-block; +} +.search input { + margin: 0; + height: 30px; + border: none; + border-radius: 0; + background: transparent; + padding: 0 50px; + /*padding-left: 50px;*/ +} +.search select{ + border:1px solid red; + position: absolute; + width: 50px; + height: 29px; + padding: 0; + text-align: center; + border-radius: 0; + padding-left: 10px; + padding-top: 2px; +} +.mui-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 998; + background-color: rgba(0,0,0,.3); +} +.mui-backdrop img{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + width: 90%; +} + + +.self_shop{ + width: calc(100% - 18px); + height: 204px; + background: white; + margin: 0 9px; + position: relative; +} +.ss_left{ + height: 204px; + position: absolute; + left: 0; + top: 0; + left: 0; + width: 147px; +} +.self_shop .img{ + float: left; + height: 204px; + display: block; + width: 147px; +} + +.sp1{ + position: absolute; + color: #FFFFFF; + font-size: 13.2px; + top: 12px; + left: 12px; +} + +.sp2{ + position: absolute; + color: #FFFFFF; + font-size: 12px; + top: 45px; + left: 12px; +} + +.sp3{ + position: absolute; + color: #FFFFFF; + font-size: 12px; + top: 63px; + left: 12px; +} + +.ss_left img{ + width: 100px; + height: 100px; + left: 15px; + bottom: 15px; + position: absolute; +} + +.ss_right{ + position: absolute; + width: calc(100% - 147px); + top: 0; + right: 0; + bottom: 0; +} + +.ssr_top{ + width: 100%; + height: 90px; + border-bottom: 1px solid #efefef; + position: relative; +} +.ssr_left,.ssr_right{ + width: 49.5%; + height: 113px; + position: absolute; + bottom: 0; +} +.ssr_left{ + left: 0; + border-right: 1px solid #efefef; +} +.ssr_right{ + right: 0; +} +.sp4{ + position: absolute; + font-size: 14.4px; + color: #ff3262; + left: 15px; + top: 12px; + font-weight: bold; +} +.sp5{ + position: absolute; + font-size: 10.8px; + color: #000; + left: 15px; + top: 33px; +} +.sp6{ + position: absolute; + font-size: 10.8px; + left: 15px; + border: 1px solid #db1a1a; + color: #db1a1a; + padding: 0 3px; + bottom: 12px; + line-height: 18px; +} +.ssr_top img{ + width: 60px; + height: 60px; + position: absolute; + right: 15px; + top: 50%; + transform: translateY(-50%); +} + + +.sp7{ + position: absolute; + font-size: 14.4px; + color: #9a7936; + left: 9px; + top: 6px; + font-weight: bold; +} +.sp8{ + position: absolute; + font-size: 10.8px; + color: #000; + left: 9px; + top: 25px; + +} + +.ssr_left img,.ssr_right img{ + width: 60px; + height: 60px; + position: absolute; + left: 50%; + transform: translateX(-50%); + bottom: 6px; +} +.ssr_right .sp7{ + color: #9b3435; +} +.ssbd{ + width: 100%; + display: block; +} +.search button{ + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; +} diff --git a/static/app/css/indent.css b/static/app/css/indent.css new file mode 100755 index 0000000..92d3fbe --- /dev/null +++ b/static/app/css/indent.css @@ -0,0 +1,48 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} + +.footer{ + position: fixed; + bottom: 0; + width: 100%; + background: white; + height: 49px; + border-top: 1px solid #e6e6e6; +} diff --git a/static/app/css/indentcon.css b/static/app/css/indentcon.css new file mode 100755 index 0000000..2c2b761 --- /dev/null +++ b/static/app/css/indentcon.css @@ -0,0 +1,220 @@ +.search { + padding: 7.2px 12px; + background: #ebebeb; +} + +.mui-search {} + +.mui-search .mui-placeholder { + background: #fff; +} + +.mui-search input { + background: #fff; + margin-bottom: 0; +} + +.mui-active::before { + margin-top: -10px; +} + +.row_title { + width: 100%; + position: relative; + height: 36px; + background: white; +} + +.store_name { + position: absolute; + background: url(../img/youjiantou.png) no-repeat center right; + background-size: 6px; + padding-right: 12px; + padding-left: 18px; + line-height: 36px; + font-size: 13.2px; +} + +.indent_status { + position: absolute; + line-height: 36px; + font-size: 12px; + right: 0; + color: #E5142A; + padding-right: 12px; +} + + +.row{ + border-bottom: 6px solid #ebebeb; + background: white; +} +.row_block { + width: 100%; + /*height: 128px;*/ + border-bottom: 2px solid #fff; + background: #efefef; +} + +.row_block img { + width: 117px; + height: 126px; + float: left; + padding: 9px 0 9px 9px; +} + +.rcr { + width: calc(100% - 117px); + float: right; + /*height: 126px;*/ + padding: 12px; + background: #efefef; +} + +.rcrc { + float: left; + width: calc(100% - 60px); +} + +.rcrc p { + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 12px; + color: black; +} + +.rcrc .leibie{ + color: #909090; +} + + +.rcrr { + width: 60px; + float: right; + text-align: right; +} + + + +.rcrr p { + color: black; + font-size: 12px; +} + +.rcrr del { + color: #909090; + font-size: 12px; + display: block; +} + +.rcrr span { + color: #909090; + font-size: 12px; +} +.combination{ + width: 100%; + height: 37px; + border-bottom: 1px solid #e6e6e6; + background: white; + text-align: right; + font-size: 12px; + line-height: 36px; + padding-right: 15px; +} +.combination o{ + font-size: 14.4px; +} +.btns{ + text-align: right; + width: 100%; + height: 48px; + /*background: white;*/ +} +.btns_btn{ + color: black; + font-size: 14.4px; + padding:3px 6px; + border: 1px solid #909090; + float: right; + margin: 9.5px 6px; + border-radius: 3px; +} +.btns .kk{ + border: 1px solid #e6e6e6; + border-radius: 1px; +} + +.btns .qrsh{ + border: 1px solid #e5132c; + color: #e5142a; +} + +.bg_{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_ts{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_con{ + width: 90%; + /*height: 160px;*/ + background: white; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 30%; + border-radius: 5px; +} +.bg_con p{ + border-bottom: 1px solid #efefef; + padding:10px 20px; + color: black; +} +.bg_con .info1{ + padding:10px 20px; + color: black; + border-bottom: none; +} +.en_true,.ts_true{ + background: #2AC845; + color: white; + /*position: absolute;*/ + margin-left: 30%; + border: none; + margin-bottom: 5%; +} +.en_false,.ts_false{ + background: #efefef; + color: #909090; + /*position: absolute;*/ + margin-right: 30%; + border: none; + float: right; +} +#content,#content_ts,#Tmoney{ + margin: 0 5% 5%; + width: 90%; +} +select{ + margin: 0; +} diff --git a/static/app/css/index.css b/static/app/css/index.css new file mode 100755 index 0000000..254a94b --- /dev/null +++ b/static/app/css/index.css @@ -0,0 +1,8 @@ +.mui-bar-tab { + height: 48px; + background: white; +} + +.mui-bar .mui-tab-item .mui-icon img { + height: 39.6px; +} \ No newline at end of file diff --git a/static/app/css/journalism.css b/static/app/css/journalism.css new file mode 100755 index 0000000..0ec8b89 --- /dev/null +++ b/static/app/css/journalism.css @@ -0,0 +1,50 @@ +.scroll_out{ + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} +.block{ + width: 100%; + height: 135px; + border-bottom: 6px solid #ebebeb; + background: white; + position: relative; +} +.block p{ + width: calc(100% - 150px); + position: absolute; + left: 15px; + top: 25px; + color: black; + font-size: 15.6px; +} + +.block img{ + width: 102px; + height: 102px; + position: absolute; + right: 12px; + top: 12px; +} +.block span{ + color: #909090; + position: absolute; + left: 15px; + height: 30px; + line-height: 30px; + bottom: 10px; + text-indent: 20px; + font-size: 12px; +} +.block span o{ + width: 15px; + height: 15px; + background: #909090; + border-radius: 50%; + display: inline-block; + position: absolute; + left: 0; + top: 7px; +} diff --git a/static/app/css/login.css b/static/app/css/login.css new file mode 100755 index 0000000..7de04f7 --- /dev/null +++ b/static/app/css/login.css @@ -0,0 +1,84 @@ +.con{ + margin-top: 78px; + +} +.row{ + width: 100%; + height: 42px; + background: white; + border-top:1px solid #e6e6e6; +} +.row img{ + width: 25.2px; + height: 25.2px; + float: left; + margin: 7px; +} +.s1{ + float: left; + line-height: 42px; + color: #525252; + font-size: 13.2px; +} +.con .row input{ + float: left; + margin: 0; + width: calc( 100% - 100px); + border: none; + +} +.con .row input::-webkit-input-placeholder{ + font-size: 13.2px; +} +.down{ + width: 100%; + padding: 12px; +} +.down .btn{ + width: 100%; + height: 42px; + text-align: center; + line-height: 42px; + color: white; + background: #f02c43; + padding: 0; +} +.s2{ + color: #525252; + font-size: 12px; + display: block; + margin-top: 6px; +} +#register{ + float: left; +} +#fogetpsd{ + float: right; +} +.ac1_left{ + width: 100%; + height: 66px; + position: relative; + line-height: 66px; +} +.con .row .yzm,.con .row .tpyzm{ + width: calc( 100% - 210px); +} +.con .row #mobileCode,.con .row #mobileCode1{ + width: 110px; + float: right; + margin-top: 4px; + text-align: center; + height: 33px; + line-height: 33px; + border-left: 1px solid #e6e6e6; + color: #909090; + font-size: 13.2px; + padding: 0; + +} +.row .yzmhh{ + width:100px; + height: 31px; + margin-top: 5px; +} diff --git a/static/app/css/logistics.css b/static/app/css/logistics.css new file mode 100755 index 0000000..aa85a49 --- /dev/null +++ b/static/app/css/logistics.css @@ -0,0 +1,117 @@ +body .header1 { + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ +} + +.header1 .p1 { + color: white; +} + +.header1 .mui-action-back { + color: white; +} + +.summarize { + border-bottom: 6px solid #efefef; + background: white; +} + +.summarize img { + float: left; + width: 54px; + height: 54px; + margin: 15px 12px; +} + +.summarizeinfo { + float: left; + width: calc( 100% - 78px); + padding: 3px 0; +} + +.pp1 { + color: #525252; + font-size: 14.4px; +} + +.pp1 o { + color: #e51329; +} + +.pp2 { + color: #525252; + font-size: 12px; +} + +.pp2 o { + color: #e51329; +} + +.track-list { + position: relative; + background: white; +} + +.track-list ul { + margin: 0; + padding-left: 20px; + +} + +ul li { + list-style: none; +} + +.track-list li { + position: relative; + padding: 9px 0 0 25px; + line-height: 18px; + border-left: 1px solid #d9d9d9; + color: #999; +} + +.track-list li.first { + color: red; + padding-top: 9px; + border-left-color: #fff; +} +.track-list li.first p{ + color: #72ca87; +} +.track-list li .node-icon { + position: absolute; + left: -6px; + top: 50%; + width: 11px; + height: 11px; + background: url(../img/order-icons.png) -21px -72px no-repeat; +} + +.track-list li.first .node-icon { + background-position: 0 -72px; +} + +.track-list li .time { + margin-right: 20px; + border-bottom: 1px solid #e6e6e6; + padding-bottom: 9px; +} + +.track-list li .txt { + padding-bottom: 3px; + margin-right: 20px; +} + +.track-list li.first .time { + margin-right: 20px; +} + +.track-list li.first .txt { + max-width: 600px; +} \ No newline at end of file diff --git a/static/app/css/msg.css b/static/app/css/msg.css new file mode 100755 index 0000000..0391605 --- /dev/null +++ b/static/app/css/msg.css @@ -0,0 +1,68 @@ +.con1 { + border-bottom: 6px solid #efefef; +} + +.row { + width: 100%; + height: 60px; + background: white; + border-bottom: 1px solid #e6e6e6; +} + +.row .img { + width: 45px; + height: 45px; + margin: 7.5px; + float: left; + border-radius: 5px; + overflow: hidden; +} +.row .img img{ + width: 100%; + height: 100%; +} + +.r_right { + width: calc(100% - 60px); + float: left; + padding: 9px; +} + +.r_right p { + margin: 0; +} + +.rrt_left { + float: left; + font-size: 14.4px; + color: black; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: calc(100% - 160px); +} + +.rrt_right { + float: right; + font-size: 13.2px; + color: #909090; +} + +.r_r_con { + font-size: 13.2px; + color: #909090; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.c2_title{ + width: 100%; + height: 45px; + line-height: 45px; + padding-left: 7.5px; + font-size: 14.4px; + color: #525252; + background: white; + border-bottom: 1px solid #e6e6e6; +} diff --git a/static/app/css/msg_con.css b/static/app/css/msg_con.css new file mode 100755 index 0000000..cea161d --- /dev/null +++ b/static/app/css/msg_con.css @@ -0,0 +1,17 @@ +.time{ + padding: 5px; + text-align: center; + background: #d2d2d2; + color: white; + width: 180px; + margin: 10px auto; + font-size: 13.2px; + border-radius: 2px; +} +.con_{ + width: 90%; + background: white; + margin: 5%; + padding: 3%; + border-radius: 5px; +} diff --git a/static/app/css/mui.css b/static/app/css/mui.css new file mode 100755 index 0000000..738eb5b --- /dev/null +++ b/static/app/css/mui.css @@ -0,0 +1,5615 @@ +/*! + * ===================================================== + * Mui v3.7.0 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ + +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */ +html +{ + font-family: sans-serif; + + -webkit-text-size-adjust: 100%; +} + +body +{ + margin: 0; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary +{ + display: block; +} + +audio, +canvas, +progress, +video +{ + display: inline-block; + + vertical-align: baseline; +} + +audio:not([controls]) +{ + display: none; + + height: 0; +} + +[hidden], +template +{ + display: none; +} + +a +{ + background: transparent; +} + +a:active, +a:hover +{ + outline: 0; +} + +abbr[title] +{ + border-bottom: 1px dotted; +} + +b, +strong +{ + font-weight: bold; +} + +dfn +{ + font-style: italic; +} + +h1 +{ + font-size: 2em; + + margin: .67em 0; +} + +mark +{ + color: #000; + background: #ff0; +} + +small +{ + font-size: 80%; +} + +sub, +sup +{ + font-size: 75%; + line-height: 0; + + position: relative; + + vertical-align: baseline; +} + +sup +{ + top: -.5em; +} + +sub +{ + bottom: -.25em; +} + +img +{ + border: 0; +} + +svg:not(:root) +{ + overflow: hidden; +} + +figure +{ + margin: 1em 40px; +} + +hr +{ + box-sizing: content-box; + height: 0; +} + +pre +{ + overflow: auto; +} + +code, +kbd, +pre, +samp +{ + font-family: monospace, monospace; + font-size: 1em; +} + +button, +input, +optgroup, +select, +textarea +{ + font: inherit; + + margin: 0; + + color: inherit; +} + +button +{ + overflow: visible; +} + +button, +select +{ + text-transform: none; +} + +button, +html input[type='button'], +input[type='reset'], +input[type='submit'] +{ + cursor: pointer; + + -webkit-appearance: button; +} + +button[disabled], +html input[disabled] +{ + cursor: default; +} + +input +{ + line-height: normal; +} + +input[type='checkbox'], +input[type='radio'] +{ + box-sizing: border-box; + padding: 0; +} + +input[type='number']::-webkit-inner-spin-button, +input[type='number']::-webkit-outer-spin-button +{ + height: auto; +} + +input[type='search'] +{ + -webkit-box-sizing: content-box; + box-sizing: content-box; + + -webkit-appearance: textfield; +} + +input[type='search']::-webkit-search-cancel-button, +input[type='search']::-webkit-search-decoration +{ + -webkit-appearance: none; +} + +fieldset +{ + margin: 0 2px; + padding: .35em .625em .75em; + + border: 1px solid #c0c0c0; +} + +legend +{ + padding: 0; + + border: 0; +} + +textarea +{ + overflow: auto; +} + +optgroup +{ + font-weight: bold; +} + +table +{ + border-spacing: 0; + border-collapse: collapse; +} + +td, +th +{ + padding: 0; +} + +* +{ + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -webkit-user-select: none; + + outline: none; + + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; +} + +body +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + font-size: 17px; + line-height: 21px; + + color: #000; + background-color: #efeff4; + + -webkit-overflow-scrolling: touch; +} + +a +{ + text-decoration: none; + + color: #007aff; +} +a:active +{ + color: #0062cc; +} + +.mui-content +{ + background-color: #efeff4; + + -webkit-overflow-scrolling: touch; +} + +.mui-bar-nav ~ .mui-content +{ + padding-top: 44px; +} +.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + top: 44px; +} + +.mui-bar-header-secondary ~ .mui-content +{ + padding-top: 88px; +} +.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + top: 88px; +} + +.mui-bar-footer ~ .mui-content +{ + padding-bottom: 44px; +} +.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 44px; +} + +.mui-bar-footer-secondary ~ .mui-content +{ + padding-bottom: 88px; +} +.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 88px; +} + +.mui-bar-tab ~ .mui-content +{ + padding-bottom: 50px; +} +.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 50px; +} + +.mui-bar-footer-secondary-tab ~ .mui-content +{ + padding-bottom: 94px; +} +.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 94px; +} + +.mui-content-padded +{ + margin: 10px; +} + +.mui-inline +{ + display: inline-block; + + vertical-align: top; +} + +.mui-block +{ + display: block !important; +} + +.mui-visibility +{ + visibility: visible !important; +} + +.mui-hidden +{ + display: none !important; +} + +.mui-ellipsis +{ + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; +} + +.mui-ellipsis-2 +{ + display: -webkit-box; + overflow: hidden; + + white-space: normal !important; + text-overflow: ellipsis; + word-wrap: break-word; + + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.mui-table +{ + display: table; + + width: 100%; + + table-layout: fixed; +} + +.mui-table-cell +{ + position: relative; + + display: table-cell; +} + +.mui-text-left +{ + text-align: left !important; +} + +.mui-text-center +{ + text-align: center !important; +} + +.mui-text-justify +{ + text-align: justify !important; +} + +.mui-text-right +{ + text-align: right !important; +} + +.mui-pull-left +{ + float: left; +} + +.mui-pull-right +{ + float: right; +} + +.mui-list-unstyled +{ + padding-left: 0; + + list-style: none; +} + +.mui-list-inline +{ + margin-left: -5px; + padding-left: 0; + + list-style: none; +} + +.mui-list-inline > li +{ + display: inline-block; + + padding-right: 5px; + padding-left: 5px; +} + +.mui-clearfix:before, .mui-clearfix:after +{ + display: table; + + content: ' '; +} +.mui-clearfix:after +{ + clear: both; +} + +.mui-bg-primary +{ + background-color: #007aff; +} + +.mui-bg-positive +{ + background-color: #4cd964; +} + +.mui-bg-negative +{ + background-color: #dd524d; +} + +.mui-error +{ + margin: 88px 35px; + padding: 10px; + + border-radius: 6px; + background-color: #bbb; +} + +.mui-subtitle +{ + font-size: 15px; +} + +h1, h2, h3, h4, h5, h6 +{ + line-height: 1; + + margin-top: 5px; + margin-bottom: 5px; +} + +h1, .mui-h1 +{ + font-size: 36px; +} + +h2, .mui-h2 +{ + font-size: 30px; +} + +h3, .mui-h3 +{ + font-size: 24px; +} + +h4, .mui-h4 +{ + font-size: 18px; +} + +h5, .mui-h5 +{ + font-size: 14px; + font-weight: normal; + + color: #8f8f94; +} + +h6, .mui-h6 +{ + font-size: 12px; + font-weight: normal; + + color: #8f8f94; +} + +p +{ + font-size: 14px; + + margin-top: 0; + margin-bottom: 10px; + + color: #8f8f94; +} + +.mui-row:before, .mui-row:after +{ + display: table; + + content: ' '; +} +.mui-row:after +{ + clear: both; +} + +.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12 +{ + position: relative; + + min-height: 1px; +} + +.mui-row > [class*='mui-col-'] +{ + float: left; +} + +.mui-col-xs-12 +{ + width: 100%; +} + +.mui-col-xs-11 +{ + width: 91.66666667%; +} + +.mui-col-xs-10 +{ + width: 83.33333333%; +} + +.mui-col-xs-9 +{ + width: 75%; +} + +.mui-col-xs-8 +{ + width: 66.66666667%; +} + +.mui-col-xs-7 +{ + width: 58.33333333%; +} + +.mui-col-xs-6 +{ + width: 50%; +} + +.mui-col-xs-5 +{ + width: 41.66666667%; +} + +.mui-col-xs-4 +{ + width: 33.33333333%; +} + +.mui-col-xs-3 +{ + width: 25%; +} + +.mui-col-xs-2 +{ + width: 16.66666667%; +} + +.mui-col-xs-1 +{ + width: 8.33333333%; +} + +@media (min-width: 400px) +{ + .mui-col-sm-12 + { + width: 100%; + } + + .mui-col-sm-11 + { + width: 91.66666667%; + } + + .mui-col-sm-10 + { + width: 83.33333333%; + } + + .mui-col-sm-9 + { + width: 75%; + } + + .mui-col-sm-8 + { + width: 66.66666667%; + } + + .mui-col-sm-7 + { + width: 58.33333333%; + } + + .mui-col-sm-6 + { + width: 50%; + } + + .mui-col-sm-5 + { + width: 41.66666667%; + } + + .mui-col-sm-4 + { + width: 33.33333333%; + } + + .mui-col-sm-3 + { + width: 25%; + } + + .mui-col-sm-2 + { + width: 16.66666667%; + } + + .mui-col-sm-1 + { + width: 8.33333333%; + } +} +.mui-scroll-wrapper +{ + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + + overflow: hidden; + + width: 100%; +} + +.mui-scroll +{ + position: absolute; + z-index: 1; + + width: 100%; + + -webkit-transform: translateZ(0); + transform: translateZ(0); +} + +.mui-scrollbar +{ + position: absolute; + z-index: 9998; + + overflow: hidden; + + -webkit-transition: 500ms; + transition: 500ms; + transform: translateZ(0px); + pointer-events: none; + + opacity: 0; +} + +.mui-scrollbar-vertical +{ + top: 0; + right: 1px; + bottom: 2px; + + width: 4px; +} +.mui-scrollbar-vertical .mui-scrollbar-indicator +{ + width: 100%; +} + +.mui-scrollbar-horizontal +{ + right: 2px; + bottom: 0; + left: 2px; + + height: 4px; +} +.mui-scrollbar-horizontal .mui-scrollbar-indicator +{ + height: 100%; +} + +.mui-scrollbar-indicator +{ + position: absolute; + + display: block; + + box-sizing: border-box; + + -webkit-transition: .01s cubic-bezier(.1, .57, .1, 1); + transition: .01s cubic-bezier(.1, .57, .1, 1); + transform: translate(0px, 0px) translateZ(0px); + + border: 1px solid rgba(255, 255, 255, .80196); + border-radius: 2px; + background: rgba(0, 0, 0, .39804); +} + +.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper +{ + position: absolute; + top: 0; + bottom: 0; + left: 0; + + overflow: hidden; + + width: 100%; +} +.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll +{ + position: absolute; + + width: 100%; +} +.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group +{ + position: static; + top: auto; + bottom: auto; + left: auto; + + overflow: auto; + + width: auto; +} +.mui-plus-pullrefresh .mui-slider-group +{ + overflow: visible; +} +.mui-plus-pullrefresh .mui-scroll +{ + position: static; + + width: auto; +} + +.mui-off-canvas-wrap .mui-bar +{ + position: absolute !important; + + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-off-canvas-wrap +{ + position: relative; + z-index: 1; + + overflow: hidden; + + width: 100%; + height: 100%; +} +.mui-off-canvas-wrap .mui-inner-wrap +{ + position: relative; + z-index: 1; + + width: 100%; + height: 100%; +} +.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms; + transition: transform 350ms cubic-bezier(.165, .84, .44, 1); +} +.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left +{ + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right +{ + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); +} +.mui-off-canvas-wrap.mui-active +{ + overflow: hidden; + + height: 100%; +} +.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop +{ + position: absolute; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + display: block; + + transition: background 350ms cubic-bezier(.165, .84, .44, 1); + + background: rgba(0, 0, 0, .4); + box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5); + + -webkit-tap-highlight-color: transparent; +} +.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right +{ + z-index: 10000 !important; + + -webkit-transform: translate3d(100%, 0px, 0px); +} +.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left +{ + z-index: 10000 !important; + + -webkit-transform: translate3d(-100%, 0px, 0px); +} + +.mui-off-canvas-left, .mui-off-canvas-right +{ + position: absolute; + z-index: -1; + top: 0; + bottom: 0; + + visibility: hidden; + + box-sizing: content-box; + width: 70%; + min-height: 100%; + + background: #333; + + -webkit-overflow-scrolling: touch; +} +.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1); + transition: transform 350ms cubic-bezier(.165, .84, .44, 1); +} + +.mui-off-canvas-left +{ + left: 0; +} + +.mui-off-canvas-right +{ + right: 0; +} + +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable +{ + background-color: #333; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right +{ + width: 80%; + + -webkit-transform: scale(.8); + transform: scale(.8); + + opacity: .1; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1); + transition: transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1); +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left +{ + -webkit-transform-origin: -100%; + transform-origin: -100%; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right +{ + -webkit-transform-origin: 200%; + transform-origin: 200%; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap +{ + -webkit-transform: scale(.8); + transform: scale(.8); +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right +{ + -webkit-transform: scale(1); + transform: scale(1); + + opacity: 1; +} + +.mui-loading .mui-spinner +{ + display: block; + + margin: 0 auto; +} + +.mui-spinner +{ + display: inline-block; + + width: 24px; + height: 24px; + + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: spinner-spin 1s step-end infinite; + animation: spinner-spin 1s step-end infinite; +} + +.mui-spinner:after +{ + display: block; + + width: 100%; + height: 100%; + + content: ''; + + background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>'); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; +} + +.mui-spinner-white:after +{ + background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>'); +} + +@-webkit-keyframes spinner-spin +{ + 0% + { + -webkit-transform: rotate(0deg); + } + + 8.33333333% + { + -webkit-transform: rotate(30deg); + } + + 16.66666667% + { + -webkit-transform: rotate(60deg); + } + + 25% + { + -webkit-transform: rotate(90deg); + } + + 33.33333333% + { + -webkit-transform: rotate(120deg); + } + + 41.66666667% + { + -webkit-transform: rotate(150deg); + } + + 50% + { + -webkit-transform: rotate(180deg); + } + + 58.33333333% + { + -webkit-transform: rotate(210deg); + } + + 66.66666667% + { + -webkit-transform: rotate(240deg); + } + + 75% + { + -webkit-transform: rotate(270deg); + } + + 83.33333333% + { + -webkit-transform: rotate(300deg); + } + + 91.66666667% + { + -webkit-transform: rotate(330deg); + } + + 100% + { + -webkit-transform: rotate(360deg); + } +} +@keyframes spinner-spin +{ + 0% + { + transform: rotate(0deg); + } + + 8.33333333% + { + transform: rotate(30deg); + } + + 16.66666667% + { + transform: rotate(60deg); + } + + 25% + { + transform: rotate(90deg); + } + + 33.33333333% + { + transform: rotate(120deg); + } + + 41.66666667% + { + transform: rotate(150deg); + } + + 50% + { + transform: rotate(180deg); + } + + 58.33333333% + { + transform: rotate(210deg); + } + + 66.66666667% + { + transform: rotate(240deg); + } + + 75% + { + transform: rotate(270deg); + } + + 83.33333333% + { + transform: rotate(300deg); + } + + 91.66666667% + { + transform: rotate(330deg); + } + + 100% + { + transform: rotate(360deg); + } +} +input[type='button'], +input[type='submit'], +input[type='reset'], +button, +.mui-btn +{ + font-size: 14px; + font-weight: 400; + line-height: 1.42; + + position: relative; + + display: inline-block; + + margin-bottom: 0; + padding: 6px 12px; + + cursor: pointer; + -webkit-transition: all; + transition: all; + -webkit-transition-timing-function: linear; + transition-timing-function: linear; + -webkit-transition-duration: .2s; + transition-duration: .2s; + text-align: center; + vertical-align: top; + white-space: nowrap; + + color: #333; + border: 1px solid #ccc; + border-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + background-color: #fff; + background-clip: padding-box; +} +input[type='button']:enabled:active, input[type='button'].mui-active:enabled, +input[type='submit']:enabled:active, +input[type='submit'].mui-active:enabled, +input[type='reset']:enabled:active, +input[type='reset'].mui-active:enabled, +button:enabled:active, +button.mui-active:enabled, +.mui-btn:enabled:active, +.mui-btn.mui-active:enabled +{ + color: #fff; + background-color: #929292; +} +input[type='button']:disabled, input[type='button'].mui-disabled, +input[type='submit']:disabled, +input[type='submit'].mui-disabled, +input[type='reset']:disabled, +input[type='reset'].mui-disabled, +button:disabled, +button.mui-disabled, +.mui-btn:disabled, +.mui-btn.mui-disabled +{ + opacity: .6; +} + +input[type='submit'], +.mui-btn-primary, +.mui-btn-blue +{ + color: #fff; + border: 1px solid #007aff; + background-color: #007aff; +} +input[type='submit']:enabled:active, input[type='submit'].mui-active:enabled, +.mui-btn-primary:enabled:active, +.mui-btn-primary.mui-active:enabled, +.mui-btn-blue:enabled:active, +.mui-btn-blue.mui-active:enabled +{ + color: #fff; + border: 1px solid #0062cc; + background-color: #0062cc; +} + +.mui-btn-positive, +.mui-btn-success, +.mui-btn-green +{ + color: #fff; + border: 1px solid #4cd964; + background-color: #4cd964; +} +.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled, +.mui-btn-success:enabled:active, +.mui-btn-success.mui-active:enabled, +.mui-btn-green:enabled:active, +.mui-btn-green.mui-active:enabled +{ + color: #fff; + border: 1px solid #2ac845; + background-color: #2ac845; +} + +.mui-btn-warning, +.mui-btn-yellow +{ + color: #fff; + border: 1px solid #f0ad4e; + background-color: #f0ad4e; +} +.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled, +.mui-btn-yellow:enabled:active, +.mui-btn-yellow.mui-active:enabled +{ + color: #fff; + border: 1px solid #ec971f; + background-color: #ec971f; +} + +.mui-btn-negative, +.mui-btn-danger, +.mui-btn-red +{ + color: #fff; + border: 1px solid #dd524d; + background-color: #dd524d; +} +.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled, +.mui-btn-danger:enabled:active, +.mui-btn-danger.mui-active:enabled, +.mui-btn-red:enabled:active, +.mui-btn-red.mui-active:enabled +{ + color: #fff; + border: 1px solid #cf2d28; + background-color: #cf2d28; +} + +.mui-btn-royal, +.mui-btn-purple +{ + color: #fff; + border: 1px solid #8a6de9; + background-color: #8a6de9; +} +.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled, +.mui-btn-purple:enabled:active, +.mui-btn-purple.mui-active:enabled +{ + color: #fff; + border: 1px solid #6641e2; + background-color: #6641e2; +} + +.mui-btn-grey +{ + color: #fff; + border: 1px solid #c7c7cc; + background-color: #c7c7cc; +} +.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled +{ + color: #fff; + border: 1px solid #acacb4; + background-color: #acacb4; +} + +.mui-btn-outlined +{ + background-color: transparent; +} +.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue +{ + color: #007aff; +} +.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green +{ + color: #4cd964; +} +.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow +{ + color: #f0ad4e; +} +.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red +{ + color: #dd524d; +} +.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple +{ + color: #8a6de9; +} +.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active +{ + color: #fff; +} + +.mui-btn-link +{ + padding-top: 6px; + padding-bottom: 6px; + + color: #007aff; + border: 0; + background-color: transparent; +} +.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled +{ + color: #0062cc; + background-color: transparent; +} + +.mui-btn-block +{ + font-size: 18px; + + display: block; + + width: 100%; + margin-bottom: 10px; + padding: 15px 0; +} + +.mui-btn .mui-badge +{ + font-size: 14px; + + margin: -2px -4px -2px 4px; + + background-color: rgba(0, 0, 0, .15); +} + +.mui-btn .mui-badge-inverted, +.mui-btn:enabled:active .mui-badge-inverted +{ + background-color: transparent; +} + +.mui-btn-primary:enabled:active .mui-badge-inverted, +.mui-btn-positive:enabled:active .mui-badge-inverted, +.mui-btn-negative:enabled:active .mui-badge-inverted +{ + color: #fff; +} + +.mui-btn-block .mui-badge +{ + position: absolute; + right: 0; + + margin-right: 10px; +} + +.mui-btn .mui-icon +{ + font-size: inherit; +} + +.mui-btn.mui-icon +{ + font-size: 14px; + line-height: 1.42; +} + +.mui-btn.mui-fab +{ + width: 56px; + height: 56px; + padding: 16px; + + border-radius: 50%; + outline: none; +} +.mui-btn.mui-fab.mui-btn-mini +{ + width: 40px; + height: 40px; + padding: 8px; +} +.mui-btn.mui-fab .mui-icon +{ + font-size: 24px; + line-height: 24px; + + width: 24px; + height: 24px; +} + +.mui-btn .mui-spinner +{ + width: 14px; + height: 14px; + + vertical-align: text-bottom; +} + +.mui-btn-block .mui-spinner +{ + width: 22px; + height: 22px; +} + +.mui-bar +{ + position: fixed; + z-index: 10; + right: 0; + left: 0; + + height: 44px; + padding-right: 10px; + padding-left: 10px; + + border-bottom: 0; + background-color: #f7f7f7; + -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85); + box-shadow: 0 0 1px rgba(0, 0, 0, .85); + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.mui-bar .mui-title +{ + right: 40px; + left: 40px; + + display: inline-block; + overflow: hidden; + + width: auto; + margin: 0; + + text-overflow: ellipsis; +} +.mui-bar .mui-backdrop +{ + background: none; +} + +.mui-bar-header-secondary +{ + top: 44px; +} + +.mui-bar-footer +{ + bottom: 0; +} + +.mui-bar-footer-secondary +{ + bottom: 44px; +} + +.mui-bar-footer-secondary-tab +{ + bottom: 50px; +} + +.mui-bar-footer, +.mui-bar-footer-secondary, +.mui-bar-footer-secondary-tab +{ + border-top: 0; +} + +.mui-bar-transparent +{ + top: 0; + + background-color: rgba(247, 247, 247, 0); + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-bar-nav +{ + top: 0; + + -webkit-box-shadow: 0 1px 6px #ccc; + box-shadow: 0 1px 6px #ccc; +} +.mui-bar-nav ~ .mui-content .mui-anchor +{ + display: block; + visibility: hidden; + + height: 45px; + margin-top: -45px; +} +.mui-bar-nav.mui-bar .mui-icon +{ + margin-right: -10px; + margin-left: -10px; + padding-right: 10px; + padding-left: 10px; +} + +.mui-title +{ + font-size: 17px; + font-weight: 500; + line-height: 44px; + + position: absolute; + + display: block; + + width: 100%; + margin: 0 -10px; + padding: 0; + + text-align: center; + white-space: nowrap; + + color: #000; +} + +.mui-title a +{ + color: inherit; +} + +.mui-bar-tab +{ + bottom: 0; + + display: table; + + width: 100%; + height: 50px; + padding: 0; + + table-layout: fixed; + + border-top: 0; + border-bottom: 0; + + -webkit-touch-callout: none; +} +.mui-bar-tab .mui-tab-item +{ + display: table-cell; + overflow: hidden; + + width: 1%; + height: 50px; + + text-align: center; + vertical-align: middle; + white-space: nowrap; + text-overflow: ellipsis; + + color: #929292; +} +.mui-bar-tab .mui-tab-item.mui-active +{ + color: #007aff; +} +.mui-bar-tab .mui-tab-item .mui-icon +{ + top: 3px; + + width: 24px; + height: 24px; + padding-top: 0; + padding-bottom: 0; +} +.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label +{ + font-size: 11px; + + display: block; + overflow: hidden; + + text-overflow: ellipsis; +} +.mui-bar-tab .mui-tab-item .mui-icon:active +{ + background: none; +} + +.mui-focusin > .mui-bar-nav, +.mui-focusin > .mui-bar-header-secondary +{ + position: absolute; +} + +.mui-focusin > .mui-bar ~ .mui-content +{ + padding-bottom: 0; +} + +.mui-bar .mui-btn +{ + font-weight: 400; + + position: relative; + z-index: 20; + top: 7px; + + margin-top: 0; + padding: 6px 12px 7px; +} +.mui-bar .mui-btn.mui-pull-right +{ + margin-left: 10px; +} +.mui-bar .mui-btn.mui-pull-left +{ + margin-right: 10px; +} + +.mui-bar .mui-btn-link +{ + font-size: 16px; + line-height: 44px; + + top: 0; + + padding: 0; + + color: #007aff; + border: 0; +} +.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active +{ + color: #0062cc; +} + +.mui-bar .mui-btn-block +{ + font-size: 16px; + + top: 6px; + + margin-bottom: 0; + padding: 5px 0; +} + +.mui-bar .mui-btn-nav.mui-pull-left +{ + margin-left: -5px; +} +.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav +{ + margin-right: -3px; +} +.mui-bar .mui-btn-nav.mui-pull-right +{ + margin-right: -5px; +} +.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav +{ + margin-left: -3px; +} +.mui-bar .mui-btn-nav:active +{ + opacity: .3; +} + +.mui-bar .mui-icon +{ + font-size: 24px; + + position: relative; + z-index: 20; + + padding-top: 10px; + padding-bottom: 10px; +} +.mui-bar .mui-icon:active +{ + opacity: .3; +} +.mui-bar .mui-btn .mui-icon +{ + top: 1px; + + margin: 0; + padding: 0; +} +.mui-bar .mui-title .mui-icon +{ + margin: 0; + padding: 0; +} +.mui-bar .mui-title .mui-icon.mui-icon-caret +{ + top: 4px; + + margin-left: -5px; +} + +.mui-bar input[type='search'] +{ + height: 29px; + margin: 6px 0; +} + +.mui-bar .mui-input-row .mui-btn +{ + padding: 12px 10px; +} + +.mui-bar .mui-search:before +{ + margin-top: -10px; +} + +.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear, +.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + top: 0; + right: 12px; +} + +.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear, +.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + top: 0; + right: 0; +} + +.mui-bar .mui-segmented-control +{ + top: 7px; + + width: auto; + margin: 0 auto; +} + +.mui-bar.mui-bar-header-secondary .mui-segmented-control +{ + top: 0; +} + +.mui-badge +{ + font-size: 12px; + line-height: 1; + + display: inline-block; + + padding: 3px 6px; + + color: #333; + border-radius: 100px; + background-color: rgba(0, 0, 0, .15); +} +.mui-badge.mui-badge-inverted +{ + padding: 0 5px 0 0; + + color: #929292; + background-color: transparent; +} + +.mui-badge-primary, .mui-badge-blue +{ + color: #fff; + background-color: #007aff; +} +.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted +{ + color: #007aff; + background-color: transparent; +} + +.mui-badge-success, .mui-badge-green +{ + color: #fff; + background-color: #4cd964; +} +.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted +{ + color: #4cd964; + background-color: transparent; +} + +.mui-badge-warning, .mui-badge-yellow +{ + color: #fff; + background-color: #f0ad4e; +} +.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted +{ + color: #f0ad4e; + background-color: transparent; +} + +.mui-badge-danger, .mui-badge-red +{ + color: #fff; + background-color: #dd524d; +} +.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted +{ + color: #dd524d; + background-color: transparent; +} + +.mui-badge-royal, .mui-badge-purple +{ + color: #fff; + background-color: #8a6de9; +} +.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted +{ + color: #8a6de9; + background-color: transparent; +} + +.mui-icon .mui-badge +{ + font-size: 10px; + line-height: 1.4; + + position: absolute; + top: -2px; + left: 100%; + + margin-left: -10px; + padding: 1px 5px; + + color: white; + background: red; +} + +.mui-card +{ + font-size: 14px; + + position: relative; + + overflow: hidden; + + margin: 10px; + + border-radius: 2px; + background-color: white; + background-clip: padding-box; + box-shadow: 0 1px 2px rgba(0, 0, 0, .3); +} + +.mui-content > .mui-card:first-child +{ + margin-top: 15px; +} + +.mui-card .mui-input-group:before, .mui-card .mui-input-group:after +{ + height: 0; +} +.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after +{ + height: 0; +} + +.mui-card .mui-table-view +{ + margin-bottom: 0; + + border-top: 0; + border-bottom: 0; + border-radius: 6px; +} +.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child +{ + top: 0; + + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} +.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child +{ + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.mui-card .mui-table-view:before, .mui-card .mui-table-view:after +{ + height: 0; +} + +.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after +{ + height: 0; +} + +.mui-card-header, +.mui-card-footer +{ + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + min-height: 44px; + padding: 10px 15px; + + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} +.mui-card-header .mui-card-link, +.mui-card-footer .mui-card-link +{ + line-height: 44px; + + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 44px; + margin-top: -10px; + margin-bottom: -10px; + + -webkit-transition-duration: .3s; + transition-duration: .3s; + text-decoration: none; + + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} + +.mui-card-header:after, +.mui-card-footer:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-card-header +{ + font-size: 17px; + + border-radius: 2px 2px 0 0; +} +.mui-card-header:after +{ + top: auto; + bottom: 0; +} +.mui-card-header > img:first-child +{ + font-size: 0; + line-height: 0; + + float: left; + + width: 34px; + height: 34px; +} + +.mui-card-footer +{ + color: #6d6d72; + border-radius: 0 0 2px 2px; +} + +.mui-card-content +{ + font-size: 14px; + + position: relative; +} + +.mui-card-content-inner +{ + position: relative; + + padding: 15px; +} + +.mui-card-media +{ + vertical-align: bottom; + + color: #fff; + background-position: center; + background-size: cover; +} + +.mui-card-header.mui-card-media +{ + display: block; + + padding: 10px; +} +.mui-card-header.mui-card-media .mui-media-body +{ + font-size: 14px; + font-weight: 500; + line-height: 17px; + + margin-bottom: 0; + margin-left: 44px; + + color: #333; +} +.mui-card-header.mui-card-media .mui-media-body p +{ + font-size: 13px; + + margin-bottom: 0; +} + +.mui-table-view +{ + position: relative; + + margin-top: 0; + margin-bottom: 0; + padding-left: 0; + + list-style: none; + + background-color: #fff; +} +.mui-table-view:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view:before +{ + top: -1px; +} + +.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon +{ + font-size: 20px; + + margin-top: -1px; + margin-right: 5px; + margin-left: -5px; +} +.mui-table-view-icon .mui-table-view-cell:after +{ + left: 40px; +} + +.mui-table-view-chevron .mui-table-view-cell +{ + padding-right: 65px; +} +.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn) +{ + margin-right: -65px; +} + +.mui-table-view-radio .mui-table-view-cell +{ + padding-right: 65px; +} +.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn) +{ + margin-right: -65px; +} +.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after +{ + font-size: 30px; + font-weight: 600; + + right: 9px; + + content: ''; + + color: #007aff; +} +.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after +{ + content: '\e472'; +} + +.mui-table-view-inverted +{ + color: #fff; + background: #333; +} +.mui-table-view-inverted:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted .mui-table-view-cell.mui-active +{ + background-color: #242424; +} +.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background-color: #242424; +} + +.mui-table-view-cell +{ + position: relative; + + overflow: hidden; + + padding: 11px 15px; + + -webkit-touch-callout: none; +} +.mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox] +{ + top: 8px; +} +.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left +{ + padding-left: 58px; +} +.mui-table-view-cell.mui-active +{ + background-color: #eee; +} +.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after +{ + height: 0; +} +.mui-table-view-cell > a:not(.mui-btn) +{ + position: relative; + + display: block; + overflow: hidden; + + margin: -11px -15px; + padding: inherit; + + white-space: nowrap; + text-overflow: ellipsis; + + color: inherit; + /*&:active { + background-color: #eee; + }*/ +} +.mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background-color: #eee; +} +.mui-table-view-cell p +{ + margin-bottom: 0; +} + +.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn +{ + -webkit-transition: -webkit-transform 300ms ease; + transition: transform 300ms ease; +} +.mui-table-view-cell.mui-active > .mui-slider-handle +{ + background-color: #eee; +} +.mui-table-view-cell > .mui-slider-handle +{ + position: relative; + + background-color: #fff; +} +.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after +{ + right: 0; +} +.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn +{ + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; +} +.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right +{ + position: absolute; + top: 0; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 100%; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn +{ + position: relative; + left: 0; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + padding: 0 30px; + + color: #fff; + border: 0; + border-radius: 0; + + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after +{ + position: absolute; + z-index: -1; + top: 0; + + width: 600%; + height: 100%; + + content: ''; + + background: inherit; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon +{ + font-size: 30px; +} +.mui-table-view-cell > .mui-slider-right +{ + right: 0; + + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +.mui-table-view-cell > .mui-slider-left +{ + left: 0; + + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +.mui-table-view-cell > .mui-slider-left > .mui-btn:after +{ + right: 100%; + + margin-right: -1px; +} + +.mui-table-view-divider +{ + font-weight: 500; + + position: relative; + + margin-top: -1px; + margin-left: 0; + padding-top: 6px; + padding-bottom: 6px; + padding-left: 15px; + + color: #999; + background-color: #fafafa; +} +.mui-table-view-divider:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view-divider:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view .mui-media, +.mui-table-view .mui-media-body +{ + overflow: hidden; +} + +.mui-table-view .mui-media-large .mui-media-object +{ + line-height: 80px; + + max-width: 80px; + height: 80px; +} +.mui-table-view .mui-media .mui-subtitle +{ + color: #000; +} +.mui-table-view .mui-media-object +{ + line-height: 42px; + + max-width: 42px; + height: 42px; +} +.mui-table-view .mui-media-object.mui-pull-left +{ + margin-right: 10px; +} +.mui-table-view .mui-media-object.mui-pull-right +{ + margin-left: 10px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object +{ + line-height: 29px; + + max-width: 29px; + height: 29px; + margin: -4px 0; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img +{ + line-height: 29px; + + max-width: 29px; + height: 29px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left +{ + margin-right: 10px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon +{ + font-size: 29px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 55px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view .mui-table-view-cell.mui-media-icon:after +{ + height: 0 !important; +} + +.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view +{ + display: block; +} +.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after +{ + height: 0 !important; +} +.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 70px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view-cell > .mui-btn, +.mui-table-view-cell > .mui-badge, +.mui-table-view-cell > .mui-switch, +.mui-table-view-cell > a > .mui-btn, +.mui-table-view-cell > a > .mui-badge, +.mui-table-view-cell > a > .mui-switch +{ + position: absolute; + top: 50%; + right: 15px; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.mui-table-view-cell .mui-navigate-right > .mui-btn, +.mui-table-view-cell .mui-navigate-right > .mui-badge, +.mui-table-view-cell .mui-navigate-right > .mui-switch, +.mui-table-view-cell .mui-push-left > .mui-btn, +.mui-table-view-cell .mui-push-left > .mui-badge, +.mui-table-view-cell .mui-push-left > .mui-switch, +.mui-table-view-cell .mui-push-right > .mui-btn, +.mui-table-view-cell .mui-push-right > .mui-badge, +.mui-table-view-cell .mui-push-right > .mui-switch, +.mui-table-view-cell > a .mui-navigate-right > .mui-btn, +.mui-table-view-cell > a .mui-navigate-right > .mui-badge, +.mui-table-view-cell > a .mui-navigate-right > .mui-switch, +.mui-table-view-cell > a .mui-push-left > .mui-btn, +.mui-table-view-cell > a .mui-push-left > .mui-badge, +.mui-table-view-cell > a .mui-push-left > .mui-switch, +.mui-table-view-cell > a .mui-push-right > .mui-btn, +.mui-table-view-cell > a .mui-push-right > .mui-badge, +.mui-table-view-cell > a .mui-push-right > .mui-switch +{ + right: 35px; +} + +.mui-content > .mui-table-view:first-child +{ + margin-top: 15px; +} + +.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after +{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after +{ + height: 0; +} +.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after +{ + content: '\e581'; +} +.mui-table-view-cell.mui-collapse.mui-active +{ + margin-top: -1px; +} +.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content +{ + display: block; +} +.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after +{ + content: '\e580'; +} +.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + margin-left: -31px; + padding-left: 47px; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content +{ + position: relative; + + display: none; + overflow: hidden; + + margin: 11px -15px -11px; + padding: 8px 15px; + + -webkit-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; + + background: white; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider +{ + width: auto; + height: auto; + margin: -8px -15px; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider +{ + margin: -8px -16px; +} +.mui-table-view-cell.mui-collapse .mui-table-view +{ + display: none; + + margin-top: 11px; + margin-right: -15px; + margin-bottom: -11px; + margin-left: -15px; + + border: 0; +} +.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron +{ + margin-right: -65px; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell +{ + padding-left: 31px; + + background-position: 31px 100%; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 30px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view.mui-grid-view +{ + font-size: 0; + + display: block; + + width: 100%; + padding: 0 10px 10px 0; + + white-space: normal; +} +.mui-table-view.mui-grid-view .mui-table-view-cell +{ + font-size: 17px; + + display: inline-block; + + margin-right: -4px; + padding: 10px 0 0 14px; + + text-align: center; + vertical-align: middle; + + background: none; +} +.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object +{ + width: 100%; + max-width: 100%; + height: auto; +} +.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn) +{ + margin: -10px 0 0 -14px; +} +.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background: none; +} +.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body +{ + font-size: 15px; + line-height: 15px; + + display: block; + + width: 100%; + height: 15px; + margin-top: 8px; + + text-overflow: ellipsis; + + color: #333; +} +.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after +{ + height: 0; +} + +.mui-grid-view.mui-grid-9 +{ + margin: 0; + padding: 0; + + border-top: 1px solid #eee; + border-left: 1px solid #eee; + background-color: #f2f2f2; +} +.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after +{ + display: table; + + content: ' '; +} +.mui-grid-view.mui-grid-9:after +{ + clear: both; +} +.mui-grid-view.mui-grid-9:after +{ + position: static; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell +{ + margin: 0; + padding: 11px 15px; + + vertical-align: top; + + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active +{ + background-color: #eee; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn) +{ + margin: 0; + padding: 10px 0; +} +.mui-grid-view.mui-grid-9:before +{ + height: 0; +} +.mui-grid-view.mui-grid-9 .mui-media +{ + color: #797979; +} +.mui-grid-view.mui-grid-9 .mui-media .mui-icon +{ + font-size: 2.4em; + + position: relative; +} + +.mui-slider-cell +{ + position: relative; +} +.mui-slider-cell > .mui-slider-handle +{ + z-index: 1; +} +.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right +{ + position: absolute; + z-index: 0; + top: 0; + bottom: 0; +} +.mui-slider-cell > .mui-slider-left +{ + left: 0; +} +.mui-slider-cell > .mui-slider-right +{ + right: 0; +} + +input, +textarea, +select +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + font-size: 17px; + + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; +} +input:focus, +textarea:focus, +select:focus +{ + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; + -webkit-user-modify: read-write-plaintext-only; +} + +select, +textarea, +input[type='text'], +input[type='search'], +input[type='password'], +input[type='datetime'], +input[type='datetime-local'], +input[type='date'], +input[type='month'], +input[type='time'], +input[type='week'], +input[type='number'], +input[type='email'], +input[type='url'], +input[type='tel'], +input[type='color'] +{ + line-height: 21px; + + width: 100%; + height: 40px; + margin-bottom: 15px; + padding: 10px 15px; + + -webkit-user-select: text; + + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 3px; + outline: none; + background-color: #fff; + + -webkit-appearance: none; +} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button +{ + margin: 0; + + -webkit-appearance: none; +} + +input[type='search'] +{ + font-size: 16px; + + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: 34px; + + text-align: center; + + border: 0; + border-radius: 6px; + background-color: rgba(0, 0, 0, .1); +} + +input[type='search']:focus +{ + text-align: left; +} + +textarea +{ + height: auto; + + resize: none; +} + +select +{ + font-size: 14px; + + height: auto; + margin-top: 1px; + + border: 0 !important; + background-color: #fff; +} +select:focus +{ + -webkit-user-modify: read-only; +} + +.mui-input-group +{ + position: relative; + + padding: 0; + + border: 0; + background-color: #fff; +} +.mui-input-group:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-input-group:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-input-group input, +.mui-input-group textarea +{ + margin-bottom: 0; + + border: 0; + border-radius: 0; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-input-group input[type='search'] +{ + background: none; +} + +.mui-input-group input:last-child +{ + background-image: none; +} + +.mui-input-row +{ + clear: left; + overflow: hidden; +} +.mui-input-row select +{ + font-size: 17px; + + height: 37px; + padding: 0; +} + +.mui-input-row:last-child, +.mui-input-row label + input, .mui-input-row .mui-btn + input +{ + background: none; +} + +.mui-input-group .mui-input-row +{ + height: 40px; +} +.mui-input-group .mui-input-row:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-input-row label +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + line-height: 1.1; + + float: left; + + width: 35%; + padding: 11px 15px; +} + +.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea +{ + float: right; + + width: 65%; + margin-bottom: 0; + padding-left: 0; + + border: 0; +} + +.mui-input-row .mui-btn +{ + line-height: 1.1; + + float: right; + + width: 15%; + padding: 10px 15px; +} + +.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea +{ + float: left; + + width: 85%; + margin-bottom: 0; + padding-left: 0; + + border: 0; +} + +.mui-button-row +{ + position: relative; + + padding-top: 5px; + + text-align: center; +} + +.mui-input-group .mui-button-row +{ + height: 45px; +} + +.mui-input-row +{ + position: relative; +} +.mui-input-row.mui-input-range +{ + overflow: visible; + + padding-right: 20px; +} +.mui-input-row .mui-inline +{ + padding: 8px 0; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye +{ + font-size: 20px; + + position: absolute; + z-index: 1; + top: 10px; + right: 0; + + width: 38px; + height: 38px; + + text-align: center; + + color: #999; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active +{ + color: #007aff; +} +.mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + font-size: 24px; + + top: 8px; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech +{ + display: none; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech +{ + display: inline-block; +} +.mui-input-row .mui-icon-speech ~ .mui-placeholder +{ + right: 38px; +} +.mui-input-row.mui-search .mui-icon-clear +{ + top: 7px; +} +.mui-input-row.mui-search .mui-icon-speech +{ + top: 5px; +} + +.mui-radio, .mui-checkbox +{ + position: relative; +} +.mui-radio label, .mui-checkbox label +{ + display: inline-block; + float: none; + + width: 100%; + padding-right: 58px; +} + +.mui-radio.mui-left input[type='radio'], .mui-checkbox.mui-left input[type='checkbox'] +{ + left: 20px; +} + +.mui-radio.mui-left label, .mui-checkbox.mui-left label +{ + padding-right: 15px; + padding-left: 58px; +} + +.mui-radio input[type='radio'], .mui-checkbox input[type='checkbox'] +{ + position: absolute; + top: 4px; + right: 20px; + + display: inline-block; + + width: 28px; + height: 26px; + + border: 0; + outline: 0 !important; + background-color: transparent; + + -webkit-appearance: none; +} +.mui-radio input[type='radio'][disabled]:before, .mui-checkbox input[type='checkbox'][disabled]:before +{ + opacity: .3; +} +.mui-radio input[type='radio']:before, .mui-checkbox input[type='checkbox']:before +{ + font-family: Muiicons; + font-size: 28px; + font-weight: normal; + line-height: 1; + + text-decoration: none; + + color: #aaa; + border-radius: 0; + background: none; + + -webkit-font-smoothing: antialiased; +} +.mui-radio input[type='radio']:checked:before, .mui-checkbox input[type='checkbox']:checked:before +{ + color: #007aff; +} + +.mui-radio.mui-disabled label, .mui-radio label.mui-disabled, .mui-checkbox.mui-disabled label, .mui-checkbox label.mui-disabled +{ + opacity: .4; +} + +.mui-radio input[type='radio']:before +{ + content: '\e411'; +} + +.mui-radio input[type='radio']:checked:before +{ + content: '\e441'; +} + +.mui-checkbox input[type='checkbox']:before +{ + content: '\e411'; +} + +.mui-checkbox input[type='checkbox']:checked:before +{ + content: '\e442'; +} + +.mui-select +{ + position: relative; +} + +.mui-select:before +{ + font-family: Muiicons; + + position: absolute; + top: 8px; + right: 21px; + + content: '\e581'; + + color: rgba(170, 170, 170, .6); +} + +.mui-input-row .mui-switch +{ + float: right; + + margin-top: 5px; + margin-right: 20px; +} + +.mui-input-range +{ + /*input[type="range"] { + -webkit-appearance: none; + background: #999; + height: 36px; + border-radius: 1px; + overflow: hidden; + margin-top: 2px; + margin-bottom: 2px; + outline:none; + position:relative; + width:100%; + }*/ + /*input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none!important; + opacity: 0.5; + height:28px; + width:28px; + border-radius: 50%; + background:#00b7fb; + position: relative; + pointer-events: none; + -webkit-box-sizing: border-box; + box-sizing: border-box; + &:before{ + position: absolute; + top: 13px; + left: -2000px; + width: 2000px; + height: 2px; + background: #00b7fb; + content:' '; + } + }*/ +} +.mui-input-range input[type='range'] +{ + position: relative; + + width: 100%; + height: 2px; + margin: 17px 0; + padding: 0; + + cursor: pointer; + + border: 0; + border-radius: 3px; + outline: none; + background-color: #999; + + -webkit-appearance: none !important; +} +.mui-input-range input[type='range']::-webkit-slider-thumb +{ + width: 28px; + height: 28px; + + border-color: #0062cc; + border-radius: 50%; + background-color: #007aff; + background-clip: padding-box; + + -webkit-appearance: none !important; +} +.mui-input-range label ~ input[type='range'] +{ + width: 65%; +} +.mui-input-range .mui-tooltip +{ + font-size: 36px; + line-height: 64px; + + position: absolute; + z-index: 1; + top: -70px; + + width: 64px; + height: 64px; + + text-align: center; + + opacity: .8; + color: #333; + border: 1px solid #ddd; + border-radius: 6px; + background-color: #fff; + text-shadow: 0 1px 0 #f3f3f3; +} + +.mui-search +{ + position: relative; +} +.mui-search input[type='search'] +{ + padding-left: 30px; +} +.mui-search .mui-placeholder +{ + font-size: 16px; + line-height: 34px; + + position: absolute; + z-index: 1; + top: 0; + right: 0; + bottom: 0; + left: 0; + + display: inline-block; + + height: 34px; + + text-align: center; + + color: #999; + border: 0; + border-radius: 6px; + background: none; +} +.mui-search .mui-placeholder .mui-icon +{ + font-size: 20px; + + color: #333; +} +.mui-search:before +{ + font-family: Muiicons; + font-size: 20px; + font-weight: normal; + + position: absolute; + top: 50%; + right: 50%; + + display: none; + + margin-top: -18px; + margin-right: 31px; + + content: '\e466'; +} +.mui-search.mui-active:before +{ + font-size: 20px; + + right: auto; + left: 5px; + + display: block; + + margin-right: 0; +} +.mui-search.mui-active input[type='search'] +{ + text-align: left; +} +.mui-search.mui-active .mui-placeholder +{ + display: none; +} + +.mui-segmented-control +{ + font-size: 15px; + font-weight: 400; + + position: relative; + + display: table; + overflow: hidden; + + width: 100%; + + table-layout: fixed; + + border: 1px solid #007aff; + border-radius: 3px; + background-color: transparent; + + -webkit-touch-callout: none; +} +.mui-segmented-control.mui-segmented-control-vertical +{ + border-collapse: collapse; + + border-width: 0; + border-radius: 0; +} +.mui-segmented-control.mui-segmented-control-vertical .mui-control-item +{ + display: block; + + border-bottom: 1px solid #c8c7cc; + border-left-width: 0; +} +.mui-segmented-control.mui-scroll-wrapper +{ + height: 38px; +} +.mui-segmented-control.mui-scroll-wrapper .mui-scroll +{ + width: auto; + height: 40px; + + white-space: nowrap; +} +.mui-segmented-control.mui-scroll-wrapper .mui-control-item +{ + display: inline-block; + + width: auto; + padding: 0 20px; + + border: 0; +} +.mui-segmented-control .mui-control-item +{ + line-height: 38px; + + display: table-cell; + overflow: hidden; + + width: 1%; + + -webkit-transition: background-color .1s linear; + transition: background-color .1s linear; + text-align: center; + white-space: nowrap; + text-overflow: ellipsis; + + color: #007aff; + border-color: #007aff; + border-left: 1px solid #007aff; +} +.mui-segmented-control .mui-control-item:first-child +{ + border-left-width: 0; +} +.mui-segmented-control .mui-control-item.mui-active +{ + color: #fff; + background-color: #007aff; +} +.mui-segmented-control.mui-segmented-control-inverted +{ + width: 100%; + + border: 0; + border-radius: 0; +} +.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item +{ + border-bottom: 1px solid #c8c7cc; +} +.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active +{ + border-bottom: 1px solid #c8c7cc; +} +.mui-segmented-control.mui-segmented-control-inverted .mui-control-item +{ + color: inherit; + border: 0; +} +.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #007aff; + border-bottom: 2px solid #007aff; + background: none; +} +.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #007aff; +} + +.mui-segmented-control-positive +{ + border: 1px solid #4cd964; +} +.mui-segmented-control-positive .mui-control-item +{ + color: #4cd964; + border-color: inherit; +} +.mui-segmented-control-positive .mui-control-item.mui-active +{ + color: #fff; + background-color: #4cd964; +} +.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #4cd964; + border-bottom: 2px solid #4cd964; + background: none; +} +.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #4cd964; +} + +.mui-segmented-control-negative +{ + border: 1px solid #dd524d; +} +.mui-segmented-control-negative .mui-control-item +{ + color: #dd524d; + border-color: inherit; +} +.mui-segmented-control-negative .mui-control-item.mui-active +{ + color: #fff; + background-color: #dd524d; +} +.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #dd524d; + border-bottom: 2px solid #dd524d; + background: none; +} +.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #dd524d; +} + +.mui-control-content +{ + position: relative; + + display: none; +} +.mui-control-content.mui-active +{ + display: block; +} + +.mui-popover +{ + position: absolute; + z-index: 999; + + display: none; + + width: 280px; + + -webkit-transition: opacity .3s; + transition: opacity .3s; + -webkit-transition-property: opacity; + transition-property: opacity; + -webkit-transform: none; + transform: none; + + opacity: 0; + border-radius: 7px; + background-color: #f7f7f7; + -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1); + box-shadow: 0 0 15px rgba(0, 0, 0, .1); +} +.mui-popover .mui-popover-arrow +{ + position: absolute; + z-index: 1000; + top: -25px; + left: 0; + + overflow: hidden; + + width: 26px; + height: 26px; +} +.mui-popover .mui-popover-arrow:after +{ + position: absolute; + top: 19px; + left: 0; + + width: 26px; + height: 26px; + + content: ' '; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + + border-radius: 3px; + background: #f7f7f7; +} +.mui-popover .mui-popover-arrow.mui-bottom +{ + top: 100%; + left: -26px; + + margin-top: -1px; +} +.mui-popover .mui-popover-arrow.mui-bottom:after +{ + top: -19px; + left: 0; +} +.mui-popover.mui-popover-action +{ + bottom: 0; + + width: 100%; + + -webkit-transition: -webkit-transform .3s, opacity .3s; + transition: transform .3s, opacity .3s; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + + border-radius: 0; + background: none; + -webkit-box-shadow: none; + box-shadow: none; +} +.mui-popover.mui-popover-action .mui-popover-arrow +{ + display: none; +} +.mui-popover.mui-popover-action.mui-popover-bottom +{ + position: fixed; +} +.mui-popover.mui-popover-action.mui-active +{ + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.mui-popover.mui-popover-action .mui-table-view +{ + margin: 8px; + + text-align: center; + + color: #007aff; + border-radius: 4px; +} +.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-popover.mui-popover-action .mui-table-view small +{ + font-weight: 400; + line-height: 1.3; + + display: block; +} +.mui-popover.mui-active +{ + display: block; + + opacity: 1; +} +.mui-popover .mui-bar ~ .mui-table-view +{ + padding-top: 44px; +} + +.mui-backdrop +{ + position: fixed; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + background-color: rgba(0, 0, 0, .3); +} + +.mui-bar-backdrop.mui-backdrop +{ + bottom: 50px; + + background: none; +} + +.mui-backdrop-action.mui-backdrop +{ + background-color: rgba(0, 0, 0, .3); +} + +.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop +{ + opacity: 0; +} +.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active +{ + -webkit-transition: all .4s ease; + transition: all .4s ease; + + opacity: 1; +} + +.mui-popover .mui-btn-block +{ + margin-bottom: 5px; +} +.mui-popover .mui-btn-block:last-child +{ + margin-bottom: 0; +} + +.mui-popover .mui-bar +{ + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-popover .mui-bar-nav +{ + border-bottom: 1px solid rgba(0, 0, 0, .15); + border-top-left-radius: 12px; + border-top-right-radius: 12px; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-popover .mui-scroll-wrapper +{ + margin: 7px 0; + + border-radius: 7px; + background-clip: padding-box; +} + +.mui-popover .mui-scroll .mui-table-view +{ + max-height: none; +} + +.mui-popover .mui-table-view +{ + overflow: auto; + + max-height: 300px; + margin-bottom: 0; + + border-radius: 7px; + background-color: #f7f7f7; + background-image: none; + + -webkit-overflow-scrolling: touch; +} +.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after +{ + height: 0; +} +.mui-popover .mui-table-view .mui-table-view-cell:first-child, +.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn) +{ + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} +.mui-popover .mui-table-view .mui-table-view-cell:last-child, +.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn) +{ + border-bottom-right-radius: 12px; + border-bottom-left-radius: 12px; +} + +.mui-popover.mui-bar-popover .mui-table-view +{ + width: 106px; +} +.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell +{ + padding: 11px 15px 11px 15px; + + background-position: 0 100%; +} +.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn) +{ + margin: -11px -15px -11px -15px; +} + +.mui-popup-backdrop +{ + position: fixed; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + + opacity: 0; + background: rgba(0, 0, 0, .4); +} +.mui-popup-backdrop.mui-active +{ + opacity: 1; +} + +.mui-popup +{ + position: fixed; + z-index: 10000; + top: 50%; + left: 50%; + + display: none; + overflow: hidden; + + width: 270px; + + -webkit-transition-property: -webkit-transform,opacity; + transition-property: transform,opacity; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1.185); + transform: translate3d(-50%, -50%, 0) scale(1.185); + text-align: center; + + opacity: 0; + color: #000; + border-radius: 13px; +} +.mui-popup.mui-popup-in +{ + display: block; + + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); + + opacity: 1; +} +.mui-popup.mui-popup-out +{ + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); + + opacity: 0; +} + +.mui-popup-inner +{ + position: relative; + + padding: 15px; + + border-radius: 13px 13px 0 0; + background: rgba(255, 255, 255, .95); +} +.mui-popup-inner:after +{ + position: absolute; + z-index: 15; + top: auto; + right: auto; + bottom: 0; + left: 0; + + display: block; + + width: 100%; + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; + + background-color: rgba(0, 0, 0, .2); +} + +.mui-popup-title +{ + font-size: 18px; + font-weight: 500; + + text-align: center; +} + +.mui-popup-title + .mui-popup-text +{ + font-family: inherit; + font-size: 14px; + + margin: 5px 0 0; +} + +.mui-popup-buttons +{ + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 44px; + + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; +} + +.mui-popup-button +{ + font-size: 17px; + line-height: 44px; + + position: relative; + + display: block; + overflow: hidden; + + box-sizing: border-box; + width: 100%; + height: 44px; + padding: 0 5px; + + cursor: pointer; + text-align: center; + white-space: nowrap; + text-overflow: ellipsis; + + color: #007aff; + background: rgba(255, 255, 255, .95); + + -webkit-box-flex: 1; +} +.mui-popup-button:after +{ + position: absolute; + z-index: 15; + top: 0; + right: 0; + bottom: auto; + left: auto; + + display: block; + + width: 1px; + height: 100%; + + content: ''; + -webkit-transform: scaleX(.5); + transform: scaleX(.5); + -webkit-transform-origin: 100% 50%; + transform-origin: 100% 50%; + + background-color: rgba(0, 0, 0, .2); +} +.mui-popup-button:first-child +{ + border-radius: 0 0 0 13px; +} +.mui-popup-button:first-child:last-child +{ + border-radius: 0 0 13px 13px; +} +.mui-popup-button:last-child +{ + border-radius: 0 0 13px 0; +} +.mui-popup-button:last-child:after +{ + display: none; +} +.mui-popup-button.mui-popup-button-bold +{ + font-weight: 600; +} + +.mui-popup-input input +{ + font-size: 14px; + + width: 100%; + height: 26px; + margin: 15px 0 0; + padding: 0 5px; + + border: 1px solid rgba(0, 0, 0, .3); + border-radius: 0; + background: #fff; +} + +.mui-plus.mui-android .mui-popup-backdrop +{ + -webkit-transition-duration: 1ms; + transition-duration: 1ms; +} + +.mui-plus.mui-android .mui-popup +{ + -webkit-transition-duration: 1ms; + transition-duration: 1ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); +} + +/* === Progress Bar === */ +.mui-progressbar +{ + position: relative; + + display: block; + overflow: hidden; + + width: 100%; + height: 2px; + + -webkit-transform-origin: center top; + transform-origin: center top; + vertical-align: middle; + + border-radius: 2px; + background: #b6b6b6; + + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.mui-progressbar span +{ + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + -webkit-transition: 150ms; + transition: 150ms; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + + background: #007aff; +} +.mui-progressbar.mui-progressbar-infinite:before +{ + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + content: ''; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + -webkit-animation: mui-progressbar-infinite 1s linear infinite; + animation: mui-progressbar-infinite 1s linear infinite; + + background: #007aff; +} + +body > .mui-progressbar +{ + position: absolute; + z-index: 10000; + top: 44px; + left: 0; + + border-radius: 0; +} + +.mui-progressbar-in +{ + -webkit-animation: mui-progressbar-in 300ms forwards; + animation: mui-progressbar-in 300ms forwards; +} + +.mui-progressbar-out +{ + -webkit-animation: mui-progressbar-out 300ms forwards; + animation: mui-progressbar-out 300ms forwards; +} + +@-webkit-keyframes mui-progressbar-in +{ + from + { + -webkit-transform: scaleY(0); + + opacity: 0; + } + + to + { + -webkit-transform: scaleY(1); + + opacity: 1; + } +} +@keyframes mui-progressbar-in +{ + from + { + transform: scaleY(0); + + opacity: 0; + } + + to + { + transform: scaleY(1); + + opacity: 1; + } +} +@-webkit-keyframes mui-progressbar-out +{ + from + { + -webkit-transform: scaleY(1); + + opacity: 1; + } + + to + { + -webkit-transform: scaleY(0); + + opacity: 0; + } +} +@keyframes mui-progressbar-out +{ + from + { + transform: scaleY(1); + + opacity: 1; + } + + to + { + transform: scaleY(0); + + opacity: 0; + } +} +@-webkit-keyframes mui-progressbar-infinite +{ + 0% + { + -webkit-transform: translate3d(-50%, 0, 0) scaleX(.5); + } + + 100% + { + -webkit-transform: translate3d(100%, 0, 0) scaleX(.5); + } +} +@keyframes mui-progressbar-infinite +{ + 0% + { + transform: translate3d(-50%, 0, 0) scaleX(.5); + } + + 100% + { + transform: translate3d(100%, 0, 0) scaleX(.5); + } +} +.mui-pagination +{ + display: inline-block; + + margin: 0 auto; + padding-left: 0; + + border-radius: 6px; +} +.mui-pagination > li +{ + display: inline; +} +.mui-pagination > li > a, +.mui-pagination > li > span +{ + line-height: 1.428571429; + + position: relative; + + float: left; + + margin-left: -1px; + padding: 6px 12px; + + text-decoration: none; + + color: #007aff; + border: 1px solid #ddd; + background-color: #fff; +} +.mui-pagination > li:first-child > a, +.mui-pagination > li:first-child > span +{ + margin-left: 0; + + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + background-clip: padding-box; +} +.mui-pagination > li:last-child > a, +.mui-pagination > li:last-child > span +{ + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + background-clip: padding-box; +} +.mui-pagination > li:active > a, .mui-pagination > li:active > a:active, +.mui-pagination > li:active > span, +.mui-pagination > li:active > span:active, +.mui-pagination > li.mui-active > a, +.mui-pagination > li.mui-active > a:active, +.mui-pagination > li.mui-active > span, +.mui-pagination > li.mui-active > span:active +{ + z-index: 2; + + cursor: default; + + color: #fff; + border-color: #007aff; + background-color: #007aff; +} +.mui-pagination > li.mui-disabled > span, +.mui-pagination > li.mui-disabled > span:active, +.mui-pagination > li.mui-disabled > a, +.mui-pagination > li.mui-disabled > a:active +{ + opacity: .6; + color: #777; + border: 1px solid #ddd; + background-color: #fff; +} + +.mui-pagination-lg > li > a, +.mui-pagination-lg > li > span +{ + font-size: 18px; + + padding: 10px 16px; +} + +.mui-pagination-sm > li > a, +.mui-pagination-sm > li > span +{ + font-size: 12px; + + padding: 5px 10px; +} + +.mui-pager +{ + padding-left: 0; + + list-style: none; + + text-align: center; +} +.mui-pager:before, .mui-pager:after +{ + display: table; + + content: ' '; +} +.mui-pager:after +{ + clear: both; +} +.mui-pager li +{ + display: inline; +} +.mui-pager li > a, +.mui-pager li > span +{ + display: inline-block; + + padding: 5px 14px; + + border: 1px solid #ddd; + border-radius: 6px; + background-color: #fff; + background-clip: padding-box; +} +.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span +{ + cursor: default; + text-decoration: none; + + color: #fff; + border-color: #007aff; + background-color: #007aff; +} +.mui-pager .mui-next > a, +.mui-pager .mui-next > span +{ + float: right; +} +.mui-pager .mui-previous > a, +.mui-pager .mui-previous > span +{ + float: left; +} +.mui-pager .mui-disabled > a, +.mui-pager .mui-disabled > a:active, +.mui-pager .mui-disabled > span, +.mui-pager .mui-disabled > span:active +{ + opacity: .6; + color: #777; + border: 1px solid #ddd; + background-color: #fff; +} + +.mui-modal +{ + position: fixed; + z-index: 999; + top: 0; + + overflow: hidden; + + width: 100%; + min-height: 100%; + + -webkit-transition: -webkit-transform .25s, opacity 1ms .25s; + transition: transform .25s, opacity 1ms .25s; + -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1); + transition-timing-function: cubic-bezier(.1, .5, .1, 1); + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + + opacity: 0; + background-color: #fff; +} +.mui-modal.mui-active +{ + height: 100%; + + -webkit-transition: -webkit-transform .25s; + transition: transform .25s; + -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1); + transition-timing-function: cubic-bezier(.1, .5, .1, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + + opacity: 1; +} + +.mui-android .mui-modal .mui-bar +{ + position: static; +} + +.mui-android .mui-modal .mui-bar-nav ~ .mui-content +{ + padding-top: 0; +} + +.mui-slider +{ + position: relative; + z-index: 1; + + overflow: hidden; + + width: 100%; +} +.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active +{ + border-bottom: 0; +} +.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item +{ + border-top: 1px solid #c8c7cc; + border-bottom: 1px solid #c8c7cc; +} +.mui-slider .mui-slider-group +{ + font-size: 0; + + position: relative; + + -webkit-transition: all 0s linear; + transition: all 0s linear; + white-space: nowrap; +} +.mui-slider .mui-slider-group .mui-slider-item +{ + font-size: 14px; + + position: relative; + + display: inline-block; + + width: 100%; + height: 100%; + + vertical-align: top; + white-space: normal; +} +.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item) +{ + line-height: 0; + + position: relative; + + display: block; +} +.mui-slider .mui-slider-group .mui-slider-item img +{ + width: 100%; +} +.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after +{ + height: 0; +} +.mui-slider .mui-slider-group.mui-slider-loop +{ + -webkit-transform: translate(-100%, 0px); + transform: translate(-100%, 0px); +} + +.mui-slider-title +{ + line-height: 30px; + + position: absolute; + bottom: 0; + left: 0; + + width: 100%; + height: 30px; + margin: 0; + + text-align: left; + text-indent: 12px; + + opacity: .8; + background-color: #000; +} + +.mui-slider-indicator +{ + position: absolute; + bottom: 8px; + + width: 100%; + + text-align: center; + + background: none; +} +.mui-slider-indicator.mui-segmented-control +{ + position: relative; + bottom: auto; +} +.mui-slider-indicator .mui-indicator +{ + display: inline-block; + + width: 6px; + height: 6px; + margin: 1px 6px; + + cursor: pointer; + + border-radius: 50%; + background: #aaa; + -webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7); + box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7); +} +.mui-slider-indicator .mui-active.mui-indicator +{ + background: #fff; +} +.mui-slider-indicator .mui-icon +{ + font-size: 20px; + line-height: 30px; + + width: 40px; + height: 30px; + margin: 3px; + + text-align: center; + + border: 1px solid #ddd; +} +.mui-slider-indicator .mui-number +{ + line-height: 32px; + + display: inline-block; + + width: 58px; +} +.mui-slider-indicator .mui-number span +{ + color: #ff5053; +} + +.mui-slider-progress-bar +{ + z-index: 1; + + height: 2px; + + -webkit-transform: translateZ(0); + transform: translateZ(0); +} + +.mui-switch +{ + position: relative; + + display: block; + + width: 74px; + height: 30px; + + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + -webkit-transition-duration: .2s; + transition-duration: .2s; + -webkit-transition-property: background-color, border; + transition-property: background-color, border; + + border: 2px solid #ddd; + border-radius: 20px; + background-color: #fff; + background-clip: padding-box; +} +.mui-switch.mui-disabled +{ + opacity: .3; +} +.mui-switch .mui-switch-handle +{ + position: absolute; + z-index: 1; + top: -1px; + left: -1px; + + width: 28px; + height: 28px; + + -webkit-transition: .2s ease-in-out; + transition: .2s ease-in-out; + -webkit-transition-property: -webkit-transform, width,left; + transition-property: transform, width,left; + + border-radius: 16px; + background-color: #fff; + background-clip: padding-box; + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4); + box-shadow: 0 2px 5px rgba(0, 0, 0, .4); +} +.mui-switch:before +{ + font-size: 13px; + + position: absolute; + top: 3px; + right: 11px; + + content: 'Off'; + text-transform: uppercase; + + color: #999; +} +.mui-switch.mui-dragging +{ + border-color: #f7f7f7; + background-color: #f7f7f7; +} +.mui-switch.mui-dragging .mui-switch-handle +{ + width: 38px; +} +.mui-switch.mui-dragging.mui-active .mui-switch-handle +{ + left: -11px; + + width: 38px; +} +.mui-switch.mui-active +{ + border-color: #4cd964; + background-color: #4cd964; +} +.mui-switch.mui-active .mui-switch-handle +{ + -webkit-transform: translate(43px, 0); + transform: translate(43px, 0); +} +.mui-switch.mui-active:before +{ + right: auto; + left: 15px; + + content: 'On'; + + color: #fff; +} +.mui-switch input[type='checkbox'] +{ + display: none; +} + +.mui-switch-mini +{ + width: 47px; +} +.mui-switch-mini:before +{ + display: none; +} +.mui-switch-mini.mui-active .mui-switch-handle +{ + -webkit-transform: translate(16px, 0); + transform: translate(16px, 0); +} + +.mui-switch-blue.mui-active +{ + border: 2px solid #007aff; + background-color: #007aff; +} + +.mui-content.mui-fade +{ + left: 0; + + opacity: 0; +} +.mui-content.mui-fade.mui-in +{ + opacity: 1; +} +.mui-content.mui-sliding +{ + z-index: 2; + + -webkit-transition: -webkit-transform .4s; + transition: transform .4s; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.mui-content.mui-sliding.mui-left +{ + z-index: 1; + + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +.mui-content.mui-sliding.mui-right +{ + z-index: 3; + + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); +} + +.mui-navigate-right:after, +.mui-push-left:after, +.mui-push-right:after +{ + font-family: Muiicons; + font-size: inherit; + line-height: 1; + + position: absolute; + top: 50%; + + display: inline-block; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + text-decoration: none; + + color: #bbb; + + -webkit-font-smoothing: antialiased; +} + +.mui-push-left:after +{ + left: 15px; + + content: '\e582'; +} + +.mui-navigate-right:after, +.mui-push-right:after +{ + right: 15px; + + content: '\e583'; +} + +.mui-pull-top-pocket, .mui-pull-bottom-pocket +{ + position: absolute; + left: 0; + + display: block; + visibility: hidden; + overflow: hidden; + + width: 100%; + height: 50px; +} + +.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket +{ + display: none; + visibility: visible; +} + +.mui-pull-top-pocket +{ + top: 0; +} + +.mui-bar-nav ~ .mui-content .mui-pull-top-pocket +{ + top: 44px; +} + +.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket +{ + top: 88px; +} + +.mui-pull-bottom-pocket +{ + position: relative; + bottom: 0; + + height: 40px; +} +.mui-pull-bottom-pocket .mui-pull-loading +{ + visibility: hidden; +} +.mui-pull-bottom-pocket .mui-pull-loading.mui-in +{ + display: inline-block; +} + +.mui-pull +{ + font-weight: bold; + + position: absolute; + right: 0; + bottom: 10px; + left: 0; + + text-align: center; + + color: #777; +} + +.mui-pull-loading +{ + margin-right: 10px; + + -webkit-transition: -webkit-transform .4s; + transition: transform .4s; + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + vertical-align: middle; +} + +.mui-pull-loading.mui-reverse +{ + -webkit-transform: rotate(180deg) translateZ(0); + transform: rotate(180deg) translateZ(0); +} + +.mui-pull-caption +{ + font-size: 15px; + line-height: 24px; + + position: relative; + + display: inline-block; + overflow: visible; + + margin-top: 0; + + vertical-align: middle; +} +.mui-pull-caption span +{ + display: none; +} +.mui-pull-caption span.mui-in +{ + display: inline; +} + +.mui-toast-container +{ + line-height: 17px; + + position: fixed; + z-index: 9999; + bottom: 50px; + left: 50%; + + -webkit-transition: opacity .3s; + transition: opacity .3s; + -webkit-transform: translate(-50%, 0); + transform: translate(-50%, 0); + + opacity: 0; +} +.mui-toast-container.mui-active +{ + opacity: .9; +} + +.mui-toast-message +{ + font-size: 14px; + + padding: 10px 25px; + + text-align: center; + + color: #fff; + border-radius: 6px; + background-color: #323232; +} + +.mui-numbox +{ + position: relative; + + display: inline-block; + overflow: hidden; + + width: 120px; + height: 35px; + padding: 0 40px 0 40px; + + vertical-align: top; + vertical-align: middle; + + border: solid 1px #bbb; + border-radius: 3px; + background-color: #efeff4; +} +.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox] +{ + font-size: 18px; + font-weight: normal; + line-height: 100%; + + position: absolute; + top: 0; + + overflow: hidden; + + width: 40px; + height: 100%; + padding: 0; + + color: #555; + border: none; + border-radius: 0; + background-color: #f9f9f9; +} +.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active +{ + background-color: #ccc; +} +.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled] +{ + color: #c0c0c0; +} +.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus +{ + right: 0; + + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus +{ + left: 0; + + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox +{ + display: inline-block; + overflow: hidden; + + width: 100% !important; + height: 100%; + margin: 0; + padding: 0 3px !important; + + text-align: center; + text-overflow: ellipsis; + word-break: normal; + + border: none !important; + border-right: solid 1px #ccc !important; + border-left: solid 1px #ccc !important; + border-radius: 0 !important; +} + +.mui-input-row .mui-numbox +{ + float: right; + + margin: 2px 8px; +} + +@font-face { + font-family: Muiicons; + font-weight: normal; + font-style: normal; + + src: url('../fonts/mui.ttf') format('truetype'); +} +.mui-icon +{ + font-family: Muiicons; + font-size: 24px; + font-weight: normal; + font-style: normal; + line-height: 1; + + display: inline-block; + + text-decoration: none; + + -webkit-font-smoothing: antialiased; +} +.mui-icon.mui-active +{ + color: #007aff; +} +.mui-icon.mui-right:before +{ + float: right; + + padding-left: .2em; +} + +.mui-icon-contact:before +{ + content: '\e100'; +} + +.mui-icon-person:before +{ + content: '\e101'; +} + +.mui-icon-personadd:before +{ + content: '\e102'; +} + +.mui-icon-contact-filled:before +{ + content: '\e130'; +} + +.mui-icon-person-filled:before +{ + content: '\e131'; +} + +.mui-icon-personadd-filled:before +{ + content: '\e132'; +} + +.mui-icon-phone:before +{ + content: '\e200'; +} + +.mui-icon-email:before +{ + content: '\e201'; +} + +.mui-icon-chatbubble:before +{ + content: '\e202'; +} + +.mui-icon-chatboxes:before +{ + content: '\e203'; +} + +.mui-icon-phone-filled:before +{ + content: '\e230'; +} + +.mui-icon-email-filled:before +{ + content: '\e231'; +} + +.mui-icon-chatbubble-filled:before +{ + content: '\e232'; +} + +.mui-icon-chatboxes-filled:before +{ + content: '\e233'; +} + +.mui-icon-weibo:before +{ + content: '\e260'; +} + +.mui-icon-weixin:before +{ + content: '\e261'; +} + +.mui-icon-pengyouquan:before +{ + content: '\e262'; +} + +.mui-icon-chat:before +{ + content: '\e263'; +} + +.mui-icon-qq:before +{ + content: '\e264'; +} + +.mui-icon-videocam:before +{ + content: '\e300'; +} + +.mui-icon-camera:before +{ + content: '\e301'; +} + +.mui-icon-mic:before +{ + content: '\e302'; +} + +.mui-icon-location:before +{ + content: '\e303'; +} + +.mui-icon-mic-filled:before, .mui-icon-speech:before +{ + content: '\e332'; +} + +.mui-icon-location-filled:before +{ + content: '\e333'; +} + +.mui-icon-micoff:before +{ + content: '\e360'; +} + +.mui-icon-image:before +{ + content: '\e363'; +} + +.mui-icon-map:before +{ + content: '\e364'; +} + +.mui-icon-compose:before +{ + content: '\e400'; +} + +.mui-icon-trash:before +{ + content: '\e401'; +} + +.mui-icon-upload:before +{ + content: '\e402'; +} + +.mui-icon-download:before +{ + content: '\e403'; +} + +.mui-icon-close:before +{ + content: '\e404'; +} + +.mui-icon-redo:before +{ + content: '\e405'; +} + +.mui-icon-undo:before +{ + content: '\e406'; +} + +.mui-icon-refresh:before +{ + content: '\e407'; +} + +.mui-icon-star:before +{ + content: '\e408'; +} + +.mui-icon-plus:before +{ + content: '\e409'; +} + +.mui-icon-minus:before +{ + content: '\e410'; +} + +.mui-icon-circle:before, .mui-icon-checkbox:before +{ + content: '\e411'; +} + +.mui-icon-close-filled:before, .mui-icon-clear:before +{ + content: '\e434'; +} + +.mui-icon-refresh-filled:before +{ + content: '\e437'; +} + +.mui-icon-star-filled:before +{ + content: '\e438'; +} + +.mui-icon-plus-filled:before +{ + content: '\e439'; +} + +.mui-icon-minus-filled:before +{ + content: '\e440'; +} + +.mui-icon-circle-filled:before +{ + content: '\e441'; +} + +.mui-icon-checkbox-filled:before +{ + content: '\e442'; +} + +.mui-icon-closeempty:before +{ + content: '\e460'; +} + +.mui-icon-refreshempty:before +{ + content: '\e461'; +} + +.mui-icon-reload:before +{ + content: '\e462'; +} + +.mui-icon-starhalf:before +{ + content: '\e463'; +} + +.mui-icon-spinner:before +{ + content: '\e464'; +} + +.mui-icon-spinner-cycle:before +{ + content: '\e465'; +} + +.mui-icon-search:before +{ + content: '\e466'; +} + +.mui-icon-plusempty:before +{ + content: '\e468'; +} + +.mui-icon-forward:before +{ + content: '\e470'; +} + +.mui-icon-back:before, .mui-icon-left-nav:before +{ + content: '\e471'; +} + +.mui-icon-checkmarkempty:before +{ + content: '\e472'; +} + +.mui-icon-home:before +{ + content: '\e500'; +} + +.mui-icon-navigate:before +{ + content: '\e501'; +} + +.mui-icon-gear:before +{ + content: '\e502'; +} + +.mui-icon-paperplane:before +{ + content: '\e503'; +} + +.mui-icon-info:before +{ + content: '\e504'; +} + +.mui-icon-help:before +{ + content: '\e505'; +} + +.mui-icon-locked:before +{ + content: '\e506'; +} + +.mui-icon-more:before +{ + content: '\e507'; +} + +.mui-icon-flag:before +{ + content: '\e508'; +} + +.mui-icon-home-filled:before +{ + content: '\e530'; +} + +.mui-icon-gear-filled:before +{ + content: '\e532'; +} + +.mui-icon-info-filled:before +{ + content: '\e534'; +} + +.mui-icon-help-filled:before +{ + content: '\e535'; +} + +.mui-icon-more-filled:before +{ + content: '\e537'; +} + +.mui-icon-settings:before +{ + content: '\e560'; +} + +.mui-icon-list:before +{ + content: '\e562'; +} + +.mui-icon-bars:before +{ + content: '\e563'; +} + +.mui-icon-loop:before +{ + content: '\e565'; +} + +.mui-icon-paperclip:before +{ + content: '\e567'; +} + +.mui-icon-eye:before +{ + content: '\e568'; +} + +.mui-icon-arrowup:before +{ + content: '\e580'; +} + +.mui-icon-arrowdown:before +{ + content: '\e581'; +} + +.mui-icon-arrowleft:before +{ + content: '\e582'; +} + +.mui-icon-arrowright:before +{ + content: '\e583'; +} + +.mui-icon-arrowthinup:before +{ + content: '\e584'; +} + +.mui-icon-arrowthindown:before +{ + content: '\e585'; +} + +.mui-icon-arrowthinleft:before +{ + content: '\e586'; +} + +.mui-icon-arrowthinright:before +{ + content: '\e587'; +} + +.mui-icon-pulldown:before +{ + content: '\e588'; +} + +.mui-fullscreen +{ + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.mui-fullscreen.mui-slider .mui-slider-group +{ + height: 100%; +} +.mui-fullscreen .mui-segmented-control ~ .mui-slider-group +{ + position: absolute; + top: 40px; + bottom: 0; + + width: 100%; + height: auto; +} +.mui-fullscreen.mui-slider .mui-slider-item > a +{ + top: 50%; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a +{ + top: auto; + + -webkit-transform: none; + transform: none; +} + +.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen +{ + top: 44px; +} + +.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group +{ + bottom: 50px; +} + +.mui-android.mui-android-4-0 input:focus, +.mui-android.mui-android-4-0 textarea:focus +{ + -webkit-user-modify: inherit; +} + +.mui-android.mui-android-4-2 input, +.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input, +.mui-android.mui-android-4-3 textarea +{ + -webkit-user-select: text; +} + +.mui-ios .mui-table-view-cell +{ + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} + +.mui-plus-visible, .mui-wechat-visible +{ + display: none !important; +} + +.mui-plus-hidden, .mui-wechat-hidden +{ + display: block !important; +} + +.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden +{ + display: table-cell !important; +} + +.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible +{ + display: block !important; +} + +.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible +{ + display: table-cell !important; +} + +.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden +{ + display: none !important; +} + +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav +{ + height: 64px; + padding-top: 20px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content +{ + padding-top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket +{ + top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary +{ + top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content +{ + padding-top: 94px; +} + +.mui-iframe-wrapper +{ + position: absolute; + right: 0; + left: 0; + + -webkit-overflow-scrolling: touch; +} +.mui-iframe-wrapper iframe +{ + width: 100%; + height: 100%; + + border: 0; +} diff --git a/static/app/css/mui.min.css b/static/app/css/mui.min.css new file mode 100755 index 0000000..b770476 --- /dev/null +++ b/static/app/css/mui.min.css @@ -0,0 +1,5 @@ +/*! + * ===================================================== + * Mui v3.7.0 (http://dev.dcloud.net.cn/mui) + * ===================================================== + *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{font:inherit;margin:0;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{margin:0 2px;padding:.35em .625em .75em;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}*{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;outline:0;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}body{font-family:'Helvetica Neue',Helvetica,sans-serif;font-size:17px;line-height:21px;color:#000;background-color:#efeff4;-webkit-overflow-scrolling:touch}a{text-decoration:none;color:#007aff}a:active{color:#0062cc}.mui-content{background-color:#efeff4;-webkit-overflow-scrolling:touch}.mui-bar-nav~.mui-content{padding-top:44px}.mui-bar-nav~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{top:44px}.mui-bar-header-secondary~.mui-content{padding-top:88px}.mui-bar-header-secondary~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{top:88px}.mui-bar-footer~.mui-content{padding-bottom:44px}.mui-bar-footer~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:44px}.mui-bar-footer-secondary~.mui-content{padding-bottom:88px}.mui-bar-footer-secondary~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:88px}.mui-bar-tab~.mui-content{padding-bottom:50px}.mui-bar-tab~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:50px}.mui-bar-footer-secondary-tab~.mui-content{padding-bottom:94px}.mui-bar-footer-secondary-tab~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:94px}.mui-content-padded{margin:10px}.mui-inline{display:inline-block;vertical-align:top}.mui-block{display:block!important}.mui-visibility{visibility:visible!important}.mui-hidden{display:none!important}.mui-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.mui-ellipsis-2{display:-webkit-box;overflow:hidden;white-space:normal!important;text-overflow:ellipsis;word-wrap:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical}.mui-table{display:table;width:100%;table-layout:fixed}.mui-table-cell{position:relative;display:table-cell}.mui-text-left{text-align:left!important}.mui-text-center{text-align:center!important}.mui-text-justify{text-align:justify!important}.mui-text-right{text-align:right!important}.mui-pull-left{float:left}.mui-pull-right{float:right}.mui-list-unstyled{padding-left:0;list-style:none}.mui-list-inline{margin-left:-5px;padding-left:0;list-style:none}.mui-list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.mui-clearfix:after,.mui-clearfix:before{display:table;content:' '}.mui-clearfix:after{clear:both}.mui-bg-primary{background-color:#007aff}.mui-bg-positive{background-color:#4cd964}.mui-bg-negative{background-color:#dd524d}.mui-error{margin:88px 35px;padding:10px;border-radius:6px;background-color:#bbb}.mui-subtitle{font-size:15px}h1,h2,h3,h4,h5,h6{line-height:1;margin-top:5px;margin-bottom:5px}.mui-h1,h1{font-size:36px}.mui-h2,h2{font-size:30px}.mui-h3,h3{font-size:24px}.mui-h4,h4{font-size:18px}.mui-h5,h5{font-size:14px;font-weight:400;color:#8f8f94}.mui-h6,h6{font-size:12px;font-weight:400;color:#8f8f94}p{font-size:14px;margin-top:0;margin-bottom:10px;color:#8f8f94}.mui-row:after,.mui-row:before{display:table;content:' '}.mui-row:after{clear:both}.mui-col-sm-1,.mui-col-sm-10,.mui-col-sm-11,.mui-col-sm-12,.mui-col-sm-2,.mui-col-sm-3,.mui-col-sm-4,.mui-col-sm-5,.mui-col-sm-6,.mui-col-sm-7,.mui-col-sm-8,.mui-col-sm-9,.mui-col-xs-1,.mui-col-xs-10,.mui-col-xs-11,.mui-col-xs-12,.mui-col-xs-2,.mui-col-xs-3,.mui-col-xs-4,.mui-col-xs-5,.mui-col-xs-6,.mui-col-xs-7,.mui-col-xs-8,.mui-col-xs-9{position:relative;min-height:1px}.mui-row>[class*=mui-col-]{float:left}.mui-col-xs-12{width:100%}.mui-col-xs-11{width:91.66666667%}.mui-col-xs-10{width:83.33333333%}.mui-col-xs-9{width:75%}.mui-col-xs-8{width:66.66666667%}.mui-col-xs-7{width:58.33333333%}.mui-col-xs-6{width:50%}.mui-col-xs-5{width:41.66666667%}.mui-col-xs-4{width:33.33333333%}.mui-col-xs-3{width:25%}.mui-col-xs-2{width:16.66666667%}.mui-col-xs-1{width:8.33333333%}@media (min-width:400px){.mui-col-sm-12{width:100%}.mui-col-sm-11{width:91.66666667%}.mui-col-sm-10{width:83.33333333%}.mui-col-sm-9{width:75%}.mui-col-sm-8{width:66.66666667%}.mui-col-sm-7{width:58.33333333%}.mui-col-sm-6{width:50%}.mui-col-sm-5{width:41.66666667%}.mui-col-sm-4{width:33.33333333%}.mui-col-sm-3{width:25%}.mui-col-sm-2{width:16.66666667%}.mui-col-sm-1{width:8.33333333%}}.mui-scroll-wrapper{position:absolute;z-index:2;top:0;bottom:0;left:0;overflow:hidden;width:100%}.mui-scroll{position:absolute;z-index:1;width:100%;-webkit-transform:translateZ(0);transform:translateZ(0)}.mui-scrollbar{position:absolute;z-index:9998;overflow:hidden;-webkit-transition:500ms;transition:500ms;transform:translateZ(0px);pointer-events:none;opacity:0}.mui-scrollbar-vertical{top:0;right:1px;bottom:2px;width:4px}.mui-scrollbar-vertical .mui-scrollbar-indicator{width:100%}.mui-scrollbar-horizontal{right:2px;bottom:0;left:2px;height:4px}.mui-scrollbar-horizontal .mui-scrollbar-indicator{height:100%}.mui-scrollbar-indicator{position:absolute;display:block;box-sizing:border-box;-webkit-transition:.01s cubic-bezier(.1,.57,.1,1);transition:.01s cubic-bezier(.1,.57,.1,1);transform:translate(0px,0) translateZ(0px);border:1px solid rgba(255,255,255,.80196);border-radius:2px;background:rgba(0,0,0,.39804)}.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper,.mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper{position:absolute;top:0;bottom:0;left:0;overflow:hidden;width:100%}.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll,.mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll{position:absolute;width:100%}.mui-plus-pullrefresh .mui-scroll-wrapper,.mui-plus-pullrefresh .mui-slider-group{position:static;top:auto;bottom:auto;left:auto;overflow:auto;width:auto}.mui-plus-pullrefresh .mui-slider-group{overflow:visible}.mui-plus-pullrefresh .mui-scroll{position:static;width:auto}.mui-off-canvas-wrap .mui-bar{position:absolute!important;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-box-shadow:none;box-shadow:none}.mui-off-canvas-wrap{position:relative;z-index:1;overflow:hidden;width:100%;height:100%}.mui-off-canvas-wrap .mui-inner-wrap{position:relative;z-index:1;width:100%;height:100%}.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning{-webkit-transition:-webkit-transform 350ms;transition:transform 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.mui-off-canvas-wrap.mui-active{overflow:hidden;height:100%}.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop{position:absolute;z-index:998;top:0;right:0;bottom:0;left:0;display:block;transition:background 350ms cubic-bezier(.165,.84,.44,1);background:rgba(0,0,0,.4);box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);-webkit-tap-highlight-color:transparent}.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right{z-index:10000!important;-webkit-transform:translate3d(100%,0,0)}.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left{z-index:10000!important;-webkit-transform:translate3d(-100%,0,0)}.mui-off-canvas-left,.mui-off-canvas-right{position:absolute;z-index:-1;top:0;bottom:0;visibility:hidden;box-sizing:content-box;width:70%;min-height:100%;background:#333;-webkit-overflow-scrolling:touch}.mui-off-canvas-left.mui-transitioning,.mui-off-canvas-right.mui-transitioning{-webkit-transition:-webkit-transform 350ms cubic-bezier(.165,.84,.44,1);transition:transform 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-left{left:0}.mui-off-canvas-right{right:0}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable{background-color:#333}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right{width:80%;-webkit-transform:scale(.8);transform:scale(.8);opacity:.1}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left.mui-transitioning,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right.mui-transitioning{-webkit-transition:-webkit-transform 350ms cubic-bezier(.165,.84,.44,1),opacity 350ms cubic-bezier(.165,.84,.44,1);transition:transform 350ms cubic-bezier(.165,.84,.44,1),opacity 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left{-webkit-transform-origin:-100%;transform-origin:-100%}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right{-webkit-transform-origin:200%;transform-origin:200%}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-inner-wrap{-webkit-transform:scale(.8);transform:scale(.8)}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-off-canvas-left,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-off-canvas-right{-webkit-transform:scale(1);transform:scale(1);opacity:1}.mui-loading .mui-spinner{display:block;margin:0 auto}.mui-spinner{display:inline-block;width:24px;height:24px;-webkit-transform-origin:50%;transform-origin:50%;-webkit-animation:spinner-spin 1s step-end infinite;animation:spinner-spin 1s step-end infinite}.mui-spinner:after{display:block;width:100%;height:100%;content:'';background-image:url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');background-repeat:no-repeat;background-position:50%;background-size:100%}.mui-spinner-white:after{background-image:url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>')}@-webkit-keyframes spinner-spin{0%{-webkit-transform:rotate(0deg)}8.33333333%{-webkit-transform:rotate(30deg)}16.66666667%{-webkit-transform:rotate(60deg)}25%{-webkit-transform:rotate(90deg)}33.33333333%{-webkit-transform:rotate(120deg)}41.66666667%{-webkit-transform:rotate(150deg)}50%{-webkit-transform:rotate(180deg)}58.33333333%{-webkit-transform:rotate(210deg)}66.66666667%{-webkit-transform:rotate(240deg)}75%{-webkit-transform:rotate(270deg)}83.33333333%{-webkit-transform:rotate(300deg)}91.66666667%{-webkit-transform:rotate(330deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes spinner-spin{0%{transform:rotate(0deg)}8.33333333%{transform:rotate(30deg)}16.66666667%{transform:rotate(60deg)}25%{transform:rotate(90deg)}33.33333333%{transform:rotate(120deg)}41.66666667%{transform:rotate(150deg)}50%{transform:rotate(180deg)}58.33333333%{transform:rotate(210deg)}66.66666667%{transform:rotate(240deg)}75%{transform:rotate(270deg)}83.33333333%{transform:rotate(300deg)}91.66666667%{transform:rotate(330deg)}100%{transform:rotate(360deg)}}.mui-btn,button,input[type=button],input[type=reset],input[type=submit]{font-size:14px;font-weight:400;line-height:1.42;position:relative;display:inline-block;margin-bottom:0;padding:6px 12px;cursor:pointer;-webkit-transition:all;transition:all;-webkit-transition-timing-function:linear;transition-timing-function:linear;-webkit-transition-duration:.2s;transition-duration:.2s;text-align:center;vertical-align:top;white-space:nowrap;color:#333;border:1px solid #ccc;border-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:#fff;background-clip:padding-box}.mui-btn.mui-active:enabled,.mui-btn:enabled:active,button.mui-active:enabled,button:enabled:active,input[type=button].mui-active:enabled,input[type=button]:enabled:active,input[type=reset].mui-active:enabled,input[type=reset]:enabled:active,input[type=submit].mui-active:enabled,input[type=submit]:enabled:active{color:#fff;background-color:#929292}.mui-btn.mui-disabled,.mui-btn:disabled,button.mui-disabled,button:disabled,input[type=button].mui-disabled,input[type=button]:disabled,input[type=reset].mui-disabled,input[type=reset]:disabled,input[type=submit].mui-disabled,input[type=submit]:disabled{opacity:.6}.mui-btn-blue,.mui-btn-primary,input[type=submit]{color:#fff;border:1px solid #007aff;background-color:#007aff}.mui-btn-blue.mui-active:enabled,.mui-btn-blue:enabled:active,.mui-btn-primary.mui-active:enabled,.mui-btn-primary:enabled:active,input[type=submit].mui-active:enabled,input[type=submit]:enabled:active{color:#fff;border:1px solid #0062cc;background-color:#0062cc}.mui-btn-green,.mui-btn-positive,.mui-btn-success{color:#fff;border:1px solid #4cd964;background-color:#4cd964}.mui-btn-green.mui-active:enabled,.mui-btn-green:enabled:active,.mui-btn-positive.mui-active:enabled,.mui-btn-positive:enabled:active,.mui-btn-success.mui-active:enabled,.mui-btn-success:enabled:active{color:#fff;border:1px solid #2ac845;background-color:#2ac845}.mui-btn-warning,.mui-btn-yellow{color:#fff;border:1px solid #f0ad4e;background-color:#f0ad4e}.mui-btn-warning.mui-active:enabled,.mui-btn-warning:enabled:active,.mui-btn-yellow.mui-active:enabled,.mui-btn-yellow:enabled:active{color:#fff;border:1px solid #ec971f;background-color:#ec971f}.mui-btn-danger,.mui-btn-negative,.mui-btn-red{color:#fff;border:1px solid #dd524d;background-color:#dd524d}.mui-btn-danger.mui-active:enabled,.mui-btn-danger:enabled:active,.mui-btn-negative.mui-active:enabled,.mui-btn-negative:enabled:active,.mui-btn-red.mui-active:enabled,.mui-btn-red:enabled:active{color:#fff;border:1px solid #cf2d28;background-color:#cf2d28}.mui-btn-purple,.mui-btn-royal{color:#fff;border:1px solid #8a6de9;background-color:#8a6de9}.mui-btn-purple.mui-active:enabled,.mui-btn-purple:enabled:active,.mui-btn-royal.mui-active:enabled,.mui-btn-royal:enabled:active{color:#fff;border:1px solid #6641e2;background-color:#6641e2}.mui-btn-grey{color:#fff;border:1px solid #c7c7cc;background-color:#c7c7cc}.mui-btn-grey.mui-active:enabled,.mui-btn-grey:enabled:active{color:#fff;border:1px solid #acacb4;background-color:#acacb4}.mui-btn-outlined{background-color:transparent}.mui-btn-outlined.mui-btn-blue,.mui-btn-outlined.mui-btn-primary{color:#007aff}.mui-btn-outlined.mui-btn-green,.mui-btn-outlined.mui-btn-positive,.mui-btn-outlined.mui-btn-success{color:#4cd964}.mui-btn-outlined.mui-btn-warning,.mui-btn-outlined.mui-btn-yellow{color:#f0ad4e}.mui-btn-outlined.mui-btn-danger,.mui-btn-outlined.mui-btn-negative,.mui-btn-outlined.mui-btn-red{color:#dd524d}.mui-btn-outlined.mui-btn-purple,.mui-btn-outlined.mui-btn-royal{color:#8a6de9}.mui-btn-outlined.mui-btn-blue:enabled:active,.mui-btn-outlined.mui-btn-danger:enabled:active,.mui-btn-outlined.mui-btn-green:enabled:active,.mui-btn-outlined.mui-btn-negative:enabled:active,.mui-btn-outlined.mui-btn-positive:enabled:active,.mui-btn-outlined.mui-btn-primary:enabled:active,.mui-btn-outlined.mui-btn-purple:enabled:active,.mui-btn-outlined.mui-btn-red:enabled:active,.mui-btn-outlined.mui-btn-royal:enabled:active,.mui-btn-outlined.mui-btn-success:enabled:active,.mui-btn-outlined.mui-btn-warning:enabled:active,.mui-btn-outlined.mui-btn-yellow:enabled:active{color:#fff}.mui-btn-link{padding-top:6px;padding-bottom:6px;color:#007aff;border:0;background-color:transparent}.mui-btn-link.mui-active:enabled,.mui-btn-link:enabled:active{color:#0062cc;background-color:transparent}.mui-btn-block{font-size:18px;display:block;width:100%;margin-bottom:10px;padding:15px 0}.mui-btn .mui-badge{font-size:14px;margin:-2px -4px -2px 4px;background-color:rgba(0,0,0,.15)}.mui-btn .mui-badge-inverted,.mui-btn:enabled:active .mui-badge-inverted{background-color:transparent}.mui-btn-negative:enabled:active .mui-badge-inverted,.mui-btn-positive:enabled:active .mui-badge-inverted,.mui-btn-primary:enabled:active .mui-badge-inverted{color:#fff}.mui-btn-block .mui-badge{position:absolute;right:0;margin-right:10px}.mui-btn .mui-icon{font-size:inherit}.mui-btn.mui-icon{font-size:14px;line-height:1.42}.mui-btn.mui-fab{width:56px;height:56px;padding:16px;border-radius:50%;outline:0}.mui-btn.mui-fab.mui-btn-mini{width:40px;height:40px;padding:8px}.mui-btn.mui-fab .mui-icon{font-size:24px;line-height:24px;width:24px;height:24px}.mui-btn .mui-spinner{width:14px;height:14px;vertical-align:text-bottom}.mui-btn-block .mui-spinner{width:22px;height:22px}.mui-bar{position:fixed;z-index:10;right:0;left:0;height:44px;padding-right:10px;padding-left:10px;border-bottom:0;background-color:#f7f7f7;-webkit-box-shadow:0 0 1px rgba(0,0,0,.85);box-shadow:0 0 1px rgba(0,0,0,.85);-webkit-backface-visibility:hidden;backface-visibility:hidden}.mui-bar .mui-title{right:40px;left:40px;display:inline-block;overflow:hidden;width:auto;margin:0;text-overflow:ellipsis}.mui-bar .mui-backdrop{background:0 0}.mui-bar-header-secondary{top:44px}.mui-bar-footer{bottom:0}.mui-bar-footer-secondary{bottom:44px}.mui-bar-footer-secondary-tab{bottom:50px}.mui-bar-footer,.mui-bar-footer-secondary,.mui-bar-footer-secondary-tab{border-top:0}.mui-bar-transparent{top:0;background-color:rgba(247,247,247,0);-webkit-box-shadow:none;box-shadow:none}.mui-bar-nav{top:0;-webkit-box-shadow:0 1px 6px #ccc;box-shadow:0 1px 6px #ccc}.mui-bar-nav~.mui-content .mui-anchor{display:block;visibility:hidden;height:45px;margin-top:-45px}.mui-bar-nav.mui-bar .mui-icon{margin-right:-10px;margin-left:-10px;padding-right:10px;padding-left:10px}.mui-title{font-size:17px;font-weight:500;line-height:44px;position:absolute;display:block;width:100%;margin:0 -10px;padding:0;text-align:center;white-space:nowrap;color:#000}.mui-title a{color:inherit}.mui-bar-tab{bottom:0;display:table;width:100%;height:50px;padding:0;table-layout:fixed;border-top:0;border-bottom:0;-webkit-touch-callout:none}.mui-bar-tab .mui-tab-item{display:table-cell;overflow:hidden;width:1%;height:50px;text-align:center;vertical-align:middle;white-space:nowrap;text-overflow:ellipsis;color:#929292}.mui-bar-tab .mui-tab-item.mui-active{color:#007aff}.mui-bar-tab .mui-tab-item .mui-icon{top:3px;width:24px;height:24px;padding-top:0;padding-bottom:0}.mui-bar-tab .mui-tab-item .mui-icon~.mui-tab-label{font-size:11px;display:block;overflow:hidden;text-overflow:ellipsis}.mui-bar-tab .mui-tab-item .mui-icon:active{background:0 0}.mui-focusin>.mui-bar-header-secondary,.mui-focusin>.mui-bar-nav{position:absolute}.mui-focusin>.mui-bar~.mui-content{padding-bottom:0}.mui-bar .mui-btn{font-weight:400;position:relative;z-index:20;top:7px;margin-top:0;padding:6px 12px 7px}.mui-bar .mui-btn.mui-pull-right{margin-left:10px}.mui-bar .mui-btn.mui-pull-left{margin-right:10px}.mui-bar .mui-btn-link{font-size:16px;line-height:44px;top:0;padding:0;color:#007aff;border:0}.mui-bar .mui-btn-link.mui-active,.mui-bar .mui-btn-link:active{color:#0062cc}.mui-bar .mui-btn-block{font-size:16px;top:6px;margin-bottom:0;padding:5px 0}.mui-bar .mui-btn-nav.mui-pull-left{margin-left:-5px}.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav{margin-right:-3px}.mui-bar .mui-btn-nav.mui-pull-right{margin-right:-5px}.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav{margin-left:-3px}.mui-bar .mui-btn-nav:active{opacity:.3}.mui-bar .mui-icon{font-size:24px;position:relative;z-index:20;padding-top:10px;padding-bottom:10px}.mui-bar .mui-icon:active{opacity:.3}.mui-bar .mui-btn .mui-icon{top:1px;margin:0;padding:0}.mui-bar .mui-title .mui-icon{margin:0;padding:0}.mui-bar .mui-title .mui-icon.mui-icon-caret{top:4px;margin-left:-5px}.mui-bar input[type=search]{height:29px;margin:6px 0}.mui-bar .mui-input-row .mui-btn{padding:12px 10px}.mui-bar .mui-search:before{margin-top:-10px}.mui-bar .mui-input-row .mui-input-clear~.mui-icon-clear,.mui-bar .mui-input-row .mui-input-speech~.mui-icon-speech{top:0;right:12px}.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear~.mui-icon-clear,.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech~.mui-icon-speech{top:0;right:0}.mui-bar .mui-segmented-control{top:7px;width:auto;margin:0 auto}.mui-bar.mui-bar-header-secondary .mui-segmented-control{top:0}.mui-badge{font-size:12px;line-height:1;display:inline-block;padding:3px 6px;color:#333;border-radius:100px;background-color:rgba(0,0,0,.15)}.mui-badge.mui-badge-inverted{padding:0 5px 0 0;color:#929292;background-color:transparent}.mui-badge-blue,.mui-badge-primary{color:#fff;background-color:#007aff}.mui-badge-blue.mui-badge-inverted,.mui-badge-primary.mui-badge-inverted{color:#007aff;background-color:transparent}.mui-badge-green,.mui-badge-success{color:#fff;background-color:#4cd964}.mui-badge-green.mui-badge-inverted,.mui-badge-success.mui-badge-inverted{color:#4cd964;background-color:transparent}.mui-badge-warning,.mui-badge-yellow{color:#fff;background-color:#f0ad4e}.mui-badge-warning.mui-badge-inverted,.mui-badge-yellow.mui-badge-inverted{color:#f0ad4e;background-color:transparent}.mui-badge-danger,.mui-badge-red{color:#fff;background-color:#dd524d}.mui-badge-danger.mui-badge-inverted,.mui-badge-red.mui-badge-inverted{color:#dd524d;background-color:transparent}.mui-badge-purple,.mui-badge-royal{color:#fff;background-color:#8a6de9}.mui-badge-purple.mui-badge-inverted,.mui-badge-royal.mui-badge-inverted{color:#8a6de9;background-color:transparent}.mui-icon .mui-badge{font-size:10px;line-height:1.4;position:absolute;top:-2px;left:100%;margin-left:-10px;padding:1px 5px;color:#fff;background:red}.mui-card{font-size:14px;position:relative;overflow:hidden;margin:10px;border-radius:2px;background-color:#fff;background-clip:padding-box;box-shadow:0 1px 2px rgba(0,0,0,.3)}.mui-content>.mui-card:first-child{margin-top:15px}.mui-card .mui-input-group .mui-input-row:last-child:after,.mui-card .mui-input-group .mui-input-row:last-child:before,.mui-card .mui-input-group:after,.mui-card .mui-input-group:before{height:0}.mui-card .mui-table-view{margin-bottom:0;border-top:0;border-bottom:0;border-radius:6px}.mui-card .mui-table-view .mui-table-view-cell:first-child,.mui-card .mui-table-view .mui-table-view-divider:first-child{top:0;border-top-left-radius:6px;border-top-right-radius:6px}.mui-card .mui-table-view .mui-table-view-cell:last-child,.mui-card .mui-table-view .mui-table-view-divider:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.mui-card .mui-table-view:after,.mui-card .mui-table-view:before,.mui-card>.mui-table-view>.mui-table-view-cell:last-child:after,.mui-card>.mui-table-view>.mui-table-view-cell:last-child:before{height:0}.mui-card-footer,.mui-card-header{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;min-height:44px;padding:10px 15px;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-card-footer .mui-card-link,.mui-card-header .mui-card-link{line-height:44px;position:relative;display:-webkit-box;display:-webkit-flex;display:flex;height:44px;margin-top:-10px;margin-bottom:-10px;-webkit-transition-duration:.3s;transition-duration:.3s;text-decoration:none;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-card-footer:before,.mui-card-header:after{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-card-header{font-size:17px;border-radius:2px 2px 0 0}.mui-card-header:after{top:auto;bottom:0}.mui-card-header>img:first-child{font-size:0;line-height:0;float:left;width:34px;height:34px}.mui-card-footer{color:#6d6d72;border-radius:0 0 2px 2px}.mui-card-content{font-size:14px;position:relative}.mui-card-content-inner{position:relative;padding:15px}.mui-card-media{vertical-align:bottom;color:#fff;background-position:center;background-size:cover}.mui-card-header.mui-card-media{display:block;padding:10px}.mui-card-header.mui-card-media .mui-media-body{font-size:14px;font-weight:500;line-height:17px;margin-bottom:0;margin-left:44px;color:#333}.mui-card-header.mui-card-media .mui-media-body p{font-size:13px;margin-bottom:0}.mui-table-view{position:relative;margin-top:0;margin-bottom:0;padding-left:0;list-style:none;background-color:#fff}.mui-table-view:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view:before{position:absolute;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc;top:-1px}.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon{font-size:20px;margin-top:-1px;margin-right:5px;margin-left:-5px}.mui-table-view-icon .mui-table-view-cell:after{left:40px}.mui-table-view-chevron .mui-table-view-cell{padding-right:65px}.mui-table-view-chevron .mui-table-view-cell>a:not(.mui-btn){margin-right:-65px}.mui-table-view-radio .mui-table-view-cell{padding-right:65px}.mui-table-view-radio .mui-table-view-cell>a:not(.mui-btn){margin-right:-65px}.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after{font-size:30px;font-weight:600;right:9px;content:'';color:#007aff}.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after{content:'\e472'}.mui-table-view-inverted{color:#fff;background:#333}.mui-table-view-inverted:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted .mui-table-view-cell.mui-active,.mui-table-view-inverted .mui-table-view-cell>a:not(.mui-btn).mui-active{background-color:#242424}.mui-table-view-cell{position:relative;overflow:hidden;padding:11px 15px;-webkit-touch-callout:none}.mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-cell.mui-checkbox input[type=checkbox],.mui-table-view-cell.mui-radio input[type=radio]{top:8px}.mui-table-view-cell.mui-checkbox.mui-left,.mui-table-view-cell.mui-radio.mui-left{padding-left:58px}.mui-table-view-cell.mui-active{background-color:#eee}.mui-table-view-cell:last-child:after,.mui-table-view-cell:last-child:before{height:0}.mui-table-view-cell>a:not(.mui-btn){position:relative;display:block;overflow:hidden;margin:-11px -15px;padding:inherit;white-space:nowrap;text-overflow:ellipsis;color:inherit}.mui-table-view-cell>a:not(.mui-btn).mui-active{background-color:#eee}.mui-table-view-cell p{margin-bottom:0}.mui-table-view-cell.mui-transitioning>.mui-slider-handle,.mui-table-view-cell.mui-transitioning>.mui-slider-left .mui-btn,.mui-table-view-cell.mui-transitioning>.mui-slider-right .mui-btn{-webkit-transition:-webkit-transform 300ms ease;transition:transform 300ms ease}.mui-table-view-cell.mui-active>.mui-slider-handle{background-color:#eee}.mui-table-view-cell>.mui-slider-handle{position:relative;background-color:#fff}.mui-table-view-cell>.mui-slider-handle .mui-navigate-right:after,.mui-table-view-cell>.mui-slider-handle.mui-navigate-right:after{right:0}.mui-table-view-cell>.mui-slider-handle,.mui-table-view-cell>.mui-slider-left .mui-btn,.mui-table-view-cell>.mui-slider-right .mui-btn{-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease}.mui-table-view-cell>.mui-slider-left,.mui-table-view-cell>.mui-slider-right{position:absolute;top:0;display:-webkit-box;display:-webkit-flex;display:flex;height:100%}.mui-table-view-cell>.mui-slider-left>.mui-btn,.mui-table-view-cell>.mui-slider-right>.mui-btn{position:relative;left:0;display:-webkit-box;display:-webkit-flex;display:flex;padding:0 30px;color:#fff;border:0;border-radius:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-table-view-cell>.mui-slider-left>.mui-btn:after,.mui-table-view-cell>.mui-slider-right>.mui-btn:after{position:absolute;z-index:-1;top:0;width:600%;height:100%;content:'';background:inherit}.mui-table-view-cell>.mui-slider-left>.mui-btn.mui-icon,.mui-table-view-cell>.mui-slider-right>.mui-btn.mui-icon{font-size:30px}.mui-table-view-cell>.mui-slider-right{right:0;-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease;-webkit-transform:translateX(100%);transform:translateX(100%)}.mui-table-view-cell>.mui-slider-left{left:0;-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.mui-table-view-cell>.mui-slider-left>.mui-btn:after{right:100%;margin-right:-1px}.mui-table-view-divider{font-weight:500;position:relative;margin-top:-1px;margin-left:0;padding-top:6px;padding-bottom:6px;padding-left:15px;color:#999;background-color:#fafafa}.mui-table-view-divider:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-divider:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view .mui-media,.mui-table-view .mui-media-body{overflow:hidden}.mui-table-view .mui-media-large .mui-media-object{line-height:80px;max-width:80px;height:80px}.mui-table-view .mui-media .mui-subtitle{color:#000}.mui-table-view .mui-media-object{line-height:42px;max-width:42px;height:42px}.mui-table-view .mui-media-object.mui-pull-left{margin-right:10px}.mui-table-view .mui-media-object.mui-pull-right{margin-left:10px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object{line-height:29px;max-width:29px;height:29px;margin:-4px 0}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img{line-height:29px;max-width:29px;height:29px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left{margin-right:10px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon{font-size:29px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after{position:absolute;right:0;bottom:0;left:55px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view .mui-table-view-cell.mui-media-icon:after{height:0!important}.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view{display:block}.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after,.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before{height:0!important}.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after{position:absolute;right:0;bottom:0;left:70px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-cell>.mui-badge,.mui-table-view-cell>.mui-btn,.mui-table-view-cell>.mui-switch,.mui-table-view-cell>a>.mui-badge,.mui-table-view-cell>a>.mui-btn,.mui-table-view-cell>a>.mui-switch{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.mui-table-view-cell .mui-navigate-right>.mui-badge,.mui-table-view-cell .mui-navigate-right>.mui-btn,.mui-table-view-cell .mui-navigate-right>.mui-switch,.mui-table-view-cell .mui-push-left>.mui-badge,.mui-table-view-cell .mui-push-left>.mui-btn,.mui-table-view-cell .mui-push-left>.mui-switch,.mui-table-view-cell .mui-push-right>.mui-badge,.mui-table-view-cell .mui-push-right>.mui-btn,.mui-table-view-cell .mui-push-right>.mui-switch,.mui-table-view-cell>a .mui-navigate-right>.mui-badge,.mui-table-view-cell>a .mui-navigate-right>.mui-btn,.mui-table-view-cell>a .mui-navigate-right>.mui-switch,.mui-table-view-cell>a .mui-push-left>.mui-badge,.mui-table-view-cell>a .mui-push-left>.mui-btn,.mui-table-view-cell>a .mui-push-left>.mui-switch,.mui-table-view-cell>a .mui-push-right>.mui-badge,.mui-table-view-cell>a .mui-push-right>.mui-btn,.mui-table-view-cell>a .mui-push-right>.mui-switch{right:35px}.mui-content>.mui-table-view:first-child{margin-top:15px}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after,.mui-table-view-cell.mui-collapse .mui-table-view:after,.mui-table-view-cell.mui-collapse .mui-table-view:before{height:0}.mui-table-view-cell.mui-collapse>.mui-navigate-right:after,.mui-table-view-cell.mui-collapse>.mui-push-right:after{content:'\e581'}.mui-table-view-cell.mui-collapse.mui-active{margin-top:-1px}.mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content,.mui-table-view-cell.mui-collapse.mui-active .mui-table-view{display:block}.mui-table-view-cell.mui-collapse.mui-active>.mui-navigate-right:after,.mui-table-view-cell.mui-collapse.mui-active>.mui-push-right:after{content:'\e580'}.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell>a:not(.mui-btn).mui-active{margin-left:-31px;padding-left:47px}.mui-table-view-cell.mui-collapse .mui-collapse-content{position:relative;display:none;overflow:hidden;margin:11px -15px -11px;padding:8px 15px;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease;background:#fff}.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-input-group,.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-slider{width:auto;height:auto;margin:-8px -15px}.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-slider{margin:-8px -16px}.mui-table-view-cell.mui-collapse .mui-table-view{display:none;margin-top:11px;margin-right:-15px;margin-bottom:-11px;margin-left:-15px;border:0}.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron{margin-right:-65px}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell{padding-left:31px;background-position:31px 100%}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:30px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view.mui-grid-view{font-size:0;display:block;width:100%;padding:0 10px 10px 0;white-space:normal}.mui-table-view.mui-grid-view .mui-table-view-cell{font-size:17px;display:inline-block;margin-right:-4px;padding:10px 0 0 14px;text-align:center;vertical-align:middle;background:0 0}.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object{width:100%;max-width:100%;height:auto}.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn){margin:-10px 0 0 -14px}.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn).mui-active,.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn):active{background:0 0}.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body{font-size:15px;line-height:15px;display:block;width:100%;height:15px;margin-top:8px;text-overflow:ellipsis;color:#333}.mui-table-view.mui-grid-view .mui-table-view-cell:after,.mui-table-view.mui-grid-view .mui-table-view-cell:before{height:0}.mui-grid-view.mui-grid-9{margin:0;padding:0;border-top:1px solid #eee;border-left:1px solid #eee;background-color:#f2f2f2}.mui-grid-view.mui-grid-9:after,.mui-grid-view.mui-grid-9:before{display:table;content:' '}.mui-grid-view.mui-grid-9:after{clear:both;position:static}.mui-grid-view.mui-grid-9 .mui-table-view-cell{margin:0;padding:11px 15px;vertical-align:top;border-right:1px solid #eee;border-bottom:1px solid #eee}.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active{background-color:#eee}.mui-grid-view.mui-grid-9 .mui-table-view-cell>a:not(.mui-btn){margin:0;padding:10px 0}.mui-grid-view.mui-grid-9:before{height:0}.mui-grid-view.mui-grid-9 .mui-media{color:#797979}.mui-grid-view.mui-grid-9 .mui-media .mui-icon{font-size:2.4em;position:relative}.mui-slider-cell{position:relative}.mui-slider-cell>.mui-slider-handle{z-index:1}.mui-slider-cell>.mui-slider-left,.mui-slider-cell>.mui-slider-right{position:absolute;z-index:0;top:0;bottom:0}.mui-slider-cell>.mui-slider-left{left:0}.mui-slider-cell>.mui-slider-right{right:0}input,select,textarea{font-family:'Helvetica Neue',Helvetica,sans-serif;font-size:17px;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}input:focus,select:focus,textarea:focus{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent;-webkit-user-modify:read-write-plaintext-only}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{line-height:21px;width:100%;height:40px;margin-bottom:15px;padding:10px 15px;-webkit-user-select:text;border:1px solid rgba(0,0,0,.2);border-radius:3px;outline:0;background-color:#fff;-webkit-appearance:none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{margin:0;-webkit-appearance:none}input[type=search]{font-size:16px;-webkit-box-sizing:border-box;box-sizing:border-box;height:34px;text-align:center;border:0;border-radius:6px;background-color:rgba(0,0,0,.1)}input[type=search]:focus{text-align:left}textarea{height:auto;resize:none}select{font-size:14px;height:auto;margin-top:1px;border:0!important;background-color:#fff}select:focus{-webkit-user-modify:read-only}.mui-input-group{position:relative;padding:0;border:0;background-color:#fff}.mui-input-group:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-group:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-group input,.mui-input-group textarea{margin-bottom:0;border:0;border-radius:0;background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.mui-input-group input[type=search]{background:0 0}.mui-input-group input:last-child{background-image:none}.mui-input-row{clear:left;overflow:hidden}.mui-input-row select{font-size:17px;height:37px;padding:0}.mui-input-row .mui-btn+input,.mui-input-row label+input,.mui-input-row:last-child{background:0 0}.mui-input-group .mui-input-row{height:40px}.mui-input-group .mui-input-row:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-row label{font-family:'Helvetica Neue',Helvetica,sans-serif;line-height:1.1;float:left;width:35%;padding:11px 15px}.mui-input-row label~input,.mui-input-row label~select,.mui-input-row label~textarea{float:right;width:65%;margin-bottom:0;padding-left:0;border:0}.mui-input-row .mui-btn{line-height:1.1;float:right;width:15%;padding:10px 15px}.mui-input-row .mui-btn~input,.mui-input-row .mui-btn~select,.mui-input-row .mui-btn~textarea{float:left;width:85%;margin-bottom:0;padding-left:0;border:0}.mui-button-row{position:relative;padding-top:5px;text-align:center}.mui-input-group .mui-button-row{height:45px}.mui-input-row{position:relative}.mui-input-row.mui-input-range{overflow:visible;padding-right:20px}.mui-input-row .mui-inline{padding:8px 0}.mui-input-row .mui-input-clear~.mui-icon-clear,.mui-input-row .mui-input-password~.mui-icon-eye,.mui-input-row .mui-input-speech~.mui-icon-speech{font-size:20px;position:absolute;z-index:1;top:10px;right:0;width:38px;height:38px;text-align:center;color:#999}.mui-input-row .mui-input-clear~.mui-icon-clear.mui-active,.mui-input-row .mui-input-password~.mui-icon-eye.mui-active,.mui-input-row .mui-input-speech~.mui-icon-speech.mui-active{color:#007aff}.mui-input-row .mui-input-speech~.mui-icon-speech{font-size:24px;top:8px}.mui-input-row .mui-input-clear~.mui-icon-clear~.mui-icon-speech{display:none}.mui-input-row .mui-input-clear~.mui-icon-clear.mui-hidden~.mui-icon-speech{display:inline-block}.mui-input-row .mui-icon-speech~.mui-placeholder{right:38px}.mui-input-row.mui-search .mui-icon-clear{top:7px}.mui-input-row.mui-search .mui-icon-speech{top:5px}.mui-checkbox,.mui-radio{position:relative}.mui-checkbox label,.mui-radio label{display:inline-block;float:none;width:100%;padding-right:58px}.mui-checkbox.mui-left input[type=checkbox],.mui-radio.mui-left input[type=radio]{left:20px}.mui-checkbox.mui-left label,.mui-radio.mui-left label{padding-right:15px;padding-left:58px}.mui-checkbox input[type=checkbox],.mui-radio input[type=radio]{position:absolute;top:4px;right:20px;display:inline-block;width:28px;height:26px;border:0;outline:0!important;background-color:transparent;-webkit-appearance:none}.mui-checkbox input[type=checkbox][disabled]:before,.mui-radio input[type=radio][disabled]:before{opacity:.3}.mui-checkbox input[type=checkbox]:before,.mui-radio input[type=radio]:before{font-family:Muiicons;font-size:28px;font-weight:400;line-height:1;text-decoration:none;color:#aaa;border-radius:0;background:0 0;-webkit-font-smoothing:antialiased}.mui-checkbox input[type=checkbox]:checked:before,.mui-radio input[type=radio]:checked:before{color:#007aff}.mui-checkbox label.mui-disabled,.mui-checkbox.mui-disabled label,.mui-radio label.mui-disabled,.mui-radio.mui-disabled label{opacity:.4}.mui-radio input[type=radio]:before{content:'\e411'}.mui-radio input[type=radio]:checked:before{content:'\e441'}.mui-checkbox input[type=checkbox]:before{content:'\e411'}.mui-checkbox input[type=checkbox]:checked:before{content:'\e442'}.mui-select{position:relative}.mui-select:before{font-family:Muiicons;position:absolute;top:8px;right:21px;content:'\e581';color:rgba(170,170,170,.6)}.mui-input-row .mui-switch{float:right;margin-top:5px;margin-right:20px}.mui-input-range input[type=range]{position:relative;width:100%;height:2px;margin:17px 0;padding:0;cursor:pointer;border:0;border-radius:3px;outline:0;background-color:#999;-webkit-appearance:none!important}.mui-input-range input[type=range]::-webkit-slider-thumb{width:28px;height:28px;border-color:#0062cc;border-radius:50%;background-color:#007aff;background-clip:padding-box;-webkit-appearance:none!important}.mui-input-range label~input[type=range]{width:65%}.mui-input-range .mui-tooltip{font-size:36px;line-height:64px;position:absolute;z-index:1;top:-70px;width:64px;height:64px;text-align:center;opacity:.8;color:#333;border:1px solid #ddd;border-radius:6px;background-color:#fff;text-shadow:0 1px 0 #f3f3f3}.mui-search{position:relative}.mui-search input[type=search]{padding-left:30px}.mui-search .mui-placeholder{font-size:16px;line-height:34px;position:absolute;z-index:1;top:0;right:0;bottom:0;left:0;display:inline-block;height:34px;text-align:center;color:#999;border:0;border-radius:6px;background:0 0}.mui-search .mui-placeholder .mui-icon{font-size:20px;color:#333}.mui-search:before{font-family:Muiicons;font-size:20px;font-weight:400;position:absolute;top:50%;right:50%;display:none;margin-top:-18px;margin-right:31px;content:'\e466'}.mui-search.mui-active:before{font-size:20px;right:auto;left:5px;display:block;margin-right:0}.mui-search.mui-active input[type=search]{text-align:left}.mui-search.mui-active .mui-placeholder{display:none}.mui-segmented-control{font-size:15px;font-weight:400;position:relative;display:table;overflow:hidden;width:100%;table-layout:fixed;border:1px solid #007aff;border-radius:3px;background-color:transparent;-webkit-touch-callout:none}.mui-segmented-control.mui-segmented-control-vertical{border-collapse:collapse;border-width:0;border-radius:0}.mui-segmented-control.mui-segmented-control-vertical .mui-control-item{display:block;border-bottom:1px solid #c8c7cc;border-left-width:0}.mui-segmented-control.mui-scroll-wrapper{height:38px}.mui-segmented-control.mui-scroll-wrapper .mui-scroll{width:auto;height:40px;white-space:nowrap}.mui-segmented-control.mui-scroll-wrapper .mui-control-item{display:inline-block;width:auto;padding:0 20px;border:0}.mui-segmented-control .mui-control-item{line-height:38px;display:table-cell;overflow:hidden;width:1%;-webkit-transition:background-color .1s linear;transition:background-color .1s linear;text-align:center;white-space:nowrap;text-overflow:ellipsis;color:#007aff;border-color:#007aff;border-left:1px solid #007aff}.mui-segmented-control .mui-control-item:first-child{border-left-width:0}.mui-segmented-control .mui-control-item.mui-active{color:#fff;background-color:#007aff}.mui-segmented-control.mui-segmented-control-inverted{width:100%;border:0;border-radius:0}.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item,.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active{border-bottom:1px solid #c8c7cc}.mui-segmented-control.mui-segmented-control-inverted .mui-control-item{color:inherit;border:0}.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active{color:#007aff;border-bottom:2px solid #007aff;background:0 0}.mui-segmented-control.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#007aff}.mui-segmented-control-positive{border:1px solid #4cd964}.mui-segmented-control-positive .mui-control-item{color:#4cd964;border-color:inherit}.mui-segmented-control-positive .mui-control-item.mui-active{color:#fff;background-color:#4cd964}.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active{color:#4cd964;border-bottom:2px solid #4cd964;background:0 0}.mui-segmented-control-positive.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#4cd964}.mui-segmented-control-negative{border:1px solid #dd524d}.mui-segmented-control-negative .mui-control-item{color:#dd524d;border-color:inherit}.mui-segmented-control-negative .mui-control-item.mui-active{color:#fff;background-color:#dd524d}.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active{color:#dd524d;border-bottom:2px solid #dd524d;background:0 0}.mui-segmented-control-negative.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#dd524d}.mui-control-content{position:relative;display:none}.mui-control-content.mui-active{display:block}.mui-popover{position:absolute;z-index:999;display:none;width:280px;-webkit-transition:opacity .3s;transition:opacity .3s;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transform:none;transform:none;opacity:0;border-radius:7px;background-color:#f7f7f7;-webkit-box-shadow:0 0 15px rgba(0,0,0,.1);box-shadow:0 0 15px rgba(0,0,0,.1)}.mui-popover .mui-popover-arrow{position:absolute;z-index:1000;top:-25px;left:0;overflow:hidden;width:26px;height:26px}.mui-popover .mui-popover-arrow:after{position:absolute;top:19px;left:0;width:26px;height:26px;content:' ';-webkit-transform:rotate(45deg);transform:rotate(45deg);border-radius:3px;background:#f7f7f7}.mui-popover .mui-popover-arrow.mui-bottom{top:100%;left:-26px;margin-top:-1px}.mui-popover .mui-popover-arrow.mui-bottom:after{top:-19px;left:0}.mui-popover.mui-popover-action{bottom:0;width:100%;-webkit-transition:-webkit-transform .3s,opacity .3s;transition:transform .3s,opacity .3s;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);border-radius:0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.mui-popover.mui-popover-action .mui-popover-arrow{display:none}.mui-popover.mui-popover-action.mui-popover-bottom{position:fixed}.mui-popover.mui-popover-action.mui-active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mui-popover.mui-popover-action .mui-table-view{margin:8px;text-align:center;color:#007aff;border-radius:4px}.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-popover.mui-popover-action .mui-table-view small{font-weight:400;line-height:1.3;display:block}.mui-popover.mui-active{display:block;opacity:1}.mui-popover .mui-bar~.mui-table-view{padding-top:44px}.mui-backdrop{position:fixed;z-index:998;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.3)}.mui-bar-backdrop.mui-backdrop{bottom:50px;background:0 0}.mui-backdrop-action.mui-backdrop{background-color:rgba(0,0,0,.3)}.mui-backdrop-action.mui-backdrop,.mui-bar-backdrop.mui-backdrop{opacity:0}.mui-backdrop-action.mui-backdrop.mui-active,.mui-bar-backdrop.mui-backdrop.mui-active{-webkit-transition:all .4s ease;transition:all .4s ease;opacity:1}.mui-popover .mui-btn-block{margin-bottom:5px}.mui-popover .mui-btn-block:last-child{margin-bottom:0}.mui-popover .mui-bar{-webkit-box-shadow:none;box-shadow:none}.mui-popover .mui-bar-nav{border-bottom:1px solid rgba(0,0,0,.15);border-top-left-radius:12px;border-top-right-radius:12px;-webkit-box-shadow:none;box-shadow:none}.mui-popover .mui-scroll-wrapper{margin:7px 0;border-radius:7px;background-clip:padding-box}.mui-popover .mui-scroll .mui-table-view{max-height:none}.mui-popover .mui-table-view{overflow:auto;max-height:300px;margin-bottom:0;border-radius:7px;background-color:#f7f7f7;background-image:none;-webkit-overflow-scrolling:touch}.mui-popover .mui-table-view:after,.mui-popover .mui-table-view:before{height:0}.mui-popover .mui-table-view .mui-table-view-cell:first-child,.mui-popover .mui-table-view .mui-table-view-cell:first-child>a:not(.mui-btn){border-top-left-radius:12px;border-top-right-radius:12px}.mui-popover .mui-table-view .mui-table-view-cell:last-child,.mui-popover .mui-table-view .mui-table-view-cell:last-child>a:not(.mui-btn){border-bottom-right-radius:12px;border-bottom-left-radius:12px}.mui-popover.mui-bar-popover .mui-table-view{width:106px}.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell{padding:11px 15px;background-position:0 100%}.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell>a:not(.mui-btn){margin:-11px -15px -11px -15px}.mui-popup-backdrop{position:fixed;z-index:998;top:0;right:0;bottom:0;left:0;-webkit-transition-duration:400ms;transition-duration:400ms;opacity:0;background:rgba(0,0,0,.4)}.mui-popup-backdrop.mui-active{opacity:1}.mui-popup{position:fixed;z-index:10000;top:50%;left:50%;display:none;overflow:hidden;width:270px;-webkit-transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-transform:translate3d(-50%,-50%,0) scale(1.185);transform:translate3d(-50%,-50%,0) scale(1.185);text-align:center;opacity:0;color:#000;border-radius:13px}.mui-popup.mui-popup-in{display:block;-webkit-transition-duration:400ms;transition-duration:400ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1);opacity:1}.mui-popup.mui-popup-out{-webkit-transition-duration:400ms;transition-duration:400ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1);opacity:0}.mui-popup-inner{position:relative;padding:15px;border-radius:13px 13px 0 0;background:rgba(255,255,255,.95)}.mui-popup-inner:after{position:absolute;z-index:15;top:auto;right:auto;bottom:0;left:0;display:block;width:100%;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;background-color:rgba(0,0,0,.2)}.mui-popup-title{font-size:18px;font-weight:500;text-align:center}.mui-popup-title+.mui-popup-text{font-family:inherit;font-size:14px;margin:5px 0 0}.mui-popup-buttons{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;height:44px;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.mui-popup-button{font-size:17px;line-height:44px;position:relative;display:block;overflow:hidden;box-sizing:border-box;width:100%;height:44px;padding:0 5px;cursor:pointer;text-align:center;white-space:nowrap;text-overflow:ellipsis;color:#007aff;background:rgba(255,255,255,.95);-webkit-box-flex:1}.mui-popup-button:after{position:absolute;z-index:15;top:0;right:0;bottom:auto;left:auto;display:block;width:1px;height:100%;content:'';-webkit-transform:scaleX(.5);transform:scaleX(.5);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;background-color:rgba(0,0,0,.2)}.mui-popup-button:first-child{border-radius:0 0 0 13px}.mui-popup-button:first-child:last-child{border-radius:0 0 13px 13px}.mui-popup-button:last-child{border-radius:0 0 13px}.mui-popup-button:last-child:after{display:none}.mui-popup-button.mui-popup-button-bold{font-weight:600}.mui-popup-input input{font-size:14px;width:100%;height:26px;margin:15px 0 0;padding:0 5px;border:1px solid rgba(0,0,0,.3);border-radius:0;background:#fff}.mui-plus.mui-android .mui-popup-backdrop{-webkit-transition-duration:1ms;transition-duration:1ms}.mui-plus.mui-android .mui-popup{-webkit-transition-duration:1ms;transition-duration:1ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1)}.mui-progressbar{position:relative;display:block;overflow:hidden;width:100%;height:2px;-webkit-transform-origin:center top;transform-origin:center top;vertical-align:middle;border-radius:2px;background:#b6b6b6;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-progressbar span{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-transition:150ms;transition:150ms;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);background:#007aff}.mui-progressbar.mui-progressbar-infinite:before{position:absolute;top:0;left:0;width:100%;height:100%;content:'';-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transform-origin:left center;transform-origin:left center;-webkit-animation:mui-progressbar-infinite 1s linear infinite;animation:mui-progressbar-infinite 1s linear infinite;background:#007aff}body>.mui-progressbar{position:absolute;z-index:10000;top:44px;left:0;border-radius:0}.mui-progressbar-in{-webkit-animation:mui-progressbar-in 300ms forwards;animation:mui-progressbar-in 300ms forwards}.mui-progressbar-out{-webkit-animation:mui-progressbar-out 300ms forwards;animation:mui-progressbar-out 300ms forwards}@-webkit-keyframes mui-progressbar-in{from{-webkit-transform:scaleY(0);opacity:0}to{-webkit-transform:scaleY(1);opacity:1}}@keyframes mui-progressbar-in{from{transform:scaleY(0);opacity:0}to{transform:scaleY(1);opacity:1}}@-webkit-keyframes mui-progressbar-out{from{-webkit-transform:scaleY(1);opacity:1}to{-webkit-transform:scaleY(0);opacity:0}}@keyframes mui-progressbar-out{from{transform:scaleY(1);opacity:1}to{transform:scaleY(0);opacity:0}}@-webkit-keyframes mui-progressbar-infinite{0%{-webkit-transform:translate3d(-50%,0,0) scaleX(.5)}100%{-webkit-transform:translate3d(100%,0,0) scaleX(.5)}}@keyframes mui-progressbar-infinite{0%{transform:translate3d(-50%,0,0) scaleX(.5)}100%{transform:translate3d(100%,0,0) scaleX(.5)}}.mui-pagination{display:inline-block;margin:0 auto;padding-left:0;border-radius:6px}.mui-pagination>li{display:inline}.mui-pagination>li>a,.mui-pagination>li>span{line-height:1.428571429;position:relative;float:left;margin-left:-1px;padding:6px 12px;text-decoration:none;color:#007aff;border:1px solid #ddd;background-color:#fff}.mui-pagination>li:first-child>a,.mui-pagination>li:first-child>span{margin-left:0;border-top-left-radius:6px;border-bottom-left-radius:6px;background-clip:padding-box}.mui-pagination>li:last-child>a,.mui-pagination>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px;background-clip:padding-box}.mui-pagination>li.mui-active>a,.mui-pagination>li.mui-active>a:active,.mui-pagination>li.mui-active>span,.mui-pagination>li.mui-active>span:active,.mui-pagination>li:active>a,.mui-pagination>li:active>a:active,.mui-pagination>li:active>span,.mui-pagination>li:active>span:active{z-index:2;cursor:default;color:#fff;border-color:#007aff;background-color:#007aff}.mui-pagination>li.mui-disabled>a,.mui-pagination>li.mui-disabled>a:active,.mui-pagination>li.mui-disabled>span,.mui-pagination>li.mui-disabled>span:active{opacity:.6;color:#777;border:1px solid #ddd;background-color:#fff}.mui-pagination-lg>li>a,.mui-pagination-lg>li>span{font-size:18px;padding:10px 16px}.mui-pagination-sm>li>a,.mui-pagination-sm>li>span{font-size:12px;padding:5px 10px}.mui-pager{padding-left:0;list-style:none;text-align:center}.mui-pager:after,.mui-pager:before{display:table;content:' '}.mui-pager:after{clear:both}.mui-pager li{display:inline}.mui-pager li>a,.mui-pager li>span{display:inline-block;padding:5px 14px;border:1px solid #ddd;border-radius:6px;background-color:#fff;background-clip:padding-box}.mui-pager li.mui-active>a,.mui-pager li.mui-active>span,.mui-pager li:active>a,.mui-pager li:active>span{cursor:default;text-decoration:none;color:#fff;border-color:#007aff;background-color:#007aff}.mui-pager .mui-next>a,.mui-pager .mui-next>span{float:right}.mui-pager .mui-previous>a,.mui-pager .mui-previous>span{float:left}.mui-pager .mui-disabled>a,.mui-pager .mui-disabled>a:active,.mui-pager .mui-disabled>span,.mui-pager .mui-disabled>span:active{opacity:.6;color:#777;border:1px solid #ddd;background-color:#fff}.mui-modal{position:fixed;z-index:999;top:0;overflow:hidden;width:100%;min-height:100%;-webkit-transition:-webkit-transform .25s,opacity 1ms .25s;transition:transform .25s,opacity 1ms .25s;-webkit-transition-timing-function:cubic-bezier(.1,.5,.1,1);transition-timing-function:cubic-bezier(.1,.5,.1,1);-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);opacity:0;background-color:#fff}.mui-modal.mui-active{height:100%;-webkit-transition:-webkit-transform .25s;transition:transform .25s;-webkit-transition-timing-function:cubic-bezier(.1,.5,.1,1);transition-timing-function:cubic-bezier(.1,.5,.1,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}.mui-android .mui-modal .mui-bar{position:static}.mui-android .mui-modal .mui-bar-nav~.mui-content{padding-top:0}.mui-slider{position:relative;z-index:1;overflow:hidden;width:100%}.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active{border-bottom:0}.mui-slider .mui-segmented-control.mui-segmented-control-inverted~.mui-slider-group .mui-slider-item{border-top:1px solid #c8c7cc;border-bottom:1px solid #c8c7cc}.mui-slider .mui-slider-group{font-size:0;position:relative;-webkit-transition:all 0s linear;transition:all 0s linear;white-space:nowrap}.mui-slider .mui-slider-group .mui-slider-item{font-size:14px;position:relative;display:inline-block;width:100%;height:100%;vertical-align:top;white-space:normal}.mui-slider .mui-slider-group .mui-slider-item>a:not(.mui-control-item){line-height:0;position:relative;display:block}.mui-slider .mui-slider-group .mui-slider-item img{width:100%}.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after,.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before{height:0}.mui-slider .mui-slider-group.mui-slider-loop{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}.mui-slider-title{line-height:30px;position:absolute;bottom:0;left:0;width:100%;height:30px;margin:0;text-align:left;text-indent:12px;opacity:.8;background-color:#000}.mui-slider-indicator{position:absolute;bottom:8px;width:100%;text-align:center;background:0 0}.mui-slider-indicator.mui-segmented-control{position:relative;bottom:auto}.mui-slider-indicator .mui-indicator{display:inline-block;width:6px;height:6px;margin:1px 6px;cursor:pointer;border-radius:50%;background:#aaa;-webkit-box-shadow:0 0 1px 1px rgba(130,130,130,.7);box-shadow:0 0 1px 1px rgba(130,130,130,.7)}.mui-slider-indicator .mui-active.mui-indicator{background:#fff}.mui-slider-indicator .mui-icon{font-size:20px;line-height:30px;width:40px;height:30px;margin:3px;text-align:center;border:1px solid #ddd}.mui-slider-indicator .mui-number{line-height:32px;display:inline-block;width:58px}.mui-slider-indicator .mui-number span{color:#ff5053}.mui-slider-progress-bar{z-index:1;height:2px;-webkit-transform:translateZ(0);transform:translateZ(0)}.mui-switch{position:relative;display:block;width:74px;height:30px;-webkit-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out;-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-property:background-color,border;transition-property:background-color,border;border:2px solid #ddd;border-radius:20px;background-color:#fff;background-clip:padding-box}.mui-switch.mui-disabled{opacity:.3}.mui-switch .mui-switch-handle{position:absolute;z-index:1;top:-1px;left:-1px;width:28px;height:28px;-webkit-transition:.2s ease-in-out;transition:.2s ease-in-out;-webkit-transition-property:-webkit-transform,width,left;transition-property:transform,width,left;border-radius:16px;background-color:#fff;background-clip:padding-box;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.4);box-shadow:0 2px 5px rgba(0,0,0,.4)}.mui-switch:before{font-size:13px;position:absolute;top:3px;right:11px;content:'Off';text-transform:uppercase;color:#999}.mui-switch.mui-dragging{border-color:#f7f7f7;background-color:#f7f7f7}.mui-switch.mui-dragging .mui-switch-handle{width:38px}.mui-switch.mui-dragging.mui-active .mui-switch-handle{left:-11px;width:38px}.mui-switch.mui-active{border-color:#4cd964;background-color:#4cd964}.mui-switch.mui-active .mui-switch-handle{-webkit-transform:translate(43px,0);transform:translate(43px,0)}.mui-switch.mui-active:before{right:auto;left:15px;content:'On';color:#fff}.mui-switch input[type=checkbox]{display:none}.mui-switch-mini{width:47px}.mui-switch-mini:before{display:none}.mui-switch-mini.mui-active .mui-switch-handle{-webkit-transform:translate(16px,0);transform:translate(16px,0)}.mui-switch-blue.mui-active{border:2px solid #007aff;background-color:#007aff}.mui-content.mui-fade{left:0;opacity:0}.mui-content.mui-fade.mui-in{opacity:1}.mui-content.mui-sliding{z-index:2;-webkit-transition:-webkit-transform .4s;transition:transform .4s;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mui-content.mui-sliding.mui-left{z-index:1;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.mui-content.mui-sliding.mui-right{z-index:3;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.mui-navigate-right:after,.mui-push-left:after,.mui-push-right:after{font-family:Muiicons;font-size:inherit;line-height:1;position:absolute;top:50%;display:inline-block;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-decoration:none;color:#bbb;-webkit-font-smoothing:antialiased}.mui-push-left:after{left:15px;content:'\e582'}.mui-navigate-right:after,.mui-push-right:after{right:15px;content:'\e583'}.mui-pull-bottom-pocket,.mui-pull-top-pocket{position:absolute;left:0;display:block;visibility:hidden;overflow:hidden;width:100%;height:50px}.mui-plus-pullrefresh .mui-pull-bottom-pocket,.mui-plus-pullrefresh .mui-pull-top-pocket{display:none;visibility:visible}.mui-pull-top-pocket{top:0}.mui-bar-nav~.mui-content .mui-pull-top-pocket{top:44px}.mui-bar-nav~.mui-bar-header-secondary~.mui-content .mui-pull-top-pocket{top:88px}.mui-pull-bottom-pocket{position:relative;bottom:0;height:40px}.mui-pull-bottom-pocket .mui-pull-loading{visibility:hidden}.mui-pull-bottom-pocket .mui-pull-loading.mui-in{display:inline-block}.mui-pull{font-weight:700;position:absolute;right:0;bottom:10px;left:0;text-align:center;color:#777}.mui-pull-loading{margin-right:10px;-webkit-transition:-webkit-transform .4s;transition:transform .4s;-webkit-transition-duration:400ms;transition-duration:400ms;vertical-align:middle}.mui-pull-loading.mui-reverse{-webkit-transform:rotate(180deg) translateZ(0);transform:rotate(180deg) translateZ(0)}.mui-pull-caption{font-size:15px;line-height:24px;position:relative;display:inline-block;overflow:visible;margin-top:0;vertical-align:middle}.mui-pull-caption span{display:none}.mui-pull-caption span.mui-in{display:inline}.mui-toast-container{line-height:17px;position:fixed;z-index:9999;bottom:50px;left:50%;-webkit-transition:opacity .3s;transition:opacity .3s;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);opacity:0}.mui-toast-container.mui-active{opacity:.9}.mui-toast-message{font-size:14px;padding:10px 25px;text-align:center;color:#fff;border-radius:6px;background-color:#323232}.mui-numbox{position:relative;display:inline-block;overflow:hidden;width:120px;height:35px;padding:0 40px;vertical-align:top;vertical-align:middle;border:solid 1px #bbb;border-radius:3px;background-color:#efeff4}.mui-numbox [class*=btn-numbox],.mui-numbox [class*=numbox-btn]{font-size:18px;font-weight:400;line-height:100%;position:absolute;top:0;overflow:hidden;width:40px;height:100%;padding:0;color:#555;border:none;border-radius:0;background-color:#f9f9f9}.mui-numbox [class*=btn-numbox]:active,.mui-numbox [class*=numbox-btn]:active{background-color:#ccc}.mui-numbox [class*=btn-numbox][disabled],.mui-numbox [class*=numbox-btn][disabled]{color:silver}.mui-numbox .mui-btn-numbox-plus,.mui-numbox .mui-numbox-btn-plus{right:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.mui-numbox .mui-btn-numbox-minus,.mui-numbox .mui-numbox-btn-minus{left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.mui-numbox .mui-input-numbox,.mui-numbox .mui-numbox-input{display:inline-block;overflow:hidden;width:100%!important;height:100%;margin:0;padding:0 3px!important;text-align:center;text-overflow:ellipsis;word-break:normal;border:none!important;border-right:solid 1px #ccc!important;border-left:solid 1px #ccc!important;border-radius:0!important}.mui-input-row .mui-numbox{float:right;margin:2px 8px}@font-face{font-family:Muiicons;font-weight:400;font-style:normal;src:url(../fonts/mui.ttf) format('truetype')}.mui-icon{font-family:Muiicons;font-size:24px;font-weight:400;font-style:normal;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased}.mui-icon.mui-active{color:#007aff}.mui-icon.mui-right:before{float:right;padding-left:.2em}.mui-icon-contact:before{content:'\e100'}.mui-icon-person:before{content:'\e101'}.mui-icon-personadd:before{content:'\e102'}.mui-icon-contact-filled:before{content:'\e130'}.mui-icon-person-filled:before{content:'\e131'}.mui-icon-personadd-filled:before{content:'\e132'}.mui-icon-phone:before{content:'\e200'}.mui-icon-email:before{content:'\e201'}.mui-icon-chatbubble:before{content:'\e202'}.mui-icon-chatboxes:before{content:'\e203'}.mui-icon-phone-filled:before{content:'\e230'}.mui-icon-email-filled:before{content:'\e231'}.mui-icon-chatbubble-filled:before{content:'\e232'}.mui-icon-chatboxes-filled:before{content:'\e233'}.mui-icon-weibo:before{content:'\e260'}.mui-icon-weixin:before{content:'\e261'}.mui-icon-pengyouquan:before{content:'\e262'}.mui-icon-chat:before{content:'\e263'}.mui-icon-qq:before{content:'\e264'}.mui-icon-videocam:before{content:'\e300'}.mui-icon-camera:before{content:'\e301'}.mui-icon-mic:before{content:'\e302'}.mui-icon-location:before{content:'\e303'}.mui-icon-mic-filled:before,.mui-icon-speech:before{content:'\e332'}.mui-icon-location-filled:before{content:'\e333'}.mui-icon-micoff:before{content:'\e360'}.mui-icon-image:before{content:'\e363'}.mui-icon-map:before{content:'\e364'}.mui-icon-compose:before{content:'\e400'}.mui-icon-trash:before{content:'\e401'}.mui-icon-upload:before{content:'\e402'}.mui-icon-download:before{content:'\e403'}.mui-icon-close:before{content:'\e404'}.mui-icon-redo:before{content:'\e405'}.mui-icon-undo:before{content:'\e406'}.mui-icon-refresh:before{content:'\e407'}.mui-icon-star:before{content:'\e408'}.mui-icon-plus:before{content:'\e409'}.mui-icon-minus:before{content:'\e410'}.mui-icon-checkbox:before,.mui-icon-circle:before{content:'\e411'}.mui-icon-clear:before,.mui-icon-close-filled:before{content:'\e434'}.mui-icon-refresh-filled:before{content:'\e437'}.mui-icon-star-filled:before{content:'\e438'}.mui-icon-plus-filled:before{content:'\e439'}.mui-icon-minus-filled:before{content:'\e440'}.mui-icon-circle-filled:before{content:'\e441'}.mui-icon-checkbox-filled:before{content:'\e442'}.mui-icon-closeempty:before{content:'\e460'}.mui-icon-refreshempty:before{content:'\e461'}.mui-icon-reload:before{content:'\e462'}.mui-icon-starhalf:before{content:'\e463'}.mui-icon-spinner:before{content:'\e464'}.mui-icon-spinner-cycle:before{content:'\e465'}.mui-icon-search:before{content:'\e466'}.mui-icon-plusempty:before{content:'\e468'}.mui-icon-forward:before{content:'\e470'}.mui-icon-back:before,.mui-icon-left-nav:before{content:'\e471'}.mui-icon-checkmarkempty:before{content:'\e472'}.mui-icon-home:before{content:'\e500'}.mui-icon-navigate:before{content:'\e501'}.mui-icon-gear:before{content:'\e502'}.mui-icon-paperplane:before{content:'\e503'}.mui-icon-info:before{content:'\e504'}.mui-icon-help:before{content:'\e505'}.mui-icon-locked:before{content:'\e506'}.mui-icon-more:before{content:'\e507'}.mui-icon-flag:before{content:'\e508'}.mui-icon-home-filled:before{content:'\e530'}.mui-icon-gear-filled:before{content:'\e532'}.mui-icon-info-filled:before{content:'\e534'}.mui-icon-help-filled:before{content:'\e535'}.mui-icon-more-filled:before{content:'\e537'}.mui-icon-settings:before{content:'\e560'}.mui-icon-list:before{content:'\e562'}.mui-icon-bars:before{content:'\e563'}.mui-icon-loop:before{content:'\e565'}.mui-icon-paperclip:before{content:'\e567'}.mui-icon-eye:before{content:'\e568'}.mui-icon-arrowup:before{content:'\e580'}.mui-icon-arrowdown:before{content:'\e581'}.mui-icon-arrowleft:before{content:'\e582'}.mui-icon-arrowright:before{content:'\e583'}.mui-icon-arrowthinup:before{content:'\e584'}.mui-icon-arrowthindown:before{content:'\e585'}.mui-icon-arrowthinleft:before{content:'\e586'}.mui-icon-arrowthinright:before{content:'\e587'}.mui-icon-pulldown:before{content:'\e588'}.mui-fullscreen{position:absolute;top:0;right:0;bottom:0;left:0}.mui-fullscreen.mui-slider .mui-slider-group{height:100%}.mui-fullscreen .mui-segmented-control~.mui-slider-group{position:absolute;top:40px;bottom:0;width:100%;height:auto}.mui-fullscreen.mui-slider .mui-slider-item>a{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item>a{top:auto;-webkit-transform:none;transform:none}.mui-bar-nav~.mui-content .mui-slider.mui-fullscreen{top:44px}.mui-bar-tab~.mui-content .mui-slider.mui-fullscreen .mui-segmented-control~.mui-slider-group{bottom:50px}.mui-android.mui-android-4-0 input:focus,.mui-android.mui-android-4-0 textarea:focus{-webkit-user-modify:inherit}.mui-android.mui-android-4-2 input,.mui-android.mui-android-4-2 textarea,.mui-android.mui-android-4-3 input,.mui-android.mui-android-4-3 textarea{-webkit-user-select:text}.mui-ios .mui-table-view-cell{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-plus-visible,.mui-wechat-visible{display:none!important}.mui-plus-hidden,.mui-wechat-hidden{display:block!important}.mui-tab-item.mui-plus-hidden,.mui-tab-item.mui-wechat-hidden{display:table-cell!important}.mui-plus .mui-plus-visible,.mui-wechat .mui-wechat-visible{display:block!important}.mui-plus .mui-tab-item.mui-plus-visible,.mui-wechat .mui-tab-item.mui-wechat-visible{display:table-cell!important}.mui-plus .mui-plus-hidden,.mui-wechat .mui-wechat-hidden{display:none!important}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav{height:64px;padding-top:20px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav~.mui-content{padding-top:64px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary,.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav~.mui-content .mui-pull-top-pocket{top:64px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary~.mui-content{padding-top:94px}.mui-iframe-wrapper{position:absolute;right:0;left:0;-webkit-overflow-scrolling:touch}.mui-iframe-wrapper iframe{width:100%;height:100%;border:0} \ No newline at end of file diff --git a/static/app/css/mui.picker.css b/static/app/css/mui.picker.css new file mode 100755 index 0000000..015723d --- /dev/null +++ b/static/app/css/mui.picker.css @@ -0,0 +1,85 @@ +/** + * 选择列表插件 + * varstion 2.0.0 + * by Houfeng + * Houfeng@DCloud.io + */ + +.mui-picker { + background-color: #ddd; + position: relative; + height: 200px; + overflow: hidden; + border: solid 1px rgba(0, 0, 0, 0.1); + -webkit-user-select: none; + user-select: none; + box-sizing: border-box; +} +.mui-picker-inner { + box-sizing: border-box; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, #fff 20%, #fff 80%, transparent 95%, transparent); + -webkit-mask-box-image: linear-gradient(top, transparent, transparent 5%, #fff 20%, #fff 80%, transparent 95%, transparent); +} +.mui-pciker-list, +.mui-pciker-rule { + box-sizing: border-box; + padding: 0px; + margin: 0px; + width: 100%; + height: 36px; + line-height: 36px; + position: absolute; + left: 0px; + top: 50%; + margin-top: -18px; +} +.mui-pciker-rule-bg { + z-index: 0; + /*background-color: #cfd5da;*/ +} +.mui-pciker-rule-ft { + z-index: 2; + border-top: solid 1px rgba(0, 0, 0, 0.1); + border-bottom: solid 1px rgba(0, 0, 0, 0.1); + /*-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);*/ + /*box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);*/ +} +.mui-pciker-list { + z-index: 1; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transform: perspective(1000px) rotateY(0deg) rotateX(0deg); + transform: perspective(1000px) rotateY(0deg) rotateX(0deg); +} +.mui-pciker-list li { + width: 100%; + height: 100%; + position: absolute; + text-align: center; + vertical-align: middle; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + overflow: hidden; + box-sizing: border-box; + font-size: 16px; + font-family: "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; + color: #888; + padding: 0px 8px; + white-space: nowrap; + -webkit-text-overflow: ellipsis; + text-overflow: ellipsis; + overflow: hidden; + cursor: default; + visibility: hidden; +} +.mui-pciker-list li.highlight, +.mui-pciker-list li.visible { + visibility: visible; +} +.mui-pciker-list li.highlight { + color: #222; +} \ No newline at end of file diff --git a/static/app/css/mui.poppicker.css b/static/app/css/mui.poppicker.css new file mode 100755 index 0000000..c0eb469 --- /dev/null +++ b/static/app/css/mui.poppicker.css @@ -0,0 +1,64 @@ +.mui-poppicker { + position: fixed; + left: 0px; + width: 100%; + z-index: 999; + background-color: #eee; + border-top: solid 1px #ccc; + box-shadow: 0px -5px 7px 0px rgba(0, 0, 0, 0.1); + -webkit-transition: .3s; + bottom: 0px; + -webkit-transform: translateY(300px); +} +.mui-poppicker.mui-active { + -webkit-transform: translateY(0px); +} +.mui-android-5-1 .mui-poppicker { + bottom: -300px; + -webkit-transition-property: bottom; + -webkit-transform: none; +} +.mui-android-5-1 .mui-poppicker.mui-active { + bottom: 0px; + -webkit-transition-property: bottom; + -webkit-transform: none; +} +.mui-poppicker-header { + padding: 6px; + font-size: 14px; + color: #888; +} +.mui-poppicker-header .mui-btn { + font-size: 12px; + padding: 5px 10px; +} +.mui-poppicker-btn-cancel { + float: left; +} +.mui-poppicker-btn-ok { + float: right; +} +.mui-poppicker-clear { + clear: both; + height: 0px; + line-height: 0px; + font-size: 0px; + overflow: hidden; +} +.mui-poppicker-body { + position: relative; + width: 100%; + height: 200px; + border-top: solid 1px #ddd; + /*-webkit-perspective: 1200px; + perspective: 1200px; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d;*/ +} +.mui-poppicker-body .mui-picker { + width: 100%; + height: 100%; + margin: 0px; + border: none; + float: left; +} \ No newline at end of file diff --git a/static/app/css/my.css b/static/app/css/my.css new file mode 100755 index 0000000..638105b --- /dev/null +++ b/static/app/css/my.css @@ -0,0 +1,186 @@ +.my{ + width: 100%; + height: 180px; + background: url(../img/my_bg.png) no-repeat center top; + background-size: 100% 100%; + position: relative; +} +.header{ + padding-top: 18px; +} +.seeting{ + font-size: 14.4px; + color: #ffffff; + margin-top: 15px; + margin-left: 9px; + float: left; +} +.con{ + position: absolute; + top: 75px; + left: 15px; + width: 93%; +} +.con img{ + width: 78px; + height: 78px; + border-radius: 50%; + border: 3px solid #fff; + left: 0; + top: 0; + z-index: 11; +} +.con p{ + position: absolute; + font-size: 14.4px; + color: #fff; + left: 93px; + top: 35px; + width: 180px; +} +.hyz{ + width: 102px; + height: 26.4px; + font-size: 13.2px; + line-height: 29px; + text-indent: 27px; + color: #fff; + background: url(../img/hyz_bg.png) no-repeat center top; + background-size: 100%; + right: 0; + position: absolute; + top: 111px; +} +.nav { + width: 100%; + height: 81px; + background: white; + border-bottom: 9px solid #ebebeb; +} +.nblock{ + width: 33.3%; + height: 72px; + text-align: center; + float: left; + padding-top: 10px; +} +.nblock p{ + color: #525252; + font-size: 13.2px; + margin-top: 3px; + +} +.order_title{ + width: 100%; + height: 37px; + background: white; + border-bottom: 1px solid #e6e6e6; + line-height: 36px; +} + +.order_title p{ + font-size: 13.2px; + color: black; + float: left; + margin: 0; + margin-left: 12px; +} + +.order_title .order_more{ + color: #909090; + font-size: 12px; + float: right; + margin: 0; + margin-right: 12px; + +} + +.order_con{ + background: white; + border-bottom: 1px solid #e6e6e6; +} +.order_cb{ + width: 20%; + height: 90px; + text-align: center; + float: left; + position: relative; +} +.order_cb img{ + width: 28.8px; + margin-top: 24px; +} +.order_cb p{ + margin-top: 3px; + color: #525252; + font-size: 12px; +} +.logistics{ + height: 96px; + background: white; +} +.num{ + position: absolute; + width: 20px; + height: 20px; + border-radius: 50%; + background: red; + color: white; + font-size: 10.8px; + text-align: center; + line-height: 20px; + top: 10px; + left: 60%; +} +.con .login{ + width: 78px; + height: 78px; + border-radius: 50%; + border: 3px solid #ebebeb; + color: white; + text-align: center; + line-height: 72px; + /*margin: 0 auto;*/ + position: absolute; + left: 0; + right: 0; + z-index: 0; +} +.myMoney{ + width: 100%; + background: white; + +} +.moneycon_{ + width: 33.3%; + float: left; + height: 81px; + position: relative; +} +.moneycon_ img{ + text-align: center; + width: 40.8px; + height: 40.8px; + position: absolute; + left: 0; + right: 0; + margin: 0 auto; + top:10px; +} +.moneycon_ p{ + text-align: center; + position: absolute; + bottom: 5px; + left: 0; + right: 0; + margin: 0 auto; + color: #E51329; + font-size: 14.4px; +} +.share{ + font-size: 14.4px; + color: #ffffff; + margin-top: 15px; + margin-right: 9px; + float: right; +} diff --git a/static/app/css/order_con.css b/static/app/css/order_con.css new file mode 100755 index 0000000..5231a23 --- /dev/null +++ b/static/app/css/order_con.css @@ -0,0 +1,182 @@ +.ad { + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + width: 100%; + height: 126px; + position: relative; +} + +.ad p { + position: absolute; + color: white; + margin: 0; + font-size: 13.2px; + top: 57px; + left: 36px; +} + +.address { + background: white; + border-bottom: 1px solid #e6e6e6; + position: relative; +} + +.add_l { + float: left; + width: 39px; + position: absolute; + top: 0; + bottom: 0; +} + +.add_l img { + width: 21.6px; + height: 21.6px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} + +.add_r { + width: calc( 100% - 39px); + float: right; + padding-right: 9px; + font-size: 13.2px; + color: #909090; +} + +.add_r_t { + width: 100%; + padding: 6px 0 1px; +} + +.add_r_t_l { + float: left; +} + +.add_r_t_r { + float: right; +} + +.add_r_b { + width: 100%; + padding: 0 0 3px; +} + +.shop_info { + border-bottom: 5px solid #efefef; +} + +.invoice_info { + width: 100%; + padding: 3px 9px; + background: white; + border-bottom: 6px solid #efefef; +} + +.invoice_info p {} + +.cost { + border-bottom: 1px solid #e6e6e6; + background: white; + padding: 9px 9px; + border-radius: ; +} + +.c1 { + font-size: 12px; + color: #909090; +} + +.c1_l { + float: left; +} + +.c1_r { + float: right; +} + +.c2 { + font-size: 13.2px; + color: black; +} + +.cost .on { + color: #e51329; +} + +.jf_info { + width: 100%; + height: 45.6px; + background: white; + border-bottom: 1px solid #e6e6e6; +} + +.jf_jf { + margin-top: 10px; + margin-left: 10px; + color: #e51326; + font-size: 10.8px; + border: 1px solid #e51227; + border-radius: 3px; + float: left; + padding: 0 5px; +} + +.jf_p { + font-size: 13.2px; + color: #525252; + float: left; + margin-left: 10px; + line-height: 46px; +} + +.jf_p o { + color: #e51329; +} + +.lxmj { + width: 100%; + height: 51.6px; + position: relative; + background: white; + border-bottom: 6px solid #efefef; + display: block; +} + +.lxmj img { + width: 15px; + position: absolute; + top: 50%; + left: 40%; + transform: translate(-50%, -50%); +} + +.lxmj p { + font-size: 13.2px; + color: #525252; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.info { + width: 100%; + padding: 9px; + background: white; + border-bottom: 6px solid #efefef; +} + +.info p { + color: #909090; + font-size: 10.8px; +} \ No newline at end of file diff --git a/static/app/css/pay.css b/static/app/css/pay.css new file mode 100755 index 0000000..3418800 --- /dev/null +++ b/static/app/css/pay.css @@ -0,0 +1,130 @@ +.bg { + background: rgba(1, 1, 1, 0.1); + position: fixed; + left: 0; + top: 0; + bottom: 0; + right: 0; + z-index: 10; +} + +.pay, +.pay_way { + position: fixed; + left: 0; + right: 0; + bottom: 0; + background: white; + height: 380px; +} +.pay{ + /*transform: translateY(380px);*/ + display: none; +} +.pay_title { + width: 100%; + height: 49px; + border-bottom: 1px solid #e6e6e6; + position: relative; +} + +.pay_title a { + position: absolute; + z-index: 10; + font-size: 48px; + color: #909090; +} + +.pay_title p { + line-height: 48px; + text-align: center; + color: black; + font-size: 15.6px; +} + +.paynum { + font-size: 27px; + text-align: center; + color: black; + padding: 20px 0; +} + +.con_1 { + padding-left: 15px; +} + +.con_1 .row { + width: 100%; + height: 42px; + border-bottom: 1px solid #e6e6e6; + line-height: 42px; + font-size: 13.2px; +} + +.row_left { + float: left; + color: #909090; +} + +.row_right { + float: right; + color: black; + padding-right: 15px; + position: relative; +} + +.row_right img { + position: absolute; + right: 15px; + top: 12px; +} + +.pay_btn { + width: 92%; + margin: 120px 4% 24px; + color: #FFFFFF; + background: #e6122b; + border: none; + border-radius: 1%; + height: 42px; +} + +.pay_way .pay_title a { + font-size: 36px; + margin: 6px; +} + +.pay_way .con .row .row_left { + color: black; +} + +.row .mui-icon { + color: #e6122b; + font-size: 42px; + padding: 0; +} +#pay_pwd .con_1 { + padding:20px 0; + position: relative; +} +#pay_pwd .con_1 input{ + margin: 30px 5%; + width: 90%; +} +#pay_pwd .con_1 .p9{ + margin: 30px 5%; + width: 90%; + position: absolute; + padding: 5%; + right: 5%; + top: 60px; +} +.pay_btn_pwd { + width: 92%; + margin: 120px 4% 24px; + color: #FFFFFF; + background: #e6122b; + border: none; + border-radius: 1%; + height: 42px; +} diff --git a/static/app/css/photoswipe.css b/static/app/css/photoswipe.css new file mode 100755 index 0000000..0ca0f80 --- /dev/null +++ b/static/app/css/photoswipe.css @@ -0,0 +1,179 @@ +/*! PhotoSwipe main CSS by Dmitry Semenov | photoswipe.com | MIT license */ +/* + Styles for basic PhotoSwipe functionality (sliding area, open/close transitions) +*/ +/* pswp = photoswipe */ +.pswp { + display: none; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + overflow: hidden; + -ms-touch-action: none; + touch-action: none; + z-index: 1500; + -webkit-text-size-adjust: 100%; + /* create separate layer, to avoid paint on window.onscroll in webkit/blink */ + -webkit-backface-visibility: hidden; + outline: none; } + .pswp * { + -webkit-box-sizing: border-box; + box-sizing: border-box; } + .pswp img { + max-width: none; } + +/* style is added when JS option showHideOpacity is set to true */ +.pswp--animate_opacity { + /* 0.001, because opacity:0 doesn't trigger Paint action, which causes lag at start of transition */ + opacity: 0.001; + will-change: opacity; + /* for open/close transition */ + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp--open { + display: block; } + +.pswp--zoom-allowed .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; } + +.pswp--zoomed-in .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; } + +.pswp--dragging .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; } + +/* + Background is added as a separate element. + As animating opacity is much faster than animating rgba() background-color. +*/ +.pswp__bg { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: #000; + opacity: 0; + -webkit-transform: translateZ(0); + transform: translateZ(0); + -webkit-backface-visibility: hidden; + will-change: opacity; } + +.pswp__scroll-wrap { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: hidden; } + +.pswp__container, +.pswp__zoom-wrap { + -ms-touch-action: none; + touch-action: none; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; } + +/* Prevent selection and tap highlights */ +.pswp__container, +.pswp__img { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; } + +.pswp__zoom-wrap { + position: absolute; + width: 100%; + -webkit-transform-origin: left top; + -ms-transform-origin: left top; + transform-origin: left top; + /* for open/close transition */ + -webkit-transition: -webkit-transform 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: transform 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp__bg { + will-change: opacity; + /* for open/close transition */ + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp--animated-in .pswp__bg, +.pswp--animated-in .pswp__zoom-wrap { + -webkit-transition: none; + transition: none; } + +.pswp__container, +.pswp__zoom-wrap { + -webkit-backface-visibility: hidden; } + +.pswp__item { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow: hidden; } + +.pswp__img { + position: absolute; + width: auto; + height: auto; + top: 0; + left: 0; } + +/* + stretched thumbnail or div placeholder element (see below) + style is added to avoid flickering in webkit/blink when layers overlap +*/ +.pswp__img--placeholder { + -webkit-backface-visibility: hidden; } + +/* + div element that matches size of large image + large image loads on top of it +*/ +.pswp__img--placeholder--blank { + background: #222; } + +.pswp--ie .pswp__img { + width: 100% !important; + height: auto !important; + left: 0; + top: 0; } + +/* + Error message appears when image is not loaded + (JS option errorMsg controls markup) +*/ +.pswp__error-msg { + position: absolute; + left: 0; + top: 50%; + width: 100%; + text-align: center; + font-size: 14px; + line-height: 16px; + margin-top: -8px; + color: #CCC; } + +.pswp__error-msg a { + color: #CCC; + text-decoration: underline; } diff --git a/static/app/css/pj.css b/static/app/css/pj.css new file mode 100755 index 0000000..f712219 --- /dev/null +++ b/static/app/css/pj.css @@ -0,0 +1,126 @@ +body { + background: #ebebeb; +} + +.describe { + width: 100%; + height: 70.2px; + background: #fff; + border-bottom: 1px solid #e7e7e7; + border-top: 1px solid #e7e7e7; +} + +.des_img { + width: 51px; + height: 51px; + margin-left: 3%; + margin-top: 2%; + float: left; +} + +.des_img img { + width: 50px; + height: 50px; +} + +.describe p { + font-family: "微软雅黑"; + font-size: 13.2px; + float: left; + line-height: 70.2px; + margin-left: 5%; + color: #000000; + width: calc(100% - 100px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.row p { + font-family: "微软雅黑"; + font-size: 13.2px; + float: left; + line-height: 40px; + margin-left: 5%; + color: #000000; +} + + + +.star_a img { + width: 15px; + height: 13.8px; + float: left; + margin-top: 80%; +} + +.row { + width: 100%; + height: 40px; + background: #fff; + border-top: 1px solid transparent; +} + +.purchase { + width: 100%; + background: #fff; + border-top: 1px solid transparent; + padding: 0 5% 10px; +} + +.purchase textarea { + width: 100%; + height: 76.2px; + padding: 0; + font-family: "微软雅黑"; + font-size: 12px; + margin-top: 5px; + /*border: none;*/ +} + +.tijiao { + width: 90%; + background: #f02c43; + margin: 10px 5%; + text-align: center; + font-family: "微软雅黑"; + font-size: 15.6px; + color: #fff; + line-height: 40.8px; + border: none; +} +.star_a{ + float: left; + padding: 10px; + width: 40px; + height: 40px; + margin-left: 2%; +} +.star_off{ + width: 100%; + height: 100%; + background: url(../img/pjhx1.png)no-repeat center center; + background-size: 100%; +} +.star_on{ + width: 100%; + height: 100%; + background: url(../img/pjhx.png)no-repeat center center; + background-size: 100%; +} +.purchase_ p{ + padding:1% 0 5%; + font-size: 13.2px; + color: black; +} +.purchase_{ + background: white; + padding-bottom: 10px; + top: 1px solid transparent; + padding: 0 5% 10px; +} +.purchase_ img{ + width: 70px; + height: 70px; + padding: 5px; +} diff --git a/static/app/css/setting.css b/static/app/css/setting.css new file mode 100755 index 0000000..3592239 --- /dev/null +++ b/static/app/css/setting.css @@ -0,0 +1,107 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 50px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} + +.footer{ + position: fixed; + bottom: 0; + width: 100%; + background: white; + height: 49px; + border-top: 1px solid #e6e6e6; +} + +.z{ + width: 100%; + height: 66px; +} +.block{ + margin-top: 36px; + padding-left: 12px; + background: white; +} + +.row{ + background: white; + width: 100%; + height: 42px; + border-bottom: 1px solid #ebebeb; + position: relative; +} +.row:last-child{ + border-bottom: none; +} + + + +.row .img{ + width: 15.6px; + position: absolute; + top: 12px; + left: 2px; +} +.r1{ + font-size: 13.2px; + color: black; + line-height: 42px; + position: absolute; + left: 25px; +} +.r2{ + font-size: 12px; + color: #909090; + line-height: 42px; + position: absolute; + right: 25px; +} +.row img.youjiantou{ + width: 6px; + position: absolute; + right: 10px; + top: 15px; +} +.loginout{ + width: 100%; + height: 42px; + line-height: 42px; + text-align: center; + margin-top: 36px; + background: white; + color: #e51329; +} diff --git a/static/app/css/setting_address.css b/static/app/css/setting_address.css new file mode 100755 index 0000000..8fc13cd --- /dev/null +++ b/static/app/css/setting_address.css @@ -0,0 +1,86 @@ +.con .block{ + width: 100%; + height: 117px; + background: white; + border-bottom: 5px solid #ebebeb; + position: relative; +} +.pname{ + position: absolute; + font-size: 14.4px; + color: black; + left: 15px; + top: 15px; +} + +.pphone{ + position: absolute; + font-size: 14.4px; + color: black; + right: 15px; + top: 15px; +} +.paddress{ + position: absolute; + font-size: 10.8px; + color: black; + left: 15px; + top: 40px; +} +.block hr{ + position: absolute; + width: 100%; + top: 60px; + border: none; + border-top: 1px dotted #909090; +} +.btnout{ + width: 42px; + height: 42px; + position: absolute; + bottom: 0; + padding: 12px; + left: 5px; +} +.btn{ + width: 100%; + height: 100%; + border-radius: 50%; + border: 1px solid #909090; +} +.btnout .on{ + border: none; + background: #e7172f; +} +.block .p1{ + position: absolute; + font-size: 12px; + color: black; + left: 40px; + bottom: 0px; + height: 42px; + padding: 0; + line-height: 42px; +} +button{ + padding-left: 20px; + padding-right: 20px; + position: absolute; + bottom: 5px; +} +.bj{ + right: 100px; +} +.del{ + right: 15px; +} +.footer_btn{ + width: 100%; + height: 50px; + border: none; + position: fixed; + bottom: 0; + background: #E5122B; + color: white; + border-radius: 0; +} diff --git a/static/app/css/share.css b/static/app/css/share.css new file mode 100755 index 0000000..27406e8 --- /dev/null +++ b/static/app/css/share.css @@ -0,0 +1,24 @@ +.con{ + position: relative; +} +.con .bg{ + width: 100%; + display: block; +} +.con .img{ + position: absolute; + top: 74%; + width: 30%; + left: 50%; + transform: translateX(-50%); +} +.share{ + position: absolute; + right: 10px; + padding: 3px 8px; + top: 30px; + font-size: 12px; +} +.img img{ + width: 100%; +} diff --git a/static/app/css/share_user_list.css b/static/app/css/share_user_list.css new file mode 100755 index 0000000..c252e1d --- /dev/null +++ b/static/app/css/share_user_list.css @@ -0,0 +1,81 @@ +.scroll_out_{ + position: fixed; + top: 114px; + bottom: 0; + left: 0; + right: 0; +} + +.row{ + width: 100%; + background: white; + border-top: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; +} +.row_top{ + width: 100%; + height: 54px; + +} +.row_h_r{ + border-top: 1px solid #e6e6e6; + width: 100%; + height: 36px; +} + +.row_h_r p{ + line-height: 36px; + margin: 0; + text-align: center; +} + + +.row_top .img{ + padding: 9px; + width: 54px; + height: 54px; + border-radius: 50%; + overflow: hidden; + display: inline-block; + float: left; +} + +.row_top p{ + float: left; + line-height: 54px; + font-size: 14.4px; + color: #222222; +} +.row_top .btn{ + width: 17px; + height: 54px; + padding: 22px 0; + float: right; + display: inline-block; + margin-right: 12px; +} + +.ani{ + transform:rotate(180deg) +} +.nav{ + position: fixed; + top: 66px; + left: 0; + right: 0; + height: 48px; + background: white; +} +.nav .block{ + float: left; + width: 40%; + margin: 0 5%; + text-align: center; + line-height: 48px; + height: 48px; + font-size: 14.4px; +} +body .nav .on{ + border-bottom: 2px solid #fc2c43; + color: #f02a40; +} diff --git a/static/app/css/shoppingcart.css b/static/app/css/shoppingcart.css new file mode 100755 index 0000000..bba8c9f --- /dev/null +++ b/static/app/css/shoppingcart.css @@ -0,0 +1,352 @@ +.con {} + +.block { + padding: 0; + margin: 0; + background: white; + border-bottom: 9px solid #efeff4; +} + +.b_title { + width: 100%; + border-bottom: 1px solid #e6e6e6; +} + +.b_title .check1 { + padding: 9px 9px; + float: left; +} + +.check_0 { + width: 18px; + height: 18px; + border: 1px solid #8e8e8e; + border-radius: 50%; +} + +.check_1 { + width: 18px; + height: 18px; + border: 1px solid #ed253d; + border-radius: 50%; + background: #ed253d; +} + +.b_title .b_link { + float: left; + text-indent: 17; + font-size: 13.2px; +} + +.b_title .b_link a { + color: black; + line-height: 40px; + height: 36px; + display: inline-block; +} + +.b_title img { + height: 12px; + margin: 12px 6px; + float: left; +} + +.b_con { + height: 105px; +} + +.btn_bj { + display: block; + float: right; + color: black; + line-height: 36px; + font-size: 12px; + padding: 0 12px; +} + +.b_con .check2 { + padding: 43.5px 9px; + float: left; +} + +.s_img { + width: 93px; + height: 93px; + margin: 6px 0; + float: left; +} + +.b_con_r1 { + padding: 9px 12px; + float: left; + width: calc(100% - 129px); +} + +.p1 { + font-size: 12px; + margin: 0; + color: black; + max-height: 42px; + overflow: hidden; +} + +.p2 { + font-size: 10.8px; + margin: 0; + color: #909090; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bz { + font-size: 10.8px; +} + +.cost { + color: #e94744; +} + +.oldcost { + color: #909090; +} + +.num { + float: right; + color: black; + padding-right: 5px; +} + +.b_con_r2 { + float: left; + width: calc(100% - 129px); +} + +.b_con_r2_l { + float: left; + width: calc(100% - 51px); + height: 105px; + padding: 15px; +} + +.b_con_r2_del { + width: 51px; + height: 105px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + text-align: center; + line-height: 105px; + color: white; + float: right; + font-size: 12px; +} + +.js { + border-top: 1px solid #e6e6e6; + width: 100%; + height: 51px; + position: fixed; + bottom: 0; + left: 0; + z-index: 10; + background: white; + line-height: 53px; +} + +.js .check { + padding: 16.5px 9px; + float: left; +} + +.qx { + font-size: 14.4px; + margin: 0; + padding: 0; +} + +.js_r { + float: right; + position: absolute; + right: 0; + top: 0; +} + +.js_r span { + font-size: 12px; +} + +.js_r span j { + color: #e94744; +} + +.js_r span o { + color: #909090; +} + +.btn_tj { + display: inline-block; + width: 102px; + height: 51px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + text-align: center; + color: white; + font-size: 14.4px; +} + +.jian { + padding: 5px; + width: 22px; + height: 22px; + float: left; +} + +.changenum input { + float: left; + margin: 0; + padding: 0; + width: calc(100% - 84px); + text-align: center; + height: 22px; + border: none; + margin: 0 20px; +} + +.jia { + padding: 5px; + width: 22px; + height: 22px; + float: left; +} + +.changeclass { + margin-top: 18px; + font-size: 12px; + color: #909090; +} + +.changeclass img { + float: right; + height: 21px; + padding: 7.5px; + display: block; +} + +.cc1 { + width: 100%; + height: 27px; +} + +.cclass_con { + position: absolute; + bottom: 0; + left: 0; +} + +.cc2 { + width: 100%; + height: 81px; + background: white; + position: relative; + border-bottom: 1px solid #e3e6ea; +} + +.cc2 p { + font-size: 15.6px; + color: #e94744; + position: absolute; + left: 120px; + top: 24px; +} + +.cc2 span { + font-size: 12px; + position: absolute; + left: 120px; + top: 48px; +} + +.closecclass { + font-size: 15.6px; + color: #9b9b9b; + position: absolute; + padding: 9px 12px; + right: 0; + top: 0; +} + +.cclass_con .img { + background: white; + padding: 6px; + position: absolute; + border: 1px solid #f2f2f2; + border-radius: 6px; + width: 85.8px; + height: 85.8px; + top: 0; + left: 12px; + z-index: 60; +} + +.cclass_con .img img { + width: 100%; + height: 100%; + border-radius: 3px; +} + +.cclass1 { + padding: 18px 0 0 12px; + background: white; + border-bottom: 1px solid #e3e6ea; +} + +.cclass1 p { + color: #626262; + font-size: 13.2px; + padding-bottom: 18px; + margin: 0; +} + +.cclass1 .block { + padding: 3px 9px; + float: left; + border: 1px solid #9e9e9e; + margin: 0 18px 18px 0; + border-radius: 6px; + font-size: 14.4px; + color: #1d1d1d; +} + +.cclass1 .on { + border: 1px solid #e94947; +} + +.ensure { + width: 100%; + height: 48px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; +} \ No newline at end of file diff --git a/static/app/css/shopsList.css b/static/app/css/shopsList.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app/css/store_activity.css b/static/app/css/store_activity.css new file mode 100755 index 0000000..9cc860d --- /dev/null +++ b/static/app/css/store_activity.css @@ -0,0 +1,175 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .b_con img { + width: 120px; + height: 120px; + } + .p3{ + width: calc( 100% - 130px ) ; + } + .p4{ + left: 130px; + } + .b_con{ + height: 120px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .b_con img { + width: 110px; + height: 110px; + } + .p3{ + width: calc( 100% - 120px ) ; + } + .p4{ + left: 120px; + } + .b_con{ + height: 110px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .b_con img { + width: 100px; + height: 100px; + } + .p3{ + width: calc( 100% - 110px ) ; + } + .p4{ + left: 110px; + } + .b_con{ + height: 100px; + } +} + +.con { + border-top: 12px solid #ebebeb; +} + +.block { + padding: 12px 5% 0; + background: white; + border-bottom: 12px solid #ebebeb; +} + +.b_title { + position: relative; + height: 48px; +} + +.b_title .img { + width: 48px; + height: 48px; + position: absolute; +} + +.clock { + width: 13.2px; + position: absolute; + left: 54px; + top: 9px; +} + +.p1 { + position: absolute; + font-size: 14.4px; + left: 72px; + top: 6px; + color: black; +} + +.p2 { + color: #222222; + position: absolute; + font-size: 14.4px; + width: calc( 100% - 60px); + left: 54px; + bottom: 0; +} + +.b_con { + margin: 12px 0 ; + position: relative; +} +.p3{ + color: #909090; + font-size: 14.4px; + float: right; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} +.p4{ + color: #222222; + font-size: 15.6px; + position: absolute; + bottom: 0; +} +.b_footer { + width: 100%; + height: 36px; + position: relative; +} + +.num { + position: absolute; + width: 90px; + top: 7.5px; + left: 0; +} + +.num img { + width: 18px; + float: left; +} + +.nun p { + float: left; +} + +.zan { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #909090; + position: absolute; + background: url(../img/zan1.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #909090; + text-indent: 15px; + right: 0; + bottom: 8px; +} + +.zanon { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #e51329; + position: absolute; + background: url(../img/zan2.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #e51329; + text-indent: 15px; + right: 18px; + bottom: 8px; +} diff --git a/static/app/css/store_class.css b/static/app/css/store_class.css new file mode 100755 index 0000000..94093da --- /dev/null +++ b/static/app/css/store_class.css @@ -0,0 +1,17 @@ +.con{ + padding-top: 66px; +} +.row{ + width: 100%; + height: 42px; + line-height: 41px; + border-bottom: 1px solid #e6e6e6; + background: white; + font-size: 13.2px; + color: #525252; + padding-left: 12px; +} +.con .all{ + margin: 6px 0; + border: none; +} diff --git a/static/app/css/store_commodity.css b/static/app/css/store_commodity.css new file mode 100755 index 0000000..33c83fc --- /dev/null +++ b/static/app/css/store_commodity.css @@ -0,0 +1,29 @@ + +.commoditylistnav{ + width: 100%; + height: 45px; + background: white; +} +.nav_block{ + width: 25%; + float: left; + height: 45px; + line-height: 45px; + text-align: center; + color:#525252; + font-size: 12px; + +} +.commoditylistnav .on{ + color: #e51329; +} +#cost_btn{ + position: relative; +} +#cost_btn img{ + position: absolute; + width: 8px; + height: 12px; + top: 15px; + +} diff --git a/static/app/css/store_home.css b/static/app/css/store_home.css new file mode 100755 index 0000000..a5e97cf --- /dev/null +++ b/static/app/css/store_home.css @@ -0,0 +1,168 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .mui-slider { + height: 210px; + } + .mui-slider-item { + height: 210px; + } + .mui-slider .mui-slider-item img { + height: 210px; + width: 100%; + } + .con { + + } + .cnxh_block img { + max-width: 188px; + max-height: 188px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 188px; + width: 95%; + height: 66px; + margin: -5px auto 0; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .mui-slider { + height: 190px; + } + .mui-slider-item { + height: 190px; + } + .mui-slider .mui-slider-item img { + height: 190px; + width: 100%; + } + .cnxh_block img { + max-width: 168px; + max-height: 168px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 168px; + width: 95%; + height: 66px; + margin: -5px auto 0; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .mui-slider { + height: 162.5; + } + .mui-slider-item { + height: 162.5; + } + .mui-slider .mui-slider-item img { + height: 162.5; + width: 100%; + } + .cnxh_block img { + max-width: 144px; + width: 95%; + max-height: 144px; + } + .cnxh_block_info { + background: white; + max-width: 144px; + width: 95%; + height: 66px; + margin: -5px auto 0; + } +} + +.label { + padding: 6px 0; +} + +.l_block { + width: 25%; + border-right: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + background: white; + text-align: center; + height: 36px; + line-height: 36px; + color: #525252; + font-size: 12px; + float: left; +} + +.lbrr { + border-right: none; +} +.cnxh_con{ + padding: 2%; +} +.cnxh_block { + width: 50%; + text-align: center; + float: left; + background: #EFEFEF; + border-bottom: 6px solid #efefef; +} + +.s_name { + font-size: 13.2px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + margin: 0; +} + +.s_name o { + font-size: 10.8px; + background: #f02e45; + color: white; + padding: 2px; + border-radius: 3px; + margin-left: 2px; +} + +.cnxh_block_info { + text-align: left; + padding: 2px; + height: 95px; +} + +.cost { + margin: 0; + margin-top: 5px; + font-size: 13.2px; + color: #f45549; +} + +.cost del { + color: #8d8d8d; + font-size: 10.8px; +} +.cost o{ + color: white; + font-size: 10.8px; + background: #E5132C; + border-radius: 3px; + line-height: 10.8px; + padding-top: 1px; +} +.cost_info{ + color: #E51329; + font-size: 9.6px; + background: #dfc4c4; + line-height: 10px; + padding: 4px 3px 1px; + display: inline-block; +} \ No newline at end of file diff --git a/static/app/css/store_info.css b/static/app/css/store_info.css new file mode 100755 index 0000000..9c1f1ac --- /dev/null +++ b/static/app/css/store_info.css @@ -0,0 +1,16 @@ +.bg{ + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + background: transparent; +} +.con{ + width: 100%; + position: absolute; + left: 0; + right: 0; + bottom: 50px; + background: white; +} diff --git a/static/app/css/store_new.css b/static/app/css/store_new.css new file mode 100755 index 0000000..61dafff --- /dev/null +++ b/static/app/css/store_new.css @@ -0,0 +1,65 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .ct_con img { + height: 414px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .ct_con img { + height: 375px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .ct_con img { + height: 320px; + } +} + +.co_title { + width: 100%; + height: 24px; + padding: 0 5%; +} + +.co_title p { + width: 120px; + height: 24px; + line-height: 24px; + float: left; + font-size: 12px; + text-align: center; +} + +.hengxian { + width: calc(50% - 60px); + height: 1px; + border-top: 1px solid #909090; + float: left; + margin-top: 11px; +} + +.con .con_one .cnxh_con { + padding-top: 0; + padding-bottom: 0; +} + +.con .con_one .cnxh_con .cnxh_block { + border-bottom: 0; +} + +.ct_con { + background: white; +} + +.ct_con img { + width: 100%; +} diff --git a/static/app/css/storeout.css b/static/app/css/storeout.css new file mode 100755 index 0000000..53e9234 --- /dev/null +++ b/static/app/css/storeout.css @@ -0,0 +1,205 @@ +.header{ + background: url(../img/storetopbg.png) no-repeat center top; + background-size: 414px; +} +.search{ + width: 100%; + height: 60px; + padding-top: 20px; + +} +.mui-action-back{ + padding: 9px; + color: white; +} +.searchcon{ + margin-top: 5px; + width: calc(100% - 84px); + height: 30px; + float: left; + background: rgba(255,255,255,0.3); + position: relative; +} +.classmenu{ + width: 30px; + height: 30px; + float: left; + margin-top: 5px; + margin-left: 5px; +} +.searchcon img{ + width: 30px; + height: 30px; + padding: 7.5px; + float: left; +} +.searchcon span{ + color: white; + font-size: 13.2px; + line-height: 30px; +} +.b_title { + width: 100%; + position: relative; + height: 60px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.b_title .b_img { + width: 48px; + height: 48px; + position: absolute; + bottom: 6px; + left: 15px; +} + +.storename { + position: absolute; + width: calc(100% - 160px); + color: black; + left: 69px; + top: 9px; + font-size: 16.8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.time { + position: absolute; + width: calc(100% - 160px); + left: 69px; + color: #909090; + font-size: 13.2px; + top: 34px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.gz_btn{ + width: 69px; + height: 30px; + border-radius: 15px; + color: white; + line-height: 33.6px; + text-indent: 30px; + position:absolute; + right: 12px; + font-size: 13.2px; + background:#e5122b url(../img/heart.png) no-repeat left center; + background-size: 35px; + bottom: 15px; + /*border: 1px solid #909090;*/ +} +.gz_btn1{ + width: 69px; + height: 30px; + border-radius: 15px; + color: #909090; + line-height: 33.6px; + position:absolute; + text-align: center; + right: 12px; + font-size: 13.2px; + bottom: 15px; + background: #efefef; + /*border: 1px solid #909090;*/ +} +.nav{ + width: 100%; + height: 56px; + background: white; +} +.nav_block{ + float: left; + width: 25%; + text-align: center; + height: 56px; +} +.nav_block img{ + width: 36px; +} +.nav .on{ + border-bottom: 2px solid #e5122b; +} +.footer{ + width: 100%; + height: 50px; + border-top: 1px solid #e6e6e6; + position: fixed; + bottom: 0; + left: 0; + background: white; + padding: 12px 0; +} +.footer div{ + width: 50%; + height: 25px; + display: block; + float: left; + text-align: center; + color: #525252; + font-size: 15.6px; +} +#rmfl{ + border-right: 1px solid #e6e6e6; +} +.rmfl{ + width: 100%; + height: 100%; + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 101; +} +.rmfl .con{ + width: 96px; + border-radius: 6px; + overflow: hidden; + position: absolute; + bottom: 48px; + left: 20%; + box-shadow: 1px 1px 1px #eeeeee; + z-index: 110; +} +.rmfl .con .row{ + width: 100%; + height: 49px; + line-height: 48px; + border-top: 1px solid #e6e6e6; + background: white; + text-align: center; + color: #525252; + font-size: 14.4px; +} +.rmfl .con .row:first-child{ + border: none; +} +.sanjiao{ + z-index: 110; + width: 12px; + height: 12px; + position: absolute; + background: white; + border-right: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + transform: rotate(45deg); + bottom: 41px; + left: 24%; +} +.search button{ + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; +} diff --git a/static/app/css/swiper.min.css b/static/app/css/swiper.min.css new file mode 100755 index 0000000..b222bea --- /dev/null +++ b/static/app/css/swiper.min.css @@ -0,0 +1,15 @@ +/** + * Swiper 3.4.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2017, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: March 10, 2017 + */ +.swiper-container{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform,height}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s;-moz-transition:.3s;-o-transition:.3s;transition:.3s;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 5px}.swiper-pagination-progress{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progress .swiper-pagination-progressbar{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar{-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progress{width:100%;height:4px;left:0;top:0}.swiper-container-vertical>.swiper-pagination-progress{width:4px;height:100%;left:0;top:0}.swiper-pagination-progress.swiper-pagination-white{background:rgba(255,255,255,.5)}.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar{background:#fff}.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar{background:#000}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper,.swiper-container-flip .swiper-wrapper{-ms-perspective:1200px}.swiper-container-cube,.swiper-container-flip{overflow:visible}.swiper-container-cube .swiper-slide,.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-cube .swiper-slide .swiper-slide,.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active,.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top,.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-slide{visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-zoom-container{width:100%;height:100%;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-box-pack:center;-moz-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-moz-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/static/app/css/time_limit.css b/static/app/css/time_limit.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app/css/upload.css b/static/app/css/upload.css new file mode 100755 index 0000000..4447551 --- /dev/null +++ b/static/app/css/upload.css @@ -0,0 +1,69 @@ +.btn { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: 400; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + text-decoration: none; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} + +a.btn:hover { + background-color: #3366b7; +} + +.progress { + margin-top: 2px; + width: 60px; + height: 10px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} + +.progress-bar { + background-color: rgb(92, 184, 92); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%, transparent); + background-size: 40px 40px; + box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset; + box-sizing: border-box; + color: rgb(255, 255, 255); + display: block; + float: left; + font-size: 12px; + height: 20px; + line-height: 20px; + text-align: center; + transition-delay: 0s; + transition-duration: 0.6s; + transition-property: width; + transition-timing-function: ease; + width: 60px; +} + +.ossfile .files_out b img{ + width: 60px; + height: 60px; +} +.files_out{ + float: left; + padding: 5px; +} diff --git a/static/app/css/upload1.css b/static/app/css/upload1.css new file mode 100755 index 0000000..4447551 --- /dev/null +++ b/static/app/css/upload1.css @@ -0,0 +1,69 @@ +.btn { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: 400; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + text-decoration: none; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} + +a.btn:hover { + background-color: #3366b7; +} + +.progress { + margin-top: 2px; + width: 60px; + height: 10px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} + +.progress-bar { + background-color: rgb(92, 184, 92); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%, transparent); + background-size: 40px 40px; + box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset; + box-sizing: border-box; + color: rgb(255, 255, 255); + display: block; + float: left; + font-size: 12px; + height: 20px; + line-height: 20px; + text-align: center; + transition-delay: 0s; + transition-duration: 0.6s; + transition-property: width; + transition-timing-function: ease; + width: 60px; +} + +.ossfile .files_out b img{ + width: 60px; + height: 60px; +} +.files_out{ + float: left; + padding: 5px; +} diff --git a/static/app/img/1.png b/static/app/img/1.png new file mode 100755 index 0000000..950d16a Binary files /dev/null and b/static/app/img/1.png differ diff --git a/static/app/img/2.png b/static/app/img/2.png new file mode 100755 index 0000000..1518343 Binary files /dev/null and b/static/app/img/2.png differ diff --git a/static/app/img/3.8acbg.png b/static/app/img/3.8acbg.png new file mode 100755 index 0000000..2103144 Binary files /dev/null and b/static/app/img/3.8acbg.png differ diff --git a/static/app/img/3.png b/static/app/img/3.png new file mode 100755 index 0000000..29a169e Binary files /dev/null and b/static/app/img/3.png differ diff --git a/static/app/img/4.png b/static/app/img/4.png new file mode 100755 index 0000000..23979ab Binary files /dev/null and b/static/app/img/4.png differ diff --git a/static/app/img/5.png b/static/app/img/5.png new file mode 100755 index 0000000..cc7cc3a Binary files /dev/null and b/static/app/img/5.png differ diff --git a/static/app/img/ac1yhqbg1.png b/static/app/img/ac1yhqbg1.png new file mode 100755 index 0000000..6c5a715 Binary files /dev/null and b/static/app/img/ac1yhqbg1.png differ diff --git a/static/app/img/ac1yhqbg2.png b/static/app/img/ac1yhqbg2.png new file mode 100755 index 0000000..bb841b7 Binary files /dev/null and b/static/app/img/ac1yhqbg2.png differ diff --git a/static/app/img/ac1yhqbg3.png b/static/app/img/ac1yhqbg3.png new file mode 100755 index 0000000..abf6c75 Binary files /dev/null and b/static/app/img/ac1yhqbg3.png differ diff --git a/static/app/img/ac1yhqbg4.png b/static/app/img/ac1yhqbg4.png new file mode 100755 index 0000000..6a95f8c Binary files /dev/null and b/static/app/img/ac1yhqbg4.png differ diff --git a/static/app/img/ac2_ac3_bg.png b/static/app/img/ac2_ac3_bg.png new file mode 100755 index 0000000..0e364f9 Binary files /dev/null and b/static/app/img/ac2_ac3_bg.png differ diff --git a/static/app/img/ac2_bg1.png b/static/app/img/ac2_bg1.png new file mode 100755 index 0000000..d012f71 Binary files /dev/null and b/static/app/img/ac2_bg1.png differ diff --git a/static/app/img/ac2_footer.png b/static/app/img/ac2_footer.png new file mode 100755 index 0000000..86e287f Binary files /dev/null and b/static/app/img/ac2_footer.png differ diff --git a/static/app/img/ac2_sanjiao.png b/static/app/img/ac2_sanjiao.png new file mode 100755 index 0000000..96a74d3 Binary files /dev/null and b/static/app/img/ac2_sanjiao.png differ diff --git a/static/app/img/ac2_title_bg.png b/static/app/img/ac2_title_bg.png new file mode 100755 index 0000000..018c1e1 Binary files /dev/null and b/static/app/img/ac2_title_bg.png differ diff --git a/static/app/img/ac2_zdzb_bg.png b/static/app/img/ac2_zdzb_bg.png new file mode 100755 index 0000000..a81827d Binary files /dev/null and b/static/app/img/ac2_zdzb_bg.png differ diff --git a/static/app/img/ac2_zdzb_zzc.png b/static/app/img/ac2_zdzb_zzc.png new file mode 100755 index 0000000..b47cf2c Binary files /dev/null and b/static/app/img/ac2_zdzb_zzc.png differ diff --git a/static/app/img/ac2activity_bg.png b/static/app/img/ac2activity_bg.png new file mode 100755 index 0000000..6c9355f Binary files /dev/null and b/static/app/img/ac2activity_bg.png differ diff --git a/static/app/img/ac2yhqbg.png b/static/app/img/ac2yhqbg.png new file mode 100755 index 0000000..bfe2fdd Binary files /dev/null and b/static/app/img/ac2yhqbg.png differ diff --git a/static/app/img/ac3_bg.png b/static/app/img/ac3_bg.png new file mode 100755 index 0000000..c318d9c Binary files /dev/null and b/static/app/img/ac3_bg.png differ diff --git a/static/app/img/ac3_bg1.png b/static/app/img/ac3_bg1.png new file mode 100755 index 0000000..ea9479b Binary files /dev/null and b/static/app/img/ac3_bg1.png differ diff --git a/static/app/img/ac3_bg2.png b/static/app/img/ac3_bg2.png new file mode 100755 index 0000000..f2b4b22 Binary files /dev/null and b/static/app/img/ac3_bg2.png differ diff --git a/static/app/img/ac3_bg3.png b/static/app/img/ac3_bg3.png new file mode 100755 index 0000000..1f17abd Binary files /dev/null and b/static/app/img/ac3_bg3.png differ diff --git a/static/app/img/ac3_bg4.png b/static/app/img/ac3_bg4.png new file mode 100755 index 0000000..e992a60 Binary files /dev/null and b/static/app/img/ac3_bg4.png differ diff --git a/static/app/img/ac3_bg5.png b/static/app/img/ac3_bg5.png new file mode 100755 index 0000000..b16dca0 Binary files /dev/null and b/static/app/img/ac3_bg5.png differ diff --git a/static/app/img/ac3_button.png b/static/app/img/ac3_button.png new file mode 100755 index 0000000..d4aaffe Binary files /dev/null and b/static/app/img/ac3_button.png differ diff --git a/static/app/img/ac3_button1.png b/static/app/img/ac3_button1.png new file mode 100755 index 0000000..a0b49bb Binary files /dev/null and b/static/app/img/ac3_button1.png differ diff --git a/static/app/img/ac3_header_bg.png b/static/app/img/ac3_header_bg.png new file mode 100755 index 0000000..91a7179 Binary files /dev/null and b/static/app/img/ac3_header_bg.png differ diff --git a/static/app/img/ac3_title.png b/static/app/img/ac3_title.png new file mode 100755 index 0000000..c81d9c1 Binary files /dev/null and b/static/app/img/ac3_title.png differ diff --git a/static/app/img/ac3_title1.png b/static/app/img/ac3_title1.png new file mode 100755 index 0000000..0bae626 Binary files /dev/null and b/static/app/img/ac3_title1.png differ diff --git a/static/app/img/ac3_title2.png b/static/app/img/ac3_title2.png new file mode 100755 index 0000000..b48fbed Binary files /dev/null and b/static/app/img/ac3_title2.png differ diff --git a/static/app/img/ac3_title3.png b/static/app/img/ac3_title3.png new file mode 100755 index 0000000..6ae61aa Binary files /dev/null and b/static/app/img/ac3_title3.png differ diff --git a/static/app/img/ac5_bg1.png b/static/app/img/ac5_bg1.png new file mode 100755 index 0000000..f58024c Binary files /dev/null and b/static/app/img/ac5_bg1.png differ diff --git a/static/app/img/ac5_title.png b/static/app/img/ac5_title.png new file mode 100755 index 0000000..c008dff Binary files /dev/null and b/static/app/img/ac5_title.png differ diff --git a/static/app/img/activity1_head.png b/static/app/img/activity1_head.png new file mode 100755 index 0000000..e4a4b30 Binary files /dev/null and b/static/app/img/activity1_head.png differ diff --git a/static/app/img/activity2_head.png b/static/app/img/activity2_head.png new file mode 100755 index 0000000..c72f202 Binary files /dev/null and b/static/app/img/activity2_head.png differ diff --git a/static/app/img/aiguangjie.png b/static/app/img/aiguangjie.png new file mode 100755 index 0000000..74b8a25 Binary files /dev/null and b/static/app/img/aiguangjie.png differ diff --git a/static/app/img/bimaiqingdan.png b/static/app/img/bimaiqingdan.png new file mode 100755 index 0000000..02e255a Binary files /dev/null and b/static/app/img/bimaiqingdan.png differ diff --git a/static/app/img/bktj1.png b/static/app/img/bktj1.png new file mode 100755 index 0000000..d92cd1b Binary files /dev/null and b/static/app/img/bktj1.png differ diff --git a/static/app/img/bktj2.png b/static/app/img/bktj2.png new file mode 100755 index 0000000..36f6ca3 Binary files /dev/null and b/static/app/img/bktj2.png differ diff --git a/static/app/img/bktj3.png b/static/app/img/bktj3.png new file mode 100755 index 0000000..a305ea9 Binary files /dev/null and b/static/app/img/bktj3.png differ diff --git a/static/app/img/bktj4.png b/static/app/img/bktj4.png new file mode 100755 index 0000000..fe4e17e Binary files /dev/null and b/static/app/img/bktj4.png differ diff --git a/static/app/img/bktj_bg.png b/static/app/img/bktj_bg.png new file mode 100755 index 0000000..582a166 Binary files /dev/null and b/static/app/img/bktj_bg.png differ diff --git a/static/app/img/cainixihuan.png b/static/app/img/cainixihuan.png new file mode 100755 index 0000000..e9f38a6 Binary files /dev/null and b/static/app/img/cainixihuan.png differ diff --git a/static/app/img/chaoshihui.png b/static/app/img/chaoshihui.png new file mode 100755 index 0000000..a331dfe Binary files /dev/null and b/static/app/img/chaoshihui.png differ diff --git a/static/app/img/chaoshihui2.png b/static/app/img/chaoshihui2.png new file mode 100755 index 0000000..5ff44dd Binary files /dev/null and b/static/app/img/chaoshihui2.png differ diff --git a/static/app/img/classmenu.png b/static/app/img/classmenu.png new file mode 100755 index 0000000..89b1f97 Binary files /dev/null and b/static/app/img/classmenu.png differ diff --git a/static/app/img/close.png b/static/app/img/close.png new file mode 100755 index 0000000..5c61b74 Binary files /dev/null and b/static/app/img/close.png differ diff --git a/static/app/img/cost1.png b/static/app/img/cost1.png new file mode 100755 index 0000000..8fc371d Binary files /dev/null and b/static/app/img/cost1.png differ diff --git a/static/app/img/cost2.png b/static/app/img/cost2.png new file mode 100755 index 0000000..192996b Binary files /dev/null and b/static/app/img/cost2.png differ diff --git a/static/app/img/cost3.png b/static/app/img/cost3.png new file mode 100755 index 0000000..83cc78c Binary files /dev/null and b/static/app/img/cost3.png differ diff --git a/static/app/img/dingwei1.png b/static/app/img/dingwei1.png new file mode 100755 index 0000000..894467e Binary files /dev/null and b/static/app/img/dingwei1.png differ diff --git a/static/app/img/eye.png b/static/app/img/eye.png new file mode 100755 index 0000000..987793c Binary files /dev/null and b/static/app/img/eye.png differ diff --git a/static/app/img/faxianhaohuo1.png b/static/app/img/faxianhaohuo1.png new file mode 100755 index 0000000..19690cf Binary files /dev/null and b/static/app/img/faxianhaohuo1.png differ diff --git a/static/app/img/feichangdapai.png b/static/app/img/feichangdapai.png new file mode 100755 index 0000000..1a45688 Binary files /dev/null and b/static/app/img/feichangdapai.png differ diff --git a/static/app/img/fenlei.png b/static/app/img/fenlei.png new file mode 100755 index 0000000..71404b1 Binary files /dev/null and b/static/app/img/fenlei.png differ diff --git a/static/app/img/gouwuquan.png b/static/app/img/gouwuquan.png new file mode 100755 index 0000000..6e2308b Binary files /dev/null and b/static/app/img/gouwuquan.png differ diff --git a/static/app/img/guangshangchang.png b/static/app/img/guangshangchang.png new file mode 100755 index 0000000..f77d165 Binary files /dev/null and b/static/app/img/guangshangchang.png differ diff --git a/static/app/img/guangshangchang1.png b/static/app/img/guangshangchang1.png new file mode 100755 index 0000000..030115c Binary files /dev/null and b/static/app/img/guangshangchang1.png differ diff --git a/static/app/img/guochan_con_bg.png b/static/app/img/guochan_con_bg.png new file mode 100755 index 0000000..dc893ab Binary files /dev/null and b/static/app/img/guochan_con_bg.png differ diff --git a/static/app/img/guochanjingxuan.png b/static/app/img/guochanjingxuan.png new file mode 100755 index 0000000..9aa7c01 Binary files /dev/null and b/static/app/img/guochanjingxuan.png differ diff --git a/static/app/img/haitunlogo.png b/static/app/img/haitunlogo.png new file mode 100755 index 0000000..5f62490 Binary files /dev/null and b/static/app/img/haitunlogo.png differ diff --git a/static/app/img/heart.png b/static/app/img/heart.png new file mode 100755 index 0000000..e3f7502 Binary files /dev/null and b/static/app/img/heart.png differ diff --git a/static/app/img/home.png b/static/app/img/home.png new file mode 100755 index 0000000..9b11de0 Binary files /dev/null and b/static/app/img/home.png differ diff --git a/static/app/img/home2.png b/static/app/img/home2.png new file mode 100755 index 0000000..695aff9 Binary files /dev/null and b/static/app/img/home2.png differ diff --git a/static/app/img/hot.png b/static/app/img/hot.png new file mode 100755 index 0000000..aef2e3d Binary files /dev/null and b/static/app/img/hot.png differ diff --git a/static/app/img/hot2.png b/static/app/img/hot2.png new file mode 100755 index 0000000..326afa8 Binary files /dev/null and b/static/app/img/hot2.png differ diff --git a/static/app/img/hui.png b/static/app/img/hui.png new file mode 100755 index 0000000..8de74a5 Binary files /dev/null and b/static/app/img/hui.png differ diff --git a/static/app/img/huigou.png b/static/app/img/huigou.png new file mode 100755 index 0000000..f822a64 Binary files /dev/null and b/static/app/img/huigou.png differ diff --git a/static/app/img/huiyuankuaibao.png b/static/app/img/huiyuankuaibao.png new file mode 100755 index 0000000..272cdab Binary files /dev/null and b/static/app/img/huiyuankuaibao.png differ diff --git a/static/app/img/huiyuankuangbao.png b/static/app/img/huiyuankuangbao.png new file mode 100755 index 0000000..98d910b Binary files /dev/null and b/static/app/img/huiyuankuangbao.png differ diff --git a/static/app/img/huiyuanmiaosha.png b/static/app/img/huiyuanmiaosha.png new file mode 100755 index 0000000..cef11ea Binary files /dev/null and b/static/app/img/huiyuanmiaosha.png differ diff --git a/static/app/img/huiyuanzhuanhui1.png b/static/app/img/huiyuanzhuanhui1.png new file mode 100755 index 0000000..a149d53 Binary files /dev/null and b/static/app/img/huiyuanzhuanhui1.png differ diff --git a/static/app/img/hyhflfs.png b/static/app/img/hyhflfs.png new file mode 100755 index 0000000..b97a7f4 Binary files /dev/null and b/static/app/img/hyhflfs.png differ diff --git a/static/app/img/hyz_bg.png b/static/app/img/hyz_bg.png new file mode 100755 index 0000000..4bcebce Binary files /dev/null and b/static/app/img/hyz_bg.png differ diff --git a/static/app/img/icon_back.png b/static/app/img/icon_back.png new file mode 100755 index 0000000..18543c8 Binary files /dev/null and b/static/app/img/icon_back.png differ diff --git a/static/app/img/icon_clock.png b/static/app/img/icon_clock.png new file mode 100755 index 0000000..8233151 Binary files /dev/null and b/static/app/img/icon_clock.png differ diff --git a/static/app/img/icon_down.png b/static/app/img/icon_down.png new file mode 100755 index 0000000..d1c62f7 Binary files /dev/null and b/static/app/img/icon_down.png differ diff --git a/static/app/img/icon_menu.png b/static/app/img/icon_menu.png new file mode 100755 index 0000000..ebb7e71 Binary files /dev/null and b/static/app/img/icon_menu.png differ diff --git a/static/app/img/icon_phone1.png b/static/app/img/icon_phone1.png new file mode 100755 index 0000000..d35ffdc Binary files /dev/null and b/static/app/img/icon_phone1.png differ diff --git a/static/app/img/icon_pwd1.png b/static/app/img/icon_pwd1.png new file mode 100755 index 0000000..e9cc9f3 Binary files /dev/null and b/static/app/img/icon_pwd1.png differ diff --git a/static/app/img/icon_right.png b/static/app/img/icon_right.png new file mode 100755 index 0000000..6967dfb Binary files /dev/null and b/static/app/img/icon_right.png differ diff --git a/static/app/img/icon_s.png b/static/app/img/icon_s.png new file mode 100755 index 0000000..1ba8288 Binary files /dev/null and b/static/app/img/icon_s.png differ diff --git a/static/app/img/icon_select.png b/static/app/img/icon_select.png new file mode 100755 index 0000000..fce1a0d Binary files /dev/null and b/static/app/img/icon_select.png differ diff --git a/static/app/img/icon_select1.png b/static/app/img/icon_select1.png new file mode 100755 index 0000000..a2c32eb Binary files /dev/null and b/static/app/img/icon_select1.png differ diff --git a/static/app/img/icon_shop.png b/static/app/img/icon_shop.png new file mode 100755 index 0000000..f5212f2 Binary files /dev/null and b/static/app/img/icon_shop.png differ diff --git a/static/app/img/icon_user1.png b/static/app/img/icon_user1.png new file mode 100755 index 0000000..96904f8 Binary files /dev/null and b/static/app/img/icon_user1.png differ diff --git a/static/app/img/imail.png b/static/app/img/imail.png new file mode 100755 index 0000000..b48b215 Binary files /dev/null and b/static/app/img/imail.png differ diff --git a/static/app/img/imail2.png b/static/app/img/imail2.png new file mode 100755 index 0000000..890e860 Binary files /dev/null and b/static/app/img/imail2.png differ diff --git a/static/app/img/jia.png b/static/app/img/jia.png new file mode 100755 index 0000000..d3e7f88 Binary files /dev/null and b/static/app/img/jia.png differ diff --git a/static/app/img/jian.png b/static/app/img/jian.png new file mode 100755 index 0000000..978f9e1 Binary files /dev/null and b/static/app/img/jian.png differ diff --git a/static/app/img/jifen.png b/static/app/img/jifen.png new file mode 100755 index 0000000..db88270 Binary files /dev/null and b/static/app/img/jifen.png differ diff --git a/static/app/img/jingpintuijian.png b/static/app/img/jingpintuijian.png new file mode 100755 index 0000000..ba069ca Binary files /dev/null and b/static/app/img/jingpintuijian.png differ diff --git a/static/app/img/jxyh.png b/static/app/img/jxyh.png new file mode 100755 index 0000000..df0e2da Binary files /dev/null and b/static/app/img/jxyh.png differ diff --git a/static/app/img/likelogo.png b/static/app/img/likelogo.png new file mode 100755 index 0000000..7b92f60 Binary files /dev/null and b/static/app/img/likelogo.png differ diff --git a/static/app/img/likelogo1.png b/static/app/img/likelogo1.png new file mode 100755 index 0000000..4ec90cd Binary files /dev/null and b/static/app/img/likelogo1.png differ diff --git a/static/app/img/likelogoon.png b/static/app/img/likelogoon.png new file mode 100755 index 0000000..23a351e Binary files /dev/null and b/static/app/img/likelogoon.png differ diff --git a/static/app/img/ljjg_bg.png b/static/app/img/ljjg_bg.png new file mode 100755 index 0000000..70c68b0 Binary files /dev/null and b/static/app/img/ljjg_bg.png differ diff --git a/static/app/img/me.png b/static/app/img/me.png new file mode 100755 index 0000000..3aa51f5 Binary files /dev/null and b/static/app/img/me.png differ diff --git a/static/app/img/me2.png b/static/app/img/me2.png new file mode 100755 index 0000000..e843967 Binary files /dev/null and b/static/app/img/me2.png differ diff --git a/static/app/img/meirigengxin.png b/static/app/img/meirigengxin.png new file mode 100755 index 0000000..ad6093a Binary files /dev/null and b/static/app/img/meirigengxin.png differ diff --git a/static/app/img/menu.png b/static/app/img/menu.png new file mode 100755 index 0000000..c2fdad5 Binary files /dev/null and b/static/app/img/menu.png differ diff --git a/static/app/img/menu_dian.png b/static/app/img/menu_dian.png new file mode 100755 index 0000000..d5b22cb Binary files /dev/null and b/static/app/img/menu_dian.png differ diff --git a/static/app/img/miaoshabg.png b/static/app/img/miaoshabg.png new file mode 100755 index 0000000..9cbbc67 Binary files /dev/null and b/static/app/img/miaoshabg.png differ diff --git a/static/app/img/my_bg.png b/static/app/img/my_bg.png new file mode 100755 index 0000000..b295676 Binary files /dev/null and b/static/app/img/my_bg.png differ diff --git a/static/app/img/order-icons.png b/static/app/img/order-icons.png new file mode 100755 index 0000000..6c083df Binary files /dev/null and b/static/app/img/order-icons.png differ diff --git a/static/app/img/paihangbang.png b/static/app/img/paihangbang.png new file mode 100755 index 0000000..30b6be5 Binary files /dev/null and b/static/app/img/paihangbang.png differ diff --git a/static/app/img/phone1.png b/static/app/img/phone1.png new file mode 100755 index 0000000..66bf91e Binary files /dev/null and b/static/app/img/phone1.png differ diff --git a/static/app/img/pingpaijie.png b/static/app/img/pingpaijie.png new file mode 100755 index 0000000..332b37f Binary files /dev/null and b/static/app/img/pingpaijie.png differ diff --git a/static/app/img/pinzhishishang.png b/static/app/img/pinzhishishang.png new file mode 100755 index 0000000..f2013d1 Binary files /dev/null and b/static/app/img/pinzhishishang.png differ diff --git a/static/app/img/pjhx.png b/static/app/img/pjhx.png new file mode 100755 index 0000000..77b8f7c Binary files /dev/null and b/static/app/img/pjhx.png differ diff --git a/static/app/img/pjhx1.png b/static/app/img/pjhx1.png new file mode 100755 index 0000000..0e88ee8 Binary files /dev/null and b/static/app/img/pjhx1.png differ diff --git a/static/app/img/pjimg.png b/static/app/img/pjimg.png new file mode 100755 index 0000000..2c322cf Binary files /dev/null and b/static/app/img/pjimg.png differ diff --git a/static/app/img/sanjiaoshang.png b/static/app/img/sanjiaoshang.png new file mode 100755 index 0000000..4a2fd37 Binary files /dev/null and b/static/app/img/sanjiaoshang.png differ diff --git a/static/app/img/sanjiaoxia.png b/static/app/img/sanjiaoxia.png new file mode 100755 index 0000000..72b9284 Binary files /dev/null and b/static/app/img/sanjiaoxia.png differ diff --git a/static/app/img/saoyisao.png b/static/app/img/saoyisao.png new file mode 100755 index 0000000..c14f6da Binary files /dev/null and b/static/app/img/saoyisao.png differ diff --git a/static/app/img/search1.png b/static/app/img/search1.png new file mode 100755 index 0000000..ef4f42c Binary files /dev/null and b/static/app/img/search1.png differ diff --git a/static/app/img/setting_lock1.png b/static/app/img/setting_lock1.png new file mode 100755 index 0000000..d8bd133 Binary files /dev/null and b/static/app/img/setting_lock1.png differ diff --git a/static/app/img/setting_user1.png b/static/app/img/setting_user1.png new file mode 100755 index 0000000..3b993b2 Binary files /dev/null and b/static/app/img/setting_user1.png differ diff --git a/static/app/img/shan.png b/static/app/img/shan.png new file mode 100755 index 0000000..e9d44c5 Binary files /dev/null and b/static/app/img/shan.png differ diff --git a/static/app/img/shan1.png b/static/app/img/shan1.png new file mode 100755 index 0000000..6bb2885 Binary files /dev/null and b/static/app/img/shan1.png differ diff --git a/static/app/img/shangxin.png b/static/app/img/shangxin.png new file mode 100755 index 0000000..3235ea8 Binary files /dev/null and b/static/app/img/shangxin.png differ diff --git a/static/app/img/shaung11jianianhua.png b/static/app/img/shaung11jianianhua.png new file mode 100755 index 0000000..0ae84f6 Binary files /dev/null and b/static/app/img/shaung11jianianhua.png differ diff --git a/static/app/img/shop.png b/static/app/img/shop.png new file mode 100755 index 0000000..b8d2015 Binary files /dev/null and b/static/app/img/shop.png differ diff --git a/static/app/img/shop2.png b/static/app/img/shop2.png new file mode 100755 index 0000000..07a23dc Binary files /dev/null and b/static/app/img/shop2.png differ diff --git a/static/app/img/shoplogo.png b/static/app/img/shoplogo.png new file mode 100755 index 0000000..f2bfc4a Binary files /dev/null and b/static/app/img/shoplogo.png differ diff --git a/static/app/img/sousuo.png b/static/app/img/sousuo.png new file mode 100755 index 0000000..873650f Binary files /dev/null and b/static/app/img/sousuo.png differ diff --git a/static/app/img/store_home.png b/static/app/img/store_home.png new file mode 100755 index 0000000..692a96a Binary files /dev/null and b/static/app/img/store_home.png differ diff --git a/static/app/img/store_home_on.png b/static/app/img/store_home_on.png new file mode 100755 index 0000000..a4ac550 Binary files /dev/null and b/static/app/img/store_home_on.png differ diff --git a/static/app/img/store_huodong.png b/static/app/img/store_huodong.png new file mode 100755 index 0000000..274171c Binary files /dev/null and b/static/app/img/store_huodong.png differ diff --git a/static/app/img/store_huodong_on.png b/static/app/img/store_huodong_on.png new file mode 100755 index 0000000..7b12569 Binary files /dev/null and b/static/app/img/store_huodong_on.png differ diff --git a/static/app/img/store_shangpin.png b/static/app/img/store_shangpin.png new file mode 100755 index 0000000..d381997 Binary files /dev/null and b/static/app/img/store_shangpin.png differ diff --git a/static/app/img/store_shangpin_on.png b/static/app/img/store_shangpin_on.png new file mode 100755 index 0000000..1238fc6 Binary files /dev/null and b/static/app/img/store_shangpin_on.png differ diff --git a/static/app/img/store_shangxin.png b/static/app/img/store_shangxin.png new file mode 100755 index 0000000..9f36adc Binary files /dev/null and b/static/app/img/store_shangxin.png differ diff --git a/static/app/img/store_shangxin_on.png b/static/app/img/store_shangxin_on.png new file mode 100755 index 0000000..e36a53a Binary files /dev/null and b/static/app/img/store_shangxin_on.png differ diff --git a/static/app/img/storetopbg.png b/static/app/img/storetopbg.png new file mode 100755 index 0000000..cd40dfb Binary files /dev/null and b/static/app/img/storetopbg.png differ diff --git a/static/app/img/thq_bg.png b/static/app/img/thq_bg.png new file mode 100755 index 0000000..8afde13 Binary files /dev/null and b/static/app/img/thq_bg.png differ diff --git a/static/app/img/time_limit.png b/static/app/img/time_limit.png new file mode 100755 index 0000000..3e03d02 Binary files /dev/null and b/static/app/img/time_limit.png differ diff --git a/static/app/img/tuijianbaokuan1.png b/static/app/img/tuijianbaokuan1.png new file mode 100755 index 0000000..31e4c08 Binary files /dev/null and b/static/app/img/tuijianbaokuan1.png differ diff --git a/static/app/img/xianshiqianggou.png b/static/app/img/xianshiqianggou.png new file mode 100755 index 0000000..a54828e Binary files /dev/null and b/static/app/img/xianshiqianggou.png differ diff --git a/static/app/img/xianshitehui.png b/static/app/img/xianshitehui.png new file mode 100755 index 0000000..77bbf58 Binary files /dev/null and b/static/app/img/xianshitehui.png differ diff --git a/static/app/img/xinpinshangshi1.png b/static/app/img/xinpinshangshi1.png new file mode 100755 index 0000000..d7f5e62 Binary files /dev/null and b/static/app/img/xinpinshangshi1.png differ diff --git a/static/app/img/xinpinshoufa.png b/static/app/img/xinpinshoufa.png new file mode 100755 index 0000000..c9e087f Binary files /dev/null and b/static/app/img/xinpinshoufa.png differ diff --git a/static/app/img/xpss_bg.png b/static/app/img/xpss_bg.png new file mode 100755 index 0000000..5125ee7 Binary files /dev/null and b/static/app/img/xpss_bg.png differ diff --git a/static/app/img/youhaohuo.png b/static/app/img/youhaohuo.png new file mode 100755 index 0000000..86fe591 Binary files /dev/null and b/static/app/img/youhaohuo.png differ diff --git a/static/app/img/youhuiquan1.png b/static/app/img/youhuiquan1.png new file mode 100755 index 0000000..4f39a18 Binary files /dev/null and b/static/app/img/youhuiquan1.png differ diff --git a/static/app/img/youhuiquan2.png b/static/app/img/youhuiquan2.png new file mode 100755 index 0000000..50c6be2 Binary files /dev/null and b/static/app/img/youhuiquan2.png differ diff --git a/static/app/img/youjiantou.png b/static/app/img/youjiantou.png new file mode 100755 index 0000000..1976dc6 Binary files /dev/null and b/static/app/img/youjiantou.png differ diff --git a/static/app/img/yuan.png b/static/app/img/yuan.png new file mode 100755 index 0000000..1c7423f Binary files /dev/null and b/static/app/img/yuan.png differ diff --git a/static/app/img/zan1.png b/static/app/img/zan1.png new file mode 100755 index 0000000..54ed64e Binary files /dev/null and b/static/app/img/zan1.png differ diff --git a/static/app/img/zan2.png b/static/app/img/zan2.png new file mode 100755 index 0000000..a58019d Binary files /dev/null and b/static/app/img/zan2.png differ diff --git a/static/app/img/zdzb2_bg.png b/static/app/img/zdzb2_bg.png new file mode 100755 index 0000000..c3e1053 Binary files /dev/null and b/static/app/img/zdzb2_bg.png differ diff --git a/static/app/js/activity1.js b/static/app/js/activity1.js new file mode 100755 index 0000000..31deea1 --- /dev/null +++ b/static/app/js/activity1.js @@ -0,0 +1,106 @@ +mui.plusReady(function() { + $('#bg').html('<img src="../img/activity1_head.png" />'); + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + data: { + typeSrc: 2 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + $.each(data['6'].list, function(num) { + num++; + if(num % 2 == 1) { + html1 += '<div class="bktj_b" data-goodsId="' + this.goodsId + '"><img src="../img/bktj' + num + '.png" /><div class="bktj_con clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="bktj_con_con"><p class="p3">' + this.goodsName + '</p><p class="p4">折扣到手价</p><p class="p3">¥.' + this.shopPrice + '</p><div class="ljjg_btn ljqg_btn">立即抢购</div></div></div></div>'; + } else { + html1 += '<div class="bktj_b" data-goodsId="' + this.goodsId + '"><img src="../img/bktj' + num + '.png" /><div class="bktj_con clearfix"><div class="bktj_con_con"><p class="p3">' + this.goodsName + '</p><p class="p4">折扣到手价</p><p class="p3">¥.' + this.shopPrice + '</p><div class="ljjg_btn ljqg_btn">立即抢购</div></div><img src="' + hyhImgUrl(this.goodsImg) + '" /></div></div>'; + } + + }); + $('.bktj').html(html1); + $.each(data['7'].list, function() { + html2 += '<div class="xpss_b" data-goodsId="' + this.goodsId + '"><img src="../img/xpss_bg.png" /><div class="xpss_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p5"><del>原价' + this.marketPrice + '</del>' + this.marketPrice + '</p><div class="xpss_ljqg_btn">立即抢购</div></div></div>' + }); + + $('.xpss').html(html2); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.bktj').on('tap', '.bktj_b', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.xpss').on('tap', '.xpss_b', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/activity10.js b/static/app/js/activity10.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/activity2.js b/static/app/js/activity2.js new file mode 100755 index 0000000..c08b0ef --- /dev/null +++ b/static/app/js/activity2.js @@ -0,0 +1,145 @@ +$('.title p').html(''); +mui.plusReady(function() { + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + data: { + typeSrc: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + var html3 = ''; + + $.each(data['1'].list, function() { + html1 += '<div class="gchh_block" data-goodsId="' + this.goodsId + '"><img class="gchh_b_bg" src="../img/guochan_con_bg.png" /><div class="gchh_b_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div></div>' + }); + $('.gchh').html(html1); + $('.title').eq(0).children('p').html(data['title_1'].name); + $.each(data['2'].list, function() { + html2 += '<div class="zdzb_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_zdzb_bg.png" /><div class="zdzb_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>' + this.goodsName + '</p><b>¥</b><span class="cost">' + this.shopPrice + '</span><div class="zdzb_btn">立即购买</div></div><img class="zdzb_zzc" src="../img/ac2_zdzb_zzc.png" /></div>' + }); + $('.zdzb').html(html2); + $('.title').eq(1).children('p').html(data['title_2'].name); + + $.each(data['3'].list, function() { + html3 += '<div class="zdzb3_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_ac3_bg.png" /><div class="zdzb3_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>RMB ' + this.shopPrice + '</p><img class="sanjiao" src="../img/ac2_sanjiao.png" /></div></div>'; + }); + $('.zdzb3').html(html3) + $('.title').eq(2).children('p').html(data['title_3'].name); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.gchh').on('tap', '.gchh_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb').on('tap', '.zdzb_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb3').on('tap', '.zdzb3_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/activity3.js b/static/app/js/activity3.js new file mode 100755 index 0000000..d03c2bc --- /dev/null +++ b/static/app/js/activity3.js @@ -0,0 +1,164 @@ +$('.jggcj').css('display','none'); +$('.time').css('display','none'); +$('.title').eq(0).css('display','none'); +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + + data: { + typeSrc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + + $.each(data['4'].list, function() { + html1 += '<div class="list_block" data-goodsId="' + this.goodsId + '"><img class="list_block_bg" src="../img/ac3_bg5.png" /><div class="list_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + '</p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + }); + $('#list1').html(html1); + $.each(data['5'].list, function() { + html2 += '<div class="list_block" data-goodsId="' + this.goodsId + '"><img class="list_block_bg" src="../img/ac3_bg5.png" /><div class="list_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + '</p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + }); + $('#list2').html(html2); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + mui.ajax(hyhUrl('addon/hyhlucky-Hyhlucky-getLuckyPrize'), {  + data: { + draw_id: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html = '<div class="content content-1" data-id="' + data.prize_list[0].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[0].prize_img) + '" /></div></div><div class="content content-2" data-id="' + data.prize_list[1].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[1].prize_img) + '" /></div></div><div class="content content-3" data-id="' + data.prize_list[2].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[2].prize_img) + '" /></div></div><div class="content content-8" data-id="' + data.prize_list[7].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[7].prize_img) + '" /></div></div><div class="content content-click"><div id="text"><img src="../img/ac3_button1.png" /></div></div><div class="content content-4" data-id="' + data.prize_list[3].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[3].prize_img) + '" /></div></div><div class="content content-7" data-id="' + data.prize_list[6].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[6].prize_img) + '" /></div></div><div class="content content-6" data-id="' + data.prize_list[5].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[5].prize_img) + '" /></div></div><div class="content content-5" data-id="' + data.prize_list[4].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[4].prize_img) + '" /></div></div>' + + $('.cj_con').html(html); + $('.num .number').html(data.max_num) + + $('.content').height($('.content').width() * 123 / 165 + 'px') + $(window).resize(function() { + $('.content').height($('.content').width() + 'px') + }) + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + // $('.content').height($('.content').width() * 123 / 165 + 'px') + // $(window).resize(function() { + // $('.content').height($('.content').width() + 'px') + // }) + + function time(a) { + return function() { + if(a > 8) { + a = parseInt(a % 8) + if(a == 0) { + a = 8; + } + } + $('.content').removeClass('active'); + $('.content-' + a).addClass('active'); + $('.zz_img').toggleClass('on'); + } + } + // 在旋转的时候不能再次被点击 + var t = true + $('.cj_con').on('tap', '.content-click', function() { + console.log(token) + if(t) { + t = false; + // 产生随机数 + var prize; + var msg = ''; + mui.ajax(hyhUrl('addon/hyhlucky-Hyhlucky-luckyDraw'), { + headers: {  + "HYH-Token": token + }, + data: { + draw_id: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + console.log(data.msg) + if(data.status == 1) { + if($('.number').html() > 0) { + data = data.data; + prize = data.v; + msg = data.yes; + + $('.number').html($('.number').html() - 1) + // 默认先转3圈 + prize += 32 + for(var i = 1; i <= prize; i++) { + setTimeout(time(i), 6 * i * i); + } + setTimeout(function() { + t = true; + alert(msg); + }, 6 * prize * prize) + } else { + alert('您没有抽奖机会了'); + } + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + } + }) + //跳商品页面 + $('.list').on('tap', '.list_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/activity4.js b/static/app/js/activity4.js new file mode 100755 index 0000000..86c2379 --- /dev/null +++ b/static/app/js/activity4.js @@ -0,0 +1,186 @@ +var scroll = mui('.con').scroll(); +mui.plusReady(function() { + var autoCatId; + var num = 1; + var isOver = 1; + mui.ajax(hyhUrl('addon/hyhbrandsrec-hyhBrandsrec-getBrandList'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + var html1 = ''; + $.each(data.brandlist_rec, function() { + html += '<div class="scroll_top_block" data-brandId="' + this.brandId + '"><img src="' + chengUrl(this.brandImg) + '" /><p>' + this.brandName + '</p></div>'; + }); + autoCatId = data.brand_list[0].catId; + $.each(data.brand_list, function() { + html1 += '<a class="mui-control-item" data-catId="' + this.catId + '">' + this.catName + '</a>'; + }); + $('.scroll_top').html(html); + $('.nav').html(html1); + document.getElementsByClassName('mui-control-item')[0].classList.add('mui-active') + $('.scroll_top_block').height($('.scroll_top_block').width()); + $('.scroll_top_block img').height($('.scroll_top_block img').width()); + getData(autoCatId, 6, 1); + + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + function getData(catIdNum, pageSizeNum, pageNum) { + if(isOver == 1) { + isOver = 0; + } else { + return; + } + + var autoData = { + catId: catIdNum, + pageSize: pageSizeNum ? pageSizeNum : 6, + page: pageNum ? pageNum : 1 + } + mui.ajax(chengUrl('addon/hyhbrandsrec-hyhBrandsrec-getBrandCatList'), {  + data: autoData, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.Rows == '' && pageNum > 1) { + $('.scroll_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + + return; + } else if(data.Rows == '') { + $('.scroll_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;margin-top:20px;">没有商品</p>'); + return; + } + + $.each(data.Rows, function() { + html += '<div class="scroll_con_block" id="' + num + '"><div class="scb_title" data-shopId="' + this.shopId + '"><img src="' + chengUrl(this.shopImg) + '" /><p>' + this.shopName + '</p><span class="s1">官方旗舰店</span><span class="s2">进店看看</span></div><div class="scroll_con_con clearfix">'; + + $.each(this.list, function() { + html += '<div class="scc_block" data-goodsId="' + this.goodsId + '"><img src="' + this.goodsImg + '" /><p>' + this.goodsName + '</p><span>¥' + this.shopPrice + '</span></div>' + }); + + html += '</div></div>' + + }); + if(pageNum == 1) { + $('.scroll_con').html(html); + } else { + $('.scroll_con').append(html); + } + + $('.scc_block img').height($('.scc_block img').width()); + + isOver = 1; + + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + document.querySelector('.con').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num += 1; + getData(autoCatId, 6, num); + } + } + }) + mui('.nav').on('tap', '.mui-control-item', function() { + autoCatId = $(this).attr('data-catId'); + num = 1; + isOver = 1; + getData(autoCatId, 6, num); + }) + //跳商店页面 + $('.con').on('tap', '.scb_title', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html'+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.con').on('tap', '.scc_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/activity5.js b/static/app/js/activity5.js new file mode 100755 index 0000000..76f10f8 --- /dev/null +++ b/static/app/js/activity5.js @@ -0,0 +1,11 @@ +mui.init() + mui('.con').scroll({ + deceleration: 0.0005 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + }); + var slider = mui("#slider"); + slider.slider({ + interval: 5000 + }); + + $('.con_o .img').height($('.con_o .img').width()) + $('.con_t_block img').height($('.con_t_block img').width()) \ No newline at end of file diff --git a/static/app/js/activity6.js b/static/app/js/activity6.js new file mode 100755 index 0000000..88a3c53 --- /dev/null +++ b/static/app/js/activity6.js @@ -0,0 +1,143 @@ +mui.plusReady(function() { + mui.ajax(chengUrl('addon/hyhactive-Hyhactive-getGoodsList'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + var html3 = ''; + + $.each(data[0].goodsInfo, function() { + html1 += '<div class="gchh_block" data-goodsId="' + this.goodsId + '"><img class="gchh_b_bg" src="../img/guochan_con_bg.png" /><div class="gchh_b_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div></div>' + }); + $('#tt1 p').html(data[0].activeTypeName); + $('.gchh').html(html1); + + $.each(data[1].goodsInfo, function() { + html2 += '<div class="zdzb_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_zdzb_bg.png" /><div class="zdzb_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>' + this.goodsName + '</p><b>¥</b><span class="cost">' + this.shopPrice + '</span><div class="zdzb_btn">立即购买</div></div><img class="zdzb_zzc" src="../img/ac2_zdzb_zzc.png" /></div>' + }); + $('#tt2 p').html(data[1].activeTypeName); + $('.zdzb').html(html2); + + $.each(data[2].goodsInfo, function() { + html3 += '<div class="zdzb3_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_ac3_bg.png" /><div class="zdzb3_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>RMB ' + this.shopPrice + '</p><img class="sanjiao" src="../img/ac2_sanjiao.png" /></div></div>'; + }); + $('#tt3 p').html(data[2].activeTypeName); + $('.zdzb3').html(html3) + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.gchh').on('tap', '.gchh_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb').on('tap', '.zdzb_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb3').on('tap', '.zdzb3_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/activity7.js b/static/app/js/activity7.js new file mode 100755 index 0000000..a78802a --- /dev/null +++ b/static/app/js/activity7.js @@ -0,0 +1,281 @@ +$('.mui-title').html('ECT专区'); +var ect_top = '<div class="ect_top"><p class="ect_m">最新价</p><p class="ect_m">24H成交量</p><img src="http://img.heyuanhui.cn/Upload/app/icon/star.png" /><p class="ect_m" id="last"></p><p class="ect_m" id="vol"></p></div>'; +$('header').before(ect_top); +var time_ = '距活动开始还有<span id="_d"></span>天'; +$('.mui-scroll-wrapper').removeClass('scroll_out1').addClass('scroll_out3'); +var info = '<img src="http://img.heyuanhui.cn/Upload/app/icon/info.png" class="tanhao" />'; +$('header').append(info); +var nav = '<div class="nav clearfix"></div>'; +$('.ect_top').before(nav); +var html_con = '<div class="ten clearfix"></div><div class="title_img"></div><div class="time_"></div><div class="con_"></div>' + +$('.con').html(html_con); +$('.time_').html(time_); +var nav_data = []; +var secTypeId = 0; +var timestamp1 = Date.parse(new Date()); +if(timestamp1 >= 1537027200000) { + secTypeId = 4; + nav_data = [{ + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} else { + secTypeId = 1; + nav_data = [{ + "secTypeId": 1, + "name": "9.15元专区" + }, { + "secTypeId": 2, + "name": "满199减100" + }, { + "secTypeId": 3, + "name": "买二赠一专区" + }, { + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} + +var issx = 0; +var doller = 0; + +function getData(secTypeId) { + // mui('').pullRefresh().scroll(0, 0, 0); + backTop(); + var data_set = { + secTypeId: secTypeId, + topTypeId: 1 + }; + mui.ajax(llUrl('addon/hyhlimitactive-Hyhlimitactive-frontList'), {  + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + + data = data.data; + var html_ = ''; + var htmlcon = ''; + + doller = data.doller; + if(data.secTypeId == 5 || data.secTypeId == 4) { + htmlcon = '<div class="ect_activity"><img src="http://img.heyuanhui.cn/static/app/img/e' + secTypeId + '.png" class="ect_hd" /></div>' + } else { + htmlcon = '' + html_ = '<div class="day"><p>此活动仅限14-15号两天</p></div>'; + } + + $.each(data.list, function() { + htmlcon += '<div class="ect_com" data-id="' + this.goodsId + '"><div class="com_img1" ><img src="' + hyhImgUrl(this.goodsImg) + '" /></div><p class="p1"><img src="http://img.heyuanhui.cn/static/app/img/ectb.png" class="com_img2" />' + this.goodsName + '</p><p class="p3"><l></l>CNY <o>' + this.shopPrice + '</o></p>' + html_ + '</div>'; + }); + $('.con_').html(htmlcon); + + setTimeout(function() { + $('.com_img1').height($('.com_img1').width()); + }, 200) + countTime(); + + } else { + console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + });  +} + +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date("2018/10/01 00:00:00"); + var end = endDate.getTime(); + //时间差 + var leftTime = end - now; + //定义变量 d,h,m,s保存倒计时的时间 + var h, m, s; + if(leftTime >= 0) { + d = Math.floor(leftTime / 1000 / 60 / 60 /24); + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(d < 10) { + d = "0" + d; + } + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + document.getElementById("_d").innerHTML = d; +// document.getElementById("_h").innerHTML = h; +// document.getElementById("_m").innerHTML = m; +// document.getElementById("_s").innerHTML = s; + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + + }); + getData(secTypeId); + + var html = ''; + $.each(nav_data, function() { + if(timestamp1 >= 1537027200000) { + html += '<div class="nav_block" style="width:50%;" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } else { + html += '<div class="nav_block" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } + }); + $('.nav').html(html); + $('.nav_block').eq(0).addClass('on'); + + setInterval(function() { + + mui.ajax('https://api.tokencan.com/exchange-open-api/open/api/get_ticker?symbol=ectusdt&random=' + Math.random(), {  + + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + $('#last').html(Math.floor((+data.data.last) * doller * 100) / 100); + $('#vol').html(data.data.vol); + $('.p3').each(function(num) { + $(this).children('l').html('ECT ' + (Math.floor(+$(this).children('o').html() / (+data.data.last) / (+doller) * 100)) / 100 + '≈'); + }) + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + }); + + }, 2000) + + mui("body").on('tap', '.nav_block', function() { + secTypeId = this.attributes["data-secTypeId"].nodeValue; + $(this).addClass('on').siblings().removeClass('on'); + getData(secTypeId) + }) + + mui(".con").on('tap', '.ect_com', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-id"].nodeValue; + var isEct = 1; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + isEct: isEct + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + // if(isjiazai == 1) { + // page++; + // } + + } else if(scroll.y > 100 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + + $('header').on('tap', '.tanhao', function() { + mui.openWindow({ + url: 'activity8.html', + id: 'activity8.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); +}) \ No newline at end of file diff --git a/static/app/js/activity8.js b/static/app/js/activity8.js new file mode 100755 index 0000000..8171485 --- /dev/null +++ b/static/app/js/activity8.js @@ -0,0 +1,31 @@ +$('.mui-title').html('活动规则'); +var html = `<p class="rul_p">ECT专区9月14-15日活动规则</p> + + <div class="rul_div"> + <p class="rul_p1">满199-100</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、参加活动产品享受此优惠</p> + <p class="rul_p2">2、此活动不叠加使用</p> + <p class="rul_p2">3、活动日期2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">4、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">5、ECT专区单品与普通单品分开结账</p> + </div> + <div class="rul_div"> + <p class="rul_p1">满二赠一</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、仅限同款产品满二赠一</p> + <p class="rul_p2">2、仅限参加活动产品享受此优惠</p> + <p class="rul_p2">3、此活动不叠加使用,每单仅限使用一次</p> + <p class="rul_p2">4、活动时间2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">5、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">6、ECT专区单品与普通单品分开结账</p> + </div> + <div class="rul_div"> + <p class="rul_p1">9.15元</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、此专区产品每人仅限购买四件</p> + <p class="rul_p2">2、活动时间2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">3、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">4、ECT专区单品与普通单品分开结账</p> + </div>`; + $('.con').html(html) diff --git a/static/app/js/activity9.js b/static/app/js/activity9.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/appraise.js b/static/app/js/appraise.js new file mode 100755 index 0000000..439bc0b --- /dev/null +++ b/static/app/js/appraise.js @@ -0,0 +1,303 @@ +var isjiazai = 1; +var type = ''; +var page = 1 + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var data_id = self.data_id; + // console.log(data_id) + + function getData(page, pagesize, type) { + var set_data = { + goodsId: data_id, + type: type ? type : '', + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + if(isjiazai == 1) { + isjiazai = 0 + + } else { + return; + } + mui.ajax(hyhUrl('app/goodsappraises/getById'), {  + + data: set_data, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + var html = ''; + if(data.status == 1) { + data = data.data; + $('#sum').html('全部(' + data.sum + ')'); + $('#pic').html('有图(' + data.picNum + ')'); + $('#bad').html('差评(' + data.badNum + ')'); + $('#good').html('中评(' + data.goodNum + ')'); + $('#best').html('好评(' + data.bestNum + ')'); + if(data.Rows == '') { + $('.pj_list').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多评价</p>'); + + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + hyhImgUrl(this.userPhoto) + '" /><p>' + this.loginName + '</p></div><div class="pjbcon">' + this.content + '</div>'; + + if(this.shopReply != null) { + html += '<div class="zjpj"><div class="sanjiao"></div><div class="pjzhuijia">商家回复:' + this.shopReply + '</div></div>'; + } + html += '<div class="pjclass">' + this.goodsSpecNames + '</div><div class="pjclass">' + this.createTime + '</div>'; + if(this.images != '' && this.images != null) { + html += '<div class="gallety"><div class="my-gallery clearfix" data-pswp-uid="">'; + var imgArr = this.images.split(','); + $.each(imgArr, function() { + html += '<figure><div class="img-dv"><a href="' + hyhImgUrl(this) + '/thumb512" data-size="1920x1080"><img src="' + hyhImgUrl(this) + '/thumb78"></a></div></figure>'; + // console.log(hyhImgUrl(this)) + }); + + html += '</div></div>'; + } + + html += '</div>'; + + }); + if(page == 1) { + $('.pj_list').html(html); + } else { + $('.pj_list').append(html); + } + + isjiazai = 1; + + setTimeout(function() { + $('.img-dv a').each(function() { + var that = $(this); + var img_ = new Image() + img_.src = that.attr('href'); + img_.onload = function() { + that.attr('data-size', img_.width + 'x' + img_.height); + } + + }); + document.addEventListener('DOMAttrModified', function() { + $('.img-dv a').each(function() { + var that = $(this); + var img_ = new Image() + img_.src = that.attr('href'); + img_.onload = function() { + that.attr('data-size', img_.width + 'x' + img_.height); + } + }); + }, false); + + var initPhotoSwipeFromDOM = function(gallerySelector) { + // 解析来自DOM元素幻灯片数据(URL,标题,大小...) + var parseThumbnailElements = function(el) { + var thumbElements = el.childNodes, + numNodes = thumbElements.length, + items = [], + figureEl, + linkEl, + size, + item, + divEl; + for(var i = 0; i < numNodes; i++) { + figureEl = thumbElements[i]; // <figure> element + // 仅包括元素节点 + if(figureEl.nodeType !== 1) { + continue; + } + divEl = figureEl.children[0]; + linkEl = divEl.children[0]; // <a> element + size = linkEl.getAttribute('data-size').split('x'); + // 创建幻灯片对象 + item = { + src: linkEl.getAttribute('href'), + w: parseInt(size[0], 10), + h: parseInt(size[1], 10) + // w: '100%' + + }; + if(figureEl.children.length > 1) { + item.title = figureEl.children[1].innerHTML; + } + if(linkEl.children.length > 0) { + // <img> 缩略图节点, 检索缩略图网址 + item.msrc = linkEl.children[0].getAttribute('src'); + } + item.el = figureEl; // 保存链接元素 for getThumbBoundsFn + items.push(item); + } + return items; + }; + + // 查找最近的父节点 + var closest = function closest(el, fn) { + return el && (fn(el) ? el : closest(el.parentNode, fn)); + }; + + // 当用户点击缩略图触发 + var onThumbnailsClick = function(e) { + e = e || window.event; + e.preventDefault ? e.preventDefault() : e.returnValue = false; + var eTarget = e.target || e.srcElement; + var clickedListItem = closest(eTarget, function(el) { + return(el.tagName && el.tagName.toUpperCase() === 'FIGURE'); + }); + if(!clickedListItem) { + return; + } + var clickedGallery = clickedListItem.parentNode, + childNodes = clickedListItem.parentNode.childNodes, + numChildNodes = childNodes.length, + nodeIndex = 0, + index; + for(var i = 0; i < numChildNodes; i++) { + if(childNodes[i].nodeType !== 1) { + continue; + } + if(childNodes[i] === clickedListItem) { + index = nodeIndex; + break; + } + nodeIndex++; + } + if(index >= 0) { + openPhotoSwipe(index, clickedGallery); + } + return false; + }; + + var photoswipeParseHash = function() { + var hash = window.location.hash.substring(1), + params = {}; + if(hash.length < 5) { + return params; + } + var vars = hash.split('&'); + for(var i = 0; i < vars.length; i++) { + if(!vars[i]) { + continue; + } + var pair = vars[i].split('='); + if(pair.length < 2) { + continue; + } + params[pair[0]] = pair[1]; + } + if(params.gid) { + params.gid = parseInt(params.gid, 10); + } + return params; + }; + + var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) { + var pswpElement = document.querySelectorAll('.pswp')[0], + gallery, + options, + items; + items = parseThumbnailElements(galleryElement); + // 这里可以定义参数 + options = { + barsSize: { + top: 100, + bottom: 100 + }, + fullscreenEl: false, + shareButtons: [{ + id: 'wechat', + label: '分享微信', + url: '#' + }, + { + id: 'weibo', + label: '新浪微博', + url: '#' + }, + { + id: 'download', + label: '保存图片', + url: '{{raw_image_url}}', + download: true + } + ], + galleryUID: galleryElement.getAttribute('data-pswp-uid'), + getThumbBoundsFn: function(index) { + var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail + pageYScroll = window.pageYOffset || document.documentElement.scrollTop, + rect = thumbnail.getBoundingClientRect(); + return { + x: rect.left, + y: rect.top + pageYScroll, + w: rect.width + }; + } + }; + if(fromURL) { + if(options.galleryPIDs) { + for(var j = 0; j < items.length; j++) { + if(items[j].pid == index) { + options.index = j; + break; + } + } + } else { + options.index = parseInt(index, 10) - 1; + } + } else { + options.index = parseInt(index, 10); + } + if(isNaN(options.index)) { + return; + } + if(disableAnimation) { + options.showAnimationDuration = 0; + } + gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options); + gallery.init(); + }; + + var galleryElements = document.querySelectorAll(gallerySelector); + for(var i = 0, l = galleryElements.length; i < l; i++) { + galleryElements[i].setAttribute('data-pswp-uid', i + 1); + galleryElements[i].onclick = onThumbnailsClick; + } + var hashData = photoswipeParseHash(); + if(hashData.pid && hashData.gid) { + openPhotoSwipe(hashData.pid, galleryElements[hashData.gid - 1], true, true); + } + }; + + initPhotoSwipeFromDOM('.my-gallery'); + }, 500) + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }  + + }) + } + getData(1, 10) + $('.nav').on('tap', '.nav_', function() { + $(this).addClass('on').siblings().removeClass('on'); + type = $(this).attr('id'); + page = 1; + isjiazai = 1; + getData(page, 10, type) + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, 10, type) + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app/js/binaryajax.js b/static/app/js/binaryajax.js new file mode 100755 index 0000000..8084ccb --- /dev/null +++ b/static/app/js/binaryajax.js @@ -0,0 +1,287 @@ + +/* + * Binary Ajax 0.1.10 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt] + */ + +var BinaryFile = function(strData, iDataOffset, iDataLength) { + var data = strData; + var dataOffset = iDataOffset || 0; + var dataLength = 0; + + this.getRawData = function() { + return data; + } + + if (typeof strData == "string") { + dataLength = iDataLength || data.length; + + this.getByteAt = function(iOffset) { + return data.charCodeAt(iOffset + dataOffset) & 0xFF; + } + + this.getBytesAt = function(iOffset, iLength) { + var aBytes = []; + + for (var i = 0; i < iLength; i++) { + aBytes[i] = data.charCodeAt((iOffset + i) + dataOffset) & 0xFF + } + ; + + return aBytes; + } + } else if (typeof strData == "unknown") { + dataLength = iDataLength || IEBinary_getLength(data); + + this.getByteAt = function(iOffset) { + return IEBinary_getByteAt(data, iOffset + dataOffset); + } + + this.getBytesAt = function(iOffset, iLength) { + return new VBArray(IEBinary_getBytesAt(data, iOffset + dataOffset, iLength)).toArray(); + } + } + + this.getLength = function() { + return dataLength; + } + + this.getSByteAt = function(iOffset) { + var iByte = this.getByteAt(iOffset); + if (iByte > 127) + return iByte - 256; + else + return iByte; + } + + this.getShortAt = function(iOffset, bBigEndian) { + var iShort = bBigEndian ? + (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1) + : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset) + if (iShort < 0) + iShort += 65536; + return iShort; + } + this.getSShortAt = function(iOffset, bBigEndian) { + var iUShort = this.getShortAt(iOffset, bBigEndian); + if (iUShort > 32767) + return iUShort - 65536; + else + return iUShort; + } + this.getLongAt = function(iOffset, bBigEndian) { + var iByte1 = this.getByteAt(iOffset), + iByte2 = this.getByteAt(iOffset + 1), + iByte3 = this.getByteAt(iOffset + 2), + iByte4 = this.getByteAt(iOffset + 3); + + var iLong = bBigEndian ? + (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4 + : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1; + if (iLong < 0) + iLong += 4294967296; + return iLong; + } + this.getSLongAt = function(iOffset, bBigEndian) { + var iULong = this.getLongAt(iOffset, bBigEndian); + if (iULong > 2147483647) + return iULong - 4294967296; + else + return iULong; + } + + this.getStringAt = function(iOffset, iLength) { + var aStr = []; + + var aBytes = this.getBytesAt(iOffset, iLength); + for (var j = 0; j < iLength; j++) { + aStr[j] = String.fromCharCode(aBytes[j]); + } + return aStr.join(""); + } + + this.getCharAt = function(iOffset) { + return String.fromCharCode(this.getByteAt(iOffset)); + } + this.toBase64 = function() { + return window.btoa(data); + } + this.fromBase64 = function(strBase64) { + data = window.atob(strBase64); + } +} + + +var BinaryAjax = (function() { + + function createRequest() { + var oHTTP = null; + if (window.ActiveXObject) { + oHTTP = new ActiveXObject("Microsoft.XMLHTTP"); + } else if (window.XMLHttpRequest) { + oHTTP = new XMLHttpRequest(); + } + return oHTTP; + } + + function getHead(strURL, fncCallback, fncError) { + var oHTTP = createRequest(); + if (oHTTP) { + if (fncCallback) { + if (typeof(oHTTP.onload) != "undefined") { + oHTTP.onload = function() { + if (oHTTP.status == "200") { + fncCallback(this); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + }; + } else { + oHTTP.onreadystatechange = function() { + if (oHTTP.readyState == 4) { + if (oHTTP.status == "200") { + fncCallback(this); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + } + }; + } + } + oHTTP.open("HEAD", strURL, true); + oHTTP.send(null); + } else { + if (fncError) + fncError(); + } + } + + function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) { + var oHTTP = createRequest(); + if (oHTTP) { + + var iDataOffset = 0; + if (aRange && !bAcceptRanges) { + iDataOffset = aRange[0]; + } + var iDataLen = 0; + if (aRange) { + iDataLen = aRange[1] - aRange[0] + 1; + } + + if (fncCallback) { + if (typeof(oHTTP.onload) != "undefined") { + oHTTP.onload = function() { + if (oHTTP.status == "200" || oHTTP.status == "206" || oHTTP.status == "0") { + oHTTP.binaryResponse = new BinaryFile(oHTTP.responseText, iDataOffset, iDataLen); + oHTTP.fileSize = iFileSize || oHTTP.getResponseHeader("Content-Length"); + fncCallback(oHTTP); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + }; + } else { + oHTTP.onreadystatechange = function() { + if (oHTTP.readyState == 4) { + if (oHTTP.status == "200" || oHTTP.status == "206" || oHTTP.status == "0") { + // IE6 craps if we try to extend the XHR object + var oRes = { + status: oHTTP.status, + // IE needs responseBody, Chrome/Safari needs responseText + binaryResponse: new BinaryFile( + typeof oHTTP.responseBody == "unknown" ? oHTTP.responseBody : oHTTP.responseText, iDataOffset, iDataLen + ), + fileSize: iFileSize || oHTTP.getResponseHeader("Content-Length") + }; + fncCallback(oRes); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + } + }; + } + } + oHTTP.open("GET", strURL, true); + + if (oHTTP.overrideMimeType) + oHTTP.overrideMimeType('text/plain; charset=x-user-defined'); + + if (aRange && bAcceptRanges) { + oHTTP.setRequestHeader("Range", "bytes=" + aRange[0] + "-" + aRange[1]); + } + + oHTTP.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1970 00:00:00 GMT"); + + oHTTP.send(null); + } else { + if (fncError) + fncError(); + } + } + + return function(strURL, fncCallback, fncError, aRange) { + + if (aRange) { + getHead( + strURL, + function(oHTTP) { + var iLength = parseInt(oHTTP.getResponseHeader("Content-Length"), 10); + var strAcceptRanges = oHTTP.getResponseHeader("Accept-Ranges"); + + var iStart, iEnd; + iStart = aRange[0]; + if (aRange[0] < 0) + iStart += iLength; + iEnd = iStart + aRange[1] - 1; + + sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == "bytes"), iLength); + } + ); + + } else { + sendRequest(strURL, fncCallback, fncError); + } + } + +}()); + +/* + document.write( + "<script type='text/vbscript'>\r\n" + + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n" + + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n" + + "End Function\r\n" + + "Function IEBinary_getLength(strBinary)\r\n" + + " IEBinary_getLength = LenB(strBinary)\r\n" + + "End Function\r\n" + + "</script>\r\n" + ); + */ + +document.write( + "<script type='text/vbscript'>\r\n" + + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n" + + " IEBinary_getByteAt = AscB(MidB(strBinary, iOffset + 1, 1))\r\n" + + "End Function\r\n" + + "Function IEBinary_getBytesAt(strBinary, iOffset, iLength)\r\n" + + " Dim aBytes()\r\n" + + " ReDim aBytes(iLength - 1)\r\n" + + " For i = 0 To iLength - 1\r\n" + + " aBytes(i) = IEBinary_getByteAt(strBinary, iOffset + i)\r\n" + + " Next\r\n" + + " IEBinary_getBytesAt = aBytes\r\n" + + "End Function\r\n" + + "Function IEBinary_getLength(strBinary)\r\n" + + " IEBinary_getLength = LenB(strBinary)\r\n" + + "End Function\r\n" + + "</script>\r\n" + ); \ No newline at end of file diff --git a/static/app/js/canvasResize.js b/static/app/js/canvasResize.js new file mode 100755 index 0000000..eb675ac --- /dev/null +++ b/static/app/js/canvasResize.js @@ -0,0 +1,344 @@ +/* + * + * canvasResize + * + * Version: 1.2.0 + * Date (d/m/y): 02/10/12 + * Update (d/m/y): 14/05/13 + * Original author: @gokercebeci + * Licensed under the MIT license + * - This plugin working with binaryajax.js and exif.js + * (It's under the MPL License http://www.nihilogic.dk/licenses/mpl-license.txt) + * Demo: http://canvasResize.gokercebeci.com/ + * + * - I fixed iOS6 Safari's image file rendering issue for large size image (over mega-pixel) + * using few functions from https://github.com/stomita/ios-imagefile-megapixel + * (detectSubsampling, ) + * And fixed orientation issue by using https://github.com/jseidelin/exif-js + * Thanks, Shinichi Tomita and Jacob Seidelin + */ + +(function($) { + var pluginName = 'canvasResize', + methods = { + newsize: function(w, h, W, H, C) { + var c = C ? 'h' : ''; + if ((W && w > W) || (H && h > H)) { + var r = w / h; + if ((r >= 1 || H === 0) && W && !C) { + w = W; + h = (W / r) >> 0; + } else if (C && r <= (W / H)) { + w = W; + h = (W / r) >> 0; + c = 'w'; + } else { + w = (H * r) >> 0; + h = H; + } + } + return { + 'width': w, + 'height': h, + 'cropped': c + }; + }, + dataURLtoBlob: function(data) { + var mimeString = data.split(',')[0].split(':')[1].split(';')[0]; + var byteString = atob(data.split(',')[1]); + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + var bb = (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder); + if (bb) { + // console.log('BlobBuilder'); + bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)(); + bb.append(ab); + return bb.getBlob(mimeString); + } else { + // console.log('Blob'); + bb = new Blob([ab], { + 'type': (mimeString) + }); + return bb; + } + }, + /** + * Detect subsampling in loaded image. + * In iOS, larger images than 2M pixels may be subsampled in rendering. + */ + detectSubsampling: function(img) { + var iw = img.width, ih = img.height; + if (iw * ih > 1048576) { // subsampling may happen over megapixel image + var canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, -iw + 1, 0); + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering edge pixel or not. + // if alpha value is 0 image is not covering, hence subsampled. + return ctx.getImageData(0, 0, 1, 1).data[3] === 0; + } else { + return false; + } + }, + /** + * Update the orientation according to the specified rotation angle + */ + rotate: function(orientation, angle) { + var o = { + // nothing + 1: {90: 6, 180: 3, 270: 8}, + // horizontal flip + 2: {90: 7, 180: 4, 270: 5}, + // 180 rotate left + 3: {90: 8, 180: 1, 270: 6}, + // vertical flip + 4: {90: 5, 180: 2, 270: 7}, + // vertical flip + 90 rotate right + 5: {90: 2, 180: 7, 270: 4}, + // 90 rotate right + 6: {90: 3, 180: 8, 270: 1}, + // horizontal flip + 90 rotate right + 7: {90: 4, 180: 5, 270: 2}, + // 90 rotate left + 8: {90: 1, 180: 6, 270: 3} + }; + return o[orientation][angle] ? o[orientation][angle] : orientation; + }, + /** + * Transform canvas coordination according to specified frame size and orientation + * Orientation value is from EXIF tag + */ + transformCoordinate: function(canvas, width, height, orientation) { + switch (orientation) { + case 5: + case 6: + case 7: + case 8: + canvas.width = height; + canvas.height = width; + break; + default: + canvas.width = width; + canvas.height = height; + } + var ctx = canvas.getContext('2d'); + switch (orientation) { + case 1: + // nothing + break; + case 2: + // horizontal flip + ctx.translate(width, 0); + ctx.scale(-1, 1); + break; + case 3: + // 180 rotate left + ctx.translate(width, height); + ctx.rotate(Math.PI); + break; + case 4: + // vertical flip + ctx.translate(0, height); + ctx.scale(1, -1); + break; + case 5: + // vertical flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.scale(1, -1); + break; + case 6: + // 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(0, -height); + break; + case 7: + // horizontal flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(width, -height); + ctx.scale(-1, 1); + break; + case 8: + // 90 rotate left + ctx.rotate(-0.5 * Math.PI); + ctx.translate(-width, 0); + break; + default: + break; + } + }, + /** + * Detecting vertical squash in loaded image. + * Fixes a bug which squash image vertically while drawing into canvas for some images. + */ + detectVerticalSquash: function(img, iw, ih) { + var canvas = document.createElement('canvas'); + canvas.width = 1; + canvas.height = ih; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + var data = ctx.getImageData(0, 0, 1, ih).data; + // search image edge pixel position in case it is squashed vertically. + var sy = 0; + var ey = ih; + var py = ih; + while (py > sy) { + var alpha = data[(py - 1) * 4 + 3]; + if (alpha === 0) { + ey = py; + } else { + sy = py; + } + py = (ey + sy) >> 1; + } + var ratio = py / ih; + return ratio === 0 ? 1 : ratio; + }, + callback: function(d) { + return d; + }, + extend: function() { + var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false; + if (target.constructor === Boolean) { + deep = target; + target = arguments[1] || {}; + } + if (al === 1) { + target = this; + a = 0; + } + var prop; + for (; a < al; a++) + if ((prop = arguments[a]) !== null) + for (var i in prop) { + if (target === prop[i]) + continue; + if (deep && typeof prop[i] === 'object' && target[i]) + methods.extend(target[i], prop[i]); + else if (prop[i] !== undefined) + target[i] = prop[i]; + } + return target; + } + }, + defaults = { + width: 300, + height: 0, + crop: false, + quality: 80, + rotate: 0, + 'callback': methods.callback + }; + function Plugin(file, options) { + this.file = file; + // EXTEND + this.options = methods.extend({}, defaults, options); + this._defaults = defaults; + this._name = pluginName; + this.init(); + } + Plugin.prototype = { + init: function() { + //this.options.init(this); + var $this = this; + var file = this.file; + + var reader = new plus.io.FileReader(); + reader.onloadend = function(e) { + + var dataURL = e.target.result; + var byteString = atob(dataURL.split(',')[1]); + var binary = new BinaryFile(byteString, 0, byteString.length); + var exif = EXIF.readFromBinaryFile(binary); + + var img = new Image(); + img.onload = function(e) { + + var orientation = exif['Orientation'] || 1; + orientation = methods.rotate(orientation, $this.options.rotate); + + // CW or CCW ? replace width and height + var size = (orientation >= 5 && orientation <= 8) + ? methods.newsize(img.height, img.width, $this.options.width, $this.options.height, $this.options.crop) + : methods.newsize(img.width, img.height, $this.options.width, $this.options.height, $this.options.crop); + + var iw = img.width, ih = img.height; + var width = size.width, height = size.height; + + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + ctx.save(); + methods.transformCoordinate(canvas, width, height, orientation); + + // over image size + if (methods.detectSubsampling(img)) { + iw /= 2; + ih /= 2; + } + var d = 1024; // size of tiling canvas + var tmpCanvas = document.createElement('canvas'); + tmpCanvas.width = tmpCanvas.height = d; + var tmpCtx = tmpCanvas.getContext('2d'); + var vertSquashRatio = methods.detectVerticalSquash(img, iw, ih); + var sy = 0; + while (sy < ih) { + var sh = sy + d > ih ? ih - sy : d; + var sx = 0; + while (sx < iw) { + var sw = sx + d > iw ? iw - sx : d; + tmpCtx.clearRect(0, 0, d, d); + tmpCtx.drawImage(img, -sx, -sy); + var dx = Math.floor(sx * width / iw); + var dw = Math.ceil(sw * width / iw); + var dy = Math.floor(sy * height / ih / vertSquashRatio); + var dh = Math.ceil(sh * height / ih / vertSquashRatio); + ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh); + sx += d; + } + sy += d; + } + ctx.restore(); + tmpCanvas = tmpCtx = null; + + // if rotated width and height data replacing issue + var newcanvas = document.createElement('canvas'); + newcanvas.width = size.cropped === 'h' ? height : width; + newcanvas.height = size.cropped === 'w' ? width : height; + var x = size.cropped === 'h' ? (height - width) * .5 : 0; + var y = size.cropped === 'w' ? (width - height) * .5 : 0; + newctx = newcanvas.getContext('2d'); + newctx.drawImage(canvas, x, y, width, height); + +// console.log(file, file.type); + if (file.type === "image/png") { + var data = newcanvas.toDataURL(file.type); + } else { + var data = newcanvas.toDataURL("image/jpeg", ($this.options.quality * .01)); + } + + // CALLBACK + $this.options.callback(data, newcanvas.width, newcanvas.height); + + // }); + }; + img.src = dataURL; + // ===================================================== + + }; + reader.readAsDataURL(file); + //reader.readAsBinaryString(file); + + } + }; + $[pluginName] = function(file, options) { +// console.log(file.size); + if (typeof file === 'string') + return methods[file](options); + else + new Plugin(file, options); + }; + +})(window); \ No newline at end of file diff --git a/static/app/js/choiceness.js b/static/app/js/choiceness.js new file mode 100755 index 0000000..7d83455 --- /dev/null +++ b/static/app/js/choiceness.js @@ -0,0 +1,291 @@ +$('.mui-slider-indicator').html('') + +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + count += 1; + //console.log(count) + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + + // console.log(order_class) + mui.ajax(hyhUrl('addon/hyhchosen-Hyhchosen-getChosen'), {  + + data: { + page: count, + goodsSize: 3, + pagesize : 10 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p><div class="btn_gz">+ 关注</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + + html += '<div data-goodId="' + this.goodsId + '" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + $('.con').append(html); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + function openAds(item) { + if(item.attr('data-adURL') == '' || item.attr('data-targetType') == 0) { + return; + } + var adURL = item.attr('data-adURL'); + var targetType = ''; + var data_set = {}; + if(item.attr('data-targetType') == 1) { + //商品 + targetType = 'details.html'; + data_set = { + data_id: adURL + } + } else if(item.attr('data-targetType') == 2) { + //商家 + targetType = 'storeout.html'; + data_set = { + shopId: adURL + } + } else if(item.attr('data-targetType') == 3) { + //活动 + targetType = adURL + '.html'; + } + mui.openWindow({ + url: targetType, + id: targetType + adURL, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: data_set, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + var data = ''; + mui.ajax(hyhUrl('addon/hyhchosen-Hyhchosen-getChosen'), {  + data: { + pagesize: 10, + goodsSize: 3, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + + data = data.data; + + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p><div class="btn_gz">+ 关注</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<div data-goodId="' + this.goodsId + '" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + $('.con').html(html) + if(data.chosenAdsList.length != 0) { + var html1 = '<div class="mui-slider-group mui-slider-loop"><div data-adId="' + data.chosenAdsList[data.chosenAdsList.length - 1].adId + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.chosenAdsList[data.chosenAdsList.length - 1].adFile) + '"></a></div>'; + var html2 = '<div class="mui-slider-indicator">'; + $.each(data.chosenAdsList, function() { + html1 += '<div data-adId="' + this.adId + '"data-adURL="' + this.adURL + '"data-targetType="' + this.targetType + '" class="mui-slider-item "><a href="#"><img src="' + hyhImgUrl(this.adFile) + '"></a></div>' + html2 += '<div class="mui-indicator"></div>' + }) + html2 += '</div>' + html1 += '<div data-adId="' + data.chosenAdsList[0].adId + '"data-adURL="' + data.chosenAdsList[0].adURL + '"data-targetType="' + data.chosenAdsList[0].targetType + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.chosenAdsList[0].adFile) + '"></a></div></div>' + html1 += html2; + $('#slider').html(html1); + + mui("#slider").slider({ + interval: 5000 + }); + document.getElementsByClassName('mui-indicator')[0].className += ' mui-active'; + } + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.storename', function() { + var shopId = $(this).parent().attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.bc_img', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.btn_gz', function() { + var shopId = $(this).parent().attr('data-shopId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/add'), {  + + data: { + id: shopId, + type : 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + that.html('已关注'); + that.addClass('btn_gz1').removeClass('btn_gz'); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }) + //轮播图跳转 + $('#slider').on('tap', '.mui-slider-item', function() { + openAds($(this)); + }) + +}) \ No newline at end of file diff --git a/static/app/js/classify.js b/static/app/js/classify.js new file mode 100755 index 0000000..a67efd9 --- /dev/null +++ b/static/app/js/classify.js @@ -0,0 +1,131 @@ +mui.init() +mui.plusReady(function() { + function classInfo(parentId) { + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: parentId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html1 = ''; + data = data.data; + $.each(data, function() { + + html1 += '<div class="r_block clearfix" data-catId="' + this.catId + '"><div class="rb_title">' + this.catName + '</div></div>'; + + }); + $('.con_right .mui-scroll').html(html1); + + $('.r_block').each(function() { + var parentId2 = $(this).attr('data-catId'); + var that = $(this); + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: parentId2 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html2 = ''; + $.each(data, function() { + html2 += '<div class="rb_block" data-catId="' + this.catId + '"><img src="' + hyhImgUrl(this.catImg) + '" /><p>' + this.catName + '</p></div>'; + }); + + that.append(html2); + $(this).addClass('on').siblings().removeClass('on'); + $('.rb_block img').height($('.rb_block img').width()) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + $(this).addClass('on').siblings().removeClass('on'); + $('.rb_block img').height($('.rb_block img').width()) + $('.con_left').on('tap', '.left_row', function() { + var classify = $(this).attr('data-catId'); + $(this).addClass('on').siblings().removeClass('on'); + $('.rb_block img').height($('.rb_block img').width()) + classInfo(classify) + }) + + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + data = data.data; + $.each(data, function() { + html += '<div class="left_row" data-catId="' + this.catId + '">' + this.catName + '</div>' + + }); + $('.con_left .mui-scroll').html(html); + document.getElementsByClassName('left_row')[0].className += ' on'; + var parentId1 = document.getElementsByClassName('left_row')[0].attributes["data-catId"].nodeValue; + classInfo(parentId1) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.con_right .mui-scroll').on('tap', '.rb_block', function() { + var catId = $(this).attr('data-catId'); + mui.openWindow({ + url: 'goodsList.html', + id: 'goodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_catId: catId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/collect.js b/static/app/js/collect.js new file mode 100755 index 0000000..064f31a --- /dev/null +++ b/static/app/js/collect.js @@ -0,0 +1,75 @@ +jumpPage(); + +function jumpPage() { + //跳转页面 + var subpages = ['collect_commodity.html', 'collect_store.html']; + var subpage_style = { + top: '66px', + bottom: '0px', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if(targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if(mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + if(targetTab == 'collect_commodity.html') { + document.getElementsByClassName('p1')[1].classList.remove('on') + this.classList.add('on'); + } + if(targetTab == 'collect_store.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + this.classList.add('on'); + } + }); + + //首次启动切滑效果 + mui.plusReady(function() { + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + + for(var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if(i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + var data_href = self.data_href; + if(data_href == 'collect_store.html') { + var defaultTab = document.getElementsByClassName("p1")[1]; + //模拟首页点击 + mui.trigger(defaultTab, 'tap'); + } + + }); + +} \ No newline at end of file diff --git a/static/app/js/collect_commodity.js b/static/app/js/collect_commodity.js new file mode 100755 index 0000000..020527a --- /dev/null +++ b/static/app/js/collect_commodity.js @@ -0,0 +1,129 @@ +mui.plusReady(function() { + var page = 1; + var isjiazai = 1; + + function getData(page, pagesize) { + var setdata = { + page: page, + pagesize: pagesize + } + if(isjiazai == 0) { + return; + } + isjiazai = 0; + mui.ajax(hyhUrl('app/favorites/listGoodsQuery'), {  + + data: setdata, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="row clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="row_r" data-favoriteId="'+ this.favoriteId +'" data-goodsId="' + this.goodsId + '"><p class="sctitle">' + this.goodsName + '</p><div class="cost">¥' + this.shopPrice + '</div><button class="qxsc">取消收藏</button></div></div>' + }); + if(page == "1") { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } + getData(page, 10); + //下拉加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, 10) + } + + } + }) + //商品页调转 + mui(".con").on('tap', '.sctitle', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = $(this).parent().attr('data-goodsId'); + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //取消关注 + $('.con').on('tap', '.qxsc', function() { + var favoriteId = $(this).parent().attr('data-favoriteId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/cancel'), {  + + data: { + id: favoriteId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + location.reload(); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }) +}) \ No newline at end of file diff --git a/static/app/js/collect_store.js b/static/app/js/collect_store.js new file mode 100755 index 0000000..83001df --- /dev/null +++ b/static/app/js/collect_store.js @@ -0,0 +1,143 @@ +mui.plusReady(function() { + var page = 1; + var isjiazai = 1; + + function getData(page, pagesize) { + var setdata = { + page: page, + pagesize: pagesize + } + if(isjiazai == 0) { + return; + } + isjiazai = 0; + mui.ajax(hyhUrl('app/favorites/listShopQuery'), {  + + data: setdata, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="row"><div class="row_title"><img class="img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="s_t" data-shopId="' + this.shopId + '">' + this.shopName + '</p><button class="qxsc" data-favoriteId="' + this.favoriteId + '">取消收藏</button></div></div></div>'; + }); + if(page == "1") { + $('.con').html(html); + } else { + $('.con').append(html); + } + + isjiazai = 1; + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } + getData(page, 10); + + //下拉加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, 10) + } + + } + }) + //店铺跳转 + mui(".con").on('tap', '.s_t', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var shopId = this.attributes["data-shopId"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //取消关注 + $('.con').on('tap', '.qxsc', function() { + var favoriteId = $(this).attr('data-favoriteId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/cancel'), {  + + data: { + id: favoriteId, + type : 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + location.reload(); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }) + // mui('.con').on('tap', '.img_btn', function() { + // + // if($(this).attr('src') == '../img/sanjiaoshang.png') { + // $(this).parent().siblings('.row_con').css('display', 'none'); + // $(this).attr('src', '../img/sanjiaoxia.png') + // } else { + // $(this).parent().siblings('.row_con').css('display', 'block'); + // $(this).attr('src', '../img/sanjiaoshang.png') + // } + // + // }) + +}) \ No newline at end of file diff --git a/static/app/js/common.js b/static/app/js/common.js new file mode 100755 index 0000000..4c62f58 --- /dev/null +++ b/static/app/js/common.js @@ -0,0 +1,98 @@ +function hyhUrl(url) { + return 'http://www.heyuanhui.cn/' + url; +} + +function llUrl(url) { + return 'http://www.heyuanhui.cn/' + url; +} + +function kxUrl(url) { + return 'http://www.heyuanhui.cn' + url; +} + +function hyhImgUrl(url) { + return 'http://img.heyuanhui.cn/' + url; +} + +function cssUrl(url) { + return '../css/' + url; +} + +function toJson(str, notLimit) { + var json = {}; + if(str) { + try { + if(typeof(str) == "object") { + json = str; + } else { + json = eval("(" + str + ")"); + } + if(!notLimit) { + if(json.status && json.status == '-999') { + console.log(str.msg) + inLogin(); + + } + } + } catch(e) { + alert("系统发生错误:" + e.getMessage); + json = {}; + } + return json; + } else { + return; + } +} +function backTop() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 0); +} + + +function inLogin() { + mui.openWindow({ + url: 'login.html', + id: 'login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +} + +var scroll = mui('.mui-scroll-wrapper').scroll(); + +var ua = navigator.userAgent.toLowerCase(); +if(/iphone|ipad|ipod/.test(ua)) { //苹果手机 + if(document.getElementsByClassName('zhe')[0]) { + document.getElementsByClassName('zhe')[0].style.display = 'none'; + } + // document.getElementsByClassName('zhe')[0].style.display='none'; +} else if(/android/.test(ua)) { + // document.getElementsByClassName('zhe')[0].style.display='block'; + if(document.getElementsByClassName('zhe')[0]) { + document.getElementsByClassName('zhe')[0].style.display = 'none'; + } +} \ No newline at end of file diff --git a/static/app/js/common_home.js b/static/app/js/common_home.js new file mode 100755 index 0000000..55c3995 --- /dev/null +++ b/static/app/js/common_home.js @@ -0,0 +1,70 @@ +function hyhUrl(url) { + return 'http://www.juzi199.com/' + url; +} +function hyhImgUrl(url) { + return 'http://img.juzi199.com/' + url; +} +function chengUrl(url) { + return 'http://www.juzi199.com/' + url; +} + +function toJson(str, notLimit) { + var json = {}; + if(str) { + try { + if(typeof(str) == "object") { + json = str; + } else { + json = eval("(" + str + ")"); + } + if(!notLimit) { + if(json.status && json.status == '-999') { + console.log(str.msg) + inLogin(); + + } + } + } catch(e) { + alert("系统发生错误:" + e.getMessage); + json = {}; + } + return json; + } else { + return; + } +} + +function inLogin() { + mui.openWindow({ + url: 'login.html', + id: 'login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +} + diff --git a/static/app/js/complain.js b/static/app/js/complain.js new file mode 100755 index 0000000..df4ffec --- /dev/null +++ b/static/app/js/complain.js @@ -0,0 +1,153 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + + mui.ajax(hyhUrl('app/Ordercomplains/getComplainCause'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html = '<option value="0">选择投诉类型</option>'; + $.each(data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>'; + }) + $('select').html(html); + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'selectfiles', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('ossfile').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false,'complains'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('ossfile').innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name))+ '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + alert("\n选择的文件太大了"); + } else if(err.code == -601) { + alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + alert("\n这个文件已经上传过一遍了"); + } else { + alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); + + $('button').on('tap', function() { + var complainType = $('select').val(); + var complainContent = $('textarea').val(); + var imagesArr = []; + $('#ossfile').children('.files_out').children('b').children('img').each(function() { + imagesArr.push($(this).attr('data-src')) + }) + var images = imagesArr.join(','); + if(complainType == 0) { + alert('请选择投诉原因!'); + return; + } + if(complainContent.length < 5) { + alert('投诉内容不小于5个字!'); + return; + } + var that = $(this); + mui.ajax(hyhUrl('app/Ordercomplains/saveComplain'), {  + data: { + orderId: data_order_id, + complainType: complainType, + complainContent: complainContent, + complainAnnex: images + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + alert('提交成功!'); + var targetTab = plus.webview.getWebviewById('complain.html'); + mui.fire(targetTab, 'refresh'); + mui.back(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }) + +}) \ No newline at end of file diff --git a/static/app/js/confirmOrder.js b/static/app/js/confirmOrder.js new file mode 100755 index 0000000..5aa817e --- /dev/null +++ b/static/app/js/confirmOrder.js @@ -0,0 +1,668 @@ +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init(); +mui.plusReady(function() { + window.addEventListener('setAddress', function(e) { + var addressId = localStorage.getItem('addressId') ? localStorage.getItem('addressId') : 0; + if(addressId == 0) { + return; + } + mui.ajax(hyhUrl('app/useraddress/getById'), {  + data: { + addressId: addressId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + // for(i in data.data){ + // console.log(i) + // console.log(data.data[i]) + // } + var html = '<div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userName + '</div><div class="add_r_t_r">' + data.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.areaName + ' ' + data.userAddress + '</div></div>'; + $('.address').html(html); + $('.address').attr('data-addressId', data.addressId); + $('.address').attr('data-areaId', data.areaId2); + + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }); + + $('.con').on('tap', '.address', function() { + var addressId = $(this).attr('data-addressId'); + localStorage.setItem('addressId', addressId); + var isOrder = true; + mui.openWindow({ + url: 'setting_address.html', + id: 'setting_address.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_addressId: addressId, + data_isOrder: isOrder + + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + //支付插件 + plus.payment.getChannels(function(channels) { + for(var i in channels) { + if(channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=1&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if(id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if(id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch(xhr.readyState) { + case 4: + if(xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + plus.webview.getWebviewById('confirmOrder.html').close(); + }); + } else { + alert("获取订单信息失败!"); + console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + var self = plus.webview.currentWebview(); + var type = self.type; + var data_1 = {}; + var isUseScore = 0; + var orderNo; + var priceT = 0; + var payCode = ''; + // console.log(type) + + mui.ajax(hyhUrl('app/carts/settlement'), {  + data: { + type: type + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + var data = toJson(data); + + if(data.status == 1) { + var allallnum = 0; + data = data.data; + data_1 = data; + if(data.userAddress.addressId) { + var html = '<div class="address clearfix" data-addressId="' + data.userAddress.addressId + '" data-areaId2="' + data.userAddress.areaId2 + '"><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userAddress.userName + '</div><div class="add_r_t_r">' + data.userAddress.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.userAddress.areaName + ' ' + data.userAddress.userAddress + '</div></div></div>'; + } else { + var html = '<div class="address clearfix" ><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l" style="height:60px;line-height:60px;font-size:14.4px;color:black">请选择收货地址</div></div></div></div>'; + } + $.each(data.carts, function() { + var allNum = 0; + html += '<div class="shop_info"><div class="row_title"><div class="store_name">' + this.shopName + '</div></div><div class="row_con clearfix">'; + $.each(this.list, function() { + allNum += this.cartNum; + var price = ''; + if(this.isWhsle == 1) { + price = this.whslePrice; + } else if(this.specPrice != 'null') { + price = this.shopPrice; + } else { + price = this.specPrice; + } + var specNames = ''; + for(var i in this.specNames[0]) { + if(i == "catName") { + specNames = this.specNames[0][i] + ':'; + } else if(i == "itemName") { + specNames += this.specNames[0][i] + } + } + + html += '<div class="row_block clearfix" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">'; + $.each(this.specNames, function() { + html += this.catName + ':' + this.itemName + ';'; + }); + + html += '</p></div><div class="rcrr"><p>¥' + price + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.cartNum + '</span></div></div></div>' + }); + allallnum += allNum; + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">买家留言:</div><div class="c1_r"><input class="remark" data-shopId="' + this.shopId + '" type="text" name="" id="" value="" placeholder="选填:填写内容已和卖家协商确认" /></div></div></div>'; + + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">选择优惠券:</div><div class="c1_r"><select name="" data-shopId="' + this.shopId + '" class="yhq"><option value="0">不使用优惠券</option>'; + $.each(this.coupons, function() { + html += '<option value="' + this.couponId + '">满' + this.useMoney + '元减' + this.couponValue + '元</option>'; + }); + html += '</select></div></div></div><div class="cost"><div class="c2 clearfix"><div class="c1_r">共' + allNum + '件商品 小计:<o class="on">¥' + this.goodsMoney + '</o> + 运费:<o class="on">¥' + this.shippingMoney + '</o></div></div></div></div></div>'; + }); + if(data.ect_pay == 0) { + html += '<div class="isHb clearfix"><div class="h_left">惠宝抵用&nbsp;&nbsp;&nbsp;&nbsp;<o id="huibao">可抵用惠宝:' + data.useOrderScore + '</o></div><div class="he_right"><div class="checkout"><div class="check_btn"></div></div></div></div>' + } + html += '<div class="jf_info clearfix"><div class="jf_jf">积分</div><div class="jf_p">奖励积分为成交价格的20%</div></div>'; + priceT = (Math.floor((+data.goodsTotalMoney - (+data.promotionMoney))*100))/100; + priceT = priceT >= 0 ? priceT : 0; + var html1 = '<span>共' + allallnum + '件商品 合计:<j>¥' + priceT + '</j></span>&nbsp;&nbsp;<div class="btn_tj">提交订单</div>'; + if(data.ect_pay == 1) { + var htmlpay = '<div class="row clearfix select_payway" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.userECT + '</o></p></div>'; + + $('.pay_info .con_1').append(htmlpay); + // $('.pay_info .con_1 .row').eq(0).attr('style','display: none;'); + $('.pay_info .con_1 .row').eq(1).remove(); + }; + $('.con').html(html); + $('.js_r').html(html1); + $('#loginName').html(data.loginName); + $('.userMoney').html(data.userMoney); + + $('#goodsTotalMoney').html(priceT); + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.con').on('change', 'select', function() { + var couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + // var addressId = $('.address').attr('data-addressId') + var areaId2 = $('.address').attr('data-areaId2') + var couponIdsArr = couponIds.join(','); + mui.ajax(hyhUrl('app/carts/getMoney'), {  + data: { + type: type, + areaId2: addressId, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + couponIds: couponIdsArr + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + // console.log(data.msg) + if(data.status == 1) { + + $('.js_r span j').html('¥' + data.data.realTotalMoney) + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }); + + $('.con').on('tap', '.checkout', function() { + + $(this).toggleClass('on'); + if($(this).hasClass('on')) { + isUseScore = 1; + } else { + isUseScore = 0; + } + var couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + + var couponIdsArr = couponIds.join(','); + var areaId2 = $('.address').attr('data-areaId2'); + // console.log(areaId2) + // console.log(couponIdsArr) + // console.log(data_1.userAddress.areaId2) + // console.log(data_1.userAddress) + mui.ajax(hyhUrl('app/carts/getMoney'), {  + data: { + type: type, + areaId2: areaId2, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + couponIds: couponIdsArr + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + // console.log(data.msg) + if(data.status == 1) { + // console.log(data) + // console.log(data.data.shopFreight) + // for(i in data.data){ + // console.log(i) + // console.log(data.data[i]) + // } + $('.js_r span j').html('¥' + data.data.realTotalMoney) + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }) + $('.footer').on('tap', '.btn_tj', function() { + payCode = $('.select_payway').attr('data-payCode'); + + if(payCode == 'ect') { + mui.ajax(hyhUrl('app/ect/getToEctNum'), {  + + data: { + total_money: priceT + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒; + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + if(data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if(e.index == 1) { + return; + } else { + var addressId = $('.address').attr('data-addressId'); + if(addressId) { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } else { + alert('未设置收货地址!') + } + } + }) + } else { + alert(data.msg); + return; + } + + } + }) + } else { + var addressId = $('.address').attr('data-addressId'); + if(addressId) { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } else { + alert('未设置收货地址!') + } + } + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.select_payway .row_right o').html($(this).children('.row_left').html()); + $('.select_payway').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + + }) + $('.pay').on('tap', '.select_payway', function() { + if($(this).attr('data-payCode') == 'ect') {} else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + } + + }) + + $('.pay_btn').on('tap', function() { + + var addressId = $('.address').attr('data-addressId'); + var areaId = $('.address').attr('data-areaId'); + var that = $(this); + payCode = $('.select_payway').attr('data-payCode'); + var data_send = { + type: type, + s_addressId: addressId, + s_areaId: areaId, + payCode: payCode, + payType: 1, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + deliverType: 0, + isInvoice: 0, + invoiceId: 0, + invoiceClient: '' + } + + $('.remark').each(function() { + data_send['remark_' + ($(this).attr('data-shopid'))] = $(this).val(); + }); + $('select').each(function() { + data_send['couponId_' + ($(this).attr('data-shopid'))] = $(this).val(); + }) + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/orders/submit'), {  + data: data_send, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.status) + data = toJson(data); + if(data.status == 1) { + orderNo = data.data; + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: data.data, + isBatch: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', data.data); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + } + }) + }) + $('#pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('#pay_pwd').on('tap', '.pay_btn_pwd', function() { + + var payPwd = $('#payPwd').val(); + if(payPwd == '') { + alert('支付密码不能为空!'); + } + var that = $(this); + that.attr('disabled', 'disabled'); + var srcc = '' + if(payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + + mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), {  + + data: { + orderNo: orderNo, + isBatch: 1, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + // mui.back(); + mui.openWindow({ + url: 'indent.html', + id: 'indent.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: 'waitDeliver' + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: false, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + setTimeout(function() { + plus.webview.getWebviewById('confirmOrder.html').close(); + }, 500) + + } else { + mui.openWindow({ + url: 'indent.html', + id: 'indent.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: 'waitPay' + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: false, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + setTimeout(function() { + plus.webview.getWebviewById('confirmOrder.html').close(); + }, 500) + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + alert(errorThrown);       + } + });  + + }) +}) \ No newline at end of file diff --git a/static/app/js/details.js b/static/app/js/details.js new file mode 100755 index 0000000..759ac22 --- /dev/null +++ b/static/app/js/details.js @@ -0,0 +1,818 @@ +var shareImgThumbs = []; +var shares = null; +var Intent = null, + File = null, + Uri = null, + main = null; +// H5 plus事件处理 +function plusReady() { + updateSerivces(); + if(plus.os.name == "Android") { + main = plus.android.runtimeMainActivity(); + Intent = plus.android.importClass("android.content.Intent"); + File = plus.android.importClass("java.io.File"); + Uri = plus.android.importClass("android.net.Uri"); + } +} +if(window.plus) { + plusReady(); +} else { + document.addEventListener("plusready", plusReady, false); +} + +/** + * + * 更新分享服务 + */ +function updateSerivces() { + plus.share.getServices(function(s) { + shares = {}; + for(var i in s) { + var t = s[i]; + shares[t.id] = t; + } + }, function(e) { + plus.nativeUI.toast("获取分享服务列表失败:" + e.message); + }); +} + +/** + * 分享操作 + * @param {JSON} sb 分享操作对象s.s为分享通道对象(plus.share.ShareService) + * @param {Boolean} bh 是否分享链接 + */ +function shareAction(sb, bh) { + if(!sb || !sb.s) { + plus.nativeUI.toast("无效的分享服务!"); + return; + } + + var msg = { + content: sharehrefDes.value, + extra: { + scene: sb.x + } + }; + if(bh) { + msg.href = sharehref.value; + if(sharehrefTitle && sharehrefTitle.value != "") { + msg.title = sharehrefTitle.value; + } + if(sharehrefDes && sharehrefDes.value != "") { + msg.content = sharehrefDes.value; + } +// msg.thumbs = ["_www/logo.png"]; + msg.thumbs = $('.swiper-slide img').eq(0).attr('src') ? [$('.swiper-slide img').eq(0).attr('src') + '/thumb60'] : ["_www/logo.png"]; + + msg.pictures = ["_www/logo.png"]; + } else { + if(pic && pic.realUrl) { + msg.pictures = [pic.realUrl]; + } + } + // 发送分享 + if(sb.s.authenticated) { + // plus.nativeUI.toast("---已授权---"); + shareMessage(msg, sb.s); + } else { + plus.nativeUI.toast("---未授权---"); + sb.s.authorize(function() { + shareMessage(msg, sb.s); + }, function(e) { + plus.nativeUI.toast("认证授权失败:" + e.code + " - " + e.message); + + }); + } +} +/** + * 发送分享消息 + * @param {JSON} msg + * @param {plus.share.ShareService} s + */ +function shareMessage(msg, s) { + + // plus.nativeUI.toast(JSON.stringify(msg)); + s.send(msg, function() { + plus.nativeUI.toast("分享到\"" + s.description + "\"成功! "); + + }, function(e) { + plus.nativeUI.toast("分享到\"" + s.description + "\"失败 "); + + }); +} +// 分析链接 +function shareHref() { + var shareBts = []; + // 更新分享列表 + var ss = shares['weixin']; + ss && ss.nativeClient && (shareBts.push({ + title: '微信朋友圈', + s: ss, + x: 'WXSceneTimeline' + }), + shareBts.push({ + title: '微信好友', + s: ss, + x: 'WXSceneSession' + })); + + // 弹出分享列表 + shareBts.length > 0 ? plus.nativeUI.actionSheet({ + title: '分享注册链接', + cancel: '取消', + buttons: shareBts + }, function(e) { + (e.index > 0) && shareAction(shareBts[e.index - 1], true); + }) : plus.nativeUI.plus.nativeUI.toast('当前环境无法支持分享链接操作!'); +} + +mui.plusReady(function() { + var data = ''; + var data_saleSpec = {} + var arry_str = ''; + var self = plus.webview.currentWebview(); + var data_id = self.data_id; + var isEct = self.isEct; + var data_bak = {}; + var token = localStorage.getItem('token'); + var isShowWhsle = 0; + var shopQQ = ''; + var shopTle = ''; + // console.log(data_id) + + function whslePrice(num, arry_str) { + for(var i in data_saleSpec) { + if(i == arry_str) { + // if(num >= (+(data_saleSpec[i].initNum)) && data_saleSpec[i].whslePrice > 0) { + if(isShowWhsle == 1 && data_saleSpec[i].whslePrice > 0) { + $('.cclass_con .cc2 o').html('批发单价:¥' + data_saleSpec[i].whslePrice); + $('.cclass_con .cc2 l').html('起批数:' + data_saleSpec[i].initNum + '件'); + } + } + } + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html('¥' + data_saleSpec[i].specPrice); + } + } + } + mui.ajax(hyhUrl('app/Goods/detail'), {  + data: { + goodsId: data_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + // console.log(data.status) + if(data.status == 1) { + // mui.alert('加载失败请重试!'); + data = data.data; + data_bak = data; + shopQQ = data.shop.shopQQ; + shopTel = data.shop.shopTel; + var isEct = data.isEct; + if(!shopQQ && shopTel) { + $('#lxkf').html('<a href="tel:' + shopTel + '"><img src="../img/haitunlogo.png" /><p>客服</p></a>') + } + var html = '<div class="none" style="display: none;"><p>链接地址:</p><input id="sharehref" type="url" value="'+ data.goods_url +'" /><p>链接标题:</p><input id="sharehrefTitle" type="text" value="' + data.goodsName + '" /><p>链接描述:</p><input id="sharehrefDes" type="text" value="' + data.goodsTips + '" /></br></div><div class="banner"><div class="swiper-container"><div class="swiper-wrapper">'; + var html2 = ''; + $.each(data.gallery, function() { + html += '<div class="swiper-slide"><img src="' + hyhImgUrl(this) + '" /></div>'; + }); + + if(isEct==1){ + html += '</div></div></div><div class="summarize"><p class="price xxl"><o>ECT专享价</o>¥' + data.shopPrice + '</p><p class="price_old">市场价 <del>¥' + data.marketPrice + '</del></p><div class="compilations"><span class="myf">'; + }else{ + html += '</div></div></div><div class="summarize"><p class="price">¥' + data.shopPrice + '</p><p class="price"><o>到手价</o>¥' + Math.round(data.shopPrice * 0.8 * 100) / 100 + '</p><p class="price_old">市场价 <del>¥' + data.marketPrice + '</del></p><div class="compilations"><span class="myf">'; + } + + + if(data.isFreeShipping == '1') { + html += '免运费'; + } else { + html += '不包邮'; + } + html += '</span><span class="yx">月销:' + data.saleNum + '件</span><span class="dz"></span></div><p class="cname" id="shareout" style="color:black;font-size:16px"><o> ' + data.goodsName + '</o><img id="share" src="../img/share.png"/></p>' + if(data.goodsTips) { + html += '<p class="cname">' + data.goodsTips + '</p>'; + } + + html += '</div><div class="guarantee"><div class="row clearfix yyyhhhqqq"><img src="../img/gouwuquan.png" /><span class="text">领取优惠券</span><button class="lq">领取</button></div><div class="row clearfix"><span class="text1">积分</span><span class="text">购买后可获得成交价格20%积分</span></div>'; + if(isEct!=1){ + html+='<div class="row clearfix"><span class="text1">惠宝</span><span class="text">本商品可用惠宝抵扣20%</span></div>' + }else{ + } + if(data.promotionList != '') { + html += '<div class="mui-table-view-cell mui-collapse row_"><a class="mui-navigate-right" href="#">促销信息 :' + data.promotionList.rewardTitle + '</a><div class="mui-collapse-content" style="width:100%">'; + $.each(data.promotionList.json, function() { + html += '<h4>满' + this.orderMoney + '元</h4>'; + + if(this.favourableJson.chk0 == true) { + html += '<h5>减' + this.favourableJson.chk0val + '元</h5>'; + } + if(this.favourableJson.chk1 == true) { + html += '<h5>送' + this.favourableJson.chk1val.text + '</h5>'; + } + if(this.favourableJson.chk2 == true) { + html += '<h5>免运费</h5>'; + } + if(this.favourableJson.chk3 == true) { + html += '<h5>送满' + this.favourableJson.chk3val.text + '元优惠券 满' + this.favourableJson.chk3val.data.useMoney + '元使用</h5>'; + } + + }); + + html += '</div></div>'; + } + + html += '<div class="row clearfix"><span class="text">正品保证 </span><button class="caidan" style="display:none"><img src="../img/menu.png"/></button></div></div><div class="guarantee" id="guarantee"><div class="row clearfix" id="changeclass"><span class="text">选择颜色分类 号码尺寸</span><button class="caidan"><img src="../img/menu.png"/></button></div></div>'; + if(data.oneAppraises == '') { + + } else { + html += '<div class="pjrk" style="display:block"><p class="pj_title">商品评价(' + data.appraiseNum + ')</p><div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + hyhImgUrl(data.oneAppraises.userPhoto) + '" /><p>' + data.oneAppraises.loginName + '</p></div><div class="pjbcon">' + data.oneAppraises.content + '</div><div class="pjclass">' + data.oneAppraises.goodsSpecNames + '</div></div><div class="pj_all">查看全部评价</div></div>'; + } + + var img_data = data.goodsDesc.replace(/src=\"__ROOT__\//g, 'data-src="').replace(/data-echo=\"__ROOT__\//g, 'src="' + hyhImgUrl('')).replace(/src=\"\//g, 'src="' + hyhImgUrl('')); + // console.log(img_data) + html += '<div class="shop_info"><div class="shop_title clearfix"><img src="' + hyhImgUrl(data.shop.shopImg) + '" /><p data-shopId="' + data.shop.shopId + '">' + data.shop.shopName + '</p></div><div class="shopinfocon clearfix"><div class="sicl"><div class="sicl_p1">' + data.goodsCount + '</div><div class="sicl_p2">全部宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.newGoodsCount + '</div><div class="sicl_p2">上新宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.favoritesShopsNum + '</div><div class="sicl_p2">关注人数</div></div><div class="sicr"><div class="sicr_p">宝贝描述&nbsp;<o>' + data.shop.goodsScore + '</o></div><div class="sicr_p">卖家服务&nbsp;<o>' + data.shop.serviceScore + '</o></div><div class="sicr_p">物流服务&nbsp;<o>' + data.shop.timeScore + '</o></div></div></div></div><div class="imgcon">' + img_data + '</div>'; + $('.con').html(html); + + $('.cclass_con .img').html('<img src="' + hyhImgUrl(data.goodsImg) + '" />'); + $('.cclass_con .cc2 p').html('¥' + data.shopPrice); + $('.cclass_con .cc2 span').html('库存' + data.goodsStock + '件'); + if(data.showWhsle == 1) { + isShowWhsle = 1; + } + $('#storebtn').attr('data-shopId', data.shopId); + $('.swiper-slide img').height($('.swiper-slide img').width()); + $('.swiper-slide').height($('.swiper-slide').width()); +// $('.banner').height($('.banner').width()); + var swiper = new Swiper('.swiper-container', { + pagination: '.swiper-pagination', + paginationClickable: true, + spaceBetween: 30, + autoplay: 3000 + }); + var html1 = ''; + // var html1 = '<div class="mui-scroll-wrapper" id="hahaha"><div class="mui-scroll">'; + $.each(data.spec, function() { + html1 += '<div class="cclass1 clearfix" data-class=""><p>' + this.name + '</p>' + $.each(this.list, function() { + // console.log(this.itemId) + html1 += '<div class="block" data-itemId="' + this.itemId + '">' + this.itemName + '</div>' + }); + html1 += '</div>' + }); + // html1+='</div></div>' + $('.ccclass').html(html1) + // var hahaha = mui('#hahaha').scroll(); + // $('.ccclass').height($('#hahaha').height()) + for(var i in data.saleSpec) { + data_saleSpec[i] = data.saleSpec[i]; + } + if(data.couponList == '') { + $('.yyyhhhqqq').css('display', 'none'); + } else { + $.each(data.couponList, function() { + html2 += '<div class="thq_block"><img src="../img/thq_bg.png"/><p>¥' + this.couponValue + '</p><span>满' + this.useMoney + '元使用</span><button class="lq_btn" data-couponId="' + this.couponId + '">领取</button></div>'; + }); + $('.yhqcon').html(html2); + } + } else if(data.status == -22) { + alert(data.msg); + mui.back(); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + var scroll = mui('.mui-scroll-wrapper').scroll({ + deceleration: 0.002 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + }); + + //导航栏渐变 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + + var num; + + if(scroll.y >= -387 && scroll.y < 0) { + + num = scroll.y / -387; + // console.log('渐变',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ +// 'display': 'block', + 'opacity': num + }) + var num1 = 0.2 - num * 0.2; + // $('.header .mui-action-back').css('background', 'rgba(0,0,0,' + num1 + ')') + } else if(scroll.y >= 0) { + num = 0; + // console.log('透明',num) + $('.header1').css({ + 'display': 'none', + 'opacity': num + }) + $('.zhe').css({ +// 'display': 'none', + 'opacity': num + }) + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } else if(scroll.y < -387) { + + num = 1; + // console.log('不透明',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ +// 'display': 'block', + 'opacity': num + }); + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } + //导航栏自动切换 + if($('.imgcon').offset().top >= 66) { + $('#nav1').addClass("on").siblings().removeClass('on'); + } else if($('.imgcon').offset().top < 66) { + $('#nav3').addClass("on").siblings().removeClass('on'); + } + }) + //点击导航栏跳转 + mui('.nav').on('tap', '#nav1', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); + $('#nav1').addClass("on").siblings().removeClass('on'); + }); + mui('.nav').on('tap', '#nav2', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); + mui('.nav').on('tap', '#nav3', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, -1124, 100); + $('#nav3').addClass("on").siblings().removeClass('on'); + }); + + mui('.con').on('tap', '#changeclass', function() { + $('#changeclass_con').show(); + }) + + //选择类型 + mui('.ccclass').on('tap', '.block', function() { + $(this).addClass('on').siblings().removeClass('on'); + $(this).parent().attr('data-class', $(this).attr('data-itemId')); + + var data_itemId = $(this).attr('data-itemId'); + // console.log(data_itemId) + $.each(data.spec, function() { + $.each(this.list, function() { + if(this.itemId == data_itemId && this.itemImg != '') { + $('.cclass_con .img').html('<img src="' + hyhImgUrl(this.itemImg) + '" />'); + } + }); + }); + + var arry = []; + + $.each($('.cclass1'), function() { + arry.push($(this).attr('data-class')) + }); + arry.sort(function(a, b) { + return a - b; + }); + + arry_str = arry.join(':'); + // $.each(data.saleSpec, function() { + // if(this == arry_str) { + // $('.cclass_con .cc2 p').html(this.specPrice); + // $('.cclass_con .cc2 span').html('库存' + this.specStock + '件'); + // + // } + // }); + + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + $('.cclass_con .cc2 span').html('库存' + data_saleSpec[i].specStock + '件'); + + } + } + + var num = +$('.change_num input').val(); + whslePrice(num, arry_str); + }) + //跳转选择类型 + + $('.footer').on('tap', '.btn_ljgm', function() { + $('#changeclass_con').show(); + }) + + mui('.cc2').on('tap', '.closecclass', function() { + $('#changeclass_con').hide(); + }) + + mui('.en').on('tap', '.engwc', function() { + $('#changeclass_con').hide(); + }) + + //改变数量 + mui('.change_num').on('tap', '.jia', function() { + // console.log($(this).siblings('input').val()) + var num = +$(this).siblings('input').val() + 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + mui('.change_num').on('tap', '.jian', function() { + var num = +$(this).siblings('input').val() - 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + $('.change_num input').on('change', function() { + var num = +$(this).val(); + + whslePrice(num, arry_str); + }) + //加入购物车&购买 + mui('.en').on('tap', '.enarr', function() { + + var that = $(this); + var goodsId = data_id; + var buyNum = $('.change_num input').val(); + var isGoodsSpecId = 0; + var goodsSpecId = 0; + var url = ''; + if($(this).hasClass('engwc')) { + url = 'addCart'; + } else if($(this).hasClass('ensure')) { + url = 'buy'; + } + // console.log(data_bak.isSpec) + for(var i in data_saleSpec) { + if(i == arry_str) { + isGoodsSpecId = 1; + goodsSpecId = data_saleSpec[i].id; + } + } + if(isGoodsSpecId == 1) { + // goodsSpecId = arry_str; + } else if(data_bak.isSpec == 0) { + goodsSpecId = 0; + } else { + alert('请选择商品分类!'); + return + } + // console.log(arry_str) + // console.log(goodsSpecId) + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/' + url), {  + data: { + goodsId: goodsId, + buyNum: buyNum, + goodsSpecId: goodsSpecId + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + data = toJson(data); + // console.log(data.msg); + // console.log(data.status); + if(data.status == 1) { + if(url == 'buy') { + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + + type: 1 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } else if(url == 'addCart') { + alert('添加购物车成功!') + } + + } else { + alert(data.msg); + //location.reload(); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + + //打开评价列表 + mui('.con').on('tap', '.pjrk', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.footer').on('tap', '#scbtn', function() { + var goodId = data_id; + var that = $(this); + if($('#scbtn p').html() == '收藏') { + mui.ajax(hyhUrl('app/Favorites/add'), {  + + data: { + id: goodId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#scbtn p').html('已收藏'); + $('#scbtn p').css('color', '#E41F4A'); + $('#scbtn img').attr('src', '../img/likelogo1.png'); + // that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } else { + mui.ajax(hyhUrl('app/Favorites/cancel'), {  + + data: { + id: goodId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#scbtn p').html('收藏'); + $('#scbtn p').css('color', '#8f8f94'); + $('#scbtn img').attr('src', '../img/likelogo.png'); + // that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } + + }) + $('.footer').on('tap', '#storebtn', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + var url = 'storeout.html'; + if(shopId==1){ + url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con').on('tap', '.shop_title p', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + var url = 'storeout.html'; + if(shopId==1){ + url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //弹出优惠券 + $('.con').on('tap', '.lq', function() { + $('#youhuiquan_con').css('display', 'block'); + }) + //关闭优惠券 + $('#youhuiquan_con').on('tap', '.thq_close', function() { + $('#youhuiquan_con').css('display', 'none'); + }) + //领取优惠券 + $('#youhuiquan_con').on('tap', '.lq_btn', function() { + var couponId = $(this).attr('data-couponId'); + mui.ajax(hyhUrl('addon/coupon-Coupons-receive'), {  + headers: {  + "HYH-Token": token + }, + data: { + couponId: couponId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + alert(data.msg); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }) + //联系客服 + + $('#lxkf').on('tap', function() { + if(shopQQ) { + // location.href="http://wpa.qq.com/msgrd?v=3&uin="+ shopQQ +"&site=qq&menu=yes"; + // mui.back(); + // window.open("http://wpa.qq.com/msgrd?v=3&uin="+ shopQQ +"&site=qq&menu=yes") + if(plus.os.name == "iOS") { + plus.runtime.launchApplication({ + action: "mqq://im/chat?chat_type=wpa&uin=" + shopQQ + "&version=1&src_type=web" + }, function(e) { + plus.nativeUI.confirm("检查到您未安装qq,请先到appstore搜索下载?", function(i) { + if(i.index == 0) { + iosAppstore("itunes.apple.com/cn/app/mqq/"); + } + }); + }); + } else if(plus.os.name == "Android") { + var Intent = plus.android.importClass('android.content.Intent'); + var Uri = plus.android.importClass('android.net.Uri'); + var main = plus.android.runtimeMainActivity(); + var uri = Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + shopQQ); + main.startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + } + }) + //分享 + $('.con').on('tap', '#share', function() { + shareHref(); + }) + +}) +// var self = plus.webview.currentWebview(); +// console.log(self.aaa) \ No newline at end of file diff --git a/static/app/js/details_ac.js b/static/app/js/details_ac.js new file mode 100755 index 0000000..347ee48 --- /dev/null +++ b/static/app/js/details_ac.js @@ -0,0 +1,444 @@ +mui.plusReady(function() { + var data = ''; + var data_saleSpec = {} + var arry_str = ''; + var self = plus.webview.currentWebview(); + var data_id = self.data_id; + var data_bak = {} + + function whslePrice(num, arry_str) { + for(var i in data_saleSpec) { + if(i == arry_str) { + if(num >= (+(data_saleSpec[i].initNum))) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].whslePrice); + } + } + } + for(var i in data_saleSpec) { + if(i == arry_str) { + if(num < (+(data_saleSpec[i].initNum))) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + } + } + } + } + mui.ajax(hyhUrl('app/Goods/detail'), {  + data: { + goodsId: data_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + if(data.status != 1) { + mui.alert('加载失败请重试!'); + } + data = data.data; + data_bak = data; + var html = '<div class="banner"><div class="swiper-container"><div class="swiper-wrapper">'; + + $.each(data.gallery, function() { + html += '<div class="swiper-slide"><img src="' + hyhImgUrl(this) + '" /></div>'; + }); + + html += '</div></div></div><div class="summarize"><p class="price">¥' + data.shopPrice + '</p><p class="price_old">价格 <del>¥' + data.marketPrice + '</del></p><div class="compilations"><span class="myf">'; + + if(data.isFreeShipping == '1') { + html += '免运费'; + } else { + html += '不包邮'; + } + html += '</span><span class="yx">月销:' + data.saleNum + '件</span><span class="dz"></span></div><p class="cname">商品介绍 ' + data.goodsTips + '</p></div><div class="guarantee"><div class="row clearfix" style="display:none"><img src="../img/gouwuquan.png" /><span class="text">全合源惠实物商品通用</span><button class="lq">领取</button></div><div class="row clearfix"><img src="../img/jifen.png" /><span class="text">购买后可获得100%积分</span></div><div class="row clearfix"><span class="text">正品保证 · 公益宝贝 · 赠运险费 · 极速退款 · 七天退货</span><button class="caidan" style="display:none"><img src="../img/menu.png"/></button></div></div><div class="guarantee" id="guarantee"><div class="row clearfix" id="changeclass"><span class="text">选择颜色分类 号码尺寸</span><button class="caidan"><img src="../img/menu.png"/></button></div></div>'; + if(data.oneAppraises == '') { + + } else { + html += '<div class="pjrk" style="display:none"><p class="pj_title">商品评价(' + data.appraiseNum + ')</p><div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + hyhImgUrl(data.oneAppraises.userPhoto) + '" /><p>' + data.oneAppraises.loginName + '</p></div><div class="pjbcon">' + data.oneAppraises.content + '</div><div class="pjclass">' + data.oneAppraises.goodsSpecNames + '</div></div><div class="pj_all">查看全部评价</div></div>'; + } + + html += '<div class="shop_info"><div class="shop_title clearfix"><img src="' + hyhImgUrl(data.shop.shopImg) + '" /><p>' + data.shop.shopName + '</p></div><div class="shopinfocon clearfix"><div class="sicl"><div class="sicl_p1">' + data.goodsCount + '</div><div class="sicl_p2">全部宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.newGoodsCount + '</div><div class="sicl_p2">上新宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.favoritesShopsNum + '</div><div class="sicl_p2">关注人数</div></div><div class="sicr"><div class="sicr_p">宝贝描述&nbsp;<o>' + data.shop.goodsScore + '</o></div><div class="sicr_p">卖家服务&nbsp;<o>' + data.shop.serviceScore + '</o></div><div class="sicr_p">物流服务&nbsp;<o>' + data.shop.timeScore + '</o></div></div></div></div><div class="imgcon">' + data.goodsDesc + '</div>'; + $('.con').html(html); + + $('.cclass_con .img').html('<img src="' + hyhImgUrl(data.goodsImg) + '" />'); + $('.cclass_con .cc2 p').html(data.shopPrice); + $('.cclass_con .cc2 span').html('库存' + data.goodsStock + '件'); + $('#storebtn').attr('data-shopId', data.shopId) + var swiper = new Swiper('.swiper-container', { + pagination: '.swiper-pagination', + paginationClickable: true, + spaceBetween: 30, + autoplay: 3000 + }); + var html1 = ''; + $.each(data.spec, function() { + html1 += '<div class="cclass1 clearfix" data-class=""><p>' + this.name + '</p>' + $.each(this.list, function() { + html1 += '<div class="block" data-itemId="' + this.itemId + '">' + this.itemName + '</div>' + }); + + html1 += '</div>' + }); + $('.ccclass').html(html1) + + for(var i in data.saleSpec) { + data_saleSpec[i] = data.saleSpec[i]; + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + var scroll = mui('.mui-scroll-wrapper').scroll({ + deceleration: 0.002 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + }); + + //导航栏渐变 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + + var num; + + if(scroll.y >= -387 && scroll.y < 0) { + + num = scroll.y / -387; + // console.log('渐变',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'block', + 'opacity': num + }) + var num1 = 0.2 - num * 0.2; + // $('.header .mui-action-back').css('background', 'rgba(0,0,0,' + num1 + ')') + } else if(scroll.y >= 0) { + num = 0; + // console.log('透明',num) + $('.header1').css({ + 'display': 'none', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'none', + 'opacity': num + }) + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } else if(scroll.y < -387) { + + num = 1; + // console.log('不透明',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'block', + 'opacity': num + }); + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } + //导航栏自动切换 + if($('.imgcon').offset().top >= 66) { + $('#nav1').addClass("on").siblings().removeClass('on'); + } else if($('.imgcon').offset().top < 66) { + $('#nav3').addClass("on").siblings().removeClass('on'); + } + }) + //点击导航栏跳转 + mui('.nav').on('tap', '#nav1', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); + $('#nav1').addClass("on").siblings().removeClass('on'); + }); + mui('.nav').on('tap', '#nav2', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); + mui('.nav').on('tap', '#nav3', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, -1124, 100); + $('#nav3').addClass("on").siblings().removeClass('on'); + }); + + mui('.con').on('tap', '#changeclass', function() { + $('#changeclass_con').show(); + }) + + //选择类型 + mui('.ccclass').on('tap', '.block', function() { + $(this).addClass('on').siblings().removeClass('on'); + $(this).parent().attr('data-class', $(this).attr('data-itemId')); + + var data_itemId = $(this).attr('data-itemId'); + + $.each(data.spec, function() { + $.each(this.list, function() { + if(this.itemId == data_itemId && this.itemImg != '') { + $('.cclass_con .img').html('<img src="' + hyhImgUrl(this.itemImg) + '" />'); + } + }); + }); + + var arry = []; + + $.each($('.cclass1'), function() { + arry.push($(this).attr('data-class')) + }); + arry.sort(function(a, b) { + return a - b; + }); + + arry_str = arry.join(':'); + $.each(data.saleSpec, function() { + if(this == arry_str) { + $('.cclass_con .cc2 p').html(this.specPrice); + $('.cclass_con .cc2 span').html('库存' + this.specStock + '件'); + } + }); + + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + $('.cclass_con .cc2 span').html('库存' + data_saleSpec[i].specStock + '件'); + } + } + + var num = +$('.change_num input').val(); + whslePrice(num, arry_str); + }) + //跳转选择类型 + + $('.footer').on('tap', '.btn_ljgm', function() { + $('#changeclass_con').show(); + }) + + mui('.cc2').on('tap', '.closecclass', function() { + $('#changeclass_con').hide(); + }) + + mui('.en').on('tap', '.engwc', function() { + $('#changeclass_con').hide(); + }) + + //改变数量 + mui('.change_num').on('tap', '.jia', function() { + // console.log($(this).siblings('input').val()) + var num = +$(this).siblings('input').val() + 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + mui('.change_num').on('tap', '.jian', function() { + var num = +$(this).siblings('input').val() - 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + $('.change_num input').on('change', function() { + var num = +$(this).val(); + + whslePrice(num, arry_str); + }) + //加入购物车&购买 + mui('.en').on('tap', '.enarr', function() { + + var that = $(this); + var goodsId = data_id; + var buyNum = $('.change_num input').val(); + var isGoodsSpecId = 0; + var goodsSpecId = 0; + var url = ''; + if($(this).hasClass('engwc')) { + url = 'addCart'; + } else if($(this).hasClass('ensure')) { + url = 'buy'; + } + // console.log(data_bak.isSpec) + for(var i in data_saleSpec) { + if(i == arry_str) { + isGoodsSpecId = 1; + } + } + if(isGoodsSpecId == 1) { + goodsSpecId = arry_str; + } else if(data_bak.isSpec == 0) { + goodsSpecId = 0; + } else { + alert('请选择商品分类!'); + return + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/' + url), {  + data: { + goodsId: goodsId, + buyNum: buyNum, + goodsSpecId: goodsSpecId + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + data = toJson(data); + if(data.status == 1) { + if(url == 'buy') { + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + + type: 1 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } else if(url == 'addCart') { + alert('添加购物车成功!') + } + + } else { + alert(data.msg); + //location.reload(); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + + //打开评价列表 + mui('.con').on('tap', '.pjrk', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.footer').on('tap', '#storebtn', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html'+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) +// var self = plus.webview.currentWebview(); +// console.log(self.aaa) \ No newline at end of file diff --git a/static/app/js/discounts.js b/static/app/js/discounts.js new file mode 100755 index 0000000..ecbda14 --- /dev/null +++ b/static/app/js/discounts.js @@ -0,0 +1,80 @@ +jumpPage(); + +function jumpPage() { + //跳转页面 + var subpages = ['choiceness.html', 'dynamic.html', 'new_product.html']; + var subpage_style = { + top: '103px', + bottom: '0px', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if(targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if(mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + + if(targetTab == 'choiceness.html') { + document.getElementsByClassName('p1')[1].classList.remove('on') + document.getElementsByClassName('p1')[2].classList.remove('on') + this.classList.add('on'); + } + + if(targetTab == 'dynamic.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + document.getElementsByClassName('p1')[2].classList.remove('on') + this.classList.add('on'); + } + + if(targetTab == 'new_product.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + document.getElementsByClassName('p1')[1].classList.remove('on') + this.classList.add('on'); + } + + }); + + //首次启动切滑效果 + + mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + for(var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if(i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + }); +} \ No newline at end of file diff --git a/static/app/js/dynamic.js b/static/app/js/dynamic.js new file mode 100755 index 0000000..3a4835a --- /dev/null +++ b/static/app/js/dynamic.js @@ -0,0 +1,171 @@ +var token = localStorage.getItem('token'); +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('addon/hyhprom-Hyhpromuser-getShopPromByUser'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: count, + pagesize : 10 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">' + this.promInfo + '</div></div>' + }); + $('.con').append(html); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var data = ''; + mui.ajax(hyhUrl('addon/hyhprom-Hyhpromuser-getShopPromByUser'), {  + data: { + pagesize: 10, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + if(data.status == 1) { + data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.updateTime + '</p></div><div class="b_con clearfix">' + this.promInfo + '</div></div>' + }); + $('.con').html(html); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html'+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', 'img[data-goodId]', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/ect_address.js b/static/app/js/ect_address.js new file mode 100755 index 0000000..80d2654 --- /dev/null +++ b/static/app/js/ect_address.js @@ -0,0 +1,158 @@ +mui.plusReady(function() { + + // function hyhUrl(url) { + // return 'http://192.168.1.101/hyh/' + url; + // } + + var token = localStorage.getItem('token'); + + // alert(token); + + mui.ajax(hyhUrl('app/Ectwallets/listQuery'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data != '') { + $.each(data.data, function() { + html += '<div class="row"><div class="r_con"><p>钱包地址 ' + this.eAddress + '</p></div><div class="r_bottom" data-eWalletId="' + this.eWalletId + '" data-isDefault="' + this.isDefault + '"><div class="default"><div class="check"></div><p>设为默认</p></div><div class="del">删除</div></div></div>'; + }); + $('.mui-scroll').html(html); + + $('.row').each(function() { + if($(this).children('.r_bottom').attr('data-isDefault') == 1) { + $(this).children('.r_bottom').children('.default').children('.check').addClass('on'); + } + }) + + } + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //设为默认 + $('.mui-scroll').on('tap', '.default', function() { + + if($(this).parent().attr('data-isDefault') == 0) { + if(confirm('设为默认地址?')) { + var eWalletId = $(this).parent().attr('data-eWalletId'); + // console.log(eWalletId) + mui.ajax(hyhUrl('app/Ectwallets/setDefault'), {  + headers: {  + "HYH-Token": token + }, + data: { + eWalletId: eWalletId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + } + }) + //删除地址 + $('.mui-scroll').on('tap', '.del', function() { + if(confirm('删除地址?')) { + var eWalletId = $(this).parent().attr('data-eWalletId'); + // console.log(eWalletId) + mui.ajax(hyhUrl('app/Ectwallets/del'), {  + headers: {  + "HYH-Token": token + }, + data: { + eWalletId: eWalletId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + }) + + //添加地址 + $('.add').on('tap', function() { + var eAddress = ''; + var eAddress_ = ''; + + if(eAddress = prompt('请输入钱包地址')) { + if(eAddress.length != 42) { + alert('钱包地址长度必须为42位'); + return; + } +// if(eAddress_ = prompt('请再次输入钱包地址')) { +// if(eAddress == eAddress_) { + var isDefault = 0; + if(confirm('是否设为默认地址?')) { + isDefault = 1; + } + mui.ajax(hyhUrl('app/Ectwallets/add'), {  + headers: {  + "HYH-Token": token + }, + data: { + eAddress: eAddress, + isDefault: isDefault + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  +// } else { +// alert('两次地址输入不一致!'); +// } +// } + } + + }) +}) \ No newline at end of file diff --git a/static/app/js/ect_index.js b/static/app/js/ect_index.js new file mode 100755 index 0000000..f09d88d --- /dev/null +++ b/static/app/js/ect_index.js @@ -0,0 +1,85 @@ +mui.plusReady(function() { + +// $('#ect_withdraw_deposit').css('display','none'); + $('#ect_transfer_accounts').css('display','none'); + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + + + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + }); + + var token = localStorage.getItem('token'); + + // alert(token); + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + + + if(data.data.eAddressInfo.eAddress){ + $('#ect_add').html('钱包地址:' + data.data.eAddressInfo.eAddress); + }else{ + $('#ect_add').html('钱包地址:未设置钱包地址' ); + } + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + //跳转 + $('body').on('tap', '.row', function() { + var url = $(this).attr('id')+'.html'; + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + +}) \ No newline at end of file diff --git a/static/app/js/ect_list.js b/static/app/js/ect_list.js new file mode 100755 index 0000000..58144b9 --- /dev/null +++ b/static/app/js/ect_list.js @@ -0,0 +1,104 @@ +mui.plusReady(function() { + var isjiazai = 1; + var page = 1; + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + function getLocalTime(nS) { + return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' '); + } + + var token = localStorage.getItem('token'); + + // alert(token); + + function getDate(page) { + var num = page; + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(hyhUrl('app/Ectwallets/getEctLog'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多记录</p>'); + isjiazai = 0; + return; + } + $.each(data.data.Rows, function() { + var ectType; + var dataSrc; + if(this.ectType == 1) { + ectType = '+'; + } else { + ectType = '-'; + } + + if(this.dataSrc == 1) { + dataSrc = '注册赠送'; + } else if(this.dataSrc == 2) { + dataSrc = '推荐赠送'; + } else if(this.dataSrc == 3) { + dataSrc = '交易'; + } else if(this.dataSrc == 4) { + dataSrc = '提现'; + }else if(this.dataSrc == 5) { + dataSrc = '联盟积分转换'; + }else if(this.dataSrc == 6) { + dataSrc = '成为商家'; + }else if(this.dataSrc == 7) { + dataSrc = '推荐成为商家'; + }else if(this.dataSrc == 8) { + dataSrc = '成为线上商城商家'; + }else if(this.dataSrc == 9) { + dataSrc = '推荐成为线上商城商家'; + } + + html += '<div class="block"><img src="../img/ect_list_bg.png"/><div class="s1">ECT变动记录</div><div class="s2">' + getLocalTime(this.createTime) + '</div><div class="s3">变动数量</div><div class="s4">' + ectType + ' ' + this.ectNum + ' </div><div class="s5">变动类型:<o>' + dataSrc + '</o></div><div class="s6">备注:<o>' + this.dataRemarks + '</o></div></div>' + }); + + if(page == 1) { + $('.mui-scroll').html(html); + } else { + $('.mui-scroll').append(html); + } + isjiazai = 1 + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + getDate(page); + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getDate(page); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app/js/ect_transfer_accounts.html.js b/static/app/js/ect_transfer_accounts.html.js new file mode 100755 index 0000000..96303a8 --- /dev/null +++ b/static/app/js/ect_transfer_accounts.html.js @@ -0,0 +1,138 @@ +mui.plusReady(function() { + + // function hyhUrl(url) { + // return 'http://192.168.1.101/hyh/' + url; + // } + var token = localStorage.getItem('token'); + + $('input').eq(0).attr('id','ectNum'); + $('input').eq(1).attr('id','payPwd'); + $('.num p').html(''); + $('input').eq(0).attr('placeholder','ect数量至少为500'); + // alert(token); + + mui.ajax(hyhUrl('app/Ectwallets/listQuery'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data != '') { + $.each(data.data, function() { + html += '<option value="' + this.eAddress + '">' + this.eAddress + '</option>' + }); + $('#select').html(html); + } + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui('body').on('tap', '.btn_ture', function() { + var eAddress = $('#select').val(); + var ectNum = $('#ectNum').val(); + var payPwd = $('#payPwd').val(); + if(eAddress == '') { + plus.nativeUI.toast('未选择钱包地址'); + return; + } + if(!(ectNum >= 500)) { + plus.nativeUI.toast('ect数量必须大于500'); + return; + } + if(payPwd == '') { + plus.nativeUI.toast('未填写支付密码'); + return; + } + $('.btn_ture').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/Ectwallets/withdraw'), {  + headers: {  + "HYH-Token": token + }, + data: { + eAddress: eAddress, + ectNum: ectNum, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data, 1); + if(data.status == 1) { +// console.log(data.data.id) + + var id =data.data.id; +// $('.btn_ture').removeAttr('disabled'); + mui.ajax('http://moacapi.heyuanhui.cn/api/ect/ect_transfer', {  + data: { + id:id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   +// console.log(data) + var data = toJson(data, 1); + if(data.status == 1) { + mui.fire(plus.webview.getWebviewById('templete/my.html'), 'refresh'); + mui.fire(plus.webview.getWebviewById('ect_index.html'), 'refresh'); + alert(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + $('.btn_ture').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + + } else { + alert(data.msg); + location.reload(); + $('.btn_ture').removeAttr('disabled'); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   +// alert(errorThrown);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app/js/ect_transfer_accounts.js b/static/app/js/ect_transfer_accounts.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/editAddress.js b/static/app/js/editAddress.js new file mode 100755 index 0000000..d08903e --- /dev/null +++ b/static/app/js/editAddress.js @@ -0,0 +1,288 @@ +mui.init({ + beforeback: function() {     //获得父页面的webview + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var addressId = self.data_addressId ? self.data_addressId : 0; + var isParentId = 1; + var isProvince; + var isCity; + var userName = $('#userName'); + var userPhone = $('#userPhone'); + var province = $('#province'); + var city = $('#city'); + var Area = $('#area'); + var Textarea = $('textarea'); + var areaVal; + if(addressId != 0) { + $('.address_info').css('display', 'none'); + $('.add_info').css('display', 'block'); + mui.ajax(hyhUrl('app/useraddress/getById'), {  + data: { + addressId: addressId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + userName.val(data.userName) + userPhone.val(data.userPhone) + $('.add_info').html(data.areaName) + Textarea.val(data.userAddress) + areaVal = data.areaId + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + mui.ajax(hyhUrl('app/areas/listQuery'), {  + data: { + parentId: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = '<option value="">选择省</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#province').html(html); + + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + }); + + // $('.scroll_out1').on('tap', '#province', function() { + // if(isParentId == 1) { + // isParentId = 0; + // mui.ajax(hyhUrl('app/areas/listQuery'), {  + // data: { + // parentId: 0 + // }, + // dataType: 'json', //服务器返回json格式数据   + // type: 'post', //HTTP请求类型   + // timeout: 10000, //超时时间设置为10秒;   + // success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // data = toJson(data); + // if(data.status == 1) { + // data = data.data; + // var html = ''; + // $.each(data, function() { + // html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + // }); + // $('#province').html(html); + // var province = data[0].areaId; + // mui.ajax(hyhUrl('app/areas/listQuery'), {  + // data: { + // parentId: province + // }, + // dataType: 'json', //服务器返回json格式数据   + // type: 'post', //HTTP请求类型   + // timeout: 10000, //超时时间设置为10秒;   + // success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // data = toJson(data); + // if(data.status == 1) { + // data = data.data; + // var html = ''; + // $.each(data, function() { + // html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + // }); + // $('#city').html(html); + // var city = data[0].areaId; + // mui.ajax(hyhUrl('app/areas/listQuery'), {  + // data: { + // parentId: city + // }, + // dataType: 'json', //服务器返回json格式数据   + // type: 'post', //HTTP请求类型   + // timeout: 10000, //超时时间设置为10秒;   + // success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // data = toJson(data); + // if(data.status == 1) { + // data = data.data; + // var html = ''; + // $.each(data, function() { + // html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + // }); + // $('#area').html(html); + // isCity = city; + // } else { + // alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) {           //异常处理;   + // // alert(type);       + // }   + // });  + // isProvince = province; + // } else { + // alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) {           //异常处理;   + // // alert(type);       + // }   + // }); + // } else { + // alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) {           //异常处理;   + // // alert(type);       + // }   + // });  + // } + // + // }) + $('.scroll_out1').on('change', '#province', function() { + var province = $(this).val() + if(isProvince != province) { + mui.ajax(hyhUrl('app/areas/listQuery'), {  + data: { + parentId: province + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = '<option value="">选择市</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#city').html(html); + // var city = data[0].areaId; + // mui.ajax(hyhUrl('app/areas/listQuery'), {  + // data: { + // parentId: city + // }, + // dataType: 'json', //服务器返回json格式数据   + // type: 'post', //HTTP请求类型   + // timeout: 10000, //超时时间设置为10秒;   + // success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // data = toJson(data); + // if(data.status == 1) { + // data = data.data; + var html = '<option value="">选择区</option>'; + // $.each(data, function() { + // html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + // }); + $('#area').html(html); + // isCity = city; + // } else { + // alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) {           //异常处理;   + // // alert(type);       + // }   + // });  + isProvince = province; + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + }) + $('.scroll_out1').on('change', '#city', function() { + var city = $(this).val() + if(isCity != city) { + mui.ajax(hyhUrl('app/areas/listQuery'), {  + data: { + parentId: city + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = '<option value="">选择区</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#area').html(html); + isCity = city; + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + }) + + $('.bc_btn').on('tap', function() { + var isDefault = $('input:radio[name="isDefault"]:checked').val() ? $('input:radio[name="isDefault"]:checked').val() : 0; + areaVal = $('#area').val() ? $('#area').val() : areaVal; + var data = { + isDefault: isDefault, + addressId: addressId, + userName: $('#userName').val(), + areaId: areaVal, + userPhone: $('#userPhone').val(), + userAddress: $('textarea').val(), + } + mui.ajax(hyhUrl('app/useraddress/edits'), {  + data: data, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + mui.back(); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + $('.add_info').on('tap', function() { + $('.address_info').css('display', 'block'); + $('.add_info').css('display', 'none'); + }) + +}) \ No newline at end of file diff --git a/static/app/js/exif.js b/static/app/js/exif.js new file mode 100755 index 0000000..77d1875 --- /dev/null +++ b/static/app/js/exif.js @@ -0,0 +1,640 @@ +/* + * Javascript EXIF Reader 0.1.6 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt] + */ + + +var EXIF = (function() { + + var debug = false; + + var ExifTags = { + + // version tags + 0x9000: "ExifVersion", // EXIF version + 0xA000: "FlashpixVersion", // Flashpix format version + + // colorspace tags + 0xA001: "ColorSpace", // Color space information tag + + // image configuration + 0xA002: "PixelXDimension", // Valid width of meaningful image + 0xA003: "PixelYDimension", // Valid height of meaningful image + 0x9101: "ComponentsConfiguration", // Information about channels + 0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel + + // user information + 0x927C: "MakerNote", // Any desired information written by the manufacturer + 0x9286: "UserComment", // Comments by user + + // related file + 0xA004: "RelatedSoundFile", // Name of related sound file + + // date and time + 0x9003: "DateTimeOriginal", // Date and time when the original image was generated + 0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally + 0x9290: "SubsecTime", // Fractions of seconds for DateTime + 0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal + 0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized + + // picture-taking conditions + 0x829A: "ExposureTime", // Exposure time (in seconds) + 0x829D: "FNumber", // F number + 0x8822: "ExposureProgram", // Exposure program + 0x8824: "SpectralSensitivity", // Spectral sensitivity + 0x8827: "ISOSpeedRatings", // ISO speed rating + 0x8828: "OECF", // Optoelectric conversion factor + 0x9201: "ShutterSpeedValue", // Shutter speed + 0x9202: "ApertureValue", // Lens aperture + 0x9203: "BrightnessValue", // Value of brightness + 0x9204: "ExposureBias", // Exposure bias + 0x9205: "MaxApertureValue", // Smallest F number of lens + 0x9206: "SubjectDistance", // Distance to subject in meters + 0x9207: "MeteringMode", // Metering mode + 0x9208: "LightSource", // Kind of light source + 0x9209: "Flash", // Flash status + 0x9214: "SubjectArea", // Location and area of main subject + 0x920A: "FocalLength", // Focal length of the lens in mm + 0xA20B: "FlashEnergy", // Strobe energy in BCPS + 0xA20C: "SpatialFrequencyResponse", // + 0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit + 0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit + 0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution + 0xA214: "SubjectLocation", // Location of subject in image + 0xA215: "ExposureIndex", // Exposure index selected on camera + 0xA217: "SensingMethod", // Image sensor type + 0xA300: "FileSource", // Image source (3 == DSC) + 0xA301: "SceneType", // Scene type (1 == directly photographed) + 0xA302: "CFAPattern", // Color filter array geometric pattern + 0xA401: "CustomRendered", // Special processing + 0xA402: "ExposureMode", // Exposure mode + 0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual + 0xA404: "DigitalZoomRation", // Digital zoom ratio + 0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) + 0xA406: "SceneCaptureType", // Type of scene + 0xA407: "GainControl", // Degree of overall image gain adjustment + 0xA408: "Contrast", // Direction of contrast processing applied by camera + 0xA409: "Saturation", // Direction of saturation processing applied by camera + 0xA40A: "Sharpness", // Direction of sharpness processing applied by camera + 0xA40B: "DeviceSettingDescription", // + 0xA40C: "SubjectDistanceRange", // Distance to subject + + // other tags + 0xA005: "InteroperabilityIFDPointer", + 0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image + }; + + var TiffTags = { + 0x0100: "ImageWidth", + 0x0101: "ImageHeight", + 0x8769: "ExifIFDPointer", + 0x8825: "GPSInfoIFDPointer", + 0xA005: "InteroperabilityIFDPointer", + 0x0102: "BitsPerSample", + 0x0103: "Compression", + 0x0106: "PhotometricInterpretation", + 0x0112: "Orientation", + 0x0115: "SamplesPerPixel", + 0x011C: "PlanarConfiguration", + 0x0212: "YCbCrSubSampling", + 0x0213: "YCbCrPositioning", + 0x011A: "XResolution", + 0x011B: "YResolution", + 0x0128: "ResolutionUnit", + 0x0111: "StripOffsets", + 0x0116: "RowsPerStrip", + 0x0117: "StripByteCounts", + 0x0201: "JPEGInterchangeFormat", + 0x0202: "JPEGInterchangeFormatLength", + 0x012D: "TransferFunction", + 0x013E: "WhitePoint", + 0x013F: "PrimaryChromaticities", + 0x0211: "YCbCrCoefficients", + 0x0214: "ReferenceBlackWhite", + 0x0132: "DateTime", + 0x010E: "ImageDescription", + 0x010F: "Make", + 0x0110: "Model", + 0x0131: "Software", + 0x013B: "Artist", + 0x8298: "Copyright" + }; + + var GPSTags = { + 0x0000: "GPSVersionID", + 0x0001: "GPSLatitudeRef", + 0x0002: "GPSLatitude", + 0x0003: "GPSLongitudeRef", + 0x0004: "GPSLongitude", + 0x0005: "GPSAltitudeRef", + 0x0006: "GPSAltitude", + 0x0007: "GPSTimeStamp", + 0x0008: "GPSSatellites", + 0x0009: "GPSStatus", + 0x000A: "GPSMeasureMode", + 0x000B: "GPSDOP", + 0x000C: "GPSSpeedRef", + 0x000D: "GPSSpeed", + 0x000E: "GPSTrackRef", + 0x000F: "GPSTrack", + 0x0010: "GPSImgDirectionRef", + 0x0011: "GPSImgDirection", + 0x0012: "GPSMapDatum", + 0x0013: "GPSDestLatitudeRef", + 0x0014: "GPSDestLatitude", + 0x0015: "GPSDestLongitudeRef", + 0x0016: "GPSDestLongitude", + 0x0017: "GPSDestBearingRef", + 0x0018: "GPSDestBearing", + 0x0019: "GPSDestDistanceRef", + 0x001A: "GPSDestDistance", + 0x001B: "GPSProcessingMethod", + 0x001C: "GPSAreaInformation", + 0x001D: "GPSDateStamp", + 0x001E: "GPSDifferential" + }; + + var StringValues = { + ExposureProgram: { + 0: "Not defined", + 1: "Manual", + 2: "Normal program", + 3: "Aperture priority", + 4: "Shutter priority", + 5: "Creative program", + 6: "Action program", + 7: "Portrait mode", + 8: "Landscape mode" + }, + MeteringMode: { + 0: "Unknown", + 1: "Average", + 2: "CenterWeightedAverage", + 3: "Spot", + 4: "MultiSpot", + 5: "Pattern", + 6: "Partial", + 255: "Other" + }, + LightSource: { + 0: "Unknown", + 1: "Daylight", + 2: "Fluorescent", + 3: "Tungsten (incandescent light)", + 4: "Flash", + 9: "Fine weather", + 10: "Cloudy weather", + 11: "Shade", + 12: "Daylight fluorescent (D 5700 - 7100K)", + 13: "Day white fluorescent (N 4600 - 5400K)", + 14: "Cool white fluorescent (W 3900 - 4500K)", + 15: "White fluorescent (WW 3200 - 3700K)", + 17: "Standard light A", + 18: "Standard light B", + 19: "Standard light C", + 20: "D55", + 21: "D65", + 22: "D75", + 23: "D50", + 24: "ISO studio tungsten", + 255: "Other" + }, + Flash: { + 0x0000: "Flash did not fire", + 0x0001: "Flash fired", + 0x0005: "Strobe return light not detected", + 0x0007: "Strobe return light detected", + 0x0009: "Flash fired, compulsory flash mode", + 0x000D: "Flash fired, compulsory flash mode, return light not detected", + 0x000F: "Flash fired, compulsory flash mode, return light detected", + 0x0010: "Flash did not fire, compulsory flash mode", + 0x0018: "Flash did not fire, auto mode", + 0x0019: "Flash fired, auto mode", + 0x001D: "Flash fired, auto mode, return light not detected", + 0x001F: "Flash fired, auto mode, return light detected", + 0x0020: "No flash function", + 0x0041: "Flash fired, red-eye reduction mode", + 0x0045: "Flash fired, red-eye reduction mode, return light not detected", + 0x0047: "Flash fired, red-eye reduction mode, return light detected", + 0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode", + 0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", + 0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", + 0x0059: "Flash fired, auto mode, red-eye reduction mode", + 0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode", + 0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode" + }, + SensingMethod: { + 1: "Not defined", + 2: "One-chip color area sensor", + 3: "Two-chip color area sensor", + 4: "Three-chip color area sensor", + 5: "Color sequential area sensor", + 7: "Trilinear sensor", + 8: "Color sequential linear sensor" + }, + SceneCaptureType: { + 0: "Standard", + 1: "Landscape", + 2: "Portrait", + 3: "Night scene" + }, + SceneType: { + 1: "Directly photographed" + }, + CustomRendered: { + 0: "Normal process", + 1: "Custom process" + }, + WhiteBalance: { + 0: "Auto white balance", + 1: "Manual white balance" + }, + GainControl: { + 0: "None", + 1: "Low gain up", + 2: "High gain up", + 3: "Low gain down", + 4: "High gain down" + }, + Contrast: { + 0: "Normal", + 1: "Soft", + 2: "Hard" + }, + Saturation: { + 0: "Normal", + 1: "Low saturation", + 2: "High saturation" + }, + Sharpness: { + 0: "Normal", + 1: "Soft", + 2: "Hard" + }, + SubjectDistanceRange: { + 0: "Unknown", + 1: "Macro", + 2: "Close view", + 3: "Distant view" + }, + FileSource: { + 3: "DSC" + }, + Components: { + 0: "", + 1: "Y", + 2: "Cb", + 3: "Cr", + 4: "R", + 5: "G", + 6: "B" + } + }; + + function addEvent(element, event, handler) { + if (element.addEventListener) { + element.addEventListener(event, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + event, handler); + } + } + + function imageHasData(img) { + return !!(img.exifdata); + } + + function getImageData(img, callback) { + BinaryAjax(img.src, function(http) { + var data = findEXIFinJPEG(http.binaryResponse); + img.exifdata = data || {}; + if (callback) { + callback.call(img) + } + }); + } + + function findEXIFinJPEG(file) { + if (file.getByteAt(0) != 0xFF || file.getByteAt(1) != 0xD8) { + return false; // not a valid jpeg + } + + var offset = 2, + length = file.getLength(), + marker; + + while (offset < length) { + if (file.getByteAt(offset) != 0xFF) { + if (debug) + console.log("Not a valid marker at offset " + offset + ", found: " + file.getByteAt(offset)); + return false; // not a valid marker, something is wrong + } + + marker = file.getByteAt(offset + 1); + + // we could implement handling for other markers here, + // but we're only looking for 0xFFE1 for EXIF data + + if (marker == 22400) { + if (debug) + console.log("Found 0xFFE1 marker"); + + return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2); + + // offset += 2 + file.getShortAt(offset+2, true); + + } else if (marker == 225) { + // 0xE1 = Application-specific 1 (for EXIF) + if (debug) + console.log("Found 0xFFE1 marker"); + + return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2); + + } else { + offset += 2 + file.getShortAt(offset + 2, true); + } + + } + + } + + + function readTags(file, tiffStart, dirStart, strings, bigEnd) { + var entries = file.getShortAt(dirStart, bigEnd), + tags = {}, + entryOffset, tag, + i; + + for (i = 0; i < entries; i++) { + entryOffset = dirStart + i * 12 + 2; + tag = strings[file.getShortAt(entryOffset, bigEnd)]; + if (!tag && debug) + console.log("Unknown tag: " + file.getShortAt(entryOffset, bigEnd)); + tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); + } + return tags; + } + + + function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) { + var type = file.getShortAt(entryOffset + 2, bigEnd), + numValues = file.getLongAt(entryOffset + 4, bigEnd), + valueOffset = file.getLongAt(entryOffset + 8, bigEnd) + tiffStart, + offset, + vals, val, n, + numerator, denominator; + + switch (type) { + case 1: // byte, 8-bit unsigned int + case 7: // undefined, 8-bit byte, value depending on field + if (numValues == 1) { + return file.getByteAt(entryOffset + 8, bigEnd); + } else { + offset = numValues > 4 ? valueOffset : (entryOffset + 8); + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getByteAt(offset + n); + } + return vals; + } + + case 2: // ascii, 8-bit byte + offset = numValues > 4 ? valueOffset : (entryOffset + 8); + return file.getStringAt(offset, numValues - 1); + + case 3: // short, 16 bit int + if (numValues == 1) { + return file.getShortAt(entryOffset + 8, bigEnd); + } else { + offset = numValues > 2 ? valueOffset : (entryOffset + 8); + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getShortAt(offset + 2 * n, bigEnd); + } + return vals; + } + + case 4: // long, 32 bit int + if (numValues == 1) { + return file.getLongAt(entryOffset + 8, bigEnd); + } else { + vals = []; + for (var n = 0; n < numValues; n++) { + vals[n] = file.getLongAt(valueOffset + 4 * n, bigEnd); + } + return vals; + } + + case 5: // rational = two long values, first is numerator, second is denominator + if (numValues == 1) { + numerator = file.getLongAt(valueOffset, bigEnd); + denominator = file.getLongAt(valueOffset + 4, bigEnd); + val = new Number(numerator / denominator); + val.numerator = numerator; + val.denominator = denominator; + return val; + } else { + vals = []; + for (n = 0; n < numValues; n++) { + numerator = file.getLongAt(valueOffset + 8 * n, bigEnd); + denominator = file.getLongAt(valueOffset + 4 + 8 * n, bigEnd); + vals[n] = new Number(numerator / denominator); + vals[n].numerator = numerator; + vals[n].denominator = denominator; + } + return vals; + } + + case 9: // slong, 32 bit signed int + if (numValues == 1) { + return file.getSLongAt(entryOffset + 8, bigEnd); + } else { + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getSLongAt(valueOffset + 4 * n, bigEnd); + } + return vals; + } + + case 10: // signed rational, two slongs, first is numerator, second is denominator + if (numValues == 1) { + return file.getSLongAt(valueOffset, bigEnd) / file.getSLongAt(valueOffset + 4, bigEnd); + } else { + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getSLongAt(valueOffset + 8 * n, bigEnd) / file.getSLongAt(valueOffset + 4 + 8 * n, bigEnd); + } + return vals; + } + } + } + + + function readEXIFData(file, start) { + if (file.getStringAt(start, 4) != "Exif") { + if (debug) + console.log("Not valid EXIF data! " + file.getStringAt(start, 4)); + return false; + } + + var bigEnd, + tags, tag, + exifData, gpsData, + tiffOffset = start + 6; + + // test for TIFF validity and endianness + if (file.getShortAt(tiffOffset) == 0x4949) { + bigEnd = false; + } else if (file.getShortAt(tiffOffset) == 0x4D4D) { + bigEnd = true; + } else { + if (debug) + console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); + return false; + } + + if (file.getShortAt(tiffOffset + 2, bigEnd) != 0x002A) { + if (debug) + console.log("Not valid TIFF data! (no 0x002A)"); + return false; + } + + if (file.getLongAt(tiffOffset + 4, bigEnd) != 0x00000008) { + if (debug) + console.log("Not valid TIFF data! (First offset not 8)", file.getShortAt(tiffOffset + 4, bigEnd)); + return false; + } + + tags = readTags(file, tiffOffset, tiffOffset + 8, TiffTags, bigEnd); + + if (tags.ExifIFDPointer) { + exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd); + for (tag in exifData) { + switch (tag) { + case "LightSource" : + case "Flash" : + case "MeteringMode" : + case "ExposureProgram" : + case "SensingMethod" : + case "SceneCaptureType" : + case "SceneType" : + case "CustomRendered" : + case "WhiteBalance" : + case "GainControl" : + case "Contrast" : + case "Saturation" : + case "Sharpness" : + case "SubjectDistanceRange" : + case "FileSource" : + exifData[tag] = StringValues[tag][exifData[tag]]; + break; + + case "ExifVersion" : + case "FlashpixVersion" : + exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]); + break; + + case "ComponentsConfiguration" : + exifData[tag] = + StringValues.Components[exifData[tag][0]] + + StringValues.Components[exifData[tag][1]] + + StringValues.Components[exifData[tag][2]] + + StringValues.Components[exifData[tag][3]]; + break; + } + tags[tag] = exifData[tag]; + } + } + + if (tags.GPSInfoIFDPointer) { + gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd); + for (tag in gpsData) { + switch (tag) { + case "GPSVersionID" : + gpsData[tag] = gpsData[tag][0] + + "." + gpsData[tag][1] + + "." + gpsData[tag][2] + + "." + gpsData[tag][3]; + break; + } + tags[tag] = gpsData[tag]; + } + } + + return tags; + } + + + function getData(img, callback) { + if (!img.complete) + return false; + if (!imageHasData(img)) { + getImageData(img, callback); + } else { + if (callback) { + callback.call(img); + } + } + return true; + } + + function getTag(img, tag) { + if (!imageHasData(img)) + return; + return img.exifdata[tag]; + } + + function getAllTags(img) { + if (!imageHasData(img)) + return {}; + var a, + data = img.exifdata, + tags = {}; + for (a in data) { + if (data.hasOwnProperty(a)) { + tags[a] = data[a]; + } + } + return tags; + } + + function pretty(img) { + if (!imageHasData(img)) + return ""; + var a, + data = img.exifdata, + strPretty = ""; + for (a in data) { + if (data.hasOwnProperty(a)) { + if (typeof data[a] == "object") { + if (data[a] instanceof Number) { + strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n"; + } else { + strPretty += a + " : [" + data[a].length + " values]\r\n"; + } + } else { + strPretty += a + " : " + data[a] + "\r\n"; + } + } + } + return strPretty; + } + + function readFromBinaryFile(file) { + return findEXIFinJPEG(file); + } + + + return { + readFromBinaryFile: readFromBinaryFile, + pretty: pretty, + getTag: getTag, + getAllTags: getAllTags, + getData: getData, + Tags: ExifTags, + TiffTags: TiffTags, + GPSTags: GPSTags, + StringValues: StringValues + }; + +})(); \ No newline at end of file diff --git a/static/app/js/goodsList.js b/static/app/js/goodsList.js new file mode 100755 index 0000000..46eaa90 --- /dev/null +++ b/static/app/js/goodsList.js @@ -0,0 +1,225 @@ +var msort = 1; +var page = 1; +var condition = 2; +var desc = 0; +var catId; +var keyword; +var isjiazai = 1; +var count = 1; + +function pullupRefresh() { + // setTimeout(function() { + + // mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + + var data_set = { + page: count, + pagesize: 10, + condition: condition, + desc: desc + } + // console.log(order_class) + if(catId) { + data_set.catId = catId; + } else if(keyword) { + data_set.keyword = keyword; + } + + mui.ajax(hyhUrl('app/Goods/pageQuery'), {  + + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').append(html); + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + isjiazai=1; + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + // }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +// function pulldownRefresh() { +// setTimeout(function() { +// window.location.reload(); +// mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed +// }, 1500); +// } +mui.plusReady(function() { + var costnum = 0; + var self = plus.webview.currentWebview(); + catId = self.data_catId; + keyword = self.data_keyword; + + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + count = 1; + $(this).addClass('on').siblings().removeClass('on'); + + condition = $(this).attr('data-condition'); + + if($('#cost_btn').hasClass('on')) { + + costnum += 1; + + if(costnum % 2 == 1) { + + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + + desc = 1; + + } else if(costnum % 2 == 0) { + + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + + desc = 0; + + } + + } else { + + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + + costnum = 0; + desc = 0 + } + + var data = { + pagesize: 10, + page: 1, + condition: condition, + desc: desc + } + if(catId) { + data.catId = catId; + } else if(keyword) { + data.keyword = keyword; + } + + mui.ajax(hyhUrl('app/Goods/pageQuery'), {  + data: data, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').html(html); + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + var data_1 = { + pagesize: 10, + page: 1, + condition: 2, + desc: 0 + } + if(catId) { + data_1.catId = catId; + } else if(keyword) { + data_1.keyword = keyword; + } + mui.ajax(hyhUrl('app/Goods/pageQuery'), {  + data: data_1, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').html(html); + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + $('.cnxh_con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // console.log(scroll.y); + // console.log(scroll.maxScrollY); + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + isjiazai = 0; + pullupRefresh() + } + } + }) + +}) + +// setInterval(function() { +// $('.cnxh_block img').height($('.cnxh_block img').width()); +// $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +// }, 100) \ No newline at end of file diff --git a/static/app/js/home.js b/static/app/js/home.js new file mode 100755 index 0000000..90a777e --- /dev/null +++ b/static/app/js/home.js @@ -0,0 +1,670 @@ +//var myDate = new Date(); +//myDate.setFullYear(2018, 9, 14); +//var today = new Date(); +var activity7 = '' +var timestamp1 = Date.parse( new Date()); +if(timestamp1 >=1536854400000) { + $('.nav_block p').eq(3).html('ECT专区'); + $('.nav_block').eq(3).attr('id', 'activity7.html'); + $('.nav_block img').eq(3).attr('src', 'http://img.juzi199.com/static/app/img/ect.png'); + $('.ssbd').attr('src', 'http://img.juzi199.com/Upload/app/banner/ectbanner.png'); + activity7 = 'activity7.html'; +}else{ + activity7 = 'newuser.html'; +} + +function getCNXH(pageNum, pagesizeNum) { + + var data_cnxh = { + page: pageNum ? pageNum : 1, + pagesize : pagesizeNum ? pagesizeNum : 10 + } + mui.ajax(hyhUrl('app/Index/guess_like'), {  + data: data_cnxh, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + $.each(data.Rows, function() { + // console.log(hyhImgUrl(this.goodsImg)) + html += '<div class="cnxh_block" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name"><o>推荐</o>' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + if(pageNum == 1) { + $('.cnxh_con').html(html); + } else if(pageNum > 1) { + $('.cnxh_con').append(html); + } + $('.cnxh_block img').height($('.cnxh_block img').width()) + } else { + alert(data.msg); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1000); +} +var count = 1; +/** + * 上拉加载具体业务实现 + */ +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh((++count > 50)); //参数为true代表没有更多数据了。 + getCNXH(count, 10) + }, 500); +} + +mui.init({ + pullRefresh: { + container: "#pullrefresh", //下拉刷新容器标识,querySelector能定位的css选择器均可,比如:id、.class等 + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +mui.plusReady(function() { + window.addEventListener('mask', function(e) { //执行刷新 + var mask = mui.createMask(); //callback为用户点击蒙版时自动执行的回调; + mask.show(); //显示遮罩 + }); + + function openAds(item) { + if(item.attr('data-adURL') == '' || item.attr('data-targetType') == 0) { + return; + } + var adURL = item.attr('data-adURL'); + var targetType = ''; + var data_set = {}; + if(item.attr('data-targetType') == 1) { + //商品 + targetType = 'details.html'; + data_set = { + data_id: adURL + } + } else if(item.attr('data-targetType') == 2) { + //商家 + targetType = 'storeout.html'; + if(adURL == 1) { + targetType = 'self_shop.html' + } + data_set = { + shopId: adURL + } + } else if(item.attr('data-targetType') == 3) { + //活动 + targetType = adURL + '.html'; + } + mui.openWindow({ + url: targetType, + id: targetType + adURL, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: data_set, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + getCNXH(1, 10); + mui('.mui-bar-transparent').transparent({ + scroller: "#pullrefresh", + offset: 150, + }); + //秒杀 + var swiper = new Swiper('.time_con .swiper-container', { + pagination: '.time_con .swiper-container .swiper-pagination', + slidesPerView: 4, + paginationClickable: true, + spaceBetween: 6, + freeMode: true + }); + $('#news').html(''); //先把惠员快讯清空 + mui.ajax(hyhUrl('app/Articles/getIndexNews'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(news_data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var news_data = toJson(news_data); + if(news_data.status == 1) { + + news_data = news_data.data; + var news = ''; + $.each(news_data, function() { + // console.log(this.articleTitle) + news += '<a href="#" data-articleId="' + this.articleId + '">' + this.articleTitle + '</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; + + }) + $('#news').html(news); + // $('#news_more').html(''); + //console.log(news); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //广告数据 + var arr1 = ["../img/faxianhaohuo1.png", "../img/huiyuanzhuanhui1.png", "../img/paihangbang.png", "../img/huigou.png", "../img/xinpinshoufa.png", "../img/shangxin.png"] + mui.ajax(hyhUrl('app/Index/getIndexAds'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + var banner1 = ''; + var banner2 = ''; + var html1 = ''; + var html2 = ''; + var html3 = ''; + var o = 0; + //顶部轮播图 + if(data.top_img.length != 0) { + var topBanner1 = '<div class="mui-slider-group mui-slider-loop"><div data-targetType="' + data.top_img[data.top_img.length - 1].targetType + '" data-adURL="' + data.top_img[data.top_img.length - 1].adURL + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.top_img[data.top_img.length - 1].adFile) + '"></a></div>'; + var topBanner2 = '<div class="mui-slider-indicator">'; + $.each(data.top_img, function() { + topBanner1 += '<div data-targetType="' + this.targetType + '" data-adURL="' + this.adURL + '" class="mui-slider-item "><a href="#"><img src="' + hyhImgUrl(this.adFile) + '"></a></div>' + topBanner2 += '<div class="mui-indicator"></div>' + }) + topBanner2 += '</div>' + topBanner1 += '<div data-targetType="' + data.top_img[0].targetType + '" data-adURL="' + data.top_img[0].adURL + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.top_img[0].adFile) + '"></a></div></div>' + topBanner1 += topBanner2; + $('#slider').html(topBanner1); + $('.mui-slider-item a img').height($('.mui-slider-item a img').width() * 188 / 375) + $('#slider').height($('.mui-slider-item a img').width() * 188 / 375) + mui("#slider").slider({ + interval: 5000 + }); + document.getElementsByClassName('mui-indicator')[0].className += ' mui-active'; + } + + //广告区banner + $.each(data.cross_img.cross_top, function() { + banner1 += '<div class="swiper-slide" data-targetType="' + this.targetType + '" data-adURL="' + this.adURL + '"><img src="' + hyhImgUrl(this.adFile) + '" /></div>'; + + }); + $('.banner .swiper-container .swiper-wrapper').html(banner1); + //banner1 + var swiper = new Swiper('.banner .swiper-container', { + pagination: '.banner .swiper-container .swiper-pagination', + slidesPerView: 1, + centeredSlides: true, + paginationClickable: true, + spaceBetween: 6, + grabCursor: true + }); + $.each(data.cross_img.cross_bottom, function() { + banner2 += '<div class="swiper-slide" data-targetType="' + this.targetType + '" data-adURL="' + this.adURL + '"><img src="' + hyhImgUrl(this.adFile) + '" /></div>'; + }); + + $('.banner1 .swiper-container .swiper-wrapper').html(banner2); + //banner2 + var swiper = new Swiper('.banner1 .swiper-container', { + pagination: '.banner1 .swiper-container .swiper-pagination', + slidesPerView: 1, + centeredSlides: true, + paginationClickable: true, + spaceBetween: 6, + grabCursor: true + }); + + $('.banner .swiper-container .swiper-wrapper .swiper-slide img').height($('.banner .swiper-container .swiper-wrapper .swiper-slide img').width() * 162 / 600); + $('.banner1 .swiper-container .swiper-wrapper .swiper-slide img').height($('.banner .swiper-container .swiper-wrapper .swiper-slide img').width() * 162 / 600); + + var adsArr = []; + for(var i in data.ads) { + adsArr.push(data.ads[i]); + } + $('.box_1').each(function(num) { + $(this).children('p').html(adsArr[num].name); + $(this).children('.boxcon').children('img').eq(0).attr('src', hyhImgUrl(adsArr[num].list[0].adFile ? adsArr[num].list[0].adFile : '')); + $(this).children('.boxcon').children('img').eq(0).attr('data-adURL', adsArr[num].list[0].adURL ? adsArr[num].list[0].adURL : ''); + $(this).children('.boxcon').children('img').eq(0).attr('data-targetType', adsArr[num].list[0].targetType ? adsArr[num].list[0].targetType : ''); + $(this).children('.boxcon').children('img').eq(1).attr('src', hyhImgUrl(adsArr[num].list[1].adFile ? adsArr[num].list[1].adFile : '')); + $(this).children('.boxcon').children('img').eq(1).attr('data-adURL', adsArr[num].list[1].adURL ? adsArr[num].list[1].adURL : ''); + $(this).children('.boxcon').children('img').eq(1).attr('data-targetType', adsArr[num].list[1].targetType ? adsArr[num].list[1].targetType : ''); + + }) + $('.pzss1').each(function(num) { + $(this).children('.p1').html(adsArr[num + 6].name.slice(0, 4)); + $(this).children('.p2').html(adsArr[num + 6].name.slice(4)); + var adsList = adsArr[num + 6].list; + if(adsList.length == 0) { + adsList.push({ + "adFile": "", + "adURL": "", + "targetType": 0 + }); + adsList.push({ + "adFile": "", + "adURL": "", + "targetType": 0 + }); + } else if(adsList.length == 1) { + adsList.push({ + "adFile": "", + "adURL": "", + "targetType": 0 + }); + } + + $(this).children('.boxcon').children('img').eq(0).attr('src', hyhImgUrl(adsList[0].adFile)); + $(this).children('.boxcon').children('img').eq(0).attr('data-adURL', adsList[0].adURL); + $(this).children('.boxcon').children('img').eq(0).attr('data-targetType', adsList[0].targetType); + $(this).children('.boxcon').children('img').eq(1).attr('src', hyhImgUrl(adsList[1].adFile)); + $(this).children('.boxcon').children('img').eq(1).attr('data-adURL', adsList[1].adURL); + $(this).children('.boxcon').children('img').eq(1).attr('data-targetType', adsList[1].targetType); + }) + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + $('.msg').on('tap', function() { + mui.openWindow({ + url: 'journalism.html', + id: 'journalism.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui(".cnxh_con").on('tap', '.cnxh_block', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-id"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui(".nav").on('tap', '.nav_block', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var url = this.attributes["id"].nodeValue; + //品牌街跳转 + if(url == 'activity4.html') { + mui.openWindow({ + url: 'self_shop.html', + id: 'self_shop.html' + 1, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: 1 + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + return; + } + + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('#keyword').on('focus', function() { + $(".search button").css('display', 'block'); + }) + $('#keyword').on('blur', function() { + $(".search button").css('display', 'none'); + }) + $(".search button").on('tap', function() { + var searchName = $('#keyword').val(); + var url = ''; + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + // console.log($('.search select').val()) + if($('.search select').val() == 0) { + url = 'goodsList.html'; + } else if($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if(keycode == '13') { + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + // console.log($('.search select').val()) + if($('.search select').val() == 0) { + url = 'goodsList.html'; + } else if($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + $("body").on('tap', '.ssbd', function() { + + + mui.openWindow({ + url: activity7, + id: activity7, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }); + //首页广告跳转 + $('.boxcon').on('tap', 'img', function() { + openAds($(this)); + }) + //轮播图跳转 + $('#slider').on('tap', '.mui-slider-item', function() { + openAds($(this)); + }) + //banner跳转 + $('.banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + $('.banner1').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + + //3.8活动页 + // var btnArray = ['否', '是']; + // mui.confirm('跳转到3.8女神节活动页?', '合源惠商城', btnArray, function(e) { + // if(e.index == 1) { + // mui.openWindow({ + // url: 'activity7.html', + // id: 'activity7.html', + // show: { + // aniShow: 'none' + // }, + // waiting: { + // autoShow: false + // } + // }) + // } else { + // + // } + // }) + var isZz = localStorage.getItem('isZz') ? localStorage.getItem('isZz') : 1; + + if(isZz == 1) { + localStorage.setItem('isZz', 0); + + $('body').append('<div class="mui-backdrop"><img src="http://img.juzi199.com/upload/sysconfigs/tanchuang.png"/></div>'); + + } + $('body').on('tap', '.mui-backdrop', function() { + $(this).css('display', 'none'); + mui.openWindow({ + url: 'newuser.html', + id: 'newuser.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/indent.js b/static/app/js/indent.js new file mode 100755 index 0000000..ac460e78 --- /dev/null +++ b/static/app/js/indent.js @@ -0,0 +1,32 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_href = self.data_href; + if(data_href == 'all') { + $('#nav2').html('全部订单'); + + } + if(data_href == 'waitPay') { + $('#nav2').html('待付款'); + } + if(data_href == 'waitDeliver') { + $('#nav2').html('待发货'); + } + if(data_href == 'waitReceive') { + $('#nav2').html('待收货'); + } + if(data_href == 'waitAppraise') { + $('#nav2').html('待评价'); + } + if(data_href == 'abnormal') { + $('#nav2').html('退款/售后'); + } + localStorage.setItem('order_class', data_href); + var sub = plus.webview.create('indentcon.html', 'indentcon.html', { + top: '66px', + bottom: '0px', + scrollIndicator: 'none' + }); + self.append(sub); + +}) \ No newline at end of file diff --git a/static/app/js/indentcon.js b/static/app/js/indentcon.js new file mode 100755 index 0000000..3457e4a --- /dev/null +++ b/static/app/js/indentcon.js @@ -0,0 +1,916 @@ +$('#content').after('<div class="tui"></div>'); + +var pay_name = 0; +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + var order_class = localStorage.getItem('order_class'); + var token = localStorage.getItem('token'); + // console.log(order_class) + if(order_class == 'all') { + order_class = ''; + } + mui.ajax(hyhUrl('app/Orders/getOrderList'), {  + headers: {  + "HYH-Token": token + }, + data: { + type: order_class, + page: count, + pagesize : 5 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.data.Rows, function() { + this.pay_name = 1; + html += '<div class="row" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + '"><div class="row_title"><div class="store_name">' + this.shopName + '</div><div class="indent_status">' + this.status + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>'; + }) + html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if(this.orderStatus == -2) { + html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if(this.orderStatus == 0) { + if(this.noticeDeliver == 0) { + html += '<div class="btns_btn txfh" style="display:none;">提醒发货</div><div class="btns_btn qxdd">取消订单</div>'; + } else { + html += '<div class="btns_btn " style="display:none;">已提醒</div><div class="btns_btn qxdd">取消订单</div>'; + } + + } else if(this.orderStatus == 1) { + html += '<div class="btns_btn qrsh">确认收货</div><div class="btns_btn ckwl">查看物流</div><div class="btns_btn qxdd_js" >拒收</div>'; + } else if(this.orderStatus == 2) { + if(this.isAppraise == 0) { + html += '<div class="btns_btn ljpj" >立即评价</div>'; + } else { + html += '<div class="btns_btn qxdd_js">查看评价</div>'; + } + + } + if(this.orderStatus != 1 && this.orderStatus != -2 && this.isComplain == 0) { + html += '<div class="btns_btn tsdd" >投诉</div>'; + } + if(this.allowRefund == 1 && (this.orderStatus == -1 || this.orderStatus == -3)) { + html += '<div class="btns_btn sqtk" >申请退款</div>'; + } + html += '</div></div>' + }) + $('.con').append(html); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + } + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var order_class = localStorage.getItem('order_class'); + var token = localStorage.getItem('token'); + var orderNo; + var orderId; + var getReasonUrl = ''; + var priceT = 0; + var payCode = ''; + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + }); + //支付插件 + plus.payment.getChannels(function(channels) { + for(var i in channels) { + if(channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=0&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if(id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if(id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch(xhr.readyState) { + case 4: + if(xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + var targetTab = plus.webview.getWebviewById("templete/my.html"); + mui.fire(targetTab, 'refresh'); + location.reload(); + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + // plus.webview.getWebviewById('confirmOrder.html').close() + }); + } else { + alert("获取订单信息失败!"); + console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + mui.ajax(hyhUrl('/app/Users/get_name_and_money'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + + if(data.status == 1) { + $('#loginName').html(data.data.name); + $('.userMoney').html(data.data.money); + var htmlpay = '<div class="row clearfix select_payway" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.data.userECT + '</o></p></div>'; + $('.pay_info .con_1').append(htmlpay); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + }) + $('.con').on('tap', '.ljfk', function() { + var that = $(this); + pay_name = $(this).attr('data-payName'); + priceT = $(this).parent().siblings('.combination').children('o').html().slice(1); + $('#goodsTotalMoney').html($(this).parent().siblings('.combination').children('o').html()) + orderNo = $(this).parent().parent().attr('data-orderNo'); + if(pay_name == 1) { + $('.pay_info .con_1 .row').eq(1).attr('style', 'display: none;'); + $('.pay_info .con_1 .row').eq(2).addClass('on'); + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/ect/getToEctNum'), {  + + data: { + total_money: priceT + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒; + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + if(data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if(e.index == 1) { + return; + } else { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } + that.removeAttr('disabled'); + }) + } else { + alert(data.msg); + that.removeAttr('disabled'); + return; + } + + } + }) + } else { + $('.pay_info .con_1 .row').eq(1).addClass('on'); + $('.pay_info .con_1 .row').eq(2).attr('style', 'display: none;'); + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.con_1 .on .row_right o').html($(this).children('.row_left').html()); + $('.con_1 .on').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + + }) + $('.pay').on('tap', '.con_1 .on', function() { + if($(this).attr('data-payCode') == 'ect') { + + } else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + } + + }) + $('.pay_btn').on('tap', function() { + payCode = $('.con_1 .on').attr('data-payCode'); + var that = $(this); + var data_ljfk = { + isBatch: 0, + orderNo: orderNo + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/orders/succeed'), {  + data: data_ljfk, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + + if(data.status == 1) { + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: orderNo, + isBatch: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', orderNo); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + }) + }) + $('#pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('#pay_pwd').on('tap', '.pay_btn_pwd', function() { + + var payPwd = $('#payPwd').val(); + if(payPwd == '') { + alert('支付密码不能为空!'); + } + var that = $(this); + that.attr('disabled', 'disabled') + var srcc = '' + if(payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + + mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), {  + + data: { + orderNo: orderNo, + isBatch: 0, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + alert(data.msg) + if(data.status == 1) { + var targetTab = plus.webview.getWebviewById("templete/my.html"); + mui.fire(targetTab, 'refresh'); + location.reload(); + } else { + + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + }) + + // console.log(order_class) + if(order_class == 'all') { + order_class = ''; + } + mui.ajax(hyhUrl('app/Orders/getOrderList'), {  + headers: {  + "HYH-Token": token + }, + data: { + type: order_class, + page: 1, + pagesize : 5 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + var html = '' + $.each(data.data.Rows, function() { + this.pay_name = 1; + html += '<div class="row" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + '"><div class="row_title"><div class="store_name">' + this.shopName + '</div><div class="indent_status">' + this.status + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>'; + }) + html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if(this.orderStatus == -2) { + html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if(this.orderStatus == 0) { + if(this.noticeDeliver == 0) { + html += '<div class="btns_btn txfh" style="display:none;">提醒发货</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else { + html += '<div class="btns_btn " style="display:none;">已提醒</div><div class="btns_btn qxdd_js">取消订单</div>'; + } + + } else if(this.orderStatus == 1) { + html += '<div class="btns_btn qrsh">确认收货</div><div class="btns_btn ckwl">查看物流</div><div class="btns_btn qxdd_js" >拒收</div>'; + } else if(this.orderStatus == 2) { + if(this.isAppraise == 0) { + html += '<div class="btns_btn ljpj" >立即评价</div>'; + } else { + html += '<div class="btns_btn ckpj">查看评价</div>'; + } + + } + if(this.orderStatus != 1 && this.orderStatus != -2 && this.isComplain == 0) { + html += '<div class="btns_btn tsdd" >投诉</div>'; + } + if(this.allowRefund == 1 && (this.orderStatus == -1 || this.orderStatus == -3)) { + html += '<div class="btns_btn qxdd_js" >申请退款</div>'; + } + + html += '</div></div>' + }) + + $('.con').append(html); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.row_con', function() { + var data_order_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'order_out.html', + id: 'order_out.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.ckwl', function() { + var data_order_id = $(this).parent().parent().attr('data-id'); //$(this).attr('data-id'); + mui.openWindow({ + url: 'logistics.html', + id: 'logistics.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.con').on('tap', '.qxdd_js', function() { + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if($(this).html() == '取消订单') { + getReasonUrl = 'getCancelCause'; + } else if($(this).html() == '拒收') { + getReasonUrl = 'getRejectCause'; + } else if($(this).html() == '申请退款') { + getReasonUrl = 'getRefundCause'; + mui.ajax(hyhUrl('/app/Orders/getRefund'), {  + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = '<input type="text" name="Tmoney" id="Tmoney" value="" placeholder="请输入退款金额"/><p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + '</o>)</p><p class="info1">(' + data.useScore + '个惠宝抵扣<o>¥' + data.scoreMoney + '</o>)</p>'; + $('.tui').html(html) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + $('.bg_').css('display', 'block'); + $('.bg_con').css('display', 'none'); + $('.bg_con').slideDown(300, function() {}); + + mui.ajax(hyhUrl('/app/Orders/' + getReasonUrl), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + var html = '<option value="0">未选择</option>'; + $.each(data.data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>' + }); + $('#select').html(html) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + + $('.bg_').on('tap', '.en_false', function() { + $('.bg_').css('display', 'none'); + + }) + $('.bg_').on('tap', '.en_true', function() { + var setReasonUrl = ''; + var content = $('#content').val(); + var reason = $('#select').val(); + if($('#select').val() == 0) { + alert('请选择原因!'); + return; + } + if($('#select').val() == 10000 && content == '') { + alert('请输入其他原因!'); + return; + } + if(getReasonUrl == 'getCancelCause') { + setReasonUrl = 'cancellation'; + mui.ajax(hyhUrl('app/Orders/' + setReasonUrl), {  + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } else if(getReasonUrl == 'getRejectCause') { + setReasonUrl = 'reject'; + mui.ajax(hyhUrl('app/Orders/' + setReasonUrl), {  + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } else if(getReasonUrl == 'getRefundCause') { + var money = $('#Tmoney').val(); + if(money < 0 || money == 0) { + alert('退款金额不能为0!'); + return; + } else { + mui.ajax(hyhUrl('app/Orderrefunds/refund'), {  + data: { + reason: reason, + id: orderId, + content: content, + money: money + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + + } + + }) + $('.con').on('tap', '.qrsh', function() { + // $('.bg_').css('display', 'block'); + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if(confirm('确认收货?')) { + mui.ajax(hyhUrl('/app/Orders/receive'), {  + headers: {  + "HYH-Token": token + }, + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + + }) + $('#select').on('change', function() { + if($(this).val() == '10000') { + $('#content').css('display', 'block'); + } else { + $('#content').css('display', 'none'); + } + }) + //跳转到评价 + mui('.con').on('tap', '.ljpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.ckpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.tsdd', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'complain.html', + id: 'complain.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/index.js b/static/app/js/index.js new file mode 100755 index 0000000..e46b68b --- /dev/null +++ b/static/app/js/index.js @@ -0,0 +1,109 @@ +var wgtVer = null; +alert("11111111") +console.log("1111111111"); +function plusReady() { // 获取本地应用资源版本号 + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + wgtVer = inf.version; + }); +} +//休眠方法 +var ver; +//获取数据 + +function sleep(numberMillis) { + var now = new Date(); + var exitTime = now.getTime() + numberMillis; + while(true) { + now = new Date(); + if(now.getTime() > exitTime) + return; + } +} + +function init(data) { + localStorage.setItem('version', data.version ? data.version : "版本号无"); + localStorage.setItem('cssUrl', data.cssUrl ? data.cssUrl:"../css/"); + localStorage.setItem('jsUrl', data.jsUrl ? data.jsUrl:"../js/"); + // console.log(data.apk_version) + // console.log(localStorage.getItem('jsUrl')) + apk_version = data.apk_version; + apkUrl = data.apk_down_url; + iosUrl = data.ios_down_url; + var must_update = data.must_update; + var ios_must_update = data.ios_must_update; + mui.plusReady(function() { + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + ver = inf.version; + var client; + var ua = navigator.userAgent.toLowerCase(); + if(/iphone|ipad|ipod/.test(ua)) { //苹果手机 + + $.ajax({ + type: "get", + dataType: 'json', + url: data.update_url, //获取当前上架APPStore版本信息 + data: { + id: data.ios_appid //APP唯一标识ID + }, + contentType: 'application/x-www-form-urlencoded;charset=UTF-8', + success: function(data) { + + if(data.results[0].version > ver) { + if(ios_must_update == 0) { + if(confirm("发现新版本:V" + data.results[0].version + "是否更新")) { + document.location.href = iosUrl; //上新APPStore下载地址 + } + } else { + alert("发现新版本:V" + data.results[0].version + "是否更新") + document.location.href = iosUrl; //上新APPStore下载地址 + } + + } else { + + } + } + }); + } else if(/android/.test(ua)) { + + if(apk_version != ver) { + if(must_update == 0) { + if(confirm("发现新版本:V" + apk_version + "是否更新")) { + var dtask = plus.downloader.createDownload(apkUrl, {}, function(d, status) { + if(status == 200) { + plus.nativeUI.toast("正在准备环境,请稍后!"); + sleep(1000); + var path = d.filename; //下载apk + plus.runtime.install(path); // 自动安装apk文件 + } else { + alert('版本更新失败:' + status); + } + }); + dtask.start(); + } + } else { + if(confirm("发现新版本:V" + apk_version + "是否更新")) { + var dtask = plus.downloader.createDownload(apkUrl, {}, function(d, status) { + if(status == 200) { + plus.nativeUI.toast("正在准备环境,请稍后!"); + sleep(1000); + var path = d.filename; //下载apk + plus.runtime.install(path); // 自动安装apk文件 + } else { + alert('版本更新失败:' + status); + } + }); + dtask.start(); + } else { + plus.runtime.quit(); + } + } + + } else { + // console.log('当前版本号已是最新'); + return; + } + } + + }) + }) +}; \ No newline at end of file diff --git a/static/app/js/journalism.js b/static/app/js/journalism.js new file mode 100755 index 0000000..4d3f887 --- /dev/null +++ b/static/app/js/journalism.js @@ -0,0 +1,99 @@ +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + var num = 1; + var isOver = 1; + + function getMsg(pageNum, pagesizeNum) { + + var data_msg = { + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + mui.ajax(hyhUrl('app/Articles/getNewsList'), {  + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + data = data.data; + if(data.Rows == '') { + $('.con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + return; + } + $.each(data.Rows, function() { + var display = '' + if(this.coverImg==''){ + display='none'; + }else{ + display='block'; + } + html += '<div class="block" data-articleId="'+ this.articleId +'"><p>'+ this.articleTitle +'</p><img style="display:'+ display +'" src="'+ hyhImgUrl(this.coverImg) +'"/><span><o></o>'+ this.createTime +'</span></div>' + }); + + if(pageNum == 1) { + $('.con').html(html); + } else if(pageNum > 1) { + $('.con').append(html); + } + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + } + getMsg(1, 10); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + isOver=0; + num += 1; + getMsg(num, 10); + } + } + }) + $('.con').on('tap', '.block', function() { + var id = $(this).attr('data-articleId'); + mui.openWindow({ + url: 'journalism_con.html', + id: 'journalism_con.html'+id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_articleId: id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/journalism_con.js b/static/app/js/journalism_con.js new file mode 100755 index 0000000..e8ad354 --- /dev/null +++ b/static/app/js/journalism_con.js @@ -0,0 +1,28 @@ +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var msgId = self.data_articleId; + mui.ajax(chengUrl('app/Articles/showArticle/'), {  + + data: { + articleId: msgId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data,1); + + if(data.status == 1) { + data = data.data; + var html = '<div class="time">'+ data.articleTitle +'</div><div class="con_">'+ data.articleContent +'</div>'; + $('.con').html(html) + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +}) \ No newline at end of file diff --git a/static/app/js/jquery-3.2.1.min.js b/static/app/js/jquery-3.2.1.min.js new file mode 100755 index 0000000..644d35e --- /dev/null +++ b/static/app/js/jquery-3.2.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/static/app/js/login.js b/static/app/js/login.js new file mode 100755 index 0000000..22e139a --- /dev/null +++ b/static/app/js/login.js @@ -0,0 +1,136 @@ +mui.init({ + beforeback: function() {     //获得父页面的webview + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + + mui('.down').on('tap', '.btn', function() { + + var loginName = $('#loginName').val(); + + var loginPwd = $('#loginPwd').val(); + + if(loginName == '') { + + alert('用户名不能为空!'); + + return; + + } + + if(loginPwd == '') { + + alert('密码不能为空!'); + + return; + } + + // var loginName = 'zxcvbn'; + // var loginPwd = 'zxcvbn'; + $('.btn').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/checkLogin'), {  + data: { + loginName: loginName, + loginPwd: loginPwd, + nameType: 3 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + + if(data.status == 1) { + var token = data.data.token; + localStorage.setItem('token', token); + //console.log(data.data.token); + mui.back(); + return; + } else { + alert(data.msg); + } + + $('.btn').removeAttr('disabled'); + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + });  + }) + mui('.down').on('tap', '#register', function() { + + mui.openWindow({ + url: 'register.html', + id: 'register.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + mui('.down').on('tap', '#fogetpsd', function() { + + mui.openWindow({ + url: 'setting_fogetPwd.html', + id: 'setting_fogetPwd.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + +}) \ No newline at end of file diff --git a/static/app/js/logistics.js b/static/app/js/logistics.js new file mode 100755 index 0000000..02b9e92 --- /dev/null +++ b/static/app/js/logistics.js @@ -0,0 +1,14 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + localStorage.setItem('data_order_id', data_order_id); + var sub = plus.webview.create('logisticscon.html', 'logisticscon.html', { + top: '66px', + bottom: '0', + scrollIndicator: 'none' + }); + self.append(sub); + + +}) \ No newline at end of file diff --git a/static/app/js/logisticscon.js b/static/app/js/logisticscon.js new file mode 100755 index 0000000..7e28ea4 --- /dev/null +++ b/static/app/js/logisticscon.js @@ -0,0 +1,44 @@ +mui.plusReady(function() { + var data_order_id = localStorage.getItem('data_order_id'); + var token = localStorage.getItem('token'); + mui.ajax(hyhUrl('app/Orders/findExpress'), {  + + data: { + orderId: data_order_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 200 || data.status == 1) { + var data_ = data.data; + var html = '<div class="summarize clearfix"><img src="" /><div class="summarizeinfo"><p class="pp1">物流状态: <o>' + data.express.stateTxt + '</o></p><p class="pp2">承运来源:' + data.express.expressName + '</p><p class="pp2">运单编号:' + data.express.expressNo + '</p></p></div></div><div class="track-list"><ul>'; + + if(data.data.length > 1) { + var d_1 = data.data[0].time; + var d_2 = data.data[data.data.length-1].time; + var e_1 = new Date(d_1).getTime(); + var e_2 = new Date(d_2).getTime(); + if (e_1<e_2){ + data_.reverse(); + } + } + + $.each(data_, function() { + html += '<li><i class="node-icon"></i><p class="txt">' + this.context + '</p><p class="time">' + this.time + '</p></li>' + }); + html += '</ul></div>' + $('.con').html(html); + document.getElementsByTagName('li')[0].className = 'first'; + } else { + // alert(data.status); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + +}) \ No newline at end of file diff --git a/static/app/js/msg.js b/static/app/js/msg.js new file mode 100755 index 0000000..590083c --- /dev/null +++ b/static/app/js/msg.js @@ -0,0 +1,102 @@ +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + var token = localStorage.getItem('token'); + var num = 1; + var isOver = 1; + + function getMsg(pageNum, pagesizeNum) { + if(isOver == 1) { + isOver = 0; + } else { + return; + } + var data_msg = { + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + var arr = ["普通消息", "订单", "商品", "订单投诉", "结算信息", "提现信息", "订单评价"] + mui.ajax(hyhUrl('app/messages/msglist'), {  + headers: {  + "HYH-Token": token + }, + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + data = data.data; + if(data.Rows == '') { + $('.con1').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多消息</p>'); + + return; + } + $.each(data.Rows, function() { + html += '<div class="row clearfix" data-id="' + this.id + '"><div class="img"><img src="' + hyhImgUrl(this.img) + '" /></div><div class="r_right"><div class="r_r_top clearfix"><p class="rrt_left">' + arr[this.from] + '</p><p class="rrt_right">' + this.createTime + '</p></div><div class="r_r_con">' + this.msgContent + '</div></div></div>' + }); + + if(pageNum == 1) { + $('.con1').html(html) + } else if(pageNum > 1) { + $('.con1').append(html) + } + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + } + getMsg(1, 10); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num += 1; + getMsg(num, 10); + } + } + }) + $('.con1').on('tap', '.row', function() { + var id = $(this).attr('data-id'); + mui.openWindow({ + url: 'msg_con.html', + id: 'msg_con.html'+id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_msgId: id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/msg_con.js b/static/app/js/msg_con.js new file mode 100755 index 0000000..8f576a9 --- /dev/null +++ b/static/app/js/msg_con.js @@ -0,0 +1,31 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var msgId = self.data_msgId; + mui.ajax(hyhUrl('app/messages/getById'), {  + headers: {  + "HYH-Token": token + }, + data: { + msgId: msgId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + + if(data.status == 1) { + data = data.data; + var html = '<div class="time">' + data.createTime + '</div><div class="con_">' + data.msgContent + '</div>'; + $('.con').html(html) + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +}) \ No newline at end of file diff --git a/static/app/js/mui.js b/static/app/js/mui.js new file mode 100755 index 0000000..4033754 --- /dev/null +++ b/static/app/js/mui.js @@ -0,0 +1,8303 @@ +/*! + * ===================================================== + * Mui v3.7.0 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ +/** + * MUI核心JS + * @type _L4.$|Function + */ +var mui = (function(document, undefined) { + var readyRE = /complete|loaded|interactive/; + var idSelectorRE = /^#([\w-]+)$/; + var classSelectorRE = /^\.([\w-]+)$/; + var tagSelectorRE = /^[\w-]+$/; + var translateRE = /translate(?:3d)?\((.+?)\)/; + var translateMatrixRE = /matrix(3d)?\((.+?)\)/; + + var $ = function(selector, context) { + context = context || document; + if (!selector) + return wrap(); + if (typeof selector === 'object') + if ($.isArrayLike(selector)) { + return wrap($.slice.call(selector), null); + } else { + return wrap([selector], null); + } + if (typeof selector === 'function') + return $.ready(selector); + if (typeof selector === 'string') { + try { + selector = selector.trim(); + if (idSelectorRE.test(selector)) { + var found = document.getElementById(RegExp.$1); + return wrap(found ? [found] : []); + } + return wrap($.qsa(selector, context), selector); + } catch (e) {} + } + return wrap(); + }; + + var wrap = function(dom, selector) { + dom = dom || []; + Object.setPrototypeOf(dom, $.fn); + dom.selector = selector || ''; + return dom; + }; + + $.uuid = 0; + + $.data = {}; + /** + * extend(simple) + * @param {type} target + * @param {type} source + * @param {type} deep + * @returns {unresolved} + */ + $.extend = function() { //from jquery2 + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + if (typeof target === "boolean") { + deep = target; + + target = arguments[i] || {}; + i++; + } + + if (typeof target !== "object" && !$.isFunction(target)) { + target = {}; + } + + if (i === length) { + target = this; + i--; + } + + for (; i < length; i++) { + if ((options = arguments[i]) != null) { + for (name in options) { + src = target[name]; + copy = options[name]; + + if (target === copy) { + continue; + } + + if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && $.isArray(src) ? src : []; + + } else { + clone = src && $.isPlainObject(src) ? src : {}; + } + + target[name] = $.extend(deep, clone, copy); + + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + return target; + }; + /** + * mui noop(function) + */ + $.noop = function() {}; + /** + * mui slice(array) + */ + $.slice = [].slice; + /** + * mui filter(array) + */ + $.filter = [].filter; + + $.type = function(obj) { + return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object"; + }; + /** + * mui isArray + */ + $.isArray = Array.isArray || + function(object) { + return object instanceof Array; + }; + /** + * mui isArrayLike + * @param {Object} obj + */ + $.isArrayLike = function(obj) { + var length = !!obj && "length" in obj && obj.length; + var type = $.type(obj); + if (type === "function" || $.isWindow(obj)) { + return false; + } + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && (length - 1) in obj; + }; + /** + * mui isWindow(需考虑obj为undefined的情况) + */ + $.isWindow = function(obj) { + return obj != null && obj === obj.window; + }; + /** + * mui isObject + */ + $.isObject = function(obj) { + return $.type(obj) === "object"; + }; + /** + * mui isPlainObject + */ + $.isPlainObject = function(obj) { + return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype; + }; + /** + * mui isEmptyObject + * @param {Object} o + */ + $.isEmptyObject = function(o) { + for (var p in o) { + if (p !== undefined) { + return false; + } + } + return true; + }; + /** + * mui isFunction + */ + $.isFunction = function(value) { + return $.type(value) === "function"; + }; + /** + * mui querySelectorAll + * @param {type} selector + * @param {type} context + * @returns {Array} + */ + $.qsa = function(selector, context) { + context = context || document; + return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector)); + }; + /** + * ready(DOMContentLoaded) + * @param {type} callback + * @returns {_L6.$} + */ + $.ready = function(callback) { + if (readyRE.test(document.readyState)) { + callback($); + } else { + document.addEventListener('DOMContentLoaded', function() { + callback($); + }, false); + } + return this; + }; + /** + * 将 fn 缓存一段时间后, 再被调用执行 + * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中; + * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样; + * 调用返回函数的 stop 停止最后一次的 buffer 效果 + * @param {Object} fn + * @param {Object} ms + * @param {Object} context + */ + $.buffer = function(fn, ms, context) { + var timer; + var lastStart = 0; + var lastEnd = 0; + var ms = ms || 150; + + function run() { + if (timer) { + timer.cancel(); + timer = 0; + } + lastStart = $.now(); + fn.apply(context || this, arguments); + lastEnd = $.now(); + } + + return $.extend(function() { + if ( + (!lastStart) || // 从未运行过 + (lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒 + (lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒 + ) { + run.apply(this, arguments); + } else { + if (timer) { + timer.cancel(); + } + timer = $.later(run, ms, null, $.slice.call(arguments)); + } + }, { + stop: function() { + if (timer) { + timer.cancel(); + timer = 0; + } + } + }); + }; + /** + * each + * @param {type} elements + * @param {type} callback + * @returns {_L8.$} + */ + $.each = function(elements, callback, hasOwnProperty) { + if (!elements) { + return this; + } + if (typeof elements.length === 'number') { + [].every.call(elements, function(el, idx) { + return callback.call(el, idx, el) !== false; + }); + } else { + for (var key in elements) { + if (hasOwnProperty) { + if (elements.hasOwnProperty(key)) { + if (callback.call(elements[key], key, elements[key]) === false) return elements; + } + } else { + if (callback.call(elements[key], key, elements[key]) === false) return elements; + } + } + } + return this; + }; + $.focus = function(element) { + if ($.os.ios) { + setTimeout(function() { + element.focus(); + }, 10); + } else { + element.focus(); + } + }; + /** + * trigger event + * @param {type} element + * @param {type} eventType + * @param {type} eventData + * @returns {_L8.$} + */ + $.trigger = function(element, eventType, eventData) { + element.dispatchEvent(new CustomEvent(eventType, { + detail: eventData, + bubbles: true, + cancelable: true + })); + return this; + }; + /** + * getStyles + * @param {type} element + * @param {type} property + * @returns {styles} + */ + $.getStyles = function(element, property) { + var styles = element.ownerDocument.defaultView.getComputedStyle(element, null); + if (property) { + return styles.getPropertyValue(property) || styles[property]; + } + return styles; + }; + /** + * parseTranslate + * @param {type} translateString + * @param {type} position + * @returns {Object} + */ + $.parseTranslate = function(translateString, position) { + var result = translateString.match(translateRE || ''); + if (!result || !result[1]) { + result = ['', '0,0,0']; + } + result = result[1].split(","); + result = { + x: parseFloat(result[0]), + y: parseFloat(result[1]), + z: parseFloat(result[2]) + }; + if (position && result.hasOwnProperty(position)) { + return result[position]; + } + return result; + }; + /** + * parseTranslateMatrix + * @param {type} translateString + * @param {type} position + * @returns {Object} + */ + $.parseTranslateMatrix = function(translateString, position) { + var matrix = translateString.match(translateMatrixRE); + var is3D = matrix && matrix[1]; + if (matrix) { + matrix = matrix[2].split(","); + if (is3D === "3d") + matrix = matrix.slice(12, 15); + else { + matrix.push(0); + matrix = matrix.slice(4, 7); + } + } else { + matrix = [0, 0, 0]; + } + var result = { + x: parseFloat(matrix[0]), + y: parseFloat(matrix[1]), + z: parseFloat(matrix[2]) + }; + if (position && result.hasOwnProperty(position)) { + return result[position]; + } + return result; + }; + $.hooks = {}; + $.addAction = function(type, hook) { + var hooks = $.hooks[type]; + if (!hooks) { + hooks = []; + } + hook.index = hook.index || 1000; + hooks.push(hook); + hooks.sort(function(a, b) { + return a.index - b.index; + }); + $.hooks[type] = hooks; + return $.hooks[type]; + }; + $.doAction = function(type, callback) { + if ($.isFunction(callback)) { //指定了callback + $.each($.hooks[type], callback); + } else { //未指定callback,直接执行 + $.each($.hooks[type], function(index, hook) { + return !hook.handle(); + }); + } + }; + /** + * setTimeout封装 + * @param {Object} fn + * @param {Object} when + * @param {Object} context + * @param {Object} data + */ + $.later = function(fn, when, context, data) { + when = when || 0; + var m = fn; + var d = data; + var f; + var r; + + if (typeof fn === 'string') { + m = context[fn]; + } + + f = function() { + m.apply(context, $.isArray(d) ? d : [d]); + }; + + r = setTimeout(f, when); + + return { + id: r, + cancel: function() { + clearTimeout(r); + } + }; + }; + $.now = Date.now || function() { + return +new Date(); + }; + var class2type = {}; + $.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) { + class2type["[object " + name + "]"] = name.toLowerCase(); + }); + if (window.JSON) { + $.parseJSON = JSON.parse; + } + /** + * $.fn + */ + $.fn = { + each: function(callback) { + [].every.call(this, function(el, idx) { + return callback.call(el, idx, el) !== false; + }); + return this; + } + }; + + /** + * 兼容 AMD 模块 + **/ + if (typeof define === 'function' && define.amd) { + define('mui', [], function() { + return $; + }); + } + + return $; +})(document); +//window.mui = mui; +//'$' in window || (window.$ = mui); +/** + * $.os + * @param {type} $ + * @returns {undefined} + */ +(function($, window) { + function detect(ua) { + this.os = {}; + var funcs = [ + + function() { //wechat + var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i); + if (wechat) { //wechat + this.os.wechat = { + version: wechat[2].replace(/_/g, '.') + }; + } + return false; + }, + function() { //android + var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); + if (android) { + this.os.android = true; + this.os.version = android[2]; + + this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion)); + } + return this.os.android === true; + }, + function() { //ios + var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/); + if (iphone) { //iphone + this.os.ios = this.os.iphone = true; + this.os.version = iphone[2].replace(/_/g, '.'); + } else { + var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + if (ipad) { //ipad + this.os.ios = this.os.ipad = true; + this.os.version = ipad[2].replace(/_/g, '.'); + } + } + return this.os.ios === true; + } + ]; + [].every.call(funcs, function(func) { + return !func.call($); + }); + } + detect.call($, navigator.userAgent); +})(mui, window); +/** + * $.os.plus + * @param {type} $ + * @returns {undefined} + */ +(function($, document) { + function detect(ua) { + this.os = this.os || {}; + var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser? + if (plus) { + this.os.plus = true; + $(function() { + document.body.classList.add('mui-plus'); + }); + if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识 + this.os.stream = true; + $(function() { + document.body.classList.add('mui-plus-stream'); + }); + } + } + } + detect.call($, navigator.userAgent); +})(mui, document); +/** + * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener) + * @param {Object} $ + */ +(function($) { + if ('ontouchstart' in window) { + $.isTouchable = true; + $.EVENT_START = 'touchstart'; + $.EVENT_MOVE = 'touchmove'; + $.EVENT_END = 'touchend'; + } else { + $.isTouchable = false; + $.EVENT_START = 'mousedown'; + $.EVENT_MOVE = 'mousemove'; + $.EVENT_END = 'mouseup'; + } + $.EVENT_CANCEL = 'touchcancel'; + $.EVENT_CLICK = 'click'; + + var _mid = 1; + var delegates = {}; + //需要wrap的函数 + var eventMethods = { + preventDefault: 'isDefaultPrevented', + stopImmediatePropagation: 'isImmediatePropagationStopped', + stopPropagation: 'isPropagationStopped' + }; + //默认true返回函数 + var returnTrue = function() { + return true + }; + //默认false返回函数 + var returnFalse = function() { + return false + }; + //wrap浏览器事件 + var compatible = function(event, target) { + if (!event.detail) { + event.detail = { + currentTarget: target + }; + } else { + event.detail.currentTarget = target; + } + $.each(eventMethods, function(name, predicate) { + var sourceMethod = event[name]; + event[name] = function() { + this[predicate] = returnTrue; + return sourceMethod && sourceMethod.apply(event, arguments) + } + event[predicate] = returnFalse; + }, true); + return event; + }; + //简单的wrap对象_mid + var mid = function(obj) { + return obj && (obj._mid || (obj._mid = _mid++)); + }; + //事件委托对象绑定的事件回调列表 + var delegateFns = {}; + //返回事件委托的wrap事件回调 + var delegateFn = function(element, event, selector, callback) { + return function(e) { + //same event + var callbackObjs = delegates[element._mid][event]; + var handlerQueue = []; + var target = e.target; + var selectorAlls = {}; + for (; target && target !== document; target = target.parentNode) { + if (target === element) { + break; + } + if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) { + break; + } + var matches = {}; + $.each(callbackObjs, function(selector, callbacks) { //same selector + selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element)); + if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) { + if (!matches[selector]) { + matches[selector] = callbacks; + } + } + }, true); + if (!$.isEmptyObject(matches)) { + handlerQueue.push({ + element: target, + handlers: matches + }); + } + } + selectorAlls = null; + e = compatible(e); //compatible event + $.each(handlerQueue, function(index, handler) { + target = handler.element; + var tagName = target.tagName; + if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) { + e.preventDefault(); + e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); + } + $.each(handler.handlers, function(index, handler) { + $.each(handler, function(index, callback) { + if (callback.call(target, e) === false) { + e.preventDefault(); + e.stopPropagation(); + } + }, true); + }, true) + if (e.isPropagationStopped()) { + return false; + } + }, true); + }; + }; + var findDelegateFn = function(element, event) { + var delegateCallbacks = delegateFns[mid(element)]; + var result = []; + if (delegateCallbacks) { + result = []; + if (event) { + var filterFn = function(fn) { + return fn.type === event; + } + return delegateCallbacks.filter(filterFn); + } else { + result = delegateCallbacks; + } + } + return result; + }; + var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; + /** + * mui delegate events + * @param {type} event + * @param {type} selector + * @param {type} callback + * @returns {undefined} + */ + $.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持 + return this.each(function() { + var element = this; + mid(element); + mid(callback); + var isAddEventListener = false; + var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {}); + var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {})); + if ($.isEmptyObject(delegateCallbackObjs)) { + isAddEventListener = true; + } + var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []); + delegateCallbacks.push(callback); + if (isAddEventListener) { + var delegateFnArray = delegateFns[mid(element)]; + if (!delegateFnArray) { + delegateFnArray = []; + } + var delegateCallback = delegateFn(element, event, selector, callback); + delegateFnArray.push(delegateCallback); + delegateCallback.i = delegateFnArray.length - 1; + delegateCallback.type = event; + delegateFns[mid(element)] = delegateFnArray; + element.addEventListener(event, delegateCallback); + if (event === 'tap') { //TODO 需要找个更好的解决方案 + element.addEventListener('click', function(e) { + if (e.target) { + var tagName = e.target.tagName; + if (!preventDefaultException.test(tagName)) { + if (tagName === 'A') { + var href = e.target.href; + if (!(href && ~href.indexOf('tel:'))) { + e.preventDefault(); + } + } else { + e.preventDefault(); + } + } + } + }); + } + } + }); + }; + $.fn.off = function(event, selector, callback) { + return this.each(function() { + var _mid = mid(this); + if (!event) { //mui(selector).off(); + delegates[_mid] && delete delegates[_mid]; + } else if (!selector) { //mui(selector).off(event); + delegates[_mid] && delete delegates[_mid][event]; + } else if (!callback) { //mui(selector).off(event,selector); + delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector]; + } else { //mui(selector).off(event,selector,callback); + var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector]; + $.each(delegateCallbacks, function(index, delegateCallback) { + if (mid(delegateCallback) === mid(callback)) { + delegateCallbacks.splice(index, 1); + return false; + } + }, true); + } + if (delegates[_mid]) { + //如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调 + if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) { + findDelegateFn(this, event).forEach(function(fn) { + this.removeEventListener(fn.type, fn); + delete delegateFns[_mid][fn.i]; + }.bind(this)); + } + } else { + //如果delegates[_mid]已不存在,删除所有 + findDelegateFn(this).forEach(function(fn) { + this.removeEventListener(fn.type, fn); + delete delegateFns[_mid][fn.i]; + }.bind(this)); + } + }); + + }; +})(mui); +/** + * mui target(action>popover>modal>tab>toggle) + */ +(function($, window, document) { + /** + * targets + */ + $.targets = {}; + /** + * target handles + */ + $.targetHandles = []; + /** + * register target + * @param {type} target + * @returns {$.targets} + */ + $.registerTarget = function(target) { + + target.index = target.index || 1000; + + $.targetHandles.push(target); + + $.targetHandles.sort(function(a, b) { + return a.index - b.index; + }); + + return $.targetHandles; + }; + window.addEventListener($.EVENT_START, function(event) { + var target = event.target; + var founds = {}; + for (; target && target !== document; target = target.parentNode) { + var isFound = false; + $.each($.targetHandles, function(index, targetHandle) { + var name = targetHandle.name; + if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) { + $.targets[name] = targetHandle.handle(event, target); + if ($.targets[name]) { + founds[name] = true; + if (targetHandle.isContinue !== true) { + isFound = true; + } + } + } else { + if (!founds[name]) { + if (targetHandle.isReset !== false) + $.targets[name] = false; + } + } + }); + if (isFound) { + break; + } + } + }); + window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A) + var target = event.target; + var isFound = false; + for (; target && target !== document; target = target.parentNode) { + if (target.tagName === 'A') { + $.each($.targetHandles, function(index, targetHandle) { + var name = targetHandle.name; + if (targetHandle.hasOwnProperty('handle')) { + if (targetHandle.handle(event, target)) { + isFound = true; + event.preventDefault(); + return false; + } + } + }); + if (isFound) { + break; + } + } + } + }); +})(mui, window, document); +/** + * fixed trim + * @param {type} undefined + * @returns {undefined} + */ +(function(undefined) { + if (String.prototype.trim === undefined) { // fix for iOS 3.2 + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ''); + }; + } + Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) { + obj['__proto__'] = proto; + return obj; + }; + +})(); +/** + * fixed CustomEvent + */ +(function() { + if (typeof window.CustomEvent === 'undefined') { + function CustomEvent(event, params) { + params = params || { + bubbles: false, + cancelable: false, + detail: undefined + }; + var evt = document.createEvent('Events'); + var bubbles = true; + for (var name in params) { + (name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]); + } + evt.initEvent(event, bubbles, true); + return evt; + }; + CustomEvent.prototype = window.Event.prototype; + window.CustomEvent = CustomEvent; + } +})(); +/* + A shim for non ES5 supporting browsers. + Adds function bind to Function prototype, so that you can do partial application. + Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees. +*/ + +Function.prototype.bind = Function.prototype.bind || function(to) { + // Make an array of our arguments, starting from second argument + var partial = Array.prototype.splice.call(arguments, 1), + // We'll need the original function. + fn = this; + var bound = function() { + // Join the already applied arguments to the now called ones (after converting to an array again). + var args = partial.concat(Array.prototype.splice.call(arguments, 0)); + // If not being called as a constructor + if (!(this instanceof bound)) { + // return the result of the function called bound to target and partially applied. + return fn.apply(to, args); + } + // If being called as a constructor, apply the function bound to self. + fn.apply(this, args); + } + // Attach the prototype of the function to our newly created function. + bound.prototype = fn.prototype; + return bound; +}; +/** + * mui fixed classList + * @param {type} document + * @returns {undefined} + */ +(function(document) { + if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') { + + Object.defineProperty(HTMLElement.prototype, 'classList', { + get: function() { + var self = this; + function update(fn) { + return function(value) { + var classes = self.className.split(/\s+/), + index = classes.indexOf(value); + + fn(classes, index, value); + self.className = classes.join(" "); + }; + } + + var ret = { + add: update(function(classes, index, value) { + ~index || classes.push(value); + }), + remove: update(function(classes, index) { + ~index && classes.splice(index, 1); + }), + toggle: update(function(classes, index, value) { + ~index ? classes.splice(index, 1) : classes.push(value); + }), + contains: function(value) { + return !!~self.className.split(/\s+/).indexOf(value); + }, + item: function(i) { + return self.className.split(/\s+/)[i] || null; + } + }; + + Object.defineProperty(ret, 'length', { + get: function() { + return self.className.split(/\s+/).length; + } + }); + + return ret; + } + }); + } +})(document); + +/** + * mui fixed requestAnimationFrame + * @param {type} window + * @returns {undefined} + */ +(function(window) { + if (!window.requestAnimationFrame) { + var lastTime = 0; + window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) { + clearTimeout(id); + }; + }; +}(window)); +/** + * fastclick(only for radio,checkbox) + */ +(function($, window, name) { + if (!$.os.android && !$.os.ios) { //目前仅识别android和ios + return; + } + if (window.FastClick) { + return; + } + + var handle = function(event, target) { + if (target.tagName === 'LABEL') { + if (target.parentNode) { + target = target.parentNode.querySelector('input'); + } + } + if (target && (target.type === 'radio' || target.type === 'checkbox')) { + if (!target.disabled) { //disabled + return target; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 40, + handle: handle, + target: false + }); + var dispatchEvent = function(event) { + var targetElement = $.targets.click; + if (targetElement) { + var clickEvent, touch; + // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect + if (document.activeElement && document.activeElement !== targetElement) { + document.activeElement.blur(); + } + touch = event.detail.gesture.changedTouches[0]; + // Synthesise a click event, with an extra attribute so it can be tracked + clickEvent = document.createEvent('MouseEvents'); + clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); + clickEvent.forwardedTouchEvent = true; + targetElement.dispatchEvent(clickEvent); + event.detail && event.detail.gesture.preventDefault(); + } + }; + window.addEventListener('tap', dispatchEvent); + window.addEventListener('doubletap', dispatchEvent); + //捕获 + window.addEventListener('click', function(event) { + if ($.targets.click) { + if (!event.forwardedTouchEvent) { //stop click + if (event.stopImmediatePropagation) { + event.stopImmediatePropagation(); + } else { + // Part of the hack for browsers that don't support Event#stopImmediatePropagation + event.propagationStopped = true; + } + event.stopPropagation(); + event.preventDefault(); + return false; + } + } + }, true); + +})(mui, window, 'click'); +(function($, document) { + $(function() { + if (!$.os.ios) { + return; + } + var CLASS_FOCUSIN = 'mui-focusin'; + var CLASS_BAR_TAB = 'mui-bar-tab'; + var CLASS_BAR_FOOTER = 'mui-bar-footer'; + var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary'; + var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab'; + // var content = document.querySelector('.' + CLASS_CONTENT); + // if (content) { + // document.body.insertBefore(content, document.body.firstElementChild); + // } + document.addEventListener('focusin', function(e) { + if ($.os.plus) { //在父webview里边不fix + if (window.plus) { + if (plus.webview.currentWebview().children().length > 0) { + return; + } + } + } + var target = e.target; + //TODO 需考虑所有键盘弹起的情况 + if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) { + if (target.disabled || target.readOnly) { + return; + } + document.body.classList.add(CLASS_FOCUSIN); + var isFooter = false; + for (; target && target !== document; target = target.parentNode) { + var classList = target.classList; + if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) { + isFooter = true; + break; + } + } + if (isFooter) { + var scrollTop = document.body.scrollHeight; + var scrollLeft = document.body.scrollLeft; + setTimeout(function() { + window.scrollTo(scrollLeft, scrollTop); + }, 20); + } + } + }); + document.addEventListener('focusout', function(e) { + var classList = document.body.classList; + if (classList.contains(CLASS_FOCUSIN)) { + classList.remove(CLASS_FOCUSIN); + setTimeout(function() { + window.scrollTo(document.body.scrollLeft, document.body.scrollTop); + }, 20); + } + }); + }); +})(mui, document); +/** + * mui namespace(optimization) + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.namespace = 'mui'; + $.classNamePrefix = $.namespace + '-'; + $.classSelectorPrefix = '.' + $.classNamePrefix; + /** + * 返回正确的className + * @param {type} className + * @returns {String} + */ + $.className = function(className) { + return $.classNamePrefix + className; + }; + /** + * 返回正确的classSelector + * @param {type} classSelector + * @returns {String} + */ + $.classSelector = function(classSelector) { + return classSelector.replace(/\./g, $.classSelectorPrefix); + }; + /** + * 返回正确的eventName + * @param {type} event + * @param {type} module + * @returns {String} + */ + $.eventName = function(event, module) { + return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : ''); + }; +})(mui); + +/** + * mui gestures + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + $.gestures = { + session: {} + }; + /** + * Gesture preventDefault + * @param {type} e + * @returns {undefined} + */ + $.preventDefault = function(e) { + e.preventDefault(); + }; + /** + * Gesture stopPropagation + * @param {type} e + * @returns {undefined} + */ + $.stopPropagation = function(e) { + e.stopPropagation(); + }; + + /** + * register gesture + * @param {type} gesture + * @returns {$.gestures} + */ + $.addGesture = function(gesture) { + return $.addAction('gestures', gesture); + + }; + + var round = Math.round; + var abs = Math.abs; + var sqrt = Math.sqrt; + var atan = Math.atan; + var atan2 = Math.atan2; + /** + * distance + * @param {type} p1 + * @param {type} p2 + * @returns {Number} + */ + var getDistance = function(p1, p2, props) { + if (!props) { + props = ['x', 'y']; + } + var x = p2[props[0]] - p1[props[0]]; + var y = p2[props[1]] - p1[props[1]]; + return sqrt((x * x) + (y * y)); + }; + /** + * scale + * @param {Object} starts + * @param {Object} moves + */ + var getScale = function(starts, moves) { + if (starts.length >= 2 && moves.length >= 2) { + var props = ['pageX', 'pageY']; + return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props); + } + return 1; + }; + /** + * angle + * @param {type} p1 + * @param {type} p2 + * @returns {Number} + */ + var getAngle = function(p1, p2, props) { + if (!props) { + props = ['x', 'y']; + } + var x = p2[props[0]] - p1[props[0]]; + var y = p2[props[1]] - p1[props[1]]; + return atan2(y, x) * 180 / Math.PI; + }; + /** + * direction + * @param {Object} x + * @param {Object} y + */ + var getDirection = function(x, y) { + if (x === y) { + return ''; + } + if (abs(x) >= abs(y)) { + return x > 0 ? 'left' : 'right'; + } + return y > 0 ? 'up' : 'down'; + }; + /** + * rotation + * @param {Object} start + * @param {Object} end + */ + var getRotation = function(start, end) { + var props = ['pageX', 'pageY']; + return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props); + }; + /** + * px per ms + * @param {Object} deltaTime + * @param {Object} x + * @param {Object} y + */ + var getVelocity = function(deltaTime, x, y) { + return { + x: x / deltaTime || 0, + y: y / deltaTime || 0 + }; + }; + /** + * detect gestures + * @param {type} event + * @param {type} touch + * @returns {undefined} + */ + var detect = function(event, touch) { + if ($.gestures.stoped) { + return; + } + $.doAction('gestures', function(index, gesture) { + if (!$.gestures.stoped) { + if ($.options.gestureConfig[gesture.name] !== false) { + gesture.handle(event, touch); + } + } + }); + }; + /** + * 暂时无用 + * @param {Object} node + * @param {Object} parent + */ + var hasParent = function(node, parent) { + while (node) { + if (node == parent) { + return true; + } + node = node.parentNode; + } + return false; + }; + + var uniqueArray = function(src, key, sort) { + var results = []; + var values = []; + var i = 0; + + while (i < src.length) { + var val = key ? src[i][key] : src[i]; + if (values.indexOf(val) < 0) { + results.push(src[i]); + } + values[i] = val; + i++; + } + + if (sort) { + if (!key) { + results = results.sort(); + } else { + results = results.sort(function sortUniqueArray(a, b) { + return a[key] > b[key]; + }); + } + } + + return results; + }; + var getMultiCenter = function(touches) { + var touchesLength = touches.length; + if (touchesLength === 1) { + return { + x: round(touches[0].pageX), + y: round(touches[0].pageY) + }; + } + + var x = 0; + var y = 0; + var i = 0; + while (i < touchesLength) { + x += touches[i].pageX; + y += touches[i].pageY; + i++; + } + + return { + x: round(x / touchesLength), + y: round(y / touchesLength) + }; + }; + var multiTouch = function() { + return $.options.gestureConfig.pinch; + }; + var copySimpleTouchData = function(touch) { + var touches = []; + var i = 0; + while (i < touch.touches.length) { + touches[i] = { + pageX: round(touch.touches[i].pageX), + pageY: round(touch.touches[i].pageY) + }; + i++; + } + return { + timestamp: $.now(), + gesture: touch.gesture, + touches: touches, + center: getMultiCenter(touch.touches), + deltaX: touch.deltaX, + deltaY: touch.deltaY + }; + }; + + var calDelta = function(touch) { + var session = $.gestures.session; + var center = touch.center; + var offset = session.offsetDelta || {}; + var prevDelta = session.prevDelta || {}; + var prevTouch = session.prevTouch || {}; + + if (touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) { + prevDelta = session.prevDelta = { + x: prevTouch.deltaX || 0, + y: prevTouch.deltaY || 0 + }; + + offset = session.offsetDelta = { + x: center.x, + y: center.y + }; + } + touch.deltaX = prevDelta.x + (center.x - offset.x); + touch.deltaY = prevDelta.y + (center.y - offset.y); + }; + var calTouchData = function(touch) { + var session = $.gestures.session; + var touches = touch.touches; + var touchesLength = touches.length; + + if (!session.firstTouch) { + session.firstTouch = copySimpleTouchData(touch); + } + + if (multiTouch() && touchesLength > 1 && !session.firstMultiTouch) { + session.firstMultiTouch = copySimpleTouchData(touch); + } else if (touchesLength === 1) { + session.firstMultiTouch = false; + } + + var firstTouch = session.firstTouch; + var firstMultiTouch = session.firstMultiTouch; + var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center; + + var center = touch.center = getMultiCenter(touches); + touch.timestamp = $.now(); + touch.deltaTime = touch.timestamp - firstTouch.timestamp; + + touch.angle = getAngle(offsetCenter, center); + touch.distance = getDistance(offsetCenter, center); + + calDelta(touch); + + touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY); + + touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1; + touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0; + + calIntervalTouchData(touch); + + }; + var CAL_INTERVAL = 25; + var calIntervalTouchData = function(touch) { + var session = $.gestures.session; + var last = session.lastInterval || touch; + var deltaTime = touch.timestamp - last.timestamp; + var velocity; + var velocityX; + var velocityY; + var direction; + + if (touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) { + var deltaX = last.deltaX - touch.deltaX; + var deltaY = last.deltaY - touch.deltaY; + + var v = getVelocity(deltaTime, deltaX, deltaY); + velocityX = v.x; + velocityY = v.y; + velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; + direction = getDirection(deltaX, deltaY) || last.direction; + + session.lastInterval = touch; + } else { + velocity = last.velocity; + velocityX = last.velocityX; + velocityY = last.velocityY; + direction = last.direction; + } + + touch.velocity = velocity; + touch.velocityX = velocityX; + touch.velocityY = velocityY; + touch.direction = direction; + }; + var targetIds = {}; + var convertTouches = function(touches) { + for (var i = 0; i < touches.length; i++) { + !touches['identifier'] && (touches['identifier'] = 0); + } + return touches; + }; + var getTouches = function(event, touch) { + var allTouches = convertTouches($.slice.call(event.touches || [event])); + + var type = event.type; + + var targetTouches = []; + var changedTargetTouches = []; + + //当touchstart或touchmove且touches长度为1,直接获得all和changed + if ((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) { + targetIds[allTouches[0].identifier] = true; + targetTouches = allTouches; + changedTargetTouches = allTouches; + touch.target = event.target; + } else { + var i = 0; + var targetTouches = []; + var changedTargetTouches = []; + var changedTouches = convertTouches($.slice.call(event.changedTouches || [event])); + + touch.target = event.target; + var sessionTarget = $.gestures.session.target || event.target; + targetTouches = allTouches.filter(function(touch) { + return hasParent(touch.target, sessionTarget); + }); + + if (type === $.EVENT_START) { + i = 0; + while (i < targetTouches.length) { + targetIds[targetTouches[i].identifier] = true; + i++; + } + } + + i = 0; + while (i < changedTouches.length) { + if (targetIds[changedTouches[i].identifier]) { + changedTargetTouches.push(changedTouches[i]); + } + if (type === $.EVENT_END || type === $.EVENT_CANCEL) { + delete targetIds[changedTouches[i].identifier]; + } + i++; + } + + if (!changedTargetTouches.length) { + return false; + } + } + targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true); + var touchesLength = targetTouches.length; + var changedTouchesLength = changedTargetTouches.length; + if (type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first + touch.isFirst = true; + $.gestures.touch = $.gestures.session = { + target: event.target + }; + } + touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0)); + + touch.touches = targetTouches; + touch.changedTouches = changedTargetTouches; + return true; + + }; + var handleTouchEvent = function(event) { + var touch = { + gesture: event + }; + var touches = getTouches(event, touch); + if (!touches) { + return; + } + calTouchData(touch); + detect(event, touch); + $.gestures.session.prevTouch = touch; + if (event.type === $.EVENT_END && !$.isTouchable) { + $.gestures.touch = $.gestures.session = {}; + } + }; + window.addEventListener($.EVENT_START, handleTouchEvent); + window.addEventListener($.EVENT_MOVE, handleTouchEvent); + window.addEventListener($.EVENT_END, handleTouchEvent); + window.addEventListener($.EVENT_CANCEL, handleTouchEvent); + //fixed hashchange(android) + window.addEventListener($.EVENT_CLICK, function(e) { + //TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等 + if (($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) { + e.preventDefault(); + } + }, true); + + + //增加原生滚动识别 + $.isScrolling = false; + var scrollingTimeout = null; + window.addEventListener('scroll', function() { + $.isScrolling = true; + scrollingTimeout && clearTimeout(scrollingTimeout); + scrollingTimeout = setTimeout(function() { + $.isScrolling = false; + }, 250); + }); +})(mui, window); +/** + * mui gesture flick[left|right|up|down] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var flickStartTime = 0; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + var now = $.now(); + switch (event.type) { + case $.EVENT_MOVE: + if (now - flickStartTime > 300) { + flickStartTime = now; + session.flickStart = touch.center; + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + touch.flick = false; + if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) { + touch.flick = true; + touch.flickTime = now - flickStartTime; + touch.flickDistanceX = touch.center.x - session.flickStart.x; + touch.flickDistanceY = touch.center.y - session.flickStart.y; + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + } + break; + } + + }; + /** + * mui gesture flick + */ + $.addGesture({ + name: name, + index: 5, + handle: handle, + options: { + flickMaxTime: 200, + flickMinDistince: 10 + } + }); +})(mui, 'flick'); +/** + * mui gesture swipe[left|right|up|down] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var session = $.gestures.session; + if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) { + var options = this.options; + touch.swipe = false; + //TODO 后续根据velocity计算 + if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) { + touch.swipe = true; + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + } + } + }; + /** + * mui gesture swipe + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + swipeMaxTime: 300, + swipeMinDistince: 18 + } + }); +})(mui, 'swipe'); +/** + * mui gesture drag[start|left|right|up|down|end] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var session = $.gestures.session; + switch (event.type) { + case $.EVENT_START: + break; + case $.EVENT_MOVE: + if (!touch.direction || !session.target) { + return; + } + //修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套 + if (session.lockDirection && session.startDirection) { + if (session.startDirection && session.startDirection !== touch.direction) { + if (session.startDirection === 'up' || session.startDirection === 'down') { + touch.direction = touch.deltaY < 0 ? 'up' : 'down'; + } else { + touch.direction = touch.deltaX < 0 ? 'left' : 'right'; + } + } + } + + if (!session.drag) { + session.drag = true; + $.trigger(session.target, name + 'start', touch); + } + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if (session.drag && touch.isFinal) { + $.trigger(session.target, name + 'end', touch); + } + break; + } + }; + /** + * mui gesture drag + */ + $.addGesture({ + name: name, + index: 20, + handle: handle, + options: { + fingers: 1 + } + }); +})(mui, 'drag'); +/** + * mui gesture tap and doubleTap + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var lastTarget; + var lastTapTime; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_END: + if (!touch.isFinal) { + return; + } + var target = session.target; + if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) { + return; + } + if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) { + if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target + if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) { + $.trigger(target, 'doubletap', touch); + lastTapTime = $.now(); + lastTarget = target; + return; + } + } + $.trigger(target, name, touch); + lastTapTime = $.now(); + lastTarget = target; + } + break; + } + }; + /** + * mui gesture tap + */ + $.addGesture({ + name: name, + index: 30, + handle: handle, + options: { + fingers: 1, + tapMaxInterval: 300, + tapMaxDistance: 5, + tapMaxTime: 250 + } + }); +})(mui, 'tap'); +/** + * mui gesture longtap + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var timer; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_START: + clearTimeout(timer); + timer = setTimeout(function() { + $.trigger(session.target, name, touch); + }, options.holdTimeout); + break; + case $.EVENT_MOVE: + if (touch.distance > options.holdThreshold) { + clearTimeout(timer); + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + clearTimeout(timer); + break; + } + }; + /** + * mui gesture longtap + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + fingers: 1, + holdTimeout: 500, + holdThreshold: 2 + } + }); +})(mui, 'longtap'); +/** + * mui gesture hold + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var timer; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_START: + if ($.options.gestureConfig.hold) { + timer && clearTimeout(timer); + timer = setTimeout(function() { + touch.hold = true; + $.trigger(session.target, name, touch); + }, options.holdTimeout); + } + break; + case $.EVENT_MOVE: + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if (timer) { + clearTimeout(timer) && (timer = null); + $.trigger(session.target, 'release', touch); + } + break; + } + }; + /** + * mui gesture hold + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + fingers: 1, + holdTimeout: 0 + } + }); +})(mui, 'hold'); +/** + * mui gesture pinch + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var options = this.options; + var session = $.gestures.session; + switch (event.type) { + case $.EVENT_START: + break; + case $.EVENT_MOVE: + if ($.options.gestureConfig.pinch) { + if (touch.touches.length < 2) { + return; + } + if (!session.pinch) { //start + session.pinch = true; + $.trigger(session.target, name + 'start', touch); + } + $.trigger(session.target, name, touch); + var scale = touch.scale; + var rotation = touch.rotation; + var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale; + var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。 + if (scale > lastScale) { //out + lastScale = scale - scaleDiff; + $.trigger(session.target, name + 'out', touch); + } //in + else if (scale < lastScale) { + lastScale = scale + scaleDiff; + $.trigger(session.target, name + 'in', touch); + } + if (Math.abs(rotation) > options.minRotationAngle) { + $.trigger(session.target, 'rotate', touch); + } + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) { + session.pinch = false; + $.trigger(session.target, name + 'end', touch); + } + break; + } + }; + /** + * mui gesture pinch + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + minRotationAngle: 0 + } + }); +})(mui, 'pinch'); +/** + * mui.init + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.global = $.options = { + gestureConfig: { + tap: true, + doubletap: false, + longtap: false, + hold: false, + flick: true, + swipe: true, + drag: true, + pinch: false + } + }; + /** + * + * @param {type} options + * @returns {undefined} + */ + $.initGlobal = function(options) { + $.options = $.extend(true, $.global, options); + return this; + }; + var inits = {}; + + /** + * 单页配置 初始化 + * @param {object} options + */ + $.init = function(options) { + $.options = $.extend(true, $.global, options || {}); + $.ready(function() { + $.doAction('inits', function(index, init) { + var isInit = !!(!inits[init.name] || init.repeat); + if (isInit) { + init.handle.call($); + inits[init.name] = true; + } + }); + }); + return this; + }; + + /** + * 增加初始化执行流程 + * @param {function} init + */ + $.addInit = function(init) { + return $.addAction('inits', init); + }; + /** + * 处理html5版本subpages + */ + $.addInit({ + name: 'iframe', + index: 100, + handle: function() { + var options = $.options; + var subpages = options.subpages || []; + if (!$.os.plus && subpages.length) { + //暂时只处理单个subpage。后续可以考虑支持多个subpage + createIframe(subpages[0]); + } + } + }); + var createIframe = function(options) { + var wrapper = document.createElement('div'); + wrapper.className = 'mui-iframe-wrapper'; + var styles = options.styles || {}; + if (typeof styles.top !== 'string') { + styles.top = '0px'; + } + if (typeof styles.bottom !== 'string') { + styles.bottom = '0px'; + } + wrapper.style.top = styles.top; + wrapper.style.bottom = styles.bottom; + var iframe = document.createElement('iframe'); + iframe.src = options.url; + iframe.id = options.id || options.url; + iframe.name = iframe.id; + wrapper.appendChild(iframe); + document.body.appendChild(wrapper); + //目前仅处理微信 + $.os.wechat && handleScroll(wrapper, iframe); + }; + + function handleScroll(wrapper, iframe) { + var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src; + var scrollTop = (parseFloat(localStorage.getItem(key)) || 0); + if (scrollTop) { + (function(y) { + iframe.onload = function() { + window.scrollTo(0, y); + }; + })(scrollTop); + } + setInterval(function() { + var _scrollTop = window.scrollY; + if (scrollTop !== _scrollTop) { + localStorage.setItem(key, _scrollTop + ''); + scrollTop = _scrollTop; + } + }, 100); + }; + $(function() { + var classList = document.body.classList; + var os = []; + if ($.os.ios) { + os.push({ + os: 'ios', + version: $.os.version + }); + classList.add('mui-ios'); + } else if ($.os.android) { + os.push({ + os: 'android', + version: $.os.version + }); + classList.add('mui-android'); + } + if ($.os.wechat) { + os.push({ + os: 'wechat', + version: $.os.wechat.version + }); + classList.add('mui-wechat'); + } + if (os.length) { + $.each(os, function(index, osObj) { + var version = ''; + var classArray = []; + if (osObj.version) { + $.each(osObj.version.split('.'), function(i, v) { + version = version + (version ? '-' : '') + v; + classList.add($.className(osObj.os + '-' + version)); + }); + } + }); + } + }); +})(mui); +/** + * mui.init 5+ + * @param {type} $ + * @returns {undefined} + */ +(function($) { + var defaultOptions = { + swipeBack: false, + preloadPages: [], //5+ lazyLoad webview + preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出) + keyEventBind: { + backbutton: true, + menubutton: true + }, + titleConfig: { + height: "44px", + backgroundColor: "#f7f7f7", //导航栏背景色 + bottomBorderColor: "#cccccc", //底部边线颜色 + title: { //标题配置 + text: "", //标题文字 + position: { + top: 0, + left: 0, + width: "100%", + height: "100%" + }, + styles: { + color: "#000000", + align: "center", + family: "'Helvetica Neue',Helvetica,sans-serif", + size: "17px", + style: "normal", + weight: "normal", + fontSrc: "" + } + }, + back: { + image: { + base64Data: '', + imgSrc: '', + sprite: { + top: '0px', + left: '0px', + width: '100%', + height: '100%' + }, + position: { + top: "10px", + left: "10px", + width: "24px", + height: "24px" + } + } + } + } + }; + + //默认页面动画 + var defaultShow = { + event:"titleUpdate", + autoShow: true, + duration: 300, + aniShow: 'slide-in-right', + extras:{} + }; + //若执行了显示动画初始化操作,则要覆盖默认配置 + if($.options.show) { + defaultShow = $.extend(true, defaultShow, $.options.show); + } + + $.currentWebview = null; + + $.extend(true, $.global, defaultOptions); + $.extend(true, $.options, defaultOptions); + /** + * 等待动画配置 + * @param {type} options + * @returns {Object} + */ + $.waitingOptions = function(options) { + return $.extend(true, {}, { + autoShow: true, + title: '', + modal: false + }, options); + }; + /** + * 窗口显示配置 + * @param {type} options + * @returns {Object} + */ + $.showOptions = function(options) { + return $.extend(true, {}, defaultShow, options); + }; + /** + * 窗口默认配置 + * @param {type} options + * @returns {Object} + */ + $.windowOptions = function(options) { + return $.extend({ + scalable: false, + bounce: "" //vertical + }, options); + }; + /** + * plusReady + * @param {type} callback + * @returns {_L6.$} + */ + $.plusReady = function(callback) { + if(window.plus) { + setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting) + callback(); + }, 0); + } else { + document.addEventListener("plusready", function() { + callback(); + }, false); + } + return this; + }; + /** + * 5+ event(5+没提供之前我自己实现) + * @param {type} webview + * @param {type} eventType + * @param {type} data + * @returns {undefined} + */ + $.fire = function(webview, eventType, data) { + if(webview) { + if(typeof data === 'undefined') { + data = ''; + } else if(typeof data === 'boolean' || typeof data === 'number') { + webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")"); + return; + } else if($.isPlainObject(data) || $.isArray(data)) { + data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c"); + } + webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')"); + } + }; + /** + * 5+ event(5+没提供之前我自己实现) + * @param {type} eventType + * @param {type} data + * @returns {undefined} + */ + $.receive = function(eventType, data) { + if(eventType) { + try { + if(data && typeof data === 'string') { + data = JSON.parse(data); + } + } catch(e) {} + $.trigger(document, eventType, data); + } + }; + var triggerPreload = function(webview) { + if(!webview.preloaded) { //保证仅触发一次 + $.fire(webview, 'preload'); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], 'preload'); + } + webview.preloaded = true; + } + }; + var trigger = function(webview, eventType, timeChecked) { + if(timeChecked) { + if(!webview[eventType + 'ed']) { + $.fire(webview, eventType); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], eventType); + } + webview[eventType + 'ed'] = true; + } + } else { + $.fire(webview, eventType); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], eventType); + } + } + + }; + /** + * 打开新窗口 + * @param {string} url 要打开的页面地址 + * @param {string} id 指定页面ID + * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}} + */ + $.openWindow = function(url, id, options) { + if(typeof url === 'object') { + options = url; + url = options.url; + id = options.id || url; + } else { + if(typeof id === 'object') { + options = id; + id = options.id || url; + } else { + id = id || url; + } + } + if(!$.os.plus) { + //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 + if($.os.ios || $.os.android) { + window.top.location.href = url; + } else { + window.parent.location.href = url; + } + return; + } + if(!window.plus) { + return; + } + + options = options || {}; + var params = options.params || {}; + var webview = null, + webviewCache = null, + nShow, nWaiting; + + if($.webviews[id]) { + webviewCache = $.webviews[id]; + //webview真实存在,才能获取 + if(plus.webview.getWebviewById(id)) { + webview = webviewCache.webview; + } + } else if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + if(webview) { //已缓存 + //每次show都需要传递动画参数; + //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; + nShow = webviewCache ? webviewCache.show : defaultShow; + nShow = options.show ? $.extend(nShow, options.show) : nShow; + nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }); + if(webviewCache) { + webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + } + return webview; + } else { //新窗口 + if(!url) { + throw new Error('webview[' + id + '] does not exist'); + } + + //显示waiting + var waitingConfig = $.waitingOptions(options.waiting); + if(waitingConfig.autoShow) { + nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); + } + + //创建页面 + options = $.extend(options, { + id: id, + url: url + }); + + webview = $.createWindow(options); + + //显示 + nShow = $.showOptions(options.show); + if(nShow.autoShow) { + var showWebview = function() { + //关闭等待框 + if(nWaiting) { + nWaiting.close(); + } + //显示页面 + webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); + options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + }; + //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview + webview.addEventListener(nShow.event, showWebview, false); + //loaded事件发生后,触发预加载和pagebeforeshow事件 + webview.addEventListener("loaded", function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }, false); + } + } + return webview; + }; + + $.openWindowWithTitle = function(options, titleConfig) { + options = options || {}; + var url = options.url; + var id = options.id || url; + + if(!$.os.plus) { + //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 + if($.os.ios || $.os.android) { + window.top.location.href = url; + } else { + window.parent.location.href = url; + } + return; + } + if(!window.plus) { + return; + } + + var params = options.params || {}; + var webview = null, + webviewCache = null, + nShow, nWaiting; + + if($.webviews[id]) { + webviewCache = $.webviews[id]; + //webview真实存在,才能获取 + if(plus.webview.getWebviewById(id)) { + webview = webviewCache.webview; + } + } else if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + if(webview) { //已缓存 + //每次show都需要传递动画参数; + //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; + nShow = webviewCache ? webviewCache.show : defaultShow; + nShow = options.show ? $.extend(nShow, options.show) : nShow; + nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }); + if(webviewCache) { + webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + } + return webview; + } else { //新窗口 + if(!url) { + throw new Error('webview[' + id + '] does not exist'); + } + + //显示waiting + var waitingConfig = $.waitingOptions(options.waiting); + if(waitingConfig.autoShow) { + nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); + } + + //创建页面 + options = $.extend(options, { + id: id, + url: url + }); + + webview = $.createWindow(options); + + if(titleConfig) { //处理原生头 + $.extend(true, $.options.titleConfig, titleConfig); + var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title"; + var view = new plus.nativeObj.View(tid, { + top: 0, + height: $.options.titleConfig.height, + width: "100%", + dock: "top", + position: "dock" + }); + view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色 + var _b = parseInt($.options.titleConfig.height) - 1; + view.drawRect($.options.titleConfig.bottomBorderColor, { + top: _b + "px", + left: "0px" + }); //绘制底部边线 + + //绘制文字 + if($.options.titleConfig.title.text){ + var _title = $.options.titleConfig.title; + view.drawText(_title.text,_title.position , _title.styles); + } + + //返回图标绘制 + var _back = $.options.titleConfig.back; + var backClick = null; + //优先字体 + + //其次是图片 + var _backImage = _back.image; + if(_backImage.base64Data || _backImage.imgSrc) { + //TODO 此处需要处理百分比的情况 + backClick = { + left:parseInt(_backImage.position.left), + right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width) + }; + var bitmap = new plus.nativeObj.Bitmap(id + "_back"); + if(_backImage.base64Data) { //优先base64编码字符串 + bitmap.loadBase64Data(_backImage.base64Data); + } else { //其次加载图片文件 + bitmap.load(_backImage.imgSrc); + } + view.drawBitmap(bitmap,_backImage.sprite , _backImage.position); + } + + //处理点击事件 + view.setTouchEventRect({ + top: "0px", + left: "0px", + width: "100%", + height: "100%" + }); + view.interceptTouchEvent(true); + view.addEventListener("click", function(e) { + var x = e.clientX; + + //返回按钮点击 + if(backClick&& x > backClick.left && x < backClick.right){ + if( _back.click && $.isFunction(_back.click)){ + _back.click(); + }else{ + webview.evalJS("window.mui&&mui.back();"); + } + } + }, false); + webview.append(view); + + } + + //显示 + nShow = $.showOptions(options.show); + if(nShow.autoShow) { + //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview + webview.addEventListener(nShow.event, function () { + //关闭等待框 + if(nWaiting) { + nWaiting.close(); + } + //显示页面 + webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); + }, false); + } + } + return webview; + }; + + /** + * 根据配置信息创建一个webview + * @param {type} options + * @param {type} isCreate + * @returns {webview} + */ + $.createWindow = function(options, isCreate) { + if(!window.plus) { + return; + } + var id = options.id || options.url; + var webview; + if(options.preload) { + if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache + webview = $.webviews[id].webview; + } else { //新增预加载窗口 + //判断是否携带createNew参数,默认为false + if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + //之前没有,那就新创建 + if(!webview) { + webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({ + preload: true + }, options.extras)); + if(options.subpages) { + $.each(options.subpages, function(index, subpage) { + var subpageId = subpage.id || subpage.url; + if(subpageId) { //过滤空对象 + var subWebview = plus.webview.getWebviewById(subpageId); + if(!subWebview) { //如果该webview不存在,则创建 + subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({ + preload: true + }, subpage.extras)); + } + webview.append(subWebview); + } + }); + } + } + } + + //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题; + $.webviews[id] = { + webview: webview, //目前仅preload的缓存webview + preload: true, + show: $.showOptions(options.show), + afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯 + }; + //索引该预加载窗口 + var preloads = $.data.preloads; + var index = preloads.indexOf(id); + if(~index) { //删除已存在的(变相调整插入位置) + preloads.splice(index, 1); + } + preloads.push(id); + if(preloads.length > $.options.preloadLimit) { + //先进先出 + var first = $.data.preloads.shift(); + var webviewCache = $.webviews[first]; + if(webviewCache && webviewCache.webview) { + //需要将自己打开的所有页面,全部close; + //关闭该预加载webview + $.closeAll(webviewCache.webview); + } + //删除缓存 + delete $.webviews[first]; + } + } else { + if(isCreate !== false) { //直接创建非预加载窗口 + webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras); + if(options.subpages) { + $.each(options.subpages, function(index, subpage) { + var subpageId = subpage.id || subpage.url; + var subWebview = plus.webview.getWebviewById(subpageId); + if(!subWebview) { + subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras); + } + webview.append(subWebview); + }); + } + } + } + return webview; + }; + + /** + * 预加载 + */ + $.preload = function(options) { + //调用预加载函数,不管是否传递preload参数,强制变为true + if(!options.preload) { + options.preload = true; + } + return $.createWindow(options); + }; + + /** + *关闭当前webview打开的所有webview; + */ + $.closeOpened = function(webview) { + var opened = webview.opened(); + if(opened) { + for(var i = 0, len = opened.length; i < len; i++) { + var openedWebview = opened[i]; + var open_open = openedWebview.opened(); + if(open_open && open_open.length > 0) { + //关闭打开的webview + $.closeOpened(openedWebview); + //关闭自己 + openedWebview.close("none"); + } else { + //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子; + if(openedWebview.parent() !== webview) { + openedWebview.close('none'); + } + } + } + } + }; + $.closeAll = function(webview, aniShow) { + $.closeOpened(webview); + if(aniShow) { + webview.close(aniShow); + } else { + webview.close(); + } + }; + + /** + * 批量创建webview + * @param {type} options + * @returns {undefined} + */ + $.createWindows = function(options) { + $.each(options, function(index, option) { + //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建) + $.createWindow(option, false); + }); + }; + /** + * 创建当前页面的子webview + * @param {type} options + * @returns {webview} + */ + $.appendWebview = function(options) { + if(!window.plus) { + return; + } + var id = options.id || options.url; + var webview; + if(!$.webviews[id]) { //保证执行一遍 + //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话; + if(!plus.webview.getWebviewById(id)) { + webview = plus.webview.create(options.url, id, options.styles, options.extras); + } + //之前的实现方案:子窗口loaded之后再append到父窗口中; + //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败; + // 比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发; + //修改方式:不再监控loaded事件,直接append + //by chb@20150521 + // webview.addEventListener('loaded', function() { + plus.webview.currentWebview().append(webview); + // }); + $.webviews[id] = options; + + } + return webview; + }; + + //全局webviews + $.webviews = {}; + //预加载窗口索引 + $.data.preloads = []; + //$.currentWebview + $.plusReady(function() { + $.currentWebview = plus.webview.currentWebview(); + }); + $.addInit({ + name: '5+', + index: 100, + handle: function() { + var options = $.options; + var subpages = options.subpages || []; + if($.os.plus) { + $.plusReady(function() { + //TODO 这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法; + //或者:在openwindow方法中,监听实现; + $.each(subpages, function(index, subpage) { + $.appendWebview(subpage); + }); + //判断是否首页 + if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) { + //首页需要自己激活预加载; + //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题; + setTimeout(function() { + triggerPreload(plus.webview.currentWebview()); + }, 300); + } + //设置ios顶部状态栏颜色; + if($.os.ios && $.options.statusBarBackground) { + plus.navigator.setStatusBarBackground($.options.statusBarBackground); + } + if($.os.android && parseFloat($.os.version) < 4.4) { + //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题; + if(plus.webview.currentWebview().parent() == null) { + document.addEventListener("resume", function() { + var body = document.body; + body.style.display = 'none'; + setTimeout(function() { + body.style.display = ''; + }, 10); + }); + } + } + }); + } else { + //已支持iframe嵌入 + // if (subpages.length > 0) { + // var err = document.createElement('div'); + // err.className = 'mui-error'; + // //文字描述 + // var span = document.createElement('span'); + // span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考'; + // err.appendChild(span); + // var a = document.createElement('a'); + // a.innerHTML = '"mui框架适用场景"'; + // a.href = 'http://ask.dcloud.net.cn/article/113'; + // err.appendChild(a); + // document.body.appendChild(err); + // console.log('在该浏览器下,不支持创建子页面'); + // } + + } + + } + }); + window.addEventListener('preload', function() { + //处理预加载部分 + var webviews = $.options.preloadPages || []; + $.plusReady(function() { + $.each(webviews, function(index, webview) { + $.createWindow($.extend(webview, { + preload: true + })); + }); + + }); + }); + $.supportStatusbarOffset = function() { + return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7; + }; + $.ready(function() { + //标识当前环境支持statusbar + if($.supportStatusbarOffset()) { + document.body.classList.add('mui-statusbar'); + } + }); +})(mui); + +/** + * mui back + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + /** + * register back + * @param {type} back + * @returns {$.gestures} + */ + $.addBack = function(back) { + return $.addAction('backs', back); + }; + /** + * default + */ + $.addBack({ + name: 'browser', + index: 100, + handle: function() { + if (window.history.length > 1) { + window.history.back(); + return true; + } + return false; + } + }); + /** + * 后退 + */ + $.back = function() { + if (typeof $.options.beforeback === 'function') { + if ($.options.beforeback() === false) { + return; + } + } + $.doAction('backs'); + }; + window.addEventListener('tap', function(e) { + var action = $.targets.action; + if (action && action.classList.contains('mui-action-back')) { + $.back(); + $.targets.action = false; + } + }); + window.addEventListener('swiperight', function(e) { + var detail = e.detail; + if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) { + $.back(); + } + }); + +})(mui, window); +/** + * mui back 5+ + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + if ($.os.plus && $.os.android) { + $.addBack({ + name: 'mui', + index: 5, + handle: function() { + //后续重新设计此处,将back放到各个空间内部实现 + //popover + if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) { + $($.targets._popover).popover('hide'); + return true; + } + //offcanvas + var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active'); + if (offCanvas) { + $(offCanvas).offCanvas('close'); + return true; + } + var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage(); + if (previewImage && previewImage.isShown()) { + previewImage.close(); + return true; + } + //popup + return $.closePopup(); + } + }); + } + //首次按下back按键的时间 + $.__back__first = null; + /** + * 5+ back + */ + $.addBack({ + name: '5+', + index: 10, + handle: function() { + if (!window.plus) { + return false; + } + var wobj = plus.webview.currentWebview(); + var parent = wobj.parent(); + if (parent) { + parent.evalJS('mui&&mui.back();'); + } else { + wobj.canBack(function(e) { + //by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回; + if (e.canBack) { //webview history back + window.history.back(); + } else { //webview close or hide + //fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close + if (wobj.id === plus.runtime.appid) { //首页 + //首页不存在opener的情况下,后退实际上应该是退出应用; + //首次按键,提示‘再按一次退出应用’ + if (!$.__back__first) { + $.__back__first = new Date().getTime(); + mui.toast('再按一次退出应用'); + setTimeout(function() { + $.__back__first = null; + }, 2000); + } else { + if (new Date().getTime() - $.__back__first < 2000) { + plus.runtime.quit(); + } + } + } else { //其他页面, + if (wobj.preload) { + wobj.hide("auto"); + } else { + //关闭页面时,需要将其打开的所有子页面全部关闭; + $.closeAll(wobj); + } + } + } + }); + } + return true; + } + }); + + + $.menu = function() { + var menu = document.querySelector('.mui-action-menu'); + if (menu) { + $.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题 + $.trigger(menu, 'tap'); + } else { //执行父窗口的menu + if (window.plus) { + var wobj = $.currentWebview; + var parent = wobj.parent(); + if (parent) { //又得evalJS + parent.evalJS('mui&&mui.menu();'); + } + } + } + }; + var __back = function() { + $.back(); + }; + var __menu = function() { + $.menu(); + }; + //默认监听 + $.plusReady(function() { + if ($.options.keyEventBind.backbutton) { + plus.key.addEventListener('backbutton', __back, false); + } + if ($.options.keyEventBind.menubutton) { + plus.key.addEventListener('menubutton', __menu, false); + } + }); + //处理按键监听事件 + $.addInit({ + name: 'keyEventBind', + index: 1000, + handle: function() { + $.plusReady(function() { + //如果不为true,则移除默认监听 + if (!$.options.keyEventBind.backbutton) { + plus.key.removeEventListener('backbutton', __back); + } + if (!$.options.keyEventBind.menubutton) { + plus.key.removeEventListener('menubutton', __menu); + } + }); + } + }); +})(mui, window); +/** + * mui.init pulldownRefresh + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.addInit({ + name: 'pullrefresh', + index: 1000, + handle: function() { + var options = $.options; + var pullRefreshOptions = options.pullRefresh || {}; + var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback'); + var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback'); + if(hasPulldown || hasPullup) { + var container = pullRefreshOptions.container; + if(container) { + var $container = $(container); + if($container.length === 1) { + if($.os.plus) { //5+环境 + if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈 + $.plusReady(function() { + //这里改写$.fn.pullRefresh + $.fn.pullRefresh = $.fn.pullRefresh_native; + $container.pullRefresh(pullRefreshOptions); + }); + + } else if($.os.android) { //非原生转圈,但是Android环境 + $.plusReady(function() { + //这里改写$.fn.pullRefresh + $.fn.pullRefresh = $.fn.pullRefresh_native + var webview = plus.webview.currentWebview(); + if(window.__NWin_Enable__ === false) { //不支持多webview + $container.pullRefresh(pullRefreshOptions); + } else { + if(hasPullup) { + //当前页面初始化pullup + var upOptions = {}; + upOptions.up = pullRefreshOptions.up; + upOptions.webviewId = webview.id || webview.getURL(); + $container.pullRefresh(upOptions); + } + if(hasPulldown) { + var parent = webview.parent(); + var id = webview.id || webview.getURL(); + if(parent) { + if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法 + $container.pullRefresh({ + webviewId: id + }); + } + var downOptions = { + webviewId: id//子页面id + }; + downOptions.down = $.extend({}, pullRefreshOptions.down); + downOptions.down.callback = '_CALLBACK'; + //改写父页面的$.fn.pullRefresh + parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native"); + //父页面初始化pulldown + parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')"); + } + } + } + }); + } else { //非原生转圈,iOS环境 + $container.pullRefresh(pullRefreshOptions); + } + } else { + $container.pullRefresh(pullRefreshOptions); + } + } + } + } + } + }); +})(mui); +/** + * mui ajax + * @param {type} $ + * @returns {undefined} + */ +(function($, window, undefined) { + + var jsonType = 'application/json'; + var htmlType = 'text/html'; + var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi; + var scriptTypeRE = /^(?:text|application)\/javascript/i; + var xmlTypeRE = /^(?:text|application)\/xml/i; + var blankRE = /^\s*$/; + + $.ajaxSettings = { + type: 'GET', + beforeSend: $.noop, + success: $.noop, + error: $.noop, + complete: $.noop, + context: null, + xhr: function(protocol) { + return new window.XMLHttpRequest(); + }, + accepts: { + script: 'text/javascript, application/javascript, application/x-javascript', + json: jsonType, + xml: 'application/xml, text/xml', + html: htmlType, + text: 'text/plain' + }, + timeout: 0, + processData: true, + cache: true + }; + var ajaxBeforeSend = function(xhr, settings) { + var context = settings.context + if(settings.beforeSend.call(context, xhr, settings) === false) { + return false; + } + }; + var ajaxSuccess = function(data, xhr, settings) { + settings.success.call(settings.context, data, 'success', xhr); + ajaxComplete('success', xhr, settings); + }; + // type: "timeout", "error", "abort", "parsererror" + var ajaxError = function(error, type, xhr, settings) { + settings.error.call(settings.context, xhr, type, error); + ajaxComplete(type, xhr, settings); + }; + // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" + var ajaxComplete = function(status, xhr, settings) { + settings.complete.call(settings.context, xhr, status); + }; + + var serialize = function(params, obj, traditional, scope) { + var type, array = $.isArray(obj), + hash = $.isPlainObject(obj); + $.each(obj, function(key, value) { + type = $.type(value); + if(scope) { + key = traditional ? scope : + scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']'; + } + // handle data in serializeArray() format + if(!scope && array) { + params.add(value.name, value.value); + } + // recurse into nested objects + else if(type === "array" || (!traditional && type === "object")) { + serialize(params, value, traditional, key); + } else { + params.add(key, value); + } + }); + }; + var serializeData = function(options) { + if(options.processData && options.data && typeof options.data !== "string") { + var contentType = options.contentType; + if(!contentType && options.headers) { + contentType = options.headers['Content-Type']; + } + if(contentType && ~contentType.indexOf(jsonType)) { //application/json + options.data = JSON.stringify(options.data); + } else { + options.data = $.param(options.data, options.traditional); + } + } + if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) { + options.url = appendQuery(options.url, options.data); + options.data = undefined; + } + }; + var appendQuery = function(url, query) { + if(query === '') { + return url; + } + return(url + '&' + query).replace(/[&?]{1,2}/, '?'); + }; + var mimeToDataType = function(mime) { + if(mime) { + mime = mime.split(';', 2)[0]; + } + return mime && (mime === htmlType ? 'html' : + mime === jsonType ? 'json' : + scriptTypeRE.test(mime) ? 'script' : + xmlTypeRE.test(mime) && 'xml') || 'text'; + }; + var parseArguments = function(url, data, success, dataType) { + if($.isFunction(data)) { + dataType = success, success = data, data = undefined; + } + if(!$.isFunction(success)) { + dataType = success, success = undefined; + } + return { + url: url, + data: data, + success: success, + dataType: dataType + }; + }; + $.ajax = function(url, options) { + if(typeof url === "object") { + options = url; + url = undefined; + } + var settings = options || {}; + settings.url = url || settings.url; + for(var key in $.ajaxSettings) { + if(settings[key] === undefined) { + settings[key] = $.ajaxSettings[key]; + } + } + serializeData(settings); + var dataType = settings.dataType; + + if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) { + settings.url = appendQuery(settings.url, '_=' + $.now()); + } + var mime = settings.accepts[dataType && dataType.toLowerCase()]; + var headers = {}; + var setHeader = function(name, value) { + headers[name.toLowerCase()] = [name, value]; + }; + var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol; + var xhr = settings.xhr(settings); + var nativeSetHeader = xhr.setRequestHeader; + var abortTimeout; + + setHeader('X-Requested-With', 'XMLHttpRequest'); + setHeader('Accept', mime || '*/*'); + if(!!(mime = settings.mimeType || mime)) { + if(mime.indexOf(',') > -1) { + mime = mime.split(',', 2)[0]; + } + xhr.overrideMimeType && xhr.overrideMimeType(mime); + } + if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) { + setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded'); + } + if(settings.headers) { + for(var name in settings.headers) + setHeader(name, settings.headers[name]); + } + xhr.setRequestHeader = setHeader; + + xhr.onreadystatechange = function() { + if(xhr.readyState === 4) { + xhr.onreadystatechange = $.noop; + clearTimeout(abortTimeout); + var result, error = false; + var isLocal = protocol === 'file:'; + if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) { + dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')); + result = xhr.responseText; + try { + // http://perfectionkills.com/global-eval-what-are-the-options/ + if(dataType === 'script') { + (1, eval)(result); + } else if(dataType === 'xml') { + result = xhr.responseXML; + } else if(dataType === 'json') { + result = blankRE.test(result) ? null : $.parseJSON(result); + } + } catch(e) { + error = e; + } + + if(error) { + ajaxError(error, 'parsererror', xhr, settings); + } else { + ajaxSuccess(result, xhr, settings); + } + } else { + var status = xhr.status ? 'error' : 'abort'; + var statusText = xhr.statusText || null; + if(isLocal) { + status = 'error'; + statusText = '404'; + } + ajaxError(statusText, status, xhr, settings); + } + } + }; + if(ajaxBeforeSend(xhr, settings) === false) { + xhr.abort(); + ajaxError(null, 'abort', xhr, settings); + return xhr; + } + + if(settings.xhrFields) { + for(var name in settings.xhrFields) { + xhr[name] = settings.xhrFields[name]; + } + } + + var async = 'async' in settings ? settings.async : true; + + xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password); + + for(var name in headers) { + if(headers.hasOwnProperty(name)) { + nativeSetHeader.apply(xhr, headers[name]); + } + } + if(settings.timeout > 0) { + abortTimeout = setTimeout(function() { + xhr.onreadystatechange = $.noop; + xhr.abort(); + ajaxError(null, 'timeout', xhr, settings); + }, settings.timeout); + } + xhr.send(settings.data ? settings.data : null); + return xhr; + }; + + $.param = function(obj, traditional) { + var params = []; + params.add = function(k, v) { + this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v)); + }; + serialize(params, obj, traditional); + return params.join('&').replace(/%20/g, '+'); + }; + $.get = function( /* url, data, success, dataType */ ) { + return $.ajax(parseArguments.apply(null, arguments)); + }; + + $.post = function( /* url, data, success, dataType */ ) { + var options = parseArguments.apply(null, arguments); + options.type = 'POST'; + return $.ajax(options); + }; + + $.getJSON = function( /* url, data, success */ ) { + var options = parseArguments.apply(null, arguments); + options.dataType = 'json'; + return $.ajax(options); + }; + + $.fn.load = function(url, data, success) { + if(!this.length) + return this; + var self = this, + parts = url.split(/\s/), + selector, + options = parseArguments(url, data, success), + callback = options.success; + if(parts.length > 1) + options.url = parts[0], selector = parts[1]; + options.success = function(response) { + if(selector) { + var div = document.createElement('div'); + div.innerHTML = response.replace(rscript, ""); + var selectorDiv = document.createElement('div'); + var childs = div.querySelectorAll(selector); + if(childs && childs.length > 0) { + for(var i = 0, len = childs.length; i < len; i++) { + selectorDiv.appendChild(childs[i]); + } + } + self[0].innerHTML = selectorDiv.innerHTML; + } else { + self[0].innerHTML = response; + } + callback && callback.apply(self, arguments); + }; + $.ajax(options); + return this; + }; + +})(mui, window); +/** + * 5+ ajax + */ +(function($) { + var originAnchor = document.createElement('a'); + originAnchor.href = window.location.href; + $.plusReady(function() { + $.ajaxSettings = $.extend($.ajaxSettings, { + xhr: function(settings) { + if (settings.crossDomain) { //强制使用plus跨域 + return new plus.net.XMLHttpRequest(); + } + //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest + if (originAnchor.protocol !== 'file:') { + var urlAnchor = document.createElement('a'); + urlAnchor.href = settings.url; + urlAnchor.href = urlAnchor.href; + settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host); + if (settings.crossDomain) { + return new plus.net.XMLHttpRequest(); + } + } + if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr + return new plus.net.XMLHttpRequest(); + } + return new window.XMLHttpRequest(); + } + }); + }); +})(mui); +/** + * mui layout(offset[,position,width,height...]) + * @param {type} $ + * @param {type} window + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, undefined) { + $.offset = function(element) { + var box = { + top : 0, + left : 0 + }; + if ( typeof element.getBoundingClientRect !== undefined) { + box = element.getBoundingClientRect(); + } + return { + top : box.top + window.pageYOffset - element.clientTop, + left : box.left + window.pageXOffset - element.clientLeft + }; + }; +})(mui, window); +/** + * mui animation + */ +(function($, window) { + /** + * scrollTo + */ + $.scrollTo = function(scrollTop, duration, callback) { + duration = duration || 1000; + var scroll = function(duration) { + if (duration <= 0) { + window.scrollTo(0, scrollTop); + callback && callback(); + return; + } + var distaince = scrollTop - window.scrollY; + setTimeout(function() { + window.scrollTo(0, window.scrollY + distaince / duration * 10); + scroll(duration - 10); + }, 16.7); + }; + scroll(duration); + }; + $.animationFrame = function(cb) { + var args, isQueued, context; + return function() { + args = arguments; + context = this; + if (!isQueued) { + isQueued = true; + requestAnimationFrame(function() { + cb.apply(context, args); + isQueued = false; + }); + } + }; + }; + +})(mui, window); +(function($) { + var initializing = false, + fnTest = /xyz/.test(function() { + xyz; + }) ? /\b_super\b/ : /.*/; + + var Class = function() {}; + Class.extend = function(prop) { + var _super = this.prototype; + initializing = true; + var prototype = new this(); + initializing = false; + for (var name in prop) { + prototype[name] = typeof prop[name] == "function" && + typeof _super[name] == "function" && fnTest.test(prop[name]) ? + (function(name, fn) { + return function() { + var tmp = this._super; + + this._super = _super[name]; + + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : + prop[name]; + } + function Class() { + if (!initializing && this.init) + this.init.apply(this, arguments); + } + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.extend = arguments.callee; + return Class; + }; + $.Class = Class; +})(mui); +(function($, document, undefined) { + var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket'; + var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket'; + var CLASS_PULL = 'mui-pull'; + var CLASS_PULL_LOADING = 'mui-pull-loading'; + var CLASS_PULL_CAPTION = 'mui-pull-caption'; + var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; + var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; + var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; + + var CLASS_ICON = 'mui-icon'; + var CLASS_SPINNER = 'mui-spinner'; + var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown'; + + var CLASS_BLOCK = 'mui-block'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_VISIBILITY = 'mui-visibility'; + + var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; + var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; + var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER; + + var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join(''); + + var PullRefresh = { + init: function(element, options) { + this._super(element, $.extend(true, { + scrollY: true, + scrollX: false, + indicators: true, + deceleration: 0.003, + down: { + height: 50, + contentinit: '下拉可以刷新', + contentdown: '下拉可以刷新', + contentover: '释放立即刷新', + contentrefresh: '正在刷新...' + }, + up: { + height: 50, + auto: false, + contentinit: '上拉显示更多', + contentdown: '上拉显示更多', + contentrefresh: '正在加载...', + contentnomore: '没有更多数据了', + duration: 300 + } + }, options)); + }, + _init: function() { + this._super(); + this._initPocket(); + }, + _initPulldownRefresh: function() { + this.pulldown = true; + if (this.topPocket) { + this.pullPocket = this.topPocket; + this.pullPocket.classList.add(CLASS_BLOCK); + this.pullPocket.classList.add(CLASS_VISIBILITY); + this.pullCaption = this.topCaption; + this.pullLoading = this.topLoading; + } + }, + _initPullupRefresh: function() { + this.pulldown = false; + if (this.bottomPocket) { + this.pullPocket = this.bottomPocket; + this.pullPocket.classList.add(CLASS_BLOCK); + this.pullPocket.classList.add(CLASS_VISIBILITY); + this.pullCaption = this.bottomCaption; + this.pullLoading = this.bottomLoading; + } + }, + _initPocket: function() { + var options = this.options; + if (options.down && options.down.hasOwnProperty('callback')) { + this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET); + if (!this.topPocket) { + this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN); + this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild); + } + this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING); + this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION); + } + if (options.up && options.up.hasOwnProperty('callback')) { + this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET); + if (!this.bottomPocket) { + this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING); + this.scroller.appendChild(this.bottomPocket); + } + this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING); + this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION); + //TODO only for h5 + this.wrapper.addEventListener('scrollbottom', this); + } + }, + _createPocket: function(clazz, options, iconClass) { + var pocket = document.createElement('div'); + pocket.className = clazz; + pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass); + return pocket; + }, + _resetPullDownLoading: function() { + var loading = this.pullLoading; + if (loading) { + this.pullCaption.innerHTML = this.options.down.contentdown; + loading.style.webkitTransition = ""; + loading.style.webkitTransform = ""; + loading.style.webkitAnimation = ""; + loading.className = CLASS_LOADING_DOWN; + } + }, + _setCaptionClass: function(isPulldown, caption, title) { + if (!isPulldown) { + switch (title) { + case this.options.up.contentdown: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + break; + case this.options.up.contentrefresh: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH + break; + case this.options.up.contentnomore: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; + break; + } + } + }, + _setCaption: function(title, reset) { + if (this.loading) { + return; + } + var options = this.options; + var pocket = this.pullPocket; + var caption = this.pullCaption; + var loading = this.pullLoading; + var isPulldown = this.pulldown; + var self = this; + if (pocket) { + if (reset) { + setTimeout(function() { + caption.innerHTML = self.lastTitle = title; + if (isPulldown) { + loading.className = CLASS_LOADING_DOWN; + } else { + self._setCaptionClass(false, caption, title); + loading.className = CLASS_LOADING; + } + loading.style.webkitAnimation = ""; + loading.style.webkitTransition = ""; + loading.style.webkitTransform = ""; + }, 100); + } else { + if (title !== this.lastTitle) { + caption.innerHTML = title; + if (isPulldown) { + if (title === options.down.contentrefresh) { + loading.className = CLASS_LOADING; + loading.style.webkitAnimation = "spinner-spin 1s step-end infinite"; + } else if (title === options.down.contentover) { + loading.className = CLASS_LOADING_UP; + loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; + loading.style.webkitTransform = "rotate(180deg)"; + } else if (title === options.down.contentdown) { + loading.className = CLASS_LOADING_DOWN; + loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; + loading.style.webkitTransform = "rotate(0deg)"; + } + } else { + if (title === options.up.contentrefresh) { + loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY; + } else { + loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN; + } + self._setCaptionClass(false, caption, title); + } + this.lastTitle = title; + } + } + + } + } + }; + $.PullRefresh = PullRefresh; +})(mui, document); +(function($, window, document, undefined) { + var CLASS_SCROLL = 'mui-scroll'; + var CLASS_SCROLLBAR = 'mui-scrollbar'; + var CLASS_INDICATOR = 'mui-scrollbar-indicator'; + var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical'; + var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal'; + + var CLASS_ACTIVE = 'mui-active'; + + var ease = { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function(k) { + return k * (2 - k); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', + fn: function(k) { + return Math.sqrt(1 - (--k * k)); + } + }, + outCirc: { + style: 'cubic-bezier(0.075, 0.82, 0.165, 1)' + }, + outCubic: { + style: 'cubic-bezier(0.165, 0.84, 0.44, 1)' + } + } + var Scroll = $.Class.extend({ + init: function(element, options) { + this.wrapper = this.element = element; + this.scroller = this.wrapper.children[0]; + this.scrollerStyle = this.scroller && this.scroller.style; + this.stopped = false; + + this.options = $.extend(true, { + scrollY: true, //是否竖向滚动 + scrollX: false, //是否横向滚动 + startX: 0, //初始化时滚动至x + startY: 0, //初始化时滚动至y + + indicators: true, //是否显示滚动条 + stopPropagation: false, + hardwareAccelerated: true, + fixedBadAndorid: false, + preventDefaultException: { + tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ + }, + momentum: true, + + snapX: 0.5, //横向切换距离(以当前容器宽度为基准) + snap: false, //图片轮播,拖拽式选项卡 + + bounce: true, //是否启用回弹 + bounceTime: 500, //回弹动画时间 + bounceEasing: ease.outCirc, //回弹动画曲线 + + scrollTime: 500, + scrollEasing: ease.outCubic, //轮播动画曲线 + + directionLockThreshold: 5, + + parallaxElement: false, //视差元素 + parallaxRatio: 0.5 + }, options); + + this.x = 0; + this.y = 0; + this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : ''; + + this._init(); + if (this.scroller) { + this.refresh(); + // if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看 + this.scrollTo(this.options.startX, this.options.startY); + // } + } + }, + _init: function() { + this._initParallax(); + this._initIndicators(); + this._initEvent(); + }, + _initParallax: function() { + if (this.options.parallaxElement) { + this.parallaxElement = document.querySelector(this.options.parallaxElement); + this.parallaxStyle = this.parallaxElement.style; + this.parallaxHeight = this.parallaxElement.offsetHeight; + this.parallaxImgStyle = this.parallaxElement.querySelector('img').style; + } + }, + _initIndicators: function() { + var self = this; + self.indicators = []; + if (!this.options.indicators) { + return; + } + var indicators = [], + indicator; + + // Vertical scrollbar + if (self.options.scrollY) { + indicator = { + el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL), + listenX: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + // Horizontal scrollbar + if (this.options.scrollX) { + indicator = { + el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL), + listenY: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + for (var i = indicators.length; i--;) { + this.indicators.push(new Indicator(this, indicators[i])); + } + + }, + _initSnap: function() { + this.currentPage = {}; + this.pages = []; + var snaps = this.snaps; + var length = snaps.length; + var m = 0; + var n = -1; + var x = 0; + var leftX = 0; + var rightX = 0; + var snapX = 0; + for (var i = 0; i < length; i++) { + var snap = snaps[i]; + var offsetLeft = snap.offsetLeft; + var offsetWidth = snap.offsetWidth; + if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) { + m = 0; + n++; + } + if (!this.pages[m]) { + this.pages[m] = []; + } + x = this._getSnapX(offsetLeft); + snapX = Math.round((offsetWidth) * this.options.snapX); + leftX = x - snapX; + rightX = x - offsetWidth + snapX; + this.pages[m][n] = { + x: x, + leftX: leftX, + rightX: rightX, + pageX: m, + element: snap + } + if (snap.classList.contains(CLASS_ACTIVE)) { + this.currentPage = this.pages[m][0]; + } + if (x >= this.maxScrollX) { + m++; + } + } + this.options.startX = this.currentPage.x || 0; + }, + _getSnapX: function(offsetLeft) { + return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX); + }, + _gotoPage: function(index) { + this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0]; + for (var i = 0, len = this.snaps.length; i < len; i++) { + if (i === index) { + this.snaps[i].classList.add(CLASS_ACTIVE); + } else { + this.snaps[i].classList.remove(CLASS_ACTIVE); + } + } + this.scrollTo(this.currentPage.x, 0, this.options.scrollTime); + }, + _nearestSnap: function(x) { + if (!this.pages.length) { + return { + x: 0, + pageX: 0 + }; + } + var i = 0; + var length = this.pages.length; + if (x > 0) { + x = 0; + } else if (x < this.maxScrollX) { + x = this.maxScrollX; + } + for (; i < length; i++) { + var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX; + if (x >= nearestX) { + return this.pages[i][0]; + } + } + return { + x: 0, + pageX: 0 + }; + }, + _initEvent: function(detach) { + var action = detach ? 'removeEventListener' : 'addEventListener'; + window[action]('orientationchange', this); + window[action]('resize', this); + + this.scroller[action]('webkitTransitionEnd', this); + + this.wrapper[action]($.EVENT_START, this); + this.wrapper[action]($.EVENT_CANCEL, this); + this.wrapper[action]($.EVENT_END, this); + this.wrapper[action]('drag', this); + this.wrapper[action]('dragend', this); + this.wrapper[action]('flick', this); + this.wrapper[action]('scrollend', this); + if (this.options.scrollX) { + this.wrapper[action]('swiperight', this); + } + var segmentedControl = this.wrapper.querySelector('.mui-segmented-control'); + if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见 + mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault); + } + + this.wrapper[action]('scrollstart', this); + this.wrapper[action]('refresh', this); + }, + _handleIndicatorScrollend: function() { + this.indicators.map(function(indicator) { + indicator.fade(); + }); + }, + _handleIndicatorScrollstart: function() { + this.indicators.map(function(indicator) { + indicator.fade(1); + }); + }, + _handleIndicatorRefresh: function() { + this.indicators.map(function(indicator) { + indicator.refresh(); + }); + }, + handleEvent: function(e) { + if (this.stopped) { + this.resetPosition(); + return; + } + + switch (e.type) { + case $.EVENT_START: + this._start(e); + break; + case 'drag': + this.options.stopPropagation && e.stopPropagation(); + this._drag(e); + break; + case 'dragend': + case 'flick': + this.options.stopPropagation && e.stopPropagation(); + this._flick(e); + break; + case $.EVENT_CANCEL: + case $.EVENT_END: + this._end(e); + break; + case 'webkitTransitionEnd': + this.transitionTimer && this.transitionTimer.cancel(); + this._transitionEnd(e); + break; + case 'scrollstart': + this._handleIndicatorScrollstart(e); + break; + case 'scrollend': + this._handleIndicatorScrollend(e); + this._scrollend(e); + e.stopPropagation(); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'swiperight': + e.stopPropagation(); + break; + case 'refresh': + this._handleIndicatorRefresh(e); + break; + + } + }, + _start: function(e) { + this.moved = this.needReset = false; + this._transitionTime(); + if (this.isInTransition) { + this.needReset = true; + this.isInTransition = false; + var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); + this.setTranslate(Math.round(pos.x), Math.round(pos.y)); + // this.resetPosition(); //reset + $.trigger(this.scroller, 'scrollend', this); + // e.stopPropagation(); + e.preventDefault(); + } + this.reLayout(); + $.trigger(this.scroller, 'beforescrollstart', this); + }, + _getDirectionByAngle: function(angle) { + if (angle < -80 && angle > -100) { + return 'up'; + } else if (angle >= 80 && angle < 100) { + return 'down'; + } else if (angle >= 170 || angle <= -170) { + return 'left'; + } else if (angle >= -35 && angle <= 10) { + return 'right'; + } + return null; + }, + _drag: function(e) { + // if (this.needReset) { + // e.stopPropagation(); //disable parent drag(nested scroller) + // return; + // } + var detail = e.detail; + if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下 + //ios8 hack + if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发 + var clientY = detail.gesture.touches[0].clientY; + //下拉刷新 or 上拉加载 + if ((clientY + 10) > window.innerHeight || clientY < 10) { + this.resetPosition(this.options.bounceTime); + return; + } + } + } + var isPreventDefault = isReturn = false; + var direction = this._getDirectionByAngle(detail.angle); + if (detail.direction === 'left' || detail.direction === 'right') { + if (this.options.scrollX) { + isPreventDefault = true; + if (!this.moved) { //识别角度(该角度导致轮播不灵敏) + // if (direction !== 'left' && direction !== 'right') { + // isReturn = true; + // } else { + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + // } + } + } else if (this.options.scrollY && !this.moved) { + isReturn = true; + } + } else if (detail.direction === 'up' || detail.direction === 'down') { + if (this.options.scrollY) { + isPreventDefault = true; + // if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证 + // if (direction !== 'up' && direction !== 'down') { + // isReturn = true; + // } + // } + if (!this.moved) { + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + } + } else if (this.options.scrollX && !this.moved) { + isReturn = true; + } + } else { + isReturn = true; + } + if (this.moved || isPreventDefault) { + e.stopPropagation(); //阻止冒泡(scroll类嵌套) + detail.gesture && detail.gesture.preventDefault(); + } + if (isReturn) { //禁止非法方向滚动 + return; + } + if (!this.moved) { + $.trigger(this.scroller, 'scrollstart', this); + } else { + e.stopPropagation(); //move期间阻止冒泡(scroll嵌套) + } + var deltaX = 0; + var deltaY = 0; + if (!this.moved) { //start + deltaX = detail.deltaX; + deltaY = detail.deltaY; + } else { //move + deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX; + deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY; + } + var absDeltaX = Math.abs(detail.deltaX); + var absDeltaY = Math.abs(detail.deltaY); + if (absDeltaX > absDeltaY + this.options.directionLockThreshold) { + deltaY = 0; + } else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) { + deltaX = 0; + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + var newX = this.x + deltaX; + var newY = this.y + deltaY; + // Slow down if outside of the boundaries + if (newX > 0 || newX < this.maxScrollX) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if (newY > 0 || newY < this.maxScrollY) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + if (!this.requestAnimationFrame) { + this._updateTranslate(); + } + this.direction = detail.deltaX > 0 ? 'right' : 'left'; + this.moved = true; + this.x = newX; + this.y = newY; + $.trigger(this.scroller, 'scroll', this); + }, + _flick: function(e) { + // if (!this.moved || this.needReset) { + // return; + // } + if (!this.moved) { + return; + } + e.stopPropagation(); + var detail = e.detail; + this._clearRequestAnimationFrame(); + if (e.type === 'dragend' && detail.flick) { //dragend + return; + } + + var newX = Math.round(this.x); + var newY = Math.round(this.y); + + this.isInTransition = false; + // reset if we are outside of the boundaries + if (this.resetPosition(this.options.bounceTime)) { + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + if (e.type === 'dragend') { //dragend + $.trigger(this.scroller, 'scrollend', this); + return; + } + var time = 0; + var easing = ''; + // start momentum animation if needed + if (this.options.momentum && detail.flickTime < 300) { + momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { + destination: newX, + duration: 0 + }; + momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { + destination: newY, + duration: 0 + }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = true; + } + + if (newX != this.x || newY != this.y) { + if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) { + easing = ease.quadratic; + } + this.scrollTo(newX, newY, time, easing); + return; + } + + $.trigger(this.scroller, 'scrollend', this); + // e.stopPropagation(); + }, + _end: function(e) { + this.needReset = false; + if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) { + this.resetPosition(); + } + }, + _transitionEnd: function(e) { + if (e.target != this.scroller || !this.isInTransition) { + return; + } + this._transitionTime(); + if (!this.resetPosition(this.options.bounceTime)) { + this.isInTransition = false; + $.trigger(this.scroller, 'scrollend', this); + } + }, + _scrollend: function(e) { + if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) { + $.trigger(this.scroller, 'scrollbottom', this); + } + }, + _resize: function() { + var that = this; + clearTimeout(that.resizeTimeout); + that.resizeTimeout = setTimeout(function() { + that.refresh(); + }, that.options.resizePolling); + }, + _transitionTime: function(time) { + time = time || 0; + this.scrollerStyle['webkitTransitionDuration'] = time + 'ms'; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = time + 'ms'; + } + if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) { + this.scrollerStyle['webkitTransitionDuration'] = '0.001s'; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = '0.001s'; + } + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].transitionTime(time); + } + } + if (time) { //自定义timer,保证webkitTransitionEnd始终触发 + this.transitionTimer && this.transitionTimer.cancel(); + this.transitionTimer = $.later(function() { + $.trigger(this.scroller, 'webkitTransitionEnd'); + }, time + 100, this); + } + }, + _transitionTimingFunction: function(easing) { + this.scrollerStyle['webkitTransitionTimingFunction'] = easing; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = easing; + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].transitionTimingFunction(easing); + } + } + }, + _translate: function(x, y) { + this.x = x; + this.y = y; + }, + _clearRequestAnimationFrame: function() { + if (this.requestAnimationFrame) { + cancelAnimationFrame(this.requestAnimationFrame); + this.requestAnimationFrame = null; + } + }, + _updateTranslate: function() { + var self = this; + if (self.x !== self.lastX || self.y !== self.lastY) { + self.setTranslate(self.x, self.y); + } + self.requestAnimationFrame = requestAnimationFrame(function() { + self._updateTranslate(); + }); + }, + _createScrollBar: function(clazz) { + var scrollbar = document.createElement('div'); + var indicator = document.createElement('div'); + scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz; + indicator.className = CLASS_INDICATOR; + scrollbar.appendChild(indicator); + if (clazz === CLASS_SCROLLBAR_VERTICAL) { + this.scrollbarY = scrollbar; + this.scrollbarIndicatorY = indicator; + } else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) { + this.scrollbarX = scrollbar; + this.scrollbarIndicatorX = indicator; + } + this.wrapper.appendChild(scrollbar); + return scrollbar; + }, + _preventDefaultException: function(el, exceptions) { + for (var i in exceptions) { + if (exceptions[i].test(el[i])) { + return true; + } + } + return false; + }, + _reLayout: function() { + if (!this.hasHorizontalScroll) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if (!this.hasVerticalScroll) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.indicators.map(function(indicator) { + indicator.refresh(); + }); + + //以防slider类嵌套使用 + if (this.options.snap && typeof this.options.snap === 'string') { + var items = this.scroller.querySelectorAll(this.options.snap); + this.itemLength = 0; + this.snaps = []; + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + if (item.parentNode === this.scroller) { + this.itemLength++; + this.snaps.push(item); + } + } + this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整 + } + }, + _momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) { + var speed = parseFloat(Math.abs(distance) / time), + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1); + duration = speed / deceleration; + if (destination < lowerMargin) { + destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if (destination > 0) { + destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }, + _getTranslateStr: function(x, y) { + if (this.options.hardwareAccelerated) { + return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ; + } + return 'translate(' + x + 'px,' + y + 'px) '; + }, + //API + setStopped: function(stopped) { + this.stopped = !!stopped; + }, + setTranslate: function(x, y) { + this.x = x; + this.y = y; + this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y); + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + var parallaxY = y * this.options.parallaxRatio; + var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2); + if (scale > 1) { + this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio; + this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')'; + } else { + this.parallaxImgStyle['opacity'] = 1; + this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)'; + } + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].updatePosition(); + } + } + this.lastX = this.x; + this.lastY = this.y; + $.trigger(this.scroller, 'scroll', this); + }, + reLayout: function() { + this.wrapper.offsetHeight; + + var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0; + var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0; + var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0; + var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0; + + var clientWidth = this.wrapper.clientWidth; + var clientHeight = this.wrapper.clientHeight; + + this.scrollerWidth = this.scroller.offsetWidth; + this.scrollerHeight = this.scroller.offsetHeight; + + this.wrapperWidth = clientWidth - paddingLeft - paddingRight; + this.wrapperHeight = clientHeight - paddingTop - paddingBottom; + + this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); + this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0); + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + this._reLayout(); + }, + resetPosition: function(time) { + var x = this.x, + y = this.y; + + time = time || 0; + if (!this.hasHorizontalScroll || this.x > 0) { + x = 0; + } else if (this.x < this.maxScrollX) { + x = this.maxScrollX; + } + + if (!this.hasVerticalScroll || this.y > 0) { + y = 0; + } else if (this.y < this.maxScrollY) { + y = this.maxScrollY; + } + + if (x == this.x && y == this.y) { + return false; + } + this.scrollTo(x, y, time, this.options.scrollEasing); + + return true; + }, + _reInit: function() { + var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL); + for (var i = 0, len = groups.length; i < len; i++) { + if (groups[i].parentNode === this.wrapper) { + this.scroller = groups[i]; + break; + } + } + this.scrollerStyle = this.scroller && this.scroller.style; + }, + refresh: function() { + this._reInit(); + this.reLayout(); + $.trigger(this.scroller, 'refresh', this); + this.resetPosition(); + }, + scrollTo: function(x, y, time, easing) { + var easing = easing || ease.circular; + // this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y); + //暂不严格判断x,y,否则会导致部分版本上不正常触发轮播 + this.isInTransition = time > 0; + if (this.isInTransition) { + this._clearRequestAnimationFrame(); + this._transitionTimingFunction(easing.style); + this._transitionTime(time); + this.setTranslate(x, y); + } else { + this.setTranslate(x, y); + } + + }, + scrollToBottom: function(time, easing) { + time = time || this.options.scrollTime; + this.scrollTo(0, this.maxScrollY, time, easing); + }, + gotoPage: function(index) { + this._gotoPage(index); + }, + destroy: function() { + this._initEvent(true); //detach + delete $.data[this.wrapper.getAttribute('data-scroll')]; + this.wrapper.setAttribute('data-scroll', ''); + } + }); + //Indicator + var Indicator = function(scroller, options) { + this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; + this.wrapperStyle = this.wrapper.style; + this.indicator = this.wrapper.children[0]; + this.indicatorStyle = this.indicator.style; + this.scroller = scroller; + + this.options = $.extend({ + listenX: true, + listenY: true, + fade: false, + speedRatioX: 0, + speedRatioY: 0 + }, options); + + this.sizeRatioX = 1; + this.sizeRatioY = 1; + this.maxPosX = 0; + this.maxPosY = 0; + + if (this.options.fade) { + this.wrapperStyle['webkitTransform'] = this.scroller.translateZ; + this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms'; + this.wrapperStyle.opacity = '0'; + } + } + Indicator.prototype = { + handleEvent: function(e) { + + }, + transitionTime: function(time) { + time = time || 0; + this.indicatorStyle['webkitTransitionDuration'] = time + 'ms'; + if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) { + this.indicatorStyle['webkitTransitionDuration'] = '0.001s'; + } + }, + transitionTimingFunction: function(easing) { + this.indicatorStyle['webkitTransitionTimingFunction'] = easing; + }, + refresh: function() { + this.transitionTime(); + + if (this.options.listenX && !this.options.listenY) { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; + } else if (this.options.listenY && !this.options.listenX) { + this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; + } else { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; + } + + this.wrapper.offsetHeight; // force refresh + + if (this.options.listenX) { + this.wrapperWidth = this.wrapper.clientWidth; + this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); + this.indicatorStyle.width = this.indicatorWidth + 'px'; + + this.maxPosX = this.wrapperWidth - this.indicatorWidth; + + this.minBoundaryX = 0; + this.maxBoundaryX = this.maxPosX; + + this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); + } + + if (this.options.listenY) { + this.wrapperHeight = this.wrapper.clientHeight; + this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); + this.indicatorStyle.height = this.indicatorHeight + 'px'; + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + + this.minBoundaryY = 0; + this.maxBoundaryY = this.maxPosY; + + this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); + } + + this.updatePosition(); + }, + + updatePosition: function() { + var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, + y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; + + if (x < this.minBoundaryX) { + this.width = Math.max(this.indicatorWidth + x, 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.minBoundaryX; + } else if (x > this.maxBoundaryX) { + this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.maxPosX + this.indicatorWidth - this.width; + } else if (this.width != this.indicatorWidth) { + this.width = this.indicatorWidth; + this.indicatorStyle.width = this.width + 'px'; + } + + if (y < this.minBoundaryY) { + this.height = Math.max(this.indicatorHeight + y * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.minBoundaryY; + } else if (y > this.maxBoundaryY) { + this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.maxPosY + this.indicatorHeight - this.height; + } else if (this.height != this.indicatorHeight) { + this.height = this.indicatorHeight; + this.indicatorStyle.height = this.height + 'px'; + } + + this.x = x; + this.y = y; + + this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y); + + }, + fade: function(val, hold) { + if (hold && !this.visible) { + return; + } + + clearTimeout(this.fadeTimeout); + this.fadeTimeout = null; + + var time = val ? 250 : 500, + delay = val ? 0 : 300; + + val = val ? '1' : '0'; + + this.wrapperStyle['webkitTransitionDuration'] = time + 'ms'; + + this.fadeTimeout = setTimeout((function(val) { + this.wrapperStyle.opacity = val; + this.visible = +val; + }).bind(this, val), delay); + } + }; + + $.Scroll = Scroll; + + $.fn.scroll = function(options) { + var scrollApis = []; + this.each(function() { + var scrollApi = null; + var self = this; + var id = self.getAttribute('data-scroll'); + if (!id) { + id = ++$.uuid; + var _options = $.extend({}, options); + if (self.classList.contains('mui-segmented-control')) { + _options = $.extend(_options, { + scrollY: false, + scrollX: true, + indicators: false, + snap: '.mui-control-item' + }); + } + $.data[id] = scrollApi = new Scroll(self, _options); + self.setAttribute('data-scroll', id); + } else { + scrollApi = $.data[id]; + } + scrollApis.push(scrollApi); + }); + return scrollApis.length === 1 ? scrollApis[0] : scrollApis; + }; +})(mui, window, document); +(function($, window, document, undefined) { + + var CLASS_VISIBILITY = 'mui-visibility'; + var CLASS_HIDDEN = 'mui-hidden'; + + var PullRefresh = $.Scroll.extend($.extend({ + handleEvent: function(e) { + this._super(e); + if (e.type === 'scrollbottom') { + if (e.target === this.scroller) { + this._scrollbottom(); + } + } + }, + _scrollbottom: function() { + if (!this.pulldown && !this.loading) { + this.pulldown = false; + this._initPullupRefresh(); + this.pullupLoading(); + } + }, + _start: function(e) { + //仅下拉刷新在start阻止默认事件 + if (e.touches && e.touches.length && e.touches[0].clientX > 30) { + e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); + } + if (!this.loading) { + this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false + } + this._super(e); + }, + _drag: function(e) { + this._super(e); + if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) { + this._initPulldownRefresh(); + } + if (this.pulldown) { + this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown); + } + }, + + _reLayout: function() { + this.hasVerticalScroll = true; + this._super(); + }, + //API + resetPosition: function(time) { + if (this.pulldown) { + if (this.y >= this.options.down.height) { + this.pulldownLoading(undefined, time || 0); + return true; + } else { + !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY); + } + } + return this._super(time); + }, + pulldownLoading: function(y, time) { + typeof y === 'undefined' && (y = this.options.down.height); //默认高度 + this.scrollTo(0, y, time, this.options.bounceEasing); + if (this.loading) { + return; + } + // if (!this.pulldown) { + this._initPulldownRefresh(); + // } + this._setCaption(this.options.down.contentrefresh); + this.loading = true; + this.indicators.map(function(indicator) { + indicator.fade(0); + }); + var callback = this.options.down.callback; + callback && callback.call(this); + }, + endPulldownToRefresh: function() { + var self = this; + if (self.topPocket && self.loading && this.pulldown) { + self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing); + self.loading = false; + self._setCaption(self.options.down.contentdown, true); + setTimeout(function() { + self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY); + }, 350); + } + }, + pullupLoading: function(callback, x, time) { + x = x || 0; + this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing); + if (this.loading) { + return; + } + this._initPullupRefresh(); + this._setCaption(this.options.up.contentrefresh); + this.indicators.map(function(indicator) { + indicator.fade(0); + }); + this.loading = true; + callback = callback || this.options.up.callback; + callback && callback.call(this); + }, + endPullupToRefresh: function(finished) { + var self = this; + if (self.bottomPocket) { // && self.loading && !this.pulldown + self.loading = false; + if (finished) { + this.finished = true; + self._setCaption(self.options.up.contentnomore); + // self.bottomPocket.classList.remove(CLASS_VISIBILITY); + // self.bottomPocket.classList.add(CLASS_HIDDEN); + self.wrapper.removeEventListener('scrollbottom', self); + } else { + self._setCaption(self.options.up.contentdown); + // setTimeout(function() { + self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY); + // }, 300); + } + } + }, + disablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; + this.wrapper.removeEventListener('scrollbottom', this); + }, + enablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.classList.remove(CLASS_HIDDEN); + this._setCaption(this.options.up.contentdown); + this.wrapper.addEventListener('scrollbottom', this); + }, + refresh: function(isReset) { + if (isReset && this.finished) { + this.enablePullupToRefresh(); + this.finished = false; + } + this._super(); + }, + }, $.PullRefresh)); + $.fn.pullRefresh = function(options) { + if (this.length === 1) { + var self = this[0]; + var pullRefreshApi = null; + var id = self.getAttribute('data-pullrefresh'); + if (!id && typeof options === 'undefined') { + return false; + } + options = options || {}; + if (!id) { + id = ++$.uuid; + $.data[id] = pullRefreshApi = new PullRefresh(self, options); + self.setAttribute('data-pullrefresh', id); + } else { + pullRefreshApi = $.data[id]; + } + if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 + pullRefreshApi.pulldownLoading(options.down.autoY); + } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 + pullRefreshApi.pullupLoading(); + } + //暂不提供这种调用方式吧 + // if (typeof options === 'string') { + // var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1)); + // if (methodValue !== undefined) { + // return methodValue; + // } + // } + return pullRefreshApi; + } + }; +})(mui, window, document); +/** + * snap 重构 + * @param {Object} $ + * @param {Object} window + */ +(function($, window) { + var CLASS_SLIDER = 'mui-slider'; + var CLASS_SLIDER_GROUP = 'mui-slider-group'; + var CLASS_SLIDER_LOOP = 'mui-slider-loop'; + var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator'; + var CLASS_ACTION_PREVIOUS = 'mui-action-previous'; + var CLASS_ACTION_NEXT = 'mui-action-next'; + var CLASS_SLIDER_ITEM = 'mui-slider-item'; + + var CLASS_ACTIVE = 'mui-active'; + + var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM; + var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR; + var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar'; + + var Slider = $.Slider = $.Scroll.extend({ + init: function(element, options) { + this._super(element, $.extend(true, { + fingers: 1, + interval: 0, //设置为0,则不定时轮播 + scrollY: false, + scrollX: true, + indicators: false, + scrollTime: 1000, + startX: false, + slideTime: 0, //滑动动画时间 + snap: SELECTOR_SLIDER_ITEM + }, options)); + if (this.options.startX) { + // $.trigger(this.wrapper, 'scrollend', this); + } + }, + _init: function() { + this._reInit(); + if (this.scroller) { + this.scrollerStyle = this.scroller.style; + this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR); + if (this.progressBar) { + this.progressBarWidth = this.progressBar.offsetWidth; + this.progressBarStyle = this.progressBar.style; + } + //忘记这个代码是干什么的了? + // this.x = this._getScroll(); + // if (this.options.startX === false) { + // this.options.startX = this.x; + // } + //根据active修正startX + + this._super(); + this._initTimer(); + } + }, + _triggerSlide: function() { + var self = this; + self.isInTransition = false; + var page = self.currentPage; + self.slideNumber = self._fixedSlideNumber(); + if (self.loop) { + if (self.slideNumber === 0) { + self.setTranslate(self.pages[1][0].x, 0); + } else if (self.slideNumber === self.itemLength - 3) { + self.setTranslate(self.pages[self.itemLength - 2][0].x, 0); + } + } + if (self.lastSlideNumber != self.slideNumber) { + self.lastSlideNumber = self.slideNumber; + self.lastPage = self.currentPage; + $.trigger(self.wrapper, 'slide', { + slideNumber: self.slideNumber + }); + } + self._initTimer(); + }, + _handleSlide: function(e) { + var self = this; + if (e.target !== self.wrapper) { + return; + } + var detail = e.detail; + detail.slideNumber = detail.slideNumber || 0; + var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM); + var items = []; + for (var i = 0, len = temps.length; i < len; i++) { + var item = temps[i]; + if (item.parentNode === self.scroller) { + items.push(item); + } + } + var _slideNumber = detail.slideNumber; + if (self.loop) { + _slideNumber += 1; + } + if (!self.wrapper.classList.contains('mui-segmented-control')) { + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + if (item.parentNode === self.scroller) { + if (i === _slideNumber) { + item.classList.add(CLASS_ACTIVE); + } else { + item.classList.remove(CLASS_ACTIVE); + } + } + } + } + var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator'); + if (indicatorWrap) { + if (indicatorWrap.getAttribute('data-scroll')) { //scroll + $(indicatorWrap).scroll().gotoPage(detail.slideNumber); + } + var indicators = indicatorWrap.querySelectorAll('.mui-indicator'); + if (indicators.length > 0) { //图片轮播 + for (var i = 0, len = indicators.length; i < len; i++) { + indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); + } + } else { + var number = indicatorWrap.querySelector('.mui-number span'); + if (number) { //图文表格 + number.innerText = (detail.slideNumber + 1); + } else { //segmented controls + var controlItems = indicatorWrap.querySelectorAll('.mui-control-item'); + for (var i = 0, len = controlItems.length; i < len; i++) { + controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); + } + } + } + } + e.stopPropagation(); + }, + _handleTabShow: function(e) { + var self = this; + self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime); + }, + _handleIndicatorTap: function(event) { + var self = this; + var target = event.target; + if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) { + self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem'](); + event.stopPropagation(); + } + }, + _initEvent: function(detach) { + var self = this; + self._super(detach); + var action = detach ? 'removeEventListener' : 'addEventListener'; + self.wrapper[action]('slide', this); + self.wrapper[action]($.eventName('shown', 'tab'), this); + }, + handleEvent: function(e) { + this._super(e); + switch (e.type) { + case 'slide': + this._handleSlide(e); + break; + case $.eventName('shown', 'tab'): + if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show + this._handleTabShow(e); + } + break; + } + }, + _scrollend: function(e) { + this._super(e); + this._triggerSlide(e); + }, + _drag: function(e) { + this._super(e); + var direction = e.detail.direction; + if (direction === 'left' || direction === 'right') { + //拖拽期间取消定时 + var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer'); + slidershowTimer && window.clearTimeout(slidershowTimer); + + e.stopPropagation(); + } + }, + _initTimer: function() { + var self = this; + var slider = self.wrapper; + var interval = self.options.interval; + var slidershowTimer = slider.getAttribute('data-slidershowTimer'); + slidershowTimer && window.clearTimeout(slidershowTimer); + if (interval) { + slidershowTimer = window.setTimeout(function() { + if (!slider) { + return; + } + //仅slider显示状态进行自动轮播 + if (!!(slider.offsetWidth || slider.offsetHeight)) { + self.nextItem(true); + //下一个 + } + self._initTimer(); + }, interval); + slider.setAttribute('data-slidershowTimer', slidershowTimer); + } + }, + + _fixedSlideNumber: function(page) { + page = page || this.currentPage; + var slideNumber = page.pageX; + if (this.loop) { + if (page.pageX === 0) { + slideNumber = this.itemLength - 3; + } else if (page.pageX === (this.itemLength - 1)) { + slideNumber = 0; + } else { + slideNumber = page.pageX - 1; + } + } + return slideNumber; + }, + _reLayout: function() { + this.hasHorizontalScroll = true; + this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP); + this._super(); + }, + _getScroll: function() { + var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); + return result ? result.x : 0; + }, + _transitionEnd: function(e) { + if (e.target !== this.scroller || !this.isInTransition) { + return; + } + this._transitionTime(); + this.isInTransition = false; + $.trigger(this.wrapper, 'scrollend', this); + }, + _flick: function(e) { + if (!this.moved) { //无moved + return; + } + var detail = e.detail; + var direction = detail.direction; + this._clearRequestAnimationFrame(); + this.isInTransition = true; + // if (direction === 'up' || direction === 'down') { + // this.resetPosition(this.options.bounceTime); + // return; + // } + if (e.type === 'flick') { + if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime + this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x; + } + this.resetPosition(this.options.bounceTime); + } else if (e.type === 'dragend' && !detail.flick) { + this.resetPosition(this.options.bounceTime); + } + e.stopPropagation(); + }, + _initSnap: function() { + this.scrollerWidth = this.itemLength * this.scrollerWidth; + this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); + this._super(); + if (!this.currentPage.x) { + //当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题 + var currentPage = this.pages[this.loop ? 1 : 0]; + currentPage = currentPage || this.pages[0]; + if (!currentPage) { + return; + } + this.currentPage = currentPage[0]; + this.slideNumber = 0; + this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber; + } else { + this.slideNumber = this._fixedSlideNumber(); + this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber; + } + this.options.startX = this.currentPage.x || 0; + }, + _getSnapX: function(offsetLeft) { + return Math.max(-offsetLeft, this.maxScrollX); + }, + _getPage: function(slideNumber, isFlick) { + if (this.loop) { + if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) { + slideNumber = 1; + time = 0; + } else if (slideNumber < (isFlick ? -1 : 0)) { + slideNumber = this.itemLength - 2; + time = 0; + } else { + slideNumber += 1; + } + } else { + if (!isFlick) { + if (slideNumber > (this.itemLength - 1)) { + slideNumber = 0; + time = 0; + } else if (slideNumber < 0) { + slideNumber = this.itemLength - 1; + time = 0; + } + } + slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1); + } + return this.pages[slideNumber][0]; + }, + _gotoItem: function(slideNumber, time) { + this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画) + this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); + if (time === 0) { + $.trigger(this.wrapper, 'scrollend', this); + } + }, + //API + setTranslate: function(x, y) { + this._super(x, y); + var progressBar = this.progressBar; + if (progressBar) { + this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0); + } + }, + resetPosition: function(time) { + time = time || 0; + if (this.x > 0) { + this.x = 0; + } else if (this.x < this.maxScrollX) { + this.x = this.maxScrollX; + } + this.currentPage = this._nearestSnap(this.x); + this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); + return true; + }, + gotoItem: function(slideNumber, time) { + this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time); + }, + nextItem: function() { + this._gotoItem(this.slideNumber + 1, this.options.scrollTime); + }, + prevItem: function() { + this._gotoItem(this.slideNumber - 1, this.options.scrollTime); + }, + getSlideNumber: function() { + return this.slideNumber || 0; + }, + _reInit: function() { + var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP); + for (var i = 0, len = groups.length; i < len; i++) { + if (groups[i].parentNode === this.wrapper) { + this.scroller = groups[i]; + break; + } + } + this.scrollerStyle = this.scroller && this.scroller.style; + if (this.progressBar) { + this.progressBarWidth = this.progressBar.offsetWidth; + this.progressBarStyle = this.progressBar.style; + } + }, + refresh: function(options) { + if (options) { + $.extend(this.options, options); + this._super(); + this._initTimer(); + } else { + this._super(); + } + }, + destroy: function() { + this._initEvent(true); //detach + delete $.data[this.wrapper.getAttribute('data-slider')]; + this.wrapper.setAttribute('data-slider', ''); + } + }); + $.fn.slider = function(options) { + var slider = null; + this.each(function() { + var sliderElement = this; + if (!this.classList.contains(CLASS_SLIDER)) { + sliderElement = this.querySelector('.' + CLASS_SLIDER); + } + if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) { + var id = sliderElement.getAttribute('data-slider'); + if (!id) { + id = ++$.uuid; + $.data[id] = slider = new Slider(sliderElement, options); + sliderElement.setAttribute('data-slider', id); + } else { + slider = $.data[id]; + if (slider && options) { + slider.refresh(options); + } + } + } + }); + return slider; + }; + $.ready(function() { + // setTimeout(function() { + $('.mui-slider').slider(); + $('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({ + scrollY: false, + scrollX: true, + indicators: false, + snap: '.mui-control-item' + }); + // }, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的) + + }); +})(mui, window); +/** + * pullRefresh 5+ + * @param {type} $ + * @returns {undefined} + */ +(function($, document) { + if (!($.os.plus)) { //仅在5+android支持多webview的使用 + return; + } + $.plusReady(function() { + if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新 + return; + } + var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh'; + var CLASS_VISIBILITY = 'mui-visibility'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_BLOCK = 'mui-block'; + + var CLASS_PULL_CAPTION = 'mui-pull-caption'; + var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; + var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; + var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; + + var PlusPullRefresh = $.Class.extend({ + init: function(element, options) { + this.element = element; + this.options = options; + this.wrapper = this.scroller = element; + this._init(); + this._initPulldownRefreshEvent(); + }, + _init: function() { + var self = this; + //document.addEventListener('plusscrollbottom', this); + window.addEventListener('dragup', self); + document.addEventListener("plusscrollbottom", self); + self.scrollInterval = window.setInterval(function() { + if (self.isScroll && !self.loading) { + if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) { + self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化 + if (self.bottomPocket) { + self.pullupLoading(); + } + } + } + }, 100); + }, + _initPulldownRefreshEvent: function() { + var self = this; + $.plusReady(function() { + if(self.options.down.style == "circle"){ + //单webview、原生转圈 + self.options.webview = plus.webview.currentWebview(); + self.options.webview.setPullToRefresh({ + support: true, + color:self.options.down.color || '#2BD009', + height: self.options.down.height || '50px', + range: self.options.down.range || '100px', + style: 'circle', + offset: self.options.down.offset || '0px' + }, function() { + self.options.down.callback(); + }); + }else if (self.topPocket && self.options.webviewId) { + var webview = plus.webview.getWebviewById(self.options.webviewId);//子窗口 + if (!webview) { + return; + } + self.options.webview = webview; + var downOptions = self.options.down; + var height = downOptions.height; + webview.addEventListener('close', function() { + var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/" + self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId); + }); + webview.addEventListener("dragBounce", function(e) { + if (!self.pulldown) { + self._initPulldownRefresh(); + } else { + self.pullPocket.classList.add(CLASS_BLOCK); + } + switch (e.status) { + case "beforeChangeOffset": //下拉可刷新状态 + self._setCaption(downOptions.contentdown); + break; + case "afterChangeOffset": //松开可刷新状态 + self._setCaption(downOptions.contentover); + break; + case "dragEndAfterChangeOffset": //正在刷新状态 + //执行下拉刷新所在webview的回调函数 + webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()"); + self._setCaption(downOptions.contentrefresh); + break; + default: + break; + } + }, false); + + webview.setBounce({ + position: { + top: height * 2 + 'px' + }, + changeoffset: { + top: height + 'px' + } + }); + + } + }); + }, + handleEvent: function(e) { + var self = this; + if (self.stopped) { + return; + } + self.isScroll = false; + if (e.type === 'dragup' || e.type === 'plusscrollbottom') { + self.isScroll = true; + setTimeout(function() { + self.isScroll = false; + }, 1000); + } + } + }).extend($.extend({ + setStopped: function(stopped) { //该方法是子页面调用的 + this.stopped = !!stopped; + //TODO 此处需要设置当前webview的bounce为none,目前5+有BUG + var webview = plus.webview.currentWebview(); + if (this.stopped) { + webview.setStyle({ + bounce: 'none' + }); + webview.setBounce({ + position: { + top: 'none' + } + }); + } else { + var height = this.options.down.height; + webview.setStyle({ + bounce: 'vertical' + }); + webview.setBounce({ + position: { + top: height * 2 + 'px' + }, + changeoffset: { + top: height + 'px' + } + }); + } + }, + beginPulldown:function() { + var self = this; + $.plusReady(function() { + //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的 + setTimeout(function () { + if(self.options.down.style == "circle"){//单webview下拉刷新 + plus.webview.currentWebview().beginPullToRefresh(); + }else{//双webview模式 + plus.webview.currentWebview().setBounce({ + offset: { + top: self.options.down.height + "px" + } + }); + } + },15); + }.bind(this)); + }, + pulldownLoading: function () {//该方法是子页面调用的,兼容老的历史API + this.beginPulldown(); + }, + _pulldownLoading: function() { //该方法是父页面调用的 + var self = this; + $.plusReady(function() { + var childWebview = plus.webview.getWebviewById(self.options.webviewId); + childWebview && childWebview.setBounce({ + offset: { + top: self.options.down.height + "px" + } + }); + }); + }, + endPulldown:function(){ + var _wv = plus.webview.currentWebview(); + //双webview的下拉刷新,需要修改父窗口提示信息 + if(_wv.parent() && this.options.down.style !== "circle"){ + _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({ + webviewId: _wv.id + }) + "')._endPulldownToRefresh()"); + }else{ + _wv.endPullToRefresh(); + } + }, + endPulldownToRefresh: function () {//该方法是子页面调用的,兼容老的历史API + this.endPulldown(); + }, + _endPulldownToRefresh: function() { //该方法是父页面调用的 + var self = this; + if (self.topPocket && self.options.webview) { + self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹 + self.loading = false; + self._setCaption(self.options.down.contentdown, true); + setTimeout(function() { + self.loading || self.topPocket.classList.remove(CLASS_BLOCK); + }, 350); + } + }, + beginPullup:function(callback) {//开始上拉加载 + var self = this; + if (self.isLoading) return; + self.isLoading = true; + if (self.pulldown !== false) { + self._initPullupRefresh(); + } else { + this.pullPocket.classList.add(CLASS_BLOCK); + } + setTimeout(function() { + self.pullLoading.classList.add(CLASS_VISIBILITY); + self.pullLoading.classList.remove(CLASS_HIDDEN); + self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的) + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH; + self.pullCaption.innerHTML = self.options.up.contentrefresh; + callback = callback || self.options.up.callback; + callback && callback.call(self); + }, 300); + }, + pullupLoading:function (callback) {//兼容老的API + this.beginPullup(callback); + }, + endPullup:function(finished) {//上拉加载结束 + var self = this; + if (self.pullLoading) { + self.pullLoading.classList.remove(CLASS_VISIBILITY); + self.pullLoading.classList.add(CLASS_HIDDEN); + self.isLoading = false; + if (finished) { + self.finished = true; + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; + self.pullCaption.innerHTML = self.options.up.contentnomore; + //取消5+的plusscrollbottom事件 + document.removeEventListener('plusscrollbottom', self); + window.removeEventListener('dragup', self); + } else { //初始化时隐藏,后续不再隐藏 + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + self.pullCaption.innerHTML = self.options.up.contentdown; + } + } + }, + endPullupToRefresh: function (finished) {//上拉加载结束,兼容老的API + this.endPullup(finished); + }, + disablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; + window.removeEventListener('dragup', this); + }, + enablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.classList.remove(CLASS_HIDDEN); + this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + this.pullCaption.innerHTML = this.options.up.contentdown; + document.addEventListener("plusscrollbottom", this); + window.addEventListener('dragup', this); + }, + scrollTo: function(x, y, time) { + $.scrollTo(y, time); + }, + scrollToBottom: function(time) { + $.scrollTo(document.documentElement.scrollHeight, time); + }, + refresh: function(isReset) { + if (isReset && this.finished) { + this.enablePullupToRefresh(); + this.finished = false; + } + } + }, $.PullRefresh)); + + //override h5 pullRefresh + $.fn.pullRefresh_native = function(options) { + var self; + if (this.length === 0) { + self = document.createElement('div'); + self.className = 'mui-content'; + document.body.appendChild(self); + } else { + self = this[0]; + } + var args = options; + //一个父需要支持多个子下拉刷新 + options = options || {} + if (typeof options === 'string') { + options = $.parseJSON(options); + }; + !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL())); + var pullRefreshApi = null; + var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/" + var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId); + if (!id && typeof args === 'undefined') { + return false; + } + if (!id) { //避免重复初始化5+ pullrefresh + id = ++$.uuid; + self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id); + document.body.classList.add(CLASS_PLUS_PULLREFRESH); + $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options); + } else { + pullRefreshApi = $.data[id]; + } + if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 + //pullRefreshApi._pulldownLoading(); //parent webview + pullRefreshApi.beginPulldown(); + } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 + pullRefreshApi.beginPullup(); + } + return pullRefreshApi; + }; + }); + +})(mui, document); +/** + * off-canvas + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} action + * @returns {undefined} + */ +(function($, window, document, name) { + var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left'; + var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right'; + var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop'; + var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap'; + + var CLASS_SLIDE_IN = 'mui-slide-in'; + var CLASS_ACTIVE = 'mui-active'; + + + var CLASS_TRANSITIONING = 'mui-transitioning'; + + var SELECTOR_INNER_WRAP = '.mui-inner-wrap'; + + + var OffCanvas = $.Class.extend({ + init: function(element, options) { + this.wrapper = this.element = element; + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + this.classList = this.wrapper.classList; + if (this.scroller) { + this.options = $.extend(true, { + dragThresholdX: 10, + scale: 0.8, + opacity: 0.1, + preventDefaultException: { + tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ + }, + }, options); + document.body.classList.add('mui-fullscreen'); //fullscreen + this.refresh(); + this.initEvent(); + } + }, + _preventDefaultException: function(el, exceptions) { + for (var i in exceptions) { + if (exceptions[i].test(el[i])) { + return true; + } + } + return false; + }, + refresh: function(offCanvas) { + // offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE); + this.slideIn = this.classList.contains(CLASS_SLIDE_IN); + this.scalable = this.classList.contains('mui-scalable') && !this.slideIn; + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + // !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING); + // !offCanvas && this.scroller.setAttribute('style', ''); + this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT); + this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT); + if (offCanvas) { + if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { + this.offCanvasLeft = offCanvas; + } else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { + this.offCanvasRight = offCanvas; + } + } else { + this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT); + this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT); + } + this.offCanvasRightWidth = this.offCanvasLeftWidth = 0; + this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false; + if (this.offCanvasRight) { + this.offCanvasRightWidth = this.offCanvasRight.offsetWidth; + this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper); + // this.offCanvasRight.classList.remove(CLASS_TRANSITIONING); + // this.offCanvasRight.classList.remove(CLASS_ACTIVE); + // this.offCanvasRight.setAttribute('style', ''); + } + if (this.offCanvasLeft) { + this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth; + this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper); + // this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING); + // this.offCanvasLeft.classList.remove(CLASS_ACTIVE); + // this.offCanvasLeft.setAttribute('style', ''); + } + this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP); + + this.options.dragThresholdX = this.options.dragThresholdX || 10; + + this.visible = false; + this.startX = null; + this.lastX = null; + this.offsetX = null; + this.lastTranslateX = null; + }, + handleEvent: function(e) { + switch (e.type) { + case $.EVENT_START: + e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); + break; + case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况 + if (e.target === this.scroller) { + this._dispatchEvent(); + } + break; + case 'drag': + var detail = e.detail; + if (!this.startX) { + this.startX = detail.center.x; + this.lastX = this.startX; + } else { + this.lastX = detail.center.x; + } + if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) { + if (this.slideIn) { + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + if (this.classList.contains(CLASS_ACTIVE)) { + if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } + } else { + if (detail.direction === 'left' && this.offCanvasRight) { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else if (detail.direction === 'right' && this.offCanvasLeft) { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.scroller = null; + } + } + } else { + if (this.classList.contains(CLASS_ACTIVE)) { + if (detail.direction === 'left') { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } + } else { + if (detail.direction === 'right') { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } + } + } + if (this.offCanvas && this.scroller) { + this.startX = this.lastX; + this.isDragging = true; + + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + + this.offCanvas.classList.remove(CLASS_TRANSITIONING); + this.scroller.classList.remove(CLASS_TRANSITIONING); + this.offsetX = this.getTranslateX(); + this._initOffCanvasVisible(); + } + } + if (this.isDragging) { + this.updateTranslate(this.offsetX + (this.lastX - this.startX)); + detail.gesture.preventDefault(); + e.stopPropagation(); + } + break; + case 'dragend': + if (this.isDragging) { + var detail = e.detail; + var direction = detail.direction; + this.isDragging = false; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + var ratio = 0; + var x = this.getTranslateX(); + if (!this.slideIn) { + if (x >= 0) { + ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; + } else { + ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; + } + if (ratio === 0) { + this.openPercentage(0); + this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch + return; + } + if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开 + this.openPercentage(100); + } else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio < 0.5) { //右滑还原打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio > 0.5) { //左滑还原打开 + this.openPercentage(100); + } else { //默认关闭 + this.openPercentage(0); + } + if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch + this._dispatchEvent(); + } + } else { + if (x >= 0) { + ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; + } else { + ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; + } + if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开 + this.openPercentage(100); + } else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开 + this.openPercentage(100); + } else { + this.openPercentage(0); + } + if (ratio === 1 || ratio === -1 || ratio === 0) { + this._dispatchEvent(); + return; + } + + } + } + break; + } + }, + _dispatchEvent: function() { + if (this.classList.contains(CLASS_ACTIVE)) { + $.trigger(this.wrapper, 'shown', this); + } else { + $.trigger(this.wrapper, 'hidden', this); + } + }, + _initOffCanvasVisible: function() { + if (!this.visible) { + this.visible = true; + if (this.offCanvasLeft) { + this.offCanvasLeft.style.visibility = 'visible'; + } + if (this.offCanvasRight) { + this.offCanvasRight.style.visibility = 'visible'; + } + } + }, + initEvent: function() { + var self = this; + if (self.backdrop) { + self.backdrop.addEventListener('tap', function(e) { + self.close(); + e.detail.gesture.preventDefault(); + }); + } + if (this.classList.contains('mui-draggable')) { + this.wrapper.addEventListener($.EVENT_START, this); //临时处理 + this.wrapper.addEventListener('drag', this); + this.wrapper.addEventListener('dragend', this); + } + this.wrapper.addEventListener('webkitTransitionEnd', this); + }, + openPercentage: function(percentage) { + var p = percentage / 100; + if (!this.slideIn) { + if (this.offCanvasLeft && percentage >= 0) { + this.updateTranslate(this.offCanvasLeftWidth * p); + this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else if (this.offCanvasRight && percentage <= 0) { + this.updateTranslate(this.offCanvasRightWidth * p); + this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else { + if (this.offCanvasLeft && percentage >= 0) { + p = p === 0 ? -1 : 0; + this.updateTranslate(this.offCanvasLeftWidth * p); + this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else if (this.offCanvasRight && percentage <= 0) { + p = p === 0 ? 1 : 0; + this.updateTranslate(this.offCanvasRightWidth * p); + this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + }, + updateTranslate: function(x) { + if (x !== this.lastTranslateX) { + if (!this.slideIn) { + if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) { + this.setTranslateX(0); + return; + } + if (this.leftShowing && x > this.offCanvasLeftWidth) { + this.setTranslateX(this.offCanvasLeftWidth); + return; + } + if (this.rightShowing && x < -this.offCanvasRightWidth) { + this.setTranslateX(-this.offCanvasRightWidth); + return; + } + this.setTranslateX(x); + if (x >= 0) { + this.leftShowing = true; + this.rightShowing = false; + if (x > 0) { + if (this.offCanvasLeft) { + $.each(this.offCanvasLefts, function(index, offCanvas) { + if (offCanvas === this.offCanvasLeft) { + this.offCanvasLeft.style.zIndex = 0; + } else { + offCanvas.style.zIndex = -1; + } + }.bind(this)); + } + if (this.offCanvasRight) { + this.offCanvasRight.style.zIndex = -1; + } + } + } else { + this.rightShowing = true; + this.leftShowing = false; + if (this.offCanvasRight) { + $.each(this.offCanvasRights, function(index, offCanvas) { + if (offCanvas === this.offCanvasRight) { + offCanvas.style.zIndex = 0; + } else { + offCanvas.style.zIndex = -1; + } + }.bind(this)); + } + if (this.offCanvasLeft) { + this.offCanvasLeft.style.zIndex = -1; + } + } + } else { + if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { + if (x < 0) { + this.setTranslateX(0); + return; + } + if (x > this.offCanvasRightWidth) { + this.setTranslateX(this.offCanvasRightWidth); + return; + } + } else { + if (x > 0) { + this.setTranslateX(0); + return; + } + if (x < -this.offCanvasLeftWidth) { + this.setTranslateX(-this.offCanvasLeftWidth); + return; + } + } + this.setTranslateX(x); + } + this.lastTranslateX = x; + } + }, + setTranslateX: $.animationFrame(function(x) { + if (this.scroller) { + if (this.scalable && this.offCanvas.parentNode === this.wrapper) { + var percent = Math.abs(x) / this.offCanvasWidth; + var zoomOutScale = 1 - (1 - this.options.scale) * percent; + var zoomInScale = this.options.scale + (1 - this.options.scale) * percent; + var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent; + var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent; + if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { + this.offCanvas.style.webkitTransformOrigin = '-100%'; + this.scroller.style.webkitTransformOrigin = 'left'; + } else { + this.offCanvas.style.webkitTransformOrigin = '200%'; + this.scroller.style.webkitTransformOrigin = 'right'; + } + this.offCanvas.style.opacity = zoomInOpacity; + this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')'; + this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')'; + } else { + if (this.slideIn) { + this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; + } else { + this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; + } + } + } + }), + getTranslateX: function() { + if (this.offCanvas) { + var scroller = this.slideIn ? this.offCanvas : this.scroller; + var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform')); + return (result && result.x) || 0; + } + return 0; + }, + isShown: function(direction) { + var shown = false; + if (!this.slideIn) { + var x = this.getTranslateX(); + if (direction === 'right') { + shown = this.classList.contains(CLASS_ACTIVE) && x < 0; + } else if (direction === 'left') { + shown = this.classList.contains(CLASS_ACTIVE) && x > 0; + } else { + shown = this.classList.contains(CLASS_ACTIVE) && x !== 0; + } + } else { + if (direction === 'left') { + shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); + } else if (direction === 'right') { + shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE); + } else { + shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE)); + } + } + return shown; + }, + close: function() { + this._initOffCanvasVisible(); + this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); + this.offCanvasWidth = this.offCanvas.offsetWidth; + if (this.scroller) { + this.offCanvas.offsetHeight; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + this.openPercentage(0); + } + }, + show: function(direction) { + this._initOffCanvasVisible(); + if (this.isShown(direction)) { + return false; + } + if (!direction) { + direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left'; + } + if (direction === 'right') { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } + if (this.scroller) { + this.offCanvas.offsetHeight; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + this.openPercentage(direction === 'left' ? 100 : -100); + } + return true; + }, + toggle: function(directionOrOffCanvas) { + var direction = directionOrOffCanvas; + if (directionOrOffCanvas && directionOrOffCanvas.classList) { + direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right'; + this.refresh(directionOrOffCanvas); + } + if (!this.show(direction)) { + this.close(); + } + } + }); + + //hash to offcanvas + var findOffCanvasContainer = function(target) { + parentNode = target.parentNode; + if (parentNode) { + if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + return parentNode; + } else { + parentNode = parentNode.parentNode; + if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + return parentNode; + } + } + } + }; + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + var offcanvas = document.getElementById(target.hash.replace('#', '')); + if (offcanvas) { + var container = findOffCanvasContainer(offcanvas); + if (container) { + $.targets._container = container; + return offcanvas; + } + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 60, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + window.addEventListener('tap', function(e) { + if (!$.targets.offcanvas) { + return; + } + //TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好 + var target = e.target; + for (; target && target !== document; target = target.parentNode) { + if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) { + e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange + $($.targets._container).offCanvas().toggle($.targets.offcanvas); + $.targets.offcanvas = $.targets._container = null; + break; + } + } + }); + + $.fn.offCanvas = function(options) { + var offCanvasApis = []; + this.each(function() { + var offCanvasApi = null; + var self = this; + //hack old version + if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + self = findOffCanvasContainer(self); + } + var id = self.getAttribute('data-offCanvas'); + if (!id) { + id = ++$.uuid; + $.data[id] = offCanvasApi = new OffCanvas(self, options); + self.setAttribute('data-offCanvas', id); + } else { + offCanvasApi = $.data[id]; + } + if (options === 'show' || options === 'close' || options === 'toggle') { + offCanvasApi.toggle(); + } + offCanvasApis.push(offCanvasApi); + }); + return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis; + }; + $.ready(function() { + $('.mui-off-canvas-wrap').offCanvas(); + }); +})(mui, window, document, 'offcanvas'); +/** + * actions + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var CLASS_ACTION = 'mui-action'; + + var handle = function(event, target) { + var className = target.className || ''; + if (typeof className !== 'string') { //svg className(SVGAnimatedString) + className = ''; + } + if (className && ~className.indexOf(CLASS_ACTION)) { + if (target.classList.contains('mui-action-back')) { + event.preventDefault(); + } + return target; + } + return false; + }; + + $.registerTarget({ + name: name, + index: 50, + handle: handle, + target: false, + isContinue: true + }); + +})(mui, 'action'); +/** + * Modals + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} name + * @returns {undefined} + */ +(function($, window, document, name) { + var CLASS_MODAL = 'mui-modal'; + + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + var modal = document.getElementById(target.hash.replace('#', '')); + if (modal && modal.classList.contains(CLASS_MODAL)) { + return modal; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 50, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + window.addEventListener('tap', function(event) { + if ($.targets.modal) { + event.detail.gesture.preventDefault(); //fixed hashchange + $.targets.modal.classList.toggle('mui-active'); + } + }); +})(mui, window, document, 'modal'); +/** + * Popovers + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} name + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, document, name) { + + var CLASS_POPOVER = 'mui-popover'; + var CLASS_POPOVER_ARROW = 'mui-popover-arrow'; + var CLASS_ACTION_POPOVER = 'mui-popover-action'; + var CLASS_BACKDROP = 'mui-backdrop'; + var CLASS_BAR_POPOVER = 'mui-bar-popover'; + var CLASS_BAR_BACKDROP = 'mui-bar-backdrop'; + var CLASS_ACTION_BACKDROP = 'mui-backdrop-action'; + var CLASS_ACTIVE = 'mui-active'; + var CLASS_BOTTOM = 'mui-bottom'; + + + + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + $.targets._popover = document.getElementById(target.hash.replace('#', '')); + if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) { + return target; + } else { + $.targets._popover = null; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 60, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + var onPopoverShown = function(e) { + this.removeEventListener('webkitTransitionEnd', onPopoverShown); + this.addEventListener($.EVENT_MOVE, $.preventDefault); + $.trigger(this, 'shown', this); + } + var onPopoverHidden = function(e) { + setStyle(this, 'none'); + this.removeEventListener('webkitTransitionEnd', onPopoverHidden); + this.removeEventListener($.EVENT_MOVE, $.preventDefault); + $.trigger(this, 'hidden', this); + }; + + var backdrop = (function() { + var element = document.createElement('div'); + element.classList.add(CLASS_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('tap', function(e) { + var popover = $.targets._popover; + if (popover) { + popover.addEventListener('webkitTransitionEnd', onPopoverHidden); + popover.classList.remove(CLASS_ACTIVE); + removeBackdrop(popover); + } + }); + + return element; + }()); + var removeBackdropTimer; + var removeBackdrop = function(popover) { + backdrop.setAttribute('style', 'opacity:0'); + $.targets.popover = $.targets._popover = null; //reset + removeBackdropTimer = $.later(function() { + if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) { + document.body.removeChild(backdrop); + } + }, 350); + }; + window.addEventListener('tap', function(e) { + if (!$.targets.popover) { + return; + } + var toggle = false; + var target = e.target; + for (; target && target !== document; target = target.parentNode) { + if (target === $.targets.popover) { + toggle = true; + } + } + if (toggle) { + e.detail.gesture.preventDefault(); //fixed hashchange + togglePopover($.targets._popover, $.targets.popover); + } + + }); + + var togglePopover = function(popover, anchor, state) { + if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) { + return; + } + removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer + //remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove + popover.removeEventListener('webkitTransitionEnd', onPopoverShown); + popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); + backdrop.classList.remove(CLASS_BAR_BACKDROP); + backdrop.classList.remove(CLASS_ACTION_BACKDROP); + var _popover = document.querySelector('.mui-popover.mui-active'); + if (_popover) { + // _popover.setAttribute('style', ''); + _popover.addEventListener('webkitTransitionEnd', onPopoverHidden); + _popover.classList.remove(CLASS_ACTIVE); + // _popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); + //同一个弹出则直接返回,解决同一个popover的toggle + if (popover === _popover) { + removeBackdrop(_popover); + return; + } + } + var isActionSheet = false; + if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar + if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover + isActionSheet = true; + backdrop.classList.add(CLASS_ACTION_BACKDROP); + } else { //bar popover + backdrop.classList.add(CLASS_BAR_BACKDROP); + // if (anchor) { + // if (anchor.parentNode) { + // var offsetWidth = anchor.offsetWidth; + // var offsetLeft = anchor.offsetLeft; + // var innerWidth = window.innerWidth; + // popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px"; + // } else { + // //TODO anchor is position:{left,top,bottom,right} + // } + // } + } + } + setStyle(popover, 'block'); //actionsheet transform + popover.offsetHeight; + popover.classList.add(CLASS_ACTIVE); + backdrop.setAttribute('style', ''); + document.body.appendChild(backdrop); + calPosition(popover, anchor, isActionSheet); //position + backdrop.classList.add(CLASS_ACTIVE); + popover.addEventListener('webkitTransitionEnd', onPopoverShown); + }; + var setStyle = function(popover, display, top, left) { + var style = popover.style; + if (typeof display !== 'undefined') + style.display = display; + if (typeof top !== 'undefined') + style.top = top + 'px'; + if (typeof left !== 'undefined') + style.left = left + 'px'; + }; + var calPosition = function(popover, anchor, isActionSheet) { + if (!popover || !anchor) { + return; + } + + if (isActionSheet) { //actionsheet + setStyle(popover, 'block') + return; + } + + var wWidth = window.innerWidth; + var wHeight = window.innerHeight; + + var pWidth = popover.offsetWidth; + var pHeight = popover.offsetHeight; + + var aWidth = anchor.offsetWidth; + var aHeight = anchor.offsetHeight; + var offset = $.offset(anchor); + + var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW); + if (!arrow) { + arrow = document.createElement('div'); + arrow.className = CLASS_POPOVER_ARROW; + popover.appendChild(arrow); + } + var arrowSize = arrow && arrow.offsetWidth / 2 || 0; + + + + var pTop = 0; + var pLeft = 0; + var diff = 0; + var arrowLeft = 0; + var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5; + + var position = 'top'; + if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top + pTop = offset.top - pHeight - arrowSize; + } else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom + position = 'bottom'; + pTop = offset.top + aHeight + arrowSize; + } else { //middle + position = 'middle'; + pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0); + pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0); + } + if (position === 'top' || position === 'bottom') { + pLeft = aWidth / 2 + offset.left - pWidth / 2; + diff = pLeft; + if (pLeft < defaultPadding) pLeft = defaultPadding; + if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding; + + if (arrow) { + if (position === 'top') { + arrow.classList.add(CLASS_BOTTOM); + } else { + arrow.classList.remove(CLASS_BOTTOM); + } + diff = diff - pLeft; + arrowLeft = (pWidth / 2 - arrowSize / 2 + diff); + arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6); + arrow.setAttribute('style', 'left:' + arrowLeft + 'px'); + } + } else if (position === 'middle') { + arrow.setAttribute('style', 'display:none'); + } + setStyle(popover, 'block', pTop, pLeft); + }; + + $.createMask = function(callback) { + var element = document.createElement('div'); + element.classList.add(CLASS_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('tap', function() { + mask.close(); + }); + var mask = [element]; + mask._show = false; + mask.show = function() { + mask._show = true; + element.setAttribute('style', 'opacity:1'); + document.body.appendChild(element); + return mask; + }; + mask._remove = function() { + if (mask._show) { + mask._show = false; + element.setAttribute('style', 'opacity:0'); + $.later(function() { + var body = document.body; + element.parentNode === body && body.removeChild(element); + }, 350); + } + return mask; + }; + mask.close = function() { + if (callback) { + if (callback() !== false) { + mask._remove(); + } + } else { + mask._remove(); + } + }; + return mask; + }; + $.fn.popover = function() { + var args = arguments; + this.each(function() { + $.targets._popover = this; + if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') { + togglePopover(this, args[1], args[0]); + } + }); + }; + +})(mui, window, document, 'popover'); +/** + * segmented-controllers + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, document, name, undefined) { + + var CLASS_CONTROL_ITEM = 'mui-control-item'; + var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control'; + var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical'; + var CLASS_CONTROL_CONTENT = 'mui-control-content'; + var CLASS_TAB_BAR = 'mui-bar-tab'; + var CLASS_TAB_ITEM = 'mui-tab-item'; + var CLASS_SLIDER_ITEM = 'mui-slider-item'; + + var handle = function(event, target) { + if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) { + if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) { + //vertical 如果preventDefault会导致无法滚动 + } else { + event.preventDefault(); //stop hash change + } + // if (target.hash) { + return target; + // } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 80, + handle: handle, + target: false + }); + + window.addEventListener('tap', function(e) { + + var targetTab = $.targets.tab; + if (!targetTab) { + return; + } + var activeTab; + var activeBodies; + var targetBody; + var className = 'mui-active'; + var classSelector = '.' + className; + var segmentedControl = targetTab.parentNode; + + for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) { + if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) { + activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM); + break; + } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) { + activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM); + } + } + + if (activeTab) { + activeTab.classList.remove(className); + } + + var isLastActive = targetTab === activeTab; + if (targetTab) { + targetTab.classList.add(className); + } + + if (!targetTab.hash) { + return; + } + targetBody = document.getElementById(targetTab.hash.replace('#', '')); + + if (!targetBody) { + return; + } + if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover + targetTab.classList[isLastActive ? 'remove' : 'add'](className); + return; + } + if (isLastActive) { //same + return; + } + var parentNode = targetBody.parentNode; + activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector); + for (var i = 0; i < activeBodies.length; i++) { + var activeBody = activeBodies[i]; + activeBody.parentNode === parentNode && activeBody.classList.remove(className); + } + + targetBody.classList.add(className); + + var contents = []; + var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT); + for (var i = 0; i < _contents.length; i++) { //查找直属子节点 + _contents[i].parentNode === parentNode && (contents.push(_contents[i])); + } + $.trigger(targetBody, $.eventName('shown', name), { + tabNumber: Array.prototype.indexOf.call(contents, targetBody) + }); + e.detail && e.detail.gesture.preventDefault(); //fixed hashchange + }); + +})(mui, window, document, 'tab'); +/** + * Toggles switch + * @param {type} $ + * @param {type} window + * @param {type} name + * @returns {undefined} + */ +(function($, window, name) { + + var CLASS_SWITCH = 'mui-switch'; + var CLASS_SWITCH_HANDLE = 'mui-switch-handle'; + var CLASS_ACTIVE = 'mui-active'; + var CLASS_DRAGGING = 'mui-dragging'; + + var CLASS_DISABLED = 'mui-disabled'; + + var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE; + + var handle = function(event, target) { + if (target.classList && target.classList.contains(CLASS_SWITCH)) { + return target; + } + return false; + }; + + $.registerTarget({ + name: name, + index: 100, + handle: handle, + target: false + }); + + + var Toggle = function(element) { + this.element = element; + this.classList = this.element.classList; + this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE); + this.init(); + this.initEvent(); + }; + Toggle.prototype.init = function() { + this.toggleWidth = this.element.offsetWidth; + this.handleWidth = this.handle.offsetWidth; + this.handleX = this.toggleWidth - this.handleWidth - 3; + }; + Toggle.prototype.initEvent = function() { + this.element.addEventListener($.EVENT_START, this); + this.element.addEventListener('drag', this); + this.element.addEventListener('swiperight', this); + this.element.addEventListener($.EVENT_END, this); + this.element.addEventListener($.EVENT_CANCEL, this); + + }; + Toggle.prototype.handleEvent = function(e) { + if (this.classList.contains(CLASS_DISABLED)) { + return; + } + switch (e.type) { + case $.EVENT_START: + this.start(e); + break; + case 'drag': + this.drag(e); + break; + case 'swiperight': + this.swiperight(); + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + this.end(e); + break; + } + }; + Toggle.prototype.start = function(e) { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; + this.classList.add(CLASS_DRAGGING); + if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化 + this.init(); + } + }; + Toggle.prototype.drag = function(e) { + var detail = e.detail; + if (!this.isDragging) { + if (detail.direction === 'left' || detail.direction === 'right') { + this.isDragging = true; + this.lastChanged = undefined; + this.initialState = this.classList.contains(CLASS_ACTIVE); + } + } + if (this.isDragging) { + this.setTranslateX(detail.deltaX); + e.stopPropagation(); + detail.gesture.preventDefault(); + } + }; + Toggle.prototype.swiperight = function(e) { + if (this.isDragging) { + e.stopPropagation(); + } + }; + Toggle.prototype.end = function(e) { + this.classList.remove(CLASS_DRAGGING); + if (this.isDragging) { + this.isDragging = false; + e.stopPropagation(); + $.trigger(this.element, 'toggle', { + isActive: this.classList.contains(CLASS_ACTIVE) + }); + } else { + this.toggle(); + } + }; + Toggle.prototype.toggle = function(animate) { + var classList = this.classList; + if (animate === false) { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s'; + } else { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; + } + if (classList.contains(CLASS_ACTIVE)) { + classList.remove(CLASS_ACTIVE); + this.handle.style.webkitTransform = 'translate(0,0)'; + } else { + classList.add(CLASS_ACTIVE); + this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)'; + } + $.trigger(this.element, 'toggle', { + isActive: this.classList.contains(CLASS_ACTIVE) + }); + }; + Toggle.prototype.setTranslateX = $.animationFrame(function(x) { + if (!this.isDragging) { + return; + } + var isChanged = false; + if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) { + isChanged = true; + } + if (this.lastChanged !== isChanged) { + if (isChanged) { + this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)'; + this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE); + } else { + this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)'; + this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.lastChanged = isChanged; + } + + }); + + $.fn['switch'] = function(options) { + var switchApis = []; + this.each(function() { + var switchApi = null; + var id = this.getAttribute('data-switch'); + if (!id) { + id = ++$.uuid; + $.data[id] = new Toggle(this); + this.setAttribute('data-switch', id); + } else { + switchApi = $.data[id]; + } + switchApis.push(switchApi); + }); + return switchApis.length > 1 ? switchApis : switchApis[0]; + }; + $.ready(function() { + $('.' + CLASS_SWITCH)['switch'](); + }); +})(mui, window, 'toggle'); +/** + * Tableviews + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + + var CLASS_ACTIVE = 'mui-active'; + var CLASS_SELECTED = 'mui-selected'; + var CLASS_GRID_VIEW = 'mui-grid-view'; + var CLASS_RADIO_VIEW = 'mui-table-view-radio'; + var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell'; + var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content'; + var CLASS_DISABLED = 'mui-disabled'; + var CLASS_TOGGLE = 'mui-switch'; + var CLASS_BTN = 'mui-btn'; + + var CLASS_SLIDER_HANDLE = 'mui-slider-handle'; + var CLASS_SLIDER_LEFT = 'mui-slider-left'; + var CLASS_SLIDER_RIGHT = 'mui-slider-right'; + var CLASS_TRANSITIONING = 'mui-transitioning'; + + + var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE; + var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT; + var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT; + var SELECTOR_SELECTED = '.' + CLASS_SELECTED; + var SELECTOR_BUTTON = '.' + CLASS_BTN; + var overFactor = 0.8; + var cell, a; + + var isMoved = isOpened = openedActions = progress = false; + var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; + var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0; + + + + var toggleActive = function(isActive) { + if (isActive) { + if (a) { + a.classList.add(CLASS_ACTIVE); + } else if (cell) { + cell.classList.add(CLASS_ACTIVE); + } + } else { + timer && timer.cancel(); + if (a) { + a.classList.remove(CLASS_ACTIVE); + } else if (cell) { + cell.classList.remove(CLASS_ACTIVE); + } + } + }; + + var updateTranslate = function() { + if (translateX !== lastTranslateX) { + if (buttonsRight && buttonsRight.length > 0) { + progress = translateX / sliderActionRightWidth; + if (translateX < -sliderActionRightWidth) { + translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor); + } + for (var i = 0, len = buttonsRight.length; i < len; i++) { + var buttonRight = buttonsRight[i]; + if (typeof buttonRight._buttonOffset === 'undefined') { + buttonRight._buttonOffset = buttonRight.offsetLeft; + } + buttonOffset = buttonRight._buttonOffset; + setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1)))); + } + } + if (buttonsLeft && buttonsLeft.length > 0) { + progress = translateX / sliderActionLeftWidth; + if (translateX > sliderActionLeftWidth) { + translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor); + } + for (var i = 0, len = buttonsLeft.length; i < len; i++) { + var buttonLeft = buttonsLeft[i]; + if (typeof buttonLeft._buttonOffset === 'undefined') { + buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; + } + buttonOffset = buttonLeft._buttonOffset; + if (buttonsLeft.length > 1) { + buttonLeft.style.zIndex = buttonsLeft.length - i; + } + setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1)))); + } + } + setTranslate(sliderHandle, translateX); + lastTranslateX = translateX; + } + sliderRequestAnimationFrame = requestAnimationFrame(function() { + updateTranslate(); + }); + }; + var setTranslate = function(element, x) { + if (element) { + element.style.webkitTransform = 'translate(' + x + 'px,0)'; + } + }; + + window.addEventListener($.EVENT_START, function(event) { + if (cell) { + toggleActive(false); + } + cell = a = false; + isMoved = isOpened = openedActions = false; + var target = event.target; + var isDisabled = false; + for (; target && target !== document; target = target.parentNode) { + if (target.classList) { + var classList = target.classList; + if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) { + isDisabled = true; + } + if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content + break; + } + if (classList.contains(CLASS_TABLE_VIEW_CELL)) { + cell = target; + //TODO swipe to delete close + var selected = cell.parentNode.querySelector(SELECTOR_SELECTED); + if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) { + $.swipeoutClose(selected); + cell = isDisabled = false; + return; + } + if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) { + var link = cell.querySelector('a'); + if (link && link.parentNode === cell) { //li>a + a = link; + } + } + var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE); + if (handle) { + toggleEvents(cell); + event.stopPropagation(); + } + if (!isDisabled) { + if (handle) { + if (timer) { + timer.cancel(); + } + timer = $.later(function() { + toggleActive(true); + }, 100); + } else { + toggleActive(true); + } + } + break; + } + } + } + }); + window.addEventListener($.EVENT_MOVE, function(event) { + toggleActive(false); + }); + + var handleEvent = { + handleEvent: function(event) { + switch (event.type) { + case 'drag': + this.drag(event); + break; + case 'dragend': + this.dragend(event); + break; + case 'flick': + this.flick(event); + break; + case 'swiperight': + this.swiperight(event); + break; + case 'swipeleft': + this.swipeleft(event); + break; + } + }, + drag: function(event) { + if (!cell) { + return; + } + if (!isMoved) { //init + sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; + sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE); + if (sliderHandle) { + sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT); + sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT); + if (sliderActionLeft) { + sliderActionLeftWidth = sliderActionLeft.offsetWidth; + buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON); + } + if (sliderActionRight) { + sliderActionRightWidth = sliderActionRight.offsetWidth; + buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON); + } + cell.classList.remove(CLASS_TRANSITIONING); + isOpened = cell.classList.contains(CLASS_SELECTED); + if (isOpened) { + openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right'; + } + } + } + var detail = event.detail; + var direction = detail.direction; + var angle = detail.angle; + if (direction === 'left' && (angle > 150 || angle < -150)) { + if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态 + isMoved = true; + } + } else if (direction === 'right' && (angle > -30 && angle < 30)) { + if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态 + isMoved = true; + } + } + if (isMoved) { + event.stopPropagation(); + event.detail.gesture.preventDefault(); + var translate = event.detail.deltaX; + if (isOpened) { + if (openedActions === 'right') { + translate = translate - sliderActionRightWidth; + } else { + translate = translate + sliderActionLeftWidth; + } + } + if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) { + if (!isOpened) { + return; + } + translate = 0; + } + if (translate < 0) { + sliderDirection = 'toLeft'; + } else if (translate > 0) { + sliderDirection = 'toRight'; + } else { + if (!sliderDirection) { + sliderDirection = 'toLeft'; + } + } + if (!sliderRequestAnimationFrame) { + updateTranslate(); + } + translateX = translate; + } + }, + flick: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + swipeleft: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + swiperight: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + dragend: function(event) { + if (!isMoved) { + return; + } + event.stopPropagation(); + if (sliderRequestAnimationFrame) { + cancelAnimationFrame(sliderRequestAnimationFrame); + sliderRequestAnimationFrame = null; + } + var detail = event.detail; + isMoved = false; + var action = 'close'; + var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth; + var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2); + if (isToggle) { + if (!isOpened) { + action = 'open'; + } else if (detail.direction === 'left' && openedActions === 'right') { + action = 'open'; + } else if (detail.direction === 'right' && openedActions === 'left') { + action = 'open'; + } + + } + cell.classList.add(CLASS_TRANSITIONING); + var buttons; + if (action === 'open') { + var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth; + setTranslate(sliderHandle, newTranslate); + buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft; + if (typeof buttons !== 'undefined') { + var button = null; + for (var i = 0; i < buttons.length; i++) { + button = buttons[i]; + setTranslate(button, newTranslate); + } + button.parentNode.classList.add(CLASS_SELECTED); + cell.classList.add(CLASS_SELECTED); + if (!isOpened) { + $.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright'); + } + } + } else { + setTranslate(sliderHandle, 0); + sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED); + sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED); + cell.classList.remove(CLASS_SELECTED); + } + var buttonOffset; + if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) { + for (var i = 0, len = buttonsLeft.length; i < len; i++) { + var buttonLeft = buttonsLeft[i]; + buttonOffset = buttonLeft._buttonOffset; + if (typeof buttonOffset === 'undefined') { + buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; + } + setTranslate(buttonLeft, buttonOffset); + } + } + if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) { + for (var i = 0, len = buttonsRight.length; i < len; i++) { + var buttonRight = buttonsRight[i]; + buttonOffset = buttonRight._buttonOffset; + if (typeof buttonOffset === 'undefined') { + buttonRight._buttonOffset = buttonRight.offsetLeft; + } + setTranslate(buttonRight, -buttonOffset); + } + } + } + }; + + function toggleEvents(element, isRemove) { + var method = !!isRemove ? 'removeEventListener' : 'addEventListener'; + element[method]('drag', handleEvent); + element[method]('dragend', handleEvent); + element[method]('swiperight', handleEvent); + element[method]('swipeleft', handleEvent); + element[method]('flick', handleEvent); + }; + /** + * 打开滑动菜单 + * @param {Object} el + * @param {Object} direction + */ + $.swipeoutOpen = function(el, direction) { + if (!el) return; + var classList = el.classList; + if (classList.contains(CLASS_SELECTED)) return; + if (!direction) { + if (el.querySelector(SELECTOR_SLIDER_RIGHT)) { + direction = 'right'; + } else { + direction = 'left'; + } + } + var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); + if (!swipeoutAction) return; + swipeoutAction.classList.add(CLASS_SELECTED); + classList.add(CLASS_SELECTED); + classList.remove(CLASS_TRANSITIONING); + var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); + var swipeoutWidth = swipeoutAction.offsetWidth; + var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth; + var length = buttons.length; + var button; + for (var i = 0; i < length; i++) { + button = buttons[i]; + if (direction === 'right') { + setTranslate(button, -button.offsetLeft); + } else { + setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); + } + } + classList.add(CLASS_TRANSITIONING); + for (var i = 0; i < length; i++) { + setTranslate(buttons[i], translate); + } + setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate); + }; + /** + * 关闭滑动菜单 + * @param {Object} el + */ + $.swipeoutClose = function(el) { + if (!el) return; + var classList = el.classList; + if (!classList.contains(CLASS_SELECTED)) return; + var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left'; + var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); + if (!swipeoutAction) return; + swipeoutAction.classList.remove(CLASS_SELECTED); + classList.remove(CLASS_SELECTED); + classList.add(CLASS_TRANSITIONING); + var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); + var swipeoutWidth = swipeoutAction.offsetWidth; + var length = buttons.length; + var button; + setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0); + for (var i = 0; i < length; i++) { + button = buttons[i]; + if (direction === 'right') { + setTranslate(button, (-button.offsetLeft)); + } else { + setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); + } + } + }; + + window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 + if (!cell) { + return; + } + toggleActive(false); + sliderHandle && toggleEvents(cell, true); + }); + window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 + if (!cell) { + return; + } + toggleActive(false); + sliderHandle && toggleEvents(cell, true); + }); + var radioOrCheckboxClick = function(event) { + var type = event.target && event.target.type || ''; + if (type === 'radio' || type === 'checkbox') { + return; + } + var classList = cell.classList; + if (classList.contains('mui-radio')) { + var input = cell.querySelector('input[type=radio]'); + if (input) { + // input.click(); + if (!input.disabled && !input.readOnly) { + input.checked = !input.checked; + $.trigger(input, 'change'); + } + } + } else if (classList.contains('mui-checkbox')) { + var input = cell.querySelector('input[type=checkbox]'); + if (input) { + // input.click(); + if (!input.disabled && !input.readOnly) { + input.checked = !input.checked; + $.trigger(input, 'change'); + } + } + } + }; + //fixed hashchange(android) + window.addEventListener($.EVENT_CLICK, function(e) { + if (cell && cell.classList.contains('mui-collapse')) { + e.preventDefault(); + } + }); + window.addEventListener('doubletap', function(event) { + if (cell) { + radioOrCheckboxClick(event); + } + }); + var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; + window.addEventListener('tap', function(event) { + if (!cell) { + return; + } + var isExpand = false; + var classList = cell.classList; + var ul = cell.parentNode; + if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) { + if (classList.contains(CLASS_SELECTED)) { + return; + } + var selected = ul.querySelector('li' + SELECTOR_SELECTED); + if (selected) { + selected.classList.remove(CLASS_SELECTED); + } + classList.add(CLASS_SELECTED); + $.trigger(cell, 'selected', { + el: cell + }); + return; + } + if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) { + if (!preventDefaultException.test(event.target.tagName)) { + event.detail.gesture.preventDefault(); + } + + if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类 + var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active'); + if (collapse) { + collapse.classList.remove(CLASS_ACTIVE); + } + isExpand = true; + } + classList.toggle(CLASS_ACTIVE); + if (isExpand) { + //触发展开事件 + $.trigger(cell, 'expand'); + + //scroll + //暂不滚动 + // var offsetTop = $.offset(cell).top; + // var scrollTop = document.body.scrollTop; + // var height = window.innerHeight; + // var offsetHeight = cell.offsetHeight; + // var cellHeight = (offsetTop - scrollTop + offsetHeight); + // if (offsetHeight > height) { + // $.scrollTo(offsetTop, 300); + // } else if (cellHeight > height) { + // $.scrollTo(cellHeight - height + scrollTop, 300); + // } + } + } else { + radioOrCheckboxClick(event); + } + }); +})(mui, window, document); +(function($, window) { + /** + * 警告消息框 + */ + $.alert = function(message, title, btnValue, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + title = null; + btnValue = '确定'; + } else if (typeof btnValue === 'function') { + callback = btnValue; + btnValue = null; + } + $.plusReady(function() { + plus.nativeUI.alert(message, callback, title, btnValue); + }); + } + + } else { + //TODO H5版本 + window.alert(message); + } + }; + +})(mui, window); +(function($, window) { + /** + * 确认消息框 + */ + $.confirm = function(message, title, btnArray, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + callback = btnArray; + btnArray = null; + } + $.plusReady(function() { + plus.nativeUI.confirm(message, callback, title, btnArray); + }); + } + + } else { + //H5版本,0为确认,1为取消 + if (window.confirm(message)) { + callback({ + index: 0 + }); + } else { + callback({ + index: 1 + }); + } + } + }; + +})(mui, window); +(function($, window) { + /** + * 输入对话框 + */ + $.prompt = function(text, defaultText, title, btnArray, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + + if (typeof defaultText === 'function') { + callback = defaultText; + defaultText = null; + title = null; + btnArray = null; + } else if (typeof title === 'function') { + callback = title; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + callback = btnArray; + btnArray = null; + } + $.plusReady(function() { + plus.nativeUI.prompt(text, callback, title, defaultText, btnArray); + }); + } + + } else { + //H5版本(确认index为0,取消index为1) + var result = window.prompt(text); + if (result) { + callback({ + index: 0, + value: result + }); + } else { + callback({ + index: 1, + value: '' + }); + } + } + }; + +})(mui, window); +(function($, window) { + var CLASS_ACTIVE = 'mui-active'; + /** + * 自动消失提示框 + */ + $.toast = function(message,options) { + var durations = { + 'long': 3500, + 'short': 2000 + }; + + //计算显示时间 + options = $.extend({ + duration: 'short' + }, options || {}); + + + if ($.os.plus && options.type !== 'div') { + //默认显示在底部; + $.plusReady(function() { + plus.nativeUI.toast(message, { + verticalAlign: 'bottom', + duration:options.duration + }); + }); + } else { + if (typeof options.duration === 'number') { + duration = options.duration>0 ? options.duration:durations['short']; + } else { + duration = durations[options.duration]; + } + if (!duration) { + duration = durations['short']; + } + var toast = document.createElement('div'); + toast.classList.add('mui-toast-container'); + toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>'; + toast.addEventListener('webkitTransitionEnd', function() { + if (!toast.classList.contains(CLASS_ACTIVE)) { + toast.parentNode.removeChild(toast); + toast = null; + } + }); + //点击则自动消失 + toast.addEventListener('click', function() { + toast.parentNode.removeChild(toast); + toast = null; + }); + document.body.appendChild(toast); + toast.offsetHeight; + toast.classList.add(CLASS_ACTIVE); + setTimeout(function() { + toast && toast.classList.remove(CLASS_ACTIVE); + }, duration); + + return { + isVisible: function() {return !!toast;} + } + } + }; + +})(mui, window); +/** + * Popup(alert,confirm,prompt) + * @param {Object} $ + * @param {Object} window + * @param {Object} document + */ +(function($, window, document) { + var CLASS_POPUP = 'mui-popup'; + var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; + var CLASS_POPUP_IN = 'mui-popup-in'; + var CLASS_POPUP_OUT = 'mui-popup-out'; + var CLASS_POPUP_INNER = 'mui-popup-inner'; + var CLASS_POPUP_TITLE = 'mui-popup-title'; + var CLASS_POPUP_TEXT = 'mui-popup-text'; + var CLASS_POPUP_INPUT = 'mui-popup-input'; + var CLASS_POPUP_BUTTONS = 'mui-popup-buttons'; + var CLASS_POPUP_BUTTON = 'mui-popup-button'; + var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold'; + var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; + var CLASS_ACTIVE = 'mui-active'; + + var popupStack = []; + var backdrop = (function() { + var element = document.createElement('div'); + element.classList.add(CLASS_POPUP_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('webkitTransitionEnd', function() { + if (!this.classList.contains(CLASS_ACTIVE)) { + element.parentNode && element.parentNode.removeChild(element); + } + }); + return element; + }()); + + var createInput = function(placeholder) { + return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>'; + }; + var createInner = function(message, title, extra) { + return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>'; + }; + var createButtons = function(btnArray) { + var length = btnArray.length; + var btns = []; + for (var i = 0; i < length; i++) { + btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>'); + } + return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>'; + }; + + var createPopup = function(html, callback) { + var popupElement = document.createElement('div'); + popupElement.className = CLASS_POPUP; + popupElement.innerHTML = html; + var removePopupElement = function() { + popupElement.parentNode && popupElement.parentNode.removeChild(popupElement); + popupElement = null; + }; + popupElement.addEventListener($.EVENT_MOVE, $.preventDefault); + popupElement.addEventListener('webkitTransitionEnd', function(e) { + if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) { + removePopupElement(); + } + }); + popupElement.style.display = 'block'; + document.body.appendChild(popupElement); + popupElement.offsetHeight; + popupElement.classList.add(CLASS_POPUP_IN); + + if (!backdrop.classList.contains(CLASS_ACTIVE)) { + backdrop.style.display = 'block'; + document.body.appendChild(backdrop); + backdrop.offsetHeight; + backdrop.classList.add(CLASS_ACTIVE); + } + var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement); + var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input'); + var popup = { + element: popupElement, + close: function(index, animate) { + if (popupElement) { + var result = callback && callback({ + index: index || 0, + value: input && input.value || '' + }); + if (result === false) { //返回false则不关闭当前popup + return; + } + if (animate !== false) { + popupElement.classList.remove(CLASS_POPUP_IN); + popupElement.classList.add(CLASS_POPUP_OUT); + } else { + removePopupElement(); + } + popupStack.pop(); + //如果还有其他popup,则不remove backdrop + if (popupStack.length) { + popupStack[popupStack.length - 1]['show'](animate); + } else { + backdrop.classList.remove(CLASS_ACTIVE); + } + } + } + }; + var handleEvent = function(e) { + popup.close(btns.indexOf(e.target)); + }; + $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent); + if (popupStack.length) { + popupStack[popupStack.length - 1]['hide'](); + } + popupStack.push({ + close: popup.close, + show: function(animate) { + popupElement.style.display = 'block'; + popupElement.offsetHeight; + popupElement.classList.add(CLASS_POPUP_IN); + }, + hide: function() { + popupElement.style.display = 'none'; + popupElement.classList.remove(CLASS_POPUP_IN); + } + }); + return popup; + }; + var createAlert = function(message, title, btnValue, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + type = btnValue; + title = null; + btnValue = null; + } else if (typeof btnValue === 'function') { + type = callback; + callback = btnValue; + btnValue = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback); + } + return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定'); + }; + var createConfirm = function(message, title, btnArray, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + type = btnArray; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + type = callback; + callback = btnArray; + btnArray = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback); + } + return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']); + }; + var createPrompt = function(message, placeholder, title, btnArray, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof placeholder === 'function') { + callback = placeholder; + type = title; + placeholder = null; + title = null; + btnArray = null; + } else if (typeof title === 'function') { + callback = title; + type = btnArray; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + type = callback; + callback = btnArray; + btnArray = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback); + } + return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']); + }; + var closePopup = function() { + if (popupStack.length) { + popupStack[popupStack.length - 1]['close'](); + return true; + } else { + return false; + } + }; + var closePopups = function() { + while (popupStack.length) { + popupStack[popupStack.length - 1]['close'](); + } + }; + + $.closePopup = closePopup; + $.closePopups = closePopups; + $.alert = createAlert; + $.confirm = createConfirm; + $.prompt = createPrompt; +})(mui, window, document); +(function($, document) { + var CLASS_PROGRESSBAR = 'mui-progressbar'; + var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in'; + var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out'; + var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite'; + + var SELECTOR_PROGRESSBAR = '.mui-progressbar'; + + var _findProgressbar = function(container) { + container = $(container || 'body'); + if (container.length === 0) return; + container = container[0]; + if (container.classList.contains(CLASS_PROGRESSBAR)) { + return container; + } + var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR); + if (progressbars) { + for (var i = 0, len = progressbars.length; i < len; i++) { + var progressbar = progressbars[i]; + if (progressbar.parentNode === container) { + return progressbar; + } + } + } + }; + /** + * 创建并显示进度条 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + * @param {Object} progress 可选,undefined表示循环,数字表示具体进度 + * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数) + */ + var showProgressbar = function(container, progress, color) { + if (typeof container === 'number') { + color = progress; + progress = container; + container = 'body'; + } + container = $(container || 'body'); + if (container.length === 0) return; + container = container[0]; + var progressbar; + if (container.classList.contains(CLASS_PROGRESSBAR)) { + progressbar = container; + } else { + var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')'); + if (progressbars) { + for (var i = 0, len = progressbars.length; i < len; i++) { + var _progressbar = progressbars[i]; + if (_progressbar.parentNode === container) { + progressbar = _progressbar; + break; + } + } + } + if (!progressbar) { + progressbar = document.createElement('span'); + progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : ''); + if (typeof progress !== 'undefined') { + progressbar.innerHTML = '<span></span>'; + } + container.appendChild(progressbar); + } else { + progressbar.classList.add(CLASS_PROGRESSBAR_IN); + } + } + if (progress) setProgressbar(container, progress); + return progressbar; + }; + /** + * 关闭进度条 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + */ + var hideProgressbar = function(container) { + var progressbar = _findProgressbar(container); + if (!progressbar) { + return; + } + var classList = progressbar.classList; + if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) { + return; + } + classList.remove(CLASS_PROGRESSBAR_IN); + classList.add(CLASS_PROGRESSBAR_OUT); + progressbar.addEventListener('webkitAnimationEnd', function() { + progressbar.parentNode && progressbar.parentNode.removeChild(progressbar); + progressbar = null; + }); + return; + }; + /** + * 设置指定进度条进度 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + * @param {Object} progress 可选,默认0 取值范围[0-100] + * @param {Object} speed 进度条动画时间 + */ + var setProgressbar = function(container, progress, speed) { + if (typeof container === 'number') { + speed = progress; + progress = container; + container = false; + } + var progressbar = _findProgressbar(container); + if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) { + return; + } + if (progress) progress = Math.min(Math.max(progress, 0), 100); + progressbar.offsetHeight; + var span = progressbar.querySelector('span'); + if (span) { + var style = span.style; + style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)'; + if (typeof speed !== 'undefined') { + style.webkitTransitionDuration = speed + 'ms'; + } else { + style.webkitTransitionDuration = ''; + } + } + return progressbar; + }; + $.fn.progressbar = function(options) { + var progressbarApis = []; + options = options || {}; + this.each(function() { + var self = this; + var progressbarApi = self.mui_plugin_progressbar; + if (!progressbarApi) { + self.mui_plugin_progressbar = progressbarApi = { + options: options, + setOptions: function(options) { + this.options = options; + }, + show: function() { + return showProgressbar(self, this.options.progress, this.options.color); + }, + setProgress: function(progress) { + return setProgressbar(self, progress); + }, + hide: function() { + return hideProgressbar(self); + } + }; + } else if (options) { + progressbarApi.setOptions(options); + } + progressbarApis.push(progressbarApi); + }); + return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis; + }; + // $.setProgressbar = setProgressbar; + // $.showProgressbar = showProgressbar; + // $.hideProgressbar = hideProgressbar; +})(mui, document); +/** + * Input(TODO resize) + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + var CLASS_ICON = 'mui-icon'; + var CLASS_ICON_CLEAR = 'mui-icon-clear'; + var CLASS_ICON_SPEECH = 'mui-icon-speech'; + var CLASS_ICON_SEARCH = 'mui-icon-search'; + var CLASS_ICON_PASSWORD = 'mui-icon-eye'; + var CLASS_INPUT_ROW = 'mui-input-row'; + var CLASS_PLACEHOLDER = 'mui-placeholder'; + var CLASS_TOOLTIP = 'mui-tooltip'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_FOCUSIN = 'mui-focusin'; + var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR; + var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH; + var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD; + var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER; + var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP; + + var findRow = function(target) { + for (; target && target !== document; target = target.parentNode) { + if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) { + return target; + } + } + return null; + }; + var Input = function(element, options) { + this.element = element; + this.options = options || { + actions: 'clear' + }; + if (~this.options.actions.indexOf('slider')) { //slider + this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN; + this.sliderActionSelector = SELECTOR_TOOLTIP; + } else { //clear,speech,search + if (~this.options.actions.indexOf('clear')) { + this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN; + this.clearActionSelector = SELECTOR_ICON_CLOSE; + } + if (~this.options.actions.indexOf('speech')) { //only for 5+ + this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH; + this.speechActionSelector = SELECTOR_ICON_SPEECH; + } + if (~this.options.actions.indexOf('search')) { + this.searchActionClass = CLASS_PLACEHOLDER; + this.searchActionSelector = SELECTOR_PLACEHOLDER; + } + if (~this.options.actions.indexOf('password')) { + this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD; + this.passwordActionSelector = SELECTOR_ICON_PASSWORD; + } + } + this.init(); + }; + Input.prototype.init = function() { + this.initAction(); + this.initElementEvent(); + }; + Input.prototype.initAction = function() { + var self = this; + + var row = self.element.parentNode; + if (row) { + if (self.sliderActionClass) { + self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector); + } else { + if (self.searchActionClass) { + self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector); + self.searchAction.addEventListener('tap', function(e) { + $.focus(self.element); + e.stopPropagation(); + }); + } + if (self.speechActionClass) { + self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector); + self.speechAction.addEventListener('click', $.stopPropagation); + self.speechAction.addEventListener('tap', function(event) { + self.speechActionClick(event); + }); + } + if (self.clearActionClass) { + self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector); + self.clearAction.addEventListener('tap', function(event) { + self.clearActionClick(event); + }); + } + if (self.passwordActionClass) { + self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector); + self.passwordAction.addEventListener('tap', function(event) { + self.passwordActionClick(event); + }); + } + } + } + }; + Input.prototype.createAction = function(row, actionClass, actionSelector) { + var action = row.querySelector(actionSelector); + if (!action) { + var action = document.createElement('span'); + action.className = actionClass; + if (actionClass === this.searchActionClass) { + action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>'; + this.element.setAttribute('placeholder', ''); + if (this.element.value.trim()) { + row.classList.add('mui-active'); + } + } + row.insertBefore(action, this.element.nextSibling); + } + return action; + }; + Input.prototype.initElementEvent = function() { + var element = this.element; + + if (this.sliderActionClass) { + var tooltip = this.sliderAction; + var timer = null; + var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的 + tooltip.classList.remove(CLASS_HIDDEN); + var offsetLeft = element.offsetLeft; + var width = element.offsetWidth - 28; + var tooltipWidth = tooltip.offsetWidth; + var distince = Math.abs(element.max - element.min); + var scaleWidth = (width / distince) * Math.abs(element.value - element.min); + tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px'; + tooltip.innerText = element.value; + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(function() { + tooltip.classList.add(CLASS_HIDDEN); + }, 1000); + }; + element.addEventListener('input', showTip); + element.addEventListener('tap', showTip); + element.addEventListener($.EVENT_MOVE, function(e) { + e.stopPropagation(); + }); + } else { + if (this.clearActionClass) { + var action = this.clearAction; + if (!action) { + return; + } + $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) { + (function(type) { + element.addEventListener(type, function() { + action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN); + }); + })(type); + }); + element.addEventListener('blur', function() { + action.classList.add(CLASS_HIDDEN); + }); + } + if (this.searchActionClass) { + element.addEventListener('focus', function() { + element.parentNode.classList.add('mui-active'); + }); + element.addEventListener('blur', function() { + if (!element.value.trim()) { + element.parentNode.classList.remove('mui-active'); + } + }); + } + } + }; + Input.prototype.setPlaceholder = function(text) { + if (this.searchActionClass) { + var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER); + placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text); + } else { + this.element.setAttribute('placeholder', text); + } + }; + Input.prototype.passwordActionClick = function(event) { + if (this.element.type === 'text') { + this.element.type = 'password'; + } else { + this.element.type = 'text'; + } + this.passwordAction.classList.toggle('mui-active'); + event.preventDefault(); + }; + Input.prototype.clearActionClick = function(event) { + var self = this; + self.element.value = ''; + $.focus(self.element); + self.clearAction.classList.add(CLASS_HIDDEN); + event.preventDefault(); + }; + Input.prototype.speechActionClick = function(event) { + if (window.plus) { + var self = this; + var oldValue = self.element.value; + self.element.value = ''; + document.body.classList.add(CLASS_FOCUSIN); + plus.speech.startRecognize({ + engine: 'iFly' + }, function(s) { + self.element.value += s; + $.focus(self.element); + plus.speech.stopRecognize(); + $.trigger(self.element, 'recognized', { + value: self.element.value + }); + if (oldValue !== self.element.value) { + $.trigger(self.element, 'change'); + $.trigger(self.element, 'input'); + } + // document.body.classList.remove(CLASS_FOCUSIN); + }, function(e) { + document.body.classList.remove(CLASS_FOCUSIN); + }); + } else { + alert('only for 5+'); + } + event.preventDefault(); + }; + $.fn.input = function(options) { + var inputApis = []; + this.each(function() { + var inputApi = null; + var actions = []; + var row = findRow(this.parentNode); + if (this.type === 'range' && row.classList.contains('mui-input-range')) { + actions.push('slider'); + } else { + var classList = this.classList; + if (classList.contains('mui-input-clear')) { + actions.push('clear'); + } + if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) { + actions.push('speech'); + } + if (classList.contains('mui-input-password')) { + actions.push('password'); + } + if (this.type === 'search' && row.classList.contains('mui-search')) { + actions.push('search'); + } + } + var id = this.getAttribute('data-input-' + actions[0]); + if (!id) { + id = ++$.uuid; + inputApi = $.data[id] = new Input(this, { + actions: actions.join(',') + }); + for (var i = 0, len = actions.length; i < len; i++) { + this.setAttribute('data-input-' + actions[i], id); + } + } else { + inputApi = $.data[id]; + } + inputApis.push(inputApi); + }); + return inputApis.length === 1 ? inputApis[0] : inputApis; + }; + $.ready(function() { + $('.mui-input-row input').input(); + }); +})(mui, window, document); +(function($, window) { + var CLASS_ACTIVE = 'mui-active'; + var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/; + var getColor = function(colorStr) { + var matches = colorStr.match(rgbaRegex); + if (matches && matches.length === 5) { + return [ + matches[1], + matches[2], + matches[3], + matches[4] + ]; + } + return []; + }; + var Transparent = function(element, options) { + this.element = element; + this.options = $.extend({ + top: 0, //距离顶部高度(到达该高度即触发) + offset: 150, //滚动透明距离 + duration: 16, //过渡时间 + scrollby: window//监听滚动距离容器 + }, options || {}); + + this.scrollByElem = this.options.scrollby || window; + if (!this.scrollByElem) { + throw new Error("监听滚动的元素不存在"); + } + this.isNativeScroll = false; + if (this.scrollByElem === window) { + this.isNativeScroll = true; + } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) { + this.isNativeScroll = true; + } + + this._style = this.element.style; + this._bgColor = this._style.backgroundColor; + var color = getColor(mui.getStyles(this.element, 'backgroundColor')); + if (color.length) { + this._R = color[0]; + this._G = color[1]; + this._B = color[2]; + this._A = parseFloat(color[3]); + this.lastOpacity = this._A; + this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this); + this.initEvent(); + } else { + throw new Error("元素背景颜色必须为RGBA"); + } + }; + + Transparent.prototype.initEvent = function() { + this.scrollByElem.addEventListener('scroll', this._bufferFn); + if (this.isNativeScroll) { //原生scroll + this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn); + } + } + Transparent.prototype.handleScroll = function(e) { + var y = window.scrollY; + if (!this.isNativeScroll && e && e.detail) { + y = -e.detail.y; + } + var opacity = (y - this.options.top) / this.options.offset + this._A; + opacity = Math.min(Math.max(this._A, opacity), 1); + this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')'; + if (opacity > this._A) { + this.element.classList.add(CLASS_ACTIVE); + } else { + this.element.classList.remove(CLASS_ACTIVE); + } + if (this.lastOpacity !== opacity) { + $.trigger(this.element, 'alpha', { + alpha: opacity + }); + this.lastOpacity = opacity; + } + }; + Transparent.prototype.destory = function() { + this.scrollByElem.removeEventListener('scroll', this._bufferFn); + this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn); + this.element.style.backgroundColor = this._bgColor; + this.element.mui_plugin_transparent = null; + }; + $.fn.transparent = function(options) { + options = options || {}; + var transparentApis = []; + this.each(function() { + var transparentApi = this.mui_plugin_transparent; + if (!transparentApi) { + var top = this.getAttribute('data-top'); + var offset = this.getAttribute('data-offset'); + var duration = this.getAttribute('data-duration'); + var scrollby = this.getAttribute('data-scrollby'); + if (top !== null && typeof options.top === 'undefined') { + options.top = top; + } + if (offset !== null && typeof options.offset === 'undefined') { + options.offset = offset; + } + if (duration !== null && typeof options.duration === 'undefined') { + options.duration = duration; + } + if (scrollby !== null && typeof options.scrollby === 'undefined') { + options.scrollby = document.querySelector(scrollby) || window; + } + transparentApi = this.mui_plugin_transparent = new Transparent(this, options); + } + transparentApis.push(transparentApi); + }); + return transparentApis.length === 1 ? transparentApis[0] : transparentApis; + }; + $.ready(function() { + $('.mui-bar-transparent').transparent(); + }); +})(mui, window); +/** + * 数字输入框 + * varstion 1.0.1 + * by Houfeng + * Houfeng@DCloud.io + */ + +(function($) { + + var touchSupport = ('ontouchstart' in document); + var tapEventName = touchSupport ? 'tap' : 'click'; + var changeEventName = 'change'; + var holderClassName = 'mui-numbox'; + var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus'; + var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus'; + var inputClassSelector = '.mui-input-numbox,.mui-numbox-input'; + + var Numbox = $.Numbox = $.Class.extend({ + /** + * 构造函数 + **/ + init: function(holder, options) { + var self = this; + if (!holder) { + throw "构造 numbox 时缺少容器元素"; + } + self.holder = holder; + options = options || {}; + options.step = parseInt(options.step || 1); + self.options = options; + self.input = $.qsa(inputClassSelector, self.holder)[0]; + self.plus = $.qsa(plusClassSelector, self.holder)[0]; + self.minus = $.qsa(minusClassSelector, self.holder)[0]; + self.checkValue(); + self.initEvent(); + }, + /** + * 初始化事件绑定 + **/ + initEvent: function() { + var self = this; + self.plus.addEventListener(tapEventName, function(event) { + var val = parseInt(self.input.value) + self.options.step; + self.input.value = val.toString(); + $.trigger(self.input, changeEventName, null); + }); + self.minus.addEventListener(tapEventName, function(event) { + var val = parseInt(self.input.value) - self.options.step; + self.input.value = val.toString(); + $.trigger(self.input, changeEventName, null); + }); + self.input.addEventListener(changeEventName, function(event) { + self.checkValue(); + var val = parseInt(self.input.value); + //触发顶层容器 + $.trigger(self.holder, changeEventName, { + value: val + }); + }); + }, + /** + * 获取当前值 + **/ + getValue: function() { + var self = this; + return parseInt(self.input.value); + }, + /** + * 验证当前值是法合法 + **/ + checkValue: function() { + var self = this; + var val = self.input.value; + if (val == null || val == '' || isNaN(val)) { + self.input.value = self.options.min || 0; + self.minus.disabled = self.options.min != null; + } else { + var val = parseInt(val); + if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) { + val = self.options.max; + self.plus.disabled = true; + } else { + self.plus.disabled = false; + } + if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) { + val = self.options.min; + self.minus.disabled = true; + } else { + self.minus.disabled = false; + } + self.input.value = val; + } + }, + /** + * 更新选项 + **/ + setOption: function(name, value) { + var self = this; + self.options[name] = value; + }, + /** + * 动态设置新值 + **/ + setValue: function(value) { + this.input.value = value; + this.checkValue(); + } + }); + + $.fn.numbox = function(options) { + var instanceArray = []; + //遍历选择的元素 + this.each(function(i, element) { + if (element.numbox) { + return; + } + if (options) { + element.numbox = new Numbox(element, options); + } else { + var optionsText = element.getAttribute('data-numbox-options'); + var options = optionsText ? JSON.parse(optionsText) : {}; + options.step = element.getAttribute('data-numbox-step') || options.step; + options.min = element.getAttribute('data-numbox-min') || options.min; + options.max = element.getAttribute('data-numbox-max') || options.max; + element.numbox = new Numbox(element, options); + } + }); + return this[0] ? this[0].numbox : null; + } + + //自动处理 class='mui-locker' 的 dom + $.ready(function() { + $('.' + holderClassName).numbox(); + }); + +}(mui)); +/** + * Button + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + var CLASS_ICON = 'mui-icon'; + var CLASS_DISABLED = 'mui-disabled'; + + var STATE_RESET = 'reset'; + var STATE_LOADING = 'loading'; + + var defaultOptions = { + loadingText: 'Loading...', //文案 + loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空 + loadingIconPosition: 'left' //图标所处位置,仅支持left|right + }; + + var Button = function(element, options) { + this.element = element; + this.options = $.extend({}, defaultOptions, options); + if (!this.options.loadingText) { + this.options.loadingText = defaultOptions.loadingText; + } + if (this.options.loadingIcon === null) { + this.options.loadingIcon = 'mui-spinner'; + if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') { + this.options.loadingIcon += ' ' + 'mui-spinner-white'; + } + } + this.isInput = this.element.tagName === 'INPUT'; + this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML; + this.state = ''; + }; + Button.prototype.loading = function() { + this.setState(STATE_LOADING); + }; + Button.prototype.reset = function() { + this.setState(STATE_RESET); + }; + Button.prototype.setState = function(state) { + if (this.state === state) { + return false; + } + this.state = state; + if (state === STATE_RESET) { + this.element.disabled = false; + this.element.classList.remove(CLASS_DISABLED); + this.setHtml(this.resetHTML); + } else if (state === STATE_LOADING) { + this.element.disabled = true; + this.element.classList.add(CLASS_DISABLED); + var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>'); + if (this.options.loadingIcon && !this.isInput) { + if (this.options.loadingIconPosition === 'right') { + html += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>'; + } else { + html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + html; + } + } + this.setHtml(html); + } + }; + Button.prototype.setHtml = function(html) { + if (this.isInput) { + this.element.value = html; + } else { + this.element.innerHTML = html; + } + } + $.fn.button = function(state) { + var buttonApis = []; + this.each(function() { + var buttonApi = this.mui_plugin_button; + if (!buttonApi) { + var loadingText = this.getAttribute('data-loading-text'); + var loadingIcon = this.getAttribute('data-loading-icon'); + var loadingIconPosition = this.getAttribute('data-loading-icon-position'); + this.mui_plugin_button = buttonApi = new Button(this, { + loadingText: loadingText, + loadingIcon: loadingIcon, + loadingIconPosition: loadingIconPosition + }); + } + if (state === STATE_LOADING || state === STATE_RESET) { + buttonApi.setState(state); + } + buttonApis.push(buttonApi); + }); + return buttonApis.length === 1 ? buttonApis[0] : buttonApis; + }; +})(mui, window, document); \ No newline at end of file diff --git a/static/app/js/mui.min.js b/static/app/js/mui.min.js new file mode 100755 index 0000000..f53e851 --- /dev/null +++ b/static/app/js/mui.min.js @@ -0,0 +1,9 @@ +/*! + * ===================================================== + * Mui v3.7.0 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ +var mui=function(a,b){var c=/complete|loaded|interactive/,d=/^#([\w-]+)$/,e=/^\.([\w-]+)$/,f=/^[\w-]+$/,g=/translate(?:3d)?\((.+?)\)/,h=/matrix(3d)?\((.+?)\)/,i=function(b,c){if(c=c||a,!b)return j();if("object"==typeof b)return i.isArrayLike(b)?j(i.slice.call(b),null):j([b],null);if("function"==typeof b)return i.ready(b);if("string"==typeof b)try{if(b=b.trim(),d.test(b)){var e=a.getElementById(RegExp.$1);return j(e?[e]:[])}return j(i.qsa(b,c),b)}catch(f){}return j()},j=function(a,b){return a=a||[],Object.setPrototypeOf(a,i.fn),a.selector=b||"",a};i.uuid=0,i.data={},i.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},j=1,k=arguments.length,l=!1;for("boolean"==typeof h&&(l=h,h=arguments[j]||{},j++),"object"==typeof h||i.isFunction(h)||(h={}),j===k&&(h=this,j--);k>j;j++)if(null!=(a=arguments[j]))for(c in a)d=h[c],e=a[c],h!==e&&(l&&e&&(i.isPlainObject(e)||(f=i.isArray(e)))?(f?(f=!1,g=d&&i.isArray(d)?d:[]):g=d&&i.isPlainObject(d)?d:{},h[c]=i.extend(l,g,e)):e!==b&&(h[c]=e));return h},i.noop=function(){},i.slice=[].slice,i.filter=[].filter,i.type=function(a){return null==a?String(a):k[{}.toString.call(a)]||"object"},i.isArray=Array.isArray||function(a){return a instanceof Array},i.isArrayLike=function(a){var b=!!a&&"length"in a&&a.length,c=i.type(a);return"function"===c||i.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a},i.isWindow=function(a){return null!=a&&a===a.window},i.isObject=function(a){return"object"===i.type(a)},i.isPlainObject=function(a){return i.isObject(a)&&!i.isWindow(a)&&Object.getPrototypeOf(a)===Object.prototype},i.isEmptyObject=function(a){for(var c in a)if(c!==b)return!1;return!0},i.isFunction=function(a){return"function"===i.type(a)},i.qsa=function(b,c){return c=c||a,i.slice.call(e.test(b)?c.getElementsByClassName(RegExp.$1):f.test(b)?c.getElementsByTagName(b):c.querySelectorAll(b))},i.ready=function(b){return c.test(a.readyState)?b(i):a.addEventListener("DOMContentLoaded",function(){b(i)},!1),this},i.buffer=function(a,b,c){function d(){e&&(e.cancel(),e=0),f=i.now(),a.apply(c||this,arguments),g=i.now()}var e,f=0,g=0,b=b||150;return i.extend(function(){!f||g>=f&&i.now()-g>b||f>g&&i.now()-f>8*b?d.apply(this,arguments):(e&&e.cancel(),e=i.later(d,b,null,i.slice.call(arguments)))},{stop:function(){e&&(e.cancel(),e=0)}})},i.each=function(a,b,c){if(!a)return this;if("number"==typeof a.length)[].every.call(a,function(a,c){return b.call(a,c,a)!==!1});else for(var d in a)if(c){if(a.hasOwnProperty(d)&&b.call(a[d],d,a[d])===!1)return a}else if(b.call(a[d],d,a[d])===!1)return a;return this},i.focus=function(a){i.os.ios?setTimeout(function(){a.focus()},10):a.focus()},i.trigger=function(a,b,c){return a.dispatchEvent(new CustomEvent(b,{detail:c,bubbles:!0,cancelable:!0})),this},i.getStyles=function(a,b){var c=a.ownerDocument.defaultView.getComputedStyle(a,null);return b?c.getPropertyValue(b)||c[b]:c},i.parseTranslate=function(a,b){var c=a.match(g||"");return c&&c[1]||(c=["","0,0,0"]),c=c[1].split(","),c={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])},b&&c.hasOwnProperty(b)?c[b]:c},i.parseTranslateMatrix=function(a,b){var c=a.match(h),d=c&&c[1];c?(c=c[2].split(","),"3d"===d?c=c.slice(12,15):(c.push(0),c=c.slice(4,7))):c=[0,0,0];var e={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])};return b&&e.hasOwnProperty(b)?e[b]:e},i.hooks={},i.addAction=function(a,b){var c=i.hooks[a];return c||(c=[]),b.index=b.index||1e3,c.push(b),c.sort(function(a,b){return a.index-b.index}),i.hooks[a]=c,i.hooks[a]},i.doAction=function(a,b){i.isFunction(b)?i.each(i.hooks[a],b):i.each(i.hooks[a],function(a,b){return!b.handle()})},i.later=function(a,b,c,d){b=b||0;var e,f,g=a,h=d;return"string"==typeof a&&(g=c[a]),e=function(){g.apply(c,i.isArray(h)?h:[h])},f=setTimeout(e,b),{id:f,cancel:function(){clearTimeout(f)}}},i.now=Date.now||function(){return+new Date};var k={};return i.each(["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],function(a,b){k["[object "+b+"]"]=b.toLowerCase()}),window.JSON&&(i.parseJSON=JSON.parse),i.fn={each:function(a){return[].every.call(this,function(b,c){return a.call(b,c,b)!==!1}),this}},"function"==typeof define&&define.amd&&define("mui",[],function(){return i}),i}(document);!function(a,b){function c(c){this.os={};var d=[function(){var a=c.match(/(MicroMessenger)\/([\d\.]+)/i);return a&&(this.os.wechat={version:a[2].replace(/_/g,".")}),!1},function(){var a=c.match(/(Android);?[\s\/]+([\d.]+)?/);return a&&(this.os.android=!0,this.os.version=a[2],this.os.isBadAndroid=!/Chrome\/\d/.test(b.navigator.appVersion)),this.os.android===!0},function(){var a=c.match(/(iPhone\sOS)\s([\d_]+)/);if(a)this.os.ios=this.os.iphone=!0,this.os.version=a[2].replace(/_/g,".");else{var b=c.match(/(iPad).*OS\s([\d_]+)/);b&&(this.os.ios=this.os.ipad=!0,this.os.version=b[2].replace(/_/g,"."))}return this.os.ios===!0}];[].every.call(d,function(b){return!b.call(a)})}c.call(a,navigator.userAgent)}(mui,window),function(a,b){function c(c){this.os=this.os||{};var d=c.match(/Html5Plus/i);d&&(this.os.plus=!0,a(function(){b.body.classList.add("mui-plus")}),c.match(/StreamApp/i)&&(this.os.stream=!0,a(function(){b.body.classList.add("mui-plus-stream")})))}c.call(a,navigator.userAgent)}(mui,document),function(a){"ontouchstart"in window?(a.isTouchable=!0,a.EVENT_START="touchstart",a.EVENT_MOVE="touchmove",a.EVENT_END="touchend"):(a.isTouchable=!1,a.EVENT_START="mousedown",a.EVENT_MOVE="mousemove",a.EVENT_END="mouseup"),a.EVENT_CANCEL="touchcancel",a.EVENT_CLICK="click";var b=1,c={},d={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"},e=function(){return!0},f=function(){return!1},g=function(b,c){return b.detail?b.detail.currentTarget=c:b.detail={currentTarget:c},a.each(d,function(a,c){var d=b[a];b[a]=function(){return this[c]=e,d&&d.apply(b,arguments)},b[c]=f},!0),b},h=function(a){return a&&(a._mid||(a._mid=b++))},i={},j=function(b,d,e,f){return function(e){for(var f=c[b._mid][d],h=[],i=e.target,j={};i&&i!==document&&i!==b&&(!~["click","tap","doubletap","longtap","hold"].indexOf(d)||!i.disabled&&!i.classList.contains("mui-disabled"));i=i.parentNode){var k={};a.each(f,function(c,d){j[c]||(j[c]=a.qsa(c,b)),j[c]&&~j[c].indexOf(i)&&(k[c]||(k[c]=d))},!0),a.isEmptyObject(k)||h.push({element:i,handlers:k})}j=null,e=g(e),a.each(h,function(b,c){i=c.element;var f=i.tagName;return"tap"===d&&"INPUT"!==f&&"TEXTAREA"!==f&&"SELECT"!==f&&(e.preventDefault(),e.detail&&e.detail.gesture&&e.detail.gesture.preventDefault()),a.each(c.handlers,function(b,c){a.each(c,function(a,b){b.call(i,e)===!1&&(e.preventDefault(),e.stopPropagation())},!0)},!0),e.isPropagationStopped()?!1:void 0},!0)}},k=function(a,b){var c=i[h(a)],d=[];if(c){if(d=[],b){var e=function(a){return a.type===b};return c.filter(e)}d=c}return d},l=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;a.fn.on=function(b,d,e){return this.each(function(){var f=this;h(f),h(e);var g=!1,k=c[f._mid]||(c[f._mid]={}),m=k[b]||(k[b]={});a.isEmptyObject(m)&&(g=!0);var n=m[d]||(m[d]=[]);if(n.push(e),g){var o=i[h(f)];o||(o=[]);var p=j(f,b,d,e);o.push(p),p.i=o.length-1,p.type=b,i[h(f)]=o,f.addEventListener(b,p),"tap"===b&&f.addEventListener("click",function(a){if(a.target){var b=a.target.tagName;if(!l.test(b))if("A"===b){var c=a.target.href;c&&~c.indexOf("tel:")||a.preventDefault()}else a.preventDefault()}})}})},a.fn.off=function(b,d,e){return this.each(function(){var f=h(this);if(b)if(d)if(e){var g=c[f]&&c[f][b]&&c[f][b][d];a.each(g,function(a,b){return h(b)===h(e)?(g.splice(a,1),!1):void 0},!0)}else c[f]&&c[f][b]&&delete c[f][b][d];else c[f]&&delete c[f][b];else c[f]&&delete c[f];c[f]?(!c[f][b]||a.isEmptyObject(c[f][b]))&&k(this,b).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this)):k(this).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this))})}}(mui),function(a,b,c){a.targets={},a.targetHandles=[],a.registerTarget=function(b){return b.index=b.index||1e3,a.targetHandles.push(b),a.targetHandles.sort(function(a,b){return a.index-b.index}),a.targetHandles},b.addEventListener(a.EVENT_START,function(b){for(var d=b.target,e={};d&&d!==c;d=d.parentNode){var f=!1;if(a.each(a.targetHandles,function(c,g){var h=g.name;f||e[h]||!g.hasOwnProperty("handle")?e[h]||g.isReset!==!1&&(a.targets[h]=!1):(a.targets[h]=g.handle(b,d),a.targets[h]&&(e[h]=!0,g.isContinue!==!0&&(f=!0)))}),f)break}}),b.addEventListener("click",function(b){for(var d=b.target,e=!1;d&&d!==c&&("A"!==d.tagName||(a.each(a.targetHandles,function(a,c){c.name;return c.hasOwnProperty("handle")&&c.handle(b,d)?(e=!0,b.preventDefault(),!1):void 0}),!e));d=d.parentNode);})}(mui,window,document),function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Object.setPrototypeOf=Object.setPrototypeOf||function(a,b){return a.__proto__=b,a}}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("Events"),d=!0;for(var e in b)"bubbles"===e?d=!!b[e]:c[e]=b[e];return c.initEvent(a,d,!0),c}"undefined"==typeof window.CustomEvent&&(a.prototype=window.Event.prototype,window.CustomEvent=a)}(),Function.prototype.bind=Function.prototype.bind||function(a){var b=Array.prototype.splice.call(arguments,1),c=this,d=function(){var e=b.concat(Array.prototype.splice.call(arguments,0));return this instanceof d?void c.apply(this,e):c.apply(a,e)};return d.prototype=c.prototype,d},function(a){"classList"in a.documentElement||!Object.defineProperty||"undefined"==typeof HTMLElement||Object.defineProperty(HTMLElement.prototype,"classList",{get:function(){function a(a){return function(c){var d=b.className.split(/\s+/),e=d.indexOf(c);a(d,e,c),b.className=d.join(" ")}}var b=this,c={add:a(function(a,b,c){~b||a.push(c)}),remove:a(function(a,b){~b&&a.splice(b,1)}),toggle:a(function(a,b,c){~b?a.splice(b,1):a.push(c)}),contains:function(a){return!!~b.className.split(/\s+/).indexOf(a)},item:function(a){return b.className.split(/\s+/)[a]||null}};return Object.defineProperty(c,"length",{get:function(){return b.className.split(/\s+/).length}}),c}})}(document),function(a){if(!a.requestAnimationFrame){var b=0;a.requestAnimationFrame=a.webkitRequestAnimationFrame||function(c,d){var e=(new Date).getTime(),f=Math.max(0,16.7-(e-b)),g=a.setTimeout(function(){c(e+f)},f);return b=e+f,g},a.cancelAnimationFrame=a.webkitCancelAnimationFrame||a.webkitCancelRequestAnimationFrame||function(a){clearTimeout(a)}}}(window),function(a,b,c){if((a.os.android||a.os.ios)&&!b.FastClick){var d=function(a,b){return"LABEL"===b.tagName&&b.parentNode&&(b=b.parentNode.querySelector("input")),!b||"radio"!==b.type&&"checkbox"!==b.type||b.disabled?!1:b};a.registerTarget({name:c,index:40,handle:d,target:!1});var e=function(c){var d=a.targets.click;if(d){var e,f;document.activeElement&&document.activeElement!==d&&document.activeElement.blur(),f=c.detail.gesture.changedTouches[0],e=document.createEvent("MouseEvents"),e.initMouseEvent("click",!0,!0,b,1,f.screenX,f.screenY,f.clientX,f.clientY,!1,!1,!1,!1,0,null),e.forwardedTouchEvent=!0,d.dispatchEvent(e),c.detail&&c.detail.gesture.preventDefault()}};b.addEventListener("tap",e),b.addEventListener("doubletap",e),b.addEventListener("click",function(b){return a.targets.click&&!b.forwardedTouchEvent?(b.stopImmediatePropagation?b.stopImmediatePropagation():b.propagationStopped=!0,b.stopPropagation(),b.preventDefault(),!1):void 0},!0)}}(mui,window,"click"),function(a,b){a(function(){if(a.os.ios){var c="mui-focusin",d="mui-bar-tab",e="mui-bar-footer",f="mui-bar-footer-secondary",g="mui-bar-footer-secondary-tab";b.addEventListener("focusin",function(h){if(!(a.os.plus&&window.plus&&plus.webview.currentWebview().children().length>0)){var i=h.target;if(i.tagName&&("TEXTAREA"===i.tagName||"INPUT"===i.tagName&&("text"===i.type||"search"===i.type||"number"===i.type))){if(i.disabled||i.readOnly)return;b.body.classList.add(c);for(var j=!1;i&&i!==b;i=i.parentNode){var k=i.classList;if(k&&k.contains(d)||k.contains(e)||k.contains(f)||k.contains(g)){j=!0;break}}if(j){var l=b.body.scrollHeight,m=b.body.scrollLeft;setTimeout(function(){window.scrollTo(m,l)},20)}}}}),b.addEventListener("focusout",function(a){var d=b.body.classList;d.contains(c)&&(d.remove(c),setTimeout(function(){window.scrollTo(b.body.scrollLeft,b.body.scrollTop)},20))})}})}(mui,document),function(a){a.namespace="mui",a.classNamePrefix=a.namespace+"-",a.classSelectorPrefix="."+a.classNamePrefix,a.className=function(b){return a.classNamePrefix+b},a.classSelector=function(b){return b.replace(/\./g,a.classSelectorPrefix)},a.eventName=function(b,c){return b+(a.namespace?"."+a.namespace:"")+(c?"."+c:"")}}(mui),function(a,b){a.gestures={session:{}},a.preventDefault=function(a){a.preventDefault()},a.stopPropagation=function(a){a.stopPropagation()},a.addGesture=function(b){return a.addAction("gestures",b)};var c=Math.round,d=Math.abs,e=Math.sqrt,f=(Math.atan,Math.atan2),g=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],f=b[c[1]]-a[c[1]];return e(d*d+f*f)},h=function(a,b){if(a.length>=2&&b.length>=2){var c=["pageX","pageY"];return g(b[1],b[0],c)/g(a[1],a[0],c)}return 1},i=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*f(e,d)/Math.PI},j=function(a,b){return a===b?"":d(a)>=d(b)?a>0?"left":"right":b>0?"up":"down"},k=function(a,b){var c=["pageX","pageY"];return i(b[1],b[0],c)-i(a[1],a[0],c)},l=function(a,b,c){return{x:b/a||0,y:c/a||0}},m=function(b,c){a.gestures.stoped||a.doAction("gestures",function(d,e){a.gestures.stoped||a.options.gestureConfig[e.name]!==!1&&e.handle(b,c)})},n=function(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1},o=function(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];e.indexOf(g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d},p=function(a){var b=a.length;if(1===b)return{x:c(a[0].pageX),y:c(a[0].pageY)};for(var d=0,e=0,f=0;b>f;)d+=a[f].pageX,e+=a[f].pageY,f++;return{x:c(d/b),y:c(e/b)}},q=function(){return a.options.gestureConfig.pinch},r=function(b){for(var d=[],e=0;e<b.touches.length;)d[e]={pageX:c(b.touches[e].pageX),pageY:c(b.touches[e].pageY)},e++;return{timestamp:a.now(),gesture:b.gesture,touches:d,center:p(b.touches),deltaX:b.deltaX,deltaY:b.deltaY}},s=function(b){var c=a.gestures.session,d=b.center,e=c.offsetDelta||{},f=c.prevDelta||{},g=c.prevTouch||{};(b.gesture.type===a.EVENT_START||b.gesture.type===a.EVENT_END)&&(f=c.prevDelta={x:g.deltaX||0,y:g.deltaY||0},e=c.offsetDelta={x:d.x,y:d.y}),b.deltaX=f.x+(d.x-e.x),b.deltaY=f.y+(d.y-e.y)},t=function(b){var c=a.gestures.session,d=b.touches,e=d.length;c.firstTouch||(c.firstTouch=r(b)),q()&&e>1&&!c.firstMultiTouch?c.firstMultiTouch=r(b):1===e&&(c.firstMultiTouch=!1);var f=c.firstTouch,l=c.firstMultiTouch,m=l?l.center:f.center,n=b.center=p(d);b.timestamp=a.now(),b.deltaTime=b.timestamp-f.timestamp,b.angle=i(m,n),b.distance=g(m,n),s(b),b.offsetDirection=j(b.deltaX,b.deltaY),b.scale=l?h(l.touches,d):1,b.rotation=l?k(l.touches,d):0,v(b)},u=25,v=function(b){var c,e,f,g,h=a.gestures.session,i=h.lastInterval||b,k=b.timestamp-i.timestamp;if(b.gesture.type!=a.EVENT_CANCEL&&(k>u||void 0===i.velocity)){var m=i.deltaX-b.deltaX,n=i.deltaY-b.deltaY,o=l(k,m,n);e=o.x,f=o.y,c=d(o.x)>d(o.y)?o.x:o.y,g=j(m,n)||i.direction,h.lastInterval=b}else c=i.velocity,e=i.velocityX,f=i.velocityY,g=i.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g},w={},x=function(a){for(var b=0;b<a.length;b++)!a.identifier&&(a.identifier=0);return a},y=function(b,c){var d=x(a.slice.call(b.touches||[b])),e=b.type,f=[],g=[];if(e!==a.EVENT_START&&e!==a.EVENT_MOVE||1!==d.length){var h=0,f=[],g=[],i=x(a.slice.call(b.changedTouches||[b]));c.target=b.target;var j=a.gestures.session.target||b.target;if(f=d.filter(function(a){return n(a.target,j)}),e===a.EVENT_START)for(h=0;h<f.length;)w[f[h].identifier]=!0,h++;for(h=0;h<i.length;)w[i[h].identifier]&&g.push(i[h]),(e===a.EVENT_END||e===a.EVENT_CANCEL)&&delete w[i[h].identifier],h++;if(!g.length)return!1}else w[d[0].identifier]=!0,f=d,g=d,c.target=b.target;f=o(f.concat(g),"identifier",!0);var k=f.length,l=g.length;return e===a.EVENT_START&&k-l===0&&(c.isFirst=!0,a.gestures.touch=a.gestures.session={target:b.target}),c.isFinal=(e===a.EVENT_END||e===a.EVENT_CANCEL)&&k-l===0,c.touches=f,c.changedTouches=g,!0},z=function(b){var c={gesture:b},d=y(b,c);d&&(t(c),m(b,c),a.gestures.session.prevTouch=c,b.type!==a.EVENT_END||a.isTouchable||(a.gestures.touch=a.gestures.session={}))};b.addEventListener(a.EVENT_START,z),b.addEventListener(a.EVENT_MOVE,z),b.addEventListener(a.EVENT_END,z),b.addEventListener(a.EVENT_CANCEL,z),b.addEventListener(a.EVENT_CLICK,function(b){(a.os.android||a.os.ios)&&(a.targets.popover&&b.target===a.targets.popover||a.targets.tab||a.targets.offcanvas||a.targets.modal)&&b.preventDefault()},!0),a.isScrolling=!1;var A=null;b.addEventListener("scroll",function(){a.isScrolling=!0,A&&clearTimeout(A),A=setTimeout(function(){a.isScrolling=!1},250)})}(mui,window),function(a,b){var c=0,d=function(d,e){var f=a.gestures.session,g=this.options,h=a.now();switch(d.type){case a.EVENT_MOVE:h-c>300&&(c=h,f.flickStart=e.center);break;case a.EVENT_END:case a.EVENT_CANCEL:e.flick=!1,f.flickStart&&g.flickMaxTime>h-c&&e.distance>g.flickMinDistince&&(e.flick=!0,e.flickTime=h-c,e.flickDistanceX=e.center.x-f.flickStart.x,e.flickDistanceY=e.center.y-f.flickStart.y,a.trigger(f.target,b,e),a.trigger(f.target,b+e.direction,e))}};a.addGesture({name:b,index:5,handle:d,options:{flickMaxTime:200,flickMinDistince:10}})}(mui,"flick"),function(a,b){var c=function(c,d){var e=a.gestures.session;if(c.type===a.EVENT_END||c.type===a.EVENT_CANCEL){var f=this.options;d.swipe=!1,d.direction&&f.swipeMaxTime>d.deltaTime&&d.distance>f.swipeMinDistince&&(d.swipe=!0,a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d))}};a.addGesture({name:b,index:10,handle:c,options:{swipeMaxTime:300,swipeMinDistince:18}})}(mui,"swipe"),function(a,b){var c=function(c,d){var e=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(!d.direction||!e.target)return;e.lockDirection&&e.startDirection&&e.startDirection&&e.startDirection!==d.direction&&("up"===e.startDirection||"down"===e.startDirection?d.direction=d.deltaY<0?"up":"down":d.direction=d.deltaX<0?"left":"right"),e.drag||(e.drag=!0,a.trigger(e.target,b+"start",d)),a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d);break;case a.EVENT_END:case a.EVENT_CANCEL:e.drag&&d.isFinal&&a.trigger(e.target,b+"end",d)}};a.addGesture({name:b,index:20,handle:c,options:{fingers:1}})}(mui,"drag"),function(a,b){var c,d,e=function(e,f){var g=a.gestures.session,h=this.options;switch(e.type){case a.EVENT_END:if(!f.isFinal)return;var i=g.target;if(!i||i.disabled||i.classList&&i.classList.contains("mui-disabled"))return;if(f.distance<h.tapMaxDistance&&f.deltaTime<h.tapMaxTime){if(a.options.gestureConfig.doubletap&&c&&c===i&&d&&f.timestamp-d<h.tapMaxInterval)return a.trigger(i,"doubletap",f),d=a.now(),void(c=i);a.trigger(i,b,f),d=a.now(),c=i}}};a.addGesture({name:b,index:30,handle:e,options:{fingers:1,tapMaxInterval:300,tapMaxDistance:5,tapMaxTime:250}})}(mui,"tap"),function(a,b){var c,d=function(d,e){var f=a.gestures.session,g=this.options;switch(d.type){case a.EVENT_START:clearTimeout(c),c=setTimeout(function(){a.trigger(f.target,b,e)},g.holdTimeout);break;case a.EVENT_MOVE:e.distance>g.holdThreshold&&clearTimeout(c);break;case a.EVENT_END:case a.EVENT_CANCEL:clearTimeout(c)}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:500,holdThreshold:2}})}(mui,"longtap"),function(a,b){var c,d=function(d,e){var f=a.gestures.session,g=this.options;switch(d.type){case a.EVENT_START:a.options.gestureConfig.hold&&(c&&clearTimeout(c),c=setTimeout(function(){e.hold=!0,a.trigger(f.target,b,e)},g.holdTimeout));break;case a.EVENT_MOVE:break;case a.EVENT_END:case a.EVENT_CANCEL:c&&(clearTimeout(c)&&(c=null),a.trigger(f.target,"release",e))}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:0}})}(mui,"hold"),function(a,b){var c=function(c,d){var e=this.options,f=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(a.options.gestureConfig.pinch){if(d.touches.length<2)return;f.pinch||(f.pinch=!0,a.trigger(f.target,b+"start",d)),a.trigger(f.target,b,d);var g=d.scale,h=d.rotation,i="undefined"==typeof d.lastScale?1:d.lastScale,j=1e-12;g>i?(i=g-j,a.trigger(f.target,b+"out",d)):i>g&&(i=g+j,a.trigger(f.target,b+"in",d)),Math.abs(h)>e.minRotationAngle&&a.trigger(f.target,"rotate",d)}break;case a.EVENT_END:case a.EVENT_CANCEL:a.options.gestureConfig.pinch&&f.pinch&&2===d.touches.length&&(f.pinch=!1,a.trigger(f.target,b+"end",d))}};a.addGesture({name:b,index:10,handle:c,options:{minRotationAngle:0}})}(mui,"pinch"),function(a){function b(a,b){var c="MUI_SCROLL_POSITION_"+document.location.href+"_"+b.src,d=parseFloat(localStorage.getItem(c))||0;d&&!function(a){b.onload=function(){window.scrollTo(0,a)}}(d),setInterval(function(){var a=window.scrollY;d!==a&&(localStorage.setItem(c,a+""),d=a)},100)}a.global=a.options={gestureConfig:{tap:!0,doubletap:!1,longtap:!1,hold:!1,flick:!0,swipe:!0,drag:!0,pinch:!1}},a.initGlobal=function(b){return a.options=a.extend(!0,a.global,b),this};var c={};a.init=function(b){return a.options=a.extend(!0,a.global,b||{}),a.ready(function(){a.doAction("inits",function(b,d){var e=!(c[d.name]&&!d.repeat);e&&(d.handle.call(a),c[d.name]=!0)})}),this},a.addInit=function(b){return a.addAction("inits",b)},a.addInit({name:"iframe",index:100,handle:function(){var b=a.options,c=b.subpages||[];!a.os.plus&&c.length&&d(c[0])}});var d=function(c){var d=document.createElement("div");d.className="mui-iframe-wrapper";var e=c.styles||{};"string"!=typeof e.top&&(e.top="0px"),"string"!=typeof e.bottom&&(e.bottom="0px"),d.style.top=e.top,d.style.bottom=e.bottom;var f=document.createElement("iframe");f.src=c.url,f.id=c.id||c.url,f.name=f.id,d.appendChild(f),document.body.appendChild(d),a.os.wechat&&b(d,f)};a(function(){var b=document.body.classList,c=[];a.os.ios?(c.push({os:"ios",version:a.os.version}),b.add("mui-ios")):a.os.android&&(c.push({os:"android",version:a.os.version}),b.add("mui-android")),a.os.wechat&&(c.push({os:"wechat",version:a.os.wechat.version}),b.add("mui-wechat")),c.length&&a.each(c,function(c,d){var e="";d.version&&a.each(d.version.split("."),function(c,f){e=e+(e?"-":"")+f,b.add(a.className(d.os+"-"+e))})})})}(mui),function(a){var b={swipeBack:!1,preloadPages:[],preloadLimit:10,keyEventBind:{backbutton:!0,menubutton:!0},titleConfig:{height:"44px",backgroundColor:"#f7f7f7",bottomBorderColor:"#cccccc",title:{text:"",position:{top:0,left:0,width:"100%",height:"100%"},styles:{color:"#000000",align:"center",family:"'Helvetica Neue',Helvetica,sans-serif",size:"17px",style:"normal",weight:"normal",fontSrc:""}},back:{image:{base64Data:"",imgSrc:"",sprite:{top:"0px",left:"0px",width:"100%",height:"100%"},position:{top:"10px",left:"10px",width:"24px",height:"24px"}}}}},c={event:"titleUpdate",autoShow:!0,duration:300,aniShow:"slide-in-right",extras:{}};a.options.show&&(c=a.extend(!0,c,a.options.show)),a.currentWebview=null,a.extend(!0,a.global,b),a.extend(!0,a.options,b),a.waitingOptions=function(b){return a.extend(!0,{},{autoShow:!0,title:"",modal:!1},b)},a.showOptions=function(b){return a.extend(!0,{},c,b)},a.windowOptions=function(b){return a.extend({scalable:!1,bounce:""},b)},a.plusReady=function(a){return window.plus?setTimeout(function(){a()},0):document.addEventListener("plusready",function(){a()},!1),this},a.fire=function(b,c,d){if(b){if("undefined"==typeof d)d="";else{if("boolean"==typeof d||"number"==typeof d)return void b.evalJS("typeof mui!=='undefined'&&mui.receive('"+c+"',"+d+")");(a.isPlainObject(d)||a.isArray(d))&&(d=JSON.stringify(d||{}).replace(/\'/g,"\\u0027").replace(/\\/g,"\\u005c"))}b.evalJS("typeof mui!=='undefined'&&mui.receive('"+c+"','"+d+"')")}},a.receive=function(b,c){if(b){try{c&&"string"==typeof c&&(c=JSON.parse(c))}catch(d){}a.trigger(document,b,c)}};var d=function(b){if(!b.preloaded){a.fire(b,"preload");for(var c=b.children(),d=0;d<c.length;d++)a.fire(c[d],"preload");b.preloaded=!0}},e=function(b,c,d){if(d){if(!b[c+"ed"]){a.fire(b,c);for(var e=b.children(),f=0;f<e.length;f++)a.fire(e[f],c);b[c+"ed"]=!0}}else{a.fire(b,c);for(var e=b.children(),f=0;f<e.length;f++)a.fire(e[f],c)}};a.openWindow=function(b,f,g){if("object"==typeof b?(g=b,b=g.url,f=g.id||b):"object"==typeof f?(g=f,f=g.id||b):f=f||b,!a.os.plus)return void(a.os.ios||a.os.android?window.top.location.href=b:window.parent.location.href=b);if(window.plus){g=g||{};var h,i,j=g.params||{},k=null,l=null;if(a.webviews[f]?(l=a.webviews[f],plus.webview.getWebviewById(f)&&(k=l.webview)):g.createNew!==!0&&(k=plus.webview.getWebviewById(f)),k)return h=l?l.show:c,h=g.show?a.extend(h,g.show):h,h.autoShow&&k.show(h.aniShow,h.duration,function(){d(k),e(k,"pagebeforeshow",!1)}),l&&l.afterShowMethodName&&k.evalJS(l.afterShowMethodName+"('"+JSON.stringify(j)+"')"),k;if(!b)throw new Error("webview["+f+"] does not exist");var m=a.waitingOptions(g.waiting);if(m.autoShow&&(i=plus.nativeUI.showWaiting(m.title,m.options)),g=a.extend(g,{id:f,url:b}),k=a.createWindow(g),h=a.showOptions(g.show),h.autoShow){var n=function(){i&&i.close(),k.show(h.aniShow,h.duration,function(){},h.extras),g.afterShowMethodName&&k.evalJS(g.afterShowMethodName+"('"+JSON.stringify(j)+"')")};k.addEventListener(h.event,n,!1),k.addEventListener("loaded",function(){d(k),e(k,"pagebeforeshow",!1)},!1)}return k}},a.openWindowWithTitle=function(b,f){b=b||{};var g=b.url,h=b.id||g;if(!a.os.plus)return void(a.os.ios||a.os.android?window.top.location.href=g:window.parent.location.href=g);if(window.plus){var i,j,k=b.params||{},l=null,m=null;if(a.webviews[h]?(m=a.webviews[h],plus.webview.getWebviewById(h)&&(l=m.webview)):b.createNew!==!0&&(l=plus.webview.getWebviewById(h)),l)return i=m?m.show:c,i=b.show?a.extend(i,b.show):i,i.autoShow&&l.show(i.aniShow,i.duration,function(){d(l),e(l,"pagebeforeshow",!1)}),m&&m.afterShowMethodName&&l.evalJS(m.afterShowMethodName+"('"+JSON.stringify(k)+"')"),l;if(!g)throw new Error("webview["+h+"] does not exist");var n=a.waitingOptions(b.waiting);if(n.autoShow&&(j=plus.nativeUI.showWaiting(n.title,n.options)),b=a.extend(b,{id:h,url:g}),l=a.createWindow(b),f){a.extend(!0,a.options.titleConfig,f);var o=a.options.titleConfig.id?a.options.titleConfig.id:h+"_title",p=new plus.nativeObj.View(o,{top:0,height:a.options.titleConfig.height,width:"100%",dock:"top",position:"dock"});p.drawRect(a.options.titleConfig.backgroundColor);var q=parseInt(a.options.titleConfig.height)-1;if(p.drawRect(a.options.titleConfig.bottomBorderColor,{top:q+"px",left:"0px"}),a.options.titleConfig.title.text){var r=a.options.titleConfig.title;p.drawText(r.text,r.position,r.styles)}var s=a.options.titleConfig.back,t=null,u=s.image;if(u.base64Data||u.imgSrc){t={left:parseInt(u.position.left),right:parseInt(u.position.left)+parseInt(u.position.width)};var v=new plus.nativeObj.Bitmap(h+"_back");u.base64Data?v.loadBase64Data(u.base64Data):v.load(u.imgSrc),p.drawBitmap(v,u.sprite,u.position)}p.setTouchEventRect({top:"0px",left:"0px",width:"100%",height:"100%"}),p.interceptTouchEvent(!0),p.addEventListener("click",function(b){var c=b.clientX;t&&c>t.left&&c<t.right&&(s.click&&a.isFunction(s.click)?s.click():l.evalJS("window.mui&&mui.back();"))},!1),l.append(p)}return i=a.showOptions(b.show),i.autoShow&&l.addEventListener(i.event,function(){j&&j.close(),l.show(i.aniShow,i.duration,function(){},i.extras)},!1),l}},a.createWindow=function(b,c){if(window.plus){var d,e=b.id||b.url;if(b.preload){a.webviews[e]&&a.webviews[e].webview.getURL()?d=a.webviews[e].webview:(b.createNew!==!0&&(d=plus.webview.getWebviewById(e)),d||(d=plus.webview.create(b.url,e,a.windowOptions(b.styles),a.extend({preload:!0},b.extras)),b.subpages&&a.each(b.subpages,function(b,c){var e=c.id||c.url;if(e){var f=plus.webview.getWebviewById(e);f||(f=plus.webview.create(c.url,e,a.windowOptions(c.styles),a.extend({preload:!0},c.extras))),d.append(f)}}))),a.webviews[e]={webview:d,preload:!0,show:a.showOptions(b.show),afterShowMethodName:b.afterShowMethodName};var f=a.data.preloads,g=f.indexOf(e);if(~g&&f.splice(g,1),f.push(e),f.length>a.options.preloadLimit){var h=a.data.preloads.shift(),i=a.webviews[h];i&&i.webview&&a.closeAll(i.webview),delete a.webviews[h]}}else c!==!1&&(d=plus.webview.create(b.url,e,a.windowOptions(b.styles),b.extras),b.subpages&&a.each(b.subpages,function(b,c){var e=c.id||c.url,f=plus.webview.getWebviewById(e);f||(f=plus.webview.create(c.url,e,a.windowOptions(c.styles),c.extras)),d.append(f)}));return d}},a.preload=function(b){return b.preload||(b.preload=!0),a.createWindow(b)},a.closeOpened=function(b){var c=b.opened();if(c)for(var d=0,e=c.length;e>d;d++){var f=c[d],g=f.opened();g&&g.length>0?(a.closeOpened(f),f.close("none")):f.parent()!==b&&f.close("none")}},a.closeAll=function(b,c){a.closeOpened(b),c?b.close(c):b.close()},a.createWindows=function(b){a.each(b,function(b,c){a.createWindow(c,!1)})},a.appendWebview=function(b){if(window.plus){var c,d=b.id||b.url;return a.webviews[d]||(plus.webview.getWebviewById(d)||(c=plus.webview.create(b.url,d,b.styles,b.extras)),plus.webview.currentWebview().append(c),a.webviews[d]=b),c}},a.webviews={},a.data.preloads=[],a.plusReady(function(){a.currentWebview=plus.webview.currentWebview()}),a.addInit({name:"5+",index:100,handle:function(){var b=a.options,c=b.subpages||[];a.os.plus&&a.plusReady(function(){a.each(c,function(b,c){a.appendWebview(c)}),plus.webview.currentWebview()===plus.webview.getWebviewById(plus.runtime.appid)&&setTimeout(function(){d(plus.webview.currentWebview())},300),a.os.ios&&a.options.statusBarBackground&&plus.navigator.setStatusBarBackground(a.options.statusBarBackground),a.os.android&&parseFloat(a.os.version)<4.4&&null==plus.webview.currentWebview().parent()&&document.addEventListener("resume",function(){var a=document.body;a.style.display="none",setTimeout(function(){a.style.display=""},10)})})}}),window.addEventListener("preload",function(){var b=a.options.preloadPages||[];a.plusReady(function(){a.each(b,function(b,c){a.createWindow(a.extend(c,{preload:!0}))})})}),a.supportStatusbarOffset=function(){return a.os.plus&&a.os.ios&&parseFloat(a.os.version)>=7},a.ready(function(){a.supportStatusbarOffset()&&document.body.classList.add("mui-statusbar")})}(mui),function(a,b){a.addBack=function(b){return a.addAction("backs",b)},a.addBack({name:"browser",index:100,handle:function(){return b.history.length>1?(b.history.back(),!0):!1}}),a.back=function(){("function"!=typeof a.options.beforeback||a.options.beforeback()!==!1)&&a.doAction("backs")},b.addEventListener("tap",function(b){var c=a.targets.action;c&&c.classList.contains("mui-action-back")&&(a.back(),a.targets.action=!1)}),b.addEventListener("swiperight",function(b){var c=b.detail;a.options.swipeBack===!0&&Math.abs(c.angle)<3&&a.back()})}(mui,window),function(a,b){a.os.plus&&a.os.android&&a.addBack({name:"mui",index:5,handle:function(){if(a.targets._popover&&a.targets._popover.classList.contains("mui-active"))return a(a.targets._popover).popover("hide"),!0;var b=document.querySelector(".mui-off-canvas-wrap.mui-active");if(b)return a(b).offCanvas("close"),!0;var c=a.isFunction(a.getPreviewImage)&&a.getPreviewImage();return c&&c.isShown()?(c.close(),!0):a.closePopup()}}),a.__back__first=null,a.addBack({name:"5+",index:10,handle:function(){if(!b.plus)return!1;var c=plus.webview.currentWebview(),d=c.parent();return d?d.evalJS("mui&&mui.back();"):c.canBack(function(d){d.canBack?b.history.back():c.id===plus.runtime.appid?a.__back__first?(new Date).getTime()-a.__back__first<2e3&&plus.runtime.quit():(a.__back__first=(new Date).getTime(),mui.toast("再按一次退出应用"),setTimeout(function(){a.__back__first=null},2e3)):c.preload?c.hide("auto"):a.closeAll(c)}),!0}}),a.menu=function(){var c=document.querySelector(".mui-action-menu");if(c)a.trigger(c,a.EVENT_START),a.trigger(c,"tap");else if(b.plus){var d=a.currentWebview,e=d.parent(); +e&&e.evalJS("mui&&mui.menu();")}};var c=function(){a.back()},d=function(){a.menu()};a.plusReady(function(){a.options.keyEventBind.backbutton&&plus.key.addEventListener("backbutton",c,!1),a.options.keyEventBind.menubutton&&plus.key.addEventListener("menubutton",d,!1)}),a.addInit({name:"keyEventBind",index:1e3,handle:function(){a.plusReady(function(){a.options.keyEventBind.backbutton||plus.key.removeEventListener("backbutton",c),a.options.keyEventBind.menubutton||plus.key.removeEventListener("menubutton",d)})}})}(mui,window),function(a){a.addInit({name:"pullrefresh",index:1e3,handle:function(){var b=a.options,c=b.pullRefresh||{},d=c.down&&c.down.hasOwnProperty("callback"),e=c.up&&c.up.hasOwnProperty("callback");if(d||e){var f=c.container;if(f){var g=a(f);1===g.length&&(a.os.plus?d&&"circle"==c.down.style?a.plusReady(function(){a.fn.pullRefresh=a.fn.pullRefresh_native,g.pullRefresh(c)}):a.os.android?a.plusReady(function(){a.fn.pullRefresh=a.fn.pullRefresh_native;var b=plus.webview.currentWebview();if(window.__NWin_Enable__===!1)g.pullRefresh(c);else{if(e){var f={};f.up=c.up,f.webviewId=b.id||b.getURL(),g.pullRefresh(f)}if(d){var h=b.parent(),i=b.id||b.getURL();if(h){e||g.pullRefresh({webviewId:i});var j={webviewId:i};j.down=a.extend({},c.down),j.down.callback="_CALLBACK",h.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native"),h.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify(j)+"')")}}}}):g.pullRefresh(c):g.pullRefresh(c))}}}})}(mui),function(a,b,c){var d="application/json",e="text/html",f=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,g=/^(?:text|application)\/javascript/i,h=/^(?:text|application)\/xml/i,i=/^\s*$/;a.ajaxSettings={type:"GET",beforeSend:a.noop,success:a.noop,error:a.noop,complete:a.noop,context:null,xhr:function(a){return new b.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:d,xml:"application/xml, text/xml",html:e,text:"text/plain"},timeout:0,processData:!0,cache:!0};var j=function(a,b){var c=b.context;return b.beforeSend.call(c,a,b)===!1?!1:void 0},k=function(a,b,c){c.success.call(c.context,a,"success",b),m("success",b,c)},l=function(a,b,c,d){d.error.call(d.context,c,b,a),m(b,c,d)},m=function(a,b,c){c.complete.call(c.context,b,a)},n=function(b,c,d,e){var f,g=a.isArray(c),h=a.isPlainObject(c);a.each(c,function(c,i){f=a.type(i),e&&(c=d?e:e+"["+(h||"object"===f||"array"===f?c:"")+"]"),!e&&g?b.add(i.name,i.value):"array"===f||!d&&"object"===f?n(b,i,d,c):b.add(c,i)})},o=function(b){if(b.processData&&b.data&&"string"!=typeof b.data){var e=b.contentType;!e&&b.headers&&(e=b.headers["Content-Type"]),e&&~e.indexOf(d)?b.data=JSON.stringify(b.data):b.data=a.param(b.data,b.traditional)}!b.data||b.type&&"GET"!==b.type.toUpperCase()||(b.url=p(b.url,b.data),b.data=c)},p=function(a,b){return""===b?a:(a+"&"+b).replace(/[&?]{1,2}/,"?")},q=function(a){return a&&(a=a.split(";",2)[0]),a&&(a===e?"html":a===d?"json":g.test(a)?"script":h.test(a)&&"xml")||"text"},r=function(b,d,e,f){return a.isFunction(d)&&(f=e,e=d,d=c),a.isFunction(e)||(f=e,e=c),{url:b,data:d,success:e,dataType:f}};a.ajax=function(d,e){"object"==typeof d&&(e=d,d=c);var f=e||{};f.url=d||f.url;for(var g in a.ajaxSettings)f[g]===c&&(f[g]=a.ajaxSettings[g]);o(f);var h=f.dataType;f.cache!==!1&&(e&&e.cache===!0||"script"!==h)||(f.url=p(f.url,"_="+a.now()));var m,n=f.accepts[h&&h.toLowerCase()],r={},s=function(a,b){r[a.toLowerCase()]=[a,b]},t=/^([\w-]+:)\/\//.test(f.url)?RegExp.$1:b.location.protocol,u=f.xhr(f),v=u.setRequestHeader;if(s("X-Requested-With","XMLHttpRequest"),s("Accept",n||"*/*"),(n=f.mimeType||n)&&(n.indexOf(",")>-1&&(n=n.split(",",2)[0]),u.overrideMimeType&&u.overrideMimeType(n)),(f.contentType||f.contentType!==!1&&f.data&&"GET"!==f.type.toUpperCase())&&s("Content-Type",f.contentType||"application/x-www-form-urlencoded"),f.headers)for(var w in f.headers)s(w,f.headers[w]);if(u.setRequestHeader=s,u.onreadystatechange=function(){if(4===u.readyState){u.onreadystatechange=a.noop,clearTimeout(m);var b,c=!1,d="file:"===t;if(u.status>=200&&u.status<300||304===u.status||0===u.status&&d&&u.responseText){h=h||q(f.mimeType||u.getResponseHeader("content-type")),b=u.responseText;try{"script"===h?(1,eval)(b):"xml"===h?b=u.responseXML:"json"===h&&(b=i.test(b)?null:a.parseJSON(b))}catch(e){c=e}c?l(c,"parsererror",u,f):k(b,u,f)}else{var g=u.status?"error":"abort",j=u.statusText||null;d&&(g="error",j="404"),l(j,g,u,f)}}},j(u,f)===!1)return u.abort(),l(null,"abort",u,f),u;if(f.xhrFields)for(var w in f.xhrFields)u[w]=f.xhrFields[w];var x="async"in f?f.async:!0;u.open(f.type.toUpperCase(),f.url,x,f.username,f.password);for(var w in r)r.hasOwnProperty(w)&&v.apply(u,r[w]);return f.timeout>0&&(m=setTimeout(function(){u.onreadystatechange=a.noop,u.abort(),l(null,"timeout",u,f)},f.timeout)),u.send(f.data?f.data:null),u},a.param=function(a,b){var c=[];return c.add=function(a,b){this.push(encodeURIComponent(a)+"="+encodeURIComponent(b))},n(c,a,b),c.join("&").replace(/%20/g,"+")},a.get=function(){return a.ajax(r.apply(null,arguments))},a.post=function(){var b=r.apply(null,arguments);return b.type="POST",a.ajax(b)},a.getJSON=function(){var b=r.apply(null,arguments);return b.dataType="json",a.ajax(b)},a.fn.load=function(b,c,d){if(!this.length)return this;var e,g=this,h=b.split(/\s/),i=r(b,c,d),j=i.success;return h.length>1&&(i.url=h[0],e=h[1]),i.success=function(a){if(e){var b=document.createElement("div");b.innerHTML=a.replace(f,"");var c=document.createElement("div"),d=b.querySelectorAll(e);if(d&&d.length>0)for(var h=0,i=d.length;i>h;h++)c.appendChild(d[h]);g[0].innerHTML=c.innerHTML}else g[0].innerHTML=a;j&&j.apply(g,arguments)},a.ajax(i),this}}(mui,window),function(a){var b=document.createElement("a");b.href=window.location.href,a.plusReady(function(){a.ajaxSettings=a.extend(a.ajaxSettings,{xhr:function(c){if(c.crossDomain)return new plus.net.XMLHttpRequest;if("file:"!==b.protocol){var d=document.createElement("a");if(d.href=c.url,d.href=d.href,c.crossDomain=b.protocol+"//"+b.host!=d.protocol+"//"+d.host,c.crossDomain)return new plus.net.XMLHttpRequest}return a.os.ios&&window.webkit&&window.webkit.messageHandlers?new plus.net.XMLHttpRequest:new window.XMLHttpRequest}})})}(mui),function(a,b,c){a.offset=function(a){var d={top:0,left:0};return typeof a.getBoundingClientRect!==c&&(d=a.getBoundingClientRect()),{top:d.top+b.pageYOffset-a.clientTop,left:d.left+b.pageXOffset-a.clientLeft}}}(mui,window),function(a,b){a.scrollTo=function(a,c,d){c=c||1e3;var e=function(c){if(0>=c)return b.scrollTo(0,a),void(d&&d());var f=a-b.scrollY;setTimeout(function(){b.scrollTo(0,b.scrollY+f/c*10),e(c-10)},16.7)};e(c)},a.animationFrame=function(a){var b,c,d;return function(){b=arguments,d=this,c||(c=!0,requestAnimationFrame(function(){a.apply(d,b),c=!1}))}}}(mui,window),function(a){var b=!1,c=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/,d=function(){};d.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a.Class=d}(mui),function(a,b,c){var d="mui-pull-top-pocket",e="mui-pull-bottom-pocket",f="mui-pull",g="mui-pull-loading",h="mui-pull-caption",i="mui-pull-caption-down",j="mui-pull-caption-refresh",k="mui-pull-caption-nomore",l="mui-icon",m="mui-spinner",n="mui-icon-pulldown",o="mui-block",p="mui-hidden",q="mui-visibility",r=g+" "+l+" "+n,s=g+" "+l+" "+n,t=g+" "+l+" "+m,u=['<div class="'+f+'">','<div class="{icon}"></div>','<div class="'+h+'">{contentrefresh}</div>',"</div>"].join(""),v={init:function(b,c){this._super(b,a.extend(!0,{scrollY:!0,scrollX:!1,indicators:!0,deceleration:.003,down:{height:50,contentinit:"下拉可以刷新",contentdown:"下拉可以刷新",contentover:"释放立即刷新",contentrefresh:"正在刷新..."},up:{height:50,auto:!1,contentinit:"上拉显示更多",contentdown:"上拉显示更多",contentrefresh:"正在加载...",contentnomore:"没有更多数据了",duration:300}},c))},_init:function(){this._super(),this._initPocket()},_initPulldownRefresh:function(){this.pulldown=!0,this.topPocket&&(this.pullPocket=this.topPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.topCaption,this.pullLoading=this.topLoading)},_initPullupRefresh:function(){this.pulldown=!1,this.bottomPocket&&(this.pullPocket=this.bottomPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.bottomCaption,this.pullLoading=this.bottomLoading)},_initPocket:function(){var a=this.options;a.down&&a.down.hasOwnProperty("callback")&&(this.topPocket=this.scroller.querySelector("."+d),this.topPocket||(this.topPocket=this._createPocket(d,a.down,s),this.wrapper.insertBefore(this.topPocket,this.wrapper.firstChild)),this.topLoading=this.topPocket.querySelector("."+g),this.topCaption=this.topPocket.querySelector("."+h)),a.up&&a.up.hasOwnProperty("callback")&&(this.bottomPocket=this.scroller.querySelector("."+e),this.bottomPocket||(this.bottomPocket=this._createPocket(e,a.up,t),this.scroller.appendChild(this.bottomPocket)),this.bottomLoading=this.bottomPocket.querySelector("."+g),this.bottomCaption=this.bottomPocket.querySelector("."+h),this.wrapper.addEventListener("scrollbottom",this))},_createPocket:function(a,c,d){var e=b.createElement("div");return e.className=a,e.innerHTML=u.replace("{contentrefresh}",c.contentinit).replace("{icon}",d),e},_resetPullDownLoading:function(){var a=this.pullLoading;a&&(this.pullCaption.innerHTML=this.options.down.contentdown,a.style.webkitTransition="",a.style.webkitTransform="",a.style.webkitAnimation="",a.className=s)},_setCaptionClass:function(a,b,c){if(!a)switch(c){case this.options.up.contentdown:b.className=h+" "+i;break;case this.options.up.contentrefresh:b.className=h+" "+j;break;case this.options.up.contentnomore:b.className=h+" "+k}},_setCaption:function(a,b){if(!this.loading){var c=this.options,d=this.pullPocket,e=this.pullCaption,f=this.pullLoading,g=this.pulldown,h=this;d&&(b?setTimeout(function(){e.innerHTML=h.lastTitle=a,g?f.className=s:(h._setCaptionClass(!1,e,a),f.className=t),f.style.webkitAnimation="",f.style.webkitTransition="",f.style.webkitTransform=""},100):a!==this.lastTitle&&(e.innerHTML=a,g?a===c.down.contentrefresh?(f.className=t,f.style.webkitAnimation="spinner-spin 1s step-end infinite"):a===c.down.contentover?(f.className=r,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(180deg)"):a===c.down.contentdown&&(f.className=s,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(0deg)"):(a===c.up.contentrefresh?f.className=t+" "+q:f.className=t+" "+p,h._setCaptionClass(!1,e,a)),this.lastTitle=a))}}};a.PullRefresh=v}(mui,document),function(a,b,c,d){var e="mui-scroll",f="mui-scrollbar",g="mui-scrollbar-indicator",h=f+"-vertical",i=f+"-horizontal",j="mui-active",k={quadratic:{style:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",fn:function(a){return a*(2-a)}},circular:{style:"cubic-bezier(0.1, 0.57, 0.1, 1)",fn:function(a){return Math.sqrt(1- --a*a)}},outCirc:{style:"cubic-bezier(0.075, 0.82, 0.165, 1)"},outCubic:{style:"cubic-bezier(0.165, 0.84, 0.44, 1)"}},l=a.Class.extend({init:function(b,c){this.wrapper=this.element=b,this.scroller=this.wrapper.children[0],this.scrollerStyle=this.scroller&&this.scroller.style,this.stopped=!1,this.options=a.extend(!0,{scrollY:!0,scrollX:!1,startX:0,startY:0,indicators:!0,stopPropagation:!1,hardwareAccelerated:!0,fixedBadAndorid:!1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/},momentum:!0,snapX:.5,snap:!1,bounce:!0,bounceTime:500,bounceEasing:k.outCirc,scrollTime:500,scrollEasing:k.outCubic,directionLockThreshold:5,parallaxElement:!1,parallaxRatio:.5},c),this.x=0,this.y=0,this.translateZ=this.options.hardwareAccelerated?" translateZ(0)":"",this._init(),this.scroller&&(this.refresh(),this.scrollTo(this.options.startX,this.options.startY))},_init:function(){this._initParallax(),this._initIndicators(),this._initEvent()},_initParallax:function(){this.options.parallaxElement&&(this.parallaxElement=c.querySelector(this.options.parallaxElement),this.parallaxStyle=this.parallaxElement.style,this.parallaxHeight=this.parallaxElement.offsetHeight,this.parallaxImgStyle=this.parallaxElement.querySelector("img").style)},_initIndicators:function(){var a=this;if(a.indicators=[],this.options.indicators){var b,c=[];a.options.scrollY&&(b={el:this._createScrollBar(h),listenX:!1},this.wrapper.appendChild(b.el),c.push(b)),this.options.scrollX&&(b={el:this._createScrollBar(i),listenY:!1},this.wrapper.appendChild(b.el),c.push(b));for(var d=c.length;d--;)this.indicators.push(new m(this,c[d]))}},_initSnap:function(){this.currentPage={},this.pages=[];for(var a=this.snaps,b=a.length,c=0,d=-1,e=0,f=0,g=0,h=0,i=0;b>i;i++){var k=a[i],l=k.offsetLeft,m=k.offsetWidth;(0===i||l<=a[i-1].offsetLeft)&&(c=0,d++),this.pages[c]||(this.pages[c]=[]),e=this._getSnapX(l),h=Math.round(m*this.options.snapX),f=e-h,g=e-m+h,this.pages[c][d]={x:e,leftX:f,rightX:g,pageX:c,element:k},k.classList.contains(j)&&(this.currentPage=this.pages[c][0]),e>=this.maxScrollX&&c++}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(Math.min(0,-a+this.wrapperWidth/2),this.maxScrollX)},_gotoPage:function(a){this.currentPage=this.pages[Math.min(a,this.pages.length-1)][0];for(var b=0,c=this.snaps.length;c>b;b++)b===a?this.snaps[b].classList.add(j):this.snaps[b].classList.remove(j);this.scrollTo(this.currentPage.x,0,this.options.scrollTime)},_nearestSnap:function(a){if(!this.pages.length)return{x:0,pageX:0};var b=0,c=this.pages.length;for(a>0?a=0:a<this.maxScrollX&&(a=this.maxScrollX);c>b;b++){var d="left"===this.direction?this.pages[b][0].leftX:this.pages[b][0].rightX;if(a>=d)return this.pages[b][0]}return{x:0,pageX:0}},_initEvent:function(c){var d=c?"removeEventListener":"addEventListener";b[d]("orientationchange",this),b[d]("resize",this),this.scroller[d]("webkitTransitionEnd",this),this.wrapper[d](a.EVENT_START,this),this.wrapper[d](a.EVENT_CANCEL,this),this.wrapper[d](a.EVENT_END,this),this.wrapper[d]("drag",this),this.wrapper[d]("dragend",this),this.wrapper[d]("flick",this),this.wrapper[d]("scrollend",this),this.options.scrollX&&this.wrapper[d]("swiperight",this);var e=this.wrapper.querySelector(".mui-segmented-control");e&&mui(e)[c?"off":"on"]("click","a",a.preventDefault),this.wrapper[d]("scrollstart",this),this.wrapper[d]("refresh",this)},_handleIndicatorScrollend:function(){this.indicators.map(function(a){a.fade()})},_handleIndicatorScrollstart:function(){this.indicators.map(function(a){a.fade(1)})},_handleIndicatorRefresh:function(){this.indicators.map(function(a){a.refresh()})},handleEvent:function(b){if(this.stopped)return void this.resetPosition();switch(b.type){case a.EVENT_START:this._start(b);break;case"drag":this.options.stopPropagation&&b.stopPropagation(),this._drag(b);break;case"dragend":case"flick":this.options.stopPropagation&&b.stopPropagation(),this._flick(b);break;case a.EVENT_CANCEL:case a.EVENT_END:this._end(b);break;case"webkitTransitionEnd":this.transitionTimer&&this.transitionTimer.cancel(),this._transitionEnd(b);break;case"scrollstart":this._handleIndicatorScrollstart(b);break;case"scrollend":this._handleIndicatorScrollend(b),this._scrollend(b),b.stopPropagation();break;case"orientationchange":case"resize":this._resize();break;case"swiperight":b.stopPropagation();break;case"refresh":this._handleIndicatorRefresh(b)}},_start:function(b){if(this.moved=this.needReset=!1,this._transitionTime(),this.isInTransition){this.needReset=!0,this.isInTransition=!1;var c=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));this.setTranslate(Math.round(c.x),Math.round(c.y)),a.trigger(this.scroller,"scrollend",this),b.preventDefault()}this.reLayout(),a.trigger(this.scroller,"beforescrollstart",this)},_getDirectionByAngle:function(a){return-80>a&&a>-100?"up":a>=80&&100>a?"down":a>=170||-170>=a?"left":a>=-35&&10>=a?"right":null},_drag:function(c){var d=c.detail;if((this.options.scrollY||"up"===d.direction||"down"===d.direction)&&a.os.ios&&parseFloat(a.os.version)>=8){var e=d.gesture.touches[0].clientY;if(e+10>b.innerHeight||10>e)return void this.resetPosition(this.options.bounceTime)}var f=isReturn=!1;this._getDirectionByAngle(d.angle);if("left"===d.direction||"right"===d.direction?this.options.scrollX?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollY&&!this.moved&&(isReturn=!0):"up"===d.direction||"down"===d.direction?this.options.scrollY?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollX&&!this.moved&&(isReturn=!0):isReturn=!0,(this.moved||f)&&(c.stopPropagation(),d.gesture&&d.gesture.preventDefault()),!isReturn){this.moved?c.stopPropagation():a.trigger(this.scroller,"scrollstart",this);var g=0,h=0;this.moved?(g=d.deltaX-a.gestures.session.prevTouch.deltaX,h=d.deltaY-a.gestures.session.prevTouch.deltaY):(g=d.deltaX,h=d.deltaY);var i=Math.abs(d.deltaX),j=Math.abs(d.deltaY);i>j+this.options.directionLockThreshold?h=0:j>=i+this.options.directionLockThreshold&&(g=0),g=this.hasHorizontalScroll?g:0,h=this.hasVerticalScroll?h:0;var k=this.x+g,l=this.y+h;(k>0||k<this.maxScrollX)&&(k=this.options.bounce?this.x+g/3:k>0?0:this.maxScrollX),(l>0||l<this.maxScrollY)&&(l=this.options.bounce?this.y+h/3:l>0?0:this.maxScrollY),this.requestAnimationFrame||this._updateTranslate(),this.direction=d.deltaX>0?"right":"left",this.moved=!0,this.x=k,this.y=l,a.trigger(this.scroller,"scroll",this)}},_flick:function(b){if(this.moved){b.stopPropagation();var c=b.detail;if(this._clearRequestAnimationFrame(),"dragend"!==b.type||!c.flick){var d=Math.round(this.x),e=Math.round(this.y);if(this.isInTransition=!1,!this.resetPosition(this.options.bounceTime)){if(this.scrollTo(d,e),"dragend"===b.type)return void a.trigger(this.scroller,"scrollend",this);var f=0,g="";return this.options.momentum&&c.flickTime<300&&(momentumX=this.hasHorizontalScroll?this._momentum(this.x,c.flickDistanceX,c.flickTime,this.maxScrollX,this.options.bounce?this.wrapperWidth:0,this.options.deceleration):{destination:d,duration:0},momentumY=this.hasVerticalScroll?this._momentum(this.y,c.flickDistanceY,c.flickTime,this.maxScrollY,this.options.bounce?this.wrapperHeight:0,this.options.deceleration):{destination:e,duration:0},d=momentumX.destination,e=momentumY.destination,f=Math.max(momentumX.duration,momentumY.duration),this.isInTransition=!0),d!=this.x||e!=this.y?((d>0||d<this.maxScrollX||e>0||e<this.maxScrollY)&&(g=k.quadratic),void this.scrollTo(d,e,f,g)):void a.trigger(this.scroller,"scrollend",this)}}}},_end:function(b){this.needReset=!1,(!this.moved&&this.needReset||b.type===a.EVENT_CANCEL)&&this.resetPosition()},_transitionEnd:function(b){b.target==this.scroller&&this.isInTransition&&(this._transitionTime(),this.resetPosition(this.options.bounceTime)||(this.isInTransition=!1,a.trigger(this.scroller,"scrollend",this)))},_scrollend:function(b){(0===this.y&&0===this.maxScrollY||Math.abs(this.y)>0&&this.y<=this.maxScrollY)&&a.trigger(this.scroller,"scrollbottom",this)},_resize:function(){var a=this;clearTimeout(a.resizeTimeout),a.resizeTimeout=setTimeout(function(){a.refresh()},a.options.resizePolling)},_transitionTime:function(b){if(b=b||0,this.scrollerStyle.webkitTransitionDuration=b+"ms",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=b+"ms"),this.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.scrollerStyle.webkitTransitionDuration="0.001s",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration="0.001s")),this.indicators)for(var c=this.indicators.length;c--;)this.indicators[c].transitionTime(b);b&&(this.transitionTimer&&this.transitionTimer.cancel(),this.transitionTimer=a.later(function(){a.trigger(this.scroller,"webkitTransitionEnd")},b+100,this))},_transitionTimingFunction:function(a){if(this.scrollerStyle.webkitTransitionTimingFunction=a,this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=a),this.indicators)for(var b=this.indicators.length;b--;)this.indicators[b].transitionTimingFunction(a)},_translate:function(a,b){this.x=a,this.y=b},_clearRequestAnimationFrame:function(){this.requestAnimationFrame&&(cancelAnimationFrame(this.requestAnimationFrame),this.requestAnimationFrame=null)},_updateTranslate:function(){var a=this;(a.x!==a.lastX||a.y!==a.lastY)&&a.setTranslate(a.x,a.y),a.requestAnimationFrame=requestAnimationFrame(function(){a._updateTranslate()})},_createScrollBar:function(a){var b=c.createElement("div"),d=c.createElement("div");return b.className=f+" "+a,d.className=g,b.appendChild(d),a===h?(this.scrollbarY=b,this.scrollbarIndicatorY=d):a===i&&(this.scrollbarX=b,this.scrollbarIndicatorX=d),this.wrapper.appendChild(b),b},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},_reLayout:function(){if(this.hasHorizontalScroll||(this.maxScrollX=0,this.scrollerWidth=this.wrapperWidth),this.hasVerticalScroll||(this.maxScrollY=0,this.scrollerHeight=this.wrapperHeight),this.indicators.map(function(a){a.refresh()}),this.options.snap&&"string"==typeof this.options.snap){var a=this.scroller.querySelectorAll(this.options.snap);this.itemLength=0,this.snaps=[];for(var b=0,c=a.length;c>b;b++){var d=a[b];d.parentNode===this.scroller&&(this.itemLength++,this.snaps.push(d))}this._initSnap()}},_momentum:function(a,b,c,e,f,g){var h,i,j=parseFloat(Math.abs(b)/c);return g=g===d?6e-4:g,h=a+j*j/(2*g)*(0>b?-1:1),i=j/g,e>h?(h=f?e-f/2.5*(j/8):e,b=Math.abs(h-a),i=b/j):h>0&&(h=f?f/2.5*(j/8):0,b=Math.abs(a)+h,i=b/j),{destination:Math.round(h),duration:i}},_getTranslateStr:function(a,b){return this.options.hardwareAccelerated?"translate3d("+a+"px,"+b+"px,0px) "+this.translateZ:"translate("+a+"px,"+b+"px) "},setStopped:function(a){this.stopped=!!a},setTranslate:function(b,c){if(this.x=b,this.y=c,this.scrollerStyle.webkitTransform=this._getTranslateStr(b,c),this.parallaxElement&&this.options.scrollY){var d=c*this.options.parallaxRatio,e=1+d/((this.parallaxHeight-d)/2);e>1?(this.parallaxImgStyle.opacity=1-d/100*this.options.parallaxRatio,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-d)+" scale("+e+","+e+")"):(this.parallaxImgStyle.opacity=1,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-1)+" scale(1,1)")}if(this.indicators)for(var f=this.indicators.length;f--;)this.indicators[f].updatePosition();this.lastX=this.x,this.lastY=this.y,a.trigger(this.scroller,"scroll",this)},reLayout:function(){this.wrapper.offsetHeight;var b=parseFloat(a.getStyles(this.wrapper,"padding-left"))||0,c=parseFloat(a.getStyles(this.wrapper,"padding-right"))||0,d=parseFloat(a.getStyles(this.wrapper,"padding-top"))||0,e=parseFloat(a.getStyles(this.wrapper,"padding-bottom"))||0,f=this.wrapper.clientWidth,g=this.wrapper.clientHeight;this.scrollerWidth=this.scroller.offsetWidth,this.scrollerHeight=this.scroller.offsetHeight,this.wrapperWidth=f-b-c,this.wrapperHeight=g-d-e,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this.maxScrollY=Math.min(this.wrapperHeight-this.scrollerHeight,0),this.hasHorizontalScroll=this.options.scrollX&&this.maxScrollX<0,this.hasVerticalScroll=this.options.scrollY&&this.maxScrollY<0,this._reLayout()},resetPosition:function(a){var b=this.x,c=this.y;return a=a||0,!this.hasHorizontalScroll||this.x>0?b=0:this.x<this.maxScrollX&&(b=this.maxScrollX),!this.hasVerticalScroll||this.y>0?c=0:this.y<this.maxScrollY&&(c=this.maxScrollY),b==this.x&&c==this.y?!1:(this.scrollTo(b,c,a,this.options.scrollEasing),!0)},_reInit:function(){for(var a=this.wrapper.querySelectorAll("."+e),b=0,c=a.length;c>b;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style},refresh:function(){this._reInit(),this.reLayout(),a.trigger(this.scroller,"refresh",this),this.resetPosition()},scrollTo:function(a,b,c,d){var d=d||k.circular;this.isInTransition=c>0,this.isInTransition?(this._clearRequestAnimationFrame(),this._transitionTimingFunction(d.style),this._transitionTime(c),this.setTranslate(a,b)):this.setTranslate(a,b)},scrollToBottom:function(a,b){a=a||this.options.scrollTime,this.scrollTo(0,this.maxScrollY,a,b)},gotoPage:function(a){this._gotoPage(a)},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-scroll")],this.wrapper.setAttribute("data-scroll","")}}),m=function(b,d){this.wrapper="string"==typeof d.el?c.querySelector(d.el):d.el,this.wrapperStyle=this.wrapper.style,this.indicator=this.wrapper.children[0],this.indicatorStyle=this.indicator.style,this.scroller=b,this.options=a.extend({listenX:!0,listenY:!0,fade:!1,speedRatioX:0,speedRatioY:0},d),this.sizeRatioX=1,this.sizeRatioY=1,this.maxPosX=0,this.maxPosY=0,this.options.fade&&(this.wrapperStyle.webkitTransform=this.scroller.translateZ,this.wrapperStyle.webkitTransitionDuration=this.options.fixedBadAndorid&&a.os.isBadAndroid?"0.001s":"0ms",this.wrapperStyle.opacity="0")};m.prototype={handleEvent:function(a){},transitionTime:function(b){b=b||0,this.indicatorStyle.webkitTransitionDuration=b+"ms",this.scroller.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.indicatorStyle.webkitTransitionDuration="0.001s")},transitionTimingFunction:function(a){this.indicatorStyle.webkitTransitionTimingFunction=a},refresh:function(){this.transitionTime(),this.options.listenX&&!this.options.listenY?this.indicatorStyle.display=this.scroller.hasHorizontalScroll?"block":"none":this.options.listenY&&!this.options.listenX?this.indicatorStyle.display=this.scroller.hasVerticalScroll?"block":"none":this.indicatorStyle.display=this.scroller.hasHorizontalScroll||this.scroller.hasVerticalScroll?"block":"none",this.wrapper.offsetHeight,this.options.listenX&&(this.wrapperWidth=this.wrapper.clientWidth,this.indicatorWidth=Math.max(Math.round(this.wrapperWidth*this.wrapperWidth/(this.scroller.scrollerWidth||this.wrapperWidth||1)),8),this.indicatorStyle.width=this.indicatorWidth+"px",this.maxPosX=this.wrapperWidth-this.indicatorWidth,this.minBoundaryX=0,this.maxBoundaryX=this.maxPosX,this.sizeRatioX=this.options.speedRatioX||this.scroller.maxScrollX&&this.maxPosX/this.scroller.maxScrollX),this.options.listenY&&(this.wrapperHeight=this.wrapper.clientHeight,this.indicatorHeight=Math.max(Math.round(this.wrapperHeight*this.wrapperHeight/(this.scroller.scrollerHeight||this.wrapperHeight||1)),8),this.indicatorStyle.height=this.indicatorHeight+"px",this.maxPosY=this.wrapperHeight-this.indicatorHeight,this.minBoundaryY=0,this.maxBoundaryY=this.maxPosY,this.sizeRatioY=this.options.speedRatioY||this.scroller.maxScrollY&&this.maxPosY/this.scroller.maxScrollY),this.updatePosition()},updatePosition:function(){var a=this.options.listenX&&Math.round(this.sizeRatioX*this.scroller.x)||0,b=this.options.listenY&&Math.round(this.sizeRatioY*this.scroller.y)||0;a<this.minBoundaryX?(this.width=Math.max(this.indicatorWidth+a,8),this.indicatorStyle.width=this.width+"px",a=this.minBoundaryX):a>this.maxBoundaryX?(this.width=Math.max(this.indicatorWidth-(a-this.maxPosX),8),this.indicatorStyle.width=this.width+"px",a=this.maxPosX+this.indicatorWidth-this.width):this.width!=this.indicatorWidth&&(this.width=this.indicatorWidth,this.indicatorStyle.width=this.width+"px"),b<this.minBoundaryY?(this.height=Math.max(this.indicatorHeight+3*b,8),this.indicatorStyle.height=this.height+"px",b=this.minBoundaryY):b>this.maxBoundaryY?(this.height=Math.max(this.indicatorHeight-3*(b-this.maxPosY),8),this.indicatorStyle.height=this.height+"px",b=this.maxPosY+this.indicatorHeight-this.height):this.height!=this.indicatorHeight&&(this.height=this.indicatorHeight,this.indicatorStyle.height=this.height+"px"),this.x=a,this.y=b,this.indicatorStyle.webkitTransform=this.scroller._getTranslateStr(a,b)},fade:function(a,b){if(!b||this.visible){clearTimeout(this.fadeTimeout),this.fadeTimeout=null;var c=a?250:500,d=a?0:300;a=a?"1":"0",this.wrapperStyle.webkitTransitionDuration=c+"ms",this.fadeTimeout=setTimeout(function(a){this.wrapperStyle.opacity=a,this.visible=+a}.bind(this,a),d)}}},a.Scroll=l,a.fn.scroll=function(b){var c=[];return this.each(function(){var d=null,e=this,f=e.getAttribute("data-scroll");if(f)d=a.data[f];else{f=++a.uuid;var g=a.extend({},b);e.classList.contains("mui-segmented-control")&&(g=a.extend(g,{scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})),a.data[f]=d=new l(e,g),e.setAttribute("data-scroll",f)}c.push(d)}),1===c.length?c[0]:c}}(mui,window,document),function(a,b,c,d){var e="mui-visibility",f="mui-hidden",g=a.Scroll.extend(a.extend({handleEvent:function(a){this._super(a),"scrollbottom"===a.type&&a.target===this.scroller&&this._scrollbottom()},_scrollbottom:function(){this.pulldown||this.loading||(this.pulldown=!1,this._initPullupRefresh(),this.pullupLoading())},_start:function(a){a.touches&&a.touches.length&&a.touches[0].clientX>30&&a.target&&!this._preventDefaultException(a.target,this.options.preventDefaultException)&&a.preventDefault(),this.loading||(this.pulldown=this.pullPocket=this.pullCaption=this.pullLoading=!1),this._super(a)},_drag:function(a){this._super(a),!this.pulldown&&!this.loading&&this.topPocket&&"down"===a.detail.direction&&this.y>=0&&this._initPulldownRefresh(),this.pulldown&&this._setCaption(this.y>this.options.down.height?this.options.down.contentover:this.options.down.contentdown)},_reLayout:function(){this.hasVerticalScroll=!0,this._super()},resetPosition:function(a){if(this.pulldown){if(this.y>=this.options.down.height)return this.pulldownLoading(d,a||0),!0;!this.loading&&this.topPocket.classList.remove(e)}return this._super(a)},pulldownLoading:function(a,b){if("undefined"==typeof a&&(a=this.options.down.height),this.scrollTo(0,a,b,this.options.bounceEasing),!this.loading){this._initPulldownRefresh(),this._setCaption(this.options.down.contentrefresh),this.loading=!0,this.indicators.map(function(a){a.fade(0)});var c=this.options.down.callback;c&&c.call(this)}},endPulldownToRefresh:function(){var a=this;a.topPocket&&a.loading&&this.pulldown&&(a.scrollTo(0,0,a.options.bounceTime,a.options.bounceEasing),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(e)},350))},pullupLoading:function(a,b,c){b=b||0,this.scrollTo(b,this.maxScrollY,c,this.options.bounceEasing),this.loading||(this._initPullupRefresh(),this._setCaption(this.options.up.contentrefresh),this.indicators.map(function(a){a.fade(0)}),this.loading=!0,a=a||this.options.up.callback,a&&a.call(this))},endPullupToRefresh:function(a){var b=this;b.bottomPocket&&(b.loading=!1,a?(this.finished=!0,b._setCaption(b.options.up.contentnomore),b.wrapper.removeEventListener("scrollbottom",b)):(b._setCaption(b.options.up.contentdown),b.loading||b.bottomPocket.classList.remove(e)))},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+f,this.wrapper.removeEventListener("scrollbottom",this)},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(f),this._setCaption(this.options.up.contentdown),this.wrapper.addEventListener("scrollbottom",this)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1),this._super()}},a.PullRefresh));a.fn.pullRefresh=function(b){if(1===this.length){var c=this[0],d=null,e=c.getAttribute("data-pullrefresh");return e||"undefined"!=typeof b?(b=b||{},e?d=a.data[e]:(e=++a.uuid,a.data[e]=d=new g(c,b),c.setAttribute("data-pullrefresh",e)),b.down&&b.down.auto?d.pulldownLoading(b.down.autoY):b.up&&b.up.auto&&d.pullupLoading(),d):!1}}}(mui,window,document),function(a,b){var c="mui-slider",d="mui-slider-group",e="mui-slider-loop",f="mui-action-previous",g="mui-action-next",h="mui-slider-item",i="mui-active",j="."+h,k=".mui-slider-progress-bar",l=a.Slider=a.Scroll.extend({ +init:function(b,c){this._super(b,a.extend(!0,{fingers:1,interval:0,scrollY:!1,scrollX:!0,indicators:!1,scrollTime:1e3,startX:!1,slideTime:0,snap:j},c)),this.options.startX},_init:function(){this._reInit(),this.scroller&&(this.scrollerStyle=this.scroller.style,this.progressBar=this.wrapper.querySelector(k),this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style),this._super(),this._initTimer())},_triggerSlide:function(){var b=this;b.isInTransition=!1;b.currentPage;b.slideNumber=b._fixedSlideNumber(),b.loop&&(0===b.slideNumber?b.setTranslate(b.pages[1][0].x,0):b.slideNumber===b.itemLength-3&&b.setTranslate(b.pages[b.itemLength-2][0].x,0)),b.lastSlideNumber!=b.slideNumber&&(b.lastSlideNumber=b.slideNumber,b.lastPage=b.currentPage,a.trigger(b.wrapper,"slide",{slideNumber:b.slideNumber})),b._initTimer()},_handleSlide:function(b){var c=this;if(b.target===c.wrapper){var d=b.detail;d.slideNumber=d.slideNumber||0;for(var e=c.scroller.querySelectorAll(j),f=[],g=0,h=e.length;h>g;g++){var k=e[g];k.parentNode===c.scroller&&f.push(k)}var l=d.slideNumber;if(c.loop&&(l+=1),!c.wrapper.classList.contains("mui-segmented-control"))for(var g=0,h=f.length;h>g;g++){var k=f[g];k.parentNode===c.scroller&&(g===l?k.classList.add(i):k.classList.remove(i))}var m=c.wrapper.querySelector(".mui-slider-indicator");if(m){m.getAttribute("data-scroll")&&a(m).scroll().gotoPage(d.slideNumber);var n=m.querySelectorAll(".mui-indicator");if(n.length>0)for(var g=0,h=n.length;h>g;g++)n[g].classList[g===d.slideNumber?"add":"remove"](i);else{var o=m.querySelector(".mui-number span");if(o)o.innerText=d.slideNumber+1;else for(var p=m.querySelectorAll(".mui-control-item"),g=0,h=p.length;h>g;g++)p[g].classList[g===d.slideNumber?"add":"remove"](i)}}b.stopPropagation()}},_handleTabShow:function(a){var b=this;b.gotoItem(a.detail.tabNumber||0,b.options.slideTime)},_handleIndicatorTap:function(a){var b=this,c=a.target;(c.classList.contains(f)||c.classList.contains(g))&&(b[c.classList.contains(f)?"prevItem":"nextItem"](),a.stopPropagation())},_initEvent:function(b){var c=this;c._super(b);var d=b?"removeEventListener":"addEventListener";c.wrapper[d]("slide",this),c.wrapper[d](a.eventName("shown","tab"),this)},handleEvent:function(b){switch(this._super(b),b.type){case"slide":this._handleSlide(b);break;case a.eventName("shown","tab"):~this.snaps.indexOf(b.target)&&this._handleTabShow(b)}},_scrollend:function(a){this._super(a),this._triggerSlide(a)},_drag:function(a){this._super(a);var c=a.detail.direction;if("left"===c||"right"===c){var d=this.wrapper.getAttribute("data-slidershowTimer");d&&b.clearTimeout(d),a.stopPropagation()}},_initTimer:function(){var a=this,c=a.wrapper,d=a.options.interval,e=c.getAttribute("data-slidershowTimer");e&&b.clearTimeout(e),d&&(e=b.setTimeout(function(){c&&((c.offsetWidth||c.offsetHeight)&&a.nextItem(!0),a._initTimer())},d),c.setAttribute("data-slidershowTimer",e))},_fixedSlideNumber:function(a){a=a||this.currentPage;var b=a.pageX;return this.loop&&(b=0===a.pageX?this.itemLength-3:a.pageX===this.itemLength-1?0:a.pageX-1),b},_reLayout:function(){this.hasHorizontalScroll=!0,this.loop=this.scroller.classList.contains(e),this._super()},_getScroll:function(){var b=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));return b?b.x:0},_transitionEnd:function(b){b.target===this.scroller&&this.isInTransition&&(this._transitionTime(),this.isInTransition=!1,a.trigger(this.wrapper,"scrollend",this))},_flick:function(a){if(this.moved){var b=a.detail,c=b.direction;this._clearRequestAnimationFrame(),this.isInTransition=!0,"flick"===a.type?(b.deltaTime<200&&(this.x=this._getPage(this.slideNumber+("right"===c?-1:1),!0).x),this.resetPosition(this.options.bounceTime)):"dragend"!==a.type||b.flick||this.resetPosition(this.options.bounceTime),a.stopPropagation()}},_initSnap:function(){if(this.scrollerWidth=this.itemLength*this.scrollerWidth,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this._super(),this.currentPage.x)this.slideNumber=this._fixedSlideNumber(),this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?this.slideNumber:this.lastSlideNumber;else{var a=this.pages[this.loop?1:0];if(a=a||this.pages[0],!a)return;this.currentPage=a[0],this.slideNumber=0,this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?0:this.lastSlideNumber}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(-a,this.maxScrollX)},_getPage:function(a,b){return this.loop?a>this.itemLength-(b?2:3)?(a=1,time=0):(b?-1:0)>a?(a=this.itemLength-2,time=0):a+=1:(b||(a>this.itemLength-1?(a=0,time=0):0>a&&(a=this.itemLength-1,time=0)),a=Math.min(Math.max(0,a),this.itemLength-1)),this.pages[a][0]},_gotoItem:function(b,c){this.currentPage=this._getPage(b,!0),this.scrollTo(this.currentPage.x,0,c,this.options.scrollEasing),0===c&&a.trigger(this.wrapper,"scrollend",this)},setTranslate:function(a,b){this._super(a,b);var c=this.progressBar;c&&(this.progressBarStyle.webkitTransform=this._getTranslateStr(-a*(this.progressBarWidth/this.wrapperWidth),0))},resetPosition:function(a){return a=a||0,this.x>0?this.x=0:this.x<this.maxScrollX&&(this.x=this.maxScrollX),this.currentPage=this._nearestSnap(this.x),this.scrollTo(this.currentPage.x,0,a,this.options.scrollEasing),!0},gotoItem:function(a,b){this._gotoItem(a,"undefined"==typeof b?this.options.scrollTime:b)},nextItem:function(){this._gotoItem(this.slideNumber+1,this.options.scrollTime)},prevItem:function(){this._gotoItem(this.slideNumber-1,this.options.scrollTime)},getSlideNumber:function(){return this.slideNumber||0},_reInit:function(){for(var a=this.wrapper.querySelectorAll("."+d),b=0,c=a.length;c>b;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style,this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style)},refresh:function(b){b?(a.extend(this.options,b),this._super(),this._initTimer()):this._super()},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-slider")],this.wrapper.setAttribute("data-slider","")}});a.fn.slider=function(b){var d=null;return this.each(function(){var e=this;if(this.classList.contains(c)||(e=this.querySelector("."+c)),e&&e.querySelector(j)){var f=e.getAttribute("data-slider");f?(d=a.data[f],d&&b&&d.refresh(b)):(f=++a.uuid,a.data[f]=d=new l(e,b),e.setAttribute("data-slider",f))}}),d},a.ready(function(){a(".mui-slider").slider(),a(".mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control").scroll({scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})})}(mui,window),function(a,b){a.os.plus&&a.plusReady(function(){if(window.__NWin_Enable__!==!1){var c="mui-plus-pullrefresh",d="mui-visibility",e="mui-hidden",f="mui-block",g="mui-pull-caption",h="mui-pull-caption-down",i="mui-pull-caption-refresh",j="mui-pull-caption-nomore",k=a.Class.extend({init:function(a,b){this.element=a,this.options=b,this.wrapper=this.scroller=a,this._init(),this._initPulldownRefreshEvent()},_init:function(){var a=this;window.addEventListener("dragup",a),b.addEventListener("plusscrollbottom",a),a.scrollInterval=window.setInterval(function(){a.isScroll&&!a.loading&&window.pageYOffset+window.innerHeight+10>=b.documentElement.scrollHeight&&(a.isScroll=!1,a.bottomPocket&&a.pullupLoading())},100)},_initPulldownRefreshEvent:function(){var b=this;a.plusReady(function(){if("circle"==b.options.down.style)b.options.webview=plus.webview.currentWebview(),b.options.webview.setPullToRefresh({support:!0,color:b.options.down.color||"#2BD009",height:b.options.down.height||"50px",range:b.options.down.range||"100px",style:"circle",offset:b.options.down.offset||"0px"},function(){b.options.down.callback()});else if(b.topPocket&&b.options.webviewId){var a=plus.webview.getWebviewById(b.options.webviewId);if(!a)return;b.options.webview=a;var c=b.options.down,d=c.height;a.addEventListener("close",function(){var a=b.options.webviewId&&b.options.webviewId.replace(/\//g,"_");b.element.removeAttribute("data-pullrefresh-plus-"+a)}),a.addEventListener("dragBounce",function(d){switch(b.pulldown?b.pullPocket.classList.add(f):b._initPulldownRefresh(),d.status){case"beforeChangeOffset":b._setCaption(c.contentdown);break;case"afterChangeOffset":b._setCaption(c.contentover);break;case"dragEndAfterChangeOffset":a.evalJS("window.mui&&mui.options.pullRefresh.down.callback()"),b._setCaption(c.contentrefresh)}},!1),a.setBounce({position:{top:2*d+"px"},changeoffset:{top:d+"px"}})}})},handleEvent:function(a){var b=this;b.stopped||(b.isScroll=!1,("dragup"===a.type||"plusscrollbottom"===a.type)&&(b.isScroll=!0,setTimeout(function(){b.isScroll=!1},1e3)))}}).extend(a.extend({setStopped:function(a){this.stopped=!!a;var b=plus.webview.currentWebview();if(this.stopped)b.setStyle({bounce:"none"}),b.setBounce({position:{top:"none"}});else{var c=this.options.down.height;b.setStyle({bounce:"vertical"}),b.setBounce({position:{top:2*c+"px"},changeoffset:{top:c+"px"}})}},beginPulldown:function(){a.plusReady(function(){var a=plus.webview.currentWebview(),b=this;setTimeout(function(){"circle"==b.options.down.style?a.beginPullToRefresh():a.setBounce({offset:{top:this.options.down.height+"px"}})},15)}.bind(this))},pulldownLoading:function(){this.beginPulldown()},_pulldownLoading:function(){var b=this;a.plusReady(function(){var a=plus.webview.getWebviewById(b.options.webviewId);a&&a.setBounce({offset:{top:b.options.down.height+"px"}})})},endPulldown:function(){var a=plus.webview.currentWebview();a.parent()&&"circle"!==this.options.down.style?a.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify({webviewId:a.id})+"')._endPulldownToRefresh()"):a.endPullToRefresh()},endPulldownToRefresh:function(){this.endPulldown()},_endPulldownToRefresh:function(){var a=this;a.topPocket&&a.options.webview&&(a.options.webview.endPullToRefresh(),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(f)},350))},beginPullup:function(a){var b=this;b.isLoading||(b.isLoading=!0,b.pulldown!==!1?b._initPullupRefresh():this.pullPocket.classList.add(f),setTimeout(function(){b.pullLoading.classList.add(d),b.pullLoading.classList.remove(e),b.pullCaption.innerHTML="",b.pullCaption.className=g+" "+i,b.pullCaption.innerHTML=b.options.up.contentrefresh,a=a||b.options.up.callback,a&&a.call(b)},300))},pullupLoading:function(a){this.beginPullup(a)},endPullup:function(a){var c=this;c.pullLoading&&(c.pullLoading.classList.remove(d),c.pullLoading.classList.add(e),c.isLoading=!1,a?(c.finished=!0,c.pullCaption.className=g+" "+j,c.pullCaption.innerHTML=c.options.up.contentnomore,b.removeEventListener("plusscrollbottom",c),window.removeEventListener("dragup",c)):(c.pullCaption.className=g+" "+h,c.pullCaption.innerHTML=c.options.up.contentdown))},endPullupToRefresh:function(a){this.endPullup(a)},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+e,window.removeEventListener("dragup",this)},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(e),this.pullCaption.className=g+" "+h,this.pullCaption.innerHTML=this.options.up.contentdown,b.addEventListener("plusscrollbottom",this),window.addEventListener("dragup",this)},scrollTo:function(b,c,d){a.scrollTo(c,d)},scrollToBottom:function(c){a.scrollTo(b.documentElement.scrollHeight,c)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1)}},a.PullRefresh));a.fn.pullRefresh_native=function(d){var e;0===this.length?(e=b.createElement("div"),e.className="mui-content",b.body.appendChild(e)):e=this[0];var f=d;d=d||{},"string"==typeof d&&(d=a.parseJSON(d)),!d.webviewId&&(d.webviewId=plus.webview.currentWebview().id||plus.webview.currentWebview().getURL());var g=null,h=d.webviewId&&d.webviewId.replace(/\//g,"_"),i=e.getAttribute("data-pullrefresh-plus-"+h);return i||"undefined"!=typeof f?(i?g=a.data[i]:(i=++a.uuid,e.setAttribute("data-pullrefresh-plus-"+h,i),b.body.classList.add(c),a.data[i]=g=new k(e,d)),d.down&&d.down.auto?g.beginPulldown():d.up&&d.up.auto&&g.beginPullup(),g):!1}}})}(mui,document),function(a,b,c,d){var e="mui-off-canvas-left",f="mui-off-canvas-right",g="mui-off-canvas-backdrop",h="mui-off-canvas-wrap",i="mui-slide-in",j="mui-active",k="mui-transitioning",l=".mui-inner-wrap",m=a.Class.extend({init:function(b,d){this.wrapper=this.element=b,this.scroller=this.wrapper.querySelector(l),this.classList=this.wrapper.classList,this.scroller&&(this.options=a.extend(!0,{dragThresholdX:10,scale:.8,opacity:.1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/}},d),c.body.classList.add("mui-fullscreen"),this.refresh(),this.initEvent())},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},refresh:function(a){this.slideIn=this.classList.contains(i),this.scalable=this.classList.contains("mui-scalable")&&!this.slideIn,this.scroller=this.wrapper.querySelector(l),this.offCanvasLefts=this.wrapper.querySelectorAll("."+e),this.offCanvasRights=this.wrapper.querySelectorAll("."+f),a?a.classList.contains(e)?this.offCanvasLeft=a:a.classList.contains(f)&&(this.offCanvasRight=a):(this.offCanvasRight=this.wrapper.querySelector("."+f),this.offCanvasLeft=this.wrapper.querySelector("."+e)),this.offCanvasRightWidth=this.offCanvasLeftWidth=0,this.offCanvasLeftSlideIn=this.offCanvasRightSlideIn=!1,this.offCanvasRight&&(this.offCanvasRightWidth=this.offCanvasRight.offsetWidth,this.offCanvasRightSlideIn=this.slideIn&&this.offCanvasRight.parentNode===this.wrapper),this.offCanvasLeft&&(this.offCanvasLeftWidth=this.offCanvasLeft.offsetWidth,this.offCanvasLeftSlideIn=this.slideIn&&this.offCanvasLeft.parentNode===this.wrapper),this.backdrop=this.scroller.querySelector("."+g),this.options.dragThresholdX=this.options.dragThresholdX||10,this.visible=!1,this.startX=null,this.lastX=null,this.offsetX=null,this.lastTranslateX=null},handleEvent:function(b){switch(b.type){case a.EVENT_START:b.target&&!this._preventDefaultException(b.target,this.options.preventDefaultException)&&b.preventDefault();break;case"webkitTransitionEnd":b.target===this.scroller&&this._dispatchEvent();break;case"drag":var c=b.detail;this.startX?this.lastX=c.center.x:(this.startX=c.center.x,this.lastX=this.startX),!this.isDragging&&Math.abs(this.lastX-this.startX)>this.options.dragThresholdX&&("left"===c.direction||"right"===c.direction)&&(this.slideIn?(this.scroller=this.wrapper.querySelector(l),this.classList.contains(j)?this.offCanvasRight&&this.offCanvasRight.classList.contains(j)?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):"left"===c.direction&&this.offCanvasRight?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction&&this.offCanvasLeft?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):this.scroller=null):this.classList.contains(j)?"left"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth),this.offCanvas&&this.scroller&&(this.startX=this.lastX,this.isDragging=!0,a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=c.direction,this.offCanvas.classList.remove(k),this.scroller.classList.remove(k),this.offsetX=this.getTranslateX(),this._initOffCanvasVisible())),this.isDragging&&(this.updateTranslate(this.offsetX+(this.lastX-this.startX)),c.gesture.preventDefault(),b.stopPropagation());break;case"dragend":if(this.isDragging){var c=b.detail,d=c.direction;this.isDragging=!1,this.offCanvas.classList.add(k),this.scroller.classList.add(k);var e=0,f=this.getTranslateX();if(this.slideIn){if(e=f>=0?this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0:this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0,"right"===d&&0>=e&&(e>=-.5||c.swipe)?this.openPercentage(100):"right"===d&&e>0&&(e>=.5||c.swipe)?this.openPercentage(0):"right"===d&&-.5>=e?this.openPercentage(0):"right"===d&&e>0&&.5>=e?this.openPercentage(-100):"left"===d&&e>=0&&(.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&0>e&&(-.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&e>=.5?this.openPercentage(0):"left"===d&&e>=-.5&&0>e?this.openPercentage(100):this.openPercentage(0),1===e||-1===e||0===e)return void this._dispatchEvent()}else{if(e=f>=0?this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0:this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0,0===e)return this.openPercentage(0),void this._dispatchEvent();"right"===d&&e>=0&&(e>=.5||c.swipe)?this.openPercentage(100):"right"===d&&0>e&&(e>-.5||c.swipe)?this.openPercentage(0):"right"===d&&e>0&&.5>e?this.openPercentage(0):"right"===d&&.5>e?this.openPercentage(-100):"left"===d&&0>=e&&(-.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&e>0&&(.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&0>e&&e>=-.5?this.openPercentage(0):"left"===d&&e>.5?this.openPercentage(100):this.openPercentage(0),(1===e||-1===e)&&this._dispatchEvent()}}}},_dispatchEvent:function(){this.classList.contains(j)?a.trigger(this.wrapper,"shown",this):a.trigger(this.wrapper,"hidden",this)},_initOffCanvasVisible:function(){this.visible||(this.visible=!0,this.offCanvasLeft&&(this.offCanvasLeft.style.visibility="visible"),this.offCanvasRight&&(this.offCanvasRight.style.visibility="visible"))},initEvent:function(){var b=this;b.backdrop&&b.backdrop.addEventListener("tap",function(a){b.close(),a.detail.gesture.preventDefault()}),this.classList.contains("mui-draggable")&&(this.wrapper.addEventListener(a.EVENT_START,this),this.wrapper.addEventListener("drag",this),this.wrapper.addEventListener("dragend",this)),this.wrapper.addEventListener("webkitTransitionEnd",this)},openPercentage:function(a){var b=a/100;this.slideIn?(this.offCanvasLeft&&a>=0?(b=0===b?-1:0,this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==a?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(b=0===b?1:0,this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==a?"add":"remove"](j)),this.classList[0!==a?"add":"remove"](j)):(this.offCanvasLeft&&a>=0?(this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==b?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==b?"add":"remove"](j)),this.classList[0!==b?"add":"remove"](j))},updateTranslate:function(b){if(b!==this.lastTranslateX){if(this.slideIn){if(this.offCanvas.classList.contains(f)){if(0>b)return void this.setTranslateX(0);if(b>this.offCanvasRightWidth)return void this.setTranslateX(this.offCanvasRightWidth)}else{if(b>0)return void this.setTranslateX(0);if(b<-this.offCanvasLeftWidth)return void this.setTranslateX(-this.offCanvasLeftWidth)}this.setTranslateX(b)}else{if(!this.offCanvasLeft&&b>0||!this.offCanvasRight&&0>b)return void this.setTranslateX(0);if(this.leftShowing&&b>this.offCanvasLeftWidth)return void this.setTranslateX(this.offCanvasLeftWidth);if(this.rightShowing&&b<-this.offCanvasRightWidth)return void this.setTranslateX(-this.offCanvasRightWidth);this.setTranslateX(b),b>=0?(this.leftShowing=!0,this.rightShowing=!1,b>0&&(this.offCanvasLeft&&a.each(this.offCanvasLefts,function(a,b){b===this.offCanvasLeft?this.offCanvasLeft.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasRight&&(this.offCanvasRight.style.zIndex=-1))):(this.rightShowing=!0,this.leftShowing=!1,this.offCanvasRight&&a.each(this.offCanvasRights,function(a,b){b===this.offCanvasRight?b.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasLeft&&(this.offCanvasLeft.style.zIndex=-1))}this.lastTranslateX=b}},setTranslateX:a.animationFrame(function(a){if(this.scroller)if(this.scalable&&this.offCanvas.parentNode===this.wrapper){var b=Math.abs(a)/this.offCanvasWidth,c=1-(1-this.options.scale)*b,d=this.options.scale+(1-this.options.scale)*b,f=(1-(1-this.options.opacity)*b,this.options.opacity+(1-this.options.opacity)*b);this.offCanvas.classList.contains(e)?(this.offCanvas.style.webkitTransformOrigin="-100%",this.scroller.style.webkitTransformOrigin="left"):(this.offCanvas.style.webkitTransformOrigin="200%",this.scroller.style.webkitTransformOrigin="right"),this.offCanvas.style.opacity=f,this.offCanvas.style.webkitTransform="translate3d(0,0,0) scale("+d+")",this.scroller.style.webkitTransform="translate3d("+a+"px,0,0) scale("+c+")"}else this.slideIn?this.offCanvas.style.webkitTransform="translate3d("+a+"px,0,0)":this.scroller.style.webkitTransform="translate3d("+a+"px,0,0)"}),getTranslateX:function(){if(this.offCanvas){var b=this.slideIn?this.offCanvas:this.scroller,c=a.parseTranslateMatrix(a.getStyles(b,"webkitTransform"));return c&&c.x||0}return 0},isShown:function(a){var b=!1;if(this.slideIn)b="left"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+e+"."+j):"right"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+f+"."+j):this.classList.contains(j)&&(this.wrapper.querySelector("."+e+"."+j)||this.wrapper.querySelector("."+f+"."+j));else{var c=this.getTranslateX();b="right"===a?this.classList.contains(j)&&0>c:"left"===a?this.classList.contains(j)&&c>0:this.classList.contains(j)&&0!==c}return b},close:function(){this._initOffCanvasVisible(),this.offCanvas=this.wrapper.querySelector("."+f+"."+j)||this.wrapper.querySelector("."+e+"."+j),this.offCanvasWidth=this.offCanvas.offsetWidth,this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage(0))},show:function(a){return this._initOffCanvasVisible(),this.isShown(a)?!1:(a||(a=this.wrapper.querySelector("."+f)?"right":"left"),"right"===a?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth),this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage("left"===a?100:-100)),!0)},toggle:function(a){var b=a;a&&a.classList&&(b=a.classList.contains(e)?"left":"right",this.refresh(a)),this.show(b)||this.close()}}),n=function(a){if(parentNode=a.parentNode,parentNode){if(parentNode.classList.contains(h))return parentNode;if(parentNode=parentNode.parentNode,parentNode.classList.contains(h))return parentNode}},o=function(b,d){if("A"===d.tagName&&d.hash){var e=c.getElementById(d.hash.replace("#",""));if(e){var f=n(e);if(f)return a.targets._container=f,e}}return!1};a.registerTarget({name:d,index:60,handle:o,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){if(a.targets.offcanvas)for(var d=b.target;d&&d!==c;d=d.parentNode)if("A"===d.tagName&&d.hash&&d.hash==="#"+a.targets.offcanvas.id){b.detail&&b.detail.gesture&&b.detail.gesture.preventDefault(),a(a.targets._container).offCanvas().toggle(a.targets.offcanvas),a.targets.offcanvas=a.targets._container=null;break}}),a.fn.offCanvas=function(b){var c=[];return this.each(function(){var d=null,e=this;e.classList.contains(h)||(e=n(e));var f=e.getAttribute("data-offCanvas");f?d=a.data[f]:(f=++a.uuid,a.data[f]=d=new m(e,b),e.setAttribute("data-offCanvas",f)),("show"===b||"close"===b||"toggle"===b)&&d.toggle(),c.push(d)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-off-canvas-wrap").offCanvas()})}(mui,window,document,"offcanvas"),function(a,b){var c="mui-action",d=function(a,b){var d=b.className||"";return"string"!=typeof d&&(d=""),d&&~d.indexOf(c)?(b.classList.contains("mui-action-back")&&a.preventDefault(),b):!1};a.registerTarget({name:b,index:50,handle:d,target:!1,isContinue:!0})}(mui,"action"),function(a,b,c,d){var e="mui-modal",f=function(a,b){if("A"===b.tagName&&b.hash){var d=c.getElementById(b.hash.replace("#",""));if(d&&d.classList.contains(e))return d}return!1};a.registerTarget({name:d,index:50,handle:f,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){a.targets.modal&&(b.detail.gesture.preventDefault(),a.targets.modal.classList.toggle("mui-active"))})}(mui,window,document,"modal"),function(a,b,c,d){var e="mui-popover",f="mui-popover-arrow",g="mui-popover-action",h="mui-backdrop",i="mui-bar-popover",j="mui-bar-backdrop",k="mui-backdrop-action",l="mui-active",m="mui-bottom",n=function(b,d){if("A"===d.tagName&&d.hash){if(a.targets._popover=c.getElementById(d.hash.replace("#","")),a.targets._popover&&a.targets._popover.classList.contains(e))return d;a.targets._popover=null}return!1};a.registerTarget({name:d,index:60,handle:n,target:!1,isReset:!1,isContinue:!0});var o,p=function(b){this.removeEventListener("webkitTransitionEnd",p),this.addEventListener(a.EVENT_MOVE,a.preventDefault),a.trigger(this,"shown",this)},q=function(b){u(this,"none"),this.removeEventListener("webkitTransitionEnd",q),this.removeEventListener(a.EVENT_MOVE,a.preventDefault),a.trigger(this,"hidden",this)},r=function(){var b=c.createElement("div");return b.classList.add(h),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("tap",function(b){var c=a.targets._popover;c&&(c.addEventListener("webkitTransitionEnd",q),c.classList.remove(l),s(c))}),b}(),s=function(b){r.setAttribute("style","opacity:0"),a.targets.popover=a.targets._popover=null,o=a.later(function(){!b.classList.contains(l)&&r.parentNode&&r.parentNode===c.body&&c.body.removeChild(r)},350)};b.addEventListener("tap",function(b){if(a.targets.popover){for(var d=!1,e=b.target;e&&e!==c;e=e.parentNode)e===a.targets.popover&&(d=!0);d&&(b.detail.gesture.preventDefault(),t(a.targets._popover,a.targets.popover))}});var t=function(a,b,d){if(!("show"===d&&a.classList.contains(l)||"hide"===d&&!a.classList.contains(l))){o&&o.cancel(),a.removeEventListener("webkitTransitionEnd",p),a.removeEventListener("webkitTransitionEnd",q),r.classList.remove(j),r.classList.remove(k);var e=c.querySelector(".mui-popover.mui-active");if(e&&(e.addEventListener("webkitTransitionEnd",q),e.classList.remove(l),a===e))return void s(e);var f=!1;(a.classList.contains(i)||a.classList.contains(g))&&(a.classList.contains(g)?(f=!0,r.classList.add(k)):r.classList.add(j)),u(a,"block"),a.offsetHeight,a.classList.add(l),r.setAttribute("style",""),c.body.appendChild(r),v(a,b,f),r.classList.add(l),a.addEventListener("webkitTransitionEnd",p)}},u=function(a,b,c,d){var e=a.style;"undefined"!=typeof b&&(e.display=b),"undefined"!=typeof c&&(e.top=c+"px"),"undefined"!=typeof d&&(e.left=d+"px")},v=function(d,e,h){if(d&&e){if(h)return void u(d,"block");var i=b.innerWidth,j=b.innerHeight,k=d.offsetWidth,l=d.offsetHeight,n=e.offsetWidth,o=e.offsetHeight,p=a.offset(e),q=d.querySelector("."+f);q||(q=c.createElement("div"),q.className=f,d.appendChild(q));var r=q&&q.offsetWidth/2||0,s=0,t=0,v=0,w=0,x=d.classList.contains(g)?0:5,y="top";l+r<p.top-b.pageYOffset?s=p.top-l-r:l+r<j-(p.top-b.pageYOffset)-o?(y="bottom",s=p.top+o+r):(y="middle",s=Math.max((j-l)/2+b.pageYOffset,0),t=Math.max((i-k)/2+b.pageXOffset,0)),"top"===y||"bottom"===y?(t=n/2+p.left-k/2,v=t,x>t&&(t=x),t+k>i&&(t=i-k-x),q&&("top"===y?q.classList.add(m):q.classList.remove(m),v-=t,w=k/2-r/2+v,w=Math.max(Math.min(w,k-2*r-6),6),q.setAttribute("style","left:"+w+"px"))):"middle"===y&&q.setAttribute("style","display:none"),u(d,"block",s,t)}};a.createMask=function(b){var d=c.createElement("div");d.classList.add(h),d.addEventListener(a.EVENT_MOVE,a.preventDefault),d.addEventListener("tap",function(){e.close()});var e=[d];return e._show=!1,e.show=function(){return e._show=!0,d.setAttribute("style","opacity:1"),c.body.appendChild(d),e},e._remove=function(){return e._show&&(e._show=!1,d.setAttribute("style","opacity:0"),a.later(function(){var a=c.body;d.parentNode===a&&a.removeChild(d)},350)),e},e.close=function(){b?b()!==!1&&e._remove():e._remove()},e},a.fn.popover=function(){var b=arguments;this.each(function(){a.targets._popover=this,("show"===b[0]||"hide"===b[0]||"toggle"===b[0])&&t(this,b[1],b[0])})}}(mui,window,document,"popover"),function(a,b,c,d,e){var f="mui-control-item",g="mui-segmented-control",h="mui-segmented-control-vertical",i="mui-control-content",j="mui-bar-tab",k="mui-tab-item",l=function(a,b){return b.classList&&(b.classList.contains(f)||b.classList.contains(k))?(b.parentNode&&b.parentNode.classList&&b.parentNode.classList.contains(h)||a.preventDefault(),b):!1};a.registerTarget({name:d,index:80,handle:l,target:!1}),b.addEventListener("tap",function(b){var e=a.targets.tab;if(e){for(var h,l,m,n="mui-active",o="."+n,p=e.parentNode;p&&p!==c;p=p.parentNode){if(p.classList.contains(g)){h=p.querySelector(o+"."+f);break}p.classList.contains(j)&&(h=p.querySelector(o+"."+k))}h&&h.classList.remove(n);var q=e===h;if(e&&e.classList.add(n),e.hash&&(m=c.getElementById(e.hash.replace("#","")))){if(!m.classList.contains(i))return void e.classList[q?"remove":"add"](n);if(!q){var r=m.parentNode;l=r.querySelectorAll("."+i+o);for(var s=0;s<l.length;s++){var t=l[s];t.parentNode===r&&t.classList.remove(n)}m.classList.add(n);for(var u=[],v=r.querySelectorAll("."+i),s=0;s<v.length;s++)v[s].parentNode===r&&u.push(v[s]);a.trigger(m,a.eventName("shown",d),{tabNumber:Array.prototype.indexOf.call(u,m)}),b.detail&&b.detail.gesture.preventDefault()}}}})}(mui,window,document,"tab"),function(a,b,c){var d="mui-switch",e="mui-switch-handle",f="mui-active",g="mui-dragging",h="mui-disabled",i="."+e,j=function(a,b){return b.classList&&b.classList.contains(d)?b:!1};a.registerTarget({name:c,index:100,handle:j,target:!1});var k=function(a){this.element=a,this.classList=this.element.classList,this.handle=this.element.querySelector(i),this.init(),this.initEvent()};k.prototype.init=function(){this.toggleWidth=this.element.offsetWidth,this.handleWidth=this.handle.offsetWidth,this.handleX=this.toggleWidth-this.handleWidth-3},k.prototype.initEvent=function(){this.element.addEventListener(a.EVENT_START,this),this.element.addEventListener("drag",this),this.element.addEventListener("swiperight",this),this.element.addEventListener(a.EVENT_END,this),this.element.addEventListener(a.EVENT_CANCEL,this)},k.prototype.handleEvent=function(b){if(!this.classList.contains(h))switch(b.type){case a.EVENT_START:this.start(b);break;case"drag":this.drag(b);break;case"swiperight":this.swiperight();break;case a.EVENT_END:case a.EVENT_CANCEL:this.end(b)}},k.prototype.start=function(a){this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration=".2s",this.classList.add(g),(0===this.toggleWidth||0===this.handleWidth)&&this.init()},k.prototype.drag=function(a){var b=a.detail;this.isDragging||("left"===b.direction||"right"===b.direction)&&(this.isDragging=!0,this.lastChanged=void 0,this.initialState=this.classList.contains(f)),this.isDragging&&(this.setTranslateX(b.deltaX),a.stopPropagation(),b.gesture.preventDefault())},k.prototype.swiperight=function(a){this.isDragging&&a.stopPropagation()},k.prototype.end=function(b){this.classList.remove(g),this.isDragging?(this.isDragging=!1,b.stopPropagation(),a.trigger(this.element,"toggle",{isActive:this.classList.contains(f)})):this.toggle()},k.prototype.toggle=function(b){var c=this.classList;b===!1?this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration="0s":this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration=".2s",c.contains(f)?(c.remove(f),this.handle.style.webkitTransform="translate(0,0)"):(c.add(f),this.handle.style.webkitTransform="translate("+this.handleX+"px,0)"),a.trigger(this.element,"toggle",{isActive:this.classList.contains(f)})},k.prototype.setTranslateX=a.animationFrame(function(a){if(this.isDragging){var b=!1;(this.initialState&&-a>this.handleX/2||!this.initialState&&a>this.handleX/2)&&(b=!0),this.lastChanged!==b&&(b?(this.handle.style.webkitTransform="translate("+(this.initialState?0:this.handleX)+"px,0)", +this.classList[this.initialState?"remove":"add"](f)):(this.handle.style.webkitTransform="translate("+(this.initialState?this.handleX:0)+"px,0)",this.classList[this.initialState?"add":"remove"](f)),this.lastChanged=b)}}),a.fn["switch"]=function(b){var c=[];return this.each(function(){var b=null,d=this.getAttribute("data-switch");d?b=a.data[d]:(d=++a.uuid,a.data[d]=new k(this),this.setAttribute("data-switch",d)),c.push(b)}),c.length>1?c:c[0]},a.ready(function(){a("."+d)["switch"]()})}(mui,window,"toggle"),function(a,b,c){function d(a,b){var c=b?"removeEventListener":"addEventListener";a[c]("drag",F),a[c]("dragend",F),a[c]("swiperight",F),a[c]("swipeleft",F),a[c]("flick",F)}var e,f,g="mui-active",h="mui-selected",i="mui-grid-view",j="mui-table-view-radio",k="mui-table-view-cell",l="mui-collapse-content",m="mui-disabled",n="mui-switch",o="mui-btn",p="mui-slider-handle",q="mui-slider-left",r="mui-slider-right",s="mui-transitioning",t="."+p,u="."+q,v="."+r,w="."+h,x="."+o,y=.8,z=isOpened=openedActions=progress=!1,A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,B=translateX=lastTranslateX=sliderActionLeftWidth=sliderActionRightWidth=0,C=function(a){a?f?f.classList.add(g):e&&e.classList.add(g):(B&&B.cancel(),f?f.classList.remove(g):e&&e.classList.remove(g))},D=function(){if(translateX!==lastTranslateX){if(buttonsRight&&buttonsRight.length>0){progress=translateX/sliderActionRightWidth,translateX<-sliderActionRightWidth&&(translateX=-sliderActionRightWidth-Math.pow(-translateX-sliderActionRightWidth,y));for(var a=0,b=buttonsRight.length;b>a;a++){var c=buttonsRight[a];"undefined"==typeof c._buttonOffset&&(c._buttonOffset=c.offsetLeft),buttonOffset=c._buttonOffset,E(c,translateX-buttonOffset*(1+Math.max(progress,-1)))}}if(buttonsLeft&&buttonsLeft.length>0){progress=translateX/sliderActionLeftWidth,translateX>sliderActionLeftWidth&&(translateX=sliderActionLeftWidth+Math.pow(translateX-sliderActionLeftWidth,y));for(var a=0,b=buttonsLeft.length;b>a;a++){var d=buttonsLeft[a];"undefined"==typeof d._buttonOffset&&(d._buttonOffset=sliderActionLeftWidth-d.offsetLeft-d.offsetWidth),buttonOffset=d._buttonOffset,buttonsLeft.length>1&&(d.style.zIndex=buttonsLeft.length-a),E(d,translateX+buttonOffset*(1-Math.min(progress,1)))}}E(A,translateX),lastTranslateX=translateX}sliderRequestAnimationFrame=requestAnimationFrame(function(){D()})},E=function(a,b){a&&(a.style.webkitTransform="translate("+b+"px,0)")};b.addEventListener(a.EVENT_START,function(b){e&&C(!1),e=f=!1,z=isOpened=openedActions=!1;for(var g=b.target,h=!1;g&&g!==c;g=g.parentNode)if(g.classList){var p=g.classList;if(("INPUT"===g.tagName&&"radio"!==g.type&&"checkbox"!==g.type||"BUTTON"===g.tagName||p.contains(n)||p.contains(o)||p.contains(m))&&(h=!0),p.contains(l))break;if(p.contains(k)){e=g;var q=e.parentNode.querySelector(w);if(!e.parentNode.classList.contains(j)&&q&&q!==e)return a.swipeoutClose(q),void(e=h=!1);if(!e.parentNode.classList.contains(i)){var r=e.querySelector("a");r&&r.parentNode===e&&(f=r)}var s=e.querySelector(t);s&&(d(e),b.stopPropagation()),h||(s?(B&&B.cancel(),B=a.later(function(){C(!0)},100)):C(!0));break}}}),b.addEventListener(a.EVENT_MOVE,function(a){C(!1)});var F={handleEvent:function(a){switch(a.type){case"drag":this.drag(a);break;case"dragend":this.dragend(a);break;case"flick":this.flick(a);break;case"swiperight":this.swiperight(a);break;case"swipeleft":this.swipeleft(a)}},drag:function(a){if(e){z||(A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,A=e.querySelector(t),A&&(sliderActionLeft=e.querySelector(u),sliderActionRight=e.querySelector(v),sliderActionLeft&&(sliderActionLeftWidth=sliderActionLeft.offsetWidth,buttonsLeft=sliderActionLeft.querySelectorAll(x)),sliderActionRight&&(sliderActionRightWidth=sliderActionRight.offsetWidth,buttonsRight=sliderActionRight.querySelectorAll(x)),e.classList.remove(s),isOpened=e.classList.contains(h),isOpened&&(openedActions=e.querySelector(u+w)?"left":"right")));var b=a.detail,c=b.direction,d=b.angle;if("left"===c&&(d>150||-150>d)?(buttonsRight||buttonsLeft&&isOpened)&&(z=!0):"right"===c&&d>-30&&30>d&&(buttonsLeft||buttonsRight&&isOpened)&&(z=!0),z){a.stopPropagation(),a.detail.gesture.preventDefault();var f=a.detail.deltaX;if(isOpened&&("right"===openedActions?f-=sliderActionRightWidth:f+=sliderActionLeftWidth),f>0&&!buttonsLeft||0>f&&!buttonsRight){if(!isOpened)return;f=0}0>f?sliderDirection="toLeft":f>0?sliderDirection="toRight":sliderDirection||(sliderDirection="toLeft"),sliderRequestAnimationFrame||D(),translateX=f}}},flick:function(a){z&&a.stopPropagation()},swipeleft:function(a){z&&a.stopPropagation()},swiperight:function(a){z&&a.stopPropagation()},dragend:function(b){if(z){b.stopPropagation(),sliderRequestAnimationFrame&&(cancelAnimationFrame(sliderRequestAnimationFrame),sliderRequestAnimationFrame=null);var c=b.detail;z=!1;var d="close",f="toLeft"===sliderDirection?sliderActionRightWidth:sliderActionLeftWidth,g=c.swipe||Math.abs(translateX)>f/2;g&&(isOpened?"left"===c.direction&&"right"===openedActions?d="open":"right"===c.direction&&"left"===openedActions&&(d="open"):d="open"),e.classList.add(s);var i;if("open"===d){var j="toLeft"===sliderDirection?-f:f;if(E(A,j),i="toLeft"===sliderDirection?buttonsRight:buttonsLeft,"undefined"!=typeof i){for(var k=null,l=0;l<i.length;l++)k=i[l],E(k,j);k.parentNode.classList.add(h),e.classList.add(h),isOpened||a.trigger(e,"toLeft"===sliderDirection?"slideleft":"slideright")}}else E(A,0),sliderActionLeft&&sliderActionLeft.classList.remove(h),sliderActionRight&&sliderActionRight.classList.remove(h),e.classList.remove(h);var m;if(buttonsLeft&&buttonsLeft.length>0&&buttonsLeft!==i)for(var l=0,n=buttonsLeft.length;n>l;l++){var o=buttonsLeft[l];m=o._buttonOffset,"undefined"==typeof m&&(o._buttonOffset=sliderActionLeftWidth-o.offsetLeft-o.offsetWidth),E(o,m)}if(buttonsRight&&buttonsRight.length>0&&buttonsRight!==i)for(var l=0,n=buttonsRight.length;n>l;l++){var p=buttonsRight[l];m=p._buttonOffset,"undefined"==typeof m&&(p._buttonOffset=p.offsetLeft),E(p,-m)}}}};a.swipeoutOpen=function(b,c){if(b){var d=b.classList;if(!d.contains(h)){c||(c=b.querySelector(v)?"right":"left");var e=b.querySelector(a.classSelector(".slider-"+c));if(e){e.classList.add(h),d.add(h),d.remove(s);for(var f,g=e.querySelectorAll(x),i=e.offsetWidth,j="right"===c?-i:i,k=g.length,l=0;k>l;l++)f=g[l],"right"===c?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft);d.add(s);for(var l=0;k>l;l++)E(g[l],j);E(b.querySelector(t),j)}}}},a.swipeoutClose=function(b){if(b){var c=b.classList;if(c.contains(h)){var d=b.querySelector(v+w)?"right":"left",e=b.querySelector(a.classSelector(".slider-"+d));if(e){e.classList.remove(h),c.remove(h),c.add(s);var f,g=e.querySelectorAll(x),i=e.offsetWidth,j=g.length;E(b.querySelector(t),0);for(var k=0;j>k;k++)f=g[k],"right"===d?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft)}}}},b.addEventListener(a.EVENT_END,function(a){e&&(C(!1),A&&d(e,!0))}),b.addEventListener(a.EVENT_CANCEL,function(a){e&&(C(!1),A&&d(e,!0))});var G=function(b){var c=b.target&&b.target.type||"";if("radio"!==c&&"checkbox"!==c){var d=e.classList;if(d.contains("mui-radio")){var f=e.querySelector("input[type=radio]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}else if(d.contains("mui-checkbox")){var f=e.querySelector("input[type=checkbox]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}}};b.addEventListener(a.EVENT_CLICK,function(a){e&&e.classList.contains("mui-collapse")&&a.preventDefault()}),b.addEventListener("doubletap",function(a){e&&G(a)});var H=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;b.addEventListener("tap",function(b){if(e){var c=!1,d=e.classList,f=e.parentNode;if(f&&f.classList.contains(j)){if(d.contains(h))return;var i=f.querySelector("li"+w);return i&&i.classList.remove(h),d.add(h),void a.trigger(e,"selected",{el:e})}if(d.contains("mui-collapse")&&!e.parentNode.classList.contains("mui-unfold")){if(H.test(b.target.tagName)||b.detail.gesture.preventDefault(),!d.contains(g)){var k=e.parentNode.querySelector(".mui-collapse.mui-active");k&&k.classList.remove(g),c=!0}d.toggle(g),c&&a.trigger(e,"expand")}else G(b)}})}(mui,window,document),function(a,b){a.alert=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e="确定"):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.alert(c,f,d,e)})}else b.alert(c)}}(mui,window),function(a,b){a.confirm=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e=null):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.confirm(c,f,d,e)})}else f(b.confirm(c)?{index:0}:{index:1})}}(mui,window),function(a,b){a.prompt=function(c,d,e,f,g){if(a.os.plus){if("undefined"==typeof message)return;"function"==typeof d?(g=d,d=null,e=null,f=null):"function"==typeof e?(g=e,e=null,f=null):"function"==typeof f&&(g=f,f=null),a.plusReady(function(){plus.nativeUI.prompt(c,g,e,d,f)})}else{var h=b.prompt(c);g(h?{index:0,value:h}:{index:1,value:""})}}}(mui,window),function(a,b){var c="mui-active";a.toast=function(b,d){var e={"long":3500,"short":2e3};if(d=a.extend({duration:"short"},d||{}),!a.os.plus||"div"===d.type){"number"==typeof d.duration?duration=d.duration>0?d.duration:e["short"]:duration=e[d.duration],duration||(duration=e["short"]);var f=document.createElement("div");return f.classList.add("mui-toast-container"),f.innerHTML='<div class="mui-toast-message">'+b+"</div>",f.addEventListener("webkitTransitionEnd",function(){f.classList.contains(c)||(f.parentNode.removeChild(f),f=null)}),f.addEventListener("click",function(){f.parentNode.removeChild(f),f=null}),document.body.appendChild(f),f.offsetHeight,f.classList.add(c),setTimeout(function(){f&&f.classList.remove(c)},duration),{isVisible:function(){return!!f}}}a.plusReady(function(){plus.nativeUI.toast(b,{verticalAlign:"bottom",duration:d.duration})})}}(mui,window),function(a,b,c){var d="mui-popup",e="mui-popup-backdrop",f="mui-popup-in",g="mui-popup-out",h="mui-popup-inner",i="mui-popup-title",j="mui-popup-text",k="mui-popup-input",l="mui-popup-buttons",m="mui-popup-button",n="mui-popup-button-bold",e="mui-popup-backdrop",o="mui-active",p=[],q=function(){var b=c.createElement("div");return b.classList.add(e),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("webkitTransitionEnd",function(){this.classList.contains(o)||b.parentNode&&b.parentNode.removeChild(b)}),b}(),r=function(a){return'<div class="'+k+'"><input type="text" autofocus placeholder="'+(a||"")+'"/></div>'},s=function(a,b,c){return'<div class="'+h+'"><div class="'+i+'">'+b+'</div><div class="'+j+'">'+a.replace(/\r\n/g,"<br/>").replace(/\n/g,"<br/>")+"</div>"+(c||"")+"</div>"},t=function(a){for(var b=a.length,c=[],d=0;b>d;d++)c.push('<span class="'+m+(d===b-1?" "+n:"")+'">'+a[d]+"</span>");return'<div class="'+l+'">'+c.join("")+"</div>"},u=function(b,e){var h=c.createElement("div");h.className=d,h.innerHTML=b;var i=function(){h.parentNode&&h.parentNode.removeChild(h),h=null};h.addEventListener(a.EVENT_MOVE,a.preventDefault),h.addEventListener("webkitTransitionEnd",function(a){h&&a.target===h&&h.classList.contains(g)&&i()}),h.style.display="block",c.body.appendChild(h),h.offsetHeight,h.classList.add(f),q.classList.contains(o)||(q.style.display="block",c.body.appendChild(q),q.offsetHeight,q.classList.add(o));var j=a.qsa("."+m,h),l=h.querySelector("."+k+" input"),n={element:h,close:function(a,b){if(h){var c=e&&e({index:a||0,value:l&&l.value||""});if(c===!1)return;b!==!1?(h.classList.remove(f),h.classList.add(g)):i(),p.pop(),p.length?p[p.length-1].show(b):q.classList.remove(o)}}},r=function(a){n.close(j.indexOf(a.target))};return a(h).on("tap","."+m,r),p.length&&p[p.length-1].hide(),p.push({close:n.close,show:function(a){h.style.display="block",h.offsetHeight,h.classList.add(f)},hide:function(){h.style.display="none",h.classList.remove(f)}}),n},v=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.alert(b,e,c||"提示",d||"确定"):u(s(b,c||"提示")+t([d||"确定"]),e)):void 0},w=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.confirm(b,e,c,d||["取消","确认"]):u(s(b,c||"提示")+t(d||["取消","确认"]),e)):void 0},x=function(b,c,d,e,f,g){return"undefined"!=typeof b?("function"==typeof c?(f=c,g=d,c=null,d=null,e=null):"function"==typeof d?(f=d,g=e,d=null,e=null):"function"==typeof e&&(g=f,f=e,e=null),a.os.plus&&"div"!==g?plus.nativeUI.prompt(b,f,d||"提示",c,e||["取消","确认"]):u(s(b,d||"提示",r(c))+t(e||["取消","确认"]),f)):void 0},y=function(){return p.length?(p[p.length-1].close(),!0):!1},z=function(){for(;p.length;)p[p.length-1].close()};a.closePopup=y,a.closePopups=z,a.alert=v,a.confirm=w,a.prompt=x}(mui,window,document),function(a,b){var c="mui-progressbar",d="mui-progressbar-in",e="mui-progressbar-out",f="mui-progressbar-infinite",g=".mui-progressbar",h=function(b){if(b=a(b||"body"),0!==b.length){if(b=b[0],b.classList.contains(c))return b;var d=b.querySelectorAll(g);if(d)for(var e=0,f=d.length;f>e;e++){var h=d[e];if(h.parentNode===b)return h}}},i=function(h,i,j){if("number"==typeof h&&(j=i,i=h,h="body"),h=a(h||"body"),0!==h.length){h=h[0];var l;if(h.classList.contains(c))l=h;else{var m=h.querySelectorAll(g+":not(."+e+")");if(m)for(var n=0,o=m.length;o>n;n++){var p=m[n];if(p.parentNode===h){l=p;break}}l?l.classList.add(d):(l=b.createElement("span"),l.className=c+" "+d+("undefined"!=typeof i?"":" "+f)+(j?" "+c+"-"+j:""),"undefined"!=typeof i&&(l.innerHTML="<span></span>"),h.appendChild(l))}return i&&k(h,i),l}},j=function(a){var b=h(a);if(b){var c=b.classList;c.contains(d)&&!c.contains(e)&&(c.remove(d),c.add(e),b.addEventListener("webkitAnimationEnd",function(){b.parentNode&&b.parentNode.removeChild(b),b=null}))}},k=function(a,b,c){"number"==typeof a&&(c=b,b=a,a=!1);var d=h(a);if(d&&!d.classList.contains(f)){b&&(b=Math.min(Math.max(b,0),100)),d.offsetHeight;var e=d.querySelector("span");if(e){var g=e.style;g.webkitTransform="translate3d("+(-100+b)+"%,0,0)","undefined"!=typeof c?g.webkitTransitionDuration=c+"ms":g.webkitTransitionDuration=""}return d}};a.fn.progressbar=function(a){var b=[];return a=a||{},this.each(function(){var c=this,d=c.mui_plugin_progressbar;d?a&&d.setOptions(a):c.mui_plugin_progressbar=d={options:a,setOptions:function(a){this.options=a},show:function(){return i(c,this.options.progress,this.options.color)},setProgress:function(a){return k(c,a)},hide:function(){return j(c)}},b.push(d)}),1===b.length?b[0]:b}}(mui,document),function(a,b,c){var d="mui-icon",e="mui-icon-clear",f="mui-icon-speech",g="mui-icon-search",h="mui-icon-eye",i="mui-input-row",j="mui-placeholder",k="mui-tooltip",l="mui-hidden",m="mui-focusin",n="."+e,o="."+f,p="."+h,q="."+j,r="."+k,s=function(a){for(;a&&a!==c;a=a.parentNode)if(a.classList&&a.classList.contains(i))return a;return null},t=function(a,b){this.element=a,this.options=b||{actions:"clear"},~this.options.actions.indexOf("slider")?(this.sliderActionClass=k+" "+l,this.sliderActionSelector=r):(~this.options.actions.indexOf("clear")&&(this.clearActionClass=d+" "+e+" "+l,this.clearActionSelector=n),~this.options.actions.indexOf("speech")&&(this.speechActionClass=d+" "+f,this.speechActionSelector=o),~this.options.actions.indexOf("search")&&(this.searchActionClass=j,this.searchActionSelector=q),~this.options.actions.indexOf("password")&&(this.passwordActionClass=d+" "+h,this.passwordActionSelector=p)),this.init()};t.prototype.init=function(){this.initAction(),this.initElementEvent()},t.prototype.initAction=function(){var b=this,c=b.element.parentNode;c&&(b.sliderActionClass?b.sliderAction=b.createAction(c,b.sliderActionClass,b.sliderActionSelector):(b.searchActionClass&&(b.searchAction=b.createAction(c,b.searchActionClass,b.searchActionSelector),b.searchAction.addEventListener("tap",function(c){a.focus(b.element),c.stopPropagation()})),b.speechActionClass&&(b.speechAction=b.createAction(c,b.speechActionClass,b.speechActionSelector),b.speechAction.addEventListener("click",a.stopPropagation),b.speechAction.addEventListener("tap",function(a){b.speechActionClick(a)})),b.clearActionClass&&(b.clearAction=b.createAction(c,b.clearActionClass,b.clearActionSelector),b.clearAction.addEventListener("tap",function(a){b.clearActionClick(a)})),b.passwordActionClass&&(b.passwordAction=b.createAction(c,b.passwordActionClass,b.passwordActionSelector),b.passwordAction.addEventListener("tap",function(a){b.passwordActionClick(a)}))))},t.prototype.createAction=function(a,b,e){var f=a.querySelector(e);if(!f){var f=c.createElement("span");f.className=b,b===this.searchActionClass&&(f.innerHTML='<span class="'+d+" "+g+'"></span><span>'+this.element.getAttribute("placeholder")+"</span>",this.element.setAttribute("placeholder",""),this.element.value.trim()&&a.classList.add("mui-active")),a.insertBefore(f,this.element.nextSibling)}return f},t.prototype.initElementEvent=function(){var b=this.element;if(this.sliderActionClass){var c=this.sliderAction,d=null,e=function(){c.classList.remove(l);var a=b.offsetLeft,e=b.offsetWidth-28,f=c.offsetWidth,g=Math.abs(b.max-b.min),h=e/g*Math.abs(b.value-b.min);c.style.left=14+a+h-f/2+"px",c.innerText=b.value,d&&clearTimeout(d),d=setTimeout(function(){c.classList.add(l)},1e3)};b.addEventListener("input",e),b.addEventListener("tap",e),b.addEventListener(a.EVENT_MOVE,function(a){a.stopPropagation()})}else{if(this.clearActionClass){var f=this.clearAction;if(!f)return;a.each(["keyup","change","input","focus","cut","paste"],function(a,c){!function(a){b.addEventListener(a,function(){f.classList[b.value.trim()?"remove":"add"](l)})}(c)}),b.addEventListener("blur",function(){f.classList.add(l)})}this.searchActionClass&&(b.addEventListener("focus",function(){b.parentNode.classList.add("mui-active")}),b.addEventListener("blur",function(){b.value.trim()||b.parentNode.classList.remove("mui-active")}))}},t.prototype.setPlaceholder=function(a){if(this.searchActionClass){var b=this.element.parentNode.querySelector(q);b&&(b.getElementsByTagName("span")[1].innerText=a)}else this.element.setAttribute("placeholder",a)},t.prototype.passwordActionClick=function(a){"text"===this.element.type?this.element.type="password":this.element.type="text",this.passwordAction.classList.toggle("mui-active"),a.preventDefault()},t.prototype.clearActionClick=function(b){var c=this;c.element.value="",a.focus(c.element),c.clearAction.classList.add(l),b.preventDefault()},t.prototype.speechActionClick=function(d){if(b.plus){var e=this,f=e.element.value;e.element.value="",c.body.classList.add(m),plus.speech.startRecognize({engine:"iFly"},function(b){e.element.value+=b,a.focus(e.element),plus.speech.stopRecognize(),a.trigger(e.element,"recognized",{value:e.element.value}),f!==e.element.value&&(a.trigger(e.element,"change"),a.trigger(e.element,"input"))},function(a){c.body.classList.remove(m)})}else alert("only for 5+");d.preventDefault()},a.fn.input=function(b){var c=[];return this.each(function(){var b=null,d=[],e=s(this.parentNode);if("range"===this.type&&e.classList.contains("mui-input-range"))d.push("slider");else{var f=this.classList;f.contains("mui-input-clear")&&d.push("clear"),a.os.android&&a.os.stream||!f.contains("mui-input-speech")||d.push("speech"),f.contains("mui-input-password")&&d.push("password"),"search"===this.type&&e.classList.contains("mui-search")&&d.push("search")}var g=this.getAttribute("data-input-"+d[0]);if(g)b=a.data[g];else{g=++a.uuid,b=a.data[g]=new t(this,{actions:d.join(",")});for(var h=0,i=d.length;i>h;h++)this.setAttribute("data-input-"+d[h],g)}c.push(b)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-input-row input").input()})}(mui,window,document),function(a,b){var c="mui-active",d=/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/,e=function(a){var b=a.match(d);return b&&5===b.length?[b[1],b[2],b[3],b[4]]:[]},f=function(c,d){if(this.element=c,this.options=a.extend({top:0,offset:150,duration:16,scrollby:b},d||{}),this.scrollByElem=this.options.scrollby||b,!this.scrollByElem)throw new Error("监听滚动的元素不存在");this.isNativeScroll=!1,this.scrollByElem===b?this.isNativeScroll=!0:~this.scrollByElem.className.indexOf("mui-scroll-wrapper")||(this.isNativeScroll=!0),this._style=this.element.style,this._bgColor=this._style.backgroundColor;var f=e(mui.getStyles(this.element,"backgroundColor"));if(!f.length)throw new Error("元素背景颜色必须为RGBA");this._R=f[0],this._G=f[1],this._B=f[2],this._A=parseFloat(f[3]),this.lastOpacity=this._A,this._bufferFn=a.buffer(this.handleScroll,this.options.duration,this),this.initEvent()};f.prototype.initEvent=function(){this.scrollByElem.addEventListener("scroll",this._bufferFn),this.isNativeScroll&&this.scrollByElem.addEventListener(a.EVENT_MOVE,this._bufferFn)},f.prototype.handleScroll=function(d){var e=b.scrollY;!this.isNativeScroll&&d&&d.detail&&(e=-d.detail.y);var f=(e-this.options.top)/this.options.offset+this._A;f=Math.min(Math.max(this._A,f),1),this._style.backgroundColor="rgba("+this._R+","+this._G+","+this._B+","+f+")",f>this._A?this.element.classList.add(c):this.element.classList.remove(c),this.lastOpacity!==f&&(a.trigger(this.element,"alpha",{alpha:f}),this.lastOpacity=f)},f.prototype.destory=function(){this.scrollByElem.removeEventListener("scroll",this._bufferFn),this.scrollByElem.removeEventListener(a.EVENT_MOVE,this._bufferFn),this.element.style.backgroundColor=this._bgColor,this.element.mui_plugin_transparent=null},a.fn.transparent=function(a){a=a||{};var c=[];return this.each(function(){var d=this.mui_plugin_transparent;if(!d){var e=this.getAttribute("data-top"),g=this.getAttribute("data-offset"),h=this.getAttribute("data-duration"),i=this.getAttribute("data-scrollby");null!==e&&"undefined"==typeof a.top&&(a.top=e),null!==g&&"undefined"==typeof a.offset&&(a.offset=g),null!==h&&"undefined"==typeof a.duration&&(a.duration=h),null!==i&&"undefined"==typeof a.scrollby&&(a.scrollby=document.querySelector(i)||b),d=this.mui_plugin_transparent=new f(this,a)}c.push(d)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-bar-transparent").transparent()})}(mui,window),function(a){var b="ontouchstart"in document,c=b?"tap":"click",d="change",e="mui-numbox",f=".mui-btn-numbox-plus,.mui-numbox-btn-plus",g=".mui-btn-numbox-minus,.mui-numbox-btn-minus",h=".mui-input-numbox,.mui-numbox-input",i=a.Numbox=a.Class.extend({init:function(b,c){var d=this;if(!b)throw"构造 numbox 时缺少容器元素";d.holder=b,c=c||{},c.step=parseInt(c.step||1),d.options=c,d.input=a.qsa(h,d.holder)[0],d.plus=a.qsa(f,d.holder)[0],d.minus=a.qsa(g,d.holder)[0],d.checkValue(),d.initEvent()},initEvent:function(){var b=this;b.plus.addEventListener(c,function(c){var e=parseInt(b.input.value)+b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.minus.addEventListener(c,function(c){var e=parseInt(b.input.value)-b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.input.addEventListener(d,function(c){b.checkValue();var e=parseInt(b.input.value);a.trigger(b.holder,d,{value:e})})},getValue:function(){var a=this;return parseInt(a.input.value)},checkValue:function(){var a=this,b=a.input.value;if(null==b||""==b||isNaN(b))a.input.value=a.options.min||0,a.minus.disabled=null!=a.options.min;else{var b=parseInt(b);null!=a.options.max&&!isNaN(a.options.max)&&b>=parseInt(a.options.max)?(b=a.options.max,a.plus.disabled=!0):a.plus.disabled=!1,null!=a.options.min&&!isNaN(a.options.min)&&b<=parseInt(a.options.min)?(b=a.options.min,a.minus.disabled=!0):a.minus.disabled=!1,a.input.value=b}},setOption:function(a,b){var c=this;c.options[a]=b},setValue:function(a){this.input.value=a,this.checkValue()}});a.fn.numbox=function(a){return this.each(function(a,b){if(!b.numbox)if(d)b.numbox=new i(b,d);else{var c=b.getAttribute("data-numbox-options"),d=c?JSON.parse(c):{};d.step=b.getAttribute("data-numbox-step")||d.step,d.min=b.getAttribute("data-numbox-min")||d.min,d.max=b.getAttribute("data-numbox-max")||d.max,b.numbox=new i(b,d)}}),this[0]?this[0].numbox:null},a.ready(function(){a("."+e).numbox()})}(mui),function(a,b,c){var d="mui-disabled",e="reset",f="loading",g={loadingText:"Loading...",loadingIcon:"mui-spinner mui-spinner-white",loadingIconPosition:"left"},h=function(b,c){this.element=b,this.options=a.extend({},g,c),this.options.loadingText||(this.options.loadingText=g.loadingText),null===this.options.loadingIcon&&(this.options.loadingIcon="mui-spinner","rgb(255, 255, 255)"===a.getStyles(this.element,"color")&&(this.options.loadingIcon+=" mui-spinner-white")),this.isInput="INPUT"===this.element.tagName,this.resetHTML=this.isInput?this.element.value:this.element.innerHTML,this.state=""};h.prototype.loading=function(){this.setState(f)},h.prototype.reset=function(){this.setState(e)},h.prototype.setState=function(a){if(this.state===a)return!1;if(this.state=a,a===e)this.element.disabled=!1,this.element.classList.remove(d),this.setHtml(this.resetHTML);else if(a===f){this.element.disabled=!0,this.element.classList.add(d);var b=this.isInput?this.options.loadingText:"<span>"+this.options.loadingText+"</span>";this.options.loadingIcon&&!this.isInput&&("right"===this.options.loadingIconPosition?b+='&nbsp;<span class="'+this.options.loadingIcon+'"></span>':b='<span class="'+this.options.loadingIcon+'"></span>&nbsp;'+b),this.setHtml(b)}},h.prototype.setHtml=function(a){this.isInput?this.element.value=a:this.element.innerHTML=a},a.fn.button=function(a){var b=[];return this.each(function(){var c=this.mui_plugin_button;if(!c){var d=this.getAttribute("data-loading-text"),g=this.getAttribute("data-loading-icon"),i=this.getAttribute("data-loading-icon-position");this.mui_plugin_button=c=new h(this,{loadingText:d,loadingIcon:g,loadingIconPosition:i})}(a===f||a===e)&&c.setState(a),b.push(c)}),1===b.length?b[0]:b}}(mui,window,document); \ No newline at end of file diff --git a/static/app/js/my.js b/static/app/js/my.js new file mode 100755 index 0000000..3703bf5 --- /dev/null +++ b/static/app/js/my.js @@ -0,0 +1,306 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); +// alert(token); + mui.ajax(hyhUrl('app/users/getUserInfo'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { +// console.log(data.data.userPhoto) + var imgurl = data.data.userPhoto?hyhImgUrl(data.data.userPhoto):'http://heyuanhui.com.cn/Template/mobile/new/Static/images/user68.png'; + var html = '<div class="header clearfix"><div class="seeting">设置</div><div class="share">分享</div></div><div class="con"><img src="' + imgurl + '" /><p>' + data.data.loginName + '</p></div><div class="hyz">惠员值:0</div>'; + $('.login').css('display', 'none'); + $('.my').html(html); + + var htmlmoney = '<div class="moneycon_"><img src="../img/yuan.png"/><p id="userMoney">'+ data.data.userMoney +'</p></div><div class="moneycon_" id="moneycon_"><img src="../img/hui.png"/><p id="userScore">'+ data.data.userScore +'</p></div><div class="moneycon_"><img src="http://img.juzi199.com/upload/sysconfigs/ect.png"/><p id="userEct">'+ data.data.userECT +'</p></div>'; + $('.moneycon').html(htmlmoney); +// $('#userMoney').html('¥' + data.data.userMoney) +// $('#userScore').html('¥' + data.data.userScore) + + }else{ +// console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   +// alert(errorThrown);       + }   + });  + mui.ajax(hyhUrl('app/users/getFavoritesNum'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data, 1); + if(data.status == 1) { +// console.log(data.data.goodsFavoritesNum) + var html = '<div class="nblock" data-href="collect_commodity.html"><p>' + data.data.goodsFavoritesNum + '</p><p>收藏夹</p></div><div class="nblock" data-href="collect_store.html"><p>' + data.data.shopFavoritesNum + '</p><p>关注店铺</p></div><div class="nblock" data-href="share_user_list.html"><p>' + data.data.shareNum + '</p><p>我的分享</p></div>'; + $('.nav').html(html); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui.ajax(hyhUrl('app/users/getOrderNum'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data, 1); + if(data.status == 1) { + var html = '<div class="order_cb indent_btn" data-href="waitPay"><div class="num">' + data.data.order.waitPay + '</div><img src="../img/1.png" /><p>待付款</p></div><div class="order_cb indent_btn" data-href="waitDeliver"><div class="num">' + data.data.order.waitSend + '</div><img src="../img/2.png" /><p>待发货</p></div><div class="order_cb indent_btn" data-href="waitReceive"><div class="num">' + data.data.order.waitReceive + '</div><img src="../img/3.png" /><p>待收货</p></div><div class="order_cb indent_btn" data-href="waitAppraise"><div class="num">' + data.data.order.waitAppraise + '</div><img src="../img/4.png" /><p>待评价</p></div><div class="order_cb indent_btn" data-href="abnormal"><img src="../img/5.png" /><p>退款/售后</p></div>'; + $('.order_con').html(html); + $('.num').each(function() { + if($(this).html() == '0') { + $(this).css('display', 'none'); + } + }) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + }); + + mui('.my').on('tap', '.seeting', function() { + mui.openWindow({ + url: 'setting.html', + id: 'setting.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.my').on('tap', '.share', function() { + mui.openWindow({ + url: 'share.html', + id: 'share.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { +// data_userId: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + mui(".nav").on('tap', '.nblock', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_href = this.attributes["data-href"].nodeValue; + var url = 'collect.html'; + if(data_href=='share_user_list.html'){ + url = 'share_user_list.html'; + } + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + mui('.order').on('tap', '.indent_btn', function() { + var data_href = this.attributes["data-href"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'indent.html', + id: 'indent.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.my').on('tap', '.login', function() { + mui.openWindow({ + url: 'login.html', + id: 'login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + + //跳转到ect钱包 + $('.moneycon').on('tap', '.moneycon_', function() { + + if($(this).children('p').attr('id','userEct')){ + mui.openWindow({ + url: 'ect_index.html', + id: 'ect_index.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + + }) + +}) \ No newline at end of file diff --git a/static/app/js/new_product.js b/static/app/js/new_product.js new file mode 100755 index 0000000..2374db8 --- /dev/null +++ b/static/app/js/new_product.js @@ -0,0 +1,179 @@ +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('app/Shops/listShopQuery'), {  + + data: { + page: count, + pagesize : 10 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<img data-goodId="' + this.goodsId + '" src="' + hyhImgUrl(this.goodsImg) + '" />' + }); + html += '</div></div>' + }); + $('.con').append(html); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var data = ''; + mui.ajax(hyhUrl('app/Shops/listShopQuery'), {  + data: { + pagesize: 10, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + data = data.data; + + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<img data-goodId="' + this.goodsId + '" src="' + hyhImgUrl(this.goodsImg) + '" />' + }); + html += '</div></div>' + }); + $('.con').html(html) + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + //console.log(shopId); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html'+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', 'img[data-goodId]', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app/js/newuser.js b/static/app/js/newuser.js new file mode 100755 index 0000000..56c7ffa --- /dev/null +++ b/static/app/js/newuser.js @@ -0,0 +1,33 @@ +mui.plusReady(function() { +// var token = localStorage.getItem('token'); +// var self = plus.webview.currentWebview(); +// var msgId = self.data_msgId; +// mui.ajax(hyhUrl('app/messages/getById'), {  +// headers: {  +// "HYH-Token": token +// }, +// data: { +// msgId: msgId +// }, +// dataType: 'json', //服务器返回json格式数据   +// type: 'post', //HTTP请求类型   +// timeout: 10000, //超时时间设置为10秒;   +// success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   +// var data = toJson(data); +// +// if(data.status == 1) { +// data = data.data; +// var html = '<div class="time">' + data.createTime + '</div><div class="con_">' + data.msgContent + '</div>'; +// $('.con').html(html) +// } else { +// console.log(data.status) +// } +// }, +// error: function(xhr, type, errorThrown) {           //异常处理;   +// // alert(type);       +// }   +// });  + var html = '<div class="con_">1、惠宝积分的获得:1)合源惠线下联盟消费者去实体店消费根据消费金额可直接获得惠宝积分 2)新手注册直接送388惠宝积分 3)商城消费成功购物,可获得实际消费金额20%的惠宝积分</div><div class="con_">2、惠宝积分的使用:惠宝积分用于商城购物在货款结算时勾选,可直抵20%货款</div>'; + $('.con').html(html) + +}) \ No newline at end of file diff --git a/static/app/js/order_con.js b/static/app/js/order_con.js new file mode 100755 index 0000000..b428685 --- /dev/null +++ b/static/app/js/order_con.js @@ -0,0 +1,110 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var data_order_id = localStorage.getItem('data_order_id'); + // console.log(data_order_id) + mui.ajax(hyhUrl('app/Orders/getDetail'), {  + headers: {  + "HYH-Token": token + }, + data: { + id: data_order_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + var html = '<div class="ad"><p>' + data.status + '</p></div><div class="address clearfix"><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userName + '</div><div class="add_r_t_r">' + data.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.userAddress + '</div></div></div><div class="invoice_info"><p>发票信息</p><p>发票抬头 ' + data.invoiceClient + '</p></div><div class="shop_info"><div class="row_title" data-shopId="' + data.shopId + '"><div class="store_name">' + data.shopName + '</div></div><div class="row_con clearfix">'; + $.each(data.goods, function() { + html += '<div class="row_block clearfix" data-goodsId="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>' + }); + + html += '<div class="cost"><div class="c1 clearfix"><div class="c1_l">商品总价</div><div class="c1_r">¥' + data.goodsMoney + '</div></div><div class="c1 clearfix"><div class="c1_l">运费(快递)</div><div class="c1_r">¥' + data.deliverMoney + '</div></div><div class="c2 clearfix"><div class="c1_l">订单总价</div><div class="c1_r">¥' + data.totalMoney + '</div></div></div><div class="cost"><div class="c2 clearfix"><div class="c1_l">实付款</div><div class="c1_r on">¥' + data.realTotalMoney + '</div></div></div></div></div><div class="jf_info clearfix"><div class="jf_jf">积分</div><div class="jf_p">奖励积分<o>' + data.orderScore + '</o>点</div></div><a href="tel:' + data.shopTel + '" class="lxmj"><img src="../img/phone1.png" /><p>联系卖家 </p></a><div class="info"><p>订单编号:' + data.orderNo + '</p><p>创建时间:' + data.createTime + '</p>'; + + if(data.deliveryTime != 'null') { + html += '<p>发货时间:' + data.deliveryTime + '</p>' + } + if(data.deliveryTime != 'null') { + html += '<p>成交时间:' + data.receiveTime + '</p>' + } + + html += '</div>'; + + $('.con').html(html); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + $('.con').on('tap', '.row_title', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + $('.con').on('tap', '.row_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/order_out.js b/static/app/js/order_out.js new file mode 100755 index 0000000..b80cbd9 --- /dev/null +++ b/static/app/js/order_out.js @@ -0,0 +1,52 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + var sub = plus.webview.create('order_con.html', 'order_con.html', { + top: '66px', + bottom: '49px', + scrollIndicator: 'none' + }); + self.append(sub); + localStorage.setItem('data_order_id', data_order_id); + if(!data_order_id) { + $('#ckwl').css('display', 'none') + } + mui(".btns").on('tap', '#ckwl', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'logistics.html', + id: 'logistics.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/photoswipe-ui-default.min.js b/static/app/js/photoswipe-ui-default.min.js new file mode 100755 index 0000000..79115c5 --- /dev/null +++ b/static/app/js/photoswipe-ui-default.min.js @@ -0,0 +1,4 @@ +/*! PhotoSwipe Default UI - 4.1.2 - 2017-04-05 +* http://photoswipe.com +* Copyright (c) 2017 Dmitry Semenov; */ +!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.PhotoSwipeUI_Default=b()}(this,function(){"use strict";var a=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v=this,w=!1,x=!0,y=!0,z={barsSize:{top:44,bottom:"auto"},closeElClasses:["item","caption","zoom-wrap","ui","top-bar"],timeToIdle:4e3,timeToIdleOutside:1e3,loadingIndicatorDelay:1e3,addCaptionHTMLFn:function(a,b){return a.title?(b.children[0].innerHTML=a.title,!0):(b.children[0].innerHTML="",!1)},closeEl:!0,captionEl:!0,fullscreenEl:!0,zoomEl:!0,shareEl:!0,counterEl:!0,arrowEl:!0,preloaderEl:!0,tapToClose:!1,tapToToggleControls:!0,clickToCloseNonZoomable:!0,shareButtons:[{id:"facebook",label:"Share on Facebook",url:"https://www.facebook.com/sharer/sharer.php?u={{url}}"},{id:"twitter",label:"Tweet",url:"https://twitter.com/intent/tweet?text={{text}}&url={{url}}"},{id:"pinterest",label:"Pin it",url:"http://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}"},{id:"download",label:"Download image",url:"{{raw_image_url}}",download:!0}],getImageURLForShare:function(){return a.currItem.src||""},getPageURLForShare:function(){return window.location.href},getTextForShare:function(){return a.currItem.title||""},indexIndicatorSep:" / ",fitControlsWidth:1200},A=function(a){if(r)return!0;a=a||window.event,q.timeToIdle&&q.mouseUsed&&!k&&K();for(var c,d,e=a.target||a.srcElement,f=e.getAttribute("class")||"",g=0;g<S.length;g++)c=S[g],c.onTap&&f.indexOf("pswp__"+c.name)>-1&&(c.onTap(),d=!0);if(d){a.stopPropagation&&a.stopPropagation(),r=!0;var h=b.features.isOldAndroid?600:30;s=setTimeout(function(){r=!1},h)}},B=function(){return!a.likelyTouchDevice||q.mouseUsed||screen.width>q.fitControlsWidth},C=function(a,c,d){b[(d?"add":"remove")+"Class"](a,"pswp__"+c)},D=function(){var a=1===q.getNumItemsFn();a!==p&&(C(d,"ui--one-slide",a),p=a)},E=function(){C(i,"share-modal--hidden",y)},F=function(){return y=!y,y?(b.removeClass(i,"pswp__share-modal--fade-in"),setTimeout(function(){y&&E()},300)):(E(),setTimeout(function(){y||b.addClass(i,"pswp__share-modal--fade-in")},30)),y||H(),!1},G=function(b){b=b||window.event;var c=b.target||b.srcElement;return a.shout("shareLinkClick",b,c),!!c.href&&(!!c.hasAttribute("download")||(window.open(c.href,"pswp_share","scrollbars=yes,resizable=yes,toolbar=no,location=yes,width=550,height=420,top=100,left="+(window.screen?Math.round(screen.width/2-275):100)),y||F(),!1))},H=function(){for(var a,b,c,d,e,f="",g=0;g<q.shareButtons.length;g++)a=q.shareButtons[g],c=q.getImageURLForShare(a),d=q.getPageURLForShare(a),e=q.getTextForShare(a),b=a.url.replace("{{url}}",encodeURIComponent(d)).replace("{{image_url}}",encodeURIComponent(c)).replace("{{raw_image_url}}",c).replace("{{text}}",encodeURIComponent(e)),f+='<a href="'+b+'" target="_blank" class="pswp__share--'+a.id+'"'+(a.download?"download":"")+">"+a.label+"</a>",q.parseShareButtonOut&&(f=q.parseShareButtonOut(a,f));i.children[0].innerHTML=f,i.children[0].onclick=G},I=function(a){for(var c=0;c<q.closeElClasses.length;c++)if(b.hasClass(a,"pswp__"+q.closeElClasses[c]))return!0},J=0,K=function(){clearTimeout(u),J=0,k&&v.setIdle(!1)},L=function(a){a=a?a:window.event;var b=a.relatedTarget||a.toElement;b&&"HTML"!==b.nodeName||(clearTimeout(u),u=setTimeout(function(){v.setIdle(!0)},q.timeToIdleOutside))},M=function(){q.fullscreenEl&&!b.features.isOldAndroid&&(c||(c=v.getFullscreenAPI()),c?(b.bind(document,c.eventK,v.updateFullscreen),v.updateFullscreen(),b.addClass(a.template,"pswp--supports-fs")):b.removeClass(a.template,"pswp--supports-fs"))},N=function(){q.preloaderEl&&(O(!0),l("beforeChange",function(){clearTimeout(o),o=setTimeout(function(){a.currItem&&a.currItem.loading?(!a.allowProgressiveImg()||a.currItem.img&&!a.currItem.img.naturalWidth)&&O(!1):O(!0)},q.loadingIndicatorDelay)}),l("imageLoadComplete",function(b,c){a.currItem===c&&O(!0)}))},O=function(a){n!==a&&(C(m,"preloader--active",!a),n=a)},P=function(a){var c=a.vGap;if(B()){var g=q.barsSize;if(q.captionEl&&"auto"===g.bottom)if(f||(f=b.createEl("pswp__caption pswp__caption--fake"),f.appendChild(b.createEl("pswp__caption__center")),d.insertBefore(f,e),b.addClass(d,"pswp__ui--fit")),q.addCaptionHTMLFn(a,f,!0)){var h=f.clientHeight;c.bottom=parseInt(h,10)||44}else c.bottom=g.top;else c.bottom="auto"===g.bottom?0:g.bottom;c.top=g.top}else c.top=c.bottom=0},Q=function(){q.timeToIdle&&l("mouseUsed",function(){b.bind(document,"mousemove",K),b.bind(document,"mouseout",L),t=setInterval(function(){J++,2===J&&v.setIdle(!0)},q.timeToIdle/2)})},R=function(){l("onVerticalDrag",function(a){x&&a<.95?v.hideControls():!x&&a>=.95&&v.showControls()});var a;l("onPinchClose",function(b){x&&b<.9?(v.hideControls(),a=!0):a&&!x&&b>.9&&v.showControls()}),l("zoomGestureEnded",function(){a=!1,a&&!x&&v.showControls()})},S=[{name:"caption",option:"captionEl",onInit:function(a){e=a}},{name:"share-modal",option:"shareEl",onInit:function(a){i=a},onTap:function(){F()}},{name:"button--share",option:"shareEl",onInit:function(a){h=a},onTap:function(){F()}},{name:"button--zoom",option:"zoomEl",onTap:a.toggleDesktopZoom},{name:"counter",option:"counterEl",onInit:function(a){g=a}},{name:"button--close",option:"closeEl",onTap:a.close},{name:"button--arrow--left",option:"arrowEl",onTap:a.prev},{name:"button--arrow--right",option:"arrowEl",onTap:a.next},{name:"button--fs",option:"fullscreenEl",onTap:function(){c.isFullscreen()?c.exit():c.enter()}},{name:"preloader",option:"preloaderEl",onInit:function(a){m=a}}],T=function(){var a,c,e,f=function(d){if(d)for(var f=d.length,g=0;g<f;g++){a=d[g],c=a.className;for(var h=0;h<S.length;h++)e=S[h],c.indexOf("pswp__"+e.name)>-1&&(q[e.option]?(b.removeClass(a,"pswp__element--disabled"),e.onInit&&e.onInit(a)):b.addClass(a,"pswp__element--disabled"))}};f(d.children);var g=b.getChildByClass(d,"pswp__top-bar");g&&f(g.children)};v.init=function(){b.extend(a.options,z,!0),q=a.options,d=b.getChildByClass(a.scrollWrap,"pswp__ui"),l=a.listen,R(),l("beforeChange",v.update),l("doubleTap",function(b){var c=a.currItem.initialZoomLevel;a.getZoomLevel()!==c?a.zoomTo(c,b,333):a.zoomTo(q.getDoubleTapZoom(!1,a.currItem),b,333)}),l("preventDragEvent",function(a,b,c){var d=a.target||a.srcElement;d&&d.getAttribute("class")&&a.type.indexOf("mouse")>-1&&(d.getAttribute("class").indexOf("__caption")>0||/(SMALL|STRONG|EM)/i.test(d.tagName))&&(c.prevent=!1)}),l("bindEvents",function(){b.bind(d,"pswpTap click",A),b.bind(a.scrollWrap,"pswpTap",v.onGlobalTap),a.likelyTouchDevice||b.bind(a.scrollWrap,"mouseover",v.onMouseOver)}),l("unbindEvents",function(){y||F(),t&&clearInterval(t),b.unbind(document,"mouseout",L),b.unbind(document,"mousemove",K),b.unbind(d,"pswpTap click",A),b.unbind(a.scrollWrap,"pswpTap",v.onGlobalTap),b.unbind(a.scrollWrap,"mouseover",v.onMouseOver),c&&(b.unbind(document,c.eventK,v.updateFullscreen),c.isFullscreen()&&(q.hideAnimationDuration=0,c.exit()),c=null)}),l("destroy",function(){q.captionEl&&(f&&d.removeChild(f),b.removeClass(e,"pswp__caption--empty")),i&&(i.children[0].onclick=null),b.removeClass(d,"pswp__ui--over-close"),b.addClass(d,"pswp__ui--hidden"),v.setIdle(!1)}),q.showAnimationDuration||b.removeClass(d,"pswp__ui--hidden"),l("initialZoomIn",function(){q.showAnimationDuration&&b.removeClass(d,"pswp__ui--hidden")}),l("initialZoomOut",function(){b.addClass(d,"pswp__ui--hidden")}),l("parseVerticalMargin",P),T(),q.shareEl&&h&&i&&(y=!0),D(),Q(),M(),N()},v.setIdle=function(a){k=a,C(d,"ui--idle",a)},v.update=function(){x&&a.currItem?(v.updateIndexIndicator(),q.captionEl&&(q.addCaptionHTMLFn(a.currItem,e),C(e,"caption--empty",!a.currItem.title)),w=!0):w=!1,y||F(),D()},v.updateFullscreen=function(d){d&&setTimeout(function(){a.setScrollOffset(0,b.getScrollY())},50),b[(c.isFullscreen()?"add":"remove")+"Class"](a.template,"pswp--fs")},v.updateIndexIndicator=function(){q.counterEl&&(g.innerHTML=a.getCurrentIndex()+1+q.indexIndicatorSep+q.getNumItemsFn())},v.onGlobalTap=function(c){c=c||window.event;var d=c.target||c.srcElement;if(!r)if(c.detail&&"mouse"===c.detail.pointerType){if(I(d))return void a.close();b.hasClass(d,"pswp__img")&&(1===a.getZoomLevel()&&a.getZoomLevel()<=a.currItem.fitRatio?q.clickToCloseNonZoomable&&a.close():a.toggleDesktopZoom(c.detail.releasePoint))}else if(q.tapToToggleControls&&(x?v.hideControls():v.showControls()),q.tapToClose&&(b.hasClass(d,"pswp__img")||I(d)))return void a.close()},v.onMouseOver=function(a){a=a||window.event;var b=a.target||a.srcElement;C(d,"ui--over-close",I(b))},v.hideControls=function(){b.addClass(d,"pswp__ui--hidden"),x=!1},v.showControls=function(){x=!0,w||v.update(),b.removeClass(d,"pswp__ui--hidden")},v.supportsFullscreen=function(){var a=document;return!!(a.exitFullscreen||a.mozCancelFullScreen||a.webkitExitFullscreen||a.msExitFullscreen)},v.getFullscreenAPI=function(){var b,c=document.documentElement,d="fullscreenchange";return c.requestFullscreen?b={enterK:"requestFullscreen",exitK:"exitFullscreen",elementK:"fullscreenElement",eventK:d}:c.mozRequestFullScreen?b={enterK:"mozRequestFullScreen",exitK:"mozCancelFullScreen",elementK:"mozFullScreenElement",eventK:"moz"+d}:c.webkitRequestFullscreen?b={enterK:"webkitRequestFullscreen",exitK:"webkitExitFullscreen",elementK:"webkitFullscreenElement",eventK:"webkit"+d}:c.msRequestFullscreen&&(b={enterK:"msRequestFullscreen",exitK:"msExitFullscreen",elementK:"msFullscreenElement",eventK:"MSFullscreenChange"}),b&&(b.enter=function(){return j=q.closeOnScroll,q.closeOnScroll=!1,"webkitRequestFullscreen"!==this.enterK?a.template[this.enterK]():void a.template[this.enterK](Element.ALLOW_KEYBOARD_INPUT)},b.exit=function(){return q.closeOnScroll=j,document[this.exitK]()},b.isFullscreen=function(){return document[this.elementK]}),b}};return a}); \ No newline at end of file diff --git a/static/app/js/photoswipe.js b/static/app/js/photoswipe.js new file mode 100755 index 0000000..837859f --- /dev/null +++ b/static/app/js/photoswipe.js @@ -0,0 +1,3734 @@ +/*! PhotoSwipe - v4.1.2 - 2017-04-05 +* http://photoswipe.com +* Copyright (c) 2017 Dmitry Semenov; */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.PhotoSwipe = factory(); + } +})(this, function () { + + 'use strict'; + var PhotoSwipe = function(template, UiClass, items, options){ + +/*>>framework-bridge*/ +/** + * + * Set of generic functions used by gallery. + * + * You're free to modify anything here as long as functionality is kept. + * + */ +var framework = { + features: null, + bind: function(target, type, listener, unbind) { + var methodName = (unbind ? 'remove' : 'add') + 'EventListener'; + type = type.split(' '); + for(var i = 0; i < type.length; i++) { + if(type[i]) { + target[methodName]( type[i], listener, false); + } + } + }, + isArray: function(obj) { + return (obj instanceof Array); + }, + createEl: function(classes, tag) { + var el = document.createElement(tag || 'div'); + if(classes) { + el.className = classes; + } + return el; + }, + getScrollY: function() { + var yOffset = window.pageYOffset; + return yOffset !== undefined ? yOffset : document.documentElement.scrollTop; + }, + unbind: function(target, type, listener) { + framework.bind(target,type,listener,true); + }, + removeClass: function(el, className) { + var reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); + el.className = el.className.replace(reg, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + }, + addClass: function(el, className) { + if( !framework.hasClass(el,className) ) { + el.className += (el.className ? ' ' : '') + className; + } + }, + hasClass: function(el, className) { + return el.className && new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); + }, + getChildByClass: function(parentEl, childClassName) { + var node = parentEl.firstChild; + while(node) { + if( framework.hasClass(node, childClassName) ) { + return node; + } + node = node.nextSibling; + } + }, + arraySearch: function(array, value, key) { + var i = array.length; + while(i--) { + if(array[i][key] === value) { + return i; + } + } + return -1; + }, + extend: function(o1, o2, preventOverwrite) { + for (var prop in o2) { + if (o2.hasOwnProperty(prop)) { + if(preventOverwrite && o1.hasOwnProperty(prop)) { + continue; + } + o1[prop] = o2[prop]; + } + } + }, + easing: { + sine: { + out: function(k) { + return Math.sin(k * (Math.PI / 2)); + }, + inOut: function(k) { + return - (Math.cos(Math.PI * k) - 1) / 2; + } + }, + cubic: { + out: function(k) { + return --k * k * k + 1; + } + } + /* + elastic: { + out: function ( k ) { + + var s, a = 0.1, p = 0.4; + if ( k === 0 ) return 0; + if ( k === 1 ) return 1; + if ( !a || a < 1 ) { a = 1; s = p / 4; } + else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); + return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 ); + + }, + }, + back: { + out: function ( k ) { + var s = 1.70158; + return --k * k * ( ( s + 1 ) * k + s ) + 1; + } + } + */ + }, + + /** + * + * @return {object} + * + * { + * raf : request animation frame function + * caf : cancel animation frame function + * transfrom : transform property key (with vendor), or null if not supported + * oldIE : IE8 or below + * } + * + */ + detectFeatures: function() { + if(framework.features) { + return framework.features; + } + var helperEl = framework.createEl(), + helperStyle = helperEl.style, + vendor = '', + features = {}; + + // IE8 and below + features.oldIE = document.all && !document.addEventListener; + + features.touch = 'ontouchstart' in window; + + if(window.requestAnimationFrame) { + features.raf = window.requestAnimationFrame; + features.caf = window.cancelAnimationFrame; + } + + features.pointerEvent = navigator.pointerEnabled || navigator.msPointerEnabled; + + // fix false-positive detection of old Android in new IE + // (IE11 ua string contains "Android 4.0") + + if(!features.pointerEvent) { + + var ua = navigator.userAgent; + + // Detect if device is iPhone or iPod and if it's older than iOS 8 + // http://stackoverflow.com/a/14223920 + // + // This detection is made because of buggy top/bottom toolbars + // that don't trigger window.resize event. + // For more info refer to _isFixedPosition variable in core.js + + if (/iP(hone|od)/.test(navigator.platform)) { + var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/); + if(v && v.length > 0) { + v = parseInt(v[1], 10); + if(v >= 1 && v < 8 ) { + features.isOldIOSPhone = true; + } + } + } + + // Detect old Android (before KitKat) + // due to bugs related to position:fixed + // http://stackoverflow.com/questions/7184573/pick-up-the-android-version-in-the-browser-by-javascript + + var match = ua.match(/Android\s([0-9\.]*)/); + var androidversion = match ? match[1] : 0; + androidversion = parseFloat(androidversion); + if(androidversion >= 1 ) { + if(androidversion < 4.4) { + features.isOldAndroid = true; // for fixed position bug & performance + } + features.androidVersion = androidversion; // for touchend bug + } + features.isMobileOpera = /opera mini|opera mobi/i.test(ua); + + // p.s. yes, yes, UA sniffing is bad, propose your solution for above bugs. + } + + var styleChecks = ['transform', 'perspective', 'animationName'], + vendors = ['', 'webkit','Moz','ms','O'], + styleCheckItem, + styleName; + + for(var i = 0; i < 4; i++) { + vendor = vendors[i]; + + for(var a = 0; a < 3; a++) { + styleCheckItem = styleChecks[a]; + + // uppercase first letter of property name, if vendor is present + styleName = vendor + (vendor ? + styleCheckItem.charAt(0).toUpperCase() + styleCheckItem.slice(1) : + styleCheckItem); + + if(!features[styleCheckItem] && styleName in helperStyle ) { + features[styleCheckItem] = styleName; + } + } + + if(vendor && !features.raf) { + vendor = vendor.toLowerCase(); + features.raf = window[vendor+'RequestAnimationFrame']; + if(features.raf) { + features.caf = window[vendor+'CancelAnimationFrame'] || + window[vendor+'CancelRequestAnimationFrame']; + } + } + } + + if(!features.raf) { + var lastTime = 0; + features.raf = function(fn) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { fn(currTime + timeToCall); }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + features.caf = function(id) { clearTimeout(id); }; + } + + // Detect SVG support + features.svg = !!document.createElementNS && + !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; + + framework.features = features; + + return features; + } +}; + +framework.detectFeatures(); + +// Override addEventListener for old versions of IE +if(framework.features.oldIE) { + + framework.bind = function(target, type, listener, unbind) { + + type = type.split(' '); + + var methodName = (unbind ? 'detach' : 'attach') + 'Event', + evName, + _handleEv = function() { + listener.handleEvent.call(listener); + }; + + for(var i = 0; i < type.length; i++) { + evName = type[i]; + if(evName) { + + if(typeof listener === 'object' && listener.handleEvent) { + if(!unbind) { + listener['oldIE' + evName] = _handleEv; + } else { + if(!listener['oldIE' + evName]) { + return false; + } + } + + target[methodName]( 'on' + evName, listener['oldIE' + evName]); + } else { + target[methodName]( 'on' + evName, listener); + } + + } + } + }; + +} + +/*>>framework-bridge*/ + +/*>>core*/ +//function(template, UiClass, items, options) + +var self = this; + +/** + * Static vars, don't change unless you know what you're doing. + */ +var DOUBLE_TAP_RADIUS = 25, + NUM_HOLDERS = 3; + +/** + * Options + */ +var _options = { + allowPanToNext:true, + spacing: 0.12, + bgOpacity: 1, + mouseUsed: false, + loop: true, + pinchToClose: true, + closeOnScroll: true, + closeOnVerticalDrag: true, + verticalDragRange: 0.75, + hideAnimationDuration: 333, + showAnimationDuration: 333, + showHideOpacity: false, + focus: true, + escKey: true, + arrowKeys: true, + mainScrollEndFriction: 0.35, + panEndFriction: 0.35, + isClickableElement: function(el) { + return el.tagName === 'A'; + }, + getDoubleTapZoom: function(isMouseClick, item) { + if(isMouseClick) { + return 1; + } else { + return item.initialZoomLevel < 0.7 ? 1 : 1.33; + } + }, + maxSpreadZoom: 1.33, + modal: true, + + // not fully implemented yet + scaleMode: 'fit' // TODO +}; +framework.extend(_options, options); + + +/** + * Private helper variables & functions + */ + +var _getEmptyPoint = function() { + return {x:0,y:0}; + }; + +var _isOpen, + _isDestroying, + _closedByScroll, + _currentItemIndex, + _containerStyle, + _containerShiftIndex, + _currPanDist = _getEmptyPoint(), + _startPanOffset = _getEmptyPoint(), + _panOffset = _getEmptyPoint(), + _upMoveEvents, // drag move, drag end & drag cancel events array + _downEvents, // drag start events array + _globalEventHandlers, + _viewportSize = {}, + _currZoomLevel, + _startZoomLevel, + _translatePrefix, + _translateSufix, + _updateSizeInterval, + _itemsNeedUpdate, + _currPositionIndex = 0, + _offset = {}, + _slideSize = _getEmptyPoint(), // size of slide area, including spacing + _itemHolders, + _prevItemIndex, + _indexDiff = 0, // difference of indexes since last content update + _dragStartEvent, + _dragMoveEvent, + _dragEndEvent, + _dragCancelEvent, + _transformKey, + _pointerEventEnabled, + _isFixedPosition = true, + _likelyTouchDevice, + _modules = [], + _requestAF, + _cancelAF, + _initalClassName, + _initalWindowScrollY, + _oldIE, + _currentWindowScrollY, + _features, + _windowVisibleSize = {}, + _renderMaxResolution = false, + _orientationChangeTimeout, + + + // Registers PhotoSWipe module (History, Controller ...) + _registerModule = function(name, module) { + framework.extend(self, module.publicMethods); + _modules.push(name); + }, + + _getLoopedId = function(index) { + var numSlides = _getNumItems(); + if(index > numSlides - 1) { + return index - numSlides; + } else if(index < 0) { + return numSlides + index; + } + return index; + }, + + // Micro bind/trigger + _listeners = {}, + _listen = function(name, fn) { + if(!_listeners[name]) { + _listeners[name] = []; + } + return _listeners[name].push(fn); + }, + _shout = function(name) { + var listeners = _listeners[name]; + + if(listeners) { + var args = Array.prototype.slice.call(arguments); + args.shift(); + + for(var i = 0; i < listeners.length; i++) { + listeners[i].apply(self, args); + } + } + }, + + _getCurrentTime = function() { + return new Date().getTime(); + }, + _applyBgOpacity = function(opacity) { + _bgOpacity = opacity; + self.bg.style.opacity = opacity * _options.bgOpacity; + }, + + _applyZoomTransform = function(styleObj,x,y,zoom,item) { + if(!_renderMaxResolution || (item && item !== self.currItem) ) { + zoom = zoom / (item ? item.fitRatio : self.currItem.fitRatio); + } + + styleObj[_transformKey] = _translatePrefix + x + 'px, ' + y + 'px' + _translateSufix + ' scale(' + zoom + ')'; + }, + _applyCurrentZoomPan = function( allowRenderResolution ) { + if(_currZoomElementStyle) { + + if(allowRenderResolution) { + if(_currZoomLevel > self.currItem.fitRatio) { + if(!_renderMaxResolution) { + _setImageSize(self.currItem, false, true); + _renderMaxResolution = true; + } + } else { + if(_renderMaxResolution) { + _setImageSize(self.currItem); + _renderMaxResolution = false; + } + } + } + + + _applyZoomTransform(_currZoomElementStyle, _panOffset.x, _panOffset.y, _currZoomLevel); + } + }, + _applyZoomPanToItem = function(item) { + if(item.container) { + + _applyZoomTransform(item.container.style, + item.initialPosition.x, + item.initialPosition.y, + item.initialZoomLevel, + item); + } + }, + _setTranslateX = function(x, elStyle) { + elStyle[_transformKey] = _translatePrefix + x + 'px, 0px' + _translateSufix; + }, + _moveMainScroll = function(x, dragging) { + + if(!_options.loop && dragging) { + var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x, + delta = Math.round(x - _mainScrollPos.x); + + if( (newSlideIndexOffset < 0 && delta > 0) || + (newSlideIndexOffset >= _getNumItems() - 1 && delta < 0) ) { + x = _mainScrollPos.x + delta * _options.mainScrollEndFriction; + } + } + + _mainScrollPos.x = x; + _setTranslateX(x, _containerStyle); + }, + _calculatePanOffset = function(axis, zoomLevel) { + var m = _midZoomPoint[axis] - _offset[axis]; + return _startPanOffset[axis] + _currPanDist[axis] + m - m * ( zoomLevel / _startZoomLevel ); + }, + + _equalizePoints = function(p1, p2) { + p1.x = p2.x; + p1.y = p2.y; + if(p2.id) { + p1.id = p2.id; + } + }, + _roundPoint = function(p) { + p.x = Math.round(p.x); + p.y = Math.round(p.y); + }, + + _mouseMoveTimeout = null, + _onFirstMouseMove = function() { + // Wait until mouse move event is fired at least twice during 100ms + // We do this, because some mobile browsers trigger it on touchstart + if(_mouseMoveTimeout ) { + framework.unbind(document, 'mousemove', _onFirstMouseMove); + framework.addClass(template, 'pswp--has_mouse'); + _options.mouseUsed = true; + _shout('mouseUsed'); + } + _mouseMoveTimeout = setTimeout(function() { + _mouseMoveTimeout = null; + }, 100); + }, + + _bindEvents = function() { + framework.bind(document, 'keydown', self); + + if(_features.transform) { + // don't bind click event in browsers that don't support transform (mostly IE8) + framework.bind(self.scrollWrap, 'click', self); + } + + + if(!_options.mouseUsed) { + framework.bind(document, 'mousemove', _onFirstMouseMove); + } + + framework.bind(window, 'resize scroll orientationchange', self); + + _shout('bindEvents'); + }, + + _unbindEvents = function() { + framework.unbind(window, 'resize scroll orientationchange', self); + framework.unbind(window, 'scroll', _globalEventHandlers.scroll); + framework.unbind(document, 'keydown', self); + framework.unbind(document, 'mousemove', _onFirstMouseMove); + + if(_features.transform) { + framework.unbind(self.scrollWrap, 'click', self); + } + + if(_isDragging) { + framework.unbind(window, _upMoveEvents, self); + } + + clearTimeout(_orientationChangeTimeout); + + _shout('unbindEvents'); + }, + + _calculatePanBounds = function(zoomLevel, update) { + var bounds = _calculateItemSize( self.currItem, _viewportSize, zoomLevel ); + if(update) { + _currPanBounds = bounds; + } + return bounds; + }, + + _getMinZoomLevel = function(item) { + if(!item) { + item = self.currItem; + } + return item.initialZoomLevel; + }, + _getMaxZoomLevel = function(item) { + if(!item) { + item = self.currItem; + } + return item.w > 0 ? _options.maxSpreadZoom : 1; + }, + + // Return true if offset is out of the bounds + _modifyDestPanOffset = function(axis, destPanBounds, destPanOffset, destZoomLevel) { + if(destZoomLevel === self.currItem.initialZoomLevel) { + destPanOffset[axis] = self.currItem.initialPosition[axis]; + return true; + } else { + destPanOffset[axis] = _calculatePanOffset(axis, destZoomLevel); + + if(destPanOffset[axis] > destPanBounds.min[axis]) { + destPanOffset[axis] = destPanBounds.min[axis]; + return true; + } else if(destPanOffset[axis] < destPanBounds.max[axis] ) { + destPanOffset[axis] = destPanBounds.max[axis]; + return true; + } + } + return false; + }, + + _setupTransforms = function() { + + if(_transformKey) { + // setup 3d transforms + var allow3dTransform = _features.perspective && !_likelyTouchDevice; + _translatePrefix = 'translate' + (allow3dTransform ? '3d(' : '('); + _translateSufix = _features.perspective ? ', 0px)' : ')'; + return; + } + + // Override zoom/pan/move functions in case old browser is used (most likely IE) + // (so they use left/top/width/height, instead of CSS transform) + + _transformKey = 'left'; + framework.addClass(template, 'pswp--ie'); + + _setTranslateX = function(x, elStyle) { + elStyle.left = x + 'px'; + }; + _applyZoomPanToItem = function(item) { + + var zoomRatio = item.fitRatio > 1 ? 1 : item.fitRatio, + s = item.container.style, + w = zoomRatio * item.w, + h = zoomRatio * item.h; + + s.width = w + 'px'; + s.height = h + 'px'; + s.left = item.initialPosition.x + 'px'; + s.top = item.initialPosition.y + 'px'; + + }; + _applyCurrentZoomPan = function() { + if(_currZoomElementStyle) { + + var s = _currZoomElementStyle, + item = self.currItem, + zoomRatio = item.fitRatio > 1 ? 1 : item.fitRatio, + w = zoomRatio * item.w, + h = zoomRatio * item.h; + + s.width = w + 'px'; + s.height = h + 'px'; + + + s.left = _panOffset.x + 'px'; + s.top = _panOffset.y + 'px'; + } + + }; + }, + + _onKeyDown = function(e) { + var keydownAction = ''; + if(_options.escKey && e.keyCode === 27) { + keydownAction = 'close'; + } else if(_options.arrowKeys) { + if(e.keyCode === 37) { + keydownAction = 'prev'; + } else if(e.keyCode === 39) { + keydownAction = 'next'; + } + } + + if(keydownAction) { + // don't do anything if special key pressed to prevent from overriding default browser actions + // e.g. in Chrome on Mac cmd+arrow-left returns to previous page + if( !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey ) { + if(e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + self[keydownAction](); + } + } + }, + + _onGlobalClick = function(e) { + if(!e) { + return; + } + + // don't allow click event to pass through when triggering after drag or some other gesture + if(_moved || _zoomStarted || _mainScrollAnimating || _verticalDragInitiated) { + e.preventDefault(); + e.stopPropagation(); + } + }, + + _updatePageScrollOffset = function() { + self.setScrollOffset(0, framework.getScrollY()); + }; + + + + + + + +// Micro animation engine +var _animations = {}, + _numAnimations = 0, + _stopAnimation = function(name) { + if(_animations[name]) { + if(_animations[name].raf) { + _cancelAF( _animations[name].raf ); + } + _numAnimations--; + delete _animations[name]; + } + }, + _registerStartAnimation = function(name) { + if(_animations[name]) { + _stopAnimation(name); + } + if(!_animations[name]) { + _numAnimations++; + _animations[name] = {}; + } + }, + _stopAllAnimations = function() { + for (var prop in _animations) { + + if( _animations.hasOwnProperty( prop ) ) { + _stopAnimation(prop); + } + + } + }, + _animateProp = function(name, b, endProp, d, easingFn, onUpdate, onComplete) { + var startAnimTime = _getCurrentTime(), t; + _registerStartAnimation(name); + + var animloop = function(){ + if ( _animations[name] ) { + + t = _getCurrentTime() - startAnimTime; // time diff + //b - beginning (start prop) + //d - anim duration + + if ( t >= d ) { + _stopAnimation(name); + onUpdate(endProp); + if(onComplete) { + onComplete(); + } + return; + } + onUpdate( (endProp - b) * easingFn(t/d) + b ); + + _animations[name].raf = _requestAF(animloop); + } + }; + animloop(); + }; + + + +var publicMethods = { + + // make a few local variables and functions public + shout: _shout, + listen: _listen, + viewportSize: _viewportSize, + options: _options, + + isMainScrollAnimating: function() { + return _mainScrollAnimating; + }, + getZoomLevel: function() { + return _currZoomLevel; + }, + getCurrentIndex: function() { + return _currentItemIndex; + }, + isDragging: function() { + return _isDragging; + }, + isZooming: function() { + return _isZooming; + }, + setScrollOffset: function(x,y) { + _offset.x = x; + _currentWindowScrollY = _offset.y = y; + _shout('updateScrollOffset', _offset); + }, + applyZoomPan: function(zoomLevel,panX,panY,allowRenderResolution) { + _panOffset.x = panX; + _panOffset.y = panY; + _currZoomLevel = zoomLevel; + _applyCurrentZoomPan( allowRenderResolution ); + }, + + init: function() { + + if(_isOpen || _isDestroying) { + return; + } + + var i; + + self.framework = framework; // basic functionality + self.template = template; // root DOM element of PhotoSwipe + self.bg = framework.getChildByClass(template, 'pswp__bg'); + + _initalClassName = template.className; + _isOpen = true; + + _features = framework.detectFeatures(); + _requestAF = _features.raf; + _cancelAF = _features.caf; + _transformKey = _features.transform; + _oldIE = _features.oldIE; + + self.scrollWrap = framework.getChildByClass(template, 'pswp__scroll-wrap'); + self.container = framework.getChildByClass(self.scrollWrap, 'pswp__container'); + + _containerStyle = self.container.style; // for fast access + + // Objects that hold slides (there are only 3 in DOM) + self.itemHolders = _itemHolders = [ + {el:self.container.children[0] , wrap:0, index: -1}, + {el:self.container.children[1] , wrap:0, index: -1}, + {el:self.container.children[2] , wrap:0, index: -1} + ]; + + // hide nearby item holders until initial zoom animation finishes (to avoid extra Paints) + _itemHolders[0].el.style.display = _itemHolders[2].el.style.display = 'none'; + + _setupTransforms(); + + // Setup global events + _globalEventHandlers = { + resize: self.updateSize, + + // Fixes: iOS 10.3 resize event + // does not update scrollWrap.clientWidth instantly after resize + // https://github.com/dimsemenov/PhotoSwipe/issues/1315 + orientationchange: function() { + clearTimeout(_orientationChangeTimeout); + _orientationChangeTimeout = setTimeout(function() { + if(_viewportSize.x !== self.scrollWrap.clientWidth) { + self.updateSize(); + } + }, 500); + }, + scroll: _updatePageScrollOffset, + keydown: _onKeyDown, + click: _onGlobalClick + }; + + // disable show/hide effects on old browsers that don't support CSS animations or transforms, + // old IOS, Android and Opera mobile. Blackberry seems to work fine, even older models. + var oldPhone = _features.isOldIOSPhone || _features.isOldAndroid || _features.isMobileOpera; + if(!_features.animationName || !_features.transform || oldPhone) { + _options.showAnimationDuration = _options.hideAnimationDuration = 0; + } + + // init modules + for(i = 0; i < _modules.length; i++) { + self['init' + _modules[i]](); + } + + // init + if(UiClass) { + var ui = self.ui = new UiClass(self, framework); + ui.init(); + } + + _shout('firstUpdate'); + _currentItemIndex = _currentItemIndex || _options.index || 0; + // validate index + if( isNaN(_currentItemIndex) || _currentItemIndex < 0 || _currentItemIndex >= _getNumItems() ) { + _currentItemIndex = 0; + } + self.currItem = _getItemAt( _currentItemIndex ); + + + if(_features.isOldIOSPhone || _features.isOldAndroid) { + _isFixedPosition = false; + } + + template.setAttribute('aria-hidden', 'false'); + if(_options.modal) { + if(!_isFixedPosition) { + template.style.position = 'absolute'; + template.style.top = framework.getScrollY() + 'px'; + } else { + template.style.position = 'fixed'; + } + } + + if(_currentWindowScrollY === undefined) { + _shout('initialLayout'); + _currentWindowScrollY = _initalWindowScrollY = framework.getScrollY(); + } + + // add classes to root element of PhotoSwipe + var rootClasses = 'pswp--open '; + if(_options.mainClass) { + rootClasses += _options.mainClass + ' '; + } + if(_options.showHideOpacity) { + rootClasses += 'pswp--animate_opacity '; + } + rootClasses += _likelyTouchDevice ? 'pswp--touch' : 'pswp--notouch'; + rootClasses += _features.animationName ? ' pswp--css_animation' : ''; + rootClasses += _features.svg ? ' pswp--svg' : ''; + framework.addClass(template, rootClasses); + + self.updateSize(); + + // initial update + _containerShiftIndex = -1; + _indexDiff = null; + for(i = 0; i < NUM_HOLDERS; i++) { + _setTranslateX( (i+_containerShiftIndex) * _slideSize.x, _itemHolders[i].el.style); + } + + if(!_oldIE) { + framework.bind(self.scrollWrap, _downEvents, self); // no dragging for old IE + } + + _listen('initialZoomInEnd', function() { + self.setContent(_itemHolders[0], _currentItemIndex-1); + self.setContent(_itemHolders[2], _currentItemIndex+1); + + _itemHolders[0].el.style.display = _itemHolders[2].el.style.display = 'block'; + + if(_options.focus) { + // focus causes layout, + // which causes lag during the animation, + // that's why we delay it untill the initial zoom transition ends + template.focus(); + } + + + _bindEvents(); + }); + + // set content for center slide (first time) + self.setContent(_itemHolders[1], _currentItemIndex); + + self.updateCurrItem(); + + _shout('afterInit'); + + if(!_isFixedPosition) { + + // On all versions of iOS lower than 8.0, we check size of viewport every second. + // + // This is done to detect when Safari top & bottom bars appear, + // as this action doesn't trigger any events (like resize). + // + // On iOS8 they fixed this. + // + // 10 Nov 2014: iOS 7 usage ~40%. iOS 8 usage 56%. + + _updateSizeInterval = setInterval(function() { + if(!_numAnimations && !_isDragging && !_isZooming && (_currZoomLevel === self.currItem.initialZoomLevel) ) { + self.updateSize(); + } + }, 1000); + } + + framework.addClass(template, 'pswp--visible'); + }, + + // Close the gallery, then destroy it + close: function() { + if(!_isOpen) { + return; + } + + _isOpen = false; + _isDestroying = true; + _shout('close'); + _unbindEvents(); + + _showOrHide(self.currItem, null, true, self.destroy); + }, + + // destroys the gallery (unbinds events, cleans up intervals and timeouts to avoid memory leaks) + destroy: function() { + _shout('destroy'); + + if(_showOrHideTimeout) { + clearTimeout(_showOrHideTimeout); + } + + template.setAttribute('aria-hidden', 'true'); + template.className = _initalClassName; + + if(_updateSizeInterval) { + clearInterval(_updateSizeInterval); + } + + framework.unbind(self.scrollWrap, _downEvents, self); + + // we unbind scroll event at the end, as closing animation may depend on it + framework.unbind(window, 'scroll', self); + + _stopDragUpdateLoop(); + + _stopAllAnimations(); + + _listeners = null; + }, + + /** + * Pan image to position + * @param {Number} x + * @param {Number} y + * @param {Boolean} force Will ignore bounds if set to true. + */ + panTo: function(x,y,force) { + if(!force) { + if(x > _currPanBounds.min.x) { + x = _currPanBounds.min.x; + } else if(x < _currPanBounds.max.x) { + x = _currPanBounds.max.x; + } + + if(y > _currPanBounds.min.y) { + y = _currPanBounds.min.y; + } else if(y < _currPanBounds.max.y) { + y = _currPanBounds.max.y; + } + } + + _panOffset.x = x; + _panOffset.y = y; + _applyCurrentZoomPan(); + }, + + handleEvent: function (e) { + e = e || window.event; + if(_globalEventHandlers[e.type]) { + _globalEventHandlers[e.type](e); + } + }, + + + goTo: function(index) { + + index = _getLoopedId(index); + + var diff = index - _currentItemIndex; + _indexDiff = diff; + + _currentItemIndex = index; + self.currItem = _getItemAt( _currentItemIndex ); + _currPositionIndex -= diff; + + _moveMainScroll(_slideSize.x * _currPositionIndex); + + + _stopAllAnimations(); + _mainScrollAnimating = false; + + self.updateCurrItem(); + }, + next: function() { + self.goTo( _currentItemIndex + 1); + }, + prev: function() { + self.goTo( _currentItemIndex - 1); + }, + + // update current zoom/pan objects + updateCurrZoomItem: function(emulateSetContent) { + if(emulateSetContent) { + _shout('beforeChange', 0); + } + + // itemHolder[1] is middle (current) item + if(_itemHolders[1].el.children.length) { + var zoomElement = _itemHolders[1].el.children[0]; + if( framework.hasClass(zoomElement, 'pswp__zoom-wrap') ) { + _currZoomElementStyle = zoomElement.style; + } else { + _currZoomElementStyle = null; + } + } else { + _currZoomElementStyle = null; + } + + _currPanBounds = self.currItem.bounds; + _startZoomLevel = _currZoomLevel = self.currItem.initialZoomLevel; + + _panOffset.x = _currPanBounds.center.x; + _panOffset.y = _currPanBounds.center.y; + + if(emulateSetContent) { + _shout('afterChange'); + } + }, + + + invalidateCurrItems: function() { + _itemsNeedUpdate = true; + for(var i = 0; i < NUM_HOLDERS; i++) { + if( _itemHolders[i].item ) { + _itemHolders[i].item.needsUpdate = true; + } + } + }, + + updateCurrItem: function(beforeAnimation) { + + if(_indexDiff === 0) { + return; + } + + var diffAbs = Math.abs(_indexDiff), + tempHolder; + + if(beforeAnimation && diffAbs < 2) { + return; + } + + + self.currItem = _getItemAt( _currentItemIndex ); + _renderMaxResolution = false; + + _shout('beforeChange', _indexDiff); + + if(diffAbs >= NUM_HOLDERS) { + _containerShiftIndex += _indexDiff + (_indexDiff > 0 ? -NUM_HOLDERS : NUM_HOLDERS); + diffAbs = NUM_HOLDERS; + } + for(var i = 0; i < diffAbs; i++) { + if(_indexDiff > 0) { + tempHolder = _itemHolders.shift(); + _itemHolders[NUM_HOLDERS-1] = tempHolder; // move first to last + + _containerShiftIndex++; + _setTranslateX( (_containerShiftIndex+2) * _slideSize.x, tempHolder.el.style); + self.setContent(tempHolder, _currentItemIndex - diffAbs + i + 1 + 1); + } else { + tempHolder = _itemHolders.pop(); + _itemHolders.unshift( tempHolder ); // move last to first + + _containerShiftIndex--; + _setTranslateX( _containerShiftIndex * _slideSize.x, tempHolder.el.style); + self.setContent(tempHolder, _currentItemIndex + diffAbs - i - 1 - 1); + } + + } + + // reset zoom/pan on previous item + if(_currZoomElementStyle && Math.abs(_indexDiff) === 1) { + + var prevItem = _getItemAt(_prevItemIndex); + if(prevItem.initialZoomLevel !== _currZoomLevel) { + _calculateItemSize(prevItem , _viewportSize ); + _setImageSize(prevItem); + _applyZoomPanToItem( prevItem ); + } + + } + + // reset diff after update + _indexDiff = 0; + + self.updateCurrZoomItem(); + + _prevItemIndex = _currentItemIndex; + + _shout('afterChange'); + + }, + + + + updateSize: function(force) { + + if(!_isFixedPosition && _options.modal) { + var windowScrollY = framework.getScrollY(); + if(_currentWindowScrollY !== windowScrollY) { + template.style.top = windowScrollY + 'px'; + _currentWindowScrollY = windowScrollY; + } + if(!force && _windowVisibleSize.x === window.innerWidth && _windowVisibleSize.y === window.innerHeight) { + return; + } + _windowVisibleSize.x = window.innerWidth; + _windowVisibleSize.y = window.innerHeight; + + //template.style.width = _windowVisibleSize.x + 'px'; + template.style.height = _windowVisibleSize.y + 'px'; + } + + + + _viewportSize.x = self.scrollWrap.clientWidth; + _viewportSize.y = self.scrollWrap.clientHeight; + + _updatePageScrollOffset(); + + _slideSize.x = _viewportSize.x + Math.round(_viewportSize.x * _options.spacing); + _slideSize.y = _viewportSize.y; + + _moveMainScroll(_slideSize.x * _currPositionIndex); + + _shout('beforeResize'); // even may be used for example to switch image sources + + + // don't re-calculate size on inital size update + if(_containerShiftIndex !== undefined) { + + var holder, + item, + hIndex; + + for(var i = 0; i < NUM_HOLDERS; i++) { + holder = _itemHolders[i]; + _setTranslateX( (i+_containerShiftIndex) * _slideSize.x, holder.el.style); + + hIndex = _currentItemIndex+i-1; + + if(_options.loop && _getNumItems() > 2) { + hIndex = _getLoopedId(hIndex); + } + + // update zoom level on items and refresh source (if needsUpdate) + item = _getItemAt( hIndex ); + + // re-render gallery item if `needsUpdate`, + // or doesn't have `bounds` (entirely new slide object) + if( item && (_itemsNeedUpdate || item.needsUpdate || !item.bounds) ) { + + self.cleanSlide( item ); + + self.setContent( holder, hIndex ); + + // if "center" slide + if(i === 1) { + self.currItem = item; + self.updateCurrZoomItem(true); + } + + item.needsUpdate = false; + + } else if(holder.index === -1 && hIndex >= 0) { + // add content first time + self.setContent( holder, hIndex ); + } + if(item && item.container) { + _calculateItemSize(item, _viewportSize); + _setImageSize(item); + _applyZoomPanToItem( item ); + } + + } + _itemsNeedUpdate = false; + } + + _startZoomLevel = _currZoomLevel = self.currItem.initialZoomLevel; + _currPanBounds = self.currItem.bounds; + + if(_currPanBounds) { + _panOffset.x = _currPanBounds.center.x; + _panOffset.y = _currPanBounds.center.y; + _applyCurrentZoomPan( true ); + } + + _shout('resize'); + }, + + // Zoom current item to + zoomTo: function(destZoomLevel, centerPoint, speed, easingFn, updateFn) { + /* + if(destZoomLevel === 'fit') { + destZoomLevel = self.currItem.fitRatio; + } else if(destZoomLevel === 'fill') { + destZoomLevel = self.currItem.fillRatio; + } + */ + + if(centerPoint) { + _startZoomLevel = _currZoomLevel; + _midZoomPoint.x = Math.abs(centerPoint.x) - _panOffset.x ; + _midZoomPoint.y = Math.abs(centerPoint.y) - _panOffset.y ; + _equalizePoints(_startPanOffset, _panOffset); + } + + var destPanBounds = _calculatePanBounds(destZoomLevel, false), + destPanOffset = {}; + + _modifyDestPanOffset('x', destPanBounds, destPanOffset, destZoomLevel); + _modifyDestPanOffset('y', destPanBounds, destPanOffset, destZoomLevel); + + var initialZoomLevel = _currZoomLevel; + var initialPanOffset = { + x: _panOffset.x, + y: _panOffset.y + }; + + _roundPoint(destPanOffset); + + var onUpdate = function(now) { + if(now === 1) { + _currZoomLevel = destZoomLevel; + _panOffset.x = destPanOffset.x; + _panOffset.y = destPanOffset.y; + } else { + _currZoomLevel = (destZoomLevel - initialZoomLevel) * now + initialZoomLevel; + _panOffset.x = (destPanOffset.x - initialPanOffset.x) * now + initialPanOffset.x; + _panOffset.y = (destPanOffset.y - initialPanOffset.y) * now + initialPanOffset.y; + } + + if(updateFn) { + updateFn(now); + } + + _applyCurrentZoomPan( now === 1 ); + }; + + if(speed) { + _animateProp('customZoomTo', 0, 1, speed, easingFn || framework.easing.sine.inOut, onUpdate); + } else { + onUpdate(1); + } + } + + +}; + + +/*>>core*/ + +/*>>gestures*/ +/** + * Mouse/touch/pointer event handlers. + * + * separated from @core.js for readability + */ + +var MIN_SWIPE_DISTANCE = 30, + DIRECTION_CHECK_OFFSET = 10; // amount of pixels to drag to determine direction of swipe + +var _gestureStartTime, + _gestureCheckSpeedTime, + + // pool of objects that are used during dragging of zooming + p = {}, // first point + p2 = {}, // second point (for zoom gesture) + delta = {}, + _currPoint = {}, + _startPoint = {}, + _currPointers = [], + _startMainScrollPos = {}, + _releaseAnimData, + _posPoints = [], // array of points during dragging, used to determine type of gesture + _tempPoint = {}, + + _isZoomingIn, + _verticalDragInitiated, + _oldAndroidTouchEndTimeout, + _currZoomedItemIndex = 0, + _centerPoint = _getEmptyPoint(), + _lastReleaseTime = 0, + _isDragging, // at least one pointer is down + _isMultitouch, // at least two _pointers are down + _zoomStarted, // zoom level changed during zoom gesture + _moved, + _dragAnimFrame, + _mainScrollShifted, + _currentPoints, // array of current touch points + _isZooming, + _currPointsDistance, + _startPointsDistance, + _currPanBounds, + _mainScrollPos = _getEmptyPoint(), + _currZoomElementStyle, + _mainScrollAnimating, // true, if animation after swipe gesture is running + _midZoomPoint = _getEmptyPoint(), + _currCenterPoint = _getEmptyPoint(), + _direction, + _isFirstMove, + _opacityChanged, + _bgOpacity, + _wasOverInitialZoom, + + _isEqualPoints = function(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; + }, + _isNearbyPoints = function(touch0, touch1) { + return Math.abs(touch0.x - touch1.x) < DOUBLE_TAP_RADIUS && Math.abs(touch0.y - touch1.y) < DOUBLE_TAP_RADIUS; + }, + _calculatePointsDistance = function(p1, p2) { + _tempPoint.x = Math.abs( p1.x - p2.x ); + _tempPoint.y = Math.abs( p1.y - p2.y ); + return Math.sqrt(_tempPoint.x * _tempPoint.x + _tempPoint.y * _tempPoint.y); + }, + _stopDragUpdateLoop = function() { + if(_dragAnimFrame) { + _cancelAF(_dragAnimFrame); + _dragAnimFrame = null; + } + }, + _dragUpdateLoop = function() { + if(_isDragging) { + _dragAnimFrame = _requestAF(_dragUpdateLoop); + _renderMovement(); + } + }, + _canPan = function() { + return !(_options.scaleMode === 'fit' && _currZoomLevel === self.currItem.initialZoomLevel); + }, + + // find the closest parent DOM element + _closestElement = function(el, fn) { + if(!el || el === document) { + return false; + } + + // don't search elements above pswp__scroll-wrap + if(el.getAttribute('class') && el.getAttribute('class').indexOf('pswp__scroll-wrap') > -1 ) { + return false; + } + + if( fn(el) ) { + return el; + } + + return _closestElement(el.parentNode, fn); + }, + + _preventObj = {}, + _preventDefaultEventBehaviour = function(e, isDown) { + _preventObj.prevent = !_closestElement(e.target, _options.isClickableElement); + + _shout('preventDragEvent', e, isDown, _preventObj); + return _preventObj.prevent; + + }, + _convertTouchToPoint = function(touch, p) { + p.x = touch.pageX; + p.y = touch.pageY; + p.id = touch.identifier; + return p; + }, + _findCenterOfPoints = function(p1, p2, pCenter) { + pCenter.x = (p1.x + p2.x) * 0.5; + pCenter.y = (p1.y + p2.y) * 0.5; + }, + _pushPosPoint = function(time, x, y) { + if(time - _gestureCheckSpeedTime > 50) { + var o = _posPoints.length > 2 ? _posPoints.shift() : {}; + o.x = x; + o.y = y; + _posPoints.push(o); + _gestureCheckSpeedTime = time; + } + }, + + _calculateVerticalDragOpacityRatio = function() { + var yOffset = _panOffset.y - self.currItem.initialPosition.y; // difference between initial and current position + return 1 - Math.abs( yOffset / (_viewportSize.y / 2) ); + }, + + + // points pool, reused during touch events + _ePoint1 = {}, + _ePoint2 = {}, + _tempPointsArr = [], + _tempCounter, + _getTouchPoints = function(e) { + // clean up previous points, without recreating array + while(_tempPointsArr.length > 0) { + _tempPointsArr.pop(); + } + + if(!_pointerEventEnabled) { + if(e.type.indexOf('touch') > -1) { + + if(e.touches && e.touches.length > 0) { + _tempPointsArr[0] = _convertTouchToPoint(e.touches[0], _ePoint1); + if(e.touches.length > 1) { + _tempPointsArr[1] = _convertTouchToPoint(e.touches[1], _ePoint2); + } + } + + } else { + _ePoint1.x = e.pageX; + _ePoint1.y = e.pageY; + _ePoint1.id = ''; + _tempPointsArr[0] = _ePoint1;//_ePoint1; + } + } else { + _tempCounter = 0; + // we can use forEach, as pointer events are supported only in modern browsers + _currPointers.forEach(function(p) { + if(_tempCounter === 0) { + _tempPointsArr[0] = p; + } else if(_tempCounter === 1) { + _tempPointsArr[1] = p; + } + _tempCounter++; + + }); + } + return _tempPointsArr; + }, + + _panOrMoveMainScroll = function(axis, delta) { + + var panFriction, + overDiff = 0, + newOffset = _panOffset[axis] + delta[axis], + startOverDiff, + dir = delta[axis] > 0, + newMainScrollPosition = _mainScrollPos.x + delta.x, + mainScrollDiff = _mainScrollPos.x - _startMainScrollPos.x, + newPanPos, + newMainScrollPos; + + // calculate fdistance over the bounds and friction + if(newOffset > _currPanBounds.min[axis] || newOffset < _currPanBounds.max[axis]) { + panFriction = _options.panEndFriction; + // Linear increasing of friction, so at 1/4 of viewport it's at max value. + // Looks not as nice as was expected. Left for history. + // panFriction = (1 - (_panOffset[axis] + delta[axis] + panBounds.min[axis]) / (_viewportSize[axis] / 4) ); + } else { + panFriction = 1; + } + + newOffset = _panOffset[axis] + delta[axis] * panFriction; + + // move main scroll or start panning + if(_options.allowPanToNext || _currZoomLevel === self.currItem.initialZoomLevel) { + + + if(!_currZoomElementStyle) { + + newMainScrollPos = newMainScrollPosition; + + } else if(_direction === 'h' && axis === 'x' && !_zoomStarted ) { + + if(dir) { + if(newOffset > _currPanBounds.min[axis]) { + panFriction = _options.panEndFriction; + overDiff = _currPanBounds.min[axis] - newOffset; + startOverDiff = _currPanBounds.min[axis] - _startPanOffset[axis]; + } + + // drag right + if( (startOverDiff <= 0 || mainScrollDiff < 0) && _getNumItems() > 1 ) { + newMainScrollPos = newMainScrollPosition; + if(mainScrollDiff < 0 && newMainScrollPosition > _startMainScrollPos.x) { + newMainScrollPos = _startMainScrollPos.x; + } + } else { + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + newPanPos = newOffset; + } + + } + + } else { + + if(newOffset < _currPanBounds.max[axis] ) { + panFriction =_options.panEndFriction; + overDiff = newOffset - _currPanBounds.max[axis]; + startOverDiff = _startPanOffset[axis] - _currPanBounds.max[axis]; + } + + if( (startOverDiff <= 0 || mainScrollDiff > 0) && _getNumItems() > 1 ) { + newMainScrollPos = newMainScrollPosition; + + if(mainScrollDiff > 0 && newMainScrollPosition < _startMainScrollPos.x) { + newMainScrollPos = _startMainScrollPos.x; + } + + } else { + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + newPanPos = newOffset; + } + } + + } + + + // + } + + if(axis === 'x') { + + if(newMainScrollPos !== undefined) { + _moveMainScroll(newMainScrollPos, true); + if(newMainScrollPos === _startMainScrollPos.x) { + _mainScrollShifted = false; + } else { + _mainScrollShifted = true; + } + } + + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + if(newPanPos !== undefined) { + _panOffset.x = newPanPos; + } else if(!_mainScrollShifted) { + _panOffset.x += delta.x * panFriction; + } + } + + return newMainScrollPos !== undefined; + } + + } + + if(!_mainScrollAnimating) { + + if(!_mainScrollShifted) { + if(_currZoomLevel > self.currItem.fitRatio) { + _panOffset[axis] += delta[axis] * panFriction; + + } + } + + + } + + }, + + // Pointerdown/touchstart/mousedown handler + _onDragStart = function(e) { + + // Allow dragging only via left mouse button. + // As this handler is not added in IE8 - we ignore e.which + // + // http://www.quirksmode.org/js/events_properties.html + // https://developer.mozilla.org/en-US/docs/Web/API/event.button + if(e.type === 'mousedown' && e.button > 0 ) { + return; + } + + if(_initialZoomRunning) { + e.preventDefault(); + return; + } + + if(_oldAndroidTouchEndTimeout && e.type === 'mousedown') { + return; + } + + if(_preventDefaultEventBehaviour(e, true)) { + e.preventDefault(); + } + + + + _shout('pointerDown'); + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + if(pointerIndex < 0) { + pointerIndex = _currPointers.length; + } + _currPointers[pointerIndex] = {x:e.pageX, y:e.pageY, id: e.pointerId}; + } + + + + var startPointsList = _getTouchPoints(e), + numPoints = startPointsList.length; + + _currentPoints = null; + + _stopAllAnimations(); + + // init drag + if(!_isDragging || numPoints === 1) { + + + + _isDragging = _isFirstMove = true; + framework.bind(window, _upMoveEvents, self); + + _isZoomingIn = + _wasOverInitialZoom = + _opacityChanged = + _verticalDragInitiated = + _mainScrollShifted = + _moved = + _isMultitouch = + _zoomStarted = false; + + _direction = null; + + _shout('firstTouchStart', startPointsList); + + _equalizePoints(_startPanOffset, _panOffset); + + _currPanDist.x = _currPanDist.y = 0; + _equalizePoints(_currPoint, startPointsList[0]); + _equalizePoints(_startPoint, _currPoint); + + //_equalizePoints(_startMainScrollPos, _mainScrollPos); + _startMainScrollPos.x = _slideSize.x * _currPositionIndex; + + _posPoints = [{ + x: _currPoint.x, + y: _currPoint.y + }]; + + _gestureCheckSpeedTime = _gestureStartTime = _getCurrentTime(); + + //_mainScrollAnimationEnd(true); + _calculatePanBounds( _currZoomLevel, true ); + + // Start rendering + _stopDragUpdateLoop(); + _dragUpdateLoop(); + + } + + // init zoom + if(!_isZooming && numPoints > 1 && !_mainScrollAnimating && !_mainScrollShifted) { + _startZoomLevel = _currZoomLevel; + _zoomStarted = false; // true if zoom changed at least once + + _isZooming = _isMultitouch = true; + _currPanDist.y = _currPanDist.x = 0; + + _equalizePoints(_startPanOffset, _panOffset); + + _equalizePoints(p, startPointsList[0]); + _equalizePoints(p2, startPointsList[1]); + + _findCenterOfPoints(p, p2, _currCenterPoint); + + _midZoomPoint.x = Math.abs(_currCenterPoint.x) - _panOffset.x; + _midZoomPoint.y = Math.abs(_currCenterPoint.y) - _panOffset.y; + _currPointsDistance = _startPointsDistance = _calculatePointsDistance(p, p2); + } + + + }, + + // Pointermove/touchmove/mousemove handler + _onDragMove = function(e) { + + e.preventDefault(); + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + if(pointerIndex > -1) { + var p = _currPointers[pointerIndex]; + p.x = e.pageX; + p.y = e.pageY; + } + } + + if(_isDragging) { + var touchesList = _getTouchPoints(e); + if(!_direction && !_moved && !_isZooming) { + + if(_mainScrollPos.x !== _slideSize.x * _currPositionIndex) { + // if main scroll position is shifted – direction is always horizontal + _direction = 'h'; + } else { + var diff = Math.abs(touchesList[0].x - _currPoint.x) - Math.abs(touchesList[0].y - _currPoint.y); + // check the direction of movement + if(Math.abs(diff) >= DIRECTION_CHECK_OFFSET) { + _direction = diff > 0 ? 'h' : 'v'; + _currentPoints = touchesList; + } + } + + } else { + _currentPoints = touchesList; + } + } + }, + // + _renderMovement = function() { + + if(!_currentPoints) { + return; + } + + var numPoints = _currentPoints.length; + + if(numPoints === 0) { + return; + } + + _equalizePoints(p, _currentPoints[0]); + + delta.x = p.x - _currPoint.x; + delta.y = p.y - _currPoint.y; + + if(_isZooming && numPoints > 1) { + // Handle behaviour for more than 1 point + + _currPoint.x = p.x; + _currPoint.y = p.y; + + // check if one of two points changed + if( !delta.x && !delta.y && _isEqualPoints(_currentPoints[1], p2) ) { + return; + } + + _equalizePoints(p2, _currentPoints[1]); + + + if(!_zoomStarted) { + _zoomStarted = true; + _shout('zoomGestureStarted'); + } + + // Distance between two points + var pointsDistance = _calculatePointsDistance(p,p2); + + var zoomLevel = _calculateZoomLevel(pointsDistance); + + // slightly over the of initial zoom level + if(zoomLevel > self.currItem.initialZoomLevel + self.currItem.initialZoomLevel / 15) { + _wasOverInitialZoom = true; + } + + // Apply the friction if zoom level is out of the bounds + var zoomFriction = 1, + minZoomLevel = _getMinZoomLevel(), + maxZoomLevel = _getMaxZoomLevel(); + + if ( zoomLevel < minZoomLevel ) { + + if(_options.pinchToClose && !_wasOverInitialZoom && _startZoomLevel <= self.currItem.initialZoomLevel) { + // fade out background if zooming out + var minusDiff = minZoomLevel - zoomLevel; + var percent = 1 - minusDiff / (minZoomLevel / 1.2); + + _applyBgOpacity(percent); + _shout('onPinchClose', percent); + _opacityChanged = true; + } else { + zoomFriction = (minZoomLevel - zoomLevel) / minZoomLevel; + if(zoomFriction > 1) { + zoomFriction = 1; + } + zoomLevel = minZoomLevel - zoomFriction * (minZoomLevel / 3); + } + + } else if ( zoomLevel > maxZoomLevel ) { + // 1.5 - extra zoom level above the max. E.g. if max is x6, real max 6 + 1.5 = 7.5 + zoomFriction = (zoomLevel - maxZoomLevel) / ( minZoomLevel * 6 ); + if(zoomFriction > 1) { + zoomFriction = 1; + } + zoomLevel = maxZoomLevel + zoomFriction * minZoomLevel; + } + + if(zoomFriction < 0) { + zoomFriction = 0; + } + + // distance between touch points after friction is applied + _currPointsDistance = pointsDistance; + + // _centerPoint - The point in the middle of two pointers + _findCenterOfPoints(p, p2, _centerPoint); + + // paning with two pointers pressed + _currPanDist.x += _centerPoint.x - _currCenterPoint.x; + _currPanDist.y += _centerPoint.y - _currCenterPoint.y; + _equalizePoints(_currCenterPoint, _centerPoint); + + _panOffset.x = _calculatePanOffset('x', zoomLevel); + _panOffset.y = _calculatePanOffset('y', zoomLevel); + + _isZoomingIn = zoomLevel > _currZoomLevel; + _currZoomLevel = zoomLevel; + _applyCurrentZoomPan(); + + } else { + + // handle behaviour for one point (dragging or panning) + + if(!_direction) { + return; + } + + if(_isFirstMove) { + _isFirstMove = false; + + // subtract drag distance that was used during the detection direction + + if( Math.abs(delta.x) >= DIRECTION_CHECK_OFFSET) { + delta.x -= _currentPoints[0].x - _startPoint.x; + } + + if( Math.abs(delta.y) >= DIRECTION_CHECK_OFFSET) { + delta.y -= _currentPoints[0].y - _startPoint.y; + } + } + + _currPoint.x = p.x; + _currPoint.y = p.y; + + // do nothing if pointers position hasn't changed + if(delta.x === 0 && delta.y === 0) { + return; + } + + if(_direction === 'v' && _options.closeOnVerticalDrag) { + if(!_canPan()) { + _currPanDist.y += delta.y; + _panOffset.y += delta.y; + + var opacityRatio = _calculateVerticalDragOpacityRatio(); + + _verticalDragInitiated = true; + _shout('onVerticalDrag', opacityRatio); + + _applyBgOpacity(opacityRatio); + _applyCurrentZoomPan(); + return ; + } + } + + _pushPosPoint(_getCurrentTime(), p.x, p.y); + + _moved = true; + _currPanBounds = self.currItem.bounds; + + var mainScrollChanged = _panOrMoveMainScroll('x', delta); + if(!mainScrollChanged) { + _panOrMoveMainScroll('y', delta); + + _roundPoint(_panOffset); + _applyCurrentZoomPan(); + } + + } + + }, + + // Pointerup/pointercancel/touchend/touchcancel/mouseup event handler + _onDragRelease = function(e) { + + if(_features.isOldAndroid ) { + + if(_oldAndroidTouchEndTimeout && e.type === 'mouseup') { + return; + } + + // on Android (v4.1, 4.2, 4.3 & possibly older) + // ghost mousedown/up event isn't preventable via e.preventDefault, + // which causes fake mousedown event + // so we block mousedown/up for 600ms + if( e.type.indexOf('touch') > -1 ) { + clearTimeout(_oldAndroidTouchEndTimeout); + _oldAndroidTouchEndTimeout = setTimeout(function() { + _oldAndroidTouchEndTimeout = 0; + }, 600); + } + + } + + _shout('pointerUp'); + + if(_preventDefaultEventBehaviour(e, false)) { + e.preventDefault(); + } + + var releasePoint; + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + + if(pointerIndex > -1) { + releasePoint = _currPointers.splice(pointerIndex, 1)[0]; + + if(navigator.pointerEnabled) { + releasePoint.type = e.pointerType || 'mouse'; + } else { + var MSPOINTER_TYPES = { + 4: 'mouse', // event.MSPOINTER_TYPE_MOUSE + 2: 'touch', // event.MSPOINTER_TYPE_TOUCH + 3: 'pen' // event.MSPOINTER_TYPE_PEN + }; + releasePoint.type = MSPOINTER_TYPES[e.pointerType]; + + if(!releasePoint.type) { + releasePoint.type = e.pointerType || 'mouse'; + } + } + + } + } + + var touchList = _getTouchPoints(e), + gestureType, + numPoints = touchList.length; + + if(e.type === 'mouseup') { + numPoints = 0; + } + + // Do nothing if there were 3 touch points or more + if(numPoints === 2) { + _currentPoints = null; + return true; + } + + // if second pointer released + if(numPoints === 1) { + _equalizePoints(_startPoint, touchList[0]); + } + + + // pointer hasn't moved, send "tap release" point + if(numPoints === 0 && !_direction && !_mainScrollAnimating) { + if(!releasePoint) { + if(e.type === 'mouseup') { + releasePoint = {x: e.pageX, y: e.pageY, type:'mouse'}; + } else if(e.changedTouches && e.changedTouches[0]) { + releasePoint = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY, type:'touch'}; + } + } + + _shout('touchRelease', e, releasePoint); + } + + // Difference in time between releasing of two last touch points (zoom gesture) + var releaseTimeDiff = -1; + + // Gesture completed, no pointers left + if(numPoints === 0) { + _isDragging = false; + framework.unbind(window, _upMoveEvents, self); + + _stopDragUpdateLoop(); + + if(_isZooming) { + // Two points released at the same time + releaseTimeDiff = 0; + } else if(_lastReleaseTime !== -1) { + releaseTimeDiff = _getCurrentTime() - _lastReleaseTime; + } + } + _lastReleaseTime = numPoints === 1 ? _getCurrentTime() : -1; + + if(releaseTimeDiff !== -1 && releaseTimeDiff < 150) { + gestureType = 'zoom'; + } else { + gestureType = 'swipe'; + } + + if(_isZooming && numPoints < 2) { + _isZooming = false; + + // Only second point released + if(numPoints === 1) { + gestureType = 'zoomPointerUp'; + } + _shout('zoomGestureEnded'); + } + + _currentPoints = null; + if(!_moved && !_zoomStarted && !_mainScrollAnimating && !_verticalDragInitiated) { + // nothing to animate + return; + } + + _stopAllAnimations(); + + + if(!_releaseAnimData) { + _releaseAnimData = _initDragReleaseAnimationData(); + } + + _releaseAnimData.calculateSwipeSpeed('x'); + + + if(_verticalDragInitiated) { + + var opacityRatio = _calculateVerticalDragOpacityRatio(); + + if(opacityRatio < _options.verticalDragRange) { + self.close(); + } else { + var initalPanY = _panOffset.y, + initialBgOpacity = _bgOpacity; + + _animateProp('verticalDrag', 0, 1, 300, framework.easing.cubic.out, function(now) { + + _panOffset.y = (self.currItem.initialPosition.y - initalPanY) * now + initalPanY; + + _applyBgOpacity( (1 - initialBgOpacity) * now + initialBgOpacity ); + _applyCurrentZoomPan(); + }); + + _shout('onVerticalDrag', 1); + } + + return; + } + + + // main scroll + if( (_mainScrollShifted || _mainScrollAnimating) && numPoints === 0) { + var itemChanged = _finishSwipeMainScrollGesture(gestureType, _releaseAnimData); + if(itemChanged) { + return; + } + gestureType = 'zoomPointerUp'; + } + + // prevent zoom/pan animation when main scroll animation runs + if(_mainScrollAnimating) { + return; + } + + // Complete simple zoom gesture (reset zoom level if it's out of the bounds) + if(gestureType !== 'swipe') { + _completeZoomGesture(); + return; + } + + // Complete pan gesture if main scroll is not shifted, and it's possible to pan current image + if(!_mainScrollShifted && _currZoomLevel > self.currItem.fitRatio) { + _completePanGesture(_releaseAnimData); + } + }, + + + // Returns object with data about gesture + // It's created only once and then reused + _initDragReleaseAnimationData = function() { + // temp local vars + var lastFlickDuration, + tempReleasePos; + + // s = this + var s = { + lastFlickOffset: {}, + lastFlickDist: {}, + lastFlickSpeed: {}, + slowDownRatio: {}, + slowDownRatioReverse: {}, + speedDecelerationRatio: {}, + speedDecelerationRatioAbs: {}, + distanceOffset: {}, + backAnimDestination: {}, + backAnimStarted: {}, + calculateSwipeSpeed: function(axis) { + + + if( _posPoints.length > 1) { + lastFlickDuration = _getCurrentTime() - _gestureCheckSpeedTime + 50; + tempReleasePos = _posPoints[_posPoints.length-2][axis]; + } else { + lastFlickDuration = _getCurrentTime() - _gestureStartTime; // total gesture duration + tempReleasePos = _startPoint[axis]; + } + s.lastFlickOffset[axis] = _currPoint[axis] - tempReleasePos; + s.lastFlickDist[axis] = Math.abs(s.lastFlickOffset[axis]); + if(s.lastFlickDist[axis] > 20) { + s.lastFlickSpeed[axis] = s.lastFlickOffset[axis] / lastFlickDuration; + } else { + s.lastFlickSpeed[axis] = 0; + } + if( Math.abs(s.lastFlickSpeed[axis]) < 0.1 ) { + s.lastFlickSpeed[axis] = 0; + } + + s.slowDownRatio[axis] = 0.95; + s.slowDownRatioReverse[axis] = 1 - s.slowDownRatio[axis]; + s.speedDecelerationRatio[axis] = 1; + }, + + calculateOverBoundsAnimOffset: function(axis, speed) { + if(!s.backAnimStarted[axis]) { + + if(_panOffset[axis] > _currPanBounds.min[axis]) { + s.backAnimDestination[axis] = _currPanBounds.min[axis]; + + } else if(_panOffset[axis] < _currPanBounds.max[axis]) { + s.backAnimDestination[axis] = _currPanBounds.max[axis]; + } + + if(s.backAnimDestination[axis] !== undefined) { + s.slowDownRatio[axis] = 0.7; + s.slowDownRatioReverse[axis] = 1 - s.slowDownRatio[axis]; + if(s.speedDecelerationRatioAbs[axis] < 0.05) { + + s.lastFlickSpeed[axis] = 0; + s.backAnimStarted[axis] = true; + + _animateProp('bounceZoomPan'+axis,_panOffset[axis], + s.backAnimDestination[axis], + speed || 300, + framework.easing.sine.out, + function(pos) { + _panOffset[axis] = pos; + _applyCurrentZoomPan(); + } + ); + + } + } + } + }, + + // Reduces the speed by slowDownRatio (per 10ms) + calculateAnimOffset: function(axis) { + if(!s.backAnimStarted[axis]) { + s.speedDecelerationRatio[axis] = s.speedDecelerationRatio[axis] * (s.slowDownRatio[axis] + + s.slowDownRatioReverse[axis] - + s.slowDownRatioReverse[axis] * s.timeDiff / 10); + + s.speedDecelerationRatioAbs[axis] = Math.abs(s.lastFlickSpeed[axis] * s.speedDecelerationRatio[axis]); + s.distanceOffset[axis] = s.lastFlickSpeed[axis] * s.speedDecelerationRatio[axis] * s.timeDiff; + _panOffset[axis] += s.distanceOffset[axis]; + + } + }, + + panAnimLoop: function() { + if ( _animations.zoomPan ) { + _animations.zoomPan.raf = _requestAF(s.panAnimLoop); + + s.now = _getCurrentTime(); + s.timeDiff = s.now - s.lastNow; + s.lastNow = s.now; + + s.calculateAnimOffset('x'); + s.calculateAnimOffset('y'); + + _applyCurrentZoomPan(); + + s.calculateOverBoundsAnimOffset('x'); + s.calculateOverBoundsAnimOffset('y'); + + + if (s.speedDecelerationRatioAbs.x < 0.05 && s.speedDecelerationRatioAbs.y < 0.05) { + + // round pan position + _panOffset.x = Math.round(_panOffset.x); + _panOffset.y = Math.round(_panOffset.y); + _applyCurrentZoomPan(); + + _stopAnimation('zoomPan'); + return; + } + } + + } + }; + return s; + }, + + _completePanGesture = function(animData) { + // calculate swipe speed for Y axis (paanning) + animData.calculateSwipeSpeed('y'); + + _currPanBounds = self.currItem.bounds; + + animData.backAnimDestination = {}; + animData.backAnimStarted = {}; + + // Avoid acceleration animation if speed is too low + if(Math.abs(animData.lastFlickSpeed.x) <= 0.05 && Math.abs(animData.lastFlickSpeed.y) <= 0.05 ) { + animData.speedDecelerationRatioAbs.x = animData.speedDecelerationRatioAbs.y = 0; + + // Run pan drag release animation. E.g. if you drag image and release finger without momentum. + animData.calculateOverBoundsAnimOffset('x'); + animData.calculateOverBoundsAnimOffset('y'); + return true; + } + + // Animation loop that controls the acceleration after pan gesture ends + _registerStartAnimation('zoomPan'); + animData.lastNow = _getCurrentTime(); + animData.panAnimLoop(); + }, + + + _finishSwipeMainScrollGesture = function(gestureType, _releaseAnimData) { + var itemChanged; + if(!_mainScrollAnimating) { + _currZoomedItemIndex = _currentItemIndex; + } + + + + var itemsDiff; + + if(gestureType === 'swipe') { + var totalShiftDist = _currPoint.x - _startPoint.x, + isFastLastFlick = _releaseAnimData.lastFlickDist.x < 10; + + // if container is shifted for more than MIN_SWIPE_DISTANCE, + // and last flick gesture was in right direction + if(totalShiftDist > MIN_SWIPE_DISTANCE && + (isFastLastFlick || _releaseAnimData.lastFlickOffset.x > 20) ) { + // go to prev item + itemsDiff = -1; + } else if(totalShiftDist < -MIN_SWIPE_DISTANCE && + (isFastLastFlick || _releaseAnimData.lastFlickOffset.x < -20) ) { + // go to next item + itemsDiff = 1; + } + } + + var nextCircle; + + if(itemsDiff) { + + _currentItemIndex += itemsDiff; + + if(_currentItemIndex < 0) { + _currentItemIndex = _options.loop ? _getNumItems()-1 : 0; + nextCircle = true; + } else if(_currentItemIndex >= _getNumItems()) { + _currentItemIndex = _options.loop ? 0 : _getNumItems()-1; + nextCircle = true; + } + + if(!nextCircle || _options.loop) { + _indexDiff += itemsDiff; + _currPositionIndex -= itemsDiff; + itemChanged = true; + } + + + + } + + var animateToX = _slideSize.x * _currPositionIndex; + var animateToDist = Math.abs( animateToX - _mainScrollPos.x ); + var finishAnimDuration; + + + if(!itemChanged && animateToX > _mainScrollPos.x !== _releaseAnimData.lastFlickSpeed.x > 0) { + // "return to current" duration, e.g. when dragging from slide 0 to -1 + finishAnimDuration = 333; + } else { + finishAnimDuration = Math.abs(_releaseAnimData.lastFlickSpeed.x) > 0 ? + animateToDist / Math.abs(_releaseAnimData.lastFlickSpeed.x) : + 333; + + finishAnimDuration = Math.min(finishAnimDuration, 400); + finishAnimDuration = Math.max(finishAnimDuration, 250); + } + + if(_currZoomedItemIndex === _currentItemIndex) { + itemChanged = false; + } + + _mainScrollAnimating = true; + + _shout('mainScrollAnimStart'); + + _animateProp('mainScroll', _mainScrollPos.x, animateToX, finishAnimDuration, framework.easing.cubic.out, + _moveMainScroll, + function() { + _stopAllAnimations(); + _mainScrollAnimating = false; + _currZoomedItemIndex = -1; + + if(itemChanged || _currZoomedItemIndex !== _currentItemIndex) { + self.updateCurrItem(); + } + + _shout('mainScrollAnimComplete'); + } + ); + + if(itemChanged) { + self.updateCurrItem(true); + } + + return itemChanged; + }, + + _calculateZoomLevel = function(touchesDistance) { + return 1 / _startPointsDistance * touchesDistance * _startZoomLevel; + }, + + // Resets zoom if it's out of bounds + _completeZoomGesture = function() { + var destZoomLevel = _currZoomLevel, + minZoomLevel = _getMinZoomLevel(), + maxZoomLevel = _getMaxZoomLevel(); + + if ( _currZoomLevel < minZoomLevel ) { + destZoomLevel = minZoomLevel; + } else if ( _currZoomLevel > maxZoomLevel ) { + destZoomLevel = maxZoomLevel; + } + + var destOpacity = 1, + onUpdate, + initialOpacity = _bgOpacity; + + if(_opacityChanged && !_isZoomingIn && !_wasOverInitialZoom && _currZoomLevel < minZoomLevel) { + //_closedByScroll = true; + self.close(); + return true; + } + + if(_opacityChanged) { + onUpdate = function(now) { + _applyBgOpacity( (destOpacity - initialOpacity) * now + initialOpacity ); + }; + } + + self.zoomTo(destZoomLevel, 0, 200, framework.easing.cubic.out, onUpdate); + return true; + }; + + +_registerModule('Gestures', { + publicMethods: { + + initGestures: function() { + + // helper function that builds touch/pointer/mouse events + var addEventNames = function(pref, down, move, up, cancel) { + _dragStartEvent = pref + down; + _dragMoveEvent = pref + move; + _dragEndEvent = pref + up; + if(cancel) { + _dragCancelEvent = pref + cancel; + } else { + _dragCancelEvent = ''; + } + }; + + _pointerEventEnabled = _features.pointerEvent; + if(_pointerEventEnabled && _features.touch) { + // we don't need touch events, if browser supports pointer events + _features.touch = false; + } + + if(_pointerEventEnabled) { + if(navigator.pointerEnabled) { + addEventNames('pointer', 'down', 'move', 'up', 'cancel'); + } else { + // IE10 pointer events are case-sensitive + addEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel'); + } + } else if(_features.touch) { + addEventNames('touch', 'start', 'move', 'end', 'cancel'); + _likelyTouchDevice = true; + } else { + addEventNames('mouse', 'down', 'move', 'up'); + } + + _upMoveEvents = _dragMoveEvent + ' ' + _dragEndEvent + ' ' + _dragCancelEvent; + _downEvents = _dragStartEvent; + + if(_pointerEventEnabled && !_likelyTouchDevice) { + _likelyTouchDevice = (navigator.maxTouchPoints > 1) || (navigator.msMaxTouchPoints > 1); + } + // make variable public + self.likelyTouchDevice = _likelyTouchDevice; + + _globalEventHandlers[_dragStartEvent] = _onDragStart; + _globalEventHandlers[_dragMoveEvent] = _onDragMove; + _globalEventHandlers[_dragEndEvent] = _onDragRelease; // the Kraken + + if(_dragCancelEvent) { + _globalEventHandlers[_dragCancelEvent] = _globalEventHandlers[_dragEndEvent]; + } + + // Bind mouse events on device with detected hardware touch support, in case it supports multiple types of input. + if(_features.touch) { + _downEvents += ' mousedown'; + _upMoveEvents += ' mousemove mouseup'; + _globalEventHandlers.mousedown = _globalEventHandlers[_dragStartEvent]; + _globalEventHandlers.mousemove = _globalEventHandlers[_dragMoveEvent]; + _globalEventHandlers.mouseup = _globalEventHandlers[_dragEndEvent]; + } + + if(!_likelyTouchDevice) { + // don't allow pan to next slide from zoomed state on Desktop + _options.allowPanToNext = false; + } + } + + } +}); + + +/*>>gestures*/ + +/*>>show-hide-transition*/ +/** + * show-hide-transition.js: + * + * Manages initial opening or closing transition. + * + * If you're not planning to use transition for gallery at all, + * you may set options hideAnimationDuration and showAnimationDuration to 0, + * and just delete startAnimation function. + * + */ + + +var _showOrHideTimeout, + _showOrHide = function(item, img, out, completeFn) { + + if(_showOrHideTimeout) { + clearTimeout(_showOrHideTimeout); + } + + _initialZoomRunning = true; + _initialContentSet = true; + + // dimensions of small thumbnail {x:,y:,w:}. + // Height is optional, as calculated based on large image. + var thumbBounds; + if(item.initialLayout) { + thumbBounds = item.initialLayout; + item.initialLayout = null; + } else { + thumbBounds = _options.getThumbBoundsFn && _options.getThumbBoundsFn(_currentItemIndex); + } + + var duration = out ? _options.hideAnimationDuration : _options.showAnimationDuration; + + var onComplete = function() { + _stopAnimation('initialZoom'); + if(!out) { + _applyBgOpacity(1); + if(img) { + img.style.display = 'block'; + } + framework.addClass(template, 'pswp--animated-in'); + _shout('initialZoom' + (out ? 'OutEnd' : 'InEnd')); + } else { + self.template.removeAttribute('style'); + self.bg.removeAttribute('style'); + } + + if(completeFn) { + completeFn(); + } + _initialZoomRunning = false; + }; + + // if bounds aren't provided, just open gallery without animation + if(!duration || !thumbBounds || thumbBounds.x === undefined) { + + _shout('initialZoom' + (out ? 'Out' : 'In') ); + + _currZoomLevel = item.initialZoomLevel; + _equalizePoints(_panOffset, item.initialPosition ); + _applyCurrentZoomPan(); + + template.style.opacity = out ? 0 : 1; + _applyBgOpacity(1); + + if(duration) { + setTimeout(function() { + onComplete(); + }, duration); + } else { + onComplete(); + } + + return; + } + + var startAnimation = function() { + var closeWithRaf = _closedByScroll, + fadeEverything = !self.currItem.src || self.currItem.loadError || _options.showHideOpacity; + + // apply hw-acceleration to image + if(item.miniImg) { + item.miniImg.style.webkitBackfaceVisibility = 'hidden'; + } + + if(!out) { + _currZoomLevel = thumbBounds.w / item.w; + _panOffset.x = thumbBounds.x; + _panOffset.y = thumbBounds.y - _initalWindowScrollY; + + self[fadeEverything ? 'template' : 'bg'].style.opacity = 0.001; + _applyCurrentZoomPan(); + } + + _registerStartAnimation('initialZoom'); + + if(out && !closeWithRaf) { + framework.removeClass(template, 'pswp--animated-in'); + } + + if(fadeEverything) { + if(out) { + framework[ (closeWithRaf ? 'remove' : 'add') + 'Class' ](template, 'pswp--animate_opacity'); + } else { + setTimeout(function() { + framework.addClass(template, 'pswp--animate_opacity'); + }, 30); + } + } + + _showOrHideTimeout = setTimeout(function() { + + _shout('initialZoom' + (out ? 'Out' : 'In') ); + + + if(!out) { + + // "in" animation always uses CSS transitions (instead of rAF). + // CSS transition work faster here, + // as developer may also want to animate other things, + // like ui on top of sliding area, which can be animated just via CSS + + _currZoomLevel = item.initialZoomLevel; + _equalizePoints(_panOffset, item.initialPosition ); + _applyCurrentZoomPan(); + _applyBgOpacity(1); + + if(fadeEverything) { + template.style.opacity = 1; + } else { + _applyBgOpacity(1); + } + + _showOrHideTimeout = setTimeout(onComplete, duration + 20); + } else { + + // "out" animation uses rAF only when PhotoSwipe is closed by browser scroll, to recalculate position + var destZoomLevel = thumbBounds.w / item.w, + initialPanOffset = { + x: _panOffset.x, + y: _panOffset.y + }, + initialZoomLevel = _currZoomLevel, + initalBgOpacity = _bgOpacity, + onUpdate = function(now) { + + if(now === 1) { + _currZoomLevel = destZoomLevel; + _panOffset.x = thumbBounds.x; + _panOffset.y = thumbBounds.y - _currentWindowScrollY; + } else { + _currZoomLevel = (destZoomLevel - initialZoomLevel) * now + initialZoomLevel; + _panOffset.x = (thumbBounds.x - initialPanOffset.x) * now + initialPanOffset.x; + _panOffset.y = (thumbBounds.y - _currentWindowScrollY - initialPanOffset.y) * now + initialPanOffset.y; + } + + _applyCurrentZoomPan(); + if(fadeEverything) { + template.style.opacity = 1 - now; + } else { + _applyBgOpacity( initalBgOpacity - now * initalBgOpacity ); + } + }; + + if(closeWithRaf) { + _animateProp('initialZoom', 0, 1, duration, framework.easing.cubic.out, onUpdate, onComplete); + } else { + onUpdate(1); + _showOrHideTimeout = setTimeout(onComplete, duration + 20); + } + } + + }, out ? 25 : 90); // Main purpose of this delay is to give browser time to paint and + // create composite layers of PhotoSwipe UI parts (background, controls, caption, arrows). + // Which avoids lag at the beginning of scale transition. + }; + startAnimation(); + + + }; + +/*>>show-hide-transition*/ + +/*>>items-controller*/ +/** +* +* Controller manages gallery items, their dimensions, and their content. +* +*/ + +var _items, + _tempPanAreaSize = {}, + _imagesToAppendPool = [], + _initialContentSet, + _initialZoomRunning, + _controllerDefaultOptions = { + index: 0, + errorMsg: '<div class="pswp__error-msg"><a href="%url%" target="_blank">The image</a> could not be loaded.</div>', + forceProgressiveLoading: false, // TODO + preload: [1,1], + getNumItemsFn: function() { + return _items.length; + } + }; + + +var _getItemAt, + _getNumItems, + _initialIsLoop, + _getZeroBounds = function() { + return { + center:{x:0,y:0}, + max:{x:0,y:0}, + min:{x:0,y:0} + }; + }, + _calculateSingleItemPanBounds = function(item, realPanElementW, realPanElementH ) { + var bounds = item.bounds; + + // position of element when it's centered + bounds.center.x = Math.round((_tempPanAreaSize.x - realPanElementW) / 2); + bounds.center.y = Math.round((_tempPanAreaSize.y - realPanElementH) / 2) + item.vGap.top; + + // maximum pan position + bounds.max.x = (realPanElementW > _tempPanAreaSize.x) ? + Math.round(_tempPanAreaSize.x - realPanElementW) : + bounds.center.x; + + bounds.max.y = (realPanElementH > _tempPanAreaSize.y) ? + Math.round(_tempPanAreaSize.y - realPanElementH) + item.vGap.top : + bounds.center.y; + + // minimum pan position + bounds.min.x = (realPanElementW > _tempPanAreaSize.x) ? 0 : bounds.center.x; + bounds.min.y = (realPanElementH > _tempPanAreaSize.y) ? item.vGap.top : bounds.center.y; + }, + _calculateItemSize = function(item, viewportSize, zoomLevel) { + + if (item.src && !item.loadError) { + var isInitial = !zoomLevel; + + if(isInitial) { + if(!item.vGap) { + item.vGap = {top:0,bottom:0}; + } + // allows overriding vertical margin for individual items + _shout('parseVerticalMargin', item); + } + + + _tempPanAreaSize.x = viewportSize.x; + _tempPanAreaSize.y = viewportSize.y - item.vGap.top - item.vGap.bottom; + + if (isInitial) { + var hRatio = _tempPanAreaSize.x / item.w; + var vRatio = _tempPanAreaSize.y / item.h; + + item.fitRatio = hRatio < vRatio ? hRatio : vRatio; + //item.fillRatio = hRatio > vRatio ? hRatio : vRatio; + + var scaleMode = _options.scaleMode; + + if (scaleMode === 'orig') { + zoomLevel = 1; + } else if (scaleMode === 'fit') { + zoomLevel = item.fitRatio; + } + + if (zoomLevel > 1) { + zoomLevel = 1; + } + + item.initialZoomLevel = zoomLevel; + + if(!item.bounds) { + // reuse bounds object + item.bounds = _getZeroBounds(); + } + } + + if(!zoomLevel) { + return; + } + + _calculateSingleItemPanBounds(item, item.w * zoomLevel, item.h * zoomLevel); + + if (isInitial && zoomLevel === item.initialZoomLevel) { + item.initialPosition = item.bounds.center; + } + + return item.bounds; + } else { + item.w = item.h = 0; + item.initialZoomLevel = item.fitRatio = 1; + item.bounds = _getZeroBounds(); + item.initialPosition = item.bounds.center; + + // if it's not image, we return zero bounds (content is not zoomable) + return item.bounds; + } + + }, + + + + + _appendImage = function(index, item, baseDiv, img, preventAnimation, keepPlaceholder) { + + + if(item.loadError) { + return; + } + + if(img) { + + item.imageAppended = true; + _setImageSize(item, img, (item === self.currItem && _renderMaxResolution) ); + + baseDiv.appendChild(img); + + if(keepPlaceholder) { + setTimeout(function() { + if(item && item.loaded && item.placeholder) { + item.placeholder.style.display = 'none'; + item.placeholder = null; + } + }, 500); + } + } + }, + + + + _preloadImage = function(item) { + item.loading = true; + item.loaded = false; + var img = item.img = framework.createEl('pswp__img', 'img'); + var onComplete = function() { + item.loading = false; + item.loaded = true; + + if(item.loadComplete) { + item.loadComplete(item); + } else { + item.img = null; // no need to store image object + } + img.onload = img.onerror = null; + img = null; + }; + img.onload = onComplete; + img.onerror = function() { + item.loadError = true; + onComplete(); + }; + + img.src = item.src;// + '?a=' + Math.random(); + + return img; + }, + _checkForError = function(item, cleanUp) { + if(item.src && item.loadError && item.container) { + + if(cleanUp) { + item.container.innerHTML = ''; + } + + item.container.innerHTML = _options.errorMsg.replace('%url%', item.src ); + return true; + + } + }, + _setImageSize = function(item, img, maxRes) { + if(!item.src) { + return; + } + + if(!img) { + img = item.container.lastChild; + } + + var w = maxRes ? item.w : Math.round(item.w * item.fitRatio), + h = maxRes ? item.h : Math.round(item.h * item.fitRatio); + + if(item.placeholder && !item.loaded) { + item.placeholder.style.width = w + 'px'; + item.placeholder.style.height = h + 'px'; + } + + img.style.width = w + 'px'; + img.style.height = h + 'px'; + }, + _appendImagesPool = function() { + + if(_imagesToAppendPool.length) { + var poolItem; + + for(var i = 0; i < _imagesToAppendPool.length; i++) { + poolItem = _imagesToAppendPool[i]; + if( poolItem.holder.index === poolItem.index ) { + _appendImage(poolItem.index, poolItem.item, poolItem.baseDiv, poolItem.img, false, poolItem.clearPlaceholder); + } + } + _imagesToAppendPool = []; + } + }; + + + +_registerModule('Controller', { + + publicMethods: { + + lazyLoadItem: function(index) { + index = _getLoopedId(index); + var item = _getItemAt(index); + + if(!item || ((item.loaded || item.loading) && !_itemsNeedUpdate)) { + return; + } + + _shout('gettingData', index, item); + + if (!item.src) { + return; + } + + _preloadImage(item); + }, + initController: function() { + framework.extend(_options, _controllerDefaultOptions, true); + self.items = _items = items; + _getItemAt = self.getItemAt; + _getNumItems = _options.getNumItemsFn; //self.getNumItems; + + + + _initialIsLoop = _options.loop; + if(_getNumItems() < 3) { + _options.loop = false; // disable loop if less then 3 items + } + + _listen('beforeChange', function(diff) { + + var p = _options.preload, + isNext = diff === null ? true : (diff >= 0), + preloadBefore = Math.min(p[0], _getNumItems() ), + preloadAfter = Math.min(p[1], _getNumItems() ), + i; + + + for(i = 1; i <= (isNext ? preloadAfter : preloadBefore); i++) { + self.lazyLoadItem(_currentItemIndex+i); + } + for(i = 1; i <= (isNext ? preloadBefore : preloadAfter); i++) { + self.lazyLoadItem(_currentItemIndex-i); + } + }); + + _listen('initialLayout', function() { + self.currItem.initialLayout = _options.getThumbBoundsFn && _options.getThumbBoundsFn(_currentItemIndex); + }); + + _listen('mainScrollAnimComplete', _appendImagesPool); + _listen('initialZoomInEnd', _appendImagesPool); + + + + _listen('destroy', function() { + var item; + for(var i = 0; i < _items.length; i++) { + item = _items[i]; + // remove reference to DOM elements, for GC + if(item.container) { + item.container = null; + } + if(item.placeholder) { + item.placeholder = null; + } + if(item.img) { + item.img = null; + } + if(item.preloader) { + item.preloader = null; + } + if(item.loadError) { + item.loaded = item.loadError = false; + } + } + _imagesToAppendPool = null; + }); + }, + + + getItemAt: function(index) { + if (index >= 0) { + return _items[index] !== undefined ? _items[index] : false; + } + return false; + }, + + allowProgressiveImg: function() { + // 1. Progressive image loading isn't working on webkit/blink + // when hw-acceleration (e.g. translateZ) is applied to IMG element. + // That's why in PhotoSwipe parent element gets zoom transform, not image itself. + // + // 2. Progressive image loading sometimes blinks in webkit/blink when applying animation to parent element. + // That's why it's disabled on touch devices (mainly because of swipe transition) + // + // 3. Progressive image loading sometimes doesn't work in IE (up to 11). + + // Don't allow progressive loading on non-large touch devices + return _options.forceProgressiveLoading || !_likelyTouchDevice || _options.mouseUsed || screen.width > 1200; + // 1200 - to eliminate touch devices with large screen (like Chromebook Pixel) + }, + + setContent: function(holder, index) { + + if(_options.loop) { + index = _getLoopedId(index); + } + + var prevItem = self.getItemAt(holder.index); + if(prevItem) { + prevItem.container = null; + } + + var item = self.getItemAt(index), + img; + + if(!item) { + holder.el.innerHTML = ''; + return; + } + + // allow to override data + _shout('gettingData', index, item); + + holder.index = index; + holder.item = item; + + // base container DIV is created only once for each of 3 holders + var baseDiv = item.container = framework.createEl('pswp__zoom-wrap'); + + + + if(!item.src && item.html) { + if(item.html.tagName) { + baseDiv.appendChild(item.html); + } else { + baseDiv.innerHTML = item.html; + } + } + + _checkForError(item); + + _calculateItemSize(item, _viewportSize); + + if(item.src && !item.loadError && !item.loaded) { + + item.loadComplete = function(item) { + + // gallery closed before image finished loading + if(!_isOpen) { + return; + } + + // check if holder hasn't changed while image was loading + if(holder && holder.index === index ) { + if( _checkForError(item, true) ) { + item.loadComplete = item.img = null; + _calculateItemSize(item, _viewportSize); + _applyZoomPanToItem(item); + + if(holder.index === _currentItemIndex) { + // recalculate dimensions + self.updateCurrZoomItem(); + } + return; + } + if( !item.imageAppended ) { + if(_features.transform && (_mainScrollAnimating || _initialZoomRunning) ) { + _imagesToAppendPool.push({ + item:item, + baseDiv:baseDiv, + img:item.img, + index:index, + holder:holder, + clearPlaceholder:true + }); + } else { + _appendImage(index, item, baseDiv, item.img, _mainScrollAnimating || _initialZoomRunning, true); + } + } else { + // remove preloader & mini-img + if(!_initialZoomRunning && item.placeholder) { + item.placeholder.style.display = 'none'; + item.placeholder = null; + } + } + } + + item.loadComplete = null; + item.img = null; // no need to store image element after it's added + + _shout('imageLoadComplete', index, item); + }; + + if(framework.features.transform) { + + var placeholderClassName = 'pswp__img pswp__img--placeholder'; + placeholderClassName += (item.msrc ? '' : ' pswp__img--placeholder--blank'); + + var placeholder = framework.createEl(placeholderClassName, item.msrc ? 'img' : ''); + if(item.msrc) { + placeholder.src = item.msrc; + } + + _setImageSize(item, placeholder); + + baseDiv.appendChild(placeholder); + item.placeholder = placeholder; + + } + + + + + if(!item.loading) { + _preloadImage(item); + } + + + if( self.allowProgressiveImg() ) { + // just append image + if(!_initialContentSet && _features.transform) { + _imagesToAppendPool.push({ + item:item, + baseDiv:baseDiv, + img:item.img, + index:index, + holder:holder + }); + } else { + _appendImage(index, item, baseDiv, item.img, true, true); + } + } + + } else if(item.src && !item.loadError) { + // image object is created every time, due to bugs of image loading & delay when switching images + img = framework.createEl('pswp__img', 'img'); + img.style.opacity = 1; + img.src = item.src; + _setImageSize(item, img); + _appendImage(index, item, baseDiv, img, true); + } + + + if(!_initialContentSet && index === _currentItemIndex) { + _currZoomElementStyle = baseDiv.style; + _showOrHide(item, (img ||item.img) ); + } else { + _applyZoomPanToItem(item); + } + + holder.el.innerHTML = ''; + holder.el.appendChild(baseDiv); + }, + + cleanSlide: function( item ) { + if(item.img ) { + item.img.onload = item.img.onerror = null; + } + item.loaded = item.loading = item.img = item.imageAppended = false; + } + + } +}); + +/*>>items-controller*/ + +/*>>tap*/ +/** + * tap.js: + * + * Displatches tap and double-tap events. + * + */ + +var tapTimer, + tapReleasePoint = {}, + _dispatchTapEvent = function(origEvent, releasePoint, pointerType) { + var e = document.createEvent( 'CustomEvent' ), + eDetail = { + origEvent:origEvent, + target:origEvent.target, + releasePoint: releasePoint, + pointerType:pointerType || 'touch' + }; + + e.initCustomEvent( 'pswpTap', true, true, eDetail ); + origEvent.target.dispatchEvent(e); + }; + +_registerModule('Tap', { + publicMethods: { + initTap: function() { + _listen('firstTouchStart', self.onTapStart); + _listen('touchRelease', self.onTapRelease); + _listen('destroy', function() { + tapReleasePoint = {}; + tapTimer = null; + }); + }, + onTapStart: function(touchList) { + if(touchList.length > 1) { + clearTimeout(tapTimer); + tapTimer = null; + } + }, + onTapRelease: function(e, releasePoint) { + if(!releasePoint) { + return; + } + + if(!_moved && !_isMultitouch && !_numAnimations) { + var p0 = releasePoint; + if(tapTimer) { + clearTimeout(tapTimer); + tapTimer = null; + + // Check if taped on the same place + if ( _isNearbyPoints(p0, tapReleasePoint) ) { + _shout('doubleTap', p0); + return; + } + } + + if(releasePoint.type === 'mouse') { + _dispatchTapEvent(e, releasePoint, 'mouse'); + return; + } + + var clickedTagName = e.target.tagName.toUpperCase(); + // avoid double tap delay on buttons and elements that have class pswp__single-tap + if(clickedTagName === 'BUTTON' || framework.hasClass(e.target, 'pswp__single-tap') ) { + _dispatchTapEvent(e, releasePoint); + return; + } + + _equalizePoints(tapReleasePoint, p0); + + tapTimer = setTimeout(function() { + _dispatchTapEvent(e, releasePoint); + tapTimer = null; + }, 300); + } + } + } +}); + +/*>>tap*/ + +/*>>desktop-zoom*/ +/** + * + * desktop-zoom.js: + * + * - Binds mousewheel event for paning zoomed image. + * - Manages "dragging", "zoomed-in", "zoom-out" classes. + * (which are used for cursors and zoom icon) + * - Adds toggleDesktopZoom function. + * + */ + +var _wheelDelta; + +_registerModule('DesktopZoom', { + + publicMethods: { + + initDesktopZoom: function() { + + if(_oldIE) { + // no zoom for old IE (<=8) + return; + } + + if(_likelyTouchDevice) { + // if detected hardware touch support, we wait until mouse is used, + // and only then apply desktop-zoom features + _listen('mouseUsed', function() { + self.setupDesktopZoom(); + }); + } else { + self.setupDesktopZoom(true); + } + + }, + + setupDesktopZoom: function(onInit) { + + _wheelDelta = {}; + + var events = 'wheel mousewheel DOMMouseScroll'; + + _listen('bindEvents', function() { + framework.bind(template, events, self.handleMouseWheel); + }); + + _listen('unbindEvents', function() { + if(_wheelDelta) { + framework.unbind(template, events, self.handleMouseWheel); + } + }); + + self.mouseZoomedIn = false; + + var hasDraggingClass, + updateZoomable = function() { + if(self.mouseZoomedIn) { + framework.removeClass(template, 'pswp--zoomed-in'); + self.mouseZoomedIn = false; + } + if(_currZoomLevel < 1) { + framework.addClass(template, 'pswp--zoom-allowed'); + } else { + framework.removeClass(template, 'pswp--zoom-allowed'); + } + removeDraggingClass(); + }, + removeDraggingClass = function() { + if(hasDraggingClass) { + framework.removeClass(template, 'pswp--dragging'); + hasDraggingClass = false; + } + }; + + _listen('resize' , updateZoomable); + _listen('afterChange' , updateZoomable); + _listen('pointerDown', function() { + if(self.mouseZoomedIn) { + hasDraggingClass = true; + framework.addClass(template, 'pswp--dragging'); + } + }); + _listen('pointerUp', removeDraggingClass); + + if(!onInit) { + updateZoomable(); + } + + }, + + handleMouseWheel: function(e) { + + if(_currZoomLevel <= self.currItem.fitRatio) { + if( _options.modal ) { + + if (!_options.closeOnScroll || _numAnimations || _isDragging) { + e.preventDefault(); + } else if(_transformKey && Math.abs(e.deltaY) > 2) { + // close PhotoSwipe + // if browser supports transforms & scroll changed enough + _closedByScroll = true; + self.close(); + } + + } + return true; + } + + // allow just one event to fire + e.stopPropagation(); + + // https://developer.mozilla.org/en-US/docs/Web/Events/wheel + _wheelDelta.x = 0; + + if('deltaX' in e) { + if(e.deltaMode === 1 /* DOM_DELTA_LINE */) { + // 18 - average line height + _wheelDelta.x = e.deltaX * 18; + _wheelDelta.y = e.deltaY * 18; + } else { + _wheelDelta.x = e.deltaX; + _wheelDelta.y = e.deltaY; + } + } else if('wheelDelta' in e) { + if(e.wheelDeltaX) { + _wheelDelta.x = -0.16 * e.wheelDeltaX; + } + if(e.wheelDeltaY) { + _wheelDelta.y = -0.16 * e.wheelDeltaY; + } else { + _wheelDelta.y = -0.16 * e.wheelDelta; + } + } else if('detail' in e) { + _wheelDelta.y = e.detail; + } else { + return; + } + + _calculatePanBounds(_currZoomLevel, true); + + var newPanX = _panOffset.x - _wheelDelta.x, + newPanY = _panOffset.y - _wheelDelta.y; + + // only prevent scrolling in nonmodal mode when not at edges + if (_options.modal || + ( + newPanX <= _currPanBounds.min.x && newPanX >= _currPanBounds.max.x && + newPanY <= _currPanBounds.min.y && newPanY >= _currPanBounds.max.y + ) ) { + e.preventDefault(); + } + + // TODO: use rAF instead of mousewheel? + self.panTo(newPanX, newPanY); + }, + + toggleDesktopZoom: function(centerPoint) { + centerPoint = centerPoint || {x:_viewportSize.x/2 + _offset.x, y:_viewportSize.y/2 + _offset.y }; + + var doubleTapZoomLevel = _options.getDoubleTapZoom(true, self.currItem); + var zoomOut = _currZoomLevel === doubleTapZoomLevel; + + self.mouseZoomedIn = !zoomOut; + + self.zoomTo(zoomOut ? self.currItem.initialZoomLevel : doubleTapZoomLevel, centerPoint, 333); + framework[ (!zoomOut ? 'add' : 'remove') + 'Class'](template, 'pswp--zoomed-in'); + } + + } +}); + + +/*>>desktop-zoom*/ + +/*>>history*/ +/** + * + * history.js: + * + * - Back button to close gallery. + * + * - Unique URL for each slide: example.com/&pid=1&gid=3 + * (where PID is picture index, and GID and gallery index) + * + * - Switch URL when slides change. + * + */ + + +var _historyDefaultOptions = { + history: true, + galleryUID: 1 +}; + +var _historyUpdateTimeout, + _hashChangeTimeout, + _hashAnimCheckTimeout, + _hashChangedByScript, + _hashChangedByHistory, + _hashReseted, + _initialHash, + _historyChanged, + _closedFromURL, + _urlChangedOnce, + _windowLoc, + + _supportsPushState, + + _getHash = function() { + return _windowLoc.hash.substring(1); + }, + _cleanHistoryTimeouts = function() { + + if(_historyUpdateTimeout) { + clearTimeout(_historyUpdateTimeout); + } + + if(_hashAnimCheckTimeout) { + clearTimeout(_hashAnimCheckTimeout); + } + }, + + // pid - Picture index + // gid - Gallery index + _parseItemIndexFromURL = function() { + var hash = _getHash(), + params = {}; + + if(hash.length < 5) { // pid=1 + return params; + } + + var i, vars = hash.split('&'); + for (i = 0; i < vars.length; i++) { + if(!vars[i]) { + continue; + } + var pair = vars[i].split('='); + if(pair.length < 2) { + continue; + } + params[pair[0]] = pair[1]; + } + if(_options.galleryPIDs) { + // detect custom pid in hash and search for it among the items collection + var searchfor = params.pid; + params.pid = 0; // if custom pid cannot be found, fallback to the first item + for(i = 0; i < _items.length; i++) { + if(_items[i].pid === searchfor) { + params.pid = i; + break; + } + } + } else { + params.pid = parseInt(params.pid,10)-1; + } + if( params.pid < 0 ) { + params.pid = 0; + } + return params; + }, + _updateHash = function() { + + if(_hashAnimCheckTimeout) { + clearTimeout(_hashAnimCheckTimeout); + } + + + if(_numAnimations || _isDragging) { + // changing browser URL forces layout/paint in some browsers, which causes noticable lag during animation + // that's why we update hash only when no animations running + _hashAnimCheckTimeout = setTimeout(_updateHash, 500); + return; + } + + if(_hashChangedByScript) { + clearTimeout(_hashChangeTimeout); + } else { + _hashChangedByScript = true; + } + + + var pid = (_currentItemIndex + 1); + var item = _getItemAt( _currentItemIndex ); + if(item.hasOwnProperty('pid')) { + // carry forward any custom pid assigned to the item + pid = item.pid; + } + var newHash = _initialHash + '&' + 'gid=' + _options.galleryUID + '&' + 'pid=' + pid; + + if(!_historyChanged) { + if(_windowLoc.hash.indexOf(newHash) === -1) { + _urlChangedOnce = true; + } + // first time - add new hisory record, then just replace + } + + var newURL = _windowLoc.href.split('#')[0] + '#' + newHash; + + if( _supportsPushState ) { + + if('#' + newHash !== window.location.hash) { + history[_historyChanged ? 'replaceState' : 'pushState']('', document.title, newURL); + } + + } else { + if(_historyChanged) { + _windowLoc.replace( newURL ); + } else { + _windowLoc.hash = newHash; + } + } + + + + _historyChanged = true; + _hashChangeTimeout = setTimeout(function() { + _hashChangedByScript = false; + }, 60); + }; + + + + + +_registerModule('History', { + + + + publicMethods: { + initHistory: function() { + + framework.extend(_options, _historyDefaultOptions, true); + + if( !_options.history ) { + return; + } + + + _windowLoc = window.location; + _urlChangedOnce = false; + _closedFromURL = false; + _historyChanged = false; + _initialHash = _getHash(); + _supportsPushState = ('pushState' in history); + + + if(_initialHash.indexOf('gid=') > -1) { + _initialHash = _initialHash.split('&gid=')[0]; + _initialHash = _initialHash.split('?gid=')[0]; + } + + + _listen('afterChange', self.updateURL); + _listen('unbindEvents', function() { + framework.unbind(window, 'hashchange', self.onHashChange); + }); + + + var returnToOriginal = function() { + _hashReseted = true; + if(!_closedFromURL) { + + if(_urlChangedOnce) { + history.back(); + } else { + + if(_initialHash) { + _windowLoc.hash = _initialHash; + } else { + if (_supportsPushState) { + + // remove hash from url without refreshing it or scrolling to top + history.pushState('', document.title, _windowLoc.pathname + _windowLoc.search ); + } else { + _windowLoc.hash = ''; + } + } + } + + } + + _cleanHistoryTimeouts(); + }; + + + _listen('unbindEvents', function() { + if(_closedByScroll) { + // if PhotoSwipe is closed by scroll, we go "back" before the closing animation starts + // this is done to keep the scroll position + returnToOriginal(); + } + }); + _listen('destroy', function() { + if(!_hashReseted) { + returnToOriginal(); + } + }); + _listen('firstUpdate', function() { + _currentItemIndex = _parseItemIndexFromURL().pid; + }); + + + + + var index = _initialHash.indexOf('pid='); + if(index > -1) { + _initialHash = _initialHash.substring(0, index); + if(_initialHash.slice(-1) === '&') { + _initialHash = _initialHash.slice(0, -1); + } + } + + + setTimeout(function() { + if(_isOpen) { // hasn't destroyed yet + framework.bind(window, 'hashchange', self.onHashChange); + } + }, 40); + + }, + onHashChange: function() { + + if(_getHash() === _initialHash) { + + _closedFromURL = true; + self.close(); + return; + } + if(!_hashChangedByScript) { + + _hashChangedByHistory = true; + self.goTo( _parseItemIndexFromURL().pid ); + _hashChangedByHistory = false; + } + + }, + updateURL: function() { + + // Delay the update of URL, to avoid lag during transition, + // and to not to trigger actions like "refresh page sound" or "blinking favicon" to often + + _cleanHistoryTimeouts(); + + + if(_hashChangedByHistory) { + return; + } + + if(!_historyChanged) { + _updateHash(); // first time + } else { + _historyUpdateTimeout = setTimeout(_updateHash, 800); + } + } + + } +}); + + +/*>>history*/ + framework.extend(self, publicMethods); }; + return PhotoSwipe; +}); \ No newline at end of file diff --git a/static/app/js/pj.js b/static/app/js/pj.js new file mode 100755 index 0000000..5ddf997 --- /dev/null +++ b/static/app/js/pj.js @@ -0,0 +1,216 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + mui.ajax(hyhUrl('app/Orders/getOrderAppraise'), {  + headers: {  + "HYH-Token": token + }, + data: { + oId: data_order_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + + if(data.status == 1) { + data = data.data + var html = ''; + var i =0; + $.each(data.Rows, function() { + if(this.appraise == null) { + html += '<div class="con_1"data-goodsId="' + this.goodsId + '"data-goodsSpecId="' + this.goodsSpecId + '"data-orderId="' + this.orderId + '"data-orderGoodsId="' + this.id + '"><div class="describe"><div class="des_img"><img src="' + hyhImgUrl(this.goodsImg) + '"/></div><p>' + this.goodsName + '</p></div><div class="row"data-class="goodsScore"data-goodsScore="0"><p>商品评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="serviceScore"data-serviceScore="0"><p>服务评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="timeScore"data-timeScore="0"><p>时效评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="purchase"><textarea class="content"name=""rows=""cols=""placeholder="分享你的购买心得"></textarea><div class="up_out"><div id="ossfile' + i + '" class="ossfile clearfix" data-num="' + i + '">你的浏览器不支持flash,Silverlight或者HTML5!</div><div id="container' + i + '" class="container" data-num="' + i + '"><a id="selectfiles' + i + '" href="javascript:void(0);" class="btn selectfiles" data-num="' + i + '">选择图片</a></div></div></div><button class="tijiao">提交评价</button></div>' + i++; + } else { + html += '<div class="con_1"data-goodsId="' + this.goodsId + '"data-goodsSpecId="' + this.goodsSpecId + '"data-orderId="' + data.orderId + '"data-orderGoodsId="' + this.orderId + '"><div class="describe"><div class="des_img"><img src="' + hyhImgUrl(this.goodsImg) + '"/></div><p>' + this.goodsName + '</p></div><div class="row"data-class="goodsScore"data-goodsScore="' + this.appraise.goodsScore + '"><p>商品评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="serviceScore"data-serviceScore="' + this.appraise.serviceScore + '"><p>服务评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="timeScore"data-timeScore="' + this.appraise.timeScore + '"><p>时效评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="purchase_"><p>' + this.appraise.content + '</p>' + + $.each(this.appraise.images, function() { + html+='<img src="'+ hyhImgUrl(this) +'"/>' + }); + + + + html+='</div></div>'; + } + }); + $('.con').html(html) + $('.star').each(function() { + if($(this).attr('data-isPj') == 1) { + var num = +$(this).parent().attr('data-' + $(this).parent().attr('data-class')) - 1 + $(this).children().eq(num).children().addClass('star_on').removeClass('star_off') + $(this).children().eq(num).prevAll().children().addClass('star_on').removeClass('star_off') + $(this).children().eq(num).nextAll().children().addClass('star_off').removeClass('star_on') + } + }) + var btnArr = []; + + $('.selectfiles').each(function(num) { + btnArr.push($(this).attr('id')); + }) + + $.each(btnArr, function(i, n) { + var self = this.toString(); + var that = document.getElementById(this); + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: self, + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + dir:'appraises', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementsByClassName('ossfile')[i].innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false,'appraises'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementsByClassName('ossfile')[i].innerHTML += '<div class="files_out" id="'+ file.id +'"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name)) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + alert("\n选择的文件太大了"); + } else if(err.code == -601) { + alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + alert("\n这个文件已经上传过一遍了"); + } else { + alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); + }); + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.con').on('tap', '.star_a', function() { + if($(this).parent().attr('data-isPj') == 1) { + return; + } + $(this).children().addClass('star_on').removeClass('star_off'); + $(this).prevAll().children().addClass('star_on').removeClass('star_off'); + $(this).nextAll().children().addClass('star_off').removeClass('star_on'); + $(this).parent().parent().attr('data-' + $(this).parent().parent().attr('data-class'), $(this).index() + 1); + }) + + $('.con').on('tap', '.tijiao', function() { + var goodsId = $(this).parent().attr('data-goodsId'); + var goodsSpecId = $(this).parent().attr('data-goodsSpecId'); + var orderId = $(this).parent().attr('data-orderId'); + var orderGoodsId = $(this).parent().attr('data-orderGoodsId'); + var timeScore = $(this).siblings('.row[data-class*=timeScore]').attr('data-timeScore'); + var goodsScore = $(this).siblings('.row[data-class*=goodsScore]').attr('data-goodsScore'); + var serviceScore = $(this).siblings('.row[data-class*=serviceScore]').attr('data-serviceScore'); + var content = $(this).siblings('.purchase').children('textarea').val(); + var that = $(this); + var imagesArr=[]; + $(this).siblings('.purchase').children('.up_out').children('.ossfile').children('.files_out').children('b').children('img').each(function(){ + imagesArr.push($(this).attr('data-src')) + }) + var images = imagesArr.join(','); + if(timeScore == 0 || serviceScore == 0 || serviceScore == 0) { + alert('评分必须1-5分之间!'); + return; + } + if(content.length < 3) { + alert('评论最少3个字!'); + return; + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/Goodsappraises/add'), {  + headers: {  + "HYH-Token": token + }, + data: { + goodsId: goodsId, + goodsSpecId: goodsSpecId, + orderId: orderId, + orderGoodsId: orderGoodsId, + timeScore: timeScore, + goodsScore: goodsScore, + serviceScore: serviceScore, + content: content, + images:images + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + alert(data.msg) + if(data.status == 1) { + location.reload(); + } else { + console.log(data.status) + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) +}) \ No newline at end of file diff --git a/static/app/js/plupload.full.min.js b/static/app/js/plupload.full.min.js new file mode 100755 index 0000000..ca6cdf8 --- /dev/null +++ b/static/app/js/plupload.full.min.js @@ -0,0 +1,28 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",h="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",b="moxie/file/FileReader",R="moxie/core/utils/Url",T="moxie/file/FileReaderSync",A="moxie/xhr/FormData",S="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",h="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var h=f[n],p=f[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<h.length;a++)if(l=h[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(h,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[h,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?void t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),void(n[this.uid][e]=s))},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,m[h++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[h++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,p],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[h,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?void i.init():void i.trigger("Error")):void o(t)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),void(i=null))}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,h,p,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,h;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);h={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},h,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:void c.files.push(new a(c.ruid,e))})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,h,u,w,v,p,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(b,[u,m,h,p,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var h=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=h;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(h)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend")) +},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(R,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(A,[h,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(S,[u,h,p,m,R,g,x,y,T,A,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function h(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:void(l.can("define_property")?y[e]=t:v[e]=t):void 0}function u(t){function i(){k&&(k.destroy(),k=null),s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",h.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==h.LOADING&&(n("readyState",h.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",h.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",h.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:b,password:R,headers:x,mimeType:A,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:h.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},b,R,T=null,A=null,S=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(b=u||l.user,R=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);S=!w,O=!1,x={},g.call(this),n("readyState",h.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[h.LOADING,h.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,A=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,A=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",A="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!S&&this.upload.hasEventListener(),N=!1,D=!n,S||(O=!0),u.call(this,n)},abort:function(){if(N=!0,S=!1,~e.inArray(n("readyState"),[h.UNSENT,h.OPENED,h.DONE]))n("readyState",h.UNSENT);else{if(n("readyState",h.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return h.UNSENT=0,h.OPENED=1,h.HEADERS_RECEIVED=2,h.LOADING=3,h.DONE=4,h.prototype=n.instance,h}),i(O,[u,m,v,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,h,T,S,g,v,O,d,p,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function h(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof h){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(p),c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,crop:!1,preserveHeaders:!0};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.getRuntime().exec.call(this,"Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),void o.trigger("embedded")}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},p,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,p=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=p.type||this.type||"image/jpeg",l=p.quality||90,d="undefined"!==e.typeOf(p.crop)?p.crop:!1,p.width)m=p.width,g=p.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new h,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var p=["progress","load","error","resize","embedded"];return h.MAX_RESIZE_WIDTH=6500,h.MAX_RESIZE_HEIGHT=6500,h.prototype=c.instance,h}),i(D,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,h,p,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),h=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(h,"position")&&(h.style.position="relative"),p=parseInt(n.getStyle(h,"z-index"),10)||1,h.style.zIndex=p,d.style.zIndex=p-1,i.addEvent(h,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?h:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser&&"IEMobile"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var n=t.toArray(e.dataTransfer.types||[]);return-1!==t.inArray("Files",n)||-1!==t.inArray("public.file-url",n)||-1!==t.inArray("application/x-moz-file",n)}function o(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function a(e){if(!f.length)return!0;var n=r.getFileExtension(e.name);return!n||-1!==t.inArray(n,f)}function s(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();a(n)&&d.push(n)}else i.push(t)}),i.length?u(i,n):n()}function u(e,n){var i=[];t.each(e,function(e){i.push(function(t){c(e,t)})}),t.inSeries(i,function(){n()})}function c(e,t){e.isFile?e.file(function(e){a(e)&&d.push(e),t()},function(){t()}):e.isDirectory?l(e,t):t()}function l(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){u(i,t)})}var d=[],f=[],h;t.extend(this,{init:function(n){var r=this,u;h=n,f=o(h.accept),u=h.container,i.addEvent(u,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},r.uid),i.addEvent(u,"drop",function(n){e(n)&&(n.preventDefault(),d=[],n.dataTransfer.items&&n.dataTransfer.items[0].webkitGetAsEntry?s(n.dataTransfer.items,function(){r.trigger("drop")}):(t.each(n.dataTransfer.files,function(e){a(e)&&d.push(e)}),r.trigger("drop")))},r.uid),i.addEvent(u,"dragenter",function(e){r.trigger("dragenter")},r.uid),i.addEvent(u,"dragleave",function(e){r.trigger("dragleave")},r.uid)},getFiles:function(){return d},destroy:function(){i.removeAllEvents(h&&n.get(h.container),this.uid),d=f=h=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,R,w,y,A,h,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return h.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,h,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),h=c(),h.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}h.upload?(n.withCredentials&&(h.withCredentials=!0),h.addEventListener("load",function(e){s.trigger(e)}),h.addEventListener("error",function(e){s.trigger(e)}),h.addEventListener("progress",function(e){s.trigger(e)}),h.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):h.onreadystatechange=function v(){switch(h.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=h.getResponseHeader("Content-Length")||0),h.responseText&&(t=h.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:h.onreadystatechange=function(){},s.trigger(0===h.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){h.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in h&&(h.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?h.sendAsBinary?h.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);h.send(e.buffer)}():h.send(r),s.trigger("loadstart")},getStatus:function(){try{if(h)return h.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,h.response),o=h.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?h.response:200===h.status&&window.JSON?JSON.parse(h.responseText):null;case"document":return l(h);default:return""!==h.responseText?h.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return h.getAllResponseHeaders()}catch(e){}return""},abort:function(){h&&h.abort()},destroy:function(){f=p=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(t>>Math.abs(a+8*s)&255);n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:void(r=e)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):void i(n,r,4)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,h,p,m=[],g={};for(r=0;i>r;r++)if(h=f=e+12*r+2,s=n[a.SHORT(h)],s!==t){switch(u=a.SHORT(h+=2),d=a.LONG(h+=2),h+=4,m=[],u){case 1:case 7:for(d>4&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(h+o);break;case 2:d>4&&(h=a.LONG(h)+c.tiffHeader),g[s]=a.STRING(h,d-1);continue;case 3:for(d>2&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(h+2*o);break;case 4:for(d>1&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(h+4*o);break;case 5:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(h+4*o)/a.LONG(h+4*o+4);break;case 9:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o);break;case 10:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o)/a.SLONG(h+4*o+4);break;default:continue}p=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof p?l[s][p]:p}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\x00"===a.STRING(4,5).toUpperCase()?r():!1):!1 +},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,h,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,h;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,h=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return h?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.getBinary())):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),h&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[h,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,h,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,h=document.createElement("canvas");h.width=h.height=f;for(var p=h.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;p.clearRect(0,0,f,f),p.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,b=Math.ceil(v*u/a/m);d.drawImage(h,0,0,w,v,E,x,_,b),y+=f}g+=f}h=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,h,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function h(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,h,g;if(R=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),h=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),h>i&&(l=Math.round((h-i)/2))):(E.width=f,E.height=h),R||m(E.width,E.height,g),p.call(this,d,E,-c,-l,f,h),this.width=E.width,this.height=E.height,b=!0,void a.trigger("Resize"))}function p(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,b=!1}var v=this,y,w,E,_,x,b=!1,R=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),void d.call(this,_)):void f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){h.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&h.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!b)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!b)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),R&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return b=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,h,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===c.mode},stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,A,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,h,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,h,p,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(h=n.get(a+"_form"),h&&t.extend(h.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),t.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=p=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=h=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,R,h,L,y,A],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function h(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),w&&p.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),h(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,h,p,m,g,v,y,w,E,_,x,b,R,T,A,S,O,I,L])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this); +/** + * Plupload - multi-runtime File Uploader + * v2.1.2 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.2",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie); \ No newline at end of file diff --git a/static/app/js/qrcode.js b/static/app/js/qrcode.js new file mode 100755 index 0000000..5507c15 --- /dev/null +++ b/static/app/js/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a> + * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a> + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}} + this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}} + return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;} + this.modules[r][6]=(r%2==0);} + for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;} + this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;} + for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);} + var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;} + if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];} + offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;} + var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}} + for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}} + return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));} + return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;} + for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;} + if(r==0&&c==0){continue;} + if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}} + if(sameCount>5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}} + for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}} + for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}} + var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}} + var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");} + return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;} + while(n>=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;} + for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];} + for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;} + function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);} + var offset=0;while(offset<num.length&&num[offset]==0){offset++;} + this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}} + QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}} + return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;} + var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);} + for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);} + return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;} + QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);} + var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}} + return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;} + QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['<table style="border:0;border-collapse:collapse;">']; + + for (var row = 0; row < nCount; row++) { + aHTML.push('<tr>'); + + for (var col = 0; col < nCount; col++) { + aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>'); + } + + aHTML.push('</tr>'); + } + + aHTML.push('</table>'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/static/app/js/register.js b/static/app/js/register.js new file mode 100755 index 0000000..abb65b9 --- /dev/null +++ b/static/app/js/register.js @@ -0,0 +1,139 @@ +mui.init({ + beforeback: function() {     //获得父页面的webview + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + } +}); + +mui.plusReady(function() { + var wait = 120; + var html = '<div class="row"><img src="../img/icon_pwd1.png" /><span class="s1">验证码:</span><input class="tpyzm" type="text" maxlength="4" placeholder="请输入图片验证码" /><img class="yzmhh" src = "'+ hyhUrl('mobile/users/getverify?rnd='+Math.random()) +'"/></input></div>'; + + $('.con').append(html); + + function time() { + if(wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + mui('.row').on('tap', '#mobileCode', function() { + var loginName = $('#loginName').val(); + if(loginName == '') { + alert('手机号不能为空!'); + return; + } + + if(!(/^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/.test(loginName))) { + alert("手机号码有误,请重填!"); + return; + } + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/getPhoneVerifyCode'), {  + + data: { + userPhone: loginName + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + time(); + } else { + alert(data.msg); + } + $('#mobileCode').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + alert(type) + // alert(type);       + } + });  + }) + mui('.down').on('tap', '.btn', function() { + var loginName = $('#loginName').val(); + var mobileCode = $('.yzm').val(); + var loginPwd = $('#loginPwd').val(); + var reUserPwd = $('#reUserPwd').val(); + var pName = $('#pName').val(); + var verifyCode = $('.tpyzm').val(); + + if(loginName == '') { + alert('手机号不能为空!'); + return; + } + if(!(/^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/.test(loginName))) { + alert("手机号码有误,请重填!"); + return; + } + if(mobileCode == '') { + alert('验证码不能为空!'); + return; + } + if(loginPwd == '') { + alert('密码不能为空!'); + return; + } + if(reUserPwd == '') { + alert('确认不能为空!'); + return; + } + if(loginPwd.length < 6) { + alert('密码不能小于6位!'); + return; + } + if(!(loginPwd == reUserPwd)) { + alert('两次密码不一致!'); + return; + } + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/register'), {  + data: { + loginName: loginName, + mobileCode: mobileCode, + loginPwd: loginPwd, + reUserPwd: reUserPwd, + pName: pName, + nameType: 3, + verifyCode: verifyCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + alert(data.msg); + + if(data.status == 1) { + mui.back(); + }else{ + $('.yzmhh').attr('src',hyhUrl('mobile/users/getverify?rnd='+Math.random())); + } + $('.btn').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + });  + + }) +}) \ No newline at end of file diff --git a/static/app/js/setting.js b/static/app/js/setting.js new file mode 100755 index 0000000..697b288 --- /dev/null +++ b/static/app/js/setting.js @@ -0,0 +1,64 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.loginout').on('tap', function() { + //console.log(111) + mui.ajax(hyhUrl('app/users/logout'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + localStorage.removeItem("token"); + mui.fire(plus.webview.getWebviewById('templete/my.html'), 'refresh'); + mui.fire(plus.webview.getWebviewById('templete/shoppingcart.html'), 'refresh'); + mui.back(); + var data = toJson(data, 1); + if(data.status == 1) { + + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) +}) \ No newline at end of file diff --git a/static/app/js/setting_address.js b/static/app/js/setting_address.js new file mode 100755 index 0000000..fbdd15c --- /dev/null +++ b/static/app/js/setting_address.js @@ -0,0 +1,169 @@ +mui.init({ + beforeback: function() {     //获得父页面的webview +      //触发父页面的自定义事件(refresh),从而进行刷新 + + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var self = plus.webview.currentWebview(); + var isOrder = self.data_isOrder; + if(isOrder == true) { + $('.con').on('tap', '.block', function() { + var addressId = $(this).attr('data-addressId'); + localStorage.setItem('addressId', addressId); + var list = plus.webview.currentWebview().opener(); + mui.fire(list, 'setAddress'); + mui.back(); + }) + } + mui.ajax(hyhUrl('app/useraddress/getList'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html = ''; + $.each(data.addressList, function() { + html += '<div class="block" data-addressId="' + this.addressId + '"><p class="pname">' + this.userName + '</p><p class="pphone">' + this.userPhone + '</p><p class="paddress">' + this.areaName + ' ' + this.userAddress + '</p><hr /><div class="btnout" data-isDefault="' + this.isDefault + '"><div class="btn"></div></div><p class="p1">设为默认地址</p><button class="bj">编辑</button><button class="del">删除</button></div>' + }); + $('.con').html(html) + $('.btnout').each(function(num) { + if($(this).attr('data-isDefault') == 1) { + $(this).children('.btn').addClass('on') + } + }) + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.footer_btn').on('tap', function() { + mui.openWindow({ + url: 'editAddress.html', + id: 'editAddress.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.con').on('tap', '.bj', function(e) { + e.stopPropagation(); + var data_addressId = $(this).parent().attr('data-addressId'); + mui.openWindow({ + url: 'editAddress.html', + id: 'editAddress.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_addressId: data_addressId + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con').on('tap', '.del', function() { + var data_addressId = $(this).parent().attr('data-addressId'); + if(confirm('确认删除地址?')) { + mui.ajax(hyhUrl('app/Useraddress/del'), {  + data: { + id: data_addressId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + location.reload() + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + + }) + $('.con').on('tap', '.btnout', function() { + $('.btnout').children('.btn').removeClass('on'); + $(this).children('.btn').addClass('on'); + var addressId = $(this).parent().attr('data-addressId') + mui.ajax(hyhUrl('app/Useraddress/setDefault'), {  + data: { + id: addressId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + location.reload() + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) +}) \ No newline at end of file diff --git a/static/app/js/setting_fogetPayPwd.js b/static/app/js/setting_fogetPayPwd.js new file mode 100755 index 0000000..60b7b5e --- /dev/null +++ b/static/app/js/setting_fogetPayPwd.js @@ -0,0 +1,200 @@ +$('#newPass').attr('type','text'); +$('#newPass2').attr('type','text'); + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var wait = 120; + + function time() { + + if(wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + mui.ajax(hyhUrl('app/users/backPayPass'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.userPhone) { + $('#userPhone').val(data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + } else { + alert('未绑定手机请先绑定手机!'); + mui.openWindow({ + url: 'setting_phone.html', + id: 'setting_phone.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } else { + alert(data.msg); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + mui('.row').on('tap', '#mobileCode', function() { + var that = $(this); + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/backpayCode'), {  + + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + time(); + } else { + alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + // alert(type);       + } + });  + }) + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/verifybackPay'), {  + headers: {  + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#con1').css('display', 'none'); + $('#down1').css('display', 'none'); + $('#con2').css('display', 'block'); + $('#down2').css('display', 'block'); + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + mui('.down').on('tap', '#true2', function() { + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + var that = $(this); + if(newPass == '') { + alert('支付密码不能为空!'); + return; + } else if(newPass.length != 6) { + alert('支付密码为6位!'); + return; + } else if(newPass != newPass2) { + alert('两次支付密码不相同!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/resetbackPay'), {  + headers: {  + "HYH-Token": token + }, + data: { + newPass: newPass + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + mui.back(); + } else { + alert(data.msg); + } + that.removeAttr('disabled') + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app/js/setting_fogetPwd.js b/static/app/js/setting_fogetPwd.js new file mode 100755 index 0000000..48431d0 --- /dev/null +++ b/static/app/js/setting_fogetPwd.js @@ -0,0 +1,208 @@ +mui.plusReady(function() { + var wait = 120; + + function time() { + + if(wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + mui('.row').on('tap', '#mobileCode', function() { + var that = $(this); + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/getfindPhone'), {  + + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + time(); + } else { + alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + // alert(type);       + } + });  + }) + mui('.down').on('tap', '#true0', function() { + var loginName0 = $('#loginName0').val(); + var that = $(this); + if(loginName0 == '') { + alert('用户名不能为空!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/findPass'), {  + + data: { + loginName: loginName0, + step: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#con0').css('display', 'none'); + $('#down0').css('display', 'none'); + $('#con1').css('display', 'block'); + $('#down1').css('display', 'block'); + mui.ajax(hyhUrl('app/users/forgetPasst'), {  + + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#loginName').val(data.data.loginName); + $('#loginName').attr('disabled', 'disabled'); + $('#userPhone').val(data.data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/findPass'), {  + data: { + Checkcode: phoneCode, + modes: 1, + step: 2 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + //console.log(data); + //alert(1) + document.getElementById("con1").style.display = "none"; + document.getElementById("down1").style.display = "none"; + document.getElementById("con2").style.display = "block"; + document.getElementById("down2").style.display = "block"; + + //$('#con1').css('display', 'none'); + //$('#down1').css('display', 'none'); + //$('#con2').css('display', 'block'); + //$('#down2').css('display', 'block'); + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + alert(type);       + }   + });  + + }) + mui('.down').on('tap', '#true2', function() { + var loginPwd = $('#loginPwd').val(); + var repassword = $('#repassword').val(); + var that = $(this); + if(loginPwd == '') { + alert('登录密码不能为空!'); + return; + } else if(loginPwd.length < 6) { + alert('登录密码最少为6位!'); + return; + } else if(loginPwd != repassword) { + alert('两次支付密码不相同!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/findPass'), {  + data: { + step: 3, + loginPwd: loginPwd, + repassword: repassword + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + mui.back(); + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app/js/setting_loginInfo.js b/static/app/js/setting_loginInfo.js new file mode 100755 index 0000000..76fcf0a --- /dev/null +++ b/static/app/js/setting_loginInfo.js @@ -0,0 +1,34 @@ +mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +}) \ No newline at end of file diff --git a/static/app/js/setting_payPwd.js b/static/app/js/setting_payPwd.js new file mode 100755 index 0000000..f97c762 --- /dev/null +++ b/static/app/js/setting_payPwd.js @@ -0,0 +1,58 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + + mui('.down').on('tap', '#true', function() { + var that = $(this) + var oldPass = $('#oldPass').val(); + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + + if(oldPass == '') { + alert('原支付密码不能为空!'); + return; + } + if(newPass == '') { + alert('新支付密码不能为空!'); + return; + } + if(newPass.length != 6) { + alert('新支付密码长度为6位!'); + return; + } + if(!(newPass == newPass2)) { + alert('两次支付密码不一致!'); + return; + } + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/editpayPwd'), {  + + data: { + oldPass: oldPass, + newPass: newPass, + reNewPass:newPass2 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + alert(data.msg); + mui.back(); + + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + } + });  + }) + +}) \ No newline at end of file diff --git a/static/app/js/setting_phone.js b/static/app/js/setting_phone.js new file mode 100755 index 0000000..780cf45 --- /dev/null +++ b/static/app/js/setting_phone.js @@ -0,0 +1,256 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var isBang = 0; + var isOver = 1; + var wait = 120; + var wait1 = 120; + + function time() { + + if(wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + function time1() { + + if(wait1 == 0) { + $('#mobileCode1').removeAttr("disabled"); + $('#mobileCode1').val("重新发送"); + wait1 = 120; + } else { + $('#mobileCode1').attr("disabled", true); + $('#mobileCode1').val("重新发送(" + wait1 + ")"); + wait1--; + setTimeout(function() { + time1(); + }, + 1000) + } + + } + mui.ajax(hyhUrl('app/users/editPhone'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + + if(data.userPhone) { + isBang = 1; + $('#userPhone').val(data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + $('#next_btn').css('display', 'block'); + } else { + $('#true').css('display', 'block'); + } + } else { + alert(data.msg); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + mui('.row').on('tap', '.codeBtn', function() { + var that = $(this) + var userPhone = $('#userPhone').val(); + var url = $(this).attr('id') == 'mobileCode' ? 'sendCodeEdit' : 'sendCodeTie' + if(isBang == 0 || isOver == 0) { + if(userPhone == '') { + alert('手机号不能为空!'); + return; + + } + if(!(/^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/.test(userPhone))) { + alert("手机号码有误,请重填!"); + return; + } + } else { + userPhone = ''; + } + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/' + url), {  + + data: { + userPhone: userPhone + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + + if(that.attr('id') == 'mobileCode') { + time(); + } else if(that.attr('id') == 'mobileCode1') { + time1(); + } + + } else { + alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + // alert(type);       + } + });  + }) + //未绑定手机 + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/phoneEdit'), {  + headers: {  + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + mui.back(); + + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + //已绑定手机 1 + mui('.down').on('tap', '#next_btn', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/phoneEdito'), {  + headers: {  + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#next_btn').css('display', 'none'); + $('#next_true').css('display', 'block'); + $('#userPhone').removeAttr('disabled'); + $('#userPhone').val(''); + $('#phoneCode').val(''); + $('#mobileCode').css('display', 'none'); + $('#mobileCode1').css('display', 'block'); + isOver = 0; + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + //已绑定手机 2 + mui('.down').on('tap', '#next_true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/phoneEdit'), {  + headers: {  + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + mui.back(); + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app/js/setting_pwd.js b/static/app/js/setting_pwd.js new file mode 100755 index 0000000..7aa6563 --- /dev/null +++ b/static/app/js/setting_pwd.js @@ -0,0 +1,60 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + + mui('.down').on('tap', '#true', function() { + var that = $(this) + var oldPass = $('#oldPass').val(); + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + + if(oldPass == '') { + alert('原支付密码不能为空!'); + return; + } + if(newPass == '') { + alert('新支付密码不能为空!'); + return; + } + if(newPass.length < 6) { + alert('新支付密码不能小于6位!'); + return; + } + if(!(newPass == newPass2)) { + alert('两次支付密码不一致!'); + return; + } + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/editloginPwd'), {  + + data: { + oldPass: oldPass, + newPass: newPass + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + console.log(data.status) + if(data.status == 1) { + + alert(data.msg); + mui.back(); + + } else { + alert(data.msg); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + // alert(type);       + } + });  + }) + +}) \ No newline at end of file diff --git a/static/app/js/setting_user.js b/static/app/js/setting_user.js new file mode 100755 index 0000000..76fcf0a --- /dev/null +++ b/static/app/js/setting_user.js @@ -0,0 +1,34 @@ +mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +}) \ No newline at end of file diff --git a/static/app/js/share.js b/static/app/js/share.js new file mode 100755 index 0000000..528ae32 --- /dev/null +++ b/static/app/js/share.js @@ -0,0 +1,166 @@ + +var shares = null; +var Intent = null, + File = null, + Uri = null, + main = null; +// H5 plus事件处理 +function plusReady() { + updateSerivces(); + if(plus.os.name == "Android") { + main = plus.android.runtimeMainActivity(); + Intent = plus.android.importClass("android.content.Intent"); + File = plus.android.importClass("java.io.File"); + Uri = plus.android.importClass("android.net.Uri"); + } +} +if(window.plus) { + plusReady(); +} else { + document.addEventListener("plusready", plusReady, false); +} + +/** + * + * 更新分享服务 + */ +function updateSerivces() { + plus.share.getServices(function(s) { + shares = {}; + for(var i in s) { + var t = s[i]; + shares[t.id] = t; + } + }, function(e) { + plus.nativeUI.toast("获取分享服务列表失败:" + e.message); + }); +} + +/** + * 分享操作 + * @param {JSON} sb 分享操作对象s.s为分享通道对象(plus.share.ShareService) + * @param {Boolean} bh 是否分享链接 + */ +function shareAction(sb, bh) { + if(!sb || !sb.s) { + plus.nativeUI.toast("无效的分享服务!"); + return; + } + + var msg = { + content: sharehrefDes.value, + extra: { + scene: sb.x + } + }; + if(bh) { + msg.href = sharehref.value; + if(sharehrefTitle && sharehrefTitle.value != "") { + msg.title = sharehrefTitle.value; + } + if(sharehrefDes && sharehrefDes.value != "") { + msg.content = sharehrefDes.value; + } + msg.thumbs = ["_www/logo.png"]; + msg.pictures = ["_www/logo.png"]; + } else { + if(pic && pic.realUrl) { + msg.pictures = [pic.realUrl]; + } + } + // 发送分享 + if(sb.s.authenticated) { + // plus.nativeUI.toast("---已授权---"); + shareMessage(msg, sb.s); + } else { +// plus.nativeUI.toast("---未授权---"); + sb.s.authorize(function() { + shareMessage(msg, sb.s); + }, function(e) { + plus.nativeUI.toast("认证授权失败:" + e.code + " - " + e.message); +// alert("认证授权失败:"+e.code+" - "+e.message ); + }); + } +} +/** + * 发送分享消息 + * @param {JSON} msg + * @param {plus.share.ShareService} s + */ +function shareMessage(msg, s) { + +// plus.nativeUI.toast(JSON.stringify(msg)); + s.send(msg, function() { + plus.nativeUI.toast("分享到\"" + s.description + "\"成功! "); + + }, function(e) { + plus.nativeUI.toast("分享到\"" + s.description + "\"失败 "); +// alert( "分享到\""+s.description+"\"失败: "+JSON.stringify(e) ); + }); +} +// 分析链接 +function shareHref() { + var shareBts = []; + // 更新分享列表 + var ss = shares['weixin']; + ss && ss.nativeClient && (shareBts.push({ + title: '微信朋友圈', + s: ss, + x: 'WXSceneTimeline' + }), + shareBts.push({ + title: '微信好友', + s: ss, + x: 'WXSceneSession' + })); + + // 弹出分享列表 + shareBts.length > 0 ? plus.nativeUI.actionSheet({ + title: '分享注册链接', + cancel: '取消', + buttons: shareBts + }, function(e) { + (e.index > 0) && shareAction(shareBts[e.index - 1], true); + }) : plus.nativeUI.plus.nativeUI.toast('当前环境无法支持分享链接操作!'); +} + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui.ajax(hyhUrl('app/Users/get_share'), {  + + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + //读取成功后 + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 96, //设置宽高 + height: 96 + }); + qrcode.makeCode(data.data.url); +// console.log(hyhImgUrl(data.data.bg_share)) + $('.bg').attr('src',hyhImgUrl(data.data.bg_share)) + $('#sharehref').val(data.data.url) + $('#sharehrefTitle').val(data.data.title) + $('#sharehrefDes').val(data.data.desc) + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // plus.nativeUI.toast(type);     + }   + });  + $('header').on('tap','.share',function(){ + shareHref(); + }) +}); + diff --git a/static/app/js/share_user_list.js b/static/app/js/share_user_list.js new file mode 100755 index 0000000..c480814 --- /dev/null +++ b/static/app/js/share_user_list.js @@ -0,0 +1,99 @@ +var page = 1; +var userType = 0; +var isjiazai = 1; + +function getData(page, userType) { + var data_set = { + page: page ? page : 1, + userType: userType ? userType : 0 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + mui.ajax(hyhUrl('app/users/getShareList'), {  +// headers: {  +// "HYH-Token": token +// }, + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.Rows; + var html = ''; + if(data == '') { + isjiazai = 0; + $('.con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;padding-top: 9px;">没有更多内容</p>'); + return; + } + + $.each(data, function() { + var defaultImg = userType==0? 'http://heyuanhui.com.cn/Template/mobile/new/Static/images/user68.png' :'http://heyuanhui.com.cn/Template/mobile/new/Static/images/user68.png'; + + var userPhoto = this.userPhoto == '' ? defaultImg : hyhImgUrl(this.userPhoto); + html += '<div class="row"><div class="row_top clearfix"><img class="img" src="' + userPhoto + '"/><p>' + this.loginName + '</p><img class="btn" src="../img/xiajiantou.png"/></div><div class="row_hid" style="display: none;"><div class="row_h_r"><p>注册时间:' + this.createTime + '</p></div></div></div>' + }) + + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } +} + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui('.con').on('tap', '.row_top', function() { + if($(this).children('.btn').hasClass('ani')) { + $(this).children('.btn').removeClass('ani'); + $(this).siblings('.row_hid').slideUp(300); + } else { + $(this).children('.btn').addClass('ani'); + $(this).siblings('.row_hid').slideDown(300); + } + }) + mui('.nav').on('tap','.block',function(){ + + if($(this).attr('data-userType')=='users'){ + userType=0; + }else{ + userType=1; + } + if($(this).hasClass('on')){ + return; + }else{ + + $(this).addClass('on').siblings().removeClass('on'); + mui('#pullrefresh').scroll().scrollTo(0,0,0); + $('.con').html(''); + isjiazai=1; + page=1; + getData(page,userType); + } + }) + + getData(1, 0); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY&&scroll.y!=0) { + + if(isjiazai == 1) { + page++; + getData(page, userType); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app/js/shopGoodsList.js b/static/app/js/shopGoodsList.js new file mode 100755 index 0000000..03e33ea --- /dev/null +++ b/static/app/js/shopGoodsList.js @@ -0,0 +1,160 @@ +var msort = 1; +var page = 1; +var condition = 1; +var desc = 0; +var keyword; +var isjiazai = 1; +var count = 1; +var pagesize = 10; +var ct1; +var ct2; + +function pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2) { + // setTimeout(function() { + + // mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + + var data_set = { + page: page, + pagesize: pagesize, + shopId: shopId, + mdesc: desc, + msort: msort + goodsName: goodsName + } + // console.log(order_class) + if(isjiazai == 0) { + return; + }else{ + isjiazai = 0; + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + if(page == "1") { + $('.cnxh_con').html(html); + } else { + $('.cnxh_con').append(html); + } + isjiazai = 1; + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + // }, 500); +} + +mui.plusReady(function() { + var shopId = localStorage.getItem('shopId') + var costnum = 0; + var self = plus.webview.currentWebview(); + keyword = self.data_keyword; + + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + isjiazai = 1; + $(this).addClass('on').siblings().removeClass('on'); + + msort = $(this).attr('data-condition'); + + if($('#cost_btn').hasClass('on')) { + + costnum += 1; + + if(costnum % 2 == 1) { + + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + + desc = 1; + + } else if(costnum % 2 == 0) { + + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + + desc = 0; + + } + + } else { + + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + + costnum = 0; + desc = 0 + } + pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2) + + }) + + $('.cnxh_con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2); + } + + } + }) + +}) + +// setInterval(function() { +// $('.cnxh_block img').height($('.cnxh_block img').width()); +// $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +// }, 100) \ No newline at end of file diff --git a/static/app/js/shoppingcart.js b/static/app/js/shoppingcart.js new file mode 100755 index 0000000..9e3d021 --- /dev/null +++ b/static/app/js/shoppingcart.js @@ -0,0 +1,475 @@ +mui.plusReady(function() { + // var scroll = mui('.mui-scroll-wrapper').scroll({ + // deceleration: 0.002 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + // }); + window.addEventListener('refresh', function(e) { + location.reload(); + }) + + function getCost() { + var cost = 0; + $('.check2').each(function() { + if($(this).children().hasClass('check_1')) { + + cost += ((+$(this).siblings('.b_con_r1').children('.bz').children('.cost').children('o').html()) * (+$(this).siblings('.b_con_r1').children('.bz').children('.num').children('o').html())) + } + }) + + $('.js_r span j').html('¥' + cost.toFixed(2)); + } + + function isChecks() { + + $('.check1').each(function() { + var isChecks = 1; + $(this).parent().siblings().children().find('.checks').each(function() { + if($(this).hasClass('check_0')) { + isChecks = 0; + } + }) + if(isChecks == 0) { + $(this).children().removeClass('check_1').addClass('check_0'); + } else { + $(this).children().removeClass('check_0').addClass('check_1'); + } + }) + + } + + mui.ajax(hyhUrl('app/carts/index'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html = ''; + $('header').html('购物车(' + data.all_carts_num + ')'); + var allids = []; + $.each(data.carts, function() { + var ids = []; + + $.each(this.list, function() { + ids.push(this.cartId); + allids.push(this.cartId); + }); + var idsStr = ids.join(','); + html += '<div class="block"><div class="b_title clearfix"><div class="check1" data-idsStr="' + idsStr + '"><div class="checks check_0"></div></div><img src="../img/icon_shop.png" /><div class="b_link"><a href="#" data-shopId="' + this.shopId + '">' + this.shopName + '</a></div><img src="../img/icon_right.png" /><div class="btn_bj">编辑</div></div><div class="bcon">'; + $.each(this.list, function() { + + html += '<div class="b_con clearfix"><div class="check2" data-cartId="' + this.cartId + '" data-cartNum="' + this.cartNum + '" data-isCheck="' + this.isCheck + '"><div class="checks check_0"></div></div><img class="s_img" src="' + hyhImgUrl(this.goodsImg) + '" /><div class="b_con_r1" data-goodsId="' + this.goodsId + '" style="display: block;"><p class="p1">' + this.goodsName + '</p><p class="p2">'; + $.each(this.specNames, function() { + html += this.catName + ':' + this.itemName + ';'; + }); + var price; + if(this.specPrice != null) { + price = this.specPrice; + } else { + price = this.shopPrice; + } + html += '</p><div class="bz clearfix"><span class="cost">¥<o>' + price + '</o>&nbsp;&nbsp;</span><del class="oldcost">¥'+ this.marketPrice +'</del><span class="num">×<o>' + this.cartNum + '</o></span></div></div><div class="b_con_r2 clearfix" style="display: none;"><div class="b_con_r2_l"><div class="changenum clearfix" data-cartId="' + this.cartId + '"><img class="jian" src="../img/jian.png" /><input type="number" name="" id="" value="' + this.cartNum + '" /><img class="jia" src="../img/jia.png" /></div></div><div class="b_con_r2_del" data-cartId="' + this.cartId + '">删除</div></div></div>'; + }); + + html += '</div></div>'; + + }); + var allIdsStr = allids.join(','); + + $('.con').html(html) + $('.check').attr('data-allIdsStr', allIdsStr); + $('.checks').each(function() { + if($(this).parent().attr('data-isCheck') == '1') { + $(this).removeClass('check_0').addClass('check_1'); + } + }) + getCost(); + isChecks(); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + $('.con').on('tap', '.b_link', function() { + var shopId = $(this).children('a').attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con').on('tap', '.b_con_r1', function() { + var data_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.check').on('tap', function() { + var isCheck; + var ids = $(this).attr('data-allIdsStr'); + if($('.check').children('.checks').hasClass('check_0')) { + $('.check').children('.checks').removeClass('check_0').addClass('check_1'); + $('.check1').children('.checks').removeClass('check_0').addClass('check_1'); + $('.check2').children('.checks').removeClass('check_0').addClass('check_1'); + isCheck = 1; + } else { + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + $('.check1').children('.checks').removeClass('check_1').addClass('check_0'); + $('.check2').children('.checks').removeClass('check_1').addClass('check_0'); + isCheck = 0; + } + getCost(); + isChecks(); + mui.ajax(hyhUrl('app/carts/batchChangeCartGoods'), {  + data: { + ids: ids, + isCheck: isCheck + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + }); + }); + + $('.con').on('tap', '.check1', function(e) { + e.stopPropagation(); + var that = $(this); + var isCheck; + var ids = $(this).attr('data-idsStr'); + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + if(that.children('.checks').hasClass('check_0')) { + isCheck = 1; + that.children('.checks').removeClass('check_0').addClass('check_1'); + that.parent().siblings().children().find('.check2').children('.checks').removeClass('check_0').addClass('check_1'); + } else { + isCheck = 0; + that.children('.checks').removeClass('check_1').addClass('check_0'); + that.parent().siblings().children().find('.check2').children('.checks').removeClass('check_1').addClass('check_0'); + } + getCost(); + isChecks(); + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/batchChangeCartGoods'), {  + data: { + ids: ids, + isCheck: isCheck + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data); + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + }); + + }); + + $('.con').on('tap', '.check2', function(e) { + //console.log() + e.stopPropagation(); + var isCheck; + var cartId = $(this).attr('data-cartId'); + var that = $(this); + var buyNum = $(this).attr('data-cartNum'); + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + if($(this).children().hasClass('check_0')) { + $(this).parent().parent().siblings().children('.check1').children('.checks').removeClass('check_1').addClass('check_0'); + $(this).children('.checks').removeClass('check_0').addClass('check_1'); + isCheck = 1; + } else { + $(this).children('.checks').removeClass('check_1').addClass('check_0'); + isCheck = 0; + } + getCost(); + isChecks() + $(this).attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/changeCartGoods'), {  + data: { + id: cartId, + isCheck: isCheck, + buyNum: buyNum + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data, 1); + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }); + + $('.con').on('tap', '.btn_bj', function(e) { + e.stopPropagation() + if($(this).html() == '编辑') { + $(this).html('完成'); + $(this).parent().siblings().children().find('.b_con_r1').css('display', 'none'); + $(this).parent().siblings().children().find('.b_con_r2').css('display', 'block'); + } else { + $(this).html('编辑'); + $(this).parent().siblings().children().find('.b_con_r2').css('display', 'none'); + $(this).parent().siblings().children().find('.b_con_r1').css('display', 'block'); + var inputArr = $(this).parent().siblings().find('input') + + $(this).parent().siblings().find('.num').each(function(num) { + $(this).html('×<o>' + inputArr.eq(num).val() + '</o>'); + }) + + } + // console.log($(this).parent().siblings().find('.commodity_num')) + // console.log($(this).parent().siblings().find('input')); + if($(this).html() == '完成') { + return; + } + getCost() + }) + + $('.con').on('tap', '.jia', function() { + // console.log($(this).siblings('input').val()) + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).siblings('input').val() + 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/changeCartGoods'), {  + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + $('.con').on('tap', '.jian', function() { + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).siblings('input').val() - 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/changeCartGoods'), {  + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + $('.con').on('blur', 'input', function() { + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).val(); + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/changeCartGoods'), {  + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + + $('.con').on('tap', '.b_con_r2_del', function() { + var cartId = $(this).attr('data-cartId'); + + if(confirm('确定删除?')) { + mui.ajax(hyhUrl('app/carts/delCart'), {  + data: { + id: cartId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否;登录成功;   + var data = toJson(data, 1); + location.reload(); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + }) + + // $('.changeclass').on('tap', '.selectclass', function() { + // $('.mui-backdrop').show(); + // }) + + //选择类型 + // $('.cclass1').on('tap', '.block', function() { + // $(this).addClass('on').siblings().removeClass('on'); + // $(this).parent().attr('data-class', $(this).html()); + // }) + + // $('.closecclass').on('tap', function() { + // $('.mui-backdrop').css('display', 'none'); + // }) + + // $('.ensure').on('tap', function() { + // $('.mui-backdrop').css('display', 'none'); + // }) + + mui('.js').on('tap', '.btn_tj', function() { + var check_length = $('.check_1').length; + if(check_length == 0) { + alert('请选择商品结算!'); + return; + } + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + + type: 0 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app/js/shopsList.js b/static/app/js/shopsList.js new file mode 100755 index 0000000..4f18024 --- /dev/null +++ b/static/app/js/shopsList.js @@ -0,0 +1,137 @@ +var page = 1; +var pagesize = 10; +var condition = 1; +var isjiazai = 1; +var desc = 0; + +function getData(page, pagesize, condition, keyword, desc) { + var data_set = { + page: page, + pagesize: pagesize, + condition: condition, + keyword: keyword, + desc: desc + } + mui.ajax(hyhUrl('app/shops/pageQuery'), {  + + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多店铺</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.shopCompany + '</p><div class="btn_gz">进店</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<div data-goodId="' + this.goodsId + '" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + +} +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + keyword = self.data_keyword; + getData(page, pagesize, 1, keyword, 0) + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.bc_img', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + isjiazai = 0; + page++; + getData(page, pagesize, 1, keyword, 0) + } + + } + }) +}) \ No newline at end of file diff --git a/static/app/js/store_activity.js b/static/app/js/store_activity.js new file mode 100755 index 0000000..fc368ac --- /dev/null +++ b/static/app/js/store_activity.js @@ -0,0 +1,68 @@ +$('.con').html(''); +var shopId = localStorage.getItem('shopId') +mui.plusReady(function() { + + $('.con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) + +mui.ajax(hyhUrl('app/Shops/getReward'), {  + data: { + shopId: shopId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.reward) { + $.each(data.reward.Rows, function() { + html += '<div class="block"><div class="b_title"><img class="img" src="' + hyhImgUrl(this.goodsImg) + '" /><img class="clock" src="../img/icon_clock.png" alt="" /><p class="p1">' + this.startDate + '至' + this.endDate + '</p><p class="p2">' + this.rewardTitle + '</p></div><div class="b_con con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + ' </p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + }); + } + + $('.con').html(html); + } else { + // console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   +}); \ No newline at end of file diff --git a/static/app/js/store_class.js b/static/app/js/store_class.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/store_commodity.js b/static/app/js/store_commodity.js new file mode 100755 index 0000000..4552dd5 --- /dev/null +++ b/static/app/js/store_commodity.js @@ -0,0 +1,202 @@ +$('.cnxh_con').html(''); +var msort = 1; +var shopId = localStorage.getItem('shopId') +var page = 1; +var condition = 1; +var desc = 0; +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + + data: { + page: count, + shopId: shopId, + pageSize: 10, + msort: condition, + mdesc: desc + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').append(html); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var costnum = 0; + + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + count = 1; + $(this).addClass('on').siblings().removeClass('on'); + + condition = $(this).attr('data-condition'); + + if($('#cost_btn').hasClass('on')) { + + costnum += 1; + + if(costnum % 2 == 1) { + + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + + desc = 0; + + } else if(costnum % 2 == 0) { + + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + + desc = 1; + + } + + } else { + + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + + costnum = 0; + desc = 1 + } + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + data: { + shopId: shopId, + pageSize: 10, + page: 1, + msort: condition, + mdesc: desc + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').html(html); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + data: { + shopId: shopId, + pageSize: 10, + page: 1, + msort: 1, + mdesc: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').html(html); + $('.cnxh_block .img').height($('.cnxh_block .img').width()); + + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + $('.cnxh_con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) + +setInterval(function() { + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +}, 100) \ No newline at end of file diff --git a/static/app/js/store_home.js b/static/app/js/store_home.js new file mode 100755 index 0000000..52c88bd --- /dev/null +++ b/static/app/js/store_home.js @@ -0,0 +1,75 @@ +mui.plusReady(function() { + var data = JSON.parse(localStorage.getItem('shop_data')); + if(data.shop.shopAds.length > 0) { + var html1 = '<div class="mui-slider-group mui-slider-loop"><div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.shop.shopAds[data.shop.shopAds.length - 1].adImg) + '"></a></div>'; + var html2 = '<div class="mui-slider-indicator">'; + $.each(data.shop.shopAds, function() { + html1 += '<div class="mui-slider-item "><a href="#"><img src="' + hyhImgUrl(this.adImg) + '"></a></div>'; + html2 += '<div class="mui-indicator"></div>'; + }); + html2 += '</div>'; + html1 += '<div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.shop.shopAds[0].adImg) + '"></a></div></div>' + html1 += html2; + $('#slider').html(html1); + mui("#slider").slider({ + interval: 5000 + }); + } else { + $('#slider').remove() + } + var html3 = ''; + $.each(data.shopcats, function() { + html3 += '<div data-catId="' + this.catId + '" class="l_block">' + this.catName + '</div>'; + }); + $('.label').html(html3); + $('.l_block').each(function(num) { + if((num + 1) % 4 == 0) { + $(this).addClass('lbrr'); + } + }) + var html = ''; + $.each(data.rec, function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + Math.round(this.shopPrice * 0.8 * 100) / 100 + '<o>到手价</o><del>¥' + this.shopPrice + '</del></p><p class="cost_info">可用惠宝抵扣20%货款</p></div></div>' + }); + $('.cnxh_con').html(html); + $('.cnxh_con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details1.html'+good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + localStorage.setItem('shop_data',''); +}) + +setInterval(function() { + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +}, 200) \ No newline at end of file diff --git a/static/app/js/store_info.js b/static/app/js/store_info.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/store_new.js b/static/app/js/store_new.js new file mode 100755 index 0000000..5d19b7a --- /dev/null +++ b/static/app/js/store_new.js @@ -0,0 +1,183 @@ +$('.con').html(''); +var shopId = localStorage.getItem('shopId'); + +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + + data: { + page: count, + shopId: shopId, + pageSize: 10, + msort: 6, + mdesc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + var obj = {}; + $.each(data.Rows, function() { + if(!obj[this.saleTime]) { + obj[this.saleTime] = [this] + } else { + obj[this.saleTime].push(this) + } + + }); + for(var i in obj) { + + if(obj[i].length == 1) { + html += '<div class="con_two con_goods" data-id="' + obj[i][0].goodsId + '"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="ct_con"><img src="' + hyhImgUrl(obj[i][0].goodsImg) + '" /><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + obj[i][0].shopPrice + '<o>' + obj[i][0].saleNum + '人付款</o></p></div></div>' + } else { + html += '<div class="con_one"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="cnxh_con clearfix">' + $.each(obj[i], function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + this.shopPrice + '<o>' + this.saleNum + '人付款</o></p></div></div>' + }); + html += '</div></div>' + + } + + } + + $('.con').append(html); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + + $('.con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) + +mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + data: { + shopId: shopId, + pageSize: 10, + page: 1, + msort: 6, + mdesc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + + var html = ''; + var obj = {}; + $.each(data.Rows, function() { + if(!obj[this.saleTime]) { + obj[this.saleTime] = [this] + } else { + obj[this.saleTime].push(this) + } + + }); + for(var i in obj) { + + if(obj[i].length == 1) { + html += '<div class="con_two con_goods" data-id="' + obj[i][0].goodsId + '"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="ct_con"><img src="' + hyhImgUrl(obj[i][0].goodsImg) + '" /><p class="s_name">' + obj[i][0].goodsName + '</p><p class="cost">¥' + obj[i][0].shopPrice + '<o>' + obj[i][0].saleNum + '人付款</o></p></div></div>' + } else { + html += '<div class="con_one"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="cnxh_con clearfix">' + $.each(obj[i], function() { + html += '<div class="cnxh_block con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="cnxh_block_info"><p class="s_name">' + this.goodsName + '</p><p class="cost">¥' + this.shopPrice + '<o>' + this.saleNum + '人付款</o></p></div></div>' + }); + html += '</div></div>' + + } + + } + + $('.con').html(html); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   +});  + +setInterval(function() { + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +}, 200) \ No newline at end of file diff --git a/static/app/js/storeout.js b/static/app/js/storeout.js new file mode 100755 index 0000000..4dded64 --- /dev/null +++ b/static/app/js/storeout.js @@ -0,0 +1,262 @@ +jumpPage(); +mui.plusReady(function() { + var data = ''; + var self = plus.webview.currentWebview(); + var shopId = self.shopId; + localStorage.setItem('shopId', shopId); + mui.ajax(hyhUrl('app/Shops/getHome'), {  + data: { + shopId: shopId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + data = data.data; + localStorage.setItem('shop_data', JSON.stringify(data)) + var html = '<div class="search clearfix"><a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a><div class="searchcon clearfix"><input type="search" name="" id="keyword" value="" placeholder="请输入商品名" /><button style="display: none;">搜索</button></div><img style="display:none;" class="classmenu" data-shopid="' + data.shop.shopId + '" src="../img/classmenu.png" /></div><div class="b_title" data-shopid="' + data.shop.shopId + '"><img class="b_img" src="' + hyhImgUrl(data.shop.shopImg) + '"/><p class="storename">' + data.shop.shopName + '</p><p class="time">' + data.shop.scores.totalScore + '分</p><div class="gz_btn">关注</div></div>'; + $('.header').html(html); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + // mui('.footer').on('tap','#dpxq',function(){ + // var w = plus.webview.create('store_info.html'); + // w.show() + // }) + mui('.search').on('tap', '.classmenu', function() { + shopId = this.attributes["data-shopid"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'store_class.html', + id: 'store_class.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + // mui('.footer').on('tap','#rmfl',function(){ + // $('.rmfl').css('display','block') + // }) + mui('.header').on('tap', '.gz_btn', function() { + + var shopId = $(this).parent().attr('data-shopid'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/add'), {  + + data: { + id: shopId, + type : 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + that.html('已关注'); + that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + + }) + $('.header').on('focus','#keyword', function() { + $(".searchcon button").css('display', 'block'); + }) + $('.header').on('blur','#keyword', function() { + $(".searchcon button").css('display', 'none'); + }) + + + + //店铺搜索 + $(".header").on('keypress','#keyword', function(e) { + var keycode = e.keyCode; + var searchName = $('#keyword').val(); + if(keycode == '13') { + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'goodsList.html', + id: 'goodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + $(".header").on('tap','.searchcon button', function(e) { + var searchName = $('#keyword').val(); + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'goodsList.html', + id: 'goodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }); + +}) + +function jumpPage() { + //跳转页面 + var subpages = ['store_home.html', 'store_commodity.html', 'store_new.html', 'store_activity.html']; + var subpage_style = { + top: '178px', + bottom: '0', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if(targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if(mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + + var html = $(this).html(); + html = html.substring(0, html.indexOf('.png')) + '_on.png">'; + $(this).html(html); + $(this).addClass('on').siblings().removeClass('on'); + $(this).siblings().each(function() { + if($(this).html().indexOf('_on') == -1) { + return + } + html = $(this).html().substring(0, $(this).html().indexOf('_on')) + html = html + '.png">'; + $(this).html(html) + }) + }); + + //首次启动切滑效果 + + mui.plusReady(function() { + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + shopId = self.shopId; + //console.log(shopId); + localStorage.setItem('shopId', shopId); + + for(var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if(i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + }); +} \ No newline at end of file diff --git a/static/app/js/swiper.min.js b/static/app/js/swiper.min.js new file mode 100755 index 0000000..03a652f --- /dev/null +++ b/static/app/js/swiper.min.js @@ -0,0 +1,19 @@ +/** + * Swiper 3.4.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2017, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: March 10, 2017 + */ +!function(){"use strict";var e,a=function(s,i){function r(e){return Math.floor(e)}function n(){var e=T.params.autoplay,a=T.slides.eq(T.activeIndex);a.attr("data-swiper-autoplay")&&(e=a.attr("data-swiper-autoplay")||T.params.autoplay),T.autoplayTimeoutId=setTimeout(function(){T.params.loop?(T.fixLoop(),T._slideNext(),T.emit("onAutoplay",T)):T.isEnd?i.autoplayStopOnLast?T.stopAutoplay():(T._slideTo(0),T.emit("onAutoplay",T)):(T._slideNext(),T.emit("onAutoplay",T))},e)}function o(a,t){var s=e(a.target);if(!s.is(t))if("string"==typeof t)s=s.parents(t);else if(t.nodeType){var i;return s.parents().each(function(e,a){a===t&&(i=t)}),i?t:void 0}if(0!==s.length)return s[0]}function l(e,a){a=a||{};var t=window.MutationObserver||window.WebkitMutationObserver,s=new t(function(e){e.forEach(function(e){T.onResize(!0),T.emit("onObserverUpdate",T,e)})});s.observe(e,{attributes:void 0===a.attributes||a.attributes,childList:void 0===a.childList||a.childList,characterData:void 0===a.characterData||a.characterData}),T.observers.push(s)}function p(e){e.originalEvent&&(e=e.originalEvent);var a=e.keyCode||e.charCode;if(!T.params.allowSwipeToNext&&(T.isHorizontal()&&39===a||!T.isHorizontal()&&40===a))return!1;if(!T.params.allowSwipeToPrev&&(T.isHorizontal()&&37===a||!T.isHorizontal()&&38===a))return!1;if(!(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||document.activeElement&&document.activeElement.nodeName&&("input"===document.activeElement.nodeName.toLowerCase()||"textarea"===document.activeElement.nodeName.toLowerCase()))){if(37===a||39===a||38===a||40===a){var t=!1;if(T.container.parents("."+T.params.slideClass).length>0&&0===T.container.parents("."+T.params.slideActiveClass).length)return;var s={left:window.pageXOffset,top:window.pageYOffset},i=window.innerWidth,r=window.innerHeight,n=T.container.offset();T.rtl&&(n.left=n.left-T.container[0].scrollLeft);for(var o=[[n.left,n.top],[n.left+T.width,n.top],[n.left,n.top+T.height],[n.left+T.width,n.top+T.height]],l=0;l<o.length;l++){var p=o[l];p[0]>=s.left&&p[0]<=s.left+i&&p[1]>=s.top&&p[1]<=s.top+r&&(t=!0)}if(!t)return}T.isHorizontal()?(37!==a&&39!==a||(e.preventDefault?e.preventDefault():e.returnValue=!1),(39===a&&!T.rtl||37===a&&T.rtl)&&T.slideNext(),(37===a&&!T.rtl||39===a&&T.rtl)&&T.slidePrev()):(38!==a&&40!==a||(e.preventDefault?e.preventDefault():e.returnValue=!1),40===a&&T.slideNext(),38===a&&T.slidePrev()),T.emit("onKeyPress",T,a)}}function d(e){var a=0,t=0,s=0,i=0;return"detail"in e&&(t=e.detail),"wheelDelta"in e&&(t=-e.wheelDelta/120),"wheelDeltaY"in e&&(t=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(a=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(a=t,t=0),s=10*a,i=10*t,"deltaY"in e&&(i=e.deltaY),"deltaX"in e&&(s=e.deltaX),(s||i)&&e.deltaMode&&(1===e.deltaMode?(s*=40,i*=40):(s*=800,i*=800)),s&&!a&&(a=s<1?-1:1),i&&!t&&(t=i<1?-1:1),{spinX:a,spinY:t,pixelX:s,pixelY:i}}function u(e){e.originalEvent&&(e=e.originalEvent);var a=0,t=T.rtl?-1:1,s=d(e);if(T.params.mousewheelForceToAxis)if(T.isHorizontal()){if(!(Math.abs(s.pixelX)>Math.abs(s.pixelY)))return;a=s.pixelX*t}else{if(!(Math.abs(s.pixelY)>Math.abs(s.pixelX)))return;a=s.pixelY}else a=Math.abs(s.pixelX)>Math.abs(s.pixelY)?-s.pixelX*t:-s.pixelY;if(0!==a){if(T.params.mousewheelInvert&&(a=-a),T.params.freeMode){var i=T.getWrapperTranslate()+a*T.params.mousewheelSensitivity,r=T.isBeginning,n=T.isEnd;if(i>=T.minTranslate()&&(i=T.minTranslate()),i<=T.maxTranslate()&&(i=T.maxTranslate()),T.setWrapperTransition(0),T.setWrapperTranslate(i),T.updateProgress(),T.updateActiveIndex(),(!r&&T.isBeginning||!n&&T.isEnd)&&T.updateClasses(),T.params.freeModeSticky?(clearTimeout(T.mousewheel.timeout),T.mousewheel.timeout=setTimeout(function(){T.slideReset()},300)):T.params.lazyLoading&&T.lazy&&T.lazy.load(),T.emit("onScroll",T,e),T.params.autoplay&&T.params.autoplayDisableOnInteraction&&T.stopAutoplay(),0===i||i===T.maxTranslate())return}else{if((new window.Date).getTime()-T.mousewheel.lastScrollTime>60)if(a<0)if(T.isEnd&&!T.params.loop||T.animating){if(T.params.mousewheelReleaseOnEdges)return!0}else T.slideNext(),T.emit("onScroll",T,e);else if(T.isBeginning&&!T.params.loop||T.animating){if(T.params.mousewheelReleaseOnEdges)return!0}else T.slidePrev(),T.emit("onScroll",T,e);T.mousewheel.lastScrollTime=(new window.Date).getTime()}return e.preventDefault?e.preventDefault():e.returnValue=!1,!1}}function c(a,t){a=e(a);var s,i,r,n=T.rtl?-1:1;s=a.attr("data-swiper-parallax")||"0",i=a.attr("data-swiper-parallax-x"),r=a.attr("data-swiper-parallax-y"),i||r?(i=i||"0",r=r||"0"):T.isHorizontal()?(i=s,r="0"):(r=s,i="0"),i=i.indexOf("%")>=0?parseInt(i,10)*t*n+"%":i*t*n+"px",r=r.indexOf("%")>=0?parseInt(r,10)*t+"%":r*t+"px",a.transform("translate3d("+i+", "+r+",0px)")}function m(e){return 0!==e.indexOf("on")&&(e=e[0]!==e[0].toUpperCase()?"on"+e[0].toUpperCase()+e.substring(1):"on"+e),e}if(!(this instanceof a))return new a(s,i);var h={direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,autoplay:!1,autoplayDisableOnInteraction:!0,autoplayStopOnLast:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flip:{slideShadows:!0,limitRotation:!0},cube:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fade:{crossFade:!1},parallax:!1,zoom:!1,zoomMax:3,zoomMin:1,zoomToggle:!0,scrollbar:null,scrollbarHide:!0,scrollbarDraggable:!1,scrollbarSnapOnRelease:!1,keyboardControl:!1,mousewheelControl:!1,mousewheelReleaseOnEdges:!1,mousewheelInvert:!1,mousewheelForceToAxis:!1,mousewheelSensitivity:1,mousewheelEventsTarged:"container",hashnav:!1,hashnavWatchState:!1,history:!1,replaceState:!1,breakpoints:void 0,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,onlyExternal:!1,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,uniqueNavElements:!0,pagination:null,paginationElement:"span",paginationClickable:!1,paginationHide:!1,paginationBulletRender:null,paginationProgressRender:null,paginationFractionRender:null,paginationCustomRender:null,paginationType:"bullets",resistance:!0,resistanceRatio:.85,nextButton:null,prevButton:null,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,lazyLoading:!1,lazyLoadingInPrevNext:!1,lazyLoadingInPrevNextAmount:1,lazyLoadingOnTransitionStart:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,control:void 0,controlInverse:!1,controlBy:"slide",normalizeSlideIndex:!0,allowSwipeToPrev:!0,allowSwipeToNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",passiveListeners:!0,containerModifierClass:"swiper-container-",slideClass:"swiper-slide",slideActiveClass:"swiper-slide-active",slideDuplicateActiveClass:"swiper-slide-duplicate-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slideDuplicateNextClass:"swiper-slide-duplicate-next",slidePrevClass:"swiper-slide-prev",slideDuplicatePrevClass:"swiper-slide-duplicate-prev",wrapperClass:"swiper-wrapper",bulletClass:"swiper-pagination-bullet",bulletActiveClass:"swiper-pagination-bullet-active",buttonDisabledClass:"swiper-button-disabled",paginationCurrentClass:"swiper-pagination-current",paginationTotalClass:"swiper-pagination-total",paginationHiddenClass:"swiper-pagination-hidden",paginationProgressbarClass:"swiper-pagination-progressbar",paginationClickableClass:"swiper-pagination-clickable",paginationModifierClass:"swiper-pagination-",lazyLoadingClass:"swiper-lazy",lazyStatusLoadingClass:"swiper-lazy-loading",lazyStatusLoadedClass:"swiper-lazy-loaded",lazyPreloaderClass:"swiper-lazy-preloader",notificationClass:"swiper-notification",preloaderClass:"preloader",zoomContainerClass:"swiper-zoom-container",observer:!1,observeParents:!1,a11y:!1,prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}",runCallbacksOnInit:!0},g=i&&i.virtualTranslate;i=i||{};var f={};for(var v in i)if("object"!=typeof i[v]||null===i[v]||(i[v].nodeType||i[v]===window||i[v]===document||void 0!==t&&i[v]instanceof t||"undefined"!=typeof jQuery&&i[v]instanceof jQuery))f[v]=i[v];else{f[v]={};for(var w in i[v])f[v][w]=i[v][w]}for(var y in h)if(void 0===i[y])i[y]=h[y];else if("object"==typeof i[y])for(var x in h[y])void 0===i[y][x]&&(i[y][x]=h[y][x]);var T=this;if(T.params=i,T.originalParams=f,T.classNames=[],void 0!==e&&void 0!==t&&(e=t),(void 0!==e||(e=void 0===t?window.Dom7||window.Zepto||window.jQuery:t))&&(T.$=e,T.currentBreakpoint=void 0,T.getActiveBreakpoint=function(){if(!T.params.breakpoints)return!1;var e,a=!1,t=[];for(e in T.params.breakpoints)T.params.breakpoints.hasOwnProperty(e)&&t.push(e);t.sort(function(e,a){return parseInt(e,10)>parseInt(a,10)});for(var s=0;s<t.length;s++)(e=t[s])>=window.innerWidth&&!a&&(a=e);return a||"max"},T.setBreakpoint=function(){var e=T.getActiveBreakpoint();if(e&&T.currentBreakpoint!==e){var a=e in T.params.breakpoints?T.params.breakpoints[e]:T.originalParams,t=T.params.loop&&a.slidesPerView!==T.params.slidesPerView;for(var s in a)T.params[s]=a[s];T.currentBreakpoint=e,t&&T.destroyLoop&&T.reLoop(!0)}},T.params.breakpoints&&T.setBreakpoint(),T.container=e(s),0!==T.container.length)){if(T.container.length>1){var b=[];return T.container.each(function(){b.push(new a(this,i))}),b}T.container[0].swiper=T,T.container.data("swiper",T),T.classNames.push(T.params.containerModifierClass+T.params.direction),T.params.freeMode&&T.classNames.push(T.params.containerModifierClass+"free-mode"),T.support.flexbox||(T.classNames.push(T.params.containerModifierClass+"no-flexbox"),T.params.slidesPerColumn=1),T.params.autoHeight&&T.classNames.push(T.params.containerModifierClass+"autoheight"),(T.params.parallax||T.params.watchSlidesVisibility)&&(T.params.watchSlidesProgress=!0),T.params.touchReleaseOnEdges&&(T.params.resistanceRatio=0),["cube","coverflow","flip"].indexOf(T.params.effect)>=0&&(T.support.transforms3d?(T.params.watchSlidesProgress=!0,T.classNames.push(T.params.containerModifierClass+"3d")):T.params.effect="slide"),"slide"!==T.params.effect&&T.classNames.push(T.params.containerModifierClass+T.params.effect),"cube"===T.params.effect&&(T.params.resistanceRatio=0,T.params.slidesPerView=1,T.params.slidesPerColumn=1,T.params.slidesPerGroup=1,T.params.centeredSlides=!1,T.params.spaceBetween=0,T.params.virtualTranslate=!0),"fade"!==T.params.effect&&"flip"!==T.params.effect||(T.params.slidesPerView=1,T.params.slidesPerColumn=1,T.params.slidesPerGroup=1,T.params.watchSlidesProgress=!0,T.params.spaceBetween=0,void 0===g&&(T.params.virtualTranslate=!0)),T.params.grabCursor&&T.support.touch&&(T.params.grabCursor=!1),T.wrapper=T.container.children("."+T.params.wrapperClass),T.params.pagination&&(T.paginationContainer=e(T.params.pagination),T.params.uniqueNavElements&&"string"==typeof T.params.pagination&&T.paginationContainer.length>1&&1===T.container.find(T.params.pagination).length&&(T.paginationContainer=T.container.find(T.params.pagination)),"bullets"===T.params.paginationType&&T.params.paginationClickable?T.paginationContainer.addClass(T.params.paginationModifierClass+"clickable"):T.params.paginationClickable=!1,T.paginationContainer.addClass(T.params.paginationModifierClass+T.params.paginationType)),(T.params.nextButton||T.params.prevButton)&&(T.params.nextButton&&(T.nextButton=e(T.params.nextButton),T.params.uniqueNavElements&&"string"==typeof T.params.nextButton&&T.nextButton.length>1&&1===T.container.find(T.params.nextButton).length&&(T.nextButton=T.container.find(T.params.nextButton))),T.params.prevButton&&(T.prevButton=e(T.params.prevButton),T.params.uniqueNavElements&&"string"==typeof T.params.prevButton&&T.prevButton.length>1&&1===T.container.find(T.params.prevButton).length&&(T.prevButton=T.container.find(T.params.prevButton)))),T.isHorizontal=function(){return"horizontal"===T.params.direction},T.rtl=T.isHorizontal()&&("rtl"===T.container[0].dir.toLowerCase()||"rtl"===T.container.css("direction")),T.rtl&&T.classNames.push(T.params.containerModifierClass+"rtl"),T.rtl&&(T.wrongRTL="-webkit-box"===T.wrapper.css("display")),T.params.slidesPerColumn>1&&T.classNames.push(T.params.containerModifierClass+"multirow"),T.device.android&&T.classNames.push(T.params.containerModifierClass+"android"),T.container.addClass(T.classNames.join(" ")),T.translate=0,T.progress=0,T.velocity=0,T.lockSwipeToNext=function(){T.params.allowSwipeToNext=!1,T.params.allowSwipeToPrev===!1&&T.params.grabCursor&&T.unsetGrabCursor()},T.lockSwipeToPrev=function(){T.params.allowSwipeToPrev=!1,T.params.allowSwipeToNext===!1&&T.params.grabCursor&&T.unsetGrabCursor()},T.lockSwipes=function(){T.params.allowSwipeToNext=T.params.allowSwipeToPrev=!1,T.params.grabCursor&&T.unsetGrabCursor()},T.unlockSwipeToNext=function(){T.params.allowSwipeToNext=!0,T.params.allowSwipeToPrev===!0&&T.params.grabCursor&&T.setGrabCursor()},T.unlockSwipeToPrev=function(){T.params.allowSwipeToPrev=!0,T.params.allowSwipeToNext===!0&&T.params.grabCursor&&T.setGrabCursor()},T.unlockSwipes=function(){T.params.allowSwipeToNext=T.params.allowSwipeToPrev=!0,T.params.grabCursor&&T.setGrabCursor()},T.setGrabCursor=function(e){T.container[0].style.cursor="move",T.container[0].style.cursor=e?"-webkit-grabbing":"-webkit-grab",T.container[0].style.cursor=e?"-moz-grabbin":"-moz-grab",T.container[0].style.cursor=e?"grabbing":"grab"},T.unsetGrabCursor=function(){T.container[0].style.cursor=""},T.params.grabCursor&&T.setGrabCursor(),T.imagesToLoad=[],T.imagesLoaded=0,T.loadImage=function(e,a,t,s,i,r){function n(){r&&r()}var o;e.complete&&i?n():a?(o=new window.Image,o.onload=n,o.onerror=n,s&&(o.sizes=s),t&&(o.srcset=t),a&&(o.src=a)):n()},T.preloadImages=function(){function e(){void 0!==T&&null!==T&&T&&(void 0!==T.imagesLoaded&&T.imagesLoaded++,T.imagesLoaded===T.imagesToLoad.length&&(T.params.updateOnImagesReady&&T.update(),T.emit("onImagesReady",T)))}T.imagesToLoad=T.container.find("img");for(var a=0;a<T.imagesToLoad.length;a++)T.loadImage(T.imagesToLoad[a],T.imagesToLoad[a].currentSrc||T.imagesToLoad[a].getAttribute("src"),T.imagesToLoad[a].srcset||T.imagesToLoad[a].getAttribute("srcset"),T.imagesToLoad[a].sizes||T.imagesToLoad[a].getAttribute("sizes"),!0,e)},T.autoplayTimeoutId=void 0,T.autoplaying=!1,T.autoplayPaused=!1,T.startAutoplay=function(){return void 0===T.autoplayTimeoutId&&(!!T.params.autoplay&&(!T.autoplaying&&(T.autoplaying=!0,T.emit("onAutoplayStart",T),void n())))},T.stopAutoplay=function(e){T.autoplayTimeoutId&&(T.autoplayTimeoutId&&clearTimeout(T.autoplayTimeoutId),T.autoplaying=!1,T.autoplayTimeoutId=void 0,T.emit("onAutoplayStop",T))},T.pauseAutoplay=function(e){T.autoplayPaused||(T.autoplayTimeoutId&&clearTimeout(T.autoplayTimeoutId),T.autoplayPaused=!0,0===e?(T.autoplayPaused=!1,n()):T.wrapper.transitionEnd(function(){T&&(T.autoplayPaused=!1,T.autoplaying?n():T.stopAutoplay())}))},T.minTranslate=function(){return-T.snapGrid[0]},T.maxTranslate=function(){return-T.snapGrid[T.snapGrid.length-1]},T.updateAutoHeight=function(){var e,a=[],t=0;if("auto"!==T.params.slidesPerView&&T.params.slidesPerView>1)for(e=0;e<Math.ceil(T.params.slidesPerView);e++){var s=T.activeIndex+e;if(s>T.slides.length)break;a.push(T.slides.eq(s)[0])}else a.push(T.slides.eq(T.activeIndex)[0]);for(e=0;e<a.length;e++)if(void 0!==a[e]){var i=a[e].offsetHeight;t=i>t?i:t}t&&T.wrapper.css("height",t+"px")},T.updateContainerSize=function(){var e,a;e=void 0!==T.params.width?T.params.width:T.container[0].clientWidth,a=void 0!==T.params.height?T.params.height:T.container[0].clientHeight,0===e&&T.isHorizontal()||0===a&&!T.isHorizontal()||(e=e-parseInt(T.container.css("padding-left"),10)-parseInt(T.container.css("padding-right"),10),a=a-parseInt(T.container.css("padding-top"),10)-parseInt(T.container.css("padding-bottom"),10),T.width=e,T.height=a,T.size=T.isHorizontal()?T.width:T.height)},T.updateSlidesSize=function(){T.slides=T.wrapper.children("."+T.params.slideClass),T.snapGrid=[],T.slidesGrid=[],T.slidesSizesGrid=[];var e,a=T.params.spaceBetween,t=-T.params.slidesOffsetBefore,s=0,i=0;if(void 0!==T.size){"string"==typeof a&&a.indexOf("%")>=0&&(a=parseFloat(a.replace("%",""))/100*T.size),T.virtualSize=-a,T.rtl?T.slides.css({marginLeft:"",marginTop:""}):T.slides.css({marginRight:"",marginBottom:""});var n;T.params.slidesPerColumn>1&&(n=Math.floor(T.slides.length/T.params.slidesPerColumn)===T.slides.length/T.params.slidesPerColumn?T.slides.length:Math.ceil(T.slides.length/T.params.slidesPerColumn)*T.params.slidesPerColumn,"auto"!==T.params.slidesPerView&&"row"===T.params.slidesPerColumnFill&&(n=Math.max(n,T.params.slidesPerView*T.params.slidesPerColumn)));var o,l=T.params.slidesPerColumn,p=n/l,d=p-(T.params.slidesPerColumn*p-T.slides.length);for(e=0;e<T.slides.length;e++){o=0;var u=T.slides.eq(e);if(T.params.slidesPerColumn>1){var c,m,h;"column"===T.params.slidesPerColumnFill?(m=Math.floor(e/l),h=e-m*l,(m>d||m===d&&h===l-1)&&++h>=l&&(h=0,m++),c=m+h*n/l,u.css({"-webkit-box-ordinal-group":c,"-moz-box-ordinal-group":c,"-ms-flex-order":c,"-webkit-order":c,order:c})):(h=Math.floor(e/p),m=e-h*p),u.css("margin-"+(T.isHorizontal()?"top":"left"),0!==h&&T.params.spaceBetween&&T.params.spaceBetween+"px").attr("data-swiper-column",m).attr("data-swiper-row",h)}"none"!==u.css("display")&&("auto"===T.params.slidesPerView?(o=T.isHorizontal()?u.outerWidth(!0):u.outerHeight(!0),T.params.roundLengths&&(o=r(o))):(o=(T.size-(T.params.slidesPerView-1)*a)/T.params.slidesPerView,T.params.roundLengths&&(o=r(o)),T.isHorizontal()?T.slides[e].style.width=o+"px":T.slides[e].style.height=o+"px"),T.slides[e].swiperSlideSize=o,T.slidesSizesGrid.push(o),T.params.centeredSlides?(t=t+o/2+s/2+a,0===s&&0!==e&&(t=t-T.size/2-a),0===e&&(t=t-T.size/2-a),Math.abs(t)<.001&&(t=0),i%T.params.slidesPerGroup==0&&T.snapGrid.push(t),T.slidesGrid.push(t)):(i%T.params.slidesPerGroup==0&&T.snapGrid.push(t),T.slidesGrid.push(t),t=t+o+a),T.virtualSize+=o+a,s=o,i++)}T.virtualSize=Math.max(T.virtualSize,T.size)+T.params.slidesOffsetAfter;var g;if(T.rtl&&T.wrongRTL&&("slide"===T.params.effect||"coverflow"===T.params.effect)&&T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}),T.support.flexbox&&!T.params.setWrapperSize||(T.isHorizontal()?T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}):T.wrapper.css({height:T.virtualSize+T.params.spaceBetween+"px"})),T.params.slidesPerColumn>1&&(T.virtualSize=(o+T.params.spaceBetween)*n,T.virtualSize=Math.ceil(T.virtualSize/T.params.slidesPerColumn)-T.params.spaceBetween,T.isHorizontal()?T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}):T.wrapper.css({height:T.virtualSize+T.params.spaceBetween+"px"}),T.params.centeredSlides)){for(g=[],e=0;e<T.snapGrid.length;e++)T.snapGrid[e]<T.virtualSize+T.snapGrid[0]&&g.push(T.snapGrid[e]);T.snapGrid=g}if(!T.params.centeredSlides){for(g=[],e=0;e<T.snapGrid.length;e++)T.snapGrid[e]<=T.virtualSize-T.size&&g.push(T.snapGrid[e]);T.snapGrid=g,Math.floor(T.virtualSize-T.size)-Math.floor(T.snapGrid[T.snapGrid.length-1])>1&&T.snapGrid.push(T.virtualSize-T.size)}0===T.snapGrid.length&&(T.snapGrid=[0]),0!==T.params.spaceBetween&&(T.isHorizontal()?T.rtl?T.slides.css({marginLeft:a+"px"}):T.slides.css({marginRight:a+"px"}):T.slides.css({marginBottom:a+"px"})),T.params.watchSlidesProgress&&T.updateSlidesOffset()}},T.updateSlidesOffset=function(){for(var e=0;e<T.slides.length;e++)T.slides[e].swiperSlideOffset=T.isHorizontal()?T.slides[e].offsetLeft:T.slides[e].offsetTop},T.currentSlidesPerView=function(){var e,a,t=1;if(T.params.centeredSlides){var s,i=T.slides[T.activeIndex].swiperSlideSize;for(e=T.activeIndex+1;e<T.slides.length;e++)T.slides[e]&&!s&&(i+=T.slides[e].swiperSlideSize,t++,i>T.size&&(s=!0));for(a=T.activeIndex-1;a>=0;a--)T.slides[a]&&!s&&(i+=T.slides[a].swiperSlideSize,t++,i>T.size&&(s=!0))}else for(e=T.activeIndex+1;e<T.slides.length;e++)T.slidesGrid[e]-T.slidesGrid[T.activeIndex]<T.size&&t++;return t},T.updateSlidesProgress=function(e){if(void 0===e&&(e=T.translate||0),0!==T.slides.length){void 0===T.slides[0].swiperSlideOffset&&T.updateSlidesOffset();var a=-e;T.rtl&&(a=e),T.slides.removeClass(T.params.slideVisibleClass);for(var t=0;t<T.slides.length;t++){var s=T.slides[t],i=(a+(T.params.centeredSlides?T.minTranslate():0)-s.swiperSlideOffset)/(s.swiperSlideSize+T.params.spaceBetween);if(T.params.watchSlidesVisibility){var r=-(a-s.swiperSlideOffset),n=r+T.slidesSizesGrid[t];(r>=0&&r<T.size||n>0&&n<=T.size||r<=0&&n>=T.size)&&T.slides.eq(t).addClass(T.params.slideVisibleClass)}s.progress=T.rtl?-i:i}}},T.updateProgress=function(e){void 0===e&&(e=T.translate||0);var a=T.maxTranslate()-T.minTranslate(),t=T.isBeginning,s=T.isEnd;0===a?(T.progress=0,T.isBeginning=T.isEnd=!0):(T.progress=(e-T.minTranslate())/a,T.isBeginning=T.progress<=0,T.isEnd=T.progress>=1),T.isBeginning&&!t&&T.emit("onReachBeginning",T),T.isEnd&&!s&&T.emit("onReachEnd",T),T.params.watchSlidesProgress&&T.updateSlidesProgress(e),T.emit("onProgress",T,T.progress)},T.updateActiveIndex=function(){var e,a,t,s=T.rtl?T.translate:-T.translate;for(a=0;a<T.slidesGrid.length;a++)void 0!==T.slidesGrid[a+1]?s>=T.slidesGrid[a]&&s<T.slidesGrid[a+1]-(T.slidesGrid[a+1]-T.slidesGrid[a])/2?e=a:s>=T.slidesGrid[a]&&s<T.slidesGrid[a+1]&&(e=a+1):s>=T.slidesGrid[a]&&(e=a);T.params.normalizeSlideIndex&&(e<0||void 0===e)&&(e=0),t=Math.floor(e/T.params.slidesPerGroup),t>=T.snapGrid.length&&(t=T.snapGrid.length-1),e!==T.activeIndex&&(T.snapIndex=t,T.previousIndex=T.activeIndex,T.activeIndex=e,T.updateClasses(),T.updateRealIndex())},T.updateRealIndex=function(){T.realIndex=parseInt(T.slides.eq(T.activeIndex).attr("data-swiper-slide-index")||T.activeIndex,10)},T.updateClasses=function(){T.slides.removeClass(T.params.slideActiveClass+" "+T.params.slideNextClass+" "+T.params.slidePrevClass+" "+T.params.slideDuplicateActiveClass+" "+T.params.slideDuplicateNextClass+" "+T.params.slideDuplicatePrevClass);var a=T.slides.eq(T.activeIndex);a.addClass(T.params.slideActiveClass),i.loop&&(a.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+T.realIndex+'"]').addClass(T.params.slideDuplicateActiveClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+T.realIndex+'"]').addClass(T.params.slideDuplicateActiveClass));var t=a.next("."+T.params.slideClass).addClass(T.params.slideNextClass);T.params.loop&&0===t.length&&(t=T.slides.eq(0),t.addClass(T.params.slideNextClass));var s=a.prev("."+T.params.slideClass).addClass(T.params.slidePrevClass);if(T.params.loop&&0===s.length&&(s=T.slides.eq(-1),s.addClass(T.params.slidePrevClass)),i.loop&&(t.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+t.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicateNextClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+t.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicateNextClass),s.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+s.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicatePrevClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+s.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicatePrevClass)),T.paginationContainer&&T.paginationContainer.length>0){var r,n=T.params.loop?Math.ceil((T.slides.length-2*T.loopedSlides)/T.params.slidesPerGroup):T.snapGrid.length;if(T.params.loop?(r=Math.ceil((T.activeIndex-T.loopedSlides)/T.params.slidesPerGroup),r>T.slides.length-1-2*T.loopedSlides&&(r-=T.slides.length-2*T.loopedSlides),r>n-1&&(r-=n),r<0&&"bullets"!==T.params.paginationType&&(r=n+r)):r=void 0!==T.snapIndex?T.snapIndex:T.activeIndex||0,"bullets"===T.params.paginationType&&T.bullets&&T.bullets.length>0&&(T.bullets.removeClass(T.params.bulletActiveClass),T.paginationContainer.length>1?T.bullets.each(function(){e(this).index()===r&&e(this).addClass(T.params.bulletActiveClass)}):T.bullets.eq(r).addClass(T.params.bulletActiveClass)),"fraction"===T.params.paginationType&&(T.paginationContainer.find("."+T.params.paginationCurrentClass).text(r+1),T.paginationContainer.find("."+T.params.paginationTotalClass).text(n)),"progress"===T.params.paginationType){var o=(r+1)/n,l=o,p=1;T.isHorizontal()||(p=o,l=1),T.paginationContainer.find("."+T.params.paginationProgressbarClass).transform("translate3d(0,0,0) scaleX("+l+") scaleY("+p+")").transition(T.params.speed)}"custom"===T.params.paginationType&&T.params.paginationCustomRender&&(T.paginationContainer.html(T.params.paginationCustomRender(T,r+1,n)),T.emit("onPaginationRendered",T,T.paginationContainer[0]))}T.params.loop||(T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.isBeginning?(T.prevButton.addClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.disable(T.prevButton)):(T.prevButton.removeClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.enable(T.prevButton))),T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.isEnd?(T.nextButton.addClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.disable(T.nextButton)):(T.nextButton.removeClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.enable(T.nextButton))))},T.updatePagination=function(){if(T.params.pagination&&T.paginationContainer&&T.paginationContainer.length>0){var e="";if("bullets"===T.params.paginationType){for(var a=T.params.loop?Math.ceil((T.slides.length-2*T.loopedSlides)/T.params.slidesPerGroup):T.snapGrid.length,t=0;t<a;t++)e+=T.params.paginationBulletRender?T.params.paginationBulletRender(T,t,T.params.bulletClass):"<"+T.params.paginationElement+' class="'+T.params.bulletClass+'"></'+T.params.paginationElement+">";T.paginationContainer.html(e),T.bullets=T.paginationContainer.find("."+T.params.bulletClass),T.params.paginationClickable&&T.params.a11y&&T.a11y&&T.a11y.initPagination()}"fraction"===T.params.paginationType&&(e=T.params.paginationFractionRender?T.params.paginationFractionRender(T,T.params.paginationCurrentClass,T.params.paginationTotalClass):'<span class="'+T.params.paginationCurrentClass+'"></span> / <span class="'+T.params.paginationTotalClass+'"></span>',T.paginationContainer.html(e)),"progress"===T.params.paginationType&&(e=T.params.paginationProgressRender?T.params.paginationProgressRender(T,T.params.paginationProgressbarClass):'<span class="'+T.params.paginationProgressbarClass+'"></span>',T.paginationContainer.html(e)),"custom"!==T.params.paginationType&&T.emit("onPaginationRendered",T,T.paginationContainer[0])}},T.update=function(e){function a(){T.rtl,T.translate;t=Math.min(Math.max(T.translate,T.maxTranslate()),T.minTranslate()),T.setWrapperTranslate(t),T.updateActiveIndex(),T.updateClasses()}if(T){T.updateContainerSize(),T.updateSlidesSize(),T.updateProgress(),T.updatePagination(),T.updateClasses(),T.params.scrollbar&&T.scrollbar&&T.scrollbar.set();var t;if(e){T.controller&&T.controller.spline&&(T.controller.spline=void 0),T.params.freeMode?(a(),T.params.autoHeight&&T.updateAutoHeight()):(("auto"===T.params.slidesPerView||T.params.slidesPerView>1)&&T.isEnd&&!T.params.centeredSlides?T.slideTo(T.slides.length-1,0,!1,!0):T.slideTo(T.activeIndex,0,!1,!0))||a()}else T.params.autoHeight&&T.updateAutoHeight()}},T.onResize=function(e){T.params.onBeforeResize&&T.params.onBeforeResize(T),T.params.breakpoints&&T.setBreakpoint();var a=T.params.allowSwipeToPrev,t=T.params.allowSwipeToNext;T.params.allowSwipeToPrev=T.params.allowSwipeToNext=!0,T.updateContainerSize(),T.updateSlidesSize(),("auto"===T.params.slidesPerView||T.params.freeMode||e)&&T.updatePagination(),T.params.scrollbar&&T.scrollbar&&T.scrollbar.set(),T.controller&&T.controller.spline&&(T.controller.spline=void 0);var s=!1;if(T.params.freeMode){var i=Math.min(Math.max(T.translate,T.maxTranslate()),T.minTranslate());T.setWrapperTranslate(i),T.updateActiveIndex(),T.updateClasses(),T.params.autoHeight&&T.updateAutoHeight()}else T.updateClasses(),s=("auto"===T.params.slidesPerView||T.params.slidesPerView>1)&&T.isEnd&&!T.params.centeredSlides?T.slideTo(T.slides.length-1,0,!1,!0):T.slideTo(T.activeIndex,0,!1,!0);T.params.lazyLoading&&!s&&T.lazy&&T.lazy.load(),T.params.allowSwipeToPrev=a,T.params.allowSwipeToNext=t,T.params.onAfterResize&&T.params.onAfterResize(T)},T.touchEventsDesktop={start:"mousedown",move:"mousemove",end:"mouseup"},window.navigator.pointerEnabled?T.touchEventsDesktop={start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled&&(T.touchEventsDesktop={start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}),T.touchEvents={start:T.support.touch||!T.params.simulateTouch?"touchstart":T.touchEventsDesktop.start,move:T.support.touch||!T.params.simulateTouch?"touchmove":T.touchEventsDesktop.move,end:T.support.touch||!T.params.simulateTouch?"touchend":T.touchEventsDesktop.end},(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&("container"===T.params.touchEventsTarget?T.container:T.wrapper).addClass("swiper-wp8-"+T.params.direction),T.initEvents=function(e){var a=e?"off":"on",t=e?"removeEventListener":"addEventListener",s="container"===T.params.touchEventsTarget?T.container[0]:T.wrapper[0],r=T.support.touch?s:document,n=!!T.params.nested;if(T.browser.ie)s[t](T.touchEvents.start,T.onTouchStart,!1),r[t](T.touchEvents.move,T.onTouchMove,n),r[t](T.touchEvents.end,T.onTouchEnd,!1);else{if(T.support.touch){var o=!("touchstart"!==T.touchEvents.start||!T.support.passiveListener||!T.params.passiveListeners)&&{passive:!0,capture:!1};s[t](T.touchEvents.start,T.onTouchStart,o),s[t](T.touchEvents.move,T.onTouchMove,n),s[t](T.touchEvents.end,T.onTouchEnd,o)}(i.simulateTouch&&!T.device.ios&&!T.device.android||i.simulateTouch&&!T.support.touch&&T.device.ios)&&(s[t]("mousedown",T.onTouchStart,!1),document[t]("mousemove",T.onTouchMove,n),document[t]("mouseup",T.onTouchEnd,!1))}window[t]("resize",T.onResize),T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.nextButton[a]("click",T.onClickNext),T.params.a11y&&T.a11y&&T.nextButton[a]("keydown",T.a11y.onEnterKey)),T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.prevButton[a]("click",T.onClickPrev),T.params.a11y&&T.a11y&&T.prevButton[a]("keydown",T.a11y.onEnterKey)),T.params.pagination&&T.params.paginationClickable&&(T.paginationContainer[a]("click","."+T.params.bulletClass,T.onClickIndex),T.params.a11y&&T.a11y&&T.paginationContainer[a]("keydown","."+T.params.bulletClass,T.a11y.onEnterKey)),(T.params.preventClicks||T.params.preventClicksPropagation)&&s[t]("click",T.preventClicks,!0)},T.attachEvents=function(){T.initEvents()},T.detachEvents=function(){T.initEvents(!0)},T.allowClick=!0,T.preventClicks=function(e){T.allowClick||(T.params.preventClicks&&e.preventDefault(),T.params.preventClicksPropagation&&T.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))},T.onClickNext=function(e){e.preventDefault(),T.isEnd&&!T.params.loop||T.slideNext()},T.onClickPrev=function(e){e.preventDefault(),T.isBeginning&&!T.params.loop||T.slidePrev()},T.onClickIndex=function(a){a.preventDefault();var t=e(this).index()*T.params.slidesPerGroup;T.params.loop&&(t+=T.loopedSlides),T.slideTo(t)}, +T.updateClickedSlide=function(a){var t=o(a,"."+T.params.slideClass),s=!1;if(t)for(var i=0;i<T.slides.length;i++)T.slides[i]===t&&(s=!0);if(!t||!s)return T.clickedSlide=void 0,void(T.clickedIndex=void 0);if(T.clickedSlide=t,T.clickedIndex=e(t).index(),T.params.slideToClickedSlide&&void 0!==T.clickedIndex&&T.clickedIndex!==T.activeIndex){var r,n=T.clickedIndex,l="auto"===T.params.slidesPerView?T.currentSlidesPerView():T.params.slidesPerView;if(T.params.loop){if(T.animating)return;r=parseInt(e(T.clickedSlide).attr("data-swiper-slide-index"),10),T.params.centeredSlides?n<T.loopedSlides-l/2||n>T.slides.length-T.loopedSlides+l/2?(T.fixLoop(),n=T.wrapper.children("."+T.params.slideClass+'[data-swiper-slide-index="'+r+'"]:not(.'+T.params.slideDuplicateClass+")").eq(0).index(),setTimeout(function(){T.slideTo(n)},0)):T.slideTo(n):n>T.slides.length-l?(T.fixLoop(),n=T.wrapper.children("."+T.params.slideClass+'[data-swiper-slide-index="'+r+'"]:not(.'+T.params.slideDuplicateClass+")").eq(0).index(),setTimeout(function(){T.slideTo(n)},0)):T.slideTo(n)}else T.slideTo(n)}};var S,C,z,M,E,P,I,k,L,D,B="input, select, textarea, button, video",H=Date.now(),G=[];T.animating=!1,T.touches={startX:0,startY:0,currentX:0,currentY:0,diff:0};var X,A;T.onTouchStart=function(a){if(a.originalEvent&&(a=a.originalEvent),(X="touchstart"===a.type)||!("which"in a)||3!==a.which){if(T.params.noSwiping&&o(a,"."+T.params.noSwipingClass))return void(T.allowClick=!0);if(!T.params.swipeHandler||o(a,T.params.swipeHandler)){var t=T.touches.currentX="touchstart"===a.type?a.targetTouches[0].pageX:a.pageX,s=T.touches.currentY="touchstart"===a.type?a.targetTouches[0].pageY:a.pageY;if(!(T.device.ios&&T.params.iOSEdgeSwipeDetection&&t<=T.params.iOSEdgeSwipeThreshold)){if(S=!0,C=!1,z=!0,E=void 0,A=void 0,T.touches.startX=t,T.touches.startY=s,M=Date.now(),T.allowClick=!0,T.updateContainerSize(),T.swipeDirection=void 0,T.params.threshold>0&&(k=!1),"touchstart"!==a.type){var i=!0;e(a.target).is(B)&&(i=!1),document.activeElement&&e(document.activeElement).is(B)&&document.activeElement.blur(),i&&a.preventDefault()}T.emit("onTouchStart",T,a)}}}},T.onTouchMove=function(a){if(a.originalEvent&&(a=a.originalEvent),!X||"mousemove"!==a.type){if(a.preventedByNestedSwiper)return T.touches.startX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,void(T.touches.startY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY);if(T.params.onlyExternal)return T.allowClick=!1,void(S&&(T.touches.startX=T.touches.currentX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,T.touches.startY=T.touches.currentY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY,M=Date.now()));if(X&&T.params.touchReleaseOnEdges&&!T.params.loop)if(T.isHorizontal()){if(T.touches.currentX<T.touches.startX&&T.translate<=T.maxTranslate()||T.touches.currentX>T.touches.startX&&T.translate>=T.minTranslate())return}else if(T.touches.currentY<T.touches.startY&&T.translate<=T.maxTranslate()||T.touches.currentY>T.touches.startY&&T.translate>=T.minTranslate())return;if(X&&document.activeElement&&a.target===document.activeElement&&e(a.target).is(B))return C=!0,void(T.allowClick=!1);if(z&&T.emit("onTouchMove",T,a),!(a.targetTouches&&a.targetTouches.length>1)){if(T.touches.currentX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,T.touches.currentY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY,void 0===E){var t;T.isHorizontal()&&T.touches.currentY===T.touches.startY||!T.isHorizontal()&&T.touches.currentX===T.touches.startX?E=!1:(t=180*Math.atan2(Math.abs(T.touches.currentY-T.touches.startY),Math.abs(T.touches.currentX-T.touches.startX))/Math.PI,E=T.isHorizontal()?t>T.params.touchAngle:90-t>T.params.touchAngle)}if(E&&T.emit("onTouchMoveOpposite",T,a),void 0===A&&(T.touches.currentX===T.touches.startX&&T.touches.currentY===T.touches.startY||(A=!0)),S){if(E)return void(S=!1);if(A){T.allowClick=!1,T.emit("onSliderMove",T,a),a.preventDefault(),T.params.touchMoveStopPropagation&&!T.params.nested&&a.stopPropagation(),C||(i.loop&&T.fixLoop(),I=T.getWrapperTranslate(),T.setWrapperTransition(0),T.animating&&T.wrapper.trigger("webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd"),T.params.autoplay&&T.autoplaying&&(T.params.autoplayDisableOnInteraction?T.stopAutoplay():T.pauseAutoplay()),D=!1,!T.params.grabCursor||T.params.allowSwipeToNext!==!0&&T.params.allowSwipeToPrev!==!0||T.setGrabCursor(!0)),C=!0;var s=T.touches.diff=T.isHorizontal()?T.touches.currentX-T.touches.startX:T.touches.currentY-T.touches.startY;s*=T.params.touchRatio,T.rtl&&(s=-s),T.swipeDirection=s>0?"prev":"next",P=s+I;var r=!0;if(s>0&&P>T.minTranslate()?(r=!1,T.params.resistance&&(P=T.minTranslate()-1+Math.pow(-T.minTranslate()+I+s,T.params.resistanceRatio))):s<0&&P<T.maxTranslate()&&(r=!1,T.params.resistance&&(P=T.maxTranslate()+1-Math.pow(T.maxTranslate()-I-s,T.params.resistanceRatio))),r&&(a.preventedByNestedSwiper=!0),!T.params.allowSwipeToNext&&"next"===T.swipeDirection&&P<I&&(P=I),!T.params.allowSwipeToPrev&&"prev"===T.swipeDirection&&P>I&&(P=I),T.params.threshold>0){if(!(Math.abs(s)>T.params.threshold||k))return void(P=I);if(!k)return k=!0,T.touches.startX=T.touches.currentX,T.touches.startY=T.touches.currentY,P=I,void(T.touches.diff=T.isHorizontal()?T.touches.currentX-T.touches.startX:T.touches.currentY-T.touches.startY)}T.params.followFinger&&((T.params.freeMode||T.params.watchSlidesProgress)&&T.updateActiveIndex(),T.params.freeMode&&(0===G.length&&G.push({position:T.touches[T.isHorizontal()?"startX":"startY"],time:M}),G.push({position:T.touches[T.isHorizontal()?"currentX":"currentY"],time:(new window.Date).getTime()})),T.updateProgress(P),T.setWrapperTranslate(P))}}}}},T.onTouchEnd=function(a){if(a.originalEvent&&(a=a.originalEvent),z&&T.emit("onTouchEnd",T,a),z=!1,S){T.params.grabCursor&&C&&S&&(T.params.allowSwipeToNext===!0||T.params.allowSwipeToPrev===!0)&&T.setGrabCursor(!1);var t=Date.now(),s=t-M;if(T.allowClick&&(T.updateClickedSlide(a),T.emit("onTap",T,a),s<300&&t-H>300&&(L&&clearTimeout(L),L=setTimeout(function(){T&&(T.params.paginationHide&&T.paginationContainer.length>0&&!e(a.target).hasClass(T.params.bulletClass)&&T.paginationContainer.toggleClass(T.params.paginationHiddenClass),T.emit("onClick",T,a))},300)),s<300&&t-H<300&&(L&&clearTimeout(L),T.emit("onDoubleTap",T,a))),H=Date.now(),setTimeout(function(){T&&(T.allowClick=!0)},0),!S||!C||!T.swipeDirection||0===T.touches.diff||P===I)return void(S=C=!1);S=C=!1;var i;if(i=T.params.followFinger?T.rtl?T.translate:-T.translate:-P,T.params.freeMode){if(i<-T.minTranslate())return void T.slideTo(T.activeIndex);if(i>-T.maxTranslate())return void(T.slides.length<T.snapGrid.length?T.slideTo(T.snapGrid.length-1):T.slideTo(T.slides.length-1));if(T.params.freeModeMomentum){if(G.length>1){var r=G.pop(),n=G.pop(),o=r.position-n.position,l=r.time-n.time;T.velocity=o/l,T.velocity=T.velocity/2,Math.abs(T.velocity)<T.params.freeModeMinimumVelocity&&(T.velocity=0),(l>150||(new window.Date).getTime()-r.time>300)&&(T.velocity=0)}else T.velocity=0;T.velocity=T.velocity*T.params.freeModeMomentumVelocityRatio,G.length=0;var p=1e3*T.params.freeModeMomentumRatio,d=T.velocity*p,u=T.translate+d;T.rtl&&(u=-u);var c,m=!1,h=20*Math.abs(T.velocity)*T.params.freeModeMomentumBounceRatio;if(u<T.maxTranslate())T.params.freeModeMomentumBounce?(u+T.maxTranslate()<-h&&(u=T.maxTranslate()-h),c=T.maxTranslate(),m=!0,D=!0):u=T.maxTranslate();else if(u>T.minTranslate())T.params.freeModeMomentumBounce?(u-T.minTranslate()>h&&(u=T.minTranslate()+h),c=T.minTranslate(),m=!0,D=!0):u=T.minTranslate();else if(T.params.freeModeSticky){var g,f=0;for(f=0;f<T.snapGrid.length;f+=1)if(T.snapGrid[f]>-u){g=f;break}u=Math.abs(T.snapGrid[g]-u)<Math.abs(T.snapGrid[g-1]-u)||"next"===T.swipeDirection?T.snapGrid[g]:T.snapGrid[g-1],T.rtl||(u=-u)}if(0!==T.velocity)p=T.rtl?Math.abs((-u-T.translate)/T.velocity):Math.abs((u-T.translate)/T.velocity);else if(T.params.freeModeSticky)return void T.slideReset();T.params.freeModeMomentumBounce&&m?(T.updateProgress(c),T.setWrapperTransition(p),T.setWrapperTranslate(u),T.onTransitionStart(),T.animating=!0,T.wrapper.transitionEnd(function(){T&&D&&(T.emit("onMomentumBounce",T),T.setWrapperTransition(T.params.speed),T.setWrapperTranslate(c),T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd()}))})):T.velocity?(T.updateProgress(u),T.setWrapperTransition(p),T.setWrapperTranslate(u),T.onTransitionStart(),T.animating||(T.animating=!0,T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd()}))):T.updateProgress(u),T.updateActiveIndex()}return void((!T.params.freeModeMomentum||s>=T.params.longSwipesMs)&&(T.updateProgress(),T.updateActiveIndex()))}var v,w=0,y=T.slidesSizesGrid[0];for(v=0;v<T.slidesGrid.length;v+=T.params.slidesPerGroup)void 0!==T.slidesGrid[v+T.params.slidesPerGroup]?i>=T.slidesGrid[v]&&i<T.slidesGrid[v+T.params.slidesPerGroup]&&(w=v,y=T.slidesGrid[v+T.params.slidesPerGroup]-T.slidesGrid[v]):i>=T.slidesGrid[v]&&(w=v,y=T.slidesGrid[T.slidesGrid.length-1]-T.slidesGrid[T.slidesGrid.length-2]);var x=(i-T.slidesGrid[w])/y;if(s>T.params.longSwipesMs){if(!T.params.longSwipes)return void T.slideTo(T.activeIndex);"next"===T.swipeDirection&&(x>=T.params.longSwipesRatio?T.slideTo(w+T.params.slidesPerGroup):T.slideTo(w)),"prev"===T.swipeDirection&&(x>1-T.params.longSwipesRatio?T.slideTo(w+T.params.slidesPerGroup):T.slideTo(w))}else{if(!T.params.shortSwipes)return void T.slideTo(T.activeIndex);"next"===T.swipeDirection&&T.slideTo(w+T.params.slidesPerGroup),"prev"===T.swipeDirection&&T.slideTo(w)}}},T._slideTo=function(e,a){return T.slideTo(e,a,!0,!0)},T.slideTo=function(e,a,t,s){void 0===t&&(t=!0),void 0===e&&(e=0),e<0&&(e=0),T.snapIndex=Math.floor(e/T.params.slidesPerGroup),T.snapIndex>=T.snapGrid.length&&(T.snapIndex=T.snapGrid.length-1);var i=-T.snapGrid[T.snapIndex];if(T.params.autoplay&&T.autoplaying&&(s||!T.params.autoplayDisableOnInteraction?T.pauseAutoplay(a):T.stopAutoplay()),T.updateProgress(i),T.params.normalizeSlideIndex)for(var r=0;r<T.slidesGrid.length;r++)-Math.floor(100*i)>=Math.floor(100*T.slidesGrid[r])&&(e=r);return!(!T.params.allowSwipeToNext&&i<T.translate&&i<T.minTranslate())&&(!(!T.params.allowSwipeToPrev&&i>T.translate&&i>T.maxTranslate()&&(T.activeIndex||0)!==e)&&(void 0===a&&(a=T.params.speed),T.previousIndex=T.activeIndex||0,T.activeIndex=e,T.updateRealIndex(),T.rtl&&-i===T.translate||!T.rtl&&i===T.translate?(T.params.autoHeight&&T.updateAutoHeight(),T.updateClasses(),"slide"!==T.params.effect&&T.setWrapperTranslate(i),!1):(T.updateClasses(),T.onTransitionStart(t),0===a||T.browser.lteIE9?(T.setWrapperTranslate(i),T.setWrapperTransition(0),T.onTransitionEnd(t)):(T.setWrapperTranslate(i),T.setWrapperTransition(a),T.animating||(T.animating=!0,T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd(t)}))),!0)))},T.onTransitionStart=function(e){void 0===e&&(e=!0),T.params.autoHeight&&T.updateAutoHeight(),T.lazy&&T.lazy.onTransitionStart(),e&&(T.emit("onTransitionStart",T),T.activeIndex!==T.previousIndex&&(T.emit("onSlideChangeStart",T),T.activeIndex>T.previousIndex?T.emit("onSlideNextStart",T):T.emit("onSlidePrevStart",T)))},T.onTransitionEnd=function(e){T.animating=!1,T.setWrapperTransition(0),void 0===e&&(e=!0),T.lazy&&T.lazy.onTransitionEnd(),e&&(T.emit("onTransitionEnd",T),T.activeIndex!==T.previousIndex&&(T.emit("onSlideChangeEnd",T),T.activeIndex>T.previousIndex?T.emit("onSlideNextEnd",T):T.emit("onSlidePrevEnd",T))),T.params.history&&T.history&&T.history.setHistory(T.params.history,T.activeIndex),T.params.hashnav&&T.hashnav&&T.hashnav.setHash()},T.slideNext=function(e,a,t){if(T.params.loop){if(T.animating)return!1;T.fixLoop();T.container[0].clientLeft;return T.slideTo(T.activeIndex+T.params.slidesPerGroup,a,e,t)}return T.slideTo(T.activeIndex+T.params.slidesPerGroup,a,e,t)},T._slideNext=function(e){return T.slideNext(!0,e,!0)},T.slidePrev=function(e,a,t){if(T.params.loop){if(T.animating)return!1;T.fixLoop();T.container[0].clientLeft;return T.slideTo(T.activeIndex-1,a,e,t)}return T.slideTo(T.activeIndex-1,a,e,t)},T._slidePrev=function(e){return T.slidePrev(!0,e,!0)},T.slideReset=function(e,a,t){return T.slideTo(T.activeIndex,a,e)},T.disableTouchControl=function(){return T.params.onlyExternal=!0,!0},T.enableTouchControl=function(){return T.params.onlyExternal=!1,!0},T.setWrapperTransition=function(e,a){T.wrapper.transition(e),"slide"!==T.params.effect&&T.effects[T.params.effect]&&T.effects[T.params.effect].setTransition(e),T.params.parallax&&T.parallax&&T.parallax.setTransition(e),T.params.scrollbar&&T.scrollbar&&T.scrollbar.setTransition(e),T.params.control&&T.controller&&T.controller.setTransition(e,a),T.emit("onSetTransition",T,e)},T.setWrapperTranslate=function(e,a,t){var s=0,i=0;T.isHorizontal()?s=T.rtl?-e:e:i=e,T.params.roundLengths&&(s=r(s),i=r(i)),T.params.virtualTranslate||(T.support.transforms3d?T.wrapper.transform("translate3d("+s+"px, "+i+"px, 0px)"):T.wrapper.transform("translate("+s+"px, "+i+"px)")),T.translate=T.isHorizontal()?s:i;var n,o=T.maxTranslate()-T.minTranslate();n=0===o?0:(e-T.minTranslate())/o,n!==T.progress&&T.updateProgress(e),a&&T.updateActiveIndex(),"slide"!==T.params.effect&&T.effects[T.params.effect]&&T.effects[T.params.effect].setTranslate(T.translate),T.params.parallax&&T.parallax&&T.parallax.setTranslate(T.translate),T.params.scrollbar&&T.scrollbar&&T.scrollbar.setTranslate(T.translate),T.params.control&&T.controller&&T.controller.setTranslate(T.translate,t),T.emit("onSetTranslate",T,T.translate)},T.getTranslate=function(e,a){var t,s,i,r;return void 0===a&&(a="x"),T.params.virtualTranslate?T.rtl?-T.translate:T.translate:(i=window.getComputedStyle(e,null),window.WebKitCSSMatrix?(s=i.transform||i.webkitTransform,s.split(",").length>6&&(s=s.split(", ").map(function(e){return e.replace(",",".")}).join(", ")),r=new window.WebKitCSSMatrix("none"===s?"":s)):(r=i.MozTransform||i.OTransform||i.MsTransform||i.msTransform||i.transform||i.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),t=r.toString().split(",")),"x"===a&&(s=window.WebKitCSSMatrix?r.m41:16===t.length?parseFloat(t[12]):parseFloat(t[4])),"y"===a&&(s=window.WebKitCSSMatrix?r.m42:16===t.length?parseFloat(t[13]):parseFloat(t[5])),T.rtl&&s&&(s=-s),s||0)},T.getWrapperTranslate=function(e){return void 0===e&&(e=T.isHorizontal()?"x":"y"),T.getTranslate(T.wrapper[0],e)},T.observers=[],T.initObservers=function(){if(T.params.observeParents)for(var e=T.container.parents(),a=0;a<e.length;a++)l(e[a]);l(T.container[0],{childList:!1}),l(T.wrapper[0],{attributes:!1})},T.disconnectObservers=function(){for(var e=0;e<T.observers.length;e++)T.observers[e].disconnect();T.observers=[]},T.createLoop=function(){T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass).remove();var a=T.wrapper.children("."+T.params.slideClass);"auto"!==T.params.slidesPerView||T.params.loopedSlides||(T.params.loopedSlides=a.length),T.loopedSlides=parseInt(T.params.loopedSlides||T.params.slidesPerView,10),T.loopedSlides=T.loopedSlides+T.params.loopAdditionalSlides,T.loopedSlides>a.length&&(T.loopedSlides=a.length);var t,s=[],i=[];for(a.each(function(t,r){var n=e(this);t<T.loopedSlides&&i.push(r),t<a.length&&t>=a.length-T.loopedSlides&&s.push(r),n.attr("data-swiper-slide-index",t)}),t=0;t<i.length;t++)T.wrapper.append(e(i[t].cloneNode(!0)).addClass(T.params.slideDuplicateClass));for(t=s.length-1;t>=0;t--)T.wrapper.prepend(e(s[t].cloneNode(!0)).addClass(T.params.slideDuplicateClass))},T.destroyLoop=function(){T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass).remove(),T.slides.removeAttr("data-swiper-slide-index")},T.reLoop=function(e){var a=T.activeIndex-T.loopedSlides;T.destroyLoop(),T.createLoop(),T.updateSlidesSize(),e&&T.slideTo(a+T.loopedSlides,0,!1)},T.fixLoop=function(){var e;T.activeIndex<T.loopedSlides?(e=T.slides.length-3*T.loopedSlides+T.activeIndex,e+=T.loopedSlides,T.slideTo(e,0,!1,!0)):("auto"===T.params.slidesPerView&&T.activeIndex>=2*T.loopedSlides||T.activeIndex>T.slides.length-2*T.params.slidesPerView)&&(e=-T.slides.length+T.activeIndex+T.loopedSlides,e+=T.loopedSlides,T.slideTo(e,0,!1,!0))},T.appendSlide=function(e){if(T.params.loop&&T.destroyLoop(),"object"==typeof e&&e.length)for(var a=0;a<e.length;a++)e[a]&&T.wrapper.append(e[a]);else T.wrapper.append(e);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0)},T.prependSlide=function(e){T.params.loop&&T.destroyLoop();var a=T.activeIndex+1;if("object"==typeof e&&e.length){for(var t=0;t<e.length;t++)e[t]&&T.wrapper.prepend(e[t]);a=T.activeIndex+e.length}else T.wrapper.prepend(e);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0),T.slideTo(a,0,!1)},T.removeSlide=function(e){T.params.loop&&(T.destroyLoop(),T.slides=T.wrapper.children("."+T.params.slideClass));var a,t=T.activeIndex;if("object"==typeof e&&e.length){for(var s=0;s<e.length;s++)a=e[s],T.slides[a]&&T.slides.eq(a).remove(),a<t&&t--;t=Math.max(t,0)}else a=e,T.slides[a]&&T.slides.eq(a).remove(),a<t&&t--,t=Math.max(t,0);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0),T.params.loop?T.slideTo(t+T.loopedSlides,0,!1):T.slideTo(t,0,!1)},T.removeAllSlides=function(){for(var e=[],a=0;a<T.slides.length;a++)e.push(a);T.removeSlide(e)},T.effects={fade:{setTranslate:function(){for(var e=0;e<T.slides.length;e++){var a=T.slides.eq(e),t=a[0].swiperSlideOffset,s=-t;T.params.virtualTranslate||(s-=T.translate);var i=0;T.isHorizontal()||(i=s,s=0);var r=T.params.fade.crossFade?Math.max(1-Math.abs(a[0].progress),0):1+Math.min(Math.max(a[0].progress,-1),0);a.css({opacity:r}).transform("translate3d("+s+"px, "+i+"px, 0px)")}},setTransition:function(e){if(T.slides.transition(e),T.params.virtualTranslate&&0!==e){var a=!1;T.slides.transitionEnd(function(){if(!a&&T){a=!0,T.animating=!1;for(var e=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],t=0;t<e.length;t++)T.wrapper.trigger(e[t])}})}}},flip:{setTranslate:function(){for(var a=0;a<T.slides.length;a++){var t=T.slides.eq(a),s=t[0].progress;T.params.flip.limitRotation&&(s=Math.max(Math.min(t[0].progress,1),-1));var i=t[0].swiperSlideOffset,r=-180*s,n=r,o=0,l=-i,p=0;if(T.isHorizontal()?T.rtl&&(n=-n):(p=l,l=0,o=-n,n=0),t[0].style.zIndex=-Math.abs(Math.round(s))+T.slides.length,T.params.flip.slideShadows){var d=T.isHorizontal()?t.find(".swiper-slide-shadow-left"):t.find(".swiper-slide-shadow-top"),u=T.isHorizontal()?t.find(".swiper-slide-shadow-right"):t.find(".swiper-slide-shadow-bottom");0===d.length&&(d=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),t.append(d)),0===u.length&&(u=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),t.append(u)),d.length&&(d[0].style.opacity=Math.max(-s,0)),u.length&&(u[0].style.opacity=Math.max(s,0))}t.transform("translate3d("+l+"px, "+p+"px, 0px) rotateX("+o+"deg) rotateY("+n+"deg)")}},setTransition:function(a){if(T.slides.transition(a).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(a),T.params.virtualTranslate&&0!==a){var t=!1;T.slides.eq(T.activeIndex).transitionEnd(function(){if(!t&&T&&e(this).hasClass(T.params.slideActiveClass)){t=!0,T.animating=!1;for(var a=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],s=0;s<a.length;s++)T.wrapper.trigger(a[s])}})}}},cube:{setTranslate:function(){var a,t=0;T.params.cube.shadow&&(T.isHorizontal()?(a=T.wrapper.find(".swiper-cube-shadow"),0===a.length&&(a=e('<div class="swiper-cube-shadow"></div>'),T.wrapper.append(a)),a.css({height:T.width+"px"})):(a=T.container.find(".swiper-cube-shadow"),0===a.length&&(a=e('<div class="swiper-cube-shadow"></div>'),T.container.append(a))));for(var s=0;s<T.slides.length;s++){var i=T.slides.eq(s),r=90*s,n=Math.floor(r/360);T.rtl&&(r=-r,n=Math.floor(-r/360));var o=Math.max(Math.min(i[0].progress,1),-1),l=0,p=0,d=0;s%4==0?(l=4*-n*T.size,d=0):(s-1)%4==0?(l=0,d=4*-n*T.size):(s-2)%4==0?(l=T.size+4*n*T.size,d=T.size):(s-3)%4==0&&(l=-T.size,d=3*T.size+4*T.size*n),T.rtl&&(l=-l),T.isHorizontal()||(p=l,l=0);var u="rotateX("+(T.isHorizontal()?0:-r)+"deg) rotateY("+(T.isHorizontal()?r:0)+"deg) translate3d("+l+"px, "+p+"px, "+d+"px)";if(o<=1&&o>-1&&(t=90*s+90*o,T.rtl&&(t=90*-s-90*o)),i.transform(u),T.params.cube.slideShadows){var c=T.isHorizontal()?i.find(".swiper-slide-shadow-left"):i.find(".swiper-slide-shadow-top"),m=T.isHorizontal()?i.find(".swiper-slide-shadow-right"):i.find(".swiper-slide-shadow-bottom");0===c.length&&(c=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),i.append(c)),0===m.length&&(m=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),i.append(m)),c.length&&(c[0].style.opacity=Math.max(-o,0)),m.length&&(m[0].style.opacity=Math.max(o,0))}}if(T.wrapper.css({"-webkit-transform-origin":"50% 50% -"+T.size/2+"px","-moz-transform-origin":"50% 50% -"+T.size/2+"px","-ms-transform-origin":"50% 50% -"+T.size/2+"px","transform-origin":"50% 50% -"+T.size/2+"px"}),T.params.cube.shadow)if(T.isHorizontal())a.transform("translate3d(0px, "+(T.width/2+T.params.cube.shadowOffset)+"px, "+-T.width/2+"px) rotateX(90deg) rotateZ(0deg) scale("+T.params.cube.shadowScale+")");else{var h=Math.abs(t)-90*Math.floor(Math.abs(t)/90),g=1.5-(Math.sin(2*h*Math.PI/360)/2+Math.cos(2*h*Math.PI/360)/2),f=T.params.cube.shadowScale,v=T.params.cube.shadowScale/g,w=T.params.cube.shadowOffset;a.transform("scale3d("+f+", 1, "+v+") translate3d(0px, "+(T.height/2+w)+"px, "+-T.height/2/v+"px) rotateX(-90deg)")}var y=T.isSafari||T.isUiWebView?-T.size/2:0;T.wrapper.transform("translate3d(0px,0,"+y+"px) rotateX("+(T.isHorizontal()?0:t)+"deg) rotateY("+(T.isHorizontal()?-t:0)+"deg)")},setTransition:function(e){T.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),T.params.cube.shadow&&!T.isHorizontal()&&T.container.find(".swiper-cube-shadow").transition(e)}},coverflow:{setTranslate:function(){for(var a=T.translate,t=T.isHorizontal()?-a+T.width/2:-a+T.height/2,s=T.isHorizontal()?T.params.coverflow.rotate:-T.params.coverflow.rotate,i=T.params.coverflow.depth,r=0,n=T.slides.length;r<n;r++){var o=T.slides.eq(r),l=T.slidesSizesGrid[r],p=o[0].swiperSlideOffset,d=(t-p-l/2)/l*T.params.coverflow.modifier,u=T.isHorizontal()?s*d:0,c=T.isHorizontal()?0:s*d,m=-i*Math.abs(d),h=T.isHorizontal()?0:T.params.coverflow.stretch*d,g=T.isHorizontal()?T.params.coverflow.stretch*d:0;Math.abs(g)<.001&&(g=0),Math.abs(h)<.001&&(h=0),Math.abs(m)<.001&&(m=0),Math.abs(u)<.001&&(u=0),Math.abs(c)<.001&&(c=0);var f="translate3d("+g+"px,"+h+"px,"+m+"px) rotateX("+c+"deg) rotateY("+u+"deg)";if(o.transform(f),o[0].style.zIndex=1-Math.abs(Math.round(d)),T.params.coverflow.slideShadows){var v=T.isHorizontal()?o.find(".swiper-slide-shadow-left"):o.find(".swiper-slide-shadow-top"),w=T.isHorizontal()?o.find(".swiper-slide-shadow-right"):o.find(".swiper-slide-shadow-bottom");0===v.length&&(v=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),o.append(v)),0===w.length&&(w=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),o.append(w)),v.length&&(v[0].style.opacity=d>0?d:0),w.length&&(w[0].style.opacity=-d>0?-d:0)}}if(T.browser.ie){T.wrapper[0].style.perspectiveOrigin=t+"px 50%"}},setTransition:function(e){T.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}}},T.lazy={initialImageLoaded:!1,loadImageInSlide:function(a,t){if(void 0!==a&&(void 0===t&&(t=!0),0!==T.slides.length)){var s=T.slides.eq(a),i=s.find("."+T.params.lazyLoadingClass+":not(."+T.params.lazyStatusLoadedClass+"):not(."+T.params.lazyStatusLoadingClass+")");!s.hasClass(T.params.lazyLoadingClass)||s.hasClass(T.params.lazyStatusLoadedClass)||s.hasClass(T.params.lazyStatusLoadingClass)||(i=i.add(s[0])),0!==i.length&&i.each(function(){var a=e(this);a.addClass(T.params.lazyStatusLoadingClass);var i=a.attr("data-background"),r=a.attr("data-src"),n=a.attr("data-srcset"),o=a.attr("data-sizes");T.loadImage(a[0],r||i,n,o,!1,function(){if(void 0!==T&&null!==T&&T){if(i?(a.css("background-image",'url("'+i+'")'),a.removeAttr("data-background")):(n&&(a.attr("srcset",n),a.removeAttr("data-srcset")),o&&(a.attr("sizes",o),a.removeAttr("data-sizes")),r&&(a.attr("src",r),a.removeAttr("data-src"))),a.addClass(T.params.lazyStatusLoadedClass).removeClass(T.params.lazyStatusLoadingClass),s.find("."+T.params.lazyPreloaderClass+", ."+T.params.preloaderClass).remove(),T.params.loop&&t){var e=s.attr("data-swiper-slide-index");if(s.hasClass(T.params.slideDuplicateClass)){var l=T.wrapper.children('[data-swiper-slide-index="'+e+'"]:not(.'+T.params.slideDuplicateClass+")");T.lazy.loadImageInSlide(l.index(),!1)}else{var p=T.wrapper.children("."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+e+'"]');T.lazy.loadImageInSlide(p.index(),!1)}}T.emit("onLazyImageReady",T,s[0],a[0])}}),T.emit("onLazyImageLoad",T,s[0],a[0])})}},load:function(){var a,t=T.params.slidesPerView;if("auto"===t&&(t=0),T.lazy.initialImageLoaded||(T.lazy.initialImageLoaded=!0),T.params.watchSlidesVisibility)T.wrapper.children("."+T.params.slideVisibleClass).each(function(){T.lazy.loadImageInSlide(e(this).index())});else if(t>1)for(a=T.activeIndex;a<T.activeIndex+t;a++)T.slides[a]&&T.lazy.loadImageInSlide(a);else T.lazy.loadImageInSlide(T.activeIndex);if(T.params.lazyLoadingInPrevNext)if(t>1||T.params.lazyLoadingInPrevNextAmount&&T.params.lazyLoadingInPrevNextAmount>1){var s=T.params.lazyLoadingInPrevNextAmount,i=t,r=Math.min(T.activeIndex+i+Math.max(s,i),T.slides.length),n=Math.max(T.activeIndex-Math.max(i,s),0);for(a=T.activeIndex+t;a<r;a++)T.slides[a]&&T.lazy.loadImageInSlide(a);for(a=n;a<T.activeIndex;a++)T.slides[a]&&T.lazy.loadImageInSlide(a)}else{var o=T.wrapper.children("."+T.params.slideNextClass);o.length>0&&T.lazy.loadImageInSlide(o.index());var l=T.wrapper.children("."+T.params.slidePrevClass);l.length>0&&T.lazy.loadImageInSlide(l.index())}},onTransitionStart:function(){T.params.lazyLoading&&(T.params.lazyLoadingOnTransitionStart||!T.params.lazyLoadingOnTransitionStart&&!T.lazy.initialImageLoaded)&&T.lazy.load()},onTransitionEnd:function(){T.params.lazyLoading&&!T.params.lazyLoadingOnTransitionStart&&T.lazy.load()}},T.scrollbar={isTouched:!1,setDragPosition:function(e){var a=T.scrollbar,t=T.isHorizontal()?"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].pageX:e.pageX||e.clientX:"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].pageY:e.pageY||e.clientY,s=t-a.track.offset()[T.isHorizontal()?"left":"top"]-a.dragSize/2,i=-T.minTranslate()*a.moveDivider,r=-T.maxTranslate()*a.moveDivider;s<i?s=i:s>r&&(s=r),s=-s/a.moveDivider,T.updateProgress(s),T.setWrapperTranslate(s,!0)},dragStart:function(e){var a=T.scrollbar;a.isTouched=!0,e.preventDefault(),e.stopPropagation(),a.setDragPosition(e),clearTimeout(a.dragTimeout),a.track.transition(0),T.params.scrollbarHide&&a.track.css("opacity",1),T.wrapper.transition(100),a.drag.transition(100),T.emit("onScrollbarDragStart",T)},dragMove:function(e){var a=T.scrollbar;a.isTouched&&(e.preventDefault?e.preventDefault():e.returnValue=!1,a.setDragPosition(e),T.wrapper.transition(0),a.track.transition(0),a.drag.transition(0),T.emit("onScrollbarDragMove",T))},dragEnd:function(e){var a=T.scrollbar;a.isTouched&&(a.isTouched=!1,T.params.scrollbarHide&&(clearTimeout(a.dragTimeout),a.dragTimeout=setTimeout(function(){a.track.css("opacity",0),a.track.transition(400)},1e3)),T.emit("onScrollbarDragEnd",T),T.params.scrollbarSnapOnRelease&&T.slideReset())},draggableEvents:function(){return T.params.simulateTouch!==!1||T.support.touch?T.touchEvents:T.touchEventsDesktop}(),enableDraggable:function(){var a=T.scrollbar,t=T.support.touch?a.track:document;e(a.track).on(a.draggableEvents.start,a.dragStart),e(t).on(a.draggableEvents.move,a.dragMove),e(t).on(a.draggableEvents.end,a.dragEnd)},disableDraggable:function(){var a=T.scrollbar,t=T.support.touch?a.track:document;e(a.track).off(a.draggableEvents.start,a.dragStart),e(t).off(a.draggableEvents.move,a.dragMove),e(t).off(a.draggableEvents.end,a.dragEnd)},set:function(){if(T.params.scrollbar){var a=T.scrollbar;a.track=e(T.params.scrollbar),T.params.uniqueNavElements&&"string"==typeof T.params.scrollbar&&a.track.length>1&&1===T.container.find(T.params.scrollbar).length&&(a.track=T.container.find(T.params.scrollbar)),a.drag=a.track.find(".swiper-scrollbar-drag"),0===a.drag.length&&(a.drag=e('<div class="swiper-scrollbar-drag"></div>'),a.track.append(a.drag)),a.drag[0].style.width="",a.drag[0].style.height="",a.trackSize=T.isHorizontal()?a.track[0].offsetWidth:a.track[0].offsetHeight,a.divider=T.size/T.virtualSize,a.moveDivider=a.divider*(a.trackSize/T.size),a.dragSize=a.trackSize*a.divider,T.isHorizontal()?a.drag[0].style.width=a.dragSize+"px":a.drag[0].style.height=a.dragSize+"px",a.divider>=1?a.track[0].style.display="none":a.track[0].style.display="",T.params.scrollbarHide&&(a.track[0].style.opacity=0)}},setTranslate:function(){if(T.params.scrollbar){var e,a=T.scrollbar,t=(T.translate,a.dragSize);e=(a.trackSize-a.dragSize)*T.progress,T.rtl&&T.isHorizontal()?(e=-e,e>0?(t=a.dragSize-e,e=0):-e+a.dragSize>a.trackSize&&(t=a.trackSize+e)):e<0?(t=a.dragSize+e,e=0):e+a.dragSize>a.trackSize&&(t=a.trackSize-e),T.isHorizontal()?(T.support.transforms3d?a.drag.transform("translate3d("+e+"px, 0, 0)"):a.drag.transform("translateX("+e+"px)"),a.drag[0].style.width=t+"px"):(T.support.transforms3d?a.drag.transform("translate3d(0px, "+e+"px, 0)"):a.drag.transform("translateY("+e+"px)"),a.drag[0].style.height=t+"px"),T.params.scrollbarHide&&(clearTimeout(a.timeout),a.track[0].style.opacity=1,a.timeout=setTimeout(function(){a.track[0].style.opacity=0,a.track.transition(400)},1e3))}},setTransition:function(e){T.params.scrollbar&&T.scrollbar.drag.transition(e)}},T.controller={LinearSpline:function(e,a){var t=function(){var e,a,t;return function(s,i){for(a=-1,e=s.length;e-a>1;)s[t=e+a>>1]<=i?a=t:e=t;return e}}();this.x=e,this.y=a,this.lastIndex=e.length-1;var s,i;this.x.length;this.interpolate=function(e){return e?(i=t(this.x,e),s=i-1,(e-this.x[s])*(this.y[i]-this.y[s])/(this.x[i]-this.x[s])+this.y[s]):0}},getInterpolateFunction:function(e){T.controller.spline||(T.controller.spline=T.params.loop?new T.controller.LinearSpline(T.slidesGrid,e.slidesGrid):new T.controller.LinearSpline(T.snapGrid,e.snapGrid))},setTranslate:function(e,t){function s(a){e=a.rtl&&"horizontal"===a.params.direction?-T.translate:T.translate,"slide"===T.params.controlBy&&(T.controller.getInterpolateFunction(a),r=-T.controller.spline.interpolate(-e)),r&&"container"!==T.params.controlBy||(i=(a.maxTranslate()-a.minTranslate())/(T.maxTranslate()-T.minTranslate()),r=(e-T.minTranslate())*i+a.minTranslate()),T.params.controlInverse&&(r=a.maxTranslate()-r),a.updateProgress(r),a.setWrapperTranslate(r,!1,T),a.updateActiveIndex()}var i,r,n=T.params.control;if(Array.isArray(n))for(var o=0;o<n.length;o++)n[o]!==t&&n[o]instanceof a&&s(n[o]);else n instanceof a&&t!==n&&s(n)},setTransition:function(e,t){function s(a){a.setWrapperTransition(e,T),0!==e&&(a.onTransitionStart(),a.wrapper.transitionEnd(function(){r&&(a.params.loop&&"slide"===T.params.controlBy&&a.fixLoop(),a.onTransitionEnd())}))}var i,r=T.params.control;if(Array.isArray(r))for(i=0;i<r.length;i++)r[i]!==t&&r[i]instanceof a&&s(r[i]);else r instanceof a&&t!==r&&s(r)}},T.hashnav={onHashCange:function(e,a){var t=document.location.hash.replace("#","");t!==T.slides.eq(T.activeIndex).attr("data-hash")&&T.slideTo(T.wrapper.children("."+T.params.slideClass+'[data-hash="'+t+'"]').index())},attachEvents:function(a){var t=a?"off":"on";e(window)[t]("hashchange",T.hashnav.onHashCange)},setHash:function(){ +if(T.hashnav.initialized&&T.params.hashnav)if(T.params.replaceState&&window.history&&window.history.replaceState)window.history.replaceState(null,null,"#"+T.slides.eq(T.activeIndex).attr("data-hash")||"");else{var e=T.slides.eq(T.activeIndex),a=e.attr("data-hash")||e.attr("data-history");document.location.hash=a||""}},init:function(){if(T.params.hashnav&&!T.params.history){T.hashnav.initialized=!0;var e=document.location.hash.replace("#","");if(e)for(var a=0,t=T.slides.length;a<t;a++){var s=T.slides.eq(a),i=s.attr("data-hash")||s.attr("data-history");if(i===e&&!s.hasClass(T.params.slideDuplicateClass)){var r=s.index();T.slideTo(r,0,T.params.runCallbacksOnInit,!0)}}T.params.hashnavWatchState&&T.hashnav.attachEvents()}},destroy:function(){T.params.hashnavWatchState&&T.hashnav.attachEvents(!0)}},T.history={init:function(){if(T.params.history){if(!window.history||!window.history.pushState)return T.params.history=!1,void(T.params.hashnav=!0);T.history.initialized=!0,this.paths=this.getPathValues(),(this.paths.key||this.paths.value)&&(this.scrollToSlide(0,this.paths.value,T.params.runCallbacksOnInit),T.params.replaceState||window.addEventListener("popstate",this.setHistoryPopState))}},setHistoryPopState:function(){T.history.paths=T.history.getPathValues(),T.history.scrollToSlide(T.params.speed,T.history.paths.value,!1)},getPathValues:function(){var e=window.location.pathname.slice(1).split("/"),a=e.length;return{key:e[a-2],value:e[a-1]}},setHistory:function(e,a){if(T.history.initialized&&T.params.history){var t=T.slides.eq(a),s=this.slugify(t.attr("data-history"));window.location.pathname.includes(e)||(s=e+"/"+s),T.params.replaceState?window.history.replaceState(null,null,s):window.history.pushState(null,null,s)}},slugify:function(e){return e.toString().toLowerCase().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\-\-+/g,"-").replace(/^-+/,"").replace(/-+$/,"")},scrollToSlide:function(e,a,t){if(a)for(var s=0,i=T.slides.length;s<i;s++){var r=T.slides.eq(s),n=this.slugify(r.attr("data-history"));if(n===a&&!r.hasClass(T.params.slideDuplicateClass)){var o=r.index();T.slideTo(o,e,t)}}else T.slideTo(0,e,t)}},T.disableKeyboardControl=function(){T.params.keyboardControl=!1,e(document).off("keydown",p)},T.enableKeyboardControl=function(){T.params.keyboardControl=!0,e(document).on("keydown",p)},T.mousewheel={event:!1,lastScrollTime:(new window.Date).getTime()},T.params.mousewheelControl&&(T.mousewheel.event=navigator.userAgent.indexOf("firefox")>-1?"DOMMouseScroll":function(){var e="onwheel"in document;if(!e){var a=document.createElement("div");a.setAttribute("onwheel","return;"),e="function"==typeof a.onwheel}return!e&&document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0&&(e=document.implementation.hasFeature("Events.wheel","3.0")),e}()?"wheel":"mousewheel"),T.disableMousewheelControl=function(){if(!T.mousewheel.event)return!1;var a=T.container;return"container"!==T.params.mousewheelEventsTarged&&(a=e(T.params.mousewheelEventsTarged)),a.off(T.mousewheel.event,u),T.params.mousewheelControl=!1,!0},T.enableMousewheelControl=function(){if(!T.mousewheel.event)return!1;var a=T.container;return"container"!==T.params.mousewheelEventsTarged&&(a=e(T.params.mousewheelEventsTarged)),a.on(T.mousewheel.event,u),T.params.mousewheelControl=!0,!0},T.parallax={setTranslate:function(){T.container.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){c(this,T.progress)}),T.slides.each(function(){var a=e(this);a.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){c(this,Math.min(Math.max(a[0].progress,-1),1))})})},setTransition:function(a){void 0===a&&(a=T.params.speed),T.container.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var t=e(this),s=parseInt(t.attr("data-swiper-parallax-duration"),10)||a;0===a&&(s=0),t.transition(s)})}},T.zoom={scale:1,currentScale:1,isScaling:!1,gesture:{slide:void 0,slideWidth:void 0,slideHeight:void 0,image:void 0,imageWrap:void 0,zoomMax:T.params.zoomMax},image:{isTouched:void 0,isMoved:void 0,currentX:void 0,currentY:void 0,minX:void 0,minY:void 0,maxX:void 0,maxY:void 0,width:void 0,height:void 0,startX:void 0,startY:void 0,touchesStart:{},touchesCurrent:{}},velocity:{x:void 0,y:void 0,prevPositionX:void 0,prevPositionY:void 0,prevTime:void 0},getDistanceBetweenTouches:function(e){if(e.targetTouches.length<2)return 1;var a=e.targetTouches[0].pageX,t=e.targetTouches[0].pageY,s=e.targetTouches[1].pageX,i=e.targetTouches[1].pageY;return Math.sqrt(Math.pow(s-a,2)+Math.pow(i-t,2))},onGestureStart:function(a){var t=T.zoom;if(!T.support.gestures){if("touchstart"!==a.type||"touchstart"===a.type&&a.targetTouches.length<2)return;t.gesture.scaleStart=t.getDistanceBetweenTouches(a)}if(!(t.gesture.slide&&t.gesture.slide.length||(t.gesture.slide=e(this),0===t.gesture.slide.length&&(t.gesture.slide=T.slides.eq(T.activeIndex)),t.gesture.image=t.gesture.slide.find("img, svg, canvas"),t.gesture.imageWrap=t.gesture.image.parent("."+T.params.zoomContainerClass),t.gesture.zoomMax=t.gesture.imageWrap.attr("data-swiper-zoom")||T.params.zoomMax,0!==t.gesture.imageWrap.length)))return void(t.gesture.image=void 0);t.gesture.image.transition(0),t.isScaling=!0},onGestureChange:function(e){var a=T.zoom;if(!T.support.gestures){if("touchmove"!==e.type||"touchmove"===e.type&&e.targetTouches.length<2)return;a.gesture.scaleMove=a.getDistanceBetweenTouches(e)}a.gesture.image&&0!==a.gesture.image.length&&(T.support.gestures?a.scale=e.scale*a.currentScale:a.scale=a.gesture.scaleMove/a.gesture.scaleStart*a.currentScale,a.scale>a.gesture.zoomMax&&(a.scale=a.gesture.zoomMax-1+Math.pow(a.scale-a.gesture.zoomMax+1,.5)),a.scale<T.params.zoomMin&&(a.scale=T.params.zoomMin+1-Math.pow(T.params.zoomMin-a.scale+1,.5)),a.gesture.image.transform("translate3d(0,0,0) scale("+a.scale+")"))},onGestureEnd:function(e){var a=T.zoom;!T.support.gestures&&("touchend"!==e.type||"touchend"===e.type&&e.changedTouches.length<2)||a.gesture.image&&0!==a.gesture.image.length&&(a.scale=Math.max(Math.min(a.scale,a.gesture.zoomMax),T.params.zoomMin),a.gesture.image.transition(T.params.speed).transform("translate3d(0,0,0) scale("+a.scale+")"),a.currentScale=a.scale,a.isScaling=!1,1===a.scale&&(a.gesture.slide=void 0))},onTouchStart:function(e,a){var t=e.zoom;t.gesture.image&&0!==t.gesture.image.length&&(t.image.isTouched||("android"===e.device.os&&a.preventDefault(),t.image.isTouched=!0,t.image.touchesStart.x="touchstart"===a.type?a.targetTouches[0].pageX:a.pageX,t.image.touchesStart.y="touchstart"===a.type?a.targetTouches[0].pageY:a.pageY))},onTouchMove:function(e){var a=T.zoom;if(a.gesture.image&&0!==a.gesture.image.length&&(T.allowClick=!1,a.image.isTouched&&a.gesture.slide)){a.image.isMoved||(a.image.width=a.gesture.image[0].offsetWidth,a.image.height=a.gesture.image[0].offsetHeight,a.image.startX=T.getTranslate(a.gesture.imageWrap[0],"x")||0,a.image.startY=T.getTranslate(a.gesture.imageWrap[0],"y")||0,a.gesture.slideWidth=a.gesture.slide[0].offsetWidth,a.gesture.slideHeight=a.gesture.slide[0].offsetHeight,a.gesture.imageWrap.transition(0),T.rtl&&(a.image.startX=-a.image.startX),T.rtl&&(a.image.startY=-a.image.startY));var t=a.image.width*a.scale,s=a.image.height*a.scale;if(!(t<a.gesture.slideWidth&&s<a.gesture.slideHeight)){if(a.image.minX=Math.min(a.gesture.slideWidth/2-t/2,0),a.image.maxX=-a.image.minX,a.image.minY=Math.min(a.gesture.slideHeight/2-s/2,0),a.image.maxY=-a.image.minY,a.image.touchesCurrent.x="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,a.image.touchesCurrent.y="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,!a.image.isMoved&&!a.isScaling){if(T.isHorizontal()&&Math.floor(a.image.minX)===Math.floor(a.image.startX)&&a.image.touchesCurrent.x<a.image.touchesStart.x||Math.floor(a.image.maxX)===Math.floor(a.image.startX)&&a.image.touchesCurrent.x>a.image.touchesStart.x)return void(a.image.isTouched=!1);if(!T.isHorizontal()&&Math.floor(a.image.minY)===Math.floor(a.image.startY)&&a.image.touchesCurrent.y<a.image.touchesStart.y||Math.floor(a.image.maxY)===Math.floor(a.image.startY)&&a.image.touchesCurrent.y>a.image.touchesStart.y)return void(a.image.isTouched=!1)}e.preventDefault(),e.stopPropagation(),a.image.isMoved=!0,a.image.currentX=a.image.touchesCurrent.x-a.image.touchesStart.x+a.image.startX,a.image.currentY=a.image.touchesCurrent.y-a.image.touchesStart.y+a.image.startY,a.image.currentX<a.image.minX&&(a.image.currentX=a.image.minX+1-Math.pow(a.image.minX-a.image.currentX+1,.8)),a.image.currentX>a.image.maxX&&(a.image.currentX=a.image.maxX-1+Math.pow(a.image.currentX-a.image.maxX+1,.8)),a.image.currentY<a.image.minY&&(a.image.currentY=a.image.minY+1-Math.pow(a.image.minY-a.image.currentY+1,.8)),a.image.currentY>a.image.maxY&&(a.image.currentY=a.image.maxY-1+Math.pow(a.image.currentY-a.image.maxY+1,.8)),a.velocity.prevPositionX||(a.velocity.prevPositionX=a.image.touchesCurrent.x),a.velocity.prevPositionY||(a.velocity.prevPositionY=a.image.touchesCurrent.y),a.velocity.prevTime||(a.velocity.prevTime=Date.now()),a.velocity.x=(a.image.touchesCurrent.x-a.velocity.prevPositionX)/(Date.now()-a.velocity.prevTime)/2,a.velocity.y=(a.image.touchesCurrent.y-a.velocity.prevPositionY)/(Date.now()-a.velocity.prevTime)/2,Math.abs(a.image.touchesCurrent.x-a.velocity.prevPositionX)<2&&(a.velocity.x=0),Math.abs(a.image.touchesCurrent.y-a.velocity.prevPositionY)<2&&(a.velocity.y=0),a.velocity.prevPositionX=a.image.touchesCurrent.x,a.velocity.prevPositionY=a.image.touchesCurrent.y,a.velocity.prevTime=Date.now(),a.gesture.imageWrap.transform("translate3d("+a.image.currentX+"px, "+a.image.currentY+"px,0)")}}},onTouchEnd:function(e,a){var t=e.zoom;if(t.gesture.image&&0!==t.gesture.image.length){if(!t.image.isTouched||!t.image.isMoved)return t.image.isTouched=!1,void(t.image.isMoved=!1);t.image.isTouched=!1,t.image.isMoved=!1;var s=300,i=300,r=t.velocity.x*s,n=t.image.currentX+r,o=t.velocity.y*i,l=t.image.currentY+o;0!==t.velocity.x&&(s=Math.abs((n-t.image.currentX)/t.velocity.x)),0!==t.velocity.y&&(i=Math.abs((l-t.image.currentY)/t.velocity.y));var p=Math.max(s,i);t.image.currentX=n,t.image.currentY=l;var d=t.image.width*t.scale,u=t.image.height*t.scale;t.image.minX=Math.min(t.gesture.slideWidth/2-d/2,0),t.image.maxX=-t.image.minX,t.image.minY=Math.min(t.gesture.slideHeight/2-u/2,0),t.image.maxY=-t.image.minY,t.image.currentX=Math.max(Math.min(t.image.currentX,t.image.maxX),t.image.minX),t.image.currentY=Math.max(Math.min(t.image.currentY,t.image.maxY),t.image.minY),t.gesture.imageWrap.transition(p).transform("translate3d("+t.image.currentX+"px, "+t.image.currentY+"px,0)")}},onTransitionEnd:function(e){var a=e.zoom;a.gesture.slide&&e.previousIndex!==e.activeIndex&&(a.gesture.image.transform("translate3d(0,0,0) scale(1)"),a.gesture.imageWrap.transform("translate3d(0,0,0)"),a.gesture.slide=a.gesture.image=a.gesture.imageWrap=void 0,a.scale=a.currentScale=1)},toggleZoom:function(a,t){var s=a.zoom;if(s.gesture.slide||(s.gesture.slide=a.clickedSlide?e(a.clickedSlide):a.slides.eq(a.activeIndex),s.gesture.image=s.gesture.slide.find("img, svg, canvas"),s.gesture.imageWrap=s.gesture.image.parent("."+a.params.zoomContainerClass)),s.gesture.image&&0!==s.gesture.image.length){var i,r,n,o,l,p,d,u,c,m,h,g,f,v,w,y,x,T;void 0===s.image.touchesStart.x&&t?(i="touchend"===t.type?t.changedTouches[0].pageX:t.pageX,r="touchend"===t.type?t.changedTouches[0].pageY:t.pageY):(i=s.image.touchesStart.x,r=s.image.touchesStart.y),s.scale&&1!==s.scale?(s.scale=s.currentScale=1,s.gesture.imageWrap.transition(300).transform("translate3d(0,0,0)"),s.gesture.image.transition(300).transform("translate3d(0,0,0) scale(1)"),s.gesture.slide=void 0):(s.scale=s.currentScale=s.gesture.imageWrap.attr("data-swiper-zoom")||a.params.zoomMax,t?(x=s.gesture.slide[0].offsetWidth,T=s.gesture.slide[0].offsetHeight,n=s.gesture.slide.offset().left,o=s.gesture.slide.offset().top,l=n+x/2-i,p=o+T/2-r,c=s.gesture.image[0].offsetWidth,m=s.gesture.image[0].offsetHeight,h=c*s.scale,g=m*s.scale,f=Math.min(x/2-h/2,0),v=Math.min(T/2-g/2,0),w=-f,y=-v,d=l*s.scale,u=p*s.scale,d<f&&(d=f),d>w&&(d=w),u<v&&(u=v),u>y&&(u=y)):(d=0,u=0),s.gesture.imageWrap.transition(300).transform("translate3d("+d+"px, "+u+"px,0)"),s.gesture.image.transition(300).transform("translate3d(0,0,0) scale("+s.scale+")"))}},attachEvents:function(a){var t=a?"off":"on";if(T.params.zoom){var s=(T.slides,!("touchstart"!==T.touchEvents.start||!T.support.passiveListener||!T.params.passiveListeners)&&{passive:!0,capture:!1});T.support.gestures?(T.slides[t]("gesturestart",T.zoom.onGestureStart,s),T.slides[t]("gesturechange",T.zoom.onGestureChange,s),T.slides[t]("gestureend",T.zoom.onGestureEnd,s)):"touchstart"===T.touchEvents.start&&(T.slides[t](T.touchEvents.start,T.zoom.onGestureStart,s),T.slides[t](T.touchEvents.move,T.zoom.onGestureChange,s),T.slides[t](T.touchEvents.end,T.zoom.onGestureEnd,s)),T[t]("touchStart",T.zoom.onTouchStart),T.slides.each(function(a,s){e(s).find("."+T.params.zoomContainerClass).length>0&&e(s)[t](T.touchEvents.move,T.zoom.onTouchMove)}),T[t]("touchEnd",T.zoom.onTouchEnd),T[t]("transitionEnd",T.zoom.onTransitionEnd),T.params.zoomToggle&&T.on("doubleTap",T.zoom.toggleZoom)}},init:function(){T.zoom.attachEvents()},destroy:function(){T.zoom.attachEvents(!0)}},T._plugins=[];for(var Y in T.plugins){var O=T.plugins[Y](T,T.params[Y]);O&&T._plugins.push(O)}return T.callPlugins=function(e){for(var a=0;a<T._plugins.length;a++)e in T._plugins[a]&&T._plugins[a][e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},T.emitterEventListeners={},T.emit=function(e){T.params[e]&&T.params[e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);var a;if(T.emitterEventListeners[e])for(a=0;a<T.emitterEventListeners[e].length;a++)T.emitterEventListeners[e][a](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);T.callPlugins&&T.callPlugins(e,arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},T.on=function(e,a){return e=m(e),T.emitterEventListeners[e]||(T.emitterEventListeners[e]=[]),T.emitterEventListeners[e].push(a),T},T.off=function(e,a){var t;if(e=m(e),void 0===a)return T.emitterEventListeners[e]=[],T;if(T.emitterEventListeners[e]&&0!==T.emitterEventListeners[e].length){for(t=0;t<T.emitterEventListeners[e].length;t++)T.emitterEventListeners[e][t]===a&&T.emitterEventListeners[e].splice(t,1);return T}},T.once=function(e,a){e=m(e);var t=function(){a(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]),T.off(e,t)};return T.on(e,t),T},T.a11y={makeFocusable:function(e){return e.attr("tabIndex","0"),e},addRole:function(e,a){return e.attr("role",a),e},addLabel:function(e,a){return e.attr("aria-label",a),e},disable:function(e){return e.attr("aria-disabled",!0),e},enable:function(e){return e.attr("aria-disabled",!1),e},onEnterKey:function(a){13===a.keyCode&&(e(a.target).is(T.params.nextButton)?(T.onClickNext(a),T.isEnd?T.a11y.notify(T.params.lastSlideMessage):T.a11y.notify(T.params.nextSlideMessage)):e(a.target).is(T.params.prevButton)&&(T.onClickPrev(a),T.isBeginning?T.a11y.notify(T.params.firstSlideMessage):T.a11y.notify(T.params.prevSlideMessage)),e(a.target).is("."+T.params.bulletClass)&&e(a.target)[0].click())},liveRegion:e('<span class="'+T.params.notificationClass+'" aria-live="assertive" aria-atomic="true"></span>'),notify:function(e){var a=T.a11y.liveRegion;0!==a.length&&(a.html(""),a.html(e))},init:function(){T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.a11y.makeFocusable(T.nextButton),T.a11y.addRole(T.nextButton,"button"),T.a11y.addLabel(T.nextButton,T.params.nextSlideMessage)),T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.a11y.makeFocusable(T.prevButton),T.a11y.addRole(T.prevButton,"button"),T.a11y.addLabel(T.prevButton,T.params.prevSlideMessage)),e(T.container).append(T.a11y.liveRegion)},initPagination:function(){T.params.pagination&&T.params.paginationClickable&&T.bullets&&T.bullets.length&&T.bullets.each(function(){var a=e(this);T.a11y.makeFocusable(a),T.a11y.addRole(a,"button"),T.a11y.addLabel(a,T.params.paginationBulletMessage.replace(/{{index}}/,a.index()+1))})},destroy:function(){T.a11y.liveRegion&&T.a11y.liveRegion.length>0&&T.a11y.liveRegion.remove()}},T.init=function(){T.params.loop&&T.createLoop(),T.updateContainerSize(),T.updateSlidesSize(),T.updatePagination(),T.params.scrollbar&&T.scrollbar&&(T.scrollbar.set(),T.params.scrollbarDraggable&&T.scrollbar.enableDraggable()),"slide"!==T.params.effect&&T.effects[T.params.effect]&&(T.params.loop||T.updateProgress(),T.effects[T.params.effect].setTranslate()),T.params.loop?T.slideTo(T.params.initialSlide+T.loopedSlides,0,T.params.runCallbacksOnInit):(T.slideTo(T.params.initialSlide,0,T.params.runCallbacksOnInit),0===T.params.initialSlide&&(T.parallax&&T.params.parallax&&T.parallax.setTranslate(),T.lazy&&T.params.lazyLoading&&(T.lazy.load(),T.lazy.initialImageLoaded=!0))),T.attachEvents(),T.params.observer&&T.support.observer&&T.initObservers(),T.params.preloadImages&&!T.params.lazyLoading&&T.preloadImages(),T.params.zoom&&T.zoom&&T.zoom.init(),T.params.autoplay&&T.startAutoplay(),T.params.keyboardControl&&T.enableKeyboardControl&&T.enableKeyboardControl(),T.params.mousewheelControl&&T.enableMousewheelControl&&T.enableMousewheelControl(),T.params.hashnavReplaceState&&(T.params.replaceState=T.params.hashnavReplaceState),T.params.history&&T.history&&T.history.init(),T.params.hashnav&&T.hashnav&&T.hashnav.init(),T.params.a11y&&T.a11y&&T.a11y.init(),T.emit("onInit",T)},T.cleanupStyles=function(){T.container.removeClass(T.classNames.join(" ")).removeAttr("style"),T.wrapper.removeAttr("style"),T.slides&&T.slides.length&&T.slides.removeClass([T.params.slideVisibleClass,T.params.slideActiveClass,T.params.slideNextClass,T.params.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-column").removeAttr("data-swiper-row"),T.paginationContainer&&T.paginationContainer.length&&T.paginationContainer.removeClass(T.params.paginationHiddenClass),T.bullets&&T.bullets.length&&T.bullets.removeClass(T.params.bulletActiveClass),T.params.prevButton&&e(T.params.prevButton).removeClass(T.params.buttonDisabledClass),T.params.nextButton&&e(T.params.nextButton).removeClass(T.params.buttonDisabledClass),T.params.scrollbar&&T.scrollbar&&(T.scrollbar.track&&T.scrollbar.track.length&&T.scrollbar.track.removeAttr("style"),T.scrollbar.drag&&T.scrollbar.drag.length&&T.scrollbar.drag.removeAttr("style"))},T.destroy=function(e,a){T.detachEvents(),T.stopAutoplay(),T.params.scrollbar&&T.scrollbar&&T.params.scrollbarDraggable&&T.scrollbar.disableDraggable(),T.params.loop&&T.destroyLoop(),a&&T.cleanupStyles(),T.disconnectObservers(),T.params.zoom&&T.zoom&&T.zoom.destroy(),T.params.keyboardControl&&T.disableKeyboardControl&&T.disableKeyboardControl(),T.params.mousewheelControl&&T.disableMousewheelControl&&T.disableMousewheelControl(),T.params.a11y&&T.a11y&&T.a11y.destroy(),T.params.history&&!T.params.replaceState&&window.removeEventListener("popstate",T.history.setHistoryPopState),T.params.hashnav&&T.hashnav&&T.hashnav.destroy(),T.emit("onDestroy"),e!==!1&&(T=null)},T.init(),T}};a.prototype={isSafari:function(){var e=window.navigator.userAgent.toLowerCase();return e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0}(),isUiWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent),isArray:function(e){return"[object Array]"===Object.prototype.toString.apply(e)},browser:{ie:window.navigator.pointerEnabled||window.navigator.msPointerEnabled,ieTouch:window.navigator.msPointerEnabled&&window.navigator.msMaxTouchPoints>1||window.navigator.pointerEnabled&&window.navigator.maxTouchPoints>1,lteIE9:function(){var e=document.createElement("div");return e.innerHTML="<!--[if lte IE 9]><i></i><![endif]-->",1===e.getElementsByTagName("i").length}()},device:function(){var e=window.navigator.userAgent,a=e.match(/(Android);?[\s\/]+([\d.]+)?/),t=e.match(/(iPad).*OS\s([\d_]+)/),s=e.match(/(iPod)(.*OS\s([\d_]+))?/),i=!t&&e.match(/(iPhone\sOS|iOS)\s([\d_]+)/);return{ios:t||i||s,android:a}}(),support:{touch:window.Modernizr&&Modernizr.touch===!0||function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)}(),transforms3d:window.Modernizr&&Modernizr.csstransforms3d===!0||function(){var e=document.createElement("div").style;return"webkitPerspective"in e||"MozPerspective"in e||"OPerspective"in e||"MsPerspective"in e||"perspective"in e}(),flexbox:function(){for(var e=document.createElement("div").style,a="alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient".split(" "),t=0;t<a.length;t++)if(a[t]in e)return!0}(),observer:function(){return"MutationObserver"in window||"WebkitMutationObserver"in window}(),passiveListener:function(){var e=!1;try{var a=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("testPassiveListener",null,a)}catch(e){}return e}(),gestures:function(){return"ongesturestart"in window}()},plugins:{}};for(var t=(function(){var e=function(e){var a=this,t=0;for(t=0;t<e.length;t++)a[t]=e[t];return a.length=e.length,this},a=function(a,t){var s=[],i=0;if(a&&!t&&a instanceof e)return a;if(a)if("string"==typeof a){var r,n,o=a.trim();if(o.indexOf("<")>=0&&o.indexOf(">")>=0){var l="div";for(0===o.indexOf("<li")&&(l="ul"),0===o.indexOf("<tr")&&(l="tbody"),0!==o.indexOf("<td")&&0!==o.indexOf("<th")||(l="tr"),0===o.indexOf("<tbody")&&(l="table"),0===o.indexOf("<option")&&(l="select"),n=document.createElement(l),n.innerHTML=a,i=0;i<n.childNodes.length;i++)s.push(n.childNodes[i])}else for(r=t||"#"!==a[0]||a.match(/[ .<>:~]/)?(t||document).querySelectorAll(a):[document.getElementById(a.split("#")[1])],i=0;i<r.length;i++)r[i]&&s.push(r[i])}else if(a.nodeType||a===window||a===document)s.push(a);else if(a.length>0&&a[0].nodeType)for(i=0;i<a.length;i++)s.push(a[i]);return new e(s)};return e.prototype={addClass:function(e){if(void 0===e)return this;for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.add(a[t]);return this},removeClass:function(e){for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.remove(a[t]);return this},hasClass:function(e){return!!this[0]&&this[0].classList.contains(e)},toggleClass:function(e){for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.toggle(a[t]);return this},attr:function(e,a){if(1===arguments.length&&"string"==typeof e)return this[0]?this[0].getAttribute(e):void 0;for(var t=0;t<this.length;t++)if(2===arguments.length)this[t].setAttribute(e,a);else for(var s in e)this[t][s]=e[s],this[t].setAttribute(s,e[s]);return this},removeAttr:function(e){for(var a=0;a<this.length;a++)this[a].removeAttribute(e);return this},data:function(e,a){if(void 0!==a){for(var t=0;t<this.length;t++){var s=this[t];s.dom7ElementDataStorage||(s.dom7ElementDataStorage={}),s.dom7ElementDataStorage[e]=a}return this}if(this[0]){var i=this[0].getAttribute("data-"+e);return i?i:this[0].dom7ElementDataStorage&&e in this[0].dom7ElementDataStorage?this[0].dom7ElementDataStorage[e]:void 0}},transform:function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this},transition:function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this},on:function(e,t,s,i){function r(e){var i=e.target;if(a(i).is(t))s.call(i,e);else for(var r=a(i).parents(),n=0;n<r.length;n++)a(r[n]).is(t)&&s.call(r[n],e)}var n,o,l=e.split(" ");for(n=0;n<this.length;n++)if("function"==typeof t||t===!1)for("function"==typeof t&&(s=arguments[1],i=arguments[2]||!1),o=0;o<l.length;o++)this[n].addEventListener(l[o],s,i);else for(o=0;o<l.length;o++)this[n].dom7LiveListeners||(this[n].dom7LiveListeners=[]),this[n].dom7LiveListeners.push({listener:s,liveListener:r}),this[n].addEventListener(l[o],r,i);return this},off:function(e,a,t,s){for(var i=e.split(" "),r=0;r<i.length;r++)for(var n=0;n<this.length;n++)if("function"==typeof a||a===!1)"function"==typeof a&&(t=arguments[1],s=arguments[2]||!1),this[n].removeEventListener(i[r],t,s);else if(this[n].dom7LiveListeners)for(var o=0;o<this[n].dom7LiveListeners.length;o++)this[n].dom7LiveListeners[o].listener===t&&this[n].removeEventListener(i[r],this[n].dom7LiveListeners[o].liveListener,s);return this},once:function(e,a,t,s){function i(n){t(n),r.off(e,a,i,s)}var r=this;"function"==typeof a&&(a=!1,t=arguments[1],s=arguments[2]),r.on(e,a,i,s)},trigger:function(e,a){for(var t=0;t<this.length;t++){var s;try{s=new window.CustomEvent(e,{detail:a,bubbles:!0,cancelable:!0})}catch(t){s=document.createEvent("Event"),s.initEvent(e,!0,!0),s.detail=a}this[t].dispatchEvent(s)}return this},transitionEnd:function(e){function a(r){if(r.target===this)for(e.call(this,r),t=0;t<s.length;t++)i.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],i=this;if(e)for(t=0;t<s.length;t++)i.on(s[t],a);return this},width:function(){return this[0]===window?window.innerWidth:this.length>0?parseFloat(this.css("width")):null},outerWidth:function(e){return this.length>0?e?this[0].offsetWidth+parseFloat(this.css("margin-right"))+parseFloat(this.css("margin-left")):this[0].offsetWidth:null},height:function(){return this[0]===window?window.innerHeight:this.length>0?parseFloat(this.css("height")):null},outerHeight:function(e){return this.length>0?e?this[0].offsetHeight+parseFloat(this.css("margin-top"))+parseFloat(this.css("margin-bottom")):this[0].offsetHeight:null},offset:function(){if(this.length>0){var e=this[0],a=e.getBoundingClientRect(),t=document.body,s=e.clientTop||t.clientTop||0,i=e.clientLeft||t.clientLeft||0,r=window.pageYOffset||e.scrollTop,n=window.pageXOffset||e.scrollLeft;return{top:a.top+r-s,left:a.left+n-i}}return null},css:function(e,a){var t;if(1===arguments.length){if("string"!=typeof e){for(t=0;t<this.length;t++)for(var s in e)this[t].style[s]=e[s];return this}if(this[0])return window.getComputedStyle(this[0],null).getPropertyValue(e)}if(2===arguments.length&&"string"==typeof e){for(t=0;t<this.length;t++)this[t].style[e]=a;return this}return this},each:function(e){for(var a=0;a<this.length;a++)e.call(this[a],a,this[a]);return this},html:function(e){if(void 0===e)return this[0]?this[0].innerHTML:void 0;for(var a=0;a<this.length;a++)this[a].innerHTML=e;return this},text:function(e){if(void 0===e)return this[0]?this[0].textContent.trim():null;for(var a=0;a<this.length;a++)this[a].textContent=e;return this},is:function(t){if(!this[0])return!1;var s,i;if("string"==typeof t){var r=this[0];if(r===document)return t===document;if(r===window)return t===window;if(r.matches)return r.matches(t);if(r.webkitMatchesSelector)return r.webkitMatchesSelector(t);if(r.mozMatchesSelector)return r.mozMatchesSelector(t);if(r.msMatchesSelector)return r.msMatchesSelector(t);for(s=a(t),i=0;i<s.length;i++)if(s[i]===this[0])return!0;return!1}if(t===document)return this[0]===document;if(t===window)return this[0]===window;if(t.nodeType||t instanceof e){for(s=t.nodeType?[t]:t,i=0;i<s.length;i++)if(s[i]===this[0])return!0;return!1}return!1},index:function(){if(this[0]){for(var e=this[0],a=0;null!==(e=e.previousSibling);)1===e.nodeType&&a++;return a}},eq:function(a){if(void 0===a)return this;var t,s=this.length;return a>s-1?new e([]):a<0?(t=s+a,new e(t<0?[]:[this[t]])):new e([this[a]])},append:function(a){var t,s;for(t=0;t<this.length;t++)if("string"==typeof a){var i=document.createElement("div");for(i.innerHTML=a;i.firstChild;)this[t].appendChild(i.firstChild)}else if(a instanceof e)for(s=0;s<a.length;s++)this[t].appendChild(a[s]);else this[t].appendChild(a);return this},prepend:function(a){var t,s;for(t=0;t<this.length;t++)if("string"==typeof a){var i=document.createElement("div");for(i.innerHTML=a,s=i.childNodes.length-1;s>=0;s--)this[t].insertBefore(i.childNodes[s],this[t].childNodes[0])}else if(a instanceof e)for(s=0;s<a.length;s++)this[t].insertBefore(a[s],this[t].childNodes[0]);else this[t].insertBefore(a,this[t].childNodes[0]);return this},insertBefore:function(e){for(var t=a(e),s=0;s<this.length;s++)if(1===t.length)t[0].parentNode.insertBefore(this[s],t[0]);else if(t.length>1)for(var i=0;i<t.length;i++)t[i].parentNode.insertBefore(this[s].cloneNode(!0),t[i])},insertAfter:function(e){for(var t=a(e),s=0;s<this.length;s++)if(1===t.length)t[0].parentNode.insertBefore(this[s],t[0].nextSibling);else if(t.length>1)for(var i=0;i<t.length;i++)t[i].parentNode.insertBefore(this[s].cloneNode(!0),t[i].nextSibling)},next:function(t){return new e(this.length>0?t?this[0].nextElementSibling&&a(this[0].nextElementSibling).is(t)?[this[0].nextElementSibling]:[]:this[0].nextElementSibling?[this[0].nextElementSibling]:[]:[])},nextAll:function(t){var s=[],i=this[0];if(!i)return new e([]);for(;i.nextElementSibling;){var r=i.nextElementSibling;t?a(r).is(t)&&s.push(r):s.push(r),i=r}return new e(s)},prev:function(t){return new e(this.length>0?t?this[0].previousElementSibling&&a(this[0].previousElementSibling).is(t)?[this[0].previousElementSibling]:[]:this[0].previousElementSibling?[this[0].previousElementSibling]:[]:[])},prevAll:function(t){var s=[],i=this[0];if(!i)return new e([]);for(;i.previousElementSibling;){var r=i.previousElementSibling;t?a(r).is(t)&&s.push(r):s.push(r),i=r}return new e(s)},parent:function(e){for(var t=[],s=0;s<this.length;s++)e?a(this[s].parentNode).is(e)&&t.push(this[s].parentNode):t.push(this[s].parentNode);return a(a.unique(t))},parents:function(e){for(var t=[],s=0;s<this.length;s++)for(var i=this[s].parentNode;i;)e?a(i).is(e)&&t.push(i):t.push(i),i=i.parentNode;return a(a.unique(t))},find:function(a){for(var t=[],s=0;s<this.length;s++)for(var i=this[s].querySelectorAll(a),r=0;r<i.length;r++)t.push(i[r]);return new e(t)},children:function(t){for(var s=[],i=0;i<this.length;i++)for(var r=this[i].childNodes,n=0;n<r.length;n++)t?1===r[n].nodeType&&a(r[n]).is(t)&&s.push(r[n]):1===r[n].nodeType&&s.push(r[n]);return new e(a.unique(s))},remove:function(){for(var e=0;e<this.length;e++)this[e].parentNode&&this[e].parentNode.removeChild(this[e]);return this},add:function(){var e,t,s=this;for(e=0;e<arguments.length;e++){var i=a(arguments[e]);for(t=0;t<i.length;t++)s[s.length]=i[t],s.length++}return s}},a.fn=e.prototype,a.unique=function(e){for(var a=[],t=0;t<e.length;t++)a.indexOf(e[t])===-1&&a.push(e[t]);return a},a}()),s=["jQuery","Zepto","Dom7"],i=0;i<s.length;i++)window[s[i]]&&function(e){e.fn.swiper=function(t){var s;return e(this).each(function(){var e=new a(this,t);s||(s=e)}),s}}(window[s[i]]);var r;r=void 0===t?window.Dom7||window.Zepto||window.jQuery:t,r&&("transitionEnd"in r.fn||(r.fn.transitionEnd=function(e){function a(r){if(r.target===this)for(e.call(this,r),t=0;t<s.length;t++)i.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],i=this;if(e)for(t=0;t<s.length;t++)i.on(s[t],a);return this}),"transform"in r.fn||(r.fn.transform=function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this}),"transition"in r.fn||(r.fn.transition=function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this}),"outerWidth"in r.fn||(r.fn.outerWidth=function(e){ +return this.length>0?e?this[0].offsetWidth+parseFloat(this.css("margin-right"))+parseFloat(this.css("margin-left")):this[0].offsetWidth:null})),window.Swiper=a}(),"undefined"!=typeof module?module.exports=window.Swiper:"function"==typeof define&&define.amd&&define([],function(){"use strict";return window.Swiper}); +//# sourceMappingURL=maps/swiper.min.js.map diff --git a/static/app/js/time_limit.js b/static/app/js/time_limit.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app/js/upload.js b/static/app/js/upload.js new file mode 100755 index 0000000..c2efe16 --- /dev/null +++ b/static/app/js/upload.js @@ -0,0 +1,129 @@ +accessid = '' +accesskey = '' +host = '' +policyBase64 = '' +signature = '' +callbackbody = '' +filename = '' +key = '' +expire = 0 +g_object_name = '' +g_object_name_type = '' +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'images' + +function send_request() { + var xmlhttp = null; + if(window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if(window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if(xmlhttp != null) { +// console.log(dir) + serverUrl = hyhUrl('oss/get.php?dir='+dir); + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + alert("Your browser does not support XMLHTTP."); + } + +}; + +function check_object_radio() { + var tt = document.getElementsByName('myradio'); + for(var i = 0; i < tt.length; i++) { + if(tt[i].checked) { + g_object_name_type = tt[i].value; + break; + } + } +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if(expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) {   + len = len || 32;   + var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   + var maxPos = chars.length;   + var pwd = '';   + for(i = 0; i < len; i++) {   + pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if(pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) { + if(g_object_name_type == 'local_name') { + g_object_name += "${filename}" + } else if(g_object_name_type == 'random_name') { + suffix = get_suffix(filename) + g_object_name = key + random_string(10) + suffix + } + return '' +} + +function get_uploaded_object_name(filename) { + if(g_object_name_type == 'local_name') { + tmp_name = g_object_name + tmp_name = tmp_name.replace("${filename}", filename); + return tmp_name + } else if(g_object_name_type == 'random_name') { + return g_object_name + } +} + +function set_upload_param(up, filename, ret,savedir) { + dir = savedir; + if(ret == false) { + ret = get_signature() + } + + g_object_name = key; + if(filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key': g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId': accessid, + 'success_action_status': '200', //让服务端返回200,不然,默认会返回204 + 'callback': callbackbody, + 'signature': signature, + }; + + up.setOption({ + 'url': host, + 'multipart_params': new_multipart_params + }); + + up.start(); +} \ No newline at end of file diff --git a/static/app/js/upload1.js b/static/app/js/upload1.js new file mode 100755 index 0000000..66f46c4 --- /dev/null +++ b/static/app/js/upload1.js @@ -0,0 +1,306 @@ +accessid = '' +accesskey = '' +host = '' +policyBase64 = '' +signature = '' +callbackbody = '' +filename = '' +key = '' +expire = 0 +g_object_name = '' +g_object_name_type = '' +now = timestamp = Date.parse(new Date()) / 1000; + +function send_request() { + var xmlhttp = null; + if(window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if(window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if(xmlhttp != null) { + serverUrl = '../php/get.php' + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + alert("Your browser does not support XMLHTTP."); + } +}; + +function check_object_radio() { + var tt = document.getElementsByName('myradio'); + for(var i = 0; i < tt.length; i++) { + if(tt[i].checked) { + g_object_name_type = tt[i].value; + break; + } + } +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if(expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) {   + len = len || 32;   + var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   + var maxPos = chars.length;   + var pwd = '';   + for(i = 0; i < len; i++) {   + pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if(pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) { + if(g_object_name_type == 'local_name') { + g_object_name += "${filename}" + } else if(g_object_name_type == 'random_name') { + suffix = get_suffix(filename) + g_object_name = key + random_string(10) + suffix + } + return '' +} + +function get_uploaded_object_name(filename) { + if(g_object_name_type == 'local_name') { + tmp_name = g_object_name + tmp_name = tmp_name.replace("${filename}", filename); + return tmp_name + } else if(g_object_name_type == 'random_name') { + return g_object_name + } +} + +function set_upload_param(up, filename, ret) { + if(ret == false) { + ret = get_signature() + } + g_object_name = key; + if(filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key': g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId': accessid, + 'success_action_status': '200', //让服务端返回200,不然,默认会返回204 + 'callback': callbackbody, + 'signature': signature, + }; + + up.setOption({ + 'url': host, + 'multipart_params': new_multipart_params + }); + + up.start(); +} +var html = ''; +for(i = 0; i < 3; i++) { + html += '<div class="up_out"><div id="ossfile' + i + '" class="ossfile clearfix" data-num="' + i + '">你的浏览器不支持flash,Silverlight或者HTML5!</div><div id="container' + i + '" class="container" data-num="' + i + '"><a id="selectfiles' + i + '" href="javascript:void(0);" class="btn selectfiles" data-num="' + i + '">选择文件</a></div></div>' +} + +$('.con').html(html) + +var btnArr = []; + +$('.selectfiles').each(function(num) { + btnArr.push($(this).attr('id')); +}) + +$.each(btnArr, function(i, n) { + var self = this.toString(); + var that = document.getElementById(this); + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: self, + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementsByClassName('ossfile')[i].innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementsByClassName('ossfile')[i].innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + get_uploaded_object_name(file.name) + '" src="http://heyuanhui.oss-cn-qingdao.aliyuncs.com/' + get_uploaded_object_name(file.name) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + alert("\n选择的文件太大了"); + } else if(err.code == -601) { + alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + alert("\n这个文件已经上传过一遍了"); + } else { + alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); +}); + +var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'selectfiles', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('ossfile').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('ossfile').innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img src="http://heyuanhui.oss-cn-qingdao.aliyuncs.com/' + get_uploaded_object_name(file.name) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + alert("\n选择的文件太大了"); + } else if(err.code == -601) { + alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + alert("\n这个文件已经上传过一遍了"); + } else { + alert("\nError xml:" + err.response); + } + } + } +}); + +uploader.init(); \ No newline at end of file diff --git a/static/app2/css/ac.css b/static/app2/css/ac.css new file mode 100755 index 0000000..e4583f1 --- /dev/null +++ b/static/app2/css/ac.css @@ -0,0 +1,3 @@ +img{ + display: block; +} diff --git a/static/app2/css/activity1.css b/static/app2/css/activity1.css new file mode 100755 index 0000000..a58054c --- /dev/null +++ b/static/app2/css/activity1.css @@ -0,0 +1,345 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .title img { + width: 324px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 288px; + margin-top: 40px; + } + .ljjg, + .ljjg img { + height: 140px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .title img { + width: 300px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 265px; + margin-top: 35px; + } + .ljjg, + .ljjg img { + height: 127px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .title img { + width: 270px; + z-index: 12; + } + .title { + margin-top: -12px; + } + .hyhflfs { + height: 230px; + margin-top: 30px; + } + .ljjg, + .ljjg img { + height: 108px; + } +} + +body { + background: #3d2467; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.title { + text-align: center; + position: absolute; + z-index: 10; + width: 100%; +} + +.hyhflfs { + width: 94%; + margin-left: 3%; + margin-right: 3%; + background: #5524a8; + border-radius: 12px; +} + +.yhq { + padding: 6px 2% 0; +} + +.yhq_block { + margin: 3px 0.8% 0; + position: relative; + float: left; + width: 23.4%; +} + +.yhq_p1 { + position: absolute; + color: #FDFFFE; + font-size: 13.2px; + text-align: center; + top: 0; + margin: 0 auto; + left: 0; + right: 0; + height: 18px; + line-height: 18px; +} + +.yhq_p2 { + position: absolute; + color: #FDFFFE; + font-size: 44.4px; + text-align: center; + top: 20%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; + letter-spacing: -3px; +} + +.yhq_p3 { + position: absolute; + color: #FDFFFE; + font-size: 7.2px; + text-align: center; + top: 42%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; +} + +.yhq_p4 { + position: absolute; + color: #FDFFFE; + font-size: 10.8px; + text-align: center; + top: 55%; + margin: 0 auto; + left: 0; + right: 0; + font-weight: bold; + z-index: 9; +} + +.yhq_btn { + z-index: 10; + width: 90%; + position: absolute; + bottom: 8px; + text-align: center; + background: #ffbd1f; + color: #fdfffe; + margin: 0 5%; + border-radius: 15px; + height: 20px; + line-height: 20px; + font-size: 10.8px; +} + +.ljjg { + margin: 0 2.5%; + background: url(../img/ljjg_bg.png) no-repeat center top; + width: 95%; + background-size: 100%; +} + +.yhq_block img { + width: 100%; +} + +.ljjg img { + margin-left: 5%; + float: left; +} + +.p1 { + color: #fdfd21; + font-size: 18px; + margin-top: 12%; +} + +.p2 { + color: #ffffff; + font-size: 14.4px; + margin-top: 3%; +} + +.ljjg_r { + float: right; + width: 51%; + text-align: center; +} + +.ljjg_btn { + width: 120px; + height: 27.6px; + line-height: 27.6px; + color: white; + background: #ffbd1f; + margin: 6% auto; + border-radius: 5px; +} + +.hengfu img { + width: 100%; + margin: 2% 0 5%; +} + +.bktj { + margin-top: 50px; + margin-bottom: 20px; +} + +.bktj_b { + background: url(../img/bktj_bg.png) no-repeat center top; + background-size: 100%; + position: relative; +} + +.bktj_b img { + width: 100%; +} + +.bktj_con { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + padding: 3% 8.7%; +} + +.bktj_con img { + width: 48%; + float: left; +} + +.bktj_con_con { + width: 52%; + float: left; + text-align: center; + position: relative; +} + +.p3 { + color: #fdfd21; + font-size: 21.6px; + margin-top: 7%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.p4 { + color: #FFFFFF; + font-size: 13.2px; + margin-top: 7%; +} + +.bktj_con_con .ljqg_btn { + /*position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 15px;*/ + margin-top: 5%; +} + +.xpss { + padding: 10px; + margin-top: 70px; +} + +.xpss_b { + width: 46%; + margin: 2%; + float: left; + position: relative; +} + +.xpss_b img { + width: 100%; +} + +.xpss_con { + padding: 3%; + width: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.xpss_b .xpss_con img { + width: 80%; + margin: 0 10% 0; +} + +.p5 del { + font-size: 12px; + color: #5f5f5f; +} + +.p5 { + color: #f10637; + font-size: 21.6px; + font-weight: bold; + text-align: center; + position: absolute; + bottom: 22%; + left: 0; + right: 0; +} + +.xpss_ljqg_btn { + width: 80%; + height: 24px; + line-height: 24px; + text-align: center; + background: #f1063a; + color: #fefefe; + font-size: 14.4px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + border-radius: 5px; + bottom: 8%; +} \ No newline at end of file diff --git a/static/app2/css/activity10.css b/static/app2/css/activity10.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/activity2.css b/static/app2/css/activity2.css new file mode 100755 index 0000000..a5efb84 --- /dev/null +++ b/static/app2/css/activity2.css @@ -0,0 +1,301 @@ +body { + background: #c82929; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.yhq { + position: relative; + width: 100%; +} + +.yhq img { + width: 100%; +} + +.yhq_con { + padding: 2.5%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.yhq_con_block { + width: 45%; + margin: 5% 2.5% 0; + float: left; + position: relative; +} + +.yhq_con_block img { + width: 100%; +} + +.yhq_con_block_con { + position: absolute; + right: 4%; + top: 6%; + bottom: 5%; + left: 35%; +} + +.yhq_p1 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + color: #C82828; + font-size: 10.8px; + top: 18%; +} + +.yhq_p2 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + color: #C82828; + font-size: 10.8px; + bottom: 2%; +} + +.yhq_p1 o { + font-weight: bold; + font-size: 36px; + letter-spacing: -3px; +} + +.ac img { + width: 100%; +} + +.gchh { + padding: 2%; +} + +.gchh_block { + width: 48%; + margin: 1%; + float: left; + position: relative; +} + +.gchh_b_bg { + width: 100%; +} + +.gchh_b_con { + position: absolute; + width: 92%; + top: 4%; + left: 4%; + border-radius: 5%; + height: 80%; + overflow: hidden; +} + +.gchh_b_con img { + width: 100%; + height: 100%; +} + +.gchh_b_con p { + position: absolute; + color: white; + bottom: 0; + left: 0; + right: 0; + text-align: center; + font-size: 14.4px; + padding: 3%; + background: rgba(200, 41, 41, 0.2); +} + +.title { + position: relative; +} + +.title img { + width: 100%; +} + +.title p { + text-align: center; + font-weight: bold; + color: #c82828; + font-size: 21.6px; + position: absolute; + left: 0; + right: 0; + margin: 6% auto; + top: 0; +} + +.zdzb_block { + position: relative; +} + +.zdzb_block img { + width: 100%; +} + +.zdzb_zzc { + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 11; +} + +.zdzb_block_con { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + padding: 5.3% 4.6% 0; +} + +.zdzb_block_con img { + border-radius: 50%; + width: 100%; + height: 87.75%; +} + +.zdzb_block_con p { + position: absolute; + left: 12%; + right: 12%; + text-align: center; + font-size: 13.2px; + color: #c82828; + margin: 1% auto 0; + height: 25px; + line-height: 25px; + background: #fef8d4; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + bottom: 10%; +} + +.cost { + position: absolute; + font-size: 33.6px; + color: #c72928; + bottom: 2%; + left: 18%; +} + +.zdzb_block_con b { + font-size: 10.8px; + position: absolute; + color: #c72928; + bottom: 1%; + left: 15%; +} + +.zdzb_btn { + font-size: 12px; + position: absolute; + background: #c72b29; + bottom: 2%; + right: 15%; + text-align: center; + height: 25px; + line-height: 25px; + color: white; + width: 75px; + border-radius: 15px; +} + +.zdzb2 { + padding: 1%; +} + +.zdzb2_block { + width: 31.3%; + position: relative; + margin: 1%; + float: left; +} + +.zdzb2_block img { + width: 100%; +} + +.zdzb2_block p { + text-align: center; + color: #C72928; + font-size: 15.6px; + margin: auto; + position: absolute; + height: 20px; + line-height: 20px; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +.zdzb3 { + padding: 2%; +} + +.zdzb3_block { + width: 30.3333%; + position: relative; + margin: 1.5%; + float: left; +} + +.zdzb3_block img { + width: 100%; +} + +.zdzb3_block .zdzb3_block_con img { + width: 90%; + position: absolute; + top: 5%; + left: 5%; + right: 5%; + height: 68%; + z-index: 10; +} + +.zdzb3_block .zdzb3_block_con p { + color: #e41f4a; + font-weight: bold; + font-size: 12px; + text-align: center; + position: absolute; + left: 0; + right: 0; + bottom: 5%; +} + +.zdzb3_block .zdzb3_block_con .sanjiao { + z-index: 11; + position: absolute; + width: 90%; + height: auto; + top: 69%; +} \ No newline at end of file diff --git a/static/app2/css/activity3.css b/static/app2/css/activity3.css new file mode 100755 index 0000000..5aaa88d --- /dev/null +++ b/static/app2/css/activity3.css @@ -0,0 +1,293 @@ +body { + background: black; +} + +.header { + position: relative; +} + +.header .mui-action-back { + margin-top: 15px; + color: white; + position: absolute; + z-index: 11; + padding: 9px; +} + +.header img { + width: 100%; +} + +.header .time { + width: 126px; + height: 39px; + line-height: 39px; + text-align: center; + border: 1px solid #f4d752; + color: #f6e164; + font-size: 21.6px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 30%; +} + +.yhq { + padding: 0 2%; +} + +.yhq_block { + width: 23%; + height: 117px; + float: left; + margin: 1%; + position: relative; + background: #c59c5a; + border-radius: 3%; +} + +.yhq_block .yhq_img { + width: 100%; +} + +.yhq_block .yhq_btn { + width: 90%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 7%; +} + +.yhq_p1 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 36px; + font-weight: bold; + letter-spacing: -3px; + text-align: center; + color: #262626; + top: 18px; +} + +.yhq_p2 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 14.4px; + text-align: center; + color: #262626; + top: 48px; +} + +.yhq_p3 { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + font-size: 9.6px; + text-align: center; + color: #262626; + top: 68px; +} + +.title { + width: 100%; + text-align: center; + padding: 5% 18%; +} + +.title img { + width: 100%; +} + +.jggcj { + width: 100%; + padding: 2%; + position: relative; +} + +.jggcj .bg_img { + width: 100%; +} + +.zz_img { + width: 96%; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + bottom: 9.5%; + z-index: 10; +} + +.jggcj .on { + transform: rotateY(180deg); +} + +.cj_con { + width: 82.8%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 18%; + z-index: 11; + padding: 0.5% 0 0 1%; +} + +.content { + width: 32.3%; + float: left; + margin: 0 1% 0.5% 0; + position: relative; +} + +.content img { + width: 100%; +} + +.num { + width: 98%; + text-align: center; + position: absolute; + bottom: 4%; + color: #FFFFFF; + font-size: 13.2px; +} + +.content_con { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 12; +} + +.cj_con .active .content_con { + background: rgba(255, 255, 255, 0.6); + border-radius: 10%; +} + +.content_con img { + width: 100%; + height: 100%; +} + +.nav { + padding: 1%; +} + +.nav_block { + width: 48%; + margin: 1%; + float: left; + position: relative; +} + +.nav_block img { + width: 100% +} + +.nav_block_con { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.p1 { + color: #fffffe; + font-size: 16.8px; + margin-left: 4%; + margin-top: 4%; +} + +.p2 { + color: #fffffe; + margin-left: 4%; + height: 16px; +} + +.go { + text-align: center; + width: 40px; + height: 16px; + line-height: 16px; + font-size: 10.8px; + background: white; + margin-left: 4%; + border-radius: 15px; + margin-top: 3%; +} + +.nav .nav_block1 { + width: 98%; +} + +.nav .nav_block1 .p1 { + margin-top: 2%; + margin-left: 2%; +} + +.nav .nav_block1 .p2 { + margin-left: 2%; +} + +.nav .nav_block1 .go { + margin-top: 1.5%; + margin-left: 2%; +} + +.list { + padding: 1%; +} + +.list_block { + width: 48%; + margin: 1%; + position: relative; + float: left; +} + +.list_block_bg { + width: 100%; +} + +.list_block_con { + padding: 2% 2% 0; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.list_block_con img { + width: 100%; + height: 85%; +} + +.p3 { + color: white; + height: 15px; + font-size: 10.8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 80%; +} + +.p4 { + color: white; + height: 15px; + font-size: 14.4px; + position: absolute; + bottom: 3%; +} \ No newline at end of file diff --git a/static/app2/css/activity4.css b/static/app2/css/activity4.css new file mode 100755 index 0000000..c27677b --- /dev/null +++ b/static/app2/css/activity4.css @@ -0,0 +1,243 @@ + +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); +} + +#topbanner .swiper-container { + width: 100%; +} + +#topbanner .swiper-wrapper { + padding: 1%; + background: white; +} + +#topbanner .swiper-slide { + float: left; + width: 30%; +} + +.ss_top p, +.ss_bottom p { + color: #909090; + font-size: 10px; + position: absolute; + bottom: 5px; + text-align: center; + left: 0; + right: 0; +} + +.ss_top, +.ss_bottom { + width: 100%; + position: absolute; + color: #909090; +} + +.ss_top { + top: 0; +} + +.ss_bottom { + margin-top: 5%; + bottom: 0; +} + +.t_con { + width: 100%; + overflow: hidden; + background: white; + border-top: 1px solid #EFEFF4; +} + +#topbanner { + /*width: 472px;*/ +} + +#topbanner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#topbanner .swiper-slide { + position: relative; +} + +.ss_top img, +.ss_bottom img { + width: 100%; + height: 100%; + display: block; +} + +.scroll_top_block { + width: 24%; + margin: 0.5%; + float: left; + background: white; + border-radius: 5%; +} + +.scroll_top_block img { + width: 60%; + margin: 15% 20% 0; +} + +.scroll_top_block p { + text-align: center; + font-size: 10.8px; + color: #909090; + margin-top: -3%; +} + +.scroll_con { + /*background: white;*/ +} + +.scroll_con_block { + background: white; + margin-bottom: 5px; + margin-top: 1px; +} + +.scb_title { + width: 100%; + height: 75px; + position: relative; +} + +.scb_title img { + width: 50px; + height: 50px; + margin: 12.5px 5px; +} + +.scb_title p { + position: absolute; + font-size: 15.6px; + color: black; + left: 65px; + top: 15px; + width: 55%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.scb_title .s1 { + padding: 0 5px; + font-size: 10.6px; + color: #fefefe; + background: #e4ae7b; + border-radius: 3px; + position: absolute; + left: 65px; + top: 40px; +} + +.scb_title .s2 { + padding: 4px 15px; + font-size: 13.2px; + color: #909090; + background: #e6e6e6; + border-radius: 15px; + position: absolute; + right: 22px; + top: 20px; +} + +.scroll_con_con { + padding: 0 0 2%; +} + +.scc_block { + width: 31%; + margin: 1%; + float: left; +} + +.scc_block img { + width: 100%; +} + +.scc_block { + /*border: 1px solid #e6e6e6;*/ +} + +.scc_block p { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + text-align: center; + padding: 0 2%; + font-size: 12px; + color: black; + height: 42px; +} + +.scc_block span { + display: block; + font-size: 14.4px; + /*font-weight: bold;*/ + text-align: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: #ed344a; +} + +.nav { + width: 100%; + height: 40px; + background: white; + border-top: 1px solid #ececec; + border-left: 1px solid #ececec; + margin-top: 5px; +} + + +.nav_block { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; + width: 20%; + text-align: center; +} + +.nav .on { + color: #ee344a; + border-bottom: 4px solid #ed374c; +} + +.con_block { + width: 100%; + height: 120px; + background: #fff; + position: relative; +} diff --git a/static/app2/css/activity5.css b/static/app2/css/activity5.css new file mode 100755 index 0000000..4f0a6a4 --- /dev/null +++ b/static/app2/css/activity5.css @@ -0,0 +1,141 @@ +body { + background: white; +} + +.con { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.mui-slider-group, +.mui-slider-item, +.mui-slider-item img { + height: 144px; +} + +.ac5_con { + padding: 3%; +} + +.title { + position: relative; + margin-bottom: 1%; +} + +.title img { + width: 100%; +} + +.title p { + position: absolute; + width: 100%; + top: 45%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + text-align: center; + color: #FFFFFF; + font-size: 16.8px; +} + +.con_o { + position: relative; + margin-bottom: 2%; +} + +.con_o img { + width: 100%; +} + +.con_o .img { + position: absolute; + left: 6%; + top: 22%; + width: 35%; +} + +.con_oo { + position: absolute; + right: 6%; + top: 22%; + bottom: 14%; + left: 43%; + text-align: center; +} + +.p1 { + font-size: 15.6px; + color: #909090; + margin-top: 2%; +} + +.p2 { + font-size: 15.6px; + color: #525252; + font-weight: bold; + margin-top: 2%; +} + +.p3 { + color: #f23046; + font-size: 19.2px; + margin-top: 2%; +} + +.con_oo_btn { + padding: 5% 10%; + background: #f23249; + color: white; + font-size: 13.2px; + border: none; + margin-top: 2%; +} + +.con_t_block { + width: 49%; + margin: 0.5%; + border: 2px solid #f1f1f1; + float: left; +} + +.con_t_block img { + width: 100%; +} + +.con_t_block p { + padding: 2%; + height: 48px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.tfooter{ + width: 100%; + height: 36px; + line-height: 36px; +} +.tfooter span{ + font-size: 14.4px; + color: #fa3c50; + float: left; + +} +.con_t_btn{ + float: right; + border: none; + border-radius: 50px 0 0 50px; + color: white; + background: -moz-linear-gradient(left, #fc055f, #fb2c54); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#fc055f), to(#fb2c54)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #fc055f, #fb2c54); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #fc055f, #fb2c54); +} diff --git a/static/app2/css/activity6.css b/static/app2/css/activity6.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/activity7.css b/static/app2/css/activity7.css new file mode 100755 index 0000000..631cedc --- /dev/null +++ b/static/app2/css/activity7.css @@ -0,0 +1,224 @@ + +.mui-scroll {} + + +.tanhao { + width: 36.5px; + position: absolute; + right: 2.8%; + bottom: 7px; + padding: 10px; +} + +.ect_top { + padding: 0 2.5%; + width: 100%; + position: relative; + height: 54px; + position: fixed; + left: 0; + right: 0; + top: 66px; + background: white; +} + +#last, +#vol { + border-bottom: none; +} + +.ect_m { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #909090; + float: left; + width: 50%; + padding: 2.5px 0; + text-align: center; + background: #fff; + border-bottom: 1px solid #e6e6e6; + height: 27px; +} + +.ect_top img { + width: 17.5px; + height: 16.2px; + position: absolute; + left: 37.2px; + top: 30.6px; +} + + +/*top end*/ + +.con { + width: 100%; + /*padding: 0 1.25%;*/ +} + +.con_{ + width: 100%; + padding: 0 1.25%; +} + +.con .ect_com { + width: 47.25%; + margin: 1.25%; + background: #fff; + float: left; +} + +.com_img1 { + width: 100%; +} + +.com_img1 img { + width: 100%; + height: 100%; + display: block; +} + +.com_img2 { + width: 30px; + height: 15px; + /*margin-left: 3.6px;*/ + margin-right: 8.4px; + margin-top: 5px; + display: inline-block; +} + +.ect_com p { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #000000; + width: 100%; + padding-left: 3.6px; +} + +.ect_com .p1 { + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.ect_com .p3 { + color: #e51329; + margin-top: 14px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ect_activity { + width: 100%; +} +.ect_activity_{ + width: 100%; + position: relative; +} + +#_h,#_m,#_s{ + background: #525252; + color: white; + padding: 0 3px; + font-size: 12px; + position: absolute; + bottom: 0px; + border-radius: 3px; + /*line-height: 13px;*/ + /*height: 14px;*/ + bottom: 12%; +} +#_h{ + left: 48.9%; +} +#_m{ + left: 55.7%; +} +#_s{ + left: 62.5%; +} +.ect_hd { + width: 48%; + display: block; + margin: 0 auto; +} +.ect_djs{ + width: 38%; + margin: 10px auto 0; + display: block; + padding-bottom: 10px; +} + +.day { + width: 80%; + height: 15px; + background: #fbdcdc; + margin-left: 2%; + margin-bottom: 2.5px; +} + +.day p { + font-family: "微软雅黑"; + font-size: 10px; + color: #e51329; + line-height: 15px; +} + +.nav { + width: 100%; + height: 36px; + position: fixed; + top: 126px; + background: white; +} + +.nav_block { + width: 20%; + float: left; + font-size: 10.8px; + color: #909090; + text-align: center; + padding: 6px 0; + height: 36px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.nav .on { + color: #e51329; + border-bottom: 3px solid #e5122b; +} + +.ten{ + width: 100%; + background:#fff; + border-top: 1px solid #EFEFF4; +} + +.ten .on{ + color: #ff0962; +} + +.ten_t{ + width: 25%; + height:38.4px; + float: left; + text-align: center; + line-height: 38.4px; + color: #909090; + font-size: 12px; +} + +.title_img img{ + width: 100%; +} + + +.time_{ + text-align: center; + font-size: 12px; +} diff --git a/static/app2/css/activity8.css b/static/app2/css/activity8.css new file mode 100755 index 0000000..e3baf0d --- /dev/null +++ b/static/app2/css/activity8.css @@ -0,0 +1,36 @@ +body{ + background: #EBEBEB; +} + +.mui-scroll{ + padding: 8.7%; +} + +.rul_p{ + font-family: "微软雅黑"; + font-size: 16.8px; + text-align: center; + color: #000000; +} + +.rul_div{ + width: 100%; + margin-top: 21px; + background: #fff; +} + +.rul_div p{ + margin-left: 2%; + margin-right: 2%; +} + +.rul_div .rul_p1{ + font-family: "微软雅黑"; + font-size: 14.4px; + color: #ff3600; +} +.rul_div .rul_p2{ + font-family: "微软雅黑"; + font-size: 10.8px; + color: #0e0e0e; +} diff --git a/static/app2/css/activity9.css b/static/app2/css/activity9.css new file mode 100755 index 0000000..a11be2a --- /dev/null +++ b/static/app2/css/activity9.css @@ -0,0 +1,110 @@ +.header { + background: -moz-linear-gradient(left, #01deff, #1d7dff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#01deff), to(#1d7dff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #01deff, #1d7dff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #01deff, #1d7dff); + /*Opera11*/ + +} + +.header_con { + background: -moz-linear-gradient(left, #01deff, #1d7dff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#01deff), to(#1d7dff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #01deff, #1d7dff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #01deff, #1d7dff); + /*Opera11*/ + position: relative; +} + +.header_con .lxy_a { + color: #fff; +} + +.mj_lxy { + position: absolute; + width:4.5rem; + left: 0; + right: 0; + margin: 0 auto; + margin-top: .5rem; +} + + + +.t_con { + width: 100%; + background: -moz-linear-gradient(left, #01deff, #1d7dff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#01deff), to(#1d7dff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #01deff, #1d7dff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #01deff, #1d7dff); + /*Opera11*/ + padding-top: 15%; + position: relative; +} + +#keyword { + width: 85%; + height: 40px; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 0; + right: 0; + margin: 0 auto; + border-radius: 30px; + border: none; + background: #99dfff; + text-align: left; + text-indent: 5px; +} + +.con_{ + position: relative; +} + +.nav { + width: 100%; + background: -moz-linear-gradient(left, #01deff, #1d7dff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#01deff), to(#1d7dff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #01deff, #1d7dff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #01deff, #1d7dff); + /*Opera11*/ + padding-bottom: 3%; + padding-top: 10%; +} + + +.nav_block { + width: 50%; + float: left; + font-size: 12px; + text-align: center; + color: #fff; +} + +.nav_block_a{ + width: 16.6%; + float: left; + font-size: 12px; + text-align: center; + color: #fff; +} + +.on span { + font-size: 12px; + border-bottom: 4px solid #fef700; + padding-bottom: 4%; + color: #fff; +} \ No newline at end of file diff --git a/static/app2/css/addessay.css b/static/app2/css/addessay.css new file mode 100755 index 0000000..0828218 --- /dev/null +++ b/static/app2/css/addessay.css @@ -0,0 +1,65 @@ +.row { + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + font-size: 16px; + margin: 0px auto; + background: #fff; + padding: 5px 5px; +} +.row select { + padding: 0px 5px; + margin: 0px 0px; + height: 40px; + color: #363636 ; + font-size: 16px; + direction: rtl; +/* text-align: right; */ +} +.row select::placeholder { + text-align: right; + color: #ccc ; + +} +.row select option { + color: #363636 ; + text-align: right; +} +.row input { + padding: 0px 5px; + margin: 0px 0px; + color: #363636; + font-size: 16px; + text-align: right; + border: 0px; +} +.row_text{ + display: inline-block; + min-width: 100px; + font-size: 16px; + font-weight: 200; + color: #363636; + padding-left: 5px; +} +.down { + margin: 55px auto ; + +} +.down .btn { + margin: 0px auto ; + width: 200px; + height: 40px; + line-height: 40px; + text-align: center; + padding: 10px auto; + background: #DD524D; + font-size: 18px; + font-weight: 200; + color: #FDECEA; +} +/* 添加备忘录图片控制 */ +.row_bottom .btn { + margin: 5px 0px; +} + diff --git a/static/app2/css/addgoods.css b/static/app2/css/addgoods.css new file mode 100755 index 0000000..52ac319 --- /dev/null +++ b/static/app2/css/addgoods.css @@ -0,0 +1,291 @@ +.addcon_con { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto; + /* flex: 1; */ + +} +.addcon_con label { + width: 100px; + font-size: 16px; + color: #363636; + +} +.addcon_con input::-webkit-input-placeholder { + font-size: 13px; + text-align: right; +} +.addcon_con input,.addcon_con select { + /* width: 230px; */ + border: 0px; + margin: 0px; + padding: 0px; + height: 21px; + text-align: right; + overflow: hidden; + font-size: 16px; + /* flex: 0; */ +} +/* 申请商都商厦商超*/ +.addcon_con #shopId{ + width: 180px; + border: 0px; + margin: 0px; + padding: 0px; + height: 21px; + + } + + +.addcon .addcon_con .label-t { + font-size: 16px; + font-weight: 300; +} + +.renzhengphoto { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 7px; + flex: 1; + margin-bottom: 8px; +} + +.renzhengphoto label { + width: 100px; + font-size: 16px; + color: #363636; + align-self: flex-start; +} + +.photos { + display: flex; + flex-direction: column; + flex: 0 0 80%; + justify-content: space-between; + align-items: center; + padding: 0px 7px; + +} +.photos_con { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + align-content: flex-start; +} +.delete{ + height: 20px; + width: 20px; + position: absolute; + top:5px; + right: 5px; + z-index: 99; + color: #f00; + +/* filter:drop-shadow( -25px 0 red); + border-left: 20px solid transparent; */ +} +.delete img { + filter: opacity(100%); + +} +.photos_con .photo { + width: 100px; + height: 100px; + margin-left: 20px; + margin-bottom: 10px; + position: relative; + + +} + +.photos_con .photo img { + width: 100%; + height: 100%; +} + +.photos span { + display: inline-block; + font-size: 10px; + color: #959595; + +} +.addcon_con .defalut_type{ + /* flex: 1; */ + width: 100px; +} +.grounding { + display: flex; + justify-content: space-around; + align-items: center; +} + +.grounding .checkinp { + /* flex: 0 0 12%; */ + width: auto; + margin-right: 5px; +} + +.addcon_con .grounding label { + width: auto; + height: auto; +} +.addcon_con .radio{ + width: 20px; +} + + .renzhengphoto .photos span { + font-size: 12px; + height: 20px; +} +.ossfile { + display: inline-block; + width: 80px; + height: 80px; + background: #ccc; + border: 1px solid #ccc; + border-radius: 5px; + position: relative; +} + +.selectarea{ + width: 100%; + height: 100%; + display: flex; + justify-content: space-between; + align-items: center; +} + +.selectarea select{ + text-align: center; + height: 40px; + color: #7B7B7B; + width: 170px; + background: url(../img/sanjiaoxia.png) no-repeat right center; + background-size: 16px; + margin: 0px; + padding: 0px; + font-size: 16px; + text-align: right; +} +.pricset { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto; + flex: 1; + +} + +.pricset label { + color: #363636; + font-size: 13px; +} +.pricset_con .addcon_con label { + text-align: center; + font-size: 14px; + color: #363636; +} +.label-t{ + margin: 0 5px; + +} +.pricset_con input { + margin: 0 5px; + text-align: center; + flex: 0 0 33.3333%; + border: 1px solid #ccc; + height: 28px; + +} + +.pricset select { + margin: 0 5px; + width: auto; +} +.goodsDesc{ + width: 98%; + margin: 0 auto; + background: #fff; +} +.goodsDesc .w-e-toolbar{ + flex-wrap: wrap; +} +.pre{ + /* height: 100%; */ +} +.btn { + padding: 0 40px; + display: flex; + justify-content: space-around; + align-items: center; +} +.bc_btn { + height: 30px; + line-height: 30px; + text-align: center; + width: 70%; + margin: 20px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} +.prelook{ + margin-bottom: 0px; +} +/* 上传凭证 */ + .info{ + display: flex; + justify-content: space-between; + align-items: flex-start; + background: #fff; + height: 80px; + position: relative; + padding: 5px 7px; + width: 98%; + margin: 0 auto; + flex: 1; + + } + .info label { + width: 100px; + font-size: 16px; + color: #363636; + align-self: flex-start; + } + .info textarea::-webkit-input-placeholder { + font-size: 16px; + text-align: left; + } + .info textarea { + /* width: 230px; */ + border: 1px solid #ccc; + font-size: 16px; + margin: 0px; + padding: 0px; + height: 70px; + text-align: left; + } + /* 上传凭证结束 */ +.info #content{ + border: 1px solid #ccc; + + margin: 0px; + padding: 0px; + height: 70px; + text-align: left; +} + diff --git a/static/app2/css/addqrrz.css b/static/app2/css/addqrrz.css new file mode 100755 index 0000000..c80d0ee --- /dev/null +++ b/static/app2/css/addqrrz.css @@ -0,0 +1,439 @@ +.row { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto; + flex: 1; + +} +.row label { + min-width: 100px; + font-size: 17px; + color: #363636; +} + +.row input { + /* width: 230px; */ + font-size: 17px; + color: #363636; + border: 0px; + margin: 0px; + padding: 0px; + height: 21px; + text-align: right; +} +.row .selectarea{ + /* width: 60%; */ + height: 100%; + display: flex; + /* justify-content: space-between; */ + /* align-items: center; */ + flex-wrap: wrap; + align-content: flex-start; + flex: 0 0 78%; + +} + +.row .selectarea select{ + /* margin: 10px; */ + text-align: center; + margin-right: 5px; + width: 30%; + height: 40px; + color: #7B7B7B; + +} +.storepos{ + height: 200px; +} +.areainp .selectarea select{ + background-size: 16px; +} +.row .selectarea select option{ + text-align: center; + +} +.row input::-webkit-input-placeholder { + font-size: 17px; + text-align: right; +} + +.selectfile { + height: 100px; +} + +.row select { + width: 170px; + background: url(../img/sanjiaoxia.png) no-repeat right center; + background-size: 16px; + margin: 0px; + padding: 0px; + font-size: 16px; + text-align: right; + +} +.renzhengphoto { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 7px; + flex: 1; + margin-bottom: 8px; +} + +.renzhengphoto label { + width: 100px; + font-size: 16px; + color: #363636; + align-self: flex-start; +} + +.photos { + align-self: flex-start; + display: flex; + flex-direction: column; + flex: 0 0 80%; + justify-content: space-between; + align-items: center; + padding: 0px 7px; + +} +.photos_con { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + align-content: flex-start; +} + +/* +.photos_con .photo { + margin-left: 20px; + position: relative; +display: flex; +flex-direction: column; +justify-content: space-between; +align-items: center; + +} */ +.photos_con .photo { + display: flex; + flex-direction:column ; + justify-content: space-between; + align-items: center; + margin-left: 20px; + margin-bottom: 10px; + position: relative; + text-align: center; + +} +/* .photoimg{ + width: 100px; + height: 100px; +} */ +.photos_con .photo img { + width: 100px; + height: 100px; +} + +.photos span { + display: inline-block; + font-size: 15px; + color: #959595; + +} + .num .renzhengphoto{ + display: flex; + flex-direction: column; + justify-content:flex-start; + align-items: flex-start; + /* flex: 2.6; */ +} +.num .renzhengphoto .photos{ + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + margin-top: 10px; + width: 100%; + /* flex:0 0 100%; */ +} +.num .renzhengphoto label{ + font-size: 13px; + /* font-weight: 300; */ + width: 100%; + /* flex: 1; */ + } + .num .renzhengphoto .photos label{ + width: 80px; + height: 100%; + display: inline-block; + } + /* .renzhengphoto .photos{ + display: flex; + flex-direction: column; + justify-content: space-between!!important ; + align-items: flex-start; + flex: 2.6; +} */ +/* .renzhengphoto .photos span { + font-size: 12px; + height: 20px; */ + /* padding-left: 5px; */ +/* } +.renzhengphoto .photos .photos_con{ + display: flex; + justify-content: space-around; + align-items: center; */ + /* width:270px; */ + /* text-align: center; */ +/* } +.num .renzhengphoto .photos .photos_con .mui-icon{ + left: 45px; + font-size: 28px; +} +.renzhengphoto { + width: 98%; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 7px; + + +} + +.renzhengphoto label { + width: 100px; + font-size: 13px; + color: #363636; + align-self: flex-start; +} + .renzhengphoto .photos span { + font-size: 12px; + height: 20px; */ + /* padding-left: 5px; */ +/* } */ + +/* +.files_out { + text-align: center; + padding-top: 24px; +} */ +/* .photos span { + display: inline-block; + font-size: 10px; + color: #959595; + +} */ + +/* .photos .mui-icon { + font-size: 30px; + color: #fff; + position: absolute; + top: 25px; + left: 25px; +} + */ + + +/* .ossfile { + display: inline-block; + width: 80px; + height: 80px; + background: #ccc; + border: 1px solid #ccc; + border-radius: 5px; + position: relative; +} */ + +/* .photoimg { + width: 70%; + text-align: right; + /* overflow: hidden; */ +} */ + +.info { + position: relative; + /* display: inline-block; */ + width: 37%; + font-size: 12px; + bottom: 3px; + color: #aaa; +} + +/* .photoimg .mui-icon { + position: absolute; + top: 28px; + left: 30px; + color: #fff; +} */ + +#bankUserName { + position: absolute; + top: 15px; + right: 30px; + width: 200px; + /* background: #6600FF; */ + +} + +.mui-scroll .con .row .mui-table-view-cell-head { + width: 30%; + display: inline-block; +} + +.selectfile img { + width: 100%; + height: 100%; +} + +.thumbnail-img { + width: 100px; + height: 100px; + text-align: center; + background: #fff; + margin: 0 auto; +} + +.thumbnail-img .mui-icon { + width: 70px; + height: 70px; + font-size: 40px; + padding-top: 20px; +} + +.mui-table-view-cell-hkimg { + width: 50%; + /* background: pink; */ +} + +.hkimg { + width: 100%; + display: none; +} + +.userimg { + height: 100px; + +} + +.mui-btn-block { + width: 70%; + margin: 30px auto; + font-size: 18px; +} + +.YZTEL { + margin: 50px auto; + width: 80%; +} + +.YZTEL .mui-table-view-cell { + padding: 5px; +} + +.YZTEL label { + width: 25%; + font-size: 15px; +} + +.mui-table-view .mui-table-view-cell { + display: flex; + justify-content: space-between; + align-items: center; +} + +.mui-table-view .mui-table-view-cell #indiv-tel { + width: 80%; + text-align: left; + border: 0px; + padding: 0px; + margin: 0px; + font-size: 16px; +} + +.mui-table-view .mui-table-view-cell .YZM { + display: inline-block; + width: 40%; + border: 0px; + padding: 0px; + margin: 0px; + text-align: left; + +} + +.mui-table-view .mui-table-view-cell input::-webkit-input-placeholder { + font-size: 16px; + text-align: left; +} + +.mui-table-view .mui-table-view-cell .HQYZM { + width: 40%; + height: 30px; + font-size: 16px; + line-height: 30px; + padding: 0px; + margin: 0px; + text-align: center; + + +} + +.bc_btn { + height: 30px; + line-height: 30px; + + + text-align: center; + width: 70%; + margin: 30px auto; + + + color: #fff; + background: #FF1A03; + border-radius: 15px; +} + +.lxy_home_zz ul { + width: 83%; + margin: 0 auto; + position: relative; + top: 40%; + padding-top: 10px; + padding-bottom: 10px; + background: #fff; + border: 1px solid #fff; + border-radius: 5px; +} + +.lxy_zz input { + /* position: absolute; */ + width: 88%; + display: block; + /* top:50%; + left: 10%; */ + margin: 10px auto; + height: 35px; +} + +.lxy_zz_btn { + /* display: flex; */ + /* justify-content: space-between; */ + width: 40%; + margin: 15px auto; + text-align: center; + background: #FF0404; + color: #FFFFFF; + border: 1px solid #FF0404; + border-radius: 15px; + height: 30px; + line-height: 30px; +} diff --git a/static/app2/css/addshopping.css b/static/app2/css/addshopping.css new file mode 100755 index 0000000..d642a83 --- /dev/null +++ b/static/app2/css/addshopping.css @@ -0,0 +1,233 @@ +.addshopping-title { + height: 60px; + line-height: 60px; + width: 100%; + background: #000000; + text-align: center; + /* font-size: 18px; */ + display: flex; + justify-content: space-between; + align-items: center; +} + +.addshopping-title a { + display: inline-block; + width: 30px; + height: 30px; + background: #242424; + border-radius: 30px; + line-height: 30px; + color: #fff; + /* padding-top: 15px; */ + /* margin-top: 15px; */ +} + +.mui-action-back { + font-size: 26px; + height: 30px; + position: absolute; + /* top: 0px; */ + left: 15px; + z-index: 100; +} + +.addshopping-title h3 { + display: inline-block; + width: 80%; + text-align: center; + font-size: 20px; + color: #fff; + height: 60px; + line-height: 60px; + /* margin-top: -3px; */ +} + +.addcon-title { + + width: 100%; + height: 60px; + line-height: 60px; + background: #CCCCCC; + margin: 0 auto; + font-size: 14px; + +} + +.addcon_title { + width: 80%; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; +} + + +.num1{ + position: relative; + width: 20px; + height: 20px; + border: 1px solid #666; + border-radius: 20px; + background: #fff; + +} +.active { + background: #0062CC; +} +.num1 span { + position: absolute; + top: -20px; + left: 5px; +} + +.pre { + width: 96%; + margin: 0 auto; +} + +.pre-title h3 { + font-size: 15px; + +} + +.pre-con span { + width: 30%; + height: 15px; + font-size: 12px; + display: inline-block; + text-align: right; + +} + +.pre-con input { + width: 68%; + height: 15px; + font-size: 12px; + +} + +.shangjia { + display: flex; + justify-content: space-between; + align-content: center; + font-size: 12px; +} + +.shangjia span { + display: inline-block; + width: 30%; + text-align: right; + +} + +.shangjia label { + width: 60%; +} + +.thumbnail-title { + margin: 15px auto; +} + +.thumbnail-title span { + font-size: 14px; +} + +.thumbnail-img { + width: 100px; + height: 100px; + text-align: center; + background: #fff; + margin: 0 auto; +} + +.thumbnail-img .mui-icon { + width: 70px; + height: 70px; + font-size: 40px; + padding-top: 20px; +} + +.shopadds-title { + margin: 15px auto; +} + +.shopadds-img { + width: 300px; + height: 200px; + overflow: hidden; + background: #fff; + margin: 0 auto; + margin-bottom: 10px; +} + +.pre-con2 form {} + +.pre-con2 form span { + display: inline-block; + width: 35%; + text-align: right; + font-size: 14px; + height: 25px; + line-height: 25px; +} + +.pre-con2 select { + width: 55%; + border: 0px; + padding: 2px; + font-size: 14px; + height: 25px; + line-height: 25px; + + + +} + +.pre-con2 table th { + width: 30%; + +} + +.pre-con2 table tr { + text-align: center; + +} + +.pre-con2 table .table-tr { + border-bottom: 1px solid #000; + +} + +.pre-con2 table tr td { + height: 45px; + line-height: 45px; + font-size: 13px; + + +} + +.pre-con2 table tr td input { + height: 25px; + margin: 0px; + padding: 1px 2px; + width: 80%; + line-height: 25px; + +} + +.nextbtn { + text-align: center; + margin: 10px auto; +} +.yulanbtn{ + text-align: center; + margin: 10px auto; + +} +.btn{ + display: flex; + justify-content: space-between; + width: 50%; + margin: 10px auto; +} + diff --git a/static/app2/css/addyhk.css b/static/app2/css/addyhk.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/applicationopen.css b/static/app2/css/applicationopen.css new file mode 100755 index 0000000..c8265c6 --- /dev/null +++ b/static/app2/css/applicationopen.css @@ -0,0 +1,162 @@ +.con-nav { + /* width: 100%; */ + height: 40px; +} + +.con-nav ul { + width: 100%; + height: 100%; + list-style: none; + /* padding: 0px; */ + margin: 10px 2px; + /* display: flex; + justify-content: space-between; + align-items: center; */ + padding: 5px 1px; + /* overflow-x: scroll; */ +} + +.con-nav ul li { + padding: 0px 20px; + line-height: 40px; + background: #999999; + display: inline-block; + color: #fff; + float: left; + margin: 0px -16px 0px 0px; + position: relative; + font-size: 14px; + /* text-align: center; */ + width: 28%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + +} + +.con-nav ul li:after { + content: ''; + width: 0px; + height: 0px; + display: block; + border: 20px solid transparent; + /* border-bottom: 20px solid transparent; */ + border-left: 20px solid #999999; + position: absolute; + right: -21px; + top: 0; + z-index: 10; +} + +.con-nav ul li:before { + content: ''; + display: block; + border: 20px solid transparent; + width: 0px; + height: 0px; + /* border-top: 20px solid transparent; + border-bottom: 20px solid transparent; */ + border-left: 20px solid #fff; + position: absolute; + left: 0px; + top: 0; + right: -20px; + +} + +.con-nav ul li:first-child { + border-radius: 4px 0 0 4px; + padding-left: 10px; +} + +.con-nav ul li:last-child, +.cssNavEnd { + border-radius: 0px 4px 4px 0px; + padding-right: 10px; +} + +.con-nav ul li:first-child:before { + display: none; +} + +.con-nav ul li:last-child:after, +.cssNavEnd:after { + display: none; +} + +.con-nav ul li.active { + background-color: #ef72b6; + /* width: 120px; */ +} + +.con-nav ul li.active:after { + border-left-color: #ef72b6; +} + +.con-content { + margin-top: 20px; +} + +.storepos label { + align-items: flex-start; +} + +.num .areainp { + height: 80px; +} + +#allmap { + flex: 0 0 80%; + height: 200px; + /* z-index: 0; */ +} + +.num .renzhengphoto .photos .photo { + width: 100px; +} + +.num .renzhengphoto .photos .photo img { + width: 100%; + +} + +.confirmationtext { + /* height: 200px; */ + width: 98%; + margin: 0 auto; + /* overflow: hidden; */ +} + +.confirmationtext .confirmationtext_con { + height: 200px; + width: 98%; + margin: 0 auto; + padding: 10px 4px; + overflow-y: scroll; +} + +.oper { + display: flex; + width: 100%; + justify-content: center; + align-items: center; +} + +.oper .next { + width: 50%; +} + +.pre { + width: 50%; +} + +.pre_btn { + height: 30px; + line-height: 30px; + text-align: center; + width: 70%; + margin: 30px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} diff --git a/static/app2/css/appraise.css b/static/app2/css/appraise.css new file mode 100755 index 0000000..090ed27 --- /dev/null +++ b/static/app2/css/appraise.css @@ -0,0 +1,145 @@ +* { + margin: 0; + padding: 0; +} +body{ + /*background: white;*/ +} +.clearfix::before, +.clearfix::after { + display: block; + content: ''; + visibility: hidden; + height: 100%; + clear: both; +} + +body { + padding-top: 2%; +} +.gallety{ + width: 100%; + overflow: hidden; + height: 80px; +} +.my-gallery { + width: 200%; + margin: 0 auto; + overflow: hidden; +} + +.my-gallery .img-dv { + width: 78px; + height: 78px; + margin-bottom: 1%; +} + +.my-gallery .img-dv a { + display: block; + width: 100%; + height: 100%; + text-align: center +} + +.my-gallery .img-dv a img { + width: 100%; + height: 100%; + /*vertical-align: middle;*/ +} + +figure { + float: left; + margin: 0; + margin-right: 5px; +} + +.con{ + /*margin-top: 66px;*/ +} + +.con_{ + background: white ; +} +.nav { + font-size: 12px; + margin-bottom: 8px; +} +.nav div{ + float: left; + width: 30%; + height: 30px; + text-align: center; + line-height: 30px; + margin-left: 2.5%; + background: #fdecea; + border-radius: 15px; + color: #525252; +} +.nav .on{ + background: #E6122B; + color: white; +} + + +.pj_breviary { + padding: 12px; + border-bottom: 1px solid #e6e6e6; +} + +.pjbtitle p { + color: #e61329; + font-size: 13.2px; + float: left; + margin: 0; + line-height: 25.2px; + padding-left: 6px; +} + +.pjbcon { + color: #525252; + font-size: 13.2px; + margin: 3px 0; +} + +.pjclass { + color: #909090; + font-size: 13.2px; +} +.pjbtitle img { + width: 25.2px; + height: 25.2px; + border-radius: 50%; + overflow: hidden; + float: left; + +} +.pj_title { + color: black; + padding: 9px 12px; + margin: 0; +} +.pjzhuijia{ + padding: 9px 6px; + background: #e4e4e4; + border-radius: 4.8px; + font-size: 12px; + margin-top: 4px; +} +.zjpj{ + position: relative; + padding-top: 0.1px; +} +.sanjiao{ + position: absolute; + width: 9px; + height: 9px; + transform: rotate(45deg); + background: #e4e4e4; + left: 32px; +} +.pswp__top-bar{ + margin-top: 20px; +} +.nav_{ + margin-top: 5px; +} diff --git a/static/app2/css/bill.css b/static/app2/css/bill.css new file mode 100755 index 0000000..23c5b98 --- /dev/null +++ b/static/app2/css/bill.css @@ -0,0 +1,42 @@ +.con { + padding-top: 10px; +} +.row{ + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 10px; + font-size: 12px; + color: #909090; + /* height: 40px; */ + background: #fff; +} +.row .left{ + width: 30px; + height: 30px; + +} +.row .left img { + width: 100%; + height: 100%; +} +.row .num { + width: 100px; + flex: 1; + text-align: center; + font-size: 15px; +} +.row .context{ + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: space-between; + text-align: left; + flex: 2; + margin-left: 20px; +} +.row .context .con_text{ + font-size: 14px +} +. \ No newline at end of file diff --git a/static/app2/css/cash-out.css b/static/app2/css/cash-out.css new file mode 100755 index 0000000..c0a023d --- /dev/null +++ b/static/app2/css/cash-out.css @@ -0,0 +1,191 @@ +.idc-total { + width: 96%; + margin: 0 auto 8px; + height: 60px; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding-left: 5px; + + /* border-bottom: 1px solid #ccc; */ +} + +.idc-total h5 { + width: 80%; +} + +.idc-total input { + font-size: 18px; + margin-right: 10px; + text-align: right; + width: 40%; + border: 0px; +} + +.btns { + display: flex; + justify-content: space-between; + align-items: center; +} +.bg .btns div { + height: 30px; + line-height: 30px; + text-align: center; + width: 40%; + margin: 5px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} +.tx-title { + width: 100%; + height: 49px; + border-bottom: 1px solid #e6e6e6; + position: relative; +} + +.tx-title a { + position: absolute; + z-index: 10; + font-size: 30px; + color: #909090; + line-height: 50px; + left: 5px; + top:0px; +} + +.tx-title p { + line-height: 48px; + text-align: center; + color: black; + font-size: 15.6px; +} +.btns div { + height: 30px; + line-height: 30px; + text-align: center; + width: 40%; + margin: 30px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} +.footer{ + position: fixed; + left: 0; + /* top: 0; */ + bottom: 0; + right: 0; + z-index: 10; + height: 40px; +} +.bg { + background: rgba(1, 1, 1, 0.1); + position: fixed; + left: 0; + /* top: 0; */ + bottom: 0px; + right: 0; + z-index: 10; +} +.bg .row{ + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto; + flex: 1; +} +.bg .row label { + width: 100px; + font-size: 13px; + color: #363636; + +} +.mui-popup-input input{ + border: 0px; + } +.bg .row select{ + /* margin: 10px; */ + /* text-align: right; */ + margin-bottom: 0px; + margin-right: 5px; + /* width: 30%; */ + height: 40px; + color: #7B7B7B; + padding: 0px; +} +.bg .row input { + /* width: 230px; */ + border: 0px; + margin: 0px; + padding: 0px; + height: 21px; + text-align: left; + font-size: 13px; + color:#7B7B7B; +} +.idc-list { + width: 96%; + height: 120px; + background: #FEEAE9; + margin: 0 auto; + /* background: #fff; */ + display: flex; + flex: 1; + align-items: flex-start; + justify-content: space-between; + /* border-bottom: 1px solid #ccc; */ + border: 1px solid #FEEAE9; + border-radius: 5px; + margin-bottom: 8px; + padding-left: 5px; +} + +.idc-list-price { + /* flex: 0 0 30%; */ + +} + +.idc-list-right { + /* flex: 0 0 70%; */ + flex-direction: column; + justify-content: space-around; + align-items: flex-start; + padding-left: 30px; + position: relative; +} + +.idc-list-title { + width: 200px; + font-size: 15px; + font-weight: 200; + margin-bottom: 10px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.idc-list-price { + font-size: 15px; + color: #F02C43; +} + +.idc-list-user { + + font-size: 13px; + margin-bottom: 15px; + +} + +.idc-list-time { + width: 50%; + font-size: 12px; + /* color: #F02C43; */ + bottom: 10px; +} diff --git a/static/app2/css/classify.css b/static/app2/css/classify.css new file mode 100755 index 0000000..0910ea0 --- /dev/null +++ b/static/app2/css/classify.css @@ -0,0 +1,66 @@ +.con_left{ + position: fixed; + left: 0; + bottom: 0; + top: 66px; + right: 75%; + width: 25%; + background: #f9f9f8; +} + + +.left_row{ + width: 100%; + min-height: 45px; + padding: 15px 0; + /*line-height: 54px;*/ + border-bottom: 1px solid #e6e6e6; + background: #f9f9f8; + text-align: center; + font-size: 14.4px; +} + +.con_left .on{ + background: white; + border-left: 3px solid #f5394e; +} + +.con_right{ + position: fixed; + left: 25%; + bottom: 0; + top: 66px; + right: 0; + background: white; + width: 75%; +} + + +.rb_title{ + width: 100%; + text-align: center; + font-size: 14.4px; + height: 50px; + line-height: 50px; +} +.rb_block{ + width: 33.3%; + padding: 5%; + float: left; +} +.rb_block img{ + width: 100%; +} +.rb_block p{ + text-align: center; + font-size: 14.4px; +} +.oc_logo{ + width: 67.5px; + height: 16.5px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 13.75px; +} \ No newline at end of file diff --git a/static/app2/css/collect.css b/static/app2/css/collect.css new file mode 100755 index 0000000..cb259ae --- /dev/null +++ b/static/app2/css/collect.css @@ -0,0 +1,41 @@ + +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + /*height: 66px;*/ +} +.p1{ + color: #909090; + float: left; + height: 45px; + line-height: 46px; + width: 26.41px; + margin-left: calc(35% - 20px ); + font-size: 13.2px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} \ No newline at end of file diff --git a/static/app2/css/collect_commodity.css b/static/app2/css/collect_commodity.css new file mode 100755 index 0000000..c68992c --- /dev/null +++ b/static/app2/css/collect_commodity.css @@ -0,0 +1,39 @@ +.con{ +} +.row{ + width: 100%; + height: 127px; + background: white; +} +.row img{ + float: left; + width: 126px; + height: 127px; + border-bottom: 1px solid #fff; + +} +.row .row_r{ + width: calc(100% - 130px); + height: 127px; + border-bottom: 1px solid #e6e6e6; + float: right; + position: relative; +} +.row_r p{ + font-size: 12px; + color: black; + padding-top: 9px; + padding-left: 6px; + padding-right: 6px; +} +.row_r .cost{ + position: absolute; + color: #e5142a; + font-size: 13.2px; + bottom: 6px; +} +.qxsc{ + position: absolute;bottom: 6px; + right: 6px; + padding: 3px 6px; +} diff --git a/static/app2/css/collect_store.css b/static/app2/css/collect_store.css new file mode 100755 index 0000000..257de32 --- /dev/null +++ b/static/app2/css/collect_store.css @@ -0,0 +1,132 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .row_con .swiper-container { + height: 125px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 99px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .row_con .swiper-container { + height: 115px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 89px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .row_con .swiper-container { + height: 101px; + width: 100%; + margin-left: 12px; + } + .row_con .swiper-slide img { + width: 100%; + height: 75.5px; + } +} + +.row { + border-bottom: 1px solid #e6e6e6; +} + +.row_title { + width: 100%; + height: 85.2px; + background: white; + position: relative; +} + +.row_title .img { + position: absolute; + width: 45px; + height: 45px; + top: 21px; + left: 14.4px; +} + +.row_title .s_t { + font-size: 13.2px; + color: black; + width: calc(100% - 200px); + position: absolute; + left: 72px; + line-height: 85.2px; + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.row_title .num { + position: absolute; + text-align: center; + width: 48px; + color: #909090; + font-size: 21.6px; + margin: 0; + right: 36px; + top: 24px; +} + +.row_title .p1 { + position: absolute; + text-align: center; + width: 48px; + color: #909090; + font-size: 13.2px; + margin: 0; + right: 36px; + top: 45px; +} + +.row_title .img_btn { + position: absolute; + width: 36.8px; + height: 30.2px; + top: 29px; + right: 8px; + padding: 10px; +} + +.swiper-container { + margin-top: 12px; + margin-bottom: 12px; +} + +.swiper-slide { + text-align: center; + background: white; +} + +.swiper-slide p { + font-size: 13.2px; + color: #E61329; +} + +.row_con { + overflow: hidden; +} + +.qxsc { + position: absolute; + right: 15px; + padding: 3px 6px; + top: 30px; +} \ No newline at end of file diff --git a/static/app2/css/complain.css b/static/app2/css/complain.css new file mode 100755 index 0000000..4f98e4a --- /dev/null +++ b/static/app2/css/complain.css @@ -0,0 +1,20 @@ +.con { + background: white; + padding: 10px 5%; +} + +select { + padding-left: 0; +} + +button { + width: 90%; + background: #f02c43; + margin: 10px 5%; + text-align: center; + font-family: "微软雅黑"; + font-size: 15.6px; + color: #fff; + border: none; + height: 40px; +} \ No newline at end of file diff --git a/static/app2/css/confirmOrder.css b/static/app2/css/confirmOrder.css new file mode 100755 index 0000000..7e55edc --- /dev/null +++ b/static/app2/css/confirmOrder.css @@ -0,0 +1,151 @@ +.scroll_out{ + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + + +.c1_r input{ + margin: 0; + border: none; + padding: 0; + height: 22px; + width: calc( 100% ); + font-size: 12px; +} +.c1_r{ + width: calc(100% - 80px); + text-align: right; +} + +.c1_l input::-webkit-input-placeholder { /* WebKit browsers */ +font-size:12px; +} +.c1_l input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ +font-size:12px; +} +.c1_l input::-moz-placeholder { /* Mozilla Firefox 19+ */ +font-size:12px; +} +.c1_l input:-ms-input-placeholder { /* Internet Explorer 10+ */ +font-size:12px; +} + + +.js_r{ + float: right; + line-height: 50px; +} +.js_r span{ + font-size: 12px; +} +.js_r span j{ + color: #e94744; +} +.js_r span o{ + color: #909090; +} +.btn_tj{ + display: inline-block; + width: 102px; + height: 51px; + background: -moz-linear-gradient(left, #ff0423, #ff58a3); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#ff0423), to(#ff58a3)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #ff0423, #ff58a3); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #ff0423, #ff58a3); + /*Opera11*/ + text-align: center; + color: white; + font-size: 14.4px; +} + +.isHb{ + width: 100%; + height: 42px; + border-bottom: 1px solid #e6e6e6; + background: white; + line-height: 41px; + padding:0 10px; +} +.h_left{ + font-size: 12px; + float: left; +} +.h_left o{ + color: #909090; +} +.he_right{ + float: right; + height: 41px; + width: 80px; + position: relative; +} +.checkout{ + width: 42px; + height: 25px; + border-radius: 15px; + /*background: #2ddd87;*/ + position: absolute; + right: 0; + top: 7px; + border:1px solid #909090; +} +.check_btn{ + position: absolute; + width: 21px; + height: 21px; + background: white; + border-radius: 50%; + top: 1px; + left: 1px; + border:1px solid #909090; +} +.he_right .on{ + top: 8px; + border: none; + height: 23px; + background: #2ddd87; +} + +.he_right .on .check_btn{ + border: none; + left: 20px; +} +select{ + margin: 0; + padding: 0 ; + font-size: 13.2px; +} +.mui-table-view-cell:after{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content{ + width: 100%; + background: transparent; +} +.row_{ + width: 100%; + font-size: 13.2px; + border-bottom: 1px solid #ebebeb; +} + +.shop_info{ + background: white; + border-bottom: none; + margin-bottom: 5px; +} +.row_block{ + background: white; +} +.row_block img{ + border-radius: 3px; + overflow: hidden; +} +.rcr { + background: white; +} diff --git a/static/app2/css/cooperative.css b/static/app2/css/cooperative.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/default-skin/default-skin.css b/static/app2/css/default-skin/default-skin.css new file mode 100755 index 0000000..74d3914 --- /dev/null +++ b/static/app2/css/default-skin/default-skin.css @@ -0,0 +1,482 @@ +/*! PhotoSwipe Default UI CSS by Dmitry Semenov | photoswipe.com | MIT license */ +/* + + Contents: + + 1. Buttons + 2. Share modal and links + 3. Index indicator ("1 of X" counter) + 4. Caption + 5. Loading indicator + 6. Additional styles (root element, top bar, idle state, hidden state, etc.) + +*/ +/* + + 1. Buttons + + */ +/* <button> css reset */ +.pswp__button { + width: 44px; + height: 44px; + position: relative; + background: none; + cursor: pointer; + overflow: visible; + -webkit-appearance: none; + display: block; + border: 0; + padding: 0; + margin: 0; + float: right; + opacity: 0.75; + -webkit-transition: opacity 0.2s; + transition: opacity 0.2s; + -webkit-box-shadow: none; + box-shadow: none; } + .pswp__button:focus, .pswp__button:hover { + opacity: 1; } + .pswp__button:active { + outline: none; + opacity: 0.9; } + .pswp__button::-moz-focus-inner { + padding: 0; + border: 0; } + +/* pswp__ui--over-close class it added when mouse is over element that should close gallery */ +.pswp__ui--over-close .pswp__button--close { + opacity: 1; } + +.pswp__button, +.pswp__button--arrow--left:before, +.pswp__button--arrow--right:before { + background: url(default-skin.png) 0 0 no-repeat; + background-size: 264px 88px; + width: 44px; + height: 44px; } + +@media (-webkit-min-device-pixel-ratio: 1.1), (-webkit-min-device-pixel-ratio: 1.09375), (min-resolution: 105dpi), (min-resolution: 1.1dppx) { + /* Serve SVG sprite if browser supports SVG and resolution is more than 105dpi */ + .pswp--svg .pswp__button, + .pswp--svg .pswp__button--arrow--left:before, + .pswp--svg .pswp__button--arrow--right:before { + background-image: url(default-skin.svg); } + .pswp--svg .pswp__button--arrow--left, + .pswp--svg .pswp__button--arrow--right { + background: none; } } + +.pswp__button--close { + background-position: 0 -44px; } + +.pswp__button--share { + background-position: -44px -44px; } + +.pswp__button--fs { + display: none; } + +.pswp--supports-fs .pswp__button--fs { + display: block; } + +.pswp--fs .pswp__button--fs { + background-position: -44px 0; } + +.pswp__button--zoom { + display: none; + background-position: -88px 0; } + +.pswp--zoom-allowed .pswp__button--zoom { + display: block; } + +.pswp--zoomed-in .pswp__button--zoom { + background-position: -132px 0; } + +/* no arrows on touch screens */ +.pswp--touch .pswp__button--arrow--left, +.pswp--touch .pswp__button--arrow--right { + visibility: hidden; } + +/* + Arrow buttons hit area + (icon is added to :before pseudo-element) +*/ +.pswp__button--arrow--left, +.pswp__button--arrow--right { + background: none; + top: 50%; + margin-top: -50px; + width: 70px; + height: 100px; + position: absolute; } + +.pswp__button--arrow--left { + left: 0; } + +.pswp__button--arrow--right { + right: 0; } + +.pswp__button--arrow--left:before, +.pswp__button--arrow--right:before { + content: ''; + top: 35px; + background-color: rgba(0, 0, 0, 0.3); + height: 30px; + width: 32px; + position: absolute; } + +.pswp__button--arrow--left:before { + left: 6px; + background-position: -138px -44px; } + +.pswp__button--arrow--right:before { + right: 6px; + background-position: -94px -44px; } + +/* + + 2. Share modal/popup and links + + */ +.pswp__counter, +.pswp__share-modal { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +.pswp__share-modal { + display: block; + background: rgba(0, 0, 0, 0.5); + width: 100%; + height: 100%; + top: 0; + left: 0; + padding: 10px; + position: absolute; + z-index: 1600; + opacity: 0; + -webkit-transition: opacity 0.25s ease-out; + transition: opacity 0.25s ease-out; + -webkit-backface-visibility: hidden; + will-change: opacity; } + +.pswp__share-modal--hidden { + display: none; } + +.pswp__share-tooltip { + z-index: 1620; + position: absolute; + background: #FFF; + top: 56px; + border-radius: 2px; + display: block; + width: auto; + right: 44px; + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); + -webkit-transform: translateY(6px); + -ms-transform: translateY(6px); + transform: translateY(6px); + -webkit-transition: -webkit-transform 0.25s; + transition: transform 0.25s; + -webkit-backface-visibility: hidden; + will-change: transform; } + .pswp__share-tooltip a { + display: block; + padding: 8px 12px; + color: #000; + text-decoration: none; + font-size: 14px; + line-height: 18px; } + .pswp__share-tooltip a:hover { + text-decoration: none; + color: #000; } + .pswp__share-tooltip a:first-child { + /* round corners on the first/last list item */ + border-radius: 2px 2px 0 0; } + .pswp__share-tooltip a:last-child { + border-radius: 0 0 2px 2px; } + +.pswp__share-modal--fade-in { + opacity: 1; } + .pswp__share-modal--fade-in .pswp__share-tooltip { + -webkit-transform: translateY(0); + -ms-transform: translateY(0); + transform: translateY(0); } + +/* increase size of share links on touch devices */ +.pswp--touch .pswp__share-tooltip a { + padding: 16px 12px; } + +a.pswp__share--facebook:before { + content: ''; + display: block; + width: 0; + height: 0; + position: absolute; + top: -12px; + right: 15px; + border: 6px solid transparent; + border-bottom-color: #FFF; + -webkit-pointer-events: none; + -moz-pointer-events: none; + pointer-events: none; } + +a.pswp__share--facebook:hover { + background: #3E5C9A; + color: #FFF; } + a.pswp__share--facebook:hover:before { + border-bottom-color: #3E5C9A; } + +a.pswp__share--twitter:hover { + background: #55ACEE; + color: #FFF; } + +a.pswp__share--pinterest:hover { + background: #CCC; + color: #CE272D; } + +a.pswp__share--download:hover { + background: #DDD; } + +/* + + 3. Index indicator ("1 of X" counter) + + */ +.pswp__counter { + position: absolute; + left: 0; + top: 0; + height: 44px; + font-size: 13px; + line-height: 44px; + color: #FFF; + opacity: 0.75; + padding: 0 10px; } + +/* + + 4. Caption + + */ +.pswp__caption { + position: absolute; + left: 0; + bottom: 0; + width: 100%; + min-height: 44px; } + .pswp__caption small { + font-size: 11px; + color: #BBB; } + +.pswp__caption__center { + text-align: left; + max-width: 420px; + margin: 0 auto; + font-size: 13px; + padding: 10px; + line-height: 20px; + color: #CCC; } + +.pswp__caption--empty { + display: none; } + +/* Fake caption element, used to calculate height of next/prev image */ +.pswp__caption--fake { + visibility: hidden; } + +/* + + 5. Loading indicator (preloader) + + You can play with it here - http://codepen.io/dimsemenov/pen/yyBWoR + + */ +.pswp__preloader { + width: 44px; + height: 44px; + position: absolute; + top: 0; + left: 50%; + margin-left: -22px; + opacity: 0; + -webkit-transition: opacity 0.25s ease-out; + transition: opacity 0.25s ease-out; + will-change: opacity; + direction: ltr; } + +.pswp__preloader__icn { + width: 20px; + height: 20px; + margin: 12px; } + +.pswp__preloader--active { + opacity: 1; } + .pswp__preloader--active .pswp__preloader__icn { + /* We use .gif in browsers that don't support CSS animation */ + background: url(preloader.gif) 0 0 no-repeat; } + +.pswp--css_animation .pswp__preloader--active { + opacity: 1; } + .pswp--css_animation .pswp__preloader--active .pswp__preloader__icn { + -webkit-animation: clockwise 500ms linear infinite; + animation: clockwise 500ms linear infinite; } + .pswp--css_animation .pswp__preloader--active .pswp__preloader__donut { + -webkit-animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; + animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; } + +.pswp--css_animation .pswp__preloader__icn { + background: none; + opacity: 0.75; + width: 14px; + height: 14px; + position: absolute; + left: 15px; + top: 15px; + margin: 0; } + +.pswp--css_animation .pswp__preloader__cut { + /* + The idea of animating inner circle is based on Polymer ("material") loading indicator + by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html + */ + position: relative; + width: 7px; + height: 14px; + overflow: hidden; } + +.pswp--css_animation .pswp__preloader__donut { + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 14px; + height: 14px; + border: 2px solid #FFF; + border-radius: 50%; + border-left-color: transparent; + border-bottom-color: transparent; + position: absolute; + top: 0; + left: 0; + background: none; + margin: 0; } + +@media screen and (max-width: 1024px) { + .pswp__preloader { + position: relative; + left: auto; + top: auto; + margin: 0; + float: right; } } + +@-webkit-keyframes clockwise { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@keyframes clockwise { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); } } + +@-webkit-keyframes donut-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); } + 50% { + -webkit-transform: rotate(-140deg); + transform: rotate(-140deg); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +@keyframes donut-rotate { + 0% { + -webkit-transform: rotate(0); + transform: rotate(0); } + 50% { + -webkit-transform: rotate(-140deg); + transform: rotate(-140deg); } + 100% { + -webkit-transform: rotate(0); + transform: rotate(0); } } + +/* + + 6. Additional styles + + */ +/* root element of UI */ +.pswp__ui { + -webkit-font-smoothing: auto; + visibility: visible; + opacity: 1; + z-index: 1550; } + +/* top black bar with buttons and "1 of X" indicator */ +.pswp__top-bar { + position: absolute; + left: 0; + top: 0; + height: 44px; + width: 100%; } + +.pswp__caption, +.pswp__top-bar, +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + -webkit-backface-visibility: hidden; + will-change: opacity; + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +/* pswp--has_mouse class is added only when two subsequent mousemove events occur */ +.pswp--has_mouse .pswp__button--arrow--left, +.pswp--has_mouse .pswp__button--arrow--right { + visibility: visible; } + +.pswp__top-bar, +.pswp__caption { + background-color: rgba(0, 0, 0, 0.5); } + +/* pswp__ui--fit class is added when main image "fits" between top bar and bottom bar (caption) */ +.pswp__ui--fit .pswp__top-bar, +.pswp__ui--fit .pswp__caption { + background-color: rgba(0, 0, 0, 0.3); } + +/* pswp__ui--idle class is added when mouse isn't moving for several seconds (JS option timeToIdle) */ +.pswp__ui--idle .pswp__top-bar { + opacity: 0; } + +.pswp__ui--idle .pswp__button--arrow--left, +.pswp__ui--idle .pswp__button--arrow--right { + opacity: 0; } + +/* + pswp__ui--hidden class is added when controls are hidden + e.g. when user taps to toggle visibility of controls +*/ +.pswp__ui--hidden .pswp__top-bar, +.pswp__ui--hidden .pswp__caption, +.pswp__ui--hidden .pswp__button--arrow--left, +.pswp__ui--hidden .pswp__button--arrow--right { + /* Force paint & create composition layer for controls. */ + opacity: 0.001; } + +/* pswp__ui--one-slide class is added when there is just one item in gallery */ +.pswp__ui--one-slide .pswp__button--arrow--left, +.pswp__ui--one-slide .pswp__button--arrow--right, +.pswp__ui--one-slide .pswp__counter { + display: none; } + +.pswp__element--disabled { + display: none !important; } + +.pswp--minimal--dark .pswp__top-bar { + background: none; } diff --git a/static/app2/css/default-skin/default-skin.png b/static/app2/css/default-skin/default-skin.png new file mode 100755 index 0000000..441c502 Binary files /dev/null and b/static/app2/css/default-skin/default-skin.png differ diff --git a/static/app2/css/default-skin/default-skin.svg b/static/app2/css/default-skin/default-skin.svg new file mode 100755 index 0000000..9d5f0c6 --- /dev/null +++ b/static/app2/css/default-skin/default-skin.svg @@ -0,0 +1 @@ +<svg width="264" height="88" viewBox="0 0 264 88" xmlns="http://www.w3.org/2000/svg"><title>default-skin 2</title><g fill="none" fill-rule="evenodd"><g><path d="M67.002 59.5v3.768c-6.307.84-9.184 5.75-10.002 9.732 2.22-2.83 5.564-5.098 10.002-5.098V71.5L73 65.585 67.002 59.5z" id="Shape" fill="#fff"/><g fill="#fff"><path d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z" id="Shape"/></g><g fill="#fff"><path d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"/></g><path d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z" fill="#fff"/><path d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z" fill="#fff"/><path d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z" fill="#fff"/><g><path id="Rectangle-11" fill="#fff" d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z"/><path d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" id="Oval-1" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M150 21h5v1h-5z"/></g><g><path d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z" fill="#fff"/><path d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M106 21h5v1h-5z"/><path fill="#fff" d="M109.043 19.008l-.085 5-1-.017.085-5z"/></g></g></g></svg> \ No newline at end of file diff --git a/static/app2/css/default-skin/preloader.gif b/static/app2/css/default-skin/preloader.gif new file mode 100755 index 0000000..b8faa69 Binary files /dev/null and b/static/app2/css/default-skin/preloader.gif differ diff --git a/static/app2/css/details.css b/static/app2/css/details.css new file mode 100755 index 0000000..c50b0b8 --- /dev/null +++ b/static/app2/css/details.css @@ -0,0 +1,916 @@ +body { + background: #f4f2f2; +} + +.header { + width: 100%; + position: fixed; + top: 0; + z-index: 10; + background: transparent; + border: none; + box-shadow: 0 0 0; + height: 66px; +} + +body .header1 { + z-index: 11; + opacity: 0; + width: 100%; + position: fixed; + top: 0; + background: rgba(255, 255, 255, 1); + border: none; + box-shadow: 0 0 0; + height: 66px; + display: none; + border-bottom: 1px solid #efefef; +} + +.mui-bar-nav.mui-bar .mui-icon { + /*margin-left: 0;*/ +} + +.mui-title { + color: black; +} + +.zhe { + opacity: 0; +} +.icon-cart{ + margin-top:.35rem; + margin-right:.5rem; + float: right; +} +.header .mui-action-back { + margin-top: 10px; + margin-left: 10px; + border-radius: 50%; + background: rgba(0, 0, 0, 0.2); + color: white; +} + +.header1 .mui-action-back { + /*margin-top: 20px;*/ + color: black; + float: left; +} + +.mui-bar-nav { + box-shadow: none; + background: rgba(0, 0, 0, 0) +} + +.header1 .on { + border-bottom: 3px solid #ff0000; + color: #e61329; +} + +.p1 { + float: left; + height: 45px; + line-height: 46px; + width: 26.41px; + margin-left: calc(25% - 35px); + font-size: 13.2px; +} + +.back { + position: absolute; + left: 15px; + top: 25px; +} + +.back img, +.like img, +.menu img { + width: 37.2px; + height: 37.2px; +} + +.like { + position: absolute; + left: 279px; + top: 15px; +} + +.menu { + position: absolute; + right: 15px; + top: 25px; +} + +.banner { + width: 100%; + height: 387px; + position: relative; + z-index: 1; +} + +.swiper-container { + width: 100%; + /*height: 387px;*/ + box-shadow: 0 -1px 3px #ddd; +} + +.swiper-slide { + text-align: center; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +.swiper-pagination-bullet-active { + background: #e94947; +} + +.swiper-slide {} + +.swiper-slide img { + width: 100%; + height: 100%; +} + +.summarize { + background: white; + width: 100%; + margin-bottom: 5px ; +} + +.cname { + font-size: 14.4px; + padding:0 10px 5px; + margin: 0; +} + +.price { + color: #F02A40; + font-size: 21.6px; + margin: 0; + padding:5px 10px; + +} +.summarize .xxl{ + color: white; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ +} + +.price o{ + font-size: 15px; + color: #909090; +} +.summarize .xxl o{ + font-size: 15px; + color: white; +} +.price_old { + color: #909090; + font-size: 15px; + /*padding-left: 9px;*/ + /*padding-bottom: 9px;*/ + margin: 0; + padding: 5px 10px 0; +} + +.compilations { + position: relative; + width: 100%; + height: 30px; + line-height: 24px; + font-size: 10.8px; + color: #727272; +} + +.myf { + position: absolute; + left: 9px; +} + +.yx { + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; +} + +.dz { + position: absolute; + right: 9px; +} + +.compilations { + /*border-bottom: 1px solid #e6e6e6;*/ + /*padding-bottom: 9px;*/ +} + +.guarantee { + width: 100%; + margin-bottom: 5px ; + background: white; +} + +.guarantee .row { + width: 100%; + height: 42px; + border-bottom: 1px solid #ebebeb; +} + +.mui-table-view-cell:after{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content{ + width: 100%; + background: transparent; +} +.row_{ + width: 100%; + font-size: 13.2px; + border-bottom: 1px solid #ebebeb; +} +.guarantee .row img { + height: 15px; + margin-left: 12px; + margin-top: 12px; + float: left; +} + +.guarantee .row .text { + color: #525252; + line-height: 42px; + font-size: 13.2px; + float: left; + max-width: calc(100% - 65px); + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + margin-left: 12px; +} + +.guarantee .row .text1 { + color: #e1202a; + background: white; + /*line-height: 42px;*/ + font-size: 10.2px; + float: left; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; + overflow: hidden; + margin-left: 12px; + padding: 0 8px; + margin-top: 10px; + height: 20px; + border: 1px solid #e1202a; + border-radius: 3px; +} + +.guarantee .row .lq { + float: right; + margin-top: 6px; + margin-right: 9px; + color: #909090; + border-radius: 15px; + line-height: 19px; + padding: 4px 10px 2px; +} + +.guarantee .row .caidan img { + width: 15px; + margin: 0; + height: 3px; +} + +.guarantee .row .caidan { + border: none; + float: right; + margin-top: 13px; + margin-right: 12px; +} + +.guarantee .row .caidan:active { + background: transparent; +} + +#guarantee .row .text { + color: black; +} + +.cc1 { + width: 100%; + height: 27px; +} + +.cclass_con { + position: absolute; + bottom: 0; + left: 0; + right: 0; +} + +.cc2 { + width: 100%; + height: 81px; + background: white; + position: relative; + border-bottom: 1px solid #e3e6ea; +} + +.cc2 p { + font-size: 17.6px; + color: #e94744; + position: absolute; + left: 120px; + top: 24px; +} + +.cc2 span { + font-size: 15px; + position: absolute; + left: 120px; + top: 48px; +} +.cc2 o{ + font-size: 12px; + color: #e94744; + position: absolute; + left: 200px; + top: 24px; +} +.cc2 l{ + font-size: 10px; + position: absolute; + left: 200px; + top: 48px; +} +.closecclass { + font-size: 15.6px; + color: #9b9b9b; + position: absolute; + padding: 9px 12px; + right: 0; + top: 0; +} + +.closecclass img { + width: 18px; +} + +.cclass_con .img { + background: white; + padding: 6px; + position: absolute; + border: 1px solid #f2f2f2; + border-radius: 6px; + width: 85.8px; + height: 85.8px; + top: 0; + left: 12px; + z-index: 60; +} + +.cclass_con .img img { + width: 100%; + height: 100%; + border-radius: 3px; +} + +.cclass1 { + padding: 9px 0 0 12px; + background: white; + width: 100%; + /*border-bottom: 1px solid #e3e6ea;*/ +} + +.cclass1 p { + color: #626262; + font-size: 17.2px; + padding-bottom: 6px; + margin: 0; +} + +.cclass1 .block { + padding: 2px 6px; + float: left; + /*border: 1px solid #9e9e9e;*/ + margin: 0px 18px 4px 0; + border-radius: 6px; + font-size: 14.4px; + color: #909090; + background: #f5f5f5; + font-size: 17.5px; +} + +.cclass1 .on { + /*border: 1px solid #e94947;*/ + color: #fff; + background: #e61329; +} + +.ensure { + width: 50%; + height: 48px; + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; + background: #e6122b; + float: left; +} + +.engwc { + width: 50%; + height: 48px; + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; + background: #ff9402; + float: left; +} + +.num { + background: white; + width: 100%; + height: 51.6px; + border-bottom: 1px solid #e3e6ea; + color: #626262; + font-size: 13.2px; + padding: 0 18px; + line-height: 51.6px; + position: relative; +} +.num span { + font-size: 15px; + } +.change_num { + width: 168px; + height: 30px; + position: absolute; + right: 30px; + top: 10.5px; +} + +.jia { + background: #ebebeb; + position: absolute; + font-size: 21px; + color: #e94947; + line-height: 30px; + width: 30px; + text-align: center; + right: 0; +} + +.jian { + background: #ebebeb; + position: absolute; + font-size: 21px; + color: #e94947; + line-height: 30px; + width: 30px; + text-align: center; + left: 0; +} + +.change_num input { + position: absolute; + width: 78px; + margin: 0 15px; + left: 30px; + height: 30px; + border: none; + text-align: center; + font-size: 18px; +} + +.pjrk { + width: 100%; + background: white; + margin-bottom: 5px ; +} + +.pj_title { + color: black; + padding: 9px 12px; + margin: 0; +} + +.pj_remark { + padding-left: 12px; +} + +.pjr { + padding: 3px 20px; + margin: 0 12px 12px 0; + font-size: 12px; + float: left; + background: #fdecea; + color: #525252; + border-radius: 20px; +} + +.pjbtitle img { + width: 25.2px; + height: 25.2px; + border-radius: 50%; + overflow: hidden; + float: left; +} + +.pj_breviary { + padding: 0 12px; +} + +.pjbtitle p { + color: #e61329; + font-size: 13.2px; + float: left; + margin: 0; + line-height: 25.2px; + padding-left: 6px; +} + +.pjbcon { + color: #525252; + font-size: 13.2px; + margin: 3px 0; +} + +.pjclass { + color: #909090; + font-size: 13.2px; + margin-bottom: 6px; +} + +.pj_all { + margin: 14px auto; + text-align: center; + width: 99px; + height: 36px; + line-height: 36px; + border: 1px solid #e61329; + color: #e61329; + border-radius: 6px; + font-size: 14.4px; +} + +.shop_info { + background: white; + width: 100%; + margin-bottom: 5px; +} + +.shop_title { + padding: 12px; +} + +.shop_title img { + width: 48px; + height: 48px; + float: left; +} + +.shop_title p { + float: left; + font-size: 16.8px; + color: black; + margin: 0; + margin-top: 3px; + margin-left: 6px; +} + +.shopinfocon {} + +.sicl { + width: 24%; + border-right: 1px solid #e6e6e6; + text-align: center; + float: left; + margin: 6px 0; +} + +.sicl_p1 { + color: #525252; + font-size: 13.2px; +} + +.sicl_p2 { + color: #909090; + font-size: 13.2px; + margin-top: 9px; +} + +.sicr { + text-align: center; + float: left; + width: calc(28% - 3px); +} + +.sicr_p { + color: #909090; + font-size: 12px; +} + +.sicr_p o { + color: #e61329; +} + +.footer { + width: 100%; + height: 50px; + background: white; + position: fixed; + bottom: 0; + left: 0; + border-top: 1px solid #ebebeb; + z-index: 13; +} + +.footerl { + position: relative; + float: left; + height: 50px; + width: calc(14% - 2px); + text-align: center; +} + +.footerl img { + width: 22.8px; + margin-top: 6px; +} + +.footerl p { + width: 100%; + margin: 0; + font-size: 13.2px; + position: absolute; + bottom: 0; +} + +.footerl1 { + position: relative; + width: 13%; + float: left; + height: 50px; + text-align: center; + border-left: 1px solid #ebebeb; +} + +.footerl1 img { + height: 16.8px; + margin-top: 8px; +} + +.footerl1 p { + width: 100%; + margin: 0; + position: absolute; + bottom: 0; + font-size: 13.2px +} + +.footerr1 { + width: 30%; + height: 50px; + line-height: 50px; + text-align: center; + color: white; + background: #ff9402; + float: right; +} + +.footerr2 { + width: 30%; + height: 50px; + line-height: 50px; + text-align: center; + color: white; + background: #E6122B; + float: right; +} + +.imgcon { + border-bottom: 50px solid #ebebeb; +} + +.imgcon img { + width: 100%; + padding: 0 1%; + display: block; +} + +.pswp__top-bar { + margin-top: 20px; +} + +.ccclass { + width: 100%; +} + +.youhuiquan_con { + position: relative; +} + +.yhq_con { + position: absolute; + bottom: 0; + right: 0; + left: 0; + background: white; +} + +.thq_close { + width: 100%; + height: 51px; + background: #E6122B; + color: white; + text-align: center; + line-height: 51px; +} + +.yhqcon { + padding: 3%; +} + +.thq_block { + width: 100%; + border-radius: 6px; + position: relative; +} + +.thq_block img { + width: 100%; +} + +.thq_block p { + position: absolute; + font-size: 35px; + color: white; + top: 50%; + left: 10px; + transform: translateY(-50%); +} +.thq_block span { + position: absolute; + font-size: 18px; + color: white; + top: 50%; + right: 30%; + transform: translateY(-50%); +} +.lq_btn{ + position: absolute; + font-size: 18px; + color: white; + top: 50%; + right: 0; + transform: translateY(-50%); + border: none; + background: transparent; + width: 25%; + height: 60px; +} +.thq_block .lq_btn:hover{ + background: transparent; + +} +.ccclass{ + /*max-height: 800px;*/ +} +.ccclass .mui-scroll-wrapper{ + /*max-height: 500px;*/ +} +#shareout{ + position: relative; +} +#shareout o{ + width: calc(100% - 50px); + display: block; +} +#shareout img{ + position: absolute; + width: 34.4px; + padding: 10px; + right: 20px; + top: 50%; + transform: translateY(-50%); +} +/*秒杀*/ +.banner{ + position: relative; +} +.miaosha{ + /*position: absolute;*/ + width: 100%; + /*padding:0 1%;*/ + bottom: 5px; + left: 0; + right: 0; + z-index: 100000; + position: relative; + background: -moz-linear-gradient(left, #ff0048, #ff3b85); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#ff0048), to(#ff3b85)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #ff0048, #ff3b85); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #ff0048, #ff3b85); + /*Opera11*/ + +} +.miaosha img{ + width: 100%; + display: block; +} +.con{ + transform: translateY(-10px); +} +.xiangou{ + position: absolute; + color: white; + bottom: 1%; + left: 44%; + font-size: 13px; +} +.miaosha1{ + position: absolute; + font-size: 30px; + color: white; + top: 18%; + left: 5%; +} +.miaosha1 o{ + font-size: 10px; +} +.miaosha2{ + position: absolute; + font-size: 13px; + color: white; + left: 27%; + bottom: 0; + height: 20px; +} +.miaosha3{ + position: absolute; + left: 65%; + right: 2%; + bottom: 5%; + text-align: center; + font-size: 14px; + color: #ff2870; +} +.miaosha3 o{ + background: #ff2870; + color: white; + margin: 0 2%; + display: inline-block; + padding: 2px 4px; + border-radius: 5px ; +} +.miaosha4{ + font-size: 12px; + color: white; + border: 1px solid white; + position: absolute; + left: 5%; + bottom: 5%; + padding: 0 10px; + border-radius:50px; + height: 16px; + line-height: 14px; +} +.miaosha5{ + position: absolute; + left: 65%; + right: 2%; + top: 10%; + font-weight: bold; + text-align: center; + font-size: 14px; + color: #ff2870; +} +.summarize{ + border-top: none; +} diff --git a/static/app2/css/discount.css b/static/app2/css/discount.css new file mode 100755 index 0000000..d761b17 --- /dev/null +++ b/static/app2/css/discount.css @@ -0,0 +1,263 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.1); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} + + +.oc_logo { + /*width: 67.5px;*/ + height: 16.5px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 13.75px; +} + +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); +} + + + +#timer_swiper .swiper-slide { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; +} +.nav .r{ + float: right; +} + +.con .recommend{ + padding: 5px 0; +} +#timer_swiper .lxy0 .on p{ + color: #00d793; + border-bottom: 4px solid #01de92; +} + +#timer_swiper .lxy1 .on p{ + color: #5f26e6; + border-bottom: 4px solid #64ed13; +} + +.t_con p{ + font-size: 13px; + color: #000; +} + + +.t_con { + width: 100%; + background: #fff; +} + +#timer_swiper { + width: 100%; +} +#timer_swiper .swiper-wrapper .swiper-slide img{ + padding: 3px; + border-radius: 7px; +} +.t_con .swiper-container { + width: 800px; +} + +.t_con .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} +.on p{ + color: #ee344a; + border-bottom: 3px solid #EE344A; +} + + +#timer_swiper .swiper-slide { + position: relative; +} + +#timer_swiper .swiper-slide img {} + +#timer_swiper .swiper-slide p { + /*position: absolute;*/ +} + + +.con_block { + margin-top: 1px; + width: 100%; + height: 170px; + background: white; + position: relative; +} + +.con_block .img { + width: 109px; + height: 109px; + position: absolute; + top: 30px; + left: 2%; +} + +.con_block .p1 { + width: calc(100% - 130px); + right: 2%; + color: #101010; + font-size: 13px; + position: absolute; + top: 20px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.con_block .p2 { + color: #fff; + font-size: 10px; + position: absolute; + background: -moz-linear-gradient(left, #ff0000, #ff0066); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#ff0000), to(#ff0066)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #ff0000, #ff0066); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #ff0000, #ff0066); + /*Opera11*/ + border-radius: 3px; + padding: 0px 2px; + top: 65px; + right: calc(100% - 171px); +} + +.pect{ + color: #fff; + font-size: 10px; + position: absolute; + background: -moz-linear-gradient(left, #6600ff, #a200ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#6600ff), to(#a200ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #6600ff, #a200ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #6600ff, #a200ff); + /*Opera11*/ + border-radius: 3px; + padding: 0px 2px; + top: 65px; + right: calc(100% - 220px); +} + +.con_block .p3 { + color: #ec3449; + font-size: 15px; + position: absolute; + width: calc(100% - 130px); + right: 2%; + top: 105px; +} + +.con_block .p3 o { + font-size: 13px; +} + +.con_block del { + color: #808080; + font-size: 14px; + position: absolute; + width: calc(100% - 130px); + right: 2%; + top: 120px; +} + +.con_block del o { + font-size: 12px; +} + +.con_block button { + color: white; + background: #ED374C; + font-size: 13px; + padding: 5px 15px; + border-radius: 5px; + position: absolute; + right: 2%; + bottom: 35px; + border: none; +} + +.con_block .p4 { + color: #808080; + font-size: 10px; + position: absolute; + bottom: 10px; + right: 80px; +} + +.con_block progress { + width: 70px; + height: 9px; + border-radius: 10px; + position: absolute; + right: 2%; + bottom: 16px; + background: white; +} + +::-ms-fill { + background: #ED374C; +} + +::-moz-progress-bar { + background: #ED374C; +} + +::-webkit-progress-bar { + background: white; + border: 1px solid #ED374C; + border-radius: 10px; +} + +::-webkit-progress-value { + background: #ED374C; + border-radius: 0 5px 5px 0; +} + + diff --git a/static/app2/css/discounts.css b/static/app2/css/discounts.css new file mode 100755 index 0000000..e581fb5 --- /dev/null +++ b/static/app2/css/discounts.css @@ -0,0 +1,21 @@ +.nav{ + width: 100%; + height: 37px; + margin-top: 66px; + border-bottom: 1px solid #e6e6e6; +} +.p1{ + color: #909090; + width: 33.33333333%; + text-align: center; + display: block; + float: left; + line-height: 36px; + font-size: 13.2px; + background: white; +} +.nav .on{ + color: #e51329; +} + + diff --git a/static/app2/css/dynamic.css b/static/app2/css/dynamic.css new file mode 100755 index 0000000..982c107 --- /dev/null +++ b/static/app2/css/dynamic.css @@ -0,0 +1,231 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .bc_img,.b_con img { + height: 125px; + } + + .mui-slider { + height: 168px; + } + .mui-slider-item { + height: 168px; + } + .mui-slider .mui-slider-item img { + height: 168px; + width: 100%; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .bc_img,.b_con img { + height: 113px; + } + .mui-slider { + height: 152px; + } + .mui-slider-item { + height: 152px; + } + .mui-slider .mui-slider-item img { + height: 152px; + width: 100%; + } +} + +/* 5 */ + +@media all and (max-width: 320px) { + .bc_img,.b_con img { + height: 94.5px; + } + .mui-slider { + height: 130px; + } + .mui-slider-item { + height: 130px; + } + .mui-slider .mui-slider-item img { + height: 130px; + width: 100%; + } +} +.con{ + width: 100%; + overflow: hidden; +} +.block { + width: 100%; + margin-bottom: 6px ; + background: white; +} + +.b_title { + width: 100%; + position: relative; + height: 60px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.b_title .b_img { + width: 48px; + height: 48px; + position: absolute; + bottom: 0; + left: 15px; +} + +.storename { + position: absolute; + width: calc(100% - 140px); + color: black; + left: 69px; + top: 15px; + font-size: 16.8px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.time { + position: absolute; + width: calc(100% - 140px); + left: 69px; + color: #909090; + font-size: 13.2px; + top: 38px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.btn_menu { + width: 38px; + height: 38px; + padding: 10px; + position: absolute; + right: 0; + top: 5px; +} + +.b_con { + width: 100%; + padding: 7.5px 13.5px; + font-size: 14.4px; + color: #525252; +} + +.b_footer { + width: 100%; + height: 36px; + position: relative; +} + +.num { + position: absolute; + width: 90px; + top: 7.5px; + left: 15px; +} + +.num img { + width: 18px; + float: left; +} + +.nun p { + float: left; +} + +.zan { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #909090; + position: absolute; + background: url(../img/zan1.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #909090; + text-indent: 15px; + right: 18px; + bottom: 8px; +} + +.zanon { + padding: 0 9px 0 12px; + height: 20px; + border: 1px solid #e51329; + position: absolute; + background: url(../img/zan2.png) no-repeat 7px center; + background-size: 18px; + border-radius: 9px; + min-width: 45px; + line-height: 18px; + font-size: 14.4px; + color: #e51329; + text-indent: 15px; + right: 18px; + bottom: 8px; +} + +.b_con img { + width: calc(33.33333333333% - 3px); + margin: 1.5px; + float: left; +} + +.btn_gz{ + height: 24px; + text-align: center; + border: 1px solid #e91b34; + line-height: 24px; + color: #e91b31; + border-radius: 15px; + padding: 0 9px; + position: absolute; + right: 18px; + font-size: 12px; + top: 25px; +} + +.btn_gz1{ + height: 24px; + text-align: center; + border: 1px solid #909090; + line-height: 24px; + color: #909090; + border-radius: 15px; + padding: 0 9px; + position: absolute; + right: 18px; + font-size: 12px; + top: 25px; +} + + +.bc_img{ + position: relative; + width: calc(33.33333333333% - 3px); + float: left; + margin: 1.5px; +} +.b_con .bc_img img{ + width: 100%; + margin: 0; +} +.bc_img p{ + position: absolute; + text-align: center; + width: 100%; + background: rgba(0,0,0,0.1); + color: white; + bottom: 0; +} diff --git a/static/app2/css/ect_address.css b/static/app2/css/ect_address.css new file mode 100755 index 0000000..e826e6e --- /dev/null +++ b/static/app2/css/ect_address.css @@ -0,0 +1,129 @@ +.add { + position: absolute; + right: 10px; + padding: 3px 8px; + top: 10px; + font-size: 13.2px; + color: #000; +} + +.header1 .mui-action-back { + color: #f02a40; +} + +.con {} + +.con .row { + width: 100%; + height: 95px; + background: white; + margin: 6px 0; +} + +.r_con { + width: 100%; + height: 55px; + border-bottom: 1px solid #dcdcdc; + line-height: 55px; + padding: 0 25px; +} + +.r_con p { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 13px; + color: black; +} + +.r_bottom { + width: 100%; + height: 40px; + position: relative; +} + +.check { + width: 25px; + height: 25px; + /*border: 1px solid #989898;*/ + border-radius: 50%; + position: absolute; + left: 25px; + top: 50%; + transform: translateY(-50%); + color: white; + background: #AAAAAA; + font-weight: bold; +} + +.r_bottom .on { + background: -moz-linear-gradient(left, #00fffc, #00a8ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#00fffc), to(#00a8ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #00fffc, #00a8ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #00fffc, #00a8ff); + /*Opera11*/ +} + +.r_bottom p { + position: absolute; + left: 54px; + top: 50%; + transform: translateY(-50%); + font-size: 12px; + color: black; +} + +.del { + position: absolute; + right: 18px; + font-size: 12px; + color: #f02a40; + width: 100px; + height: 40px; + text-align: center; + /*border: 1px solid #f02a40;*/ + /*border-radius: 5px;*/ + color: #404040; +} + +.del_icon,.del_text { + position: absolute; + top: 50%; + transform: translateY(-50%); +} +.del_text{ + right: 0; +} +.con { + position: fixed; + transform: translateY(0); +} + +.mui-scroll { + width: 96%; +} + +.addAddress { + border-radius: 0; + width: 100%; + text-align: center; + border: none; + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 100000; + height: 50px; + color: white; + background: -moz-linear-gradient(left, #209eff, #61d8ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#209eff), to(#61d8ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #209eff, #61d8ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #209eff, #61d8ff); + /*Opera11*/ +} \ No newline at end of file diff --git a/static/app2/css/ect_area.css b/static/app2/css/ect_area.css new file mode 100755 index 0000000..feab8f4 --- /dev/null +++ b/static/app2/css/ect_area.css @@ -0,0 +1,202 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.2); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} +.mui-scroll {} + +.tanhao { + width: 36.5px; + position: absolute; + right: 2.8%; + bottom: 7px; + padding: 10px; +} + +.ect_top { + padding: 0 2.5%; + width: 100%; + position: relative; + height: 54px; + position: fixed; + left: 0; + right: 0; + top: 66px; + background: white; +} + +#last, +#vol { + border-bottom: none; +} + +.ect_m { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #909090; + float: left; + width: 50%; + padding: 2.5px 0; + text-align: center; + background: #fff; + border-bottom: 1px solid #e6e6e6; + height: 27px; +} + +.ect_top img { + width: 17.5px; + height: 16.2px; + position: absolute; + left: 37.2px; + top: 30.6px; +} + + +/*top end*/ + +.con { + width: 100%; + padding: 0 1.25%; +} + +.con .ect_com { + width: 47.25%; + margin: 1.25%; + background: #fff; + float: left; +} + +.com_img1 { + width: 100%; +} + +.com_img1 img { + width: 100%; + height: 100%; + display: block; +} + +.com_img2 { + width: 30px; + height: 15px; + /*margin-left: 3.6px;*/ + margin-right: 8.4px; + margin-top: 5px; + display: inline-block; +} + +.ect_com p { + font-family: "微软雅黑"; + font-size: 13.2px; + color: #000000; + width: 100%; + padding-left: 3.6px; +} + +.ect_com .p1 { + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} + +.ect_com .p3 { + color: #e51329; + margin-top: 14px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.ect_activity { + width: 100%; +} +.ect_activity_{ + width: 100%; + position: relative; +} + +#_h,#_m,#_s{ + background: #525252; + color: white; + padding: 0 3px; + font-size: 12px; + position: absolute; + bottom: 0px; + border-radius: 3px; + /*line-height: 13px;*/ + /*height: 14px;*/ + bottom: 12%; +} +#_h{ + left: 48.9%; +} +#_m{ + left: 55.7%; +} +#_s{ + left: 62.5%; +} +.ect_hd { + width: 48%; + display: block; + margin: 0 auto; +} +.ect_djs{ + width: 38%; + margin: 10px auto 0; + display: block; + padding-bottom: 10px; +} + +.day { + width: 80%; + height: 15px; + background: #fbdcdc; + margin-left: 2%; + margin-bottom: 2.5px; +} + +.day p { + font-family: "微软雅黑"; + font-size: 10px; + color: #e51329; + line-height: 15px; +} + +.nav { + width: 100%; + height: 36px; + position: fixed; + top: 126px; + background: white; +} + +.nav_block { + width: 20%; + float: left; + font-size: 10.8px; + color: #909090; + text-align: center; + padding: 6px 0; + height: 36px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.nav .on { + color: #e51329; + border-bottom: 3px solid #e5122b; +} \ No newline at end of file diff --git a/static/app2/css/ect_index.css b/static/app2/css/ect_index.css new file mode 100755 index 0000000..986bb7e --- /dev/null +++ b/static/app2/css/ect_index.css @@ -0,0 +1,79 @@ +body { +} + +.num { + width: 100%; + position: relative; +} +.header,.header_con{ + +} + +.header_con a,.header_con .title{ + /*color: white;*/ +} +.num p { + text-align: center; + width: 100%; + position: absolute; + top: 40px; + color: white; + font-size: 30px; +} +.num span{ + text-align: center; + width: 100%; + position: absolute; + top: 80px; + color: white; + font-size: 13px; +} + +.row { + width: 100%; + height: 55px; + position: relative; + background: white; + /*margin-bottom: 5px;*/ + border-top: 1px solid #EFEFF4; +} +.top{ + /*opacity: 0;*/ +} +.row .icon { + width: 41px; + height: 41px; + position: absolute; + top: 50%; + transform: translateY(-50%); + left: 13px; +} + +.row p { + width: calc(100% - 120px); + position: absolute; + color: #525252; + top: 50%; + transform: translateY(-50%); + left: 70px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.row .img{ + width: 24px; + height: 24px; + position: absolute; + top: 50%; + transform: translateY(-50%); + right: 15px; +} + + +.num img{ + width: 100%; + height: 134px; + display: block; +} + + diff --git a/static/app2/css/ect_list.css b/static/app2/css/ect_list.css new file mode 100755 index 0000000..f574099 --- /dev/null +++ b/static/app2/css/ect_list.css @@ -0,0 +1,74 @@ +.header1 .mui-action-back{ + color: #f02a40; +} + +.block img{ + width: 100%; +} +.block{ + position: relative; + margin-top: 12px; +} +.block .s1{ + position: absolute; + color: #222222; + font-size: 14.4px; + top: 8%; + left: 18%; + display: inline-block; +} +.block .s2{ + position: absolute; + color: #909090; + font-size: 12px; + top: 15%; + left: 18%; + display: inline-block; +} + +.block .s3{ + position: absolute; + color: #909090; + font-size: 13.2px; + top: 25%; + left: 0; + right: 0; + width: 100%; + text-align: center; + display: inline-block; +} + +.block .s4{ + position: absolute; + color: #f02a40; + font-size: 42px; + top: 45%; + left: 0; + right: 0; + width: 100%; + text-align: center; + display: inline-block; +} +.block .s5{ + position: absolute; + color: #525252; + font-size: 14.4px; + bottom: 20%; + left: 7%; + display: inline-block; +} +.s5 o{ + color: #222222; +} + +.block .s6{ + position: absolute; + color: #525252; + font-size: 14.4px; + bottom: 10%; + left: 7%; + display: inline-block; +} +.s6 o{ + color: #222222; +} diff --git a/static/app2/css/editAddress.css b/static/app2/css/editAddress.css new file mode 100755 index 0000000..2909571 --- /dev/null +++ b/static/app2/css/editAddress.css @@ -0,0 +1,43 @@ +.row{ + width: 100%; + height: 42px; + border-bottom: 1px solid #E6E6E6; + line-height: 41px; + background: white; + margin-bottom: 5px; +} +.row input{ + border: none; + margin: 0; +} +.row input::-webkit-input-placeholder{ + font-size: 12px +} +.row select{ + float: left; + margin: 0; + width: 33%; + text-align: center; +} +.row select option{ + text-align: center; +} +textarea{ + border-top: none; + font-size: 12px +} +.bc_btn{ + margin: 0 auto; + left: 5%; + right: 5%; + /*position: absolute;*/ + width: 90%; + height: 42px; + border: none; + background: #F02C43; + color: white; +} +.add_info,.isdef{ + padding: 0 15px; + font-size: 12px; +} diff --git a/static/app2/css/essay.css b/static/app2/css/essay.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/essaylist.css b/static/app2/css/essaylist.css new file mode 100755 index 0000000..12641b4 --- /dev/null +++ b/static/app2/css/essaylist.css @@ -0,0 +1,22 @@ +.add1{ + width: 96%; + margin: 5px auto; + height: 63px; + background:#C9C9C9; + border:1px solid #C9C9C9; + border-radius: 5px; + display:flex; + justify-content: center; + align-items:center ; + /* margin-top: 10px; */ + } + .addimg{ + width: 40px; + height: 40px; + } + .add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + } + \ No newline at end of file diff --git a/static/app2/css/family.css b/static/app2/css/family.css new file mode 100755 index 0000000..13fe9e3 --- /dev/null +++ b/static/app2/css/family.css @@ -0,0 +1,109 @@ + +.oc_logo { + /*width: 67.5px;*/ + height: 20px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + /*top: 13.75px;*/ + transform: translateY(-50%); + top: 50%; +} + +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); +} + + + +#timer_swiper .swiper-slide { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; +} +.nav .r{ + float: right; +} + +.con .recommend{ + padding: 5px 0; +} +#timer_swiper .lxy0 .on p{ + color: #00d793; + border-bottom: 4px solid #01de92; +} + +#timer_swiper .lxy1 .on p{ + color: #5f26e6; + border-bottom: 4px solid #64ed13; +} + +.t_con p{ + font-size: 13px; + color: #000; +} + + +.t_con { + width: 100%; + background: #fff; +} + +#timer_swiper { + width: 100%; +} +#timer_swiper .swiper-wrapper .swiper-slide img{ + padding: 3px; + border-radius: 7px; +} +.t_con .swiper-container { + width: 800px; +} + +.t_con .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#timer_swiper .swiper-slide { + position: relative; +} + +#timer_swiper .swiper-slide img { + +} + +#timer_swiper .swiper-slide p { + /*position: absolute;*/ +} + +.header a{ + color: #fff; +} + + diff --git a/static/app2/css/friends.css b/static/app2/css/friends.css new file mode 100755 index 0000000..ca60847 --- /dev/null +++ b/static/app2/css/friends.css @@ -0,0 +1,247 @@ +.fri-con-tit { + /* margin-top: 45px; */ + display: flex; + justify-content: space-between; + align-items: center; + /* padding: 15px; */ + flex: 1; + background: #fff; + width: 98%; + margin: 0 auto 5px; +} + +.headerimg { + + width: 78px; + height: 78px; + border-radius: 100px; + border: 3px solid #fff; + margin-right: 10px; +} + +.headerimg img { + width: 100%; +} + +.fri-con-tit .shop_info { + flex: 3; +} + +.fri-con-tit .shop_info p { + font-size: 21px; + color: #666; + font-weight: 300; +} + +.fri-con-tit .shop_info span { + font-size: 17px; + color: #ce2121; + margin-right: 10px; +} + +.fri-con-tit .shop_info .orange { + background: rgba(224, 35, 218, 0.68); + font-size: 14px; + border: 1px solid #ff7900; + border-radius: 10px; + margin-left: 10px; + margin-top: -5px; + display: inline-block; + width: 30px; + height: 20px; + text-align: center; + line-height: 20px; +} + +.fri-con .row { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto 5px; + flex: 1; +} + +.row label { + font-size: 17px; + color: #363636; + +} +.row label .lock{ + color: #ce2121; +} +.fri-con { + margin-top: 11px; +} + +.fri-share { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + width: 220px; + margin: 30px auto; + text-align: center; +} + +.fri-share-img { + width: 150px; + height: 150px; +} + +.fri-share-img img { + width: 100%; + height: 100%; +} + +.list_row{ + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + align-content: flex-start; + background: #fff; + padding-top: 10px; + margin-bottom: 7px; +} +.lock_row{ + display: flex; + justify-content: space-around; + align-items: center; + background: #fff; + /* padding-top: 10px; */ + margin-bottom: 7px; +} + +.lock_row label{ + + display: inline-block; + padding: 10px 5px; + font-size: 13px; + color: #363636; + +} +.lock_row span{ + display: inline-block; + font-size: 13px; + color: #363636; +} +.list_row label{ + display: inline-block; + padding: 0px 8px 10px; + + width: 20%; + font-size: 13px; + color: #363636; +} +.list_row span{ + display: inline-block; + width: 30%; + padding: 0px 8px 10px; + font-size: 13px; + color: #363636; +} +/* 烂笔头 */ +.con{ + +} +.essay-con{ + width: 98%; + margin: 0px auto; + margin-bottom: 5px; + } +.essay-con .row{ + display:flex ; + justify-content: space-between; + align-items: center; + padding: 10px; + background: #eee; + /* height: 20px; */ +} +.essay-con .row .del{ + width: 25px; + height: 25px; +} +.essay-con .row .name{ + font-size: 15px; + + +} +.essay-con .row .del img { + width: 100%; + height: 100%; +} +.row_con{ + display:flex ; + justify-content: space-between; + align-items: center; + background: #fff; +} +.row_con_con{ + display:flex ; + flex-direction: column; + justify-content: space-between; + align-items: center; + padding: 10px; + font-size: 15px; +} +.row_con_con .row_con_con_{ + width: 60px; + height:60px; + padding: 10px; +} +.row_con_con .row_con_con_ img{ + width: 100%; + height: 100%; +} +.essay-con .row .pass { + position: relative; +} +.essay-con .row .pass input{ + width:200px; + margin: 0px; + padding-right: 50px; + +} +.essay-con .row .pass .send{ + width:30px ; + height: 30px; + position: absolute; + right: 3px; + top: 5px; +} +.essay-con .row .pass .send img { + + width: 100%; + height: 100%; + +} +.add1{ + width: 96%; + margin: 35px auto; + height: 63px; + background:#C9C9C9; + border:1px solid #C9C9C9; + border-radius: 5px; + display:flex; + justify-content: center; + align-items:center ; + /* margin-top: 10px; */ + } + .addimg{ + width: 40px; + height: 40px; + } + .add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + } + + + + diff --git a/static/app2/css/global.1.css b/static/app2/css/global.1.css new file mode 100755 index 0000000..eee071f --- /dev/null +++ b/static/app2/css/global.1.css @@ -0,0 +1,144 @@ +.clearfix:after { + height: 0; + content: " "; + display: block; + overflow: hidden; + clear: both; +} + +.clearfix { + zoom: 1; + /*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + +a { + color: black; +} + +a:active { + color: white; +} + +p { + margin: 0; +} + +input { + margin: 0; +} + +img {} + +.scroll_out { + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out1 { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out2 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out3 { + position: fixed; + top: 162px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out4 { + position: fixed; + top: 120px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out_tb { + position: fixed; + top: 64px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out_t { + position: fixed; + top: 64px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +body { + font-family: "微软雅黑"; +} + +.shadown_wai { + box-shadow: 2px 2px 5px rgba(25, 25, 25, 0.2); + border-radius: 5px; + overflow: hidden; + border-top: 1px solid #EFEFF4; + margin-bottom: 1px; +} + +.pect { + color: #fff; + font-size: 10px; + position: absolute; + background: -moz-linear-gradient(left, #6600ff, #a200ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#6600ff), to(#a200ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #6600ff, #a200ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #6600ff, #a200ff); + /*Opera11*/ + border-radius: 3px; + padding: 0px 2px; + top: 65px; + right: calc(100% - 220px); +} + +.hide { + display: none; +} + +.backTop { + background: #DDDDDD; + border-radius: 50%; + position: fixed; + right: 10px; + bottom: 15px; + width: 38px; + height: 38px; + z-index: 9999; + text-align: center; + font-size: 18px; + color: #666666; + padding-top: 8px; + opacity: 0.8; +} diff --git a/static/app2/css/global.css b/static/app2/css/global.css new file mode 100755 index 0000000..78f7770 --- /dev/null +++ b/static/app2/css/global.css @@ -0,0 +1,144 @@ +.clearfix:after { + height: 0; + content: " "; + display: block; + overflow: hidden; + clear: both; +} + +.clearfix { + zoom: 1; + /*IE低版本浏览器不支持after伪类所以要加这一句*/ +} + +a { + color: black; +} + +a:active { + color: white; +} + +p { + margin: 0; +} + +input { + margin: 0; +} + +img {} + +.scroll_out { + position: fixed; + top: 66px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out1 { + position: fixed; + top: 66px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out2 { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out3 { + position: fixed; + top: 162px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out4 { + position: fixed; + top: 120px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out_tb { + position: fixed; + top: 64px; + bottom: 50px; + left: 0; + right: 0; +} + +.scroll_out_t { + position: fixed; + top: 64px; + bottom: 0; + left: 0; + right: 0; +} + +.scroll_out { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +body { + font-family: "微软雅黑"; +} + +.shadown_wai { + box-shadow: 2px 2px 5px rgba(25, 25, 25, 0.2); + border-radius: 5px; + overflow: hidden; + border-top: 1px solid #EFEFF4; + margin-bottom: 1px; +} + +.pect { + color: #fff; + font-size: 10px; + position: absolute; + background: -moz-linear-gradient(left, #6600ff, #a200ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#6600ff), to(#a200ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #6600ff, #a200ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #6600ff, #a200ff); + /*Opera11*/ + border-radius: 3px; + padding: 0px 2px; + top: 65px; + right: calc(100% - 220px); +} + +.hide { + display: none; +} + +.backTop { + background: #DDDDDD; + border-radius: 50%; + position: fixed; + right: 10px; + bottom: 15px; + width: 38px; + height: 38px; + z-index: 9999; + text-align: center; + font-size: 18px; + color: #666666; + padding-top: 8px; + opacity: 0.8; +} \ No newline at end of file diff --git a/static/app2/css/goodsList.css b/static/app2/css/goodsList.css new file mode 100755 index 0000000..fb12ae2 --- /dev/null +++ b/static/app2/css/goodsList.css @@ -0,0 +1,8 @@ + +.kkkk{ + width: 100%; + height: 66px; +} +.search input{ + margin-top: 20px; +} diff --git a/static/app2/css/guide.css b/static/app2/css/guide.css new file mode 100755 index 0000000..81f1020 --- /dev/null +++ b/static/app2/css/guide.css @@ -0,0 +1,19 @@ +#close { + position: absolute; + width: 60px; + /*height: 24px;*/ + right: 5%; + top: 5%; + /*left: 50%; + margin-left: -80px; + bottom: 15%;*/ + padding: 5px; + color: #fff; + border-color: #fff; +} + +img { + width: 100%; + height: 100%; + display: block; +} \ No newline at end of file diff --git a/static/app2/css/header.css b/static/app2/css/header.css new file mode 100755 index 0000000..3e2cd83 --- /dev/null +++ b/static/app2/css/header.css @@ -0,0 +1,100 @@ +header { + padding-top: 18px; + line-height: 48px; + text-align: center; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 18px; + z-index: 10; + position: fixed; + width: 100%; + top: 0; + left: 0; +} +header .nav{ + color: white; + /*text-align: center;*/ +} +.mui-bar{ + height: 66px; + color: white; +} + +.mui-title{ + color: white; + bottom: 0; +} + +a{ + /*color: white;*/ +} + +.mui-bar-nav{ + box-shadow: 0 0 0; +} + + +.header { + width: 100%; + height: 64px; + padding-top: 20px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 111111111; + background-color: rgba(255, 255, 255, 1); +} + +.header_con { + position: relative; + width: 100%; + height: 44px; +} + +.mui-action-back{ + position: absolute; + top: 10px; + left: 12px; + z-index: 100; +} +.oc_logo { + width: 20%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 27%; +} +.header_con .title{ + color: #101010; + font-size: 17px; + position: absolute; + left: 0; + right: 0; + text-align: center; + margin: 0 auto; + bottom: 11.5px; + z-index: 10; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.header_con .header_con_bc{ + color: #101010; + font-size: 17px; + position: absolute; + /* left: 0; */ + right: 10px; + text-align: center; + margin: 0 auto; + bottom: 11.5px; + z-index: 10; +} \ No newline at end of file diff --git a/static/app2/css/header1.css b/static/app2/css/header1.css new file mode 100755 index 0000000..a683add --- /dev/null +++ b/static/app2/css/header1.css @@ -0,0 +1,41 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + left: 0; + right: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} diff --git a/static/app2/css/home.css b/static/app2/css/home.css new file mode 100755 index 0000000..ec21a12 --- /dev/null +++ b/static/app2/css/home.css @@ -0,0 +1,709 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.2); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} + + +.con{ + overflow: hidden; +} + +.news marquee{ + font-size: 12px; +} +.sx{ + margin-top: -50px; + height: 50px; + width: 100%; + text-align: center; + font-size: 12px; +} + +.header { + width: 100%; + height: 64px; + padding-top: 20px; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 111111111; + background-color: rgba(0, 0, 0, 0); +} + +.header_con { + position: relative; + width: 100%; + height: 44px; +} + +#search { + margin: 0; + width: 65%; + height: 31px; + position: absolute; + left: 13.8%; + right: 21%; + top: 7px; + border-radius: 16px; + border: none; + /*text-indent: 20px;*/ + background-color: rgb(255, 255, 255); + font-size: 11px; + line-height: 34px; + text-indent: 30px; +} + +.searchimg { + width: 12.5px; + height: 12.5px; + position: absolute; + top: 17px; + left: 16.4%; +} +.search input { + margin: 0; + height: 30px; + border: none; + border-radius: 0; + background: transparent; + padding: 0 40px; + /*padding-left: 50px;*/ +} +.search select{ + border:1px solid red; + position: absolute; + width: 50px; + height: 29px; + padding: 0; + text-align: center; + border-radius: 0; + padding-left: 0px; + padding-top: 2px; + background: transparent; +} +.search button{ + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; + border-radius: 50px; +} + +.saoyisao { + position: absolute; + padding: 5px 10px 0; + width: 52.5px; + height: 37.5px; + top: 1.5px; + left: 1.0%; +} + +.getquan { + position: absolute; + width: 37.5px; + height: 42.5px; + bottom: 2px; + right: 11%; +} + +.msg { + position: absolute; + padding: 5px 5px 0; + width: 42.5px; + height: 37.5px; + top: 1.5px; + right: 1%; +} + +.mui-scroll-wrapper, +.scroll_out { + /*position: relative;*/ + z-index: 10; +} + +#top_banner { + width: 100%; + height: 300px; + margin: 20px auto; + margin: 0; + position: relative; +} + +#top_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#top_banner .swiper-slide img { + width: 100%; + height: 100%; +} + +#top_banner .swiper-pagination-bullet-active { + background: white; +} + +#top_banner .swiper-pagination-bullet { + background: #eee; +} + +.mui-scroll-wrapper {} + +.con { + width: 100%; + padding: 0 2%; + float: left; + position: relative; + z-index: 111; + transform: translateY(-6px); +} + +.con_nav { + border-radius: 5px; + overflow: hidden; + background: white; +} + + +.class_block { + width: 20%; + float: left; + padding: 0.85%; +} + +.class_block p { + text-align: center; + font-size: 14px; + color: black; +} + +.classify { + width: 100%; + margin: 0 auto; + padding: 10px 1% 5px; + background: white; + border-bottom: 1px solid #EFEFF4; +} + +.class_block img { + width: 100%; + height: 100%; +} + +.news { + width: 100%; + height: 30px; + position: relative; +} + +.news img { + width: 70px; + height: 21px; + position: absolute; + left: 3%; + top: 4px; +} + +.hot { + color: #e51329; + font-size: 12px; + line-height: 30px; + position: absolute; + left: 25%; +} + +.news marquee { + width: 53%; + line-height: 30px; + position: absolute; + left: 30%; + height: 30px; +} + +.msg_more { + width: 15%; + height: 30px; + line-height: 30px; + position: absolute; + right: 0; + font-size: 12px; + color: black; +} + +.kkk { + width: 10px; + height: 2000px; +} + +.time { + width: 100%; + margin-top: 3px; + background: white; + border-radius: 5px; + overflow: hidden; +} + +.t_title { + width: 100%; + height: 50px; + position: relative; +} + +.time_icon { + position: absolute; + width: 80.5px; + height: 32.5px; + top: 6px; + left: 1.5%; +} + +.timer { + border: 1px solid #f5394e; + border-radius: 3px; + /*width: 110px;*/ + height: 15px; + line-height: 13px; + font-size: 12px; + text-align: center; + position: absolute; + left: 28%; + top: 18px; + font-family: "微软雅黑"; +} + +.timer_left { + float: left; + background: #f5394e; + color: white; + width: 45px; +} + +.timer_right { + float: left; + color: #f5394e; +} + +.timer_more { + position: absolute; + right: 0; + width: 50px; + height: 20px; + top: 15px; +} + +.timer_more span { + color: #f5364c; + font-size: 12px; + position: absolute; + line-height: 20px; + height: 20px; + left: 0; + right: 0; +} + +.timer_more img { + width: 15px; + height: 15px; + position: absolute; + right: 20%; + top: 2px; +} + +.t_con { + width: 100%; +} + +#timer_swiper { + width: 100%; +} +#timer_swiper .swiper-wrapper .swiper-slide img{ + padding: 3px; + border-radius: 7px; +} +.t_con .swiper-container { + width: 800px; +} + +.t_con .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#timer_swiper .swiper-slide { + position: relative; +} + +#timer_swiper .swiper-slide img { + width: 100%; + display: block; + position: absolute; + top: 0; +} + +#timer_swiper .swiper-slide p { + position: absolute; + bottom: 25px; + text-align: center; + font-size: 14px; + color: #e51329; + width: 100%; + height: 21px; +} + +#timer_swiper .swiper-slide del { + text-align: center; + position: absolute; + bottom: 5px; + font-size: 12px; + color: #808080; + width: 100%; + height: 21px; +} + +.add { + background: white; + margin-top: 3px; + border-radius: 5px; +} + +.add_top { + width: 100%; + height: 212.5px; + border-bottom: 1px solid #EFEFF4; +} + +.add_top_left { + width: 41.5%; + border-right: 1px solid #EFEFF4; + float: left; + height: 212.5px; + position: relative; +} + +.p1 { + font-size: 15px; + position: absolute; +} + +.p2 { + color: black; + font-size: 13px; + position: absolute; +} + +.add_top_left .p1 { + background: linear-gradient(to right, #8b1afc, #f095ff); + -webkit-background-clip: text; + color: transparent; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + top: 27px; +} + +.add_top_left .p2, +.add_bottom_con .p2 { + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + top: 50px; +} + +.add_top_left img { + width: 70%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 15px; +} + +.add_top_right { + width: calc(100% - (41.5%+1px)); + float: left; + height: 212.5px; +} + +.add_top_right_con { + width: 100%; + height: 105.75px; + position: relative; +} + +.atrct { + border-bottom: 1px solid #EFEFF4; +} + +.add_top_right_con img { + width: 34%; + position: absolute; + top: 12px; + left: 8.5%; +} + +.add_top_right_con .p1 { + background: linear-gradient(to right, #f33334, #cc27f6); + -webkit-background-clip: text; + color: transparent; + top: 12px; + left: 50%; +} + +.add_top_right_con .p2 { + top: 40px; + left: 50%; +} + +.add_top_right .atrct .p1 { + background: linear-gradient(to right, #f58e66, #f64848); + -webkit-background-clip: text; + color: transparent; +} + +.add_bottom { + width: 100%; + height: 187.5px; +} + +.add_bottom_con { + width: 33.3%; + height: 187.5px; + float: left; + position: relative; +} + +.add_bottom_con .p1 { + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + top: 27px; +} + +#abc_1 .p1 { + background: linear-gradient(to right, #5ed62e, #2ed68d); + -webkit-background-clip: text; + color: transparent; +} + +#abc_1 { + border-right: 1px solid #EFEFF4; +} + +#abc_2 .p1 { + background: linear-gradient(to right, #6533f3, #33bbf3); + -webkit-background-clip: text; + color: transparent; +} + +#abc_2 { + border-right: 1px solid #EFEFF4; +} + +#abc_3 .p1 { + background: linear-gradient(to right, #f3336e, #3389f3); + -webkit-background-clip: text; + color: transparent; +} + +#abc_3 {} + +.add_bottom_con img { + width: 58%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 25px; +} + +.hot_shop { + width: 100%; + border-radius: 5px; + /*overflow: hidden;*/ + margin-top: 3px; + background: white; +} + +.hot_title { + width: 100%; + height: 50px; + position: relative; +} + +.hot_img { + width: 58.5px; + height: 41.5px; + position: absolute; + left: 0; + right: 0; + margin: 0 auto; + bottom: 15px; +} +.hotimg{ + width: 100%; +} +#hot_more { + bottom: 15px; +} + +.hot_banner { + width: 100%; +} + +#hot_banner { + width: 100%; + border-radius: 5px; + overflow: hidden; +} + +#hot_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + /*display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center;*/ +} + +#hot_banner .swiper-slide .hotimg img { + width: 92%; + margin: 0 auto; + height: 100%; + border-radius: 5px; + overflow: hidden; +} +#hot_banner_pageination{ + bottom: 60%; +} +#hot_banner .swiper-pagination-bullet-active { + background: white; +} + +#hot_banner .swiper-pagination-bullet { + background: #eee; +} +.hot_con{ + width: 100%; +} + +.hot_con_block { + width: 33.3%; + position: relative; + padding: 2%; + float: left; +} + +.hot_con_block_img { + width: 100%; + display: block; + border-radius: 5px; + overflow: hidden; +} + +.hcb_name { + margin-top: 5px; + width: 100%; + font-size: 13px; + color: black; + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} +.hcb_pay{ + font-size: 14px; + color: #e51329; + height: 21px; + margin-top: 5px; +} + + +.hot_bottom_icon{ + margin-top: 5px; + width: 40px; + height: 21px; + background: #ffd7d7; + position: relative; + border-radius: 15px; + overflow: hidden; +} +.hot_bottom_icon span{ + color: #E51329; + font-size: 10px; + right: 5px; + position: absolute; + height: 21px; + line-height: 21px; + top: 0; +} +.icon_star{ + width: 10px; + height: 10px; + position: absolute; + left: 4px; + top: 5px; +} + +.shadown_wai{ + overflow: inherit; +} diff --git a/static/app2/css/home_new.css b/static/app2/css/home_new.css new file mode 100755 index 0000000..15bf49e --- /dev/null +++ b/static/app2/css/home_new.css @@ -0,0 +1,192 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.1); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} +body{ + height: 100%; +} +.con { + overflow: hidden; +} + +.news marquee { + font-size: 12px; +} + +.sx { + margin-top: -50px; + height: 50px; + width: 100%; + text-align: center; + font-size: 12px; +} + +.header { + width: 100%; + height: 64px; + /* padding-top: 20px; */ + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 111111111; + background-color: rgba(0, 0, 0, 0); +} + +.header_con { + position: relative; + width: 100%; + height: 44px; +} + +#search { + margin: 0; + width: 65%; + height: 31px; + position: absolute; + left: 13.8%; + right: 21%; + top: 7px; + border-radius: 16px; + border: none; + /*text-indent: 20px;*/ + background-color: rgb(255, 255, 255); + font-size: 11px; + line-height: 34px; + text-indent: 30px; +} + +.searchimg { + width: 12.5px; + height: 12.5px; + position: absolute; + top: 17px; + left: 16.4%; +} + +.search input { + margin: 0; + height: 30px; + border: none; + border-radius: 0; + background: transparent; + padding: 0 40px; + /*padding-left: 50px;*/ +} + +.search select { + border: 1px solid red; + position: absolute; + width: 50px; + height: 29px; + padding: 0; + text-align: center; + border-radius: 0; + padding-left: 0px; + padding-top: 2px; + background: transparent; +} + +.search button { + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; + border-radius: 50px; +} + +.saoyisao { + position: absolute; + padding: 5px 10px 0; + width: 52.5px; + height: 37.5px; + top: 1.5px; + right: 1.0%; +} + + + + + +.mui-scroll-wrapper, +.scroll_out { + /*position: relative;*/ + z-index: 10; +} +#pullrefresh .mui-scroll{ + position: relative; +} +#top_banner { + width: 100%; + height: 300px; + margin: 20px auto; + margin: 0; + position: relative; +} + +#top_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#top_banner .swiper-slide img { + width: 100%; + height: 100%; +} + +#top_banner .swiper-pagination-bullet-active { + background: white; +} + +#top_banner .swiper-pagination-bullet { + background: #eee; +} + +.mui-scroll-wrapper {} + +.lxy_home_zz img{ + width: 100%; + position: absolute; + top: 50%; + left: 0; + right: 0; + margin: 0 auto; + transform: translateY(-50%); +} +.lxy_home_zz input{ + width: 80%; + margin: 40% auto; + height: 25px; + +} \ No newline at end of file diff --git a/static/app2/css/income-details.css b/static/app2/css/income-details.css new file mode 100755 index 0000000..348a9a2 --- /dev/null +++ b/static/app2/css/income-details.css @@ -0,0 +1,74 @@ + + +.idc-total{ + width: 96%; + margin: 0 auto 8px; + height: 60px; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding-left: 5px; + + /* border-bottom: 1px solid #ccc; */ +} +.idc-total h5 { + width: 80%; +} +.idc-total span{ + font-size: 18px; + margin-right: 10px; +} +.idc-list{ + width: 96%; + height: 120px; + background: #FEEAE9; + margin: 0 auto; + /* background: #fff; */ + display: flex; + flex: 1; + align-items: flex-start; + justify-content: space-between; + /* border-bottom: 1px solid #ccc; */ + border: 1px solid #FEEAE9; + border-radius: 5px; + margin-bottom: 8px; + padding-left: 5px; +} +.idc-list-price { + /* flex: 0 0 30%; */ + +} +.idc-list-right { + /* flex: 0 0 70%; */ + flex-direction: column; + justify-content: space-around; + align-items: flex-start; + padding-left: 30px; + position: relative; +} +.idc-list-title { + width: 200px; + font-size:15px; + font-weight: 200; + margin-bottom: 10px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +.idc-list-price { + font-size:15px; + color: #F02C43; +} +.idc-list-user{ + + font-size: 13px; + margin-bottom: 15px; + +} +.idc-list-time { + width: 50%; + font-size:12px; + /* color: #F02C43; */ + bottom: 10px; +} \ No newline at end of file diff --git a/static/app2/css/indent.css b/static/app2/css/indent.css new file mode 100755 index 0000000..92d3fbe --- /dev/null +++ b/static/app2/css/indent.css @@ -0,0 +1,48 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 100px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} + +.footer{ + position: fixed; + bottom: 0; + width: 100%; + background: white; + height: 49px; + border-top: 1px solid #e6e6e6; +} diff --git a/static/app2/css/indentcon.css b/static/app2/css/indentcon.css new file mode 100755 index 0000000..7642a75 --- /dev/null +++ b/static/app2/css/indentcon.css @@ -0,0 +1,282 @@ +.search { + padding: 7.2px 12px; + background: #ebebeb; +} + +.mui-search {} + +.mui-search .mui-placeholder { + background: #fff; +} + +.mui-search input { + background: #fff; + margin-bottom: 0; +} + +.mui-active::before { + margin-top: -10px; +} + +.row_title { + width: 100%; + position: relative; + height: 36px; + background: white; + display: flex; + justify-content: space-between ; + align-items: center; +} + +.store_name { + /* position: absolute; */ + /*background: url(../img/youjiantou.png) no-repeat center right;*/ + /*background-size: 6px;*/ + /* padding-right: 12px; + padding-left: 18px; */ + line-height: 36px; + font-size: 14px; +} + +.indent_status { + /* position: absolute; */ + line-height: 36px; + font-size: 13px; + /* right: 0; + padding-right: 12px; + float: right; */ +} +.yellow{ + color: #ffa800; +} +.shopPhone{ + color:tomato; +} +.shopPhone a{ + text-decoration:underline; + color:tomato; + +} +.confirm_wait{ + color: cadetblue; +} +.confirm_ok{ + color: seagreen; +} +.confirm_no{ + color:red; +} +.row{ + margin-bottom: 5px ; + background: white; + padding: 5px 10px; +} +.row_block { + width: 100%; + /*height: 128px;*/ + border-bottom: 2px solid #fff; + /*background: #efefef;*/ +} + +.row_block img { + width: 117px; + height: 126px; + float: left; + padding: 9px 0 9px 9px; +} + +.rcr { + width: calc(100% - 117px); + float: right; + /*height: 126px;*/ + padding: 12px; + background: #efefef; +} + +.rcrc { + float: left; + width: calc(100% - 60px); +} + +.rcrc p { + height: 42px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 12px; + color: black; +} + +.rcrc .leibie{ + color: #909090; +} + + +.rcrr { + width: 60px; + float: right; + text-align: right; +} + + + +.rcrr p { + color: black; + font-size: 12px; +} + +.rcrr del { + color: #909090; + font-size: 12px; + display: block; +} + +.rcrr span { + color: #909090; + font-size: 12px; +} +.combination{ + width: 100%; + height: 37px; + border-bottom: 1px solid #e6e6e6; + background: white; + text-align: right; + font-size: 12px; + line-height: 36px; + padding-right: 15px; +} +.combination o{ + font-size: 14.4px; +} +.btns{ + text-align: right; + width: 100%; + height: 48px; + /*background: white;*/ +} +.btns_btn{ + color: black; + font-size: 12px; + padding:4px 6px 0px; + float: right; + /* line-height: 48px; */ + margin: 9.5px 6px; + border-radius: 30px; + background: -moz-linear-gradient(left, #fcff00, #ffde00); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#fcff00), to(#ffde00)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #fcff00, #ffde00); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #fcff00, #ffde00); + /*Opera11*/ + box-shadow: 1px 1px 5px #ffde00; + +} +.btns .kk{ + border: 1px solid #e6e6e6; + border-radius: 1px; +} + +.btns .qrsh{ + border: 1px solid #e5132c; + color: #e5142a; +} + +.bg_{ + position: fixed; + top: 0; + right: 0; + bottom: 0px; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_ts{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_con{ + width: 90%; + /*height: 160px;*/ + background: white; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + bottom: 10px; + /* top: 30%; */ + border-radius: 5px; +} +.bg_con p{ + border-bottom: 1px solid #efefef; + padding:10px 20px; + color: black; +} +.bg_con .info1{ + padding:10px 20px; + color: black; + border-bottom: none; +} +.en_true,.ts_true{ + background: #2AC845; + color: white; + /*position: absolute;*/ + margin-left: 30%; + border: none; + margin-top:10px; + margin-bottom: 5%; +} +.en_false,.ts_false{ + background: #efefef; + color: #909090; + /*position: absolute;*/ + margin-right: 30%; + margin-top:10px; + + border: none; + float: right; +} +#content,#content_ts,#Tmoney{ + margin: 0 5% 5%; + width: 90%; +} +.refundInfo{ + float:left; +} +.refundTxt{ + display: block; + margin: 0 5% 5%; + width: 90% !important; +} +select{ + /*margin: 0;*/ +} +.row_block{ + background: #fbfbfb; +} +.row_block img{ + border-radius: 3px; + overflow: hidden; +} +.rcr { + background: #FBFBFB; +} + +/*20181018*/ +#select{ + margin: 5px 5%; + border: 1px solid rgba(0,0,0,.2)!important; + /*background: red;*/ + width: 90%; +} diff --git a/static/app2/css/index.css b/static/app2/css/index.css new file mode 100755 index 0000000..7757183 --- /dev/null +++ b/static/app2/css/index.css @@ -0,0 +1,63 @@ +body{ + background: white; +} + +body .mui-bar-tab { + height: 50px; + background: white; + z-index: 999; +} +body .mui-bar-tab{ + height: 50px; +} +.mui-bar .mui-tab-item .mui-icon img { + height: 35px; +} +.mui-bar .mui-tab-item .mui-icon{ + padding: 0; + width: 50px; +} +.mui-bar .mui-tab-item{ + height: 50px; +} +.mui-bar{ + width: 100%; + height: 50px; +} +.mui-bar-tab{ +} +.mui-bar-tab .mui-tab-item .mui-icon{ + top:1; +} +.mui-bar-tab,.mui-bar{ + box-shadow: none +} +.mui-icon{ + position: relative; +} +.nav_in{ + position: absolute; + left: 0; + right: 0; + margin: 0 auto; +} + + +.shun{ + animation: shun 1s; + animation-timing-function: ease-in-out; +} + +.ni{ + animation: ni 1s; + animation-timing-function:ease-in-out; +} + +@keyframes shun{ + from{transform: rotate(0deg);} + to{transform: rotate(360deg);} +} +@keyframes ni{ + from{transform: rotate(0deg);} + to{transform: rotate(-720deg);} +} \ No newline at end of file diff --git a/static/app2/css/individual.css b/static/app2/css/individual.css new file mode 100755 index 0000000..739920f --- /dev/null +++ b/static/app2/css/individual.css @@ -0,0 +1,302 @@ +.individual-title { + height: 60px; + width: 100%; + /* background: #000000; */ + text-align: center; + padding-top: 30px; + /* font-size: 18px; */ + display: flex; + justify-content: space-between; + align-items: center; +} + +.individual-title a { + display: inline-block; + width: 23px; + height: 23px; + background: #242424; + border-radius: 23px; + color: #fff; + padding-top: 3px; + margin-top: 25px; +} +.individual-title span { + display: inline-block; + width: 40px; + font-size: 16px; +} +.mui-action-back { + font-size: 20px; + /* height: 20px; */ + position: absolute; + + left: 15px; + z-index: 100; +} + +.individual-title h3 { + display: inline-block; + width: 80%; + text-align: center; + font-size: 16px; + color: ##c0c0c0; + /* height: 60px; */ + /* padding-top: 35px; */ + padding-left: 50px; + /* margin-top: -3px; */ +} + +.mui-table-view-cell { + width: 100%; + /* height: 50px; */ + display: flex; + justify-content: space-between; + align-items: center; + +} +#headerimg img { + width: 100%; + height: 100%; +} +.mui-table-view-cell label { + width: 35%; + text-align: left; + padding: 0px; + font-size: 15px; +} + +/* .mui-input-row input{ */ +.mui-table-view-cell input ,.mui-table-view-cell p,.mui-table-view-cell textarea{ + padding: 0px; + /* width:calc(100%-100px); */ + font-size: 15px; + margin: 0px; + border: 0px; + text-align: right; +} + + +.addresscon { + width: 100%; + height: 50px; + line-height: 50px; +} + +.addresscon textarea { + display: inline-block; + width: 50%; + height: 50px; + margin: 0px; + padding: 0px; + border: 0px; +} + +.addresscon label { + display: inline-block; + /* width:60px; */ +} + +.addresscon textarea::-webkit-input-placeholder { + text-align: right; + height: 50px; + line-height: 50px; + font-size: 15px; +} + +.mui-table-view-cell input::-webkit-input-placeholder { + text-align: right; +} + +.mui-input-row { + width: 100%; +} + +.mui-table-view-cell .mui-table-view-cell-head { + display:block; + /* width:120px; */ + /* height: 100px; */ + /* background: pink; */ + padding-top: 7px; + + +} + +.mui-table-view-cell-img { + display: block; + width: 50px; + height: 50px; + border-radius: 50px; + overflow: hidden; + float: left; +} +.mui-table-view-cell-img img { + width: 100%; +} +.photo{ + align-self: stretch; + display: inline-block; + width:30% ; +} +.longstr{ + align-self: stretch; + display: inline-block; + width:50% ; + font-size: 15px; +} +.photoimg { + width: 70%; + text-align: right; + overflow: hidden; +} +.info{ + position: relative; + /* display: inline-block; */ + width:37% ; + font-size: 12px; + bottom: 3px; + color: #aaa; +} +.ossfile{ + display: inline-block; + width: 80px; + height: 80px; + /* background: #ccc; */ + /* border: 1px solid #ccc; */ + border-radius: 3px; + position: relative; +} +.ossfile .files_out{ + width: 100%; + height: 100%; +} +.ossfile img{ + width: 100%; + height: 100%; + +} + +.photoimg .mui-icon{ + position: absolute; + top:28px; + left: 30px; + color: #fff; +} +.qrbb ,.qrrz { + height: 60px; +} +.qrbb p,.qrrz p{ + display: inline-block; + width: 50%; + color: #6E6E6E; + font-size: 15px; +} +.mui-table-view-cell-img img { + width: 100%; +} + + +.pheight{ + height: 40px; + line-height: 40px; +} +.thumbnail-img { + width: 100px; + height: 100px; + text-align: center; + background: #fff; + position: relative; + float: left; + /* margin: 0 auto; */ +} + +.thumbnail-img .mui-icon { + width: 70px; + height: 70px; + font-size: 40px; + padding-top: 20px; +} +.thumbnail-img p { + text-align: center; +} +.mui-table-view-cell-img-img { + position: relative; + float: left; + padding-left: 200px; +} +.mui-table-view-cell-hkimg { + /* width:300px; + overflow: hidden; + position: relative; */ + float: left; + /* padding-left: 100px; */ + /* height: 100px; */ + /* background: pink; */ +} +.mui-table-view-cell-hkimg .files_out{ + width: 100px; + height: 100px; + float: left; +} +.mui-table-view-cell-hkimg .files_out img{ + width: 100%; + height: 100px; +} +.hkimg { + width: 100%; + display: none; +} + +.YZTEL{ + margin: 50px auto; + width: 80%; +} +.YZTEL .mui-table-view-cell{ + padding: 5px; +} +.YZTEL label{ + width:25%; +} + + +.mui-table-view .mui-table-view-cell .indiv-tel { + width: 80%; + /* text-align: left; */ + +} +.mui-table-view .mui-table-view-cell .YZM { + display: inline-block; + width: 50%; + text-align: center; +} +.mui-table-view .mui-table-view-cell .YZM::-webkit-input-placeholder{ + text-align: center; +} +.mui-table-view .mui-table-view-cell .HQYZM { + width: 40%; + height: 30px; + font-size: 16px; + line-height: 30px; + color: #8E8E8E; + /* background: #ccc; */ + text-align: center; + border-radius: 5px; + border: 1px solid #ccc; +} +.mui-btn-block { + height: 30px; + line-height: 1px; + width: 70%; + margin:30px auto; + } + .bc_btn { + height: 30px; + line-height: 30px; + + + text-align: center; + width: 70%; + margin: 30px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; + } diff --git a/static/app2/css/invest.css b/static/app2/css/invest.css new file mode 100755 index 0000000..272aa47 --- /dev/null +++ b/static/app2/css/invest.css @@ -0,0 +1,155 @@ +.con_ { + width: 98%; + margin: 5px auto ; + display: flex; + /* justify-content: space-between; */ + align-items: center; + flex-direction: column; + /* padding: 10px; */ +} +.con_ .top{ + width: 100%; + display: flex; + /* justify-content: space-between; */ + align-items: center; + flex-direction: row; + padding: 10px; + font-size: 14px; + background: #fff; +} +.con_ .bottom{ + width: 100%; + display: flex; + justify-content: flex-start; + align-items: center; + flex-direction: row; + padding: 10px; +} +.con_ .bottom .img { + width: 20px; + height: 20px; +} +.con_ .bottom .img img { + width: 100% ; + height: 100%; +} +.con_ .bottom .pos { + font-size: 15px; +} +.con_ .left { + width: 78px; + height: 78px; + margin-right: 10px ; + /* padding-right: 5px; */ + border-radius: 78px; + border: 3px solid #CF2D28; + overflow: hidden; +} +.con_ .left img { + width: 100%; + height: 100%; +} +.con_ .mid { + flex: 1; + display: flex; + justify-content: space-around; + align-items:flex-start ; + flex-direction: column; + height: 78px; + font-size: 18px; + +} +.con_ .mid .partner { + font-size: 15px; +} +.con_ .mid .timer{ + font-size: 15px; + } +.con_ .right .scale { + width: 78px; + height:78px; + border: 3px solid #CF2D28; + border-radius: 78px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + font-size: 18px; +} +.con_ .right .scale p { + font-size: 18px; +} +.shopName { + margin-bottom: 10px; + text-align: center; +} + +/* 分配券值 start*/ +.nav{ + width: 100%; + height: 40px; + display: flex; + justify-content: space-between; + align-items: center; +} + .nav-item { + width: 50%; + text-align: center; + color: #1D1D1D; +} +.active{ + border-bottom: 1px solid #C24F4A; + color:#C24F4A ; +} +.content .content_ .title { + height: 60px ; + width: 98%; + margin: 0px auto; + text-align: center; + font-size: 18px; + background: #fff; + line-height: 60px; +} +.row { + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + margin: 0px auto; + background: #fff; + padding: 10px 2px; +} +.row label{ + min-width: 100px; +} +.row input { + margin: 0px; + padding: 0px 3px; + text-align: right; + border: 0px; +} +/* 分配券值 end*/ +/* 按钮*/ +.down { + margin: 55px auto ; + +} +.down .btn { + margin: 0px auto ; + width: 200px; + height: 40px; + line-height: 40px; + text-align: center; + padding: 10px auto; + background: #DD524D; + font-size: 18px; + font-weight: 200; + color: #FDECEA; +} + + + + + + + diff --git a/static/app2/css/investdetail.css b/static/app2/css/investdetail.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/journalism.css b/static/app2/css/journalism.css new file mode 100755 index 0000000..b3051db --- /dev/null +++ b/static/app2/css/journalism.css @@ -0,0 +1,80 @@ +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); +} + +.nav { + width: 100%; + height: 40px; + background: white; + border-top: 1px solid #ececec; + border-left: 1px solid #ececec; +} + +.con_ { + margin-top: 1px; +} + +.nav_block { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; + text-align: center; +} + +body .mui-scroll-wrapper .mui-scroll .con .nav #timer_swiper .on .p1{ + color: #ee344a; + border-bottom: 4px solid #ed374c; +} +#timer_swiper .p1{ + text-align: center; + display: inline-block; +} +.con_block { + width: 100%; + height: 120px; + background: #fff; + position: relative; +} + +.cbimg { + width: 88px; + height: 88px; + position: absolute; + left: 16px; + top: 16px; +} + +.cbtitle { + width: calc(100% - 140px); + position: absolute; + left: 120px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + color: black; + font-size: 13px; + top: 18px; +} + +.name{ + font-size: 10px; + color: #808080; + position: absolute; + left: 120px; + top: 60px; +} +.name img{ + width: 17.5px; +} diff --git a/static/app2/css/journalism_con.css b/static/app2/css/journalism_con.css new file mode 100755 index 0000000..addf1c4 --- /dev/null +++ b/static/app2/css/journalism_con.css @@ -0,0 +1,67 @@ +.con_ { + width: 100%; + background: white; +} + +.con_ .con_top { + width: 100%; + height: 92px; + position: relative; +} + +.headImg { + position: absolute; + width: 50px; + height: 50px; + border-radius: 50%; + overflow: hidden; + left: 21px; + top: 21px; +} + +.con_top_title { + position: absolute; + width: calc(100% - 140px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 15px; + color: #101010; + left: 80px; + top: 25px; +} + +.num{ + color: #808080; + font-size: 12px; + position: absolute; + left: 80px; + top: 45px; +} +.guanzhu{ + position: absolute; + padding: 2px 10px; + background: #ED374C; + color: white; + border: none; + right: 10px; + top: 30px; +} +.con_con p{ + font-size: 13px; + color: #101010; + padding: 0 2%; +} + +.con_con img{ + width: 100%; + display: block; +} +.time{ + width: 100%; + height: 50px; + font-size: 12px; + color: #808080; + line-height: 50px; + padding-left: 75%; +} diff --git a/static/app2/css/login.css b/static/app2/css/login.css new file mode 100755 index 0000000..460f3a8 --- /dev/null +++ b/static/app2/css/login.css @@ -0,0 +1,350 @@ +.con { + margin-top: 78px; + +} + +.top { + margin-top: 5px; +} + +.header .header_con .title { + /* margin-top: 40px; */ + line-height: 22px; +} + +.logincon { + margin-top: 11px; +} + +.loginbg .header { + background-color: rgba(256, 256, 256, 0.4); +} + +.login_con { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; +} + +.login_con .con { + /* 控制登录页面 */ + margin-top: 0px; +} + +.login_con .con .row { + display: flex; + justify-content: flex-start; + align-items: center; + width: 100%; + height: 42px; + background: white; + border-top: 1px solid #e6e6e6; +} + +.commercial .con, +.supermarket .con, +.shangdu .con { + /* 控制申请商厦 申请商超 申请商都 页面 */ + margin-top: 0px; +} + +.logintop { + width: 98%; + margin: 0 auto 11px; + /* background: #ccc; */ + text-align: center; + padding: 10px; + +} + +.logintop h3 { + font-size: 20px; + margin: 23px auto 33px; + color: #E51329; +} + +.logintop p { + margin: 10px auto; + font-size: 18px; + color: #E51329; +} + +.row { + display: flex; + justify-content: flex-start; + align-items: center; + width: 100%; + height: 42px; + background: white; + border-top: 1px solid #e6e6e6; +} + +.row img { + width: 25.2px; + height: 25.2px; + /* float: left; */ + margin: 7px; + display: inline-block; +} + +.row span { + display: inline-block; +} + +.s_reg { + /* float: left; */ + min-width: 100px; + line-height: 42px; + color: #525252; + font-size: 16px; +} + +.s1 { + /* float: left; */ + /* min-width: 60px; */ + line-height: 42px; + color: #525252; + font-size: 17px; + white-space: nowrap; + /* flex: 1.2; */ +} + +.con .row input { + /* float: left; */ + margin: 0; + width:auto ; + border: none; + font-size: 17px; +} + +.con .row input::-webkit-input-placeholder { + font-size: 17px; +} + +.down { + width: 100%; + padding: 12px; + margin: 15px auto; +} + +.down .btn { + width: 100%; + height: 42px; + text-align: center; + line-height: 42px; + color: white; + background: #f02c43; + padding: 0; +} + +.s2 { + color: #525252; + font-size: 17px; + display: block; + margin-top: 10px; +} + +.pNameCode .s99 { + min-width: 60px; +} + +#register { + float: left; +} + +#fogetpsd { + float: right; +} + +.ac1_left { + width: 100%; + height: 66px; + position: relative; + line-height: 66px; +} + +.con .row .yzm{ + width: 100%; +} +.con .row .tpyzm { + width: calc(100% - 210px); +} + +.con .row #mobileCode, +.con .row #mobileCode1 { + /* width: 110px; */ + float: right; + margin-top: 4px; + text-align: center; + height: 33px; + line-height: 33px; + border-left: 1px solid #e6e6e6; + color: #909090; + font-size: 17px; + padding: 0; + +} +#getMobileCode{ + font-size: 17px; + float: right; +} +.row .yzmhh { + width: 100px; + height: 31px; + margin-top: 5px; +} + +.bottom { + position: relative; + bottom: 10px; + /* background: #ccc; */ + width: 98%; + margin: 7px auto; + +} + +.bottom-con { + display: flex; + justify-content: space-between; + width: 77%; + margin: 33px auto; + +} + +.bottom p { + display: inline-block; + width: 10px; + color: #E51329; + font-size: 17px; + padding-top: 5px; +} + +.zcxy { + /* margin-top: 22px; */ +} + +.zcxytitle { + width: 97%; + height: 36px; + line-height: 36px; + margin: 0px auto 10px; + font-size: 14px; + color: #333333; + background: #fff; + /* box-shadow: 2px 2px 5px rgba(25, 25, 25, 0.2); */ + +} + +.zcxytitle label { + padding: 8px 5px; + font-size: 17px; + +} + +.zcxy .zcxycontent, .con .zcxycontent { + + width: 97%; + margin: 0px auto; + background: pink; + overflow-y: scroll; + height: 300px; + background: #fff; + padding: 10px 4PX; + /* overflow: auto; */ +} + +.zcxycontent h3 { + font-size: 15px; + text-align: center; +} + +.zcxycontent::-webkit-scrollbar { + background: hotpink; + /* display: none!important; */ + width: 0px; + height: 0px; +} + +.hkimg { + width: 100%; + display: none; +} + +.mui-table-view-cell-hkimg { + float: left; +} + +.thumbnail-img { + float: left; + width: 100px; + height: 100px; + text-align: center; + /* background:pink; */ + /* margin: 0 auto; */ +} + +.thumbnail-img .mui-icon { + width: 70px; + height: 70px; + font-size: 40px; + padding-top: 20px; +} + +.mui-table-view-cell-hkimg .files_out { + width: 100px; + height: 100px; + margin: 0 auto; + float: left; +} + +.mui-table-view-cell-hkimg .files_out img { + width: 100%; + height: 100%; +} + +.renzhengphoto { + width: 98%; + margin: 10px auto 0px; + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + padding: 7px; + /* flex: 1; */ +} + +.renzhengphoto label { + width: 100px; + font-size: 13px; + color: #363636; + align-self: flex-start; +} + +.renzhengphoto .photos span { + font-size: 12px; + height: 20px; + /* padding-left: 5px; */ +} + +.ossfile { + display: inline-block; + width: 80px; + height: 80px; + background: #ccc; + border: 1px solid #ccc; + border-radius: 5px; + position: relative; +} + +.files_out { + text-align: center; + padding-top: 24px; +} + +.photos span { + display: inline-block; + font-size: 10px; + color: #959595; + +} diff --git a/static/app2/css/logistics.css b/static/app2/css/logistics.css new file mode 100755 index 0000000..240a1a6 --- /dev/null +++ b/static/app2/css/logistics.css @@ -0,0 +1,117 @@ +body .header1 { + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ +} + +.header1 .p1 { + color: white; +} + +.header1 .mui-action-back { + color: white; +} + +.summarize { + border-bottom: 6px solid #efefef; + background: white; +} + +.summarize img { + float: left; + width: 54px; + height: 54px; + margin: 15px 12px; +} + +.summarizeinfo { + float: left; + width: calc( 100% - 78px); + padding: 3px 0; +} + +.pp1 { + color: #525252; + font-size: 14.4px; +} + +.pp1 o { + color: #e51329; +} + +.pp2 { + color: #525252; + font-size: 12px; +} + +.pp2 o { + color: #e51329; +} + +.track-list { + position: relative; + background: white; +} + +.track-list ul { + margin: 0; + padding-left: 20px; + +} + +ul li { + list-style: none; +} + +.track-list li { + position: relative; + padding: 9px 0 0 25px; + line-height: 18px; + border-left: 1px solid #d9d9d9; + color: #999; +} + +.track-list li.first { + color: red; + padding-top: 9px; + border-left-color: #fff; +} +.track-list li.first p{ + color: #72ca87; +} +.track-list li .node-icon { + position: absolute; + left: -6px; + top: 50%; + width: 11px; + height: 11px; + background: url(../img/order-icons.png) -21px -72px no-repeat; +} + +.track-list li.first .node-icon { + background-position: 0 -72px; +} + +.track-list li .time { + margin-right: 20px; + border-bottom: 1px solid #e6e6e6; + padding-bottom: 9px; +} + +.track-list li .txt { + padding-bottom: 3px; + margin-right: 20px; +} + +.track-list li.first .time { + margin-right: 20px; +} + +.track-list li.first .txt { + max-width: 600px; +} \ No newline at end of file diff --git a/static/app2/css/map.css b/static/app2/css/map.css new file mode 100755 index 0000000..ea670c6 --- /dev/null +++ b/static/app2/css/map.css @@ -0,0 +1,331 @@ +body { + background: #ebebeb; +} +.header { + width: 10rem; + height: 1.25rem; + background: #f23249; +} +.header img { + width: 0.171875rem; + height: 0.5rem; + float: left; + margin-top: 0.375rem; + margin-left: 0.4375rem; +} +.header p { + font-family: "微软雅黑"; + font-size: 0.46875rem; + color: #fff; + line-height: 1.25rem; + margin-left: 4.0625rem; +} +/*header end*/ +.rz_input { + width: 10rem; + background: #fff; + margin-top: 0.3125rem; +} +.rz_input img { + width: 0.5625rem; + height: 0.546875rem; + float: left; + margin-left: 0.234375rem; + margin-top: 0.234375rem; +} +.rz_input .mc .phone { + width: 0.421875rem; + height: 0.546875rem; + margin-right: 0.125rem; +} +.rz_input input { + width: 7.8125rem; + height: 1.015625rem; + margin-left: 0.359375rem; + float: left; + border: none; +} +.mc { + border-bottom: 1px solid #e6e6e6; +} +/*用户名... ed*/ +.time { + width: 10rem; + height: 1.09375rem; + background: #fff; + margin-top: 0.15625rem; + margin-bottom: 0.15625rem; + position: relative; +} +.time p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + line-height: 1.09375rem; + margin-left: 0.265625rem; + float: left; +} +.time #stime { + width: 2.03125rem; + height: 0.78125rem; + text-align: center; + position: absolute; + left: 2.390625rem; + top: 0.125rem; +} +.time #etime { + width: 2.03125rem; + height: 0.78125rem; + text-align: center; + position: absolute; + left: 4.96875rem; + top: 0.125rem; +} +/*time ed*/ +.location { + width: 10rem; + height: 3.5625rem; + background: #fff; +} +.location p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + float: left; + margin-left: 0.28125rem; + margin-top: 0.4375rem; +} +.location select { + width: auto; + padding: 0 1.71875rem; + height: 0.921875rem; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + float: left; + margin-top: 0.25rem; + margin-left: 0.46875rem; +} +/*location ed*/ +.classification { + width: 10rem; + height: 2.421875rem; + background: #fff; + margin-top: 0.1875rem; +} +.classification p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + color: #222222; + float: left; + margin-left: 0.28125rem; + margin-top: 0.46875rem; +} +.business_fenlei { + position: relative; +} +.business_fenlei select { + width: auto; + padding: 0 1.71875rem; + height: 0.921875rem; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + float: left; + margin-top: 0.25rem; + margin-left: 0.46875rem; +} +#cat_id_2 { + position: absolute; + top: 1.09375rem; + left: 1.65625rem; +} +/*classification ed*/ +.License { + width: 10rem; + height: 3.796875rem; + background: #fff; + margin-top: 0.1875rem; +} +.upload { + width:100%; + height: 0.859375rem; + border-bottom: 1px solid #e6e6e6; +} +.upload p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + line-height: 0.859375rem; + margin-left: 0.296875rem; +} +/*License ed*/ +.position { + width: 100%; + /* height: 19.53125rem; */ + background: #fff; + margin-top: 0.1875rem; + position: relative; +} +#r-result { + display: flex; + justify-content: space-between; + align-content: center; + height: 30px; + width: 100%; + } + +#r-result p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + width: 100px; + margin-left: 0.296875rem; + margin-top: 0.359375rem; +} +#r-result input { + width:-webkit-calc(100%-100px); + height: 0.890625rem; + margin: 0px; + /* margin-left: 0.46875rem; */ + /* margin-top: 0.15625rem; */ + text-align: center; +} +.points,.right{ + display: flex; + justify-content: space-between; + align-items: center; +} +.points p { + font-family: "微软雅黑"; + font-size: 0.34375rem; + /* float: left; */ + margin-left: 0.296875rem; + margin-top: 0.359375rem; +} +#lng, +#lat { + width: 100px; + /* float: left; */ + margin-left: 0.203125rem; + margin-top: 0.390625rem; + margin-bottom: 0.15625rem; +} +#allmap { + width: 100%; + height: 12.03125rem; + + /* position: absolute; */ + left: 0.234375rem; +} +.map_title { + font-family: "微软雅黑"; + font-size: 0.375rem; + color: #222222; +} +.describe { + position: absolute; + width: 9.6875rem; + height: 6.25rem; + bottom: 1.875rem; + left: 0.125rem; +} +#shop_info { + resize: none; + width: 9.6875rem; + height: 5.46875rem; +} +.qdtj_btn { + width: 9.375rem; + height: 1.09375rem; + background: #f02c43; + position: absolute; + bottom: 0.15625rem; + left: 0.296875rem; + text-align: center; + font-size: 0.40625rem; + color: #fff; + line-height: 1.09375rem; +} +/*btn ed*/ +/*上传图片 start*/ +.container { + width: 55%; + margin-right: 25px; + float: left; +} +.weui_cell { + padding: 0; +} +.weui_cell, +.weui_cell_bd, +.weui_cell_primary, +.weui_cells, +.weui_cells_form { + border: none; + margin: 0; +} +.weui_cells_form::before, +.weui_cells_form::after { + border: none; +} +.weui_uploader_file { + position: relative; +} +.wuf { + float: left; + margin-right: 9px; + margin-bottom: 9px; + width: 79px; + height: 79px; + background: no-repeat center center; + background-size: cover; + position: relative; +} +.del_btn { + width: 20px; + height: 20px; + background: red; + border-radius: 50%; + display: inline-block; + text-align: center; + line-height: 20px; + font-size: 14px; + color: white; + position: absolute; + right: 0; + top: 0; +} +/*上传图片 end*/ +*{ + -webkit-tap-highlight-color: transparent; + +} + + + + #allmap table { + border-collapse:collapse; /*让表格边框细线*/ + border-spacing:0; /*清除边框间距*/ +} + #allmap fieldset,img { + border:0 none; /*有些浏览器默认这些标签有边框,所以要清除默认边框*/ + display:block; +} + #allmap address,#allmap caption,#allmap cite, #allmap code,#allmap dfn, #allmap em,#allmap i,#allmap u,#allmap b,#allmap strong, #allmap th,#allmap var { + font-style:normal; + font-weight:normal; + /*清除标签默认文本样式和加粗*/ +} +#allmap input,#allmap textarea{ + outline:0 none;/*去掉文本框的默认轮廓线*/ +} + #allmap ol,#allmap ul { + list-style:none; /*清除列表默认样式*/ +} +#allmap caption,#allmap th { + text-align:left; /*清除标签默认文本居中对齐*/ +} +#allmap h1,#allmap h2,#allmap h3,#allmap h4,#allmap h5,#allmap h6 { + font-size:100%; + font-weight:normal; /*清除标题标签的默认样式*/ +} +#allmap a{ + text-decoration:none;/*大部分页面中的链接没有下划线*/ +} \ No newline at end of file diff --git a/static/app2/css/memorandumlist.css b/static/app2/css/memorandumlist.css new file mode 100755 index 0000000..c2caf0e --- /dev/null +++ b/static/app2/css/memorandumlist.css @@ -0,0 +1,82 @@ +.con .content { + display: flex; + justify-content: space-between; + flex-direction: column; + /* align-items: center; */ + width: 98%; + margin: 0 auto; + margin-bottom: 5px; + background: #fff; +} +.content .top { + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + padding: 5px; +} +.content .top .title { + flex: 1; +} +.content .top .img { + width: 40px; + height: 40px; + margin-right: 10px; +} +.content .top .img img { + width: 100%; + height: 100%; +} +.content .top .oper { + width: 100px; + height: 40px; + align-self: flex-end; + margin-right: 10px; + display: flex; + justify-content: space-between; + align-items: center; +} +.content .top .oper .del{ + width: 30px; + height: 30px; +} +.content .top .oper .del img { + width: 100%; + height: 100%; +} +.content .top .oper .bj{ + width: 30px; + height: 30px +} +.content .top .oper .bj img { + width: 100%; + height: 100%; +} +.content .bottom { + display: flex; + justify-content: space-between; + align-items: center; + margin: 5px; + font-size: 15px; +} +.add1{ + width: 96%; + margin: 35px auto; + height: 63px; + background:#C9C9C9; + border:1px solid #C9C9C9; + border-radius: 5px; + display:flex; + justify-content: center; + align-items:center ; + /* margin-top: 10px; */ + } + .addimg{ + width: 40px; + height: 40px; + } + .add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + } \ No newline at end of file diff --git a/static/app2/css/msg.css b/static/app2/css/msg.css new file mode 100755 index 0000000..0391605 --- /dev/null +++ b/static/app2/css/msg.css @@ -0,0 +1,68 @@ +.con1 { + border-bottom: 6px solid #efefef; +} + +.row { + width: 100%; + height: 60px; + background: white; + border-bottom: 1px solid #e6e6e6; +} + +.row .img { + width: 45px; + height: 45px; + margin: 7.5px; + float: left; + border-radius: 5px; + overflow: hidden; +} +.row .img img{ + width: 100%; + height: 100%; +} + +.r_right { + width: calc(100% - 60px); + float: left; + padding: 9px; +} + +.r_right p { + margin: 0; +} + +.rrt_left { + float: left; + font-size: 14.4px; + color: black; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: calc(100% - 160px); +} + +.rrt_right { + float: right; + font-size: 13.2px; + color: #909090; +} + +.r_r_con { + font-size: 13.2px; + color: #909090; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.c2_title{ + width: 100%; + height: 45px; + line-height: 45px; + padding-left: 7.5px; + font-size: 14.4px; + color: #525252; + background: white; + border-bottom: 1px solid #e6e6e6; +} diff --git a/static/app2/css/msg_con.css b/static/app2/css/msg_con.css new file mode 100755 index 0000000..e369c4a --- /dev/null +++ b/static/app2/css/msg_con.css @@ -0,0 +1,22 @@ +.time{ + padding: 5px; + text-align: center; + background: #d2d2d2; + color: white; + width: 180px; + margin: 10px auto; + font-size: 13.2px; + border-radius: 2px; +} +.con_{ + width: 100%; + background: white; + padding: 3%; + border-radius: 5px; +} + +.con_b{ + width: 100%; + background: white; + border-radius: 5px; +} diff --git a/static/app2/css/mui.css b/static/app2/css/mui.css new file mode 100755 index 0000000..52654c7 --- /dev/null +++ b/static/app2/css/mui.css @@ -0,0 +1,5613 @@ +/*! + * ===================================================== + * Mui v3.7.2 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ + +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */ +html +{ + font-family: sans-serif; + + -webkit-text-size-adjust: 100%; +} + +body +{ + margin: 0; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary +{ + display: block; +} + +audio, +canvas, +progress, +video +{ + display: inline-block; + + vertical-align: baseline; +} + +audio:not([controls]) +{ + display: none; + + height: 0; +} + +[hidden], +template +{ + display: none; +} + +a +{ + background: transparent; +} + +a:active, +a:hover +{ + outline: 0; +} + +abbr[title] +{ + border-bottom: 1px dotted; +} + +b, +strong +{ + font-weight: bold; +} + +dfn +{ + font-style: italic; +} + +h1 +{ + font-size: 2em; + + margin: .67em 0; +} + +mark +{ + color: #000; + background: #ff0; +} + +small +{ + font-size: 80%; +} + +sub, +sup +{ + font-size: 75%; + line-height: 0; + + position: relative; + + vertical-align: baseline; +} + +sup +{ + top: -.5em; +} + +sub +{ + bottom: -.25em; +} + +img +{ + border: 0; +} + +svg:not(:root) +{ + overflow: hidden; +} + +figure +{ + margin: 1em 40px; +} + +hr +{ + box-sizing: content-box; + height: 0; +} + +pre +{ + overflow: auto; +} + +code, +kbd, +pre, +samp +{ + font-family: monospace, monospace; + font-size: 1em; +} + +button, +input, +optgroup, +select, +textarea +{ + font: inherit; + + margin: 0; + + color: inherit; +} + +button +{ + overflow: visible; +} + +button, +select +{ + text-transform: none; +} + +button, +html input[type='button'], +input[type='reset'], +input[type='submit'] +{ + cursor: pointer; + + -webkit-appearance: button; +} + +button[disabled], +html input[disabled] +{ + cursor: default; +} + +input +{ + line-height: normal; +} + +input[type='checkbox'], +input[type='radio'] +{ + box-sizing: border-box; + padding: 0; +} + +input[type='number']::-webkit-inner-spin-button, +input[type='number']::-webkit-outer-spin-button +{ + height: auto; +} + +input[type='search'] +{ + -webkit-box-sizing: content-box; + box-sizing: content-box; + + -webkit-appearance: textfield; +} + +input[type='search']::-webkit-search-cancel-button, +input[type='search']::-webkit-search-decoration +{ + -webkit-appearance: none; +} + +fieldset +{ + margin: 0 2px; + padding: .35em .625em .75em; + + border: 1px solid #c0c0c0; +} + +legend +{ + padding: 0; + + border: 0; +} + +textarea +{ + overflow: auto; +} + +optgroup +{ + font-weight: bold; +} + +table +{ + border-spacing: 0; + border-collapse: collapse; +} + +td, +th +{ + padding: 0; +} + +* +{ + -webkit-box-sizing: border-box; + box-sizing: border-box; + + -webkit-user-select: none; + + outline: none; + + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; +} + +body +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + font-size: 17px; + line-height: 21px; + + color: #000; + background-color: #efeff4; + + -webkit-overflow-scrolling: touch; +} + +a +{ + text-decoration: none; + + color: #007aff; +} +a:active +{ + color: #0062cc; +} + +.mui-content +{ + background-color: #efeff4; + + -webkit-overflow-scrolling: touch; +} + +.mui-bar-nav ~ .mui-content +{ + padding-top: 44px; +} +.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + top: 44px; +} + +.mui-bar-header-secondary ~ .mui-content +{ + padding-top: 88px; +} +.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + top: 88px; +} + +.mui-bar-footer ~ .mui-content +{ + padding-bottom: 44px; +} +.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 44px; +} + +.mui-bar-footer-secondary ~ .mui-content +{ + padding-bottom: 88px; +} +.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 88px; +} + +.mui-bar-tab ~ .mui-content +{ + padding-bottom: 50px; +} +.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 50px; +} + +.mui-bar-footer-secondary-tab ~ .mui-content +{ + padding-bottom: 94px; +} +.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical +{ + bottom: 94px; +} + +.mui-content-padded +{ + margin: 10px; +} + +.mui-inline +{ + display: inline-block; + + vertical-align: top; +} + +.mui-block +{ + display: block !important; +} + +.mui-visibility +{ + visibility: visible !important; +} + +.mui-hidden +{ + display: none !important; +} + +.mui-ellipsis +{ + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; +} + +.mui-ellipsis-2 +{ + display: -webkit-box; + overflow: hidden; + + white-space: normal !important; + text-overflow: ellipsis; + word-wrap: break-word; + + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.mui-table +{ + display: table; + + width: 100%; + + table-layout: fixed; +} + +.mui-table-cell +{ + position: relative; + + display: table-cell; +} + +.mui-text-left +{ + text-align: left !important; +} + +.mui-text-center +{ + text-align: center !important; +} + +.mui-text-justify +{ + text-align: justify !important; +} + +.mui-text-right +{ + text-align: right !important; +} + +.mui-pull-left +{ + float: left; +} + +.mui-pull-right +{ + float: right; +} + +.mui-list-unstyled +{ + padding-left: 0; + + list-style: none; +} + +.mui-list-inline +{ + margin-left: -5px; + padding-left: 0; + + list-style: none; +} + +.mui-list-inline > li +{ + display: inline-block; + + padding-right: 5px; + padding-left: 5px; +} + +.mui-clearfix:before, .mui-clearfix:after +{ + display: table; + + content: ' '; +} +.mui-clearfix:after +{ + clear: both; +} + +.mui-bg-primary +{ + background-color: #007aff; +} + +.mui-bg-positive +{ + background-color: #4cd964; +} + +.mui-bg-negative +{ + background-color: #dd524d; +} + +.mui-error +{ + margin: 88px 35px; + padding: 10px; + + border-radius: 6px; + background-color: #bbb; +} + +.mui-subtitle +{ + font-size: 15px; +} + +h1, h2, h3, h4, h5, h6 +{ + line-height: 1; + + margin-top: 5px; + margin-bottom: 5px; +} + +h1, .mui-h1 +{ + font-size: 36px; +} + +h2, .mui-h2 +{ + font-size: 30px; +} + +h3, .mui-h3 +{ + font-size: 24px; +} + +h4, .mui-h4 +{ + font-size: 18px; +} + +h5, .mui-h5 +{ + font-size: 14px; + font-weight: normal; + + color: #8f8f94; +} + +h6, .mui-h6 +{ + font-size: 12px; + font-weight: normal; + + color: #8f8f94; +} + +p +{ + font-size: 14px; + + margin-top: 0; + margin-bottom: 10px; + + color: #8f8f94; +} + +.mui-row:before, .mui-row:after +{ + display: table; + + content: ' '; +} +.mui-row:after +{ + clear: both; +} + +.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12 +{ + position: relative; + + min-height: 1px; +} + +.mui-row > [class*='mui-col-'] +{ + float: left; +} + +.mui-col-xs-12 +{ + width: 100%; +} + +.mui-col-xs-11 +{ + width: 91.66666667%; +} + +.mui-col-xs-10 +{ + width: 83.33333333%; +} + +.mui-col-xs-9 +{ + width: 75%; +} + +.mui-col-xs-8 +{ + width: 66.66666667%; +} + +.mui-col-xs-7 +{ + width: 58.33333333%; +} + +.mui-col-xs-6 +{ + width: 50%; +} + +.mui-col-xs-5 +{ + width: 41.66666667%; +} + +.mui-col-xs-4 +{ + width: 33.33333333%; +} + +.mui-col-xs-3 +{ + width: 25%; +} + +.mui-col-xs-2 +{ + width: 16.66666667%; +} + +.mui-col-xs-1 +{ + width: 8.33333333%; +} + +@media (min-width: 400px) +{ + .mui-col-sm-12 + { + width: 100%; + } + + .mui-col-sm-11 + { + width: 91.66666667%; + } + + .mui-col-sm-10 + { + width: 83.33333333%; + } + + .mui-col-sm-9 + { + width: 75%; + } + + .mui-col-sm-8 + { + width: 66.66666667%; + } + + .mui-col-sm-7 + { + width: 58.33333333%; + } + + .mui-col-sm-6 + { + width: 50%; + } + + .mui-col-sm-5 + { + width: 41.66666667%; + } + + .mui-col-sm-4 + { + width: 33.33333333%; + } + + .mui-col-sm-3 + { + width: 25%; + } + + .mui-col-sm-2 + { + width: 16.66666667%; + } + + .mui-col-sm-1 + { + width: 8.33333333%; + } +} +.mui-scroll-wrapper +{ + position: absolute; + z-index: 2; + top: 0; + bottom: 0; + left: 0; + + overflow: hidden; + + width: 100%; +} + +.mui-scroll +{ + position: absolute; + z-index: 1; + + width: 100%; +} + +.mui-scrollbar +{ + position: absolute; + z-index: 9998; + + overflow: hidden; + + -webkit-transition: 500ms; + transition: 500ms; + transform: translateZ(0px); + pointer-events: none; + + opacity: 0; +} + +.mui-scrollbar-vertical +{ + top: 0; + right: 1px; + bottom: 2px; + + width: 4px; +} +.mui-scrollbar-vertical .mui-scrollbar-indicator +{ + width: 100%; +} + +.mui-scrollbar-horizontal +{ + right: 2px; + bottom: 0; + left: 2px; + + height: 4px; +} +.mui-scrollbar-horizontal .mui-scrollbar-indicator +{ + height: 100%; +} + +.mui-scrollbar-indicator +{ + position: absolute; + + display: block; + + box-sizing: border-box; + + -webkit-transition: .01s cubic-bezier(.1, .57, .1, 1); + transition: .01s cubic-bezier(.1, .57, .1, 1); + transform: translate(0px, 0px) translateZ(0px); + + border: 1px solid rgba(255, 255, 255, .80196); + border-radius: 2px; + background: rgba(0, 0, 0, .39804); +} + +.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper +{ + position: absolute; + top: 0; + bottom: 0; + left: 0; + + overflow: hidden; + + width: 100%; +} +.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll +{ + position: absolute; + + width: 100%; +} +.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group +{ + position: static; + top: auto; + bottom: auto; + left: auto; + + overflow: auto; + + width: auto; +} +.mui-plus-pullrefresh .mui-slider-group +{ + overflow: visible; +} +.mui-plus-pullrefresh .mui-scroll +{ + position: static; + + width: auto; +} + +.mui-off-canvas-wrap .mui-bar +{ + position: absolute !important; + + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-off-canvas-wrap +{ + position: relative; + z-index: 1; + + overflow: hidden; + + width: 100%; + height: 100%; +} +.mui-off-canvas-wrap .mui-inner-wrap +{ + position: relative; + z-index: 1; + + width: 100%; + height: 100%; +} +.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms; + transition: transform 350ms cubic-bezier(.165, .84, .44, 1); +} +.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left +{ + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right +{ + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); +} +.mui-off-canvas-wrap.mui-active +{ + overflow: hidden; + + height: 100%; +} +.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop +{ + position: absolute; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + display: block; + + transition: background 350ms cubic-bezier(.165, .84, .44, 1); + + background: rgba(0, 0, 0, .4); + box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5); + + -webkit-tap-highlight-color: transparent; +} +.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right +{ + z-index: 10000 !important; + + -webkit-transform: translate3d(100%, 0px, 0px); +} +.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left +{ + z-index: 10000 !important; + + -webkit-transform: translate3d(-100%, 0px, 0px); +} + +.mui-off-canvas-left, .mui-off-canvas-right +{ + position: absolute; + z-index: -1; + top: 0; + bottom: 0; + + visibility: hidden; + + box-sizing: content-box; + width: 70%; + min-height: 100%; + + background: #333; + + -webkit-overflow-scrolling: touch; +} +.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1); + transition: transform 350ms cubic-bezier(.165, .84, .44, 1); +} + +.mui-off-canvas-left +{ + left: 0; +} + +.mui-off-canvas-right +{ + right: 0; +} + +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable +{ + background-color: #333; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right +{ + width: 80%; + + -webkit-transform: scale(.8); + transform: scale(.8); + + opacity: .1; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning +{ + -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1); + transition: transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1); +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left +{ + -webkit-transform-origin: -100%; + transform-origin: -100%; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right +{ + -webkit-transform-origin: 200%; + transform-origin: 200%; +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap +{ + -webkit-transform: scale(.8); + transform: scale(.8); +} +.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right +{ + -webkit-transform: scale(1); + transform: scale(1); + + opacity: 1; +} + +.mui-loading .mui-spinner +{ + display: block; + + margin: 0 auto; +} + +.mui-spinner +{ + display: inline-block; + + width: 24px; + height: 24px; + + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: spinner-spin 1s step-end infinite; + animation: spinner-spin 1s step-end infinite; +} + +.mui-spinner:after +{ + display: block; + + width: 100%; + height: 100%; + + content: ''; + + background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>'); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; +} + +.mui-spinner-white:after +{ + background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>'); +} + +@-webkit-keyframes spinner-spin +{ + 0% + { + -webkit-transform: rotate(0deg); + } + + 8.33333333% + { + -webkit-transform: rotate(30deg); + } + + 16.66666667% + { + -webkit-transform: rotate(60deg); + } + + 25% + { + -webkit-transform: rotate(90deg); + } + + 33.33333333% + { + -webkit-transform: rotate(120deg); + } + + 41.66666667% + { + -webkit-transform: rotate(150deg); + } + + 50% + { + -webkit-transform: rotate(180deg); + } + + 58.33333333% + { + -webkit-transform: rotate(210deg); + } + + 66.66666667% + { + -webkit-transform: rotate(240deg); + } + + 75% + { + -webkit-transform: rotate(270deg); + } + + 83.33333333% + { + -webkit-transform: rotate(300deg); + } + + 91.66666667% + { + -webkit-transform: rotate(330deg); + } + + 100% + { + -webkit-transform: rotate(360deg); + } +} +@keyframes spinner-spin +{ + 0% + { + transform: rotate(0deg); + } + + 8.33333333% + { + transform: rotate(30deg); + } + + 16.66666667% + { + transform: rotate(60deg); + } + + 25% + { + transform: rotate(90deg); + } + + 33.33333333% + { + transform: rotate(120deg); + } + + 41.66666667% + { + transform: rotate(150deg); + } + + 50% + { + transform: rotate(180deg); + } + + 58.33333333% + { + transform: rotate(210deg); + } + + 66.66666667% + { + transform: rotate(240deg); + } + + 75% + { + transform: rotate(270deg); + } + + 83.33333333% + { + transform: rotate(300deg); + } + + 91.66666667% + { + transform: rotate(330deg); + } + + 100% + { + transform: rotate(360deg); + } +} +input[type='button'], +input[type='submit'], +input[type='reset'], +button, +.mui-btn +{ + font-size: 14px; + font-weight: 400; + line-height: 1.42; + + position: relative; + + display: inline-block; + + margin-bottom: 0; + padding: 6px 12px; + + cursor: pointer; + -webkit-transition: all; + transition: all; + -webkit-transition-timing-function: linear; + transition-timing-function: linear; + -webkit-transition-duration: .2s; + transition-duration: .2s; + text-align: center; + vertical-align: top; + white-space: nowrap; + + color: #333; + border: 1px solid #ccc; + border-radius: 3px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + background-color: #fff; + background-clip: padding-box; +} +input[type='button']:enabled:active, input[type='button'].mui-active:enabled, +input[type='submit']:enabled:active, +input[type='submit'].mui-active:enabled, +input[type='reset']:enabled:active, +input[type='reset'].mui-active:enabled, +button:enabled:active, +button.mui-active:enabled, +.mui-btn:enabled:active, +.mui-btn.mui-active:enabled +{ + color: #fff; + background-color: #929292; +} +input[type='button']:disabled, input[type='button'].mui-disabled, +input[type='submit']:disabled, +input[type='submit'].mui-disabled, +input[type='reset']:disabled, +input[type='reset'].mui-disabled, +button:disabled, +button.mui-disabled, +.mui-btn:disabled, +.mui-btn.mui-disabled +{ + opacity: .6; +} + +input[type='submit'], +.mui-btn-primary, +.mui-btn-blue +{ + color: #fff; + border: 1px solid #007aff; + background-color: #007aff; +} +input[type='submit']:enabled:active, input[type='submit'].mui-active:enabled, +.mui-btn-primary:enabled:active, +.mui-btn-primary.mui-active:enabled, +.mui-btn-blue:enabled:active, +.mui-btn-blue.mui-active:enabled +{ + color: #fff; + border: 1px solid #0062cc; + background-color: #0062cc; +} + +.mui-btn-positive, +.mui-btn-success, +.mui-btn-green +{ + color: #fff; + border: 1px solid #4cd964; + background-color: #4cd964; +} +.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled, +.mui-btn-success:enabled:active, +.mui-btn-success.mui-active:enabled, +.mui-btn-green:enabled:active, +.mui-btn-green.mui-active:enabled +{ + color: #fff; + border: 1px solid #2ac845; + background-color: #2ac845; +} + +.mui-btn-warning, +.mui-btn-yellow +{ + color: #fff; + border: 1px solid #f0ad4e; + background-color: #f0ad4e; +} +.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled, +.mui-btn-yellow:enabled:active, +.mui-btn-yellow.mui-active:enabled +{ + color: #fff; + border: 1px solid #ec971f; + background-color: #ec971f; +} + +.mui-btn-negative, +.mui-btn-danger, +.mui-btn-red +{ + color: #fff; + border: 1px solid #dd524d; + background-color: #dd524d; +} +.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled, +.mui-btn-danger:enabled:active, +.mui-btn-danger.mui-active:enabled, +.mui-btn-red:enabled:active, +.mui-btn-red.mui-active:enabled +{ + color: #fff; + border: 1px solid #cf2d28; + background-color: #cf2d28; +} + +.mui-btn-royal, +.mui-btn-purple +{ + color: #fff; + border: 1px solid #8a6de9; + background-color: #8a6de9; +} +.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled, +.mui-btn-purple:enabled:active, +.mui-btn-purple.mui-active:enabled +{ + color: #fff; + border: 1px solid #6641e2; + background-color: #6641e2; +} + +.mui-btn-grey +{ + color: #fff; + border: 1px solid #c7c7cc; + background-color: #c7c7cc; +} +.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled +{ + color: #fff; + border: 1px solid #acacb4; + background-color: #acacb4; +} + +.mui-btn-outlined +{ + background-color: transparent; +} +.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue +{ + color: #007aff; +} +.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green +{ + color: #4cd964; +} +.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow +{ + color: #f0ad4e; +} +.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red +{ + color: #dd524d; +} +.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple +{ + color: #8a6de9; +} +.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active +{ + color: #fff; +} + +.mui-btn-link +{ + padding-top: 6px; + padding-bottom: 6px; + + color: #007aff; + border: 0; + background-color: transparent; +} +.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled +{ + color: #0062cc; + background-color: transparent; +} + +.mui-btn-block +{ + font-size: 18px; + + display: block; + + width: 100%; + margin-bottom: 10px; + padding: 15px 0; +} + +.mui-btn .mui-badge +{ + font-size: 14px; + + margin: -2px -4px -2px 4px; + + background-color: rgba(0, 0, 0, .15); +} + +.mui-btn .mui-badge-inverted, +.mui-btn:enabled:active .mui-badge-inverted +{ + background-color: transparent; +} + +.mui-btn-primary:enabled:active .mui-badge-inverted, +.mui-btn-positive:enabled:active .mui-badge-inverted, +.mui-btn-negative:enabled:active .mui-badge-inverted +{ + color: #fff; +} + +.mui-btn-block .mui-badge +{ + position: absolute; + right: 0; + + margin-right: 10px; +} + +.mui-btn .mui-icon +{ + font-size: inherit; +} + +.mui-btn.mui-icon +{ + font-size: 14px; + line-height: 1.42; +} + +.mui-btn.mui-fab +{ + width: 56px; + height: 56px; + padding: 16px; + + border-radius: 50%; + outline: none; +} +.mui-btn.mui-fab.mui-btn-mini +{ + width: 40px; + height: 40px; + padding: 8px; +} +.mui-btn.mui-fab .mui-icon +{ + font-size: 24px; + line-height: 24px; + + width: 24px; + height: 24px; +} + +.mui-btn .mui-spinner +{ + width: 14px; + height: 14px; + + vertical-align: text-bottom; +} + +.mui-btn-block .mui-spinner +{ + width: 22px; + height: 22px; +} + +.mui-bar +{ + position: fixed; + z-index: 10; + right: 0; + left: 0; + + height: 44px; + padding-right: 10px; + padding-left: 10px; + + border-bottom: 0; + background-color: #f7f7f7; + -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85); + box-shadow: 0 0 1px rgba(0, 0, 0, .85); + + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.mui-bar .mui-title +{ + right: 40px; + left: 40px; + + display: inline-block; + overflow: hidden; + + width: auto; + margin: 0; + + text-overflow: ellipsis; +} +.mui-bar .mui-backdrop +{ + background: none; +} + +.mui-bar-header-secondary +{ + top: 44px; +} + +.mui-bar-footer +{ + bottom: 0; +} + +.mui-bar-footer-secondary +{ + bottom: 44px; +} + +.mui-bar-footer-secondary-tab +{ + bottom: 50px; +} + +.mui-bar-footer, +.mui-bar-footer-secondary, +.mui-bar-footer-secondary-tab +{ + border-top: 0; +} + +.mui-bar-transparent +{ + top: 0; + + background-color: rgba(247, 247, 247, 0); + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-bar-nav +{ + top: 0; + + -webkit-box-shadow: 0 1px 6px #ccc; + box-shadow: 0 1px 6px #ccc; +} +.mui-bar-nav ~ .mui-content .mui-anchor +{ + display: block; + visibility: hidden; + + height: 45px; + margin-top: -45px; +} +.mui-bar-nav.mui-bar .mui-icon +{ + margin-right: -10px; + margin-left: -10px; + padding-right: 10px; + padding-left: 10px; +} + +.mui-title +{ + font-size: 17px; + font-weight: 500; + line-height: 44px; + + position: absolute; + + display: block; + + width: 100%; + margin: 0 -10px; + padding: 0; + + text-align: center; + white-space: nowrap; + + color: #000; +} + +.mui-title a +{ + color: inherit; +} + +.mui-bar-tab +{ + bottom: 0; + + display: table; + + width: 100%; + height: 50px; + padding: 0; + + table-layout: fixed; + + border-top: 0; + border-bottom: 0; + + -webkit-touch-callout: none; +} +.mui-bar-tab .mui-tab-item +{ + display: table-cell; + overflow: hidden; + + width: 1%; + height: 50px; + + text-align: center; + vertical-align: middle; + white-space: nowrap; + text-overflow: ellipsis; + + color: #929292; +} +.mui-bar-tab .mui-tab-item.mui-active +{ + color: #007aff; +} +.mui-bar-tab .mui-tab-item .mui-icon +{ + top: 3px; + + width: 24px; + height: 24px; + padding-top: 0; + padding-bottom: 0; +} +.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label +{ + font-size: 11px; + + display: block; + overflow: hidden; + + text-overflow: ellipsis; +} +.mui-bar-tab .mui-tab-item .mui-icon:active +{ + background: none; +} + +.mui-focusin > .mui-bar-nav, +.mui-focusin > .mui-bar-header-secondary +{ + position: absolute; +} + +.mui-focusin > .mui-bar ~ .mui-content +{ + padding-bottom: 0; +} + +.mui-bar .mui-btn +{ + font-weight: 400; + + position: relative; + z-index: 20; + top: 7px; + + margin-top: 0; + padding: 6px 12px 7px; +} +.mui-bar .mui-btn.mui-pull-right +{ + margin-left: 10px; +} +.mui-bar .mui-btn.mui-pull-left +{ + margin-right: 10px; +} + +.mui-bar .mui-btn-link +{ + font-size: 16px; + line-height: 44px; + + top: 0; + + padding: 0; + + color: #007aff; + border: 0; +} +.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active +{ + color: #0062cc; +} + +.mui-bar .mui-btn-block +{ + font-size: 16px; + + top: 6px; + + margin-bottom: 0; + padding: 5px 0; +} + +.mui-bar .mui-btn-nav.mui-pull-left +{ + margin-left: -5px; +} +.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav +{ + margin-right: -3px; +} +.mui-bar .mui-btn-nav.mui-pull-right +{ + margin-right: -5px; +} +.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav +{ + margin-left: -3px; +} +.mui-bar .mui-btn-nav:active +{ + opacity: .3; +} + +.mui-bar .mui-icon +{ + font-size: 24px; + + position: relative; + z-index: 20; + + padding-top: 10px; + padding-bottom: 10px; +} +.mui-bar .mui-icon:active +{ + opacity: .3; +} +.mui-bar .mui-btn .mui-icon +{ + top: 1px; + + margin: 0; + padding: 0; +} +.mui-bar .mui-title .mui-icon +{ + margin: 0; + padding: 0; +} +.mui-bar .mui-title .mui-icon.mui-icon-caret +{ + top: 4px; + + margin-left: -5px; +} + +.mui-bar input[type='search'] +{ + height: 29px; + margin: 6px 0; +} + +.mui-bar .mui-input-row .mui-btn +{ + padding: 12px 10px; +} + +.mui-bar .mui-search:before +{ + margin-top: -10px; +} + +.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear, +.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + top: 0; + right: 12px; +} + +.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear, +.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + top: 0; + right: 0; +} + +.mui-bar .mui-segmented-control +{ + top: 7px; + + width: auto; + margin: 0 auto; +} + +.mui-bar.mui-bar-header-secondary .mui-segmented-control +{ + top: 0; +} + +.mui-badge +{ + font-size: 12px; + line-height: 1; + + display: inline-block; + + padding: 3px 6px; + + color: #333; + border-radius: 100px; + background-color: rgba(0, 0, 0, .15); +} +.mui-badge.mui-badge-inverted +{ + padding: 0 5px 0 0; + + color: #929292; + background-color: transparent; +} + +.mui-badge-primary, .mui-badge-blue +{ + color: #fff; + background-color: #007aff; +} +.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted +{ + color: #007aff; + background-color: transparent; +} + +.mui-badge-success, .mui-badge-green +{ + color: #fff; + background-color: #4cd964; +} +.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted +{ + color: #4cd964; + background-color: transparent; +} + +.mui-badge-warning, .mui-badge-yellow +{ + color: #fff; + background-color: #f0ad4e; +} +.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted +{ + color: #f0ad4e; + background-color: transparent; +} + +.mui-badge-danger, .mui-badge-red +{ + color: #fff; + background-color: #dd524d; +} +.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted +{ + color: #dd524d; + background-color: transparent; +} + +.mui-badge-royal, .mui-badge-purple +{ + color: #fff; + background-color: #8a6de9; +} +.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted +{ + color: #8a6de9; + background-color: transparent; +} + +.mui-icon .mui-badge +{ + font-size: 10px; + line-height: 1.4; + + position: absolute; + top: -2px; + left: 100%; + + margin-left: -10px; + padding: 1px 5px; + + color: white; + background: red; +} + +.mui-card +{ + font-size: 14px; + + position: relative; + + overflow: hidden; + + margin: 10px; + + border-radius: 2px; + background-color: white; + background-clip: padding-box; + box-shadow: 0 1px 2px rgba(0, 0, 0, .3); +} + +.mui-content > .mui-card:first-child +{ + margin-top: 15px; +} + +.mui-card .mui-input-group:before, .mui-card .mui-input-group:after +{ + height: 0; +} +.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after +{ + height: 0; +} + +.mui-card .mui-table-view +{ + margin-bottom: 0; + + border-top: 0; + border-bottom: 0; + border-radius: 6px; +} +.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child +{ + top: 0; + + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} +.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child +{ + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} +.mui-card .mui-table-view:before, .mui-card .mui-table-view:after +{ + height: 0; +} + +.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after +{ + height: 0; +} + +.mui-card-header, +.mui-card-footer +{ + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + min-height: 44px; + padding: 10px 15px; + + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} +.mui-card-header .mui-card-link, +.mui-card-footer .mui-card-link +{ + line-height: 44px; + + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 44px; + margin-top: -10px; + margin-bottom: -10px; + + -webkit-transition-duration: .3s; + transition-duration: .3s; + text-decoration: none; + + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + justify-content: flex-start; + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} + +.mui-card-header:after, +.mui-card-footer:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-card-header +{ + font-size: 17px; + + border-radius: 2px 2px 0 0; +} +.mui-card-header:after +{ + top: auto; + bottom: 0; +} +.mui-card-header > img:first-child +{ + font-size: 0; + line-height: 0; + + float: left; + + width: 34px; + height: 34px; +} + +.mui-card-footer +{ + color: #6d6d72; + border-radius: 0 0 2px 2px; +} + +.mui-card-content +{ + font-size: 14px; + + position: relative; +} + +.mui-card-content-inner +{ + position: relative; + + padding: 15px; +} + +.mui-card-media +{ + vertical-align: bottom; + + color: #fff; + background-position: center; + background-size: cover; +} + +.mui-card-header.mui-card-media +{ + display: block; + + padding: 10px; +} +.mui-card-header.mui-card-media .mui-media-body +{ + font-size: 14px; + font-weight: 500; + line-height: 17px; + + margin-bottom: 0; + margin-left: 44px; + + color: #333; +} +.mui-card-header.mui-card-media .mui-media-body p +{ + font-size: 13px; + + margin-bottom: 0; +} + +.mui-table-view +{ + position: relative; + + margin-top: 0; + margin-bottom: 0; + padding-left: 0; + + list-style: none; + + background-color: #fff; +} +.mui-table-view:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view:before +{ + top: -1px; +} + +.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon +{ + font-size: 20px; + + margin-top: -1px; + margin-right: 5px; + margin-left: -5px; +} +.mui-table-view-icon .mui-table-view-cell:after +{ + left: 40px; +} + +.mui-table-view-chevron .mui-table-view-cell +{ + padding-right: 65px; +} +.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn) +{ + margin-right: -65px; +} + +.mui-table-view-radio .mui-table-view-cell +{ + padding-right: 65px; +} +.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn) +{ + margin-right: -65px; +} +.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after +{ + font-size: 30px; + font-weight: 600; + + right: 9px; + + content: ''; + + color: #007aff; +} +.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after +{ + content: '\e472'; +} + +.mui-table-view-inverted +{ + color: #fff; + background: #333; +} +.mui-table-view-inverted:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #222; +} +.mui-table-view-inverted .mui-table-view-cell.mui-active +{ + background-color: #242424; +} +.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background-color: #242424; +} + +.mui-table-view-cell +{ + position: relative; + + overflow: hidden; + + padding: 11px 15px; + + -webkit-touch-callout: none; +} +.mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox] +{ + top: 8px; +} +.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left +{ + padding-left: 58px; +} +.mui-table-view-cell.mui-active +{ + background-color: #eee; +} +.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after +{ + height: 0; +} +.mui-table-view-cell > a:not(.mui-btn) +{ + position: relative; + + display: block; + overflow: hidden; + + margin: -11px -15px; + padding: inherit; + + white-space: nowrap; + text-overflow: ellipsis; + + color: inherit; + /*&:active { + background-color: #eee; + }*/ +} +.mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background-color: #eee; +} +.mui-table-view-cell p +{ + margin-bottom: 0; +} + +.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn +{ + -webkit-transition: -webkit-transform 300ms ease; + transition: transform 300ms ease; +} +.mui-table-view-cell.mui-active > .mui-slider-handle +{ + background-color: #eee; +} +.mui-table-view-cell > .mui-slider-handle +{ + position: relative; + + background-color: #fff; +} +.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after +{ + right: 0; +} +.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn +{ + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; +} +.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right +{ + position: absolute; + top: 0; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 100%; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn +{ + position: relative; + left: 0; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + padding: 0 30px; + + color: #fff; + border: 0; + border-radius: 0; + + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after +{ + position: absolute; + z-index: -1; + top: 0; + + width: 600%; + height: 100%; + + content: ''; + + background: inherit; +} +.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon +{ + font-size: 30px; +} +.mui-table-view-cell > .mui-slider-right +{ + right: 0; + + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +.mui-table-view-cell > .mui-slider-left +{ + left: 0; + + -webkit-transition: -webkit-transform 0ms ease; + transition: transform 0ms ease; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +.mui-table-view-cell > .mui-slider-left > .mui-btn:after +{ + right: 100%; + + margin-right: -1px; +} + +.mui-table-view-divider +{ + font-weight: 500; + + position: relative; + + margin-top: -1px; + margin-left: 0; + padding-top: 6px; + padding-bottom: 6px; + padding-left: 15px; + + color: #999; + background-color: #fafafa; +} +.mui-table-view-divider:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view-divider:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view .mui-media, +.mui-table-view .mui-media-body +{ + overflow: hidden; +} + +.mui-table-view .mui-media-large .mui-media-object +{ + line-height: 80px; + + max-width: 80px; + height: 80px; +} +.mui-table-view .mui-media .mui-subtitle +{ + color: #000; +} +.mui-table-view .mui-media-object +{ + line-height: 42px; + + max-width: 42px; + height: 42px; +} +.mui-table-view .mui-media-object.mui-pull-left +{ + margin-right: 10px; +} +.mui-table-view .mui-media-object.mui-pull-right +{ + margin-left: 10px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object +{ + line-height: 29px; + + max-width: 29px; + height: 29px; + margin: -4px 0; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img +{ + line-height: 29px; + + max-width: 29px; + height: 29px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left +{ + margin-right: 10px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon +{ + font-size: 29px; +} +.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 55px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-table-view .mui-table-view-cell.mui-media-icon:after +{ + height: 0 !important; +} + +.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view +{ + display: block; +} +.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after +{ + height: 0 !important; +} +.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 70px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view-cell > .mui-btn, +.mui-table-view-cell > .mui-badge, +.mui-table-view-cell > .mui-switch, +.mui-table-view-cell > a > .mui-btn, +.mui-table-view-cell > a > .mui-badge, +.mui-table-view-cell > a > .mui-switch +{ + position: absolute; + top: 50%; + right: 15px; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.mui-table-view-cell .mui-navigate-right > .mui-btn, +.mui-table-view-cell .mui-navigate-right > .mui-badge, +.mui-table-view-cell .mui-navigate-right > .mui-switch, +.mui-table-view-cell .mui-push-left > .mui-btn, +.mui-table-view-cell .mui-push-left > .mui-badge, +.mui-table-view-cell .mui-push-left > .mui-switch, +.mui-table-view-cell .mui-push-right > .mui-btn, +.mui-table-view-cell .mui-push-right > .mui-badge, +.mui-table-view-cell .mui-push-right > .mui-switch, +.mui-table-view-cell > a .mui-navigate-right > .mui-btn, +.mui-table-view-cell > a .mui-navigate-right > .mui-badge, +.mui-table-view-cell > a .mui-navigate-right > .mui-switch, +.mui-table-view-cell > a .mui-push-left > .mui-btn, +.mui-table-view-cell > a .mui-push-left > .mui-badge, +.mui-table-view-cell > a .mui-push-left > .mui-switch, +.mui-table-view-cell > a .mui-push-right > .mui-btn, +.mui-table-view-cell > a .mui-push-right > .mui-badge, +.mui-table-view-cell > a .mui-push-right > .mui-switch +{ + right: 35px; +} + +.mui-content > .mui-table-view:first-child +{ + margin-top: 15px; +} + +.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after +{ + height: 0; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after +{ + height: 0; +} +.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after +{ + content: '\e581'; +} +.mui-table-view-cell.mui-collapse.mui-active +{ + margin-top: -1px; +} +.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content +{ + display: block; +} +.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after +{ + content: '\e580'; +} +.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + margin-left: -31px; + padding-left: 47px; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content +{ + position: relative; + + display: none; + overflow: hidden; + + margin: 11px -15px -11px; + padding: 8px 15px; + + -webkit-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; + + background: white; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider +{ + width: auto; + height: auto; + margin: -8px -15px; +} +.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider +{ + margin: -8px -16px; +} +.mui-table-view-cell.mui-collapse .mui-table-view +{ + display: none; + + margin-top: 11px; + margin-right: -15px; + margin-bottom: -11px; + margin-left: -15px; + + border: 0; +} +.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron +{ + margin-right: -65px; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell +{ + padding-left: 31px; + + background-position: 31px 100%; +} +.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 30px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-table-view.mui-grid-view +{ + font-size: 0; + + display: block; + + width: 100%; + padding: 0 10px 10px 0; + + white-space: normal; +} +.mui-table-view.mui-grid-view .mui-table-view-cell +{ + font-size: 17px; + + display: inline-block; + + margin-right: -4px; + padding: 10px 0 0 14px; + + text-align: center; + vertical-align: middle; + + background: none; +} +.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object +{ + width: 100%; + max-width: 100%; + height: auto; +} +.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn) +{ + margin: -10px 0 0 -14px; +} +.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active +{ + background: none; +} +.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body +{ + font-size: 15px; + line-height: 15px; + + display: block; + + width: 100%; + height: 15px; + margin-top: 8px; + + text-overflow: ellipsis; + + color: #333; +} +.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after +{ + height: 0; +} + +.mui-grid-view.mui-grid-9 +{ + margin: 0; + padding: 0; + + border-top: 1px solid #eee; + border-left: 1px solid #eee; + background-color: #f2f2f2; +} +.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after +{ + display: table; + + content: ' '; +} +.mui-grid-view.mui-grid-9:after +{ + clear: both; +} +.mui-grid-view.mui-grid-9:after +{ + position: static; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell +{ + margin: 0; + padding: 11px 15px; + + vertical-align: top; + + border-right: 1px solid #eee; + border-bottom: 1px solid #eee; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active +{ + background-color: #eee; +} +.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn) +{ + margin: 0; + padding: 10px 0; +} +.mui-grid-view.mui-grid-9:before +{ + height: 0; +} +.mui-grid-view.mui-grid-9 .mui-media +{ + color: #797979; +} +.mui-grid-view.mui-grid-9 .mui-media .mui-icon +{ + font-size: 2.4em; + + position: relative; +} + +.mui-slider-cell +{ + position: relative; +} +.mui-slider-cell > .mui-slider-handle +{ + z-index: 1; +} +.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right +{ + position: absolute; + z-index: 0; + top: 0; + bottom: 0; +} +.mui-slider-cell > .mui-slider-left +{ + left: 0; +} +.mui-slider-cell > .mui-slider-right +{ + right: 0; +} + +input, +textarea, +select +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + font-size: 17px; + + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; +} +input:focus, +textarea:focus, +select:focus +{ + -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: transparent; + -webkit-user-modify: read-write-plaintext-only; +} + +select, +textarea, +input[type='text'], +input[type='search'], +input[type='password'], +input[type='datetime'], +input[type='datetime-local'], +input[type='date'], +input[type='month'], +input[type='time'], +input[type='week'], +input[type='number'], +input[type='email'], +input[type='url'], +input[type='tel'], +input[type='color'] +{ + line-height: 21px; + + width: 100%; + height: 40px; + margin-bottom: 15px; + padding: 10px 15px; + + -webkit-user-select: text; + + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 3px; + outline: none; + background-color: #fff; + + -webkit-appearance: none; +} + +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button +{ + margin: 0; + + -webkit-appearance: none; +} + +input[type='search'] +{ + font-size: 16px; + + -webkit-box-sizing: border-box; + box-sizing: border-box; + height: 34px; + + text-align: center; + + border: 0; + border-radius: 6px; + background-color: rgba(0, 0, 0, .1); +} + +input[type='search']:focus +{ + text-align: left; +} + +textarea +{ + height: auto; + + resize: none; +} + +select +{ + font-size: 14px; + + height: auto; + margin-top: 1px; + + border: 0 !important; + background-color: #fff; +} +select:focus +{ + -webkit-user-modify: read-only; +} + +.mui-input-group +{ + position: relative; + + padding: 0; + + border: 0; + background-color: #fff; +} +.mui-input-group:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-input-group:before +{ + position: absolute; + top: 0; + right: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-input-group input, +.mui-input-group textarea +{ + margin-bottom: 0; + + border: 0; + border-radius: 0; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-input-group input[type='search'] +{ + background: none; +} + +.mui-input-group input:last-child +{ + background-image: none; +} + +.mui-input-row +{ + clear: left; + overflow: hidden; +} +.mui-input-row select +{ + font-size: 17px; + + height: 37px; + padding: 0; +} + +.mui-input-row:last-child, +.mui-input-row label + input, .mui-input-row .mui-btn + input +{ + background: none; +} + +.mui-input-group .mui-input-row +{ + height: 40px; +} +.mui-input-group .mui-input-row:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 15px; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} + +.mui-input-row label +{ + font-family: 'Helvetica Neue', Helvetica, sans-serif; + line-height: 1.1; + + float: left; + + width: 35%; + padding: 11px 15px; +} + +.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea +{ + float: right; + + width: 65%; + margin-bottom: 0; + padding-left: 0; + + border: 0; +} + +.mui-input-row .mui-btn +{ + line-height: 1.1; + + float: right; + + width: 15%; + padding: 10px 15px; +} + +.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea +{ + float: left; + + width: 85%; + margin-bottom: 0; + padding-left: 0; + + border: 0; +} + +.mui-button-row +{ + position: relative; + + padding-top: 5px; + + text-align: center; +} + +.mui-input-group .mui-button-row +{ + height: 45px; +} + +.mui-input-row +{ + position: relative; +} +.mui-input-row.mui-input-range +{ + overflow: visible; + + padding-right: 20px; +} +.mui-input-row .mui-inline +{ + padding: 8px 0; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye +{ + font-size: 20px; + + position: absolute; + z-index: 1; + top: 10px; + right: 0; + + width: 38px; + height: 38px; + + text-align: center; + + color: #999; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active +{ + color: #007aff; +} +.mui-input-row .mui-input-speech ~ .mui-icon-speech +{ + font-size: 24px; + + top: 8px; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech +{ + display: none; +} +.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech +{ + display: inline-block; +} +.mui-input-row .mui-icon-speech ~ .mui-placeholder +{ + right: 38px; +} +.mui-input-row.mui-search .mui-icon-clear +{ + top: 7px; +} +.mui-input-row.mui-search .mui-icon-speech +{ + top: 5px; +} + +.mui-radio, .mui-checkbox +{ + position: relative; +} +.mui-radio label, .mui-checkbox label +{ + display: inline-block; + float: none; + + width: 100%; + padding-right: 58px; +} + +.mui-radio.mui-left input[type='radio'], .mui-checkbox.mui-left input[type='checkbox'] +{ + left: 20px; +} + +.mui-radio.mui-left label, .mui-checkbox.mui-left label +{ + padding-right: 15px; + padding-left: 58px; +} + +.mui-radio input[type='radio'], .mui-checkbox input[type='checkbox'] +{ + position: absolute; + top: 4px; + right: 20px; + + display: inline-block; + + width: 28px; + height: 26px; + + border: 0; + outline: 0 !important; + background-color: transparent; + + -webkit-appearance: none; +} +.mui-radio input[type='radio'][disabled]:before, .mui-checkbox input[type='checkbox'][disabled]:before +{ + opacity: .3; +} +.mui-radio input[type='radio']:before, .mui-checkbox input[type='checkbox']:before +{ + font-family: Muiicons; + font-size: 28px; + font-weight: normal; + line-height: 1; + + text-decoration: none; + + color: #aaa; + border-radius: 0; + background: none; + + -webkit-font-smoothing: antialiased; +} +.mui-radio input[type='radio']:checked:before, .mui-checkbox input[type='checkbox']:checked:before +{ + color: #007aff; +} + +.mui-radio.mui-disabled label, .mui-radio label.mui-disabled, .mui-checkbox.mui-disabled label, .mui-checkbox label.mui-disabled +{ + opacity: .4; +} + +.mui-radio input[type='radio']:before +{ + content: '\e411'; +} + +.mui-radio input[type='radio']:checked:before +{ + content: '\e441'; +} + +.mui-checkbox input[type='checkbox']:before +{ + content: '\e411'; +} + +.mui-checkbox input[type='checkbox']:checked:before +{ + content: '\e442'; +} + +.mui-select +{ + position: relative; +} + +.mui-select:before +{ + font-family: Muiicons; + + position: absolute; + top: 8px; + right: 21px; + + content: '\e581'; + + color: rgba(170, 170, 170, .6); +} + +.mui-input-row .mui-switch +{ + float: right; + + margin-top: 5px; + margin-right: 20px; +} + +.mui-input-range +{ + /*input[type="range"] { + -webkit-appearance: none; + background: #999; + height: 36px; + border-radius: 1px; + overflow: hidden; + margin-top: 2px; + margin-bottom: 2px; + outline:none; + position:relative; + width:100%; + }*/ + /*input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none!important; + opacity: 0.5; + height:28px; + width:28px; + border-radius: 50%; + background:#00b7fb; + position: relative; + pointer-events: none; + -webkit-box-sizing: border-box; + box-sizing: border-box; + &:before{ + position: absolute; + top: 13px; + left: -2000px; + width: 2000px; + height: 2px; + background: #00b7fb; + content:' '; + } + }*/ +} +.mui-input-range input[type='range'] +{ + position: relative; + + width: 100%; + height: 2px; + margin: 17px 0; + padding: 0; + + cursor: pointer; + + border: 0; + border-radius: 3px; + outline: none; + background-color: #999; + + -webkit-appearance: none !important; +} +.mui-input-range input[type='range']::-webkit-slider-thumb +{ + width: 28px; + height: 28px; + + border-color: #0062cc; + border-radius: 50%; + background-color: #007aff; + background-clip: padding-box; + + -webkit-appearance: none !important; +} +.mui-input-range label ~ input[type='range'] +{ + width: 65%; +} +.mui-input-range .mui-tooltip +{ + font-size: 36px; + line-height: 64px; + + position: absolute; + z-index: 1; + top: -70px; + + width: 64px; + height: 64px; + + text-align: center; + + opacity: .8; + color: #333; + border: 1px solid #ddd; + border-radius: 6px; + background-color: #fff; + text-shadow: 0 1px 0 #f3f3f3; +} + +.mui-search +{ + position: relative; +} +.mui-search input[type='search'] +{ + padding-left: 30px; +} +.mui-search .mui-placeholder +{ + font-size: 16px; + line-height: 34px; + + position: absolute; + z-index: 1; + top: 0; + right: 0; + bottom: 0; + left: 0; + + display: inline-block; + + height: 34px; + + text-align: center; + + color: #999; + border: 0; + border-radius: 6px; + background: none; +} +.mui-search .mui-placeholder .mui-icon +{ + font-size: 20px; + + color: #333; +} +.mui-search:before +{ + font-family: Muiicons; + font-size: 20px; + font-weight: normal; + + position: absolute; + top: 50%; + right: 50%; + + display: none; + + margin-top: -18px; + margin-right: 31px; + + content: '\e466'; +} +.mui-search.mui-active:before +{ + font-size: 20px; + + right: auto; + left: 5px; + + display: block; + + margin-right: 0; +} +.mui-search.mui-active input[type='search'] +{ + text-align: left; +} +.mui-search.mui-active .mui-placeholder +{ + display: none; +} + +.mui-segmented-control +{ + font-size: 15px; + font-weight: 400; + + position: relative; + + display: table; + overflow: hidden; + + width: 100%; + + table-layout: fixed; + + border: 1px solid #007aff; + border-radius: 3px; + background-color: transparent; + + -webkit-touch-callout: none; +} +.mui-segmented-control.mui-segmented-control-vertical +{ + border-collapse: collapse; + + border-width: 0; + border-radius: 0; +} +.mui-segmented-control.mui-segmented-control-vertical .mui-control-item +{ + display: block; + + border-bottom: 1px solid #c8c7cc; + border-left-width: 0; +} +.mui-segmented-control.mui-scroll-wrapper +{ + height: 38px; +} +.mui-segmented-control.mui-scroll-wrapper .mui-scroll +{ + width: auto; + height: 40px; + + white-space: nowrap; +} +.mui-segmented-control.mui-scroll-wrapper .mui-control-item +{ + display: inline-block; + + width: auto; + padding: 0 20px; + + border: 0; +} +.mui-segmented-control .mui-control-item +{ + line-height: 38px; + + display: table-cell; + overflow: hidden; + + width: 1%; + + -webkit-transition: background-color .1s linear; + transition: background-color .1s linear; + text-align: center; + white-space: nowrap; + text-overflow: ellipsis; + + color: #007aff; + border-color: #007aff; + border-left: 1px solid #007aff; +} +.mui-segmented-control .mui-control-item:first-child +{ + border-left-width: 0; +} +.mui-segmented-control .mui-control-item.mui-active +{ + color: #fff; + background-color: #007aff; +} +.mui-segmented-control.mui-segmented-control-inverted +{ + width: 100%; + + border: 0; + border-radius: 0; +} +.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item +{ + border-bottom: 1px solid #c8c7cc; +} +.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active +{ + border-bottom: 1px solid #c8c7cc; +} +.mui-segmented-control.mui-segmented-control-inverted .mui-control-item +{ + color: inherit; + border: 0; +} +.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #007aff; + border-bottom: 2px solid #007aff; + background: none; +} +.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #007aff; +} + +.mui-segmented-control-positive +{ + border: 1px solid #4cd964; +} +.mui-segmented-control-positive .mui-control-item +{ + color: #4cd964; + border-color: inherit; +} +.mui-segmented-control-positive .mui-control-item.mui-active +{ + color: #fff; + background-color: #4cd964; +} +.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #4cd964; + border-bottom: 2px solid #4cd964; + background: none; +} +.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #4cd964; +} + +.mui-segmented-control-negative +{ + border: 1px solid #dd524d; +} +.mui-segmented-control-negative .mui-control-item +{ + color: #dd524d; + border-color: inherit; +} +.mui-segmented-control-negative .mui-control-item.mui-active +{ + color: #fff; + background-color: #dd524d; +} +.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active +{ + color: #dd524d; + border-bottom: 2px solid #dd524d; + background: none; +} +.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar +{ + background-color: #dd524d; +} + +.mui-control-content +{ + position: relative; + + display: none; +} +.mui-control-content.mui-active +{ + display: block; +} + +.mui-popover +{ + position: absolute; + z-index: 999; + + display: none; + + width: 280px; + + -webkit-transition: opacity .3s; + transition: opacity .3s; + -webkit-transition-property: opacity; + transition-property: opacity; + -webkit-transform: none; + transform: none; + + opacity: 0; + border-radius: 7px; + background-color: #f7f7f7; + -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1); + box-shadow: 0 0 15px rgba(0, 0, 0, .1); +} +.mui-popover .mui-popover-arrow +{ + position: absolute; + z-index: 1000; + top: -25px; + left: 0; + + overflow: hidden; + + width: 26px; + height: 26px; +} +.mui-popover .mui-popover-arrow:after +{ + position: absolute; + top: 19px; + left: 0; + + width: 26px; + height: 26px; + + content: ' '; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + + border-radius: 3px; + background: #f7f7f7; +} +.mui-popover .mui-popover-arrow.mui-bottom +{ + top: 100%; + left: -26px; + + margin-top: -1px; +} +.mui-popover .mui-popover-arrow.mui-bottom:after +{ + top: -19px; + left: 0; +} +.mui-popover.mui-popover-action +{ + bottom: 0; + + width: 100%; + + -webkit-transition: -webkit-transform .3s, opacity .3s; + transition: transform .3s, opacity .3s; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + + border-radius: 0; + background: none; + -webkit-box-shadow: none; + box-shadow: none; +} +.mui-popover.mui-popover-action .mui-popover-arrow +{ + display: none; +} +.mui-popover.mui-popover-action.mui-popover-bottom +{ + position: fixed; +} +.mui-popover.mui-popover-action.mui-active +{ + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.mui-popover.mui-popover-action .mui-table-view +{ + margin: 8px; + + text-align: center; + + color: #007aff; + border-radius: 4px; +} +.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after +{ + position: absolute; + right: 0; + bottom: 0; + left: 0; + + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + + background-color: #c8c7cc; +} +.mui-popover.mui-popover-action .mui-table-view small +{ + font-weight: 400; + line-height: 1.3; + + display: block; +} +.mui-popover.mui-active +{ + display: block; + + opacity: 1; +} +.mui-popover .mui-bar ~ .mui-table-view +{ + padding-top: 44px; +} + +.mui-backdrop +{ + + position: fixed; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + background-color: rgba(0, 0, 0, .3); +} + +.mui-bar-backdrop.mui-backdrop +{ + bottom: 50px; + + background: none; +} + +.mui-backdrop-action.mui-backdrop +{ + background-color: rgba(0, 0, 0, .3); +} + +.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop +{ + opacity: 0; +} +.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active +{ + -webkit-transition: all .4s ease; + transition: all .4s ease; + + opacity: 1; +} + +.mui-popover .mui-btn-block +{ + margin-bottom: 5px; +} +.mui-popover .mui-btn-block:last-child +{ + margin-bottom: 0; +} + +.mui-popover .mui-bar +{ + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-popover .mui-bar-nav +{ + border-bottom: 1px solid rgba(0, 0, 0, .15); + border-top-left-radius: 12px; + border-top-right-radius: 12px; + -webkit-box-shadow: none; + box-shadow: none; +} + +.mui-popover .mui-scroll-wrapper +{ + margin: 7px 0; + + border-radius: 7px; + background-clip: padding-box; +} + +.mui-popover .mui-scroll .mui-table-view +{ + max-height: none; +} + +.mui-popover .mui-table-view +{ + overflow: auto; + + max-height: 300px; + margin-bottom: 0; + + border-radius: 7px; + background-color: #f7f7f7; + background-image: none; + + -webkit-overflow-scrolling: touch; +} +.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after +{ + height: 0; +} +.mui-popover .mui-table-view .mui-table-view-cell:first-child, +.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn) +{ + border-top-left-radius: 12px; + border-top-right-radius: 12px; +} +.mui-popover .mui-table-view .mui-table-view-cell:last-child, +.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn) +{ + border-bottom-right-radius: 12px; + border-bottom-left-radius: 12px; +} + +.mui-popover.mui-bar-popover .mui-table-view +{ + width: 106px; +} +.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell +{ + padding: 11px 15px 11px 15px; + + background-position: 0 100%; +} +.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn) +{ + margin: -11px -15px -11px -15px; +} + +.mui-popup-backdrop +{ + position: fixed; + z-index: 998; + top: 0; + right: 0; + bottom: 0; + left: 0; + + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + + opacity: 0; + background: rgba(0, 0, 0, .4); +} +.mui-popup-backdrop.mui-active +{ + opacity: 1; +} + +.mui-popup +{ + position: fixed; + z-index: 10000; + top: 50%; + left: 50%; + + display: none; + overflow: hidden; + + width: 270px; + + -webkit-transition-property: -webkit-transform,opacity; + transition-property: transform,opacity; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1.185); + transform: translate3d(-50%, -50%, 0) scale(1.185); + text-align: center; + + opacity: 0; + color: #000; + border-radius: 13px; +} +.mui-popup.mui-popup-in +{ + display: block; + + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); + + opacity: 1; +} +.mui-popup.mui-popup-out +{ + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); + + opacity: 0; +} + +.mui-popup-inner +{ + position: relative; + + padding: 15px; + + border-radius: 13px 13px 0 0; + background: rgba(255, 255, 255, .95); +} +.mui-popup-inner:after +{ + position: absolute; + z-index: 15; + top: auto; + right: auto; + bottom: 0; + left: 0; + + display: block; + + width: 100%; + height: 1px; + + content: ''; + -webkit-transform: scaleY(.5); + transform: scaleY(.5); + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; + + background-color: rgba(0, 0, 0, .2); +} + +.mui-popup-title +{ + font-size: 18px; + font-weight: 500; + + text-align: center; +} + +.mui-popup-title + .mui-popup-text +{ + font-family: inherit; + font-size: 14px; + + margin: 5px 0 0; +} + +.mui-popup-buttons +{ + position: relative; + + display: -webkit-box; + display: -webkit-flex; + display: flex; + + height: 44px; + + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; +} + +.mui-popup-button +{ + font-size: 17px; + line-height: 44px; + + position: relative; + + display: block; + overflow: hidden; + + box-sizing: border-box; + width: 100%; + height: 44px; + padding: 0 5px; + + cursor: pointer; + text-align: center; + white-space: nowrap; + text-overflow: ellipsis; + + color: #007aff; + background: rgba(255, 255, 255, .95); + + -webkit-box-flex: 1; +} +.mui-popup-button:after +{ + position: absolute; + z-index: 15; + top: 0; + right: 0; + bottom: auto; + left: auto; + + display: block; + + width: 1px; + height: 100%; + + content: ''; + -webkit-transform: scaleX(.5); + transform: scaleX(.5); + -webkit-transform-origin: 100% 50%; + transform-origin: 100% 50%; + + background-color: rgba(0, 0, 0, .2); +} +.mui-popup-button:first-child +{ + border-radius: 0 0 0 13px; +} +.mui-popup-button:first-child:last-child +{ + border-radius: 0 0 13px 13px; +} +.mui-popup-button:last-child +{ + border-radius: 0 0 13px 0; +} +.mui-popup-button:last-child:after +{ + display: none; +} +.mui-popup-button.mui-popup-button-bold +{ + font-weight: 600; +} + +.mui-popup-input input +{ + font-size: 14px; + + width: 100%; + height: 26px; + margin: 15px 0 0; + padding: 0 5px; + + border: 1px solid rgba(0, 0, 0, .3); + border-radius: 0; + background: #fff; +} + +.mui-plus.mui-android .mui-popup-backdrop +{ + -webkit-transition-duration: 1ms; + transition-duration: 1ms; +} + +.mui-plus.mui-android .mui-popup +{ + -webkit-transition-duration: 1ms; + transition-duration: 1ms; + -webkit-transform: translate3d(-50%, -50%, 0) scale(1); + transform: translate3d(-50%, -50%, 0) scale(1); +} + +/* === Progress Bar === */ +.mui-progressbar +{ + position: relative; + + display: block; + overflow: hidden; + + width: 100%; + height: 2px; + + -webkit-transform-origin: center top; + transform-origin: center top; + vertical-align: middle; + + border-radius: 2px; + background: #b6b6b6; + + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.mui-progressbar span +{ + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + -webkit-transition: 150ms; + transition: 150ms; + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + + background: #007aff; +} +.mui-progressbar.mui-progressbar-infinite:before +{ + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + content: ''; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + -webkit-transform-origin: left center; + transform-origin: left center; + -webkit-animation: mui-progressbar-infinite 1s linear infinite; + animation: mui-progressbar-infinite 1s linear infinite; + + background: #007aff; +} + +body > .mui-progressbar +{ + position: absolute; + z-index: 10000; + top: 44px; + left: 0; + + border-radius: 0; +} + +.mui-progressbar-in +{ + -webkit-animation: mui-progressbar-in 300ms forwards; + animation: mui-progressbar-in 300ms forwards; +} + +.mui-progressbar-out +{ + -webkit-animation: mui-progressbar-out 300ms forwards; + animation: mui-progressbar-out 300ms forwards; +} + +@-webkit-keyframes mui-progressbar-in +{ + from + { + -webkit-transform: scaleY(0); + + opacity: 0; + } + + to + { + -webkit-transform: scaleY(1); + + opacity: 1; + } +} +@keyframes mui-progressbar-in +{ + from + { + transform: scaleY(0); + + opacity: 0; + } + + to + { + transform: scaleY(1); + + opacity: 1; + } +} +@-webkit-keyframes mui-progressbar-out +{ + from + { + -webkit-transform: scaleY(1); + + opacity: 1; + } + + to + { + -webkit-transform: scaleY(0); + + opacity: 0; + } +} +@keyframes mui-progressbar-out +{ + from + { + transform: scaleY(1); + + opacity: 1; + } + + to + { + transform: scaleY(0); + + opacity: 0; + } +} +@-webkit-keyframes mui-progressbar-infinite +{ + 0% + { + -webkit-transform: translate3d(-50%, 0, 0) scaleX(.5); + } + + 100% + { + -webkit-transform: translate3d(100%, 0, 0) scaleX(.5); + } +} +@keyframes mui-progressbar-infinite +{ + 0% + { + transform: translate3d(-50%, 0, 0) scaleX(.5); + } + + 100% + { + transform: translate3d(100%, 0, 0) scaleX(.5); + } +} +.mui-pagination +{ + display: inline-block; + + margin: 0 auto; + padding-left: 0; + + border-radius: 6px; +} +.mui-pagination > li +{ + display: inline; +} +.mui-pagination > li > a, +.mui-pagination > li > span +{ + line-height: 1.428571429; + + position: relative; + + float: left; + + margin-left: -1px; + padding: 6px 12px; + + text-decoration: none; + + color: #007aff; + border: 1px solid #ddd; + background-color: #fff; +} +.mui-pagination > li:first-child > a, +.mui-pagination > li:first-child > span +{ + margin-left: 0; + + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; + background-clip: padding-box; +} +.mui-pagination > li:last-child > a, +.mui-pagination > li:last-child > span +{ + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; + background-clip: padding-box; +} +.mui-pagination > li:active > a, .mui-pagination > li:active > a:active, +.mui-pagination > li:active > span, +.mui-pagination > li:active > span:active, +.mui-pagination > li.mui-active > a, +.mui-pagination > li.mui-active > a:active, +.mui-pagination > li.mui-active > span, +.mui-pagination > li.mui-active > span:active +{ + z-index: 2; + + cursor: default; + + color: #fff; + border-color: #007aff; + background-color: #007aff; +} +.mui-pagination > li.mui-disabled > span, +.mui-pagination > li.mui-disabled > span:active, +.mui-pagination > li.mui-disabled > a, +.mui-pagination > li.mui-disabled > a:active +{ + opacity: .6; + color: #777; + border: 1px solid #ddd; + background-color: #fff; +} + +.mui-pagination-lg > li > a, +.mui-pagination-lg > li > span +{ + font-size: 18px; + + padding: 10px 16px; +} + +.mui-pagination-sm > li > a, +.mui-pagination-sm > li > span +{ + font-size: 12px; + + padding: 5px 10px; +} + +.mui-pager +{ + padding-left: 0; + + list-style: none; + + text-align: center; +} +.mui-pager:before, .mui-pager:after +{ + display: table; + + content: ' '; +} +.mui-pager:after +{ + clear: both; +} +.mui-pager li +{ + display: inline; +} +.mui-pager li > a, +.mui-pager li > span +{ + display: inline-block; + + padding: 5px 14px; + + border: 1px solid #ddd; + border-radius: 6px; + background-color: #fff; + background-clip: padding-box; +} +.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span +{ + cursor: default; + text-decoration: none; + + color: #fff; + border-color: #007aff; + background-color: #007aff; +} +.mui-pager .mui-next > a, +.mui-pager .mui-next > span +{ + float: right; +} +.mui-pager .mui-previous > a, +.mui-pager .mui-previous > span +{ + float: left; +} +.mui-pager .mui-disabled > a, +.mui-pager .mui-disabled > a:active, +.mui-pager .mui-disabled > span, +.mui-pager .mui-disabled > span:active +{ + opacity: .6; + color: #777; + border: 1px solid #ddd; + background-color: #fff; +} + +.mui-modal +{ + position: fixed; + z-index: 999; + top: 0; + + overflow: hidden; + + width: 100%; + min-height: 100%; + + -webkit-transition: -webkit-transform .25s, opacity 1ms .25s; + transition: transform .25s, opacity 1ms .25s; + -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1); + transition-timing-function: cubic-bezier(.1, .5, .1, 1); + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + + opacity: 0; + background-color: #fff; +} +.mui-modal.mui-active +{ + height: 100%; + + -webkit-transition: -webkit-transform .25s; + transition: transform .25s; + -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1); + transition-timing-function: cubic-bezier(.1, .5, .1, 1); + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + + opacity: 1; +} + +.mui-android .mui-modal .mui-bar +{ + position: static; +} + +.mui-android .mui-modal .mui-bar-nav ~ .mui-content +{ + padding-top: 0; +} + +.mui-slider +{ + position: relative; + z-index: 1; + + overflow: hidden; + + width: 100%; +} +.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active +{ + border-bottom: 0; +} +.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item +{ + border-top: 1px solid #c8c7cc; + border-bottom: 1px solid #c8c7cc; +} +.mui-slider .mui-slider-group +{ + font-size: 0; + + position: relative; + + -webkit-transition: all 0s linear; + transition: all 0s linear; + white-space: nowrap; +} +.mui-slider .mui-slider-group .mui-slider-item +{ + font-size: 14px; + + position: relative; + + display: inline-block; + + width: 100%; + height: 100%; + + vertical-align: top; + white-space: normal; +} +.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item) +{ + line-height: 0; + + position: relative; + + display: block; +} +.mui-slider .mui-slider-group .mui-slider-item img +{ + width: 100%; +} +.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after +{ + height: 0; +} +.mui-slider .mui-slider-group.mui-slider-loop +{ + -webkit-transform: translate(-100%, 0px); + transform: translate(-100%, 0px); +} + +.mui-slider-title +{ + line-height: 30px; + + position: absolute; + bottom: 0; + left: 0; + + width: 100%; + height: 30px; + margin: 0; + + text-align: left; + text-indent: 12px; + + opacity: .8; + background-color: #000; +} + +.mui-slider-indicator +{ + position: absolute; + bottom: 8px; + + width: 100%; + + text-align: center; + + background: none; +} +.mui-slider-indicator.mui-segmented-control +{ + position: relative; + bottom: auto; +} +.mui-slider-indicator .mui-indicator +{ + display: inline-block; + + width: 6px; + height: 6px; + margin: 1px 6px; + + cursor: pointer; + + border-radius: 50%; + background: #aaa; + -webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7); + box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7); +} +.mui-slider-indicator .mui-active.mui-indicator +{ + background: #fff; +} +.mui-slider-indicator .mui-icon +{ + font-size: 20px; + line-height: 30px; + + width: 40px; + height: 30px; + margin: 3px; + + text-align: center; + + border: 1px solid #ddd; +} +.mui-slider-indicator .mui-number +{ + line-height: 32px; + + display: inline-block; + + width: 58px; +} +.mui-slider-indicator .mui-number span +{ + color: #ff5053; +} + +.mui-slider-progress-bar +{ + z-index: 1; + + height: 2px; + + -webkit-transform: translateZ(0); + transform: translateZ(0); +} + +.mui-switch +{ + position: relative; + + display: block; + + width: 74px; + height: 30px; + + -webkit-transition-timing-function: ease-in-out; + transition-timing-function: ease-in-out; + -webkit-transition-duration: .2s; + transition-duration: .2s; + -webkit-transition-property: background-color, border; + transition-property: background-color, border; + + border: 2px solid #ddd; + border-radius: 20px; + background-color: #fff; + background-clip: padding-box; +} +.mui-switch.mui-disabled +{ + opacity: .3; +} +.mui-switch .mui-switch-handle +{ + position: absolute; + z-index: 1; + top: -1px; + left: -1px; + + width: 28px; + height: 28px; + + -webkit-transition: .2s ease-in-out; + transition: .2s ease-in-out; + -webkit-transition-property: -webkit-transform, width,left; + transition-property: transform, width,left; + + border-radius: 16px; + background-color: #fff; + background-clip: padding-box; + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4); + box-shadow: 0 2px 5px rgba(0, 0, 0, .4); +} +.mui-switch:before +{ + font-size: 13px; + + position: absolute; + top: 3px; + right: 11px; + + content: 'Off'; + text-transform: uppercase; + + color: #999; +} +.mui-switch.mui-dragging +{ + border-color: #f7f7f7; + background-color: #f7f7f7; +} +.mui-switch.mui-dragging .mui-switch-handle +{ + width: 38px; +} +.mui-switch.mui-dragging.mui-active .mui-switch-handle +{ + left: -11px; + + width: 38px; +} +.mui-switch.mui-active +{ + border-color: #4cd964; + background-color: #4cd964; +} +.mui-switch.mui-active .mui-switch-handle +{ + -webkit-transform: translate(43px, 0); + transform: translate(43px, 0); +} +.mui-switch.mui-active:before +{ + right: auto; + left: 15px; + + content: 'On'; + + color: #fff; +} +.mui-switch input[type='checkbox'] +{ + display: none; +} + +.mui-switch-mini +{ + width: 47px; +} +.mui-switch-mini:before +{ + display: none; +} +.mui-switch-mini.mui-active .mui-switch-handle +{ + -webkit-transform: translate(16px, 0); + transform: translate(16px, 0); +} + +.mui-switch-blue.mui-active +{ + border: 2px solid #007aff; + background-color: #007aff; +} + +.mui-content.mui-fade +{ + left: 0; + + opacity: 0; +} +.mui-content.mui-fade.mui-in +{ + opacity: 1; +} +.mui-content.mui-sliding +{ + z-index: 2; + + -webkit-transition: -webkit-transform .4s; + transition: transform .4s; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.mui-content.mui-sliding.mui-left +{ + z-index: 1; + + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); +} +.mui-content.mui-sliding.mui-right +{ + z-index: 3; + + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); +} + +.mui-navigate-right:after, +.mui-push-left:after, +.mui-push-right:after +{ + font-family: Muiicons; + font-size: inherit; + line-height: 1; + + position: absolute; + top: 50%; + + display: inline-block; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + text-decoration: none; + + color: #bbb; + + -webkit-font-smoothing: antialiased; +} + +.mui-push-left:after +{ + left: 15px; + + content: '\e582'; +} + +.mui-navigate-right:after, +.mui-push-right:after +{ + right: 15px; + + content: '\e583'; +} + +.mui-pull-top-pocket, .mui-pull-bottom-pocket +{ + position: absolute; + left: 0; + + display: block; + visibility: hidden; + overflow: hidden; + + width: 100%; + height: 50px; +} + +.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket +{ + display: none; + visibility: visible; +} + +.mui-pull-top-pocket +{ + top: 0; +} + +.mui-bar-nav ~ .mui-content .mui-pull-top-pocket +{ + top: 44px; +} + +.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket +{ + top: 88px; +} + +.mui-pull-bottom-pocket +{ + position: relative; + bottom: 0; + + height: 40px; +} +.mui-pull-bottom-pocket .mui-pull-loading +{ + visibility: hidden; +} +.mui-pull-bottom-pocket .mui-pull-loading.mui-in +{ + display: inline-block; +} + +.mui-pull +{ + font-weight: bold; + + position: absolute; + right: 0; + bottom: 10px; + left: 0; + + text-align: center; + + color: #777; +} + +.mui-pull-loading +{ + margin-right: 10px; + + -webkit-transition: -webkit-transform .4s; + transition: transform .4s; + -webkit-transition-duration: 400ms; + transition-duration: 400ms; + vertical-align: middle; +} + +.mui-pull-loading.mui-reverse +{ + -webkit-transform: rotate(180deg) translateZ(0); + transform: rotate(180deg) translateZ(0); +} + +.mui-pull-caption +{ + font-size: 15px; + line-height: 24px; + + position: relative; + + display: inline-block; + overflow: visible; + + margin-top: 0; + + vertical-align: middle; +} +.mui-pull-caption span +{ + display: none; +} +.mui-pull-caption span.mui-in +{ + display: inline; +} + +.mui-toast-container +{ + line-height: 17px; + + position: fixed; + z-index: 9999; + bottom: 50px; + left: 50%; + + -webkit-transition: opacity .3s; + transition: opacity .3s; + -webkit-transform: translate(-50%, 0); + transform: translate(-50%, 0); + + opacity: 0; +} +.mui-toast-container.mui-active +{ + opacity: .9; +} + +.mui-toast-message +{ + font-size: 14px; + + padding: 10px 25px; + + text-align: center; + + color: #fff; + border-radius: 6px; + background-color: #323232; +} + +.mui-numbox +{ + position: relative; + + display: inline-block; + overflow: hidden; + + width: 120px; + height: 35px; + padding: 0 40px 0 40px; + + vertical-align: top; + vertical-align: middle; + + border: solid 1px #bbb; + border-radius: 3px; + background-color: #efeff4; +} +.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox] +{ + font-size: 18px; + font-weight: normal; + line-height: 100%; + + position: absolute; + top: 0; + + overflow: hidden; + + width: 40px; + height: 100%; + padding: 0; + + color: #555; + border: none; + border-radius: 0; + background-color: #f9f9f9; +} +.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active +{ + background-color: #ccc; +} +.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled] +{ + color: #c0c0c0; +} +.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus +{ + right: 0; + + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus +{ + left: 0; + + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox +{ + display: inline-block; + overflow: hidden; + + width: 100% !important; + height: 100%; + margin: 0; + padding: 0 3px !important; + + text-align: center; + text-overflow: ellipsis; + word-break: normal; + + border: none !important; + border-right: solid 1px #ccc !important; + border-left: solid 1px #ccc !important; + border-radius: 0 !important; +} + +.mui-input-row .mui-numbox +{ + float: right; + + margin: 2px 8px; +} + +@font-face { + font-family: Muiicons; + font-weight: normal; + font-style: normal; + + src: url('../fonts/mui.ttf') format('truetype'); +} +.mui-icon +{ + font-family: Muiicons; + font-size: 24px; + font-weight: normal; + font-style: normal; + line-height: 1; + + display: inline-block; + + text-decoration: none; + + -webkit-font-smoothing: antialiased; +} +.mui-icon.mui-active +{ + color: #007aff; +} +.mui-icon.mui-right:before +{ + float: right; + + padding-left: .2em; +} + +.mui-icon-contact:before +{ + content: '\e100'; +} + +.mui-icon-person:before +{ + content: '\e101'; +} + +.mui-icon-personadd:before +{ + content: '\e102'; +} + +.mui-icon-contact-filled:before +{ + content: '\e130'; +} + +.mui-icon-person-filled:before +{ + content: '\e131'; +} + +.mui-icon-personadd-filled:before +{ + content: '\e132'; +} + +.mui-icon-phone:before +{ + content: '\e200'; +} + +.mui-icon-email:before +{ + content: '\e201'; +} + +.mui-icon-chatbubble:before +{ + content: '\e202'; +} + +.mui-icon-chatboxes:before +{ + content: '\e203'; +} + +.mui-icon-phone-filled:before +{ + content: '\e230'; +} + +.mui-icon-email-filled:before +{ + content: '\e231'; +} + +.mui-icon-chatbubble-filled:before +{ + content: '\e232'; +} + +.mui-icon-chatboxes-filled:before +{ + content: '\e233'; +} + +.mui-icon-weibo:before +{ + content: '\e260'; +} + +.mui-icon-weixin:before +{ + content: '\e261'; +} + +.mui-icon-pengyouquan:before +{ + content: '\e262'; +} + +.mui-icon-chat:before +{ + content: '\e263'; +} + +.mui-icon-qq:before +{ + content: '\e264'; +} + +.mui-icon-videocam:before +{ + content: '\e300'; +} + +.mui-icon-camera:before +{ + content: '\e301'; +} + +.mui-icon-mic:before +{ + content: '\e302'; +} + +.mui-icon-location:before +{ + content: '\e303'; +} + +.mui-icon-mic-filled:before, .mui-icon-speech:before +{ + content: '\e332'; +} + +.mui-icon-location-filled:before +{ + content: '\e333'; +} + +.mui-icon-micoff:before +{ + content: '\e360'; +} + +.mui-icon-image:before +{ + content: '\e363'; +} + +.mui-icon-map:before +{ + content: '\e364'; +} + +.mui-icon-compose:before +{ + content: '\e400'; +} + +.mui-icon-trash:before +{ + content: '\e401'; +} + +.mui-icon-upload:before +{ + content: '\e402'; +} + +.mui-icon-download:before +{ + content: '\e403'; +} + +.mui-icon-close:before +{ + content: '\e404'; +} + +.mui-icon-redo:before +{ + content: '\e405'; +} + +.mui-icon-undo:before +{ + content: '\e406'; +} + +.mui-icon-refresh:before +{ + content: '\e407'; +} + +.mui-icon-star:before +{ + content: '\e408'; +} + +.mui-icon-plus:before +{ + content: '\e409'; +} + +.mui-icon-minus:before +{ + content: '\e410'; +} + +.mui-icon-circle:before, .mui-icon-checkbox:before +{ + content: '\e411'; +} + +.mui-icon-close-filled:before, .mui-icon-clear:before +{ + content: '\e434'; +} + +.mui-icon-refresh-filled:before +{ + content: '\e437'; +} + +.mui-icon-star-filled:before +{ + content: '\e438'; +} + +.mui-icon-plus-filled:before +{ + content: '\e439'; +} + +.mui-icon-minus-filled:before +{ + content: '\e440'; +} + +.mui-icon-circle-filled:before +{ + content: '\e441'; +} + +.mui-icon-checkbox-filled:before +{ + content: '\e442'; +} + +.mui-icon-closeempty:before +{ + content: '\e460'; +} + +.mui-icon-refreshempty:before +{ + content: '\e461'; +} + +.mui-icon-reload:before +{ + content: '\e462'; +} + +.mui-icon-starhalf:before +{ + content: '\e463'; +} + +.mui-icon-spinner:before +{ + content: '\e464'; +} + +.mui-icon-spinner-cycle:before +{ + content: '\e465'; +} + +.mui-icon-search:before +{ + content: '\e466'; +} + +.mui-icon-plusempty:before +{ + content: '\e468'; +} + +.mui-icon-forward:before +{ + content: '\e470'; +} + +.mui-icon-back:before, .mui-icon-left-nav:before +{ + content: '\e471'; +} + +.mui-icon-checkmarkempty:before +{ + content: '\e472'; +} + +.mui-icon-home:before +{ + content: '\e500'; +} + +.mui-icon-navigate:before +{ + content: '\e501'; +} + +.mui-icon-gear:before +{ + content: '\e502'; +} + +.mui-icon-paperplane:before +{ + content: '\e503'; +} + +.mui-icon-info:before +{ + content: '\e504'; +} + +.mui-icon-help:before +{ + content: '\e505'; +} + +.mui-icon-locked:before +{ + content: '\e506'; +} + +.mui-icon-more:before +{ + content: '\e507'; +} + +.mui-icon-flag:before +{ + content: '\e508'; +} + +.mui-icon-home-filled:before +{ + content: '\e530'; +} + +.mui-icon-gear-filled:before +{ + content: '\e532'; +} + +.mui-icon-info-filled:before +{ + content: '\e534'; +} + +.mui-icon-help-filled:before +{ + content: '\e535'; +} + +.mui-icon-more-filled:before +{ + content: '\e537'; +} + +.mui-icon-settings:before +{ + content: '\e560'; +} + +.mui-icon-list:before +{ + content: '\e562'; +} + +.mui-icon-bars:before +{ + content: '\e563'; +} + +.mui-icon-loop:before +{ + content: '\e565'; +} + +.mui-icon-paperclip:before +{ + content: '\e567'; +} + +.mui-icon-eye:before +{ + content: '\e568'; +} + +.mui-icon-arrowup:before +{ + content: '\e580'; +} + +.mui-icon-arrowdown:before +{ + content: '\e581'; +} + +.mui-icon-arrowleft:before +{ + content: '\e582'; +} + +.mui-icon-arrowright:before +{ + content: '\e583'; +} + +.mui-icon-arrowthinup:before +{ + content: '\e584'; +} + +.mui-icon-arrowthindown:before +{ + content: '\e585'; +} + +.mui-icon-arrowthinleft:before +{ + content: '\e586'; +} + +.mui-icon-arrowthinright:before +{ + content: '\e587'; +} + +.mui-icon-pulldown:before +{ + content: '\e588'; +} + +.mui-fullscreen +{ + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.mui-fullscreen.mui-slider .mui-slider-group +{ + height: 100%; +} +.mui-fullscreen .mui-segmented-control ~ .mui-slider-group +{ + position: absolute; + top: 40px; + bottom: 0; + + width: 100%; + height: auto; +} +.mui-fullscreen.mui-slider .mui-slider-item > a +{ + top: 50%; + + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a +{ + top: auto; + + -webkit-transform: none; + transform: none; +} + +.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen +{ + top: 44px; +} + +.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group +{ + bottom: 50px; +} + +.mui-android.mui-android-4-0 input:focus, +.mui-android.mui-android-4-0 textarea:focus +{ + -webkit-user-modify: inherit; +} + +.mui-android.mui-android-4-2 input, +.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input, +.mui-android.mui-android-4-3 textarea +{ + -webkit-user-select: text; +} + +.mui-ios .mui-table-view-cell +{ + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} + +.mui-plus-visible, .mui-wechat-visible +{ + display: none !important; +} + +.mui-plus-hidden, .mui-wechat-hidden +{ + display: block !important; +} + +.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden +{ + display: table-cell !important; +} + +.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible +{ + display: block !important; +} + +.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible +{ + display: table-cell !important; +} + +.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden +{ + display: none !important; +} + +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav +{ + height: 64px; + padding-top: 20px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content +{ + padding-top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket +{ + top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary +{ + top: 64px; +} +.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content +{ + padding-top: 94px; +} + +.mui-iframe-wrapper +{ + position: absolute; + right: 0; + left: 0; + + -webkit-overflow-scrolling: touch; +} +.mui-iframe-wrapper iframe +{ + width: 100%; + height: 100%; + + border: 0; +} diff --git a/static/app2/css/mui.min.css b/static/app2/css/mui.min.css new file mode 100755 index 0000000..c330ba6 --- /dev/null +++ b/static/app2/css/mui.min.css @@ -0,0 +1,5 @@ +/*! + * ===================================================== + * Mui v3.7.2 (http://dev.dcloud.net.cn/mui) + * ===================================================== + *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{font:inherit;margin:0;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button}button[disabled],html input[disabled]{cursor:default}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{margin:0 2px;padding:.35em .625em .75em;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}*{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-select:none;outline:0;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}body{font-family:'Helvetica Neue',Helvetica,sans-serif;font-size:17px;line-height:21px;color:#000;background-color:#efeff4;-webkit-overflow-scrolling:touch}a{text-decoration:none;color:#007aff}a:active{color:#0062cc}.mui-content{background-color:#efeff4;-webkit-overflow-scrolling:touch}.mui-bar-nav~.mui-content{padding-top:44px}.mui-bar-nav~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{top:44px}.mui-bar-header-secondary~.mui-content{padding-top:88px}.mui-bar-header-secondary~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{top:88px}.mui-bar-footer~.mui-content{padding-bottom:44px}.mui-bar-footer~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:44px}.mui-bar-footer-secondary~.mui-content{padding-bottom:88px}.mui-bar-footer-secondary~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:88px}.mui-bar-tab~.mui-content{padding-bottom:50px}.mui-bar-tab~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:50px}.mui-bar-footer-secondary-tab~.mui-content{padding-bottom:94px}.mui-bar-footer-secondary-tab~.mui-content.mui-scroll-wrapper .mui-scrollbar-vertical{bottom:94px}.mui-content-padded{margin:10px}.mui-inline{display:inline-block;vertical-align:top}.mui-block{display:block!important}.mui-visibility{visibility:visible!important}.mui-hidden{display:none!important}.mui-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.mui-ellipsis-2{display:-webkit-box;overflow:hidden;white-space:normal!important;text-overflow:ellipsis;word-wrap:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical}.mui-table{display:table;width:100%;table-layout:fixed}.mui-table-cell{position:relative;display:table-cell}.mui-text-left{text-align:left!important}.mui-text-center{text-align:center!important}.mui-text-justify{text-align:justify!important}.mui-text-right{text-align:right!important}.mui-pull-left{float:left}.mui-pull-right{float:right}.mui-list-unstyled{padding-left:0;list-style:none}.mui-list-inline{margin-left:-5px;padding-left:0;list-style:none}.mui-list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}.mui-clearfix:after,.mui-clearfix:before{display:table;content:' '}.mui-clearfix:after{clear:both}.mui-bg-primary{background-color:#007aff}.mui-bg-positive{background-color:#4cd964}.mui-bg-negative{background-color:#dd524d}.mui-error{margin:88px 35px;padding:10px;border-radius:6px;background-color:#bbb}.mui-subtitle{font-size:15px}h1,h2,h3,h4,h5,h6{line-height:1;margin-top:5px;margin-bottom:5px}.mui-h1,h1{font-size:36px}.mui-h2,h2{font-size:30px}.mui-h3,h3{font-size:24px}.mui-h4,h4{font-size:18px}.mui-h5,h5{font-size:14px;font-weight:400;color:#8f8f94}.mui-h6,h6{font-size:12px;font-weight:400;color:#8f8f94}p{font-size:14px;margin-top:0;margin-bottom:10px;color:#8f8f94}.mui-row:after,.mui-row:before{display:table;content:' '}.mui-row:after{clear:both}.mui-col-sm-1,.mui-col-sm-10,.mui-col-sm-11,.mui-col-sm-12,.mui-col-sm-2,.mui-col-sm-3,.mui-col-sm-4,.mui-col-sm-5,.mui-col-sm-6,.mui-col-sm-7,.mui-col-sm-8,.mui-col-sm-9,.mui-col-xs-1,.mui-col-xs-10,.mui-col-xs-11,.mui-col-xs-12,.mui-col-xs-2,.mui-col-xs-3,.mui-col-xs-4,.mui-col-xs-5,.mui-col-xs-6,.mui-col-xs-7,.mui-col-xs-8,.mui-col-xs-9{position:relative;min-height:1px}.mui-row>[class*=mui-col-]{float:left}.mui-col-xs-12{width:100%}.mui-col-xs-11{width:91.66666667%}.mui-col-xs-10{width:83.33333333%}.mui-col-xs-9{width:75%}.mui-col-xs-8{width:66.66666667%}.mui-col-xs-7{width:58.33333333%}.mui-col-xs-6{width:50%}.mui-col-xs-5{width:41.66666667%}.mui-col-xs-4{width:33.33333333%}.mui-col-xs-3{width:25%}.mui-col-xs-2{width:16.66666667%}.mui-col-xs-1{width:8.33333333%}@media (min-width:400px){.mui-col-sm-12{width:100%}.mui-col-sm-11{width:91.66666667%}.mui-col-sm-10{width:83.33333333%}.mui-col-sm-9{width:75%}.mui-col-sm-8{width:66.66666667%}.mui-col-sm-7{width:58.33333333%}.mui-col-sm-6{width:50%}.mui-col-sm-5{width:41.66666667%}.mui-col-sm-4{width:33.33333333%}.mui-col-sm-3{width:25%}.mui-col-sm-2{width:16.66666667%}.mui-col-sm-1{width:8.33333333%}}.mui-scroll-wrapper{position:absolute;z-index:2;top:0;bottom:0;left:0;overflow:hidden;width:100%}.mui-scroll{position:absolute;z-index:1;width:100%}.mui-scrollbar{position:absolute;z-index:9998;overflow:hidden;-webkit-transition:500ms;transition:500ms;transform:translateZ(0px);pointer-events:none;opacity:0}.mui-scrollbar-vertical{top:0;right:1px;bottom:2px;width:4px}.mui-scrollbar-vertical .mui-scrollbar-indicator{width:100%}.mui-scrollbar-horizontal{right:2px;bottom:0;left:2px;height:4px}.mui-scrollbar-horizontal .mui-scrollbar-indicator{height:100%}.mui-scrollbar-indicator{position:absolute;display:block;box-sizing:border-box;-webkit-transition:.01s cubic-bezier(.1,.57,.1,1);transition:.01s cubic-bezier(.1,.57,.1,1);transform:translate(0px,0) translateZ(0px);border:1px solid rgba(255,255,255,.80196);border-radius:2px;background:rgba(0,0,0,.39804)}.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper,.mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper{position:absolute;top:0;bottom:0;left:0;overflow:hidden;width:100%}.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll,.mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll{position:absolute;width:100%}.mui-plus-pullrefresh .mui-scroll-wrapper,.mui-plus-pullrefresh .mui-slider-group{position:static;top:auto;bottom:auto;left:auto;overflow:auto;width:auto}.mui-plus-pullrefresh .mui-slider-group{overflow:visible}.mui-plus-pullrefresh .mui-scroll{position:static;width:auto}.mui-off-canvas-wrap .mui-bar{position:absolute!important;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-box-shadow:none;box-shadow:none}.mui-off-canvas-wrap{position:relative;z-index:1;overflow:hidden;width:100%;height:100%}.mui-off-canvas-wrap .mui-inner-wrap{position:relative;z-index:1;width:100%;height:100%}.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning{-webkit-transition:-webkit-transform 350ms;transition:transform 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.mui-off-canvas-wrap.mui-active{overflow:hidden;height:100%}.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop{position:absolute;z-index:998;top:0;right:0;bottom:0;left:0;display:block;transition:background 350ms cubic-bezier(.165,.84,.44,1);background:rgba(0,0,0,.4);box-shadow:-4px 0 4px rgba(0,0,0,.5),4px 0 4px rgba(0,0,0,.5);-webkit-tap-highlight-color:transparent}.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right{z-index:10000!important;-webkit-transform:translate3d(100%,0,0)}.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left{z-index:10000!important;-webkit-transform:translate3d(-100%,0,0)}.mui-off-canvas-left,.mui-off-canvas-right{position:absolute;z-index:-1;top:0;bottom:0;visibility:hidden;box-sizing:content-box;width:70%;min-height:100%;background:#333;-webkit-overflow-scrolling:touch}.mui-off-canvas-left.mui-transitioning,.mui-off-canvas-right.mui-transitioning{-webkit-transition:-webkit-transform 350ms cubic-bezier(.165,.84,.44,1);transition:transform 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-left{left:0}.mui-off-canvas-right{right:0}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable{background-color:#333}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right{width:80%;-webkit-transform:scale(.8);transform:scale(.8);opacity:.1}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left.mui-transitioning,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right.mui-transitioning{-webkit-transition:-webkit-transform 350ms cubic-bezier(.165,.84,.44,1),opacity 350ms cubic-bezier(.165,.84,.44,1);transition:transform 350ms cubic-bezier(.165,.84,.44,1),opacity 350ms cubic-bezier(.165,.84,.44,1)}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-left{-webkit-transform-origin:-100%;transform-origin:-100%}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable>.mui-off-canvas-right{-webkit-transform-origin:200%;transform-origin:200%}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-inner-wrap{-webkit-transform:scale(.8);transform:scale(.8)}.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-off-canvas-left,.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active>.mui-off-canvas-right{-webkit-transform:scale(1);transform:scale(1);opacity:1}.mui-loading .mui-spinner{display:block;margin:0 auto}.mui-spinner{display:inline-block;width:24px;height:24px;-webkit-transform-origin:50%;transform-origin:50%;-webkit-animation:spinner-spin 1s step-end infinite;animation:spinner-spin 1s step-end infinite}.mui-spinner:after{display:block;width:100%;height:100%;content:'';background-image:url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');background-repeat:no-repeat;background-position:50%;background-size:100%}.mui-spinner-white:after{background-image:url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>')}@-webkit-keyframes spinner-spin{0%{-webkit-transform:rotate(0deg)}8.33333333%{-webkit-transform:rotate(30deg)}16.66666667%{-webkit-transform:rotate(60deg)}25%{-webkit-transform:rotate(90deg)}33.33333333%{-webkit-transform:rotate(120deg)}41.66666667%{-webkit-transform:rotate(150deg)}50%{-webkit-transform:rotate(180deg)}58.33333333%{-webkit-transform:rotate(210deg)}66.66666667%{-webkit-transform:rotate(240deg)}75%{-webkit-transform:rotate(270deg)}83.33333333%{-webkit-transform:rotate(300deg)}91.66666667%{-webkit-transform:rotate(330deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes spinner-spin{0%{transform:rotate(0deg)}8.33333333%{transform:rotate(30deg)}16.66666667%{transform:rotate(60deg)}25%{transform:rotate(90deg)}33.33333333%{transform:rotate(120deg)}41.66666667%{transform:rotate(150deg)}50%{transform:rotate(180deg)}58.33333333%{transform:rotate(210deg)}66.66666667%{transform:rotate(240deg)}75%{transform:rotate(270deg)}83.33333333%{transform:rotate(300deg)}91.66666667%{transform:rotate(330deg)}100%{transform:rotate(360deg)}}.mui-btn,button,input[type=button],input[type=reset],input[type=submit]{font-size:14px;font-weight:400;line-height:1.42;position:relative;display:inline-block;margin-bottom:0;padding:6px 12px;cursor:pointer;-webkit-transition:all;transition:all;-webkit-transition-timing-function:linear;transition-timing-function:linear;-webkit-transition-duration:.2s;transition-duration:.2s;text-align:center;vertical-align:top;white-space:nowrap;color:#333;border:1px solid #ccc;border-radius:3px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;background-color:#fff;background-clip:padding-box}.mui-btn.mui-active:enabled,.mui-btn:enabled:active,button.mui-active:enabled,button:enabled:active,input[type=button].mui-active:enabled,input[type=button]:enabled:active,input[type=reset].mui-active:enabled,input[type=reset]:enabled:active,input[type=submit].mui-active:enabled,input[type=submit]:enabled:active{color:#fff;background-color:#929292}.mui-btn.mui-disabled,.mui-btn:disabled,button.mui-disabled,button:disabled,input[type=button].mui-disabled,input[type=button]:disabled,input[type=reset].mui-disabled,input[type=reset]:disabled,input[type=submit].mui-disabled,input[type=submit]:disabled{opacity:.6}.mui-btn-blue,.mui-btn-primary,input[type=submit]{color:#fff;border:1px solid #007aff;background-color:#007aff}.mui-btn-blue.mui-active:enabled,.mui-btn-blue:enabled:active,.mui-btn-primary.mui-active:enabled,.mui-btn-primary:enabled:active,input[type=submit].mui-active:enabled,input[type=submit]:enabled:active{color:#fff;border:1px solid #0062cc;background-color:#0062cc}.mui-btn-green,.mui-btn-positive,.mui-btn-success{color:#fff;border:1px solid #4cd964;background-color:#4cd964}.mui-btn-green.mui-active:enabled,.mui-btn-green:enabled:active,.mui-btn-positive.mui-active:enabled,.mui-btn-positive:enabled:active,.mui-btn-success.mui-active:enabled,.mui-btn-success:enabled:active{color:#fff;border:1px solid #2ac845;background-color:#2ac845}.mui-btn-warning,.mui-btn-yellow{color:#fff;border:1px solid #f0ad4e;background-color:#f0ad4e}.mui-btn-warning.mui-active:enabled,.mui-btn-warning:enabled:active,.mui-btn-yellow.mui-active:enabled,.mui-btn-yellow:enabled:active{color:#fff;border:1px solid #ec971f;background-color:#ec971f}.mui-btn-danger,.mui-btn-negative,.mui-btn-red{color:#fff;border:1px solid #dd524d;background-color:#dd524d}.mui-btn-danger.mui-active:enabled,.mui-btn-danger:enabled:active,.mui-btn-negative.mui-active:enabled,.mui-btn-negative:enabled:active,.mui-btn-red.mui-active:enabled,.mui-btn-red:enabled:active{color:#fff;border:1px solid #cf2d28;background-color:#cf2d28}.mui-btn-purple,.mui-btn-royal{color:#fff;border:1px solid #8a6de9;background-color:#8a6de9}.mui-btn-purple.mui-active:enabled,.mui-btn-purple:enabled:active,.mui-btn-royal.mui-active:enabled,.mui-btn-royal:enabled:active{color:#fff;border:1px solid #6641e2;background-color:#6641e2}.mui-btn-grey{color:#fff;border:1px solid #c7c7cc;background-color:#c7c7cc}.mui-btn-grey.mui-active:enabled,.mui-btn-grey:enabled:active{color:#fff;border:1px solid #acacb4;background-color:#acacb4}.mui-btn-outlined{background-color:transparent}.mui-btn-outlined.mui-btn-blue,.mui-btn-outlined.mui-btn-primary{color:#007aff}.mui-btn-outlined.mui-btn-green,.mui-btn-outlined.mui-btn-positive,.mui-btn-outlined.mui-btn-success{color:#4cd964}.mui-btn-outlined.mui-btn-warning,.mui-btn-outlined.mui-btn-yellow{color:#f0ad4e}.mui-btn-outlined.mui-btn-danger,.mui-btn-outlined.mui-btn-negative,.mui-btn-outlined.mui-btn-red{color:#dd524d}.mui-btn-outlined.mui-btn-purple,.mui-btn-outlined.mui-btn-royal{color:#8a6de9}.mui-btn-outlined.mui-btn-blue:enabled:active,.mui-btn-outlined.mui-btn-danger:enabled:active,.mui-btn-outlined.mui-btn-green:enabled:active,.mui-btn-outlined.mui-btn-negative:enabled:active,.mui-btn-outlined.mui-btn-positive:enabled:active,.mui-btn-outlined.mui-btn-primary:enabled:active,.mui-btn-outlined.mui-btn-purple:enabled:active,.mui-btn-outlined.mui-btn-red:enabled:active,.mui-btn-outlined.mui-btn-royal:enabled:active,.mui-btn-outlined.mui-btn-success:enabled:active,.mui-btn-outlined.mui-btn-warning:enabled:active,.mui-btn-outlined.mui-btn-yellow:enabled:active{color:#fff}.mui-btn-link{padding-top:6px;padding-bottom:6px;color:#007aff;border:0;background-color:transparent}.mui-btn-link.mui-active:enabled,.mui-btn-link:enabled:active{color:#0062cc;background-color:transparent}.mui-btn-block{font-size:18px;display:block;width:100%;margin-bottom:10px;padding:15px 0}.mui-btn .mui-badge{font-size:14px;margin:-2px -4px -2px 4px;background-color:rgba(0,0,0,.15)}.mui-btn .mui-badge-inverted,.mui-btn:enabled:active .mui-badge-inverted{background-color:transparent}.mui-btn-negative:enabled:active .mui-badge-inverted,.mui-btn-positive:enabled:active .mui-badge-inverted,.mui-btn-primary:enabled:active .mui-badge-inverted{color:#fff}.mui-btn-block .mui-badge{position:absolute;right:0;margin-right:10px}.mui-btn .mui-icon{font-size:inherit}.mui-btn.mui-icon{font-size:14px;line-height:1.42}.mui-btn.mui-fab{width:56px;height:56px;padding:16px;border-radius:50%;outline:0}.mui-btn.mui-fab.mui-btn-mini{width:40px;height:40px;padding:8px}.mui-btn.mui-fab .mui-icon{font-size:24px;line-height:24px;width:24px;height:24px}.mui-btn .mui-spinner{width:14px;height:14px;vertical-align:text-bottom}.mui-btn-block .mui-spinner{width:22px;height:22px}.mui-bar{position:fixed;z-index:10;right:0;left:0;height:44px;padding-right:10px;padding-left:10px;border-bottom:0;background-color:#f7f7f7;-webkit-box-shadow:0 0 1px rgba(0,0,0,.85);box-shadow:0 0 1px rgba(0,0,0,.85);-webkit-backface-visibility:hidden;backface-visibility:hidden}.mui-bar .mui-title{right:40px;left:40px;display:inline-block;overflow:hidden;width:auto;margin:0;text-overflow:ellipsis}.mui-bar .mui-backdrop{background:0 0}.mui-bar-header-secondary{top:44px}.mui-bar-footer{bottom:0}.mui-bar-footer-secondary{bottom:44px}.mui-bar-footer-secondary-tab{bottom:50px}.mui-bar-footer,.mui-bar-footer-secondary,.mui-bar-footer-secondary-tab{border-top:0}.mui-bar-transparent{top:0;background-color:rgba(247,247,247,0);-webkit-box-shadow:none;box-shadow:none}.mui-bar-nav{top:0;-webkit-box-shadow:0 1px 6px #ccc;box-shadow:0 1px 6px #ccc}.mui-bar-nav~.mui-content .mui-anchor{display:block;visibility:hidden;height:45px;margin-top:-45px}.mui-bar-nav.mui-bar .mui-icon{margin-right:-10px;margin-left:-10px;padding-right:10px;padding-left:10px}.mui-title{font-size:17px;font-weight:500;line-height:44px;position:absolute;display:block;width:100%;margin:0 -10px;padding:0;text-align:center;white-space:nowrap;color:#000}.mui-title a{color:inherit}.mui-bar-tab{bottom:0;display:table;width:100%;height:50px;padding:0;table-layout:fixed;border-top:0;border-bottom:0;-webkit-touch-callout:none}.mui-bar-tab .mui-tab-item{display:table-cell;overflow:hidden;width:1%;height:50px;text-align:center;vertical-align:middle;white-space:nowrap;text-overflow:ellipsis;color:#929292}.mui-bar-tab .mui-tab-item.mui-active{color:#007aff}.mui-bar-tab .mui-tab-item .mui-icon{top:3px;width:24px;height:24px;padding-top:0;padding-bottom:0}.mui-bar-tab .mui-tab-item .mui-icon~.mui-tab-label{font-size:11px;display:block;overflow:hidden;text-overflow:ellipsis}.mui-bar-tab .mui-tab-item .mui-icon:active{background:0 0}.mui-focusin>.mui-bar-header-secondary,.mui-focusin>.mui-bar-nav{position:absolute}.mui-focusin>.mui-bar~.mui-content{padding-bottom:0}.mui-bar .mui-btn{font-weight:400;position:relative;z-index:20;top:7px;margin-top:0;padding:6px 12px 7px}.mui-bar .mui-btn.mui-pull-right{margin-left:10px}.mui-bar .mui-btn.mui-pull-left{margin-right:10px}.mui-bar .mui-btn-link{font-size:16px;line-height:44px;top:0;padding:0;color:#007aff;border:0}.mui-bar .mui-btn-link.mui-active,.mui-bar .mui-btn-link:active{color:#0062cc}.mui-bar .mui-btn-block{font-size:16px;top:6px;margin-bottom:0;padding:5px 0}.mui-bar .mui-btn-nav.mui-pull-left{margin-left:-5px}.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav{margin-right:-3px}.mui-bar .mui-btn-nav.mui-pull-right{margin-right:-5px}.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav{margin-left:-3px}.mui-bar .mui-btn-nav:active{opacity:.3}.mui-bar .mui-icon{font-size:24px;position:relative;z-index:20;padding-top:10px;padding-bottom:10px}.mui-bar .mui-icon:active{opacity:.3}.mui-bar .mui-btn .mui-icon{top:1px;margin:0;padding:0}.mui-bar .mui-title .mui-icon{margin:0;padding:0}.mui-bar .mui-title .mui-icon.mui-icon-caret{top:4px;margin-left:-5px}.mui-bar input[type=search]{height:29px;margin:6px 0}.mui-bar .mui-input-row .mui-btn{padding:12px 10px}.mui-bar .mui-search:before{margin-top:-10px}.mui-bar .mui-input-row .mui-input-clear~.mui-icon-clear,.mui-bar .mui-input-row .mui-input-speech~.mui-icon-speech{top:0;right:12px}.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear~.mui-icon-clear,.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech~.mui-icon-speech{top:0;right:0}.mui-bar .mui-segmented-control{top:7px;width:auto;margin:0 auto}.mui-bar.mui-bar-header-secondary .mui-segmented-control{top:0}.mui-badge{font-size:12px;line-height:1;display:inline-block;padding:3px 6px;color:#333;border-radius:100px;background-color:rgba(0,0,0,.15)}.mui-badge.mui-badge-inverted{padding:0 5px 0 0;color:#929292;background-color:transparent}.mui-badge-blue,.mui-badge-primary{color:#fff;background-color:#007aff}.mui-badge-blue.mui-badge-inverted,.mui-badge-primary.mui-badge-inverted{color:#007aff;background-color:transparent}.mui-badge-green,.mui-badge-success{color:#fff;background-color:#4cd964}.mui-badge-green.mui-badge-inverted,.mui-badge-success.mui-badge-inverted{color:#4cd964;background-color:transparent}.mui-badge-warning,.mui-badge-yellow{color:#fff;background-color:#f0ad4e}.mui-badge-warning.mui-badge-inverted,.mui-badge-yellow.mui-badge-inverted{color:#f0ad4e;background-color:transparent}.mui-badge-danger,.mui-badge-red{color:#fff;background-color:#dd524d}.mui-badge-danger.mui-badge-inverted,.mui-badge-red.mui-badge-inverted{color:#dd524d;background-color:transparent}.mui-badge-purple,.mui-badge-royal{color:#fff;background-color:#8a6de9}.mui-badge-purple.mui-badge-inverted,.mui-badge-royal.mui-badge-inverted{color:#8a6de9;background-color:transparent}.mui-icon .mui-badge{font-size:10px;line-height:1.4;position:absolute;top:-2px;left:100%;margin-left:-10px;padding:1px 5px;color:#fff;background:red}.mui-card{font-size:14px;position:relative;overflow:hidden;margin:10px;border-radius:2px;background-color:#fff;background-clip:padding-box;box-shadow:0 1px 2px rgba(0,0,0,.3)}.mui-content>.mui-card:first-child{margin-top:15px}.mui-card .mui-input-group .mui-input-row:last-child:after,.mui-card .mui-input-group .mui-input-row:last-child:before,.mui-card .mui-input-group:after,.mui-card .mui-input-group:before{height:0}.mui-card .mui-table-view{margin-bottom:0;border-top:0;border-bottom:0;border-radius:6px}.mui-card .mui-table-view .mui-table-view-cell:first-child,.mui-card .mui-table-view .mui-table-view-divider:first-child{top:0;border-top-left-radius:6px;border-top-right-radius:6px}.mui-card .mui-table-view .mui-table-view-cell:last-child,.mui-card .mui-table-view .mui-table-view-divider:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.mui-card .mui-table-view:after,.mui-card .mui-table-view:before,.mui-card>.mui-table-view>.mui-table-view-cell:last-child:after,.mui-card>.mui-table-view>.mui-table-view-cell:last-child:before{height:0}.mui-card-footer,.mui-card-header{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;min-height:44px;padding:10px 15px;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-card-footer .mui-card-link,.mui-card-header .mui-card-link{line-height:44px;position:relative;display:-webkit-box;display:-webkit-flex;display:flex;height:44px;margin-top:-10px;margin-bottom:-10px;-webkit-transition-duration:.3s;transition-duration:.3s;text-decoration:none;-webkit-box-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-card-footer:before,.mui-card-header:after{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-card-header{font-size:17px;border-radius:2px 2px 0 0}.mui-card-header:after{top:auto;bottom:0}.mui-card-header>img:first-child{font-size:0;line-height:0;float:left;width:34px;height:34px}.mui-card-footer{color:#6d6d72;border-radius:0 0 2px 2px}.mui-card-content{font-size:14px;position:relative}.mui-card-content-inner{position:relative;padding:15px}.mui-card-media{vertical-align:bottom;color:#fff;background-position:center;background-size:cover}.mui-card-header.mui-card-media{display:block;padding:10px}.mui-card-header.mui-card-media .mui-media-body{font-size:14px;font-weight:500;line-height:17px;margin-bottom:0;margin-left:44px;color:#333}.mui-card-header.mui-card-media .mui-media-body p{font-size:13px;margin-bottom:0}.mui-table-view{position:relative;margin-top:0;margin-bottom:0;padding-left:0;list-style:none;background-color:#fff}.mui-table-view:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view:before{position:absolute;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc;top:-1px}.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon{font-size:20px;margin-top:-1px;margin-right:5px;margin-left:-5px}.mui-table-view-icon .mui-table-view-cell:after{left:40px}.mui-table-view-chevron .mui-table-view-cell{padding-right:65px}.mui-table-view-chevron .mui-table-view-cell>a:not(.mui-btn){margin-right:-65px}.mui-table-view-radio .mui-table-view-cell{padding-right:65px}.mui-table-view-radio .mui-table-view-cell>a:not(.mui-btn){margin-right:-65px}.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after{font-size:30px;font-weight:600;right:9px;content:'';color:#007aff}.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after{content:'\e472'}.mui-table-view-inverted{color:#fff;background:#333}.mui-table-view-inverted:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#222}.mui-table-view-inverted .mui-table-view-cell.mui-active,.mui-table-view-inverted .mui-table-view-cell>a:not(.mui-btn).mui-active{background-color:#242424}.mui-table-view-cell{position:relative;overflow:hidden;padding:11px 15px;-webkit-touch-callout:none}.mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-cell.mui-checkbox input[type=checkbox],.mui-table-view-cell.mui-radio input[type=radio]{top:8px}.mui-table-view-cell.mui-checkbox.mui-left,.mui-table-view-cell.mui-radio.mui-left{padding-left:58px}.mui-table-view-cell.mui-active{background-color:#eee}.mui-table-view-cell:last-child:after,.mui-table-view-cell:last-child:before{height:0}.mui-table-view-cell>a:not(.mui-btn){position:relative;display:block;overflow:hidden;margin:-11px -15px;padding:inherit;white-space:nowrap;text-overflow:ellipsis;color:inherit}.mui-table-view-cell>a:not(.mui-btn).mui-active{background-color:#eee}.mui-table-view-cell p{margin-bottom:0}.mui-table-view-cell.mui-transitioning>.mui-slider-handle,.mui-table-view-cell.mui-transitioning>.mui-slider-left .mui-btn,.mui-table-view-cell.mui-transitioning>.mui-slider-right .mui-btn{-webkit-transition:-webkit-transform 300ms ease;transition:transform 300ms ease}.mui-table-view-cell.mui-active>.mui-slider-handle{background-color:#eee}.mui-table-view-cell>.mui-slider-handle{position:relative;background-color:#fff}.mui-table-view-cell>.mui-slider-handle .mui-navigate-right:after,.mui-table-view-cell>.mui-slider-handle.mui-navigate-right:after{right:0}.mui-table-view-cell>.mui-slider-handle,.mui-table-view-cell>.mui-slider-left .mui-btn,.mui-table-view-cell>.mui-slider-right .mui-btn{-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease}.mui-table-view-cell>.mui-slider-left,.mui-table-view-cell>.mui-slider-right{position:absolute;top:0;display:-webkit-box;display:-webkit-flex;display:flex;height:100%}.mui-table-view-cell>.mui-slider-left>.mui-btn,.mui-table-view-cell>.mui-slider-right>.mui-btn{position:relative;left:0;display:-webkit-box;display:-webkit-flex;display:flex;padding:0 30px;color:#fff;border:0;border-radius:0;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.mui-table-view-cell>.mui-slider-left>.mui-btn:after,.mui-table-view-cell>.mui-slider-right>.mui-btn:after{position:absolute;z-index:-1;top:0;width:600%;height:100%;content:'';background:inherit}.mui-table-view-cell>.mui-slider-left>.mui-btn.mui-icon,.mui-table-view-cell>.mui-slider-right>.mui-btn.mui-icon{font-size:30px}.mui-table-view-cell>.mui-slider-right{right:0;-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease;-webkit-transform:translateX(100%);transform:translateX(100%)}.mui-table-view-cell>.mui-slider-left{left:0;-webkit-transition:-webkit-transform 0ms ease;transition:transform 0ms ease;-webkit-transform:translateX(-100%);transform:translateX(-100%)}.mui-table-view-cell>.mui-slider-left>.mui-btn:after{right:100%;margin-right:-1px}.mui-table-view-divider{font-weight:500;position:relative;margin-top:-1px;margin-left:0;padding-top:6px;padding-bottom:6px;padding-left:15px;color:#999;background-color:#fafafa}.mui-table-view-divider:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-divider:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view .mui-media,.mui-table-view .mui-media-body{overflow:hidden}.mui-table-view .mui-media-large .mui-media-object{line-height:80px;max-width:80px;height:80px}.mui-table-view .mui-media .mui-subtitle{color:#000}.mui-table-view .mui-media-object{line-height:42px;max-width:42px;height:42px}.mui-table-view .mui-media-object.mui-pull-left{margin-right:10px}.mui-table-view .mui-media-object.mui-pull-right{margin-left:10px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object{line-height:29px;max-width:29px;height:29px;margin:-4px 0}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img{line-height:29px;max-width:29px;height:29px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left{margin-right:10px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon{font-size:29px}.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after{position:absolute;right:0;bottom:0;left:55px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view .mui-table-view-cell.mui-media-icon:after{height:0!important}.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view{display:block}.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after,.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before{height:0!important}.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after{position:absolute;right:0;bottom:0;left:70px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view-cell>.mui-badge,.mui-table-view-cell>.mui-btn,.mui-table-view-cell>.mui-switch,.mui-table-view-cell>a>.mui-badge,.mui-table-view-cell>a>.mui-btn,.mui-table-view-cell>a>.mui-switch{position:absolute;top:50%;right:15px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.mui-table-view-cell .mui-navigate-right>.mui-badge,.mui-table-view-cell .mui-navigate-right>.mui-btn,.mui-table-view-cell .mui-navigate-right>.mui-switch,.mui-table-view-cell .mui-push-left>.mui-badge,.mui-table-view-cell .mui-push-left>.mui-btn,.mui-table-view-cell .mui-push-left>.mui-switch,.mui-table-view-cell .mui-push-right>.mui-badge,.mui-table-view-cell .mui-push-right>.mui-btn,.mui-table-view-cell .mui-push-right>.mui-switch,.mui-table-view-cell>a .mui-navigate-right>.mui-badge,.mui-table-view-cell>a .mui-navigate-right>.mui-btn,.mui-table-view-cell>a .mui-navigate-right>.mui-switch,.mui-table-view-cell>a .mui-push-left>.mui-badge,.mui-table-view-cell>a .mui-push-left>.mui-btn,.mui-table-view-cell>a .mui-push-left>.mui-switch,.mui-table-view-cell>a .mui-push-right>.mui-badge,.mui-table-view-cell>a .mui-push-right>.mui-btn,.mui-table-view-cell>a .mui-push-right>.mui-switch{right:35px}.mui-content>.mui-table-view:first-child{margin-top:15px}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after,.mui-table-view-cell.mui-collapse .mui-table-view:after,.mui-table-view-cell.mui-collapse .mui-table-view:before{height:0}.mui-table-view-cell.mui-collapse>.mui-navigate-right:after,.mui-table-view-cell.mui-collapse>.mui-push-right:after{content:'\e581'}.mui-table-view-cell.mui-collapse.mui-active{margin-top:-1px}.mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content,.mui-table-view-cell.mui-collapse.mui-active .mui-table-view{display:block}.mui-table-view-cell.mui-collapse.mui-active>.mui-navigate-right:after,.mui-table-view-cell.mui-collapse.mui-active>.mui-push-right:after{content:'\e580'}.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell>a:not(.mui-btn).mui-active{margin-left:-31px;padding-left:47px}.mui-table-view-cell.mui-collapse .mui-collapse-content{position:relative;display:none;overflow:hidden;margin:11px -15px -11px;padding:8px 15px;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease;background:#fff}.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-input-group,.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-slider{width:auto;height:auto;margin:-8px -15px}.mui-table-view-cell.mui-collapse .mui-collapse-content>.mui-slider{margin:-8px -16px}.mui-table-view-cell.mui-collapse .mui-table-view{display:none;margin-top:11px;margin-right:-15px;margin-bottom:-11px;margin-left:-15px;border:0}.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron{margin-right:-65px}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell{padding-left:31px;background-position:31px 100%}.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:30px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-table-view.mui-grid-view{font-size:0;display:block;width:100%;padding:0 10px 10px 0;white-space:normal}.mui-table-view.mui-grid-view .mui-table-view-cell{font-size:17px;display:inline-block;margin-right:-4px;padding:10px 0 0 14px;text-align:center;vertical-align:middle;background:0 0}.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object{width:100%;max-width:100%;height:auto}.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn){margin:-10px 0 0 -14px}.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn).mui-active,.mui-table-view.mui-grid-view .mui-table-view-cell>a:not(.mui-btn):active{background:0 0}.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body{font-size:15px;line-height:15px;display:block;width:100%;height:15px;margin-top:8px;text-overflow:ellipsis;color:#333}.mui-table-view.mui-grid-view .mui-table-view-cell:after,.mui-table-view.mui-grid-view .mui-table-view-cell:before{height:0}.mui-grid-view.mui-grid-9{margin:0;padding:0;border-top:1px solid #eee;border-left:1px solid #eee;background-color:#f2f2f2}.mui-grid-view.mui-grid-9:after,.mui-grid-view.mui-grid-9:before{display:table;content:' '}.mui-grid-view.mui-grid-9:after{clear:both;position:static}.mui-grid-view.mui-grid-9 .mui-table-view-cell{margin:0;padding:11px 15px;vertical-align:top;border-right:1px solid #eee;border-bottom:1px solid #eee}.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active{background-color:#eee}.mui-grid-view.mui-grid-9 .mui-table-view-cell>a:not(.mui-btn){margin:0;padding:10px 0}.mui-grid-view.mui-grid-9:before{height:0}.mui-grid-view.mui-grid-9 .mui-media{color:#797979}.mui-grid-view.mui-grid-9 .mui-media .mui-icon{font-size:2.4em;position:relative}.mui-slider-cell{position:relative}.mui-slider-cell>.mui-slider-handle{z-index:1}.mui-slider-cell>.mui-slider-left,.mui-slider-cell>.mui-slider-right{position:absolute;z-index:0;top:0;bottom:0}.mui-slider-cell>.mui-slider-left{left:0}.mui-slider-cell>.mui-slider-right{right:0}input,select,textarea{font-family:'Helvetica Neue',Helvetica,sans-serif;font-size:17px;-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent}input:focus,select:focus,textarea:focus{-webkit-tap-highlight-color:transparent;-webkit-tap-highlight-color:transparent;-webkit-user-modify:read-write-plaintext-only}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{line-height:21px;width:100%;height:40px;margin-bottom:15px;padding:10px 15px;-webkit-user-select:text;border:1px solid rgba(0,0,0,.2);border-radius:3px;outline:0;background-color:#fff;-webkit-appearance:none}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{margin:0;-webkit-appearance:none}input[type=search]{font-size:16px;-webkit-box-sizing:border-box;box-sizing:border-box;height:34px;text-align:center;border:0;border-radius:6px;background-color:rgba(0,0,0,.1)}input[type=search]:focus{text-align:left}textarea{height:auto;resize:none}select{font-size:14px;height:auto;margin-top:1px;border:0!important;background-color:#fff}select:focus{-webkit-user-modify:read-only}.mui-input-group{position:relative;padding:0;border:0;background-color:#fff}.mui-input-group:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-group:before{position:absolute;top:0;right:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-group input,.mui-input-group textarea{margin-bottom:0;border:0;border-radius:0;background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.mui-input-group input[type=search]{background:0 0}.mui-input-group input:last-child{background-image:none}.mui-input-row{clear:left;overflow:hidden}.mui-input-row select{font-size:17px;height:37px;padding:0}.mui-input-row .mui-btn+input,.mui-input-row label+input,.mui-input-row:last-child{background:0 0}.mui-input-group .mui-input-row{height:40px}.mui-input-group .mui-input-row:after{position:absolute;right:0;bottom:0;left:15px;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-input-row label{font-family:'Helvetica Neue',Helvetica,sans-serif;line-height:1.1;float:left;width:35%;padding:11px 15px}.mui-input-row label~input,.mui-input-row label~select,.mui-input-row label~textarea{float:right;width:65%;margin-bottom:0;padding-left:0;border:0}.mui-input-row .mui-btn{line-height:1.1;float:right;width:15%;padding:10px 15px}.mui-input-row .mui-btn~input,.mui-input-row .mui-btn~select,.mui-input-row .mui-btn~textarea{float:left;width:85%;margin-bottom:0;padding-left:0;border:0}.mui-button-row{position:relative;padding-top:5px;text-align:center}.mui-input-group .mui-button-row{height:45px}.mui-input-row{position:relative}.mui-input-row.mui-input-range{overflow:visible;padding-right:20px}.mui-input-row .mui-inline{padding:8px 0}.mui-input-row .mui-input-clear~.mui-icon-clear,.mui-input-row .mui-input-password~.mui-icon-eye,.mui-input-row .mui-input-speech~.mui-icon-speech{font-size:20px;position:absolute;z-index:1;top:10px;right:0;width:38px;height:38px;text-align:center;color:#999}.mui-input-row .mui-input-clear~.mui-icon-clear.mui-active,.mui-input-row .mui-input-password~.mui-icon-eye.mui-active,.mui-input-row .mui-input-speech~.mui-icon-speech.mui-active{color:#007aff}.mui-input-row .mui-input-speech~.mui-icon-speech{font-size:24px;top:8px}.mui-input-row .mui-input-clear~.mui-icon-clear~.mui-icon-speech{display:none}.mui-input-row .mui-input-clear~.mui-icon-clear.mui-hidden~.mui-icon-speech{display:inline-block}.mui-input-row .mui-icon-speech~.mui-placeholder{right:38px}.mui-input-row.mui-search .mui-icon-clear{top:7px}.mui-input-row.mui-search .mui-icon-speech{top:5px}.mui-checkbox,.mui-radio{position:relative}.mui-checkbox label,.mui-radio label{display:inline-block;float:none;width:100%;padding-right:58px}.mui-checkbox.mui-left input[type=checkbox],.mui-radio.mui-left input[type=radio]{left:20px}.mui-checkbox.mui-left label,.mui-radio.mui-left label{padding-right:15px;padding-left:58px}.mui-checkbox input[type=checkbox],.mui-radio input[type=radio]{position:absolute;top:4px;right:20px;display:inline-block;width:28px;height:26px;border:0;outline:0!important;background-color:transparent;-webkit-appearance:none}.mui-checkbox input[type=checkbox][disabled]:before,.mui-radio input[type=radio][disabled]:before{opacity:.3}.mui-checkbox input[type=checkbox]:before,.mui-radio input[type=radio]:before{font-family:Muiicons;font-size:28px;font-weight:400;line-height:1;text-decoration:none;color:#aaa;border-radius:0;background:0 0;-webkit-font-smoothing:antialiased}.mui-checkbox input[type=checkbox]:checked:before,.mui-radio input[type=radio]:checked:before{color:#007aff}.mui-checkbox label.mui-disabled,.mui-checkbox.mui-disabled label,.mui-radio label.mui-disabled,.mui-radio.mui-disabled label{opacity:.4}.mui-radio input[type=radio]:before{content:'\e411'}.mui-radio input[type=radio]:checked:before{content:'\e441'}.mui-checkbox input[type=checkbox]:before{content:'\e411'}.mui-checkbox input[type=checkbox]:checked:before{content:'\e442'}.mui-select{position:relative}.mui-select:before{font-family:Muiicons;position:absolute;top:8px;right:21px;content:'\e581';color:rgba(170,170,170,.6)}.mui-input-row .mui-switch{float:right;margin-top:5px;margin-right:20px}.mui-input-range input[type=range]{position:relative;width:100%;height:2px;margin:17px 0;padding:0;cursor:pointer;border:0;border-radius:3px;outline:0;background-color:#999;-webkit-appearance:none!important}.mui-input-range input[type=range]::-webkit-slider-thumb{width:28px;height:28px;border-color:#0062cc;border-radius:50%;background-color:#007aff;background-clip:padding-box;-webkit-appearance:none!important}.mui-input-range label~input[type=range]{width:65%}.mui-input-range .mui-tooltip{font-size:36px;line-height:64px;position:absolute;z-index:1;top:-70px;width:64px;height:64px;text-align:center;opacity:.8;color:#333;border:1px solid #ddd;border-radius:6px;background-color:#fff;text-shadow:0 1px 0 #f3f3f3}.mui-search{position:relative}.mui-search input[type=search]{padding-left:30px}.mui-search .mui-placeholder{font-size:16px;line-height:34px;position:absolute;z-index:1;top:0;right:0;bottom:0;left:0;display:inline-block;height:34px;text-align:center;color:#999;border:0;border-radius:6px;background:0 0}.mui-search .mui-placeholder .mui-icon{font-size:20px;color:#333}.mui-search:before{font-family:Muiicons;font-size:20px;font-weight:400;position:absolute;top:50%;right:50%;display:none;margin-top:-18px;margin-right:31px;content:'\e466'}.mui-search.mui-active:before{font-size:20px;right:auto;left:5px;display:block;margin-right:0}.mui-search.mui-active input[type=search]{text-align:left}.mui-search.mui-active .mui-placeholder{display:none}.mui-segmented-control{font-size:15px;font-weight:400;position:relative;display:table;overflow:hidden;width:100%;table-layout:fixed;border:1px solid #007aff;border-radius:3px;background-color:transparent;-webkit-touch-callout:none}.mui-segmented-control.mui-segmented-control-vertical{border-collapse:collapse;border-width:0;border-radius:0}.mui-segmented-control.mui-segmented-control-vertical .mui-control-item{display:block;border-bottom:1px solid #c8c7cc;border-left-width:0}.mui-segmented-control.mui-scroll-wrapper{height:38px}.mui-segmented-control.mui-scroll-wrapper .mui-scroll{width:auto;height:40px;white-space:nowrap}.mui-segmented-control.mui-scroll-wrapper .mui-control-item{display:inline-block;width:auto;padding:0 20px;border:0}.mui-segmented-control .mui-control-item{line-height:38px;display:table-cell;overflow:hidden;width:1%;-webkit-transition:background-color .1s linear;transition:background-color .1s linear;text-align:center;white-space:nowrap;text-overflow:ellipsis;color:#007aff;border-color:#007aff;border-left:1px solid #007aff}.mui-segmented-control .mui-control-item:first-child{border-left-width:0}.mui-segmented-control .mui-control-item.mui-active{color:#fff;background-color:#007aff}.mui-segmented-control.mui-segmented-control-inverted{width:100%;border:0;border-radius:0}.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item,.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active{border-bottom:1px solid #c8c7cc}.mui-segmented-control.mui-segmented-control-inverted .mui-control-item{color:inherit;border:0}.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active{color:#007aff;border-bottom:2px solid #007aff;background:0 0}.mui-segmented-control.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#007aff}.mui-segmented-control-positive{border:1px solid #4cd964}.mui-segmented-control-positive .mui-control-item{color:#4cd964;border-color:inherit}.mui-segmented-control-positive .mui-control-item.mui-active{color:#fff;background-color:#4cd964}.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active{color:#4cd964;border-bottom:2px solid #4cd964;background:0 0}.mui-segmented-control-positive.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#4cd964}.mui-segmented-control-negative{border:1px solid #dd524d}.mui-segmented-control-negative .mui-control-item{color:#dd524d;border-color:inherit}.mui-segmented-control-negative .mui-control-item.mui-active{color:#fff;background-color:#dd524d}.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active{color:#dd524d;border-bottom:2px solid #dd524d;background:0 0}.mui-segmented-control-negative.mui-segmented-control-inverted~.mui-slider-progress-bar{background-color:#dd524d}.mui-control-content{position:relative;display:none}.mui-control-content.mui-active{display:block}.mui-popover{position:absolute;z-index:999;display:none;width:280px;-webkit-transition:opacity .3s;transition:opacity .3s;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transform:none;transform:none;opacity:0;border-radius:7px;background-color:#f7f7f7;-webkit-box-shadow:0 0 15px rgba(0,0,0,.1);box-shadow:0 0 15px rgba(0,0,0,.1)}.mui-popover .mui-popover-arrow{position:absolute;z-index:1000;top:-25px;left:0;overflow:hidden;width:26px;height:26px}.mui-popover .mui-popover-arrow:after{position:absolute;top:19px;left:0;width:26px;height:26px;content:' ';-webkit-transform:rotate(45deg);transform:rotate(45deg);border-radius:3px;background:#f7f7f7}.mui-popover .mui-popover-arrow.mui-bottom{top:100%;left:-26px;margin-top:-1px}.mui-popover .mui-popover-arrow.mui-bottom:after{top:-19px;left:0}.mui-popover.mui-popover-action{bottom:0;width:100%;-webkit-transition:-webkit-transform .3s,opacity .3s;transition:transform .3s,opacity .3s;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);border-radius:0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.mui-popover.mui-popover-action .mui-popover-arrow{display:none}.mui-popover.mui-popover-action.mui-popover-bottom{position:fixed}.mui-popover.mui-popover-action.mui-active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mui-popover.mui-popover-action .mui-table-view{margin:8px;text-align:center;color:#007aff;border-radius:4px}.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after{position:absolute;right:0;bottom:0;left:0;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);background-color:#c8c7cc}.mui-popover.mui-popover-action .mui-table-view small{font-weight:400;line-height:1.3;display:block}.mui-popover.mui-active{display:block;opacity:1}.mui-popover .mui-bar~.mui-table-view{padding-top:44px}.mui-backdrop{position:fixed;z-index:998;top:0;right:0;bottom:0;left:0;background-color:rgba(0,0,0,.3)}.mui-bar-backdrop.mui-backdrop{bottom:50px;background:0 0}.mui-backdrop-action.mui-backdrop{background-color:rgba(0,0,0,.3)}.mui-backdrop-action.mui-backdrop,.mui-bar-backdrop.mui-backdrop{opacity:0}.mui-backdrop-action.mui-backdrop.mui-active,.mui-bar-backdrop.mui-backdrop.mui-active{-webkit-transition:all .4s ease;transition:all .4s ease;opacity:1}.mui-popover .mui-btn-block{margin-bottom:5px}.mui-popover .mui-btn-block:last-child{margin-bottom:0}.mui-popover .mui-bar{-webkit-box-shadow:none;box-shadow:none}.mui-popover .mui-bar-nav{border-bottom:1px solid rgba(0,0,0,.15);border-top-left-radius:12px;border-top-right-radius:12px;-webkit-box-shadow:none;box-shadow:none}.mui-popover .mui-scroll-wrapper{margin:7px 0;border-radius:7px;background-clip:padding-box}.mui-popover .mui-scroll .mui-table-view{max-height:none}.mui-popover .mui-table-view{overflow:auto;max-height:300px;margin-bottom:0;border-radius:7px;background-color:#f7f7f7;background-image:none;-webkit-overflow-scrolling:touch}.mui-popover .mui-table-view:after,.mui-popover .mui-table-view:before{height:0}.mui-popover .mui-table-view .mui-table-view-cell:first-child,.mui-popover .mui-table-view .mui-table-view-cell:first-child>a:not(.mui-btn){border-top-left-radius:12px;border-top-right-radius:12px}.mui-popover .mui-table-view .mui-table-view-cell:last-child,.mui-popover .mui-table-view .mui-table-view-cell:last-child>a:not(.mui-btn){border-bottom-right-radius:12px;border-bottom-left-radius:12px}.mui-popover.mui-bar-popover .mui-table-view{width:106px}.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell{padding:11px 15px;background-position:0 100%}.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell>a:not(.mui-btn){margin:-11px -15px -11px -15px}.mui-popup-backdrop{position:fixed;z-index:998;top:0;right:0;bottom:0;left:0;-webkit-transition-duration:400ms;transition-duration:400ms;opacity:0;background:rgba(0,0,0,.4)}.mui-popup-backdrop.mui-active{opacity:1}.mui-popup{position:fixed;z-index:10000;top:50%;left:50%;display:none;overflow:hidden;width:270px;-webkit-transition-property:-webkit-transform,opacity;transition-property:transform,opacity;-webkit-transform:translate3d(-50%,-50%,0) scale(1.185);transform:translate3d(-50%,-50%,0) scale(1.185);text-align:center;opacity:0;color:#000;border-radius:13px}.mui-popup.mui-popup-in{display:block;-webkit-transition-duration:400ms;transition-duration:400ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1);opacity:1}.mui-popup.mui-popup-out{-webkit-transition-duration:400ms;transition-duration:400ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1);opacity:0}.mui-popup-inner{position:relative;padding:15px;border-radius:13px 13px 0 0;background:rgba(255,255,255,.95)}.mui-popup-inner:after{position:absolute;z-index:15;top:auto;right:auto;bottom:0;left:0;display:block;width:100%;height:1px;content:'';-webkit-transform:scaleY(.5);transform:scaleY(.5);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;background-color:rgba(0,0,0,.2)}.mui-popup-title{font-size:18px;font-weight:500;text-align:center}.mui-popup-title+.mui-popup-text{font-family:inherit;font-size:14px;margin:5px 0 0}.mui-popup-buttons{position:relative;display:-webkit-box;display:-webkit-flex;display:flex;height:44px;-webkit-box-pack:center;-webkit-justify-content:center;justify-content:center}.mui-popup-button{font-size:17px;line-height:44px;position:relative;display:block;overflow:hidden;box-sizing:border-box;width:100%;height:44px;padding:0 5px;cursor:pointer;text-align:center;white-space:nowrap;text-overflow:ellipsis;color:#007aff;background:rgba(255,255,255,.95);-webkit-box-flex:1}.mui-popup-button:after{position:absolute;z-index:15;top:0;right:0;bottom:auto;left:auto;display:block;width:1px;height:100%;content:'';-webkit-transform:scaleX(.5);transform:scaleX(.5);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;background-color:rgba(0,0,0,.2)}.mui-popup-button:first-child{border-radius:0 0 0 13px}.mui-popup-button:first-child:last-child{border-radius:0 0 13px 13px}.mui-popup-button:last-child{border-radius:0 0 13px}.mui-popup-button:last-child:after{display:none}.mui-popup-button.mui-popup-button-bold{font-weight:600}.mui-popup-input input{font-size:14px;width:100%;height:26px;margin:15px 0 0;padding:0 5px;border:1px solid rgba(0,0,0,.3);border-radius:0;background:#fff}.mui-plus.mui-android .mui-popup-backdrop{-webkit-transition-duration:1ms;transition-duration:1ms}.mui-plus.mui-android .mui-popup{-webkit-transition-duration:1ms;transition-duration:1ms;-webkit-transform:translate3d(-50%,-50%,0) scale(1);transform:translate3d(-50%,-50%,0) scale(1)}.mui-progressbar{position:relative;display:block;overflow:hidden;width:100%;height:2px;-webkit-transform-origin:center top;transform-origin:center top;vertical-align:middle;border-radius:2px;background:#b6b6b6;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-progressbar span{position:absolute;top:0;left:0;width:100%;height:100%;-webkit-transition:150ms;transition:150ms;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);background:#007aff}.mui-progressbar.mui-progressbar-infinite:before{position:absolute;top:0;left:0;width:100%;height:100%;content:'';-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-transform-origin:left center;transform-origin:left center;-webkit-animation:mui-progressbar-infinite 1s linear infinite;animation:mui-progressbar-infinite 1s linear infinite;background:#007aff}body>.mui-progressbar{position:absolute;z-index:10000;top:44px;left:0;border-radius:0}.mui-progressbar-in{-webkit-animation:mui-progressbar-in 300ms forwards;animation:mui-progressbar-in 300ms forwards}.mui-progressbar-out{-webkit-animation:mui-progressbar-out 300ms forwards;animation:mui-progressbar-out 300ms forwards}@-webkit-keyframes mui-progressbar-in{from{-webkit-transform:scaleY(0);opacity:0}to{-webkit-transform:scaleY(1);opacity:1}}@keyframes mui-progressbar-in{from{transform:scaleY(0);opacity:0}to{transform:scaleY(1);opacity:1}}@-webkit-keyframes mui-progressbar-out{from{-webkit-transform:scaleY(1);opacity:1}to{-webkit-transform:scaleY(0);opacity:0}}@keyframes mui-progressbar-out{from{transform:scaleY(1);opacity:1}to{transform:scaleY(0);opacity:0}}@-webkit-keyframes mui-progressbar-infinite{0%{-webkit-transform:translate3d(-50%,0,0) scaleX(.5)}100%{-webkit-transform:translate3d(100%,0,0) scaleX(.5)}}@keyframes mui-progressbar-infinite{0%{transform:translate3d(-50%,0,0) scaleX(.5)}100%{transform:translate3d(100%,0,0) scaleX(.5)}}.mui-pagination{display:inline-block;margin:0 auto;padding-left:0;border-radius:6px}.mui-pagination>li{display:inline}.mui-pagination>li>a,.mui-pagination>li>span{line-height:1.428571429;position:relative;float:left;margin-left:-1px;padding:6px 12px;text-decoration:none;color:#007aff;border:1px solid #ddd;background-color:#fff}.mui-pagination>li:first-child>a,.mui-pagination>li:first-child>span{margin-left:0;border-top-left-radius:6px;border-bottom-left-radius:6px;background-clip:padding-box}.mui-pagination>li:last-child>a,.mui-pagination>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px;background-clip:padding-box}.mui-pagination>li.mui-active>a,.mui-pagination>li.mui-active>a:active,.mui-pagination>li.mui-active>span,.mui-pagination>li.mui-active>span:active,.mui-pagination>li:active>a,.mui-pagination>li:active>a:active,.mui-pagination>li:active>span,.mui-pagination>li:active>span:active{z-index:2;cursor:default;color:#fff;border-color:#007aff;background-color:#007aff}.mui-pagination>li.mui-disabled>a,.mui-pagination>li.mui-disabled>a:active,.mui-pagination>li.mui-disabled>span,.mui-pagination>li.mui-disabled>span:active{opacity:.6;color:#777;border:1px solid #ddd;background-color:#fff}.mui-pagination-lg>li>a,.mui-pagination-lg>li>span{font-size:18px;padding:10px 16px}.mui-pagination-sm>li>a,.mui-pagination-sm>li>span{font-size:12px;padding:5px 10px}.mui-pager{padding-left:0;list-style:none;text-align:center}.mui-pager:after,.mui-pager:before{display:table;content:' '}.mui-pager:after{clear:both}.mui-pager li{display:inline}.mui-pager li>a,.mui-pager li>span{display:inline-block;padding:5px 14px;border:1px solid #ddd;border-radius:6px;background-color:#fff;background-clip:padding-box}.mui-pager li.mui-active>a,.mui-pager li.mui-active>span,.mui-pager li:active>a,.mui-pager li:active>span{cursor:default;text-decoration:none;color:#fff;border-color:#007aff;background-color:#007aff}.mui-pager .mui-next>a,.mui-pager .mui-next>span{float:right}.mui-pager .mui-previous>a,.mui-pager .mui-previous>span{float:left}.mui-pager .mui-disabled>a,.mui-pager .mui-disabled>a:active,.mui-pager .mui-disabled>span,.mui-pager .mui-disabled>span:active{opacity:.6;color:#777;border:1px solid #ddd;background-color:#fff}.mui-modal{position:fixed;z-index:999;top:0;overflow:hidden;width:100%;min-height:100%;-webkit-transition:-webkit-transform .25s,opacity 1ms .25s;transition:transform .25s,opacity 1ms .25s;-webkit-transition-timing-function:cubic-bezier(.1,.5,.1,1);transition-timing-function:cubic-bezier(.1,.5,.1,1);-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);opacity:0;background-color:#fff}.mui-modal.mui-active{height:100%;-webkit-transition:-webkit-transform .25s;transition:transform .25s;-webkit-transition-timing-function:cubic-bezier(.1,.5,.1,1);transition-timing-function:cubic-bezier(.1,.5,.1,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);opacity:1}.mui-android .mui-modal .mui-bar{position:static}.mui-android .mui-modal .mui-bar-nav~.mui-content{padding-top:0}.mui-slider{position:relative;z-index:1;overflow:hidden;width:100%}.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active{border-bottom:0}.mui-slider .mui-segmented-control.mui-segmented-control-inverted~.mui-slider-group .mui-slider-item{border-top:1px solid #c8c7cc;border-bottom:1px solid #c8c7cc}.mui-slider .mui-slider-group{font-size:0;position:relative;-webkit-transition:all 0s linear;transition:all 0s linear;white-space:nowrap}.mui-slider .mui-slider-group .mui-slider-item{font-size:14px;position:relative;display:inline-block;width:100%;height:100%;vertical-align:top;white-space:normal}.mui-slider .mui-slider-group .mui-slider-item>a:not(.mui-control-item){line-height:0;position:relative;display:block}.mui-slider .mui-slider-group .mui-slider-item img{width:100%}.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after,.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before{height:0}.mui-slider .mui-slider-group.mui-slider-loop{-webkit-transform:translate(-100%,0);transform:translate(-100%,0)}.mui-slider-title{line-height:30px;position:absolute;bottom:0;left:0;width:100%;height:30px;margin:0;text-align:left;text-indent:12px;opacity:.8;background-color:#000}.mui-slider-indicator{position:absolute;bottom:8px;width:100%;text-align:center;background:0 0}.mui-slider-indicator.mui-segmented-control{position:relative;bottom:auto}.mui-slider-indicator .mui-indicator{display:inline-block;width:6px;height:6px;margin:1px 6px;cursor:pointer;border-radius:50%;background:#aaa;-webkit-box-shadow:0 0 1px 1px rgba(130,130,130,.7);box-shadow:0 0 1px 1px rgba(130,130,130,.7)}.mui-slider-indicator .mui-active.mui-indicator{background:#fff}.mui-slider-indicator .mui-icon{font-size:20px;line-height:30px;width:40px;height:30px;margin:3px;text-align:center;border:1px solid #ddd}.mui-slider-indicator .mui-number{line-height:32px;display:inline-block;width:58px}.mui-slider-indicator .mui-number span{color:#ff5053}.mui-slider-progress-bar{z-index:1;height:2px;-webkit-transform:translateZ(0);transform:translateZ(0)}.mui-switch{position:relative;display:block;width:74px;height:30px;-webkit-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out;-webkit-transition-duration:.2s;transition-duration:.2s;-webkit-transition-property:background-color,border;transition-property:background-color,border;border:2px solid #ddd;border-radius:20px;background-color:#fff;background-clip:padding-box}.mui-switch.mui-disabled{opacity:.3}.mui-switch .mui-switch-handle{position:absolute;z-index:1;top:-1px;left:-1px;width:28px;height:28px;-webkit-transition:.2s ease-in-out;transition:.2s ease-in-out;-webkit-transition-property:-webkit-transform,width,left;transition-property:transform,width,left;border-radius:16px;background-color:#fff;background-clip:padding-box;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.4);box-shadow:0 2px 5px rgba(0,0,0,.4)}.mui-switch:before{font-size:13px;position:absolute;top:3px;right:11px;content:'Off';text-transform:uppercase;color:#999}.mui-switch.mui-dragging{border-color:#f7f7f7;background-color:#f7f7f7}.mui-switch.mui-dragging .mui-switch-handle{width:38px}.mui-switch.mui-dragging.mui-active .mui-switch-handle{left:-11px;width:38px}.mui-switch.mui-active{border-color:#4cd964;background-color:#4cd964}.mui-switch.mui-active .mui-switch-handle{-webkit-transform:translate(43px,0);transform:translate(43px,0)}.mui-switch.mui-active:before{right:auto;left:15px;content:'On';color:#fff}.mui-switch input[type=checkbox]{display:none}.mui-switch-mini{width:47px}.mui-switch-mini:before{display:none}.mui-switch-mini.mui-active .mui-switch-handle{-webkit-transform:translate(16px,0);transform:translate(16px,0)}.mui-switch-blue.mui-active{border:2px solid #007aff;background-color:#007aff}.mui-content.mui-fade{left:0;opacity:0}.mui-content.mui-fade.mui-in{opacity:1}.mui-content.mui-sliding{z-index:2;-webkit-transition:-webkit-transform .4s;transition:transform .4s;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.mui-content.mui-sliding.mui-left{z-index:1;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.mui-content.mui-sliding.mui-right{z-index:3;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.mui-navigate-right:after,.mui-push-left:after,.mui-push-right:after{font-family:Muiicons;font-size:inherit;line-height:1;position:absolute;top:50%;display:inline-block;-webkit-transform:translateY(-50%);transform:translateY(-50%);text-decoration:none;color:#bbb;-webkit-font-smoothing:antialiased}.mui-push-left:after{left:15px;content:'\e582'}.mui-navigate-right:after,.mui-push-right:after{right:15px;content:'\e583'}.mui-pull-bottom-pocket,.mui-pull-top-pocket{position:absolute;left:0;display:block;visibility:hidden;overflow:hidden;width:100%;height:50px}.mui-plus-pullrefresh .mui-pull-bottom-pocket,.mui-plus-pullrefresh .mui-pull-top-pocket{display:none;visibility:visible}.mui-pull-top-pocket{top:0}.mui-bar-nav~.mui-content .mui-pull-top-pocket{top:44px}.mui-bar-nav~.mui-bar-header-secondary~.mui-content .mui-pull-top-pocket{top:88px}.mui-pull-bottom-pocket{position:relative;bottom:0;height:40px}.mui-pull-bottom-pocket .mui-pull-loading{visibility:hidden}.mui-pull-bottom-pocket .mui-pull-loading.mui-in{display:inline-block}.mui-pull{font-weight:700;position:absolute;right:0;bottom:10px;left:0;text-align:center;color:#777}.mui-pull-loading{margin-right:10px;-webkit-transition:-webkit-transform .4s;transition:transform .4s;-webkit-transition-duration:400ms;transition-duration:400ms;vertical-align:middle}.mui-pull-loading.mui-reverse{-webkit-transform:rotate(180deg) translateZ(0);transform:rotate(180deg) translateZ(0)}.mui-pull-caption{font-size:15px;line-height:24px;position:relative;display:inline-block;overflow:visible;margin-top:0;vertical-align:middle}.mui-pull-caption span{display:none}.mui-pull-caption span.mui-in{display:inline}.mui-toast-container{line-height:17px;position:fixed;z-index:9999;bottom:50px;left:50%;-webkit-transition:opacity .3s;transition:opacity .3s;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);opacity:0}.mui-toast-container.mui-active{opacity:.9}.mui-toast-message{font-size:14px;padding:10px 25px;text-align:center;color:#fff;border-radius:6px;background-color:#323232}.mui-numbox{position:relative;display:inline-block;overflow:hidden;width:120px;height:35px;padding:0 40px;vertical-align:top;vertical-align:middle;border:solid 1px #bbb;border-radius:3px;background-color:#efeff4}.mui-numbox [class*=btn-numbox],.mui-numbox [class*=numbox-btn]{font-size:18px;font-weight:400;line-height:100%;position:absolute;top:0;overflow:hidden;width:40px;height:100%;padding:0;color:#555;border:none;border-radius:0;background-color:#f9f9f9}.mui-numbox [class*=btn-numbox]:active,.mui-numbox [class*=numbox-btn]:active{background-color:#ccc}.mui-numbox [class*=btn-numbox][disabled],.mui-numbox [class*=numbox-btn][disabled]{color:silver}.mui-numbox .mui-btn-numbox-plus,.mui-numbox .mui-numbox-btn-plus{right:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.mui-numbox .mui-btn-numbox-minus,.mui-numbox .mui-numbox-btn-minus{left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.mui-numbox .mui-input-numbox,.mui-numbox .mui-numbox-input{display:inline-block;overflow:hidden;width:100%!important;height:100%;margin:0;padding:0 3px!important;text-align:center;text-overflow:ellipsis;word-break:normal;border:none!important;border-right:solid 1px #ccc!important;border-left:solid 1px #ccc!important;border-radius:0!important}.mui-input-row .mui-numbox{float:right;margin:2px 8px}@font-face{font-family:Muiicons;font-weight:400;font-style:normal;src:url(../fonts/mui.ttf) format('truetype')}.mui-icon{font-family:Muiicons;font-size:24px;font-weight:400;font-style:normal;line-height:1;display:inline-block;text-decoration:none;-webkit-font-smoothing:antialiased}.mui-icon.mui-active{color:#007aff}.mui-icon.mui-right:before{float:right;padding-left:.2em}.mui-icon-contact:before{content:'\e100'}.mui-icon-person:before{content:'\e101'}.mui-icon-personadd:before{content:'\e102'}.mui-icon-contact-filled:before{content:'\e130'}.mui-icon-person-filled:before{content:'\e131'}.mui-icon-personadd-filled:before{content:'\e132'}.mui-icon-phone:before{content:'\e200'}.mui-icon-email:before{content:'\e201'}.mui-icon-chatbubble:before{content:'\e202'}.mui-icon-chatboxes:before{content:'\e203'}.mui-icon-phone-filled:before{content:'\e230'}.mui-icon-email-filled:before{content:'\e231'}.mui-icon-chatbubble-filled:before{content:'\e232'}.mui-icon-chatboxes-filled:before{content:'\e233'}.mui-icon-weibo:before{content:'\e260'}.mui-icon-weixin:before{content:'\e261'}.mui-icon-pengyouquan:before{content:'\e262'}.mui-icon-chat:before{content:'\e263'}.mui-icon-qq:before{content:'\e264'}.mui-icon-videocam:before{content:'\e300'}.mui-icon-camera:before{content:'\e301'}.mui-icon-mic:before{content:'\e302'}.mui-icon-location:before{content:'\e303'}.mui-icon-mic-filled:before,.mui-icon-speech:before{content:'\e332'}.mui-icon-location-filled:before{content:'\e333'}.mui-icon-micoff:before{content:'\e360'}.mui-icon-image:before{content:'\e363'}.mui-icon-map:before{content:'\e364'}.mui-icon-compose:before{content:'\e400'}.mui-icon-trash:before{content:'\e401'}.mui-icon-upload:before{content:'\e402'}.mui-icon-download:before{content:'\e403'}.mui-icon-close:before{content:'\e404'}.mui-icon-redo:before{content:'\e405'}.mui-icon-undo:before{content:'\e406'}.mui-icon-refresh:before{content:'\e407'}.mui-icon-star:before{content:'\e408'}.mui-icon-plus:before{content:'\e409'}.mui-icon-minus:before{content:'\e410'}.mui-icon-checkbox:before,.mui-icon-circle:before{content:'\e411'}.mui-icon-clear:before,.mui-icon-close-filled:before{content:'\e434'}.mui-icon-refresh-filled:before{content:'\e437'}.mui-icon-star-filled:before{content:'\e438'}.mui-icon-plus-filled:before{content:'\e439'}.mui-icon-minus-filled:before{content:'\e440'}.mui-icon-circle-filled:before{content:'\e441'}.mui-icon-checkbox-filled:before{content:'\e442'}.mui-icon-closeempty:before{content:'\e460'}.mui-icon-refreshempty:before{content:'\e461'}.mui-icon-reload:before{content:'\e462'}.mui-icon-starhalf:before{content:'\e463'}.mui-icon-spinner:before{content:'\e464'}.mui-icon-spinner-cycle:before{content:'\e465'}.mui-icon-search:before{content:'\e466'}.mui-icon-plusempty:before{content:'\e468'}.mui-icon-forward:before{content:'\e470'}.mui-icon-back:before,.mui-icon-left-nav:before{content:'\e471'}.mui-icon-checkmarkempty:before{content:'\e472'}.mui-icon-home:before{content:'\e500'}.mui-icon-navigate:before{content:'\e501'}.mui-icon-gear:before{content:'\e502'}.mui-icon-paperplane:before{content:'\e503'}.mui-icon-info:before{content:'\e504'}.mui-icon-help:before{content:'\e505'}.mui-icon-locked:before{content:'\e506'}.mui-icon-more:before{content:'\e507'}.mui-icon-flag:before{content:'\e508'}.mui-icon-home-filled:before{content:'\e530'}.mui-icon-gear-filled:before{content:'\e532'}.mui-icon-info-filled:before{content:'\e534'}.mui-icon-help-filled:before{content:'\e535'}.mui-icon-more-filled:before{content:'\e537'}.mui-icon-settings:before{content:'\e560'}.mui-icon-list:before{content:'\e562'}.mui-icon-bars:before{content:'\e563'}.mui-icon-loop:before{content:'\e565'}.mui-icon-paperclip:before{content:'\e567'}.mui-icon-eye:before{content:'\e568'}.mui-icon-arrowup:before{content:'\e580'}.mui-icon-arrowdown:before{content:'\e581'}.mui-icon-arrowleft:before{content:'\e582'}.mui-icon-arrowright:before{content:'\e583'}.mui-icon-arrowthinup:before{content:'\e584'}.mui-icon-arrowthindown:before{content:'\e585'}.mui-icon-arrowthinleft:before{content:'\e586'}.mui-icon-arrowthinright:before{content:'\e587'}.mui-icon-pulldown:before{content:'\e588'}.mui-fullscreen{position:absolute;top:0;right:0;bottom:0;left:0}.mui-fullscreen.mui-slider .mui-slider-group{height:100%}.mui-fullscreen .mui-segmented-control~.mui-slider-group{position:absolute;top:40px;bottom:0;width:100%;height:auto}.mui-fullscreen.mui-slider .mui-slider-item>a{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item>a{top:auto;-webkit-transform:none;transform:none}.mui-bar-nav~.mui-content .mui-slider.mui-fullscreen{top:44px}.mui-bar-tab~.mui-content .mui-slider.mui-fullscreen .mui-segmented-control~.mui-slider-group{bottom:50px}.mui-android.mui-android-4-0 input:focus,.mui-android.mui-android-4-0 textarea:focus{-webkit-user-modify:inherit}.mui-android.mui-android-4-2 input,.mui-android.mui-android-4-2 textarea,.mui-android.mui-android-4-3 input,.mui-android.mui-android-4-3 textarea{-webkit-user-select:text}.mui-ios .mui-table-view-cell{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.mui-plus-visible,.mui-wechat-visible{display:none!important}.mui-plus-hidden,.mui-wechat-hidden{display:block!important}.mui-tab-item.mui-plus-hidden,.mui-tab-item.mui-wechat-hidden{display:table-cell!important}.mui-plus .mui-plus-visible,.mui-wechat .mui-wechat-visible{display:block!important}.mui-plus .mui-tab-item.mui-plus-visible,.mui-wechat .mui-tab-item.mui-wechat-visible{display:table-cell!important}.mui-plus .mui-plus-hidden,.mui-wechat .mui-wechat-hidden{display:none!important}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav{height:64px;padding-top:20px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav~.mui-content{padding-top:64px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary,.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav~.mui-content .mui-pull-top-pocket{top:64px}.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary~.mui-content{padding-top:94px}.mui-iframe-wrapper{position:absolute;right:0;left:0;-webkit-overflow-scrolling:touch}.mui-iframe-wrapper iframe{width:100%;height:100%;border:0} \ No newline at end of file diff --git a/static/app2/css/mui.picker.css b/static/app2/css/mui.picker.css new file mode 100755 index 0000000..015723d --- /dev/null +++ b/static/app2/css/mui.picker.css @@ -0,0 +1,85 @@ +/** + * 选择列表插件 + * varstion 2.0.0 + * by Houfeng + * Houfeng@DCloud.io + */ + +.mui-picker { + background-color: #ddd; + position: relative; + height: 200px; + overflow: hidden; + border: solid 1px rgba(0, 0, 0, 0.1); + -webkit-user-select: none; + user-select: none; + box-sizing: border-box; +} +.mui-picker-inner { + box-sizing: border-box; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, #fff 20%, #fff 80%, transparent 95%, transparent); + -webkit-mask-box-image: linear-gradient(top, transparent, transparent 5%, #fff 20%, #fff 80%, transparent 95%, transparent); +} +.mui-pciker-list, +.mui-pciker-rule { + box-sizing: border-box; + padding: 0px; + margin: 0px; + width: 100%; + height: 36px; + line-height: 36px; + position: absolute; + left: 0px; + top: 50%; + margin-top: -18px; +} +.mui-pciker-rule-bg { + z-index: 0; + /*background-color: #cfd5da;*/ +} +.mui-pciker-rule-ft { + z-index: 2; + border-top: solid 1px rgba(0, 0, 0, 0.1); + border-bottom: solid 1px rgba(0, 0, 0, 0.1); + /*-webkit-box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);*/ + /*box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.1);*/ +} +.mui-pciker-list { + z-index: 1; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transform: perspective(1000px) rotateY(0deg) rotateX(0deg); + transform: perspective(1000px) rotateY(0deg) rotateX(0deg); +} +.mui-pciker-list li { + width: 100%; + height: 100%; + position: absolute; + text-align: center; + vertical-align: middle; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + overflow: hidden; + box-sizing: border-box; + font-size: 16px; + font-family: "Helvetica Neue", "Helvetica", "Arial", "sans-serif"; + color: #888; + padding: 0px 8px; + white-space: nowrap; + -webkit-text-overflow: ellipsis; + text-overflow: ellipsis; + overflow: hidden; + cursor: default; + visibility: hidden; +} +.mui-pciker-list li.highlight, +.mui-pciker-list li.visible { + visibility: visible; +} +.mui-pciker-list li.highlight { + color: #222; +} \ No newline at end of file diff --git a/static/app2/css/mui.poppicker.css b/static/app2/css/mui.poppicker.css new file mode 100755 index 0000000..c0eb469 --- /dev/null +++ b/static/app2/css/mui.poppicker.css @@ -0,0 +1,64 @@ +.mui-poppicker { + position: fixed; + left: 0px; + width: 100%; + z-index: 999; + background-color: #eee; + border-top: solid 1px #ccc; + box-shadow: 0px -5px 7px 0px rgba(0, 0, 0, 0.1); + -webkit-transition: .3s; + bottom: 0px; + -webkit-transform: translateY(300px); +} +.mui-poppicker.mui-active { + -webkit-transform: translateY(0px); +} +.mui-android-5-1 .mui-poppicker { + bottom: -300px; + -webkit-transition-property: bottom; + -webkit-transform: none; +} +.mui-android-5-1 .mui-poppicker.mui-active { + bottom: 0px; + -webkit-transition-property: bottom; + -webkit-transform: none; +} +.mui-poppicker-header { + padding: 6px; + font-size: 14px; + color: #888; +} +.mui-poppicker-header .mui-btn { + font-size: 12px; + padding: 5px 10px; +} +.mui-poppicker-btn-cancel { + float: left; +} +.mui-poppicker-btn-ok { + float: right; +} +.mui-poppicker-clear { + clear: both; + height: 0px; + line-height: 0px; + font-size: 0px; + overflow: hidden; +} +.mui-poppicker-body { + position: relative; + width: 100%; + height: 200px; + border-top: solid 1px #ddd; + /*-webkit-perspective: 1200px; + perspective: 1200px; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d;*/ +} +.mui-poppicker-body .mui-picker { + width: 100%; + height: 100%; + margin: 0px; + border: none; + float: left; +} \ No newline at end of file diff --git a/static/app2/css/my.css b/static/app2/css/my.css new file mode 100755 index 0000000..2dfa928 --- /dev/null +++ b/static/app2/css/my.css @@ -0,0 +1,369 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.1); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} + +.my{ + width: 100%; + position: relative; +} + +.mui-scroll{ + /* background: url(../img/my_bg.png) no-repeat center top; */ + background-size: 100% ; +} + + +.con{ + position: absolute; + top: 35px; + left: 15px; + width: 93%; + /* height: 70px; */ + +} +.con .login{ + width: 78px; + height:78px; + border-radius: 100px; + border: 3px solid #ebebeb; + color: white; + text-align: center; + line-height: 72px; + /*margin: 0 auto;*/ + position: absolute; + top: -20px; + left: 0; + right: 0; + z-index: 0; + margin:0px auto; + /* font-size: 22px; */ + background: white; + color: black; +} +.con1{ + margin-top: 30px; + display: flex; + justify-content: flex-start; + align-items:center; + padding: 10px; + height:120px ; +} +.con1 img{ + display: inline-block; + width: 78px; + height: 78px; + border-radius: 100px; + border: 3px solid #fff; + margin-right: 20px; + /* left: 0; + top: 0; + right: 0; + margin: 0 auto; + z-index: 11; + position: absolute; */ +} +.con1 .left { + width: 60%; + height: 80px; + display: flex; + justify-content: space-around; + align-items: flex-start; + flex-direction: column; +} +.con1 p{ + display: inline-block; + /* position: absolute; */ + font-size: 19px; + color: #fff; + font-weight:300; + /* width: 60%; */ + + /* left: 0; */ + /* top: 85px; */ + /* right: 0; */ + /* margin: 0 auto; */ + /* width: 100%; */ + /* text-align: center; */ +} +.con1 .left p span { + padding-right: 10px; + font-size: 14px +} +.seeting{ + font-size: 22px; + color: #fff; + /* margin-top: 15px; + margin-left: 9px; + float: left; */ + width: 10%; +} +.hyz{ + width: 102px; + height: 26.4px; + font-size: 13.2px; + line-height: 29px; + text-indent: 27px; + color: #fff; + background: url(../img/hyz_bg.png) no-repeat center top; + background-size: 100%; + right: 0; + position: absolute; + top: 111px; +} +.nav { + width: 96%; + height: 122px; + background: white; + /* margin-bottom: 9px; */ + margin: 0 2%; + padding-top: 58px; + margin-top: 30px; +} +.nblock{ + width: 33.3%; + height: 72px; + text-align: center; + float: left; + /* padding-top: 10px; */ +} +.nblock p{ + color: #525252; + font-size: 13.2px; + margin-top: 3px; + +} + +.order, .myMoney, .myYouhuiquan, .mydata, .shenqingcon{ + margin: 6px 2%; + width: 96%; +} +/* 优惠券 */ +.myYouhuiquan{ + /* height: 150px; */ + width: 98%; + margin: 5px auto 0px; + /* padding-top: 30px; */ + /* display: none; */ +} +.myYouhuiquan_con{ + /* position: absolute; */ + height: 100px; + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: center; + background: white; + box-sizing: border-box; + border: 1px solid #FFFFFF; + border-radius: 5px; + /* border-bottom: 1px solid #e6e6e6; */ +} +.myYouhuiquan_con1{ + width: 90%; + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: center; + /* padding-top: 111px; */ + /* background: #000000; */ + margin: 15px auto 2px; +} +.myYouhuiquan_cb{ + width:33.333%; + height: 50px; + padding: 4px auto; + text-align: center; + /* float: left; */ + /* position: relative; */ +display: flex; +flex-direction: column; +/* align-items: center; */ +justify-content: center; + border-bottom: 1px solid #c0c0c0; + /* border: 1px solid #C0C0C0; */ +} + +.myYouhuiquan_cb p{ + color: #525252; + font-size: 18px; +} +.myYouhuiquan_cb .orange{ + color:#FC773F; + font-size: 18px; +} +/* 订单 */ + +.order_title{ + width: 100%; + height: 43px; + background: white; + border-bottom: 1px solid #e6e6e6; + line-height: 43px; + +} + +.order_title p{ + font-size: 18px; + color: black; + float: left; + margin: 0; + margin-left: 12px; +} + +.order_title .order_more{ + color: #909090; + font-size: 17px; + float: right; + margin: 0; + margin-right: 12px; + +} +.order_con{ + background: white; + border-bottom: 1px solid #e6e6e6; +} +.order_cb{ + width: 20%; + height: 90px; + text-align: center; + float: left; + position: relative; +} +.orderimg{ + width: 30px; + /* height: 30px; */ + margin: 10px auto; +} + .orderimg img{ + width:100%; + /* margin-top: 15px; */ +} +.order_cb p{ + margin: 0px; + padding: 0px; + /* margin-top: 3px; */ + /* color: #525252; */ + color: #909090; + font-size: 18px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.logistics{ + height: 96px; + background: white; +} +.waitReceive{ + position: relative; +} +.num{ + position: absolute; + width: 20px; + height: 20px; + border-radius: 50%; + background: red; + color: white; + font-size: 10.8px; + text-align: center; + line-height: 20px; + top: 5px; + left: 70%; +} + +.myMoney{ + width: 96%; + background: white; + +} +.moneycon_{ + width: 25%; + float: left; + height: 100px; + position: relative; +} +.moneycon_ img{ + text-align: center; + width: 61px; + height: 61px; + position: absolute; + left: 0; + right: 0; + margin: 0 auto; + top:5px; +} +.moneycon_ p{ + text-align: center; + position: absolute; + bottom: 5px; + left: 0; + right: 0; + margin: 0 auto; + color: #E51329; + font-size: 14.4px; +} +.share{ + font-size: 14.4px; + color: #ffffff; + margin-top: 15px; + margin-right: 9px; + float: right; +} +.mydata .mydata-content{ + background: #fff; + width: 100%; + display: flex; + justify-content: flex-start; + flex-wrap: wrap; +} + +.mydata .mydata-content .mydata-table-view-cell{ + width: 25%; + text-align: center; + padding: 5px 0px; + border-right: 1px solid #ECECEC; + border-bottom: 1px solid #ECECEC; + +} +.mydata .mydata-content .mydata-table-view-cell a { + color:#525252 ; + display: inline-block; + width: 100%; +} +.mydata .mydata-content .mydata-table-view-cell p { + font-size: 18px; +} +.mydata .mydata-content .mydata-table-view-cell .mydata-media-body { + font-size: 13px; + + } + .shenqingcon { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + } + .shenqingcon .shenqingcon_{ + width: 24%; + text-align: center; + } + .shenqingcon .shenqingcon_ img{ + text-align: center; + width: 61px; + height: 61px; + /* position: absolute; + left: 0; + right: 0; */ + margin: 0 auto; + top:5px; + } diff --git a/static/app2/css/myshop.css b/static/app2/css/myshop.css new file mode 100755 index 0000000..e44b119 --- /dev/null +++ b/static/app2/css/myshop.css @@ -0,0 +1,291 @@ +.header { + background: none !important; + +} +.header_bg_con .shop_info .myshopname{ + width:200px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + + + +/* .mui-icon-gear { + font-size: 26px; + height: 30px; + position: absolute;*/ +/* top: 0px; */ +/* right: 15px; + z-index: 100; +} */ + +.header_background { + height: 200px; + width: 100%; + background: #FF7900; + border: 1px solid #ff7900; + border-radius: 10px; +} + +.header_bg_con { + margin-top: 45px; + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px; + flex: 1; +} + +.headerimg { + + width: 78px; + height: 78px; + border-radius: 100px; + border: 3px solid #fff; + margin-right: 10px; +} + +.headerimg img { + width: 100%; +} + +.header_bg_con .shop_info { + flex: 3; +} + +.header_bg_con .shop_info p { + font-size: 19px; + color: #fff; + font-weight: 300; +} + +.header_bg_con .shop_info span { + font-size: 16px; + color: #fff; + margin-right: 10px; +} + +.seeting { + font-size: 25px; + color: #fff; + + +} + + + +.myYouhuiquan_con { + /* position: absolute; */ + height: 100px; + display: flex; + justify-content: space-between; + flex-wrap: wrap; + align-items: center; + background: white; + box-sizing: border-box; + border: 1px solid #FFFFFF; + border-radius: 5px; + /* border-bottom: 1px solid #e6e6e6; */ +} + +.money { + width: 80%; + display: flex; + justify-content: space-between; + align-items: center; + margin: -35px auto 2px; + background: #fff; +} + +.myYouhuiquan_cb { + width: 48%; + height: 80px; + padding: 4px auto; + text-align: center; + display: flex; + flex-direction: column; + justify-content: space-around; + border-right: 1px solid #c0c0c0; +} + +.myYouhuiquan_cb p { + color: #525252; + font-size: 14px; +} + +.myYouhuiquan_cb .orange { + color: #FC773F; + font-size: 16px; +} + + +.order { + margin:10px auto 3px; + width: 96%; + +} + +.order_title { + width: 100%; + height: 43px; + background: white; + border-bottom: 1px solid #e6e6e6; + line-height: 43px; + +} + +.order_title p { + font-size: 13.2px; + color: black; + float: left; + margin: 0; + margin-left: 12px; +} + +.order_title .order_more { + color: #909090; + font-size: 15px; + float: right; + margin: 0; + margin-right: 12px; + +} + +.order_con { + background: white; + border-bottom: 1px solid #e6e6e6; + display: flex; + justify-content:flex-start; + align-items: center; +} + +.order_cb { + height: 90px; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; + position: relative; + /* flex: 1; */ + width: 20%; +} + +.orderimg { + width: 30px; + /* height: 30px; */ +/* margin: 10px auto; */ + +} + +.orderimg img { + width: 100%; + +} + +.order_cb p { + margin: 0px; + padding: 0px; + + color: #909090; + font-size: 15px; +} + +.waitReceive { + position: relative; +} + +.num { + position: absolute; + width: 20px; + height: 20px; + border-radius: 50%; + background: red; + color: white; + font-size: 10.8px; + text-align: center; + line-height: 20px; + top: 5px; + left: 50px; +} +.offline_order .num{ + left: 75px; + } + + +.orders-title { + padding: 10px; + /* background: #fff; */ + text-align: center; + color: #f11; +} + +.orders-title h3 { + font-size: 15px; +} + +.shop-goods{ + width: 96%; + margin: 0 auto; + background: #EFEFEF; +} + +.shop-goods-content { + width: 100%; + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.shop-goods-detail { + width: 49%; + height: 240px; + padding: 10px; + background: #fff; +} + +.sgd-list { + width: 98%; + margin: 0 auto; + +} + +.shop-goods-detail .sdg-img { + width: 100%; + margin: 0 auto; + display: inline-block; +} + +.sgd-info { + font-size: 12px; + color: #000; + margin: 5px auto; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.sgd-price { + display: flex; + justify-content: space-between; +} + +.market-price span { + font-size: 12px; + color: #000; +} + +.market-price .price { + color: #F02A40; + /* font-size: 16px; */ + margin-left: 10px; +} + +.youhuilv span { + font-size: 12px; + color: #000; +} + +.youhuilv .preference-rate { + margin-left: 5px; +} diff --git a/static/app2/css/myshops.css b/static/app2/css/myshops.css new file mode 100755 index 0000000..b85b3c6 --- /dev/null +++ b/static/app2/css/myshops.css @@ -0,0 +1,186 @@ +.con{ + margin-bottom: 25px; +} + +.list { + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + margin: 0 auto; + padding: 2px 5px; + background: #fff; + flex: 1; +} + +.listimg { + width: 50px; + height: 50px; + border: 1px solid #fff; + border-radius: 50px; +} + +.listimg img { + width: 100%; + height: 100%; +} + +.lctop { + display: flex; + justify-content: space-between; + align-items: center; +} + +.listcenter { + flex: 2; + align-self: flex-start; + margin: 10px; +} + +.listright { + display: flex; + justify-content: flex-start; + align-items: center; + margin: 8px auto 3px; +} + +.listcenter .name, +.listcenter .info { + display: flex; + justify-content: flex-start; + align-items: center; +} + +.nc { + display: none; + /* font-size: 14px; */ + /* color: #000; + height: 18px; + width: 20px; */ + /* width: 70%; */ + /* display: inline-block; */ + /* margin-left: 2px; */ + /* margin: 0px 11px; */ +} + +.shopname { + max-width: 120px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.infocom { + font-size: 12px; + color: #ccc; + margin: 0px 5px; +} + +.supermaket .namecom { +/* border: 1px solid #FF4500; + border-radius: 4px; */ + text-align: center; + line-height: 23px; + color:#FF4500; +} + +.commercial .namecom { +/* border: 1px solid #FEAA24; + border-radius: 4px; */ + text-align: center; + line-height: 23px; + color:#FEAA24; + +} + +.shangdu .namecom { + /* border: 1px solid #F50003; */ + /* border-radius: 4px; */ + text-align: center; + line-height: 23px; + color:#F50003; + +} + +.scinfo { + color: #FF4500; +} + +.ssinfo { + color: #FEAA24; +} + +.sdinfo { + color: #F50003; +} + +.listright p { + margin-right: 15%; + padding: 5px 15px; + border: 1px solid #ccc; + border-radius: 10px; + /* margin: 4px auto; */ + text-align: center; + font-size: 16px; + /* background: #efefef; */ +} + +.add1 { + width: 96%; + margin: 5px auto; + height: 63px; + background: #C9C9C9; + border: 1px solid #C9C9C9; + border-radius: 5px; + display: flex; + justify-content: center; + align-items: center; + /* margin-top: 10px; */ +} + +.addimg { + width: 40px; + height: 40px; +} + +.add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + +} + +.lxy_zz { + width: 80%; + margin: 0 auto; + position: relative; + top: 40%; + padding-top: 10px; + padding-bottom: 10px; + background: #fff; +} + +.lxy_zz h3 { + text-align: center; + font-size: 18px; + font-weight: 200; + +} + +.lxy_zz input { + /* position: absolute; */ + width: 88%; + display: block; + /* top:50%; + left: 10%; */ + margin: 10px auto; + height: 35px; + border-radius: 5px; +} + +.lxy_zz_btn { + display: flex; + justify-content: space-between; + width: 80%; + margin: 0 auto; +} diff --git a/static/app2/css/order_con.css b/static/app2/css/order_con.css new file mode 100755 index 0000000..d877da6 --- /dev/null +++ b/static/app2/css/order_con.css @@ -0,0 +1,183 @@ +.ad { + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + width: 100%; + height: 126px; + position: relative; +} + +.ad p { + position: absolute; + color: white; + margin: 0; + font-size: 13.2px; + top: 57px; + left: 36px; +} + +.address { + background: white; + /*border-bottom: 1px solid #e6e6e6;*/ + margin-bottom: 5px; + position: relative; +} + +.add_l { + float: left; + width: 39px; + position: absolute; + top: 0; + bottom: 0; +} + +.add_l img { + width: 21.6px; + height: 21.6px; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; +} + +.add_r { + width: calc( 100% - 39px); + float: right; + padding-right: 9px; + font-size: 13.2px; + color: #909090; +} + +.add_r_t { + width: 100%; + padding: 6px 0 1px; +} + +.add_r_t_l { + float: left; +} + +.add_r_t_r { + float: right; +} + +.add_r_b { + width: 100%; + padding: 0 0 3px; +} + +.shop_info { + margin-bottom: 5px; +} + +.invoice_info { + width: 100%; + padding: 3px 9px; + background: white; + margin-bottom: 6px; +} + +.invoice_info p {} + +.cost { + border-bottom: 1px solid #e6e6e6; + background: white; + padding: 9px 9px; + border-radius: ; +} + +.c1 { + font-size: 12px; + color: #909090; +} + +.c1_l { + float: left; +} + +.c1_r { + float: right; +} + +.c2 { + font-size: 13.2px; + color: black; +} + +.cost .on { + color: #e51329; +} + +.jf_info { + width: 100%; + height: 45.6px; + background: white; + border-bottom: 1px solid #e6e6e6; +} + +.jf_jf { + margin-top: 10px; + margin-left: 10px; + color: #e51326; + font-size: 10.8px; + border: 1px solid #e51227; + border-radius: 3px; + float: left; + padding: 0 5px; +} + +.jf_p { + font-size: 13.2px; + color: #525252; + float: left; + margin-left: 10px; + line-height: 46px; +} + +.jf_p o { + color: #e51329; +} + +.lxmj { + width: 100%; + height: 51.6px; + position: relative; + background: white; + margin-bottom: 6px; + display: block; +} + +.lxmj img { + width: 15px; + position: absolute; + top: 50%; + left: 40%; + transform: translate(-50%, -50%); +} + +.lxmj p { + font-size: 13.2px; + color: #525252; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.info { + width: 100%; + padding: 9px; + background: white; + margin-bottom: 6px ; +} + +.info p { + color: #909090; + font-size: 10.8px; +} \ No newline at end of file diff --git a/static/app2/css/orsupermarket.css b/static/app2/css/orsupermarket.css new file mode 100755 index 0000000..c4cd1a1 --- /dev/null +++ b/static/app2/css/orsupermarket.css @@ -0,0 +1,385 @@ +body{ + background: #e3e3e3; +} + +.oc_logo { + width: 67.5px; + height: 16.5px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 13.75px; +} + +.search { + width: 100%; + height: 37px; + border-top: 1px solid #EFEFF4; + background-color: rgba(255, 255, 255, 1); + position: relative; +} + +.search .class { + width: 24px; + height: 21px; + float: left; + margin-left: 4%; + margin-top: 7.5px; +} + +.oc_search { + width: 72%; + height: 28px; + background-color: rgb(216, 216, 216); + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + border-radius: 16px; + margin-top: 4px; +} + +.oc_class { + width: 12.5px; + height: 12.5px; + float: left; + margin-left: 2.7%; + margin-top: 7.5px; +} + +#search_p { + font-family: "微软雅黑"; + font-size: 11px; + color: #fff; + line-height: 26px; + float: left; + margin-left: 2.6%; +} + +.oc_shopcar { + width: 22.5px; + height: 21.5px; + float: right; + margin-top: 7.5px; + margin-right: 2.7%; +} + +.orS { + width: 100%; + padding: 1% 2% 0 2%; +} + +#top_banner { + width: 100%; + height: 300px; + margin: 20px auto; + margin: 0; + position: relative; +} + +#top_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#top_banner .swiper-slide img { + width: 100%; + height: 100%; +} + +#top_banner .swiper-pagination-bullet-active { + background: white; +} + +#top_banner .swiper-pagination-bullet { + background: #eee; +} + +.recommend { + width: 100%; + background-color: rgba(255, 255, 255, 1); + position: relative; + z-index: 111; + border-radius: 5px; + transform: translateY(-8px); +} + +.recommend .muji { + width: 101px; + height: 37.5px; + margin-left: 42%; + float: left; +} + +.recommend .all { + float: left; + font-family: "微软雅黑"; + font-size: 12px; + color: #f5364c; + right: 5%; + top: 20px; + position: absolute; +} + +.recommend .all img { + width: 13px; + height: 13px; + transform: translateY(1px); +} + +.mujireco { + width: 100%; + margin-top: 12px; + margin-left: 2%; +} + +.reco_res { + width: 30%; + float: left; + margin-left: 3%; +} + +#reco_1 { + margin-left: 0; +} + +.reco_res img { + width: 100%; +} + +.reco_res .p1 { + width: 100%; + font-family: "微软雅黑"; + font-size: 13px; + color: #000000; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp:2; + overflow: hidden; + margin-top: 15px; + margin-bottom: 17px; + height: 40px; +} + +.reco_res .p2{ + width: 100%; + font-family: "微软雅黑"; + font-size: 12px; + color:#e51329; + margin-bottom: 21px; +} + +.rec_food{ + width: 100%; + background-color: rgba(255, 255, 255, 1); + border-radius: 5px; + /*margin-bottom:-10.5px;*/ +} + +.add_top { + width: 100%; + height: 264px; +} + +.add_top_left { + width: 41.5%; + border-right: 1px solid #EFEFF4; + float: left; + height: 264px; + position: relative; +} + +.food_p1 { + font-size: 15px; + position: absolute; +} + +.food_p2 { + color: black; + font-size: 13px; + position: absolute; +} + +.add_top_left .food_p1 { + background: linear-gradient(to right, #26a4ce, #ff65ce); + -webkit-background-clip: text; + color: transparent; + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + top: 41.5px; +} + +.add_top_left .food_p2 { + margin: 0 auto; + left: 0; + right: 0; + text-align: center; + top: 69.5px; +} + +.add_top_left img { + width: 70%; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + bottom: 30.5px; +} + +.add_top_right { + width: calc(100% - (41.5%+1px)); + float: left; + height: 264px; +} + +.add_top_right_con { + width: 100%; + height: 132px; + position: relative; +} + +.atrct { + border-bottom: 1px solid #EFEFF4; +} + +.food_right_p{ + background: linear-gradient(to right, #ffb400, #ff6c00); + -webkit-background-clip: text; + color: transparent; + left:40%; + top: 15px; +} + +.add_top_right_con .food_p2{ + background: linear-gradient(to right, #00aeff, #01ffcc); + -webkit-background-clip: text; +} + +.add_top_right img{ + width: 34%; + position: absolute; + top: 40.5px; +} + +.add_top_right_con .food_right_img1{ + left: 14%; +} +.add_top_right_con .food_right_img2{ + left: 55%; +} + +.food_class{ + width: 100%; + background: #fff; + border-radius: 5px; + + margin-top: 5px ; +} + +.food_class_top{ + width: 100%; +} + +.food_class_top ul{ + width: 100%; + padding: 0; +} + +.food_class_top ul li{ + float: left; + font-family: "微软雅黑"; + font-size: 13px; + margin-left: 16px; + padding-top:13.5px ; + padding-bottom:13.5px ; +} + +.food_class_top .on{ + color:#f5364c; + border-bottom:3px solid #f5364c; +} + +.food_class_list{ + width: 100%; + background: #fff; +} + +.recommend_con_block{ + margin: 0 1%; + width: 48%; + border-radius: 5px; + background: white; + position: relative; + float: left; + margin-bottom: 5px; + overflow: hidden; +} +.rcb_img{ + width: 100%; + display: block; +} + +.rcb_con{ + width: 100%; + height: 105px; + padding: 3% 3% 0; +} +.rcb_title{ + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 13px; + height: 43px; +} +.rcb_title span{ + border-radius: 5px; + font-size: 11px; + color: white; + background: #e6132c; + padding: 0 2px; +} +.rcb_pay{ + margin-top: 2px; + width: 100%; + font-size: 14px; + color: #e51329; +} +.rcb_pay span{ + border: 1px solid #e51329; + font-size: 10px; + padding: 0 2px; + border-radius: 5px; + margin-left: 10px; +} +.rcb_bottom{ + margin-top: 2px; +} +.rcb_bottom span{ + color: #e51329; + font-size: 10px; + padding: 1px 2px; + background: #FFD7D7; +} + + + + + diff --git a/static/app2/css/pay.css b/static/app2/css/pay.css new file mode 100755 index 0000000..7510146 --- /dev/null +++ b/static/app2/css/pay.css @@ -0,0 +1,195 @@ +.bg { + background: rgba(1, 1, 1, 0.1); + position: fixed; + left: 0; + top: 0; + bottom: 0; + right: 0; + z-index: 10; +} +.pay_info{ + margin-bottom: 100px; + + } +.pay,.pay_way { + position: fixed; + left: 0; + right: 0; + bottom: 0; + background: white; + margin-bottom: 52px; + min-height: 400px; + /* height: 90%; */ +} +.pay{ + /*transform: translateY(380px);*/ + display: none; +} +.pay_title { + width: 100%; + height: 49px; + border-bottom: 1px solid #e6e6e6; + position: relative; +} + +.pay_title a { + position: absolute; + z-index: 10; + font-size: 30px; + color: #909090; + line-height: 50px; + left: 5px; +} + +.pay_title p { + line-height: 48px; + text-align: center; + color: black; + font-size: 15.6px; +} + +.paynum { + font-size: 15px; + text-align: center; + color: black; + padding: 20px 0; +} + +.con_1 { + padding-left: 15px; +} + +.con_1 .row { + width: 100%; + height: 42px; + border-bottom: 1px solid #e6e6e6; + line-height: 42px; + font-size: 13.2px; +} + +.row_left { + float: left; + color: #909090; +} + +.row_right { + float: right; + color: black; + padding-right: 15px; + position: relative; +} + +.row_right img { + position: absolute; + right: 15px; + top: 12px; +} + +.pay_btn { + width: 92%; + margin: 3px 4% ; + color: #FFFFFF; + background: #e6122b; + border: none; + border-radius: 1%; + height: 42px; +} + +/* .pay_way .pay_title a { + font-size: 30px; + margin: 6px; +} */ +#qlg_pay_pwd .con_2 .prod .info{ + padding: 5px; + display: flex; + justify-content: space-between; + align-items: center; + margin: 0px; +} +#qlg_pay_pwd .con_2 .prod .info .p1{ + flex: 1; + padding: 0px; + margin: 0px 8px; + text-align: left; +} +#qlg_pay_pwd .con_2 .prod .info .p1 span{ + margin-left: 10px; +} +#qlg_pay_pwd .con_2 .shadown_wai input{ + width: 40%; + min-width: 65px; + padding: 0px; + margin: 5px 20px; + text-align: right; + height: 30px; + /* border: 0px; */ +} +.wangInfo .p1{ + min-width: 50px; + padding-left: 10px; +} +.pay_way .con .row .row_left { + color: black; +} + +.row .mui-icon { + color: #e6122b; + font-size: 42px; + padding: 0; +} +#pay_pwd,#qlg_pay_pwd .con_1 { + width: 70%; + margin: 0 auto; + padding:10px 0px; + text-align: center; + position: relative; +} +#pay_pwd,#qlg_pay_pwd .con_2{ + padding:0; + margin: 0; + /* position: relative; */ +} + +#pay_pwd,#qlg_pay_pwd .con_1 input{ + margin: 14px 5%; + width: 70%; + height: 30px; +} +/* #pay_pwd,#qlg_pay_pwd .con_2 input{ + margin: 0 5%; + width: 90%; +} */ +#pay_pwd,#qlg_pay_pwd .con_1 .p9{ + /* margin: 30px 5%; */ + /* width: 90%; */ + position: absolute; + /* padding:10px; */ + left:18%; + /* right: 5%; */ + top:57px; +} + +/* #pay_pwd,#qlg_pay_pwd .con_2 .p1{ + display: inline-block; + padding:0; + margin: 0; + font-size:15px; +} */ +.pay_btn_pwd { + width: 50%; + text-align: center; + margin:5px 25%; + color: #FFFFFF; + background: #e6122b; + border: none; + border-radius: 2%; + height: 42px; +} +.footer{ + position: fixed; + bottom: 0; + width: 100%; + background: white; + height: 49px; + border-top: 1px solid #e6e6e6; +} \ No newline at end of file diff --git a/static/app2/css/paymentVoucher.css b/static/app2/css/paymentVoucher.css new file mode 100755 index 0000000..6b874df --- /dev/null +++ b/static/app2/css/paymentVoucher.css @@ -0,0 +1,232 @@ +.con { + width: 98%; + margin: 0px auto 20px; +} +.con .info { + margin-bottom: 5px; + +} +.rowList { + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + margin: 0px auto; + padding: 3px 1px; + background: #fff; + border-bottom:1px solid #ccc; +} +.rowList label{ + min-width:70px; + font-size: 13px; + +} +.rowList input { + font-size: 13px; + padding: 0px 10px; + margin: 0px; + text-align: right; + border: 0px; + } +input{ + margin-right: 5px; + height: 20px; +} +.con_nav { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + overflow: hidden; + border: 1px solid #fff; + border-radius: 15px; +} +.nh_left{ + /* border: 1px solid #fff; */ + +} +.nav_header { + text-align: center; + flex: 1; + background: #00D793; + color: #fff; + height: 30px; + line-height: 30px; + /* border-right: 1px solid #f00; */ + +} + +.active { + background: #f00; + color: #ccc; +} +.row{ + margin:8px auto; + background: white; + padding:0px 5px; +} +.row_block_list { + display: flex; + justify-content: space-between; + align-items: flex-start; + /* background: #efefef; */ + padding: 5px auto; + +} + +.row_block_img { + width: 117px; + height: 126px; + padding: 9px 0 9px 9px; +} + +.row_block_img img { + width: 100%; + height: 100%; +} + + .row_title { + display: flex; + justify-content:space-between; + align-items: center; + padding: 5px 1%; + font-size: 14px; +} + .row_title_ { + display: flex; + justify-content:space-between; + align-items: center; + padding: 5px 1%; + font-size: 14px; +} +/* .uncommitted .row_title { + justify-content:flex-start; + +} */ +.committed .row_title { + justify-content:space-between; + font-size: 12px; +} +.store_name{ + font-size: 15px; + +} +/* .committed .oper{ + background: url(../img/bianji.png) no-repeat /50% 50%; + background: #000000; + } */ +.rcr { + flex: 0.8; + padding-top: 9px; +} + +.rcrc p { + overflow: hidden; + font-size: 12px; + color: black; +} + +.rcrc .leibie { + color: #909090; +} + +.rcrr { + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + padding-top: 9px; +} + +.rcrr p { + color: black; + font-size: 12px; + margin-bottom: 5px; +} + +/* .rcrr del { + color: #909090; + font-size: 12px; + + } */ +.row_title label{ + font-size: 14px; + color: black; +} +.rcrr span { + color: #909090; + font-size: 12px; +} + +.combination { + width: 100%; + height: 37px; + border-bottom: 1px solid #e6e6e6; + background: white; + text-align: right; + font-size: 12px; + line-height: 36px; + padding-right: 9px; +} + +.combination_totle { + font-size: 15px; + background: #FF1A03; + padding: 0px 10px; + + /* flex: 1; */ + height: 30px; + line-height: 30px; + text-align: center; + border: 1px solid #f00; + border-radius: 15px; + color: #fff; +} + +.combination_totle span { + /* color: #f00; */ + margin:0px 5px; +} +.committed { + margin-top: 10px; +} +.row_cont .row_block_list{ + font-size: 13px; + align-items: center; + padding: 6px 1%; + } +.oper{ + width: 20px; + height: 20px; +} +.oper img { + width: 100%; + height: 100%; +} +.btns { + display: flex; + justify-content: space-between; + align-items: center; + margin: 10px 0px; +} +.btns input{ + height: 20px; + +} +.btns label{ + font-size: 14px; + color: black; +} +.bc_btn { + height: 30px; + line-height: 30px; + /* flex: 0.7; */ + font-size: 15px; + text-align: center; + padding: 0px 10px; + /* width: 70%; */ + /* margin: 10px auto; */ + color: #fff; + background: #FF1A03; + border-radius: 15px; +} diff --git a/static/app2/css/photoswipe.css b/static/app2/css/photoswipe.css new file mode 100755 index 0000000..0ca0f80 --- /dev/null +++ b/static/app2/css/photoswipe.css @@ -0,0 +1,179 @@ +/*! PhotoSwipe main CSS by Dmitry Semenov | photoswipe.com | MIT license */ +/* + Styles for basic PhotoSwipe functionality (sliding area, open/close transitions) +*/ +/* pswp = photoswipe */ +.pswp { + display: none; + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + overflow: hidden; + -ms-touch-action: none; + touch-action: none; + z-index: 1500; + -webkit-text-size-adjust: 100%; + /* create separate layer, to avoid paint on window.onscroll in webkit/blink */ + -webkit-backface-visibility: hidden; + outline: none; } + .pswp * { + -webkit-box-sizing: border-box; + box-sizing: border-box; } + .pswp img { + max-width: none; } + +/* style is added when JS option showHideOpacity is set to true */ +.pswp--animate_opacity { + /* 0.001, because opacity:0 doesn't trigger Paint action, which causes lag at start of transition */ + opacity: 0.001; + will-change: opacity; + /* for open/close transition */ + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp--open { + display: block; } + +.pswp--zoom-allowed .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-zoom-in; + cursor: -moz-zoom-in; + cursor: zoom-in; } + +.pswp--zoomed-in .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; } + +.pswp--dragging .pswp__img { + /* autoprefixer: off */ + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; } + +/* + Background is added as a separate element. + As animating opacity is much faster than animating rgba() background-color. +*/ +.pswp__bg { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: #000; + opacity: 0; + -webkit-transform: translateZ(0); + transform: translateZ(0); + -webkit-backface-visibility: hidden; + will-change: opacity; } + +.pswp__scroll-wrap { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: hidden; } + +.pswp__container, +.pswp__zoom-wrap { + -ms-touch-action: none; + touch-action: none; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; } + +/* Prevent selection and tap highlights */ +.pswp__container, +.pswp__img { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; } + +.pswp__zoom-wrap { + position: absolute; + width: 100%; + -webkit-transform-origin: left top; + -ms-transform-origin: left top; + transform-origin: left top; + /* for open/close transition */ + -webkit-transition: -webkit-transform 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: transform 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp__bg { + will-change: opacity; + /* for open/close transition */ + -webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); + transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); } + +.pswp--animated-in .pswp__bg, +.pswp--animated-in .pswp__zoom-wrap { + -webkit-transition: none; + transition: none; } + +.pswp__container, +.pswp__zoom-wrap { + -webkit-backface-visibility: hidden; } + +.pswp__item { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow: hidden; } + +.pswp__img { + position: absolute; + width: auto; + height: auto; + top: 0; + left: 0; } + +/* + stretched thumbnail or div placeholder element (see below) + style is added to avoid flickering in webkit/blink when layers overlap +*/ +.pswp__img--placeholder { + -webkit-backface-visibility: hidden; } + +/* + div element that matches size of large image + large image loads on top of it +*/ +.pswp__img--placeholder--blank { + background: #222; } + +.pswp--ie .pswp__img { + width: 100% !important; + height: auto !important; + left: 0; + top: 0; } + +/* + Error message appears when image is not loaded + (JS option errorMsg controls markup) +*/ +.pswp__error-msg { + position: absolute; + left: 0; + top: 50%; + width: 100%; + text-align: center; + font-size: 14px; + line-height: 16px; + margin-top: -8px; + color: #CCC; } + +.pswp__error-msg a { + color: #CCC; + text-decoration: underline; } diff --git a/static/app2/css/pj.css b/static/app2/css/pj.css new file mode 100755 index 0000000..755aab7 --- /dev/null +++ b/static/app2/css/pj.css @@ -0,0 +1,126 @@ +body { + background: #ebebeb; +} + +.describe { + width: 100%; + height: 70.2px; + background: #fff; + border-bottom: 1px solid #e7e7e7; + border-top: 1px solid #e7e7e7; +} + +.des_img { + width: 51px; + height: 51px; + margin-left: 3%; + margin-top: 2%; + float: left; +} + +.des_img img { + width: 50px; + height: 50px; +} + +.describe p { + font-family: "微软雅黑"; + font-size: 13.2px; + float: left; + line-height: 70.2px; + margin-left: 5%; + color: #000000; + width: calc(100% - 100px); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.row p { + font-family: "微软雅黑"; + font-size: 13.2px; + float: left; + line-height: 40px; + margin-left: 5%; + color: #000000; +} + + + +.star_a img { + width: 15px; + height: 13.8px; + float: left; + margin-top: 80%; +} + +.row { + width: 100%; + height: 40px; + background: #fff; + border-top: 1px solid transparent; +} + +.purchase { + width: 100%; + background: #fff; + border-top: 1px solid transparent; + padding: 0 5% 10px; +} + +.purchase textarea { + width: 100%; + height: 76.2px; + padding: 0; + font-family: "微软雅黑"; + font-size: 12px; + margin-top: 5px; + /*border: none;*/ +} + +.tijiao { + width: 90%; + background: #f02c43; + margin: 10px 5%; + text-align: center; + font-family: "微软雅黑"; + font-size: 15.6px; + color: #fff; + line-height: 40.8px; + border: none; +} +.star_a{ + float: left; + padding: 10px; + width: 40px; + height: 40px; + margin-left: 2%; +} +.star_off{ + width: 100%; + height: 100%; + background: url(../img/pjhx1.png)no-repeat center center; + background-size: 100%; +} +.star_on{ + width: 100%; + height: 100%; + background: url(../img/pjhx.png)no-repeat center center; + background-size: 100%; +} +.purchase_ p{ + padding:1% 0 5%; + font-size: 13.2px; + color: black; +} +.purchase_{ + background: white; + padding-bottom: 10px; + top: 1px solid transparent; + padding: 0 5% 10px; +} +.purchase_ img{ + width: 70px; + height: 70px; + padding: 5px; +} diff --git a/static/app2/css/properties.css b/static/app2/css/properties.css new file mode 100755 index 0000000..c4f78cf --- /dev/null +++ b/static/app2/css/properties.css @@ -0,0 +1,116 @@ + +.row { + display: flex; + justify-content: space-between; + align-items: center; + background:#10B5AF; + /* height: 50px; */ + position: relative; + /* padding: 0px 7px; */ + width: 98%; + margin: 5px auto; + padding: 10px; + flex: 1; + border: 1px solid #10B5AF; +} + +.row label { + max-width: 200px; + font-size: 16px; + color: #fff; + +} + +.caozuo { + width: 25%; + display: flex; + justify-content: space-around; + align-items: space-between; +} + +.caozuo span { + display: inline-block; + /* width: 28%; */ +} +.caozuo .mui-icon{ + font-size: 32px; +} +.caozuo span img { + width: 100%; + height: 100%; + /* color: #000; */ +} +.row input { + width:180px; + border: 1px solid #CECECE; + margin: 0px; + padding: 0px 2px; + height: 26px; + text-align: right; +} +.row input::-webkit-input-placeholder{ + font-size: 13px; +} + +.addproperties-content { + width: 100%; +} +.add1{ + width: 96%; + margin: 5px auto; + height: 63px; + background:#C9C9C9; + border:1px solid #C9C9C9; + border-radius: 5px; + display:flex; + justify-content: center; + align-items:center ; + margin-top: 10px; + } + .addimg{ + width: 40px; + height: 40px; + } + .add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + } + + + + +.addproperties-img { + width: 70px; + height: 70px; + text-align: center; + background: #fff; + margin: 0 auto; +} + +.addproperties-img .mui-icon { + width: 70px; + height: 30px; + font-size: 40px; + margin-bottom: 15px; + text-align: center; +} + +.save { + text-align: center; + margin: 50px auto 5px; +} + +.mui-btn { + width: 50%; +} +.bc_btn { + height: 30px; + line-height: 30px; + text-align: center; + width: 70%; + margin: 30px auto; + color: #fff; + background: #FF1A03; + border-radius: 15px; +} diff --git a/static/app2/css/qrrz.css b/static/app2/css/qrrz.css new file mode 100755 index 0000000..048d766 --- /dev/null +++ b/static/app2/css/qrrz.css @@ -0,0 +1,103 @@ +.con{ + margin-bottom: 25px; +} +.con .block{ + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px 10px; + color: #fff; + background:#10B5AF; + margin: 5px auto; + border: 1px solid #10B5AF; + border-radius: 5px; + } + .pname{ + + width: 80%; + color: #fff; + } + .guanxi { + width: 37%; + color: #242424; + text-align: right; + } + .caozuo { + width: 20%; + display: flex; + justify-content: space-around; + align-items: center; + } + .caozuo span { + display: inline-block; + width: 25%; + } + .caozuo span img{ + width: 100%; + + } + .add1{ + width: 96%; + margin: 5px auto; + height: 63px; + background:#C9C9C9; + border:1px solid #C9C9C9; + border-radius: 5px; + display:flex; + justify-content: center; + align-items:center ; + /* margin-top: 10px; */ + } + .addimg{ + width: 40px; + height: 40px; + } + .add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; + } + + + .footer_btn{ + width: 100%; + height: 50px; + border: none; + position: fixed; + bottom: 0; + background: #E5122B; + color: white; + border-radius: 0; + } + .lxy_zz{ + width: 80%; + margin: 0 auto; + position: relative; + top:40%; + padding-top:10px; + padding-bottom:10px; + background: #fff; + } + .lxy_zz h3{ + text-align: center; + font-size: 18px; + font-weight: 200; + + } + .lxy_zz input{ + /* position: absolute; */ + width: 88%; + display:block; + /* top:50%; + left: 10%; */ + margin: 10px auto; + height: 35px; + border-radius: 5px; + } + .lxy_zz_btn{ + display: flex; + justify-content: space-between; + width: 80%; + margin: 0 auto; + } \ No newline at end of file diff --git a/static/app2/css/recommend.css b/static/app2/css/recommend.css new file mode 100755 index 0000000..9c6ed1c --- /dev/null +++ b/static/app2/css/recommend.css @@ -0,0 +1,113 @@ +.recommend{ + width: 100%; + padding: 0 1%; +} +.recommend_title{ + padding: 0 1%; +} +.recommend_title img{ + width: 100%; + display: block; +} +.recommend_con{ + +} +.recommend_con_block{ + margin: 0 1%; + width: 48%; + border-radius: 5px; + background: white; + position: relative; + float: left; + margin-bottom: 5px; + overflow: hidden; +} +.rcb_img{ + width: 100%; + display: block; +} + +.rcb_con{ + width: 100%; + height: 105px; + padding: 3% 3% 0; +} +.rcb_title{ + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 13px; + height: 42px; +} +.rcb_title span{ + border-radius: 5px; + font-size: 11px; + color: white; + background: #e6132c; + padding: 0 2px; +} +.rcb_pay{ + margin-top: 2px; + width: 100%; + font-size: 14px; + color: #e51329; +} +.rcb_pay span{ + border: 1px solid #e51329; + font-size: 10px; + padding: 0 2px; + border-radius: 5px; + margin-left: 10px; +} +.rcb_bottom{ + margin-top: 2px; + display: flex; + justify-content: space-between; + align-items: center; +} +.rcb_bottom span{ + color: #e51329; + font-size: 10px; + padding: 1px 2px; + /* background: #FFD7D7; */ + border-radius: 20px 0 0px 20px; +} +.rcb_bottom .s1{ + color: white; + font-size: 10px; + padding: 1px 2px; + background: -moz-linear-gradient(left, #e9c520, #ffad03); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#e9c520), to(#ffad03)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #e9c520, #ffad03); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #e9c520, #ffad03); + /*Opera11*/ + border-radius:0 20px 20px 0px; +} +.icon_icon{ + position: absolute; + width: 27px; + height: 29px; + right: 5%; + top: 10px; +} +.rcb_pay o{ + background: -moz-linear-gradient(left, #a200ff, #6600ff); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#a200ff), to(#6600ff)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #a200ff, #6600ff); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #a200ff, #6600ff); + /*Opera11*/ + color: white; + font-size: 12px; + padding: 0 3px; + border-radius:4px; +} +.rcb_pay o img{ + width: 20px; +} diff --git a/static/app2/css/reviewsmanage.css b/static/app2/css/reviewsmanage.css new file mode 100755 index 0000000..64b27d4 --- /dev/null +++ b/static/app2/css/reviewsmanage.css @@ -0,0 +1,90 @@ +.overallmanage{ + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + height: 155px; + margin: 2px auto 10px; + background: #fff; + } + .overallmanage label{ + font-size: 15px; + /* font-weight: 300; */ + color: #414141; + } +.overallscore{ + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; +} + .overallscore .score{ + font-size: 50px; + color: orange; + height: 55px; + } +.fivestars { + flex: 2; +} +.fivestars .row{ + display: flex; + justify-content: space-around; + align-items: flex-start; + padding: 5px; +} +.stars{ + display: flex; + justify-content: space-around; + align-items: center; +} +.stars span{ + display: inline-block; + width: 21px; + height: 21px; +} +.stars span img{ + width: 100%; + height: 100%; +} + +.con_con{ + padding: 5px; + margin-bottom: 5px; +} +.overallmanage_con{ + width: 98%; + margin: 3px auto; + background: #fff; +} +.con_top{ + display: flex; + justify-content: space-between; + align-items: center; +} +.con_con_con{ + display: flex; + justify-content: space-between; + align-items: center; +} +.imgs{ + display: flex; + justify-content: flex-start; + align-items: center; + flex-wrap: wrap; + align-content: flex-start; + +} +.img_con{ + width: 20%; + height: 80px; + margin: 10px auto; +} +.img_con img{ + width: 100%; + height: 100%; +} + + + \ No newline at end of file diff --git a/static/app2/css/rul.css b/static/app2/css/rul.css new file mode 100755 index 0000000..d57a8f4 --- /dev/null +++ b/static/app2/css/rul.css @@ -0,0 +1,36 @@ +body{ + background: #EBEBEB; +} + +.mui-scroll{ + padding: 8.7%; +} + +.rul_p{ + font-family: "微软雅黑"; + font-size: 16.8px; + text-align: center; + color: #000000; +} + +.rul_div{ + width: 100%; + margin-top: 21px; + background: #fff; +} + +.rul_div p{ + margin-left: 2%; + margin-right: 2%; +} + +.rul_div .rul_p1{ + font-family: "微软雅黑"; + font-size: 14.4px; + color: #ff3600; +} +.rul_div .rul_p2{ + font-family: "微软雅黑"; + font-size: 10.8px; + color: #0e0e0e; +} diff --git a/static/app2/css/saoyisao.css b/static/app2/css/saoyisao.css new file mode 100755 index 0000000..c5ea7bc --- /dev/null +++ b/static/app2/css/saoyisao.css @@ -0,0 +1,34 @@ +#bcid { + width: 100%; + height: 100%; + position: absolute; + background: #000000; +} + +html, +body, +div { + height: 100%; + width: 100%; +} + +.fbt { + color: #0E76E1; + width: 50%; + background-color: #ffffff; + float: left; + line-height: 44px; + text-align: center; +} +.choose{ + height: 50px; + display: flex; + justify-content: space-between; + align-items: center; +} +.choose .cancel{ + position:static; + /* top: 10px; */ + /* right: 12px; */ + z-index: 100; + } \ No newline at end of file diff --git a/static/app2/css/self_shop.css b/static/app2/css/self_shop.css new file mode 100755 index 0000000..7e4060a --- /dev/null +++ b/static/app2/css/self_shop.css @@ -0,0 +1,381 @@ +.saoyisao { + color: white; + font-size: 30px; + background: rgba(25, 25, 25, .4); + width: 35px; + height: 35px; + padding: 2.5px; + right: 3%; + top: 50%; + transform: translateY(-50%); + border-radius: 50%; + line-height: 27px; + } + + .mui-icon-arrowdown { + margin-top: 23px; + color: white; + font-size: 25px; + background: rgba(25, 25, 25, .4); + width: 30px; + height: 30px; + padding: 2px; + margin-left: 5px; + top: 50%; + transform: translateY(-50%); + border-radius: 50%; + line-height: 27px; + + } + + #location, + #location-r { + display: inline-block; + color: #555555; + font-size: 18px; + height: 44px; + line-height: 48px; + min-width: 44px; + } + + .search input { + padding: 0; + width: auto; + text-align: left; + font-size: 18px; + } + + .zy_ac { + width: 100%; + background: white; + margin-top: 9px; + } + + .zyac_c { + width: 50%; + float: left; + } + + .zyac_c .time_icon { + width: 43px; + } + + .zyac_c .timer { + left: 50px; + } + + .zyac_con { + padding: 2%; + } + + .zyac_block { + width: 50%; + float: left; + } + + .zyac_con img { + width: 100%; + padding: 0 8%; + display: block; + } + + .zyac_block p { + /*position: absolute;*/ + bottom: 25px; + text-align: center; + font-size: 14px; + color: #e51329; + width: 100%; + height: 21px; + } + + .zyac_block del { + text-align: center; + /*position: absolute;*/ + bottom: 5px; + font-size: 12px; + color: #808080; + width: 100%; + height: 21px; + display: block; + } + + .zy_add { + margin-top: 9px; + width: 100%; + background: white; + } + + .zya_block { + width: 50%; + float: left; + position: relative; + } + + .zya_block p { + position: absolute; + left: 5%; + } + + .zya_block .p1 { + top: 7%; + color: #333333; + font-weight: bold; + font-size: 14px; + } + + .zya_block .p2 { + top: 25%; + color: 818181; + font-size: 12px; + } + + .zya_block img { + width: 50%; + position: absolute; + right: 0; + bottom: 0; + padding: 10% 3% 3% 10%; + } + + .addsc_top img { + width: 100%; + display: block; + } + + .adds .p1 { + background: linear-gradient(to right, #f24e5a, #fd891f); + -webkit-background-clip: text; + color: transparent; + } + + .adds .p1_ { + background: linear-gradient(to right, #4ea3f2, #f94e97); + -webkit-background-clip: text; + color: transparent; + } + + .adds .p1__ { + background: linear-gradient(to right, #f24e5a, #8c3ad8); + -webkit-background-clip: text; + color: transparent; + } + + .classify { + padding: 0 4% 5px; + } + + #top_banner { + /* height: 460px; */ + width: 100%; + height: 300px; + margin: 20px auto; + /* margin: 0; */ + position: relative; + } + + #top_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + } + + #top_banner .swiper-slide img { + width: 100%; + height: 100%; + } + + #top_banner .swiper-pagination-bullet-active { + background: white; + } + + #top_banner .swiper-pagination-bullet { + background: #eee; + } + + .shops-nav { + background: #fff; + margin: 10px auto; + padding: 10px auto; + height: 30px; + line-height: 30px; + width: 100%; + display: flex; + justify-content: space-between; + border-radius: 10px; + overflow: hidden; + } + + .shops-nav .on { + color: #f00; + /* background: #FF0000; */ + border-bottom: 1px solid #f00; + } + + .shops-nav1 { + width: 50%; + text-align: center; + } + + .shops-content1-content { + margin: 0px; + padding: 0px; + /* padding: 0px 10px; */ + } + + .shops-content1-title { + display: flex; + justify-content: space-between; + align-items: center; + height: 60px; + width: 100%; + padding: 0px 10px; + overflow: hidden; + } + + .shops-content1-title .shop-name { + font-size: 17px; + /* font-weight: 200; */ + color: #505050; + display: inline-block; + width: 65%; + } + + .shops-content1-title .aixinImg { + width: 13px; + height: 13px; + margin-left: 7px; + vertical-align: middle; + } +.aixinlevel { + display: inline-block; + height: 13px; + line-height: 13px; + font-size: 14px; + color: #F02A40; + } +/* .shops-content1-title .aixinImg img { + width: 100%; + height: 100%; + } */ + .shops-content1-title .logoimg { + display: inline-block; + width: 40px; + height: 40px; + /* height: 30px; */ + } + + .shops-con-con { + background: #fff; + margin: 5px auto; + } + + .shops-content1-title .logoimg img { + width: 100%; + height: 100%; + /* padding-top: 3px; */ + } + + .shops-content1-title .gogogo { + display: inline-block; + width: 25%; + height: 24px; + line-height: 24px; + font-size: 18px; + border: 1px solid #E94744; + text-align: center; + border-radius: 12px; + color: #fff; + background: #E94744; + } + + .t_con { + display: flex; + justify-content: flex-start; + align-items: center; + /* height: 150px; */ + padding: 5px 10px; + } + + .t_con_ { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + height: 130px; + width: 30%; + } + + .t_con_ span { + font-size: 18px; + color: #666; + } + + .t_con_img { + height: 100px; + width: 100%; + } + + .t_con_ img { + width: 100%; + height: 100%; + } + + /* #timer_swiper .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; */ + /* Center slide text vertically */ + /* display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + } */ + + /* #timer_swiper .swiper-slide img { + width: 100%; + height: 100%; + } */ + + .pos { + margin: 5px auto; + padding: 0px 10px; + height: 25px; + line-height: 25px; + width: 100%; + text-align: right; + } + + .pos img { + display: inline-block; + width: 4%; + padding-top: 3px; + margin-right: 5px; + + } + + .pos span { + font-size: 18px; + color: #909090; + } diff --git a/static/app2/css/setting.css b/static/app2/css/setting.css new file mode 100755 index 0000000..40db993 --- /dev/null +++ b/static/app2/css/setting.css @@ -0,0 +1,114 @@ +body .header1{ + z-index: 11; + width: 100%; + position: fixed; + top: 0; + background: rgba(255,255,255,1); + border: none; + box-shadow: 0 0 0; + height: 66px; + border-bottom: 1px solid #efefef; +} +.mui-bar-nav.mui-bar .mui-icon { + margin-left: 0; +} +.mui-title{ + color: #909090; +} +.header1 .on{ + border-bottom: 3px solid #ff0000; + color: #e61329; +} +.nav{ + padding: 0 50px; + height: 66px; + text-align: center; +} +.p1{ + color: #000; + display: block; + line-height: 46px; + font-size: 18px; + padding-top: 20px; +} +.header1 .mui-action-back { + margin-top: 20px; + margin-left: 0; + color: #848484; + float: left; +} + +.footer{ + position: fixed; + bottom: 0; + width: 100%; + background: white; + height: 49px; + border-top: 1px solid #e6e6e6; +} + +.z{ + width: 100%; + height: 66px; +} +.block{ + margin-top: 36px; + padding: 0 2%; +} + +.row{ + background: white; + width: 100%; + height: 42px; + border-bottom: 1px solid #ebebeb; + position: relative; + margin-bottom: 5px; +} +.row:last-child{ + border-bottom: none; +} + + + +.row .img{ + width: 15.6px; + position: absolute; + top: 12px; + left: 12px; +} +.r1{ + font-size: 13.2px; + color: black; + line-height: 42px; + position: absolute; + left: 35px; +} +.r2{ + font-size: 12px; + color: #909090; + line-height: 42px; + position: absolute; + right: 25px; +} +.row img.youjiantou{ + width: 6px; + position: absolute; + right: 10px; + top: 15px; +} +.loginout{ + width: 96%; + height: 42px; + line-height: 42px; + text-align: center; + margin: 36px 2%; + background: -moz-linear-gradient(left, #f5354b, #ff005a); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5354b), to(#ff005a)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5354b, #ff005a); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5354b, #ff005a); + /*Opera11*/ + color: #fff; +} diff --git a/static/app2/css/setting_address.css b/static/app2/css/setting_address.css new file mode 100755 index 0000000..8fc13cd --- /dev/null +++ b/static/app2/css/setting_address.css @@ -0,0 +1,86 @@ +.con .block{ + width: 100%; + height: 117px; + background: white; + border-bottom: 5px solid #ebebeb; + position: relative; +} +.pname{ + position: absolute; + font-size: 14.4px; + color: black; + left: 15px; + top: 15px; +} + +.pphone{ + position: absolute; + font-size: 14.4px; + color: black; + right: 15px; + top: 15px; +} +.paddress{ + position: absolute; + font-size: 10.8px; + color: black; + left: 15px; + top: 40px; +} +.block hr{ + position: absolute; + width: 100%; + top: 60px; + border: none; + border-top: 1px dotted #909090; +} +.btnout{ + width: 42px; + height: 42px; + position: absolute; + bottom: 0; + padding: 12px; + left: 5px; +} +.btn{ + width: 100%; + height: 100%; + border-radius: 50%; + border: 1px solid #909090; +} +.btnout .on{ + border: none; + background: #e7172f; +} +.block .p1{ + position: absolute; + font-size: 12px; + color: black; + left: 40px; + bottom: 0px; + height: 42px; + padding: 0; + line-height: 42px; +} +button{ + padding-left: 20px; + padding-right: 20px; + position: absolute; + bottom: 5px; +} +.bj{ + right: 100px; +} +.del{ + right: 15px; +} +.footer_btn{ + width: 100%; + height: 50px; + border: none; + position: fixed; + bottom: 0; + background: #E5122B; + color: white; + border-radius: 0; +} diff --git a/static/app2/css/sha.css b/static/app2/css/sha.css new file mode 100755 index 0000000..e8cf3bc --- /dev/null +++ b/static/app2/css/sha.css @@ -0,0 +1,13 @@ +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); + position: relative; + z-index: 1000; +} diff --git a/static/app2/css/share.css b/static/app2/css/share.css new file mode 100755 index 0000000..58a1d0c --- /dev/null +++ b/static/app2/css/share.css @@ -0,0 +1,25 @@ +.con{ + position: relative; +} +.con .bg{ + width: 100%; + display: block; +} +.con .img{ + position: absolute; + top: 17.1%; + width: 28%; + left: 50%; + transform: translateX(-50%); +} +.share{ + position: absolute; + right: 10px; + padding: 3px 8px; + bottom: 5px; + font-size: 12px; + z-index:1000; +} +.img img{ + width: 100%; +} diff --git a/static/app2/css/share_user_list.css b/static/app2/css/share_user_list.css new file mode 100755 index 0000000..336c71a --- /dev/null +++ b/static/app2/css/share_user_list.css @@ -0,0 +1,164 @@ +.scroll_out_{ + position: fixed; + top: 114px; + bottom: 0; + left: 0; + right: 0; +} + +.row{ + width: 100%; + background: white; + border-top: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; +} +.row_top{ + width: 100%; + height: 54px; + +} +.row_h_r{ + border-top: 1px solid #e6e6e6; + width: 100%; + height: 36px; +} + +.row_h_r p{ + line-height: 36px; + margin: 0; + text-align: center; +} + + +.row_top .img{ + padding: 9px; + width: 54px; + height: 54px; + border-radius: 50%; + overflow: hidden; + display: inline-block; + float: left; +} + +.row_top p{ + float: left; + line-height: 54px; + font-size: 14.4px; + color: #222222; +} +.row_top .btn{ + width: 17px; + height: 54px; + padding: 22px 0; + float: right; + display: inline-block; + margin-right: 12px; +} + +.ani{ + transform:rotate(180deg) +} +.nav{ + position: fixed; + top: 66px; + left: 0; + right: 0; + height: 48px; + background: white; +} +.nav .block{ + float: left; + width: 40%; + margin: 0 5%; + text-align: center; + line-height: 48px; + height: 48px; + font-size: 14.4px; +} +body .nav .on{ + border-bottom: 2px solid #fc2c43; + color: #f02a40; +} +.show_share{ + position:absolute; + top: 15rem; + left:41%; + margin-top:-100px; + margin-left:-100px; + +} +.show_share img{ + width:85%; +} +.header_img{ + position:absolute; + top:0.5%; + left:25.9%; + z-index:2; + width:33.9%; + /*background: #333;*/ + text-align:center; +} +.header_img img{ + border-radius:50%; +} +.name_info{ + position:absolute; + z-index:2; + width:85%; + height: 2rem; + color:#101010; + /*background: #333;*/ + text-align:center; +} + +.name_str{ + font-weight:bold; + font-size:1.35rem; + top:21.7%; +} +.time_str{ + font-size:1.2rem; + top:27%; +} +.share_info{ + position:absolute; + z-index:2; + font-size:1rem; + width:8rem; + height: 2rem; + /*background: #333;*/ + text-align:center; +} +.left{ + left:3.5%; +} +.left1{ + color:#0078fe; + top:41%; +} +.left2{ + color:#fe0000; + top:55%; +} +.right{ + left:41.5%; +} +.right1{ + color:#ff8400; + top:41%; +} +.right2{ + color:#9000ff; + top:55%; +} +.qrcode_img{ + position: absolute; + top: 67%; + width: 35%; + left:43%; + transform: translateX(-50%); +} +.qrcode_img img{ + width: 100%; +} diff --git a/static/app2/css/shop_decorate.css b/static/app2/css/shop_decorate.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/shop_indentcon.css b/static/app2/css/shop_indentcon.css new file mode 100755 index 0000000..758d2af --- /dev/null +++ b/static/app2/css/shop_indentcon.css @@ -0,0 +1,369 @@ +.search { + padding: 7.2px 12px; + background: #ebebeb; +} + +.mui-search {} + +.mui-search .mui-placeholder { + background: #fff; +} + +.mui-search input { + background: #fff; + margin-bottom: 0; +} + +.mui-active::before { + margin-top: -10px; +} + +.row_title { + width: 100%; + position: relative; + height: 36px; + background: white; + border-bottom: 1px solid #e6e6e6 ; +} + +.store_name { + position: absolute; + /*background: url(../img/youjiantou.png) no-repeat center right;*/ + /*background-size: 6px;*/ + padding-right: 12px; + padding-left: 18px; + line-height: 36px; + font-size: 14px; +} + +.indent_status { + /* position: absolute; */ + line-height: 36px; + font-size: 13px; + right: 0; + padding-right: 12px; + float: right; +} +.yellow{ + color: #ffa800; +} +.shopPhone{ + color:tomato; +} +.shopPhone a{ + text-decoration:underline; + color:tomato; + +} +.confirm_wait{ + color: cadetblue; +} +.confirm_ok{ + color: seagreen; +} +.confirm_no{ + color:red; +} +.row{ + margin-bottom: 5px ; + background: white; + padding: 5px 10px; +} +.row_block { + width: 100%; + /*height: 128px;*/ + border-bottom: 2px solid #fff; + /*background: #efefef;*/ +} + +.row_block img { + width: 117px; + height: 126px; + float: left; + padding: 9px 5px 9px 9px; +} +.rc{ + width: calc(100% - 117px); + float: right; +} +.rcr { + /* width: calc(100% - 117px); + float: right; */ + /*height: 126px;*/ + /* padding: 12px; */ + padding-top: 12px; + background: #efefef; +} + +.rcrc { + float: left; + width: calc(100% - 60px); +} + +.rcrc p { + /* height: 42px; */ + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + font-size: 12px; + color: black; +} + +.rcrc .leibie{ + color: #909090; +} + + +.rcrr { + width: 60px; + float: right; + text-align: right; +} +#expressId{ + width: 160px; +} + + +.rcrr p { + color: black; + font-size: 12px; +} + +.rcrr del { + color: #909090; + font-size: 12px; + display: block; + /* height: 20px; */ +} + +.rcrr span { + color: #909090; + font-size: 12px; +} +.rtl { + position: absolute; + /*background: url(../img/youjiantou.png) no-repeat center right;*/ + /*background-size: 6px;*/ + padding-right: 12px; + padding-left: 18px; + line-height: 36px; + font-size: 14px; +} + +.rtr { + /* position: absolute; */ + line-height: 36px; + font-size: 13px; + right: 0; + /* padding-right: 12px; */ + float: right; +} +.rcb span{ + color: #909090; + font-size: 12px; + margin-right: 20px; +} +.combination{ + width: 100%; + /* height: 37px; */ + /* border-bottom: 1px solid #e6e6e6; */ + background: white; + text-align: right; + font-size: 12px; + /* line-height: 36px; */ + padding-right: 4px; +} +.combination o{ + font-size: 14.4px; +} +.user_info_{ + padding: 5px; + background: #fff; + border-top: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + +} +.u_address{ + display: flex; + justify-content:flex-start; + align-items: center; + height: 37px; + width: 100%; +} +.pos_c select{ + max-width: 160px; + margin: 0px; + +} +.pos_c input{ + max-width: 200px; + + +} +.u_address .pos{ + width: 20px; + height: 20px; + +} + .u_address .pos img{ + width: 100%; + height: 100%; + } + +.pos_c{ + display: flex; + justify-content: flex-start; + align-items: center; + padding: 10px; +} +.pos_c label{ + margin-right: 19px; +} +.pos_c p { + display: inline-block; + margin-right: 10px; +} +.pos_c_p{ + width: 50px; + /* margin-left: 10px; */ +} +.btns{ + text-align: right; + width: 100%; + height: 48px; + /*background: white;*/ +} +.btns_btn{ + color: black; + font-size: 12px; + padding:3px 6px; + float: right; + margin: 9.5px 6px; + border-radius: 30px; + background: -moz-linear-gradient(left, #fcff00, #ffde00); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#fcff00), to(#ffde00)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #fcff00, #ffde00); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #fcff00, #ffde00); + /*Opera11*/ + box-shadow: 1px 1px 5px #ffde00; + +} +.btns .kk{ + border: 1px solid #e6e6e6; + border-radius: 1px; +} + +.btns .qrsh{ + border: 1px solid #e5132c; + color: #e5142a; +} + +.bg_{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_ts{ + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.1); + +} +.bg_con{ + width: 90%; + /*height: 160px;*/ + background: white; + margin: 0 auto; + position: absolute; + left: 0; + right: 0; + top: 30%; + border-radius: 5px; +} +#querenshoukuan .con_1,#querentuikuan .con_1{ + /* margin-top: 20px; */ + padding: 20px; + display: flex; + justify-content: space-between; + align-items: center; +} +#querentuikuan { + text-align: center; + } +#querentuikuan textarea{ + width: 98%; + } +.bg_con p{ + border-bottom: 1px solid #efefef; + padding:10px 20px; + color: black; +} +.bg_con .info1{ + padding:10px 20px; + color: black; + border-bottom: none; +} +.en_true,.ts_true{ + background: #2AC845; + color: white; + /*position: absolute;*/ + margin-left: 30%; + border: none; + margin-bottom: 5%; +} +.en_false,.ts_false{ + background: #efefef; + color: #909090; + /*position: absolute;*/ + margin-right: 30%; + border: none; + float: right; +} +#content,#content_ts,#Tmoney{ + margin: 0 5% 5%; + width: 90%; +} +.refundInfo{ + float:left; +} +.refundTxt{ + display: block; + margin: 0 5% 5%; + width: 90% !important; +} +select{ + /*margin: 0;*/ +} +.row_block{ + background: #fbfbfb; +} +.row_block img{ + border-radius: 3px; + overflow: hidden; +} +.rcr { + background: #FBFBFB; +} + +/*20181018*/ +#select{ + margin: 5px 5%; + border: 1px solid rgba(0,0,0,.2)!important; + /*background: red;*/ + width: 90%; +} diff --git a/static/app2/css/shopdecoration.css b/static/app2/css/shopdecoration.css new file mode 100755 index 0000000..34eb68e --- /dev/null +++ b/static/app2/css/shopdecoration.css @@ -0,0 +1,76 @@ +.shopdecoration-title { + height: 60px; + line-height: 60px; + width: 100%; + background: #000000; + text-align: center; + /* font-size: 18px; */ + display: flex; + justify-content: space-between; + align-items: center; +} + +.shopdecoration-title a { + display: inline-block; + width: 30px; + height: 30px; + background: #242424; + border-radius: 30px; + line-height: 30px; + color: #fff; + /* padding-top: 15px; */ + /* margin-top: 15px; */ +} + +.mui-action-back { + font-size: 26px; + height: 30px; + position: absolute; + /* top: 0px; */ + left: 15px; + z-index: 100; +} +.shopdecoration-title h3 { + display: inline-block; + width: 80%; + text-align: center; + font-size: 20px; + color: #fff; + height: 60px; + line-height: 60px; + /* margin-top: -3px; */ +} +.thumbnail-title{ + margin: 15px auto; +} +.thumbnail-img{ + width: 100px; + height: 100px; + text-align: center; + background: #fff; + margin: 0 auto; +} +.thumbnail-img .mui-icon{ + width: 70px; + height: 70px; + font-size: 40px; + padding-top: 20px; +} +.shopadds-title{ + margin: 15px auto; +} +.shopadds-img{ + width: 300px; + height: 200px; + overflow: hidden; + background: #fff; + margin: 0 auto; + margin-bottom: 10px; +} +.save{ + text-align: center; + margin: 10px auto; +} +.mui-btn{ + width: 50%; +} \ No newline at end of file diff --git a/static/app2/css/shopgoodlist.css b/static/app2/css/shopgoodlist.css new file mode 100755 index 0000000..d28a92b --- /dev/null +++ b/static/app2/css/shopgoodlist.css @@ -0,0 +1,90 @@ +.con { + margin-bottom: 35px; +} + +.row { + display: flex; + justify-content: space-between; + /* align-items: center; */ + width: 98%; + height: 100px; + margin: 3px auto; + background: #0FD5F7; + padding: 8px; +} + +.row .left { + flex: 1; + margin-right: 10px; +} + +.row .left img { + width: 100%; + height: 100%; +} +.row .right { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: auto; + flex: 1; + +} + +.row .right .oper { + + display: flex; + justify-content: space-around; + align-items: center; +} + +.row .right span { + display: inline-block; + width: 30%; + height: 25px; + /* background: #0FD5F7; */ +} + +.row .right span img { + width: 100%; + height: 100%; +} + +.row .right p { + /* display: inline-block; */ + text-align: center; + background: #F0AD4E; + color: #fff; +} + +.row .center { + flex: 2; + color: #fff; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.add1 { + width: 96%; + margin: 10px auto; + height: 63px; + background: #C9C9C9; + border: 1px solid #C9C9C9; + border-radius: 5px; + display: flex; + justify-content: center; + align-items: center; + /* margin-top: 10px; */ +} + +.addimg { + width: 40px; + height: 40px; +} + +.add1 img { + /* position: absolute; */ + width: 100%; + height: 100%; +} diff --git a/static/app2/css/shoppingcart.css b/static/app2/css/shoppingcart.css new file mode 100755 index 0000000..1bcd633 --- /dev/null +++ b/static/app2/css/shoppingcart.css @@ -0,0 +1,396 @@ +body:after { + content: ""; + position: fixed; + /*top: -10px;*/ + bottom: -10px; + left: 0; + width: 100%; + height: 10px; + box-shadow: 0 -0.5vw 2.3vw 3px rgba(25, 25, 25, 0.1); + /*-webkit-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -moz-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -o-box-shadow: 0 0.5vw 2.3vw 15px #ccc; + -ms-box-shadow: 0 0.5vw 2.3vw 15px #ccc;*/ + z-index: 100; +} + +.con {} + +.block { + padding: 0; + margin: 0; + background: white; + padding-bottom: 5px; + margin-bottom: 4px; +} + +.b_title { + width: 100%; + border-bottom: 1px solid #e6e6e6; +} + +.b_title .check1 { + padding: 9px 9px; + float: left; +} + +.check_0 { + width: 18px; + height: 18px; + background: url(http://img.juzi199.com/static/app2/img/no_checked.png) no-repeat top left; + background-size: 18px 18px; + border-radius: 50%; +} + +.check_1 { + width: 18px; + height: 18px; + background: url(http://img.juzi199.com/static/app2/img/checked.png) no-repeat top left; + background-size: 18px 18px; + border-radius: 50%; +} + +.b_title .b_link { + float: left; + text-indent: 17; + font-size: 13.2px; +} + +.b_title .b_link a { + color: black; + line-height: 40px; + height: 36px; + display: inline-block; +} + +.b_title img { + height: 12px; + margin: 12px 6px; + float: left; +} + +.b_con { + height: 105px; +} + +.btn_bj { + display: block; + float: right; + color: black; + line-height: 36px; + font-size: 12px; + padding: 0 12px; +} + +.b_con .check2 { + padding: 43.5px 9px; + float: left; +} + +.s_img { + width: 93px; + height: 93px; + margin: 6px 0; + float: left; +} + + +.b_con_r1 { + padding: 9px 12px; + float: left; + width: calc(100% - 129px); +} + +.p1 { + font-size: 12px; + margin: 0; + color: black; + max-height: 42px; + overflow: hidden; +} + +.p2 { + font-size: 10.8px; + margin: 0; + color: #909090; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bz { + font-size: 10.8px; +} + +.cost { + color: #e94744; +} + +.oldcost { + color: #909090; +} + +.num { + float: right; + color: black; + padding-right: 5px; +} + +.b_con_r2 { + float: left; + height: 105px; + width: calc(100% - 129px); +} + +.b_con_r2_l { + float: left; + height: 105px; + /* 修改 */ + /* padding: 15px; */ + padding: 40px 30px; + /* width: calc(100% - 51px); */ + width: calc(100% - 56px); +} + +.b_con_r2_r { + height: 105px; + line-height: 105px; + float: right; + width: 51px; + padding: 34px 0px; + margin-right: 5px; +} + +.b_con_r2_del { + width: 51px; + + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 12px; + text-align: center; + /* 修改 */ + /* height: 105px; */ + /* line-height: 105px; */ + /* float: right; */ + + line-height: 36px; + height: 36px; + /* padding-top: 30px; */ + +} + +.js { + border-top: 1px solid #e6e6e6; + width: 100%; + height: 51px; + position: fixed; + bottom: 0; + left: 0; + z-index: 10; + background: white; + line-height: 53px; +} + +.js .check { + padding: 16.5px 9px; + float: left; +} + +.qx { + font-size: 14.4px; + margin: 0; + padding: 0; +} + +.js_r { + float: right; + position: absolute; + right: 0; + top: 0; +} + +.js_r span { + font-size: 12px; +} + +.js_r span j { + color: #e94744; +} + +.js_r span o { + color: #909090; +} + +.btn_tj { + display: inline-block; + width: 102px; + height: 51px; + background: -moz-linear-gradient(left, #ff0423, #ff58a3); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#ff0423), to(#ff58a3)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #ff0423, #ff58a3); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #ff0423, #ff58a3); + /*Opera11*/ + text-align: center; + color: white; + font-size: 14.4px; +} + +.jian { + padding: 5px; + width: 22px; + height: 22px; + float: left; +} + +.changenum input { + float: left; + margin: 0; + padding: 0; + /* width: calc(100% - 84px); */ + width: calc(100% - 64px); + text-align: center; + height: 22px; + border: none; + /* margin: 0 20px; */ + + margin: 0 10px; +} + +.jia { + padding: 5px; + width: 22px; + height: 22px; + float: left; +} + +.changeclass { + margin-top: 18px; + font-size: 12px; + color: #909090; +} + +.changeclass img { + float: right; + height: 21px; + padding: 7.5px; + display: block; +} + +.cc1 { + width: 100%; + height: 27px; +} + +.cclass_con { + position: absolute; + bottom: 0; + left: 0; +} + +.cc2 { + width: 100%; + height: 81px; + background: white; + position: relative; + border-bottom: 1px solid #e3e6ea; +} + +.cc2 p { + font-size: 15.6px; + color: #e94744; + position: absolute; + left: 120px; + top: 24px; +} + +.cc2 span { + font-size: 12px; + position: absolute; + left: 120px; + top: 48px; +} + +.closecclass { + font-size: 15.6px; + color: #9b9b9b; + position: absolute; + padding: 9px 12px; + right: 0; + top: 0; +} + +.cclass_con .img { + background: white; + padding: 6px; + position: absolute; + border: 1px solid #f2f2f2; + border-radius: 6px; + width: 85.8px; + height: 85.8px; + top: 0; + left: 12px; + z-index: 60; +} + +.cclass_con .img img { + width: 100%; + height: 100%; + border-radius: 3px; +} + +.cclass1 { + padding: 18px 0 0 12px; + background: white; + border-bottom: 1px solid #e3e6ea; +} + +.cclass1 p { + color: #626262; + font-size: 13.2px; + padding-bottom: 18px; + margin: 0; +} + +.cclass1 .block { + padding: 3px 9px; + float: left; + border: 1px solid #9e9e9e; + margin: 0 18px 18px 0; + border-radius: 6px; + font-size: 14.4px; + color: #1d1d1d; +} + +.cclass1 .on { + border: 1px solid #e94947; +} + +.ensure { + width: 100%; + height: 48px; + background: -moz-linear-gradient(left, #f5364c, #e51329); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#f5364c), to(#e51329)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #f5364c, #e51329); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #f5364c, #e51329); + /*Opera11*/ + color: white; + font-size: 14.4px; + display: block; + line-height: 51px; + text-align: center; +} + +.con .recommend {} diff --git a/static/app2/css/shopsList.css b/static/app2/css/shopsList.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/shopsetting.css b/static/app2/css/shopsetting.css new file mode 100755 index 0000000..05261c4 --- /dev/null +++ b/static/app2/css/shopsetting.css @@ -0,0 +1,23 @@ +.row { + display: flex; + justify-content: space-between; + align-items: center; + background: #fff; + height: 50px; + position: relative; + padding: 0px 7px; + width: 98%; + margin: 0 auto; + flex: 1; +} +.row label { + flex: 1; + font-size: 13px; + color: #363636; +} +.sl-img{ + flex: 1; + text-align: right; +} + + \ No newline at end of file diff --git a/static/app2/css/store_activity.css b/static/app2/css/store_activity.css new file mode 100755 index 0000000..cc117e5 --- /dev/null +++ b/static/app2/css/store_activity.css @@ -0,0 +1,189 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .b_con img { + width: 120px; + height: 120px; + } + .p3{ + width: calc( 100% - 130px ) ; + } + .p4{ + left: 130px; + } + .b_con{ + height: 120px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .b_con img { + width: 110px; + height: 110px; + } + .p3{ + width: calc( 100% - 120px ) ; + } + .p4{ + left: 120px; + } + .b_con{ + height: 110px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .b_con img { + width: 100px; + height: 100px; + } + .p3{ + width: calc( 100% - 110px ) ; + } + .p4{ + left: 110px; + } + .b_con{ + height: 100px; + } +} + + + +.block { + padding: 12px 5% 0; + background: white; + margin-bottom: 5px; +} + +.b_title { + position: relative; + height: 48px; +} + +.block .b_title1 { + position: relative; + height: 80px; +} + +.clock { + width: 13.2px; + position: absolute; + left:0; + top: 9px; +} + +.b_title1 .ac_jt{ + width: 12px; + position: absolute; + left: 0; + top:34px; +} + +.b_title .ac_jt{ + width: 12px; + position: absolute; + left: 0; + top:34px; +} + +.b_title1 .p1 { + position: absolute; + font-size: 14.4px; + left: 15px; + top: 6px; + color: black; +} + + +.b_title1 .p2 { + color: #222222; + position: absolute; + font-size: 14.4px; + width: calc( 100% - 60px); + left: 15px; + top: 29.5px; +} +.b_title .p2 { + color: #222222; + position: absolute; + font-size: 14.4px; + width: calc( 100% - 60px); + left: 15px; + top: 29.5px; +} + +.b_title1 .p5{ + color:#585858; + font-size: 14px; + position: absolute; + left: 12px; + top: 55px; +} +.b_title .p5{ + color:#585858; + font-size: 14px; + position: absolute; + left: 12px; + top: 55px; +} + + .ele .img{ + width: 100%; +} + +.b_con { + margin: 12px 0 ; + position: relative; +} + +.p3{ + color: #909090; + font-size: 14.4px; + float: right; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} +.p4{ + color: #e51329; + font-size: 15.6px; + position: absolute; + bottom: 30px; +} + +.manjian{ + width:10%; + height: 14.5px; + border: 1px solid #e51329; + text-align: center; + position: absolute; + bottom: 32px; + left: 180px; + color: #e51329; + font-size: 10px; + line-height: 12.5px; + border-radius: 4px; +} + +.muji{ + width: 39%; + height: 16px; + background: #ffd7d7; + position: absolute; + bottom: 10px; + left: 122px; + font-size:10px; + color:#e51329; + line-height: 16px; + text-align: center; +} + + diff --git a/static/app2/css/store_class.css b/static/app2/css/store_class.css new file mode 100755 index 0000000..94093da --- /dev/null +++ b/static/app2/css/store_class.css @@ -0,0 +1,17 @@ +.con{ + padding-top: 66px; +} +.row{ + width: 100%; + height: 42px; + line-height: 41px; + border-bottom: 1px solid #e6e6e6; + background: white; + font-size: 13.2px; + color: #525252; + padding-left: 12px; +} +.con .all{ + margin: 6px 0; + border: none; +} diff --git a/static/app2/css/store_commodity.css b/static/app2/css/store_commodity.css new file mode 100755 index 0000000..fbb3a6d --- /dev/null +++ b/static/app2/css/store_commodity.css @@ -0,0 +1,29 @@ + +.commoditylistnav{ + width: 100%; + height: 45px; + background: white; +} +.nav_block{ + width: 25%; + float: left; + height: 45px; + line-height: 45px; + text-align: center; + color:#525252; + font-size: 12px; + +} +.commoditylistnav .on{ + color: #ff9300; +} +#cost_btn{ + position: relative; +} +#cost_btn img{ + position: absolute; + width: 8px; + height: 12px; + top: 15px; + +} diff --git a/static/app2/css/store_home.css b/static/app2/css/store_home.css new file mode 100755 index 0000000..59735f7 --- /dev/null +++ b/static/app2/css/store_home.css @@ -0,0 +1,344 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .mui-slider { + height: 210px; + } + .mui-slider-item { + height: 210px; + } + .mui-slider .mui-slider-item img { + height: 210px; + width: 100%; + } + .con { + + } + .cnxh_block img { + max-width: 188px; + max-height: 188px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 188px; + width: 95%; + margin: -5px auto 0; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .mui-slider { + height: 190px; + } + .mui-slider-item { + height: 190px; + } + .mui-slider .mui-slider-item img { + height: 190px; + width: 100%; + } + .cnxh_block img { + max-width: 168px; + max-height: 168px; + width: 95%; + } + .cnxh_block_info { + background: white; + max-width: 168px; + width: 95%; + margin: -5px auto 0; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .mui-slider { + height: 162.5; + } + .mui-slider-item { + height: 162.5; + } + .mui-slider .mui-slider-item img { + height: 162.5; + width: 100%; + } + .cnxh_block img { + max-width: 144px; + width: 95%; + max-height: 144px; + } + .cnxh_block_info { + background: white; + max-width: 144px; + width: 95%; + margin: -5px auto 0; + } +} + +.label { + padding: 6px 0; +} + +.l_block { + width: 25%; + border-right: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + background: white; + text-align: center; + height: 36px; + line-height: 36px; + color: #525252; + font-size: 12px; + float: left; +} + +.lbrr { + border-right: none; +} +.cnxh_con{ + padding: 2%; +} +.cnxh_block { + width: 50%; + text-align: center; + float: left; + background: #EFEFEF; + border-bottom: 6px solid #efefef; +} + +.s_name { + font-size: 13.2px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + margin: 0; +} + +.s_name o { + font-size: 10.8px; + background: #f02e45; + color: white; + padding: 2px; + border-radius: 3px; + margin-left: 2px; +} + +.cnxh_block_info { + text-align: left; + padding: 2px; + height: 115px; +} + +.cost { + margin: 0; + margin-top: 5px; + font-size: 13.2px; + color: #f45549; +} + +.cost del { + color: #8d8d8d; + font-size: 10.8px; +} +.cost o{ + color: white; + font-size: 10.8px; + background: #E5132C; + border-radius: 3px; + line-height: 10.8px; + padding-top: 1px; +} +.cost_info{ + color: #E51329; + font-size: 9.6px; + background: #dfc4c4; + line-height: 10px; + padding: 4px 3px 1px; + display: inline-block; +} + +.recommend_title{ + padding: 0; + margin:4.8px; +} + +.time { + width: 100%; + margin-top: 3px; + background: white; + border-radius: 5px; + overflow: hidden; +} + +.t_title { + width: 100%; + height: 50px; + position: relative; +} + +.time_icon { + position: absolute; + width: 80.5px; + height: 32.5px; + top: 6px; + left: 1.5%; +} + +.timer { + border: 1px solid #f5394e; + border-radius: 3px; + width: 97.5px; + height: 15px; + line-height: 13px; + font-size: 12px; + text-align: center; + position: absolute; + left: 28%; + top: 18px; + font-family: "微软雅黑"; +} + +.timer_left { + float: left; + background: #f5394e; + color: white; + width: 45px; +} + +.timer_right { + float: left; + color: #f5394e; +} + +.timer_more { + position: absolute; + right: 0; + width: 50px; + height: 20px; + top: 15px; +} + +.timer_more span { + color: #f5364c; + font-size: 12px; + position: absolute; + line-height: 20px; + height: 20px; + left: 0; + right: 0; +} + +.timer_more img { + width: 15px; + height: 15px; + position: absolute; + right: 20%; + top: 2px; +} + +.t_con { + width: 100%; +} + +#top_banner .swiper-slide img { + width: 100%; + height: 100%; +} + +#top_banner .swiper-pagination-bullet-active { + background: white; +} + +#top_banner .swiper-pagination-bullet { + background: #eee; +} +#timer_swiper { + width: 100%; +} +#timer_swiper .swiper-wrapper .swiper-slide img{ + padding: 3px; + border-radius: 7px; +} +.t_con .swiper-container { + width: 800px; +} + +.t_con .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#timer_swiper .swiper-slide { + position: relative; +} + +#timer_swiper .swiper-slide img { + width: 100%; + display: block; +} + +#timer_swiper .swiper-slide p { + position: absolute; +} + +#timer_swiper .swiper-slide del { + text-align: center; + position: absolute; + bottom: 5px; + font-size: 12px; + color: #808080; + width: 100%; + height: 21px; +} + +.home_yhj{ + position: relative; +} + +.home_yhj p{ + color: #fff; +} + +.home_yhj .p1{ + position: absolute; + top: 30%; + left: 6%; + font-size: 12px; +} +.home_yhj .p2{ + position: absolute; + top: 58%; + left: 6%; + font-size: 12px; +} +.home_yhj .p3{ + position: absolute; + top: 38%; + right: 5%; + left: 45%; + text-align: center; + font-size: 50px; + letter-spacing:-4px; +} + diff --git a/static/app2/css/store_info.css b/static/app2/css/store_info.css new file mode 100755 index 0000000..d0294db --- /dev/null +++ b/static/app2/css/store_info.css @@ -0,0 +1,16 @@ +.bg{ + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + background: transparent; +} +.con{ + width: 100%; + position: absolute; + left: 0; + right: 0; + bottom: 50px; + background: white; +} diff --git a/static/app2/css/store_new.css b/static/app2/css/store_new.css new file mode 100755 index 0000000..59f18d2 --- /dev/null +++ b/static/app2/css/store_new.css @@ -0,0 +1,67 @@ +/* 6p */ + +@media all and (min-width: 376px) { + .ct_con img { + height: 414px; + } +} + + +/* 6 */ + +@media all and (min-width: 321px) and (max-width: 375px) { + .ct_con img { + height: 375px; + } +} + + +/* 5 */ + +@media all and (max-width: 320px) { + .ct_con img { + height: 320px; + } +} + +.co_title { + width: 100%; + height: 24px; + padding: 0 5%; +} + +.co_title p { + width: 120px; + height: 24px; + line-height: 24px; + float: left; + font-size: 12px; + text-align: center; +} + +.hengxian { + width: calc(50% - 60px); + height: 1px; + border-top: 1px solid #909090; + float: left; + margin-top: 11px; +} + +.con .con_one .cnxh_con { + padding-top: 0; + padding-bottom: 0; +} + +.con .con_one .cnxh_con .cnxh_block { + border-bottom: 0; +} + + + +.ct_con img { + width: 100%; +} + +.ct_con{ + background: #fff; +} diff --git a/static/app2/css/storeout.css b/static/app2/css/storeout.css new file mode 100755 index 0000000..20a7ea0 --- /dev/null +++ b/static/app2/css/storeout.css @@ -0,0 +1,450 @@ +body .header { + /*background: url(../img/storetopbg.png) no-repeat center top; + background-size: 414px;*/ + background: none; +} +#store .scroll_out,#store1 .scroll_out_t{ + bottom: 50px; +} +.mui-scroll-wrapper .mui-scroll .con { + padding: 0px; +} + +/* .search{ + width: 100%; + height: 60px; + padding-top: 20px; + +} */ +/* .header_con{ + text-align: center; + background: rgba(0, 0,0, 0.8); + height: 66px; +} */ +/* .header_con h3{ + font-size: 18px; + font-weight: 300; + color: #fff; + padding-top: 25px; +} */ +/* body .header .title { + width: 100%; + text-align: center; + height: 30px; + line-height: 30px; + font-size: 16px; + position: relative; + position: absolute; + top: 5px; */ +/* } */ + +/* .mui-action-back{ + position: absolute;top:32px; + left:12px; + color: #fff; + width: 60px; + background: #777; +} */ +/* .mui-icon-email{ + width: 60px; + color: #fff; + background: #777; + +} */ +.con_ { + position: relative; + width: 100%; + /* height: 200px; */ +} + +.con_ .con_img { + width: 100%; + /* height: 200px; */ +} + + +.mui-slider .mui-slider-group .mui-slider-item a img { + width: 100%; + height: 100%; +} +.searchcon { + margin-top: 5px; + width: calc(100% - 84px); + height: 30px; + float: left; + background: #dedede; + position: relative; + border-radius: 13px; +} + +.classmenu { + width: 30px; + height: 30px; + float: left; + margin-top: 5px; + margin-left: 5px; +} + +.searchcon img { + width: 30px; + height: 30px; + padding: 7.5px; + float: left; +} + +.searchcon span { + color: #989898; + font-size: 13.2px; + line-height: 30px; +} + +.b_title { + width: 100%; + position: relative; + height: 60px; + /* top:10px; */ + display: flex; + justify-content: space-between; + align-items: center; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + background: rgba(256, 256, 256, 0.3); +} + +.b_title span { + display: inline-block; +} + +.b_title .b_img { + width: 60px; + height: 60px; + position: absolute; + bottom: 6px; + left: 15px; +} + +.b_title .storename { + /* position: absolute; */ + width: calc(100% - 160px); + margin: 0px auto; + color: #fff; + background: pink; + /* left: 79px; */ + /* top: 18px; */ + font-size: 19.2px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +#allmap { + /* margin-top: 15px; */ +} + +.gothere { + padding: 6px 8px; + height: 44px; + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + background: #ccc; + font-size: 14px; +} + +.go, +.address { + display: flex; + justify-content: center; + align-items: center; +} + +.goimg { + display: inline-block; + width: 20px; + height: 20px; +} +.sx { + margin-top: -50px; + height: 50px; + width: 100%; + text-align: center; + font-size: 12px; +} +.mui-scroll-wrapper, +.scroll_out { + /*position: relative;*/ + z-index: 10; +} +#pullrefresh .mui-scroll{ + position: relative; +} +#top_banner { + width: 100%; + height: 300px; + margin: 20px auto; + margin: 0; + position: relative; +} + +#top_banner .swiper-slide { + text-align: center; + font-size: 18px; + background: #fff; + /* Center slide text vertically */ + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} + +#top_banner .swiper-slide img { + width: 100%; + height: 100%; +} + +#top_banner .swiper-pagination-bullet-active { + background: white; +} + +#top_banner .swiper-pagination-bullet { + background: #eee; +} + +.goimg img { + width: 100%; + height: 100%; +} + +.contactimg { + width: 30px; + height:30px; + /* background: #2B79C3; */ + /* border-radius: 30px; */ +} + +.contactimg img { + width: 100%; + height: 100%; +} +.gt_con_con{ + width: 100%; +} +.row{ + background: #fff; + /* padding: 10px; */ +} +.row .name{ + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px ; + width: 60%; +} +.row .name label{ + display: inline-block; + text-align: center; +} +.label-idx{ + flex: 1; +} +.label-val{ + flex: 2; +} +.time { + position: absolute; + padding: 0 2px; + /*width: calc(100% - 270px);*/ + left: 79px; + color: #fff; + font-size: 14.4px; + top: 42px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + background: -moz-linear-gradient(left, #ff6600, #ff9c00); + /*Mozilla*/ + background: -webkit-gradient(linear, 0 50%, 100% 50%, from(#ff6600), to(#ff9c00)); + /*Old gradient for webkit*/ + background: -webkit-linear-gradient(left, #ff6600, #ff9c00); + /*new gradient for Webkit*/ + background: -o-linear-gradient(left, #ff6600, #ff9c00); + /*Opera11*/ + border-radius: 5px; + text-align: center; +} + +.gz_btn { + width: 71.4px; + height: 21px; + border-radius: 15px; + color: white; + line-height: 21px; + position: absolute; + right: 12px; + font-size: 13.2px; + background: #ff0909; + /* bottom: 15px; */ + bottom: 10px; + text-align: center; +} + +.gz_btn1 { + width: 71.4px; + height: 21px; + border-radius: 15px; + color: #909090; + line-height: 21px; + position: absolute; + text-align: center; + right: 12px; + font-size: 13.2px; + /* bottom: 15px;*/ + bottom: 10px; + + background: #efefef; + /*border: 1px solid #909090;*/ +} + +.nav { + width: 100%; + background: white; + /*padding: 10px 0;*/ +} + +.nav_block { + float: left; + width: 40%; + text-align: center; + margin: 0 5%; + color: #414141; +} + +.nav span { + height: 42px; + line-height: 42px; + display: inline-block; +} + +.nav .on span { + /* color: #0F0F0F; */ + color: #E51329; + /* border-bottom: 2px solid #0f0f0f; */ + border-bottom: 2px solid #E51329; +} + +.footer { + width: 100%; + height: 50px; + border-top: 1px solid #e6e6e6; + position: fixed; + bottom: 0; + left: 0; + background: white; + padding: 12px 0; +} + +.footer div { + width: 50%; + height: 25px; + display: block; + float: left; + text-align: center; + color: #525252; + font-size: 15.6px; +} + +#rmfl { + border-right: 1px solid #e6e6e6; +} + +.rmfl { + width: 100%; + height: 100%; + position: fixed; + top: 0; + bottom: 0; + left: 0; + z-index: 101; +} + +.rmfl .con { + width: 96px; + border-radius: 6px; + overflow: hidden; + position: absolute; + bottom: 48px; + left: 20%; + box-shadow: 1px 1px 1px #eeeeee; + z-index: 110; +} + +.rmfl .con .row { + width: 100%; + height: 49px; + line-height: 48px; + border-top: 1px solid #e6e6e6; + background: white; + text-align: center; + color: #525252; + font-size: 14.4px; +} + +.rmfl .con .row:first-child { + border: none; +} + +.sanjiao { + z-index: 110; + width: 12px; + height: 12px; + position: absolute; + background: white; + border-right: 1px solid #e6e6e6; + border-bottom: 1px solid #e6e6e6; + transform: rotate(45deg); + bottom: 41px; + left: 24%; +} + +.search button { + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; +} + +#keyword { + background: transparent; + height: 30px; + margin: 0; +} + +.searchcon button { + position: absolute; + right: 0; + top: 0; + border: none; + position: absolute; + width: 50px; + height: 30px; + border-radius: 0; + background: #007AFF; + color: white; + border-radius: 50px; +} diff --git a/static/app2/css/swiper.min.css b/static/app2/css/swiper.min.css new file mode 100755 index 0000000..b222bea --- /dev/null +++ b/static/app2/css/swiper.min.css @@ -0,0 +1,15 @@ +/** + * Swiper 3.4.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2017, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: March 10, 2017 + */ +.swiper-container{margin-left:auto;margin-right:auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform,height}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s;-moz-transition:.3s;-o-transition:.3s;transition:.3s;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 5px}.swiper-pagination-progress{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progress .swiper-pagination-progressbar{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar{-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progress{width:100%;height:4px;left:0;top:0}.swiper-container-vertical>.swiper-pagination-progress{width:4px;height:100%;left:0;top:0}.swiper-pagination-progress.swiper-pagination-white{background:rgba(255,255,255,.5)}.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar{background:#fff}.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar{background:#000}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper,.swiper-container-flip .swiper-wrapper{-ms-perspective:1200px}.swiper-container-cube,.swiper-container-flip{overflow:visible}.swiper-container-cube .swiper-slide,.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-cube .swiper-slide .swiper-slide,.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active,.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top,.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-slide{visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-zoom-container{width:100%;height:100%;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-box-pack:center;-moz-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-align:center;-moz-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;text-align:center}.swiper-zoom-container>canvas,.swiper-zoom-container>img,.swiper-zoom-container>svg{max-width:100%;max-height:100%;object-fit:contain}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/static/app2/css/time.css b/static/app2/css/time.css new file mode 100755 index 0000000..d2e85a0 --- /dev/null +++ b/static/app2/css/time.css @@ -0,0 +1,184 @@ +.oc_logo { + width: 67.5px; + height: 16.5px; + position: absolute; + margin: 0 auto; + left: 0; + right: 0; + top: 13.75px; +} + +.top { + width: 100%; + height: 16px; + background: white; +} + +.con { + width: 100%; + padding: 0 2%; + transform: translateY(-16px); +} + +.nav { + width: 100%; + height: 40px; + background: white; + border-top: 1px solid #ececec; + border-left: 1px solid #ececec; +} + +.nav_block { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; + margin: 0 calc(25% - 26.5px); +} +.nav .r{ + float: right; +} +.nav .on { + color: #ee344a; + border-bottom: 4px solid #ed374c; +} + +.time { + width: 100%; + height: 30px; + background: white; + margin-top: 1px; +} + +.time .p1 { + color: #EE344A; + font-size: 13px; + float: left; + padding: 4.5px 0; + margin-left: 15px; +} + +.time .p2 { + color: #101010; + font-size: 10px; + float: right; + padding: 4.5px 0; + margin-right: 15px; +} + +.time .p2 o { + background: #ED374C; + color: white; + padding: 1px 2px; + border-radius: 5px; +} + +.con_ { + +} + +.con_block { + margin-top: 1px; + width: 100%; + height: 170px; + background: white; + position: relative; +} + +.con_block .img { + width: 109px; + height: 109px; + position: absolute; + top: 30px; + left: 2%; +} + +.con_block .p1 { + width: calc(100% - 130px); + right: 2%; + color: #101010; + font-size: 13px; + position: absolute; + + top: 20px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; +} +.con_block .p2{ + color: #ee344a; + font-size: 10px; + position: absolute; + background: #ffd7d7; + border-radius: 3px; + padding: 0px 4px; + top: 70px; + /*width: calc(100% - 130px);*/ + right: calc(100% - 171px); +} +.con_block .p3{ + color: #ec3449; + font-size: 15px; + position: absolute; + width: calc(100% - 130px); + right: 2%; + top: 105px; +} +.con_block .p3 o{ + font-size: 13px; +} +.con_block del{ + color: #808080; + font-size: 14px; + position: absolute; + width: calc(100% - 130px); + right: 2%; + top: 120px; +} +.con_block del o{ + font-size: 12px; +} +.con_block button{ + color: white; + background: #ED374C; + font-size: 13px; + padding: 5px 15px; + border-radius: 5px; + position: absolute; + right: 2%; + bottom: 35px; + border: none; +} +.con_block .p4{ + color: #808080; + font-size: 10px; + position: absolute; + bottom: 10px; + right: 80px; +} +.con_block progress{ + width: 70px; + height: 9px; + border-radius: 10px; + position: absolute; + right: 2%; + bottom: 16px; + background: white; +} +::-ms-fill{ + background:#ED374C; +} +::-moz-progress-bar{ + background:#ED374C; + } +::-webkit-progress-bar{ + background:white; + border: 1px solid #ED374C; + border-radius: 10px; + } +::-webkit-progress-value{ + background:#ED374C; + border-radius:0 5px 5px 0; + } \ No newline at end of file diff --git a/static/app2/css/time_limit.css b/static/app2/css/time_limit.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/topnav.css b/static/app2/css/topnav.css new file mode 100755 index 0000000..7d48ae3 --- /dev/null +++ b/static/app2/css/topnav.css @@ -0,0 +1,23 @@ +.nav { + width: 100%; + height: 40px; + background: white; + border-top: 1px solid #ececec; + border-left: 1px solid #ececec; +} + + +.nav_block { + color: #101010; + font-size: 13px; + float: left; + padding: 9px 0; + height: 40px; + width: 20%; + text-align: center; +} + +.nav .on { + color: #ee344a; + border-bottom: 4px solid #ed374c; +} \ No newline at end of file diff --git a/static/app2/css/upload.css b/static/app2/css/upload.css new file mode 100755 index 0000000..86f70b0 --- /dev/null +++ b/static/app2/css/upload.css @@ -0,0 +1,82 @@ +/* .ossfile{ + width: 80px; + height: 80px; + float: right; +} +.ossfile .files_out{ + width: 80px; + height: 80px; +} +.ossfile img{ + width: 100%; + height: 100%; +} */ +.btn { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: 400; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + text-decoration: none; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} + +a.btn:hover { + background-color: #3366b7; +} + +.progress { + margin-top: 2px; + width: 60px; + height: 10px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} + +.progress-bar { + background-color: rgb(92, 184, 92); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%, transparent); + background-size: 40px 40px; + box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset; + box-sizing: border-box; + color: rgb(255, 255, 255); + display: block; + float: left; + font-size: 12px; + height: 20px; + line-height: 20px; + text-align: center; + transition-delay: 0s; + transition-duration: 0.6s; + transition-property: width; + transition-timing-function: ease; + width: 60px; +} + +.ossfile .files_out b img{ + width: 60px; + height: 60px; +} +.files_out{ + float: left; + padding: 5px; +} diff --git a/static/app2/css/upload1.css b/static/app2/css/upload1.css new file mode 100755 index 0000000..4447551 --- /dev/null +++ b/static/app2/css/upload1.css @@ -0,0 +1,69 @@ +.btn { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: 400; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + text-decoration: none; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} + +a.btn:hover { + background-color: #3366b7; +} + +.progress { + margin-top: 2px; + width: 60px; + height: 10px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} + +.progress-bar { + background-color: rgb(92, 184, 92); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%, transparent); + background-size: 40px 40px; + box-shadow: rgba(0, 0, 0, 0.14902) 0px -1px 0px 0px inset; + box-sizing: border-box; + color: rgb(255, 255, 255); + display: block; + float: left; + font-size: 12px; + height: 20px; + line-height: 20px; + text-align: center; + transition-delay: 0s; + transition-duration: 0.6s; + transition-property: width; + transition-timing-function: ease; + width: 60px; +} + +.ossfile .files_out b img{ + width: 60px; + height: 60px; +} +.files_out{ + float: left; + padding: 5px; +} diff --git a/static/app2/css/vouchers.css b/static/app2/css/vouchers.css new file mode 100755 index 0000000..5589aef --- /dev/null +++ b/static/app2/css/vouchers.css @@ -0,0 +1,44 @@ +.row{ + display: flex; + justify-content: space-between; + align-items: center; + width: 98%; + margin: 0 auto; + padding: 10px; + font-size: 12px; + color: #909090; + height: 100px; + background: pink; +} +.row .num{ + width: 100px; + text-align: center; + font-size: 22px; + color: #FA0306; + font-weight: 400; + /* height: 100px; */ +} +.row .info{ + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: space-between; + text-align: left; + flex: 2; + +} +.row .info .info_{ + font-size: 15px; + color: #525252; + +} +.row .info .time{ + font-size: 13px; + color: #666; + margin:10px 0px 20px; +} +.row .info .valid{ + font-size: 13px; + color: #666; + padding-left: 10px; +} \ No newline at end of file diff --git a/static/app2/css/yhk.css b/static/app2/css/yhk.css new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/css/zhuweiba.css b/static/app2/css/zhuweiba.css new file mode 100755 index 0000000..0f5c147 --- /dev/null +++ b/static/app2/css/zhuweiba.css @@ -0,0 +1,3 @@ +/* .mui-scroll-wrapper .con{ + margin-top: 40px; +} */ \ No newline at end of file diff --git a/static/app2/img/1.png b/static/app2/img/1.png new file mode 100755 index 0000000..950d16a Binary files /dev/null and b/static/app2/img/1.png differ diff --git a/static/app2/img/10.1.png b/static/app2/img/10.1.png new file mode 100755 index 0000000..e906699 Binary files /dev/null and b/static/app2/img/10.1.png differ diff --git a/static/app2/img/2.png b/static/app2/img/2.png new file mode 100755 index 0000000..1518343 Binary files /dev/null and b/static/app2/img/2.png differ diff --git a/static/app2/img/3.8acbg.png b/static/app2/img/3.8acbg.png new file mode 100755 index 0000000..2103144 Binary files /dev/null and b/static/app2/img/3.8acbg.png differ diff --git a/static/app2/img/3.png b/static/app2/img/3.png new file mode 100755 index 0000000..29a169e Binary files /dev/null and b/static/app2/img/3.png differ diff --git a/static/app2/img/4.png b/static/app2/img/4.png new file mode 100755 index 0000000..23979ab Binary files /dev/null and b/static/app2/img/4.png differ diff --git a/static/app2/img/5.png b/static/app2/img/5.png new file mode 100755 index 0000000..cc7cc3a Binary files /dev/null and b/static/app2/img/5.png differ diff --git a/static/app2/img/ac1yhqbg1.png b/static/app2/img/ac1yhqbg1.png new file mode 100755 index 0000000..6c5a715 Binary files /dev/null and b/static/app2/img/ac1yhqbg1.png differ diff --git a/static/app2/img/ac1yhqbg2.png b/static/app2/img/ac1yhqbg2.png new file mode 100755 index 0000000..bb841b7 Binary files /dev/null and b/static/app2/img/ac1yhqbg2.png differ diff --git a/static/app2/img/ac1yhqbg3.png b/static/app2/img/ac1yhqbg3.png new file mode 100755 index 0000000..abf6c75 Binary files /dev/null and b/static/app2/img/ac1yhqbg3.png differ diff --git a/static/app2/img/ac1yhqbg4.png b/static/app2/img/ac1yhqbg4.png new file mode 100755 index 0000000..6a95f8c Binary files /dev/null and b/static/app2/img/ac1yhqbg4.png differ diff --git a/static/app2/img/ac2_ac3_bg.png b/static/app2/img/ac2_ac3_bg.png new file mode 100755 index 0000000..0e364f9 Binary files /dev/null and b/static/app2/img/ac2_ac3_bg.png differ diff --git a/static/app2/img/ac2_bg1.png b/static/app2/img/ac2_bg1.png new file mode 100755 index 0000000..d012f71 Binary files /dev/null and b/static/app2/img/ac2_bg1.png differ diff --git a/static/app2/img/ac2_footer.png b/static/app2/img/ac2_footer.png new file mode 100755 index 0000000..86e287f Binary files /dev/null and b/static/app2/img/ac2_footer.png differ diff --git a/static/app2/img/ac2_sanjiao.png b/static/app2/img/ac2_sanjiao.png new file mode 100755 index 0000000..96a74d3 Binary files /dev/null and b/static/app2/img/ac2_sanjiao.png differ diff --git a/static/app2/img/ac2_title_bg.png b/static/app2/img/ac2_title_bg.png new file mode 100755 index 0000000..018c1e1 Binary files /dev/null and b/static/app2/img/ac2_title_bg.png differ diff --git a/static/app2/img/ac2_zdzb_bg.png b/static/app2/img/ac2_zdzb_bg.png new file mode 100755 index 0000000..a81827d Binary files /dev/null and b/static/app2/img/ac2_zdzb_bg.png differ diff --git a/static/app2/img/ac2_zdzb_zzc.png b/static/app2/img/ac2_zdzb_zzc.png new file mode 100755 index 0000000..b47cf2c Binary files /dev/null and b/static/app2/img/ac2_zdzb_zzc.png differ diff --git a/static/app2/img/ac2activity_bg.png b/static/app2/img/ac2activity_bg.png new file mode 100755 index 0000000..6c9355f Binary files /dev/null and b/static/app2/img/ac2activity_bg.png differ diff --git a/static/app2/img/ac2yhqbg.png b/static/app2/img/ac2yhqbg.png new file mode 100755 index 0000000..bfe2fdd Binary files /dev/null and b/static/app2/img/ac2yhqbg.png differ diff --git a/static/app2/img/ac3_bg.png b/static/app2/img/ac3_bg.png new file mode 100755 index 0000000..c318d9c Binary files /dev/null and b/static/app2/img/ac3_bg.png differ diff --git a/static/app2/img/ac3_bg1.png b/static/app2/img/ac3_bg1.png new file mode 100755 index 0000000..ea9479b Binary files /dev/null and b/static/app2/img/ac3_bg1.png differ diff --git a/static/app2/img/ac3_bg2.png b/static/app2/img/ac3_bg2.png new file mode 100755 index 0000000..f2b4b22 Binary files /dev/null and b/static/app2/img/ac3_bg2.png differ diff --git a/static/app2/img/ac3_bg3.png b/static/app2/img/ac3_bg3.png new file mode 100755 index 0000000..1f17abd Binary files /dev/null and b/static/app2/img/ac3_bg3.png differ diff --git a/static/app2/img/ac3_bg4.png b/static/app2/img/ac3_bg4.png new file mode 100755 index 0000000..e992a60 Binary files /dev/null and b/static/app2/img/ac3_bg4.png differ diff --git a/static/app2/img/ac3_bg5.png b/static/app2/img/ac3_bg5.png new file mode 100755 index 0000000..b16dca0 Binary files /dev/null and b/static/app2/img/ac3_bg5.png differ diff --git a/static/app2/img/ac3_button.png b/static/app2/img/ac3_button.png new file mode 100755 index 0000000..d4aaffe Binary files /dev/null and b/static/app2/img/ac3_button.png differ diff --git a/static/app2/img/ac3_button1.png b/static/app2/img/ac3_button1.png new file mode 100755 index 0000000..a0b49bb Binary files /dev/null and b/static/app2/img/ac3_button1.png differ diff --git a/static/app2/img/ac3_header_bg.png b/static/app2/img/ac3_header_bg.png new file mode 100755 index 0000000..91a7179 Binary files /dev/null and b/static/app2/img/ac3_header_bg.png differ diff --git a/static/app2/img/ac3_title.png b/static/app2/img/ac3_title.png new file mode 100755 index 0000000..c81d9c1 Binary files /dev/null and b/static/app2/img/ac3_title.png differ diff --git a/static/app2/img/ac3_title1.png b/static/app2/img/ac3_title1.png new file mode 100755 index 0000000..0bae626 Binary files /dev/null and b/static/app2/img/ac3_title1.png differ diff --git a/static/app2/img/ac3_title2.png b/static/app2/img/ac3_title2.png new file mode 100755 index 0000000..b48fbed Binary files /dev/null and b/static/app2/img/ac3_title2.png differ diff --git a/static/app2/img/ac3_title3.png b/static/app2/img/ac3_title3.png new file mode 100755 index 0000000..6ae61aa Binary files /dev/null and b/static/app2/img/ac3_title3.png differ diff --git a/static/app2/img/ac5_bg1.png b/static/app2/img/ac5_bg1.png new file mode 100755 index 0000000..f58024c Binary files /dev/null and b/static/app2/img/ac5_bg1.png differ diff --git a/static/app2/img/ac5_title.png b/static/app2/img/ac5_title.png new file mode 100755 index 0000000..c008dff Binary files /dev/null and b/static/app2/img/ac5_title.png differ diff --git a/static/app2/img/activity1_head.png b/static/app2/img/activity1_head.png new file mode 100755 index 0000000..e4a4b30 Binary files /dev/null and b/static/app2/img/activity1_head.png differ diff --git a/static/app2/img/activity2_head.png b/static/app2/img/activity2_head.png new file mode 100755 index 0000000..c72f202 Binary files /dev/null and b/static/app2/img/activity2_head.png differ diff --git a/static/app2/img/aiguangjie.png b/static/app2/img/aiguangjie.png new file mode 100755 index 0000000..74b8a25 Binary files /dev/null and b/static/app2/img/aiguangjie.png differ diff --git a/static/app2/img/bimaiqingdan.png b/static/app2/img/bimaiqingdan.png new file mode 100755 index 0000000..02e255a Binary files /dev/null and b/static/app2/img/bimaiqingdan.png differ diff --git a/static/app2/img/bktj1.png b/static/app2/img/bktj1.png new file mode 100755 index 0000000..d92cd1b Binary files /dev/null and b/static/app2/img/bktj1.png differ diff --git a/static/app2/img/bktj2.png b/static/app2/img/bktj2.png new file mode 100755 index 0000000..36f6ca3 Binary files /dev/null and b/static/app2/img/bktj2.png differ diff --git a/static/app2/img/bktj3.png b/static/app2/img/bktj3.png new file mode 100755 index 0000000..a305ea9 Binary files /dev/null and b/static/app2/img/bktj3.png differ diff --git a/static/app2/img/bktj4.png b/static/app2/img/bktj4.png new file mode 100755 index 0000000..fe4e17e Binary files /dev/null and b/static/app2/img/bktj4.png differ diff --git a/static/app2/img/bktj_bg.png b/static/app2/img/bktj_bg.png new file mode 100755 index 0000000..582a166 Binary files /dev/null and b/static/app2/img/bktj_bg.png differ diff --git a/static/app2/img/cainixihuan.png b/static/app2/img/cainixihuan.png new file mode 100755 index 0000000..e9f38a6 Binary files /dev/null and b/static/app2/img/cainixihuan.png differ diff --git a/static/app2/img/chaoshihui.png b/static/app2/img/chaoshihui.png new file mode 100755 index 0000000..a331dfe Binary files /dev/null and b/static/app2/img/chaoshihui.png differ diff --git a/static/app2/img/chaoshihui2.png b/static/app2/img/chaoshihui2.png new file mode 100755 index 0000000..5ff44dd Binary files /dev/null and b/static/app2/img/chaoshihui2.png differ diff --git a/static/app2/img/classmenu.png b/static/app2/img/classmenu.png new file mode 100755 index 0000000..89b1f97 Binary files /dev/null and b/static/app2/img/classmenu.png differ diff --git a/static/app2/img/close.png b/static/app2/img/close.png new file mode 100755 index 0000000..5c61b74 Binary files /dev/null and b/static/app2/img/close.png differ diff --git a/static/app2/img/cost1.png b/static/app2/img/cost1.png new file mode 100755 index 0000000..8fc371d Binary files /dev/null and b/static/app2/img/cost1.png differ diff --git a/static/app2/img/cost2.png b/static/app2/img/cost2.png new file mode 100755 index 0000000..192996b Binary files /dev/null and b/static/app2/img/cost2.png differ diff --git a/static/app2/img/cost3.png b/static/app2/img/cost3.png new file mode 100755 index 0000000..83cc78c Binary files /dev/null and b/static/app2/img/cost3.png differ diff --git a/static/app2/img/countdown.png b/static/app2/img/countdown.png new file mode 100755 index 0000000..1d11cca Binary files /dev/null and b/static/app2/img/countdown.png differ diff --git a/static/app2/img/dingwei1.png b/static/app2/img/dingwei1.png new file mode 100755 index 0000000..894467e Binary files /dev/null and b/static/app2/img/dingwei1.png differ diff --git a/static/app2/img/e1.png b/static/app2/img/e1.png new file mode 100755 index 0000000..225da71 Binary files /dev/null and b/static/app2/img/e1.png differ diff --git a/static/app2/img/e2.png b/static/app2/img/e2.png new file mode 100755 index 0000000..6189f46 Binary files /dev/null and b/static/app2/img/e2.png differ diff --git a/static/app2/img/e3.png b/static/app2/img/e3.png new file mode 100755 index 0000000..5c51de8 Binary files /dev/null and b/static/app2/img/e3.png differ diff --git a/static/app2/img/e4.png b/static/app2/img/e4.png new file mode 100755 index 0000000..5fdf160 Binary files /dev/null and b/static/app2/img/e4.png differ diff --git a/static/app2/img/e5.png b/static/app2/img/e5.png new file mode 100755 index 0000000..209f4bd Binary files /dev/null and b/static/app2/img/e5.png differ diff --git a/static/app2/img/ect.png b/static/app2/img/ect.png new file mode 100755 index 0000000..f0e5067 Binary files /dev/null and b/static/app2/img/ect.png differ diff --git a/static/app2/img/ect101-1.png b/static/app2/img/ect101-1.png new file mode 100755 index 0000000..fa2cc2b Binary files /dev/null and b/static/app2/img/ect101-1.png differ diff --git a/static/app2/img/ect101-2.png b/static/app2/img/ect101-2.png new file mode 100755 index 0000000..abee73e Binary files /dev/null and b/static/app2/img/ect101-2.png differ diff --git a/static/app2/img/ect101-3.png b/static/app2/img/ect101-3.png new file mode 100755 index 0000000..bc1cdfd Binary files /dev/null and b/static/app2/img/ect101-3.png differ diff --git a/static/app2/img/ect101-4.png b/static/app2/img/ect101-4.png new file mode 100755 index 0000000..b3379c5 Binary files /dev/null and b/static/app2/img/ect101-4.png differ diff --git a/static/app2/img/ect101-5.png b/static/app2/img/ect101-5.png new file mode 100755 index 0000000..8610d22 Binary files /dev/null and b/static/app2/img/ect101-5.png differ diff --git a/static/app2/img/ectb.png b/static/app2/img/ectb.png new file mode 100755 index 0000000..bd3f0b5 Binary files /dev/null and b/static/app2/img/ectb.png differ diff --git a/static/app2/img/eye.png b/static/app2/img/eye.png new file mode 100755 index 0000000..987793c Binary files /dev/null and b/static/app2/img/eye.png differ diff --git a/static/app2/img/faxianhaohuo1.png b/static/app2/img/faxianhaohuo1.png new file mode 100755 index 0000000..19690cf Binary files /dev/null and b/static/app2/img/faxianhaohuo1.png differ diff --git a/static/app2/img/feichangdapai.png b/static/app2/img/feichangdapai.png new file mode 100755 index 0000000..1a45688 Binary files /dev/null and b/static/app2/img/feichangdapai.png differ diff --git a/static/app2/img/fenlei.png b/static/app2/img/fenlei.png new file mode 100755 index 0000000..71404b1 Binary files /dev/null and b/static/app2/img/fenlei.png differ diff --git a/static/app2/img/gouwuquan.png b/static/app2/img/gouwuquan.png new file mode 100755 index 0000000..6e2308b Binary files /dev/null and b/static/app2/img/gouwuquan.png differ diff --git a/static/app2/img/guangshangchang.png b/static/app2/img/guangshangchang.png new file mode 100755 index 0000000..f77d165 Binary files /dev/null and b/static/app2/img/guangshangchang.png differ diff --git a/static/app2/img/guangshangchang1.png b/static/app2/img/guangshangchang1.png new file mode 100755 index 0000000..030115c Binary files /dev/null and b/static/app2/img/guangshangchang1.png differ diff --git a/static/app2/img/guochan_con_bg.png b/static/app2/img/guochan_con_bg.png new file mode 100755 index 0000000..dc893ab Binary files /dev/null and b/static/app2/img/guochan_con_bg.png differ diff --git a/static/app2/img/guochanjingxuan.png b/static/app2/img/guochanjingxuan.png new file mode 100755 index 0000000..9aa7c01 Binary files /dev/null and b/static/app2/img/guochanjingxuan.png differ diff --git a/static/app2/img/haitunlogo.png b/static/app2/img/haitunlogo.png new file mode 100755 index 0000000..5f62490 Binary files /dev/null and b/static/app2/img/haitunlogo.png differ diff --git a/static/app2/img/heart.png b/static/app2/img/heart.png new file mode 100755 index 0000000..e3f7502 Binary files /dev/null and b/static/app2/img/heart.png differ diff --git a/static/app2/img/home.png b/static/app2/img/home.png new file mode 100755 index 0000000..9b11de0 Binary files /dev/null and b/static/app2/img/home.png differ diff --git a/static/app2/img/home2.png b/static/app2/img/home2.png new file mode 100755 index 0000000..695aff9 Binary files /dev/null and b/static/app2/img/home2.png differ diff --git a/static/app2/img/hot.png b/static/app2/img/hot.png new file mode 100755 index 0000000..aef2e3d Binary files /dev/null and b/static/app2/img/hot.png differ diff --git a/static/app2/img/hot2.png b/static/app2/img/hot2.png new file mode 100755 index 0000000..326afa8 Binary files /dev/null and b/static/app2/img/hot2.png differ diff --git a/static/app2/img/hui.png b/static/app2/img/hui.png new file mode 100755 index 0000000..8de74a5 Binary files /dev/null and b/static/app2/img/hui.png differ diff --git a/static/app2/img/huigou.png b/static/app2/img/huigou.png new file mode 100755 index 0000000..f822a64 Binary files /dev/null and b/static/app2/img/huigou.png differ diff --git a/static/app2/img/huiyuankuaibao.png b/static/app2/img/huiyuankuaibao.png new file mode 100755 index 0000000..272cdab Binary files /dev/null and b/static/app2/img/huiyuankuaibao.png differ diff --git a/static/app2/img/huiyuankuangbao.png b/static/app2/img/huiyuankuangbao.png new file mode 100755 index 0000000..98d910b Binary files /dev/null and b/static/app2/img/huiyuankuangbao.png differ diff --git a/static/app2/img/huiyuanmiaosha.png b/static/app2/img/huiyuanmiaosha.png new file mode 100755 index 0000000..cef11ea Binary files /dev/null and b/static/app2/img/huiyuanmiaosha.png differ diff --git a/static/app2/img/huiyuanzhuanhui1.png b/static/app2/img/huiyuanzhuanhui1.png new file mode 100755 index 0000000..a149d53 Binary files /dev/null and b/static/app2/img/huiyuanzhuanhui1.png differ diff --git a/static/app2/img/hyhflfs.png b/static/app2/img/hyhflfs.png new file mode 100755 index 0000000..b97a7f4 Binary files /dev/null and b/static/app2/img/hyhflfs.png differ diff --git a/static/app2/img/hyz_bg.png b/static/app2/img/hyz_bg.png new file mode 100755 index 0000000..4bcebce Binary files /dev/null and b/static/app2/img/hyz_bg.png differ diff --git a/static/app2/img/icon_back.png b/static/app2/img/icon_back.png new file mode 100755 index 0000000..18543c8 Binary files /dev/null and b/static/app2/img/icon_back.png differ diff --git a/static/app2/img/icon_cart.png b/static/app2/img/icon_cart.png new file mode 100755 index 0000000..50a99b2 Binary files /dev/null and b/static/app2/img/icon_cart.png differ diff --git a/static/app2/img/icon_clock.png b/static/app2/img/icon_clock.png new file mode 100755 index 0000000..8233151 Binary files /dev/null and b/static/app2/img/icon_clock.png differ diff --git a/static/app2/img/icon_down.png b/static/app2/img/icon_down.png new file mode 100755 index 0000000..d1c62f7 Binary files /dev/null and b/static/app2/img/icon_down.png differ diff --git a/static/app2/img/icon_menu.png b/static/app2/img/icon_menu.png new file mode 100755 index 0000000..ebb7e71 Binary files /dev/null and b/static/app2/img/icon_menu.png differ diff --git a/static/app2/img/icon_phone1.png b/static/app2/img/icon_phone1.png new file mode 100755 index 0000000..d35ffdc Binary files /dev/null and b/static/app2/img/icon_phone1.png differ diff --git a/static/app2/img/icon_pwd1.png b/static/app2/img/icon_pwd1.png new file mode 100755 index 0000000..e9cc9f3 Binary files /dev/null and b/static/app2/img/icon_pwd1.png differ diff --git a/static/app2/img/icon_right.png b/static/app2/img/icon_right.png new file mode 100755 index 0000000..6967dfb Binary files /dev/null and b/static/app2/img/icon_right.png differ diff --git a/static/app2/img/icon_s.png b/static/app2/img/icon_s.png new file mode 100755 index 0000000..1ba8288 Binary files /dev/null and b/static/app2/img/icon_s.png differ diff --git a/static/app2/img/icon_select.png b/static/app2/img/icon_select.png new file mode 100755 index 0000000..fce1a0d Binary files /dev/null and b/static/app2/img/icon_select.png differ diff --git a/static/app2/img/icon_select1.png b/static/app2/img/icon_select1.png new file mode 100755 index 0000000..a2c32eb Binary files /dev/null and b/static/app2/img/icon_select1.png differ diff --git a/static/app2/img/icon_shop.png b/static/app2/img/icon_shop.png new file mode 100755 index 0000000..f5212f2 Binary files /dev/null and b/static/app2/img/icon_shop.png differ diff --git a/static/app2/img/icon_user1.png b/static/app2/img/icon_user1.png new file mode 100755 index 0000000..96904f8 Binary files /dev/null and b/static/app2/img/icon_user1.png differ diff --git a/static/app2/img/imail.png b/static/app2/img/imail.png new file mode 100755 index 0000000..b48b215 Binary files /dev/null and b/static/app2/img/imail.png differ diff --git a/static/app2/img/imail2.png b/static/app2/img/imail2.png new file mode 100755 index 0000000..890e860 Binary files /dev/null and b/static/app2/img/imail2.png differ diff --git a/static/app2/img/jia.png b/static/app2/img/jia.png new file mode 100755 index 0000000..d3e7f88 Binary files /dev/null and b/static/app2/img/jia.png differ diff --git a/static/app2/img/jian.png b/static/app2/img/jian.png new file mode 100755 index 0000000..978f9e1 Binary files /dev/null and b/static/app2/img/jian.png differ diff --git a/static/app2/img/jifen.png b/static/app2/img/jifen.png new file mode 100755 index 0000000..db88270 Binary files /dev/null and b/static/app2/img/jifen.png differ diff --git a/static/app2/img/jingpintuijian.png b/static/app2/img/jingpintuijian.png new file mode 100755 index 0000000..ba069ca Binary files /dev/null and b/static/app2/img/jingpintuijian.png differ diff --git a/static/app2/img/jxyh.png b/static/app2/img/jxyh.png new file mode 100755 index 0000000..df0e2da Binary files /dev/null and b/static/app2/img/jxyh.png differ diff --git a/static/app2/img/likelogo.png b/static/app2/img/likelogo.png new file mode 100755 index 0000000..7b92f60 Binary files /dev/null and b/static/app2/img/likelogo.png differ diff --git a/static/app2/img/likelogo1.png b/static/app2/img/likelogo1.png new file mode 100755 index 0000000..4ec90cd Binary files /dev/null and b/static/app2/img/likelogo1.png differ diff --git a/static/app2/img/likelogoon.png b/static/app2/img/likelogoon.png new file mode 100755 index 0000000..23a351e Binary files /dev/null and b/static/app2/img/likelogoon.png differ diff --git a/static/app2/img/ljjg_bg.png b/static/app2/img/ljjg_bg.png new file mode 100755 index 0000000..70c68b0 Binary files /dev/null and b/static/app2/img/ljjg_bg.png differ diff --git a/static/app2/img/me.png b/static/app2/img/me.png new file mode 100755 index 0000000..3aa51f5 Binary files /dev/null and b/static/app2/img/me.png differ diff --git a/static/app2/img/me2.png b/static/app2/img/me2.png new file mode 100755 index 0000000..e843967 Binary files /dev/null and b/static/app2/img/me2.png differ diff --git a/static/app2/img/meirigengxin.png b/static/app2/img/meirigengxin.png new file mode 100755 index 0000000..ad6093a Binary files /dev/null and b/static/app2/img/meirigengxin.png differ diff --git a/static/app2/img/menu.png b/static/app2/img/menu.png new file mode 100755 index 0000000..c2fdad5 Binary files /dev/null and b/static/app2/img/menu.png differ diff --git a/static/app2/img/menu_dian.png b/static/app2/img/menu_dian.png new file mode 100755 index 0000000..d5b22cb Binary files /dev/null and b/static/app2/img/menu_dian.png differ diff --git a/static/app2/img/miaoshabg.png b/static/app2/img/miaoshabg.png new file mode 100755 index 0000000..9cbbc67 Binary files /dev/null and b/static/app2/img/miaoshabg.png differ diff --git a/static/app2/img/my_bg.png b/static/app2/img/my_bg.png new file mode 100755 index 0000000..b295676 Binary files /dev/null and b/static/app2/img/my_bg.png differ diff --git a/static/app2/img/nav_0_0.png b/static/app2/img/nav_0_0.png new file mode 100755 index 0000000..ff1d2ef Binary files /dev/null and b/static/app2/img/nav_0_0.png differ diff --git a/static/app2/img/nav_0_1.png b/static/app2/img/nav_0_1.png new file mode 100755 index 0000000..025db46 Binary files /dev/null and b/static/app2/img/nav_0_1.png differ diff --git a/static/app2/img/nav_1_0.png b/static/app2/img/nav_1_0.png new file mode 100755 index 0000000..c3cc95c Binary files /dev/null and b/static/app2/img/nav_1_0.png differ diff --git a/static/app2/img/nav_1_1.png b/static/app2/img/nav_1_1.png new file mode 100755 index 0000000..d6dac4d Binary files /dev/null and b/static/app2/img/nav_1_1.png differ diff --git a/static/app2/img/nav_3_0.png b/static/app2/img/nav_3_0.png new file mode 100755 index 0000000..db8e426 Binary files /dev/null and b/static/app2/img/nav_3_0.png differ diff --git a/static/app2/img/nav_3_1.png b/static/app2/img/nav_3_1.png new file mode 100755 index 0000000..49500d9 Binary files /dev/null and b/static/app2/img/nav_3_1.png differ diff --git a/static/app2/img/nav_4_0.png b/static/app2/img/nav_4_0.png new file mode 100755 index 0000000..51456a4 Binary files /dev/null and b/static/app2/img/nav_4_0.png differ diff --git a/static/app2/img/nav_4_1.png b/static/app2/img/nav_4_1.png new file mode 100755 index 0000000..7a403ff Binary files /dev/null and b/static/app2/img/nav_4_1.png differ diff --git a/static/app2/img/order-icons.png b/static/app2/img/order-icons.png new file mode 100755 index 0000000..6c083df Binary files /dev/null and b/static/app2/img/order-icons.png differ diff --git a/static/app2/img/paihangbang.png b/static/app2/img/paihangbang.png new file mode 100755 index 0000000..30b6be5 Binary files /dev/null and b/static/app2/img/paihangbang.png differ diff --git a/static/app2/img/phone1.png b/static/app2/img/phone1.png new file mode 100755 index 0000000..66bf91e Binary files /dev/null and b/static/app2/img/phone1.png differ diff --git a/static/app2/img/pingpaijie.png b/static/app2/img/pingpaijie.png new file mode 100755 index 0000000..332b37f Binary files /dev/null and b/static/app2/img/pingpaijie.png differ diff --git a/static/app2/img/pinzhishishang.png b/static/app2/img/pinzhishishang.png new file mode 100755 index 0000000..f2013d1 Binary files /dev/null and b/static/app2/img/pinzhishishang.png differ diff --git a/static/app2/img/pjhx.png b/static/app2/img/pjhx.png new file mode 100755 index 0000000..77b8f7c Binary files /dev/null and b/static/app2/img/pjhx.png differ diff --git a/static/app2/img/pjhx1.png b/static/app2/img/pjhx1.png new file mode 100755 index 0000000..0e88ee8 Binary files /dev/null and b/static/app2/img/pjhx1.png differ diff --git a/static/app2/img/pjimg.png b/static/app2/img/pjimg.png new file mode 100755 index 0000000..2c322cf Binary files /dev/null and b/static/app2/img/pjimg.png differ diff --git a/static/app2/img/sanjiaoshang.png b/static/app2/img/sanjiaoshang.png new file mode 100755 index 0000000..4a2fd37 Binary files /dev/null and b/static/app2/img/sanjiaoshang.png differ diff --git a/static/app2/img/sanjiaoxia.png b/static/app2/img/sanjiaoxia.png new file mode 100755 index 0000000..72b9284 Binary files /dev/null and b/static/app2/img/sanjiaoxia.png differ diff --git a/static/app2/img/saoyisao.png b/static/app2/img/saoyisao.png new file mode 100755 index 0000000..c14f6da Binary files /dev/null and b/static/app2/img/saoyisao.png differ diff --git a/static/app2/img/search1.png b/static/app2/img/search1.png new file mode 100755 index 0000000..ef4f42c Binary files /dev/null and b/static/app2/img/search1.png differ diff --git a/static/app2/img/setting_lock1.png b/static/app2/img/setting_lock1.png new file mode 100755 index 0000000..d8bd133 Binary files /dev/null and b/static/app2/img/setting_lock1.png differ diff --git a/static/app2/img/setting_user1.png b/static/app2/img/setting_user1.png new file mode 100755 index 0000000..3b993b2 Binary files /dev/null and b/static/app2/img/setting_user1.png differ diff --git a/static/app2/img/shan.png b/static/app2/img/shan.png new file mode 100755 index 0000000..e9d44c5 Binary files /dev/null and b/static/app2/img/shan.png differ diff --git a/static/app2/img/shan1.png b/static/app2/img/shan1.png new file mode 100755 index 0000000..6bb2885 Binary files /dev/null and b/static/app2/img/shan1.png differ diff --git a/static/app2/img/shangxin.png b/static/app2/img/shangxin.png new file mode 100755 index 0000000..3235ea8 Binary files /dev/null and b/static/app2/img/shangxin.png differ diff --git a/static/app2/img/shaung11jianianhua.png b/static/app2/img/shaung11jianianhua.png new file mode 100755 index 0000000..0ae84f6 Binary files /dev/null and b/static/app2/img/shaung11jianianhua.png differ diff --git a/static/app2/img/shop.png b/static/app2/img/shop.png new file mode 100755 index 0000000..b8d2015 Binary files /dev/null and b/static/app2/img/shop.png differ diff --git a/static/app2/img/shop2.png b/static/app2/img/shop2.png new file mode 100755 index 0000000..07a23dc Binary files /dev/null and b/static/app2/img/shop2.png differ diff --git a/static/app2/img/shoplogo.png b/static/app2/img/shoplogo.png new file mode 100755 index 0000000..f2bfc4a Binary files /dev/null and b/static/app2/img/shoplogo.png differ diff --git a/static/app2/img/sousuo.png b/static/app2/img/sousuo.png new file mode 100755 index 0000000..873650f Binary files /dev/null and b/static/app2/img/sousuo.png differ diff --git a/static/app2/img/store_home.png b/static/app2/img/store_home.png new file mode 100755 index 0000000..692a96a Binary files /dev/null and b/static/app2/img/store_home.png differ diff --git a/static/app2/img/store_home_on.png b/static/app2/img/store_home_on.png new file mode 100755 index 0000000..a4ac550 Binary files /dev/null and b/static/app2/img/store_home_on.png differ diff --git a/static/app2/img/store_huodong.png b/static/app2/img/store_huodong.png new file mode 100755 index 0000000..274171c Binary files /dev/null and b/static/app2/img/store_huodong.png differ diff --git a/static/app2/img/store_huodong_on.png b/static/app2/img/store_huodong_on.png new file mode 100755 index 0000000..7b12569 Binary files /dev/null and b/static/app2/img/store_huodong_on.png differ diff --git a/static/app2/img/store_shangpin.png b/static/app2/img/store_shangpin.png new file mode 100755 index 0000000..d381997 Binary files /dev/null and b/static/app2/img/store_shangpin.png differ diff --git a/static/app2/img/store_shangpin_on.png b/static/app2/img/store_shangpin_on.png new file mode 100755 index 0000000..1238fc6 Binary files /dev/null and b/static/app2/img/store_shangpin_on.png differ diff --git a/static/app2/img/store_shangxin.png b/static/app2/img/store_shangxin.png new file mode 100755 index 0000000..9f36adc Binary files /dev/null and b/static/app2/img/store_shangxin.png differ diff --git a/static/app2/img/store_shangxin_on.png b/static/app2/img/store_shangxin_on.png new file mode 100755 index 0000000..e36a53a Binary files /dev/null and b/static/app2/img/store_shangxin_on.png differ diff --git a/static/app2/img/storetopbg.png b/static/app2/img/storetopbg.png new file mode 100755 index 0000000..cd40dfb Binary files /dev/null and b/static/app2/img/storetopbg.png differ diff --git a/static/app2/img/thq_bg.png b/static/app2/img/thq_bg.png new file mode 100755 index 0000000..8afde13 Binary files /dev/null and b/static/app2/img/thq_bg.png differ diff --git a/static/app2/img/time_limit.png b/static/app2/img/time_limit.png new file mode 100755 index 0000000..3e03d02 Binary files /dev/null and b/static/app2/img/time_limit.png differ diff --git a/static/app2/img/tuijianbaokuan1.png b/static/app2/img/tuijianbaokuan1.png new file mode 100755 index 0000000..31e4c08 Binary files /dev/null and b/static/app2/img/tuijianbaokuan1.png differ diff --git a/static/app2/img/xianshiqianggou.png b/static/app2/img/xianshiqianggou.png new file mode 100755 index 0000000..a54828e Binary files /dev/null and b/static/app2/img/xianshiqianggou.png differ diff --git a/static/app2/img/xianshitehui.png b/static/app2/img/xianshitehui.png new file mode 100755 index 0000000..77bbf58 Binary files /dev/null and b/static/app2/img/xianshitehui.png differ diff --git a/static/app2/img/xinpinshangshi1.png b/static/app2/img/xinpinshangshi1.png new file mode 100755 index 0000000..d7f5e62 Binary files /dev/null and b/static/app2/img/xinpinshangshi1.png differ diff --git a/static/app2/img/xinpinshoufa.png b/static/app2/img/xinpinshoufa.png new file mode 100755 index 0000000..c9e087f Binary files /dev/null and b/static/app2/img/xinpinshoufa.png differ diff --git a/static/app2/img/xpss_bg.png b/static/app2/img/xpss_bg.png new file mode 100755 index 0000000..5125ee7 Binary files /dev/null and b/static/app2/img/xpss_bg.png differ diff --git a/static/app2/img/youhaohuo.png b/static/app2/img/youhaohuo.png new file mode 100755 index 0000000..86fe591 Binary files /dev/null and b/static/app2/img/youhaohuo.png differ diff --git a/static/app2/img/youhuiquan1.png b/static/app2/img/youhuiquan1.png new file mode 100755 index 0000000..4f39a18 Binary files /dev/null and b/static/app2/img/youhuiquan1.png differ diff --git a/static/app2/img/youhuiquan2.png b/static/app2/img/youhuiquan2.png new file mode 100755 index 0000000..50c6be2 Binary files /dev/null and b/static/app2/img/youhuiquan2.png differ diff --git a/static/app2/img/youjiantou.png b/static/app2/img/youjiantou.png new file mode 100755 index 0000000..1976dc6 Binary files /dev/null and b/static/app2/img/youjiantou.png differ diff --git a/static/app2/img/yuan.png b/static/app2/img/yuan.png new file mode 100755 index 0000000..1c7423f Binary files /dev/null and b/static/app2/img/yuan.png differ diff --git a/static/app2/img/zan1.png b/static/app2/img/zan1.png new file mode 100755 index 0000000..54ed64e Binary files /dev/null and b/static/app2/img/zan1.png differ diff --git a/static/app2/img/zan2.png b/static/app2/img/zan2.png new file mode 100755 index 0000000..a58019d Binary files /dev/null and b/static/app2/img/zan2.png differ diff --git a/static/app2/img/zdzb2_bg.png b/static/app2/img/zdzb2_bg.png new file mode 100755 index 0000000..c3e1053 Binary files /dev/null and b/static/app2/img/zdzb2_bg.png differ diff --git a/static/app2/js/1.js b/static/app2/js/1.js new file mode 100755 index 0000000..e0fe13a --- /dev/null +++ b/static/app2/js/1.js @@ -0,0 +1,4879 @@ +! +function(t) { + function e(r) { + if (n[r]) return n[r].exports; + var i = n[r] = { + i: r, + l: !1, + exports: {} + }; + return t[r].call(i.exports, i, i.exports, e), + i.l = !0, + i.exports + } + var n = {}; + e.m = t, + e.c = n, + e.d = function(t, n, r) { + e.o(t, n) || Object.defineProperty(t, n, { + configurable: !1, + enumerable: !0, + get: r + }) + }, + e.n = function(t) { + var n = t && t.__esModule ? + function() { + return t. + default + }: + function() { + return t + }; + return e.d(n, "a", n), + n + }, + e.o = function(t, e) { + return Object.prototype.hasOwnProperty.call(t, e) + }, + e.p = "//wq.360buyimg.com/wxsq_project/portal/m_jd_index/", + e(e.s = 43) +} ([function(t, e) { + var n = t.exports = "undefined" != typeof window && window.Math == Math ? window: "undefined" != typeof self && self.Math == Math ? self: Function("return this")(); + "number" == typeof __g && (__g = n) +}, +function(t, e) { + var n = t.exports = { + version: "2.5.7" + }; + "number" == typeof __e && (__e = n) +}, +function(t, e) { + var n = {}.hasOwnProperty; + t.exports = function(t, e) { + return n.call(t, e) + } +}, +function(t, e, n) { + var r = n(4), + i = n(13); + t.exports = n(5) ? + function(t, e, n) { + return r.f(t, e, i(1, n)) + }: function(t, e, n) { + return t[e] = n, + t + } +}, +function(t, e, n) { + var r = n(12), + i = n(31), + o = n(19), + a = Object.defineProperty; + e.f = n(5) ? Object.defineProperty: function(t, e, n) { + if (r(t), e = o(e, !0), r(n), i) try { + return a(t, e, n) + } catch(t) {} + if ("get" in n || "set" in n) throw TypeError("Accessors not supported!"); + return "value" in n && (t[e] = n.value), + t + } +}, +function(t, e, n) { + t.exports = !n(9)(function() { + return 7 != Object.defineProperty({}, + "a", { + get: function() { + return 7 + } + }).a + }) +}, +function(t, e, n) { + var r = n(53), + i = n(17); + t.exports = function(t) { + return r(i(t)) + } +}, +function(t, e, n) { + var r = n(23)("wks"), + i = n(14), + o = n(0).Symbol, + a = "function" == typeof o; (t.exports = function(t) { + return r[t] || (r[t] = a && o[t] || (a ? o: i)("Symbol." + t)) + }).store = r +}, +function(t, e) { + t.exports = function(t) { + return "object" == typeof t ? null !== t: "function" == typeof t + } +}, +function(t, e) { + t.exports = function(t) { + try { + return !! t() + } catch(t) { + return ! 0 + } + } +}, +function(t, e, n) { + "use strict"; + function r(t) { + return t && t.__esModule ? t: { + default: + t + } + } + e.__esModule = !0; + var i = n(45), + o = r(i), + a = n(62), + s = r(a), + c = "function" == typeof s. +default && "symbol" == typeof o. +default ? + function(t) { + return typeof t + }: function(t) { + return t && "function" == typeof s. + default && t.constructor === s. + default && t !== s. + default.prototype ? "symbol": typeof t + }; + e. +default = "function" == typeof s. +default && "symbol" === c(o. +default) ? + function(t) { + return void 0 === t ? "undefined": c(t) + }: function(t) { + return t && "function" == typeof s. + default && t.constructor === s. + default && t !== s. + default.prototype ? "symbol": void 0 === t ? "undefined": c(t) + } +}, +function(t, e) { + t.exports = !0 +}, +function(t, e, n) { + var r = n(8); + t.exports = function(t) { + if (!r(t)) throw TypeError(t + " is not an object!"); + return t + } +}, +function(t, e) { + t.exports = function(t, e) { + return { + enumerable: !(1 & t), + configurable: !(2 & t), + writable: !(4 & t), + value: e + } + } +}, +function(t, e) { + var n = 0, + r = Math.random(); + t.exports = function(t) { + return "Symbol(".concat(void 0 === t ? "": t, ")_", (++n + r).toString(36)) + } +}, +function(t, e, n) { + "use strict"; + function r(t) { + return t && t.__esModule ? t: { + default: + t + } + } + var i = n(10), + o = r(i), + a = n(41), + s = r(a), + c = function() { + function t(t) { + return null == t ? String(t) : Y[K.call(t)] || "object" + } + function e(e) { + return "function" == t(e) + } + function n(t) { + return null != t && t == t.window + } + function r(t) { + return null != t && t.nodeType == t.DOCUMENT_NODE + } + function i(e) { + return "object" == t(e) + } + function a(t) { + return i(t) && !n(t) && (0, s. + default)(t) == Object.prototype + } + function c(t) { + var e = !!t && "length" in t && t.length, + r = S.type(t); + return "function" != r && !n(t) && ("array" == r || 0 === e || "number" == typeof e && e > 0 && e - 1 in t) + } + function u(t) { + return M.call(t, + function(t) { + return null != t + }) + } + function l(t) { + return t.length > 0 ? S.fn.concat.apply([], t) : t + } + function f(t) { + return t.replace(/::/g, "/").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/([a-z\d])([A-Z])/g, "$1_$2").replace(/_/g, "-").toLowerCase() + } + function p(t) { + return t in N ? N[t] : N[t] = new RegExp("(^|\\s)" + t + "(\\s|$)") + } + function h(t, e) { + return "number" != typeof e || F[f(t)] ? e: e + "px" + } + function d(t) { + var e, n; + return L[t] || (e = A.createElement(t), A.body.appendChild(e), n = getComputedStyle(e, "").getPropertyValue("display"), e.parentNode.removeChild(e), "none" == n && (n = "block"), L[t] = n), + L[t] + } + function m(t) { + return "children" in t ? P.call(t.children) : S.map(t.childNodes, + function(t) { + if (1 == t.nodeType) return t + }) + } + function v(t, e) { + var n, r = t ? t.length: 0; + for (n = 0; n < r; n++) this[n] = t[n]; + this.length = r, + this.selector = e || "" + } + function g(t, e, n) { + for (k in e) n && (a(e[k]) || et(e[k])) ? (a(e[k]) && !a(t[k]) && (t[k] = {}), et(e[k]) && !et(t[k]) && (t[k] = []), g(t[k], e[k], n)) : e[k] !== T && (t[k] = e[k]) + } + function y(t, e) { + return null == e ? S(t) : S(t).filter(e) + } + function w(t, n, r, i) { + return e(n) ? n.call(t, r, i) : n + } + function b(t, e, n) { + null == n ? t.removeAttribute(e) : t.setAttribute(e, n) + } + function _(t, e) { + var n = t.className || "", + r = n && n.baseVal !== T; + if (e === T) return r ? n.baseVal: n; + r ? n.baseVal = e: t.className = e + } + function x(t) { + try { + return t ? "true" == t || "false" != t && ("null" == t ? null: +t + "" == t ? +t: /^[\[\{]/.test(t) ? S.parseJSON(t) : t) : t + } catch(e) { + return t + } + } + function j(t, e) { + e(t); + for (var n = 0, + r = t.childNodes.length; n < r; n++) j(t.childNodes[n], e) + } + var T, k, S, E, C, O, D = [], + I = D.concat, + M = D.filter, + P = D.slice, + A = window.document, + L = {}, + N = {}, + F = { + "column-count": 1, + columns: 1, + "font-weight": 1, + "line-height": 1, + opacity: 1, + "z-index": 1, + zoom: 1 + }, + R = /^\s*<(\w+|!)[^>]*>/, + q = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + J = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + $ = /^(?:body|html)$/i, + U = /([A-Z])/g, + B = ["val", "css", "html", "text", "data", "width", "height", "offset"], + H = ["after", "prepend", "before", "append"], + W = A.createElement("table"), + z = A.createElement("tr"), + V = { + tr: A.createElement("tbody"), + tbody: W, + thead: W, + tfoot: W, + td: z, + th: z, + "*": A.createElement("div") + }, + G = /complete|loaded|interactive/, + X = /^[\w-]*$/, + Y = {}, + K = Y.toString, + Z = {}, + Q = A.createElement("div"), + tt = { + tabindex: "tabIndex", + readonly: "readOnly", + for: "htmlFor", + class: "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + et = Array.isArray || + function(t) { + return t instanceof Array + }; + return Z.matches = function(t, e) { + if (!e || !t || 1 !== t.nodeType) return ! 1; + var n = t.matches || t.webkitMatchesSelector || t.mozMatchesSelector || t.oMatchesSelector || t.matchesSelector; + if (n) return n.call(t, e); + var r, i = t.parentNode, + o = !i; + return o && (i = Q).appendChild(t), + r = ~Z.qsa(i, e).indexOf(t), + o && Q.removeChild(t), + r + }, + C = function(t) { + return t.replace(/-+(.)?/g, + function(t, e) { + return e ? e.toUpperCase() : "" + }) + }, + O = function(t) { + return M.call(t, + function(e, n) { + return t.indexOf(e) == n + }) + }, + Z.fragment = function(t, e, n) { + var r, i, o; + return q.test(t) && (r = S(A.createElement(RegExp.$1))), + r || (t.replace && (t = t.replace(J, "<$1></$2>")), e === T && (e = R.test(t) && RegExp.$1), e in V || (e = "*"), o = V[e], o.innerHTML = "" + t, r = S.each(P.call(o.childNodes), + function() { + o.removeChild(this) + })), + a(n) && (i = S(r), S.each(n, + function(t, e) { + B.indexOf(t) > -1 ? i[t](e) : i.attr(t, e) + })), + r + }, + Z.Z = function(t, e) { + return new v(t, e) + }, + Z.isZ = function(t) { + return t instanceof Z.Z + }, + Z.init = function(t, n) { + var r; + if (!t) return Z.Z(); + if ("string" == typeof t) if (t = t.trim(), "<" == t[0] && R.test(t)) r = Z.fragment(t, RegExp.$1, n), + t = null; + else { + if (n !== T) return S(n).find(t); + r = Z.qsa(A, t) + } else { + if (e(t)) return S(A).ready(t); + if (Z.isZ(t)) return t; + if (et(t)) r = u(t); + else if (i(t)) r = [t], + t = null; + else if (R.test(t)) r = Z.fragment(t.trim(), RegExp.$1, n), + t = null; + else { + if (n !== T) return S(n).find(t); + r = Z.qsa(A, t) + } + } + return Z.Z(r, t) + }, + S = function(t, e) { + return Z.init(t, e) + }, + S.extend = function(t) { + var e, n = P.call(arguments, 1); + return "boolean" == typeof t && (e = t, t = n.shift()), + n.forEach(function(n) { + g(t, n, e) + }), + t + }, + Z.qsa = function(t, e) { + var n, r = "#" == e[0], + i = !r && "." == e[0], + o = r || i ? e.slice(1) : e, + a = X.test(o); + return t.getElementById && a && r ? (n = t.getElementById(o)) ? [n] : [] : 1 !== t.nodeType && 9 !== t.nodeType && 11 !== t.nodeType ? [] : P.call(a && !r && t.getElementsByClassName ? i ? t.getElementsByClassName(o) : t.getElementsByTagName(e) : t.querySelectorAll(e)) + }, + S.contains = A.documentElement.contains ? + function(t, e) { + return t !== e && t.contains(e) + }: function(t, e) { + for (; e && (e = e.parentNode);) if (e === t) return ! 0; + return ! 1 + }, + S.type = t, + S.isFunction = e, + S.isWindow = n, + S.isArray = et, + S.isPlainObject = a, + S.isEmptyObject = function(t) { + var e; + for (e in t) return ! 1; + return ! 0 + }, + S.isNumeric = function(t) { + var e = Number(t), + n = void 0 === t ? "undefined": (0, o. + default)(t); + return null != t && "boolean" != n && ("string" != n || t.length) && !isNaN(e) && isFinite(e) || !1 + }, + S.inArray = function(t, e, n) { + return D.indexOf.call(e, t, n) + }, + S.camelCase = C, + S.trim = function(t) { + return null == t ? "": String.prototype.trim.call(t) + }, + S.uuid = 0, + S.support = {}, + S.expr = {}, + S.noop = function() {}, + S.map = function(t, e) { + var n, r, i, o = []; + if (c(t)) for (r = 0; r < t.length; r++) null != (n = e(t[r], r)) && o.push(n); + else for (i in t) null != (n = e(t[i], i)) && o.push(n); + return l(o) + }, + S.each = function(t, e) { + var n, r; + if (c(t)) { + for (n = 0; n < t.length; n++) if (!1 === e.call(t[n], n, t[n])) return t + } else for (r in t) if (!1 === e.call(t[r], r, t[r])) return t; + return t + }, + S.grep = function(t, e) { + return M.call(t, e) + }, + window.JSON && (S.parseJSON = JSON.parse), + S.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), + function(t, e) { + Y["[object " + e + "]"] = e.toLowerCase() + }), + S.fn = { + constructor: Z.Z, + length: 0, + forEach: D.forEach, + reduce: D.reduce, + push: D.push, + sort: D.sort, + splice: D.splice, + indexOf: D.indexOf, + concat: function() { + var t, e, n = []; + for (t = 0; t < arguments.length; t++) e = arguments[t], + n[t] = Z.isZ(e) ? e.toArray() : e; + return I.apply(Z.isZ(this) ? this.toArray() : this, n) + }, + map: function(t) { + return S(S.map(this, + function(e, n) { + return t.call(e, n, e) + })) + }, + slice: function() { + return S(P.apply(this, arguments)) + }, + ready: function(t) { + return G.test(A.readyState) && A.body ? t(S) : A.addEventListener("DOMContentLoaded", + function() { + t(S) + }, + !1), + this + }, + get: function(t) { + return t === T ? P.call(this) : this[t >= 0 ? t: t + this.length] + }, + toArray: function() { + return this.get() + }, + size: function() { + return this.length + }, + remove: function() { + return this.each(function() { + null != this.parentNode && this.parentNode.removeChild(this) + }) + }, + each: function(t) { + return D.every.call(this, + function(e, n) { + return ! 1 !== t.call(e, n, e) + }), + this + }, + filter: function(t) { + return e(t) ? this.not(this.not(t)) : S(M.call(this, + function(e) { + return Z.matches(e, t) + })) + }, + add: function(t, e) { + return S(O(this.concat(S(t, e)))) + }, + is: function(t) { + return this.length > 0 && Z.matches(this[0], t) + }, + not: function(t) { + var n = []; + if (e(t) && t.call !== T) this.each(function(e) { + t.call(this, e) || n.push(this) + }); + else { + var r = "string" == typeof t ? this.filter(t) : c(t) && e(t.item) ? P.call(t) : S(t); + this.forEach(function(t) { + r.indexOf(t) < 0 && n.push(t) + }) + } + return S(n) + }, + has: function(t) { + return this.filter(function() { + return i(t) ? S.contains(this, t) : S(this).find(t).size() + }) + }, + eq: function(t) { + return - 1 === t ? this.slice(t) : this.slice(t, +t + 1) + }, + first: function() { + var t = this[0]; + return t && !i(t) ? t: S(t) + }, + last: function() { + var t = this[this.length - 1]; + return t && !i(t) ? t: S(t) + }, + find: function(t) { + var e = this; + return t ? "object" == (void 0 === t ? "undefined": (0, o. + default)(t)) ? S(t).filter(function() { + var t = this; + return D.some.call(e, + function(e) { + return S.contains(e, t) + }) + }) : 1 == this.length ? S(Z.qsa(this[0], t)) : this.map(function() { + return Z.qsa(this, t) + }) : S() + }, + closest: function(t, e) { + var n = [], + i = "object" == (void 0 === t ? "undefined": (0, o. + default)(t)) && S(t); + return this.each(function(o, a) { + for (; a && !(i ? i.indexOf(a) >= 0 : Z.matches(a, t));) a = a !== e && !r(a) && a.parentNode; + a && n.indexOf(a) < 0 && n.push(a) + }), + S(n) + }, + parents: function(t) { + for (var e = [], n = this; n.length > 0;) n = S.map(n, + function(t) { + if ((t = t.parentNode) && !r(t) && e.indexOf(t) < 0) return e.push(t), + t + }); + return y(e, t) + }, + parent: function(t) { + return y(O(this.pluck("parentNode")), t) + }, + children: function(t) { + return y(this.map(function() { + return m(this) + }), t) + }, + contents: function() { + return this.map(function() { + return this.contentDocument || P.call(this.childNodes) + }) + }, + siblings: function(t) { + return y(this.map(function(t, e) { + return M.call(m(e.parentNode), + function(t) { + return t !== e + }) + }), t) + }, + empty: function() { + return this.each(function() { + this.innerHTML = "" + }) + }, + pluck: function(t) { + return S.map(this, + function(e) { + return e[t] + }) + }, + show: function() { + return this.each(function() { + "none" == this.style.display && (this.style.display = ""), + "none" == getComputedStyle(this, "").getPropertyValue("display") && (this.style.display = d(this.nodeName)) + }) + }, + replaceWith: function(t) { + return this.before(t).remove() + }, + wrap: function(t) { + var n = e(t); + if (this[0] && !n) var r = S(t).get(0), + i = r.parentNode || this.length > 1; + return this.each(function(e) { + S(this).wrapAll(n ? t.call(this, e) : i ? r.cloneNode(!0) : r) + }) + }, + wrapAll: function(t) { + if (this[0]) { + S(this[0]).before(t = S(t)); + for (var e; (e = t.children()).length;) t = e.first(); + S(t).append(this) + } + return this + }, + wrapInner: function(t) { + var n = e(t); + return this.each(function(e) { + var r = S(this), + i = r.contents(), + o = n ? t.call(this, e) : t; + i.length ? i.wrapAll(o) : r.append(o) + }) + }, + unwrap: function() { + return this.parent().each(function() { + S(this).replaceWith(S(this).children()) + }), + this + }, + clone: function() { + return this.map(function() { + return this.cloneNode(!0) + }) + }, + hide: function() { + return this.css("display", "none") + }, + toggle: function(t) { + return this.each(function() { + var e = S(this); (t === T ? "none" == e.css("display") : t) ? e.show() : e.hide() + }) + }, + prev: function(t) { + return S(this.pluck("previousElementSibling")).filter(t || "*") + }, + next: function(t) { + return S(this.pluck("nextElementSibling")).filter(t || "*") + }, + html: function(t) { + return 0 in arguments ? this.each(function(e) { + var n = this.innerHTML; + S(this).empty().append(w(this, t, e, n)) + }) : 0 in this ? this[0].innerHTML: null + }, + text: function(t) { + return 0 in arguments ? this.each(function(e) { + var n = w(this, t, e, this.textContent); + this.textContent = null == n ? "": "" + n + }) : 0 in this ? this.pluck("textContent").join("") : null + }, + attr: function(t, e) { + var n; + return "string" != typeof t || 1 in arguments ? this.each(function(n) { + if (1 === this.nodeType) if (i(t)) for (k in t) b(this, k, t[k]); + else b(this, t, w(this, e, n, this.getAttribute(t))) + }) : 0 in this && 1 == this[0].nodeType && null != (n = this[0].getAttribute(t)) ? n: T + }, + removeAttr: function(t) { + return this.each(function() { + 1 === this.nodeType && t.split(" ").forEach(function(t) { + b(this, t) + }, + this) + }) + }, + prop: function(t, e) { + return t = tt[t] || t, + 1 in arguments ? this.each(function(n) { + this[t] = w(this, e, n, this[t]) + }) : this[0] && this[0][t] + }, + removeProp: function(t) { + return t = tt[t] || t, + this.each(function() { + delete this[t] + }) + }, + data: function(t, e) { + var n = "data-" + t.replace(U, "-$1").toLowerCase(), + r = 1 in arguments ? this.attr(n, e) : this.attr(n); + return null !== r ? x(r) : T + }, + val: function(t) { + return 0 in arguments ? (null == t && (t = ""), this.each(function(e) { + this.value = w(this, t, e, this.value) + })) : this[0] && (this[0].multiple ? S(this[0]).find("option").filter(function() { + return this.selected + }).pluck("value") : this[0].value) + }, + offset: function(t) { + if (t) return this.each(function(e) { + var n = S(this), + r = w(this, t, e, n.offset()), + i = n.offsetParent().offset(), + o = { + top: r.top - i.top, + left: r.left - i.left + }; + "static" == n.css("position") && (o.position = "relative"), + n.css(o) + }); + if (!this.length) return null; + if (A.documentElement !== this[0] && !S.contains(A.documentElement, this[0])) return { + top: 0, + left: 0 + }; + var e = this[0].getBoundingClientRect(); + return { + left: e.left + window.pageXOffset, + top: e.top + window.pageYOffset, + width: Math.round(e.width), + height: Math.round(e.height) + } + }, + css: function(e, n) { + if (arguments.length < 2) { + var r = this[0]; + if ("string" == typeof e) { + if (!r) return; + return r.style[C(e)] || getComputedStyle(r, "").getPropertyValue(e) + } + if (et(e)) { + if (!r) return; + var i = {}, + o = getComputedStyle(r, ""); + return S.each(e, + function(t, e) { + i[e] = r.style[C(e)] || o.getPropertyValue(e) + }), + i + } + } + var a = ""; + if ("string" == t(e)) n || 0 === n ? a = f(e) + ":" + h(e, n) : this.each(function() { + this.style.removeProperty(f(e)) + }); + else for (k in e) e[k] || 0 === e[k] ? a += f(k) + ":" + h(k, e[k]) + ";": this.each(function() { + this.style.removeProperty(f(k)) + }); + return this.each(function() { + this.style.cssText += ";" + a + }) + }, + index: function(t) { + return t ? this.indexOf(S(t)[0]) : this.parent().children().indexOf(this[0]) + }, + hasClass: function(t) { + return !! t && D.some.call(this, + function(t) { + return this.test(_(t)) + }, + p(t)) + }, + addClass: function(t) { + return t ? this.each(function(e) { + if ("className" in this) { + E = []; + var n = _(this); + w(this, t, e, n).split(/\s+/g).forEach(function(t) { + S(this).hasClass(t) || E.push(t) + }, + this), + E.length && _(this, n + (n ? " ": "") + E.join(" ")) + } + }) : this + }, + removeClass: function(t) { + return this.each(function(e) { + if ("className" in this) { + if (t === T) return _(this, ""); + E = _(this), + w(this, t, e, E).split(/\s+/g).forEach(function(t) { + E = E.replace(p(t), " ") + }), + _(this, E.trim()) + } + }) + }, + toggleClass: function(t, e) { + return t ? this.each(function(n) { + var r = S(this); + w(this, t, n, _(this)).split(/\s+/g).forEach(function(t) { (e === T ? !r.hasClass(t) : e) ? r.addClass(t) : r.removeClass(t) + }) + }) : this + }, + scrollTop: function(t) { + if (this.length) { + var e = "scrollTop" in this[0]; + return t === T ? e ? this[0].scrollTop: this[0].pageYOffset: this.each(e ? + function() { + this.scrollTop = t + }: function() { + this.scrollTo(this.scrollX, t) + }) + } + }, + scrollLeft: function(t) { + if (this.length) { + var e = "scrollLeft" in this[0]; + return t === T ? e ? this[0].scrollLeft: this[0].pageXOffset: this.each(e ? + function() { + this.scrollLeft = t + }: function() { + this.scrollTo(t, this.scrollY) + }) + } + }, + position: function() { + if (this.length) { + var t = this[0], + e = this.offsetParent(), + n = this.offset(), + r = $.test(e[0].nodeName) ? { + top: 0, + left: 0 + }: e.offset(); + return n.top -= parseFloat(S(t).css("margin-top")) || 0, + n.left -= parseFloat(S(t).css("margin-left")) || 0, + r.top += parseFloat(S(e[0]).css("border-top-width")) || 0, + r.left += parseFloat(S(e[0]).css("border-left-width")) || 0, + { + top: n.top - r.top, + left: n.left - r.left + } + } + }, + offsetParent: function() { + return this.map(function() { + for (var t = this.offsetParent || A.body; t && !$.test(t.nodeName) && "static" == S(t).css("position");) t = t.offsetParent; + return t + }) + } + }, + S.fn.detach = S.fn.remove, + ["width", "height"].forEach(function(t) { + var e = t.replace(/./, + function(t) { + return t[0].toUpperCase() + }); + S.fn[t] = function(i) { + var o, a = this[0]; + return i === T ? n(a) ? a["inner" + e] : r(a) ? a.documentElement["scroll" + e] : (o = this.offset()) && o[t] : this.each(function(e) { + a = S(this), + a.css(t, w(this, i, e, a[t]())) + }) + } + }), + H.forEach(function(e, n) { + var r = n % 2; + S.fn[e] = function() { + var e, i, o = S.map(arguments, + function(n) { + var r = []; + return e = t(n), + "array" == e ? (n.forEach(function(t) { + return t.nodeType !== T ? r.push(t) : S.zepto.isZ(t) ? r = r.concat(t.get()) : void(r = r.concat(Z.fragment(t))) + }), r) : "object" == e || null == n ? n: Z.fragment(n) + }), + a = this.length > 1; + return o.length < 1 ? this: this.each(function(t, e) { + i = r ? e: e.parentNode, + e = 0 == n ? e.nextSibling: 1 == n ? e.firstChild: 2 == n ? e: null; + var s = S.contains(A.documentElement, i); + o.forEach(function(t) { + if (a) t = t.cloneNode(!0); + else if (!i) return S(t).remove(); + i.insertBefore(t, e), + s && j(t, + function(t) { + if (! (null == t.nodeName || "SCRIPT" !== t.nodeName.toUpperCase() || t.type && "text/javascript" !== t.type || t.src)) { + var e = t.ownerDocument ? t.ownerDocument.defaultView: window; + e.eval.call(e, t.innerHTML) + } + }) + }) + }) + }, + S.fn[r ? e + "To": "insert" + (n ? "Before": "After")] = function(t) { + return S(t)[e](this), + this + } + }), + Z.Z.prototype = v.prototype = S.fn, + Z.uniq = O, + Z.deserializeValue = x, + S.zepto = Z, + S + } (); + window.Zepto = c, + void 0 === window.$ && (window.$ = c), + function(t) { + function e(t) { + return t._zid || (t._zid = p++) + } + function n(t, n, o, a) { + if (n = r(n), n.ns) var s = i(n.ns); + return (v[e(t)] || []).filter(function(t) { + return t && (!n.e || t.e == n.e) && (!n.ns || s.test(t.ns)) && (!o || e(t.fn) === e(o)) && (!a || t.sel == a) + }) + } + function r(t) { + var e = ("" + t).split("."); + return { + e: e[0], + ns: e.slice(1).sort().join(" ") + } + } + function i(t) { + return new RegExp("(?:^| )" + t.replace(" ", " .* ?") + "(?: |$)") + } + function o(t, e) { + return t.del && !y && t.e in w || !!e + } + function a(t) { + return b[t] || y && w[t] || t + } + function s(n, i, s, c, l, p, h) { + var d = e(n), + m = v[d] || (v[d] = []); + i.split(/\s/).forEach(function(e) { + if ("ready" == e) return t(document).ready(s); + var i = r(e); + i.fn = s, + i.sel = l, + i.e in b && (s = function(e) { + var n = e.relatedTarget; + if (!n || n !== this && !t.contains(this, n)) return i.fn.apply(this, arguments) + }), + i.del = p; + var d = p || s; + i.proxy = function(t) { + if (t = u(t), !t.isImmediatePropagationStopped()) { + try { + t.data = c + } catch(t) {} + var e = d.apply(n, t._args == f ? [t] : [t].concat(t._args)); + return ! 1 === e && (t.preventDefault(), t.stopPropagation()), + e + } + }, + i.i = m.length, + m.push(i), + "addEventListener" in n && n.addEventListener(a(i.e), i.proxy, o(i, h)) + }) + } + function c(t, r, i, s, c) { + var u = e(t); (r || "").split(/\s/).forEach(function(e) { + n(t, e, i, s).forEach(function(e) { + delete v[u][e.i], + "removeEventListener" in t && t.removeEventListener(a(e.e), e.proxy, o(e, c)) + }) + }) + } + function u(e, n) { + if (n || !e.isDefaultPrevented) { + n || (n = e), + t.each(T, + function(t, r) { + var i = n[t]; + e[t] = function() { + return this[r] = _, + i && i.apply(n, arguments) + }, + e[r] = x + }); + try { + e.timeStamp || (e.timeStamp = Date.now()) + } catch(t) { + console.log(t) + } (n.defaultPrevented !== f ? n.defaultPrevented: "returnValue" in n ? !1 === n.returnValue: n.getPreventDefault && n.getPreventDefault()) && (e.isDefaultPrevented = _) + } + return e + } + function l(t) { + var e, n = { + originalEvent: t + }; + for (e in t) j.test(e) || t[e] === f || (n[e] = t[e]); + return u(n, t) + } + var f, p = 1, + h = Array.prototype.slice, + d = t.isFunction, + m = function(t) { + return "string" == typeof t + }, + v = {}, + g = {}, + y = "onfocusin" in window, + w = { + focus: "focusin", + blur: "focusout" + }, + b = { + mouseenter: "mouseover", + mouseleave: "mouseout" + }; + g.click = g.mousedown = g.mouseup = g.mousemove = "MouseEvents", + t.event = { + add: s, + remove: c + }, + t.proxy = function(n, r) { + var i = 2 in arguments && h.call(arguments, 2); + if (d(n)) { + var o = function() { + return n.apply(r, i ? i.concat(h.call(arguments)) : arguments) + }; + return o._zid = e(n), + o + } + if (m(r)) return i ? (i.unshift(n[r], n), t.proxy.apply(null, i)) : t.proxy(n[r], n); + throw new TypeError("expected function") + }, + t.fn.bind = function(t, e, n) { + return this.on(t, e, n) + }, + t.fn.unbind = function(t, e) { + return this.off(t, e) + }, + t.fn.one = function(t, e, n, r) { + return this.on(t, e, n, r, 1) + }; + var _ = function() { + return ! 0 + }, + x = function() { + return ! 1 + }, + j = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/, + T = { + preventDefault: "isDefaultPrevented", + stopImmediatePropagation: "isImmediatePropagationStopped", + stopPropagation: "isPropagationStopped" + }; + t.fn.delegate = function(t, e, n) { + return this.on(e, t, n) + }, + t.fn.undelegate = function(t, e, n) { + return this.off(e, t, n) + }, + t.fn.live = function(e, n) { + return t(document.body).delegate(this.selector, e, n), + this + }, + t.fn.die = function(e, n) { + return t(document.body).undelegate(this.selector, e, n), + this + }, + t.fn.on = function(e, n, r, i, o) { + var a, u, p = this; + return e && !m(e) ? (t.each(e, + function(t, e) { + p.on(t, n, r, e, o) + }), p) : (m(n) || d(i) || !1 === i || (i = r, r = n, n = f), i !== f && !1 !== r || (i = r, r = f), !1 === i && (i = x), p.each(function(f, p) { + o && (a = function(t) { + return c(p, t.type, i), + i.apply(this, arguments) + }), + n && (u = function(e) { + var r, o = t(e.target).closest(n, p).get(0); + if (o && o !== p) return r = t.extend(l(e), { + currentTarget: o, + liveFired: p + }), + (a || i).apply(o, [r].concat(h.call(arguments, 1))) + }), + s(p, e, i, r, n, u || a) + })) + }, + t.fn.off = function(e, n, r) { + var i = this; + return e && !m(e) ? (t.each(e, + function(t, e) { + i.off(t, n, e) + }), i) : (m(n) || d(r) || !1 === r || (r = n, n = f), !1 === r && (r = x), i.each(function() { + c(this, e, r, n) + })) + }, + t.fn.trigger = function(e, n) { + return e = m(e) || t.isPlainObject(e) ? t.Event(e) : u(e), + e._args = n, + this.each(function() { + e.type in w && "function" == typeof this[e.type] ? this[e.type]() : "dispatchEvent" in this ? this.dispatchEvent(e) : t(this).triggerHandler(e, n) + }) + }, + t.fn.triggerHandler = function(e, r) { + var i, o; + return this.each(function(a, s) { + i = l(m(e) ? t.Event(e) : e), + i._args = r, + i.target = s, + t.each(n(s, e.type || e), + function(t, e) { + if (o = e.proxy(i), i.isImmediatePropagationStopped()) return ! 1 + }) + }), + o + }, + "focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e) { + t.fn[e] = function(t) { + return 0 in arguments ? this.bind(e, t) : this.trigger(e) + } + }), + t.Event = function(t, e) { + m(t) || (e = t, t = e.type); + var n = document.createEvent(g[t] || "Events"), + r = !0; + if (e) for (var i in e)"bubbles" == i ? r = !!e[i] : n[i] = e[i]; + return n.initEvent(t, r, !0), + u(n) + } + } (c), + function(t) { + function e(e, n, r) { + var i = t.Event(n); + return t(e).trigger(i, r), + !i.isDefaultPrevented() + } + function n(t, n, r, i) { + if (t.global) return e(n || w, r, i) + } + function r(e) { + e.global && 0 == t.active++&&n(e, null, "ajaxStart") + } + function i(e) { + e.global && !--t.active && n(e, null, "ajaxStop") + } + function o(t, e) { + var r = e.context; + if (!1 === e.beforeSend.call(r, t, e) || !1 === n(e, r, "ajaxBeforeSend", [t, e])) return ! 1; + n(e, r, "ajaxSend", [t, e]) + } + function a(t, e, r, i) { + var o = r.context; + r.success.call(o, t, "success", e), + i && i.resolveWith(o, [t, "success", e]), + n(r, o, "ajaxSuccess", [e, r, t]), + c("success", e, r) + } + function s(t, e, r, i, o) { + var a = i.context; + i.error.call(a, r, e, t), + o && o.rejectWith(a, [r, e, t]), + n(i, a, "ajaxError", [r, i, t || e]), + c(e, r, i) + } + function c(t, e, r) { + var o = r.context; + r.complete.call(o, e, t), + n(r, o, "ajaxComplete", [e, r]), + i(r) + } + function u(t, e, n) { + if (n.dataFilter == l) return t; + var r = n.context; + return n.dataFilter.call(r, t, e) + } + function l() {} + function f(t) { + return t && (t = t.split(";", 2)[0]), + t && (t == T ? "html": t == j ? "json": _.test(t) ? "script": x.test(t) && "xml") || "text" + } + function p(t, e) { + return "" == e ? t: (t + "&" + e).replace(/[&?]{1,2}/, "?") + } + function h(e) { + e.processData && e.data && "string" != t.type(e.data) && (e.data = t.param(e.data, e.traditional)), + !e.data || e.type && "GET" != e.type.toUpperCase() && "jsonp" != e.dataType || (e.url = p(e.url, e.data), e.data = void 0) + } + function d(e, n, r, i) { + return t.isFunction(n) && (i = r, r = n, n = void 0), + t.isFunction(r) || (i = r, r = void 0), + { + url: e, + data: n, + success: r, + dataType: i + } + } + function m(e, n, r, i) { + var o, a = t.isArray(n), + s = t.isPlainObject(n); + t.each(n, + function(n, c) { + o = t.type(c), + i && (n = r ? i: i + "[" + (s || "object" == o || "array" == o ? n: "") + "]"), + !i && a ? e.add(c.name, c.value) : "array" == o || !r && "object" == o ? m(e, c, r, n) : e.add(n, c) + }) + } + var v, g, y = +new Date, + w = window.document, + b = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, + _ = /^(?:text|application)\/javascript/i, + x = /^(?:text|application)\/xml/i, + j = "application/json", + T = "text/html", + k = /^\s*$/, + S = w.createElement("a"); + S.href = window.location.href, + t.active = 0, + t.ajaxJSONP = function(e, n) { + if (! ("type" in e)) return t.ajax(e); + var r, i, c = e.jsonpCallback, + u = (t.isFunction(c) ? c() : c) || "Zepto" + y++, + l = w.createElement("script"), + f = window[u], + p = function(e) { + t(l).triggerHandler("error", e || "abort") + }, + h = { + abort: p + }; + return n && n.promise(h), + t(l).on("load error", + function(o, c) { + clearTimeout(i), + t(l).off().remove(), + "error" != o.type && r ? a(r[0], h, e, n) : s(null, c || "error", h, e, n), + window[u] = f, + r && t.isFunction(f) && f(r[0]), + f = r = void 0 + }), + !1 === o(h, e) ? (p("abort"), h) : (window[u] = function() { + r = arguments + }, + l.src = e.url.replace(/\?(.+)=\?/, "?$1=" + u), w.head.appendChild(l), e.timeout > 0 && (i = setTimeout(function() { + p("timeout") + }, + e.timeout)), h) + }, + t.ajaxSettings = { + type: "GET", + beforeSend: l, + success: l, + error: l, + complete: l, + context: null, + global: !0, + xhr: function() { + return new window.XMLHttpRequest + }, + accepts: { + script: "text/javascript, application/javascript, application/x-javascript", + json: j, + xml: "application/xml, text/xml", + html: T, + text: "text/plain" + }, + crossDomain: !1, + timeout: 0, + processData: !0, + cache: !0, + dataFilter: l + }, + t.ajax = function(e) { + var n, i, c = t.extend({}, + e || {}), + d = t.Deferred && t.Deferred(); + for (v in t.ajaxSettings) void 0 === c[v] && (c[v] = t.ajaxSettings[v]); + r(c), + c.crossDomain || (n = w.createElement("a"), n.href = c.url, n.href = n.href, c.crossDomain = S.protocol + "//" + S.host != n.protocol + "//" + n.host), + c.url || (c.url = window.location.toString()), + (i = c.url.indexOf("#")) > -1 && (c.url = c.url.slice(0, i)), + h(c); + var m = c.dataType, + y = /\?.+=\?/.test(c.url); + if (y && (m = "jsonp"), !1 !== c.cache && (e && !0 === e.cache || "script" != m && "jsonp" != m) || (c.url = p(c.url, "_=" + Date.now())), "jsonp" == m) return y || (c.url = p(c.url, c.jsonp ? c.jsonp + "=?": !1 === c.jsonp ? "": "callback=?")), + t.ajaxJSONP(c, d); + var b, _ = c.accepts[m], + x = {}, + j = function(t, e) { + x[t.toLowerCase()] = [t, e] + }, + T = /^([\w-]+:)\/\//.test(c.url) ? RegExp.$1: window.location.protocol, + E = c.xhr(), + C = E.setRequestHeader; + if (d && d.promise(E), c.crossDomain || j("X-Requested-With", "XMLHttpRequest"), j("Accept", _ || "*/*"), (_ = c.mimeType || _) && (_.indexOf(",") > -1 && (_ = _.split(",", 2)[0]), E.overrideMimeType && E.overrideMimeType(_)), (c.contentType || !1 !== c.contentType && c.data && "GET" != c.type.toUpperCase()) && j("Content-Type", c.contentType || "application/x-www-form-urlencoded"), c.headers) for (g in c.headers) j(g, c.headers[g]); + if (E.setRequestHeader = j, E.onreadystatechange = function() { + if (4 == E.readyState) { + E.onreadystatechange = l, + clearTimeout(b); + var e, n = !1; + if (E.status >= 200 && E.status < 300 || 304 == E.status || 0 == E.status && "file:" == T) { + if (m = m || f(c.mimeType || E.getResponseHeader("content-type")), "arraybuffer" == E.responseType || "blob" == E.responseType) e = E.response; + else { + e = E.responseText; + try { + e = u(e, m, c), + "script" == m ? (0, eval)(e) : "xml" == m ? e = E.responseXML: "json" == m && (e = k.test(e) ? null: t.parseJSON(e)) + } catch(t) { + n = t + } + if (n) return s(n, "parsererror", E, c, d) + } + a(e, E, c, d) + } else s(E.statusText || null, E.status ? "error": "abort", E, c, d) + } + }, + !1 === o(E, c)) return E.abort(), + s(null, "abort", E, c, d), + E; + var O = !("async" in c) || c.async; + if (E.open(c.type, c.url, O, c.username, c.password), c.xhrFields) for (g in c.xhrFields) E[g] = c.xhrFields[g]; + for (g in x) C.apply(E, x[g]); + return c.timeout > 0 && (b = setTimeout(function() { + E.onreadystatechange = l, + E.abort(), + s(null, "timeout", E, c, d) + }, + c.timeout)), + E.send(c.data ? c.data: null), + E + }, + t.get = function() { + return t.ajax(d.apply(null, arguments)) + }, + t.post = function() { + var e = d.apply(null, arguments); + return e.type = "POST", + t.ajax(e) + }, + t.getJSON = function() { + var e = d.apply(null, arguments); + return e.dataType = "json", + t.ajax(e) + }, + t.fn.load = function(e, n, r) { + if (!this.length) return this; + var i, o = this, + a = e.split(/\s/), + s = d(e, n, r), + c = s.success; + return a.length > 1 && (s.url = a[0], i = a[1]), + s.success = function(e) { + o.html(i ? t("<div>").html(e.replace(b, "")).find(i) : e), + c && c.apply(o, arguments) + }, + t.ajax(s), + this + }; + var E = encodeURIComponent; + t.param = function(e, n) { + var r = []; + return r.add = function(e, n) { + t.isFunction(n) && (n = n()), + null == n && (n = ""), + this.push(E(e) + "=" + E(n)) + }, + m(r, e, n), + r.join("&").replace(/%20/g, "+") + } + } (c), + function(t) { + t.fn.serializeArray = function() { + var e, n, r = [], + i = function t(n) { + if (n.forEach) return n.forEach(t); + r.push({ + name: e, + value: n + }) + }; + return this[0] && t.each(this[0].elements, + function(r, o) { + n = o.type, + e = o.name, + e && "fieldset" != o.nodeName.toLowerCase() && !o.disabled && "submit" != n && "reset" != n && "button" != n && "file" != n && ("radio" != n && "checkbox" != n || o.checked) && i(t(o).val()) + }), + r + }, + t.fn.serialize = function() { + var t = []; + return this.serializeArray().forEach(function(e) { + t.push(encodeURIComponent(e.name) + "=" + encodeURIComponent(e.value)) + }), + t.join("&") + }, + t.fn.submit = function(e) { + if (0 in arguments) this.bind("submit", e); + else if (this.length) { + var n = t.Event("submit"); + this.eq(0).trigger(n), + n.isDefaultPrevented() || this.get(0).submit() + } + return this + } + } (c), + function() { + try { + getComputedStyle(void 0) + } catch(e) { + var t = getComputedStyle; + window.getComputedStyle = function(e, n) { + try { + return t(e, n) + } catch(t) { + return null + } + } + } + } (), + function(t) { + function e(t, e) { + var n = this.os = {}, + r = this.browser = {}, + i = t.match(/Web[kK]it[\/]{0,1}([\d.]+)/), + o = t.match(/(Android);?[\s\/]+([\d.]+)?/), + a = !!t.match(/\(Macintosh\; Intel /), + s = t.match(/(iPad).*OS\s([\d_]+)/), + c = t.match(/(iPod)(.*OS\s([\d_]+))?/), + u = !s && t.match(/(iPhone\sOS)\s([\d_]+)/), + l = t.match(/(webOS|hpwOS)[\s\/]([\d.]+)/), + f = /Win\d{2}|Windows/.test(e), + p = t.match(/Windows Phone ([\d.]+)/), + h = l && t.match(/TouchPad/), + d = t.match(/Kindle\/([\d.]+)/), + m = t.match(/Silk\/([\d._]+)/), + v = t.match(/(BlackBerry).*Version\/([\d.]+)/), + g = t.match(/(BB10).*Version\/([\d.]+)/), + y = t.match(/(RIM\sTablet\sOS)\s([\d.]+)/), + w = t.match(/PlayBook/), + b = t.match(/Chrome\/([\d.]+)/) || t.match(/CriOS\/([\d.]+)/), + _ = t.match(/Firefox\/([\d.]+)/), + x = t.match(/\((?:Mobile|Tablet); rv:([\d.]+)\).*Firefox\/[\d.]+/), + j = t.match(/MSIE\s([\d.]+)/) || t.match(/Trident\/[\d](?=[^\?]+).*rv:([0-9.].)/), + T = !b && t.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/), + k = T || t.match(/Version\/([\d.]+)([^S](Safari)|[^M]*(Mobile)[^S]*(Safari))/); (r.webkit = !!i) && (r.version = i[1]), + o && (n.android = !0, n.version = o[2]), + u && !c && (n.ios = n.iphone = !0, n.version = u[2].replace(/_/g, ".")), + s && (n.ios = n.ipad = !0, n.version = s[2].replace(/_/g, ".")), + c && (n.ios = n.ipod = !0, n.version = c[3] ? c[3].replace(/_/g, ".") : null), + p && (n.wp = !0, n.version = p[1]), + l && (n.webos = !0, n.version = l[2]), + h && (n.touchpad = !0), + v && (n.blackberry = !0, n.version = v[2]), + g && (n.bb10 = !0, n.version = g[2]), + y && (n.rimtabletos = !0, n.version = y[2]), + w && (r.playbook = !0), + d && (n.kindle = !0, n.version = d[1]), + m && (r.silk = !0, r.version = m[1]), + !m && n.android && t.match(/Kindle Fire/) && (r.silk = !0), + b && (r.chrome = !0, r.version = b[1]), + _ && (r.firefox = !0, r.version = _[1]), + x && (n.firefoxos = !0, n.version = x[1]), + j && (r.ie = !0, r.version = j[1]), + k && (a || n.ios || f) && (r.safari = !0, n.ios || (r.version = k[1])), + T && (r.webview = !0), + n.tablet = !!(s || w || o && !t.match(/Mobile/) || _ && t.match(/Tablet/) || j && !t.match(/Phone/) && t.match(/Touch/)), + n.phone = !(n.tablet || n.ipod || !(o || u || l || v || g || b && t.match(/Android/) || b && t.match(/CriOS\/([\d.]+)/) || _ && t.match(/Mobile/) || j && t.match(/Touch/))) + } + e.call(t, navigator.userAgent, navigator.platform), + t.__detect = e + } (c), + function(t) { + var e, n = []; + t.fn.remove = function() { + return this.each(function() { + this.parentNode && ("IMG" === this.tagName && (n.push(this), this.src = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=", e && clearTimeout(e), e = setTimeout(function() { + n = [] + }, + 6e4)), this.parentNode.removeChild(this)) + }) + } + } (c), + function(t) { + function e(e, r) { + var c = e[s], + u = c && i[c]; + if (void 0 === r) return u || n(e); + if (u) { + if (r in u) return u[r]; + var l = a(r); + if (l in u) return u[l] + } + return o.call(t(e), r) + } + function n(e, n, o) { + var c = e[s] || (e[s] = ++t.uuid), + u = i[c] || (i[c] = r(e)); + return void 0 !== n && (u[a(n)] = o), + u + } + function r(e) { + var n = {}; + return t.each(e.attributes || c, + function(e, r) { + 0 == r.name.indexOf("data-") && (n[a(r.name.replace("data-", ""))] = t.zepto.deserializeValue(r.value)) + }), + n + } + var i = {}, + o = t.fn.data, + a = t.camelCase, + s = t.expando = "Zepto" + +new Date, + c = []; + t.fn.data = function(r, i) { + return void 0 === i ? t.isPlainObject(r) ? this.each(function(e, i) { + t.each(r, + function(t, e) { + n(i, t, e) + }) + }) : 0 in this ? e(this[0], r) : void 0 : this.each(function() { + n(this, r, i) + }) + }, + t.data = function(e, n, r) { + return t(e).data(n, r) + }, + t.hasData = function(e) { + var n = e[s], + r = n && i[n]; + return !! r && !t.isEmptyObject(r) + }, + t.fn.removeData = function(e) { + return "string" == typeof e && (e = e.split(/\s+/)), + this.each(function() { + var n = this[s], + r = n && i[n]; + r && t.each(e || r, + function(t) { + delete r[e ? a(this) : t] + }) + }) + }, + ["remove", "empty"].forEach(function(e) { + var n = t.fn[e]; + t.fn[e] = function() { + var t = this.find("*"); + return "remove" === e && (t = t.add(this)), + t.removeData(), + n.call(this) + } + }) + } (c), + function(t) { + function e(n) { + var r = [["resolve", "done", t.Callbacks({ + once: 1, + memory: 1 + }), "resolved"], ["reject", "fail", t.Callbacks({ + once: 1, + memory: 1 + }), "rejected"], ["notify", "progress", t.Callbacks({ + memory: 1 + })]], + i = "pending", + o = { + state: function() { + return i + }, + always: function() { + return a.done(arguments).fail(arguments), + this + }, + then: function() { + var n = arguments; + return e(function(e) { + t.each(r, + function(r, i) { + var s = t.isFunction(n[r]) && n[r]; + a[i[1]](function() { + var n = s && s.apply(this, arguments); + if (n && t.isFunction(n.promise)) n.promise().done(e.resolve).fail(e.reject).progress(e.notify); + else { + var r = this === o ? e.promise() : this, + a = s ? [n] : arguments; + e[i[0] + "With"](r, a) + } + }) + }), + n = null + }).promise() + }, + promise: function(e) { + return null != e ? t.extend(e, o) : o + } + }, + a = {}; + return t.each(r, + function(t, e) { + var n = e[2], + s = e[3]; + o[e[1]] = n.add, + s && n.add(function() { + i = s + }, + r[1 ^ t][2].disable, r[2][2].lock), + a[e[0]] = function() { + return a[e[0] + "With"](this === a ? o: this, arguments), + this + }, + a[e[0] + "With"] = n.fireWith + }), + o.promise(a), + n && n.call(a, a), + a + } + var n = Array.prototype.slice; + t.when = function(r) { + var i, o, a, s = n.call(arguments), + c = s.length, + u = 0, + l = 1 !== c || r && t.isFunction(r.promise) ? c: 0, + f = 1 === l ? r: e(), + p = function(t, e, r) { + return function(o) { + e[t] = this, + r[t] = arguments.length > 1 ? n.call(arguments) : o, + r === i ? f.notifyWith(e, r) : --l || f.resolveWith(e, r) + } + }; + if (c > 1) for (i = new Array(c), o = new Array(c), a = new Array(c); u < c; ++u) s[u] && t.isFunction(s[u].promise) ? s[u].promise().done(p(u, a, s)).fail(f.reject).progress(p(u, o, i)) : --l; + return l || f.resolveWith(a, s), + f.promise() + }, + t.Deferred = e + } (c), + function(t) { + t.Callbacks = function(e) { + e = t.extend({}, + e); + var n, r, i, o, a, s, c = [], + u = !e.once && [], + l = function t(l) { + for (n = e.memory && l, r = !0, s = o || 0, o = 0, a = c.length, i = !0; c && s < a; ++s) if (!1 === c[s].apply(l[0], l[1]) && e.stopOnFalse) { + n = !1; + break + } + i = !1, + c && (u ? u.length && t(u.shift()) : n ? c.length = 0 : f.disable()) + }, + f = { + add: function() { + if (c) { + var r = c.length; ! + function n(r) { + t.each(r, + function(t, r) { + "function" == typeof r ? e.unique && f.has(r) || c.push(r) : r && r.length && "string" != typeof r && n(r) + }) + } (arguments), + i ? a = c.length: n && (o = r, l(n)) + } + return this + }, + remove: function() { + return c && t.each(arguments, + function(e, n) { + for (var r; (r = t.inArray(n, c, r)) > -1;) c.splice(r, 1), + i && (r <= a && --a, r <= s && --s) + }), + this + }, + has: function(e) { + return ! (!c || !(e ? t.inArray(e, c) > -1 : c.length)) + }, + empty: function() { + return a = c.length = 0, + this + }, + disable: function() { + return c = u = n = void 0, + this + }, + disabled: function() { + return ! c + }, + lock: function() { + return u = void 0, + n || f.disable(), + this + }, + locked: function() { + return ! u + }, + fireWith: function(t, e) { + return ! c || r && !u || (e = e || [], e = [t, e.slice ? e.slice() : e], i ? u.push(e) : l(e)), + this + }, + fire: function() { + return f.fireWith(this, arguments) + }, + fired: function() { + return !! r + } + }; + return f + } + } (c), + function(t) { + function e(e) { + return e = t(e), + !(!e.width() && !e.height()) && "none" !== e.css("display") + } + function n(t, e) { + t = t.replace(/=#\]/g, '="#"]'); + var n, r, i = s.exec(t); + if (i && i[2] in a && (n = a[i[2]], r = i[3], t = i[1], r)) { + var o = Number(r); + r = isNaN(o) ? r.replace(/^["']|["']$/g, "") : o + } + return e(t, n, r) + } + var r = t.zepto, + i = r.qsa, + o = r.matches, + a = t.expr[":"] = { + visible: function() { + if (e(this)) return this + }, + hidden: function() { + if (!e(this)) return this + }, + selected: function() { + if (this.selected) return this + }, + checked: function() { + if (this.checked) return this + }, + parent: function() { + return this.parentNode + }, + first: function(t) { + if (0 === t) return this + }, + last: function(t, e) { + if (t === e.length - 1) return this + }, + eq: function(t, e, n) { + if (t === n) return this + }, + contains: function(e, n, r) { + if (t(this).text().indexOf(r) > -1) return this + }, + has: function(t, e, n) { + if (r.qsa(this, n).length) return this + } + }, + s = new RegExp("(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*"), + c = /^\s*>/, + u = "Zepto" + +new Date; + r.qsa = function(e, o) { + return n(o, + function(n, a, s) { + try { + var l; ! n && a ? n = "*": c.test(n) && (l = t(e).addClass(u), n = "." + u + " " + n); + var f = i(e, n) + } catch(t) { + throw console.error("error performing selector: %o", o), + t + } finally { + l && l.removeClass(u) + } + return a ? r.uniq(t.map(f, + function(t, e) { + return a.call(t, e, f, s) + })) : f + }) + }, + r.matches = function(t, e) { + return n(e, + function(e, n, r) { + return (!e || o(t, e)) && (!n || n.call(t, null, r) === t) + }) + } + } (c), + function(t) { + function e(t, e, n, r) { + return Math.abs(t - e) >= Math.abs(n - r) ? t - e > 0 ? "Left": "Right": n - r > 0 ? "Up": "Down" + } + function n() { + l = null, + p.last && (p.el.trigger("longTap"), p = {}) + } + function r() { + l && clearTimeout(l), + l = null + } + function i() { + s && clearTimeout(s), + c && clearTimeout(c), + u && clearTimeout(u), + l && clearTimeout(l), + s = c = u = l = null, + p = {} + } + function o(t) { + return ("touch" == t.pointerType || t.pointerType == t.MSPOINTER_TYPE_TOUCH) && t.isPrimary + } + function a(t, e) { + return t.type == "pointer" + e || t.type.toLowerCase() == "mspointer" + e + } + var s, c, u, l, f, p = {}; + t(document).ready(function() { + var h, d, m, v, g = 0, + y = 0; + "MSGesture" in window && (f = new MSGesture, f.target = document.body), + t(document).bind("MSGestureEnd", + function(t) { + var e = t.velocityX > 1 ? "Right": t.velocityX < -1 ? "Left": t.velocityY > 1 ? "Down": t.velocityY < -1 ? "Up": null; + e && (p.el.trigger("swipe"), p.el.trigger("swipe" + e)) + }).on("touchstart MSPointerDown pointerdown", + function(e) { (v = a(e, "down")) && !o(e) || (m = v ? e: e.touches[0], e.touches && 1 === e.touches.length && p.x2 && (p.x2 = void 0, p.y2 = void 0), h = Date.now(), d = h - (p.last || h), p.el = t("tagName" in m.target ? m.target: m.target.parentNode), s && clearTimeout(s), p.x1 = m.pageX, p.y1 = m.pageY, d > 0 && d <= 250 && (p.isDoubleTap = !0), p.last = h, l = setTimeout(n, 750), f && v && f.addPointer(e.pointerId)) + }).on("touchmove MSPointerMove pointermove", + function(t) { (v = a(t, "move")) && !o(t) || (m = v ? t: t.touches[0], r(), p.x2 = m.pageX, p.y2 = m.pageY, g += Math.abs(p.x1 - p.x2), y += Math.abs(p.y1 - p.y2)) + }).on("touchend MSPointerUp pointerup", + function(n) { (v = a(n, "up")) && !o(n) || (r(), p.x2 && Math.abs(p.x1 - p.x2) > 30 || p.y2 && Math.abs(p.y1 - p.y2) > 30 ? u = setTimeout(function() { + p.el && (p.el.trigger("swipe"), p.el.trigger("swipe" + e(p.x1, p.x2, p.y1, p.y2))), + p = {} + }, + 0) : "last" in p && (g < 30 && y < 30 ? c = setTimeout(function() { + var e = t.Event("tap"); + e.pageX = p.x2 || p.x1 || 0, + e.pageY = p.y2 || p.y1 || 0, + e.cancelTouch = i, + p.el && p.el.trigger(e), + p.isDoubleTap ? (p.el && p.el.trigger("doubleTap"), p = {}) : s = setTimeout(function() { + s = null, + p.el && p.el.trigger("singleTap"), + p = {} + }, + 250) + }, + 0) : p = {}), g = y = 0) + }).on("touchcancel MSPointerCancel pointercancel", i), + t(window).on("scroll", i) + }), + ["swipe", "swipeLeft", "swipeRight", "swipeUp", "swipeDown", "doubleTap", "tap", "singleTap", "longTap"].forEach(function(e) { + t.fn[e] = function(t) { + return this.on(e, t) + } + }) + } (c), + function(t) { + if (t.os.ios) { + var e = function(t) { + return "tagName" in t ? t: t.parentNode + }, + n = {}; + t(document).bind("gesturestart", + function(t) { + var r = Date.now(); + n.last; + n.target = e(t.target), + n.e1 = t.scale, + n.last = r + }).bind("gesturechange", + function(t) { + n.e2 = t.scale + }).bind("gestureend", + function(e) { + n.e2 > 0 ? (0 != Math.abs(n.e1 - n.e2) && t(n.target).trigger("pinch") && t(n.target).trigger("pinch" + (n.e1 - n.e2 > 0 ? "In": "Out")), n.e1 = n.e2 = n.last = 0) : "last" in n && (n = {}) + }), + ["pinch", "pinchIn", "pinchOut"].forEach(function(e) { + t.fn[e] = function(t) { + return this.bind(e, t) + } + }) + } + } (c), + function(t) { + t.fn.end = function() { + return this.prevObject || t() + }, + t.fn.andSelf = function() { + return this.add(this.prevObject || t()) + }, + "filter,add,not,eq,first,last,find,closest,parents,parent,children,siblings".split(",").forEach(function(e) { + var n = t.fn[e]; + t.fn[e] = function() { + var t = n.apply(this, arguments); + return t.prevObject = this, + t + } + }) + } (c), + function(t) { + void 0 === String.prototype.trim && (String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, "") + }), + void 0 === Array.prototype.reduce && (Array.prototype.reduce = function(t) { + if (void 0 === this || null === this) throw new TypeError; + var e, n = Object(this), + r = n.length >>> 0, + i = 0; + if ("function" != typeof t) throw new TypeError; + if (0 == r && 1 == arguments.length) throw new TypeError; + if (arguments.length >= 2) e = arguments[1]; + else for (;;) { + if (i in n) { + e = n[i++]; + break + } + if (++i >= r) throw new TypeError + } + for (; i < r;) i in n && (e = t.call(void 0, e, n[i], i, n)), + i++; + return e + }) + } (), + t.exports = c +}, +function(t, e) { + var n = Math.ceil, + r = Math.floor; + t.exports = function(t) { + return isNaN(t = +t) ? 0 : (t > 0 ? r: n)(t) + } +}, +function(t, e) { + t.exports = function(t) { + if (void 0 == t) throw TypeError("Can't call method on " + t); + return t + } +}, +function(t, e, n) { + var r = n(0), + i = n(1), + o = n(49), + a = n(3), + s = n(2), + c = function(t, e, n) { + var u, l, f, p = t & c.F, + h = t & c.G, + d = t & c.S, + m = t & c.P, + v = t & c.B, + g = t & c.W, + y = h ? i: i[e] || (i[e] = {}), + w = y.prototype, + b = h ? r: d ? r[e] : (r[e] || {}).prototype; + h && (n = e); + for (u in n)(l = !p && b && void 0 !== b[u]) && s(y, u) || (f = l ? b[u] : n[u], y[u] = h && "function" != typeof b[u] ? n[u] : v && l ? o(f, r) : g && b[u] == f ? + function(t) { + var e = function(e, n, r) { + if (this instanceof t) { + switch (arguments.length) { + case 0: + return new t; + case 1: + return new t(e); + case 2: + return new t(e, n) + } + return new t(e, n, r) + } + return t.apply(this, arguments) + }; + return e.prototype = t.prototype, + e + } (f) : m && "function" == typeof f ? o(Function.call, f) : f, m && ((y.virtual || (y.virtual = {}))[u] = f, t & c.R && w && !w[u] && a(w, u, f))) + }; + c.F = 1, + c.G = 2, + c.S = 4, + c.P = 8, + c.B = 16, + c.W = 32, + c.U = 64, + c.R = 128, + t.exports = c +}, +function(t, e, n) { + var r = n(8); + t.exports = function(t, e) { + if (!r(t)) return t; + var n, i; + if (e && "function" == typeof(n = t.toString) && !r(i = n.call(t))) return i; + if ("function" == typeof(n = t.valueOf) && !r(i = n.call(t))) return i; + if (!e && "function" == typeof(n = t.toString) && !r(i = n.call(t))) return i; + throw TypeError("Can't convert object to primitive value") + } +}, +function(t, e) { + t.exports = {} +}, +function(t, e, n) { + var r = n(35), + i = n(24); + t.exports = Object.keys || + function(t) { + return r(t, i) + } +}, +function(t, e, n) { + var r = n(23)("keys"), + i = n(14); + t.exports = function(t) { + return r[t] || (r[t] = i(t)) + } +}, +function(t, e, n) { + var r = n(1), + i = n(0), + o = i["__core-js_shared__"] || (i["__core-js_shared__"] = {}); (t.exports = function(t, e) { + return o[t] || (o[t] = void 0 !== e ? e: {}) + })("versions", []).push({ + version: r.version, + mode: n(11) ? "pure": "global", + copyright: "© 2018 Denis Pushkarev (zloirock.ru)" + }) +}, +function(t, e) { + t.exports = "constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",") +}, +function(t, e, n) { + var r = n(4).f, + i = n(2), + o = n(7)("toStringTag"); + t.exports = function(t, e, n) { + t && !i(t = n ? t: t.prototype, o) && r(t, o, { + configurable: !0, + value: e + }) + } +}, +function(t, e, n) { + e.f = n(7) +}, +function(t, e, n) { + var r = n(0), + i = n(1), + o = n(11), + a = n(26), + s = n(4).f; + t.exports = function(t) { + var e = i.Symbol || (i.Symbol = o ? {}: r.Symbol || {}); + "_" == t.charAt(0) || t in e || s(e, t, { + value: a.f(t) + }) + } +}, +function(t, e) { + e.f = {}.propertyIsEnumerable +}, +function(t, e, n) { + t.exports = { + default: + n(44), + __esModule: !0 + } +}, +function(t, e, n) { + "use strict"; + var r = n(11), + i = n(18), + o = n(33), + a = n(3), + s = n(20), + c = n(51), + u = n(25), + l = n(37), + f = n(7)("iterator"), + p = !([].keys && "next" in [].keys()), + h = function() { + return this + }; + t.exports = function(t, e, n, d, m, v, g) { + c(n, e, d); + var y, w, b, _ = function(t) { + if (!p && t in k) return k[t]; + switch (t) { + case "keys": + case "values": + return function() { + return new n(this, t) + } + } + return function() { + return new n(this, t) + } + }, + x = e + " Iterator", + j = "values" == m, + T = !1, + k = t.prototype, + S = k[f] || k["@@iterator"] || m && k[m], + E = S || _(m), + C = m ? j ? _("entries") : E: void 0, + O = "Array" == e ? k.entries || S: S; + if (O && (b = l(O.call(new t))) !== Object.prototype && b.next && (u(b, x, !0), r || "function" == typeof b[f] || a(b, f, h)), j && S && "values" !== S.name && (T = !0, E = function() { + return S.call(this) + }), r && !g || !p && !T && k[f] || a(k, f, E), s[e] = E, s[x] = h, m) if (y = { + values: j ? E: _("values"), + keys: v ? E: _("keys"), + entries: C + }, + g) for (w in y) w in k || o(k, w, y[w]); + else i(i.P + i.F * (p || T), e, y); + return y + } +}, +function(t, e, n) { + t.exports = !n(5) && !n(9)(function() { + return 7 != Object.defineProperty(n(32)("div"), "a", { + get: function() { + return 7 + } + }).a + }) +}, +function(t, e, n) { + var r = n(8), + i = n(0).document, + o = r(i) && r(i.createElement); + t.exports = function(t) { + return o ? i.createElement(t) : {} + } +}, +function(t, e, n) { + t.exports = n(3) +}, +function(t, e, n) { + var r = n(12), + i = n(52), + o = n(24), + a = n(22)("IE_PROTO"), + s = function() {}, + c = function() { + var t, e = n(32)("iframe"), + r = o.length; + for (e.style.display = "none", n(57).appendChild(e), e.src = "javascript:", t = e.contentWindow.document, t.open(), t.write("<script>document.F=Object<\/script>"), t.close(), c = t.F; r--;) delete c.prototype[o[r]]; + return c() + }; + t.exports = Object.create || + function(t, e) { + var n; + return null !== t ? (s.prototype = r(t), n = new s, s.prototype = null, n[a] = t) : n = c(), + void 0 === e ? n: i(n, e) + } +}, +function(t, e, n) { + var r = n(2), + i = n(6), + o = n(54)(!1), + a = n(22)("IE_PROTO"); + t.exports = function(t, e) { + var n, s = i(t), + c = 0, + u = []; + for (n in s) n != a && r(s, n) && u.push(n); + for (; e.length > c;) r(s, n = e[c++]) && (~o(u, n) || u.push(n)); + return u + } +}, +function(t, e) { + var n = {}.toString; + t.exports = function(t) { + return n.call(t).slice(8, -1) + } +}, +function(t, e, n) { + var r = n(2), + i = n(38), + o = n(22)("IE_PROTO"), + a = Object.prototype; + t.exports = Object.getPrototypeOf || + function(t) { + return t = i(t), + r(t, o) ? t[o] : "function" == typeof t.constructor && t instanceof t.constructor ? t.constructor.prototype: t instanceof Object ? a: null + } +}, +function(t, e, n) { + var r = n(17); + t.exports = function(t) { + return Object(r(t)) + } +}, +function(t, e) { + e.f = Object.getOwnPropertySymbols +}, +function(t, e, n) { + var r = n(35), + i = n(24).concat("length", "prototype"); + e.f = Object.getOwnPropertyNames || + function(t) { + return r(t, i) + } +}, +function(t, e, n) { + t.exports = { + default: + n(73), + __esModule: !0 + } +}, +function(t, e, n) { + "use strict"; + function r(t) { + var e = new RegExp("(^| )" + t + "(?:=([^;]*))?(;|$)"), + n = document.cookie.match(e); + if (!n || !n[2]) return ""; + var r = n[2]; + try { + return /(%[0-9A-F]{2}){2,}/.test(r) ? decodeURIComponent(r) : unescape(r) + } catch(t) { + return unescape(r) + } + } + function i(t, e, n, r, i, o) { + var a = new Date, + n = arguments[2] || null, + r = arguments[3] || "/", + i = arguments[4] || null, + o = arguments[5] || !1; + n && a.setMinutes(a.getMinutes() + parseInt(n)), + document.cookie = t + "=" + escape(e) + (n ? ";expires=" + a.toGMTString() : "") + (r ? ";path=" + r: "") + (i ? ";domain=" + i: "") + (o ? ";secure": "") + } + function o(t, e, n, i) { + if (null != r(t)) { + var o = new Date; + o.setMinutes(o.getMinutes() - 1e3), + e = e || "/", + document.cookie = t + "=;expires=" + o.toGMTString() + (e ? ";path=" + e: "") + (n ? ";domain=" + n: "") + (i ? ";secure": "") + } + } + t.exports = { + get: r, + set: i, + del: o + } +}, +function(t, e, n) { + "use strict"; + function r() { + var t = tt("#slideWrapper"); + t.length && (et.init({ + tp: "img", + moveDom: t.find(".j_slide_list"), + moveChild: t.find(".j_slide_li"), + tab: t.find(".j_slide_nav span"), + len: t.find(".j_slide_li").length, + index: 1, + loopScroll: !0, + lockScrY: !0, + enableTransX: !0, + tabClass: "active", + autoTime: parseInt(tt(".slide_time").data("slide_time")) || 3e3, + fun: function(e) { ! pt && B(t) && tt(".j_slide_li").each(function(t) { + var n = tt(this); + t == e && !n.hasClass(st) && n.data("exposal_url") && (n.addClass(st), P(n.data("exposal_url"))), + t == e + 1 && n.find("img[init_src]").each(function() { + tt(this).attr("src", tt(this).attr("init_src")).removeAttr("init_src") + }) + }), + tt(".j_slide_li").each(function(t) { + var n = tt(this); + t == e + 1 && n.find("img[init_src]").each(function() { + tt(this).attr("src", tt(this).attr("init_src")).removeAttr("init_src") + }) + }) + } + }), t.find(".j_slide_li").each(function(t) { + tt(this).css({ + left: 100 * t + "%" + }) + })) + } + function i() { + var t = document.querySelectorAll(".catchimg"); + t = Array.prototype.slice.call(t, 0), + t.forEach(function(t) { + var e = t.querySelectorAll(".catchimg-skus"); + e = Array.prototype.slice.call(e, 0); + var n = t.querySelectorAll(".catchimg-skus-link"), + r = t.clientWidth, + i = r / 750; + e.forEach(function(e, r) { + var o = 0, + a = e.getAttribute("data-server-position"), + s = e.getAttribute("data-server-width"), + c = e.getAttribute("data-server-ani"), + u = s * i, + l = e.querySelectorAll(".catchimg-skus-item"); + l = Array.prototype.slice.call(l, 0); + var f = l.length; + if (0 != f) { + var p = n[r]; + l.forEach(function(t) { + var e = t.getAttribute("jump-href"), + n = t.getAttribute("data-sku_index"); + e += e.indexOf("?") > -1 ? "&innerIndex=" + n: "?innerIndex=" + n, + t.setAttribute("jump-href", e) + }), + p.onclick = function(t) { + t.stopPropagation(), + l[o].click() + }, + 0 === r && (t.onclick = function(t) { + l[o].click() + }), + a = a && a.split(","), + p.style.left = e.style.left = 1 * a[0] * i + "px", + p.style.top = e.style.top = 1 * a[1] * i + "px", + p.style.width = e.style.width = u + "px", + p.style.height = e.style.height = u + "px", + p.style.display = e.style.display = "block", + p.style.position = "absolute", + 1 != f && 2 != c && (1 != c && 0 != c || setInterval(function() { + o++, + o >= f && (o = 0), + e.scrollTop = o ? o * u: 0 + }, + 2e3)) + } + }) + }) + } + function o() { + console.log("东家小院灰度"); + var t = window.M_GREY[0].djxy[0], + e = t.url, + n = t.ratio; + if (! (1 * (JD.cookie.get("visitkey").substr( - 2, 2) || parseInt(100 * Math.random())) > 1 * n)) { + var r = document.querySelectorAll('[event_id="MHome_DGardenFloorExpo"]'); + r = Array.prototype.slice.call(r, 0), + r.forEach(function(t) { + var n = t.querySelectorAll("[jump-href]"); + n = Array.prototype.slice.call(n, 0), + n.forEach(function(t) { + var n = t.getAttribute("data-jump_params"), + r = t.getAttribute("data-jump_innerindex"), + i = (e || "https://h5.m.jd.com/active/yard-channel/index.html") + "?innerIndex=" + r + "&" + n; + t.setAttribute("jump-href", i) + }) + }) + } + } + function a() { + var t = tt(".j_slide_06001"); + t.length && t.each(function() { + var t = tt(this), + e = !0, + n = t.find(".slide_06001_li"); + if (n.length) { + var r = Math.min(t.width(), 640) * (358 / 375); + n.each(function() { + tt(this).width(r) + }), + et.init({ + tp: "img", + viewDom: t, + moveDom: t.find(".slide_06001"), + moveChild: n, + len: n.length, + index: 1, + tab: t.find(".j_nav"), + loopScroll: !0, + lockScrY: !0, + enableTransX: !1, + tabClass: "active", + step: r, + autoTime: 3e3, + fun: function(i) { + if (e) { + e = !1; + var o = 0; + n = t.find(".slide_06001_li"), + n.each(function() { + tt(this).width(r), + tt(this).css({ + left: o + "px" + }), + o += r + }) + } + n.each(function(t) { + t == i ? tt(this).css({ + transform: "scale(1)", + webKitTransform: "scale(1)" + }) : tt(this).css({ + transform: "scale(0.9)", + webKitTransform: "scale(0.9)" + }) + }) + } + }) + } + }) + } + function s() { + function t() { + i = document.querySelector(".j_scroll_news .news_item"); + var t = i.offsetHeight + 8; + r.style.transition = "transform 500ms ease-in-out", + r.style.webkitTransition = "transform 500ms ease-in-out", + r.style.transform = "translate3d(0, -" + t + "px, 0)", + r.style.webkitTransform = "translate3d(0, -" + t + "px, 0)" + } + function e() { + var t = setTimeout(function() { + clearTimeout(t), + r.style.transition = "none", + r.style.webkitTransition = "none", + r.style.transform = "translate3d(0, 0px, 0)", + r.style.webkitTransform = "translate3d(0, 0px, 0)", + i && r.removeChild(i), + i && r.appendChild(i) + }, + 0) + } + var n = "onwebkittransitionend" in window ? "webkitTransitionEnd": "transitionend", + r = document.querySelector(".j_scroll_news"), + i = null; + r && (r.addEventListener(n, e), document.querySelectorAll(".j_scroll_news .news_item").length > 1 && setInterval(t, 2e3)) + } + function c() { + var t = document.querySelector(".j_curtain"); + if (t) { + var e, n = function() { + mt = !0, + E(), + t && t.parentNode && t.parentNode.removeChild(t) + }, + r = new Date, + i = "" + r.getFullYear() + (r.getMonth() + 1) + r.getDate(); + if (at.local.getItem("m_jd_index_curtain") == i) return mt = !0, + void n(); + at.local.setItem("m_jd_index_curtain", i, !0, 86400), + window.activeData && window.activeData.length ? (window.activeData.forEach(function(t) { + var n = t.starttime ? new Date(t.starttime) : -1 / 0, + i = t.endtime ? new Date(t.endtime) : 1 / 0; + r <= i && r >= n && (e = t) + }), e && e.pic && e.url && 1 == e.aShow && (tt(".j_curtain_link").attr("jump-href", e.url), tt(".j_curtain_pic").attr("src", window.JD ? JD.img.getImgUrl(e.pic) : e.pic), t.style.display = "block", t.style.opacity = 1, $({ + eventId: "MHome_CurtainExpo" + })), tt(".j_close_curtain").click(function() { + n() + }), tt(".j_curtain").click(function(t) { + var e = tt(t.target || t.srcElement); + n(), + e.hasClass("j_curtain_pic") || e.hasClass("j_curtain_link") || $({ + eventId: "MHome_CurtainClose" + }) + })) : mt = !0 + } + } + function u() { + var t = JD.url.getUrlParam("debug_skuids"), + e = t || nt.get("warehistory"); + e = e.replace(/"/g, "").split(",").filter(function(t) { + return /^[0-9]+$/.test(t) + }).slice(0, 4), + e.length < 4 || + function() { + p(e, + function(t) { + if (t && 4 === t.length) { + var n = it.formatJson("footPrintSkuTpl", { + skuList: t + }); + tt(".j_foot_print_sku_list").html(n), + tt("#footPrintFloor").show(), + tt("#footPrintSeat").hide(), + $({ + eventId: "MHome_FootFloorExpo" + }), + ot.autoLoadImage({ + container: "footPrintFloor", + skip_invisible: !0 + }), + h(e, + function(t) { + if (t) for (var e in t) { + var n = t[e].price, + r = n.split(".")[0], + i = n.split(".")[1], + o = '<span class="int">暂无报价</span>'; + parseFloat(n) > 0 && (o = '<span class="symbol">¥</span> <span class="int">' + r + '</span> <span class="float" style="margin-left: 0;">.' + i + "</span>"), + tt('.j_fp_sku[sku_id="' + e + '"]').find(".j_fp_sku_price").html(o) + } + }), + l(e, + function(t) { + if (t) for (var e in t) tt('.j_fp_sku[sku_id="' + e + '"]').find(".j_fp_sku_tag").html(t[e]) + }) + } else tt("#footPrintFloor").hide() + }) + } () + } + function l(t, e) { + var n = m("getSkuPromotionInfo"), + r = []; + t && t.length && t.forEach(function(t) { + r.push("J_" + t) + }), + window[n] = function(t) { + console.log(t); + var n = { + 3 : "赠券", + 4 : "赠京豆", + 5 : "赠品", + 11 : "会员特价", + 22 : "京豆优惠购", + 55 : "满减", + 57 : "加价购", + 58 : "满赠", + 59 : "多买优惠", + 60 : "换购", + 80 : "plus赠品" + }, + r = {}; + t && t.length && t.forEach(function(t) { + var e = t.pid, + i = []; + t && t.pf && t.pf.length && t.pf.forEach(function(t) { + if (n[t]) { + var e = n[t]; + i.push('<span class="ellipse"> <em>' + e + "</em> <span>" + e + "</span> </span>") + } + }), + i.length && (r[e] = i.slice(0, 2).join("")) + }), + e && e(r) + }, + rt.loadScript({ + url: "//pf.3.cn/flags/mgets?skuids=" + r.join(",") + "&origin=1&source=m_index&area=" + d() + "&callback=" + n, + charset: "utf-8", + onError: function() { + e && e(!1) + }, + onTimeout: function() { + e && e(!1) + } + }) + } + function f(t) { + return t.indexOf("360buyimg.com") >= 0 ? JD.img.getImgUrl(t) : JD.img.getImgUrl("//img1" + ~~ (5 * Math.random()) + ".360buyimg.com/n7/" + t) + } + function p(t, e) { + var n = m("getSkuInfo"); + window[n] = function(n) { + var r = []; + for (var i in n) { + var o = n[i]; + r.push({ + name: o.name, + img: f(o.imagePath), + link: "//item.m.jd.com/product/" + i + ".html", + skuId: i + }) + } + r.sort(function(e, n) { + return t.indexOf(e.skuId) - t.indexOf(n.skuId) + }), + e && e(r) + }, + rt.loadScript({ + url: "//yx.3.cn/service/info.action?ids=" + t.join(",") + "&callback=" + n, + charset: "utf-8", + onError: function() { + e && e(!1) + }, + onTimeout: function() { + e && e(!1) + } + }) + } + function h(t, e) { + for (var n = {}, + r = 0, + i = [], o = 0, a = 0;;) { + var s = t.slice(20 * r, 20 * (r + 1)); + if (i.push(s), 20 * (r + 1) > t.length) break; + r++ + } + i.forEach(function(t, r) { + var i = m("realTimePriceCB"); + o++, + window[i] = function(t) { + a++; + for (var r = t.length, + i = 0; i < r; i++) n[t[i].id] = { + price: t[i].p, + plusPrice: t[i].tpp + }; + o == a && e && e(n) + }, + rt.loadScript({ + url: "//pe.3.cn/prices/mgets?skuids=" + t.join(",") + "&area=" + d() + "&origin=4&source=wxsqpage&callback=" + i + "&t=" + Math.random(), + charset: "utf-8" + }) + }) + } + function d() { + return (JD.cookie.get("jdAddrId") || JD.cookie.get("jdLOCAddrId") || "1_72_4139_0").split("_").slice(0, 3).join("_") + } + function m(t) { + for (var e = t + Math.ceil(1e6 * Math.random()); window[e];) e = t + Math.ceil(1e6 * Math.random()); + return e + } + function v(t, e, n) { + try { + JD.report.umpBiz({ + bizid: 975, + operation: t, + result: e, + source: "0", + message: (n || "").replace(/[,,]/g, "").replace(/\s+/g, "") + }), + 0 != e && console.log("%cUMP:" + n, "color:red;") + } catch(t) { + console.log(t) + } + } + function g() { + var t; + try { + t = window.m_recommend[0] + } catch(t) { + console.error("页面片/sinclude/update/wx/2018/9/m-recommend.html丢失!或者数据格式被修改!" + t) + } + return t || {} + } + function y(t, e) { + var n = g(), + r = n.recommendId || 6163, + i = 1 * n.pageCount || 22; + tt(".j_scroll_load_rec").show(), + 0 == t && $({ + eventId: "Mhome_BRecommendExpo" + }), + tt.ajax({ + dataType: "jsonp", + url: "https://wqcoss.jd.com/mcoss/reclike/getrecinfo", + data: { + pi: t, + pc: i, + recpos: r, + hi: "{page:" + t + ",pagesize:" + i + "}" + }, + success: function(r) { + if (v(2, 0, "猜你喜欢接口调用成功"), r.data instanceof Array && r.data.length) { + var i = tt(".j_similar_li").length; + r.data.forEach(function(e, o) { + if (1 == e.jpnonshow) e._showPrice0 = "待发布"; + else if (0 == e.jpnonshow && e.jp) { + var a = e.jp / 100 + ""; + if (e._showPrice0 = a.split(".")[0] || "", e._showPrice1 = a.split(".")[1] || "", e.dpicon && e.dpicon.icon > 0) { + var s = "¥ " + e.dpicon.p / 100; + e._dbPrice = 3 == e.dpicon.icon ? "<del>" + s + "</del>": s + } + e._priceTag = _(e), + e._dbPriceTag = x(e) + } else console.error("推荐数据缺少jp!!!"); + if (e.yd && (e.yd._time = T(1e3 * e.yd.start) + "-" + T(1e3 * e.yd.end)), e.t = e.t.trim(), e._sourceValue = k(t, o, e, r.flow, r.impr), e._img = f(e.img), e._showIndex = ++i, n.iconCorner instanceof Array && n.iconCorner[0]) { + var c = n.iconCorner[0], + u = 1 * new Date(c.beginTime), + l = 1 * new Date(c.endTime), + p = 1 * new Date; + c && 1 == e.prom && p >= u && p <= l && (e._promTag = JD.img.getImgUrl(c.img, "30", "30")) + } + }); + var o = it.formatJson("recSkuTpl", { + getImgUrl: w, + sourceUrl: "//st.360buyimg.com", + skuList: r.data + }); + 0 == t ? tt(".j_rec_goods_list").html(o) : tt(".j_rec_goods_list").append(o), + tt(".j_scroll_load_rec").hide(), + ot.autoLoadImage({ + container: "recFloor", + skip_invisible: !0 + }); + var a = setTimeout(function() { + clearTimeout(a), + j(), + F() + }, + 200); + e && e(!0) + } + }, + error: function() { + v(2, 1, "猜你喜欢接口调用出错"), + e && e(!1) + } + }) + } + function w(t, e) { + switch (t) { + case "sku": + return f(e); + case "product-text": + return b(e); + default: + return "" + } + } + function b(t) { + var e = ""; + try { + e = ppms_recom[0].iconList.filter(function(e) { + return e.key == t + }), + e = e[0].iconImg + } catch(t) { + console.error("页面片/sinclude/update/wx/2018/3/ppms_recom.shtml丢失,或者数据格式被篡改!" + t) + } + return e + } + function _(t) { + return t.paicon > 0 ? vt.paicon[t.paicon] || "": "" + } + function x(t) { + return t.dpicon instanceof Object && t.dpicon.icon > 0 ? vt.dbicon[t.dpicon.icon] || "": "" + } + function j() { + tt(".j_rec_goods_pic").each(function() { + var t = tt(this).parent().width(); + t >= 50 && tt(this).css({ + width: t, + height: t + }) + }) + } + function T(t) { + var e = new Date(t); + return e.getMonth() + 1 + "." + e.getDate() + } + function k(t, e, n, r, i) { + var o = n.sku, + a = n.source, + s = n.sid; + return [t, e, o, S("expid", i), r, s, a, "-100", S("reqsig", i), "-100", n.yd ? 1 : 0].join("_") + } + function S(t, e) { + var n = arguments[1] || window.location.search, + r = new RegExp(t + "=([^$|&]*)"), + i = n.substr(n.indexOf("?") + 1).match(r); + return null != i ? i[1] : "" + } + function E() { + if (mt && !gt) { + gt = !0; + window.getIpLocate = function(t) { + if (0 == t.code && t.data && "中国大陆" != t.data.countryName) { + var e = function() { + tt("#locatePop").hide(), + $({ + eventId: "MHome_OverSeaClose" + }) + }; + $({ + eventId: "MHome_OverSeaExpo" + }), + tt(".j_location_title").text(t.data.localCountryName), + tt(".j_location_desc").text(t.data.markedWords), + tt(".j_location_okay").text(t.data.buttonChange), + tt(".j_location_cancel").text(t.data.buttonStay), + tt("#locatePop").show(), + tt(".j_location_okay").click(function() { + $({ + eventId: "MHome_OverSeaSwitch" + }); + var e = setTimeout(function() { + clearTimeout(e), + tt("#locatePop").hide(), + C(t.data.mUrl) + }, + ct) + }), + tt(".j_location_cancel").click(function() { + $({ + eventId: "MHome_OverSeaStay" + }), + tt("#locatePop").hide() + }), + tt(".j_location_mask").click(function() { + e() + }), + tt(".j_location_close").click(function() { + e() + }) + } + }, + rt.loadScript({ + url: "//ip-dict.joybuy.com/countryQuery/get_country_by_ip?callback=getIpLocate", + charset: "utf-8" + }) + } + } + function C(t) { + O(t === dt), + location.href = t + } + function O(t) { + var e = window.pageYOffset, + n = M(); + ut.length && (n.sksLeft = t ? 0 : ut.scrollLeft()), + n.st = e, + D(n) + } + function D(t) { + var e = []; + for (var n in t) e.push(n + "=" + t[n]); + var r = e.length ? "#" + e.join("&") : ""; + history.replaceState("", document.title, location.href.replace(location.hash, "") + r) + } + function I(t) { + var e = M(); + delete e[t], + D(e) + } + function M() { + var t = location.hash.substr(1), + e = {}; + return t.replace(/([^?&]+)=([^?&]+)/g, + function(t, n, r) { + e[n] = r + }), + e + } + function P(t) { (new Image).src = t + } + function A() { + function t() { + O(), + a.css({ + position: "absolute" + }), + pt = !0, + ft.unbind("scroll", n), + i.hide(), + tt("#commonNav").hide(), + tt("#mainContent").hide(), + tt("#mCommonFooter").hide(), + a.removeClass("skin_transparent"), + a.css({ + top: "0" + }); + var t = setTimeout(function() { + clearTimeout(t), + ft.unbind("scroll", n) + }, + 100) + } + function e() { + a.css({ + position: "fixed" + }), + pt = !1, + tt("#commonNav").show(), + tt("#mainContent").show(), + tt("#mCommonFooter").show(), + a.addClass("skin_transparent"), + ft.unbind("scroll", n).scroll(n), + ft.scroll(), + V(!0) + } + function n() { + c && (setTimeout(function() { + if (c = !0, u || window.pageYOffset >= 5 || !i.data("show") || pt) a.css({ + top: 0 + }), + i.hide(), + o.hide(); + else { + i.show(), + o.show(); + var t = i.length ? i.offset().height: 0; + a.css({ + top: t + }) + } + r(window.pageYOffset > 5 ? "home_normal": "home_transparent") + }, + 0), c = !1) + } + function r(t) { + window.JD && window.JD.M && window.JD.M.smartbox && window.JD.M.smartbox.changeTheam && JD.M.smartbox.changeTheam(t) + } + var i = tt("#m_common_tip"), + o = tt("#pannelSeat"), + a = tt(".j_smart_box_wrapper"); + window.JD && window.JD.M && window.JD.M.smartbox && window.JD.M.smartbox.init && (window.JD.M.smartbox.init({ + css: "", + sf: "home", + isLogin: lt, + smartboxBlock: "searchWrapper", + shortCutShow: !0, + showCb: function() { + t() + }, + hideCb: function() { + e() + } + }), JD.M.smartbox.setLogin(lt)); + var s = tt("#slideWrapper").length ? tt("#slideWrapper").offset().height: 0, + c = !0, + u = navigator.userAgent.indexOf("UCBrowser") > -1; + s ? (ft.unbind("scroll", n).scroll(n), ft.scroll()) : r("home_normal") + } + function L() { + try { + MPing.inputs.Click.attachEvent() + } catch(t) {} + var t = tt(".j_back_to_top"); + window.addEventListener("load", + function() { + ht = !0, + u(), + E(), + V(!0) + }), + t.click(function() { + ft.scrollTop(0) + }); + var e = !0; + ft.scroll(function() { + if (e) { + e = !1; + var n = setTimeout(function() { + e = !0, + clearTimeout(n), + window.pageYOffset > window.innerHeight ? t.show() : t.hide() + }, + 200) + } + }), + J(), + U() + } + function N() { + function t() { (o && n || n && B(tt(".j_rec_load_wrapper"))) && (o = !1, n = !1, y(e, + function(i) { + n = !0, + e >= s ? (n = !1, r.show()) : n = !0, + i && e++, + ft.unbind("scroll", t); + var o = setTimeout(function() { + clearTimeout(o), + ft.unbind("scroll", t).scroll(t) + }, + 1e3) + })), + i || (i = setTimeout(function() { + clearTimeout(i), + j(), + F() + }, + 100)) + } + var e = 1, + n = !0, + r = tt(".j_click_load_rec"); + tt("#recFloor").delegate("[data-click_expo_url]", "click", + function() { + var t = tt(this); + t.data("click_expo_url") && P(t.data("click_expo_url")) + }); + var i, o = !0, + a = g(), + s = 1 * a.scrollPage || 2; + ft.unbind("scroll", t).scroll(t), + t(), + r.click(function() { + r.hide(), + y(e, + function(n) { + n && e++, + r.show(), + ft.unbind("scroll", t) + }) + }) + } + function F() { + var t = tt(".j_similar_goods:first-child").find(".similar-product").height(); + tt(".similar-shop .shop-posre").each(function() { + tt(this).height(t - 1) + }) + } + function R() { + tt(".j_linear_color").each(function() { + var t = tt(this).data("color"); + t && -1 == t.indexOf(",") && tt(this).css({ + color: t + }) + }) + } + function q(t) { + var e = (t.data("event_param") || "") + ""; + if (e && ("j_event_param" == e && (e = t.find(".j_event_param").text()), 0 === e.indexOf("j_garden_event_param"))) { + e = e.replace(/^j_garden_event_param\((.*)\)$/, "$1"); + var n = e.split("|"), + r = { + biinfo: n[0] || "", + floorid: n[1] || "", + moduleid: n[2] || "", + position: n[3] || "", + sku: n[4] || "", + theme: n[5] || "" + }; + e = (0, Q. + default)(r) + } + if ($({ + eventId: + t.data("event_id"), + eventLevel: t.data("event_level"), + eventParam: e + }), t.attr("jump-href")) var i = setTimeout(function() { + clearTimeout(i), + C(t.attr("jump-href")) + }, + ct) + } + function J() { + tt(document).delegate("[data-event_id]", "click", + function() { + q(tt(this)) + }) + } + function $(t) { + if (t.eventId) try { + var e = location.origin + location.pathname, + n = new MPing.inputs.Click(t.eventId); + n.event_param = t.eventParam || "", + n.event_level = t.eventLevel || "", + e && (n.page_name = e), + n.page_param = "B", + n.updateEventSeries(); (new MPing).send(n) + } catch(t) {} + } + function U() { + var t = !0; + ft.scroll(function() { + if (t) { + t = !1; + var e = setTimeout(function() { + clearTimeout(e), + t = !0; + var n = tt(".j_expo"); + n.length && n.each(function() { + var t = tt(this); + t.hasClass(st) || !t.is(":hidden") && B(t) && ($({ + eventId: t.attr("event_id"), + eventLevel: t.attr("event_level"), + eventParam: t.attr("event_param") + }), t.addClass(st)) + }); + var r = tt(".j_similar_li"); + r.length && r.each(function() { + var t = tt(this); + if (!t.hasClass(st) && !t.is(":hidden") && B(t)) { + var e = t.attr("event_param"); + $({ + eventId: t.attr("event_id"), + eventParam: e + }), + t.addClass(st), + tt('.j_similar_li[event_param="' + e + '"]').addClass(st) + } + }) + }, + 0) + } + }) + } + function B(t) { + var e = t.offset().top, + n = t.offset().height, + r = e + n, + i = ft.scrollTop(), + o = ft.height(); + return e >= i && e < i + o || (r >= i && r < i + o || e <= i && r >= i + o) + } + function H() { + var t = new Date, + e = t.getFullYear() + "/" + (t.getMonth() + 1) + "/" + t.getDate(), + n = t.getHours(), + r = n <= 5 ? 0 : Math.ceil((n - 5) / 2); + return [{ + name: "0点场", + endTime: new Date(e + " 06:00:00").getTime() + }, + { + name: "6点场", + endTime: new Date(e + " 08:00:00").getTime() + }, + { + name: "8点场", + endTime: new Date(e + " 10:00:00").getTime() + }, + { + name: "10点场", + endTime: new Date(e + " 12:00:00").getTime() + }, + { + name: "12点场", + endTime: new Date(e + " 14:00:00").getTime() + }, + { + name: "14点场", + endTime: new Date(e + " 16:00:00").getTime() + }, + { + name: "16点场", + endTime: new Date(e + " 18:00:00").getTime() + }, + { + name: "18点场", + endTime: new Date(e + " 20:00:00").getTime() + }, + { + name: "20点场", + endTime: new Date(e + " 22:00:00").getTime() + }, + { + name: "22点场", + endTime: new Date(e + " 00:00:00").getTime() + 864e5 + }][r] + } + function W() { + function t() { + var t = setTimeout(function() { + clearTimeout(t); + var e = tt(".j_sk_list li:first-child img").width(), + n = tt(".j_sk_list li:first-child img").height(); + tt(".j_sk_list").find("img").each(function() { + var t = tt(this); + t.attr("data-src") && t.css({ + width: e + "px", + height: n + "px" + }) + }) + }, + 0) + } + function e() { + c && t(), + c = !1; + var e = ut.scrollLeft(); + a || (n.each(function() { + var t = tt(this), + n = t.offset().left, + r = n + t.width(), + i = n - e, + o = r - e; (i <= window.innerWidth && i >= 0 || o <= window.innerWidth && o >= 0) && t.find("img").each(function() { + var t = tt(this); + t.attr("data-src") && t.attr("src", t.attr("data-src")).removeAttr("data-src") + }) + }), ut.find("img[data-src]").length || (a = !0)), + e + ut.width() + 5 >= tt(".j_sk_list").width() ? (s = !0, o && clearTimeout(o), o = setTimeout(function() { + clearTimeout(o), + s && tt(".j_scroll_more_sec_link").click() + }, + 200)) : s = !1 + } + if (ut.length) { + var n = tt(".j_sk_list li"), + r = 0, + i = ut.offset().width / 4.65; + n.each(function() { + tt(this).hasClass("seckill-all-item") ? r += tt(this).width() : (tt(this).width(i), r += i) + }), + tt(".j_sk_list").css({ + width: r + 5 + }), + ut.unbind("scroll", e).scroll(e); + var o, a = !1, + s = !1, + c = !0, + u = H(); + tt(".j_sec_order").text(u.name), + tt(".j_more_sec_link").each(function() { + tt(this).attr("jump-href", dt) + }); + var l = u.endTime, + f = l - (new Date).getTime(), + p = setInterval(function() { + f <= 0 && clearInterval(p), + f -= 1e3; + var t = z(f); + tt(".j_sk_h").text(t.h), + tt(".j_sk_m").text(t.m), + tt(".j_sk_s").text(t.s) + }, + 1e3) + } + } + function z(t) { + t /= 1e3; + var e = t / 3600, + n = t % 3600 / 60, + r = t % 60; + return { + h: Math.floor(e) < 10 ? "0" + Math.floor(e) : Math.floor(e), + s: Math.floor(r) < 10 ? "0" + Math.floor(r) : Math.floor(r), + m: Math.floor(n) < 10 ? "0" + Math.floor(n) : Math.floor(n) + } + } + function V(t) { + var e = JD.url.getHashParam("st"); + e && parseInt(e) > 0 && ft.scrollTop(parseInt(e)), + (tt("body").offset().height >= parseInt(e) || t) && I("st"), + G() + } + function G() { + var t = JD.url.getHashParam("sksLeft"), + e = t ? parseInt(t) / 2 : 0, + n = 0; + I("sksLeft"); + var r = setInterval(function() { + n += e, + n >= parseInt(t) && clearInterval(r), + t && ut.length && ut.scrollLeft(n) + }, + 50) + } + function X() { + var t = nt.get("warehistory"); + t = t.replace(/"/g, "").split(",").filter(function(t) { + return /^[0-9]+$/.test(t) + }).slice(0, 4), + $({ + eventId: "MHome_PageExpo", + eventParam: "null_A1_" + (4 === t.length ? "B2": "A2") + }) + } + function Y() { + var t, e, n, r; + t = tt(".j_slide_li").length > 0, + r = tt(".j_app_box").length > 0, + e = tt(".j_sk_li").length > 0, + n = tt(".j_scroll_news li").length > 0; + var i = ""; + t || (i += ";首焦展示异常"), + r || (i += ";百宝箱展示异常"), + n || (i += ";京东快报展示异常"), + e || (i += ";京东秒杀展示异常"), + t && r && e && n ? v(3, 0, "m首页首屏展示正常") : v(3, 1, "m首页首屏展示异常," + i) + } + function K() { + Y(), + A(), + r(), + s(), + a(), + R(), + c(), + W(), + N(), + X(); + try { + setTimeout(i, 0) + } catch(t) { + console.error("【抓图通栏】", t) + } + try { + setTimeout(o, 0) + } catch(t) { + console.error("【东家小院灰度跳转】", t) + } + ot.autoLoadImage({ + container: "floorContent", + skip_invisible: !0 + }) + } + var Z = n(29), + Q = function(t) { + return t && t.__esModule ? t: { + default: + t + } + } (Z), + tt = n(15), + et = n(76), + nt = n(42), + rt = n(77), + it = n(78), + ot = n(79), + at = (n(81), n(82)), + st = "expo_loaded", + ct = 250, + ut = tt(".j_sk_wrapper"), + lt = !(!_cookiePtKey || !_cookiePtPin), + ft = tt(window), + pt = !1, + ht = !1, + dt = "//wqs.jd.com/portal/wx/seckill_m/index.shtml", + mt = !1, + vt = { + paicon: { + 1 : "满减", + 2 : "券", + 3 : "闪购", + 4 : "新品", + 5 : "秒杀", + 6 : "拼购" + }, + dbicon: { + 1 : "sam-price", + 2 : "plus-price", + 3 : "rec-seckill-price" + } + }, + gt = !1; + window._PFM_TIMING && (window._PFM_TIMING[3] = new Date), + function() { + K(), + L() + } () +}, +function(t, e, n) { + var r = n(1), + i = r.JSON || (r.JSON = { + stringify: JSON.stringify + }); + t.exports = function(t) { + return i.stringify.apply(i, arguments) + } +}, +function(t, e, n) { + t.exports = { + default: + n(46), + __esModule: !0 + } +}, +function(t, e, n) { + n(47), + n(58), + t.exports = n(26).f("iterator") +}, +function(t, e, n) { + "use strict"; + var r = n(48)(!0); + n(30)(String, "String", + function(t) { + this._t = String(t), + this._i = 0 + }, + function() { + var t, e = this._t, + n = this._i; + return n >= e.length ? { + value: void 0, + done: !0 + }: (t = r(e, n), this._i += t.length, { + value: t, + done: !1 + }) + }) +}, +function(t, e, n) { + var r = n(16), + i = n(17); + t.exports = function(t) { + return function(e, n) { + var o, a, s = String(i(e)), + c = r(n), + u = s.length; + return c < 0 || c >= u ? t ? "": void 0 : (o = s.charCodeAt(c), o < 55296 || o > 56319 || c + 1 === u || (a = s.charCodeAt(c + 1)) < 56320 || a > 57343 ? t ? s.charAt(c) : o: t ? s.slice(c, c + 2) : a - 56320 + (o - 55296 << 10) + 65536) + } + } +}, +function(t, e, n) { + var r = n(50); + t.exports = function(t, e, n) { + if (r(t), void 0 === e) return t; + switch (n) { + case 1: + return function(n) { + return t.call(e, n) + }; + case 2: + return function(n, r) { + return t.call(e, n, r) + }; + case 3: + return function(n, r, i) { + return t.call(e, n, r, i) + } + } + return function() { + return t.apply(e, arguments) + } + } +}, +function(t, e) { + t.exports = function(t) { + if ("function" != typeof t) throw TypeError(t + " is not a function!"); + return t + } +}, +function(t, e, n) { + "use strict"; + var r = n(34), + i = n(13), + o = n(25), + a = {}; + n(3)(a, n(7)("iterator"), + function() { + return this + }), + t.exports = function(t, e, n) { + t.prototype = r(a, { + next: i(1, n) + }), + o(t, e + " Iterator") + } +}, +function(t, e, n) { + var r = n(4), + i = n(12), + o = n(21); + t.exports = n(5) ? Object.defineProperties: function(t, e) { + i(t); + for (var n, a = o(e), s = a.length, c = 0; s > c;) r.f(t, n = a[c++], e[n]); + return t + } +}, +function(t, e, n) { + var r = n(36); + t.exports = Object("z").propertyIsEnumerable(0) ? Object: function(t) { + return "String" == r(t) ? t.split("") : Object(t) + } +}, +function(t, e, n) { + var r = n(6), + i = n(55), + o = n(56); + t.exports = function(t) { + return function(e, n, a) { + var s, c = r(e), + u = i(c.length), + l = o(a, u); + if (t && n != n) { + for (; u > l;) if ((s = c[l++]) != s) return ! 0 + } else for (; u > l; l++) if ((t || l in c) && c[l] === n) return t || l || 0; + return ! t && -1 + } + } +}, +function(t, e, n) { + var r = n(16), + i = Math.min; + t.exports = function(t) { + return t > 0 ? i(r(t), 9007199254740991) : 0 + } +}, +function(t, e, n) { + var r = n(16), + i = Math.max, + o = Math.min; + t.exports = function(t, e) { + return t = r(t), + t < 0 ? i(t + e, 0) : o(t, e) + } +}, +function(t, e, n) { + var r = n(0).document; + t.exports = r && r.documentElement +}, +function(t, e, n) { + n(59); + for (var r = n(0), i = n(3), o = n(20), a = n(7)("toStringTag"), s = "CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","), c = 0; c < s.length; c++) { + var u = s[c], + l = r[u], + f = l && l.prototype; + f && !f[a] && i(f, a, u), + o[u] = o.Array + } +}, +function(t, e, n) { + "use strict"; + var r = n(60), + i = n(61), + o = n(20), + a = n(6); + t.exports = n(30)(Array, "Array", + function(t, e) { + this._t = a(t), + this._i = 0, + this._k = e + }, + function() { + var t = this._t, + e = this._k, + n = this._i++; + return ! t || n >= t.length ? (this._t = void 0, i(1)) : "keys" == e ? i(0, n) : "values" == e ? i(0, t[n]) : i(0, [n, t[n]]) + }, + "values"), + o.Arguments = o.Array, + r("keys"), + r("values"), + r("entries") +}, +function(t, e) { + t.exports = function() {} +}, +function(t, e) { + t.exports = function(t, e) { + return { + value: e, + done: !!t + } + } +}, +function(t, e, n) { + t.exports = { + default: + n(63), + __esModule: !0 + } +}, +function(t, e, n) { + n(64), + n(70), + n(71), + n(72), + t.exports = n(1).Symbol +}, +function(t, e, n) { + "use strict"; + var r = n(0), + i = n(2), + o = n(5), + a = n(18), + s = n(33), + c = n(65).KEY, + u = n(9), + l = n(23), + f = n(25), + p = n(14), + h = n(7), + d = n(26), + m = n(27), + v = n(66), + g = n(67), + y = n(12), + w = n(8), + b = n(6), + _ = n(19), + x = n(13), + j = n(34), + T = n(68), + k = n(69), + S = n(4), + E = n(21), + C = k.f, + O = S.f, + D = T.f, + I = r.Symbol, + M = r.JSON, + P = M && M.stringify, + A = h("_hidden"), + L = h("toPrimitive"), + N = {}.propertyIsEnumerable, + F = l("symbol-registry"), + R = l("symbols"), + q = l("op-symbols"), + J = Object.prototype, + $ = "function" == typeof I, + U = r.QObject, + B = !U || !U.prototype || !U.prototype.findChild, + H = o && u(function() { + return 7 != j(O({}, + "a", { + get: function() { + return O(this, "a", { + value: 7 + }).a + } + })).a + }) ? + function(t, e, n) { + var r = C(J, e); + r && delete J[e], + O(t, e, n), + r && t !== J && O(J, e, r) + }: O, + W = function(t) { + var e = R[t] = j(I.prototype); + return e._k = t, + e + }, + z = $ && "symbol" == typeof I.iterator ? + function(t) { + return "symbol" == typeof t + }: function(t) { + return t instanceof I + }, + V = function(t, e, n) { + return t === J && V(q, e, n), + y(t), + e = _(e, !0), + y(n), + i(R, e) ? (n.enumerable ? (i(t, A) && t[A][e] && (t[A][e] = !1), n = j(n, { + enumerable: x(0, !1) + })) : (i(t, A) || O(t, A, x(1, {})), t[A][e] = !0), H(t, e, n)) : O(t, e, n) + }, + G = function(t, e) { + y(t); + for (var n, r = v(e = b(e)), i = 0, o = r.length; o > i;) V(t, n = r[i++], e[n]); + return t + }, + X = function(t, e) { + return void 0 === e ? j(t) : G(j(t), e) + }, + Y = function(t) { + var e = N.call(this, t = _(t, !0)); + return ! (this === J && i(R, t) && !i(q, t)) && (!(e || !i(this, t) || !i(R, t) || i(this, A) && this[A][t]) || e) + }, + K = function(t, e) { + if (t = b(t), e = _(e, !0), t !== J || !i(R, e) || i(q, e)) { + var n = C(t, e); + return ! n || !i(R, e) || i(t, A) && t[A][e] || (n.enumerable = !0), + n + } + }, + Z = function(t) { + for (var e, n = D(b(t)), r = [], o = 0; n.length > o;) i(R, e = n[o++]) || e == A || e == c || r.push(e); + return r + }, + Q = function(t) { + for (var e, n = t === J, + r = D(n ? q: b(t)), o = [], a = 0; r.length > a;) ! i(R, e = r[a++]) || n && !i(J, e) || o.push(R[e]); + return o + }; + $ || (I = function() { + if (this instanceof I) throw TypeError("Symbol is not a constructor!"); + var t = p(arguments.length > 0 ? arguments[0] : void 0), + e = function(n) { + this === J && e.call(q, n), + i(this, A) && i(this[A], t) && (this[A][t] = !1), + H(this, t, x(1, n)) + }; + return o && B && H(J, t, { + configurable: !0, + set: e + }), + W(t) + }, + s(I.prototype, "toString", + function() { + return this._k + }), k.f = K, S.f = V, n(40).f = T.f = Z, n(28).f = Y, n(39).f = Q, o && !n(11) && s(J, "propertyIsEnumerable", Y, !0), d.f = function(t) { + return W(h(t)) + }), + a(a.G + a.W + a.F * !$, { + Symbol: I + }); + for (var tt = "hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","), et = 0; tt.length > et;) h(tt[et++]); + for (var nt = E(h.store), rt = 0; nt.length > rt;) m(nt[rt++]); + a(a.S + a.F * !$, "Symbol", { + for: function(t) { + return i(F, t += "") ? F[t] : F[t] = I(t) + }, + keyFor: function(t) { + if (!z(t)) throw TypeError(t + " is not a symbol!"); + for (var e in F) if (F[e] === t) return e + }, + useSetter: function() { + B = !0 + }, + useSimple: function() { + B = !1 + } + }), + a(a.S + a.F * !$, "Object", { + create: X, + defineProperty: V, + defineProperties: G, + getOwnPropertyDescriptor: K, + getOwnPropertyNames: Z, + getOwnPropertySymbols: Q + }), + M && a(a.S + a.F * (!$ || u(function() { + var t = I(); + return "[null]" != P([t]) || "{}" != P({ + a: t + }) || "{}" != P(Object(t)) + })), "JSON", { + stringify: function(t) { + for (var e, n, r = [t], i = 1; arguments.length > i;) r.push(arguments[i++]); + if (n = e = r[1], (w(e) || void 0 !== t) && !z(t)) return g(e) || (e = function(t, e) { + if ("function" == typeof n && (e = n.call(this, t, e)), !z(e)) return e + }), + r[1] = e, + P.apply(M, r) + } + }), + I.prototype[L] || n(3)(I.prototype, L, I.prototype.valueOf), + f(I, "Symbol"), + f(Math, "Math", !0), + f(r.JSON, "JSON", !0) +}, +function(t, e, n) { + var r = n(14)("meta"), + i = n(8), + o = n(2), + a = n(4).f, + s = 0, + c = Object.isExtensible || + function() { + return ! 0 + }, + u = !n(9)(function() { + return c(Object.preventExtensions({})) + }), + l = function(t) { + a(t, r, { + value: { + i: "O" + ++s, + w: {} + } + }) + }, + f = function(t, e) { + if (!i(t)) return "symbol" == typeof t ? t: ("string" == typeof t ? "S": "P") + t; + if (!o(t, r)) { + if (!c(t)) return "F"; + if (!e) return "E"; + l(t) + } + return t[r].i + }, + p = function(t, e) { + if (!o(t, r)) { + if (!c(t)) return ! 0; + if (!e) return ! 1; + l(t) + } + return t[r].w + }, + h = function(t) { + return u && d.NEED && c(t) && !o(t, r) && l(t), + t + }, + d = t.exports = { + KEY: r, + NEED: !1, + fastKey: f, + getWeak: p, + onFreeze: h + } +}, +function(t, e, n) { + var r = n(21), + i = n(39), + o = n(28); + t.exports = function(t) { + var e = r(t), + n = i.f; + if (n) for (var a, s = n(t), c = o.f, u = 0; s.length > u;) c.call(t, a = s[u++]) && e.push(a); + return e + } +}, +function(t, e, n) { + var r = n(36); + t.exports = Array.isArray || + function(t) { + return "Array" == r(t) + } +}, +function(t, e, n) { + var r = n(6), + i = n(40).f, + o = {}.toString, + a = "object" == typeof window && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [], + s = function(t) { + try { + return i(t) + } catch(t) { + return a.slice() + } + }; + t.exports.f = function(t) { + return a && "[object Window]" == o.call(t) ? s(t) : i(r(t)) + } +}, +function(t, e, n) { + var r = n(28), + i = n(13), + o = n(6), + a = n(19), + s = n(2), + c = n(31), + u = Object.getOwnPropertyDescriptor; + e.f = n(5) ? u: function(t, e) { + if (t = o(t), e = a(e, !0), c) try { + return u(t, e) + } catch(t) {} + if (s(t, e)) return i(!r.f.call(t, e), t[e]) + } +}, +function(t, e) {}, +function(t, e, n) { + n(27)("asyncIterator") +}, +function(t, e, n) { + n(27)("observable") +}, +function(t, e, n) { + n(74), + t.exports = n(1).Object.getPrototypeOf +}, +function(t, e, n) { + var r = n(38), + i = n(37); + n(75)("getPrototypeOf", + function() { + return function(t) { + return i(r(t)) + } + }) +}, +function(t, e, n) { + var r = n(18), + i = n(1), + o = n(9); + t.exports = function(t, e) { + var n = (i.Object || {})[t] || Object[t], + a = {}; + a[t] = e(n), + r(r.S + r.F * o(function() { + n(1) + }), "Object", a) + } +}, +function(t, e, n) { + "use strict"; + var r = n(15), + i = function(t) { + if (this.opt = { + tp: "text", + moveDom: null, + moveChild: [], + tab: [], + viewDom: null, + touchDom2: [], + sp: { + x: 0, + y: 0 + }, + min: 0, + minp: 0, + step: 0, + len: 1, + index: 1, + offset: 0, + loadImg: !1, + image: [], + loopScroll: !1, + lockScrY: !1, + stopOnce: !1, + autoTime: 0, + holdAuto: !1, + tabClass: "cur", + transition: .3, + imgInit: !0, + imgInitLazy: 4e3, + enableTransX: !1, + transXVal: 100, + useVue: !1, + ignoreAppend: !1, + fun: function() {} + }, + r.extend(this, this.opt, t), this.len = this.moveChild.length, this.min = this.min || { + text: 100, + img: 1 + } [this.tp], this.minp = this.minp || Math.max(this.min, 30), this.viewDom || (this.viewDom = r(window)), this.len > 1 && this.startEvent(), this.loadImg && (this.image = this.moveDom.find("img")), this.resize(this.step || this.moveChild.eq(0).width()), this.autoTime) { + var e = this; + setInterval(function() { + e.holdAuto || (e.stopOnce || e.stepMove(e.index + 1), e.stopOnce = !1) + }, + this.autoTime) + } + }; + r.extend(i.prototype, { + resize: function(t) { + this.step = t || this.step; + var e = (this.viewDom.width() - this.step) / 2; + this.offset = this.loopScroll ? this.step - e: e, + 1 == this.len && (this.offset = -e), + this.stepMove(this.index, !0) + }, + addChild: function(t, e) { + this.loopScroll && (this.moveChild.eq(0).after(t), this.len += 1, this.tab.eq(this.len - 2).after(e), this.tab = this.tab.parent().children(), 2 == this.len ? (this.moveChild = this.moveDom.children(), this.startEvent()) : this.stepMove(2)) + }, + startEvent: function() { + var t = this, + e = this.moveDom.get(0), + n = function(e) { + e.addEventListener("touchstart", t, !1), + e.addEventListener("touchmove", t, !1), + e.addEventListener("touchend", t, !1), + e.addEventListener("touchcancel", t, !1), + e.addEventListener("webkitTransitionEnd", t, !1) + }; + if (n(e), this.tab.each(function(e, n) { + r(n).attr("no", e + 1), + r(n).click(function() { + t.stepMove(r(this).attr("no")) + }) + }), this.loopScroll) { + var i = this.moveChild.eq(0).clone().attr({ + id: "", + onload: "" + }); + i.find("img").attr({ + id: "", + onload: "" + }), + !this.ignoreAppend && this.moveDom.append(i); + var o = this.moveChild.eq(this.len - 1).clone().attr({ + id: "", + onload: "" + }); + o.find("img").attr({ + id: "", + onload: "" + }), + !this.ignoreAppend && this.moveDom.prepend(o) + } + for (var a = 0; a < this.touchDom2.length; a++) n(this.touchDom2[a]) + }, + handleEvent: function(t) { + switch (t.type) { + case "touchstart": + this.sp = this.getPosition(t), + this.holdAuto = !0, + this.stopOnce = !0; + break; + case "touchmove": + this.touchmove(t); + break; + case "touchend": + case "touchcancel": + this.move(t), + this.holdAuto = !1; + break; + case "webkitTransitionEnd": + t.preventDefault() + } + }, + getPosition: function(t) { + var e = t.changedTouches ? t.changedTouches[0] : t; + return { + x: e.pageX, + y: e.pageY + } + }, + touchmove: function(t) { + var e = this.getPosition(t), + n = e.x - this.sp.x, + r = e.y - this.sp.y; + if (Math.abs(n) - Math.abs(r) > this.min) { + t.preventDefault(); + var i = n - this.step * (this.index - 1) - this.offset; ! this.useVue && this.moveDom.css({ + "-webkit-backface-visibility": "hidden", + "-webkit-transform": this.enableTransX ? "translateX(" + (this.loopScroll ? this.index: this.index - 1) * -this.transXVal + "%)": "translate3D(" + i + "px,0,0)", + "-webkit-transition": "0" + }) + } else this.lockScrY || t.preventDefault() + }, + move: function(t) { + var e = this.getPosition(t), + n = e.x - this.sp.x, + r = e.y - this.sp.y; + if (Math.abs(n) < Math.abs(r) || Math.abs(n) < this.minp) return void this.stepMove(this.index); + n > 0 ? (t.preventDefault(), this.stepMove(this.index - 1)) : (t.preventDefault(), this.stepMove(this.index + 1)) + }, + loadImage: function(t) { + var e = this.image, + n = function(t) { + e[t] && r(e[t]).attr("back_src") && (e[t].src = r(e[t]).attr("back_src"), r(e[t]).removeAttr("back_src")) + }; + n(t), + function(t, e, r) { + setTimeout(function() { + n(t - 1), + n(t + 1) + }, + e ? r: 0) + } (t, this.imgInit, this.imgInitLazy), + this.imgInit = !1 + }, + stepMove: function(t, e) { + this.index = t > this.len ? this.len: t < 1 ? 1 : t, + this.tab.removeClass(this.tabClass), + this.tab.eq(this.index - 1).addClass(this.tabClass); + var n = -this.step * ((this.loopScroll ? t: this.index) - 1) - this.offset; + if (!this.useVue && this.moveDom.css({ + "-webkit-transform": this.enableTransX ? "translateX(" + (this.loopScroll ? t: this.index - 1) * -this.transXVal + "%)": "translate3D(" + n + "px,0,0)", + "-webkit-transition": e ? "0ms": "all " + this.transition + "s ease" + }), this.loadImg && this.loadImage(this.index), this.fun(this.index), this.loopScroll && !e) { + var r = this, + i = t; + t <= 0 && (i = this.len), + t > this.len && (i = 1), + i != t && setTimeout(function() { + r.stepMove(i, !0) + }, + 1e3 * this.transition) + } + }, + _isOutScreen: function(t) { + return t.offset().top >= r(window).height() + window.scrollY || t.offset().top + t.height() < window.scrollY + }, + _isElementHidden: function(t) { + var e = t.parents().concat(); + return e.unshift(t[0]), + e.some(function(t) { + if ("none" == getComputedStyle(t, "").getPropertyValue("display")) return ! 0 + }) + } + }), + e.init = function(t) { + return new i(t) + } +}, +function(t, e, n) { + "use strict"; + function r(t) { + for (var e = (t + "").split(""), n = [], r = 0; r < e.length; r++) n.push(m[e[r]]); + return n.join("") + } + function i(t) { + return d[t] ? d[t] += 1 : d[t] = 1, + t + r(d[t]) + } + function o(t) { + return t.indexOf("wq.360buyimg.com") > -1 || t.indexOf("wqs.jd.com") > -1 || t.indexOf("wqcoss.jd.com/mcoss/") > -1 || t.indexOf("btshow.jd.com/queryBtPlanInfo.do") > -1 || t.indexOf("storage.360buyimg.com") > -1 + } + function a(t, e) { + var n, r = { + onLoad: null, + onError: null, + onTimeout: null, + timeout: 8e3, + isToken: !0, + keepProtocol: !1, + charset: "utf-8", + setReportUrl: "" + }, + a = function() { + d && (n && clearTimeout(n), d.onload = d.onreadystatechange = d.onerror = null, d.parentNode && d.parentNode.removeChild(d), d = null) + }; + if (1 == arguments.length && ("object" == (0, f. + default)(arguments[0]) ? (e = arguments[0], t = e.url) : e = {}), "object" == (0, f. + default)(e.data)) { + var c = []; + for (var u in e.data) c.push(u + "=" + e.data[u]); + c.length > 0 && (c = c.join("&"), t += (t.indexOf("?") > 0 ? "&": "?") + c) + } + if (window.traceid) { + var l = t.split("#"); + t += (l[0].indexOf("?") > 0 ? "&": "?") + "traceid=" + window.traceid + (l[1] ? "#" + l[1] : "") + } + for (var p in e) e.hasOwnProperty(p) && (r[p] = e[p]); + var d = document.createElement("script"); + d.charset = r.charset || "utf-8"; + var m = !1, + v = !1, + g = ""; + e.setReportUrl && "function" == typeof e.setReportUrl ? !(g = e.setReportUrl()) && (g = t) : g = window.CGI302ReportKeepUrl ? t: t.replace(/\?.*/, ""), + d.onload = d.onreadystatechange = function() { (/loaded|complete/i.test(this.readyState) || -1 == navigator.userAgent.toLowerCase().indexOf("msie")) && (r.onLoad && r.onLoad(), m && !v && (window.JD && h.report.umpBiz({ + bizid: 24, + operation: 3, + result: "1", + source: 0, + message: g + }), r.onError && r.onError(), window.onerror("", "", "", "", { + stack: "servererror:" + g + }), console.log("loadJs Failed:" + t)), a()) + }, + d.onerror = function() { + window.__reloadResource && window.__reloadResource(d), + r.onError && r.onError(), + a() + }; + var y = r.isToken ? s(t, "ls") : t; + if (!o(y)) { + var w, b, _, x = y.replace(/callback=([^&]+)/, + function(t, e) { + return w = e, + "callback=" + (b = i(w)) + }); + w && window[w] && (m = !0, y = x, _ = window[w], window[b] = function(t) { + v = !0, + _(t) + }) + } + window.JD && (y = h.url.getCgiUrl(y)), + d.src = r.keepProtocol ? y: y.replace(/^http(s?):/, ""), + !e.cancleLog && console.log("loadJs request:" + d.src), + document.getElementsByTagName("head")[0].appendChild(d), + "function" == typeof r.onTimeout && (n = setTimeout(function() { + r.onTimeout() + }, + r.timeout)) + } + function s(t, e) { + if ("" == t || 0 != (t.indexOf("://") < 0 ? location.href: t).indexOf("http")) return t; + var n = c("wq_skey"), + r = c("pt_key"), + i = t.split("#"), + o = i[0].split("?"), + a = o[0], + s = (2 == o.length ? o[1] : "").split("&"), + u = 2 == i.length ? i[1] : ""; + s = s.filter(function(t) { + return ! (/g_tk=\d+/.test(t) || /g_pt_tk=\d+/.test(t) || /g_ty=\w+/.test(t)) + }), + n && s.push("g_tk=" + n), + r && s.push("g_pt_tk=" + r), + (n || r) && s.push("g_ty=" + e); + var l = s.join("&"); + return a + (l ? "?" + l: "") + (u ? "#" + u: "") + } + function c(t) { + t = t || "wq_skey"; + var e = p.get(t); + return e ? u(e) : "" + } + function u(t) { + for (var e = 0, + n = t.length, + r = 5381; e < n; ++e) r += (r << 5) + t.charAt(e).charCodeAt(); + return 2147483647 & r + } + var l = n(10), + f = function(t) { + return t && t.__esModule ? t: { + default: + t + } + } (l), + p = n(42), + h = window.JD, + d = {}, + m = ["Z", "A", "B", "C", "D", "E", "F", "G", "H", "I"]; + t.exports = e = {}, + e.loadScript = function(t, e) { + var n = [].slice.call(arguments); + setTimeout(function() { + a.apply(null, n) + }, + 0) + }, + e.addToken = s +}, +function(t, e, n) { + "use strict"; + var r = {}, + i = function t(e, n) { + var i = /\W/.test(e) ? new Function("obj", "var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('" + e.replace(/[\r\t\n]/g, " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'") + "');}return p.join('');") : r[e] = r[e] || t(document.getElementById(e).innerHTML); + return n ? i(n) : i + }; + e.formatJson = i +}, +function(t, e, n) { + "use strict"; + function r() { + var t = [" <style>", " .ll_fadeIn{", " -webkit-transition: opacity .5s ease-in;", " opacity:0;", " transition:opacity .5s ease-in;", " }", " </style>"].join(""); + i("head").append(t) + } + var i = n(15), + o = n(80).withinviewport, + a = {}; + a.autoLoadImage = function(t) { + function e() { + i("img[" + c.initSrcName + "]").each(function(t, e) { + var n = i(e), + r = !n.is(":hidden") && o(e, { + top: c.top, + bottom: c.bottom, + left: c.left, + right: c.right + }); + if (c.fadeIn && !n.hasClass("ll_fadeIn") && n.addClass("ll_fadeIn"), r) { + n.on("load", + function() { + c.fadeIn && n.css({ + opacity: 1 + }), + c.afterImgLoaded && c.afterImgLoaded(n) + }), + n.attr("onerror", "__reloadResource(this)"); + var a = n.attr(c.initSrcName); + if (window.JD) { + var s = n.attr("data-size") || "", + u = 0, + l = 0; + /^(\d+)x(\d+)$/i.test(s) && (u = RegExp.$1, l = RegExp.$2, a = JD.img.getImgUrl(a, u, l)), + a = JD.url.getImageUrl(a, u, l) + } + n.attr("src", a), + n.attr(c.initSrcName, null), + n.attr("loaded", 1) + } + }) + } + var n = i(window).height(), + s = i(window).width(), + c = { + top: -.5 * n, + bottom: -1 * n, + left: -.5 * s, + right: -.5 * s, + initSrcName: "init_src", + fadeIn: !0, + afterImgLoaded: null + }; + a.init || (a.init = !0, i.extend(c, t || {}), r(), setInterval(e, 150)) + }, + t.exports = a +}, +function(t, e, n) { + "use strict"; + var r = n(10), + i = function(t) { + return t && t.__esModule ? t: { + default: + t + } + } (r), + o = void 0 !== window.innerHeight, + a = function t(e, n) { + var r, a, s, c, u, l, f, p, h, d, m, v = !1, + g = {}, + y = {}, + w = [0, 0]; + if ("undefined" != typeof jQuery && e instanceof jQuery && (e = e.get(0)), "object" !== (void 0 === e ? "undefined": (0, i. + default)(e)) || 1 !== e.nodeType) throw new Error("First argument must be an element"); + for (e.getAttribute("data-withinviewport-settings") && window.JSON && (g = JSON.parse(e.getAttribute("data-withinviewport-settings"))), r = "string" == typeof n ? { + sides: n + }: n || {}, + y.container = r.container || g.container || t.defaults.container || window, y.sides = r.sides || g.sides || t.defaults.sides || "all", y.top = r.top || g.top || t.defaults.top || 0, y.right = r.right || g.right || t.defaults.right || 0, y.bottom = r.bottom || g.bottom || t.defaults.bottom || 0, y.left = r.left || g.left || t.defaults.left || 0, "undefined" != typeof jQuery && y.container instanceof jQuery && (y.container = y.container.get(0)), y.container !== document.body && 1 !== !y.container.nodeType || (y.container = window), s = y.container === window, a = { + top: function() { + return s ? c.top >= y.top: c.top >= l - (l - u.top) + y.top + }, + right: function() { + return s ? c.right <= u.right + f - y.right: c.right <= u.right - w[0] - y.right + }, + bottom: function() { + var t; + return t = s ? o ? y.container.innerHeight: document.documentElement.clientHeight: u.bottom, + c.bottom <= t - w[1] - y.bottom + }, + left: function() { + return s ? c.left >= y.left: c.left >= f - (f - u.left) + y.left + }, + all: function() { + return a.top() && a.bottom() && a.left() && a.right() + } + }, + c = e.getBoundingClientRect(), s ? (u = document.documentElement.getBoundingClientRect(), l = document.body.scrollTop, f = document.body.scrollLeft) : (u = y.container.getBoundingClientRect(), l = y.container.scrollTop, f = y.container.scrollLeft), f && (w[0] = 18), l && (w[1] = 16), p = /^top$|^right$|^bottom$|^left$|^all$/, h = y.sides.split(" "), m = h.length; m--;) if (d = h[m].toLowerCase(), p.test(d)) { + if (!a[d]()) { + v = !1; + break + } + v = !0 + } + return v + }; + a.prototype.defaults = { + container: document.body, + sides: "all", + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + a.defaults = a.prototype.defaults, + a.prototype.top = function(t) { + return a(t, "top") + }, + a.prototype.right = function(t) { + return a(t, "right") + }, + a.prototype.bottom = function(t) { + return a(t, "bottom") + }, + a.prototype.left = function(t) { + return a(t, "left") + }, + e.withinviewport = a +}, +function(t, e, n) { + "use strict"; + function r(t) { + if (!t) return ! 1; + var e = t; + for (var n in M) void 0 === e[n] && (e[n] = M[n]); + if (e.globalLock) { + if (j) return console.log("ajax loading ..."), + e.lockCallback && e.lockCallback(), + !1; + j = !0 + } + if (e.cgiKey && (window.cgiData = I), e.cgiKey && I[e.cgiKey]) return console.log("ajax命中临时缓存"), + e.isCache = 1, + u(I[e.cgiKey], "", e), + !1; + "ppms.jd.com" == location.hostname && (e.dataType = "jsonp"), + e.url = e.url.replace(/^http:/, ""), + e.setReportUrl && "function" == typeof e.setReportUrl ? !(F = e.setReportUrl()) && (F = e.url) : F = window.CGI302ReportKeepUrl ? e.url: e.url.replace(/\?.*/, ""), + e.crossDomain || (e.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(e.url) && RegExp.$2 != window.location.host), + e.crossDomain && (e.xhrFields = { + withCredentials: !0 + }), + e.url || (e.url = window.location.toString()), + d(e); + var r = e.dataType, + o = /\?.+=\?/.test(e.url); + if (o && (r = "jsonp"), !1 !== e.cache && (t && !0 === t.cache || "script" != r && "jsonp" != r) || (e.url = v(e.url, "_=" + Date.now())), !t.noSceneVal && R && (e.url = v(e.url, "sceneval=" + R)), e.url = v(e.url, "g_login_type=" + J), "jsonp" == r || e.wqunit) return o || (e.urlbak = e.url, e.url = v(e.url, e.jsonp ? e.jsonp + "=?": !1 === e.jsonp ? "": "callback=?")), + e.url = g(e.url, "ls"), + a(e); + if ("post" == e.type.toLowerCase() && e.jsonpCallback) return e.url = g(e.url, "fr"), + s(e); + /[?&]ajaxtest=1/.test(location.search) && "json" == r && (e.url = e.url.replace("http://wq.jd.com", "http://wqs.jd.com")), + e.url = g(e.url, "ajax"), + window.JD && (e.url = T.url.getCgiUrl(e.url)); + var c, f = e.accepts[r], + p = {}, + y = function(t, e) { + p[t.toLowerCase()] = [t, e] + }, + w = /^([\w-]+:)\/\//.test(e.url) ? RegExp.$1: window.location.protocol, + b = e.xhr(), + _ = b.setRequestHeader; + if (e.crossDomain || y("X-Requested-With", "XMLHttpRequest"), y("Accept", f || "*/*"), (f = e.mimeType || f) && (f.indexOf(",") > -1 && (f = f.split(",", 2)[0]), b.overrideMimeType && b.overrideMimeType(f)), (e.contentType || !1 !== e.contentType && e.data && "GET" != e.type.toUpperCase()) && y("Content-Type", e.contentType || "application/x-www-form-urlencoded"), e.headers) for (var x in e.headers) y(x, e.headers[x]); + b.setRequestHeader = y, + b.onreadystatechange = function() { + if (4 == b.readyState) { + b.onreadystatechange = h, + clearTimeout(c); + var t, n = !1; + if (b.status >= 200 && b.status < 300 || 304 == b.status || 0 == b.status && "file:" == w) { + r = r || m(e.mimeType || b.getResponseHeader("content-type")), + t = b.responseText; + try { + "script" == r ? (0, eval)(t) : "xml" == r ? t = b.responseXML: "json" == r && (t = /^\s*$/.test(t) ? null: i(t)) + } catch(t) { + n = t + } + n ? l(n, "parsererror", b, e) : u(t, b, e) + } else console.log("ajax error", b), + l(b.statusText || null, "load", b, e) + } + }; + var k = !("async" in e) || e.async; + if (b.open(e.type, e.url, k, e.username, e.password), e.xhrFields) for (x in e.xhrFields) b[x] = e.xhrFields[x]; + for (x in p) _.apply(b, p[x]); + return e.timeout > 0 && (c = setTimeout(function() { + b.onreadystatechange = h, + b.abort(), + l(null, "timeout", b, e) + }, + 1e3 * e.timeout)), + b.send(e.data ? e.data: null), + b + } + function i(t) { + return t && "string" == typeof t ? (t = t.replace(/^\s+|\s+$/g, ""), t ? JSON.parse(t) : t) : t + } + function o(t, e) { + window.JD && T.sendJs("//wq.jd.com/ubanalysis?t=t_ajax&d=" + q + "&tp=" + e) + } + function a(t) { + var e, n, i = t.jsonpCallback, + a = ("function" == typeof i ? i() : i) || "jsonpCBK" + P.callbackName[P.ajaxCount++%P.callbackName.length], + s = document.createElement("script"), + c = (window[a], { + abort: f + }), + f = function(e) { + p = 1, + q--, + console.log(t.url, "timeout"), + o(q, "timeout"), + l(null, "timeout", c, t) + }, + p = 0; + return t.callbackName = a, + s.charset = t.charset || "utf-8", + q++, + s.onload = s.onerror = function(i, a) { + if (clearTimeout(n), p) return console.log("timeout"), + !1; + q--, + "error" == i.type ? (console.log(t.url, a || i.type || "error"), o(q, "error"), l(null, "error", c, t)) : e ? e[0] && -1 == e[0].retcode && "没有找到" == e[0].message && 1 == e[0].unitReload ? (t.wqunit = !1, t.url = t.urlbak, r(t)) : u(e[0], c, t) : (o(q, "load"), l(null, i.type, c, t), window.onerror("", "", "", "", { + stack: "servererror:" + F + })), + e = void 0, + s.parentNode.removeChild(s) + }, + window[a] = function() { + e = arguments + }, + t.url = t.url.replace(/\?(.+)=\?/, "?$1=" + a), + s.src = t.url, + t.wqunit && (s.src = "http://ppms.jd.com/wqunit/unittest?pageUrl=" + encodeURIComponent(location.href) + "&cgiUrl=" + encodeURIComponent(s.src) + "&callback=" + a), + document.head.appendChild(s), + t.timeout > 0 && (n = setTimeout(function() { + f("timeout") + }, + 1e3 * t.timeout)), + c + } + function s(t) { + var e, n = t.jsonpCallback, + r = ("function" == typeof n ? n() : n) || "jsonpCBK" + A[D++%A.length], + i = { + abort: o + }, + o = function(e) { + a = 1, + console.log(t.url, "timeout"), + l(null, "timeout", i, t) + }, + a = 0; + window[r] = function() { + clearTimeout(e); + var n = arguments, + r = document.getElementById("ajaxPostForm"); + r && r.remove(); + var o = document.getElementById("ajaxPostIframe"); + o && o.remove(), + u(n[0], i, t) + }, + t.data.callback = r, + t.data.g_tk = y(), + c(t, t.isFile), + t.timeout > 0 && (e = setTimeout(function() { + window[r] = h, + o("timeout") + }, + 1e3 * t.timeout)) + } + function c(t, e) { + var n = document.getElementById("ajaxPostForm"), + r = document.getElementById("ajaxPostIframe"); + n || (n = document.createElement("form"), n.id = "ajaxPostForm", r = document.createElement("iframe"), r.height = 0, r.width = 0, r.id = r.name = "ajaxPostIframe", n.style.display = "none", document.body.appendChild(r), document.body.appendChild(n)), + k("input", n).remove(); + for (var i in t.data) { + var o = document.createElement("input"); + k(n).append(k(o).attr("type", "hidden").attr("name", i).attr("value", t.data[i])) + } + n.target = "ajaxPostIframe", + n.action = t.url, + n.method = "POST", + n.enctype = e ? "multipart/form-data": "application/x-www-form-urlencoded", + n.submit() + } + function u(t, e, n) { + n.globalLock && (j = !1); + var r = n.context; + console.log(n.url, t), + n.success.call(r, t, n, "success", e), + p("success", e, n) + } + function l(t, e, n, i, o) { + return i.retryCount <= 0 || "post" == i.type.toLowerCase() ? void f(t, e, n, i) : ["error", "parsererror"].indexOf(e) >= 0 ? void f(t, e, n, i) : void setTimeout(function() { + i.url = i.url.replace(/(&)?(_|g_tk|g_ty|callback)=\w+/g, ""), + console.log("start retry," + i), + i.retryCount--, + i.globalLock && (j = !1), + r(i) + }, + 0) + } + function f(t, e, n, r) { + r.globalLock && (j = !1); + var i = r.context; + console.log(r.url, e, t), + r.degrade && (console.log("降级", r.degrade), r.isDegrade = 1, r.success.call(i, r.degrade, r)); + var o = { + timeout: 8e3, + error: 5e3, + load: 3020, + abort: 5001, + parsererror: 3021 + }; + r.error.call(i, e, o[e] || 9e3, r, t, n), + p(e, n, r) + } + function p(t, e, n) { + var r = n.context; + n.complete.call(r, t, e) + } + function h() {} + function d(t) { + if (t.processData && t.data && "string" != typeof t.data) { + if ("post" == t.type.toLowerCase() && t.jsonpCallback) return; + t.data = x(t.data) + } ! t.data || t.type && "GET" != t.type.toUpperCase() || (t.url = v(t.url, t.data), t.data = void 0) + } + function m(t) { + return t && (t = t.split(";", 2)[0]), + t && (t == S ? "html": t == E ? "json": C.test(t) ? "script": O.test(t) && "xml") || "text" + } + function v(t, e) { + return "" == e ? t: (t + "&" + e).replace(/[&?]{1,2}/, "?") + } + function g(t, e) { + var n = y(); + if ("" == t || 0 != (t.indexOf("://") < 0 ? location.href: t).indexOf("http")) return t; + if ( - 1 != t.indexOf("#")) { + var r = t.match(/\?.+\#/); + if (r) { + var i = r[0].split("#"), + o = [i[0], "&g_tk=", n, "&g_ty=", e, "#", i[1]].join(""); + return t.replace(r[0], o) + } + var i = t.split("#"); + return [i[0], "?g_tk=", n, "&g_ty=", e, "#", i[1]].join("") + } + return "" == n ? t + ( - 1 != t.indexOf("?") ? "&": "?") + "g_ty=" + e: t + ( - 1 != t.indexOf("?") ? "&": "?") + "g_tk=" + n + "&g_ty=" + e + } + function y() { + var t = b("wq_skey"); + return null == t ? "": w(t) + } + function w(t) { + for (var e = 0, + n = t.length, + r = 5381; e < n; ++e) r += (r << 5) + t.charAt(e).charCodeAt(); + return 2147483647 & r + } + function b(t) { + var e = new RegExp("(^| )" + t + "(?:=([^;]*))?(;|$)"), + n = document.cookie.match(e); + return n ? n[2] ? unescape(n[2]) : "": null + } + function _(t, e) { + for (var n in e) t.add(n, e[n]) + } + function x(t) { + var e = []; + return e.add = function(t, e) { + this.push($(t) + "=" + $(e)) + }, + _(e, t), + e.join("&").replace(/%20/g, "+") + } + var j = !1, + T = window.JD, + k = window.$, + S = window.htmlType, + E = window.jsonType, + C = window.scriptTypeRE, + O = window.xmlTypeRE, + D = 0, + I = {}, + M = { + type: "GET", + success: h, + error: h, + complete: h, + load: h, + context: null, + global: !0, + retryCount: 0, + globalLock: 0, + lockCallback: null, + cgiKey: !1, + setCache: function(t) { + if (!this.cgiKey) throw Error("cgiKey不能为空"); + I[this.cgiKey] = t + }, + degrade: !1, + xhr: function() { + return new window.XMLHttpRequest + }, + dataType: "json", + accepts: { + script: "text/javascript, application/javascript, application/x-javascript", + json: "application/json", + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain" + }, + crossDomain: !1, + timeout: 8, + processData: !0, + cache: !1, + wqunit: /[?&]_wqunit_=1/.test(location.search), + setReportUrl: "" + }, + P = ""; + if (window.JD ? (T.ajax || (T.ajax = {}), P = T.ajax) : P = window, !P.callbackName) { + for (var A = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], L = 0; L < 3; L++) for (var N = 0; N < 26; N++) A.push(A[26 * L + N] + A[N]); + P.callbackName = A + } + P.ajaxCount = P.ajaxCount || 0; + var F = "", + R = window.JD && T.url && T.url.getUrlParam("sceneval") || (/(\.|^)m\.jd\.com/.test(window.location.hostname) ? 2 : 0), + q = 0, + J = function() { + var t = navigator.userAgent.toLowerCase(), + e = 0; + return window.JD && T.wxapp && 3 == T.wxapp.wxappType ? e = 1 : R ? e = 1 : /jdapp;/.test(t) && (e = 1), + e + } (), + $ = encodeURIComponent; + window.addEventListener("message", + function(t) { + if (!t || !t.data) return ! 1; + var e = t.data.callback; + e && window[e] && window[e](t.data.data) + }), + t.exports = { + load: r, + addToken: g + } +}, +function(t, e, n) { + "use strict"; + function r(t) { + return t && t.__esModule ? t: { + default: + t + } + } + function i(t) { + return null != t && t == t.window + } + function o(t) { + return null != t && "object" == (void 0 === t ? "undefined": (0, g. + default)(t)) + } + function a(t) { + return o(t) && !i(t) && (0, m. + default)(t) == Object.prototype + } + function s(t, e, n) { + for (var r in e) n && (a(e[r]) || x(e[r])) ? (a(e[r]) && !a(t[r]) && (t[r] = {}), x(e[r]) && !x(t[r]) && (t[r] = []), s(t[r], e[r], n)) : void 0 !== e[r] && (t[r] = e[r]); + return t + } + function c(t) { + if (!t || "string" != typeof t) return t; + if (! (t = t.replace(/^\s+|\s+$/g, ""))) return t; + try { + t = JSON.parse(t) + } catch(t) {} + return t + } + function u(t) { + var e = ""; + try { + e = j.getItem(t) + } catch(t) {} + return e + } + function l(t, e, n, r, i, o) { + if ("function" == typeof i && (o = i, i = !1), "number" == typeof r && (i = r, r = !1), "function" == typeof r && (o = r, r = !1), "function" == typeof n && (o = n, n = !1), "number" == typeof n && (i = n, n = !1), n && (!i || "number" != typeof i)) throw new Error("请设置过期时间"); + j.persistence( !! n), + j.setItem(t, e, r, i, o) + } + function f(t) { + j.removeItem(t) + } + var p = n(29), + h = r(p), + d = n(41), + m = r(d), + v = n(10), + g = r(v), + y = !0, + w = !0, + b = window.JD, + _ = function(t) { + var e, n = "WXSQ_STOARGE_TEST"; + try { + return t.setItem(n, 1), + e = t.getItem(n), + t.removeItem(n), + 1 == e + } catch(t) { + return ! 1 + } + }; + try { + y = _(window.sessionStorage), + w = _(window.localStorage) + } catch(t) { + y = !1, + w = !1 + } + y && w || b.report.umpBiz({ + bizid: 45, + operation: 1, + result: 2, + source: 0, + message: "session " + y + "|local " + w + }); + var x = Array.isArray || + function(t) { + return t instanceof Array + }, + j = function() { + var t = window.sessionStorage, + e = function(t, e, n, r, o) { + var l = c(u("WQ_" + t)); + l && (n && a(e) && a(l.v) || x(e) && x(l.v)) && (e = s(l.v, e, !0)); + var f = { + v: e, + t: (new Date).getTime(), + e: "number" != typeof r ? "": r + }; + i("WQ_" + t, f, o) + }, + n = function(e) { + var n = t.getItem("WQ_" + e); + if (!n) return t.getItem(e); + n = c(n); + var i = n && n.e; + return 0 === i || i && new Date - n.t >= 1e3 * i ? (r(e), "") : n.v + }, + r = function(e) { + try { + t.removeItem("WQ_" + e) + } catch(t) {} + }, + i = function(e, n, r) { + var i = ""; + try { + i = (0, h. + default)(n) + } catch(t) { + throw new Error("JSON数据格式异常:" + t.message) + } + try { + t.setItem(e, i), + r && r(0) + } catch(n) { + r && r(0), + setTimeout(function() { + l(); + try { + t.setItem(e, i) + } catch(t) { + return b.report.umpBiz({ + bizid: 45, + operation: 1, + result: 1, + source: 0, + message: e + "|" + t.message + }), + !1 + } + }, + 0) + } + return ! 0 + }, + o = function(e) { + t = e ? window.localStorage: window.sessionStorage + }, + l = function() { + for (var e = "", + r = t.length - 1; r >= 0; r--) e = t.key(r), + 0 == e.indexOf("WQ_") && n(e.slice("WQ_".length)) + }; + return { + setItem: e, + getItem: n, + removeItem: r, + persistence: o, + clearOut: l + } + } (); + t.exports = { + getItem: function(t, e) { + return j.persistence( !! e), + u(t) + }, + setItem: function(t, e, n, r, i, o) { + return l(t, e, n, r, i, o) + }, + removeItem: function(t, e) { + return j.persistence( !! e), + f(t) + }, + clearOut: function(t) { + j.persistence( !! t), + j.clearOut() + }, + session: { + getItem: function(t) { + return j.persistence(!1), + u(t) + }, + setItem: function(t, e, n, r, i) { + return l(t, e, !1, n, r, i) + }, + removeItem: function(t) { + return j.persistence(!1), + f(t) + }, + clearOut: function() { + j.persistence(!1), + j.clearOut() + } + }, + local: { + getItem: function(t) { + return j.persistence(!0), + u(t) + }, + setItem: function(t, e, n, r, i) { + return l(t, e, !0, n, r, i) + }, + removeItem: function(t) { + return j.persistence(!0), + f(t) + }, + clearOut: function() { + j.persistence(!0), + j.clearOut() + } + } + } +}]); \ No newline at end of file diff --git a/static/app2/js/ac1111next.js b/static/app2/js/ac1111next.js new file mode 100755 index 0000000..0410491 --- /dev/null +++ b/static/app2/js/ac1111next.js @@ -0,0 +1,119 @@ +//添加返回顶部按钮 +document.write('<script type="text/javascript" src="' + localStorage.getItem("jsUrl") + 'scrollToTop.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); +var isjiazai = 1; +var topTypeId = ''; +var type = 1; +var order = 'desc'; +var page = 1; +var pageSize = 10; +var costnum = 0; + +var swiper = new Swiper('#timer_swiper', { + slidesPerView: 3, + paginationClickable: true, + spaceBetween: 0, + freeMode: true +}); + +function getData(topTypeId, type, order, page, pageSize) { + var data_ = { + topTypeId: topTypeId, + type: type ? type : 1, + order: order ? order : 'desc', + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(llUrl('addon/shuff-shuff-moreGoodsList'), {  + data: data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) +// var data = toJson(data); + if(data.status == 1) { + var data = data.data; + var html = ''; + + if(data.Rows == '') { + $('#recommend_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + + }); + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + }else{ +// console.log(data.msg) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  +} + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + topTypeId = self.topTypeId; + + getData(topTypeId, type, order, page, pageSize) + + $('.nav').on('tap', '.nav_block', function() { + type = $(this).attr('data-type'); + isjiazai = 1; + page = 1; + + if(type == 3) { + + costnum += 1; + + if(costnum % 2 == 1) { + + $('.nav_block').eq(2).html('价格 <img src="../img/cost_3.png"/>'); + + order = 'asc'; + + } else if(costnum % 2 == 0) { + + $('.nav_block').eq(2).html('价格 <img src="../img/cost_2.png"/>'); + + order = 'desc'; + + } + + } else { + + $('.nav_block').eq(2).html('价格 <img src="../img/cost_1.png"/>') + + costnum = 0; + order = 'desc'; + } + getData(topTypeId, type, order, page, pageSize); + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(topTypeId, type, order, page, pageSize); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ac1111next_.js b/static/app2/js/ac1111next_.js new file mode 100755 index 0000000..245cffd --- /dev/null +++ b/static/app2/js/ac1111next_.js @@ -0,0 +1,83 @@ +//添加返回顶部按钮 +document.write('<script type="text/javascript" src="' + localStorage.getItem("jsUrl") + 'scrollToTop.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); +var isjiazai = 1; +var topTypeId = ''; +var page = 1; +var pageSize = 10; +var costnum = 0; + +function getData(topTypeId, page, pageSize) { + var data_ = { + goodsName: topTypeId, + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(llUrl('addon/shuff-shuff-appSearch'), {  + data: data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + // var data = toJson(data); + console.log(data.status) + if(data.status == 1) { + var data = data.data; + var html = ''; + + if(data.Rows == '') { + if(page == 1) { + $('#recommend_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } else { + $('#recommend_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + + }); + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + } else { + // console.log(data.msg) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  +} + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + topTypeId = self.data_keyword; + console.log(topTypeId) + + getData(topTypeId, page, pageSize) + + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(topTypeId, page, pageSize); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ac2.js b/static/app2/js/ac2.js new file mode 100755 index 0000000..eae2e41 --- /dev/null +++ b/static/app2/js/ac2.js @@ -0,0 +1,71 @@ +var data_keyword = ''; +var pageSize = 10; +var page = 1; +var topTypeId=1; +var isjiazai = 1; +$('.title').html('更多商品'); +document.write('<link rel="stylesheet" type="text/css" href="' + localStorage.getItem("cssUrl") + 'recommend.css?ver=' + localStorage.getItem("version") + '"/>'); +document.write('<script type="text/javascript" src="' + localStorage.getItem("jsUrl") + 'recommend.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); + +function lxy_search(page, pageSize, data_keyword) { + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + var lxy_data_ = { + goodsName : data_keyword ? data_keyword : '', + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10, + topTypeId:topTypeId + } + + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-inqueryList'), {  + data: lxy_data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + //var data = toJson(data); + var data = data.data + var html = ''; + + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" src="../img/icon_sscl.png"alt=""style="display:none;"/></div>' + }); + + if(page == 1) { + $('.con_').html(html); + } else { + $('.con_').append(html); + } + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  +} + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + data_keyword = self.data_keyword; + if(self.topTypeId){ + topTypeId = self.topTypeId; + } + //console.log(data_keyword); + //console.log(topTypeId) + lxy_search(page, pageSize, data_keyword); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + lxy_search(page, pageSize, data_keyword); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/ac3.js b/static/app2/js/ac3.js new file mode 100755 index 0000000..5ee4ad1 --- /dev/null +++ b/static/app2/js/ac3.js @@ -0,0 +1,73 @@ +$('.title').html('更多'); +document.write('<link rel="stylesheet" type="text/css" href="' + localStorage.getItem("cssUrl") + 'recommend.css?ver=' + localStorage.getItem("version") + '"/>'); +document.write('<script type="text/javascript" src="' + localStorage.getItem("jsUrl") + 'recommend.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); +var page = 1; +var pageSize = 10; +var isjiazai = 1; + +function getData(page, pageSize) { + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + var data_ = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + mui.ajax(llUrl('addon/selfmarket-selfmarket-selfMore'), {  + + data: data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + // var data = toJson(data); + var data = data.data + var html = ''; + if(data.Rows == '') { + + if(page == 1) { + $('.con_').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;margin-top:20px;">没有更多商品</p>'); + } else { + $('.con_').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;margin-top:20px;">没有更多商品</p>'); + } + + isjiazai = 0; + return; + } + + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: inline-block;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" src="../img/icon_sscl.png"alt=""style="display:none;"/></div>' + }); + + if(page == 1) { + $('.con_').html(html); + } else { + $('.con_').append(html); + } + + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  +} + +mui.plusReady(function() { + getData(page, pageSize); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, pageSize); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/activity1.js b/static/app2/js/activity1.js new file mode 100755 index 0000000..31deea1 --- /dev/null +++ b/static/app2/js/activity1.js @@ -0,0 +1,106 @@ +mui.plusReady(function() { + $('#bg').html('<img src="../img/activity1_head.png" />'); + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + data: { + typeSrc: 2 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + $.each(data['6'].list, function(num) { + num++; + if(num % 2 == 1) { + html1 += '<div class="bktj_b" data-goodsId="' + this.goodsId + '"><img src="../img/bktj' + num + '.png" /><div class="bktj_con clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="bktj_con_con"><p class="p3">' + this.goodsName + '</p><p class="p4">折扣到手价</p><p class="p3">¥.' + this.shopPrice + '</p><div class="ljjg_btn ljqg_btn">立即抢购</div></div></div></div>'; + } else { + html1 += '<div class="bktj_b" data-goodsId="' + this.goodsId + '"><img src="../img/bktj' + num + '.png" /><div class="bktj_con clearfix"><div class="bktj_con_con"><p class="p3">' + this.goodsName + '</p><p class="p4">折扣到手价</p><p class="p3">¥.' + this.shopPrice + '</p><div class="ljjg_btn ljqg_btn">立即抢购</div></div><img src="' + hyhImgUrl(this.goodsImg) + '" /></div></div>'; + } + + }); + $('.bktj').html(html1); + $.each(data['7'].list, function() { + html2 += '<div class="xpss_b" data-goodsId="' + this.goodsId + '"><img src="../img/xpss_bg.png" /><div class="xpss_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p5"><del>原价' + this.marketPrice + '</del>' + this.marketPrice + '</p><div class="xpss_ljqg_btn">立即抢购</div></div></div>' + }); + + $('.xpss').html(html2); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.bktj').on('tap', '.bktj_b', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.xpss').on('tap', '.xpss_b', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/activity10.js b/static/app2/js/activity10.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/activity1111.js b/static/app2/js/activity1111.js new file mode 100755 index 0000000..fabd287 --- /dev/null +++ b/static/app2/js/activity1111.js @@ -0,0 +1,288 @@ + +function getData(topTypeId,secTypeId,html_){ + mui.ajax(llUrl('addon/shuff-shuff-actGoodsList'), {  + data:{ + topTypeId:topTypeId, + secTypeId:secTypeId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="accc_block" data-goodsId="'+ this.goodsId +'"><img src="'+ ectImgUrl(this.goodsImg) +'" /><p>'+this.goodsName+'</p><span>'+this.shopPrice+'</span></div>'; + }); + html_.html(html); + html_.find('img').height(html_.find('img').width()) + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + }); +} + +mui.plusReady(function() { + + //双11弹窗 + var lxy_div = '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"><div class="lxy_zz" style="width:100%"><img src="'+ectImgUrl('static/app2/img/to_coupon2.png')+'" /></div></div>'; + + $('body').append(lxy_div); + + //点击让遮罩层消失 + mui('body').on('tap', '#home_zhezhao', function() { + $('#home_zhezhao').css('display', 'none'); + }); + //跳转 + mui('#home_zhezhao').on('tap', '.lxy_zz', function() { + mui.openWindow({ + url: 'god_ect.html', + id: 'god_ect.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }); + + + + + + + //折扣专区 + mui.ajax(llUrl('addon/shuff-shuff-activityList'), {  + data:{ + topTypeId:105 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="acct_block" data-topTypeId="105" data-secTypeId="'+ this.secTypeId +'"><p>'+ this.secTypeName +'</p></div>'; + }); + $('.acc_title').eq(0).html(html); + $('.acc_title').eq(0).find('.acct_block').eq(0).addClass('on'); + getData(105,$('.acc_title').eq(0).find('.acct_block').eq(0).attr('data-secTypeId'),$('.acc_title').eq(0).siblings()) + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + }); + //11.11专区 + getData(118,119,$('.acc_con').eq(1)) + mui.ajax(llUrl('addon/shuff-shuff-activityList'), {  + data:{ + topTypeId:110 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="acct_block" data-topTypeId="110" data-secTypeId="'+ this.secTypeId +'"><p>'+ this.secTypeName +'</p></div>'; + }); + $('.acc_title').eq(1).html(html); + $('.acc_title').eq(1).find('.acct_block').eq(0).addClass('on'); + getData(110,$('.acc_title').eq(1).find('.acct_block').eq(0).attr('data-secTypeId'),$('.acc_title').eq(1).siblings()) + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + }); + mui.ajax(llUrl('addon/shuff-shuff-activityList'), {  + data:{ + topTypeId:115 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="acct_block" data-topTypeId="115" data-secTypeId="'+ this.secTypeId +'"><p>'+ this.secTypeName +'</p></div>'; + }); + $('.acc_title').eq(2).html(html); + $('.acc_title').eq(2).find('.acct_block').eq(0).addClass('on'); + getData(115,$('.acc_title').eq(2).find('.acct_block').eq(0).attr('data-secTypeId'),$('.acc_title').eq(2).siblings()) + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + }); + + mui('body').on('tap','.acct_block',function(){ + $(this).addClass('on').siblings().removeClass('on'); + getData($(this).attr('data-topTypeId'),$(this).attr('data-secTypeId'),$(this).parent().siblings()) + }) + mui('body').on('tap','.more',function(){ + + var topTypeId = $(this).attr('data-topTypeId'); + + mui.openWindow({ + url: 'ac1111next.html', + id: 'ac1111next.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + topTypeId: topTypeId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + mui('body').on('tap','.accc_block',function(){ + + var data_id = this.attributes["data-goodsId"].nodeValue; + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + data_id: data_id + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + + mui('body').on('tap','.next',function(){ + $('#next').show(); + }) + mui('body').on('tap','#next',function(){ + $('#next').hide(); + }) + $('.header').on('focus', '#keyword', function() { + $(".search button").css('display', 'block'); + }) + $('.header').on('blur', '#keyword', function() { + $(".search button").css('display', 'none'); + }) + //店铺搜索 + $(".header").on('keypress', '#keyword', function(e) { + var keycode = e.keyCode; + var searchName = $('#keyword').val(); + if(keycode == '13') { + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'ac1111next_.html', + id: 'ac1111next_.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + $(".header").on('tap', '.search button', function(e) { + var searchName = $('#keyword').val(); + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'ac1111next_.html', + id: 'ac1111next_.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }); + +}) \ No newline at end of file diff --git a/static/app2/js/activity2.js b/static/app2/js/activity2.js new file mode 100755 index 0000000..d14326a --- /dev/null +++ b/static/app2/js/activity2.js @@ -0,0 +1,154 @@ +$('.title p').html(''); +mui.plusReady(function() { + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + data: { + typeSrc: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + var html3 = ''; + $('.title').css('display','none'); + if(data['1'].list) { + $.each(data['1'].list, function() { + html1 += '<div class="gchh_block" data-goodsId="' + this.goodsId + '"><img class="gchh_b_bg" src="../img/guochan_con_bg.png" /><div class="gchh_b_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div></div>' + }); + $('.gchh').html(html1); + $('.title').eq(0).children('p').html(data['title_1'].name); + $('.title').eq(0).css('display','block'); + } + if(data['2'].list) { + $.each(data['2'].list, function() { + html2 += '<div class="zdzb_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_zdzb_bg.png" /><div class="zdzb_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>' + this.goodsName + '</p><b>¥</b><span class="cost">' + this.shopPrice + '</span><div class="zdzb_btn">立即购买</div></div><img class="zdzb_zzc" src="../img/ac2_zdzb_zzc.png" /></div>' + }); + $('.zdzb').html(html2); + $('.title').eq(1).children('p').html(data['title_2'].name); + $('.title').eq(1).css('display','block'); + } + if(data['3'].list) { + $.each(data['3'].list, function() { + html3 += '<div class="zdzb3_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_ac3_bg.png" /><div class="zdzb3_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>RMB ' + this.shopPrice + '</p><img class="sanjiao" src="../img/ac2_sanjiao.png" /></div></div>'; + }); + $('.zdzb3').html(html3) + $('.title').eq(2).children('p').html(data['title_3'].name); + $('.title').eq(2).css('display','block'); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.gchh').on('tap', '.gchh_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb').on('tap', '.zdzb_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb3').on('tap', '.zdzb3_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/activity3.js b/static/app2/js/activity3.js new file mode 100755 index 0000000..1222923 --- /dev/null +++ b/static/app2/js/activity3.js @@ -0,0 +1,167 @@ +$('.jggcj').css('display', 'none'); +$('.time').css('display', 'none'); +$('.title').eq(0).css('display', 'none'); +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui.ajax(hyhUrl('addon/hyhdailyupdate-Hyhdailyupdate-getIndex'), {  + + data: { + typeSrc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + + $.each(data['4'].list, function() { + html1 += '<div class="list_block" data-goodsId="' + this.goodsId + '"><img class="list_block_bg" src="../img/ac3_bg5.png" /><div class="list_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + '</p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + }); + $('#list1').html(html1); + $.each(data['5'].list, function() { + html2 += '<div class="list_block" data-goodsId="' + this.goodsId + '"><img class="list_block_bg" src="../img/ac3_bg5.png" /><div class="list_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + '</p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + }); + $('#list2').html(html2); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + mui.ajax(hyhUrl('addon/hyhlucky-Hyhlucky-getLuckyPrize'), {  + data: { + draw_id: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + + if(data.prize_list) { + var html = '<div class="content content-1" data-id="' + data.prize_list[0].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[0].prize_img) + '" /></div></div><div class="content content-2" data-id="' + data.prize_list[1].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[1].prize_img) + '" /></div></div><div class="content content-3" data-id="' + data.prize_list[2].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[2].prize_img) + '" /></div></div><div class="content content-8" data-id="' + data.prize_list[7].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[7].prize_img) + '" /></div></div><div class="content content-click"><div id="text"><img src="../img/ac3_button1.png" /></div></div><div class="content content-4" data-id="' + data.prize_list[3].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[3].prize_img) + '" /></div></div><div class="content content-7" data-id="' + data.prize_list[6].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[6].prize_img) + '" /></div></div><div class="content content-6" data-id="' + data.prize_list[5].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[5].prize_img) + '" /></div></div><div class="content content-5" data-id="' + data.prize_list[4].id + '"><img src="../img/ac3_bg1.png" /><div class="content_con"><img src="' + hyhImgUrl(data.prize_list[4].prize_img) + '" /></div></div>' + + $('.cj_con').html(html); + $('.num .number').html(data.max_num) + + $('.content').height($('.content').width() * 123 / 165 + 'px') + $(window).resize(function() { + $('.content').height($('.content').width() + 'px') + }) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + // $('.content').height($('.content').width() * 123 / 165 + 'px') + // $(window).resize(function() { + // $('.content').height($('.content').width() + 'px') + // }) + + function time(a) { + return function() { + if(a > 8) { + a = parseInt(a % 8) + if(a == 0) { + a = 8; + } + } + $('.content').removeClass('active'); + $('.content-' + a).addClass('active'); + $('.zz_img').toggleClass('on'); + } + } + // 在旋转的时候不能再次被点击 + var t = true + $('.cj_con').on('tap', '.content-click', function() { + console.log(token) + if(t) { + t = false; + // 产生随机数 + var prize; + var msg = ''; + mui.ajax(hyhUrl('addon/hyhlucky-Hyhlucky-luckyDraw'), { + headers: {  + "HYH-Token": token + }, + data: { + draw_id: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + console.log(data.msg) + if(data.status == 1) { + if($('.number').html() > 0) { + data = data.data; + prize = data.v; + msg = data.yes; + + $('.number').html($('.number').html() - 1) + // 默认先转3圈 + prize += 32 + for(var i = 1; i <= prize; i++) { + setTimeout(time(i), 6 * i * i); + } + setTimeout(function() { + t = true; + alert(msg); + }, 6 * prize * prize) + } else { + alert('您没有抽奖机会了'); + } + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + } + }) + //跳商品页面 + $('.list').on('tap', '.list_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/activity4.js b/static/app2/js/activity4.js new file mode 100755 index 0000000..f623e80 --- /dev/null +++ b/static/app2/js/activity4.js @@ -0,0 +1,199 @@ +//添加返回顶部按钮 +document.write('<script type="text/javascript" src="' + localStorage.getItem("jsUrl") + 'scrollToTop.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); + +var num = 1; +var isOver = 1; +var catId = ''; + +function getMsg(catIdNum, pageNum, pagesizeNum) { + + var data_msg = { + catId: catIdNum ? catIdNum : '', + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + + if(isOver == 0) { + return; + } else { + isOver = 0; + } + mui.ajax(llUrl('addon/hyhbrandsrec-hyhBrandsrec-getBrandCatList'), {  + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + var htmlcon = ''; + data = data.data; + if(data.Rows == '') { + if(pageNum == 1) { + $('.scroll_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } else if(pageNum > 1) { + $('.scroll_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } + + isOver = 0; + return; + } + $.each(data.Rows, function() { + htmlcon += '<div class="scroll_con_block shadown_wai"><div class="scb_title" data-shopId="'+ this.shopId +'"><img src="'+ ectImgUrl(this.shopImg) +'" /><p>'+ this.shopName +'</p><span class="s1">官方旗舰店</span><span class="s2">进店看看</span></div>'; + + if(this.list != '') { + htmlcon += '<div class="scroll_con_con clearfix">'; + + $.each(this.list, function() { + htmlcon += '<div class = "scc_block" data-goodsId="' + this.goodsId + '"><img src = "'+ ectImgUrl(this.goodsImg) +'" /><p>'+ this.goodsName +'</p><span>¥'+ this.shopPrice +'</span></div>'; + }); + + htmlcon += '</div>'; + } + htmlcon += '</div>'; + + }); + + if(pageNum == 1) { + $('.scroll_con').html(htmlcon); + } else if(pageNum > 1) { + $('.scroll_con').append(htmlcon); + } + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +} + +mui.plusReady(function() { + mui.ajax(llUrl('addon/hyhbrandsrec-hyhBrandsrec-getBrandList'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + var html_ = ''; + var data = data.data; + $.each(data.brandlist_rec, function(num) { + if(num % 2 == 0) { + html += '<div class="swiper-slide"><div class="ss_top ss_ shadown_wai"data-shopId="' + this.shopId + '"><img src="' + ectImgUrl(this.brandImg) + '" /><p>' + this.brandName + '</p></div>'; + } else { + html += '<div class="ss_bottom ss_ shadown_wai"data-shopId="' + this.shopId + '"><img src="' + ectImgUrl(this.brandImg) + '" /><p>' + this.brandName + '</p></div></div>'; + } + }) + $.each(data.brand_list, function() { + html_ += '<div class="nav_block" data-catId="' + this.catId + '">' + this.typeName + '</div>'; + }); + $('.swiper-wrapper').html(html); + $('.nav').html(html_); + $('.nav_block').eq(0).addClass('on'); + $('.t_con').height($('.t_con').width() * 470 / 718); + $('#topbanner').height($('#topbanner').width() * 470 / 718); + + $('#topbanner .swiper-slide').height($('#topbanner .swiper-slide').width() * 2.1); + var swiper = new Swiper('#topbanner', { + slidesPerView: 3.1, + paginationClickable: true, + spaceBetween: 5, + freeMode: true + }); + $('.ss_top').height($('.ss_top').width()); + $('.ss_bottom').height($('.ss_bottom').width()); + getMsg($('.nav_block').eq(0).attr('data-catId'), 1, 10); + } else { + console.log(data.status); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + console.log(errorThrown);       + }   + });  + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num++; + getMsg(catId, num, 10); + } + } + }) + $('.con').on('tap', '.scc_block', function() { + var id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: id + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: false, //自动显示等待框,默认为true + } + }) + }) + $('.con').on('tap', '.scb_title', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: false, //自动显示等待框,默认为true + } + }) + }) + $('.con').on('tap', '.ss_', function() { + var shopId = $(this).attr('data-shopId'); + mui.openWindow({ + url: 'storeout.html', + id: 'storeout.html' + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: false, //自动显示等待框,默认为true + } + }) + }) + $('.nav').on('tap', '.nav_block', function() { + catId = $(this).attr('data-catId'); + isOver = 1; + num = 1; + getMsg(catId, 1, 10); + $(this).addClass('on').siblings().removeClass('on') + }) + +}) \ No newline at end of file diff --git a/static/app2/js/activity5.js b/static/app2/js/activity5.js new file mode 100755 index 0000000..76f10f8 --- /dev/null +++ b/static/app2/js/activity5.js @@ -0,0 +1,11 @@ +mui.init() + mui('.con').scroll({ + deceleration: 0.0005 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + }); + var slider = mui("#slider"); + slider.slider({ + interval: 5000 + }); + + $('.con_o .img').height($('.con_o .img').width()) + $('.con_t_block img').height($('.con_t_block img').width()) \ No newline at end of file diff --git a/static/app2/js/activity6.js b/static/app2/js/activity6.js new file mode 100755 index 0000000..88a3c53 --- /dev/null +++ b/static/app2/js/activity6.js @@ -0,0 +1,143 @@ +mui.plusReady(function() { + mui.ajax(chengUrl('addon/hyhactive-Hyhactive-getGoodsList'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + var html1 = ''; + var html2 = ''; + var html3 = ''; + + $.each(data[0].goodsInfo, function() { + html1 += '<div class="gchh_block" data-goodsId="' + this.goodsId + '"><img class="gchh_b_bg" src="../img/guochan_con_bg.png" /><div class="gchh_b_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>¥' + this.shopPrice + '</p></div></div>' + }); + $('#tt1 p').html(data[0].activeTypeName); + $('.gchh').html(html1); + + $.each(data[1].goodsInfo, function() { + html2 += '<div class="zdzb_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_zdzb_bg.png" /><div class="zdzb_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>' + this.goodsName + '</p><b>¥</b><span class="cost">' + this.shopPrice + '</span><div class="zdzb_btn">立即购买</div></div><img class="zdzb_zzc" src="../img/ac2_zdzb_zzc.png" /></div>' + }); + $('#tt2 p').html(data[1].activeTypeName); + $('.zdzb').html(html2); + + $.each(data[2].goodsInfo, function() { + html3 += '<div class="zdzb3_block" data-goodsId="' + this.goodsId + '"><img src="../img/ac2_ac3_bg.png" /><div class="zdzb3_block_con"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p>RMB ' + this.shopPrice + '</p><img class="sanjiao" src="../img/ac2_sanjiao.png" /></div></div>'; + }); + $('#tt3 p').html(data[2].activeTypeName); + $('.zdzb3').html(html3) + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //跳商品页面 + $('.gchh').on('tap', '.gchh_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb').on('tap', '.zdzb_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳商品页面 + $('.zdzb3').on('tap', '.zdzb3_block', function() { + var goodsId = $(this).attr('data-goodsId'); + console.log(goodsId) + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/activity7.js b/static/app2/js/activity7.js new file mode 100755 index 0000000..c73c649 --- /dev/null +++ b/static/app2/js/activity7.js @@ -0,0 +1,330 @@ +$('.mui-title').html('ECT专区'); +var ect_top = '<div class="ect_top"><p class="ect_m">最新价</p><p class="ect_m">24H成交量</p><img src="'+ hyhImgUrl('Upload/app/icon/star.png') +'" /><p class="ect_m" id="last"></p><p class="ect_m" id="vol"></p></div>'; +$('header').before(ect_top); +var time_ = '距活动结束还有<span id="_d"></span>天'; + +$('.mui-scroll-wrapper').removeClass('scroll_out1').addClass('scroll_out3'); +//var info = '<img src="http://img.heyuanhui.cn/Upload/app/icon/info.png" class="tanhao" />'; +//$('header').append(info); +var nav = '<div class="nav clearfix"></div>'; +$('.ect_top').before(nav); + +var html_con = '<div class="ten clearfix"></div><div class="title_img"></div><div class="time_"></div><div class="con_"></div>' + +$('.con').html(html_con); +$('.time_').html(time_); +var nav_data = []; +var secTypeId = 1; +var timestamp1 = Date.parse(new Date()); +if(timestamp1 >= 1538755200000) { + $('.mui-scroll-wrapper').removeClass('scroll_out3').addClass('scroll_out4'); +} else { + +} + +function getimg(num) { + var img_ = '<img src="'+ hyhImgUrl('static/app/img/ect101-' + num + '.png') +'"/>' + $('.title_img').html(img_); + +} + +function getTwoClass(secTypeId) { + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-activits'), { + data: { + topTypeId: secTypeId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html_ = ''; + $.each(data, function() { + html_ += '<div class="ten_t" data-secTypeId="' + this.secTypeId + '">' + this.secTypeName + '</div>' + }); + $('.ten').html(html_); + + } else { + console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(errorThrown); + } + }); +} + +var issx = 0; +var doller = 0; +var secTypeId = ''; + +function getData(secTypeId, goodsCatId) { + // mui('').pullRefresh().scroll(0, 0, 0); + backTop(); + var data_set = { + secTypeId: secTypeId, + topTypeId: 1, + goodsCatId: goodsCatId ? goodsCatId : '' + }; + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-frontList'), { + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + + data = data.data; + var html_ = ''; + var htmlcon = ''; + + doller = data.doller; + // if(data.secTypeId == 5 || data.secTypeId == 4) { + // htmlcon = '<div class="ect_activity"><img src="http://img.heyuanhui.cn/static/app/img/e' + secTypeId + '.png" class="ect_hd" /></div>' + // } else { + // htmlcon = '<div class="ect_activity_"><img src="http://img.heyuanhui.cn/static/app/img/countdown.png" class="ect_djs" /> <span id="_h">00</span><span id="_m">00</span><span id="_s">00</span></div>' + // html_ = '<div class="day"><p>此活动仅限14-15号两天</p></div>'; + // } + + $.each(data.list, function(num) { + htmlcon += '<div class="ect_com" data-id="' + this.goodsId + '" ><div class="com_img1" ><img src="' + hyhImgUrl(this.goodsImg) + '" /></div><p class="p1"><img src="'+ hyhImgUrl('static/app/img/ectb.png') +'" class="com_img2" />' + this.goodsName + '</p><p class="p3"><l></l>CNY <o>' + this.shopPrice + '</o></p>' + html_ + '</div>'; + }); + $('.con_').html(htmlcon); + + setTimeout(function() { + $('.com_img1').height($('.com_img1').width()); + }, 200) + countTime(); + + } else { + console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); +} + +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date("2018/10/6 00:00:00"); + var end = endDate.getTime(); + //时间差 + var leftTime = end - now; + //定义变量 d,h,m,s保存倒计时的时间 + var d, h, m, s; + if(leftTime >= 0) { + d = Math.floor(leftTime / 1000 / 60 / 60 / 24); + // h = Math.floor(leftTime / 1000 / 60 / 60); + // m = Math.floor(leftTime / 1000 / 60 % 60); + // s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(d < 10) { + d = "0" + d; + } + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + $("#_d").html(d); + // $("#_h").html(h); + // $("#_m").html(m); + // $("#_s").html(s); + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + + }); + // countTime(); + // getData(secTypeId); + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-activityList'), { + data: { + topTypeId: 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if(data.status == 1) { + // console.log(1) + var data = data.data; + var html_ = ''; + $.each(data, function(num) { + html_ += '<div class="nav_block" data-num="' + num + '" data-secTypeId="' + this.secTypeId + '">' + this.secTypeName + '</div>'; + }); + $('.nav').html(html_); + $('.nav_block').eq(0).addClass('on'); + secTypeId = $('.nav_block').eq(0).attr('data-secTypeId'); + getTwoClass(secTypeId); + getData(secTypeId); + getimg(1); + } + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + setInterval(function() { + + mui.ajax('https://api.tokencan.net/exchange-open-api/open/api/get_ticker?symbol=ectusdt&random=' + Math.random(), { + + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + $('#last').html(Math.floor((+data.data.last) * doller * 100) / 100); + $('#vol').html(data.data.vol); + $('.p3').each(function(num) { + $(this).children('l').html('ECT ' + (Math.floor(+$(this).children('o').html() / (+data.data.last) / (+doller) * 100)) / 100 + '≈'); + }) + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }, 2000) + + mui("body").on('tap', '.nav_block', function(e) { + secTypeId = this.attributes["data-secTypeId"].nodeValue; + var num = +$(this).attr('data-num'); + $(this).addClass('on').siblings().removeClass('on'); + getTwoClass(secTypeId); + getData(secTypeId); + getimg(num + 1); + }) + + mui("body").on('tap', '.ten_t', function() { + var goodsCatId = this.attributes["data-secTypeId"].nodeValue; + $(this).addClass('on').siblings().removeClass('on'); + getData(secTypeId, goodsCatId) + }) + + mui(".con").on('tap', '.ect_com', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-id"].nodeValue; + var isEct = 1; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + isEct: isEct + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + // if(isjiazai == 1) { + // page++; + // } + + } else if(scroll.y > 100 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + + $('header').on('tap', '.tanhao', function() { + mui.openWindow({ + url: 'activity8.html', + id: 'activity8.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); +}) \ No newline at end of file diff --git a/static/app2/js/activity8.js b/static/app2/js/activity8.js new file mode 100755 index 0000000..8171485 --- /dev/null +++ b/static/app2/js/activity8.js @@ -0,0 +1,31 @@ +$('.mui-title').html('活动规则'); +var html = `<p class="rul_p">ECT专区9月14-15日活动规则</p> + + <div class="rul_div"> + <p class="rul_p1">满199-100</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、参加活动产品享受此优惠</p> + <p class="rul_p2">2、此活动不叠加使用</p> + <p class="rul_p2">3、活动日期2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">4、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">5、ECT专区单品与普通单品分开结账</p> + </div> + <div class="rul_div"> + <p class="rul_p1">满二赠一</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、仅限同款产品满二赠一</p> + <p class="rul_p2">2、仅限参加活动产品享受此优惠</p> + <p class="rul_p2">3、此活动不叠加使用,每单仅限使用一次</p> + <p class="rul_p2">4、活动时间2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">5、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">6、ECT专区单品与普通单品分开结账</p> + </div> + <div class="rul_div"> + <p class="rul_p1">9.15元</p> + <p class="rul_p2">活动规则</p> + <p class="rul_p2">1、此专区产品每人仅限购买四件</p> + <p class="rul_p2">2、活动时间2018-9-14 00:00至2018-9-15 23:59:59</p> + <p class="rul_p2">3、此活动不兑换现金、不兑换券</p> + <p class="rul_p2">4、ECT专区单品与普通单品分开结账</p> + </div>`; + $('.con').html(html) diff --git a/static/app2/js/activity9.js b/static/app2/js/activity9.js new file mode 100755 index 0000000..429eddc --- /dev/null +++ b/static/app2/js/activity9.js @@ -0,0 +1,145 @@ +var puch_html = '<div class="header"><div class="header_con"><a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left lxy_a"></a><img src="'+ectImgUrl('static/app2/img/mj_log.png')+'" class="mj_lxy" /></div></div><div class="mui-scroll-wrapper scroll_out_t"><div class="mui-scroll"><div class="t_con"><input type="search" name="ect_pre" id="keyword" value="" placeholder="请输入搜索内容" /></div <div class="con_"><div class="nav clearfix"><div class="nav_block on" data-type="326"><span>满200减50</span></div><div class="nav_block" data-type="328"><span>满400减100</span></div></div><div class="nav clearfix"></div><div class="recommend"><div class="recommend_con clearfix" id="recommend_con"></div></div></div></div></div>'; +$('body').html(puch_html); +(function($){ + $(".mui-scroll-wrapper").scroll({ + bounce: true,//滚动条是否有弹力默认是true + indicators: false, //是否显示滚动条,默认是true + }); +})(mui); +document.write('<link rel="stylesheet" type="text/css" href="' + localStorage.getItem("cssUrl") + 'recommend.css?ver=' + localStorage.getItem("version") + '"/>'); +mui.plusReady(function(){ + + var topId = $('.nav_block').first().attr('data-type'); + var secTypeId=0; + var page = 1; + getTitle(); + mui(".nav").on('tap', '.nav_block', function() { + page=1; + topId = $(this).attr('data-type'); + $(this).addClass('on').siblings().removeClass('on'); + getTitle(); + }) + mui(".nav").on('tap', '.nav_block_a', function() { + page=1; + secTypeId = $(this).attr('data-type'); + $(this).addClass('on').siblings().removeClass('on'); + getData(); + }) + + function getTitle(){ + mui.ajax(hyhUrl('addon/shuff-Shuff-actList'), { + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + data:{'topTypeId':topId}, + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data, 1); + var html = ''; + $.each(data.data, function() { + html+='<div class="nav_block_a" data-type="'+this.secTypeId+'"><span>'+this.secTypeName+'</span></div>'; + }); + $('.nav').eq(1).html(html); + $('.nav_block_a').first().addClass('on'); + secTypeId = $('.nav_block_a').first().attr('data-type'); + getData(); + }, + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + }); + } + function getData() { + if(isjiazai == 0) { + return; + }else{ + isjiazai = 0; + } + // mui('').pullRefresh().scroll(0, 0, 0); + //backTop(); + var data_set = { + 'secTypeId': secTypeId, + 'topTypeId': topId, + 'pageSize':10, + 'page':page + }; + mui.ajax(hyhUrl('addon/shuff-Shuff-activits'), {  + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + //console.log(JSON.stringify(data)) + var html = ''; + if(data.list.Rows != ''){ + $.each(data.list.Rows, function() { +// console.log(ectImgUrl(this.goodsImg)) + html += '<div class="recommend_con_block shadown_wai" data-goodsId="'+this.goodsId+'"><img class="rcb_img" src="'+ectImgUrl(this.goodsImg)+'" alt="" /><div class="rcb_con"><div class="rcb_title"><span>满减</span>'+this.goodsName+'</div><div class="rcb_pay">'+this.shopPrice+'</div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div></div>'; + }); + + }else{ + //html='<div>没有更多商品</div>'; + } + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai=1; + + } else { + //console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + });  + } + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if(keycode == '13') { + JZL.openWindow('ac2.html', 'ac2.html',{'data_keyword': searchName,'topTypeId':($('.nav_block').eq(0).attr('data-type')+','+$('.nav_block').eq(1).attr('data-type'))}); + } + }); + + var issx = 0; + var isjiazai = 1; + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(); + } + + } else if(scroll.y > 100 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + +// window.addEventListener('refresh', function(e) { //执行刷新 +// location.reload(); +// +// }); + mui("body").on('tap', '.recommend_con_block', function() { + var data_id = this.attributes["data-goodsId"].nodeValue; + JZL.openWindow('details.html', 'details.html'+data_id,{data_id: data_id}); + }); + //puchase的html_lxy_2018/12/08 + //var lxy_puch_html = '<div class="header"><div class="header_con"><a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left lxy_a"></a><img src="../img/mj_log.png" class="mj_lxy" /></div></div><div class="mui-scroll-wrapper scroll_out_t"><div class="mui-scroll"><div class="t_con"><input type="search" name="ect_pre" id="keyword" value="" placeholder="请输入搜索内容" /></div <div class="con_"><div class="nav clearfix"><div class="nav_block on" data-type="1"><span>满200减50</span></div><div class="nav_block" data-type="2"><span>满400减100</span></div></div><div class="nav clearfix"><div class="nav_block_a on" data-type="1"><span>食品</span></div><div class="nav_block_a" data-type="2"><span>服饰</span></div><div class="nav_block_a" data-type="3"><span>家居</span></div><div class="nav_block_a" data-type="4"><span>时尚</span></div><div class="nav_block_a" data-type="5"><span>美妆</span></div><div class="nav_block_a" data-type="6"><span>电器</span></div></div><div class="recommend"><div class="recommend_con clearfix" id="recommend_con"><div class="recommend_con_block shadown_wai"><img class="rcb_img" src="../img/kong.png" alt="" /><div class="rcb_con"><div class="rcb_title"><span>满减</span>VeroModa双腰头修身九分棉弹牛仔裤</div><div class="rcb_pay">¥269.00</div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div></div><div class="recommend_con_block shadown_wai"><img class="rcb_img" src="../img/kong.png" alt="" /><div class="rcb_con"><div class="rcb_title"><span>满减</span>VeroModa双腰头修身九分棉弹牛仔裤</div><div class="rcb_pay">¥269.00</div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div></div></div></div></div></div></div>'; + + //$('body').append(lxy_puch_html); +}) \ No newline at end of file diff --git a/static/app2/js/addessay.js b/static/app2/js/addessay.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/addgoods.1.js b/static/app2/js/addgoods.1.js new file mode 100755 index 0000000..19e0a7f --- /dev/null +++ b/static/app2/js/addgoods.1.js @@ -0,0 +1,658 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); + +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + var goodsId = self.goodsId; + // //console.log(shopId); + // var isSale = typeof(self.isSale)!= 'undefined' ? self.isSale : ""; + // var isSpec = typeof(self.isSpec)!= 'undefined' ? self.isSpec : ""; + if (goodsId > 0) { + $(".title").text("编辑商品") + + JZL.ajax(qlgUrl("app/shops/getGoodsInfo"), { + shopId: shopId, + goodsId: goodsId + }, function(data) { + //console.log(data); + if (data.status == 1) { + var html1 = ''; + var data = data.data; + var i = 0, + j = 0; + var res = ''; + var id = data.setNameId; + if (1 == data.isSpec) { + getRecommend(page, pageSize, id) + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(datas) { + setSpec(data.spec, specList) + }); + + } + if (1 == data.isSale) { + $('#isSale').prop("checked", "checked"); + } + mui.each(data, function(index, element) { + if ($('#' + index).attr("type") == "hidden" & $('#' + index).hasClass('inp')) { + var imgindex = index.substring(0, index.length - 3); + var obj = '#' + imgindex; + // //console.log(obj); + // if ($(obj)!= "") { + if ($(obj).is('img')) { + // //console.log(element); + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index).val(element) + // } + } else if ($('#' + index).hasClass('gallery')) { + var html = '' + // //console.log(element.length); + if (element.length > 0) { + var imgurls = element.split(",") ? imgurls = element.split(",") : imgurls = element; + //console.log("test"); + + html = '' + for (var i = 0; i < imgurls.length; i++) { + html += '<div data-id="' + i + + '" data-src="" class="galleryImg photo"><div class="delete"><img src="../img/close.png" alt=""></div><img src=' + + hyhImgUrl(imgurls[i]) + ' class="ossfile" id="galleryImg[' + i + + ']" alt=""><input type="hidden" value="' + imgurls[i] + + '" name="gallery[]" class="gallery" id="gallery[' + i + ']"><span class=""></span></div>' + // $('#' + index+'Img['+i+']').val(hyhImgUrl(imgurls[i])) + } + var maxNum = +$('.galleryImg').last().attr('data-id') + 1; //$('.batchImg').children('.galleryImg').length - 1; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html) + } else { + html = ""; + html = + '<div class="galleryImg photo" data-id="0" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[0]" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[0]"><span class=""></span></div>'; + $(".batchImg").html(html) + } + } + } else if (index == 'goodsCatIdPath') { + // data.goodsCatIdPath 三级目录 + var goodsCatIdPathArr = []; + var pathArr = ["largeCat", "mediumCat", "smallCat"] + // //console.log(data.goodsCatIdPath); + goodsCatIdPathArr = data.goodsCatIdPath.split('_') + goodsCatIdPathArr.pop() + // //console.log(goodsCatIdPathArr); + mui.each(pathArr, function(idx, ele) { + // //console.log(idx); + switch (ele) { + case 'largeCat': + getCatIdPathName(goodsCatIdPathArr[0], function(data) { + // //console.log(data); + getGoodsCats('largeCat', 0, goodsCatIdPathArr[0]); + }) + break; + case 'mediumCat': + getCatIdPathName(goodsCatIdPathArr[1], function(data) { + $('#mediumCat').html('<option selected value="' + goodsCatIdPathArr[1] + '">' + data.data.catName + + '</option>') + }); + break; + case 'smallCat': + getCatIdPathName(goodsCatIdPathArr[2], function(data) { + $('#smallCat').html('<option selected value="' + goodsCatIdPathArr[2] + '">' + data.data.catName + + '</option>') + }); + break; + } + }) + + } else { + $('#' + index).val(element) + } + }) + } + }) + + } else { + getGoodsCats("largeCat", 0) + getRecommend(page, pageSize); + + $(".title").text("添加商品") + } + + function setSpec(goodsSpec, specList) { + var html1 = '', + res = '', + goodsRes = '' + + var arr = []; + var arr2 = {}; + for (var i = 0; i < specList.length; i++) { + arr.push(specList[i].list); + arr2[specList[i].catId] = specList[i].list; + } + var a = combins(arr); + var cLength = 0; + var catId = 0; + var showSpecNames = []; + while (c = a.next()) { + res = c.join(' '); + cLength = c.length; + for (i = 0; i < cLength; i++) { + $.each(arr2, function(ind, val) { + $.each(val, function(index, value) { + if (value == c[i]) { + catId = ind; + return; + } + }); + }) + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + c[ + i] + + '" />'; + } + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value=\'0\' />' + + '<div class="addcon_con shadown_wai"><label for="" data-id = "'+j+'" name="showSpecNames[]" class=""><input name="defultType" type="radio" value="" />' + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>' + j++; + } + $('.pricset_con_con').html(html1); + mui.each(goodsSpec, function(idx, val) { + goodsRes = ''; + i = 0; + mui.each(val.names, function(index, value) { + goodsRes += value.itemName + ' '; //hongse 39ma + }) + var showSpecNames = $('label[name="showSpecNames[]"]'); + + var specNameArr=[]; + for(var k=0;k<showSpecNames.length;k++){ + specNameArr[$(showSpecNames[k]).attr('data-id')]= $(showSpecNames[k]).text(); + } + $.each(specNameArr,function(sitem,sval){ + if (goodsSpec == sval) { + i=0; + //find + mui.each(val.names, function(index, value) { + $('#specItemIds[' + sitem + '][' + i + + ']').val(value.itemId); + i++; + }); + $('#specIds[' + sitem + ']').val(val.id); + $('#specPrice[' + sitem + ']').val(val.specPrice); + $('#specStock[' + sitem + ']').val(val.specStock); + + } + }) + +// mui.each(val.names, function(index, value) { +// html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + +// ']" class="inp" value="' + value.itemId + '" />' + +// '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + +// ']" class="inp" value="' + +// value.catId + '" />' + +// '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + +// value.itemName + +// '" />'; +// goodsRes += value.itemName + ' '; +// i++; +// }) +// html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value="' + val.id + +// '" />' + +// '<div class="addcon_con shadown_wai"><label for="" class="">' + goodsRes + +// '</label><input type="text" name="specPrice[]" id="specPrice[' + j + +// ']" class="inp label-t" value="' + val.specPrice + +// '" /><input type="text" name="specStock[]" id="specStock[' + j + +// ']" class="inp label-t" value="' + val.specStock + '"/></div>'; + // j++; + }) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // $('.pricset_con_con').html(html1); + } + +}) +} + +function getCatIdPathName(catId, callback) { + JZL.ajax(qlgUrl("app/goodscats/getCatName"), { + catId: catId + }, function(data) { + callback(data); + }) +} + +//获取商品总规格列表 +var page = 1; +var pageSize = 100; +var isjiazai = 1; + +function getRecommend(page, pageSize, defaultVal) { + + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 100 + } + recommenddata.shopId = shopId + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shops/getSpecs'), recommenddata, function(data) { + + + // //console.log(data); + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="0">选择属性</option>'; + if (typeof(defaultVal) == "undefined") { + // //console.log(1); + $.each(data.Rows, function() { + html += '<option data-id="' + this.id + ' "value="' + this.id + '">' + this.setName + '</option>' + }); + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + } else { + // //console.log(defaultVal); + $.each(data.Rows, function() { + if (this.id = defaultVal) { + selected = 'selected'; + } else { + selected = ''; + } + html = '<option value="' + defaultVal + '"' + selected + '>' + this.setName + '</option>'; + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + }); + + + } + + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + isjiazai = 1; + }) +} + +//获取商品规格 + +combins = function(args) { + + if (args.length < 2) return args[0] || []; + // if (arguments.length < 2) return arguments[0] || []; + //var args = Array.prototype.slice.call(arguments); + var that = { + index: 0, + nth: function(n) { + var result = [], + d = 0; + for (; d < this.dim; d++) { + var l = this[d].length; + var i = n % l; + result.push(this[d][i]); + n -= i; + n /= l; + } + return result; + }, + next: function() { + if (this.index >= size) return; + var result = this.nth(this.index); + this.index++; + return result; + } + }; + var size = 1; + for (var i = 0; i < args.length; i++) { + size = size * args[i].length; + that[i] = args[i]; + } + that.size = size; + that.dim = args.length; + return that; +} + +// 判断是否上架 +var isSale = "", + setNameId, + isSpec; +if ($("#isSale").prop("checked")) { + isSale = "1"; +} else { + isSale = "0"; +} +// 判断有没有商品属性 + +if ($("#setNameId option:selected").val() != "") { + isSpec = 1; +} else { + isSpec = 0; +} + +$('#setNameId').change(function() { + var id = $('#setNameId option:selected').val() + + var html1 = ""; + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(data) { + + // //console.log(data); + if (1 == data.status) { + + var arr = []; + var arr2 = {}; + for (var i = 0; i < data.data.length; i++) { + arr.push(data.data[i].list); + arr2[data.data[i].catId] = data.data[i].list; + } + var a = combins(arr); + var j = 0; + var res = ''; + var cLength = 0; + var catId = 0; + while (c = a.next()) { + res = c.join(','); + cLength = c.length; + for (i = 0; i < cLength; i++) { + $.each(arr2, function(ind, val) { + $.each(val, function(index, value) { + if (value == c[i]) { + catId = ind; + return; + } + }); + + }) + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + c[i] + + '" />'; + + } + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value=\'0\' />' + + '<div class="addcon_con shadown_wai"><label for="" class="">' + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>' + j++; + } + $('.pricset_con_con').html(html1); + } + }) +}) + +// 下一页 +var check = true; +mui("body").on('tap', '.next_btn', function() { + check = true; + $('.isemptyinp').each(function() { + // //console.log(this); + + if (!this.value || "" == $.trim(this.value)) { + var label = this.previousElementSibling; + //console.log(label); + mui.alert(label.innerText + "不允许为空") + check = false; + return false; + } + }) + + if ($("#shopPrice").val() == "" & $("#setNameId option:selected").val() == "0" & check == true) { + mui.alert("商品没有属性必须输入商品价格") + check = false; + return false; + } + + if ($("#setNameId option:selected").val() != "" & check == true) { + $('.pricset_con_con input').each(function() { + if ((!this.value || "" == $.trim(this.value))) { + mui.alert("请输入数据") + check = false; + return false; + } + }) + } + + + if (check == true) { + $(".addcon").css("display", "none") + $(".pre").css("display", "block"); + backTop(); + let E = window.wangEditor; + + let editor = new E('#goodsDesc'); + editor.customConfig.uploadImgShowBase64 = true; + editor.create(); + } + + +}) +//预览 +mui("body").on('tap', '.prelook', function() { + + + +}) + + + +// 上一页 +mui('body').on('tap', '.pre_btn', function() { + $(".addcon").css("display", "block") + $(".pre").css("display", "none") +}) +// //console.log($("#goodsDesc").text()); + +//提交 +var click = false; +mui('.btn').on('tap', '.submit_btn ', function() { + if (click == true) { + return + } + + var imgs = ''; + var data = $('input[name="gallery[]"]'); + // //console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + + }) + + + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + + + $('#gallery').val(imgs); + // //console.log($('#gallery').val()); + + var params = JZL.getParams(".inp"); + params.shopId = shopId; + params.isSale = isSale; + params.isSpec = isSpec; + params.goodsDesc = $("#goodsDesc").text(); + params.setNameId = $('#setNameId option:selected').val() + click = true; + if (goodsId > 0) { + params.goodsId = goodsId; + + } + JZL.ajax(qlgUrl('app/shops/addGoods'), params, function(data) { + // //console.log(data); + if (data.status == 1) { + mui.back(); + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + + }) + + +}) + +//获取类目 +$('.selectarea').on("change", ".area", function() { + var objs = ['largeCat', 'mediumCat', 'smallCat']; + // var areaStr = ['请选择', '请选择', '请选择']; + var level = +$(this).attr('data-level') + 1; //0 + pid = $('#' + objs[level - 1] + ' option:selected').val(); + getGoodsCats(objs[level], pid); + +}) + +//三级类目 +function getGoodsCats(obj, pid, defaultId) { + JZL.ajax(qlgUrl('app/shops/getGoodsCats'), { + pid: pid + }, + function(data) { + // //console.log(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">' + "请选择" + '</option>'; + if ('undefined' == typeof(defaultId)) { + $.each(data, function() { + // //console.log(this); + html += '<option value="' + this.catId + '">' + this.catName + '</option>' + }); + } else { + $.each(data, function() { + if (this.catId == defaultId) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option value="' + this.catId + '" ' + selected + '>' + this.catName + '</option>' + }); + } + $('#' + obj).html(html); + } + }) +} + +// 上传图片 +$(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + // //console.log($('#galleryImg[' + num + ']')); + //if ($('#galleryImg[' + num + ']').length > 0) { + that.html(html); + //} else { + // $(".batchImg").append(html); + //} + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); +}) + +$(".oneImg").on("tap", '#goods', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("goodsImg", "test", "goods") + openCamera(function(t, status, fileName, serverName) { + var html = '<img src="' + serverName + '" class="ossfile" data-src="' + fileName + + '" id="goods" alt=""><input type="hidden" value="' + fileName + + '" class="goodsImg inp" id="goodsImg"><span class=""></span>'; + + $(".goods").html(html); + + }) +}) +// 删除图片 +$(".batchImg").on('tap', '.delete', function(e) { + +e.preventDefault(); +e.stopPropagation() + +// //console.log(this); +var that = $(this) +//var idx = that.parent().attr('data-id'); +//var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; +if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; +} +}) + +}) diff --git a/static/app2/js/addgoods.2.js b/static/app2/js/addgoods.2.js new file mode 100755 index 0000000..5fd7f09 --- /dev/null +++ b/static/app2/js/addgoods.2.js @@ -0,0 +1,859 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +$(".pricset_con").hide(); +function escape2Html(str) { + var arrEntities = { + 'lt': '<', + 'gt': '>', + 'nbsp': ' ', + 'amp': '&', + 'quot': '"' + }; + return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function(all, i) { + return arrEntities[i]; + }); +}; +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + // ////console.log(self); + var shopId = self.id; + var goodsId = self.goodsId; + var richText = ''; + + var E = window.wangEditor + var editor = new E('#goodsDesc') + // editor.customConfig.showLinkImg = false // 隐藏“网络图片”tab + // editor.customConfig.uploadFileName = 'yourFileName' //给上传的本地图片文件命名的统一名称 + // editor.customConfig.uploadImgServer = '/upload'; //官方文档上写的是服务器地址,也就是上传图片的方法名 + + // 允许上传到七牛云存储 + editor.customConfig.qiniu = true; + editor.customConfig.debug = true; + // editor.customConfig.onchange = function (html) { + // // 监控变化,同步更新到 textarea + // // $text1.val(html) + // }; + editor.create(); + // 初始化七牛上传 + + + if (goodsId > 0) { + $(".title").text("编辑商品") + + JZL.ajax(qlgUrl("app/shops/getGoodsInfo"), { + shopId: shopId, + goodsId: goodsId + }, function(data) { + //console.log(data); + if (data.status == 1) { + var html1 = ''; + var data = data.data; + var i = 0, + j = 0; + var res = ''; + var bjSpec = data.isSpec; + if (1 == data.isSpec) { + $(".pricset_con").show() + var id = data.setNameId; + + // ////console.log(id); + getRecommend(page, pageSize, id) + + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(data1) { + //console.log(data1); + if (1 == data1.status) { + var that = this + var arr = []; + var arr2 = {}; + for (var i = 0; i < data1.data.length; i++) { + arr.push(data1.data[i].list); + arr2[data1.data[i].catId] = data1.data[i].list; + } + + // ////console.log(a); + var cLength = 0; + var catId = 0; + var goodsRes = ""; + if (arr.length > 0) { + var tmpI = 0; + var a = combins(arr); + while (true) { + if (arr.length > 1) { + c = a.next(); + if (!c) break; + cLength = c.length; + res = c.join(' '); + } else { + if (tmpI >= arr[0].length) { + break; + } + c = arr[0]; + res = arr[0][tmpI]; + cLength = arr[0].length; + } + tmpI++; + // ////console.log(c); + // ////console.log(res); + for (i = 0; i < cLength; i++) { + $.each(arr2, function(ind, val) { + $.each(val, function(index, value) { + if (value == c[i]) { + catId = ind; + return; + } + }); + + }) + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + //属性值id + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + //分类ID + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + c[ + i] + //属性值 + '" />'; + } + //console.log(j); + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value="0" />' + //规格表ID 新增传0 + '<div class="addcon_con shadown_wai"><div class="radio"><input name="defaultId" type="radio" value="' + + j + '" /></div><label for="" data-id = "' + j + + '" name="showSpecNames[]" class="">' + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>'; + j++; + } + + $('.pricset_con_con').html(html1); + var setNum = 0; + mui.each(data.spec, function(idx, val) { + if (cLength != val.names.length) return false; + goodsRes = ''; + i = 0; + if (arr.length > 1) { + mui.each(val.names, function(index, value) { + goodsRes += value.itemName + ' '; //hongse 39ma + }) + } else { + // //console.log(val); + //console.log(val.names); + goodsRes = val.names[setNum].itemName; + setNum++; + } + var showSpecNames = $('label[name="showSpecNames[]"]'); + var specNameArr = []; + for (var k = 0; k < showSpecNames.length; k++) { + specNameArr[$(showSpecNames[k]).attr('data-id')] = $(showSpecNames[k]).text(); + } + $.each(specNameArr, function(sitem, sval) { + if ($.trim(goodsRes) == $.trim(sval)) { //去除空格 不然报错 + i = 0; + mui.each(val.names, function(index, value) { + // ////console.log(i); + document.getElementById('specItemIds[' + +sitem + '][' + i + ']').value = value.itemId //属性值ID 新增传0 + i++; + }); + document.getElementById('specIds[' + +sitem + ']').value = val.id //规格表ID,新增传0 + document.getElementById('specPrice[' + +sitem + ']').value = val.specPrice + document.getElementById('specStock[' + +sitem + ']').value = val.specStock + if (1 == val.isDefault) { + + //checked + var inputList = $('input[name=defaultId]') + + + $.each(inputList, function(index, value) { + // ////console.log(value, index); + this.previousElementSibling + if (sitem == this.value) { + this.checked = true + } + }) + } + + } + }) + + }) + } + } + }) + + + } else if (0 == data.isSpec) { + // $('#setNameId').html('<option value="0">选择属性</option>') + getRecommend(page, pageSize) + } + if (1 == data.isSale) { + $('#isSale').prop("checked", "checked"); + } + mui.each(data, function(index, element) { + if ($('#' + index).attr("type") == "hidden" & $('#' + index).hasClass('inp')) { + var imgindex = index.substring(0, index.length - 3); + var obj = '#' + imgindex; + if ($(obj).is('img')) { + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index).val(element) + } else if ($('#' + index).hasClass('gallery')) { + var html = ''; + if (element.length > 0) { + var imgurls = element.split(",") ? imgurls = element.split(",") : imgurls = element; + html = '' + for (var i = 0; i < imgurls.length; i++) { + html += '<div data-id="' + i + + '" data-src="" class="galleryImg photo"><div class="delete"><img src="../img/close.png" alt=""></div><img src=' + + hyhImgUrl(imgurls[i]) + ' class="ossfile" id="galleryImg[' + i + + ']" alt=""><input type="hidden" value="' + imgurls[i] + + '" name="gallery[]" class="gallery" id="gallery[' + i + ']"><span class=""></span></div>' + // $('#' + index+'Img['+i+']').val(hyhImgUrl(imgurls[i])) + } + var maxNum = +$('.galleryImg').last().attr('data-id') + 1; //$('.batchImg').children('.galleryImg').length - 1; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html) + } else { + html = ""; + html = + '<div class="galleryImg photo" data-id="0" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[0]" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[0]"><span class=""></span></div>'; + $(".batchImg").html(html) + } + } + } else if (index == 'goodsCatIdPath') { + // data.goodsCatIdPath 三级目录 + var goodsCatIdPathArr = []; + var pathArr = ["largeCat", "mediumCat", "smallCat"] + // ////console.log(data.goodsCatIdPath); + goodsCatIdPathArr = data.goodsCatIdPath.split('_') + goodsCatIdPathArr.pop() //移除最后一个数组元素 _ + mui.each(pathArr, function(idx, ele) { + // ////console.log(idx); + switch (ele) { + case 'largeCat': + getCatIdPathName(goodsCatIdPathArr[0], function(data) { + getGoodsCats('largeCat', 0, goodsCatIdPathArr[0]); + }) + break; + case 'mediumCat': + getCatIdPathName(goodsCatIdPathArr[1], function(data) { + $('#mediumCat').html('<option selected value="' + goodsCatIdPathArr[1] + '">' + data.data.catName + + '</option>') + }); + break; + case 'smallCat': + getCatIdPathName(goodsCatIdPathArr[2], function(data) { + $('#smallCat').html('<option selected value="' + goodsCatIdPathArr[2] + '">' + data.data.catName + + '</option>') + }); + break; + } + }) + + } else { + $('#' + index).val(element) + } + }) + if ('' != data.goodsDesc) { + var Desc = escape2Html(data.goodsDesc) + // var Desc= HtmlUtils.htmlUnescape(data.goodsDesc) + ////console.log(Desc) + // $('#goodsDesc').val(Desc) + // $('#goodsDesc').html(Desc) + editor.txt.html(Desc) + } + + // params.goodsDesc = editor.txt.html(); + + } else { + mui.alert(data.msg) + } + }) + + } else { + getGoodsCats("largeCat", 0) + getRecommend(page, pageSize); + + $(".title").text("添加商品") + } + + + function getCatIdPathName(catId, callback) { + JZL.ajax(qlgUrl("app/goodscats/getCatName"), { + catId: catId + }, function(data) { + callback(data); + }) + } + + //获取商品总规格列表 + var page = 1; + var pageSize = 100; + var isjiazai = 1; + + function getRecommend(page, pageSize, defaultVal) { + + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 100 + } + recommenddata.shopId = shopId + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shops/getSpecs'), recommenddata, function(data) { + + + // ////console.log(data); + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="0">无规格属性</option>'; + if (typeof(defaultVal) == "undefined") { + // ////console.log(1); + $.each(data.Rows, function() { + html += '<option value= "' + this.id + '" data-id="' + this.id + ' ">' + this.setName + '</option>' + }); + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + } else { + // ////console.log(defaultVal); + $.each(data.Rows, function() { + if (this.id == defaultVal) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option data-id="' + this.id + '" value="' + this.id + '" ' + selected + '>' + this.setName + + '</option>'; + + }); + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + + } + + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg); + // location.reload(); + } + isjiazai = 1; + }) + } + + //获取商品规格 + // 笛卡尔积 + combins = function(args) { + + if (args.length < 2) return args[0] || []; + // if (arguments.length < 2) return arguments[0] || []; + //var args = Array.prototype.slice.call(arguments); + var that = { + index: 0, + nth: function(n) { + var result = [], + d = 0; + for (; d < this.dim; d++) { + var l = this[d].length; + var i = n % l; + result.push(this[d][i]); + n -= i; + n /= l; + } + return result; + }, + next: function() { + if (this.index >= size) return; + var result = this.nth(this.index); + this.index++; + return result; + } + }; + var size = 1; + for (var i = 0; i < args.length; i++) { + size = size * args[i].length; + that[i] = args[i]; + } + that.size = size; + that.dim = args.length; + return that; + } + + + + $('#setNameId').change(function() { + var id = $('#setNameId option:selected').attr('data-id') + // ////console.log(id); + + var html1 = ""; + if (typeof id == "undefined" || 0 == id) { + $(".pricset_con").hide() + } else { + $(".pricset_con").show() + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(data) { + // ////console.log(data); + if (1 == data.status) { + html1 = ""; + var arr = []; + var arr2 = {}; + for (var i = 0; i < data.data.length; i++) { + arr.push(data.data[i].list); + arr2[data.data[i].catId] = data.data[i].list; + } + + var j = 0; + var res = ''; + var cLength = 0; + var catId = 0; + var tmpI = 0; + var a = combins(arr); + while (true) { + if (arr.length > 1) { + c = a.next(); + if (!c) break; + cLength = c.length; + res = c.join(' '); + } else { + if (tmpI >= arr[0].length) { + break; + } + c = arr[0]; + res = arr[0][tmpI]; + cLength = arr[0].length; + } + tmpI++; + for (i = 0; i < cLength; i++) { + $.each(arr2, function(ind, val) { + $.each(val, function(index, value) { + if (value == c[i]) { + catId = ind; + return; + } + }); + + }) + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + c[i] + + '" />'; + + } + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value=\'0\' />' + + '<div class="addcon_con shadown_wai"><div class="radio"><input name="defaultId" type="radio" value="' + j + + '" /></div><label for="" class="">' + + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>' + j++; + } + $('.pricset_con_con').html(html1); + } else { + mui.alert(data.msg) + } + }) + } + }) + + // 下一页 + var check = true; + mui("body").on('tap', '.next_btn', function() { + check = true; + $('.isemptyinp').each(function() { + if (!this.value || "" == $.trim(this.value)) { + var label = this.previousElementSibling; + mui.alert(label.innerText + "不允许为空") + check = false; + return false; + } + }) + + if ($("#shopPrice").val() == "" & $("#setNameId option:selected").val() == "0" & check == true) { + mui.alert("商品没有属性必须输入商品价格") + check = false; + return false; + } + if ($("#setNameId option:selected").val() != 0 && check == true) { + + if ($('input[name="defaultId"]:checked').length == 0) { + mui.alert("请选择默认规格") + check = false; + return false + } + $('.pricset_con_con input').each(function() { + if ((!$(this).val() || "" == $.trim(this.value))) { + + + mui.alert("请输入数据") + $(this).focus(); + check = false; + return false; + } + }) + } + // var shopPrice= $('input[name="defaultId"]:checked').parent().parent().find('input[name="specPrice[]"]').val(); + // ////console.log(shopPrice) + if ($("#isSale").prop("checked")) { + isSale = "1"; + } else { + isSale = "0"; + } + if (check == true) { + $(".addcon").css("display", "none") + $(".pre").css("display", "block"); + backTop(); + + } + + + }) + //预览 + $('.prelook').hide(); + // mui("body").on('tap', '.prelook', function() { + // + // + // + // }) + // 上一页 + mui('body').on('tap', '.pre_btn', function() { + $(".addcon").css("display", "block") + $(".pre").css("display", "none") + }) + // ////console.log($("#goodsDesc").text()); + + //提交 + // 判断是否上架 + var isSale = "", + setNameId, + isSpec; + + // ////console.log(typeof($("#setNameId option:selected").val())); + + + //提交 + var click = false; + mui('.btn').on('tap', '.submit_btn ', function() { + richText = editor.txt.text() + // 判断有没有商品属性 + if ($("#setNameId option:selected").val() != 0) { + isSpec = 1; + } else { + isSpec = 0; + } + if (click == true) { + return + } + + if ($("#isSale").prop("checked")) { + // ////console.log(1); + isSale = "1"; + } else { + // ////console.log(0); + isSale = "0"; + } + var imgs = ''; + var data = $('input[name="gallery[]"]'); + // ////console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + + }) + + + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + + + $('#gallery').val(imgs); + //默认选中 + var defaultPrice = $('input[name="defaultId"]:checked').parent().parent().find('input[name="specPrice[]"]').val(); + var params = JZL.getParams(".inp"); + params.shopId = shopId; + params.isSale = isSale; + params.isSpec = isSpec; + params.defaultId = $('input[name="defaultId"]:checked').val(); + params.goodsDesc = editor.txt.html(); + params.setNameId = $('#setNameId option:selected').val() + if (isSpec == 1) { + // params.shopPrice = shopPrice + $('#shopPrice').val(defaultPrice); + + } + params.shopPrice = $('#shopPrice').val() + click = true; + if (goodsId > 0) { + params.goodsId = goodsId; + + } + // alert(editor.txt.html()) + JZL.ajax(qlgUrl('app/shops/addGoods'), params, function(data) { + // ////console.log(data); + if (data.status == 1) { + mui.toast(data.msg); + mui.back(); + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + + }) + + + }) + + //获取类目 + $('.selectarea').on("change", ".area", function() { + var objs = ['largeCat', 'mediumCat', 'smallCat']; + // var areaStr = ['请选择', '请选择', '请选择']; + var level = +$(this).attr('data-level') + 1; //0 + pid = $('#' + objs[level - 1] + ' option:selected').val(); + getGoodsCats(objs[level], pid); + + }) + + //三级类目 + function getGoodsCats(obj, pid, defaultId) { + JZL.ajax(qlgUrl('app/shops/getGoodsCats'), { + pid: pid + }, + function(data) { + // ////console.log(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">' + "请选择" + '</option>'; + if ('undefined' == typeof(defaultId)) { + $.each(data, function() { + // ////console.log(this); + html += '<option value="' + this.catId + '">' + this.catName + '</option>' + }); + } else { + $.each(data, function() { + if (this.catId == defaultId) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option value="' + this.catId + '" ' + selected + '>' + this.catName + '</option>' + }); + } + $('#' + obj).html(html); + } + }) + } + + // 上传图片 + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + // ////console.log($('#galleryImg[' + num + ']')); + //if ($('#galleryImg[' + num + ']').length > 0) { + that.html(html); + //} else { + // $(".batchImg").append(html); + //} + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + + $(".oneImg").on("tap", '#goods', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("goodsImg", "test", "goods") + openCamera(function(t, status, fileName, serverName) { + var html = '<img src="' + serverName + '" class="ossfile" data-src="' + fileName + + '" id="goods" alt=""><input type="hidden" value="' + fileName + + '" class="goodsImg inp" id="goodsImg"><span class=""></span>'; + + $(".goods").html(html); + + }) + }) + // 删除图片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + // ////console.log(this); + var that = $(this) + //var idx = that.parent().attr('data-id'); + //var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; + } + }) + //上传图片到七牛; + + var uptoken = ''; + var rs = send_request(); + rs = JSON.parse(rs); + + uptoken = rs.token; + + function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + // ////console.log(dir) + serverUrl = hyhUrl('oss/qiniu.php'); + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + + }; + + + // 初始化七牛上传的方法 + function uploadInit() { + var btnId = editor.imgMenuId; + var containerId = editor.toolbarElemId; + var textElemId = editor.textElemId; + // 创建上传对象 + var uploader = Qiniu.uploader({ + runtimes: 'html5,flash,html4', //上传模式,依次退化 + browse_button: btnId, //上传选择的点选按钮,**必需** + //uptoken_url: rs, + //Ajax请求upToken的Url,**强烈建议设置**(服务端提供) + uptoken: uptoken, + // url: 'http://up-z1.qiniup.com', + + // uptoken : '<Your upload token>', + //若未指定uptoken_url,则必须指定 uptoken ,uptoken由其他程序生成 + // unique_names: true, + // 默认 false,key为文件名。若开启该选项,SDK会为每个文件自动生成key(文件名) + // save_key: true, + // 默认 false。若在服务端生成uptoken的上传策略中指定了 `sava_key`,则开启,SDK在前端将不对key进行任何处理 + // domain: 'http://7xrjl5.com1.z0.glb.clouddn.com/', + // domain:$('#domain').val(), + domain: rs.url, + + //bucket 域名,下载资源时用到,**必需** + container: containerId, //上传区域DOM ID,默认是browser_button的父元素, + max_file_size: '100mb', //最大文件体积限制 + flash_swf_url: '../js/plupload/Moxie.swf', //引入flash,相对路径 + filters: { + mime_types: [ + //只允许上传图片文件 (注意,extensions中,逗号后面不要加空格) + { + title: "图片文件", + extensions: "jpg,gif,png,bmp" + } + ] + }, + max_retries: 3, //上传失败最大重试次数 + dragdrop: true, //开启可拖曳上传 + drop_element: textElemId, //拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传 + chunk_size: '4mb', //分块上传时,每片的体积 + auto_start: true, //选择文件后自动上传,若关闭需要自己绑定事件触发上传 + init: { + 'FilesAdded': function(up, files) { + plupload.each(files, function(file) { + // 文件添加进队列后,处理相关的事情 + // printLog('on FilesAdded'); + }); + }, + 'BeforeUpload': function(up, file) { + // 每个文件上传前,处理相关的事情 + // printLog('on BeforeUpload'); + }, + 'UploadProgress': function(up, file) { + // 显示进度 + // printLog('进度 ' + file.percent) + }, + 'FileUploaded': function(up, file, info) { + // 每个文件上传成功后,处理相关的事情 + // 其中 info 是文件上传成功后,服务端返回的json,形式如 + // { + // "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98", + // "key": "gogopher.jpg" + // } + // printLog(info); + // 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html + + var domain = up.getOption('domain'); + var res = $.parseJSON(info); + var sourceLink = domain + res.key; //获取上传成功后的文件的Url + // 插入图片到editor + editor.cmd.do('insertHtml', '<img src="' + sourceLink + '" style="max-width:100%;"/>') + }, + 'Error': function(up, err, errTip) { + //上传出错时,处理相关的事情 + // printLog('on Error'); + }, + 'UploadComplete': function() { + //队列文件处理完毕后,处理相关的事情 + // printLog('on UploadComplete'); + } + // Key 函数如果有需要自行配置,无特殊需要请注释 + //, + // 'Key': function(up, file) { + // // 若想在前端对每个文件的key进行个性化处理,可以配置该函数 + // // 该配置必须要在 unique_names: false , save_key: false 时才生效 + // var key = ""; + // // do something with key here + // return key + // } + } + // domain 为七牛空间(bucket)对应的域名,选择某个空间后,可通过"空间设置->基本设置->域名设置"查看获取 + // uploader 为一个plupload对象,继承了所有plupload的方法,参考http://plupload.com/docs + }); + } + uploadInit(); + // 封装 ////console.log 函数 + function printLog(title, info) { + window.console && console.log(title, info); + } +}) diff --git a/static/app2/js/addgoods.js b/static/app2/js/addgoods.js new file mode 100755 index 0000000..848d7fb --- /dev/null +++ b/static/app2/js/addgoods.js @@ -0,0 +1,855 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +$(".pricset_con").hide(); + +function escape2Html(str) { + var arrEntities = { + 'lt': '<', + 'gt': '>', + 'nbsp': ' ', + 'amp': '&', + 'quot': '"' + }; + return str.replace(/&(lt|gt|nbsp|amp|quot);/ig, function(all, i) { + return arrEntities[i]; + }); +}; +mui.plusReady(function() { + $("#isSale").prop("checked", true); + var self = plus.webview.currentWebview(); + + var shopId = self.id; + var goodsId = self.goodsId; + var richText = ''; + + var E = window.wangEditor + var editor = new E('#goodsDesc') + // editor.customConfig.showLinkImg = false // 隐藏“网络图片”tab + // editor.customConfig.uploadFileName = 'yourFileName' //给上传的本地图片文件命名的统一名称 + // editor.customConfig.uploadImgServer = '/upload'; //官方文档上写的是服务器地址,也就是上传图片的方法名 + + // 允许上传到七牛云存储 + editor.customConfig.qiniu = true; + editor.customConfig.debug = true; + // editor.customConfig.onchange = function (html) { + // // 监控变化,同步更新到 textarea + // // $text1.val(html) + // }; + editor.create(); + // 初始化七牛上传 + + + if (goodsId > 0) { + $(".title").text("编辑商品") + + JZL.ajax(qlgUrl("app/shops/getGoodsInfo"), { + shopId: shopId, + goodsId: goodsId + }, function(data) { + //console.log(data); + if (data.status == 1) { + var html1 = ''; + var data = data.data; + var i = 0, + j = 0; + var res = ''; + var bjSpec = data.isSpec; + if (1 == data.isSpec) { + $(".pricset_con").show() + var id = data.setNameId; + + + getRecommend(page, pageSize, id) + + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(data1) { + + if (1 == data1.status) { + var that = this + var arr = []; + var arr2 = {}; + for (var i = 0; i < data1.data.length; i++) { + arr.push(data1.data[i].list); + arr2[data1.data[i].catId] = data1.data[i].list; + } + + + var cLength = 0; + var catId = 0; + var goodsRes = ""; + if (arr.length > 0) { + var calc = calcDescartes(arr); + var cIndex = 0, + cArr = []; + while (true) { + if (cIndex >= calc.length) { + break; + } + //区分单规格和多规格 + if (Array.isArray(calc[cIndex])) { + res = calc[cIndex].join(' '); + cArr = calc[cIndex]; + cLength = calc[cIndex].length; + } else { + res = calc[cIndex]; + cArr[0] = res; + cLength = 1; + } + for (i = 0; i < cArr.length; i++) { + //获取catId + + // console.log(cArr[i]); + $.each(arr2, function(ind, val) { + //console.log(val); + $.each(val, function(index, value) { + if (value == cArr[i]) { + catId = ind; + // console.log(catId); + return; + } + }); + }); + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + //属性值id + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + //分类ID + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + + cArr[i] + //属性值 + '" />'; + } + //console.log(j); + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value="0" />' + //规格表ID 新增传0 + '<div class="addcon_con shadown_wai"><div class="radio"><input name="defaultId" type="radio" value="' + + j + '" /></div><label for="" data-id = "' + j + + '" name="showSpecNames[]" class="">' + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>'; + j++; + cIndex++; + } + + $('.pricset_con_con').html(html1); + //var setNum = 0; + + mui.each(data.spec, function(idx, val) { + // console.log(val.names); + //if (calc[setNum].length != val.names.length) return false; + //setNum++; + goodsRes = ''; + i = 0; + mui.each(val.names, function(index, value) { + goodsRes += value.itemName + ' '; //hongse 39ma + }) + + var showSpecNames = $('label[name="showSpecNames[]"]'); + var specNameArr = []; + for (var k = 0; k < showSpecNames.length; k++) { + specNameArr[$(showSpecNames[k]).attr('data-id')] = $(showSpecNames[k]).text(); + } + $.each(specNameArr, function(sitem, sval) { + if ($.trim(goodsRes) == $.trim(sval)) { //去除空格 不然报错 + i = 0; + mui.each(val.names, function(index, value) { + + document.getElementById('specItemIds[' + +sitem + '][' + i + ']').value = value.itemId //属性值ID 新增传0 + i++; + }); + document.getElementById('specIds[' + +sitem + ']').value = val.id //规格表ID,新增传0 + document.getElementById('specPrice[' + +sitem + ']').value = val.specPrice + document.getElementById('specStock[' + +sitem + ']').value = val.specStock + if (1 == val.isDefault) { + + //checked + var inputList = $('input[name=defaultId]') + + + $.each(inputList, function(index, value) { + + this.previousElementSibling + if (sitem == this.value) { + this.checked = true + } + }) + } + + } + }) + + }) + } + } + }) + + + } else if (0 == data.isSpec) { + // $('#setNameId').html('<option value="0">选择属性</option>') + getRecommend(page, pageSize) + } + if (1 == data.isSale) { + $('#isSale').prop("checked", "checked"); + } + mui.each(data, function(index, element) { + if ($('#' + index).attr("type") == "hidden" & $('#' + index).hasClass('inp')) { + var imgindex = index.substring(0, index.length - 3); + var obj = '#' + imgindex; + if ($(obj).is('img')) { + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index).val(element) + } else if ($('#' + index).hasClass('gallery')) { + var html = ''; + if (element.length > 0) { + var imgurls = element.split(",") ? imgurls = element.split(",") : imgurls = element; + html = '' + for (var i = 0; i < imgurls.length; i++) { + html += '<div data-id="' + i + + '" data-src="" class="galleryImg photo"><div class="delete"><img src="../img/close.png" alt=""></div><img src=' + + hyhImgUrl(imgurls[i]) + ' class="ossfile" id="galleryImg[' + i + + ']" alt=""><input type="hidden" value="' + imgurls[i] + + '" name="gallery[]" class="gallery" id="gallery[' + i + ']"><span class=""></span></div>' + // $('#' + index+'Img['+i+']').val(hyhImgUrl(imgurls[i])) + } + var maxNum = +$('.galleryImg').last().attr('data-id') + 1; //$('.batchImg').children('.galleryImg').length - 1; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html) + } else { + html = ""; + html = + '<div class="galleryImg photo" data-id="0" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[0]" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[0]"><span class=""></span></div>'; + $(".batchImg").html(html) + } + } + } else if (index == 'goodsCatIdPath') { + // data.goodsCatIdPath 三级目录 + var goodsCatIdPathArr = []; + var pathArr = ["largeCat", "mediumCat", "smallCat"] + //console.log(data.goodsCatIdPath); + goodsCatIdPathArr = data.goodsCatIdPath.split('_') + goodsCatIdPathArr.pop() //移除最后一个数组元素 _ + mui.each(pathArr, function(idx, ele) { + //console.log(idx); + switch (ele) { + case 'largeCat': + getCatIdPathName(goodsCatIdPathArr[0], function(data) { + getGoodsCats('largeCat', 0, goodsCatIdPathArr[0]); + }) + break; + case 'mediumCat': + getCatIdPathName(goodsCatIdPathArr[1], function(data) { + $('#mediumCat').html('<option selected value="' + goodsCatIdPathArr[1] + '">' + data.data.catName + + '</option>') + }); + break; + case 'smallCat': + getCatIdPathName(goodsCatIdPathArr[2], function(data) { + $('#smallCat').html('<option selected value="' + goodsCatIdPathArr[2] + '">' + data.data.catName + + '</option>') + }); + break; + } + }) + + } else { + $('#' + index).val(element) + } + }) + if ('' != data.goodsDesc) { + var Desc = escape2Html(data.goodsDesc) + editor.txt.html(Desc) + } + } else { + mui.alert(data.msg) + } + }) + + } else { + getGoodsCats("largeCat", 0) + getRecommend(page, pageSize); + $(".title").text("添加商品") + } + function getCatIdPathName(catId, callback) { + JZL.ajax(qlgUrl("app/goodscats/getCatName"), { + catId: catId + }, function(data) { + callback(data); + }) + } + + //获取商品总规格列表 + var page = 1; + var pageSize = 100; + var isjiazai = 1; + function getRecommend(page, pageSize, defaultVal) { + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 100 + } + recommenddata.shopId = shopId + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shops/getSpecs'), recommenddata, function(data) { + + + // ////console.log(data); + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="0">无规格属性</option>'; + if (typeof(defaultVal) == "undefined") { + // ////console.log(1); + $.each(data.Rows, function() { + html += '<option value= "' + this.id + '" data-id="' + this.id + ' ">' + this.setName + '</option>' + }); + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + } else { + // ////console.log(defaultVal); + $.each(data.Rows, function() { + if (this.id == defaultVal) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option data-id="' + this.id + '" value="' + this.id + '" ' + selected + '>' + this.setName + + '</option>'; + + }); + if (page == 1) { + $('#setNameId').html(html); + + } else { + $('#setNameId').append(html); + + } + + } + + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg); + // location.reload(); + } + isjiazai = 1; + }) + } + + //获取商品规格 + //笛卡尔积 + function calcDescartes(array) { + if (array.length < 2) return array[0] || []; + return [].reduce.call(array, function(col, set) { + var res = []; + col.forEach(function(c) { + set.forEach(function(s) { + var t = [].concat(Array.isArray(c) ? c : [c]); + t.push(s); + res.push(t); + }) + }); + return res; + }); + } + // 笛卡尔积 +// combins = function(args) { +// +// if (args.length < 2) return args[0] || []; +// // if (arguments.length < 2) return arguments[0] || []; +// //var args = Array.prototype.slice.call(arguments); +// var that = { +// index: 0, +// nth: function(n) { +// var result = [], +// d = 0; +// for (; d < this.dim; d++) { +// var l = this[d].length; +// var i = n % l; +// result.push(this[d][i]); +// n -= i; +// n /= l; +// } +// return result; +// }, +// next: function() { +// if (this.index >= size) return; +// var result = this.nth(this.index); +// this.index++; +// return result; +// } +// }; +// var size = 1; +// for (var i = 0; i < args.length; i++) { +// size = size * args[i].length; +// that[i] = args[i]; +// } +// that.size = size; +// that.dim = args.length; +// return that; +// } + + + + $('#setNameId').change(function() { + var id = $('#setNameId option:selected').attr('data-id') + // ////console.log(id); + + var html1 = ""; + if (typeof id == "undefined" || 0 == id) { + $(".pricset_con").hide() + } else { + $(".pricset_con").show() + JZL.ajax(qlgUrl('app/shops/getGoodsSpecCats'), { + shopId: shopId, + id: id + }, function(data) { + // ////console.log(data); + if (1 == data.status) { + html1 = ""; + var arr = []; + var arr2 = {}; + for (var i = 0; i < data.data.length; i++) { + arr.push(data.data[i].list); + arr2[data.data[i].catId] = data.data[i].list; + } + var calc = calcDescartes(arr); + var cIndex = 0; + var i = 0, + j = 0, + cArr = []; + while (true) { + if (cIndex >= calc.length) { + break; + } + //区分单规格和多规格 + if (Array.isArray(calc[cIndex])) { + res = calc[cIndex].join(' '); + cArr = calc[cIndex]; + cLength = calc[cIndex].length; + } else { + res = calc[cIndex]; + cArr[0] = res; + cLength = 1; + } + for (i = 0; i < cArr.length; i++) { + //获取catId + + // console.log(cArr[i]); + $.each(arr2, function(ind, val) { + //console.log(val); + $.each(val, function(index, value) { + if (value == cArr[i]) { + catId = ind; + // console.log(catId); + return; + } + }); + }); + html1 += '<input type="hidden" name="specItemIds[]" id="specItemIds[' + j + '][' + i + + ']" class="inp" value="0" />' + //属性值id + '<input type="hidden" name="specNamesId[]" id="specNamesId[' + j + '][' + i + ']" class="inp" value="' + + catId + '" />' + //分类ID + '<input type="hidden" name="specItems[]" id="specItems[' + j + '][' + i + ']" class="inp" value="' + cArr[ + i] + //属性值 + '" />'; + } + //console.log(j); + html1 += '<input type="hidden" name="specIds[]" id="specIds[' + j + ']" class="inp" value="0" />' + //规格表ID 新增传0 + '<div class="addcon_con shadown_wai"><div class="radio"><input name="defaultId" type="radio" value="' + j + + '" /></div><label for="" data-id = "' + j + + '" name="showSpecNames[]" class="">' + res + + '</label><input type="text" name="specPrice[]" id="specPrice[' + j + + ']" class="inp label-t" value="" /><input type="text" name="specStock[]" id="specStock[' + j + + ']" class="inp label-t" value=""/></div>'; + j++; + cIndex++; + } + + $('.pricset_con_con').html(html1); + } else { + mui.alert(data.msg) + } + }) + } + }) + + // 下一页 + var check = true; + mui("body").on('tap', '.next_btn', function() { + check = true; + $('.isemptyinp').each(function() { + if (!this.value || "" == $.trim(this.value)) { + var label = this.previousElementSibling; + mui.alert(label.innerText + "不允许为空") + check = false; + return false; + } + }) + + if ($("#shopPrice").val() == "" & $("#setNameId option:selected").val() == "0" & check == true) { + mui.alert("商品没有属性必须输入商品价格") + check = false; + return false; + } + if ($("#setNameId option:selected").val() != 0 && check == true) { + + if ($('input[name="defaultId"]:checked').length == 0) { + mui.alert("请选择默认规格") + check = false; + return false + } + $('.pricset_con_con input').each(function() { + if ((!$(this).val() || "" == $.trim(this.value))) { + + + mui.alert("请输入数据") + $(this).focus(); + check = false; + return false; + } + }) + } + // var shopPrice= $('input[name="defaultId"]:checked').parent().parent().find('input[name="specPrice[]"]').val(); + // ////console.log(shopPrice) + if ($("#isSale").prop("checked")) { + isSale = "1"; + } else { + isSale = "0"; + } + if (check == true) { + $(".addcon").css("display", "none") + $(".pre").css("display", "block"); + backTop(); + } + + + }) + //预览 + $('.prelook').hide(); + // mui("body").on('tap', '.prelook', function() { + // + // + // + // }) + // 上一页 + mui('body').on('tap', '.pre_btn', function() { + $(".addcon").css("display", "block") + $(".pre").css("display", "none") + }) + // ////console.log($("#goodsDesc").text()); + + //提交 + // 判断是否上架 + var isSale = "", + setNameId, + isSpec; + //提交 + var click = false; + mui('.btn').on('tap', '.submit_btn ', function() { + // if (click == true) return; + richText = editor.txt.text() + // 判断有没有商品属性 + if ($("#setNameId option:selected").val() != 0) { + isSpec = 1; + } else { + isSpec = 0; + } + if (click == true) return; + if ($("#isSale").prop("checked")) { + isSale = "1"; + } else { + isSale = "0"; + } + var imgs = ''; + var data = $('input[name="gallery[]"]'); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + + }) + + + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + + + $('#gallery').val(imgs); + //默认选中 + var defaultPrice = $('input[name="defaultId"]:checked').parent().parent().find('input[name="specPrice[]"]').val(); + var params = JZL.getParams(".inp"); + params.shopId = shopId; + params.isSale = isSale; + params.isSpec = isSpec; + params.defaultId = $('input[name="defaultId"]:checked').val(); + params.goodsDesc = editor.txt.html(); + params.setNameId = $('#setNameId option:selected').val() + if (isSpec == 1) { + // params.shopPrice = shopPrice + $('#shopPrice').val(defaultPrice); + + } + params.shopPrice = $('#shopPrice').val() + click = true; + if (goodsId > 0) { + params.goodsId = goodsId; + + } + + JZL.ajax(qlgUrl('app/shops/addGoods'), params, function(data) { + + if (data.status == 1) { + click = false; + mui.toast(data.msg); + mui.back(); + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + + }) + + + }) + + //获取类目 + $('.selectarea').on("change", ".area", function() { + var objs = ['largeCat', 'mediumCat', 'smallCat']; + // var areaStr = ['请选择', '请选择', '请选择']; + var level = +$(this).attr('data-level') + 1; //0 + pid = $('#' + objs[level - 1] + ' option:selected').val(); + getGoodsCats(objs[level], pid); + + }) + + //三级类目 + function getGoodsCats(obj, pid, defaultId) { + JZL.ajax(qlgUrl('app/shops/getGoodsCats'), { + pid: pid + }, + function(data) { + // ////console.log(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">' + "请选择" + '</option>'; + if ('undefined' == typeof(defaultId)) { + $.each(data, function() { + // ////console.log(this); + html += '<option value="' + this.catId + '">' + this.catName + '</option>' + }); + } else { + $.each(data, function() { + if (this.catId == defaultId) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option value="' + this.catId + '" ' + selected + '>' + this.catName + '</option>' + }); + } + $('#' + obj).html(html); + } + }) + } + + // 上传图片 + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + + + that.html(html); + + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + + $(".oneImg").on("tap", '#goods', function() { + + + UP.init("goodsImg", "test", "goods") + openCamera(function(t, status, fileName, serverName) { + var html = '<img src="' + serverName + '" class="ossfile" data-src="' + fileName + + '" id="goods" alt=""><input type="hidden" value="' + fileName + + '" class="goodsImg inp" id="goodsImg"><span class=""></span>'; + + $(".goods").html(html); + + }) + }) + // 删除图片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + + var that = $(this) + + if (confirm('确认删除图片?')) { + that.parent().remove() + + } + }) + //上传图片到七牛; + + var uptoken = ''; + var rs = send_request(); + rs = JSON.parse(rs); + + uptoken = rs.token; + + function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + + serverUrl = hyhUrl('oss/qiniu.php'); + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + + }; + + + // 初始化七牛上传的方法 + function uploadInit() { + var btnId = editor.imgMenuId; + var containerId = editor.toolbarElemId; + var textElemId = editor.textElemId; + // 创建上传对象 + var uploader = Qiniu.uploader({ + runtimes: 'html5,flash,html4', //上传模式,依次退化 + browse_button: btnId, //上传选择的点选按钮,**必需** + //uptoken_url: rs, + //Ajax请求upToken的Url,**强烈建议设置**(服务端提供) + uptoken: uptoken, + // url: 'http://up-z1.qiniup.com', + + // uptoken : '<Your upload token>', + //若未指定uptoken_url,则必须指定 uptoken ,uptoken由其他程序生成 + // unique_names: true, + // 默认 false,key为文件名。若开启该选项,SDK会为每个文件自动生成key(文件名) + // save_key: true, + // 默认 false。若在服务端生成uptoken的上传策略中指定了 `sava_key`,则开启,SDK在前端将不对key进行任何处理 + // domain: 'http://7xrjl5.com1.z0.glb.clouddn.com/', + // domain:$('#domain').val(), + domain: rs.url, + + //bucket 域名,下载资源时用到,**必需** + container: containerId, //上传区域DOM ID,默认是browser_button的父元素, + max_file_size: '100mb', //最大文件体积限制 + flash_swf_url: '../js/plupload/Moxie.swf', //引入flash,相对路径 + filters: { + mime_types: [ + //只允许上传图片文件 (注意,extensions中,逗号后面不要加空格) + { + title: "图片文件", + extensions: "jpg,gif,png,bmp" + } + ] + }, + max_retries: 3, //上传失败最大重试次数 + dragdrop: true, //开启可拖曳上传 + drop_element: textElemId, //拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传 + chunk_size: '4mb', //分块上传时,每片的体积 + auto_start: true, //选择文件后自动上传,若关闭需要自己绑定事件触发上传 + init: { + 'FilesAdded': function(up, files) { + plupload.each(files, function(file) { + // 文件添加进队列后,处理相关的事情 + // printLog('on FilesAdded'); + }); + }, + 'BeforeUpload': function(up, file) { + // 每个文件上传前,处理相关的事情 + // printLog('on BeforeUpload'); + }, + 'UploadProgress': function(up, file) { + // 显示进度 + // printLog('进度 ' + file.percent) + }, + 'FileUploaded': function(up, file, info) { + // 每个文件上传成功后,处理相关的事情 + // 其中 info 是文件上传成功后,服务端返回的json,形式如 + // { + // "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98", + // "key": "gogopher.jpg" + // } + // printLog(info); + // 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html + + var domain = up.getOption('domain'); + var res = $.parseJSON(info); + var sourceLink = domain + res.key; //获取上传成功后的文件的Url + // 插入图片到editor + editor.cmd.do('insertHtml', '<img src="' + sourceLink + '" style="max-width:100%;"/>') + }, + 'Error': function(up, err, errTip) { + //上传出错时,处理相关的事情 + // printLog('on Error'); + }, + 'UploadComplete': function() { + //队列文件处理完毕后,处理相关的事情 + // printLog('on UploadComplete'); + } + // Key 函数如果有需要自行配置,无特殊需要请注释 + //, + // 'Key': function(up, file) { + // // 若想在前端对每个文件的key进行个性化处理,可以配置该函数 + // // 该配置必须要在 unique_names: false , save_key: false 时才生效 + // var key = ""; + // // do something with key here + // return key + // } + } + // domain 为七牛空间(bucket)对应的域名,选择某个空间后,可通过"空间设置->基本设置->域名设置"查看获取 + // uploader 为一个plupload对象,继承了所有plupload的方法,参考http://plupload.com/docs + }); + } + uploadInit(); + // 封装 ////console.log 函数 + function printLog(title, info) { + window.console && console.log(title, info); + } +}) diff --git a/static/app2/js/addhhrrz.js b/static/app2/js/addhhrrz.js new file mode 100755 index 0000000..09ef22c --- /dev/null +++ b/static/app2/js/addhhrrz.js @@ -0,0 +1,174 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var hhrrzid = self.id ? self.id : 0; + //console.log(hhrrzid); + if (hhrrzid > 0) { + $('.header .title').html("编辑合伙人认证信息") + $('#home_zhezhao').hide(); + + JZL.ajax(qlgUrl('app/auth/getAuthFamilyPersonalInfo'), { + id: hhrrzid + }, function(data) { + // //console.log(data); + if (data.status == 1) { + var data = data.data + $('#userName').val(data.familyName); + $('#cardId').val(data.familyIdCard); + $('#familyRelations').val(data.familyRelations); + // var html='<img data-src="' +data.familyRelationsImg + '" src="' + hyhImgUrl(data.familyRelationsImg)+ '" />'; + $("#familyRelationsImg").val(data.familyRelationsImg) + $("#idCardFrontImg").val(data.idCardFrontImg) + $("#idCardBackImg").val(data.idCardBackImg) + + $("#familyRelationsimg").attr("src", hyhImgUrl(data.familyRelationsImg)) + $("#idCardBack").attr("src", hyhImgUrl(data.idCardBackImg)) + + $("#idCardFront").attr("src", hyhImgUrl(data.idCardFrontImg)) + }else{ + mui.alert(data.msg) + } + }) + } else { + $('.header .title').html("添加合伙人认证信息") + } + + $('.lxy_home_zz ul').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + }) + var wait = 120; + + function time() { + if (wait == 0) { + $('.HQYZM').removeAttr("disabled"); + $('.HQYZM').val("重新发送"); + wait = 120; + } else { + $('.HQYZM').attr("disabled", true); + $('.HQYZM').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + mui('.lxy_home_zz ul').on('tap', '.HQYZM', function() { + var pargams = {} + pargams.userPhone = $('#indiv-tel').val(); + if ('' == pargams.userPhone) { + mui.alert('手机号不能为空!'); + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pargams.userPhone))) { + mui.alert("手机号码有误,请重填!"); + return; + } + + JZL.ajax(qlgUrl('app/auth/getPartnerPhoneCode'), pargams, function(data) { + data = toJson(data); + //console.log(data) + if (data.status == 1) { + telephoneNo = pargams.userPhone; + time(); + } else { + mui.alert(data.msg); + } + }); + }) + var click = 0; + + mui('.lxy_home_zz ul').on('tap', '.lxy_zz_btn', function() { + if (1 == click) return + click = 1 + var pargams = {} + pargams.userPhone = $('#indiv-tel').val(); + pargams.mobileCode = $('.YZM').val(); + if ('' == pargams.mobileCode) { + mui.alert('请输入验证码!'); + return; + } + JZL.ajax(qlgUrl('app/auth/getAuthInfoByMobile'), { + mobileCode: pargams.mobileCode + }, function(data) { + //console.log(data); + if (data.status == 1) { + var data = data.data; + $('#home_zhezhao').hide(); + + $('#familyName').val(data.uName); + $('#familyIdCard').val(data.idCard); + }else{ + mui.alert (data.msg) + } + }) + + }) + $(".photos_con").on("tap", '.business', function() { + UP.init("businessImg", "test", "business") + openCamera(); + }) + $(".photos_con").on("tap", '.idCardFront', function() { + UP.init("idCardFrontImg", "test", "idCardFront") + openCamera(); + }) + $(".photos_con").on("tap", '.idCardBack', function() { + UP.init("idCardBackImg", "test", "idCardBack") + openCamera(); + }) + + +var bcclick = 0 + $(".bc_btn").on('tap',function() { + if (bcclick == 1) return; + bcclick = 1; + var pargams = JZL.getParams('.inp'); + pargams.id = hhrrzid + + if (pargams.positionName == '') { + mui.alert('职位名不能为空!'); + return; + } + if (pargams.stake == '') { + mui.alert('持股比例不能为空!'); + return; + } + if (pargams.businessImg == '') { + mui.alert('请上传手持营业执照照!'); + return; + } + if (pargams.idCardFrontImg == '') { + mui.alert('请上传身份证正面照!'); + return; + } + if (pargams.idCardBackImg == '') { + mui.alert('请上传身份证反面照!'); + return; + } + + + JZL.ajax(qlgUrl('app/auth/setAuthPartner'), pargams, function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + var data = toJson(data); + if (data.status == 1) { + mui.back(); + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }) + + + }) +}) diff --git a/static/app2/js/addmemorandum.js b/static/app2/js/addmemorandum.js new file mode 100755 index 0000000..e0b5d05 --- /dev/null +++ b/static/app2/js/addmemorandum.js @@ -0,0 +1,84 @@ +mui.plusReady(function () { + + + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'selectfiles', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('ossfile').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false, 'complains'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('ossfile').innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if (info.status == 200) { + console.log(get_uploaded_object_name (file.name)); + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name)) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if (err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if (err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if (err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); +}) \ No newline at end of file diff --git a/static/app2/js/addproperties.js b/static/app2/js/addproperties.js new file mode 100755 index 0000000..006768b --- /dev/null +++ b/static/app2/js/addproperties.js @@ -0,0 +1,125 @@ +mui.plusReady(function() { + mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } + }); + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + var specCatsId = self.specCatsId ? self.specCatsId : 0; + var setName = self.setName ? self.setName : 0; + var index = 0; + //console.log(shopId,specCatsId,setName); + if (specCatsId > 0) { + $(".title").html("编辑产品规格属性") + JZL.ajax(qlgUrl("app/shops/getSpecCats"), { + id: specCatsId, + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status) { + $("#setName").val(setName) + //var specNames = $('input[name="specNames[]"]'); + //var specItems = $('input[name="specItems[]"]');// + var html = ''; + $.each(data.data, function(i, v) { + + html += + '<div class="row shadown_wai "><label>属性名称</label><input type="text" name="specNames[]" id="specNames[' + i + + ']" class="inp" value="' + this.catName + + '" /></div><div class="row shadown_wai "><label>可选值列表</label><input type="text" name="specItems[]" id="specItems[' + + i + ']" class="inp" value="' + this.itemNames + + '" placeholder="输入多项请用英文逗号分隔" /></div><input type="hidden" id="specNamesId[' + i + ']" class="inp" value="' + + this.catId + '" /><input type="hidden" id="specItemsId[' + i + ']" class="inp" value="' + this.itemId + + '" />' + }) + + $('.con_con').append(html); + + // $(specNames[i]).val(data.data[i].catName) + // $(specItems[i]).val(data.data[i].itemNames) + // } + } else { + mui.alert(data.msg) + } + + }) + + } else { + $(".title").html("添加产品规格属性") + + var html = ''; + html = '<div class="row shadown_wai "><label>属性名称</label><input type="text" name="specNames[]" id="specNames[' + + index + + ']" class="inp" value="" /></div><div class="row shadown_wai "><label>可选值列表</label><input type="text" name="specItems[]" id="specItems[' + + index + + ']" class="inp" value="" placeholder="输入多项请用英文逗号分隔" /></div><input type="hidden" id="specNamesId[0]" class="inp" value="0" /><input type="hidden" id="specItemsId[0]" class="inp" value="0" />' + index++ + $('.con_con').append(html); + + } + + mui('body').on('tap', '.add1', function() { + var html = ''; + html += '<div class="row shadown_wai "><label>属性名称</label><input type="text" name="specNames[]" id="specNames[' + index + + ']" class="inp" value="" /></div><div class="row shadown_wai "><label>可选值列表</label><input type="text" name="specItems[]" id="specItems[' + + index + ']" class="inp" value="" /></div><input type="hidden" id="specNamesId[' + index + + ']" class="inp" value="0" /><input type="hidden" id="specItemsId[' + index + ']" class="inp" value="0" />' + $('.con_con').append(html); + index++; + }) + var click = false; + mui('body').on('tap', '.bc_btn', function() { + //if (true == click) return; + click = true; + var length = $('input[name="specNames[]"]').length; + var specName,specItem; + for (var i = 0; i < length; i++) { + specName = document.getElementById('specNames[' + +i + ']'); + specItem = document.getElementById('specItems[' + +i + ']'); + if ('' == specItem.value && '' == specItem.value) { + if (specCatsId == 0) { + specName.classList.remove("inp"); + specItem.classList.remove("inp"); + document.getElementById('specNamesId[' + +i + ']').classList.remove("inp"); + document.getElementById('specItemsId[' + +i + ']').classList.remove("inp"); + } + } else { + if ('' == specName.value) { + mui.alert('请输入属性名'); + specName.focus(); + return; + } + if ('' == specItem.value) { + specItem.focus(); + mui.alert('请输入属性值'); + return; + } + specItem.value = specItem.value.replace(/,/g, ','); + } + } + var params = JZL.getParams(".inp"); +// $.each(params,function(i,v){ +// params[i] = v.replace(/,/g, ','); +// }) + params.shopId = shopId; + if (specCatsId > 0) { + params.id = specCatsId; + } + JZL.ajax(qlgUrl("app/shops/setSpecs"), params, function(data) { + //console.log(data); + if (data.status == 1) { + mui.toast('添加规格成功'); + mui.back(); + } else { + mui.alert(data.msg); + //location.reload(); + } + click = false; + }) + }) +}) diff --git a/static/app2/js/addqrbb.js b/static/app2/js/addqrbb.js new file mode 100755 index 0000000..8dfa5eb --- /dev/null +++ b/static/app2/js/addqrbb.js @@ -0,0 +1,89 @@ +mui.init({ + beforeback: function() {     //获得父页面的webview + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { +var self = plus.webview.currentWebview(); + // //console.log(self); + var qrbbid = self.id ? self.id : 0; + //console.log(qrbbid);// + + if (qrbbid >0) { + $('.header .title').html("编辑亲人报备信息") + JZL.ajax(qlgUrl('app/auth/getAuthFamilyReportInfo'), {id: qrbbid}, function(data) { + //console.log(data); + if (data.status == 1) { + var data = data.data + $('#familyName').val(data.familyName); + $('#familyIdCard').val(data.familyIdCard); + $('#familyRelations').val(data.familyRelations); +// var html='<img data-src="' +data.familyRelationsImg + '" src="' + hyhImgUrl(data.familyRelationsImg)+ '" />'; +// $('#ossfile').html(html); +$('#familyRelationsImg').val(data.familyRelationsImg) +$('#familyRelations1').attr('src',hyhImgUrl(data.familyRelationsImg)) + } else { + mui.alert(data.msg); + } + }) + }else{ + $('.header .title').html("添加亲人报备信息") + + } +var click = false; + + $(".bc_btn").on('tap', function() { + if(click ==true) return; + + click=true; + + var pargams = JZL.getParams('.inp'); + if (pargams.familyName == '') { + mui.alert('姓名不能为空!'); + return; + } + if (pargams.familyIdCard == '') { + mui.alert('身份证号不能为空!'); + return; + } + if (pargams.familyRelations == '') { + mui.alert('与户主关系不能为空!'); + return; + } + if (pargams.familyRelationsImg == '') { + mui.alert('请上传与户主关系照!'); + return; + } + // $('.bc_btn').attr('disabled','disabled'); + if (qrbbid >0) { + //console.log(qrbbid); + pargams.id=qrbbid + } + + JZL.ajax(qlgUrl('app/auth/setAuthFamilyReport'),pargams,function(data){ + + //console.log(data); + var data = toJson(data); + if(data.status == 1) { + mui.back(); + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + }) + + click = false + + }) +//上传图片 + $('.renzhengphoto').on('tap','.familyRelations',function () { + UP.init("familyRelationsImg", "test", "familyRelations1") + openCamera() + }) + + }) + diff --git a/static/app2/js/addqrrz.js b/static/app2/js/addqrrz.js new file mode 100755 index 0000000..b0ee107 --- /dev/null +++ b/static/app2/js/addqrrz.js @@ -0,0 +1,213 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var qrrzid = self.id ? self.id : 0; + //console.log(qrrzid); + if (qrrzid > 0) { + $('.header .title').html("编辑亲人认证信息") + $('#home_zhezhao').hide(); + + JZL.ajax(qlgUrl('app/auth/getAuthFamilyPersonalInfo'), { + id: qrrzid + }, function(data) { + //console.log(data); + if (data.status == 1) { + var data = data.data + $('#userName').val(data.familyName); + $('#cardId').val(data.familyIdCard); + $('#familyRelations').val(data.familyRelations); + // var html='<img data-src="' +data.familyRelationsImg + '" src="' + hyhImgUrl(data.familyRelationsImg)+ '" />'; + $("#familyRelationsImg").val(data.familyRelationsImg) + $("#idCardFrontImg").val(data.idCardFrontImg) + $("#idCardBackImg").val(data.idCardBackImg) + + $("#familyRelationsimg").attr("src", hyhImgUrl(data.familyRelationsImg)) + $("#idCardBack").attr("src", hyhImgUrl(data.idCardBackImg)) + $("#idCardFront").attr("src", hyhImgUrl(data.idCardFrontImg)) + } else { + mui.alert(data.msg) + } + }) + + + var click = false; + + $(".bc_btn").on('tap', function() { + if (click == true) return; + var pargams = JZL.getParams('.inp'); + pargams.id = qrrzid + if (pargams.familyRelations == '') { + mui.alert('与户主关系不能为空!'); + return; + } + if (pargams.familyRelationsImg == '') { + mui.alert('请上传与户主关系照!'); + return; + } + if (pargams.idCardFrontImg == '') { + mui.alert('请上传身份证正面照!'); + return; + } + if (pargams.idCardBackImg == '') { + mui.alert('请上传身份证反面照!'); + return; + } + click = true; + JZL.ajax(qlgUrl('app/auth/setAuthFamilyPersonal'), pargams, function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + var data = toJson(data); + if (data.status == 1) { + mui.back(); + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + }) + + + }) + } else { + $('.header .title').html("添加亲人认证信息") + } + + + + + + + + + + + + $('.lxy_home_zz ul').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + }) + var wait = 120; + + function time() { + if (wait == 0) { + $('.HQYZM').removeAttr("disabled"); + $('.HQYZM').val("重新发送"); + wait = 120; + } else { + $('.HQYZM').attr("disabled", true); + $('.HQYZM').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + mui('.lxy_home_zz ul').on('tap', '.HQYZM', function() { + var pargams = {} + pargams.userPhone = $('#indiv-tel').val(); + if ('' == pargams.userPhone) { + mui.alert('手机号不能为空!'); + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pargams.userPhone))) { + mui.alert("手机号码有误,请重填!"); + return; + } + + JZL.ajax(qlgUrl('app/auth/getFamilyPhoneCode'), pargams, function(data) { + data = toJson(data); + //console.log(data) + if (data.status == 1) { + telephoneNo = pargams.userPhone; + time(); + } else { + mui.alert(data.msg); + } + }); + }) + mui('.lxy_home_zz ul').on('tap', '.lxy_zz_btn', function() { + var pargams = {} + pargams.userPhone = $('#indiv-tel').val(); + pargams.mobileCode = $('.YZM').val(); + if ('' == pargams.mobileCode) { + mui.alert('请输入验证码!'); + return; + } + JZL.ajax(qlgUrl('app/auth/getAuthInfoByMobile'), pargams, function(data) { + //console.log(data) + if (data.status == 1) { + var data = data.data; + $('#home_zhezhao').hide(); + $('#userName').val(data.uName); + $('#cardId').val(data.idCard); + $('#telephone').val(pargams.userPhone); + } else { + mui.alert(data.msg); + } + }) + + + }) + $(".photos_con").on("tap", '.familyRelations', function() { + UP.init("familyRelationsImg", "test", "familyRelationsimg") + openCamera(); + }) + $(".photos_con").on("tap", '.idCardFront', function() { + UP.init("idCardFrontImg", "test", "idCardFront") + openCamera(); + }) + $(".photos_con").on("tap", '.idCardBack', function() { + UP.init("idCardBackImg", "test", "idCardBack") + openCamera(); + }) + + var click = false; + + $(".bc_btn").on('tap', function() { + if (click == true) return; + var pargams = JZL.getParams('.inp'); + + if (pargams.familyRelations == '') { + mui.alert('与户主关系不能为空!'); + return; + } + if (pargams.familyRelationsImg == '') { + mui.alert('请上传与户主关系照!'); + return; + } + if (pargams.idCardFrontImg == '') { + mui.alert('请上传身份证正面照!'); + return; + } + if (pargams.idCardBackImg == '') { + mui.alert('请上传身份证反面照!'); + return; + } + // $('.bc_btn').attr('disabled','disabled'); + click = true; + JZL.ajax(qlgUrl('app/auth/setAuthFamilyPersonal'), pargams, function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + var data = toJson(data); + if (data.status == 1) { + mui.back(); + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + }) + + + }) +}) diff --git a/static/app2/js/addshopping.js b/static/app2/js/addshopping.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/addyhk.js b/static/app2/js/addyhk.js new file mode 100755 index 0000000..77b1f01 --- /dev/null +++ b/static/app2/js/addyhk.js @@ -0,0 +1,98 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + + $('#_select').on('change', function() { + var selectValue = $('#_select option:selected').text(); //选中select的内容 + // alert("selectValue" + selectValue); + + $("#bankUserName").val(selectValue); + }) + var self = plus.webview.currentWebview(); + ////console.log(self); + var yhkid = self.id ? self.id : 0; + // //console.log(yhkid);// + + if (yhkid > 0) { + $('.header .title').html("编辑银行卡") + JZL.ajax(qlgUrl('app/auth/getCompanyBankInfo'), { + id: yhkid + }, function(data) { + ////console.log(data); + if (data.status == 1) { + var data = data.data + $('#_select').css("background", "none"); + $("#bankUserName").val(data.accountName); + $('.bankname').prepend('<option value="' + data.bankName + '">' + data.bankName + '</option>'); + $("#cardnum").val(data.bankNo); + } else { + mui.alert(data.msg); + } + }) + }else{ + $('.header .title').html("添加银行卡") + + } + // 选择银行 + JZL.ajax(qlgUrl('app/auth/getBankNameList'), {}, function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + ////console.log(data) + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">选择银行</option>'; + $.each(data, function() { + html += '<option value="' + this.bankName + '">' + this.bankName + '</option>' + }); + $('.bankname').append(html); + + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + }) + +//提交 +var click = false + $('.bc_btn').on('tap', function() { + if(true == click) return; + click =true; + var pargams = {}; + //编辑页面需要加id + if (yhkid > 0) { + pargams.id = yhkid; + } + pargams.accountName = $("#bankUserName").val(); + pargams.bankName = $(".bankname option:selected").text(); + pargams.bankNo = $("#cardnum").val(); + if ('' == pargams.accountName) { + mui.alert("请输入持卡人姓名") + return; + } + if ('' == pargams.bankNo) { + mui.alert("请输入银行卡号") + return; + } + if ('选择银行' == pargams.bankName) { + mui.alert("请输入银行名称") + return; + } + JZL.ajax(qlgUrl('app/auth/setBank'), pargams, function(data) { + data = toJson(data); + ////console.log(data) + if (data.status == 1) { + mui.back(); + } else { + mui.alert(data.msg); + } + }); + + }) +}) diff --git a/static/app2/js/applicationopen.js b/static/app2/js/applicationopen.js new file mode 100755 index 0000000..e6869cb --- /dev/null +++ b/static/app2/js/applicationopen.js @@ -0,0 +1,443 @@ +mui.plusReady(function() { + mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } + }); + var shopAddress = ""; + $('.header_con').append('<p class="header_con_bc">保存</p>') + $(".oper .next").css("width", "100%") + $(".oper .pre").css("width", "0px") + // 判断是编辑还是新增 + var self = plus.webview.currentWebview(); + // //console.log(self); + var shopId = self.id ? self.id : 0; + // //console.log(shopid); + if (shopId > 0) { + //console.log(22); + JZL.ajax(qlgUrl('app/shops/getShopJoinInfo'), { + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status) { + var data = data.data; + getMap(data.lng, data.lat); + mui.each(data, function(index, element) { + //console.log(element); + if ($('#' + index).attr("type") == "hidden") { + var imgindex = index.substring(0, index.length - 3); + var obj = '#' + imgindex + '' + // //console.log('#' + imgindex + '') + if (imgindex != "") { + if ($(obj).is('img')) { + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index + '').val(element) + } + } + + } else if ($('#' + index).is("select")) { + + switch (index) { + case 'provinceId': + getAreaName(element, 1, function(data) { + getArea(index, 1, 0, '请选择省', data.data.areaId); + // $('#'+index).html('<option selected value="'+data.data.areaId+'">'+data.data.areaName+'</option>') + }) + break; + case 'cityId': + getAreaName(element, 2, function(data) { + $('#' + index).html('<option selected value="' + data.data.areaId + '">' + data.data.areaName + + '</option>') + }); + break; + case 'countyId': + getAreaName(element, 3, function(data) { + $('#' + index).html('<option selected value="' + data.data.areaId + '">' + data.data.areaName + + '</option>') + }); + break; + case 'townId': + getAreaName(element, 4, function(data) { + $('#' + index).html('<option selected value="' + data.data.areaId + '">' + data.data.areaName + + '</option>') + }); + break; + case 'villageId': + getAreaName(element, 5, function(data) { + $('#' + index).html('<option selected value="' + data.data.areaId + '">' + data.data.areaName + + '</option>') + }); + break; + case 'bankName': + getBankList(element); + + break; + default: + break; + } + // $('#'+index+' option:selected').text(element) + // $('#'+index+' option:selected').attr('value',element) + // $('#'+index+' option:selected').attr('text',element) + } else { + $('#' + index).val(element) + // //console.log(this); + } + }) + shopAddress = $('#shopAddress').val(); + } else { + mui.alert(data.msg) + } + }) + setTimeout(function() { + $('#shopAddress').val(shopAddress) + }, 1000) + } else { + + getBankList(); + getArea('provinceId', 1, 0, '请选择省'); + getLocation(function(data) { + //console.log(11); + if (1 == data.status) { + $('#lng').val(data.lng); + $('#lat').val(data.lat); + getMap(data.lng, data.lat) + //console.log(JSON.stringify(data)); + } else { + mui.alert(data.errStr); + return; + } + }); + JZL.getItems('editorShopInfo') + } + + function getAreaName(id, level, callback) { + JZL.ajax(qlgUrl("app/Position/getAreaName"), { + id: id, + level: level + }, function(data) { + callback(data); + }) + } + //下一步 + mui('.next').on('tap', '.bc_btn', function() { + var params = JZL.getParams(".inp") + // //console.log(params); + // var html= + var idx = $(this).index() + 1; + var prenum = idx + 1; + // checkStep(idx) + if (checkStep(idx)) { + if (prenum !== 1) { + // //console.log(1); + $(".pre").attr("display", "block") + $(".oper .pre").css("width", "50%") + $(".oper .next").css("width", "50%") + } + if (prenum == 1) { + // //console.log(1); + $(".oper .next").css("width", "100%") + $(".oper .pre").css("width", "0px") + } + $('.con-nav ul li').eq(idx).addClass("active") + $('.next .bc_btn').eq(idx).show().siblings().hide() + $('.pre .pre_btn').eq(idx).show().siblings().hide() + $('.con-content .num').eq(idx).show().siblings().hide() + JZL.saveItems('.localinp', 'auth_personal'); + backTop() + } + }) + //上一步 + mui('.pre').on('tap', '.pre_btn', function() { + var idx = $(this).index() - 1; + var prenum = idx + 1; + if (checkStep(idx)) { + if (prenum !== 1) { + $(".pre").attr("display", "block") + $(".oper .pre").css("width", "50%") + $(".oper .next").css("width", "50%") + } + if (prenum == 1) { + $(".oper .next").css("width", "100%") + $(".oper .pre").css("width", "0px") + } + $('.con-nav ul li').eq(idx + 1).removeClass("active") + $('.next .bc_btn').eq(idx).show().siblings().hide() + $('.pre .pre_btn').eq(idx).show().siblings().hide() + $('.con-content .num').eq(idx).show().siblings().hide() + JZL.getItems('auth_personal'); + backTop() + } + }) + //五级联动 + $('.selectarea').on("change", ".area", function() { + var areas = ['province', 'city', 'county', 'town', 'village']; + var areaStr = ['请选择省', '请选择市', '选择区县', '选择乡镇', '选择村社区']; + var level = $(this).attr('data-level'); //1 + pid = $("#" + areas[level - 1] + "Id option:selected").val(); + var sonLevel = +level + 1; + getArea(areas[level] + 'Id', sonLevel, pid, areaStr[level]); + + }) + + function getArea(area, level, pid, selectAreaStr, defaultId) { + JZL.ajax(qlgUrl('app/Position/listQuery'), { + level: level, + pid: pid + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">' + selectAreaStr + '</option>'; + if ('undefined' == typeof(defaultId)) { + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + } else { + $.each(data, function() { + if (this.areaId == defaultId) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option value="' + this.areaId + '" ' + selected + '>' + this.areaName + '</option>' + }); + } + + // //console.log(area) + $('#' + area).html(html); + + } else { + // mui.alert('发生错误请刷新后重试!'); + // // location.reload(); + mui.alert(data.msg) + } + }) + } + + // 上传图片 + + $(".photos_con").on("tap", '.sfzzm', function() { + UP.init("idCardFrontImg", "test", "idCardFront") + openCamera(); + }) + + $(".photos_con").on("tap", '.sfzfm', function() { + UP.init("idCardBackImg", "test", "idCardBack") + openCamera(); + }) + $(".photos_con").on("tap", '.weituoshu', function() { + UP.init("commissionImg", "test", "commission") + openCamera(); + }) + $(".photos_con").on("tap", '.shopsimg', function() { + UP.init("businessLicenceImg", "test", "businessLicence") + openCamera(); + }) + $(".photos_con").on("tap", '.querenshu', function() { + UP.init("confirmationImg", "test", "confirmation") + openCamera(); + }) + + function getBankList(defaultBankName) { + JZL.ajax(qlgUrl('app/auth/getBankNameList'), { + + }, + function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data) + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">选择银行</option>'; + // var html=""; + if ('undefined' == typeof(defaultBankName)) { + $.each(data, function() { + // //console.log(data); + html += '<option value="' + this.bankName + '">' + this.bankName + '</option>' + }); + } else { + // //console.log(data); + $.each(data, function() { + // //console.log(data); + if (this.bankName == defaultBankName) { + selected = 'selected'; + } else { + selected = ''; + } + html += '<option value="' + this.bankName + '" ' + selected + '>' + this.bankName + '</option>' + }); + } + + $('.bankname').append(html); + + } else { + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + mui.alert(data.msg) + } + }) + } + + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 112 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.confirmationtext_con').html(data.articleContent) + + // } + + }); + + + function checkStep(step) { + var params = JZL.getParams(".inp") + // //console.log(params); + // //console.log(step); + switch (step) { + case 1: + if ('' == params.shopName) { + mui.alert("请输入店铺名称") + return; + } + if ('' == params.phone) { + mui.alert("请输入手机号码") + //console.log(params); + return; + } + if ('' == params.userName) { + mui.alert("请输入姓名") + return; + + } + + if ('' == params.provinceId) { + mui.alert("请输入所在省") + return; + + } + if ('' == params.cityId) { + mui.alert("请输入所在市") + return; + + } + if ('' == params.countyId) { + mui.alert("请输入所在区") + return; + + } + if ('' == params.townId) { + mui.alert("请输入所在镇") + return; + } + if ('' == params.villageId) { + mui.alert("请输入所在村") + return; + } + if ('' == params.shopAddress) { + mui.alert("请输入详细地址") + return; + } + if ('' == params.lat) { + mui.alert("请在地图上选择位置") + return; + } + break; + case 2: + if ('' == params.accountName) { + mui.alert("请输入持卡人姓名") + return; + + } + if ('' == params.bankName) { + mui.alert("请输入银行名称") + return; + + } + if ('' == params.bankNo) { + mui.alert("请输入银行卡号") + return; + + } + if ('' == params.userName) { + mui.alert("请输入开户行") + return; + + } + break; + case 3: + if ('' == params.idCardFrontImg) { + mui.alert("请上传身份证正面照") + return; + } + if ('' == params.idCardBackImg) { + mui.alert("请上传身份证反面照") + return; + } + if ('' == params.commissionImg) { + mui.alert("请上传直营人委托书照片") + return; + } + if ('' == params.businessLicenceImg) { + mui.alert("请上传营业执照照片") + return; + } + break; + case 4: + + + if ('' == params.commissionImg) { + mui.alert("请上传手持确认书照片") + return; + } + + break; + default: + break; + } + return true; + } + + // 保存 + mui('.header').on('tap','.header_con_bc',function(){ + JZL.saveItems (".inp","editorShopInfo"); + mui.toast('保存成功'); + }) + //提交 + var flag = false; + + + mui('.next').on('tap', '.finish', function() { + if (flag == true) return; + flag = true + var params = JZL.getParams(".inp") + if (shopId > 0) { + params.shopId = shopId + } + + JZL.ajax(qlgUrl('app/shops/shopJoin'), params, function(data) { + + //console.log(data); + if (1 == data.status) { + // JZL.saveItems ("inp","editorShopInfo"); + mui.toast(data.msg) + localStorage.removeItem("editorShopInfo") + mui.back() + // JZL.openWindow("myshops.html", "myshops.html") + // JZL.openWindow("myshop.html", "myshop.html") + + } else { + mui.alert(data.msg) + } + + + }) + + }) + +}) diff --git a/static/app2/js/appraise.js b/static/app2/js/appraise.js new file mode 100755 index 0000000..84b0e17 --- /dev/null +++ b/static/app2/js/appraise.js @@ -0,0 +1,319 @@ +var isjiazai = 1; +var type = ''; +var page = 1 + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var data_id = self.goodsId; + // //console.log(data_id) + + function getData(page, pagesize, type) { + var set_data = { + goodsId: data_id, + type: type ? type : '', + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + if (isjiazai == 1) { + isjiazai = 0 + + } else { + return; + } + mui.ajax(qlgUrl('app/goodsappraises/getById'), { + + data: set_data, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + var html = ''; + + if (data.status == 1) { + data = data.data; + $('#sum').html('全部(' + data.sum + ')'); + $('#pic').html('有图(' + data.picNum + ')'); + $('#bad').html('差评(' + data.badNum + ')'); + $('#good').html('中评(' + data.goodNum + ')'); + $('#best').html('好评(' + data.bestNum + ')'); + if (data.Rows == '') { + if (page == 1) { + $('.pj_list').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多评价</p>'); + } else { + $('.pj_list').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多评价</p>'); + } + + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + + var userImg = ''; + if (this.userPhoto) { + userImg = hyhImgUrl(this.userPhoto); + } else { + userImg = '../img/mujiimg.png' + } + + html += '<div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + userImg + '" /><p>' + this.loginName + + '</p></div><div class="pjbcon">' + this.content + '</div>'; + + if (this.shopReply != null) { + html += '<div class="zjpj"><div class="sanjiao"></div><div class="pjzhuijia">商家回复:' + this.shopReply + + '</div></div>'; + } + html += '<div class="pjclass">' + this.goodsSpecNames + '</div><div class="pjclass">' + this.createTime + + '</div>'; + if (this.images != '' && this.images != null) { + html += '<div class="gallety"><div class="my-gallery clearfix" data-pswp-uid="">'; + var imgArr = this.images.split(','); + $.each(imgArr, function() { + html += '<figure><div class="img-dv"><a href="' + hyhImgUrl(this) + + '/thumb512" data-size="1920x1080"><img src="' + hyhImgUrl(this) + '/thumb78"></a></div></figure>'; + // //console.log(hyhImgUrl(this)) + }); + + html += '</div></div>'; + } + + html += '</div>'; + + }); + if (page == 1) { + $('.pj_list').html(html); + } else { + $('.pj_list').append(html); + } + + isjiazai = 1; + + setTimeout(function() { + $('.img-dv a').each(function() { + var that = $(this); + var img_ = new Image() + img_.src = that.attr('href'); + img_.onload = function() { + that.attr('data-size', img_.width + 'x' + img_.height); + } + }); + document.addEventListener('DOMAttrModified', function() { + $('.img-dv a').each(function() { + var that = $(this); + var img_ = new Image() + img_.src = that.attr('href'); + img_.onload = function() { + that.attr('data-size', img_.width + 'x' + img_.height); + } + }); + }, false); + + var initPhotoSwipeFromDOM = function(gallerySelector) { + // 解析来自DOM元素幻灯片数据(URL,标题,大小...) + var parseThumbnailElements = function(el) { + var thumbElements = el.childNodes, + numNodes = thumbElements.length, + items = [], + figureEl, + linkEl, + size, + item, + divEl; + for (var i = 0; i < numNodes; i++) { + figureEl = thumbElements[i]; // <figure> element + // 仅包括元素节点 + if (figureEl.nodeType !== 1) { + continue; + } + divEl = figureEl.children[0]; + linkEl = divEl.children[0]; // <a> element + size = linkEl.getAttribute('data-size').split('x'); + // 创建幻灯片对象 + item = { + src: linkEl.getAttribute('href'), + w: parseInt(size[0], 10), + h: parseInt(size[1], 10) + // w: '100%' + }; + if (figureEl.children.length > 1) { + item.title = figureEl.children[1].innerHTML; + } + if (linkEl.children.length > 0) { + // <img> 缩略图节点, 检索缩略图网址 + item.msrc = linkEl.children[0].getAttribute('src'); + } + item.el = figureEl; // 保存链接元素 for getThumbBoundsFn + items.push(item); + } + return items; + }; + + // 查找最近的父节点 + var closest = function closest(el, fn) { + return el && (fn(el) ? el : closest(el.parentNode, fn)); + }; + + // 当用户点击缩略图触发 + var onThumbnailsClick = function(e) { + e = e || window.event; + e.preventDefault ? e.preventDefault() : e.returnValue = false; + var eTarget = e.target || e.srcElement; + var clickedListItem = closest(eTarget, function(el) { + return (el.tagName && el.tagName.toUpperCase() === 'FIGURE'); + }); + if (!clickedListItem) { + return; + } + var clickedGallery = clickedListItem.parentNode, + childNodes = clickedListItem.parentNode.childNodes, + numChildNodes = childNodes.length, + nodeIndex = 0, + index; + for (var i = 0; i < numChildNodes; i++) { + if (childNodes[i].nodeType !== 1) { + continue; + } + if (childNodes[i] === clickedListItem) { + index = nodeIndex; + break; + } + nodeIndex++; + } + if (index >= 0) { + openPhotoSwipe(index, clickedGallery); + } + return false; + }; + + var photoswipeParseHash = function() { + var hash = window.location.hash.substring(1), + params = {}; + if (hash.length < 5) { + return params; + } + var vars = hash.split('&'); + for (var i = 0; i < vars.length; i++) { + if (!vars[i]) { + continue; + } + var pair = vars[i].split('='); + if (pair.length < 2) { + continue; + } + params[pair[0]] = pair[1]; + } + if (params.gid) { + params.gid = parseInt(params.gid, 10); + } + return params; + }; + + var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) { + var pswpElement = document.querySelectorAll('.pswp')[0], + gallery, + options, + items; + items = parseThumbnailElements(galleryElement); + // 这里可以定义参数 + options = { + barsSize: { + top: 100, + bottom: 100 + }, + fullscreenEl: false, + shareButtons: [{ + id: 'wechat', + label: '分享微信', + url: '#' + }, + { + id: 'weibo', + label: '新浪微博', + url: '#' + }, + { + id: 'download', + label: '保存图片', + url: '{{raw_image_url}}', + download: true + } + ], + galleryUID: galleryElement.getAttribute('data-pswp-uid'), + getThumbBoundsFn: function(index) { + var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail + pageYScroll = window.pageYOffset || document.documentElement.scrollTop, + rect = thumbnail.getBoundingClientRect(); + return { + x: rect.left, + y: rect.top + pageYScroll, + w: rect.width + }; + } + }; + if (fromURL) { + if (options.galleryPIDs) { + for (var j = 0; j < items.length; j++) { + if (items[j].pid == index) { + options.index = j; + break; + } + } + } else { + options.index = parseInt(index, 10) - 1; + } + } else { + options.index = parseInt(index, 10); + } + if (isNaN(options.index)) { + return; + } + if (disableAnimation) { + options.showAnimationDuration = 0; + } + gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options); + gallery.init(); + }; + + var galleryElements = document.querySelectorAll(gallerySelector); + for (var i = 0, l = galleryElements.length; i < l; i++) { + galleryElements[i].setAttribute('data-pswp-uid', i + 1); + galleryElements[i].onclick = onThumbnailsClick; + } + var hashData = photoswipeParseHash(); + if (hashData.pid && hashData.gid) { + openPhotoSwipe(hashData.pid, galleryElements[hashData.gid - 1], true, true); + } + }; + + initPhotoSwipeFromDOM('.my-gallery'); + }, 500) + } else { + //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + + }) + } + getData(1, 10) + $('.nav').on('tap', '.nav_', function() { + $(this).addClass('on').siblings().removeClass('on'); + type = $(this).attr('id'); + page = 1; + isjiazai = 1; + getData(page, 10, type) + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getData(page, 10, type) + } + + } + }) + +}) diff --git a/static/app2/js/bill.js b/static/app2/js/bill.js new file mode 100755 index 0000000..8d73c86 --- /dev/null +++ b/static/app2/js/bill.js @@ -0,0 +1,72 @@ +var vouchersType = '', + isExpected = ''; +var data_href = ''; +var pageSize = 20; +var count = 1; +var isLoading = false; +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + //console.log(self) + vouchersType = self.data_type; + isExpected = self.data_expected; + data_href = data_href; + getBillList(count, pageSize) + + function getBillList(count, pageSize) { + if (true == isLoading) return; + isLoading = true; + JZL.ajax(qlgUrl('app/Uservouchers/getVouchers'), { + page: count, + perPage: pageSize, + vouchersType: vouchersType, + isExpected: isExpected, + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + //console.log(data); + var data = toJson(data); + if (data.status == 1) { + data = data.data; + if (data.Rows == '') { + $('.con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + return; + } + var html = '' + $.each(data.Rows, function() { + html += + '<div class="row shadown_wai"><div class="left"> <img src="../img/dingwei1.png" alt=""></div><div class="context"><p class="con_text">' + + this.remark + '</p><p class="con_time">' + this.createTime + '</p></div><div class="num">-' + this.num + + '</div></div>'; + + }) + if (count == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + + } else { + mui.alert(data.msg) + } + isLoading = false; + }); + } + + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (e.cancelable) { + // 判断默认行为是否已经被禁用 + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (scroll.y == scroll.maxScrollY) { + if (isLoading == false) { + count++; + getBillList(count, pageSize) + } + } + }) +}) diff --git a/static/app2/js/binaryajax.js b/static/app2/js/binaryajax.js new file mode 100755 index 0000000..8084ccb --- /dev/null +++ b/static/app2/js/binaryajax.js @@ -0,0 +1,287 @@ + +/* + * Binary Ajax 0.1.10 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt] + */ + +var BinaryFile = function(strData, iDataOffset, iDataLength) { + var data = strData; + var dataOffset = iDataOffset || 0; + var dataLength = 0; + + this.getRawData = function() { + return data; + } + + if (typeof strData == "string") { + dataLength = iDataLength || data.length; + + this.getByteAt = function(iOffset) { + return data.charCodeAt(iOffset + dataOffset) & 0xFF; + } + + this.getBytesAt = function(iOffset, iLength) { + var aBytes = []; + + for (var i = 0; i < iLength; i++) { + aBytes[i] = data.charCodeAt((iOffset + i) + dataOffset) & 0xFF + } + ; + + return aBytes; + } + } else if (typeof strData == "unknown") { + dataLength = iDataLength || IEBinary_getLength(data); + + this.getByteAt = function(iOffset) { + return IEBinary_getByteAt(data, iOffset + dataOffset); + } + + this.getBytesAt = function(iOffset, iLength) { + return new VBArray(IEBinary_getBytesAt(data, iOffset + dataOffset, iLength)).toArray(); + } + } + + this.getLength = function() { + return dataLength; + } + + this.getSByteAt = function(iOffset) { + var iByte = this.getByteAt(iOffset); + if (iByte > 127) + return iByte - 256; + else + return iByte; + } + + this.getShortAt = function(iOffset, bBigEndian) { + var iShort = bBigEndian ? + (this.getByteAt(iOffset) << 8) + this.getByteAt(iOffset + 1) + : (this.getByteAt(iOffset + 1) << 8) + this.getByteAt(iOffset) + if (iShort < 0) + iShort += 65536; + return iShort; + } + this.getSShortAt = function(iOffset, bBigEndian) { + var iUShort = this.getShortAt(iOffset, bBigEndian); + if (iUShort > 32767) + return iUShort - 65536; + else + return iUShort; + } + this.getLongAt = function(iOffset, bBigEndian) { + var iByte1 = this.getByteAt(iOffset), + iByte2 = this.getByteAt(iOffset + 1), + iByte3 = this.getByteAt(iOffset + 2), + iByte4 = this.getByteAt(iOffset + 3); + + var iLong = bBigEndian ? + (((((iByte1 << 8) + iByte2) << 8) + iByte3) << 8) + iByte4 + : (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1; + if (iLong < 0) + iLong += 4294967296; + return iLong; + } + this.getSLongAt = function(iOffset, bBigEndian) { + var iULong = this.getLongAt(iOffset, bBigEndian); + if (iULong > 2147483647) + return iULong - 4294967296; + else + return iULong; + } + + this.getStringAt = function(iOffset, iLength) { + var aStr = []; + + var aBytes = this.getBytesAt(iOffset, iLength); + for (var j = 0; j < iLength; j++) { + aStr[j] = String.fromCharCode(aBytes[j]); + } + return aStr.join(""); + } + + this.getCharAt = function(iOffset) { + return String.fromCharCode(this.getByteAt(iOffset)); + } + this.toBase64 = function() { + return window.btoa(data); + } + this.fromBase64 = function(strBase64) { + data = window.atob(strBase64); + } +} + + +var BinaryAjax = (function() { + + function createRequest() { + var oHTTP = null; + if (window.ActiveXObject) { + oHTTP = new ActiveXObject("Microsoft.XMLHTTP"); + } else if (window.XMLHttpRequest) { + oHTTP = new XMLHttpRequest(); + } + return oHTTP; + } + + function getHead(strURL, fncCallback, fncError) { + var oHTTP = createRequest(); + if (oHTTP) { + if (fncCallback) { + if (typeof(oHTTP.onload) != "undefined") { + oHTTP.onload = function() { + if (oHTTP.status == "200") { + fncCallback(this); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + }; + } else { + oHTTP.onreadystatechange = function() { + if (oHTTP.readyState == 4) { + if (oHTTP.status == "200") { + fncCallback(this); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + } + }; + } + } + oHTTP.open("HEAD", strURL, true); + oHTTP.send(null); + } else { + if (fncError) + fncError(); + } + } + + function sendRequest(strURL, fncCallback, fncError, aRange, bAcceptRanges, iFileSize) { + var oHTTP = createRequest(); + if (oHTTP) { + + var iDataOffset = 0; + if (aRange && !bAcceptRanges) { + iDataOffset = aRange[0]; + } + var iDataLen = 0; + if (aRange) { + iDataLen = aRange[1] - aRange[0] + 1; + } + + if (fncCallback) { + if (typeof(oHTTP.onload) != "undefined") { + oHTTP.onload = function() { + if (oHTTP.status == "200" || oHTTP.status == "206" || oHTTP.status == "0") { + oHTTP.binaryResponse = new BinaryFile(oHTTP.responseText, iDataOffset, iDataLen); + oHTTP.fileSize = iFileSize || oHTTP.getResponseHeader("Content-Length"); + fncCallback(oHTTP); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + }; + } else { + oHTTP.onreadystatechange = function() { + if (oHTTP.readyState == 4) { + if (oHTTP.status == "200" || oHTTP.status == "206" || oHTTP.status == "0") { + // IE6 craps if we try to extend the XHR object + var oRes = { + status: oHTTP.status, + // IE needs responseBody, Chrome/Safari needs responseText + binaryResponse: new BinaryFile( + typeof oHTTP.responseBody == "unknown" ? oHTTP.responseBody : oHTTP.responseText, iDataOffset, iDataLen + ), + fileSize: iFileSize || oHTTP.getResponseHeader("Content-Length") + }; + fncCallback(oRes); + } else { + if (fncError) + fncError(); + } + oHTTP = null; + } + }; + } + } + oHTTP.open("GET", strURL, true); + + if (oHTTP.overrideMimeType) + oHTTP.overrideMimeType('text/plain; charset=x-user-defined'); + + if (aRange && bAcceptRanges) { + oHTTP.setRequestHeader("Range", "bytes=" + aRange[0] + "-" + aRange[1]); + } + + oHTTP.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1970 00:00:00 GMT"); + + oHTTP.send(null); + } else { + if (fncError) + fncError(); + } + } + + return function(strURL, fncCallback, fncError, aRange) { + + if (aRange) { + getHead( + strURL, + function(oHTTP) { + var iLength = parseInt(oHTTP.getResponseHeader("Content-Length"), 10); + var strAcceptRanges = oHTTP.getResponseHeader("Accept-Ranges"); + + var iStart, iEnd; + iStart = aRange[0]; + if (aRange[0] < 0) + iStart += iLength; + iEnd = iStart + aRange[1] - 1; + + sendRequest(strURL, fncCallback, fncError, [iStart, iEnd], (strAcceptRanges == "bytes"), iLength); + } + ); + + } else { + sendRequest(strURL, fncCallback, fncError); + } + } + +}()); + +/* + document.write( + "<script type='text/vbscript'>\r\n" + + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n" + + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n" + + "End Function\r\n" + + "Function IEBinary_getLength(strBinary)\r\n" + + " IEBinary_getLength = LenB(strBinary)\r\n" + + "End Function\r\n" + + "</script>\r\n" + ); + */ + +document.write( + "<script type='text/vbscript'>\r\n" + + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n" + + " IEBinary_getByteAt = AscB(MidB(strBinary, iOffset + 1, 1))\r\n" + + "End Function\r\n" + + "Function IEBinary_getBytesAt(strBinary, iOffset, iLength)\r\n" + + " Dim aBytes()\r\n" + + " ReDim aBytes(iLength - 1)\r\n" + + " For i = 0 To iLength - 1\r\n" + + " aBytes(i) = IEBinary_getByteAt(strBinary, iOffset + i)\r\n" + + " Next\r\n" + + " IEBinary_getBytesAt = aBytes\r\n" + + "End Function\r\n" + + "Function IEBinary_getLength(strBinary)\r\n" + + " IEBinary_getLength = LenB(strBinary)\r\n" + + "End Function\r\n" + + "</script>\r\n" + ); \ No newline at end of file diff --git a/static/app2/js/canvasResize.js b/static/app2/js/canvasResize.js new file mode 100755 index 0000000..eb675ac --- /dev/null +++ b/static/app2/js/canvasResize.js @@ -0,0 +1,344 @@ +/* + * + * canvasResize + * + * Version: 1.2.0 + * Date (d/m/y): 02/10/12 + * Update (d/m/y): 14/05/13 + * Original author: @gokercebeci + * Licensed under the MIT license + * - This plugin working with binaryajax.js and exif.js + * (It's under the MPL License http://www.nihilogic.dk/licenses/mpl-license.txt) + * Demo: http://canvasResize.gokercebeci.com/ + * + * - I fixed iOS6 Safari's image file rendering issue for large size image (over mega-pixel) + * using few functions from https://github.com/stomita/ios-imagefile-megapixel + * (detectSubsampling, ) + * And fixed orientation issue by using https://github.com/jseidelin/exif-js + * Thanks, Shinichi Tomita and Jacob Seidelin + */ + +(function($) { + var pluginName = 'canvasResize', + methods = { + newsize: function(w, h, W, H, C) { + var c = C ? 'h' : ''; + if ((W && w > W) || (H && h > H)) { + var r = w / h; + if ((r >= 1 || H === 0) && W && !C) { + w = W; + h = (W / r) >> 0; + } else if (C && r <= (W / H)) { + w = W; + h = (W / r) >> 0; + c = 'w'; + } else { + w = (H * r) >> 0; + h = H; + } + } + return { + 'width': w, + 'height': h, + 'cropped': c + }; + }, + dataURLtoBlob: function(data) { + var mimeString = data.split(',')[0].split(':')[1].split(';')[0]; + var byteString = atob(data.split(',')[1]); + var ab = new ArrayBuffer(byteString.length); + var ia = new Uint8Array(ab); + for (var i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + var bb = (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder); + if (bb) { + // console.log('BlobBuilder'); + bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder)(); + bb.append(ab); + return bb.getBlob(mimeString); + } else { + // console.log('Blob'); + bb = new Blob([ab], { + 'type': (mimeString) + }); + return bb; + } + }, + /** + * Detect subsampling in loaded image. + * In iOS, larger images than 2M pixels may be subsampled in rendering. + */ + detectSubsampling: function(img) { + var iw = img.width, ih = img.height; + if (iw * ih > 1048576) { // subsampling may happen over megapixel image + var canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, -iw + 1, 0); + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering edge pixel or not. + // if alpha value is 0 image is not covering, hence subsampled. + return ctx.getImageData(0, 0, 1, 1).data[3] === 0; + } else { + return false; + } + }, + /** + * Update the orientation according to the specified rotation angle + */ + rotate: function(orientation, angle) { + var o = { + // nothing + 1: {90: 6, 180: 3, 270: 8}, + // horizontal flip + 2: {90: 7, 180: 4, 270: 5}, + // 180 rotate left + 3: {90: 8, 180: 1, 270: 6}, + // vertical flip + 4: {90: 5, 180: 2, 270: 7}, + // vertical flip + 90 rotate right + 5: {90: 2, 180: 7, 270: 4}, + // 90 rotate right + 6: {90: 3, 180: 8, 270: 1}, + // horizontal flip + 90 rotate right + 7: {90: 4, 180: 5, 270: 2}, + // 90 rotate left + 8: {90: 1, 180: 6, 270: 3} + }; + return o[orientation][angle] ? o[orientation][angle] : orientation; + }, + /** + * Transform canvas coordination according to specified frame size and orientation + * Orientation value is from EXIF tag + */ + transformCoordinate: function(canvas, width, height, orientation) { + switch (orientation) { + case 5: + case 6: + case 7: + case 8: + canvas.width = height; + canvas.height = width; + break; + default: + canvas.width = width; + canvas.height = height; + } + var ctx = canvas.getContext('2d'); + switch (orientation) { + case 1: + // nothing + break; + case 2: + // horizontal flip + ctx.translate(width, 0); + ctx.scale(-1, 1); + break; + case 3: + // 180 rotate left + ctx.translate(width, height); + ctx.rotate(Math.PI); + break; + case 4: + // vertical flip + ctx.translate(0, height); + ctx.scale(1, -1); + break; + case 5: + // vertical flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.scale(1, -1); + break; + case 6: + // 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(0, -height); + break; + case 7: + // horizontal flip + 90 rotate right + ctx.rotate(0.5 * Math.PI); + ctx.translate(width, -height); + ctx.scale(-1, 1); + break; + case 8: + // 90 rotate left + ctx.rotate(-0.5 * Math.PI); + ctx.translate(-width, 0); + break; + default: + break; + } + }, + /** + * Detecting vertical squash in loaded image. + * Fixes a bug which squash image vertically while drawing into canvas for some images. + */ + detectVerticalSquash: function(img, iw, ih) { + var canvas = document.createElement('canvas'); + canvas.width = 1; + canvas.height = ih; + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + var data = ctx.getImageData(0, 0, 1, ih).data; + // search image edge pixel position in case it is squashed vertically. + var sy = 0; + var ey = ih; + var py = ih; + while (py > sy) { + var alpha = data[(py - 1) * 4 + 3]; + if (alpha === 0) { + ey = py; + } else { + sy = py; + } + py = (ey + sy) >> 1; + } + var ratio = py / ih; + return ratio === 0 ? 1 : ratio; + }, + callback: function(d) { + return d; + }, + extend: function() { + var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false; + if (target.constructor === Boolean) { + deep = target; + target = arguments[1] || {}; + } + if (al === 1) { + target = this; + a = 0; + } + var prop; + for (; a < al; a++) + if ((prop = arguments[a]) !== null) + for (var i in prop) { + if (target === prop[i]) + continue; + if (deep && typeof prop[i] === 'object' && target[i]) + methods.extend(target[i], prop[i]); + else if (prop[i] !== undefined) + target[i] = prop[i]; + } + return target; + } + }, + defaults = { + width: 300, + height: 0, + crop: false, + quality: 80, + rotate: 0, + 'callback': methods.callback + }; + function Plugin(file, options) { + this.file = file; + // EXTEND + this.options = methods.extend({}, defaults, options); + this._defaults = defaults; + this._name = pluginName; + this.init(); + } + Plugin.prototype = { + init: function() { + //this.options.init(this); + var $this = this; + var file = this.file; + + var reader = new plus.io.FileReader(); + reader.onloadend = function(e) { + + var dataURL = e.target.result; + var byteString = atob(dataURL.split(',')[1]); + var binary = new BinaryFile(byteString, 0, byteString.length); + var exif = EXIF.readFromBinaryFile(binary); + + var img = new Image(); + img.onload = function(e) { + + var orientation = exif['Orientation'] || 1; + orientation = methods.rotate(orientation, $this.options.rotate); + + // CW or CCW ? replace width and height + var size = (orientation >= 5 && orientation <= 8) + ? methods.newsize(img.height, img.width, $this.options.width, $this.options.height, $this.options.crop) + : methods.newsize(img.width, img.height, $this.options.width, $this.options.height, $this.options.crop); + + var iw = img.width, ih = img.height; + var width = size.width, height = size.height; + + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + ctx.save(); + methods.transformCoordinate(canvas, width, height, orientation); + + // over image size + if (methods.detectSubsampling(img)) { + iw /= 2; + ih /= 2; + } + var d = 1024; // size of tiling canvas + var tmpCanvas = document.createElement('canvas'); + tmpCanvas.width = tmpCanvas.height = d; + var tmpCtx = tmpCanvas.getContext('2d'); + var vertSquashRatio = methods.detectVerticalSquash(img, iw, ih); + var sy = 0; + while (sy < ih) { + var sh = sy + d > ih ? ih - sy : d; + var sx = 0; + while (sx < iw) { + var sw = sx + d > iw ? iw - sx : d; + tmpCtx.clearRect(0, 0, d, d); + tmpCtx.drawImage(img, -sx, -sy); + var dx = Math.floor(sx * width / iw); + var dw = Math.ceil(sw * width / iw); + var dy = Math.floor(sy * height / ih / vertSquashRatio); + var dh = Math.ceil(sh * height / ih / vertSquashRatio); + ctx.drawImage(tmpCanvas, 0, 0, sw, sh, dx, dy, dw, dh); + sx += d; + } + sy += d; + } + ctx.restore(); + tmpCanvas = tmpCtx = null; + + // if rotated width and height data replacing issue + var newcanvas = document.createElement('canvas'); + newcanvas.width = size.cropped === 'h' ? height : width; + newcanvas.height = size.cropped === 'w' ? width : height; + var x = size.cropped === 'h' ? (height - width) * .5 : 0; + var y = size.cropped === 'w' ? (width - height) * .5 : 0; + newctx = newcanvas.getContext('2d'); + newctx.drawImage(canvas, x, y, width, height); + +// console.log(file, file.type); + if (file.type === "image/png") { + var data = newcanvas.toDataURL(file.type); + } else { + var data = newcanvas.toDataURL("image/jpeg", ($this.options.quality * .01)); + } + + // CALLBACK + $this.options.callback(data, newcanvas.width, newcanvas.height); + + // }); + }; + img.src = dataURL; + // ===================================================== + + }; + reader.readAsDataURL(file); + //reader.readAsBinaryString(file); + + } + }; + $[pluginName] = function(file, options) { +// console.log(file.size); + if (typeof file === 'string') + return methods[file](options); + else + new Plugin(file, options); + }; + +})(window); \ No newline at end of file diff --git a/static/app2/js/cash-out.js b/static/app2/js/cash-out.js new file mode 100755 index 0000000..19f6d76 --- /dev/null +++ b/static/app2/js/cash-out.js @@ -0,0 +1,110 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); + +mui.plusReady(function() { + //获取数值 + $('.bg').css("display", 'none') + var self = plus.webview.currentWebview() + var shopId = self.id; + var totlemoney = ""; + JZL.ajax(qlgUrl('app/users/getMoney'), { + type: 3 + }, function(data) { + if (1 == data.status) { + var data = data.data; + totlemoney = data.wangNum; + // $('.idc-total span').html('¥'+data.wangNum) + $('#money').val(totlemoney) + } else { + mui.alert(data.msg) + } + $('.btns').on('tap', '.sqtx', function() { + if ($('#money').val() > totlemoney) { + mui.alert("超过最大提现金额") + return; + } else if ('' == $('#money').val()) { + mui.alert("请输入提现金额") + return; + } else if (1 > $('#money').val()) { + mui.alert("提现金额不能小于1") + return; + } + $('.bg').css('display', 'block'); + $('.footer').hide(); + JZL.ajax(qlgUrl('app/shops/getBank'), { + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status) { + var data = data.data + $('#bankUserName').val(data.accountName) + // $('.bankname').prepend('<option value="' + data.bankName + '">' + data.bankName + '</option>') + $('.bankname').val(data.bankName) + $('#cardnum').val(data.bankNo) + $('#money').on('focus', function() { + $('.bg').css('display', 'none'); + $('.footer').show(); + }) + + } else { + mui.alert(data.msg) + } + }) + }) + $('.bg').on('tap', '.qrtx', function() { + // mui.prompt("请输入操作密码:") + mui.prompt('请输入操作密码', '', '全亮共商城', ['取消', '忘记密码', '确定'], function(e) { + //console.log(e); + if (2 == e.index) { + var payPwd = e.value; + if ('' == payPwd) { + mui.alert('密码不能为空') + return; + } + var money = $('#money').val(); + JZL.ajax(qlgUrl('app/shops/withdrawal'), { + payPwd: payPwd, + money: money, + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status) { + mui.toast(data.msg) + mui.back() + } else { + mui.alert(data.msg) + } + }) + } else if (1 == e.index) { + JZL.openWindow('setting_fogetPwd.html', 'setting_fogetPwd.html') + } + + }, 'div') + document.querySelector('.mui-popup-input input').type = 'password' + + // var mark=mui.prompt("请输入操作密码:") + // //console.log(document.querySelector('.mui-popup-input input').value) + // if(null!=mark){ + // var payPwd =document.getElementById('mark') + // //console.log(payPwd); + // } + }) + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.bg').css('display', 'none'); + $('.footer').show(); + }) + }) + + $('.btns').on('tap', '.ckmx', function() { + JZL.openWindow("vouchers.html", "vouchers.html", { + data_href: "wang", + isExpected: 1 + }) + }) +}) diff --git a/static/app2/js/choiceness.js b/static/app2/js/choiceness.js new file mode 100755 index 0000000..89744db --- /dev/null +++ b/static/app2/js/choiceness.js @@ -0,0 +1,316 @@ +$('.mui-slider-indicator').html('') + +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + count += 1; + ////console.log(count) + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + + // //console.log(order_class) + mui.ajax(qlgUrl('addon/hyhchosen-Hyhchosen-getChosen'), { + + data: { + page: count, + goodsSize: 3, + pagesize: 10 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + data = data.data; + if (data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + + '</p><p class="time">' + this.newTime + + '</p><div class="btn_gz">+ 关注</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + + html += '<div data-goodsId="' + this.goodsId + '" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + $('.con').append(html); + } else { + mui.alert(data.msg) + ////console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + function openAds(item) { + if (item.attr('data-adURL') == '' || item.attr('data-targetType') == 0) { + return; + } + var adURL = item.attr('data-adURL'); + var targetType = ''; + var data_set = {}; + if (item.attr('data-targetType') == 1) { + //商品 + targetType = 'details.html'; + data_set = { + data_id: adURL + } + } else if (item.attr('data-targetType') == 2) { + //商家 + targetType = 'storeout.html'; + + if (adURL == 1) { + // targetType='self_shop.html'; + } + data_set = { + shopId: adURL + } + } else if (item.attr('data-targetType') == 3) { + //活动 + targetType = adURL + '.html'; + } + mui.openWindow({ + url: targetType, + id: targetType + adURL, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: data_set, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + var data = ''; + mui.ajax(qlgUrl('addon/hyhchosen-Hyhchosen-getChosen'), { + data: { + pagesize: 10, + goodsSize: 3, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + + data = data.data; + + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + + '</p><p class="time">' + this.newTime + + '</p><div class="btn_gz">+ 关注</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<div data-goodsId="' + this.goodsId + '" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + $('.con').html(html) + if (data.chosenAdsList.length != 0) { + var html1 = '<div class="mui-slider-group mui-slider-loop"><div data-adId="' + data.chosenAdsList[data.chosenAdsList + .length - 1].adId + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + + hyhImgUrl(data.chosenAdsList[data.chosenAdsList.length - 1].adFile) + '"></a></div>'; + var html2 = '<div class="mui-slider-indicator">'; + $.each(data.chosenAdsList, function() { + html1 += '<div data-adId="' + this.adId + '"data-adURL="' + this.adURL + '"data-targetType="' + this.targetType + + '" class="mui-slider-item "><a href="#"><img src="' + hyhImgUrl(this.adFile) + '"></a></div>' + html2 += '<div class="mui-indicator"></div>' + }) + html2 += '</div>' + html1 += '<div data-adId="' + data.chosenAdsList[0].adId + '"data-adURL="' + data.chosenAdsList[0].adURL + + '"data-targetType="' + data.chosenAdsList[0].targetType + + '" class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="' + hyhImgUrl(data.chosenAdsList[ + 0].adFile) + '"></a></div></div>' + html1 += html2; + $('#slider').html(html1); + + mui("#slider").slider({ + interval: 5000 + }); + document.getElementsByClassName('mui-indicator')[0].className += ' mui-active'; + } + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + mui('.con').on('tap', '.storename', function() { + var shopId = $(this).parent().attr('data-shopId'); + var url = 'storeout.html'; + if (shopId == 1) { + // url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.bc_img', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.btn_gz', function() { + var shopId = $(this).parent().attr('data-shopId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/add'), { + + data: { + id: shopId, + type: 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + that.html('已关注'); + that.addClass('btn_gz1').removeClass('btn_gz'); + } else { + mui.alert(data.msg) ////console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + //轮播图跳转 + $('#slider').on('tap', '.mui-slider-item', function() { + openAds($(this)); + }) + +}) diff --git a/static/app2/js/classify.js b/static/app2/js/classify.js new file mode 100755 index 0000000..4541354 --- /dev/null +++ b/static/app2/js/classify.js @@ -0,0 +1,129 @@ +function classInfo(parentId) { + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: parentId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html1 = ''; + data = data.data; + $.each(data, function() { + + html1 += '<div class="r_block clearfix" data-catId="' + this.catId + '"><div class="rb_title">' + this.catName + '</div></div>'; + + }); + $('.con_right .mui-scroll').html(html1); + + $('.r_block').each(function() { + var parentId2 = $(this).attr('data-catId'); + var that = $(this); + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: parentId2 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + data = data.data; + var html2 = ''; + $.each(data, function() { + html2 += '<div class="rb_block" data-catId="' + this.catId + '"><img src="' + hyhImgUrl(this.catImg) + '" /><p>' + this.catName + '</p></div>'; + }); + + that.append(html2); + $(this).addClass('on').siblings().removeClass('on'); + $('.rb_block img').height($('.rb_block img').width()) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  +} +mui.plusReady(function() { + + $('.con_left').on('tap', '.left_row', function() { + var classify = $(this).attr('data-catId'); + $(this).addClass('on').siblings().removeClass('on'); + $('.rb_block img').height($('.rb_block img').width()) + classInfo(classify) + }) + + mui.ajax(hyhUrl('app/goodscats/getGoodsCat'), {  + data: { + parentId: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + data = data.data; + $.each(data, function() { + html += '<div class="left_row" data-catId="' + this.catId + '">' + this.catName + '</div>' + + }); + $('.con_left .mui-scroll').html(html); + document.getElementsByClassName('left_row')[0].className += ' on'; + var parentId1 = document.getElementsByClassName('left_row')[0].attributes["data-catId"].nodeValue; + classInfo(parentId1) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.con_right .mui-scroll').on('tap', '.rb_block', function() { + var catId = $(this).attr('data-catId'); + mui.openWindow({ + url: 'goodsList.html', + id: 'goodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_catId: catId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/collect.js b/static/app2/js/collect.js new file mode 100755 index 0000000..ca204e1 --- /dev/null +++ b/static/app2/js/collect.js @@ -0,0 +1,77 @@ +jumpPage(); + +function jumpPage() { + //跳转页面 +// localStorage.setItem('order_class', data_href); + var bSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var subpages = ['collect_commodity.html', 'collect_store.html']; + var subpage_style = { + top: bSize, + bottom: '0px', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if(targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if(mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + if(targetTab == 'collect_commodity.html') { + document.getElementsByClassName('p1')[1].classList.remove('on') + this.classList.add('on'); + } + if(targetTab == 'collect_store.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + this.classList.add('on'); + } + }); + + //首次启动切滑效果 + mui.plusReady(function() { + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + + for(var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if(i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + var data_href = self.data_href; + if(data_href == 'collect_store.html') { + var defaultTab = document.getElementsByClassName("p1")[1]; + //模拟首页点击 + mui.trigger(defaultTab, 'tap'); + } + + }); + +} \ No newline at end of file diff --git a/static/app2/js/collect_commodity.js b/static/app2/js/collect_commodity.js new file mode 100755 index 0000000..b59d16d --- /dev/null +++ b/static/app2/js/collect_commodity.js @@ -0,0 +1,129 @@ +mui.plusReady(function() { + var page = 1; + var isjiazai = 1; + + function getData(page, pagesize) { + var setdata = { + page: page, + pagesize: pagesize + } + if(isjiazai == 0) { + return; + } + isjiazai = 0; + mui.ajax(hyhUrl('app/favorites/listGoodsQuery'), {  + + data: setdata, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="row shadown_wai clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="row_r" data-favoriteId="'+ this.favoriteId +'" data-goodsId="' + this.goodsId + '"><p class="sctitle">' + this.goodsName + '</p><div class="cost">¥' + this.shopPrice + '</div><button class="qxsc">取消收藏</button></div></div>' + }); + if(page == "1") { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } + getData(page, 10); + //下拉加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, 10) + } + + } + }) + //商品页调转 + mui(".con").on('tap', '.sctitle', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = $(this).parent().attr('data-goodsId'); + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //取消关注 + $('.con').on('tap', '.qxsc', function() { + var favoriteId = $(this).parent().attr('data-favoriteId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/cancel'), {  + + data: { + id: favoriteId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + location.reload(); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }) +}) \ No newline at end of file diff --git a/static/app2/js/collect_store.js b/static/app2/js/collect_store.js new file mode 100755 index 0000000..4922754 --- /dev/null +++ b/static/app2/js/collect_store.js @@ -0,0 +1,147 @@ +mui.plusReady(function() { + var page = 1; + var isjiazai = 1; + + function getData(page, pagesize) { + var setdata = { + page: page, + pagesize: pagesize + } + if(isjiazai == 0) { + return; + } + isjiazai = 0; + mui.ajax(hyhUrl('app/favorites/listShopQuery'), { + + data: setdata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="row shadown_wai"><div class="row_title"><img class="img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="s_t" data-shopId="' + this.shopId + '">' + this.shopName + '</p><button class="qxsc" data-favoriteId="' + this.favoriteId + '">取消收藏</button></div></div></div>'; + }); + if(page == "1") { + $('.con').html(html); + } else { + $('.con').append(html); + } + + isjiazai = 1; + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + getData(page, 10); + + //下拉加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getData(page, 10) + } + + } + }) + //店铺跳转 + mui(".con").on('tap', '.s_t', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + var shopId = this.attributes["data-shopId"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + var url = 'storeout.html'; + if(shopId==1){ + url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //取消关注 + $('.con').on('tap', '.qxsc', function() { + var favoriteId = $(this).attr('data-favoriteId'); + var that = $(this); + mui.ajax(hyhUrl('app/Favorites/cancel'), { + + data: { + id: favoriteId, + type : 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + mui.alert(data.msg); + location.reload(); + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + // mui('.con').on('tap', '.img_btn', function() { + // + // if($(this).attr('src') == '../img/sanjiaoshang.png') { + // $(this).parent().siblings('.row_con').css('display', 'none'); + // $(this).attr('src', '../img/sanjiaoxia.png') + // } else { + // $(this).parent().siblings('.row_con').css('display', 'block'); + // $(this).attr('src', '../img/sanjiaoshang.png') + // } + // + // }) + +}) \ No newline at end of file diff --git a/static/app2/js/commercial.js b/static/app2/js/commercial.js new file mode 100755 index 0000000..5c8b811 --- /dev/null +++ b/static/app2/js/commercial.js @@ -0,0 +1,222 @@ +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + //console.log(self); + + + var id = self.ssid ? self.ssid : ''; + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 3 + }, function(data) { + //console.log(data); + if (1 == data.status & undefined != data.data) { + var data = data.data; + + if (0 == data.status || 2 == data.status) { + if (id == '') { + id = data.id + } + getShopList(data.shopId); + + $('#confirm').attr('src', hyhImgUrl(data.confirmImg)) + $('#confirmImg').val(data.confirmImg) + + var imgs = data.shopImg + imgs = Array.from(imgs.split(',')) + //console.log(imgs); + var html = ""; + var html1 = ''; + mui.each(imgs, function(index, element) { + //console.log(index, element); + html += '<div class="galleryImg photo" data-id="' + index + + '" ><div class="delete" data-id="' + index + '"><img src="../img/close.png" alt=""></div><img src="' + + hyhImgUrl(element) + '" class="ossfile" data-src="' + element + '" data-id="' + index + '" id="galleryImg[' + + index + + ']" alt=""><input type="hidden" name="gallery[]" value="' + element + + '" class="gallery" id="gallery[' + index + ']"><span class=""></span></div>'; + }) + // $(".batchImg").html(html); + + // var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + var maxNum = imgs.length; + + + // if (num == maxNum) { + // maxNum++; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html); + // } + + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 116 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + + } else if (1 == data.status) { + //tiaozhuandao shangdu yemian + } + } else { + getShopList(); + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 116 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + } + }) + + + // 上传图片 + $('.photos_con').on('tap', '.confirm', function() { + UP.init("confirmImg", "test", "confirm") + openCamera() + }) + // 获取店铺信息 + + function getShopList(defaultShopId) { + + JZL.ajax(qlgUrl('app/shops/userShopList'), { + shopType: 1 + }, function(data) { + //console.log(data); + if (1 == data.status) { + var html = ""; + html = `<option value ="">选择店铺</option>`; + if (undefined == typeof defaultShop) { + + mui.each(data.data, function() { + // //console.log(index, element); + html += `<option value =${this.shopId}>${this.shopName}</option>`; + }) + } else { + mui.each(data.data, function() { + if (this.shopId == defaultShopId) { + selected = 'selected'; + } else { + selected = ''; + } + html += `<option value =${this.shopId} ${selected}>${this.shopName}</option>`; + }) + + } + $("#shopId").html(html) + } else { + mui.alert(data.msg) + } + // }) + }) + } + + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + + that.html(html); + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + //删除照片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + // //console.log(this); + var that = $(this) + //var idx = that.parent().attr('data-id'); + //var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; + } + }) + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 116 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + var click = 0; + $('.down').on('tap', '.btn', function() { + + if (click == 1) { + return; + } + click = 1 + var imgs = ''; + var data = $('input[name="gallery[]"]'); + //console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + }) + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + $('#shopImg').val(imgs); + if ('' == $('#shopId option:selected').val()) { + mui.alert('请选择要升级的店铺名称') + return; + } + + if ('' == $('#confirmImg').val()) { + mui.alert('请上传确认书照片') + return; + } + if ('' == $('#shopImg').val()) { + mui.alert('请上传店铺照片') + return; + } + + + var params = JZL.getParams(".inp"); + params.applyLevel = 3; + if ("" != id) { + params.id = id; + + } + JZL.ajax(qlgUrl('app/shops/userUpdate'), params, function(data) { + // //console.log(data); + if (1 == data.status) { + mui.back() + } else { + mui.alert(data.msg) + } + }) + }) +}) diff --git a/static/app2/js/common.js b/static/app2/js/common.js new file mode 100755 index 0000000..0e7050b --- /dev/null +++ b/static/app2/js/common.js @@ -0,0 +1,479 @@ +var is_online = 1; +var is_app = 1; +var imgUrl = 'http://img.zgqlg.com.cn/'; +var webUrl = 'http://t.ect99.com/'; +var webUrl1 = 'http://t.ect99.com/'; +var cssUrl = localStorage.getItem("cssUrl"); +var jsUrl = localStorage.getItem("jsUrl"); +var version = localStorage.getItem("version"); +if (0 == is_online) { + webUrl = 'http://192.168.1.111/'; +} + +function qlgUrl(url) { + return webUrl + url; +} + +function hyhUrl(url) { + return webUrl + url; +} + +function llUrl(url) { + return webUrl + url; +} + +function hgUrl(url) { + return webUrl + url; +} + +function kxUrl(url) { + return webUrl + url; +} + +function hyhImgUrl(url) { + return imgUrl + url; +} + +function ectUrl(url) { + return webUrl + url; +} + +function ectImgUrl(url) { + return imgUrl + url; +} + +function cssUrl(url) { + return '../css/' + url; +} + +function formatDate(date) { + var d = new Date(date), + + month = '' + (d.getMonth() + 1), + day = '' + d.getDate(), + year = d.getFullYear(), + hour = d.getHours(), + minute =d.getMinutes(), + second = d.getSeconds(); + console.log(hour ); + if (month.length < 2) month = '0' + month; + if (day.length < 2) day = '0' + day; + if (hour< 10) hour = '0' + hour; + if (minute< 10) minute = '0' + minute; + if (second < 10) second = '0' + second; + // return [year, month, day].join('-')+" "+[hour,minute,second].join(':'); + return year+"年"+month +"月"+day+"日"; +} + +function backTop() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 0); +} +function bMapTransQQMap(lng, lat) { + var x_pi = 3.14159265358979324 * 3000.0 / 180.0; + var x = lng - 0.0065; + var y = lat - 0.006; + var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); + var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); + var lngs = z * Math.cos(theta); + var lats = z * Math.sin(theta); + + return { + lng: lngs, + lat: lats + } +} +function toJson(str, notLimit) { + var json = {}; + if (str) { + try { + if (typeof(str) == "object") { + json = str; + } else { + json = eval("(" + str + ")"); + } + if(json.status && (json.status == '-555' || json.status == '-666')){ + //topingzheng + var type = 0; + if(json.status == '-666') type = 1; + JZL.openWindow("paymentVoucher.html",json.data.shopId,{'type':type}); + } + if (!notLimit) { + if (json.status && json.status == '-999') { + //console.log(str.msg) + inLogin(); + + } + } + } catch (e) { + mui.alert("系统发生错误:" + e.getMessage); + json = {}; + } + return json; + } else { + return; + } +} +var JZL = JZL || {}; +JZL.js_init = function(cdn) { + var typeName = 'script'; + var type = 'text/javascript'; + var element, i = 0, + file, parent = document.body; + + for (i; i < cdn.length; i++) { + file = cdn[i]; + element = document.createElement(typeName); + element.type = type; + element.src = file; + parent.appendChild(element); + //free file's value + file = null; + } + /* + * Cleanup at end of function, which isn't necessary unless lots of memory is being + * used up. + * No point nulling a Number, however. In some ECMAScript implementations + * (ActionScript 3), this throws a warning. + */ + //empty array + cdn.splice(0, cdn.length); + //clear variable values + element = null; + parent = null; + cdn = null; +} +JZL.css_init = function(cdn) { + var typeName = 'style'; + var type = 'text/css'; + var rel = 'stylesheet'; + var element, i = 0, + file, head, parent = document.head || document.getElementsByTagName('head')[0]; + for (i; i < cdn.length; i++) { + file = cdn[i]; + element = document.createElement('link'); + element.rel = rel; + element.type = type; + element.href = file; + parent.appendChild(element); + //free file's value + file = null; + } + cdn.splice(0, cdn.length); + element = null; + parent = null; + cdn = null; +} +JZL.getToken = function() { + return localStorage.getItem('token'); +} +JZL.getCssUrl = function(cssName) { + return cssUrl + cssName + '?ver=' + version +} +JZL.getJsUrl = function(jsName) { + return jsUrl + jsName + '?ver=' + version +} +JZL.openWindow = function(openUrl, openId, extras, targetUrl) { + if (1 == is_app) { + if (typeof(extras) == "undefined") extras = {}; + mui.openWindow({ + url: openUrl, + id: openId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: extras, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } else { + location.href = targetUrl; + } + +} + +JZL.closeWindow = function(closeId) { + if (1 == is_app) { + plus.webview.getWebviewById(closeId).close(); + } +} + +JZL.ajax = function(url, data, fnDeal, sendType, sendToken) { + if (typeof(sendType) == "undefined") sendType = 'POST'; + if (typeof(sendToken) == "undefined") sendToken = 1; + if (1 == sendToken) + headers = { + "HYH-Token": JZL.getToken() + }; + else + headers = {}; + // //console.log(JSON.stringify(headers)) + if (1 == is_app) { + + mui.ajax(url, { + headers: headers, + data: data, + dataType: 'json', //服务器返回json格式数据 + type: sendType, //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(result) { //服务器返回响应,根据响应结果,分析是否登录成功; + + if (typeof(fnDeal) != "undefined") { + fnDeal(result); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(xhr+type+errorThrown); + console.log(JSON.stringify(data)); + console.log(url); + //mui.alert(xhr); + } + }); + } else { + + $.ajax(url, { + headers: headers, + data: data, + dataType: 'jsonp', //服务器返回json格式数据 + type: sendType, //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(result) { //服务器返回响应,根据响应结果,分析是否登录成功; + if (typeof(fnDeal) != "undefined") { + fnDeal(result); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(xhr+type+errorThrown); + alert(type); + } + }); + } + +} + +function inLogin() { + JZL.openWindow('login.html', 'login.html'); +} + +var scroll = mui('.mui-scroll-wrapper').scroll(); + +var ua = navigator.userAgent.toLowerCase(); +if (/iphone|ipad|ipod/.test(ua)) { //苹果手机 + if (document.getElementsByClassName('zhe')[0]) { + document.getElementsByClassName('zhe')[0].style.display = 'none'; + } + // document.getElementsByClassName('zhe')[0].style.display='none'; +} else if (/android/.test(ua)) { + // document.getElementsByClassName('zhe')[0].style.display='block'; + if (document.getElementsByClassName('zhe')[0]) { + document.getElementsByClassName('zhe')[0].style.display = 'none'; + } +} + +var hSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; +var hPadding = 22 + (+localStorage.getItem('ipxSizeTop')) + 'px'; +$('.header').css('height', hSize); +$('.header').css('padding-top', hPadding); +$('.scroll_out_tb').css('top', hSize); +$('.scroll_out_t').css('top', hSize); +mui.plusReady(function() { + plus.navigator.setStatusBarStyle('dark'); +}) + +mui('.nav').on('tap', '.nav_block', function() { + $(this).addClass('on').siblings().removeClass('on'); +}) + +//打开广告 +function openAds(item) { + if (item.attr('data-adURL') == '' || item.attr('data-targetType') == 0) { + return; + } + var adURL = item.attr('data-adURL'); + var targetType = ''; + var data_set = {}; + if (item.attr('data-targetType') == 1) { + //商品 + targetType = 'details.html'; + data_set = { + data_id: adURL + } + } else if (item.attr('data-targetType') == 2) { + //商家 + targetType = 'storeout.html'; + if (adURL == 1) { + // targetType = 'self_shop.html' + } + data_set = { + shopId: adURL + } + } else if (item.attr('data-targetType') == 3) { + //活动 + targetType = adURL; + data_set = { + adURLId: adURL.split('?')[1] + } + } + ////console.log(item.attr('data-adURL')); + JZL.openWindow(targetType, targetType + adURL, data_set); +} + +//返回顶部 +//var scrollToTopBox = document.getElementById('scrollToTop'); //返回按钮tap +//scrollToTopBox.addEventListener('tap', function(e) { +// e.stopPropagation(); +// mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); //滚动到顶部 +//}); +// Android上监听原生滚动,iOS上监听div滚动,上拉超过一屏后显示按钮,否则隐藏,可自行在条件判断中修改 +//if(mui.os.android) { +// window.addEventListener('scroll', function(e) { +// if(window.pageYOffset >= window.innerHeight && scrollToTopBox.classList.contains('hide')) { +// scrollToTopBox.classList.remove('hide'); +// } else if(window.pageYOffset < window.innerHeight && !scrollToTopBox.classList.contains('hide')) { +// scrollToTopBox.classList.add('hide'); +// } +// }); +//} else { +// document.getElementsByClassName('mui-scroll-wrapper')[0].addEventListener('scroll', function() { +// if(mui('.mui-scroll-wrapper').scroll().y <= window.innerHeight * (-1) && scrollToTopBox.classList.contains('hide')) { +// scrollToTopBox.classList.remove('hide'); +// } else if(mui('.mui-scroll-wrapper').scroll().y > window.innerHeight * (-1) && !scrollToTopBox.classList.contains('hide')) { +// scrollToTopBox.classList.add('hide'); +// } +// }); +//} +JZL.saveItems = function(className, itemName) { + var params = JZL.getParams(className); + localStorage.setItem(itemName, JSON.stringify(params)); +} +JZL.getItems = function(itemName) { + var itemNames = localStorage.getItem(itemName); + //if(null != itemNames) + JZL.setValues(JSON.parse(itemNames)); + +} +JZL.getParams = function(obj) { + var params = {}; + var chk = {}; + var s; + $(obj).each(function() { + // //console.log($(this)[0]); + if ($(this)[0].type == 'hidden' || $(this)[0].type == 'number' || $(this)[0].type == 'tel' || $(this)[0].type == + 'password' || $(this)[0].type == 'select-one' || $(this)[0].type == 'textarea' || $(this)[0].type == 'text') { + params[$(this).attr('id')] = $.trim($(this).val()); + } else if ($(this).is('img')) { + // //console.log(1) + params[$(this).attr('id')] = $.trim($(this).attr('data-src')); + } else if ($(this)[0].type == 'radio') { + if ($(this).attr('name')) { + params[$(this).attr('name')] = $('input[name=' + $(this).attr('name') + ']:checked').val(); + } + } else if ($(this)[0].type == 'checkbox') { + if ($(this).attr('name') && !chk[$(this).attr('name')]) { + s = []; + chk[$(this).attr('name')] = 1; + $('input[name=' + $(this).attr('name') + ']:checked').each(function() { + s.push($(this).val()); + }); + params[$(this).attr('name')] = s.join(','); + } + } + }); + chk = null, s = null; + return params; +} +JZL.setValue = function(name, value) { + + var first = name.substr(0, 1), + input, i = 0, + val; + if ("#" === first || "." === first) { + input = $(name); + } else { + input = $("[name='" + name + "']"); + } + + if (input.eq(0).is(":radio")) { //单选按钮 + input.filter("[value='" + value + "']").each(function() { + this.checked = true + }); + } else if (input.eq(0).is(":checkbox")) { //复选框 + if (!$.isArray(value)) { + val = new Array(); + val[0] = value; + } else { + val = value; + } + for (i = 0, len = val.length; i < len; i++) { + input.filter("[value='" + val[i] + "']").each(function() { + this.checked = true + }); + } + } else if (input.is('img')) { //图片 + + if (''!= value) { + input.attr('src',hyhImgUrl(value)); + input.attr('data-src',value); + } + + } else { //其他表单选项直接设置值 + input.val(value); + } + +} +JZL.setValues = function(obj) { + var input, value, val; + for (var key in obj) { + if ($('#' + key)[0]) { + JZL.setValue('#' + key, obj[key]); + } else if ($("[name='" + key + "']")[0]) { + JZL.setValue(key, obj[key]); + } + } +} + + + + +/** + * 邮箱格式判断 + * @param str + */ +function checkEmail(str){ + var reg = /^[a-z0-9]([a-z0-9\\.]*[-_]{0,4}?[a-z0-9-_\\.]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+([\.][\w_-]+){1,5}$/i; + if(reg.test(str)){ + return true; + }else{ + return false; + } +} +/** + * 输入为空检查 + * @param name '#id' '.id' (name模式直接写名称) + * @param type 类型 0 默认是id或者class方式 1 name='X'模式 + */ +function is_empty(name,type){ + if(type == 1){ + if($('input[name="'+name+'"]').val() == ''){ + return true; + } + }else{ + if($(name).val() == ''){ + return true; + } + } + return false; +} + + diff --git a/static/app2/js/common_home.js b/static/app2/js/common_home.js new file mode 100755 index 0000000..cf31a57 --- /dev/null +++ b/static/app2/js/common_home.js @@ -0,0 +1,70 @@ +function hyhUrl(url) { + return 'http://www.juzi199.com/' + url; +} +function hyhImgUrl(url) { + return 'http://img.juzi199.com/' + url; +} +function chengUrl(url) { + return 'http://www.juzi199.com/' + url; +} + +function toJson(str, notLimit) { + var json = {}; + if(str) { + try { + if(typeof(str) == "object") { + json = str; + } else { + json = eval("(" + str + ")"); + } + if(!notLimit) { + if(json.status && json.status == '-999') { + // console.log(str.msg) + inLogin(); + + } + } + } catch(e) { + alert("系统发生错误:" + e.getMessage); + json = {}; + } + return json; + } else { + return; + } +} + +function inLogin() { + mui.openWindow({ + url: 'login.html', + id: 'login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +} + diff --git a/static/app2/js/compare.js b/static/app2/js/compare.js new file mode 100755 index 0000000..7ba4287 --- /dev/null +++ b/static/app2/js/compare.js @@ -0,0 +1,96 @@ +//加载对比商品 +function loadCompare(isrefresh) { + $("#comparelist").load(HOMESITEURL + '/Compare/showcompare.html'); + return; + if (!$("#comparelist").html()) { + isrefresh = true; + } + if (isrefresh == true) { + $("#comparelist").load(HOMESITEURL + '/Compare/showcompare.html'); + } +} +//添加对比商品 +function addCompare(gid) { + gid = parseInt(gid); + if (gid > 0) { + $.ajax({ + type: "GET", + dataType: "json", + url: HOMESITEURL + '/Compare/addcompare.html?id=' + gid, + async: false, + success: function (data) { + if (data.done == true) { + $("[ds_type='compare_" + gid + "']").addClass('selected'); + loadCompare(true); + $(".top #content-compare").animate({right: '40px'}); + } else { + showDialog(data.msg); + } + } + }); + } else { + showDialog('参数错误'); + } + $("#lockcompare").val('unlock');//解除加入对比按钮的锁定 +} +//清空对比栏 +function delCompare(gid, type) { + $.ajax({ + type: "GET", + dataType: "json", + url: HOMESITEURL + '/Compare/delcompare?gid=' + gid + '&type=' + type, + async: false, + success: function (data) { + if (data.done == true) { + //将对比按钮置为未对比状态 + if (type == 'mini') { + if (gid == 'all') { + $("[ds_type^='compare_']").removeClass('selected'); + } else { + $("[ds_type='compare_" + gid + "']").removeClass('selected'); + } + } + //加载对比信息 + if (type == 'mini') { + //加载对比栏 + loadCompare(true); + $("#content-compare").animate({right: '40px'}); + } else { + go(HOMESITEURL + '/Compare/index/gids/' + data.gid_str); + } + } + $("#lockcompare").val('unlock');//解除加入对比按钮的锁定 + } + }); +} +//初始加入对比按钮 +function initCompare() { + //绑定对比按钮事件 + $("[ds_type^='compare_']").bind('click', function () { + if ($("#lockcompare").val() == 'unlock') { + $("#lockcompare").val('lock');//锁定加入对比按钮 + //处理参数 + var data_str = ''; + eval('data_str =' + $(this).attr('data-param')); + var gid = data_str.gid; + + if ($(this).hasClass('selected')) { + $(this).removeClass('selected'); + //删除该对比商品 + delCompare(gid, 'mini'); + } else { + //新增该对比商品 + addCompare(gid); + } + } + }); + + //根据是否已加入对比,显示不同样式 + $.getJSON(HOMESITEURL + '/Compare/checkcompare', function (data) { + if (data) { + $.each(data, function (i, val) { + $("[ds_type='compare_" + val + "']").addClass('selected'); + }); + } + }); +} \ No newline at end of file diff --git a/static/app2/js/complain.js b/static/app2/js/complain.js new file mode 100755 index 0000000..c9d526d --- /dev/null +++ b/static/app2/js/complain.js @@ -0,0 +1,156 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + + mui.ajax(hyhUrl('app/Ordercomplains/getComplainCause'), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + data = data.data; + var html = '<option value="0">选择投诉类型</option>'; + $.each(data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>'; + }) + $('select').html(html); + + } else { + mui.alert(data.msg) + // //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'selectfiles', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('ossfile').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false, 'complains'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('ossfile').innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if (info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name)) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if (err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if (err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if (err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); + + $('button').on('tap', function() { + var complainType = $('select').val(); + var complainContent = $('textarea').val(); + var imagesArr = []; + $('#ossfile').children('.files_out').children('b').children('img').each(function() { + imagesArr.push($(this).attr('data-src')) + }) + var images = imagesArr.join(','); + if (complainType == 0) { + mui.alert('请选择投诉原因!'); + return; + } + if (complainContent.length < 5) { + mui.alert('投诉内容不小于5个字!'); + return; + } + var that = $(this); + mui.ajax(hyhUrl('app/Ordercomplains/saveComplain'), { + data: { + orderId: data_order_id, + complainType: complainType, + complainContent: complainContent, + complainAnnex: images + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + mui.alert('提交成功!'); + var targetTab = plus.webview.getWebviewById('complain.html'); + mui.fire(targetTab, 'refresh'); + mui.back(); + } else { + mui.alert(data.msg) + // //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + }) + +}) diff --git a/static/app2/js/confirmOrder.js b/static/app2/js/confirmOrder.js new file mode 100755 index 0000000..cfe4838 --- /dev/null +++ b/static/app2/js/confirmOrder.js @@ -0,0 +1,717 @@ +//$('.pay_info .row_left').eq(0).html('桔子链账号'); +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init(); +mui.plusReady(function() { + window.addEventListener('setAddress', function(e) { + var addressId = localStorage.getItem('addressId') ? localStorage.getItem('addressId') : 0; + if (addressId == 0) { + return; + } + mui.ajax(hyhUrl('app/useraddress/getById'), { + data: { + addressId: addressId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + // for(i in data.data){ + // //console.log(i) + // //console.log(data.data[i]) + // } + var html = + '<div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + + data.userName + '</div><div class="add_r_t_r">' + data.userPhone + + '</div></div><div class="add_r_b">收货地址:' + data.areaName + ' ' + data.userAddress + '</div></div>'; + $('.address').html(html); + $('.address').attr('data-addressId', data.addressId); + $('.address').attr('data-areaId', data.areaId2); + + } else { + mui.alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }); + + $('.con').on('tap', '.address', function() { + var addressId = $(this).attr('data-addressId'); + localStorage.setItem('addressId', addressId); + var isOrder = true; + mui.openWindow({ + url: 'setting_address.html', + id: 'setting_address.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_addressId: addressId, + data_isOrder: isOrder + + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + //支付插件 + plus.payment.getChannels(function(channels) { + for (var i in channels) { + if (channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + mui.alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=1&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if (id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if (id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch (xhr.readyState) { + case 4: + if (xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + plus.webview.getWebviewById('confirmOrder.html').close(); + }); + } else { + mui.alert("获取订单信息失败!"); + ////console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + var self = plus.webview.currentWebview(); + var type = self.type; + var data_1 = {}; + var isUseScore = 0; + var orderNo; + var priceT = 0; + var payCode = ''; + var userCoupon = ''; + var couponIds = []; + var areaId2 = ''; + // //console.log(type) + + mui.ajax(qlgUrl('app/carts/settlement'), { + data: { + type: type + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data) + var data = toJson(data); + // //console.log(JSON.stringify(data)); + if (data.status == 1) { + var allallnum = 0; + data = data.data; + data_1 = data; + if (data.userAddress.addressId) { + var html = '<div class="address clearfix" data-addressId="' + data.userAddress.addressId + '" data-areaId2="' + + data.userAddress.areaId2 + + '"><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + + data.userAddress.userName + '</div><div class="add_r_t_r">' + data.userAddress.userPhone + + '</div></div><div class="add_r_b">收货地址:' + data.userAddress.areaName + ' ' + data.userAddress.userAddress + + '</div></div></div>'; + } else { + var html = + '<div class="address clearfix" ><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l" style="height:60px;line-height:60px;font-size:14.4px;color:black">请选择收货地址</div></div></div></div>'; + } + $.each(data.carts, function() { + var allNum = 0; + html += '<div class="shop_info"><div class="row_title"><div class="store_name">' + this.shopName + + '</div></div><div class="row_con clearfix">'; + $.each(this.list, function() { + allNum += this.cartNum; + var price = ''; + if (this.isWhsle == 1) { + price = this.whslePrice; + } else if (this.specPrice != 'null') { + price = this.shopPrice; + } else { + price = this.specPrice; + } + var specNames = ''; + for (var i in this.specNames[0]) { + if (i == "catName") { + specNames = this.specNames[0][i] + ':'; + } else if (i == "itemName") { + specNames += this.specNames[0][i] + } + } + + html += '<div class="row_block clearfix" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">'; + $.each(this.specNames, function() { + html += this.catName + ':' + this.itemName + ';'; + }); + + html += '</p></div><div class="rcrr"><p>¥' + price + '</p><del>¥' + this.marketPrice + '</del><span>x' + + this.cartNum + '</span></div></div></div>' + }); + allallnum += allNum; + html += + '<div class="cost"><div class="c2 clearfix"><div class="c1_l">买家留言:</div><div class="c1_r"><input class="remark" data-shopId="' + + this.shopId + '" type="text" name="" id="" value="" placeholder="选填:填写内容已和卖家协商确认" /></div></div></div>'; + // if (this.coupons != '') { + // couponName = '<option value="0">请选择优惠券</option>'; + // html += + // '<div class="cost"><div class="c2 clearfix"><div class="c1_l">选择优惠券:</div><div class="c1_r"><select name="" data-shopId="' + + // this.shopId + '" class="yhq yhq_">' + couponName; + // $.each(this.coupons, function() { + // html += '<option value="' + this.couponId + '">满' + this.useMoney + '元减' + this.couponValue + + // '元</option>'; + // }); + // html += '</select></div></div></div>'; + // } else { + html += '<div class="c1_r" style="display:none"><select name="" data-shopId="' + this.shopId + + '" class="yhq yhq_"><option value="0"></option></select></div>'; + //} + + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_r">共' + allNum + + '件商品 小计:<o class="on">¥' + this.goodsMoney + '</o> + 运费:<o class="on">¥' + this.shippingMoney + + '</o></div></div></div></div></div>'; + }); + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">发货方式:</div><div class="c1_r"><select name="" id="deliverType" class="yhq"><option value="0" selected>快递发货</option><option value="1" >门店自提【免运费】</option>'; + + //双11优惠券 + // html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">选择优惠券:</div><div class="c1_r"><select name="" id="userCoupon" class="yhq"><option value="0">不使用优惠券</option>'; + // $.each(data.userCoupon, function() { + // html += '<option value="' + this.recordId + '">满' + this.man + '元减' + this.price + '元</option>'; + // }); + // html += '</select></div></div></div>' + //木吉抵扣 + if (data.is_seckilling == 1 || data.promotion_goods == 1 || data.ect_pay == 1) { + // data.useOrderScore=0; + } else { + // html += '<div class="isHb clearfix"><div class="h_left">木吉抵用&nbsp;&nbsp;&nbsp;&nbsp;<o id="huibao">可抵用木吉:' + data.useOrderScore + '</o></div><div class="he_right"><div class="checkout"><div class="check_btn"></div></div></div></div>' + + } + // html+='<div class="num"><span>购买数量</span><div class="change_num"><span class="jian">-</span><input type="text" name="" id="" value="1" /><span class="jia">+</span></div></div>' + // html += '<div class="jf_info clearfix"><div class="jf_jf">木吉</div><div class="jf_p">成交后奖励成交价20%的木吉</div></div>'; + priceT = (Math.floor((+data.goodsTotalMoney - (+data.promotionMoney)) * 100)) / 100; + priceT = priceT >= 0 ? priceT : 0; + var html1 = '<span>共' + allallnum + '件商品 合计:<j>¥' + priceT + + '</j></span>&nbsp;&nbsp;<button class="btn_tj">提交订单</button>'; + // if(data.ect_pay == 1) { + // var htmlpay = '<div class="row clearfix select_payway" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.userECT + '</o></p></div>'; + // + // $('.pay_info .con_1').append(htmlpay); + // // $('.pay_info .con_1 .row').eq(0).attr('style','display: none;'); + // $('.pay_info .con_1 .row').eq(1).remove(); + // }; + $.each(data.payments, function(i, v) { + $.each(v, function() { + $('#pay_way,.pay_info .con_1').append('<div class="row clearfix select_payway" data-payCode="' + this.payCode + + '"><p class="row_left">付款方式</p><p class="row_right">' + this.payName + '</p></div>'); + }) + }) + $('.con').html(html); + $('.js_r').html(html1); + $('#loginName').html(data.loginName); + $('.userMoney').html(data.userMoney); + + $('#goodsTotalMoney').html(priceT); + } else { + mui.alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + //店铺优惠券 + $('.con').on('change', '.yhq_', function() { + userCoupon = $('#userCoupon').val(); + areaId2 = $('.address').attr('data-areaId2'); + couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + // var addressId = $('.address').attr('data-addressId') + var areaId2 = $('.address').attr('data-areaId2') + var couponIdsArr = couponIds.join(','); + mui.ajax(qlgUrl('app/carts/getMoney'), { + data: { + type: type, + areaId2: areaId2, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + couponIds: couponIdsArr, + recordId: userCoupon + + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + data = toJson(data); + // //console.log(data.msg) + if (data.status == 1) { + data_1.useOrderScore = data.data.maxScore; + $('#huibao').html('可抵用木吉:' + data_1.useOrderScore); + priceT = data.data.realTotalMoney; + $('.js_r span j').html('¥' + data.data.realTotalMoney) + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + }); + //订单优惠券 + $('body').on('change', '#userCoupon,#deliverType', function() { + userCoupon = $('#userCoupon').val(); + areaId2 = $('.address').attr('data-areaId2'); + couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + // var addressId = $('.address').attr('data-addressId') + var areaId2 = $('.address').attr('data-areaId2') + var couponIdsArr = couponIds.join(','); + mui.ajax(hyhUrl('app/carts/getMoney'), { + data: { + type: type, + deliverType:$('#deliverType').val(), + areaId2: areaId2, + //isUseScore: isUseScore, + useScore: data_1.useOrderScore, + //couponIds: couponIdsArr, + //recordId: userCoupon + + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(JSON.stringify( data)) + data = toJson(data); + // //console.log(data.msg) + if (data.status == 1) { + data_1.useOrderScore = data.data.maxScore; + $('#huibao').html('可抵用木吉:' + data_1.useOrderScore); + $('.js_r span j').html('¥' + data.data.realTotalMoney); + priceT = data.data.realTotalMoney; + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + }); + //是否使用木吉 +// $('.con').on('tap', '.checkout', function() { +// userCoupon = $('#userCoupon').val(); +// $(this).toggleClass('on'); +// if ($(this).hasClass('on')) { +// isUseScore = 1; +// } else { +// isUseScore = 0; +// } +// couponIds = []; +// $('select').each(function() { +// couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); +// }) +// couponIdsArr = couponIds.join(','); +// areaId2 = $('.address').attr('data-areaId2'); +// // //console.log(areaId2) +// // //console.log(couponIdsArr) +// // //console.log(data_1.userAddress.areaId2) +// // //console.log(data_1.userAddress) +// +// // //console.log( areaId2) +// // //console.log(isUseScore) +// // //console.log( data_1.useOrderScore) +// // //console.log(couponIdsArr) +// // //console.log(userCoupon); +// mui.ajax(hyhUrl('app/carts/getMoney'), { +// data: { +// type: type, +// areaId2: areaId2, +// isUseScore: isUseScore, +// useScore: data_1.useOrderScore, +// couponIds: couponIdsArr, +// recordId: userCoupon +// +// }, +// dataType: 'json', //服务器返回json格式数据 +// type: 'post', //HTTP请求类型 +// timeout: 10000, //超时时间设置为10秒; +// success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; +// +// data = toJson(data); +// +// if (data.status == 1) { +// data_1.useOrderScore = data.data.maxScore; +// $('#huibao').html('可抵用木吉:' + data_1.useOrderScore); +// // //console.log(data) +// // //console.log(data.data.shopFreight) +// // for(i in data.data){ +// // //console.log(i) +// // //console.log(data.data[i]) +// // } +// priceT = data.data.realTotalMoney; +// $('.js_r span j').html('¥' + data.data.realTotalMoney) +// $('#goodsTotalMoney').html(data.data.realTotalMoney); +// } else { +// mui.alert('发生错误请刷新后重试!'); +// // location.reload(); +// } +// }, +// error: function(xhr, type, errorThrown) { //异常处理; +// //alert(errorThrown); +// } +// }); +// }) + $('.footer').on('tap', '.btn_tj', function() { + payCode = $('.select_payway').attr('data-payCode'); + var that = $(this); + if (payCode == 'ect') { + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/ect/getToEctNum'), { + + data: { + total_money: priceT + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if (e.index == 1) { + that.removeAttr('disabled'); + return; + + } else { + var addressId = $('.address').attr('data-addressId'); + if (addressId) { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } else { + mui.alert('未设置收货地址!') + } + that.removeAttr('disabled'); + } + }) + } else { + mui.alert(data.msg); + return; + } + + } + }) + } else { + var addressId = $('.address').attr('data-addressId'); + if (addressId) { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } else { + mui.alert('未设置收货地址!') + } + } + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.select_payway .row_right o').html($(this).children('.row_left').html()); + $('.select_payway').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + + }) + $('.pay').on('tap', '.select_payway', function() { + if ($(this).attr('data-payCode') == 'ect') {} else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + } + + }) + var click = false; + $('.pay_btn').on('tap', function() { + + var addressId = $('.address').attr('data-addressId'); + var areaId = $('.address').attr('data-areaId'); + var that = $(this); + payCode = $('.select_payway').attr('data-payCode'); + var data_send = { + type: type, + s_addressId: addressId, + s_areaId: areaId, + payCode: payCode, + payType: 1, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + deliverType: $('#deliverType').val(), + isInvoice: 0, + invoiceId: 0, + invoiceClient: '', + recordId: userCoupon + } + $('.remark').each(function() { + data_send['remark_' + ($(this).attr('data-shopid'))] = $(this).val(); + }); + $('select').each(function() { + data_send['couponId_' + ($(this).attr('data-shopid'))] = $(this).val(); + }) + if (true == click) return; + click = true; + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/orders/submit'), { + data: data_send, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + ////console.log(JSON.stringify(data)) + data = toJson(data); + if (data.status == 1) { + orderNo = data.data; + if (payCode == 'qlgpay') { + JZL.ajax(hyhUrl('app/' + payCode + '/payment'), { + orderNo: orderNo, + isBatch: 1 + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(JSON.stringify(data)); + var data = toJson(data); + // //console.log(JSON.stringify(data)) + if (data.status == 1) { + $('.pay').css('display', 'none'); + $('#qlg_pay_pwd').css('display', 'block'); + if (data.data.payPwd == '0') { + mui.alert('还未设置支付密码请先设置操作密码!'); + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + //return; + } + $('#totalMoney').html('付款总额:¥<o>' + data.data.needPay + '</o>'); + $('#productNum').val(data.data.product.useProduct); + if (data.data.product.useProduct > 0) { + var html1 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.product.useProductOk + + '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.product.useProductTaxFee + + '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.product.useProductHandlingFee + + '</span></p>'; + $('.productInfo_').html(html1) + // $('#productInfo').html('产品券[抵扣额:'+data.data.product.useProductOk+',扣税:'+data.data.product.useProductTaxFee+',手续费:'+data.data.product.useProductHandlingFee+']'); + } + $('#couponsNum').val(data.data.coupons.useCoupons); + if (data.data.coupons.useCoupons > 0) { + var html2 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.coupons.useCouponsOk + + '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.coupons.useCouponsTaxFee + + '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.coupons.useCouponsHandlingFee + + '</span></p>'; + $('.couponsInfo_').html(html2) + // $('#coupousInfo').html('优惠券[抵扣额:' + data.data.coupons.useCouponsOk + ',扣税:' + data.data.coupons.useCouponsTaxFee + + // ',手续费:' + data.data.coupons.useCouponsHandlingFee + ']'); + } + $('#wangNum').val(data.data.wang.useWang); + $('#moneyNum').val(data.data.money.useMoney); + + } else { + mui.alert(data.msg) + } + }); + //显示支付页面 + } else if (payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + JZL.ajax(hyhUrl('app/' + payCode + '/payment'), { + orderNo: data.data, + isBatch: 1 + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if (data.data.payPwd == '0') { + mui.alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + } + } + }); + + } else if (payCode == 'alipays') { + pay('alipay', data.data); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + } else { + mui.alert(data.msg); //'发生错误请刷新后重试!'); + if (-2 == data.status) { + JZL.openWindow('indent.html', 'waitPay', { + data_href: 'waitPay' + }); + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + }, 500) + } else { + //location.reload(); + } + + //mui.back(); + + } + click = false; + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // //console.log(type) + // //console.log(errorThrown) + //mui.alert(errorThrown); + } + }) + }) + $('#pay_pwd,#qlg_pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + }) + $('#pay_pwd,#qlg_pay_pwd').on('tap', '.pay_btn_pwd', function() { + var payPwd = $('#payPwd').val(); + if (payPwd == '') { + mui.alert('支付密码不能为空!'); + return; + } + var that = $(this); + that.attr('disabled', 'disabled'); + var srcc = '' + if (payCode == 'qlgpay') { + srcc = 'payByQlg'; + } else if (payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + JZL.ajax(hyhUrl('app/' + payCode + '/' + srcc), { + orderNo: orderNo, + isBatch: 1, + payPwd: payPwd + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(JSON.stringify(data)); + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + JZL.openWindow('indent.html', 'waitDeliver', { + data_href: 'waitDeliver' + }); + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + }, 700) + + } else { + if (-1 == data.status) { + JZL.openWindow('indent.html', 'waitPay', { + data_href: 'waitPay' + }); + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + }, 700) + } else if (-2 == data.status) { + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + } else if (-3 == data.status) { + + } else if (-4 == data.status) { + JZL.openWindow('indent.html', 'waitDeliver', { + data_href: 'waitDeliver' + }); + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + }, 700) + } + + } + that.removeAttr('disabled'); + }); + }) +}) diff --git a/static/app2/js/cooperative.js b/static/app2/js/cooperative.js new file mode 100755 index 0000000..dfa3230 --- /dev/null +++ b/static/app2/js/cooperative.js @@ -0,0 +1,187 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + JZL.getItems('auth_company'); + var id = ''; + var count = 0; + $('.header_con_bc').on('tap', function() { + JZL.saveItems('.localinp', 'auth_company'); + mui.toast('保存成功'); + }) + + if ('' == $('#headImg').val()) { + $("#headImgTag").attr("src", "../img/touxiang.jpg") + + } + JZL.ajax(qlgUrl('app/auth/getAuthInfo'), { + isCompany: 1 + }, function(data) { + //console.log(data); + + if ('undefined' != typeof(data.data) && 1 == data.status) { //编辑 + count = 1; + $('.mobileCode').hide() + $('.userPhone').hide() + $('.payPwd').show() + id = data.data.id + + //赋值 + ////console.log(data); + mui.each(data.data, function(index, element) { + if ($('#' + index).attr("type") == "hidden") { + // var imgindex = index.substring(0, index.length - 3); + var imgindex = index + 'Tag' + var obj = '#' + imgindex + // //console.log('#' + imgindex + '') + if (imgindex != "") { + if ($(obj).is('img')) { + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index + '').val(element) + } + } + + } else { + $('#' + index).val(element) + } + + + }) + + } else { // 添加 + count = 0 + $('.userPhone').show() + $('.mobileCode').show() + $('.payPwd').hide() + JZL.getItems('auth_company'); + + } + + }) + mui('.mui-content').on('tap', '.yhk', function() { + JZL.openWindow('yhk.html', 'yhk.html'); + + }) + mui('.mui-content').on('tap', '.hhrrz', function() { + JZL.openWindow('hhrrz.html', 'hhrrz.html'); + + }) + + var wait = 120; + + function time() { + if (wait == 0) { + $('.HQYZM').removeAttr("disabled"); + $('.HQYZM').val("重新发送"); + wait = 120; + } else { + $('.HQYZM').attr("disabled", true); + $('.HQYZM').css("background", "#c0a0a0"); + $('.HQYZM').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + //获取验证码 + mui('.mui-table-view-cell').on('tap', '.HQYZM', function() { + var userPhone = $('.indiv-tel').val(); + // if (userPhone == '') { + // mui.alert('手机号不能为空!'); + // return; + // } + // 判断手机号码格式 + // if (!( + // /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + // .test(userPhone))) { + // mui.alert("手机号码有误,请重填!"); + // return; + // } + // $(".HQYZM").attr("disabled", true); + JZL.ajax(qlgUrl('app/auth/getPhoneCode'), { + userPhone: userPhone + }, function(data) { + //console.log(data); + if (1 == data.status) { + time(); + } + mui.toast(data.msg); + }) + + + }) + + // 上传头像 + $("#headerimg").on("tap", '#headImgTag', function() { + UP.init("headImg", "test", "headImgTag") + openCamera(); + }) + + $('.bc_btn').on('tap', function() { + + + var params = JZL.getParams(".inp"); + if ('' == params.trueName) { + mui.alert("请输入直营人姓名"); + return; + + } + if ('' == params.idCard) { + mui.alert("请输入身份证号"); + return; + + } + if ('' == params.companyName) { + mui.alert("请输入合作名称"); + return; + } + if ('' == params.companyAddress) { + mui.alert("请输入地址"); + return; + } + + + if ('' == params.companyName) { + mui.alert("请输入合作名称"); + return; + } + if (0 == count) { //添加 + if ('' == $('#mobileCode').val()) { + mui.alert("请输入验证码"); + return; + } + params.mobileCode = $('#mobileCode').val(); + + } else if (1 == count) { //编辑 + if ('' == $('#payPwd').val()) { + mui.alert("请输入操作密码"); + return; + } + params.authId = id; + params.payPwd = $('#payPwd').val(); + } + params.isCompany = 1 + JZL.ajax(qlgUrl('app/auth/setAuthInfo'), params, function(data) { + //console.log(data); + if (data.status == 1) { + JZL.saveItems('.localinp', 'auth_company'); + localStorage.setItem("authType","2") + mui.toast("提交成功 请等待审核") + // $(".mui-table-view").attr("readonly", "readonly") + $(".mobileCode").hide() + $('.userPhone').hide() + mui.back(); + } else { + mui.alert(data.msg); + } + + }) + }) +}) diff --git a/static/app2/js/details.js b/static/app2/js/details.js new file mode 100755 index 0000000..aac8373 --- /dev/null +++ b/static/app2/js/details.js @@ -0,0 +1,874 @@ +var data = ''; +var data_saleSpec = {} +var arry_str = ''; +var data_bak = {}; +var shopQQ = ''; +var shopTle = ''; +var shopName=''; +var isDefaultArr = []; +var token = localStorage.getItem('token'); +var isShowWhsle = 0; +var seckilling_end_time = '' +var shareImgThumbs = []; +var shares = null; +var img_data=''; +var Intent = null, + File = null, + Uri = null, + main = null; + +//点击遮罩关闭 +$('.cclass_con').before('<div class="mask" style="height:100%"></div>') +$('.header_con').append('<a class="icon-cart"><img style="width:1.7rem;" src="'+ectImgUrl('static/app2/img/icon_cart.png')+'"</a>'); +function getNextDate(dayStr) { + var dd = new Date(dayStr); + dd.setDate(dd.getDate() + 1); + var y = dd.getFullYear(); + var m = dd.getMonth() + 1; //获取当前月份的日期 + var d = dd.getDate(); + return y + "/" + m + "/" + d + " 00:00:00"; +}; +//倒计时 +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date(getNextDate(seckilling_end_time * 1000)); + var end = endDate.getTime(); + //时间差 + var leftTime = seckilling_end_time * 1000 - now; + //定义变量 d,h,m,s保存倒计时的时间 + var d, h, m, s; + if(leftTime >= 0) { + d = Math.floor(leftTime / 1000 / 60 / 60 / 24); + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(d < 10) { + d = "0" + d; + } + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + // $("#_d").html(d); + $("#_h").html(h); + $("#_m").html(m); + $("#_s").html(s); + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + + //秒杀限购四件 + var xg = ''; + $('.miaosha').append(xg); +//秒杀规格选择 +function miaoshaSaleSpec(specId, SaleSpec) { + for(i in SaleSpec) { + if(SaleSpec[i].id == specId) { + var data_sArry = i.split(':'); + var data_s = SaleSpec[i]; + arry_str = i; + isDefaultArr = i.split(':'); + $.each(data_sArry, function() { + var that = this; + $('.cclass1 .block').each(function() { + if($(this).attr('data-itemId') == that) { + $(this).addClass('on'); + $(this).parent().attr('data-class', that); + } + + }) + + }) + seckilling_end_time = data_s.seckilling_end_time; + html_miaosha = '<img src="../img/bg_miaosha.png"/><p class="miaosha1"><o>¥</o>' + data_s.specPrice + '</p><del class="miaosha2">¥' + data_s.marketPrice + '</del><div class="xiangou">限购四件</div><p class="miaosha3"><o id="_h">00</o>:<o id="_m">00</o>:<o id="_s">00</o></p><p class="miaosha4">桔子抢购</p><p class="miaosha5">距结束还剩</p>'; + $('.miaosha').html(html_miaosha); + $('.cclass_con .cc2 p').html(data_s.specPrice); + $('.miaosha').css('display', 'block'); + $('.price').css('display', 'none'); + $('.price_old').css('display', 'none'); + countTime(); + $('.mujidikou').css('display', 'none'); + + } + } + +} +// H5 plus事件处理 +function plusReady() { + updateSerivces(); + if(plus.os.name == "Android") { + main = plus.android.runtimeMainActivity(); + Intent = plus.android.importClass("android.content.Intent"); + File = plus.android.importClass("java.io.File"); + Uri = plus.android.importClass("android.net.Uri"); + } +} +if(window.plus) { + plusReady(); +} else { + document.addEventListener("plusready", plusReady, false); +} + +/** + * + * 更新分享服务 + */ +function updateSerivces() { + plus.share.getServices(function(s) { + shares = {}; + for(var i in s) { + var t = s[i]; + shares[t.id] = t; + } + }, function(e) { + plus.nativeUI.toast("获取分享服务列表失败:" + e.message); + }); +} + +/** + * 分享操作 + * @param {JSON} sb 分享操作对象s.s为分享通道对象(plus.share.ShareService) + * @param {Boolean} bh 是否分享链接 + */ +function shareAction(sb, bh) { + if(!sb || !sb.s) { + plus.nativeUI.toast("无效的分享服务!"); + return; + } + + var msg = { + content: sharehrefDes.value, + extra: { + scene: sb.x + }, + type: "web" + }; + if(bh) { + msg.href = sharehref.value; + if(sharehrefTitle && sharehrefTitle.value != "") { + msg.title = sharehrefTitle.value; + } + if(sharehrefDes && sharehrefDes.value != "") { + msg.content = sharehrefDes.value; + } + // msg.thumbs = ["_www/logo.png"]; + msg.thumbs = $('.swiper-slide img').eq(0).attr('src') ? [$('.swiper-slide img').eq(0).attr('src') + '/thumb60'] : ["_www/logo.png"]; + + msg.pictures = ["_www/logo.png"]; + } else { + if(pic && pic.realUrl) { + msg.pictures = [pic.realUrl]; + } + } + // 发送分享 + if(sb.s.authenticated) { + // plus.nativeUI.toast("---已授权---"); + shareMessage(msg, sb.s); + } else { + plus.nativeUI.toast("---未授权---"); + sb.s.authorize(function() { + shareMessage(msg, sb.s); + }, function(e) { + plus.nativeUI.toast("认证授权失败:" + e.code + " - " + e.message); + + }); + } +} +/** + * 发送分享消息 + * @param {JSON} msg + * @param {plus.share.ShareService} s + */ +function shareMessage(msg, s) { + + // plus.nativeUI.toast(JSON.stringify(msg)); + s.send(msg, function() { + plus.nativeUI.toast("分享到\"" + s.description + "\"成功! "); + + }, function(e) { + plus.nativeUI.toast("分享到\"" + s.description + "\"失败 "); + + }); +} +// 分析链接 +function shareHref() { + var shareBts = []; + // 更新分享列表 + var ss = shares['weixin']; + ss && ss.nativeClient && (shareBts.push({ + title: '微信朋友圈', + s: ss, + x: 'WXSceneTimeline' + }), + shareBts.push({ + title: '微信好友', + s: ss, + x: 'WXSceneSession' + })); + + // 弹出分享列表 + shareBts.length > 0 ? plus.nativeUI.actionSheet({ + title: '分享注册链接', + cancel: '取消', + buttons: shareBts + }, function(e) { + (e.index > 0) && shareAction(shareBts[e.index - 1], true); + }) : plus.nativeUI.plus.nativeUI.toast('当前环境无法支持分享链接操作!'); +} + +function whslePrice(num, arry_str) { + for(var i in data_saleSpec) { + if(i == arry_str) { + // if(num >= (+(data_saleSpec[i].initNum)) && data_saleSpec[i].whslePrice > 0) { + if(isShowWhsle == 1 && data_saleSpec[i].whslePrice > 0) { + $('.cclass_con .cc2 o').html('批发单价:¥' + data_saleSpec[i].whslePrice); + $('.cclass_con .cc2 l').html('起批数:' + data_saleSpec[i].initNum + '件'); + } + } + } + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html('¥' + data_saleSpec[i].specPrice); + } + } +} +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var goodsType; + if (self.goodsType) { + goodsType=self.goodsType; + } + var goodsId = self.data_id; + var isEct = self.isEct; + var isMiaosha = self.isMiaosha; + var MiaoshaSaleSpec = self.MiaoshaSaleSpec; + var specsId = ''; +// //console.log(isMiaosha) + // isMiaosha = 1; + // MiaoshaSaleSpec = '0'; +// console.log(goodsId) + + // mui.ajax(hyhUrl('app/Goods/detail'), { + mui.ajax(qlgUrl('app/Goods/detail'), { + data: { + goodsId: goodsId + // goodsId: 1206 + // goodsId: 1203 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // console.log(data) + var data = toJson(data); + // console.log(data.status) + if(data.status == 1) { + // mui.alert('加载失败请重试!'); + + data = data.data; + data_bak = data; + shopQQ = data.shop.shopQQ; + shopTel = data.shop.phone; + var isEct = data.isEct; + shopName = data.shop.shopName; + // if(!shopQQ && shopTel) { + $('#lxkf').html('<a href="tel:' + shopTel + '"><img src="../img/haitunlogo.png" /><p>客服</p></a>') + // } + if(1 == data.isFavorites){ + $('#scbtn img').attr('src','../img/likelogo1.png') + $('#scbtn p').html("已收藏") + } + var html = '<div class="none" style="display: none;"><p>链接地址:</p><input id="sharehref" type="url" value="' + data.goods_url + '" /><p>链接标题:</p><input id="sharehrefTitle" type="text" value="' + data.goodsName + '" /><p>链接描述:</p><input id="sharehrefDes" type="text" value="' + data.goodsTips + '" /></br></div><div class="banner"><div class="swiper-container"><div class="swiper-wrapper">'; + var html2 = ''; + $.each(data.gallery, function() { + html += '<div class="swiper-slide"><img src="' + hyhImgUrl(this) + '" /></div>'; + }); + + if(isEct == 1) { + html += '</div></div></div><div class="con"><div class="summarize shadown_wai"><div class="miaosha" style="display:none;"></div><p class="price xxl"><o>ECT专享价</o>¥' + data.shopPrice + '</p><p class="price_old">市场价 <del>¥' + data.marketPrice + '</del></p>'; + } else { + html += '</div></div></div><div class="con"><div class="summarize shadown_wai"><div class="miaosha" style="display:none;"></div><p class="price">¥' + data.shopPrice + '</p><p class="price_old">市场价 <del>¥' + data.marketPrice + '</del></p>'; + } + + // var str1 = '<p class="price"><o>到手价</o>¥' + Math.round(data.shopPrice * 0.8 * 100) / 100 + '</p>' + + html += '<p class="cname" id="shareout" style="color:black;font-size:16px"><o> ' + data.goodsName + '</o><img id="share" src="../img/share.png"/></p>'; + if(data.goodsTips) { + html += '<p class="cname">' + data.goodsTips + '</p>'; + } + if(data.isFreeShipping == '1') { + html += '<div class="compilations"><span class="myf">免运费'; + } else { + //html += '<div class="compilations"><span class="myf">不包邮'; + html += '<div class="compilations"><span class="myf">运费'+data.freight; + } + html += '</span><span class="yx">月销:' + data.saleNum + '件</span><span class="dz"></span></div>' + + html += '</div><div class="guarantee shadown_wai"><div class="row clearfix yyyhhhqqq"><img src="../img/gouwuquan.png" /><span class="text">领取优惠券</span><button class="lq">领取</button></div>';//<div class="row clearfix"><span class="text1">木吉</span><span class="text">购买后可获得成交价格20%木吉</span></div> + if(isEct != 1) { + //html += '<div class="row clearfix mujidikou"><span class="text1">木吉</span><span class="text">本商品可用木吉抵扣20%</span></div>' + } else {} + if(data.promotionList != '') { +// html += '<div class="mui-table-view-cell mui-collapse row_"><a class="mui-navigate-right" href="#">促销信息 :' + data.promotionList.rewardTitle + '</a><div class="mui-collapse-content" style="width:100%">'; +// $.each(data.promotionList.json, function() { +// html += '<h4>满' + this.orderMoney + '元</h4>'; +// +// if(this.favourableJson.chk0 == true) { +// html += '<h5>减' + this.favourableJson.chk0val + '元</h5>'; +// } +// if(this.favourableJson.chk1 == true) { +// html += '<h5>送' + this.favourableJson.chk1val.text + '</h5>'; +// } +// if(this.favourableJson.chk2 == true) { +// html += '<h5>免运费</h5>'; +// } +// if(this.favourableJson.chk3 == true) { +// html += '<h5>送满' + this.favourableJson.chk3val.text + '元优惠券 满' + this.favourableJson.chk3val.data.useMoney + '元使用</h5>'; +// } +// +// }); +// +// html += '</div></div>'; + } + var showShopMsg = '<span class="text">正品保证 </span>'; + // if(1778 == data.shopId){ + // showShopMsg+='<span class="text">此商品拆封概不退货换</span>'; + // showShopMsg+='<span class="text">温馨提示:不支持7天无理由退货</span>'; + // + // } + html += '<div class="row clearfix">'+showShopMsg+'<button class="caidan" style="display:none"><img src="../img/menu.png"/></button></div></div><div class="guarantee shadown_wai" id="guarantee"><div class="row clearfix" id="changeclass"><span class="text">选择颜色分类 号码尺寸</span><button class="caidan"><img src="../img/menu.png"/></button></div></div>'; + if(data.oneAppraises == '') { + + } else { + var userImg = ''; + if(data.oneAppraises.userPhoto) { + userImg = hyhImgUrl(data.oneAppraises.userPhoto); + } else { + userImg = '../img/mujiimg.png' + } + + html += '<div class="pjrk shadown_wai" style="display:block"><p class="pj_title">商品评价(' + data.appraiseNum + ')</p><div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + userImg + '" /><p>' + data.oneAppraises.loginName + '</p></div><div class="pjbcon">' + data.oneAppraises.content + '</div><div class="pjclass">' + data.oneAppraises.goodsSpecNames + '</div></div><div class="pj_all">查看全部评价</div></div>'; + } + + img_data = data.goodsDesc.replace(/src=\"__ROOT__\//g, 'data-src="').replace(/data-echo=\"__ROOT__\//g, 'src="' + hyhImgUrl('')).replace(/src=\"\//g, 'src="' + hyhImgUrl('')); + img_data = img_data.replace(/src=\"http\:\/\/img.heyuanhui.cn\//g,'src="' + hyhImgUrl('')); + ////console.log(img_data) + html += '<div class="shop_info shadown_wai"><div class="shop_title clearfix"><img src="' + hyhImgUrl(data.shop.shopImg) + '" /><p data-shopId="' + data.shop.shopId + '">' + data.shop.shopName + '</p></div><div class="shopinfocon clearfix"><div class="sicl"><div class="sicl_p1">' + data.goodsCount + '</div><div class="sicl_p2">全部宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.newGoodsCount + '</div><div class="sicl_p2">上新宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.favoritesShopsNum + '</div><div class="sicl_p2">关注人数</div></div><div class="sicr"><div class="sicr_p">宝贝描述&nbsp;<o>' + data.shop.goodsScore + '</o></div><div class="sicr_p">卖家服务&nbsp;<o>' + data.shop.serviceScore + '</o></div><div class="sicr_p">物流服务&nbsp;<o>' + data.shop.timeScore + '</o></div></div></div></div><div class="imgcon"></div></div>'; + $('.con_').html(html); + + $('.cclass_con .img').html('<img src="' + hyhImgUrl(data.goodsImg) + '" />'); + $('.cclass_con .cc2 p').html('¥' + data.shopPrice); + $('.cclass_con .cc2 span').html('库存' + data.goodsStock + '件'); + if(data.showWhsle == 1) { + isShowWhsle = 1; + } + $('#storebtn').attr('data-shopId', data.shopId); + $('.swiper-slide img').height($('.swiper-slide img').width()); + $('.swiper-slide').height($('.swiper-slide').width()); + //$('.swiper-slide').height($('.swiper-slide').width() * 460 / 750); + //$('.swiper-slide img').height($('.swiper-slide img').width() * 460 / 750); + + // $('.banner').height($('.banner').width()); + var swiper = new Swiper('.swiper-container', { + pagination: '.swiper-pagination', + paginationClickable: true, + spaceBetween: 30, + autoplay: 3000 + }); + var html1 = ''; + // var html1 = '<div class="mui-scroll-wrapper" id="hahaha"><div class="mui-scroll">'; + $.each(data.spec, function() { + html1 += '<div class="cclass1 clearfix" data-class=""><p>' + this.name + '</p>' + $.each(this.list, function() { + // //console.log(this.itemId) + html1 += '<div class="block" data-itemId="' + this.itemId + '" data-itemImg="' + this.itemImg + '">' + this.itemName + '</div>' + }); + html1 += '</div>' + }); + // html1+='</div></div>' + $('.ccclass').html(html1); + // var hahaha = mui('#hahaha').scroll(); + // $('.ccclass').height($('#hahaha').height()) + for(var i in data.saleSpec) { + data_saleSpec[i] = data.saleSpec[i]; + // if(data.saleSpec[i]["id"] == MiaoshaSaleSpec) { + // specsId = i + // arry_str = i; + // isDefaultArr = i.split(':'); + // } + if(data.saleSpec[i]["isDefault"] == 1) { + isDefaultArr = i.split(':'); + arry_str = i; + } + + } + if(data.couponList == '') { + $('.yyyhhhqqq').css('display', 'none'); + } else { + $.each(data.couponList, function() { + html2 += '<div class="thq_block"><img src="' + hyhImgUrl('static/app2/img/coupon_bg.png') + '"/><p>¥' + this.couponValue + '</p><span>满' + this.useMoney + '元使用</span><button class="lq_btn" data-couponId="' + this.couponId + '">领取</button></div>'; + }); + $('.yhqcon').html(html2); + } + + // if(isMiaosha == 1 || (data.is_seckilling&&data.is_seckilling == 1)||(data_saleSpec[arry_str].is_seckilling&&data_saleSpec[arry_str].is_seckilling==1)) { + var html_miaosha = '' + if(data.is_seckilling && data.is_seckilling == '1') { + $('.mujidikou').css('display', 'none'); + seckilling_end_time = data.seckilling_end_time; + html_miaosha = '<img src="../img/bg_miaosha.png"/><p class="miaosha1"><o>¥</o>' + data.shopPrice + '</p><del class="miaosha2">¥' + data.marketPrice + '</del><div class="xiangou">限购四件</div><p class="miaosha3"><o id="_h">00</o>:<o id="_m">00</o>:<o id="_s">00</o></p><p class="miaosha4">桔子抢购</p><p class="miaosha5">距结束还剩</p>'; + + $('.miaosha').html(html_miaosha); + $('.miaosha').css('display', 'block'); + $('.price').css('display', 'none'); + $('.price_old').css('display', 'none'); + countTime(); + } else if(data_saleSpec[arry_str] && data_saleSpec[arry_str].is_seckilling && data_saleSpec[arry_str].is_seckilling == 1) { + miaoshaSaleSpec(data_saleSpec[arry_str].id, data_saleSpec); + } else if(isMiaosha == 1) { + miaoshaSaleSpec(MiaoshaSaleSpec, data_saleSpec); + } + // } + else { + $.each(isDefaultArr, function() { + var that = this; + $('.cclass1 .block').each(function() { + + if($(this).attr('data-itemId') == that) { + $(this).addClass('on'); + $(this).parent().attr('data-class', that); + } + + }) + + }) + } + } else if(data.status == -22) { + alert(data.msg); + mui.back(); + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + //console.log(errorThrown); + } + }); + var scroll = mui('.mui-scroll-wrapper').scroll({ + //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + deceleration: 0.002 + }); + var show_img=false; + //导航栏渐变 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + var num; + if(scroll.y >= -387 && scroll.y < 0) { + + num = scroll.y / -387; + // //console.log('渐变',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + if(false == show_img){ + show_img=true; + $('.imgcon').html(img_data); + } + var num1 = 0.2 - num * 0.2; + } else if(scroll.y >= 0) { + num = 0; + // //console.log('透明',num) + $('.header1').css({ + 'display': 'none', + 'opacity': num + }) + } else if(scroll.y < -387) { + + num = 1; + // //console.log('不透明',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + } + //导航栏自动切换 + if($('.imgcon').offset().top >= 66) { + $('#nav1').addClass("on").siblings().removeClass('on'); + } else if($('.imgcon').offset().top < 66) { + $('#nav3').addClass("on").siblings().removeClass('on'); + } + }) + + mui('.header').on('tap', '.icon-cart', function() { + JZL.openWindow('shoppingcart.html','shoppingcart.html'); + }); + //点击导航栏跳转 + mui('.nav').on('tap', '#nav1', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); + $('#nav1').addClass("on").siblings().removeClass('on'); + }); + mui('.nav').on('tap', '#nav2', function() { + JZL.openWindow('appraise.html','appraise.html',{goodsId: goodsId}); + }); + mui('.nav').on('tap', '#nav3', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, -1124, 100); + $('#nav3').addClass("on").siblings().removeClass('on'); + }); + + mui('.con_').on('tap', '#changeclass', function() { + $('#changeclass_con').show(); + }) + + //选择类型 + mui('.ccclass').on('tap', '.block', function() { + $(this).addClass('on').siblings().removeClass('on'); + $(this).parent().attr('data-class', $(this).attr('data-itemId')); + + var data_itemId = $(this).attr('data-itemId'); + if($(this).attr('data-itemImg') != '') { + $('.cclass_con .img').html('<img src="' + hyhImgUrl($(this).attr('data-itemImg')) + '" />'); + } + + var arry = []; + + $.each($('.cclass1'), function() { + arry.push($(this).attr('data-class')) + }); + arry.sort(function(a, b) { + return a - b; + }); + + arry_str = arry.join(':'); + + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + $('.cclass_con .cc2 span').html('库存' + data_saleSpec[i].specStock + '件'); + + if(data_saleSpec[i].is_seckilling && data_saleSpec[i].is_seckilling == 1) { + miaoshaSaleSpec(data_saleSpec[i].id, data_saleSpec); + } else { + + $('.miaosha').html(''); + $('.miaosha').css('display', 'none'); + $('.price').html('¥' + data_saleSpec[i].specPrice); + $('.price_old').html('市场价 <del>¥' + data_saleSpec[i].marketPrice + '</del>'); + $('.price').css('display', 'block'); + $('.price_old').css('display', 'block'); + } + } + } + + var num = +$('.change_num input').val(); + whslePrice(num, arry_str); + + }) + //跳转选择类型 + + $('.footer').on('tap', '.btn_ljgm', function() { + $('#changeclass_con').show(); + }) + //关闭 + mui('.cc2').on('tap', '.closecclass', function() { + $('#changeclass_con').hide(); + }) + + mui('.en').on('tap', '.engwc', function() { + $('#changeclass_con').hide(); + }) + + //改变数量 + mui('.change_num').on('tap', '.jia', function() { + // //console.log($(this).siblings('input').val()) + var num = +$(this).siblings('input').val() + 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + mui('.change_num').on('tap', '.jian', function() { + var num = +$(this).siblings('input').val() - 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + $('.change_num input').on('change', function() { + var num = +$(this).val(); + + whslePrice(num, arry_str); + }) + + mui('.mui-backdrop').on('tap', '.mask', function() { + $('#changeclass_con').hide(); + }) + //加入购物车&购买 + mui('.en').on('tap', '.enarr', function() { + + var that = $(this); + // var goodsId = goodsId; + var buyNum = $('.change_num input').val(); + var isGoodsSpecId = 0; + var goodsSpecId = 0; + var url = ''; + if($(this).hasClass('engwc')) { + url = 'addCart'; + } else if($(this).hasClass('ensure')) { + url = 'buy'; + } + // //console.log(data_bak.isSpec) + for(var i in data_saleSpec) { + if(i == arry_str) { + isGoodsSpecId = 1; + goodsSpecId = data_saleSpec[i].id; + } + } + if(isGoodsSpecId == 1) { + // goodsSpecId = arry_str; + } else if(data_bak.isSpec == 0) { + goodsSpecId = 0; + } else { + alert('请选择商品分类!'); + return + } + if(goodsType==2 & $(this).hasClass('engwc')) { + mui.alert ("助微吧商品不能加入购物车") + return; + } + // //console.log(arry_str) + // //console.log(goodsSpecId) + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/' + url), { + headers: { + "HYH-Token": token + }, + data: { + if(goodsType){ + goodsType:goodsType + }, + goodsId: goodsId, + buyNum: buyNum, + goodsSpecId: goodsSpecId + + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + data = toJson(data); + // //console.log(data.msg); + // //console.log(data.status); + if(data.status == 1) { + if(url == 'buy') { + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // goodsId: goodsId + + type: 1 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } else if(url == 'addCart') { + mui.alert('添加购物车成功!') + } + + } else { + mui.alert(data.msg); + //location.reload(); + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // alert(type); + } + }); + + }) + + //打开评价列表 + mui('.con_').on('tap', '.pjrk', function() { + JZL.openWindow('appraise.html','appraise.html',{goodsId: goodsId}); + }) + $('.footer').on('tap', '#scbtn', function() { + var goodId = goodsId; + var that = $(this); + if($('#scbtn p').html() == '收藏') { + mui.ajax(qlgUrl('app/Favorites/add'), { + + data: { + id: goodId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#scbtn p').html('已收藏'); + $('#scbtn p').css('color', '#E41F4A'); + $('#scbtn img').attr('src', '../img/likelogo1.png'); + // that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + mui.alert(data.msg) + ////console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // alert(type); + } + }); + } else { + mui.ajax(hyhUrl('app/Favorites/cancel'), { + + data: { + id: goodId, + type : 0 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#scbtn p').html('收藏'); + $('#scbtn p').css('color', '#8f8f94'); + $('#scbtn img').attr('src', '../img/likelogo.png'); + // that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + mui.alert(data.msg) + ////console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // alert(type); + } + }); + } + + }) + $('.footer').on('tap', '#storebtn', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + JZL.openWindow('storeout.html','storeout.html'+ shopId,{shopId: shopId,shopName:shopName}); + }) + $('.con').on('tap', '.shop_title p', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + JZL.openWindow('storeout.html','storeout.html'+ shopId,{shopId: shopId}); + }) + //弹出优惠券 + $('.con_').on('tap', '.lq', function() { + $('#youhuiquan_con').css('display', 'block'); + }) + //关闭优惠券 + $('#youhuiquan_con').on('tap', '.thq_close', function() { + $('#youhuiquan_con').css('display', 'none'); + }) + //领取优惠券 + $('#youhuiquan_con').on('tap', '.lq_btn', function() { + var couponId = $(this).attr('data-couponId'); + mui.ajax(hyhUrl('addon/coupon-Coupons-receive'), { + headers: { + "HYH-Token": token + }, + data: { + couponId: couponId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + var data = toJson(data); + alert(data.msg); + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // alert(type); + } + }); + }) + //联系客服 + + $('#lxkf').on('tap', function() { + if(shopQQ) { + // location.href="http://wpa.qq.com/msgrd?v=3&uin="+ shopQQ +"&site=qq&menu=yes"; + // mui.back(); + // window.open("http://wpa.qq.com/msgrd?v=3&uin="+ shopQQ +"&site=qq&menu=yes") + if(plus.os.name == "iOS") { + plus.runtime.launchApplication({ + action: "mqq://im/chat?chat_type=wpa&uin=" + shopQQ + "&version=1&src_type=web" + }, function(e) { + plus.nativeUI.confirm("检查到您未安装qq,请先到appstore搜索下载?", function(i) { + if(i.index == 0) { + iosAppstore("itunes.apple.com/cn/app/mqq/"); + } + }); + }); + } else if(plus.os.name == "Android") { + var Intent = plus.android.importClass('android.content.Intent'); + var Uri = plus.android.importClass('android.net.Uri'); + var main = plus.android.runtimeMainActivity(); + var uri = Uri.parse("mqqwpa://im/chat?chat_type=wpa&uin=" + shopQQ); + main.startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + } + }) + //分享 + $('.con_').on('tap', '#share', function() { + shareHref(); + }) + + + +}) +// var self = plus.webview.currentWebview(); +// //console.log(self.aaa) \ No newline at end of file diff --git a/static/app2/js/details_ac.js b/static/app2/js/details_ac.js new file mode 100755 index 0000000..b152275 --- /dev/null +++ b/static/app2/js/details_ac.js @@ -0,0 +1,448 @@ +mui.plusReady(function() { + var data = ''; + var data_saleSpec = {} + var arry_str = ''; + var self = plus.webview.currentWebview(); + var data_id = self.data_id; + var data_bak = {} + + function whslePrice(num, arry_str) { + for(var i in data_saleSpec) { + if(i == arry_str) { + if(num >= (+(data_saleSpec[i].initNum))) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].whslePrice); + } + } + } + for(var i in data_saleSpec) { + if(i == arry_str) { + if(num < (+(data_saleSpec[i].initNum))) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + } + } + } + } + mui.ajax(hyhUrl('app/Goods/detail'), {  + data: { + goodsId: data_id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + if(data.status != 1) { + mui.alert('加载失败请重试!'); + } + data = data.data; + data_bak = data; + var html = '<div class="banner"><div class="swiper-container"><div class="swiper-wrapper">'; + + $.each(data.gallery, function() { + html += '<div class="swiper-slide"><img src="' + hyhImgUrl(this) + '" /></div>'; + }); + + html += '</div></div></div><div class="summarize"><p class="price">¥' + data.shopPrice + '</p><p class="price_old">价格 <del>¥' + data.marketPrice + '</del></p><div class="compilations"><span class="myf">'; + + if(data.isFreeShipping == '1') { + html += '免运费'; + } else { + html += '不包邮'; + } + html += '</span><span class="yx">月销:' + data.saleNum + '件</span><span class="dz"></span></div><p class="cname">商品介绍 ' + data.goodsTips + '</p></div><div class="guarantee"><div class="row clearfix" style="display:none"><img src="../img/gouwuquan.png" /><span class="text">全合源惠实物商品通用</span><button class="lq">领取</button></div><div class="row clearfix"><img src="../img/jifen.png" /><span class="text">购买后可获得100%积分</span></div><div class="row clearfix"><span class="text">正品保证 · 公益宝贝 · 赠运险费 · 极速退款 · 七天退货</span><button class="caidan" style="display:none"><img src="../img/menu.png"/></button></div></div><div class="guarantee" id="guarantee"><div class="row clearfix" id="changeclass"><span class="text">选择颜色分类 号码尺寸</span><button class="caidan"><img src="../img/menu.png"/></button></div></div>'; + if(data.oneAppraises == '') { + + } else { + html += '<div class="pjrk" style="display:none"><p class="pj_title">商品评价(' + data.appraiseNum + ')</p><div class="pj_breviary"><div class="pjbtitle clearfix"><img src="' + hyhImgUrl(data.oneAppraises.userPhoto) + '" /><p>' + data.oneAppraises.loginName + '</p></div><div class="pjbcon">' + data.oneAppraises.content + '</div><div class="pjclass">' + data.oneAppraises.goodsSpecNames + '</div></div><div class="pj_all">查看全部评价</div></div>'; + } + + html += '<div class="shop_info"><div class="shop_title clearfix"><img src="' + hyhImgUrl(data.shop.shopImg) + '" /><p>' + data.shop.shopName + '</p></div><div class="shopinfocon clearfix"><div class="sicl"><div class="sicl_p1">' + data.goodsCount + '</div><div class="sicl_p2">全部宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.newGoodsCount + '</div><div class="sicl_p2">上新宝贝</div></div><div class="sicl"><div class="sicl_p1">' + data.favoritesShopsNum + '</div><div class="sicl_p2">关注人数</div></div><div class="sicr"><div class="sicr_p">宝贝描述&nbsp;<o>' + data.shop.goodsScore + '</o></div><div class="sicr_p">卖家服务&nbsp;<o>' + data.shop.serviceScore + '</o></div><div class="sicr_p">物流服务&nbsp;<o>' + data.shop.timeScore + '</o></div></div></div></div><div class="imgcon">' + data.goodsDesc + '</div>'; + $('.con').html(html); + + $('.cclass_con .img').html('<img src="' + hyhImgUrl(data.goodsImg) + '" />'); + $('.cclass_con .cc2 p').html(data.shopPrice); + $('.cclass_con .cc2 span').html('库存' + data.goodsStock + '件'); + $('#storebtn').attr('data-shopId', data.shopId) + var swiper = new Swiper('.swiper-container', { + pagination: '.swiper-pagination', + paginationClickable: true, + spaceBetween: 30, + autoplay: 3000 + }); + var html1 = ''; + $.each(data.spec, function() { + html1 += '<div class="cclass1 clearfix" data-class=""><p>' + this.name + '</p>' + $.each(this.list, function() { + html1 += '<div class="block" data-itemId="' + this.itemId + '">' + this.itemName + '</div>' + }); + + html1 += '</div>' + }); + $('.ccclass').html(html1) + + for(var i in data.saleSpec) { + data_saleSpec[i] = data.saleSpec[i]; + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + var scroll = mui('.mui-scroll-wrapper').scroll({ + deceleration: 0.002 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + }); + + //导航栏渐变 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + + var num; + + if(scroll.y >= -387 && scroll.y < 0) { + + num = scroll.y / -387; + // console.log('渐变',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'block', + 'opacity': num + }) + var num1 = 0.2 - num * 0.2; + // $('.header .mui-action-back').css('background', 'rgba(0,0,0,' + num1 + ')') + } else if(scroll.y >= 0) { + num = 0; + // console.log('透明',num) + $('.header1').css({ + 'display': 'none', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'none', + 'opacity': num + }) + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } else if(scroll.y < -387) { + + num = 1; + // console.log('不透明',num) + $('.header1').css({ + 'display': 'block', + 'opacity': num + }) + $('.zhe').css({ + 'display': 'block', + 'opacity': num + }); + // $('.header .mui-action-back').css('background', 'rgba(0, 0, 0, 0.2)') + } + //导航栏自动切换 + if($('.imgcon').offset().top >= 66) { + $('#nav1').addClass("on").siblings().removeClass('on'); + } else if($('.imgcon').offset().top < 66) { + $('#nav3').addClass("on").siblings().removeClass('on'); + } + }) + //点击导航栏跳转 + mui('.nav').on('tap', '#nav1', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); + $('#nav1').addClass("on").siblings().removeClass('on'); + }); + mui('.nav').on('tap', '#nav2', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); + mui('.nav').on('tap', '#nav3', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, -1124, 100); + $('#nav3').addClass("on").siblings().removeClass('on'); + }); + + mui('.con').on('tap', '#changeclass', function() { + $('#changeclass_con').show(); + }) + + //选择类型 + mui('.ccclass').on('tap', '.block', function() { + $(this).addClass('on').siblings().removeClass('on'); + $(this).parent().attr('data-class', $(this).attr('data-itemId')); + + var data_itemId = $(this).attr('data-itemId'); + + $.each(data.spec, function() { + $.each(this.list, function() { + if(this.itemId == data_itemId && this.itemImg != '') { + $('.cclass_con .img').html('<img src="' + hyhImgUrl(this.itemImg) + '" />'); + } + }); + }); + + var arry = []; + + $.each($('.cclass1'), function() { + arry.push($(this).attr('data-class')) + }); + arry.sort(function(a, b) { + return a - b; + }); + + arry_str = arry.join(':'); + $.each(data.saleSpec, function() { + if(this == arry_str) { + $('.cclass_con .cc2 p').html(this.specPrice); + $('.cclass_con .cc2 span').html('库存' + this.specStock + '件'); + } + }); + + for(var i in data_saleSpec) { + if(i == arry_str) { + $('.cclass_con .cc2 p').html(data_saleSpec[i].specPrice); + $('.cclass_con .cc2 span').html('库存' + data_saleSpec[i].specStock + '件'); + } + } + + var num = +$('.change_num input').val(); + whslePrice(num, arry_str); + }) + //跳转选择类型 + + $('.footer').on('tap', '.btn_ljgm', function() { + $('#changeclass_con').show(); + }) + + mui('.cc2').on('tap', '.closecclass', function() { + $('#changeclass_con').hide(); + }) + + mui('.en').on('tap', '.engwc', function() { + $('#changeclass_con').hide(); + }) + + //改变数量 + mui('.change_num').on('tap', '.jia', function() { + // console.log($(this).siblings('input').val()) + var num = +$(this).siblings('input').val() + 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + mui('.change_num').on('tap', '.jian', function() { + var num = +$(this).siblings('input').val() - 1; + if(num <= 0) { + alert('购买数最小为1!'); + return; + } + $(this).siblings('input').val(num); + whslePrice(num, arry_str) + }) + $('.change_num input').on('change', function() { + var num = +$(this).val(); + + whslePrice(num, arry_str); + }) + //加入购物车&购买 + mui('.en').on('tap', '.enarr', function() { + + var that = $(this); + var goodsId = data_id; + var buyNum = $('.change_num input').val(); + var isGoodsSpecId = 0; + var goodsSpecId = 0; + var url = ''; + if($(this).hasClass('engwc')) { + url = 'addCart'; + } else if($(this).hasClass('ensure')) { + url = 'buy'; + } + // console.log(data_bak.isSpec) + for(var i in data_saleSpec) { + if(i == arry_str) { + isGoodsSpecId = 1; + } + } + if(isGoodsSpecId == 1) { + goodsSpecId = arry_str; + } else if(data_bak.isSpec == 0) { + goodsSpecId = 0; + } else { + alert('请选择商品分类!'); + return + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/' + url), {  + data: { + goodsId: goodsId, + buyNum: buyNum, + goodsSpecId: goodsSpecId + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + data = toJson(data); + if(data.status == 1) { + if(url == 'buy') { + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + + type: 1 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } else if(url == 'addCart') { + alert('添加购物车成功!') + } + + } else { + alert(data.msg); + //location.reload(); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + + //打开评价列表 + mui('.con').on('tap', '.pjrk', function() { + mui.openWindow({ + url: 'appraise.html', + id: 'appraise.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.footer').on('tap', '#storebtn', function() { + var shopId = this.attributes["data-shopId"].nodeValue; + var url = 'storeout.html'; + if(shopId==1){ + url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) +// var self = plus.webview.currentWebview(); +// console.log(self.aaa) \ No newline at end of file diff --git a/static/app2/js/discount.js b/static/app2/js/discount.js new file mode 100755 index 0000000..7f356d0 --- /dev/null +++ b/static/app2/js/discount.js @@ -0,0 +1,164 @@ +$('.mui-action-back').css('display', 'none'); +$('.header_con img').attr('src', hyhImgUrl('static/app2/img/sale.png')); +var topTypeId = '40'; +var secTypeId = ''; +var pageSize = 10; +var page = 1; +var isjiazai = 1; + +function lxy_dis(topTypeId, secTypeId, page, pageSize) { + + var lxy_data_ = { + topTypeId: topTypeId ? topTypeId : '40', + secTypeId: secTypeId ? secTypeId : '', + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(llUrl('addon/hyhlimitactive-Hyhlimitactive-actGoodsList'), {  + data: lxy_data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + + //var data = toJson(data); + var data = data.data + var html = ''; + + if(data.Rows == '') { + + if(page == 1) { + $('#recommend_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } else { + $('#recommend_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } + + isjiazai = 0; + return; + } + + $.each(data.Rows, function() { + html += '<div class="con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="img" src="' + ectImgUrl(this.goodsImg) + '" /><p class="p1">' + this.goodsName + '</p><p class="p2">享' + parseInt(this.shopPrice * 10 / this.marketPrice) + '折优惠</p><p class="p3">¥<o>' + this.shopPrice + '</o></p><del><o>' + this.marketPrice + '</o></del><button>立即购买</button></div>' + }); + + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + + isjiazai = 1; + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  +} + +mui.plusReady(function() { + + mui.ajax(llUrl('addon/hyhlimitactive-Hyhlimitactive-actList'), { + data: { + topTypeId: topTypeId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum); + //console.log(data.data.Rows); + //console.log(data.status); + //var data = toJson(data); + if(data.status == 1) { + var data = data.data + var html = ''; + var len = 0; + $.each(data.lists, function() { + html += '<div class="swiper-slide nav_block" data-secTypeId="' + this.secTypeId + '"><p class="p1">' + this.secTypeName + '</p></div>' + + }); + $('.nav').html(html); + + if(data.lists.length > 5) { + len = 4.5 + } else { + len = data.lists.length; + } + var swiper = new Swiper('#timer_swiper', { + slidesPerView: len, + paginationClickable: true, + spaceBetween: 0, + freeMode: true + }); + + $('.nav_block').eq(0).addClass('on'); + secTypeId = $('.nav_block').eq(0).attr('data-secTypeId'); + lxy_dis(topTypeId, secTypeId, 1, 10); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type); + }  + }) + + mui('.nav').on('tap', '.nav_block', function() { + secTypeId = $(this).attr('data-secTypeId'); + page = 1; + isjiazai=1; + lxy_dis(topTypeId, secTypeId, page, 10); + + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + lxy_dis(topTypeId, secTypeId, page, pageSize); + } + + } + }) + + $('#recommend_con').on('tap', '.con_block', function() { + var good_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/discounts.js b/static/app2/js/discounts.js new file mode 100755 index 0000000..2648c3e --- /dev/null +++ b/static/app2/js/discounts.js @@ -0,0 +1,80 @@ +jumpPage(); + +function jumpPage() { + //跳转页面 + var subpages = ['choiceness.html', 'dynamic.html', 'new_product.html']; + var subpage_style = { + top: '103px', + bottom: '0px', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if(targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if(mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + + if(targetTab == 'choiceness.html') { + document.getElementsByClassName('p1')[1].classList.remove('on') + document.getElementsByClassName('p1')[2].classList.remove('on') + this.classList.add('on'); + } + + if(targetTab == 'dynamic.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + document.getElementsByClassName('p1')[2].classList.remove('on') + this.classList.add('on'); + } + + if(targetTab == 'new_product.html') { + document.getElementsByClassName('p1')[0].classList.remove('on') + document.getElementsByClassName('p1')[1].classList.remove('on') + this.classList.add('on'); + } + + }); + + //首次启动切滑效果 + + mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // //console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + for(var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if(i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + }); +} \ No newline at end of file diff --git a/static/app2/js/distribution.js b/static/app2/js/distribution.js new file mode 100755 index 0000000..e14f850 --- /dev/null +++ b/static/app2/js/distribution.js @@ -0,0 +1,98 @@ +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var userId = self.userId + var idx = 0; + var curIdx; + var productNum = ""; + var couponsNum = ''; + var click = false; + var type, payPwd, num; + //获取数据 + JZL.ajax(qlgUrl('app/users/getInvestmentMoney'), { + userId: userId + }, function(data) { + // console.log(data); + if (1 == data.status) { + var data = data.data; + productNum = data.productNum; + couponsNum = data.couponsNum; + $(".product .productNum").val(productNum); + + } + }) + + + $(".nav").on("tap", ".nav-item", function() { + curIdx = idx + idx = $(this).index() + + $(".nav .nav-item ").eq(idx).addClass("active") + $(".nav .nav-item ").not($(".nav .nav-item ").eq(idx)).removeClass("active") + $(".content .content_ ").eq(idx).show() + $(".content .content_ ").not($(".content .content_ ").eq(idx)).hide() + if (0 == idx) { //product + if (curIdx != idx) { + //获取数据 + $(".product .productNum").val(productNum); + } + + } else if (1 == idx) { //voucher + if (curIdx != idx) { + //获取数据 + $('.voucher .couponsNum ').val(couponsNum) + } + } + + }) + + + $(".down").on("tap", function() { + if (true == click) { + return + } + click = true; + + + if ('' == $('.product .productNum').val() || '' == $.trim($('.product .productNum').val())) { + mui.alert("券值不能为空"); + return; + } + if ($('.product .productNum').val() < 15) { + mui.alert("券值不能低于15 "); + return; + } + + if (0 == idx) { //product + num = parseFloat($('.product .productNum').val()) + type = 1; + payPwd = $('.proPassWord').val(); + + } + if (1 == idx) { //voucher + //ajax + num = parseFloat($('.voucher .couponsNum').val()) + type = 2; + payPwd = $('.vouPassWord').val(); + + } + if ('' == payPwd) { + mui.alert("操作密码不能为空"); + return; + } + console.log(idx); + JZL.ajax(qlgUrl("app/users/distributionInvestmentMoney"), { + userId: userId, + type: type, + num: num, + payPwd: payPwd + }, function(data) { + if (1 == data.status){ + mui.toast(data.msg) + mui.back(); + }else { + mui.alert (data.msg) + } + }) + + }) +}) diff --git a/static/app2/js/dynamic.js b/static/app2/js/dynamic.js new file mode 100755 index 0000000..1877884 --- /dev/null +++ b/static/app2/js/dynamic.js @@ -0,0 +1,175 @@ +var token = localStorage.getItem('token'); +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('addon/hyhprom-Hyhpromuser-getShopPromByUser'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: count, + pagesize : 10 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">' + this.promInfo + '</div></div>' + }); + $('.con').append(html); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var data = ''; + mui.ajax(hyhUrl('addon/hyhprom-Hyhpromuser-getShopPromByUser'), {  + data: { + pagesize: 10, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + if(data.status == 1) { + data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.updateTime + '</p></div><div class="b_con clearfix">' + this.promInfo + '</div></div>' + }); + $('.con').html(html); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + var url = 'storeout.html'; + if(shopId==1){ +// url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', 'img[data-goodId]', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_address.js b/static/app2/js/ect_address.js new file mode 100755 index 0000000..a5ec52c --- /dev/null +++ b/static/app2/js/ect_address.js @@ -0,0 +1,159 @@ +$('.add').css('display','none'); +$('body').append('<button class="addAddress">添加地址</button>'); +mui.plusReady(function() { + + // function hyhUrl(url) { + // return 'http://192.168.1.101/hyh/' + url; + // } + + var token = localStorage.getItem('token'); + + // alert(token); + + mui.ajax(hyhUrl('app/Ectwallets/listQuery'), {  + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data != '') { + $.each(data.data, function() { + html += '<div class="row shadown_wai"><div class="r_con"><p>钱包地址 ' + this.eAddress + '</p></div><div class="r_bottom " data-eWalletId="' + this.eWalletId + '" data-isDefault="' + this.isDefault + '"><div class="default "><div class="check mui-icon mui-icon-checkmarkempty"></div><p>设为默认</p></div><div class="del"><a class="mui-icon mui-icon-trash del_icon"></a><div class="del_text">删除</div></div></div></div>'; + }); + $('.mui-scroll').html(html); + + $('.row').each(function() { + if($(this).children('.r_bottom').attr('data-isDefault') == 1) { + $(this).children('.r_bottom').children('.default').children('.check').addClass('on'); + } + }) + + } + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //设为默认 + $('.mui-scroll').on('tap', '.default', function() { + + if($(this).parent().attr('data-isDefault') == 0) { + if(confirm('设为默认地址?')) { + var eWalletId = $(this).parent().attr('data-eWalletId'); + // console.log(eWalletId) + mui.ajax(hyhUrl('app/Ectwallets/setDefault'), {  + headers: {  + "HYH-Token": token + }, + data: { + eWalletId: eWalletId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + } + }) + //删除地址 + $('.mui-scroll').on('tap', '.del', function() { + if(confirm('删除地址?')) { + var eWalletId = $(this).parent().attr('data-eWalletId'); + // console.log(eWalletId) + mui.ajax(hyhUrl('app/Ectwallets/del'), {  + headers: {  + "HYH-Token": token + }, + data: { + eWalletId: eWalletId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + }) + + //添加地址 + $('body').on('tap','.addAddress', function() { + var eAddress = ''; + var eAddress_ = ''; + + if(eAddress = prompt('请输入钱包地址')) { + if(eAddress.length != 42) { + alert('钱包地址长度必须为42位'); + return; + } +// if(eAddress_ = prompt('请再次输入钱包地址')) { +// if(eAddress == eAddress_) { + var isDefault = 0; + if(confirm('是否设为默认地址?')) { + isDefault = 1; + } + mui.ajax(hyhUrl('app/Ectwallets/add'), {  + headers: {  + "HYH-Token": token + }, + data: { + eAddress: eAddress, + isDefault: isDefault + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + plus.nativeUI.toast(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  +// } else { +// alert('两次地址输入不一致!'); +// } +// } + } + + }) +}) \ No newline at end of file diff --git a/static/app2/js/ect_area.js b/static/app2/js/ect_area.js new file mode 100755 index 0000000..7b33542 --- /dev/null +++ b/static/app2/js/ect_area.js @@ -0,0 +1,270 @@ +$('.mui-title').html('ECT专区'); +var ect_top = '<div class="ect_top"><p class="ect_m">最新价</p><p class="ect_m">24H成交量</p><img src="http://img.juzi199.com/Upload/app/icon/star.png" /><p class="ect_m" id="last"></p><p class="ect_m" id="vol"></p></div>'; +$('header').before(ect_top); + +$('.mui-scroll-wrapper').removeClass('scroll_out1').addClass('scroll_out3'); +var info = '<img src="http://img.juzi199.com/Upload/app/icon/info.png" class="tanhao" />'; +$('header').append(info); +var nav = '<div class="nav clearfix"></div>'; +$('.ect_top').before(nav); +var nav_data = []; +var secTypeId = 0; +var timestamp1 = Date.parse(new Date()); +if(timestamp1 >= 1537027200000) { + secTypeId = 4; + nav_data = [{ + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} else { + secTypeId = 1; + nav_data = [{ + "secTypeId": 1, + "name": "9.15元专区" + }, { + "secTypeId": 2, + "name": "满199减100" + }, { + "secTypeId": 3, + "name": "买二赠一专区" + }, { + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} + +var issx = 0; +var doller = 0; +function getData(secTypeId) { + // mui('').pullRefresh().scroll(0, 0, 0); + backTop(); + var data_set = { + secTypeId: secTypeId, + topTypeId: 1 + }; + mui.ajax(llUrl('addon/hyhlimitactive-Hyhlimitactive-frontList'), { + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + + data = data.data; + var html_ = ''; + var htmlcon = ''; + doller = data.doller; + if(data.secTypeId == 5 || data.secTypeId == 4) { + htmlcon = '<div class="ect_activity"><img src="http://img.juzi199.com/static/app/img/e' + secTypeId + '.png" class="ect_hd" /></div>' + } else { + htmlcon = '<div class="ect_activity_"><img src="http://img.juzi199.com/static/app/img/countdown.png" class="ect_djs" /> <span id="_h">00</span><span id="_m">00</span><span id="_s">00</span></div>' + html_ = '<div class="day"><p>此活动仅限14-15号两天</p></div>'; + } + + $.each(data.list, function() { + htmlcon += '<div class="ect_com" data-id="' + this.goodsId + '"><div class="com_img1" ><img src="' + hyhImgUrl(this.goodsImg) + '" /></div><p class="p1"><img src="http://img.juzi199.com/static/app/img/ectb.png" class="com_img2" />' + this.goodsName + '</p><p class="p3"><l></l>CNY <o>' + this.shopPrice + '</o></p>' + html_ + '</div>'; + }); + $('.con').html(htmlcon); + setTimeout(function() { + $('.com_img1').height($('.com_img1').width()); + }, 200) + countTime(); + + } else { + console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); +} + +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date("2018/09/16 00:00:00"); + var end = endDate.getTime(); + //时间差 + var leftTime = end - now; + //定义变量 d,h,m,s保存倒计时的时间 + var h, m, s; + if(leftTime >= 0) { + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + document.getElementById("_h").innerHTML = h; + document.getElementById("_m").innerHTML = m; + document.getElementById("_s").innerHTML = s; + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + + }); + getData(secTypeId); + + var html = ''; + $.each(nav_data, function() { + if(timestamp1 >= 1537027200000) { + html += '<div class="nav_block" style="width:50%;" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } else { + html += '<div class="nav_block" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } + + }); + $('.nav').html(html); + $('.nav_block').eq(0).addClass('on'); + + setInterval(function() { + + mui.ajax('https://api.tokencan.net/exchange-open-api/open/api/get_ticker?symbol=ectusdt&random=' + Math.random(), { + + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + $('#last').html(Math.floor((+data.data.last) * doller * 100) / 100); + $('#vol').html(data.data.vol); + $('.p3').each(function(num) { + $(this).children('l').html('ECT ' + (Math.floor(+$(this).children('o').html() / (+data.data.last) / (+doller) * 100)) / 100 + '≈'); + }) + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }, 2000) + + mui("body").on('tap', '.nav_block', function() { + secTypeId = this.attributes["data-secTypeId"].nodeValue; + $(this).addClass('on').siblings().removeClass('on'); + getData(secTypeId) + }) + + mui(".con").on('tap', '.ect_com', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-id"].nodeValue; + var isEct = 1; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + isEct: isEct + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + // if(isjiazai == 1) { + // page++; + // } + + } else if(scroll.y > 100 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + + $('header').on('tap', '.tanhao', function() { + mui.openWindow({ + url: 'activity8.html', + id: 'activity8.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); +}) \ No newline at end of file diff --git a/static/app2/js/ect_index.js b/static/app2/js/ect_index.js new file mode 100755 index 0000000..6a6752d --- /dev/null +++ b/static/app2/js/ect_index.js @@ -0,0 +1,110 @@ +mui.plusReady(function() { + +// $('#ect_withdraw_deposit').css('display','none'); + $('#ect_transfer_accounts').css('display','none'); + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + + + window.addEventListener('refresh', function(e) { //执行刷新 +// location.reload(); + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + if(data.data.eAddressInfo.eAddress){ + $('#ect_add').html('钱包地址:' + data.data.eAddressInfo.eAddress); + }else{ + $('#ect_add').html('钱包地址:未设置钱包地址' ); + } + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }); + + var token = localStorage.getItem('token'); + + // alert(token); + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + if(data.data.eAddressInfo.eAddress){ + $('#ect_add').html('钱包地址:' + data.data.eAddressInfo.eAddress); + }else{ + $('#ect_add').html('钱包地址:未设置钱包地址' ); + } + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + //跳转 + $('body').on('tap', '.row', function() { + var url = $(this).attr('id')+'.html'; + if(url==''){ + return; + } + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_list.js b/static/app2/js/ect_list.js new file mode 100755 index 0000000..9e2ff9f --- /dev/null +++ b/static/app2/js/ect_list.js @@ -0,0 +1,120 @@ +$('.scroll_out_t').removeClass('con'); +$('.mui-scroll').html('<div class="con"></div>'); + +mui.plusReady(function() { + var isjiazai = 1; + var page = 1; + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + function getLocalTime(nS) { + return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' '); + } + + var token = localStorage.getItem('token'); + + // alert(token); + + function getDate(page) { + var num = page; + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(hyhUrl('app/Ectwallets/getEctLog'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data.Rows == '') { + $('.con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多记录</p>'); + isjiazai = 0; + return; + } + $.each(data.data.Rows, function() { + var ectType; + var dataSrc; + if(this.ectType == 1) { + ectType = '+'; + } else { + ectType = '-'; + } + + if(this.dataSrc == 1) { + dataSrc = '注册赠送'; + } else if(this.dataSrc == 2) { + dataSrc = '推荐赠送'; + } else if(this.dataSrc == 3) { + dataSrc = '交易'; + } else if(this.dataSrc == 4) { + dataSrc = '提现'; + }else if(this.dataSrc == 5) { + dataSrc = '联盟积分转换'; + }else if(this.dataSrc == 6) { + dataSrc = '成为商家'; + }else if(this.dataSrc == 7) { + dataSrc = '推荐成为商家'; + }else if(this.dataSrc == 8) { + dataSrc = '成为线上商城商家'; + }else if(this.dataSrc == 9) { + dataSrc = '推荐成为线上商城商家'; + }else if(this.dataSrc == 11) { + dataSrc = '购物'; + }else if(this.dataSrc == 12) { + dataSrc = '结算'; + }else if(this.dataSrc == 13) { + dataSrc = '退款'; + }else if(this.dataSrc == 14) { + dataSrc = '充值'; + }else{ + dataSrc = ''; + } + +// html += '<div class="block"><img src="../img/ect_list_bg.png"/><div class="s1">ECT变动记录</div><div class="s2">' + getLocalTime(this.createTime) + '</div><div class="s3">变动数量</div><div class="s4">' + ectType + ' ' + this.ectNum + ' </div><div class="s5">变动类型:<o>' + dataSrc + '</o></div><div class="s6">备注:<o>' + this.dataRemarks + '</o></div></div>'; + + html +='<div class="row"><img src="../img/bg_pay_list.png"/><p class="p1">' + ectType + ' ' + this.ectNum + '</p><p class="p3">变动类型:<o>' + dataSrc + '</o></p><p class="p2">备注:<o>' + this.dataRemarks + '</p><p class="p4">' + getLocalTime(this.createTime) + '</p></div>' + + }); + + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1 + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } + + getDate(page); + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getDate(page); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_pre_.js b/static/app2/js/ect_pre_.js new file mode 100755 index 0000000..f781f57 --- /dev/null +++ b/static/app2/js/ect_pre_.js @@ -0,0 +1,251 @@ +var topTypeId = '1'; +var secTypeId = ''; +//var sectypeId = ''; +var page = 1; +var pagesize = 10; +var isjiazai = 1; + +function getRecommend(topTypeId, secTypeId, page, pagesize) { + + var recommenddata = { + topTypeId: topTypeId ? topTypeId : '1', + secTypeId: secTypeId ? secTypeId : '', + page: page ? page : 1, + pageSize: pagesize ? pagesize : 10 + } + // console.log(recommenddata.secTypeId); + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-frontList'), { + + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + if(data.list.Rows == '') { + if(page == 1) { + $('#recommend_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } else { + $('#recommend_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + } + isjiazai = 0; + return; + } + + $.each(data.list.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title">' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <!--span>八折</span--></div></div></div>'; + }); + + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + + $('.rcb_img').height($('.rcb_img').width()); + + } else { + //console.log(2) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(errorThrown); + } + }); + +} + +mui.plusReady(function() { + var ua = navigator.userAgent.toLowerCase(); + var issx = 0; + var doller = ''; + //获取 美元价格 + mui.ajax(llUrl('app/ect/getDollerPrice'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if(data.status == 1) { + doller = data.data.now_doller; + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + //ect数据 + setInterval(function() { + + mui.ajax('https://api.tokencan.net/exchange-open-api/open/api/get_ticker?symbol=ectusdt&random=' + Math.random(), { + + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + $('.p2 span').html(Math.floor((+data.data.last) * doller * 100) / 100); + $('.p4 span').html(data.data.vol.toFixed(2)); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }, 2000) + //bannerTop + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-activityList'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="nav_block" data-secTypeId="' + this.secTypeId + '"><span>' + this.secTypeName + '</span></div>'; + }); + $('.nav').html(html); + $('.nav_block').eq(0).addClass('on'); + secTypeId=$('.nav_block').eq(0).attr('data-secTypeId') + getRecommend(topTypeId, secTypeId, page, 10) + } else { + //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(errorThrown); + } + }); + + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-ectCarousel'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + '"><img src="' + ectImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + $('#top_bansner').height($('#top_bansner').width() * 320 / 750); + } else { + //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + //alert(errorThrown); + } + }); + + //轮播图跳转 + $('#top_banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + + mui('.nav').on('tap', '.nav_block', function() { + secTypeId = $(this).attr('data-secTypeId'); + isjiazai = 1; + page = 1; + getRecommend(topTypeId, secTypeId, page, 10); + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getRecommend(topTypeId, secTypeId, page, 10); + } + + } + }) + + //跳转到了解ect + $('.header_con').on('tap', '.know_ect', function() { + mui.openWindow({ + url: 'know_ect.html', + id: 'know_ect.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if(keycode == '13') { + //e.preventDefault(); + //console.log(searchName) + + mui.openWindow({ + url: 'ac2.html', + id: 'ac2.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + +}) \ No newline at end of file diff --git a/static/app2/js/ect_recharge.js b/static/app2/js/ect_recharge.js new file mode 100755 index 0000000..b28c8bb --- /dev/null +++ b/static/app2/js/ect_recharge.js @@ -0,0 +1,119 @@ +var userId = ''; +var address = ''; + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui.ajax(hgUrl('app/Ectwallets/getEctAddress'), {  + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + userId = data.data.userId; + address = data.data.address; +// address = '0x29208ff5719cbd856c2e1ab32b2d3e101da6f721'; +// console.log(address) + if(address == null) { +// console.log(1) + mui.ajax('http://moacapi.juzi199.com/api/ect/recharge_token', {  + data:{ + userId:userId, + tokenName:'ect' + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + address = data.data.address; + $('#address').html(address); + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 118, //设置宽高 + height: 118 + }); + qrcode.makeCode(address); +// console.log(address) + + } else { + console.log(data.msg) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + } else { + $('#address').html(address); + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 118, //设置宽高 + height: 118 + }); + qrcode.makeCode(address); + } + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + alert(errorThrown);       + }   + });  + + + $('.con').on('tap','#copy_address',function(){ + copyShareUrl() + }) + $('.header').on('tap','.add',function(){ + mui.openWindow({ + url: 'ect_recharge_list.html', + id: 'ect_recharge_list.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + +}) + +function copyShareUrl() { + mui.plusReady(function() { + //复制链接到剪切板 + var copy_content = address; + //判断是安卓还是ios + if(mui.os.ios) { + //ios + var UIPasteboard = plus.ios.importClass("UIPasteboard");   + var generalPasteboard = UIPasteboard.generalPasteboard();   //设置/获取文本内容: +    + generalPasteboard.plusCallMethod({     + setValue: copy_content, +     forPasteboardType: "public.utf8-plain-text"   + });   + generalPasteboard.plusCallMethod({     + valueForPasteboardType: "public.utf8-plain-text"   + }); + } else { + //安卓 + var context = plus.android.importClass("android.content.Context");  + var main = plus.android.runtimeMainActivity();  + var clip = main.getSystemService(context.CLIPBOARD_SERVICE);  + plus.android.invoke(clip, "setText", copy_content); + } + plus.nativeUI.toast("复制到剪切板成功 "); + }); +} \ No newline at end of file diff --git a/static/app2/js/ect_recharge_list.js b/static/app2/js/ect_recharge_list.js new file mode 100755 index 0000000..5e1cb6f --- /dev/null +++ b/static/app2/js/ect_recharge_list.js @@ -0,0 +1,90 @@ +mui.plusReady(function() { + var isjiazai = 1; + var page = 1; + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + function getLocalTime(nS) { + return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' '); + } + + var token = localStorage.getItem('token'); + + // alert(token); + + function getDate(page) { + var num = page; + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(hgUrl('app/Ectwallets/getEctRechargeLog'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data.list.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多记录</p>'); + isjiazai = 0; + return; + } + $.each(data.data.list.Rows, function() { + var ectType; + var dataSrc; + if(this.status == 0){ + dataSrc = '待确认'; + }else if(this.status == 1) { + dataSrc = '已确认'; + } else if(this.status == 2) { + dataSrc = '已拒绝'; + } else{ + dataSrc = ''; + } + + + html += '<div class="row"><img src="../img/bg_pay_list.png"/><p class="p1">' + this.value + '</p><p class="p3">状态:' + dataSrc + '</p><p class="p4">' + getLocalTime(this.createTime) + '</p></div>' + + }); + + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1 + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + alert(errorThrown);       + }   + });  + } + + getDate(page); + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getDate(page); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_transfer_accounts.html.js b/static/app2/js/ect_transfer_accounts.html.js new file mode 100755 index 0000000..96303a8 --- /dev/null +++ b/static/app2/js/ect_transfer_accounts.html.js @@ -0,0 +1,138 @@ +mui.plusReady(function() { + + // function hyhUrl(url) { + // return 'http://192.168.1.101/hyh/' + url; + // } + var token = localStorage.getItem('token'); + + $('input').eq(0).attr('id','ectNum'); + $('input').eq(1).attr('id','payPwd'); + $('.num p').html(''); + $('input').eq(0).attr('placeholder','ect数量至少为500'); + // alert(token); + + mui.ajax(hyhUrl('app/Ectwallets/listQuery'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data != '') { + $.each(data.data, function() { + html += '<option value="' + this.eAddress + '">' + this.eAddress + '</option>' + }); + $('#select').html(html); + } + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui('body').on('tap', '.btn_ture', function() { + var eAddress = $('#select').val(); + var ectNum = $('#ectNum').val(); + var payPwd = $('#payPwd').val(); + if(eAddress == '') { + plus.nativeUI.toast('未选择钱包地址'); + return; + } + if(!(ectNum >= 500)) { + plus.nativeUI.toast('ect数量必须大于500'); + return; + } + if(payPwd == '') { + plus.nativeUI.toast('未填写支付密码'); + return; + } + $('.btn_ture').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/Ectwallets/withdraw'), {  + headers: {  + "HYH-Token": token + }, + data: { + eAddress: eAddress, + ectNum: ectNum, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data, 1); + if(data.status == 1) { +// console.log(data.data.id) + + var id =data.data.id; +// $('.btn_ture').removeAttr('disabled'); + mui.ajax('http://moacapi.heyuanhui.cn/api/ect/ect_transfer', {  + data: { + id:id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   +// console.log(data) + var data = toJson(data, 1); + if(data.status == 1) { + mui.fire(plus.webview.getWebviewById('templete/my.html'), 'refresh'); + mui.fire(plus.webview.getWebviewById('ect_index.html'), 'refresh'); + alert(data.msg); + location.reload(); + } else { + // console.log(data.status) + } + $('.btn_ture').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + + } else { + alert(data.msg); + location.reload(); + $('.btn_ture').removeAttr('disabled'); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   +// alert(errorThrown);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_transfer_accounts.js b/static/app2/js/ect_transfer_accounts.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/ect_withdraw.js b/static/app2/js/ect_withdraw.js new file mode 100755 index 0000000..cd735ac --- /dev/null +++ b/static/app2/js/ect_withdraw.js @@ -0,0 +1,90 @@ +mui.plusReady(function() { + var isjiazai = 1; + var page = 1; + +// function hyhUrl(url) { +// return 'http://192.168.1.101/hyh/' + url; +// } + + function getLocalTime(nS) { + return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' '); + } + + var token = localStorage.getItem('token'); + + // alert(token); + + function getDate(page) { + var num = page; + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(hgUrl('app/Ectwallets/getUserEctCashLog'), {  + headers: {  + "HYH-Token": token + }, + data: { + page: num + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data.list.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多记录</p>'); + isjiazai = 0; + return; + } + $.each(data.data.list.Rows, function() { + var ectType; + var dataSrc; + if(this.status == 0){ + dataSrc = '待审核'; + }else if(this.status == 1) { + dataSrc = '已发送'; + } else if(this.status == 2) { + dataSrc = '已拒绝'; + } else{ + dataSrc = ''; + } + + html += '<div class="row"><img src="../img/bg_pay_list.png"/><p class="p1">' + this.ectNum + '</p><p class="p2">' + this.toAccount + '</p><p class="p3">状态:' + dataSrc + '</p><p class="p4">' + getLocalTime(this.createTime) + '</p></div>' + + }); + + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1 + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   +// alert(errorThrown);       + }   + });  + } + + getDate(page); + console.log(1) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getDate(page); + } + + } + }) + +}) \ No newline at end of file diff --git a/static/app2/js/ect_withdraw_deposit.js b/static/app2/js/ect_withdraw_deposit.js new file mode 100755 index 0000000..1d9ea35 --- /dev/null +++ b/static/app2/js/ect_withdraw_deposit.js @@ -0,0 +1,136 @@ +mui.plusReady(function() { + + // function hyhUrl(url) { + // return 'http://192.168.1.101/hyh/' + url; + // } + var token = localStorage.getItem('token'); + + // alert(token); + + mui.ajax(hyhUrl('app/Ectwallets/listQuery'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + if(data.data != '') { + $.each(data.data, function() { + html += '<option value="' + this.eAddress + '">' + this.eAddress + '</option>' + }); + $('#select').html(html); + }else{ + plus.nativeUI.toast('未设置钱包地址'); + } + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui.ajax(hyhUrl('app/Ectwallets/index'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + $('.num p').html(data.data.ectNum); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + mui('body').on('tap', '.btn_ture', function() { + var eAddress = $('#select').val(); + var ectNum = $('#ectNum').val(); + var payPwd = $('#payPwd').val(); + if(eAddress == '') { + plus.nativeUI.toast('未选择钱包地址'); + return; + } + if(!(ectNum >= 500)) { + plus.nativeUI.toast('ect数量必须大于500'); + return; + } + if(payPwd == '') { + plus.nativeUI.toast('未填写支付密码'); + return; + } + $('.btn_ture').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/Ectwallets/withdraw'), {  + headers: {  + "HYH-Token": token + }, + data: { + eAddress: eAddress, + ectNum: ectNum, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data, 1); + if(data.status == 1) { + // console.log(data.data.id) + + var id = data.data.id; + // $('.btn_ture').removeAttr('disabled'); + mui.ajax('http://moacapi.heyuanhui.cn/api/ect/ect_transfer', {  + data: { + id: id + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + var data = toJson(data, 1); + if(data.status == 1) { + + alert(data.msg); + mui.fire(plus.webview.getWebviewById('templete/my.html'), 'refresh'); + mui.fire(plus.webview.getWebviewById('ect_index.html'), 'refresh'); + location.reload(); + } else { + // console.log(data.status) + } + $('.btn_ture').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + } else { + alert(data.msg); + location.reload(); + $('.btn_ture').removeAttr('disabled'); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app2/js/editAddress.js b/static/app2/js/editAddress.js new file mode 100755 index 0000000..f60150c --- /dev/null +++ b/static/app2/js/editAddress.js @@ -0,0 +1,299 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var addressId = self.data_addressId ? self.data_addressId : 0; + var isParentId = 1; + var isProvince; + var isCity; + var userName = $('#userName'); + var userPhone = $('#userPhone'); + var province = $('#province'); + var city = $('#city'); + var Area = $('#area'); + var Textarea = $('textarea'); + var areaVal; + if (addressId != 0) { + $('.address_info').css('display', 'none'); + $('.add_info').css('display', 'block'); + mui.ajax(qlgUrl('app/useraddress/getById'), { + data: { + addressId: addressId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { + //console.log(data);//服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + //console.log(data); + userName.val(data.userName) + userPhone.val(data.userPhone) + $('.add_info').html(data.areaName) + Textarea.val(data.userAddress) + areaVal = data.areaId + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg) + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + mui.ajax(qlgUrl('app/areas/listQuery'), { + data: { + parentId: 0 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">选择省</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#province').html(html); + + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg) + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + $('.scroll_out_t').on('tap', '#province', function() { + if (isParentId == 1) { + isParentId = 0; + mui.ajax(qlgUrl('app/areas/listQuery'), { + data: { + parentId: 0 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = ''; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#province').html(html); + var province = data[0].areaId; + mui.ajax(hyhUrl('app/areas/listQuery'), { + data: { + parentId: province + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = ''; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#city').html(html); + var city = data[0].areaId; + mui.ajax(hyhUrl('app/areas/listQuery'), { + data: { + parentId: city + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = ''; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#area').html(html); + isCity = city; + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + isProvince = province; + } else { + mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg) + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + + }) + $('.scroll_out_t').on('change', '#province', function() { + var province = $(this).val() + //console.log(province) + if (isProvince != province) { + mui.ajax(qlgUrl('app/areas/listQuery'), { + data: { + parentId: province + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">选择市</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#city').html(html); + // var city = data[0].areaId; + // mui.ajax(hyhUrl('app/areas/listQuery'), { + // data: { + // parentId: city + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // data = toJson(data); + // if(data.status == 1) { + // data = data.data; + var html = '<option value="">选择区</option>'; + // $.each(data, function() { + // html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + // }); + $('#area').html(html); + // isCity = city; + // } else { + // mui.alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + isProvince = province; + } else { + // mui.alert('发生错误请刷新后重试!'); + mui.alert(data.msg) + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + }) + $('.scroll_out_t').on('change', '#city', function() { + var city = $(this).val() + if (isCity != city) { + mui.ajax(qlgUrl('app/areas/listQuery'), { + data: { + parentId: city, + level: 2 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = '<option value="">选择区</option>'; + $.each(data, function() { + html += '<option value="' + this.areaId + '">' + this.areaName + '</option>' + }); + $('#area').html(html); + isCity = city; + } else { + mui.alert(data.msg) + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + }) + + $('.bc_btn').on('tap', function() { + var isDefault = $('input:radio[name="isDefault"]:checked').val() ? $('input:radio[name="isDefault"]:checked').val() : + 0; + areaVal = $('#area').val() ? $('#area').val() : areaVal; + var data = { + isDefault: isDefault, + addressId: addressId, + userName: $('#userName').val(), + areaId: areaVal, + userPhone: $('#userPhone').val(), + userAddress: $('textarea').val(), + } + mui.ajax(hyhUrl('app/useraddress/edits'), { + data: data, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + mui.back(); + } else { + mui.alert(data.msg) + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + $('.add_info').on('tap', function() { + $('.address_info').css('display', 'block'); + $('.add_info').css('display', 'none'); + }) + +}) diff --git a/static/app2/js/essay.js b/static/app2/js/essay.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/essaylist.js b/static/app2/js/essaylist.js new file mode 100755 index 0000000..4b2fb77 --- /dev/null +++ b/static/app2/js/essaylist.js @@ -0,0 +1,9 @@ +mui.plusReady(function () { + // var url ="", + $("body").on("tap" ,".add1",function () { + JZL.openWindow('addessay.html', 'addessay.html') + }) + $(".row_con").on("tap" ,".memorandum",function () { + JZL.openWindow('memorandumlist.html', 'memorandumlist.html') + }) +}) \ No newline at end of file diff --git a/static/app2/js/exif.js b/static/app2/js/exif.js new file mode 100755 index 0000000..77d1875 --- /dev/null +++ b/static/app2/js/exif.js @@ -0,0 +1,640 @@ +/* + * Javascript EXIF Reader 0.1.6 + * Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/ + * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt] + */ + + +var EXIF = (function() { + + var debug = false; + + var ExifTags = { + + // version tags + 0x9000: "ExifVersion", // EXIF version + 0xA000: "FlashpixVersion", // Flashpix format version + + // colorspace tags + 0xA001: "ColorSpace", // Color space information tag + + // image configuration + 0xA002: "PixelXDimension", // Valid width of meaningful image + 0xA003: "PixelYDimension", // Valid height of meaningful image + 0x9101: "ComponentsConfiguration", // Information about channels + 0x9102: "CompressedBitsPerPixel", // Compressed bits per pixel + + // user information + 0x927C: "MakerNote", // Any desired information written by the manufacturer + 0x9286: "UserComment", // Comments by user + + // related file + 0xA004: "RelatedSoundFile", // Name of related sound file + + // date and time + 0x9003: "DateTimeOriginal", // Date and time when the original image was generated + 0x9004: "DateTimeDigitized", // Date and time when the image was stored digitally + 0x9290: "SubsecTime", // Fractions of seconds for DateTime + 0x9291: "SubsecTimeOriginal", // Fractions of seconds for DateTimeOriginal + 0x9292: "SubsecTimeDigitized", // Fractions of seconds for DateTimeDigitized + + // picture-taking conditions + 0x829A: "ExposureTime", // Exposure time (in seconds) + 0x829D: "FNumber", // F number + 0x8822: "ExposureProgram", // Exposure program + 0x8824: "SpectralSensitivity", // Spectral sensitivity + 0x8827: "ISOSpeedRatings", // ISO speed rating + 0x8828: "OECF", // Optoelectric conversion factor + 0x9201: "ShutterSpeedValue", // Shutter speed + 0x9202: "ApertureValue", // Lens aperture + 0x9203: "BrightnessValue", // Value of brightness + 0x9204: "ExposureBias", // Exposure bias + 0x9205: "MaxApertureValue", // Smallest F number of lens + 0x9206: "SubjectDistance", // Distance to subject in meters + 0x9207: "MeteringMode", // Metering mode + 0x9208: "LightSource", // Kind of light source + 0x9209: "Flash", // Flash status + 0x9214: "SubjectArea", // Location and area of main subject + 0x920A: "FocalLength", // Focal length of the lens in mm + 0xA20B: "FlashEnergy", // Strobe energy in BCPS + 0xA20C: "SpatialFrequencyResponse", // + 0xA20E: "FocalPlaneXResolution", // Number of pixels in width direction per FocalPlaneResolutionUnit + 0xA20F: "FocalPlaneYResolution", // Number of pixels in height direction per FocalPlaneResolutionUnit + 0xA210: "FocalPlaneResolutionUnit", // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution + 0xA214: "SubjectLocation", // Location of subject in image + 0xA215: "ExposureIndex", // Exposure index selected on camera + 0xA217: "SensingMethod", // Image sensor type + 0xA300: "FileSource", // Image source (3 == DSC) + 0xA301: "SceneType", // Scene type (1 == directly photographed) + 0xA302: "CFAPattern", // Color filter array geometric pattern + 0xA401: "CustomRendered", // Special processing + 0xA402: "ExposureMode", // Exposure mode + 0xA403: "WhiteBalance", // 1 = auto white balance, 2 = manual + 0xA404: "DigitalZoomRation", // Digital zoom ratio + 0xA405: "FocalLengthIn35mmFilm", // Equivalent foacl length assuming 35mm film camera (in mm) + 0xA406: "SceneCaptureType", // Type of scene + 0xA407: "GainControl", // Degree of overall image gain adjustment + 0xA408: "Contrast", // Direction of contrast processing applied by camera + 0xA409: "Saturation", // Direction of saturation processing applied by camera + 0xA40A: "Sharpness", // Direction of sharpness processing applied by camera + 0xA40B: "DeviceSettingDescription", // + 0xA40C: "SubjectDistanceRange", // Distance to subject + + // other tags + 0xA005: "InteroperabilityIFDPointer", + 0xA420: "ImageUniqueID" // Identifier assigned uniquely to each image + }; + + var TiffTags = { + 0x0100: "ImageWidth", + 0x0101: "ImageHeight", + 0x8769: "ExifIFDPointer", + 0x8825: "GPSInfoIFDPointer", + 0xA005: "InteroperabilityIFDPointer", + 0x0102: "BitsPerSample", + 0x0103: "Compression", + 0x0106: "PhotometricInterpretation", + 0x0112: "Orientation", + 0x0115: "SamplesPerPixel", + 0x011C: "PlanarConfiguration", + 0x0212: "YCbCrSubSampling", + 0x0213: "YCbCrPositioning", + 0x011A: "XResolution", + 0x011B: "YResolution", + 0x0128: "ResolutionUnit", + 0x0111: "StripOffsets", + 0x0116: "RowsPerStrip", + 0x0117: "StripByteCounts", + 0x0201: "JPEGInterchangeFormat", + 0x0202: "JPEGInterchangeFormatLength", + 0x012D: "TransferFunction", + 0x013E: "WhitePoint", + 0x013F: "PrimaryChromaticities", + 0x0211: "YCbCrCoefficients", + 0x0214: "ReferenceBlackWhite", + 0x0132: "DateTime", + 0x010E: "ImageDescription", + 0x010F: "Make", + 0x0110: "Model", + 0x0131: "Software", + 0x013B: "Artist", + 0x8298: "Copyright" + }; + + var GPSTags = { + 0x0000: "GPSVersionID", + 0x0001: "GPSLatitudeRef", + 0x0002: "GPSLatitude", + 0x0003: "GPSLongitudeRef", + 0x0004: "GPSLongitude", + 0x0005: "GPSAltitudeRef", + 0x0006: "GPSAltitude", + 0x0007: "GPSTimeStamp", + 0x0008: "GPSSatellites", + 0x0009: "GPSStatus", + 0x000A: "GPSMeasureMode", + 0x000B: "GPSDOP", + 0x000C: "GPSSpeedRef", + 0x000D: "GPSSpeed", + 0x000E: "GPSTrackRef", + 0x000F: "GPSTrack", + 0x0010: "GPSImgDirectionRef", + 0x0011: "GPSImgDirection", + 0x0012: "GPSMapDatum", + 0x0013: "GPSDestLatitudeRef", + 0x0014: "GPSDestLatitude", + 0x0015: "GPSDestLongitudeRef", + 0x0016: "GPSDestLongitude", + 0x0017: "GPSDestBearingRef", + 0x0018: "GPSDestBearing", + 0x0019: "GPSDestDistanceRef", + 0x001A: "GPSDestDistance", + 0x001B: "GPSProcessingMethod", + 0x001C: "GPSAreaInformation", + 0x001D: "GPSDateStamp", + 0x001E: "GPSDifferential" + }; + + var StringValues = { + ExposureProgram: { + 0: "Not defined", + 1: "Manual", + 2: "Normal program", + 3: "Aperture priority", + 4: "Shutter priority", + 5: "Creative program", + 6: "Action program", + 7: "Portrait mode", + 8: "Landscape mode" + }, + MeteringMode: { + 0: "Unknown", + 1: "Average", + 2: "CenterWeightedAverage", + 3: "Spot", + 4: "MultiSpot", + 5: "Pattern", + 6: "Partial", + 255: "Other" + }, + LightSource: { + 0: "Unknown", + 1: "Daylight", + 2: "Fluorescent", + 3: "Tungsten (incandescent light)", + 4: "Flash", + 9: "Fine weather", + 10: "Cloudy weather", + 11: "Shade", + 12: "Daylight fluorescent (D 5700 - 7100K)", + 13: "Day white fluorescent (N 4600 - 5400K)", + 14: "Cool white fluorescent (W 3900 - 4500K)", + 15: "White fluorescent (WW 3200 - 3700K)", + 17: "Standard light A", + 18: "Standard light B", + 19: "Standard light C", + 20: "D55", + 21: "D65", + 22: "D75", + 23: "D50", + 24: "ISO studio tungsten", + 255: "Other" + }, + Flash: { + 0x0000: "Flash did not fire", + 0x0001: "Flash fired", + 0x0005: "Strobe return light not detected", + 0x0007: "Strobe return light detected", + 0x0009: "Flash fired, compulsory flash mode", + 0x000D: "Flash fired, compulsory flash mode, return light not detected", + 0x000F: "Flash fired, compulsory flash mode, return light detected", + 0x0010: "Flash did not fire, compulsory flash mode", + 0x0018: "Flash did not fire, auto mode", + 0x0019: "Flash fired, auto mode", + 0x001D: "Flash fired, auto mode, return light not detected", + 0x001F: "Flash fired, auto mode, return light detected", + 0x0020: "No flash function", + 0x0041: "Flash fired, red-eye reduction mode", + 0x0045: "Flash fired, red-eye reduction mode, return light not detected", + 0x0047: "Flash fired, red-eye reduction mode, return light detected", + 0x0049: "Flash fired, compulsory flash mode, red-eye reduction mode", + 0x004D: "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected", + 0x004F: "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected", + 0x0059: "Flash fired, auto mode, red-eye reduction mode", + 0x005D: "Flash fired, auto mode, return light not detected, red-eye reduction mode", + 0x005F: "Flash fired, auto mode, return light detected, red-eye reduction mode" + }, + SensingMethod: { + 1: "Not defined", + 2: "One-chip color area sensor", + 3: "Two-chip color area sensor", + 4: "Three-chip color area sensor", + 5: "Color sequential area sensor", + 7: "Trilinear sensor", + 8: "Color sequential linear sensor" + }, + SceneCaptureType: { + 0: "Standard", + 1: "Landscape", + 2: "Portrait", + 3: "Night scene" + }, + SceneType: { + 1: "Directly photographed" + }, + CustomRendered: { + 0: "Normal process", + 1: "Custom process" + }, + WhiteBalance: { + 0: "Auto white balance", + 1: "Manual white balance" + }, + GainControl: { + 0: "None", + 1: "Low gain up", + 2: "High gain up", + 3: "Low gain down", + 4: "High gain down" + }, + Contrast: { + 0: "Normal", + 1: "Soft", + 2: "Hard" + }, + Saturation: { + 0: "Normal", + 1: "Low saturation", + 2: "High saturation" + }, + Sharpness: { + 0: "Normal", + 1: "Soft", + 2: "Hard" + }, + SubjectDistanceRange: { + 0: "Unknown", + 1: "Macro", + 2: "Close view", + 3: "Distant view" + }, + FileSource: { + 3: "DSC" + }, + Components: { + 0: "", + 1: "Y", + 2: "Cb", + 3: "Cr", + 4: "R", + 5: "G", + 6: "B" + } + }; + + function addEvent(element, event, handler) { + if (element.addEventListener) { + element.addEventListener(event, handler, false); + } else if (element.attachEvent) { + element.attachEvent("on" + event, handler); + } + } + + function imageHasData(img) { + return !!(img.exifdata); + } + + function getImageData(img, callback) { + BinaryAjax(img.src, function(http) { + var data = findEXIFinJPEG(http.binaryResponse); + img.exifdata = data || {}; + if (callback) { + callback.call(img) + } + }); + } + + function findEXIFinJPEG(file) { + if (file.getByteAt(0) != 0xFF || file.getByteAt(1) != 0xD8) { + return false; // not a valid jpeg + } + + var offset = 2, + length = file.getLength(), + marker; + + while (offset < length) { + if (file.getByteAt(offset) != 0xFF) { + if (debug) + console.log("Not a valid marker at offset " + offset + ", found: " + file.getByteAt(offset)); + return false; // not a valid marker, something is wrong + } + + marker = file.getByteAt(offset + 1); + + // we could implement handling for other markers here, + // but we're only looking for 0xFFE1 for EXIF data + + if (marker == 22400) { + if (debug) + console.log("Found 0xFFE1 marker"); + + return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2); + + // offset += 2 + file.getShortAt(offset+2, true); + + } else if (marker == 225) { + // 0xE1 = Application-specific 1 (for EXIF) + if (debug) + console.log("Found 0xFFE1 marker"); + + return readEXIFData(file, offset + 4, file.getShortAt(offset + 2, true) - 2); + + } else { + offset += 2 + file.getShortAt(offset + 2, true); + } + + } + + } + + + function readTags(file, tiffStart, dirStart, strings, bigEnd) { + var entries = file.getShortAt(dirStart, bigEnd), + tags = {}, + entryOffset, tag, + i; + + for (i = 0; i < entries; i++) { + entryOffset = dirStart + i * 12 + 2; + tag = strings[file.getShortAt(entryOffset, bigEnd)]; + if (!tag && debug) + console.log("Unknown tag: " + file.getShortAt(entryOffset, bigEnd)); + tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd); + } + return tags; + } + + + function readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd) { + var type = file.getShortAt(entryOffset + 2, bigEnd), + numValues = file.getLongAt(entryOffset + 4, bigEnd), + valueOffset = file.getLongAt(entryOffset + 8, bigEnd) + tiffStart, + offset, + vals, val, n, + numerator, denominator; + + switch (type) { + case 1: // byte, 8-bit unsigned int + case 7: // undefined, 8-bit byte, value depending on field + if (numValues == 1) { + return file.getByteAt(entryOffset + 8, bigEnd); + } else { + offset = numValues > 4 ? valueOffset : (entryOffset + 8); + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getByteAt(offset + n); + } + return vals; + } + + case 2: // ascii, 8-bit byte + offset = numValues > 4 ? valueOffset : (entryOffset + 8); + return file.getStringAt(offset, numValues - 1); + + case 3: // short, 16 bit int + if (numValues == 1) { + return file.getShortAt(entryOffset + 8, bigEnd); + } else { + offset = numValues > 2 ? valueOffset : (entryOffset + 8); + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getShortAt(offset + 2 * n, bigEnd); + } + return vals; + } + + case 4: // long, 32 bit int + if (numValues == 1) { + return file.getLongAt(entryOffset + 8, bigEnd); + } else { + vals = []; + for (var n = 0; n < numValues; n++) { + vals[n] = file.getLongAt(valueOffset + 4 * n, bigEnd); + } + return vals; + } + + case 5: // rational = two long values, first is numerator, second is denominator + if (numValues == 1) { + numerator = file.getLongAt(valueOffset, bigEnd); + denominator = file.getLongAt(valueOffset + 4, bigEnd); + val = new Number(numerator / denominator); + val.numerator = numerator; + val.denominator = denominator; + return val; + } else { + vals = []; + for (n = 0; n < numValues; n++) { + numerator = file.getLongAt(valueOffset + 8 * n, bigEnd); + denominator = file.getLongAt(valueOffset + 4 + 8 * n, bigEnd); + vals[n] = new Number(numerator / denominator); + vals[n].numerator = numerator; + vals[n].denominator = denominator; + } + return vals; + } + + case 9: // slong, 32 bit signed int + if (numValues == 1) { + return file.getSLongAt(entryOffset + 8, bigEnd); + } else { + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getSLongAt(valueOffset + 4 * n, bigEnd); + } + return vals; + } + + case 10: // signed rational, two slongs, first is numerator, second is denominator + if (numValues == 1) { + return file.getSLongAt(valueOffset, bigEnd) / file.getSLongAt(valueOffset + 4, bigEnd); + } else { + vals = []; + for (n = 0; n < numValues; n++) { + vals[n] = file.getSLongAt(valueOffset + 8 * n, bigEnd) / file.getSLongAt(valueOffset + 4 + 8 * n, bigEnd); + } + return vals; + } + } + } + + + function readEXIFData(file, start) { + if (file.getStringAt(start, 4) != "Exif") { + if (debug) + console.log("Not valid EXIF data! " + file.getStringAt(start, 4)); + return false; + } + + var bigEnd, + tags, tag, + exifData, gpsData, + tiffOffset = start + 6; + + // test for TIFF validity and endianness + if (file.getShortAt(tiffOffset) == 0x4949) { + bigEnd = false; + } else if (file.getShortAt(tiffOffset) == 0x4D4D) { + bigEnd = true; + } else { + if (debug) + console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"); + return false; + } + + if (file.getShortAt(tiffOffset + 2, bigEnd) != 0x002A) { + if (debug) + console.log("Not valid TIFF data! (no 0x002A)"); + return false; + } + + if (file.getLongAt(tiffOffset + 4, bigEnd) != 0x00000008) { + if (debug) + console.log("Not valid TIFF data! (First offset not 8)", file.getShortAt(tiffOffset + 4, bigEnd)); + return false; + } + + tags = readTags(file, tiffOffset, tiffOffset + 8, TiffTags, bigEnd); + + if (tags.ExifIFDPointer) { + exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd); + for (tag in exifData) { + switch (tag) { + case "LightSource" : + case "Flash" : + case "MeteringMode" : + case "ExposureProgram" : + case "SensingMethod" : + case "SceneCaptureType" : + case "SceneType" : + case "CustomRendered" : + case "WhiteBalance" : + case "GainControl" : + case "Contrast" : + case "Saturation" : + case "Sharpness" : + case "SubjectDistanceRange" : + case "FileSource" : + exifData[tag] = StringValues[tag][exifData[tag]]; + break; + + case "ExifVersion" : + case "FlashpixVersion" : + exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3]); + break; + + case "ComponentsConfiguration" : + exifData[tag] = + StringValues.Components[exifData[tag][0]] + + StringValues.Components[exifData[tag][1]] + + StringValues.Components[exifData[tag][2]] + + StringValues.Components[exifData[tag][3]]; + break; + } + tags[tag] = exifData[tag]; + } + } + + if (tags.GPSInfoIFDPointer) { + gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd); + for (tag in gpsData) { + switch (tag) { + case "GPSVersionID" : + gpsData[tag] = gpsData[tag][0] + + "." + gpsData[tag][1] + + "." + gpsData[tag][2] + + "." + gpsData[tag][3]; + break; + } + tags[tag] = gpsData[tag]; + } + } + + return tags; + } + + + function getData(img, callback) { + if (!img.complete) + return false; + if (!imageHasData(img)) { + getImageData(img, callback); + } else { + if (callback) { + callback.call(img); + } + } + return true; + } + + function getTag(img, tag) { + if (!imageHasData(img)) + return; + return img.exifdata[tag]; + } + + function getAllTags(img) { + if (!imageHasData(img)) + return {}; + var a, + data = img.exifdata, + tags = {}; + for (a in data) { + if (data.hasOwnProperty(a)) { + tags[a] = data[a]; + } + } + return tags; + } + + function pretty(img) { + if (!imageHasData(img)) + return ""; + var a, + data = img.exifdata, + strPretty = ""; + for (a in data) { + if (data.hasOwnProperty(a)) { + if (typeof data[a] == "object") { + if (data[a] instanceof Number) { + strPretty += a + " : " + data[a] + " [" + data[a].numerator + "/" + data[a].denominator + "]\r\n"; + } else { + strPretty += a + " : [" + data[a].length + " values]\r\n"; + } + } else { + strPretty += a + " : " + data[a] + "\r\n"; + } + } + } + return strPretty; + } + + function readFromBinaryFile(file) { + return findEXIFinJPEG(file); + } + + + return { + readFromBinaryFile: readFromBinaryFile, + pretty: pretty, + getTag: getTag, + getAllTags: getAllTags, + getData: getData, + Tags: ExifTags, + TiffTags: TiffTags, + GPSTags: GPSTags, + StringValues: StringValues + }; + +})(); \ No newline at end of file diff --git a/static/app2/js/family.js b/static/app2/js/family.js new file mode 100755 index 0000000..ec74f50 --- /dev/null +++ b/static/app2/js/family.js @@ -0,0 +1,185 @@ +$('.t_con').css('display', 'none'); + var html_li='<p class="title"></p>'; + $('.header_con').append(html_li); + $('.header_con .title').css('display','none'); + + +var topTypeId = ''; +var isBrand = 0; +var secTypeId = ''; +var pageSize = 10; +var page = 1; +var lxy_num = 0; +var header_class = ''; +var nav_class = ''; +var lxy_top = ''; +var isjiazai = 1; + +function lxy_(topTypeId, secTypeId, page, pageSize) { + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + var lxy_data_ = { + topTypeId: topTypeId ? topTypeId : '', + secTypeId: secTypeId ? secTypeId : '', + isBrand:isBrand, + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-actGoodsList'), {  + + data: lxy_data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + // var data = toJson(data); + var data = data.data + var html = ''; + if(data.Rows == '') { + + if(page==1){ + $('#recommend_con').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;margin-top:20px;">没有更多商品</p>'); + }else{ + $('#recommend_con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;margin-top:20px;">没有更多商品</p>'); + } + + isjiazai = 0; + return; + } + + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" src="../img/icon_sscl.png"alt=""style="display:none;"/></div>' + }); + + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  +} + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var adUrl = self.adURLId; + if(adUrl.indexOf('brandId') >= 0){ + isBrand = 1; + } + topTypeId = self.adURLId.split('=')[1]; +// console.log(topTypeId) + if(topTypeId == '45' && isBrand == 0) { + lxy_num = 0; + } else if(topTypeId == '46' && isBrand == 0) { + lxy_num = 1; + } else if(topTypeId == '47' && isBrand == 0) { + lxy_num = 2; + } else if(topTypeId == '48' && isBrand == 0) { + lxy_num = 3; + } else if(topTypeId == '49' && isBrand == 0) { + lxy_num = 4; + } else if(topTypeId == '50' && isBrand == 0) { + lxy_num = 5; + } else { + lxy_num = null; + } + + if(lxy_num == null) { + $('.header_con .title').css('display','block'); + $('.mui-action-back').css('color','black'); + } else { + header_class = 'header' + lxy_num; + nav_class = 'lxy' + lxy_num; + lxy_top = 'top' + lxy_num; + $('.header').addClass(header_class); + var html_lxy = '<img src="'+ hyhImgUrl('static/app2/img/family_log_' + topTypeId + '.png') +'" class="oc_logo" />'; + $('.header_con').append(html_lxy); + $('#timer_swiper .nav').addClass(nav_class); + $('.top').addClass(lxy_top); + } + + mui.ajax(kxUrl('addon/hyhlimitactive-Hyhlimitactive-actList'), {  + + data: { + topTypeId: topTypeId, + isBrand:isBrand + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + // var data = toJson(data); + if(data.status == 1) { +// console.log(isBrand+JSON.stringify(data) ); + var data = data.data + var html = ''; + var len = 0; + $.each(data.lists, function(num) { + html += '<div class="swiper-slide nav_block" data-secTypeId="' + this.secTypeId + '"><p class="p1">' + this.secTypeName + '</p></div>'; + len = num + 1; + }); + $('.nav').html(html); + $('.header_con .title').html(data.title); + $('.nav_block').eq(0).addClass('on'); + + if(len == 0) { + // mui.back(); + } else if(len == 1) { + + } else { + $('.t_con').css('display', 'block'); + } + if(len > 5) { + len = 4.5 + } else { + len = len; + } + var swiper = new Swiper('#timer_swiper', { + slidesPerView: len, + paginationClickable: true, + spaceBetween: 0, + freeMode: true + }); + secTypeId = $('.nav_block').eq(0).attr('data-secTypeId'); + lxy_(topTypeId, secTypeId, 1, 10); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  + + mui('.nav').on('tap', '.nav_block', function() { + secTypeId = $(this).attr('data-secTypeId'); + isjiazai = 1; + page = 1; + lxy_(topTypeId, secTypeId, page, 10); + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + lxy_(topTypeId, secTypeId, page, pageSize); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/friends.js b/static/app2/js/friends.js new file mode 100755 index 0000000..3a7b168 --- /dev/null +++ b/static/app2/js/friends.js @@ -0,0 +1,53 @@ +mui.plusReady(function() { + var level = ''; + JZL.ajax(qlgUrl('app/users/myFriend'), {}, function(data) { + //console.log(data); + if (1 == data.status) { + var data = data.data; + var html = '', + html1 = ''; + + html1 = '<p class="">' + data.pInfo.trueName + '<span class="orange">' + data.pInfo.userStatus + + '</span></p><span class="shop_info">' + data.pInfo.userLevel + '</span><span class="shop_info">' + data.pInfo.userPhone + + '</span>'; + html = + '<div class="row shadown_wai" data-level="-1"><label for="">我推荐</label><label for=""><span class="lock"></>' + + data.lockUserCount + + '</span><span class="lock">(禁用)</span></label></div><div class="row shadown_wai" data-level="0"><label for="">购户</label><label for="">' + + data.userCount + + '</label></div><div class="row shadown_wai" data-level="1"><label for="">商户</label><label for="">' + data.shopCount + + '</label></div><div class="row shadown_wai" data-level="2"><label for="">商超</label><label for="">' + data.storeCount + + '</label></div><div class="row shadown_wai" data-level="3"><label for="">商厦</label><label for="">' + data.mallCount + + '</label></div><div class="row shadown_wai" data-level="4"><label for="">商都</label><label for="">' + data.marketCount + + '</label></div>'; + // html1=data.user.loginName+" "+data.user.userId + $('.fri-con').html(html) + $('.shop_info').html(html1) + $('.userInfo').text(data.user.loginName) + //二维码生成 + // var content='' + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 100, //设置宽高 + height: 100 + }); + //console.log(data.share_url); + //$('body').append('<div id="qrcode" class="qrcode_img" style="display:none;"></div>'); + qrcode.makeCode(data.share_url); + // //console.log('http://t.ect99.com/mobile/users/reg?pName='+ data.user.loginName); + $('#qrcode').show(); + }else{ + mui.alert(data.msg) + } + }) + + $('body').on("tap", '.row', function() { + // alert(1) + level = $(this).attr('data-level'); + JZL.openWindow('friendsList.html', 'friendsList.html', { + 'level': level + }) + }) + + + +}) diff --git a/static/app2/js/friendsList.js b/static/app2/js/friendsList.js new file mode 100755 index 0000000..2c16bd5 --- /dev/null +++ b/static/app2/js/friendsList.js @@ -0,0 +1,86 @@ +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var userLevel = self.level + // mui.alert(userLevel) + var page = 1; + var pagesize = 10; + var isjiazai = 1; + getRecommend(page, pagesize) + + function getRecommend(page, pagesize) { + var recommenddata = { + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + recommenddata.userLevel = userLevel; + if (-1 == userLevel) { + recommenddata.isLock = 1; + } else { + recommenddata.isLock = 0; + + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/users/myFriendList'), recommenddata, function(data) { + //console.log(data); + if (1 == data.status) { + var data = data.data; + var html = ''; + if (data.Rows == '') { + $('.fri-con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; padding-top:9px;">没有更多朋友</p>'); + isjiazai = 0; + return; + } + mui.each(data.Rows, function() { + if (!this.lockReason || '' == this.lockReason) { + html += '<div class="lock_row shadown_wai"><label for="">姓名</label><span for="">' + this.trueName + + '</span><label for="">手机号</label><span for="" >' + this.userPhone + '</span></div>' + } else { + html += '<div class="list_row shadown_wai"><label for="">姓名</label><span for="">' + this.trueName + + '</span><label for="">手机号</label><span for="">' + this.userPhone + + '</span><label for="">锁定原因</label><span for="">' + this.lockReason + + '</span><label for="">锁定时间</label><span for="">8' + this.lockTime + + '小时</span><label for="">开始时间</label><span for="">' + this.createTime + '</span></div>' + + } + + }) + + if (page == 1) { + $('.fri-con').html(html); + } else { + $('.fri-con').append(html); + } + isjiazai = 1; + } else { + mui.alert(data.msg) + } + }) + } + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // 判断默认行为是否可以被禁用 + if (e.cancelable) { + // 判断默认行为是否已经被禁用 + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pagesize); + } + } + if (scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + }, false) +}) diff --git a/static/app2/js/god_ect.js b/static/app2/js/god_ect.js new file mode 100755 index 0000000..ee0112c --- /dev/null +++ b/static/app2/js/god_ect.js @@ -0,0 +1,135 @@ +$('.god_rech').on('tap', function() { + $('.rech_block').css('display', 'none'); + $('.rech_none').css('display', 'block'); + + setTimeout(function() { + $('.rech_block').css('display', 'block'); + $('.rech_none').css('display', 'none'); + }, 500) +}) + +mui.plusReady(function() { + //返回用户有多少ect + mui.ajax(kxUrl('app/ect/userECT'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + //var data = toJson(data); + if(data.status == 1) { + var lxy_god = $('.god_ect_num'); + var data = data.data; + lxy_god.html(data.ectNum); + } + }, + + error: function(xhr, type, errorThrown) { //异常处理;   + //alert(type);     + }   + });  + + // ect实时价格,和购买神券需要多少ect + mui.ajax(kxUrl('app/ect/getEctNum'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + //var data = toJson(data); + if(data.status == 1) { + var data = data.data; + $('.p2_span').html(data.now_rmb); + $('.p3_span').html(data.ect_num); + console.log('data.now_rmb') + + } + }, + + error: function(xhr, type, errorThrown) { //异常处理;   + //alert(type);     + }   + });  + + mui('.con').on('tap', '.god_shopping', function() { //立即购买 + $('#god_zhezhao').css('display', 'block'); + $('.god_ect_money').css('display', 'block'); + $('.shopping_block').css('display', 'none'); + $('.shopping_none').css('display', 'block'); + }); + + mui('.god_ect_money').on('tap', '.money_btn', function() { //购买神劵 + var that = $(this); + that.attr('disabled', 'disabled'); + mui.ajax(kxUrl('app/ect/payElevenEct'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + var data = toJson(data); + console.log(data.status); + if(data.status == 1) { + //购买成功 + $('.shopping_success').css('display', 'block'); + $('.god_ect_money').css('display', 'none'); + } else if(data.status == -1) { + //购买失败 + console.log(111) + $('.shopping_success').css('display', 'none'); + $('.shopping_lose img').attr('src', ectImgUrl('static/app2/img/error-1.png')); + $('.shopping_lose').css('display', 'block'); + $('.shopping_lose img').css('display', 'block'); + $('.god_ect_money').css('display', 'none'); + + } else if(data.status == -2) { + //余额不足 + console.log(444) + $('.shopping_lose').css('display', 'block'); + $('.shopping_lose img').css('display', 'block'); + $('.god_ect_money').css('display', 'none'); + $('.shopping_success').css('display', 'none'); + } else { + //不要重复购买 + console.log(2222) + $('.shopping_lose img').attr('src', ectImgUrl('static/app2/img/error-3.png')); + $('.shopping_lose').css('display', 'block'); + $('.shopping_lose img').css('display', 'block'); + $('.shopping_success').css('display', 'none'); + $('.god_ect_money').css('display', 'none'); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理;   + console.log(errorThrown);     + }   + }); + }) + + mui('body').on('tap', '#god_zhezhao', function() { + $('#god_zhezhao').css('display', 'none'); + $('.shopping_block').css('display', 'block'); + $('.shopping_none').css('display', 'none'); + }) + mui('body').on('tap', '.rech_block', function() { + mui.openWindow({ + url: 'ect_recharge.html', + id: 'ect_recharge.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/goodsList.js b/static/app2/js/goodsList.js new file mode 100755 index 0000000..706686d --- /dev/null +++ b/static/app2/js/goodsList.js @@ -0,0 +1,216 @@ +var msort = 1; +var page = 1; +var condition = 2; +var desc = 0; +var catId; +var keyword; +var isjiazai = 1; +var count = 1; +var goodsType; + +function pullupRefresh() { + // setTimeout(function() { + + // mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + + var data_set = { + page: count, + pagesize: 10, + condition: condition, + desc: desc + } + // //console.log(order_class) + if (catId) { + data_set.catId = catId; + } else if (keyword) { + data_set.keyword = keyword; + } + if (goodsType) { + data_set.goodsType = goodsType; + } + mui.ajax(qlgUrl('app/Goods/pageQuery'), { + + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if (data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"data-goodsType=2><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '</span><span>人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>' + this.discountRate + + '%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + $('.recommend_con').append(html); + $('.rcb_img').height($('.rcb_img').width()); + isjiazai = 1; + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + // }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +// function pulldownRefresh() { +// setTimeout(function() { +// window.location.reload(); +// mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed +// }, 1500); +// } +mui.plusReady(function() { + var costnum = 0; + var self = plus.webview.currentWebview(); + catId = self.data_catId; + keyword = self.data_keyword; + goodsType = self.goodsType?self.goodsType :""; + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + count = 1; + $(this).addClass('on').siblings().removeClass('on'); + + condition = $(this).attr('data-condition'); + + if ($('#cost_btn').hasClass('on')) { + + costnum += 1; + + if (costnum % 2 == 1) { + + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + + desc = 1; + + } else if (costnum % 2 == 0) { + + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + + desc = 0; + + } + + } else { + + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + + costnum = 0; + desc = 0 + } + + var data = { + pagesize: 10, + page: 1, + condition: condition, + desc: desc, + goodsType :goodsType + } + if (catId) { + data.catId = catId; + } else if (keyword) { + data.keyword = keyword; + } + + mui.ajax(qlgUrl('app/Goods/pageQuery'), { + data: data, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '" data-goodsType="'+goodsType+'"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '</span><span>人购买</span></div><div style ="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>' + + this.discountRate + + '%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + $('.recommend_con').html(html); + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + var data_1 = { + pagesize: 10, + page: 1, + condition: 2, + desc: 0 + } + if (catId) { + data_1.catId = catId; + } else if (keyword) { + data_1.keyword = keyword; + } + mui.ajax(qlgUrl('app/Goods/pageQuery'), { + data: data_1, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + data = data.data; + var html = ''; + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '" data-goodsType="'+goodsType+'"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '</span><span>人购买</span></div><div style ="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>' + this.discountRate + + '%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + $('.recommend_con').html(html); + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // //console.log(scroll.y); + // //console.log(scroll.maxScrollY); + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + isjiazai = 0; + pullupRefresh() + } + } + }) + +}) + +// setInterval(function() { +// $('.cnxh_block img').height($('.cnxh_block img').width()); +// $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +// }, 100) diff --git a/static/app2/js/guide.js b/static/app2/js/guide.js new file mode 100755 index 0000000..f83db23 --- /dev/null +++ b/static/app2/js/guide.js @@ -0,0 +1,61 @@ + +var swiperTest = null; +var banerArray = new Array(); + +mui.init({ + swipeBack: true //启用右滑关闭功能 +}); + +/**/ +mui.back = function() {}; +mui.plusReady(function() { + var timestamp1 = Date.parse(new Date()); +if(timestamp1 >= 1542470400000) { + plus.storage.setItem("lauchFlag", "true"); //第一次登陆显示 + plus.navigator.setFullscreen(false); + plus.webview.currentWebview().close(); + return; +} + $.ajax('http://www.juzi199.com/get_startup.php', { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + var html = ''; + $.each(data.img, function() { + html += '<div class="mui-slider-item "><img src="' + this + '"/></div>' + }); + $('.mui-slider-group').html(html) + $('.mui-slider-item').eq(0).addClass('mui-slider-item-duplicate'); + $('.mui-slider-item').eq(data.img.length - 1).append('<button id="close" class="mui-btn mui-btn-warning mui-btn-outlined">跳过</button>'); + var slider = mui("#slider"); + swiperTest = document.getElementById('swiperTest'); + plus.navigator.setFullscreen(true); + plus.navigator.closeSplashscreen(); + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + + mui('body').on('tap', '#close', function() { +// plus.storage.setItem("lauchFlag", "true"); //第一次登陆显示 + plus.storage.removeItem("lauchFlag"); + plus.navigator.setFullscreen(false); + plus.webview.currentWebview().close(); + + }) + setTimeout(function(){ +// plus.storage.setItem("lauchFlag", "true"); //第一次登陆显示 + plus.storage.removeItem("lauchFlag"); + plus.navigator.setFullscreen(false); + plus.webview.currentWebview().close(); + },5000) + +}); +//立即体验按钮点击事件 +//document.getElementById("close").addEventListener('tap', function(event) { +// +//}, false); \ No newline at end of file diff --git a/static/app2/js/hhrrz.js b/static/app2/js/hhrrz.js new file mode 100755 index 0000000..5867d55 --- /dev/null +++ b/static/app2/js/hhrrz.js @@ -0,0 +1,44 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + + + + var self = plus.webview.currentWebview(); + + mui('.block').on('tap', '.bj', function() { + JZL.openWindow('addhhrrz.html', 'addhhrrz.html'); + + }) + $('.con').on('tap', '.del', function() { + var data_addressId = $(this).parent().attr('data-addressId'); + if (confirm('确认删除信息?')) { + mui.ajax(qlgUrl('app/Useraddress/del'), { + data: { + id: data_addressId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + location.reload() + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + + }) + $('.add1').on('tap', function() { + JZL.openWindow('addhhrrz.html', 'addhhrrz.html'); + }) + +}) diff --git a/static/app2/js/home.js b/static/app2/js/home.js new file mode 100755 index 0000000..8dd24af --- /dev/null +++ b/static/app2/js/home.js @@ -0,0 +1,299 @@ +// $('.saoyisao').css('display', 'none'); +$('#search').css('width', '80%'); +$('#search').css('left', '5%'); +$('.searchimg').css('left', '8%'); + + +var page = 1; +var pagesize = 10; +var isjiazai = 1; + +function getRecommend(page, pagesize) { + var recommenddata = { + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(qlgUrl('addon/shuff-Shuff-recommend'), { + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if (data.status == 1) { + var html = ''; + var data = data.data; + if (data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + + } else { + mui.alert(data.msg) + // //console.log(2) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + +} +mui.plusReady(function() { + var ua = navigator.userAgent.toLowerCase(); + var issx = 0; + + //bannerTop + mui.ajax(qlgUrl('addon/shuff-Shuff-homeCarousel'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if (data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + + '"><img src="' + ectImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + $('#top_banner').height($('#top_banner').width() * 460 / 750); + } else { + mui.alert(data.msg) + // //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + //为你推荐 + getRecommend(page, pagesize); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pagesize); + } + } + }) + setInterval(function() { + + $('.add_top_left img').height($('.add_top_left img').width()); + $('.add_top_right_con img').height($('.add_top_right_con img').width()); + $('.add_bottom_con img').height($('.add_bottom_con img').width()); + + $('.rcb_img').height($('.rcb_img').width()); + + }, 100) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (-scroll.y < 0) { + num = 0; + } else if ((-scroll.y > 0 || scroll.y == 0) && -scroll.y < 150) { + num = -scroll.y / 150; + } else { + num = 1; + } + $('.header').css('background-color', 'rgba(255,255,255,' + num + ')') + + if (-scroll.y < 75) { + $('.saoyisao').attr('src', '../img/saoyisao.png'); + $('.msg').attr('src', '../img/icon_msg.png'); + $('.search').attr('src', '../img/icon_search.png'); + $('#search').css('background-color', 'white'); + // $('#search').css('color', 'black'); + // $('#keyword').css('color', 'black'); + $('.header').removeClass('shadown_wai'); + } else { + $('.saoyisao').attr('src', '../img/saoyisao1.png'); + $('.msg').attr('src', '../img/icon_msg1.png'); + $('.search').attr('src', '../img/icon_search1.png'); + $('#search').css('background-color', '#d8d8d8'); + // $('#search').css('color', 'white'); + // $('#keyword').css('color', 'white'); + $('.header').addClass('shadown_wai'); + } + + if (scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + //轮播图跳转 + $('#top_banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + + var num = 0; + + + mui('.classify').on('tap', '.class_block', function() { + var classifyId = $(this).attr('data-classifyId'); + var url = 'orSupermarket.html'; + + if (classifyId == 5) { + url = 'classify.html'; + } + + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + classifyId: classifyId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + + + + //搜索 + $('#keyword').on('focus', function() { + $(".search button").css('display', 'block'); + }) + $('#keyword').on('blur', function() { + $(".search button").css('display', 'none'); + }) + $(".search button").on('tap', function() { + var searchName = $('#keyword').val(); + var url = ''; + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + // //console.log($('.search select').val()) + if ($('.search select').val() == 0) { + url = 'goodslist.html'; + } else if ($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if (keycode == '13') { + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + // //console.log($('.search select').val()) + if ($('.search select').val() == 0) { + url = 'goodslist.html'; + } else if ($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + +}) diff --git a/static/app2/js/home_new.js b/static/app2/js/home_new.js new file mode 100755 index 0000000..190b5b5 --- /dev/null +++ b/static/app2/js/home_new.js @@ -0,0 +1,452 @@ + +var timestamp1 = Date.parse(new Date()); +//$('.getquan').css('display', 'none'); +$('#search').css('width', '82%'); +$('#search').css('left', '5%'); +$('.searchimg').css('left', '8%'); +//$('.time').css('display', 'none'); +//首页navId +$('.class_block').eq(0).attr('data-classifyId', 0); +$('.class_block').eq(1).attr('data-classifyId', 2); +$('.class_block').eq(2).attr('data-classifyId', 4); +$('.class_block').eq(3).attr('data-classifyId', 3); +$('.class_block').eq(4).attr('data-classifyId', 9); +$('.class_block').eq(5).attr('data-classifyId', 1); +$('.class_block').eq(6).attr('data-classifyId', 10); +$('.class_block').eq(7).attr('data-classifyId', 11); +$('.class_block').eq(8).attr('data-classifyId', 12); +$('.class_block').eq(9).attr('data-classifyId', ''); +var $uList = $(".scroll-box ul"); +var timer = null; +//触摸清空定时器 +$uList.hover(function() { + clearInterval(timer); + }, + function() { //离开启动定时器 + timer = setInterval(function() { + scrollList($uList); + }, + 2000); + }).trigger("mouseleave"); //自动触发触摸事件 +//滚动动画 +function scrollList(obj) { + //获得当前<li>的高度 + var scrollHeight = $("ul li:first").height(); + //滚动出一个<li>的高度 + $uList.stop().animate({ + marginTop: -scrollHeight + }, + 600, + function() { + //动画结束后,将当前<ul>marginTop置为初始值0状态,再将第一个<li>拼接到末尾。 + $uList.css({ + marginTop: 0 + }).find("li:first").appendTo($uList); + }); +} + +$('.bcon_left').height($('.bcon_left').width() * 345 / 185); + +$('.bcr_block').height($('.bcr_block').width()); +$('.addsct_block').height($('.addsct_block').width() * 225 / 355); +$('.addscb_block').height($('.addscb_block').width() * 260 / 180); + +var page = 1; +var pagesize = 10; +var isjiazai = 1; + +function getRecommend(page, pagesize) { + var recommenddata = { + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(qlgUrl('app/index/getHotGoods'), { + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data); + + // var data = toJson(data, 1); + if (data.status == 1) { + //console.log(data); + + var html = ''; + var data = data.data; + if (data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>'+this.saleNum+'</span><span>人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>'+this.discountRate+'%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + + } else { + // //console.log(2) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + +} + + +//滚动动画 +function scrollList(obj) { + //获得当前<li>的高度 + var scrollHeight = $("ul li:first").height(); + //滚动出一个<li>的高度 + $uList.stop().animate({ + marginTop: -scrollHeight + }, + 600, + function() { + //动画结束后,将当前<ul>marginTop置为初始值0状态,再将第一个<li>拼接到末尾。 + $uList.css({ + marginTop: 0 + }).find("li:first").appendTo($uList); + }); +} +mui.plusReady(function() { + var ua = navigator.userAgent.toLowerCase(); + var issx = 0; + + if (timestamp1 <= 1550678400000) { + //活动弹窗 + var lxy_div = + '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"><div class="lxy_zz"><img src="' + + ectImgUrl('static/app2/img/showActive.png') + '" /></div></div>'; + + $('body').append(lxy_div); + } + //点击让遮罩层消失 + mui('body').on('tap', '#home_zhezhao', function() { + $('#home_zhezhao').css('display', 'none'); + }); + + //跳转活动会场 + mui('#home_zhezhao').on('tap', '.lxy_zz', function() { + mui.openWindow({ + url: 'journalism_con.html', + id: 'journalism_con.html21', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + data_articleId: 21 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }); +// 点击扫一扫 +$('.saoyisao').on('tap',function () { + JZL.openWindow('saoyisao.html','saoyisao.html') +}) + + //bannerTop + mui.ajax(qlgUrl('app/appport/appBanner'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + + '"><img src="' + hyhImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + // console.log($('#top_banner').width()); + var topBannerheight=($('#top_banner').width() )* 460 / 750; + // console.log(topBannerheight); + $('#top_banner').height(($('#top_banner').width() )* 460 / 750); + localStorage.setItem('topBannerheight',topBannerheight) + } else { + // //console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + //为你推荐 + getRecommend(page, pagesize); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // 判断默认行为是否可以被禁用 + if (e.cancelable) { + // 判断默认行为是否已经被禁用 + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pagesize); + } + } + if (-scroll.y < 0) { + num = 0; + } else if ((-scroll.y > 0 || scroll.y == 0) && -scroll.y < 150) { + num = -scroll.y / 150; + } else { + num = 1; + } + $('.header').css('background-color', 'rgba(255,255,255,' + num + ')') + + if (-scroll.y < 75) { + $('.saoyisao').attr('src', '../img/saoyisao.png'); + $('.msg').attr('src', '../img/icon_msg.png'); + $('.search').attr('src', '../img/icon_search.png'); + $('#search').css('background-color', 'white'); + // $('#search').css('color', 'black'); + // $('#keyword').css('color', 'black'); + $('.header').removeClass('shadown_wai'); + } else { + $('.saoyisao').attr('src', '../img/saoyisao1.png'); + $('.msg').attr('src', '../img/icon_msg1.png'); + $('.search').attr('src', '../img/icon_search1.png'); + $('#search').css('background-color', '#d8d8d8'); + // $('#search').css('color', 'white'); + // $('#keyword').css('color', 'white'); + $('.header').addClass('shadown_wai'); + } + + if (scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + }, false) + setInterval(function() { + + $('.add_top_left img').height($('.add_top_left img').width()); + $('.add_top_right_con img').height($('.add_top_right_con img').width()); + $('.add_bottom_con img').height($('.add_bottom_con img').width()); + + $('.rcb_img').height($('.rcb_img').width()); + + }, 100) + //轮播图跳转 + $('#top_banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + + mui('body').on('tap', '.bannerAdd', function() { + localStorage.setItem('aaaaaa', 1); + }) + mui('.classify').on('tap', '.class_block', function() { + var classifyId = $(this).attr('data-classifyId'); + var url = 'orSupermarket.html'; + + if (classifyId == 0) { + url = 'self_shop.html'; + } + if (classifyId == '') { + url = 'classify.html'; + } + + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + classifyId: classifyId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) +// mui('body').on('tap', '.add_bcr', function() { +// //var brandId = $(this).attr('data-brandId'); +// +// // openAds($(this)); +// mui.openWindow({ +// url: 'storeout.html', +// id: 'storeout.html' + shopId, +// styles: { +// top: '0px', //新页面顶部位置 +// bottom: '0px', //新页面底部位置 +// }, +// extras: { +// shopId: shopId +// // ..... //自定义扩展参数,可以用来处理页面间传值 +// }, +// createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 +// show: {}, +// waiting: {} +// }) +// }) + + + //领券 + mui('body').on('tap', '.getquan', function() { + if (timestamp1 >= 1542470400000) { + mui.alert('敬请期待!'); + return; + } + mui.openWindow({ + url: 'god_ect.html', + id: 'god_ect.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + + //搜索 + $('#keyword').on('focus', function() { + $(".search button").css('display', 'block'); + }) + $('#keyword').on('blur', function() { + $(".search button").css('display', 'none'); + }) + $(".search button").on('tap', function() { + var searchName = $('#keyword').val(); + var url = ''; + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + // //console.log($('.search select').val()) + if ($('.search select').val() == 0) { + url = 'goodslist.html'; + } else if ($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +$('#keyword').val("") + }) + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if (keycode == '13') { + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + // //console.log($('.search select').val()) + if ($('.search select').val() == 0) { + url = 'goodslist.html'; + } else if ($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); +}) diff --git a/static/app2/js/income-details.js b/static/app2/js/income-details.js new file mode 100755 index 0000000..a43f351 --- /dev/null +++ b/static/app2/js/income-details.js @@ -0,0 +1,20 @@ +mui.plusReady(function() { + var self=plus.webview.currentWebview(); + //console.log(self) + var shopId=self.id; + var data_href=self.data_href; + var data_expect=self.data_expect; + if('wait_money' == data_href){ + $('.title')="待收款" + } + if('comp_money' == data_href){ + $('.title')="已收款" + } + + + + + + + +}) \ No newline at end of file diff --git a/static/app2/js/indent.js b/static/app2/js/indent.js new file mode 100755 index 0000000..9d0c5df --- /dev/null +++ b/static/app2/js/indent.js @@ -0,0 +1,42 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}) + +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_href = self.data_href; + if(data_href == 'all') { + $('.title').html('全部订单'); + + } + if(data_href == 'waitPay') { + $('.title').html('待付款'); + } + if(data_href == 'waitDeliver') { + $('.title').html('待发货'); + } + if(data_href == 'waitReceive') { + $('.title').html('待收货'); + } + if(data_href == 'waitAppraise') { + $('.title').html('待评价'); + } + if(data_href == 'abnormal') { + $('.title').html('退款/售后'); + } + localStorage.setItem('order_class', data_href); + var bSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var sub = plus.webview.create('indentcon.html', data_href, { + top: bSize, + bottom: '0px', + scrollIndicator: 'none' + }); + self.append(sub); + +}) \ No newline at end of file diff --git a/static/app2/js/indentcon.js b/static/app2/js/indentcon.js new file mode 100755 index 0000000..7a93b48 --- /dev/null +++ b/static/app2/js/indentcon.js @@ -0,0 +1,939 @@ +$('#content').after('<div class="tui"></div>'); +var pay_name = 0; +var token = localStorage.getItem('token'); +var order_class = localStorage.getItem('order_class'); +var orderNo; +var orderId; +var getReasonUrl = ''; +var priceT = 0; +var payCode = ''; +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + contentnomore: '没有更多数据了', + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + count += 1; + getData(count); + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + //mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +var isLoad = false; + +function getData(page) { + if (true == isLoad) return; + isLoad = true; + JZL.ajax(qlgUrl('app/Orders/getOrderList'), { + type: order_class, + page: page, + pagesize: 10 + }, function(data) { + //console.log(data); + var data = toJson(data); + var html = '' + if ('' == data.data.Rows) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + $.each(data.data.Rows, function() { + //this.pay_name = 1; + var shopConfirmHtml = ''; + if (this.orderStatus == 0) { + if (0 == this.shopConfirm) { + shopConfirmHtml = '<div class="indent_status confirm_wait" > 待商家确认</div>'; + } else if (1 == this.shopConfirm) { + shopConfirmHtml = '<div class="indent_status confirm_ok" > 商家已确认</div>'; + } else if (2 == this.shopConfirm) { + shopConfirmHtml = '<div class="indent_status confirm_no" > 商家未收款</div>'; + } + } + html += '<div class="row" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + + '"><div class="row_title"><div class="store_name">' + this.shopName + + '</div><div class="indent_status shopPhone">商家电话:<a href="tel:' + + this.phone + '">' + this.phone + '</a></div>' + shopConfirmHtml + '<div class="indent_status yellow">' + + this.status + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + + this.goodsNum + '</span></div></div></div>'; + }) + html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if (this.orderStatus == -2) { + html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + + '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if (this.orderStatus == 0) { + html += '<div class="btns_btn uploadCertificate">上传凭证</div>'; + if (this.noticeDeliver == 0) { + html += '<div class="btns_btn txfh" style="display:none;">提醒发货</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else { + html += '<div class="btns_btn " style="display:none;">已提醒</div><div class="btns_btn qxdd_js">取消订单</div>'; + } + + } else if (this.orderStatus == 1) { + html += + '<div class="btns_btn qrsh">确认收货</div><div class="btns_btn ckwl">查看物流</div><div class="btns_btn qxdd_js" >拒收</div><div class="btns_btn yssh">延长收货</div>'; + } else if (this.orderStatus == 2) { + if (this.isAppraise == 0) { + html += '<div class="btns_btn ljpj" >立即评价</div>'; + } else { + html += '<div class="btns_btn ckpj">查看评价</div>'; + } + + } + if (this.orderStatus != 1 && this.orderStatus != -2 && this.isComplain == 0) { + html += '<div class="btns_btn tsdd" >投诉</div>'; + } + if (this.allowRefund == 1 && (this.orderStatus == -1 || this.orderStatus == -3)) { + html += '<div class="btns_btn qxdd_js" >申请退款</div>'; + } + + html += '</div></div>' + }) + + $('.con').append(html); + isLoad = false; + }) +} +mui.plusReady(function() { + + // window.addEventListener('refresh', function(e) { //执行刷新 + // location.reload(); + // }); + // //console.log(order_class) + if (order_class == 'all') { + order_class = ''; + } + getData(count); + + //支付插件 + plus.payment.getChannels(function(channels) { + for (var i in channels) { + if (channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + mui.alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=0&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if (id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if (id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch (xhr.readyState) { + case 4: + if (xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + var targetTab = plus.webview.getWebviewById("templete/my.html"); + mui.fire(targetTab, 'refresh'); + location.reload(); + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + // plus.webview.getWebviewById('confirmOrder.html').close() + }); + } else { + mui.alert("获取订单信息失败!"); + //console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + $('#pay_way,.pay_info .con_1').append( + '<div class="row clearfix select_payway" data-payCode="qlgpay"><p class="row_left">付款方式</p><p class="row_right">线下支付</p></div>' + ); + + // mui.ajax(hyhUrl('/app/Users/get_name_and_money'), { + // headers: { + // "HYH-Token": token + // }, + // data: {}, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // // //console.log(data) + // data = toJson(data); + // + // if(data.status == 1) { + // $('#loginName').html(data.data.name); + // $('.userMoney').html(data.data.money); + // var htmlpay = '<div class="row clearfix select_payway" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.data.userECT + '</o></p></div>'; + // $('.pay_info .con_1').append(htmlpay); + // } else { + // mui.alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }) + $('.con').on('tap', '.ljfk', function() { + var that = $(this); + pay_name = $(this).attr('data-payName'); + priceT = $(this).parent().siblings('.combination').children('o').html().slice(1); + $('#goodsTotalMoney').html($(this).parent().siblings('.combination').children('o').html()) + orderNo = $(this).parent().parent().attr('data-orderNo'); + if (pay_name == 1) { + $('.pay_info .con_1 .row').eq(1).attr('style', 'display: none;'); + $('.pay_info .con_1 .row').eq(2).addClass('on'); + that.attr('disabled', 'disabled'); + mui.ajax(hqlgUrl('app/ect/getToEctNum'), { + + data: { + total_money: priceT + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if (e.index == 1) { + return; + } else { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } + that.removeAttr('disabled'); + }) + } else { + mui.alert(data.msg); + that.removeAttr('disabled'); + return; + } + + } + }) + } else { + $('.pay_info .con_1 .row').eq(1).addClass('on'); + $('.pay_info .con_1 .row').eq(2).attr('style', 'display: none;'); + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.con_1 .on .row_right o').html($(this).children('.row_left').html()); + $('.con_1 .on').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + + }) + $('.pay').on('tap', '.con_1 .on', function() { + if ($(this).attr('data-payCode') == 'ect') { + + } else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + } + + }) + $('.pay_btn').on('tap', function() { + payCode = $('.con_1 .on').attr('data-payCode'); + ////console.log(payCode) + var that = $(this); + var data_ljfk = { + isBatch: 0, + orderNo: orderNo + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/orders/succeed'), { + data: data_ljfk, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + data = toJson(data); + + if (data.status == 1) { + if (payCode == 'qlgpay') { + JZL.ajax(hyhUrl('app/' + payCode + '/payment'), { + orderNo: orderNo, + isBatch: 0 + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(JSON.stringify(data)); + var data = toJson(data); + // //console.log(JSON.stringify(data)) + if (data.status == 1) { + $('.pay').css('display', 'none'); + $('#qlg_pay_pwd').css('display', 'block'); + if (data.data.payPwd == '0') { + mui.alert('还未设置支付密码请先设置操作密码!'); + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + //return; + } + $('#totalMoney').html('付款总额:¥<o>' + data.data.needPay + '</o>'); + $('#productNum').val(data.data.product.useProduct); + if (data.data.product.useProduct > 0) { + var html1 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.product.useProductOk + + '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.product.useProductTaxFee + + '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.product.useProductHandlingFee + + '</span></p>'; + // $('#productInfo').html('产品券[抵扣额:' + data.data.product.useProductOk + ',扣税:' + data.data.product.useProductTaxFee + + // ',手续费:' + data.data.product.useProductHandlingFee + ']'); + $('.productInfo_').html(html1) + + } + $('#couponsNum').val(data.data.coupons.useCoupons); + if (data.data.coupons.useCoupons > 0) { + var html2 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.coupons.useCouponsOk + + '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.coupons.useCouponsTaxFee + + '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.coupons.useCouponsHandlingFee + + '</span></p>'; + $('.couponsInfo_').html(html2) + // $('#couponsInfo').html('优惠券[抵扣额:' + data.data.coupons.useCouponsOk + ',扣税:' + data.data.coupons.useCouponsTaxFee + + // ',手续费:' + data.data.coupons.useCouponsHandlingFee + ']'); + } + $('#wangNum').val(data.data.wang.useWang); + $('#moneyNum').val(data.data.money.useMoney); + + } else { + mui.alert(data.msg) + } + }); + } else if (payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + mui.ajax(hyhUrl('app/' + payCode + '/payment'), { + data: { + orderNo: orderNo, + isBatch: 0 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + if (data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if (data.data.payPwd == '0') { + mui.alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + } else if (payCode == 'alipays') { + pay('alipay', orderNo); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + mui.alert(data.msg) + // mui.alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + mui.alert(type); + } + }) + }) + $('#pay_pwd,#qlg_pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + JZL.openWindow(url + '.html', url + '.html'); + }) + $('#pay_pwd,#qlg_pay_pwd').on('tap', '.pay_btn_pwd', function() { + // var self = plus.webview.currentWebview(); + // var data_href = self.id; + // //console.log(data_href) + // JZL.closeWindow('waitPay'); + //return; + var payPwd = $('#payPwd').val(); + if (payPwd == '') { + mui.alert('支付密码不能为空!'); + return; + } + var that = $(this); + that.attr('disabled', 'disabled') + var srcc = '' + if (payCode == 'qlgpay') { + srcc = 'payByQlg'; + } else if (payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + + mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), { + + data: { + orderNo: orderNo, + isBatch: 0, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + mui.alert(data.msg) + //console.log(data.status) + if (data.status == 1) { + JZL.openWindow('indent.html', 'waitDeliver', { + data_href: 'waitDeliver' + }); + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + // JZL.closeWindow('indent.html'); + }, 700) + // var targetTab = plus.webview.getWebviewById("templete/my.html"); + // mui.fire(targetTab, 'refresh'); + // location.reload(); + } else { + + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + + mui('.con').on('tap', '.row_con', function() { + var data_order_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'order_out.html', + id: 'order_out.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.ckwl', function() { + var data_order_id = $(this).parent().parent().attr('data-id'); //$(this).attr('data-id'); + JZL.openWindow('logistics.html', 'logistics.html', { + data_order_id: data_order_id + }); + }) + //上传凭证 + mui('.con').on('tap', '.uploadCertificate', function() { + var orderId = $(this).parent().parent().attr('data-id'); + // mui.alert('跳到上传凭证页'+orderId) + + JZL.openWindow('uploadVoucher.html', 'uploadVoucher.html' + orderId, { + orderId: orderId + }); + + }) + $('.con').on('tap', '.qxdd_js', function() { + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if ($(this).html() == '取消订单') { + getReasonUrl = 'getCancelCause'; + } else if ($(this).html() == '拒收') { + getReasonUrl = 'getRejectCause'; + } else if ($(this).html() == '申请退款') { + getReasonUrl = 'getRefundCause'; + JZL.ajax(hyhUrl('/app/Orders/getRefund'), { + id: orderId + }, function(data) { //服务器返回响应 + // //console.log(JSON.stringify(data)); + var data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = ''; + if ('qlgpay' == data.payFrom) { + html = '&nbsp;退款产品券数量:<input type="text" class="refundTxt" name="productNum" id="productNum" value="' + + data.productNum + + '" placeholder="请输入产品券数量"/>' + + '&nbsp;退款优惠券数量:<input type="text" class="refundTxt" name="couponsNum" id="couponsNum" value="' + data.couponsNum + + '" placeholder="请输入优惠券数量"/>' + + '&nbsp;退款旺旺券数量:<input type="text" class="refundTxt" name="wangNum" id="wangNum" value="' + data.wangNum + + '" placeholder="请输入旺旺券数量"/>' + + '&nbsp;退款现金数量:' + data.moneyNum + ',现金方面请与商家协商' + + // '<p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + + '</o>)</p>'; + } else { + html = '<input type="text" name="Tmoney" id="Tmoney" value="' + data.realTotalMoney + + '" placeholder="请输入退款金额"/><p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + + '</o>)</p><p class="info1">(积分数量:' + data.ectNum + ')</p>'; + } + + $('.tui').html(html) + } else { + mui.alert(data.msg) + } + }); + } + $('.bg_').css('display', 'block'); + $('.bg_con').css('display', 'none'); + $('.bg_con').slideDown(300, function() {}); + + mui.ajax(hyhUrl('/app/Orders/' + getReasonUrl), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + var html = '<option value="0">请下拉选择原因</option>'; + $.each(data.data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>' + }); + $('#select').html(html) + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + + $('.bg_').on('tap', '.en_false', function() { + $('.bg_').css('display', 'none'); + + }) + $('.bg_').on('tap', '.en_true', function() { + var setReasonUrl = ''; + var content = $('#content').val(); + var reason = $('#select').val(); + if ($('#select').val() == 0) { + mui.alert('请选择原因!'); + return; + } + if ($('#select').val() == 10000 && content == '') { + mui.alert('请输入其他原因!'); + return; + } + if (getReasonUrl == 'getCancelCause') { + setReasonUrl = 'cancellation'; + mui.ajax(qlgUrl('app/Orders/' + setReasonUrl), { + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + // var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + // mui.fire(list, 'refresh'); + if ('waitPay' == plus.webview.currentWebview().id) { + location.reload(); + } else { + JZL.openWindow('indent.html', 'abnormal', { + data_href: 'abnormal' + }); + setTimeout(function() { + //plus.webview.currentWebview().close(); + JZL.closeWindow(plus.webview.currentWebview().id); + }, 500) + } + // JZL.openWindow('indent.html', 'abnormal', { + // data_href: 'abnormal' + // }); + // setTimeout(function() { + // plus.webview.currentWebview().close(); + // // JZL.closeWindow(plus.webview.currentWebview().id); + // }, 500) + //location.reload(); + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else if (getReasonUrl == 'getRejectCause') { + setReasonUrl = 'reject'; + mui.ajax(qlgUrl('app/Orders/' + setReasonUrl), { + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + // var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + // mui.fire(list, 'refresh'); + location.reload(); + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else if (getReasonUrl == 'getRefundCause') { + var params = {} + // params.money = $('#Tmoney').val(); + // if (params.money < 0 || params.money == 0) { + // mui.alert('退款金额不能为0!'); + // return; + // } + params.productNum = $('#productNum').val(); + params.couponsNum = $('#couponsNum').val(); + params.wangNum = $('#wangNum').val(); + params.reason = reason; + params.id = orderId; + params.content = content; + JZL.ajax(qlgUrl('app/Orderrefunds/refund'), params, function(data) { + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }) + + } + + }) + + $('.con').on('tap', '.yssh', function() { + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if (confirm('你要延长收货么?')) { + mui.ajax(qlgUrl('/app/orders/delay'), { + headers: { + "HYH-Token": token + }, + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + ////console.log(data.data.goodsFavoritesNum) + ////console.log(data.data.Rows) + var data = toJson(data); + ////console.log(data.status) + if (data.status == 1) { + mui.alert(data.msg); + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + } + }) + + $('.con').on('tap', '.qrsh', function() { + //$('.bg_').css('display', 'block'); + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if (confirm('确认收货?')) { + mui.ajax(hyhUrl('/app/Orders/receive'), { + headers: { + "HYH-Token": token + }, + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + ////console.log(data.data.goodsFavoritesNum) + ////console.log(data.data.Rows) + var data = toJson(data); + ////console.log(data.status) + if (data.status == 1) { + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + } + + }) + $('#select').on('change', function() { + if ($(this).val() == '10000') { + $('#content').css('display', 'block'); + } else { + $('#content').css('display', 'none'); + } + }) + //跳转到评价 + mui('.con').on('tap', '.ljpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.ckpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.tsdd', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'complain.html', + id: 'complain.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) diff --git a/static/app2/js/index.js b/static/app2/js/index.js new file mode 100755 index 0000000..e66df04 --- /dev/null +++ b/static/app2/js/index.js @@ -0,0 +1,101 @@ +var wgtVer = null; +var is_juzi_online = 0; + +function plusReady() { // 获取本地应用资源版本号 + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + wgtVer = inf.version; + }); +} +//休眠方法 +var ver; +//获取数据 + +function sleep(numberMillis) { + var now = new Date(); + var exitTime = now.getTime() + numberMillis; + while (true) { + now = new Date(); + if (now.getTime() > exitTime) + return; + } +} + +mui.init({ + swipeBack: true +}); +var firstBackbutton = null; +mui.back = function() { + if (!firstBackbutton) { + window.plus.nativeUI.toast('再按一次退出应用'); + firstBackbutton = new Date().getTime(); + setTimeout(function() { + firstBackbutton = null + }, 2000); + return false; + } else { + if (new Date().getTime() - firstBackbutton < 2000) { + if (mui.os.ios) { + const threadClass = plus.ios.importClass("NSThread"); + const mainThread = plus.ios.invoke(threadClass, "mainThread"); + plus.ios.invoke(mainThread, "exit"); + } else { + plus.runtime.quit(); + } + } + } +}; +//获取cid用于推送 +mui.plusReady(function() { + // var cid = plus.push.getClientInfo().clientid; + var timer = 0; + timer = setInterval(function() { + getData(); + }, 3000) + getData(); + + function getData() { + + if (!localStorage.getItem('isFirstDownlodad')) { + localStorage.setItem('isFirstDownlodad', true); + } + mui.ajax('http://www.juzi199.com/get_version_new.php?' + Math.random(), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功;clearInterval(timer) + clearInterval(timer); + localStorage.setItem('version', data.version); + if (0 == is_juzi_online) { + localStorage.setItem('cssUrl', "../css/"); + localStorage.setItem('jsUrl', "../js/"); + } else { + localStorage.setItem('cssUrl', data.cssUrl ? data.cssUrl : "../css/"); + localStorage.setItem('jsUrl', data.jsUrl ? data.jsUrl : "../js/"); + } + $('nav').css('display', 'block'); + $('#bg').css('display', 'none'); + var ipxSizeTop = 0; + var ipxSizeBottom = 0; + if (/iphone/gi.test(navigator.userAgent) && ((screen.height == 812 && screen.width == 375) || (screen.height == + 896 && screen.width == 414) || (screen.height == 1792 / 3 && screen.width == 828 / 3))) { + + ipxSizeTop = 24; + ipxSizeBottom = 34; + //$('.mui-bar').attr('style', "bottom: 34px;") + }; + + localStorage.setItem('ipxSizeTop', ipxSizeTop); + localStorage.setItem('ipxSizeBottom', ipxSizeBottom); + init(data); + jumpPage(ipxSizeBottom); + nav(0); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + mui.toast("网络异常,请检查网络设置!"); + } + }); + } + +}) diff --git a/static/app2/js/individual.js b/static/app2/js/individual.js new file mode 100755 index 0000000..699c580 --- /dev/null +++ b/static/app2/js/individual.js @@ -0,0 +1,179 @@ +mui.plusReady(function() { + var wait = 120; + var count = 0; + var authId = ''; + JZL.getItems('auth_personal'); + + $('.header_con_bc').on('tap', function() { + JZL.saveItems('.localinp', 'auth_personal'); + mui.toast('保存成功'); + }) + // //console.log($('#headImg').val()); + + if ('' == $('#headImg').val()) { + $("#headImgTag").attr("src", "../img/touxiang.jpg") + } + if ('' == $('#accountBookImg').val()) { + $("#accountBookImgTag").attr("src", "../img/hukou.jpg") + } + + JZL.ajax(qlgUrl('app/auth/getAuthInfo'), {}, function(data) { + //console.log(data); + // //console.log(typeof(data.data)); + if ('undefined' != typeof(data.data) && 1 == data.status) { //编辑 + count = 1; + authId = data.data.id + $('.mobileCode').hide() + $('.userPhone').hide() + $('.payPwd').show() + mui.each(data.data, function(index, element) { + if ($('#' + index).attr("type") == "hidden") { + // var imgindex = index.substring(0, index.length - 3); + var imgindex = index + 'Tag' + var obj = '#' + imgindex + // //console.log('#' + imgindex + '') + if (imgindex != "") { + if ($(obj).is('img')) { + $(obj).attr("src", hyhImgUrl(element)) + $('#' + index + '').val(element) + } + } + + } else { + $('#' + index).val(element) + } + + + }) + // if (data.status == 1) { + // $('.qrbb').show(); + // $('.qrrz').show(); + // } else { + // $('.qrbb').hide(); + // $('.qrrz').hide(); + // } + } else { + //console.log(2222); + $('.userPhone').show() + $('.mobileCode').show() + $('.payPwd').hide() + JZL.getItems('auth_company'); + } + }) + + function time() { + if (wait == 0) { + $('.HQYZM').removeAttr("disabled"); + $('.HQYZM').html("重新发送"); + wait = 120; + } else { + $('.HQYZM').attr("disabled", true); + $('.HQYZM').html("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + $(".HQYZM").on("tap", function() { + var userPhone = $('#userPhone').val(); + if ('' == userPhone) { + mui.alert("请输入手机号") + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(userPhone))) { + mui.alert("手机号码有误,请重填!"); + return; + } + $(".HQYZM").attr("disabled", true); + + JZL.ajax(qlgUrl('app/auth/getPhoneCode'), { + userPhone: userPhone + }, function(data) { + //console.log(data); + if (data.status == 1) { + time(); + $('.YZM').focus(); + } else { + mui.alert(data.msg); + } + + }) + }) + + $('.bc_btn').on('tap', function() { + var params = JZL.getParams(".inp"); + if ('' == params.houseAddress) { + mui.alert("请输入地址"); + return; + } + if ('' == params.householdIdCard) { + mui.alert("请输入身份证号"); + return; + + } + if ('' == params.householdName) { + mui.alert("请输入户主姓名"); + return; + + } + if (0 == count) { + if ('' == params.mobileCode) { + mui.alert("请输入验证码"); + return; + + } + } else if (1 == count) { + if ('' == params.payPwd) { + mui.alert("请输入操作密码"); + return; + } + params.authId = authId; + } + + //console.log(params); + JZL.ajax(qlgUrl('app/auth/setAuthInfo'), params, function(data) { + //console.log(data); + if (data.status == 1) { + + JZL.saveItems('.localinp', 'auth_personal'); + localStorage.setItem("authType","1") + mui.toast("提交成功 请等待审核") + // $(".mui-table-view").attr("readonly", "readonly") + $(".mobileCode").attr("display", "none") + mui.back(); + } else { + mui.alert(data.msg); + } + + }) + }) + + mui('.mui-table-content').on('tap', '.qrbb', function() { + JZL.openWindow('qrbb.html', 'qrbb.html'); + + }) + mui('.mui-table-content').on('tap', '.qrrz', function() { + JZL.openWindow('qrrz.html', 'qrrz.html'); + + }) + + + $(".ossfile").on("tap", '#accountBookImgTag', function() { + UP.init("accountBookImg", "test", "accountBookImgTag") + + // UP.init("id", "test", "imgId") + + openCamera(); + }) + //更换头像 + $("#headerimg").on("tap", '#headImgTag', function() { + UP.init("headImg", "test", "headImgTag") + openCamera(); + }) + + +}) diff --git a/static/app2/js/invest.js b/static/app2/js/invest.js new file mode 100755 index 0000000..d45b2db --- /dev/null +++ b/static/app2/js/invest.js @@ -0,0 +1,27 @@ +mui.plusReady(function () { + var userId=""; + var shopName=""; + // 获取数据 + JZL.ajax(qlgUrl('app/users/familyInvestmentList'),{},function (data ) { + console.log(data); + var html =""; + if (1 == data.status){ + var data = data.data + $.each(data,function () { + html+='<div class="con_ shadown_wai" data-id ='+this.userId+' data-shopName="'+this.companyName+'" ><div class="top"><div class="left"> <img src="'+hyhImgUrl(this.headImg)+'" alt=""></div><div class="mid"><div class="title">'+this.companyName+' </div><div class="partner"> 合作人'+this.count +'人</div><div class="timer">'+formatDate(new Date(this.createTime*1000))+'创建 </div></div><div class="right"><div class="scale"><div class="scaleNum">'+this.stake+'%</div><p>持股</p></div></div></div><div class="bottom"><div class="img"> <img src="../img/ditudingwei.png" ></div><div class="pos">'+this.companyAddress+' </div></div></div>' + }) + + $('.con').append(html) + + } + + }) + + + $("body").on("tap",".con_",function () { + userId=$(this).attr("data-id") + shopName=$(this).attr("data-shopName") + + JZL.openWindow('investdetail.html', 'investdetail.html',{userId : userId,shopName:shopName}) + }) +}) \ No newline at end of file diff --git a/static/app2/js/investdetail.js b/static/app2/js/investdetail.js new file mode 100755 index 0000000..ece77e0 --- /dev/null +++ b/static/app2/js/investdetail.js @@ -0,0 +1,24 @@ +mui.plusReady(function () { + var self =plus.webview.currentWebview() + var userId = self.userId; + var shopName = self.shopName; + var html = ""; + + // console.log(self.userId); + //获取数据 + JZL.ajax(qlgUrl("app/users/investmentInfo"),{userId:userId},function (data) { + console.log(data); + if (1 == data.status) { + var data =data.data; + html ='<div class="shopName">'+shopName+'</div>' + $.each(data,function () { + html += '<div class="con_ shadown_wai"><div class="top"><div class="left"> <img src="'+hyhImgUrl(this.businessImg)+'" alt=""></div><div class="mid"><div class="title partnerName">'+ this.uName+'</div><div class=" partner zhiwei">'+this.positionName+'</div><div class="timer">'+formatDate(new Date(this.createTime*1000))+'加入</div></div><div class="right"><div class="scale"><div class="scaleNum">'+this.stake+'%</div><p>持股</p></div></div></div></div>' + }) + $('.con').html(html) + } + }) + + $('.down').on ("tap",".btn",function () { + JZL.openWindow("distribution.html","distribution.html",{userId :userId}) + }) +}) \ No newline at end of file diff --git a/static/app2/js/journalism.js b/static/app2/js/journalism.js new file mode 100755 index 0000000..77a46b9 --- /dev/null +++ b/static/app2/js/journalism.js @@ -0,0 +1,155 @@ +document.write('<link rel="stylesheet" type="text/css" href="../css/swiper.min.css"/>'); +document.write('<script type="text/javascript" src="../js/swiper.min.js"></scr' + 'ipt>'); +var num = 1; +var isOver = 1; +var catId = ''; + +function getMsg(catIdNum, pageNum, pagesizeNum) { + + var data_msg = { + catId: catIdNum ? catIdNum : '', + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + + if(isOver == 0) { + return; + } else { + isOver = 0; + } + mui.ajax(kxUrl('app/Articles/headLine'), {  + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + data = data.data; + if(data.Rows == '') { + if(pageNum == 1) { + $('.con_').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } else if(pageNum > 1) { + $('.con_').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } + + isOver = 0; + return; + } + $.each(data.Rows, function() { + var coverImg = ''; + if(data.coverImg) { + coverImg = ectImgUrl(data.coverImg) + } else { + coverImg = '../img/mujiimg.png' + } + html += '<div class="con_block shadown_wai" data-articleId = "' + this.articleId + '" data-><img src="' + coverImg + '" alt="" class="cbimg"/><p class="cbtitle">' + this.articleTitle + '</p><p class="name">' + this.articleKey + ' <img src="../img/icon_eye.png" alt="" />' + this.visitorNum + '</p></div>' + }); + + if(pageNum == 1) { + $('.con_').html(html); + } else if(pageNum > 1) { + $('.con_').append(html); + } + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +} +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + mui.ajax(kxUrl('app/Articles/orange'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data,1); + if(data.status == 1) { + var html = '<div class="swiper-container" id="timer_swiper"><div class="swiper-wrapper">'; + var len = 0; + var data = data.data; + $.each(data, function(num) { + html += '<div class="swiper-slide nav_block" data-catId="' + this.catId + '"><p class="p1">' + this.catName + '</p></div>'; + len = num + 1; + }) + + html += '</div></div>' + $('.nav').html(html); + + if(len == 0) { + // mui.back(); + } else if(len == 1) { + + } else { + $('.t_con').css('display', 'block'); + } + if(len > 5) { + len = 4.5 + } else { + len = len; + } + var swiper = new Swiper('#timer_swiper', { + slidesPerView: len, + paginationClickable: true, + spaceBetween: 0, + freeMode: true + }); + $('.nav_block').eq(0).addClass('on'); + catId = $('.nav_block').eq(0).attr('data-catId'); + getMsg(catId, 1, 10); + } else { + console.log(data.status); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + console.log(errorThrown);       + }   + });  + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num++; + getMsg(catId, num, 10); + } + } + }) + $('.con').on('tap', '.con_block', function() { + var id = $(this).attr('data-articleId'); + mui.openWindow({ + url: 'journalism_con.html', + id: 'journalism_con.html' + id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_articleId: id + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: false, //自动显示等待框,默认为true + } + }) + }) + $('.nav').on('tap', '.nav_block', function() { + catId = $(this).attr('data-catId'); + isOver = 1; + num = 1; + getMsg(catId, 1, 10); + $(this).addClass('on').siblings().removeClass('on') + }) + +}) \ No newline at end of file diff --git a/static/app2/js/journalism_con.js b/static/app2/js/journalism_con.js new file mode 100755 index 0000000..d970c8f --- /dev/null +++ b/static/app2/js/journalism_con.js @@ -0,0 +1,38 @@ +$('.con_').html(''); + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var msgId = self.data_articleId; + mui.ajax(kxUrl('app/Articles/detail'), {  + + data: { + articleId: msgId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   +// var data = toJson(data,1); + + if(data.status == 1) { + var data = data.data; + + var coverImg = ''; + + if(data.coverImg){ + coverImg = ectImgUrl(data.coverImg) + }else{ + coverImg = '../img/mujiimg.png' + } + var html = '<div class="con_top"><img class="headImg" src="'+ coverImg +'" /><div class="con_top_title">'+ data.articleKey +'</div><div class="num">'+ data.visitorNum +'阅读</div><button class="guanzhu"style="display: none;">关注</button></div><div class="con_con">'+ data.articleContent +'</div><div class="time">'+ data.createTime +'</div>'; + $('.con_').html(html); + } else { + console.log(data.status); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +}) \ No newline at end of file diff --git a/static/app2/js/jquery-3.2.1.min.js b/static/app2/js/jquery-3.2.1.min.js new file mode 100755 index 0000000..644d35e --- /dev/null +++ b/static/app2/js/jquery-3.2.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r}); diff --git a/static/app2/js/jquery-ui.min.js b/static/app2/js/jquery-ui.min.js new file mode 100755 index 0000000..04b2f92 --- /dev/null +++ b/static/app2/js/jquery-ui.min.js @@ -0,0 +1,13 @@ +/*! jQuery UI - v1.12.1 - 2017-06-25 +* http://jqueryui.com +* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/selectmenu.js, widgets/slider.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(p.inline?p.dpDiv.parent()[0]:p.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,g,m,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),k={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,g=_.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),k[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?m.left+=p:"center"===n.at[0]&&(m.left+=p/2),"bottom"===n.at[1]?m.top+=f:"center"===n.at[1]&&(m.top+=f/2),u=e(k.at,p,f),m.left+=u[0],m.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),x=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},m),I=e(k.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=I[0],D.top+=I[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[u[0]+I[0],u[1]+I[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=g.left-D.left,i=e+p-l,s=g.top-D.top,r=s+f-c,u={target:{element:v,left:g.left,top:g.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var c=!1;t(document).on("mouseup",function(){c=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!c){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),c=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,c=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0) +},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY<n.scrollSensitivity?a.scrollTop=o=a.scrollTop+n.scrollSpeed:e.pageY-s.overflowOffset.top<n.scrollSensitivity&&(a.scrollTop=o=a.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+a.offsetWidth-e.pageX<n.scrollSensitivity?a.scrollLeft=o=a.scrollLeft+n.scrollSpeed:e.pageX-s.overflowOffset.left<n.scrollSensitivity&&(a.scrollLeft=o=a.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(e.pageY-t(r).scrollTop()<n.scrollSensitivity?o=t(r).scrollTop(t(r).scrollTop()-n.scrollSpeed):t(window).height()-(e.pageY-t(r).scrollTop())<n.scrollSensitivity&&(o=t(r).scrollTop(t(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(e.pageX-t(r).scrollLeft()<n.scrollSensitivity?o=t(r).scrollLeft(t(r).scrollLeft()-n.scrollSpeed):t(window).width()-(e.pageX-t(r).scrollLeft())<n.scrollSensitivity&&(o=t(r).scrollLeft(t(r).scrollLeft()+n.scrollSpeed)))),o!==!1&&t.ui.ddmanager&&!n.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var n=s.options;s.snapElements=[],t(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var n,o,a,r,h,l,c,u,d,p,f=s.options,g=f.snapTolerance,m=i.offset.left,_=m+s.helperProportions.width,v=i.offset.top,b=v+s.helperProportions.height;for(d=s.snapElements.length-1;d>=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&u(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var u=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&u(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=u(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0}; +t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-this.document.scrollTop()<a.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-a.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<a.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+a.scrollSpeed)),e.pageX-this.document.scrollLeft()<a.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-a.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<a.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td>&#160;</td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t("<span>"),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons")) +},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()<e.index()),c=this.options.animate||{},u=l&&c.down||c,d=function(){a._toggleComplete(i)};return"number"==typeof u&&(o=u),"string"==typeof u&&(n=u),n=n||u.easing||c.easing,o=o||u.duration||c.duration,e.length?t.length?(s=t.show().outerHeight(),e.animate(this.hideProps,{duration:o,easing:n,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(this.showProps,{duration:o,easing:n,complete:d,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?"content-box"===h&&(r+=i.now):"content"!==a.options.heightStyle&&(i.now=Math.round(s-e.outerHeight()-r),r=0)}}),void 0):e.animate(this.hideProps,o,n,d):t.animate(this.showProps,o,n,d)},_toggleComplete:function(t){var e=t.oldPanel,i=e.prev();this._removeClass(e,"ui-accordion-content-active"),this._removeClass(i,"ui-accordion-header-active")._addClass(i,"ui-accordion-header-collapsed"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}}),t.widget("ui.menu",{version:"1.12.1",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("<span>").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)},_filterMenuItems:function(e){var i=e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(t.trim(t(this).children(".ui-menu-item-wrapper").text()))})}}),t.widget("ui.autocomplete",{version:"1.12.1",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return t.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")},this)},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({},e,{label:e.label||e.value,value:e.value||e.label})})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<div>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("<div>").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var d=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"<div>",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("<span class='ui-controlgroup-label-contents'></span>")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(d,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t("<span>"),this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon) +},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"<button>",options:{classes:{"ui-button":"ui-corner-all"},disabled:null,icon:null,iconPosition:"beginning",label:null,showLabel:!0},_getCreateOptions:function(){var t,e=this._super()||{};return this.isInput=this.element.is("input"),t=this.element[0].disabled,null!=t&&(e.disabled=t),this.originalLabel=this.isInput?this.element.val():this.element.html(),this.originalLabel&&(e.label=this.originalLabel),e},_create:function(){!this.option.showLabel&!this.options.icon&&(this.options.showLabel=!0),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled||!1),this.hasTitle=!!this.element.attr("title"),this.options.label&&this.options.label!==this.originalLabel&&(this.isInput?this.element.val(this.options.label):this.element.html(this.options.label)),this._addClass("ui-button","ui-widget"),this._setOption("disabled",this.options.disabled),this._enhance(),this.element.is("a")&&this._on({keyup:function(e){e.keyCode===t.ui.keyCode.SPACE&&(e.preventDefault(),this.element[0].click?this.element[0].click():this.element.trigger("click"))}})},_enhance:function(){this.element.is("button")||this.element.attr("role","button"),this.options.icon&&(this._updateIcon("icon",this.options.icon),this._updateTooltip())},_updateTooltip:function(){this.title=this.element.attr("title"),this.options.showLabel||this.title||this.element.attr("title",this.options.label)},_updateIcon:function(e,i){var s="iconPosition"!==e,n=s?this.options.iconPosition:i,o="top"===n||"bottom"===n;this.icon?s&&this._removeClass(this.icon,null,this.options.icon):(this.icon=t("<span>"),this._addClass(this.icon,"ui-button-icon","ui-icon"),this.options.showLabel||this._addClass("ui-button-icon-only")),s&&this._addClass(this.icon,null,i),this._attachIcon(n),o?(this._addClass(this.icon,null,"ui-widget-icon-block"),this.iconSpace&&this.iconSpace.remove()):(this.iconSpace||(this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-button-icon-space")),this._removeClass(this.icon,null,"ui-wiget-icon-block"),this._attachIconSpace(n))},_destroy:function(){this.element.removeAttr("role"),this.icon&&this.icon.remove(),this.iconSpace&&this.iconSpace.remove(),this.hasTitle||this.element.removeAttr("title")},_attachIconSpace:function(t){this.icon[/^(?:end|bottom)/.test(t)?"before":"after"](this.iconSpace)},_attachIcon:function(t){this.element[/^(?:end|bottom)/.test(t)?"append":"prepend"](this.icon)},_setOptions:function(t){var e=void 0===t.showLabel?this.options.showLabel:t.showLabel,i=void 0===t.icon?this.options.icon:t.icon;e||i||(t.showLabel=!0),this._super(t)},_setOption:function(t,e){"icon"===t&&(e?this._updateIcon(t,e):this.icon&&(this.icon.remove(),this.iconSpace&&this.iconSpace.remove())),"iconPosition"===t&&this._updateIcon(t,e),"showLabel"===t&&(this._toggleClass("ui-button-icon-only",null,!e),this._updateTooltip()),"label"===t&&(this.isInput?this.element.val(e):(this.element.html(e),this.icon&&(this._attachIcon(this.options.iconPosition),this._attachIconSpace(this.options.iconPosition)))),this._super(t,e),"disabled"===t&&(this._toggleClass(null,"ui-state-disabled",e),this.element[0].disabled=e,e&&this.element.blur())},refresh:function(){var t=this.element.is("input, button")?this.element[0].disabled:this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOptions({disabled:t}),this._updateTooltip()}}),t.uiBackCompat!==!1&&(t.widget("ui.button",t.ui.button,{options:{text:!0,icons:{primary:null,secondary:null}},_create:function(){this.options.showLabel&&!this.options.text&&(this.options.showLabel=this.options.text),!this.options.showLabel&&this.options.text&&(this.options.text=this.options.showLabel),this.options.icon||!this.options.icons.primary&&!this.options.icons.secondary?this.options.icon&&(this.options.icons.primary=this.options.icon):this.options.icons.primary?this.options.icon=this.options.icons.primary:(this.options.icon=this.options.icons.secondary,this.options.iconPosition="end"),this._super()},_setOption:function(t,e){return"text"===t?(this._super("showLabel",e),void 0):("showLabel"===t&&(this.options.text=e),"icon"===t&&(this.options.icons.primary=e),"icons"===t&&(e.primary?(this._super("icon",e.primary),this._super("iconPosition","beginning")):e.secondary&&(this._super("icon",e.secondary),this._super("iconPosition","end"))),this._superApply(arguments),void 0)}}),t.fn.button=function(e){return function(){return!this.length||this.length&&"INPUT"!==this[0].tagName||this.length&&"INPUT"===this[0].tagName&&"checkbox"!==this.attr("type")&&"radio"!==this.attr("type")?e.apply(this,arguments):(t.ui.checkboxradio||t.error("Checkboxradio widget missing"),0===arguments.length?this.checkboxradio({icon:!1}):this.checkboxradio.apply(this,arguments))}}(t.fn.button),t.fn.buttonset=function(){return t.ui.controlgroup||t.error("Controlgroup widget missing"),"option"===arguments[0]&&"items"===arguments[1]&&arguments[2]?this.controlgroup.apply(this,[arguments[0],"items.button",arguments[2]]):"option"===arguments[0]&&"items"===arguments[1]?this.controlgroup.apply(this,[arguments[0],"items.button"]):("object"==typeof arguments[0]&&arguments[0].items&&(arguments[0].items={button:arguments[0].items}),this.controlgroup.apply(this,arguments))}),t.ui.button,t.extend(t.ui,{datepicker:{version:"1.12.1"}});var p;t.extend(s.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return a(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var s=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?n(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).on("keydown",this._doKeyDown).on("keypress",this._doKeyPress).on("keyup",this._doKeyUp),this._autoSize(i),t.data(e,"datepicker",i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.off("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.on("focus",this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+r+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),p===n&&(p=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s))}},_updateDatepicker:function(e){this.maxRows=4,p=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":q?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":q?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=j?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="<div class='ui-datepicker-group",U[1]>1)switch(C){case 0:T+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left"); +break;case U[1]-1:T+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:T+=" ui-datepicker-group-middle",I=""}T+="'>"}for(T+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",P=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,P+="<th scope='col'"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(T+=P+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(A)+"</td>":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(A.getTime()===D.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===A.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!_?"":" "+E[1]+(A.getTime()===G.getTime()?" "+this._currentClass:"")+(A.getTime()===B.getTime()?" ui-datepicker-today":""))+"'"+(F&&!_||!E[2]?"":" title='"+E[2].replace(/'/g,"&#39;")+"'")+(L?"":" data-handler='selectDay' data-event='click' data-month='"+A.getMonth()+"' data-year='"+A.getFullYear()+"'")+">"+(F&&!_?"&#xa0;":L?"<span class='ui-state-default'>"+A.getDate()+"</span>":"<a class='ui-state-default"+(A.getTime()===B.getTime()?" ui-state-highlight":"")+(A.getTime()===G.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+A.getDate()+"</a>")+"</td>",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),T+="</tbody></table>"+(X?"</div>"+(U[0]>0&&C===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(v||(b+=y+(!o&&m&&_?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!_)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("<button type='button'></button>").button({label:t("<a>").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html("&#160;")},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("<button></button>",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("<a>").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("<div>").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("<div>").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div>").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"<select>",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=t()},_drawButton:function(){var e,i=this,s=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.focus(),t.preventDefault()}}),this.element.hide(),this.button=t("<span>",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),e=t("<span>").appendTo(this.button),this._addClass(e,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(s).appendTo(this.button),this.options.width!==!1&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){i._rendered||i._refreshMenu()})},_drawMenu:function(){var e=this;this.menu=t("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=t("<div>").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,i){t.preventDefault(),e._setSelection(),e._select(i.item.data("ui-selectmenu-item"),t)},focus:function(t,i){var s=i.item.data("ui-selectmenu-item");null!=e.focusIndex&&s.index!==e.focusIndex&&(e._trigger("focus",t,{item:s}),e.isOpen||e._select(s,t)),e.focusIndex=s.index,e.button.attr("aria-activedescendant",e.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t,e=this.element.find("option");this.menu.empty(),this._parseOptions(e),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,e.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(t.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(e){var i=t("<span>");return this._setText(i,e.label),this._addClass(i,"ui-selectmenu-text"),i},_renderMenu:function(e,i){var s=this,n="";t.each(i,function(i,o){var a;o.optgroup!==n&&(a=t("<li>",{text:o.optgroup}),s._addClass(a,"ui-selectmenu-optgroup","ui-menu-divider"+(o.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),a.appendTo(e),n=o.optgroup),s._renderItemData(e,o)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(e,i){var s=t("<li>"),n=t("<div>",{title:i.element.attr("title")});return i.disabled&&this._addClass(s,null,"ui-state-disabled"),this._setText(n,i.label),s.append(n).appendTo(e)},_setText:function(t,e){e?t.text(e):t.html("&#160;")},_move:function(t,e){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),n+=":not(.ui-state-disabled)"),s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](n).eq(-1):i[t+"All"](n).eq(0),s.length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?(t=window.getSelection(),t.removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(e){this.isOpen&&(t(e.target).closest(".ui-selectmenu-menu, #"+t.ui.escapeSelector(this.ids.button)).length||this.close(e))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection(),t.rangeCount&&(this.range=t.getRangeAt(0))):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(e){var i=!0;switch(e.keyCode){case t.ui.keyCode.TAB:case t.ui.keyCode.ESCAPE:this.close(e),i=!1;break;case t.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(e);break;case t.ui.keyCode.UP:e.altKey?this._toggle(e):this._move("prev",e);break;case t.ui.keyCode.DOWN:e.altKey?this._toggle(e):this._move("next",e);break;case t.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(e):this._toggle(e);break;case t.ui.keyCode.LEFT:this._move("prev",e);break;case t.ui.keyCode.RIGHT:this._move("next",e);break;case t.ui.keyCode.HOME:case t.ui.keyCode.PAGE_UP:this._move("first",e);break;case t.ui.keyCode.END:case t.ui.keyCode.PAGE_DOWN:this._move("last",e);break;default:this.menu.trigger(e),i=!1}i&&e.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){var e=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":e,"aria-activedescendant":e}),this.menu.attr("aria-activedescendant",e)},_setOption:function(t,e){if("icons"===t){var i=this.button.find("span.ui-icon");this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)}this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;return t===!1?(this.button.css("width",""),void 0):(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t),void 0)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(e){var i=this,s=[];e.each(function(e,n){s.push(i._parseOption(t(n),e))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="<span tabindex='0'></span>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("<div>").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null) +},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}}),t.widget("ui.spinner",{version:"1.12.1",defaultElement:"<input>",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("<span>").parent().append("<a></a><a></a>")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return"<span>"},_buttonHtml:function(){return"<a></a><a></a>"}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("<div>").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e] +}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("<div>").attr("role","tooltip"),s=t("<div>").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip;var f="ui-effects-",g="ui-effects-style",m="ui-effects-animated",_=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(_),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(_.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(m)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(f+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(f+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(g,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(g)||"",t.removeData(g)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(f+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=f+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(m),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(m,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var v=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var v;t.uiBackCompat!==!1&&(v=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)}))}); \ No newline at end of file diff --git a/static/app2/js/jquery.cookie.js b/static/app2/js/jquery.cookie.js new file mode 100755 index 0000000..c7f3a59 --- /dev/null +++ b/static/app2/js/jquery.cookie.js @@ -0,0 +1,117 @@ +/*! + * jQuery Cookie Plugin v1.4.1 + * https://github.com/carhartl/jquery-cookie + * + * Copyright 2013 Klaus Hartl + * Released under the MIT license + */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // CommonJS + 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 (value !== undefined && !$.isFunction(value)) { + options = $.extend({}, config.defaults, options); + + if (typeof options.expires === 'number') { + var days = options.expires, t = options.expires = new Date(); + t.setTime(+t + 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(). + var cookies = document.cookie ? document.cookie.split('; ') : []; + + for (var i = 0, l = cookies.length; i < l; i++) { + var parts = cookies[i].split('='); + var name = decode(parts.shift()); + var cookie = parts.join('='); + + if (key && 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) { + if ($.cookie(key) === undefined) { + return false; + } + + // Must not alter options, thus extending a fresh object... + $.cookie(key, '', $.extend({}, options, { expires: -1 })); + return !$.cookie(key); + }; + +})); diff --git a/static/app2/js/jquery.qtip.min.js b/static/app2/js/jquery.qtip.min.js new file mode 100755 index 0000000..d2f28c5 --- /dev/null +++ b/static/app2/js/jquery.qtip.min.js @@ -0,0 +1,5 @@ +/* qtip2 v3.0.3 | Plugins: tips modal viewport svg imagemap ie6 | Styles: core basic css3 | qtip2.com | Licensed MIT | Wed May 11 2016 22:31:31 */ + +!function(a,b,c){!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):jQuery&&!jQuery.fn.qtip&&a(jQuery)}(function(d){"use strict";function e(a,b,c,e){this.id=c,this.target=a,this.tooltip=F,this.elements={target:a},this._id=S+"-"+c,this.timers={img:{}},this.options=b,this.plugins={},this.cache={event:{},target:d(),disabled:E,attr:e,onTooltip:E,lastClass:""},this.rendered=this.destroyed=this.disabled=this.waiting=this.hiddenDuringWait=this.positioning=this.triggering=E}function f(a){return a===F||"object"!==d.type(a)}function g(a){return!(d.isFunction(a)||a&&a.attr||a.length||"object"===d.type(a)&&(a.jquery||a.then))}function h(a){var b,c,e,h;return f(a)?E:(f(a.metadata)&&(a.metadata={type:a.metadata}),"content"in a&&(b=a.content,f(b)||b.jquery||b.done?(c=g(b)?E:b,b=a.content={text:c}):c=b.text,"ajax"in b&&(e=b.ajax,h=e&&e.once!==E,delete b.ajax,b.text=function(a,b){var f=c||d(this).attr(b.options.content.attr)||"Loading...",g=d.ajax(d.extend({},e,{context:b})).then(e.success,F,e.error).then(function(a){return a&&h&&b.set("content.text",a),a},function(a,c,d){b.destroyed||0===a.status||b.set("content.text",c+": "+d)});return h?f:(b.set("content.text",f),g)}),"title"in b&&(d.isPlainObject(b.title)&&(b.button=b.title.button,b.title=b.title.text),g(b.title||E)&&(b.title=E))),"position"in a&&f(a.position)&&(a.position={my:a.position,at:a.position}),"show"in a&&f(a.show)&&(a.show=a.show.jquery?{target:a.show}:a.show===D?{ready:D}:{event:a.show}),"hide"in a&&f(a.hide)&&(a.hide=a.hide.jquery?{target:a.hide}:{event:a.hide}),"style"in a&&f(a.style)&&(a.style={classes:a.style}),d.each(R,function(){this.sanitize&&this.sanitize(a)}),a)}function i(a,b){for(var c,d=0,e=a,f=b.split(".");e=e[f[d++]];)d<f.length&&(c=e);return[c||a,f.pop()]}function j(a,b){var c,d,e;for(c in this.checks)if(this.checks.hasOwnProperty(c))for(d in this.checks[c])this.checks[c].hasOwnProperty(d)&&(e=new RegExp(d,"i").exec(a))&&(b.push(e),("builtin"===c||this.plugins[c])&&this.checks[c][d].apply(this.plugins[c]||this,b))}function k(a){return V.concat("").join(a?"-"+a+" ":" ")}function l(a,b){return b>0?setTimeout(d.proxy(a,this),b):void a.call(this)}function m(a){this.tooltip.hasClass(aa)||(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this.timers.show=l.call(this,function(){this.toggle(D,a)},this.options.show.delay))}function n(a){if(!this.tooltip.hasClass(aa)&&!this.destroyed){var b=d(a.relatedTarget),c=b.closest(W)[0]===this.tooltip[0],e=b[0]===this.options.show.target[0];if(clearTimeout(this.timers.show),clearTimeout(this.timers.hide),this!==b[0]&&"mouse"===this.options.position.target&&c||this.options.hide.fixed&&/mouse(out|leave|move)/.test(a.type)&&(c||e))try{a.preventDefault(),a.stopImmediatePropagation()}catch(f){}else this.timers.hide=l.call(this,function(){this.toggle(E,a)},this.options.hide.delay,this)}}function o(a){!this.tooltip.hasClass(aa)&&this.options.hide.inactive&&(clearTimeout(this.timers.inactive),this.timers.inactive=l.call(this,function(){this.hide(a)},this.options.hide.inactive))}function p(a){this.rendered&&this.tooltip[0].offsetWidth>0&&this.reposition(a)}function q(a,c,e){d(b.body).delegate(a,(c.split?c:c.join("."+S+" "))+"."+S,function(){var a=y.api[d.attr(this,U)];a&&!a.disabled&&e.apply(a,arguments)})}function r(a,c,f){var g,i,j,k,l,m=d(b.body),n=a[0]===b?m:a,o=a.metadata?a.metadata(f.metadata):F,p="html5"===f.metadata.type&&o?o[f.metadata.name]:F,q=a.data(f.metadata.name||"qtipopts");try{q="string"==typeof q?d.parseJSON(q):q}catch(r){}if(k=d.extend(D,{},y.defaults,f,"object"==typeof q?h(q):F,h(p||o)),i=k.position,k.id=c,"boolean"==typeof k.content.text){if(j=a.attr(k.content.attr),k.content.attr===E||!j)return E;k.content.text=j}if(i.container.length||(i.container=m),i.target===E&&(i.target=n),k.show.target===E&&(k.show.target=n),k.show.solo===D&&(k.show.solo=i.container.closest("body")),k.hide.target===E&&(k.hide.target=n),k.position.viewport===D&&(k.position.viewport=i.container),i.container=i.container.eq(0),i.at=new A(i.at,D),i.my=new A(i.my),a.data(S))if(k.overwrite)a.qtip("destroy",!0);else if(k.overwrite===E)return E;return a.attr(T,c),k.suppress&&(l=a.attr("title"))&&a.removeAttr("title").attr(ca,l).attr("title",""),g=new e(a,k,c,!!j),a.data(S,g),g}function s(a){return a.charAt(0).toUpperCase()+a.slice(1)}function t(a,b){var d,e,f=b.charAt(0).toUpperCase()+b.slice(1),g=(b+" "+va.join(f+" ")+f).split(" "),h=0;if(ua[b])return a.css(ua[b]);for(;d=g[h++];)if((e=a.css(d))!==c)return ua[b]=d,e}function u(a,b){return Math.ceil(parseFloat(t(a,b)))}function v(a,b){this._ns="tip",this.options=b,this.offset=b.offset,this.size=[b.width,b.height],this.qtip=a,this.init(a)}function w(a,b){this.options=b,this._ns="-modal",this.qtip=a,this.init(a)}function x(a){this._ns="ie6",this.qtip=a,this.init(a)}var y,z,A,B,C,D=!0,E=!1,F=null,G="x",H="y",I="width",J="height",K="top",L="left",M="bottom",N="right",O="center",P="flipinvert",Q="shift",R={},S="qtip",T="data-hasqtip",U="data-qtip-id",V=["ui-widget","ui-tooltip"],W="."+S,X="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),Y=S+"-fixed",Z=S+"-default",$=S+"-focus",_=S+"-hover",aa=S+"-disabled",ba="_replacedByqTip",ca="oldtitle",da={ie:function(){var a,c;for(a=4,c=b.createElement("div");(c.innerHTML="<!--[if gt IE "+a+"]><i></i><![endif]-->")&&c.getElementsByTagName("i")[0];a+=1);return a>4?a:NaN}(),iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,5})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_",".").replace("_",""))||E};z=e.prototype,z._when=function(a){return d.when.apply(d,a)},z.render=function(a){if(this.rendered||this.destroyed)return this;var b=this,c=this.options,e=this.cache,f=this.elements,g=c.content.text,h=c.content.title,i=c.content.button,j=c.position,k=[];return d.attr(this.target[0],"aria-describedby",this._id),e.posClass=this._createPosClass((this.position={my:j.my,at:j.at}).my),this.tooltip=f.tooltip=d("<div/>",{id:this._id,"class":[S,Z,c.style.classes,e.posClass].join(" "),width:c.style.width||"",height:c.style.height||"",tracking:"mouse"===j.target&&j.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":E,"aria-describedby":this._id+"-content","aria-hidden":D}).toggleClass(aa,this.disabled).attr(U,this.id).data(S,this).appendTo(j.container).append(f.content=d("<div />",{"class":S+"-content",id:this._id+"-content","aria-atomic":D})),this.rendered=-1,this.positioning=D,h&&(this._createTitle(),d.isFunction(h)||k.push(this._updateTitle(h,E))),i&&this._createButton(),d.isFunction(g)||k.push(this._updateContent(g,E)),this.rendered=D,this._setWidget(),d.each(R,function(a){var c;"render"===this.initialize&&(c=this(b))&&(b.plugins[a]=c)}),this._unassignEvents(),this._assignEvents(),this._when(k).then(function(){b._trigger("render"),b.positioning=E,b.hiddenDuringWait||!c.show.ready&&!a||b.toggle(D,e.event,E),b.hiddenDuringWait=E}),y.api[this.id]=this,this},z.destroy=function(a){function b(){if(!this.destroyed){this.destroyed=D;var a,b=this.target,c=b.attr(ca);this.rendered&&this.tooltip.stop(1,0).find("*").remove().end().remove(),d.each(this.plugins,function(){this.destroy&&this.destroy()});for(a in this.timers)this.timers.hasOwnProperty(a)&&clearTimeout(this.timers[a]);b.removeData(S).removeAttr(U).removeAttr(T).removeAttr("aria-describedby"),this.options.suppress&&c&&b.attr("title",c).removeAttr(ca),this._unassignEvents(),this.options=this.elements=this.cache=this.timers=this.plugins=this.mouse=F,delete y.api[this.id]}}return this.destroyed?this.target:(a===D&&"hide"!==this.triggering||!this.rendered?b.call(this):(this.tooltip.one("tooltiphidden",d.proxy(b,this)),!this.triggering&&this.hide()),this.target)},B=z.checks={builtin:{"^id$":function(a,b,c,e){var f=c===D?y.nextid:c,g=S+"-"+f;f!==E&&f.length>0&&!d("#"+g).length?(this._id=g,this.rendered&&(this.tooltip[0].id=this._id,this.elements.content[0].id=this._id+"-content",this.elements.title[0].id=this._id+"-title")):a[b]=e},"^prerender":function(a,b,c){c&&!this.rendered&&this.render(this.options.show.ready)},"^content.text$":function(a,b,c){this._updateContent(c)},"^content.attr$":function(a,b,c,d){this.options.content.text===this.target.attr(d)&&this._updateContent(this.target.attr(c))},"^content.title$":function(a,b,c){return c?(c&&!this.elements.title&&this._createTitle(),void this._updateTitle(c)):this._removeTitle()},"^content.button$":function(a,b,c){this._updateButton(c)},"^content.title.(text|button)$":function(a,b,c){this.set("content."+b,c)},"^position.(my|at)$":function(a,b,c){"string"==typeof c&&(this.position[b]=a[b]=new A(c,"at"===b))},"^position.container$":function(a,b,c){this.rendered&&this.tooltip.appendTo(c)},"^show.ready$":function(a,b,c){c&&(!this.rendered&&this.render(D)||this.toggle(D))},"^style.classes$":function(a,b,c,d){this.rendered&&this.tooltip.removeClass(d).addClass(c)},"^style.(width|height)":function(a,b,c){this.rendered&&this.tooltip.css(b,c)},"^style.widget|content.title":function(){this.rendered&&this._setWidget()},"^style.def":function(a,b,c){this.rendered&&this.tooltip.toggleClass(Z,!!c)},"^events.(render|show|move|hide|focus|blur)$":function(a,b,c){this.rendered&&this.tooltip[(d.isFunction(c)?"":"un")+"bind"]("tooltip"+b,c)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){if(this.rendered){var a=this.options.position;this.tooltip.attr("tracking","mouse"===a.target&&a.adjust.mouse),this._unassignEvents(),this._assignEvents()}}}},z.get=function(a){if(this.destroyed)return this;var b=i(this.options,a.toLowerCase()),c=b[0][b[1]];return c.precedance?c.string():c};var ea=/^position\.(my|at|adjust|target|container|viewport)|style|content|show\.ready/i,fa=/^prerender|show\.ready/i;z.set=function(a,b){if(this.destroyed)return this;var c,e=this.rendered,f=E,g=this.options;return"string"==typeof a?(c=a,a={},a[c]=b):a=d.extend({},a),d.each(a,function(b,c){if(e&&fa.test(b))return void delete a[b];var h,j=i(g,b.toLowerCase());h=j[0][j[1]],j[0][j[1]]=c&&c.nodeType?d(c):c,f=ea.test(b)||f,a[b]=[j[0],j[1],c,h]}),h(g),this.positioning=D,d.each(a,d.proxy(j,this)),this.positioning=E,this.rendered&&this.tooltip[0].offsetWidth>0&&f&&this.reposition("mouse"===g.position.target?F:this.cache.event),this},z._update=function(a,b){var c=this,e=this.cache;return this.rendered&&a?(d.isFunction(a)&&(a=a.call(this.elements.target,e.event,this)||""),d.isFunction(a.then)?(e.waiting=D,a.then(function(a){return e.waiting=E,c._update(a,b)},F,function(a){return c._update(a,b)})):a===E||!a&&""!==a?E:(a.jquery&&a.length>0?b.empty().append(a.css({display:"block",visibility:"visible"})):b.html(a),this._waitForContent(b).then(function(a){c.rendered&&c.tooltip[0].offsetWidth>0&&c.reposition(e.event,!a.length)}))):E},z._waitForContent=function(a){var b=this.cache;return b.waiting=D,(d.fn.imagesLoaded?a.imagesLoaded():(new d.Deferred).resolve([])).done(function(){b.waiting=E}).promise()},z._updateContent=function(a,b){this._update(a,this.elements.content,b)},z._updateTitle=function(a,b){this._update(a,this.elements.title,b)===E&&this._removeTitle(E)},z._createTitle=function(){var a=this.elements,b=this._id+"-title";a.titlebar&&this._removeTitle(),a.titlebar=d("<div />",{"class":S+"-titlebar "+(this.options.style.widget?k("header"):"")}).append(a.title=d("<div />",{id:b,"class":S+"-title","aria-atomic":D})).insertBefore(a.content).delegate(".qtip-close","mousedown keydown mouseup keyup mouseout",function(a){d(this).toggleClass("ui-state-active ui-state-focus","down"===a.type.substr(-4))}).delegate(".qtip-close","mouseover mouseout",function(a){d(this).toggleClass("ui-state-hover","mouseover"===a.type)}),this.options.content.button&&this._createButton()},z._removeTitle=function(a){var b=this.elements;b.title&&(b.titlebar.remove(),b.titlebar=b.title=b.button=F,a!==E&&this.reposition())},z._createPosClass=function(a){return S+"-pos-"+(a||this.options.position.my).abbrev()},z.reposition=function(c,e){if(!this.rendered||this.positioning||this.destroyed)return this;this.positioning=D;var f,g,h,i,j=this.cache,k=this.tooltip,l=this.options.position,m=l.target,n=l.my,o=l.at,p=l.viewport,q=l.container,r=l.adjust,s=r.method.split(" "),t=k.outerWidth(E),u=k.outerHeight(E),v=0,w=0,x=k.css("position"),y={left:0,top:0},z=k[0].offsetWidth>0,A=c&&"scroll"===c.type,B=d(a),C=q[0].ownerDocument,F=this.mouse;if(d.isArray(m)&&2===m.length)o={x:L,y:K},y={left:m[0],top:m[1]};else if("mouse"===m)o={x:L,y:K},(!r.mouse||this.options.hide.distance)&&j.origin&&j.origin.pageX?c=j.origin:!c||c&&("resize"===c.type||"scroll"===c.type)?c=j.event:F&&F.pageX&&(c=F),"static"!==x&&(y=q.offset()),C.body.offsetWidth!==(a.innerWidth||C.documentElement.clientWidth)&&(g=d(b.body).offset()),y={left:c.pageX-y.left+(g&&g.left||0),top:c.pageY-y.top+(g&&g.top||0)},r.mouse&&A&&F&&(y.left-=(F.scrollX||0)-B.scrollLeft(),y.top-=(F.scrollY||0)-B.scrollTop());else{if("event"===m?c&&c.target&&"scroll"!==c.type&&"resize"!==c.type?j.target=d(c.target):c.target||(j.target=this.elements.target):"event"!==m&&(j.target=d(m.jquery?m:this.elements.target)),m=j.target,m=d(m).eq(0),0===m.length)return this;m[0]===b||m[0]===a?(v=da.iOS?a.innerWidth:m.width(),w=da.iOS?a.innerHeight:m.height(),m[0]===a&&(y={top:(p||m).scrollTop(),left:(p||m).scrollLeft()})):R.imagemap&&m.is("area")?f=R.imagemap(this,m,o,R.viewport?s:E):R.svg&&m&&m[0].ownerSVGElement?f=R.svg(this,m,o,R.viewport?s:E):(v=m.outerWidth(E),w=m.outerHeight(E),y=m.offset()),f&&(v=f.width,w=f.height,g=f.offset,y=f.position),y=this.reposition.offset(m,y,q),(da.iOS>3.1&&da.iOS<4.1||da.iOS>=4.3&&da.iOS<4.33||!da.iOS&&"fixed"===x)&&(y.left-=B.scrollLeft(),y.top-=B.scrollTop()),(!f||f&&f.adjustable!==E)&&(y.left+=o.x===N?v:o.x===O?v/2:0,y.top+=o.y===M?w:o.y===O?w/2:0)}return y.left+=r.x+(n.x===N?-t:n.x===O?-t/2:0),y.top+=r.y+(n.y===M?-u:n.y===O?-u/2:0),R.viewport?(h=y.adjusted=R.viewport(this,y,l,v,w,t,u),g&&h.left&&(y.left+=g.left),g&&h.top&&(y.top+=g.top),h.my&&(this.position.my=h.my)):y.adjusted={left:0,top:0},j.posClass!==(i=this._createPosClass(this.position.my))&&(j.posClass=i,k.removeClass(j.posClass).addClass(i)),this._trigger("move",[y,p.elem||p],c)?(delete y.adjusted,e===E||!z||isNaN(y.left)||isNaN(y.top)||"mouse"===m||!d.isFunction(l.effect)?k.css(y):d.isFunction(l.effect)&&(l.effect.call(k,this,d.extend({},y)),k.queue(function(a){d(this).css({opacity:"",height:""}),da.ie&&this.style.removeAttribute("filter"),a()})),this.positioning=E,this):this},z.reposition.offset=function(a,c,e){function f(a,b){c.left+=b*a.scrollLeft(),c.top+=b*a.scrollTop()}if(!e[0])return c;var g,h,i,j,k=d(a[0].ownerDocument),l=!!da.ie&&"CSS1Compat"!==b.compatMode,m=e[0];do"static"!==(h=d.css(m,"position"))&&("fixed"===h?(i=m.getBoundingClientRect(),f(k,-1)):(i=d(m).position(),i.left+=parseFloat(d.css(m,"borderLeftWidth"))||0,i.top+=parseFloat(d.css(m,"borderTopWidth"))||0),c.left-=i.left+(parseFloat(d.css(m,"marginLeft"))||0),c.top-=i.top+(parseFloat(d.css(m,"marginTop"))||0),g||"hidden"===(j=d.css(m,"overflow"))||"visible"===j||(g=d(m)));while(m=m.offsetParent);return g&&(g[0]!==k[0]||l)&&f(g,1),c};var ga=(A=z.reposition.Corner=function(a,b){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,O).toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase(),this.forceY=!!b;var c=a.charAt(0);this.precedance="t"===c||"b"===c?H:G}).prototype;ga.invert=function(a,b){this[a]=this[a]===L?N:this[a]===N?L:b||this[a]},ga.string=function(a){var b=this.x,c=this.y,d=b!==c?"center"===b||"center"!==c&&(this.precedance===H||this.forceY)?[c,b]:[b,c]:[b];return a!==!1?d.join(" "):d},ga.abbrev=function(){var a=this.string(!1);return a[0].charAt(0)+(a[1]&&a[1].charAt(0)||"")},ga.clone=function(){return new A(this.string(),this.forceY)},z.toggle=function(a,c){var e=this.cache,f=this.options,g=this.tooltip;if(c){if(/over|enter/.test(c.type)&&e.event&&/out|leave/.test(e.event.type)&&f.show.target.add(c.target).length===f.show.target.length&&g.has(c.relatedTarget).length)return this;e.event=d.event.fix(c)}if(this.waiting&&!a&&(this.hiddenDuringWait=D),!this.rendered)return a?this.render(1):this;if(this.destroyed||this.disabled)return this;var h,i,j,k=a?"show":"hide",l=this.options[k],m=this.options.position,n=this.options.content,o=this.tooltip.css("width"),p=this.tooltip.is(":visible"),q=a||1===l.target.length,r=!c||l.target.length<2||e.target[0]===c.target;return(typeof a).search("boolean|number")&&(a=!p),h=!g.is(":animated")&&p===a&&r,i=h?F:!!this._trigger(k,[90]),this.destroyed?this:(i!==E&&a&&this.focus(c),!i||h?this:(d.attr(g[0],"aria-hidden",!a),a?(this.mouse&&(e.origin=d.event.fix(this.mouse)),d.isFunction(n.text)&&this._updateContent(n.text,E),d.isFunction(n.title)&&this._updateTitle(n.title,E),!C&&"mouse"===m.target&&m.adjust.mouse&&(d(b).bind("mousemove."+S,this._storeMouse),C=D),o||g.css("width",g.outerWidth(E)),this.reposition(c,arguments[2]),o||g.css("width",""),l.solo&&("string"==typeof l.solo?d(l.solo):d(W,l.solo)).not(g).not(l.target).qtip("hide",new d.Event("tooltipsolo"))):(clearTimeout(this.timers.show),delete e.origin,C&&!d(W+'[tracking="true"]:visible',l.solo).not(g).length&&(d(b).unbind("mousemove."+S),C=E),this.blur(c)),j=d.proxy(function(){a?(da.ie&&g[0].style.removeAttribute("filter"),g.css("overflow",""),"string"==typeof l.autofocus&&d(this.options.show.autofocus,g).focus(),this.options.show.target.trigger("qtip-"+this.id+"-inactive")):g.css({display:"",visibility:"",opacity:"",left:"",top:""}),this._trigger(a?"visible":"hidden")},this),l.effect===E||q===E?(g[k](),j()):d.isFunction(l.effect)?(g.stop(1,1),l.effect.call(g,this),g.queue("fx",function(a){j(),a()})):g.fadeTo(90,a?1:0,j),a&&l.target.trigger("qtip-"+this.id+"-inactive"),this))},z.show=function(a){return this.toggle(D,a)},z.hide=function(a){return this.toggle(E,a)},z.focus=function(a){if(!this.rendered||this.destroyed)return this;var b=d(W),c=this.tooltip,e=parseInt(c[0].style.zIndex,10),f=y.zindex+b.length;return c.hasClass($)||this._trigger("focus",[f],a)&&(e!==f&&(b.each(function(){this.style.zIndex>e&&(this.style.zIndex=this.style.zIndex-1)}),b.filter("."+$).qtip("blur",a)),c.addClass($)[0].style.zIndex=f),this},z.blur=function(a){return!this.rendered||this.destroyed?this:(this.tooltip.removeClass($),this._trigger("blur",[this.tooltip.css("zIndex")],a),this)},z.disable=function(a){return this.destroyed?this:("toggle"===a?a=!(this.rendered?this.tooltip.hasClass(aa):this.disabled):"boolean"!=typeof a&&(a=D),this.rendered&&this.tooltip.toggleClass(aa,a).attr("aria-disabled",a),this.disabled=!!a,this)},z.enable=function(){return this.disable(E)},z._createButton=function(){var a=this,b=this.elements,c=b.tooltip,e=this.options.content.button,f="string"==typeof e,g=f?e:"Close tooltip";b.button&&b.button.remove(),e.jquery?b.button=e:b.button=d("<a />",{"class":"qtip-close "+(this.options.style.widget?"":S+"-icon"),title:g,"aria-label":g}).prepend(d("<span />",{"class":"ui-icon ui-icon-close",html:"&times;"})),b.button.appendTo(b.titlebar||c).attr("role","button").click(function(b){return c.hasClass(aa)||a.hide(b),E})},z._updateButton=function(a){if(!this.rendered)return E;var b=this.elements.button;a?this._createButton():b.remove()},z._setWidget=function(){var a=this.options.style.widget,b=this.elements,c=b.tooltip,d=c.hasClass(aa);c.removeClass(aa),aa=a?"ui-state-disabled":"qtip-disabled",c.toggleClass(aa,d),c.toggleClass("ui-helper-reset "+k(),a).toggleClass(Z,this.options.style.def&&!a),b.content&&b.content.toggleClass(k("content"),a),b.titlebar&&b.titlebar.toggleClass(k("header"),a),b.button&&b.button.toggleClass(S+"-icon",!a)},z._storeMouse=function(a){return(this.mouse=d.event.fix(a)).type="mousemove",this},z._bind=function(a,b,c,e,f){if(a&&c&&b.length){var g="."+this._id+(e?"-"+e:"");return d(a).bind((b.split?b:b.join(g+" "))+g,d.proxy(c,f||this)),this}},z._unbind=function(a,b){return a&&d(a).unbind("."+this._id+(b?"-"+b:"")),this},z._trigger=function(a,b,c){var e=new d.Event("tooltip"+a);return e.originalEvent=c&&d.extend({},c)||this.cache.event||F,this.triggering=a,this.tooltip.trigger(e,[this].concat(b||[])),this.triggering=E,!e.isDefaultPrevented()},z._bindEvents=function(a,b,c,e,f,g){var h=c.filter(e).add(e.filter(c)),i=[];h.length&&(d.each(b,function(b,c){var e=d.inArray(c,a);e>-1&&i.push(a.splice(e,1)[0])}),i.length&&(this._bind(h,i,function(a){var b=this.rendered?this.tooltip[0].offsetWidth>0:!1;(b?g:f).call(this,a)}),c=c.not(h),e=e.not(h))),this._bind(c,a,f),this._bind(e,b,g)},z._assignInitialEvents=function(a){function b(a){return this.disabled||this.destroyed?E:(this.cache.event=a&&d.event.fix(a),this.cache.target=a&&d(a.target),clearTimeout(this.timers.show),void(this.timers.show=l.call(this,function(){this.render("object"==typeof a||c.show.ready)},c.prerender?0:c.show.delay)))}var c=this.options,e=c.show.target,f=c.hide.target,g=c.show.event?d.trim(""+c.show.event).split(" "):[],h=c.hide.event?d.trim(""+c.hide.event).split(" "):[];this._bind(this.elements.target,["remove","removeqtip"],function(){this.destroy(!0)},"destroy"),/mouse(over|enter)/i.test(c.show.event)&&!/mouse(out|leave)/i.test(c.hide.event)&&h.push("mouseleave"),this._bind(e,"mousemove",function(a){this._storeMouse(a),this.cache.onTarget=D}),this._bindEvents(g,h,e,f,b,function(){return this.timers?void clearTimeout(this.timers.show):E}),(c.show.ready||c.prerender)&&b.call(this,a)},z._assignEvents=function(){var c=this,e=this.options,f=e.position,g=this.tooltip,h=e.show.target,i=e.hide.target,j=f.container,k=f.viewport,l=d(b),q=d(a),r=e.show.event?d.trim(""+e.show.event).split(" "):[],s=e.hide.event?d.trim(""+e.hide.event).split(" "):[];d.each(e.events,function(a,b){c._bind(g,"toggle"===a?["tooltipshow","tooltiphide"]:["tooltip"+a],b,null,g)}),/mouse(out|leave)/i.test(e.hide.event)&&"window"===e.hide.leave&&this._bind(l,["mouseout","blur"],function(a){/select|option/.test(a.target.nodeName)||a.relatedTarget||this.hide(a)}),e.hide.fixed?i=i.add(g.addClass(Y)):/mouse(over|enter)/i.test(e.show.event)&&this._bind(i,"mouseleave",function(){clearTimeout(this.timers.show)}),(""+e.hide.event).indexOf("unfocus")>-1&&this._bind(j.closest("html"),["mousedown","touchstart"],function(a){var b=d(a.target),c=this.rendered&&!this.tooltip.hasClass(aa)&&this.tooltip[0].offsetWidth>0,e=b.parents(W).filter(this.tooltip[0]).length>0;b[0]===this.target[0]||b[0]===this.tooltip[0]||e||this.target.has(b[0]).length||!c||this.hide(a)}),"number"==typeof e.hide.inactive&&(this._bind(h,"qtip-"+this.id+"-inactive",o,"inactive"),this._bind(i.add(g),y.inactiveEvents,o)),this._bindEvents(r,s,h,i,m,n),this._bind(h.add(g),"mousemove",function(a){if("number"==typeof e.hide.distance){var b=this.cache.origin||{},c=this.options.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&this.hide(a)}this._storeMouse(a)}),"mouse"===f.target&&f.adjust.mouse&&(e.hide.event&&this._bind(h,["mouseenter","mouseleave"],function(a){return this.cache?void(this.cache.onTarget="mouseenter"===a.type):E}),this._bind(l,"mousemove",function(a){this.rendered&&this.cache.onTarget&&!this.tooltip.hasClass(aa)&&this.tooltip[0].offsetWidth>0&&this.reposition(a)})),(f.adjust.resize||k.length)&&this._bind(d.event.special.resize?k:q,"resize",p),f.adjust.scroll&&this._bind(q.add(f.container),"scroll",p)},z._unassignEvents=function(){var c=this.options,e=c.show.target,f=c.hide.target,g=d.grep([this.elements.target[0],this.rendered&&this.tooltip[0],c.position.container[0],c.position.viewport[0],c.position.container.closest("html")[0],a,b],function(a){return"object"==typeof a});e&&e.toArray&&(g=g.concat(e.toArray())),f&&f.toArray&&(g=g.concat(f.toArray())),this._unbind(g)._unbind(g,"destroy")._unbind(g,"inactive")},d(function(){q(W,["mouseenter","mouseleave"],function(a){var b="mouseenter"===a.type,c=d(a.currentTarget),e=d(a.relatedTarget||a.target),f=this.options;b?(this.focus(a),c.hasClass(Y)&&!c.hasClass(aa)&&clearTimeout(this.timers.hide)):"mouse"===f.position.target&&f.position.adjust.mouse&&f.hide.event&&f.show.target&&!e.closest(f.show.target[0]).length&&this.hide(a),c.toggleClass(_,b)}),q("["+U+"]",X,o)}),y=d.fn.qtip=function(a,b,e){var f=(""+a).toLowerCase(),g=F,i=d.makeArray(arguments).slice(1),j=i[i.length-1],k=this[0]?d.data(this[0],S):F;return!arguments.length&&k||"api"===f?k:"string"==typeof a?(this.each(function(){var a=d.data(this,S);if(!a)return D;if(j&&j.timeStamp&&(a.cache.event=j),!b||"option"!==f&&"options"!==f)a[f]&&a[f].apply(a,i);else{if(e===c&&!d.isPlainObject(b))return g=a.get(b),E;a.set(b,e)}}),g!==F?g:this):"object"!=typeof a&&arguments.length?void 0:(k=h(d.extend(D,{},a)),this.each(function(a){var b,c;return c=d.isArray(k.id)?k.id[a]:k.id,c=!c||c===E||c.length<1||y.api[c]?y.nextid++:c,b=r(d(this),c,k),b===E?D:(y.api[c]=b,d.each(R,function(){"initialize"===this.initialize&&this(b)}),void b._assignInitialEvents(j))}))},d.qtip=e,y.api={},d.each({attr:function(a,b){if(this.length){var c=this[0],e="title",f=d.data(c,"qtip");if(a===e&&f&&f.options&&"object"==typeof f&&"object"==typeof f.options&&f.options.suppress)return arguments.length<2?d.attr(c,ca):(f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",b),this.attr(ca,b))}return d.fn["attr"+ba].apply(this,arguments)},clone:function(a){var b=d.fn["clone"+ba].apply(this,arguments);return a||b.filter("["+ca+"]").attr("title",function(){return d.attr(this,ca)}).removeAttr(ca),b}},function(a,b){if(!b||d.fn[a+ba])return D;var c=d.fn[a+ba]=d.fn[a];d.fn[a]=function(){return b.apply(this,arguments)||c.apply(this,arguments)}}),d.ui||(d["cleanData"+ba]=d.cleanData,d.cleanData=function(a){for(var b,c=0;(b=d(a[c])).length;c++)if(b.attr(T))try{b.triggerHandler("removeqtip")}catch(e){}d["cleanData"+ba].apply(this,arguments)}),y.version="3.0.3",y.nextid=0,y.inactiveEvents=X,y.zindex=15e3,y.defaults={prerender:E,id:E,overwrite:D,suppress:D,content:{text:D,attr:"title",title:E,button:E},position:{my:"top left",at:"bottom right",target:E,container:E,viewport:E,adjust:{x:0,y:0,mouse:D,scroll:D,resize:D,method:"flipinvert flipinvert"},effect:function(a,b){d(this).animate(b,{duration:200,queue:E})}},show:{target:E,event:"mouseenter",effect:D,delay:90,solo:E,ready:E,autofocus:E},hide:{target:E,event:"mouseleave",effect:D,delay:0,fixed:E,inactive:E,leave:"window",distance:E},style:{classes:"",widget:E,width:E,height:E,def:D},events:{render:F,move:F,show:F,hide:F,toggle:F,visible:F,hidden:F,focus:F,blur:F}};var ha,ia,ja,ka,la,ma="margin",na="border",oa="color",pa="background-color",qa="transparent",ra=" !important",sa=!!b.createElement("canvas").getContext,ta=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,ua={},va=["Webkit","O","Moz","ms"];sa?(ka=a.devicePixelRatio||1,la=function(){var a=b.createElement("canvas").getContext("2d");return a.backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||1}(),ja=ka/la):ia=function(a,b,c){return"<qtipvml:"+a+' xmlns="urn:schemas-microsoft.com:vml" class="qtip-vml" '+(b||"")+' style="behavior: url(#default#VML); '+(c||"")+'" />'},d.extend(v.prototype,{init:function(a){var b,c;c=this.element=a.elements.tip=d("<div />",{"class":S+"-tip"}).prependTo(a.tooltip),sa?(b=d("<canvas />").appendTo(this.element)[0].getContext("2d"),b.lineJoin="miter",b.miterLimit=1e5,b.save()):(b=ia("shape",'coordorigin="0,0"',"position:absolute;"),this.element.html(b+b),a._bind(d("*",c).add(c),["click","mousedown"],function(a){a.stopPropagation()},this._ns)),a._bind(a.tooltip,"tooltipmove",this.reposition,this._ns,this),this.create()},_swapDimensions:function(){this.size[0]=this.options.height,this.size[1]=this.options.width},_resetDimensions:function(){this.size[0]=this.options.width,this.size[1]=this.options.height},_useTitle:function(a){var b=this.qtip.elements.titlebar;return b&&(a.y===K||a.y===O&&this.element.position().top+this.size[1]/2+this.options.offset<b.outerHeight(D))},_parseCorner:function(a){var b=this.qtip.options.position.my;return a===E||b===E?a=E:a===D?a=new A(b.string()):a.string||(a=new A(a),a.fixed=D),a},_parseWidth:function(a,b,c){var d=this.qtip.elements,e=na+s(b)+"Width";return(c?u(c,e):u(d.content,e)||u(this._useTitle(a)&&d.titlebar||d.content,e)||u(d.tooltip,e))||0},_parseRadius:function(a){var b=this.qtip.elements,c=na+s(a.y)+s(a.x)+"Radius";return da.ie<9?0:u(this._useTitle(a)&&b.titlebar||b.content,c)||u(b.tooltip,c)||0},_invalidColour:function(a,b,c){var d=a.css(b);return!d||c&&d===a.css(c)||ta.test(d)?E:d},_parseColours:function(a){var b=this.qtip.elements,c=this.element.css("cssText",""),e=na+s(a[a.precedance])+s(oa),f=this._useTitle(a)&&b.titlebar||b.content,g=this._invalidColour,h=[];return h[0]=g(c,pa)||g(f,pa)||g(b.content,pa)||g(b.tooltip,pa)||c.css(pa),h[1]=g(c,e,oa)||g(f,e,oa)||g(b.content,e,oa)||g(b.tooltip,e,oa)||b.tooltip.css(e),d("*",c).add(c).css("cssText",pa+":"+qa+ra+";"+na+":0"+ra+";"),h},_calculateSize:function(a){var b,c,d,e=a.precedance===H,f=this.options.width,g=this.options.height,h="c"===a.abbrev(),i=(e?f:g)*(h?.5:1),j=Math.pow,k=Math.round,l=Math.sqrt(j(i,2)+j(g,2)),m=[this.border/i*l,this.border/g*l];return m[2]=Math.sqrt(j(m[0],2)-j(this.border,2)),m[3]=Math.sqrt(j(m[1],2)-j(this.border,2)),b=l+m[2]+m[3]+(h?0:m[0]),c=b/l,d=[k(c*f),k(c*g)],e?d:d.reverse()},_calculateTip:function(a,b,c){c=c||1,b=b||this.size;var d=b[0]*c,e=b[1]*c,f=Math.ceil(d/2),g=Math.ceil(e/2),h={br:[0,0,d,e,d,0],bl:[0,0,d,0,0,e],tr:[0,e,d,0,d,e],tl:[0,0,0,e,d,e],tc:[0,e,f,0,d,e],bc:[0,0,d,0,f,e],rc:[0,0,d,g,0,e],lc:[d,0,d,e,0,g]};return h.lt=h.br,h.rt=h.bl,h.lb=h.tr,h.rb=h.tl,h[a.abbrev()]},_drawCoords:function(a,b){a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(b[2],b[3]),a.lineTo(b[4],b[5]),a.closePath()},create:function(){var a=this.corner=(sa||da.ie)&&this._parseCorner(this.options.corner);return this.enabled=!!this.corner&&"c"!==this.corner.abbrev(),this.enabled&&(this.qtip.cache.corner=a.clone(),this.update()),this.element.toggle(this.enabled),this.corner},update:function(b,c){if(!this.enabled)return this;var e,f,g,h,i,j,k,l,m=this.qtip.elements,n=this.element,o=n.children(),p=this.options,q=this.size,r=p.mimic,s=Math.round;b||(b=this.qtip.cache.corner||this.corner),r===E?r=b:(r=new A(r),r.precedance=b.precedance,"inherit"===r.x?r.x=b.x:"inherit"===r.y?r.y=b.y:r.x===r.y&&(r[b.precedance]=b[b.precedance])),f=r.precedance,b.precedance===G?this._swapDimensions():this._resetDimensions(),e=this.color=this._parseColours(b),e[1]!==qa?(l=this.border=this._parseWidth(b,b[b.precedance]),p.border&&1>l&&!ta.test(e[1])&&(e[0]=e[1]),this.border=l=p.border!==D?p.border:l):this.border=l=0,k=this.size=this._calculateSize(b),n.css({width:k[0],height:k[1],lineHeight:k[1]+"px"}),j=b.precedance===H?[s(r.x===L?l:r.x===N?k[0]-q[0]-l:(k[0]-q[0])/2),s(r.y===K?k[1]-q[1]:0)]:[s(r.x===L?k[0]-q[0]:0),s(r.y===K?l:r.y===M?k[1]-q[1]-l:(k[1]-q[1])/2)],sa?(g=o[0].getContext("2d"),g.restore(),g.save(),g.clearRect(0,0,6e3,6e3),h=this._calculateTip(r,q,ja),i=this._calculateTip(r,this.size,ja),o.attr(I,k[0]*ja).attr(J,k[1]*ja),o.css(I,k[0]).css(J,k[1]),this._drawCoords(g,i),g.fillStyle=e[1],g.fill(),g.translate(j[0]*ja,j[1]*ja),this._drawCoords(g,h),g.fillStyle=e[0],g.fill()):(h=this._calculateTip(r),h="m"+h[0]+","+h[1]+" l"+h[2]+","+h[3]+" "+h[4]+","+h[5]+" xe",j[2]=l&&/^(r|b)/i.test(b.string())?8===da.ie?2:1:0,o.css({coordsize:k[0]+l+" "+k[1]+l,antialias:""+(r.string().indexOf(O)>-1),left:j[0]-j[2]*Number(f===G),top:j[1]-j[2]*Number(f===H),width:k[0]+l,height:k[1]+l}).each(function(a){var b=d(this);b[b.prop?"prop":"attr"]({coordsize:k[0]+l+" "+k[1]+l,path:h,fillcolor:e[0],filled:!!a,stroked:!a}).toggle(!(!l&&!a)),!a&&b.html(ia("stroke",'weight="'+2*l+'px" color="'+e[1]+'" miterlimit="1000" joinstyle="miter"'))})),a.opera&&setTimeout(function(){m.tip.css({display:"inline-block",visibility:"visible"})},1),c!==E&&this.calculate(b,k)},calculate:function(a,b){if(!this.enabled)return E;var c,e,f=this,g=this.qtip.elements,h=this.element,i=this.options.offset,j={}; +return a=a||this.corner,c=a.precedance,b=b||this._calculateSize(a),e=[a.x,a.y],c===G&&e.reverse(),d.each(e,function(d,e){var h,k,l;e===O?(h=c===H?L:K,j[h]="50%",j[ma+"-"+h]=-Math.round(b[c===H?0:1]/2)+i):(h=f._parseWidth(a,e,g.tooltip),k=f._parseWidth(a,e,g.content),l=f._parseRadius(a),j[e]=Math.max(-f.border,d?k:i+(l>h?l:-h)))}),j[a[c]]-=b[c===G?0:1],h.css({margin:"",top:"",bottom:"",left:"",right:""}).css(j),j},reposition:function(a,b,d){function e(a,b,c,d,e){a===Q&&j.precedance===b&&k[d]&&j[c]!==O?j.precedance=j.precedance===G?H:G:a!==Q&&k[d]&&(j[b]=j[b]===O?k[d]>0?d:e:j[b]===d?e:d)}function f(a,b,e){j[a]===O?p[ma+"-"+b]=o[a]=g[ma+"-"+b]-k[b]:(h=g[e]!==c?[k[b],-g[b]]:[-k[b],g[b]],(o[a]=Math.max(h[0],h[1]))>h[0]&&(d[b]-=k[b],o[b]=E),p[g[e]!==c?e:b]=o[a])}if(this.enabled){var g,h,i=b.cache,j=this.corner.clone(),k=d.adjusted,l=b.options.position.adjust.method.split(" "),m=l[0],n=l[1]||l[0],o={left:E,top:E,x:0,y:0},p={};this.corner.fixed!==D&&(e(m,G,H,L,N),e(n,H,G,K,M),j.string()===i.corner.string()&&i.cornerTop===k.top&&i.cornerLeft===k.left||this.update(j,E)),g=this.calculate(j),g.right!==c&&(g.left=-g.right),g.bottom!==c&&(g.top=-g.bottom),g.user=this.offset,o.left=m===Q&&!!k.left,o.left&&f(G,L,N),o.top=n===Q&&!!k.top,o.top&&f(H,K,M),this.element.css(p).toggle(!(o.x&&o.y||j.x===O&&o.y||j.y===O&&o.x)),d.left-=g.left.charAt?g.user:m!==Q||o.top||!o.left&&!o.top?g.left+this.border:0,d.top-=g.top.charAt?g.user:n!==Q||o.left||!o.left&&!o.top?g.top+this.border:0,i.cornerLeft=k.left,i.cornerTop=k.top,i.corner=j.clone()}},destroy:function(){this.qtip._unbind(this.qtip.tooltip,this._ns),this.qtip.elements.tip&&this.qtip.elements.tip.find("*").remove().end().remove()}}),ha=R.tip=function(a){return new v(a,a.options.style.tip)},ha.initialize="render",ha.sanitize=function(a){if(a.style&&"tip"in a.style){var b=a.style.tip;"object"!=typeof b&&(b=a.style.tip={corner:b}),/string|boolean/i.test(typeof b.corner)||(b.corner=D)}},B.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){this.create(),this.qtip.reposition()},"^style.tip.(height|width)$":function(a){this.size=[a.width,a.height],this.update(),this.qtip.reposition()},"^content.title|style.(classes|widget)$":function(){this.update()}},d.extend(D,y.defaults,{style:{tip:{corner:D,mimic:E,width:6,height:6,border:D,offset:0}}});var wa,xa,ya="qtip-modal",za="."+ya;xa=function(){function a(a){if(d.expr[":"].focusable)return d.expr[":"].focusable;var b,c,e,f=!isNaN(d.attr(a,"tabindex")),g=a.nodeName&&a.nodeName.toLowerCase();return"area"===g?(b=a.parentNode,c=b.name,a.href&&c&&"map"===b.nodeName.toLowerCase()?(e=d("img[usemap=#"+c+"]")[0],!!e&&e.is(":visible")):!1):/input|select|textarea|button|object/.test(g)?!a.disabled:"a"===g?a.href||f:f}function c(a){j.length<1&&a.length?a.not("body").blur():j.first().focus()}function e(a){if(h.is(":visible")){var b,e=d(a.target),g=f.tooltip,i=e.closest(W);b=i.length<1?E:parseInt(i[0].style.zIndex,10)>parseInt(g[0].style.zIndex,10),b||e.closest(W)[0]===g[0]||c(e)}}var f,g,h,i=this,j={};d.extend(i,{init:function(){return h=i.elem=d("<div />",{id:"qtip-overlay",html:"<div></div>",mousedown:function(){return E}}).hide(),d(b.body).bind("focusin"+za,e),d(b).bind("keydown"+za,function(a){f&&f.options.show.modal.escape&&27===a.keyCode&&f.hide(a)}),h.bind("click"+za,function(a){f&&f.options.show.modal.blur&&f.hide(a)}),i},update:function(b){f=b,j=b.options.show.modal.stealfocus!==E?b.tooltip.find("*").filter(function(){return a(this)}):[]},toggle:function(a,e,j){var k=a.tooltip,l=a.options.show.modal,m=l.effect,n=e?"show":"hide",o=h.is(":visible"),p=d(za).filter(":visible:not(:animated)").not(k);return i.update(a),e&&l.stealfocus!==E&&c(d(":focus")),h.toggleClass("blurs",l.blur),e&&h.appendTo(b.body),h.is(":animated")&&o===e&&g!==E||!e&&p.length?i:(h.stop(D,E),d.isFunction(m)?m.call(h,e):m===E?h[n]():h.fadeTo(parseInt(j,10)||90,e?1:0,function(){e||h.hide()}),e||h.queue(function(a){h.css({left:"",top:""}),d(za).length||h.detach(),a()}),g=e,f.destroyed&&(f=F),i)}}),i.init()},xa=new xa,d.extend(w.prototype,{init:function(a){var b=a.tooltip;return this.options.on?(a.elements.overlay=xa.elem,b.addClass(ya).css("z-index",y.modal_zindex+d(za).length),a._bind(b,["tooltipshow","tooltiphide"],function(a,c,e){var f=a.originalEvent;if(a.target===b[0])if(f&&"tooltiphide"===a.type&&/mouse(leave|enter)/.test(f.type)&&d(f.relatedTarget).closest(xa.elem[0]).length)try{a.preventDefault()}catch(g){}else(!f||f&&"tooltipsolo"!==f.type)&&this.toggle(a,"tooltipshow"===a.type,e)},this._ns,this),a._bind(b,"tooltipfocus",function(a,c){if(!a.isDefaultPrevented()&&a.target===b[0]){var e=d(za),f=y.modal_zindex+e.length,g=parseInt(b[0].style.zIndex,10);xa.elem[0].style.zIndex=f-1,e.each(function(){this.style.zIndex>g&&(this.style.zIndex-=1)}),e.filter("."+$).qtip("blur",a.originalEvent),b.addClass($)[0].style.zIndex=f,xa.update(c);try{a.preventDefault()}catch(h){}}},this._ns,this),void a._bind(b,"tooltiphide",function(a){a.target===b[0]&&d(za).filter(":visible").not(b).last().qtip("focus",a)},this._ns,this)):this},toggle:function(a,b,c){return a&&a.isDefaultPrevented()?this:void xa.toggle(this.qtip,!!b,c)},destroy:function(){this.qtip.tooltip.removeClass(ya),this.qtip._unbind(this.qtip.tooltip,this._ns),xa.toggle(this.qtip,E),delete this.qtip.elements.overlay}}),wa=R.modal=function(a){return new w(a,a.options.show.modal)},wa.sanitize=function(a){a.show&&("object"!=typeof a.show.modal?a.show.modal={on:!!a.show.modal}:"undefined"==typeof a.show.modal.on&&(a.show.modal.on=D))},y.modal_zindex=y.zindex-200,wa.initialize="render",B.modal={"^show.modal.(on|blur)$":function(){this.destroy(),this.init(),this.qtip.elems.overlay.toggle(this.qtip.tooltip[0].offsetWidth>0)}},d.extend(D,y.defaults,{show:{modal:{on:E,effect:D,blur:D,stealfocus:D,escape:D}}}),R.viewport=function(c,d,e,f,g,h,i){function j(a,b,c,e,f,g,h,i,j){var k=d[f],s=u[a],t=v[a],w=c===Q,x=s===f?j:s===g?-j:-j/2,y=t===f?i:t===g?-i:-i/2,z=q[f]+r[f]-(n?0:m[f]),A=z-k,B=k+j-(h===I?o:p)-z,C=x-(u.precedance===a||s===u[b]?y:0)-(t===O?i/2:0);return w?(C=(s===f?1:-1)*x,d[f]+=A>0?A:B>0?-B:0,d[f]=Math.max(-m[f]+r[f],k-C,Math.min(Math.max(-m[f]+r[f]+(h===I?o:p),k+C),d[f],"center"===s?k-x:1e9))):(e*=c===P?2:0,A>0&&(s!==f||B>0)?(d[f]-=C+e,l.invert(a,f)):B>0&&(s!==g||A>0)&&(d[f]-=(s===O?-C:C)+e,l.invert(a,g)),d[f]<q[f]&&-d[f]>B&&(d[f]=k,l=u.clone())),d[f]-k}var k,l,m,n,o,p,q,r,s=e.target,t=c.elements.tooltip,u=e.my,v=e.at,w=e.adjust,x=w.method.split(" "),y=x[0],z=x[1]||x[0],A=e.viewport,B=e.container,C={left:0,top:0};return A.jquery&&s[0]!==a&&s[0]!==b.body&&"none"!==w.method?(m=B.offset()||C,n="static"===B.css("position"),k="fixed"===t.css("position"),o=A[0]===a?A.width():A.outerWidth(E),p=A[0]===a?A.height():A.outerHeight(E),q={left:k?0:A.scrollLeft(),top:k?0:A.scrollTop()},r=A.offset()||C,"shift"===y&&"shift"===z||(l=u.clone()),C={left:"none"!==y?j(G,H,y,w.x,L,N,I,f,h):0,top:"none"!==z?j(H,G,z,w.y,K,M,J,g,i):0,my:l}):C},R.polys={polygon:function(a,b){var c,d,e,f={width:0,height:0,position:{top:1e10,right:0,bottom:0,left:1e10},adjustable:E},g=0,h=[],i=1,j=1,k=0,l=0;for(g=a.length;g--;)c=[parseInt(a[--g],10),parseInt(a[g+1],10)],c[0]>f.position.right&&(f.position.right=c[0]),c[0]<f.position.left&&(f.position.left=c[0]),c[1]>f.position.bottom&&(f.position.bottom=c[1]),c[1]<f.position.top&&(f.position.top=c[1]),h.push(c);if(d=f.width=Math.abs(f.position.right-f.position.left),e=f.height=Math.abs(f.position.bottom-f.position.top),"c"===b.abbrev())f.position={left:f.position.left+f.width/2,top:f.position.top+f.height/2};else{for(;d>0&&e>0&&i>0&&j>0;)for(d=Math.floor(d/2),e=Math.floor(e/2),b.x===L?i=d:b.x===N?i=f.width-d:i+=Math.floor(d/2),b.y===K?j=e:b.y===M?j=f.height-e:j+=Math.floor(e/2),g=h.length;g--&&!(h.length<2);)k=h[g][0]-f.position.left,l=h[g][1]-f.position.top,(b.x===L&&k>=i||b.x===N&&i>=k||b.x===O&&(i>k||k>f.width-i)||b.y===K&&l>=j||b.y===M&&j>=l||b.y===O&&(j>l||l>f.height-j))&&h.splice(g,1);f.position={left:h[0][0],top:h[0][1]}}return f},rect:function(a,b,c,d){return{width:Math.abs(c-a),height:Math.abs(d-b),position:{left:Math.min(a,c),top:Math.min(b,d)}}},_angles:{tc:1.5,tr:7/4,tl:5/4,bc:.5,br:.25,bl:.75,rc:2,lc:1,c:0},ellipse:function(a,b,c,d,e){var f=R.polys._angles[e.abbrev()],g=0===f?0:c*Math.cos(f*Math.PI),h=d*Math.sin(f*Math.PI);return{width:2*c-Math.abs(g),height:2*d-Math.abs(h),position:{left:a+g,top:b+h},adjustable:E}},circle:function(a,b,c,d){return R.polys.ellipse(a,b,c,c,d)}},R.svg=function(a,c,e){for(var f,g,h,i,j,k,l,m,n,o=c[0],p=d(o.ownerSVGElement),q=o.ownerDocument,r=(parseInt(c.css("stroke-width"),10)||0)/2;!o.getBBox;)o=o.parentNode;if(!o.getBBox||!o.parentNode)return E;switch(o.nodeName){case"ellipse":case"circle":m=R.polys.ellipse(o.cx.baseVal.value,o.cy.baseVal.value,(o.rx||o.r).baseVal.value+r,(o.ry||o.r).baseVal.value+r,e);break;case"line":case"polygon":case"polyline":for(l=o.points||[{x:o.x1.baseVal.value,y:o.y1.baseVal.value},{x:o.x2.baseVal.value,y:o.y2.baseVal.value}],m=[],k=-1,i=l.numberOfItems||l.length;++k<i;)j=l.getItem?l.getItem(k):l[k],m.push.apply(m,[j.x,j.y]);m=R.polys.polygon(m,e);break;default:m=o.getBBox(),m={width:m.width,height:m.height,position:{left:m.x,top:m.y}}}return n=m.position,p=p[0],p.createSVGPoint&&(g=o.getScreenCTM(),l=p.createSVGPoint(),l.x=n.left,l.y=n.top,h=l.matrixTransform(g),n.left=h.x,n.top=h.y),q!==b&&"mouse"!==a.position.target&&(f=d((q.defaultView||q.parentWindow).frameElement).offset(),f&&(n.left+=f.left,n.top+=f.top)),q=d(q),n.left+=q.scrollLeft(),n.top+=q.scrollTop(),m},R.imagemap=function(a,b,c){b.jquery||(b=d(b));var e,f,g,h,i,j=(b.attr("shape")||"rect").toLowerCase().replace("poly","polygon"),k=d('img[usemap="#'+b.parent("map").attr("name")+'"]'),l=d.trim(b.attr("coords")),m=l.replace(/,$/,"").split(",");if(!k.length)return E;if("polygon"===j)h=R.polys.polygon(m,c);else{if(!R.polys[j])return E;for(g=-1,i=m.length,f=[];++g<i;)f.push(parseInt(m[g],10));h=R.polys[j].apply(this,f.concat(c))}return e=k.offset(),e.left+=Math.ceil((k.outerWidth(E)-k.width())/2),e.top+=Math.ceil((k.outerHeight(E)-k.height())/2),h.position.left+=e.left,h.position.top+=e.top,h};var Aa,Ba='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:\'\';" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=0); -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";"></iframe>';d.extend(x.prototype,{_scroll:function(){var b=this.qtip.elements.overlay;b&&(b[0].style.top=d(a).scrollTop()+"px")},init:function(c){var e=c.tooltip;d("select, object").length<1&&(this.bgiframe=c.elements.bgiframe=d(Ba).appendTo(e),c._bind(e,"tooltipmove",this.adjustBGIFrame,this._ns,this)),this.redrawContainer=d("<div/>",{id:S+"-rcontainer"}).appendTo(b.body),c.elements.overlay&&c.elements.overlay.addClass("qtipmodal-ie6fix")&&(c._bind(a,["scroll","resize"],this._scroll,this._ns,this),c._bind(e,["tooltipshow"],this._scroll,this._ns,this)),this.redraw()},adjustBGIFrame:function(){var a,b,c=this.qtip.tooltip,d={height:c.outerHeight(E),width:c.outerWidth(E)},e=this.qtip.plugins.tip,f=this.qtip.elements.tip;b=parseInt(c.css("borderLeftWidth"),10)||0,b={left:-b,top:-b},e&&f&&(a="x"===e.corner.precedance?[I,L]:[J,K],b[a[1]]-=f[a[0]]()),this.bgiframe.css(b).css(d)},redraw:function(){if(this.qtip.rendered<1||this.drawing)return this;var a,b,c,d,e=this.qtip.tooltip,f=this.qtip.options.style,g=this.qtip.options.position.container;return this.qtip.drawing=1,f.height&&e.css(J,f.height),f.width?e.css(I,f.width):(e.css(I,"").appendTo(this.redrawContainer),b=e.width(),1>b%2&&(b+=1),c=e.css("maxWidth")||"",d=e.css("minWidth")||"",a=(c+d).indexOf("%")>-1?g.width()/100:0,c=(c.indexOf("%")>-1?a:1*parseInt(c,10))||b,d=(d.indexOf("%")>-1?a:1*parseInt(d,10))||0,b=c+d?Math.min(Math.max(b,d),c):b,e.css(I,Math.round(b)).appendTo(g)),this.drawing=0,this},destroy:function(){this.bgiframe&&this.bgiframe.remove(),this.qtip._unbind([a,this.qtip.tooltip],this._ns)}}),Aa=R.ie6=function(a){return 6===da.ie?new x(a):E},Aa.initialize="render",B.ie6={"^content|style$":function(){this.redraw()}}})}(window,document); +//# sourceMappingURL=jquery.qtip.min.map \ No newline at end of file diff --git a/static/app2/js/jquery.validate.min.js b/static/app2/js/jquery.validate.min.js new file mode 100755 index 0000000..4f15a11 --- /dev/null +++ b/static/app2/js/jquery.validate.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.16.0 - 12/2/2016 + * http://jqueryvalidation.org/ + * Copyright (c) 2016 Jörn Zaefferer; Licensed MIT */ +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return!c.settings.submitHandler||(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&null!=j.form){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]);var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)a[b]&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0]),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);if("function"==typeof f.normalizer){if(i=f.normalizer.call(b,i),"string"!=typeof i)throw new TypeError("The normalizer should return a string value.");delete f.normalizer}for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&//console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]},defaultMessage:function(b,c){"string"==typeof c&&(c={method:c});var d=this.findDefined(this.customMessage(b.name,c.method),this.customDataMessage(b,c.method),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c.method],"<strong>Warning: No message defined for "+b.name+"</strong>"),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a}); \ No newline at end of file diff --git a/static/app2/js/juan_goods.js b/static/app2/js/juan_goods.js new file mode 100755 index 0000000..b127497 --- /dev/null +++ b/static/app2/js/juan_goods.js @@ -0,0 +1,69 @@ +$('.t_con').css('display', 'none'); +var html_li = '<p class="title"></p>'; +$('.header_con').append(html_li); +$('.header_con .title').css('display', 'none'); + +var couponId = ''; +var secTypeId = ''; +var pageSize = 10; +var page = 1; +var isjiazai = 1; + +function lxy_(couponId, page, pageSize) { + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + var lxy_data_ = { + couponId: couponId ? couponId : '', + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + + mui.ajax(kxUrl('addon/hyhcouponset-Hyhcouponset-cateGoods'), {  + data: lxy_data_, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + //var data = toJson(data); + var data = data.data + var html = ''; + + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" src="../img/icon_sscl.png"alt=""style="display:none;"/></div>' + }); + + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  +} + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + couponId = self.couponId; + console.log(couponId); + // console.log(topTypeId) + lxy_(couponId, page, pageSize); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + lxy_(couponId, page, pageSize); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/juan_index.js b/static/app2/js/juan_index.js new file mode 100755 index 0000000..62a0d7e --- /dev/null +++ b/static/app2/js/juan_index.js @@ -0,0 +1,125 @@ +var pageSize = 10; +var page = 1; +var isjiazai = 1; +var userCoupon = 'userCoupon'; + +function lxy_quan(page, pageSize, userCoupon) { + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + + var lxy_quan_data = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + + mui.ajax(kxUrl('addon/hyhcouponset-Hyhcouponset-' + userCoupon), { + data: lxy_quan_data, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + //console.log(data.data.goodsFavoritesNum) + //console.log(data.data.Rows) + // var data = toJson(data); + if(data.status == 1) { + var data = data.data; + var html = ''; + if(data.Rows == '') { + if(page == 1) { + $('#con_juan').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多内容</p>'); + } else { + $('#con_juan').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多内容</p>'); + } + isjiazai = 0; + return; + + } + $.each(data.Rows, function() { + html += '<div class="coupon" data-couponId="' + this.couponId + '"><p class="cou_p1">¥ <span>' + this.price + '</span> 满' + this.man + '减' + this.price + '</p><p class="cou_p2">' + this.couponDesc + '</p><p class="cou_p3">' + this.begin_time + '——' + this.end_time + '</p><button class="cou_btn" data-couponId="' + this.couponId + '" style="display: none;">去使用</button><img src="../img/juan_yes.png"/ class="j_yes" style="display: none;"></div>'; + }); + if(page == 1) { + $('#con_juan').html(html); + } else { + $('#con_juan').append(html); + } + + if(userCoupon == 'userCoupon') { + $('.cou_btn').show(); + } else { + $('.j_yes').show(); + } + isjiazai = 1; + + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + //alert(type);     + }   + });  + +} + +mui.plusReady(function() { + lxy_quan(1, pageSize, userCoupon); + mui('.nav').on('tap', '.nav_block', function() { + if($(this).attr('data-id') == 1) { + userCoupon = 'userCoupon' + } else { + userCoupon = 'userYetCoupon' + } + isjiazai = 1; + page = 1; + lxy_quan(page, pageSize, userCoupon); + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + lxy_quan(page, pageSize, userCoupon); + } + + } + }) + + //跳转到优惠劵使用页 + $('.con_').on('tap', '.cou_btn', function() { + var couponId = $(this).attr('data-couponId'); + mui.openWindow({ + url: 'juan_goods.html', + id: 'juan_godds.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + couponId: couponId + //..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/login.js b/static/app2/js/login.js new file mode 100755 index 0000000..381d559 --- /dev/null +++ b/static/app2/js/login.js @@ -0,0 +1,121 @@ + document.write('<script type="text/javascript" src="https://ssl.captcha.qq.com/TCaptcha.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); + +$('.top').attr('style', "margin-top:"+(localStorage.getItem("ipxSizeTop")*4)+"px;") +mui.init({ + beforeback: function() {     //获得父页面的webview + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + $('.loginbg').height(window.screen.height); + $('.btn').attr('id','Tcaptcha'); + $('.btn').attr('data-appid','2089606583'); + $('.btn').attr('data-cbfn','callback'); + window.callback = function(res){ + // //console.log(JSON.stringify(res)); + $('.btn').removeAttr('disabled'); + // res(未通过验证)= {ret: 1, ticket: null} + // res(验证成功) = {ret: 0, ticket: "String", randstr: "String"} + + if(res.ret === 0){ + var send_data = {}; + send_data.loginName = $('#loginName').val(); + send_data.loginPwd = $('#loginPwd').val(); + send_data.ticket = res.ticket; // 票据 + send_data.randstr = res.randstr; + var url = qlgUrl('app/users/checkLogin'); + // var url = hyhUrl('app/users/checkLogin'); + + JZL.ajax(url, send_data, function(data){ + if(data.status == 1) { + var token = data.data.token; + localStorage.setItem('token', token); + ////console.log(data.data.token); + mui.back(); + return; + } else { + mui.alert(data.msg); + } + }, 'POST',0); + } + } + mui('.down').on('tap', '.btn', function() { + + var loginName = $('#loginName').val(); + + var loginPwd = $('#loginPwd').val(); + + if(loginName == '') { + + mui.alert('用户名不能为空!'); + + return; + + } + + if(loginPwd == '') { + + mui.alert('密码不能为空!'); + + return; + } + $('.btn').attr('disabled', 'disabled'); + var captcha1 = new TencentCaptcha(document.getElementById('Tcaptcha')); + captcha1.show(); + setTimeout(function(){ + $('.feedback-group',document.getElementById('tcaptcha_iframe').contentWindow.document).hide(); + // $('.feedback-group',document.frames("")).hide(); + },2000) + //$(this).trigger('click'); + return; + // var loginName = 'zxcvbn'; + // s var loginPwd = 'zxcvbn'; + + mui.ajax(qlgUrl('app/users/checkLogin'), { + // mui.ajax(hyhUrl('app/users/checkLogin'), { + + data: { + loginName: loginName, + loginPwd: loginPwd, + nameType: 3, + ticker:ticker + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; +// //console.log(data); + if(data.status == 1) { + var token = data.data.token; + localStorage.setItem('token', token); + ////console.log(data.data.token); + mui.back(); + return; + } else { + mui.alert(data.msg); + } + + $('.btn').removeAttr('disabled'); + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + }) + mui('.down').on('tap', '#register', function() { + // JZL.openWindow('register.html', 'register.html'); + JZL.openWindow('register.html', 'register.html'); + + }) + mui('.down').on('tap', '#fogetpsd', function() { + JZL.openWindow('setting_fogetPwd.html', 'setting_fogetPwd.html'); + }) + +}) \ No newline at end of file diff --git a/static/app2/js/logistics.js b/static/app2/js/logistics.js new file mode 100755 index 0000000..cbdc8ad --- /dev/null +++ b/static/app2/js/logistics.js @@ -0,0 +1,15 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + localStorage.setItem('data_order_id', data_order_id); + var bSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var sub = plus.webview.create('logisticscon.html', 'logisticscon.html', { + top: bSize, + bottom: '0', + scrollIndicator: 'none' + }); + self.append(sub); + + +}) \ No newline at end of file diff --git a/static/app2/js/logisticscon.js b/static/app2/js/logisticscon.js new file mode 100755 index 0000000..4ec8482 --- /dev/null +++ b/static/app2/js/logisticscon.js @@ -0,0 +1,50 @@ +$('.summarize').html(''); +mui.plusReady(function() { + var data_order_id = localStorage.getItem('data_order_id'); + var token = localStorage.getItem('token'); + var nwaiting = plus.nativeUI.showWaiting(); + mui.ajax(hyhUrl('app/Orders/findExpress'), { + + data: { + orderId: data_order_id + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + nwaiting.close(); + var data = toJson(data); + if(!data.express){ + data=data.data; + } + var html = '<div class="summarize clearfix"><img src="' + ectImgUrl(data.express.expressImg) + '" /><div class="summarizeinfo"><p class="pp1">物流状态: <o>' + data.express.stateTxt + '</o></p><p class="pp2">承运来源:' + data.express.expressName + '</p><p class="pp2">运单编号:' + data.express.expressNo + '</p></p></div></div><div class="track-list"><ul>'; + if(data.status == 200 || data.status == 1) { + var data_ = data.data; + if(data.data.length > 1) { + var d_1 = data.data[0].time; + var d_2 = data.data[data.data.length - 1].time; + var e_1 = new Date(d_1).getTime(); + var e_2 = new Date(d_2).getTime(); + if(e_1 < e_2) { + data_.reverse(); + } + } + + $.each(data_, function() { + html += '<li><i class="node-icon"></i><p class="txt">' + this.context + '</p><p class="time">' + this.time + '</p></li>' + }); + + } else { + // mui.alert(data.status); + } + html += '</ul></div>' + $('.con').html(html); + document.getElementsByTagName('li')[0].className = 'first'; + }, + error: function(xhr, type, errorThrown) { //异常处理; + nwaiting.close(); + // mui.alert(type); + } + }); + +}) \ No newline at end of file diff --git a/static/app2/js/lrz.bundle.js b/static/app2/js/lrz.bundle.js new file mode 100755 index 0000000..8294911 --- /dev/null +++ b/static/app2/js/lrz.bundle.js @@ -0,0 +1,2 @@ +!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n=t();for(var r in n)("object"==typeof exports?exports:e)[r]=n[r]}}(this,function(){return function(e){function t(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return e[n].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n=window.webpackJsonp;window.webpackJsonp=function(r,o){for(var a,s,u=0,l=[];u<r.length;u++)s=r[u],i[s]&&l.push.apply(l,i[s]),i[s]=0;for(a in o)e[a]=o[a];for(n&&n(r,o);l.length;)l.shift().call(null,t)};var r={},i={0:0};return t.e=function(e,n){if(0===i[e])return n.call(null,t);if(void 0!==i[e])i[e].push(n);else{i[e]=[n];var r=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+""+({}[e]||e)+".chunk.js",r.appendChild(o)}},t.m=e,t.c=r,t.p="",t(0)}([function(e,t,n){function r(e,t){var n=this;if(!e)throw new Error("没有收到图片,可能的解决方案:https://github.com/think2011/localResizeIMG/issues/7");t=t||{},n.defaults={width:null,height:null,fieldName:"file",quality:.7},n.file=e;for(var r in t)t.hasOwnProperty(r)&&(n.defaults[r]=t[r]);return this.init()}function i(e){var t=null;return t=e?[].filter.call(document.scripts,function(t){return-1!==t.src.indexOf(e)})[0]:document.scripts[document.scripts.length-1],t?t.src.substr(0,t.src.lastIndexOf("/")):null}function o(e){var t;t=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):unescape(e.split(",")[1]);for(var n=e.split(",")[0].split(":")[1].split(";")[0],r=new Uint8Array(t.length),i=0;i<t.length;i++)r[i]=t.charCodeAt(i);return new s.Blob([r.buffer],{type:n})}n.p=i("lrz")+"/",window.URL=window.URL||window.webkitURL;var a=n(1),s=n(4),u=n(5),l=function(e){var t=/OS (\d)_.* like Mac OS X/g.exec(e),n=/Android (\d.*?);/g.exec(e)||/Android\/(\d.*?) /g.exec(e);return{oldIOS:t?+t.pop()<8:!1,oldAndroid:n?+n.pop().substr(0,3)<4.5:!1,iOS:/\(i[^;]+;( U;)? CPU.+Mac OS X/.test(e),android:/Android/g.test(e),mQQBrowser:/MQQBrowser/g.test(e)}}(navigator.userAgent);r.prototype.init=function(){var e=this,t=e.file,n="string"==typeof t,r=/^data:/.test(t),i=new Image,u=document.createElement("canvas"),l=n?t:URL.createObjectURL(t);if(e.img=i,e.blob=l,e.canvas=u,n?e.fileName=r?"base64.jpg":t.split("/").pop():e.fileName=t.name,!document.createElement("canvas").getContext)throw new Error("浏览器不支持canvas");return new a(function(n,a){i.onerror=function(){var e=new Error("加载图片文件失败");throw a(e),e},i.onload=function(){e._getBase64().then(function(e){if(e.length<10){var t=new Error("生成base64失败");throw a(t),t}return e}).then(function(r){var i=null;"object"==typeof e.file&&r.length>e.file.size?(i=new FormData,t=e.file):(i=new s.FormData,t=o(r)),i.append(e.defaults.fieldName,t,e.fileName.replace(/\..+/g,".jpg")),n({formData:i,fileLen:+t.size,base64:r,base64Len:r.length,origin:e.file,file:t});for(var a in e)e.hasOwnProperty(a)&&(e[a]=null);URL.revokeObjectURL(e.blob)})},!r&&(i.crossOrigin="*"),i.src=l})},r.prototype._getBase64=function(){var e=this,t=e.img,n=e.file,r=e.canvas;return new a(function(i){try{u.getData("object"==typeof n?n:t,function(){e.orientation=u.getTag(this,"Orientation"),e.resize=e._getResize(),e.ctx=r.getContext("2d"),r.width=e.resize.width,r.height=e.resize.height,e.ctx.fillStyle="#fff",e.ctx.fillRect(0,0,r.width,r.height),l.oldIOS?e._createBase64ForOldIOS().then(i):e._createBase64().then(i)})}catch(o){throw new Error(o)}})},r.prototype._createBase64ForOldIOS=function(){var e=this,t=e.img,r=e.canvas,i=e.defaults,o=e.orientation;return new a(function(e){n.e(1,function(n){var a=[n(6)];(function(n){var a=new n(t);"5678".indexOf(o)>-1?a.render(r,{width:r.height,height:r.width,orientation:o}):a.render(r,{width:r.width,height:r.height,orientation:o}),e(r.toDataURL("image/jpeg",i.quality))}).apply(null,a)})})},r.prototype._createBase64=function(){var e=this,t=e.resize,r=e.img,i=e.canvas,o=e.ctx,s=e.defaults,u=e.orientation;switch(u){case 3:o.rotate(180*Math.PI/180),o.drawImage(r,-t.width,-t.height,t.width,t.height);break;case 6:o.rotate(90*Math.PI/180),o.drawImage(r,0,-t.width,t.height,t.width);break;case 8:o.rotate(270*Math.PI/180),o.drawImage(r,-t.height,0,t.height,t.width);break;case 2:o.translate(t.width,0),o.scale(-1,1),o.drawImage(r,0,0,t.width,t.height);break;case 4:o.translate(t.width,0),o.scale(-1,1),o.rotate(180*Math.PI/180),o.drawImage(r,-t.width,-t.height,t.width,t.height);break;case 5:o.translate(t.width,0),o.scale(-1,1),o.rotate(90*Math.PI/180),o.drawImage(r,0,-t.width,t.height,t.width);break;case 7:o.translate(t.width,0),o.scale(-1,1),o.rotate(270*Math.PI/180),o.drawImage(r,-t.height,0,t.height,t.width);break;default:o.drawImage(r,0,0,t.width,t.height)}return new a(function(e){l.oldAndroid||l.mQQBrowser||!navigator.userAgent?n.e(2,function(t){var n=[t(7)];(function(t){var n=new t,r=o.getImageData(0,0,i.width,i.height);e(n.encode(r,100*s.quality))}).apply(null,n)}):e(i.toDataURL("image/jpeg",s.quality))})},r.prototype._getResize=function(){var e=this,t=e.img,n=e.defaults,r=n.width,i=n.height,o=e.orientation,a={width:t.width,height:t.height};if("5678".indexOf(o)>-1&&(a.width=t.height,a.height=t.width),a.width<r||a.height<i)return a;var s=a.width/a.height;for(r&&i?s>=r/i?a.width>r&&(a.width=r,a.height=Math.ceil(r/s)):a.height>i&&(a.height=i,a.width=Math.ceil(i*s)):r?r<a.width&&(a.width=r,a.height=Math.ceil(r/s)):i&&i<a.height&&(a.width=Math.ceil(i*s),a.height=i);a.width>=3264||a.height>=2448;)a.width*=.8,a.height*=.8;return a},window.lrz=function(e,t){return new r(e,t)},window.lrz.version="4.9.40",e.exports=window.lrz},function(e,t,n){(function(t){!function(n){function r(e,t){return function(){e.apply(t,arguments)}}function i(e){if("object"!=typeof this)throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=null,this._value=null,this._deferreds=[],c(e,r(a,this),r(s,this))}function o(e){var t=this;return null===this._state?void this._deferreds.push(e):void f(function(){var n=t._state?e.onFulfilled:e.onRejected;if(null===n)return void(t._state?e.resolve:e.reject)(t._value);var r;try{r=n(t._value)}catch(i){return void e.reject(i)}e.resolve(r)})}function a(e){try{if(e===this)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var t=e.then;if("function"==typeof t)return void c(r(t,e),r(a,this),r(s,this))}this._state=!0,this._value=e,u.call(this)}catch(n){s.call(this,n)}}function s(e){this._state=!1,this._value=e,u.call(this)}function u(){for(var e=0,t=this._deferreds.length;t>e;e++)o.call(this,this._deferreds[e]);this._deferreds=null}function l(e,t,n,r){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof t?t:null,this.resolve=n,this.reject=r}function c(e,t,n){var r=!1;try{e(function(e){r||(r=!0,t(e))},function(e){r||(r=!0,n(e))})}catch(i){if(r)return;r=!0,n(i)}}var f="function"==typeof t&&t||function(e){setTimeout(e,1)},d=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};i.prototype["catch"]=function(e){return this.then(null,e)},i.prototype.then=function(e,t){var n=this;return new i(function(r,i){o.call(n,new l(e,t,r,i))})},i.all=function(){var e=Array.prototype.slice.call(1===arguments.length&&d(arguments[0])?arguments[0]:arguments);return new i(function(t,n){function r(o,a){try{if(a&&("object"==typeof a||"function"==typeof a)){var s=a.then;if("function"==typeof s)return void s.call(a,function(e){r(o,e)},n)}e[o]=a,0===--i&&t(e)}catch(u){n(u)}}if(0===e.length)return t([]);for(var i=e.length,o=0;o<e.length;o++)r(o,e[o])})},i.resolve=function(e){return e&&"object"==typeof e&&e.constructor===i?e:new i(function(t){t(e)})},i.reject=function(e){return new i(function(t,n){n(e)})},i.race=function(e){return new i(function(t,n){for(var r=0,i=e.length;i>r;r++)e[r].then(t,n)})},i._setImmediateFn=function(e){f=e},i.prototype.always=function(e){var t=this.constructor;return this.then(function(n){return t.resolve(e()).then(function(){return n})},function(n){return t.resolve(e()).then(function(){throw n})})},"undefined"!=typeof e&&e.exports?e.exports=i:n.Promise||(n.Promise=i)}(this)}).call(t,n(2).setImmediate)},function(e,t,n){(function(e,r){function i(e,t){this._id=e,this._clearFn=t}var o=n(3).nextTick,a=Function.prototype.apply,s=Array.prototype.slice,u={},l=0;t.setTimeout=function(){return new i(a.call(setTimeout,window,arguments),clearTimeout)},t.setInterval=function(){return new i(a.call(setInterval,window,arguments),clearInterval)},t.clearTimeout=t.clearInterval=function(e){e.close()},i.prototype.unref=i.prototype.ref=function(){},i.prototype.close=function(){this._clearFn.call(window,this._id)},t.enroll=function(e,t){clearTimeout(e._idleTimeoutId),e._idleTimeout=t},t.unenroll=function(e){clearTimeout(e._idleTimeoutId),e._idleTimeout=-1},t._unrefActive=t.active=function(e){clearTimeout(e._idleTimeoutId);var t=e._idleTimeout;t>=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},t.setImmediate="function"==typeof e?e:function(e){var n=l++,r=arguments.length<2?!1:s.call(arguments,1);return u[n]=!0,o(function(){u[n]&&(r?e.apply(null,r):e.call(null),t.clearImmediate(n))}),n},t.clearImmediate="function"==typeof r?r:function(e){delete u[e]}}).call(t,n(2).setImmediate,n(2).clearImmediate)},function(e,t){function n(){l=!1,a.length?u=a.concat(u):c=-1,u.length&&r()}function r(){if(!l){var e=setTimeout(n);l=!0;for(var t=u.length;t;){for(a=u,u=[];++c<t;)a&&a[c].run();c=-1,t=u.length}a=null,l=!1,clearTimeout(e)}}function i(e,t){this.fun=e,this.array=t}function o(){}var a,s=e.exports={},u=[],l=!1,c=-1;s.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];u.push(new i(e,t)),1!==u.length||l||setTimeout(r,0)},i.prototype.run=function(){this.fun.apply(null,this.array)},s.title="browser",s.browser=!0,s.env={},s.argv=[],s.version="",s.versions={},s.on=o,s.addListener=o,s.once=o,s.off=o,s.removeListener=o,s.removeAllListeners=o,s.emit=o,s.binding=function(e){throw new Error("process.binding is not supported")},s.cwd=function(){return"/"},s.chdir=function(e){throw new Error("process.chdir is not supported")},s.umask=function(){return 0}},function(e,t){function n(){var e=~navigator.userAgent.indexOf("Android")&&~navigator.vendor.indexOf("Google")&&!~navigator.userAgent.indexOf("Chrome");return e&&navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop()<=534||/MQQBrowser/g.test(navigator.userAgent)}var r=function(){try{return new Blob,!0}catch(e){return!1}}()?window.Blob:function(e,t){var n=new(window.BlobBuilder||window.WebKitBlobBuilder||window.MSBlobBuilder||window.MozBlobBuilder);return e.forEach(function(e){n.append(e)}),n.getBlob(t?t.type:void 0)},i=function(){function e(){var e=this,n=[],i=Array(21).join("-")+(+new Date*(1e16*Math.random())).toString(36),o=XMLHttpRequest.prototype.send;this.getParts=function(){return n.toString()},this.append=function(e,t,r){n.push("--"+i+'\r\nContent-Disposition: form-data; name="'+e+'"'),t instanceof Blob?(n.push('; filename="'+(r||"blob")+'"\r\nContent-Type: '+t.type+"\r\n\r\n"),n.push(t)):n.push("\r\n\r\n"+t),n.push("\r\n")},t++,XMLHttpRequest.prototype.send=function(a){var s,u,l=this;a===e?(n.push("--"+i+"--\r\n"),u=new r(n),s=new FileReader,s.onload=function(){o.call(l,s.result)},s.onerror=function(e){throw e},s.readAsArrayBuffer(u),this.setRequestHeader("Content-Type","multipart/form-data; boundary="+i),t--,0==t&&(XMLHttpRequest.prototype.send=o)):o.call(this,a)}}var t=0;return e.prototype=Object.create(FormData.prototype),e}();e.exports={Blob:r,FormData:n()?i:FormData}},function(e,t,n){var r,i;(function(){function n(e){return!!e.exifdata}function o(e,t){t=t||e.match(/^data\:([^\;]+)\;base64,/im)[1]||"",e=e.replace(/^data\:([^\;]+)\;base64,/gim,"");for(var n=atob(e),r=n.length,i=new ArrayBuffer(r),o=new Uint8Array(i),a=0;r>a;a++)o[a]=n.charCodeAt(a);return i}function a(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.responseType="blob",n.onload=function(e){(200==this.status||0===this.status)&&t(this.response)},n.send()}function s(e,t){function n(n){var r=u(n),i=l(n);e.exifdata=r||{},e.iptcdata=i||{},t&&t.call(e)}if(e.src)if(/^data\:/i.test(e.src)){var r=o(e.src);n(r)}else if(/^blob\:/i.test(e.src)){var i=new FileReader;i.onload=function(e){n(e.target.result)},a(e.src,function(e){i.readAsArrayBuffer(e)})}else{var s=new XMLHttpRequest;s.onload=function(){200==this.status||0===this.status?n(s.response):t(new Error("Could not load image")),s=null},s.open("GET",e.src,!0),s.responseType="arraybuffer",s.send(null)}else if(window.FileReader&&(e instanceof window.Blob||e instanceof window.File)){var i=new FileReader;i.onload=function(e){p&&console.log("Got file of length "+e.target.result.byteLength),n(e.target.result)},i.readAsArrayBuffer(e)}}function u(e){var t=new DataView(e);if(p&&console.log("Got file of length "+e.byteLength),255!=t.getUint8(0)||216!=t.getUint8(1))return p&&console.log("Not a valid JPEG"),!1;for(var n,r=2,i=e.byteLength;i>r;){if(255!=t.getUint8(r))return p&&console.log("Not a valid marker at offset "+r+", found: "+t.getUint8(r)),!1;if(n=t.getUint8(r+1),p&&console.log(n),225==n)return p&&console.log("Found 0xFFE1 marker"),g(t,r+4,t.getUint16(r+2)-2);r+=2+t.getUint16(r+2)}}function l(e){var t=new DataView(e);if(p&&console.log("Got file of length "+e.byteLength),255!=t.getUint8(0)||216!=t.getUint8(1))return p&&console.log("Not a valid JPEG"),!1;for(var n=2,r=e.byteLength,i=function(e,t){return 56===e.getUint8(t)&&66===e.getUint8(t+1)&&73===e.getUint8(t+2)&&77===e.getUint8(t+3)&&4===e.getUint8(t+4)&&4===e.getUint8(t+5)};r>n;){if(i(t,n)){var o=t.getUint8(n+7);o%2!==0&&(o+=1),0===o&&(o=4);var a=n+8+o,s=t.getUint16(n+6+o);return c(e,a,s)}n++}}function c(e,t,n){for(var r,i,o,a,s,u=new DataView(e),l={},c=t;t+n>c;)28===u.getUint8(c)&&2===u.getUint8(c+1)&&(a=u.getUint8(c+2),a in b&&(o=u.getInt16(c+3),s=o+5,i=b[a],r=h(u,c+5,o),l.hasOwnProperty(i)?l[i]instanceof Array?l[i].push(r):l[i]=[l[i],r]:l[i]=r)),c++;return l}function f(e,t,n,r,i){var o,a,s,u=e.getUint16(n,!i),l={};for(s=0;u>s;s++)o=n+12*s+2,a=r[e.getUint16(o,!i)],!a&&p&&console.log("Unknown tag: "+e.getUint16(o,!i)),l[a]=d(e,o,t,n,i);return l}function d(e,t,n,r,i){var o,a,s,u,l,c,f=e.getUint16(t+2,!i),d=e.getUint32(t+4,!i),g=e.getUint32(t+8,!i)+n;switch(f){case 1:case 7:if(1==d)return e.getUint8(t+8,!i);for(o=d>4?g:t+8,a=[],u=0;d>u;u++)a[u]=e.getUint8(o+u);return a;case 2:return o=d>4?g:t+8,h(e,o,d-1);case 3:if(1==d)return e.getUint16(t+8,!i);for(o=d>2?g:t+8,a=[],u=0;d>u;u++)a[u]=e.getUint16(o+2*u,!i);return a;case 4:if(1==d)return e.getUint32(t+8,!i);for(a=[],u=0;d>u;u++)a[u]=e.getUint32(g+4*u,!i);return a;case 5:if(1==d)return l=e.getUint32(g,!i),c=e.getUint32(g+4,!i),s=new Number(l/c),s.numerator=l,s.denominator=c,s;for(a=[],u=0;d>u;u++)l=e.getUint32(g+8*u,!i),c=e.getUint32(g+4+8*u,!i),a[u]=new Number(l/c),a[u].numerator=l,a[u].denominator=c;return a;case 9:if(1==d)return e.getInt32(t+8,!i);for(a=[],u=0;d>u;u++)a[u]=e.getInt32(g+4*u,!i);return a;case 10:if(1==d)return e.getInt32(g,!i)/e.getInt32(g+4,!i);for(a=[],u=0;d>u;u++)a[u]=e.getInt32(g+8*u,!i)/e.getInt32(g+4+8*u,!i);return a}}function h(e,t,n){var r,i="";for(r=t;t+n>r;r++)i+=String.fromCharCode(e.getUint8(r));return i}function g(e,t){if("Exif"!=h(e,t,4))return p&&console.log("Not valid EXIF data! "+h(e,t,4)),!1;var n,r,i,o,a,s=t+6;if(18761==e.getUint16(s))n=!1;else{if(19789!=e.getUint16(s))return p&&console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)"),!1;n=!0}if(42!=e.getUint16(s+2,!n))return p&&console.log("Not valid TIFF data! (no 0x002A)"),!1;var u=e.getUint32(s+4,!n);if(8>u)return p&&console.log("Not valid TIFF data! (First offset less than 8)",e.getUint32(s+4,!n)),!1;if(r=f(e,s,s+u,y,n),r.ExifIFDPointer){o=f(e,s,s+r.ExifIFDPointer,w,n);for(i in o){switch(i){case"LightSource":case"Flash":case"MeteringMode":case"ExposureProgram":case"SensingMethod":case"SceneCaptureType":case"SceneType":case"CustomRendered":case"WhiteBalance":case"GainControl":case"Contrast":case"Saturation":case"Sharpness":case"SubjectDistanceRange":case"FileSource":o[i]=S[i][o[i]];break;case"ExifVersion":case"FlashpixVersion":o[i]=String.fromCharCode(o[i][0],o[i][1],o[i][2],o[i][3]);break;case"ComponentsConfiguration":o[i]=S.Components[o[i][0]]+S.Components[o[i][1]]+S.Components[o[i][2]]+S.Components[o[i][3]]}r[i]=o[i]}}if(r.GPSInfoIFDPointer){a=f(e,s,s+r.GPSInfoIFDPointer,v,n);for(i in a){switch(i){case"GPSVersionID":a[i]=a[i][0]+"."+a[i][1]+"."+a[i][2]+"."+a[i][3]}r[i]=a[i]}}return r}var p=!1,m=function(e){return e instanceof m?e:this instanceof m?void(this.EXIFwrapped=e):new m(e)};"undefined"!=typeof e&&e.exports&&(t=e.exports=m),t.EXIF=m;var w=m.Tags={36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubsecTime",37521:"SubsecTimeOriginal",37522:"SubsecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"ISOSpeedRatings",34856:"OECF",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRation",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",40965:"InteroperabilityIFDPointer",42016:"ImageUniqueID"},y=m.TiffTags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright"},v=m.GPSTags={0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential"},S=m.StringValues={ExposureProgram:{0:"Not defined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Not defined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},Components:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"}},b={120:"caption",110:"credit",25:"keywords",55:"dateCreated",80:"byline",85:"bylineTitle",122:"captionWriter",105:"headline",116:"copyright",15:"category"};m.getData=function(e,t){return(e instanceof Image||e instanceof HTMLImageElement)&&!e.complete?!1:(n(e)?t&&t.call(e):s(e,t),!0)},m.getTag=function(e,t){return n(e)?e.exifdata[t]:void 0},m.getAllTags=function(e){if(!n(e))return{};var t,r=e.exifdata,i={};for(t in r)r.hasOwnProperty(t)&&(i[t]=r[t]);return i},m.pretty=function(e){if(!n(e))return"";var t,r=e.exifdata,i="";for(t in r)r.hasOwnProperty(t)&&(i+="object"==typeof r[t]?r[t]instanceof Number?t+" : "+r[t]+" ["+r[t].numerator+"/"+r[t].denominator+"]\r\n":t+" : ["+r[t].length+" values]\r\n":t+" : "+r[t]+"\r\n");return i},m.readFromBinaryFile=function(e){return u(e)},r=[],i=function(){return m}.apply(t,r),!(void 0!==i&&(e.exports=i))}).call(this)}])}); +//# sourceMappingURL=lrz.bundle.js.map \ No newline at end of file diff --git a/static/app2/js/main_guide.js b/static/app2/js/main_guide.js new file mode 100755 index 0000000..968c02f --- /dev/null +++ b/static/app2/js/main_guide.js @@ -0,0 +1,86 @@ +mui.init({ + swipeBack: true //启用右滑关闭功能 +}); +/**/ +mui.back = function() {}; +mui.plusReady(function() { + var showGuide = plus.storage.getItem("lauchFlag"); + if(showGuide) { + //有值,说明已经显示过了,无需显示//关闭splash页面; + plus.navigator.closeSplashscreen(); + closeGuide(); + }else{ + launchScreen(); + } + function launchScreen() { + mui.ajax('http://www.juzi199.com/get_startup.php', { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + aysnc:false, + success: function(data) {//服务器返回响应,根据响应结果,分析是否登录成功; + if(1 == data.show){ + var html = ''; + var indicatorHtml = ''; + $.each(data.img, function() { + html += '<div class="mui-slider-item"><img class="guide-img" src="' + this.src + '"/></div>'; + indicatorHtml+='<div class="mui-indicator"></div>'; + }); + $(".mui-slider-group").html(html); + $(".mui-slider-indicator").html(indicatorHtml); + $('.mui-slider-item').first().addClass('mui-slider-item-duplicate'); + $('.mui-slider-item').last().append('<button id="close" class="mui-btn mui-btn-warning mui-btn-outlined">跳过</button>'); + $('.mui-indicator').first().addClass('mui-active'); + setTimeout(function(){ + plus.navigator.closeSplashscreen(); + },1000) + }else{ + plus.navigator.closeSplashscreen(); + closeGuide(); + } + //if(data.img.count() == 1){ + + //} + + }, + error: function(xhr, type, errorThrown) { + //异常处理; + //alert(errorThrown); + } + }); + setTimeout(function(){ + closeGuide(); + },6000) + } + mui('body').on('tap', '#close', function(){ + closeGuide(); + }) +// document.addEventListener('tap', function() { +// // //console.log("addEventListener: newintent"); +// //console.log(1) +// }, false); + + function closeGuide(){ + //显示启动导航 + mui.openWindow({ + id: 'index', + url: 'index.html', + show: { + }, + waiting: { + autoShow: false + } + }); + setTimeout(function(){ + //plus.storage.setItem("lauchFlag", "true"); //第一次登陆显示 + //plus.storage.removeItem("lauchFlag"); + //plus.navigator.setFullscreen(false); + plus.webview.currentWebview().close(); + },1000) + } +}); + +//立即体验按钮点击事件 +//document.getElementById("close").addEventListener('tap', function(event) { +// +//}, false); \ No newline at end of file diff --git a/static/app2/js/mapcommon.js b/static/app2/js/mapcommon.js new file mode 100755 index 0000000..6c08d47 --- /dev/null +++ b/static/app2/js/mapcommon.js @@ -0,0 +1,347 @@ +// var num = 1 / window.devicePixelRatio; +// // document.querySelector('meta').setAttribute('name', 'viewport') +// //document.querySelector('meta').setAttribute('content', 'width=device-width, initial-scale=' + num + ', maximum-scale=' + num + ', minimum-scale=' + num + ', user-scalable=no'); +// // document.querySelector('meta').setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no'); +// +// // browserRedirect(); +// function browserRedirect() { +// var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); +// var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); +// var width = w > h ? h : w; +// var sUserAgent = navigator.userAgent.toLowerCase(); +// var bIsIpad = sUserAgent.match(/ipad/i) == "ipad"; +// var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os"; +// var bIsMidp = sUserAgent.match(/midp/i) == "midp"; +// var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4"; +// var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb"; +// var bIsAndroid = sUserAgent.match(/android/i) == "android"; +// var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce"; +// var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile"; +// var bIsWX = sUserAgent.match(/MicroMessenger/i) == "micromessenger"; +// // document.writeln("您的浏览设备为:"); +// if(bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM || bIsWX) { +// width = width; +// // document.writeln("phone"); +// } else { +// width = 640; +// // document.writeln("pc"); +// } +// var fz = ~~(width * 64000 / 100) / 6400; +// document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz + "px"; +// var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px', '') * 6400) / 6400 +// if(fz !== realfz) { +// document.getElementsByTagName("html")[0].style.cssText = 'font-size:' + fz * (fz / realfz) + "px"; +// } +// +// } +// window.onresize = function(){ +// browserRedirect(); +// } + + +var EARTH_RADIUS = 6378137.0; //单位M + +var PI = Math.PI; + +function getRad(d) { + + return d * PI / 180.0; + +} + +// var dis = getFlatternDistance(118.515179,37.478422,118.51471,37.475623); + +/** + + * approx distance between two points on earth ellipsoid + + * @param {Object} lat1 + + * @param {Object} lng1 + + * @param {Object} lat2 + + * @param {Object} lng2 + + */ + +function getFlatternDistance(lat1, lng1, lat2, lng2) { + + var f = getRad((lat1 + lat2) / 2); + + var g = getRad((lat1 - lat2) / 2); + + var l = getRad((lng1 - lng2) / 2); + + var sg = Math.sin(g); + + var sl = Math.sin(l); + + var sf = Math.sin(f); + + var s, c, w, r, d, h1, h2; + + var a = EARTH_RADIUS; + + var fl = 1 / 298.257; + + sg = sg * sg; + + sl = sl * sl; + + sf = sf * sf; + + s = sg * (1 - sl) + (1 - sf) * sl; + + c = (1 - sg) * (1 - sl) + sf * sl; + + w = Math.atan(Math.sqrt(s / c)); + + r = Math.sqrt(s * c) / w; + + d = 2 * w * a; + + h1 = (3 * r - 1) / 2 / c; + + h2 = (3 * r + 1) / 2 / s; + + return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg)); + +} +/** + * 获取省份 + */ +function get_province() { + var url = '/index.php?m=Admin&c=Api&a=getRegion&level=1&parent_id=0'; + $.ajax({ + type: "GET", + url: url, + error: function(request) { + alert("服务器繁忙, 请联系管理员!"); + return; + }, + success: function(v) { + v = '<option value="0">选择省份</option>' + v; + $('#province').empty().html(v); + } + }); +} + + +/** + * 获取城市 + * @param t 省份select对象 + */ +function get_city(t) { + var parent_id = $(t).val(); + if (!parent_id > 0) { + return; + } + $('#twon').empty().css('display', 'none'); + var url = '/index.php?m=Home&c=Api&a=getRegion&level=2&parent_id=' + parent_id; + $.ajax({ + type: "GET", + url: url, + error: function(request) { + alert("服务器繁忙, 请联系管理员!"); + return; + }, + success: function(v) { + v = '<option value="0">选择城市</option>' + v; + $('#city').empty().html(v); + } + }); +} + +/** + * 获取地区 + * @param t 城市select对象 + */ +function get_area(t) { + var parent_id = $(t).val(); + if (!parent_id > 0) { + return; + } + var url = '/index.php?m=Home&c=Api&a=getRegion&level=3&parent_id=' + parent_id; + $.ajax({ + type: "GET", + url: url, + error: function(request) { + alert("服务器繁忙, 请联系管理员!"); + return; + }, + success: function(v) { + v = '<option value="0">选择区域</option>' + v; + $('#district').empty().html(v); + } + }); +} +// 获取最后一级乡镇 +function get_twon(obj) { + var parent_id = $(obj).val(); + var url = '/index.php?m=Home&c=Api&a=getTwon&parent_id=' + parent_id; + $.ajax({ + type: "GET", + url: url, + success: function(res) { + if (parseInt(res) == 0) { + $('#twon').empty().css('display', 'none'); + } else { + $('#twon').css('display', 'block'); + $('#twon').empty().html(res); + } + } + }); +} + +// 点击收藏商品 +function collect_goods(goods_id) { + $.ajax({ + type: "GET", + dataType: "json", + url: "/index.php?m=Home&c=goods&a=collect_goods&goods_id=" + goods_id, //+tab, + success: function(data) { + alert(data.msg); + } + }); +} + + +//加载地图 +function getMap(lng, lat) { +// var pcenter = new plus.maps.Point(lng,lat); // 地图中心点 +// var map = new plus.maps.Map('allmap'); +// map.centerAndZoom(pcenter, 15); // 设置地图的中心点和缩放级别 +// map.showUserLocation( true ); // 设置是否显示用户的位置 +// 还有很多属性可以设置,请参考官方文档 + var map = new BMap.Map("allmap"); + // var point = new BMap.Point("{$apply_info['lng']|default=118.514285}", "{$apply_info['lat']|default=37.478362}"); + var point = new BMap.Point(lng, lat); + map.centerAndZoom(point, 16); + var marker = new BMap.Marker(point); + map.clearOverlays(); + map.addOverlay(marker); + marker.setAnimation(BMAP_ANIMATION_BOUNCE); + function showInfo(e) { + parent.selectCallBack('data_lng', 'data_lat', document.getElementById('lng').value, document.getElementById('lat').value); + } + function showPoint(e) { + + document.getElementById('lat').value = e.point.lat; + document.getElementById('lng').value = e.point.lng; + var p = new BMap.Point(e.point.lng, e.point.lat); + var mk = new BMap.Marker(p); + map.clearOverlays(); + map.addOverlay(mk); + mk.setAnimation(BMAP_ANIMATION_BOUNCE); + // //console.log(BMAP_ANIMATION_BOUNCE); + } + map.enableScrollWheelZoom(true); + map.addControl(new BMap.NavigationControl()); + map.addEventListener("click", showPoint); + + function G(id) { + return document.getElementById(id); + } + + var ac = new BMap.Autocomplete({ + "input": "shopAddress", + "location": map + }); + ac.addEventListener("onhighlight", function(e) { + var str = ""; + var _value = e.fromitem.value; + var value = ""; + if (e.fromitem.index > -1) { + value = _value.province + _value.city + _value.district + _value.street + _value.business; + } + str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value; + + value = ""; + if (e.toitem.index > -1) { + _value = e.toitem.value; + value = _value.province + _value.city + _value.district + _value.street + _value.business; + } + str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value; + // G("searchResultPanel").innerHTML = str; + }); + var myValue; + ac.addEventListener("onconfirm", function(e) { + var _value = e.item.value; + myValue = _value.province + _value.city + _value.district + _value.street + _value.business; + G("searchResultPanel").innerHTML = "onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue; + + setPlace(); + }); + function setPlace() { + map.clearOverlays(); + + function myFun() { + var pp = local.getResults().getPoi(0).point; + map.centerAndZoom(pp, 18); + map.addOverlay(new BMap.Marker(pp)); + } + var local = new BMap.LocalSearch(map, { + onSearchComplete: myFun + }); + local.search(myValue); + } +} + + + +// 读取本地地址 +function getLocation(callback) { + // var object = obj; + plus.geolocation.getCurrentPosition(function(res) { + //成功回调 + var obj = new Object(); + obj.status = 1; + obj.lat = res.coords.latitude; //纬度 + obj.lng = res.coords.longitude; //经度 + callback(obj); + }, function(e) { + //失败回调 + //console.log('Gelocation Error: code - ' + e.code + '; message - ' + e.message); + switch (e.code) { + case 10: + obj.errStr = '请开启应用的定位权限'; + break; + case 9: + //mui.alert('请开启手机定位服务'); + obj.errStr = '请开启手机定位服务'; + break; + case 2: + if (e.message.indexOf("[geolocation:13]") > -1) { + //如果网络开启,定位失败,提示检查定位权限 + obj.errStr = '请开启应用的定位权限'; + } + if (e.message.indexOf("[geolocation:14]") > -1) { + //如果应用的权限开了,提示网络异常 + obj.errStr = '请检查网络是否正常'; + } + break; + case e.PERMISSION_DENIED: + obj.errStr = '请求定位被拒绝'; + break; + case e.POSITION_UNAVAILABLE: + obj.errStr = "位置信息不可用"; + break; + case e.TIMEOUT: + obj.errStr = "获取位置信息超时"; + break; + case e.UNKNOWN_ERROR: + obj.errStr = "未知错误"; + break; + } + + var obj = new Object(); + obj.errCode = e.code; + obj.status = 0; + callback(obj); + }, { + //超时未获取到经纬度信息 执行失败回调 (默认为5秒) + timeout: 3000 + }); + //JZL.saveItems('.user_pos', 'user_pos'); +} diff --git a/static/app2/js/memorandumlist.js b/static/app2/js/memorandumlist.js new file mode 100755 index 0000000..c1d997f --- /dev/null +++ b/static/app2/js/memorandumlist.js @@ -0,0 +1,7 @@ +mui.plusReady(function () { + + + $("body").on("tap" ,".add1",function () { + JZL.openWindow('addmemorandum.html', 'addmemorandum.html') + }) +}) \ No newline at end of file diff --git a/static/app2/js/msg.js b/static/app2/js/msg.js new file mode 100755 index 0000000..e1ab9cc --- /dev/null +++ b/static/app2/js/msg.js @@ -0,0 +1,102 @@ +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { + location.reload(); + }) + var token = localStorage.getItem('token'); + var num = 1; + var isOver = 1; + + function getMsg(pageNum, pagesizeNum) { + if(isOver == 1) { + isOver = 0; + } else { + return; + } + var data_msg = { + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + var arr = ["普通消息", "订单", "商品", "订单投诉", "结算信息", "提现信息", "订单评价"] + mui.ajax(hyhUrl('app/messages/msglist'), {  + headers: {  + "HYH-Token": token + }, + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + data = data.data; + if(data.Rows == '') { + $('.con1').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多消息</p>'); + + return; + } + $.each(data.Rows, function() { + html += '<div class="row clearfix shadown_wai" data-id="' + this.id + '"><div class="img"><img src="' + hyhImgUrl(this.img) + '" /></div><div class="r_right"><div class="r_r_top clearfix"><p class="rrt_left">' + arr[this.from] + '</p><p class="rrt_right">' + this.createTime + '</p></div><div class="r_r_con">' + this.msgContent + '</div></div></div>' + }); + + if(pageNum == 1) { + $('.con1').html(html) + } else if(pageNum > 1) { + $('.con1').append(html) + } + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + } + getMsg(1, 10); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num += 1; + getMsg(num, 10); + } + } + }) + $('.con1').on('tap', '.row', function() { + var id = $(this).attr('data-id'); + mui.openWindow({ + url: 'msg_con.html', + id: 'msg_con.html'+id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_msgId: id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/msg_con.js b/static/app2/js/msg_con.js new file mode 100755 index 0000000..5113503 --- /dev/null +++ b/static/app2/js/msg_con.js @@ -0,0 +1,31 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var msgId = self.data_msgId; + mui.ajax(hyhUrl('app/messages/getById'), {  + headers: {  + "HYH-Token": token + }, + data: { + msgId: msgId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + + if(data.status == 1) { + data = data.data; + var html = '<div class="time">' + data.createTime + '</div><div class="con_">' + data.msgContent + '</div>'; + $('.con_b').html(html); + } else { + console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +}) \ No newline at end of file diff --git a/static/app2/js/mui.js b/static/app2/js/mui.js new file mode 100755 index 0000000..978e8b5 --- /dev/null +++ b/static/app2/js/mui.js @@ -0,0 +1,8386 @@ +/*! + * ===================================================== + * Mui v3.7.2 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ +/** + * MUI核心JS + * @type _L4.$|Function + */ +var mui = (function(document, undefined) { + var readyRE = /complete|loaded|interactive/; + var idSelectorRE = /^#([\w-]+)$/; + var classSelectorRE = /^\.([\w-]+)$/; + var tagSelectorRE = /^[\w-]+$/; + var translateRE = /translate(?:3d)?\((.+?)\)/; + var translateMatrixRE = /matrix(3d)?\((.+?)\)/; + + var $ = function(selector, context) { + context = context || document; + if (!selector) + return wrap(); + if (typeof selector === 'object') + if ($.isArrayLike(selector)) { + return wrap($.slice.call(selector), null); + } else { + return wrap([selector], null); + } + if (typeof selector === 'function') + return $.ready(selector); + if (typeof selector === 'string') { + try { + selector = selector.trim(); + if (idSelectorRE.test(selector)) { + var found = document.getElementById(RegExp.$1); + return wrap(found ? [found] : []); + } + return wrap($.qsa(selector, context), selector); + } catch (e) {} + } + return wrap(); + }; + + var wrap = function(dom, selector) { + dom = dom || []; + Object.setPrototypeOf(dom, $.fn); + dom.selector = selector || ''; + return dom; + }; + + $.uuid = 0; + + $.data = {}; + /** + * extend(simple) + * @param {type} target + * @param {type} source + * @param {type} deep + * @returns {unresolved} + */ + $.extend = function() { //from jquery2 + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + if (typeof target === "boolean") { + deep = target; + + target = arguments[i] || {}; + i++; + } + + if (typeof target !== "object" && !$.isFunction(target)) { + target = {}; + } + + if (i === length) { + target = this; + i--; + } + + for (; i < length; i++) { + if ((options = arguments[i]) != null) { + for (name in options) { + src = target[name]; + copy = options[name]; + + if (target === copy) { + continue; + } + + if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && $.isArray(src) ? src : []; + + } else { + clone = src && $.isPlainObject(src) ? src : {}; + } + + target[name] = $.extend(deep, clone, copy); + + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + return target; + }; + /** + * mui noop(function) + */ + $.noop = function() {}; + /** + * mui slice(array) + */ + $.slice = [].slice; + /** + * mui filter(array) + */ + $.filter = [].filter; + + $.type = function(obj) { + return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object"; + }; + /** + * mui isArray + */ + $.isArray = Array.isArray || + function(object) { + return object instanceof Array; + }; + /** + * mui isArrayLike + * @param {Object} obj + */ + $.isArrayLike = function(obj) { + var length = !!obj && "length" in obj && obj.length; + var type = $.type(obj); + if (type === "function" || $.isWindow(obj)) { + return false; + } + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && (length - 1) in obj; + }; + /** + * mui isWindow(需考虑obj为undefined的情况) + */ + $.isWindow = function(obj) { + return obj != null && obj === obj.window; + }; + /** + * mui isObject + */ + $.isObject = function(obj) { + return $.type(obj) === "object"; + }; + /** + * mui isPlainObject + */ + $.isPlainObject = function(obj) { + return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype; + }; + /** + * mui isEmptyObject + * @param {Object} o + */ + $.isEmptyObject = function(o) { + for (var p in o) { + if (p !== undefined) { + return false; + } + } + return true; + }; + /** + * mui isFunction + */ + $.isFunction = function(value) { + return $.type(value) === "function"; + }; + /** + * mui querySelectorAll + * @param {type} selector + * @param {type} context + * @returns {Array} + */ + $.qsa = function(selector, context) { + context = context || document; + return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector)); + }; + /** + * ready(DOMContentLoaded) + * @param {type} callback + * @returns {_L6.$} + */ + $.ready = function(callback) { + if (readyRE.test(document.readyState)) { + callback($); + } else { + document.addEventListener('DOMContentLoaded', function() { + callback($); + }, false); + } + return this; + }; + /** + * 将 fn 缓存一段时间后, 再被调用执行 + * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中; + * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样; + * 调用返回函数的 stop 停止最后一次的 buffer 效果 + * @param {Object} fn + * @param {Object} ms + * @param {Object} context + */ + $.buffer = function(fn, ms, context) { + var timer; + var lastStart = 0; + var lastEnd = 0; + var ms = ms || 150; + + function run() { + if (timer) { + timer.cancel(); + timer = 0; + } + lastStart = $.now(); + fn.apply(context || this, arguments); + lastEnd = $.now(); + } + + return $.extend(function() { + if ( + (!lastStart) || // 从未运行过 + (lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒 + (lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒 + ) { + run.apply(this, arguments); + } else { + if (timer) { + timer.cancel(); + } + timer = $.later(run, ms, null, $.slice.call(arguments)); + } + }, { + stop: function() { + if (timer) { + timer.cancel(); + timer = 0; + } + } + }); + }; + /** + * each + * @param {type} elements + * @param {type} callback + * @returns {_L8.$} + */ + $.each = function(elements, callback, hasOwnProperty) { + if (!elements) { + return this; + } + if (typeof elements.length === 'number') { + [].every.call(elements, function(el, idx) { + return callback.call(el, idx, el) !== false; + }); + } else { + for (var key in elements) { + if (hasOwnProperty) { + if (elements.hasOwnProperty(key)) { + if (callback.call(elements[key], key, elements[key]) === false) return elements; + } + } else { + if (callback.call(elements[key], key, elements[key]) === false) return elements; + } + } + } + return this; + }; + $.focus = function(element) { + if ($.os.ios) { + setTimeout(function() { + element.focus(); + }, 10); + } else { + element.focus(); + } + }; + /** + * trigger event + * @param {type} element + * @param {type} eventType + * @param {type} eventData + * @returns {_L8.$} + */ + $.trigger = function(element, eventType, eventData) { + element.dispatchEvent(new CustomEvent(eventType, { + detail: eventData, + bubbles: true, + cancelable: true + })); + return this; + }; + /** + * getStyles + * @param {type} element + * @param {type} property + * @returns {styles} + */ + $.getStyles = function(element, property) { + var styles = element.ownerDocument.defaultView.getComputedStyle(element, null); + if (property) { + return styles.getPropertyValue(property) || styles[property]; + } + return styles; + }; + /** + * parseTranslate + * @param {type} translateString + * @param {type} position + * @returns {Object} + */ + $.parseTranslate = function(translateString, position) { + var result = translateString.match(translateRE || ''); + if (!result || !result[1]) { + result = ['', '0,0,0']; + } + result = result[1].split(","); + result = { + x: parseFloat(result[0]), + y: parseFloat(result[1]), + z: parseFloat(result[2]) + }; + if (position && result.hasOwnProperty(position)) { + return result[position]; + } + return result; + }; + /** + * parseTranslateMatrix + * @param {type} translateString + * @param {type} position + * @returns {Object} + */ + $.parseTranslateMatrix = function(translateString, position) { + var matrix = translateString.match(translateMatrixRE); + var is3D = matrix && matrix[1]; + if (matrix) { + matrix = matrix[2].split(","); + if (is3D === "3d") + matrix = matrix.slice(12, 15); + else { + matrix.push(0); + matrix = matrix.slice(4, 7); + } + } else { + matrix = [0, 0, 0]; + } + var result = { + x: parseFloat(matrix[0]), + y: parseFloat(matrix[1]), + z: parseFloat(matrix[2]) + }; + if (position && result.hasOwnProperty(position)) { + return result[position]; + } + return result; + }; + $.hooks = {}; + $.addAction = function(type, hook) { + var hooks = $.hooks[type]; + if (!hooks) { + hooks = []; + } + hook.index = hook.index || 1000; + hooks.push(hook); + hooks.sort(function(a, b) { + return a.index - b.index; + }); + $.hooks[type] = hooks; + return $.hooks[type]; + }; + $.doAction = function(type, callback) { + if ($.isFunction(callback)) { //指定了callback + $.each($.hooks[type], callback); + } else { //未指定callback,直接执行 + $.each($.hooks[type], function(index, hook) { + return !hook.handle(); + }); + } + }; + /** + * setTimeout封装 + * @param {Object} fn + * @param {Object} when + * @param {Object} context + * @param {Object} data + */ + $.later = function(fn, when, context, data) { + when = when || 0; + var m = fn; + var d = data; + var f; + var r; + + if (typeof fn === 'string') { + m = context[fn]; + } + + f = function() { + m.apply(context, $.isArray(d) ? d : [d]); + }; + + r = setTimeout(f, when); + + return { + id: r, + cancel: function() { + clearTimeout(r); + } + }; + }; + $.now = Date.now || function() { + return +new Date(); + }; + var class2type = {}; + $.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) { + class2type["[object " + name + "]"] = name.toLowerCase(); + }); + if (window.JSON) { + $.parseJSON = JSON.parse; + } + /** + * $.fn + */ + $.fn = { + each: function(callback) { + [].every.call(this, function(el, idx) { + return callback.call(el, idx, el) !== false; + }); + return this; + } + }; + + /** + * 兼容 AMD 模块 + **/ + if (typeof define === 'function' && define.amd) { + define('mui', [], function() { + return $; + }); + } + + return $; +})(document); +//window.mui = mui; +//'$' in window || (window.$ = mui); +/** + * $.os + * @param {type} $ + * @returns {undefined} + */ +(function($, window) { + function detect(ua) { + this.os = {}; + var funcs = [ + + function() { //wechat + var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i); + if (wechat) { //wechat + this.os.wechat = { + version: wechat[2].replace(/_/g, '.') + }; + } + return false; + }, + function() { //android + var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); + if (android) { + this.os.android = true; + this.os.version = android[2]; + + this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion)); + } + return this.os.android === true; + }, + function() { //ios + var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/); + if (iphone) { //iphone + this.os.ios = this.os.iphone = true; + this.os.version = iphone[2].replace(/_/g, '.'); + } else { + var ipad = ua.match(/(iPad).*OS\s([\d_]+)/); + if (ipad) { //ipad + this.os.ios = this.os.ipad = true; + this.os.version = ipad[2].replace(/_/g, '.'); + } + } + return this.os.ios === true; + } + ]; + [].every.call(funcs, function(func) { + return !func.call($); + }); + } + detect.call($, navigator.userAgent); +})(mui, window); +/** + * $.os.plus + * @param {type} $ + * @returns {undefined} + */ +(function($, document) { + function detect(ua) { + this.os = this.os || {}; + var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser? + if (plus) { + this.os.plus = true; + $(function() { + document.body.classList.add('mui-plus'); + }); + if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识 + this.os.stream = true; + $(function() { + document.body.classList.add('mui-plus-stream'); + }); + } + } + } + detect.call($, navigator.userAgent); +})(mui, document); +/** + * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener) + * @param {Object} $ + */ +(function($) { + if ('ontouchstart' in window) { + $.isTouchable = true; + $.EVENT_START = 'touchstart'; + $.EVENT_MOVE = 'touchmove'; + $.EVENT_END = 'touchend'; + } else { + $.isTouchable = false; + $.EVENT_START = 'mousedown'; + $.EVENT_MOVE = 'mousemove'; + $.EVENT_END = 'mouseup'; + } + $.EVENT_CANCEL = 'touchcancel'; + $.EVENT_CLICK = 'click'; + + var _mid = 1; + var delegates = {}; + //需要wrap的函数 + var eventMethods = { + preventDefault: 'isDefaultPrevented', + stopImmediatePropagation: 'isImmediatePropagationStopped', + stopPropagation: 'isPropagationStopped' + }; + //默认true返回函数 + var returnTrue = function() { + return true + }; + //默认false返回函数 + var returnFalse = function() { + return false + }; + //wrap浏览器事件 + var compatible = function(event, target) { + if (!event.detail) { + event.detail = { + currentTarget: target + }; + } else { + event.detail.currentTarget = target; + } + $.each(eventMethods, function(name, predicate) { + var sourceMethod = event[name]; + event[name] = function() { + this[predicate] = returnTrue; + return sourceMethod && sourceMethod.apply(event, arguments) + } + event[predicate] = returnFalse; + }, true); + return event; + }; + //简单的wrap对象_mid + var mid = function(obj) { + return obj && (obj._mid || (obj._mid = _mid++)); + }; + //事件委托对象绑定的事件回调列表 + var delegateFns = {}; + //返回事件委托的wrap事件回调 + var delegateFn = function(element, event, selector, callback) { + return function(e) { + //same event + var callbackObjs = delegates[element._mid][event]; + var handlerQueue = []; + var target = e.target; + var selectorAlls = {}; + for (; target && target !== document; target = target.parentNode) { + if (target === element) { + break; + } + if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) { + break; + } + var matches = {}; + $.each(callbackObjs, function(selector, callbacks) { //same selector + selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element)); + if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) { + if (!matches[selector]) { + matches[selector] = callbacks; + } + } + }, true); + if (!$.isEmptyObject(matches)) { + handlerQueue.push({ + element: target, + handlers: matches + }); + } + } + selectorAlls = null; + e = compatible(e); //compatible event + $.each(handlerQueue, function(index, handler) { + target = handler.element; + var tagName = target.tagName; + if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) { + e.preventDefault(); + e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); + } + $.each(handler.handlers, function(index, handler) { + $.each(handler, function(index, callback) { + if (callback.call(target, e) === false) { + e.preventDefault(); + e.stopPropagation(); + } + }, true); + }, true) + if (e.isPropagationStopped()) { + return false; + } + }, true); + }; + }; + var findDelegateFn = function(element, event) { + var delegateCallbacks = delegateFns[mid(element)]; + var result = []; + if (delegateCallbacks) { + result = []; + if (event) { + var filterFn = function(fn) { + return fn.type === event; + } + return delegateCallbacks.filter(filterFn); + } else { + result = delegateCallbacks; + } + } + return result; + }; + var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; + /** + * mui delegate events + * @param {type} event + * @param {type} selector + * @param {type} callback + * @returns {undefined} + */ + $.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持 + return this.each(function() { + var element = this; + mid(element); + mid(callback); + var isAddEventListener = false; + var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {}); + var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {})); + if ($.isEmptyObject(delegateCallbackObjs)) { + isAddEventListener = true; + } + var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []); + delegateCallbacks.push(callback); + if (isAddEventListener) { + var delegateFnArray = delegateFns[mid(element)]; + if (!delegateFnArray) { + delegateFnArray = []; + } + var delegateCallback = delegateFn(element, event, selector, callback); + delegateFnArray.push(delegateCallback); + delegateCallback.i = delegateFnArray.length - 1; + delegateCallback.type = event; + delegateFns[mid(element)] = delegateFnArray; + element.addEventListener(event, delegateCallback); + if (event === 'tap') { //TODO 需要找个更好的解决方案 + element.addEventListener('click', function(e) { + if (e.target) { + var tagName = e.target.tagName; + if (!preventDefaultException.test(tagName)) { + if (tagName === 'A') { + var href = e.target.href; + if (!(href && ~href.indexOf('tel:'))) { + e.preventDefault(); + } + } else { + e.preventDefault(); + } + } + } + }); + } + } + }); + }; + $.fn.off = function(event, selector, callback) { + return this.each(function() { + var _mid = mid(this); + if (!event) { //mui(selector).off(); + delegates[_mid] && delete delegates[_mid]; + } else if (!selector) { //mui(selector).off(event); + delegates[_mid] && delete delegates[_mid][event]; + } else if (!callback) { //mui(selector).off(event,selector); + delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector]; + } else { //mui(selector).off(event,selector,callback); + var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector]; + $.each(delegateCallbacks, function(index, delegateCallback) { + if (mid(delegateCallback) === mid(callback)) { + delegateCallbacks.splice(index, 1); + return false; + } + }, true); + } + if (delegates[_mid]) { + //如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调 + if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) { + findDelegateFn(this, event).forEach(function(fn) { + this.removeEventListener(fn.type, fn); + delete delegateFns[_mid][fn.i]; + }.bind(this)); + } + } else { + //如果delegates[_mid]已不存在,删除所有 + findDelegateFn(this).forEach(function(fn) { + this.removeEventListener(fn.type, fn); + delete delegateFns[_mid][fn.i]; + }.bind(this)); + } + }); + + }; +})(mui); +/** + * mui target(action>popover>modal>tab>toggle) + */ +(function($, window, document) { + /** + * targets + */ + $.targets = {}; + /** + * target handles + */ + $.targetHandles = []; + /** + * register target + * @param {type} target + * @returns {$.targets} + */ + $.registerTarget = function(target) { + + target.index = target.index || 1000; + + $.targetHandles.push(target); + + $.targetHandles.sort(function(a, b) { + return a.index - b.index; + }); + + return $.targetHandles; + }; + window.addEventListener($.EVENT_START, function(event) { + var target = event.target; + var founds = {}; + for (; target && target !== document; target = target.parentNode) { + var isFound = false; + $.each($.targetHandles, function(index, targetHandle) { + var name = targetHandle.name; + if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) { + $.targets[name] = targetHandle.handle(event, target); + if ($.targets[name]) { + founds[name] = true; + if (targetHandle.isContinue !== true) { + isFound = true; + } + } + } else { + if (!founds[name]) { + if (targetHandle.isReset !== false) + $.targets[name] = false; + } + } + }); + if (isFound) { + break; + } + } + }); + window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A) + var target = event.target; + var isFound = false; + for (; target && target !== document; target = target.parentNode) { + if (target.tagName === 'A') { + $.each($.targetHandles, function(index, targetHandle) { + var name = targetHandle.name; + if (targetHandle.hasOwnProperty('handle')) { + if (targetHandle.handle(event, target)) { + isFound = true; + event.preventDefault(); + return false; + } + } + }); + if (isFound) { + break; + } + } + } + }); +})(mui, window, document); +/** + * fixed trim + * @param {type} undefined + * @returns {undefined} + */ +(function(undefined) { + if (String.prototype.trim === undefined) { // fix for iOS 3.2 + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ''); + }; + } + Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) { + obj['__proto__'] = proto; + return obj; + }; + +})(); +/** + * fixed CustomEvent + */ +(function() { + if (typeof window.CustomEvent === 'undefined') { + function CustomEvent(event, params) { + params = params || { + bubbles: false, + cancelable: false, + detail: undefined + }; + var evt = document.createEvent('Events'); + var bubbles = true; + for (var name in params) { + (name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]); + } + evt.initEvent(event, bubbles, true); + return evt; + }; + CustomEvent.prototype = window.Event.prototype; + window.CustomEvent = CustomEvent; + } +})(); +/* + A shim for non ES5 supporting browsers. + Adds function bind to Function prototype, so that you can do partial application. + Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees. +*/ + +Function.prototype.bind = Function.prototype.bind || function(to) { + // Make an array of our arguments, starting from second argument + var partial = Array.prototype.splice.call(arguments, 1), + // We'll need the original function. + fn = this; + var bound = function() { + // Join the already applied arguments to the now called ones (after converting to an array again). + var args = partial.concat(Array.prototype.splice.call(arguments, 0)); + // If not being called as a constructor + if (!(this instanceof bound)) { + // return the result of the function called bound to target and partially applied. + return fn.apply(to, args); + } + // If being called as a constructor, apply the function bound to self. + fn.apply(this, args); + } + // Attach the prototype of the function to our newly created function. + bound.prototype = fn.prototype; + return bound; +}; +/** + * mui fixed classList + * @param {type} document + * @returns {undefined} + */ +(function(document) { + if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') { + + Object.defineProperty(HTMLElement.prototype, 'classList', { + get: function() { + var self = this; + function update(fn) { + return function(value) { + var classes = self.className.split(/\s+/), + index = classes.indexOf(value); + + fn(classes, index, value); + self.className = classes.join(" "); + }; + } + + var ret = { + add: update(function(classes, index, value) { + ~index || classes.push(value); + }), + remove: update(function(classes, index) { + ~index && classes.splice(index, 1); + }), + toggle: update(function(classes, index, value) { + ~index ? classes.splice(index, 1) : classes.push(value); + }), + contains: function(value) { + return !!~self.className.split(/\s+/).indexOf(value); + }, + item: function(i) { + return self.className.split(/\s+/)[i] || null; + } + }; + + Object.defineProperty(ret, 'length', { + get: function() { + return self.className.split(/\s+/).length; + } + }); + + return ret; + } + }); + } +})(document); + +/** + * mui fixed requestAnimationFrame + * @param {type} window + * @returns {undefined} + */ +(function(window) { + if (!window.requestAnimationFrame) { + var lastTime = 0; + window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) { + clearTimeout(id); + }; + }; +}(window)); +/** + * fastclick(only for radio,checkbox) + */ +(function($, window, name) { + if (!$.os.android && !$.os.ios) { //目前仅识别android和ios + return; + } + if (window.FastClick) { + return; + } + + var handle = function(event, target) { + if (target.tagName === 'LABEL') { + if (target.parentNode) { + target = target.parentNode.querySelector('input'); + } + } + if (target && (target.type === 'radio' || target.type === 'checkbox')) { + if (!target.disabled) { //disabled + return target; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 40, + handle: handle, + target: false + }); + var dispatchEvent = function(event) { + var targetElement = $.targets.click; + if (targetElement) { + var clickEvent, touch; + // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect + if (document.activeElement && document.activeElement !== targetElement) { + document.activeElement.blur(); + } + touch = event.detail.gesture.changedTouches[0]; + // Synthesise a click event, with an extra attribute so it can be tracked + clickEvent = document.createEvent('MouseEvents'); + clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); + clickEvent.forwardedTouchEvent = true; + targetElement.dispatchEvent(clickEvent); + event.detail && event.detail.gesture.preventDefault(); + } + }; + window.addEventListener('tap', dispatchEvent); + window.addEventListener('doubletap', dispatchEvent); + //捕获 + window.addEventListener('click', function(event) { + if ($.targets.click) { + if (!event.forwardedTouchEvent) { //stop click + if (event.stopImmediatePropagation) { + event.stopImmediatePropagation(); + } else { + // Part of the hack for browsers that don't support Event#stopImmediatePropagation + event.propagationStopped = true; + } + event.stopPropagation(); + event.preventDefault(); + return false; + } + } + }, true); + +})(mui, window, 'click'); +(function($, document) { + $(function() { + if (!$.os.ios) { + return; + } + var CLASS_FOCUSIN = 'mui-focusin'; + var CLASS_BAR_TAB = 'mui-bar-tab'; + var CLASS_BAR_FOOTER = 'mui-bar-footer'; + var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary'; + var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab'; + // var content = document.querySelector('.' + CLASS_CONTENT); + // if (content) { + // document.body.insertBefore(content, document.body.firstElementChild); + // } + document.addEventListener('focusin', function(e) { + if ($.os.plus) { //在父webview里边不fix + if (window.plus) { + if (plus.webview.currentWebview().children().length > 0) { + return; + } + } + } + var target = e.target; + //TODO 需考虑所有键盘弹起的情况 + if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) { + if (target.disabled || target.readOnly) { + return; + } + document.body.classList.add(CLASS_FOCUSIN); + var isFooter = false; + for (; target && target !== document; target = target.parentNode) { + var classList = target.classList; + if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) { + isFooter = true; + break; + } + } + if (isFooter) { + var scrollTop = document.body.scrollHeight; + var scrollLeft = document.body.scrollLeft; + setTimeout(function() { + window.scrollTo(scrollLeft, scrollTop); + }, 20); + } + } + }); + document.addEventListener('focusout', function(e) { + var classList = document.body.classList; + if (classList.contains(CLASS_FOCUSIN)) { + classList.remove(CLASS_FOCUSIN); + setTimeout(function() { + window.scrollTo(document.body.scrollLeft, document.body.scrollTop); + }, 20); + } + }); + }); +})(mui, document); +/** + * mui namespace(optimization) + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.namespace = 'mui'; + $.classNamePrefix = $.namespace + '-'; + $.classSelectorPrefix = '.' + $.classNamePrefix; + /** + * 返回正确的className + * @param {type} className + * @returns {String} + */ + $.className = function(className) { + return $.classNamePrefix + className; + }; + /** + * 返回正确的classSelector + * @param {type} classSelector + * @returns {String} + */ + $.classSelector = function(classSelector) { + return classSelector.replace(/\./g, $.classSelectorPrefix); + }; + /** + * 返回正确的eventName + * @param {type} event + * @param {type} module + * @returns {String} + */ + $.eventName = function(event, module) { + return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : ''); + }; +})(mui); + +/** + * mui gestures + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + $.gestures = { + session: {} + }; + /** + * Gesture preventDefault + * @param {type} e + * @returns {undefined} + */ + $.preventDefault = function(e) { + e.preventDefault(); + }; + /** + * Gesture stopPropagation + * @param {type} e + * @returns {undefined} + */ + $.stopPropagation = function(e) { + e.stopPropagation(); + }; + + /** + * register gesture + * @param {type} gesture + * @returns {$.gestures} + */ + $.addGesture = function(gesture) { + return $.addAction('gestures', gesture); + + }; + + var round = Math.round; + var abs = Math.abs; + var sqrt = Math.sqrt; + var atan = Math.atan; + var atan2 = Math.atan2; + /** + * distance + * @param {type} p1 + * @param {type} p2 + * @returns {Number} + */ + var getDistance = function(p1, p2, props) { + if(!props) { + props = ['x', 'y']; + } + var x = p2[props[0]] - p1[props[0]]; + var y = p2[props[1]] - p1[props[1]]; + return sqrt((x * x) + (y * y)); + }; + /** + * scale + * @param {Object} starts + * @param {Object} moves + */ + var getScale = function(starts, moves) { + if(starts.length >= 2 && moves.length >= 2) { + var props = ['pageX', 'pageY']; + return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props); + } + return 1; + }; + /** + * angle + * @param {type} p1 + * @param {type} p2 + * @returns {Number} + */ + var getAngle = function(p1, p2, props) { + if(!props) { + props = ['x', 'y']; + } + var x = p2[props[0]] - p1[props[0]]; + var y = p2[props[1]] - p1[props[1]]; + return atan2(y, x) * 180 / Math.PI; + }; + /** + * direction + * @param {Object} x + * @param {Object} y + */ + var getDirection = function(x, y) { + if(x === y) { + return ''; + } + if(abs(x) >= abs(y)) { + return x > 0 ? 'left' : 'right'; + } + return y > 0 ? 'up' : 'down'; + }; + /** + * rotation + * @param {Object} start + * @param {Object} end + */ + var getRotation = function(start, end) { + var props = ['pageX', 'pageY']; + return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props); + }; + /** + * px per ms + * @param {Object} deltaTime + * @param {Object} x + * @param {Object} y + */ + var getVelocity = function(deltaTime, x, y) { + return { + x: x / deltaTime || 0, + y: y / deltaTime || 0 + }; + }; + /** + * detect gestures + * @param {type} event + * @param {type} touch + * @returns {undefined} + */ + var detect = function(event, touch) { + if($.gestures.stoped) { + return; + } + $.doAction('gestures', function(index, gesture) { + if(!$.gestures.stoped) { + if($.options.gestureConfig[gesture.name] !== false) { + gesture.handle(event, touch); + } + } + }); + }; + /** + * 暂时无用 + * @param {Object} node + * @param {Object} parent + */ + var hasParent = function(node, parent) { + while(node) { + if(node == parent) { + return true; + } + node = node.parentNode; + } + return false; + }; + + var uniqueArray = function(src, key, sort) { + var results = []; + var values = []; + var i = 0; + + while(i < src.length) { + var val = key ? src[i][key] : src[i]; + if(values.indexOf(val) < 0) { + results.push(src[i]); + } + values[i] = val; + i++; + } + + if(sort) { + if(!key) { + results = results.sort(); + } else { + results = results.sort(function sortUniqueArray(a, b) { + return a[key] > b[key]; + }); + } + } + + return results; + }; + var getMultiCenter = function(touches) { + var touchesLength = touches.length; + if(touchesLength === 1) { + return { + x: round(touches[0].pageX), + y: round(touches[0].pageY) + }; + } + + var x = 0; + var y = 0; + var i = 0; + while(i < touchesLength) { + x += touches[i].pageX; + y += touches[i].pageY; + i++; + } + + return { + x: round(x / touchesLength), + y: round(y / touchesLength) + }; + }; + var multiTouch = function() { + return $.options.gestureConfig.pinch; + }; + var copySimpleTouchData = function(touch) { + var touches = []; + var i = 0; + while(i < touch.touches.length) { + touches[i] = { + pageX: round(touch.touches[i].pageX), + pageY: round(touch.touches[i].pageY) + }; + i++; + } + return { + timestamp: $.now(), + gesture: touch.gesture, + touches: touches, + center: getMultiCenter(touch.touches), + deltaX: touch.deltaX, + deltaY: touch.deltaY + }; + }; + + var calDelta = function(touch) { + var session = $.gestures.session; + var center = touch.center; + var offset = session.offsetDelta || {}; + var prevDelta = session.prevDelta || {}; + var prevTouch = session.prevTouch || {}; + + if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) { + prevDelta = session.prevDelta = { + x: prevTouch.deltaX || 0, + y: prevTouch.deltaY || 0 + }; + + offset = session.offsetDelta = { + x: center.x, + y: center.y + }; + } + touch.deltaX = prevDelta.x + (center.x - offset.x); + touch.deltaY = prevDelta.y + (center.y - offset.y); + }; + var calTouchData = function(touch) { + var session = $.gestures.session; + var touches = touch.touches; + var touchesLength = touches.length; + + if(!session.firstTouch) { + session.firstTouch = copySimpleTouchData(touch); + } + + if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) { + session.firstMultiTouch = copySimpleTouchData(touch); + } else if(touchesLength === 1) { + session.firstMultiTouch = false; + } + + var firstTouch = session.firstTouch; + var firstMultiTouch = session.firstMultiTouch; + var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center; + + var center = touch.center = getMultiCenter(touches); + touch.timestamp = $.now(); + touch.deltaTime = touch.timestamp - firstTouch.timestamp; + + touch.angle = getAngle(offsetCenter, center); + touch.distance = getDistance(offsetCenter, center); + + calDelta(touch); + + touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY); + + touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1; + touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0; + + calIntervalTouchData(touch); + + }; + var CAL_INTERVAL = 25; + var calIntervalTouchData = function(touch) { + var session = $.gestures.session; + var last = session.lastInterval || touch; + var deltaTime = touch.timestamp - last.timestamp; + var velocity; + var velocityX; + var velocityY; + var direction; + + if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) { + var deltaX = last.deltaX - touch.deltaX; + var deltaY = last.deltaY - touch.deltaY; + + var v = getVelocity(deltaTime, deltaX, deltaY); + velocityX = v.x; + velocityY = v.y; + velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; + direction = getDirection(deltaX, deltaY) || last.direction; + + session.lastInterval = touch; + } else { + velocity = last.velocity; + velocityX = last.velocityX; + velocityY = last.velocityY; + direction = last.direction; + } + + touch.velocity = velocity; + touch.velocityX = velocityX; + touch.velocityY = velocityY; + touch.direction = direction; + }; + var targetIds = {}; + var convertTouches = function(touches) { + for(var i = 0; i < touches.length; i++) { + !touches['identifier'] && (touches['identifier'] = 0); + } + return touches; + }; + var getTouches = function(event, touch) { + var allTouches = convertTouches($.slice.call(event.touches || [event])); + + var type = event.type; + + var targetTouches = []; + var changedTargetTouches = []; + + //当touchstart或touchmove且touches长度为1,直接获得all和changed + if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) { + targetIds[allTouches[0].identifier] = true; + targetTouches = allTouches; + changedTargetTouches = allTouches; + touch.target = event.target; + } else { + var i = 0; + var targetTouches = []; + var changedTargetTouches = []; + var changedTouches = convertTouches($.slice.call(event.changedTouches || [event])); + + touch.target = event.target; + var sessionTarget = $.gestures.session.target || event.target; + targetTouches = allTouches.filter(function(touch) { + return hasParent(touch.target, sessionTarget); + }); + + if(type === $.EVENT_START) { + i = 0; + while(i < targetTouches.length) { + targetIds[targetTouches[i].identifier] = true; + i++; + } + } + + i = 0; + while(i < changedTouches.length) { + if(targetIds[changedTouches[i].identifier]) { + changedTargetTouches.push(changedTouches[i]); + } + if(type === $.EVENT_END || type === $.EVENT_CANCEL) { + delete targetIds[changedTouches[i].identifier]; + } + i++; + } + + if(!changedTargetTouches.length) { + return false; + } + } + targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true); + var touchesLength = targetTouches.length; + var changedTouchesLength = changedTargetTouches.length; + if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first + touch.isFirst = true; + $.gestures.touch = $.gestures.session = { + target: event.target + }; + } + touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0)); + + touch.touches = targetTouches; + touch.changedTouches = changedTargetTouches; + return true; + + }; + var handleTouchEvent = function(event) { + var touch = { + gesture: event + }; + var touches = getTouches(event, touch); + if(!touches) { + return; + } + calTouchData(touch); + detect(event, touch); + $.gestures.session.prevTouch = touch; + if(event.type === $.EVENT_END && !$.isTouchable) { + $.gestures.touch = $.gestures.session = {}; + } + }; + var supportsPassive = (function checkPassiveListener() { + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + supportsPassive = true; + }, + }); + window.addEventListener('testPassiveListener', null, opts); + } catch(e) { + // No support + } + return supportsPassive; + }()) + window.addEventListener($.EVENT_START, handleTouchEvent); + window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? { + passive: false, + capture: false + } : false); + window.addEventListener($.EVENT_END, handleTouchEvent); + window.addEventListener($.EVENT_CANCEL, handleTouchEvent); + //fixed hashchange(android) + window.addEventListener($.EVENT_CLICK, function(e) { + //TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等 + if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) { + e.preventDefault(); + } + }, true); + + //增加原生滚动识别 + $.isScrolling = false; + var scrollingTimeout = null; + window.addEventListener('scroll', function() { + $.isScrolling = true; + scrollingTimeout && clearTimeout(scrollingTimeout); + scrollingTimeout = setTimeout(function() { + $.isScrolling = false; + }, 250); + }); +})(mui, window); +/** + * mui gesture flick[left|right|up|down] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var flickStartTime = 0; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + var now = $.now(); + switch (event.type) { + case $.EVENT_MOVE: + if (now - flickStartTime > 300) { + flickStartTime = now; + session.flickStart = touch.center; + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + touch.flick = false; + if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) { + touch.flick = true; + touch.flickTime = now - flickStartTime; + touch.flickDistanceX = touch.center.x - session.flickStart.x; + touch.flickDistanceY = touch.center.y - session.flickStart.y; + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + } + break; + } + + }; + /** + * mui gesture flick + */ + $.addGesture({ + name: name, + index: 5, + handle: handle, + options: { + flickMaxTime: 200, + flickMinDistince: 10 + } + }); +})(mui, 'flick'); +/** + * mui gesture swipe[left|right|up|down] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var session = $.gestures.session; + if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) { + var options = this.options; + touch.swipe = false; + //TODO 后续根据velocity计算 + if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) { + touch.swipe = true; + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + } + } + }; + /** + * mui gesture swipe + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + swipeMaxTime: 300, + swipeMinDistince: 18 + } + }); +})(mui, 'swipe'); +/** + * mui gesture drag[start|left|right|up|down|end] + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var session = $.gestures.session; + switch (event.type) { + case $.EVENT_START: + break; + case $.EVENT_MOVE: + if (!touch.direction || !session.target) { + return; + } + //修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套 + if (session.lockDirection && session.startDirection) { + if (session.startDirection && session.startDirection !== touch.direction) { + if (session.startDirection === 'up' || session.startDirection === 'down') { + touch.direction = touch.deltaY < 0 ? 'up' : 'down'; + } else { + touch.direction = touch.deltaX < 0 ? 'left' : 'right'; + } + } + } + + if (!session.drag) { + session.drag = true; + $.trigger(session.target, name + 'start', touch); + } + $.trigger(session.target, name, touch); + $.trigger(session.target, name + touch.direction, touch); + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if (session.drag && touch.isFinal) { + $.trigger(session.target, name + 'end', touch); + } + break; + } + }; + /** + * mui gesture drag + */ + $.addGesture({ + name: name, + index: 20, + handle: handle, + options: { + fingers: 1 + } + }); +})(mui, 'drag'); +/** + * mui gesture tap and doubleTap + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var lastTarget; + var lastTapTime; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_END: + if (!touch.isFinal) { + return; + } + var target = session.target; + if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) { + return; + } + if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) { + if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target + if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) { + $.trigger(target, 'doubletap', touch); + lastTapTime = $.now(); + lastTarget = target; + return; + } + } + $.trigger(target, name, touch); + lastTapTime = $.now(); + lastTarget = target; + } + break; + } + }; + /** + * mui gesture tap + */ + $.addGesture({ + name: name, + index: 30, + handle: handle, + options: { + fingers: 1, + tapMaxInterval: 300, + tapMaxDistance: 5, + tapMaxTime: 250 + } + }); +})(mui, 'tap'); +/** + * mui gesture longtap + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var timer; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_START: + clearTimeout(timer); + timer = setTimeout(function() { + $.trigger(session.target, name, touch); + }, options.holdTimeout); + break; + case $.EVENT_MOVE: + if (touch.distance > options.holdThreshold) { + clearTimeout(timer); + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + clearTimeout(timer); + break; + } + }; + /** + * mui gesture longtap + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + fingers: 1, + holdTimeout: 500, + holdThreshold: 2 + } + }); +})(mui, 'longtap'); +/** + * mui gesture hold + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var timer; + var handle = function(event, touch) { + var session = $.gestures.session; + var options = this.options; + switch (event.type) { + case $.EVENT_START: + if ($.options.gestureConfig.hold) { + timer && clearTimeout(timer); + timer = setTimeout(function() { + touch.hold = true; + $.trigger(session.target, name, touch); + }, options.holdTimeout); + } + break; + case $.EVENT_MOVE: + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if (timer) { + clearTimeout(timer) && (timer = null); + $.trigger(session.target, 'release', touch); + } + break; + } + }; + /** + * mui gesture hold + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + fingers: 1, + holdTimeout: 0 + } + }); +})(mui, 'hold'); +/** + * mui gesture pinch + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var handle = function(event, touch) { + var options = this.options; + var session = $.gestures.session; + switch (event.type) { + case $.EVENT_START: + break; + case $.EVENT_MOVE: + if ($.options.gestureConfig.pinch) { + if (touch.touches.length < 2) { + return; + } + if (!session.pinch) { //start + session.pinch = true; + $.trigger(session.target, name + 'start', touch); + } + $.trigger(session.target, name, touch); + var scale = touch.scale; + var rotation = touch.rotation; + var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale; + var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。 + if (scale > lastScale) { //out + lastScale = scale - scaleDiff; + $.trigger(session.target, name + 'out', touch); + } //in + else if (scale < lastScale) { + lastScale = scale + scaleDiff; + $.trigger(session.target, name + 'in', touch); + } + if (Math.abs(rotation) > options.minRotationAngle) { + $.trigger(session.target, 'rotate', touch); + } + } + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) { + session.pinch = false; + $.trigger(session.target, name + 'end', touch); + } + break; + } + }; + /** + * mui gesture pinch + */ + $.addGesture({ + name: name, + index: 10, + handle: handle, + options: { + minRotationAngle: 0 + } + }); +})(mui, 'pinch'); +/** + * mui.init + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.global = $.options = { + gestureConfig: { + tap: true, + doubletap: false, + longtap: false, + hold: false, + flick: true, + swipe: true, + drag: true, + pinch: false + } + }; + /** + * + * @param {type} options + * @returns {undefined} + */ + $.initGlobal = function(options) { + $.options = $.extend(true, $.global, options); + return this; + }; + var inits = {}; + + /** + * 单页配置 初始化 + * @param {object} options + */ + $.init = function(options) { + $.options = $.extend(true, $.global, options || {}); + $.ready(function() { + $.doAction('inits', function(index, init) { + var isInit = !!(!inits[init.name] || init.repeat); + if (isInit) { + init.handle.call($); + inits[init.name] = true; + } + }); + }); + return this; + }; + + /** + * 增加初始化执行流程 + * @param {function} init + */ + $.addInit = function(init) { + return $.addAction('inits', init); + }; + /** + * 处理html5版本subpages + */ + $.addInit({ + name: 'iframe', + index: 100, + handle: function() { + var options = $.options; + var subpages = options.subpages || []; + if (!$.os.plus && subpages.length) { + //暂时只处理单个subpage。后续可以考虑支持多个subpage + createIframe(subpages[0]); + } + } + }); + var createIframe = function(options) { + var wrapper = document.createElement('div'); + wrapper.className = 'mui-iframe-wrapper'; + var styles = options.styles || {}; + if (typeof styles.top !== 'string') { + styles.top = '0px'; + } + if (typeof styles.bottom !== 'string') { + styles.bottom = '0px'; + } + wrapper.style.top = styles.top; + wrapper.style.bottom = styles.bottom; + var iframe = document.createElement('iframe'); + iframe.src = options.url; + iframe.id = options.id || options.url; + iframe.name = iframe.id; + wrapper.appendChild(iframe); + document.body.appendChild(wrapper); + //目前仅处理微信 + $.os.wechat && handleScroll(wrapper, iframe); + }; + + function handleScroll(wrapper, iframe) { + var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src; + var scrollTop = (parseFloat(localStorage.getItem(key)) || 0); + if (scrollTop) { + (function(y) { + iframe.onload = function() { + window.scrollTo(0, y); + }; + })(scrollTop); + } + setInterval(function() { + var _scrollTop = window.scrollY; + if (scrollTop !== _scrollTop) { + localStorage.setItem(key, _scrollTop + ''); + scrollTop = _scrollTop; + } + }, 100); + }; + $(function() { + var classList = document.body.classList; + var os = []; + if ($.os.ios) { + os.push({ + os: 'ios', + version: $.os.version + }); + classList.add('mui-ios'); + } else if ($.os.android) { + os.push({ + os: 'android', + version: $.os.version + }); + classList.add('mui-android'); + } + if ($.os.wechat) { + os.push({ + os: 'wechat', + version: $.os.wechat.version + }); + classList.add('mui-wechat'); + } + if (os.length) { + $.each(os, function(index, osObj) { + var version = ''; + var classArray = []; + if (osObj.version) { + $.each(osObj.version.split('.'), function(i, v) { + version = version + (version ? '-' : '') + v; + classList.add($.className(osObj.os + '-' + version)); + }); + } + }); + } + }); +})(mui); +/** + * mui.init 5+ + * @param {type} $ + * @returns {undefined} + */ +(function($) { + var defaultOptions = { + swipeBack: false, + preloadPages: [], //5+ lazyLoad webview + preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出) + keyEventBind: { + backbutton: true, + menubutton: true + }, + titleConfig: { + height: "44px", + backgroundColor: "#f7f7f7", //导航栏背景色 + bottomBorderColor: "#cccccc", //底部边线颜色 + title: { //标题配置 + text: "", //标题文字 + position: { + top: 0, + left: 0, + width: "100%", + height: "100%" + }, + styles: { + color: "#000000", + align: "center", + family: "'Helvetica Neue',Helvetica,sans-serif", + size: "17px", + style: "normal", + weight: "normal", + fontSrc: "" + } + }, + back: { + image: { + base64Data: '', + imgSrc: '', + sprite: { + top: '0px', + left: '0px', + width: '100%', + height: '100%' + }, + position: { + top: "10px", + left: "10px", + width: "24px", + height: "24px" + } + } + } + } + }; + + //默认页面动画 + var defaultShow = { + event:"titleUpdate", + autoShow: true, + duration: 300, + aniShow: 'slide-in-right', + extras:{} + }; + //若执行了显示动画初始化操作,则要覆盖默认配置 + if($.options.show) { + defaultShow = $.extend(true, defaultShow, $.options.show); + } + + $.currentWebview = null; + + $.extend(true, $.global, defaultOptions); + $.extend(true, $.options, defaultOptions); + /** + * 等待动画配置 + * @param {type} options + * @returns {Object} + */ + $.waitingOptions = function(options) { + return $.extend(true, {}, { + autoShow: true, + title: '', + modal: false + }, options); + }; + /** + * 窗口显示配置 + * @param {type} options + * @returns {Object} + */ + $.showOptions = function(options) { + return $.extend(true, {}, defaultShow, options); + }; + /** + * 窗口默认配置 + * @param {type} options + * @returns {Object} + */ + $.windowOptions = function(options) { + return $.extend({ + scalable: false, + bounce: "" //vertical + }, options); + }; + /** + * plusReady + * @param {type} callback + * @returns {_L6.$} + */ + $.plusReady = function(callback) { + if(window.plus) { + setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting) + callback(); + }, 0); + } else { + document.addEventListener("plusready", function() { + callback(); + }, false); + } + return this; + }; + /** + * 5+ event(5+没提供之前我自己实现) + * @param {type} webview + * @param {type} eventType + * @param {type} data + * @returns {undefined} + */ + $.fire = function(webview, eventType, data) { + if(webview) { + if(typeof data === 'undefined') { + data = ''; + } else if(typeof data === 'boolean' || typeof data === 'number') { + webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")"); + return; + } else if($.isPlainObject(data) || $.isArray(data)) { + data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c"); + } + webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')"); + } + }; + /** + * 5+ event(5+没提供之前我自己实现) + * @param {type} eventType + * @param {type} data + * @returns {undefined} + */ + $.receive = function(eventType, data) { + if(eventType) { + try { + if(data && typeof data === 'string') { + data = JSON.parse(data); + } + } catch(e) {} + $.trigger(document, eventType, data); + } + }; + var triggerPreload = function(webview) { + if(!webview.preloaded) { //保证仅触发一次 + $.fire(webview, 'preload'); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], 'preload'); + } + webview.preloaded = true; + } + }; + var trigger = function(webview, eventType, timeChecked) { + if(timeChecked) { + if(!webview[eventType + 'ed']) { + $.fire(webview, eventType); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], eventType); + } + webview[eventType + 'ed'] = true; + } + } else { + $.fire(webview, eventType); + var list = webview.children(); + for(var i = 0; i < list.length; i++) { + $.fire(list[i], eventType); + } + } + + }; + /** + * 打开新窗口 + * @param {string} url 要打开的页面地址 + * @param {string} id 指定页面ID + * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}} + */ + $.openWindow = function(url, id, options) { + if(typeof url === 'object') { + options = url; + url = options.url; + id = options.id || url; + } else { + if(typeof id === 'object') { + options = id; + id = options.id || url; + } else { + id = id || url; + } + } + if(!$.os.plus) { + //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 + if($.os.ios || $.os.android) { + window.top.location.href = url; + } else { + window.parent.location.href = url; + } + return; + } + if(!window.plus) { + return; + } + + options = options || {}; + var params = options.params || {}; + var webview = null, + webviewCache = null, + nShow, nWaiting; + + if($.webviews[id]) { + webviewCache = $.webviews[id]; + //webview真实存在,才能获取 + if(plus.webview.getWebviewById(id)) { + webview = webviewCache.webview; + } + } else if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + if(webview) { //已缓存 + //每次show都需要传递动画参数; + //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; + nShow = webviewCache ? webviewCache.show : defaultShow; + nShow = options.show ? $.extend(nShow, options.show) : nShow; + nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }); + if(webviewCache) { + webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + } + return webview; + } else { //新窗口 + if(!url) { + throw new Error('webview[' + id + '] does not exist'); + } + + //显示waiting + var waitingConfig = $.waitingOptions(options.waiting); + if(waitingConfig.autoShow) { + nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); + } + + //创建页面 + options = $.extend(options, { + id: id, + url: url + }); + + webview = $.createWindow(options); + + //显示 + nShow = $.showOptions(options.show); + if(nShow.autoShow) { + var showWebview = function() { + //关闭等待框 + if(nWaiting) { + nWaiting.close(); + } + //显示页面 + webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); + options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + }; + //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview + webview.addEventListener(nShow.event, showWebview, false); + //loaded事件发生后,触发预加载和pagebeforeshow事件 + webview.addEventListener("loaded", function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }, false); + } + } + return webview; + }; + + $.openWindowWithTitle = function(options, titleConfig) { + options = options || {}; + var url = options.url; + var id = options.id || url; + + if(!$.os.plus) { + //TODO 先临时这么处理:手机上顶层跳,PC上parent跳 + if($.os.ios || $.os.android) { + window.top.location.href = url; + } else { + window.parent.location.href = url; + } + return; + } + if(!window.plus) { + return; + } + + var params = options.params || {}; + var webview = null, + webviewCache = null, + nShow, nWaiting; + + if($.webviews[id]) { + webviewCache = $.webviews[id]; + //webview真实存在,才能获取 + if(plus.webview.getWebviewById(id)) { + webview = webviewCache.webview; + } + } else if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + if(webview) { //已缓存 + //每次show都需要传递动画参数; + //预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置; + nShow = webviewCache ? webviewCache.show : defaultShow; + nShow = options.show ? $.extend(nShow, options.show) : nShow; + nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() { + triggerPreload(webview); + trigger(webview, 'pagebeforeshow', false); + }); + if(webviewCache) { + webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')'); + } + return webview; + } else { //新窗口 + if(!url) { + throw new Error('webview[' + id + '] does not exist'); + } + + //显示waiting + var waitingConfig = $.waitingOptions(options.waiting); + if(waitingConfig.autoShow) { + nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options); + } + + //创建页面 + options = $.extend(options, { + id: id, + url: url + }); + + webview = $.createWindow(options); + + if(titleConfig) { //处理原生头 + $.extend(true, $.options.titleConfig, titleConfig); + var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title"; + var view = new plus.nativeObj.View(tid, { + top: 0, + height: $.options.titleConfig.height, + width: "100%", + dock: "top", + position: "dock" + }); + view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色 + var _b = parseInt($.options.titleConfig.height) - 1; + view.drawRect($.options.titleConfig.bottomBorderColor, { + top: _b + "px", + left: "0px" + }); //绘制底部边线 + + //绘制文字 + if($.options.titleConfig.title.text){ + var _title = $.options.titleConfig.title; + view.drawText(_title.text,_title.position , _title.styles); + } + + //返回图标绘制 + var _back = $.options.titleConfig.back; + var backClick = null; + //优先字体 + + //其次是图片 + var _backImage = _back.image; + if(_backImage.base64Data || _backImage.imgSrc) { + //TODO 此处需要处理百分比的情况 + backClick = { + left:parseInt(_backImage.position.left), + right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width) + }; + var bitmap = new plus.nativeObj.Bitmap(id + "_back"); + if(_backImage.base64Data) { //优先base64编码字符串 + bitmap.loadBase64Data(_backImage.base64Data); + } else { //其次加载图片文件 + bitmap.load(_backImage.imgSrc); + } + view.drawBitmap(bitmap,_backImage.sprite , _backImage.position); + } + + //处理点击事件 + view.setTouchEventRect({ + top: "0px", + left: "0px", + width: "100%", + height: "100%" + }); + view.interceptTouchEvent(true); + view.addEventListener("click", function(e) { + var x = e.clientX; + + //返回按钮点击 + if(backClick&& x > backClick.left && x < backClick.right){ + if( _back.click && $.isFunction(_back.click)){ + _back.click(); + }else{ + webview.evalJS("window.mui&&mui.back();"); + } + } + }, false); + webview.append(view); + + } + + //显示 + nShow = $.showOptions(options.show); + if(nShow.autoShow) { + //titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview + webview.addEventListener(nShow.event, function () { + //关闭等待框 + if(nWaiting) { + nWaiting.close(); + } + //显示页面 + webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras); + }, false); + } + } + return webview; + }; + + /** + * 根据配置信息创建一个webview + * @param {type} options + * @param {type} isCreate + * @returns {webview} + */ + $.createWindow = function(options, isCreate) { + if(!window.plus) { + return; + } + var id = options.id || options.url; + var webview; + if(options.preload) { + if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache + webview = $.webviews[id].webview; + } else { //新增预加载窗口 + //判断是否携带createNew参数,默认为false + if(options.createNew !== true) { + webview = plus.webview.getWebviewById(id); + } + + //之前没有,那就新创建 + if(!webview) { + webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({ + preload: true + }, options.extras)); + if(options.subpages) { + $.each(options.subpages, function(index, subpage) { + var subpageId = subpage.id || subpage.url; + if(subpageId) { //过滤空对象 + var subWebview = plus.webview.getWebviewById(subpageId); + if(!subWebview) { //如果该webview不存在,则创建 + subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({ + preload: true + }, subpage.extras)); + } + webview.append(subWebview); + } + }); + } + } + } + + //TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题; + $.webviews[id] = { + webview: webview, //目前仅preload的缓存webview + preload: true, + show: $.showOptions(options.show), + afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯 + }; + //索引该预加载窗口 + var preloads = $.data.preloads; + var index = preloads.indexOf(id); + if(~index) { //删除已存在的(变相调整插入位置) + preloads.splice(index, 1); + } + preloads.push(id); + if(preloads.length > $.options.preloadLimit) { + //先进先出 + var first = $.data.preloads.shift(); + var webviewCache = $.webviews[first]; + if(webviewCache && webviewCache.webview) { + //需要将自己打开的所有页面,全部close; + //关闭该预加载webview + $.closeAll(webviewCache.webview); + } + //删除缓存 + delete $.webviews[first]; + } + } else { + if(isCreate !== false) { //直接创建非预加载窗口 + webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras); + if(options.subpages) { + $.each(options.subpages, function(index, subpage) { + var subpageId = subpage.id || subpage.url; + var subWebview = plus.webview.getWebviewById(subpageId); + if(!subWebview) { + subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras); + } + webview.append(subWebview); + }); + } + } + } + return webview; + }; + + /** + * 预加载 + */ + $.preload = function(options) { + //调用预加载函数,不管是否传递preload参数,强制变为true + if(!options.preload) { + options.preload = true; + } + return $.createWindow(options); + }; + + /** + *关闭当前webview打开的所有webview; + */ + $.closeOpened = function(webview) { + var opened = webview.opened(); + if(opened) { + for(var i = 0, len = opened.length; i < len; i++) { + var openedWebview = opened[i]; + var open_open = openedWebview.opened(); + if(open_open && open_open.length > 0) { + //关闭打开的webview + $.closeOpened(openedWebview); + //关闭自己 + openedWebview.close("none"); + } else { + //如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子; + if(openedWebview.parent() !== webview) { + openedWebview.close('none'); + } + } + } + } + }; + $.closeAll = function(webview, aniShow) { + $.closeOpened(webview); + if(aniShow) { + webview.close(aniShow); + } else { + webview.close(); + } + }; + + /** + * 批量创建webview + * @param {type} options + * @returns {undefined} + */ + $.createWindows = function(options) { + $.each(options, function(index, option) { + //初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建) + $.createWindow(option, false); + }); + }; + /** + * 创建当前页面的子webview + * @param {type} options + * @returns {webview} + */ + $.appendWebview = function(options) { + if(!window.plus) { + return; + } + var id = options.id || options.url; + var webview; + if(!$.webviews[id]) { //保证执行一遍 + //TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话; + if(!plus.webview.getWebviewById(id)) { + webview = plus.webview.create(options.url, id, options.styles, options.extras); + } + //之前的实现方案:子窗口loaded之后再append到父窗口中; + //问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败; + // 比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发; + //修改方式:不再监控loaded事件,直接append + //by chb@20150521 + // webview.addEventListener('loaded', function() { + plus.webview.currentWebview().append(webview); + // }); + $.webviews[id] = options; + + } + return webview; + }; + + //全局webviews + $.webviews = {}; + //预加载窗口索引 + $.data.preloads = []; + //$.currentWebview + $.plusReady(function() { + $.currentWebview = plus.webview.currentWebview(); + }); + $.addInit({ + name: '5+', + index: 100, + handle: function() { + var options = $.options; + var subpages = options.subpages || []; + if($.os.plus) { + $.plusReady(function() { + //TODO 这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法; + //或者:在openwindow方法中,监听实现; + $.each(subpages, function(index, subpage) { + $.appendWebview(subpage); + }); + //判断是否首页 + if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) { + //首页需要自己激活预加载; + //timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题; + setTimeout(function() { + triggerPreload(plus.webview.currentWebview()); + }, 300); + } + //设置ios顶部状态栏颜色; + if($.os.ios && $.options.statusBarBackground) { + plus.navigator.setStatusBarBackground($.options.statusBarBackground); + } + if($.os.android && parseFloat($.os.version) < 4.4) { + //解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题; + if(plus.webview.currentWebview().parent() == null) { + document.addEventListener("resume", function() { + var body = document.body; + body.style.display = 'none'; + setTimeout(function() { + body.style.display = ''; + }, 10); + }); + } + } + }); + } else { + //已支持iframe嵌入 + // if (subpages.length > 0) { + // var err = document.createElement('div'); + // err.className = 'mui-error'; + // //文字描述 + // var span = document.createElement('span'); + // span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考'; + // err.appendChild(span); + // var a = document.createElement('a'); + // a.innerHTML = '"mui框架适用场景"'; + // a.href = 'http://ask.dcloud.net.cn/article/113'; + // err.appendChild(a); + // document.body.appendChild(err); + // //console.log('在该浏览器下,不支持创建子页面'); + // } + + } + + } + }); + window.addEventListener('preload', function() { + //处理预加载部分 + var webviews = $.options.preloadPages || []; + $.plusReady(function() { + $.each(webviews, function(index, webview) { + $.createWindow($.extend(webview, { + preload: true + })); + }); + + }); + }); + $.supportStatusbarOffset = function() { + return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7; + }; + $.ready(function() { + //标识当前环境支持statusbar + if($.supportStatusbarOffset()) { + document.body.classList.add('mui-statusbar'); + } + }); +})(mui); + +/** + * mui back + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + /** + * register back + * @param {type} back + * @returns {$.gestures} + */ + $.addBack = function(back) { + return $.addAction('backs', back); + }; + /** + * default + */ + $.addBack({ + name: 'browser', + index: 100, + handle: function() { + if (window.history.length > 1) { + window.history.back(); + return true; + } + return false; + } + }); + /** + * 后退 + */ + $.back = function() { + if (typeof $.options.beforeback === 'function') { + if ($.options.beforeback() === false) { + return; + } + } + $.doAction('backs'); + }; + window.addEventListener('tap', function(e) { + var action = $.targets.action; + if (action && action.classList.contains('mui-action-back')) { + $.back(); + $.targets.action = false; + } + }); + window.addEventListener('swiperight', function(e) { + var detail = e.detail; + if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) { + $.back(); + } + }); + +})(mui, window); +/** + * mui back 5+ + * @param {type} $ + * @param {type} window + * @returns {undefined} + */ +(function($, window) { + if ($.os.plus && $.os.android) { + $.addBack({ + name: 'mui', + index: 5, + handle: function() { + //后续重新设计此处,将back放到各个空间内部实现 + //popover + if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) { + $($.targets._popover).popover('hide'); + return true; + } + //offcanvas + var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active'); + if (offCanvas) { + $(offCanvas).offCanvas('close'); + return true; + } + var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage(); + if (previewImage && previewImage.isShown()) { + previewImage.close(); + return true; + } + //popup + return $.closePopup(); + } + }); + } + //首次按下back按键的时间 + $.__back__first = null; + /** + * 5+ back + */ + $.addBack({ + name: '5+', + index: 10, + handle: function() { + if (!window.plus) { + return false; + } + var wobj = plus.webview.currentWebview(); + var parent = wobj.parent(); + if (parent) { + parent.evalJS('mui&&mui.back();'); + } else { + wobj.canBack(function(e) { + //by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回; + if (e.canBack) { //webview history back + window.history.back(); + } else { //webview close or hide + //fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close + if (wobj.id === plus.runtime.appid) { //首页 + //首页不存在opener的情况下,后退实际上应该是退出应用; + //首次按键,提示‘再按一次退出应用’ + if (!$.__back__first) { + $.__back__first = new Date().getTime(); + mui.toast('再按一次退出应用'); + setTimeout(function() { + $.__back__first = null; + }, 2000); + } else { + if (new Date().getTime() - $.__back__first < 2000) { + plus.runtime.quit(); + } + } + } else { //其他页面, + if (wobj.preload) { + wobj.hide("auto"); + } else { + //关闭页面时,需要将其打开的所有子页面全部关闭; + $.closeAll(wobj); + } + } + } + }); + } + return true; + } + }); + + + $.menu = function() { + var menu = document.querySelector('.mui-action-menu'); + if (menu) { + $.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题 + $.trigger(menu, 'tap'); + } else { //执行父窗口的menu + if (window.plus) { + var wobj = $.currentWebview; + var parent = wobj.parent(); + if (parent) { //又得evalJS + parent.evalJS('mui&&mui.menu();'); + } + } + } + }; + var __back = function() { + $.back(); + }; + var __menu = function() { + $.menu(); + }; + //默认监听 + $.plusReady(function() { + if ($.options.keyEventBind.backbutton) { + plus.key.addEventListener('backbutton', __back, false); + } + if ($.options.keyEventBind.menubutton) { + plus.key.addEventListener('menubutton', __menu, false); + } + }); + //处理按键监听事件 + $.addInit({ + name: 'keyEventBind', + index: 1000, + handle: function() { + $.plusReady(function() { + //如果不为true,则移除默认监听 + if (!$.options.keyEventBind.backbutton) { + plus.key.removeEventListener('backbutton', __back); + } + if (!$.options.keyEventBind.menubutton) { + plus.key.removeEventListener('menubutton', __menu); + } + }); + } + }); +})(mui, window); +/** + * mui.init pulldownRefresh + * @param {type} $ + * @returns {undefined} + */ +(function($) { + $.addInit({ + name: 'pullrefresh', + index: 1000, + handle: function() { + var options = $.options; + var pullRefreshOptions = options.pullRefresh || {}; + var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback'); + var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback'); + if(hasPulldown || hasPullup) { + var container = pullRefreshOptions.container; + if(container) { + var $container = $(container); + if($container.length === 1) { + if($.os.plus) { //5+环境 + if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈 + $.plusReady(function() { + //这里改写$.fn.pullRefresh + $.fn.pullRefresh = $.fn.pullRefresh_native; + $container.pullRefresh(pullRefreshOptions); + }); + + } else if($.os.android) { //非原生转圈,但是Android环境 + $.plusReady(function() { + //这里改写$.fn.pullRefresh + $.fn.pullRefresh = $.fn.pullRefresh_native + var webview = plus.webview.currentWebview(); + if(window.__NWin_Enable__ === false) { //不支持多webview + $container.pullRefresh(pullRefreshOptions); + } else { + if(hasPullup) { + //当前页面初始化pullup + var upOptions = {}; + upOptions.up = pullRefreshOptions.up; + upOptions.webviewId = webview.id || webview.getURL(); + $container.pullRefresh(upOptions); + } + if(hasPulldown) { + var parent = webview.parent(); + var id = webview.id || webview.getURL(); + if(parent) { + if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法 + $container.pullRefresh({ + webviewId: id + }); + } + var downOptions = { + webviewId: id//子页面id + }; + downOptions.down = $.extend({}, pullRefreshOptions.down); + downOptions.down.callback = '_CALLBACK'; + //改写父页面的$.fn.pullRefresh + parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native"); + //父页面初始化pulldown + parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')"); + } + } + } + }); + } else { //非原生转圈,iOS环境 + $container.pullRefresh(pullRefreshOptions); + } + } else { + $container.pullRefresh(pullRefreshOptions); + } + } + } + } + } + }); +})(mui); +/** + * mui ajax + * @param {type} $ + * @returns {undefined} + */ +(function($, window, undefined) { + + var jsonType = 'application/json'; + var htmlType = 'text/html'; + var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi; + var scriptTypeRE = /^(?:text|application)\/javascript/i; + var xmlTypeRE = /^(?:text|application)\/xml/i; + var blankRE = /^\s*$/; + + $.ajaxSettings = { + type: 'GET', + beforeSend: $.noop, + success: $.noop, + error: $.noop, + complete: $.noop, + context: null, + xhr: function(protocol) { + return new window.XMLHttpRequest(); + }, + accepts: { + script: 'text/javascript, application/javascript, application/x-javascript', + json: jsonType, + xml: 'application/xml, text/xml', + html: htmlType, + text: 'text/plain' + }, + timeout: 0, + processData: true, + cache: true + }; + var ajaxBeforeSend = function(xhr, settings) { + var context = settings.context + if(settings.beforeSend.call(context, xhr, settings) === false) { + return false; + } + }; + var ajaxSuccess = function(data, xhr, settings) { + settings.success.call(settings.context, data, 'success', xhr); + ajaxComplete('success', xhr, settings); + }; + // type: "timeout", "error", "abort", "parsererror" + var ajaxError = function(error, type, xhr, settings) { + settings.error.call(settings.context, xhr, type, error); + ajaxComplete(type, xhr, settings); + }; + // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" + var ajaxComplete = function(status, xhr, settings) { + settings.complete.call(settings.context, xhr, status); + }; + + var serialize = function(params, obj, traditional, scope) { + var type, array = $.isArray(obj), + hash = $.isPlainObject(obj); + $.each(obj, function(key, value) { + type = $.type(value); + if(scope) { + key = traditional ? scope : + scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']'; + } + // handle data in serializeArray() format + if(!scope && array) { + params.add(value.name, value.value); + } + // recurse into nested objects + else if(type === "array" || (!traditional && type === "object")) { + serialize(params, value, traditional, key); + } else { + params.add(key, value); + } + }); + }; + var serializeData = function(options) { + if(options.processData && options.data && typeof options.data !== "string") { + var contentType = options.contentType; + if(!contentType && options.headers) { + contentType = options.headers['Content-Type']; + } + if(contentType && ~contentType.indexOf(jsonType)) { //application/json + options.data = JSON.stringify(options.data); + } else { + options.data = $.param(options.data, options.traditional); + } + } + if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) { + options.url = appendQuery(options.url, options.data); + options.data = undefined; + } + }; + var appendQuery = function(url, query) { + if(query === '') { + return url; + } + return(url + '&' + query).replace(/[&?]{1,2}/, '?'); + }; + var mimeToDataType = function(mime) { + if(mime) { + mime = mime.split(';', 2)[0]; + } + return mime && (mime === htmlType ? 'html' : + mime === jsonType ? 'json' : + scriptTypeRE.test(mime) ? 'script' : + xmlTypeRE.test(mime) && 'xml') || 'text'; + }; + var parseArguments = function(url, data, success, dataType) { + if($.isFunction(data)) { + dataType = success, success = data, data = undefined; + } + if(!$.isFunction(success)) { + dataType = success, success = undefined; + } + return { + url: url, + data: data, + success: success, + dataType: dataType + }; + }; + $.ajax = function(url, options) { + if(typeof url === "object") { + options = url; + url = undefined; + } + var settings = options || {}; + settings.url = url || settings.url; + for(var key in $.ajaxSettings) { + if(settings[key] === undefined) { + settings[key] = $.ajaxSettings[key]; + } + } + serializeData(settings); + var dataType = settings.dataType; + + if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) { + settings.url = appendQuery(settings.url, '_=' + $.now()); + } + var mime = settings.accepts[dataType && dataType.toLowerCase()]; + var headers = {}; + var setHeader = function(name, value) { + headers[name.toLowerCase()] = [name, value]; + }; + var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol; + var xhr = settings.xhr(settings); + var nativeSetHeader = xhr.setRequestHeader; + var abortTimeout; + + setHeader('X-Requested-With', 'XMLHttpRequest'); + setHeader('Accept', mime || '*/*'); + if(!!(mime = settings.mimeType || mime)) { + if(mime.indexOf(',') > -1) { + mime = mime.split(',', 2)[0]; + } + xhr.overrideMimeType && xhr.overrideMimeType(mime); + } + if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) { + setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded'); + } + if(settings.headers) { + for(var name in settings.headers) + setHeader(name, settings.headers[name]); + } + xhr.setRequestHeader = setHeader; + + xhr.onreadystatechange = function() { + if(xhr.readyState === 4) { + xhr.onreadystatechange = $.noop; + clearTimeout(abortTimeout); + var result, error = false; + var isLocal = protocol === 'file:'; + if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) { + dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')); + result = xhr.responseText; + try { + // http://perfectionkills.com/global-eval-what-are-the-options/ + if(dataType === 'script') { + (1, eval)(result); + } else if(dataType === 'xml') { + result = xhr.responseXML; + } else if(dataType === 'json') { + result = blankRE.test(result) ? null : $.parseJSON(result); + } + } catch(e) { + error = e; + } + + if(error) { + ajaxError(error, 'parsererror', xhr, settings); + } else { + ajaxSuccess(result, xhr, settings); + } + } else { + var status = xhr.status ? 'error' : 'abort'; + var statusText = xhr.statusText || null; + if(isLocal) { + status = 'error'; + statusText = '404'; + } + ajaxError(statusText, status, xhr, settings); + } + } + }; + if(ajaxBeforeSend(xhr, settings) === false) { + xhr.abort(); + ajaxError(null, 'abort', xhr, settings); + return xhr; + } + + if(settings.xhrFields) { + for(var name in settings.xhrFields) { + xhr[name] = settings.xhrFields[name]; + } + } + + var async = 'async' in settings ? settings.async : true; + + xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password); + + for(var name in headers) { + if(headers.hasOwnProperty(name)) { + nativeSetHeader.apply(xhr, headers[name]); + } + } + if(settings.timeout > 0) { + abortTimeout = setTimeout(function() { + xhr.onreadystatechange = $.noop; + xhr.abort(); + ajaxError(null, 'timeout', xhr, settings); + }, settings.timeout); + } + xhr.send(settings.data ? settings.data : null); + return xhr; + }; + + $.param = function(obj, traditional) { + var params = []; + params.add = function(k, v) { + this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v)); + }; + serialize(params, obj, traditional); + return params.join('&').replace(/%20/g, '+'); + }; + $.get = function( /* url, data, success, dataType */ ) { + return $.ajax(parseArguments.apply(null, arguments)); + }; + + $.post = function( /* url, data, success, dataType */ ) { + var options = parseArguments.apply(null, arguments); + options.type = 'POST'; + return $.ajax(options); + }; + + $.getJSON = function( /* url, data, success */ ) { + var options = parseArguments.apply(null, arguments); + options.dataType = 'json'; + return $.ajax(options); + }; + + $.fn.load = function(url, data, success) { + if(!this.length) + return this; + var self = this, + parts = url.split(/\s/), + selector, + options = parseArguments(url, data, success), + callback = options.success; + if(parts.length > 1) + options.url = parts[0], selector = parts[1]; + options.success = function(response) { + if(selector) { + var div = document.createElement('div'); + div.innerHTML = response.replace(rscript, ""); + var selectorDiv = document.createElement('div'); + var childs = div.querySelectorAll(selector); + if(childs && childs.length > 0) { + for(var i = 0, len = childs.length; i < len; i++) { + selectorDiv.appendChild(childs[i]); + } + } + self[0].innerHTML = selectorDiv.innerHTML; + } else { + self[0].innerHTML = response; + } + callback && callback.apply(self, arguments); + }; + $.ajax(options); + return this; + }; + +})(mui, window); +/** + * 5+ ajax + */ +(function($) { + var originAnchor = document.createElement('a'); + originAnchor.href = window.location.href; + $.plusReady(function() { + $.ajaxSettings = $.extend($.ajaxSettings, { + xhr: function(settings) { + if (settings.crossDomain) { //强制使用plus跨域 + return new plus.net.XMLHttpRequest(); + } + //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest + if (originAnchor.protocol !== 'file:') { + var urlAnchor = document.createElement('a'); + urlAnchor.href = settings.url; + urlAnchor.href = urlAnchor.href; + settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host); + if (settings.crossDomain) { + return new plus.net.XMLHttpRequest(); + } + } + if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr + return new plus.net.XMLHttpRequest(); + } + return new window.XMLHttpRequest(); + } + }); + }); +})(mui); +/** + * mui layout(offset[,position,width,height...]) + * @param {type} $ + * @param {type} window + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, undefined) { + $.offset = function(element) { + var box = { + top : 0, + left : 0 + }; + if ( typeof element.getBoundingClientRect !== undefined) { + box = element.getBoundingClientRect(); + } + return { + top : box.top + window.pageYOffset - element.clientTop, + left : box.left + window.pageXOffset - element.clientLeft + }; + }; +})(mui, window); +/** + * mui animation + */ +(function($, window) { + /** + * scrollTo + */ + $.scrollTo = function(scrollTop, duration, callback) { + duration = duration || 1000; + var scroll = function(duration) { + if (duration <= 0) { + window.scrollTo(0, scrollTop); + callback && callback(); + return; + } + var distaince = scrollTop - window.scrollY; + setTimeout(function() { + window.scrollTo(0, window.scrollY + distaince / duration * 10); + scroll(duration - 10); + }, 16.7); + }; + scroll(duration); + }; + $.animationFrame = function(cb) { + var args, isQueued, context; + return function() { + args = arguments; + context = this; + if (!isQueued) { + isQueued = true; + requestAnimationFrame(function() { + cb.apply(context, args); + isQueued = false; + }); + } + }; + }; + +})(mui, window); +(function($) { + var initializing = false, + fnTest = /xyz/.test(function() { + xyz; + }) ? /\b_super\b/ : /.*/; + + var Class = function() {}; + Class.extend = function(prop) { + var _super = this.prototype; + initializing = true; + var prototype = new this(); + initializing = false; + for (var name in prop) { + prototype[name] = typeof prop[name] == "function" && + typeof _super[name] == "function" && fnTest.test(prop[name]) ? + (function(name, fn) { + return function() { + var tmp = this._super; + + this._super = _super[name]; + + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : + prop[name]; + } + function Class() { + if (!initializing && this.init) + this.init.apply(this, arguments); + } + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.extend = arguments.callee; + return Class; + }; + $.Class = Class; +})(mui); +(function($, document, undefined) { + var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket'; + var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket'; + var CLASS_PULL = 'mui-pull'; + var CLASS_PULL_LOADING = 'mui-pull-loading'; + var CLASS_PULL_CAPTION = 'mui-pull-caption'; + var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; + var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; + var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; + + var CLASS_ICON = 'mui-icon'; + var CLASS_SPINNER = 'mui-spinner'; + var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown'; + + var CLASS_BLOCK = 'mui-block'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_VISIBILITY = 'mui-visibility'; + + var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; + var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN; + var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER; + + var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join(''); + + var PullRefresh = { + init: function(element, options) { + this._super(element, $.extend(true, { + scrollY: true, + scrollX: false, + indicators: true, + deceleration: 0.003, + down: { + height: 50, + contentinit: '下拉可以刷新', + contentdown: '下拉可以刷新', + contentover: '释放立即刷新', + contentrefresh: '正在刷新...' + }, + up: { + height: 50, + auto: false, + contentinit: '上拉显示更多', + contentdown: '上拉显示更多', + contentrefresh: '正在加载...', + contentnomore: '没有更多数据了', + duration: 300 + } + }, options)); + }, + _init: function() { + this._super(); + this._initPocket(); + }, + _initPulldownRefresh: function() { + this.pulldown = true; + if (this.topPocket) { + this.pullPocket = this.topPocket; + this.pullPocket.classList.add(CLASS_BLOCK); + this.pullPocket.classList.add(CLASS_VISIBILITY); + this.pullCaption = this.topCaption; + this.pullLoading = this.topLoading; + } + }, + _initPullupRefresh: function() { + this.pulldown = false; + if (this.bottomPocket) { + this.pullPocket = this.bottomPocket; + this.pullPocket.classList.add(CLASS_BLOCK); + this.pullPocket.classList.add(CLASS_VISIBILITY); + this.pullCaption = this.bottomCaption; + this.pullLoading = this.bottomLoading; + } + }, + _initPocket: function() { + var options = this.options; + if (options.down && options.down.hasOwnProperty('callback')) { + this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET); + if (!this.topPocket) { + this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN); + this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild); + } + this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING); + this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION); + } + if (options.up && options.up.hasOwnProperty('callback')) { + this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET); + if (!this.bottomPocket) { + this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING); + this.scroller.appendChild(this.bottomPocket); + } + this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING); + this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION); + //TODO only for h5 + this.wrapper.addEventListener('scrollbottom', this); + } + }, + _createPocket: function(clazz, options, iconClass) { + var pocket = document.createElement('div'); + pocket.className = clazz; + pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass); + return pocket; + }, + _resetPullDownLoading: function() { + var loading = this.pullLoading; + if (loading) { + this.pullCaption.innerHTML = this.options.down.contentdown; + loading.style.webkitTransition = ""; + loading.style.webkitTransform = ""; + loading.style.webkitAnimation = ""; + loading.className = CLASS_LOADING_DOWN; + } + }, + _setCaptionClass: function(isPulldown, caption, title) { + if (!isPulldown) { + switch (title) { + case this.options.up.contentdown: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + break; + case this.options.up.contentrefresh: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH + break; + case this.options.up.contentnomore: + caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; + break; + } + } + }, + _setCaption: function(title, reset) { + if (this.loading) { + return; + } + var options = this.options; + var pocket = this.pullPocket; + var caption = this.pullCaption; + var loading = this.pullLoading; + var isPulldown = this.pulldown; + var self = this; + if (pocket) { + if (reset) { + setTimeout(function() { + caption.innerHTML = self.lastTitle = title; + if (isPulldown) { + loading.className = CLASS_LOADING_DOWN; + } else { + self._setCaptionClass(false, caption, title); + loading.className = CLASS_LOADING; + } + loading.style.webkitAnimation = ""; + loading.style.webkitTransition = ""; + loading.style.webkitTransform = ""; + }, 100); + } else { + if (title !== this.lastTitle) { + caption.innerHTML = title; + if (isPulldown) { + if (title === options.down.contentrefresh) { + loading.className = CLASS_LOADING; + loading.style.webkitAnimation = "spinner-spin 1s step-end infinite"; + } else if (title === options.down.contentover) { + loading.className = CLASS_LOADING_UP; + loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; + loading.style.webkitTransform = "rotate(180deg)"; + } else if (title === options.down.contentdown) { + loading.className = CLASS_LOADING_DOWN; + loading.style.webkitTransition = "-webkit-transform 0.3s ease-in"; + loading.style.webkitTransform = "rotate(0deg)"; + } + } else { + if (title === options.up.contentrefresh) { + loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY; + } else { + loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN; + } + self._setCaptionClass(false, caption, title); + } + this.lastTitle = title; + } + } + + } + } + }; + $.PullRefresh = PullRefresh; +})(mui, document); +(function($, window, document, undefined) { + var CLASS_SCROLL = 'mui-scroll'; + var CLASS_SCROLLBAR = 'mui-scrollbar'; + var CLASS_INDICATOR = 'mui-scrollbar-indicator'; + var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical'; + var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal'; + + var CLASS_ACTIVE = 'mui-active'; + + var ease = { + quadratic: { + style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fn: function(k) { + return k * (2 - k); + } + }, + circular: { + style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', + fn: function(k) { + return Math.sqrt(1 - (--k * k)); + } + }, + outCirc: { + style: 'cubic-bezier(0.075, 0.82, 0.165, 1)' + }, + outCubic: { + style: 'cubic-bezier(0.165, 0.84, 0.44, 1)' + } + } + var Scroll = $.Class.extend({ + init: function(element, options) { + this.wrapper = this.element = element; + this.scroller = this.wrapper.children[0]; + this.scrollerStyle = this.scroller && this.scroller.style; + this.stopped = false; + + this.options = $.extend(true, { + scrollY: true, //是否竖向滚动 + scrollX: false, //是否横向滚动 + startX: 0, //初始化时滚动至x + startY: 0, //初始化时滚动至y + + indicators: true, //是否显示滚动条 + stopPropagation: false, + hardwareAccelerated: true, + fixedBadAndorid: false, + preventDefaultException: { + tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ + }, + momentum: true, + + snapX: 0.5, //横向切换距离(以当前容器宽度为基准) + snap: false, //图片轮播,拖拽式选项卡 + + bounce: true, //是否启用回弹 + bounceTime: 500, //回弹动画时间 + bounceEasing: ease.outCirc, //回弹动画曲线 + + scrollTime: 500, + scrollEasing: ease.outCubic, //轮播动画曲线 + + directionLockThreshold: 5, + + parallaxElement: false, //视差元素 + parallaxRatio: 0.5 + }, options); + + this.x = 0; + this.y = 0; + this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : ''; + + this._init(); + if (this.scroller) { + this.refresh(); + // if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看 + this.scrollTo(this.options.startX, this.options.startY); + // } + } + }, + _init: function() { + this._initParallax(); + this._initIndicators(); + this._initEvent(); + }, + _initParallax: function() { + if (this.options.parallaxElement) { + this.parallaxElement = document.querySelector(this.options.parallaxElement); + this.parallaxStyle = this.parallaxElement.style; + this.parallaxHeight = this.parallaxElement.offsetHeight; + this.parallaxImgStyle = this.parallaxElement.querySelector('img').style; + } + }, + _initIndicators: function() { + var self = this; + self.indicators = []; + if (!this.options.indicators) { + return; + } + var indicators = [], + indicator; + + // Vertical scrollbar + if (self.options.scrollY) { + indicator = { + el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL), + listenX: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + // Horizontal scrollbar + if (this.options.scrollX) { + indicator = { + el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL), + listenY: false + }; + + this.wrapper.appendChild(indicator.el); + indicators.push(indicator); + } + + for (var i = indicators.length; i--;) { + this.indicators.push(new Indicator(this, indicators[i])); + } + + }, + _initSnap: function() { + this.currentPage = {}; + this.pages = []; + var snaps = this.snaps; + var length = snaps.length; + var m = 0; + var n = -1; + var x = 0; + var leftX = 0; + var rightX = 0; + var snapX = 0; + for (var i = 0; i < length; i++) { + var snap = snaps[i]; + var offsetLeft = snap.offsetLeft; + var offsetWidth = snap.offsetWidth; + if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) { + m = 0; + n++; + } + if (!this.pages[m]) { + this.pages[m] = []; + } + x = this._getSnapX(offsetLeft); + snapX = Math.round((offsetWidth) * this.options.snapX); + leftX = x - snapX; + rightX = x - offsetWidth + snapX; + this.pages[m][n] = { + x: x, + leftX: leftX, + rightX: rightX, + pageX: m, + element: snap + } + if (snap.classList.contains(CLASS_ACTIVE)) { + this.currentPage = this.pages[m][0]; + } + if (x >= this.maxScrollX) { + m++; + } + } + this.options.startX = this.currentPage.x || 0; + }, + _getSnapX: function(offsetLeft) { + return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX); + }, + _gotoPage: function(index) { + this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0]; + for (var i = 0, len = this.snaps.length; i < len; i++) { + if (i === index) { + this.snaps[i].classList.add(CLASS_ACTIVE); + } else { + this.snaps[i].classList.remove(CLASS_ACTIVE); + } + } + this.scrollTo(this.currentPage.x, 0, this.options.scrollTime); + }, + _nearestSnap: function(x) { + if (!this.pages.length) { + return { + x: 0, + pageX: 0 + }; + } + var i = 0; + var length = this.pages.length; + if (x > 0) { + x = 0; + } else if (x < this.maxScrollX) { + x = this.maxScrollX; + } + for (; i < length; i++) { + var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX; + if (x >= nearestX) { + return this.pages[i][0]; + } + } + return { + x: 0, + pageX: 0 + }; + }, + _initEvent: function(detach) { + var action = detach ? 'removeEventListener' : 'addEventListener'; + window[action]('orientationchange', this); + window[action]('resize', this); + + this.scroller[action]('webkitTransitionEnd', this); + + this.wrapper[action]($.EVENT_START, this); + this.wrapper[action]($.EVENT_CANCEL, this); + this.wrapper[action]($.EVENT_END, this); + this.wrapper[action]('drag', this); + this.wrapper[action]('dragend', this); + this.wrapper[action]('flick', this); + this.wrapper[action]('scrollend', this); + if (this.options.scrollX) { + this.wrapper[action]('swiperight', this); + } + var segmentedControl = this.wrapper.querySelector('.mui-segmented-control'); + if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见 + mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault); + } + + this.wrapper[action]('scrollstart', this); + this.wrapper[action]('refresh', this); + }, + _handleIndicatorScrollend: function() { + this.indicators.map(function(indicator) { + indicator.fade(); + }); + }, + _handleIndicatorScrollstart: function() { + this.indicators.map(function(indicator) { + indicator.fade(1); + }); + }, + _handleIndicatorRefresh: function() { + this.indicators.map(function(indicator) { + indicator.refresh(); + }); + }, + handleEvent: function(e) { + if (this.stopped) { + this.resetPosition(); + return; + } + + switch (e.type) { + case $.EVENT_START: + this._start(e); + break; + case 'drag': + this.options.stopPropagation && e.stopPropagation(); + this._drag(e); + break; + case 'dragend': + case 'flick': + this.options.stopPropagation && e.stopPropagation(); + this._flick(e); + break; + case $.EVENT_CANCEL: + case $.EVENT_END: + this._end(e); + break; + case 'webkitTransitionEnd': + this.transitionTimer && this.transitionTimer.cancel(); + this._transitionEnd(e); + break; + case 'scrollstart': + this._handleIndicatorScrollstart(e); + break; + case 'scrollend': + this._handleIndicatorScrollend(e); + this._scrollend(e); + e.stopPropagation(); + break; + case 'orientationchange': + case 'resize': + this._resize(); + break; + case 'swiperight': + e.stopPropagation(); + break; + case 'refresh': + this._handleIndicatorRefresh(e); + break; + + } + }, + _start: function(e) { + this.moved = this.needReset = false; + this._transitionTime(); + if (this.isInTransition) { + this.needReset = true; + this.isInTransition = false; + var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); + this.setTranslate(Math.round(pos.x), Math.round(pos.y)); + // this.resetPosition(); //reset + $.trigger(this.scroller, 'scrollend', this); + // e.stopPropagation(); + e.preventDefault(); + } + this.reLayout(); + $.trigger(this.scroller, 'beforescrollstart', this); + }, + _getDirectionByAngle: function(angle) { + if (angle < -80 && angle > -100) { + return 'up'; + } else if (angle >= 80 && angle < 100) { + return 'down'; + } else if (angle >= 170 || angle <= -170) { + return 'left'; + } else if (angle >= -35 && angle <= 10) { + return 'right'; + } + return null; + }, + _drag: function(e) { + // if (this.needReset) { + // e.stopPropagation(); //disable parent drag(nested scroller) + // return; + // } + var detail = e.detail; + if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下 + //ios8 hack + if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发 + var clientY = detail.gesture.touches[0].clientY; + //下拉刷新 or 上拉加载 + if ((clientY + 10) > window.innerHeight || clientY < 10) { + this.resetPosition(this.options.bounceTime); + return; + } + } + } + var isPreventDefault = isReturn = false; + var direction = this._getDirectionByAngle(detail.angle); + if (detail.direction === 'left' || detail.direction === 'right') { + if (this.options.scrollX) { + isPreventDefault = true; + if (!this.moved) { //识别角度(该角度导致轮播不灵敏) + // if (direction !== 'left' && direction !== 'right') { + // isReturn = true; + // } else { + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + // } + } + } else if (this.options.scrollY && !this.moved) { + isReturn = true; + } + } else if (detail.direction === 'up' || detail.direction === 'down') { + if (this.options.scrollY) { + isPreventDefault = true; + // if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证 + // if (direction !== 'up' && direction !== 'down') { + // isReturn = true; + // } + // } + if (!this.moved) { + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + } + } else if (this.options.scrollX && !this.moved) { + isReturn = true; + } + } else { + isReturn = true; + } + if (this.moved || isPreventDefault) { + e.stopPropagation(); //阻止冒泡(scroll类嵌套) + detail.gesture && detail.gesture.preventDefault(); + } + if (isReturn) { //禁止非法方向滚动 + return; + } + if (!this.moved) { + $.trigger(this.scroller, 'scrollstart', this); + } else { + e.stopPropagation(); //move期间阻止冒泡(scroll嵌套) + } + var deltaX = 0; + var deltaY = 0; + if (!this.moved) { //start + deltaX = detail.deltaX; + deltaY = detail.deltaY; + } else { //move + deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX; + deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY; + } + var absDeltaX = Math.abs(detail.deltaX); + var absDeltaY = Math.abs(detail.deltaY); + if (absDeltaX > absDeltaY + this.options.directionLockThreshold) { + deltaY = 0; + } else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) { + deltaX = 0; + } + + deltaX = this.hasHorizontalScroll ? deltaX : 0; + deltaY = this.hasVerticalScroll ? deltaY : 0; + var newX = this.x + deltaX; + var newY = this.y + deltaY; + // Slow down if outside of the boundaries + if (newX > 0 || newX < this.maxScrollX) { + newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX; + } + if (newY > 0 || newY < this.maxScrollY) { + newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY; + } + + if (!this.requestAnimationFrame) { + this._updateTranslate(); + } + this.direction = detail.deltaX > 0 ? 'right' : 'left'; + this.moved = true; + this.x = newX; + this.y = newY; + $.trigger(this.scroller, 'scroll', this); + }, + _flick: function(e) { + // if (!this.moved || this.needReset) { + // return; + // } + if (!this.moved) { + return; + } + e.stopPropagation(); + var detail = e.detail; + this._clearRequestAnimationFrame(); + if (e.type === 'dragend' && detail.flick) { //dragend + return; + } + + var newX = Math.round(this.x); + var newY = Math.round(this.y); + + this.isInTransition = false; + // reset if we are outside of the boundaries + if (this.resetPosition(this.options.bounceTime)) { + return; + } + + this.scrollTo(newX, newY); // ensures that the last position is rounded + + if (e.type === 'dragend') { //dragend + $.trigger(this.scroller, 'scrollend', this); + return; + } + var time = 0; + var easing = ''; + // start momentum animation if needed + if (this.options.momentum && detail.flickTime < 300) { + momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { + destination: newX, + duration: 0 + }; + momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { + destination: newY, + duration: 0 + }; + newX = momentumX.destination; + newY = momentumY.destination; + time = Math.max(momentumX.duration, momentumY.duration); + this.isInTransition = true; + } + + if (newX != this.x || newY != this.y) { + if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) { + easing = ease.quadratic; + } + this.scrollTo(newX, newY, time, easing); + return; + } + + $.trigger(this.scroller, 'scrollend', this); + // e.stopPropagation(); + }, + _end: function(e) { + this.needReset = false; + if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) { + this.resetPosition(); + } + }, + _transitionEnd: function(e) { + if (e.target != this.scroller || !this.isInTransition) { + return; + } + this._transitionTime(); + if (!this.resetPosition(this.options.bounceTime)) { + this.isInTransition = false; + $.trigger(this.scroller, 'scrollend', this); + } + }, + _scrollend: function(e) { + if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) { + $.trigger(this.scroller, 'scrollbottom', this); + } + }, + _resize: function() { + var that = this; + clearTimeout(that.resizeTimeout); + that.resizeTimeout = setTimeout(function() { + that.refresh(); + }, that.options.resizePolling); + }, + _transitionTime: function(time) { + time = time || 0; + this.scrollerStyle['webkitTransitionDuration'] = time + 'ms'; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = time + 'ms'; + } + if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) { + this.scrollerStyle['webkitTransitionDuration'] = '0.001s'; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = '0.001s'; + } + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].transitionTime(time); + } + } + if (time) { //自定义timer,保证webkitTransitionEnd始终触发 + this.transitionTimer && this.transitionTimer.cancel(); + this.transitionTimer = $.later(function() { + $.trigger(this.scroller, 'webkitTransitionEnd'); + }, time + 100, this); + } + }, + _transitionTimingFunction: function(easing) { + this.scrollerStyle['webkitTransitionTimingFunction'] = easing; + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + this.parallaxStyle['webkitTransitionDuration'] = easing; + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].transitionTimingFunction(easing); + } + } + }, + _translate: function(x, y) { + this.x = x; + this.y = y; + }, + _clearRequestAnimationFrame: function() { + if (this.requestAnimationFrame) { + cancelAnimationFrame(this.requestAnimationFrame); + this.requestAnimationFrame = null; + } + }, + _updateTranslate: function() { + var self = this; + if (self.x !== self.lastX || self.y !== self.lastY) { + self.setTranslate(self.x, self.y); + } + self.requestAnimationFrame = requestAnimationFrame(function() { + self._updateTranslate(); + }); + }, + _createScrollBar: function(clazz) { + var scrollbar = document.createElement('div'); + var indicator = document.createElement('div'); + scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz; + indicator.className = CLASS_INDICATOR; + scrollbar.appendChild(indicator); + if (clazz === CLASS_SCROLLBAR_VERTICAL) { + this.scrollbarY = scrollbar; + this.scrollbarIndicatorY = indicator; + } else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) { + this.scrollbarX = scrollbar; + this.scrollbarIndicatorX = indicator; + } + this.wrapper.appendChild(scrollbar); + return scrollbar; + }, + _preventDefaultException: function(el, exceptions) { + for (var i in exceptions) { + if (exceptions[i].test(el[i])) { + return true; + } + } + return false; + }, + _reLayout: function() { + if (!this.hasHorizontalScroll) { + this.maxScrollX = 0; + this.scrollerWidth = this.wrapperWidth; + } + + if (!this.hasVerticalScroll) { + this.maxScrollY = 0; + this.scrollerHeight = this.wrapperHeight; + } + + this.indicators.map(function(indicator) { + indicator.refresh(); + }); + + //以防slider类嵌套使用 + if (this.options.snap && typeof this.options.snap === 'string') { + var items = this.scroller.querySelectorAll(this.options.snap); + this.itemLength = 0; + this.snaps = []; + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + if (item.parentNode === this.scroller) { + this.itemLength++; + this.snaps.push(item); + } + } + this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整 + } + }, + _momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) { + var speed = parseFloat(Math.abs(distance) / time), + destination, + duration; + + deceleration = deceleration === undefined ? 0.0006 : deceleration; + destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1); + duration = speed / deceleration; + if (destination < lowerMargin) { + destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin; + distance = Math.abs(destination - current); + duration = distance / speed; + } else if (destination > 0) { + destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0; + distance = Math.abs(current) + destination; + duration = distance / speed; + } + + return { + destination: Math.round(destination), + duration: duration + }; + }, + _getTranslateStr: function(x, y) { + if (this.options.hardwareAccelerated) { + return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ; + } + return 'translate(' + x + 'px,' + y + 'px) '; + }, + //API + setStopped: function(stopped) { + // this.stopped = !!stopped; + + // fixed ios双webview模式下拉刷新 + if(stopped) { + this.disablePullupToRefresh(); + this.disablePulldownToRefresh(); + } else { + this.enablePullupToRefresh(); + this.enablePulldownToRefresh(); + } + }, + setTranslate: function(x, y) { + this.x = x; + this.y = y; + this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y); + if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果 + var parallaxY = y * this.options.parallaxRatio; + var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2); + if (scale > 1) { + this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio; + this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')'; + } else { + this.parallaxImgStyle['opacity'] = 1; + this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)'; + } + } + if (this.indicators) { + for (var i = this.indicators.length; i--;) { + this.indicators[i].updatePosition(); + } + } + this.lastX = this.x; + this.lastY = this.y; + $.trigger(this.scroller, 'scroll', this); + }, + reLayout: function() { + this.wrapper.offsetHeight; + + var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0; + var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0; + var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0; + var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0; + + var clientWidth = this.wrapper.clientWidth; + var clientHeight = this.wrapper.clientHeight; + + this.scrollerWidth = this.scroller.offsetWidth; + this.scrollerHeight = this.scroller.offsetHeight; + + this.wrapperWidth = clientWidth - paddingLeft - paddingRight; + this.wrapperHeight = clientHeight - paddingTop - paddingBottom; + + this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); + this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0); + this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0; + this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0; + this._reLayout(); + }, + resetPosition: function(time) { + var x = this.x, + y = this.y; + + time = time || 0; + if (!this.hasHorizontalScroll || this.x > 0) { + x = 0; + } else if (this.x < this.maxScrollX) { + x = this.maxScrollX; + } + + if (!this.hasVerticalScroll || this.y > 0) { + y = 0; + } else if (this.y < this.maxScrollY) { + y = this.maxScrollY; + } + + if (x == this.x && y == this.y) { + return false; + } + this.scrollTo(x, y, time, this.options.scrollEasing); + + return true; + }, + _reInit: function() { + var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL); + for (var i = 0, len = groups.length; i < len; i++) { + if (groups[i].parentNode === this.wrapper) { + this.scroller = groups[i]; + break; + } + } + this.scrollerStyle = this.scroller && this.scroller.style; + }, + refresh: function() { + this._reInit(); + this.reLayout(); + $.trigger(this.scroller, 'refresh', this); + this.resetPosition(); + }, + scrollTo: function(x, y, time, easing) { + var easing = easing || ease.circular; + // this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y); + //暂不严格判断x,y,否则会导致部分版本上不正常触发轮播 + this.isInTransition = time > 0; + if (this.isInTransition) { + this._clearRequestAnimationFrame(); + this._transitionTimingFunction(easing.style); + this._transitionTime(time); + this.setTranslate(x, y); + } else { + this.setTranslate(x, y); + } + + }, + scrollToBottom: function(time, easing) { + time = time || this.options.scrollTime; + this.scrollTo(0, this.maxScrollY, time, easing); + }, + gotoPage: function(index) { + this._gotoPage(index); + }, + destroy: function() { + this._initEvent(true); //detach + delete $.data[this.wrapper.getAttribute('data-scroll')]; + this.wrapper.setAttribute('data-scroll', ''); + } + }); + //Indicator + var Indicator = function(scroller, options) { + this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el; + this.wrapperStyle = this.wrapper.style; + this.indicator = this.wrapper.children[0]; + this.indicatorStyle = this.indicator.style; + this.scroller = scroller; + + this.options = $.extend({ + listenX: true, + listenY: true, + fade: false, + speedRatioX: 0, + speedRatioY: 0 + }, options); + + this.sizeRatioX = 1; + this.sizeRatioY = 1; + this.maxPosX = 0; + this.maxPosY = 0; + + if (this.options.fade) { + this.wrapperStyle['webkitTransform'] = this.scroller.translateZ; + this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms'; + this.wrapperStyle.opacity = '0'; + } + } + Indicator.prototype = { + handleEvent: function(e) { + + }, + transitionTime: function(time) { + time = time || 0; + this.indicatorStyle['webkitTransitionDuration'] = time + 'ms'; + if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) { + this.indicatorStyle['webkitTransitionDuration'] = '0.001s'; + } + }, + transitionTimingFunction: function(easing) { + this.indicatorStyle['webkitTransitionTimingFunction'] = easing; + }, + refresh: function() { + this.transitionTime(); + + if (this.options.listenX && !this.options.listenY) { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none'; + } else if (this.options.listenY && !this.options.listenX) { + this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none'; + } else { + this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none'; + } + + this.wrapper.offsetHeight; // force refresh + + if (this.options.listenX) { + this.wrapperWidth = this.wrapper.clientWidth; + this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8); + this.indicatorStyle.width = this.indicatorWidth + 'px'; + + this.maxPosX = this.wrapperWidth - this.indicatorWidth; + + this.minBoundaryX = 0; + this.maxBoundaryX = this.maxPosX; + + this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX)); + } + + if (this.options.listenY) { + this.wrapperHeight = this.wrapper.clientHeight; + this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8); + this.indicatorStyle.height = this.indicatorHeight + 'px'; + + this.maxPosY = this.wrapperHeight - this.indicatorHeight; + + this.minBoundaryY = 0; + this.maxBoundaryY = this.maxPosY; + + this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY)); + } + + this.updatePosition(); + }, + + updatePosition: function() { + var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0, + y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0; + + if (x < this.minBoundaryX) { + this.width = Math.max(this.indicatorWidth + x, 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.minBoundaryX; + } else if (x > this.maxBoundaryX) { + this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8); + this.indicatorStyle.width = this.width + 'px'; + x = this.maxPosX + this.indicatorWidth - this.width; + } else if (this.width != this.indicatorWidth) { + this.width = this.indicatorWidth; + this.indicatorStyle.width = this.width + 'px'; + } + + if (y < this.minBoundaryY) { + this.height = Math.max(this.indicatorHeight + y * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.minBoundaryY; + } else if (y > this.maxBoundaryY) { + this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8); + this.indicatorStyle.height = this.height + 'px'; + y = this.maxPosY + this.indicatorHeight - this.height; + } else if (this.height != this.indicatorHeight) { + this.height = this.indicatorHeight; + this.indicatorStyle.height = this.height + 'px'; + } + + this.x = x; + this.y = y; + + this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y); + + }, + fade: function(val, hold) { + if (hold && !this.visible) { + return; + } + + clearTimeout(this.fadeTimeout); + this.fadeTimeout = null; + + var time = val ? 250 : 500, + delay = val ? 0 : 300; + + val = val ? '1' : '0'; + + this.wrapperStyle['webkitTransitionDuration'] = time + 'ms'; + + this.fadeTimeout = setTimeout((function(val) { + this.wrapperStyle.opacity = val; + this.visible = +val; + }).bind(this, val), delay); + } + }; + + $.Scroll = Scroll; + + $.fn.scroll = function(options) { + var scrollApis = []; + this.each(function() { + var scrollApi = null; + var self = this; + var id = self.getAttribute('data-scroll'); + if (!id) { + id = ++$.uuid; + var _options = $.extend({}, options); + if (self.classList.contains('mui-segmented-control')) { + _options = $.extend(_options, { + scrollY: false, + scrollX: true, + indicators: false, + snap: '.mui-control-item' + }); + } + $.data[id] = scrollApi = new Scroll(self, _options); + self.setAttribute('data-scroll', id); + } else { + scrollApi = $.data[id]; + } + scrollApis.push(scrollApi); + }); + return scrollApis.length === 1 ? scrollApis[0] : scrollApis; + }; +})(mui, window, document); +(function($, window, document, undefined) { + + var CLASS_VISIBILITY = 'mui-visibility'; + var CLASS_HIDDEN = 'mui-hidden'; + + var PullRefresh = $.Scroll.extend($.extend({ + handleEvent: function(e) { + this._super(e); + if (e.type === 'scrollbottom') { + if (e.target === this.scroller) { + this._scrollbottom(); + } + } + }, + _scrollbottom: function() { + if (!this.pulldown && !this.loading) { + this.pulldown = false; + this._initPullupRefresh(); + this.pullupLoading(); + } + }, + _start: function(e) { + //仅下拉刷新在start阻止默认事件 + if (e.touches && e.touches.length && e.touches[0].clientX > 30) { + e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); + } + if (!this.loading) { + this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false + } + this._super(e); + }, + _drag: function(e) { + if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新 + return; + } + this._super(e); + if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) { + this._initPulldownRefresh(); + } + if (this.pulldown) { + this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown); + } + }, + + _reLayout: function() { + this.hasVerticalScroll = true; + this._super(); + }, + //API + resetPosition: function(time) { + if (this.pulldown && !this.disablePulldown) { + if (this.y >= this.options.down.height) { + this.pulldownLoading(undefined, time || 0); + return true; + } else { + !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY); + } + } + return this._super(time); + }, + pulldownLoading: function(y, time) { + typeof y === 'undefined' && (y = this.options.down.height); //默认高度 + this.scrollTo(0, y, time, this.options.bounceEasing); + if (this.loading) { + return; + } + // if (!this.pulldown) { + this._initPulldownRefresh(); + // } + this._setCaption(this.options.down.contentrefresh); + this.loading = true; + this.indicators.map(function(indicator) { + indicator.fade(0); + }); + var callback = this.options.down.callback; + callback && callback.call(this); + }, + endPulldownToRefresh: function() { + var self = this; + if (self.topPocket && self.loading && this.pulldown) { + self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing); + self.loading = false; + self._setCaption(self.options.down.contentdown, true); + setTimeout(function() { + self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY); + }, 350); + } + }, + pullupLoading: function(callback, x, time) { + x = x || 0; + this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing); + if (this.loading) { + return; + } + this._initPullupRefresh(); + this._setCaption(this.options.up.contentrefresh); + this.indicators.map(function(indicator) { + indicator.fade(0); + }); + this.loading = true; + callback = callback || this.options.up.callback; + callback && callback.call(this); + }, + endPullupToRefresh: function(finished) { + var self = this; + if (self.bottomPocket) { // && self.loading && !this.pulldown + self.loading = false; + if (finished) { + this.finished = true; + self._setCaption(self.options.up.contentnomore); + // self.bottomPocket.classList.remove(CLASS_VISIBILITY); + // self.bottomPocket.classList.add(CLASS_HIDDEN); + self.wrapper.removeEventListener('scrollbottom', self); + } else { + self._setCaption(self.options.up.contentdown); + // setTimeout(function() { + self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY); + // }, 300); + } + } + }, + disablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; + this.wrapper.removeEventListener('scrollbottom', this); + }, + disablePulldownToRefresh: function() { + this._initPulldownRefresh(); + this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN; + this.disablePulldown = true; + }, + enablePulldownToRefresh: function() { + this._initPulldownRefresh(); + this.topPocket.classList.remove(CLASS_HIDDEN); + this._setCaption(this.options.down.contentdown); + this.disablePulldown = false; + }, + enablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.classList.remove(CLASS_HIDDEN); + this._setCaption(this.options.up.contentdown); + this.wrapper.addEventListener('scrollbottom', this); + }, + refresh: function(isReset) { + if (isReset && this.finished) { + this.enablePullupToRefresh(); + this.finished = false; + } + this._super(); + }, + }, $.PullRefresh)); + $.fn.pullRefresh = function(options) { + if (this.length === 1) { + var self = this[0]; + var pullRefreshApi = null; + var id = self.getAttribute('data-pullrefresh'); + if (!id && typeof options === 'undefined') { + return false; + } + options = options || {}; + if (!id) { + id = ++$.uuid; + $.data[id] = pullRefreshApi = new PullRefresh(self, options); + self.setAttribute('data-pullrefresh', id); + } else { + pullRefreshApi = $.data[id]; + } + if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 + pullRefreshApi.pulldownLoading(options.down.autoY); + } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 + pullRefreshApi.pullupLoading(); + } + //暂不提供这种调用方式吧 + // if (typeof options === 'string') { + // var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1)); + // if (methodValue !== undefined) { + // return methodValue; + // } + // } + return pullRefreshApi; + } + }; +})(mui, window, document); +/** + * snap 重构 + * @param {Object} $ + * @param {Object} window + */ +(function($, window) { + var CLASS_SLIDER = 'mui-slider'; + var CLASS_SLIDER_GROUP = 'mui-slider-group'; + var CLASS_SLIDER_LOOP = 'mui-slider-loop'; + var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator'; + var CLASS_ACTION_PREVIOUS = 'mui-action-previous'; + var CLASS_ACTION_NEXT = 'mui-action-next'; + var CLASS_SLIDER_ITEM = 'mui-slider-item'; + + var CLASS_ACTIVE = 'mui-active'; + + var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM; + var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR; + var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar'; + + var Slider = $.Slider = $.Scroll.extend({ + init: function(element, options) { + this._super(element, $.extend(true, { + fingers: 1, + interval: 0, //设置为0,则不定时轮播 + scrollY: false, + scrollX: true, + indicators: false, + scrollTime: 1000, + startX: false, + slideTime: 0, //滑动动画时间 + snap: SELECTOR_SLIDER_ITEM + }, options)); + if (this.options.startX) { + // $.trigger(this.wrapper, 'scrollend', this); + } + }, + _init: function() { + this._reInit(); + if (this.scroller) { + this.scrollerStyle = this.scroller.style; + this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR); + if (this.progressBar) { + this.progressBarWidth = this.progressBar.offsetWidth; + this.progressBarStyle = this.progressBar.style; + } + //忘记这个代码是干什么的了? + // this.x = this._getScroll(); + // if (this.options.startX === false) { + // this.options.startX = this.x; + // } + //根据active修正startX + + this._super(); + this._initTimer(); + } + }, + _triggerSlide: function() { + var self = this; + self.isInTransition = false; + var page = self.currentPage; + self.slideNumber = self._fixedSlideNumber(); + if (self.loop) { + if (self.slideNumber === 0) { + self.setTranslate(self.pages[1][0].x, 0); + } else if (self.slideNumber === self.itemLength - 3) { + self.setTranslate(self.pages[self.itemLength - 2][0].x, 0); + } + } + if (self.lastSlideNumber != self.slideNumber) { + self.lastSlideNumber = self.slideNumber; + self.lastPage = self.currentPage; + $.trigger(self.wrapper, 'slide', { + slideNumber: self.slideNumber + }); + } + self._initTimer(); + }, + _handleSlide: function(e) { + var self = this; + if (e.target !== self.wrapper) { + return; + } + var detail = e.detail; + detail.slideNumber = detail.slideNumber || 0; + var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM); + var items = []; + for (var i = 0, len = temps.length; i < len; i++) { + var item = temps[i]; + if (item.parentNode === self.scroller) { + items.push(item); + } + } + var _slideNumber = detail.slideNumber; + if (self.loop) { + _slideNumber += 1; + } + if (!self.wrapper.classList.contains('mui-segmented-control')) { + for (var i = 0, len = items.length; i < len; i++) { + var item = items[i]; + if (item.parentNode === self.scroller) { + if (i === _slideNumber) { + item.classList.add(CLASS_ACTIVE); + } else { + item.classList.remove(CLASS_ACTIVE); + } + } + } + } + var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator'); + if (indicatorWrap) { + if (indicatorWrap.getAttribute('data-scroll')) { //scroll + $(indicatorWrap).scroll().gotoPage(detail.slideNumber); + } + var indicators = indicatorWrap.querySelectorAll('.mui-indicator'); + if (indicators.length > 0) { //图片轮播 + for (var i = 0, len = indicators.length; i < len; i++) { + indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); + } + } else { + var number = indicatorWrap.querySelector('.mui-number span'); + if (number) { //图文表格 + number.innerText = (detail.slideNumber + 1); + } else { //segmented controls + var controlItems = indicatorWrap.querySelectorAll('.mui-control-item'); + for (var i = 0, len = controlItems.length; i < len; i++) { + controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE); + } + } + } + } + e.stopPropagation(); + }, + _handleTabShow: function(e) { + var self = this; + self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime); + }, + _handleIndicatorTap: function(event) { + var self = this; + var target = event.target; + if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) { + self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem'](); + event.stopPropagation(); + } + }, + _initEvent: function(detach) { + var self = this; + self._super(detach); + var action = detach ? 'removeEventListener' : 'addEventListener'; + self.wrapper[action]('slide', this); + self.wrapper[action]($.eventName('shown', 'tab'), this); + }, + handleEvent: function(e) { + this._super(e); + switch (e.type) { + case 'slide': + this._handleSlide(e); + break; + case $.eventName('shown', 'tab'): + if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show + this._handleTabShow(e); + } + break; + } + }, + _scrollend: function(e) { + this._super(e); + this._triggerSlide(e); + }, + _drag: function(e) { + this._super(e); + var direction = e.detail.direction; + if (direction === 'left' || direction === 'right') { + //拖拽期间取消定时 + var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer'); + slidershowTimer && window.clearTimeout(slidershowTimer); + + e.stopPropagation(); + } + }, + _initTimer: function() { + var self = this; + var slider = self.wrapper; + var interval = self.options.interval; + var slidershowTimer = slider.getAttribute('data-slidershowTimer'); + slidershowTimer && window.clearTimeout(slidershowTimer); + if (interval) { + slidershowTimer = window.setTimeout(function() { + if (!slider) { + return; + } + //仅slider显示状态进行自动轮播 + if (!!(slider.offsetWidth || slider.offsetHeight)) { + self.nextItem(true); + //下一个 + } + self._initTimer(); + }, interval); + slider.setAttribute('data-slidershowTimer', slidershowTimer); + } + }, + + _fixedSlideNumber: function(page) { + page = page || this.currentPage; + var slideNumber = page.pageX; + if (this.loop) { + if (page.pageX === 0) { + slideNumber = this.itemLength - 3; + } else if (page.pageX === (this.itemLength - 1)) { + slideNumber = 0; + } else { + slideNumber = page.pageX - 1; + } + } + return slideNumber; + }, + _reLayout: function() { + this.hasHorizontalScroll = true; + this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP); + this._super(); + }, + _getScroll: function() { + var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform')); + return result ? result.x : 0; + }, + _transitionEnd: function(e) { + if (e.target !== this.scroller || !this.isInTransition) { + return; + } + this._transitionTime(); + this.isInTransition = false; + $.trigger(this.wrapper, 'scrollend', this); + }, + _flick: function(e) { + if (!this.moved) { //无moved + return; + } + var detail = e.detail; + var direction = detail.direction; + this._clearRequestAnimationFrame(); + this.isInTransition = true; + // if (direction === 'up' || direction === 'down') { + // this.resetPosition(this.options.bounceTime); + // return; + // } + if (e.type === 'flick') { + if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime + this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x; + } + this.resetPosition(this.options.bounceTime); + } else if (e.type === 'dragend' && !detail.flick) { + this.resetPosition(this.options.bounceTime); + } + e.stopPropagation(); + }, + _initSnap: function() { + this.scrollerWidth = this.itemLength * this.scrollerWidth; + this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0); + this._super(); + if (!this.currentPage.x) { + //当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题 + var currentPage = this.pages[this.loop ? 1 : 0]; + currentPage = currentPage || this.pages[0]; + if (!currentPage) { + return; + } + this.currentPage = currentPage[0]; + this.slideNumber = 0; + this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber; + } else { + this.slideNumber = this._fixedSlideNumber(); + this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber; + } + this.options.startX = this.currentPage.x || 0; + }, + _getSnapX: function(offsetLeft) { + return Math.max(-offsetLeft, this.maxScrollX); + }, + _getPage: function(slideNumber, isFlick) { + if (this.loop) { + if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) { + slideNumber = 1; + time = 0; + } else if (slideNumber < (isFlick ? -1 : 0)) { + slideNumber = this.itemLength - 2; + time = 0; + } else { + slideNumber += 1; + } + } else { + if (!isFlick) { + if (slideNumber > (this.itemLength - 1)) { + slideNumber = 0; + time = 0; + } else if (slideNumber < 0) { + slideNumber = this.itemLength - 1; + time = 0; + } + } + slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1); + } + return this.pages[slideNumber][0]; + }, + _gotoItem: function(slideNumber, time) { + this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画) + this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); + if (time === 0) { + $.trigger(this.wrapper, 'scrollend', this); + } + }, + //API + setTranslate: function(x, y) { + this._super(x, y); + var progressBar = this.progressBar; + if (progressBar) { + this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0); + } + }, + resetPosition: function(time) { + time = time || 0; + if (this.x > 0) { + this.x = 0; + } else if (this.x < this.maxScrollX) { + this.x = this.maxScrollX; + } + this.currentPage = this._nearestSnap(this.x); + this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing); + return true; + }, + gotoItem: function(slideNumber, time) { + this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time); + }, + nextItem: function() { + this._gotoItem(this.slideNumber + 1, this.options.scrollTime); + }, + prevItem: function() { + this._gotoItem(this.slideNumber - 1, this.options.scrollTime); + }, + getSlideNumber: function() { + return this.slideNumber || 0; + }, + _reInit: function() { + var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP); + for (var i = 0, len = groups.length; i < len; i++) { + if (groups[i].parentNode === this.wrapper) { + this.scroller = groups[i]; + break; + } + } + this.scrollerStyle = this.scroller && this.scroller.style; + if (this.progressBar) { + this.progressBarWidth = this.progressBar.offsetWidth; + this.progressBarStyle = this.progressBar.style; + } + }, + refresh: function(options) { + if (options) { + $.extend(this.options, options); + this._super(); + this._initTimer(); + } else { + this._super(); + } + }, + destroy: function() { + this._initEvent(true); //detach + delete $.data[this.wrapper.getAttribute('data-slider')]; + this.wrapper.setAttribute('data-slider', ''); + } + }); + $.fn.slider = function(options) { + var slider = null; + this.each(function() { + var sliderElement = this; + if (!this.classList.contains(CLASS_SLIDER)) { + sliderElement = this.querySelector('.' + CLASS_SLIDER); + } + if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) { + var id = sliderElement.getAttribute('data-slider'); + if (!id) { + id = ++$.uuid; + $.data[id] = slider = new Slider(sliderElement, options); + sliderElement.setAttribute('data-slider', id); + } else { + slider = $.data[id]; + if (slider && options) { + slider.refresh(options); + } + } + } + }); + return slider; + }; + $.ready(function() { + // setTimeout(function() { + $('.mui-slider').slider(); + $('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({ + scrollY: false, + scrollX: true, + indicators: false, + snap: '.mui-control-item' + }); + // }, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的) + + }); +})(mui, window); +/** + * pullRefresh 5+ + * @param {type} $ + * @returns {undefined} + */ +(function($, document) { + if (!($.os.plus)) { //仅在5+android支持多webview的使用 + return; + } + $.plusReady(function() { + if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新 + return; + } + var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh'; + var CLASS_VISIBILITY = 'mui-visibility'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_BLOCK = 'mui-block'; + + var CLASS_PULL_CAPTION = 'mui-pull-caption'; + var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down'; + var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh'; + var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore'; + + var PlusPullRefresh = $.Class.extend({ + init: function(element, options) { + this.element = element; + this.options = options; + this.wrapper = this.scroller = element; + this._init(); + this._initPulldownRefreshEvent(); + }, + _init: function() { + var self = this; + //document.addEventListener('plusscrollbottom', this); + window.addEventListener('dragup', self); + document.addEventListener("plusscrollbottom", self); + self.scrollInterval = window.setInterval(function() { + if (self.isScroll && !self.loading) { + if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) { + self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化 + if (self.bottomPocket) { + self.pullupLoading(); + } + } + } + }, 100); + }, + _initPulldownRefreshEvent: function() { + var self = this; + $.plusReady(function() { + if (self.options.down.style == "circle") { + //单webview、原生转圈 + self.options.webview = plus.webview.currentWebview(); + self.options.webview.setPullToRefresh({ + support: true, + color: self.options.down.color || '#2BD009', + height: self.options.down.height || '50px', + range: self.options.down.range || '100px', + style: 'circle', + offset: self.options.down.offset || '0px' + }, function() { + self.options.down.callback(); + }); + } else if (self.topPocket && self.options.webviewId) { + var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口 + if (!webview) { + return; + } + self.options.webview = webview; + var downOptions = self.options.down; + var height = downOptions.height; + webview.addEventListener('close', function() { + var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/" + self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId); + }); + webview.addEventListener("dragBounce", function(e) { + if (!self.pulldown) { + self._initPulldownRefresh(); + } else { + self.pullPocket.classList.add(CLASS_BLOCK); + } + switch (e.status) { + case "beforeChangeOffset": //下拉可刷新状态 + self._setCaption(downOptions.contentdown); + break; + case "afterChangeOffset": //松开可刷新状态 + self._setCaption(downOptions.contentover); + break; + case "dragEndAfterChangeOffset": //正在刷新状态 + //执行下拉刷新所在webview的回调函数 + webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()"); + self._setCaption(downOptions.contentrefresh); + break; + default: + break; + } + }, false); + + webview.setBounce({ + position: { + top: height * 2 + 'px' + }, + changeoffset: { + top: height + 'px' + } + }); + + } + }); + }, + handleEvent: function(e) { + var self = this; + if (self.stopped) { + return; + } + self.isScroll = false; + if (e.type === 'dragup' || e.type === 'plusscrollbottom') { + self.isScroll = true; + setTimeout(function() { + self.isScroll = false; + }, 1000); + } + } + }).extend($.extend({ + setStopped: function(stopped) { //该方法是子页面调用的 + this.stopped = !!stopped; + // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG + if (this.stopped) { + this.disablePullupToRefresh(); + this.disablePulldownToRefresh(); + } else { + this.enablePullupToRefresh(); + this.enablePulldownToRefresh(); + } + }, + beginPulldown: function() { + var self = this; + $.plusReady(function() { + //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的 + setTimeout(function() { + if (self.options.down.style == "circle") { //单webview下拉刷新 + plus.webview.currentWebview().beginPullToRefresh(); + } else { //双webview模式 + var webview = self.options.webview; + if (webview) { + webview.setBounce({ + offset: { + top: self.options.down.height + "px" + } + }); + } + } + }, 15); + }.bind(this)); + }, + pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API + this.beginPulldown(); + }, + _pulldownLoading: function() { //该方法是父页面调用的 + var self = this; + $.plusReady(function() { + var childWebview = plus.webview.getWebviewById(self.options.webviewId); + childWebview && childWebview.setBounce({ + offset: { + top: self.options.down.height + "px" + } + }); + }); + }, + endPulldown: function() { + var _wv = plus.webview.currentWebview(); + //双webview的下拉刷新,需要修改父窗口提示信息 + if (_wv.parent() && this.options.down.style !== "circle") { + _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({ + webviewId: _wv.id + }) + "')._endPulldownToRefresh()"); + } else { + _wv.endPullToRefresh(); + } + }, + endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API + this.endPulldown(); + }, + _endPulldownToRefresh: function() { //该方法是父页面调用的 + var self = this; + if (self.topPocket && self.options.webview) { + self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹 + self.loading = false; + self._setCaption(self.options.down.contentdown, true); + setTimeout(function() { + self.loading || self.topPocket.classList.remove(CLASS_BLOCK); + }, 350); + } + }, + beginPullup: function(callback) { //开始上拉加载 + var self = this; + if (self.isLoading) return; + self.isLoading = true; + if (self.pulldown !== false) { + self._initPullupRefresh(); + } else { + this.pullPocket.classList.add(CLASS_BLOCK); + } + setTimeout(function() { + self.pullLoading.classList.add(CLASS_VISIBILITY); + self.pullLoading.classList.remove(CLASS_HIDDEN); + self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的) + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH; + self.pullCaption.innerHTML = self.options.up.contentrefresh; + callback = callback || self.options.up.callback; + callback && callback.call(self); + }, 300); + }, + pullupLoading: function(callback) { //兼容老的API + this.beginPullup(callback); + }, + endPullup: function(finished) { //上拉加载结束 + var self = this; + if (self.pullLoading) { + self.pullLoading.classList.remove(CLASS_VISIBILITY); + self.pullLoading.classList.add(CLASS_HIDDEN); + self.isLoading = false; + if (finished) { + self.finished = true; + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE; + self.pullCaption.innerHTML = self.options.up.contentnomore; + //取消5+的plusscrollbottom事件 + document.removeEventListener('plusscrollbottom', self); + window.removeEventListener('dragup', self); + } else { //初始化时隐藏,后续不再隐藏 + self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + self.pullCaption.innerHTML = self.options.up.contentdown; + } + } + }, + endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API + this.endPullup(finished); + }, + disablePulldownToRefresh: function() { + var webview = plus.webview.currentWebview(); + if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新 + this.options.webview.setPullToRefresh({ + support: false, + style: 'circle' + }); + } else { // 双webview模式禁止下拉刷新 + webview.setStyle({ + bounce: 'none' + }); + webview.setBounce({ + position: { + top: 'none' + } + }); + } + }, + enablePulldownToRefresh: function() { + var self = this, + webview = plus.webview.currentWebview(), + height = this.options.down.height; + // 单webview模式禁止原生下拉刷新 + if (this.options.down.style && this.options.down.style == 'circle') { + webview.setPullToRefresh({ + support: true, + height: height || '50px', + range: self.options.down.range || '100px', + style: 'circle', + offset: self.options.down.offset || '0px' + }); + } else { // 重新初始化双webview模式下拉刷新 + webview.setStyle({ + bounce: 'vertical' + }); + webview.setBounce({ + position: { + top: height * 2 + 'px' + }, + changeoffset: { + top: height + 'px' + } + }); + } + }, + disablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN; + window.removeEventListener('dragup', this); + }, + enablePullupToRefresh: function() { + this._initPullupRefresh(); + this.bottomPocket.classList.remove(CLASS_HIDDEN); + this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN; + this.pullCaption.innerHTML = this.options.up.contentdown; + document.addEventListener("plusscrollbottom", this); + window.addEventListener('dragup', this); + }, + scrollTo: function(x, y, time) { + $.scrollTo(y, time); + }, + scrollToBottom: function(time) { + $.scrollTo(document.documentElement.scrollHeight, time); + }, + refresh: function(isReset) { + if (isReset && this.finished) { + this.enablePullupToRefresh(); + this.finished = false; + } + } + }, $.PullRefresh)); + + //override h5 pullRefresh + $.fn.pullRefresh_native = function(options) { + var self; + if (this.length === 0) { + self = document.createElement('div'); + self.className = 'mui-content'; + document.body.appendChild(self); + } else { + self = this[0]; + } + var args = options; + //一个父需要支持多个子下拉刷新 + options = options || {} + if (typeof options === 'string') { + options = $.parseJSON(options); + }; + !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL())); + var pullRefreshApi = null; + var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/" + var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId); + if (!id && typeof args === 'undefined') { + return false; + } + if (!id) { //避免重复初始化5+ pullrefresh + id = ++$.uuid; + self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id); + document.body.classList.add(CLASS_PLUS_PULLREFRESH); + $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options); + } else { + pullRefreshApi = $.data[id]; + } + if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次 + //pullRefreshApi._pulldownLoading(); //parent webview + pullRefreshApi.beginPulldown(); + } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次 + pullRefreshApi.beginPullup(); + } + return pullRefreshApi; + }; + }); + +})(mui, document); +/** + * off-canvas + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} action + * @returns {undefined} + */ +(function($, window, document, name) { + var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left'; + var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right'; + var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop'; + var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap'; + + var CLASS_SLIDE_IN = 'mui-slide-in'; + var CLASS_ACTIVE = 'mui-active'; + + + var CLASS_TRANSITIONING = 'mui-transitioning'; + + var SELECTOR_INNER_WRAP = '.mui-inner-wrap'; + + + var OffCanvas = $.Class.extend({ + init: function(element, options) { + this.wrapper = this.element = element; + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + this.classList = this.wrapper.classList; + if (this.scroller) { + this.options = $.extend(true, { + dragThresholdX: 10, + scale: 0.8, + opacity: 0.1, + preventDefaultException: { + tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/ + }, + }, options); + document.body.classList.add('mui-fullscreen'); //fullscreen + this.refresh(); + this.initEvent(); + } + }, + _preventDefaultException: function(el, exceptions) { + for (var i in exceptions) { + if (exceptions[i].test(el[i])) { + return true; + } + } + return false; + }, + refresh: function(offCanvas) { + // offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE); + this.slideIn = this.classList.contains(CLASS_SLIDE_IN); + this.scalable = this.classList.contains('mui-scalable') && !this.slideIn; + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + // !offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING); + // !offCanvas && this.scroller.setAttribute('style', ''); + this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT); + this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT); + if (offCanvas) { + if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { + this.offCanvasLeft = offCanvas; + } else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { + this.offCanvasRight = offCanvas; + } + } else { + this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT); + this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT); + } + this.offCanvasRightWidth = this.offCanvasLeftWidth = 0; + this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false; + if (this.offCanvasRight) { + this.offCanvasRightWidth = this.offCanvasRight.offsetWidth; + this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper); + // this.offCanvasRight.classList.remove(CLASS_TRANSITIONING); + // this.offCanvasRight.classList.remove(CLASS_ACTIVE); + // this.offCanvasRight.setAttribute('style', ''); + } + if (this.offCanvasLeft) { + this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth; + this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper); + // this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING); + // this.offCanvasLeft.classList.remove(CLASS_ACTIVE); + // this.offCanvasLeft.setAttribute('style', ''); + } + this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP); + + this.options.dragThresholdX = this.options.dragThresholdX || 10; + + this.visible = false; + this.startX = null; + this.lastX = null; + this.offsetX = null; + this.lastTranslateX = null; + }, + handleEvent: function(e) { + switch (e.type) { + case $.EVENT_START: + e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault(); + break; + case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况 + if (e.target === this.scroller) { + this._dispatchEvent(); + } + break; + case 'drag': + var detail = e.detail; + if (!this.startX) { + this.startX = detail.center.x; + this.lastX = this.startX; + } else { + this.lastX = detail.center.x; + } + if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) { + if (this.slideIn) { + this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP); + if (this.classList.contains(CLASS_ACTIVE)) { + if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } + } else { + if (detail.direction === 'left' && this.offCanvasRight) { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else if (detail.direction === 'right' && this.offCanvasLeft) { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.scroller = null; + } + } + } else { + if (this.classList.contains(CLASS_ACTIVE)) { + if (detail.direction === 'left') { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } + } else { + if (detail.direction === 'right') { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } else { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } + } + } + if (this.offCanvas && this.scroller) { + this.startX = this.lastX; + this.isDragging = true; + + $.gestures.session.lockDirection = true; //锁定方向 + $.gestures.session.startDirection = detail.direction; + + this.offCanvas.classList.remove(CLASS_TRANSITIONING); + this.scroller.classList.remove(CLASS_TRANSITIONING); + this.offsetX = this.getTranslateX(); + this._initOffCanvasVisible(); + } + } + if (this.isDragging) { + this.updateTranslate(this.offsetX + (this.lastX - this.startX)); + detail.gesture.preventDefault(); + e.stopPropagation(); + } + break; + case 'dragend': + if (this.isDragging) { + var detail = e.detail; + var direction = detail.direction; + this.isDragging = false; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + var ratio = 0; + var x = this.getTranslateX(); + if (!this.slideIn) { + if (x >= 0) { + ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; + } else { + ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; + } + if (ratio === 0) { + this.openPercentage(0); + this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch + return; + } + if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开 + this.openPercentage(100); + } else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio < 0.5) { //右滑还原打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio > 0.5) { //左滑还原打开 + this.openPercentage(100); + } else { //默认关闭 + this.openPercentage(0); + } + if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch + this._dispatchEvent(); + } + } else { + if (x >= 0) { + ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0; + } else { + ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0; + } + if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开 + this.openPercentage(100); + } else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭 + this.openPercentage(0); + } else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开 + this.openPercentage(-100); + } else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭 + this.openPercentage(0); + } else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开 + this.openPercentage(100); + } else { + this.openPercentage(0); + } + if (ratio === 1 || ratio === -1 || ratio === 0) { + this._dispatchEvent(); + return; + } + + } + } + break; + } + }, + _dispatchEvent: function() { + if (this.classList.contains(CLASS_ACTIVE)) { + $.trigger(this.wrapper, 'shown', this); + } else { + $.trigger(this.wrapper, 'hidden', this); + } + }, + _initOffCanvasVisible: function() { + if (!this.visible) { + this.visible = true; + if (this.offCanvasLeft) { + this.offCanvasLeft.style.visibility = 'visible'; + } + if (this.offCanvasRight) { + this.offCanvasRight.style.visibility = 'visible'; + } + } + }, + initEvent: function() { + var self = this; + if (self.backdrop) { + self.backdrop.addEventListener('tap', function(e) { + self.close(); + e.detail.gesture.preventDefault(); + }); + } + if (this.classList.contains('mui-draggable')) { + this.wrapper.addEventListener($.EVENT_START, this); //临时处理 + this.wrapper.addEventListener('drag', this); + this.wrapper.addEventListener('dragend', this); + } + this.wrapper.addEventListener('webkitTransitionEnd', this); + }, + openPercentage: function(percentage) { + var p = percentage / 100; + if (!this.slideIn) { + if (this.offCanvasLeft && percentage >= 0) { + this.updateTranslate(this.offCanvasLeftWidth * p); + this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else if (this.offCanvasRight && percentage <= 0) { + this.updateTranslate(this.offCanvasRightWidth * p); + this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else { + if (this.offCanvasLeft && percentage >= 0) { + p = p === 0 ? -1 : 0; + this.updateTranslate(this.offCanvasLeftWidth * p); + this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } else if (this.offCanvasRight && percentage <= 0) { + p = p === 0 ? 1 : 0; + this.updateTranslate(this.offCanvasRightWidth * p); + this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE); + } + }, + updateTranslate: function(x) { + if (x !== this.lastTranslateX) { + if (!this.slideIn) { + if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) { + this.setTranslateX(0); + return; + } + if (this.leftShowing && x > this.offCanvasLeftWidth) { + this.setTranslateX(this.offCanvasLeftWidth); + return; + } + if (this.rightShowing && x < -this.offCanvasRightWidth) { + this.setTranslateX(-this.offCanvasRightWidth); + return; + } + this.setTranslateX(x); + if (x >= 0) { + this.leftShowing = true; + this.rightShowing = false; + if (x > 0) { + if (this.offCanvasLeft) { + $.each(this.offCanvasLefts, function(index, offCanvas) { + if (offCanvas === this.offCanvasLeft) { + this.offCanvasLeft.style.zIndex = 0; + } else { + offCanvas.style.zIndex = -1; + } + }.bind(this)); + } + if (this.offCanvasRight) { + this.offCanvasRight.style.zIndex = -1; + } + } + } else { + this.rightShowing = true; + this.leftShowing = false; + if (this.offCanvasRight) { + $.each(this.offCanvasRights, function(index, offCanvas) { + if (offCanvas === this.offCanvasRight) { + offCanvas.style.zIndex = 0; + } else { + offCanvas.style.zIndex = -1; + } + }.bind(this)); + } + if (this.offCanvasLeft) { + this.offCanvasLeft.style.zIndex = -1; + } + } + } else { + if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) { + if (x < 0) { + this.setTranslateX(0); + return; + } + if (x > this.offCanvasRightWidth) { + this.setTranslateX(this.offCanvasRightWidth); + return; + } + } else { + if (x > 0) { + this.setTranslateX(0); + return; + } + if (x < -this.offCanvasLeftWidth) { + this.setTranslateX(-this.offCanvasLeftWidth); + return; + } + } + this.setTranslateX(x); + } + this.lastTranslateX = x; + } + }, + setTranslateX: $.animationFrame(function(x) { + if (this.scroller) { + if (this.scalable && this.offCanvas.parentNode === this.wrapper) { + var percent = Math.abs(x) / this.offCanvasWidth; + var zoomOutScale = 1 - (1 - this.options.scale) * percent; + var zoomInScale = this.options.scale + (1 - this.options.scale) * percent; + var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent; + var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent; + if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) { + this.offCanvas.style.webkitTransformOrigin = '-100%'; + this.scroller.style.webkitTransformOrigin = 'left'; + } else { + this.offCanvas.style.webkitTransformOrigin = '200%'; + this.scroller.style.webkitTransformOrigin = 'right'; + } + this.offCanvas.style.opacity = zoomInOpacity; + this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')'; + this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')'; + } else { + if (this.slideIn) { + this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; + } else { + this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)'; + } + } + } + }), + getTranslateX: function() { + if (this.offCanvas) { + var scroller = this.slideIn ? this.offCanvas : this.scroller; + var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform')); + return (result && result.x) || 0; + } + return 0; + }, + isShown: function(direction) { + var shown = false; + if (!this.slideIn) { + var x = this.getTranslateX(); + if (direction === 'right') { + shown = this.classList.contains(CLASS_ACTIVE) && x < 0; + } else if (direction === 'left') { + shown = this.classList.contains(CLASS_ACTIVE) && x > 0; + } else { + shown = this.classList.contains(CLASS_ACTIVE) && x !== 0; + } + } else { + if (direction === 'left') { + shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); + } else if (direction === 'right') { + shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE); + } else { + shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE)); + } + } + return shown; + }, + close: function() { + this._initOffCanvasVisible(); + this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE); + this.offCanvasWidth = this.offCanvas.offsetWidth; + if (this.scroller) { + this.offCanvas.offsetHeight; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + this.openPercentage(0); + } + }, + show: function(direction) { + this._initOffCanvasVisible(); + if (this.isShown(direction)) { + return false; + } + if (!direction) { + direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left'; + } + if (direction === 'right') { + this.offCanvas = this.offCanvasRight; + this.offCanvasWidth = this.offCanvasRightWidth; + } else { + this.offCanvas = this.offCanvasLeft; + this.offCanvasWidth = this.offCanvasLeftWidth; + } + if (this.scroller) { + this.offCanvas.offsetHeight; + this.offCanvas.classList.add(CLASS_TRANSITIONING); + this.scroller.classList.add(CLASS_TRANSITIONING); + this.openPercentage(direction === 'left' ? 100 : -100); + } + return true; + }, + toggle: function(directionOrOffCanvas) { + var direction = directionOrOffCanvas; + if (directionOrOffCanvas && directionOrOffCanvas.classList) { + direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right'; + this.refresh(directionOrOffCanvas); + } + if (!this.show(direction)) { + this.close(); + } + } + }); + + //hash to offcanvas + var findOffCanvasContainer = function(target) { + parentNode = target.parentNode; + if (parentNode) { + if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + return parentNode; + } else { + parentNode = parentNode.parentNode; + if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + return parentNode; + } + } + } + }; + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + var offcanvas = document.getElementById(target.hash.replace('#', '')); + if (offcanvas) { + var container = findOffCanvasContainer(offcanvas); + if (container) { + $.targets._container = container; + return offcanvas; + } + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 60, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + window.addEventListener('tap', function(e) { + if (!$.targets.offcanvas) { + return; + } + //TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好 + var target = e.target; + for (; target && target !== document; target = target.parentNode) { + if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) { + e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange + $($.targets._container).offCanvas().toggle($.targets.offcanvas); + $.targets.offcanvas = $.targets._container = null; + break; + } + } + }); + + $.fn.offCanvas = function(options) { + var offCanvasApis = []; + this.each(function() { + var offCanvasApi = null; + var self = this; + //hack old version + if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) { + self = findOffCanvasContainer(self); + } + var id = self.getAttribute('data-offCanvas'); + if (!id) { + id = ++$.uuid; + $.data[id] = offCanvasApi = new OffCanvas(self, options); + self.setAttribute('data-offCanvas', id); + } else { + offCanvasApi = $.data[id]; + } + if (options === 'show' || options === 'close' || options === 'toggle') { + offCanvasApi.toggle(); + } + offCanvasApis.push(offCanvasApi); + }); + return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis; + }; + $.ready(function() { + $('.mui-off-canvas-wrap').offCanvas(); + }); +})(mui, window, document, 'offcanvas'); +/** + * actions + * @param {type} $ + * @param {type} name + * @returns {undefined} + */ +(function($, name) { + var CLASS_ACTION = 'mui-action'; + + var handle = function(event, target) { + var className = target.className || ''; + if (typeof className !== 'string') { //svg className(SVGAnimatedString) + className = ''; + } + if (className && ~className.indexOf(CLASS_ACTION)) { + if (target.classList.contains('mui-action-back')) { + event.preventDefault(); + } + return target; + } + return false; + }; + + $.registerTarget({ + name: name, + index: 50, + handle: handle, + target: false, + isContinue: true + }); + +})(mui, 'action'); +/** + * Modals + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} name + * @returns {undefined} + */ +(function($, window, document, name) { + var CLASS_MODAL = 'mui-modal'; + + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + var modal = document.getElementById(target.hash.replace('#', '')); + if (modal && modal.classList.contains(CLASS_MODAL)) { + return modal; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 50, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + window.addEventListener('tap', function(event) { + if ($.targets.modal) { + event.detail.gesture.preventDefault(); //fixed hashchange + $.targets.modal.classList.toggle('mui-active'); + } + }); +})(mui, window, document, 'modal'); +/** + * Popovers + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} name + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, document, name) { + + var CLASS_POPOVER = 'mui-popover'; + var CLASS_POPOVER_ARROW = 'mui-popover-arrow'; + var CLASS_ACTION_POPOVER = 'mui-popover-action'; + var CLASS_BACKDROP = 'mui-backdrop'; + var CLASS_BAR_POPOVER = 'mui-bar-popover'; + var CLASS_BAR_BACKDROP = 'mui-bar-backdrop'; + var CLASS_ACTION_BACKDROP = 'mui-backdrop-action'; + var CLASS_ACTIVE = 'mui-active'; + var CLASS_BOTTOM = 'mui-bottom'; + + + + var handle = function(event, target) { + if (target.tagName === 'A' && target.hash) { + $.targets._popover = document.getElementById(target.hash.replace('#', '')); + if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) { + return target; + } else { + $.targets._popover = null; + } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 60, + handle: handle, + target: false, + isReset: false, + isContinue: true + }); + + var onPopoverShown = function(e) { + this.removeEventListener('webkitTransitionEnd', onPopoverShown); + this.addEventListener($.EVENT_MOVE, $.preventDefault); + $.trigger(this, 'shown', this); + } + var onPopoverHidden = function(e) { + setStyle(this, 'none'); + this.removeEventListener('webkitTransitionEnd', onPopoverHidden); + this.removeEventListener($.EVENT_MOVE, $.preventDefault); + $.trigger(this, 'hidden', this); + }; + + var backdrop = (function() { + var element = document.createElement('div'); + element.classList.add(CLASS_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('tap', function(e) { + var popover = $.targets._popover; + if (popover) { + popover.addEventListener('webkitTransitionEnd', onPopoverHidden); + popover.classList.remove(CLASS_ACTIVE); + removeBackdrop(popover); + } + }); + + return element; + }()); + var removeBackdropTimer; + var removeBackdrop = function(popover) { + backdrop.setAttribute('style', 'opacity:0'); + $.targets.popover = $.targets._popover = null; //reset + removeBackdropTimer = $.later(function() { + if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) { + document.body.removeChild(backdrop); + } + }, 350); + }; + window.addEventListener('tap', function(e) { + if (!$.targets.popover) { + return; + } + var toggle = false; + var target = e.target; + for (; target && target !== document; target = target.parentNode) { + if (target === $.targets.popover) { + toggle = true; + } + } + if (toggle) { + e.detail.gesture.preventDefault(); //fixed hashchange + togglePopover($.targets._popover, $.targets.popover); + } + + }); + + var togglePopover = function(popover, anchor, state) { + if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) { + return; + } + removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer + //remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove + popover.removeEventListener('webkitTransitionEnd', onPopoverShown); + popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); + backdrop.classList.remove(CLASS_BAR_BACKDROP); + backdrop.classList.remove(CLASS_ACTION_BACKDROP); + var _popover = document.querySelector('.mui-popover.mui-active'); + if (_popover) { + // _popover.setAttribute('style', ''); + _popover.addEventListener('webkitTransitionEnd', onPopoverHidden); + _popover.classList.remove(CLASS_ACTIVE); + // _popover.removeEventListener('webkitTransitionEnd', onPopoverHidden); + //同一个弹出则直接返回,解决同一个popover的toggle + if (popover === _popover) { + removeBackdrop(_popover); + return; + } + } + var isActionSheet = false; + if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar + if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover + isActionSheet = true; + backdrop.classList.add(CLASS_ACTION_BACKDROP); + } else { //bar popover + backdrop.classList.add(CLASS_BAR_BACKDROP); + // if (anchor) { + // if (anchor.parentNode) { + // var offsetWidth = anchor.offsetWidth; + // var offsetLeft = anchor.offsetLeft; + // var innerWidth = window.innerWidth; + // popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px"; + // } else { + // //TODO anchor is position:{left,top,bottom,right} + // } + // } + } + } + setStyle(popover, 'block'); //actionsheet transform + popover.offsetHeight; + popover.classList.add(CLASS_ACTIVE); + backdrop.setAttribute('style', ''); + document.body.appendChild(backdrop); + calPosition(popover, anchor, isActionSheet); //position + backdrop.classList.add(CLASS_ACTIVE); + popover.addEventListener('webkitTransitionEnd', onPopoverShown); + }; + var setStyle = function(popover, display, top, left) { + var style = popover.style; + if (typeof display !== 'undefined') + style.display = display; + if (typeof top !== 'undefined') + style.top = top + 'px'; + if (typeof left !== 'undefined') + style.left = left + 'px'; + }; + var calPosition = function(popover, anchor, isActionSheet) { + if (!popover || !anchor) { + return; + } + + if (isActionSheet) { //actionsheet + setStyle(popover, 'block') + return; + } + + var wWidth = window.innerWidth; + var wHeight = window.innerHeight; + + var pWidth = popover.offsetWidth; + var pHeight = popover.offsetHeight; + + var aWidth = anchor.offsetWidth; + var aHeight = anchor.offsetHeight; + var offset = $.offset(anchor); + + var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW); + if (!arrow) { + arrow = document.createElement('div'); + arrow.className = CLASS_POPOVER_ARROW; + popover.appendChild(arrow); + } + var arrowSize = arrow && arrow.offsetWidth / 2 || 0; + + + + var pTop = 0; + var pLeft = 0; + var diff = 0; + var arrowLeft = 0; + var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5; + + var position = 'top'; + if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top + pTop = offset.top - pHeight - arrowSize; + } else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom + position = 'bottom'; + pTop = offset.top + aHeight + arrowSize; + } else { //middle + position = 'middle'; + pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0); + pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0); + } + if (position === 'top' || position === 'bottom') { + pLeft = aWidth / 2 + offset.left - pWidth / 2; + diff = pLeft; + if (pLeft < defaultPadding) pLeft = defaultPadding; + if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding; + + if (arrow) { + if (position === 'top') { + arrow.classList.add(CLASS_BOTTOM); + } else { + arrow.classList.remove(CLASS_BOTTOM); + } + diff = diff - pLeft; + arrowLeft = (pWidth / 2 - arrowSize / 2 + diff); + arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6); + arrow.setAttribute('style', 'left:' + arrowLeft + 'px'); + } + } else if (position === 'middle') { + arrow.setAttribute('style', 'display:none'); + } + setStyle(popover, 'block', pTop, pLeft); + }; + + $.createMask = function(callback) { + var element = document.createElement('div'); + element.classList.add(CLASS_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('tap', function() { + mask.close(); + }); + var mask = [element]; + mask._show = false; + mask.show = function() { + mask._show = true; + element.setAttribute('style', 'opacity:1'); + document.body.appendChild(element); + return mask; + }; + mask._remove = function() { + if (mask._show) { + mask._show = false; + element.setAttribute('style', 'opacity:0'); + $.later(function() { + var body = document.body; + element.parentNode === body && body.removeChild(element); + }, 350); + } + return mask; + }; + mask.close = function() { + if (callback) { + if (callback() !== false) { + mask._remove(); + } + } else { + mask._remove(); + } + }; + return mask; + }; + $.fn.popover = function() { + var args = arguments; + this.each(function() { + $.targets._popover = this; + if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') { + togglePopover(this, args[1], args[0]); + } + }); + }; + +})(mui, window, document, 'popover'); +/** + * segmented-controllers + * @param {type} $ + * @param {type} window + * @param {type} document + * @param {type} undefined + * @returns {undefined} + */ +(function($, window, document, name, undefined) { + + var CLASS_CONTROL_ITEM = 'mui-control-item'; + var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control'; + var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical'; + var CLASS_CONTROL_CONTENT = 'mui-control-content'; + var CLASS_TAB_BAR = 'mui-bar-tab'; + var CLASS_TAB_ITEM = 'mui-tab-item'; + var CLASS_SLIDER_ITEM = 'mui-slider-item'; + + var handle = function(event, target) { + if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) { + if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) { + //vertical 如果preventDefault会导致无法滚动 + } else { + + event.preventDefault(); + // if(target.tagName == 'A') { + // // fixed 底部选项卡href 无法跳转 && stop hash change + // var curr_href = location.hostname + location.pathname, + // target_href = target.hostname + target.pathname; + + // if (curr_href == target_href && target.hash !== "") { + // event.preventDefault(); + // return target; + // }else{ + // return false + // } + // } + } + // if (target.hash) { + return target; + // } + } + return false; + }; + + $.registerTarget({ + name: name, + index: 80, + handle: handle, + target: false + }); + + window.addEventListener('tap', function(e) { + + var targetTab = $.targets.tab; + if (!targetTab) { + return; + } + var activeTab; + var activeBodies; + var targetBody; + var className = 'mui-active'; + var classSelector = '.' + className; + var segmentedControl = targetTab.parentNode; + + for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) { + if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) { + activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM); + break; + } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) { + activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM); + } + } + + if (activeTab) { + activeTab.classList.remove(className); + } + + var isLastActive = targetTab === activeTab; + if (targetTab) { + targetTab.classList.add(className); + } + + if (!targetTab.hash) { + return; + } + targetBody = document.getElementById(targetTab.hash.replace('#', '')); + + if (!targetBody) { + return; + } + if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover + targetTab.classList[isLastActive ? 'remove' : 'add'](className); + return; + } + if (isLastActive) { //same + return; + } + var parentNode = targetBody.parentNode; + activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector); + for (var i = 0; i < activeBodies.length; i++) { + var activeBody = activeBodies[i]; + activeBody.parentNode === parentNode && activeBody.classList.remove(className); + } + + targetBody.classList.add(className); + + var contents = []; + var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT); + for (var i = 0; i < _contents.length; i++) { //查找直属子节点 + _contents[i].parentNode === parentNode && (contents.push(_contents[i])); + } + $.trigger(targetBody, $.eventName('shown', name), { + tabNumber: Array.prototype.indexOf.call(contents, targetBody) + }); + e.detail && e.detail.gesture.preventDefault(); //fixed hashchange + }); + +})(mui, window, document, 'tab'); +/** + * Toggles switch + * @param {type} $ + * @param {type} window + * @param {type} name + * @returns {undefined} + */ +(function($, window, name) { + + var CLASS_SWITCH = 'mui-switch'; + var CLASS_SWITCH_HANDLE = 'mui-switch-handle'; + var CLASS_ACTIVE = 'mui-active'; + var CLASS_DRAGGING = 'mui-dragging'; + + var CLASS_DISABLED = 'mui-disabled'; + + var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE; + + var handle = function(event, target) { + if (target.classList && target.classList.contains(CLASS_SWITCH)) { + return target; + } + return false; + }; + + $.registerTarget({ + name: name, + index: 100, + handle: handle, + target: false + }); + + + var Toggle = function(element) { + this.element = element; + this.classList = this.element.classList; + this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE); + this.init(); + this.initEvent(); + }; + Toggle.prototype.init = function() { + this.toggleWidth = this.element.offsetWidth; + this.handleWidth = this.handle.offsetWidth; + this.handleX = this.toggleWidth - this.handleWidth - 3; + }; + Toggle.prototype.initEvent = function() { + this.element.addEventListener($.EVENT_START, this); + this.element.addEventListener('drag', this); + this.element.addEventListener('swiperight', this); + this.element.addEventListener($.EVENT_END, this); + this.element.addEventListener($.EVENT_CANCEL, this); + + }; + Toggle.prototype.handleEvent = function(e) { + if (this.classList.contains(CLASS_DISABLED)) { + return; + } + switch (e.type) { + case $.EVENT_START: + this.start(e); + break; + case 'drag': + this.drag(e); + break; + case 'swiperight': + this.swiperight(); + break; + case $.EVENT_END: + case $.EVENT_CANCEL: + this.end(e); + break; + } + }; + Toggle.prototype.start = function(e) { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; + this.classList.add(CLASS_DRAGGING); + if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化 + this.init(); + } + }; + Toggle.prototype.drag = function(e) { + var detail = e.detail; + if (!this.isDragging) { + if (detail.direction === 'left' || detail.direction === 'right') { + this.isDragging = true; + this.lastChanged = undefined; + this.initialState = this.classList.contains(CLASS_ACTIVE); + } + } + if (this.isDragging) { + this.setTranslateX(detail.deltaX); + e.stopPropagation(); + detail.gesture.preventDefault(); + } + }; + Toggle.prototype.swiperight = function(e) { + if (this.isDragging) { + e.stopPropagation(); + } + }; + Toggle.prototype.end = function(e) { + this.classList.remove(CLASS_DRAGGING); + if (this.isDragging) { + this.isDragging = false; + e.stopPropagation(); + $.trigger(this.element, 'toggle', { + isActive: this.classList.contains(CLASS_ACTIVE) + }); + } else { + this.toggle(); + } + }; + Toggle.prototype.toggle = function(animate) { + var classList = this.classList; + if (animate === false) { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s'; + } else { + this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s'; + } + if (classList.contains(CLASS_ACTIVE)) { + classList.remove(CLASS_ACTIVE); + this.handle.style.webkitTransform = 'translate(0,0)'; + } else { + classList.add(CLASS_ACTIVE); + this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)'; + } + $.trigger(this.element, 'toggle', { + isActive: this.classList.contains(CLASS_ACTIVE) + }); + }; + Toggle.prototype.setTranslateX = $.animationFrame(function(x) { + if (!this.isDragging) { + return; + } + var isChanged = false; + if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) { + isChanged = true; + } + if (this.lastChanged !== isChanged) { + if (isChanged) { + this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)'; + this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE); + } else { + this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)'; + this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE); + } + this.lastChanged = isChanged; + } + + }); + + $.fn['switch'] = function(options) { + var switchApis = []; + this.each(function() { + var switchApi = null; + var id = this.getAttribute('data-switch'); + if (!id) { + id = ++$.uuid; + $.data[id] = new Toggle(this); + this.setAttribute('data-switch', id); + } else { + switchApi = $.data[id]; + } + switchApis.push(switchApi); + }); + return switchApis.length > 1 ? switchApis : switchApis[0]; + }; + $.ready(function() { + $('.' + CLASS_SWITCH)['switch'](); + }); +})(mui, window, 'toggle'); +/** + * Tableviews + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + + var CLASS_ACTIVE = 'mui-active'; + var CLASS_SELECTED = 'mui-selected'; + var CLASS_GRID_VIEW = 'mui-grid-view'; + var CLASS_RADIO_VIEW = 'mui-table-view-radio'; + var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell'; + var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content'; + var CLASS_DISABLED = 'mui-disabled'; + var CLASS_TOGGLE = 'mui-switch'; + var CLASS_BTN = 'mui-btn'; + + var CLASS_SLIDER_HANDLE = 'mui-slider-handle'; + var CLASS_SLIDER_LEFT = 'mui-slider-left'; + var CLASS_SLIDER_RIGHT = 'mui-slider-right'; + var CLASS_TRANSITIONING = 'mui-transitioning'; + + + var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE; + var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT; + var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT; + var SELECTOR_SELECTED = '.' + CLASS_SELECTED; + var SELECTOR_BUTTON = '.' + CLASS_BTN; + var overFactor = 0.8; + var cell, a; + + var isMoved = isOpened = openedActions = progress = false; + var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; + var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0; + + + + var toggleActive = function(isActive) { + if (isActive) { + if (a) { + a.classList.add(CLASS_ACTIVE); + } else if (cell) { + cell.classList.add(CLASS_ACTIVE); + } + } else { + timer && timer.cancel(); + if (a) { + a.classList.remove(CLASS_ACTIVE); + } else if (cell) { + cell.classList.remove(CLASS_ACTIVE); + } + } + }; + + var updateTranslate = function() { + if (translateX !== lastTranslateX) { + if (buttonsRight && buttonsRight.length > 0) { + progress = translateX / sliderActionRightWidth; + if (translateX < -sliderActionRightWidth) { + translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor); + } + for (var i = 0, len = buttonsRight.length; i < len; i++) { + var buttonRight = buttonsRight[i]; + if (typeof buttonRight._buttonOffset === 'undefined') { + buttonRight._buttonOffset = buttonRight.offsetLeft; + } + buttonOffset = buttonRight._buttonOffset; + setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1)))); + } + } + if (buttonsLeft && buttonsLeft.length > 0) { + progress = translateX / sliderActionLeftWidth; + if (translateX > sliderActionLeftWidth) { + translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor); + } + for (var i = 0, len = buttonsLeft.length; i < len; i++) { + var buttonLeft = buttonsLeft[i]; + if (typeof buttonLeft._buttonOffset === 'undefined') { + buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; + } + buttonOffset = buttonLeft._buttonOffset; + if (buttonsLeft.length > 1) { + buttonLeft.style.zIndex = buttonsLeft.length - i; + } + setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1)))); + } + } + setTranslate(sliderHandle, translateX); + lastTranslateX = translateX; + } + sliderRequestAnimationFrame = requestAnimationFrame(function() { + updateTranslate(); + }); + }; + var setTranslate = function(element, x) { + if (element) { + element.style.webkitTransform = 'translate(' + x + 'px,0)'; + } + }; + + window.addEventListener($.EVENT_START, function(event) { + if (cell) { + toggleActive(false); + } + cell = a = false; + isMoved = isOpened = openedActions = false; + var target = event.target; + var isDisabled = false; + for (; target && target !== document; target = target.parentNode) { + if (target.classList) { + var classList = target.classList; + if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) { + isDisabled = true; + } + if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content + break; + } + if (classList.contains(CLASS_TABLE_VIEW_CELL)) { + cell = target; + //TODO swipe to delete close + var selected = cell.parentNode.querySelector(SELECTOR_SELECTED); + if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) { + $.swipeoutClose(selected); + cell = isDisabled = false; + return; + } + if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) { + var link = cell.querySelector('a'); + if (link && link.parentNode === cell) { //li>a + a = link; + } + } + var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE); + if (handle) { + toggleEvents(cell); + event.stopPropagation(); + } + if (!isDisabled) { + if (handle) { + if (timer) { + timer.cancel(); + } + timer = $.later(function() { + toggleActive(true); + }, 100); + } else { + toggleActive(true); + } + } + break; + } + } + } + }); + window.addEventListener($.EVENT_MOVE, function(event) { + toggleActive(false); + }); + + var handleEvent = { + handleEvent: function(event) { + switch (event.type) { + case 'drag': + this.drag(event); + break; + case 'dragend': + this.dragend(event); + break; + case 'flick': + this.flick(event); + break; + case 'swiperight': + this.swiperight(event); + break; + case 'swipeleft': + this.swipeleft(event); + break; + } + }, + drag: function(event) { + if (!cell) { + return; + } + if (!isMoved) { //init + sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false; + sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE); + if (sliderHandle) { + sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT); + sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT); + if (sliderActionLeft) { + sliderActionLeftWidth = sliderActionLeft.offsetWidth; + buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON); + } + if (sliderActionRight) { + sliderActionRightWidth = sliderActionRight.offsetWidth; + buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON); + } + cell.classList.remove(CLASS_TRANSITIONING); + isOpened = cell.classList.contains(CLASS_SELECTED); + if (isOpened) { + openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right'; + } + } + } + var detail = event.detail; + var direction = detail.direction; + var angle = detail.angle; + if (direction === 'left' && (angle > 150 || angle < -150)) { + if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态 + isMoved = true; + } + } else if (direction === 'right' && (angle > -30 && angle < 30)) { + if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态 + isMoved = true; + } + } + if (isMoved) { + event.stopPropagation(); + event.detail.gesture.preventDefault(); + var translate = event.detail.deltaX; + if (isOpened) { + if (openedActions === 'right') { + translate = translate - sliderActionRightWidth; + } else { + translate = translate + sliderActionLeftWidth; + } + } + if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) { + if (!isOpened) { + return; + } + translate = 0; + } + if (translate < 0) { + sliderDirection = 'toLeft'; + } else if (translate > 0) { + sliderDirection = 'toRight'; + } else { + if (!sliderDirection) { + sliderDirection = 'toLeft'; + } + } + if (!sliderRequestAnimationFrame) { + updateTranslate(); + } + translateX = translate; + } + }, + flick: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + swipeleft: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + swiperight: function(event) { + if (isMoved) { + event.stopPropagation(); + } + }, + dragend: function(event) { + if (!isMoved) { + return; + } + event.stopPropagation(); + if (sliderRequestAnimationFrame) { + cancelAnimationFrame(sliderRequestAnimationFrame); + sliderRequestAnimationFrame = null; + } + var detail = event.detail; + isMoved = false; + var action = 'close'; + var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth; + var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2); + if (isToggle) { + if (!isOpened) { + action = 'open'; + } else if (detail.direction === 'left' && openedActions === 'right') { + action = 'open'; + } else if (detail.direction === 'right' && openedActions === 'left') { + action = 'open'; + } + + } + cell.classList.add(CLASS_TRANSITIONING); + var buttons; + if (action === 'open') { + var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth; + setTranslate(sliderHandle, newTranslate); + buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft; + if (typeof buttons !== 'undefined') { + var button = null; + for (var i = 0; i < buttons.length; i++) { + button = buttons[i]; + setTranslate(button, newTranslate); + } + button.parentNode.classList.add(CLASS_SELECTED); + cell.classList.add(CLASS_SELECTED); + if (!isOpened) { + $.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright'); + } + } + } else { + setTranslate(sliderHandle, 0); + sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED); + sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED); + cell.classList.remove(CLASS_SELECTED); + } + var buttonOffset; + if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) { + for (var i = 0, len = buttonsLeft.length; i < len; i++) { + var buttonLeft = buttonsLeft[i]; + buttonOffset = buttonLeft._buttonOffset; + if (typeof buttonOffset === 'undefined') { + buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth; + } + setTranslate(buttonLeft, buttonOffset); + } + } + if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) { + for (var i = 0, len = buttonsRight.length; i < len; i++) { + var buttonRight = buttonsRight[i]; + buttonOffset = buttonRight._buttonOffset; + if (typeof buttonOffset === 'undefined') { + buttonRight._buttonOffset = buttonRight.offsetLeft; + } + setTranslate(buttonRight, -buttonOffset); + } + } + } + }; + + function toggleEvents(element, isRemove) { + var method = !!isRemove ? 'removeEventListener' : 'addEventListener'; + element[method]('drag', handleEvent); + element[method]('dragend', handleEvent); + element[method]('swiperight', handleEvent); + element[method]('swipeleft', handleEvent); + element[method]('flick', handleEvent); + }; + /** + * 打开滑动菜单 + * @param {Object} el + * @param {Object} direction + */ + $.swipeoutOpen = function(el, direction) { + if (!el) return; + var classList = el.classList; + if (classList.contains(CLASS_SELECTED)) return; + if (!direction) { + if (el.querySelector(SELECTOR_SLIDER_RIGHT)) { + direction = 'right'; + } else { + direction = 'left'; + } + } + var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); + if (!swipeoutAction) return; + swipeoutAction.classList.add(CLASS_SELECTED); + classList.add(CLASS_SELECTED); + classList.remove(CLASS_TRANSITIONING); + var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); + var swipeoutWidth = swipeoutAction.offsetWidth; + var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth; + var length = buttons.length; + var button; + for (var i = 0; i < length; i++) { + button = buttons[i]; + if (direction === 'right') { + setTranslate(button, -button.offsetLeft); + } else { + setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); + } + } + classList.add(CLASS_TRANSITIONING); + for (var i = 0; i < length; i++) { + setTranslate(buttons[i], translate); + } + setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate); + }; + /** + * 关闭滑动菜单 + * @param {Object} el + */ + $.swipeoutClose = function(el) { + if (!el) return; + var classList = el.classList; + if (!classList.contains(CLASS_SELECTED)) return; + var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left'; + var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction)); + if (!swipeoutAction) return; + swipeoutAction.classList.remove(CLASS_SELECTED); + classList.remove(CLASS_SELECTED); + classList.add(CLASS_TRANSITIONING); + var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON); + var swipeoutWidth = swipeoutAction.offsetWidth; + var length = buttons.length; + var button; + setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0); + for (var i = 0; i < length; i++) { + button = buttons[i]; + if (direction === 'right') { + setTranslate(button, (-button.offsetLeft)); + } else { + setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft)); + } + } + }; + + window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 + if (!cell) { + return; + } + toggleActive(false); + sliderHandle && toggleEvents(cell, true); + }); + window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件 + if (!cell) { + return; + } + toggleActive(false); + sliderHandle && toggleEvents(cell, true); + }); + var radioOrCheckboxClick = function(event) { + var type = event.target && event.target.type || ''; + if (type === 'radio' || type === 'checkbox') { + return; + } + var classList = cell.classList; + if (classList.contains('mui-radio')) { + var input = cell.querySelector('input[type=radio]'); + if (input) { + // input.click(); + if (!input.disabled && !input.readOnly) { + input.checked = !input.checked; + $.trigger(input, 'change'); + } + } + } else if (classList.contains('mui-checkbox')) { + var input = cell.querySelector('input[type=checkbox]'); + if (input) { + // input.click(); + if (!input.disabled && !input.readOnly) { + input.checked = !input.checked; + $.trigger(input, 'change'); + } + } + } + }; + //fixed hashchange(android) + window.addEventListener($.EVENT_CLICK, function(e) { + if (cell && cell.classList.contains('mui-collapse')) { + e.preventDefault(); + } + }); + window.addEventListener('doubletap', function(event) { + if (cell) { + radioOrCheckboxClick(event); + } + }); + var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/; + window.addEventListener('tap', function(event) { + if (!cell) { + return; + } + var isExpand = false; + var classList = cell.classList; + var ul = cell.parentNode; + if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) { + if (classList.contains(CLASS_SELECTED)) { + return; + } + var selected = ul.querySelector('li' + SELECTOR_SELECTED); + if (selected) { + selected.classList.remove(CLASS_SELECTED); + } + classList.add(CLASS_SELECTED); + $.trigger(cell, 'selected', { + el: cell + }); + return; + } + if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) { + if (!preventDefaultException.test(event.target.tagName)) { + event.detail.gesture.preventDefault(); + } + + if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类 + var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active'); + if (collapse) { + collapse.classList.remove(CLASS_ACTIVE); + } + isExpand = true; + } + classList.toggle(CLASS_ACTIVE); + if (isExpand) { + //触发展开事件 + $.trigger(cell, 'expand'); + + //scroll + //暂不滚动 + // var offsetTop = $.offset(cell).top; + // var scrollTop = document.body.scrollTop; + // var height = window.innerHeight; + // var offsetHeight = cell.offsetHeight; + // var cellHeight = (offsetTop - scrollTop + offsetHeight); + // if (offsetHeight > height) { + // $.scrollTo(offsetTop, 300); + // } else if (cellHeight > height) { + // $.scrollTo(cellHeight - height + scrollTop, 300); + // } + } + } else { + radioOrCheckboxClick(event); + } + }); +})(mui, window, document); +(function($, window) { + /** + * 警告消息框 + */ + $.alert = function(message, title, btnValue, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + title = null; + btnValue = '确定'; + } else if (typeof btnValue === 'function') { + callback = btnValue; + btnValue = null; + } + $.plusReady(function() { + plus.nativeUI.alert(message, callback, title, btnValue); + }); + } + + } else { + //TODO H5版本 + window.alert(message); + } + }; + +})(mui, window); +(function($, window) { + /** + * 确认消息框 + */ + $.confirm = function(message, title, btnArray, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + callback = btnArray; + btnArray = null; + } + $.plusReady(function() { + plus.nativeUI.confirm(message, callback, title, btnArray); + }); + } + + } else { + //H5版本,0为确认,1为取消 + if (window.confirm(message)) { + callback({ + index: 0 + }); + } else { + callback({ + index: 1 + }); + } + } + }; + +})(mui, window); +(function($, window) { + /** + * 输入对话框 + */ + $.prompt = function(text, defaultText, title, btnArray, callback) { + if ($.os.plus) { + if (typeof message === 'undefined') { + return; + } else { + + if (typeof defaultText === 'function') { + callback = defaultText; + defaultText = null; + title = null; + btnArray = null; + } else if (typeof title === 'function') { + callback = title; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + callback = btnArray; + btnArray = null; + } + $.plusReady(function() { + plus.nativeUI.prompt(text, callback, title, defaultText, btnArray); + }); + } + + } else { + //H5版本(确认index为0,取消index为1) + var result = window.prompt(text); + if (result) { + callback({ + index: 0, + value: result + }); + } else { + callback({ + index: 1, + value: '' + }); + } + } + }; + +})(mui, window); +(function($, window) { + var CLASS_ACTIVE = 'mui-active'; + /** + * 自动消失提示框 + */ + $.toast = function(message,options) { + var durations = { + 'long': 3500, + 'short': 2000 + }; + + //计算显示时间 + options = $.extend({ + duration: 'short' + }, options || {}); + + + if ($.os.plus && options.type !== 'div') { + //默认显示在底部; + $.plusReady(function() { + plus.nativeUI.toast(message, { + verticalAlign: 'bottom', + duration:options.duration + }); + }); + } else { + if (typeof options.duration === 'number') { + duration = options.duration>0 ? options.duration:durations['short']; + } else { + duration = durations[options.duration]; + } + if (!duration) { + duration = durations['short']; + } + var toast = document.createElement('div'); + toast.classList.add('mui-toast-container'); + toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>'; + toast.addEventListener('webkitTransitionEnd', function() { + if (!toast.classList.contains(CLASS_ACTIVE)) { + toast.parentNode.removeChild(toast); + toast = null; + } + }); + //点击则自动消失 + toast.addEventListener('click', function() { + toast.parentNode.removeChild(toast); + toast = null; + }); + document.body.appendChild(toast); + toast.offsetHeight; + toast.classList.add(CLASS_ACTIVE); + setTimeout(function() { + toast && toast.classList.remove(CLASS_ACTIVE); + }, duration); + + return { + isVisible: function() {return !!toast;} + } + } + }; + +})(mui, window); +/** + * Popup(alert,confirm,prompt) + * @param {Object} $ + * @param {Object} window + * @param {Object} document + */ +(function($, window, document) { + var CLASS_POPUP = 'mui-popup'; + var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; + var CLASS_POPUP_IN = 'mui-popup-in'; + var CLASS_POPUP_OUT = 'mui-popup-out'; + var CLASS_POPUP_INNER = 'mui-popup-inner'; + var CLASS_POPUP_TITLE = 'mui-popup-title'; + var CLASS_POPUP_TEXT = 'mui-popup-text'; + var CLASS_POPUP_INPUT = 'mui-popup-input'; + var CLASS_POPUP_BUTTONS = 'mui-popup-buttons'; + var CLASS_POPUP_BUTTON = 'mui-popup-button'; + var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold'; + var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop'; + var CLASS_ACTIVE = 'mui-active'; + + var popupStack = []; + var backdrop = (function() { + var element = document.createElement('div'); + element.classList.add(CLASS_POPUP_BACKDROP); + element.addEventListener($.EVENT_MOVE, $.preventDefault); + element.addEventListener('webkitTransitionEnd', function() { + if (!this.classList.contains(CLASS_ACTIVE)) { + element.parentNode && element.parentNode.removeChild(element); + } + }); + return element; + }()); + + var createInput = function(placeholder) { + return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>'; + }; + var createInner = function(message, title, extra) { + return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>'; + }; + var createButtons = function(btnArray) { + var length = btnArray.length; + var btns = []; + for (var i = 0; i < length; i++) { + btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>'); + } + return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>'; + }; + + var createPopup = function(html, callback) { + var popupElement = document.createElement('div'); + popupElement.className = CLASS_POPUP; + popupElement.innerHTML = html; + var removePopupElement = function() { + popupElement.parentNode && popupElement.parentNode.removeChild(popupElement); + popupElement = null; + }; + popupElement.addEventListener($.EVENT_MOVE, $.preventDefault); + popupElement.addEventListener('webkitTransitionEnd', function(e) { + if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) { + removePopupElement(); + } + }); + popupElement.style.display = 'block'; + document.body.appendChild(popupElement); + popupElement.offsetHeight; + popupElement.classList.add(CLASS_POPUP_IN); + + if (!backdrop.classList.contains(CLASS_ACTIVE)) { + backdrop.style.display = 'block'; + document.body.appendChild(backdrop); + backdrop.offsetHeight; + backdrop.classList.add(CLASS_ACTIVE); + } + var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement); + var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input'); + var popup = { + element: popupElement, + close: function(index, animate) { + if (popupElement) { + var result = callback && callback({ + index: index || 0, + value: input && input.value || '' + }); + if (result === false) { //返回false则不关闭当前popup + return; + } + if (animate !== false) { + popupElement.classList.remove(CLASS_POPUP_IN); + popupElement.classList.add(CLASS_POPUP_OUT); + } else { + removePopupElement(); + } + popupStack.pop(); + //如果还有其他popup,则不remove backdrop + if (popupStack.length) { + popupStack[popupStack.length - 1]['show'](animate); + } else { + backdrop.classList.remove(CLASS_ACTIVE); + } + } + } + }; + var handleEvent = function(e) { + popup.close(btns.indexOf(e.target)); + }; + $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent); + if (popupStack.length) { + popupStack[popupStack.length - 1]['hide'](); + } + popupStack.push({ + close: popup.close, + show: function(animate) { + popupElement.style.display = 'block'; + popupElement.offsetHeight; + popupElement.classList.add(CLASS_POPUP_IN); + }, + hide: function() { + popupElement.style.display = 'none'; + popupElement.classList.remove(CLASS_POPUP_IN); + } + }); + return popup; + }; + var createAlert = function(message, title, btnValue, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + type = btnValue; + title = null; + btnValue = null; + } else if (typeof btnValue === 'function') { + type = callback; + callback = btnValue; + btnValue = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback); + } + return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定'); + }; + var createConfirm = function(message, title, btnArray, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof title === 'function') { + callback = title; + type = btnArray; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + type = callback; + callback = btnArray; + btnArray = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback); + } + return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']); + }; + var createPrompt = function(message, placeholder, title, btnArray, callback, type) { + if (typeof message === 'undefined') { + return; + } else { + if (typeof placeholder === 'function') { + callback = placeholder; + type = title; + placeholder = null; + title = null; + btnArray = null; + } else if (typeof title === 'function') { + callback = title; + type = btnArray; + title = null; + btnArray = null; + } else if (typeof btnArray === 'function') { + type = callback; + callback = btnArray; + btnArray = null; + } + } + if (!$.os.plus || type === 'div') { + return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback); + } + return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']); + }; + var closePopup = function() { + if (popupStack.length) { + popupStack[popupStack.length - 1]['close'](); + return true; + } else { + return false; + } + }; + var closePopups = function() { + while (popupStack.length) { + popupStack[popupStack.length - 1]['close'](); + } + }; + + $.closePopup = closePopup; + $.closePopups = closePopups; + $.alert = createAlert; + $.confirm = createConfirm; + $.prompt = createPrompt; +})(mui, window, document); +(function($, document) { + var CLASS_PROGRESSBAR = 'mui-progressbar'; + var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in'; + var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out'; + var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite'; + + var SELECTOR_PROGRESSBAR = '.mui-progressbar'; + + var _findProgressbar = function(container) { + container = $(container || 'body'); + if (container.length === 0) return; + container = container[0]; + if (container.classList.contains(CLASS_PROGRESSBAR)) { + return container; + } + var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR); + if (progressbars) { + for (var i = 0, len = progressbars.length; i < len; i++) { + var progressbar = progressbars[i]; + if (progressbar.parentNode === container) { + return progressbar; + } + } + } + }; + /** + * 创建并显示进度条 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + * @param {Object} progress 可选,undefined表示循环,数字表示具体进度 + * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数) + */ + var showProgressbar = function(container, progress, color) { + if (typeof container === 'number') { + color = progress; + progress = container; + container = 'body'; + } + container = $(container || 'body'); + if (container.length === 0) return; + container = container[0]; + var progressbar; + if (container.classList.contains(CLASS_PROGRESSBAR)) { + progressbar = container; + } else { + var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')'); + if (progressbars) { + for (var i = 0, len = progressbars.length; i < len; i++) { + var _progressbar = progressbars[i]; + if (_progressbar.parentNode === container) { + progressbar = _progressbar; + break; + } + } + } + if (!progressbar) { + progressbar = document.createElement('span'); + progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : ''); + if (typeof progress !== 'undefined') { + progressbar.innerHTML = '<span></span>'; + } + container.appendChild(progressbar); + } else { + progressbar.classList.add(CLASS_PROGRESSBAR_IN); + } + } + if (progress) setProgressbar(container, progress); + return progressbar; + }; + /** + * 关闭进度条 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + */ + var hideProgressbar = function(container) { + var progressbar = _findProgressbar(container); + if (!progressbar) { + return; + } + var classList = progressbar.classList; + if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) { + return; + } + classList.remove(CLASS_PROGRESSBAR_IN); + classList.add(CLASS_PROGRESSBAR_OUT); + progressbar.addEventListener('webkitAnimationEnd', function() { + progressbar.parentNode && progressbar.parentNode.removeChild(progressbar); + progressbar = null; + }); + return; + }; + /** + * 设置指定进度条进度 + * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper + * @param {Object} progress 可选,默认0 取值范围[0-100] + * @param {Object} speed 进度条动画时间 + */ + var setProgressbar = function(container, progress, speed) { + if (typeof container === 'number') { + speed = progress; + progress = container; + container = false; + } + var progressbar = _findProgressbar(container); + if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) { + return; + } + if (progress) progress = Math.min(Math.max(progress, 0), 100); + progressbar.offsetHeight; + var span = progressbar.querySelector('span'); + if (span) { + var style = span.style; + style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)'; + if (typeof speed !== 'undefined') { + style.webkitTransitionDuration = speed + 'ms'; + } else { + style.webkitTransitionDuration = ''; + } + } + return progressbar; + }; + $.fn.progressbar = function(options) { + var progressbarApis = []; + options = options || {}; + this.each(function() { + var self = this; + var progressbarApi = self.mui_plugin_progressbar; + if (!progressbarApi) { + self.mui_plugin_progressbar = progressbarApi = { + options: options, + setOptions: function(options) { + this.options = options; + }, + show: function() { + return showProgressbar(self, this.options.progress, this.options.color); + }, + setProgress: function(progress) { + return setProgressbar(self, progress); + }, + hide: function() { + return hideProgressbar(self); + } + }; + } else if (options) { + progressbarApi.setOptions(options); + } + progressbarApis.push(progressbarApi); + }); + return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis; + }; + // $.setProgressbar = setProgressbar; + // $.showProgressbar = showProgressbar; + // $.hideProgressbar = hideProgressbar; +})(mui, document); +/** + * Input(TODO resize) + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + var CLASS_ICON = 'mui-icon'; + var CLASS_ICON_CLEAR = 'mui-icon-clear'; + var CLASS_ICON_SPEECH = 'mui-icon-speech'; + var CLASS_ICON_SEARCH = 'mui-icon-search'; + var CLASS_ICON_PASSWORD = 'mui-icon-eye'; + var CLASS_INPUT_ROW = 'mui-input-row'; + var CLASS_PLACEHOLDER = 'mui-placeholder'; + var CLASS_TOOLTIP = 'mui-tooltip'; + var CLASS_HIDDEN = 'mui-hidden'; + var CLASS_FOCUSIN = 'mui-focusin'; + var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR; + var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH; + var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD; + var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER; + var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP; + + var findRow = function(target) { + for (; target && target !== document; target = target.parentNode) { + if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) { + return target; + } + } + return null; + }; + var Input = function(element, options) { + this.element = element; + this.options = options || { + actions: 'clear' + }; + if (~this.options.actions.indexOf('slider')) { //slider + this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN; + this.sliderActionSelector = SELECTOR_TOOLTIP; + } else { //clear,speech,search + if (~this.options.actions.indexOf('clear')) { + this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN; + this.clearActionSelector = SELECTOR_ICON_CLOSE; + } + if (~this.options.actions.indexOf('speech')) { //only for 5+ + this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH; + this.speechActionSelector = SELECTOR_ICON_SPEECH; + } + if (~this.options.actions.indexOf('search')) { + this.searchActionClass = CLASS_PLACEHOLDER; + this.searchActionSelector = SELECTOR_PLACEHOLDER; + } + if (~this.options.actions.indexOf('password')) { + this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD; + this.passwordActionSelector = SELECTOR_ICON_PASSWORD; + } + } + this.init(); + }; + Input.prototype.init = function() { + this.initAction(); + this.initElementEvent(); + }; + Input.prototype.initAction = function() { + var self = this; + + var row = self.element.parentNode; + if (row) { + if (self.sliderActionClass) { + self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector); + } else { + if (self.searchActionClass) { + self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector); + self.searchAction.addEventListener('tap', function(e) { + $.focus(self.element); + e.stopPropagation(); + }); + } + if (self.speechActionClass) { + self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector); + self.speechAction.addEventListener('click', $.stopPropagation); + self.speechAction.addEventListener('tap', function(event) { + self.speechActionClick(event); + }); + } + if (self.clearActionClass) { + self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector); + self.clearAction.addEventListener('tap', function(event) { + self.clearActionClick(event); + }); + } + if (self.passwordActionClass) { + self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector); + self.passwordAction.addEventListener('tap', function(event) { + self.passwordActionClick(event); + }); + } + } + } + }; + Input.prototype.createAction = function(row, actionClass, actionSelector) { + var action = row.querySelector(actionSelector); + if (!action) { + var action = document.createElement('span'); + action.className = actionClass; + if (actionClass === this.searchActionClass) { + action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>'; + this.element.setAttribute('placeholder', ''); + if (this.element.value.trim()) { + row.classList.add('mui-active'); + } + } + row.insertBefore(action, this.element.nextSibling); + } + return action; + }; + Input.prototype.initElementEvent = function() { + var element = this.element; + + if (this.sliderActionClass) { + var tooltip = this.sliderAction; + var timer = null; + var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的 + tooltip.classList.remove(CLASS_HIDDEN); + var offsetLeft = element.offsetLeft; + var width = element.offsetWidth - 28; + var tooltipWidth = tooltip.offsetWidth; + var distince = Math.abs(element.max - element.min); + var scaleWidth = (width / distince) * Math.abs(element.value - element.min); + tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px'; + tooltip.innerText = element.value; + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(function() { + tooltip.classList.add(CLASS_HIDDEN); + }, 1000); + }; + element.addEventListener('input', showTip); + element.addEventListener('tap', showTip); + element.addEventListener($.EVENT_MOVE, function(e) { + e.stopPropagation(); + }); + } else { + if (this.clearActionClass) { + var action = this.clearAction; + if (!action) { + return; + } + $.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) { + (function(type) { + element.addEventListener(type, function() { + action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN); + }); + })(type); + }); + element.addEventListener('blur', function() { + action.classList.add(CLASS_HIDDEN); + }); + } + if (this.searchActionClass) { + element.addEventListener('focus', function() { + element.parentNode.classList.add('mui-active'); + }); + element.addEventListener('blur', function() { + if (!element.value.trim()) { + element.parentNode.classList.remove('mui-active'); + } + }); + } + } + }; + Input.prototype.setPlaceholder = function(text) { + if (this.searchActionClass) { + var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER); + placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text); + } else { + this.element.setAttribute('placeholder', text); + } + }; + Input.prototype.passwordActionClick = function(event) { + if (this.element.type === 'text') { + this.element.type = 'password'; + } else { + this.element.type = 'text'; + } + this.passwordAction.classList.toggle('mui-active'); + event.preventDefault(); + }; + Input.prototype.clearActionClick = function(event) { + var self = this; + self.element.value = ''; + $.focus(self.element); + self.clearAction.classList.add(CLASS_HIDDEN); + event.preventDefault(); + }; + Input.prototype.speechActionClick = function(event) { + if (window.plus) { + var self = this; + var oldValue = self.element.value; + self.element.value = ''; + document.body.classList.add(CLASS_FOCUSIN); + plus.speech.startRecognize({ + engine: 'iFly' + }, function(s) { + self.element.value += s; + $.focus(self.element); + plus.speech.stopRecognize(); + $.trigger(self.element, 'recognized', { + value: self.element.value + }); + if (oldValue !== self.element.value) { + $.trigger(self.element, 'change'); + $.trigger(self.element, 'input'); + } + // document.body.classList.remove(CLASS_FOCUSIN); + }, function(e) { + document.body.classList.remove(CLASS_FOCUSIN); + }); + } else { + alert('only for 5+'); + } + event.preventDefault(); + }; + $.fn.input = function(options) { + var inputApis = []; + this.each(function() { + var inputApi = null; + var actions = []; + var row = findRow(this.parentNode); + if (this.type === 'range' && row.classList.contains('mui-input-range')) { + actions.push('slider'); + } else { + var classList = this.classList; + if (classList.contains('mui-input-clear')) { + actions.push('clear'); + } + if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) { + actions.push('speech'); + } + if (classList.contains('mui-input-password')) { + actions.push('password'); + } + if (this.type === 'search' && row.classList.contains('mui-search')) { + actions.push('search'); + } + } + var id = this.getAttribute('data-input-' + actions[0]); + if (!id) { + id = ++$.uuid; + inputApi = $.data[id] = new Input(this, { + actions: actions.join(',') + }); + for (var i = 0, len = actions.length; i < len; i++) { + this.setAttribute('data-input-' + actions[i], id); + } + } else { + inputApi = $.data[id]; + } + inputApis.push(inputApi); + }); + return inputApis.length === 1 ? inputApis[0] : inputApis; + }; + $.ready(function() { + $('.mui-input-row input').input(); + }); +})(mui, window, document); +(function($, window) { + var CLASS_ACTIVE = 'mui-active'; + var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/; + var getColor = function(colorStr) { + var matches = colorStr.match(rgbaRegex); + if (matches && matches.length === 5) { + return [ + matches[1], + matches[2], + matches[3], + matches[4] + ]; + } + return []; + }; + var Transparent = function(element, options) { + this.element = element; + this.options = $.extend({ + top: 0, //距离顶部高度(到达该高度即触发) + offset: 150, //滚动透明距离 + duration: 16, //过渡时间 + scrollby: window//监听滚动距离容器 + }, options || {}); + + this.scrollByElem = this.options.scrollby || window; + if (!this.scrollByElem) { + throw new Error("监听滚动的元素不存在"); + } + this.isNativeScroll = false; + if (this.scrollByElem === window) { + this.isNativeScroll = true; + } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) { + this.isNativeScroll = true; + } + + this._style = this.element.style; + this._bgColor = this._style.backgroundColor; + var color = getColor(mui.getStyles(this.element, 'backgroundColor')); + if (color.length) { + this._R = color[0]; + this._G = color[1]; + this._B = color[2]; + this._A = parseFloat(color[3]); + this.lastOpacity = this._A; + this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this); + this.initEvent(); + } else { + throw new Error("元素背景颜色必须为RGBA"); + } + }; + + Transparent.prototype.initEvent = function() { + this.scrollByElem.addEventListener('scroll', this._bufferFn); + if (this.isNativeScroll) { //原生scroll + this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn); + } + } + Transparent.prototype.handleScroll = function(e) { + var y = window.scrollY; + if (!this.isNativeScroll && e && e.detail) { + y = -e.detail.y; + } + var opacity = (y - this.options.top) / this.options.offset + this._A; + opacity = Math.min(Math.max(this._A, opacity), 1); + this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')'; + if (opacity > this._A) { + this.element.classList.add(CLASS_ACTIVE); + } else { + this.element.classList.remove(CLASS_ACTIVE); + } + if (this.lastOpacity !== opacity) { + $.trigger(this.element, 'alpha', { + alpha: opacity + }); + this.lastOpacity = opacity; + } + }; + Transparent.prototype.destory = function() { + this.scrollByElem.removeEventListener('scroll', this._bufferFn); + this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn); + this.element.style.backgroundColor = this._bgColor; + this.element.mui_plugin_transparent = null; + }; + $.fn.transparent = function(options) { + options = options || {}; + var transparentApis = []; + this.each(function() { + var transparentApi = this.mui_plugin_transparent; + if (!transparentApi) { + var top = this.getAttribute('data-top'); + var offset = this.getAttribute('data-offset'); + var duration = this.getAttribute('data-duration'); + var scrollby = this.getAttribute('data-scrollby'); + if (top !== null && typeof options.top === 'undefined') { + options.top = top; + } + if (offset !== null && typeof options.offset === 'undefined') { + options.offset = offset; + } + if (duration !== null && typeof options.duration === 'undefined') { + options.duration = duration; + } + if (scrollby !== null && typeof options.scrollby === 'undefined') { + options.scrollby = document.querySelector(scrollby) || window; + } + transparentApi = this.mui_plugin_transparent = new Transparent(this, options); + } + transparentApis.push(transparentApi); + }); + return transparentApis.length === 1 ? transparentApis[0] : transparentApis; + }; + $.ready(function() { + $('.mui-bar-transparent').transparent(); + }); +})(mui, window); +/** + * 数字输入框 + * varstion 1.0.1 + * by Houfeng + * Houfeng@DCloud.io + */ + +(function($) { + + var touchSupport = ('ontouchstart' in document); + var tapEventName = touchSupport ? 'tap' : 'click'; + var changeEventName = 'change'; + var holderClassName = 'mui-numbox'; + var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus'; + var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus'; + var inputClassSelector = '.mui-input-numbox,.mui-numbox-input'; + + var Numbox = $.Numbox = $.Class.extend({ + /** + * 构造函数 + **/ + init: function(holder, options) { + var self = this; + if (!holder) { + throw "构造 numbox 时缺少容器元素"; + } + self.holder = holder; + options = options || {}; + options.step = parseInt(options.step || 1); + self.options = options; + self.input = $.qsa(inputClassSelector, self.holder)[0]; + self.plus = $.qsa(plusClassSelector, self.holder)[0]; + self.minus = $.qsa(minusClassSelector, self.holder)[0]; + self.checkValue(); + self.initEvent(); + }, + /** + * 初始化事件绑定 + **/ + initEvent: function() { + var self = this; + self.plus.addEventListener(tapEventName, function(event) { + var val = parseInt(self.input.value) + self.options.step; + self.input.value = val.toString(); + $.trigger(self.input, changeEventName, null); + }); + self.minus.addEventListener(tapEventName, function(event) { + var val = parseInt(self.input.value) - self.options.step; + self.input.value = val.toString(); + $.trigger(self.input, changeEventName, null); + }); + self.input.addEventListener(changeEventName, function(event) { + self.checkValue(); + var val = parseInt(self.input.value); + //触发顶层容器 + $.trigger(self.holder, changeEventName, { + value: val + }); + }); + }, + /** + * 获取当前值 + **/ + getValue: function() { + var self = this; + return parseInt(self.input.value); + }, + /** + * 验证当前值是法合法 + **/ + checkValue: function() { + var self = this; + var val = self.input.value; + if (val == null || val == '' || isNaN(val)) { + self.input.value = self.options.min || 0; + self.minus.disabled = self.options.min != null; + } else { + var val = parseInt(val); + if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) { + val = self.options.max; + self.plus.disabled = true; + } else { + self.plus.disabled = false; + } + if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) { + val = self.options.min; + self.minus.disabled = true; + } else { + self.minus.disabled = false; + } + self.input.value = val; + } + }, + /** + * 更新选项 + **/ + setOption: function(name, value) { + var self = this; + self.options[name] = value; + }, + /** + * 动态设置新值 + **/ + setValue: function(value) { + this.input.value = value; + this.checkValue(); + } + }); + + $.fn.numbox = function(options) { + var instanceArray = []; + //遍历选择的元素 + this.each(function(i, element) { + if (element.numbox) { + return; + } + if (options) { + element.numbox = new Numbox(element, options); + } else { + var optionsText = element.getAttribute('data-numbox-options'); + var options = optionsText ? JSON.parse(optionsText) : {}; + options.step = element.getAttribute('data-numbox-step') || options.step; + options.min = element.getAttribute('data-numbox-min') || options.min; + options.max = element.getAttribute('data-numbox-max') || options.max; + element.numbox = new Numbox(element, options); + } + }); + return this[0] ? this[0].numbox : null; + } + + //自动处理 class='mui-locker' 的 dom + $.ready(function() { + $('.' + holderClassName).numbox(); + }); + +}(mui)); +/** + * Button + * @param {type} $ + * @param {type} window + * @param {type} document + * @returns {undefined} + */ +(function($, window, document) { + var CLASS_ICON = 'mui-icon'; + var CLASS_DISABLED = 'mui-disabled'; + + var STATE_RESET = 'reset'; + var STATE_LOADING = 'loading'; + + var defaultOptions = { + loadingText: 'Loading...', //文案 + loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空 + loadingIconPosition: 'left' //图标所处位置,仅支持left|right + }; + + var Button = function(element, options) { + this.element = element; + this.options = $.extend({}, defaultOptions, options); + if (!this.options.loadingText) { + this.options.loadingText = defaultOptions.loadingText; + } + if (this.options.loadingIcon === null) { + this.options.loadingIcon = 'mui-spinner'; + if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') { + this.options.loadingIcon += ' ' + 'mui-spinner-white'; + } + } + this.isInput = this.element.tagName === 'INPUT'; + this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML; + this.state = ''; + }; + Button.prototype.loading = function() { + this.setState(STATE_LOADING); + }; + Button.prototype.reset = function() { + this.setState(STATE_RESET); + }; + Button.prototype.setState = function(state) { + if (this.state === state) { + return false; + } + this.state = state; + if (state === STATE_RESET) { + this.element.disabled = false; + this.element.classList.remove(CLASS_DISABLED); + this.setHtml(this.resetHTML); + } else if (state === STATE_LOADING) { + this.element.disabled = true; + this.element.classList.add(CLASS_DISABLED); + var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>'); + if (this.options.loadingIcon && !this.isInput) { + if (this.options.loadingIconPosition === 'right') { + html += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>'; + } else { + html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + html; + } + } + this.setHtml(html); + } + }; + Button.prototype.setHtml = function(html) { + if (this.isInput) { + this.element.value = html; + } else { + this.element.innerHTML = html; + } + } + $.fn.button = function(state) { + var buttonApis = []; + this.each(function() { + var buttonApi = this.mui_plugin_button; + if (!buttonApi) { + var loadingText = this.getAttribute('data-loading-text'); + var loadingIcon = this.getAttribute('data-loading-icon'); + var loadingIconPosition = this.getAttribute('data-loading-icon-position'); + this.mui_plugin_button = buttonApi = new Button(this, { + loadingText: loadingText, + loadingIcon: loadingIcon, + loadingIconPosition: loadingIconPosition + }); + } + if (state === STATE_LOADING || state === STATE_RESET) { + buttonApi.setState(state); + } + buttonApis.push(buttonApi); + }); + return buttonApis.length === 1 ? buttonApis[0] : buttonApis; + }; +})(mui, window, document); \ No newline at end of file diff --git a/static/app2/js/mui.min.js b/static/app2/js/mui.min.js new file mode 100755 index 0000000..bc87ee2 --- /dev/null +++ b/static/app2/js/mui.min.js @@ -0,0 +1,9 @@ +/*! + * ===================================================== + * Mui v3.7.2 (http://dev.dcloud.net.cn/mui) + * ===================================================== + */ +var mui=function(a,b){var c=/complete|loaded|interactive/,d=/^#([\w-]+)$/,e=/^\.([\w-]+)$/,f=/^[\w-]+$/,g=/translate(?:3d)?\((.+?)\)/,h=/matrix(3d)?\((.+?)\)/,i=function(b,c){if(c=c||a,!b)return j();if("object"==typeof b)return i.isArrayLike(b)?j(i.slice.call(b),null):j([b],null);if("function"==typeof b)return i.ready(b);if("string"==typeof b)try{if(b=b.trim(),d.test(b)){var e=a.getElementById(RegExp.$1);return j(e?[e]:[])}return j(i.qsa(b,c),b)}catch(f){}return j()},j=function(a,b){return a=a||[],Object.setPrototypeOf(a,i.fn),a.selector=b||"",a};i.uuid=0,i.data={},i.extend=function(){var a,c,d,e,f,g,h=arguments[0]||{},j=1,k=arguments.length,l=!1;for("boolean"==typeof h&&(l=h,h=arguments[j]||{},j++),"object"==typeof h||i.isFunction(h)||(h={}),j===k&&(h=this,j--);k>j;j++)if(null!=(a=arguments[j]))for(c in a)d=h[c],e=a[c],h!==e&&(l&&e&&(i.isPlainObject(e)||(f=i.isArray(e)))?(f?(f=!1,g=d&&i.isArray(d)?d:[]):g=d&&i.isPlainObject(d)?d:{},h[c]=i.extend(l,g,e)):e!==b&&(h[c]=e));return h},i.noop=function(){},i.slice=[].slice,i.filter=[].filter,i.type=function(a){return null==a?String(a):k[{}.toString.call(a)]||"object"},i.isArray=Array.isArray||function(a){return a instanceof Array},i.isArrayLike=function(a){var b=!!a&&"length"in a&&a.length,c=i.type(a);return"function"===c||i.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a},i.isWindow=function(a){return null!=a&&a===a.window},i.isObject=function(a){return"object"===i.type(a)},i.isPlainObject=function(a){return i.isObject(a)&&!i.isWindow(a)&&Object.getPrototypeOf(a)===Object.prototype},i.isEmptyObject=function(a){for(var c in a)if(c!==b)return!1;return!0},i.isFunction=function(a){return"function"===i.type(a)},i.qsa=function(b,c){return c=c||a,i.slice.call(e.test(b)?c.getElementsByClassName(RegExp.$1):f.test(b)?c.getElementsByTagName(b):c.querySelectorAll(b))},i.ready=function(b){return c.test(a.readyState)?b(i):a.addEventListener("DOMContentLoaded",function(){b(i)},!1),this},i.buffer=function(a,b,c){function d(){e&&(e.cancel(),e=0),f=i.now(),a.apply(c||this,arguments),g=i.now()}var e,f=0,g=0,b=b||150;return i.extend(function(){!f||g>=f&&i.now()-g>b||f>g&&i.now()-f>8*b?d.apply(this,arguments):(e&&e.cancel(),e=i.later(d,b,null,i.slice.call(arguments)))},{stop:function(){e&&(e.cancel(),e=0)}})},i.each=function(a,b,c){if(!a)return this;if("number"==typeof a.length)[].every.call(a,function(a,c){return b.call(a,c,a)!==!1});else for(var d in a)if(c){if(a.hasOwnProperty(d)&&b.call(a[d],d,a[d])===!1)return a}else if(b.call(a[d],d,a[d])===!1)return a;return this},i.focus=function(a){i.os.ios?setTimeout(function(){a.focus()},10):a.focus()},i.trigger=function(a,b,c){return a.dispatchEvent(new CustomEvent(b,{detail:c,bubbles:!0,cancelable:!0})),this},i.getStyles=function(a,b){var c=a.ownerDocument.defaultView.getComputedStyle(a,null);return b?c.getPropertyValue(b)||c[b]:c},i.parseTranslate=function(a,b){var c=a.match(g||"");return c&&c[1]||(c=["","0,0,0"]),c=c[1].split(","),c={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])},b&&c.hasOwnProperty(b)?c[b]:c},i.parseTranslateMatrix=function(a,b){var c=a.match(h),d=c&&c[1];c?(c=c[2].split(","),"3d"===d?c=c.slice(12,15):(c.push(0),c=c.slice(4,7))):c=[0,0,0];var e={x:parseFloat(c[0]),y:parseFloat(c[1]),z:parseFloat(c[2])};return b&&e.hasOwnProperty(b)?e[b]:e},i.hooks={},i.addAction=function(a,b){var c=i.hooks[a];return c||(c=[]),b.index=b.index||1e3,c.push(b),c.sort(function(a,b){return a.index-b.index}),i.hooks[a]=c,i.hooks[a]},i.doAction=function(a,b){i.isFunction(b)?i.each(i.hooks[a],b):i.each(i.hooks[a],function(a,b){return!b.handle()})},i.later=function(a,b,c,d){b=b||0;var e,f,g=a,h=d;return"string"==typeof a&&(g=c[a]),e=function(){g.apply(c,i.isArray(h)?h:[h])},f=setTimeout(e,b),{id:f,cancel:function(){clearTimeout(f)}}},i.now=Date.now||function(){return+new Date};var k={};return i.each(["Boolean","Number","String","Function","Array","Date","RegExp","Object","Error"],function(a,b){k["[object "+b+"]"]=b.toLowerCase()}),window.JSON&&(i.parseJSON=JSON.parse),i.fn={each:function(a){return[].every.call(this,function(b,c){return a.call(b,c,b)!==!1}),this}},"function"==typeof define&&define.amd&&define("mui",[],function(){return i}),i}(document);!function(a,b){function c(c){this.os={};var d=[function(){var a=c.match(/(MicroMessenger)\/([\d\.]+)/i);return a&&(this.os.wechat={version:a[2].replace(/_/g,".")}),!1},function(){var a=c.match(/(Android);?[\s\/]+([\d.]+)?/);return a&&(this.os.android=!0,this.os.version=a[2],this.os.isBadAndroid=!/Chrome\/\d/.test(b.navigator.appVersion)),this.os.android===!0},function(){var a=c.match(/(iPhone\sOS)\s([\d_]+)/);if(a)this.os.ios=this.os.iphone=!0,this.os.version=a[2].replace(/_/g,".");else{var b=c.match(/(iPad).*OS\s([\d_]+)/);b&&(this.os.ios=this.os.ipad=!0,this.os.version=b[2].replace(/_/g,"."))}return this.os.ios===!0}];[].every.call(d,function(b){return!b.call(a)})}c.call(a,navigator.userAgent)}(mui,window),function(a,b){function c(c){this.os=this.os||{};var d=c.match(/Html5Plus/i);d&&(this.os.plus=!0,a(function(){b.body.classList.add("mui-plus")}),c.match(/StreamApp/i)&&(this.os.stream=!0,a(function(){b.body.classList.add("mui-plus-stream")})))}c.call(a,navigator.userAgent)}(mui,document),function(a){"ontouchstart"in window?(a.isTouchable=!0,a.EVENT_START="touchstart",a.EVENT_MOVE="touchmove",a.EVENT_END="touchend"):(a.isTouchable=!1,a.EVENT_START="mousedown",a.EVENT_MOVE="mousemove",a.EVENT_END="mouseup"),a.EVENT_CANCEL="touchcancel",a.EVENT_CLICK="click";var b=1,c={},d={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"},e=function(){return!0},f=function(){return!1},g=function(b,c){return b.detail?b.detail.currentTarget=c:b.detail={currentTarget:c},a.each(d,function(a,c){var d=b[a];b[a]=function(){return this[c]=e,d&&d.apply(b,arguments)},b[c]=f},!0),b},h=function(a){return a&&(a._mid||(a._mid=b++))},i={},j=function(b,d,e,f){return function(e){for(var f=c[b._mid][d],h=[],i=e.target,j={};i&&i!==document&&i!==b&&(!~["click","tap","doubletap","longtap","hold"].indexOf(d)||!i.disabled&&!i.classList.contains("mui-disabled"));i=i.parentNode){var k={};a.each(f,function(c,d){j[c]||(j[c]=a.qsa(c,b)),j[c]&&~j[c].indexOf(i)&&(k[c]||(k[c]=d))},!0),a.isEmptyObject(k)||h.push({element:i,handlers:k})}j=null,e=g(e),a.each(h,function(b,c){i=c.element;var f=i.tagName;return"tap"===d&&"INPUT"!==f&&"TEXTAREA"!==f&&"SELECT"!==f&&(e.preventDefault(),e.detail&&e.detail.gesture&&e.detail.gesture.preventDefault()),a.each(c.handlers,function(b,c){a.each(c,function(a,b){b.call(i,e)===!1&&(e.preventDefault(),e.stopPropagation())},!0)},!0),e.isPropagationStopped()?!1:void 0},!0)}},k=function(a,b){var c=i[h(a)],d=[];if(c){if(d=[],b){var e=function(a){return a.type===b};return c.filter(e)}d=c}return d},l=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;a.fn.on=function(b,d,e){return this.each(function(){var f=this;h(f),h(e);var g=!1,k=c[f._mid]||(c[f._mid]={}),m=k[b]||(k[b]={});a.isEmptyObject(m)&&(g=!0);var n=m[d]||(m[d]=[]);if(n.push(e),g){var o=i[h(f)];o||(o=[]);var p=j(f,b,d,e);o.push(p),p.i=o.length-1,p.type=b,i[h(f)]=o,f.addEventListener(b,p),"tap"===b&&f.addEventListener("click",function(a){if(a.target){var b=a.target.tagName;if(!l.test(b))if("A"===b){var c=a.target.href;c&&~c.indexOf("tel:")||a.preventDefault()}else a.preventDefault()}})}})},a.fn.off=function(b,d,e){return this.each(function(){var f=h(this);if(b)if(d)if(e){var g=c[f]&&c[f][b]&&c[f][b][d];a.each(g,function(a,b){return h(b)===h(e)?(g.splice(a,1),!1):void 0},!0)}else c[f]&&c[f][b]&&delete c[f][b][d];else c[f]&&delete c[f][b];else c[f]&&delete c[f];c[f]?(!c[f][b]||a.isEmptyObject(c[f][b]))&&k(this,b).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this)):k(this).forEach(function(a){this.removeEventListener(a.type,a),delete i[f][a.i]}.bind(this))})}}(mui),function(a,b,c){a.targets={},a.targetHandles=[],a.registerTarget=function(b){return b.index=b.index||1e3,a.targetHandles.push(b),a.targetHandles.sort(function(a,b){return a.index-b.index}),a.targetHandles},b.addEventListener(a.EVENT_START,function(b){for(var d=b.target,e={};d&&d!==c;d=d.parentNode){var f=!1;if(a.each(a.targetHandles,function(c,g){var h=g.name;f||e[h]||!g.hasOwnProperty("handle")?e[h]||g.isReset!==!1&&(a.targets[h]=!1):(a.targets[h]=g.handle(b,d),a.targets[h]&&(e[h]=!0,g.isContinue!==!0&&(f=!0)))}),f)break}}),b.addEventListener("click",function(b){for(var d=b.target,e=!1;d&&d!==c&&("A"!==d.tagName||(a.each(a.targetHandles,function(a,c){c.name;return c.hasOwnProperty("handle")&&c.handle(b,d)?(e=!0,b.preventDefault(),!1):void 0}),!e));d=d.parentNode);})}(mui,window,document),function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),Object.setPrototypeOf=Object.setPrototypeOf||function(a,b){return a.__proto__=b,a}}(),function(){function a(a,b){b=b||{bubbles:!1,cancelable:!1,detail:void 0};var c=document.createEvent("Events"),d=!0;for(var e in b)"bubbles"===e?d=!!b[e]:c[e]=b[e];return c.initEvent(a,d,!0),c}"undefined"==typeof window.CustomEvent&&(a.prototype=window.Event.prototype,window.CustomEvent=a)}(),Function.prototype.bind=Function.prototype.bind||function(a){var b=Array.prototype.splice.call(arguments,1),c=this,d=function(){var e=b.concat(Array.prototype.splice.call(arguments,0));return this instanceof d?void c.apply(this,e):c.apply(a,e)};return d.prototype=c.prototype,d},function(a){"classList"in a.documentElement||!Object.defineProperty||"undefined"==typeof HTMLElement||Object.defineProperty(HTMLElement.prototype,"classList",{get:function(){function a(a){return function(c){var d=b.className.split(/\s+/),e=d.indexOf(c);a(d,e,c),b.className=d.join(" ")}}var b=this,c={add:a(function(a,b,c){~b||a.push(c)}),remove:a(function(a,b){~b&&a.splice(b,1)}),toggle:a(function(a,b,c){~b?a.splice(b,1):a.push(c)}),contains:function(a){return!!~b.className.split(/\s+/).indexOf(a)},item:function(a){return b.className.split(/\s+/)[a]||null}};return Object.defineProperty(c,"length",{get:function(){return b.className.split(/\s+/).length}}),c}})}(document),function(a){if(!a.requestAnimationFrame){var b=0;a.requestAnimationFrame=a.webkitRequestAnimationFrame||function(c,d){var e=(new Date).getTime(),f=Math.max(0,16.7-(e-b)),g=a.setTimeout(function(){c(e+f)},f);return b=e+f,g},a.cancelAnimationFrame=a.webkitCancelAnimationFrame||a.webkitCancelRequestAnimationFrame||function(a){clearTimeout(a)}}}(window),function(a,b,c){if((a.os.android||a.os.ios)&&!b.FastClick){var d=function(a,b){return"LABEL"===b.tagName&&b.parentNode&&(b=b.parentNode.querySelector("input")),!b||"radio"!==b.type&&"checkbox"!==b.type||b.disabled?!1:b};a.registerTarget({name:c,index:40,handle:d,target:!1});var e=function(c){var d=a.targets.click;if(d){var e,f;document.activeElement&&document.activeElement!==d&&document.activeElement.blur(),f=c.detail.gesture.changedTouches[0],e=document.createEvent("MouseEvents"),e.initMouseEvent("click",!0,!0,b,1,f.screenX,f.screenY,f.clientX,f.clientY,!1,!1,!1,!1,0,null),e.forwardedTouchEvent=!0,d.dispatchEvent(e),c.detail&&c.detail.gesture.preventDefault()}};b.addEventListener("tap",e),b.addEventListener("doubletap",e),b.addEventListener("click",function(b){return a.targets.click&&!b.forwardedTouchEvent?(b.stopImmediatePropagation?b.stopImmediatePropagation():b.propagationStopped=!0,b.stopPropagation(),b.preventDefault(),!1):void 0},!0)}}(mui,window,"click"),function(a,b){a(function(){if(a.os.ios){var c="mui-focusin",d="mui-bar-tab",e="mui-bar-footer",f="mui-bar-footer-secondary",g="mui-bar-footer-secondary-tab";b.addEventListener("focusin",function(h){if(!(a.os.plus&&window.plus&&plus.webview.currentWebview().children().length>0)){var i=h.target;if(i.tagName&&("TEXTAREA"===i.tagName||"INPUT"===i.tagName&&("text"===i.type||"search"===i.type||"number"===i.type))){if(i.disabled||i.readOnly)return;b.body.classList.add(c);for(var j=!1;i&&i!==b;i=i.parentNode){var k=i.classList;if(k&&k.contains(d)||k.contains(e)||k.contains(f)||k.contains(g)){j=!0;break}}if(j){var l=b.body.scrollHeight,m=b.body.scrollLeft;setTimeout(function(){window.scrollTo(m,l)},20)}}}}),b.addEventListener("focusout",function(a){var d=b.body.classList;d.contains(c)&&(d.remove(c),setTimeout(function(){window.scrollTo(b.body.scrollLeft,b.body.scrollTop)},20))})}})}(mui,document),function(a){a.namespace="mui",a.classNamePrefix=a.namespace+"-",a.classSelectorPrefix="."+a.classNamePrefix,a.className=function(b){return a.classNamePrefix+b},a.classSelector=function(b){return b.replace(/\./g,a.classSelectorPrefix)},a.eventName=function(b,c){return b+(a.namespace?"."+a.namespace:"")+(c?"."+c:"")}}(mui),function(a,b){a.gestures={session:{}},a.preventDefault=function(a){a.preventDefault()},a.stopPropagation=function(a){a.stopPropagation()},a.addGesture=function(b){return a.addAction("gestures",b)};var c=Math.round,d=Math.abs,e=Math.sqrt,f=(Math.atan,Math.atan2),g=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],f=b[c[1]]-a[c[1]];return e(d*d+f*f)},h=function(a,b){if(a.length>=2&&b.length>=2){var c=["pageX","pageY"];return g(b[1],b[0],c)/g(a[1],a[0],c)}return 1},i=function(a,b,c){c||(c=["x","y"]);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*f(e,d)/Math.PI},j=function(a,b){return a===b?"":d(a)>=d(b)?a>0?"left":"right":b>0?"up":"down"},k=function(a,b){var c=["pageX","pageY"];return i(b[1],b[0],c)-i(a[1],a[0],c)},l=function(a,b,c){return{x:b/a||0,y:c/a||0}},m=function(b,c){a.gestures.stoped||a.doAction("gestures",function(d,e){a.gestures.stoped||a.options.gestureConfig[e.name]!==!1&&e.handle(b,c)})},n=function(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1},o=function(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];e.indexOf(g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d},p=function(a){var b=a.length;if(1===b)return{x:c(a[0].pageX),y:c(a[0].pageY)};for(var d=0,e=0,f=0;b>f;)d+=a[f].pageX,e+=a[f].pageY,f++;return{x:c(d/b),y:c(e/b)}},q=function(){return a.options.gestureConfig.pinch},r=function(b){for(var d=[],e=0;e<b.touches.length;)d[e]={pageX:c(b.touches[e].pageX),pageY:c(b.touches[e].pageY)},e++;return{timestamp:a.now(),gesture:b.gesture,touches:d,center:p(b.touches),deltaX:b.deltaX,deltaY:b.deltaY}},s=function(b){var c=a.gestures.session,d=b.center,e=c.offsetDelta||{},f=c.prevDelta||{},g=c.prevTouch||{};(b.gesture.type===a.EVENT_START||b.gesture.type===a.EVENT_END)&&(f=c.prevDelta={x:g.deltaX||0,y:g.deltaY||0},e=c.offsetDelta={x:d.x,y:d.y}),b.deltaX=f.x+(d.x-e.x),b.deltaY=f.y+(d.y-e.y)},t=function(b){var c=a.gestures.session,d=b.touches,e=d.length;c.firstTouch||(c.firstTouch=r(b)),q()&&e>1&&!c.firstMultiTouch?c.firstMultiTouch=r(b):1===e&&(c.firstMultiTouch=!1);var f=c.firstTouch,l=c.firstMultiTouch,m=l?l.center:f.center,n=b.center=p(d);b.timestamp=a.now(),b.deltaTime=b.timestamp-f.timestamp,b.angle=i(m,n),b.distance=g(m,n),s(b),b.offsetDirection=j(b.deltaX,b.deltaY),b.scale=l?h(l.touches,d):1,b.rotation=l?k(l.touches,d):0,v(b)},u=25,v=function(b){var c,e,f,g,h=a.gestures.session,i=h.lastInterval||b,k=b.timestamp-i.timestamp;if(b.gesture.type!=a.EVENT_CANCEL&&(k>u||void 0===i.velocity)){var m=i.deltaX-b.deltaX,n=i.deltaY-b.deltaY,o=l(k,m,n);e=o.x,f=o.y,c=d(o.x)>d(o.y)?o.x:o.y,g=j(m,n)||i.direction,h.lastInterval=b}else c=i.velocity,e=i.velocityX,f=i.velocityY,g=i.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g},w={},x=function(a){for(var b=0;b<a.length;b++)!a.identifier&&(a.identifier=0);return a},y=function(b,c){var d=x(a.slice.call(b.touches||[b])),e=b.type,f=[],g=[];if(e!==a.EVENT_START&&e!==a.EVENT_MOVE||1!==d.length){var h=0,f=[],g=[],i=x(a.slice.call(b.changedTouches||[b]));c.target=b.target;var j=a.gestures.session.target||b.target;if(f=d.filter(function(a){return n(a.target,j)}),e===a.EVENT_START)for(h=0;h<f.length;)w[f[h].identifier]=!0,h++;for(h=0;h<i.length;)w[i[h].identifier]&&g.push(i[h]),(e===a.EVENT_END||e===a.EVENT_CANCEL)&&delete w[i[h].identifier],h++;if(!g.length)return!1}else w[d[0].identifier]=!0,f=d,g=d,c.target=b.target;f=o(f.concat(g),"identifier",!0);var k=f.length,l=g.length;return e===a.EVENT_START&&k-l===0&&(c.isFirst=!0,a.gestures.touch=a.gestures.session={target:b.target}),c.isFinal=(e===a.EVENT_END||e===a.EVENT_CANCEL)&&k-l===0,c.touches=f,c.changedTouches=g,!0},z=function(b){var c={gesture:b},d=y(b,c);d&&(t(c),m(b,c),a.gestures.session.prevTouch=c,b.type!==a.EVENT_END||a.isTouchable||(a.gestures.touch=a.gestures.session={}))},A=function(){var a=!1;try{var c=Object.defineProperty({},"passive",{get:function(){a=!0}});b.addEventListener("testPassiveListener",null,c)}catch(d){}return a}();b.addEventListener(a.EVENT_START,z),b.addEventListener(a.EVENT_MOVE,z,A?{passive:!1,capture:!1}:!1),b.addEventListener(a.EVENT_END,z),b.addEventListener(a.EVENT_CANCEL,z),b.addEventListener(a.EVENT_CLICK,function(b){(a.os.android||a.os.ios)&&(a.targets.popover&&b.target===a.targets.popover||a.targets.tab||a.targets.offcanvas||a.targets.modal)&&b.preventDefault()},!0),a.isScrolling=!1;var B=null;b.addEventListener("scroll",function(){a.isScrolling=!0,B&&clearTimeout(B),B=setTimeout(function(){a.isScrolling=!1},250)})}(mui,window),function(a,b){var c=0,d=function(d,e){var f=a.gestures.session,g=this.options,h=a.now();switch(d.type){case a.EVENT_MOVE:h-c>300&&(c=h,f.flickStart=e.center);break;case a.EVENT_END:case a.EVENT_CANCEL:e.flick=!1,f.flickStart&&g.flickMaxTime>h-c&&e.distance>g.flickMinDistince&&(e.flick=!0,e.flickTime=h-c,e.flickDistanceX=e.center.x-f.flickStart.x,e.flickDistanceY=e.center.y-f.flickStart.y,a.trigger(f.target,b,e),a.trigger(f.target,b+e.direction,e))}};a.addGesture({name:b,index:5,handle:d,options:{flickMaxTime:200,flickMinDistince:10}})}(mui,"flick"),function(a,b){var c=function(c,d){var e=a.gestures.session;if(c.type===a.EVENT_END||c.type===a.EVENT_CANCEL){var f=this.options;d.swipe=!1,d.direction&&f.swipeMaxTime>d.deltaTime&&d.distance>f.swipeMinDistince&&(d.swipe=!0,a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d))}};a.addGesture({name:b,index:10,handle:c,options:{swipeMaxTime:300,swipeMinDistince:18}})}(mui,"swipe"),function(a,b){var c=function(c,d){var e=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(!d.direction||!e.target)return;e.lockDirection&&e.startDirection&&e.startDirection&&e.startDirection!==d.direction&&("up"===e.startDirection||"down"===e.startDirection?d.direction=d.deltaY<0?"up":"down":d.direction=d.deltaX<0?"left":"right"),e.drag||(e.drag=!0,a.trigger(e.target,b+"start",d)),a.trigger(e.target,b,d),a.trigger(e.target,b+d.direction,d);break;case a.EVENT_END:case a.EVENT_CANCEL:e.drag&&d.isFinal&&a.trigger(e.target,b+"end",d)}};a.addGesture({name:b,index:20,handle:c,options:{fingers:1}})}(mui,"drag"),function(a,b){var c,d,e=function(e,f){var g=a.gestures.session,h=this.options;switch(e.type){case a.EVENT_END:if(!f.isFinal)return;var i=g.target;if(!i||i.disabled||i.classList&&i.classList.contains("mui-disabled"))return;if(f.distance<h.tapMaxDistance&&f.deltaTime<h.tapMaxTime){if(a.options.gestureConfig.doubletap&&c&&c===i&&d&&f.timestamp-d<h.tapMaxInterval)return a.trigger(i,"doubletap",f),d=a.now(),void(c=i);a.trigger(i,b,f),d=a.now(),c=i}}};a.addGesture({name:b,index:30,handle:e,options:{fingers:1,tapMaxInterval:300,tapMaxDistance:5,tapMaxTime:250}})}(mui,"tap"),function(a,b){var c,d=function(d,e){var f=a.gestures.session,g=this.options;switch(d.type){case a.EVENT_START:clearTimeout(c),c=setTimeout(function(){a.trigger(f.target,b,e)},g.holdTimeout);break;case a.EVENT_MOVE:e.distance>g.holdThreshold&&clearTimeout(c);break;case a.EVENT_END:case a.EVENT_CANCEL:clearTimeout(c)}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:500,holdThreshold:2}})}(mui,"longtap"),function(a,b){var c,d=function(d,e){var f=a.gestures.session,g=this.options;switch(d.type){case a.EVENT_START:a.options.gestureConfig.hold&&(c&&clearTimeout(c),c=setTimeout(function(){e.hold=!0,a.trigger(f.target,b,e)},g.holdTimeout));break;case a.EVENT_MOVE:break;case a.EVENT_END:case a.EVENT_CANCEL:c&&(clearTimeout(c)&&(c=null),a.trigger(f.target,"release",e))}};a.addGesture({name:b,index:10,handle:d,options:{fingers:1,holdTimeout:0}})}(mui,"hold"),function(a,b){var c=function(c,d){var e=this.options,f=a.gestures.session;switch(c.type){case a.EVENT_START:break;case a.EVENT_MOVE:if(a.options.gestureConfig.pinch){if(d.touches.length<2)return;f.pinch||(f.pinch=!0,a.trigger(f.target,b+"start",d)),a.trigger(f.target,b,d);var g=d.scale,h=d.rotation,i="undefined"==typeof d.lastScale?1:d.lastScale,j=1e-12;g>i?(i=g-j,a.trigger(f.target,b+"out",d)):i>g&&(i=g+j,a.trigger(f.target,b+"in",d)),Math.abs(h)>e.minRotationAngle&&a.trigger(f.target,"rotate",d)}break;case a.EVENT_END:case a.EVENT_CANCEL:a.options.gestureConfig.pinch&&f.pinch&&2===d.touches.length&&(f.pinch=!1,a.trigger(f.target,b+"end",d))}};a.addGesture({name:b,index:10,handle:c,options:{minRotationAngle:0}})}(mui,"pinch"),function(a){function b(a,b){var c="MUI_SCROLL_POSITION_"+document.location.href+"_"+b.src,d=parseFloat(localStorage.getItem(c))||0;d&&!function(a){b.onload=function(){window.scrollTo(0,a)}}(d),setInterval(function(){var a=window.scrollY;d!==a&&(localStorage.setItem(c,a+""),d=a)},100)}a.global=a.options={gestureConfig:{tap:!0,doubletap:!1,longtap:!1,hold:!1,flick:!0,swipe:!0,drag:!0,pinch:!1}},a.initGlobal=function(b){return a.options=a.extend(!0,a.global,b),this};var c={};a.init=function(b){return a.options=a.extend(!0,a.global,b||{}),a.ready(function(){a.doAction("inits",function(b,d){var e=!(c[d.name]&&!d.repeat);e&&(d.handle.call(a),c[d.name]=!0)})}),this},a.addInit=function(b){return a.addAction("inits",b)},a.addInit({name:"iframe",index:100,handle:function(){var b=a.options,c=b.subpages||[];!a.os.plus&&c.length&&d(c[0])}});var d=function(c){var d=document.createElement("div");d.className="mui-iframe-wrapper";var e=c.styles||{};"string"!=typeof e.top&&(e.top="0px"),"string"!=typeof e.bottom&&(e.bottom="0px"),d.style.top=e.top,d.style.bottom=e.bottom;var f=document.createElement("iframe");f.src=c.url,f.id=c.id||c.url,f.name=f.id,d.appendChild(f),document.body.appendChild(d),a.os.wechat&&b(d,f)};a(function(){var b=document.body.classList,c=[];a.os.ios?(c.push({os:"ios",version:a.os.version}),b.add("mui-ios")):a.os.android&&(c.push({os:"android",version:a.os.version}),b.add("mui-android")),a.os.wechat&&(c.push({os:"wechat",version:a.os.wechat.version}),b.add("mui-wechat")),c.length&&a.each(c,function(c,d){var e="";d.version&&a.each(d.version.split("."),function(c,f){e=e+(e?"-":"")+f,b.add(a.className(d.os+"-"+e))})})})}(mui),function(a){var b={swipeBack:!1,preloadPages:[],preloadLimit:10,keyEventBind:{backbutton:!0,menubutton:!0},titleConfig:{height:"44px",backgroundColor:"#f7f7f7",bottomBorderColor:"#cccccc",title:{text:"",position:{top:0,left:0,width:"100%",height:"100%"},styles:{color:"#000000",align:"center",family:"'Helvetica Neue',Helvetica,sans-serif",size:"17px",style:"normal",weight:"normal",fontSrc:""}},back:{image:{base64Data:"",imgSrc:"",sprite:{top:"0px",left:"0px",width:"100%",height:"100%"},position:{top:"10px",left:"10px",width:"24px",height:"24px"}}}}},c={event:"titleUpdate",autoShow:!0,duration:300,aniShow:"slide-in-right",extras:{}};a.options.show&&(c=a.extend(!0,c,a.options.show)),a.currentWebview=null,a.extend(!0,a.global,b),a.extend(!0,a.options,b),a.waitingOptions=function(b){return a.extend(!0,{},{autoShow:!0,title:"",modal:!1},b)},a.showOptions=function(b){return a.extend(!0,{},c,b)},a.windowOptions=function(b){return a.extend({scalable:!1,bounce:""},b)},a.plusReady=function(a){return window.plus?setTimeout(function(){a()},0):document.addEventListener("plusready",function(){a()},!1),this},a.fire=function(b,c,d){if(b){if("undefined"==typeof d)d="";else{if("boolean"==typeof d||"number"==typeof d)return void b.evalJS("typeof mui!=='undefined'&&mui.receive('"+c+"',"+d+")");(a.isPlainObject(d)||a.isArray(d))&&(d=JSON.stringify(d||{}).replace(/\'/g,"\\u0027").replace(/\\/g,"\\u005c"))}b.evalJS("typeof mui!=='undefined'&&mui.receive('"+c+"','"+d+"')")}},a.receive=function(b,c){if(b){try{c&&"string"==typeof c&&(c=JSON.parse(c))}catch(d){}a.trigger(document,b,c)}};var d=function(b){if(!b.preloaded){a.fire(b,"preload");for(var c=b.children(),d=0;d<c.length;d++)a.fire(c[d],"preload");b.preloaded=!0}},e=function(b,c,d){if(d){if(!b[c+"ed"]){a.fire(b,c);for(var e=b.children(),f=0;f<e.length;f++)a.fire(e[f],c);b[c+"ed"]=!0}}else{a.fire(b,c);for(var e=b.children(),f=0;f<e.length;f++)a.fire(e[f],c)}};a.openWindow=function(b,f,g){if("object"==typeof b?(g=b,b=g.url,f=g.id||b):"object"==typeof f?(g=f,f=g.id||b):f=f||b,!a.os.plus)return void(a.os.ios||a.os.android?window.top.location.href=b:window.parent.location.href=b);if(window.plus){g=g||{};var h,i,j=g.params||{},k=null,l=null;if(a.webviews[f]?(l=a.webviews[f],plus.webview.getWebviewById(f)&&(k=l.webview)):g.createNew!==!0&&(k=plus.webview.getWebviewById(f)),k)return h=l?l.show:c,h=g.show?a.extend(h,g.show):h,h.autoShow&&k.show(h.aniShow,h.duration,function(){d(k),e(k,"pagebeforeshow",!1)}),l&&l.afterShowMethodName&&k.evalJS(l.afterShowMethodName+"('"+JSON.stringify(j)+"')"),k;if(!b)throw new Error("webview["+f+"] does not exist");var m=a.waitingOptions(g.waiting);if(m.autoShow&&(i=plus.nativeUI.showWaiting(m.title,m.options)),g=a.extend(g,{id:f,url:b}),k=a.createWindow(g),h=a.showOptions(g.show),h.autoShow){var n=function(){i&&i.close(),k.show(h.aniShow,h.duration,function(){},h.extras),g.afterShowMethodName&&k.evalJS(g.afterShowMethodName+"('"+JSON.stringify(j)+"')")};k.addEventListener(h.event,n,!1),k.addEventListener("loaded",function(){d(k),e(k,"pagebeforeshow",!1)},!1)}return k}},a.openWindowWithTitle=function(b,f){b=b||{};var g=b.url,h=b.id||g;if(!a.os.plus)return void(a.os.ios||a.os.android?window.top.location.href=g:window.parent.location.href=g);if(window.plus){var i,j,k=b.params||{},l=null,m=null;if(a.webviews[h]?(m=a.webviews[h],plus.webview.getWebviewById(h)&&(l=m.webview)):b.createNew!==!0&&(l=plus.webview.getWebviewById(h)),l)return i=m?m.show:c,i=b.show?a.extend(i,b.show):i,i.autoShow&&l.show(i.aniShow,i.duration,function(){d(l),e(l,"pagebeforeshow",!1)}),m&&m.afterShowMethodName&&l.evalJS(m.afterShowMethodName+"('"+JSON.stringify(k)+"')"),l;if(!g)throw new Error("webview["+h+"] does not exist");var n=a.waitingOptions(b.waiting);if(n.autoShow&&(j=plus.nativeUI.showWaiting(n.title,n.options)),b=a.extend(b,{id:h,url:g}),l=a.createWindow(b),f){a.extend(!0,a.options.titleConfig,f);var o=a.options.titleConfig.id?a.options.titleConfig.id:h+"_title",p=new plus.nativeObj.View(o,{top:0,height:a.options.titleConfig.height,width:"100%",dock:"top",position:"dock"});p.drawRect(a.options.titleConfig.backgroundColor);var q=parseInt(a.options.titleConfig.height)-1;if(p.drawRect(a.options.titleConfig.bottomBorderColor,{top:q+"px",left:"0px"}),a.options.titleConfig.title.text){var r=a.options.titleConfig.title;p.drawText(r.text,r.position,r.styles)}var s=a.options.titleConfig.back,t=null,u=s.image;if(u.base64Data||u.imgSrc){t={left:parseInt(u.position.left),right:parseInt(u.position.left)+parseInt(u.position.width)};var v=new plus.nativeObj.Bitmap(h+"_back");u.base64Data?v.loadBase64Data(u.base64Data):v.load(u.imgSrc),p.drawBitmap(v,u.sprite,u.position)}p.setTouchEventRect({top:"0px",left:"0px",width:"100%",height:"100%"}),p.interceptTouchEvent(!0),p.addEventListener("click",function(b){var c=b.clientX;t&&c>t.left&&c<t.right&&(s.click&&a.isFunction(s.click)?s.click():l.evalJS("window.mui&&mui.back();"))},!1),l.append(p)}return i=a.showOptions(b.show),i.autoShow&&l.addEventListener(i.event,function(){j&&j.close(),l.show(i.aniShow,i.duration,function(){},i.extras)},!1),l}},a.createWindow=function(b,c){if(window.plus){var d,e=b.id||b.url;if(b.preload){a.webviews[e]&&a.webviews[e].webview.getURL()?d=a.webviews[e].webview:(b.createNew!==!0&&(d=plus.webview.getWebviewById(e)),d||(d=plus.webview.create(b.url,e,a.windowOptions(b.styles),a.extend({preload:!0},b.extras)),b.subpages&&a.each(b.subpages,function(b,c){var e=c.id||c.url;if(e){var f=plus.webview.getWebviewById(e);f||(f=plus.webview.create(c.url,e,a.windowOptions(c.styles),a.extend({preload:!0},c.extras))),d.append(f)}}))),a.webviews[e]={webview:d,preload:!0,show:a.showOptions(b.show),afterShowMethodName:b.afterShowMethodName};var f=a.data.preloads,g=f.indexOf(e);if(~g&&f.splice(g,1),f.push(e),f.length>a.options.preloadLimit){var h=a.data.preloads.shift(),i=a.webviews[h];i&&i.webview&&a.closeAll(i.webview),delete a.webviews[h]}}else c!==!1&&(d=plus.webview.create(b.url,e,a.windowOptions(b.styles),b.extras),b.subpages&&a.each(b.subpages,function(b,c){var e=c.id||c.url,f=plus.webview.getWebviewById(e);f||(f=plus.webview.create(c.url,e,a.windowOptions(c.styles),c.extras)),d.append(f)}));return d}},a.preload=function(b){return b.preload||(b.preload=!0),a.createWindow(b)},a.closeOpened=function(b){var c=b.opened();if(c)for(var d=0,e=c.length;e>d;d++){var f=c[d],g=f.opened();g&&g.length>0?(a.closeOpened(f),f.close("none")):f.parent()!==b&&f.close("none")}},a.closeAll=function(b,c){a.closeOpened(b),c?b.close(c):b.close()},a.createWindows=function(b){a.each(b,function(b,c){a.createWindow(c,!1)})},a.appendWebview=function(b){if(window.plus){var c,d=b.id||b.url;return a.webviews[d]||(plus.webview.getWebviewById(d)||(c=plus.webview.create(b.url,d,b.styles,b.extras)),plus.webview.currentWebview().append(c),a.webviews[d]=b),c}},a.webviews={},a.data.preloads=[],a.plusReady(function(){a.currentWebview=plus.webview.currentWebview()}),a.addInit({name:"5+",index:100,handle:function(){var b=a.options,c=b.subpages||[];a.os.plus&&a.plusReady(function(){a.each(c,function(b,c){a.appendWebview(c)}),plus.webview.currentWebview()===plus.webview.getWebviewById(plus.runtime.appid)&&setTimeout(function(){d(plus.webview.currentWebview())},300),a.os.ios&&a.options.statusBarBackground&&plus.navigator.setStatusBarBackground(a.options.statusBarBackground),a.os.android&&parseFloat(a.os.version)<4.4&&null==plus.webview.currentWebview().parent()&&document.addEventListener("resume",function(){var a=document.body;a.style.display="none",setTimeout(function(){a.style.display=""},10)})})}}),window.addEventListener("preload",function(){var b=a.options.preloadPages||[];a.plusReady(function(){a.each(b,function(b,c){a.createWindow(a.extend(c,{preload:!0}))})})}),a.supportStatusbarOffset=function(){return a.os.plus&&a.os.ios&&parseFloat(a.os.version)>=7},a.ready(function(){a.supportStatusbarOffset()&&document.body.classList.add("mui-statusbar")})}(mui),function(a,b){a.addBack=function(b){return a.addAction("backs",b)},a.addBack({name:"browser",index:100,handle:function(){return b.history.length>1?(b.history.back(),!0):!1}}),a.back=function(){("function"!=typeof a.options.beforeback||a.options.beforeback()!==!1)&&a.doAction("backs")},b.addEventListener("tap",function(b){var c=a.targets.action;c&&c.classList.contains("mui-action-back")&&(a.back(),a.targets.action=!1)}),b.addEventListener("swiperight",function(b){var c=b.detail;a.options.swipeBack===!0&&Math.abs(c.angle)<3&&a.back()})}(mui,window),function(a,b){a.os.plus&&a.os.android&&a.addBack({name:"mui",index:5,handle:function(){if(a.targets._popover&&a.targets._popover.classList.contains("mui-active"))return a(a.targets._popover).popover("hide"),!0;var b=document.querySelector(".mui-off-canvas-wrap.mui-active");if(b)return a(b).offCanvas("close"),!0;var c=a.isFunction(a.getPreviewImage)&&a.getPreviewImage();return c&&c.isShown()?(c.close(),!0):a.closePopup()}}),a.__back__first=null,a.addBack({name:"5+",index:10,handle:function(){if(!b.plus)return!1;var c=plus.webview.currentWebview(),d=c.parent();return d?d.evalJS("mui&&mui.back();"):c.canBack(function(d){d.canBack?b.history.back():c.id===plus.runtime.appid?a.__back__first?(new Date).getTime()-a.__back__first<2e3&&plus.runtime.quit():(a.__back__first=(new Date).getTime(),mui.toast("再按一次退出应用"),setTimeout(function(){a.__back__first=null},2e3)):c.preload?c.hide("auto"):a.closeAll(c); +}),!0}}),a.menu=function(){var c=document.querySelector(".mui-action-menu");if(c)a.trigger(c,a.EVENT_START),a.trigger(c,"tap");else if(b.plus){var d=a.currentWebview,e=d.parent();e&&e.evalJS("mui&&mui.menu();")}};var c=function(){a.back()},d=function(){a.menu()};a.plusReady(function(){a.options.keyEventBind.backbutton&&plus.key.addEventListener("backbutton",c,!1),a.options.keyEventBind.menubutton&&plus.key.addEventListener("menubutton",d,!1)}),a.addInit({name:"keyEventBind",index:1e3,handle:function(){a.plusReady(function(){a.options.keyEventBind.backbutton||plus.key.removeEventListener("backbutton",c),a.options.keyEventBind.menubutton||plus.key.removeEventListener("menubutton",d)})}})}(mui,window),function(a){a.addInit({name:"pullrefresh",index:1e3,handle:function(){var b=a.options,c=b.pullRefresh||{},d=c.down&&c.down.hasOwnProperty("callback"),e=c.up&&c.up.hasOwnProperty("callback");if(d||e){var f=c.container;if(f){var g=a(f);1===g.length&&(a.os.plus?d&&"circle"==c.down.style?a.plusReady(function(){a.fn.pullRefresh=a.fn.pullRefresh_native,g.pullRefresh(c)}):a.os.android?a.plusReady(function(){a.fn.pullRefresh=a.fn.pullRefresh_native;var b=plus.webview.currentWebview();if(window.__NWin_Enable__===!1)g.pullRefresh(c);else{if(e){var f={};f.up=c.up,f.webviewId=b.id||b.getURL(),g.pullRefresh(f)}if(d){var h=b.parent(),i=b.id||b.getURL();if(h){e||g.pullRefresh({webviewId:i});var j={webviewId:i};j.down=a.extend({},c.down),j.down.callback="_CALLBACK",h.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native"),h.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify(j)+"')")}}}}):g.pullRefresh(c):g.pullRefresh(c))}}}})}(mui),function(a,b,c){var d="application/json",e="text/html",f=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,g=/^(?:text|application)\/javascript/i,h=/^(?:text|application)\/xml/i,i=/^\s*$/;a.ajaxSettings={type:"GET",beforeSend:a.noop,success:a.noop,error:a.noop,complete:a.noop,context:null,xhr:function(a){return new b.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:d,xml:"application/xml, text/xml",html:e,text:"text/plain"},timeout:0,processData:!0,cache:!0};var j=function(a,b){var c=b.context;return b.beforeSend.call(c,a,b)===!1?!1:void 0},k=function(a,b,c){c.success.call(c.context,a,"success",b),m("success",b,c)},l=function(a,b,c,d){d.error.call(d.context,c,b,a),m(b,c,d)},m=function(a,b,c){c.complete.call(c.context,b,a)},n=function(b,c,d,e){var f,g=a.isArray(c),h=a.isPlainObject(c);a.each(c,function(c,i){f=a.type(i),e&&(c=d?e:e+"["+(h||"object"===f||"array"===f?c:"")+"]"),!e&&g?b.add(i.name,i.value):"array"===f||!d&&"object"===f?n(b,i,d,c):b.add(c,i)})},o=function(b){if(b.processData&&b.data&&"string"!=typeof b.data){var e=b.contentType;!e&&b.headers&&(e=b.headers["Content-Type"]),e&&~e.indexOf(d)?b.data=JSON.stringify(b.data):b.data=a.param(b.data,b.traditional)}!b.data||b.type&&"GET"!==b.type.toUpperCase()||(b.url=p(b.url,b.data),b.data=c)},p=function(a,b){return""===b?a:(a+"&"+b).replace(/[&?]{1,2}/,"?")},q=function(a){return a&&(a=a.split(";",2)[0]),a&&(a===e?"html":a===d?"json":g.test(a)?"script":h.test(a)&&"xml")||"text"},r=function(b,d,e,f){return a.isFunction(d)&&(f=e,e=d,d=c),a.isFunction(e)||(f=e,e=c),{url:b,data:d,success:e,dataType:f}};a.ajax=function(d,e){"object"==typeof d&&(e=d,d=c);var f=e||{};f.url=d||f.url;for(var g in a.ajaxSettings)f[g]===c&&(f[g]=a.ajaxSettings[g]);o(f);var h=f.dataType;f.cache!==!1&&(e&&e.cache===!0||"script"!==h)||(f.url=p(f.url,"_="+a.now()));var m,n=f.accepts[h&&h.toLowerCase()],r={},s=function(a,b){r[a.toLowerCase()]=[a,b]},t=/^([\w-]+:)\/\//.test(f.url)?RegExp.$1:b.location.protocol,u=f.xhr(f),v=u.setRequestHeader;if(s("X-Requested-With","XMLHttpRequest"),s("Accept",n||"*/*"),(n=f.mimeType||n)&&(n.indexOf(",")>-1&&(n=n.split(",",2)[0]),u.overrideMimeType&&u.overrideMimeType(n)),(f.contentType||f.contentType!==!1&&f.data&&"GET"!==f.type.toUpperCase())&&s("Content-Type",f.contentType||"application/x-www-form-urlencoded"),f.headers)for(var w in f.headers)s(w,f.headers[w]);if(u.setRequestHeader=s,u.onreadystatechange=function(){if(4===u.readyState){u.onreadystatechange=a.noop,clearTimeout(m);var b,c=!1,d="file:"===t;if(u.status>=200&&u.status<300||304===u.status||0===u.status&&d&&u.responseText){h=h||q(f.mimeType||u.getResponseHeader("content-type")),b=u.responseText;try{"script"===h?(1,eval)(b):"xml"===h?b=u.responseXML:"json"===h&&(b=i.test(b)?null:a.parseJSON(b))}catch(e){c=e}c?l(c,"parsererror",u,f):k(b,u,f)}else{var g=u.status?"error":"abort",j=u.statusText||null;d&&(g="error",j="404"),l(j,g,u,f)}}},j(u,f)===!1)return u.abort(),l(null,"abort",u,f),u;if(f.xhrFields)for(var w in f.xhrFields)u[w]=f.xhrFields[w];var x="async"in f?f.async:!0;u.open(f.type.toUpperCase(),f.url,x,f.username,f.password);for(var w in r)r.hasOwnProperty(w)&&v.apply(u,r[w]);return f.timeout>0&&(m=setTimeout(function(){u.onreadystatechange=a.noop,u.abort(),l(null,"timeout",u,f)},f.timeout)),u.send(f.data?f.data:null),u},a.param=function(a,b){var c=[];return c.add=function(a,b){this.push(encodeURIComponent(a)+"="+encodeURIComponent(b))},n(c,a,b),c.join("&").replace(/%20/g,"+")},a.get=function(){return a.ajax(r.apply(null,arguments))},a.post=function(){var b=r.apply(null,arguments);return b.type="POST",a.ajax(b)},a.getJSON=function(){var b=r.apply(null,arguments);return b.dataType="json",a.ajax(b)},a.fn.load=function(b,c,d){if(!this.length)return this;var e,g=this,h=b.split(/\s/),i=r(b,c,d),j=i.success;return h.length>1&&(i.url=h[0],e=h[1]),i.success=function(a){if(e){var b=document.createElement("div");b.innerHTML=a.replace(f,"");var c=document.createElement("div"),d=b.querySelectorAll(e);if(d&&d.length>0)for(var h=0,i=d.length;i>h;h++)c.appendChild(d[h]);g[0].innerHTML=c.innerHTML}else g[0].innerHTML=a;j&&j.apply(g,arguments)},a.ajax(i),this}}(mui,window),function(a){var b=document.createElement("a");b.href=window.location.href,a.plusReady(function(){a.ajaxSettings=a.extend(a.ajaxSettings,{xhr:function(c){if(c.crossDomain)return new plus.net.XMLHttpRequest;if("file:"!==b.protocol){var d=document.createElement("a");if(d.href=c.url,d.href=d.href,c.crossDomain=b.protocol+"//"+b.host!=d.protocol+"//"+d.host,c.crossDomain)return new plus.net.XMLHttpRequest}return a.os.ios&&window.webkit&&window.webkit.messageHandlers?new plus.net.XMLHttpRequest:new window.XMLHttpRequest}})})}(mui),function(a,b,c){a.offset=function(a){var d={top:0,left:0};return typeof a.getBoundingClientRect!==c&&(d=a.getBoundingClientRect()),{top:d.top+b.pageYOffset-a.clientTop,left:d.left+b.pageXOffset-a.clientLeft}}}(mui,window),function(a,b){a.scrollTo=function(a,c,d){c=c||1e3;var e=function(c){if(0>=c)return b.scrollTo(0,a),void(d&&d());var f=a-b.scrollY;setTimeout(function(){b.scrollTo(0,b.scrollY+f/c*10),e(c-10)},16.7)};e(c)},a.animationFrame=function(a){var b,c,d;return function(){b=arguments,d=this,c||(c=!0,requestAnimationFrame(function(){a.apply(d,b),c=!1}))}}}(mui,window),function(a){var b=!1,c=/xyz/.test(function(){xyz})?/\b_super\b/:/.*/,d=function(){};d.extend=function(a){function d(){!b&&this.init&&this.init.apply(this,arguments)}var e=this.prototype;b=!0;var f=new this;b=!1;for(var g in a)f[g]="function"==typeof a[g]&&"function"==typeof e[g]&&c.test(a[g])?function(a,b){return function(){var c=this._super;this._super=e[a];var d=b.apply(this,arguments);return this._super=c,d}}(g,a[g]):a[g];return d.prototype=f,d.prototype.constructor=d,d.extend=arguments.callee,d},a.Class=d}(mui),function(a,b,c){var d="mui-pull-top-pocket",e="mui-pull-bottom-pocket",f="mui-pull",g="mui-pull-loading",h="mui-pull-caption",i="mui-pull-caption-down",j="mui-pull-caption-refresh",k="mui-pull-caption-nomore",l="mui-icon",m="mui-spinner",n="mui-icon-pulldown",o="mui-block",p="mui-hidden",q="mui-visibility",r=g+" "+l+" "+n,s=g+" "+l+" "+n,t=g+" "+l+" "+m,u=['<div class="'+f+'">','<div class="{icon}"></div>','<div class="'+h+'">{contentrefresh}</div>',"</div>"].join(""),v={init:function(b,c){this._super(b,a.extend(!0,{scrollY:!0,scrollX:!1,indicators:!0,deceleration:.003,down:{height:50,contentinit:"下拉可以刷新",contentdown:"下拉可以刷新",contentover:"释放立即刷新",contentrefresh:"正在刷新..."},up:{height:50,auto:!1,contentinit:"上拉显示更多",contentdown:"上拉显示更多",contentrefresh:"正在加载...",contentnomore:"没有更多数据了",duration:300}},c))},_init:function(){this._super(),this._initPocket()},_initPulldownRefresh:function(){this.pulldown=!0,this.topPocket&&(this.pullPocket=this.topPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.topCaption,this.pullLoading=this.topLoading)},_initPullupRefresh:function(){this.pulldown=!1,this.bottomPocket&&(this.pullPocket=this.bottomPocket,this.pullPocket.classList.add(o),this.pullPocket.classList.add(q),this.pullCaption=this.bottomCaption,this.pullLoading=this.bottomLoading)},_initPocket:function(){var a=this.options;a.down&&a.down.hasOwnProperty("callback")&&(this.topPocket=this.scroller.querySelector("."+d),this.topPocket||(this.topPocket=this._createPocket(d,a.down,s),this.wrapper.insertBefore(this.topPocket,this.wrapper.firstChild)),this.topLoading=this.topPocket.querySelector("."+g),this.topCaption=this.topPocket.querySelector("."+h)),a.up&&a.up.hasOwnProperty("callback")&&(this.bottomPocket=this.scroller.querySelector("."+e),this.bottomPocket||(this.bottomPocket=this._createPocket(e,a.up,t),this.scroller.appendChild(this.bottomPocket)),this.bottomLoading=this.bottomPocket.querySelector("."+g),this.bottomCaption=this.bottomPocket.querySelector("."+h),this.wrapper.addEventListener("scrollbottom",this))},_createPocket:function(a,c,d){var e=b.createElement("div");return e.className=a,e.innerHTML=u.replace("{contentrefresh}",c.contentinit).replace("{icon}",d),e},_resetPullDownLoading:function(){var a=this.pullLoading;a&&(this.pullCaption.innerHTML=this.options.down.contentdown,a.style.webkitTransition="",a.style.webkitTransform="",a.style.webkitAnimation="",a.className=s)},_setCaptionClass:function(a,b,c){if(!a)switch(c){case this.options.up.contentdown:b.className=h+" "+i;break;case this.options.up.contentrefresh:b.className=h+" "+j;break;case this.options.up.contentnomore:b.className=h+" "+k}},_setCaption:function(a,b){if(!this.loading){var c=this.options,d=this.pullPocket,e=this.pullCaption,f=this.pullLoading,g=this.pulldown,h=this;d&&(b?setTimeout(function(){e.innerHTML=h.lastTitle=a,g?f.className=s:(h._setCaptionClass(!1,e,a),f.className=t),f.style.webkitAnimation="",f.style.webkitTransition="",f.style.webkitTransform=""},100):a!==this.lastTitle&&(e.innerHTML=a,g?a===c.down.contentrefresh?(f.className=t,f.style.webkitAnimation="spinner-spin 1s step-end infinite"):a===c.down.contentover?(f.className=r,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(180deg)"):a===c.down.contentdown&&(f.className=s,f.style.webkitTransition="-webkit-transform 0.3s ease-in",f.style.webkitTransform="rotate(0deg)"):(a===c.up.contentrefresh?f.className=t+" "+q:f.className=t+" "+p,h._setCaptionClass(!1,e,a)),this.lastTitle=a))}}};a.PullRefresh=v}(mui,document),function(a,b,c,d){var e="mui-scroll",f="mui-scrollbar",g="mui-scrollbar-indicator",h=f+"-vertical",i=f+"-horizontal",j="mui-active",k={quadratic:{style:"cubic-bezier(0.25, 0.46, 0.45, 0.94)",fn:function(a){return a*(2-a)}},circular:{style:"cubic-bezier(0.1, 0.57, 0.1, 1)",fn:function(a){return Math.sqrt(1- --a*a)}},outCirc:{style:"cubic-bezier(0.075, 0.82, 0.165, 1)"},outCubic:{style:"cubic-bezier(0.165, 0.84, 0.44, 1)"}},l=a.Class.extend({init:function(b,c){this.wrapper=this.element=b,this.scroller=this.wrapper.children[0],this.scrollerStyle=this.scroller&&this.scroller.style,this.stopped=!1,this.options=a.extend(!0,{scrollY:!0,scrollX:!1,startX:0,startY:0,indicators:!0,stopPropagation:!1,hardwareAccelerated:!0,fixedBadAndorid:!1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/},momentum:!0,snapX:.5,snap:!1,bounce:!0,bounceTime:500,bounceEasing:k.outCirc,scrollTime:500,scrollEasing:k.outCubic,directionLockThreshold:5,parallaxElement:!1,parallaxRatio:.5},c),this.x=0,this.y=0,this.translateZ=this.options.hardwareAccelerated?" translateZ(0)":"",this._init(),this.scroller&&(this.refresh(),this.scrollTo(this.options.startX,this.options.startY))},_init:function(){this._initParallax(),this._initIndicators(),this._initEvent()},_initParallax:function(){this.options.parallaxElement&&(this.parallaxElement=c.querySelector(this.options.parallaxElement),this.parallaxStyle=this.parallaxElement.style,this.parallaxHeight=this.parallaxElement.offsetHeight,this.parallaxImgStyle=this.parallaxElement.querySelector("img").style)},_initIndicators:function(){var a=this;if(a.indicators=[],this.options.indicators){var b,c=[];a.options.scrollY&&(b={el:this._createScrollBar(h),listenX:!1},this.wrapper.appendChild(b.el),c.push(b)),this.options.scrollX&&(b={el:this._createScrollBar(i),listenY:!1},this.wrapper.appendChild(b.el),c.push(b));for(var d=c.length;d--;)this.indicators.push(new m(this,c[d]))}},_initSnap:function(){this.currentPage={},this.pages=[];for(var a=this.snaps,b=a.length,c=0,d=-1,e=0,f=0,g=0,h=0,i=0;b>i;i++){var k=a[i],l=k.offsetLeft,m=k.offsetWidth;(0===i||l<=a[i-1].offsetLeft)&&(c=0,d++),this.pages[c]||(this.pages[c]=[]),e=this._getSnapX(l),h=Math.round(m*this.options.snapX),f=e-h,g=e-m+h,this.pages[c][d]={x:e,leftX:f,rightX:g,pageX:c,element:k},k.classList.contains(j)&&(this.currentPage=this.pages[c][0]),e>=this.maxScrollX&&c++}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(Math.min(0,-a+this.wrapperWidth/2),this.maxScrollX)},_gotoPage:function(a){this.currentPage=this.pages[Math.min(a,this.pages.length-1)][0];for(var b=0,c=this.snaps.length;c>b;b++)b===a?this.snaps[b].classList.add(j):this.snaps[b].classList.remove(j);this.scrollTo(this.currentPage.x,0,this.options.scrollTime)},_nearestSnap:function(a){if(!this.pages.length)return{x:0,pageX:0};var b=0,c=this.pages.length;for(a>0?a=0:a<this.maxScrollX&&(a=this.maxScrollX);c>b;b++){var d="left"===this.direction?this.pages[b][0].leftX:this.pages[b][0].rightX;if(a>=d)return this.pages[b][0]}return{x:0,pageX:0}},_initEvent:function(c){var d=c?"removeEventListener":"addEventListener";b[d]("orientationchange",this),b[d]("resize",this),this.scroller[d]("webkitTransitionEnd",this),this.wrapper[d](a.EVENT_START,this),this.wrapper[d](a.EVENT_CANCEL,this),this.wrapper[d](a.EVENT_END,this),this.wrapper[d]("drag",this),this.wrapper[d]("dragend",this),this.wrapper[d]("flick",this),this.wrapper[d]("scrollend",this),this.options.scrollX&&this.wrapper[d]("swiperight",this);var e=this.wrapper.querySelector(".mui-segmented-control");e&&mui(e)[c?"off":"on"]("click","a",a.preventDefault),this.wrapper[d]("scrollstart",this),this.wrapper[d]("refresh",this)},_handleIndicatorScrollend:function(){this.indicators.map(function(a){a.fade()})},_handleIndicatorScrollstart:function(){this.indicators.map(function(a){a.fade(1)})},_handleIndicatorRefresh:function(){this.indicators.map(function(a){a.refresh()})},handleEvent:function(b){if(this.stopped)return void this.resetPosition();switch(b.type){case a.EVENT_START:this._start(b);break;case"drag":this.options.stopPropagation&&b.stopPropagation(),this._drag(b);break;case"dragend":case"flick":this.options.stopPropagation&&b.stopPropagation(),this._flick(b);break;case a.EVENT_CANCEL:case a.EVENT_END:this._end(b);break;case"webkitTransitionEnd":this.transitionTimer&&this.transitionTimer.cancel(),this._transitionEnd(b);break;case"scrollstart":this._handleIndicatorScrollstart(b);break;case"scrollend":this._handleIndicatorScrollend(b),this._scrollend(b),b.stopPropagation();break;case"orientationchange":case"resize":this._resize();break;case"swiperight":b.stopPropagation();break;case"refresh":this._handleIndicatorRefresh(b)}},_start:function(b){if(this.moved=this.needReset=!1,this._transitionTime(),this.isInTransition){this.needReset=!0,this.isInTransition=!1;var c=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));this.setTranslate(Math.round(c.x),Math.round(c.y)),a.trigger(this.scroller,"scrollend",this),b.preventDefault()}this.reLayout(),a.trigger(this.scroller,"beforescrollstart",this)},_getDirectionByAngle:function(a){return-80>a&&a>-100?"up":a>=80&&100>a?"down":a>=170||-170>=a?"left":a>=-35&&10>=a?"right":null},_drag:function(c){var d=c.detail;if((this.options.scrollY||"up"===d.direction||"down"===d.direction)&&a.os.ios&&parseFloat(a.os.version)>=8){var e=d.gesture.touches[0].clientY;if(e+10>b.innerHeight||10>e)return void this.resetPosition(this.options.bounceTime)}var f=isReturn=!1;this._getDirectionByAngle(d.angle);if("left"===d.direction||"right"===d.direction?this.options.scrollX?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollY&&!this.moved&&(isReturn=!0):"up"===d.direction||"down"===d.direction?this.options.scrollY?(f=!0,this.moved||(a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=d.direction)):this.options.scrollX&&!this.moved&&(isReturn=!0):isReturn=!0,(this.moved||f)&&(c.stopPropagation(),d.gesture&&d.gesture.preventDefault()),!isReturn){this.moved?c.stopPropagation():a.trigger(this.scroller,"scrollstart",this);var g=0,h=0;this.moved?(g=d.deltaX-a.gestures.session.prevTouch.deltaX,h=d.deltaY-a.gestures.session.prevTouch.deltaY):(g=d.deltaX,h=d.deltaY);var i=Math.abs(d.deltaX),j=Math.abs(d.deltaY);i>j+this.options.directionLockThreshold?h=0:j>=i+this.options.directionLockThreshold&&(g=0),g=this.hasHorizontalScroll?g:0,h=this.hasVerticalScroll?h:0;var k=this.x+g,l=this.y+h;(k>0||k<this.maxScrollX)&&(k=this.options.bounce?this.x+g/3:k>0?0:this.maxScrollX),(l>0||l<this.maxScrollY)&&(l=this.options.bounce?this.y+h/3:l>0?0:this.maxScrollY),this.requestAnimationFrame||this._updateTranslate(),this.direction=d.deltaX>0?"right":"left",this.moved=!0,this.x=k,this.y=l,a.trigger(this.scroller,"scroll",this)}},_flick:function(b){if(this.moved){b.stopPropagation();var c=b.detail;if(this._clearRequestAnimationFrame(),"dragend"!==b.type||!c.flick){var d=Math.round(this.x),e=Math.round(this.y);if(this.isInTransition=!1,!this.resetPosition(this.options.bounceTime)){if(this.scrollTo(d,e),"dragend"===b.type)return void a.trigger(this.scroller,"scrollend",this);var f=0,g="";return this.options.momentum&&c.flickTime<300&&(momentumX=this.hasHorizontalScroll?this._momentum(this.x,c.flickDistanceX,c.flickTime,this.maxScrollX,this.options.bounce?this.wrapperWidth:0,this.options.deceleration):{destination:d,duration:0},momentumY=this.hasVerticalScroll?this._momentum(this.y,c.flickDistanceY,c.flickTime,this.maxScrollY,this.options.bounce?this.wrapperHeight:0,this.options.deceleration):{destination:e,duration:0},d=momentumX.destination,e=momentumY.destination,f=Math.max(momentumX.duration,momentumY.duration),this.isInTransition=!0),d!=this.x||e!=this.y?((d>0||d<this.maxScrollX||e>0||e<this.maxScrollY)&&(g=k.quadratic),void this.scrollTo(d,e,f,g)):void a.trigger(this.scroller,"scrollend",this)}}}},_end:function(b){this.needReset=!1,(!this.moved&&this.needReset||b.type===a.EVENT_CANCEL)&&this.resetPosition()},_transitionEnd:function(b){b.target==this.scroller&&this.isInTransition&&(this._transitionTime(),this.resetPosition(this.options.bounceTime)||(this.isInTransition=!1,a.trigger(this.scroller,"scrollend",this)))},_scrollend:function(b){(0===this.y&&0===this.maxScrollY||Math.abs(this.y)>0&&this.y<=this.maxScrollY)&&a.trigger(this.scroller,"scrollbottom",this)},_resize:function(){var a=this;clearTimeout(a.resizeTimeout),a.resizeTimeout=setTimeout(function(){a.refresh()},a.options.resizePolling)},_transitionTime:function(b){if(b=b||0,this.scrollerStyle.webkitTransitionDuration=b+"ms",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=b+"ms"),this.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.scrollerStyle.webkitTransitionDuration="0.001s",this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration="0.001s")),this.indicators)for(var c=this.indicators.length;c--;)this.indicators[c].transitionTime(b);b&&(this.transitionTimer&&this.transitionTimer.cancel(),this.transitionTimer=a.later(function(){a.trigger(this.scroller,"webkitTransitionEnd")},b+100,this))},_transitionTimingFunction:function(a){if(this.scrollerStyle.webkitTransitionTimingFunction=a,this.parallaxElement&&this.options.scrollY&&(this.parallaxStyle.webkitTransitionDuration=a),this.indicators)for(var b=this.indicators.length;b--;)this.indicators[b].transitionTimingFunction(a)},_translate:function(a,b){this.x=a,this.y=b},_clearRequestAnimationFrame:function(){this.requestAnimationFrame&&(cancelAnimationFrame(this.requestAnimationFrame),this.requestAnimationFrame=null)},_updateTranslate:function(){var a=this;(a.x!==a.lastX||a.y!==a.lastY)&&a.setTranslate(a.x,a.y),a.requestAnimationFrame=requestAnimationFrame(function(){a._updateTranslate()})},_createScrollBar:function(a){var b=c.createElement("div"),d=c.createElement("div");return b.className=f+" "+a,d.className=g,b.appendChild(d),a===h?(this.scrollbarY=b,this.scrollbarIndicatorY=d):a===i&&(this.scrollbarX=b,this.scrollbarIndicatorX=d),this.wrapper.appendChild(b),b},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},_reLayout:function(){if(this.hasHorizontalScroll||(this.maxScrollX=0,this.scrollerWidth=this.wrapperWidth),this.hasVerticalScroll||(this.maxScrollY=0,this.scrollerHeight=this.wrapperHeight),this.indicators.map(function(a){a.refresh()}),this.options.snap&&"string"==typeof this.options.snap){var a=this.scroller.querySelectorAll(this.options.snap);this.itemLength=0,this.snaps=[];for(var b=0,c=a.length;c>b;b++){var d=a[b];d.parentNode===this.scroller&&(this.itemLength++,this.snaps.push(d))}this._initSnap()}},_momentum:function(a,b,c,e,f,g){var h,i,j=parseFloat(Math.abs(b)/c);return g=g===d?6e-4:g,h=a+j*j/(2*g)*(0>b?-1:1),i=j/g,e>h?(h=f?e-f/2.5*(j/8):e,b=Math.abs(h-a),i=b/j):h>0&&(h=f?f/2.5*(j/8):0,b=Math.abs(a)+h,i=b/j),{destination:Math.round(h),duration:i}},_getTranslateStr:function(a,b){return this.options.hardwareAccelerated?"translate3d("+a+"px,"+b+"px,0px) "+this.translateZ:"translate("+a+"px,"+b+"px) "},setStopped:function(a){a?(this.disablePullupToRefresh(),this.disablePulldownToRefresh()):(this.enablePullupToRefresh(),this.enablePulldownToRefresh())},setTranslate:function(b,c){if(this.x=b,this.y=c,this.scrollerStyle.webkitTransform=this._getTranslateStr(b,c),this.parallaxElement&&this.options.scrollY){var d=c*this.options.parallaxRatio,e=1+d/((this.parallaxHeight-d)/2);e>1?(this.parallaxImgStyle.opacity=1-d/100*this.options.parallaxRatio,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-d)+" scale("+e+","+e+")"):(this.parallaxImgStyle.opacity=1,this.parallaxStyle.webkitTransform=this._getTranslateStr(0,-1)+" scale(1,1)")}if(this.indicators)for(var f=this.indicators.length;f--;)this.indicators[f].updatePosition();this.lastX=this.x,this.lastY=this.y,a.trigger(this.scroller,"scroll",this)},reLayout:function(){this.wrapper.offsetHeight;var b=parseFloat(a.getStyles(this.wrapper,"padding-left"))||0,c=parseFloat(a.getStyles(this.wrapper,"padding-right"))||0,d=parseFloat(a.getStyles(this.wrapper,"padding-top"))||0,e=parseFloat(a.getStyles(this.wrapper,"padding-bottom"))||0,f=this.wrapper.clientWidth,g=this.wrapper.clientHeight;this.scrollerWidth=this.scroller.offsetWidth,this.scrollerHeight=this.scroller.offsetHeight,this.wrapperWidth=f-b-c,this.wrapperHeight=g-d-e,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this.maxScrollY=Math.min(this.wrapperHeight-this.scrollerHeight,0),this.hasHorizontalScroll=this.options.scrollX&&this.maxScrollX<0,this.hasVerticalScroll=this.options.scrollY&&this.maxScrollY<0,this._reLayout()},resetPosition:function(a){var b=this.x,c=this.y;return a=a||0,!this.hasHorizontalScroll||this.x>0?b=0:this.x<this.maxScrollX&&(b=this.maxScrollX),!this.hasVerticalScroll||this.y>0?c=0:this.y<this.maxScrollY&&(c=this.maxScrollY),b==this.x&&c==this.y?!1:(this.scrollTo(b,c,a,this.options.scrollEasing),!0)},_reInit:function(){for(var a=this.wrapper.querySelectorAll("."+e),b=0,c=a.length;c>b;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style},refresh:function(){this._reInit(),this.reLayout(),a.trigger(this.scroller,"refresh",this),this.resetPosition()},scrollTo:function(a,b,c,d){var d=d||k.circular;this.isInTransition=c>0,this.isInTransition?(this._clearRequestAnimationFrame(),this._transitionTimingFunction(d.style),this._transitionTime(c),this.setTranslate(a,b)):this.setTranslate(a,b)},scrollToBottom:function(a,b){a=a||this.options.scrollTime,this.scrollTo(0,this.maxScrollY,a,b)},gotoPage:function(a){this._gotoPage(a)},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-scroll")],this.wrapper.setAttribute("data-scroll","")}}),m=function(b,d){this.wrapper="string"==typeof d.el?c.querySelector(d.el):d.el,this.wrapperStyle=this.wrapper.style,this.indicator=this.wrapper.children[0],this.indicatorStyle=this.indicator.style,this.scroller=b,this.options=a.extend({listenX:!0,listenY:!0,fade:!1,speedRatioX:0,speedRatioY:0},d),this.sizeRatioX=1,this.sizeRatioY=1,this.maxPosX=0,this.maxPosY=0,this.options.fade&&(this.wrapperStyle.webkitTransform=this.scroller.translateZ,this.wrapperStyle.webkitTransitionDuration=this.options.fixedBadAndorid&&a.os.isBadAndroid?"0.001s":"0ms",this.wrapperStyle.opacity="0")};m.prototype={handleEvent:function(a){},transitionTime:function(b){b=b||0,this.indicatorStyle.webkitTransitionDuration=b+"ms",this.scroller.options.fixedBadAndorid&&!b&&a.os.isBadAndroid&&(this.indicatorStyle.webkitTransitionDuration="0.001s")},transitionTimingFunction:function(a){this.indicatorStyle.webkitTransitionTimingFunction=a},refresh:function(){this.transitionTime(),this.options.listenX&&!this.options.listenY?this.indicatorStyle.display=this.scroller.hasHorizontalScroll?"block":"none":this.options.listenY&&!this.options.listenX?this.indicatorStyle.display=this.scroller.hasVerticalScroll?"block":"none":this.indicatorStyle.display=this.scroller.hasHorizontalScroll||this.scroller.hasVerticalScroll?"block":"none",this.wrapper.offsetHeight,this.options.listenX&&(this.wrapperWidth=this.wrapper.clientWidth,this.indicatorWidth=Math.max(Math.round(this.wrapperWidth*this.wrapperWidth/(this.scroller.scrollerWidth||this.wrapperWidth||1)),8),this.indicatorStyle.width=this.indicatorWidth+"px",this.maxPosX=this.wrapperWidth-this.indicatorWidth,this.minBoundaryX=0,this.maxBoundaryX=this.maxPosX,this.sizeRatioX=this.options.speedRatioX||this.scroller.maxScrollX&&this.maxPosX/this.scroller.maxScrollX),this.options.listenY&&(this.wrapperHeight=this.wrapper.clientHeight,this.indicatorHeight=Math.max(Math.round(this.wrapperHeight*this.wrapperHeight/(this.scroller.scrollerHeight||this.wrapperHeight||1)),8),this.indicatorStyle.height=this.indicatorHeight+"px",this.maxPosY=this.wrapperHeight-this.indicatorHeight,this.minBoundaryY=0,this.maxBoundaryY=this.maxPosY,this.sizeRatioY=this.options.speedRatioY||this.scroller.maxScrollY&&this.maxPosY/this.scroller.maxScrollY),this.updatePosition()},updatePosition:function(){var a=this.options.listenX&&Math.round(this.sizeRatioX*this.scroller.x)||0,b=this.options.listenY&&Math.round(this.sizeRatioY*this.scroller.y)||0;a<this.minBoundaryX?(this.width=Math.max(this.indicatorWidth+a,8),this.indicatorStyle.width=this.width+"px",a=this.minBoundaryX):a>this.maxBoundaryX?(this.width=Math.max(this.indicatorWidth-(a-this.maxPosX),8),this.indicatorStyle.width=this.width+"px",a=this.maxPosX+this.indicatorWidth-this.width):this.width!=this.indicatorWidth&&(this.width=this.indicatorWidth,this.indicatorStyle.width=this.width+"px"),b<this.minBoundaryY?(this.height=Math.max(this.indicatorHeight+3*b,8),this.indicatorStyle.height=this.height+"px",b=this.minBoundaryY):b>this.maxBoundaryY?(this.height=Math.max(this.indicatorHeight-3*(b-this.maxPosY),8),this.indicatorStyle.height=this.height+"px",b=this.maxPosY+this.indicatorHeight-this.height):this.height!=this.indicatorHeight&&(this.height=this.indicatorHeight,this.indicatorStyle.height=this.height+"px"),this.x=a,this.y=b,this.indicatorStyle.webkitTransform=this.scroller._getTranslateStr(a,b)},fade:function(a,b){if(!b||this.visible){clearTimeout(this.fadeTimeout),this.fadeTimeout=null;var c=a?250:500,d=a?0:300;a=a?"1":"0",this.wrapperStyle.webkitTransitionDuration=c+"ms",this.fadeTimeout=setTimeout(function(a){this.wrapperStyle.opacity=a,this.visible=+a}.bind(this,a),d)}}},a.Scroll=l,a.fn.scroll=function(b){var c=[];return this.each(function(){var d=null,e=this,f=e.getAttribute("data-scroll");if(f)d=a.data[f];else{f=++a.uuid;var g=a.extend({},b);e.classList.contains("mui-segmented-control")&&(g=a.extend(g,{scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})),a.data[f]=d=new l(e,g),e.setAttribute("data-scroll",f)}c.push(d)}),1===c.length?c[0]:c}}(mui,window,document),function(a,b,c,d){var e="mui-visibility",f="mui-hidden",g=a.Scroll.extend(a.extend({handleEvent:function(a){this._super(a),"scrollbottom"===a.type&&a.target===this.scroller&&this._scrollbottom()},_scrollbottom:function(){this.pulldown||this.loading||(this.pulldown=!1,this._initPullupRefresh(),this.pullupLoading())},_start:function(a){a.touches&&a.touches.length&&a.touches[0].clientX>30&&a.target&&!this._preventDefaultException(a.target,this.options.preventDefaultException)&&a.preventDefault(),this.loading||(this.pulldown=this.pullPocket=this.pullCaption=this.pullLoading=!1),this._super(a)},_drag:function(a){this.y>=0&&this.disablePulldown&&"down"===a.detail.direction||(this._super(a),!this.pulldown&&!this.loading&&this.topPocket&&"down"===a.detail.direction&&this.y>=0&&this._initPulldownRefresh(),this.pulldown&&this._setCaption(this.y>this.options.down.height?this.options.down.contentover:this.options.down.contentdown))},_reLayout:function(){this.hasVerticalScroll=!0,this._super()},resetPosition:function(a){if(this.pulldown&&!this.disablePulldown){if(this.y>=this.options.down.height)return this.pulldownLoading(d,a||0),!0;!this.loading&&this.topPocket.classList.remove(e)}return this._super(a)},pulldownLoading:function(a,b){if("undefined"==typeof a&&(a=this.options.down.height),this.scrollTo(0,a,b,this.options.bounceEasing),!this.loading){this._initPulldownRefresh(),this._setCaption(this.options.down.contentrefresh),this.loading=!0,this.indicators.map(function(a){a.fade(0)});var c=this.options.down.callback;c&&c.call(this)}},endPulldownToRefresh:function(){var a=this;a.topPocket&&a.loading&&this.pulldown&&(a.scrollTo(0,0,a.options.bounceTime,a.options.bounceEasing),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(e)},350))},pullupLoading:function(a,b,c){b=b||0,this.scrollTo(b,this.maxScrollY,c,this.options.bounceEasing),this.loading||(this._initPullupRefresh(),this._setCaption(this.options.up.contentrefresh),this.indicators.map(function(a){a.fade(0)}),this.loading=!0,a=a||this.options.up.callback,a&&a.call(this))},endPullupToRefresh:function(a){var b=this;b.bottomPocket&&(b.loading=!1,a?(this.finished=!0,b._setCaption(b.options.up.contentnomore),b.wrapper.removeEventListener("scrollbottom",b)):(b._setCaption(b.options.up.contentdown),b.loading||b.bottomPocket.classList.remove(e)))},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+f,this.wrapper.removeEventListener("scrollbottom",this)},disablePulldownToRefresh:function(){this._initPulldownRefresh(),this.topPocket.className="mui-pull-top-pocket "+f,this.disablePulldown=!0},enablePulldownToRefresh:function(){this._initPulldownRefresh(),this.topPocket.classList.remove(f),this._setCaption(this.options.down.contentdown),this.disablePulldown=!1},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(f), +this._setCaption(this.options.up.contentdown),this.wrapper.addEventListener("scrollbottom",this)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1),this._super()}},a.PullRefresh));a.fn.pullRefresh=function(b){if(1===this.length){var c=this[0],d=null,e=c.getAttribute("data-pullrefresh");return e||"undefined"!=typeof b?(b=b||{},e?d=a.data[e]:(e=++a.uuid,a.data[e]=d=new g(c,b),c.setAttribute("data-pullrefresh",e)),b.down&&b.down.auto?d.pulldownLoading(b.down.autoY):b.up&&b.up.auto&&d.pullupLoading(),d):!1}}}(mui,window,document),function(a,b){var c="mui-slider",d="mui-slider-group",e="mui-slider-loop",f="mui-action-previous",g="mui-action-next",h="mui-slider-item",i="mui-active",j="."+h,k=".mui-slider-progress-bar",l=a.Slider=a.Scroll.extend({init:function(b,c){this._super(b,a.extend(!0,{fingers:1,interval:0,scrollY:!1,scrollX:!0,indicators:!1,scrollTime:1e3,startX:!1,slideTime:0,snap:j},c)),this.options.startX},_init:function(){this._reInit(),this.scroller&&(this.scrollerStyle=this.scroller.style,this.progressBar=this.wrapper.querySelector(k),this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style),this._super(),this._initTimer())},_triggerSlide:function(){var b=this;b.isInTransition=!1;b.currentPage;b.slideNumber=b._fixedSlideNumber(),b.loop&&(0===b.slideNumber?b.setTranslate(b.pages[1][0].x,0):b.slideNumber===b.itemLength-3&&b.setTranslate(b.pages[b.itemLength-2][0].x,0)),b.lastSlideNumber!=b.slideNumber&&(b.lastSlideNumber=b.slideNumber,b.lastPage=b.currentPage,a.trigger(b.wrapper,"slide",{slideNumber:b.slideNumber})),b._initTimer()},_handleSlide:function(b){var c=this;if(b.target===c.wrapper){var d=b.detail;d.slideNumber=d.slideNumber||0;for(var e=c.scroller.querySelectorAll(j),f=[],g=0,h=e.length;h>g;g++){var k=e[g];k.parentNode===c.scroller&&f.push(k)}var l=d.slideNumber;if(c.loop&&(l+=1),!c.wrapper.classList.contains("mui-segmented-control"))for(var g=0,h=f.length;h>g;g++){var k=f[g];k.parentNode===c.scroller&&(g===l?k.classList.add(i):k.classList.remove(i))}var m=c.wrapper.querySelector(".mui-slider-indicator");if(m){m.getAttribute("data-scroll")&&a(m).scroll().gotoPage(d.slideNumber);var n=m.querySelectorAll(".mui-indicator");if(n.length>0)for(var g=0,h=n.length;h>g;g++)n[g].classList[g===d.slideNumber?"add":"remove"](i);else{var o=m.querySelector(".mui-number span");if(o)o.innerText=d.slideNumber+1;else for(var p=m.querySelectorAll(".mui-control-item"),g=0,h=p.length;h>g;g++)p[g].classList[g===d.slideNumber?"add":"remove"](i)}}b.stopPropagation()}},_handleTabShow:function(a){var b=this;b.gotoItem(a.detail.tabNumber||0,b.options.slideTime)},_handleIndicatorTap:function(a){var b=this,c=a.target;(c.classList.contains(f)||c.classList.contains(g))&&(b[c.classList.contains(f)?"prevItem":"nextItem"](),a.stopPropagation())},_initEvent:function(b){var c=this;c._super(b);var d=b?"removeEventListener":"addEventListener";c.wrapper[d]("slide",this),c.wrapper[d](a.eventName("shown","tab"),this)},handleEvent:function(b){switch(this._super(b),b.type){case"slide":this._handleSlide(b);break;case a.eventName("shown","tab"):~this.snaps.indexOf(b.target)&&this._handleTabShow(b)}},_scrollend:function(a){this._super(a),this._triggerSlide(a)},_drag:function(a){this._super(a);var c=a.detail.direction;if("left"===c||"right"===c){var d=this.wrapper.getAttribute("data-slidershowTimer");d&&b.clearTimeout(d),a.stopPropagation()}},_initTimer:function(){var a=this,c=a.wrapper,d=a.options.interval,e=c.getAttribute("data-slidershowTimer");e&&b.clearTimeout(e),d&&(e=b.setTimeout(function(){c&&((c.offsetWidth||c.offsetHeight)&&a.nextItem(!0),a._initTimer())},d),c.setAttribute("data-slidershowTimer",e))},_fixedSlideNumber:function(a){a=a||this.currentPage;var b=a.pageX;return this.loop&&(b=0===a.pageX?this.itemLength-3:a.pageX===this.itemLength-1?0:a.pageX-1),b},_reLayout:function(){this.hasHorizontalScroll=!0,this.loop=this.scroller.classList.contains(e),this._super()},_getScroll:function(){var b=a.parseTranslateMatrix(a.getStyles(this.scroller,"webkitTransform"));return b?b.x:0},_transitionEnd:function(b){b.target===this.scroller&&this.isInTransition&&(this._transitionTime(),this.isInTransition=!1,a.trigger(this.wrapper,"scrollend",this))},_flick:function(a){if(this.moved){var b=a.detail,c=b.direction;this._clearRequestAnimationFrame(),this.isInTransition=!0,"flick"===a.type?(b.deltaTime<200&&(this.x=this._getPage(this.slideNumber+("right"===c?-1:1),!0).x),this.resetPosition(this.options.bounceTime)):"dragend"!==a.type||b.flick||this.resetPosition(this.options.bounceTime),a.stopPropagation()}},_initSnap:function(){if(this.scrollerWidth=this.itemLength*this.scrollerWidth,this.maxScrollX=Math.min(this.wrapperWidth-this.scrollerWidth,0),this._super(),this.currentPage.x)this.slideNumber=this._fixedSlideNumber(),this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?this.slideNumber:this.lastSlideNumber;else{var a=this.pages[this.loop?1:0];if(a=a||this.pages[0],!a)return;this.currentPage=a[0],this.slideNumber=0,this.lastSlideNumber="undefined"==typeof this.lastSlideNumber?0:this.lastSlideNumber}this.options.startX=this.currentPage.x||0},_getSnapX:function(a){return Math.max(-a,this.maxScrollX)},_getPage:function(a,b){return this.loop?a>this.itemLength-(b?2:3)?(a=1,time=0):(b?-1:0)>a?(a=this.itemLength-2,time=0):a+=1:(b||(a>this.itemLength-1?(a=0,time=0):0>a&&(a=this.itemLength-1,time=0)),a=Math.min(Math.max(0,a),this.itemLength-1)),this.pages[a][0]},_gotoItem:function(b,c){this.currentPage=this._getPage(b,!0),this.scrollTo(this.currentPage.x,0,c,this.options.scrollEasing),0===c&&a.trigger(this.wrapper,"scrollend",this)},setTranslate:function(a,b){this._super(a,b);var c=this.progressBar;c&&(this.progressBarStyle.webkitTransform=this._getTranslateStr(-a*(this.progressBarWidth/this.wrapperWidth),0))},resetPosition:function(a){return a=a||0,this.x>0?this.x=0:this.x<this.maxScrollX&&(this.x=this.maxScrollX),this.currentPage=this._nearestSnap(this.x),this.scrollTo(this.currentPage.x,0,a,this.options.scrollEasing),!0},gotoItem:function(a,b){this._gotoItem(a,"undefined"==typeof b?this.options.scrollTime:b)},nextItem:function(){this._gotoItem(this.slideNumber+1,this.options.scrollTime)},prevItem:function(){this._gotoItem(this.slideNumber-1,this.options.scrollTime)},getSlideNumber:function(){return this.slideNumber||0},_reInit:function(){for(var a=this.wrapper.querySelectorAll("."+d),b=0,c=a.length;c>b;b++)if(a[b].parentNode===this.wrapper){this.scroller=a[b];break}this.scrollerStyle=this.scroller&&this.scroller.style,this.progressBar&&(this.progressBarWidth=this.progressBar.offsetWidth,this.progressBarStyle=this.progressBar.style)},refresh:function(b){b?(a.extend(this.options,b),this._super(),this._initTimer()):this._super()},destroy:function(){this._initEvent(!0),delete a.data[this.wrapper.getAttribute("data-slider")],this.wrapper.setAttribute("data-slider","")}});a.fn.slider=function(b){var d=null;return this.each(function(){var e=this;if(this.classList.contains(c)||(e=this.querySelector("."+c)),e&&e.querySelector(j)){var f=e.getAttribute("data-slider");f?(d=a.data[f],d&&b&&d.refresh(b)):(f=++a.uuid,a.data[f]=d=new l(e,b),e.setAttribute("data-slider",f))}}),d},a.ready(function(){a(".mui-slider").slider(),a(".mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control").scroll({scrollY:!1,scrollX:!0,indicators:!1,snap:".mui-control-item"})})}(mui,window),function(a,b){a.os.plus&&a.plusReady(function(){if(window.__NWin_Enable__!==!1){var c="mui-plus-pullrefresh",d="mui-visibility",e="mui-hidden",f="mui-block",g="mui-pull-caption",h="mui-pull-caption-down",i="mui-pull-caption-refresh",j="mui-pull-caption-nomore",k=a.Class.extend({init:function(a,b){this.element=a,this.options=b,this.wrapper=this.scroller=a,this._init(),this._initPulldownRefreshEvent()},_init:function(){var a=this;window.addEventListener("dragup",a),b.addEventListener("plusscrollbottom",a),a.scrollInterval=window.setInterval(function(){a.isScroll&&!a.loading&&window.pageYOffset+window.innerHeight+10>=b.documentElement.scrollHeight&&(a.isScroll=!1,a.bottomPocket&&a.pullupLoading())},100)},_initPulldownRefreshEvent:function(){var b=this;a.plusReady(function(){if("circle"==b.options.down.style)b.options.webview=plus.webview.currentWebview(),b.options.webview.setPullToRefresh({support:!0,color:b.options.down.color||"#2BD009",height:b.options.down.height||"50px",range:b.options.down.range||"100px",style:"circle",offset:b.options.down.offset||"0px"},function(){b.options.down.callback()});else if(b.topPocket&&b.options.webviewId){var a=plus.webview.getWebviewById(b.options.webviewId);if(!a)return;b.options.webview=a;var c=b.options.down,d=c.height;a.addEventListener("close",function(){var a=b.options.webviewId&&b.options.webviewId.replace(/\//g,"_");b.element.removeAttribute("data-pullrefresh-plus-"+a)}),a.addEventListener("dragBounce",function(d){switch(b.pulldown?b.pullPocket.classList.add(f):b._initPulldownRefresh(),d.status){case"beforeChangeOffset":b._setCaption(c.contentdown);break;case"afterChangeOffset":b._setCaption(c.contentover);break;case"dragEndAfterChangeOffset":a.evalJS("window.mui&&mui.options.pullRefresh.down.callback()"),b._setCaption(c.contentrefresh)}},!1),a.setBounce({position:{top:2*d+"px"},changeoffset:{top:d+"px"}})}})},handleEvent:function(a){var b=this;b.stopped||(b.isScroll=!1,("dragup"===a.type||"plusscrollbottom"===a.type)&&(b.isScroll=!0,setTimeout(function(){b.isScroll=!1},1e3)))}}).extend(a.extend({setStopped:function(a){this.stopped=!!a,this.stopped?(this.disablePullupToRefresh(),this.disablePulldownToRefresh()):(this.enablePullupToRefresh(),this.enablePulldownToRefresh())},beginPulldown:function(){var b=this;a.plusReady(function(){setTimeout(function(){if("circle"==b.options.down.style)plus.webview.currentWebview().beginPullToRefresh();else{var a=b.options.webview;a&&a.setBounce({offset:{top:b.options.down.height+"px"}})}},15)}.bind(this))},pulldownLoading:function(){this.beginPulldown()},_pulldownLoading:function(){var b=this;a.plusReady(function(){var a=plus.webview.getWebviewById(b.options.webviewId);a&&a.setBounce({offset:{top:b.options.down.height+"px"}})})},endPulldown:function(){var a=plus.webview.currentWebview();a.parent()&&"circle"!==this.options.down.style?a.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('"+JSON.stringify({webviewId:a.id})+"')._endPulldownToRefresh()"):a.endPullToRefresh()},endPulldownToRefresh:function(){this.endPulldown()},_endPulldownToRefresh:function(){var a=this;a.topPocket&&a.options.webview&&(a.options.webview.endPullToRefresh(),a.loading=!1,a._setCaption(a.options.down.contentdown,!0),setTimeout(function(){a.loading||a.topPocket.classList.remove(f)},350))},beginPullup:function(a){var b=this;b.isLoading||(b.isLoading=!0,b.pulldown!==!1?b._initPullupRefresh():this.pullPocket.classList.add(f),setTimeout(function(){b.pullLoading.classList.add(d),b.pullLoading.classList.remove(e),b.pullCaption.innerHTML="",b.pullCaption.className=g+" "+i,b.pullCaption.innerHTML=b.options.up.contentrefresh,a=a||b.options.up.callback,a&&a.call(b)},300))},pullupLoading:function(a){this.beginPullup(a)},endPullup:function(a){var c=this;c.pullLoading&&(c.pullLoading.classList.remove(d),c.pullLoading.classList.add(e),c.isLoading=!1,a?(c.finished=!0,c.pullCaption.className=g+" "+j,c.pullCaption.innerHTML=c.options.up.contentnomore,b.removeEventListener("plusscrollbottom",c),window.removeEventListener("dragup",c)):(c.pullCaption.className=g+" "+h,c.pullCaption.innerHTML=c.options.up.contentdown))},endPullupToRefresh:function(a){this.endPullup(a)},disablePulldownToRefresh:function(){var a=plus.webview.currentWebview();this.options.down.style&&"circle"==this.options.down.style?this.options.webview.setPullToRefresh({support:!1,style:"circle"}):(a.setStyle({bounce:"none"}),a.setBounce({position:{top:"none"}}))},enablePulldownToRefresh:function(){var a=this,b=plus.webview.currentWebview(),c=this.options.down.height;this.options.down.style&&"circle"==this.options.down.style?b.setPullToRefresh({support:!0,height:c||"50px",range:a.options.down.range||"100px",style:"circle",offset:a.options.down.offset||"0px"}):(b.setStyle({bounce:"vertical"}),b.setBounce({position:{top:2*c+"px"},changeoffset:{top:c+"px"}}))},disablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.className="mui-pull-bottom-pocket "+e,window.removeEventListener("dragup",this)},enablePullupToRefresh:function(){this._initPullupRefresh(),this.bottomPocket.classList.remove(e),this.pullCaption.className=g+" "+h,this.pullCaption.innerHTML=this.options.up.contentdown,b.addEventListener("plusscrollbottom",this),window.addEventListener("dragup",this)},scrollTo:function(b,c,d){a.scrollTo(c,d)},scrollToBottom:function(c){a.scrollTo(b.documentElement.scrollHeight,c)},refresh:function(a){a&&this.finished&&(this.enablePullupToRefresh(),this.finished=!1)}},a.PullRefresh));a.fn.pullRefresh_native=function(d){var e;0===this.length?(e=b.createElement("div"),e.className="mui-content",b.body.appendChild(e)):e=this[0];var f=d;d=d||{},"string"==typeof d&&(d=a.parseJSON(d)),!d.webviewId&&(d.webviewId=plus.webview.currentWebview().id||plus.webview.currentWebview().getURL());var g=null,h=d.webviewId&&d.webviewId.replace(/\//g,"_"),i=e.getAttribute("data-pullrefresh-plus-"+h);return i||"undefined"!=typeof f?(i?g=a.data[i]:(i=++a.uuid,e.setAttribute("data-pullrefresh-plus-"+h,i),b.body.classList.add(c),a.data[i]=g=new k(e,d)),d.down&&d.down.auto?g.beginPulldown():d.up&&d.up.auto&&g.beginPullup(),g):!1}}})}(mui,document),function(a,b,c,d){var e="mui-off-canvas-left",f="mui-off-canvas-right",g="mui-off-canvas-backdrop",h="mui-off-canvas-wrap",i="mui-slide-in",j="mui-active",k="mui-transitioning",l=".mui-inner-wrap",m=a.Class.extend({init:function(b,d){this.wrapper=this.element=b,this.scroller=this.wrapper.querySelector(l),this.classList=this.wrapper.classList,this.scroller&&(this.options=a.extend(!0,{dragThresholdX:10,scale:.8,opacity:.1,preventDefaultException:{tagName:/^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/}},d),c.body.classList.add("mui-fullscreen"),this.refresh(),this.initEvent())},_preventDefaultException:function(a,b){for(var c in b)if(b[c].test(a[c]))return!0;return!1},refresh:function(a){this.slideIn=this.classList.contains(i),this.scalable=this.classList.contains("mui-scalable")&&!this.slideIn,this.scroller=this.wrapper.querySelector(l),this.offCanvasLefts=this.wrapper.querySelectorAll("."+e),this.offCanvasRights=this.wrapper.querySelectorAll("."+f),a?a.classList.contains(e)?this.offCanvasLeft=a:a.classList.contains(f)&&(this.offCanvasRight=a):(this.offCanvasRight=this.wrapper.querySelector("."+f),this.offCanvasLeft=this.wrapper.querySelector("."+e)),this.offCanvasRightWidth=this.offCanvasLeftWidth=0,this.offCanvasLeftSlideIn=this.offCanvasRightSlideIn=!1,this.offCanvasRight&&(this.offCanvasRightWidth=this.offCanvasRight.offsetWidth,this.offCanvasRightSlideIn=this.slideIn&&this.offCanvasRight.parentNode===this.wrapper),this.offCanvasLeft&&(this.offCanvasLeftWidth=this.offCanvasLeft.offsetWidth,this.offCanvasLeftSlideIn=this.slideIn&&this.offCanvasLeft.parentNode===this.wrapper),this.backdrop=this.scroller.querySelector("."+g),this.options.dragThresholdX=this.options.dragThresholdX||10,this.visible=!1,this.startX=null,this.lastX=null,this.offsetX=null,this.lastTranslateX=null},handleEvent:function(b){switch(b.type){case a.EVENT_START:b.target&&!this._preventDefaultException(b.target,this.options.preventDefaultException)&&b.preventDefault();break;case"webkitTransitionEnd":b.target===this.scroller&&this._dispatchEvent();break;case"drag":var c=b.detail;this.startX?this.lastX=c.center.x:(this.startX=c.center.x,this.lastX=this.startX),!this.isDragging&&Math.abs(this.lastX-this.startX)>this.options.dragThresholdX&&("left"===c.direction||"right"===c.direction)&&(this.slideIn?(this.scroller=this.wrapper.querySelector(l),this.classList.contains(j)?this.offCanvasRight&&this.offCanvasRight.classList.contains(j)?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):"left"===c.direction&&this.offCanvasRight?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction&&this.offCanvasLeft?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):this.scroller=null):this.classList.contains(j)?"left"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):"right"===c.direction?(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth):(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth),this.offCanvas&&this.scroller&&(this.startX=this.lastX,this.isDragging=!0,a.gestures.session.lockDirection=!0,a.gestures.session.startDirection=c.direction,this.offCanvas.classList.remove(k),this.scroller.classList.remove(k),this.offsetX=this.getTranslateX(),this._initOffCanvasVisible())),this.isDragging&&(this.updateTranslate(this.offsetX+(this.lastX-this.startX)),c.gesture.preventDefault(),b.stopPropagation());break;case"dragend":if(this.isDragging){var c=b.detail,d=c.direction;this.isDragging=!1,this.offCanvas.classList.add(k),this.scroller.classList.add(k);var e=0,f=this.getTranslateX();if(this.slideIn){if(e=f>=0?this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0:this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0,"right"===d&&0>=e&&(e>=-.5||c.swipe)?this.openPercentage(100):"right"===d&&e>0&&(e>=.5||c.swipe)?this.openPercentage(0):"right"===d&&-.5>=e?this.openPercentage(0):"right"===d&&e>0&&.5>=e?this.openPercentage(-100):"left"===d&&e>=0&&(.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&0>e&&(-.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&e>=.5?this.openPercentage(0):"left"===d&&e>=-.5&&0>e?this.openPercentage(100):this.openPercentage(0),1===e||-1===e||0===e)return void this._dispatchEvent()}else{if(e=f>=0?this.offCanvasLeftWidth&&f/this.offCanvasLeftWidth||0:this.offCanvasRightWidth&&f/this.offCanvasRightWidth||0,0===e)return this.openPercentage(0),void this._dispatchEvent();"right"===d&&e>=0&&(e>=.5||c.swipe)?this.openPercentage(100):"right"===d&&0>e&&(e>-.5||c.swipe)?this.openPercentage(0):"right"===d&&e>0&&.5>e?this.openPercentage(0):"right"===d&&.5>e?this.openPercentage(-100):"left"===d&&0>=e&&(-.5>=e||c.swipe)?this.openPercentage(-100):"left"===d&&e>0&&(.5>=e||c.swipe)?this.openPercentage(0):"left"===d&&0>e&&e>=-.5?this.openPercentage(0):"left"===d&&e>.5?this.openPercentage(100):this.openPercentage(0),(1===e||-1===e)&&this._dispatchEvent()}}}},_dispatchEvent:function(){this.classList.contains(j)?a.trigger(this.wrapper,"shown",this):a.trigger(this.wrapper,"hidden",this)},_initOffCanvasVisible:function(){this.visible||(this.visible=!0,this.offCanvasLeft&&(this.offCanvasLeft.style.visibility="visible"),this.offCanvasRight&&(this.offCanvasRight.style.visibility="visible"))},initEvent:function(){var b=this;b.backdrop&&b.backdrop.addEventListener("tap",function(a){b.close(),a.detail.gesture.preventDefault()}),this.classList.contains("mui-draggable")&&(this.wrapper.addEventListener(a.EVENT_START,this),this.wrapper.addEventListener("drag",this),this.wrapper.addEventListener("dragend",this)),this.wrapper.addEventListener("webkitTransitionEnd",this)},openPercentage:function(a){var b=a/100;this.slideIn?(this.offCanvasLeft&&a>=0?(b=0===b?-1:0,this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==a?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(b=0===b?1:0,this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==a?"add":"remove"](j)),this.classList[0!==a?"add":"remove"](j)):(this.offCanvasLeft&&a>=0?(this.updateTranslate(this.offCanvasLeftWidth*b),this.offCanvasLeft.classList[0!==b?"add":"remove"](j)):this.offCanvasRight&&0>=a&&(this.updateTranslate(this.offCanvasRightWidth*b),this.offCanvasRight.classList[0!==b?"add":"remove"](j)),this.classList[0!==b?"add":"remove"](j))},updateTranslate:function(b){if(b!==this.lastTranslateX){if(this.slideIn){if(this.offCanvas.classList.contains(f)){if(0>b)return void this.setTranslateX(0);if(b>this.offCanvasRightWidth)return void this.setTranslateX(this.offCanvasRightWidth)}else{if(b>0)return void this.setTranslateX(0);if(b<-this.offCanvasLeftWidth)return void this.setTranslateX(-this.offCanvasLeftWidth)}this.setTranslateX(b)}else{if(!this.offCanvasLeft&&b>0||!this.offCanvasRight&&0>b)return void this.setTranslateX(0);if(this.leftShowing&&b>this.offCanvasLeftWidth)return void this.setTranslateX(this.offCanvasLeftWidth);if(this.rightShowing&&b<-this.offCanvasRightWidth)return void this.setTranslateX(-this.offCanvasRightWidth);this.setTranslateX(b),b>=0?(this.leftShowing=!0,this.rightShowing=!1,b>0&&(this.offCanvasLeft&&a.each(this.offCanvasLefts,function(a,b){b===this.offCanvasLeft?this.offCanvasLeft.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasRight&&(this.offCanvasRight.style.zIndex=-1))):(this.rightShowing=!0,this.leftShowing=!1,this.offCanvasRight&&a.each(this.offCanvasRights,function(a,b){b===this.offCanvasRight?b.style.zIndex=0:b.style.zIndex=-1}.bind(this)),this.offCanvasLeft&&(this.offCanvasLeft.style.zIndex=-1))}this.lastTranslateX=b}},setTranslateX:a.animationFrame(function(a){if(this.scroller)if(this.scalable&&this.offCanvas.parentNode===this.wrapper){var b=Math.abs(a)/this.offCanvasWidth,c=1-(1-this.options.scale)*b,d=this.options.scale+(1-this.options.scale)*b,f=(1-(1-this.options.opacity)*b,this.options.opacity+(1-this.options.opacity)*b);this.offCanvas.classList.contains(e)?(this.offCanvas.style.webkitTransformOrigin="-100%",this.scroller.style.webkitTransformOrigin="left"):(this.offCanvas.style.webkitTransformOrigin="200%",this.scroller.style.webkitTransformOrigin="right"),this.offCanvas.style.opacity=f,this.offCanvas.style.webkitTransform="translate3d(0,0,0) scale("+d+")",this.scroller.style.webkitTransform="translate3d("+a+"px,0,0) scale("+c+")"}else this.slideIn?this.offCanvas.style.webkitTransform="translate3d("+a+"px,0,0)":this.scroller.style.webkitTransform="translate3d("+a+"px,0,0)"}),getTranslateX:function(){if(this.offCanvas){var b=this.slideIn?this.offCanvas:this.scroller,c=a.parseTranslateMatrix(a.getStyles(b,"webkitTransform"));return c&&c.x||0}return 0},isShown:function(a){var b=!1;if(this.slideIn)b="left"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+e+"."+j):"right"===a?this.classList.contains(j)&&this.wrapper.querySelector("."+f+"."+j):this.classList.contains(j)&&(this.wrapper.querySelector("."+e+"."+j)||this.wrapper.querySelector("."+f+"."+j));else{var c=this.getTranslateX();b="right"===a?this.classList.contains(j)&&0>c:"left"===a?this.classList.contains(j)&&c>0:this.classList.contains(j)&&0!==c}return b},close:function(){this._initOffCanvasVisible(),this.offCanvas=this.wrapper.querySelector("."+f+"."+j)||this.wrapper.querySelector("."+e+"."+j),this.offCanvasWidth=this.offCanvas.offsetWidth,this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage(0))},show:function(a){return this._initOffCanvasVisible(),this.isShown(a)?!1:(a||(a=this.wrapper.querySelector("."+f)?"right":"left"),"right"===a?(this.offCanvas=this.offCanvasRight,this.offCanvasWidth=this.offCanvasRightWidth):(this.offCanvas=this.offCanvasLeft,this.offCanvasWidth=this.offCanvasLeftWidth),this.scroller&&(this.offCanvas.offsetHeight,this.offCanvas.classList.add(k),this.scroller.classList.add(k),this.openPercentage("left"===a?100:-100)),!0)},toggle:function(a){var b=a;a&&a.classList&&(b=a.classList.contains(e)?"left":"right",this.refresh(a)),this.show(b)||this.close()}}),n=function(a){if(parentNode=a.parentNode,parentNode){if(parentNode.classList.contains(h))return parentNode;if(parentNode=parentNode.parentNode,parentNode.classList.contains(h))return parentNode}},o=function(b,d){if("A"===d.tagName&&d.hash){var e=c.getElementById(d.hash.replace("#",""));if(e){var f=n(e);if(f)return a.targets._container=f,e}}return!1};a.registerTarget({name:d,index:60,handle:o,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){if(a.targets.offcanvas)for(var d=b.target;d&&d!==c;d=d.parentNode)if("A"===d.tagName&&d.hash&&d.hash==="#"+a.targets.offcanvas.id){b.detail&&b.detail.gesture&&b.detail.gesture.preventDefault(),a(a.targets._container).offCanvas().toggle(a.targets.offcanvas),a.targets.offcanvas=a.targets._container=null;break}}),a.fn.offCanvas=function(b){var c=[];return this.each(function(){var d=null,e=this;e.classList.contains(h)||(e=n(e));var f=e.getAttribute("data-offCanvas");f?d=a.data[f]:(f=++a.uuid,a.data[f]=d=new m(e,b),e.setAttribute("data-offCanvas",f)),("show"===b||"close"===b||"toggle"===b)&&d.toggle(),c.push(d)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-off-canvas-wrap").offCanvas()})}(mui,window,document,"offcanvas"),function(a,b){var c="mui-action",d=function(a,b){var d=b.className||"";return"string"!=typeof d&&(d=""),d&&~d.indexOf(c)?(b.classList.contains("mui-action-back")&&a.preventDefault(),b):!1};a.registerTarget({name:b,index:50,handle:d,target:!1,isContinue:!0})}(mui,"action"),function(a,b,c,d){var e="mui-modal",f=function(a,b){if("A"===b.tagName&&b.hash){var d=c.getElementById(b.hash.replace("#",""));if(d&&d.classList.contains(e))return d}return!1};a.registerTarget({name:d,index:50,handle:f,target:!1,isReset:!1,isContinue:!0}),b.addEventListener("tap",function(b){a.targets.modal&&(b.detail.gesture.preventDefault(),a.targets.modal.classList.toggle("mui-active"))})}(mui,window,document,"modal"),function(a,b,c,d){var e="mui-popover",f="mui-popover-arrow",g="mui-popover-action",h="mui-backdrop",i="mui-bar-popover",j="mui-bar-backdrop",k="mui-backdrop-action",l="mui-active",m="mui-bottom",n=function(b,d){if("A"===d.tagName&&d.hash){if(a.targets._popover=c.getElementById(d.hash.replace("#","")),a.targets._popover&&a.targets._popover.classList.contains(e))return d;a.targets._popover=null}return!1};a.registerTarget({name:d,index:60,handle:n,target:!1,isReset:!1,isContinue:!0});var o,p=function(b){this.removeEventListener("webkitTransitionEnd",p),this.addEventListener(a.EVENT_MOVE,a.preventDefault),a.trigger(this,"shown",this)},q=function(b){u(this,"none"),this.removeEventListener("webkitTransitionEnd",q),this.removeEventListener(a.EVENT_MOVE,a.preventDefault),a.trigger(this,"hidden",this)},r=function(){var b=c.createElement("div");return b.classList.add(h),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("tap",function(b){var c=a.targets._popover;c&&(c.addEventListener("webkitTransitionEnd",q),c.classList.remove(l),s(c))}),b}(),s=function(b){r.setAttribute("style","opacity:0"),a.targets.popover=a.targets._popover=null,o=a.later(function(){!b.classList.contains(l)&&r.parentNode&&r.parentNode===c.body&&c.body.removeChild(r)},350)};b.addEventListener("tap",function(b){if(a.targets.popover){for(var d=!1,e=b.target;e&&e!==c;e=e.parentNode)e===a.targets.popover&&(d=!0);d&&(b.detail.gesture.preventDefault(),t(a.targets._popover,a.targets.popover))}});var t=function(a,b,d){if(!("show"===d&&a.classList.contains(l)||"hide"===d&&!a.classList.contains(l))){o&&o.cancel(),a.removeEventListener("webkitTransitionEnd",p),a.removeEventListener("webkitTransitionEnd",q),r.classList.remove(j),r.classList.remove(k);var e=c.querySelector(".mui-popover.mui-active");if(e&&(e.addEventListener("webkitTransitionEnd",q),e.classList.remove(l),a===e))return void s(e);var f=!1;(a.classList.contains(i)||a.classList.contains(g))&&(a.classList.contains(g)?(f=!0,r.classList.add(k)):r.classList.add(j)),u(a,"block"),a.offsetHeight,a.classList.add(l),r.setAttribute("style",""),c.body.appendChild(r),v(a,b,f),r.classList.add(l),a.addEventListener("webkitTransitionEnd",p)}},u=function(a,b,c,d){var e=a.style;"undefined"!=typeof b&&(e.display=b),"undefined"!=typeof c&&(e.top=c+"px"),"undefined"!=typeof d&&(e.left=d+"px")},v=function(d,e,h){if(d&&e){if(h)return void u(d,"block");var i=b.innerWidth,j=b.innerHeight,k=d.offsetWidth,l=d.offsetHeight,n=e.offsetWidth,o=e.offsetHeight,p=a.offset(e),q=d.querySelector("."+f);q||(q=c.createElement("div"),q.className=f,d.appendChild(q));var r=q&&q.offsetWidth/2||0,s=0,t=0,v=0,w=0,x=d.classList.contains(g)?0:5,y="top";l+r<p.top-b.pageYOffset?s=p.top-l-r:l+r<j-(p.top-b.pageYOffset)-o?(y="bottom",s=p.top+o+r):(y="middle",s=Math.max((j-l)/2+b.pageYOffset,0),t=Math.max((i-k)/2+b.pageXOffset,0)),"top"===y||"bottom"===y?(t=n/2+p.left-k/2,v=t,x>t&&(t=x),t+k>i&&(t=i-k-x),q&&("top"===y?q.classList.add(m):q.classList.remove(m),v-=t,w=k/2-r/2+v,w=Math.max(Math.min(w,k-2*r-6),6),q.setAttribute("style","left:"+w+"px"))):"middle"===y&&q.setAttribute("style","display:none"),u(d,"block",s,t)}};a.createMask=function(b){var d=c.createElement("div");d.classList.add(h),d.addEventListener(a.EVENT_MOVE,a.preventDefault),d.addEventListener("tap",function(){e.close()});var e=[d];return e._show=!1,e.show=function(){return e._show=!0,d.setAttribute("style","opacity:1"),c.body.appendChild(d),e},e._remove=function(){return e._show&&(e._show=!1,d.setAttribute("style","opacity:0"),a.later(function(){var a=c.body;d.parentNode===a&&a.removeChild(d)},350)),e},e.close=function(){b?b()!==!1&&e._remove():e._remove()},e},a.fn.popover=function(){var b=arguments;this.each(function(){a.targets._popover=this,("show"===b[0]||"hide"===b[0]||"toggle"===b[0])&&t(this,b[1],b[0])})}}(mui,window,document,"popover"),function(a,b,c,d,e){var f="mui-control-item",g="mui-segmented-control",h="mui-segmented-control-vertical",i="mui-control-content",j="mui-bar-tab",k="mui-tab-item",l=function(a,b){return b.classList&&(b.classList.contains(f)||b.classList.contains(k))?(b.parentNode&&b.parentNode.classList&&b.parentNode.classList.contains(h)||a.preventDefault(),b):!1};a.registerTarget({name:d,index:80,handle:l,target:!1}),b.addEventListener("tap",function(b){var e=a.targets.tab;if(e){for(var h,l,m,n="mui-active",o="."+n,p=e.parentNode;p&&p!==c;p=p.parentNode){if(p.classList.contains(g)){h=p.querySelector(o+"."+f);break}p.classList.contains(j)&&(h=p.querySelector(o+"."+k))}h&&h.classList.remove(n);var q=e===h;if(e&&e.classList.add(n),e.hash&&(m=c.getElementById(e.hash.replace("#","")))){if(!m.classList.contains(i))return void e.classList[q?"remove":"add"](n);if(!q){var r=m.parentNode;l=r.querySelectorAll("."+i+o);for(var s=0;s<l.length;s++){var t=l[s];t.parentNode===r&&t.classList.remove(n)}m.classList.add(n);for(var u=[],v=r.querySelectorAll("."+i),s=0;s<v.length;s++)v[s].parentNode===r&&u.push(v[s]);a.trigger(m,a.eventName("shown",d),{tabNumber:Array.prototype.indexOf.call(u,m)}),b.detail&&b.detail.gesture.preventDefault()}}}})}(mui,window,document,"tab"),function(a,b,c){var d="mui-switch",e="mui-switch-handle",f="mui-active",g="mui-dragging",h="mui-disabled",i="."+e,j=function(a,b){return b.classList&&b.classList.contains(d)?b:!1};a.registerTarget({name:c,index:100,handle:j,target:!1});var k=function(a){this.element=a,this.classList=this.element.classList,this.handle=this.element.querySelector(i),this.init(),this.initEvent()};k.prototype.init=function(){this.toggleWidth=this.element.offsetWidth,this.handleWidth=this.handle.offsetWidth,this.handleX=this.toggleWidth-this.handleWidth-3},k.prototype.initEvent=function(){this.element.addEventListener(a.EVENT_START,this),this.element.addEventListener("drag",this),this.element.addEventListener("swiperight",this),this.element.addEventListener(a.EVENT_END,this),this.element.addEventListener(a.EVENT_CANCEL,this)},k.prototype.handleEvent=function(b){if(!this.classList.contains(h))switch(b.type){case a.EVENT_START:this.start(b);break;case"drag":this.drag(b);break;case"swiperight":this.swiperight();break;case a.EVENT_END:case a.EVENT_CANCEL:this.end(b)}},k.prototype.start=function(a){this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration=".2s", +this.classList.add(g),(0===this.toggleWidth||0===this.handleWidth)&&this.init()},k.prototype.drag=function(a){var b=a.detail;this.isDragging||("left"===b.direction||"right"===b.direction)&&(this.isDragging=!0,this.lastChanged=void 0,this.initialState=this.classList.contains(f)),this.isDragging&&(this.setTranslateX(b.deltaX),a.stopPropagation(),b.gesture.preventDefault())},k.prototype.swiperight=function(a){this.isDragging&&a.stopPropagation()},k.prototype.end=function(b){this.classList.remove(g),this.isDragging?(this.isDragging=!1,b.stopPropagation(),a.trigger(this.element,"toggle",{isActive:this.classList.contains(f)})):this.toggle()},k.prototype.toggle=function(b){var c=this.classList;b===!1?this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration="0s":this.handle.style.webkitTransitionDuration=this.element.style.webkitTransitionDuration=".2s",c.contains(f)?(c.remove(f),this.handle.style.webkitTransform="translate(0,0)"):(c.add(f),this.handle.style.webkitTransform="translate("+this.handleX+"px,0)"),a.trigger(this.element,"toggle",{isActive:this.classList.contains(f)})},k.prototype.setTranslateX=a.animationFrame(function(a){if(this.isDragging){var b=!1;(this.initialState&&-a>this.handleX/2||!this.initialState&&a>this.handleX/2)&&(b=!0),this.lastChanged!==b&&(b?(this.handle.style.webkitTransform="translate("+(this.initialState?0:this.handleX)+"px,0)",this.classList[this.initialState?"remove":"add"](f)):(this.handle.style.webkitTransform="translate("+(this.initialState?this.handleX:0)+"px,0)",this.classList[this.initialState?"add":"remove"](f)),this.lastChanged=b)}}),a.fn["switch"]=function(b){var c=[];return this.each(function(){var b=null,d=this.getAttribute("data-switch");d?b=a.data[d]:(d=++a.uuid,a.data[d]=new k(this),this.setAttribute("data-switch",d)),c.push(b)}),c.length>1?c:c[0]},a.ready(function(){a("."+d)["switch"]()})}(mui,window,"toggle"),function(a,b,c){function d(a,b){var c=b?"removeEventListener":"addEventListener";a[c]("drag",F),a[c]("dragend",F),a[c]("swiperight",F),a[c]("swipeleft",F),a[c]("flick",F)}var e,f,g="mui-active",h="mui-selected",i="mui-grid-view",j="mui-table-view-radio",k="mui-table-view-cell",l="mui-collapse-content",m="mui-disabled",n="mui-switch",o="mui-btn",p="mui-slider-handle",q="mui-slider-left",r="mui-slider-right",s="mui-transitioning",t="."+p,u="."+q,v="."+r,w="."+h,x="."+o,y=.8,z=isOpened=openedActions=progress=!1,A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,B=translateX=lastTranslateX=sliderActionLeftWidth=sliderActionRightWidth=0,C=function(a){a?f?f.classList.add(g):e&&e.classList.add(g):(B&&B.cancel(),f?f.classList.remove(g):e&&e.classList.remove(g))},D=function(){if(translateX!==lastTranslateX){if(buttonsRight&&buttonsRight.length>0){progress=translateX/sliderActionRightWidth,translateX<-sliderActionRightWidth&&(translateX=-sliderActionRightWidth-Math.pow(-translateX-sliderActionRightWidth,y));for(var a=0,b=buttonsRight.length;b>a;a++){var c=buttonsRight[a];"undefined"==typeof c._buttonOffset&&(c._buttonOffset=c.offsetLeft),buttonOffset=c._buttonOffset,E(c,translateX-buttonOffset*(1+Math.max(progress,-1)))}}if(buttonsLeft&&buttonsLeft.length>0){progress=translateX/sliderActionLeftWidth,translateX>sliderActionLeftWidth&&(translateX=sliderActionLeftWidth+Math.pow(translateX-sliderActionLeftWidth,y));for(var a=0,b=buttonsLeft.length;b>a;a++){var d=buttonsLeft[a];"undefined"==typeof d._buttonOffset&&(d._buttonOffset=sliderActionLeftWidth-d.offsetLeft-d.offsetWidth),buttonOffset=d._buttonOffset,buttonsLeft.length>1&&(d.style.zIndex=buttonsLeft.length-a),E(d,translateX+buttonOffset*(1-Math.min(progress,1)))}}E(A,translateX),lastTranslateX=translateX}sliderRequestAnimationFrame=requestAnimationFrame(function(){D()})},E=function(a,b){a&&(a.style.webkitTransform="translate("+b+"px,0)")};b.addEventListener(a.EVENT_START,function(b){e&&C(!1),e=f=!1,z=isOpened=openedActions=!1;for(var g=b.target,h=!1;g&&g!==c;g=g.parentNode)if(g.classList){var p=g.classList;if(("INPUT"===g.tagName&&"radio"!==g.type&&"checkbox"!==g.type||"BUTTON"===g.tagName||p.contains(n)||p.contains(o)||p.contains(m))&&(h=!0),p.contains(l))break;if(p.contains(k)){e=g;var q=e.parentNode.querySelector(w);if(!e.parentNode.classList.contains(j)&&q&&q!==e)return a.swipeoutClose(q),void(e=h=!1);if(!e.parentNode.classList.contains(i)){var r=e.querySelector("a");r&&r.parentNode===e&&(f=r)}var s=e.querySelector(t);s&&(d(e),b.stopPropagation()),h||(s?(B&&B.cancel(),B=a.later(function(){C(!0)},100)):C(!0));break}}}),b.addEventListener(a.EVENT_MOVE,function(a){C(!1)});var F={handleEvent:function(a){switch(a.type){case"drag":this.drag(a);break;case"dragend":this.dragend(a);break;case"flick":this.flick(a);break;case"swiperight":this.swiperight(a);break;case"swipeleft":this.swipeleft(a)}},drag:function(a){if(e){z||(A=sliderActionLeft=sliderActionRight=buttonsLeft=buttonsRight=sliderDirection=sliderRequestAnimationFrame=!1,A=e.querySelector(t),A&&(sliderActionLeft=e.querySelector(u),sliderActionRight=e.querySelector(v),sliderActionLeft&&(sliderActionLeftWidth=sliderActionLeft.offsetWidth,buttonsLeft=sliderActionLeft.querySelectorAll(x)),sliderActionRight&&(sliderActionRightWidth=sliderActionRight.offsetWidth,buttonsRight=sliderActionRight.querySelectorAll(x)),e.classList.remove(s),isOpened=e.classList.contains(h),isOpened&&(openedActions=e.querySelector(u+w)?"left":"right")));var b=a.detail,c=b.direction,d=b.angle;if("left"===c&&(d>150||-150>d)?(buttonsRight||buttonsLeft&&isOpened)&&(z=!0):"right"===c&&d>-30&&30>d&&(buttonsLeft||buttonsRight&&isOpened)&&(z=!0),z){a.stopPropagation(),a.detail.gesture.preventDefault();var f=a.detail.deltaX;if(isOpened&&("right"===openedActions?f-=sliderActionRightWidth:f+=sliderActionLeftWidth),f>0&&!buttonsLeft||0>f&&!buttonsRight){if(!isOpened)return;f=0}0>f?sliderDirection="toLeft":f>0?sliderDirection="toRight":sliderDirection||(sliderDirection="toLeft"),sliderRequestAnimationFrame||D(),translateX=f}}},flick:function(a){z&&a.stopPropagation()},swipeleft:function(a){z&&a.stopPropagation()},swiperight:function(a){z&&a.stopPropagation()},dragend:function(b){if(z){b.stopPropagation(),sliderRequestAnimationFrame&&(cancelAnimationFrame(sliderRequestAnimationFrame),sliderRequestAnimationFrame=null);var c=b.detail;z=!1;var d="close",f="toLeft"===sliderDirection?sliderActionRightWidth:sliderActionLeftWidth,g=c.swipe||Math.abs(translateX)>f/2;g&&(isOpened?"left"===c.direction&&"right"===openedActions?d="open":"right"===c.direction&&"left"===openedActions&&(d="open"):d="open"),e.classList.add(s);var i;if("open"===d){var j="toLeft"===sliderDirection?-f:f;if(E(A,j),i="toLeft"===sliderDirection?buttonsRight:buttonsLeft,"undefined"!=typeof i){for(var k=null,l=0;l<i.length;l++)k=i[l],E(k,j);k.parentNode.classList.add(h),e.classList.add(h),isOpened||a.trigger(e,"toLeft"===sliderDirection?"slideleft":"slideright")}}else E(A,0),sliderActionLeft&&sliderActionLeft.classList.remove(h),sliderActionRight&&sliderActionRight.classList.remove(h),e.classList.remove(h);var m;if(buttonsLeft&&buttonsLeft.length>0&&buttonsLeft!==i)for(var l=0,n=buttonsLeft.length;n>l;l++){var o=buttonsLeft[l];m=o._buttonOffset,"undefined"==typeof m&&(o._buttonOffset=sliderActionLeftWidth-o.offsetLeft-o.offsetWidth),E(o,m)}if(buttonsRight&&buttonsRight.length>0&&buttonsRight!==i)for(var l=0,n=buttonsRight.length;n>l;l++){var p=buttonsRight[l];m=p._buttonOffset,"undefined"==typeof m&&(p._buttonOffset=p.offsetLeft),E(p,-m)}}}};a.swipeoutOpen=function(b,c){if(b){var d=b.classList;if(!d.contains(h)){c||(c=b.querySelector(v)?"right":"left");var e=b.querySelector(a.classSelector(".slider-"+c));if(e){e.classList.add(h),d.add(h),d.remove(s);for(var f,g=e.querySelectorAll(x),i=e.offsetWidth,j="right"===c?-i:i,k=g.length,l=0;k>l;l++)f=g[l],"right"===c?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft);d.add(s);for(var l=0;k>l;l++)E(g[l],j);E(b.querySelector(t),j)}}}},a.swipeoutClose=function(b){if(b){var c=b.classList;if(c.contains(h)){var d=b.querySelector(v+w)?"right":"left",e=b.querySelector(a.classSelector(".slider-"+d));if(e){e.classList.remove(h),c.remove(h),c.add(s);var f,g=e.querySelectorAll(x),i=e.offsetWidth,j=g.length;E(b.querySelector(t),0);for(var k=0;j>k;k++)f=g[k],"right"===d?E(f,-f.offsetLeft):E(f,i-f.offsetWidth-f.offsetLeft)}}}},b.addEventListener(a.EVENT_END,function(a){e&&(C(!1),A&&d(e,!0))}),b.addEventListener(a.EVENT_CANCEL,function(a){e&&(C(!1),A&&d(e,!0))});var G=function(b){var c=b.target&&b.target.type||"";if("radio"!==c&&"checkbox"!==c){var d=e.classList;if(d.contains("mui-radio")){var f=e.querySelector("input[type=radio]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}else if(d.contains("mui-checkbox")){var f=e.querySelector("input[type=checkbox]");f&&(f.disabled||f.readOnly||(f.checked=!f.checked,a.trigger(f,"change")))}}};b.addEventListener(a.EVENT_CLICK,function(a){e&&e.classList.contains("mui-collapse")&&a.preventDefault()}),b.addEventListener("doubletap",function(a){e&&G(a)});var H=/^(INPUT|TEXTAREA|BUTTON|SELECT)$/;b.addEventListener("tap",function(b){if(e){var c=!1,d=e.classList,f=e.parentNode;if(f&&f.classList.contains(j)){if(d.contains(h))return;var i=f.querySelector("li"+w);return i&&i.classList.remove(h),d.add(h),void a.trigger(e,"selected",{el:e})}if(d.contains("mui-collapse")&&!e.parentNode.classList.contains("mui-unfold")){if(H.test(b.target.tagName)||b.detail.gesture.preventDefault(),!d.contains(g)){var k=e.parentNode.querySelector(".mui-collapse.mui-active");k&&k.classList.remove(g),c=!0}d.toggle(g),c&&a.trigger(e,"expand")}else G(b)}})}(mui,window,document),function(a,b){a.alert=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e="确定"):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.alert(c,f,d,e)})}else b.alert(c)}}(mui,window),function(a,b){a.confirm=function(c,d,e,f){if(a.os.plus){if("undefined"==typeof c)return;"function"==typeof d?(f=d,d=null,e=null):"function"==typeof e&&(f=e,e=null),a.plusReady(function(){plus.nativeUI.confirm(c,f,d,e)})}else f(b.confirm(c)?{index:0}:{index:1})}}(mui,window),function(a,b){a.prompt=function(c,d,e,f,g){if(a.os.plus){if("undefined"==typeof message)return;"function"==typeof d?(g=d,d=null,e=null,f=null):"function"==typeof e?(g=e,e=null,f=null):"function"==typeof f&&(g=f,f=null),a.plusReady(function(){plus.nativeUI.prompt(c,g,e,d,f)})}else{var h=b.prompt(c);g(h?{index:0,value:h}:{index:1,value:""})}}}(mui,window),function(a,b){var c="mui-active";a.toast=function(b,d){var e={"long":3500,"short":2e3};if(d=a.extend({duration:"short"},d||{}),!a.os.plus||"div"===d.type){"number"==typeof d.duration?duration=d.duration>0?d.duration:e["short"]:duration=e[d.duration],duration||(duration=e["short"]);var f=document.createElement("div");return f.classList.add("mui-toast-container"),f.innerHTML='<div class="mui-toast-message">'+b+"</div>",f.addEventListener("webkitTransitionEnd",function(){f.classList.contains(c)||(f.parentNode.removeChild(f),f=null)}),f.addEventListener("click",function(){f.parentNode.removeChild(f),f=null}),document.body.appendChild(f),f.offsetHeight,f.classList.add(c),setTimeout(function(){f&&f.classList.remove(c)},duration),{isVisible:function(){return!!f}}}a.plusReady(function(){plus.nativeUI.toast(b,{verticalAlign:"bottom",duration:d.duration})})}}(mui,window),function(a,b,c){var d="mui-popup",e="mui-popup-backdrop",f="mui-popup-in",g="mui-popup-out",h="mui-popup-inner",i="mui-popup-title",j="mui-popup-text",k="mui-popup-input",l="mui-popup-buttons",m="mui-popup-button",n="mui-popup-button-bold",e="mui-popup-backdrop",o="mui-active",p=[],q=function(){var b=c.createElement("div");return b.classList.add(e),b.addEventListener(a.EVENT_MOVE,a.preventDefault),b.addEventListener("webkitTransitionEnd",function(){this.classList.contains(o)||b.parentNode&&b.parentNode.removeChild(b)}),b}(),r=function(a){return'<div class="'+k+'"><input type="text" autofocus placeholder="'+(a||"")+'"/></div>'},s=function(a,b,c){return'<div class="'+h+'"><div class="'+i+'">'+b+'</div><div class="'+j+'">'+a.replace(/\r\n/g,"<br/>").replace(/\n/g,"<br/>")+"</div>"+(c||"")+"</div>"},t=function(a){for(var b=a.length,c=[],d=0;b>d;d++)c.push('<span class="'+m+(d===b-1?" "+n:"")+'">'+a[d]+"</span>");return'<div class="'+l+'">'+c.join("")+"</div>"},u=function(b,e){var h=c.createElement("div");h.className=d,h.innerHTML=b;var i=function(){h.parentNode&&h.parentNode.removeChild(h),h=null};h.addEventListener(a.EVENT_MOVE,a.preventDefault),h.addEventListener("webkitTransitionEnd",function(a){h&&a.target===h&&h.classList.contains(g)&&i()}),h.style.display="block",c.body.appendChild(h),h.offsetHeight,h.classList.add(f),q.classList.contains(o)||(q.style.display="block",c.body.appendChild(q),q.offsetHeight,q.classList.add(o));var j=a.qsa("."+m,h),l=h.querySelector("."+k+" input"),n={element:h,close:function(a,b){if(h){var c=e&&e({index:a||0,value:l&&l.value||""});if(c===!1)return;b!==!1?(h.classList.remove(f),h.classList.add(g)):i(),p.pop(),p.length?p[p.length-1].show(b):q.classList.remove(o)}}},r=function(a){n.close(j.indexOf(a.target))};return a(h).on("tap","."+m,r),p.length&&p[p.length-1].hide(),p.push({close:n.close,show:function(a){h.style.display="block",h.offsetHeight,h.classList.add(f)},hide:function(){h.style.display="none",h.classList.remove(f)}}),n},v=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.alert(b,e,c||"提示",d||"确定"):u(s(b,c||"提示")+t([d||"确定"]),e)):void 0},w=function(b,c,d,e,f){return"undefined"!=typeof b?("function"==typeof c?(e=c,f=d,c=null,d=null):"function"==typeof d&&(f=e,e=d,d=null),a.os.plus&&"div"!==f?plus.nativeUI.confirm(b,e,c,d||["取消","确认"]):u(s(b,c||"提示")+t(d||["取消","确认"]),e)):void 0},x=function(b,c,d,e,f,g){return"undefined"!=typeof b?("function"==typeof c?(f=c,g=d,c=null,d=null,e=null):"function"==typeof d?(f=d,g=e,d=null,e=null):"function"==typeof e&&(g=f,f=e,e=null),a.os.plus&&"div"!==g?plus.nativeUI.prompt(b,f,d||"提示",c,e||["取消","确认"]):u(s(b,d||"提示",r(c))+t(e||["取消","确认"]),f)):void 0},y=function(){return p.length?(p[p.length-1].close(),!0):!1},z=function(){for(;p.length;)p[p.length-1].close()};a.closePopup=y,a.closePopups=z,a.alert=v,a.confirm=w,a.prompt=x}(mui,window,document),function(a,b){var c="mui-progressbar",d="mui-progressbar-in",e="mui-progressbar-out",f="mui-progressbar-infinite",g=".mui-progressbar",h=function(b){if(b=a(b||"body"),0!==b.length){if(b=b[0],b.classList.contains(c))return b;var d=b.querySelectorAll(g);if(d)for(var e=0,f=d.length;f>e;e++){var h=d[e];if(h.parentNode===b)return h}}},i=function(h,i,j){if("number"==typeof h&&(j=i,i=h,h="body"),h=a(h||"body"),0!==h.length){h=h[0];var l;if(h.classList.contains(c))l=h;else{var m=h.querySelectorAll(g+":not(."+e+")");if(m)for(var n=0,o=m.length;o>n;n++){var p=m[n];if(p.parentNode===h){l=p;break}}l?l.classList.add(d):(l=b.createElement("span"),l.className=c+" "+d+("undefined"!=typeof i?"":" "+f)+(j?" "+c+"-"+j:""),"undefined"!=typeof i&&(l.innerHTML="<span></span>"),h.appendChild(l))}return i&&k(h,i),l}},j=function(a){var b=h(a);if(b){var c=b.classList;c.contains(d)&&!c.contains(e)&&(c.remove(d),c.add(e),b.addEventListener("webkitAnimationEnd",function(){b.parentNode&&b.parentNode.removeChild(b),b=null}))}},k=function(a,b,c){"number"==typeof a&&(c=b,b=a,a=!1);var d=h(a);if(d&&!d.classList.contains(f)){b&&(b=Math.min(Math.max(b,0),100)),d.offsetHeight;var e=d.querySelector("span");if(e){var g=e.style;g.webkitTransform="translate3d("+(-100+b)+"%,0,0)","undefined"!=typeof c?g.webkitTransitionDuration=c+"ms":g.webkitTransitionDuration=""}return d}};a.fn.progressbar=function(a){var b=[];return a=a||{},this.each(function(){var c=this,d=c.mui_plugin_progressbar;d?a&&d.setOptions(a):c.mui_plugin_progressbar=d={options:a,setOptions:function(a){this.options=a},show:function(){return i(c,this.options.progress,this.options.color)},setProgress:function(a){return k(c,a)},hide:function(){return j(c)}},b.push(d)}),1===b.length?b[0]:b}}(mui,document),function(a,b,c){var d="mui-icon",e="mui-icon-clear",f="mui-icon-speech",g="mui-icon-search",h="mui-icon-eye",i="mui-input-row",j="mui-placeholder",k="mui-tooltip",l="mui-hidden",m="mui-focusin",n="."+e,o="."+f,p="."+h,q="."+j,r="."+k,s=function(a){for(;a&&a!==c;a=a.parentNode)if(a.classList&&a.classList.contains(i))return a;return null},t=function(a,b){this.element=a,this.options=b||{actions:"clear"},~this.options.actions.indexOf("slider")?(this.sliderActionClass=k+" "+l,this.sliderActionSelector=r):(~this.options.actions.indexOf("clear")&&(this.clearActionClass=d+" "+e+" "+l,this.clearActionSelector=n),~this.options.actions.indexOf("speech")&&(this.speechActionClass=d+" "+f,this.speechActionSelector=o),~this.options.actions.indexOf("search")&&(this.searchActionClass=j,this.searchActionSelector=q),~this.options.actions.indexOf("password")&&(this.passwordActionClass=d+" "+h,this.passwordActionSelector=p)),this.init()};t.prototype.init=function(){this.initAction(),this.initElementEvent()},t.prototype.initAction=function(){var b=this,c=b.element.parentNode;c&&(b.sliderActionClass?b.sliderAction=b.createAction(c,b.sliderActionClass,b.sliderActionSelector):(b.searchActionClass&&(b.searchAction=b.createAction(c,b.searchActionClass,b.searchActionSelector),b.searchAction.addEventListener("tap",function(c){a.focus(b.element),c.stopPropagation()})),b.speechActionClass&&(b.speechAction=b.createAction(c,b.speechActionClass,b.speechActionSelector),b.speechAction.addEventListener("click",a.stopPropagation),b.speechAction.addEventListener("tap",function(a){b.speechActionClick(a)})),b.clearActionClass&&(b.clearAction=b.createAction(c,b.clearActionClass,b.clearActionSelector),b.clearAction.addEventListener("tap",function(a){b.clearActionClick(a)})),b.passwordActionClass&&(b.passwordAction=b.createAction(c,b.passwordActionClass,b.passwordActionSelector),b.passwordAction.addEventListener("tap",function(a){b.passwordActionClick(a)}))))},t.prototype.createAction=function(a,b,e){var f=a.querySelector(e);if(!f){var f=c.createElement("span");f.className=b,b===this.searchActionClass&&(f.innerHTML='<span class="'+d+" "+g+'"></span><span>'+this.element.getAttribute("placeholder")+"</span>",this.element.setAttribute("placeholder",""),this.element.value.trim()&&a.classList.add("mui-active")),a.insertBefore(f,this.element.nextSibling)}return f},t.prototype.initElementEvent=function(){var b=this.element;if(this.sliderActionClass){var c=this.sliderAction,d=null,e=function(){c.classList.remove(l);var a=b.offsetLeft,e=b.offsetWidth-28,f=c.offsetWidth,g=Math.abs(b.max-b.min),h=e/g*Math.abs(b.value-b.min);c.style.left=14+a+h-f/2+"px",c.innerText=b.value,d&&clearTimeout(d),d=setTimeout(function(){c.classList.add(l)},1e3)};b.addEventListener("input",e),b.addEventListener("tap",e),b.addEventListener(a.EVENT_MOVE,function(a){a.stopPropagation()})}else{if(this.clearActionClass){var f=this.clearAction;if(!f)return;a.each(["keyup","change","input","focus","cut","paste"],function(a,c){!function(a){b.addEventListener(a,function(){f.classList[b.value.trim()?"remove":"add"](l)})}(c)}),b.addEventListener("blur",function(){f.classList.add(l)})}this.searchActionClass&&(b.addEventListener("focus",function(){b.parentNode.classList.add("mui-active")}),b.addEventListener("blur",function(){b.value.trim()||b.parentNode.classList.remove("mui-active")}))}},t.prototype.setPlaceholder=function(a){if(this.searchActionClass){var b=this.element.parentNode.querySelector(q);b&&(b.getElementsByTagName("span")[1].innerText=a)}else this.element.setAttribute("placeholder",a)},t.prototype.passwordActionClick=function(a){"text"===this.element.type?this.element.type="password":this.element.type="text",this.passwordAction.classList.toggle("mui-active"),a.preventDefault()},t.prototype.clearActionClick=function(b){var c=this;c.element.value="",a.focus(c.element),c.clearAction.classList.add(l),b.preventDefault()},t.prototype.speechActionClick=function(d){if(b.plus){var e=this,f=e.element.value;e.element.value="",c.body.classList.add(m),plus.speech.startRecognize({engine:"iFly"},function(b){e.element.value+=b,a.focus(e.element),plus.speech.stopRecognize(),a.trigger(e.element,"recognized",{value:e.element.value}),f!==e.element.value&&(a.trigger(e.element,"change"),a.trigger(e.element,"input"))},function(a){c.body.classList.remove(m)})}else alert("only for 5+");d.preventDefault()},a.fn.input=function(b){var c=[];return this.each(function(){var b=null,d=[],e=s(this.parentNode);if("range"===this.type&&e.classList.contains("mui-input-range"))d.push("slider");else{var f=this.classList;f.contains("mui-input-clear")&&d.push("clear"),a.os.android&&a.os.stream||!f.contains("mui-input-speech")||d.push("speech"),f.contains("mui-input-password")&&d.push("password"),"search"===this.type&&e.classList.contains("mui-search")&&d.push("search")}var g=this.getAttribute("data-input-"+d[0]);if(g)b=a.data[g];else{g=++a.uuid,b=a.data[g]=new t(this,{actions:d.join(",")});for(var h=0,i=d.length;i>h;h++)this.setAttribute("data-input-"+d[h],g)}c.push(b)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-input-row input").input()})}(mui,window,document),function(a,b){var c="mui-active",d=/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/,e=function(a){var b=a.match(d);return b&&5===b.length?[b[1],b[2],b[3],b[4]]:[]},f=function(c,d){if(this.element=c,this.options=a.extend({top:0,offset:150,duration:16,scrollby:b},d||{}),this.scrollByElem=this.options.scrollby||b,!this.scrollByElem)throw new Error("监听滚动的元素不存在");this.isNativeScroll=!1,this.scrollByElem===b?this.isNativeScroll=!0:~this.scrollByElem.className.indexOf("mui-scroll-wrapper")||(this.isNativeScroll=!0),this._style=this.element.style,this._bgColor=this._style.backgroundColor;var f=e(mui.getStyles(this.element,"backgroundColor"));if(!f.length)throw new Error("元素背景颜色必须为RGBA");this._R=f[0],this._G=f[1],this._B=f[2],this._A=parseFloat(f[3]),this.lastOpacity=this._A,this._bufferFn=a.buffer(this.handleScroll,this.options.duration,this),this.initEvent()};f.prototype.initEvent=function(){this.scrollByElem.addEventListener("scroll",this._bufferFn),this.isNativeScroll&&this.scrollByElem.addEventListener(a.EVENT_MOVE,this._bufferFn)},f.prototype.handleScroll=function(d){var e=b.scrollY;!this.isNativeScroll&&d&&d.detail&&(e=-d.detail.y);var f=(e-this.options.top)/this.options.offset+this._A;f=Math.min(Math.max(this._A,f),1),this._style.backgroundColor="rgba("+this._R+","+this._G+","+this._B+","+f+")",f>this._A?this.element.classList.add(c):this.element.classList.remove(c),this.lastOpacity!==f&&(a.trigger(this.element,"alpha",{alpha:f}),this.lastOpacity=f)},f.prototype.destory=function(){this.scrollByElem.removeEventListener("scroll",this._bufferFn),this.scrollByElem.removeEventListener(a.EVENT_MOVE,this._bufferFn),this.element.style.backgroundColor=this._bgColor,this.element.mui_plugin_transparent=null},a.fn.transparent=function(a){a=a||{};var c=[];return this.each(function(){var d=this.mui_plugin_transparent;if(!d){var e=this.getAttribute("data-top"),g=this.getAttribute("data-offset"),h=this.getAttribute("data-duration"),i=this.getAttribute("data-scrollby");null!==e&&"undefined"==typeof a.top&&(a.top=e),null!==g&&"undefined"==typeof a.offset&&(a.offset=g),null!==h&&"undefined"==typeof a.duration&&(a.duration=h),null!==i&&"undefined"==typeof a.scrollby&&(a.scrollby=document.querySelector(i)||b),d=this.mui_plugin_transparent=new f(this,a)}c.push(d)}),1===c.length?c[0]:c},a.ready(function(){a(".mui-bar-transparent").transparent()})}(mui,window),function(a){var b="ontouchstart"in document,c=b?"tap":"click",d="change",e="mui-numbox",f=".mui-btn-numbox-plus,.mui-numbox-btn-plus",g=".mui-btn-numbox-minus,.mui-numbox-btn-minus",h=".mui-input-numbox,.mui-numbox-input",i=a.Numbox=a.Class.extend({init:function(b,c){var d=this;if(!b)throw"构造 numbox 时缺少容器元素";d.holder=b,c=c||{},c.step=parseInt(c.step||1),d.options=c,d.input=a.qsa(h,d.holder)[0],d.plus=a.qsa(f,d.holder)[0],d.minus=a.qsa(g,d.holder)[0],d.checkValue(),d.initEvent()},initEvent:function(){var b=this;b.plus.addEventListener(c,function(c){var e=parseInt(b.input.value)+b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.minus.addEventListener(c,function(c){var e=parseInt(b.input.value)-b.options.step;b.input.value=e.toString(),a.trigger(b.input,d,null)}),b.input.addEventListener(d,function(c){b.checkValue();var e=parseInt(b.input.value);a.trigger(b.holder,d,{value:e})})},getValue:function(){var a=this;return parseInt(a.input.value)},checkValue:function(){var a=this,b=a.input.value;if(null==b||""==b||isNaN(b))a.input.value=a.options.min||0,a.minus.disabled=null!=a.options.min;else{var b=parseInt(b);null!=a.options.max&&!isNaN(a.options.max)&&b>=parseInt(a.options.max)?(b=a.options.max,a.plus.disabled=!0):a.plus.disabled=!1,null!=a.options.min&&!isNaN(a.options.min)&&b<=parseInt(a.options.min)?(b=a.options.min,a.minus.disabled=!0):a.minus.disabled=!1,a.input.value=b}},setOption:function(a,b){var c=this;c.options[a]=b},setValue:function(a){this.input.value=a,this.checkValue()}});a.fn.numbox=function(a){return this.each(function(a,b){if(!b.numbox)if(d)b.numbox=new i(b,d);else{var c=b.getAttribute("data-numbox-options"),d=c?JSON.parse(c):{};d.step=b.getAttribute("data-numbox-step")||d.step,d.min=b.getAttribute("data-numbox-min")||d.min,d.max=b.getAttribute("data-numbox-max")||d.max,b.numbox=new i(b,d)}}),this[0]?this[0].numbox:null},a.ready(function(){a("."+e).numbox()})}(mui),function(a,b,c){var d="mui-disabled",e="reset",f="loading",g={loadingText:"Loading...",loadingIcon:"mui-spinner mui-spinner-white",loadingIconPosition:"left"},h=function(b,c){this.element=b,this.options=a.extend({},g,c),this.options.loadingText||(this.options.loadingText=g.loadingText),null===this.options.loadingIcon&&(this.options.loadingIcon="mui-spinner","rgb(255, 255, 255)"===a.getStyles(this.element,"color")&&(this.options.loadingIcon+=" mui-spinner-white")),this.isInput="INPUT"===this.element.tagName,this.resetHTML=this.isInput?this.element.value:this.element.innerHTML,this.state=""};h.prototype.loading=function(){this.setState(f)},h.prototype.reset=function(){this.setState(e)},h.prototype.setState=function(a){if(this.state===a)return!1;if(this.state=a,a===e)this.element.disabled=!1,this.element.classList.remove(d),this.setHtml(this.resetHTML);else if(a===f){this.element.disabled=!0,this.element.classList.add(d);var b=this.isInput?this.options.loadingText:"<span>"+this.options.loadingText+"</span>";this.options.loadingIcon&&!this.isInput&&("right"===this.options.loadingIconPosition?b+='&nbsp;<span class="'+this.options.loadingIcon+'"></span>':b='<span class="'+this.options.loadingIcon+'"></span>&nbsp;'+b),this.setHtml(b)}},h.prototype.setHtml=function(a){this.isInput?this.element.value=a:this.element.innerHTML=a},a.fn.button=function(a){var b=[];return this.each(function(){var c=this.mui_plugin_button;if(!c){var d=this.getAttribute("data-loading-text"),g=this.getAttribute("data-loading-icon"),i=this.getAttribute("data-loading-icon-position");this.mui_plugin_button=c=new h(this,{loadingText:d,loadingIcon:g,loadingIconPosition:i})}(a===f||a===e)&&c.setState(a),b.push(c)}),1===b.length?b[0]:b}}(mui,window,document); \ No newline at end of file diff --git a/static/app2/js/my.js b/static/app2/js/my.js new file mode 100755 index 0000000..a99b40a --- /dev/null +++ b/static/app2/js/my.js @@ -0,0 +1,624 @@ +$('.mui-scroll').css('background', 'url(http://img.juzi199.com/static/app2/img/user_center.png) no-repeat center top'); +$('.mui-scroll').css('background-size', '100%'); + +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var token = localStorage.getItem('token'); + var authType = 0; //0 未认证 1 个人认证 2 合作认证 + var userId = 0; + var authTypeText = ""; + var authTypeStatus = ""; + var reasonsForRefusal = ""; + // $('.nblock').on('tap',function () { + // + // }) +var localAuthType = localStorage.getItem("authType"); + + // if (token) { + // console.log(token); + + JZL.ajax(qlgUrl('app/users/getIndex'), {}, function(data) { + // console.log(data); //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + userId = parseInt(data.data.user.userId); + authType = parseInt(data.data.user.authType); + var imgurl = data.data.user.userPhoto ? hyhImgUrl(data.data.user.userPhoto) : '../img/mujiimg.png'; + if(1 == localAuthType){ + //本地申请亲人认证 + JZL.ajax(qlgUrl('app/auth/getAuthInfo'), {}, function(result) { + authTypeText = "个人认证" + if (0 == result.data.status) { + authTypeStatus = "待审核" + } else if (1 == result.data.status) { + authTypeStatus = "已通过" + localStorage.setItem("authType","0") + } else if (2 == result.data.status) { + $('.mydata').on('tap', '.cooperative', function() { + JZL.openWindow('cooperative.html', 'cooperative.html') + }) + $('.mydata').on('tap', '.individual', function() { + JZL.openWindow('individual.html', 'individual.html') + }) + + authTypeStatus = "已拒绝"; + reasonsForRefusal = result.data.reasonsForRefusal; + var html1 = '<img src="' + imgurl + '" /><div class="left"><p>' + data.data.user.loginName + + '</p><p><span>' + authTypeText + + '</span><span>' + authTypeStatus + + '</span></p><p><span>' + reasonsForRefusal + + '</span></p></div>'; + $('.con1').html(html1); + } + + }) + }else if(2 == localAuthType){ + //本地申请合作认证 + JZL.ajax(qlgUrl('app/auth/getAuthInfo'), { + isCompany: 1 + }, function(res) { + console.log(res); + authTypeText = "合作认证" + if (0 == res.data.status) { + authTypeStatus = "待审核" + } else if (1 == res.data.status) { + authTypeStatus = "已通过" + localStorage.setItem("authType","0") + + } else if (2 == res.data.status) { + $('.mydata').on('tap', '.cooperative', function() { + JZL.openWindow('cooperative.html', 'cooperative.html') + }) + $('.mydata').on('tap', '.individual', function() { + JZL.openWindow('individual.html', 'individual.html') + }) + authTypeStatus = "已拒绝"; + reasonsForRefusal = res.data.reasonsForRefusal; + var html1 = '<img src="' + imgurl + '" /><div class="left"><p>' + data.data.user.loginName + + '</p><p><span>' + authTypeText + + '</span><span>' + authTypeStatus + + '</span></p><p><span>' + reasonsForRefusal + + '</span></p></div>'; + $('.con1').html(html1); + } + + }) + }else{ + if(1 == authType){ + //个体认证 + authTypeText = "个人认证" + authTypeStatus = "已通过" + $('.cooperative img').attr('src', "../img/trade1.png") + $('.mydata').on('tap', '.cooperative', function() { + mui.alert('已认证 无需再次认证') + }) + $('.mydata').on('tap', '.individual', function() { + JZL.openWindow('individual.html', 'individual.html') + }) + + }else if(2 == authType){ + //合作认证 + authTypeText = "合作认证" + authTypeStatus = "已通过" + $('.individual img').attr('src', "../img/renzheng1.png") + $('.mydata').on('tap', '.individual', function() { + mui.alert('已认证 无需再次认证') + }) + $('.mydata').on('tap', '.cooperative', function() { + JZL.openWindow('cooperative.html', 'cooperative.html') + }) + }else{ + //未申请认证 + if (userId > 0) { + authTypeText = "未认证 请认证" + $('.mydata').on('tap', '.cooperative', function() { + JZL.openWindow('cooperative.html', 'cooperative.html') + }) + $('.mydata').on('tap', '.individual', function() { + JZL.openWindow('individual.html', 'individual.html') + }) + } + } + } +// if (2 == authType) { +// JZL.ajax(qlgUrl('app/auth/getAuthInfo'), { +// isCompany: 1 +// }, function(res) { +// console.log(res); +// authTypeText = "合作认证" +// if (0 == res.data.status) { +// authTypeStatus = "待审核" +// } else if (1 == res.data.status) { +// authTypeStatus = "已通过" +// +// } else if (2 == res.data.status) { +// authTypeStatus = "已拒绝"; +// reasonsForRefusal = res.data.reasonsForRefusal; +// } +// +// }) +// } else if (1 == authType) { +// JZL.ajax(qlgUrl('app/auth/getAuthInfo'), {}, function(result) { +// console.log(result); +// authTypeText = "个人认证" +// if (0 == result.data.status) { +// authTypeStatus = "待审核" +// } else if (1 == result.data.status) { +// authTypeStatus = "已通过" +// +// } else if (2 == result.data.status) { +// authTypeStatus = "已拒绝"; +// reasonsForRefusal = result.data.reasonsForRefusal; +// } +// +// }) +// } + // setTimeout(function () { + var html1 = '<img src="' + imgurl + '" /><div class="left"><p>' + data.data.user.loginName + + '</p><p><span>' + authTypeText + + '</span><span>' + authTypeStatus + + '</span></p><p><span>' + reasonsForRefusal + + '</span></p></div>'; + $('.con1').html(html1); + // },200) + $('.header').html(""); + // $('.header').html(html); + $('.con .login').css('display', 'none') + + $('.nav').css('display', 'none') + $('.myYouhuiquan_con').addClass("myYouhuiquan_con1") + $('.myYouhuiquan').removeClass("shadown_wai") + $('#expectedProductNum').html(+data.data.expectedProductNum); + $('#expectedCouponsNum').html(+data.data.expectedCouponsNum); + $('#expectedWangNum').html(+data.data.expectedWangNum); + $('#couponsNum').html(+data.data.user.couponsNum); + $('#productNum').html(+data.data.user.productNum); + $('#wangNum').html(+data.data.user.wangNum); + + mui.ajax(qlgUrl('app/users/getFavoritesNum'), { + headers: { + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + var data = toJson(data, 1); + if (data.status == 1) { + // //console.log(data.data.goodsFavoritesNum) + var html = '<div class="nblock" data-href="collect_commodity.html"><p>' + data.data.goodsFavoritesNum + + '</p><p>收藏夹</p></div><div class="nblock" data-href="collect_store.html"><p>' + data.data.shopFavoritesNum + + '</p><p>关注店铺</p></div><div class="nblock" data-href="share_user_list.html"><p>' + data.data.shareNum + + '</p><p>我的分享</p></div>'; + $('.nav').html(html); + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + // 订单个数 + mui.ajax(qlgUrl('app/users/getOrderNum'), { + headers: { + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // console.log(data); + // //console.log(data.data.goodsFavoritesNum) + var data = toJson(data, 1); + if (data.status == 1) { + + var html = '<div class="order_cb indent_btn" data-href="waitPay"><div class="num">' + data.data.order.waitPay + + '</div><div class="orderimg"><img src="../img/daifukuan.png" /></div><p>待付款</p></div><div class="order_cb indent_btn" data-href="waitDeliver"><div class="num">' + + data.data.order.waitSend + + '</div><div class="orderimg"><img src="../img/daifahuo.png" /></div><p>待发货</p></div><div class="order_cb indent_btn" data-href="waitReceive"><div class="num">' + + data.data.order.waitReceive + + '</div><div class="orderimg"><img src="../img/daishouhuo.png" /></div><p>待收货</p></div><div class="order_cb indent_btn" data-href="waitAppraise"><div class="num">' + + data.data.order.waitAppraise + + '</div><div class="orderimg"><img src="../img/pingjia.png" /></div><p>待评价</p></div><div class="order_cb indent_btn" data-href="abnormal"><div class="num">' + + data.data.order.cancelNum + + '</div><div class="orderimg"><img src="../img/orderdetail.png" /></div><p>退款/售后</p></div>'; + $('.order .order_con').html(html); + $('.num').each(function() { + if ($(this).html() == '0') { + $(this).css('display', 'none'); + } + }) + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + $('.mydata-content').on('tap', '.friends', function() { + if ("undefined" != typeof(cooperativeData) && "undefined" != typeof(individualData)) { + mui.alert('请先进行认证') + return; + } else { + JZL.openWindow('friends.html', 'friends.html') + } + + }) + + $('.mydata-content').on('tap', '.applicationopen', function() { + if (authType > 0) { + JZL.openWindow('applicationopen.html', 'applicationopen.html') + } else { + mui.alert('请先进行认证') + } + + }) + $('.mydata-content').on('tap', '.myshops', function() { + if (authType > 0) { + JZL.openWindow('myshops.html', 'myshops.html') + } else { + mui.alert('请先进行认证') + } + + }) + $('.mydata-content').on('tap', '.setting', function() { + JZL.openWindow('setting.html', 'setting.html') + }) + $('.mydata-content').on('tap', '.shoppingcart', function() { + JZL.openWindow('shoppingcart.html', 'shoppingcart.html') + }) + + $('.mydata-content').on('tap', '.shangdu', function() { + if (authType == 2) { + JZL.openWindow('shangdu.html', 'shangdu.html') + } else if (authType == 0) { + mui.alert('请先进行认证') + } else if (authType == 1) { + mui.alert('只有合作认证才可以申请商都') + } + }) + $('.mydata-content').on('tap', '.supermarket', function() { + if (2 == authType) { + JZL.openWindow('supermarket.html', 'supermarket.html') + } else if (0 == authType) { + mui.alert('请先进行认证') + } else if (1 == authType) { + mui.alert('只有合作认证才可以申请商超') + } + }) + $('.mydata-content').on('tap', '.commercial', function() { + if (2 == authType) { + JZL.openWindow('commercial.html', 'commercial.html') + } else if (0 == authType) { + mui.alert('请先进行认证') + } else if (1 == authType) { + mui.alert('只有合作认证才可以申请商厦') + } + }) +// setTimeout(function() { +// //console.log(authType); +// if (2 == authType) { // 合作认证 +// $('.individual img').attr('src', "../img/renzheng1.png") +// $('.mydata').on('tap', '.individual', function() { +// mui.alert('已认证 无需再次认证') +// }) +// $('.mydata').on('tap', '.cooperative', function() { +// JZL.openWindow('cooperative.html', 'cooperative.html') +// }) +// } else if (1 == authType) { // 个体认证 +// $('.cooperative img').attr('src', "../img/trade1.png") +// $('.mydata').on('tap', '.cooperative', function() { +// mui.alert('已认证 无需再次认证') +// }) +// $('.mydata').on('tap', '.individual', function() { +// JZL.openWindow('individual.html', 'individual.html') +// }) +// } else if (userId > 0) { +// $('.mydata').on('tap', '.cooperative', function() { +// JZL.openWindow('cooperative.html', 'cooperative.html') +// }) +// $('.mydata').on('tap', '.individual', function() { +// JZL.openWindow('individual.html', 'individual.html') +// }) +// } +// +// }, 500) + + + } else { + // mui.alert(data.msg) + //console.log(data.status) + } + + }) + + // } else { + // // $('.con').attr('display','block') + // + // // JZL.openWindow('login.html', 'login.html'); + // } + + $('.mydata-content').on('tap', '.zhuweiba', function() { //助威吧 + // JZL.openWindow('essay.html', 'essay.html') + mui.alert("功能开发中......") + + }) + $('.mydata-content').on('tap', '.essaylist', function() { //烂笔头 + // JZL.openWindow('essaylist.html', 'essaylist.html') + // mui.alert("功能开发中......") + + }) + + $('.mydata-content').on('tap', '.touzi', function() { //投资 + // JZL.openWindow('invest.html', 'invest.html') + // mui.alert("功能开发中......") + + }) + $('.mydata-content').on('tap', '.shenqingweiba', function() { //申请微吧 + // JZL.openWindow('essay.html', 'essay.html') + mui.alert("功能开发中......") + + }) + $('.moneycon').on('tap', '.moneycon_', function() { + + if ($(this).children('p').attr('id') == 'userECT') { + mui.openWindow({ + url: 'ect_index.html', + id: 'ect_index.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + + }) + // 跳转到券值 + $('.myYouhuiquan').on('tap', '.indent_btn', function() { //预获 已获优惠券 + var data_href = $(this).attr('data-href') + var data_type = $(this).attr('data-type') + var data_expect = $(this).attr('data-expect') + // var data_href = this.attributes["data-href"].nodeValue; + //console.log(data_href); + JZL.openWindow("vouchers.html", "vouchers.html", { + data_href: data_href, + data_type: data_type, + data_expect: data_expect + }) + + }) + //跳转到劵包 + $('.moneycon').on('tap', '.moneycon_', function() { + if ($(this).children('p').attr('id') == 'userJuan') { + mui.openWindow({ + url: 'juan_index.html', + id: 'juan_index.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + + }) + + $('.mydata-content').on('tap', '.userPaymentvoucher', function() { //首页付款凭证 + // JZL.openWindow('paymentvoucher.html', 'paymentvoucher.html') + mui.alert("功能开发中......") + + }) + //订单按钮 + mui('.order').on('tap', '.indent_btn', function() { + var data_href = this.attributes["data-href"].nodeValue; + // //console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'indent.html', + id: data_href, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.my').on('tap', '.share', function() { + mui.openWindow({ + url: 'share.html', + id: 'share.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_userId: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + mui(".nav").on('tap', '.nblock', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + // var data_href = this.attributes["data-href"].nodeValue; + // var url = 'collect.html'; + // if (data_href == 'share_user_list.html') { + // url = 'share_user_list.html'; + // } + // // //console.log(this.attributes["data-id"].nodeValue); + // mui.openWindow({ + // url: url, + // id: url, + // styles: { + // top: '0px', //新页面顶部位置 + // bottom: '0px', //新页面底部位置 + // width: '100%', //新页面宽度,默认为100% + // height: '100%' //新页面高度,默认为100% + // }, + // extras: { + // data_href: data_href + // // ..... //自定义扩展参数,可以用来处理页面间传值 + // }, + // createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + // show: { + // // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // // extras: {} //窗口动画是否使用图片加速 + // }, + // waiting: { + // autoShow: true, //自动显示等待框,默认为true + // title: '正在加载...', //等待对话框上显示的提示内容 + // options: { + // // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // // ...... + // } + // } + // }) + }) + + + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + }); + + // + mui('.my').on('tap', '.seeting', function() { + JZL.openWindow('setting.html', 'setting.html') + }) + + // 登录 + $('.my').on('tap', '.login', function() { + mui.openWindow({ + url: 'login.html', + id: 'login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + + +}) diff --git a/static/app2/js/myshop.js b/static/app2/js/myshop.js new file mode 100755 index 0000000..4e6a6ce --- /dev/null +++ b/static/app2/js/myshop.js @@ -0,0 +1,194 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + $('.orange').html("¥000.00") + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + //console.log(shopId); + $('.seeting').on("tap", function() { + JZL.openWindow('shopsetting.html', parseInt(shopId)) + }) + $('.money').on('tap', function() { + JZL.openWindow('cash-out.html', parseInt(shopId)) + }) + // $('.money').on('tap','.myYouhuiquan_cb',function () { + // var data_href=$(this).attr('data-href') + // var data_expect =$(this).attr('data_expect') + // //console.log(data_href) + // JZL.openWindow('income-details.html',parseInt(shopId),{data_href:data_href,data_expect:data_expect}) + // }) + // $('.money').on('tap',function () { + // JZL.openWindow('paymentvoucher.html',parseInt(shopId)) + // }) + // 获取商家首页信息 + JZL.ajax(qlgUrl('app/shops/shopInfo'), { + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status) { + data = data.data; + // //console.log(data.status); + var html = ""; + var html1 = ""; + html = '<p class="myshopname">' + data.shopName + '</p><span class="shop_">' + data.userName + + '</span><span class="shop_">' + data.phone + '</span>' + $('.shop_info').html(html) + $('.wait_money .orange').text('¥' + data.waitPayMoneyNum); + $('.comp_money .orange').text('¥' + data.receivedPayMoneyNum); + var html1 = '<div class="order_cb indent_btn" data-href="waitPay"><div class="num">' + data.waitPayNum + + '</div><div class="orderimg"><img src="../img/daifukuan.png" /></div><p>待付款</p></div><div class="order_cb indent_btn" data-href="waitConfirm"><div class="num">' + + data.waitConfirmNum + + '</div><div class="orderimg"><img src="../img/pingjia.png" /></div><p>待确认</p></div><div class="order_cb indent_btn" data-href="waitDeliver"><div class="num">' + + data.waitDeliverNum + + '</div><div class="orderimg"><img src="../img/daifahuo.png" /></div><p>待发货</p></div><div class="order_cb indent_btn" data-href="waitReceive"><div class="num">' + + data.waitReceiveNum + + '</div><div class="orderimg"><img src="../img/daishouhuo.png" /></div><p>待收货</p></div><div class="order_cb indent_btn" data-href="abnormal"><div class="num">' + + data.abnormal + '</div><div class="orderimg"><img src="../img/orderdetail.png" /></div><p>退款/售后</p></div>'; + $('.line_order .order_con').html(html1); + $('.num').each(function() { + if ($(this).html() == '0') { + $(this).css('display', 'none'); + } + }) + }else{ + mui.alert(data.msg) + } + }) + + mui('.order').on('tap', '.indent_btn', function() { + var data_href = this.attributes["data-href"].nodeValue; + JZL.openWindow("shop_indent.html", data_href, { + data_href: data_href, + shopId: shopId + }) + + }) + mui('.order').on('tap', '.pingzheng', function() { + // var data_href = this.attributes["data-href"].nodeValue; + JZL.openWindow("paymentVoucher.html", parseInt(shopId)) + + }) + mui('.order').on('tap', '.tixian', function() { + // var data_href = this.attributes["data-href"].nodeValue; + JZL.openWindow('cash-out.html', parseInt(shopId)) + + }) + getRecommend(nowpage, pagesize) + // 获取店铺商品 + var nowpage = 1; + var pagesize = 10; + var isload = false; + + function getRecommend(nowpage, pagesize) { + var recommenddata = { + nowpage: nowpage ? nowpage : 1, + pagesize: pagesize ? pagesize : 10 + } + recommenddata.shopId = shopId + + if (isload == true) { + return; + } + isload = true + mui.ajax(qlgUrl('app/Shopping/getShopIndexGoodsList'), { + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data); + + // var data = toJson(data, 1); + if (data.status == 1) { + //console.log(data); + + var html = ''; + var data = data.data; + if (data.Rows == '') { + $('.mui-scroll').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + + return; + } + $.each(data.Rows, function() { + html += '<div class="shop-goods-detail" data-goodsId="' + this.goodsId + + '"><div class="sgd-list"><img class="sdg-img" src="' + hyhImgUrl(this.goodsImg) + + '" alt=""><div class="sgd-info">' + this.goodsName + + '</div><div class="sgd-price"><div class="market-price"><span>价格</span><span class="price">¥' + this.shopPrice + + '</span></div><div class="youhuilv"><span>优惠率</span><span class="preference-rate">' + this.discountRate + + '%</span></div></div></div></div>' + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + // '"><img class="rcb_img" src="' + hyhImgUrl(this.goodsImg) + + // '" alt="" /><div class="rcb_con"><div class="rcb_title">'+ this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + // ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>'+this.saleNum+'</span><span>人购买</span></div><div><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>'+this.discountRate+'%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (nowpage == 1) { + // //console.log(222); + $('.shop-goods-content').html(html); + } else { + $('.shop-goods-content').append(html); + } + + // $('.rcb_title span').each(function() { + // if ($(this).attr('data-goodsId') == 1) { + // $(this).css('display', 'none'); + // } + // }) + $('.sdg-img').height($('.sdg-img').width()); + + } else{ + mui.alert(data.msg) + } + isload - false + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + + } + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // 判断默认行为是否可以被禁用 + if (e.cancelable) { + // 判断默认行为是否已经被禁用 + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (scroll.y == scroll.maxScrollY) { + if (isload = true) { + nowpage++; + getRecommend(nowpage, pagesize); + } + } + }) + + $('.shop-goods').on('tap', '.shop-goods-detail', function() { + var good_id = $(this).attr('data-goodsId'); + JZL.openWindow('details.html', parseInt(good_id), { + shopId: shopId, + data_id: good_id + }) + + }) + + + + + + + + + + + + + + + + +}) diff --git a/static/app2/js/myshops.js b/static/app2/js/myshops.js new file mode 100755 index 0000000..e2dea2c --- /dev/null +++ b/static/app2/js/myshops.js @@ -0,0 +1,316 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var authType = localStorage.getItem('authType') + var supermarket = '', + commercial = '', + shangdu = ''; + var scinfo = '', + ssinfo = '', + sdinfo = ''; + var shopName = ''; + var scshopId = '', + ssshopId = "", + sdshopId = ''; + var scid = '', + ssid = '', + sdid = ''; + $('.nc').hide(); + $('.ic').hide(); + // 获取商超商厦申请记录 + // //console.log(authType); + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 2 + }, function(data) { //shangchang + // console.log(data) + if ("undefined" != typeof(data.data)) { + scshopId = data.data.shopId; + scid = data.data.id; + + if (0 == data.data.status) { + scinfo = "待审核" + } + if (1 == data.data.status) { + scinfo = "已通过" + } + if (2 == data.data.status) { + scinfo = "已拒绝" + } + + }else{ + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 2, + status:1 + }, function(data) { //shangchang + // console.log(data) + if ("undefined" != typeof(data.data)) { + scshopId = data.data.shopId; + scid = data.data.id; + + if (0 == data.data.status) { + scinfo = "待审核" + } + if (1 == data.data.status) { + scinfo = "已通过" + } + if (2 == data.data.status) { + scinfo = "已拒绝" + } + + } + + + }) + } + + + }) + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 3 + }, function(data) { //xiaodian + // console.log(data) + if ("undefined" != typeof(data.data)) { + + if (0 == data.data.status) { + ssinfo = "待审核" + } + if (1 == data.data.status) { + ssinfo = "已通过" + } + if (2 == data.data.status) { + ssinfo = "已拒绝" + } + ssid = data.data.id; + + ssshopId = data.data.shopId; + // ssinfo=data.data.status; + + }else{ + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 3, + status:1 + }, function(data) { //xiaodian + // console.log(data) + if ("undefined" != typeof(data.data)) { + + if (0 == data.data.status) { + ssinfo = "待审核" + } + if (1 == data.data.status) { + ssinfo = "已通过" + } + if (2 == data.data.status) { + ssinfo = "已拒绝" + } + ssid = data.data.id; + + ssshopId = data.data.shopId; + // ssinfo=data.data.status; + + } + }) + } + }) + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 4 + }, function(data) { //shangchangkefu + // console.log(data) + if ("undefined" != typeof(data.data)) { + + if (0 == data.data.status) { + sdinfo = "待审核" + } + if (1 == data.data.status) { + sdinfo = "已通过" + } + if (2 == data.data.status) { + sdinfo = "已拒绝" + } + sdid = data.data.id; + + sdshopId = data.data.shopId; + // sdinfo = data.data.status; + // shangdu = '<img src="../img/shangchangkefu.png">' + }else{ + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 4, + status:1 + }, function(data) { //shangchangkefu + // console.log(data) + if ("undefined" != typeof(data.data)) { + + if (0 == data.data.status) { + sdinfo = "待审核" + } + if (1 == data.data.status) { + sdinfo = "已通过" + } + if (2 == data.data.status) { + sdinfo = "已拒绝" + } + sdid = data.data.id; + + sdshopId = data.data.shopId; + // sdinfo = data.data.status; + // shangdu = '<img src="../img/shangchangkefu.png">' + } + }) + } + }) + JZL.ajax(qlgUrl('app/shops/userShopList'), {}, function(data) { + if (1 == data.status) { + var data = data.data; + var html = ''; + var info = "", + infotext; + $.each(data, function() { + if (this.status == 0) { + info = "待审核", + infotext = "编辑" + } else if (this.status == 1) { + info = "已通过"; + infotext = "进入店铺" + + } else if (this.status == 2) { + info = "已拒绝"; + infotext = "编辑" + } + html = '<div class="list shadown_wai" data-id="' + this.shopId + ' " data-info="' + this.status + + '"><div class="listleft"><div class="listimg"><img src="../img/icon_7.png" alt=""></div></div><div class="listcenter"><div class="lctop"><div class="shopname"><p class="shopname namecom ">' + + this.shopName + '</p><p class="infocom shopinfo">' + info + + '</p></div><div class="shopname supermaket nc "><p class=" namecom ">商超</p><p class="infocom scinfo ">' + + scinfo + + '</p></div><div class="shopname commercial nc"><p class=" namecom ">商厦</p><p class="infocom ssinfo ">' + + ssinfo + '</p></div><div class="shopname shangdu nc"><p class=" namecom ">商都 </p><p class="infocom sdinfo">' + + sdinfo + '</p></div></div><div class="listright"><p class="bj">' + infotext + + '</p><p class="del">删除</p></div></div></div>'; + // html = '<div class="list shadown_wai" data-id="' + this.shopId + ' " data-info="' + this.status + + // '"><div class="listleft"><div class="listimg"><img src="../img/icon_7.png" alt=""></div></div><div class="listcenter"><div class="name"><span class="shopname namecom ">' + + // this.shopName + + // '</span><span class="supermaket namecom nc"></span><span class="commercial namecom nc"></span><span class="shangdu nc namecom"></span></div><div class="info"><p class="infocom shopinfo">' + + // info + + // '</p><p class="scinfo ic infocom"></p><p class="ssinfo ic infocom"></p><p class="sdinfo ic infocom"></p></div><div class="listright"><p class="bj">' + + // infotext + + // '</p><p class="del">删除</p></div></div></div>'; + // + $('.con').append(html); + }) + }else{ + mui.alert(data.msg) + } + }) + setTimeout(function() { + $.each($(".list"), function() { + var shop_id = $(this).attr("data-id"); + if (shop_id == scshopId) { + $(this).find($('.listcenter .supermaket')).show() + // $(this).find($('.listcenter .supermaket .namecom')).html('商超') + // $(this).find($('.listcenter .shopname .scinfo')).show() + $(this).find($('.listcenter .shopname .scinfo')).html(scinfo) + } + if (shop_id == ssshopId) { + $(this).find($('.listcenter .commercial')).show() + // $(this).find($('.listcenter .commercial .namecom')).html('商厦') + // $(this).find($('.listcenter .shopname .ssinfo')).show() + $(this).find($('.listcenter .shopname .ssinfo')).html(ssinfo) + } + if (shop_id == sdshopId) { + $(this).find($('.listcenter .shangdu')).show() + + // $(this).find($('.listcenter .shangdu .namecom')).html('商都') + // $(this).find($('.listcenter .shopname .sdinfo')).show() + + $(this).find($('.listcenter .shopname .sdinfo')).html(sdinfo) + } + }) + }, 1000) + // 申请店铺 + $('.add1').on('tap', function() { + JZL.openWindow('applicationopen.html', 'applicationopen.html'); + }) + + //编辑店铺 + var shopId = ''; + mui('.con').on('tap', '.bj', function() { + shopId = $(this).parents().parents().parents().attr("data-id"); + var status = $(this).parents().parents().parents().attr("data-info"); + + if (1 == status) { + JZL.openWindow('myshop.html', shopId, { + 'shopId': shopId + }); + + // JZL.openWindow('storeout.html', shopId); + } else { + JZL.openWindow('applicationopen.html', shopId, { + 'status': status, + 'shopId': shopId + }); + // JZL.openWindow('myshop.html', shopId); + + } + }) + mui('.con').on('tap', '.supermaket', function() { + if (scinfo != "已通过") { + JZL.openWindow('supermarket.html', 'supermarket.html', { + scid: scid + }) + } + }) + mui('.con').on('tap', '.commercial', function() { + if (ssinfo != "已通过") { + JZL.openWindow('commercial.html', 'commercial.html', { + ssid: ssid + }) + } + }) + mui('.con').on('tap', '.shangdu', function() { + if (sdinfo != "已通过") { + JZL.openWindow('shangdu.html', 'shangdu.html', { + sdid: sdid + }) + } + }) + //删除店铺 + mui('.con').on('tap', '.del', function() { + + shopId = $(this).parents().parents().parents().attr("data-id"); + + if (confirm('确认删除?')) { + var lxy_div = + '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"> <div class="lxy_zz clearfix"><h3>请输入操作密码</h3><div style="background:linear-gradient(to right,#48D1CC,#FFD700,#D2691E);height:2px; margin:10px auto"></div><input class="payword" type="password" placeholder="请输入操作密码"><div class="lxy_zz_btn"><button class="cancle" type="button">取消</button><button class="sure" type="button">确定</button></div></div></div>'; + $('body').append(lxy_div); + $('.lxy_zz').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + }) + mui('.lxy_zz_btn').on('tap', '.cancle', function() { + $('#home_zhezhao').remove(); + return; + }) + + mui('.lxy_zz_btn').on('tap', '.sure', function() { + var payPwd = $('.payword').val(); + if (payPwd == '') { + mui.alert("请输入密码") + } + JZL.ajax(qlgUrl('app/shops/delShop'), { + shopId: shopId, + payPwd: payPwd + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + console.log(data); + if (data.status == 1) { + $('#home_zhezhao').remove(); + mui.toast(data.msg) + location.reload() + }else{ + mui.alert(data.msg) + } + }) + + }) + } + }) +}) diff --git a/static/app2/js/new_product.js b/static/app2/js/new_product.js new file mode 100755 index 0000000..faac7c1 --- /dev/null +++ b/static/app2/js/new_product.js @@ -0,0 +1,183 @@ +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('app/Shops/listShopQuery'), {  + + data: { + page: count, + pagesize : 10 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<img data-goodId="' + this.goodsId + '" src="' + hyhImgUrl(this.goodsImg) + '" />' + }); + html += '</div></div>' + }); + $('.con').append(html); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var data = ''; + mui.ajax(hyhUrl('app/Shops/listShopQuery'), {  + data: { + pagesize: 10, + page: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + data = data.data; + + var html = ''; + $.each(data.Rows, function() { + html += '<div class="block"><div class="b_title" data-shopId="' + this.shopId + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + '</p><p class="time">' + this.newTime + '</p></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<img data-goodId="' + this.goodsId + '" src="' + hyhImgUrl(this.goodsImg) + '" />' + }); + html += '</div></div>' + }); + $('.con').html(html) + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + //console.log(shopId); + var url = 'storeout.html'; + if(shopId==1){ +// url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', 'img[data-goodId]', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html'+goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/newuser.js b/static/app2/js/newuser.js new file mode 100755 index 0000000..d63552f --- /dev/null +++ b/static/app2/js/newuser.js @@ -0,0 +1,33 @@ +mui.plusReady(function() { +// var token = localStorage.getItem('token'); +// var self = plus.webview.currentWebview(); +// var msgId = self.data_msgId; +// mui.ajax(hyhUrl('app/messages/getById'), {  +// headers: {  +// "HYH-Token": token +// }, +// data: { +// msgId: msgId +// }, +// dataType: 'json', //服务器返回json格式数据   +// type: 'post', //HTTP请求类型   +// timeout: 10000, //超时时间设置为10秒;   +// success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   +// var data = toJson(data); +// +// if(data.status == 1) { +// data = data.data; +// var html = '<div class="time">' + data.createTime + '</div><div class="con_">' + data.msgContent + '</div>'; +// $('.con').html(html) +// } else { +// console.log(data.status) +// } +// }, +// error: function(xhr, type, errorThrown) {           //异常处理;   +// // alert(type);       +// }   +// });  + var html = '<div class="con_ shadown_wai">1、惠宝积分的获得:1)合源惠线下联盟消费者去实体店消费根据消费金额可直接获得惠宝积分 2)新手注册直接送388惠宝积分 3)商城消费成功购物,可获得实际消费金额20%的惠宝积分</div><div class="con_ shadown_wai">2、惠宝积分的使用:惠宝积分用于商城购物在货款结算时勾选,可直抵20%货款</div>'; + $('.con').html(html); + $('.header_con .mui-action-back').css('display','none'); +}) \ No newline at end of file diff --git a/static/app2/js/order_con.js b/static/app2/js/order_con.js new file mode 100755 index 0000000..a1eb4ab --- /dev/null +++ b/static/app2/js/order_con.js @@ -0,0 +1,115 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var data_order_id = localStorage.getItem('data_order_id'); +// //console.log(data_order_id) + mui.ajax(hyhUrl('app/Orders/getDetail'), { + headers: { + "HYH-Token": token + }, + data: { + id: data_order_id + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + var data = toJson(data.data); + var html = '<div class="ad shadown_wai"><p>' + data.status + '</p></div><div class="address clearfix shadown_wai"><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r "><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userName + '</div><div class="add_r_t_r">' + data.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.userAddress + '</div></div></div><div class="invoice_info shadown_wai"><p>发票信息</p><p>发票抬头 ' + data.invoiceClient + '</p></div><div class="shop_info shadown_wai"><div class="row_title" data-shopId="' + data.shopId + '"><div class="store_name">' + data.shopName + '</div></div><div class="row_con clearfix">'; + $.each(data.goods, function() { + html += '<div class="row_block clearfix" data-goodsId="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>' + }); + + // html += '<div class="cost"><div class="c1 clearfix"><div class="c1_l">商品总价</div><div class="c1_r">¥' + data.goodsMoney + '</div></div><div class="c1 clearfix"><div class="c1_l">运费(快递)</div><div class="c1_r">¥' + data.deliverMoney + '</div></div><div class="c2 clearfix"><div class="c1_l">订单总价</div><div class="c1_r">¥' + data.totalMoney + '</div></div></div><div class="cost"><div class="c2 clearfix"><div class="c1_l">实付款</div><div class="c1_r on">¥' + data.realTotalMoney + '</div></div></div></div></div><div class="jf_info shadown_wai clearfix"><div class="jf_jf">积分</div><div class="jf_p">奖励积分<o>' + data.orderScore + '</o>点</div></div><a href="tel:' + data.shopTel + '" class="lxmj shadown_wai"><img src="../img/phone1.png" /><p>联系卖家 </p></a><div class="info shadown_wai"><p>订单编号:' + data.orderNo + '</p><p>创建时间:' + data.createTime + '</p>'; + html += '<div class="cost"><div class="c1 clearfix"><div class="c1_l">商品总价</div><div class="c1_r">¥' + data.goodsMoney + '</div></div><div class="c1 clearfix"><div class="c1_l">运费(快递)</div><div class="c1_r">¥' + data.deliverMoney + '</div></div><div class="c2 clearfix"><div class="c1_l">订单总价</div><div class="c1_r">¥' + data.totalMoney + '</div></div></div><div class="cost"><div class="c2 clearfix"><div class="c1_l">产品券</div><div class="c1_r on">¥' + data.productNum + '【税费:' +data.productHandlingFee+',手续费:'+data.productTaxFee+'】</div></div><div class="c2 clearfix"><div class="c1_l">优惠券</div><div class="c1_r on">¥' + data.couponsNum + '【税费:' +data.couponsHandlingFee+',手续费:'+data.couponsTaxFee+'】</div></div><div class="c2 clearfix"><div class="c1_l">旺旺券</div><div class="c1_r on">¥' + data.wangNum + '</div></div><div class="c2 clearfix"><div class="c1_l">现金</div><div class="c1_r on">¥' + data.moneyNum + '</div></div></div></div></div><a href="tel:' + data.shopTel + '" class="lxmj shadown_wai"><img src="../img/phone1.png" /><p>联系卖家 </p></a><div class="info shadown_wai"><p>订单编号:' + data.orderNo + '</p><p>创建时间:' + data.createTime + '</p>'; + + if(data.deliveryTime != null) { + html += '<p>发货时间:' + data.deliveryTime + '</p>' + } + if(data.deliveryTime != null) { + html += '<p>成交时间:' + data.receiveTime + '</p>' + } + + html += '</div>'; + + $('.con').html(html); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + $('.con').on('tap', '.row_title', function() { + var shopId = $(this).attr('data-shopId'); + var url = 'storeout.html'; + if(shopId==1){ +// url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url+shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + $('.con').on('tap', '.row_block', function() { + var goodsId = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodsId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodsId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/order_out.js b/static/app2/js/order_out.js new file mode 100755 index 0000000..bb40629 --- /dev/null +++ b/static/app2/js/order_out.js @@ -0,0 +1,53 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + var bSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var sub = plus.webview.create('order_con.html', 'order_con.html', { + top: bSize, + bottom: '49px', + scrollIndicator: 'none' + }); + self.append(sub); + localStorage.setItem('data_order_id', data_order_id); + if(!data_order_id) { + $('#ckwl').css('display', 'none') + } + mui(".btns").on('tap', '#ckwl', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + // //console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'logistics.html', + id: 'logistics.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/orsupermarket.js b/static/app2/js/orsupermarket.js new file mode 100755 index 0000000..92cd718 --- /dev/null +++ b/static/app2/js/orsupermarket.js @@ -0,0 +1,290 @@ + + +$('.search').css('display', 'none'); + +var num = 1; +var isOver = 1; +var recomId = ''; + +function getMsg(recomId, pageNum, pagesizeNum, classifyId,recomGoodsUrl) { + + var data_msg = { + classifyId: classifyId, + recomId: recomId ? recomId : '', + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + + if(isOver == 0) { + return; + } else { + isOver = 0; + } + mui.ajax(llUrl(recomGoodsUrl), {  + data: data_msg, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + data = data.data; + if(data.Rows == '') { + if(pageNum == 1) { + $('.food_class_list').html('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } else if(pageNum > 1) { + $('.food_class_list').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } + + isOver = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span>精选</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + '<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div></div>' + }); + + if(pageNum == 1) { + $('.food_class_list').html(html); + } else if(pageNum > 1) { + $('.food_class_list').append(html); + } + $('.rcb_img').height($('.rcb_img').width()); + + isOver = 1; + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + +} +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var classifyId = self.classifyId; + + if(classifyId == 2 ) { + $('.title').html('服饰'); + }else if(classifyId == 4){ + $('.title').html('家电'); + }else if(classifyId == 3){ + $('.title').html('家居'); + }else if(classifyId == 9){ + $('.title').html('生鲜'); + }else if(classifyId == 1){ + $('.title').html('桔子超市'); + }else if(classifyId == 10){ + $('.title').html('美妆'); + }else if(classifyId == 11){ + $('.title').html('数码'); + }else if(classifyId == 12){ + $('.title').html('箱包'); + }else if(classifyId == 5){ + $('.title').html('家电'); + }else if(classifyId == 6){ + $('.title').html('家纺'); + }else if(classifyId == 7){ + $('.title').html('配饰'); + }else if(classifyId == 8){ + $('.title').html('洗护'); + } +// $('.oc_logo').attr('src', '../img/oc_logo' + classifyId + '.png'); + var bannerUrl = ''; + var recomactiveUrl = ''; + var recomlistUrl = ''; + if(classifyId == 2||classifyId == 4||classifyId == 3||classifyId == 9||classifyId == 1||classifyId == 10||classifyId == 11||classifyId == 12){ + bannerUrl='addon/shuff-Shuff-topshow'; + recomactiveUrl='addon/shuff-Shuff-recomactive'; + recomlistUrl='addon/shuff-Shuff-recomlist'; + recomGoodsUrl='addon/shuff-Shuff-recomgoods'; + }else if(classifyId == 5||classifyId == 6||classifyId == 7||classifyId == 8){ + bannerUrl='addon/selfmarket-selfmarket-selfSecBanner'; + recomactiveUrl='addon/selfmarket-selfmarket-recomActive' + recomlistUrl='addon/selfmarket-selfmarket-recomList' + recomGoodsUrl='addon/selfmarket-selfmarket-recomGoods' + } + + mui.ajax(llUrl(bannerUrl), {  + data: { + classifyId: classifyId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data.banner, function() { + html += '<div class="swiper-slide" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + '"><img src="' + ectImgUrl(this.adFile) + '" /></div>' + }) + $('#top_banner .swiper-wrapper').html(html); + $('#top_banner').height($('#top_banner').width() * 460 / 750); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + + if(data.left[0]) { + $('.add_top_left .food_p1').html(data.left[0].adName.split('|')[0]); + $('.add_top_left .food_p2').html(data.left[0].adName.split('|')[1]); + $('.add_top_left img').attr('src', ectImgUrl(data.left[0].adFile)); + $('.add_top_left img').attr('data-adURL', data.left[0].adURL); + $('.add_top_left img').attr('data-targetType', data.left[0].targetType); + } + if(data.right_top[0]) { + $('.add_top_right_con .food_p1').html(data.right_top[0].adName.split('|')[0]); + $('.add_top_right .top .food_right_img1').attr('src', ectImgUrl(data.right_top[0].adFile)); + $('.add_top_right .top .food_right_img1').attr('data-adURL', data.right_top[0].adURL); + $('.add_top_right .top .food_right_img1').attr('data-targetType', data.right_top[0].targetType); + $('.add_top_right .top .food_right_img2').attr('src', ectImgUrl(data.right_top[1].adFile)); + $('.add_top_right .top .food_right_img2').attr('data-adURL', data.right_top[1].adURL); + $('.add_top_right .top .food_right_img2').attr('data-targetType', data.right_top[1].targetType); + } + if(data.right_bottom[0]) { + $('.add_top_right_con .food_p2').html(data.right_bottom[0].adName.split('|')[0]); + $('.add_top_right .bottom .food_right_img1').attr('src', ectImgUrl(data.right_bottom[0].adFile)); + $('.add_top_right .bottom .food_right_img1').attr('data-adURL', data.right_bottom[0].adURL); + $('.add_top_right .bottom .food_right_img1').attr('data-targetType', data.right_bottom[0].targetType); + $('.add_top_right .bottom .food_right_img2').attr('src', ectImgUrl(data.right_bottom[1].adFile)); + $('.add_top_right .bottom .food_right_img2').attr('data-adURL', data.right_bottom[1].adURL); + $('.add_top_right .bottom .food_right_img2').attr('data-targetType', data.right_bottom[1].targetType); + } + + $('.add_top_left img').height($('.add_top_left img').width()); + $('.add_top_right img').height($('.add_top_right img').width()); + } else { + console.log(data.status); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + console.log(errorThrown);       + }   + });  + + mui.ajax(llUrl(recomactiveUrl), {  + data: { + type: 3, + classifyId: classifyId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + data = data.data; + $.each(data, function() { + html += '<div class="reco_res" data-goodsId="' + this.goodsId + '"><img src="' + ectImgUrl(this.goodsImg) + '" class="reco_img" /><p class="p1">' + this.goodsName + '</p><p class="p2">¥ ' + this.shopPrice + '</p></div>' + }); + $('.mujireco').html(html); + $('.mujireco').eq(0).attr('id', 'reco_1'); + $('.reco_img').height($('.reco_img').width()); + } else { + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui.ajax(llUrl(recomlistUrl), {  + data: { + classifyId: classifyId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data,1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="nav_block" data-recomId="' + this.recomId + '">' + this.recomName + '</div>'; + }) + $('.nav').html(html); + + $('.nav_block').eq(0).addClass('on'); + recomId=$('.nav_block').eq(0).attr('data-recomId'); +// console.log(recomId) + getMsg(recomId, 1, 10, classifyId,recomGoodsUrl); + } else { + console.log(data.status); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + console.log(errorThrown);       + }   + });  + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isOver == 1) { + num++; + getMsg(recomId, num, 10, classifyId,recomGoodsUrl); + } + } + }) + $('.nav').on('tap', '.nav_block', function() { + recomId = $(this).attr('data-recomId'); + isOver = 1; + num = 1; + getMsg(recomId, num, 10, classifyId,recomGoodsUrl); + console.log(recomId) + }) + //广告跳转 + + $('.rec_food').on('tap', 'img', function() { + openAds($(this)); + }); + //banner跳转 + $('#top_banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }); + //展示跳转 + $('.mujireco').on('tap', '.reco_res', function() { + var data_id = this.attributes["data-goodsId"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/paymentVoucher.js b/static/app2/js/paymentVoucher.js new file mode 100755 index 0000000..6dfbe2c --- /dev/null +++ b/static/app2/js/paymentVoucher.js @@ -0,0 +1,277 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + + var comName = "山东省全亮共信息科技有限公司"; + var cardNum = "810102701421013395"; + var cardBank = "日照银行股份有限公司泰安路支行"; + $('.comName ').val(comName) + $('.comNameBtn').attr("data-value", comName) + $('.cardNum ').val(cardNum) + $('.cardNumBtn').attr("data-value", cardNum) + $('.cardBank ').val(cardBank) + $('.cardBankBtn').attr("data-value", cardBank) + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + var type = 0; //0 huozhe 1 + + if ("undefined" != typeof(self.type)) { + type = self.type + } + if (0 == type) { + getuncommitted(); + } else if (1 == type) { + getcommitted(); + } + $('.con_con_com').eq(type).show().siblings().hide(); + $('.con_nav').on("tap", ".nav_header", function() { + type = $(this).index(); + $(this).addClass('active').siblings().removeClass('active'); + $('.con_con_com').eq(type).show().siblings().hide(); + if (0 == type) { + getuncommitted(); + } else if (1 == type) { + getcommitted(); + } + }) + $('.committed').on("tap", ".row_title", function() { + var idx = $(this).index(); + // //console.log(idx); + $('.row_cont').eq(idx).toggle() + }) + $('.committed').on("tap", ".oper", function(e) { + e.preventDefault(); + e.stopPropagation() + id = $(this).parents().parents().attr("data-id") + id = parseInt(id); + //console.log(id); + JZL.openWindow("shoperUploadVoucher.html", "shoperUploadVoucher.html", { + orderId: id, + shopId: shopId + }) + }) + // $('.btns').on('tap', '.bc_btn', function() { + // var idx = $(this).index() + // JZL.openWindow("uploadVoucher.html", "uploadVoucher.html") + // }) + // 获取未提交凭证 + getuncommitted(); + + function getuncommitted() { + JZL.ajax(qlgUrl('app/Shoporders/getCertificate'), { + shopId: shopId, + type: 0 + }, function(data) { + //console.log(data) + if ("undefined" != typeof data.data) { + + var html = ''; + var youhui = 0; + var payable = 0; + mui.each(data.data, function() { + payable = Math.abs(this.payable); + youhui = Math.abs(youhui) + payable; + + html += '<div class="row shadown_wai" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + + '"><div class="row_title"><div class="row_title_"><input type="checkbox" name="check1" class="check1" data-payable=' + + payable + ' value="" checked/><label class="store_name">订单编号:' + + this.orderNo + ' </label></div><div class="indent_status"><span>' + this.status + + '</span> </div><div class="indent_youhui">优惠款<span>' + payable + + '</span> </div></div><div class="row_con clearfix" data-id=""><div class="row_block clearfix">' + + mui.each(this.list, function() { + + html += '<div class="row_block_list"><div class="row_block_img"><img src="' + hyhImgUrl(this.goodsImg) + + '" /></div><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + '</p><p class="leibie">' + + this.goodsSpecNames + '</p></div></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p></div></div>' + }); + youhui = youhui.toFixed(2); + html += '</div><div class="combination"> 共' + this.list.length + '件商品 合计<o>¥' + this.realTotalMoney + + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="combination create_time shadown_wai">订单完成时间:' + this.receiveTime + + '</div></div></div></div>' + + }) + html += + '<div class="btns clearfix"><input type="checkbox" name="" id="checkall" value="" checked /><label for="checkall">全选</label><div class="combination_totle">共<span class= "orderNo">' + + data.data.length + '</span>笔订单 优惠款<span class="youhuiNo">' + youhui + + '</span></div><div class="bc_btn">提交凭证</div></div>' + } else { + + html = '<p style="float: left;width: 100%;text-align: center;padding: 10px;">没有更多订单了</p>'; + // html = '<div class="row_title_ shadown_wai clearfix"><label>没有需要提交的订单</label></div>' + } + $('.uncommitted .con_con_com_').html(html); + }) + } + var i = 0; + //全选或者全不选 + $('body').on('change', '#checkall', function() { + checkAll('.check1', $(this).prop("checked")); + if (false == $(this).prop("checked")) { + $('.orderNo').html("0") + $('.youhuiNo').html("0") + } else { + var youhui = 0; + $('.orderNo').html($('.check1').length) + mui.each($('.indent_youhui span'), function() { + youhui += Number($(this).text()) + }) + $('.youhuiNo').html(youhui) + } + // if (0 == i) { + // $('input[name="check1"]').prop('checked', true); + // i = 1; + // } else { + // / $('input[name="check1"]').prop('checked', false); + // i = 0; + // } + }) + // checkAll('.check1',$('#checkall').checked); + function checkAll(domName, isChecked) { + //console.log(isChecked); + $(domName).prop("checked", isChecked); + } + + function checkNum() { + var length = $('input[name=check1]:checked').length; + var len = $('input[name=check1]').length; + + if (length == len) { + $('#checkall').prop('checked', true); + } else { + $('#checkall').prop('checked', false); + } + var youhui = 0; + $.each($('input[name="check1"]:checked'), function() { + youhui += Number($(this).attr('data-payable')); + + }) + $('.orderNo').html(length); + $('.youhuiNo').html(youhui); + + } + $('body').on('change', '.check1', function() { + checkNum(); + }) + var click = 0 + $('body').on('tap', ".bc_btn", function() { + if (0 == $('input[name="check1"]:checked').length) { + mui.alert("请选择至少一个订单") + return; + } + if (1 == click) { + return; + } + click = 1; + var orderIdsArr = []; + $.each($('input[name="check1"]:checked'), function() { + orderIdsArr.push($(this).parents().parents().parents().attr('data-id')) + }) + orderIds = orderIdsArr.join(',') + + + JZL.openWindow("shoperUploadVoucher.html", "shoperUploadVoucher.html", { + shopId: shopId, + orderIds: orderIds + }) + }) + var isjiazai = false; + + function getcommitted(page, PerPage) { + var recommenddata = { + page: page ? page : 1, + PerPage: PerPage ? PerPage : 10 + } + if (isjiazai == true) { + return; + } + isjiazai = true; + + + JZL.ajax(qlgUrl('app/Shoporders/getCertificate'), { + shopId: shopId, + type: 1 + }, function(data) { + //console.log(data); + if (1 == data.status) { + var data = data.data; + var html = ''; + var totPayable = 0; + if (data.Rows == '') { + $('.committed ').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多订单了</p>'); + return; + } + $.each(data.Rows, function() { + totPayable = 0; + if ("已通过" == this.statusStr) { + html += '<div class="row shadown_wai" data-id="' + this.id + + '"><div class="row_title "><span class="created_time">提交时间:' + this.createTime + + '</span><span class="indent_status">' + this.statusStr + '</span></div><div class="row_cont">' + } else { + html += '<div class="row shadown_wai" data-id="' + this.id + + '"><div class="row_title "><span class="created_time">提交时间:' + this.createTime + + '</span><span class="indent_status">' + this.statusStr + + '</span><span class="oper"><img src="../img/bianji9.png"></span></div><div class="row_cont">' + } + + $.each(this.list, function() { + totPayable += Number(this.payable) + html += ' <div class="row_block_list"><div class="order_num">订单编号:' + this.orderNo + + '</div><div class="discount_amount">优惠金额:' + this.payable + '</div></div>' + }) + totPayable = totPayable.toFixed(2) + + html += '<div class="combination">总计优惠款:' + totPayable + '</div></div></div>' + }) + if (page == 1) { + $('.committed').html(html); + } else { + $('.committed').append(html); + } + } else { + mui.alert(data.msg) + } + }) + } + + mui('body').on('tap', '.btn', function() { + // 每次触发事件就会使用 innerText 获取纯文本。 + var copy_content = $(this).attr("data-value"); + + // var copy_content = this.innerText; + // 加了一个确认框 让用户选择是否复制 + // mui.confirm('您要复制内容吗?', '小禾CRM', ['取消', '复制内容'], function (e) { + // if (e.index == 1) { + //判断是安卓还是ios + if (mui.os.ios) { + // ios 的方法 这个我没具体研究过 直接拿来用了 + var UIPasteboard = plus.ios.importClass("UIPasteboard"); + var generalPasteboard = UIPasteboard.generalPasteboard(); + //设置 复制的内容也就是 触发事件 innerText 获取的内容 + generalPasteboard.plusCallMethod({ + setValue: copy_content, + forPasteboardType: "public.utf8-plain-text" + }); + generalPasteboard.plusCallMethod({ + valueForPasteboardType: "public.utf8-plain-text" + }); + // 在上边都走完 给用户一个提示 + mui.toast('复制成功') + } else { + //安卓 的方法 这个我没具体研究过 直接拿来用了 + var context = plus.android.importClass("android.content.Context"); + var main = plus.android.runtimeMainActivity(); + var clip = main.getSystemService(context.CLIPBOARD_SERVICE); + plus.android.invoke(clip, "setText", copy_content); + // 在上边都走完 给用户一个提示 + mui.toast('复制成功') + } + // } + }) + + + +}) diff --git a/static/app2/js/perfect-scrollbar.min.js b/static/app2/js/perfect-scrollbar.min.js new file mode 100755 index 0000000..8633db3 --- /dev/null +++ b/static/app2/js/perfect-scrollbar.min.js @@ -0,0 +1,4 @@ +/*! perfect-scrollbar - v0.4.9 +* http://noraesae.github.com/perfect-scrollbar/ +* Copyright (c) 2014 Hyeonje Jun; Licensed MIT */ +(function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(jQuery)})(function(e){"use strict";var t={wheelSpeed:10,wheelPropagation:!1,minScrollbarLength:null,useBothWheelAxes:!1,useKeyboard:!0,suppressScrollX:!1,suppressScrollY:!1,scrollXMarginOffset:0,scrollYMarginOffset:0,includePadding:!1},n=function(){var e=0;return function(){var t=e;return e+=1,".perfect-scrollbar-"+t}}();e.fn.perfectScrollbar=function(o,r){return this.each(function(){var l=e.extend(!0,{},t),a=e(this);if("object"==typeof o?e.extend(!0,l,o):r=o,"update"===r)return a.data("perfect-scrollbar-update")&&a.data("perfect-scrollbar-update")(),a;if("destroy"===r)return a.data("perfect-scrollbar-destroy")&&a.data("perfect-scrollbar-destroy")(),a;if(a.data("perfect-scrollbar"))return a.data("perfect-scrollbar");a.addClass("ps-container");var s,i,c,u,d,p,f,h,v,g,b=e("<div class='ps-scrollbar-x-rail'></div>").appendTo(a),m=e("<div class='ps-scrollbar-y-rail'></div>").appendTo(a),w=e("<div class='ps-scrollbar-x'></div>").appendTo(b),T=e("<div class='ps-scrollbar-y'></div>").appendTo(m),y=parseInt(b.css("bottom"),10),L=parseInt(m.css("right"),10),S=n(),x=function(e,t){var n=e+t,o=u-v;g=0>n?0:n>o?o:n;var r=parseInt(g*(p-u)/(u-v),10);a.scrollTop(r),b.css({bottom:y-r})},M=function(e,t){var n=e+t,o=c-f;h=0>n?0:n>o?o:n;var r=parseInt(h*(d-c)/(c-f),10);a.scrollLeft(r),m.css({right:L-r})},P=function(e){return l.minScrollbarLength&&(e=Math.max(e,l.minScrollbarLength)),e},X=function(){b.css({left:a.scrollLeft(),bottom:y-a.scrollTop(),width:c,display:s?"inherit":"none"}),m.css({top:a.scrollTop(),right:L-a.scrollLeft(),height:u,display:i?"inherit":"none"}),w.css({left:h,width:f}),T.css({top:g,height:v})},D=function(){c=l.includePadding?a.innerWidth():a.width(),u=l.includePadding?a.innerHeight():a.height(),d=a.prop("scrollWidth"),p=a.prop("scrollHeight"),!l.suppressScrollX&&d>c+l.scrollXMarginOffset?(s=!0,f=P(parseInt(c*c/d,10)),h=parseInt(a.scrollLeft()*(c-f)/(d-c),10)):(s=!1,f=0,h=0,a.scrollLeft(0)),!l.suppressScrollY&&p>u+l.scrollYMarginOffset?(i=!0,v=P(parseInt(u*u/p,10)),g=parseInt(a.scrollTop()*(u-v)/(p-u),10)):(i=!1,v=0,g=0,a.scrollTop(0)),g>=u-v&&(g=u-v),h>=c-f&&(h=c-f),X()},I=function(){var t,n;w.bind("mousedown"+S,function(e){n=e.pageX,t=w.position().left,b.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(document).bind("mousemove"+S,function(e){b.hasClass("in-scrolling")&&(M(t,e.pageX-n),e.stopPropagation(),e.preventDefault())}),e(document).bind("mouseup"+S,function(){b.hasClass("in-scrolling")&&b.removeClass("in-scrolling")}),t=n=null},Y=function(){var t,n;T.bind("mousedown"+S,function(e){n=e.pageY,t=T.position().top,m.addClass("in-scrolling"),e.stopPropagation(),e.preventDefault()}),e(document).bind("mousemove"+S,function(e){m.hasClass("in-scrolling")&&(x(t,e.pageY-n),e.stopPropagation(),e.preventDefault())}),e(document).bind("mouseup"+S,function(){m.hasClass("in-scrolling")&&m.removeClass("in-scrolling")}),t=n=null},k=function(e,t){var n=a.scrollTop();if(0===e){if(!i)return!1;if(0===n&&t>0||n>=p-u&&0>t)return!l.wheelPropagation}var o=a.scrollLeft();if(0===t){if(!s)return!1;if(0===o&&0>e||o>=d-c&&e>0)return!l.wheelPropagation}return!0},C=function(){l.wheelSpeed/=10;var e=!1;a.bind("mousewheel"+S,function(t,n,o,r){var c=t.deltaX*t.deltaFactor||o,u=t.deltaY*t.deltaFactor||r;e=!1,l.useBothWheelAxes?i&&!s?(u?a.scrollTop(a.scrollTop()-u*l.wheelSpeed):a.scrollTop(a.scrollTop()+c*l.wheelSpeed),e=!0):s&&!i&&(c?a.scrollLeft(a.scrollLeft()+c*l.wheelSpeed):a.scrollLeft(a.scrollLeft()-u*l.wheelSpeed),e=!0):(a.scrollTop(a.scrollTop()-u*l.wheelSpeed),a.scrollLeft(a.scrollLeft()+c*l.wheelSpeed)),D(),e=e||k(c,u),e&&(t.stopPropagation(),t.preventDefault())}),a.bind("MozMousePixelScroll"+S,function(t){e&&t.preventDefault()})},j=function(){var t=!1;a.bind("mouseenter"+S,function(){t=!0}),a.bind("mouseleave"+S,function(){t=!1});var n=!1;e(document).bind("keydown"+S,function(o){if(t&&!e(document.activeElement).is(":input,[contenteditable]")){var r=0,l=0;switch(o.which){case 37:r=-30;break;case 38:l=30;break;case 39:r=30;break;case 40:l=-30;break;case 33:l=90;break;case 32:case 34:l=-90;break;case 35:l=-u;break;case 36:l=u;break;default:return}a.scrollTop(a.scrollTop()-l),a.scrollLeft(a.scrollLeft()+r),n=k(r,l),n&&o.preventDefault()}})},O=function(){var e=function(e){e.stopPropagation()};T.bind("click"+S,e),m.bind("click"+S,function(e){var t=parseInt(v/2,10),n=e.pageY-m.offset().top-t,o=u-v,r=n/o;0>r?r=0:r>1&&(r=1),a.scrollTop((p-u)*r)}),w.bind("click"+S,e),b.bind("click"+S,function(e){var t=parseInt(f/2,10),n=e.pageX-b.offset().left-t,o=c-f,r=n/o;0>r?r=0:r>1&&(r=1),a.scrollLeft((d-c)*r)})},E=function(){var t=function(e,t){a.scrollTop(a.scrollTop()-t),a.scrollLeft(a.scrollLeft()-e),D()},n={},o=0,r={},l=null,s=!1;e(window).bind("touchstart"+S,function(){s=!0}),e(window).bind("touchend"+S,function(){s=!1}),a.bind("touchstart"+S,function(e){var t=e.originalEvent.targetTouches[0];n.pageX=t.pageX,n.pageY=t.pageY,o=(new Date).getTime(),null!==l&&clearInterval(l),e.stopPropagation()}),a.bind("touchmove"+S,function(e){if(!s&&1===e.originalEvent.targetTouches.length){var l=e.originalEvent.targetTouches[0],a={};a.pageX=l.pageX,a.pageY=l.pageY;var i=a.pageX-n.pageX,c=a.pageY-n.pageY;t(i,c),n=a;var u=(new Date).getTime(),d=u-o;d>0&&(r.x=i/d,r.y=c/d,o=u),e.preventDefault()}}),a.bind("touchend"+S,function(){clearInterval(l),l=setInterval(function(){return.01>Math.abs(r.x)&&.01>Math.abs(r.y)?(clearInterval(l),void 0):(t(30*r.x,30*r.y),r.x*=.8,r.y*=.8,void 0)},10)})},H=function(){a.bind("scroll"+S,function(){D()})},A=function(){a.unbind(S),e(window).unbind(S),e(document).unbind(S),a.data("perfect-scrollbar",null),a.data("perfect-scrollbar-update",null),a.data("perfect-scrollbar-destroy",null),w.remove(),T.remove(),b.remove(),m.remove(),w=T=c=u=d=p=f=h=y=v=g=L=null},W=function(t){a.addClass("ie").addClass("ie"+t);var n=function(){var t=function(){e(this).addClass("hover")},n=function(){e(this).removeClass("hover")};a.bind("mouseenter"+S,t).bind("mouseleave"+S,n),b.bind("mouseenter"+S,t).bind("mouseleave"+S,n),m.bind("mouseenter"+S,t).bind("mouseleave"+S,n),w.bind("mouseenter"+S,t).bind("mouseleave"+S,n),T.bind("mouseenter"+S,t).bind("mouseleave"+S,n)},o=function(){X=function(){w.css({left:h+a.scrollLeft(),bottom:y,width:f}),T.css({top:g+a.scrollTop(),right:L,height:v}),w.hide().show(),T.hide().show()}};6===t&&(n(),o())},q="ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,F=function(){var e=navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);e&&"msie"===e[1]&&W(parseInt(e[2],10)),D(),H(),I(),Y(),O(),q&&E(),a.mousewheel&&C(),l.useKeyboard&&j(),a.data("perfect-scrollbar",a),a.data("perfect-scrollbar-update",D),a.data("perfect-scrollbar-destroy",A)};return F(),a})}}),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(e){function t(t){var a=t||window.event,s=i.call(arguments,1),c=0,u=0,d=0,p=0;if(t=e.event.fix(a),t.type="mousewheel","detail"in a&&(d=-1*a.detail),"wheelDelta"in a&&(d=a.wheelDelta),"wheelDeltaY"in a&&(d=a.wheelDeltaY),"wheelDeltaX"in a&&(u=-1*a.wheelDeltaX),"axis"in a&&a.axis===a.HORIZONTAL_AXIS&&(u=-1*d,d=0),c=0===d?u:d,"deltaY"in a&&(d=-1*a.deltaY,c=d),"deltaX"in a&&(u=a.deltaX,0===d&&(c=-1*u)),0!==d||0!==u){if(1===a.deltaMode){var f=e.data(this,"mousewheel-line-height");c*=f,d*=f,u*=f}else if(2===a.deltaMode){var h=e.data(this,"mousewheel-page-height");c*=h,d*=h,u*=h}return p=Math.max(Math.abs(d),Math.abs(u)),(!l||l>p)&&(l=p,o(a,p)&&(l/=40)),o(a,p)&&(c/=40,u/=40,d/=40),c=Math[c>=1?"floor":"ceil"](c/l),u=Math[u>=1?"floor":"ceil"](u/l),d=Math[d>=1?"floor":"ceil"](d/l),t.deltaX=u,t.deltaY=d,t.deltaFactor=l,t.deltaMode=0,s.unshift(t,c,u,d),r&&clearTimeout(r),r=setTimeout(n,200),(e.event.dispatch||e.event.handle).apply(this,s)}}function n(){l=null}function o(e,t){return u.settings.adjustOldDeltas&&"mousewheel"===e.type&&0===t%120}var r,l,a=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],s="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(e.event.fixHooks)for(var c=a.length;c;)e.event.fixHooks[a[--c]]=e.event.mouseHooks;var u=e.event.special.mousewheel={version:"3.1.9",setup:function(){if(this.addEventListener)for(var n=s.length;n;)this.addEventListener(s[--n],t,!1);else this.onmousewheel=t;e.data(this,"mousewheel-line-height",u.getLineHeight(this)),e.data(this,"mousewheel-page-height",u.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=s.length;e;)this.removeEventListener(s[--e],t,!1);else this.onmousewheel=null},getLineHeight:function(t){return parseInt(e(t)["offsetParent"in e.fn?"offsetParent":"parent"]().css("fontSize"),10)},getPageHeight:function(t){return e(t).height()},settings:{adjustOldDeltas:!0}};e.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}})}); \ No newline at end of file diff --git a/static/app2/js/photoswipe-ui-default.min.js b/static/app2/js/photoswipe-ui-default.min.js new file mode 100755 index 0000000..79115c5 --- /dev/null +++ b/static/app2/js/photoswipe-ui-default.min.js @@ -0,0 +1,4 @@ +/*! PhotoSwipe Default UI - 4.1.2 - 2017-04-05 +* http://photoswipe.com +* Copyright (c) 2017 Dmitry Semenov; */ +!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.PhotoSwipeUI_Default=b()}(this,function(){"use strict";var a=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v=this,w=!1,x=!0,y=!0,z={barsSize:{top:44,bottom:"auto"},closeElClasses:["item","caption","zoom-wrap","ui","top-bar"],timeToIdle:4e3,timeToIdleOutside:1e3,loadingIndicatorDelay:1e3,addCaptionHTMLFn:function(a,b){return a.title?(b.children[0].innerHTML=a.title,!0):(b.children[0].innerHTML="",!1)},closeEl:!0,captionEl:!0,fullscreenEl:!0,zoomEl:!0,shareEl:!0,counterEl:!0,arrowEl:!0,preloaderEl:!0,tapToClose:!1,tapToToggleControls:!0,clickToCloseNonZoomable:!0,shareButtons:[{id:"facebook",label:"Share on Facebook",url:"https://www.facebook.com/sharer/sharer.php?u={{url}}"},{id:"twitter",label:"Tweet",url:"https://twitter.com/intent/tweet?text={{text}}&url={{url}}"},{id:"pinterest",label:"Pin it",url:"http://www.pinterest.com/pin/create/button/?url={{url}}&media={{image_url}}&description={{text}}"},{id:"download",label:"Download image",url:"{{raw_image_url}}",download:!0}],getImageURLForShare:function(){return a.currItem.src||""},getPageURLForShare:function(){return window.location.href},getTextForShare:function(){return a.currItem.title||""},indexIndicatorSep:" / ",fitControlsWidth:1200},A=function(a){if(r)return!0;a=a||window.event,q.timeToIdle&&q.mouseUsed&&!k&&K();for(var c,d,e=a.target||a.srcElement,f=e.getAttribute("class")||"",g=0;g<S.length;g++)c=S[g],c.onTap&&f.indexOf("pswp__"+c.name)>-1&&(c.onTap(),d=!0);if(d){a.stopPropagation&&a.stopPropagation(),r=!0;var h=b.features.isOldAndroid?600:30;s=setTimeout(function(){r=!1},h)}},B=function(){return!a.likelyTouchDevice||q.mouseUsed||screen.width>q.fitControlsWidth},C=function(a,c,d){b[(d?"add":"remove")+"Class"](a,"pswp__"+c)},D=function(){var a=1===q.getNumItemsFn();a!==p&&(C(d,"ui--one-slide",a),p=a)},E=function(){C(i,"share-modal--hidden",y)},F=function(){return y=!y,y?(b.removeClass(i,"pswp__share-modal--fade-in"),setTimeout(function(){y&&E()},300)):(E(),setTimeout(function(){y||b.addClass(i,"pswp__share-modal--fade-in")},30)),y||H(),!1},G=function(b){b=b||window.event;var c=b.target||b.srcElement;return a.shout("shareLinkClick",b,c),!!c.href&&(!!c.hasAttribute("download")||(window.open(c.href,"pswp_share","scrollbars=yes,resizable=yes,toolbar=no,location=yes,width=550,height=420,top=100,left="+(window.screen?Math.round(screen.width/2-275):100)),y||F(),!1))},H=function(){for(var a,b,c,d,e,f="",g=0;g<q.shareButtons.length;g++)a=q.shareButtons[g],c=q.getImageURLForShare(a),d=q.getPageURLForShare(a),e=q.getTextForShare(a),b=a.url.replace("{{url}}",encodeURIComponent(d)).replace("{{image_url}}",encodeURIComponent(c)).replace("{{raw_image_url}}",c).replace("{{text}}",encodeURIComponent(e)),f+='<a href="'+b+'" target="_blank" class="pswp__share--'+a.id+'"'+(a.download?"download":"")+">"+a.label+"</a>",q.parseShareButtonOut&&(f=q.parseShareButtonOut(a,f));i.children[0].innerHTML=f,i.children[0].onclick=G},I=function(a){for(var c=0;c<q.closeElClasses.length;c++)if(b.hasClass(a,"pswp__"+q.closeElClasses[c]))return!0},J=0,K=function(){clearTimeout(u),J=0,k&&v.setIdle(!1)},L=function(a){a=a?a:window.event;var b=a.relatedTarget||a.toElement;b&&"HTML"!==b.nodeName||(clearTimeout(u),u=setTimeout(function(){v.setIdle(!0)},q.timeToIdleOutside))},M=function(){q.fullscreenEl&&!b.features.isOldAndroid&&(c||(c=v.getFullscreenAPI()),c?(b.bind(document,c.eventK,v.updateFullscreen),v.updateFullscreen(),b.addClass(a.template,"pswp--supports-fs")):b.removeClass(a.template,"pswp--supports-fs"))},N=function(){q.preloaderEl&&(O(!0),l("beforeChange",function(){clearTimeout(o),o=setTimeout(function(){a.currItem&&a.currItem.loading?(!a.allowProgressiveImg()||a.currItem.img&&!a.currItem.img.naturalWidth)&&O(!1):O(!0)},q.loadingIndicatorDelay)}),l("imageLoadComplete",function(b,c){a.currItem===c&&O(!0)}))},O=function(a){n!==a&&(C(m,"preloader--active",!a),n=a)},P=function(a){var c=a.vGap;if(B()){var g=q.barsSize;if(q.captionEl&&"auto"===g.bottom)if(f||(f=b.createEl("pswp__caption pswp__caption--fake"),f.appendChild(b.createEl("pswp__caption__center")),d.insertBefore(f,e),b.addClass(d,"pswp__ui--fit")),q.addCaptionHTMLFn(a,f,!0)){var h=f.clientHeight;c.bottom=parseInt(h,10)||44}else c.bottom=g.top;else c.bottom="auto"===g.bottom?0:g.bottom;c.top=g.top}else c.top=c.bottom=0},Q=function(){q.timeToIdle&&l("mouseUsed",function(){b.bind(document,"mousemove",K),b.bind(document,"mouseout",L),t=setInterval(function(){J++,2===J&&v.setIdle(!0)},q.timeToIdle/2)})},R=function(){l("onVerticalDrag",function(a){x&&a<.95?v.hideControls():!x&&a>=.95&&v.showControls()});var a;l("onPinchClose",function(b){x&&b<.9?(v.hideControls(),a=!0):a&&!x&&b>.9&&v.showControls()}),l("zoomGestureEnded",function(){a=!1,a&&!x&&v.showControls()})},S=[{name:"caption",option:"captionEl",onInit:function(a){e=a}},{name:"share-modal",option:"shareEl",onInit:function(a){i=a},onTap:function(){F()}},{name:"button--share",option:"shareEl",onInit:function(a){h=a},onTap:function(){F()}},{name:"button--zoom",option:"zoomEl",onTap:a.toggleDesktopZoom},{name:"counter",option:"counterEl",onInit:function(a){g=a}},{name:"button--close",option:"closeEl",onTap:a.close},{name:"button--arrow--left",option:"arrowEl",onTap:a.prev},{name:"button--arrow--right",option:"arrowEl",onTap:a.next},{name:"button--fs",option:"fullscreenEl",onTap:function(){c.isFullscreen()?c.exit():c.enter()}},{name:"preloader",option:"preloaderEl",onInit:function(a){m=a}}],T=function(){var a,c,e,f=function(d){if(d)for(var f=d.length,g=0;g<f;g++){a=d[g],c=a.className;for(var h=0;h<S.length;h++)e=S[h],c.indexOf("pswp__"+e.name)>-1&&(q[e.option]?(b.removeClass(a,"pswp__element--disabled"),e.onInit&&e.onInit(a)):b.addClass(a,"pswp__element--disabled"))}};f(d.children);var g=b.getChildByClass(d,"pswp__top-bar");g&&f(g.children)};v.init=function(){b.extend(a.options,z,!0),q=a.options,d=b.getChildByClass(a.scrollWrap,"pswp__ui"),l=a.listen,R(),l("beforeChange",v.update),l("doubleTap",function(b){var c=a.currItem.initialZoomLevel;a.getZoomLevel()!==c?a.zoomTo(c,b,333):a.zoomTo(q.getDoubleTapZoom(!1,a.currItem),b,333)}),l("preventDragEvent",function(a,b,c){var d=a.target||a.srcElement;d&&d.getAttribute("class")&&a.type.indexOf("mouse")>-1&&(d.getAttribute("class").indexOf("__caption")>0||/(SMALL|STRONG|EM)/i.test(d.tagName))&&(c.prevent=!1)}),l("bindEvents",function(){b.bind(d,"pswpTap click",A),b.bind(a.scrollWrap,"pswpTap",v.onGlobalTap),a.likelyTouchDevice||b.bind(a.scrollWrap,"mouseover",v.onMouseOver)}),l("unbindEvents",function(){y||F(),t&&clearInterval(t),b.unbind(document,"mouseout",L),b.unbind(document,"mousemove",K),b.unbind(d,"pswpTap click",A),b.unbind(a.scrollWrap,"pswpTap",v.onGlobalTap),b.unbind(a.scrollWrap,"mouseover",v.onMouseOver),c&&(b.unbind(document,c.eventK,v.updateFullscreen),c.isFullscreen()&&(q.hideAnimationDuration=0,c.exit()),c=null)}),l("destroy",function(){q.captionEl&&(f&&d.removeChild(f),b.removeClass(e,"pswp__caption--empty")),i&&(i.children[0].onclick=null),b.removeClass(d,"pswp__ui--over-close"),b.addClass(d,"pswp__ui--hidden"),v.setIdle(!1)}),q.showAnimationDuration||b.removeClass(d,"pswp__ui--hidden"),l("initialZoomIn",function(){q.showAnimationDuration&&b.removeClass(d,"pswp__ui--hidden")}),l("initialZoomOut",function(){b.addClass(d,"pswp__ui--hidden")}),l("parseVerticalMargin",P),T(),q.shareEl&&h&&i&&(y=!0),D(),Q(),M(),N()},v.setIdle=function(a){k=a,C(d,"ui--idle",a)},v.update=function(){x&&a.currItem?(v.updateIndexIndicator(),q.captionEl&&(q.addCaptionHTMLFn(a.currItem,e),C(e,"caption--empty",!a.currItem.title)),w=!0):w=!1,y||F(),D()},v.updateFullscreen=function(d){d&&setTimeout(function(){a.setScrollOffset(0,b.getScrollY())},50),b[(c.isFullscreen()?"add":"remove")+"Class"](a.template,"pswp--fs")},v.updateIndexIndicator=function(){q.counterEl&&(g.innerHTML=a.getCurrentIndex()+1+q.indexIndicatorSep+q.getNumItemsFn())},v.onGlobalTap=function(c){c=c||window.event;var d=c.target||c.srcElement;if(!r)if(c.detail&&"mouse"===c.detail.pointerType){if(I(d))return void a.close();b.hasClass(d,"pswp__img")&&(1===a.getZoomLevel()&&a.getZoomLevel()<=a.currItem.fitRatio?q.clickToCloseNonZoomable&&a.close():a.toggleDesktopZoom(c.detail.releasePoint))}else if(q.tapToToggleControls&&(x?v.hideControls():v.showControls()),q.tapToClose&&(b.hasClass(d,"pswp__img")||I(d)))return void a.close()},v.onMouseOver=function(a){a=a||window.event;var b=a.target||a.srcElement;C(d,"ui--over-close",I(b))},v.hideControls=function(){b.addClass(d,"pswp__ui--hidden"),x=!1},v.showControls=function(){x=!0,w||v.update(),b.removeClass(d,"pswp__ui--hidden")},v.supportsFullscreen=function(){var a=document;return!!(a.exitFullscreen||a.mozCancelFullScreen||a.webkitExitFullscreen||a.msExitFullscreen)},v.getFullscreenAPI=function(){var b,c=document.documentElement,d="fullscreenchange";return c.requestFullscreen?b={enterK:"requestFullscreen",exitK:"exitFullscreen",elementK:"fullscreenElement",eventK:d}:c.mozRequestFullScreen?b={enterK:"mozRequestFullScreen",exitK:"mozCancelFullScreen",elementK:"mozFullScreenElement",eventK:"moz"+d}:c.webkitRequestFullscreen?b={enterK:"webkitRequestFullscreen",exitK:"webkitExitFullscreen",elementK:"webkitFullscreenElement",eventK:"webkit"+d}:c.msRequestFullscreen&&(b={enterK:"msRequestFullscreen",exitK:"msExitFullscreen",elementK:"msFullscreenElement",eventK:"MSFullscreenChange"}),b&&(b.enter=function(){return j=q.closeOnScroll,q.closeOnScroll=!1,"webkitRequestFullscreen"!==this.enterK?a.template[this.enterK]():void a.template[this.enterK](Element.ALLOW_KEYBOARD_INPUT)},b.exit=function(){return q.closeOnScroll=j,document[this.exitK]()},b.isFullscreen=function(){return document[this.elementK]}),b}};return a}); \ No newline at end of file diff --git a/static/app2/js/photoswipe.js b/static/app2/js/photoswipe.js new file mode 100755 index 0000000..837859f --- /dev/null +++ b/static/app2/js/photoswipe.js @@ -0,0 +1,3734 @@ +/*! PhotoSwipe - v4.1.2 - 2017-04-05 +* http://photoswipe.com +* Copyright (c) 2017 Dmitry Semenov; */ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.PhotoSwipe = factory(); + } +})(this, function () { + + 'use strict'; + var PhotoSwipe = function(template, UiClass, items, options){ + +/*>>framework-bridge*/ +/** + * + * Set of generic functions used by gallery. + * + * You're free to modify anything here as long as functionality is kept. + * + */ +var framework = { + features: null, + bind: function(target, type, listener, unbind) { + var methodName = (unbind ? 'remove' : 'add') + 'EventListener'; + type = type.split(' '); + for(var i = 0; i < type.length; i++) { + if(type[i]) { + target[methodName]( type[i], listener, false); + } + } + }, + isArray: function(obj) { + return (obj instanceof Array); + }, + createEl: function(classes, tag) { + var el = document.createElement(tag || 'div'); + if(classes) { + el.className = classes; + } + return el; + }, + getScrollY: function() { + var yOffset = window.pageYOffset; + return yOffset !== undefined ? yOffset : document.documentElement.scrollTop; + }, + unbind: function(target, type, listener) { + framework.bind(target,type,listener,true); + }, + removeClass: function(el, className) { + var reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); + el.className = el.className.replace(reg, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + }, + addClass: function(el, className) { + if( !framework.hasClass(el,className) ) { + el.className += (el.className ? ' ' : '') + className; + } + }, + hasClass: function(el, className) { + return el.className && new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); + }, + getChildByClass: function(parentEl, childClassName) { + var node = parentEl.firstChild; + while(node) { + if( framework.hasClass(node, childClassName) ) { + return node; + } + node = node.nextSibling; + } + }, + arraySearch: function(array, value, key) { + var i = array.length; + while(i--) { + if(array[i][key] === value) { + return i; + } + } + return -1; + }, + extend: function(o1, o2, preventOverwrite) { + for (var prop in o2) { + if (o2.hasOwnProperty(prop)) { + if(preventOverwrite && o1.hasOwnProperty(prop)) { + continue; + } + o1[prop] = o2[prop]; + } + } + }, + easing: { + sine: { + out: function(k) { + return Math.sin(k * (Math.PI / 2)); + }, + inOut: function(k) { + return - (Math.cos(Math.PI * k) - 1) / 2; + } + }, + cubic: { + out: function(k) { + return --k * k * k + 1; + } + } + /* + elastic: { + out: function ( k ) { + + var s, a = 0.1, p = 0.4; + if ( k === 0 ) return 0; + if ( k === 1 ) return 1; + if ( !a || a < 1 ) { a = 1; s = p / 4; } + else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); + return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 ); + + }, + }, + back: { + out: function ( k ) { + var s = 1.70158; + return --k * k * ( ( s + 1 ) * k + s ) + 1; + } + } + */ + }, + + /** + * + * @return {object} + * + * { + * raf : request animation frame function + * caf : cancel animation frame function + * transfrom : transform property key (with vendor), or null if not supported + * oldIE : IE8 or below + * } + * + */ + detectFeatures: function() { + if(framework.features) { + return framework.features; + } + var helperEl = framework.createEl(), + helperStyle = helperEl.style, + vendor = '', + features = {}; + + // IE8 and below + features.oldIE = document.all && !document.addEventListener; + + features.touch = 'ontouchstart' in window; + + if(window.requestAnimationFrame) { + features.raf = window.requestAnimationFrame; + features.caf = window.cancelAnimationFrame; + } + + features.pointerEvent = navigator.pointerEnabled || navigator.msPointerEnabled; + + // fix false-positive detection of old Android in new IE + // (IE11 ua string contains "Android 4.0") + + if(!features.pointerEvent) { + + var ua = navigator.userAgent; + + // Detect if device is iPhone or iPod and if it's older than iOS 8 + // http://stackoverflow.com/a/14223920 + // + // This detection is made because of buggy top/bottom toolbars + // that don't trigger window.resize event. + // For more info refer to _isFixedPosition variable in core.js + + if (/iP(hone|od)/.test(navigator.platform)) { + var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/); + if(v && v.length > 0) { + v = parseInt(v[1], 10); + if(v >= 1 && v < 8 ) { + features.isOldIOSPhone = true; + } + } + } + + // Detect old Android (before KitKat) + // due to bugs related to position:fixed + // http://stackoverflow.com/questions/7184573/pick-up-the-android-version-in-the-browser-by-javascript + + var match = ua.match(/Android\s([0-9\.]*)/); + var androidversion = match ? match[1] : 0; + androidversion = parseFloat(androidversion); + if(androidversion >= 1 ) { + if(androidversion < 4.4) { + features.isOldAndroid = true; // for fixed position bug & performance + } + features.androidVersion = androidversion; // for touchend bug + } + features.isMobileOpera = /opera mini|opera mobi/i.test(ua); + + // p.s. yes, yes, UA sniffing is bad, propose your solution for above bugs. + } + + var styleChecks = ['transform', 'perspective', 'animationName'], + vendors = ['', 'webkit','Moz','ms','O'], + styleCheckItem, + styleName; + + for(var i = 0; i < 4; i++) { + vendor = vendors[i]; + + for(var a = 0; a < 3; a++) { + styleCheckItem = styleChecks[a]; + + // uppercase first letter of property name, if vendor is present + styleName = vendor + (vendor ? + styleCheckItem.charAt(0).toUpperCase() + styleCheckItem.slice(1) : + styleCheckItem); + + if(!features[styleCheckItem] && styleName in helperStyle ) { + features[styleCheckItem] = styleName; + } + } + + if(vendor && !features.raf) { + vendor = vendor.toLowerCase(); + features.raf = window[vendor+'RequestAnimationFrame']; + if(features.raf) { + features.caf = window[vendor+'CancelAnimationFrame'] || + window[vendor+'CancelRequestAnimationFrame']; + } + } + } + + if(!features.raf) { + var lastTime = 0; + features.raf = function(fn) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { fn(currTime + timeToCall); }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + features.caf = function(id) { clearTimeout(id); }; + } + + // Detect SVG support + features.svg = !!document.createElementNS && + !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect; + + framework.features = features; + + return features; + } +}; + +framework.detectFeatures(); + +// Override addEventListener for old versions of IE +if(framework.features.oldIE) { + + framework.bind = function(target, type, listener, unbind) { + + type = type.split(' '); + + var methodName = (unbind ? 'detach' : 'attach') + 'Event', + evName, + _handleEv = function() { + listener.handleEvent.call(listener); + }; + + for(var i = 0; i < type.length; i++) { + evName = type[i]; + if(evName) { + + if(typeof listener === 'object' && listener.handleEvent) { + if(!unbind) { + listener['oldIE' + evName] = _handleEv; + } else { + if(!listener['oldIE' + evName]) { + return false; + } + } + + target[methodName]( 'on' + evName, listener['oldIE' + evName]); + } else { + target[methodName]( 'on' + evName, listener); + } + + } + } + }; + +} + +/*>>framework-bridge*/ + +/*>>core*/ +//function(template, UiClass, items, options) + +var self = this; + +/** + * Static vars, don't change unless you know what you're doing. + */ +var DOUBLE_TAP_RADIUS = 25, + NUM_HOLDERS = 3; + +/** + * Options + */ +var _options = { + allowPanToNext:true, + spacing: 0.12, + bgOpacity: 1, + mouseUsed: false, + loop: true, + pinchToClose: true, + closeOnScroll: true, + closeOnVerticalDrag: true, + verticalDragRange: 0.75, + hideAnimationDuration: 333, + showAnimationDuration: 333, + showHideOpacity: false, + focus: true, + escKey: true, + arrowKeys: true, + mainScrollEndFriction: 0.35, + panEndFriction: 0.35, + isClickableElement: function(el) { + return el.tagName === 'A'; + }, + getDoubleTapZoom: function(isMouseClick, item) { + if(isMouseClick) { + return 1; + } else { + return item.initialZoomLevel < 0.7 ? 1 : 1.33; + } + }, + maxSpreadZoom: 1.33, + modal: true, + + // not fully implemented yet + scaleMode: 'fit' // TODO +}; +framework.extend(_options, options); + + +/** + * Private helper variables & functions + */ + +var _getEmptyPoint = function() { + return {x:0,y:0}; + }; + +var _isOpen, + _isDestroying, + _closedByScroll, + _currentItemIndex, + _containerStyle, + _containerShiftIndex, + _currPanDist = _getEmptyPoint(), + _startPanOffset = _getEmptyPoint(), + _panOffset = _getEmptyPoint(), + _upMoveEvents, // drag move, drag end & drag cancel events array + _downEvents, // drag start events array + _globalEventHandlers, + _viewportSize = {}, + _currZoomLevel, + _startZoomLevel, + _translatePrefix, + _translateSufix, + _updateSizeInterval, + _itemsNeedUpdate, + _currPositionIndex = 0, + _offset = {}, + _slideSize = _getEmptyPoint(), // size of slide area, including spacing + _itemHolders, + _prevItemIndex, + _indexDiff = 0, // difference of indexes since last content update + _dragStartEvent, + _dragMoveEvent, + _dragEndEvent, + _dragCancelEvent, + _transformKey, + _pointerEventEnabled, + _isFixedPosition = true, + _likelyTouchDevice, + _modules = [], + _requestAF, + _cancelAF, + _initalClassName, + _initalWindowScrollY, + _oldIE, + _currentWindowScrollY, + _features, + _windowVisibleSize = {}, + _renderMaxResolution = false, + _orientationChangeTimeout, + + + // Registers PhotoSWipe module (History, Controller ...) + _registerModule = function(name, module) { + framework.extend(self, module.publicMethods); + _modules.push(name); + }, + + _getLoopedId = function(index) { + var numSlides = _getNumItems(); + if(index > numSlides - 1) { + return index - numSlides; + } else if(index < 0) { + return numSlides + index; + } + return index; + }, + + // Micro bind/trigger + _listeners = {}, + _listen = function(name, fn) { + if(!_listeners[name]) { + _listeners[name] = []; + } + return _listeners[name].push(fn); + }, + _shout = function(name) { + var listeners = _listeners[name]; + + if(listeners) { + var args = Array.prototype.slice.call(arguments); + args.shift(); + + for(var i = 0; i < listeners.length; i++) { + listeners[i].apply(self, args); + } + } + }, + + _getCurrentTime = function() { + return new Date().getTime(); + }, + _applyBgOpacity = function(opacity) { + _bgOpacity = opacity; + self.bg.style.opacity = opacity * _options.bgOpacity; + }, + + _applyZoomTransform = function(styleObj,x,y,zoom,item) { + if(!_renderMaxResolution || (item && item !== self.currItem) ) { + zoom = zoom / (item ? item.fitRatio : self.currItem.fitRatio); + } + + styleObj[_transformKey] = _translatePrefix + x + 'px, ' + y + 'px' + _translateSufix + ' scale(' + zoom + ')'; + }, + _applyCurrentZoomPan = function( allowRenderResolution ) { + if(_currZoomElementStyle) { + + if(allowRenderResolution) { + if(_currZoomLevel > self.currItem.fitRatio) { + if(!_renderMaxResolution) { + _setImageSize(self.currItem, false, true); + _renderMaxResolution = true; + } + } else { + if(_renderMaxResolution) { + _setImageSize(self.currItem); + _renderMaxResolution = false; + } + } + } + + + _applyZoomTransform(_currZoomElementStyle, _panOffset.x, _panOffset.y, _currZoomLevel); + } + }, + _applyZoomPanToItem = function(item) { + if(item.container) { + + _applyZoomTransform(item.container.style, + item.initialPosition.x, + item.initialPosition.y, + item.initialZoomLevel, + item); + } + }, + _setTranslateX = function(x, elStyle) { + elStyle[_transformKey] = _translatePrefix + x + 'px, 0px' + _translateSufix; + }, + _moveMainScroll = function(x, dragging) { + + if(!_options.loop && dragging) { + var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x, + delta = Math.round(x - _mainScrollPos.x); + + if( (newSlideIndexOffset < 0 && delta > 0) || + (newSlideIndexOffset >= _getNumItems() - 1 && delta < 0) ) { + x = _mainScrollPos.x + delta * _options.mainScrollEndFriction; + } + } + + _mainScrollPos.x = x; + _setTranslateX(x, _containerStyle); + }, + _calculatePanOffset = function(axis, zoomLevel) { + var m = _midZoomPoint[axis] - _offset[axis]; + return _startPanOffset[axis] + _currPanDist[axis] + m - m * ( zoomLevel / _startZoomLevel ); + }, + + _equalizePoints = function(p1, p2) { + p1.x = p2.x; + p1.y = p2.y; + if(p2.id) { + p1.id = p2.id; + } + }, + _roundPoint = function(p) { + p.x = Math.round(p.x); + p.y = Math.round(p.y); + }, + + _mouseMoveTimeout = null, + _onFirstMouseMove = function() { + // Wait until mouse move event is fired at least twice during 100ms + // We do this, because some mobile browsers trigger it on touchstart + if(_mouseMoveTimeout ) { + framework.unbind(document, 'mousemove', _onFirstMouseMove); + framework.addClass(template, 'pswp--has_mouse'); + _options.mouseUsed = true; + _shout('mouseUsed'); + } + _mouseMoveTimeout = setTimeout(function() { + _mouseMoveTimeout = null; + }, 100); + }, + + _bindEvents = function() { + framework.bind(document, 'keydown', self); + + if(_features.transform) { + // don't bind click event in browsers that don't support transform (mostly IE8) + framework.bind(self.scrollWrap, 'click', self); + } + + + if(!_options.mouseUsed) { + framework.bind(document, 'mousemove', _onFirstMouseMove); + } + + framework.bind(window, 'resize scroll orientationchange', self); + + _shout('bindEvents'); + }, + + _unbindEvents = function() { + framework.unbind(window, 'resize scroll orientationchange', self); + framework.unbind(window, 'scroll', _globalEventHandlers.scroll); + framework.unbind(document, 'keydown', self); + framework.unbind(document, 'mousemove', _onFirstMouseMove); + + if(_features.transform) { + framework.unbind(self.scrollWrap, 'click', self); + } + + if(_isDragging) { + framework.unbind(window, _upMoveEvents, self); + } + + clearTimeout(_orientationChangeTimeout); + + _shout('unbindEvents'); + }, + + _calculatePanBounds = function(zoomLevel, update) { + var bounds = _calculateItemSize( self.currItem, _viewportSize, zoomLevel ); + if(update) { + _currPanBounds = bounds; + } + return bounds; + }, + + _getMinZoomLevel = function(item) { + if(!item) { + item = self.currItem; + } + return item.initialZoomLevel; + }, + _getMaxZoomLevel = function(item) { + if(!item) { + item = self.currItem; + } + return item.w > 0 ? _options.maxSpreadZoom : 1; + }, + + // Return true if offset is out of the bounds + _modifyDestPanOffset = function(axis, destPanBounds, destPanOffset, destZoomLevel) { + if(destZoomLevel === self.currItem.initialZoomLevel) { + destPanOffset[axis] = self.currItem.initialPosition[axis]; + return true; + } else { + destPanOffset[axis] = _calculatePanOffset(axis, destZoomLevel); + + if(destPanOffset[axis] > destPanBounds.min[axis]) { + destPanOffset[axis] = destPanBounds.min[axis]; + return true; + } else if(destPanOffset[axis] < destPanBounds.max[axis] ) { + destPanOffset[axis] = destPanBounds.max[axis]; + return true; + } + } + return false; + }, + + _setupTransforms = function() { + + if(_transformKey) { + // setup 3d transforms + var allow3dTransform = _features.perspective && !_likelyTouchDevice; + _translatePrefix = 'translate' + (allow3dTransform ? '3d(' : '('); + _translateSufix = _features.perspective ? ', 0px)' : ')'; + return; + } + + // Override zoom/pan/move functions in case old browser is used (most likely IE) + // (so they use left/top/width/height, instead of CSS transform) + + _transformKey = 'left'; + framework.addClass(template, 'pswp--ie'); + + _setTranslateX = function(x, elStyle) { + elStyle.left = x + 'px'; + }; + _applyZoomPanToItem = function(item) { + + var zoomRatio = item.fitRatio > 1 ? 1 : item.fitRatio, + s = item.container.style, + w = zoomRatio * item.w, + h = zoomRatio * item.h; + + s.width = w + 'px'; + s.height = h + 'px'; + s.left = item.initialPosition.x + 'px'; + s.top = item.initialPosition.y + 'px'; + + }; + _applyCurrentZoomPan = function() { + if(_currZoomElementStyle) { + + var s = _currZoomElementStyle, + item = self.currItem, + zoomRatio = item.fitRatio > 1 ? 1 : item.fitRatio, + w = zoomRatio * item.w, + h = zoomRatio * item.h; + + s.width = w + 'px'; + s.height = h + 'px'; + + + s.left = _panOffset.x + 'px'; + s.top = _panOffset.y + 'px'; + } + + }; + }, + + _onKeyDown = function(e) { + var keydownAction = ''; + if(_options.escKey && e.keyCode === 27) { + keydownAction = 'close'; + } else if(_options.arrowKeys) { + if(e.keyCode === 37) { + keydownAction = 'prev'; + } else if(e.keyCode === 39) { + keydownAction = 'next'; + } + } + + if(keydownAction) { + // don't do anything if special key pressed to prevent from overriding default browser actions + // e.g. in Chrome on Mac cmd+arrow-left returns to previous page + if( !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey ) { + if(e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + self[keydownAction](); + } + } + }, + + _onGlobalClick = function(e) { + if(!e) { + return; + } + + // don't allow click event to pass through when triggering after drag or some other gesture + if(_moved || _zoomStarted || _mainScrollAnimating || _verticalDragInitiated) { + e.preventDefault(); + e.stopPropagation(); + } + }, + + _updatePageScrollOffset = function() { + self.setScrollOffset(0, framework.getScrollY()); + }; + + + + + + + +// Micro animation engine +var _animations = {}, + _numAnimations = 0, + _stopAnimation = function(name) { + if(_animations[name]) { + if(_animations[name].raf) { + _cancelAF( _animations[name].raf ); + } + _numAnimations--; + delete _animations[name]; + } + }, + _registerStartAnimation = function(name) { + if(_animations[name]) { + _stopAnimation(name); + } + if(!_animations[name]) { + _numAnimations++; + _animations[name] = {}; + } + }, + _stopAllAnimations = function() { + for (var prop in _animations) { + + if( _animations.hasOwnProperty( prop ) ) { + _stopAnimation(prop); + } + + } + }, + _animateProp = function(name, b, endProp, d, easingFn, onUpdate, onComplete) { + var startAnimTime = _getCurrentTime(), t; + _registerStartAnimation(name); + + var animloop = function(){ + if ( _animations[name] ) { + + t = _getCurrentTime() - startAnimTime; // time diff + //b - beginning (start prop) + //d - anim duration + + if ( t >= d ) { + _stopAnimation(name); + onUpdate(endProp); + if(onComplete) { + onComplete(); + } + return; + } + onUpdate( (endProp - b) * easingFn(t/d) + b ); + + _animations[name].raf = _requestAF(animloop); + } + }; + animloop(); + }; + + + +var publicMethods = { + + // make a few local variables and functions public + shout: _shout, + listen: _listen, + viewportSize: _viewportSize, + options: _options, + + isMainScrollAnimating: function() { + return _mainScrollAnimating; + }, + getZoomLevel: function() { + return _currZoomLevel; + }, + getCurrentIndex: function() { + return _currentItemIndex; + }, + isDragging: function() { + return _isDragging; + }, + isZooming: function() { + return _isZooming; + }, + setScrollOffset: function(x,y) { + _offset.x = x; + _currentWindowScrollY = _offset.y = y; + _shout('updateScrollOffset', _offset); + }, + applyZoomPan: function(zoomLevel,panX,panY,allowRenderResolution) { + _panOffset.x = panX; + _panOffset.y = panY; + _currZoomLevel = zoomLevel; + _applyCurrentZoomPan( allowRenderResolution ); + }, + + init: function() { + + if(_isOpen || _isDestroying) { + return; + } + + var i; + + self.framework = framework; // basic functionality + self.template = template; // root DOM element of PhotoSwipe + self.bg = framework.getChildByClass(template, 'pswp__bg'); + + _initalClassName = template.className; + _isOpen = true; + + _features = framework.detectFeatures(); + _requestAF = _features.raf; + _cancelAF = _features.caf; + _transformKey = _features.transform; + _oldIE = _features.oldIE; + + self.scrollWrap = framework.getChildByClass(template, 'pswp__scroll-wrap'); + self.container = framework.getChildByClass(self.scrollWrap, 'pswp__container'); + + _containerStyle = self.container.style; // for fast access + + // Objects that hold slides (there are only 3 in DOM) + self.itemHolders = _itemHolders = [ + {el:self.container.children[0] , wrap:0, index: -1}, + {el:self.container.children[1] , wrap:0, index: -1}, + {el:self.container.children[2] , wrap:0, index: -1} + ]; + + // hide nearby item holders until initial zoom animation finishes (to avoid extra Paints) + _itemHolders[0].el.style.display = _itemHolders[2].el.style.display = 'none'; + + _setupTransforms(); + + // Setup global events + _globalEventHandlers = { + resize: self.updateSize, + + // Fixes: iOS 10.3 resize event + // does not update scrollWrap.clientWidth instantly after resize + // https://github.com/dimsemenov/PhotoSwipe/issues/1315 + orientationchange: function() { + clearTimeout(_orientationChangeTimeout); + _orientationChangeTimeout = setTimeout(function() { + if(_viewportSize.x !== self.scrollWrap.clientWidth) { + self.updateSize(); + } + }, 500); + }, + scroll: _updatePageScrollOffset, + keydown: _onKeyDown, + click: _onGlobalClick + }; + + // disable show/hide effects on old browsers that don't support CSS animations or transforms, + // old IOS, Android and Opera mobile. Blackberry seems to work fine, even older models. + var oldPhone = _features.isOldIOSPhone || _features.isOldAndroid || _features.isMobileOpera; + if(!_features.animationName || !_features.transform || oldPhone) { + _options.showAnimationDuration = _options.hideAnimationDuration = 0; + } + + // init modules + for(i = 0; i < _modules.length; i++) { + self['init' + _modules[i]](); + } + + // init + if(UiClass) { + var ui = self.ui = new UiClass(self, framework); + ui.init(); + } + + _shout('firstUpdate'); + _currentItemIndex = _currentItemIndex || _options.index || 0; + // validate index + if( isNaN(_currentItemIndex) || _currentItemIndex < 0 || _currentItemIndex >= _getNumItems() ) { + _currentItemIndex = 0; + } + self.currItem = _getItemAt( _currentItemIndex ); + + + if(_features.isOldIOSPhone || _features.isOldAndroid) { + _isFixedPosition = false; + } + + template.setAttribute('aria-hidden', 'false'); + if(_options.modal) { + if(!_isFixedPosition) { + template.style.position = 'absolute'; + template.style.top = framework.getScrollY() + 'px'; + } else { + template.style.position = 'fixed'; + } + } + + if(_currentWindowScrollY === undefined) { + _shout('initialLayout'); + _currentWindowScrollY = _initalWindowScrollY = framework.getScrollY(); + } + + // add classes to root element of PhotoSwipe + var rootClasses = 'pswp--open '; + if(_options.mainClass) { + rootClasses += _options.mainClass + ' '; + } + if(_options.showHideOpacity) { + rootClasses += 'pswp--animate_opacity '; + } + rootClasses += _likelyTouchDevice ? 'pswp--touch' : 'pswp--notouch'; + rootClasses += _features.animationName ? ' pswp--css_animation' : ''; + rootClasses += _features.svg ? ' pswp--svg' : ''; + framework.addClass(template, rootClasses); + + self.updateSize(); + + // initial update + _containerShiftIndex = -1; + _indexDiff = null; + for(i = 0; i < NUM_HOLDERS; i++) { + _setTranslateX( (i+_containerShiftIndex) * _slideSize.x, _itemHolders[i].el.style); + } + + if(!_oldIE) { + framework.bind(self.scrollWrap, _downEvents, self); // no dragging for old IE + } + + _listen('initialZoomInEnd', function() { + self.setContent(_itemHolders[0], _currentItemIndex-1); + self.setContent(_itemHolders[2], _currentItemIndex+1); + + _itemHolders[0].el.style.display = _itemHolders[2].el.style.display = 'block'; + + if(_options.focus) { + // focus causes layout, + // which causes lag during the animation, + // that's why we delay it untill the initial zoom transition ends + template.focus(); + } + + + _bindEvents(); + }); + + // set content for center slide (first time) + self.setContent(_itemHolders[1], _currentItemIndex); + + self.updateCurrItem(); + + _shout('afterInit'); + + if(!_isFixedPosition) { + + // On all versions of iOS lower than 8.0, we check size of viewport every second. + // + // This is done to detect when Safari top & bottom bars appear, + // as this action doesn't trigger any events (like resize). + // + // On iOS8 they fixed this. + // + // 10 Nov 2014: iOS 7 usage ~40%. iOS 8 usage 56%. + + _updateSizeInterval = setInterval(function() { + if(!_numAnimations && !_isDragging && !_isZooming && (_currZoomLevel === self.currItem.initialZoomLevel) ) { + self.updateSize(); + } + }, 1000); + } + + framework.addClass(template, 'pswp--visible'); + }, + + // Close the gallery, then destroy it + close: function() { + if(!_isOpen) { + return; + } + + _isOpen = false; + _isDestroying = true; + _shout('close'); + _unbindEvents(); + + _showOrHide(self.currItem, null, true, self.destroy); + }, + + // destroys the gallery (unbinds events, cleans up intervals and timeouts to avoid memory leaks) + destroy: function() { + _shout('destroy'); + + if(_showOrHideTimeout) { + clearTimeout(_showOrHideTimeout); + } + + template.setAttribute('aria-hidden', 'true'); + template.className = _initalClassName; + + if(_updateSizeInterval) { + clearInterval(_updateSizeInterval); + } + + framework.unbind(self.scrollWrap, _downEvents, self); + + // we unbind scroll event at the end, as closing animation may depend on it + framework.unbind(window, 'scroll', self); + + _stopDragUpdateLoop(); + + _stopAllAnimations(); + + _listeners = null; + }, + + /** + * Pan image to position + * @param {Number} x + * @param {Number} y + * @param {Boolean} force Will ignore bounds if set to true. + */ + panTo: function(x,y,force) { + if(!force) { + if(x > _currPanBounds.min.x) { + x = _currPanBounds.min.x; + } else if(x < _currPanBounds.max.x) { + x = _currPanBounds.max.x; + } + + if(y > _currPanBounds.min.y) { + y = _currPanBounds.min.y; + } else if(y < _currPanBounds.max.y) { + y = _currPanBounds.max.y; + } + } + + _panOffset.x = x; + _panOffset.y = y; + _applyCurrentZoomPan(); + }, + + handleEvent: function (e) { + e = e || window.event; + if(_globalEventHandlers[e.type]) { + _globalEventHandlers[e.type](e); + } + }, + + + goTo: function(index) { + + index = _getLoopedId(index); + + var diff = index - _currentItemIndex; + _indexDiff = diff; + + _currentItemIndex = index; + self.currItem = _getItemAt( _currentItemIndex ); + _currPositionIndex -= diff; + + _moveMainScroll(_slideSize.x * _currPositionIndex); + + + _stopAllAnimations(); + _mainScrollAnimating = false; + + self.updateCurrItem(); + }, + next: function() { + self.goTo( _currentItemIndex + 1); + }, + prev: function() { + self.goTo( _currentItemIndex - 1); + }, + + // update current zoom/pan objects + updateCurrZoomItem: function(emulateSetContent) { + if(emulateSetContent) { + _shout('beforeChange', 0); + } + + // itemHolder[1] is middle (current) item + if(_itemHolders[1].el.children.length) { + var zoomElement = _itemHolders[1].el.children[0]; + if( framework.hasClass(zoomElement, 'pswp__zoom-wrap') ) { + _currZoomElementStyle = zoomElement.style; + } else { + _currZoomElementStyle = null; + } + } else { + _currZoomElementStyle = null; + } + + _currPanBounds = self.currItem.bounds; + _startZoomLevel = _currZoomLevel = self.currItem.initialZoomLevel; + + _panOffset.x = _currPanBounds.center.x; + _panOffset.y = _currPanBounds.center.y; + + if(emulateSetContent) { + _shout('afterChange'); + } + }, + + + invalidateCurrItems: function() { + _itemsNeedUpdate = true; + for(var i = 0; i < NUM_HOLDERS; i++) { + if( _itemHolders[i].item ) { + _itemHolders[i].item.needsUpdate = true; + } + } + }, + + updateCurrItem: function(beforeAnimation) { + + if(_indexDiff === 0) { + return; + } + + var diffAbs = Math.abs(_indexDiff), + tempHolder; + + if(beforeAnimation && diffAbs < 2) { + return; + } + + + self.currItem = _getItemAt( _currentItemIndex ); + _renderMaxResolution = false; + + _shout('beforeChange', _indexDiff); + + if(diffAbs >= NUM_HOLDERS) { + _containerShiftIndex += _indexDiff + (_indexDiff > 0 ? -NUM_HOLDERS : NUM_HOLDERS); + diffAbs = NUM_HOLDERS; + } + for(var i = 0; i < diffAbs; i++) { + if(_indexDiff > 0) { + tempHolder = _itemHolders.shift(); + _itemHolders[NUM_HOLDERS-1] = tempHolder; // move first to last + + _containerShiftIndex++; + _setTranslateX( (_containerShiftIndex+2) * _slideSize.x, tempHolder.el.style); + self.setContent(tempHolder, _currentItemIndex - diffAbs + i + 1 + 1); + } else { + tempHolder = _itemHolders.pop(); + _itemHolders.unshift( tempHolder ); // move last to first + + _containerShiftIndex--; + _setTranslateX( _containerShiftIndex * _slideSize.x, tempHolder.el.style); + self.setContent(tempHolder, _currentItemIndex + diffAbs - i - 1 - 1); + } + + } + + // reset zoom/pan on previous item + if(_currZoomElementStyle && Math.abs(_indexDiff) === 1) { + + var prevItem = _getItemAt(_prevItemIndex); + if(prevItem.initialZoomLevel !== _currZoomLevel) { + _calculateItemSize(prevItem , _viewportSize ); + _setImageSize(prevItem); + _applyZoomPanToItem( prevItem ); + } + + } + + // reset diff after update + _indexDiff = 0; + + self.updateCurrZoomItem(); + + _prevItemIndex = _currentItemIndex; + + _shout('afterChange'); + + }, + + + + updateSize: function(force) { + + if(!_isFixedPosition && _options.modal) { + var windowScrollY = framework.getScrollY(); + if(_currentWindowScrollY !== windowScrollY) { + template.style.top = windowScrollY + 'px'; + _currentWindowScrollY = windowScrollY; + } + if(!force && _windowVisibleSize.x === window.innerWidth && _windowVisibleSize.y === window.innerHeight) { + return; + } + _windowVisibleSize.x = window.innerWidth; + _windowVisibleSize.y = window.innerHeight; + + //template.style.width = _windowVisibleSize.x + 'px'; + template.style.height = _windowVisibleSize.y + 'px'; + } + + + + _viewportSize.x = self.scrollWrap.clientWidth; + _viewportSize.y = self.scrollWrap.clientHeight; + + _updatePageScrollOffset(); + + _slideSize.x = _viewportSize.x + Math.round(_viewportSize.x * _options.spacing); + _slideSize.y = _viewportSize.y; + + _moveMainScroll(_slideSize.x * _currPositionIndex); + + _shout('beforeResize'); // even may be used for example to switch image sources + + + // don't re-calculate size on inital size update + if(_containerShiftIndex !== undefined) { + + var holder, + item, + hIndex; + + for(var i = 0; i < NUM_HOLDERS; i++) { + holder = _itemHolders[i]; + _setTranslateX( (i+_containerShiftIndex) * _slideSize.x, holder.el.style); + + hIndex = _currentItemIndex+i-1; + + if(_options.loop && _getNumItems() > 2) { + hIndex = _getLoopedId(hIndex); + } + + // update zoom level on items and refresh source (if needsUpdate) + item = _getItemAt( hIndex ); + + // re-render gallery item if `needsUpdate`, + // or doesn't have `bounds` (entirely new slide object) + if( item && (_itemsNeedUpdate || item.needsUpdate || !item.bounds) ) { + + self.cleanSlide( item ); + + self.setContent( holder, hIndex ); + + // if "center" slide + if(i === 1) { + self.currItem = item; + self.updateCurrZoomItem(true); + } + + item.needsUpdate = false; + + } else if(holder.index === -1 && hIndex >= 0) { + // add content first time + self.setContent( holder, hIndex ); + } + if(item && item.container) { + _calculateItemSize(item, _viewportSize); + _setImageSize(item); + _applyZoomPanToItem( item ); + } + + } + _itemsNeedUpdate = false; + } + + _startZoomLevel = _currZoomLevel = self.currItem.initialZoomLevel; + _currPanBounds = self.currItem.bounds; + + if(_currPanBounds) { + _panOffset.x = _currPanBounds.center.x; + _panOffset.y = _currPanBounds.center.y; + _applyCurrentZoomPan( true ); + } + + _shout('resize'); + }, + + // Zoom current item to + zoomTo: function(destZoomLevel, centerPoint, speed, easingFn, updateFn) { + /* + if(destZoomLevel === 'fit') { + destZoomLevel = self.currItem.fitRatio; + } else if(destZoomLevel === 'fill') { + destZoomLevel = self.currItem.fillRatio; + } + */ + + if(centerPoint) { + _startZoomLevel = _currZoomLevel; + _midZoomPoint.x = Math.abs(centerPoint.x) - _panOffset.x ; + _midZoomPoint.y = Math.abs(centerPoint.y) - _panOffset.y ; + _equalizePoints(_startPanOffset, _panOffset); + } + + var destPanBounds = _calculatePanBounds(destZoomLevel, false), + destPanOffset = {}; + + _modifyDestPanOffset('x', destPanBounds, destPanOffset, destZoomLevel); + _modifyDestPanOffset('y', destPanBounds, destPanOffset, destZoomLevel); + + var initialZoomLevel = _currZoomLevel; + var initialPanOffset = { + x: _panOffset.x, + y: _panOffset.y + }; + + _roundPoint(destPanOffset); + + var onUpdate = function(now) { + if(now === 1) { + _currZoomLevel = destZoomLevel; + _panOffset.x = destPanOffset.x; + _panOffset.y = destPanOffset.y; + } else { + _currZoomLevel = (destZoomLevel - initialZoomLevel) * now + initialZoomLevel; + _panOffset.x = (destPanOffset.x - initialPanOffset.x) * now + initialPanOffset.x; + _panOffset.y = (destPanOffset.y - initialPanOffset.y) * now + initialPanOffset.y; + } + + if(updateFn) { + updateFn(now); + } + + _applyCurrentZoomPan( now === 1 ); + }; + + if(speed) { + _animateProp('customZoomTo', 0, 1, speed, easingFn || framework.easing.sine.inOut, onUpdate); + } else { + onUpdate(1); + } + } + + +}; + + +/*>>core*/ + +/*>>gestures*/ +/** + * Mouse/touch/pointer event handlers. + * + * separated from @core.js for readability + */ + +var MIN_SWIPE_DISTANCE = 30, + DIRECTION_CHECK_OFFSET = 10; // amount of pixels to drag to determine direction of swipe + +var _gestureStartTime, + _gestureCheckSpeedTime, + + // pool of objects that are used during dragging of zooming + p = {}, // first point + p2 = {}, // second point (for zoom gesture) + delta = {}, + _currPoint = {}, + _startPoint = {}, + _currPointers = [], + _startMainScrollPos = {}, + _releaseAnimData, + _posPoints = [], // array of points during dragging, used to determine type of gesture + _tempPoint = {}, + + _isZoomingIn, + _verticalDragInitiated, + _oldAndroidTouchEndTimeout, + _currZoomedItemIndex = 0, + _centerPoint = _getEmptyPoint(), + _lastReleaseTime = 0, + _isDragging, // at least one pointer is down + _isMultitouch, // at least two _pointers are down + _zoomStarted, // zoom level changed during zoom gesture + _moved, + _dragAnimFrame, + _mainScrollShifted, + _currentPoints, // array of current touch points + _isZooming, + _currPointsDistance, + _startPointsDistance, + _currPanBounds, + _mainScrollPos = _getEmptyPoint(), + _currZoomElementStyle, + _mainScrollAnimating, // true, if animation after swipe gesture is running + _midZoomPoint = _getEmptyPoint(), + _currCenterPoint = _getEmptyPoint(), + _direction, + _isFirstMove, + _opacityChanged, + _bgOpacity, + _wasOverInitialZoom, + + _isEqualPoints = function(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; + }, + _isNearbyPoints = function(touch0, touch1) { + return Math.abs(touch0.x - touch1.x) < DOUBLE_TAP_RADIUS && Math.abs(touch0.y - touch1.y) < DOUBLE_TAP_RADIUS; + }, + _calculatePointsDistance = function(p1, p2) { + _tempPoint.x = Math.abs( p1.x - p2.x ); + _tempPoint.y = Math.abs( p1.y - p2.y ); + return Math.sqrt(_tempPoint.x * _tempPoint.x + _tempPoint.y * _tempPoint.y); + }, + _stopDragUpdateLoop = function() { + if(_dragAnimFrame) { + _cancelAF(_dragAnimFrame); + _dragAnimFrame = null; + } + }, + _dragUpdateLoop = function() { + if(_isDragging) { + _dragAnimFrame = _requestAF(_dragUpdateLoop); + _renderMovement(); + } + }, + _canPan = function() { + return !(_options.scaleMode === 'fit' && _currZoomLevel === self.currItem.initialZoomLevel); + }, + + // find the closest parent DOM element + _closestElement = function(el, fn) { + if(!el || el === document) { + return false; + } + + // don't search elements above pswp__scroll-wrap + if(el.getAttribute('class') && el.getAttribute('class').indexOf('pswp__scroll-wrap') > -1 ) { + return false; + } + + if( fn(el) ) { + return el; + } + + return _closestElement(el.parentNode, fn); + }, + + _preventObj = {}, + _preventDefaultEventBehaviour = function(e, isDown) { + _preventObj.prevent = !_closestElement(e.target, _options.isClickableElement); + + _shout('preventDragEvent', e, isDown, _preventObj); + return _preventObj.prevent; + + }, + _convertTouchToPoint = function(touch, p) { + p.x = touch.pageX; + p.y = touch.pageY; + p.id = touch.identifier; + return p; + }, + _findCenterOfPoints = function(p1, p2, pCenter) { + pCenter.x = (p1.x + p2.x) * 0.5; + pCenter.y = (p1.y + p2.y) * 0.5; + }, + _pushPosPoint = function(time, x, y) { + if(time - _gestureCheckSpeedTime > 50) { + var o = _posPoints.length > 2 ? _posPoints.shift() : {}; + o.x = x; + o.y = y; + _posPoints.push(o); + _gestureCheckSpeedTime = time; + } + }, + + _calculateVerticalDragOpacityRatio = function() { + var yOffset = _panOffset.y - self.currItem.initialPosition.y; // difference between initial and current position + return 1 - Math.abs( yOffset / (_viewportSize.y / 2) ); + }, + + + // points pool, reused during touch events + _ePoint1 = {}, + _ePoint2 = {}, + _tempPointsArr = [], + _tempCounter, + _getTouchPoints = function(e) { + // clean up previous points, without recreating array + while(_tempPointsArr.length > 0) { + _tempPointsArr.pop(); + } + + if(!_pointerEventEnabled) { + if(e.type.indexOf('touch') > -1) { + + if(e.touches && e.touches.length > 0) { + _tempPointsArr[0] = _convertTouchToPoint(e.touches[0], _ePoint1); + if(e.touches.length > 1) { + _tempPointsArr[1] = _convertTouchToPoint(e.touches[1], _ePoint2); + } + } + + } else { + _ePoint1.x = e.pageX; + _ePoint1.y = e.pageY; + _ePoint1.id = ''; + _tempPointsArr[0] = _ePoint1;//_ePoint1; + } + } else { + _tempCounter = 0; + // we can use forEach, as pointer events are supported only in modern browsers + _currPointers.forEach(function(p) { + if(_tempCounter === 0) { + _tempPointsArr[0] = p; + } else if(_tempCounter === 1) { + _tempPointsArr[1] = p; + } + _tempCounter++; + + }); + } + return _tempPointsArr; + }, + + _panOrMoveMainScroll = function(axis, delta) { + + var panFriction, + overDiff = 0, + newOffset = _panOffset[axis] + delta[axis], + startOverDiff, + dir = delta[axis] > 0, + newMainScrollPosition = _mainScrollPos.x + delta.x, + mainScrollDiff = _mainScrollPos.x - _startMainScrollPos.x, + newPanPos, + newMainScrollPos; + + // calculate fdistance over the bounds and friction + if(newOffset > _currPanBounds.min[axis] || newOffset < _currPanBounds.max[axis]) { + panFriction = _options.panEndFriction; + // Linear increasing of friction, so at 1/4 of viewport it's at max value. + // Looks not as nice as was expected. Left for history. + // panFriction = (1 - (_panOffset[axis] + delta[axis] + panBounds.min[axis]) / (_viewportSize[axis] / 4) ); + } else { + panFriction = 1; + } + + newOffset = _panOffset[axis] + delta[axis] * panFriction; + + // move main scroll or start panning + if(_options.allowPanToNext || _currZoomLevel === self.currItem.initialZoomLevel) { + + + if(!_currZoomElementStyle) { + + newMainScrollPos = newMainScrollPosition; + + } else if(_direction === 'h' && axis === 'x' && !_zoomStarted ) { + + if(dir) { + if(newOffset > _currPanBounds.min[axis]) { + panFriction = _options.panEndFriction; + overDiff = _currPanBounds.min[axis] - newOffset; + startOverDiff = _currPanBounds.min[axis] - _startPanOffset[axis]; + } + + // drag right + if( (startOverDiff <= 0 || mainScrollDiff < 0) && _getNumItems() > 1 ) { + newMainScrollPos = newMainScrollPosition; + if(mainScrollDiff < 0 && newMainScrollPosition > _startMainScrollPos.x) { + newMainScrollPos = _startMainScrollPos.x; + } + } else { + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + newPanPos = newOffset; + } + + } + + } else { + + if(newOffset < _currPanBounds.max[axis] ) { + panFriction =_options.panEndFriction; + overDiff = newOffset - _currPanBounds.max[axis]; + startOverDiff = _startPanOffset[axis] - _currPanBounds.max[axis]; + } + + if( (startOverDiff <= 0 || mainScrollDiff > 0) && _getNumItems() > 1 ) { + newMainScrollPos = newMainScrollPosition; + + if(mainScrollDiff > 0 && newMainScrollPosition < _startMainScrollPos.x) { + newMainScrollPos = _startMainScrollPos.x; + } + + } else { + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + newPanPos = newOffset; + } + } + + } + + + // + } + + if(axis === 'x') { + + if(newMainScrollPos !== undefined) { + _moveMainScroll(newMainScrollPos, true); + if(newMainScrollPos === _startMainScrollPos.x) { + _mainScrollShifted = false; + } else { + _mainScrollShifted = true; + } + } + + if(_currPanBounds.min.x !== _currPanBounds.max.x) { + if(newPanPos !== undefined) { + _panOffset.x = newPanPos; + } else if(!_mainScrollShifted) { + _panOffset.x += delta.x * panFriction; + } + } + + return newMainScrollPos !== undefined; + } + + } + + if(!_mainScrollAnimating) { + + if(!_mainScrollShifted) { + if(_currZoomLevel > self.currItem.fitRatio) { + _panOffset[axis] += delta[axis] * panFriction; + + } + } + + + } + + }, + + // Pointerdown/touchstart/mousedown handler + _onDragStart = function(e) { + + // Allow dragging only via left mouse button. + // As this handler is not added in IE8 - we ignore e.which + // + // http://www.quirksmode.org/js/events_properties.html + // https://developer.mozilla.org/en-US/docs/Web/API/event.button + if(e.type === 'mousedown' && e.button > 0 ) { + return; + } + + if(_initialZoomRunning) { + e.preventDefault(); + return; + } + + if(_oldAndroidTouchEndTimeout && e.type === 'mousedown') { + return; + } + + if(_preventDefaultEventBehaviour(e, true)) { + e.preventDefault(); + } + + + + _shout('pointerDown'); + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + if(pointerIndex < 0) { + pointerIndex = _currPointers.length; + } + _currPointers[pointerIndex] = {x:e.pageX, y:e.pageY, id: e.pointerId}; + } + + + + var startPointsList = _getTouchPoints(e), + numPoints = startPointsList.length; + + _currentPoints = null; + + _stopAllAnimations(); + + // init drag + if(!_isDragging || numPoints === 1) { + + + + _isDragging = _isFirstMove = true; + framework.bind(window, _upMoveEvents, self); + + _isZoomingIn = + _wasOverInitialZoom = + _opacityChanged = + _verticalDragInitiated = + _mainScrollShifted = + _moved = + _isMultitouch = + _zoomStarted = false; + + _direction = null; + + _shout('firstTouchStart', startPointsList); + + _equalizePoints(_startPanOffset, _panOffset); + + _currPanDist.x = _currPanDist.y = 0; + _equalizePoints(_currPoint, startPointsList[0]); + _equalizePoints(_startPoint, _currPoint); + + //_equalizePoints(_startMainScrollPos, _mainScrollPos); + _startMainScrollPos.x = _slideSize.x * _currPositionIndex; + + _posPoints = [{ + x: _currPoint.x, + y: _currPoint.y + }]; + + _gestureCheckSpeedTime = _gestureStartTime = _getCurrentTime(); + + //_mainScrollAnimationEnd(true); + _calculatePanBounds( _currZoomLevel, true ); + + // Start rendering + _stopDragUpdateLoop(); + _dragUpdateLoop(); + + } + + // init zoom + if(!_isZooming && numPoints > 1 && !_mainScrollAnimating && !_mainScrollShifted) { + _startZoomLevel = _currZoomLevel; + _zoomStarted = false; // true if zoom changed at least once + + _isZooming = _isMultitouch = true; + _currPanDist.y = _currPanDist.x = 0; + + _equalizePoints(_startPanOffset, _panOffset); + + _equalizePoints(p, startPointsList[0]); + _equalizePoints(p2, startPointsList[1]); + + _findCenterOfPoints(p, p2, _currCenterPoint); + + _midZoomPoint.x = Math.abs(_currCenterPoint.x) - _panOffset.x; + _midZoomPoint.y = Math.abs(_currCenterPoint.y) - _panOffset.y; + _currPointsDistance = _startPointsDistance = _calculatePointsDistance(p, p2); + } + + + }, + + // Pointermove/touchmove/mousemove handler + _onDragMove = function(e) { + + e.preventDefault(); + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + if(pointerIndex > -1) { + var p = _currPointers[pointerIndex]; + p.x = e.pageX; + p.y = e.pageY; + } + } + + if(_isDragging) { + var touchesList = _getTouchPoints(e); + if(!_direction && !_moved && !_isZooming) { + + if(_mainScrollPos.x !== _slideSize.x * _currPositionIndex) { + // if main scroll position is shifted – direction is always horizontal + _direction = 'h'; + } else { + var diff = Math.abs(touchesList[0].x - _currPoint.x) - Math.abs(touchesList[0].y - _currPoint.y); + // check the direction of movement + if(Math.abs(diff) >= DIRECTION_CHECK_OFFSET) { + _direction = diff > 0 ? 'h' : 'v'; + _currentPoints = touchesList; + } + } + + } else { + _currentPoints = touchesList; + } + } + }, + // + _renderMovement = function() { + + if(!_currentPoints) { + return; + } + + var numPoints = _currentPoints.length; + + if(numPoints === 0) { + return; + } + + _equalizePoints(p, _currentPoints[0]); + + delta.x = p.x - _currPoint.x; + delta.y = p.y - _currPoint.y; + + if(_isZooming && numPoints > 1) { + // Handle behaviour for more than 1 point + + _currPoint.x = p.x; + _currPoint.y = p.y; + + // check if one of two points changed + if( !delta.x && !delta.y && _isEqualPoints(_currentPoints[1], p2) ) { + return; + } + + _equalizePoints(p2, _currentPoints[1]); + + + if(!_zoomStarted) { + _zoomStarted = true; + _shout('zoomGestureStarted'); + } + + // Distance between two points + var pointsDistance = _calculatePointsDistance(p,p2); + + var zoomLevel = _calculateZoomLevel(pointsDistance); + + // slightly over the of initial zoom level + if(zoomLevel > self.currItem.initialZoomLevel + self.currItem.initialZoomLevel / 15) { + _wasOverInitialZoom = true; + } + + // Apply the friction if zoom level is out of the bounds + var zoomFriction = 1, + minZoomLevel = _getMinZoomLevel(), + maxZoomLevel = _getMaxZoomLevel(); + + if ( zoomLevel < minZoomLevel ) { + + if(_options.pinchToClose && !_wasOverInitialZoom && _startZoomLevel <= self.currItem.initialZoomLevel) { + // fade out background if zooming out + var minusDiff = minZoomLevel - zoomLevel; + var percent = 1 - minusDiff / (minZoomLevel / 1.2); + + _applyBgOpacity(percent); + _shout('onPinchClose', percent); + _opacityChanged = true; + } else { + zoomFriction = (minZoomLevel - zoomLevel) / minZoomLevel; + if(zoomFriction > 1) { + zoomFriction = 1; + } + zoomLevel = minZoomLevel - zoomFriction * (minZoomLevel / 3); + } + + } else if ( zoomLevel > maxZoomLevel ) { + // 1.5 - extra zoom level above the max. E.g. if max is x6, real max 6 + 1.5 = 7.5 + zoomFriction = (zoomLevel - maxZoomLevel) / ( minZoomLevel * 6 ); + if(zoomFriction > 1) { + zoomFriction = 1; + } + zoomLevel = maxZoomLevel + zoomFriction * minZoomLevel; + } + + if(zoomFriction < 0) { + zoomFriction = 0; + } + + // distance between touch points after friction is applied + _currPointsDistance = pointsDistance; + + // _centerPoint - The point in the middle of two pointers + _findCenterOfPoints(p, p2, _centerPoint); + + // paning with two pointers pressed + _currPanDist.x += _centerPoint.x - _currCenterPoint.x; + _currPanDist.y += _centerPoint.y - _currCenterPoint.y; + _equalizePoints(_currCenterPoint, _centerPoint); + + _panOffset.x = _calculatePanOffset('x', zoomLevel); + _panOffset.y = _calculatePanOffset('y', zoomLevel); + + _isZoomingIn = zoomLevel > _currZoomLevel; + _currZoomLevel = zoomLevel; + _applyCurrentZoomPan(); + + } else { + + // handle behaviour for one point (dragging or panning) + + if(!_direction) { + return; + } + + if(_isFirstMove) { + _isFirstMove = false; + + // subtract drag distance that was used during the detection direction + + if( Math.abs(delta.x) >= DIRECTION_CHECK_OFFSET) { + delta.x -= _currentPoints[0].x - _startPoint.x; + } + + if( Math.abs(delta.y) >= DIRECTION_CHECK_OFFSET) { + delta.y -= _currentPoints[0].y - _startPoint.y; + } + } + + _currPoint.x = p.x; + _currPoint.y = p.y; + + // do nothing if pointers position hasn't changed + if(delta.x === 0 && delta.y === 0) { + return; + } + + if(_direction === 'v' && _options.closeOnVerticalDrag) { + if(!_canPan()) { + _currPanDist.y += delta.y; + _panOffset.y += delta.y; + + var opacityRatio = _calculateVerticalDragOpacityRatio(); + + _verticalDragInitiated = true; + _shout('onVerticalDrag', opacityRatio); + + _applyBgOpacity(opacityRatio); + _applyCurrentZoomPan(); + return ; + } + } + + _pushPosPoint(_getCurrentTime(), p.x, p.y); + + _moved = true; + _currPanBounds = self.currItem.bounds; + + var mainScrollChanged = _panOrMoveMainScroll('x', delta); + if(!mainScrollChanged) { + _panOrMoveMainScroll('y', delta); + + _roundPoint(_panOffset); + _applyCurrentZoomPan(); + } + + } + + }, + + // Pointerup/pointercancel/touchend/touchcancel/mouseup event handler + _onDragRelease = function(e) { + + if(_features.isOldAndroid ) { + + if(_oldAndroidTouchEndTimeout && e.type === 'mouseup') { + return; + } + + // on Android (v4.1, 4.2, 4.3 & possibly older) + // ghost mousedown/up event isn't preventable via e.preventDefault, + // which causes fake mousedown event + // so we block mousedown/up for 600ms + if( e.type.indexOf('touch') > -1 ) { + clearTimeout(_oldAndroidTouchEndTimeout); + _oldAndroidTouchEndTimeout = setTimeout(function() { + _oldAndroidTouchEndTimeout = 0; + }, 600); + } + + } + + _shout('pointerUp'); + + if(_preventDefaultEventBehaviour(e, false)) { + e.preventDefault(); + } + + var releasePoint; + + if(_pointerEventEnabled) { + var pointerIndex = framework.arraySearch(_currPointers, e.pointerId, 'id'); + + if(pointerIndex > -1) { + releasePoint = _currPointers.splice(pointerIndex, 1)[0]; + + if(navigator.pointerEnabled) { + releasePoint.type = e.pointerType || 'mouse'; + } else { + var MSPOINTER_TYPES = { + 4: 'mouse', // event.MSPOINTER_TYPE_MOUSE + 2: 'touch', // event.MSPOINTER_TYPE_TOUCH + 3: 'pen' // event.MSPOINTER_TYPE_PEN + }; + releasePoint.type = MSPOINTER_TYPES[e.pointerType]; + + if(!releasePoint.type) { + releasePoint.type = e.pointerType || 'mouse'; + } + } + + } + } + + var touchList = _getTouchPoints(e), + gestureType, + numPoints = touchList.length; + + if(e.type === 'mouseup') { + numPoints = 0; + } + + // Do nothing if there were 3 touch points or more + if(numPoints === 2) { + _currentPoints = null; + return true; + } + + // if second pointer released + if(numPoints === 1) { + _equalizePoints(_startPoint, touchList[0]); + } + + + // pointer hasn't moved, send "tap release" point + if(numPoints === 0 && !_direction && !_mainScrollAnimating) { + if(!releasePoint) { + if(e.type === 'mouseup') { + releasePoint = {x: e.pageX, y: e.pageY, type:'mouse'}; + } else if(e.changedTouches && e.changedTouches[0]) { + releasePoint = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY, type:'touch'}; + } + } + + _shout('touchRelease', e, releasePoint); + } + + // Difference in time between releasing of two last touch points (zoom gesture) + var releaseTimeDiff = -1; + + // Gesture completed, no pointers left + if(numPoints === 0) { + _isDragging = false; + framework.unbind(window, _upMoveEvents, self); + + _stopDragUpdateLoop(); + + if(_isZooming) { + // Two points released at the same time + releaseTimeDiff = 0; + } else if(_lastReleaseTime !== -1) { + releaseTimeDiff = _getCurrentTime() - _lastReleaseTime; + } + } + _lastReleaseTime = numPoints === 1 ? _getCurrentTime() : -1; + + if(releaseTimeDiff !== -1 && releaseTimeDiff < 150) { + gestureType = 'zoom'; + } else { + gestureType = 'swipe'; + } + + if(_isZooming && numPoints < 2) { + _isZooming = false; + + // Only second point released + if(numPoints === 1) { + gestureType = 'zoomPointerUp'; + } + _shout('zoomGestureEnded'); + } + + _currentPoints = null; + if(!_moved && !_zoomStarted && !_mainScrollAnimating && !_verticalDragInitiated) { + // nothing to animate + return; + } + + _stopAllAnimations(); + + + if(!_releaseAnimData) { + _releaseAnimData = _initDragReleaseAnimationData(); + } + + _releaseAnimData.calculateSwipeSpeed('x'); + + + if(_verticalDragInitiated) { + + var opacityRatio = _calculateVerticalDragOpacityRatio(); + + if(opacityRatio < _options.verticalDragRange) { + self.close(); + } else { + var initalPanY = _panOffset.y, + initialBgOpacity = _bgOpacity; + + _animateProp('verticalDrag', 0, 1, 300, framework.easing.cubic.out, function(now) { + + _panOffset.y = (self.currItem.initialPosition.y - initalPanY) * now + initalPanY; + + _applyBgOpacity( (1 - initialBgOpacity) * now + initialBgOpacity ); + _applyCurrentZoomPan(); + }); + + _shout('onVerticalDrag', 1); + } + + return; + } + + + // main scroll + if( (_mainScrollShifted || _mainScrollAnimating) && numPoints === 0) { + var itemChanged = _finishSwipeMainScrollGesture(gestureType, _releaseAnimData); + if(itemChanged) { + return; + } + gestureType = 'zoomPointerUp'; + } + + // prevent zoom/pan animation when main scroll animation runs + if(_mainScrollAnimating) { + return; + } + + // Complete simple zoom gesture (reset zoom level if it's out of the bounds) + if(gestureType !== 'swipe') { + _completeZoomGesture(); + return; + } + + // Complete pan gesture if main scroll is not shifted, and it's possible to pan current image + if(!_mainScrollShifted && _currZoomLevel > self.currItem.fitRatio) { + _completePanGesture(_releaseAnimData); + } + }, + + + // Returns object with data about gesture + // It's created only once and then reused + _initDragReleaseAnimationData = function() { + // temp local vars + var lastFlickDuration, + tempReleasePos; + + // s = this + var s = { + lastFlickOffset: {}, + lastFlickDist: {}, + lastFlickSpeed: {}, + slowDownRatio: {}, + slowDownRatioReverse: {}, + speedDecelerationRatio: {}, + speedDecelerationRatioAbs: {}, + distanceOffset: {}, + backAnimDestination: {}, + backAnimStarted: {}, + calculateSwipeSpeed: function(axis) { + + + if( _posPoints.length > 1) { + lastFlickDuration = _getCurrentTime() - _gestureCheckSpeedTime + 50; + tempReleasePos = _posPoints[_posPoints.length-2][axis]; + } else { + lastFlickDuration = _getCurrentTime() - _gestureStartTime; // total gesture duration + tempReleasePos = _startPoint[axis]; + } + s.lastFlickOffset[axis] = _currPoint[axis] - tempReleasePos; + s.lastFlickDist[axis] = Math.abs(s.lastFlickOffset[axis]); + if(s.lastFlickDist[axis] > 20) { + s.lastFlickSpeed[axis] = s.lastFlickOffset[axis] / lastFlickDuration; + } else { + s.lastFlickSpeed[axis] = 0; + } + if( Math.abs(s.lastFlickSpeed[axis]) < 0.1 ) { + s.lastFlickSpeed[axis] = 0; + } + + s.slowDownRatio[axis] = 0.95; + s.slowDownRatioReverse[axis] = 1 - s.slowDownRatio[axis]; + s.speedDecelerationRatio[axis] = 1; + }, + + calculateOverBoundsAnimOffset: function(axis, speed) { + if(!s.backAnimStarted[axis]) { + + if(_panOffset[axis] > _currPanBounds.min[axis]) { + s.backAnimDestination[axis] = _currPanBounds.min[axis]; + + } else if(_panOffset[axis] < _currPanBounds.max[axis]) { + s.backAnimDestination[axis] = _currPanBounds.max[axis]; + } + + if(s.backAnimDestination[axis] !== undefined) { + s.slowDownRatio[axis] = 0.7; + s.slowDownRatioReverse[axis] = 1 - s.slowDownRatio[axis]; + if(s.speedDecelerationRatioAbs[axis] < 0.05) { + + s.lastFlickSpeed[axis] = 0; + s.backAnimStarted[axis] = true; + + _animateProp('bounceZoomPan'+axis,_panOffset[axis], + s.backAnimDestination[axis], + speed || 300, + framework.easing.sine.out, + function(pos) { + _panOffset[axis] = pos; + _applyCurrentZoomPan(); + } + ); + + } + } + } + }, + + // Reduces the speed by slowDownRatio (per 10ms) + calculateAnimOffset: function(axis) { + if(!s.backAnimStarted[axis]) { + s.speedDecelerationRatio[axis] = s.speedDecelerationRatio[axis] * (s.slowDownRatio[axis] + + s.slowDownRatioReverse[axis] - + s.slowDownRatioReverse[axis] * s.timeDiff / 10); + + s.speedDecelerationRatioAbs[axis] = Math.abs(s.lastFlickSpeed[axis] * s.speedDecelerationRatio[axis]); + s.distanceOffset[axis] = s.lastFlickSpeed[axis] * s.speedDecelerationRatio[axis] * s.timeDiff; + _panOffset[axis] += s.distanceOffset[axis]; + + } + }, + + panAnimLoop: function() { + if ( _animations.zoomPan ) { + _animations.zoomPan.raf = _requestAF(s.panAnimLoop); + + s.now = _getCurrentTime(); + s.timeDiff = s.now - s.lastNow; + s.lastNow = s.now; + + s.calculateAnimOffset('x'); + s.calculateAnimOffset('y'); + + _applyCurrentZoomPan(); + + s.calculateOverBoundsAnimOffset('x'); + s.calculateOverBoundsAnimOffset('y'); + + + if (s.speedDecelerationRatioAbs.x < 0.05 && s.speedDecelerationRatioAbs.y < 0.05) { + + // round pan position + _panOffset.x = Math.round(_panOffset.x); + _panOffset.y = Math.round(_panOffset.y); + _applyCurrentZoomPan(); + + _stopAnimation('zoomPan'); + return; + } + } + + } + }; + return s; + }, + + _completePanGesture = function(animData) { + // calculate swipe speed for Y axis (paanning) + animData.calculateSwipeSpeed('y'); + + _currPanBounds = self.currItem.bounds; + + animData.backAnimDestination = {}; + animData.backAnimStarted = {}; + + // Avoid acceleration animation if speed is too low + if(Math.abs(animData.lastFlickSpeed.x) <= 0.05 && Math.abs(animData.lastFlickSpeed.y) <= 0.05 ) { + animData.speedDecelerationRatioAbs.x = animData.speedDecelerationRatioAbs.y = 0; + + // Run pan drag release animation. E.g. if you drag image and release finger without momentum. + animData.calculateOverBoundsAnimOffset('x'); + animData.calculateOverBoundsAnimOffset('y'); + return true; + } + + // Animation loop that controls the acceleration after pan gesture ends + _registerStartAnimation('zoomPan'); + animData.lastNow = _getCurrentTime(); + animData.panAnimLoop(); + }, + + + _finishSwipeMainScrollGesture = function(gestureType, _releaseAnimData) { + var itemChanged; + if(!_mainScrollAnimating) { + _currZoomedItemIndex = _currentItemIndex; + } + + + + var itemsDiff; + + if(gestureType === 'swipe') { + var totalShiftDist = _currPoint.x - _startPoint.x, + isFastLastFlick = _releaseAnimData.lastFlickDist.x < 10; + + // if container is shifted for more than MIN_SWIPE_DISTANCE, + // and last flick gesture was in right direction + if(totalShiftDist > MIN_SWIPE_DISTANCE && + (isFastLastFlick || _releaseAnimData.lastFlickOffset.x > 20) ) { + // go to prev item + itemsDiff = -1; + } else if(totalShiftDist < -MIN_SWIPE_DISTANCE && + (isFastLastFlick || _releaseAnimData.lastFlickOffset.x < -20) ) { + // go to next item + itemsDiff = 1; + } + } + + var nextCircle; + + if(itemsDiff) { + + _currentItemIndex += itemsDiff; + + if(_currentItemIndex < 0) { + _currentItemIndex = _options.loop ? _getNumItems()-1 : 0; + nextCircle = true; + } else if(_currentItemIndex >= _getNumItems()) { + _currentItemIndex = _options.loop ? 0 : _getNumItems()-1; + nextCircle = true; + } + + if(!nextCircle || _options.loop) { + _indexDiff += itemsDiff; + _currPositionIndex -= itemsDiff; + itemChanged = true; + } + + + + } + + var animateToX = _slideSize.x * _currPositionIndex; + var animateToDist = Math.abs( animateToX - _mainScrollPos.x ); + var finishAnimDuration; + + + if(!itemChanged && animateToX > _mainScrollPos.x !== _releaseAnimData.lastFlickSpeed.x > 0) { + // "return to current" duration, e.g. when dragging from slide 0 to -1 + finishAnimDuration = 333; + } else { + finishAnimDuration = Math.abs(_releaseAnimData.lastFlickSpeed.x) > 0 ? + animateToDist / Math.abs(_releaseAnimData.lastFlickSpeed.x) : + 333; + + finishAnimDuration = Math.min(finishAnimDuration, 400); + finishAnimDuration = Math.max(finishAnimDuration, 250); + } + + if(_currZoomedItemIndex === _currentItemIndex) { + itemChanged = false; + } + + _mainScrollAnimating = true; + + _shout('mainScrollAnimStart'); + + _animateProp('mainScroll', _mainScrollPos.x, animateToX, finishAnimDuration, framework.easing.cubic.out, + _moveMainScroll, + function() { + _stopAllAnimations(); + _mainScrollAnimating = false; + _currZoomedItemIndex = -1; + + if(itemChanged || _currZoomedItemIndex !== _currentItemIndex) { + self.updateCurrItem(); + } + + _shout('mainScrollAnimComplete'); + } + ); + + if(itemChanged) { + self.updateCurrItem(true); + } + + return itemChanged; + }, + + _calculateZoomLevel = function(touchesDistance) { + return 1 / _startPointsDistance * touchesDistance * _startZoomLevel; + }, + + // Resets zoom if it's out of bounds + _completeZoomGesture = function() { + var destZoomLevel = _currZoomLevel, + minZoomLevel = _getMinZoomLevel(), + maxZoomLevel = _getMaxZoomLevel(); + + if ( _currZoomLevel < minZoomLevel ) { + destZoomLevel = minZoomLevel; + } else if ( _currZoomLevel > maxZoomLevel ) { + destZoomLevel = maxZoomLevel; + } + + var destOpacity = 1, + onUpdate, + initialOpacity = _bgOpacity; + + if(_opacityChanged && !_isZoomingIn && !_wasOverInitialZoom && _currZoomLevel < minZoomLevel) { + //_closedByScroll = true; + self.close(); + return true; + } + + if(_opacityChanged) { + onUpdate = function(now) { + _applyBgOpacity( (destOpacity - initialOpacity) * now + initialOpacity ); + }; + } + + self.zoomTo(destZoomLevel, 0, 200, framework.easing.cubic.out, onUpdate); + return true; + }; + + +_registerModule('Gestures', { + publicMethods: { + + initGestures: function() { + + // helper function that builds touch/pointer/mouse events + var addEventNames = function(pref, down, move, up, cancel) { + _dragStartEvent = pref + down; + _dragMoveEvent = pref + move; + _dragEndEvent = pref + up; + if(cancel) { + _dragCancelEvent = pref + cancel; + } else { + _dragCancelEvent = ''; + } + }; + + _pointerEventEnabled = _features.pointerEvent; + if(_pointerEventEnabled && _features.touch) { + // we don't need touch events, if browser supports pointer events + _features.touch = false; + } + + if(_pointerEventEnabled) { + if(navigator.pointerEnabled) { + addEventNames('pointer', 'down', 'move', 'up', 'cancel'); + } else { + // IE10 pointer events are case-sensitive + addEventNames('MSPointer', 'Down', 'Move', 'Up', 'Cancel'); + } + } else if(_features.touch) { + addEventNames('touch', 'start', 'move', 'end', 'cancel'); + _likelyTouchDevice = true; + } else { + addEventNames('mouse', 'down', 'move', 'up'); + } + + _upMoveEvents = _dragMoveEvent + ' ' + _dragEndEvent + ' ' + _dragCancelEvent; + _downEvents = _dragStartEvent; + + if(_pointerEventEnabled && !_likelyTouchDevice) { + _likelyTouchDevice = (navigator.maxTouchPoints > 1) || (navigator.msMaxTouchPoints > 1); + } + // make variable public + self.likelyTouchDevice = _likelyTouchDevice; + + _globalEventHandlers[_dragStartEvent] = _onDragStart; + _globalEventHandlers[_dragMoveEvent] = _onDragMove; + _globalEventHandlers[_dragEndEvent] = _onDragRelease; // the Kraken + + if(_dragCancelEvent) { + _globalEventHandlers[_dragCancelEvent] = _globalEventHandlers[_dragEndEvent]; + } + + // Bind mouse events on device with detected hardware touch support, in case it supports multiple types of input. + if(_features.touch) { + _downEvents += ' mousedown'; + _upMoveEvents += ' mousemove mouseup'; + _globalEventHandlers.mousedown = _globalEventHandlers[_dragStartEvent]; + _globalEventHandlers.mousemove = _globalEventHandlers[_dragMoveEvent]; + _globalEventHandlers.mouseup = _globalEventHandlers[_dragEndEvent]; + } + + if(!_likelyTouchDevice) { + // don't allow pan to next slide from zoomed state on Desktop + _options.allowPanToNext = false; + } + } + + } +}); + + +/*>>gestures*/ + +/*>>show-hide-transition*/ +/** + * show-hide-transition.js: + * + * Manages initial opening or closing transition. + * + * If you're not planning to use transition for gallery at all, + * you may set options hideAnimationDuration and showAnimationDuration to 0, + * and just delete startAnimation function. + * + */ + + +var _showOrHideTimeout, + _showOrHide = function(item, img, out, completeFn) { + + if(_showOrHideTimeout) { + clearTimeout(_showOrHideTimeout); + } + + _initialZoomRunning = true; + _initialContentSet = true; + + // dimensions of small thumbnail {x:,y:,w:}. + // Height is optional, as calculated based on large image. + var thumbBounds; + if(item.initialLayout) { + thumbBounds = item.initialLayout; + item.initialLayout = null; + } else { + thumbBounds = _options.getThumbBoundsFn && _options.getThumbBoundsFn(_currentItemIndex); + } + + var duration = out ? _options.hideAnimationDuration : _options.showAnimationDuration; + + var onComplete = function() { + _stopAnimation('initialZoom'); + if(!out) { + _applyBgOpacity(1); + if(img) { + img.style.display = 'block'; + } + framework.addClass(template, 'pswp--animated-in'); + _shout('initialZoom' + (out ? 'OutEnd' : 'InEnd')); + } else { + self.template.removeAttribute('style'); + self.bg.removeAttribute('style'); + } + + if(completeFn) { + completeFn(); + } + _initialZoomRunning = false; + }; + + // if bounds aren't provided, just open gallery without animation + if(!duration || !thumbBounds || thumbBounds.x === undefined) { + + _shout('initialZoom' + (out ? 'Out' : 'In') ); + + _currZoomLevel = item.initialZoomLevel; + _equalizePoints(_panOffset, item.initialPosition ); + _applyCurrentZoomPan(); + + template.style.opacity = out ? 0 : 1; + _applyBgOpacity(1); + + if(duration) { + setTimeout(function() { + onComplete(); + }, duration); + } else { + onComplete(); + } + + return; + } + + var startAnimation = function() { + var closeWithRaf = _closedByScroll, + fadeEverything = !self.currItem.src || self.currItem.loadError || _options.showHideOpacity; + + // apply hw-acceleration to image + if(item.miniImg) { + item.miniImg.style.webkitBackfaceVisibility = 'hidden'; + } + + if(!out) { + _currZoomLevel = thumbBounds.w / item.w; + _panOffset.x = thumbBounds.x; + _panOffset.y = thumbBounds.y - _initalWindowScrollY; + + self[fadeEverything ? 'template' : 'bg'].style.opacity = 0.001; + _applyCurrentZoomPan(); + } + + _registerStartAnimation('initialZoom'); + + if(out && !closeWithRaf) { + framework.removeClass(template, 'pswp--animated-in'); + } + + if(fadeEverything) { + if(out) { + framework[ (closeWithRaf ? 'remove' : 'add') + 'Class' ](template, 'pswp--animate_opacity'); + } else { + setTimeout(function() { + framework.addClass(template, 'pswp--animate_opacity'); + }, 30); + } + } + + _showOrHideTimeout = setTimeout(function() { + + _shout('initialZoom' + (out ? 'Out' : 'In') ); + + + if(!out) { + + // "in" animation always uses CSS transitions (instead of rAF). + // CSS transition work faster here, + // as developer may also want to animate other things, + // like ui on top of sliding area, which can be animated just via CSS + + _currZoomLevel = item.initialZoomLevel; + _equalizePoints(_panOffset, item.initialPosition ); + _applyCurrentZoomPan(); + _applyBgOpacity(1); + + if(fadeEverything) { + template.style.opacity = 1; + } else { + _applyBgOpacity(1); + } + + _showOrHideTimeout = setTimeout(onComplete, duration + 20); + } else { + + // "out" animation uses rAF only when PhotoSwipe is closed by browser scroll, to recalculate position + var destZoomLevel = thumbBounds.w / item.w, + initialPanOffset = { + x: _panOffset.x, + y: _panOffset.y + }, + initialZoomLevel = _currZoomLevel, + initalBgOpacity = _bgOpacity, + onUpdate = function(now) { + + if(now === 1) { + _currZoomLevel = destZoomLevel; + _panOffset.x = thumbBounds.x; + _panOffset.y = thumbBounds.y - _currentWindowScrollY; + } else { + _currZoomLevel = (destZoomLevel - initialZoomLevel) * now + initialZoomLevel; + _panOffset.x = (thumbBounds.x - initialPanOffset.x) * now + initialPanOffset.x; + _panOffset.y = (thumbBounds.y - _currentWindowScrollY - initialPanOffset.y) * now + initialPanOffset.y; + } + + _applyCurrentZoomPan(); + if(fadeEverything) { + template.style.opacity = 1 - now; + } else { + _applyBgOpacity( initalBgOpacity - now * initalBgOpacity ); + } + }; + + if(closeWithRaf) { + _animateProp('initialZoom', 0, 1, duration, framework.easing.cubic.out, onUpdate, onComplete); + } else { + onUpdate(1); + _showOrHideTimeout = setTimeout(onComplete, duration + 20); + } + } + + }, out ? 25 : 90); // Main purpose of this delay is to give browser time to paint and + // create composite layers of PhotoSwipe UI parts (background, controls, caption, arrows). + // Which avoids lag at the beginning of scale transition. + }; + startAnimation(); + + + }; + +/*>>show-hide-transition*/ + +/*>>items-controller*/ +/** +* +* Controller manages gallery items, their dimensions, and their content. +* +*/ + +var _items, + _tempPanAreaSize = {}, + _imagesToAppendPool = [], + _initialContentSet, + _initialZoomRunning, + _controllerDefaultOptions = { + index: 0, + errorMsg: '<div class="pswp__error-msg"><a href="%url%" target="_blank">The image</a> could not be loaded.</div>', + forceProgressiveLoading: false, // TODO + preload: [1,1], + getNumItemsFn: function() { + return _items.length; + } + }; + + +var _getItemAt, + _getNumItems, + _initialIsLoop, + _getZeroBounds = function() { + return { + center:{x:0,y:0}, + max:{x:0,y:0}, + min:{x:0,y:0} + }; + }, + _calculateSingleItemPanBounds = function(item, realPanElementW, realPanElementH ) { + var bounds = item.bounds; + + // position of element when it's centered + bounds.center.x = Math.round((_tempPanAreaSize.x - realPanElementW) / 2); + bounds.center.y = Math.round((_tempPanAreaSize.y - realPanElementH) / 2) + item.vGap.top; + + // maximum pan position + bounds.max.x = (realPanElementW > _tempPanAreaSize.x) ? + Math.round(_tempPanAreaSize.x - realPanElementW) : + bounds.center.x; + + bounds.max.y = (realPanElementH > _tempPanAreaSize.y) ? + Math.round(_tempPanAreaSize.y - realPanElementH) + item.vGap.top : + bounds.center.y; + + // minimum pan position + bounds.min.x = (realPanElementW > _tempPanAreaSize.x) ? 0 : bounds.center.x; + bounds.min.y = (realPanElementH > _tempPanAreaSize.y) ? item.vGap.top : bounds.center.y; + }, + _calculateItemSize = function(item, viewportSize, zoomLevel) { + + if (item.src && !item.loadError) { + var isInitial = !zoomLevel; + + if(isInitial) { + if(!item.vGap) { + item.vGap = {top:0,bottom:0}; + } + // allows overriding vertical margin for individual items + _shout('parseVerticalMargin', item); + } + + + _tempPanAreaSize.x = viewportSize.x; + _tempPanAreaSize.y = viewportSize.y - item.vGap.top - item.vGap.bottom; + + if (isInitial) { + var hRatio = _tempPanAreaSize.x / item.w; + var vRatio = _tempPanAreaSize.y / item.h; + + item.fitRatio = hRatio < vRatio ? hRatio : vRatio; + //item.fillRatio = hRatio > vRatio ? hRatio : vRatio; + + var scaleMode = _options.scaleMode; + + if (scaleMode === 'orig') { + zoomLevel = 1; + } else if (scaleMode === 'fit') { + zoomLevel = item.fitRatio; + } + + if (zoomLevel > 1) { + zoomLevel = 1; + } + + item.initialZoomLevel = zoomLevel; + + if(!item.bounds) { + // reuse bounds object + item.bounds = _getZeroBounds(); + } + } + + if(!zoomLevel) { + return; + } + + _calculateSingleItemPanBounds(item, item.w * zoomLevel, item.h * zoomLevel); + + if (isInitial && zoomLevel === item.initialZoomLevel) { + item.initialPosition = item.bounds.center; + } + + return item.bounds; + } else { + item.w = item.h = 0; + item.initialZoomLevel = item.fitRatio = 1; + item.bounds = _getZeroBounds(); + item.initialPosition = item.bounds.center; + + // if it's not image, we return zero bounds (content is not zoomable) + return item.bounds; + } + + }, + + + + + _appendImage = function(index, item, baseDiv, img, preventAnimation, keepPlaceholder) { + + + if(item.loadError) { + return; + } + + if(img) { + + item.imageAppended = true; + _setImageSize(item, img, (item === self.currItem && _renderMaxResolution) ); + + baseDiv.appendChild(img); + + if(keepPlaceholder) { + setTimeout(function() { + if(item && item.loaded && item.placeholder) { + item.placeholder.style.display = 'none'; + item.placeholder = null; + } + }, 500); + } + } + }, + + + + _preloadImage = function(item) { + item.loading = true; + item.loaded = false; + var img = item.img = framework.createEl('pswp__img', 'img'); + var onComplete = function() { + item.loading = false; + item.loaded = true; + + if(item.loadComplete) { + item.loadComplete(item); + } else { + item.img = null; // no need to store image object + } + img.onload = img.onerror = null; + img = null; + }; + img.onload = onComplete; + img.onerror = function() { + item.loadError = true; + onComplete(); + }; + + img.src = item.src;// + '?a=' + Math.random(); + + return img; + }, + _checkForError = function(item, cleanUp) { + if(item.src && item.loadError && item.container) { + + if(cleanUp) { + item.container.innerHTML = ''; + } + + item.container.innerHTML = _options.errorMsg.replace('%url%', item.src ); + return true; + + } + }, + _setImageSize = function(item, img, maxRes) { + if(!item.src) { + return; + } + + if(!img) { + img = item.container.lastChild; + } + + var w = maxRes ? item.w : Math.round(item.w * item.fitRatio), + h = maxRes ? item.h : Math.round(item.h * item.fitRatio); + + if(item.placeholder && !item.loaded) { + item.placeholder.style.width = w + 'px'; + item.placeholder.style.height = h + 'px'; + } + + img.style.width = w + 'px'; + img.style.height = h + 'px'; + }, + _appendImagesPool = function() { + + if(_imagesToAppendPool.length) { + var poolItem; + + for(var i = 0; i < _imagesToAppendPool.length; i++) { + poolItem = _imagesToAppendPool[i]; + if( poolItem.holder.index === poolItem.index ) { + _appendImage(poolItem.index, poolItem.item, poolItem.baseDiv, poolItem.img, false, poolItem.clearPlaceholder); + } + } + _imagesToAppendPool = []; + } + }; + + + +_registerModule('Controller', { + + publicMethods: { + + lazyLoadItem: function(index) { + index = _getLoopedId(index); + var item = _getItemAt(index); + + if(!item || ((item.loaded || item.loading) && !_itemsNeedUpdate)) { + return; + } + + _shout('gettingData', index, item); + + if (!item.src) { + return; + } + + _preloadImage(item); + }, + initController: function() { + framework.extend(_options, _controllerDefaultOptions, true); + self.items = _items = items; + _getItemAt = self.getItemAt; + _getNumItems = _options.getNumItemsFn; //self.getNumItems; + + + + _initialIsLoop = _options.loop; + if(_getNumItems() < 3) { + _options.loop = false; // disable loop if less then 3 items + } + + _listen('beforeChange', function(diff) { + + var p = _options.preload, + isNext = diff === null ? true : (diff >= 0), + preloadBefore = Math.min(p[0], _getNumItems() ), + preloadAfter = Math.min(p[1], _getNumItems() ), + i; + + + for(i = 1; i <= (isNext ? preloadAfter : preloadBefore); i++) { + self.lazyLoadItem(_currentItemIndex+i); + } + for(i = 1; i <= (isNext ? preloadBefore : preloadAfter); i++) { + self.lazyLoadItem(_currentItemIndex-i); + } + }); + + _listen('initialLayout', function() { + self.currItem.initialLayout = _options.getThumbBoundsFn && _options.getThumbBoundsFn(_currentItemIndex); + }); + + _listen('mainScrollAnimComplete', _appendImagesPool); + _listen('initialZoomInEnd', _appendImagesPool); + + + + _listen('destroy', function() { + var item; + for(var i = 0; i < _items.length; i++) { + item = _items[i]; + // remove reference to DOM elements, for GC + if(item.container) { + item.container = null; + } + if(item.placeholder) { + item.placeholder = null; + } + if(item.img) { + item.img = null; + } + if(item.preloader) { + item.preloader = null; + } + if(item.loadError) { + item.loaded = item.loadError = false; + } + } + _imagesToAppendPool = null; + }); + }, + + + getItemAt: function(index) { + if (index >= 0) { + return _items[index] !== undefined ? _items[index] : false; + } + return false; + }, + + allowProgressiveImg: function() { + // 1. Progressive image loading isn't working on webkit/blink + // when hw-acceleration (e.g. translateZ) is applied to IMG element. + // That's why in PhotoSwipe parent element gets zoom transform, not image itself. + // + // 2. Progressive image loading sometimes blinks in webkit/blink when applying animation to parent element. + // That's why it's disabled on touch devices (mainly because of swipe transition) + // + // 3. Progressive image loading sometimes doesn't work in IE (up to 11). + + // Don't allow progressive loading on non-large touch devices + return _options.forceProgressiveLoading || !_likelyTouchDevice || _options.mouseUsed || screen.width > 1200; + // 1200 - to eliminate touch devices with large screen (like Chromebook Pixel) + }, + + setContent: function(holder, index) { + + if(_options.loop) { + index = _getLoopedId(index); + } + + var prevItem = self.getItemAt(holder.index); + if(prevItem) { + prevItem.container = null; + } + + var item = self.getItemAt(index), + img; + + if(!item) { + holder.el.innerHTML = ''; + return; + } + + // allow to override data + _shout('gettingData', index, item); + + holder.index = index; + holder.item = item; + + // base container DIV is created only once for each of 3 holders + var baseDiv = item.container = framework.createEl('pswp__zoom-wrap'); + + + + if(!item.src && item.html) { + if(item.html.tagName) { + baseDiv.appendChild(item.html); + } else { + baseDiv.innerHTML = item.html; + } + } + + _checkForError(item); + + _calculateItemSize(item, _viewportSize); + + if(item.src && !item.loadError && !item.loaded) { + + item.loadComplete = function(item) { + + // gallery closed before image finished loading + if(!_isOpen) { + return; + } + + // check if holder hasn't changed while image was loading + if(holder && holder.index === index ) { + if( _checkForError(item, true) ) { + item.loadComplete = item.img = null; + _calculateItemSize(item, _viewportSize); + _applyZoomPanToItem(item); + + if(holder.index === _currentItemIndex) { + // recalculate dimensions + self.updateCurrZoomItem(); + } + return; + } + if( !item.imageAppended ) { + if(_features.transform && (_mainScrollAnimating || _initialZoomRunning) ) { + _imagesToAppendPool.push({ + item:item, + baseDiv:baseDiv, + img:item.img, + index:index, + holder:holder, + clearPlaceholder:true + }); + } else { + _appendImage(index, item, baseDiv, item.img, _mainScrollAnimating || _initialZoomRunning, true); + } + } else { + // remove preloader & mini-img + if(!_initialZoomRunning && item.placeholder) { + item.placeholder.style.display = 'none'; + item.placeholder = null; + } + } + } + + item.loadComplete = null; + item.img = null; // no need to store image element after it's added + + _shout('imageLoadComplete', index, item); + }; + + if(framework.features.transform) { + + var placeholderClassName = 'pswp__img pswp__img--placeholder'; + placeholderClassName += (item.msrc ? '' : ' pswp__img--placeholder--blank'); + + var placeholder = framework.createEl(placeholderClassName, item.msrc ? 'img' : ''); + if(item.msrc) { + placeholder.src = item.msrc; + } + + _setImageSize(item, placeholder); + + baseDiv.appendChild(placeholder); + item.placeholder = placeholder; + + } + + + + + if(!item.loading) { + _preloadImage(item); + } + + + if( self.allowProgressiveImg() ) { + // just append image + if(!_initialContentSet && _features.transform) { + _imagesToAppendPool.push({ + item:item, + baseDiv:baseDiv, + img:item.img, + index:index, + holder:holder + }); + } else { + _appendImage(index, item, baseDiv, item.img, true, true); + } + } + + } else if(item.src && !item.loadError) { + // image object is created every time, due to bugs of image loading & delay when switching images + img = framework.createEl('pswp__img', 'img'); + img.style.opacity = 1; + img.src = item.src; + _setImageSize(item, img); + _appendImage(index, item, baseDiv, img, true); + } + + + if(!_initialContentSet && index === _currentItemIndex) { + _currZoomElementStyle = baseDiv.style; + _showOrHide(item, (img ||item.img) ); + } else { + _applyZoomPanToItem(item); + } + + holder.el.innerHTML = ''; + holder.el.appendChild(baseDiv); + }, + + cleanSlide: function( item ) { + if(item.img ) { + item.img.onload = item.img.onerror = null; + } + item.loaded = item.loading = item.img = item.imageAppended = false; + } + + } +}); + +/*>>items-controller*/ + +/*>>tap*/ +/** + * tap.js: + * + * Displatches tap and double-tap events. + * + */ + +var tapTimer, + tapReleasePoint = {}, + _dispatchTapEvent = function(origEvent, releasePoint, pointerType) { + var e = document.createEvent( 'CustomEvent' ), + eDetail = { + origEvent:origEvent, + target:origEvent.target, + releasePoint: releasePoint, + pointerType:pointerType || 'touch' + }; + + e.initCustomEvent( 'pswpTap', true, true, eDetail ); + origEvent.target.dispatchEvent(e); + }; + +_registerModule('Tap', { + publicMethods: { + initTap: function() { + _listen('firstTouchStart', self.onTapStart); + _listen('touchRelease', self.onTapRelease); + _listen('destroy', function() { + tapReleasePoint = {}; + tapTimer = null; + }); + }, + onTapStart: function(touchList) { + if(touchList.length > 1) { + clearTimeout(tapTimer); + tapTimer = null; + } + }, + onTapRelease: function(e, releasePoint) { + if(!releasePoint) { + return; + } + + if(!_moved && !_isMultitouch && !_numAnimations) { + var p0 = releasePoint; + if(tapTimer) { + clearTimeout(tapTimer); + tapTimer = null; + + // Check if taped on the same place + if ( _isNearbyPoints(p0, tapReleasePoint) ) { + _shout('doubleTap', p0); + return; + } + } + + if(releasePoint.type === 'mouse') { + _dispatchTapEvent(e, releasePoint, 'mouse'); + return; + } + + var clickedTagName = e.target.tagName.toUpperCase(); + // avoid double tap delay on buttons and elements that have class pswp__single-tap + if(clickedTagName === 'BUTTON' || framework.hasClass(e.target, 'pswp__single-tap') ) { + _dispatchTapEvent(e, releasePoint); + return; + } + + _equalizePoints(tapReleasePoint, p0); + + tapTimer = setTimeout(function() { + _dispatchTapEvent(e, releasePoint); + tapTimer = null; + }, 300); + } + } + } +}); + +/*>>tap*/ + +/*>>desktop-zoom*/ +/** + * + * desktop-zoom.js: + * + * - Binds mousewheel event for paning zoomed image. + * - Manages "dragging", "zoomed-in", "zoom-out" classes. + * (which are used for cursors and zoom icon) + * - Adds toggleDesktopZoom function. + * + */ + +var _wheelDelta; + +_registerModule('DesktopZoom', { + + publicMethods: { + + initDesktopZoom: function() { + + if(_oldIE) { + // no zoom for old IE (<=8) + return; + } + + if(_likelyTouchDevice) { + // if detected hardware touch support, we wait until mouse is used, + // and only then apply desktop-zoom features + _listen('mouseUsed', function() { + self.setupDesktopZoom(); + }); + } else { + self.setupDesktopZoom(true); + } + + }, + + setupDesktopZoom: function(onInit) { + + _wheelDelta = {}; + + var events = 'wheel mousewheel DOMMouseScroll'; + + _listen('bindEvents', function() { + framework.bind(template, events, self.handleMouseWheel); + }); + + _listen('unbindEvents', function() { + if(_wheelDelta) { + framework.unbind(template, events, self.handleMouseWheel); + } + }); + + self.mouseZoomedIn = false; + + var hasDraggingClass, + updateZoomable = function() { + if(self.mouseZoomedIn) { + framework.removeClass(template, 'pswp--zoomed-in'); + self.mouseZoomedIn = false; + } + if(_currZoomLevel < 1) { + framework.addClass(template, 'pswp--zoom-allowed'); + } else { + framework.removeClass(template, 'pswp--zoom-allowed'); + } + removeDraggingClass(); + }, + removeDraggingClass = function() { + if(hasDraggingClass) { + framework.removeClass(template, 'pswp--dragging'); + hasDraggingClass = false; + } + }; + + _listen('resize' , updateZoomable); + _listen('afterChange' , updateZoomable); + _listen('pointerDown', function() { + if(self.mouseZoomedIn) { + hasDraggingClass = true; + framework.addClass(template, 'pswp--dragging'); + } + }); + _listen('pointerUp', removeDraggingClass); + + if(!onInit) { + updateZoomable(); + } + + }, + + handleMouseWheel: function(e) { + + if(_currZoomLevel <= self.currItem.fitRatio) { + if( _options.modal ) { + + if (!_options.closeOnScroll || _numAnimations || _isDragging) { + e.preventDefault(); + } else if(_transformKey && Math.abs(e.deltaY) > 2) { + // close PhotoSwipe + // if browser supports transforms & scroll changed enough + _closedByScroll = true; + self.close(); + } + + } + return true; + } + + // allow just one event to fire + e.stopPropagation(); + + // https://developer.mozilla.org/en-US/docs/Web/Events/wheel + _wheelDelta.x = 0; + + if('deltaX' in e) { + if(e.deltaMode === 1 /* DOM_DELTA_LINE */) { + // 18 - average line height + _wheelDelta.x = e.deltaX * 18; + _wheelDelta.y = e.deltaY * 18; + } else { + _wheelDelta.x = e.deltaX; + _wheelDelta.y = e.deltaY; + } + } else if('wheelDelta' in e) { + if(e.wheelDeltaX) { + _wheelDelta.x = -0.16 * e.wheelDeltaX; + } + if(e.wheelDeltaY) { + _wheelDelta.y = -0.16 * e.wheelDeltaY; + } else { + _wheelDelta.y = -0.16 * e.wheelDelta; + } + } else if('detail' in e) { + _wheelDelta.y = e.detail; + } else { + return; + } + + _calculatePanBounds(_currZoomLevel, true); + + var newPanX = _panOffset.x - _wheelDelta.x, + newPanY = _panOffset.y - _wheelDelta.y; + + // only prevent scrolling in nonmodal mode when not at edges + if (_options.modal || + ( + newPanX <= _currPanBounds.min.x && newPanX >= _currPanBounds.max.x && + newPanY <= _currPanBounds.min.y && newPanY >= _currPanBounds.max.y + ) ) { + e.preventDefault(); + } + + // TODO: use rAF instead of mousewheel? + self.panTo(newPanX, newPanY); + }, + + toggleDesktopZoom: function(centerPoint) { + centerPoint = centerPoint || {x:_viewportSize.x/2 + _offset.x, y:_viewportSize.y/2 + _offset.y }; + + var doubleTapZoomLevel = _options.getDoubleTapZoom(true, self.currItem); + var zoomOut = _currZoomLevel === doubleTapZoomLevel; + + self.mouseZoomedIn = !zoomOut; + + self.zoomTo(zoomOut ? self.currItem.initialZoomLevel : doubleTapZoomLevel, centerPoint, 333); + framework[ (!zoomOut ? 'add' : 'remove') + 'Class'](template, 'pswp--zoomed-in'); + } + + } +}); + + +/*>>desktop-zoom*/ + +/*>>history*/ +/** + * + * history.js: + * + * - Back button to close gallery. + * + * - Unique URL for each slide: example.com/&pid=1&gid=3 + * (where PID is picture index, and GID and gallery index) + * + * - Switch URL when slides change. + * + */ + + +var _historyDefaultOptions = { + history: true, + galleryUID: 1 +}; + +var _historyUpdateTimeout, + _hashChangeTimeout, + _hashAnimCheckTimeout, + _hashChangedByScript, + _hashChangedByHistory, + _hashReseted, + _initialHash, + _historyChanged, + _closedFromURL, + _urlChangedOnce, + _windowLoc, + + _supportsPushState, + + _getHash = function() { + return _windowLoc.hash.substring(1); + }, + _cleanHistoryTimeouts = function() { + + if(_historyUpdateTimeout) { + clearTimeout(_historyUpdateTimeout); + } + + if(_hashAnimCheckTimeout) { + clearTimeout(_hashAnimCheckTimeout); + } + }, + + // pid - Picture index + // gid - Gallery index + _parseItemIndexFromURL = function() { + var hash = _getHash(), + params = {}; + + if(hash.length < 5) { // pid=1 + return params; + } + + var i, vars = hash.split('&'); + for (i = 0; i < vars.length; i++) { + if(!vars[i]) { + continue; + } + var pair = vars[i].split('='); + if(pair.length < 2) { + continue; + } + params[pair[0]] = pair[1]; + } + if(_options.galleryPIDs) { + // detect custom pid in hash and search for it among the items collection + var searchfor = params.pid; + params.pid = 0; // if custom pid cannot be found, fallback to the first item + for(i = 0; i < _items.length; i++) { + if(_items[i].pid === searchfor) { + params.pid = i; + break; + } + } + } else { + params.pid = parseInt(params.pid,10)-1; + } + if( params.pid < 0 ) { + params.pid = 0; + } + return params; + }, + _updateHash = function() { + + if(_hashAnimCheckTimeout) { + clearTimeout(_hashAnimCheckTimeout); + } + + + if(_numAnimations || _isDragging) { + // changing browser URL forces layout/paint in some browsers, which causes noticable lag during animation + // that's why we update hash only when no animations running + _hashAnimCheckTimeout = setTimeout(_updateHash, 500); + return; + } + + if(_hashChangedByScript) { + clearTimeout(_hashChangeTimeout); + } else { + _hashChangedByScript = true; + } + + + var pid = (_currentItemIndex + 1); + var item = _getItemAt( _currentItemIndex ); + if(item.hasOwnProperty('pid')) { + // carry forward any custom pid assigned to the item + pid = item.pid; + } + var newHash = _initialHash + '&' + 'gid=' + _options.galleryUID + '&' + 'pid=' + pid; + + if(!_historyChanged) { + if(_windowLoc.hash.indexOf(newHash) === -1) { + _urlChangedOnce = true; + } + // first time - add new hisory record, then just replace + } + + var newURL = _windowLoc.href.split('#')[0] + '#' + newHash; + + if( _supportsPushState ) { + + if('#' + newHash !== window.location.hash) { + history[_historyChanged ? 'replaceState' : 'pushState']('', document.title, newURL); + } + + } else { + if(_historyChanged) { + _windowLoc.replace( newURL ); + } else { + _windowLoc.hash = newHash; + } + } + + + + _historyChanged = true; + _hashChangeTimeout = setTimeout(function() { + _hashChangedByScript = false; + }, 60); + }; + + + + + +_registerModule('History', { + + + + publicMethods: { + initHistory: function() { + + framework.extend(_options, _historyDefaultOptions, true); + + if( !_options.history ) { + return; + } + + + _windowLoc = window.location; + _urlChangedOnce = false; + _closedFromURL = false; + _historyChanged = false; + _initialHash = _getHash(); + _supportsPushState = ('pushState' in history); + + + if(_initialHash.indexOf('gid=') > -1) { + _initialHash = _initialHash.split('&gid=')[0]; + _initialHash = _initialHash.split('?gid=')[0]; + } + + + _listen('afterChange', self.updateURL); + _listen('unbindEvents', function() { + framework.unbind(window, 'hashchange', self.onHashChange); + }); + + + var returnToOriginal = function() { + _hashReseted = true; + if(!_closedFromURL) { + + if(_urlChangedOnce) { + history.back(); + } else { + + if(_initialHash) { + _windowLoc.hash = _initialHash; + } else { + if (_supportsPushState) { + + // remove hash from url without refreshing it or scrolling to top + history.pushState('', document.title, _windowLoc.pathname + _windowLoc.search ); + } else { + _windowLoc.hash = ''; + } + } + } + + } + + _cleanHistoryTimeouts(); + }; + + + _listen('unbindEvents', function() { + if(_closedByScroll) { + // if PhotoSwipe is closed by scroll, we go "back" before the closing animation starts + // this is done to keep the scroll position + returnToOriginal(); + } + }); + _listen('destroy', function() { + if(!_hashReseted) { + returnToOriginal(); + } + }); + _listen('firstUpdate', function() { + _currentItemIndex = _parseItemIndexFromURL().pid; + }); + + + + + var index = _initialHash.indexOf('pid='); + if(index > -1) { + _initialHash = _initialHash.substring(0, index); + if(_initialHash.slice(-1) === '&') { + _initialHash = _initialHash.slice(0, -1); + } + } + + + setTimeout(function() { + if(_isOpen) { // hasn't destroyed yet + framework.bind(window, 'hashchange', self.onHashChange); + } + }, 40); + + }, + onHashChange: function() { + + if(_getHash() === _initialHash) { + + _closedFromURL = true; + self.close(); + return; + } + if(!_hashChangedByScript) { + + _hashChangedByHistory = true; + self.goTo( _parseItemIndexFromURL().pid ); + _hashChangedByHistory = false; + } + + }, + updateURL: function() { + + // Delay the update of URL, to avoid lag during transition, + // and to not to trigger actions like "refresh page sound" or "blinking favicon" to often + + _cleanHistoryTimeouts(); + + + if(_hashChangedByHistory) { + return; + } + + if(!_historyChanged) { + _updateHash(); // first time + } else { + _historyUpdateTimeout = setTimeout(_updateHash, 800); + } + } + + } +}); + + +/*>>history*/ + framework.extend(self, publicMethods); }; + return PhotoSwipe; +}); \ No newline at end of file diff --git a/static/app2/js/pj.js b/static/app2/js/pj.js new file mode 100755 index 0000000..22ae733 --- /dev/null +++ b/static/app2/js/pj.js @@ -0,0 +1,236 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var self = plus.webview.currentWebview(); + var data_order_id = self.data_order_id; + mui.ajax(qlgUrl('app/Orders/getOrderAppraise'), { + headers: { + "HYH-Token": token + }, + data: { + oId: data_order_id + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + data = data.data + var html = ''; + var i = 0; + $.each(data.Rows, function() { + if (this.appraise == null) { + html += '<div class="con_1"data-goodsId="' + this.goodsId + '"data-goodsSpecId="' + this.goodsSpecId + + '"data-orderId="' + this.orderId + '"data-orderGoodsId="' + this.id + + '"><div class="describe"><div class="des_img"><img src="' + hyhImgUrl(this.goodsImg) + '"/></div><p>' + + this.goodsName + + '</p></div><div class="row"data-class="goodsScore"data-goodsScore="0"><p>商品评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="serviceScore"data-serviceScore="0"><p>服务评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="timeScore"data-timeScore="0"><p>时效评分</p><div class="star"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="purchase"><textarea class="content"name=""rows=""cols=""placeholder="分享你的购买心得"></textarea><div class="up_out"><div id="ossfile' + + i + '" class="ossfile clearfix" data-num="' + i + + '">你的浏览器不支持flash,Silverlight或者HTML5!</div><div id="container' + i + '" class="container" data-num="' + i + + '"><a id="selectfiles' + i + '" href="javascript:void(0);" class="btn selectfiles" data-num="' + i + + '">选择图片</a></div></div></div><button class="tijiao">提交评价</button></div>' + i++; + } else { + html += '<div class="con_1"data-goodsId="' + this.goodsId + '"data-goodsSpecId="' + this.goodsSpecId + + '"data-orderId="' + data.orderId + '"data-orderGoodsId="' + this.orderId + + '"><div class="describe"><div class="des_img"><img src="' + hyhImgUrl(this.goodsImg) + '"/></div><p>' + + this.goodsName + '</p></div><div class="row"data-class="goodsScore"data-goodsScore="' + this.appraise.goodsScore + + '"><p>商品评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="serviceScore"data-serviceScore="' + + this.appraise.serviceScore + + '"><p>服务评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="row"data-class="timeScore"data-timeScore="' + + this.appraise.timeScore + + '"><p>时效评分</p><div class="star"data-isPj="1"><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div><div class="star_a"><div class="star_off"></div></div></div></div><div class="purchase_"><p>' + + this.appraise.content + '</p>' + + $.each(this.appraise.images, function() { + html += '<img src="' + hyhImgUrl(this) + '"/>' + }); + + + + html += '</div></div>'; + } + }); + $('.con').html(html) + $('.star').each(function() { + if ($(this).attr('data-isPj') == 1) { + var num = +$(this).parent().attr('data-' + $(this).parent().attr('data-class')) - 1 + $(this).children().eq(num).children().addClass('star_on').removeClass('star_off') + $(this).children().eq(num).prevAll().children().addClass('star_on').removeClass('star_off') + $(this).children().eq(num).nextAll().children().addClass('star_off').removeClass('star_on') + } + }) + var btnArr = []; + + $('.selectfiles').each(function(num) { + btnArr.push($(this).attr('id')); + }) + + $.each(btnArr, function(i, n) { + var self = this.toString(); + var that = document.getElementById(this); + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: self, + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + dir: 'appraises', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementsByClassName('ossfile')[i].innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false, 'appraises'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementsByClassName('ossfile')[i].innerHTML += '<div class="files_out" id="' + file.id + + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if (info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name)) + + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if (err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if (err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if (err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); + }); + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + $('.con').on('tap', '.star_a', function() { + if ($(this).parent().attr('data-isPj') == 1) { + return; + } + $(this).children().addClass('star_on').removeClass('star_off'); + $(this).prevAll().children().addClass('star_on').removeClass('star_off'); + $(this).nextAll().children().addClass('star_off').removeClass('star_on'); + $(this).parent().parent().attr('data-' + $(this).parent().parent().attr('data-class'), $(this).index() + 1); + }) + + $('.con').on('tap', '.tijiao', function() { + var goodsId = $(this).parent().attr('data-goodsId'); + var goodsSpecId = $(this).parent().attr('data-goodsSpecId'); + var orderId = $(this).parent().attr('data-orderId'); + var orderGoodsId = $(this).parent().attr('data-orderGoodsId'); + var timeScore = $(this).siblings('.row[data-class*=timeScore]').attr('data-timeScore'); + var goodsScore = $(this).siblings('.row[data-class*=goodsScore]').attr('data-goodsScore'); + var serviceScore = $(this).siblings('.row[data-class*=serviceScore]').attr('data-serviceScore'); + var content = $(this).siblings('.purchase').children('textarea').val(); + var that = $(this); + var imagesArr = []; + $(this).siblings('.purchase').children('.up_out').children('.ossfile').children('.files_out').children('b').children( + 'img').each(function() { + imagesArr.push($(this).attr('data-src')) + }) + var images = imagesArr.join(','); + if (timeScore == 0 || serviceScore == 0 || serviceScore == 0) { + mui.alert('评分必须1-5分之间!'); + return; + } + if (content.length < 3) { + mui.alert('评论最少3个字!'); + return; + } + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/Goodsappraises/add'), { + headers: { + "HYH-Token": token + }, + data: { + goodsId: goodsId, + goodsSpecId: goodsSpecId, + orderId: orderId, + orderGoodsId: orderGoodsId, + timeScore: timeScore, + goodsScore: goodsScore, + serviceScore: serviceScore, + content: content, + images: images + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + mui.alert(data.msg) + if (data.status == 1) { + location.reload(); + } else { + mui.alert(data.msg) + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) +}) diff --git a/static/app2/js/plupload.full.min.js b/static/app2/js/plupload.full.min.js new file mode 100755 index 0000000..ca6cdf8 --- /dev/null +++ b/static/app2/js/plupload.full.min.js @@ -0,0 +1,28 @@ +/** + * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill + * v1.2.1 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",h="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",b="moxie/file/FileReader",R="moxie/core/utils/Url",T="moxie/file/FileReaderSync",A="moxie/xhr/FormData",S="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",h="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var h=f[n],p=f[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<h.length;a++)if(l=h[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(h,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[h,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?void t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),void(n[this.uid][e]=s))},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,m[h++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[h++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,p],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[h,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?void i.init():void i.trigger("Error")):void o(t)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),void(i=null))}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,h,p,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,h;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);h={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},h,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:void c.files.push(new a(c.ruid,e))})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,h,u,w,v,p,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(b,[u,m,h,p,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var h=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=h;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(h)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend")) +},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(R,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(A,[h,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(S,[u,h,p,m,R,g,x,y,T,A,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function h(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:void(l.can("define_property")?y[e]=t:v[e]=t):void 0}function u(t){function i(){k&&(k.destroy(),k=null),s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",h.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==h.LOADING&&(n("readyState",h.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",h.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",h.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:b,password:R,headers:x,mimeType:A,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:h.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},b,R,T=null,A=null,S=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(b=u||l.user,R=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);S=!w,O=!1,x={},g.call(this),n("readyState",h.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[h.LOADING,h.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,A=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,A=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",A="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!S&&this.upload.hasEventListener(),N=!1,D=!n,S||(O=!0),u.call(this,n)},abort:function(){if(N=!0,S=!1,~e.inArray(n("readyState"),[h.UNSENT,h.OPENED,h.DONE]))n("readyState",h.UNSENT);else{if(n("readyState",h.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return h.UNSENT=0,h.OPENED=1,h.HEADERS_RECEIVED=2,h.LOADING=3,h.DONE=4,h.prototype=n.instance,h}),i(O,[u,m,v,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,h,T,S,g,v,O,d,p,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function h(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof h){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(p),c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,crop:!1,preserveHeaders:!0};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.getRuntime().exec.call(this,"Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),void o.trigger("embedded")}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},p,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,p=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=p.type||this.type||"image/jpeg",l=p.quality||90,d="undefined"!==e.typeOf(p.crop)?p.crop:!1,p.width)m=p.width,g=p.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new h,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var p=["progress","load","error","resize","embedded"];return h.MAX_RESIZE_WIDTH=6500,h.MAX_RESIZE_HEIGHT=6500,h.prototype=c.instance,h}),i(D,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,h,p,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),h=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(h,"position")&&(h.style.position="relative"),p=parseInt(n.getStyle(h,"z-index"),10)||1,h.style.zIndex=p,d.style.zIndex=p-1,i.addEvent(h,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?h:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser&&"IEMobile"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var n=t.toArray(e.dataTransfer.types||[]);return-1!==t.inArray("Files",n)||-1!==t.inArray("public.file-url",n)||-1!==t.inArray("application/x-moz-file",n)}function o(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function a(e){if(!f.length)return!0;var n=r.getFileExtension(e.name);return!n||-1!==t.inArray(n,f)}function s(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();a(n)&&d.push(n)}else i.push(t)}),i.length?u(i,n):n()}function u(e,n){var i=[];t.each(e,function(e){i.push(function(t){c(e,t)})}),t.inSeries(i,function(){n()})}function c(e,t){e.isFile?e.file(function(e){a(e)&&d.push(e),t()},function(){t()}):e.isDirectory?l(e,t):t()}function l(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){u(i,t)})}var d=[],f=[],h;t.extend(this,{init:function(n){var r=this,u;h=n,f=o(h.accept),u=h.container,i.addEvent(u,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},r.uid),i.addEvent(u,"drop",function(n){e(n)&&(n.preventDefault(),d=[],n.dataTransfer.items&&n.dataTransfer.items[0].webkitGetAsEntry?s(n.dataTransfer.items,function(){r.trigger("drop")}):(t.each(n.dataTransfer.files,function(e){a(e)&&d.push(e)}),r.trigger("drop")))},r.uid),i.addEvent(u,"dragenter",function(e){r.trigger("dragenter")},r.uid),i.addEvent(u,"dragleave",function(e){r.trigger("dragleave")},r.uid)},getFiles:function(){return d},destroy:function(){i.removeAllEvents(h&&n.get(h.container),this.uid),d=f=h=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,R,w,y,A,h,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return h.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,h,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),h=c(),h.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}h.upload?(n.withCredentials&&(h.withCredentials=!0),h.addEventListener("load",function(e){s.trigger(e)}),h.addEventListener("error",function(e){s.trigger(e)}),h.addEventListener("progress",function(e){s.trigger(e)}),h.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):h.onreadystatechange=function v(){switch(h.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=h.getResponseHeader("Content-Length")||0),h.responseText&&(t=h.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:h.onreadystatechange=function(){},s.trigger(0===h.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){h.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in h&&(h.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?h.sendAsBinary?h.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);h.send(e.buffer)}():h.send(r),s.trigger("loadstart")},getStatus:function(){try{if(h)return h.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,h.response),o=h.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?h.response:200===h.status&&window.JSON?JSON.parse(h.responseText):null;case"document":return l(h);default:return""!==h.responseText?h.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return h.getAllResponseHeaders()}catch(e){}return""},abort:function(){h&&h.abort()},destroy:function(){f=p=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(t>>Math.abs(a+8*s)&255);n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:void(r=e)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):void i(n,r,4)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,h,p,m=[],g={};for(r=0;i>r;r++)if(h=f=e+12*r+2,s=n[a.SHORT(h)],s!==t){switch(u=a.SHORT(h+=2),d=a.LONG(h+=2),h+=4,m=[],u){case 1:case 7:for(d>4&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(h+o);break;case 2:d>4&&(h=a.LONG(h)+c.tiffHeader),g[s]=a.STRING(h,d-1);continue;case 3:for(d>2&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(h+2*o);break;case 4:for(d>1&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(h+4*o);break;case 5:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(h+4*o)/a.LONG(h+4*o+4);break;case 9:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o);break;case 10:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o)/a.SLONG(h+4*o+4);break;default:continue}p=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof p?l[s][p]:p}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\x00"===a.STRING(4,5).toUpperCase()?r():!1):!1 +},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,h,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,h;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,h=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return h?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.getBinary())):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),h&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[h,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,h,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,h=document.createElement("canvas");h.width=h.height=f;for(var p=h.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;p.clearRect(0,0,f,f),p.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,b=Math.ceil(v*u/a/m);d.drawImage(h,0,0,w,v,E,x,_,b),y+=f}g+=f}h=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,h,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function h(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,h,g;if(R=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),h=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),h>i&&(l=Math.round((h-i)/2))):(E.width=f,E.height=h),R||m(E.width,E.height,g),p.call(this,d,E,-c,-l,f,h),this.width=E.width,this.height=E.height,b=!0,void a.trigger("Resize"))}function p(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,b=!1}var v=this,y,w,E,_,x,b=!1,R=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),void d.call(this,_)):void f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){h.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&h.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!b)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!b)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),R&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return b=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,h,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===c.mode},stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,A,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,h,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,h,p,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(h=n.get(a+"_form"),h&&t.extend(h.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),t.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=p=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=h=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,R,h,L,y,A],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function h(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),w&&p.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),h(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,h,p,m,g,v,y,w,E,_,x,b,R,T,A,S,O,I,L])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this); +/** + * Plupload - multi-runtime File Uploader + * v2.1.2 + * + * Copyright 2013, Moxiecode Systems AB + * Released under GPL License. + * + * License: http://www.plupload.com/license + * Contributing: http://www.plupload.com/contributing + * + * Date: 2014-05-14 + */ +;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.2",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie); \ No newline at end of file diff --git a/static/app2/js/properties.js b/static/app2/js/properties.js new file mode 100755 index 0000000..3ebfedf --- /dev/null +++ b/static/app2/js/properties.js @@ -0,0 +1,106 @@ +mui.plusReady(function() { + + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + //console.log(shopId); + var page = 1; + var pageSize = 10; + var isloading = false; + getRecommend(page, pageSize); + + function getRecommend(page, pageSize) { + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + recommenddata.shopId = shopId + if (isloading == true) { + return; + } else { + isloading = false; + } + isloading == true + JZL.ajax(qlgUrl("app/shops/getSpecs"), recommenddata, function(data) { + //console.log(data); + if (data.status == 1) { + var html = ''; + var data = data.data; + if ('' == data.Rows) { + //console.log("去" ); + $('.con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + return; + } + $.each(data.Rows, function() { + html += '<div class="row shadown_wai" data-id="' + this.id + '"><label>' + this.setName + + '</label><div class="caozuo"><span class="bj"><img src="../img/bianji.png"></span><span class="del"><img src="../img/delete.png"></span></div></div>' + + if (page == 1) { + $('.con_con').html(html); + } else { + $('.con_con').append(html); + } + + }) + } else { + mui.alert(data.msg) + } + isloading == false; + }) + + } + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isloading == true) { + page++; + getRecommend(page, pageSize); + } + } + }) + var specCatsId = ""; + mui('.con').on('tap', '.bj', function() { + + // //console.log(1); + specCatsId = $(this).parent().parent().attr("data-id"); + //console.log(specCatsId); + var setName = $(this).parent().parent().find("label").text(); + //console.log(setName); + + JZL.openWindow("addproperties.html", parseInt(shopId), { + "specCatsId": specCatsId, + "setName": setName + }) + }) + //删除 + $('.con').on('tap', '.del', function() { + specCatsId = $(this).parent().parent().attr("data-id"); + + if (confirm('确认删除?')) { + JZL.ajax(qlgUrl('app/shops/delSpecSet'), { + id: specCatsId, + shopId: shopId + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + //console.log(1); + //console.log(data); + if (data.status == 1) { + + location.reload() + } else { + mui.alert(data.msg) + } + }) + + } + }) + + $('.add1').on('tap', function() { + JZL.openWindow('addproperties.html',parseInt(shopId)); + }) + +}) diff --git a/static/app2/js/qrbb.js b/static/app2/js/qrbb.js new file mode 100755 index 0000000..a670935 --- /dev/null +++ b/static/app2/js/qrbb.js @@ -0,0 +1,111 @@ +mui.plusReady(function() { + + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var page = 1; + var pageSize = 10; + // var isloading = false; + getRecommend(); + + function getRecommend() { + + // //console.log(recommenddata); + //获取亲人报备列表 + JZL.ajax(qlgUrl('app/auth/getAuthFamilyReportSelect'), {}, function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + if (data.status == 1) { + var html = ''; + var data = data.data; + if (data == '') { + $('.con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + return; + } + $.each(data, function() { + html += '<div class="block clearfix" data-id="' + this.id + + '"><p class="pname">' + this.familyName + '(' + this.familyRelations + + ')</p><div class="caozuo"><span class="bj" data-id="' + this.id + + '"><img src="../img/bianji.png"></span><span class="del" data-id="' + this.id + + '"><img src="../img/delete.png"></span></div></div>'; + }) + $('.con').html(html); + } else { + mui.alert(data.msg) + } + }); + + + } + // document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + // if (scroll.y == scroll.maxScrollY) { + // if (isloading == true) { + // page++; + // getRecommend(page, pageSize); + // } + // } + // }) + + var qrbbid; + mui('.con').on('tap', '.bj', function() { + qrbbid = $(this).attr('data-id') + + JZL.openWindow('addqrbb.html', qrbbid); + + }) + $('.con').on('tap', '.del', function() { + qrbbid = $(this).attr('data-id') + if (confirm('确认删除?')) { + var lxy_div = + '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"> <div class="lxy_zz clearfix"><h3>请输入操作密码</h3><div style="background:linear-gradient(to right,#48D1CC,#FFD700,#D2691E);height:5px; margin:10px auto"></div><input class="payword" type="password" placeholder="请输入操作密码"><div class="lxy_zz_btn"><button class="cancle" type="button">取消</button><button class="sure" type="button">确定</button></div></div></div>'; + + $('body').append(lxy_div); + + $('.lxy_zz').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + }) + mui('.lxy_zz_btn').on('tap', '.cancle', function() { + // $('#home_zhezhao').css('display', 'none'); + $('#home_zhezhao').remove(); + return; + + }) + + mui('.lxy_zz_btn').on('tap', '.sure', function() { + var payPwd = $('.payword').val(); + //console.log(payPwd); + if (payPwd == '') { + mui.alert("请输入密码") + } + JZL.ajax(qlgUrl('app/auth/delAuthFamily'), { + isReport: 1, + id: qrbbid, + payPwd: payPwd + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + var data = toJson(data, 1); + if (data.status == 1) { + $('#home_zhezhao').remove(); + location.reload() + } else { + mui.alert(data.msg) + } + }) + + }); + } + + }) + /* mui('.mui-content').on('tap','.qrrz',function(){ + JZL.openWindow('qrrz.html', 'qrrz.html'); + + }) */ + $('.add1').on('tap', function() { + JZL.openWindow('addqrbb.html', 'addqrbb.html'); + }) + + + + +}) diff --git a/static/app2/js/qrcode.js b/static/app2/js/qrcode.js new file mode 100755 index 0000000..5507c15 --- /dev/null +++ b/static/app2/js/qrcode.js @@ -0,0 +1,614 @@ +/** + * @fileoverview + * - Using the 'QRCode for Javascript library' + * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. + * - this library has no dependencies. + * + * @author davidshimjs + * @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a> + * @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a> + */ +var QRCode; + +(function () { + //--------------------------------------------------------------------- + // QRCode for JavaScript + // + // Copyright (c) 2009 Kazuhiko Arase + // + // URL: http://www.d-project.com/ + // + // Licensed under the MIT license: + // http://www.opensource.org/licenses/mit-license.php + // + // The word "QR Code" is registered trademark of + // DENSO WAVE INCORPORATED + // http://www.denso-wave.com/qrcode/faqpatent-e.html + // + //--------------------------------------------------------------------- + function QR8bitByte(data) { + this.mode = QRMode.MODE_8BIT_BYTE; + this.data = data; + this.parsedData = []; + + // Added to support UTF-8 Characters + for (var i = 0, l = this.data.length; i < l; i++) { + var byteArray = []; + var code = this.data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + this.parsedData.push(byteArray); + } + + this.parsedData = Array.prototype.concat.apply([], this.parsedData); + + if (this.parsedData.length != this.data.length) { + this.parsedData.unshift(191); + this.parsedData.unshift(187); + this.parsedData.unshift(239); + } + } + + QR8bitByte.prototype = { + getLength: function (buffer) { + return this.parsedData.length; + }, + write: function (buffer) { + for (var i = 0, l = this.parsedData.length; i < l; i++) { + buffer.put(this.parsedData[i], 8); + } + } + }; + + function QRCodeModel(typeNumber, errorCorrectLevel) { + this.typeNumber = typeNumber; + this.errorCorrectLevel = errorCorrectLevel; + this.modules = null; + this.moduleCount = 0; + this.dataCache = null; + this.dataList = []; + } + + QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} + return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}} + this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);} + if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} + this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} + return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}} + return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;} + this.modules[r][6]=(r%2==0);} + for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;} + this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;} + for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} + for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} + for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} + this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} + var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} + this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} + row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);} + var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;} + if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. (" + +buffer.getLengthInBits() + +">" + +totalDataCount*8 + +")");} + if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} + while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} + while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} + buffer.put(QRCodeModel.PAD1,8);} + return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];} + offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}} + var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;} + var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}} + for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}} + return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} + return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} + return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} + return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));} + return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;} + for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;} + if(r==0&&c==0){continue;} + if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}} + if(sameCount>5){lostPoint+=(3+sameCount-5);}}} + for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}} + for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}} + for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}} + var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}} + var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");} + return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;} + while(n>=256){n-=255;} + return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;} + for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];} + for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;} + function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);} + var offset=0;while(offset<num.length&&num[offset]==0){offset++;} + this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}} + QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}} + return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;} + var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);} + for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);} + return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;} + QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);} + var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}} + return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;} + QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} + if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} + this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; + + function _isSupportCanvas() { + return typeof CanvasRenderingContext2D != "undefined"; + } + + // android 2.x doesn't support Data-URI spec + function _getAndroid() { + var android = false; + var sAgent = navigator.userAgent; + + if (/android/i.test(sAgent)) { // android + android = true; + var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); + + if (aMat && aMat[1]) { + android = parseFloat(aMat[1]); + } + } + + return android; + } + + var svgDrawer = (function() { + + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + + this.clear(); + + function makeSVG(tag, attrs) { + var el = document.createElementNS('http://www.w3.org/2000/svg', tag); + for (var k in attrs) + if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); + return el; + } + + var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); + svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); + _el.appendChild(svg); + + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); + svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + if (oQRCode.isDark(row, col)) { + var child = makeSVG("use", {"x": String(col), "y": String(row)}); + child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") + svg.appendChild(child); + } + } + } + }; + Drawing.prototype.clear = function () { + while (this._el.hasChildNodes()) + this._el.removeChild(this._el.lastChild); + }; + return Drawing; + })(); + + var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; + + // Drawing in DOM by using Table tag + var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { + var Drawing = function (el, htOption) { + this._el = el; + this._htOption = htOption; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _htOption = this._htOption; + var _el = this._el; + var nCount = oQRCode.getModuleCount(); + var nWidth = Math.floor(_htOption.width / nCount); + var nHeight = Math.floor(_htOption.height / nCount); + var aHTML = ['<table style="border:0;border-collapse:collapse;">']; + + for (var row = 0; row < nCount; row++) { + aHTML.push('<tr>'); + + for (var col = 0; col < nCount; col++) { + aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>'); + } + + aHTML.push('</tr>'); + } + + aHTML.push('</table>'); + _el.innerHTML = aHTML.join(''); + + // Fix the margin values as real size. + var elTable = _el.childNodes[0]; + var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; + var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; + + if (nLeftMarginTable > 0 && nTopMarginTable > 0) { + elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; + } + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._el.innerHTML = ''; + }; + + return Drawing; + })() : (function () { // Drawing in Canvas + function _onMakeImage() { + this._elImage.src = this._elCanvas.toDataURL("image/png"); + this._elImage.style.display = "block"; + this._elCanvas.style.display = "none"; + } + + // Android 2.1 bug workaround + // http://code.google.com/p/android/issues/detail?id=5141 + if (this._android && this._android <= 2.1) { + var factor = 1 / window.devicePixelRatio; + var drawImage = CanvasRenderingContext2D.prototype.drawImage; + CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { + if (("nodeName" in image) && /img/i.test(image.nodeName)) { + for (var i = arguments.length - 1; i >= 1; i--) { + arguments[i] = arguments[i] * factor; + } + } else if (typeof dw == "undefined") { + arguments[1] *= factor; + arguments[2] *= factor; + arguments[3] *= factor; + arguments[4] *= factor; + } + + drawImage.apply(this, arguments); + }; + } + + /** + * Check whether the user's browser supports Data URI or not + * + * @private + * @param {Function} fSuccess Occurs if it supports Data URI + * @param {Function} fFail Occurs if it doesn't support Data URI + */ + function _safeSetDataURI(fSuccess, fFail) { + var self = this; + self._fFail = fFail; + self._fSuccess = fSuccess; + + // Check it just once + if (self._bSupportDataURI === null) { + var el = document.createElement("img"); + var fOnError = function() { + self._bSupportDataURI = false; + + if (self._fFail) { + self._fFail.call(self); + } + }; + var fOnSuccess = function() { + self._bSupportDataURI = true; + + if (self._fSuccess) { + self._fSuccess.call(self); + } + }; + + el.onabort = fOnError; + el.onerror = fOnError; + el.onload = fOnSuccess; + el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. + return; + } else if (self._bSupportDataURI === true && self._fSuccess) { + self._fSuccess.call(self); + } else if (self._bSupportDataURI === false && self._fFail) { + self._fFail.call(self); + } + }; + + /** + * Drawing QRCode by using canvas + * + * @constructor + * @param {HTMLElement} el + * @param {Object} htOption QRCode Options + */ + var Drawing = function (el, htOption) { + this._bIsPainted = false; + this._android = _getAndroid(); + + this._htOption = htOption; + this._elCanvas = document.createElement("canvas"); + this._elCanvas.width = htOption.width; + this._elCanvas.height = htOption.height; + el.appendChild(this._elCanvas); + this._el = el; + this._oContext = this._elCanvas.getContext("2d"); + this._bIsPainted = false; + this._elImage = document.createElement("img"); + this._elImage.alt = "Scan me!"; + this._elImage.style.display = "none"; + this._el.appendChild(this._elImage); + this._bSupportDataURI = null; + }; + + /** + * Draw the QRCode + * + * @param {QRCode} oQRCode + */ + Drawing.prototype.draw = function (oQRCode) { + var _elImage = this._elImage; + var _oContext = this._oContext; + var _htOption = this._htOption; + + var nCount = oQRCode.getModuleCount(); + var nWidth = _htOption.width / nCount; + var nHeight = _htOption.height / nCount; + var nRoundedWidth = Math.round(nWidth); + var nRoundedHeight = Math.round(nHeight); + + _elImage.style.display = "none"; + this.clear(); + + for (var row = 0; row < nCount; row++) { + for (var col = 0; col < nCount; col++) { + var bIsDark = oQRCode.isDark(row, col); + var nLeft = col * nWidth; + var nTop = row * nHeight; + _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.lineWidth = 1; + _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; + _oContext.fillRect(nLeft, nTop, nWidth, nHeight); + + // 안티 앨리어싱 방지 처리 + _oContext.strokeRect( + Math.floor(nLeft) + 0.5, + Math.floor(nTop) + 0.5, + nRoundedWidth, + nRoundedHeight + ); + + _oContext.strokeRect( + Math.ceil(nLeft) - 0.5, + Math.ceil(nTop) - 0.5, + nRoundedWidth, + nRoundedHeight + ); + } + } + + this._bIsPainted = true; + }; + + /** + * Make the image from Canvas if the browser supports Data URI. + */ + Drawing.prototype.makeImage = function () { + if (this._bIsPainted) { + _safeSetDataURI.call(this, _onMakeImage); + } + }; + + /** + * Return whether the QRCode is painted or not + * + * @return {Boolean} + */ + Drawing.prototype.isPainted = function () { + return this._bIsPainted; + }; + + /** + * Clear the QRCode + */ + Drawing.prototype.clear = function () { + this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); + this._bIsPainted = false; + }; + + /** + * @private + * @param {Number} nNumber + */ + Drawing.prototype.round = function (nNumber) { + if (!nNumber) { + return nNumber; + } + + return Math.floor(nNumber * 1000) / 1000; + }; + + return Drawing; + })(); + + /** + * Get the type by string length + * + * @private + * @param {String} sText + * @param {Number} nCorrectLevel + * @return {Number} type + */ + function _getTypeNumber(sText, nCorrectLevel) { + var nType = 1; + var length = _getUTF8Length(sText); + + for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { + var nLimit = 0; + + switch (nCorrectLevel) { + case QRErrorCorrectLevel.L : + nLimit = QRCodeLimitLength[i][0]; + break; + case QRErrorCorrectLevel.M : + nLimit = QRCodeLimitLength[i][1]; + break; + case QRErrorCorrectLevel.Q : + nLimit = QRCodeLimitLength[i][2]; + break; + case QRErrorCorrectLevel.H : + nLimit = QRCodeLimitLength[i][3]; + break; + } + + if (length <= nLimit) { + break; + } else { + nType++; + } + } + + if (nType > QRCodeLimitLength.length) { + throw new Error("Too long data"); + } + + return nType; + } + + function _getUTF8Length(sText) { + var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); + return replacedText.length + (replacedText.length != sText ? 3 : 0); + } + + /** + * @class QRCode + * @constructor + * @example + * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); + * + * @example + * var oQRCode = new QRCode("test", { + * text : "http://naver.com", + * width : 128, + * height : 128 + * }); + * + * oQRCode.clear(); // Clear the QRCode. + * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. + * + * @param {HTMLElement|String} el target element or 'id' attribute of element. + * @param {Object|String} vOption + * @param {String} vOption.text QRCode link data + * @param {Number} [vOption.width=256] + * @param {Number} [vOption.height=256] + * @param {String} [vOption.colorDark="#000000"] + * @param {String} [vOption.colorLight="#ffffff"] + * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] + */ + QRCode = function (el, vOption) { + this._htOption = { + width : 256, + height : 256, + typeNumber : 4, + colorDark : "#000000", + colorLight : "#ffffff", + correctLevel : QRErrorCorrectLevel.H + }; + + if (typeof vOption === 'string') { + vOption = { + text : vOption + }; + } + + // Overwrites options + if (vOption) { + for (var i in vOption) { + this._htOption[i] = vOption[i]; + } + } + + if (typeof el == "string") { + el = document.getElementById(el); + } + + if (this._htOption.useSVG) { + Drawing = svgDrawer; + } + + this._android = _getAndroid(); + this._el = el; + this._oQRCode = null; + this._oDrawing = new Drawing(this._el, this._htOption); + + if (this._htOption.text) { + this.makeCode(this._htOption.text); + } + }; + + /** + * Make the QRCode + * + * @param {String} sText link data + */ + QRCode.prototype.makeCode = function (sText) { + this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); + this._oQRCode.addData(sText); + this._oQRCode.make(); + this._el.title = sText; + this._oDrawing.draw(this._oQRCode); + this.makeImage(); + }; + + /** + * Make the Image from Canvas element + * - It occurs automatically + * - Android below 3 doesn't support Data-URI spec. + * + * @private + */ + QRCode.prototype.makeImage = function () { + if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { + this._oDrawing.makeImage(); + } + }; + + /** + * Clear the QRCode + */ + QRCode.prototype.clear = function () { + this._oDrawing.clear(); + }; + + /** + * @name QRCode.CorrectLevel + */ + QRCode.CorrectLevel = QRErrorCorrectLevel; +})(); diff --git a/static/app2/js/qrrz.js b/static/app2/js/qrrz.js new file mode 100755 index 0000000..a2ecb39 --- /dev/null +++ b/static/app2/js/qrrz.js @@ -0,0 +1,114 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + //获取亲人认证列表 + var page = 1; + var pageSize = 10; + var isjiazai = 1; + getRecommend(page, pageSize); + + function getRecommend(page, pageSize) { + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/auth/getAuthFamilyPersonalSelect'), recommenddata, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + if (data.status == 1) { + var html = ''; + var data = data.data; + if ('' == data.Rows) { + $('.mui-scroll').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="block clearfix"><p class="pname">' + this.familyName + + '(' + this.familyRelations + + ')</p><div class="caozuo"><span class="bj" data-id="' + this.id + + '"><img src="../img/bianji.png"></span><span class="del" data-id="' + this.id + + '"><img src="../img/delete.png"></span></div></div>'; + // //console.log(this.id); + + + }) + if (page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + } else { + + } + isjiazai = 1; + }) + } + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pageSize); + } + } + }) + var qrrzid; + // 编辑 + mui('.con').on('tap', '.bj', function() { + + qrrzid = $(this).attr('data-id'); + //console.log(qrrzid); + JZL.openWindow('addqrrz.html', qrrzid); + }) + // 删除 + $('.con').on('tap', '.del', function() { + qrrzid = $(this).attr('data-id'); + if (confirm('确认删除?')) { + var lxy_div = + '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"> <div class="lxy_zz clearfix"><h3>请输入操作密码</h3><div style="background:linear-gradient(to right,#48D1CC,#FFD700,#D2691E);height:2px; margin:10px auto"></div><input class="payword" type="password" placeholder="请输入操作密码"><div class="lxy_zz_btn"><button class="cancle" type="button">取消</button><button class="sure" type="button">确定</button></div></div></div>'; + $('body').append(lxy_div); + $('.lxy_zz').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + }) + mui('.lxy_zz_btn').on('tap', '.cancle', function() { + $('#home_zhezhao').remove(); + return; + }) + + mui('.lxy_zz_btn').on('tap', '.sure', function() { + var payPwd = $('.payword').val(); + if (payPwd == '') { + mui.alert("请输入密码") + } + JZL.ajax(qlgUrl('app/auth/delAuthFamily'), { + id: qrrzid, + payPwd: payPwd + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + + if (data.status == 1) { + $('#home_zhezhao').remove(); + location.reload() + } + }) + + }) + } + }) + $('.add1').on('tap', function() { + JZL.openWindow('addqrrz.html', 'addqrrz.html'); + + }) + + + + +}) diff --git a/static/app2/js/recommend.js b/static/app2/js/recommend.js new file mode 100755 index 0000000..6df2458 --- /dev/null +++ b/static/app2/js/recommend.js @@ -0,0 +1,45 @@ +mui.plusReady(function() { + + //跳转到商品详情 + mui("body").on('tap', '.recommend_con_block', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-goodsId"].nodeValue; + var goodsType =$(this).attr('data-goodsType') + // //console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + goodsType : goodsType?goodsType :"" + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/reg.js b/static/app2/js/reg.js new file mode 100755 index 0000000..aebde9f --- /dev/null +++ b/static/app2/js/reg.js @@ -0,0 +1,499 @@ +// mui.init({ +// beforeback: function() { //获得父页面的webview +// var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 +// mui.fire(list, 'refresh'); +// //返回true,继续页面关闭逻辑 +// return true; +// } +// }); + +mui.plusReady(function() { + + var wait = 120; + + // 判断用户名是否存在 + $('#loginName').on('blur', function() { + var loginName = $('#loginName').val(); + JZL.ajax('http://t.ect99.com/app/users/check_login_name', { + loginName: loginName + }, function(data) { + // console.log(data); + if (1 != data.status) { + mui.alert(data.msg) + } + }) + }) + + function GetQueryString(name) { + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + console.log(reg); + var r = window.location.search.substr(1).match(reg); + if (r != null) + return unescape(r[2]); + return null; + } + + var pName = GetQueryString('pName') ? GetQueryString('pName') : localStorage.getItem('pName'); + +// if (!pName) { +// pName = localStorage.getItem('pName'); +// var indexNum = pName.indexOf('&'); +// if (indexNum > 0) { +// pName = pName.slice(0, indexNum); +// } +// } +// + if (pName) { + console.log(pName); +// $('#pName').val(pname);; +// $('#pName').attr('disabled', 'disabled'); + } + // 推荐人信息 + //var PName = ""; + $('#pName').on('blur', function() { + pName = $('#pName').val(); + if ('' != pName) { + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pName))) { + mui.alert("手机号码有误,请重填!"); + return; + } + $('.pNameCode').show(); + + mui('.row').on('tap', '#mobileCode1', function() { + $(this).attr("disabled", true); + JZL.ajax('http://t.ect99.com/app/users/getPhoneVerifyCode', { + userPhone: pName + }, function(data) { + if (1 == data.status) { + time() + } else { + mui.alert(data.msg); + } + $('#mobileCode1').removeAttr('disabled'); + + }) + }) + + + + } else { + $('.pNameCode').hide(); + } + + }) + // JZL.ajax(qlgUrl('app/users/check_login_name'),{loginName:loginName},function (data) { + // // console.log(data); + // + // if (1 != data.status) { + // mui.alert(data.msg) + // } + // }) + function time() { + if (wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + //获取验证码 + mui('.row').on('tap', '#mobileCode', function() { + var loginName = $('#loginName').val(); + if (loginName == '') { + mui.alert('手机号不能为空!'); + return; + } + // if (!( + // /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + // .test(loginName))) { + // mui.alert("手机号码有误,请重填!"); + // return; + // } + $(this).attr("disabled", true); + mui.ajax('http://t.ect99.com/app/users/getPhoneVerifyCode', { + + data: { + userPhone: loginName + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + console.log(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + time(); + } else { + mui.alert(data.msg); + } + $('#mobileCode').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + mui.alert(type) + // mui.alert(type); + } + }); + }) + //注册协议 + mui.ajax('http://t.ect99.com/app/Tags/articleDetail', { + data: { + articleId: 114 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { + console.log(data); + // if(data.status==1){ + // console.log(1); + var html1 = '' + html1 = '<h3>' + data.articleContent + '</h3>' + $('.zcxycontent').append(html1) + // } + }, + error: function(xhr, type, errorThrown) { + + } + }); + //上传图片 + + var files = []; //存储文件信息的数组 + var fname = ""; //表示文件名,例如 XXXX.jpg; + var expire = 0; + var pathName = ''; + var inpId = ''; + var keyname = ''; + var imgId = ''; + var isZip = 1; + var qualityNum = 90; + var response = ';' + var UP = UP || {}; + UP.isBatch = 0; + UP.init = function(inputId, path, imageId, isBatch, isZipImg, quality) { + inpId = inputId; + pathName = path; + imgId = imageId; + if (typeof(isBatch) != 'undefined') { + UP.isBatch = isBatch; + } + if (typeof(isZipImg) != 'undefined') { + // console.log(typeof(isZipImg)); + isZip = isZipImg; + } + if (typeof(quality) != 'undefined') { + qualityNum = quality; + } + + } + + function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + // console.log(dir) + serverUrl = 'http://t.ect99.com/oss/get.php?dir=' + pathName; + // serverUrl = 'https://img.zgqlg.com.cn/oss/get.php?dir=' + pathName; + + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText; + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + + } + + function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + response = obj; + // console.log(obj); + } + return response; + }; + // 上传文件 + function upload(callback) { + // console.log(files); + if (files.length <= 0) { + mui.toast('没有添加上传文件'); + return; + } + var obj = get_signature(); + if (obj) { + server = obj['host']; + policyBase64 = obj['policy']; + accessid = obj['accessid']; + signature = obj['signature']; + expire = parseInt(obj['expire']); + callbackbody = obj['callback']; + path = obj['dir']; + + } else { + mui.toast('初始化失败'); + return; + } + + var wt = plus.nativeUI.showWaiting(); + var task = plus.uploader.createUpload(server, { + method: "POST" + }, function(t, status) { + //上传完成 + if (status == 200) { + wt.close(); + if (1 == UP.isBatch) { + callback(t, status, keyname, server + '/' + keyname); + } else { + document.getElementById(inpId).value = keyname; + var ele = document.getElementById(imgId); + ele.src = server + '/' + keyname; + ele.setAttribute('data-src', keyname); + mui.toast('上传成功'); + //至此上传成功,上传后的图片完整地址为server+testName + //keyname + } + + } else { + wt.close(); + mui.toast('上传失败:' + status); + } + }); + var suffix1 = get_suffix(fname); //文件后缀 例如 .jpg + keyname = path + new Date().getTime() + suffix1; + task.addData("key", keyname); + task.addData("policy", policyBase64); + task.addData("OSSAccessKeyId", accessid); + task.addData("success_action_status", "200"); + // task.addData("callback", callbackbody); + task.addData("signature", signature); + var f = files[files.length - 1]; + // console.log(f) + + task.addFile(f.path, { + key: "file", + name: "file", + mime: "image/jpeg" + }); + //files.length = 0; + task.start(); + + } + + //得到文件名的后缀 + function get_suffix(filename) { + var pos = filename.lastIndexOf('.'); + var suffix = ''; + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; + } + // 拍照添加文件 + function appendByCamera(callback) { + plus.camera.getCamera().captureImage(function(p) { + uploadImg(p, callback); + }); + } + // 从相册添加文件 + function appendByGallery(callback) { + plus.gallery.pick(function(p) { + uploadImg(p, callback); + }); + } + + // 添加文件 + var index = 1; + + function uploadImg(p, callback) { + if (1 == isZip) { + compressImg(p, callback); + } else { + appendFile(p, callback) + } + } + + function appendFile(p, callback) { + // var fe = document.getElementById(fileId); + var n = p.substr(p.lastIndexOf('/') + 1); + // fname = n/////////; + files.push({ + name: "uploadkey" + index, + path: p + }); + //console.log(3); + // index++; + upload(callback); + } + + function compressImg(src, callback) { + var filename = src.substring(src.lastIndexOf('/') + 1); + var opions = { + src: src, + dst: '_doc/tmp/' + filename, + overwrite: true, + //width: '300px', //这里指定了宽度,同样可以修改 + format: 'jpg', + quality: qualityNum //图片质量不再修改,以免失真 + }; + var successCB = function(evt) { + // console.log(JSON.stringify(evt)); + fname = filename; + // files[0]={ + // name: "uploadkey", + // path: evt.target + // }; + files.push({ + name: "uploadkey" + index, + path: evt.target + }); + // index++; + //上传 + upload(callback); + //_this.avatar(evt.target); + }; + var errorCB = function(err) { + appendFile(src, callback); + + //console.log(JSON.stringify(err)); + //mui.toast("图片压缩失败");i m + }; + plus.zip.compressImage(opions, successCB, errorCB); + }; + + function openCamera(callback) { + plus.nativeUI.actionSheet({ + cancel: "取消", + buttons: [{ + title: "拍照" + }, + { + title: "从相册中选择" + } + ] + }, function(e) { //1 是拍照 2 从相册中选择 + switch (e.index) { + case 1: + appendByCamera(callback); + break; + case 2: + appendByGallery(callback); + break; + } + }); + } + $(".photos").on("tap", '.regConfirm', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("regConfirmImg", "test", "regConfirmImg") + openCamera() + }) + + + mui('.down').on('tap', '.btn', function() { + var loginName = $('#loginName').val(); + var mobileCode = $('.yzm').val(); + var loginPwd = $('#loginPwd').val(); + var reUserPwd = $('#reUserPwd').val(); + var mobileCode1 = $('#mobileCode1').val() ? $('#mobileCode1').val() : ""; //推荐人验证码 + + + pName = $('#pName').val(); + + // var verifyCode = $('.tpyzm').val(); + var regConfirmImg = $('#regConfirmImg').val(); + if (loginName == '') { + mui.alert('手机号不能为空!'); + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(loginName))) { + mui.alert("手机号码有误,请重填!"); + return; + } + if (mobileCode == '') { + mui.alert('验证码不能为空!'); + return; + } + if (loginPwd == '') { + mui.alert('密码不能为空!'); + return; + } + if (reUserPwd == '') { + mui.alert('确认密码不能为空!'); + return; + } + if (loginPwd.length < 6) { + mui.alert('密码不能小于6位!'); + return; + } + if (!(loginPwd == reUserPwd)) { + mui.alert('两次密码不一致!'); + return; + } + if (regConfirmImg == '') { + mui.alert('请上传确认书照片'); + return; + } + if (pName != '') { + if ('' == mobileCode1) { + mui.alert('请输入推荐人验证码'); + return; + } + } + $(this).attr("disabled", true); + mui.ajax('http://t.ect99.com/app/users/register', { + data: { + loginName: loginName, + mobileCode: mobileCode, + loginPwd: loginPwd, + reUserPwd: reUserPwd, + pName: pName, + nameType: 3, + regConfirmImg: regConfirmImg, + mobileCode1: mobileCode1 + // verifyCode: verifyCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + mui.alert(data.msg); + + if (data.status == 1) { + // mui.back(); + plus.runtime.open + } else { + // $('.yzmhh').attr('src', hyhUrl('mobile/users/getverify?rnd=' + Math.random())); + } + $('.btn').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }) + +}) diff --git a/static/app2/js/register.js b/static/app2/js/register.js new file mode 100755 index 0000000..4a872fe --- /dev/null +++ b/static/app2/js/register.js @@ -0,0 +1,201 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + } +}); + +mui.plusReady(function() { + var wait = 120; + // var html = + // '<div class="row"><img src="../img/icon_pwd1.png" /><span class="s1">验证码:</span><input class="tpyzm" type="text" maxlength="4" placeholder="请输入图片验证码" /><img class="yzmhh" src = "'+ hyhUrl('mobile/users/getverify?rnd='+Math.random())+'"/></input></div>'; + // + // $('.con').append(html); + // 判断用户名是否存在 + $('#loginName').on('blur', function() { + var loginName = $('#loginName').val(); + if ('' == loginName) { + mui.mui.alert('用户名不能为空') + return; + } + if (6 > loginName.length) { + mui.alert('用户名不能小于6个字符') + return; + } + JZL.ajax(qlgUrl('app/users/check_login_name'), { + loginName: loginName + }, function(data) { + // //console.log(data); + if (1 != data.status) { + mui.alert(data.msg) + } + }) + }) + // 推荐人信息 + $('.pNameCode').hide(); + + var PName = ""; + $('#pName').on('blur', function() { + pName = $('#pName').val(); + if ('' != pName) { + + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pName))) { + mui.alert("手机号码有误,请重填!"); + return; + } + $('.pNameCode').show(); + mui('.row').on('tap', '#getMobileCode', function() { + var that=$(this) + that.attr("disabled", true); + JZL.ajax(qlgUrl('app/users/getPhoneVerifyCode'), { + userPhone: pName + }, function(data) { + if (1 == data.status) { + time() + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + + }) + }) + + + + } else { + $('.pNameCode').hide(); + } + + }) + + function time() { + if (wait == 0) { + $('#getMobileCode').removeAttr("disabled"); + $('#getMobileCode').val("重新发送"); + wait = 120; + } else { + $('#getMobileCode').attr("disabled", true); + $('#getMobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + + //注册协议 + mui.ajax(qlgUrl('app/Tags/articleDetail'), { + data: { + articleId: 114 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { + //console.log(data); + // if(data.status==1){ + // //console.log(1); + + $('.zcxycontent').html(data.articleContent) + // } + }, + error: function(xhr, type, errorThrown) { + + } + }); + //上传图片 + $(".photos").on("tap", '.regConfirm', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("regConfirmImg", "test", "regConfirm") + openCamera() + }) + + + mui('.down').on('tap', '.btn', function() { + var loginName = $('#loginName').val(); + // var mobileCode = $('.yzm').val(); + var loginPwd = $('#loginPwd').val(); + var reUserPwd = $('#reUserPwd').val(); + var mobileCode = $('#mobileCode').val() ? $('#mobileCode').val() : ""; //推荐人验证码 + var payPwd = $('#loginPaywd').val(); + var reUserPaywd = $('#reUserPaywd').val(); + var pName = $('#pName').val(); + + // var verifyCode = $('.tpyzm').val(); + var regConfirmImg = $('#regConfirmImg').val(); + if (loginName == '') { + mui.alert('用户名不能为空!'); + return; + } + if (loginPwd.length < 6) { + mui.alert('登录密码不能小于6位!'); + return; + } + if (!(loginPwd == reUserPwd)) { + mui.alert('两次登录密码不一致!'); + return; + } + if (payPwd.length < 6) { + mui.alert('操作密码不能小于6位!'); + return; + } + if (payPwd != reUserPaywd) { + mui.alert('两次操作密码不一致!'); + return; + } + if (regConfirmImg == '') { + mui.alert('请上传确认书照片'); + return; + } + if (pName != '') { + if ('' == mobileCode) { + mui.alert('请输入推荐人验证码'); + return; + } + } + var ajaxData={ + loginName: loginName, + // mobileCode: mobileCode, + loginPwd: loginPwd, + payPwd: payPwd, + pName: pName, + // nameType: 3, + regConfirmImg: regConfirmImg, + mobileCode: mobileCode + }; + + var that = $(this) + that.attr("disabled", true); + + mui.ajax(qlgUrl('app/users/register'), { + data:ajaxData, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + mui.alert(data.msg); + + if (data.status == 1) { + mui.back(); + } else { + // $('.yzmhh').attr('src', hyhUrl('mobile/users/getverify?rnd=' + Math.random())); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }) + +}) diff --git a/static/app2/js/register1.js b/static/app2/js/register1.js new file mode 100755 index 0000000..ed290d6 --- /dev/null +++ b/static/app2/js/register1.js @@ -0,0 +1,471 @@ +// mui.init({ +// beforeback: function() { //获得父页面的webview +// var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 +// mui.fire(list, 'refresh'); +// //返回true,继续页面关闭逻辑 +// return true; +// } +// }); + +mui.plusReady(function() { + var wait = 120; + // var html = + // '<div class="row"><img src="../img/icon_pwd1.png" /><span class="s1">验证码:</span><input class="tpyzm" type="text" maxlength="4" placeholder="请输入图片验证码" /><img class="yzmhh" src = "'+ hyhUrl('mobile/users/getverify?rnd='+Math.random())+'"/></input></div>'; + // + // $('.con').append(html); + // 判断手机号是否存在 格式是否正确 + $('#loginName').on('blur', function() { + var loginName = $('#loginName').val(); + JZL.ajax('http://t.ect99.com/app/users/check_login_name', { + loginName: loginName + }, function(data) { + // //console.log(data); + if (1 != data.status) { + mui.alert(data.msg) + } + }) + }) + // 推荐人信息 + $('.pNameCode').hide(); + + var PName=""; + $('#pName').on('blur', function() { + pName = $('#pName').val(); + if ('' != pName) { + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(pName))) { + mui.alert("手机号码有误,请重填!"); + return; + } + $('.pNameCode').show(); + + mui('.row').on('tap', '#mobileCode1', function() { + $(this).attr("disabled", true); + JZL.ajax('http://t.ect99.com/app/users/getPhoneVerifyCode',{userPhone:pName},function (data) { + if (1==data.status) { + time() + }else { + mui.alert(data.msg); + } + $('#mobileCode1').removeAttr('disabled'); + + }) +}) + + + + } else { + $('.pNameCode').hide(); + } + + }) +// JZL.ajax(qlgUrl('app/users/check_login_name'),{loginName:loginName},function (data) { +// // //console.log(data); +// +// if (1 != data.status) { +// mui.alert(data.msg) +// } +// }) + function time() { + if (wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time() + }, + 1000) + } + } + //获取验证码 + mui('.row').on('tap', '#mobileCode', function() { + var loginName = $('#loginName').val(); + if (loginName == '') { + mui.alert('手机号不能为空!'); + return; + } + // if (!( + // /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + // .test(loginName))) { + // mui.alert("手机号码有误,请重填!"); + // return; + // } + $(this).attr("disabled", true); + mui.ajax('http://t.ect99.com/app/users/getPhoneVerifyCode', { + + data: { + userPhone: loginName + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //console.log(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + time(); + } else { + mui.alert(data.msg); + } + $('#mobileCode').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + mui.alert(type) + // mui.alert(type); + } + }); + }) + //注册协议 + mui.ajax('http://t.ect99.com/app/Tags/articleDetail', { + data: { + articleId: 114 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { + //console.log(data); + // if(data.status==1){ + // //console.log(1); + var html1 = '' + html1 = '<h3>' + data.articleContent + '</h3>' + $('.zcxycontent').append(html1) + // } + }, + error: function(xhr, type, errorThrown) { + + } + }); + //上传图片 + + var files = []; //存储文件信息的数组 + var fname = ""; //表示文件名,例如 XXXX.jpg; + var expire = 0; + var pathName = ''; + var inpId = ''; + var keyname = ''; + var imgId=''; + var isZip=1; + var qualityNum=90; + var response=';' + var UP = UP || {}; + UP.isBatch=0; + UP.init = function(inputId, path,imageId,isBatch,isZipImg,quality) { + inpId = inputId; + pathName = path; + imgId = imageId; + if(typeof(isBatch) != 'undefined'){ + UP.isBatch = isBatch; + } + if(typeof(isZipImg) != 'undefined'){ + // //console.log(typeof(isZipImg)); + isZip = isZipImg; + } + if(typeof(quality) != 'undefined'){ + qualityNum = quality; + } + + } + + function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + // //console.log(dir) + serverUrl = 'http://t.ect99.com/oss/get.php?dir=' + pathName; + // serverUrl = 'https://img.zgqlg.com.cn/oss/get.php?dir=' + pathName; + + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText; + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + + } + + function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + response = obj; + // //console.log(obj); + } + return response; + }; + // 上传文件 + function upload(callback) { + // //console.log(files); + if (files.length <= 0) { + mui.toast('没有添加上传文件'); + return; + } + var obj = get_signature(); + if (obj) { + server = obj['host']; + policyBase64 = obj['policy']; + accessid = obj['accessid']; + signature = obj['signature']; + expire = parseInt(obj['expire']); + callbackbody = obj['callback']; + path = obj['dir']; + + } else { + mui.toast('初始化失败'); + return; + } + + var wt = plus.nativeUI.showWaiting(); + var task = plus.uploader.createUpload(server, { + method: "POST" + }, function(t, status) { + //上传完成 + if (status == 200) { + wt.close(); + if(1 == UP.isBatch){ + callback(t,status,keyname,server + '/'+keyname); + }else{ + document.getElementById(inpId).value = keyname; + var ele=document.getElementById(imgId); + ele.src=server + '/'+keyname; + ele.setAttribute('data-src',keyname); + mui.toast('上传成功'); + //至此上传成功,上传后的图片完整地址为server+testName + //keyname + } + + } else { + wt.close(); + mui.toast('上传失败:' + status); + } + }); + var suffix1 = get_suffix(fname); //文件后缀 例如 .jpg + keyname = path + new Date().getTime() + suffix1; + task.addData("key", keyname); + task.addData("policy", policyBase64); + task.addData("OSSAccessKeyId", accessid); + task.addData("success_action_status", "200"); + // task.addData("callback", callbackbody); + task.addData("signature", signature); + var f = files[files.length-1]; + // //console.log(f) + + task.addFile(f.path, { + key: "file", + name: "file", + mime: "image/jpeg" + }); + //files.length = 0; + task.start(); + + } + + //得到文件名的后缀 + function get_suffix(filename) { + var pos = filename.lastIndexOf('.'); + var suffix = ''; + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; + } + // 拍照添加文件 + function appendByCamera(callback) { + plus.camera.getCamera().captureImage(function(p) { + uploadImg(p,callback); + }); + } + // 从相册添加文件 + function appendByGallery(callback) { + plus.gallery.pick(function(p) { + uploadImg(p,callback); + }); + } + + // 添加文件 + var index = 1; + function uploadImg(p,callback){ + if(1 == isZip){ + compressImg(p,callback); + }else{ + appendFile(p,callback) + } + } + function appendFile(p,callback) { + // var fe = document.getElementById(fileId); + var n = p.substr(p.lastIndexOf('/') + 1); + fname = n; + files.push({ + name: "uploadkey" + index, + path: p + }); + ////console.log(3); + // index++; + upload(callback); + } + function compressImg(src,callback) { + var filename = src.substring(src.lastIndexOf('/') + 1); + var opions = { + src: src, + dst: '_doc/tmp/' + filename, + overwrite: true, + //width: '300px', //这里指定了宽度,同样可以修改 + format: 'jpg', + quality: qualityNum //图片质量不再修改,以免失真 + }; + var successCB = function(evt) { + // //console.log(JSON.stringify(evt)); + fname = filename; + // files[0]={ + // name: "uploadkey", + // path: evt.target + // }; + files.push({ + name: "uploadkey" + index, + path: evt.target + }); + // index++; + //上传 + upload(callback); + //_this.avatar(evt.target); + }; + var errorCB = function(err) { + appendFile(src,callback); + ////console.log(JSON.stringify(err)); + //mui.toast("图片压缩失败"); + }; + plus.zip.compressImage(opions, successCB, errorCB); + }; + function openCamera(callback) { + plus.nativeUI.actionSheet({ + cancel: "取消", + buttons: [{ + title: "拍照" + }, + { + title: "从相册中选择" + } + ] + }, function(e) { //1 是拍照 2 从相册中选择 + switch (e.index) { + case 1: + appendByCamera(callback); + break; + case 2: + appendByGallery(callback); + break; + } + }); + } + $(".photos").on("tap", '.regConfirm', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("regConfirmImg", "test", "regConfirmImg") + openCamera() + }) + + + mui('.down').on('tap', '.btn', function() { + var loginName = $('#loginName').val(); + var mobileCode = $('.yzm').val(); + var loginPwd = $('#loginPwd').val(); + var reUserPwd = $('#reUserPwd').val(); + var mobileCode1 = $('#mobileCode1').val() ? $('#mobileCode1').val() : "";//推荐人验证码 + + + pName = $('#pName').val(); + + // var verifyCode = $('.tpyzm').val(); + var regConfirmImg = $('#regConfirmImg').val(); + if (loginName == '') { + mui.alert('手机号不能为空!'); + return; + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(loginName))) { + mui.alert("手机号码有误,请重填!"); + return; + } + if (mobileCode == '') { + mui.alert('验证码不能为空!'); + return; + } + if (loginPwd == '') { + mui.alert('密码不能为空!'); + return; + } + if (reUserPwd == '') { + mui.alert('确认密码不能为空!'); + return; + } + if (loginPwd.length < 6) { + mui.alert('密码不能小于6位!'); + return; + } + if (!(loginPwd == reUserPwd)) { + mui.alert('两次密码不一致!'); + return; + } + if (regConfirmImg == '') { + mui.alert('请上传确认书照片'); + return; + } + if (pName != '') { + if(''==mobileCode1){ + mui.alert('请输入推荐人验证码'); + return; + } + } + $(this).attr("disabled", true); + mui.ajax('http://t.ect99.com/app/users/register', { + data: { + loginName: loginName, + mobileCode: mobileCode, + loginPwd: loginPwd, + reUserPwd: reUserPwd, + pName: pName, + nameType: 3, + regConfirmImg: regConfirmImg, + mobileCode1:mobileCode1 + // verifyCode: verifyCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + mui.alert(data.msg); + + if (data.status == 1) { + // mui.back(); + plus.runtime.open + } else { + // $('.yzmhh').attr('src', hyhUrl('mobile/users/getverify?rnd=' + Math.random())); + } + $('.btn').removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type); + } + }); + + }) + +}) diff --git a/static/app2/js/reviewsmanage.js b/static/app2/js/reviewsmanage.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/rul.js b/static/app2/js/rul.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/saoyisao.js b/static/app2/js/saoyisao.js new file mode 100755 index 0000000..9ca22d2 --- /dev/null +++ b/static/app2/js/saoyisao.js @@ -0,0 +1,77 @@ +scan = null; //扫描对象 + mui.plusReady(function() { + mui.init(); + startRecognize(); + }); + + function startRecognize() { + try { + var filter; + //自定义的扫描控件样式 + var styles = { + frameColor: "#29E52C", + scanbarColor: "#29E52C", + background: "" + } + //扫描控件构造 + scan = new plus.barcode.Barcode('bcid', filter, styles); + scan.onmarked = onmarked; + scan.onerror = onerror; + scan.start(); + //打开关闭闪光灯处理 + var flag = false; + document.getElementById("turnTheLight").addEventListener('tap', function() { + if(flag == false) { + scan.setFlash(true); + flag = true; + } else { + scan.setFlash(false); + flag = false; + } + }); + } catch(e) { + mui.alert("出现错误啦:\n" + e); + } + }; + + function onerror(e) { + mui.alert(e); + }; + + function onmarked(type, result) { + var text = ''; + switch(type) { + case plus.barcode.QR: + text = 'QR: '; + break; + case plus.barcode.EAN13: + text = '条码: '; + break; + case plus.barcode.EAN8: + text = '条码: '; + break; + } + + if('http' == result.substring(0,4)){ + console.log(result); + plus.runtime.openURL(result); + }else{ + mui.alert(text + " : " + result); + } + + scan.cancel(); + scan.close(); +// scanDoit(result) + + }; + + // 从相册中选择二维码图片 + function scanPicture() { + plus.gallery.pick(function(path) { + plus.barcode.scan(path, onmarked, function(error) { + plus.nativeUI.alert("无法识别此图片"); + }); + }, function(err) { + plus.nativeUI.alert("Failed: " + err.message); + }); + } \ No newline at end of file diff --git a/static/app2/js/scrollToTop.js b/static/app2/js/scrollToTop.js new file mode 100755 index 0000000..2cc0c1f --- /dev/null +++ b/static/app2/js/scrollToTop.js @@ -0,0 +1,14 @@ +$('body').append('<a id="scrollToTop" class="backTop hide"> <span class="mui-icon mui-icon-arrowup"></span> </a>') + + +$('body').on('tap', '#scrollToTop', function() { + mui('.mui-scroll-wrapper').scroll().scrollTo(0, 0, 100); //滚动到顶部 +}) +document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y <= window.innerHeight * (-1)) { + $('#scrollToTop').removeClass('hide'); + + } else { + $('#scrollToTop').addClass('hide'); + } +}) \ No newline at end of file diff --git a/static/app2/js/self_shop.js b/static/app2/js/self_shop.js new file mode 100755 index 0000000..b1fd8f0 --- /dev/null +++ b/static/app2/js/self_shop.js @@ -0,0 +1,327 @@ +$('.getquan').css('display', 'none'); +// $('#search').css('width', '80%'); +$('.saoyisao').hide(); +$('.class_block').eq(0).attr('data-classifyId', 5); +$('.class_block').eq(1).attr('data-classifyId', 6); +$('.class_block').eq(2).attr('data-classifyId', 7); +$('.class_block').eq(3).attr('data-classifyId', 8); +$('.class_block').eq(4).attr('data-classifyId', ''); +$('.zya_block').addClass('add_'); +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + }, +}); +var data = ''; +var addr = ''; +var lat = '', + lat1 = '', + lng = ''; +var page = 1; +var pageSize = 5; +var count = 1; +var isjiazai = 1; +var nowPage = 1; +var isLoading = false; +mui.plusReady(function() { + getLocation(); + function getLocation() { + if (navigator.geolocation) { + plus.geolocation.getCurrentPosition(showPosition, showError); + + } else { + mui.alert("手机不支持定位") + } + } + function showPosition(position) { + + lat = position.coords.latitude; + lng = position.coords.longitude; + localStorage.setItem('lat', lat); + localStorage.setItem('lng', lng); + getShopList(nowPage, pageSize); + addr = position.address.city; + localStorage.setItem('addr', addr); + $('#location').html(addr); + $('#location-r').html(addr); + + } + + function showError(error) { + switch (error.code) { + case error.TIMEOUT: + mui.alert('请求超时,请重试') + break; + case error.POSITION_UNAVAILABLE: + mui.alert('定位不到你的地址') + break; + case error.PERMISSION_DENIED: + // case 22: + mui.alert('您拒绝了地理位置请求') + break; + case error.UNKNOWN_ERROR: + mui.alert('未知错误') + break; + default: + mui.alert(error.message) + break; + } + getShopList(nowPage, pageSize); + } + //bannerTop + mui.ajax(qlgUrl('app/shopping/getCarousel'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide add_" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + + '"><img src="' + hyhImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + var topBannerheight = localStorage.getItem('topBannerheight') + + $('#top_banner').height(topBannerheight) + // $('#top_banner').height(($('#top_banner').width() )* 460 / 750); + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + + mui('.con').on('tap', '.bc_img', function() { + var goodsId = $(this).attr('data-goodsId'); + JZL.openWindow('details.html', 'details.html' + goodsId, {data_id: goodsId}); + }) + function getShopList(nowPage, pageSize) { + + lat = localStorage.getItem('lat'); + lng = localStorage.getItem('lng'); + + if (null == lat) { + lat = 36.659565; + lng = 117.125824; + } + var recommenddata = { + shopType: 1, + page: nowPage ? nowPage : 1, + perPage: pageSize ? pageSize : 10, + lat: lat, + lng: lng + } + if (true == isLoading) return; + isLoading = true; + //console.log(lat); + JZL.ajax(hyhUrl('app/shopping/getShops'), recommenddata, function(data) { + + var html = ''; + if (1 == data.status) { + var data = data.data; + // console.log(data); + if ('' == data.Rows) { + $('.shoplist').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + // isLoading = false; + return; + } + $.each(data.Rows, function(index, element) { + html += + '<div class="con shadown_wai" data-shopId="' + this.shopId + + '"><div class="shops-content1-title" data-shopId="' + this.shopId + + '" data-shopName="'+this.shopName +'" ><span class="logoimg"><img src="' + hyhImgUrl(this.shopImg) + + '"alt=""></span><span class="shop-name">' + + this.shopName + '</span><span class="gogogo">进店逛逛</span></div><div class="t_con">' + if (0 != this.goods.length) { + $.each(this.goods, function(idx, ele) { + + html += '<div class="t_con_ bc_img" data-goodsId="' + this.goodsId + + '"><div class="t_con_img"><img src="' + hyhImgUrl(this.goodsImg) + '" data-goodsId="' + this.goodsId + + '" alt=""></div><span>¥' + this.shopPrice + '</span></div>' + }) + } + + html += '</div><div class="pos clearfix"><img src="../img/dingwei1.png"><span>距离:' + this.distance / 1000 + + '公里</span></div></div>' + }) + if (nowPage == 1) { + $('.shoplist').html(html); + } else { + $('.shoplist').append(html); + } + isLoading = false; + } else { + mui.alert(data.msg) + } + }) + } + //加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isLoading == false) { + nowPage++; + // getShops(nowPage, pageSize); + getShopList(nowPage, pageSize) + } + } + }) + mui('.shoplist').on('tap', '.shops-content1-title', function() { + // var goodsId = $(this).attr('data-goodsId'); + var shopName = $(this).attr("data-shopName"); + var shopId = $(this).attr("data-shopId"); + JZL.openWindow('storeout.html', 'storeout.html', {shopName: shopName,shopId: shopId}); + }) +}) + +//获取推荐页 +function getRecommend(page, pagesize) { + var recommenddata = { + type:1, + page: page ? page : 1, + pagesize: pageSize ? pageSize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shopping/getGoods'), recommenddata, function(data) { + // console.log(data); + // if (data.status == 1) { + var html = ''; + // var data = data.data; + if (data.Rows == '') { + $('.self_shop_rem').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:inline-block;" data-shopId="' + + this.shopId + '"></span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;' + this.discountRate + + '</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (page == 1) { + $('.recommend_con').html(html); + } else { + $('.recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + + // } else { + // mui.alert(data.msg) + // } + }) +} +$('.bcon_left').height($('.bcon_left').width() * 345 / 185); +$('.bcon_left img').height($('.bcon_left img').width() * 345 / 185); +$('.bcr_block').height($('.bcr_block').width()); +$('.addsct_block').height($('.addsct_block').width() * 225 / 355); +$('.addscb_block').height($('.addscb_block').width() * 260 / 180); +$('.zya_block').height($('.zya_block').width() * 185 / 355); + +var issx = 0; + +// 轮播图跳转 +$('#slider').on('tap', '.swiper-slide', function() { + openAds($(this)); +}) + +//导航栏 +document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (-scroll.y < 0) { + num = 0; + } else if ((-scroll.y > 0 || scroll.y == 0) && -scroll.y < 150) { + num = -scroll.y / 150; + } else { + num = 1; + } + $('.header').css('background-color', 'rgba(255,255,255,' + num + ')') + + if (-scroll.y < 75) { + $('.saoyisao').attr('src', '../img/saoyisao.png'); + $('.msg').attr('src', '../img/icon_msg.png'); + $('.search').attr('src', '../img/icon_search.png'); + $('#search').css('background-color', 'white'); + $('.header').removeClass('shadown_wai'); + } else { + $('.saoyisao').attr('src', '../img/saoyisao1.png'); + $('.msg').attr('src', '../img/icon_msg1.png'); + $('.search').attr('src', '../img/icon_search1.png'); + $('#search').css('background-color', '#d8d8d8'); + $('.header').addClass('shadown_wai'); + } + + if (scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } +}) +mui('.classify').on('tap', '.class_block', function() { + var classifyId = $(this).attr('data-classifyId'); + var url = 'orSupermarket.html'; + + if (classifyId == '') { + url = 'ac3.html'; + } + JZL.openWindow(url, url, {classifyId: classifyId}); +}) + +//为你推荐 +getRecommend(page, pageSize); +document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pageSize); + } + } +}) +//搜索 +$('.header').on('focus', '#keyword', function() { + $(".search button").css('display', 'block'); +}) +$('.header').on('blur', '#keyword', function() { + $(".search button").css('display', 'none'); +}) +$(".header").on('tap', '.search button', function(e) { + var searchName = $('#keyword').val(); + JZL.openWindow('goodslist.html', 'goodslist.html', {data_keyword: searchName}); + $('#keyword').val("") + // JZL.openWindow('shopsList.html', 'shopsList.html', {data_keyword: searchName}); + //JZL.openWindow('shopgoodList.html', 'shopgoodList.html', {data_keyword: searchName}); +}); +//跳转商品详情页 +mui("body").on('tap', '.bc_img', function() { + var goodsId = $(this).attr('data-goodsId'); + var shopId = $(this).parent().parent().attr('data-shopId'); + JZL.openWindow('details.html', 'details.html' + goodsId, {data_id: goodsId,shopId: shopId}); +}) diff --git a/static/app2/js/setting.js b/static/app2/js/setting.js new file mode 100755 index 0000000..32b4146 --- /dev/null +++ b/static/app2/js/setting.js @@ -0,0 +1,67 @@ +$('.header_con .title').html('设置'); +$('#setting_loginInfo').hide(); +$('#connect_our').hide(); +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.loginout').on('tap', function() { + ////console.log(111) + mui.ajax(qlgUrl('app/users/logout'), { + headers: { + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + localStorage.removeItem("token"); + mui.fire(plus.webview.getWebviewById('templete/my.html'), 'refresh'); + mui.fire(plus.webview.getWebviewById('templete/shoppingcart.html'), 'refresh'); + mui.back(); + var data = toJson(data, 1); + if(data.status == 1) { + + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) +}) \ No newline at end of file diff --git a/static/app2/js/setting_address.js b/static/app2/js/setting_address.js new file mode 100755 index 0000000..45bef1d --- /dev/null +++ b/static/app2/js/setting_address.js @@ -0,0 +1,183 @@ +$('.header_con .title').html('编辑收货地址'); + +$('.mui-scroll-wrapper').addClass('scroll_out_t').removeClass('scroll_out'); +$('.footer_btn').css('z-index', '10000') + +mui.init({ + beforeback: function() { //获得父页面的webview + //触发父页面的自定义事件(refresh),从而进行刷新 + + //返回true,继续页面关闭逻辑 + return true; + } +}); +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var self = plus.webview.currentWebview(); + var isOrder = self.data_isOrder; + if (isOrder == true) { + $('.con').on('tap', '.block', function() { + var addressId = $(this).attr('data-addressId'); + localStorage.setItem('addressId', addressId); + var list = plus.webview.currentWebview().opener(); + mui.fire(list, 'setAddress'); + mui.back(); + }) + } + mui.ajax(qlgUrl('app/useraddress/getList'), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + data = data.data; + var html = ''; + $.each(data.addressList, function() { + html += '<div class="block" data-addressId="' + this.addressId + '"><p class="pname">' + this.userName + + '</p><p class="pphone">' + this.userPhone + '</p><p class="paddress">' + this.areaName + ' ' + this.userAddress + + '</p><hr /><div class="btnout" data-isDefault="' + this.isDefault + + '"><div class="btn"></div></div><p class="p1">设为默认地址</p><button class="bj">编辑</button><button class="del">删除</button></div>' + }); + $('.con').html(html) + $('.btnout').each(function(num) { + if ($(this).attr('data-isDefault') == 1) { + $(this).children('.btn').addClass('on') + } + }) + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + $('body').on('tap', '.footer_btn', function() { + mui.openWindow({ + url: 'editAddress.html', + id: 'editAddress.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.con').on('tap', '.bj', function(e) { + e.stopPropagation(); + var data_addressId = $(this).parent().attr('data-addressId'); + mui.openWindow({ + url: 'editAddress.html', + id: 'editAddress.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_addressId: data_addressId + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con').on('tap', '.del', function() { + var data_addressId = $(this).parent().attr('data-addressId'); + if (confirm('确认删除地址?')) { + mui.ajax(hyhUrl('app/Useraddress/del'), { + data: { + id: data_addressId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + location.reload() + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + + }) + $('.con').on('tap', '.btnout', function() { + $('.btnout').children('.btn').removeClass('on'); + $(this).children('.btn').addClass('on'); + var addressId = $(this).parent().attr('data-addressId') + mui.ajax(hyhUrl('app/Useraddress/setDefault'), { + data: { + id: addressId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + location.reload() + + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) +}) diff --git a/static/app2/js/setting_fogetPayPwd.js b/static/app2/js/setting_fogetPayPwd.js new file mode 100755 index 0000000..60b7b5e --- /dev/null +++ b/static/app2/js/setting_fogetPayPwd.js @@ -0,0 +1,200 @@ +$('#newPass').attr('type','text'); +$('#newPass2').attr('type','text'); + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var wait = 120; + + function time() { + + if(wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + mui.ajax(hyhUrl('app/users/backPayPass'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + if(data.userPhone) { + $('#userPhone').val(data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + } else { + alert('未绑定手机请先绑定手机!'); + mui.openWindow({ + url: 'setting_phone.html', + id: 'setting_phone.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } else { + alert(data.msg); + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + mui('.row').on('tap', '#mobileCode', function() { + var that = $(this); + + $(this).attr("disabled", true); + mui.ajax(hyhUrl('app/users/backpayCode'), {  + + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if(data.status == 1) { + time(); + } else { + alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type) + // alert(type);       + } + });  + }) + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if(phoneCode == '') { + alert('验证码不能为空!'); + return; + } else if(phoneCode.length < 4) { + alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/verifybackPay'), {  + headers: {  + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + $('#con1').css('display', 'none'); + $('#down1').css('display', 'none'); + $('#con2').css('display', 'block'); + $('#down2').css('display', 'block'); + } else { + alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + mui('.down').on('tap', '#true2', function() { + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + var that = $(this); + if(newPass == '') { + alert('支付密码不能为空!'); + return; + } else if(newPass.length != 6) { + alert('支付密码为6位!'); + return; + } else if(newPass != newPass2) { + alert('两次支付密码不相同!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/users/resetbackPay'), {  + headers: {  + "HYH-Token": token + }, + data: { + newPass: newPass + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + alert(data.msg); + mui.back(); + } else { + alert(data.msg); + } + that.removeAttr('disabled') + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + }) + +}) \ No newline at end of file diff --git a/static/app2/js/setting_fogetPwd.js b/static/app2/js/setting_fogetPwd.js new file mode 100755 index 0000000..e243908 --- /dev/null +++ b/static/app2/js/setting_fogetPwd.js @@ -0,0 +1,208 @@ +mui.plusReady(function() { + var wait = 120; + + function time() { + + if (wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + mui('.row').on('tap', '#mobileCode', function() { + var that = $(this); + + $(this).attr("disabled", true); + mui.ajax(qlgUrl('app/users/getfindPhone'), { + + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + time(); + } else { + mui.alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type) + // mui.alert(type); + } + }); + }) + mui('.down').on('tap', '#true0', function() { + var loginName0 = $('#loginName0').val(); + var that = $(this); + if (loginName0 == '') { + mui.alert('用户名不能为空!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/findPass'), { + + data: { + loginName: loginName0, + step: 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + $('#con0').css('display', 'none'); + $('#down0').css('display', 'none'); + $('#con1').css('display', 'block'); + $('#down1').css('display', 'block'); + mui.ajax(hyhUrl('app/users/forgetPasst'), { + + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + $('#loginName').val(data.data.loginName); + $('#loginName').attr('disabled', 'disabled'); + $('#userPhone').val(data.data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if (phoneCode == '') { + mui.alert('验证码不能为空!'); + return; + } else if (phoneCode.length < 4) { + mui.alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/findPass'), { + data: { + Checkcode: phoneCode, + modes: 1, + step: 2 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + ////console.log(data); + //alert(1) + document.getElementById("con1").style.display = "none"; + document.getElementById("down1").style.display = "none"; + document.getElementById("con2").style.display = "block"; + document.getElementById("down2").style.display = "block"; + + //$('#con1').css('display', 'none'); + //$('#down1').css('display', 'none'); + //$('#con2').css('display', 'block'); + //$('#down2').css('display', 'block'); + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) { //异常处理; + mui.alert(type); + } + }); + + }) + mui('.down').on('tap', '#true2', function() { + var loginPwd = $('#loginPwd').val(); + var repassword = $('#repassword').val(); + var that = $(this); + if (loginPwd == '') { + mui.alert('登录密码不能为空!'); + return; + } else if (loginPwd.length < 6) { + mui.alert('登录密码最少为6位!'); + return; + } else if (loginPwd != repassword) { + mui.alert('两次支付密码不相同!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/findPass'), { + data: { + step: 3, + loginPwd: loginPwd, + repassword: repassword + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + mui.alert(data.msg); + mui.back(); + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + +}) diff --git a/static/app2/js/setting_loginInfo.js b/static/app2/js/setting_loginInfo.js new file mode 100755 index 0000000..76fcf0a --- /dev/null +++ b/static/app2/js/setting_loginInfo.js @@ -0,0 +1,34 @@ +mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/setting_payPwd.js b/static/app2/js/setting_payPwd.js new file mode 100755 index 0000000..4d9220b --- /dev/null +++ b/static/app2/js/setting_payPwd.js @@ -0,0 +1,58 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + + mui('.down').on('tap', '#true', function() { + var that = $(this) + var oldPass = $('#oldPass').val(); + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + + if (oldPass == '') { + mui.alert('原支付密码不能为空!'); + return; + } + if (newPass == '') { + mui.alert('新支付密码不能为空!'); + return; + } + if (newPass.length != 6) { + mui.alert('新支付密码长度为6位!'); + return; + } + if (!(newPass == newPass2)) { + mui.alert('两次支付密码不一致!'); + return; + } + + $(this).attr("disabled", true); + mui.ajax(qlgUrl('app/users/editpayPwd'), { + + data: { + oldPass: oldPass, + newPass: newPass, + reNewPass: newPass2 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + mui.alert(data.msg); + mui.back(); + + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type) + } + }); + }) + +}) diff --git a/static/app2/js/setting_phone.js b/static/app2/js/setting_phone.js new file mode 100755 index 0000000..a77d2e8 --- /dev/null +++ b/static/app2/js/setting_phone.js @@ -0,0 +1,258 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var isBang = 0; + var isOver = 1; + var wait = 120; + var wait1 = 120; + + function time() { + + if (wait == 0) { + $('#mobileCode').removeAttr("disabled"); + $('#mobileCode').val("重新发送"); + wait = 120; + } else { + $('#mobileCode').attr("disabled", true); + $('#mobileCode').val("重新发送(" + wait + ")"); + wait--; + setTimeout(function() { + time(); + }, + 1000) + } + + } + + function time1() { + + if (wait1 == 0) { + $('#mobileCode1').removeAttr("disabled"); + $('#mobileCode1').val("重新发送"); + wait1 = 120; + } else { + $('#mobileCode1').attr("disabled", true); + $('#mobileCode1').val("重新发送(" + wait1 + ")"); + wait1--; + setTimeout(function() { + time1(); + }, + 1000) + } + + } + mui.ajax(qlgUrl('app/users/editPhone'), { + headers: { + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data); + if (data.status == 1) { + data = data.data; + + if (data.userPhone) { + isBang = 1; + $('#userPhone').val(data.userPhone); + $('#userPhone').attr('disabled', 'disabled'); + $('#next_btn').css('display', 'block'); + } else { + $('#true').css('display', 'block'); + } + } else { + mui.alert(data.msg); + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + mui('.row').on('tap', '.codeBtn', function() { + var that = $(this) + var userPhone = $('#userPhone').val(); + var url = $(this).attr('id') == 'mobileCode' ? 'sendCodeEdit' : 'sendCodeTie' + if (isBang == 0 || isOver == 0) { + if (userPhone == '') { + mui.alert('手机号不能为空!'); + return; + + } + if (!( + /^134[0-8]\d{7}$|^13[^4]\d{8}$|^14[5-9]\d{8}$|^15[^4]\d{8}$|^16[6]\d{8}$|^17[0-8]\d{8}$|^18[\d]{9}$|^19[8,9]\d{8}$/ + .test(userPhone))) { + mui.alert("手机号码有误,请重填!"); + return; + } + } else { + userPhone = ''; + } + + $(this).attr("disabled", true); + mui.ajax(qlgUrl('app/users/' + url), { + + data: { + userPhone: userPhone + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + + if (that.attr('id') == 'mobileCode') { + time(); + } else if (that.attr('id') == 'mobileCode1') { + time1(); + } + + } else { + mui.alert(data.msg) + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type) + // mui.alert(type); + } + }); + }) + //未绑定手机 + mui('.down').on('tap', '#true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if (phoneCode == '') { + mui.alert('验证码不能为空!'); + return; + } else if (phoneCode.length < 4) { + mui.alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/phoneEdit'), { + headers: { + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + mui.alert(data.msg); + mui.back(); + + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + //已绑定手机 1 + mui('.down').on('tap', '#next_btn', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if (phoneCode == '') { + mui.alert('验证码不能为空!'); + return; + } else if (phoneCode.length < 4) { + mui.alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/phoneEdito'), { + headers: { + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + $('#next_btn').css('display', 'none'); + $('#next_true').css('display', 'block'); + $('#userPhone').removeAttr('disabled'); + $('#userPhone').val(''); + $('#phoneCode').val(''); + $('#mobileCode').css('display', 'none'); + $('#mobileCode1').css('display', 'block'); + isOver = 0; + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + //已绑定手机 2 + mui('.down').on('tap', '#next_true', function() { + var phoneCode = $('#phoneCode').val(); + var that = $(this); + if (phoneCode == '') { + mui.alert('验证码不能为空!'); + return; + } else if (phoneCode.length < 4) { + mui.alert('验证码格式不正确!'); + return; + } + + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/users/phoneEdit'), { + headers: { + "HYH-Token": token + }, + data: { + phoneCode: phoneCode + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + mui.alert(data.msg); + mui.back(); + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + +}) diff --git a/static/app2/js/setting_pwd.js b/static/app2/js/setting_pwd.js new file mode 100755 index 0000000..2569bd1 --- /dev/null +++ b/static/app2/js/setting_pwd.js @@ -0,0 +1,60 @@ +mui.plusReady(function() { + var token = localStorage.getItem('token'); + + mui('.down').on('tap', '#true', function() { + var that = $(this) + var oldPass = $('#oldPass').val(); + var newPass = $('#newPass').val(); + var newPass2 = $('#newPass2').val(); + + if(oldPass == '') { + mui.alert('原支付密码不能为空!'); + return; + } + if(newPass == '') { + mui.alert('新支付密码不能为空!'); + return; + } + if(newPass.length < 6) { + mui.alert('新支付密码不能小于6位!'); + return; + } + if(!(newPass == newPass2)) { + mui.alert('两次支付密码不一致!'); + return; + } + + $(this).attr("disabled", true); + mui.ajax(qlgUrl('app/users/editloginPwd'), { + + data: { + oldPass: oldPass, + newPass: newPass + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + var data = toJson(data); + //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data.status) + if(data.status == 1) { + + mui.alert(data.msg); + mui.back(); + + } else { + mui.alert(data.msg); + } + that.removeAttr('disabled'); + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // mui.alert(type) + // mui.alert(type); + } + }); + }) + +}) \ No newline at end of file diff --git a/static/app2/js/setting_user.js b/static/app2/js/setting_user.js new file mode 100755 index 0000000..0a0dd05 --- /dev/null +++ b/static/app2/js/setting_user.js @@ -0,0 +1,39 @@ +$('.header_con .title').html('个人信息'); + +$('.block').addClass('scroll_out_t') + +mui('.block').on('tap', '.row', function() { + var url = $(this).attr('id'); + //console.log($(this)); + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/shangdu.js b/static/app2/js/shangdu.js new file mode 100755 index 0000000..c574e3d --- /dev/null +++ b/static/app2/js/shangdu.js @@ -0,0 +1,225 @@ +mui.plusReady(function() { + // 获取申请信息 + var self = plus.webview.currentWebview(); + //console.log(self); + var id = self.ssid ? self.ssid : ''; + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 4 + }, function(data) { + //console.log(data); + if (1 == data.status & undefined != data.data) { + var data = data.data; + + if (0 == data.status || 2 == data.status) { + if (id == '') { + id = data.id + } + + getShopList(data.shopId); + + $('#confirm').attr('src', hyhImgUrl(data.confirmImg)) + $('#confirmImg').val(data.confirmImg) + + var imgs = data.shopImg + imgs = Array.from(imgs.split(',')) + //console.log(imgs); + var html = ""; + mui.each(imgs, function(index, element) { + //console.log(index, element); + html += '<div class="galleryImg photo" data-id="' + index + + '" ><div class="delete" data-id="' + index + '"><img src="../img/close.png" alt=""></div><img src="' + + hyhImgUrl(element) + '" class="ossfile" data-src="' + element + '" data-id="' + index + '" id="galleryImg[' + + index + + ']" alt=""><input type="hidden" name="gallery[]" value="' + element + + '" class="gallery" id="gallery[' + index + ']"><span class=""></span></div>'; + }) + // var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + var maxNum = imgs.length - 1; + // //console.log(maxNum); + // //console.log(num); + // if (num == maxNum) { + maxNum++; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html); + // } + + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 117 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + + } else if (1 == data.status) { + //tiaozhuandao shangdu yemian + } + } else { + getShopList(); + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 117 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + } + }) + + + + + + + // 上传图片 + $('.photos_con').on('tap', '.confirm', function() { + UP.init("confirmImg", "test", "confirm") + openCamera() + }) + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + + that.html(html); + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + //删除照片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + // //console.log(this); + var that = $(this) + //var idx = that.parent().attr('data-id'); + //var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; + } + }) + + // 获取店铺信息 + function getShopList(defaultShopId) { + + JZL.ajax(qlgUrl('app/shops/userShopList'), { + shopType: 1 + }, function(data) { + //console.log(data); + if (1 == data.status) { + var html = ""; + html = `<option value ="">选择店铺</option>`; + if (undefined == typeof defaultShop) { + + mui.each(data.data, function() { + // //console.log(index, element); + html += `<option value =${this.shopId}>${this.shopName}</option>`; + }) + } else { + mui.each(data.data, function() { + if (this.shopId == defaultShopId) { + selected = 'selected'; + } else { + selected = ''; + } + html += `<option value =${this.shopId} ${selected}>${this.shopName}</option>`; + }) + + } + $("#shopId").html(html) + } else { + mui.alert(data.msg) + } + // }) + }) + + + } + + + + + + let click = 0 + $('.down').on('tap', '.btn', function() { + + if (click == 1) { + return; + } + click = 1 + var imgs = ''; + var data = $('input[name="gallery[]"]'); + //console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + }) + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + $('#shopImg').val(imgs); + if ('' == $('#shopId option:selected').val()) { + mui.alert('请选择要升级的店铺名称') + return; + } + + if ('' == $('#confirmImg').val()) { + mui.alert('请上传确认书照片') + return; + } + if ('' == $('#shopImg').val()) { + mui.alert('请上传店铺照片') + return; + } + + + var params = JZL.getParams(".inp"); + + // var shopId=$("#chooseshop option:selected").val() + // //console.log(shopId); + // params.shopId=shopId; + params.applyLevel = 4; + if ("" != id) { + params.id = id; + + } + JZL.ajax(qlgUrl('app/shops/userUpdate'), params, function(data) { + //console.log(data); + if (1 == data.status) { + mui.back() + } else { + mui.alert(data.msg) + } + }) + }) + + + + +}) diff --git a/static/app2/js/share.js b/static/app2/js/share.js new file mode 100755 index 0000000..49889d8 --- /dev/null +++ b/static/app2/js/share.js @@ -0,0 +1,168 @@ + +var shares = null; +var Intent = null, + File = null, + Uri = null, + main = null; +// H5 plus事件处理 +function plusReady() { + updateSerivces(); + if(plus.os.name == "Android") { + main = plus.android.runtimeMainActivity(); + Intent = plus.android.importClass("android.content.Intent"); + File = plus.android.importClass("java.io.File"); + Uri = plus.android.importClass("android.net.Uri"); + } +} +if(window.plus) { + plusReady(); +} else { + document.addEventListener("plusready", plusReady, false); +} + +/** + * + * 更新分享服务 + */ +function updateSerivces() { + plus.share.getServices(function(s) { + shares = {}; + for(var i in s) { + var t = s[i]; + shares[t.id] = t; + } + }, function(e) { + plus.nativeUI.toast("获取分享服务列表失败:" + e.message); + }); +} + +/** + * 分享操作 + * @param {JSON} sb 分享操作对象s.s为分享通道对象(plus.share.ShareService) + * @param {Boolean} bh 是否分享链接 + */ +function shareAction(sb, bh) { + if(!sb || !sb.s) { + plus.nativeUI.toast("无效的分享服务!"); + return; + } + + var msg = { + content: sharehrefDes.value, + extra: { + scene: sb.x + }, + type:"web" + }; + if(bh) { + msg.href = sharehref.value; + if(sharehrefTitle && sharehrefTitle.value != "") { + msg.title = sharehrefTitle.value; + } + if(sharehrefDes && sharehrefDes.value != "") { + msg.content = sharehrefDes.value; + } + msg.thumbs = ["_www/logo.png"]; + msg.pictures = ["_www/logo.png"]; + } else { + if(pic && pic.realUrl) { + msg.pictures = [pic.realUrl]; + } + } + // 发送分享 + if(sb.s.authenticated) { + // plus.nativeUI.toast("---已授权---"); + shareMessage(msg, sb.s); + } else { +// plus.nativeUI.toast("---未授权---"); + sb.s.authorize(function() { + shareMessage(msg, sb.s); + }, function(e) { + plus.nativeUI.toast("认证授权失败:" + e.code + " - " + e.message); +// alert("认证授权失败:"+e.code+" - "+e.message ); + }); + } +} +/** + * 发送分享消息 + * @param {JSON} msg + * @param {plus.share.ShareService} s + */ +function shareMessage(msg, s) { + +// plus.nativeUI.toast(JSON.stringify(msg)); + s.send(msg, function() { + plus.nativeUI.toast("分享到\"" + s.description + "\"成功! "); + + }, function(e) { + plus.nativeUI.toast("分享到\"" + s.description + "\"失败 "); +// alert( "分享到\""+s.description+"\"失败: "+JSON.stringify(e) ); + }); +} +// 分析链接 +function shareHref() { + var shareBts = []; + // 更新分享列表 + var ss = shares['weixin']; + ss && ss.nativeClient && (shareBts.push({ + title: '微信朋友圈', + s: ss, + x: 'WXSceneTimeline' + }), + shareBts.push({ + title: '微信好友', + s: ss, + x: 'WXSceneSession' + })); + + // 弹出分享列表 + shareBts.length > 0 ? plus.nativeUI.actionSheet({ + title: '分享注册链接', + cancel: '取消', + buttons: shareBts + }, function(e) { + (e.index > 0) && shareAction(shareBts[e.index - 1], true); + }) : plus.nativeUI.plus.nativeUI.toast('当前环境无法支持分享链接操作!'); +} + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui.ajax(hyhUrl('app/Users/get_share'), {  + + headers: {  + "HYH-Token": token + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + //读取成功后 + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 96, //设置宽高 + height: 96 + }); + qrcode.makeCode(data.data.url); +// console.log(hyhImgUrl(data.data.bg_share)) + $('.bg').attr('src',hyhImgUrl(data.data.bg_share)) +// $('.bg').attr('src','../img/fenx111.png') + $('#sharehref').val(data.data.url) + $('#sharehrefTitle').val(data.data.title) + $('#sharehrefDes').val(data.data.desc) + } else { + //console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // plus.nativeUI.toast(type);     + }   + });  + $('.header').on('tap','.share',function(){ + shareHref(); + }) +}); + diff --git a/static/app2/js/share_user_list.js b/static/app2/js/share_user_list.js new file mode 100755 index 0000000..cf2b5fd --- /dev/null +++ b/static/app2/js/share_user_list.js @@ -0,0 +1,138 @@ +//$('#pullrefresh').removeClass('scroll_out_').addClass('scroll_out_t'); +//var hSize = 120 + (+localStorage.getItem('ipxSizeTop')) + 'px'; +//$('#pullrefresh').css('top', hSize); +var page = 1; +var userType = 0; +var isjiazai = 1; +document.write('<script type="text/javascript" src="../js/qrcode.js?ver=' + localStorage.getItem('version') + '"></scr' + 'ipt>'); +$('body').append('<div id="share_user_info"></div>'); + +function getData(page, userType) { + var data_set = { + page: page ? page : 1, + userType: userType ? userType : 0 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + mui.ajax(hyhUrl('app/users/getShareList'), {  +// headers: {  +// "HYH-Token": token +// }, + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.Rows; + var html = ''; + if(data == '') { + isjiazai = 0; + $('.con').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;padding-top: 9px;">没有更多内容</p>'); + return; + } + var defaultImg = ''; + var userPhoto = ''; + var userName = ''; + var setName = ''; + $.each(data, function() { + defaultImg = userType==0? ectImgUrl('static/app2/img/user68.png'):ectImgUrl('static/app2/img/user68.png'); + userPhoto = this.userPhoto == '' ? defaultImg : hyhImgUrl(this.userPhoto); + userName = this.userName == '' ? this.userName : this.loginName; + setName = this.isLogin == 1 ? userName : userName + '<a style="color:red;">--未登录--</a>'; + html += '<div class="row"><div class="row_top clearfix" data-loginName="'+this.loginName+'" data-name="'+userName+'" data-time="'+this.createTime+'" data-userId="'+this.userId+'"><img class="img" src="' + userPhoto + '"/><p>' + setName + '</p><img class="btn" src="../img/xiajiantou.png"/></div><div class="row_hid" style="display: none;"><div class="row_h_r"><p>注册时间:' + this.createTime + '</p></div></div></div>' + }) + + if(page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + } +} + +mui.plusReady(function() { + var token = localStorage.getItem('token'); + mui('.con').on('tap', '.row_top', function() { + if($(this).children('.btn').hasClass('ani')) { + //$(this).children('.btn').removeClass('ani'); + //$(this).siblings('.row_hid').slideUp(300); + } else { + //$(this).children('.btn').addClass('ani'); + //$(this).siblings('.row_hid').slideDown(300); + var data_set = { + sid: $(this).attr('data-userId'), + userType: userType ? userType : 0 + } + var userName = $(this).attr('data-name'); + var createTime = $(this).attr('data-time'); + var loginName = $(this).attr('data-loginName'); + JZL.ajax(hyhUrl('app/users/getShareInfo'), data_set, function(data){ + data=toJson(data); + var ect_order_num = null == data['ect']['order_num'] ? '0.00' : data['ect']['order_num']; + var ect_reward_num = null == data['ect']['reward_num'] ? '0.00' : data['ect']['reward_num']; + var order_num = null == data['money']['order_num'] ? '0.00' : data['money']['order_num']; + var reward_num = null == data['money']['reward_num'] ? '0.00' : data['money']['reward_num']; + $('#share_user_info').html('<div class="mui-backdrop" style="display: block;background-color: rgba(0,0,0,.7);" ><div class="show_share"><img src="'+ectImgUrl('static/app2/img/share_info.png')+'" /><div class="header_img""><img src="'+ectImgUrl('static/app2/img/user68.png')+'" /></div><div class="name_info name_str"">'+userName+'</div><div class="name_info time_str"">'+createTime+'</div><div class="share_info left left1"">'+ect_order_num+'</div><div class="share_info left left2"">'+order_num+'</div><div class="share_info right right1"">'+ect_reward_num+'</div><div class="share_info right right2"">'+reward_num+'</div><div id="qrcode" class="share_info qrcode_img" style="display:none;"></div></div></div>') + var qrcode = new QRCode(document.getElementById("qrcode"), { + width: 150, //设置宽高 + height: 150 + }); + + //$('body').append('<div id="qrcode" class="qrcode_img" style="display:none;"></div>'); + qrcode.makeCode('http://www.juzi199.com/mobile/users/reg?pName='+loginName); + $('#qrcode').show(); + },'POST'); + + } + }) + //点击让遮罩层消失 + mui('body').on('tap', '.mui-backdrop,.qrcode_img', function() { + $('#qrcode').html(''); + $('#qrcode').hide(); + $('.mui-backdrop').hide(); + }); + mui('.nav').on('tap','.block',function(){ + + if($(this).attr('data-userType')=='users'){ + userType=0; + }else{ + userType=1; + } + if($(this).hasClass('on')){ + return; + }else{ + + $(this).addClass('on').siblings().removeClass('on'); + mui('#pullrefresh').scroll().scrollTo(0,0,0); + $('.con').html('&nbsp;'); + isjiazai=1; + page=1; + getData(page,userType); + } + }) + + getData(1, 0); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY&&scroll.y!=0) { + + if(isjiazai == 1) { + page++; + getData(page, userType); + } + + } + }) +}) \ No newline at end of file diff --git a/static/app2/js/shopGoodsList.js b/static/app2/js/shopGoodsList.js new file mode 100755 index 0000000..2515312 --- /dev/null +++ b/static/app2/js/shopGoodsList.js @@ -0,0 +1,128 @@ +var msort = 1; +var page = 1; +var condition = 1; +var desc = 0; +var keyword; +var isjiazai = 1; +var count = 1; +var pagesize = 10; +var ct1; +var ct2; +var goodsName = ''; + +function pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2) { + // setTimeout(function() { + + // mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + + var data_set = { + page: page, + pagesize: pagesize, + shopId: shopId, + mdesc: desc, + msort: msort, + goodsName: goodsName + } + // console.log(order_class) + if(isjiazai == 0) { + return; + }else{ + isjiazai = 0; + } + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + + data: data_set, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + if(page == "1") { + $('.recommend_con').html(html); + } else { + $('.recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_img').height($('.rcb_img').width()); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + // }, 500); +} + +mui.plusReady(function() { + var shopId = localStorage.getItem('shopId') + var costnum = 0; + var self = plus.webview.currentWebview(); + goodsName = self.data_keyword; + pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2) + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + isjiazai = 1; + $(this).addClass('on').siblings().removeClass('on'); + + msort = $(this).attr('data-condition'); + + if($('#cost_btn').hasClass('on')) { + + costnum += 1; + + if(costnum % 2 == 1) { + + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + + desc = 1; + + } else if(costnum % 2 == 0) { + + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + + desc = 0; + + } + + } else { + + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + + costnum = 0; + desc = 0 + } + pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2) + + }) + + + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + pullupRefresh(shopId, msort, desc, pagesize, page, goodsName, ct1, ct2); + } + + } + }) + +}) + +// setInterval(function() { +// $('.cnxh_block img').height($('.cnxh_block img').width()); +// $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +// }, 100) \ No newline at end of file diff --git a/static/app2/js/shop_decorate.js b/static/app2/js/shop_decorate.js new file mode 100755 index 0000000..5ce4dd9 --- /dev/null +++ b/static/app2/js/shop_decorate.js @@ -0,0 +1,126 @@ +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId = self.id; + //获取店铺相册 + JZL.ajax(qlgUrl('app/shops/getShopImg'), { + shopId: shopId + }, function(data) { + //console.log(data); + if (1 == data.status && '' != data.data.shopImg) { + $('#shop').attr('src', hyhImgUrl(data.data.shopImg)) + $('#shopImg').val(data.data.shopImg) + if ('' != data.data.shopAds) { + var shopAds = data.data.shopAds; + + ads = shopAds.split(",") + //console.log(ads); + var html = ''; + mui.each(ads, function(index, element) { + //console.log(element); + html += '<div data-id="' + index + + '" data-src="" class="galleryImg photo"><div class="delete"><img src="../img/close.png" alt=""></div><img src= "' + + hyhImgUrl(element) + '" class="ossfile" id="galleryImg[' + index + ']" alt=""><input type="hidden" value="' + + element + '" name="gallery[]" class="gallery inp" id="gallery[' + index + ']"><span class=""></span></div>' + }) + var maxNum = ads.length; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $('.batchImg').html(html) + + } + + } else { + mui.alert(data.msg) + } + }) + + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + + that.html(html); + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + + + $(".oneImg").on("tap", '#shop', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("shopImg", "test", "shop") + openCamera() + }) + // 删除图片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + // //console.log(this); + var that = $(this) + //var idx = that.parent().attr('data-id'); + //var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; + } + }) + // 提交 + var click = false; + $('.bc_btn').on('tap', function() { + if (click == true) { + return + } + + var imgs = ''; + var data = $('input[name="gallery[]"]'); + // //console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + + }) + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + $('#shopAds').val(imgs); + if ($.trim($('#shopImg').val()) == '') { + mui.alert("请上传店铺主图") + return + } + if ($.trim($('#shopAds').val()) == '') { + mui.alert("请上传店铺图片") + return + } + var params = JZL.getParams(".inp"); + params.shopId = shopId; + click == true; + JZL.ajax(qlgUrl('app/shops/uploadShopImg'), params, function(data) { + if (data.status == 1) { + mui.toast('保存成功'); + mui.back(); + } else { + mui.alert(data.msg); + } + }) + }) + + + +}) diff --git a/static/app2/js/shop_indent.js b/static/app2/js/shop_indent.js new file mode 100755 index 0000000..6e6a85e --- /dev/null +++ b/static/app2/js/shop_indent.js @@ -0,0 +1,44 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } +}) +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId=self.shopId; + var data_href = self.data_href; + if(data_href == 'all') { + $('.title').html('全部订单'); + + } + if(data_href == 'waitPay') { + $('.title').html('待付款'); + } + if(data_href == 'waitDeliver') { + $('.title').html('待发货'); + } + if(data_href == 'waitReceive') { + $('.title').html('待收货'); + } + if(data_href == 'waitConfirm') { + $('.title').html('待确认'); + } + if(data_href == 'abnormal') { + $('.title').html('退款/售后'); + } + localStorage.setItem('shop_order_class', data_href); + var bSize = 64 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var sub = plus.webview.create('shop_indentcon.html', data_href, { + top: bSize, + bottom: '0px', + scrollIndicator: 'none', + + },{ shopId:shopId}); + self.append(sub); + +}) \ No newline at end of file diff --git a/static/app2/js/shop_indentcon.js b/static/app2/js/shop_indentcon.js new file mode 100755 index 0000000..eeafb1e --- /dev/null +++ b/static/app2/js/shop_indentcon.js @@ -0,0 +1,831 @@ +$('#content').after('<div class="tui"></div>'); +var pay_name = 0; +var token = localStorage.getItem('token'); +var order_class = localStorage.getItem('shop_order_class'); +var orderNo; +var orderId; +var getReasonUrl = ''; +var priceT = 0; +var payCode = ''; +var shopId = ''; +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + contentnomore: '没有更多数据了', + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + }, + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + } + } +}); +var count = 1; + +function pullupRefresh() { + count += 1; + getData(count); + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); +} +// //console.log(order_class); +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + //mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +var isLoad = false; + +function getData(page) { + if (true == isLoad) return; + isLoad = true; + JZL.ajax(qlgUrl('app/Shoporders/getSellerOrderList'), { + type: order_class, + shopId: shopId, + page: page, + pagesize: 10 + }, function(data) { + //console.log(data); + var data = toJson(data); + var html = '', + html1 = ""; + if (1 == data.status) { + // console.log(data); + if ('' == data.data.Rows) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + $.each(data.data.Rows, function() { + //this.pay_name = 1; + var shopConfirmHtml = ''; + // console.log(this.orderStatus); + // if ( == 0) { + // if (0 == this.shopConfirm) { + // shopConfirmHtml = '<div class="indent_status confirm_wait" > 待商家确认</div>'; + // } else if (1 == this.shopConfirm) { + // shopConfirmHtml = '<div class="indent_status confirm_ok" > 商家已确认</div>'; + // }else if (2 == this.shopConfirm) { + // shopConfirmHtml = '<div class="indent_status confirm_no" > 商家未收款</div>'; + // } + // } + // html += '<div class="row" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + + // '"><div class="row_title"><div class="store_name">' + this.shopName + + // '</div><div class="indent_status yellow">' + + // this.status + '</div>' + shopConfirmHtml + '<div class="indent_status shopPhone">商家电话:<a href="tel:' + + // this.phone + '">'+this.phone+'</a></div></div><div class="row_con clearfix" data-id="' + this.orderId + + // '">' + html += '<div class="row shadown_wai" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + + '"><div class="row_title"><div class="rtl store_no">订单编号:' + this.orderNo + + '</div><div class="rtr indent_time">' + this.createTime + + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><div class="rc clearfix"><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + + '</p><del></del><span>x' + this.goodsNum + + '</span></div></div><div class="rcb clearfix"><span>优惠</span><span>优惠:0.52</span><span>优惠:0.52</span></div></div></div>' + // html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + + // '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + + // '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + + // this.goodsNum + '</span></div></div></div>'; + }) + + html += + '</div><div class="row_title clearfix"><div class="rtl user_info">买家信息</div><div class="rtr combination">共' + + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + '</o>(含运费¥0.00)</div></div>' + html += + '<div class="user_info_"><div class="u_address"><div class="pos"><img src="../img/dingwei1.png"></div><div class="pos_c"><p class="pos_c_p">地址:</p><p for="">' + + this.userAddress + + '</p></div></div><div class="u_address"><div class="pos"><img src="../img/dingwei1.png"></div><div class="pos_c"><p class="">电话:</p><p>' + + this.userPhone + '</p><p>' + this.userName + '</p></div></div></div>' + // html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + + // '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if (this.orderStatus == -2) { //未付款 + html += '<div class="btns clearfix"><div class="btns_btn ">未付款</div></div>' + // html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + + // '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if (this.orderStatus == -1) { + if (1 == this.isPay) { + if (1 == this.isRefund) { + //yituikuan + // html += '<div class="btns clearfix"><div class="btns_btn ">已退款</div></div>' + html += + '<div class="btns clearfix"><div class="btns_btn ">已退款</div><div class="btns_btn ">订单已取消</div></div>' + } else { + //tuikuancaozuoanniu + // html += '<div class="btns clearfix"><div class="btns_btn qrtk">确认退款</div></div>' + html += + '<div class="btns clearfix"><div class="btns_btn ">确认退款</div><div class="btns_btn ">订单已取消</div></div>' + + } + } else { + html += '<div class="btns clearfix"><div class="btns_btn ">订单已取消</div></div>' + } //0 daiqueren 1 queren 2 jujue + } else if (this.orderStatus == 0) { + if (1 == this.shopConfirm) { + html += '<div class="btns clearfix"><div class="btns_btn qrfh">确认发货</div></div>' + } else if (0 == this.shopConfirm) { + html += '<div class="btns clearfix"><div class="btns_btn qrsk">确认收款</div></div>' + } else if (2 == this.shopConfirm) { + html += + '<div class="btns clearfix"><div class="btns_btn qrsk">确认收款</div><div class="btns_btn ">已拒绝</div></div>' + + } + + // html +='<div class="btns clearfix"><div class="btns_btn qrfh">确认发货</div></div>' + //html += + // '<div class="btns clearfix"><div class="btns_btn qrfh">确认发货</div><div class="btns_btn qrsk">确认收款</div></div>' + } else if (this.orderStatus == 1) { + html += '<div class="btns clearfix"><div class="btns_btn yfh">已发货</div><div class="btns_btn">配送中</div></div>' + } else if (this.orderStatus == 2) { + html += + '<div class="btns clearfix"><div class="btns_btn finish">已完成</div><div class="btns_btn tjpz">提交凭证</div></div>' + } else if (this.orderStatus == -3) { + // html += '<div class="btns clearfix"><div class="btns_btn yhjs">用户拒收</div></div>' + if (1 == this.isPay) { + if (1 == this.isRefund) { + //yituikuan + html += + '<div class="btns clearfix"><div class="btns_btn ">已退款</div><div class="btns_btn ">用户拒收</div></div>' + + } else { + //tuikuancaozuoanniu + // html += '<div class="btns clearfix"><div class="btns_btn qrtk">确认退款</div></div>' + html += + '<div class="btns clearfix"><div class="btns_btn qrtk">确认退款</div><div class="btns_btn ">用户拒收</div></div>' + } + } + } + + // if(-1 == this.orderStatus || -3 ==this.orderStatus){ + // if(1 == this.isPay){ + // if(1 == this.isRefund){ + // //yituikuan + // html += '<div class="btns clearfix"><div class="btns_btn ">已退款</div></div>' + // + // }else{ + // //tuikuancaozuoanniu + // html += '<div class="btns clearfix"><div class="btns_btn qrtk">确认退款</div></div>' + // + // } + // } + // } + html1 = '<span>产品券:' + this.productNum + '</span><span>优惠券:' + this.couponsNum + '</span><br/><span>旺旺券:' + + this.wangNum + '<span>'; + html += '</div>' + }) + + $('.con').append(html); + $(".rcb").html(html1) + } else { + mui.alert(data.msg) + } + isLoad = false; + }) +} +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + // //console.log(self); + shopId = self.shopId; + getData(count); + // window.addEventListener('refresh', function(e) { //执行刷新 + // location.reload(); + // }); + // //console.log(order_class) + if (order_class == 'all') { + order_class = ''; + + } + // 已付款 店家确认收款 + $('.con').on('tap', '.qrsk', function() { + orderId = $(this).parent().parent().attr('data-id'); + $('.bg').css('display', 'block') + $('#querenshoukuan').css('display', 'block') + }) + $('#querenshoukuan').on('tap', '.pay_btn', function() { + // orderId = $(this).parent().parent().attr('data-id'); + var confirmType = $('#querenshoukuan input[type="radio"]:checked').val(); + //console.log(confirmType,orderId,shopId); + JZL.ajax(qlgUrl('app/Shoporders/orderConfirm'), { + confirmType: confirmType, + shopId: shopId, + id: orderId + }, function(data) { + // console.log(data); + if (1 == data.status) { + $('.bg').css('display', 'none') + $('#querenshoukuan').css('display', 'none') + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + + // mui.back(); + } else { + mui.alert(data.msg) + } + }) + }) + // 店家确认退款 + var content = ""; + $('.con').on('tap', '.qrtk', function() { + orderId = $(this).parent().parent().attr('data-id'); + $('.bg').css('display', 'block') + $('#querentuikuan').css('display', 'block') + }) + $('#querentuikuan').on('tap', '.pay_btn', function() { + // orderId = $(this).parent().parent().attr('data-id'); + var confirmType = $('#querentuikuan input[type="radio"]:checked').val(); + content = $("#refuse_con").val() + // console.log(confirmType, orderId, shopId, content, $("#refuse_con")); + if (-1 == confirmType) { + if ('' == $.trim($("#refuse_con").val())) { + mui.alert("请输入拒绝原因") + return + } else {} + } + JZL.ajax(qlgUrl('app/Shoporders/shopRefund'), { + refundStatus: confirmType, + content: content, + shopId: shopId, + id: orderId + }, function(data) { + //console.log(data); + if (1 == data.status) { + $('.bg').css('display', 'none') + $('#querentuikuan').css('display', 'none') + // location.reload(); + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + // mui.back(); + } else { + mui.alert(data.msg) + } + + }) + }) + // 已付款 店家发货 + $('.con').on('tap', '.qrfh', function() { + orderId = $(this).parent().parent().attr("data-id") + $('.bg').show(); + $('.delivery').show(); + JZL.ajax(qlgUrl('app/Orders/getExpress'), {}, function(data) { + // //console.log(data); + if (data.status == 1) { + // html = ''; + var html = '<option value="0">请选择快递公司</option>' + mui.each(data.data, function(index, element) { + html += '<option value="' + this.expressId + '">' + this.expressName + '</option>' + }) + $('#expressId').append(html) + } else { + mui.alert(data.msg) + } + }) + + }) + // 选择快递公司名称 + + + + //确认发货 + $('.delivery').on('tap', '.pay_btn', function() { + if (0 == $('#expressId option:selected').val()) { + mui.alert('请选择快递公司名称') + return; + } + if ('' == $('#expressNo').val()) { + mui.alert('请输入快递单号') + return; + } + var pargams = {} + pargams.expressNo = $('#expressNo').val(); + pargams.expressId = $('#expressId').val(); + pargams.id = orderId; + pargams.shopId = shopId; + JZL.ajax(qlgUrl('app/ShopOrders/deliver'), pargams, function(data) { + // console.log(data); + if (1 == data.status) { + // var data = data.data; + mui.toast(data.msg) + $('.delivery').css('display', 'none') + $('.bg').css('display', 'none') + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + + } else { + mui.alert(data.msg) + } + + }) + }) + // 返回 + $('.bg').on('tap', '.mui-icon-left-nav', function() { + // $('.pay').css('display', 'block'); + $('.bg').css('display', 'none'); + $('.pay_way').css('display', 'none'); + }) + //提交凭证 + $('.con').on('tap', '.tjpz', function() { + var orderId = $(this).parent().parent().attr("data-id") + JZL.openWindow('shoperUploadVoucher.html', 'shoperUploadVoucher.html', { + orderIds: orderId, + shopId: shopId, + }); + }) + + // 关闭 + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + // $(".pay").slideUp(300, function() { + // + // }); + }) + // + + // $('#pay_way').on('tap', '.row', function() { + // $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + // $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + // $('.con_1 .on .row_right o').html($(this).children('.row_left').html()); + // $('.con_1 .on').attr('data-payCode', $(this).attr('data-payCode')) + // $('.pay').css('display', 'block'); + // $('#pay_way').css('display', 'none'); + // + // }) + // $('.pay').on('tap', '.con_1 .on', function() { + // if ($(this).attr('data-payCode') == 'ect') { + // + // } else { + // $('.pay').css('display', 'none'); + // $('#pay_way').css('display', 'block'); + // } + // + // }) + // $('.pay_btn').on('tap', function() { + // payCode = $('.con_1 .on').attr('data-payCode'); + // ////console.log(payCode) + // var that = $(this); + // var data_ljfk = { + // isBatch: 0, + // orderNo: orderNo + // } + // that.attr('disabled', 'disabled'); + // mui.ajax(hyhUrl('app/orders/succeed'), { + // data: data_ljfk, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // data = toJson(data); + // + // if (data.status == 1) { + // if (payCode == 'qlgpay') { + // JZL.ajax(hyhUrl('app/' + payCode + '/payment'), { + // orderNo: orderNo, + // isBatch: 0 + // }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // // //console.log(JSON.stringify(data)); + // var data = toJson(data); + // // //console.log(JSON.stringify(data)) + // if (data.status == 1) { + // $('.pay').css('display', 'none'); + // $('#qlg_pay_pwd').css('display', 'block'); + // if (data.data.payPwd == '0') { + // mui.alert('还未设置支付密码请先设置操作密码!'); + // var url = 'setting_fogetPayPwd'; + // JZL.openWindow(url + '.html', url + '.html'); + // //return; + // } + // $('#totalMoney').html('付款总额:¥<o>' + data.data.needPay + '</o>'); + // $('#productNum').val(data.data.product.useProduct); + // if (data.data.product.useProduct > 0) { + // var html1 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.product.useProductOk + + // '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.product.useProductTaxFee + + // '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.product.useProductHandlingFee + + // '</span></p>'; + // // $('#productInfo').html('产品券[抵扣额:' + data.data.product.useProductOk + ',扣税:' + data.data.product.useProductTaxFee + + // // ',手续费:' + data.data.product.useProductHandlingFee + ']'); + // $('.productInfo_').html(html1) + // + // } + // $('#couponsNum').val(data.data.coupons.useCoupons); + // if (data.data.coupons.useCoupons > 0) { + // var html2 = '<p id="" class="p1"><span>抵扣额</span><span>' + data.data.coupons.useCouponsOk + + // '</span> </p><p id="" class="p1"><span>扣税</span> <span>' + data.data.coupons.useCouponsTaxFee + + // '</span></p><p id="" class="p1"><span>手续费</span> <span>' + data.data.coupons.useCouponsHandlingFee + + // '</span></p>'; + // $('.couponsInfo_').html(html2) + // // $('#couponsInfo').html('优惠券[抵扣额:' + data.data.coupons.useCouponsOk + ',扣税:' + data.data.coupons.useCouponsTaxFee + + // // ',手续费:' + data.data.coupons.useCouponsHandlingFee + ']'); + // } + // $('#wangNum').val(data.data.wang.useWang); + // $('#moneyNum').val(data.data.money.useMoney); + // + // } else { + // mui.alert(data.msg) + // } + // }); + // } else if (payCode == 'wallets' || payCode == 'ect') { + // //跳输入密码的页面 + // mui.ajax(hyhUrl('app/' + payCode + '/payment'), { + // data: { + // orderNo: orderNo, + // isBatch: 0 + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // // //console.log(data.data.goodsFavoritesNum) + // var data = toJson(data); + // if (data.status == 1) { + // $('.pay').css('display', 'none'); + // $('#pay_pwd').css('display', 'block'); + // if (data.data.payPwd == '0') { + // mui.alert('还未设置支付密码请先设置支付密码!'); + // var url = 'setting_fogetPayPwd'; + // mui.openWindow({ + // url: url + '.html', + // id: url + '.html', + // styles: { + // top: '0px', //新页面顶部位置 + // bottom: '0px', //新页面底部位置 + // width: '100%', //新页面宽度,默认为100% + // height: '100%' //新页面高度,默认为100% + // }, + // extras: { + // // data_href: data_href + // // ..... //自定义扩展参数,可以用来处理页面间传值 + // }, + // createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + // show: { + // // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // // extras: {} //窗口动画是否使用图片加速 + // }, + // waiting: { + // autoShow: true, //自动显示等待框,默认为true + // title: '正在加载...', //等待对话框上显示的提示内容 + // options: { + // // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // // ...... + // } + // } + // }) + // } + // } + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + // + // } else if (payCode == 'alipays') { + // pay('alipay', orderNo); + // // plus.nativeUI.showWaiting(); + // // mui.post(hyhUrl('app/Alipays/payment'), { + // // orderNo: data.data, + // // isBatch: 1 + // // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + // + // } + // + // that.removeAttr('disabled'); + // } else { + // mui.alert('发生错误请刷新后重试!'); + // // location.reload(); + // } + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + // } + // }) + // }) + // $('#pay_pwd,#qlg_pay_pwd').on('tap', '.p9', function() { + // var url = 'setting_fogetPayPwd'; + // JZL.openWindow(url + '.html', url + '.html'); + // }) + // $('#pay_pwd,#qlg_pay_pwd').on('tap', '.pay_btn_pwd', function() { + // // var self = plus.webview.currentWebview(); + // // var data_href = self.id; + // // //console.log(data_href) + // // JZL.closeWindow('waitPay'); + // //return; + // var payPwd = $('#payPwd').val(); + // if (payPwd == '') { + // mui.alert('支付密码不能为空!'); + // return; + // } + // var that = $(this); + // that.attr('disabled', 'disabled') + // var srcc = '' + // if (payCode == 'qlgpay') { + // srcc = 'payByQlg'; + // } else if (payCode == 'ect') { + // srcc = 'payByEct'; + // } else { + // srcc = 'payByWallet'; + // } + // + // mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), { + // + // data: { + // orderNo: orderNo, + // isBatch: 0, + // payPwd: payPwd + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // // //console.log(data.data.goodsFavoritesNum) + // var data = toJson(data); + // mui.alert(data.msg) + // //console.log(data.status) + // if (data.status == 1) { + // JZL.openWindow('indent.html', 'waitDeliver', { + // data_href: 'waitDeliver' + // }); + // setTimeout(function() { + // JZL.closeWindow(plus.webview.currentWebview().id); + // // JZL.closeWindow('indent.html'); + // }, 700) + // // var targetTab = plus.webview.getWebviewById("templete/my.html"); + // // mui.fire(targetTab, 'refresh'); + // // location.reload(); + // } else { + // + // } + // that.removeAttr('disabled') + // + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + // + // }) + + mui('.con').on('tap', '.row_con', function() { + var data_order_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'order_out.html', + id: 'order_out.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.ckwl', function() { + var data_order_id = $(this).parent().parent().attr('data-id'); //$(this).attr('data-id'); + JZL.openWindow('logistics.html', 'logistics.html', { + data_order_id: data_order_id + }); + }) + //上传凭证 + mui('.con').on('tap', '.uploadCertificate', function() { + var orderId = $(this).parent().parent().attr('data-id'); + // mui.alert('跳到上传凭证页' + orderId) + JZL.openWindow("uploadVoucher.html", "uploadVoucher.html", { + orderId: orderId + }) + }) + $('.con').on('tap', '.qxdd_js', function() { + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if ($(this).html() == '取消订单') { + getReasonUrl = 'getCancelCause'; + } else if ($(this).html() == '拒收') { + getReasonUrl = 'getRejectCause'; + } else if ($(this).html() == '申请退款') { + getReasonUrl = 'getRefundCause'; + JZL.ajax(hyhUrl('/app/Orders/getRefund'), { + id: orderId + }, function(data) { //服务器返回响应 + // //console.log(JSON.stringify(data)); + var data = toJson(data); + if (data.status == 1) { + data = data.data; + var html = ''; + if ('qlgpay' == data.payFrom) { + html = '&nbsp;退款产品券数量:<input type="text" class="refundTxt" name="productNum" id="productNum" value="' + + data.productNum + + '" placeholder="请输入产品券数量"/>' + + '&nbsp;退款优惠券数量:<input type="text" class="refundTxt" name="couponsNum" id="couponsNum" value="' + data.couponsNum + + '" placeholder="请输入优惠券数量"/>' + + '&nbsp;退款旺旺券数量:<input type="text" class="refundTxt" name="wangNum" id="wangNum" value="' + data.wangNum + + '" placeholder="请输入旺旺券数量"/>' + + '&nbsp;退款现金数量:' + data.moneyNum + ',现金方面请与商家协商' + + // '<p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + + '</o>)</p>'; + } else { + html = '<input type="text" name="Tmoney" id="Tmoney" value="' + data.realTotalMoney + + '" placeholder="请输入退款金额"/><p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + + '</o>)</p><p class="info1">(积分数量:' + data.ectNum + ')</p>'; + } + + $('.tui').html(html) + } else { + mui.alert(data.msg) + } + }); + } + $('.bg_').css('display', 'block'); + $('.bg_con').css('display', 'none'); + $('.bg_con').slideDown(300, function() {}); + mui.ajax(hyhUrl('/app/Orders/' + getReasonUrl), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + var html = '<option value="0">请下拉选择原因</option>'; + $.each(data.data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>' + }); + $('#select').html(html) + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + + $('.bg_').on('tap', '.en_false', function() { + $('.bg_').css('display', 'none'); + + }) + $('.bg_').on('tap', '.en_true', function() { + var setReasonUrl = ''; + var content = $('#content').val(); + var reason = $('#select').val(); + if ($('#select').val() == 0) { + mui.alert('请选择原因!'); + return; + } + if ($('#select').val() == 10000 && content == '') { + mui.alert('请输入其他原因!'); + return; + } + if (getReasonUrl == 'getCancelCause') { + setReasonUrl = 'cancellation'; + mui.ajax(qlgUrl('app/Orders/' + setReasonUrl), { + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + // var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + // mui.fire(list, 'refresh'); + if ('waitPay' == plus.webview.currentWebview().id) { + location.reload(); + } else { + JZL.openWindow('indent.html', 'abnormal', { + data_href: 'abnormal' + }); + setTimeout(function() { + //plus.webview.currentWebview().close(); + JZL.closeWindow(plus.webview.currentWebview().id); + }, 500) + } + // JZL.openWindow('indent.html', 'abnormal', { + // data_href: 'abnormal' + // }); + // setTimeout(function() { + // plus.webview.currentWebview().close(); + // // JZL.closeWindow(plus.webview.currentWebview().id); + // }, 500) + //location.reload(); + + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else if (getReasonUrl == 'getRejectCause') { + setReasonUrl = 'reject'; + mui.ajax(hyhUrl('app/Orders/' + setReasonUrl), { + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + // var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + // mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } else if (getReasonUrl == 'getRefundCause') { + var params = {} + // params.money = $('#Tmoney').val(); + // if (params.money < 0 || params.money == 0) { + // mui.alert('退款金额不能为0!'); + // return; + // } + params.productNum = $('#productNum').val(); + params.couponsNum = $('#couponsNum').val(); + params.wangNum = $('#wangNum').val(); + params.reason = reason; + params.id = orderId; + params.content = content; + JZL.ajax(hyhUrl('app/Orderrefunds/refund'), params, function(data) { + var data = toJson(data); + mui.alert(data.msg); + if (data.status == 1) { + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + } + }) + } + }) + $('#select').on('change', function() { + if ($(this).val() == '10000') { + $('#content').css('display', 'block'); + } else { + $('#content').css('display', 'none'); + } + }) +}) diff --git a/static/app2/js/shoperUploadVoucher.js b/static/app2/js/shoperUploadVoucher.js new file mode 100755 index 0000000..79c2335 --- /dev/null +++ b/static/app2/js/shoperUploadVoucher.js @@ -0,0 +1,67 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + }, +}) +mui.plusReady(function() { + var orderId = '', + id = '', + shopId = ''; + + var self = plus.webview.currentWebview(); + //console.log(self); + orderIds = self.orderIds; + shopId = self.shopId; + if ('undefined' != typeof self.orderId) { + id = self.orderId + } + if (id > 0) { //bianji + JZL.ajax(qlgUrl('app/shopOrders/getCertificateInfo'), { + shopId: shopId, + id: id + }, function(data) { + //console.log(data); + $('#content').val(data.data.content); + $('#img').attr('src', hyhImgUrl(data.data.imgUrl)) + $('#imgUrl').val(data.data.imgUrl) + }) + } + // 上传图片 + $(".oneImg").on("tap", '#img', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + UP.init("imgUrl", "test", "img") + openCamera() + }) + + var click = false; + $(".con").on("tap", '.bc_btn', function() { + if (true == click) return; + click = true; + var params = JZL.getParams(".inp"); + params.orderIds = orderIds; + params.shopId = shopId; + if (id > 0) { + params.id = id; + } + if ('' == $.trim($('#content').val())) { + mui.alert("请输入凭证说明") + return; + } + if ('' == $('#imgUrl').val()) { + mui.alert("请上传凭证图片") + return; + } + JZL.ajax(qlgUrl('app/Shoporders/uploadCertificate'), params, function(data) { + //console.log(data); + if (-1 == data.status) { + mui.alert(data.msg) + mui.back(); + } else { + mui.alert(data.msg) + } + }) + }) +}) diff --git a/static/app2/js/shopgoodlist.js b/static/app2/js/shopgoodlist.js new file mode 100755 index 0000000..ebefc13 --- /dev/null +++ b/static/app2/js/shopgoodlist.js @@ -0,0 +1,100 @@ +mui.plusReady(function() { + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + var self = plus.webview.currentWebview(); + // //console.log(self); + var shopId = self.id; + $('.add1').on('tap', function() { + JZL.openWindow('addgoods.html', parseInt(shopId)); + }) + //获取商品列表 + var page = 1; + var pageSize = 10; + var isjiazai = 1; + getRecommend(page, pageSize); + + function getRecommend(page, pageSize) { + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + recommenddata.shopId = shopId + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shops/getGoodsList'), recommenddata, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + if (data.status == 1) { + var html = ''; + var status = ''; + var data = data.data; + var status = ""; + if ('' == data.Rows) { + $('.mui-scroll').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + // //console.log(this.goodsStatus); + if (0 == this.goodsStatus) { + status = "等待审核" + } + if (1 == this.goodsStatus) { + status = "已上架" + } + if (-1 == this.goodsStatus) { + status = "已拒绝" + } + html += '<div class="row shadown_wai" data-spec="' + this.isSpec + '" data-sale="' + this.isSale + + '"><div class="left"><img src="' + hyhImgUrl(this.goodsImg) + + '" alt=""></div><div class="center"><div><h4>' + this.goodsName + '</h4></div><div><span>价格:</span><span>' + + this.shopPrice + + '</span></div></div><div class="right"><div><p>' + status + + '</p></div><div class="oper"><span class="bj" data-id="' + + this.goodsId + '"><img src="../img/bianji.png"></span><span class="del" data-id="' + this.goodsId + + '"><img src="../img/delete.png"></span></div></div></div>' + }) + $('.con').append(html); + } else { + mui.alert(data.msg) + } + isjiazai = 1; + }) + } + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pageSize); + } + } + }) + var goodsId = ""; + var isSpec = ""; + $('.con').on('tap', '.bj', function() { + goodsId = $(this).attr('data-id') + isSpec = $(this).parent().parent().parent().attr("data-spec") + isSale = $(this).parent().parent().parent().attr("data-sale") + JZL.openWindow('addgoods.html', parseInt(shopId), { + goodsId: goodsId, + isSpec: isSpec, + isSale: isSale + }); + }) + $('.con').on('tap', '.del', function() { + goodsId = $(this).attr('data-id') + if (confirm('确认删除?')) { + JZL.ajax(qlgUrl("app/shops/delGoods"), { + shopId: shopId, + goodsId: goodsId + }, function() { + $(this).parent().parent().parent().remove(); + location.reload() + }) + } + }) +}) diff --git a/static/app2/js/shoppingcart.js b/static/app2/js/shoppingcart.js new file mode 100755 index 0000000..8a72424 --- /dev/null +++ b/static/app2/js/shoppingcart.js @@ -0,0 +1,586 @@ +var num = 1; +var isOver = 1; +$('.mui-action-back').show(); + +function getMsg(pageNum, pagesizeNum) { + + var data_msg = { + page: pageNum ? pageNum : 1, + pagesize: pagesizeNum ? pagesizeNum : 10 + } + + if (isOver == 0) { + return; + } else { + isOver = 0; + } + mui.ajax(qlgUrl('app/Articles/headLine'), { + + // mui.ajax(kxUrl('app/Articles/headLine'), { + data: data_msg, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + var html = ''; + data = data.data; + if (data.Rows == '') { + if (pageNum == 1) { + $('.recommend_con').html( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } else if (pageNum > 1) { + $('.recommend_con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px; margin-top:10px">没有更多内容</p>'); + } + + isOver = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none">满减</span></div><div class="rcb_bottom" style="display:none"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (pageNum == 1) { + $('.recommend_con').html(html); + } else if (pageNum > 1) { + $('.recommend_con').append(html); + } + $('.recommend_title').css('display', 'block'); + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + isOver = 1; + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + +} + + + +mui.plusReady(function() { + // var scroll = mui('.mui-scroll-wrapper').scroll({ + // deceleration: 0.002 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006 + // }); + window.addEventListener('refresh', function(e) { + location.reload(); + }) + getMsg(num, 10); + + function getCost() { + var cost = 0; + $('.check2').each(function() { + if ($(this).children().hasClass('check_1')) { + + cost += ((+$(this).siblings('.b_con_r1').children('.bz').children('.cost').children('o').html()) * (+$(this).siblings( + '.b_con_r1').children('.bz').children('.num').children('o').html())) + } + }) + + $('.js_r span j').html('¥' + cost.toFixed(2)); + } + + function isChecks() { + + $('.check1').each(function() { + var isChecks = 1; + $(this).parent().siblings().children().find('.checks').each(function() { + if ($(this).hasClass('check_0')) { + isChecks = 0; + } + }) + if (isChecks == 0) { + $(this).children().removeClass('check_1').addClass('check_0'); + } else { + $(this).children().removeClass('check_0').addClass('check_1'); + } + }) + + } + mui.ajax(qlgUrl('app/carts/index'), { + // mui.ajax(hyhUrl('app/carts/index'), { + data: {}, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if (data.status == 1) { + data = data.data; + var html = ''; + $('header').html('购物车(' + data.all_carts_num + ')'); + var allids = []; + $.each(data.carts, function() { + var ids = []; + + $.each(this.list, function() { + ids.push(this.cartId); + allids.push(this.cartId); + }); + var idsStr = ids.join(','); + html += '<div class="block"><div class="b_title clearfix"><div class="check1" data-idsStr="' + idsStr + + '"><div class="checks check_0"></div></div><img src="../img/icon_shop.png" /><div class="b_link"><a href="#" data-shopId="' + + this.shopId + '">' + this.shopName + + '</a></div><img style="display:none;" src="../img/icon_right.png" /><div class="btn_bj">编辑</div></div><div class="bcon">'; + $.each(this.list, function() { + + html += '<div class="b_con shadown_wai clearfix"><div class="check2" data-cartId="' + this.cartId + + '" data-cartNum="' + this.cartNum + '" data-isCheck="' + this.isCheck + + '"><div class="checks check_0"></div></div><img class="s_img" src="' + hyhImgUrl(this.goodsImg) + + '" /><div class="b_con_r1" data-goodsId="' + this.goodsId + '" style="display: block;"><p class="p1">' + + this.goodsName + '</p><p class="p2">'; + $.each(this.specNames, function() { + html += this.catName + ':' + this.itemName + ';'; + }); + var price; + if (this.specPrice != null) { + price = this.specPrice; + } else { + price = this.shopPrice; + } + html += '</p><div class="bz clearfix"><span class="cost">¥<o>' + price + + '</o>&nbsp;&nbsp;</span><del stye="display:none;" class="oldcost">¥' + this.marketPrice + + '</del><span class="num">×<o>' + this.cartNum + + '</o></span></div></div><div class="b_con_r2 clearfix" style="display: none;"><div class="b_con_r2_l"><div class="changenum clearfix" data-cartId="' + + this.cartId + '"><img class="jian" src="../img/jian.png" /><input type="number" name="" id="" value="' + + this.cartNum + + '" /><img class="jia" src="../img/jia.png" /></div></div><div class="b_con_r2_r"><div class="b_con_r2_del" data-cartId="' + + this.cartId + '">删除</div></div></div></div>'; + }); + + html += '</div></div>'; + + }); + var allIdsStr = allids.join(','); + + $('.con_').html(html) + $('.check').attr('data-allIdsStr', allIdsStr); + $('.checks').each(function() { + if ($(this).parent().attr('data-isCheck') == '1') { + $(this).removeClass('check_0').addClass('check_1'); + } + }) + getCost(); + isChecks(); + } else { + mui.alert(data.msg) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + $('.con_').on('tap', '.b_link', function() { + var shopId = $(this).children('a').attr('data-shopId'); + var url = 'storeout.html'; + if (shopId == 1) { + // url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con_').on('tap', '.b_con_r1', function() { + var data_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.check').on('tap', function() { + var isCheck; + var ids = $(this).attr('data-allIdsStr'); + if ($('.check').children('.checks').hasClass('check_0')) { + $('.check').children('.checks').removeClass('check_0').addClass('check_1'); + $('.check1').children('.checks').removeClass('check_0').addClass('check_1'); + $('.check2').children('.checks').removeClass('check_0').addClass('check_1'); + isCheck = 1; + } else { + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + $('.check1').children('.checks').removeClass('check_1').addClass('check_0'); + $('.check2').children('.checks').removeClass('check_1').addClass('check_0'); + isCheck = 0; + } + getCost(); + isChecks(); + mui.ajax(qlgUrl('app/carts/batchChangeCartGoods'), { + data: { + ids: ids, + isCheck: isCheck + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }); + + $('.con_').on('tap', '.check1', function(e) { + e.stopPropagation(); + var that = $(this); + var isCheck; + var ids = $(this).attr('data-idsStr'); + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + if (that.children('.checks').hasClass('check_0')) { + isCheck = 1; + that.children('.checks').removeClass('check_0').addClass('check_1'); + that.parent().siblings().children().find('.check2').children('.checks').removeClass('check_0').addClass( + 'check_1'); + } else { + isCheck = 0; + that.children('.checks').removeClass('check_1').addClass('check_0'); + that.parent().siblings().children().find('.check2').children('.checks').removeClass('check_1').addClass( + 'check_0'); + } + getCost(); + isChecks(); + that.attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/carts/batchChangeCartGoods'), { + data: { + ids: ids, + isCheck: isCheck + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data); + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }); + + $('.con_').on('tap', '.check2', function(e) { + ////console.log() + e.stopPropagation(); + var isCheck; + var cartId = $(this).attr('data-cartId'); + var that = $(this); + var buyNum = $(this).attr('data-cartNum'); + $('.check').children('.checks').removeClass('check_1').addClass('check_0'); + if ($(this).children().hasClass('check_0')) { + $(this).parent().parent().siblings().children('.check1').children('.checks').removeClass('check_1').addClass( + 'check_0'); + $(this).children('.checks').removeClass('check_0').addClass('check_1'); + isCheck = 1; + } else { + $(this).children('.checks').removeClass('check_1').addClass('check_0'); + isCheck = 0; + } + getCost(); + isChecks() + $(this).attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/carts/changeCartGoods'), { + data: { + id: cartId, + isCheck: isCheck, + buyNum: buyNum + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data, 1); + that.removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }); + + $('.con_').on('tap', '.btn_bj', function(e) { + e.stopPropagation() + if ($(this).html() == '编辑') { + $(this).html('完成'); + $(this).parent().siblings().children().find('.b_con_r1').css('display', 'none'); + $(this).parent().siblings().children().find('.b_con_r2').css('display', 'block'); + } else { + $(this).html('编辑'); + $(this).parent().siblings().children().find('.b_con_r2').css('display', 'none'); + $(this).parent().siblings().children().find('.b_con_r1').css('display', 'block'); + var inputArr = $(this).parent().siblings().find('input') + + $(this).parent().siblings().find('.num').each(function(num) { + $(this).html('×<o>' + inputArr.eq(num).val() + '</o>'); + }) + + } + // //console.log($(this).parent().siblings().find('.commodity_num')) + // //console.log($(this).parent().siblings().find('input')); + if ($(this).html() == '完成') { + return; + } + getCost() + }) + + $('.con_').on('tap', '.jia', function() { + // //console.log($(this).siblings('input').val()) + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).siblings('input').val() + 1; + if (num <= 0) { + mui.alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/carts/changeCartGoods'), { + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + $('.con_').on('tap', '.jian', function() { + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).siblings('input').val() - 1; + if (num <= 0) { + mui.alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/carts/changeCartGoods'), { + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + $('.con_').on('blur', 'input', function() { + var that = $(this); + var cartId = $(this).parent().attr('data-cartId') + var num = +$(this).val(); + if (num <= 0) { + mui.alert('购买数最小为1!'); + return; + } + $('.jia').attr('disabled', 'disabled'); + $('.jian').attr('disabled', 'disabled'); + $('input').attr('disabled', 'disabled'); + mui.ajax(qlgUrl('app/carts/changeCartGoods'), { + data: { + id: cartId, + buyNum: num + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data, 1); + that.siblings('input').val(num); + $('.jia').removeAttr('disabled'); + $('.jian').removeAttr('disabled'); + $('input').removeAttr('disabled'); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + + $('.con_').on('tap', '.b_con_r2_del', function() { + var cartId = $(this).attr('data-cartId'); + + if (confirm('确定删除?')) { + mui.ajax(hyhUrl('app/carts/delCart'), { + data: { + id: cartId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否;登录成功; + var data = toJson(data, 1); + location.reload(); + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + } + }) + + // $('.changeclass').on('tap', '.selectclass', function() { + // $('.mui-backdrop').show(); + // }) + + //选择类型 + // $('.cclass1').on('tap', '.block', function() { + // $(this).addClass('on').siblings().removeClass('on'); + // $(this).parent().attr('data-class', $(this).html()); + // }) + + // $('.closecclass').on('tap', function() { + // $('.mui-backdrop').css('display', 'none'); + // }) + + // $('.ensure').on('tap', function() { + // $('.mui-backdrop').css('display', 'none'); + // }) + + mui('.js').on('tap', '.btn_tj', function() { + var check_length = $('.check_1').length; + if (check_length == 0) { + mui.alert('请选择商品结算!'); + return; + } + mui.openWindow({ + url: 'confirmOrder.html', + id: 'confirmOrder.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_id: data_id + + type: 0 + + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + setTimeout(function() { + JZL.closeWindow(plus.webview.currentWebview().id); + }, 1000) + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isOver == 1) { + num++; + getMsg(num, 10); + } + } + }) +}) diff --git a/static/app2/js/shopsList.js b/static/app2/js/shopsList.js new file mode 100755 index 0000000..874b210 --- /dev/null +++ b/static/app2/js/shopsList.js @@ -0,0 +1,148 @@ +var page = 1; +var pagesize = 10; +var condition = 1; +var isjiazai = 1; +var desc = 0; + + +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + keyword = self.data_keyword; + goodsType = self.goodsType ? self.goodsType :'' + function getData(page, pagesize, condition, keyword, desc,goodsType) { + var data_set = { + page: page, + pagesize: pagesize, + condition: condition, + keyword: keyword, + desc: desc, + goodsType:goodsType + } + mui.ajax(qlgUrl('app/shops/pageQuery'), { + + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + + var data = toJson(data); + data = data.data; + var html = ''; + if (data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多店铺</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="block shadown_wai"><div class="b_title" data-shopId="' + this.shopId + + '"><img class="b_img" src="' + hyhImgUrl(this.shopImg) + '" /><p class="storename">' + this.shopName + + '</p><p class="time">' + this.shopCompany + + '</p><div class="btn_gz">进店</div></div><div class="b_con clearfix">'; + + $.each(this.goods, function() { + html += '<div data-goodId="' + this.goodsId + '" data-goodsType="'+goodsType+'" class="bc_img"><img src="' + hyhImgUrl(this.goodsImg) + + '" /><p>¥' + this.shopPrice + '</p></div>'; + }); + html += '</div></div>' + }); + if (page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + isjiazai = 1; + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // alert(type); + } + }); + } + + getData(page, pagesize, 1, keyword, 0, goodsType ) + mui('.con').on('tap', '.b_title', function() { + var shopId = $(this).attr('data-shopId'); + var url = 'storeout.html'; + if (shopId == 1) { + // url='self_shop.html' + } + mui.openWindow({ + url: url, + id: url + shopId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + shopId: shopId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.bc_img', function() { + var goodId = $(this).attr('data-goodId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + goodId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: goodId, + goodsType:goodsType + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + isjiazai = 0; + page++; + getData(page, pagesize, 1, keyword, 0) + } + } + }) +}) diff --git a/static/app2/js/shopsetting.js b/static/app2/js/shopsetting.js new file mode 100755 index 0000000..1d2e3f1 --- /dev/null +++ b/static/app2/js/shopsetting.js @@ -0,0 +1,19 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + //console.log(self); + var shopId=self.id; + var shopIdObj = { + id: self.id + } + $('.row').on("tap", function() { + + var URL = $(this).attr("data-url"); + //console.log(URL); + // JZL.openWindow('income-details.html', 'income-details.html') + JZL.openWindow(URL + '.html',parseInt(shopId)) + + }) + + +}) diff --git a/static/app2/js/start.js b/static/app2/js/start.js new file mode 100755 index 0000000..2ae9c0e --- /dev/null +++ b/static/app2/js/start.js @@ -0,0 +1,274 @@ +function init(data) { + ////console.log(data.apk_version) + // //console.log(localStorage.getItem('jsUrl')) + apk_version = data.apk_version; + apkUrl = data.apk_down_url; + iosUrl = data.ios_down_url; + var must_update = data.must_update; + var ios_must_update = data.ios_must_update; + mui.plusReady(function() { + plus.navigator.setStatusBarStyle('dark'); + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + ver = inf.version; + var client; + var ua = navigator.userAgent.toLowerCase(); + if(/iphone|ipad|ipod/.test(ua)) { //苹果手机 + $.ajax({ + type: "get", + dataType: 'json', + url: data.update_url, //获取当前上架APPStore版本信息 + data: { + id: data.ios_appid //APP唯一标识ID + }, + contentType: 'application/x-www-form-urlencoded;charset=UTF-8', + success: function(data) { + + if(data.results[0].version > ver) { + if(ios_must_update == 0) { + if(confirm("发现新版本:V" + data.results[0].version + "是否更新")) { + document.location.href = iosUrl; //上新APPStore下载地址 + } + } else { + mui.alert("发现新版本:V" + data.results[0].version + "是否更新") + document.location.href = iosUrl; //上新APPStore下载地址 + } + + } else { + + } + } + }); + } else if(/android/.test(ua)) { + + if(apk_version > ver) { + if(must_update == 0) { + if(confirm("发现新版本:V" + apk_version + "是否更新")) { + var dtask = plus.downloader.createDownload(apkUrl, {}, function(d, status) { + if(status == 200) { + plus.nativeUI.toast("正在准备环境,请稍后!"); + sleep(1000); + var path = d.filename; //下载apk + plus.runtime.install(path); // 自动安装apk文件 + } else { + mui.alert('版本更新失败:' + status); + } + }); + dtask.start(); + } + } else { + if(confirm("发现新版本:V" + apk_version + "是否更新")) { + var dtask = plus.downloader.createDownload(apkUrl, {}, function(d, status) { + if(status == 200) { + plus.nativeUI.toast("正在准备环境,请稍后!"); + sleep(1000); + var path = d.filename; //下载apk + plus.runtime.install(path); // 自动安装apk文件 + } else { + mui.alert('版本更新失败:' + status); + } + }); + dtask.start(); + } else { + plus.runtime.quit(); + } + } + + } else { + // //console.log('当前版本号已是最新'); + return; + } + } + + }) + }) +}; + +function jumpPage(ipxSizeBottom) { + //跳转页面 + + var bSize = 50 + (+ipxSizeBottom) + 'px'; + var subpages = ['templete/home.html', 'templete/shops.html', '', 'templete/zhuweiba.html', + 'templete/my.html' + ]; + var subpage_style = { + top: '0px', + bottom: bSize, + scrollIndicator: 'none' + }; + var aniShow = {}; //动画显示 + //首次启动切滑效果 + mui.plusReady(function() { + //刷新 + window.addEventListener('refresh', function(e) { + var my = plus.webview.getWebviewById('templete/my.html'); //触发父页面的自定义事件(refresh),从而进行刷新 + var zhuweiba = plus.webview.getWebviewById('templete/zhuweiba.html'); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(my, 'refresh'); + mui.fire(zhuweiba, 'refresh'); + }) + // launchScreen(); + plus.screen.lockOrientation("portrait-primary"); + // plus.navigator.setStatusBarStyle('dark'); + // //console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + for (var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if (i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + }); + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + mui('.mui-bar-tab').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + if (targetTab == activeTab) { + // var targetTab = plus.webview.getWebviewById(targetTab); + // mui.fire(targetTab, 'refresh'); + return; + } + //更换标题 + // title.innerHTML = this.querySelector('.mui-tab-label').innerHTML; + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if (mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + if (targetTab == 'templete/home.html') {} + if (targetTab == 'templete/shops.html') { + var targetTab = plus.webview.getWebviewById(targetTab); + mui.fire(targetTab, 'refresh'); + } + + if (targetTab == 'templete/zhuweiba.html') { + var targetTab = plus.webview.getWebviewById(targetTab); + mui.fire(targetTab, 'refresh'); + } + if (targetTab == 'templete/my.html') { + var targetTab = plus.webview.getWebviewById(targetTab); + mui.fire(targetTab, 'refresh'); + var token = localStorage.getItem("token"); + if (!token) { + mui.openWindow({ + url: 'templete/login.html', + id: 'templete/login.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: {}, + createNew: false, + show: {}, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: {} + } + }) + } + } + }); +} + +function nav(num) { +//console.log(num); + $('.mui-tab-item span .img').each(function(a) { + + if (a == 2) { + + } else if (num == a && a != 2) { + // //console.log(a); + $(this).attr('src', 'http://img.zgqlg.com.cn/static/app2/img/nav_' + a + '_1.png?version='+localStorage.getItem('version')); + } else { + $(this).attr('src', 'http://img.zgqlg.com.cn/static/app2/img/nav_' + a + '_0.png?version='+localStorage.getItem('version')); + } + }) + +} + +$('.mui-bar').on('tap', '.mui-tab-item', function(e) { + var num = $(this).attr('data-num'); + if (num == 2) { + $('.nav_in').addClass('shun'); + $('.nav_out').addClass('ni'); + } else { + $('.nav_in').removeClass('shun'); + $('.nav_out').removeClass('ni'); + } + nav(num); + +}) +document.addEventListener('plusready', function() { + checkArguments(); +}, false); +// 判断启动方式 +function checkArguments() { + var args = plus.runtime.arguments; + if (args) { + // 处理args参数,如打开新页面等 + var url; + var id; + var datago = {}; + var arrgo = args.slice(args.indexOf('//') + 2).split(': '); + // //console.log(args.slice(args.indexOf('//')+2).split(':')) + if (arrgo[0] == 'goods_id') { + url = 'details.html'; + id = arrgo[1]; + datago = { + data_id: arrgo[1] + } + } else if (arrgo[0] == 'shop_id') { + url = 'storeout.html'; + id = arrgo[1]; + datago = { + shopId: arrgo[1] + } + } else { + return; + } + + mui.openWindow({ + url: 'templete/' + url, + id: url + id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: datago, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: {} + } + }) + } +} + + +// 处理从后台恢复 +document.addEventListener('newintent', function() { + checkArguments(); +}, false); diff --git a/static/app2/js/store_activity.js b/static/app2/js/store_activity.js new file mode 100755 index 0000000..2ba219e --- /dev/null +++ b/static/app2/js/store_activity.js @@ -0,0 +1,67 @@ +$('.con').html(''); +var shopId = localStorage.getItem('shopId') +mui.plusReady(function() { + mui.ajax(hyhUrl('app/Shops/getReward'), {  + data: { + shopId: shopId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = ''; + if(data.reward) { + $.each(data.reward.Rows, function() { + html += '<div class="block"><div class="b_title"><img class="img" src="' + hyhImgUrl(this.goodsImg) + '" /><img class="clock" src="../img/icon_clock.png" alt="" /><p class="p1">' + this.startDate + '至' + this.endDate + '</p><p class="p2">' + this.rewardTitle + '</p></div><div class="b_con con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + ' </p><p class="p4">¥' + this.shopPrice + '</p></div></div>'; + html += '<div class="block shadown_wai"><div class="b_title"><img src="../img/activity_jt.png" class="ac_jt"/><p class="p2">' + this.rewardTitle + '</p></div><div class="b_con con_goods" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><p class="p3">' + this.goodsName + '</p><p class="p4">¥' + this.shopPrice + '</p><div class="manjian">满减</div><div class="muji">可用木吉抵扣20%货款</div></div></div>'; + }); + } + + $('.con').html(html); + } else { + // console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + }); + $('.con').on('tap', '.con_goods', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/store_class.js b/static/app2/js/store_class.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/store_commodity.js b/static/app2/js/store_commodity.js new file mode 100755 index 0000000..cd5fe59 --- /dev/null +++ b/static/app2/js/store_commodity.js @@ -0,0 +1,305 @@ +$('.recommend_con').html(''); +var msort = 1; +var shopId = localStorage.getItem('shopId'); +var nowpage = 1; +var condition = 1; +var desc = 0; +var pagesize = 5; +var isload = false; +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + // window.location.reload(); + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + nowpage += 1 + mui.ajax(qlgUrl('app/Shopping/getShopIndexGoodsList'), { + data: { + page: nowpage, + PerPage: 10, + shopId: shopId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + + // var data = toJson(data, 1); + if (data.status == 1) { + //console.log(data); + + var html = ''; + var data = data.data; + if (data.Rows == '') { + // $('.recommend_con').append( + // '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + $('.mui-pull-caption').html("没有更多商品") + + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + hyhImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title">' + this.goodsName + + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '</span><span>人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>' + this.discountRate + + '%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + $('#recommend_con_').append(html); + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + mui.alert(errorThrown); + } + }); + // //console.log(order_class) + // mui.ajax(hyhUrl('app/Shops/getShopGoods'), { + // + // data: { + // page: count, + // shopId: shopId, + // pageSize: 10, + // msort: condition, + // mdesc: desc + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // // //console.log(data.data.goodsFavoritesNum) + // // //console.log(data.data.Rows) + // + // var data = toJson(data); + // data = data.data; + // var html = ''; + // $.each(data.Rows, function() { + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="'+this.goodsId+'"><img class="rcb_img" src="'+ectImgUrl(this.goodsImg)+'" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;">自营</span>'+this.goodsName+'</div><div class="rcb_pay">¥'+this.shopPrice+'<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" style="display:none;"src="../img/icon_sscl.png" alt="" /></div>' + // }); + // $('.recommend_con').append(html); + // + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var costnum = 0; + getRecommend(nowpage, pagesize) + $('.commoditylistnav').on('tap', '.nav_block', function() { + page = 1; + count = 1; + $(this).addClass('on').siblings().removeClass('on'); + condition = $(this).attr('data-condition'); + if ($('#cost_btn').hasClass('on')) { + costnum += 1; + if (costnum % 2 == 1) { + $('#cost_btn').html('价格 <img src="../img/cost3.png"/>'); + desc = 0; + } else if (costnum % 2 == 0) { + $('#cost_btn').html('价格 <img src="../img/cost2.png"/>'); + desc = 1; + } + } else { + $('#cost_btn').html('价格 <img src="../img/cost1.png"/>') + costnum = 0; + desc = 1 + } + // mui.ajax(hyhUrl('app/Shops/getShopGoods'), { + // data: { + // shopId: shopId, + // pageSize: 10, + // page: 1, + // msort: condition, + // mdesc: desc + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data); + // data = data.data; + // var html = ''; + // $.each(data.Rows, function() { + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="'+this.goodsId+'"><img class="rcb_img" src="'+ectImgUrl(this.goodsImg)+'" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;">自营</span>'+this.goodsName+'</div><div class="rcb_pay">¥'+this.shopPrice+'<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" style="display:none;"src="../img/icon_sscl.png" alt="" /></div>' + // }); + // $('.recommend_con').html(html); + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + }) + // mui.ajax(hyhUrl('app/Shops/getShopGoods'), { + // data: { + // shopId: shopId, + // pageSize: 10, + // page: 1, + // msort: 1, + // mdesc: 0 + // }, + // dataType: 'json', //服务器返回json格式数据 + // type: 'post', //HTTP请求类型 + // timeout: 10000, //超时时间设置为10秒; + // success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data); + // data = data.data; + // var html = ''; + // $.each(data.Rows, function() { + // html += '<div class="recommend_con_block shadown_wai" data-goodsId="'+this.goodsId+'"><img class="rcb_img" src="'+ectImgUrl(this.goodsImg)+'" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;">自营</span>'+this.goodsName+'</div><div class="rcb_pay">¥'+this.shopPrice+'<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" style="display:none;"src="../img/icon_sscl.png" alt="" /></div>' + // }); + // $('.recommend_con').html(html); + // $('.recommend_con_block .img').height($('.recommend_con_block .img').width()); + // + // // $('.recommend_con_block').height($('.recommend_con_block').width() * 266 / 198); + // }, + // error: function(xhr, type, errorThrown) { //异常处理; + // // mui.alert(type); + // } + // }); + $('.recommend_con').on('tap', '.recommend_con_block', function() { + var good_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + + + function getRecommend(nowpage, pagesize) { + var recommenddata = { + page: nowpage ? nowpage : 1, + PerPage: pagesize ? pagesize : 10 + } + recommenddata.shopId = shopId + //console.log(recommenddata); + if (isload == true) { + return; + } + isload = true + mui.ajax(qlgUrl('app/Shopping/getShopIndexGoodsList'), { + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + console.log(recommenddata); + + // var data = toJson(data, 1); + if (data.status == 1) { + console.log(data); + + var html = ''; + var data = data.data; + if (data.Rows == '') { + $('.recommend_con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + + return; + } + $.each(data.Rows, function() { + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + hyhImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title">' + this.goodsName + + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '</span><span>人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;&nbsp;</span><span>' + this.discountRate + + '%</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + if (nowpage == 1) { + //console.log(222); + $('#recommend_con_').html(html); + } else { + $('#recommend_con_').append(html); + } + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + } else { + mui.alert(data.msg) + } + isload = false + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + } +}) + +setInterval(function() { + $('.recommend_con_block img').height($('.recommend_con_block img').width()); + // $('.recommend_con_block').height($('.recommend_con_block').width() * 266 / 198); +}, 100) diff --git a/static/app2/js/store_home.1.js b/static/app2/js/store_home.1.js new file mode 100755 index 0000000..b907f33 --- /dev/null +++ b/static/app2/js/store_home.1.js @@ -0,0 +1,306 @@ +$('.recommend_title img').eq(0).attr('src', hyhImgUrl('static/app2/img/goods_title.png')); +$('.recommend_title img').eq(1).attr('src', hyhImgUrl('static/app2/img/coupon_title.png')); +$('.recommend_title img').eq(0).css('display', 'none'); +$('.recommend_title img').eq(1).css('display', 'none'); +var shopId = localStorage.getItem('shopId'); +mui.plusReady(function() { + // var data = JSON.parse(localStorage.getItem('shop_data')); + // var Intent = plus.android.importClass("android.content.Intent"); + // //console.log(Intent) + // + mui.ajax(ectUrl('app/Shops/getHome'), { + data: { + shopId: shopId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + if (data.status == 1) { + var data = data.data; + if (data.shop.shopAds.length > 0) { + var html = ''; + $.each(data.shop.shopAds, function() { + html += '<div class="swiper-slide"><img src="' + ectImgUrl(this.adImg) + '" /></div>' + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + $('#top_banner').height($('#top_banner').width() * 420 / 715); + $('#top_banner img').height($('#top_banner img').width() * 420 / 715); + } else { + $('#top_banner').remove() + } + + if (data.couponList.coupons.length > 0) { + var html_ = ''; + $.each(data.couponList.coupons, function(num) { + html_ += '<div class="swiper-slide home_yhj" data-couponId="' + this.couponId + '"><img src=" ' + + ectImgUrl('static/app2/img/bg_' + (num % 3 + 1) + '.png') + + '" alt="" /><p class="p1">点击领取</p><p class="p2">满' + this.useMoney + '使用</p><p class="p3">' + this.couponValue + + '</p></div>' + }); + $('#timer_swiper .swiper-wrapper').html(html_); + $('.recommend_title img').eq(0).css('display', 'block'); + var swiper = new Swiper('#timer_swiper', { + slidesPerView: 2.3, + paginationClickable: true, + spaceBetween: 0, + freeMode: true + }); + $('#timer_swiper .swiper-slide img').height($('#timer_swiper .swiper-slide img').width() * 140 / 300); + $('#timer_swiper .swiper-slide').height($('#timer_swiper .swiper-slide').width() * 190 / 300); + } else { + $('.time').css('display', 'none'); + } + + // var html3 = ''; + // $.each(data.shopcats, function() { + // html3 += '<div data-catId="' + this.catId + '" class="l_block">' + this.catName + '</div>'; + // }); + // $('.label').html(html3); + // $('.l_block').each(function(num) { + // if((num + 1) % 4 == 0) { + // $(this).addClass('lbrr'); + // } + // }) + var html4 = ''; + if (data.rec == '') { + $('.recommend_title').eq(1).css('display', 'none'); + } else { + $.each(data.rec, function() { + html4 += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;">自营</span>' + this.goodsName + + '</div><div class="rcb_pay">¥' + this.shopPrice + + '<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" style="display:none;"src="../img/icon_sscl.png" alt="" /></div>' + }); + $('.recommend_con').html(html4); + $('.recommend_title img').eq(1).css('display', 'block'); + $('.rcb_img').height($('.rcb_img').width()) + } + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + //领取优惠券 + $('.time').on('tap', '.home_yhj', function() { + var couponId = $(this).attr('data-couponId'); + mui.ajax(hyhUrl('addon/coupon-Coupons-receive'), { + // headers: { + // "HYH-Token": token + // }, + data: { + couponId: couponId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + var data = toJson(data); + mui.alert(data.msg); + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + $('.recommend_con').on('tap', '.recommend_con_block', function() { + var good_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + localStorage.setItem('shop_data', ''); +}) + +setInterval(function() { + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); +}, 200) + +var scheme = ""; +var arr = []; +var title = {}; +$('.go').on("tap", function() { + if (0 == arr.length) { + //console.log(111) + } + //底部弹出选择地图软件 + plus.nativeUI.actionSheet({ + title: "请选择!", + cancel: "取消", + buttons: arr + }, function(e) { + var title = arr[e.index - 1].title; + // var i1 = new Intent(); + switch (title) { + case "百度地图": + // plus.runtime.openURL( "baidumap://map/direction?origin=latlng:39.98871,116.43234|name:我的位置&destination=40.007623,116.360582&mode=driving&src=webapp.navi.hanguosoft.yinyijianghu", function(error){ alert("打开百度地图失败")}); + launchTest() +// if (plus.os.name == "Android") { +// plus.runtime.launchApplication({ +// pname: "com.android.browser", +// extra: { +// // url: "://map/direction?origin=latlng:33,33|name:我的位置&destination=latlng:43.335,39.966|name:beijing&mode=driving", +// // url:"://map/direction?destination=latlng:33,44|name:geijign&mode=driving&" + // 导航路线方式 +// // "region=武汉" +// +// url:"http://www.html5plus.org" +// +// // url :"baidumap://map/direction?origin=name:对外经贸大学|latlng:39.98871,116.43234&destination=西直门&coord_type=bd09ll&mode=transit" +// // url : "http://api.map.baidu.com/direction?origin=latlng:42.111,111|name:当前位置&destination=latlng:31,111|name:终点&mode=driving&region=中国&output=html" +// } +// }, function(e) { +// alert("Open system default browser failed: " + e.message); +// +// }); +// } else if (plus.os.name == "iOS") { +// plus.runtime.launchApplication({ +// action: "://map/direction?origin=latlng:114,33|name:我的位置&destination=latlng:116.335, 39.966|name:beijing&mode=driving"//"第三方提供的uri" +// }, function(e) { +// alert("Open system default browser failed: " + e.message); +// }); +// } + break; + case "高德地图": + + } + }); + + + +}) +var maps=[{pname:'com.baidu.BaiduMap',action:'baidumap',name:'百度地图'},{pname:'com.autonavi.minimap',action:'iosamap',name:'高德地图'},{pname:'com.google.android.apps.maps',action:'com.google.android.apps.maps',name:'谷歌地图'},{pname:'com.tencent.map',action:'com.google.android.apps.maps',name:'腾讯地图'}] +// checkApp("com.baidu.BaiduMap", "baidumap", "百度地图") +// checkApp("com.autonavi.minimap", "iosamap", "高德地图") +// checkApp("com.google.android.apps.maps", "com.google.android.apps.maps", "谷歌地图") +// 判断地图软件是否安装 +// maps= toJson(maps) +// //console.log(maps) +// $.each(maps,function(i,v){ +// +// var that=this +// +// checkApp(that.pname, that.action, that.name) +// }) +// function checkApp(pn, ac, name) { +// if (plus.runtime.isApplicationExist({ +// pname: pn,//包名 +// action: ac //ios包名 +// })) { +// // //console.log("微信应用已安装"); +// title = { +// title: name +// }; +// arr.push(title) +// } else { +// // //console.log("微信应用未安装"); +// // title={}; +// // arr.push(title) +// +// } +// } + +function launchTest() { + if (plus.os.name == "Android") { + plus.runtime.launchApplication( {pname:"com.baidu.BaiduMap" + ,extra:{url:"://map/direction?origin=name:对外经贸大学|latlng:39.98871,116.43234&destination=西直门&coord_type=bd09ll&mode=transit&sy=3&index=0&target=1&src=andr.baidu.openAPIdemo"}}, function ( e ) { + alert( "Open system default browser failed: " + e.message );}) +// plus.runtime.launchApplication({ +// +// pname: "com.baidu.BaiduMap", +// // pname: "bdapp", +// +// // http://uri.amap.com/navigation?from=" + fromLongitude + "," + fromLatitude + "&to="+ longitude + "," + latitude + "&mode=car&src=nyx_super; +// +// extra: { +// url:"baidumap://map/bikenavi?origin=39.98871,116.43234&destination=39.91441,116.40405&coord_type=bd09ll&src=andr.baidu.openAPIdemo" +// // url:"bdapp://map/direction?destination=latlng:31,111|name:终点&mode=driving&region=中国&src=andr.baidu.openAPIdemo" +// // url:"http://baidu.com" +// // url:"com.baidu.BaiduMap://map/direction?origin=中关村&destination=五道口&mode=driving&region=北京 " +// // url: "://map/direction?origin=latlng:114,33|name:我的位置&destination=latlng:116.335,39.966|name:beijing&mode=driving" +// } +// }, function(e) { +// alert("Open system default browser failed: " + e.message); +// +// }); + } else if (plus.os.name == "iOS") { + plus.runtime.launchApplication({ + action: "第三方提供的uri" + }, function(e) { + alert("Open system default browser failed: " + e.message); + }); + } +} + + launchTest() + + + + + + +mui('.gothere').on("tap", ".gt_con", function(e) { + var idx = $(this).index(); + var html = ''; + + switch (idx) { + case 0: + + break; + case 1: + + break; + case 2: + // $('.gt_con_con1').css('display','none') + + $('.gt_con_con').toggle() + html = + '<div class="row shadown_wai"><div class="name"><label class="label-idx" for="">姓名:</label><label class="label-val" for="">张三</label></div><div class="name"><label class="label-idx" for="">电话:</label><label class="label-val" for=""><a href="tel:13482378262">13482378262</label></div></div>' + $('.row .name').css("width", "60%") + $('.gt_con_con').html(html) + break; + + } +}) diff --git a/static/app2/js/store_home.js b/static/app2/js/store_home.js new file mode 100755 index 0000000..71a50ab --- /dev/null +++ b/static/app2/js/store_home.js @@ -0,0 +1,351 @@ +$('.recommend_title img').eq(0).attr('src', hyhImgUrl('static/app2/img/goods_title.png')); +$('.recommend_title img').eq(1).attr('src', hyhImgUrl('static/app2/img/coupon_title.png')); +$('.recommend_title img').eq(0).css('display', 'none'); +$('.recommend_title img').eq(1).css('display', 'none'); + var shopId = localStorage.getItem('shopId'); + var shopLat = localStorage.getItem('shopLat'); + var shopLng = localStorage.getItem('shopLng'); + var shopName = localStorage.getItem('shopName'); + var phone = localStorage.getItem('phone'); + var userName = localStorage.getItem('userName'); +mui.plusReady(function() { + // var data = JSON.parse(localStorage.getItem('shop_data')); +var self = plus.webview.currentWebview(); + var userLat=''; + var userLng=''; + var scheme = ""; + var arr = []; + var title = {}; + var shopAddress=""; + // 加载地图 + getLocation(function(data) { + // console.log(data); + if (1 == data.status) { + $('#lng').val(data.lng); + $('#lat').val(data.lat); + getMap(shopLng, shopLat) + // //console.log(JSON.stringify(data)); + } else { + mui.alert(data.errStr); + return; + } + }); + $.getJSON('http://api.map.baidu.com/geocoder/v2/?ak=Zm7kae5pzZogp8a0uwIOlyyz&callback=?&location='+shopLat+','+shopLng+'&output=json&pois=1',function(res){ + // //console.log(res); + //addressComponent => {city: "广州市", district: "天河区", province: "广东省", street: "广州大道", street_number: "中922号-之101-128"} + // //console.log(res.result.addressComponent.city) + $(".shopAddress").html(res.result.formatted_address); + // $("#location-r").html(res.result.addressComponent.city); + + }) +// $.getScript('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js',function(){ +// alert(remote_ip_info.country);//国家 +// alert(remote_ip_info.province);//省份 +// alert(remote_ip_info.city);//城市 +// }); +// 获取用户地址 + +plus.geolocation.getCurrentPosition(function (p) { + //console.log(p.coords.latitude); + //console.log(p.coords.longitude); +userLat=p.coords.latitude; +userLng=p.coords.longitude +},function (err) { + +}) +// mui.ajax(ectUrl('app/Shops/getHome'), { +// data: { +// shopId: shopId +// }, +// dataType: 'json', //服务器返回json格式数据 +// type: 'post', //HTTP请求类型 +// timeout: 10000, //超时时间设置为10秒; +// success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; +// +// if (data.status == 1) { +// var data = data.data; +// if (data.shop.shopAds.length > 0) { +// var html = ''; +// $.each(data.shop.shopAds, function() { +// html += '<div class="swiper-slide"><img src="' + ectImgUrl(this.adImg) + '" /></div>' +// }); +// $('#top_banner .swiper-wrapper').html(html); +// var swiper = new Swiper('#top_banner', { +// pagination: '#top_banner_pagination', +// spaceBetween: 0, +// loop: true, +// autoplay: 3500, +// autoplayDisableOnInteraction: false +// }); +// $('#top_banner').height($('#top_banner').width() * 420 / 715); +// $('#top_banner img').height($('#top_banner img').width() * 420 / 715); +// } else { +// $('#top_banner').remove() +// } +// +// if (data.couponList.coupons.length > 0) { +// var html_ = ''; +// $.each(data.couponList.coupons, function(num) { +// html_ += '<div class="swiper-slide home_yhj" data-couponId="' + this.couponId + '"><img src=" ' + +// ectImgUrl('static/app2/img/bg_' + (num % 3 + 1) + '.png') + +// '" alt="" /><p class="p1">点击领取</p><p class="p2">满' + this.useMoney + '使用</p><p class="p3">' + this.couponValue + +// '</p></div>' +// }); +// $('#timer_swiper .swiper-wrapper').html(html_); +// $('.recommend_title img').eq(0).css('display', 'block'); +// var swiper = new Swiper('#timer_swiper', { +// slidesPerView: 2.3, +// paginationClickable: true, +// spaceBetween: 0, +// freeMode: true +// }); +// $('#timer_swiper .swiper-slide img').height($('#timer_swiper .swiper-slide img').width() * 140 / 300); +// $('#timer_swiper .swiper-slide').height($('#timer_swiper .swiper-slide').width() * 190 / 300); +// } else { +// $('.time').css('display', 'none'); +// } +// +// // var html3 = ''; +// // $.each(data.shopcats, function() { +// // html3 += '<div data-catId="' + this.catId + '" class="l_block">' + this.catName + '</div>'; +// // }); +// // $('.label').html(html3); +// // $('.l_block').each(function(num) { +// // if((num + 1) % 4 == 0) { +// // $(this).addClass('lbrr'); +// // } +// // }) +// var html4 = ''; +// if (data.rec == '') { +// $('.recommend_title').eq(1).css('display', 'none'); +// } else { +// $.each(data.rec, function() { +// html4 += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + +// '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + +// '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;">自营</span>' + this.goodsName + +// '</div><div class="rcb_pay">¥' + this.shopPrice + +// '<span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img class="icon_icon" style="display:none;"src="../img/icon_sscl.png" alt="" /></div>' +// }); +// $('.recommend_con').html(html4); +// $('.recommend_title img').eq(1).css('display', 'block'); +// $('.rcb_img').height($('.rcb_img').width()) +// } +// } else { +// mui.alert(data.msg) +// } +// }, +// error: function(xhr, type, errorThrown) { //异常处理; +// // mui.alert(type); +// } +// }); + //领取优惠券 + $('.time').on('tap', '.home_yhj', function() { + var couponId = $(this).attr('data-couponId'); + mui.ajax(hyhUrl('addon/coupon-Coupons-receive'), { + // headers: { + // "HYH-Token": token + // }, + data: { + couponId: couponId + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + + var data = toJson(data); + mui.alert(data.msg); + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + }) + $('.recommend_con').on('tap', '.recommend_con_block', function() { + var good_id = $(this).attr('data-goodsId'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + localStorage.setItem('shop_data', ''); + + + setInterval(function() { + $('.cnxh_block img').height($('.cnxh_block img').width()); + $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + }, 200) + + + + + + $('.go').on("tap", function() { + isHasApp() + }) + + + var maps = [{ + pname: 'com.baidu.BaiduMap', + action: 'baidumap', + name: '百度地图' + }, { + pname: 'com.autonavi.minimap', + action: 'iosamap', + name: '高德地图' + } + // , { + // pname: 'com.google.android.apps.maps', + // action: 'com.google.android.apps.maps', + // name: '谷歌地图' + // } + // , { + // pname: 'com.tencent.map', + // action: 'com.google.android.apps.maps', + // name: '腾讯地图' + // }, + ] + // checkApp("com.baidu.BaiduMap", "baidumap", "百度地图") + // checkApp("com.autonavi.minimap", "iosamap", "高德地图") + // checkApp("com.google.android.apps.maps", "com.google.android.apps.maps", "谷歌地图") + // 判断地图软件是否安装 + // maps= toJson(maps) + // //console.log(maps) + $.each(maps, function(i, v) {//不能写进点击事件函数里 不然点击一次增加一个title + var that = this + checkApp(that.pname, that.action, that.name) + }) + function isHasApp() { + if (0 == arr.length) { +// plus.nativeUI.confirm("没有地图软件??请安装", function(i) { +// if (0 == i.index) { + var startpos= bMapTransQQMap(userLng, userLat) + var endpos = bMapTransQQMap(shopLng, shopLat) + //console.log(userLng); + var urlStr = encodeURI('http://uri.amap.com/navigation?from='+startpos.lng+','+startpos.lat+',startpoint&to='+endpos.lng+','+endpos.lat+',endpoint&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0') +plus.runtime.openURL(urlStr) +// plus.runtime.openURL('http://uri.amap.com/navigation?from=116.43234,39.98871,当前位置&to=121,31,站点&mode=car&src=公司名称&callnative=0' // androidMarket('com.baidu.BaiduMap') +// // } +// +// ) + return false + } + openMapApp() + } + + function openMapApp() { + //底部弹出选择地图软件 + plus.nativeUI.actionSheet({ + title: "请选择!", + cancel: "取消", + buttons: arr + }, function(e) { + + var title = arr[e.index - 1].title; + // var i1 = new Intent(); + switch (title) { + case "百度地图": + // if (plus.os.name == "Android") { + // plus.runtime.openURL( + // "baidumap://map/direction?origin=latlng:39.98871,116.43234|name:我的位置&destination=31.236244,121.480239&mode=driving&src=webapp.navi.hanguosoft.yinyijianghu", + // function(error) { + // mui.alert('打开' + title + '失败'); + // }); + // } + goMaps( + "baidumap://map/direction?origin=我的位置&destination="+shopLat+","+shopLng+"&mode=driving&src=webapp.navi.hanguosoft.yinyijianghu" + ) + + break; + case "高德地图": + + var endpos = bMapTransQQMap(shopLng, shopLat) + // plus.runtime.openURL('androidamap://navi?sourceApplication=nyx_super&lat=' + endpos.lat + '&lon=' + endpos.lng + + // '&mode=driving&region=www&output=html&src="全亮共"', + // function(e) { + // mui.alert('打开' + title + '失败'); + // }) + goMaps('androidamap://navi?sourceApplication=nyx_super&lat=' + endpos.lat + '&lon=' + endpos.lng + + '&mode=driving&region='+shopName+'&output=html&src="全亮共"') + + break; + } + }) + } + + function goMaps(url) { + var mContext = plus.android.runtimeMainActivity(); + var Uri = plus.android.importClass('android.net.Uri'); + var Intent = plus.android.importClass('android.content.Intent'); + var intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + mContext.startActivity(intent); + } + + function checkApp(pn, ac, name) { // pname:android 包名 action:ios包名 name:用作底部弹出 + + if (plus.runtime.isApplicationExist({ + pname: pn, //包名 + action: ac //ios包名 + })) { + // //console.log("微信应用已安装"); + title = { + title: name + }; + arr.push(title) + } else { + // //console.log("微信应用未安装"); + // title={}; + // arr.push(title) + + } + } + + mui('.gothere').on("tap", ".gt_con", function(e) { + var idx = $(this).index(); + var html = ''; + switch (idx) { + case 0: + break; + case 1: + break; + case 2: + // $('.gt_con_con1').css('display','none') + + $('.gt_con_con').toggle() + html = + '<div class="row shadown_wai"><div class="name"><label class="label-idx" for="">姓名:</label><label class="label-val" for="">'+userName+'</label></div><div class="name"><label class="label-idx" for="">电话:</label><label class="label-val" for=""><a href="tel:'+phone+'">'+phone+'</label></div></div>' + $('.row .name').css("width", "60%") + $('.gt_con_con').html(html) + break; + + } + }) +}) diff --git a/static/app2/js/store_info.js b/static/app2/js/store_info.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/store_new.js b/static/app2/js/store_new.js new file mode 100755 index 0000000..e173b00 --- /dev/null +++ b/static/app2/js/store_new.js @@ -0,0 +1,219 @@ +$('.con').html(''); +$('.con').css('padding','0'); +var shopId = localStorage.getItem('shopId'); + +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + // console.log(order_class) + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + data: { + page: count, + shopId: shopId, + pageSize: 10, + msort: 6, + mdesc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + data = data.data; + var html = ''; + var obj = {}; + $.each(data.Rows, function() { + if(!obj[this.saleTime]) { + obj[this.saleTime] = [this] + } else { + obj[this.saleTime].push(this) + } + + }); + for(var i in obj) { + + if(obj[i].length == 1) { + html += '<div class="con_two con_goods" style="padding:0 2%;"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="ct_con shadown_wai" data-id="' + obj[i][0].goodsId + '"><img class="rcb_img" src="' + hyhImgUrl(obj[i][0].goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + obj[i][0].goodsName + '</div><div class="rcb_pay">¥' + obj[i][0].shopPrice + '<span style="display: none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display: none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>' + } else { + html += '<div class="con_one"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="cnxh_con clearfix">' + $.each(obj[i], function() { + html += '<div class="recommend_con_block shadown_wai" data-id="' + this.goodsId + '"><img class="rcb_img" src="' + hyhImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + '<span style="display: none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display: none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>' + }); + html += '</div></div>' + + } + + } + + $('.con').append(html); +// $('.cnxh_block img').height($('.cnxh_block img').width()); +// $('.rcb_img').height($('.rcb_img').width()); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + }   + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + mui.ajax(hyhUrl('app/Shops/getShopGoods'), {  + data: { + shopId: shopId, + pageSize: 10, + page: 1, + msort: 6, + mdesc: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var data = toJson(data); + data = data.data; + + var html = ''; + var obj = {}; + $.each(data.Rows, function() { + if(!obj[this.saleTime]) { + obj[this.saleTime] = [this] + } else { + obj[this.saleTime].push(this) + } + + }); + for(var i in obj) { + if(obj[i].length == 1) { + html += '<div class="con_two con_goods" style="padding:0 2%;"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="ct_con shadown_wai" data-id="' + obj[i][0].goodsId + '"><img class="rcb_img" src="' + hyhImgUrl(obj[i][0].goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + obj[i][0].goodsName + '</div><div class="rcb_pay">¥' + obj[i][0].shopPrice + '<span style="display: none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display: none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>' + } else { + html += '<div class="con_one"><div class="co_title clearfix"><div class="hengxian"></div><p>本店' + obj[i][0].saleTime + '上新</p><div class="hengxian"></div></div><div class="cnxh_con clearfix">' + $.each(obj[i], function() { + html += '<div class="recommend_con_block shadown_wai" data-id="' + this.goodsId + '"><img class="rcb_img" src="' + hyhImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display: none;">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + '<span style="display: none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display: none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>' + }); + html += '</div></div>' + + } + + } + + $('.con').html(html); +// $('.ct_con img').height($('.ct_con img').width()); +// $('.rcb_img').height($('.rcb_img').width()); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + setInterval(function() { + // $('.cnxh_block img').height($('.cnxh_block img').width()); + // $('.cnxh_block').height($('.cnxh_block').width() * 266 / 198); + $('.recommend_con_block img').height($('.recommend_con_block img').width()); + $('.ct_con img').height($('.ct_con img').width()); + }, 200) + $('.con').on('tap', '.ct_con', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('.con').on('tap', '.recommend_con_block', function() { + var good_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + good_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: good_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) +}) \ No newline at end of file diff --git a/static/app2/js/storeout.js b/static/app2/js/storeout.js new file mode 100755 index 0000000..0361f85 --- /dev/null +++ b/static/app2/js/storeout.js @@ -0,0 +1,323 @@ +//$('.searchcon').css('display', 'none'); +$('.title').css('width', '50%'); +$('.gz_btn').hide() +// var data = ''; +localStorage.removeItem('shopId'); +localStorage.removeItem('shopLat'); +localStorage.removeItem('shopLng'); +localStorage.removeItem('shopName'); +localStorage.removeItem('phone'); +localStorage.removeItem('userName'); +// $('.nav').html( +// '<a class="nav_block on" href="store_home.html"><span>首页</span></a><a class="nav_block" href="store_commodity.html"><span>商品</span></a><a class="nav_block" href="store_new.html"><span>上新</span></a><a class="nav_block" href="store_activity.html"><span>活动</span></a>' +// ); +// $('.searchcon').html( +// '<input type="search" name="" id="keyword" value="" placeholder="请输入搜索内容" /><button style="display: none;">搜索</button></div>' +// ); +mui.plusReady(function() { + var self = plus.webview.currentWebview(); + var shopId = self.shopId; + var shopName = self.shopName; + var shopLat=""; + var shopLng=''; + var phone=''; + var userName=''; + $('.title').html(shopName) + localStorage.setItem('shopId', shopId); + localStorage.setItem('shopName', shopName); + + JZL.ajax(qlgUrl('app/shopping/getShopInfo'),{ + shopId:shopId + },function (data) { + // console.log(data); + if (data.status == 1) { + var html = ''; + var data = data.data; + shopLat=data.lat; + shopLng=data.lng; + phone=data.phone; + userName=data.userName; + //console.log(shopLng); + localStorage.setItem('shopLat', shopLat); + localStorage.setItem('shopLng', shopLng); + localStorage.setItem('phone', phone); + localStorage.setItem('userName', userName); + var imgs=data.shopAds.split(","); + var firstImg = ''; + var endImg=''; + $.each(imgs, function(index,val) { + if(index == 0) firstImg='<div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="'+hyhImgUrl(val)+'"></a></div>'; + if(index == imgs.length-1) endImg='<div class="mui-slider-item mui-slider-item-duplicate"><a href="#"><img src="'+hyhImgUrl(val)+'"></a></div>'; + ////console.log(val); + html+='<div class="mui-slider-item"><a href="#"><img src="'+hyhImgUrl(val)+'"></a></div>'; + //html += '<div class="swiper-slide" ><img src="' + hyhImgUrl(val) + '" alt="" /></div>'; + }); + $('#imgsw').html(html); + $('#imgsw').prepend(endImg); + $('#imgsw').append(firstImg); + var slider = mui("#slider"); + slider.slider({ + interval: 2000 + }); + //$('#top_banner .swiper-wrapper').html(html); + // var swiper = new Swiper('#top_banner', { + // pagination: '#top_banner_pagination', + // spaceBetween: 0, + // loop: true, + // autoplay: 3500, + // autoplayDisableOnInteraction: false + // }); + $('#slider').height($('#slider').width() * 460 / 750); + } else{ + mui.alert(data.msg) + } + }) + // mui('.search').on('tap', '.classmenu', function() { + // shopId = this.attributes["data-shopid"].nodeValue; + // // //console.log(this.attributes["data-id"].nodeValue); + // mui.openWindow({ + // url: 'store_class.html', + // id: 'store_class.html', + // styles: { + // top: '0px', //新页面顶部位置 + // bottom: '0px', //新页面底部位置 + // width: '100%', //新页面宽度,默认为100% + // height: '100%' //新页面高度,默认为100% + // }, + // extras: { + // shopId: shopId + // // ..... //自定义扩展参数,可以用来处理页面间传值 + // }, + // createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + // show: { + // // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // // extras: {} //窗口动画是否使用图片加速 + // }, + // waiting: { + // autoShow: true, //自动显示等待框,默认为true + // title: '正在加载...', //等待对话框上显示的提示内容 + // options: { + // // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // // ...... + // } + // } + // }) + // }) +// mui('.footer').on('tap', '#dpxq', function() { +// //console.log(11); +// var w = plus.webview.create('store_info.html'); +// w.show() +// }) +// mui('.footer').on('tap', '#rmfl', function() { +// +// $('.rmfl').css('display', 'block') +// }) + // mui('.con').on('tap', '.gz_btn', function() { + mui('.header_con').on('tap', '.gz_btn', function() { + // var shopId = shopId; + var that = $(this); + //console.log(shopId) + mui.ajax(qlgUrl('app/Favorites/add'), { + data: { + id: shopId, + type: 1 + }, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data) + // //console.log(data.data.goodsFavoritesNum) + // //console.log(data.data.Rows) + var data = toJson(data); + if (data.status == 1) { + that.html('已关注'); + that.addClass('gz_btn1').removeClass('gz_btn'); + } else { + ////console.log(data.status) + } + + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(type); + } + }); + + }) + $('.header').on('focus', '#keyword', function() { + $(".searchcon button").css('display', 'block'); + }) + $('.header').on('blur', '#keyword', function() { + $(".searchcon button").css('display', 'none'); + }) + + //店铺搜索 + $(".header").on('keypress', '#keyword', function(e) { + var keycode = e.keyCode; + var searchName = $('#keyword').val(); + if(keycode == '13') { + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'shopGoodsList.html', + id: 'shopGoodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + $(".header").on('tap', '.searchcon button', function(e) { + var searchName = $('#keyword').val(); + // e.preventDefault(); + // //console.log(searchName) + //请求搜索接口 + mui.openWindow({ + url: 'shopGoodsList.html', + id: 'shopGoodsList.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }); + +}) + +function jumpPage() { + //跳转页面 + // var bSize = 190 + (+localStorage.getItem('ipxSizeTop')) + 'px'; + var bSize = +localStorage.getItem('topBannerheight')+42+'px'; + var subpages = ['store_home.html', 'store_commodity.html']; + // var subpages = ['store_home.html', 'store_commodity.html', 'store_new.html', 'store_activity.html']; + // top: bSize, + var subpage_style = { + top: bSize, + bottom: '0', + scrollIndicator: 'none' + }; + + var aniShow = {}; //动画显示 + //当前激活选项 + var activeTab = subpages[0]; + //选项卡点击事件 + // mui('.footer').on('tap', 'a', function(e) { + + mui('.nav').on('tap', 'a', function(e) { + var targetTab = this.getAttribute('href'); + // //console.log(targetTab); + if (targetTab == activeTab) { + return; + } + //显示目标选项卡 + //若为iOS平台或非首次显示,则直接显示 + if (mui.os.ios || aniShow[targetTab]) { + plus.webview.show(targetTab); + } else { + //否则,使用fade-in动画,且保存变量 + var temp = {}; + temp[targetTab] = "true"; + mui.extend(aniShow, temp); + plus.webview.show(targetTab, "fade-in", 300); + + } + //隐藏当前; + plus.webview.hide(activeTab); + //更改当前活跃的选项卡 + activeTab = targetTab; + + // var html = $(this).html(); + // html = html.substring(0, html.indexOf('.png')) + '_on.png">'; + // $(this).html(html); + $(this).addClass('on').siblings().removeClass('on'); + // $(this).siblings().each(function() { + // if($(this).html().indexOf('_on') == -1) { + // return + // } + // html = $(this).html().substring(0, $(this).html().indexOf('_on')) + // html = html + '.png">'; + // $(this).html(html) + // }) + }); + + //首次启动切滑效果 + + mui.plusReady(function() { + // launchScreen(); + // plus.navigator.setStatusBarStyle('dark'); + // //console.log(plus.navigator.getStatusBarStyle()) + var self = plus.webview.currentWebview(); + shopId = self.shopId; + // console.log(shopId); + localStorage.setItem('shopId', shopId); + + for (var i = 0; i < subpages.length; i++) { + var temp = {}; + //http://www.html5plus.org/doc/zh_cn/webview.html#plus.webview.create + var sub = plus.webview.create(subpages[i], subpages[i], subpage_style); + if (i > 0) { + sub.hide(); + } else { + temp[subpages[i]] = "true"; + mui.extend(aniShow, temp); //合并对象 + } + self.append(sub); + } + }); +} +jumpPage(); + diff --git a/static/app2/js/supermarket.js b/static/app2/js/supermarket.js new file mode 100755 index 0000000..f290ac9 --- /dev/null +++ b/static/app2/js/supermarket.js @@ -0,0 +1,225 @@ +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + //console.log(self); + + + var id = self.scid ? self.scid : ''; + JZL.ajax(qlgUrl('app/shops/getUserUpdate'), { + applyLevel: 2 + }, function(data) { + //console.log(data); + if (1 == data.status && undefined != data.data) { + var data = data.data; + + if (0 == data.status || 2 == data.status) { + //console.log(id); + if (id == "") { + id = data.id + } + getShopList(data.shopId); + + $('#confirm').attr('src', hyhImgUrl(data.confirmImg)) + $('#confirmImg').val(data.confirmImg) + + var imgs = data.shopImg + imgs = Array.from(imgs.split(',')) + //console.log(imgs); + var html = ""; + mui.each(imgs, function(index, element) { + //console.log(index, element); + html += '<div class="galleryImg photo" data-id="' + index + + '" ><div class="delete" data-id="' + index + '"><img src="../img/close.png" alt=""></div><img src="' + + hyhImgUrl(element) + '" class="ossfile" data-src="' + element + '" data-id="' + index + '" id="galleryImg[' + + index + + ']" alt=""><input type="hidden" name="gallery[]" value="' + element + + '" class="gallery" id="gallery[' + index + ']"><span class=""></span></div>'; + }) + // var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + var maxNum = imgs.length - 1; + // //console.log(maxNum); + // //console.log(num); + // if (num == maxNum) { + maxNum++; + html += '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").html(html); + // } + + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 115 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + + } else if (1 == data.status) { + //tiaozhuandao shangdu yemian + } + } else if ('' == data.data) { + getShopList(); + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 115 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + } + }) + // 上传图片 + $('.photos_con').on('tap', '.confirm', function() { + UP.init("confirmImg", "test", "confirm") + openCamera() + }) + $(".batchImg").on("tap", '.galleryImg', function() { + var num = $(this).attr('data-id'); + UP.init("gallery[" + num + "]", "test", "galleryImg[" + num + "]", 1); + var that = $(this); + openCamera(function(t, status, fileName, serverName) { + var html = '<div class="delete" data-id="' + num + '"><img src="../img/close.png" alt=""></div><img src="' + + serverName + '" class="ossfile" data-src="' + fileName + '" data-id="' + num + '" id="galleryImg[' + num + + ']" alt=""><input type="hidden" name="gallery[]" value="' + fileName + + '" class="gallery" id="gallery[' + num + ']"><span class=""></span>'; + + that.html(html); + + var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (num == maxNum) { + maxNum++; + html = '<div class="galleryImg photo" data-id="' + maxNum + + '" ><img src="../img/pjimg.png" class="ossfile" id="galleryImg[' + + maxNum + ']" alt=""><input type="hidden" name="gallery[]" value="" class="gallery" id="gallery[' + maxNum + + ']"><span class=""></span></div>'; + $(".batchImg").append(html); + } + }); + }) + //删除照片 + $(".batchImg").on('tap', '.delete', function(e) { + + e.preventDefault(); + e.stopPropagation() + + // //console.log(this); + var that = $(this) + //var idx = that.parent().attr('data-id'); + //var maxNum = $('.galleryImg').last().attr('data-id'); //$('.batchImg').children('.galleryImg').length - 1; + if (confirm('确认删除图片?')) { + that.parent().remove() + //delete galleryarr[idx]; + } + }) + //获取协议 + JZL.ajax(qlgUrl('app/Tags/articleDetail'), { + articleId: 115 + }, function(data) { + //console.log(data); + // if (1==data.status) { + // $('.zcxycontent').html(data.data.articleContent) + $('.zcxycontent').html(data.articleContent) + + // } + + }) + //获取店铺信息 + getShopList() + + function getShopList(defaultShopId) { + + JZL.ajax(qlgUrl('app/shops/userShopList'), { + shopType: 1 + }, function(data) { + //console.log(data); + if (1 == data.status) { + var html = ""; + html = `<option value ="">选择店铺</option>`; + if (undefined == typeof defaultShop) { + + mui.each(data.data, function() { + // //console.log(index, element); + html += `<option value =${this.shopId}>${this.shopName}</option>`; + }) + } else { + mui.each(data.data, function() { + if (this.shopId == defaultShopId) { + selected = 'selected'; + } else { + selected = ''; + } + html += `<option value =${this.shopId} ${selected}>${this.shopName}</option>`; + }) + + } + $("#shopId").html(html) + } else { + mui.alert(data.msg) + } + // }) + }) + + + } + let click = 0; + $('.down').on('tap', '.btn', function() { + + if (click == 1) { + return; + } + click = 1 + var imgs = ''; + var data = $('input[name="gallery[]"]'); + //console.log(data); + $.each(data, function() { + if ('' != $(this).val()) + imgs = $(this).val() + ',' + imgs; + }) + imgs = imgs.substring(0, imgs.lastIndexOf(',')); + $('#shopImg').val(imgs); + if ('' == $('#shopId option:selected').val()) { + mui.alert('请选择要升级的店铺名称') + return; + } + + if ('' == $('#confirmImg').val()) { + mui.alert('请上传确认书照片') + return; + } + if ('' == $('#shopImg').val()) { + mui.alert('请上传店铺照片') + return; + } + + + var params = JZL.getParams(".inp"); + params.applyLevel = 2; + if ("" != id) { + params.id = id; + //console.log(params.id); + } + JZL.ajax(qlgUrl('app/shops/userUpdate'), params, function(data) { + // //console.log(data); + if (1 == data.status) { + // mui.back() + } else { + mui.alert(data.msg) + } + }) + }) + + + + +}) diff --git a/static/app2/js/swiper.min.js b/static/app2/js/swiper.min.js new file mode 100755 index 0000000..03a652f --- /dev/null +++ b/static/app2/js/swiper.min.js @@ -0,0 +1,19 @@ +/** + * Swiper 3.4.2 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2017, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: March 10, 2017 + */ +!function(){"use strict";var e,a=function(s,i){function r(e){return Math.floor(e)}function n(){var e=T.params.autoplay,a=T.slides.eq(T.activeIndex);a.attr("data-swiper-autoplay")&&(e=a.attr("data-swiper-autoplay")||T.params.autoplay),T.autoplayTimeoutId=setTimeout(function(){T.params.loop?(T.fixLoop(),T._slideNext(),T.emit("onAutoplay",T)):T.isEnd?i.autoplayStopOnLast?T.stopAutoplay():(T._slideTo(0),T.emit("onAutoplay",T)):(T._slideNext(),T.emit("onAutoplay",T))},e)}function o(a,t){var s=e(a.target);if(!s.is(t))if("string"==typeof t)s=s.parents(t);else if(t.nodeType){var i;return s.parents().each(function(e,a){a===t&&(i=t)}),i?t:void 0}if(0!==s.length)return s[0]}function l(e,a){a=a||{};var t=window.MutationObserver||window.WebkitMutationObserver,s=new t(function(e){e.forEach(function(e){T.onResize(!0),T.emit("onObserverUpdate",T,e)})});s.observe(e,{attributes:void 0===a.attributes||a.attributes,childList:void 0===a.childList||a.childList,characterData:void 0===a.characterData||a.characterData}),T.observers.push(s)}function p(e){e.originalEvent&&(e=e.originalEvent);var a=e.keyCode||e.charCode;if(!T.params.allowSwipeToNext&&(T.isHorizontal()&&39===a||!T.isHorizontal()&&40===a))return!1;if(!T.params.allowSwipeToPrev&&(T.isHorizontal()&&37===a||!T.isHorizontal()&&38===a))return!1;if(!(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||document.activeElement&&document.activeElement.nodeName&&("input"===document.activeElement.nodeName.toLowerCase()||"textarea"===document.activeElement.nodeName.toLowerCase()))){if(37===a||39===a||38===a||40===a){var t=!1;if(T.container.parents("."+T.params.slideClass).length>0&&0===T.container.parents("."+T.params.slideActiveClass).length)return;var s={left:window.pageXOffset,top:window.pageYOffset},i=window.innerWidth,r=window.innerHeight,n=T.container.offset();T.rtl&&(n.left=n.left-T.container[0].scrollLeft);for(var o=[[n.left,n.top],[n.left+T.width,n.top],[n.left,n.top+T.height],[n.left+T.width,n.top+T.height]],l=0;l<o.length;l++){var p=o[l];p[0]>=s.left&&p[0]<=s.left+i&&p[1]>=s.top&&p[1]<=s.top+r&&(t=!0)}if(!t)return}T.isHorizontal()?(37!==a&&39!==a||(e.preventDefault?e.preventDefault():e.returnValue=!1),(39===a&&!T.rtl||37===a&&T.rtl)&&T.slideNext(),(37===a&&!T.rtl||39===a&&T.rtl)&&T.slidePrev()):(38!==a&&40!==a||(e.preventDefault?e.preventDefault():e.returnValue=!1),40===a&&T.slideNext(),38===a&&T.slidePrev()),T.emit("onKeyPress",T,a)}}function d(e){var a=0,t=0,s=0,i=0;return"detail"in e&&(t=e.detail),"wheelDelta"in e&&(t=-e.wheelDelta/120),"wheelDeltaY"in e&&(t=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(a=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(a=t,t=0),s=10*a,i=10*t,"deltaY"in e&&(i=e.deltaY),"deltaX"in e&&(s=e.deltaX),(s||i)&&e.deltaMode&&(1===e.deltaMode?(s*=40,i*=40):(s*=800,i*=800)),s&&!a&&(a=s<1?-1:1),i&&!t&&(t=i<1?-1:1),{spinX:a,spinY:t,pixelX:s,pixelY:i}}function u(e){e.originalEvent&&(e=e.originalEvent);var a=0,t=T.rtl?-1:1,s=d(e);if(T.params.mousewheelForceToAxis)if(T.isHorizontal()){if(!(Math.abs(s.pixelX)>Math.abs(s.pixelY)))return;a=s.pixelX*t}else{if(!(Math.abs(s.pixelY)>Math.abs(s.pixelX)))return;a=s.pixelY}else a=Math.abs(s.pixelX)>Math.abs(s.pixelY)?-s.pixelX*t:-s.pixelY;if(0!==a){if(T.params.mousewheelInvert&&(a=-a),T.params.freeMode){var i=T.getWrapperTranslate()+a*T.params.mousewheelSensitivity,r=T.isBeginning,n=T.isEnd;if(i>=T.minTranslate()&&(i=T.minTranslate()),i<=T.maxTranslate()&&(i=T.maxTranslate()),T.setWrapperTransition(0),T.setWrapperTranslate(i),T.updateProgress(),T.updateActiveIndex(),(!r&&T.isBeginning||!n&&T.isEnd)&&T.updateClasses(),T.params.freeModeSticky?(clearTimeout(T.mousewheel.timeout),T.mousewheel.timeout=setTimeout(function(){T.slideReset()},300)):T.params.lazyLoading&&T.lazy&&T.lazy.load(),T.emit("onScroll",T,e),T.params.autoplay&&T.params.autoplayDisableOnInteraction&&T.stopAutoplay(),0===i||i===T.maxTranslate())return}else{if((new window.Date).getTime()-T.mousewheel.lastScrollTime>60)if(a<0)if(T.isEnd&&!T.params.loop||T.animating){if(T.params.mousewheelReleaseOnEdges)return!0}else T.slideNext(),T.emit("onScroll",T,e);else if(T.isBeginning&&!T.params.loop||T.animating){if(T.params.mousewheelReleaseOnEdges)return!0}else T.slidePrev(),T.emit("onScroll",T,e);T.mousewheel.lastScrollTime=(new window.Date).getTime()}return e.preventDefault?e.preventDefault():e.returnValue=!1,!1}}function c(a,t){a=e(a);var s,i,r,n=T.rtl?-1:1;s=a.attr("data-swiper-parallax")||"0",i=a.attr("data-swiper-parallax-x"),r=a.attr("data-swiper-parallax-y"),i||r?(i=i||"0",r=r||"0"):T.isHorizontal()?(i=s,r="0"):(r=s,i="0"),i=i.indexOf("%")>=0?parseInt(i,10)*t*n+"%":i*t*n+"px",r=r.indexOf("%")>=0?parseInt(r,10)*t+"%":r*t+"px",a.transform("translate3d("+i+", "+r+",0px)")}function m(e){return 0!==e.indexOf("on")&&(e=e[0]!==e[0].toUpperCase()?"on"+e[0].toUpperCase()+e.substring(1):"on"+e),e}if(!(this instanceof a))return new a(s,i);var h={direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,autoplay:!1,autoplayDisableOnInteraction:!0,autoplayStopOnLast:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flip:{slideShadows:!0,limitRotation:!0},cube:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fade:{crossFade:!1},parallax:!1,zoom:!1,zoomMax:3,zoomMin:1,zoomToggle:!0,scrollbar:null,scrollbarHide:!0,scrollbarDraggable:!1,scrollbarSnapOnRelease:!1,keyboardControl:!1,mousewheelControl:!1,mousewheelReleaseOnEdges:!1,mousewheelInvert:!1,mousewheelForceToAxis:!1,mousewheelSensitivity:1,mousewheelEventsTarged:"container",hashnav:!1,hashnavWatchState:!1,history:!1,replaceState:!1,breakpoints:void 0,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,onlyExternal:!1,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,uniqueNavElements:!0,pagination:null,paginationElement:"span",paginationClickable:!1,paginationHide:!1,paginationBulletRender:null,paginationProgressRender:null,paginationFractionRender:null,paginationCustomRender:null,paginationType:"bullets",resistance:!0,resistanceRatio:.85,nextButton:null,prevButton:null,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,lazyLoading:!1,lazyLoadingInPrevNext:!1,lazyLoadingInPrevNextAmount:1,lazyLoadingOnTransitionStart:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,control:void 0,controlInverse:!1,controlBy:"slide",normalizeSlideIndex:!0,allowSwipeToPrev:!0,allowSwipeToNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",passiveListeners:!0,containerModifierClass:"swiper-container-",slideClass:"swiper-slide",slideActiveClass:"swiper-slide-active",slideDuplicateActiveClass:"swiper-slide-duplicate-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slideDuplicateNextClass:"swiper-slide-duplicate-next",slidePrevClass:"swiper-slide-prev",slideDuplicatePrevClass:"swiper-slide-duplicate-prev",wrapperClass:"swiper-wrapper",bulletClass:"swiper-pagination-bullet",bulletActiveClass:"swiper-pagination-bullet-active",buttonDisabledClass:"swiper-button-disabled",paginationCurrentClass:"swiper-pagination-current",paginationTotalClass:"swiper-pagination-total",paginationHiddenClass:"swiper-pagination-hidden",paginationProgressbarClass:"swiper-pagination-progressbar",paginationClickableClass:"swiper-pagination-clickable",paginationModifierClass:"swiper-pagination-",lazyLoadingClass:"swiper-lazy",lazyStatusLoadingClass:"swiper-lazy-loading",lazyStatusLoadedClass:"swiper-lazy-loaded",lazyPreloaderClass:"swiper-lazy-preloader",notificationClass:"swiper-notification",preloaderClass:"preloader",zoomContainerClass:"swiper-zoom-container",observer:!1,observeParents:!1,a11y:!1,prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}",runCallbacksOnInit:!0},g=i&&i.virtualTranslate;i=i||{};var f={};for(var v in i)if("object"!=typeof i[v]||null===i[v]||(i[v].nodeType||i[v]===window||i[v]===document||void 0!==t&&i[v]instanceof t||"undefined"!=typeof jQuery&&i[v]instanceof jQuery))f[v]=i[v];else{f[v]={};for(var w in i[v])f[v][w]=i[v][w]}for(var y in h)if(void 0===i[y])i[y]=h[y];else if("object"==typeof i[y])for(var x in h[y])void 0===i[y][x]&&(i[y][x]=h[y][x]);var T=this;if(T.params=i,T.originalParams=f,T.classNames=[],void 0!==e&&void 0!==t&&(e=t),(void 0!==e||(e=void 0===t?window.Dom7||window.Zepto||window.jQuery:t))&&(T.$=e,T.currentBreakpoint=void 0,T.getActiveBreakpoint=function(){if(!T.params.breakpoints)return!1;var e,a=!1,t=[];for(e in T.params.breakpoints)T.params.breakpoints.hasOwnProperty(e)&&t.push(e);t.sort(function(e,a){return parseInt(e,10)>parseInt(a,10)});for(var s=0;s<t.length;s++)(e=t[s])>=window.innerWidth&&!a&&(a=e);return a||"max"},T.setBreakpoint=function(){var e=T.getActiveBreakpoint();if(e&&T.currentBreakpoint!==e){var a=e in T.params.breakpoints?T.params.breakpoints[e]:T.originalParams,t=T.params.loop&&a.slidesPerView!==T.params.slidesPerView;for(var s in a)T.params[s]=a[s];T.currentBreakpoint=e,t&&T.destroyLoop&&T.reLoop(!0)}},T.params.breakpoints&&T.setBreakpoint(),T.container=e(s),0!==T.container.length)){if(T.container.length>1){var b=[];return T.container.each(function(){b.push(new a(this,i))}),b}T.container[0].swiper=T,T.container.data("swiper",T),T.classNames.push(T.params.containerModifierClass+T.params.direction),T.params.freeMode&&T.classNames.push(T.params.containerModifierClass+"free-mode"),T.support.flexbox||(T.classNames.push(T.params.containerModifierClass+"no-flexbox"),T.params.slidesPerColumn=1),T.params.autoHeight&&T.classNames.push(T.params.containerModifierClass+"autoheight"),(T.params.parallax||T.params.watchSlidesVisibility)&&(T.params.watchSlidesProgress=!0),T.params.touchReleaseOnEdges&&(T.params.resistanceRatio=0),["cube","coverflow","flip"].indexOf(T.params.effect)>=0&&(T.support.transforms3d?(T.params.watchSlidesProgress=!0,T.classNames.push(T.params.containerModifierClass+"3d")):T.params.effect="slide"),"slide"!==T.params.effect&&T.classNames.push(T.params.containerModifierClass+T.params.effect),"cube"===T.params.effect&&(T.params.resistanceRatio=0,T.params.slidesPerView=1,T.params.slidesPerColumn=1,T.params.slidesPerGroup=1,T.params.centeredSlides=!1,T.params.spaceBetween=0,T.params.virtualTranslate=!0),"fade"!==T.params.effect&&"flip"!==T.params.effect||(T.params.slidesPerView=1,T.params.slidesPerColumn=1,T.params.slidesPerGroup=1,T.params.watchSlidesProgress=!0,T.params.spaceBetween=0,void 0===g&&(T.params.virtualTranslate=!0)),T.params.grabCursor&&T.support.touch&&(T.params.grabCursor=!1),T.wrapper=T.container.children("."+T.params.wrapperClass),T.params.pagination&&(T.paginationContainer=e(T.params.pagination),T.params.uniqueNavElements&&"string"==typeof T.params.pagination&&T.paginationContainer.length>1&&1===T.container.find(T.params.pagination).length&&(T.paginationContainer=T.container.find(T.params.pagination)),"bullets"===T.params.paginationType&&T.params.paginationClickable?T.paginationContainer.addClass(T.params.paginationModifierClass+"clickable"):T.params.paginationClickable=!1,T.paginationContainer.addClass(T.params.paginationModifierClass+T.params.paginationType)),(T.params.nextButton||T.params.prevButton)&&(T.params.nextButton&&(T.nextButton=e(T.params.nextButton),T.params.uniqueNavElements&&"string"==typeof T.params.nextButton&&T.nextButton.length>1&&1===T.container.find(T.params.nextButton).length&&(T.nextButton=T.container.find(T.params.nextButton))),T.params.prevButton&&(T.prevButton=e(T.params.prevButton),T.params.uniqueNavElements&&"string"==typeof T.params.prevButton&&T.prevButton.length>1&&1===T.container.find(T.params.prevButton).length&&(T.prevButton=T.container.find(T.params.prevButton)))),T.isHorizontal=function(){return"horizontal"===T.params.direction},T.rtl=T.isHorizontal()&&("rtl"===T.container[0].dir.toLowerCase()||"rtl"===T.container.css("direction")),T.rtl&&T.classNames.push(T.params.containerModifierClass+"rtl"),T.rtl&&(T.wrongRTL="-webkit-box"===T.wrapper.css("display")),T.params.slidesPerColumn>1&&T.classNames.push(T.params.containerModifierClass+"multirow"),T.device.android&&T.classNames.push(T.params.containerModifierClass+"android"),T.container.addClass(T.classNames.join(" ")),T.translate=0,T.progress=0,T.velocity=0,T.lockSwipeToNext=function(){T.params.allowSwipeToNext=!1,T.params.allowSwipeToPrev===!1&&T.params.grabCursor&&T.unsetGrabCursor()},T.lockSwipeToPrev=function(){T.params.allowSwipeToPrev=!1,T.params.allowSwipeToNext===!1&&T.params.grabCursor&&T.unsetGrabCursor()},T.lockSwipes=function(){T.params.allowSwipeToNext=T.params.allowSwipeToPrev=!1,T.params.grabCursor&&T.unsetGrabCursor()},T.unlockSwipeToNext=function(){T.params.allowSwipeToNext=!0,T.params.allowSwipeToPrev===!0&&T.params.grabCursor&&T.setGrabCursor()},T.unlockSwipeToPrev=function(){T.params.allowSwipeToPrev=!0,T.params.allowSwipeToNext===!0&&T.params.grabCursor&&T.setGrabCursor()},T.unlockSwipes=function(){T.params.allowSwipeToNext=T.params.allowSwipeToPrev=!0,T.params.grabCursor&&T.setGrabCursor()},T.setGrabCursor=function(e){T.container[0].style.cursor="move",T.container[0].style.cursor=e?"-webkit-grabbing":"-webkit-grab",T.container[0].style.cursor=e?"-moz-grabbin":"-moz-grab",T.container[0].style.cursor=e?"grabbing":"grab"},T.unsetGrabCursor=function(){T.container[0].style.cursor=""},T.params.grabCursor&&T.setGrabCursor(),T.imagesToLoad=[],T.imagesLoaded=0,T.loadImage=function(e,a,t,s,i,r){function n(){r&&r()}var o;e.complete&&i?n():a?(o=new window.Image,o.onload=n,o.onerror=n,s&&(o.sizes=s),t&&(o.srcset=t),a&&(o.src=a)):n()},T.preloadImages=function(){function e(){void 0!==T&&null!==T&&T&&(void 0!==T.imagesLoaded&&T.imagesLoaded++,T.imagesLoaded===T.imagesToLoad.length&&(T.params.updateOnImagesReady&&T.update(),T.emit("onImagesReady",T)))}T.imagesToLoad=T.container.find("img");for(var a=0;a<T.imagesToLoad.length;a++)T.loadImage(T.imagesToLoad[a],T.imagesToLoad[a].currentSrc||T.imagesToLoad[a].getAttribute("src"),T.imagesToLoad[a].srcset||T.imagesToLoad[a].getAttribute("srcset"),T.imagesToLoad[a].sizes||T.imagesToLoad[a].getAttribute("sizes"),!0,e)},T.autoplayTimeoutId=void 0,T.autoplaying=!1,T.autoplayPaused=!1,T.startAutoplay=function(){return void 0===T.autoplayTimeoutId&&(!!T.params.autoplay&&(!T.autoplaying&&(T.autoplaying=!0,T.emit("onAutoplayStart",T),void n())))},T.stopAutoplay=function(e){T.autoplayTimeoutId&&(T.autoplayTimeoutId&&clearTimeout(T.autoplayTimeoutId),T.autoplaying=!1,T.autoplayTimeoutId=void 0,T.emit("onAutoplayStop",T))},T.pauseAutoplay=function(e){T.autoplayPaused||(T.autoplayTimeoutId&&clearTimeout(T.autoplayTimeoutId),T.autoplayPaused=!0,0===e?(T.autoplayPaused=!1,n()):T.wrapper.transitionEnd(function(){T&&(T.autoplayPaused=!1,T.autoplaying?n():T.stopAutoplay())}))},T.minTranslate=function(){return-T.snapGrid[0]},T.maxTranslate=function(){return-T.snapGrid[T.snapGrid.length-1]},T.updateAutoHeight=function(){var e,a=[],t=0;if("auto"!==T.params.slidesPerView&&T.params.slidesPerView>1)for(e=0;e<Math.ceil(T.params.slidesPerView);e++){var s=T.activeIndex+e;if(s>T.slides.length)break;a.push(T.slides.eq(s)[0])}else a.push(T.slides.eq(T.activeIndex)[0]);for(e=0;e<a.length;e++)if(void 0!==a[e]){var i=a[e].offsetHeight;t=i>t?i:t}t&&T.wrapper.css("height",t+"px")},T.updateContainerSize=function(){var e,a;e=void 0!==T.params.width?T.params.width:T.container[0].clientWidth,a=void 0!==T.params.height?T.params.height:T.container[0].clientHeight,0===e&&T.isHorizontal()||0===a&&!T.isHorizontal()||(e=e-parseInt(T.container.css("padding-left"),10)-parseInt(T.container.css("padding-right"),10),a=a-parseInt(T.container.css("padding-top"),10)-parseInt(T.container.css("padding-bottom"),10),T.width=e,T.height=a,T.size=T.isHorizontal()?T.width:T.height)},T.updateSlidesSize=function(){T.slides=T.wrapper.children("."+T.params.slideClass),T.snapGrid=[],T.slidesGrid=[],T.slidesSizesGrid=[];var e,a=T.params.spaceBetween,t=-T.params.slidesOffsetBefore,s=0,i=0;if(void 0!==T.size){"string"==typeof a&&a.indexOf("%")>=0&&(a=parseFloat(a.replace("%",""))/100*T.size),T.virtualSize=-a,T.rtl?T.slides.css({marginLeft:"",marginTop:""}):T.slides.css({marginRight:"",marginBottom:""});var n;T.params.slidesPerColumn>1&&(n=Math.floor(T.slides.length/T.params.slidesPerColumn)===T.slides.length/T.params.slidesPerColumn?T.slides.length:Math.ceil(T.slides.length/T.params.slidesPerColumn)*T.params.slidesPerColumn,"auto"!==T.params.slidesPerView&&"row"===T.params.slidesPerColumnFill&&(n=Math.max(n,T.params.slidesPerView*T.params.slidesPerColumn)));var o,l=T.params.slidesPerColumn,p=n/l,d=p-(T.params.slidesPerColumn*p-T.slides.length);for(e=0;e<T.slides.length;e++){o=0;var u=T.slides.eq(e);if(T.params.slidesPerColumn>1){var c,m,h;"column"===T.params.slidesPerColumnFill?(m=Math.floor(e/l),h=e-m*l,(m>d||m===d&&h===l-1)&&++h>=l&&(h=0,m++),c=m+h*n/l,u.css({"-webkit-box-ordinal-group":c,"-moz-box-ordinal-group":c,"-ms-flex-order":c,"-webkit-order":c,order:c})):(h=Math.floor(e/p),m=e-h*p),u.css("margin-"+(T.isHorizontal()?"top":"left"),0!==h&&T.params.spaceBetween&&T.params.spaceBetween+"px").attr("data-swiper-column",m).attr("data-swiper-row",h)}"none"!==u.css("display")&&("auto"===T.params.slidesPerView?(o=T.isHorizontal()?u.outerWidth(!0):u.outerHeight(!0),T.params.roundLengths&&(o=r(o))):(o=(T.size-(T.params.slidesPerView-1)*a)/T.params.slidesPerView,T.params.roundLengths&&(o=r(o)),T.isHorizontal()?T.slides[e].style.width=o+"px":T.slides[e].style.height=o+"px"),T.slides[e].swiperSlideSize=o,T.slidesSizesGrid.push(o),T.params.centeredSlides?(t=t+o/2+s/2+a,0===s&&0!==e&&(t=t-T.size/2-a),0===e&&(t=t-T.size/2-a),Math.abs(t)<.001&&(t=0),i%T.params.slidesPerGroup==0&&T.snapGrid.push(t),T.slidesGrid.push(t)):(i%T.params.slidesPerGroup==0&&T.snapGrid.push(t),T.slidesGrid.push(t),t=t+o+a),T.virtualSize+=o+a,s=o,i++)}T.virtualSize=Math.max(T.virtualSize,T.size)+T.params.slidesOffsetAfter;var g;if(T.rtl&&T.wrongRTL&&("slide"===T.params.effect||"coverflow"===T.params.effect)&&T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}),T.support.flexbox&&!T.params.setWrapperSize||(T.isHorizontal()?T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}):T.wrapper.css({height:T.virtualSize+T.params.spaceBetween+"px"})),T.params.slidesPerColumn>1&&(T.virtualSize=(o+T.params.spaceBetween)*n,T.virtualSize=Math.ceil(T.virtualSize/T.params.slidesPerColumn)-T.params.spaceBetween,T.isHorizontal()?T.wrapper.css({width:T.virtualSize+T.params.spaceBetween+"px"}):T.wrapper.css({height:T.virtualSize+T.params.spaceBetween+"px"}),T.params.centeredSlides)){for(g=[],e=0;e<T.snapGrid.length;e++)T.snapGrid[e]<T.virtualSize+T.snapGrid[0]&&g.push(T.snapGrid[e]);T.snapGrid=g}if(!T.params.centeredSlides){for(g=[],e=0;e<T.snapGrid.length;e++)T.snapGrid[e]<=T.virtualSize-T.size&&g.push(T.snapGrid[e]);T.snapGrid=g,Math.floor(T.virtualSize-T.size)-Math.floor(T.snapGrid[T.snapGrid.length-1])>1&&T.snapGrid.push(T.virtualSize-T.size)}0===T.snapGrid.length&&(T.snapGrid=[0]),0!==T.params.spaceBetween&&(T.isHorizontal()?T.rtl?T.slides.css({marginLeft:a+"px"}):T.slides.css({marginRight:a+"px"}):T.slides.css({marginBottom:a+"px"})),T.params.watchSlidesProgress&&T.updateSlidesOffset()}},T.updateSlidesOffset=function(){for(var e=0;e<T.slides.length;e++)T.slides[e].swiperSlideOffset=T.isHorizontal()?T.slides[e].offsetLeft:T.slides[e].offsetTop},T.currentSlidesPerView=function(){var e,a,t=1;if(T.params.centeredSlides){var s,i=T.slides[T.activeIndex].swiperSlideSize;for(e=T.activeIndex+1;e<T.slides.length;e++)T.slides[e]&&!s&&(i+=T.slides[e].swiperSlideSize,t++,i>T.size&&(s=!0));for(a=T.activeIndex-1;a>=0;a--)T.slides[a]&&!s&&(i+=T.slides[a].swiperSlideSize,t++,i>T.size&&(s=!0))}else for(e=T.activeIndex+1;e<T.slides.length;e++)T.slidesGrid[e]-T.slidesGrid[T.activeIndex]<T.size&&t++;return t},T.updateSlidesProgress=function(e){if(void 0===e&&(e=T.translate||0),0!==T.slides.length){void 0===T.slides[0].swiperSlideOffset&&T.updateSlidesOffset();var a=-e;T.rtl&&(a=e),T.slides.removeClass(T.params.slideVisibleClass);for(var t=0;t<T.slides.length;t++){var s=T.slides[t],i=(a+(T.params.centeredSlides?T.minTranslate():0)-s.swiperSlideOffset)/(s.swiperSlideSize+T.params.spaceBetween);if(T.params.watchSlidesVisibility){var r=-(a-s.swiperSlideOffset),n=r+T.slidesSizesGrid[t];(r>=0&&r<T.size||n>0&&n<=T.size||r<=0&&n>=T.size)&&T.slides.eq(t).addClass(T.params.slideVisibleClass)}s.progress=T.rtl?-i:i}}},T.updateProgress=function(e){void 0===e&&(e=T.translate||0);var a=T.maxTranslate()-T.minTranslate(),t=T.isBeginning,s=T.isEnd;0===a?(T.progress=0,T.isBeginning=T.isEnd=!0):(T.progress=(e-T.minTranslate())/a,T.isBeginning=T.progress<=0,T.isEnd=T.progress>=1),T.isBeginning&&!t&&T.emit("onReachBeginning",T),T.isEnd&&!s&&T.emit("onReachEnd",T),T.params.watchSlidesProgress&&T.updateSlidesProgress(e),T.emit("onProgress",T,T.progress)},T.updateActiveIndex=function(){var e,a,t,s=T.rtl?T.translate:-T.translate;for(a=0;a<T.slidesGrid.length;a++)void 0!==T.slidesGrid[a+1]?s>=T.slidesGrid[a]&&s<T.slidesGrid[a+1]-(T.slidesGrid[a+1]-T.slidesGrid[a])/2?e=a:s>=T.slidesGrid[a]&&s<T.slidesGrid[a+1]&&(e=a+1):s>=T.slidesGrid[a]&&(e=a);T.params.normalizeSlideIndex&&(e<0||void 0===e)&&(e=0),t=Math.floor(e/T.params.slidesPerGroup),t>=T.snapGrid.length&&(t=T.snapGrid.length-1),e!==T.activeIndex&&(T.snapIndex=t,T.previousIndex=T.activeIndex,T.activeIndex=e,T.updateClasses(),T.updateRealIndex())},T.updateRealIndex=function(){T.realIndex=parseInt(T.slides.eq(T.activeIndex).attr("data-swiper-slide-index")||T.activeIndex,10)},T.updateClasses=function(){T.slides.removeClass(T.params.slideActiveClass+" "+T.params.slideNextClass+" "+T.params.slidePrevClass+" "+T.params.slideDuplicateActiveClass+" "+T.params.slideDuplicateNextClass+" "+T.params.slideDuplicatePrevClass);var a=T.slides.eq(T.activeIndex);a.addClass(T.params.slideActiveClass),i.loop&&(a.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+T.realIndex+'"]').addClass(T.params.slideDuplicateActiveClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+T.realIndex+'"]').addClass(T.params.slideDuplicateActiveClass));var t=a.next("."+T.params.slideClass).addClass(T.params.slideNextClass);T.params.loop&&0===t.length&&(t=T.slides.eq(0),t.addClass(T.params.slideNextClass));var s=a.prev("."+T.params.slideClass).addClass(T.params.slidePrevClass);if(T.params.loop&&0===s.length&&(s=T.slides.eq(-1),s.addClass(T.params.slidePrevClass)),i.loop&&(t.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+t.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicateNextClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+t.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicateNextClass),s.hasClass(T.params.slideDuplicateClass)?T.wrapper.children("."+T.params.slideClass+":not(."+T.params.slideDuplicateClass+')[data-swiper-slide-index="'+s.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicatePrevClass):T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+s.attr("data-swiper-slide-index")+'"]').addClass(T.params.slideDuplicatePrevClass)),T.paginationContainer&&T.paginationContainer.length>0){var r,n=T.params.loop?Math.ceil((T.slides.length-2*T.loopedSlides)/T.params.slidesPerGroup):T.snapGrid.length;if(T.params.loop?(r=Math.ceil((T.activeIndex-T.loopedSlides)/T.params.slidesPerGroup),r>T.slides.length-1-2*T.loopedSlides&&(r-=T.slides.length-2*T.loopedSlides),r>n-1&&(r-=n),r<0&&"bullets"!==T.params.paginationType&&(r=n+r)):r=void 0!==T.snapIndex?T.snapIndex:T.activeIndex||0,"bullets"===T.params.paginationType&&T.bullets&&T.bullets.length>0&&(T.bullets.removeClass(T.params.bulletActiveClass),T.paginationContainer.length>1?T.bullets.each(function(){e(this).index()===r&&e(this).addClass(T.params.bulletActiveClass)}):T.bullets.eq(r).addClass(T.params.bulletActiveClass)),"fraction"===T.params.paginationType&&(T.paginationContainer.find("."+T.params.paginationCurrentClass).text(r+1),T.paginationContainer.find("."+T.params.paginationTotalClass).text(n)),"progress"===T.params.paginationType){var o=(r+1)/n,l=o,p=1;T.isHorizontal()||(p=o,l=1),T.paginationContainer.find("."+T.params.paginationProgressbarClass).transform("translate3d(0,0,0) scaleX("+l+") scaleY("+p+")").transition(T.params.speed)}"custom"===T.params.paginationType&&T.params.paginationCustomRender&&(T.paginationContainer.html(T.params.paginationCustomRender(T,r+1,n)),T.emit("onPaginationRendered",T,T.paginationContainer[0]))}T.params.loop||(T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.isBeginning?(T.prevButton.addClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.disable(T.prevButton)):(T.prevButton.removeClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.enable(T.prevButton))),T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.isEnd?(T.nextButton.addClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.disable(T.nextButton)):(T.nextButton.removeClass(T.params.buttonDisabledClass),T.params.a11y&&T.a11y&&T.a11y.enable(T.nextButton))))},T.updatePagination=function(){if(T.params.pagination&&T.paginationContainer&&T.paginationContainer.length>0){var e="";if("bullets"===T.params.paginationType){for(var a=T.params.loop?Math.ceil((T.slides.length-2*T.loopedSlides)/T.params.slidesPerGroup):T.snapGrid.length,t=0;t<a;t++)e+=T.params.paginationBulletRender?T.params.paginationBulletRender(T,t,T.params.bulletClass):"<"+T.params.paginationElement+' class="'+T.params.bulletClass+'"></'+T.params.paginationElement+">";T.paginationContainer.html(e),T.bullets=T.paginationContainer.find("."+T.params.bulletClass),T.params.paginationClickable&&T.params.a11y&&T.a11y&&T.a11y.initPagination()}"fraction"===T.params.paginationType&&(e=T.params.paginationFractionRender?T.params.paginationFractionRender(T,T.params.paginationCurrentClass,T.params.paginationTotalClass):'<span class="'+T.params.paginationCurrentClass+'"></span> / <span class="'+T.params.paginationTotalClass+'"></span>',T.paginationContainer.html(e)),"progress"===T.params.paginationType&&(e=T.params.paginationProgressRender?T.params.paginationProgressRender(T,T.params.paginationProgressbarClass):'<span class="'+T.params.paginationProgressbarClass+'"></span>',T.paginationContainer.html(e)),"custom"!==T.params.paginationType&&T.emit("onPaginationRendered",T,T.paginationContainer[0])}},T.update=function(e){function a(){T.rtl,T.translate;t=Math.min(Math.max(T.translate,T.maxTranslate()),T.minTranslate()),T.setWrapperTranslate(t),T.updateActiveIndex(),T.updateClasses()}if(T){T.updateContainerSize(),T.updateSlidesSize(),T.updateProgress(),T.updatePagination(),T.updateClasses(),T.params.scrollbar&&T.scrollbar&&T.scrollbar.set();var t;if(e){T.controller&&T.controller.spline&&(T.controller.spline=void 0),T.params.freeMode?(a(),T.params.autoHeight&&T.updateAutoHeight()):(("auto"===T.params.slidesPerView||T.params.slidesPerView>1)&&T.isEnd&&!T.params.centeredSlides?T.slideTo(T.slides.length-1,0,!1,!0):T.slideTo(T.activeIndex,0,!1,!0))||a()}else T.params.autoHeight&&T.updateAutoHeight()}},T.onResize=function(e){T.params.onBeforeResize&&T.params.onBeforeResize(T),T.params.breakpoints&&T.setBreakpoint();var a=T.params.allowSwipeToPrev,t=T.params.allowSwipeToNext;T.params.allowSwipeToPrev=T.params.allowSwipeToNext=!0,T.updateContainerSize(),T.updateSlidesSize(),("auto"===T.params.slidesPerView||T.params.freeMode||e)&&T.updatePagination(),T.params.scrollbar&&T.scrollbar&&T.scrollbar.set(),T.controller&&T.controller.spline&&(T.controller.spline=void 0);var s=!1;if(T.params.freeMode){var i=Math.min(Math.max(T.translate,T.maxTranslate()),T.minTranslate());T.setWrapperTranslate(i),T.updateActiveIndex(),T.updateClasses(),T.params.autoHeight&&T.updateAutoHeight()}else T.updateClasses(),s=("auto"===T.params.slidesPerView||T.params.slidesPerView>1)&&T.isEnd&&!T.params.centeredSlides?T.slideTo(T.slides.length-1,0,!1,!0):T.slideTo(T.activeIndex,0,!1,!0);T.params.lazyLoading&&!s&&T.lazy&&T.lazy.load(),T.params.allowSwipeToPrev=a,T.params.allowSwipeToNext=t,T.params.onAfterResize&&T.params.onAfterResize(T)},T.touchEventsDesktop={start:"mousedown",move:"mousemove",end:"mouseup"},window.navigator.pointerEnabled?T.touchEventsDesktop={start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled&&(T.touchEventsDesktop={start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}),T.touchEvents={start:T.support.touch||!T.params.simulateTouch?"touchstart":T.touchEventsDesktop.start,move:T.support.touch||!T.params.simulateTouch?"touchmove":T.touchEventsDesktop.move,end:T.support.touch||!T.params.simulateTouch?"touchend":T.touchEventsDesktop.end},(window.navigator.pointerEnabled||window.navigator.msPointerEnabled)&&("container"===T.params.touchEventsTarget?T.container:T.wrapper).addClass("swiper-wp8-"+T.params.direction),T.initEvents=function(e){var a=e?"off":"on",t=e?"removeEventListener":"addEventListener",s="container"===T.params.touchEventsTarget?T.container[0]:T.wrapper[0],r=T.support.touch?s:document,n=!!T.params.nested;if(T.browser.ie)s[t](T.touchEvents.start,T.onTouchStart,!1),r[t](T.touchEvents.move,T.onTouchMove,n),r[t](T.touchEvents.end,T.onTouchEnd,!1);else{if(T.support.touch){var o=!("touchstart"!==T.touchEvents.start||!T.support.passiveListener||!T.params.passiveListeners)&&{passive:!0,capture:!1};s[t](T.touchEvents.start,T.onTouchStart,o),s[t](T.touchEvents.move,T.onTouchMove,n),s[t](T.touchEvents.end,T.onTouchEnd,o)}(i.simulateTouch&&!T.device.ios&&!T.device.android||i.simulateTouch&&!T.support.touch&&T.device.ios)&&(s[t]("mousedown",T.onTouchStart,!1),document[t]("mousemove",T.onTouchMove,n),document[t]("mouseup",T.onTouchEnd,!1))}window[t]("resize",T.onResize),T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.nextButton[a]("click",T.onClickNext),T.params.a11y&&T.a11y&&T.nextButton[a]("keydown",T.a11y.onEnterKey)),T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.prevButton[a]("click",T.onClickPrev),T.params.a11y&&T.a11y&&T.prevButton[a]("keydown",T.a11y.onEnterKey)),T.params.pagination&&T.params.paginationClickable&&(T.paginationContainer[a]("click","."+T.params.bulletClass,T.onClickIndex),T.params.a11y&&T.a11y&&T.paginationContainer[a]("keydown","."+T.params.bulletClass,T.a11y.onEnterKey)),(T.params.preventClicks||T.params.preventClicksPropagation)&&s[t]("click",T.preventClicks,!0)},T.attachEvents=function(){T.initEvents()},T.detachEvents=function(){T.initEvents(!0)},T.allowClick=!0,T.preventClicks=function(e){T.allowClick||(T.params.preventClicks&&e.preventDefault(),T.params.preventClicksPropagation&&T.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))},T.onClickNext=function(e){e.preventDefault(),T.isEnd&&!T.params.loop||T.slideNext()},T.onClickPrev=function(e){e.preventDefault(),T.isBeginning&&!T.params.loop||T.slidePrev()},T.onClickIndex=function(a){a.preventDefault();var t=e(this).index()*T.params.slidesPerGroup;T.params.loop&&(t+=T.loopedSlides),T.slideTo(t)}, +T.updateClickedSlide=function(a){var t=o(a,"."+T.params.slideClass),s=!1;if(t)for(var i=0;i<T.slides.length;i++)T.slides[i]===t&&(s=!0);if(!t||!s)return T.clickedSlide=void 0,void(T.clickedIndex=void 0);if(T.clickedSlide=t,T.clickedIndex=e(t).index(),T.params.slideToClickedSlide&&void 0!==T.clickedIndex&&T.clickedIndex!==T.activeIndex){var r,n=T.clickedIndex,l="auto"===T.params.slidesPerView?T.currentSlidesPerView():T.params.slidesPerView;if(T.params.loop){if(T.animating)return;r=parseInt(e(T.clickedSlide).attr("data-swiper-slide-index"),10),T.params.centeredSlides?n<T.loopedSlides-l/2||n>T.slides.length-T.loopedSlides+l/2?(T.fixLoop(),n=T.wrapper.children("."+T.params.slideClass+'[data-swiper-slide-index="'+r+'"]:not(.'+T.params.slideDuplicateClass+")").eq(0).index(),setTimeout(function(){T.slideTo(n)},0)):T.slideTo(n):n>T.slides.length-l?(T.fixLoop(),n=T.wrapper.children("."+T.params.slideClass+'[data-swiper-slide-index="'+r+'"]:not(.'+T.params.slideDuplicateClass+")").eq(0).index(),setTimeout(function(){T.slideTo(n)},0)):T.slideTo(n)}else T.slideTo(n)}};var S,C,z,M,E,P,I,k,L,D,B="input, select, textarea, button, video",H=Date.now(),G=[];T.animating=!1,T.touches={startX:0,startY:0,currentX:0,currentY:0,diff:0};var X,A;T.onTouchStart=function(a){if(a.originalEvent&&(a=a.originalEvent),(X="touchstart"===a.type)||!("which"in a)||3!==a.which){if(T.params.noSwiping&&o(a,"."+T.params.noSwipingClass))return void(T.allowClick=!0);if(!T.params.swipeHandler||o(a,T.params.swipeHandler)){var t=T.touches.currentX="touchstart"===a.type?a.targetTouches[0].pageX:a.pageX,s=T.touches.currentY="touchstart"===a.type?a.targetTouches[0].pageY:a.pageY;if(!(T.device.ios&&T.params.iOSEdgeSwipeDetection&&t<=T.params.iOSEdgeSwipeThreshold)){if(S=!0,C=!1,z=!0,E=void 0,A=void 0,T.touches.startX=t,T.touches.startY=s,M=Date.now(),T.allowClick=!0,T.updateContainerSize(),T.swipeDirection=void 0,T.params.threshold>0&&(k=!1),"touchstart"!==a.type){var i=!0;e(a.target).is(B)&&(i=!1),document.activeElement&&e(document.activeElement).is(B)&&document.activeElement.blur(),i&&a.preventDefault()}T.emit("onTouchStart",T,a)}}}},T.onTouchMove=function(a){if(a.originalEvent&&(a=a.originalEvent),!X||"mousemove"!==a.type){if(a.preventedByNestedSwiper)return T.touches.startX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,void(T.touches.startY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY);if(T.params.onlyExternal)return T.allowClick=!1,void(S&&(T.touches.startX=T.touches.currentX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,T.touches.startY=T.touches.currentY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY,M=Date.now()));if(X&&T.params.touchReleaseOnEdges&&!T.params.loop)if(T.isHorizontal()){if(T.touches.currentX<T.touches.startX&&T.translate<=T.maxTranslate()||T.touches.currentX>T.touches.startX&&T.translate>=T.minTranslate())return}else if(T.touches.currentY<T.touches.startY&&T.translate<=T.maxTranslate()||T.touches.currentY>T.touches.startY&&T.translate>=T.minTranslate())return;if(X&&document.activeElement&&a.target===document.activeElement&&e(a.target).is(B))return C=!0,void(T.allowClick=!1);if(z&&T.emit("onTouchMove",T,a),!(a.targetTouches&&a.targetTouches.length>1)){if(T.touches.currentX="touchmove"===a.type?a.targetTouches[0].pageX:a.pageX,T.touches.currentY="touchmove"===a.type?a.targetTouches[0].pageY:a.pageY,void 0===E){var t;T.isHorizontal()&&T.touches.currentY===T.touches.startY||!T.isHorizontal()&&T.touches.currentX===T.touches.startX?E=!1:(t=180*Math.atan2(Math.abs(T.touches.currentY-T.touches.startY),Math.abs(T.touches.currentX-T.touches.startX))/Math.PI,E=T.isHorizontal()?t>T.params.touchAngle:90-t>T.params.touchAngle)}if(E&&T.emit("onTouchMoveOpposite",T,a),void 0===A&&(T.touches.currentX===T.touches.startX&&T.touches.currentY===T.touches.startY||(A=!0)),S){if(E)return void(S=!1);if(A){T.allowClick=!1,T.emit("onSliderMove",T,a),a.preventDefault(),T.params.touchMoveStopPropagation&&!T.params.nested&&a.stopPropagation(),C||(i.loop&&T.fixLoop(),I=T.getWrapperTranslate(),T.setWrapperTransition(0),T.animating&&T.wrapper.trigger("webkitTransitionEnd transitionend oTransitionEnd MSTransitionEnd msTransitionEnd"),T.params.autoplay&&T.autoplaying&&(T.params.autoplayDisableOnInteraction?T.stopAutoplay():T.pauseAutoplay()),D=!1,!T.params.grabCursor||T.params.allowSwipeToNext!==!0&&T.params.allowSwipeToPrev!==!0||T.setGrabCursor(!0)),C=!0;var s=T.touches.diff=T.isHorizontal()?T.touches.currentX-T.touches.startX:T.touches.currentY-T.touches.startY;s*=T.params.touchRatio,T.rtl&&(s=-s),T.swipeDirection=s>0?"prev":"next",P=s+I;var r=!0;if(s>0&&P>T.minTranslate()?(r=!1,T.params.resistance&&(P=T.minTranslate()-1+Math.pow(-T.minTranslate()+I+s,T.params.resistanceRatio))):s<0&&P<T.maxTranslate()&&(r=!1,T.params.resistance&&(P=T.maxTranslate()+1-Math.pow(T.maxTranslate()-I-s,T.params.resistanceRatio))),r&&(a.preventedByNestedSwiper=!0),!T.params.allowSwipeToNext&&"next"===T.swipeDirection&&P<I&&(P=I),!T.params.allowSwipeToPrev&&"prev"===T.swipeDirection&&P>I&&(P=I),T.params.threshold>0){if(!(Math.abs(s)>T.params.threshold||k))return void(P=I);if(!k)return k=!0,T.touches.startX=T.touches.currentX,T.touches.startY=T.touches.currentY,P=I,void(T.touches.diff=T.isHorizontal()?T.touches.currentX-T.touches.startX:T.touches.currentY-T.touches.startY)}T.params.followFinger&&((T.params.freeMode||T.params.watchSlidesProgress)&&T.updateActiveIndex(),T.params.freeMode&&(0===G.length&&G.push({position:T.touches[T.isHorizontal()?"startX":"startY"],time:M}),G.push({position:T.touches[T.isHorizontal()?"currentX":"currentY"],time:(new window.Date).getTime()})),T.updateProgress(P),T.setWrapperTranslate(P))}}}}},T.onTouchEnd=function(a){if(a.originalEvent&&(a=a.originalEvent),z&&T.emit("onTouchEnd",T,a),z=!1,S){T.params.grabCursor&&C&&S&&(T.params.allowSwipeToNext===!0||T.params.allowSwipeToPrev===!0)&&T.setGrabCursor(!1);var t=Date.now(),s=t-M;if(T.allowClick&&(T.updateClickedSlide(a),T.emit("onTap",T,a),s<300&&t-H>300&&(L&&clearTimeout(L),L=setTimeout(function(){T&&(T.params.paginationHide&&T.paginationContainer.length>0&&!e(a.target).hasClass(T.params.bulletClass)&&T.paginationContainer.toggleClass(T.params.paginationHiddenClass),T.emit("onClick",T,a))},300)),s<300&&t-H<300&&(L&&clearTimeout(L),T.emit("onDoubleTap",T,a))),H=Date.now(),setTimeout(function(){T&&(T.allowClick=!0)},0),!S||!C||!T.swipeDirection||0===T.touches.diff||P===I)return void(S=C=!1);S=C=!1;var i;if(i=T.params.followFinger?T.rtl?T.translate:-T.translate:-P,T.params.freeMode){if(i<-T.minTranslate())return void T.slideTo(T.activeIndex);if(i>-T.maxTranslate())return void(T.slides.length<T.snapGrid.length?T.slideTo(T.snapGrid.length-1):T.slideTo(T.slides.length-1));if(T.params.freeModeMomentum){if(G.length>1){var r=G.pop(),n=G.pop(),o=r.position-n.position,l=r.time-n.time;T.velocity=o/l,T.velocity=T.velocity/2,Math.abs(T.velocity)<T.params.freeModeMinimumVelocity&&(T.velocity=0),(l>150||(new window.Date).getTime()-r.time>300)&&(T.velocity=0)}else T.velocity=0;T.velocity=T.velocity*T.params.freeModeMomentumVelocityRatio,G.length=0;var p=1e3*T.params.freeModeMomentumRatio,d=T.velocity*p,u=T.translate+d;T.rtl&&(u=-u);var c,m=!1,h=20*Math.abs(T.velocity)*T.params.freeModeMomentumBounceRatio;if(u<T.maxTranslate())T.params.freeModeMomentumBounce?(u+T.maxTranslate()<-h&&(u=T.maxTranslate()-h),c=T.maxTranslate(),m=!0,D=!0):u=T.maxTranslate();else if(u>T.minTranslate())T.params.freeModeMomentumBounce?(u-T.minTranslate()>h&&(u=T.minTranslate()+h),c=T.minTranslate(),m=!0,D=!0):u=T.minTranslate();else if(T.params.freeModeSticky){var g,f=0;for(f=0;f<T.snapGrid.length;f+=1)if(T.snapGrid[f]>-u){g=f;break}u=Math.abs(T.snapGrid[g]-u)<Math.abs(T.snapGrid[g-1]-u)||"next"===T.swipeDirection?T.snapGrid[g]:T.snapGrid[g-1],T.rtl||(u=-u)}if(0!==T.velocity)p=T.rtl?Math.abs((-u-T.translate)/T.velocity):Math.abs((u-T.translate)/T.velocity);else if(T.params.freeModeSticky)return void T.slideReset();T.params.freeModeMomentumBounce&&m?(T.updateProgress(c),T.setWrapperTransition(p),T.setWrapperTranslate(u),T.onTransitionStart(),T.animating=!0,T.wrapper.transitionEnd(function(){T&&D&&(T.emit("onMomentumBounce",T),T.setWrapperTransition(T.params.speed),T.setWrapperTranslate(c),T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd()}))})):T.velocity?(T.updateProgress(u),T.setWrapperTransition(p),T.setWrapperTranslate(u),T.onTransitionStart(),T.animating||(T.animating=!0,T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd()}))):T.updateProgress(u),T.updateActiveIndex()}return void((!T.params.freeModeMomentum||s>=T.params.longSwipesMs)&&(T.updateProgress(),T.updateActiveIndex()))}var v,w=0,y=T.slidesSizesGrid[0];for(v=0;v<T.slidesGrid.length;v+=T.params.slidesPerGroup)void 0!==T.slidesGrid[v+T.params.slidesPerGroup]?i>=T.slidesGrid[v]&&i<T.slidesGrid[v+T.params.slidesPerGroup]&&(w=v,y=T.slidesGrid[v+T.params.slidesPerGroup]-T.slidesGrid[v]):i>=T.slidesGrid[v]&&(w=v,y=T.slidesGrid[T.slidesGrid.length-1]-T.slidesGrid[T.slidesGrid.length-2]);var x=(i-T.slidesGrid[w])/y;if(s>T.params.longSwipesMs){if(!T.params.longSwipes)return void T.slideTo(T.activeIndex);"next"===T.swipeDirection&&(x>=T.params.longSwipesRatio?T.slideTo(w+T.params.slidesPerGroup):T.slideTo(w)),"prev"===T.swipeDirection&&(x>1-T.params.longSwipesRatio?T.slideTo(w+T.params.slidesPerGroup):T.slideTo(w))}else{if(!T.params.shortSwipes)return void T.slideTo(T.activeIndex);"next"===T.swipeDirection&&T.slideTo(w+T.params.slidesPerGroup),"prev"===T.swipeDirection&&T.slideTo(w)}}},T._slideTo=function(e,a){return T.slideTo(e,a,!0,!0)},T.slideTo=function(e,a,t,s){void 0===t&&(t=!0),void 0===e&&(e=0),e<0&&(e=0),T.snapIndex=Math.floor(e/T.params.slidesPerGroup),T.snapIndex>=T.snapGrid.length&&(T.snapIndex=T.snapGrid.length-1);var i=-T.snapGrid[T.snapIndex];if(T.params.autoplay&&T.autoplaying&&(s||!T.params.autoplayDisableOnInteraction?T.pauseAutoplay(a):T.stopAutoplay()),T.updateProgress(i),T.params.normalizeSlideIndex)for(var r=0;r<T.slidesGrid.length;r++)-Math.floor(100*i)>=Math.floor(100*T.slidesGrid[r])&&(e=r);return!(!T.params.allowSwipeToNext&&i<T.translate&&i<T.minTranslate())&&(!(!T.params.allowSwipeToPrev&&i>T.translate&&i>T.maxTranslate()&&(T.activeIndex||0)!==e)&&(void 0===a&&(a=T.params.speed),T.previousIndex=T.activeIndex||0,T.activeIndex=e,T.updateRealIndex(),T.rtl&&-i===T.translate||!T.rtl&&i===T.translate?(T.params.autoHeight&&T.updateAutoHeight(),T.updateClasses(),"slide"!==T.params.effect&&T.setWrapperTranslate(i),!1):(T.updateClasses(),T.onTransitionStart(t),0===a||T.browser.lteIE9?(T.setWrapperTranslate(i),T.setWrapperTransition(0),T.onTransitionEnd(t)):(T.setWrapperTranslate(i),T.setWrapperTransition(a),T.animating||(T.animating=!0,T.wrapper.transitionEnd(function(){T&&T.onTransitionEnd(t)}))),!0)))},T.onTransitionStart=function(e){void 0===e&&(e=!0),T.params.autoHeight&&T.updateAutoHeight(),T.lazy&&T.lazy.onTransitionStart(),e&&(T.emit("onTransitionStart",T),T.activeIndex!==T.previousIndex&&(T.emit("onSlideChangeStart",T),T.activeIndex>T.previousIndex?T.emit("onSlideNextStart",T):T.emit("onSlidePrevStart",T)))},T.onTransitionEnd=function(e){T.animating=!1,T.setWrapperTransition(0),void 0===e&&(e=!0),T.lazy&&T.lazy.onTransitionEnd(),e&&(T.emit("onTransitionEnd",T),T.activeIndex!==T.previousIndex&&(T.emit("onSlideChangeEnd",T),T.activeIndex>T.previousIndex?T.emit("onSlideNextEnd",T):T.emit("onSlidePrevEnd",T))),T.params.history&&T.history&&T.history.setHistory(T.params.history,T.activeIndex),T.params.hashnav&&T.hashnav&&T.hashnav.setHash()},T.slideNext=function(e,a,t){if(T.params.loop){if(T.animating)return!1;T.fixLoop();T.container[0].clientLeft;return T.slideTo(T.activeIndex+T.params.slidesPerGroup,a,e,t)}return T.slideTo(T.activeIndex+T.params.slidesPerGroup,a,e,t)},T._slideNext=function(e){return T.slideNext(!0,e,!0)},T.slidePrev=function(e,a,t){if(T.params.loop){if(T.animating)return!1;T.fixLoop();T.container[0].clientLeft;return T.slideTo(T.activeIndex-1,a,e,t)}return T.slideTo(T.activeIndex-1,a,e,t)},T._slidePrev=function(e){return T.slidePrev(!0,e,!0)},T.slideReset=function(e,a,t){return T.slideTo(T.activeIndex,a,e)},T.disableTouchControl=function(){return T.params.onlyExternal=!0,!0},T.enableTouchControl=function(){return T.params.onlyExternal=!1,!0},T.setWrapperTransition=function(e,a){T.wrapper.transition(e),"slide"!==T.params.effect&&T.effects[T.params.effect]&&T.effects[T.params.effect].setTransition(e),T.params.parallax&&T.parallax&&T.parallax.setTransition(e),T.params.scrollbar&&T.scrollbar&&T.scrollbar.setTransition(e),T.params.control&&T.controller&&T.controller.setTransition(e,a),T.emit("onSetTransition",T,e)},T.setWrapperTranslate=function(e,a,t){var s=0,i=0;T.isHorizontal()?s=T.rtl?-e:e:i=e,T.params.roundLengths&&(s=r(s),i=r(i)),T.params.virtualTranslate||(T.support.transforms3d?T.wrapper.transform("translate3d("+s+"px, "+i+"px, 0px)"):T.wrapper.transform("translate("+s+"px, "+i+"px)")),T.translate=T.isHorizontal()?s:i;var n,o=T.maxTranslate()-T.minTranslate();n=0===o?0:(e-T.minTranslate())/o,n!==T.progress&&T.updateProgress(e),a&&T.updateActiveIndex(),"slide"!==T.params.effect&&T.effects[T.params.effect]&&T.effects[T.params.effect].setTranslate(T.translate),T.params.parallax&&T.parallax&&T.parallax.setTranslate(T.translate),T.params.scrollbar&&T.scrollbar&&T.scrollbar.setTranslate(T.translate),T.params.control&&T.controller&&T.controller.setTranslate(T.translate,t),T.emit("onSetTranslate",T,T.translate)},T.getTranslate=function(e,a){var t,s,i,r;return void 0===a&&(a="x"),T.params.virtualTranslate?T.rtl?-T.translate:T.translate:(i=window.getComputedStyle(e,null),window.WebKitCSSMatrix?(s=i.transform||i.webkitTransform,s.split(",").length>6&&(s=s.split(", ").map(function(e){return e.replace(",",".")}).join(", ")),r=new window.WebKitCSSMatrix("none"===s?"":s)):(r=i.MozTransform||i.OTransform||i.MsTransform||i.msTransform||i.transform||i.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,"),t=r.toString().split(",")),"x"===a&&(s=window.WebKitCSSMatrix?r.m41:16===t.length?parseFloat(t[12]):parseFloat(t[4])),"y"===a&&(s=window.WebKitCSSMatrix?r.m42:16===t.length?parseFloat(t[13]):parseFloat(t[5])),T.rtl&&s&&(s=-s),s||0)},T.getWrapperTranslate=function(e){return void 0===e&&(e=T.isHorizontal()?"x":"y"),T.getTranslate(T.wrapper[0],e)},T.observers=[],T.initObservers=function(){if(T.params.observeParents)for(var e=T.container.parents(),a=0;a<e.length;a++)l(e[a]);l(T.container[0],{childList:!1}),l(T.wrapper[0],{attributes:!1})},T.disconnectObservers=function(){for(var e=0;e<T.observers.length;e++)T.observers[e].disconnect();T.observers=[]},T.createLoop=function(){T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass).remove();var a=T.wrapper.children("."+T.params.slideClass);"auto"!==T.params.slidesPerView||T.params.loopedSlides||(T.params.loopedSlides=a.length),T.loopedSlides=parseInt(T.params.loopedSlides||T.params.slidesPerView,10),T.loopedSlides=T.loopedSlides+T.params.loopAdditionalSlides,T.loopedSlides>a.length&&(T.loopedSlides=a.length);var t,s=[],i=[];for(a.each(function(t,r){var n=e(this);t<T.loopedSlides&&i.push(r),t<a.length&&t>=a.length-T.loopedSlides&&s.push(r),n.attr("data-swiper-slide-index",t)}),t=0;t<i.length;t++)T.wrapper.append(e(i[t].cloneNode(!0)).addClass(T.params.slideDuplicateClass));for(t=s.length-1;t>=0;t--)T.wrapper.prepend(e(s[t].cloneNode(!0)).addClass(T.params.slideDuplicateClass))},T.destroyLoop=function(){T.wrapper.children("."+T.params.slideClass+"."+T.params.slideDuplicateClass).remove(),T.slides.removeAttr("data-swiper-slide-index")},T.reLoop=function(e){var a=T.activeIndex-T.loopedSlides;T.destroyLoop(),T.createLoop(),T.updateSlidesSize(),e&&T.slideTo(a+T.loopedSlides,0,!1)},T.fixLoop=function(){var e;T.activeIndex<T.loopedSlides?(e=T.slides.length-3*T.loopedSlides+T.activeIndex,e+=T.loopedSlides,T.slideTo(e,0,!1,!0)):("auto"===T.params.slidesPerView&&T.activeIndex>=2*T.loopedSlides||T.activeIndex>T.slides.length-2*T.params.slidesPerView)&&(e=-T.slides.length+T.activeIndex+T.loopedSlides,e+=T.loopedSlides,T.slideTo(e,0,!1,!0))},T.appendSlide=function(e){if(T.params.loop&&T.destroyLoop(),"object"==typeof e&&e.length)for(var a=0;a<e.length;a++)e[a]&&T.wrapper.append(e[a]);else T.wrapper.append(e);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0)},T.prependSlide=function(e){T.params.loop&&T.destroyLoop();var a=T.activeIndex+1;if("object"==typeof e&&e.length){for(var t=0;t<e.length;t++)e[t]&&T.wrapper.prepend(e[t]);a=T.activeIndex+e.length}else T.wrapper.prepend(e);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0),T.slideTo(a,0,!1)},T.removeSlide=function(e){T.params.loop&&(T.destroyLoop(),T.slides=T.wrapper.children("."+T.params.slideClass));var a,t=T.activeIndex;if("object"==typeof e&&e.length){for(var s=0;s<e.length;s++)a=e[s],T.slides[a]&&T.slides.eq(a).remove(),a<t&&t--;t=Math.max(t,0)}else a=e,T.slides[a]&&T.slides.eq(a).remove(),a<t&&t--,t=Math.max(t,0);T.params.loop&&T.createLoop(),T.params.observer&&T.support.observer||T.update(!0),T.params.loop?T.slideTo(t+T.loopedSlides,0,!1):T.slideTo(t,0,!1)},T.removeAllSlides=function(){for(var e=[],a=0;a<T.slides.length;a++)e.push(a);T.removeSlide(e)},T.effects={fade:{setTranslate:function(){for(var e=0;e<T.slides.length;e++){var a=T.slides.eq(e),t=a[0].swiperSlideOffset,s=-t;T.params.virtualTranslate||(s-=T.translate);var i=0;T.isHorizontal()||(i=s,s=0);var r=T.params.fade.crossFade?Math.max(1-Math.abs(a[0].progress),0):1+Math.min(Math.max(a[0].progress,-1),0);a.css({opacity:r}).transform("translate3d("+s+"px, "+i+"px, 0px)")}},setTransition:function(e){if(T.slides.transition(e),T.params.virtualTranslate&&0!==e){var a=!1;T.slides.transitionEnd(function(){if(!a&&T){a=!0,T.animating=!1;for(var e=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],t=0;t<e.length;t++)T.wrapper.trigger(e[t])}})}}},flip:{setTranslate:function(){for(var a=0;a<T.slides.length;a++){var t=T.slides.eq(a),s=t[0].progress;T.params.flip.limitRotation&&(s=Math.max(Math.min(t[0].progress,1),-1));var i=t[0].swiperSlideOffset,r=-180*s,n=r,o=0,l=-i,p=0;if(T.isHorizontal()?T.rtl&&(n=-n):(p=l,l=0,o=-n,n=0),t[0].style.zIndex=-Math.abs(Math.round(s))+T.slides.length,T.params.flip.slideShadows){var d=T.isHorizontal()?t.find(".swiper-slide-shadow-left"):t.find(".swiper-slide-shadow-top"),u=T.isHorizontal()?t.find(".swiper-slide-shadow-right"):t.find(".swiper-slide-shadow-bottom");0===d.length&&(d=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),t.append(d)),0===u.length&&(u=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),t.append(u)),d.length&&(d[0].style.opacity=Math.max(-s,0)),u.length&&(u[0].style.opacity=Math.max(s,0))}t.transform("translate3d("+l+"px, "+p+"px, 0px) rotateX("+o+"deg) rotateY("+n+"deg)")}},setTransition:function(a){if(T.slides.transition(a).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(a),T.params.virtualTranslate&&0!==a){var t=!1;T.slides.eq(T.activeIndex).transitionEnd(function(){if(!t&&T&&e(this).hasClass(T.params.slideActiveClass)){t=!0,T.animating=!1;for(var a=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],s=0;s<a.length;s++)T.wrapper.trigger(a[s])}})}}},cube:{setTranslate:function(){var a,t=0;T.params.cube.shadow&&(T.isHorizontal()?(a=T.wrapper.find(".swiper-cube-shadow"),0===a.length&&(a=e('<div class="swiper-cube-shadow"></div>'),T.wrapper.append(a)),a.css({height:T.width+"px"})):(a=T.container.find(".swiper-cube-shadow"),0===a.length&&(a=e('<div class="swiper-cube-shadow"></div>'),T.container.append(a))));for(var s=0;s<T.slides.length;s++){var i=T.slides.eq(s),r=90*s,n=Math.floor(r/360);T.rtl&&(r=-r,n=Math.floor(-r/360));var o=Math.max(Math.min(i[0].progress,1),-1),l=0,p=0,d=0;s%4==0?(l=4*-n*T.size,d=0):(s-1)%4==0?(l=0,d=4*-n*T.size):(s-2)%4==0?(l=T.size+4*n*T.size,d=T.size):(s-3)%4==0&&(l=-T.size,d=3*T.size+4*T.size*n),T.rtl&&(l=-l),T.isHorizontal()||(p=l,l=0);var u="rotateX("+(T.isHorizontal()?0:-r)+"deg) rotateY("+(T.isHorizontal()?r:0)+"deg) translate3d("+l+"px, "+p+"px, "+d+"px)";if(o<=1&&o>-1&&(t=90*s+90*o,T.rtl&&(t=90*-s-90*o)),i.transform(u),T.params.cube.slideShadows){var c=T.isHorizontal()?i.find(".swiper-slide-shadow-left"):i.find(".swiper-slide-shadow-top"),m=T.isHorizontal()?i.find(".swiper-slide-shadow-right"):i.find(".swiper-slide-shadow-bottom");0===c.length&&(c=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),i.append(c)),0===m.length&&(m=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),i.append(m)),c.length&&(c[0].style.opacity=Math.max(-o,0)),m.length&&(m[0].style.opacity=Math.max(o,0))}}if(T.wrapper.css({"-webkit-transform-origin":"50% 50% -"+T.size/2+"px","-moz-transform-origin":"50% 50% -"+T.size/2+"px","-ms-transform-origin":"50% 50% -"+T.size/2+"px","transform-origin":"50% 50% -"+T.size/2+"px"}),T.params.cube.shadow)if(T.isHorizontal())a.transform("translate3d(0px, "+(T.width/2+T.params.cube.shadowOffset)+"px, "+-T.width/2+"px) rotateX(90deg) rotateZ(0deg) scale("+T.params.cube.shadowScale+")");else{var h=Math.abs(t)-90*Math.floor(Math.abs(t)/90),g=1.5-(Math.sin(2*h*Math.PI/360)/2+Math.cos(2*h*Math.PI/360)/2),f=T.params.cube.shadowScale,v=T.params.cube.shadowScale/g,w=T.params.cube.shadowOffset;a.transform("scale3d("+f+", 1, "+v+") translate3d(0px, "+(T.height/2+w)+"px, "+-T.height/2/v+"px) rotateX(-90deg)")}var y=T.isSafari||T.isUiWebView?-T.size/2:0;T.wrapper.transform("translate3d(0px,0,"+y+"px) rotateX("+(T.isHorizontal()?0:t)+"deg) rotateY("+(T.isHorizontal()?-t:0)+"deg)")},setTransition:function(e){T.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),T.params.cube.shadow&&!T.isHorizontal()&&T.container.find(".swiper-cube-shadow").transition(e)}},coverflow:{setTranslate:function(){for(var a=T.translate,t=T.isHorizontal()?-a+T.width/2:-a+T.height/2,s=T.isHorizontal()?T.params.coverflow.rotate:-T.params.coverflow.rotate,i=T.params.coverflow.depth,r=0,n=T.slides.length;r<n;r++){var o=T.slides.eq(r),l=T.slidesSizesGrid[r],p=o[0].swiperSlideOffset,d=(t-p-l/2)/l*T.params.coverflow.modifier,u=T.isHorizontal()?s*d:0,c=T.isHorizontal()?0:s*d,m=-i*Math.abs(d),h=T.isHorizontal()?0:T.params.coverflow.stretch*d,g=T.isHorizontal()?T.params.coverflow.stretch*d:0;Math.abs(g)<.001&&(g=0),Math.abs(h)<.001&&(h=0),Math.abs(m)<.001&&(m=0),Math.abs(u)<.001&&(u=0),Math.abs(c)<.001&&(c=0);var f="translate3d("+g+"px,"+h+"px,"+m+"px) rotateX("+c+"deg) rotateY("+u+"deg)";if(o.transform(f),o[0].style.zIndex=1-Math.abs(Math.round(d)),T.params.coverflow.slideShadows){var v=T.isHorizontal()?o.find(".swiper-slide-shadow-left"):o.find(".swiper-slide-shadow-top"),w=T.isHorizontal()?o.find(".swiper-slide-shadow-right"):o.find(".swiper-slide-shadow-bottom");0===v.length&&(v=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"left":"top")+'"></div>'),o.append(v)),0===w.length&&(w=e('<div class="swiper-slide-shadow-'+(T.isHorizontal()?"right":"bottom")+'"></div>'),o.append(w)),v.length&&(v[0].style.opacity=d>0?d:0),w.length&&(w[0].style.opacity=-d>0?-d:0)}}if(T.browser.ie){T.wrapper[0].style.perspectiveOrigin=t+"px 50%"}},setTransition:function(e){T.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}}},T.lazy={initialImageLoaded:!1,loadImageInSlide:function(a,t){if(void 0!==a&&(void 0===t&&(t=!0),0!==T.slides.length)){var s=T.slides.eq(a),i=s.find("."+T.params.lazyLoadingClass+":not(."+T.params.lazyStatusLoadedClass+"):not(."+T.params.lazyStatusLoadingClass+")");!s.hasClass(T.params.lazyLoadingClass)||s.hasClass(T.params.lazyStatusLoadedClass)||s.hasClass(T.params.lazyStatusLoadingClass)||(i=i.add(s[0])),0!==i.length&&i.each(function(){var a=e(this);a.addClass(T.params.lazyStatusLoadingClass);var i=a.attr("data-background"),r=a.attr("data-src"),n=a.attr("data-srcset"),o=a.attr("data-sizes");T.loadImage(a[0],r||i,n,o,!1,function(){if(void 0!==T&&null!==T&&T){if(i?(a.css("background-image",'url("'+i+'")'),a.removeAttr("data-background")):(n&&(a.attr("srcset",n),a.removeAttr("data-srcset")),o&&(a.attr("sizes",o),a.removeAttr("data-sizes")),r&&(a.attr("src",r),a.removeAttr("data-src"))),a.addClass(T.params.lazyStatusLoadedClass).removeClass(T.params.lazyStatusLoadingClass),s.find("."+T.params.lazyPreloaderClass+", ."+T.params.preloaderClass).remove(),T.params.loop&&t){var e=s.attr("data-swiper-slide-index");if(s.hasClass(T.params.slideDuplicateClass)){var l=T.wrapper.children('[data-swiper-slide-index="'+e+'"]:not(.'+T.params.slideDuplicateClass+")");T.lazy.loadImageInSlide(l.index(),!1)}else{var p=T.wrapper.children("."+T.params.slideDuplicateClass+'[data-swiper-slide-index="'+e+'"]');T.lazy.loadImageInSlide(p.index(),!1)}}T.emit("onLazyImageReady",T,s[0],a[0])}}),T.emit("onLazyImageLoad",T,s[0],a[0])})}},load:function(){var a,t=T.params.slidesPerView;if("auto"===t&&(t=0),T.lazy.initialImageLoaded||(T.lazy.initialImageLoaded=!0),T.params.watchSlidesVisibility)T.wrapper.children("."+T.params.slideVisibleClass).each(function(){T.lazy.loadImageInSlide(e(this).index())});else if(t>1)for(a=T.activeIndex;a<T.activeIndex+t;a++)T.slides[a]&&T.lazy.loadImageInSlide(a);else T.lazy.loadImageInSlide(T.activeIndex);if(T.params.lazyLoadingInPrevNext)if(t>1||T.params.lazyLoadingInPrevNextAmount&&T.params.lazyLoadingInPrevNextAmount>1){var s=T.params.lazyLoadingInPrevNextAmount,i=t,r=Math.min(T.activeIndex+i+Math.max(s,i),T.slides.length),n=Math.max(T.activeIndex-Math.max(i,s),0);for(a=T.activeIndex+t;a<r;a++)T.slides[a]&&T.lazy.loadImageInSlide(a);for(a=n;a<T.activeIndex;a++)T.slides[a]&&T.lazy.loadImageInSlide(a)}else{var o=T.wrapper.children("."+T.params.slideNextClass);o.length>0&&T.lazy.loadImageInSlide(o.index());var l=T.wrapper.children("."+T.params.slidePrevClass);l.length>0&&T.lazy.loadImageInSlide(l.index())}},onTransitionStart:function(){T.params.lazyLoading&&(T.params.lazyLoadingOnTransitionStart||!T.params.lazyLoadingOnTransitionStart&&!T.lazy.initialImageLoaded)&&T.lazy.load()},onTransitionEnd:function(){T.params.lazyLoading&&!T.params.lazyLoadingOnTransitionStart&&T.lazy.load()}},T.scrollbar={isTouched:!1,setDragPosition:function(e){var a=T.scrollbar,t=T.isHorizontal()?"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].pageX:e.pageX||e.clientX:"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].pageY:e.pageY||e.clientY,s=t-a.track.offset()[T.isHorizontal()?"left":"top"]-a.dragSize/2,i=-T.minTranslate()*a.moveDivider,r=-T.maxTranslate()*a.moveDivider;s<i?s=i:s>r&&(s=r),s=-s/a.moveDivider,T.updateProgress(s),T.setWrapperTranslate(s,!0)},dragStart:function(e){var a=T.scrollbar;a.isTouched=!0,e.preventDefault(),e.stopPropagation(),a.setDragPosition(e),clearTimeout(a.dragTimeout),a.track.transition(0),T.params.scrollbarHide&&a.track.css("opacity",1),T.wrapper.transition(100),a.drag.transition(100),T.emit("onScrollbarDragStart",T)},dragMove:function(e){var a=T.scrollbar;a.isTouched&&(e.preventDefault?e.preventDefault():e.returnValue=!1,a.setDragPosition(e),T.wrapper.transition(0),a.track.transition(0),a.drag.transition(0),T.emit("onScrollbarDragMove",T))},dragEnd:function(e){var a=T.scrollbar;a.isTouched&&(a.isTouched=!1,T.params.scrollbarHide&&(clearTimeout(a.dragTimeout),a.dragTimeout=setTimeout(function(){a.track.css("opacity",0),a.track.transition(400)},1e3)),T.emit("onScrollbarDragEnd",T),T.params.scrollbarSnapOnRelease&&T.slideReset())},draggableEvents:function(){return T.params.simulateTouch!==!1||T.support.touch?T.touchEvents:T.touchEventsDesktop}(),enableDraggable:function(){var a=T.scrollbar,t=T.support.touch?a.track:document;e(a.track).on(a.draggableEvents.start,a.dragStart),e(t).on(a.draggableEvents.move,a.dragMove),e(t).on(a.draggableEvents.end,a.dragEnd)},disableDraggable:function(){var a=T.scrollbar,t=T.support.touch?a.track:document;e(a.track).off(a.draggableEvents.start,a.dragStart),e(t).off(a.draggableEvents.move,a.dragMove),e(t).off(a.draggableEvents.end,a.dragEnd)},set:function(){if(T.params.scrollbar){var a=T.scrollbar;a.track=e(T.params.scrollbar),T.params.uniqueNavElements&&"string"==typeof T.params.scrollbar&&a.track.length>1&&1===T.container.find(T.params.scrollbar).length&&(a.track=T.container.find(T.params.scrollbar)),a.drag=a.track.find(".swiper-scrollbar-drag"),0===a.drag.length&&(a.drag=e('<div class="swiper-scrollbar-drag"></div>'),a.track.append(a.drag)),a.drag[0].style.width="",a.drag[0].style.height="",a.trackSize=T.isHorizontal()?a.track[0].offsetWidth:a.track[0].offsetHeight,a.divider=T.size/T.virtualSize,a.moveDivider=a.divider*(a.trackSize/T.size),a.dragSize=a.trackSize*a.divider,T.isHorizontal()?a.drag[0].style.width=a.dragSize+"px":a.drag[0].style.height=a.dragSize+"px",a.divider>=1?a.track[0].style.display="none":a.track[0].style.display="",T.params.scrollbarHide&&(a.track[0].style.opacity=0)}},setTranslate:function(){if(T.params.scrollbar){var e,a=T.scrollbar,t=(T.translate,a.dragSize);e=(a.trackSize-a.dragSize)*T.progress,T.rtl&&T.isHorizontal()?(e=-e,e>0?(t=a.dragSize-e,e=0):-e+a.dragSize>a.trackSize&&(t=a.trackSize+e)):e<0?(t=a.dragSize+e,e=0):e+a.dragSize>a.trackSize&&(t=a.trackSize-e),T.isHorizontal()?(T.support.transforms3d?a.drag.transform("translate3d("+e+"px, 0, 0)"):a.drag.transform("translateX("+e+"px)"),a.drag[0].style.width=t+"px"):(T.support.transforms3d?a.drag.transform("translate3d(0px, "+e+"px, 0)"):a.drag.transform("translateY("+e+"px)"),a.drag[0].style.height=t+"px"),T.params.scrollbarHide&&(clearTimeout(a.timeout),a.track[0].style.opacity=1,a.timeout=setTimeout(function(){a.track[0].style.opacity=0,a.track.transition(400)},1e3))}},setTransition:function(e){T.params.scrollbar&&T.scrollbar.drag.transition(e)}},T.controller={LinearSpline:function(e,a){var t=function(){var e,a,t;return function(s,i){for(a=-1,e=s.length;e-a>1;)s[t=e+a>>1]<=i?a=t:e=t;return e}}();this.x=e,this.y=a,this.lastIndex=e.length-1;var s,i;this.x.length;this.interpolate=function(e){return e?(i=t(this.x,e),s=i-1,(e-this.x[s])*(this.y[i]-this.y[s])/(this.x[i]-this.x[s])+this.y[s]):0}},getInterpolateFunction:function(e){T.controller.spline||(T.controller.spline=T.params.loop?new T.controller.LinearSpline(T.slidesGrid,e.slidesGrid):new T.controller.LinearSpline(T.snapGrid,e.snapGrid))},setTranslate:function(e,t){function s(a){e=a.rtl&&"horizontal"===a.params.direction?-T.translate:T.translate,"slide"===T.params.controlBy&&(T.controller.getInterpolateFunction(a),r=-T.controller.spline.interpolate(-e)),r&&"container"!==T.params.controlBy||(i=(a.maxTranslate()-a.minTranslate())/(T.maxTranslate()-T.minTranslate()),r=(e-T.minTranslate())*i+a.minTranslate()),T.params.controlInverse&&(r=a.maxTranslate()-r),a.updateProgress(r),a.setWrapperTranslate(r,!1,T),a.updateActiveIndex()}var i,r,n=T.params.control;if(Array.isArray(n))for(var o=0;o<n.length;o++)n[o]!==t&&n[o]instanceof a&&s(n[o]);else n instanceof a&&t!==n&&s(n)},setTransition:function(e,t){function s(a){a.setWrapperTransition(e,T),0!==e&&(a.onTransitionStart(),a.wrapper.transitionEnd(function(){r&&(a.params.loop&&"slide"===T.params.controlBy&&a.fixLoop(),a.onTransitionEnd())}))}var i,r=T.params.control;if(Array.isArray(r))for(i=0;i<r.length;i++)r[i]!==t&&r[i]instanceof a&&s(r[i]);else r instanceof a&&t!==r&&s(r)}},T.hashnav={onHashCange:function(e,a){var t=document.location.hash.replace("#","");t!==T.slides.eq(T.activeIndex).attr("data-hash")&&T.slideTo(T.wrapper.children("."+T.params.slideClass+'[data-hash="'+t+'"]').index())},attachEvents:function(a){var t=a?"off":"on";e(window)[t]("hashchange",T.hashnav.onHashCange)},setHash:function(){ +if(T.hashnav.initialized&&T.params.hashnav)if(T.params.replaceState&&window.history&&window.history.replaceState)window.history.replaceState(null,null,"#"+T.slides.eq(T.activeIndex).attr("data-hash")||"");else{var e=T.slides.eq(T.activeIndex),a=e.attr("data-hash")||e.attr("data-history");document.location.hash=a||""}},init:function(){if(T.params.hashnav&&!T.params.history){T.hashnav.initialized=!0;var e=document.location.hash.replace("#","");if(e)for(var a=0,t=T.slides.length;a<t;a++){var s=T.slides.eq(a),i=s.attr("data-hash")||s.attr("data-history");if(i===e&&!s.hasClass(T.params.slideDuplicateClass)){var r=s.index();T.slideTo(r,0,T.params.runCallbacksOnInit,!0)}}T.params.hashnavWatchState&&T.hashnav.attachEvents()}},destroy:function(){T.params.hashnavWatchState&&T.hashnav.attachEvents(!0)}},T.history={init:function(){if(T.params.history){if(!window.history||!window.history.pushState)return T.params.history=!1,void(T.params.hashnav=!0);T.history.initialized=!0,this.paths=this.getPathValues(),(this.paths.key||this.paths.value)&&(this.scrollToSlide(0,this.paths.value,T.params.runCallbacksOnInit),T.params.replaceState||window.addEventListener("popstate",this.setHistoryPopState))}},setHistoryPopState:function(){T.history.paths=T.history.getPathValues(),T.history.scrollToSlide(T.params.speed,T.history.paths.value,!1)},getPathValues:function(){var e=window.location.pathname.slice(1).split("/"),a=e.length;return{key:e[a-2],value:e[a-1]}},setHistory:function(e,a){if(T.history.initialized&&T.params.history){var t=T.slides.eq(a),s=this.slugify(t.attr("data-history"));window.location.pathname.includes(e)||(s=e+"/"+s),T.params.replaceState?window.history.replaceState(null,null,s):window.history.pushState(null,null,s)}},slugify:function(e){return e.toString().toLowerCase().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\-\-+/g,"-").replace(/^-+/,"").replace(/-+$/,"")},scrollToSlide:function(e,a,t){if(a)for(var s=0,i=T.slides.length;s<i;s++){var r=T.slides.eq(s),n=this.slugify(r.attr("data-history"));if(n===a&&!r.hasClass(T.params.slideDuplicateClass)){var o=r.index();T.slideTo(o,e,t)}}else T.slideTo(0,e,t)}},T.disableKeyboardControl=function(){T.params.keyboardControl=!1,e(document).off("keydown",p)},T.enableKeyboardControl=function(){T.params.keyboardControl=!0,e(document).on("keydown",p)},T.mousewheel={event:!1,lastScrollTime:(new window.Date).getTime()},T.params.mousewheelControl&&(T.mousewheel.event=navigator.userAgent.indexOf("firefox")>-1?"DOMMouseScroll":function(){var e="onwheel"in document;if(!e){var a=document.createElement("div");a.setAttribute("onwheel","return;"),e="function"==typeof a.onwheel}return!e&&document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0&&(e=document.implementation.hasFeature("Events.wheel","3.0")),e}()?"wheel":"mousewheel"),T.disableMousewheelControl=function(){if(!T.mousewheel.event)return!1;var a=T.container;return"container"!==T.params.mousewheelEventsTarged&&(a=e(T.params.mousewheelEventsTarged)),a.off(T.mousewheel.event,u),T.params.mousewheelControl=!1,!0},T.enableMousewheelControl=function(){if(!T.mousewheel.event)return!1;var a=T.container;return"container"!==T.params.mousewheelEventsTarged&&(a=e(T.params.mousewheelEventsTarged)),a.on(T.mousewheel.event,u),T.params.mousewheelControl=!0,!0},T.parallax={setTranslate:function(){T.container.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){c(this,T.progress)}),T.slides.each(function(){var a=e(this);a.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){c(this,Math.min(Math.max(a[0].progress,-1),1))})})},setTransition:function(a){void 0===a&&(a=T.params.speed),T.container.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y]").each(function(){var t=e(this),s=parseInt(t.attr("data-swiper-parallax-duration"),10)||a;0===a&&(s=0),t.transition(s)})}},T.zoom={scale:1,currentScale:1,isScaling:!1,gesture:{slide:void 0,slideWidth:void 0,slideHeight:void 0,image:void 0,imageWrap:void 0,zoomMax:T.params.zoomMax},image:{isTouched:void 0,isMoved:void 0,currentX:void 0,currentY:void 0,minX:void 0,minY:void 0,maxX:void 0,maxY:void 0,width:void 0,height:void 0,startX:void 0,startY:void 0,touchesStart:{},touchesCurrent:{}},velocity:{x:void 0,y:void 0,prevPositionX:void 0,prevPositionY:void 0,prevTime:void 0},getDistanceBetweenTouches:function(e){if(e.targetTouches.length<2)return 1;var a=e.targetTouches[0].pageX,t=e.targetTouches[0].pageY,s=e.targetTouches[1].pageX,i=e.targetTouches[1].pageY;return Math.sqrt(Math.pow(s-a,2)+Math.pow(i-t,2))},onGestureStart:function(a){var t=T.zoom;if(!T.support.gestures){if("touchstart"!==a.type||"touchstart"===a.type&&a.targetTouches.length<2)return;t.gesture.scaleStart=t.getDistanceBetweenTouches(a)}if(!(t.gesture.slide&&t.gesture.slide.length||(t.gesture.slide=e(this),0===t.gesture.slide.length&&(t.gesture.slide=T.slides.eq(T.activeIndex)),t.gesture.image=t.gesture.slide.find("img, svg, canvas"),t.gesture.imageWrap=t.gesture.image.parent("."+T.params.zoomContainerClass),t.gesture.zoomMax=t.gesture.imageWrap.attr("data-swiper-zoom")||T.params.zoomMax,0!==t.gesture.imageWrap.length)))return void(t.gesture.image=void 0);t.gesture.image.transition(0),t.isScaling=!0},onGestureChange:function(e){var a=T.zoom;if(!T.support.gestures){if("touchmove"!==e.type||"touchmove"===e.type&&e.targetTouches.length<2)return;a.gesture.scaleMove=a.getDistanceBetweenTouches(e)}a.gesture.image&&0!==a.gesture.image.length&&(T.support.gestures?a.scale=e.scale*a.currentScale:a.scale=a.gesture.scaleMove/a.gesture.scaleStart*a.currentScale,a.scale>a.gesture.zoomMax&&(a.scale=a.gesture.zoomMax-1+Math.pow(a.scale-a.gesture.zoomMax+1,.5)),a.scale<T.params.zoomMin&&(a.scale=T.params.zoomMin+1-Math.pow(T.params.zoomMin-a.scale+1,.5)),a.gesture.image.transform("translate3d(0,0,0) scale("+a.scale+")"))},onGestureEnd:function(e){var a=T.zoom;!T.support.gestures&&("touchend"!==e.type||"touchend"===e.type&&e.changedTouches.length<2)||a.gesture.image&&0!==a.gesture.image.length&&(a.scale=Math.max(Math.min(a.scale,a.gesture.zoomMax),T.params.zoomMin),a.gesture.image.transition(T.params.speed).transform("translate3d(0,0,0) scale("+a.scale+")"),a.currentScale=a.scale,a.isScaling=!1,1===a.scale&&(a.gesture.slide=void 0))},onTouchStart:function(e,a){var t=e.zoom;t.gesture.image&&0!==t.gesture.image.length&&(t.image.isTouched||("android"===e.device.os&&a.preventDefault(),t.image.isTouched=!0,t.image.touchesStart.x="touchstart"===a.type?a.targetTouches[0].pageX:a.pageX,t.image.touchesStart.y="touchstart"===a.type?a.targetTouches[0].pageY:a.pageY))},onTouchMove:function(e){var a=T.zoom;if(a.gesture.image&&0!==a.gesture.image.length&&(T.allowClick=!1,a.image.isTouched&&a.gesture.slide)){a.image.isMoved||(a.image.width=a.gesture.image[0].offsetWidth,a.image.height=a.gesture.image[0].offsetHeight,a.image.startX=T.getTranslate(a.gesture.imageWrap[0],"x")||0,a.image.startY=T.getTranslate(a.gesture.imageWrap[0],"y")||0,a.gesture.slideWidth=a.gesture.slide[0].offsetWidth,a.gesture.slideHeight=a.gesture.slide[0].offsetHeight,a.gesture.imageWrap.transition(0),T.rtl&&(a.image.startX=-a.image.startX),T.rtl&&(a.image.startY=-a.image.startY));var t=a.image.width*a.scale,s=a.image.height*a.scale;if(!(t<a.gesture.slideWidth&&s<a.gesture.slideHeight)){if(a.image.minX=Math.min(a.gesture.slideWidth/2-t/2,0),a.image.maxX=-a.image.minX,a.image.minY=Math.min(a.gesture.slideHeight/2-s/2,0),a.image.maxY=-a.image.minY,a.image.touchesCurrent.x="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,a.image.touchesCurrent.y="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,!a.image.isMoved&&!a.isScaling){if(T.isHorizontal()&&Math.floor(a.image.minX)===Math.floor(a.image.startX)&&a.image.touchesCurrent.x<a.image.touchesStart.x||Math.floor(a.image.maxX)===Math.floor(a.image.startX)&&a.image.touchesCurrent.x>a.image.touchesStart.x)return void(a.image.isTouched=!1);if(!T.isHorizontal()&&Math.floor(a.image.minY)===Math.floor(a.image.startY)&&a.image.touchesCurrent.y<a.image.touchesStart.y||Math.floor(a.image.maxY)===Math.floor(a.image.startY)&&a.image.touchesCurrent.y>a.image.touchesStart.y)return void(a.image.isTouched=!1)}e.preventDefault(),e.stopPropagation(),a.image.isMoved=!0,a.image.currentX=a.image.touchesCurrent.x-a.image.touchesStart.x+a.image.startX,a.image.currentY=a.image.touchesCurrent.y-a.image.touchesStart.y+a.image.startY,a.image.currentX<a.image.minX&&(a.image.currentX=a.image.minX+1-Math.pow(a.image.minX-a.image.currentX+1,.8)),a.image.currentX>a.image.maxX&&(a.image.currentX=a.image.maxX-1+Math.pow(a.image.currentX-a.image.maxX+1,.8)),a.image.currentY<a.image.minY&&(a.image.currentY=a.image.minY+1-Math.pow(a.image.minY-a.image.currentY+1,.8)),a.image.currentY>a.image.maxY&&(a.image.currentY=a.image.maxY-1+Math.pow(a.image.currentY-a.image.maxY+1,.8)),a.velocity.prevPositionX||(a.velocity.prevPositionX=a.image.touchesCurrent.x),a.velocity.prevPositionY||(a.velocity.prevPositionY=a.image.touchesCurrent.y),a.velocity.prevTime||(a.velocity.prevTime=Date.now()),a.velocity.x=(a.image.touchesCurrent.x-a.velocity.prevPositionX)/(Date.now()-a.velocity.prevTime)/2,a.velocity.y=(a.image.touchesCurrent.y-a.velocity.prevPositionY)/(Date.now()-a.velocity.prevTime)/2,Math.abs(a.image.touchesCurrent.x-a.velocity.prevPositionX)<2&&(a.velocity.x=0),Math.abs(a.image.touchesCurrent.y-a.velocity.prevPositionY)<2&&(a.velocity.y=0),a.velocity.prevPositionX=a.image.touchesCurrent.x,a.velocity.prevPositionY=a.image.touchesCurrent.y,a.velocity.prevTime=Date.now(),a.gesture.imageWrap.transform("translate3d("+a.image.currentX+"px, "+a.image.currentY+"px,0)")}}},onTouchEnd:function(e,a){var t=e.zoom;if(t.gesture.image&&0!==t.gesture.image.length){if(!t.image.isTouched||!t.image.isMoved)return t.image.isTouched=!1,void(t.image.isMoved=!1);t.image.isTouched=!1,t.image.isMoved=!1;var s=300,i=300,r=t.velocity.x*s,n=t.image.currentX+r,o=t.velocity.y*i,l=t.image.currentY+o;0!==t.velocity.x&&(s=Math.abs((n-t.image.currentX)/t.velocity.x)),0!==t.velocity.y&&(i=Math.abs((l-t.image.currentY)/t.velocity.y));var p=Math.max(s,i);t.image.currentX=n,t.image.currentY=l;var d=t.image.width*t.scale,u=t.image.height*t.scale;t.image.minX=Math.min(t.gesture.slideWidth/2-d/2,0),t.image.maxX=-t.image.minX,t.image.minY=Math.min(t.gesture.slideHeight/2-u/2,0),t.image.maxY=-t.image.minY,t.image.currentX=Math.max(Math.min(t.image.currentX,t.image.maxX),t.image.minX),t.image.currentY=Math.max(Math.min(t.image.currentY,t.image.maxY),t.image.minY),t.gesture.imageWrap.transition(p).transform("translate3d("+t.image.currentX+"px, "+t.image.currentY+"px,0)")}},onTransitionEnd:function(e){var a=e.zoom;a.gesture.slide&&e.previousIndex!==e.activeIndex&&(a.gesture.image.transform("translate3d(0,0,0) scale(1)"),a.gesture.imageWrap.transform("translate3d(0,0,0)"),a.gesture.slide=a.gesture.image=a.gesture.imageWrap=void 0,a.scale=a.currentScale=1)},toggleZoom:function(a,t){var s=a.zoom;if(s.gesture.slide||(s.gesture.slide=a.clickedSlide?e(a.clickedSlide):a.slides.eq(a.activeIndex),s.gesture.image=s.gesture.slide.find("img, svg, canvas"),s.gesture.imageWrap=s.gesture.image.parent("."+a.params.zoomContainerClass)),s.gesture.image&&0!==s.gesture.image.length){var i,r,n,o,l,p,d,u,c,m,h,g,f,v,w,y,x,T;void 0===s.image.touchesStart.x&&t?(i="touchend"===t.type?t.changedTouches[0].pageX:t.pageX,r="touchend"===t.type?t.changedTouches[0].pageY:t.pageY):(i=s.image.touchesStart.x,r=s.image.touchesStart.y),s.scale&&1!==s.scale?(s.scale=s.currentScale=1,s.gesture.imageWrap.transition(300).transform("translate3d(0,0,0)"),s.gesture.image.transition(300).transform("translate3d(0,0,0) scale(1)"),s.gesture.slide=void 0):(s.scale=s.currentScale=s.gesture.imageWrap.attr("data-swiper-zoom")||a.params.zoomMax,t?(x=s.gesture.slide[0].offsetWidth,T=s.gesture.slide[0].offsetHeight,n=s.gesture.slide.offset().left,o=s.gesture.slide.offset().top,l=n+x/2-i,p=o+T/2-r,c=s.gesture.image[0].offsetWidth,m=s.gesture.image[0].offsetHeight,h=c*s.scale,g=m*s.scale,f=Math.min(x/2-h/2,0),v=Math.min(T/2-g/2,0),w=-f,y=-v,d=l*s.scale,u=p*s.scale,d<f&&(d=f),d>w&&(d=w),u<v&&(u=v),u>y&&(u=y)):(d=0,u=0),s.gesture.imageWrap.transition(300).transform("translate3d("+d+"px, "+u+"px,0)"),s.gesture.image.transition(300).transform("translate3d(0,0,0) scale("+s.scale+")"))}},attachEvents:function(a){var t=a?"off":"on";if(T.params.zoom){var s=(T.slides,!("touchstart"!==T.touchEvents.start||!T.support.passiveListener||!T.params.passiveListeners)&&{passive:!0,capture:!1});T.support.gestures?(T.slides[t]("gesturestart",T.zoom.onGestureStart,s),T.slides[t]("gesturechange",T.zoom.onGestureChange,s),T.slides[t]("gestureend",T.zoom.onGestureEnd,s)):"touchstart"===T.touchEvents.start&&(T.slides[t](T.touchEvents.start,T.zoom.onGestureStart,s),T.slides[t](T.touchEvents.move,T.zoom.onGestureChange,s),T.slides[t](T.touchEvents.end,T.zoom.onGestureEnd,s)),T[t]("touchStart",T.zoom.onTouchStart),T.slides.each(function(a,s){e(s).find("."+T.params.zoomContainerClass).length>0&&e(s)[t](T.touchEvents.move,T.zoom.onTouchMove)}),T[t]("touchEnd",T.zoom.onTouchEnd),T[t]("transitionEnd",T.zoom.onTransitionEnd),T.params.zoomToggle&&T.on("doubleTap",T.zoom.toggleZoom)}},init:function(){T.zoom.attachEvents()},destroy:function(){T.zoom.attachEvents(!0)}},T._plugins=[];for(var Y in T.plugins){var O=T.plugins[Y](T,T.params[Y]);O&&T._plugins.push(O)}return T.callPlugins=function(e){for(var a=0;a<T._plugins.length;a++)e in T._plugins[a]&&T._plugins[a][e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},T.emitterEventListeners={},T.emit=function(e){T.params[e]&&T.params[e](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);var a;if(T.emitterEventListeners[e])for(a=0;a<T.emitterEventListeners[e].length;a++)T.emitterEventListeners[e][a](arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);T.callPlugins&&T.callPlugins(e,arguments[1],arguments[2],arguments[3],arguments[4],arguments[5])},T.on=function(e,a){return e=m(e),T.emitterEventListeners[e]||(T.emitterEventListeners[e]=[]),T.emitterEventListeners[e].push(a),T},T.off=function(e,a){var t;if(e=m(e),void 0===a)return T.emitterEventListeners[e]=[],T;if(T.emitterEventListeners[e]&&0!==T.emitterEventListeners[e].length){for(t=0;t<T.emitterEventListeners[e].length;t++)T.emitterEventListeners[e][t]===a&&T.emitterEventListeners[e].splice(t,1);return T}},T.once=function(e,a){e=m(e);var t=function(){a(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]),T.off(e,t)};return T.on(e,t),T},T.a11y={makeFocusable:function(e){return e.attr("tabIndex","0"),e},addRole:function(e,a){return e.attr("role",a),e},addLabel:function(e,a){return e.attr("aria-label",a),e},disable:function(e){return e.attr("aria-disabled",!0),e},enable:function(e){return e.attr("aria-disabled",!1),e},onEnterKey:function(a){13===a.keyCode&&(e(a.target).is(T.params.nextButton)?(T.onClickNext(a),T.isEnd?T.a11y.notify(T.params.lastSlideMessage):T.a11y.notify(T.params.nextSlideMessage)):e(a.target).is(T.params.prevButton)&&(T.onClickPrev(a),T.isBeginning?T.a11y.notify(T.params.firstSlideMessage):T.a11y.notify(T.params.prevSlideMessage)),e(a.target).is("."+T.params.bulletClass)&&e(a.target)[0].click())},liveRegion:e('<span class="'+T.params.notificationClass+'" aria-live="assertive" aria-atomic="true"></span>'),notify:function(e){var a=T.a11y.liveRegion;0!==a.length&&(a.html(""),a.html(e))},init:function(){T.params.nextButton&&T.nextButton&&T.nextButton.length>0&&(T.a11y.makeFocusable(T.nextButton),T.a11y.addRole(T.nextButton,"button"),T.a11y.addLabel(T.nextButton,T.params.nextSlideMessage)),T.params.prevButton&&T.prevButton&&T.prevButton.length>0&&(T.a11y.makeFocusable(T.prevButton),T.a11y.addRole(T.prevButton,"button"),T.a11y.addLabel(T.prevButton,T.params.prevSlideMessage)),e(T.container).append(T.a11y.liveRegion)},initPagination:function(){T.params.pagination&&T.params.paginationClickable&&T.bullets&&T.bullets.length&&T.bullets.each(function(){var a=e(this);T.a11y.makeFocusable(a),T.a11y.addRole(a,"button"),T.a11y.addLabel(a,T.params.paginationBulletMessage.replace(/{{index}}/,a.index()+1))})},destroy:function(){T.a11y.liveRegion&&T.a11y.liveRegion.length>0&&T.a11y.liveRegion.remove()}},T.init=function(){T.params.loop&&T.createLoop(),T.updateContainerSize(),T.updateSlidesSize(),T.updatePagination(),T.params.scrollbar&&T.scrollbar&&(T.scrollbar.set(),T.params.scrollbarDraggable&&T.scrollbar.enableDraggable()),"slide"!==T.params.effect&&T.effects[T.params.effect]&&(T.params.loop||T.updateProgress(),T.effects[T.params.effect].setTranslate()),T.params.loop?T.slideTo(T.params.initialSlide+T.loopedSlides,0,T.params.runCallbacksOnInit):(T.slideTo(T.params.initialSlide,0,T.params.runCallbacksOnInit),0===T.params.initialSlide&&(T.parallax&&T.params.parallax&&T.parallax.setTranslate(),T.lazy&&T.params.lazyLoading&&(T.lazy.load(),T.lazy.initialImageLoaded=!0))),T.attachEvents(),T.params.observer&&T.support.observer&&T.initObservers(),T.params.preloadImages&&!T.params.lazyLoading&&T.preloadImages(),T.params.zoom&&T.zoom&&T.zoom.init(),T.params.autoplay&&T.startAutoplay(),T.params.keyboardControl&&T.enableKeyboardControl&&T.enableKeyboardControl(),T.params.mousewheelControl&&T.enableMousewheelControl&&T.enableMousewheelControl(),T.params.hashnavReplaceState&&(T.params.replaceState=T.params.hashnavReplaceState),T.params.history&&T.history&&T.history.init(),T.params.hashnav&&T.hashnav&&T.hashnav.init(),T.params.a11y&&T.a11y&&T.a11y.init(),T.emit("onInit",T)},T.cleanupStyles=function(){T.container.removeClass(T.classNames.join(" ")).removeAttr("style"),T.wrapper.removeAttr("style"),T.slides&&T.slides.length&&T.slides.removeClass([T.params.slideVisibleClass,T.params.slideActiveClass,T.params.slideNextClass,T.params.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-column").removeAttr("data-swiper-row"),T.paginationContainer&&T.paginationContainer.length&&T.paginationContainer.removeClass(T.params.paginationHiddenClass),T.bullets&&T.bullets.length&&T.bullets.removeClass(T.params.bulletActiveClass),T.params.prevButton&&e(T.params.prevButton).removeClass(T.params.buttonDisabledClass),T.params.nextButton&&e(T.params.nextButton).removeClass(T.params.buttonDisabledClass),T.params.scrollbar&&T.scrollbar&&(T.scrollbar.track&&T.scrollbar.track.length&&T.scrollbar.track.removeAttr("style"),T.scrollbar.drag&&T.scrollbar.drag.length&&T.scrollbar.drag.removeAttr("style"))},T.destroy=function(e,a){T.detachEvents(),T.stopAutoplay(),T.params.scrollbar&&T.scrollbar&&T.params.scrollbarDraggable&&T.scrollbar.disableDraggable(),T.params.loop&&T.destroyLoop(),a&&T.cleanupStyles(),T.disconnectObservers(),T.params.zoom&&T.zoom&&T.zoom.destroy(),T.params.keyboardControl&&T.disableKeyboardControl&&T.disableKeyboardControl(),T.params.mousewheelControl&&T.disableMousewheelControl&&T.disableMousewheelControl(),T.params.a11y&&T.a11y&&T.a11y.destroy(),T.params.history&&!T.params.replaceState&&window.removeEventListener("popstate",T.history.setHistoryPopState),T.params.hashnav&&T.hashnav&&T.hashnav.destroy(),T.emit("onDestroy"),e!==!1&&(T=null)},T.init(),T}};a.prototype={isSafari:function(){var e=window.navigator.userAgent.toLowerCase();return e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0}(),isUiWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(window.navigator.userAgent),isArray:function(e){return"[object Array]"===Object.prototype.toString.apply(e)},browser:{ie:window.navigator.pointerEnabled||window.navigator.msPointerEnabled,ieTouch:window.navigator.msPointerEnabled&&window.navigator.msMaxTouchPoints>1||window.navigator.pointerEnabled&&window.navigator.maxTouchPoints>1,lteIE9:function(){var e=document.createElement("div");return e.innerHTML="<!--[if lte IE 9]><i></i><![endif]-->",1===e.getElementsByTagName("i").length}()},device:function(){var e=window.navigator.userAgent,a=e.match(/(Android);?[\s\/]+([\d.]+)?/),t=e.match(/(iPad).*OS\s([\d_]+)/),s=e.match(/(iPod)(.*OS\s([\d_]+))?/),i=!t&&e.match(/(iPhone\sOS|iOS)\s([\d_]+)/);return{ios:t||i||s,android:a}}(),support:{touch:window.Modernizr&&Modernizr.touch===!0||function(){return!!("ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch)}(),transforms3d:window.Modernizr&&Modernizr.csstransforms3d===!0||function(){var e=document.createElement("div").style;return"webkitPerspective"in e||"MozPerspective"in e||"OPerspective"in e||"MsPerspective"in e||"perspective"in e}(),flexbox:function(){for(var e=document.createElement("div").style,a="alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient".split(" "),t=0;t<a.length;t++)if(a[t]in e)return!0}(),observer:function(){return"MutationObserver"in window||"WebkitMutationObserver"in window}(),passiveListener:function(){var e=!1;try{var a=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("testPassiveListener",null,a)}catch(e){}return e}(),gestures:function(){return"ongesturestart"in window}()},plugins:{}};for(var t=(function(){var e=function(e){var a=this,t=0;for(t=0;t<e.length;t++)a[t]=e[t];return a.length=e.length,this},a=function(a,t){var s=[],i=0;if(a&&!t&&a instanceof e)return a;if(a)if("string"==typeof a){var r,n,o=a.trim();if(o.indexOf("<")>=0&&o.indexOf(">")>=0){var l="div";for(0===o.indexOf("<li")&&(l="ul"),0===o.indexOf("<tr")&&(l="tbody"),0!==o.indexOf("<td")&&0!==o.indexOf("<th")||(l="tr"),0===o.indexOf("<tbody")&&(l="table"),0===o.indexOf("<option")&&(l="select"),n=document.createElement(l),n.innerHTML=a,i=0;i<n.childNodes.length;i++)s.push(n.childNodes[i])}else for(r=t||"#"!==a[0]||a.match(/[ .<>:~]/)?(t||document).querySelectorAll(a):[document.getElementById(a.split("#")[1])],i=0;i<r.length;i++)r[i]&&s.push(r[i])}else if(a.nodeType||a===window||a===document)s.push(a);else if(a.length>0&&a[0].nodeType)for(i=0;i<a.length;i++)s.push(a[i]);return new e(s)};return e.prototype={addClass:function(e){if(void 0===e)return this;for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.add(a[t]);return this},removeClass:function(e){for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.remove(a[t]);return this},hasClass:function(e){return!!this[0]&&this[0].classList.contains(e)},toggleClass:function(e){for(var a=e.split(" "),t=0;t<a.length;t++)for(var s=0;s<this.length;s++)this[s].classList.toggle(a[t]);return this},attr:function(e,a){if(1===arguments.length&&"string"==typeof e)return this[0]?this[0].getAttribute(e):void 0;for(var t=0;t<this.length;t++)if(2===arguments.length)this[t].setAttribute(e,a);else for(var s in e)this[t][s]=e[s],this[t].setAttribute(s,e[s]);return this},removeAttr:function(e){for(var a=0;a<this.length;a++)this[a].removeAttribute(e);return this},data:function(e,a){if(void 0!==a){for(var t=0;t<this.length;t++){var s=this[t];s.dom7ElementDataStorage||(s.dom7ElementDataStorage={}),s.dom7ElementDataStorage[e]=a}return this}if(this[0]){var i=this[0].getAttribute("data-"+e);return i?i:this[0].dom7ElementDataStorage&&e in this[0].dom7ElementDataStorage?this[0].dom7ElementDataStorage[e]:void 0}},transform:function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this},transition:function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this},on:function(e,t,s,i){function r(e){var i=e.target;if(a(i).is(t))s.call(i,e);else for(var r=a(i).parents(),n=0;n<r.length;n++)a(r[n]).is(t)&&s.call(r[n],e)}var n,o,l=e.split(" ");for(n=0;n<this.length;n++)if("function"==typeof t||t===!1)for("function"==typeof t&&(s=arguments[1],i=arguments[2]||!1),o=0;o<l.length;o++)this[n].addEventListener(l[o],s,i);else for(o=0;o<l.length;o++)this[n].dom7LiveListeners||(this[n].dom7LiveListeners=[]),this[n].dom7LiveListeners.push({listener:s,liveListener:r}),this[n].addEventListener(l[o],r,i);return this},off:function(e,a,t,s){for(var i=e.split(" "),r=0;r<i.length;r++)for(var n=0;n<this.length;n++)if("function"==typeof a||a===!1)"function"==typeof a&&(t=arguments[1],s=arguments[2]||!1),this[n].removeEventListener(i[r],t,s);else if(this[n].dom7LiveListeners)for(var o=0;o<this[n].dom7LiveListeners.length;o++)this[n].dom7LiveListeners[o].listener===t&&this[n].removeEventListener(i[r],this[n].dom7LiveListeners[o].liveListener,s);return this},once:function(e,a,t,s){function i(n){t(n),r.off(e,a,i,s)}var r=this;"function"==typeof a&&(a=!1,t=arguments[1],s=arguments[2]),r.on(e,a,i,s)},trigger:function(e,a){for(var t=0;t<this.length;t++){var s;try{s=new window.CustomEvent(e,{detail:a,bubbles:!0,cancelable:!0})}catch(t){s=document.createEvent("Event"),s.initEvent(e,!0,!0),s.detail=a}this[t].dispatchEvent(s)}return this},transitionEnd:function(e){function a(r){if(r.target===this)for(e.call(this,r),t=0;t<s.length;t++)i.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],i=this;if(e)for(t=0;t<s.length;t++)i.on(s[t],a);return this},width:function(){return this[0]===window?window.innerWidth:this.length>0?parseFloat(this.css("width")):null},outerWidth:function(e){return this.length>0?e?this[0].offsetWidth+parseFloat(this.css("margin-right"))+parseFloat(this.css("margin-left")):this[0].offsetWidth:null},height:function(){return this[0]===window?window.innerHeight:this.length>0?parseFloat(this.css("height")):null},outerHeight:function(e){return this.length>0?e?this[0].offsetHeight+parseFloat(this.css("margin-top"))+parseFloat(this.css("margin-bottom")):this[0].offsetHeight:null},offset:function(){if(this.length>0){var e=this[0],a=e.getBoundingClientRect(),t=document.body,s=e.clientTop||t.clientTop||0,i=e.clientLeft||t.clientLeft||0,r=window.pageYOffset||e.scrollTop,n=window.pageXOffset||e.scrollLeft;return{top:a.top+r-s,left:a.left+n-i}}return null},css:function(e,a){var t;if(1===arguments.length){if("string"!=typeof e){for(t=0;t<this.length;t++)for(var s in e)this[t].style[s]=e[s];return this}if(this[0])return window.getComputedStyle(this[0],null).getPropertyValue(e)}if(2===arguments.length&&"string"==typeof e){for(t=0;t<this.length;t++)this[t].style[e]=a;return this}return this},each:function(e){for(var a=0;a<this.length;a++)e.call(this[a],a,this[a]);return this},html:function(e){if(void 0===e)return this[0]?this[0].innerHTML:void 0;for(var a=0;a<this.length;a++)this[a].innerHTML=e;return this},text:function(e){if(void 0===e)return this[0]?this[0].textContent.trim():null;for(var a=0;a<this.length;a++)this[a].textContent=e;return this},is:function(t){if(!this[0])return!1;var s,i;if("string"==typeof t){var r=this[0];if(r===document)return t===document;if(r===window)return t===window;if(r.matches)return r.matches(t);if(r.webkitMatchesSelector)return r.webkitMatchesSelector(t);if(r.mozMatchesSelector)return r.mozMatchesSelector(t);if(r.msMatchesSelector)return r.msMatchesSelector(t);for(s=a(t),i=0;i<s.length;i++)if(s[i]===this[0])return!0;return!1}if(t===document)return this[0]===document;if(t===window)return this[0]===window;if(t.nodeType||t instanceof e){for(s=t.nodeType?[t]:t,i=0;i<s.length;i++)if(s[i]===this[0])return!0;return!1}return!1},index:function(){if(this[0]){for(var e=this[0],a=0;null!==(e=e.previousSibling);)1===e.nodeType&&a++;return a}},eq:function(a){if(void 0===a)return this;var t,s=this.length;return a>s-1?new e([]):a<0?(t=s+a,new e(t<0?[]:[this[t]])):new e([this[a]])},append:function(a){var t,s;for(t=0;t<this.length;t++)if("string"==typeof a){var i=document.createElement("div");for(i.innerHTML=a;i.firstChild;)this[t].appendChild(i.firstChild)}else if(a instanceof e)for(s=0;s<a.length;s++)this[t].appendChild(a[s]);else this[t].appendChild(a);return this},prepend:function(a){var t,s;for(t=0;t<this.length;t++)if("string"==typeof a){var i=document.createElement("div");for(i.innerHTML=a,s=i.childNodes.length-1;s>=0;s--)this[t].insertBefore(i.childNodes[s],this[t].childNodes[0])}else if(a instanceof e)for(s=0;s<a.length;s++)this[t].insertBefore(a[s],this[t].childNodes[0]);else this[t].insertBefore(a,this[t].childNodes[0]);return this},insertBefore:function(e){for(var t=a(e),s=0;s<this.length;s++)if(1===t.length)t[0].parentNode.insertBefore(this[s],t[0]);else if(t.length>1)for(var i=0;i<t.length;i++)t[i].parentNode.insertBefore(this[s].cloneNode(!0),t[i])},insertAfter:function(e){for(var t=a(e),s=0;s<this.length;s++)if(1===t.length)t[0].parentNode.insertBefore(this[s],t[0].nextSibling);else if(t.length>1)for(var i=0;i<t.length;i++)t[i].parentNode.insertBefore(this[s].cloneNode(!0),t[i].nextSibling)},next:function(t){return new e(this.length>0?t?this[0].nextElementSibling&&a(this[0].nextElementSibling).is(t)?[this[0].nextElementSibling]:[]:this[0].nextElementSibling?[this[0].nextElementSibling]:[]:[])},nextAll:function(t){var s=[],i=this[0];if(!i)return new e([]);for(;i.nextElementSibling;){var r=i.nextElementSibling;t?a(r).is(t)&&s.push(r):s.push(r),i=r}return new e(s)},prev:function(t){return new e(this.length>0?t?this[0].previousElementSibling&&a(this[0].previousElementSibling).is(t)?[this[0].previousElementSibling]:[]:this[0].previousElementSibling?[this[0].previousElementSibling]:[]:[])},prevAll:function(t){var s=[],i=this[0];if(!i)return new e([]);for(;i.previousElementSibling;){var r=i.previousElementSibling;t?a(r).is(t)&&s.push(r):s.push(r),i=r}return new e(s)},parent:function(e){for(var t=[],s=0;s<this.length;s++)e?a(this[s].parentNode).is(e)&&t.push(this[s].parentNode):t.push(this[s].parentNode);return a(a.unique(t))},parents:function(e){for(var t=[],s=0;s<this.length;s++)for(var i=this[s].parentNode;i;)e?a(i).is(e)&&t.push(i):t.push(i),i=i.parentNode;return a(a.unique(t))},find:function(a){for(var t=[],s=0;s<this.length;s++)for(var i=this[s].querySelectorAll(a),r=0;r<i.length;r++)t.push(i[r]);return new e(t)},children:function(t){for(var s=[],i=0;i<this.length;i++)for(var r=this[i].childNodes,n=0;n<r.length;n++)t?1===r[n].nodeType&&a(r[n]).is(t)&&s.push(r[n]):1===r[n].nodeType&&s.push(r[n]);return new e(a.unique(s))},remove:function(){for(var e=0;e<this.length;e++)this[e].parentNode&&this[e].parentNode.removeChild(this[e]);return this},add:function(){var e,t,s=this;for(e=0;e<arguments.length;e++){var i=a(arguments[e]);for(t=0;t<i.length;t++)s[s.length]=i[t],s.length++}return s}},a.fn=e.prototype,a.unique=function(e){for(var a=[],t=0;t<e.length;t++)a.indexOf(e[t])===-1&&a.push(e[t]);return a},a}()),s=["jQuery","Zepto","Dom7"],i=0;i<s.length;i++)window[s[i]]&&function(e){e.fn.swiper=function(t){var s;return e(this).each(function(){var e=new a(this,t);s||(s=e)}),s}}(window[s[i]]);var r;r=void 0===t?window.Dom7||window.Zepto||window.jQuery:t,r&&("transitionEnd"in r.fn||(r.fn.transitionEnd=function(e){function a(r){if(r.target===this)for(e.call(this,r),t=0;t<s.length;t++)i.off(s[t],a)}var t,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"],i=this;if(e)for(t=0;t<s.length;t++)i.on(s[t],a);return this}),"transform"in r.fn||(r.fn.transform=function(e){for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransform=t.MsTransform=t.msTransform=t.MozTransform=t.OTransform=t.transform=e}return this}),"transition"in r.fn||(r.fn.transition=function(e){"string"!=typeof e&&(e+="ms");for(var a=0;a<this.length;a++){var t=this[a].style;t.webkitTransitionDuration=t.MsTransitionDuration=t.msTransitionDuration=t.MozTransitionDuration=t.OTransitionDuration=t.transitionDuration=e}return this}),"outerWidth"in r.fn||(r.fn.outerWidth=function(e){ +return this.length>0?e?this[0].offsetWidth+parseFloat(this.css("margin-right"))+parseFloat(this.css("margin-left")):this[0].offsetWidth:null})),window.Swiper=a}(),"undefined"!=typeof module?module.exports=window.Swiper:"function"==typeof define&&define.amd&&define([],function(){"use strict";return window.Swiper}); +//# sourceMappingURL=maps/swiper.min.js.map diff --git a/static/app2/js/test.js b/static/app2/js/test.js new file mode 100755 index 0000000..c05bc22 --- /dev/null +++ b/static/app2/js/test.js @@ -0,0 +1,104 @@ +mui.plusReady(function() { + var btnArr = []; + + $('.selectfiles').each(function(num) { + btnArr.push($(this).attr('id')); + }) + + $.each(btnArr, function(i, n) { + var self = this.toString(); + var that = document.getElementById(this); + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: self, + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + dir:'appraises', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementsByClassName('ossfile')[i].innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false,'appraises'); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementsByClassName('ossfile')[i].innerHTML += '<div class="files_out" id="'+ file.id +'"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + get_uploaded_object_name(file.name) + '" src="' + hyhImgUrl(get_uploaded_object_name(file.name)) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + //console.log(JSON.stringify(up)) + //console.log(JSON.stringify(file)) + //console.log(JSON.stringify(info)) + //console.log(file.name); + //console.log((hyhImgUrl(get_uploaded_object_name(file.name)))); + }, + + Error: function(up, err) { + if(err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if(err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); + + +}) + }); + + \ No newline at end of file diff --git a/static/app2/js/time.js b/static/app2/js/time.js new file mode 100755 index 0000000..af26da5 --- /dev/null +++ b/static/app2/js/time.js @@ -0,0 +1,175 @@ +function getNextDate(dayStr) { + var dd = new Date(dayStr); + dd.setDate(dd.getDate() + 1); + var y = dd.getFullYear(); + var m = dd.getMonth() + 1; //获取当前月份的日期 + var d = dd.getDate(); + return y + "/" + m + "/" + d + " 00:00:00"; +}; + +var seckilling_end_time = ''; +var is_start=1; +startSeckilling(); +//console.log($(".nav").children('nav_block')) +function startSeckilling(){ + is_start=1; + $('.time .p1').html(' 秒杀进行中……'); + $('.time .p2').html('距结束:<o id="_h"></o>:<o id="_m"></o>:<o id="_s"></o>'); +} +function nextSeckilling(){ + is_start=0; + $('.time .p1').html(' 下场更精彩……'); + $('.time .p2').html('距开始:<o id="_h"></o>:<o id="_m"></o>:<o id="_s"></o>'); +} +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date(getNextDate(seckilling_end_time*1000)); + var end = endDate.getTime(); + //时间差 + var leftTime = seckilling_end_time*1000 - now; + + //定义变量 d,h,m,s保存倒计时的时间 + var h, m, s; + if(leftTime >= 0) { + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + document.getElementById("_h").innerHTML = h; + document.getElementById("_m").innerHTML = m; + document.getElementById("_s").innerHTML = s; + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +function getData(type, pagesize) { + // console.log(type) + var recommenddata = { + typeId: type ? type : 1, + pagesize: pagesize ? pagesize : 10 + } + + + mui.ajax(ectUrl('addon/hyhsale-Goods-alreadyBuy'), { + data: recommenddata, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data.Rows, function() { + if($(".nav").children('.nav_block').first().hasClass('on')){ + seckilling_end_time = this.endTime; + }else{ + seckilling_end_time = this.startTime; + } + html += '<div class="con_block shadown_wai" data-goodsId="' + this.goodsId + '" data-specsId="'+this.specsId+'"><img class="img" src="' + ectImgUrl(this.goodsImg) + '"/><p class="p1">' + this.goodsName + '</p><p class="p2" style="display:none;">买3赠1</p><p class="p3">¥<o>' + this.goodsPrice + '</o></p><del>¥<o>' + this.marketPrice + '</o></del>'; + if(1 == is_start){ + html +='<button>去抢购</button><p class="p4">已售</p><progress value=' + this.orderNum + ' max=' + this.totalNum + '></progress>'; + }else{ + html +='<button>原价购买</button>'; + } + html+='</div>'; + }); + $('.con_').html(html); + if(1 == is_start){ + $('progress').each(function(num) { + $('.p4').eq(num).html('已售' + Math.round($(this).attr('value') / $(this).attr('max') * 100) + '%') + }) + } + + if(type==1){ + + }else{ + + } + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + +} + +mui.plusReady(function() { + getData(1); + countTime() + mui('.nav').on('tap', '.nav_block', function() { + if($(".nav").children('.nav_block').first().hasClass('on')){ + startSeckilling(); + }else{ + nextSeckilling(); + } + var type = $(this).attr('data-type'); + getData(type); + $(this).addClass('on').siblings().removeClass('on'); + + + + }) + + mui("body").on('tap', '.con_block', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // mui.alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-goodsId"].nodeValue; + var specsId = this.attributes["data-specsId"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + MiaoshaSaleSpec:specsId, + isMiaosha:1 + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/app2/js/time_limit.js b/static/app2/js/time_limit.js new file mode 100755 index 0000000..e69de29 diff --git a/static/app2/js/upload.js b/static/app2/js/upload.js new file mode 100755 index 0000000..a98f0b9 --- /dev/null +++ b/static/app2/js/upload.js @@ -0,0 +1,134 @@ +accessid = '' +accesskey = '' +host = '' +policyBase64 = '' +signature = '' +callbackbody = '' +filename = '' +key = '' +expire = 0 +g_object_name = '' +g_object_name_type = '' +now = timestamp = Date.parse(new Date()) / 1000; +dir = 'images' + +function send_request() { + var xmlhttp = null; + if(window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if(window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if(xmlhttp != null) { +// //console.log(dir) + serverUrl = hyhUrl('oss/get.php?dir='+dir); + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + +}; + +function check_object_radio() { + var tt = document.getElementsByName('myradio'); + for(var i = 0; i < tt.length; i++) { + if(tt[i].checked) { + g_object_name_type = tt[i].value; + break; + } + } +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if(expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) {   + len = len || 32;   + var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   + var maxPos = chars.length;   + var pwd = '';   + for(i = 0; i < len; i++) {   + pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if(pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) { + if(g_object_name_type == 'local_name') { + g_object_name += "${filename}" + } else if(g_object_name_type == 'random_name') { + suffix = get_suffix(filename) + g_object_name = key + random_string(10) + suffix + } + return '' +} + +function get_uploaded_object_name(filename) { + if(g_object_name_type == 'local_name') { + tmp_name = g_object_name + tmp_name = tmp_name.replace("${filename}", filename); + return tmp_name + } else if(g_object_name_type == 'random_name') { + return g_object_name + } +} + +function set_upload_param(up, filename, ret,savedir) { + dir = savedir; + if(ret == false) { + ret = get_signature() + } + //console.log(filename); + g_object_name = key; + //console.log(g_object_name); + if(filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + + + //console.log(g_object_name); +// alert(g_object_name) +// //console.log(g_object_name); + new_multipart_params = { + 'key': g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId': accessid, + 'success_action_status': '200', //让服务端返回200,不然,默认会返回204 + 'callback': callbackbody, + 'signature': signature, + }; +// //console.log(callbackbody); + up.setOption({ + 'url': host, + 'multipart_params': new_multipart_params + }); + up.start(); +} \ No newline at end of file diff --git a/static/app2/js/upload1.js b/static/app2/js/upload1.js new file mode 100755 index 0000000..96cf7c8 --- /dev/null +++ b/static/app2/js/upload1.js @@ -0,0 +1,306 @@ +accessid = '' +accesskey = '' +host = '' +policyBase64 = '' +signature = '' +callbackbody = '' +filename = '' +key = '' +expire = 0 +g_object_name = '' +g_object_name_type = '' +now = timestamp = Date.parse(new Date()) / 1000; + +function send_request() { + var xmlhttp = null; + if(window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if(window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if(xmlhttp != null) { + serverUrl = '../php/get.php' + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } +}; + +function check_object_radio() { + var tt = document.getElementsByName('myradio'); + for(var i = 0; i < tt.length; i++) { + if(tt[i].checked) { + g_object_name_type = tt[i].value; + break; + } + } +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if(expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + host = obj['host'] + policyBase64 = obj['policy'] + accessid = obj['accessid'] + signature = obj['signature'] + expire = parseInt(obj['expire']) + callbackbody = obj['callback'] + key = obj['dir'] + return true; + } + return false; +}; + +function random_string(len) {   + len = len || 32;   + var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   + var maxPos = chars.length;   + var pwd = '';   + for(i = 0; i < len; i++) {   + pwd += chars.charAt(Math.floor(Math.random() * maxPos)); + } + return pwd; +} + +function get_suffix(filename) { + pos = filename.lastIndexOf('.') + suffix = '' + if(pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} + +function calculate_object_name(filename) { + if(g_object_name_type == 'local_name') { + g_object_name += "${filename}" + } else if(g_object_name_type == 'random_name') { + suffix = get_suffix(filename) + g_object_name = key + random_string(10) + suffix + } + return '' +} + +function get_uploaded_object_name(filename) { + if(g_object_name_type == 'local_name') { + tmp_name = g_object_name + tmp_name = tmp_name.replace("${filename}", filename); + return tmp_name + } else if(g_object_name_type == 'random_name') { + return g_object_name + } +} + +function set_upload_param(up, filename, ret) { + if(ret == false) { + ret = get_signature() + } + g_object_name = key; + if(filename != '') { + suffix = get_suffix(filename) + calculate_object_name(filename) + } + new_multipart_params = { + 'key': g_object_name, + 'policy': policyBase64, + 'OSSAccessKeyId': accessid, + 'success_action_status': '200', //让服务端返回200,不然,默认会返回204 + 'callback': callbackbody, + 'signature': signature, + }; + + up.setOption({ + 'url': host, + 'multipart_params': new_multipart_params + }); + + up.start(); +} +var html = ''; +for(i = 0; i < 3; i++) { + html += '<div class="up_out"><div id="ossfile' + i + '" class="ossfile clearfix" data-num="' + i + '">你的浏览器不支持flash,Silverlight或者HTML5!</div><div id="container' + i + '" class="container" data-num="' + i + '"><a id="selectfiles' + i + '" href="javascript:void(0);" class="btn selectfiles" data-num="' + i + '">选择文件</a></div></div>' +} + +$('.con').html(html) + +var btnArr = []; + +$('.selectfiles').each(function(num) { + btnArr.push($(this).attr('id')); +}) + +$.each(btnArr, function(i, n) { + var self = this.toString(); + var that = document.getElementById(this); + var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: self, + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementsByClassName('ossfile')[i].innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementsByClassName('ossfile')[i].innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img data-src="' + get_uploaded_object_name(file.name) + '" src="http://heyuanhui.oss-cn-qingdao.aliyuncs.com/' + get_uploaded_object_name(file.name) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if(err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } + }); + + uploader.init(); +}); + +var uploader = new plupload.Uploader({ + runtimes: 'html5,flash,silverlight,html4', + browse_button: 'selectfiles', + //multi_selection: false, + // container: document.getElementById('container'), + flash_swf_url: '../lib/plupload-2.1.2/js/Moxie.swf', + silverlight_xap_url: '../lib/plupload-2.1.2/js/Moxie.xap', + url: 'http://oss.aliyuncs.com', + + filters: { + mime_types: [ //只允许上传图片和zip,rar文件 + { + title: "Image files", + extensions: "jpg,gif,png,bmp" + }, + { + title: "Zip files", + extensions: "zip,rar" + } + ], + max_file_size: '10mb', //最大只能上传10mb的文件 + prevent_duplicates: true //不允许选取重复文件 + }, + + init: { + PostInit: function() { + document.getElementById('ossfile').innerHTML = ''; + // document.getElementById('postfiles').onclick = function() { + // set_upload_param(uploader, '', false); + // return false; + // }; + uploader.bind('FilesAdded', function() { + set_upload_param(uploader, '', false); + return false; + }); + }, + + FilesAdded: function(up, files) { + plupload.each(files, function(file) { + document.getElementById('ossfile').innerHTML += '<div class="files_out" id="' + file.id + '"><b></b>' + + '<div class="progress"><div class="progress-bar" style="width: 60px"></div></div>' + + '</div>'; + }); + }, + + BeforeUpload: function(up, file) { + check_object_radio(); + set_upload_param(up, file.name, true); + }, + + UploadProgress: function(up, file) { + var d = document.getElementById(file.id); + d.getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>"; + var prog = d.getElementsByTagName('div')[0]; + var progBar = prog.getElementsByTagName('div')[0] + progBar.style.width = 2 * file.percent + 'px'; + progBar.setAttribute('aria-valuenow', file.percent); + }, + + FileUploaded: function(up, file, info) { + if(info.status == 200) { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = '<img src="http://heyuanhui.oss-cn-qingdao.aliyuncs.com/' + get_uploaded_object_name(file.name) + '" />'; + } else { + document.getElementById(file.id).getElementsByTagName('b')[0].innerHTML = info.response; + } + }, + + Error: function(up, err) { + if(err.code == -600) { + mui.alert("\n选择的文件太大了"); + } else if(err.code == -601) { + mui.alert("\n选择的文件后缀不对"); + } else if(err.code == -602) { + mui.alert("\n这个文件已经上传过一遍了"); + } else { + mui.alert("\nError xml:" + err.response); + } + } + } +}); + +uploader.init(); \ No newline at end of file diff --git a/static/app2/js/uploadVoucher.js b/static/app2/js/uploadVoucher.js new file mode 100755 index 0000000..0a39dee --- /dev/null +++ b/static/app2/js/uploadVoucher.js @@ -0,0 +1,48 @@ +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'reload'); + //返回true,继续页面关闭逻辑 + return true; + }, +}) +mui.plusReady(function() { + var orderId = ''; + var self = plus.webview.currentWebview() + orderId = self.orderId + // 上传图片 + $(".oneImg").on("tap", '#img', function() { + // UP.init("accountBookImg", "test", "accountBookImgTag") + + UP.init("imgUrl", "test", "img") + openCamera() + }) + + var click = false; + $("body").on("tap", '.bc_btn', function() { + if (click == true) return; + + click = true; + var params = JZL.getParams(".inp"); + params.orderId = orderId + if ('' == $.trim($('#content').val())) { + mui.alert("请输入凭证说明") + return; + } + if ('' == $('#imgUrl').val()) { + mui.alert("请上传凭证图片") + return; + } + + JZL.ajax(qlgUrl('app/orders/uploadCertificate'), params, function(data) { + if (1 == data.status) { + mui.alert(data.msg); + mui.back() + } else { + mui.alert(data.msg) + } + }) + + + }) +}) diff --git a/static/app2/js/uploader.js b/static/app2/js/uploader.js new file mode 100755 index 0000000..b453401 --- /dev/null +++ b/static/app2/js/uploader.js @@ -0,0 +1,226 @@ +var files = []; //存储文件信息的数组 +var fname = ""; //表示文件名,例如 XXXX.jpg; +var expire = 0; +var pathName = ''; +var inpId = ''; +var keyname = ''; +var imgId=''; +var isZip=1; +var qualityNum=90; +var response=';' +var UP = UP || {}; +UP.isBatch=0; +UP.init = function(inputId, path,imageId,isBatch,isZipImg,quality) { + inpId = inputId; + pathName = path; + imgId = imageId; + if(typeof(isBatch) != 'undefined'){ + UP.isBatch = isBatch; + } + if(typeof(isZipImg) != 'undefined'){ + // //console.log(typeof(isZipImg)); + isZip = isZipImg; + } + if(typeof(quality) != 'undefined'){ + qualityNum = quality; + } + +} + +function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + // //console.log(dir) + serverUrl = qlgUrl('oss/get.php?dir=' + pathName); + // serverUrl = 'https://img.zgqlg.com.cn/oss/get.php?dir=' + pathName; + + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText; + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + response = obj; + // //console.log(obj); + } + return response; +}; +// 上传文件 +function upload(callback) { + // //console.log(files); + if (files.length <= 0) { + mui.toast('没有添加上传文件'); + return; + } + var obj = get_signature(); + if (obj) { + server = obj['host']; + policyBase64 = obj['policy']; + accessid = obj['accessid']; + signature = obj['signature']; + expire = parseInt(obj['expire']); + callbackbody = obj['callback']; + path = obj['dir']; + + } else { + mui.toast('初始化失败'); + return; + } + + var wt = plus.nativeUI.showWaiting(); + var task = plus.uploader.createUpload(server, { + method: "POST" + }, function(t, status) { + //上传完成 + if (status == 200) { + wt.close(); + if(1 == UP.isBatch){ + callback(t,status,keyname,server + '/'+keyname); + }else{ + document.getElementById(inpId).value = keyname; + var ele=document.getElementById(imgId); + ele.src=server + '/'+keyname; + ele.setAttribute('data-src',keyname); + mui.toast('上传成功'); + //至此上传成功,上传后的图片完整地址为server+testName + //keyname + } + + } else { + wt.close(); + mui.toast('上传失败:' + status); + } + }); + var suffix1 = get_suffix(fname); //文件后缀 例如 .jpg + keyname = path + new Date().getTime() + suffix1; + task.addData("key", keyname); + task.addData("policy", policyBase64); + task.addData("OSSAccessKeyId", accessid); + task.addData("success_action_status", "200"); + // task.addData("callback", callbackbody); + task.addData("signature", signature); + var f = files[files.length-1]; + // //console.log(f) + + task.addFile(f.path, { + key: "file", + name: "file", + mime: "image/jpeg" + }); + //files.length = 0; + task.start(); + +} + +//得到文件名的后缀 +function get_suffix(filename) { + var pos = filename.lastIndexOf('.'); + var suffix = ''; + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} +// 拍照添加文件 +function appendByCamera(callback) { + plus.camera.getCamera().captureImage(function(p) { + uploadImg(p,callback); + }); +} +// 从相册添加文件 +function appendByGallery(callback) { + plus.gallery.pick(function(p) { + uploadImg(p,callback); + }); +} + +// 添加文件 +var index = 1; +function uploadImg(p,callback){ + if(1 == isZip){ + compressImg(p,callback); + }else{ + appendFile(p,callback) + } +} +function appendFile(p,callback) { + // var fe = document.getElementById(fileId); + var n = p.substr(p.lastIndexOf('/') + 1); + fname = n; + files.push({ + name: "uploadkey" + index, + path: p + }); + ////console.log(3); + // index++; + upload(callback); +} +function compressImg(src,callback) { + var filename = src.substring(src.lastIndexOf('/') + 1); + var opions = { + src: src, + dst: '_doc/tmp/' + filename, + overwrite: true, + //width: '300px', //这里指定了宽度,同样可以修改 + format: 'jpg', + quality: qualityNum //图片质量不再修改,以免失真 + }; + var successCB = function(evt) { + // //console.log(JSON.stringify(evt)); + fname = filename; +// files[0]={ +// name: "uploadkey", +// path: evt.target +// }; + files.push({ + name: "uploadkey" + index, + path: evt.target + }); + // index++; + //上传 + upload(callback); + //_this.avatar(evt.target); + }; + var errorCB = function(err) { + appendFile(src,callback); + ////console.log(JSON.stringify(err)); + //mui.toast("图片压缩失败"); + }; + plus.zip.compressImage(opions, successCB, errorCB); +}; +function openCamera(callback) { + plus.nativeUI.actionSheet({ + cancel: "取消", + buttons: [{ + title: "拍照" + }, + { + title: "从相册中选择" + } + ] + }, function(e) { //1 是拍照 2 从相册中选择 + switch (e.index) { + case 1: + appendByCamera(callback); + break; + case 2: + appendByGallery(callback); + break; + } + }); + } \ No newline at end of file diff --git a/static/app2/js/uploaderBatch.js b/static/app2/js/uploaderBatch.js new file mode 100755 index 0000000..f98393f --- /dev/null +++ b/static/app2/js/uploaderBatch.js @@ -0,0 +1,219 @@ +var files = []; //存储文件信息的数组 +var fname = ""; //表示文件名,例如 XXXX.jpg; +var expire = 0; +var pathName = ''; +var keyname = ''; +var isZip=1; +var qualityNum=90; +var UP = UP || {}; +UP.isOk=0; +UP.init = function( path,isZipImg,quality) { + pathName = path; + if(typeof(isZipImg) != 'undefined'){ + // //console.log(typeof(isZipImg)); + isZip = isZipImg; + } + if(typeof(quality) != 'undefined'){ + qualityNum = quality; + } +} + +function send_request() { + var xmlhttp = null; + if (window.XMLHttpRequest) { + xmlhttp = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + + if (xmlhttp != null) { + // //console.log(dir) + serverUrl = 'http://t.ect99.com/oss/get.php?dir=' + pathName; + xmlhttp.open("GET", serverUrl, false); + xmlhttp.send(null); + return xmlhttp.responseText + } else { + mui.alert("Your browser does not support XMLHTTP."); + } + +} + +function get_signature() { + //可以判断当前expire是否超过了当前时间,如果超过了当前时间,就重新取一下.3s 做为缓冲 + now = timestamp = Date.parse(new Date()) / 1000; + if (expire < now + 3) { + body = send_request() + var obj = eval("(" + body + ")"); + // //console.log(obj); + return obj; + } + return false; +}; +// 上传文件 +function uploadInit(){ + // //console.log(files); + if (files.length <= 0) { + mui.toast('没有添加上传文件'); + return; + } + var obj = get_signature(); + if (obj) { + server = obj['host']; + policyBase64 = obj['policy']; + accessid = obj['accessid']; + signature = obj['signature']; + expire = parseInt(obj['expire']); + callbackbody = obj['callback']; + path = obj['dir']; + + } else { + mui.toast('初始化失败'); + return; + } + var suffix1 = get_suffix(fname); //文件后缀 例如 .jpg + keyname = path + new Date().getTime() + suffix1; + task.addData("key", keyname); + task.addData("policy", policyBase64); + task.addData("OSSAccessKeyId", accessid); + task.addData("success_action_status", "200"); + // task.addData("callback", callbackbody); + task.addData("signature", signature); + var f = files[files.length-1]; + // //console.log(f) + + task.addFile(f.path, { + key: "file", + name: "file", + mime: "image/jpeg" + }); + //files.length = 0; + return true; +} +// //上传完成 +// if (status == 200) { +// +// //console.log(inpId); +// document.getElementById(inpId).value = keyname; +// var ele=document.getElementById(imgId); +// ele.src=server + '/'+keyname; +// ele.setAttribute('data-src',keyname); +// wt.close(); +// mui.toast('上传成功'); +// UP.isOk=1; +// if(1 == UP.isOk){ +// var html='<div class="galleryImg photo"><img src="" class="ossfile" data-id="'+num+'" id="galleryImg['+num+']" alt=""><input type="hidden" value="" class="gallery inp" id="gallery['+num+']"><span class=""></span></div>'; +// if($('#galleryImg['+num+']').length>0){ +// $('#galleryImg['+num+']').parent().html(html); +// +// +// }else{ +// $(".photos_con").append(html); +// var maxNum = $('.photos_con').children('.galleryImg').length-1; +// if(num >= maxNum){ +// html='<div class="galleryImg photo"><img src="" class="ossfile" data-id="'+num+'" id="galleryImg['+num+']" alt=""><input type="hidden" value="" class="gallery inp" id="gallery['+num+']"><span class=""></span></div>'; +// $(".photos_con").append(html); +// } +// +// } +// } + //至此上传成功,上传后的图片完整地址为server+testName + + +//得到文件名的后缀 +function get_suffix(filename) { + var pos = filename.lastIndexOf('.'); + var suffix = ''; + if (pos != -1) { + suffix = filename.substring(pos) + } + return suffix; +} +// 拍照添加文件 +function appendByCamera() { + plus.camera.getCamera().captureImage(function(p) { + uploadImg(p); + }); +} +// 从相册添加文件 +function appendByGallery() { + plus.gallery.pick(function(p) { + uploadImg(p); + }); +} + +// 添加文件 +var index = 1; +function uploadImg(p){ + UP.isOk=0; + if(1 == isZip){ + compressImg(p); + }else{ + appendFile(p) + } +} +function appendFile(p) { + // var fe = document.getElementById(fileId); + var n = p.substr(p.lastIndexOf('/') + 1); + fname = n; + files.push({ + name: "uploadkey" + index, + path: p + }); + ////console.log(3); + // index++; + upload(); +} +function compressImg(src) { + var filename = src.substring(src.lastIndexOf('/') + 1); + var opions = { + src: src, + dst: '_doc/tmp/' + filename, + overwrite: true, + //width: '300px', //这里指定了宽度,同样可以修改 + format: 'jpg', + quality: qualityNum //图片质量不再修改,以免失真 + }; + var successCB = function(evt) { + // //console.log(JSON.stringify(evt)); + fname = filename; +// files[0]={ +// name: "uploadkey", +// path: evt.target +// }; + files.push({ + name: "uploadkey" + index, + path: evt.target + }); + // index++; + //上传 + upload(); + //_this.avatar(evt.target); + }; + var errorCB = function(err) { + appendFile(src); + ////console.log(JSON.stringify(err)); + //mui.toast("图片压缩失败"); + }; + plus.zip.compressImage(opions, successCB, errorCB); +}; +function openCamera() { + plus.nativeUI.actionSheet({ + cancel: "取消", + buttons: [{ + title: "拍照" + }, + { + title: "从相册中选择" + } + ] + }, function(e) { //1 是拍照 2 从相册中选择 + switch (e.index) { + case 1: + appendByCamera(); + break; + case 2: + appendByGallery(); + break; + } + }); + } \ No newline at end of file diff --git a/static/app2/js/uploadqiniu.js b/static/app2/js/uploadqiniu.js new file mode 100755 index 0000000..725a0ce --- /dev/null +++ b/static/app2/js/uploadqiniu.js @@ -0,0 +1,92 @@ +function uploadInit(btnId,containerId,textElemId) { + // 获取相关 DOM 节点的 ID +// var btnId = editor.imgMenuId; +// var containerId = editor.toolbarElemId; +// var textElemId = editor.textElemId; +// var btnId =''; +// var containerId ='' +// var textElemId = '' + // 创建上传对象 + var uploader = new Qiniu.uploader({ + runtimes: 'html5,flash,html4', //上传模式,依次退化 + browse_button: btnId, //上传选择的点选按钮,**必需** + uptoken_url: '/uptoken', + //Ajax请求upToken的Url,**强烈建议设置**(服务端提供) + // uptoken : '<Your upload token>', + //若未指定uptoken_url,则必须指定 uptoken ,uptoken由其他程序生成 + // unique_names: true, + // 默认 false,key为文件名。若开启该选项,SDK会为每个文件自动生成key(文件名) + // save_key: true, + // 默认 false。若在服务端生成uptoken的上传策略中指定了 `sava_key`,则开启,SDK在前端将不对key进行任何处理 + domain: 'http://7xrjl5.com1.z0.glb.clouddn.com/', + //bucket 域名,下载资源时用到,**必需** + container: containerId, //上传区域DOM ID,默认是browser_button的父元素, + max_file_size: '100mb', //最大文件体积限制 + flash_swf_url: '../js/plupload/Moxie.swf', //引入flash,相对路径 + filters: { + mime_types: [ + //只允许上传图片文件 (注意,extensions中,逗号后面不要加空格) + { title: "图片文件", extensions: "jpg,gif,png,bmp" } + ] + }, + max_retries: 3, //上传失败最大重试次数 + dragdrop: true, //开启可拖曳上传 + drop_element: textElemId, //拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传 + chunk_size: '4mb', //分块上传时,每片的体积 + auto_start: true, //选择文件后自动上传,若关闭需要自己绑定事件触发上传 + init: { + 'FilesAdded': function(up, files) { + plupload.each(files, function(file) { + // 文件添加进队列后,处理相关的事情 + printLog('on FilesAdded'); + }); + }, + 'BeforeUpload': function(up, file) { + // 每个文件上传前,处理相关的事情 + printLog('on BeforeUpload'); + }, + 'UploadProgress': function(up, file) { + // 显示进度 + printLog('进度 ' + file.percent) + }, + 'FileUploaded': function(up, file, info) { + // 每个文件上传成功后,处理相关的事情 + // 其中 info 是文件上传成功后,服务端返回的json,形式如 + // { + // "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98", + // "key": "gogopher.jpg" + // } + printLog(info); + // 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html + + var domain = up.getOption('domain'); + var res = $.parseJSON(info); + var sourceLink = domain + res.key; //获取上传成功后的文件的Url + + printLog(sourceLink); + + // 插入图片到editor + editor.cmd.do('insertHtml', '<img src="' + sourceLink + '" style="max-width:100%;"/>') + }, + 'Error': function(up, err, errTip) { + //上传出错时,处理相关的事情 + printLog('on Error'); + }, + 'UploadComplete': function() { + //队列文件处理完毕后,处理相关的事情 + printLog('on UploadComplete'); + } + // Key 函数如果有需要自行配置,无特殊需要请注释 + //, + // 'Key': function(up, file) { + // // 若想在前端对每个文件的key进行个性化处理,可以配置该函数 + // // 该配置必须要在 unique_names: false , save_key: false 时才生效 + // var key = ""; + // // do something with key here + // return key + // } + } + // domain 为七牛空间(bucket)对应的域名,选择某个空间后,可通过"空间设置->基本设置->域名设置"查看获取 + // uploader 为一个plupload对象,继承了所有plupload的方法,参考http://plupload.com/docs + }); +} diff --git a/static/app2/js/vouchers.js b/static/app2/js/vouchers.js new file mode 100755 index 0000000..e6b79f6 --- /dev/null +++ b/static/app2/js/vouchers.js @@ -0,0 +1,92 @@ +var vouchersType = '', + isExpected = ''; +var data_href = ''; +var pageSize = 10; +var count = 1; +var isLoading = false; +mui.plusReady(function() { + + var self = plus.webview.currentWebview(); + + vouchersType = self.data_type; + isExpected = self.data_expect; + data_href = self.data_href; + + getvoucherList(count, pageSize); + + switch (data_href) { + case "expectedProduct": + $('.title').html('预获产品券'); + + break; + case "expectedCoupons": + $('.title').text('预获优惠券'); + break; + case "expectedWang": + $('.title').text('预获旺旺券'); + break + case "coupons": + $('.title').text('已获优惠券'); + break + case "product": + $('.title').text('已获产品券'); + break + case "wang": + $('.title').text('已获旺旺券'); + break + + } + + + function getvoucherList(count, pageSize) { + if (true == isLoading) return; + isLoading = true; + JZL.ajax(qlgUrl('app/Uservouchers/getVouchers'), { + page: count, + perPage: pageSize, + vouchersType: vouchersType, + isExpected: isExpected, + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + // console.log(data); + var data = toJson(data); + if (data.status == 1) { + data = data.data; + if (data.Rows == '') { + $('.con').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + return; + } + var html = '' + $.each(data.Rows, function() { + html += '<div class="row shadown_wai"><div class="num">' + this.num + + '</div><div class="info"><div class="info_">' + this.remark + '</div><div class="time">' + this.createTime + + '</div><div class="valid"></div></div></div>'; + }) + if (count == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + } else { + mui.alert(data.msg) + } + isLoading = false; + }); + } + + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (e.cancelable) { + // 判断默认行为是否已经被禁用 + if (!e.defaultPrevented) { + e.preventDefault(); + } + } + if (scroll.y == scroll.maxScrollY) { + if (isLoading == false) { + count++; + getvoucherList(count, pageSize) + } + } + }) +}) diff --git a/static/app2/js/yhk.js b/static/app2/js/yhk.js new file mode 100755 index 0000000..1600e80 --- /dev/null +++ b/static/app2/js/yhk.js @@ -0,0 +1,124 @@ +mui.plusReady(function() { + + window.addEventListener('reload', function(e) { //执行刷新 + location.reload(); + }); + + $('.add1').on('tap', function() { + JZL.openWindow('addyhk.html', 'addyhk.html'); + }) + var yhkid; + mui('.con').on('tap', '.bj', function() { + yhkid = $(this).attr("data-id"); + JZL.openWindow('addyhk.html', yhkid); + }) + + var page = 1; + var pageSize = 10; + var isjiazai = 1; + getRecommend(page, pageSize); + + function getRecommend(page, pageSize) { + var recommenddata = { + page: page ? page : 1, + pageSize: pageSize ? pageSize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/auth/getCompanyBankList'), recommenddata, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + if (data.status == 1) { + var html = ''; + var data = data.data; + if ('' == data.Rows) { + $('.mui-scroll').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + html += '<div class="block clearfix"><p class="pname">' + this.accountName + + '(' + this.bankNo + + ')</p><div class="caozuo"><span class="bj" data-id="' + this.id + + '"><img src="../img/bianji.png"></span><span class="del" data-id="' + this.id + + '"><img src="../img/delete.png"></span></div></div>'; + // //console.log(this.id); + + + }) + if (page == 1) { + $('.con').html(html); + } else { + $('.con').append(html); + } + } else { + mui.alert(data.msg) + } + isjiazai = 1; + }) + + } + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pageSize); + } + } + }) + + $('.con').on('tap', '.del', function() { + + yhkid = $(this).attr('data-id'); + if (confirm('确认删除?')) { + var lxy_div = + '<div class="mui-backdrop lxy_home_zz" style="display: block;background-color: rgba(0,0,0,.7);" id="home_zhezhao"> <div class="lxy_zz clearfix"><h3>请输入操作密码</h3><div style="background:linear-gradient(to right,#48D1CC,#FFD700,#D2691E);height:5px; margin:10px auto"></div><input class="payword" type="password" placeholder="请输入操作密码"><div class="lxy_zz_btn"><button class="cancle" type="button">取消</button><button class="sure" type="button">确定</button></div></div></div>'; + + $('body').append(lxy_div); + + $('.lxy_zz').on('tap', function(e) { + e.preventDefault(); + e.stopPropagation() + + }) + mui('.lxy_zz_btn').on('tap', '.cancle', function() { + $('#home_zhezhao').remove(); + return; + }) + + mui('.lxy_zz_btn').on('tap', '.sure', function() { + var payPwd = $('.payword').val(); + if (payPwd == '') { + mui.alert("请输入密码") + } + + JZL.ajax(qlgUrl('app/auth/delCompanyBank'), { + id: yhkid, + payPwd: payPwd + }, function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + //console.log(data); + var data = toJson(data, 1); + if (data.status == 1) { + $('#home_zhezhao').remove(); + location.reload() + + } else { + mui.alert(data.msg) + } + }) + // //console.log(data_addressId); + // mui.ajax(hyhUrl('app/Useraddress/del'), { + + }); + } + + }) + + + + + +}) diff --git a/static/app2/js/zepto.min.js b/static/app2/js/zepto.min.js new file mode 100755 index 0000000..8a76710 --- /dev/null +++ b/static/app2/js/zepto.min.js @@ -0,0 +1,2 @@ +/* Zepto v1.0rc1 - polyfill zepto event detect fx ajax form touch - zeptojs.com/license */ +(function(a){String.prototype.trim===a&&(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Array.prototype.reduce===a&&(Array.prototype.reduce=function(b){if(this===void 0||this===null)throw new TypeError;var c=Object(this),d=c.length>>>0,e=0,f;if(typeof b!="function")throw new TypeError;if(d==0&&arguments.length==1)throw new TypeError;if(arguments.length>=2)f=arguments[1];else do{if(e in c){f=c[e++];break}if(++e>=d)throw new TypeError}while(!0);while(e<d)e in c&&(f=b.call(a,f,c[e],e,c)),e++;return f})})();var Zepto=function(){function A(a){return v.call(a)=="[object Function]"}function B(a){return a instanceof Object}function C(b){var c,d;if(v.call(b)!=="[object Object]")return!1;d=A(b.constructor)&&b.constructor.prototype;if(!d||!hasOwnProperty.call(d,"isPrototypeOf"))return!1;for(c in b);return c===a||hasOwnProperty.call(b,c)}function D(a){return a instanceof Array}function E(a){return typeof a.length=="number"}function F(b){return b.filter(function(b){return b!==a&&b!==null})}function G(a){return a.length>0?[].concat.apply([],a):a}function H(a){return a.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function I(a){return a in i?i[a]:i[a]=new RegExp("(^|\\s)"+a+"(\\s|$)")}function J(a,b){return typeof b=="number"&&!k[H(a)]?b+"px":b}function K(a){var b,c;return h[a]||(b=g.createElement(a),g.body.appendChild(b),c=j(b,"").getPropertyValue("display"),b.parentNode.removeChild(b),c=="none"&&(c="block"),h[a]=c),h[a]}function L(b,d){return d===a?c(b):c(b).filter(d)}function M(a,b,c,d){return A(b)?b.call(a,c,d):b}function N(a,b,d){var e=a%2?b:b.parentNode;e?e.insertBefore(d,a?a==1?e.firstChild:a==2?b:null:b.nextSibling):c(d).remove()}function O(a,b){b(a);for(var c in a.childNodes)O(a.childNodes[c],b)}var a,b,c,d,e=[],f=e.slice,g=window.document,h={},i={},j=g.defaultView.getComputedStyle,k={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},l=/^\s*<(\w+|!)[^>]*>/,m=[1,3,8,9,11],n=["after","prepend","before","append"],o=g.createElement("table"),p=g.createElement("tr"),q={tr:g.createElement("tbody"),tbody:o,thead:o,tfoot:o,td:p,th:p,"*":g.createElement("div")},r=/complete|loaded|interactive/,s=/^\.([\w-]+)$/,t=/^#([\w-]+)$/,u=/^[\w-]+$/,v={}.toString,w={},x,y,z=g.createElement("div");return w.matches=function(a,b){if(!a||a.nodeType!==1)return!1;var c=a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.matchesSelector;if(c)return c.call(a,b);var d,e=a.parentNode,f=!e;return f&&(e=z).appendChild(a),d=~w.qsa(e,b).indexOf(a),f&&z.removeChild(a),d},x=function(a){return a.replace(/-+(.)?/g,function(a,b){return b?b.toUpperCase():""})},y=function(a){return a.filter(function(b,c){return a.indexOf(b)==c})},w.fragment=function(b,d){d===a&&(d=l.test(b)&&RegExp.$1),d in q||(d="*");var e=q[d];return e.innerHTML=""+b,c.each(f.call(e.childNodes),function(){e.removeChild(this)})},w.Z=function(a,b){return a=a||[],a.__proto__=arguments.callee.prototype,a.selector=b||"",a},w.isZ=function(a){return a instanceof w.Z},w.init=function(b,d){if(!b)return w.Z();if(A(b))return c(g).ready(b);if(w.isZ(b))return b;var e;if(D(b))e=F(b);else if(C(b))e=[c.extend({},b)],b=null;else if(m.indexOf(b.nodeType)>=0||b===window)e=[b],b=null;else if(l.test(b))e=w.fragment(b.trim(),RegExp.$1),b=null;else{if(d!==a)return c(d).find(b);e=w.qsa(g,b)}return w.Z(e,b)},c=function(a,b){return w.init(a,b)},c.extend=function(c){return f.call(arguments,1).forEach(function(d){for(b in d)d[b]!==a&&(c[b]=d[b])}),c},w.qsa=function(a,b){var c;return a===g&&t.test(b)?(c=a.getElementById(RegExp.$1))?[c]:e:a.nodeType!==1&&a.nodeType!==9?e:f.call(s.test(b)?a.getElementsByClassName(RegExp.$1):u.test(b)?a.getElementsByTagName(b):a.querySelectorAll(b))},c.isFunction=A,c.isObject=B,c.isArray=D,c.isPlainObject=C,c.inArray=function(a,b,c){return e.indexOf.call(b,a,c)},c.trim=function(a){return a.trim()},c.uuid=0,c.map=function(a,b){var c,d=[],e,f;if(E(a))for(e=0;e<a.length;e++)c=b(a[e],e),c!=null&&d.push(c);else for(f in a)c=b(a[f],f),c!=null&&d.push(c);return G(d)},c.each=function(a,b){var c,d;if(E(a)){for(c=0;c<a.length;c++)if(b.call(a[c],c,a[c])===!1)return a}else for(d in a)if(b.call(a[d],d,a[d])===!1)return a;return a},c.fn={forEach:e.forEach,reduce:e.reduce,push:e.push,indexOf:e.indexOf,concat:e.concat,map:function(a){return c.map(this,function(b,c){return a.call(b,c,b)})},slice:function(){return c(f.apply(this,arguments))},ready:function(a){return r.test(g.readyState)?a(c):g.addEventListener("DOMContentLoaded",function(){a(c)},!1),this},get:function(b){return b===a?f.call(this):this[b]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){this.parentNode!=null&&this.parentNode.removeChild(this)})},each:function(a){return this.forEach(function(b,c){a.call(b,c,b)}),this},filter:function(a){return c([].filter.call(this,function(b){return w.matches(b,a)}))},add:function(a,b){return c(y(this.concat(c(a,b))))},is:function(a){return this.length>0&&w.matches(this[0],a)},not:function(b){var d=[];if(A(b)&&b.call!==a)this.each(function(a){b.call(this,a)||d.push(this)});else{var e=typeof b=="string"?this.filter(b):E(b)&&A(b.item)?f.call(b):c(b);this.forEach(function(a){e.indexOf(a)<0&&d.push(a)})}return c(d)},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){var a=this[0];return a&&!B(a)?a:c(a)},last:function(){var a=this[this.length-1];return a&&!B(a)?a:c(a)},find:function(a){var b;return this.length==1?b=w.qsa(this[0],a):b=this.map(function(){return w.qsa(this,a)}),c(b)},closest:function(a,b){var d=this[0];while(d&&!w.matches(d,a))d=d!==b&&d!==g&&d.parentNode;return c(d)},parents:function(a){var b=[],d=this;while(d.length>0)d=c.map(d,function(a){if((a=a.parentNode)&&a!==g&&b.indexOf(a)<0)return b.push(a),a});return L(b,a)},parent:function(a){return L(y(this.pluck("parentNode")),a)},children:function(a){return L(this.map(function(){return f.call(this.children)}),a)},siblings:function(a){return L(this.map(function(a,b){return f.call(b.parentNode.children).filter(function(a){return a!==b})}),a)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(a){return this.map(function(){return this[a]})},show:function(){return this.each(function(){this.style.display=="none"&&(this.style.display=null),j(this,"").getPropertyValue("display")=="none"&&(this.style.display=K(this.nodeName))})},replaceWith:function(a){return this.before(a).remove()},wrap:function(a){return this.each(function(){c(this).wrapAll(c(a)[0].cloneNode(!1))})},wrapAll:function(a){return this[0]&&(c(this[0]).before(a=c(a)),a.append(this)),this},unwrap:function(){return this.parent().each(function(){c(this).replaceWith(c(this).children())}),this},clone:function(){return c(this.map(function(){return this.cloneNode(!0)}))},hide:function(){return this.css("display","none")},toggle:function(b){return(b===a?this.css("display")=="none":b)?this.show():this.hide()},prev:function(){return c(this.pluck("previousElementSibling"))},next:function(){return c(this.pluck("nextElementSibling"))},html:function(b){return b===a?this.length>0?this[0].innerHTML:null:this.each(function(a){var d=this.innerHTML;c(this).empty().append(M(this,b,a,d))})},text:function(b){return b===a?this.length>0?this[0].textContent:null:this.each(function(){this.textContent=b})},attr:function(c,d){var e;return typeof c=="string"&&d===a?this.length==0||this[0].nodeType!==1?a:c=="value"&&this[0].nodeName=="INPUT"?this.val():!(e=this[0].getAttribute(c))&&c in this[0]?this[0][c]:e:this.each(function(a){if(this.nodeType!==1)return;if(B(c))for(b in c)this.setAttribute(b,c[b]);else this.setAttribute(c,M(this,d,a,this.getAttribute(c)))})},removeAttr:function(a){return this.each(function(){this.nodeType===1&&this.removeAttribute(a)})},prop:function(b,c){return c===a?this[0]?this[0][b]:a:this.each(function(a){this[b]=M(this,c,a,this[b])})},data:function(b,c){var d=this.attr("data-"+H(b),c);return d!==null?d:a},val:function(b){return b===a?this.length>0?this[0].value:a:this.each(function(a){this.value=M(this,b,a,this.value)})},offset:function(){if(this.length==0)return null;var a=this[0].getBoundingClientRect();return{left:a.left+window.pageXOffset,top:a.top+window.pageYOffset,width:a.width,height:a.height}},css:function(c,d){if(d===a&&typeof c=="string")return this.length==0?a:this[0].style[x(c)]||j(this[0],"").getPropertyValue(c);var e="";for(b in c)typeof c[b]=="string"&&c[b]==""?this.each(function(){this.style.removeProperty(H(b))}):e+=H(b)+":"+J(b,c[b])+";";return typeof c=="string"&&(d==""?this.each(function(){this.style.removeProperty(H(c))}):e=H(c)+":"+J(c,d)),this.each(function(){this.style.cssText+=";"+e})},index:function(a){return a?this.indexOf(c(a)[0]):this.parent().children().indexOf(this[0])},hasClass:function(a){return this.length<1?!1:I(a).test(this[0].className)},addClass:function(a){return this.each(function(b){d=[];var e=this.className,f=M(this,a,b,e);f.split(/\s+/g).forEach(function(a){c(this).hasClass(a)||d.push(a)},this),d.length&&(this.className+=(e?" ":"")+d.join(" "))})},removeClass:function(b){return this.each(function(c){if(b===a)return this.className="";d=this.className,M(this,b,c,d).split(/\s+/g).forEach(function(a){d=d.replace(I(a)," ")}),this.className=d.trim()})},toggleClass:function(b,d){return this.each(function(e){var f=M(this,b,e,this.className);(d===a?!c(this).hasClass(f):d)?c(this).addClass(f):c(this).removeClass(f)})}},["width","height"].forEach(function(b){c.fn[b]=function(d){var e,f=b.replace(/./,function(a){return a[0].toUpperCase()});return d===a?this[0]==window?window["inner"+f]:this[0]==g?g.documentElement["offset"+f]:(e=this.offset())&&e[b]:this.each(function(a){var e=c(this);e.css(b,M(this,d,a,e[b]()))})}}),n.forEach(function(a,b){c.fn[a]=function(){var a=c.map(arguments,function(a){return B(a)?a:w.fragment(a)});if(a.length<1)return this;var d=this.length,e=d>1,f=b<2;return this.each(function(c,g){for(var h=0;h<a.length;h++){var i=a[f?a.length-h-1:h];O(i,function(a){a.nodeName!=null&&a.nodeName.toUpperCase()==="SCRIPT"&&(!a.type||a.type==="text/javascript")&&window.eval.call(window,a.innerHTML)}),e&&c<d-1&&(i=i.cloneNode(!0)),N(b,g,i)}})},c.fn[b%2?a+"To":"insert"+(b?"Before":"After")]=function(b){return c(b)[a](this),this}}),w.Z.prototype=c.fn,w.camelize=x,w.uniq=y,c.zepto=w,c}();window.Zepto=Zepto,"$"in window||(window.$=Zepto),function(a){function f(a){return a._zid||(a._zid=d++)}function g(a,b,d,e){b=h(b);if(b.ns)var g=i(b.ns);return(c[f(a)]||[]).filter(function(a){return a&&(!b.e||a.e==b.e)&&(!b.ns||g.test(a.ns))&&(!d||f(a.fn)===f(d))&&(!e||a.sel==e)})}function h(a){var b=(""+a).split(".");return{e:b[0],ns:b.slice(1).sort().join(" ")}}function i(a){return new RegExp("(?:^| )"+a.replace(" "," .* ?")+"(?: |$)")}function j(b,c,d){a.isObject(b)?a.each(b,d):b.split(/\s/).forEach(function(a){d(a,c)})}function k(b,d,e,g,i,k){k=!!k;var l=f(b),m=c[l]||(c[l]=[]);j(d,e,function(c,d){var e=i&&i(d,c),f=e||d,j=function(a){var c=f.apply(b,[a].concat(a.data));return c===!1&&a.preventDefault(),c},l=a.extend(h(c),{fn:d,proxy:j,sel:g,del:e,i:m.length});m.push(l),b.addEventListener(l.e,j,k)})}function l(a,b,d,e){var h=f(a);j(b||"",d,function(b,d){g(a,b,d,e).forEach(function(b){delete c[h][b.i],a.removeEventListener(b.e,b.proxy,!1)})})}function p(b){var c=a.extend({originalEvent:b},b);return a.each(o,function(a,d){c[a]=function(){return this[d]=m,b[a].apply(b,arguments)},c[d]=n}),c}function q(a){if(!("defaultPrevented"in a)){a.defaultPrevented=!1;var b=a.preventDefault;a.preventDefault=function(){this.defaultPrevented=!0,b.call(this)}}}var b=a.zepto.qsa,c={},d=1,e={};e.click=e.mousedown=e.mouseup=e.mousemove="MouseEvents",a.event={add:k,remove:l},a.proxy=function(b,c){if(a.isFunction(b)){var d=function(){return b.apply(c,arguments)};return d._zid=f(b),d}if(typeof c=="string")return a.proxy(b[c],b);throw new TypeError("expected function")},a.fn.bind=function(a,b){return this.each(function(){k(this,a,b)})},a.fn.unbind=function(a,b){return this.each(function(){l(this,a,b)})},a.fn.one=function(a,b){return this.each(function(c,d){k(this,a,b,null,function(a,b){return function(){var c=a.apply(d,arguments);return l(d,b,a),c}})})};var m=function(){return!0},n=function(){return!1},o={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};a.fn.delegate=function(b,c,d){var e=!1;if(c=="blur"||c=="focus")a.iswebkit?c=c=="blur"?"focusout":c=="focus"?"focusin":c:e=!0;return this.each(function(f,g){k(g,c,d,b,function(c){return function(d){var e,f=a(d.target).closest(b,g).get(0);if(f)return e=a.extend(p(d),{currentTarget:f,liveFired:g}),c.apply(f,[e].concat([].slice.call(arguments,1)))}},e)})},a.fn.undelegate=function(a,b,c){return this.each(function(){l(this,b,c,a)})},a.fn.live=function(b,c){return a(document.body).delegate(this.selector,b,c),this},a.fn.die=function(b,c){return a(document.body).undelegate(this.selector,b,c),this},a.fn.on=function(b,c,d){return c==undefined||a.isFunction(c)?this.bind(b,c):this.delegate(c,b,d)},a.fn.off=function(b,c,d){return c==undefined||a.isFunction(c)?this.unbind(b,c):this.undelegate(c,b,d)},a.fn.trigger=function(b,c){return typeof b=="string"&&(b=a.Event(b)),q(b),b.data=c,this.each(function(){"dispatchEvent"in this&&this.dispatchEvent(b)})},a.fn.triggerHandler=function(b,c){var d,e;return this.each(function(f,h){d=p(typeof b=="string"?a.Event(b):b),d.data=c,d.target=h,a.each(g(h,b.type||b),function(a,b){e=b.proxy(d);if(d.isImmediatePropagationStopped())return!1})}),e},"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout change select keydown keypress keyup error".split(" ").forEach(function(b){a.fn[b]=function(a){return this.bind(b,a)}}),["focus","blur"].forEach(function(b){a.fn[b]=function(a){if(a)this.bind(b,a);else if(this.length)try{this.get(0)[b]()}catch(c){}return this}}),a.Event=function(a,b){var c=document.createEvent(e[a]||"Events"),d=!0;if(b)for(var f in b)f=="bubbles"?d=!!b[f]:c[f]=b[f];return c.initEvent(a,d,!0,null,null,null,null,null,null,null,null,null,null,null,null),c}}(Zepto),function(a){function b(a){var b=this.os={},c=this.browser={},d=a.match(/WebKit\/([\d.]+)/),e=a.match(/(Android)\s+([\d.]+)/),f=a.match(/(iPad).*OS\s([\d_]+)/),g=!f&&a.match(/(iPhone\sOS)\s([\d_]+)/),h=a.match(/(webOS|hpwOS)[\s\/]([\d.]+)/),i=h&&a.match(/TouchPad/),j=a.match(/Kindle\/([\d.]+)/),k=a.match(/Silk\/([\d._]+)/),l=a.match(/(BlackBerry).*Version\/([\d.]+)/);if(c.webkit=!!d)c.version=d[1];e&&(b.android=!0,b.version=e[2]),g&&(b.ios=b.iphone=!0,b.version=g[2].replace(/_/g,".")),f&&(b.ios=b.ipad=!0,b.version=f[2].replace(/_/g,".")),h&&(b.webos=!0,b.version=h[2]),i&&(b.touchpad=!0),l&&(b.blackberry=!0,b.version=l[2]),j&&(b.kindle=!0,b.version=j[1]),k&&(c.silk=!0,c.version=k[1]),!k&&b.android&&a.match(/Kindle Fire/)&&(c.silk=!0)}b.call(a,navigator.userAgent),a.__detect=b}(Zepto),function(a,b){function l(a){return a.toLowerCase()}function m(a){return d?d+a:l(a)}var c="",d,e,f,g={Webkit:"webkit",Moz:"",O:"o",ms:"MS"},h=window.document,i=h.createElement("div"),j=/^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i,k={};a.each(g,function(a,e){if(i.style[a+"TransitionProperty"]!==b)return c="-"+l(a)+"-",d=e,!1}),k[c+"transition-property"]=k[c+"transition-duration"]=k[c+"transition-timing-function"]=k[c+"animation-name"]=k[c+"animation-duration"]="",a.fx={off:d===b&&i.style.transitionProperty===b,cssPrefix:c,transitionEnd:m("TransitionEnd"),animationEnd:m("AnimationEnd")},a.fn.animate=function(b,c,d,e){return a.isObject(c)&&(d=c.easing,e=c.complete,c=c.duration),c&&(c/=1e3),this.anim(b,c,d,e)},a.fn.anim=function(d,e,f,g){var h,i={},l,m=this,n,o=a.fx.transitionEnd;e===b&&(e=.4),a.fx.off&&(e=0);if(typeof d=="string")i[c+"animation-name"]=d,i[c+"animation-duration"]=e+"s",o=a.fx.animationEnd;else{for(l in d)j.test(l)?(h||(h=[]),h.push(l+"("+d[l]+")")):i[l]=d[l];h&&(i[c+"transform"]=h.join(" ")),!a.fx.off&&typeof d=="object"&&(i[c+"transition-property"]=Object.keys(d).join(", "),i[c+"transition-duration"]=e+"s",i[c+"transition-timing-function"]=f||"linear")}return n=function(b){if(typeof b!="undefined"){if(b.target!==b.currentTarget)return;a(b.target).unbind(o,arguments.callee)}a(this).css(k),g&&g.call(this)},e>0&&this.bind(o,n),setTimeout(function(){m.css(i),e<=0&&setTimeout(function(){m.each(function(){n.call(this)})},0)},0),this},i=null}(Zepto),function($){function triggerAndReturn(a,b,c){var d=$.Event(b);return $(a).trigger(d,c),!d.defaultPrevented}function triggerGlobal(a,b,c,d){if(a.global)return triggerAndReturn(b||document,c,d)}function ajaxStart(a){a.global&&$.active++===0&&triggerGlobal(a,null,"ajaxStart")}function ajaxStop(a){a.global&&!--$.active&&triggerGlobal(a,null,"ajaxStop")}function ajaxBeforeSend(a,b){var c=b.context;if(b.beforeSend.call(c,a,b)===!1||triggerGlobal(b,c,"ajaxBeforeSend",[a,b])===!1)return!1;triggerGlobal(b,c,"ajaxSend",[a,b])}function ajaxSuccess(a,b,c){var d=c.context,e="success";c.success.call(d,a,e,b),triggerGlobal(c,d,"ajaxSuccess",[b,c,a]),ajaxComplete(e,b,c)}function ajaxError(a,b,c,d){var e=d.context;d.error.call(e,c,b,a),triggerGlobal(d,e,"ajaxError",[c,d,a]),ajaxComplete(b,c,d)}function ajaxComplete(a,b,c){var d=c.context;c.complete.call(d,b,a),triggerGlobal(c,d,"ajaxComplete",[b,c]),ajaxStop(c)}function empty(){}function mimeToDataType(a){return a&&(a==htmlType?"html":a==jsonType?"json":scriptTypeRE.test(a)?"script":xmlTypeRE.test(a)&&"xml")||"text"}function appendQuery(a,b){return(a+"&"+b).replace(/[&?]{1,2}/,"?")}function serializeData(a){isObject(a.data)&&(a.data=$.param(a.data)),a.data&&(!a.type||a.type.toUpperCase()=="GET")&&(a.url=appendQuery(a.url,a.data))}function serialize(a,b,c,d){var e=$.isArray(b);$.each(b,function(b,f){d&&(b=c?d:d+"["+(e?"":b)+"]"),!d&&e?a.add(f.name,f.value):(c?$.isArray(f):isObject(f))?serialize(a,f,c,b):a.add(b,f)})}var jsonpID=0,isObject=$.isObject,document=window.document,key,name,rscript=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,scriptTypeRE=/^(?:text|application)\/javascript/i,xmlTypeRE=/^(?:text|application)\/xml/i,jsonType="application/json",htmlType="text/html",blankRE=/^\s*$/;$.active=0,$.ajaxJSONP=function(a){var b="jsonp"+ ++jsonpID,c=document.createElement("script"),d=function(){$(c).remove(),b in window&&(window[b]=empty),ajaxComplete("abort",e,a)},e={abort:d},f;return a.error&&(c.onerror=function(){e.abort(),a.error()}),window[b]=function(d){clearTimeout(f),$(c).remove(),delete window[b],ajaxSuccess(d,e,a)},serializeData(a),c.src=a.url.replace(/=\?/,"="+b),$("head").append(c),a.timeout>0&&(f=setTimeout(function(){e.abort(),ajaxComplete("timeout",e,a)},a.timeout)),e},$.ajaxSettings={type:"GET",beforeSend:empty,success:empty,error:empty,complete:empty,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript",json:jsonType,xml:"application/xml, text/xml",html:htmlType,text:"text/plain"},crossDomain:!1,timeout:0},$.ajax=function(options){var settings=$.extend({},options||{});for(key in $.ajaxSettings)settings[key]===undefined&&(settings[key]=$.ajaxSettings[key]);ajaxStart(settings),settings.crossDomain||(settings.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(settings.url)&&RegExp.$2!=window.location.host);var dataType=settings.dataType,hasPlaceholder=/=\?/.test(settings.url);if(dataType=="jsonp"||hasPlaceholder)return hasPlaceholder||(settings.url=appendQuery(settings.url,"callback=?")),$.ajaxJSONP(settings);settings.url||(settings.url=window.location.toString()),serializeData(settings);var mime=settings.accepts[dataType],baseHeaders={},protocol=/^([\w-]+:)\/\//.test(settings.url)?RegExp.$1:window.location.protocol,xhr=$.ajaxSettings.xhr(),abortTimeout;settings.crossDomain||(baseHeaders["X-Requested-With"]="XMLHttpRequest"),mime&&(baseHeaders.Accept=mime,mime.indexOf(",")>-1&&(mime=mime.split(",",2)[0]),xhr.overrideMimeType&&xhr.overrideMimeType(mime));if(settings.contentType||settings.data&&settings.type.toUpperCase()!="GET")baseHeaders["Content-Type"]=settings.contentType||"application/x-www-form-urlencoded";settings.headers=$.extend(baseHeaders,settings.headers||{}),xhr.onreadystatechange=function(){if(xhr.readyState==4){clearTimeout(abortTimeout);var result,error=!1;if(xhr.status>=200&&xhr.status<300||xhr.status==304||xhr.status==0&&protocol=="file:"){dataType=dataType||mimeToDataType(xhr.getResponseHeader("content-type")),result=xhr.responseText;try{dataType=="script"?(1,eval)(result):dataType=="xml"?result=xhr.responseXML:dataType=="json"&&(result=blankRE.test(result)?null:JSON.parse(result))}catch(e){error=e}error?ajaxError(error,"parsererror",xhr,settings):ajaxSuccess(result,xhr,settings)}else ajaxError(null,"error",xhr,settings)}};var async="async"in settings?settings.async:!0;xhr.open(settings.type,settings.url,async);for(name in settings.headers)xhr.setRequestHeader(name,settings.headers[name]);return ajaxBeforeSend(xhr,settings)===!1?(xhr.abort(),!1):(settings.timeout>0&&(abortTimeout=setTimeout(function(){xhr.onreadystatechange=empty,xhr.abort(),ajaxError(null,"timeout",xhr,settings)},settings.timeout)),xhr.send(settings.data?settings.data:null),xhr)},$.get=function(a,b){return $.ajax({url:a,success:b})},$.post=function(a,b,c,d){return $.isFunction(b)&&(d=d||c,c=b,b=null),$.ajax({type:"POST",url:a,data:b,success:c,dataType:d})},$.getJSON=function(a,b){return $.ajax({url:a,success:b,dataType:"json"})},$.fn.load=function(a,b){if(!this.length)return this;var c=this,d=a.split(/\s/),e;return d.length>1&&(a=d[0],e=d[1]),$.get(a,function(a){c.html(e?$(document.createElement("div")).html(a.replace(rscript,"")).find(e).html():a),b&&b.call(c)}),this};var escape=encodeURIComponent;$.param=function(a,b){var c=[];return c.add=function(a,b){this.push(escape(a)+"="+escape(b))},serialize(c,a,b),c.join("&").replace("%20","+")}}(Zepto),function(a){a.fn.serializeArray=function(){var b=[],c;return a(Array.prototype.slice.call(this.get(0).elements)).each(function(){c=a(this);var d=c.attr("type");this.nodeName.toLowerCase()!="fieldset"&&!this.disabled&&d!="submit"&&d!="reset"&&d!="button"&&(d!="radio"&&d!="checkbox"||this.checked)&&b.push({name:c.attr("name"),value:c.val()})}),b},a.fn.serialize=function(){var a=[];return this.serializeArray().forEach(function(b){a.push(encodeURIComponent(b.name)+"="+encodeURIComponent(b.value))}),a.join("&")},a.fn.submit=function(b){if(b)this.bind("submit",b);else if(this.length){var c=a.Event("submit");this.eq(0).trigger(c),c.defaultPrevented||this.get(0).submit()}return this}}(Zepto),function(a){function d(a){return"tagName"in a?a:a.parentNode}function e(a,b,c,d){var e=Math.abs(a-b),f=Math.abs(c-d);return e>=f?a-b>0?"Left":"Right":c-d>0?"Up":"Down"}function h(){g=null,b.last&&(b.el.trigger("longTap"),b={})}function i(){g&&clearTimeout(g),g=null}var b={},c,f=750,g;a(document).ready(function(){var j,k;a(document.body).bind("touchstart",function(e){j=Date.now(),k=j-(b.last||j),b.el=a(d(e.touches[0].target)),c&&clearTimeout(c),b.x1=e.touches[0].pageX,b.y1=e.touches[0].pageY,k>0&&k<=250&&(b.isDoubleTap=!0),b.last=j,g=setTimeout(h,f)}).bind("touchmove",function(a){i(),b.x2=a.touches[0].pageX,b.y2=a.touches[0].pageY}).bind("touchend",function(a){i(),b.isDoubleTap?(b.el.trigger("doubleTap"),b={}):b.x2&&Math.abs(b.x1-b.x2)>30||b.y2&&Math.abs(b.y1-b.y2)>30?(b.el.trigger("swipe")&&b.el.trigger("swipe"+e(b.x1,b.x2,b.y1,b.y2)),b={}):"last"in b&&(b.el.trigger("tap"),c=setTimeout(function(){c=null,b.el.trigger("singleTap"),b={}},250))}).bind("touchcancel",function(){c&&clearTimeout(c),g&&clearTimeout(g),g=c=null,b={}})}),["swipe","swipeLeft","swipeRight","swipeUp","swipeDown","doubleTap","tap","singleTap","longTap"].forEach(function(b){a.fn[b]=function(a){return this.bind(b,a)}})}(Zepto); \ No newline at end of file diff --git a/static/app2/js/zhuweiba.js b/static/app2/js/zhuweiba.js new file mode 100755 index 0000000..de7df83 --- /dev/null +++ b/static/app2/js/zhuweiba.js @@ -0,0 +1,332 @@ +$('.getquan').css('display', 'none'); +// $('#search').css('width', '80%'); +$('.saoyisao').hide(); +$('.class_block').eq(0).attr('data-classifyId', 5); +$('.class_block').eq(1).attr('data-classifyId', 6); +$('.class_block').eq(2).attr('data-classifyId', 7); +$('.class_block').eq(3).attr('data-classifyId', 8); +$('.class_block').eq(4).attr('data-classifyId', ''); +$('.zya_block').addClass('add_'); +mui.init({ + beforeback: function() { //获得父页面的webview + var list = plus.webview.currentWebview().opener(); //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + //返回true,继续页面关闭逻辑 + return true; + }, +}); +var data = ''; +var addr = ''; +var lat = '', + lat1 = '', + lng = ''; +var page = 1; +var pageSize = 5; +var count = 1; +var isjiazai = 1; +var nowPage = 1; +var isLoading = false; +mui.plusReady(function() { + getLocation(); + function getLocation() { + if (navigator.geolocation) { + plus.geolocation.getCurrentPosition(showPosition, showError); + + } else { + mui.alert("手机不支持定位") + } + } + function showPosition(position) { + + lat = position.coords.latitude; + lng = position.coords.longitude; + localStorage.setItem('lat', lat); + localStorage.setItem('lng', lng); + getShopList(nowPage, pageSize); + addr = position.address.city; + localStorage.setItem('addr', addr); + $('#location').html(addr); + $('#location-r').html(addr); + } + + function showError(error) { + switch (error.code) { + case error.TIMEOUT: + mui.alert('请求超时,请重试') + break; + case error.POSITION_UNAVAILABLE: + mui.alert('定位不到你的地址') + break; + case error.PERMISSION_DENIED: + // case 22: + mui.alert('您拒绝了地理位置请求') + break; + case error.UNKNOWN_ERROR: + mui.alert('未知错误') + break; + default: + mui.alert(error.message) + break; + } + getShopList(nowPage, pageSize); + } + //bannerTop + mui.ajax(qlgUrl('app/shopping/getHelpCarousel'), { + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒; + success: function(data) { //服务器返回响应,根据响应结果,分析是否登录成功; + if (data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide add_" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + + '"><img src="' + hyhImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + var topBannerheight = localStorage.getItem('topBannerheight') + + $('#top_banner').height(topBannerheight) + // $('#top_banner').height(($('#top_banner').width() )* 460 / 750); + } else { + mui.alert(data.msg) + } + }, + error: function(xhr, type, errorThrown) { //异常处理; + // mui.alert(errorThrown); + } + }); + + mui('.con').on('tap', '.bc_img', function() { + var goodsId = $(this).attr('data-goodsId'); + JZL.openWindow('details.html', 'details.html' + goodsId, {data_id: goodsId}); + }) + function getShopList(nowPage, pageSize) { + + lat = localStorage.getItem('lat'); + lng = localStorage.getItem('lng'); + + if (null == lat) { + lat = 36.659565; + lng = 117.125824; + } + var recommenddata = { + shopType: 1, + page: nowPage ? nowPage : 1, + perPage: pageSize ? pageSize : 10, + lat: lat, + lng: lng, + } + if (true == isLoading) return; + isLoading = true; + //console.log(lat); + JZL.ajax(hyhUrl('app/shopping/getHelpShops'), recommenddata, function(data) { + + var html = ''; + var shopLevel + if (1 == data.status) { + var data = data.data; + // console.log(data); + if ('' == data.Rows) { + $('.shoplist').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多数据</p>'); + // isLoading = false; + return; + } + $.each(data.Rows, function(index, element) { + shopLevel = this.shopLevel + if(0==shopLevel){ + shopLevel ='' + } + html += + '<div class="con shadown_wai" data-shopId="' + this.shopId + + '"><div class="shops-content1-title" data-shopId="' + this.shopId + + '" data-shopName="'+this.shopName +'" ><span class="logoimg"><img src="' + hyhImgUrl(this.shopImg) + + '"alt=""></span><div class="shop-name">' + + this.shopName + '<img class ="aixinImg" src = "../img/aixin.png"><span class="aixinlevel">'+ shopLevel + '</span> </div><span class="gogogo">进店逛逛</span></div><div class="t_con">' + if (0 != this.goods.length) { + $.each(this.goods, function(idx, ele) { + + html += '<div class="t_con_ bc_img" data-goodsId="' + this.goodsId + + '" data-goodsType = 2 ><div class="t_con_img"><img src="' + hyhImgUrl(this.goodsImg) + '" data-goodsId="' + this.goodsId + + '" alt=""></div><span>¥' + this.shopPrice + '</span></div>' + }) + } + + html += '</div><div class="pos clearfix"><img src="../img/dingwei1.png"><span>距离:' + this.distance / 1000 + + '公里</span></div></div>' + }) + if (nowPage == 1) { + $('.shoplist').html(html); + } else { + $('.shoplist').append(html); + } + isLoading = false; + } else { + mui.alert(data.msg) + } + }) + } + //加载 + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isLoading == false) { + nowPage++; + // getShops(nowPage, pageSize); + getShopList(nowPage, pageSize) + } + } + }) + mui('.shoplist').on('tap', '.shops-content1-title', function() { + // var goodsId = $(this).attr('data-goodsId'); + var shopName = $(this).attr("data-shopName"); + var shopId = $(this).attr("data-shopId"); + JZL.openWindow('storeout.html', 'storeout.html', {shopName: shopName,shopId: shopId}); + }) +}) + +//获取推荐页 +function getRecommend(page, pagesize) { + var recommenddata = { + type : 2 , + page: page ? page : 1, + pagesize: pageSize ? pageSize : 10 + } + if (isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + JZL.ajax(qlgUrl('app/shopping/getGoods'), recommenddata, function(data) { + // console.log(data); + // if (data.status == 1) { + var html = ''; + // var data = data.data; + if (data.Rows == '') { + $('.self_shop_rem').append( + '<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + + '" data-goodsType = 2><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:inline-block;" data-shopId="' + + this.shopId + '"></span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><div><span>' + this.saleNum + + '人购买</span></div><div style="display:none"><span>优惠率&nbsp;&nbsp;' + this.discountRate + + '</span></div></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if (page == 1) { + $('.recommend_con').html(html); + } else { + $('.recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_title span').each(function() { + if ($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + + // } else { + // mui.alert(data.msg) + // } + }) +} +$('.bcon_left').height($('.bcon_left').width() * 345 / 185); +$('.bcon_left img').height($('.bcon_left img').width() * 345 / 185); +$('.bcr_block').height($('.bcr_block').width()); +$('.addsct_block').height($('.addsct_block').width() * 225 / 355); +$('.addscb_block').height($('.addscb_block').width() * 260 / 180); +$('.zya_block').height($('.zya_block').width() * 185 / 355); + +var issx = 0; + +// 轮播图跳转 +$('#slider').on('tap', '.swiper-slide', function() { + openAds($(this)); +}) + +//导航栏 +document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (-scroll.y < 0) { + num = 0; + } else if ((-scroll.y > 0 || scroll.y == 0) && -scroll.y < 150) { + num = -scroll.y / 150; + } else { + num = 1; + } + $('.header').css('background-color', 'rgba(255,255,255,' + num + ')') + + if (-scroll.y < 75) { + $('.saoyisao').attr('src', '../img/saoyisao.png'); + $('.msg').attr('src', '../img/icon_msg.png'); + $('.search').attr('src', '../img/icon_search.png'); + $('#search').css('background-color', 'white'); + $('.header').removeClass('shadown_wai'); + } else { + $('.saoyisao').attr('src', '../img/saoyisao1.png'); + $('.msg').attr('src', '../img/icon_msg1.png'); + $('.search').attr('src', '../img/icon_search1.png'); + $('#search').css('background-color', '#d8d8d8'); + $('.header').addClass('shadown_wai'); + } + + if (scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } +}) +mui('.classify').on('tap', '.class_block', function() { + var classifyId = $(this).attr('data-classifyId'); + var url = 'orSupermarket.html'; + + if (classifyId == '') { + url = 'ac3.html'; + } + JZL.openWindow(url, url, {classifyId: classifyId}); +}) + +//为你推荐 +getRecommend(page, pageSize); +document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if (scroll.y == scroll.maxScrollY) { + if (isjiazai == 1) { + page++; + getRecommend(page, pageSize); + } + } +}) +//搜索 +$('.header').on('focus', '#keyword', function() { + $(".search button").css('display', 'block'); +}) +$('.header').on('blur', '#keyword', function() { + $(".search button").css('display', 'none'); +}) +$(".header").on('tap', '.search button', function(e) { + var searchName = $('#keyword').val(); + // JZL.openWindow('shopsList.html', 'shopsList.html', {data_keyword: searchName,goodsType:2}); + JZL.openWindow('goodslist.html', 'goodslist.html', {data_keyword: searchName,goodsType :2}); + $('#keyword').val("") +}); +//跳转商品详情页 +mui("body").on('tap', '.bc_img', function() { + var goodsId = $(this).attr('data-goodsId'); + var shopId = $(this).parent().parent().attr('data-shopId'); + var goodsType=$(this).attr('data-goodsType') + JZL.openWindow('details.html', 'details.html' + goodsId, {data_id: goodsId,shopId: shopId,goodsType : goodsType}); +}) diff --git a/static/app2/js/╕┤╓╞ activity7.js b/static/app2/js/╕┤╓╞ activity7.js new file mode 100755 index 0000000..2591365 --- /dev/null +++ b/static/app2/js/╕┤╓╞ activity7.js @@ -0,0 +1,282 @@ +$('.mui-title').html('ECT专区'); +var ect_top = '<div class="ect_top"><p class="ect_m">最新价</p><p class="ect_m">24H成交量</p><img src="http://img.heyuanhui.cn/Upload/app/icon/star.png" /><p class="ect_m" id="last"></p><p class="ect_m" id="vol"></p></div>'; +$('header').before(ect_top); +var time_ = '距活动开始还有<span id="_d"></span>天'; +$('.mui-scroll-wrapper').removeClass('scroll_out1').addClass('scroll_out3'); +var info = '<img src="http://img.heyuanhui.cn/Upload/app/icon/info.png" class="tanhao" />'; +$('header').append(info); +var nav = '<div class="nav clearfix"></div>'; +$('.ect_top').before(nav); +var html_con = '<div class="ten clearfix"></div><div class="title_img"></div><div class="time_"></div><div class="con_"></div>' + +$('.con').html(html_con); +$('.time_').html(time_); +var nav_data = []; +var secTypeId = 0; +var timestamp1 = Date.parse(new Date()); +if(timestamp1 >= 1537027200000) { + secTypeId = 4; + nav_data = [{ + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} else { + secTypeId = 1; + nav_data = [{ + "secTypeId": 1, + "name": "9.15元专区" + }, { + "secTypeId": 2, + "name": "满199减100" + }, { + "secTypeId": 3, + "name": "买二赠一专区" + }, { + "secTypeId": 4, + "name": "海鲜大咖" + }, { + "secTypeId": 5, + "name": "为您推荐" + }]; +} + +var issx = 0; +var doller = 0; + +function getData(secTypeId) { + // mui('').pullRefresh().scroll(0, 0, 0); + backTop(); + var data_set = { + secTypeId: secTypeId, + topTypeId: 1 + }; + mui.ajax(llUrl('addon/hyhlimitactive-Hyhlimitactive-frontList'), {  + data: data_set, + dataType: 'json', //服务器返回json格式数据 + type: 'post', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + var data = toJson(data, 1); + if(data.status == 1) { + + data = data.data; + var html_ = ''; + var htmlcon = ''; + + doller = data.doller; + if(data.secTypeId == 5 || data.secTypeId == 4) { + htmlcon = '<div class="ect_activity"><img src="http://img.heyuanhui.cn/static/app/img/e' + secTypeId + '.png" class="ect_hd" /></div>' + } else { + htmlcon = '<div class="ect_activity_"><img src="http://img.heyuanhui.cn/static/app/img/countdown.png" class="ect_djs" /> <span id="_h">00</span><span id="_m">00</span><span id="_s">00</span></div>' + html_ = '<div class="day"><p>此活动仅限14-15号两天</p></div>'; + } + + $.each(data.list, function() { + htmlcon += '<div class="ect_com" data-id="' + this.goodsId + '"><div class="com_img1" ><img src="' + hyhImgUrl(this.goodsImg) + '" /></div><p class="p1"><img src="http://img.heyuanhui.cn/static/app/img/ectb.png" class="com_img2" />' + this.goodsName + '</p><p class="p3"><l></l>CNY <o>' + this.shopPrice + '</o></p>' + html_ + '</div>'; + }); + $('.con').html(htmlcon); + + setTimeout(function() { + $('.com_img1').height($('.com_img1').width()); + }, 200) + countTime(); + + } else { + console.log(data); + } + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + });  +} + +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date("2018/09/16 00:00:00"); + var end = endDate.getTime(); + //时间差 + var leftTime = end - now; + //定义变量 d,h,m,s保存倒计时的时间 + var h, m, s; + if(leftTime >= 0) { + d = Math.floor(leftTime / 1000 / 60 / 60 /24); + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(d < 10) { + d = "0" + d; + } + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + document.getElementById("_d").innerHTML = d; +// document.getElementById("_h").innerHTML = h; +// document.getElementById("_m").innerHTML = m; +// document.getElementById("_s").innerHTML = s; + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +mui.plusReady(function() { + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + + }); + getData(secTypeId); + + var html = ''; + $.each(nav_data, function() { + if(timestamp1 >= 1537027200000) { + html += '<div class="nav_block" style="width:50%;" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } else { + html += '<div class="nav_block" data-secTypeId="' + this.secTypeId + '">' + this.name + '</div>'; + } + + }); + $('.nav').html(html); + $('.nav_block').eq(0).addClass('on'); + + setInterval(function() { + + mui.ajax('https://api.tokencan.com/exchange-open-api/open/api/get_ticker?symbol=ectusdt&random=' + Math.random(), {  + + dataType: 'json', //服务器返回json格式数据 + type: 'get', //HTTP请求类型 + timeout: 10000, //超时时间设置为10秒 + success: function(data) { + //服务器返回响应,根据响应结果,分析是否登录成功; + // var data = toJson(data, 1); + $('#last').html(Math.floor((+data.data.last) * doller * 100) / 100); + $('#vol').html(data.data.vol); + $('.p3').each(function(num) { + $(this).children('l').html('ECT ' + (Math.floor(+$(this).children('o').html() / (+data.data.last) / (+doller) * 100)) / 100 + '≈'); + }) + + }, + + error: function(xhr, type, errorThrown) { + //异常处理; + // alert(type);       + } + }); + + }, 2000) + + mui("body").on('tap', '.nav_block', function() { + secTypeId = this.attributes["data-secTypeId"].nodeValue; + $(this).addClass('on').siblings().removeClass('on'); + getData(secTypeId) + }) + + mui(".con").on('tap', '.ect_com', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-id"].nodeValue; + var isEct = 1; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id, + isEct: isEct + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + // if(isjiazai == 1) { + // page++; + // } + + } else if(scroll.y > 100 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + + $('header').on('tap', '.tanhao', function() { + mui.openWindow({ + url: 'activity8.html', + id: 'activity8.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }); +}) \ No newline at end of file diff --git a/static/app2/js/╕┤╓╞ confirmOrder.js b/static/app2/js/╕┤╓╞ confirmOrder.js new file mode 100755 index 0000000..1d15609 --- /dev/null +++ b/static/app2/js/╕┤╓╞ confirmOrder.js @@ -0,0 +1,764 @@ +$('.pay_info .row_left').eq(0).html('桔子链账号'); + +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init(); +mui.plusReady(function() { + window.addEventListener('setAddress', function(e) { + var addressId = localStorage.getItem('addressId') ? localStorage.getItem('addressId') : 0; + if(addressId == 0) { + return; + } + mui.ajax(hyhUrl('app/useraddress/getById'), {  + data: { + addressId: addressId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + data = toJson(data); + if(data.status == 1) { + data = data.data; + // for(i in data.data){ + // console.log(i) + // console.log(data.data[i]) + // } + var html = '<div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userName + '</div><div class="add_r_t_r">' + data.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.areaName + ' ' + data.userAddress + '</div></div>'; + $('.address').html(html); + $('.address').attr('data-addressId', data.addressId); + $('.address').attr('data-areaId', data.areaId2); + + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }); + + $('.con').on('tap', '.address', function() { + var addressId = $(this).attr('data-addressId'); + localStorage.setItem('addressId', addressId); + var isOrder = true; + mui.openWindow({ + url: 'setting_address.html', + id: 'setting_address.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_addressId: addressId, + data_isOrder: isOrder + + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + //支付插件 + plus.payment.getChannels(function(channels) { + for(var i in channels) { + if(channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=1&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if(id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if(id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch(xhr.readyState) { + case 4: + if(xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + plus.webview.getWebviewById('confirmOrder.html').close(); + }); + } else { + alert("获取订单信息失败!"); + console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + var self = plus.webview.currentWebview(); + var type = self.type; + var data_1 = {}; + var isUseScore = 0; + var orderNo; + var priceT = 0; + var payCode = ''; + // console.log(type) + + mui.ajax(hyhUrl('app/carts/settlement'), {  + data: { + type: type + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + var data = toJson(data); + + if(data.status == 1) { + var allallnum = 0; + data = data.data; + data_1 = data; + if(data.userAddress.addressId) { + var html = '<div class="address shadown_wai clearfix" data-addressId="' + data.userAddress.addressId + '" data-areaId2="' + data.userAddress.areaId2 + '"><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l">收货人:' + data.userAddress.userName + '</div><div class="add_r_t_r">' + data.userAddress.userPhone + '</div></div><div class="add_r_b">收货地址:' + data.userAddress.areaName + ' ' + data.userAddress.userAddress + '</div></div></div>'; + } else { + var html = '<div class="address shadown_wai clearfix" ><div class="add_l"><img src="../img/dingwei1.png" /></div><div class="add_r"><div class="add_r_t clearfix"><div class="add_r_t_l" style="height:60px;line-height:60px;font-size:14.4px;color:black">请选择收货地址</div></div></div></div>'; + } + $.each(data.carts, function() { + var allNum = 0; + html += '<div class="shop_info shadown_wai"><div class="row_title"><div class="store_name">' + this.shopName + '</div></div><div class="row_con clearfix">'; + $.each(this.list, function() { + allNum += this.cartNum; + var price = ''; + if(this.isWhsle == 1) { + price = this.whslePrice; + } else if(this.specPrice != 'null') { + price = this.shopPrice; + } else { + price = this.specPrice; + } + var specNames = ''; + for(var i in this.specNames[0]) { + if(i == "catName") { + specNames = this.specNames[0][i] + ':'; + } else if(i == "itemName") { + specNames += this.specNames[0][i] + } + } + + html += '<div class="row_block clearfix" data-id="' + this.goodsId + '"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">'; + $.each(this.specNames, function() { + html += this.catName + ':' + this.itemName + ';'; + }); + + html += '</p></div><div class="rcrr"><p>¥' + price + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.cartNum + '</span></div></div></div>' + }); + allallnum += allNum; + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">买家留言:</div><div class="c1_r"><input class="remark" data-shopId="' + this.shopId + '" type="text" name="" id="" value="" placeholder="选填:填写内容已和卖家协商确认" /></div></div></div>'; + + html += '<div class="cost"><div class="c2 clearfix"><div class="c1_l">选择优惠券:</div><div class="c1_r"><select name="" data-shopId="' + this.shopId + '" class="yhq"><option value="0">不使用优惠券</option>'; + $.each(this.coupons, function() { + html += '<option value="' + this.couponId + '">满' + this.useMoney + '元减' + this.couponValue + '元</option>'; + }); + html += '</select></div></div></div><div class="cost"><div class="c2 clearfix"><div class="c1_r">共' + allNum + '件商品 小计:<o class="on">¥' + this.goodsMoney + '</o> + 运费:<o class="on">¥' + this.shippingMoney + '</o></div></div></div></div></div>'; + }); + + html += '<div class="shadown_wai">'; + // if(data.ect_pay == 0) { + html += '<div class="isHb clearfix"><div class="h_left">木吉抵用&nbsp;&nbsp;&nbsp;&nbsp;<o id="huibao">可抵用木吉:' + data.useOrderScore + '</o></div><div class="he_right"><div class="checkout"><div class="check_btn"></div></div></div></div>' + // } + html += '<div class="jf_info clearfix"><div class="jf_jf">木吉</div><div class="jf_p">奖励木吉为成交价格的20%</div></div></div>'; + priceT = (Math.floor((+data.goodsTotalMoney - (+data.promotionMoney)) * 100)) / 100; + priceT = priceT >= 0 ? priceT : 0; + var html1 = '<span>共' + allallnum + '件商品 合计:<j>¥' + priceT + '</j></span>&nbsp;&nbsp;<button class="btn_tj">提交订单</button>'; + // if(data.ect_pay == 1) { + var htmlpay = '<div class="row clearfix" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.userECT + '</o></p><p class="row_right mui-icon"></p><span style="color:red;">&nbsp;&nbsp;限时9.5折</span></div>'; + + $('#pay_way .con_1').append(htmlpay); + // $('.pay_info .con_1 .row').eq(0).attr('style','display: none;'); + // $('.pay_info .con_1 .row').eq(1).remove(); + // }; + $('.con_').html(html); + $('.js_r').html(html1); + $('#loginName').html(data.loginName); + $('.userMoney').html(data.userMoney); + + $('#goodsTotalMoney').html(priceT); + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + $('.con').on('change', 'select', function() { + var couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + // var addressId = $('.address').attr('data-addressId') + var areaId2 = $('.address').attr('data-areaId2') + var couponIdsArr = couponIds.join(','); + mui.ajax(hyhUrl('app/carts/getMoney'), {  + data: { + type: type, + areaId2: addressId, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + couponIds: couponIdsArr + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + // console.log(data.msg) + if(data.status == 1) { + + $('.js_r span j').html('¥' + data.data.realTotalMoney) + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }); + + $('.con').on('tap', '.checkout', function() { + + $(this).toggleClass('on'); + if($(this).hasClass('on')) { + isUseScore = 1; + } else { + isUseScore = 0; + } + var couponIds = []; + $('select').each(function() { + couponIds.push($(this).attr('data-shopId') + ':' + $(this).val()); + }) + + var couponIdsArr = couponIds.join(','); + var areaId2 = $('.address').attr('data-areaId2'); + // console.log(areaId2) + // console.log(couponIdsArr) + // console.log(data_1.userAddress.areaId2) + // console.log(data_1.userAddress) + mui.ajax(hyhUrl('app/carts/getMoney'), {  + data: { + type: type, + areaId2: areaId2, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + couponIds: couponIdsArr + + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + // console.log(data.msg) + if(data.status == 1) { + // console.log(data) + // console.log(data.data.shopFreight) + // for(i in data.data){ + // console.log(i) + // console.log(data.data[i]) + // } + $('.js_r span j').html('¥' + data.data.realTotalMoney) + priceT = data.data.realTotalMoney; + $('#goodsTotalMoney').html(data.data.realTotalMoney); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + }) + $('.footer').on('tap', '.btn_tj', function() { + payCode = $('.select_payway').attr('data-payCode'); + var that = $(this); + var addressId = $('.address').attr('data-addressId'); + if(addressId) { + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + } else { + alert('未设置收货地址!') + } + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.select_payway .row_right o').html($(this).children('.row_left').html()); + $('.select_payway').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + + }) + $('.pay').on('tap', '.select_payway', function() { + //if($(this).attr('data-payCode') == 'ect') {} else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + //} + + }) + + $('.pay_btn').on('tap', function() { + + var addressId = $('.address').attr('data-addressId'); + var areaId = $('.address').attr('data-areaId'); + var that = $(this); + payCode = $('.select_payway').attr('data-payCode'); + var data_send = { + type: type, + s_addressId: addressId, + s_areaId: areaId, + payCode: payCode, + payType: 1, + isUseScore: isUseScore, + useScore: data_1.useOrderScore, + deliverType: 0, + isInvoice: 0, + invoiceId: 0, + invoiceClient: '' + } + + $('.remark').each(function() { + data_send['remark_' + ($(this).attr('data-shopid'))] = $(this).val(); + }); + $('select').each(function() { + data_send['couponId_' + ($(this).attr('data-shopid'))] = $(this).val(); + }) + + console.log(priceT) + if(payCode == 'ect') { + that.attr('disabled', 'disabled'); + mui.ajax(hyhUrl('app/ect/getToEctNum'), {  + + data: { + total_money: priceT + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒; + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + if(data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if(e.index == 1) { + that.removeAttr('disabled'); + return; + + } else { + mui.ajax(hyhUrl('app/orders/submit'), {  + data: data_send, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.status) + data = toJson(data); + if(data.status == 1) { + orderNo = data.data; + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: data.data, + isBatch: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', data.data); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert(data.msg); + // that.removeAttr('disabled'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + } + }) + that.removeAttr('disabled'); + } + }) + } else { + alert(data.msg); + return; + } + + } + }) + } else { + mui.ajax(hyhUrl('app/orders/submit'), {  + data: data_send, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.status) + data = toJson(data); + if(data.status == 1) { + orderNo = data.data; + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: data.data, + isBatch: 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', data.data); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert(data.msg); + // that.removeAttr('disabled'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + } + }) + } + + }) + $('#pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('#pay_pwd').on('tap', '.pay_btn_pwd', function() { + + var payPwd = $('#payPwd').val(); + if(payPwd == '') { + alert('支付密码不能为空!'); + } + var that = $(this); + that.attr('disabled', 'disabled'); + var srcc = '' + if(payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + + mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), {  + + data: { + orderNo: orderNo, + isBatch: 1, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + // mui.back(); + mui.openWindow({ + url: 'indent.html', + id: 'indent.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: 'waitDeliver' + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: false, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + setTimeout(function() { + plus.webview.getWebviewById('confirmOrder.html').close(); + }, 500) + + } else { + mui.openWindow({ + url: 'indent.html', + id: 'indent.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_href: 'waitPay' + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: false, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + setTimeout(function() { + plus.webview.getWebviewById('confirmOrder.html').close(); + }, 500) + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + alert(errorThrown);       + } + });  + + }) +}) \ No newline at end of file diff --git a/static/app2/js/╕┤╓╞ home.js b/static/app2/js/╕┤╓╞ home.js new file mode 100755 index 0000000..f2f3b73 --- /dev/null +++ b/static/app2/js/╕┤╓╞ home.js @@ -0,0 +1,679 @@ +$('.saoyisao').css('display', 'none'); +$('.getquan').css('display', 'none'); +$('#hot_more').css('display', 'none'); +$('#search').css('width', '80%'); +$('#search').css('left', '5%'); +$('.searchimg').css('left', '8%'); +$('.time').css('display', 'none'); + +var page = 1; +var pagesize = 10; +var isjiazai = 1; + +function getRecommend(page, pagesize) { + var recommenddata = { + page: page ? page : 1, + pagesize: pagesize ? pagesize : 10 + } + if(isjiazai == 0) { + return; + } else { + isjiazai = 0; + } + mui.ajax(ectUrl('addon/shuff-Shuff-recommend'), {  + data: recommenddata, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + if(data.Rows == '') { + $('.mui-scroll').append('<p style="float: left;width: 100%;text-align: center;padding-bottom: 9px;">没有更多商品</p>'); + isjiazai = 0; + return; + } + $.each(data.Rows, function() { + + html += '<div class="recommend_con_block shadown_wai" data-goodsId="' + this.goodsId + '"><img class="rcb_img" src="' + ectImgUrl(this.goodsImg) + '" alt="" /><div class="rcb_con"><div class="rcb_title"><span style="display:none;" data-shopId="' + this.shopId + '">自营</span>' + this.goodsName + '</div><div class="rcb_pay">¥' + this.shopPrice + ' <span style="display:none;">满减</span></div><div class="rcb_bottom"><span>可用木吉抵扣20%货款</span></div></div><img style="display:none;" class="icon_icon" src="../img/icon_sscl.png" alt="" /></div>'; + }); + + if(page == 1) { + $('#recommend_con').html(html); + } else { + $('#recommend_con').append(html); + } + isjiazai = 1; + $('.rcb_title span').each(function() { + if($(this).attr('data-goodsId') == 1) { + $(this).css('display', 'none'); + } + }) + $('.rcb_img').height($('.rcb_img').width()); + + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + +} + +function getNextDate(dayStr) { + var dd = new Date(dayStr); + dd.setDate(dd.getDate() + 1); + var y = dd.getFullYear(); + var m = dd.getMonth() + 1; //获取当前月份的日期 + var d = dd.getDate(); + return y + "/" + m + "/" + d + " 00:00:00"; +}; + +function countTime() { + + //获取当前时间 + var date = new Date(); + var now = date.getTime(); + //设置截止时间 + var endDate = new Date(getNextDate(date)); + var end = endDate.getTime(); + //时间差 + var leftTime = end - now; + //定义变量 d,h,m,s保存倒计时的时间 + var h, m, s; + if(leftTime >= 0) { + h = Math.floor(leftTime / 1000 / 60 / 60); + m = Math.floor(leftTime / 1000 / 60 % 60); + s = Math.floor(leftTime / 1000 % 60); + //将倒计时赋值到div中 + if(h < 10) { + h = "0" + h; + } + if(m < 10) { + m = "0" + m; + } + if(s < 10) { + s = "0" + s; + } + document.getElementById("_h").innerHTML = h; + document.getElementById("_m").innerHTML = m; + document.getElementById("_s").innerHTML = s; + } + + //递归每秒调用countTime方法,显示动态时间效果 + setTimeout(countTime, 1000); + +} + +mui.plusReady(function() { + var ua = navigator.userAgent.toLowerCase(); + var issx = 0; + //获取折扣 + localStorage.removeItem('ectzhekou'); + mui.ajax(llUrl('addon/shuff-Shuff-ectDiscount'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + localStorage.setItem('ectzhekou',data.data); + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //bannerTop + mui.ajax(llUrl('addon/shuff-Shuff-homeCarousel'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide" data-adURL="' + this.adURL + '" data-targetType="' + this.targetType + '"><img src="' + ectImgUrl(this.adFile) + '" alt="" /></div>'; + }); + $('#top_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#top_banner', { + pagination: '#top_banner_pagination', + spaceBetween: 0, + loop: true, + autoplay: 3500, + autoplayDisableOnInteraction: false + }); + $('#top_banner').height($('#top_banner').width() * 460 / 750); + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + }); //秒杀 + mui.ajax(ectUrl('addon/hyhsale-Goods-appGoodsList'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide" data-goodsId="' + this.goodsId + '"><img src="' + ectImgUrl(this.goodsImg) + '" alt="" /><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del></div>'; + }); + $('#timer_swiper .swiper-wrapper').html(html); + countTime() + var swiper = new Swiper('#timer_swiper', { + slidesPerView: 4.5, + paginationClickable: true, + spaceBetween: 0, + freeMode: true + }); + $('#timer_swiper .swiper-slide img').height($('#timer_swiper .swiper-slide img').width()); + $('#timer_swiper .swiper-slide').height($('#timer_swiper .swiper-slide').width() * 250 / 160); + + } else { + // console.log(data.status) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //会员快报 + mui.ajax(hyhUrl('app/Articles/getIndexNews'), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(news_data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + var news_data = toJson(news_data); + if(news_data.status == 1) { + + news_data = news_data.data; + var news = ''; + $.each(news_data, function() { + // console.log(this.articleTitle) + news += '<a href="#" data-articleId="' + this.articleId + '">' + this.articleTitle + '</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; + + }) + $('#news').html(news); + // $('#news_more').html(''); + //console.log(news); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + //热门品牌 + mui.ajax(llUrl('addon/shuff-Shuff-shuff'), {  + data: { + positionId: 392 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var html = ''; + var data = data.data; + $.each(data, function() { + html += '<div class="swiper-slide"><div class="hotimg" data-targetType="' + this.targetType + '" data-adURL="' + this.adURL + '"><img class="hotimg_" src="' + ectImgUrl(this.adFile) + '" /></div><div class="hot_con clearfix">'; + + if(this.list != '') { + $.each(this.list, function(num) { + + if(num >= 3) { + return; + } + var adGoodsStatus = ''; + if(this.adGoodsStatus == 1) { + adGoodsStatus = '精品'; + } else if(this.adGoodsStatus == 2) { + adGoodsStatus = '推荐'; + } else if(this.adGoodsStatus == 3) { + adGoodsStatus = '热卖'; + } + html += '<div class="hot_con_block" data-goodsId="' + this.goodsId + '"><img class="hot_con_block_img" src="' + ectImgUrl(this.adGoodsImg) + '" /><p class="hcb_name">' + this.goodsName + '</p><p class="hcb_pay">¥' + this.shopPrice + '</p><div class="hot_bottom_icon"><img class="icon_star" src="../img/icon_star.png" /><span>' + adGoodsStatus + '</span></div></div>' + }) + } + + html += '</div></div>'; + }); + $('#hot_banner .swiper-wrapper').html(html); + var swiper = new Swiper('#hot_banner', { + pagination: '#hot_banner_pageination', + spaceBetween: 0, + loop: true, + autoplay: 5500, + autoplayDisableOnInteraction: false + }); + $('#hot_banner .swiper-wrapper .swiper-slide ').height($('#hot_banner ').width() * 820 / 718); + $('#hot_banner .swiper-wrapper .swiper-slide .hotimg').height($('#hot_banner .hotimg').width() * 320 / 662); + + $('.hot_con_block_img').height($('.hot_con_block_img').width()); + + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //广告位 + mui.ajax(llUrl('addon/shuff-Shuff-active'), {  + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // var data = toJson(data, 1); + if(data.status == 1) { + var data = data.data; + if(data[0]) { + $('.add_top_left').addClass('add_').attr('data-adURL', data[0].adURL).attr('data-targetType', data[0].targetType); + $('.add_top_left .p1').html(data[0].adName.split('|')[0]); + $('.add_top_left .p2').html(data[0].adName.split('|')[1]); + $('.add_top_left img').attr('src', ectImgUrl(data[0].adFile)); + } + if(data[1]) { + $('.add_top_right_con').eq(0).addClass('add_').attr('data-adURL', data[1].adURL).attr('data-targetType', data[1].targetType); + $('.add_top_right_con .p1').eq(0).html(data[1].adName.split('|')[0]); + $('.add_top_right_con .p2').eq(0).html(data[1].adName.split('|')[1]); + $('.add_top_right_con img').eq(0).attr('src', ectImgUrl(data[1].adFile)); + } + if(data[2]) { + $('.add_top_right_con').eq(1).addClass('add_').attr('data-adURL', data[2].adURL).attr('data-targetType', data[2].targetType); + $('.add_top_right_con .p1').eq(1).html(data[2].adName.split('|')[0]); + $('.add_top_right_con .p2').eq(1).html(data[2].adName.split('|')[1]); + $('.add_top_right_con img').eq(1).attr('src', ectImgUrl(data[2].adFile)); + } + if(data[3]) { + $('#abc_1').addClass('add_').attr('data-adURL', data[3].adURL).attr('data-targetType', data[3].targetType); + $('#abc_1 .p1').html(data[3].adName.split('|')[0]); + $('#abc_1 .p2').html(data[3].adName.split('|')[1]); + $('#abc_1 img').attr('src', ectImgUrl(data[3].adFile)); + } + if(data[4]) { + $('#abc_2').addClass('add_').attr('data-adURL', data[4].adURL).attr('data-targetType', data[4].targetType); + $('#abc_2 .p1').html(data[4].adName.split('|')[0]); + $('#abc_2 .p2').html(data[4].adName.split('|')[1]); + $('#abc_2 img').attr('src', ectImgUrl(data[4].adFile)); + } + if(data[5]) { + $('#abc_3').addClass('add_').attr('data-adURL', data[5].adURL).attr('data-targetType', data[5].targetType); + $('#abc_3 .p1').html(data[5].adName.split('|')[0]); + $('#abc_3 .p2').html(data[5].adName.split('|')[1]); + $('#abc_3 img').attr('src', ectImgUrl(data[5].adFile)); + + } + + // var html1 = `<div class="add_top_left add_" data-adURL="` + data[0].adURL + `" data-targetType="` + data[0].targetType + `"> + // <p class="p1">` + data[0].adName.split('|')[0] + `</p> + // <p class="p2">` + data[0].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[0].adFile) + `" /> + // </div> + // <div class="add_top_right"> + // <div class="add_top_right_con atrct add_" data-adURL="` + data[1].adURL + `" data-targetType="` + data[1].targetType + `"> + // <p class="p1">` + data[1].adName.split('|')[0] + `</p> + // <p class="p2">` + data[1].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[1].adFile) + `" /> + // </div> + // <div class="add_top_right_con add_" data-adURL="` + data[2].adURL + `" data-targetType="` + data[2].targetType + `"> + // <p class="p1">` + data[2].adName.split('|')[0] + `</p> + // <p class="p2">` + data[2].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[2].adFile) + `" /> + // </div> + // </div>`; + // + // $('.add_top').html(html1); + // var html2 = `<div class="add_bottom_con add_" id="abc_1" data-adURL="` + data[3].adURL + `" data-targetType="` + data[3].targetType + `"> + // <p class="p1">` + data[3].adName.split('|')[0] + `</p> + // <p class="p2">` + data[3].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[3].adFile) + `" /> + // </div> + // <div class="add_bottom_con add_" id="abc_2" data-adURL="` + data[4].adURL + `" data-targetType="` + data[4].targetType + `"> + // <p class="p1">` + data[4].adName.split('|')[0] + `</p> + // <p class="p2">` + data[4].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[4].adFile) + `" /> + // </div> + // <div class="add_bottom_con add_" id="abc_3" data-adURL="` + data[5].adURL + `" data-targetType="` + data[5].targetType + `"> + // <p class="p1">` + data[5].adName.split('|')[0] + `</p> + // <p class="p2">` + data[5].adName.split('|')[1] + `</p> + // <img src="` + ectImgUrl(data[5].adFile) + `" /> + // </div>`; + // $('.add_bottom').html(html2); + } else { + // console.log(2) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(errorThrown);       + }   + });  + //为你推荐 + getRecommend(page, pagesize); + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(scroll.y == scroll.maxScrollY) { + if(isjiazai == 1) { + page++; + getRecommend(page, pagesize); + } + } + }) + setInterval(function() { + + $('.add_top_left img').height($('.add_top_left img').width()); + $('.add_top_right_con img').height($('.add_top_right_con img').width()); + $('.add_bottom_con img').height($('.add_bottom_con img').width()); + + $('.rcb_img').height($('.rcb_img').width()); + + }, 100) + + document.querySelector('.mui-scroll-wrapper').addEventListener('scroll', function(e) { + if(-scroll.y < 0) { + num = 0; + } else if((-scroll.y > 0 || scroll.y == 0) && -scroll.y < 150) { + num = -scroll.y / 150; + } else { + num = 1; + } + $('.header').css('background-color', 'rgba(255,255,255,' + num + ')') + + if(-scroll.y < 75) { + $('.saoyisao').attr('src', '../img/saoyisao.png'); + $('.msg').attr('src', '../img/icon_msg.png'); + $('.search').attr('src', '../img/icon_search.png'); + $('#search').css('background-color', 'white'); + // $('#search').css('color', 'black'); + // $('#keyword').css('color', 'black'); + $('.header').removeClass('shadown_wai'); + } else { + $('.saoyisao').attr('src', '../img/saoyisao1.png'); + $('.msg').attr('src', '../img/icon_msg1.png'); + $('.search').attr('src', '../img/icon_search1.png'); + $('#search').css('background-color', '#d8d8d8'); + // $('#search').css('color', 'white'); + // $('#keyword').css('color', 'white'); + $('.header').addClass('shadown_wai'); + } + + if(scroll.y > 80 && issx == 0) { + issx = 1; + setTimeout(function() { + location.reload() + }, 1000) + } + + }) + //轮播图跳转 + $('#top_banner').on('tap', '.swiper-slide', function() { + openAds($(this)); + }) + //秒杀跳转 + $('#timer_swiper').on('tap', '.swiper-slide', function() { + // openAds($(this)); + }) + //广告 + $('.add').on('tap', '.add_', function() { + openAds($(this)); + }) + //品牌跳转 + $('#hot_banner').on('tap', '.hotimg', function() { + openAds($(this)); + }) + var num = 0; + + mui('.time').on('tap', '#timer_more', function() { + mui.openWindow({ + url: 'time.html', + id: 'time.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + mui('.classify').on('tap', '.class_block', function() { + var classifyId = $(this).attr('data-classifyId'); + var url = 'orSupermarket.html'; + + if(classifyId == 5) { + url = 'classify.html'; + } + + mui.openWindow({ + url: url, + id: url, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + classifyId: classifyId + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + //跳新闻 + mui('.con_nav').on('tap', '.news', function() { + mui.openWindow({ + url: 'journalism.html', + id: 'journalism.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + //跳消息 + mui('.header').on('tap', '.msg', function() { + mui.openWindow({ + url: 'msg.html', + id: 'msg.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + mui('.hot_shop').on('tap', '#hot_more', function() { + mui.openWindow({ + url: 'activity4.html', + id: 'activity4.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + }, + extras: { + // data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: {}, + waiting: {} + }) + }) + + //搜索 + $('#keyword').on('focus', function() { + $(".search button").css('display', 'block'); + }) + $('#keyword').on('blur', function() { + $(".search button").css('display', 'none'); + }) + $(".search button").on('tap', function() { + var searchName = $('#keyword').val(); + var url = ''; + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + // console.log($('.search select').val()) + if($('.search select').val() == 0) { + url = 'goodsList.html'; + } else if($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + }) + $("#keyword").on('keypress', function(e) { + var keycode = e.keyCode; + var searchName = $(this).val(); + var url = ''; + if(keycode == '13') { + // e.preventDefault(); + // console.log(searchName) + //请求搜索接口 + // console.log($('.search select').val()) + if($('.search select').val() == 0) { + url = 'goodsList.html'; + } else if($('.search select').val() == 1) { + url = 'shopsList.html'; + } + + mui.openWindow({ + url: url, + id: url + searchName, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_keyword: searchName + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: true, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + + } + }); + + mui("#hot_banner").on('tap', '.hot_con_block', function() { + // var tj = plus.webview.create('search.html'); + // tj.show(); + // alert(e.target.attributes["data-id"].nodeValue); + var data_id = this.attributes["data-goodsId"].nodeValue; + // console.log(this.attributes["data-id"].nodeValue); + mui.openWindow({ + url: 'details.html', + id: 'details.html' + data_id, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + +}) \ No newline at end of file diff --git a/static/app2/js/╕┤╓╞ indentcon.js b/static/app2/js/╕┤╓╞ indentcon.js new file mode 100755 index 0000000..b9aa589 --- /dev/null +++ b/static/app2/js/╕┤╓╞ indentcon.js @@ -0,0 +1,1006 @@ +$('#content').after('<div class="tui"></div>'); +$('.pay_info .row_left').eq(0).html('桔子链账号'); + +var pay_name = 0; +var wxChannel = null; // 微信支付 +var aliChannel = null; // 支付宝支付 +var channel = null; //支付通道 +mui.init({ + pullRefresh: { + container: '#pullrefresh', + down: { + style: 'circle', //必选,下拉刷新样式,目前支持原生5+ ‘circle’ 样式 + color: '#2BD009', //可选,默认“#2BD009” 下拉刷新控件颜色 + height: '50px', //可选,默认50px.下拉刷新控件的高度, + range: '100px', //可选 默认100px,控件可下拉拖拽的范围 + offset: '0px', //可选 默认0px,下拉刷新控件的起始位置 + // auto: true, //可选,默认false.首次加载自动上拉刷新一次 + contentdown: "下拉可以刷新", //可选,在下拉可刷新状态时,下拉刷新控件上显示的标题内容 + contentover: "释放立即刷新", //可选,在释放可刷新状态时,下拉刷新控件上显示的标题内容 + contentrefresh: "正在刷新...", //可选,正在刷新状态时,下拉刷新控件上显示的标题内容 + callback: pulldownRefresh //必选,刷新函数,根据具体业务来编写,比如通过ajax从服务器获取新数据; + }, + up: { + contentrefresh: '正在加载...', + callback: pullupRefresh + } + } +}); +var count = 1; + +function pullupRefresh() { + + setTimeout(function() { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(); + count += 1; + var order_class = localStorage.getItem('order_class'); + var token = localStorage.getItem('token'); + // console.log(order_class) + if(order_class == 'all') { + order_class = ''; + } + mui.ajax(hyhUrl('app/Orders/getOrderList'), {  + headers: {  + "HYH-Token": token + }, + data: { + type: order_class, + page: count, + pagesize : 5 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + + var data = toJson(data); + if(data.data.Rows.length == 0) { + mui('#pullrefresh').pullRefresh().endPullupToRefresh(true); + return; + } + + var html = '' + $.each(data.data.Rows, function() { + this.pay_name = 1; + html += '<div class="row shadown_wai" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + '"><div class="row_title"><div class="store_name">' + this.shopName + '</div><div class="indent_status">' + this.status + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>'; + }) + html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if(this.orderStatus == -2) { + html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if(this.orderStatus == 0) { + if(this.noticeDeliver == 0) { + html += '<div class="btns_btn txfh" style="display:none;">提醒发货</div><div class="btns_btn qxdd">取消订单</div>'; + } else { + html += '<div class="btns_btn " style="display:none;">已提醒</div><div class="btns_btn qxdd">取消订单</div>'; + } + + } else if(this.orderStatus == 1) { + html += '<div class="btns_btn qrsh">确认收货</div><div class="btns_btn ckwl">查看物流</div><div class="btns_btn qxdd_js" >拒收</div>'; + } else if(this.orderStatus == 2) { + if(this.isAppraise == 0) { + html += '<div class="btns_btn ljpj" >立即评价</div>'; + } else { + html += '<div class="btns_btn qxdd_js">查看评价</div>'; + } + + } + if(this.orderStatus != 1 && this.orderStatus != -2 && this.isComplain == 0) { + html += '<div class="btns_btn tsdd" >投诉</div>'; + } + if(this.allowRefund == 1 && (this.orderStatus == -1 || this.orderStatus == -3)) { + html += '<div class="btns_btn qxdd_js" >申请退款</div>'; + } + html += '</div></div>' + }) + $('.con').append(html); + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);     + } + });  + }, 500); +} + +/** + * 下拉刷新具体业务实现 + */ +function pulldownRefresh() { + setTimeout(function() { + window.location.reload(); + mui('#pullrefresh').pullRefresh().endPulldownToRefresh(); //refresh completed + }, 1500); +} +mui.plusReady(function() { + var token = localStorage.getItem('token'); + var order_class = localStorage.getItem('order_class'); + var orderNo; + var orderId; + var getReasonUrl = ''; + var priceT = 0; + var payCode = ''; + window.addEventListener('refresh', function(e) { //执行刷新 + location.reload(); + }); + //支付插件 + plus.payment.getChannels(function(channels) { + for(var i in channels) { + if(channels[i].id == "wxpay") { + wxChannel = channels[i]; + } else { + aliChannel = channels[i]; + } + } + }, function(e) { + alert("获取支付通道失败:" + e.message); + }); + // var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total='; + var ALIPAYSERVER = hyhUrl('app/Alipays/toAlipay?isBatch=0&orderNo='); + // 2. 发起支付请求 + function pay(id, orderNo) { + // 从服务器请求支付订单 + var PAYSERVER = ''; + if(id == 'alipay') { + PAYSERVER = ALIPAYSERVER; + channel = aliChannel; + } else if(id == 'wxpay') { + PAYSERVER = WXPAYSERVER; + channel = wxChannel; + } else { + plus.nativeUI.alert("不支持此支付通道!", null, "捐赠"); + return; + } + var xhr = new XMLHttpRequest(); + // var amount = 1; + + xhr.onreadystatechange = function() { + switch(xhr.readyState) { + case 4: + if(xhr.status == 200) { + plus.payment.request(channel, xhr.responseText, function(result) { + plus.nativeUI.alert("支付成功!", function() { + // back(); + var targetTab = plus.webview.getWebviewById("templete/my.html"); + mui.fire(targetTab, 'refresh'); + location.reload(); + }); + }, function(error) { + // plus.nativeUI.alert("支付失败:" + error.code); + // plus.webview.getWebviewById('confirmOrder.html').close() + }); + } else { + alert("获取订单信息失败!"); + console.log(xhr.status) + } + break; + default: + break; + } + } + xhr.open('GET', PAYSERVER + orderNo); + xhr.send(); + + } + mui.ajax(hyhUrl('/app/Users/get_name_and_money'), {  + headers: {  + "HYH-Token": token + }, + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + + if(data.status == 1) { + $('#loginName').html(data.data.name); + $('.userMoney').html(data.data.money); + var htmlpay = '<div class="row clearfix" data-payCode="ect"><p class="row_left">ECT余额:<o class="userECT">' + data.data.userECT + '</o></p></div>'; + $('#pay_way .con_1').append(htmlpay); + } else { + alert('发生错误请刷新后重试!'); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + }) + + $('.pay').on('tap', '.select_payway', function() { + //if($(this).attr('data-payCode') == 'ect') {} else { + $('.pay').css('display', 'none'); + $('#pay_way').css('display', 'block'); + //} + + }) + + $('.con').on('tap', '.ljfk', function() { + var that = $(this); + + priceT = $(this).parent().siblings('.combination').children('o').html().slice(1); + $('#goodsTotalMoney').html($(this).parent().siblings('.combination').children('o').html()) + orderNo = $(this).parent().parent().attr('data-orderNo'); + // $('.pay_info .con_1 .row').eq(1).addClass('on'); + // $('.pay_info .con_1 .row').eq(2).attr('style', 'display: none;'); + $('.bg').css('display', 'block'); + $(".pay").slideDown(300); + + }) + + $('.bg').on('tap', '.mui-icon-left-nav', function() { + $('.pay').css('display', 'block'); + $('.pay_way').css('display', 'none'); + }) + $('.bg').on('tap', '.mui-icon-closeempty', function() { + $('.bg').css('display', 'none'); + $(".pay").slideUp(300, function() { + + }); + }) + + $('#pay_way').on('tap', '.row', function() { + $('#pay_way .row .mui-icon').removeClass('mui-icon-checkmarkempty'); + $(this).children('.mui-icon').addClass('mui-icon-checkmarkempty'); + $('.select_payway .row_right o').html($(this).children('.row_left').html()); + $('.select_payway').attr('data-payCode', $(this).attr('data-payCode')) + $('.pay').css('display', 'block'); + $('#pay_way').css('display', 'none'); + }) + $('.pay_btn').on('tap', function() { + payCode = $('.select_payway').attr('data-payCode'); + var that = $(this); + var data_ljfk = { + isBatch: 0, + orderNo: orderNo + } + that.attr('disabled', 'disabled'); + console.log(payCode) + if(payCode == 'ect') { + mui.ajax(hyhUrl('app/ect/getToEctNum'), {  + + data: { + 'total_money': priceT, + 'wait_pay': 1 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒; + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;  + var data = toJson(data); + if(data.status == 1) { + var btnArray = ['是', '否']; + mui.confirm(data.msg, 'ECT确认支付', btnArray, function(e) { + if(e.index == 1) { + that.removeAttr('disabled'); + return; + } else { + mui.ajax(hyhUrl('app/orders/succeed'), {  + data: data_ljfk, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + + if(data.status == 1) { + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: orderNo, + isBatch: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', orderNo); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + }) + } + that.removeAttr('disabled'); + }) + } else { + alert(data.msg); + that.removeAttr('disabled'); + return; + } + + } + }) + } else { + mui.ajax(hyhUrl('app/orders/succeed'), {  + data: data_ljfk, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data) + data = toJson(data); + + if(data.status == 1) { + if(payCode == 'wallets' || payCode == 'ect') { + //跳输入密码的页面 + + mui.ajax(hyhUrl('app/' + payCode + '/payment'), {  + + data: { + orderNo: orderNo, + isBatch: 0 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + if(data.status == 1) { + $('.pay').css('display', 'none'); + $('#pay_pwd').css('display', 'block'); + if(data.data.payPwd == '0') { + alert('还未设置支付密码请先设置支付密码!'); + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + } + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + } else if(payCode == 'alipays') { + pay('alipay', orderNo); + // plus.nativeUI.showWaiting(); + // mui.post(hyhUrl('app/Alipays/payment'), { + // orderNo: data.data, + // isBatch: 1 + // var ALIPAYSERVER = hyhUrl('app/Alipays/payment?orderNo=' + data.data + '&isBatch=1'); + + } + + that.removeAttr('disabled'); + } else { + alert(data.msg); + // location.reload(); + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + }) + } + + }) + $('#pay_pwd').on('tap', '.p9', function() { + var url = 'setting_fogetPayPwd'; + mui.openWindow({ + url: url + '.html', + id: url + '.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + // data_href: data_href + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + $('#pay_pwd').on('tap', '.pay_btn_pwd', function() { + + var payPwd = $('#payPwd').val(); + if(payPwd == '') { + alert('支付密码不能为空!'); + } + var that = $(this); + that.attr('disabled', 'disabled') + var srcc = '' + if(payCode == 'ect') { + srcc = 'payByEct'; + } else { + srcc = 'payByWallet'; + } + + mui.ajax(hyhUrl('app/' + payCode + '/' + srcc), {  + + data: { + orderNo: orderNo, + isBatch: 0, + payPwd: payPwd + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + var data = toJson(data); + alert(data.msg) + if(data.status == 1) { + var targetTab = plus.webview.getWebviewById("templete/my.html"); + mui.fire(targetTab, 'refresh'); + location.reload(); + } else { + + } + that.removeAttr('disabled') + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + } + });  + + }) + + // console.log(order_class) + if(order_class == 'all') { + order_class = ''; + } + mui.ajax(hyhUrl('app/Orders/getOrderList'), {  + headers: {  + "HYH-Token": token + }, + data: { + type: order_class, + page: 1, + pagesize : 5 + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + var html = '' + $.each(data.data.Rows, function() { + // this.pay_name = 1; + html += '<div class="row shadown_wai" data-orderNo="' + this.orderNo + '" data-id="' + this.orderId + '"><div class="row_title"><div class="store_name">' + this.shopName + '</div><div class="indent_status">' + this.status + '</div></div><div class="row_con clearfix" data-id="' + this.orderId + '">' + $.each(this.list, function() { + html += '<div class="row_block clearfix"><img src="' + hyhImgUrl(this.goodsImg) + '" /><div class="rcr clearfix"><div class="rcrc"><p>' + this.goodsName + ' </p><p class="leibie">' + this.goodsSpecNames + '</p></div><div class="rcrr"><p>¥' + this.goodsPrice + '</p><del>¥' + this.marketPrice + '</del><span>x' + this.goodsNum + '</span></div></div></div>'; + }) + html += '</div><div class="combination">共' + this.list.length + '件商品 合计:<o>¥' + this.realTotalMoney + '</o>(含运费¥' + this.deliverMoney + ')</div><div class="btns clearfix">'; + if(this.orderStatus == -2) { + html += '<div class="btns_btn ljfk" data-payName="' + this.pay_name + '">立即付款</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else if(this.orderStatus == 0) { + if(this.noticeDeliver == 0) { + html += '<div class="btns_btn txfh" style="display:none;">提醒发货</div><div class="btns_btn qxdd_js">取消订单</div>'; + } else { + html += '<div class="btns_btn " style="display:none;">已提醒</div><div class="btns_btn qxdd_js">取消订单</div>'; + } + + } else if(this.orderStatus == 1) { + html += '<div class="btns_btn qrsh">确认收货</div><div class="btns_btn ckwl">查看物流</div><div class="btns_btn qxdd_js" >拒收</div>'; + } else if(this.orderStatus == 2) { + if(this.isAppraise == 0) { + html += '<div class="btns_btn ljpj" >立即评价</div>'; + } else { + html += '<div class="btns_btn ckpj">查看评价</div>'; + } + + } + if(this.orderStatus != 1 && this.orderStatus != -2 && this.isComplain == 0) { + html += '<div class="btns_btn tsdd" >投诉</div>'; + } + if(this.allowRefund == 1 && (this.orderStatus == -1 || this.orderStatus == -3)) { + html += '<div class="btns_btn qxdd_js" >申请退款</div>'; + } + + html += '</div></div>' + }) + + $('.con').append(html); + + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + + mui('.con').on('tap', '.row_con', function() { + var data_order_id = $(this).attr('data-id'); + mui.openWindow({ + url: 'order_out.html', + id: 'order_out.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + mui('.con').on('tap', '.ckwl', function() { + var data_order_id = $(this).parent().parent().attr('data-id'); //$(this).attr('data-id'); + mui.openWindow({ + url: 'logistics.html', + id: 'logistics.html', + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: data_order_id + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + + $('.con').on('tap', '.qxdd_js', function() { + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if($(this).html() == '取消订单') { + getReasonUrl = 'getCancelCause'; + } else if($(this).html() == '拒收') { + getReasonUrl = 'getRejectCause'; + } else if($(this).html() == '申请退款') { + getReasonUrl = 'getRefundCause'; + mui.ajax(hyhUrl('/app/Orders/getRefund'), {  + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + data = data.data; + var html = '<input type="text" name="Tmoney" id="Tmoney" value="" placeholder="请输入退款金额"/><p class="info1">(金额不能超过<o>¥' + data.realTotalMoney + '</o>)</p><p class="info1">(' + data.useScore + '个惠宝抵扣<o>¥' + data.scoreMoney + '</o>)</p>'; + $('.tui').html(html) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + $('.bg_').css('display', 'block'); + $('.bg_con').css('display', 'none'); + $('.bg_con').slideDown(300, function() {}); + + mui.ajax(hyhUrl('/app/Orders/' + getReasonUrl), {  + data: {}, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + var html = '<option value="0">未选择</option>'; + $.each(data.data, function() { + html += '<option value="' + this.dataVal + '">' + this.dataName + '</option>' + }); + $('#select').html(html) + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + }) + + $('.bg_').on('tap', '.en_false', function() { + $('.bg_').css('display', 'none'); + + }) + $('.bg_').on('tap', '.en_true', function() { + var setReasonUrl = ''; + var content = $('#content').val(); + var reason = $('#select').val(); + if($('#select').val() == 0) { + alert('请选择原因!'); + return; + } + if($('#select').val() == 10000 && content == '') { + alert('请输入其他原因!'); + return; + } + if(getReasonUrl == 'getCancelCause') { + setReasonUrl = 'cancellation'; + mui.ajax(hyhUrl('app/Orders/' + setReasonUrl), {  + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } else if(getReasonUrl == 'getRejectCause') { + setReasonUrl = 'reject'; + mui.ajax(hyhUrl('app/Orders/' + setReasonUrl), {  + data: { + reason: reason, + id: orderId, + content: content + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } else if(getReasonUrl == 'getRefundCause') { + var money = $('#Tmoney').val(); + if(money < 0 || money == 0) { + alert('退款金额不能为0!'); + return; + } else { + mui.ajax(hyhUrl('app/Orderrefunds/refund'), {  + data: { + reason: reason, + id: orderId, + content: content, + money: money + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + alert(data.msg); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload(); + + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + + } + + }) + $('.con').on('tap', '.qrsh', function() { + // $('.bg_').css('display', 'block'); + orderNo = $(this).parent().parent().attr('data-orderNo'); + orderId = $(this).parent().parent().attr('data-id'); + if(confirm('确认收货?')) { + mui.ajax(hyhUrl('/app/Orders/receive'), {  + headers: {  + "HYH-Token": token + }, + data: { + id: orderId + }, + dataType: 'json', //服务器返回json格式数据   + type: 'post', //HTTP请求类型   + timeout: 10000, //超时时间设置为10秒;   + success: function(data) {           //服务器返回响应,根据响应结果,分析是否登录成功;   + // console.log(data.data.goodsFavoritesNum) + // console.log(data.data.Rows) + var data = toJson(data); + if(data.status == 1) { + var list = plus.webview.currentWebview().opener();     //触发父页面的自定义事件(refresh),从而进行刷新 + mui.fire(list, 'refresh'); + location.reload() + } + }, + error: function(xhr, type, errorThrown) {           //异常处理;   + // alert(type);       + }   + });  + } + + }) + $('#select').on('change', function() { + if($(this).val() == '10000') { + $('#content').css('display', 'block'); + } else { + $('#content').css('display', 'none'); + } + }) + //跳转到评价 + mui('.con').on('tap', '.ljpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.ckpj', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'pj.html', + id: 'pj.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + //跳转到评价 + mui('.con').on('tap', '.tsdd', function() { + var oId = $(this).parent().parent().attr('data-id'); + mui.openWindow({ + url: 'complain.html', + id: 'complain.html' + oId, + styles: { + top: '0px', //新页面顶部位置 + bottom: '0px', //新页面底部位置 + width: '100%', //新页面宽度,默认为100% + height: '100%' //新页面高度,默认为100% + }, + extras: { + data_order_id: oId + // data_id: data_id + // ..... //自定义扩展参数,可以用来处理页面间传值 + }, + createNew: false, //是否重复创建同样id的webview,默认为false:不重复创建,直接显示 + show: { + // autoShow: true, //页面loaded事件发生后自动显示,默认为true + // aniShow: animationType, //页面显示动画,默认为”slide-in-right“; + // duration: animationTime, //页面动画持续时间,Android平台默认100毫秒,iOS平台默认200毫秒; + // event: 'titleUpdate', //页面显示时机,默认为titleUpdate事件时显示 + // extras: {} //窗口动画是否使用图片加速 + }, + waiting: { + autoShow: true, //自动显示等待框,默认为true + title: '正在加载...', //等待对话框上显示的提示内容 + options: { + // width: waiting - dialog - widht, //等待框背景区域宽度,默认根据内容自动计算合适宽度 + // height: waiting - dialog - height, //等待框背景区域高度,默认根据内容自动计算合适高度 + // ...... + } + } + }) + }) + +}) \ No newline at end of file diff --git a/static/images/loading.gif b/static/images/loading.gif new file mode 100755 index 0000000..9a8f813 Binary files /dev/null and b/static/images/loading.gif differ diff --git a/static/images/loading_16x16.gif b/static/images/loading_16x16.gif new file mode 100755 index 0000000..e8c2892 Binary files /dev/null and b/static/images/loading_16x16.gif differ diff --git a/static/images/wst_icon.png b/static/images/wst_icon.png new file mode 100755 index 0000000..bb19626 Binary files /dev/null and b/static/images/wst_icon.png differ diff --git a/static/js/common.js b/static/js/common.js new file mode 100755 index 0000000..b2a2597 --- /dev/null +++ b/static/js/common.js @@ -0,0 +1,524 @@ +var WST = WST || {}; +WST.v = 'a2.0.2'; +WST.checkBrowser = function(){ + return { + mozilla : /firefox/.test(navigator.userAgent.toLowerCase()), + webkit : /webkit/.test(navigator.userAgent.toLowerCase()), + opera : /opera/.test(navigator.userAgent.toLowerCase()), + msie : /msie/.test(navigator.userAgent.toLowerCase()) + } +} +WST.pageHeight = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientHeight : + document.body.clientHeight; + }else{ + return self.innerHeight; + } +}; +//返回当前页面宽度 +WST.pageWidth = function(){ + if(WST.checkBrowser().msie){ + return document.compatMode == "CSS1Compat"? document.documentElement.clientWidth : + document.body.clientWidth; + }else{ + return self.innerWidth; + } +}; +WST.TreeSelector = function(item,data,rootId,defaultValue){ + this._data = data; + this._item = item; + this._rootId = rootId; + if(defaultValue)this.defaultValue = defaultValue; +} +WST.TreeSelector.prototype.createTree = function(){ + var len =this._data.length; + for( var i= 0;i<len;i++){ + if ( this._data[i].pid == this._rootId){ + + this._item.options.add(new Option(" "+this._data[i].text,this._data[i].id)); + for(var j=0;j<len;j++){ + this.createSubOption(len,this._data[i],this._data[j]); + } + } + } + if(this.defaultValue)this._item.value = this.defaultValue; +} + +WST.TreeSelector.prototype.createSubOption = function(len,current,next){ + var blank = ".."; + if ( next.pid == current.id){ + intLevel =0; + var intlvl =this.getLevel(this._data,this._rootId,current); + for(a=0;a<intlvl;a++) + blank += ".."; + blank += "├-"; + this._item.options.add(new Option(blank + next.text,next.id)); + for(var j=0;j<len;j++){ + this.createSubOption(len,next,this._data[j]); + } + } + } + WST.TreeSelector.prototype.getLevel = function(datasources,topId,currentitem){ + + var pid =currentitem.pid; + if( pid !=topId) + { + for(var i =0 ;i<datasources.length;i++) + { + if( datasources[i].id == pid) + { + intLevel ++; + this.getLevel(datasources,topId,datasources[i]); + } + } + } + return intLevel; +} +//多选下拉框移动元素 +WST.multSelect = function(opts){ + var e1 = document.getElementById(opts.left); + var e2 = document.getElementById(opts.right); + for(var i=0;i<e1.options.length;i++){ + if(e1.options[i].selected){ + var e = e1.options[i]; + e2.options.add(new Option(e.text, e.value)); + e1.remove(i); + i=i-1 + } + } + document.getElementById(opts.val).value=getValue(document.getElementById(opts.vtarget)); + + function getValue(geto){ + var ids = []; + for(var i=0;i<geto.options.length;i++){ + ids.push(geto.options[i].value); + } + return ids.join(','); + } +} +// 只能輸入數字,且第一數字不能為0 +WST.digitalOnly = function(obj) { + // 先把非数字的都替换掉 + obj.value=obj.value.replace(/\D/g, ""); +} +/** + * 获取版本 + */ +WST.getWSTMARTVersion = function(url){ + $.post(url,{},function(data,textStatus){ + var json = {}; + try{ + if(typeof(data )=="object"){ + json = data; + }else{ + json = eval("("+data+")"); + } + }catch(e){} + if(json){ + if(json.version && json.version!='same'){ + $('.wstmart-version-tips').show(); + $('#wstmart_version').html(json.version); + $('#wstmart_down').attr('href',json.downloadUrl); + } + if(json.accredit=='no'){ + $('.wstmart-accredit-tips').show(); + } + if(json.licenseStatus)$('#licenseStatus').html(json.licenseStatus); + } + }); +} + /******************** + * 取窗口滚动条高度 + ******************/ + WST.getScrollTop = function() + { + var scrollTop=0; + if(document.documentElement&&document.documentElement.scrollTop) + { + scrollTop=document.documentElement.scrollTop; + } + else if(document.body) + { + scrollTop=document.body.scrollTop; + } + return scrollTop; + } + + /******************** + * 取文档内容实际高度 + *******************/ + WST.getScrollHeight = function() + { + return Math.max(document.body.scrollHeight,document.documentElement.scrollHeight); + } + + //只能輸入數字 + WST.isNumberKey = function(evt){ + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && (charCode < 48 || charCode > 57)){ + return false; + }else{ + return true; + } + } + + //只能輸入數字和小數點 + WST.isNumberdoteKey = function(evt){ + var e = evt || window.event; + var srcElement = e.srcElement || e.target; + + var charCode = (evt.which) ? evt.which : event.keyCode; + if (charCode > 31 && ((charCode < 48 || charCode > 57) && charCode!=46)){ + return false; + }else{ + if(charCode==46){ + var s = srcElement.value; + if(s.length==0 || s.indexOf(".")!=-1){ + return false; + } + } + return true; + } + } + + //只能輸入數字和字母 + WST.isNumberCharKey = function(evt){ + var e = evt || window.event; + var srcElement = e.srcElement || e.target; + var charCode = (evt.which) ? evt.which : event.keyCode; + + if((charCode>=48 && charCode<=57) || (charCode>=65 && charCode<=90) || (charCode>=97 && charCode<=122) || charCode==8){ + return true; + }else{ + return false; + } + } + +WST.isChinese = function(obj,isReplace){ + var pattern = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/i + if(pattern.test(obj.value)){ + if(isReplace)obj.value=obj.value.replace(/[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/ig,""); + return true; + } + return false; + } + +Number.prototype.toFixed = function(exponent){ + return parseInt(this * Math.pow(10, exponent)+0.5 )/Math.pow(10,exponent); +} + +//用户名判断 (可输入"_",".","@", 数字,字母) + WST.isUserName = function(evt){ + var evt = evt || window.event; + var charCode = (evt.which) ? evt.which : evt.keyCode; + if((charCode==95 || charCode==46 || charCode==64) || (charCode>=48 && charCode<=57) || (charCode>=65 && charCode<=90) || (charCode>=97 && charCode<=122) || charCode==8){ + return true; + }else{ + return false; + } + } + +WST.isEmail =function(v){ + var tel = new RegExp("^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$"); + return(tel.test(v)); +} +//判断是否电话 +WST.isTel = function(v){ + var tel = new RegExp("^[[0-9]{3}-|\[0-9]{4}-]?(\[0-9]{8}|[0-9]{7})?$"); + return(tel.test(v)); +} +WST.isPhone = function(v){ + var tel = new RegExp("^[1][0-9]{10}$"); + return(tel.test(v)); +} +//判断url +WST.isUrl = function(str){ + if(str==null||str=="") return false; + var result=str.match(/^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\’:+!]*([^<>\"])*$/); + if(result==null)return false; + return true; +} +//比较时间差 +WST.getTimeDiff = function(startTime,endTime,diffType){ + //将xxxx-xx-xx的时间格式,转换为 xxxx/xx/xx的格式 + startTime = startTime.replace(/-/g, "/"); + endTime = endTime.replace(/-/g, "/"); + //将计算间隔类性字符转换为小写 + diffType = diffType.toLowerCase(); + var sTime = new Date(startTime); //开始时间 + var eTime = new Date(endTime); //结束时间 + //作为除数的数字 + var divNum = 1; + switch (diffType) { + case "second": + divNum = 1000; + break; + case "minute": + divNum = 1000 * 60; + break; + case "hour": + divNum = 1000 * 3600; + break; + case "day": + divNum = 1000 * 3600 * 24; + break; + default: + break; + } + return parseInt((eTime.getTime() - sTime.getTime()) / parseInt(divNum)); +} +/** + * 截取字符串 + */ +WST.cutStr = function (str,len) +{ + if(!str || str=='')return ''; + var strlen = 0; + var s = ""; + for(var i = 0;i < str.length;i++) + { + if(strlen >= len){ + return s + "..."; + } + if(str.charCodeAt(i) > 128) + strlen += 2; + else + strlen++; + s += str.charAt(i); + } + return s; +} +WST.checkChks = function(obj,cobj){ + $(cobj).each(function(){ + $(this)[0].checked = obj.checked; + }) +} +WST.getChks = function(obj){ + var ids = []; + $(obj).each(function(){ + if($(this)[0].checked)ids.push($(this).val()); + }); + return ids; +} +WST.showHide = function(t,str){ + var s = str.split(','); + if(t){ + for(var i=0;i<s.length;i++){ + $(s[i]).show(); + } + }else{ + for(var i=0;i<s.length;i++){ + $(s[i]).hide(); + } + } + s = null; +} +WST.blank = function(str,defaultVal){ + if(str=='0000-00-00')str = ''; + if(str=='0000-00-00 00:00:00')str = ''; + if(!str)str = ''; + if(typeof(str)=='null')str = ''; + if(typeof(str)=='undefined')str = ''; + if(str=='' && defaultVal)str = defaultVal; + return str; +} +WST.limitDecimal = function(obj,len){ + var s = obj.value; + if(s.indexOf(".")>-1){ + if((s.length - s.indexOf(".")-1)>len){ + obj.value = s.substring(0,s.indexOf(".")+len+1); + } + } + s = null; +} +WST.getParams = function(obj){ + var params = {}; + var chk = {},s; + $(obj).each(function(){ + if($(this)[0].type=='hidden' || $(this)[0].type=='number' || $(this)[0].type=='tel' || $(this)[0].type=='password' || $(this)[0].type=='select-one' || $(this)[0].type=='textarea' || $(this)[0].type=='text'){ + params[$(this).attr('id')] = $.trim($(this).val()); + }else if($(this)[0].type=='radio'){ + if($(this).attr('name')){ + params[$(this).attr('name')] = $('input[name='+$(this).attr('name')+']:checked').val(); + } + }else if($(this)[0].type=='checkbox'){ + if($(this).attr('name') && !chk[$(this).attr('name')]){ + s = []; + chk[$(this).attr('name')] = 1; + $('input[name='+$(this).attr('name')+']:checked').each(function(){ + s.push($(this).val()); + }); + params[$(this).attr('name')] = s.join(','); + } + } + }); + chk=null,s=null; + return params; +} +WST.setValue = function(name, value){ + var first = name.substr(0,1), input, i = 0, val; + if("#" === first || "." === first){ + input = $(name); + } else { + input = $("[name='" + name + "']"); + } + + if(input.eq(0).is(":radio")) { //单选按钮 + input.filter("[value='" + value + "']").each(function(){this.checked = true}); + } else if(input.eq(0).is(":checkbox")) { //复选框 + if(!$.isArray(value)){ + val = new Array(); + val[0] = value; + } else { + val = value; + } + for(i = 0, len = val.length; i < len; i++){ + input.filter("[value='" + val[i] + "']").each(function(){this.checked = true}); + } + } else { //其他表单选项直接设置值 + input.val(value); + } +} +WST.setValues = function(obj){ + var input,value,val; + for(var key in obj){ + if($('#'+key)[0]){ + WST.setValue('#'+key,obj[key]); + }else if($("[name='" + key + "']")[0]){ + WST.setValue(key,obj[key]); + } + } +} + +$(function(){ + /** + * 获取WSTMart基础配置 + * @type {object} + */ + WST.conf = window.conf; + /* 基础对象检测 */ + WST.conf || $.error("WSTMart基础配置没有正确加载!"); + if(WST.conf.ROUTES)WST.conf.ROUTES = eval("("+WST.conf.ROUTES+")"); + /** + * 解析URL + * @param {string} url 被解析的URL + * @return {object} 解析后的数据 + */ + WST.parse_url = function(url){ + var parse = url.match(/^(?:([a-z]+):\/\/)?([\w-]+(?:\.[\w-]+)+)?(?::(\d+))?([\w-\/]+)?(?:\?((?:\w+=[^#&=\/]*)?(?:&\w+=[^#&=\/]*)*))?(?:#([\w-]+))?$/i); + parse || $.error("url格式不正确!"); + return { + "scheme" : parse[1], + "host" : parse[2], + "port" : parse[3], + "path" : parse[4], + "query" : parse[5], + "fragment" : parse[6] + }; + } + + WST.parse_str = function(str){ + var value = str.split("&"), vars = {}, param; + for(var i=0;i<value.length;i++){ + param = value[i].split("="); + vars[param[0]] = param[1]; + } + return vars; + } + WST.initU = function(url,vars){ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + var newUrl = WST.conf.ROUTES[url]; + var urlparams = newUrl.match(/<(\w+(\??))>/g); + var tmpv = null; + for(var v in vars){ + tmpv = '<'+v+'>'; + if($.inArray(tmpv,urlparams)>-1){ + newUrl = newUrl.replace(tmpv,vars[v]); + delete vars[v]; + } + } + tmpv = urlparams = null; + if(false !== WST.conf.SUFFIX){ + newUrl += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')newUrl += "?"+tmp; + tmp = null; + } + //url = url.replace(new RegExp("%2F","gm"),"+"); + newUrl = WST.conf.APP + "/"+newUrl; + return newUrl; + } + + WST.U0 = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url), path = [], reg; + /* 验证info */ + info.path || $.error("url格式错误!"); + url = info.path; + /* 解析URL */ + path = url.split("/"); + path = [path.pop(), path.pop(), path.pop()].reverse(); + path[1] || $.error("WST.U(" + url + ")没有指定控制器"); + + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + /* 解析URL自带的参数 */ + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')url += "?"+tmp; + tmp = null; + } + //url = url.replace(new RegExp("%2F","gm"),"+"); + url = WST.conf.APP + "/"+url; + return url; + } + WST.U = function(url,vars){ + if(WST.conf.ROUTES && WST.conf.ROUTES[url]){ + return WST.initU(url,vars); + }else{ + return WST.U0(url, vars); + } + } + + WST.AU = function(url, vars){ + if(!url || url=='')return ''; + var info = this.parse_url(url); + url = info.path; + path = url.split("/"); + url = "addon/"; + path = [path.pop(), path.pop()].reverse(); + path[0] || $.error("WST.AU(" + url + ")没有指定控制器"); + path[1] || $.error("WST.AU(" + url + ")没有指定接口"); + url = url + info.scheme + "-" + path.join('-'); + /* 解析参数 */ + if(typeof vars === "string"){ + vars = this.parse_str(vars); + } + info.query && $.extend(vars, this.parse_str(info.query)); + if(false !== WST.conf.SUFFIX){ + url += "." + WST.conf.SUFFIX; + } + if($.isPlainObject(vars)){ + var tmp = $.param(vars); + if(tmp!='')url += "?"+tmp; + tmp = null; + } + return WST.conf.APP + "/"+url; + } +}); + +WST.replaceImg = function(v,str){ + var vs = v.split('.'); + return v.replace("."+vs[1],str+"."+vs[1]); +} \ No newline at end of file diff --git a/static/js/jquery.min.js b/static/js/jquery.min.js new file mode 100755 index 0000000..5a880ea --- /dev/null +++ b/static/js/jquery.min.js @@ -0,0 +1,8 @@ +/*! jQuery v1.11.300119f3fc12403a05a1ef5609ff96e66 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){ +return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m}); +//jQuery cookie +jQuery.cookie=function(name,value,options){if(typeof value!=="undefined"){options=options||{};if(value===null){value="";options.expires=-1}var expires="";if(options.expires&&(typeof options.expires==="number"||options.expires.toUTCString)){var date;if(typeof options.expires==="number"){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000))}else{date=options.expires}expires="; expires="+date.toUTCString()}var path=options.path?"; path="+options.path:"";var domain=options.domain?"; domain="+options.domain:"";var secure=options.secure?"; secure":"";document.cookie=[name,"=",encodeURIComponent(value),expires,path,domain,secure].join("")}else{var cookieValue=null;if(document.cookie&&document.cookie!=""){var cookies=document.cookie.split(";");for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+"=")){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break}}}return cookieValue}}; + diff --git a/static/js/jquery.min.map b/static/js/jquery.min.map new file mode 100755 index 0000000..4dc4920 --- /dev/null +++ b/static/js/jquery.min.map @@ -0,0 +1 @@ +{"version":3,"file":"jquery-1.10.2.min.js","sources":["jquery-1.10.2.js"],"names":["window","undefined","readyList","rootjQuery","core_strundefined","location","document","docElem","documentElement","_jQuery","jQuery","_$","$","class2type","core_deletedIds","core_version","core_concat","concat","core_push","push","core_slice","slice","core_indexOf","indexOf","core_toString","toString","core_hasOwn","hasOwnProperty","core_trim","trim","selector","context","fn","init","core_pnum","source","core_rnotwhite","rtrim","rquickExpr","rsingleTag","rvalidchars","rvalidbraces","rvalidescape","rvalidtokens","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","completed","event","addEventListener","type","readyState","detach","ready","removeEventListener","detachEvent","prototype","jquery","constructor","match","elem","this","charAt","length","exec","find","merge","parseHTML","nodeType","ownerDocument","test","isPlainObject","isFunction","attr","getElementById","parentNode","id","makeArray","toArray","call","get","num","pushStack","elems","ret","prevObject","each","callback","args","promise","done","apply","arguments","first","eq","last","i","len","j","map","end","sort","splice","extend","src","copyIsArray","copy","name","options","clone","target","deep","isArray","expando","Math","random","replace","noConflict","isReady","readyWait","holdReady","hold","wait","body","setTimeout","resolveWith","trigger","off","obj","Array","isWindow","isNumeric","isNaN","parseFloat","isFinite","String","key","e","support","ownLast","isEmptyObject","error","msg","Error","data","keepScripts","parsed","scripts","createElement","buildFragment","remove","childNodes","parseJSON","JSON","parse","Function","parseXML","xml","tmp","DOMParser","parseFromString","ActiveXObject","async","loadXML","getElementsByTagName","noop","globalEval","execScript","camelCase","string","nodeName","toLowerCase","value","isArraylike","text","arr","results","Object","inArray","max","second","l","grep","inv","retVal","arg","guid","proxy","access","chainable","emptyGet","raw","bulk","now","Date","getTime","swap","old","style","Deferred","attachEvent","top","frameElement","doScroll","doScrollCheck","split","cachedruns","Expr","getText","isXML","compile","outermostContext","sortInput","setDocument","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","hasDuplicate","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","RegExp","rcomma","rcombinators","rsibling","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rnative","rinputs","rheader","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","fromCharCode","els","Sizzle","seed","m","groups","nid","newContext","newSelector","getElementsByClassName","qsa","tokenize","getAttribute","setAttribute","toSelector","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","removeChild","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","node","doc","parent","defaultView","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","dirkey","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","matcherCachedRuns","bySet","byElement","superMatcher","expandContext","setMatched","matchedCount","outermost","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","optionsCache","createOptions","object","flag","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","list","stack","once","fire","stopOnFalse","self","disable","add","index","lock","locked","fireWith","func","tuples","state","always","deferred","fail","then","fns","newDefer","tuple","action","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","progressContexts","resolveContexts","fragment","opt","eventName","isSupported","cssText","getSetAttribute","leadingWhitespace","tbody","htmlSerialize","hrefNormalized","opacity","cssFloat","checkOn","optSelected","enctype","html5Clone","cloneNode","outerHTML","inlineBlockNeedsLayout","shrinkWrapBlocks","pixelPosition","deleteExpando","noCloneEvent","reliableMarginRight","boxSizingReliable","noCloneChecked","optDisabled","radioValue","createDocumentFragment","appendChecked","checkClone","click","change","focusin","backgroundClip","clearCloneStyle","container","marginDiv","tds","divReset","offsetHeight","display","reliableHiddenOffsets","zoom","boxSizing","offsetWidth","getComputedStyle","width","marginRight","rbrace","rmultiDash","internalData","pvt","acceptData","thisCache","internalKey","isNode","toJSON","internalRemoveData","isEmptyDataObject","cleanData","noData","applet","embed","hasData","removeData","_data","_removeData","dataAttr","queue","dequeue","startLength","hooks","_queueHooks","next","stop","setter","delay","time","fx","speeds","timeout","clearTimeout","clearQueue","count","defer","nodeHook","boolHook","rclass","rreturn","rfocusable","rclickable","ruseDefault","getSetInput","removeAttr","prop","removeProp","propFix","addClass","classes","clazz","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","valHooks","set","option","one","optionSet","nType","attrHooks","propName","attrNames","for","class","notxml","propHooks","tabindex","parseInt","getter","setAttributeNode","createAttribute","coords","contenteditable","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","global","types","events","t","handleObjIn","special","eventHandle","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","props","srcElement","metaKey","original","which","charCode","keyCode","eventDoc","fromElement","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","relatedTarget","toElement","load","blur","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","cancelBubble","stopImmediatePropagation","mouseenter","mouseleave","orig","related","submitBubbles","form","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","on","origFn","triggerHandler","isSimple","rparentsprev","rneedsContext","guaranteedUnique","children","contents","prev","targets","winnow","is","closest","pos","prevAll","addBack","sibling","parents","parentsUntil","until","nextAll","nextUntil","prevUntil","siblings","contentDocument","contentWindow","reverse","n","r","qualifier","createSafeFragment","nodeNames","safeFrag","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","manipulation_rcheckableType","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","legend","area","param","thead","tr","col","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","th","append","createTextNode","domManip","manipulationTarget","prepend","insertBefore","before","after","keepData","getAll","setGlobalEval","dataAndEvents","deepDataAndEvents","html","replaceWith","allowIntersection","hasScripts","iNoClone","disableScript","restoreScript","_evalUrl","content","refElements","cloneCopyEvent","dest","oldData","curData","fixCloneNodeIssues","defaultChecked","defaultSelected","appendTo","prependTo","insertAfter","replaceAll","insert","found","fixDefaultChecked","destElements","srcElements","inPage","selection","wrap","safe","nodes","url","ajax","dataType","throws","wrapAll","wrapInner","unwrap","iframe","getStyles","curCSS","ralpha","ropacity","rposition","rdisplayswap","rmargin","rnumsplit","rnumnonpx","rrelNum","elemdisplay","BODY","cssShow","position","visibility","cssNormalTransform","letterSpacing","fontWeight","cssExpand","cssPrefixes","vendorPropName","capName","origName","isHidden","el","css","showHide","show","hidden","css_defaultDisplay","styles","hide","toggle","cssHooks","computed","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","extra","_computed","minWidth","maxWidth","getPropertyValue","currentStyle","left","rs","rsLeft","runtimeStyle","pixelLeft","setPositiveNumber","subtract","augmentWidthOrHeight","isBorderBox","getWidthOrHeight","valueIsBorderBox","actualDisplay","write","close","$1","visible","margin","padding","border","prefix","suffix","expand","expanded","parts","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","serialize","serializeArray","traditional","s","encodeURIComponent","ajaxSettings","buildParams","v","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","ajaxLocParts","ajaxLocation","ajax_nonce","ajax_rquery","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","_load","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataTypes","inspectPrefiltersOrTransports","originalOptions","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","params","response","responseText","complete","status","active","lastModified","etag","isLocal","processData","contentType","accepts","*","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","cacheURL","responseHeadersString","timeoutTimer","fireGlobals","transport","responseHeaders","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","mimeType","code","abort","statusText","finalText","success","method","crossDomain","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","responses","isSuccess","modified","ajaxHandleResponses","ajaxConvert","rejectWith","getJSON","getScript","firstDataType","ct","finalDataType","conv2","current","conv","dataFilter","script","text script","head","scriptCharset","charset","onload","onreadystatechange","isAbort","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","xhrCallbacks","xhrSupported","xhrId","xhrOnUnloadAbort","createStandardXHR","XMLHttpRequest","createActiveXHR","xhr","cors","username","open","xhrFields","firefoxAccessException","unload","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","tween","createTween","unit","scale","maxIterations","createFxNow","animation","collection","Animation","properties","stopped","tick","currentTime","startTime","duration","percent","tweens","run","opts","specialEasing","originalProperties","Tween","easing","gotoEnd","propFilter","timer","anim","tweener","prefilter","oldfire","dataShow","unqueued","overflow","overflowX","overflowY","eased","step","cssFn","speed","animate","genFx","fadeTo","to","optall","doAnimation","finish","stopQueue","timers","includeWidth","height","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","linear","p","swing","cos","PI","interval","setInterval","clearInterval","slow","fast","animated","offset","setOffset","win","box","getBoundingClientRect","getWindow","pageYOffset","pageXOffset","curElem","curOffset","curCSSTop","curCSSLeft","calculatePosition","curPosition","curTop","curLeft","using","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","module","exports","define","amd"],"mappings":";;;CAaA,SAAWA,EAAQC,GAOnB,GAECC,GAGAC,EAIAC,QAA2BH,GAG3BI,EAAWL,EAAOK,SAClBC,EAAWN,EAAOM,SAClBC,EAAUD,EAASE,gBAGnBC,EAAUT,EAAOU,OAGjBC,EAAKX,EAAOY,EAGZC,KAGAC,KAEAC,EAAe,SAGfC,EAAcF,EAAgBG,OAC9BC,EAAYJ,EAAgBK,KAC5BC,EAAaN,EAAgBO,MAC7BC,EAAeR,EAAgBS,QAC/BC,EAAgBX,EAAWY,SAC3BC,EAAcb,EAAWc,eACzBC,EAAYb,EAAac,KAGzBnB,EAAS,SAAUoB,EAAUC,GAE5B,MAAO,IAAIrB,GAAOsB,GAAGC,KAAMH,EAAUC,EAAS5B,IAI/C+B,EAAY,sCAAsCC,OAGlDC,EAAiB,OAGjBC,EAAQ,qCAKRC,EAAa,sCAGbC,EAAa,6BAGbC,EAAc,gBACdC,EAAe,uBACfC,EAAe,qCACfC,EAAe,kEAGfC,EAAY,QACZC,EAAa,eAGbC,EAAa,SAAUC,EAAKC,GAC3B,MAAOA,GAAOC,eAIfC,EAAY,SAAUC,IAGhB7C,EAAS8C,kBAAmC,SAAfD,EAAME,MAA2C,aAAxB/C,EAASgD,cACnEC,IACA7C,EAAO8C,UAITD,EAAS,WACHjD,EAAS8C,kBACb9C,EAASmD,oBAAqB,mBAAoBP,GAAW,GAC7DlD,EAAOyD,oBAAqB,OAAQP,GAAW,KAG/C5C,EAASoD,YAAa,qBAAsBR,GAC5ClD,EAAO0D,YAAa,SAAUR,IAIjCxC,GAAOsB,GAAKtB,EAAOiD,WAElBC,OAAQ7C,EAER8C,YAAanD,EACbuB,KAAM,SAAUH,EAAUC,EAAS5B,GAClC,GAAI2D,GAAOC,CAGX,KAAMjC,EACL,MAAOkC,KAIR,IAAyB,gBAAblC,GAAwB,CAUnC,GAPCgC,EAF2B,MAAvBhC,EAASmC,OAAO,IAAyD,MAA3CnC,EAASmC,OAAQnC,EAASoC,OAAS,IAAepC,EAASoC,QAAU,GAE7F,KAAMpC,EAAU,MAGlBQ,EAAW6B,KAAMrC,IAIrBgC,IAAUA,EAAM,IAAO/B,EAqDrB,OAAMA,GAAWA,EAAQ6B,QACtB7B,GAAW5B,GAAaiE,KAAMtC,GAKhCkC,KAAKH,YAAa9B,GAAUqC,KAAMtC,EAxDzC,IAAKgC,EAAM,GAAK,CAWf,GAVA/B,EAAUA,YAAmBrB,GAASqB,EAAQ,GAAKA,EAGnDrB,EAAO2D,MAAOL,KAAMtD,EAAO4D,UAC1BR,EAAM,GACN/B,GAAWA,EAAQwC,SAAWxC,EAAQyC,eAAiBzC,EAAUzB,GACjE,IAIIiC,EAAWkC,KAAMX,EAAM,KAAQpD,EAAOgE,cAAe3C,GACzD,IAAM+B,IAAS/B,GAETrB,EAAOiE,WAAYX,KAAMF,IAC7BE,KAAMF,GAAS/B,EAAS+B,IAIxBE,KAAKY,KAAMd,EAAO/B,EAAS+B,GAK9B,OAAOE,MAQP,GAJAD,EAAOzD,EAASuE,eAAgBf,EAAM,IAIjCC,GAAQA,EAAKe,WAAa,CAG9B,GAAKf,EAAKgB,KAAOjB,EAAM,GACtB,MAAO3D,GAAWiE,KAAMtC,EAIzBkC,MAAKE,OAAS,EACdF,KAAK,GAAKD,EAKX,MAFAC,MAAKjC,QAAUzB,EACf0D,KAAKlC,SAAWA,EACTkC,KAcH,MAAKlC,GAASyC,UACpBP,KAAKjC,QAAUiC,KAAK,GAAKlC,EACzBkC,KAAKE,OAAS,EACPF,MAIItD,EAAOiE,WAAY7C,GACvB3B,EAAWqD,MAAO1B,IAGrBA,EAASA,WAAa7B,IAC1B+D,KAAKlC,SAAWA,EAASA,SACzBkC,KAAKjC,QAAUD,EAASC,SAGlBrB,EAAOsE,UAAWlD,EAAUkC,QAIpClC,SAAU,GAGVoC,OAAQ,EAERe,QAAS,WACR,MAAO7D,GAAW8D,KAAMlB,OAKzBmB,IAAK,SAAUC,GACd,MAAc,OAAPA,EAGNpB,KAAKiB,UAGG,EAANG,EAAUpB,KAAMA,KAAKE,OAASkB,GAAQpB,KAAMoB,IAKhDC,UAAW,SAAUC,GAGpB,GAAIC,GAAM7E,EAAO2D,MAAOL,KAAKH,cAAeyB,EAO5C,OAJAC,GAAIC,WAAaxB,KACjBuB,EAAIxD,QAAUiC,KAAKjC,QAGZwD,GAMRE,KAAM,SAAUC,EAAUC,GACzB,MAAOjF,GAAO+E,KAAMzB,KAAM0B,EAAUC,IAGrCnC,MAAO,SAAUxB,GAIhB,MAFAtB,GAAO8C,MAAMoC,UAAUC,KAAM7D,GAEtBgC,MAGR3C,MAAO,WACN,MAAO2C,MAAKqB,UAAWjE,EAAW0E,MAAO9B,KAAM+B,aAGhDC,MAAO,WACN,MAAOhC,MAAKiC,GAAI,IAGjBC,KAAM,WACL,MAAOlC,MAAKiC,GAAI,KAGjBA,GAAI,SAAUE,GACb,GAAIC,GAAMpC,KAAKE,OACdmC,GAAKF,GAAU,EAAJA,EAAQC,EAAM,EAC1B,OAAOpC,MAAKqB,UAAWgB,GAAK,GAASD,EAAJC,GAAYrC,KAAKqC,SAGnDC,IAAK,SAAUZ,GACd,MAAO1B,MAAKqB,UAAW3E,EAAO4F,IAAItC,KAAM,SAAUD,EAAMoC,GACvD,MAAOT,GAASR,KAAMnB,EAAMoC,EAAGpC,OAIjCwC,IAAK,WACJ,MAAOvC,MAAKwB,YAAcxB,KAAKH,YAAY,OAK5C1C,KAAMD,EACNsF,QAASA,KACTC,UAAWA,QAIZ/F,EAAOsB,GAAGC,KAAK0B,UAAYjD,EAAOsB,GAElCtB,EAAOgG,OAAShG,EAAOsB,GAAG0E,OAAS,WAClC,GAAIC,GAAKC,EAAaC,EAAMC,EAAMC,EAASC,EAC1CC,EAASlB,UAAU,OACnBI,EAAI,EACJjC,EAAS6B,UAAU7B,OACnBgD,GAAO,CAqBR,KAlBuB,iBAAXD,KACXC,EAAOD,EACPA,EAASlB,UAAU,OAEnBI,EAAI,GAIkB,gBAAXc,IAAwBvG,EAAOiE,WAAWsC,KACrDA,MAII/C,IAAWiC,IACfc,EAASjD,OACPmC,GAGSjC,EAAJiC,EAAYA,IAEnB,GAAmC,OAA7BY,EAAUhB,UAAWI,IAE1B,IAAMW,IAAQC,GACbJ,EAAMM,EAAQH,GACdD,EAAOE,EAASD,GAGXG,IAAWJ,IAKXK,GAAQL,IAAUnG,EAAOgE,cAAcmC,KAAUD,EAAclG,EAAOyG,QAAQN,MAC7ED,GACJA,GAAc,EACdI,EAAQL,GAAOjG,EAAOyG,QAAQR,GAAOA,MAGrCK,EAAQL,GAAOjG,EAAOgE,cAAciC,GAAOA,KAI5CM,EAAQH,GAASpG,EAAOgG,OAAQQ,EAAMF,EAAOH,IAGlCA,IAAS5G,IACpBgH,EAAQH,GAASD,GAOrB,OAAOI,IAGRvG,EAAOgG,QAGNU,QAAS,UAAarG,EAAesG,KAAKC,UAAWC,QAAS,MAAO,IAErEC,WAAY,SAAUN,GASrB,MARKlH,GAAOY,IAAMF,IACjBV,EAAOY,EAAID,GAGPuG,GAAQlH,EAAOU,SAAWA,IAC9BV,EAAOU,OAASD,GAGVC,GAIR+G,SAAS,EAITC,UAAW,EAGXC,UAAW,SAAUC,GACfA,EACJlH,EAAOgH,YAEPhH,EAAO8C,OAAO,IAKhBA,MAAO,SAAUqE,GAGhB,GAAKA,KAAS,KAASnH,EAAOgH,WAAYhH,EAAO+G,QAAjD,CAKA,IAAMnH,EAASwH,KACd,MAAOC,YAAYrH,EAAO8C,MAI3B9C,GAAO+G,SAAU,EAGZI,KAAS,KAAUnH,EAAOgH,UAAY,IAK3CxH,EAAU8H,YAAa1H,GAAYI,IAG9BA,EAAOsB,GAAGiG,SACdvH,EAAQJ,GAAW2H,QAAQ,SAASC,IAAI,YAO1CvD,WAAY,SAAUwD,GACrB,MAA4B,aAArBzH,EAAO2C,KAAK8E,IAGpBhB,QAASiB,MAAMjB,SAAW,SAAUgB,GACnC,MAA4B,UAArBzH,EAAO2C,KAAK8E,IAGpBE,SAAU,SAAUF,GAEnB,MAAc,OAAPA,GAAeA,GAAOA,EAAInI,QAGlCsI,UAAW,SAAUH,GACpB,OAAQI,MAAOC,WAAWL,KAAUM,SAAUN,IAG/C9E,KAAM,SAAU8E,GACf,MAAY,OAAPA,EACWA,EAARO,GAEc,gBAARP,IAAmC,kBAARA,GACxCtH,EAAYW,EAAc0D,KAAKiD,KAAU,eAClCA,IAGTzD,cAAe,SAAUyD,GACxB,GAAIQ,EAKJ,KAAMR,GAA4B,WAArBzH,EAAO2C,KAAK8E,IAAqBA,EAAI5D,UAAY7D,EAAO2H,SAAUF,GAC9E,OAAO,CAGR,KAEC,GAAKA,EAAItE,cACPnC,EAAYwD,KAAKiD,EAAK,iBACtBzG,EAAYwD,KAAKiD,EAAItE,YAAYF,UAAW,iBAC7C,OAAO,EAEP,MAAQiF,GAET,OAAO,EAKR,GAAKlI,EAAOmI,QAAQC,QACnB,IAAMH,IAAOR,GACZ,MAAOzG,GAAYwD,KAAMiD,EAAKQ,EAMhC,KAAMA,IAAOR,IAEb,MAAOQ,KAAQ1I,GAAayB,EAAYwD,KAAMiD,EAAKQ,IAGpDI,cAAe,SAAUZ,GACxB,GAAIrB,EACJ,KAAMA,IAAQqB,GACb,OAAO,CAER,QAAO,GAGRa,MAAO,SAAUC,GAChB,KAAUC,OAAOD,IAMlB3E,UAAW,SAAU6E,EAAMpH,EAASqH,GACnC,IAAMD,GAAwB,gBAATA,GACpB,MAAO,KAEgB,kBAAZpH,KACXqH,EAAcrH,EACdA,GAAU,GAEXA,EAAUA,GAAWzB,CAErB,IAAI+I,GAAS9G,EAAW4B,KAAMgF,GAC7BG,GAAWF,KAGZ,OAAKC,IACKtH,EAAQwH,cAAeF,EAAO,MAGxCA,EAAS3I,EAAO8I,eAAiBL,GAAQpH,EAASuH,GAC7CA,GACJ5I,EAAQ4I,GAAUG,SAEZ/I,EAAO2D,SAAWgF,EAAOK,cAGjCC,UAAW,SAAUR,GAEpB,MAAKnJ,GAAO4J,MAAQ5J,EAAO4J,KAAKC,MACxB7J,EAAO4J,KAAKC,MAAOV,GAGb,OAATA,EACGA,EAGa,gBAATA,KAGXA,EAAOzI,EAAOmB,KAAMsH,GAEfA,GAGC3G,EAAYiC,KAAM0E,EAAK5B,QAAS7E,EAAc,KACjD6E,QAAS5E,EAAc,KACvB4E,QAAS9E,EAAc,MAEXqH,SAAU,UAAYX,MAKtCzI,EAAOsI,MAAO,iBAAmBG,GAAjCzI,IAIDqJ,SAAU,SAAUZ,GACnB,GAAIa,GAAKC,CACT,KAAMd,GAAwB,gBAATA,GACpB,MAAO,KAER,KACMnJ,EAAOkK,WACXD,EAAM,GAAIC,WACVF,EAAMC,EAAIE,gBAAiBhB,EAAO,cAElCa,EAAM,GAAII,eAAe,oBACzBJ,EAAIK,MAAQ,QACZL,EAAIM,QAASnB,IAEb,MAAOP,GACRoB,EAAM/J,EAKP,MAHM+J,IAAQA,EAAIxJ,kBAAmBwJ,EAAIO,qBAAsB,eAAgBrG,QAC9ExD,EAAOsI,MAAO,gBAAkBG,GAE1Ba,GAGRQ,KAAM,aAKNC,WAAY,SAAUtB,GAChBA,GAAQzI,EAAOmB,KAAMsH,KAIvBnJ,EAAO0K,YAAc,SAAUvB,GAChCnJ,EAAe,KAAEkF,KAAMlF,EAAQmJ,KAC3BA,IAMPwB,UAAW,SAAUC,GACpB,MAAOA,GAAOrD,QAAS3E,EAAW,OAAQ2E,QAAS1E,EAAYC,IAGhE+H,SAAU,SAAU9G,EAAM+C,GACzB,MAAO/C,GAAK8G,UAAY9G,EAAK8G,SAASC,gBAAkBhE,EAAKgE,eAI9DrF,KAAM,SAAU0C,EAAKzC,EAAUC,GAC9B,GAAIoF,GACH5E,EAAI,EACJjC,EAASiE,EAAIjE,OACbiD,EAAU6D,EAAa7C,EAExB,IAAKxC,GACJ,GAAKwB,GACJ,KAAYjD,EAAJiC,EAAYA,IAGnB,GAFA4E,EAAQrF,EAASI,MAAOqC,EAAKhC,GAAKR,GAE7BoF,KAAU,EACd,UAIF,KAAM5E,IAAKgC,GAGV,GAFA4C,EAAQrF,EAASI,MAAOqC,EAAKhC,GAAKR,GAE7BoF,KAAU,EACd,UAOH,IAAK5D,GACJ,KAAYjD,EAAJiC,EAAYA,IAGnB,GAFA4E,EAAQrF,EAASR,KAAMiD,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpC4E,KAAU,EACd,UAIF,KAAM5E,IAAKgC,GAGV,GAFA4C,EAAQrF,EAASR,KAAMiD,EAAKhC,GAAKA,EAAGgC,EAAKhC,IAEpC4E,KAAU,EACd,KAMJ,OAAO5C,IAIRtG,KAAMD,IAAcA,EAAUsD,KAAK,gBAClC,SAAU+F,GACT,MAAe,OAARA,EACN,GACArJ,EAAUsD,KAAM+F,IAIlB,SAAUA,GACT,MAAe,OAARA,EACN,IACEA,EAAO,IAAK1D,QAASlF,EAAO,KAIjC2C,UAAW,SAAUkG,EAAKC,GACzB,GAAI5F,GAAM4F,KAaV,OAXY,OAAPD,IACCF,EAAaI,OAAOF,IACxBxK,EAAO2D,MAAOkB,EACE,gBAAR2F,IACLA,GAAQA,GAGXhK,EAAUgE,KAAMK,EAAK2F,IAIhB3F,GAGR8F,QAAS,SAAUtH,EAAMmH,EAAK/E,GAC7B,GAAIC,EAEJ,IAAK8E,EAAM,CACV,GAAK5J,EACJ,MAAOA,GAAa4D,KAAMgG,EAAKnH,EAAMoC,EAMtC,KAHAC,EAAM8E,EAAIhH,OACViC,EAAIA,EAAQ,EAAJA,EAAQkB,KAAKiE,IAAK,EAAGlF,EAAMD,GAAMA,EAAI,EAEjCC,EAAJD,EAASA,IAEhB,GAAKA,IAAK+E,IAAOA,EAAK/E,KAAQpC,EAC7B,MAAOoC,GAKV,MAAO,IAGR9B,MAAO,SAAU2B,EAAOuF,GACvB,GAAIC,GAAID,EAAOrH,OACdiC,EAAIH,EAAM9B,OACVmC,EAAI,CAEL,IAAkB,gBAANmF,GACX,KAAYA,EAAJnF,EAAOA,IACdL,EAAOG,KAAQoF,EAAQlF,OAGxB,OAAQkF,EAAOlF,KAAOpG,EACrB+F,EAAOG,KAAQoF,EAAQlF,IAMzB,OAFAL,GAAM9B,OAASiC,EAERH,GAGRyF,KAAM,SAAUnG,EAAOI,EAAUgG,GAChC,GAAIC,GACHpG,KACAY,EAAI,EACJjC,EAASoB,EAAMpB,MAKhB,KAJAwH,IAAQA,EAIIxH,EAAJiC,EAAYA,IACnBwF,IAAWjG,EAAUJ,EAAOa,GAAKA,GAC5BuF,IAAQC,GACZpG,EAAIpE,KAAMmE,EAAOa,GAInB,OAAOZ,IAIRe,IAAK,SAAUhB,EAAOI,EAAUkG,GAC/B,GAAIb,GACH5E,EAAI,EACJjC,EAASoB,EAAMpB,OACfiD,EAAU6D,EAAa1F,GACvBC,IAGD,IAAK4B,EACJ,KAAYjD,EAAJiC,EAAYA,IACnB4E,EAAQrF,EAAUJ,EAAOa,GAAKA,EAAGyF,GAEnB,MAATb,IACJxF,EAAKA,EAAIrB,QAAW6G,OAMtB,KAAM5E,IAAKb,GACVyF,EAAQrF,EAAUJ,EAAOa,GAAKA,EAAGyF,GAEnB,MAATb,IACJxF,EAAKA,EAAIrB,QAAW6G,EAMvB,OAAO/J,GAAY8E,SAAWP,IAI/BsG,KAAM,EAINC,MAAO,SAAU9J,EAAID,GACpB,GAAI4D,GAAMmG,EAAO7B,CAUjB,OARwB,gBAAZlI,KACXkI,EAAMjI,EAAID,GACVA,EAAUC,EACVA,EAAKiI,GAKAvJ,EAAOiE,WAAY3C,IAKzB2D,EAAOvE,EAAW8D,KAAMa,UAAW,GACnC+F,EAAQ,WACP,MAAO9J,GAAG8D,MAAO/D,GAAWiC,KAAM2B,EAAK1E,OAAQG,EAAW8D,KAAMa,cAIjE+F,EAAMD,KAAO7J,EAAG6J,KAAO7J,EAAG6J,MAAQnL,EAAOmL,OAElCC,GAZC7L,GAiBT8L,OAAQ,SAAUzG,EAAOtD,EAAI2G,EAAKoC,EAAOiB,EAAWC,EAAUC,GAC7D,GAAI/F,GAAI,EACPjC,EAASoB,EAAMpB,OACfiI,EAAc,MAAPxD,CAGR,IAA4B,WAAvBjI,EAAO2C,KAAMsF,GAAqB,CACtCqD,GAAY,CACZ,KAAM7F,IAAKwC,GACVjI,EAAOqL,OAAQzG,EAAOtD,EAAImE,EAAGwC,EAAIxC,IAAI,EAAM8F,EAAUC,OAIhD,IAAKnB,IAAU9K,IACrB+L,GAAY,EAENtL,EAAOiE,WAAYoG,KACxBmB,GAAM,GAGFC,IAECD,GACJlK,EAAGkD,KAAMI,EAAOyF,GAChB/I,EAAK,OAILmK,EAAOnK,EACPA,EAAK,SAAU+B,EAAM4E,EAAKoC,GACzB,MAAOoB,GAAKjH,KAAMxE,EAAQqD,GAAQgH,MAKhC/I,GACJ,KAAYkC,EAAJiC,EAAYA,IACnBnE,EAAIsD,EAAMa,GAAIwC,EAAKuD,EAAMnB,EAAQA,EAAM7F,KAAMI,EAAMa,GAAIA,EAAGnE,EAAIsD,EAAMa,GAAIwC,IAK3E,OAAOqD,GACN1G,EAGA6G,EACCnK,EAAGkD,KAAMI,GACTpB,EAASlC,EAAIsD,EAAM,GAAIqD,GAAQsD,GAGlCG,IAAK,WACJ,OAAO,GAAMC,OAASC,WAMvBC,KAAM,SAAUxI,EAAMgD,EAASrB,EAAUC,GACxC,GAAIJ,GAAKuB,EACR0F,IAGD,KAAM1F,IAAQC,GACbyF,EAAK1F,GAAS/C,EAAK0I,MAAO3F,GAC1B/C,EAAK0I,MAAO3F,GAASC,EAASD,EAG/BvB,GAAMG,EAASI,MAAO/B,EAAM4B,MAG5B,KAAMmB,IAAQC,GACbhD,EAAK0I,MAAO3F,GAAS0F,EAAK1F,EAG3B,OAAOvB,MAIT7E,EAAO8C,MAAMoC,QAAU,SAAUuC,GAChC,IAAMjI,EAOL,GALAA,EAAYQ,EAAOgM,WAKU,aAAxBpM,EAASgD,WAEbyE,WAAYrH,EAAO8C,WAGb,IAAKlD,EAAS8C,iBAEpB9C,EAAS8C,iBAAkB,mBAAoBF,GAAW,GAG1DlD,EAAOoD,iBAAkB,OAAQF,GAAW,OAGtC,CAEN5C,EAASqM,YAAa,qBAAsBzJ,GAG5ClD,EAAO2M,YAAa,SAAUzJ,EAI9B,IAAI0J,IAAM,CAEV,KACCA,EAA6B,MAAvB5M,EAAO6M,cAAwBvM,EAASE,gBAC7C,MAAMoI,IAEHgE,GAAOA,EAAIE,UACf,QAAUC,KACT,IAAMrM,EAAO+G,QAAU,CAEtB,IAGCmF,EAAIE,SAAS,QACZ,MAAMlE,GACP,MAAOb,YAAYgF,EAAe,IAInCxJ,IAGA7C,EAAO8C,YAMZ,MAAOtD,GAAU0F,QAASuC,IAI3BzH,EAAO+E,KAAK,gEAAgEuH,MAAM,KAAM,SAAS7G,EAAGW,GACnGjG,EAAY,WAAaiG,EAAO,KAAQA,EAAKgE,eAG9C,SAASE,GAAa7C,GACrB,GAAIjE,GAASiE,EAAIjE,OAChBb,EAAO3C,EAAO2C,KAAM8E,EAErB,OAAKzH,GAAO2H,SAAUF,IACd,EAGc,IAAjBA,EAAI5D,UAAkBL,GACnB,EAGQ,UAATb,GAA6B,aAATA,IACb,IAAXa,GACgB,gBAAXA,IAAuBA,EAAS,GAAOA,EAAS,IAAOiE,IAIhEhI,EAAaO,EAAOJ,GAWpB,SAAWN,EAAQC,GAEnB,GAAIkG,GACH0C,EACAoE,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAlN,EACAC,EACAkN,EACAC,EACAC,EACAC,EACAC,EAGAzG,EAAU,UAAY,GAAKiF,MAC3ByB,EAAe9N,EAAOM,SACtByN,EAAU,EACVlI,EAAO,EACPmI,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,GAAe,EACfC,EAAY,SAAUC,EAAGC,GACxB,MAAKD,KAAMC,GACVH,GAAe,EACR,GAED,GAIRI,QAAsBvO,GACtBwO,EAAe,GAAK,GAGpBC,KAAc/M,eACduJ,KACAyD,EAAMzD,EAAIyD,IACVC,EAAc1D,EAAI/J,KAClBA,EAAO+J,EAAI/J,KACXE,EAAQ6J,EAAI7J,MAEZE,EAAU2J,EAAI3J,SAAW,SAAUwC,GAClC,GAAIoC,GAAI,EACPC,EAAMpC,KAAKE,MACZ,MAAYkC,EAAJD,EAASA,IAChB,GAAKnC,KAAKmC,KAAOpC,EAChB,MAAOoC,EAGT,OAAO,IAGR0I,EAAW,6HAKXC,EAAa,sBAEbC,EAAoB,mCAKpBC,EAAaD,EAAkBxH,QAAS,IAAK,MAG7C0H,EAAa,MAAQH,EAAa,KAAOC,EAAoB,IAAMD,EAClE,mBAAqBA,EAAa,wCAA0CE,EAAa,QAAUF,EAAa,OAQjHI,EAAU,KAAOH,EAAoB,mEAAqEE,EAAW1H,QAAS,EAAG,GAAM,eAGvIlF,EAAY8M,OAAQ,IAAML,EAAa,8BAAgCA,EAAa,KAAM,KAE1FM,EAAaD,OAAQ,IAAML,EAAa,KAAOA,EAAa,KAC5DO,EAAmBF,OAAQ,IAAML,EAAa,WAAaA,EAAa,IAAMA,EAAa,KAE3FQ,EAAeH,OAAQL,EAAa,SACpCS,EAAuBJ,OAAQ,IAAML,EAAa,gBAAkBA,EAAa,OAAQ,KAEzFU,EAAcL,OAAQD,GACtBO,EAAkBN,OAAQ,IAAMH,EAAa,KAE7CU,GACCC,GAAUR,OAAQ,MAAQJ,EAAoB,KAC9Ca,MAAaT,OAAQ,QAAUJ,EAAoB,KACnDc,IAAWV,OAAQ,KAAOJ,EAAkBxH,QAAS,IAAK,MAAS,KACnEuI,KAAYX,OAAQ,IAAMF,GAC1Bc,OAAcZ,OAAQ,IAAMD,GAC5Bc,MAAab,OAAQ,yDAA2DL,EAC/E,+BAAiCA,EAAa,cAAgBA,EAC9D,aAAeA,EAAa,SAAU,KACvCmB,KAAYd,OAAQ,OAASN,EAAW,KAAM,KAG9CqB,aAAoBf,OAAQ,IAAML,EAAa,mDAC9CA,EAAa,mBAAqBA,EAAa,mBAAoB,MAGrEqB,EAAU,yBAGV7N,EAAa,mCAEb8N,GAAU,sCACVC,GAAU,SAEVC,GAAU,QAGVC,GAAgBpB,OAAQ,qBAAuBL,EAAa,MAAQA,EAAa,OAAQ,MACzF0B,GAAY,SAAUC,EAAGC,EAASC,GACjC,GAAIC,GAAO,KAAOF,EAAU,KAI5B,OAAOE,KAASA,GAAQD,EACvBD,EAEO,EAAPE,EACClI,OAAOmI,aAAcD,EAAO,OAE5BlI,OAAOmI,aAA2B,MAAbD,GAAQ,GAA4B,MAAR,KAAPA,GAI9C,KACCzP,EAAK2E,MACHoF,EAAM7J,EAAM6D,KAAM4I,EAAapE,YAChCoE,EAAapE,YAIdwB,EAAK4C,EAAapE,WAAWxF,QAASK,SACrC,MAAQqE,IACTzH,GAAS2E,MAAOoF,EAAIhH,OAGnB,SAAU+C,EAAQ6J,GACjBlC,EAAY9I,MAAOmB,EAAQ5F,EAAM6D,KAAK4L,KAKvC,SAAU7J,EAAQ6J,GACjB,GAAIzK,GAAIY,EAAO/C,OACdiC,EAAI,CAEL,OAASc,EAAOZ,KAAOyK,EAAI3K,MAC3Bc,EAAO/C,OAASmC,EAAI,IAKvB,QAAS0K,IAAQjP,EAAUC,EAASoJ,EAAS6F,GAC5C,GAAIlN,GAAOC,EAAMkN,EAAG1M,EAEnB4B,EAAG+K,EAAQ1E,EAAK2E,EAAKC,EAAYC,CASlC,KAPOtP,EAAUA,EAAQyC,eAAiBzC,EAAU+L,KAAmBxN,GACtEkN,EAAazL,GAGdA,EAAUA,GAAWzB,EACrB6K,EAAUA,OAEJrJ,GAAgC,gBAAbA,GACxB,MAAOqJ,EAGR,IAAuC,KAAjC5G,EAAWxC,EAAQwC,WAAgC,IAAbA,EAC3C,QAGD,IAAKkJ,IAAmBuD,EAAO,CAG9B,GAAMlN,EAAQxB,EAAW6B,KAAMrC,GAE9B,GAAMmP,EAAInN,EAAM,IACf,GAAkB,IAAbS,EAAiB,CAIrB,GAHAR,EAAOhC,EAAQ8C,eAAgBoM,IAG1BlN,IAAQA,EAAKe,WAQjB,MAAOqG,EALP,IAAKpH,EAAKgB,KAAOkM,EAEhB,MADA9F,GAAQhK,KAAM4C,GACPoH,MAOT,IAAKpJ,EAAQyC,gBAAkBT,EAAOhC,EAAQyC,cAAcK,eAAgBoM,KAC3EpD,EAAU9L,EAASgC,IAAUA,EAAKgB,KAAOkM,EAEzC,MADA9F,GAAQhK,KAAM4C,GACPoH,MAKH,CAAA,GAAKrH,EAAM,GAEjB,MADA3C,GAAK2E,MAAOqF,EAASpJ,EAAQwI,qBAAsBzI,IAC5CqJ,CAGD,KAAM8F,EAAInN,EAAM,KAAO+E,EAAQyI,wBAA0BvP,EAAQuP,uBAEvE,MADAnQ,GAAK2E,MAAOqF,EAASpJ,EAAQuP,uBAAwBL,IAC9C9F,EAKT,GAAKtC,EAAQ0I,OAAS7D,IAAcA,EAAUjJ,KAAM3C,IAAc,CASjE,GARAqP,EAAM3E,EAAMpF,EACZgK,EAAarP,EACbsP,EAA2B,IAAb9M,GAAkBzC,EAMd,IAAbyC,GAAqD,WAAnCxC,EAAQ8I,SAASC,cAA6B,CACpEoG,EAASM,GAAU1P,IAEb0K,EAAMzK,EAAQ0P,aAAa,OAChCN,EAAM3E,EAAIjF,QAAS+I,GAAS,QAE5BvO,EAAQ2P,aAAc,KAAMP,GAE7BA,EAAM,QAAUA,EAAM,MAEtBhL,EAAI+K,EAAOhN,MACX,OAAQiC,IACP+K,EAAO/K,GAAKgL,EAAMQ,GAAYT,EAAO/K,GAEtCiL,GAAa9B,EAAS7K,KAAM3C,IAAcC,EAAQ+C,YAAc/C,EAChEsP,EAAcH,EAAOU,KAAK,KAG3B,GAAKP,EACJ,IAIC,MAHAlQ,GAAK2E,MAAOqF,EACXiG,EAAWS,iBAAkBR,IAEvBlG,EACN,MAAM2G,IACN,QACKtF,GACLzK,EAAQgQ,gBAAgB,QAQ7B,MAAOC,IAAQlQ,EAASyF,QAASlF,EAAO,MAAQN,EAASoJ,EAAS6F,GASnE,QAAS/C,MACR,GAAIgE,KAEJ,SAASC,GAAOvJ,EAAKoC,GAMpB,MAJKkH,GAAK9Q,KAAMwH,GAAO,KAAQuE,EAAKiF,mBAE5BD,GAAOD,EAAKG,SAEZF,EAAOvJ,GAAQoC,EAExB,MAAOmH,GAOR,QAASG,IAAcrQ,GAEtB,MADAA,GAAIoF,IAAY,EACTpF,EAOR,QAASsQ,IAAQtQ,GAChB,GAAIuQ,GAAMjS,EAASiJ,cAAc,MAEjC,KACC,QAASvH,EAAIuQ,GACZ,MAAO3J,GACR,OAAO,EACN,QAEI2J,EAAIzN,YACRyN,EAAIzN,WAAW0N,YAAaD,GAG7BA,EAAM,MASR,QAASE,IAAWC,EAAOC,GAC1B,GAAIzH,GAAMwH,EAAM1F,MAAM,KACrB7G,EAAIuM,EAAMxO,MAEX,OAAQiC,IACP+G,EAAK0F,WAAY1H,EAAI/E,IAAOwM,EAU9B,QAASE,IAAcvE,EAAGC,GACzB,GAAIuE,GAAMvE,GAAKD,EACdyE,EAAOD,GAAsB,IAAfxE,EAAE/J,UAAiC,IAAfgK,EAAEhK,YAChCgK,EAAEyE,aAAevE,KACjBH,EAAE0E,aAAevE,EAGtB,IAAKsE,EACJ,MAAOA,EAIR,IAAKD,EACJ,MAASA,EAAMA,EAAIG,YAClB,GAAKH,IAAQvE,EACZ,MAAO,EAKV,OAAOD,GAAI,EAAI,GAOhB,QAAS4E,IAAmB7P,GAC3B,MAAO,UAAUU,GAChB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,OAAgB,UAAThE,GAAoB/C,EAAKV,OAASA,GAQ3C,QAAS8P,IAAoB9P,GAC5B,MAAO,UAAUU,GAChB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,QAAiB,UAAThE,GAA6B,WAATA,IAAsB/C,EAAKV,OAASA,GAQlE,QAAS+P,IAAwBpR,GAChC,MAAOqQ,IAAa,SAAUgB,GAE7B,MADAA,IAAYA,EACLhB,GAAa,SAAUrB,EAAMpD,GACnC,GAAIvH,GACHiN,EAAetR,KAAQgP,EAAK9M,OAAQmP,GACpClN,EAAImN,EAAapP,MAGlB,OAAQiC,IACF6K,EAAO3K,EAAIiN,EAAanN,MAC5B6K,EAAK3K,KAAOuH,EAAQvH,GAAK2K,EAAK3K,SAWnC+G,EAAQ2D,GAAO3D,MAAQ,SAAUrJ,GAGhC,GAAIvD,GAAkBuD,IAASA,EAAKS,eAAiBT,GAAMvD,eAC3D,OAAOA,GAA+C,SAA7BA,EAAgBqK,UAAsB,GAIhEhC,EAAUkI,GAAOlI,WAOjB2E,EAAcuD,GAAOvD,YAAc,SAAU+F,GAC5C,GAAIC,GAAMD,EAAOA,EAAK/O,eAAiB+O,EAAOzF,EAC7C2F,EAASD,EAAIE,WAGd,OAAKF,KAAQlT,GAA6B,IAAjBkT,EAAIjP,UAAmBiP,EAAIhT,iBAKpDF,EAAWkT,EACXjT,EAAUiT,EAAIhT,gBAGdiN,GAAkBL,EAAOoG,GAMpBC,GAAUA,EAAO9G,aAAe8G,IAAWA,EAAO7G,KACtD6G,EAAO9G,YAAa,iBAAkB,WACrCa,MASF3E,EAAQoG,WAAaqD,GAAO,SAAUC,GAErC,MADAA,GAAIoB,UAAY,KACRpB,EAAId,aAAa,eAO1B5I,EAAQ0B,qBAAuB+H,GAAO,SAAUC,GAE/C,MADAA,GAAIqB,YAAaJ,EAAIK,cAAc,MAC3BtB,EAAIhI,qBAAqB,KAAKrG,SAIvC2E,EAAQyI,uBAAyBgB,GAAO,SAAUC,GAQjD,MAPAA,GAAIuB,UAAY,+CAIhBvB,EAAIwB,WAAWJ,UAAY,IAGuB,IAA3CpB,EAAIjB,uBAAuB,KAAKpN,SAOxC2E,EAAQmL,QAAU1B,GAAO,SAAUC,GAElC,MADAhS,GAAQqT,YAAarB,GAAMxN,GAAKqC,GACxBoM,EAAIS,oBAAsBT,EAAIS,kBAAmB7M,GAAUlD,SAI/D2E,EAAQmL,SACZ9G,EAAK9I,KAAS,GAAI,SAAUW,EAAIhD,GAC/B,SAAYA,GAAQ8C,iBAAmB2J,GAAgBf,EAAiB,CACvE,GAAIwD,GAAIlP,EAAQ8C,eAAgBE,EAGhC,OAAOkM,IAAKA,EAAEnM,YAAcmM,QAG9B/D,EAAKgH,OAAW,GAAI,SAAUnP,GAC7B,GAAIoP,GAASpP,EAAGwC,QAASgJ,GAAWC,GACpC,OAAO,UAAUzM,GAChB,MAAOA,GAAK0N,aAAa,QAAU0C,YAM9BjH,GAAK9I,KAAS,GAErB8I,EAAKgH,OAAW,GAAK,SAAUnP,GAC9B,GAAIoP,GAASpP,EAAGwC,QAASgJ,GAAWC,GACpC,OAAO,UAAUzM,GAChB,GAAIwP,SAAcxP,GAAKqQ,mBAAqB5F,GAAgBzK,EAAKqQ,iBAAiB,KAClF,OAAOb,IAAQA,EAAKxI,QAAUoJ,KAMjCjH,EAAK9I,KAAU,IAAIyE,EAAQ0B,qBAC1B,SAAU8J,EAAKtS,GACd,aAAYA,GAAQwI,uBAAyBiE,EACrCzM,EAAQwI,qBAAsB8J,GADtC,GAID,SAAUA,EAAKtS,GACd,GAAIgC,GACHkG,KACA9D,EAAI,EACJgF,EAAUpJ,EAAQwI,qBAAsB8J,EAGzC,IAAa,MAARA,EAAc,CAClB,MAAStQ,EAAOoH,EAAQhF,KACA,IAAlBpC,EAAKQ,UACT0F,EAAI9I,KAAM4C,EAIZ,OAAOkG,GAER,MAAOkB,IAIT+B,EAAK9I,KAAY,MAAIyE,EAAQyI,wBAA0B,SAAUqC,EAAW5R,GAC3E,aAAYA,GAAQuP,yBAA2B9C,GAAgBf,EACvD1L,EAAQuP,uBAAwBqC,GADxC,GAWDhG,KAOAD,MAEM7E,EAAQ0I,IAAMpB,EAAQ1L,KAAM+O,EAAI3B,qBAGrCS,GAAO,SAAUC,GAMhBA,EAAIuB,UAAY,iDAIVvB,EAAIV,iBAAiB,cAAc3N,QACxCwJ,EAAUvM,KAAM,MAAQ2N,EAAa,aAAeD,EAAW,KAM1D0D,EAAIV,iBAAiB,YAAY3N,QACtCwJ,EAAUvM,KAAK,cAIjBmR,GAAO,SAAUC,GAOhB,GAAI+B,GAAQd,EAAIjK,cAAc,QAC9B+K,GAAM5C,aAAc,OAAQ,UAC5Ba,EAAIqB,YAAaU,GAAQ5C,aAAc,IAAK,IAEvCa,EAAIV,iBAAiB,WAAW3N,QACpCwJ,EAAUvM,KAAM,SAAW2N,EAAa,gBAKnCyD,EAAIV,iBAAiB,YAAY3N,QACtCwJ,EAAUvM,KAAM,WAAY,aAI7BoR,EAAIV,iBAAiB,QACrBnE,EAAUvM,KAAK,YAIX0H,EAAQ0L,gBAAkBpE,EAAQ1L,KAAOmJ,EAAUrN,EAAQiU,uBAChEjU,EAAQkU,oBACRlU,EAAQmU,kBACRnU,EAAQoU,qBAERrC,GAAO,SAAUC,GAGhB1J,EAAQ+L,kBAAoBhH,EAAQ1I,KAAMqN,EAAK,OAI/C3E,EAAQ1I,KAAMqN,EAAK,aACnB5E,EAAcxM,KAAM,KAAM+N,KAI5BxB,EAAYA,EAAUxJ,QAAciL,OAAQzB,EAAUkE,KAAK,MAC3DjE,EAAgBA,EAAczJ,QAAciL,OAAQxB,EAAciE,KAAK,MAQvE/D,EAAWsC,EAAQ1L,KAAMlE,EAAQsN,WAActN,EAAQsU,wBACtD,SAAUvG,EAAGC,GACZ,GAAIuG,GAAuB,IAAfxG,EAAE/J,SAAiB+J,EAAE9N,gBAAkB8N,EAClDyG,EAAMxG,GAAKA,EAAEzJ,UACd,OAAOwJ,KAAMyG,MAAWA,GAAwB,IAAjBA,EAAIxQ,YAClCuQ,EAAMjH,SACLiH,EAAMjH,SAAUkH,GAChBzG,EAAEuG,yBAA8D,GAAnCvG,EAAEuG,wBAAyBE,MAG3D,SAAUzG,EAAGC,GACZ,GAAKA,EACJ,MAASA,EAAIA,EAAEzJ,WACd,GAAKyJ,IAAMD,EACV,OAAO,CAIV,QAAO,GAOTD,EAAY9N,EAAQsU,wBACpB,SAAUvG,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGR,IAAI4G,GAAUzG,EAAEsG,yBAA2BvG,EAAEuG,yBAA2BvG,EAAEuG,wBAAyBtG,EAEnG,OAAKyG,GAEW,EAAVA,IACFnM,EAAQoM,cAAgB1G,EAAEsG,wBAAyBvG,KAAQ0G,EAGxD1G,IAAMkF,GAAO3F,EAASC,EAAcQ,GACjC,GAEHC,IAAMiF,GAAO3F,EAASC,EAAcS,GACjC,EAIDhB,EACJhM,EAAQ2D,KAAMqI,EAAWe,GAAM/M,EAAQ2D,KAAMqI,EAAWgB,GAC1D,EAGe,EAAVyG,EAAc,GAAK,EAIpB1G,EAAEuG,wBAA0B,GAAK,GAEzC,SAAUvG,EAAGC,GACZ,GAAIuE,GACH3M,EAAI,EACJ+O,EAAM5G,EAAExJ,WACRiQ,EAAMxG,EAAEzJ,WACRqQ,GAAO7G,GACP8G,GAAO7G,EAGR,IAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGD,KAAM8G,IAAQH,EACpB,MAAOzG,KAAMkF,EAAM,GAClBjF,IAAMiF,EAAM,EACZ0B,EAAM,GACNH,EAAM,EACNxH,EACEhM,EAAQ2D,KAAMqI,EAAWe,GAAM/M,EAAQ2D,KAAMqI,EAAWgB,GAC1D,CAGK,IAAK2G,IAAQH,EACnB,MAAOlC,IAAcvE,EAAGC,EAIzBuE,GAAMxE,CACN,OAASwE,EAAMA,EAAIhO,WAClBqQ,EAAGE,QAASvC,EAEbA,GAAMvE,CACN,OAASuE,EAAMA,EAAIhO,WAClBsQ,EAAGC,QAASvC,EAIb,OAAQqC,EAAGhP,KAAOiP,EAAGjP,GACpBA,GAGD,OAAOA,GAEN0M,GAAcsC,EAAGhP,GAAIiP,EAAGjP,IAGxBgP,EAAGhP,KAAO2H,EAAe,GACzBsH,EAAGjP,KAAO2H,EAAe,EACzB,GAGK0F,GA1UClT,GA6UTyQ,GAAOnD,QAAU,SAAU0H,EAAMC,GAChC,MAAOxE,IAAQuE,EAAM,KAAM,KAAMC,IAGlCxE,GAAOwD,gBAAkB,SAAUxQ,EAAMuR,GASxC,IAPOvR,EAAKS,eAAiBT,KAAWzD,GACvCkN,EAAazJ,GAIduR,EAAOA,EAAK/N,QAASgI,EAAkB,aAElC1G,EAAQ0L,kBAAmB9G,GAC5BE,GAAkBA,EAAclJ,KAAM6Q,IACtC5H,GAAkBA,EAAUjJ,KAAM6Q,IAErC,IACC,GAAI/P,GAAMqI,EAAQ1I,KAAMnB,EAAMuR,EAG9B,IAAK/P,GAAOsD,EAAQ+L,mBAGlB7Q,EAAKzD,UAAuC,KAA3ByD,EAAKzD,SAASiE,SAChC,MAAOgB,GAEP,MAAMqD,IAGT,MAAOmI,IAAQuE,EAAMhV,EAAU,MAAOyD,IAAQG,OAAS,GAGxD6M,GAAOlD,SAAW,SAAU9L,EAASgC,GAKpC,OAHOhC,EAAQyC,eAAiBzC,KAAczB,GAC7CkN,EAAazL,GAEP8L,EAAU9L,EAASgC,IAG3BgN,GAAOnM,KAAO,SAAUb,EAAM+C,IAEtB/C,EAAKS,eAAiBT,KAAWzD,GACvCkN,EAAazJ,EAGd,IAAI/B,GAAKkL,EAAK0F,WAAY9L,EAAKgE,eAE9B0K,EAAMxT,GAAM0M,EAAOxJ,KAAMgI,EAAK0F,WAAY9L,EAAKgE,eAC9C9I,EAAI+B,EAAM+C,GAAO2G,GACjBxN,CAEF,OAAOuV,KAAQvV,EACd4I,EAAQoG,aAAexB,EACtB1J,EAAK0N,aAAc3K,IAClB0O,EAAMzR,EAAKqQ,iBAAiBtN,KAAU0O,EAAIC,UAC1CD,EAAIzK,MACJ,KACFyK,GAGFzE,GAAO/H,MAAQ,SAAUC,GACxB,KAAUC,OAAO,0CAA4CD,IAO9D8H,GAAO2E,WAAa,SAAUvK,GAC7B,GAAIpH,GACH4R,KACAtP,EAAI,EACJF,EAAI,CAOL,IAJAiI,GAAgBvF,EAAQ+M,iBACxBrI,GAAa1E,EAAQgN,YAAc1K,EAAQ9J,MAAO,GAClD8J,EAAQ3E,KAAM6H,GAETD,EAAe,CACnB,MAASrK,EAAOoH,EAAQhF,KAClBpC,IAASoH,EAAShF,KACtBE,EAAIsP,EAAWxU,KAAMgF,GAGvB,OAAQE,IACP8E,EAAQ1E,OAAQkP,EAAYtP,GAAK,GAInC,MAAO8E,IAORgC,EAAU4D,GAAO5D,QAAU,SAAUpJ,GACpC,GAAIwP,GACHhO,EAAM,GACNY,EAAI,EACJ5B,EAAWR,EAAKQ,QAEjB,IAAMA,GAMC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAGjE,GAAiC,gBAArBR,GAAK+R,YAChB,MAAO/R,GAAK+R,WAGZ,KAAM/R,EAAOA,EAAKgQ,WAAYhQ,EAAMA,EAAOA,EAAKkP,YAC/C1N,GAAO4H,EAASpJ,OAGZ,IAAkB,IAAbQ,GAA+B,IAAbA,EAC7B,MAAOR,GAAKgS,cAhBZ,MAASxC,EAAOxP,EAAKoC,GAAKA,IAEzBZ,GAAO4H,EAASoG,EAkBlB,OAAOhO,IAGR2H,EAAO6D,GAAOiF,WAGb7D,YAAa,GAEb8D,aAAc5D,GAEdvO,MAAO4L,EAEPkD,cAEAxO,QAEA8R,UACCC,KAAOC,IAAK,aAAcpQ,OAAO,GACjCqQ,KAAOD,IAAK,cACZE,KAAOF,IAAK,kBAAmBpQ,OAAO,GACtCuQ,KAAOH,IAAK,oBAGbI,WACC1G,KAAQ,SAAUhM,GAUjB,MATAA,GAAM,GAAKA,EAAM,GAAGyD,QAASgJ,GAAWC,IAGxC1M,EAAM,IAAOA,EAAM,IAAMA,EAAM,IAAM,IAAKyD,QAASgJ,GAAWC,IAE5C,OAAb1M,EAAM,KACVA,EAAM,GAAK,IAAMA,EAAM,GAAK,KAGtBA,EAAMzC,MAAO,EAAG,IAGxB2O,MAAS,SAAUlM,GA6BlB,MAlBAA,GAAM,GAAKA,EAAM,GAAGgH,cAEY,QAA3BhH,EAAM,GAAGzC,MAAO,EAAG,IAEjByC,EAAM,IACXiN,GAAO/H,MAAOlF,EAAM,IAKrBA,EAAM,KAAQA,EAAM,GAAKA,EAAM,IAAMA,EAAM,IAAM,GAAK,GAAmB,SAAbA,EAAM,IAA8B,QAAbA,EAAM,KACzFA,EAAM,KAAUA,EAAM,GAAKA,EAAM,IAAqB,QAAbA,EAAM,KAGpCA,EAAM,IACjBiN,GAAO/H,MAAOlF,EAAM,IAGdA,GAGRiM,OAAU,SAAUjM,GACnB,GAAI2S,GACHC,GAAY5S,EAAM,IAAMA,EAAM,EAE/B,OAAK4L,GAAiB,MAAEjL,KAAMX,EAAM,IAC5B,MAIHA,EAAM,IAAMA,EAAM,KAAO7D,EAC7B6D,EAAM,GAAKA,EAAM,GAGN4S,GAAYlH,EAAQ/K,KAAMiS,KAEpCD,EAASjF,GAAUkF,GAAU,MAE7BD,EAASC,EAASnV,QAAS,IAAKmV,EAASxS,OAASuS,GAAWC,EAASxS,UAGvEJ,EAAM,GAAKA,EAAM,GAAGzC,MAAO,EAAGoV,GAC9B3S,EAAM,GAAK4S,EAASrV,MAAO,EAAGoV,IAIxB3S,EAAMzC,MAAO,EAAG,MAIzB6S,QAECrE,IAAO,SAAU8G,GAChB,GAAI9L,GAAW8L,EAAiBpP,QAASgJ,GAAWC,IAAY1F,aAChE,OAA4B,MAArB6L,EACN,WAAa,OAAO,GACpB,SAAU5S,GACT,MAAOA,GAAK8G,UAAY9G,EAAK8G,SAASC,gBAAkBD,IAI3D+E,MAAS,SAAU+D,GAClB,GAAIiD,GAAU5I,EAAY2F,EAAY,IAEtC,OAAOiD,KACLA,EAAczH,OAAQ,MAAQL,EAAa,IAAM6E,EAAY,IAAM7E,EAAa,SACjFd,EAAY2F,EAAW,SAAU5P,GAChC,MAAO6S,GAAQnS,KAAgC,gBAAnBV,GAAK4P,WAA0B5P,EAAK4P,iBAAoB5P,GAAK0N,eAAiBjD,GAAgBzK,EAAK0N,aAAa,UAAY,OAI3J3B,KAAQ,SAAUhJ,EAAM+P,EAAUC,GACjC,MAAO,UAAU/S,GAChB,GAAIgT,GAAShG,GAAOnM,KAAMb,EAAM+C,EAEhC,OAAe,OAAViQ,EACgB,OAAbF,EAEFA,GAINE,GAAU,GAEU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAOxV,QAASuV,GAChC,OAAbD,EAAoBC,GAASC,EAAOxV,QAASuV,GAAU,GAC1C,OAAbD,EAAoBC,GAASC,EAAO1V,OAAQyV,EAAM5S,UAAa4S,EAClD,OAAbD,GAAsB,IAAME,EAAS,KAAMxV,QAASuV,GAAU,GACjD,OAAbD,EAAoBE,IAAWD,GAASC,EAAO1V,MAAO,EAAGyV,EAAM5S,OAAS,KAAQ4S,EAAQ,KACxF,IAZO,IAgBV9G,MAAS,SAAU3M,EAAM2T,EAAM3D,EAAUrN,EAAOE,GAC/C,GAAI+Q,GAAgC,QAAvB5T,EAAKhC,MAAO,EAAG,GAC3B6V,EAA+B,SAArB7T,EAAKhC,MAAO,IACtB8V,EAAkB,YAATH,CAEV,OAAiB,KAAVhR,GAAwB,IAATE,EAGrB,SAAUnC,GACT,QAASA,EAAKe,YAGf,SAAUf,EAAMhC,EAASiI,GACxB,GAAIkI,GAAOkF,EAAY7D,EAAMR,EAAMsE,EAAWC,EAC7ClB,EAAMa,IAAWC,EAAU,cAAgB,kBAC3CzD,EAAS1P,EAAKe,WACdgC,EAAOqQ,GAAUpT,EAAK8G,SAASC,cAC/ByM,GAAYvN,IAAQmN,CAErB,IAAK1D,EAAS,CAGb,GAAKwD,EAAS,CACb,MAAQb,EAAM,CACb7C,EAAOxP,CACP,OAASwP,EAAOA,EAAM6C,GACrB,GAAKe,EAAS5D,EAAK1I,SAASC,gBAAkBhE,EAAyB,IAAlByM,EAAKhP,SACzD,OAAO,CAIT+S,GAAQlB,EAAe,SAAT/S,IAAoBiU,GAAS,cAE5C,OAAO,EAMR,GAHAA,GAAUJ,EAAUzD,EAAOM,WAAaN,EAAO+D,WAG1CN,GAAWK,EAAW,CAE1BH,EAAa3D,EAAQrM,KAAcqM,EAAQrM,OAC3C8K,EAAQkF,EAAY/T,OACpBgU,EAAYnF,EAAM,KAAOnE,GAAWmE,EAAM,GAC1Ca,EAAOb,EAAM,KAAOnE,GAAWmE,EAAM,GACrCqB,EAAO8D,GAAa5D,EAAO/J,WAAY2N,EAEvC,OAAS9D,IAAS8D,GAAa9D,GAAQA,EAAM6C,KAG3CrD,EAAOsE,EAAY,IAAMC,EAAM3I,MAGhC,GAAuB,IAAlB4E,EAAKhP,YAAoBwO,GAAQQ,IAASxP,EAAO,CACrDqT,EAAY/T,IAAW0K,EAASsJ,EAAWtE,EAC3C,YAKI,IAAKwE,IAAarF,GAASnO,EAAMqD,KAAcrD,EAAMqD,QAAkB/D,KAAW6O,EAAM,KAAOnE,EACrGgF,EAAOb,EAAM,OAKb,OAASqB,IAAS8D,GAAa9D,GAAQA,EAAM6C,KAC3CrD,EAAOsE,EAAY,IAAMC,EAAM3I,MAEhC,IAAOwI,EAAS5D,EAAK1I,SAASC,gBAAkBhE,EAAyB,IAAlByM,EAAKhP,aAAsBwO,IAE5EwE,KACHhE,EAAMnM,KAAcmM,EAAMnM,QAAkB/D,IAAW0K,EAASgF,IAG7DQ,IAASxP,GACb,KAQJ,OADAgP,IAAQ7M,EACD6M,IAAS/M,GAA4B,IAAjB+M,EAAO/M,GAAe+M,EAAO/M,GAAS,KAKrE+J,OAAU,SAAU0H,EAAQpE,GAK3B,GAAI1N,GACH3D,EAAKkL,EAAKgC,QAASuI,IAAYvK,EAAKwK,WAAYD,EAAO3M,gBACtDiG,GAAO/H,MAAO,uBAAyByO,EAKzC,OAAKzV,GAAIoF,GACDpF,EAAIqR,GAIPrR,EAAGkC,OAAS,GAChByB,GAAS8R,EAAQA,EAAQ,GAAIpE,GACtBnG,EAAKwK,WAAW/V,eAAgB8V,EAAO3M,eAC7CuH,GAAa,SAAUrB,EAAMpD,GAC5B,GAAI+J,GACHC,EAAU5V,EAAIgP,EAAMqC,GACpBlN,EAAIyR,EAAQ1T,MACb,OAAQiC,IACPwR,EAAMpW,EAAQ2D,KAAM8L,EAAM4G,EAAQzR,IAClC6K,EAAM2G,KAAW/J,EAAS+J,GAAQC,EAAQzR,MAG5C,SAAUpC,GACT,MAAO/B,GAAI+B,EAAM,EAAG4B,KAIhB3D,IAITkN,SAEC2I,IAAOxF,GAAa,SAAUvQ,GAI7B,GAAIwS,MACHnJ,KACA2M,EAAUzK,EAASvL,EAASyF,QAASlF,EAAO,MAE7C,OAAOyV,GAAS1Q,GACfiL,GAAa,SAAUrB,EAAMpD,EAAS7L,EAASiI,GAC9C,GAAIjG,GACHgU,EAAYD,EAAS9G,EAAM,KAAMhH,MACjC7D,EAAI6K,EAAK9M,MAGV,OAAQiC,KACDpC,EAAOgU,EAAU5R,MACtB6K,EAAK7K,KAAOyH,EAAQzH,GAAKpC,MAI5B,SAAUA,EAAMhC,EAASiI,GAGxB,MAFAsK,GAAM,GAAKvQ,EACX+T,EAASxD,EAAO,KAAMtK,EAAKmB,IACnBA,EAAQwD,SAInBqJ,IAAO3F,GAAa,SAAUvQ,GAC7B,MAAO,UAAUiC,GAChB,MAAOgN,IAAQjP,EAAUiC,GAAOG,OAAS,KAI3C2J,SAAYwE,GAAa,SAAUpH,GAClC,MAAO,UAAUlH,GAChB,OAASA,EAAK+R,aAAe/R,EAAKkU,WAAa9K,EAASpJ,IAASxC,QAAS0J,GAAS,MAWrFiN,KAAQ7F,GAAc,SAAU6F,GAM/B,MAJMzI,GAAYhL,KAAKyT,GAAQ,KAC9BnH,GAAO/H,MAAO,qBAAuBkP,GAEtCA,EAAOA,EAAK3Q,QAASgJ,GAAWC,IAAY1F,cACrC,SAAU/G,GAChB,GAAIoU,EACJ,GACC,IAAMA,EAAW1K,EAChB1J,EAAKmU,KACLnU,EAAK0N,aAAa,aAAe1N,EAAK0N,aAAa,QAGnD,MADA0G,GAAWA,EAASrN,cACbqN,IAAaD,GAA2C,IAAnCC,EAAS5W,QAAS2W,EAAO,YAE5CnU,EAAOA,EAAKe,aAAiC,IAAlBf,EAAKQ,SAC3C,QAAO,KAKT0C,OAAU,SAAUlD,GACnB,GAAIqU,GAAOpY,EAAOK,UAAYL,EAAOK,SAAS+X,IAC9C,OAAOA,IAAQA,EAAK/W,MAAO,KAAQ0C,EAAKgB,IAGzCsT,KAAQ,SAAUtU,GACjB,MAAOA,KAASxD,GAGjB+X,MAAS,SAAUvU,GAClB,MAAOA,KAASzD,EAASiY,iBAAmBjY,EAASkY,UAAYlY,EAASkY,gBAAkBzU,EAAKV,MAAQU,EAAK0U,OAAS1U,EAAK2U,WAI7HC,QAAW,SAAU5U,GACpB,MAAOA,GAAK6U,YAAa,GAG1BA,SAAY,SAAU7U,GACrB,MAAOA,GAAK6U,YAAa,GAG1BC,QAAW,SAAU9U,GAGpB,GAAI8G,GAAW9G,EAAK8G,SAASC,aAC7B,OAAqB,UAAbD,KAA0B9G,EAAK8U,SAA0B,WAAbhO,KAA2B9G,EAAK+U,UAGrFA,SAAY,SAAU/U,GAOrB,MAJKA,GAAKe,YACTf,EAAKe,WAAWiU,cAGVhV,EAAK+U,YAAa,GAI1BE,MAAS,SAAUjV,GAMlB,IAAMA,EAAOA,EAAKgQ,WAAYhQ,EAAMA,EAAOA,EAAKkP,YAC/C,GAAKlP,EAAK8G,SAAW,KAAyB,IAAlB9G,EAAKQ,UAAoC,IAAlBR,EAAKQ,SACvD,OAAO,CAGT,QAAO,GAGRkP,OAAU,SAAU1P,GACnB,OAAQmJ,EAAKgC,QAAe,MAAGnL,IAIhCkV,OAAU,SAAUlV,GACnB,MAAOsM,IAAQ5L,KAAMV,EAAK8G,WAG3ByJ,MAAS,SAAUvQ,GAClB,MAAOqM,IAAQ3L,KAAMV,EAAK8G,WAG3BqO,OAAU,SAAUnV,GACnB,GAAI+C,GAAO/C,EAAK8G,SAASC,aACzB,OAAgB,UAAThE,GAAkC,WAAd/C,EAAKV,MAA8B,WAATyD,GAGtDmE,KAAQ,SAAUlH,GACjB,GAAIa,EAGJ,OAAuC,UAAhCb,EAAK8G,SAASC,eACN,SAAd/G,EAAKV,OACmC,OAArCuB,EAAOb,EAAK0N,aAAa,UAAoB7M,EAAKkG,gBAAkB/G,EAAKV,OAI9E2C,MAASoN,GAAuB,WAC/B,OAAS,KAGVlN,KAAQkN,GAAuB,SAAUE,EAAcpP,GACtD,OAASA,EAAS,KAGnB+B,GAAMmN,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,OAAoB,EAAXA,EAAeA,EAAWnP,EAASmP,KAG7C8F,KAAQ/F,GAAuB,SAAUE,EAAcpP,GACtD,GAAIiC,GAAI,CACR,MAAYjC,EAAJiC,EAAYA,GAAK,EACxBmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGR8F,IAAOhG,GAAuB,SAAUE,EAAcpP,GACrD,GAAIiC,GAAI,CACR,MAAYjC,EAAJiC,EAAYA,GAAK,EACxBmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGR+F,GAAMjG,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,GAAIlN,GAAe,EAAXkN,EAAeA,EAAWnP,EAASmP,CAC3C,QAAUlN,GAAK,GACdmN,EAAanS,KAAMgF,EAEpB,OAAOmN,KAGRgG,GAAMlG,GAAuB,SAAUE,EAAcpP,EAAQmP,GAC5D,GAAIlN,GAAe,EAAXkN,EAAeA,EAAWnP,EAASmP,CAC3C,MAAcnP,IAAJiC,GACTmN,EAAanS,KAAMgF,EAEpB,OAAOmN,OAKVpG,EAAKgC,QAAa,IAAIhC,EAAKgC,QAAY,EAGvC,KAAM/I,KAAOoT,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5EzM,EAAKgC,QAAS/I,GAAM+M,GAAmB/M,EAExC,KAAMA,KAAOyT,QAAQ,EAAMC,OAAO,GACjC3M,EAAKgC,QAAS/I,GAAMgN,GAAoBhN,EAIzC,SAASuR,OACTA,GAAW/T,UAAYuJ,EAAK4M,QAAU5M,EAAKgC,QAC3ChC,EAAKwK,WAAa,GAAIA,GAEtB,SAASlG,IAAU1P,EAAUiY,GAC5B,GAAInC,GAAS9T,EAAOkW,EAAQ3W,EAC3B4W,EAAO/I,EAAQgJ,EACfC,EAASjM,EAAYpM,EAAW,IAEjC,IAAKqY,EACJ,MAAOJ,GAAY,EAAII,EAAO9Y,MAAO,EAGtC4Y,GAAQnY,EACRoP,KACAgJ,EAAahN,EAAKsJ,SAElB,OAAQyD,EAAQ,GAGTrC,IAAY9T,EAAQsL,EAAOjL,KAAM8V,OACjCnW,IAEJmW,EAAQA,EAAM5Y,MAAOyC,EAAM,GAAGI,SAAY+V,GAE3C/I,EAAO/P,KAAM6Y,OAGdpC,GAAU,GAGJ9T,EAAQuL,EAAalL,KAAM8V,MAChCrC,EAAU9T,EAAMsO,QAChB4H,EAAO7Y,MACN4J,MAAO6M,EAEPvU,KAAMS,EAAM,GAAGyD,QAASlF,EAAO,OAEhC4X,EAAQA,EAAM5Y,MAAOuW,EAAQ1T,QAI9B,KAAMb,IAAQ6J,GAAKgH,SACZpQ,EAAQ4L,EAAWrM,GAAOc,KAAM8V,KAAcC,EAAY7W,MAC9DS,EAAQoW,EAAY7W,GAAQS,MAC7B8T,EAAU9T,EAAMsO,QAChB4H,EAAO7Y,MACN4J,MAAO6M,EACPvU,KAAMA,EACNuK,QAAS9J,IAEVmW,EAAQA,EAAM5Y,MAAOuW,EAAQ1T,QAI/B,KAAM0T,EACL,MAOF,MAAOmC,GACNE,EAAM/V,OACN+V,EACClJ,GAAO/H,MAAOlH,GAEdoM,EAAYpM,EAAUoP,GAAS7P,MAAO,GAGzC,QAASsQ,IAAYqI,GACpB,GAAI7T,GAAI,EACPC,EAAM4T,EAAO9V,OACbpC,EAAW,EACZ,MAAYsE,EAAJD,EAASA,IAChBrE,GAAYkY,EAAO7T,GAAG4E,KAEvB,OAAOjJ,GAGR,QAASsY,IAAetC,EAASuC,EAAYC,GAC5C,GAAIlE,GAAMiE,EAAWjE,IACpBmE,EAAmBD,GAAgB,eAARlE,EAC3BoE,EAAW3U,GAEZ,OAAOwU,GAAWrU,MAEjB,SAAUjC,EAAMhC,EAASiI,GACxB,MAASjG,EAAOA,EAAMqS,GACrB,GAAuB,IAAlBrS,EAAKQ,UAAkBgW,EAC3B,MAAOzC,GAAS/T,EAAMhC,EAASiI,IAMlC,SAAUjG,EAAMhC,EAASiI,GACxB,GAAIb,GAAM+I,EAAOkF,EAChBqD,EAAS1M,EAAU,IAAMyM,CAG1B,IAAKxQ,GACJ,MAASjG,EAAOA,EAAMqS,GACrB,IAAuB,IAAlBrS,EAAKQ,UAAkBgW,IACtBzC,EAAS/T,EAAMhC,EAASiI,GAC5B,OAAO,MAKV,OAASjG,EAAOA,EAAMqS,GACrB,GAAuB,IAAlBrS,EAAKQ,UAAkBgW,EAE3B,GADAnD,EAAarT,EAAMqD,KAAcrD,EAAMqD,QACjC8K,EAAQkF,EAAYhB,KAAUlE,EAAM,KAAOuI,GAChD,IAAMtR,EAAO+I,EAAM,OAAQ,GAAQ/I,IAAS8D,EAC3C,MAAO9D,MAAS,MAKjB,IAFA+I,EAAQkF,EAAYhB,IAAUqE,GAC9BvI,EAAM,GAAK4F,EAAS/T,EAAMhC,EAASiI,IAASiD,EACvCiF,EAAM,MAAO,EACjB,OAAO,GASf,QAASwI,IAAgBC,GACxB,MAAOA,GAASzW,OAAS,EACxB,SAAUH,EAAMhC,EAASiI,GACxB,GAAI7D,GAAIwU,EAASzW,MACjB,OAAQiC,IACP,IAAMwU,EAASxU,GAAIpC,EAAMhC,EAASiI,GACjC,OAAO,CAGT,QAAO,GAER2Q,EAAS,GAGX,QAASC,IAAU7C,EAAWzR,EAAK4N,EAAQnS,EAASiI,GACnD,GAAIjG,GACH8W,KACA1U,EAAI,EACJC,EAAM2R,EAAU7T,OAChB4W,EAAgB,MAAPxU,CAEV,MAAYF,EAAJD,EAASA,KACVpC,EAAOgU,EAAU5R,OAChB+N,GAAUA,EAAQnQ,EAAMhC,EAASiI,MACtC6Q,EAAa1Z,KAAM4C,GACd+W,GACJxU,EAAInF,KAAMgF,GAMd,OAAO0U,GAGR,QAASE,IAAYvE,EAAW1U,EAAUgW,EAASkD,EAAYC,EAAYC,GAO1E,MANKF,KAAeA,EAAY5T,KAC/B4T,EAAaD,GAAYC,IAErBC,IAAeA,EAAY7T,KAC/B6T,EAAaF,GAAYE,EAAYC,IAE/B7I,GAAa,SAAUrB,EAAM7F,EAASpJ,EAASiI,GACrD,GAAImR,GAAMhV,EAAGpC,EACZqX,KACAC,KACAC,EAAcnQ,EAAQjH,OAGtBoB,EAAQ0L,GAAQuK,GAAkBzZ,GAAY,IAAKC,EAAQwC,UAAaxC,GAAYA,MAGpFyZ,GAAYhF,IAAexF,GAASlP,EAEnCwD,EADAsV,GAAUtV,EAAO8V,EAAQ5E,EAAWzU,EAASiI,GAG9CyR,EAAa3D,EAEZmD,IAAgBjK,EAAOwF,EAAY8E,GAAeN,MAMjD7P,EACDqQ,CAQF,IALK1D,GACJA,EAAS0D,EAAWC,EAAY1Z,EAASiI,GAIrCgR,EAAa,CACjBG,EAAOP,GAAUa,EAAYJ,GAC7BL,EAAYG,KAAUpZ,EAASiI,GAG/B7D,EAAIgV,EAAKjX,MACT,OAAQiC,KACDpC,EAAOoX,EAAKhV,MACjBsV,EAAYJ,EAAQlV,MAASqV,EAAWH,EAAQlV,IAAOpC,IAK1D,GAAKiN,GACJ,GAAKiK,GAAczE,EAAY,CAC9B,GAAKyE,EAAa,CAEjBE,KACAhV,EAAIsV,EAAWvX,MACf,OAAQiC,KACDpC,EAAO0X,EAAWtV,KAEvBgV,EAAKha,KAAOqa,EAAUrV,GAAKpC,EAG7BkX,GAAY,KAAOQ,KAAkBN,EAAMnR,GAI5C7D,EAAIsV,EAAWvX,MACf,OAAQiC,KACDpC,EAAO0X,EAAWtV,MACtBgV,EAAOF,EAAa1Z,EAAQ2D,KAAM8L,EAAMjN,GAASqX,EAAOjV,IAAM,KAE/D6K,EAAKmK,KAAUhQ,EAAQgQ,GAAQpX,SAOlC0X,GAAab,GACZa,IAAetQ,EACdsQ,EAAWhV,OAAQ6U,EAAaG,EAAWvX,QAC3CuX,GAEGR,EACJA,EAAY,KAAM9P,EAASsQ,EAAYzR,GAEvC7I,EAAK2E,MAAOqF,EAASsQ,KAMzB,QAASC,IAAmB1B,GAC3B,GAAI2B,GAAc7D,EAASzR,EAC1BD,EAAM4T,EAAO9V,OACb0X,EAAkB1O,EAAKgJ,SAAU8D,EAAO,GAAG3W,MAC3CwY,EAAmBD,GAAmB1O,EAAKgJ,SAAS,KACpD/P,EAAIyV,EAAkB,EAAI,EAG1BE,EAAe1B,GAAe,SAAUrW,GACvC,MAAOA,KAAS4X,GACdE,GAAkB,GACrBE,EAAkB3B,GAAe,SAAUrW,GAC1C,MAAOxC,GAAQ2D,KAAMyW,EAAc5X,GAAS,IAC1C8X,GAAkB,GACrBlB,GAAa,SAAU5W,EAAMhC,EAASiI,GACrC,OAAU4R,IAAqB5R,GAAOjI,IAAYuL,MAChDqO,EAAe5Z,GAASwC,SACxBuX,EAAc/X,EAAMhC,EAASiI,GAC7B+R,EAAiBhY,EAAMhC,EAASiI,KAGpC,MAAY5D,EAAJD,EAASA,IAChB,GAAM2R,EAAU5K,EAAKgJ,SAAU8D,EAAO7T,GAAG9C,MACxCsX,GAAaP,GAAcM,GAAgBC,GAAY7C,QACjD,CAIN,GAHAA,EAAU5K,EAAKgH,OAAQ8F,EAAO7T,GAAG9C,MAAOyC,MAAO,KAAMkU,EAAO7T,GAAGyH,SAG1DkK,EAAS1Q,GAAY,CAGzB,IADAf,IAAMF,EACMC,EAAJC,EAASA,IAChB,GAAK6G,EAAKgJ,SAAU8D,EAAO3T,GAAGhD,MAC7B,KAGF,OAAO0X,IACN5U,EAAI,GAAKuU,GAAgBC,GACzBxU,EAAI,GAAKwL,GAERqI,EAAO3Y,MAAO,EAAG8E,EAAI,GAAIlF,QAAS8J,MAAgC,MAAzBiP,EAAQ7T,EAAI,GAAI9C,KAAe,IAAM,MAC7EkE,QAASlF,EAAO,MAClByV,EACIzR,EAAJF,GAASuV,GAAmB1B,EAAO3Y,MAAO8E,EAAGE,IACzCD,EAAJC,GAAWqV,GAAoB1B,EAASA,EAAO3Y,MAAOgF,IAClDD,EAAJC,GAAWsL,GAAYqI,IAGzBW,EAASxZ,KAAM2W,GAIjB,MAAO4C,IAAgBC,GAGxB,QAASqB,IAA0BC,EAAiBC,GAEnD,GAAIC,GAAoB,EACvBC,EAAQF,EAAYhY,OAAS,EAC7BmY,EAAYJ,EAAgB/X,OAAS,EACrCoY,EAAe,SAAUtL,EAAMjP,EAASiI,EAAKmB,EAASoR,GACrD,GAAIxY,GAAMsC,EAAGyR,EACZ0E,KACAC,EAAe,EACftW,EAAI,IACJ4R,EAAY/G,MACZ0L,EAA6B,MAAjBH,EACZI,EAAgBrP,EAEhBhI,EAAQ0L,GAAQqL,GAAanP,EAAK9I,KAAU,IAAG,IAAKmY,GAAiBxa,EAAQ+C,YAAc/C,GAE3F6a,EAAiB7O,GAA4B,MAAjB4O,EAAwB,EAAItV,KAAKC,UAAY,EAS1E,KAPKoV,IACJpP,EAAmBvL,IAAYzB,GAAYyB,EAC3CkL,EAAakP,GAKe,OAApBpY,EAAOuB,EAAMa,IAAaA,IAAM,CACxC,GAAKkW,GAAatY,EAAO,CACxBsC,EAAI,CACJ,OAASyR,EAAUmE,EAAgB5V,KAClC,GAAKyR,EAAS/T,EAAMhC,EAASiI,GAAQ,CACpCmB,EAAQhK,KAAM4C,EACd,OAGG2Y,IACJ3O,EAAU6O,EACV3P,IAAekP,GAKZC,KAEErY,GAAQ+T,GAAW/T,IACxB0Y,IAIIzL,GACJ+G,EAAU5W,KAAM4C,IAOnB,GADA0Y,GAAgBtW,EACXiW,GAASjW,IAAMsW,EAAe,CAClCpW,EAAI,CACJ,OAASyR,EAAUoE,EAAY7V,KAC9ByR,EAASC,EAAWyE,EAAYza,EAASiI,EAG1C,IAAKgH,EAAO,CAEX,GAAKyL,EAAe,EACnB,MAAQtW,IACA4R,EAAU5R,IAAMqW,EAAWrW,KACjCqW,EAAWrW,GAAKwI,EAAIzJ,KAAMiG,GAM7BqR,GAAa5B,GAAU4B,GAIxBrb,EAAK2E,MAAOqF,EAASqR,GAGhBE,IAAc1L,GAAQwL,EAAWtY,OAAS,GAC5CuY,EAAeP,EAAYhY,OAAW,GAExC6M,GAAO2E,WAAYvK,GAUrB,MALKuR,KACJ3O,EAAU6O,EACVtP,EAAmBqP,GAGb5E,EAGT,OAAOqE,GACN/J,GAAciK,GACdA,EAGFjP,EAAU0D,GAAO1D,QAAU,SAAUvL,EAAU+a,GAC9C,GAAI1W,GACH+V,KACAD,KACA9B,EAAShM,EAAerM,EAAW,IAEpC,KAAMqY,EAAS,CAER0C,IACLA,EAAQrL,GAAU1P,IAEnBqE,EAAI0W,EAAM3Y,MACV,OAAQiC,IACPgU,EAASuB,GAAmBmB,EAAM1W,IAC7BgU,EAAQ/S,GACZ8U,EAAY/a,KAAMgZ,GAElB8B,EAAgB9a,KAAMgZ,EAKxBA,GAAShM,EAAerM,EAAUka,GAA0BC,EAAiBC,IAE9E,MAAO/B,GAGR,SAASoB,IAAkBzZ,EAAUgb,EAAU3R,GAC9C,GAAIhF,GAAI,EACPC,EAAM0W,EAAS5Y,MAChB,MAAYkC,EAAJD,EAASA,IAChB4K,GAAQjP,EAAUgb,EAAS3W,GAAIgF,EAEhC,OAAOA,GAGR,QAAS6G,IAAQlQ,EAAUC,EAASoJ,EAAS6F,GAC5C,GAAI7K,GAAG6T,EAAQ+C,EAAO1Z,EAAMe,EAC3BN,EAAQ0N,GAAU1P,EAEnB,KAAMkP,GAEiB,IAAjBlN,EAAMI,OAAe,CAIzB,GADA8V,EAASlW,EAAM,GAAKA,EAAM,GAAGzC,MAAO,GAC/B2Y,EAAO9V,OAAS,GAAkC,QAA5B6Y,EAAQ/C,EAAO,IAAI3W,MAC5CwF,EAAQmL,SAAgC,IAArBjS,EAAQwC,UAAkBkJ,GAC7CP,EAAKgJ,SAAU8D,EAAO,GAAG3W,MAAS,CAGnC,GADAtB,GAAYmL,EAAK9I,KAAS,GAAG2Y,EAAMnP,QAAQ,GAAGrG,QAAQgJ,GAAWC,IAAYzO,QAAkB,IACzFA,EACL,MAAOoJ,EAERrJ,GAAWA,EAAST,MAAO2Y,EAAO5H,QAAQrH,MAAM7G,QAIjDiC,EAAIuJ,EAAwB,aAAEjL,KAAM3C,GAAa,EAAIkY,EAAO9V,MAC5D,OAAQiC,IAAM,CAIb,GAHA4W,EAAQ/C,EAAO7T,GAGV+G,EAAKgJ,SAAW7S,EAAO0Z,EAAM1Z,MACjC,KAED,KAAMe,EAAO8I,EAAK9I,KAAMf,MAEjB2N,EAAO5M,EACZ2Y,EAAMnP,QAAQ,GAAGrG,QAASgJ,GAAWC,IACrClB,EAAS7K,KAAMuV,EAAO,GAAG3W,OAAUtB,EAAQ+C,YAAc/C,IACrD,CAKJ,GAFAiY,EAAOvT,OAAQN,EAAG,GAClBrE,EAAWkP,EAAK9M,QAAUyN,GAAYqI,IAChClY,EAEL,MADAX,GAAK2E,MAAOqF,EAAS6F,GACd7F,CAGR,SAgBL,MAPAkC,GAASvL,EAAUgC,GAClBkN,EACAjP,GACC0L,EACDtC,EACAmE,EAAS7K,KAAM3C,IAETqJ,EAMRtC,EAAQgN,WAAazO,EAAQ4F,MAAM,IAAIxG,KAAM6H,GAAYuD,KAAK,MAAQxK,EAItEyB,EAAQ+M,iBAAmBxH,EAG3BZ,IAIA3E,EAAQoM,aAAe3C,GAAO,SAAU0K,GAEvC,MAAuE,GAAhEA,EAAKnI,wBAAyBvU,EAASiJ,cAAc,UAMvD+I,GAAO,SAAUC,GAEtB,MADAA,GAAIuB,UAAY,mBAC+B,MAAxCvB,EAAIwB,WAAWtC,aAAa,WAEnCgB,GAAW,yBAA0B,SAAU1O,EAAM+C,EAAMsG,GAC1D,MAAMA,GAAN,EACQrJ,EAAK0N,aAAc3K,EAA6B,SAAvBA,EAAKgE,cAA2B,EAAI,KAOjEjC,EAAQoG,YAAeqD,GAAO,SAAUC,GAG7C,MAFAA,GAAIuB,UAAY,WAChBvB,EAAIwB,WAAWrC,aAAc,QAAS,IACY,KAA3Ca,EAAIwB,WAAWtC,aAAc,YAEpCgB,GAAW,QAAS,SAAU1O,EAAM+C,EAAMsG,GACzC,MAAMA,IAAyC,UAAhCrJ,EAAK8G,SAASC,cAA7B,EACQ/G,EAAKkZ,eAOT3K,GAAO,SAAUC,GACtB,MAAuC,OAAhCA,EAAId,aAAa,eAExBgB,GAAW5D,EAAU,SAAU9K,EAAM+C,EAAMsG,GAC1C,GAAIoI,EACJ,OAAMpI,GAAN,GACSoI,EAAMzR,EAAKqQ,iBAAkBtN,KAAW0O,EAAIC,UACnDD,EAAIzK,MACJhH,EAAM+C,MAAW,EAAOA,EAAKgE,cAAgB,OAKjDpK,EAAO0D,KAAO2M,GACdrQ,EAAO4U,KAAOvE,GAAOiF,UACrBtV,EAAO4U,KAAK,KAAO5U,EAAO4U,KAAKpG,QAC/BxO,EAAOwc,OAASnM,GAAO2E,WACvBhV,EAAOuK,KAAO8F,GAAO5D,QACrBzM,EAAOyc,SAAWpM,GAAO3D,MACzB1M,EAAOmN,SAAWkD,GAAOlD,UAGrB7N,EAEJ,IAAIod,KAGJ,SAASC,GAAetW,GACvB,GAAIuW,GAASF,EAAcrW,KAI3B,OAHArG,GAAO+E,KAAMsB,EAAQjD,MAAO1B,OAAwB,SAAUqO,EAAG8M,GAChED,EAAQC,IAAS,IAEXD,EAyBR5c,EAAO8c,UAAY,SAAUzW,GAI5BA,EAA6B,gBAAZA,GACdqW,EAAcrW,IAAasW,EAAetW,GAC5CrG,EAAOgG,UAAYK,EAEpB,IACC0W,GAEAC,EAEAC,EAEAC,EAEAC,EAEAC,EAEAC,KAEAC,GAASjX,EAAQkX,SAEjBC,EAAO,SAAU/U,GAOhB,IANAuU,EAAS3W,EAAQ2W,QAAUvU,EAC3BwU,GAAQ,EACRE,EAAcC,GAAe,EAC7BA,EAAc,EACdF,EAAeG,EAAK7Z,OACpBuZ,GAAS,EACDM,GAAsBH,EAAdC,EAA4BA,IAC3C,GAAKE,EAAMF,GAAc/X,MAAOqD,EAAM,GAAKA,EAAM,OAAU,GAASpC,EAAQoX,YAAc,CACzFT,GAAS,CACT,OAGFD,GAAS,EACJM,IACCC,EACCA,EAAM9Z,QACVga,EAAMF,EAAM5L,SAEFsL,EACXK,KAEAK,EAAKC,YAKRD,GAECE,IAAK,WACJ,GAAKP,EAAO,CAEX,GAAIzG,GAAQyG,EAAK7Z,QACjB,QAAUoa,GAAK3Y,GACdjF,EAAO+E,KAAME,EAAM,SAAU8K,EAAG7E,GAC/B,GAAIvI,GAAO3C,EAAO2C,KAAMuI,EACV,cAATvI,EACE0D,EAAQmW,QAAWkB,EAAKpG,IAAKpM,IAClCmS,EAAK5c,KAAMyK,GAEDA,GAAOA,EAAI1H,QAAmB,WAATb,GAEhCib,EAAK1S,OAGJ7F,WAGC0X,EACJG,EAAeG,EAAK7Z,OAGTwZ,IACXI,EAAcxG,EACd4G,EAAMR,IAGR,MAAO1Z,OAGRyF,OAAQ,WAkBP,MAjBKsU,IACJrd,EAAO+E,KAAMM,UAAW,SAAU0K,EAAG7E,GACpC,GAAI2S,EACJ,QAASA,EAAQ7d,EAAO2K,QAASO,EAAKmS,EAAMQ,IAAY,GACvDR,EAAKtX,OAAQ8X,EAAO,GAEfd,IACUG,GAATW,GACJX,IAEaC,GAATU,GACJV,OAME7Z,MAIRgU,IAAK,SAAUhW,GACd,MAAOA,GAAKtB,EAAO2K,QAASrJ,EAAI+b,GAAS,MAASA,IAAQA,EAAK7Z,SAGhE8U,MAAO,WAGN,MAFA+E,MACAH,EAAe,EACR5Z,MAGRqa,QAAS,WAER,MADAN,GAAOC,EAAQN,EAASzd,EACjB+D,MAGR4U,SAAU,WACT,OAAQmF,GAGTS,KAAM,WAKL,MAJAR,GAAQ/d,EACFyd,GACLU,EAAKC,UAECra,MAGRya,OAAQ,WACP,OAAQT,GAGTU,SAAU,SAAU3c,EAAS4D,GAU5B,OATKoY,GAAWJ,IAASK,IACxBrY,EAAOA,MACPA,GAAS5D,EAAS4D,EAAKtE,MAAQsE,EAAKtE,QAAUsE,GACzC8X,EACJO,EAAM7c,KAAMwE,GAEZuY,EAAMvY,IAGD3B,MAGRka,KAAM,WAEL,MADAE,GAAKM,SAAU1a,KAAM+B,WACd/B,MAGR2Z,MAAO,WACN,QAASA,GAIZ,OAAOS,IAER1d,EAAOgG,QAENgG,SAAU,SAAUiS,GACnB,GAAIC,KAEA,UAAW,OAAQle,EAAO8c,UAAU,eAAgB,aACpD,SAAU,OAAQ9c,EAAO8c,UAAU,eAAgB,aACnD,SAAU,WAAY9c,EAAO8c,UAAU,YAE1CqB,EAAQ,UACRjZ,GACCiZ,MAAO,WACN,MAAOA,IAERC,OAAQ,WAEP,MADAC,GAASlZ,KAAME,WAAYiZ,KAAMjZ,WAC1B/B,MAERib,KAAM,WACL,GAAIC,GAAMnZ,SACV,OAAOrF,GAAOgM,SAAS,SAAUyS,GAChCze,EAAO+E,KAAMmZ,EAAQ,SAAUzY,EAAGiZ,GACjC,GAAIC,GAASD,EAAO,GACnBpd,EAAKtB,EAAOiE,WAAYua,EAAK/Y,KAAS+Y,EAAK/Y,EAE5C4Y,GAAUK,EAAM,IAAK,WACpB,GAAIE,GAAWtd,GAAMA,EAAG8D,MAAO9B,KAAM+B,UAChCuZ,IAAY5e,EAAOiE,WAAY2a,EAAS1Z,SAC5C0Z,EAAS1Z,UACPC,KAAMsZ,EAASI,SACfP,KAAMG,EAASK,QACfC,SAAUN,EAASO,QAErBP,EAAUE,EAAS,QAAUrb,OAAS4B,EAAUuZ,EAASvZ,UAAY5B,KAAMhC,GAAOsd,GAAavZ,eAIlGmZ,EAAM,OACJtZ,WAIJA,QAAS,SAAUuC,GAClB,MAAc,OAAPA,EAAczH,EAAOgG,OAAQyB,EAAKvC,GAAYA,IAGvDmZ,IAwCD,OArCAnZ,GAAQ+Z,KAAO/Z,EAAQqZ,KAGvBve,EAAO+E,KAAMmZ,EAAQ,SAAUzY,EAAGiZ,GACjC,GAAIrB,GAAOqB,EAAO,GACjBQ,EAAcR,EAAO,EAGtBxZ,GAASwZ,EAAM,IAAOrB,EAAKO,IAGtBsB,GACJ7B,EAAKO,IAAI,WAERO,EAAQe,GAGNhB,EAAY,EAAJzY,GAAS,GAAIkY,QAASO,EAAQ,GAAK,GAAIJ,MAInDO,EAAUK,EAAM,IAAO,WAEtB,MADAL,GAAUK,EAAM,GAAK,QAAUpb,OAAS+a,EAAWnZ,EAAU5B,KAAM+B,WAC5D/B,MAER+a,EAAUK,EAAM,GAAK,QAAWrB,EAAKW,WAItC9Y,EAAQA,QAASmZ,GAGZJ,GACJA,EAAKzZ,KAAM6Z,EAAUA,GAIfA,GAIRc,KAAM,SAAUC,GACf,GAAI3Z,GAAI,EACP4Z,EAAgB3e,EAAW8D,KAAMa,WACjC7B,EAAS6b,EAAc7b,OAGvB8b,EAAuB,IAAX9b,GAAkB4b,GAAepf,EAAOiE,WAAYmb,EAAYla,SAAc1B,EAAS,EAGnG6a,EAAyB,IAAdiB,EAAkBF,EAAcpf,EAAOgM,WAGlDuT,EAAa,SAAU9Z,EAAG2W,EAAUoD,GACnC,MAAO,UAAUnV,GAChB+R,EAAU3W,GAAMnC,KAChBkc,EAAQ/Z,GAAMJ,UAAU7B,OAAS,EAAI9C,EAAW8D,KAAMa,WAAcgF,EAChEmV,IAAWC,EACdpB,EAASqB,WAAYtD,EAAUoD,KACfF,GAChBjB,EAAS/W,YAAa8U,EAAUoD,KAKnCC,EAAgBE,EAAkBC,CAGnC,IAAKpc,EAAS,EAIb,IAHAic,EAAqB/X,MAAOlE,GAC5Bmc,EAAuBjY,MAAOlE,GAC9Boc,EAAsBlY,MAAOlE,GACjBA,EAAJiC,EAAYA,IACd4Z,EAAe5Z,IAAOzF,EAAOiE,WAAYob,EAAe5Z,GAAIP,SAChEma,EAAe5Z,GAAIP,UACjBC,KAAMoa,EAAY9Z,EAAGma,EAAiBP,IACtCf,KAAMD,EAASS,QACfC,SAAUQ,EAAY9Z,EAAGka,EAAkBF,MAE3CH,CAUL,OAJMA,IACLjB,EAAS/W,YAAasY,EAAiBP,GAGjChB,EAASnZ,aAGlBlF,EAAOmI,QAAU,SAAWA,GAE3B,GAAI9F,GAAKuL,EAAGgG,EAAOtC,EAAQuO,EAAUC,EAAKC,EAAWC,EAAava,EACjEoM,EAAMjS,EAASiJ,cAAc,MAS9B,IANAgJ,EAAIb,aAAc,YAAa,KAC/Ba,EAAIuB,UAAY,qEAGhB/Q,EAAMwP,EAAIhI,qBAAqB,SAC/B+D,EAAIiE,EAAIhI,qBAAqB,KAAM,IAC7B+D,IAAMA,EAAE7B,QAAU1J,EAAImB,OAC3B,MAAO2E,EAIRmJ,GAAS1R,EAASiJ,cAAc,UAChCiX,EAAMxO,EAAO4B,YAAatT,EAASiJ,cAAc,WACjD+K,EAAQ/B,EAAIhI,qBAAqB,SAAU,GAE3C+D,EAAE7B,MAAMkU,QAAU,gCAGlB9X,EAAQ+X,gBAAoC,MAAlBrO,EAAIoB,UAG9B9K,EAAQgY,kBAAgD,IAA5BtO,EAAIwB,WAAWxP,SAI3CsE,EAAQiY,OAASvO,EAAIhI,qBAAqB,SAASrG,OAInD2E,EAAQkY,gBAAkBxO,EAAIhI,qBAAqB,QAAQrG,OAI3D2E,EAAQ4D,MAAQ,MAAMhI,KAAM6J,EAAEmD,aAAa,UAI3C5I,EAAQmY,eAA4C,OAA3B1S,EAAEmD,aAAa,QAKxC5I,EAAQoY,QAAU,OAAOxc,KAAM6J,EAAE7B,MAAMwU,SAIvCpY,EAAQqY,WAAa5S,EAAE7B,MAAMyU,SAG7BrY,EAAQsY,UAAY7M,EAAMvJ,MAI1BlC,EAAQuY,YAAcZ,EAAI1H,SAG1BjQ,EAAQwY,UAAY/gB,EAASiJ,cAAc,QAAQ8X,QAInDxY,EAAQyY,WAA2E,kBAA9DhhB,EAASiJ,cAAc,OAAOgY,WAAW,GAAOC,UAGrE3Y,EAAQ4Y,wBAAyB,EACjC5Y,EAAQ6Y,kBAAmB,EAC3B7Y,EAAQ8Y,eAAgB,EACxB9Y,EAAQ+Y,eAAgB,EACxB/Y,EAAQgZ,cAAe,EACvBhZ,EAAQiZ,qBAAsB,EAC9BjZ,EAAQkZ,mBAAoB,EAG5BzN,EAAMuE,SAAU,EAChBhQ,EAAQmZ,eAAiB1N,EAAMiN,WAAW,GAAO1I,QAIjD7G,EAAO4G,UAAW,EAClB/P,EAAQoZ,aAAezB,EAAI5H,QAG3B,WACQrG,GAAI9N,KACV,MAAOmE,GACRC,EAAQ+Y,eAAgB,EAIzBtN,EAAQhU,EAASiJ,cAAc,SAC/B+K,EAAM5C,aAAc,QAAS,IAC7B7I,EAAQyL,MAA0C,KAAlCA,EAAM7C,aAAc,SAGpC6C,EAAMvJ,MAAQ,IACduJ,EAAM5C,aAAc,OAAQ,SAC5B7I,EAAQqZ,WAA6B,MAAhB5N,EAAMvJ,MAG3BuJ,EAAM5C,aAAc,UAAW,KAC/B4C,EAAM5C,aAAc,OAAQ,KAE5B6O,EAAWjgB,EAAS6hB,yBACpB5B,EAAS3M,YAAaU,GAItBzL,EAAQuZ,cAAgB9N,EAAMuE,QAG9BhQ,EAAQwZ,WAAa9B,EAASgB,WAAW,GAAOA,WAAW,GAAO/J,UAAUqB,QAKvEtG,EAAI5F,cACR4F,EAAI5F,YAAa,UAAW,WAC3B9D,EAAQgZ,cAAe,IAGxBtP,EAAIgP,WAAW,GAAOe,QAKvB,KAAMnc,KAAOyT,QAAQ,EAAM2I,QAAQ,EAAMC,SAAS,GACjDjQ,EAAIb,aAAc+O,EAAY,KAAOta,EAAG,KAExC0C,EAAS1C,EAAI,WAAcsa,IAAazgB,IAAUuS,EAAItD,WAAYwR,GAAYrZ,WAAY,CAG3FmL,GAAI9F,MAAMgW,eAAiB,cAC3BlQ,EAAIgP,WAAW,GAAO9U,MAAMgW,eAAiB,GAC7C5Z,EAAQ6Z,gBAA+C,gBAA7BnQ,EAAI9F,MAAMgW,cAIpC,KAAMtc,IAAKzF,GAAQmI,GAClB,KAoGD,OAlGAA,GAAQC,QAAgB,MAAN3C,EAGlBzF,EAAO,WACN,GAAIiiB,GAAWC,EAAWC,EACzBC,EAAW,+HACXhb,EAAOxH,EAASiK,qBAAqB,QAAQ,EAExCzC,KAKN6a,EAAYriB,EAASiJ,cAAc,OACnCoZ,EAAUlW,MAAMkU,QAAU,gFAE1B7Y,EAAK8L,YAAa+O,GAAY/O,YAAarB,GAS3CA,EAAIuB,UAAY,8CAChB+O,EAAMtQ,EAAIhI,qBAAqB,MAC/BsY,EAAK,GAAIpW,MAAMkU,QAAU,2CACzBD,EAA0C,IAA1BmC,EAAK,GAAIE,aAEzBF,EAAK,GAAIpW,MAAMuW,QAAU,GACzBH,EAAK,GAAIpW,MAAMuW,QAAU,OAIzBna,EAAQoa,sBAAwBvC,GAA2C,IAA1BmC,EAAK,GAAIE,aAG1DxQ,EAAIuB,UAAY,GAChBvB,EAAI9F,MAAMkU,QAAU,wKAIpBjgB,EAAO6L,KAAMzE,EAAyB,MAAnBA,EAAK2E,MAAMyW,MAAiBA,KAAM,MAAU,WAC9Dra,EAAQsa,UAAgC,IAApB5Q,EAAI6Q,cAIpBpjB,EAAOqjB,mBACXxa,EAAQ8Y,cAAuE,QAArD3hB,EAAOqjB,iBAAkB9Q,EAAK,WAAe3F,IACvE/D,EAAQkZ,kBAA2F,SAArE/hB,EAAOqjB,iBAAkB9Q,EAAK,QAAY+Q,MAAO,QAAUA,MAMzFV,EAAYrQ,EAAIqB,YAAatT,EAASiJ,cAAc,QACpDqZ,EAAUnW,MAAMkU,QAAUpO,EAAI9F,MAAMkU,QAAUmC,EAC9CF,EAAUnW,MAAM8W,YAAcX,EAAUnW,MAAM6W,MAAQ,IACtD/Q,EAAI9F,MAAM6W,MAAQ,MAElBza,EAAQiZ,qBACNtZ,YAAcxI,EAAOqjB,iBAAkBT,EAAW,WAAeW,oBAGxDhR,GAAI9F,MAAMyW,OAAS9iB,IAK9BmS,EAAIuB,UAAY,GAChBvB,EAAI9F,MAAMkU,QAAUmC,EAAW,8CAC/Bja,EAAQ4Y,uBAA+C,IAApBlP,EAAI6Q,YAIvC7Q,EAAI9F,MAAMuW,QAAU,QACpBzQ,EAAIuB,UAAY,cAChBvB,EAAIwB,WAAWtH,MAAM6W,MAAQ,MAC7Bza,EAAQ6Y,iBAAyC,IAApBnP,EAAI6Q,YAE5Bva,EAAQ4Y,yBAIZ3Z,EAAK2E,MAAMyW,KAAO,IAIpBpb,EAAK0K,YAAamQ,GAGlBA,EAAYpQ,EAAMsQ,EAAMD,EAAY,QAIrC7f,EAAMiP,EAASuO,EAAWC,EAAMlS,EAAIgG,EAAQ,KAErCzL;KAGR,IAAI2a,GAAS,+BACZC,EAAa,UAEd,SAASC,GAAc3f,EAAM+C,EAAMqC,EAAMwa,GACxC,GAAMjjB,EAAOkjB,WAAY7f,GAAzB,CAIA,GAAIwB,GAAKse,EACRC,EAAcpjB,EAAO0G,QAIrB2c,EAAShgB,EAAKQ,SAId2N,EAAQ6R,EAASrjB,EAAOwR,MAAQnO,EAIhCgB,EAAKgf,EAAShgB,EAAM+f,GAAgB/f,EAAM+f,IAAiBA,CAI5D,IAAO/e,GAAOmN,EAAMnN,KAAS4e,GAAQzR,EAAMnN,GAAIoE,OAAUA,IAASlJ,GAA6B,gBAAT6G,GAgEtF,MA5DM/B,KAIJA,EADIgf,EACChgB,EAAM+f,GAAgBhjB,EAAgB6N,OAASjO,EAAOmL,OAEtDiY,GAID5R,EAAOnN,KAGZmN,EAAOnN,GAAOgf,MAAgBC,OAAQtjB,EAAO8J,QAKzB,gBAAT1D,IAAqC,kBAATA,MAClC6c,EACJzR,EAAOnN,GAAOrE,EAAOgG,OAAQwL,EAAOnN,GAAM+B,GAE1CoL,EAAOnN,GAAKoE,KAAOzI,EAAOgG,OAAQwL,EAAOnN,GAAKoE,KAAMrC,IAItD+c,EAAY3R,EAAOnN,GAKb4e,IACCE,EAAU1a,OACf0a,EAAU1a,SAGX0a,EAAYA,EAAU1a,MAGlBA,IAASlJ,IACb4jB,EAAWnjB,EAAOiK,UAAW7D,IAAWqC,GAKpB,gBAATrC,IAGXvB,EAAMse,EAAW/c,GAGL,MAAPvB,IAGJA,EAAMse,EAAWnjB,EAAOiK,UAAW7D,MAGpCvB,EAAMse,EAGAte,GAGR,QAAS0e,GAAoBlgB,EAAM+C,EAAM6c,GACxC,GAAMjjB,EAAOkjB,WAAY7f,GAAzB,CAIA,GAAI8f,GAAW1d,EACd4d,EAAShgB,EAAKQ,SAGd2N,EAAQ6R,EAASrjB,EAAOwR,MAAQnO,EAChCgB,EAAKgf,EAAShgB,EAAMrD,EAAO0G,SAAY1G,EAAO0G,OAI/C,IAAM8K,EAAOnN,GAAb,CAIA,GAAK+B,IAEJ+c,EAAYF,EAAMzR,EAAOnN,GAAOmN,EAAOnN,GAAKoE,MAE3B,CAGVzI,EAAOyG,QAASL,GAsBrBA,EAAOA,EAAK7F,OAAQP,EAAO4F,IAAKQ,EAAMpG,EAAOiK,YAnBxC7D,IAAQ+c,GACZ/c,GAASA,IAITA,EAAOpG,EAAOiK,UAAW7D,GAExBA,EADIA,IAAQ+c,IACH/c,GAEFA,EAAKkG,MAAM,MAarB7G,EAAIW,EAAK5C,MACT,OAAQiC,UACA0d,GAAW/c,EAAKX,GAKxB,IAAKwd,GAAOO,EAAkBL,IAAcnjB,EAAOqI,cAAc8a,GAChE,QAMGF,UACEzR,GAAOnN,GAAKoE,KAIb+a,EAAmBhS,EAAOnN,QAM5Bgf,EACJrjB,EAAOyjB,WAAapgB,IAAQ,GAIjBrD,EAAOmI,QAAQ+Y,eAAiB1P,GAASA,EAAMlS,aAEnDkS,GAAOnN,GAIdmN,EAAOnN,GAAO,QAIhBrE,EAAOgG,QACNwL,SAIAkS,QACCC,QAAU,EACVC,OAAS,EAEThH,OAAU,8CAGXiH,QAAS,SAAUxgB,GAElB,MADAA,GAAOA,EAAKQ,SAAW7D,EAAOwR,MAAOnO,EAAKrD,EAAO0G,UAAarD,EAAMrD,EAAO0G,WAClErD,IAASmgB,EAAmBngB,IAGtCoF,KAAM,SAAUpF,EAAM+C,EAAMqC,GAC3B,MAAOua,GAAc3f,EAAM+C,EAAMqC,IAGlCqb,WAAY,SAAUzgB,EAAM+C,GAC3B,MAAOmd,GAAoBlgB,EAAM+C,IAIlC2d,MAAO,SAAU1gB,EAAM+C,EAAMqC,GAC5B,MAAOua,GAAc3f,EAAM+C,EAAMqC,GAAM,IAGxCub,YAAa,SAAU3gB,EAAM+C,GAC5B,MAAOmd,GAAoBlgB,EAAM+C,GAAM,IAIxC8c,WAAY,SAAU7f,GAErB,GAAKA,EAAKQ,UAA8B,IAAlBR,EAAKQ,UAAoC,IAAlBR,EAAKQ,SACjD,OAAO,CAGR,IAAI6f,GAASrgB,EAAK8G,UAAYnK,EAAO0jB,OAAQrgB,EAAK8G,SAASC,cAG3D,QAAQsZ,GAAUA,KAAW,GAAQrgB,EAAK0N,aAAa,aAAe2S,KAIxE1jB,EAAOsB,GAAG0E,QACTyC,KAAM,SAAUR,EAAKoC,GACpB,GAAI2H,GAAO5L,EACVqC,EAAO,KACPhD,EAAI,EACJpC,EAAOC,KAAK,EAMb,IAAK2E,IAAQ1I,EAAY,CACxB,GAAK+D,KAAKE,SACTiF,EAAOzI,EAAOyI,KAAMpF,GAEG,IAAlBA,EAAKQ,WAAmB7D,EAAO+jB,MAAO1gB,EAAM,gBAAkB,CAElE,IADA2O,EAAQ3O,EAAKkL,WACDyD,EAAMxO,OAAViC,EAAkBA,IACzBW,EAAO4L,EAAMvM,GAAGW,KAEe,IAA1BA,EAAKvF,QAAQ,WACjBuF,EAAOpG,EAAOiK,UAAW7D,EAAKzF,MAAM,IAEpCsjB,EAAU5gB,EAAM+C,EAAMqC,EAAMrC,IAG9BpG,GAAO+jB,MAAO1gB,EAAM,eAAe,GAIrC,MAAOoF,GAIR,MAAoB,gBAARR,GACJ3E,KAAKyB,KAAK,WAChB/E,EAAOyI,KAAMnF,KAAM2E,KAId5C,UAAU7B,OAAS,EAGzBF,KAAKyB,KAAK,WACT/E,EAAOyI,KAAMnF,KAAM2E,EAAKoC,KAKzBhH,EAAO4gB,EAAU5gB,EAAM4E,EAAKjI,EAAOyI,KAAMpF,EAAM4E,IAAU,MAG3D6b,WAAY,SAAU7b,GACrB,MAAO3E,MAAKyB,KAAK,WAChB/E,EAAO8jB,WAAYxgB,KAAM2E,OAK5B,SAASgc,GAAU5gB,EAAM4E,EAAKQ,GAG7B,GAAKA,IAASlJ,GAA+B,IAAlB8D,EAAKQ,SAAiB,CAEhD,GAAIuC,GAAO,QAAU6B,EAAIpB,QAASkc,EAAY,OAAQ3Y,aAItD,IAFA3B,EAAOpF,EAAK0N,aAAc3K,GAEL,gBAATqC,GAAoB,CAC/B,IACCA,EAAgB,SAATA,GAAkB,EACf,UAATA,GAAmB,EACV,SAATA,EAAkB,MAEjBA,EAAO,KAAOA,GAAQA,EACvBqa,EAAO/e,KAAM0E,GAASzI,EAAOiJ,UAAWR,GACvCA,EACD,MAAOP,IAGTlI,EAAOyI,KAAMpF,EAAM4E,EAAKQ,OAGxBA,GAAOlJ,EAIT,MAAOkJ,GAIR,QAAS+a,GAAmB/b,GAC3B,GAAIrB,EACJ,KAAMA,IAAQqB,GAGb,IAAc,SAATrB,IAAmBpG,EAAOqI,cAAeZ,EAAIrB,MAGpC,WAATA,EACJ,OAAO,CAIT,QAAO,EAERpG,EAAOgG,QACNke,MAAO,SAAU7gB,EAAMV,EAAM8F,GAC5B,GAAIyb,EAEJ,OAAK7gB,IACJV,GAASA,GAAQ,MAAS,QAC1BuhB,EAAQlkB,EAAO+jB,MAAO1gB,EAAMV,GAGvB8F,KACEyb,GAASlkB,EAAOyG,QAAQgC,GAC7Byb,EAAQlkB,EAAO+jB,MAAO1gB,EAAMV,EAAM3C,EAAOsE,UAAUmE,IAEnDyb,EAAMzjB,KAAMgI,IAGPyb,OAZR,GAgBDC,QAAS,SAAU9gB,EAAMV,GACxBA,EAAOA,GAAQ,IAEf,IAAIuhB,GAAQlkB,EAAOkkB,MAAO7gB,EAAMV,GAC/ByhB,EAAcF,EAAM1gB,OACpBlC,EAAK4iB,EAAMxS,QACX2S,EAAQrkB,EAAOskB,YAAajhB,EAAMV,GAClC4hB,EAAO,WACNvkB,EAAOmkB,QAAS9gB,EAAMV,GAIZ,gBAAPrB,IACJA,EAAK4iB,EAAMxS,QACX0S,KAGI9iB,IAIU,OAATqB,GACJuhB,EAAMvP,QAAS,oBAIT0P,GAAMG,KACbljB,EAAGkD,KAAMnB,EAAMkhB,EAAMF,KAGhBD,GAAeC,GACpBA,EAAM/L,MAAMkF,QAKd8G,YAAa,SAAUjhB,EAAMV,GAC5B,GAAIsF,GAAMtF,EAAO,YACjB,OAAO3C,GAAO+jB,MAAO1gB,EAAM4E,IAASjI,EAAO+jB,MAAO1gB,EAAM4E,GACvDqQ,MAAOtY,EAAO8c,UAAU,eAAec,IAAI,WAC1C5d,EAAOgkB,YAAa3gB,EAAMV,EAAO,SACjC3C,EAAOgkB,YAAa3gB,EAAM4E,UAM9BjI,EAAOsB,GAAG0E,QACTke,MAAO,SAAUvhB,EAAM8F,GACtB,GAAIgc,GAAS,CAQb,OANqB,gBAAT9hB,KACX8F,EAAO9F,EACPA,EAAO,KACP8hB,KAGuBA,EAAnBpf,UAAU7B,OACPxD,EAAOkkB,MAAO5gB,KAAK,GAAIX,GAGxB8F,IAASlJ,EACf+D,KACAA,KAAKyB,KAAK,WACT,GAAImf,GAAQlkB,EAAOkkB,MAAO5gB,KAAMX,EAAM8F,EAGtCzI,GAAOskB,YAAahhB,KAAMX,GAEZ,OAATA,GAA8B,eAAbuhB,EAAM,IAC3BlkB,EAAOmkB,QAAS7gB,KAAMX,MAI1BwhB,QAAS,SAAUxhB,GAClB,MAAOW,MAAKyB,KAAK,WAChB/E,EAAOmkB,QAAS7gB,KAAMX,MAKxB+hB,MAAO,SAAUC,EAAMhiB,GAItB,MAHAgiB,GAAO3kB,EAAO4kB,GAAK5kB,EAAO4kB,GAAGC,OAAQF,IAAUA,EAAOA,EACtDhiB,EAAOA,GAAQ,KAERW,KAAK4gB,MAAOvhB,EAAM,SAAU4hB,EAAMF,GACxC,GAAIS,GAAUzd,WAAYkd,EAAMI,EAChCN,GAAMG,KAAO,WACZO,aAAcD,OAIjBE,WAAY,SAAUriB,GACrB,MAAOW,MAAK4gB,MAAOvhB,GAAQ,UAI5BuC,QAAS,SAAUvC,EAAM8E,GACxB,GAAI8B,GACH0b,EAAQ,EACRC,EAAQllB,EAAOgM,WACf6I,EAAWvR,KACXmC,EAAInC,KAAKE,OACTqb,EAAU,aACCoG,GACTC,EAAM5d,YAAauN,GAAYA,IAIb,iBAATlS,KACX8E,EAAM9E,EACNA,EAAOpD,GAERoD,EAAOA,GAAQ,IAEf,OAAO8C,IACN8D,EAAMvJ,EAAO+jB,MAAOlP,EAAUpP,GAAK9C,EAAO,cACrC4G,GAAOA,EAAI+O,QACf2M,IACA1b,EAAI+O,MAAMsF,IAAKiB,GAIjB,OADAA,KACOqG,EAAMhgB,QAASuC,KAGxB,IAAI0d,GAAUC,EACbC,EAAS,cACTC,EAAU,MACVC,EAAa,6CACbC,EAAa,gBACbC,EAAc,0BACdvF,EAAkBlgB,EAAOmI,QAAQ+X,gBACjCwF,EAAc1lB,EAAOmI,QAAQyL,KAE9B5T,GAAOsB,GAAG0E,QACT9B,KAAM,SAAUkC,EAAMiE,GACrB,MAAOrK,GAAOqL,OAAQ/H,KAAMtD,EAAOkE,KAAMkC,EAAMiE,EAAOhF,UAAU7B,OAAS,IAG1EmiB,WAAY,SAAUvf,GACrB,MAAO9C,MAAKyB,KAAK,WAChB/E,EAAO2lB,WAAYriB,KAAM8C,MAI3Bwf,KAAM,SAAUxf,EAAMiE,GACrB,MAAOrK,GAAOqL,OAAQ/H,KAAMtD,EAAO4lB,KAAMxf,EAAMiE,EAAOhF,UAAU7B,OAAS,IAG1EqiB,WAAY,SAAUzf,GAErB,MADAA,GAAOpG,EAAO8lB,QAAS1f,IAAUA,EAC1B9C,KAAKyB,KAAK,WAEhB,IACCzB,KAAM8C,GAAS7G,QACR+D,MAAM8C,GACZ,MAAO8B,QAIX6d,SAAU,SAAU1b,GACnB,GAAI2b,GAAS3iB,EAAM+O,EAAK6T,EAAOtgB,EAC9BF,EAAI,EACJC,EAAMpC,KAAKE,OACX0iB,EAA2B,gBAAV7b,IAAsBA,CAExC,IAAKrK,EAAOiE,WAAYoG,GACvB,MAAO/G,MAAKyB,KAAK,SAAUY,GAC1B3F,EAAQsD,MAAOyiB,SAAU1b,EAAM7F,KAAMlB,KAAMqC,EAAGrC,KAAK2P,aAIrD,IAAKiT,EAIJ,IAFAF,GAAY3b,GAAS,IAAKjH,MAAO1B,OAErBgE,EAAJD,EAASA,IAOhB,GANApC,EAAOC,KAAMmC,GACb2M,EAAwB,IAAlB/O,EAAKQ,WAAoBR,EAAK4P,WACjC,IAAM5P,EAAK4P,UAAY,KAAMpM,QAASwe,EAAQ,KAChD,KAGU,CACV1f,EAAI,CACJ,OAASsgB,EAAQD,EAAQrgB,KACgB,EAAnCyM,EAAIvR,QAAS,IAAMolB,EAAQ,OAC/B7T,GAAO6T,EAAQ,IAGjB5iB,GAAK4P,UAAYjT,EAAOmB,KAAMiR,GAMjC,MAAO9O,OAGR6iB,YAAa,SAAU9b,GACtB,GAAI2b,GAAS3iB,EAAM+O,EAAK6T,EAAOtgB,EAC9BF,EAAI,EACJC,EAAMpC,KAAKE,OACX0iB,EAA+B,IAArB7gB,UAAU7B,QAAiC,gBAAV6G,IAAsBA,CAElE,IAAKrK,EAAOiE,WAAYoG,GACvB,MAAO/G,MAAKyB,KAAK,SAAUY,GAC1B3F,EAAQsD,MAAO6iB,YAAa9b,EAAM7F,KAAMlB,KAAMqC,EAAGrC,KAAK2P,aAGxD,IAAKiT,EAGJ,IAFAF,GAAY3b,GAAS,IAAKjH,MAAO1B,OAErBgE,EAAJD,EAASA,IAQhB,GAPApC,EAAOC,KAAMmC,GAEb2M,EAAwB,IAAlB/O,EAAKQ,WAAoBR,EAAK4P,WACjC,IAAM5P,EAAK4P,UAAY,KAAMpM,QAASwe,EAAQ,KAChD,IAGU,CACV1f,EAAI,CACJ,OAASsgB,EAAQD,EAAQrgB,KAExB,MAAQyM,EAAIvR,QAAS,IAAMolB,EAAQ,MAAS,EAC3C7T,EAAMA,EAAIvL,QAAS,IAAMof,EAAQ,IAAK,IAGxC5iB,GAAK4P,UAAY5I,EAAQrK,EAAOmB,KAAMiR,GAAQ,GAKjD,MAAO9O,OAGR8iB,YAAa,SAAU/b,EAAOgc,GAC7B,GAAI1jB,SAAc0H,EAElB,OAAyB,iBAAbgc,IAAmC,WAAT1jB,EAC9B0jB,EAAW/iB,KAAKyiB,SAAU1b,GAAU/G,KAAK6iB,YAAa9b,GAGzDrK,EAAOiE,WAAYoG,GAChB/G,KAAKyB,KAAK,SAAUU,GAC1BzF,EAAQsD,MAAO8iB,YAAa/b,EAAM7F,KAAKlB,KAAMmC,EAAGnC,KAAK2P,UAAWoT,GAAWA,KAItE/iB,KAAKyB,KAAK,WAChB,GAAc,WAATpC,EAAoB,CAExB,GAAIsQ,GACHxN,EAAI,EACJiY,EAAO1d,EAAQsD,MACfgjB,EAAajc,EAAMjH,MAAO1B,MAE3B,OAASuR,EAAYqT,EAAY7gB,KAE3BiY,EAAK6I,SAAUtT,GACnByK,EAAKyI,YAAalT,GAElByK,EAAKqI,SAAU9S,QAKNtQ,IAASjD,GAA8B,YAATiD,KACpCW,KAAK2P,WAETjT,EAAO+jB,MAAOzgB,KAAM,gBAAiBA,KAAK2P,WAO3C3P,KAAK2P,UAAY3P,KAAK2P,WAAa5I,KAAU,EAAQ,GAAKrK,EAAO+jB,MAAOzgB,KAAM,kBAAqB,OAKtGijB,SAAU,SAAUnlB,GACnB,GAAI6R,GAAY,IAAM7R,EAAW,IAChCqE,EAAI,EACJqF,EAAIxH,KAAKE,MACV,MAAYsH,EAAJrF,EAAOA,IACd,GAA0B,IAArBnC,KAAKmC,GAAG5B,WAAmB,IAAMP,KAAKmC,GAAGwN,UAAY,KAAKpM,QAAQwe,EAAQ,KAAKxkB,QAASoS,IAAe,EAC3G,OAAO,CAIT,QAAO,GAGR6B,IAAK,SAAUzK,GACd,GAAIxF,GAAKwf,EAAOpgB,EACfZ,EAAOC,KAAK,EAEb,EAAA,GAAM+B,UAAU7B,OAsBhB,MAFAS,GAAajE,EAAOiE,WAAYoG,GAEzB/G,KAAKyB,KAAK,SAAUU,GAC1B,GAAIqP,EAEmB,KAAlBxR,KAAKO,WAKTiR,EADI7Q,EACEoG,EAAM7F,KAAMlB,KAAMmC,EAAGzF,EAAQsD,MAAOwR,OAEpCzK,EAIK,MAAPyK,EACJA,EAAM,GACoB,gBAARA,GAClBA,GAAO,GACI9U,EAAOyG,QAASqO,KAC3BA,EAAM9U,EAAO4F,IAAIkP,EAAK,SAAWzK,GAChC,MAAgB,OAATA,EAAgB,GAAKA,EAAQ,MAItCga,EAAQrkB,EAAOwmB,SAAUljB,KAAKX,OAAU3C,EAAOwmB,SAAUljB,KAAK6G,SAASC,eAGjEia,GAAW,OAASA,IAAUA,EAAMoC,IAAKnjB,KAAMwR,EAAK,WAAcvV,IACvE+D,KAAK+G,MAAQyK,KAjDd,IAAKzR,EAGJ,MAFAghB,GAAQrkB,EAAOwmB,SAAUnjB,EAAKV,OAAU3C,EAAOwmB,SAAUnjB,EAAK8G,SAASC,eAElEia,GAAS,OAASA,KAAUxf,EAAMwf,EAAM5f,IAAKpB,EAAM,YAAe9D,EAC/DsF,GAGRA,EAAMxB,EAAKgH,MAEW,gBAARxF,GAEbA,EAAIgC,QAAQye,EAAS,IAEd,MAAPzgB,EAAc,GAAKA,OA0CxB7E,EAAOgG,QACNwgB,UACCE,QACCjiB,IAAK,SAAUpB,GAEd,GAAIyR,GAAM9U,EAAO0D,KAAKQ,KAAMb,EAAM,QAClC,OAAc,OAAPyR,EACNA,EACAzR,EAAKkH,OAGR+G,QACC7M,IAAK,SAAUpB,GACd,GAAIgH,GAAOqc,EACVrgB,EAAUhD,EAAKgD,QACfwX,EAAQxa,EAAKgV,cACbsO,EAAoB,eAAdtjB,EAAKV,MAAiC,EAARkb,EACpC2B,EAASmH,EAAM,QACf/b,EAAM+b,EAAM9I,EAAQ,EAAIxX,EAAQ7C,OAChCiC,EAAY,EAARoY,EACHjT,EACA+b,EAAM9I,EAAQ,CAGhB,MAAYjT,EAAJnF,EAASA,IAIhB,GAHAihB,EAASrgB,EAASZ,MAGXihB,EAAOtO,UAAY3S,IAAMoY,IAE5B7d,EAAOmI,QAAQoZ,YAAemF,EAAOxO,SAA+C,OAApCwO,EAAO3V,aAAa,cACnE2V,EAAOtiB,WAAW8T,UAAalY,EAAOmK,SAAUuc,EAAOtiB,WAAY,aAAiB,CAMxF,GAHAiG,EAAQrK,EAAQ0mB,GAAS5R,MAGpB6R,EACJ,MAAOtc,EAIRmV,GAAO/e,KAAM4J,GAIf,MAAOmV,IAGRiH,IAAK,SAAUpjB,EAAMgH,GACpB,GAAIuc,GAAWF,EACdrgB,EAAUhD,EAAKgD,QACfmZ,EAASxf,EAAOsE,UAAW+F,GAC3B5E,EAAIY,EAAQ7C,MAEb,OAAQiC,IACPihB,EAASrgB,EAASZ,IACZihB,EAAOtO,SAAWpY,EAAO2K,QAAS3K,EAAO0mB,GAAQ5R,MAAO0K,IAAY,KACzEoH,GAAY,EAQd,OAHMA,KACLvjB,EAAKgV,cAAgB,IAEfmH,KAKVtb,KAAM,SAAUb,EAAM+C,EAAMiE,GAC3B,GAAIga,GAAOxf,EACVgiB,EAAQxjB,EAAKQ,QAGd,IAAMR,GAAkB,IAAVwjB,GAAyB,IAAVA,GAAyB,IAAVA,EAK5C,aAAYxjB,GAAK0N,eAAiBrR,EAC1BM,EAAO4lB,KAAMviB,EAAM+C,EAAMiE,IAKlB,IAAVwc,GAAgB7mB,EAAOyc,SAAUpZ,KACrC+C,EAAOA,EAAKgE,cACZia,EAAQrkB,EAAO8mB,UAAW1gB,KACvBpG,EAAO4U,KAAKxR,MAAMmM,KAAKxL,KAAMqC,GAASgf,EAAWD,IAGhD9a,IAAU9K,EAaH8kB,GAAS,OAASA,IAA6C,QAAnCxf,EAAMwf,EAAM5f,IAAKpB,EAAM+C,IACvDvB,GAGPA,EAAM7E,EAAO0D,KAAKQ,KAAMb,EAAM+C,GAGhB,MAAPvB,EACNtF,EACAsF,GApBc,OAAVwF,EAGOga,GAAS,OAASA,KAAUxf,EAAMwf,EAAMoC,IAAKpjB,EAAMgH,EAAOjE,MAAY7G,EAC1EsF,GAGPxB,EAAK2N,aAAc5K,EAAMiE,EAAQ,IAC1BA,IAPPrK,EAAO2lB,WAAYtiB,EAAM+C,GAAzBpG,KAuBH2lB,WAAY,SAAUtiB,EAAMgH,GAC3B,GAAIjE,GAAM2gB,EACTthB,EAAI,EACJuhB,EAAY3c,GAASA,EAAMjH,MAAO1B,EAEnC,IAAKslB,GAA+B,IAAlB3jB,EAAKQ,SACtB,MAASuC,EAAO4gB,EAAUvhB,KACzBshB,EAAW/mB,EAAO8lB,QAAS1f,IAAUA,EAGhCpG,EAAO4U,KAAKxR,MAAMmM,KAAKxL,KAAMqC,GAE5Bsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GACzD/C,EAAM0jB,IAAa,EAInB1jB,EAAMrD,EAAOiK,UAAW,WAAa7D,IACpC/C,EAAM0jB,IAAa,EAKrB/mB,EAAOkE,KAAMb,EAAM+C,EAAM,IAG1B/C,EAAKgO,gBAAiB6O,EAAkB9Z,EAAO2gB,IAKlDD,WACCnkB,MACC8jB,IAAK,SAAUpjB,EAAMgH,GACpB,IAAMrK,EAAOmI,QAAQqZ,YAAwB,UAAVnX,GAAqBrK,EAAOmK,SAAS9G,EAAM,SAAW,CAGxF,GAAIyR,GAAMzR,EAAKgH,KAKf,OAJAhH,GAAK2N,aAAc,OAAQ3G,GACtByK,IACJzR,EAAKgH,MAAQyK,GAEPzK,MAMXyb,SACCmB,MAAO,UACPC,QAAS,aAGVtB,KAAM,SAAUviB,EAAM+C,EAAMiE,GAC3B,GAAIxF,GAAKwf,EAAO8C,EACfN,EAAQxjB,EAAKQ,QAGd,IAAMR,GAAkB,IAAVwjB,GAAyB,IAAVA,GAAyB,IAAVA,EAY5C,MARAM,GAAmB,IAAVN,IAAgB7mB,EAAOyc,SAAUpZ,GAErC8jB,IAEJ/gB,EAAOpG,EAAO8lB,QAAS1f,IAAUA,EACjCie,EAAQrkB,EAAOonB,UAAWhhB,IAGtBiE,IAAU9K,EACP8kB,GAAS,OAASA,KAAUxf,EAAMwf,EAAMoC,IAAKpjB,EAAMgH,EAAOjE,MAAY7G,EAC5EsF,EACExB,EAAM+C,GAASiE,EAGXga,GAAS,OAASA,IAA6C,QAAnCxf,EAAMwf,EAAM5f,IAAKpB,EAAM+C,IACzDvB,EACAxB,EAAM+C,IAITghB,WACCpP,UACCvT,IAAK,SAAUpB,GAId,GAAIgkB,GAAWrnB,EAAO0D,KAAKQ,KAAMb,EAAM,WAEvC,OAAOgkB,GACNC,SAAUD,EAAU,IACpB9B,EAAWxhB,KAAMV,EAAK8G,WAAcqb,EAAWzhB,KAAMV,EAAK8G,WAAc9G,EAAK0U,KAC5E,EACA,QAONqN,GACCqB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAa3B,MAZKiE,MAAU,EAEdrK,EAAO2lB,WAAYtiB,EAAM+C,GACdsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GAEhE/C,EAAK2N,cAAekP,GAAmBlgB,EAAO8lB,QAAS1f,IAAUA,EAAMA,GAIvE/C,EAAMrD,EAAOiK,UAAW,WAAa7D,IAAW/C,EAAM+C,IAAS,EAGzDA,IAGTpG,EAAO+E,KAAM/E,EAAO4U,KAAKxR,MAAMmM,KAAK9N,OAAO2B,MAAO,QAAU,SAAUqC,EAAGW,GACxE,GAAImhB,GAASvnB,EAAO4U,KAAK1C,WAAY9L,IAAUpG,EAAO0D,KAAKQ,IAE3DlE,GAAO4U,KAAK1C,WAAY9L,GAASsf,GAAexF,IAAoBuF,EAAY1hB,KAAMqC,GACrF,SAAU/C,EAAM+C,EAAMsG,GACrB,GAAIpL,GAAKtB,EAAO4U,KAAK1C,WAAY9L,GAChCvB,EAAM6H,EACLnN,GAECS,EAAO4U,KAAK1C,WAAY9L,GAAS7G,IACjCgoB,EAAQlkB,EAAM+C,EAAMsG,GAEpBtG,EAAKgE,cACL,IAEH,OADApK,GAAO4U,KAAK1C,WAAY9L,GAAS9E,EAC1BuD,GAER,SAAUxB,EAAM+C,EAAMsG,GACrB,MAAOA,GACNnN,EACA8D,EAAMrD,EAAOiK,UAAW,WAAa7D,IACpCA,EAAKgE,cACL,QAKCsb,GAAgBxF,IACrBlgB,EAAO8mB,UAAUzc,OAChBoc,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAC3B,MAAKpG,GAAOmK,SAAU9G,EAAM,UAE3BA,EAAKkZ,aAAelS,EAApBhH,GAGO8hB,GAAYA,EAASsB,IAAKpjB,EAAMgH,EAAOjE,MAO5C8Z,IAILiF,GACCsB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAE3B,GAAIvB,GAAMxB,EAAKqQ,iBAAkBtN,EAUjC,OATMvB,IACLxB,EAAKmkB,iBACH3iB,EAAMxB,EAAKS,cAAc2jB,gBAAiBrhB,IAI7CvB,EAAIwF,MAAQA,GAAS,GAGL,UAATjE,GAAoBiE,IAAUhH,EAAK0N,aAAc3K,GACvDiE,EACA9K,IAGHS,EAAO4U,KAAK1C,WAAW7N,GAAKrE,EAAO4U,KAAK1C,WAAW9L,KAAOpG,EAAO4U,KAAK1C,WAAWwV,OAEhF,SAAUrkB,EAAM+C,EAAMsG,GACrB,GAAI7H,EACJ,OAAO6H,GACNnN,GACCsF,EAAMxB,EAAKqQ,iBAAkBtN,KAAyB,KAAdvB,EAAIwF,MAC5CxF,EAAIwF,MACJ,MAEJrK,EAAOwmB,SAAShO,QACf/T,IAAK,SAAUpB,EAAM+C,GACpB,GAAIvB,GAAMxB,EAAKqQ,iBAAkBtN,EACjC,OAAOvB,IAAOA,EAAIkQ,UACjBlQ,EAAIwF,MACJ9K,GAEFknB,IAAKtB,EAASsB,KAKfzmB,EAAO8mB,UAAUa,iBAChBlB,IAAK,SAAUpjB,EAAMgH,EAAOjE,GAC3B+e,EAASsB,IAAKpjB,EAAgB,KAAVgH,GAAe,EAAQA,EAAOjE,KAMpDpG,EAAO+E,MAAO,QAAS,UAAY,SAAUU,EAAGW,GAC/CpG,EAAO8mB,UAAW1gB,IACjBqgB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAe,KAAVA,GACJhH,EAAK2N,aAAc5K,EAAM,QAClBiE,GAFR,OAYErK,EAAOmI,QAAQmY,gBAEpBtgB,EAAO+E,MAAO,OAAQ,OAAS,SAAUU,EAAGW,GAC3CpG,EAAOonB,UAAWhhB,IACjB3B,IAAK,SAAUpB,GACd,MAAOA,GAAK0N,aAAc3K,EAAM,OAM9BpG,EAAOmI,QAAQ4D,QACpB/L,EAAO8mB,UAAU/a,OAChBtH,IAAK,SAAUpB,GAId,MAAOA,GAAK0I,MAAMkU,SAAW1gB,GAE9BknB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAShH,GAAK0I,MAAMkU,QAAU5V,EAAQ,MAOnCrK,EAAOmI,QAAQuY,cACpB1gB,EAAOonB,UAAUhP,UAChB3T,IAAK,SAAUpB,GACd,GAAI0P,GAAS1P,EAAKe,UAUlB,OARK2O,KACJA,EAAOsF,cAGFtF,EAAO3O,YACX2O,EAAO3O,WAAWiU,eAGb,QAKVrY,EAAO+E,MACN,WACA,WACA,YACA,cACA,cACA,UACA,UACA,SACA,cACA,mBACE,WACF/E,EAAO8lB,QAASxiB,KAAK8G,eAAkB9G,OAIlCtD,EAAOmI,QAAQwY,UACpB3gB,EAAO8lB,QAAQnF,QAAU,YAI1B3gB,EAAO+E,MAAO,QAAS,YAAc,WACpC/E,EAAOwmB,SAAUljB,OAChBmjB,IAAK,SAAUpjB,EAAMgH,GACpB,MAAKrK,GAAOyG,QAAS4D,GACXhH,EAAK8U,QAAUnY,EAAO2K,QAAS3K,EAAOqD,GAAMyR,MAAOzK,IAAW,EADxE,IAKIrK,EAAOmI,QAAQsY,UACpBzgB,EAAOwmB,SAAUljB,MAAOmB,IAAM,SAAUpB,GAGvC,MAAsC,QAA/BA,EAAK0N,aAAa,SAAoB,KAAO1N,EAAKgH,SAI5D,IAAIud,GAAa,+BAChBC,GAAY,OACZC,GAAc,+BACdC,GAAc,kCACdC,GAAiB,sBAElB,SAASC,MACR,OAAO,EAGR,QAASC,MACR,OAAO,EAGR,QAASC,MACR,IACC,MAAOvoB,GAASiY,cACf,MAAQuQ,KAOXpoB,EAAOyC,OAEN4lB,UAEAzK,IAAK,SAAUva,EAAMilB,EAAOrW,EAASxJ,EAAMrH,GAC1C,GAAImI,GAAKgf,EAAQC,EAAGC,EACnBC,EAASC,EAAaC,EACtBC,EAAUlmB,EAAMmmB,EAAYC,EAC5BC,EAAWhpB,EAAO+jB,MAAO1gB,EAG1B,IAAM2lB,EAAN,CAKK/W,EAAQA,UACZwW,EAAcxW,EACdA,EAAUwW,EAAYxW,QACtB7Q,EAAWqnB,EAAYrnB,UAIlB6Q,EAAQ9G,OACb8G,EAAQ9G,KAAOnL,EAAOmL,SAIhBod,EAASS,EAAST,UACxBA,EAASS,EAAST,YAEZI,EAAcK,EAASC,UAC7BN,EAAcK,EAASC,OAAS,SAAU/gB,GAGzC,aAAclI,KAAWN,GAAuBwI,GAAKlI,EAAOyC,MAAMymB,YAAchhB,EAAEvF,KAEjFpD,EADAS,EAAOyC,MAAM0mB,SAAS/jB,MAAOujB,EAAYtlB,KAAMgC,YAIjDsjB,EAAYtlB,KAAOA,GAIpBilB,GAAUA,GAAS,IAAKllB,MAAO1B,KAAqB,IACpD8mB,EAAIF,EAAM9kB,MACV,OAAQglB,IACPjf,EAAMye,GAAevkB,KAAM6kB,EAAME,QACjC7lB,EAAOomB,EAAWxf,EAAI,GACtBuf,GAAevf,EAAI,IAAM,IAAK+C,MAAO,KAAMxG,OAGrCnD,IAKN+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAGhCA,GAASvB,EAAWsnB,EAAQU,aAAeV,EAAQW,WAAc1mB,EAGjE+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAGhCimB,EAAY5oB,EAAOgG,QAClBrD,KAAMA,EACNomB,SAAUA,EACVtgB,KAAMA,EACNwJ,QAASA,EACT9G,KAAM8G,EAAQ9G,KACd/J,SAAUA,EACVoO,aAAcpO,GAAYpB,EAAO4U,KAAKxR,MAAMoM,aAAazL,KAAM3C,GAC/DkoB,UAAWR,EAAW5X,KAAK,MACzBuX,IAGII,EAAWN,EAAQ5lB,MACzBkmB,EAAWN,EAAQ5lB,MACnBkmB,EAASU,cAAgB,EAGnBb,EAAQc,OAASd,EAAQc,MAAMhlB,KAAMnB,EAAMoF,EAAMqgB,EAAYH,MAAkB,IAE/EtlB,EAAKX,iBACTW,EAAKX,iBAAkBC,EAAMgmB,GAAa,GAE/BtlB,EAAK4I,aAChB5I,EAAK4I,YAAa,KAAOtJ,EAAMgmB,KAK7BD,EAAQ9K,MACZ8K,EAAQ9K,IAAIpZ,KAAMnB,EAAMulB,GAElBA,EAAU3W,QAAQ9G,OACvByd,EAAU3W,QAAQ9G,KAAO8G,EAAQ9G,OAK9B/J,EACJynB,EAAS9iB,OAAQ8iB,EAASU,gBAAiB,EAAGX,GAE9CC,EAASpoB,KAAMmoB,GAIhB5oB,EAAOyC,MAAM4lB,OAAQ1lB,IAAS,EAI/BU,GAAO,OAIR0F,OAAQ,SAAU1F,EAAMilB,EAAOrW,EAAS7Q,EAAUqoB,GACjD,GAAI9jB,GAAGijB,EAAWrf,EACjBmgB,EAAWlB,EAAGD,EACdG,EAASG,EAAUlmB,EACnBmmB,EAAYC,EACZC,EAAWhpB,EAAO6jB,QAASxgB,IAAUrD,EAAO+jB,MAAO1gB,EAEpD,IAAM2lB,IAAcT,EAASS,EAAST,QAAtC,CAKAD,GAAUA,GAAS,IAAKllB,MAAO1B,KAAqB,IACpD8mB,EAAIF,EAAM9kB,MACV,OAAQglB,IAMP,GALAjf,EAAMye,GAAevkB,KAAM6kB,EAAME,QACjC7lB,EAAOomB,EAAWxf,EAAI,GACtBuf,GAAevf,EAAI,IAAM,IAAK+C,MAAO,KAAMxG,OAGrCnD,EAAN,CAOA+lB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAChCA,GAASvB,EAAWsnB,EAAQU,aAAeV,EAAQW,WAAc1mB,EACjEkmB,EAAWN,EAAQ5lB,OACnB4G,EAAMA,EAAI,IAAUkF,OAAQ,UAAYqa,EAAW5X,KAAK,iBAAmB,WAG3EwY,EAAY/jB,EAAIkjB,EAASrlB,MACzB,OAAQmC,IACPijB,EAAYC,EAAUljB,IAEf8jB,GAAeV,IAAaH,EAAUG,UACzC9W,GAAWA,EAAQ9G,OAASyd,EAAUzd,MACtC5B,IAAOA,EAAIxF,KAAM6kB,EAAUU,YAC3BloB,GAAYA,IAAawnB,EAAUxnB,WAAyB,OAAbA,IAAqBwnB,EAAUxnB,YACjFynB,EAAS9iB,OAAQJ,EAAG,GAEfijB,EAAUxnB,UACdynB,EAASU,gBAELb,EAAQ3f,QACZ2f,EAAQ3f,OAAOvE,KAAMnB,EAAMulB,GAOzBc,KAAcb,EAASrlB,SACrBklB,EAAQiB,UAAYjB,EAAQiB,SAASnlB,KAAMnB,EAAMylB,EAAYE,EAASC,WAAa,GACxFjpB,EAAO4pB,YAAavmB,EAAMV,EAAMqmB,EAASC,cAGnCV,GAAQ5lB,QAtCf,KAAMA,IAAQ4lB,GACbvoB,EAAOyC,MAAMsG,OAAQ1F,EAAMV,EAAO2lB,EAAOE,GAAKvW,EAAS7Q,GAAU,EA0C/DpB,GAAOqI,cAAekgB,WACnBS,GAASC,OAIhBjpB,EAAOgkB,YAAa3gB,EAAM,aAI5BkE,QAAS,SAAU9E,EAAOgG,EAAMpF,EAAMwmB,GACrC,GAAIZ,GAAQa,EAAQ1X,EACnB2X,EAAYrB,EAASnf,EAAK9D,EAC1BukB,GAAc3mB,GAAQzD,GACtB+C,EAAO3B,EAAYwD,KAAM/B,EAAO,QAAWA,EAAME,KAAOF,EACxDqmB,EAAa9nB,EAAYwD,KAAM/B,EAAO,aAAgBA,EAAM6mB,UAAUhd,MAAM,OAK7E,IAHA8F,EAAM7I,EAAMlG,EAAOA,GAAQzD,EAGJ,IAAlByD,EAAKQ,UAAoC,IAAlBR,EAAKQ,WAK5BkkB,GAAYhkB,KAAMpB,EAAO3C,EAAOyC,MAAMymB,aAItCvmB,EAAK9B,QAAQ,MAAQ,IAEzBioB,EAAanmB,EAAK2J,MAAM,KACxB3J,EAAOmmB,EAAWpX,QAClBoX,EAAWhjB,QAEZgkB,EAA6B,EAApBnnB,EAAK9B,QAAQ,MAAY,KAAO8B,EAGzCF,EAAQA,EAAOzC,EAAO0G,SACrBjE,EACA,GAAIzC,GAAOiqB,MAAOtnB,EAAuB,gBAAVF,IAAsBA,GAGtDA,EAAMynB,UAAYL,EAAe,EAAI,EACrCpnB,EAAM6mB,UAAYR,EAAW5X,KAAK,KAClCzO,EAAM0nB,aAAe1nB,EAAM6mB,UACtB7a,OAAQ,UAAYqa,EAAW5X,KAAK,iBAAmB,WAC3D,KAGDzO,EAAM4T,OAAS9W,EACTkD,EAAM8D,SACX9D,EAAM8D,OAASlD,GAIhBoF,EAAe,MAARA,GACJhG,GACFzC,EAAOsE,UAAWmE,GAAQhG,IAG3BimB,EAAU1oB,EAAOyC,MAAMimB,QAAS/lB,OAC1BknB,IAAgBnB,EAAQnhB,SAAWmhB,EAAQnhB,QAAQnC,MAAO/B,EAAMoF,MAAW,GAAjF,CAMA,IAAMohB,IAAiBnB,EAAQ0B,WAAapqB,EAAO2H,SAAUtE,GAAS,CAMrE,IAJA0mB,EAAarB,EAAQU,cAAgBzmB,EAC/BolB,GAAYhkB,KAAMgmB,EAAapnB,KACpCyP,EAAMA,EAAIhO,YAEHgO,EAAKA,EAAMA,EAAIhO,WACtB4lB,EAAUvpB,KAAM2R,GAChB7I,EAAM6I,CAIF7I,MAASlG,EAAKS,eAAiBlE,IACnCoqB,EAAUvpB,KAAM8I,EAAIyJ,aAAezJ,EAAI8gB,cAAgB/qB,GAKzDmG,EAAI,CACJ,QAAS2M,EAAM4X,EAAUvkB,QAAUhD,EAAM6nB,uBAExC7nB,EAAME,KAAO8C,EAAI,EAChBskB,EACArB,EAAQW,UAAY1mB,EAGrBsmB,GAAWjpB,EAAO+jB,MAAO3R,EAAK,eAAoB3P,EAAME,OAAU3C,EAAO+jB,MAAO3R,EAAK,UAChF6W,GACJA,EAAO7jB,MAAOgN,EAAK3J,GAIpBwgB,EAASa,GAAU1X,EAAK0X,GACnBb,GAAUjpB,EAAOkjB,WAAY9Q,IAAS6W,EAAO7jB,OAAS6jB,EAAO7jB,MAAOgN,EAAK3J,MAAW,GACxFhG,EAAM8nB,gBAMR,IAHA9nB,EAAME,KAAOA,GAGPknB,IAAiBpnB,EAAM+nB,wBAErB9B,EAAQ+B,UAAY/B,EAAQ+B,SAASrlB,MAAO4kB,EAAU/b,MAAOxF,MAAW,IAC9EzI,EAAOkjB,WAAY7f,IAKdymB,GAAUzmB,EAAMV,KAAW3C,EAAO2H,SAAUtE,GAAS,CAGzDkG,EAAMlG,EAAMymB,GAEPvgB,IACJlG,EAAMymB,GAAW,MAIlB9pB,EAAOyC,MAAMymB,UAAYvmB,CACzB,KACCU,EAAMV,KACL,MAAQuF,IAIVlI,EAAOyC,MAAMymB,UAAY3pB,EAEpBgK,IACJlG,EAAMymB,GAAWvgB,GAMrB,MAAO9G,GAAM4T,SAGd8S,SAAU,SAAU1mB,GAGnBA,EAAQzC,EAAOyC,MAAMioB,IAAKjoB,EAE1B,IAAIgD,GAAGZ,EAAK+jB,EAAW1R,EAASvR,EAC/BglB,KACA1lB,EAAOvE,EAAW8D,KAAMa,WACxBwjB,GAAa7oB,EAAO+jB,MAAOzgB,KAAM,eAAoBb,EAAME,UAC3D+lB,EAAU1oB,EAAOyC,MAAMimB,QAASjmB,EAAME,SAOvC,IAJAsC,EAAK,GAAKxC,EACVA,EAAMmoB,eAAiBtnB,MAGlBolB,EAAQmC,aAAenC,EAAQmC,YAAYrmB,KAAMlB,KAAMb,MAAY,EAAxE,CAKAkoB,EAAe3qB,EAAOyC,MAAMomB,SAASrkB,KAAMlB,KAAMb,EAAOomB,GAGxDpjB,EAAI,CACJ,QAASyR,EAAUyT,EAAcllB,QAAWhD,EAAM6nB,uBAAyB,CAC1E7nB,EAAMqoB,cAAgB5T,EAAQ7T,KAE9BsC,EAAI,CACJ,QAASijB,EAAY1R,EAAQ2R,SAAUljB,QAAWlD,EAAMsoB,kCAIjDtoB,EAAM0nB,cAAgB1nB,EAAM0nB,aAAapmB,KAAM6kB,EAAUU,cAE9D7mB,EAAMmmB,UAAYA,EAClBnmB,EAAMgG,KAAOmgB,EAAUngB,KAEvB5D,IAAS7E,EAAOyC,MAAMimB,QAASE,EAAUG,eAAkBE,QAAUL,EAAU3W,SAC5E7M,MAAO8R,EAAQ7T,KAAM4B,GAEnBJ,IAAQtF,IACNkD,EAAM4T,OAASxR,MAAS,IAC7BpC,EAAM8nB,iBACN9nB,EAAMuoB,oBAYX,MAJKtC,GAAQuC,cACZvC,EAAQuC,aAAazmB,KAAMlB,KAAMb,GAG3BA,EAAM4T,SAGdwS,SAAU,SAAUpmB,EAAOomB,GAC1B,GAAIqC,GAAKtC,EAAW1b,EAASzH,EAC5BklB,KACApB,EAAgBV,EAASU,cACzBnX,EAAM3P,EAAM8D,MAKb,IAAKgjB,GAAiBnX,EAAIvO,YAAcpB,EAAM+V,QAAyB,UAAf/V,EAAME,MAG7D,KAAQyP,GAAO9O,KAAM8O,EAAMA,EAAIhO,YAAcd,KAK5C,GAAsB,IAAjB8O,EAAIvO,WAAmBuO,EAAI8F,YAAa,GAAuB,UAAfzV,EAAME,MAAoB,CAE9E,IADAuK,KACMzH,EAAI,EAAO8jB,EAAJ9jB,EAAmBA,IAC/BmjB,EAAYC,EAAUpjB,GAGtBylB,EAAMtC,EAAUxnB,SAAW,IAEtB8L,EAASge,KAAU3rB,IACvB2N,EAASge,GAAQtC,EAAUpZ,aAC1BxP,EAAQkrB,EAAK5nB,MAAOua,MAAOzL,IAAS,EACpCpS,EAAO0D,KAAMwnB,EAAK5nB,KAAM,MAAQ8O,IAAQ5O,QAErC0J,EAASge,IACbhe,EAAQzM,KAAMmoB,EAGX1b,GAAQ1J,QACZmnB,EAAalqB,MAAO4C,KAAM+O,EAAKyW,SAAU3b,IAW7C,MAJqB2b,GAASrlB,OAAzB+lB,GACJoB,EAAalqB,MAAO4C,KAAMC,KAAMulB,SAAUA,EAASloB,MAAO4oB,KAGpDoB,GAGRD,IAAK,SAAUjoB,GACd,GAAKA,EAAOzC,EAAO0G,SAClB,MAAOjE,EAIR,IAAIgD,GAAGmgB,EAAMzf,EACZxD,EAAOF,EAAME,KACbwoB,EAAgB1oB,EAChB2oB,EAAU9nB,KAAK+nB,SAAU1oB,EAEpByoB,KACL9nB,KAAK+nB,SAAU1oB,GAASyoB,EACvBtD,GAAY/jB,KAAMpB,GAASW,KAAKgoB,WAChCzD,GAAU9jB,KAAMpB,GAASW,KAAKioB,aAGhCplB,EAAOilB,EAAQI,MAAQloB,KAAKkoB,MAAMjrB,OAAQ6qB,EAAQI,OAAUloB,KAAKkoB,MAEjE/oB,EAAQ,GAAIzC,GAAOiqB,MAAOkB,GAE1B1lB,EAAIU,EAAK3C,MACT,OAAQiC,IACPmgB,EAAOzf,EAAMV,GACbhD,EAAOmjB,GAASuF,EAAevF,EAmBhC,OAdMnjB,GAAM8D,SACX9D,EAAM8D,OAAS4kB,EAAcM,YAAc7rB,GAKb,IAA1B6C,EAAM8D,OAAO1C,WACjBpB,EAAM8D,OAAS9D,EAAM8D,OAAOnC,YAK7B3B,EAAMipB,UAAYjpB,EAAMipB,QAEjBN,EAAQ5X,OAAS4X,EAAQ5X,OAAQ/Q,EAAO0oB,GAAkB1oB,GAIlE+oB,MAAO,wHAAwHlf,MAAM,KAErI+e,YAEAE,UACCC,MAAO,4BAA4Blf,MAAM,KACzCkH,OAAQ,SAAU/Q,EAAOkpB,GAOxB,MAJoB,OAAflpB,EAAMmpB,QACVnpB,EAAMmpB,MAA6B,MAArBD,EAASE,SAAmBF,EAASE,SAAWF,EAASG,SAGjErpB,IAIT6oB,YACCE,MAAO,mGAAmGlf,MAAM,KAChHkH,OAAQ,SAAU/Q,EAAOkpB,GACxB,GAAIvkB,GAAM2kB,EAAUjZ,EACnB0F,EAASmT,EAASnT,OAClBwT,EAAcL,EAASK,WAuBxB,OApBoB,OAAfvpB,EAAMwpB,OAAqC,MAApBN,EAASO,UACpCH,EAAWtpB,EAAM8D,OAAOzC,eAAiBlE,EACzCkT,EAAMiZ,EAASjsB,gBACfsH,EAAO2kB,EAAS3kB,KAEhB3E,EAAMwpB,MAAQN,EAASO,SAAYpZ,GAAOA,EAAIqZ,YAAc/kB,GAAQA,EAAK+kB,YAAc,IAAQrZ,GAAOA,EAAIsZ,YAAchlB,GAAQA,EAAKglB,YAAc,GACnJ3pB,EAAM4pB,MAAQV,EAASW,SAAYxZ,GAAOA,EAAIyZ,WAAcnlB,GAAQA,EAAKmlB,WAAc,IAAQzZ,GAAOA,EAAI0Z,WAAcplB,GAAQA,EAAKolB,WAAc,KAI9I/pB,EAAMgqB,eAAiBT,IAC5BvpB,EAAMgqB,cAAgBT,IAAgBvpB,EAAM8D,OAASolB,EAASe,UAAYV,GAKrEvpB,EAAMmpB,OAASpT,IAAWjZ,IAC/BkD,EAAMmpB,MAAmB,EAATpT,EAAa,EAAe,EAATA,EAAa,EAAe,EAATA,EAAa,EAAI,GAGjE/V,IAITimB,SACCiE,MAECvC,UAAU,GAEXxS,OAECrQ,QAAS,WACR,GAAKjE,OAAS6kB,MAAuB7kB,KAAKsU,MACzC,IAEC,MADAtU,MAAKsU,SACE,EACN,MAAQ1P,MAOZkhB,aAAc,WAEfwD,MACCrlB,QAAS,WACR,MAAKjE,QAAS6kB,MAAuB7kB,KAAKspB,MACzCtpB,KAAKspB,QACE,GAFR,GAKDxD,aAAc,YAEfxH,OAECra,QAAS,WACR,MAAKvH,GAAOmK,SAAU7G,KAAM,UAA2B,aAAdA,KAAKX,MAAuBW,KAAKse,OACzEte,KAAKse,SACE,GAFR,GAOD6I,SAAU,SAAUhoB,GACnB,MAAOzC,GAAOmK,SAAU1H,EAAM8D,OAAQ,OAIxCsmB,cACC5B,aAAc,SAAUxoB,GAGlBA,EAAM4T,SAAW9W,IACrBkD,EAAM0oB,cAAc2B,YAAcrqB,EAAM4T,WAM5C0W,SAAU,SAAUpqB,EAAMU,EAAMZ,EAAOuqB,GAItC,GAAI9kB,GAAIlI,EAAOgG,OACd,GAAIhG,GAAOiqB,MACXxnB,GAECE,KAAMA,EACNsqB,aAAa,EACb9B,kBAGG6B,GACJhtB,EAAOyC,MAAM8E,QAASW,EAAG,KAAM7E,GAE/BrD,EAAOyC,MAAM0mB,SAAS3kB,KAAMnB,EAAM6E,GAE9BA,EAAEsiB,sBACN/nB,EAAM8nB,mBAKTvqB,EAAO4pB,YAAchqB,EAASmD,oBAC7B,SAAUM,EAAMV,EAAMsmB,GAChB5lB,EAAKN,qBACTM,EAAKN,oBAAqBJ,EAAMsmB,GAAQ,IAG1C,SAAU5lB,EAAMV,EAAMsmB,GACrB,GAAI7iB,GAAO,KAAOzD,CAEbU,GAAKL,oBAIGK,GAAM+C,KAAW1G,IAC5B2D,EAAM+C,GAAS,MAGhB/C,EAAKL,YAAaoD,EAAM6iB,KAI3BjpB,EAAOiqB,MAAQ,SAAUhkB,EAAKulB,GAE7B,MAAOloB,gBAAgBtD,GAAOiqB,OAKzBhkB,GAAOA,EAAItD,MACfW,KAAK6nB,cAAgBllB,EACrB3C,KAAKX,KAAOsD,EAAItD,KAIhBW,KAAKknB,mBAAuBvkB,EAAIinB,kBAAoBjnB,EAAI6mB,eAAgB,GACvE7mB,EAAIknB,mBAAqBlnB,EAAIknB,oBAAwBlF,GAAaC,IAInE5kB,KAAKX,KAAOsD,EAIRulB,GACJxrB,EAAOgG,OAAQ1C,KAAMkoB,GAItBloB,KAAK8pB,UAAYnnB,GAAOA,EAAImnB,WAAaptB,EAAO0L,MAGhDpI,KAAMtD,EAAO0G,UAAY,EAvBzB,GAJQ,GAAI1G,GAAOiqB,MAAOhkB,EAAKulB,IAgChCxrB,EAAOiqB,MAAMhnB,WACZunB,mBAAoBtC,GACpBoC,qBAAsBpC,GACtB6C,8BAA+B7C,GAE/BqC,eAAgB,WACf,GAAIriB,GAAI5E,KAAK6nB,aAEb7nB,MAAKknB,mBAAqBvC,GACpB/f,IAKDA,EAAEqiB,eACNriB,EAAEqiB,iBAKFriB,EAAE4kB,aAAc,IAGlB9B,gBAAiB,WAChB,GAAI9iB,GAAI5E,KAAK6nB,aAEb7nB,MAAKgnB,qBAAuBrC,GACtB/f,IAIDA,EAAE8iB,iBACN9iB,EAAE8iB,kBAKH9iB,EAAEmlB,cAAe,IAElBC,yBAA0B,WACzBhqB,KAAKynB,8BAAgC9C,GACrC3kB,KAAK0nB,oBAKPhrB,EAAO+E,MACNwoB,WAAY,YACZC,WAAY,YACV,SAAUC,EAAM/C,GAClB1qB,EAAOyC,MAAMimB,QAAS+E,IACrBrE,aAAcsB,EACdrB,SAAUqB,EAEVzB,OAAQ,SAAUxmB,GACjB,GAAIoC,GACH0B,EAASjD,KACToqB,EAAUjrB,EAAMgqB,cAChB7D,EAAYnmB,EAAMmmB,SASnB,SALM8E,GAAYA,IAAYnnB,IAAWvG,EAAOmN,SAAU5G,EAAQmnB,MACjEjrB,EAAME,KAAOimB,EAAUG,SACvBlkB,EAAM+jB,EAAU3W,QAAQ7M,MAAO9B,KAAM+B,WACrC5C,EAAME,KAAO+nB,GAEP7lB,MAMJ7E,EAAOmI,QAAQwlB,gBAEpB3tB,EAAOyC,MAAMimB,QAAQxP,QACpBsQ,MAAO,WAEN,MAAKxpB,GAAOmK,SAAU7G,KAAM,SACpB,GAIRtD,EAAOyC,MAAMmb,IAAKta,KAAM,iCAAkC,SAAU4E,GAEnE,GAAI7E,GAAO6E,EAAE3B,OACZqnB,EAAO5tB,EAAOmK,SAAU9G,EAAM,UAAarD,EAAOmK,SAAU9G,EAAM,UAAaA,EAAKuqB,KAAOruB,CACvFquB,KAAS5tB,EAAO+jB,MAAO6J,EAAM,mBACjC5tB,EAAOyC,MAAMmb,IAAKgQ,EAAM,iBAAkB,SAAUnrB,GACnDA,EAAMorB,gBAAiB,IAExB7tB,EAAO+jB,MAAO6J,EAAM,iBAAiB,MARvC5tB,IAcDirB,aAAc,SAAUxoB,GAElBA,EAAMorB,uBACHprB,GAAMorB,eACRvqB,KAAKc,aAAe3B,EAAMynB,WAC9BlqB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAKc,WAAY3B,GAAO,KAK5DknB,SAAU,WAET,MAAK3pB,GAAOmK,SAAU7G,KAAM,SACpB,GAIRtD,EAAOyC,MAAMsG,OAAQzF,KAAM,YAA3BtD,MAMGA,EAAOmI,QAAQ2lB,gBAEpB9tB,EAAOyC,MAAMimB,QAAQ7G,QAEpB2H,MAAO,WAEN,MAAK5B,GAAW7jB,KAAMT,KAAK6G,YAIP,aAAd7G,KAAKX,MAAqC,UAAdW,KAAKX,QACrC3C,EAAOyC,MAAMmb,IAAKta,KAAM,yBAA0B,SAAUb,GACjB,YAArCA,EAAM0oB,cAAc4C,eACxBzqB,KAAK0qB,eAAgB,KAGvBhuB,EAAOyC,MAAMmb,IAAKta,KAAM,gBAAiB,SAAUb,GAC7Ca,KAAK0qB,gBAAkBvrB,EAAMynB,YACjC5mB,KAAK0qB,eAAgB,GAGtBhuB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAMb,GAAO,OAGzC,IAGRzC,EAAOyC,MAAMmb,IAAKta,KAAM,yBAA0B,SAAU4E,GAC3D,GAAI7E,GAAO6E,EAAE3B,MAERqhB,GAAW7jB,KAAMV,EAAK8G,YAAenK,EAAO+jB,MAAO1gB,EAAM,mBAC7DrD,EAAOyC,MAAMmb,IAAKva,EAAM,iBAAkB,SAAUZ,IAC9Ca,KAAKc,YAAe3B,EAAMwqB,aAAgBxqB,EAAMynB,WACpDlqB,EAAOyC,MAAMsqB,SAAU,SAAUzpB,KAAKc,WAAY3B,GAAO,KAG3DzC,EAAO+jB,MAAO1gB,EAAM,iBAAiB,MATvCrD,IAcDipB,OAAQ,SAAUxmB,GACjB,GAAIY,GAAOZ,EAAM8D,MAGjB,OAAKjD,QAASD,GAAQZ,EAAMwqB,aAAexqB,EAAMynB,WAA4B,UAAd7mB,EAAKV,MAAkC,aAAdU,EAAKV,KACrFF,EAAMmmB,UAAU3W,QAAQ7M,MAAO9B,KAAM+B,WAD7C,GAKDskB,SAAU,WAGT,MAFA3pB,GAAOyC,MAAMsG,OAAQzF,KAAM,aAEnBskB,EAAW7jB,KAAMT,KAAK6G,aAM3BnK,EAAOmI,QAAQ8lB,gBACpBjuB,EAAO+E,MAAO6S,MAAO,UAAWgV,KAAM,YAAc,SAAUa,EAAM/C,GAGnE,GAAIwD,GAAW,EACdjc,EAAU,SAAUxP,GACnBzC,EAAOyC,MAAMsqB,SAAUrC,EAAKjoB,EAAM8D,OAAQvG,EAAOyC,MAAMioB,IAAKjoB,IAAS,GAGvEzC,GAAOyC,MAAMimB,QAASgC,IACrBlB,MAAO,WACc,IAAf0E,KACJtuB,EAAS8C,iBAAkB+qB,EAAMxb,GAAS,IAG5C0X,SAAU,WACW,MAAbuE,GACNtuB,EAASmD,oBAAqB0qB,EAAMxb,GAAS,OAOlDjS,EAAOsB,GAAG0E,QAETmoB,GAAI,SAAU7F,EAAOlnB,EAAUqH,EAAMnH,EAAiBqlB,GACrD,GAAIhkB,GAAMyrB,CAGV,IAAsB,gBAAV9F,GAAqB,CAEP,gBAAblnB,KAEXqH,EAAOA,GAAQrH,EACfA,EAAW7B,EAEZ,KAAMoD,IAAQ2lB,GACbhlB,KAAK6qB,GAAIxrB,EAAMvB,EAAUqH,EAAM6f,EAAO3lB,GAAQgkB,EAE/C,OAAOrjB,MAmBR,GAhBa,MAARmF,GAAsB,MAANnH,GAEpBA,EAAKF,EACLqH,EAAOrH,EAAW7B,GACD,MAAN+B,IACc,gBAAbF,IAEXE,EAAKmH,EACLA,EAAOlJ,IAGP+B,EAAKmH,EACLA,EAAOrH,EACPA,EAAW7B,IAGR+B,KAAO,EACXA,EAAK4mB,OACC,KAAM5mB,EACZ,MAAOgC,KAaR,OAVa,KAARqjB,IACJyH,EAAS9sB,EACTA,EAAK,SAAUmB,GAGd,MADAzC,KAASwH,IAAK/E,GACP2rB,EAAOhpB,MAAO9B,KAAM+B,YAG5B/D,EAAG6J,KAAOijB,EAAOjjB,OAAUijB,EAAOjjB,KAAOnL,EAAOmL,SAE1C7H,KAAKyB,KAAM,WACjB/E,EAAOyC,MAAMmb,IAAKta,KAAMglB,EAAOhnB,EAAImH,EAAMrH,MAG3CulB,IAAK,SAAU2B,EAAOlnB,EAAUqH,EAAMnH,GACrC,MAAOgC,MAAK6qB,GAAI7F,EAAOlnB,EAAUqH,EAAMnH,EAAI,IAE5CkG,IAAK,SAAU8gB,EAAOlnB,EAAUE,GAC/B,GAAIsnB,GAAWjmB,CACf,IAAK2lB,GAASA,EAAMiC,gBAAkBjC,EAAMM,UAQ3C,MANAA,GAAYN,EAAMM,UAClB5oB,EAAQsoB,EAAMsC,gBAAiBpjB,IAC9BohB,EAAUU,UAAYV,EAAUG,SAAW,IAAMH,EAAUU,UAAYV,EAAUG,SACjFH,EAAUxnB,SACVwnB,EAAU3W,SAEJ3O,IAER,IAAsB,gBAAVglB,GAAqB,CAEhC,IAAM3lB,IAAQ2lB,GACbhlB,KAAKkE,IAAK7E,EAAMvB,EAAUknB,EAAO3lB,GAElC,OAAOW,MAUR,OARKlC,KAAa,GAA6B,kBAAbA,MAEjCE,EAAKF,EACLA,EAAW7B,GAEP+B,KAAO,IACXA,EAAK4mB,IAEC5kB,KAAKyB,KAAK,WAChB/E,EAAOyC,MAAMsG,OAAQzF,KAAMglB,EAAOhnB,EAAIF,MAIxCmG,QAAS,SAAU5E,EAAM8F,GACxB,MAAOnF,MAAKyB,KAAK,WAChB/E,EAAOyC,MAAM8E,QAAS5E,EAAM8F,EAAMnF,SAGpC+qB,eAAgB,SAAU1rB,EAAM8F,GAC/B,GAAIpF,GAAOC,KAAK,EAChB,OAAKD,GACGrD,EAAOyC,MAAM8E,QAAS5E,EAAM8F,EAAMpF,GAAM,GADhD,IAKF,IAAIirB,IAAW,iBACdC,GAAe,iCACfC,GAAgBxuB,EAAO4U,KAAKxR,MAAMoM,aAElCif,IACCC,UAAU,EACVC,UAAU,EACVpK,MAAM,EACNqK,MAAM,EAGR5uB,GAAOsB,GAAG0E,QACTtC,KAAM,SAAUtC,GACf,GAAIqE,GACHZ,KACA6Y,EAAOpa,KACPoC,EAAMgY,EAAKla,MAEZ,IAAyB,gBAAbpC,GACX,MAAOkC,MAAKqB,UAAW3E,EAAQoB,GAAWoS,OAAO,WAChD,IAAM/N,EAAI,EAAOC,EAAJD,EAASA,IACrB,GAAKzF,EAAOmN,SAAUuQ,EAAMjY,GAAKnC,MAChC,OAAO,IAMX,KAAMmC,EAAI,EAAOC,EAAJD,EAASA,IACrBzF,EAAO0D,KAAMtC,EAAUsc,EAAMjY,GAAKZ,EAMnC,OAFAA,GAAMvB,KAAKqB,UAAWe,EAAM,EAAI1F,EAAOwc,OAAQ3X,GAAQA,GACvDA,EAAIzD,SAAWkC,KAAKlC,SAAWkC,KAAKlC,SAAW,IAAMA,EAAWA,EACzDyD,GAGRyS,IAAK,SAAU/Q,GACd,GAAId,GACHopB,EAAU7uB,EAAQuG,EAAQjD,MAC1BoC,EAAMmpB,EAAQrrB,MAEf,OAAOF,MAAKkQ,OAAO,WAClB,IAAM/N,EAAI,EAAOC,EAAJD,EAASA,IACrB,GAAKzF,EAAOmN,SAAU7J,KAAMurB,EAAQppB,IACnC,OAAO,KAMX0R,IAAK,SAAU/V,GACd,MAAOkC,MAAKqB,UAAWmqB,GAAOxrB,KAAMlC,OAAgB,KAGrDoS,OAAQ,SAAUpS,GACjB,MAAOkC,MAAKqB,UAAWmqB,GAAOxrB,KAAMlC,OAAgB,KAGrD2tB,GAAI,SAAU3tB,GACb,QAAS0tB,GACRxrB,KAIoB,gBAAblC,IAAyBotB,GAAczqB,KAAM3C,GACnDpB,EAAQoB,GACRA,OACD,GACCoC,QAGHwrB,QAAS,SAAU1Z,EAAWjU,GAC7B,GAAI+Q,GACH3M,EAAI,EACJqF,EAAIxH,KAAKE,OACTqB,KACAoqB,EAAMT,GAAczqB,KAAMuR,IAAoC,gBAAdA,GAC/CtV,EAAQsV,EAAWjU,GAAWiC,KAAKjC,SACnC,CAEF,MAAYyJ,EAAJrF,EAAOA,IACd,IAAM2M,EAAM9O,KAAKmC,GAAI2M,GAAOA,IAAQ/Q,EAAS+Q,EAAMA,EAAIhO,WAEtD,GAAoB,GAAfgO,EAAIvO,WAAkBorB,EAC1BA,EAAIpR,MAAMzL,GAAO,GAGA,IAAjBA,EAAIvO,UACH7D,EAAO0D,KAAKmQ,gBAAgBzB,EAAKkD,IAAc,CAEhDlD,EAAMvN,EAAIpE,KAAM2R,EAChB,OAKH,MAAO9O,MAAKqB,UAAWE,EAAIrB,OAAS,EAAIxD,EAAOwc,OAAQ3X,GAAQA,IAKhEgZ,MAAO,SAAUxa,GAGhB,MAAMA,GAKe,gBAATA,GACJrD,EAAO2K,QAASrH,KAAK,GAAItD,EAAQqD,IAIlCrD,EAAO2K,QAEbtH,EAAKH,OAASG,EAAK,GAAKA,EAAMC,MAXrBA,KAAK,IAAMA,KAAK,GAAGc,WAAed,KAAKgC,QAAQ4pB,UAAU1rB,OAAS,IAc7Eoa,IAAK,SAAUxc,EAAUC,GACxB,GAAIolB,GAA0B,gBAAbrlB,GACfpB,EAAQoB,EAAUC,GAClBrB,EAAOsE,UAAWlD,GAAYA,EAASyC,UAAazC,GAAaA,GAClEiB,EAAMrC,EAAO2D,MAAOL,KAAKmB,MAAOgiB,EAEjC,OAAOnjB,MAAKqB,UAAW3E,EAAOwc,OAAOna,KAGtC8sB,QAAS,SAAU/tB,GAClB,MAAOkC,MAAKsa,IAAiB,MAAZxc,EAChBkC,KAAKwB,WAAaxB,KAAKwB,WAAW0O,OAAOpS,MAK5C,SAASguB,IAAShd,EAAKsD,GACtB,EACCtD,GAAMA,EAAKsD,SACFtD,GAAwB,IAAjBA,EAAIvO,SAErB,OAAOuO,GAGRpS,EAAO+E,MACNgO,OAAQ,SAAU1P,GACjB,GAAI0P,GAAS1P,EAAKe,UAClB,OAAO2O,IAA8B,KAApBA,EAAOlP,SAAkBkP,EAAS,MAEpDsc,QAAS,SAAUhsB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,eAE1BisB,aAAc,SAAUjsB,EAAMoC,EAAG8pB,GAChC,MAAOvvB,GAAO0V,IAAKrS,EAAM,aAAcksB,IAExChL,KAAM,SAAUlhB,GACf,MAAO+rB,IAAS/rB,EAAM,gBAEvBurB,KAAM,SAAUvrB,GACf,MAAO+rB,IAAS/rB,EAAM,oBAEvBmsB,QAAS,SAAUnsB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,gBAE1B6rB,QAAS,SAAU7rB,GAClB,MAAOrD,GAAO0V,IAAKrS,EAAM,oBAE1BosB,UAAW,SAAUpsB,EAAMoC,EAAG8pB,GAC7B,MAAOvvB,GAAO0V,IAAKrS,EAAM,cAAeksB,IAEzCG,UAAW,SAAUrsB,EAAMoC,EAAG8pB,GAC7B,MAAOvvB,GAAO0V,IAAKrS,EAAM,kBAAmBksB,IAE7CI,SAAU,SAAUtsB,GACnB,MAAOrD,GAAOovB,SAAW/rB,EAAKe,gBAAmBiP,WAAYhQ,IAE9DqrB,SAAU,SAAUrrB,GACnB,MAAOrD,GAAOovB,QAAS/rB,EAAKgQ,aAE7Bsb,SAAU,SAAUtrB,GACnB,MAAOrD,GAAOmK,SAAU9G,EAAM,UAC7BA,EAAKusB,iBAAmBvsB,EAAKwsB,cAAcjwB,SAC3CI,EAAO2D,SAAWN,EAAK2F,cAEvB,SAAU5C,EAAM9E,GAClBtB,EAAOsB,GAAI8E,GAAS,SAAUmpB,EAAOnuB,GACpC,GAAIyD,GAAM7E,EAAO4F,IAAKtC,KAAMhC,EAAIiuB,EAsBhC,OApB0B,UAArBnpB,EAAKzF,MAAO,MAChBS,EAAWmuB,GAGPnuB,GAAgC,gBAAbA,KACvByD,EAAM7E,EAAOwT,OAAQpS,EAAUyD,IAG3BvB,KAAKE,OAAS,IAEZirB,GAAkBroB,KACvBvB,EAAM7E,EAAOwc,OAAQ3X,IAIjB0pB,GAAaxqB,KAAMqC,KACvBvB,EAAMA,EAAIirB,YAILxsB,KAAKqB,UAAWE,MAIzB7E,EAAOgG,QACNwN,OAAQ,SAAUoB,EAAMhQ,EAAOuS,GAC9B,GAAI9T,GAAOuB,EAAO,EAMlB,OAJKuS,KACJvC,EAAO,QAAUA,EAAO,KAGD,IAAjBhQ,EAAMpB,QAAkC,IAAlBH,EAAKQ,SACjC7D,EAAO0D,KAAKmQ,gBAAiBxQ,EAAMuR,IAAWvR,MAC9CrD,EAAO0D,KAAKwJ,QAAS0H,EAAM5U,EAAO+K,KAAMnG,EAAO,SAAUvB,GACxD,MAAyB,KAAlBA,EAAKQ,aAIf6R,IAAK,SAAUrS,EAAMqS,EAAK6Z,GACzB,GAAIrY,MACH9E,EAAM/O,EAAMqS,EAEb,OAAQtD,GAAwB,IAAjBA,EAAIvO,WAAmB0rB,IAAUhwB,GAA8B,IAAjB6S,EAAIvO,WAAmB7D,EAAQoS,GAAM2c,GAAIQ,IAC/E,IAAjBnd,EAAIvO,UACRqT,EAAQzW,KAAM2R,GAEfA,EAAMA,EAAIsD,EAEX,OAAOwB,IAGRkY,QAAS,SAAUW,EAAG1sB,GACrB,GAAI2sB,KAEJ,MAAQD,EAAGA,EAAIA,EAAExd,YACI,IAAfwd,EAAElsB,UAAkBksB,IAAM1sB,GAC9B2sB,EAAEvvB,KAAMsvB,EAIV,OAAOC,KAKT,SAASlB,IAAQja,EAAUob,EAAW9Y,GACrC,GAAKnX,EAAOiE,WAAYgsB,GACvB,MAAOjwB,GAAO+K,KAAM8J,EAAU,SAAUxR,EAAMoC,GAE7C,QAASwqB,EAAUzrB,KAAMnB,EAAMoC,EAAGpC,KAAW8T,GAK/C,IAAK8Y,EAAUpsB,SACd,MAAO7D,GAAO+K,KAAM8J,EAAU,SAAUxR,GACvC,MAASA,KAAS4sB,IAAgB9Y,GAKpC,IAA0B,gBAAd8Y,GAAyB,CACpC,GAAK3B,GAASvqB,KAAMksB,GACnB,MAAOjwB,GAAOwT,OAAQyc,EAAWpb,EAAUsC,EAG5C8Y,GAAYjwB,EAAOwT,OAAQyc,EAAWpb,GAGvC,MAAO7U,GAAO+K,KAAM8J,EAAU,SAAUxR,GACvC,MAASrD,GAAO2K,QAAStH,EAAM4sB,IAAe,IAAQ9Y,IAGxD,QAAS+Y,IAAoBtwB,GAC5B,GAAIyd,GAAO8S,GAAU7jB,MAAO,KAC3B8jB,EAAWxwB,EAAS6hB,wBAErB,IAAK2O,EAASvnB,cACb,MAAQwU,EAAK7Z,OACZ4sB,EAASvnB,cACRwU,EAAKpP,MAIR,OAAOmiB,GAGR,GAAID,IAAY,6JAEfE,GAAgB,6BAChBC,GAAmB7hB,OAAO,OAAS0hB,GAAY,WAAY,KAC3DI,GAAqB,OACrBC,GAAY,0EACZC,GAAW,YACXC,GAAS,UACTC,GAAQ,YACRC,GAAe,0BACfC,GAA8B,wBAE9BC,GAAW,oCACXC,GAAc,4BACdC,GAAoB,cACpBC,GAAe,2CAGfC,IACCxK,QAAU,EAAG,+BAAgC,aAC7CyK,QAAU,EAAG,aAAc,eAC3BC,MAAQ,EAAG,QAAS,UACpBC,OAAS,EAAG,WAAY,aACxBC,OAAS,EAAG,UAAW,YACvBC,IAAM,EAAG,iBAAkB,oBAC3BC,KAAO,EAAG,mCAAoC,uBAC9CC,IAAM,EAAG,qBAAsB,yBAI/BhH,SAAUzqB,EAAOmI,QAAQkY,eAAkB,EAAG,GAAI,KAAS,EAAG,SAAU,WAEzEqR,GAAexB,GAAoBtwB,GACnC+xB,GAAcD,GAAaxe,YAAatT,EAASiJ,cAAc,OAEhEqoB,IAAQU,SAAWV,GAAQxK,OAC3BwK,GAAQ9Q,MAAQ8Q,GAAQW,MAAQX,GAAQY,SAAWZ,GAAQa,QAAUb,GAAQI,MAC7EJ,GAAQc,GAAKd,GAAQO,GAErBzxB,EAAOsB,GAAG0E,QACTuE,KAAM,SAAUF,GACf,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAU+G,GACrC,MAAOA,KAAU9K,EAChBS,EAAOuK,KAAMjH,MACbA,KAAKgV,QAAQ2Z,QAAU3uB,KAAK,IAAMA,KAAK,GAAGQ,eAAiBlE,GAAWsyB,eAAgB7nB,KACrF,KAAMA,EAAOhF,UAAU7B,SAG3ByuB,OAAQ,WACP,MAAO3uB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAI0C,GAAS6rB,GAAoB9uB,KAAMD,EACvCkD,GAAO2M,YAAa7P,OAKvBgvB,QAAS,WACR,MAAO/uB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAI0C,GAAS6rB,GAAoB9uB,KAAMD,EACvCkD,GAAO+rB,aAAcjvB,EAAMkD,EAAO8M,gBAKrCkf,OAAQ,WACP,MAAOjvB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACrCC,KAAKc,YACTd,KAAKc,WAAWkuB,aAAcjvB,EAAMC,SAKvCkvB,MAAO,WACN,MAAOlvB,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACrCC,KAAKc,YACTd,KAAKc,WAAWkuB,aAAcjvB,EAAMC,KAAKiP,gBAM5CxJ,OAAQ,SAAU3H,EAAUqxB,GAC3B,GAAIpvB,GACHuB,EAAQxD,EAAWpB,EAAOwT,OAAQpS,EAAUkC,MAASA,KACrDmC,EAAI,CAEL,MAA6B,OAApBpC,EAAOuB,EAAMa,IAAaA,IAE5BgtB,GAA8B,IAAlBpvB,EAAKQ,UACtB7D,EAAOyjB,UAAWiP,GAAQrvB,IAGtBA,EAAKe,aACJquB,GAAYzyB,EAAOmN,SAAU9J,EAAKS,cAAeT,IACrDsvB,GAAeD,GAAQrvB,EAAM,WAE9BA,EAAKe,WAAW0N,YAAazO,GAI/B,OAAOC,OAGRgV,MAAO,WACN,GAAIjV,GACHoC,EAAI,CAEL,MAA4B,OAAnBpC,EAAOC,KAAKmC,IAAaA,IAAM,CAEhB,IAAlBpC,EAAKQ,UACT7D,EAAOyjB,UAAWiP,GAAQrvB,GAAM,GAIjC,OAAQA,EAAKgQ,WACZhQ,EAAKyO,YAAazO,EAAKgQ,WAKnBhQ,GAAKgD,SAAWrG,EAAOmK,SAAU9G,EAAM,YAC3CA,EAAKgD,QAAQ7C,OAAS,GAIxB,MAAOF,OAGRgD,MAAO,SAAUssB,EAAeC,GAI/B,MAHAD,GAAiC,MAAjBA,GAAwB,EAAQA,EAChDC,EAAyC,MAArBA,EAA4BD,EAAgBC,EAEzDvvB,KAAKsC,IAAK,WAChB,MAAO5F,GAAOsG,MAAOhD,KAAMsvB,EAAeC,MAI5CC,KAAM,SAAUzoB,GACf,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAU+G,GACrC,GAAIhH,GAAOC,KAAK,OACfmC,EAAI,EACJqF,EAAIxH,KAAKE,MAEV,IAAK6G,IAAU9K,EACd,MAAyB,KAAlB8D,EAAKQ,SACXR,EAAK+P,UAAUvM,QAASwpB,GAAe,IACvC9wB,CAIF,MAAsB,gBAAV8K,IAAuBumB,GAAa7sB,KAAMsG,KACnDrK,EAAOmI,QAAQkY,eAAkBiQ,GAAavsB,KAAMsG,KACpDrK,EAAOmI,QAAQgY,mBAAsBoQ,GAAmBxsB,KAAMsG,IAC/D6mB,IAAWT,GAAShtB,KAAM4G,KAAY,GAAI,KAAM,GAAGD,gBAAkB,CAEtEC,EAAQA,EAAMxD,QAAS2pB,GAAW,YAElC,KACC,KAAW1lB,EAAJrF,EAAOA,IAEbpC,EAAOC,KAAKmC,OACW,IAAlBpC,EAAKQ,WACT7D,EAAOyjB,UAAWiP,GAAQrvB,GAAM,IAChCA,EAAK+P,UAAY/I,EAInBhH,GAAO,EAGN,MAAM6E,KAGJ7E,GACJC,KAAKgV,QAAQ2Z,OAAQ5nB,IAEpB,KAAMA,EAAOhF,UAAU7B,SAG3BuvB,YAAa,WACZ,GAEC9tB,GAAOjF,EAAO4F,IAAKtC,KAAM,SAAUD,GAClC,OAASA,EAAKkP,YAAalP,EAAKe,cAEjCqB,EAAI,CAmBL,OAhBAnC,MAAK6uB,SAAU9sB,UAAW,SAAUhC,GACnC,GAAIkhB,GAAOtf,EAAMQ,KAChBsN,EAAS9N,EAAMQ,IAEXsN,KAECwR,GAAQA,EAAKngB,aAAe2O,IAChCwR,EAAOjhB,KAAKiP,aAEbvS,EAAQsD,MAAOyF,SACfgK,EAAOuf,aAAcjvB,EAAMkhB,MAG1B,GAGI9e,EAAInC,KAAOA,KAAKyF,UAGxBlG,OAAQ,SAAUzB,GACjB,MAAOkC,MAAKyF,OAAQ3H,GAAU,IAG/B+wB,SAAU,SAAUltB,EAAMD,EAAUguB,GAGnC/tB,EAAO3E,EAAY8E,SAAWH,EAE9B,IAAIK,GAAOuN,EAAMogB,EAChBrqB,EAASkK,EAAK+M,EACdpa,EAAI,EACJqF,EAAIxH,KAAKE,OACTijB,EAAMnjB,KACN4vB,EAAWpoB,EAAI,EACfT,EAAQpF,EAAK,GACbhB,EAAajE,EAAOiE,WAAYoG,EAGjC,IAAKpG,KAAsB,GAAL6G,GAA2B,gBAAVT,IAAsBrK,EAAOmI,QAAQwZ,aAAemP,GAAS/sB,KAAMsG,GACzG,MAAO/G,MAAKyB,KAAK,SAAU8Y,GAC1B,GAAIH,GAAO+I,EAAIlhB,GAAIsY,EACd5Z,KACJgB,EAAK,GAAKoF,EAAM7F,KAAMlB,KAAMua,EAAOH,EAAKoV,SAEzCpV,EAAKyU,SAAUltB,EAAMD,EAAUguB,IAIjC,IAAKloB,IACJ+U,EAAW7f,EAAO8I,cAAe7D,EAAM3B,KAAM,GAAIQ,eAAe,GAAQkvB,GAAqB1vB,MAC7FgC,EAAQua,EAASxM,WAEmB,IAA/BwM,EAAS7W,WAAWxF,SACxBqc,EAAWva,GAGPA,GAAQ,CAMZ,IALAsD,EAAU5I,EAAO4F,IAAK8sB,GAAQ7S,EAAU,UAAYsT,IACpDF,EAAarqB,EAAQpF,OAITsH,EAAJrF,EAAOA,IACdoN,EAAOgN,EAEFpa,IAAMytB,IACVrgB,EAAO7S,EAAOsG,MAAOuM,GAAM,GAAM,GAG5BogB,GACJjzB,EAAO2D,MAAOiF,EAAS8pB,GAAQ7f,EAAM,YAIvC7N,EAASR,KAAMlB,KAAKmC,GAAIoN,EAAMpN,EAG/B,IAAKwtB,EAOJ,IANAngB,EAAMlK,EAASA,EAAQpF,OAAS,GAAIM,cAGpC9D,EAAO4F,IAAKgD,EAASwqB,IAGf3tB,EAAI,EAAOwtB,EAAJxtB,EAAgBA,IAC5BoN,EAAOjK,EAASnD,GACXsrB,GAAYhtB,KAAM8O,EAAKlQ,MAAQ,MAClC3C,EAAO+jB,MAAOlR,EAAM,eAAkB7S,EAAOmN,SAAU2F,EAAKD,KAExDA,EAAK5M,IAETjG,EAAOqzB,SAAUxgB,EAAK5M,KAEtBjG,EAAO+J,YAAc8I,EAAKtI,MAAQsI,EAAKuC,aAAevC,EAAKO,WAAa,IAAKvM,QAASoqB,GAAc,KAOxGpR,GAAWva,EAAQ,KAIrB,MAAOhC,QAMT,SAAS8uB,IAAoB/uB,EAAMiwB,GAClC,MAAOtzB,GAAOmK,SAAU9G,EAAM,UAC7BrD,EAAOmK,SAA+B,IAArBmpB,EAAQzvB,SAAiByvB,EAAUA,EAAQjgB,WAAY,MAExEhQ,EAAKwG,qBAAqB,SAAS,IAClCxG,EAAK6P,YAAa7P,EAAKS,cAAc+E,cAAc,UACpDxF,EAIF,QAAS8vB,IAAe9vB,GAEvB,MADAA,GAAKV,MAA6C,OAArC3C,EAAO0D,KAAKQ,KAAMb,EAAM,SAAqB,IAAMA,EAAKV,KAC9DU,EAER,QAAS+vB,IAAe/vB,GACvB,GAAID,GAAQ4tB,GAAkBvtB,KAAMJ,EAAKV,KAMzC,OALKS,GACJC,EAAKV,KAAOS,EAAM,GAElBC,EAAKgO,gBAAgB,QAEfhO,EAIR,QAASsvB,IAAe/tB,EAAO2uB,GAC9B,GAAIlwB,GACHoC,EAAI,CACL,MAA6B,OAApBpC,EAAOuB,EAAMa,IAAaA,IAClCzF,EAAO+jB,MAAO1gB,EAAM,cAAekwB,GAAevzB,EAAO+jB,MAAOwP,EAAY9tB,GAAI,eAIlF,QAAS+tB,IAAgBvtB,EAAKwtB,GAE7B,GAAuB,IAAlBA,EAAK5vB,UAAmB7D,EAAO6jB,QAAS5d,GAA7C,CAIA,GAAItD,GAAM8C,EAAGqF,EACZ4oB,EAAU1zB,EAAO+jB,MAAO9d,GACxB0tB,EAAU3zB,EAAO+jB,MAAO0P,EAAMC,GAC9BnL,EAASmL,EAAQnL,MAElB,IAAKA,EAAS,OACNoL,GAAQ1K,OACf0K,EAAQpL,SAER,KAAM5lB,IAAQ4lB,GACb,IAAM9iB,EAAI,EAAGqF,EAAIyd,EAAQ5lB,GAAOa,OAAYsH,EAAJrF,EAAOA,IAC9CzF,EAAOyC,MAAMmb,IAAK6V,EAAM9wB,EAAM4lB,EAAQ5lB,GAAQ8C,IAM5CkuB,EAAQlrB,OACZkrB,EAAQlrB,KAAOzI,EAAOgG,UAAY2tB,EAAQlrB,QAI5C,QAASmrB,IAAoB3tB,EAAKwtB,GACjC,GAAItpB,GAAUjC,EAAGO,CAGjB,IAAuB,IAAlBgrB,EAAK5vB,SAAV,CAOA,GAHAsG,EAAWspB,EAAKtpB,SAASC,eAGnBpK,EAAOmI,QAAQgZ,cAAgBsS,EAAMzzB,EAAO0G,SAAY,CAC7D+B,EAAOzI,EAAO+jB,MAAO0P,EAErB,KAAMvrB,IAAKO,GAAK8f,OACfvoB,EAAO4pB,YAAa6J,EAAMvrB,EAAGO,EAAKwgB,OAInCwK,GAAKpiB,gBAAiBrR,EAAO0G,SAIZ,WAAbyD,GAAyBspB,EAAKlpB,OAAStE,EAAIsE,MAC/C4oB,GAAeM,GAAOlpB,KAAOtE,EAAIsE,KACjC6oB,GAAeK,IAIS,WAAbtpB,GACNspB,EAAKrvB,aACTqvB,EAAK3S,UAAY7a,EAAI6a,WAOjB9gB,EAAOmI,QAAQyY,YAAgB3a,EAAImN,YAAcpT,EAAOmB,KAAKsyB,EAAKrgB,aACtEqgB,EAAKrgB,UAAYnN,EAAImN,YAGE,UAAbjJ,GAAwB0mB,GAA4B9sB,KAAMkC,EAAItD,OAKzE8wB,EAAKI,eAAiBJ,EAAKtb,QAAUlS,EAAIkS,QAIpCsb,EAAKppB,QAAUpE,EAAIoE,QACvBopB,EAAKppB,MAAQpE,EAAIoE,QAKM,WAAbF,EACXspB,EAAKK,gBAAkBL,EAAKrb,SAAWnS,EAAI6tB,iBAInB,UAAb3pB,GAAqC,aAAbA,KACnCspB,EAAKlX,aAAetW,EAAIsW,eAI1Bvc,EAAO+E,MACNgvB,SAAU,SACVC,UAAW,UACX1B,aAAc,SACd2B,YAAa,QACbC,WAAY,eACV,SAAU9tB,EAAMulB,GAClB3rB,EAAOsB,GAAI8E,GAAS,SAAUhF,GAC7B,GAAIwD,GACHa,EAAI,EACJZ,KACAsvB,EAASn0B,EAAQoB,GACjBoE,EAAO2uB,EAAO3wB,OAAS,CAExB,MAAagC,GAALC,EAAWA,IAClBb,EAAQa,IAAMD,EAAOlC,KAAOA,KAAKgD,OAAM,GACvCtG,EAAQm0B,EAAO1uB,IAAMkmB,GAAY/mB,GAGjCpE,EAAU4E,MAAOP,EAAKD,EAAMH,MAG7B,OAAOnB,MAAKqB,UAAWE,KAIzB,SAAS6tB,IAAQrxB,EAASsS,GACzB,GAAI/O,GAAOvB,EACVoC,EAAI,EACJ2uB,QAAe/yB,GAAQwI,uBAAyBnK,EAAoB2B,EAAQwI,qBAAsB8J,GAAO,WACjGtS,GAAQ8P,mBAAqBzR,EAAoB2B,EAAQ8P,iBAAkBwC,GAAO,KACzFpU,CAEF,KAAM60B,EACL,IAAMA,KAAYxvB,EAAQvD,EAAQ2H,YAAc3H,EAA8B,OAApBgC,EAAOuB,EAAMa,IAAaA,KAC7EkO,GAAO3T,EAAOmK,SAAU9G,EAAMsQ,GACnCygB,EAAM3zB,KAAM4C,GAEZrD,EAAO2D,MAAOywB,EAAO1B,GAAQrvB,EAAMsQ,GAKtC,OAAOA,KAAQpU,GAAaoU,GAAO3T,EAAOmK,SAAU9I,EAASsS,GAC5D3T,EAAO2D,OAAStC,GAAW+yB,GAC3BA,EAIF,QAASC,IAAmBhxB,GACtBwtB,GAA4B9sB,KAAMV,EAAKV,QAC3CU,EAAKwwB,eAAiBxwB,EAAK8U,SAI7BnY,EAAOgG,QACNM,MAAO,SAAUjD,EAAMuvB,EAAeC,GACrC,GAAIyB,GAAczhB,EAAMvM,EAAOb,EAAG8uB,EACjCC,EAASx0B,EAAOmN,SAAU9J,EAAKS,cAAeT,EAW/C,IATKrD,EAAOmI,QAAQyY,YAAc5gB,EAAOyc,SAASpZ,KAAUitB,GAAavsB,KAAM,IAAMV,EAAK8G,SAAW,KACpG7D,EAAQjD,EAAKwd,WAAW,IAIxB8Q,GAAYve,UAAY/P,EAAKyd,UAC7B6Q,GAAY7f,YAAaxL,EAAQqrB,GAAYte,eAGvCrT,EAAOmI,QAAQgZ,cAAiBnhB,EAAOmI,QAAQmZ,gBACjC,IAAlBje,EAAKQ,UAAoC,KAAlBR,EAAKQ,UAAqB7D,EAAOyc,SAASpZ,IAOnE,IAJAixB,EAAe5B,GAAQpsB,GACvBiuB,EAAc7B,GAAQrvB,GAGhBoC,EAAI,EAA8B,OAA1BoN,EAAO0hB,EAAY9uB,MAAeA,EAE1C6uB,EAAa7uB,IACjBmuB,GAAoB/gB,EAAMyhB,EAAa7uB,GAM1C,IAAKmtB,EACJ,GAAKC,EAIJ,IAHA0B,EAAcA,GAAe7B,GAAQrvB,GACrCixB,EAAeA,GAAgB5B,GAAQpsB,GAEjCb,EAAI,EAA8B,OAA1BoN,EAAO0hB,EAAY9uB,IAAaA,IAC7C+tB,GAAgB3gB,EAAMyhB,EAAa7uB,QAGpC+tB,IAAgBnwB,EAAMiD,EAaxB,OARAguB,GAAe5B,GAAQpsB,EAAO,UACzBguB,EAAa9wB,OAAS,GAC1BmvB,GAAe2B,GAAeE,GAAU9B,GAAQrvB,EAAM,WAGvDixB,EAAeC,EAAc1hB,EAAO,KAG7BvM,GAGRwC,cAAe,SAAUlE,EAAOvD,EAASuH,EAAS6rB,GACjD,GAAI9uB,GAAGtC,EAAM8J,EACZ5D,EAAKoK,EAAKyM,EAAOsU,EACjB5pB,EAAIlG,EAAMpB,OAGVmxB,EAAOzE,GAAoB7uB,GAE3BuzB,KACAnvB,EAAI,CAEL,MAAYqF,EAAJrF,EAAOA,IAGd,GAFApC,EAAOuB,EAAOa,GAETpC,GAAiB,IAATA,EAGZ,GAA6B,WAAxBrD,EAAO2C,KAAMU,GACjBrD,EAAO2D,MAAOixB,EAAOvxB,EAAKQ,UAAaR,GAASA,OAG1C,IAAMstB,GAAM5sB,KAAMV,GAIlB,CACNkG,EAAMA,GAAOorB,EAAKzhB,YAAa7R,EAAQwH,cAAc,QAGrD8K,GAAQ8c,GAAShtB,KAAMJ,KAAW,GAAI,KAAM,GAAG+G,cAC/CsqB,EAAOxD,GAASvd,IAASud,GAAQzG,SAEjClhB,EAAI6J,UAAYshB,EAAK,GAAKrxB,EAAKwD,QAAS2pB,GAAW,aAAgBkE,EAAK,GAGxE/uB,EAAI+uB,EAAK,EACT,OAAQ/uB,IACP4D,EAAMA,EAAIuN,SASX,KALM9W,EAAOmI,QAAQgY,mBAAqBoQ,GAAmBxsB,KAAMV,IAClEuxB,EAAMn0B,KAAMY,EAAQ6wB,eAAgB3B,GAAmB9sB,KAAMJ,GAAO,MAI/DrD,EAAOmI,QAAQiY,MAAQ,CAG5B/c,EAAe,UAARsQ,GAAoB+c,GAAO3sB,KAAMV,GAI3B,YAAZqxB,EAAK,IAAqBhE,GAAO3sB,KAAMV,GAEtC,EADAkG,EAJDA,EAAI8J,WAOL1N,EAAItC,GAAQA,EAAK2F,WAAWxF,MAC5B,OAAQmC,IACF3F,EAAOmK,SAAWiW,EAAQ/c,EAAK2F,WAAWrD,GAAK,WAAcya,EAAMpX,WAAWxF,QAClFH,EAAKyO,YAAasO,GAKrBpgB,EAAO2D,MAAOixB,EAAOrrB,EAAIP,YAGzBO,EAAI6L,YAAc,EAGlB,OAAQ7L,EAAI8J,WACX9J,EAAIuI,YAAavI,EAAI8J,WAItB9J,GAAMorB,EAAK7d,cAtDX8d,GAAMn0B,KAAMY,EAAQ6wB,eAAgB7uB,GA4DlCkG,IACJorB,EAAK7iB,YAAavI,GAKbvJ,EAAOmI,QAAQuZ,eACpB1hB,EAAO+K,KAAM2nB,GAAQkC,EAAO,SAAWP,IAGxC5uB,EAAI,CACJ,OAASpC,EAAOuxB,EAAOnvB,KAItB,KAAKgvB,GAAmD,KAAtCz0B,EAAO2K,QAAStH,EAAMoxB,MAIxCtnB,EAAWnN,EAAOmN,SAAU9J,EAAKS,cAAeT,GAGhDkG,EAAMmpB,GAAQiC,EAAKzhB,YAAa7P,GAAQ,UAGnC8J,GACJwlB,GAAeppB,GAIXX,GAAU,CACdjD,EAAI,CACJ,OAAStC,EAAOkG,EAAK5D,KACforB,GAAYhtB,KAAMV,EAAKV,MAAQ,KACnCiG,EAAQnI,KAAM4C,GAQlB,MAFAkG,GAAM,KAECorB,GAGRlR,UAAW,SAAU7e,EAAsBse,GAC1C,GAAI7f,GAAMV,EAAM0B,EAAIoE,EACnBhD,EAAI,EACJ2d,EAAcpjB,EAAO0G,QACrB8K,EAAQxR,EAAOwR,MACf0P,EAAgBlhB,EAAOmI,QAAQ+Y,cAC/BwH,EAAU1oB,EAAOyC,MAAMimB,OAExB,MAA6B,OAApBrlB,EAAOuB,EAAMa,IAAaA,IAElC,IAAKyd,GAAcljB,EAAOkjB,WAAY7f,MAErCgB,EAAKhB,EAAM+f,GACX3a,EAAOpE,GAAMmN,EAAOnN,IAER,CACX,GAAKoE,EAAK8f,OACT,IAAM5lB,IAAQ8F,GAAK8f,OACbG,EAAS/lB,GACb3C,EAAOyC,MAAMsG,OAAQ1F,EAAMV,GAI3B3C,EAAO4pB,YAAavmB,EAAMV,EAAM8F,EAAKwgB,OAMnCzX;EAAOnN,WAEJmN,GAAOnN,GAKT6c,QACG7d,GAAM+f,SAEK/f,GAAKgO,kBAAoB3R,EAC3C2D,EAAKgO,gBAAiB+R,GAGtB/f,EAAM+f,GAAgB,KAGvBhjB,EAAgBK,KAAM4D,MAO3BgvB,SAAU,SAAUwB,GACnB,MAAO70B,GAAO80B,MACbD,IAAKA,EACLlyB,KAAM,MACNoyB,SAAU,SACVprB,OAAO,EACP0e,QAAQ,EACR2M,UAAU,OAIbh1B,EAAOsB,GAAG0E,QACTivB,QAAS,SAAUnC,GAClB,GAAK9yB,EAAOiE,WAAY6uB,GACvB,MAAOxvB,MAAKyB,KAAK,SAASU,GACzBzF,EAAOsD,MAAM2xB,QAASnC,EAAKtuB,KAAKlB,KAAMmC,KAIxC,IAAKnC,KAAK,GAAK,CAEd,GAAIoxB,GAAO10B,EAAQ8yB,EAAMxvB,KAAK,GAAGQ,eAAgByB,GAAG,GAAGe,OAAM,EAExDhD,MAAK,GAAGc,YACZswB,EAAKpC,aAAchvB,KAAK,IAGzBoxB,EAAK9uB,IAAI,WACR,GAAIvC,GAAOC,IAEX,OAAQD,EAAKgQ,YAA2C,IAA7BhQ,EAAKgQ,WAAWxP,SAC1CR,EAAOA,EAAKgQ,UAGb,OAAOhQ,KACL4uB,OAAQ3uB,MAGZ,MAAOA,OAGR4xB,UAAW,SAAUpC,GACpB,MAAK9yB,GAAOiE,WAAY6uB,GAChBxvB,KAAKyB,KAAK,SAASU,GACzBzF,EAAOsD,MAAM4xB,UAAWpC,EAAKtuB,KAAKlB,KAAMmC,MAInCnC,KAAKyB,KAAK,WAChB,GAAI2Y,GAAO1d,EAAQsD,MAClBqrB,EAAWjR,EAAKiR,UAEZA,GAASnrB,OACbmrB,EAASsG,QAASnC,GAGlBpV,EAAKuU,OAAQa,MAKhB4B,KAAM,SAAU5B,GACf,GAAI7uB,GAAajE,EAAOiE,WAAY6uB,EAEpC,OAAOxvB,MAAKyB,KAAK,SAASU,GACzBzF,EAAQsD,MAAO2xB,QAAShxB,EAAa6uB,EAAKtuB,KAAKlB,KAAMmC,GAAKqtB,MAI5DqC,OAAQ,WACP,MAAO7xB,MAAKyP,SAAShO,KAAK,WACnB/E,EAAOmK,SAAU7G,KAAM,SAC5BtD,EAAQsD,MAAOyvB,YAAazvB,KAAK0F,cAEhCnD,QAGL,IAAIuvB,IAAQC,GAAWC,GACtBC,GAAS,kBACTC,GAAW,wBACXC,GAAY,4BAGZC,GAAe,4BACfC,GAAU,UACVC,GAAgBnnB,OAAQ,KAAOjN,EAAY,SAAU,KACrDq0B,GAAgBpnB,OAAQ,KAAOjN,EAAY,kBAAmB,KAC9Ds0B,GAAcrnB,OAAQ,YAAcjN,EAAY,IAAK,KACrDu0B,IAAgBC,KAAM,SAEtBC,IAAYC,SAAU,WAAYC,WAAY,SAAU7T,QAAS,SACjE8T,IACCC,cAAe,EACfC,WAAY,KAGbC,IAAc,MAAO,QAAS,SAAU,QACxCC,IAAgB,SAAU,IAAK,MAAO,KAGvC,SAASC,IAAgB1qB,EAAO3F,GAG/B,GAAKA,IAAQ2F,GACZ,MAAO3F,EAIR,IAAIswB,GAAUtwB,EAAK7C,OAAO,GAAGhB,cAAgB6D,EAAKzF,MAAM,GACvDg2B,EAAWvwB,EACXX,EAAI+wB,GAAYhzB,MAEjB,OAAQiC,IAEP,GADAW,EAAOowB,GAAa/wB,GAAMixB,EACrBtwB,IAAQ2F,GACZ,MAAO3F,EAIT,OAAOuwB,GAGR,QAASC,IAAUvzB,EAAMwzB,GAIxB,MADAxzB,GAAOwzB,GAAMxzB,EAC4B,SAAlCrD,EAAO82B,IAAKzzB,EAAM,aAA2BrD,EAAOmN,SAAU9J,EAAKS,cAAeT,GAG1F,QAAS0zB,IAAUliB,EAAUmiB,GAC5B,GAAI1U,GAASjf,EAAM4zB,EAClBzX,KACA3B,EAAQ,EACRra,EAASqR,EAASrR,MAEnB,MAAgBA,EAARqa,EAAgBA,IACvBxa,EAAOwR,EAAUgJ,GACXxa,EAAK0I,QAIXyT,EAAQ3B,GAAU7d,EAAO+jB,MAAO1gB,EAAM,cACtCif,EAAUjf,EAAK0I,MAAMuW,QAChB0U,GAGExX,EAAQ3B,IAAuB,SAAZyE,IACxBjf,EAAK0I,MAAMuW,QAAU,IAMM,KAAvBjf,EAAK0I,MAAMuW,SAAkBsU,GAAUvzB,KAC3Cmc,EAAQ3B,GAAU7d,EAAO+jB,MAAO1gB,EAAM,aAAc6zB,GAAmB7zB,EAAK8G,aAIvEqV,EAAQ3B,KACboZ,EAASL,GAAUvzB,IAEdif,GAAuB,SAAZA,IAAuB2U,IACtCj3B,EAAO+jB,MAAO1gB,EAAM,aAAc4zB,EAAS3U,EAAUtiB,EAAO82B,IAAKzzB,EAAM,aAQ3E,KAAMwa,EAAQ,EAAWra,EAARqa,EAAgBA,IAChCxa,EAAOwR,EAAUgJ,GACXxa,EAAK0I,QAGLirB,GAA+B,SAAvB3zB,EAAK0I,MAAMuW,SAA6C,KAAvBjf,EAAK0I,MAAMuW,UACzDjf,EAAK0I,MAAMuW,QAAU0U,EAAOxX,EAAQ3B,IAAW,GAAK,QAItD,OAAOhJ,GAGR7U,EAAOsB,GAAG0E,QACT8wB,IAAK,SAAU1wB,EAAMiE,GACpB,MAAOrK,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAM+C,EAAMiE,GACjD,GAAI3E,GAAKyxB,EACRvxB,KACAH,EAAI,CAEL,IAAKzF,EAAOyG,QAASL,GAAS,CAI7B,IAHA+wB,EAAS9B,GAAWhyB,GACpBqC,EAAMU,EAAK5C,OAECkC,EAAJD,EAASA,IAChBG,EAAKQ,EAAMX,IAAQzF,EAAO82B,IAAKzzB,EAAM+C,EAAMX,IAAK,EAAO0xB,EAGxD,OAAOvxB,GAGR,MAAOyE,KAAU9K,EAChBS,EAAO+L,MAAO1I,EAAM+C,EAAMiE,GAC1BrK,EAAO82B,IAAKzzB,EAAM+C,IACjBA,EAAMiE,EAAOhF,UAAU7B,OAAS,IAEpCwzB,KAAM,WACL,MAAOD,IAAUzzB,MAAM,IAExB8zB,KAAM,WACL,MAAOL,IAAUzzB,OAElB+zB,OAAQ,SAAUlZ,GACjB,MAAsB,iBAAVA,GACJA,EAAQ7a,KAAK0zB,OAAS1zB,KAAK8zB,OAG5B9zB,KAAKyB,KAAK,WACX6xB,GAAUtzB,MACdtD,EAAQsD,MAAO0zB,OAEfh3B,EAAQsD,MAAO8zB,YAMnBp3B,EAAOgG,QAGNsxB,UACC/W,SACC9b,IAAK,SAAUpB,EAAMk0B,GACpB,GAAKA,EAAW,CAEf,GAAI1yB,GAAMywB,GAAQjyB,EAAM,UACxB,OAAe,KAARwB,EAAa,IAAMA,MAO9B2yB,WACCC,aAAe,EACfC,aAAe,EACfpB,YAAc,EACdqB,YAAc,EACdpX,SAAW,EACXqX,OAAS,EACTC,SAAW,EACXC,QAAU,EACVC,QAAU,EACVvV,MAAQ,GAKTwV,UAECC,QAASj4B,EAAOmI,QAAQqY,SAAW,WAAa,cAIjDzU,MAAO,SAAU1I,EAAM+C,EAAMiE,EAAO6tB,GAEnC,GAAM70B,GAA0B,IAAlBA,EAAKQ,UAAoC,IAAlBR,EAAKQ,UAAmBR,EAAK0I,MAAlE,CAKA,GAAIlH,GAAKlC,EAAM0hB,EACdsS,EAAW32B,EAAOiK,UAAW7D,GAC7B2F,EAAQ1I,EAAK0I,KASd,IAPA3F,EAAOpG,EAAOg4B,SAAUrB,KAAgB32B,EAAOg4B,SAAUrB,GAAaF,GAAgB1qB,EAAO4qB,IAI7FtS,EAAQrkB,EAAOs3B,SAAUlxB,IAAUpG,EAAOs3B,SAAUX,GAG/CtsB,IAAU9K,EAsCd,MAAK8kB,IAAS,OAASA,KAAUxf,EAAMwf,EAAM5f,IAAKpB,GAAM,EAAO60B,MAAa34B,EACpEsF,EAIDkH,EAAO3F,EAhCd,IAVAzD,QAAc0H,GAGA,WAAT1H,IAAsBkC,EAAMixB,GAAQryB,KAAM4G,MAC9CA,GAAUxF,EAAI,GAAK,GAAMA,EAAI,GAAKiD,WAAY9H,EAAO82B,IAAKzzB,EAAM+C,IAEhEzD,EAAO,YAIM,MAAT0H,GAA0B,WAAT1H,GAAqBkF,MAAOwC,KAKpC,WAAT1H,GAAsB3C,EAAOw3B,UAAWb,KAC5CtsB,GAAS,MAKJrK,EAAOmI,QAAQ6Z,iBAA6B,KAAV3X,GAA+C,IAA/BjE,EAAKvF,QAAQ,gBACpEkL,EAAO3F,GAAS,WAIXie,GAAW,OAASA,KAAWha,EAAQga,EAAMoC,IAAKpjB,EAAMgH,EAAO6tB,MAAa34B,IAIjF,IACCwM,EAAO3F,GAASiE,EACf,MAAMnC,OAcX4uB,IAAK,SAAUzzB,EAAM+C,EAAM8xB,EAAOf,GACjC,GAAIzyB,GAAKoQ,EAAKuP,EACbsS,EAAW32B,EAAOiK,UAAW7D,EAyB9B,OAtBAA,GAAOpG,EAAOg4B,SAAUrB,KAAgB32B,EAAOg4B,SAAUrB,GAAaF,GAAgBpzB,EAAK0I,MAAO4qB,IAIlGtS,EAAQrkB,EAAOs3B,SAAUlxB,IAAUpG,EAAOs3B,SAAUX,GAG/CtS,GAAS,OAASA,KACtBvP,EAAMuP,EAAM5f,IAAKpB,GAAM,EAAM60B,IAIzBpjB,IAAQvV,IACZuV,EAAMwgB,GAAQjyB,EAAM+C,EAAM+wB,IAId,WAARriB,GAAoB1O,IAAQgwB,MAChCthB,EAAMshB,GAAoBhwB,IAIZ,KAAV8xB,GAAgBA,GACpBxzB,EAAMoD,WAAYgN,GACXojB,KAAU,GAAQl4B,EAAO4H,UAAWlD,GAAQA,GAAO,EAAIoQ,GAExDA,KAMJxV,EAAOqjB,kBACX0S,GAAY,SAAUhyB,GACrB,MAAO/D,GAAOqjB,iBAAkBtf,EAAM,OAGvCiyB,GAAS,SAAUjyB,EAAM+C,EAAM+xB,GAC9B,GAAIvV,GAAOwV,EAAUC,EACpBd,EAAWY,GAAa9C,GAAWhyB,GAGnCwB,EAAM0yB,EAAWA,EAASe,iBAAkBlyB,IAAUmxB,EAAUnxB,GAAS7G,EACzEwM,EAAQ1I,EAAK0I,KA8Bd,OA5BKwrB,KAES,KAAR1yB,GAAe7E,EAAOmN,SAAU9J,EAAKS,cAAeT,KACxDwB,EAAM7E,EAAO+L,MAAO1I,EAAM+C,IAOtByvB,GAAU9xB,KAAMc,IAAS8wB,GAAQ5xB,KAAMqC,KAG3Cwc,EAAQ7W,EAAM6W,MACdwV,EAAWrsB,EAAMqsB,SACjBC,EAAWtsB,EAAMssB,SAGjBtsB,EAAMqsB,SAAWrsB,EAAMssB,SAAWtsB,EAAM6W,MAAQ/d,EAChDA,EAAM0yB,EAAS3U,MAGf7W,EAAM6W,MAAQA,EACd7W,EAAMqsB,SAAWA,EACjBrsB,EAAMssB,SAAWA,IAIZxzB,IAEGjF,EAASE,gBAAgBy4B,eACpClD,GAAY,SAAUhyB,GACrB,MAAOA,GAAKk1B,cAGbjD,GAAS,SAAUjyB,EAAM+C,EAAM+xB,GAC9B,GAAIK,GAAMC,EAAIC,EACbnB,EAAWY,GAAa9C,GAAWhyB,GACnCwB,EAAM0yB,EAAWA,EAAUnxB,GAAS7G,EACpCwM,EAAQ1I,EAAK0I,KAoCd,OAhCY,OAAPlH,GAAekH,GAASA,EAAO3F,KACnCvB,EAAMkH,EAAO3F,IAUTyvB,GAAU9xB,KAAMc,KAAU4wB,GAAU1xB,KAAMqC,KAG9CoyB,EAAOzsB,EAAMysB,KACbC,EAAKp1B,EAAKs1B,aACVD,EAASD,GAAMA,EAAGD,KAGbE,IACJD,EAAGD,KAAOn1B,EAAKk1B,aAAaC,MAE7BzsB,EAAMysB,KAAgB,aAATpyB,EAAsB,MAAQvB,EAC3CA,EAAMkH,EAAM6sB,UAAY,KAGxB7sB,EAAMysB,KAAOA,EACRE,IACJD,EAAGD,KAAOE,IAIG,KAAR7zB,EAAa,OAASA,GAI/B,SAASg0B,IAAmBx1B,EAAMgH,EAAOyuB,GACxC,GAAI5rB,GAAU0oB,GAAUnyB,KAAM4G,EAC9B,OAAO6C,GAENvG,KAAKiE,IAAK,EAAGsC,EAAS,IAAQ4rB,GAAY,KAAU5rB,EAAS,IAAO,MACpE7C,EAGF,QAAS0uB,IAAsB11B,EAAM+C,EAAM8xB,EAAOc,EAAa7B,GAC9D,GAAI1xB,GAAIyyB,KAAYc,EAAc,SAAW,WAE5C,EAES,UAAT5yB,EAAmB,EAAI,EAEvB0O,EAAM,CAEP,MAAY,EAAJrP,EAAOA,GAAK,EAEJ,WAAVyyB,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM60B,EAAQ3B,GAAW9wB,IAAK,EAAM0xB,IAGnD6B,GAEW,YAAVd,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,UAAYkzB,GAAW9wB,IAAK,EAAM0xB,IAI7C,WAAVe,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,SAAWkzB,GAAW9wB,GAAM,SAAS,EAAM0xB,MAIrEriB,GAAO9U,EAAO82B,IAAKzzB,EAAM,UAAYkzB,GAAW9wB,IAAK,EAAM0xB,GAG5C,YAAVe,IACJpjB,GAAO9U,EAAO82B,IAAKzzB,EAAM,SAAWkzB,GAAW9wB,GAAM,SAAS,EAAM0xB,IAKvE,OAAOriB,GAGR,QAASmkB,IAAkB51B,EAAM+C,EAAM8xB,GAGtC,GAAIgB,IAAmB,EACtBpkB,EAAe,UAAT1O,EAAmB/C,EAAKqf,YAAcrf,EAAKgf,aACjD8U,EAAS9B,GAAWhyB,GACpB21B,EAAch5B,EAAOmI,QAAQsa,WAAgE,eAAnDziB,EAAO82B,IAAKzzB,EAAM,aAAa,EAAO8zB,EAKjF,IAAY,GAAPriB,GAAmB,MAAPA,EAAc,CAQ9B,GANAA,EAAMwgB,GAAQjyB,EAAM+C,EAAM+wB,IACf,EAANriB,GAAkB,MAAPA,KACfA,EAAMzR,EAAK0I,MAAO3F,IAIdyvB,GAAU9xB,KAAK+Q,GACnB,MAAOA,EAKRokB,GAAmBF,IAAiBh5B,EAAOmI,QAAQkZ,mBAAqBvM,IAAQzR,EAAK0I,MAAO3F,IAG5F0O,EAAMhN,WAAYgN,IAAS,EAI5B,MAASA,GACRikB,GACC11B,EACA+C,EACA8xB,IAAWc,EAAc,SAAW,WACpCE,EACA/B,GAEE,KAIL,QAASD,IAAoB/sB,GAC5B,GAAI2I,GAAMlT,EACT0iB,EAAUyT,GAAa5rB,EA0BxB,OAxBMmY,KACLA,EAAU6W,GAAehvB,EAAU2I,GAGlB,SAAZwP,GAAuBA,IAE3B8S,IAAWA,IACVp1B,EAAO,kDACN82B,IAAK,UAAW,6BAChB/C,SAAUjhB,EAAIhT,iBAGhBgT,GAAQsiB,GAAO,GAAGvF,eAAiBuF,GAAO,GAAGxF,iBAAkBhwB,SAC/DkT,EAAIsmB,MAAM,+BACVtmB,EAAIumB,QAEJ/W,EAAU6W,GAAehvB,EAAU2I,GACnCsiB,GAAOvyB,UAIRkzB,GAAa5rB,GAAamY,GAGpBA,EAIR,QAAS6W,IAAe/yB,EAAM0M,GAC7B,GAAIzP,GAAOrD,EAAQ8S,EAAIjK,cAAezC,IAAS2tB,SAAUjhB,EAAI1L,MAC5Dkb,EAAUtiB,EAAO82B,IAAKzzB,EAAK,GAAI,UAEhC,OADAA,GAAK0F,SACEuZ,EAGRtiB,EAAO+E,MAAO,SAAU,SAAW,SAAUU,EAAGW,GAC/CpG,EAAOs3B,SAAUlxB,IAChB3B,IAAK,SAAUpB,EAAMk0B,EAAUW,GAC9B,MAAKX,GAGwB,IAArBl0B,EAAKqf,aAAqBgT,GAAa3xB,KAAM/D,EAAO82B,IAAKzzB,EAAM,YACrErD,EAAO6L,KAAMxI,EAAM4yB,GAAS,WAC3B,MAAOgD,IAAkB51B,EAAM+C,EAAM8xB,KAEtCe,GAAkB51B,EAAM+C,EAAM8xB,GAPhC,GAWDzR,IAAK,SAAUpjB,EAAMgH,EAAO6tB,GAC3B,GAAIf,GAASe,GAAS7C,GAAWhyB,EACjC,OAAOw1B,IAAmBx1B,EAAMgH,EAAO6tB,EACtCa,GACC11B,EACA+C,EACA8xB,EACAl4B,EAAOmI,QAAQsa,WAAgE,eAAnDziB,EAAO82B,IAAKzzB,EAAM,aAAa,EAAO8zB,GAClEA,GACG,OAMFn3B,EAAOmI,QAAQoY,UACpBvgB,EAAOs3B,SAAS/W,SACf9b,IAAK,SAAUpB,EAAMk0B,GAEpB,MAAO/B,IAASzxB,MAAOwzB,GAAYl0B,EAAKk1B,aAAel1B,EAAKk1B,aAAa/kB,OAASnQ,EAAK0I,MAAMyH,SAAW,IACrG,IAAO1L,WAAY2G,OAAO6qB,IAAS,GACrC/B,EAAW,IAAM,IAGnB9Q,IAAK,SAAUpjB,EAAMgH,GACpB,GAAI0B,GAAQ1I,EAAK0I,MAChBwsB,EAAel1B,EAAKk1B,aACpBhY,EAAUvgB,EAAO4H,UAAWyC,GAAU,iBAA2B,IAARA,EAAc,IAAM,GAC7EmJ,EAAS+kB,GAAgBA,EAAa/kB,QAAUzH,EAAMyH,QAAU,EAIjEzH,GAAMyW,KAAO,GAINnY,GAAS,GAAe,KAAVA,IAC6B,KAAhDrK,EAAOmB,KAAMqS,EAAO3M,QAAS0uB,GAAQ,MACrCxpB,EAAMsF,kBAKPtF,EAAMsF,gBAAiB,UAGR,KAAVhH,GAAgBkuB,IAAiBA,EAAa/kB,UAMpDzH,EAAMyH,OAAS+hB,GAAOxxB,KAAMyP,GAC3BA,EAAO3M,QAAS0uB,GAAQhV,GACxB/M,EAAS,IAAM+M,MAOnBvgB,EAAO,WACAA,EAAOmI,QAAQiZ,sBACpBphB,EAAOs3B,SAASzU,aACfpe,IAAK,SAAUpB,EAAMk0B,GACpB,MAAKA,GAGGv3B,EAAO6L,KAAMxI,GAAQif,QAAW,gBACtCgT,IAAUjyB,EAAM,gBAJlB,MAaGrD,EAAOmI,QAAQ8Y,eAAiBjhB,EAAOsB,GAAG40B,UAC/Cl2B,EAAO+E,MAAQ,MAAO,QAAU,SAAUU,EAAGmgB,GAC5C5lB,EAAOs3B,SAAU1R,IAChBnhB,IAAK,SAAUpB,EAAMk0B,GACpB,MAAKA,IACJA,EAAWjC,GAAQjyB,EAAMuiB,GAElBiQ,GAAU9xB,KAAMwzB,GACtBv3B,EAAQqD,GAAO6yB,WAAYtQ,GAAS,KACpC2R,GALF,QAcAv3B,EAAO4U,MAAQ5U,EAAO4U,KAAKwE,UAC/BpZ,EAAO4U,KAAKwE,QAAQ6d,OAAS,SAAU5zB,GAGtC,MAA2B,IAApBA,EAAKqf,aAAyC,GAArBrf,EAAKgf,eAClCriB,EAAOmI,QAAQoa,uBAAmG,UAAxElf,EAAK0I,OAAS1I,EAAK0I,MAAMuW,SAAYtiB,EAAO82B,IAAKzzB,EAAM,aAGrGrD,EAAO4U,KAAKwE,QAAQmgB,QAAU,SAAUl2B,GACvC,OAAQrD,EAAO4U,KAAKwE,QAAQ6d,OAAQ5zB,KAKtCrD,EAAO+E,MACNy0B,OAAQ,GACRC,QAAS,GACTC,OAAQ,SACN,SAAUC,EAAQC,GACpB55B,EAAOs3B,SAAUqC,EAASC,IACzBC,OAAQ,SAAUxvB,GACjB,GAAI5E,GAAI,EACPq0B,KAGAC,EAAyB,gBAAV1vB,GAAqBA,EAAMiC,MAAM,MAASjC,EAE1D,MAAY,EAAJ5E,EAAOA,IACdq0B,EAAUH,EAASpD,GAAW9wB,GAAMm0B,GACnCG,EAAOt0B,IAAOs0B,EAAOt0B,EAAI,IAAOs0B,EAAO,EAGzC,OAAOD,KAIHnE,GAAQ5xB,KAAM41B,KACnB35B,EAAOs3B,SAAUqC,EAASC,GAASnT,IAAMoS,KAG3C,IAAImB,IAAM,OACTC,GAAW,QACXC,GAAQ,SACRC,GAAkB,wCAClBC,GAAe,oCAEhBp6B,GAAOsB,GAAG0E,QACTq0B,UAAW,WACV,MAAOr6B,GAAOqxB,MAAO/tB,KAAKg3B,mBAE3BA,eAAgB,WACf,MAAOh3B,MAAKsC,IAAI,WAEf,GAAIiP,GAAW7U,EAAO4lB,KAAMtiB,KAAM,WAClC,OAAOuR,GAAW7U,EAAOsE,UAAWuQ,GAAavR,OAEjDkQ,OAAO,WACP,GAAI7Q,GAAOW,KAAKX,IAEhB,OAAOW,MAAK8C,OAASpG,EAAQsD,MAAOyrB,GAAI,cACvCqL,GAAar2B,KAAMT,KAAK6G,YAAegwB,GAAgBp2B,KAAMpB,KAC3DW,KAAK6U,UAAY0Y,GAA4B9sB,KAAMpB,MAEtDiD,IAAI,SAAUH,EAAGpC,GACjB,GAAIyR,GAAM9U,EAAQsD,MAAOwR,KAEzB,OAAc,OAAPA,EACN,KACA9U,EAAOyG,QAASqO,GACf9U,EAAO4F,IAAKkP,EAAK,SAAUA,GAC1B,OAAS1O,KAAM/C,EAAK+C,KAAMiE,MAAOyK,EAAIjO,QAASqzB,GAAO,YAEpD9zB,KAAM/C,EAAK+C,KAAMiE,MAAOyK,EAAIjO,QAASqzB,GAAO,WAC9Cz1B,SAMLzE,EAAOqxB,MAAQ,SAAUzjB,EAAG2sB,GAC3B,GAAIZ,GACHa,KACA5c,EAAM,SAAU3V,EAAKoC,GAEpBA,EAAQrK,EAAOiE,WAAYoG,GAAUA,IAAqB,MAATA,EAAgB,GAAKA,EACtEmwB,EAAGA,EAAEh3B,QAAWi3B,mBAAoBxyB,GAAQ,IAAMwyB,mBAAoBpwB,GASxE,IALKkwB,IAAgBh7B,IACpBg7B,EAAcv6B,EAAO06B,cAAgB16B,EAAO06B,aAAaH,aAIrDv6B,EAAOyG,QAASmH,IAASA,EAAE1K,SAAWlD,EAAOgE,cAAe4J,GAEhE5N,EAAO+E,KAAM6I,EAAG,WACfgQ,EAAKta,KAAK8C,KAAM9C,KAAK+G,aAMtB,KAAMsvB,IAAU/rB,GACf+sB,GAAahB,EAAQ/rB,EAAG+rB,GAAUY,EAAa3c,EAKjD,OAAO4c,GAAEtpB,KAAM,KAAMrK,QAASmzB,GAAK,KAGpC,SAASW,IAAahB,EAAQlyB,EAAK8yB,EAAa3c,GAC/C,GAAIxX,EAEJ,IAAKpG,EAAOyG,QAASgB,GAEpBzH,EAAO+E,KAAM0C,EAAK,SAAUhC,EAAGm1B,GACzBL,GAAeN,GAASl2B,KAAM41B,GAElC/b,EAAK+b,EAAQiB,GAIbD,GAAahB,EAAS,KAAqB,gBAANiB,GAAiBn1B,EAAI,IAAO,IAAKm1B,EAAGL,EAAa3c,SAIlF,IAAM2c,GAAsC,WAAvBv6B,EAAO2C,KAAM8E,GAQxCmW,EAAK+b,EAAQlyB,OANb,KAAMrB,IAAQqB,GACbkzB,GAAahB,EAAS,IAAMvzB,EAAO,IAAKqB,EAAKrB,GAAQm0B,EAAa3c,GAQrE5d,EAAO+E,KAAM,0MAEqDuH,MAAM,KAAM,SAAU7G,EAAGW,GAG1FpG,EAAOsB,GAAI8E,GAAS,SAAUqC,EAAMnH,GACnC,MAAO+D,WAAU7B,OAAS,EACzBF,KAAK6qB,GAAI/nB,EAAM,KAAMqC,EAAMnH,GAC3BgC,KAAKiE,QAASnB,MAIjBpG,EAAOsB,GAAG0E,QACT60B,MAAO,SAAUC,EAAQC,GACxB,MAAOz3B,MAAKiqB,WAAYuN,GAAStN,WAAYuN,GAASD,IAGvDE,KAAM,SAAU1S,EAAO7f,EAAMnH,GAC5B,MAAOgC,MAAK6qB,GAAI7F,EAAO,KAAM7f,EAAMnH,IAEpC25B,OAAQ,SAAU3S,EAAOhnB,GACxB,MAAOgC,MAAKkE,IAAK8gB,EAAO,KAAMhnB,IAG/B45B,SAAU,SAAU95B,EAAUknB,EAAO7f,EAAMnH,GAC1C,MAAOgC,MAAK6qB,GAAI7F,EAAOlnB,EAAUqH,EAAMnH,IAExC65B,WAAY,SAAU/5B,EAAUknB,EAAOhnB,GAEtC,MAA4B,KAArB+D,UAAU7B,OAAeF,KAAKkE,IAAKpG,EAAU,MAASkC,KAAKkE,IAAK8gB,EAAOlnB,GAAY,KAAME,KAGlG,IAEC85B,IACAC,GACAC,GAAat7B,EAAO0L,MAEpB6vB,GAAc,KACdC,GAAQ,OACRC,GAAM,gBACNC,GAAW,gCAEXC,GAAiB,4DACjBC,GAAa,iBACbC,GAAY,QACZC,GAAO,8CAGPC,GAAQ/7B,EAAOsB,GAAGqrB,KAWlBqP,MAOAC,MAGAC,GAAW,KAAK37B,OAAO,IAIxB,KACC86B,GAAe17B,EAASoY,KACvB,MAAO7P,IAGRmzB,GAAez7B,EAASiJ,cAAe,KACvCwyB,GAAatjB,KAAO,GACpBsjB,GAAeA,GAAatjB,KAI7BqjB,GAAeU,GAAKr4B,KAAM43B,GAAajxB,kBAGvC,SAAS+xB,IAA6BC,GAGrC,MAAO,UAAUC,EAAoBpe,GAED,gBAAvBoe,KACXpe,EAAOoe,EACPA,EAAqB,IAGtB,IAAItH,GACHtvB,EAAI,EACJ62B,EAAYD,EAAmBjyB,cAAchH,MAAO1B,MAErD,IAAK1B,EAAOiE,WAAYga,GAEvB,MAAS8W,EAAWuH,EAAU72B,KAER,MAAhBsvB,EAAS,IACbA,EAAWA,EAASp0B,MAAO,IAAO,KACjCy7B,EAAWrH,GAAaqH,EAAWrH,QAAkBpgB,QAASsJ,KAI9Dme,EAAWrH,GAAaqH,EAAWrH,QAAkBt0B,KAAMwd,IAQjE,QAASse,IAA+BH,EAAW/1B,EAASm2B,EAAiBC,GAE5E,GAAIC,MACHC,EAAqBP,IAAcH,EAEpC,SAASW,GAAS7H,GACjB,GAAI3c,EAYJ,OAXAskB,GAAW3H,IAAa,EACxB/0B,EAAO+E,KAAMq3B,EAAWrH,OAAkB,SAAUhlB,EAAG8sB,GACtD,GAAIC,GAAsBD,EAAoBx2B,EAASm2B,EAAiBC,EACxE,OAAmC,gBAAxBK,IAAqCH,GAAqBD,EAAWI,GAIpEH,IACDvkB,EAAW0kB,GADf,GAHNz2B,EAAQi2B,UAAU3nB,QAASmoB,GAC3BF,EAASE,IACF,KAKF1kB,EAGR,MAAOwkB,GAASv2B,EAAQi2B,UAAW,MAAUI,EAAW,MAASE,EAAS,KAM3E,QAASG,IAAYx2B,EAAQN,GAC5B,GAAIO,GAAMyB,EACT+0B,EAAch9B,EAAO06B,aAAasC,eAEnC,KAAM/0B,IAAOhC,GACPA,EAAKgC,KAAU1I,KACjBy9B,EAAa/0B,GAAQ1B,EAAWC,IAASA,OAAgByB,GAAQhC,EAAKgC,GAO1E,OAJKzB,IACJxG,EAAOgG,QAAQ,EAAMO,EAAQC,GAGvBD,EAGRvG,EAAOsB,GAAGqrB,KAAO,SAAUkI,EAAKoI,EAAQj4B,GACvC,GAAoB,gBAAR6vB,IAAoBkH,GAC/B,MAAOA,IAAM32B,MAAO9B,KAAM+B,UAG3B,IAAIjE,GAAU87B,EAAUv6B,EACvB+a,EAAOpa,KACPkE,EAAMqtB,EAAIh0B,QAAQ,IA+CnB,OA7CK2G,IAAO,IACXpG,EAAWyzB,EAAIl0B,MAAO6G,EAAKqtB,EAAIrxB,QAC/BqxB,EAAMA,EAAIl0B,MAAO,EAAG6G,IAIhBxH,EAAOiE,WAAYg5B,IAGvBj4B,EAAWi4B,EACXA,EAAS19B,GAGE09B,GAA4B,gBAAXA,KAC5Bt6B,EAAO,QAIH+a,EAAKla,OAAS,GAClBxD,EAAO80B,MACND,IAAKA,EAGLlyB,KAAMA,EACNoyB,SAAU,OACVtsB,KAAMw0B,IACJ93B,KAAK,SAAUg4B,GAGjBD,EAAW73B,UAEXqY,EAAKoV,KAAM1xB,EAIVpB,EAAO,SAASiyB,OAAQjyB,EAAO4D,UAAWu5B,IAAiBz5B,KAAMtC,GAGjE+7B,KAECC,SAAUp4B,GAAY,SAAUy3B,EAAOY,GACzC3f,EAAK3Y,KAAMC,EAAUk4B,IAAcT,EAAMU,aAAcE,EAAQZ,MAI1Dn5B,MAIRtD,EAAO+E,MAAQ,YAAa,WAAY,eAAgB,YAAa,cAAe,YAAc,SAAUU,EAAG9C,GAC9G3C,EAAOsB,GAAIqB,GAAS,SAAUrB,GAC7B,MAAOgC,MAAK6qB,GAAIxrB,EAAMrB,MAIxBtB,EAAOgG,QAGNs3B,OAAQ,EAGRC,gBACAC,QAEA9C,cACC7F,IAAKwG,GACL14B,KAAM,MACN86B,QAAS9B,GAAe53B,KAAMq3B,GAAc,IAC5C/S,QAAQ,EACRqV,aAAa,EACb/zB,OAAO,EACPg0B,YAAa,mDAabC,SACCC,IAAK3B,GACL3xB,KAAM,aACNuoB,KAAM,YACNxpB,IAAK,4BACLw0B,KAAM,qCAGPnP,UACCrlB,IAAK,MACLwpB,KAAM,OACNgL,KAAM,QAGPC,gBACCz0B,IAAK,cACLiB,KAAM,eACNuzB,KAAM,gBAKPE,YAGCC,SAAUj2B,OAGVk2B,aAAa,EAGbC,YAAan+B,EAAOiJ,UAGpBm1B,WAAYp+B,EAAOqJ,UAOpB2zB,aACCnI,KAAK,EACLxzB,SAAS,IAOXg9B,UAAW,SAAU93B,EAAQ+3B,GAC5B,MAAOA,GAGNvB,GAAYA,GAAYx2B,EAAQvG,EAAO06B,cAAgB4D,GAGvDvB,GAAY/8B,EAAO06B,aAAcn0B,IAGnCg4B,cAAepC,GAA6BH,IAC5CwC,cAAerC,GAA6BF,IAG5CnH,KAAM,SAAUD,EAAKxuB,GAGA,gBAARwuB,KACXxuB,EAAUwuB,EACVA,EAAMt1B,GAIP8G,EAAUA,KAEV,IACC0zB,GAEAt0B,EAEAg5B,EAEAC,EAEAC,EAGAC,EAEAC,EAEAC,EAEAtE,EAAIx6B,EAAOq+B,aAAeh4B,GAE1B04B,EAAkBvE,EAAEn5B,SAAWm5B,EAE/BwE,EAAqBxE,EAAEn5B,UAAa09B,EAAgBl7B,UAAYk7B,EAAgB77B,QAC/ElD,EAAQ++B,GACR/+B,EAAOyC,MAER4b,EAAWre,EAAOgM,WAClBizB,EAAmBj/B,EAAO8c,UAAU,eAEpCoiB,EAAa1E,EAAE0E,eAEfC,KACAC,KAEAjhB,EAAQ,EAERkhB,EAAW,WAEX5C,GACC75B,WAAY,EAGZ08B,kBAAmB,SAAUr3B,GAC5B,GAAI7E,EACJ,IAAe,IAAV+a,EAAc,CAClB,IAAM2gB,EAAkB,CACvBA,IACA,OAAS17B,EAAQs4B,GAASj4B,KAAMi7B,GAC/BI,EAAiB17B,EAAM,GAAGgH,eAAkBhH,EAAO,GAGrDA,EAAQ07B,EAAiB72B,EAAImC,eAE9B,MAAgB,OAAThH,EAAgB,KAAOA,GAI/Bm8B,sBAAuB,WACtB,MAAiB,KAAVphB,EAAcugB,EAAwB,MAI9Cc,iBAAkB,SAAUp5B,EAAMiE,GACjC,GAAIo1B,GAAQr5B,EAAKgE,aAKjB,OAJM+T,KACL/X,EAAOg5B,EAAqBK,GAAUL,EAAqBK,IAAWr5B,EACtE+4B,EAAgB/4B,GAASiE,GAEnB/G,MAIRo8B,iBAAkB,SAAU/8B,GAI3B,MAHMwb,KACLqc,EAAEmF,SAAWh9B,GAEPW,MAIR47B,WAAY,SAAUt5B,GACrB,GAAIg6B,EACJ,IAAKh6B,EACJ,GAAa,EAARuY,EACJ,IAAMyhB,IAAQh6B,GAEbs5B,EAAYU,IAAWV,EAAYU,GAAQh6B,EAAKg6B,QAIjDnD,GAAMre,OAAQxY,EAAK62B,EAAMY,QAG3B,OAAO/5B,OAIRu8B,MAAO,SAAUC,GAChB,GAAIC,GAAYD,GAAcT,CAK9B,OAJKR,IACJA,EAAUgB,MAAOE,GAElB56B,EAAM,EAAG46B,GACFz8B,MAwCV,IAnCA+a,EAASnZ,QAASu3B,GAAQW,SAAW6B,EAAiBrhB,IACtD6e,EAAMuD,QAAUvD,EAAMt3B,KACtBs3B,EAAMn0B,MAAQm0B,EAAMne,KAMpBkc,EAAE3F,MAAUA,GAAO2F,EAAE3F,KAAOwG,IAAiB,IAAKx0B,QAAS20B,GAAO,IAAK30B,QAASg1B,GAAWT,GAAc,GAAM,MAG/GZ,EAAE73B,KAAO0D,EAAQ45B,QAAU55B,EAAQ1D,MAAQ63B,EAAEyF,QAAUzF,EAAE73B,KAGzD63B,EAAE8B,UAAYt8B,EAAOmB,KAAMq5B,EAAEzF,UAAY,KAAM3qB,cAAchH,MAAO1B,KAAqB,IAGnE,MAAjB84B,EAAE0F,cACNnG,EAAQ+B,GAAKr4B,KAAM+2B,EAAE3F,IAAIzqB,eACzBowB,EAAE0F,eAAkBnG,GACjBA,EAAO,KAAQqB,GAAc,IAAOrB,EAAO,KAAQqB,GAAc,KAChErB,EAAO,KAAwB,UAAfA,EAAO,GAAkB,KAAO,WAC/CqB,GAAc,KAA+B,UAAtBA,GAAc,GAAkB,KAAO,UAK/DZ,EAAE/xB,MAAQ+xB,EAAEkD,aAAiC,gBAAXlD,GAAE/xB,OACxC+xB,EAAE/xB,KAAOzI,EAAOqxB,MAAOmJ,EAAE/xB,KAAM+xB,EAAED,cAIlCgC,GAA+BP,GAAYxB,EAAGn0B,EAASo2B,GAGxC,IAAVte,EACJ,MAAOse,EAIRmC,GAAcpE,EAAEnS,OAGXuW,GAAmC,IAApB5+B,EAAOs9B,UAC1Bt9B,EAAOyC,MAAM8E,QAAQ,aAItBizB,EAAE73B,KAAO63B,EAAE73B,KAAKJ,cAGhBi4B,EAAE2F,YAAcvE,GAAW73B,KAAMy2B,EAAE73B,MAInC87B,EAAWjE,EAAE3F,IAGP2F,EAAE2F,aAGF3F,EAAE/xB,OACNg2B,EAAajE,EAAE3F,MAAS0G,GAAYx3B,KAAM06B,GAAa,IAAM,KAAQjE,EAAE/xB,WAEhE+xB,GAAE/xB,MAIL+xB,EAAEhpB,SAAU,IAChBgpB,EAAE3F,IAAM4G,GAAI13B,KAAM06B,GAGjBA,EAAS53B,QAAS40B,GAAK,OAASH,MAGhCmD,GAAalD,GAAYx3B,KAAM06B,GAAa,IAAM,KAAQ,KAAOnD,OAK/Dd,EAAE4F,aACDpgC,EAAOu9B,aAAckB,IACzBhC,EAAM+C,iBAAkB,oBAAqBx/B,EAAOu9B,aAAckB,IAE9Dz+B,EAAOw9B,KAAMiB,IACjBhC,EAAM+C,iBAAkB,gBAAiBx/B,EAAOw9B,KAAMiB,MAKnDjE,EAAE/xB,MAAQ+xB,EAAE2F,YAAc3F,EAAEmD,eAAgB,GAASt3B,EAAQs3B,cACjElB,EAAM+C,iBAAkB,eAAgBhF,EAAEmD,aAI3ClB,EAAM+C,iBACL,SACAhF,EAAE8B,UAAW,IAAO9B,EAAEoD,QAASpD,EAAE8B,UAAU,IAC1C9B,EAAEoD,QAASpD,EAAE8B,UAAU,KAA8B,MAArB9B,EAAE8B,UAAW,GAAc,KAAOJ,GAAW,WAAa,IAC1F1B,EAAEoD,QAAS,KAIb,KAAMn4B,IAAK+0B,GAAE6F,QACZ5D,EAAM+C,iBAAkB/5B,EAAG+0B,EAAE6F,QAAS56B,GAIvC,IAAK+0B,EAAE8F,aAAgB9F,EAAE8F,WAAW97B,KAAMu6B,EAAiBtC,EAAOjC,MAAQ,GAAmB,IAAVrc,GAElF,MAAOse,GAAMoD,OAIdR,GAAW,OAGX,KAAM55B,KAAOu6B,QAAS,EAAG13B,MAAO,EAAG80B,SAAU,GAC5CX,EAAOh3B,GAAK+0B,EAAG/0B,GAOhB,IAHAo5B,EAAYtC,GAA+BN,GAAYzB,EAAGn0B,EAASo2B,GAK5D,CACNA,EAAM75B,WAAa,EAGdg8B,GACJI,EAAmBz3B,QAAS,YAAck1B,EAAOjC,IAG7CA,EAAE7wB,OAAS6wB,EAAE1V,QAAU,IAC3B6Z,EAAet3B,WAAW,WACzBo1B,EAAMoD,MAAM,YACVrF,EAAE1V,SAGN,KACC3G,EAAQ,EACR0gB,EAAU0B,KAAMpB,EAAgBh6B,GAC/B,MAAQ+C,GAET,KAAa,EAARiW,GAIJ,KAAMjW,EAHN/C,GAAM,GAAI+C,QArBZ/C,GAAM,GAAI,eA8BX,SAASA,GAAMk4B,EAAQmD,EAAkBC,EAAWJ,GACnD,GAAIK,GAAWV,EAAS13B,EAAO40B,EAAUyD,EACxCb,EAAaU,CAGC,KAAVriB,IAKLA,EAAQ,EAGHwgB,GACJ5Z,aAAc4Z,GAKfE,EAAYt/B,EAGZm/B,EAAwB2B,GAAW,GAGnC5D,EAAM75B,WAAay6B,EAAS,EAAI,EAAI,EAGpCqD,EAAYrD,GAAU,KAAgB,IAATA,GAA2B,MAAXA,EAGxCoD,IACJvD,EAAW0D,GAAqBpG,EAAGiC,EAAOgE,IAI3CvD,EAAW2D,GAAarG,EAAG0C,EAAUT,EAAOiE,GAGvCA,GAGClG,EAAE4F,aACNO,EAAWlE,EAAM6C,kBAAkB,iBAC9BqB,IACJ3gC,EAAOu9B,aAAckB,GAAakC,GAEnCA,EAAWlE,EAAM6C,kBAAkB,QAC9BqB,IACJ3gC,EAAOw9B,KAAMiB,GAAakC,IAKZ,MAAXtD,GAA6B,SAAX7C,EAAE73B,KACxBm9B,EAAa,YAGS,MAAXzC,EACXyC,EAAa,eAIbA,EAAa5C,EAAS/e,MACtB6hB,EAAU9C,EAASz0B,KACnBH,EAAQ40B,EAAS50B,MACjBo4B,GAAap4B,KAKdA,EAAQw3B,GACHzC,IAAWyC,KACfA,EAAa,QACC,EAATzC,IACJA,EAAS,KAMZZ,EAAMY,OAASA,EACfZ,EAAMqD,YAAeU,GAAoBV,GAAe,GAGnDY,EACJriB,EAAS/W,YAAay3B,GAAmBiB,EAASF,EAAYrD,IAE9Dpe,EAASyiB,WAAY/B,GAAmBtC,EAAOqD,EAAYx3B,IAI5Dm0B,EAAMyC,WAAYA,GAClBA,EAAa3/B,EAERq/B,GACJI,EAAmBz3B,QAASm5B,EAAY,cAAgB,aACrDjE,EAAOjC,EAAGkG,EAAYV,EAAU13B,IAIpC22B,EAAiBjhB,SAAU+gB,GAAmBtC,EAAOqD,IAEhDlB,IACJI,EAAmBz3B,QAAS,gBAAkBk1B,EAAOjC,MAE3Cx6B,EAAOs9B,QAChBt9B,EAAOyC,MAAM8E,QAAQ,cAKxB,MAAOk1B,IAGRsE,QAAS,SAAUlM,EAAKpsB,EAAMzD,GAC7B,MAAOhF,GAAOyE,IAAKowB,EAAKpsB,EAAMzD,EAAU,SAGzCg8B,UAAW,SAAUnM,EAAK7vB,GACzB,MAAOhF,GAAOyE,IAAKowB,EAAKt1B,EAAWyF,EAAU,aAI/ChF,EAAO+E,MAAQ,MAAO,QAAU,SAAUU,EAAGw6B,GAC5CjgC,EAAQigC,GAAW,SAAUpL,EAAKpsB,EAAMzD,EAAUrC,GAQjD,MANK3C,GAAOiE,WAAYwE,KACvB9F,EAAOA,GAAQqC,EACfA,EAAWyD,EACXA,EAAOlJ,GAGDS,EAAO80B,MACbD,IAAKA,EACLlyB,KAAMs9B,EACNlL,SAAUpyB,EACV8F,KAAMA,EACNu3B,QAASh7B,MASZ,SAAS47B,IAAqBpG,EAAGiC,EAAOgE,GACvC,GAAIQ,GAAeC,EAAIC,EAAex+B,EACrCgsB,EAAW6L,EAAE7L,SACb2N,EAAY9B,EAAE8B,SAGf,OAA0B,MAAnBA,EAAW,GACjBA,EAAU5qB,QACLwvB,IAAO3hC,IACX2hC,EAAK1G,EAAEmF,UAAYlD,EAAM6C,kBAAkB,gBAK7C,IAAK4B,EACJ,IAAMv+B,IAAQgsB,GACb,GAAKA,EAAUhsB,IAAUgsB,EAAUhsB,GAAOoB,KAAMm9B,GAAO,CACtD5E,EAAU3nB,QAAShS,EACnB,OAMH,GAAK25B,EAAW,IAAOmE,GACtBU,EAAgB7E,EAAW,OACrB,CAEN,IAAM35B,IAAQ89B,GAAY,CACzB,IAAMnE,EAAW,IAAO9B,EAAEwD,WAAYr7B,EAAO,IAAM25B,EAAU,IAAO,CACnE6E,EAAgBx+B,CAChB,OAEKs+B,IACLA,EAAgBt+B,GAIlBw+B,EAAgBA,GAAiBF,EAMlC,MAAKE,IACCA,IAAkB7E,EAAW,IACjCA,EAAU3nB,QAASwsB,GAEbV,EAAWU,IAJnB,EAWD,QAASN,IAAarG,EAAG0C,EAAUT,EAAOiE,GACzC,GAAIU,GAAOC,EAASC,EAAM/3B,EAAKqlB,EAC9BoP,KAEA1B,EAAY9B,EAAE8B,UAAU37B,OAGzB,IAAK27B,EAAW,GACf,IAAMgF,IAAQ9G,GAAEwD,WACfA,EAAYsD,EAAKl3B,eAAkBowB,EAAEwD,WAAYsD,EAInDD,GAAU/E,EAAU5qB,OAGpB,OAAQ2vB,EAcP,GAZK7G,EAAEuD,eAAgBsD,KACtB5E,EAAOjC,EAAEuD,eAAgBsD,IAAcnE,IAIlCtO,GAAQ8R,GAAalG,EAAE+G,aAC5BrE,EAAW1C,EAAE+G,WAAYrE,EAAU1C,EAAEzF,WAGtCnG,EAAOyS,EACPA,EAAU/E,EAAU5qB,QAKnB,GAAiB,MAAZ2vB,EAEJA,EAAUzS,MAGJ,IAAc,MAATA,GAAgBA,IAASyS,EAAU,CAM9C,GAHAC,EAAOtD,EAAYpP,EAAO,IAAMyS,IAAarD,EAAY,KAAOqD,IAG1DC,EACL,IAAMF,IAASpD,GAId,GADAz0B,EAAM63B,EAAM90B,MAAO,KACd/C,EAAK,KAAQ83B,IAGjBC,EAAOtD,EAAYpP,EAAO,IAAMrlB,EAAK,KACpCy0B,EAAY,KAAOz0B,EAAK,KACb,CAEN+3B,KAAS,EACbA,EAAOtD,EAAYoD,GAGRpD,EAAYoD,MAAY,IACnCC,EAAU93B,EAAK,GACf+yB,EAAU3nB,QAASpL,EAAK,IAEzB,OAOJ,GAAK+3B,KAAS,EAGb,GAAKA,GAAQ9G,EAAG,UACf0C,EAAWoE,EAAMpE,OAEjB,KACCA,EAAWoE,EAAMpE,GAChB,MAAQh1B,GACT,OAASiW,MAAO,cAAe7V,MAAOg5B,EAAOp5B,EAAI,sBAAwB0mB,EAAO,OAASyS,IAQ/F,OAASljB,MAAO,UAAW1V,KAAMy0B,GAGlCl9B,EAAOq+B,WACNT,SACC4D,OAAQ,6FAET7S,UACC6S,OAAQ,uBAETxD,YACCyD,cAAe,SAAUl3B,GAExB,MADAvK,GAAO+J,WAAYQ,GACZA,MAMVvK,EAAOu+B,cAAe,SAAU,SAAU/D,GACpCA,EAAEhpB,QAAUjS,IAChBi7B,EAAEhpB,OAAQ,GAENgpB,EAAE0F,cACN1F,EAAE73B,KAAO,MACT63B,EAAEnS,QAAS,KAKbroB,EAAOw+B,cAAe,SAAU,SAAShE,GAGxC,GAAKA,EAAE0F,YAAc,CAEpB,GAAIsB,GACHE,EAAO9hC,EAAS8hC,MAAQ1hC,EAAO,QAAQ,IAAMJ,EAASE,eAEvD,QAECygC,KAAM,SAAUxwB,EAAG/K,GAElBw8B,EAAS5hC,EAASiJ,cAAc,UAEhC24B,EAAO73B,OAAQ,EAEV6wB,EAAEmH,gBACNH,EAAOI,QAAUpH,EAAEmH,eAGpBH,EAAOv7B,IAAMu0B,EAAE3F,IAGf2M,EAAOK,OAASL,EAAOM,mBAAqB,SAAU/xB,EAAGgyB,IAEnDA,IAAYP,EAAO5+B,YAAc,kBAAkBmB,KAAMy9B,EAAO5+B,eAGpE4+B,EAAOK,OAASL,EAAOM,mBAAqB,KAGvCN,EAAOp9B,YACXo9B,EAAOp9B,WAAW0N,YAAa0vB,GAIhCA,EAAS,KAGHO,GACL/8B,EAAU,IAAK,aAOlB08B,EAAKpP,aAAckP,EAAQE,EAAKruB,aAGjCwsB,MAAO,WACD2B,GACJA,EAAOK,OAAQtiC,GAAW,OAM/B,IAAIyiC,OACHC,GAAS,mBAGVjiC,GAAOq+B,WACN6D,MAAO,WACPC,cAAe,WACd,GAAIn9B,GAAWg9B,GAAa/zB,OAAWjO,EAAO0G,QAAU,IAAQ40B,IAEhE,OADAh4B,MAAM0B,IAAa,EACZA,KAKThF,EAAOu+B,cAAe,aAAc,SAAU/D,EAAG4H,EAAkB3F,GAElE,GAAI4F,GAAcC,EAAaC,EAC9BC,EAAWhI,EAAE0H,SAAU,IAAWD,GAAOl+B,KAAMy2B,EAAE3F,KAChD,MACkB,gBAAX2F,GAAE/xB,QAAwB+xB,EAAEmD,aAAe,IAAK98B,QAAQ,sCAAwCohC,GAAOl+B,KAAMy2B,EAAE/xB,OAAU,OAIlI,OAAK+5B,IAAiC,UAArBhI,EAAE8B,UAAW,IAG7B+F,EAAe7H,EAAE2H,cAAgBniC,EAAOiE,WAAYu2B,EAAE2H,eACrD3H,EAAE2H,gBACF3H,EAAE2H,cAGEK,EACJhI,EAAGgI,GAAahI,EAAGgI,GAAW37B,QAASo7B,GAAQ,KAAOI,GAC3C7H,EAAE0H,SAAU,IACvB1H,EAAE3F,MAAS0G,GAAYx3B,KAAMy2B,EAAE3F,KAAQ,IAAM,KAAQ2F,EAAE0H,MAAQ,IAAMG,GAItE7H,EAAEwD,WAAW,eAAiB,WAI7B,MAHMuE,IACLviC,EAAOsI,MAAO+5B,EAAe,mBAEvBE,EAAmB,IAI3B/H,EAAE8B,UAAW,GAAM,OAGnBgG,EAAchjC,EAAQ+iC,GACtB/iC,EAAQ+iC,GAAiB,WACxBE,EAAoBl9B,WAIrBo3B,EAAMre,OAAO,WAEZ9e,EAAQ+iC,GAAiBC,EAGpB9H,EAAG6H,KAEP7H,EAAE2H,cAAgBC,EAAiBD,cAGnCH,GAAavhC,KAAM4hC,IAIfE,GAAqBviC,EAAOiE,WAAYq+B,IAC5CA,EAAaC,EAAmB,IAGjCA,EAAoBD,EAAc/iC,IAI5B,UAtDR,GAyDD,IAAIkjC,IAAcC,GACjBC,GAAQ,EAERC,GAAmBtjC,EAAOoK,eAAiB,WAE1C,GAAIzB,EACJ,KAAMA,IAAOw6B,IACZA,GAAcx6B,GAAO1I,GAAW,GAKnC,SAASsjC,MACR,IACC,MAAO,IAAIvjC,GAAOwjC,eACjB,MAAO56B,KAGV,QAAS66B,MACR,IACC,MAAO,IAAIzjC,GAAOoK,cAAc,qBAC/B,MAAOxB,KAKVlI,EAAO06B,aAAasI,IAAM1jC,EAAOoK,cAOhC,WACC,OAAQpG,KAAKm6B,SAAWoF,MAAuBE,MAGhDF,GAGDH,GAAe1iC,EAAO06B,aAAasI,MACnChjC,EAAOmI,QAAQ86B,OAASP,IAAkB,mBAAqBA,IAC/DA,GAAe1iC,EAAOmI,QAAQ2sB,OAAS4N,GAGlCA,IAEJ1iC,EAAOw+B,cAAc,SAAUhE,GAE9B,IAAMA,EAAE0F,aAAelgC,EAAOmI,QAAQ86B,KAAO,CAE5C,GAAIj+B,EAEJ,QACCu7B,KAAM,SAAUF,EAASjD,GAGxB,GAAInU,GAAQxjB,EACXu9B,EAAMxI,EAAEwI,KAWT,IAPKxI,EAAE0I,SACNF,EAAIG,KAAM3I,EAAE73B,KAAM63B,EAAE3F,IAAK2F,EAAE7wB,MAAO6wB,EAAE0I,SAAU1I,EAAExhB,UAEhDgqB,EAAIG,KAAM3I,EAAE73B,KAAM63B,EAAE3F,IAAK2F,EAAE7wB,OAIvB6wB,EAAE4I,UACN,IAAM39B,IAAK+0B,GAAE4I,UACZJ,EAAKv9B,GAAM+0B,EAAE4I,UAAW39B,EAKrB+0B,GAAEmF,UAAYqD,EAAItD,kBACtBsD,EAAItD,iBAAkBlF,EAAEmF,UAQnBnF,EAAE0F,aAAgBG,EAAQ,sBAC/BA,EAAQ,oBAAsB,iBAI/B,KACC,IAAM56B,IAAK46B,GACV2C,EAAIxD,iBAAkB/5B,EAAG46B,EAAS56B,IAElC,MAAO2iB,IAKT4a,EAAIzC,KAAQ/F,EAAE2F,YAAc3F,EAAE/xB,MAAU,MAGxCzD,EAAW,SAAU+K,EAAGgyB,GACvB,GAAI1E,GAAQyB,EAAiBgB,EAAYW,CAKzC,KAGC,GAAKz7B,IAAc+8B,GAA8B,IAAnBiB,EAAIpgC,YAcjC,GAXAoC,EAAWzF,EAGN0pB,IACJ+Z,EAAIlB,mBAAqB9hC,EAAO8J,KAC3B84B,UACGH,IAAcxZ,IAKlB8Y,EAEoB,IAAnBiB,EAAIpgC,YACRogC,EAAInD,YAEC,CACNY,KACApD,EAAS2F,EAAI3F,OACbyB,EAAkBkE,EAAIzD,wBAIW,gBAArByD,GAAI7F,eACfsD,EAAUl2B,KAAOy4B,EAAI7F,aAKtB,KACC2C,EAAakD,EAAIlD,WAChB,MAAO53B,GAER43B,EAAa,GAQRzC,IAAU7C,EAAEiD,SAAYjD,EAAE0F,YAGT,OAAX7C,IACXA,EAAS,KAHTA,EAASoD,EAAUl2B,KAAO,IAAM,KAOlC,MAAO84B,GACFtB,GACL3E,EAAU,GAAIiG,GAKX5C,GACJrD,EAAUC,EAAQyC,EAAYW,EAAW3B,IAIrCtE,EAAE7wB,MAGuB,IAAnBq5B,EAAIpgC,WAGfyE,WAAYrC,IAEZikB,IAAW0Z,GACNC,KAGEH,KACLA,MACAziC,EAAQV,GAASgkC,OAAQV,KAG1BH,GAAcxZ,GAAWjkB,GAE1Bg+B,EAAIlB,mBAAqB98B,GAjBzBA,KAqBF66B,MAAO,WACD76B,GACJA,EAAUzF,GAAW,OAO3B,IAAIgkC,IAAOC,GACVC,GAAW,yBACXC,GAAaj1B,OAAQ,iBAAmBjN,EAAY,cAAe,KACnEmiC,GAAO,cACPC,IAAwBC,IACxBC,IACCjG,KAAM,SAAUjY,EAAMvb,GACrB,GAAI05B,GAAQzgC,KAAK0gC,YAAape,EAAMvb,GACnC9D,EAASw9B,EAAM3xB,MACf2nB,EAAQ2J,GAAOjgC,KAAM4G,GACrB45B,EAAOlK,GAASA,EAAO,KAAS/5B,EAAOw3B,UAAW5R,GAAS,GAAK,MAGhEhP,GAAU5W,EAAOw3B,UAAW5R,IAAmB,OAATqe,IAAkB19B,IACvDm9B,GAAOjgC,KAAMzD,EAAO82B,IAAKiN,EAAM1gC,KAAMuiB,IACtCse,EAAQ,EACRC,EAAgB,EAEjB,IAAKvtB,GAASA,EAAO,KAAQqtB,EAAO,CAEnCA,EAAOA,GAAQrtB,EAAO,GAGtBmjB,EAAQA,MAGRnjB,GAASrQ,GAAU,CAEnB,GAGC29B,GAAQA,GAAS,KAGjBttB,GAAgBstB,EAChBlkC,EAAO+L,MAAOg4B,EAAM1gC,KAAMuiB,EAAMhP,EAAQqtB,SAI/BC,KAAWA,EAAQH,EAAM3xB,MAAQ7L,IAAqB,IAAV29B,KAAiBC,GAaxE,MATKpK,KACJnjB,EAAQmtB,EAAMntB,OAASA,IAAUrQ,GAAU,EAC3Cw9B,EAAME,KAAOA,EAEbF,EAAMl+B,IAAMk0B,EAAO,GAClBnjB,GAAUmjB,EAAO,GAAM,GAAMA,EAAO,IACnCA,EAAO,IAGHgK,IAKV,SAASK,MAIR,MAHA/8B,YAAW,WACVk8B,GAAQhkC,IAEAgkC,GAAQvjC,EAAO0L,MAGzB,QAASs4B,IAAa35B,EAAOub,EAAMye,GAClC,GAAIN,GACHO,GAAeR,GAAUle,QAAerlB,OAAQujC,GAAU,MAC1DjmB,EAAQ,EACRra,EAAS8gC,EAAW9gC,MACrB,MAAgBA,EAARqa,EAAgBA,IACvB,GAAMkmB,EAAQO,EAAYzmB,GAAQrZ,KAAM6/B,EAAWze,EAAMvb,GAGxD,MAAO05B,GAKV,QAASQ,IAAWlhC,EAAMmhC,EAAYn+B,GACrC,GAAIgQ,GACHouB,EACA5mB,EAAQ,EACRra,EAASogC,GAAoBpgC,OAC7B6a,EAAWre,EAAOgM,WAAWoS,OAAQ,iBAE7BsmB,GAAKrhC,OAEbqhC,EAAO,WACN,GAAKD,EACJ,OAAO,CAER,IAAIE,GAAcpB,IAASa,KAC1B9kB,EAAY3Y,KAAKiE,IAAK,EAAGy5B,EAAUO,UAAYP,EAAUQ,SAAWF,GAEpElqB,EAAO6E,EAAY+kB,EAAUQ,UAAY,EACzCC,EAAU,EAAIrqB,EACdoD,EAAQ,EACRra,EAAS6gC,EAAUU,OAAOvhC,MAE3B,MAAgBA,EAARqa,EAAiBA,IACxBwmB,EAAUU,OAAQlnB,GAAQmnB,IAAKF,EAKhC,OAFAzmB,GAASqB,WAAYrc,GAAQghC,EAAWS,EAASxlB,IAElC,EAAVwlB,GAAethC,EACZ8b,GAEPjB,EAAS/W,YAAajE,GAAQghC,KACvB,IAGTA,EAAYhmB,EAASnZ,SACpB7B,KAAMA,EACNmoB,MAAOxrB,EAAOgG,UAAYw+B,GAC1BS,KAAMjlC,EAAOgG,QAAQ,GAAQk/B,kBAAqB7+B,GAClD8+B,mBAAoBX,EACpBhI,gBAAiBn2B,EACjBu+B,UAAWrB,IAASa,KACpBS,SAAUx+B,EAAQw+B,SAClBE,UACAf,YAAa,SAAUpe,EAAM/f,GAC5B,GAAIk+B,GAAQ/jC,EAAOolC,MAAO/hC,EAAMghC,EAAUY,KAAMrf,EAAM/f,EACpDw+B,EAAUY,KAAKC,cAAetf,IAAUye,EAAUY,KAAKI,OAEzD,OADAhB,GAAUU,OAAOtkC,KAAMsjC,GAChBA,GAERvf,KAAM,SAAU8gB,GACf,GAAIznB,GAAQ,EAGXra,EAAS8hC,EAAUjB,EAAUU,OAAOvhC,OAAS,CAC9C,IAAKihC,EACJ,MAAOnhC,KAGR,KADAmhC,GAAU,EACMjhC,EAARqa,EAAiBA,IACxBwmB,EAAUU,OAAQlnB,GAAQmnB,IAAK,EAUhC,OALKM,GACJjnB,EAAS/W,YAAajE,GAAQghC,EAAWiB,IAEzCjnB,EAASyiB,WAAYz9B,GAAQghC,EAAWiB,IAElChiC,QAGTkoB,EAAQ6Y,EAAU7Y,KAInB,KAFA+Z,GAAY/Z,EAAO6Y,EAAUY,KAAKC,eAElB1hC,EAARqa,EAAiBA,IAExB,GADAxH,EAASutB,GAAqB/lB,GAAQrZ,KAAM6/B,EAAWhhC,EAAMmoB,EAAO6Y,EAAUY,MAE7E,MAAO5uB,EAmBT,OAfArW,GAAO4F,IAAK4lB,EAAOwY,GAAaK,GAE3BrkC,EAAOiE,WAAYogC,EAAUY,KAAKruB,QACtCytB,EAAUY,KAAKruB,MAAMpS,KAAMnB,EAAMghC,GAGlCrkC,EAAO4kB,GAAG4gB,MACTxlC,EAAOgG,OAAQ0+B,GACdrhC,KAAMA,EACNoiC,KAAMpB,EACNngB,MAAOmgB,EAAUY,KAAK/gB,SAKjBmgB,EAAUtlB,SAAUslB,EAAUY,KAAKlmB,UACxC5Z,KAAMk/B,EAAUY,KAAK9/B,KAAMk/B,EAAUY,KAAK7H,UAC1C9e,KAAM+lB,EAAUY,KAAK3mB,MACrBF,OAAQimB,EAAUY,KAAK7mB,QAG1B,QAASmnB,IAAY/Z,EAAO0Z,GAC3B,GAAIrnB,GAAOzX,EAAMi/B,EAAQh7B,EAAOga,CAGhC,KAAMxG,IAAS2N,GAed,GAdAplB,EAAOpG,EAAOiK,UAAW4T,GACzBwnB,EAASH,EAAe9+B,GACxBiE,EAAQmhB,EAAO3N,GACV7d,EAAOyG,QAAS4D,KACpBg7B,EAASh7B,EAAO,GAChBA,EAAQmhB,EAAO3N,GAAUxT,EAAO,IAG5BwT,IAAUzX,IACdolB,EAAOplB,GAASiE,QACTmhB,GAAO3N,IAGfwG,EAAQrkB,EAAOs3B,SAAUlxB,GACpBie,GAAS,UAAYA,GAAQ,CACjCha,EAAQga,EAAMwV,OAAQxvB,SACfmhB,GAAOplB,EAId,KAAMyX,IAASxT,GACNwT,IAAS2N,KAChBA,EAAO3N,GAAUxT,EAAOwT,GACxBqnB,EAAernB,GAAUwnB,OAI3BH,GAAe9+B,GAASi/B,EAK3BrlC,EAAOukC,UAAYvkC,EAAOgG,OAAQu+B,IAEjCmB,QAAS,SAAUla,EAAOxmB,GACpBhF,EAAOiE,WAAYunB,IACvBxmB,EAAWwmB,EACXA,GAAU,MAEVA,EAAQA,EAAMlf,MAAM,IAGrB,IAAIsZ,GACH/H,EAAQ,EACRra,EAASgoB,EAAMhoB,MAEhB,MAAgBA,EAARqa,EAAiBA,IACxB+H,EAAO4F,EAAO3N,GACdimB,GAAUle,GAASke,GAAUle,OAC7Bke,GAAUle,GAAOjR,QAAS3P,IAI5B2gC,UAAW,SAAU3gC,EAAUqtB,GACzBA,EACJuR,GAAoBjvB,QAAS3P,GAE7B4+B,GAAoBnjC,KAAMuE,KAK7B,SAAS6+B,IAAkBxgC,EAAMmoB,EAAOyZ,GAEvC,GAAIrf,GAAMvb,EAAOgtB,EAAQ0M,EAAO1f,EAAOuhB,EACtCH,EAAOniC,KACPmqB,KACA1hB,EAAQ1I,EAAK0I,MACbkrB,EAAS5zB,EAAKQ,UAAY+yB,GAAUvzB,GACpCwiC,EAAW7lC,EAAO+jB,MAAO1gB,EAAM,SAG1B4hC,GAAK/gB,QACVG,EAAQrkB,EAAOskB,YAAajhB,EAAM,MACX,MAAlBghB,EAAMyhB,WACVzhB,EAAMyhB,SAAW,EACjBF,EAAUvhB,EAAM/L,MAAMkF,KACtB6G,EAAM/L,MAAMkF,KAAO,WACZ6G,EAAMyhB,UACXF,MAIHvhB,EAAMyhB,WAENL,EAAKrnB,OAAO,WAGXqnB,EAAKrnB,OAAO,WACXiG,EAAMyhB,WACA9lC,EAAOkkB,MAAO7gB,EAAM,MAAOG,QAChC6gB,EAAM/L,MAAMkF,YAOO,IAAlBna,EAAKQ,WAAoB,UAAY2nB,IAAS,SAAWA,MAK7DyZ,EAAKc,UAAah6B,EAAMg6B,SAAUh6B,EAAMi6B,UAAWj6B,EAAMk6B,WAIlB,WAAlCjmC,EAAO82B,IAAKzzB,EAAM,YACW,SAAhCrD,EAAO82B,IAAKzzB,EAAM,WAIbrD,EAAOmI,QAAQ4Y,wBAAkE,WAAxCmW,GAAoB7zB,EAAK8G,UAIvE4B,EAAMyW,KAAO,EAHbzW,EAAMuW,QAAU,iBAQd2iB,EAAKc,WACTh6B,EAAMg6B,SAAW,SACX/lC,EAAOmI,QAAQ6Y,kBACpBykB,EAAKrnB,OAAO,WACXrS,EAAMg6B,SAAWd,EAAKc,SAAU,GAChCh6B,EAAMi6B,UAAYf,EAAKc,SAAU,GACjCh6B,EAAMk6B,UAAYhB,EAAKc,SAAU,KAOpC,KAAMngB,IAAQ4F,GAEb,GADAnhB,EAAQmhB,EAAO5F,GACV6d,GAAShgC,KAAM4G,GAAU,CAG7B,SAFOmhB,GAAO5F,GACdyR,EAASA,GAAoB,WAAVhtB,EACdA,KAAY4sB,EAAS,OAAS,QAClC,QAEDxJ,GAAM7H,GAASigB,GAAYA,EAAUjgB,IAAU5lB,EAAO+L,MAAO1I,EAAMuiB,GAIrE,IAAM5lB,EAAOqI,cAAeolB,GAAS,CAC/BoY,EACC,UAAYA,KAChB5O,EAAS4O,EAAS5O,QAGnB4O,EAAW7lC,EAAO+jB,MAAO1gB,EAAM,aAI3Bg0B,IACJwO,EAAS5O,QAAUA,GAEfA,EACJj3B,EAAQqD,GAAO2zB,OAEfyO,EAAKtgC,KAAK,WACTnF,EAAQqD,GAAO+zB,SAGjBqO,EAAKtgC,KAAK,WACT,GAAIygB,EACJ5lB,GAAOgkB,YAAa3gB,EAAM,SAC1B,KAAMuiB,IAAQ6H,GACbztB,EAAO+L,MAAO1I,EAAMuiB,EAAM6H,EAAM7H,KAGlC,KAAMA,IAAQ6H,GACbsW,EAAQC,GAAa/M,EAAS4O,EAAUjgB,GAAS,EAAGA,EAAM6f,GAElD7f,IAAQigB,KACfA,EAAUjgB,GAASme,EAAMntB,MACpBqgB,IACJ8M,EAAMl+B,IAAMk+B,EAAMntB,MAClBmtB,EAAMntB,MAAiB,UAATgP,GAA6B,WAATA,EAAoB,EAAI,KAO/D,QAASwf,IAAO/hC,EAAMgD,EAASuf,EAAM/f,EAAKw/B,GACzC,MAAO,IAAID,IAAMniC,UAAU1B,KAAM8B,EAAMgD,EAASuf,EAAM/f,EAAKw/B,GAE5DrlC,EAAOolC,MAAQA,GAEfA,GAAMniC,WACLE,YAAaiiC,GACb7jC,KAAM,SAAU8B,EAAMgD,EAASuf,EAAM/f,EAAKw/B,EAAQpB,GACjD3gC,KAAKD,KAAOA,EACZC,KAAKsiB,KAAOA,EACZtiB,KAAK+hC,OAASA,GAAU,QACxB/hC,KAAK+C,QAAUA,EACf/C,KAAKsT,MAAQtT,KAAKoI,IAAMpI,KAAK8O,MAC7B9O,KAAKuC,IAAMA,EACXvC,KAAK2gC,KAAOA,IAAUjkC,EAAOw3B,UAAW5R,GAAS,GAAK,OAEvDxT,IAAK,WACJ,GAAIiS,GAAQ+gB,GAAMhe,UAAW9jB,KAAKsiB,KAElC,OAAOvB,IAASA,EAAM5f,IACrB4f,EAAM5f,IAAKnB,MACX8hC,GAAMhe,UAAUqD,SAAShmB,IAAKnB,OAEhC0hC,IAAK,SAAUF,GACd,GAAIoB,GACH7hB,EAAQ+gB,GAAMhe,UAAW9jB,KAAKsiB,KAoB/B,OAjBCtiB,MAAK2rB,IAAMiX,EADP5iC,KAAK+C,QAAQw+B,SACE7kC,EAAOqlC,OAAQ/hC,KAAK+hC,QACtCP,EAASxhC,KAAK+C,QAAQw+B,SAAWC,EAAS,EAAG,EAAGxhC,KAAK+C,QAAQw+B,UAG3CC,EAEpBxhC,KAAKoI,KAAQpI,KAAKuC,IAAMvC,KAAKsT,OAAUsvB,EAAQ5iC,KAAKsT,MAE/CtT,KAAK+C,QAAQ8/B,MACjB7iC,KAAK+C,QAAQ8/B,KAAK3hC,KAAMlB,KAAKD,KAAMC,KAAKoI,IAAKpI,MAGzC+gB,GAASA,EAAMoC,IACnBpC,EAAMoC,IAAKnjB,MAEX8hC,GAAMhe,UAAUqD,SAAShE,IAAKnjB,MAExBA,OAIT8hC,GAAMniC,UAAU1B,KAAK0B,UAAYmiC,GAAMniC,UAEvCmiC,GAAMhe,WACLqD,UACChmB,IAAK,SAAUs/B,GACd,GAAI1tB,EAEJ,OAAiC,OAA5B0tB,EAAM1gC,KAAM0gC,EAAMne,OACpBme,EAAM1gC,KAAK0I,OAA2C,MAAlCg4B,EAAM1gC,KAAK0I,MAAOg4B,EAAMne,OAQ/CvP,EAASrW,EAAO82B,IAAKiN,EAAM1gC,KAAM0gC,EAAMne,KAAM,IAErCvP,GAAqB,SAAXA,EAAwBA,EAAJ,GAT9B0tB,EAAM1gC,KAAM0gC,EAAMne,OAW3Ba,IAAK,SAAUsd,GAGT/jC,EAAO4kB,GAAGuhB,KAAMpC,EAAMne,MAC1B5lB,EAAO4kB,GAAGuhB,KAAMpC,EAAMne,MAAQme,GACnBA,EAAM1gC,KAAK0I,QAAgE,MAArDg4B,EAAM1gC,KAAK0I,MAAO/L,EAAOg4B,SAAU+L,EAAMne,QAAoB5lB,EAAOs3B,SAAUyM,EAAMne,OACrH5lB,EAAO+L,MAAOg4B,EAAM1gC,KAAM0gC,EAAMne,KAAMme,EAAMr4B,IAAMq4B,EAAME,MAExDF,EAAM1gC,KAAM0gC,EAAMne,MAASme,EAAMr4B,OASrC05B,GAAMhe,UAAUmF,UAAY6Y,GAAMhe,UAAU+E,YAC3C1F,IAAK,SAAUsd,GACTA,EAAM1gC,KAAKQ,UAAYkgC,EAAM1gC,KAAKe,aACtC2/B,EAAM1gC,KAAM0gC,EAAMne,MAASme,EAAMr4B,OAKpC1L,EAAO+E,MAAO,SAAU,OAAQ,QAAU,SAAUU,EAAGW,GACtD,GAAIggC,GAAQpmC,EAAOsB,GAAI8E,EACvBpG,GAAOsB,GAAI8E,GAAS,SAAUigC,EAAOhB,EAAQrgC,GAC5C,MAAgB,OAATqhC,GAAkC,iBAAVA,GAC9BD,EAAMhhC,MAAO9B,KAAM+B,WACnB/B,KAAKgjC,QAASC,GAAOngC,GAAM,GAAQigC,EAAOhB,EAAQrgC,MAIrDhF,EAAOsB,GAAG0E,QACTwgC,OAAQ,SAAUH,EAAOI,EAAIpB,EAAQrgC,GAGpC,MAAO1B,MAAKkQ,OAAQojB,IAAWE,IAAK,UAAW,GAAIE,OAGjDnxB,MAAMygC,SAAU/lB,QAASkmB,GAAMJ,EAAOhB,EAAQrgC,IAEjDshC,QAAS,SAAU1gB,EAAMygB,EAAOhB,EAAQrgC,GACvC,GAAIsT,GAAQtY,EAAOqI,cAAeud,GACjC8gB,EAAS1mC,EAAOqmC,MAAOA,EAAOhB,EAAQrgC,GACtC2hC,EAAc,WAEb,GAAIlB,GAAOlB,GAAWjhC,KAAMtD,EAAOgG,UAAY4f,GAAQ8gB,IAGlDpuB,GAAStY,EAAO+jB,MAAOzgB,KAAM,YACjCmiC,EAAKjhB,MAAM,GAKd,OAFCmiB,GAAYC,OAASD,EAEfruB,GAASouB,EAAOxiB,SAAU,EAChC5gB,KAAKyB,KAAM4hC,GACXrjC,KAAK4gB,MAAOwiB,EAAOxiB,MAAOyiB,IAE5BniB,KAAM,SAAU7hB,EAAMqiB,EAAYsgB,GACjC,GAAIuB,GAAY,SAAUxiB,GACzB,GAAIG,GAAOH,EAAMG,WACVH,GAAMG,KACbA,EAAM8gB,GAYP,OATqB,gBAAT3iC,KACX2iC,EAAUtgB,EACVA,EAAariB,EACbA,EAAOpD,GAEHylB,GAAcriB,KAAS,GAC3BW,KAAK4gB,MAAOvhB,GAAQ,SAGdW,KAAKyB,KAAK,WAChB,GAAIof,IAAU,EACbtG,EAAgB,MAARlb,GAAgBA,EAAO,aAC/BmkC,EAAS9mC,EAAO8mC,OAChBr+B,EAAOzI,EAAO+jB,MAAOzgB,KAEtB,IAAKua,EACCpV,EAAMoV,IAAWpV,EAAMoV,GAAQ2G,MACnCqiB,EAAWp+B,EAAMoV,QAGlB,KAAMA,IAASpV,GACTA,EAAMoV,IAAWpV,EAAMoV,GAAQ2G,MAAQmf,GAAK5/B,KAAM8Z,IACtDgpB,EAAWp+B,EAAMoV,GAKpB,KAAMA,EAAQipB,EAAOtjC,OAAQqa,KACvBipB,EAAQjpB,GAAQxa,OAASC,MAAiB,MAARX,GAAgBmkC,EAAQjpB,GAAQqG,QAAUvhB,IAChFmkC,EAAQjpB,GAAQ4nB,KAAKjhB,KAAM8gB,GAC3BnhB,GAAU,EACV2iB,EAAO/gC,OAAQ8X,EAAO,KAOnBsG,IAAYmhB,IAChBtlC,EAAOmkB,QAAS7gB,KAAMX,MAIzBikC,OAAQ,SAAUjkC,GAIjB,MAHKA,MAAS,IACbA,EAAOA,GAAQ,MAETW,KAAKyB,KAAK,WAChB,GAAI8Y,GACHpV,EAAOzI,EAAO+jB,MAAOzgB,MACrB4gB,EAAQzb,EAAM9F,EAAO,SACrB0hB,EAAQ5b,EAAM9F,EAAO,cACrBmkC,EAAS9mC,EAAO8mC,OAChBtjC,EAAS0gB,EAAQA,EAAM1gB,OAAS,CAajC,KAVAiF,EAAKm+B,QAAS,EAGd5mC,EAAOkkB,MAAO5gB,KAAMX,MAEf0hB,GAASA,EAAMG,MACnBH,EAAMG,KAAKhgB,KAAMlB,MAAM,GAIlBua,EAAQipB,EAAOtjC,OAAQqa,KACvBipB,EAAQjpB,GAAQxa,OAASC,MAAQwjC,EAAQjpB,GAAQqG,QAAUvhB,IAC/DmkC,EAAQjpB,GAAQ4nB,KAAKjhB,MAAM,GAC3BsiB,EAAO/gC,OAAQ8X,EAAO,GAKxB,KAAMA,EAAQ,EAAWra,EAARqa,EAAgBA,IAC3BqG,EAAOrG,IAAWqG,EAAOrG,GAAQ+oB,QACrC1iB,EAAOrG,GAAQ+oB,OAAOpiC,KAAMlB,YAKvBmF,GAAKm+B,WAMf,SAASL,IAAO5jC,EAAMokC,GACrB,GAAInb,GACH5Z,GAAUg1B,OAAQrkC,GAClB8C,EAAI,CAKL,KADAshC,EAAeA,EAAc,EAAI,EACtB,EAAJthC,EAAQA,GAAK,EAAIshC,EACvBnb,EAAQ2K,GAAW9wB,GACnBuM,EAAO,SAAW4Z,GAAU5Z,EAAO,UAAY4Z,GAAUjpB,CAO1D,OAJKokC,KACJ/0B,EAAMuO,QAAUvO,EAAM4Q,MAAQjgB,GAGxBqP,EAIRhS,EAAO+E,MACNkiC,UAAWV,GAAM,QACjBW,QAASX,GAAM,QACfY,YAAaZ,GAAM,UACnBa,QAAU7mB,QAAS,QACnB8mB,SAAW9mB,QAAS,QACpB+mB,YAAc/mB,QAAS,WACrB,SAAUna,EAAMolB,GAClBxrB,EAAOsB,GAAI8E,GAAS,SAAUigC,EAAOhB,EAAQrgC,GAC5C,MAAO1B,MAAKgjC,QAAS9a,EAAO6a,EAAOhB,EAAQrgC,MAI7ChF,EAAOqmC,MAAQ,SAAUA,EAAOhB,EAAQ/jC,GACvC,GAAIwe,GAAMumB,GAA0B,gBAAVA,GAAqBrmC,EAAOgG,UAAYqgC,IACjEjJ,SAAU97B,IAAOA,GAAM+jC,GACtBrlC,EAAOiE,WAAYoiC,IAAWA,EAC/BxB,SAAUwB,EACVhB,OAAQ/jC,GAAM+jC,GAAUA,IAAWrlC,EAAOiE,WAAYohC,IAAYA,EAwBnE,OArBAvlB,GAAI+kB,SAAW7kC,EAAO4kB,GAAGpd,IAAM,EAA4B,gBAAjBsY,GAAI+kB,SAAwB/kB,EAAI+kB,SACzE/kB,EAAI+kB,WAAY7kC,GAAO4kB,GAAGC,OAAS7kB,EAAO4kB,GAAGC,OAAQ/E,EAAI+kB,UAAa7kC,EAAO4kB,GAAGC,OAAO4F,UAGtE,MAAb3K,EAAIoE,OAAiBpE,EAAIoE,SAAU,KACvCpE,EAAIoE,MAAQ,MAIbpE,EAAIhU,IAAMgU,EAAIsd,SAEdtd,EAAIsd,SAAW,WACTp9B,EAAOiE,WAAY6b,EAAIhU,MAC3BgU,EAAIhU,IAAItH,KAAMlB,MAGVwc,EAAIoE,OACRlkB,EAAOmkB,QAAS7gB,KAAMwc,EAAIoE,QAIrBpE,GAGR9f,EAAOqlC,QACNkC,OAAQ,SAAUC,GACjB,MAAOA,IAERC,MAAO,SAAUD,GAChB,MAAO,GAAM7gC,KAAK+gC,IAAKF,EAAE7gC,KAAKghC,IAAO,IAIvC3nC,EAAO8mC,UACP9mC,EAAO4kB,GAAKwgB,GAAMniC,UAAU1B,KAC5BvB,EAAO4kB,GAAG8f,KAAO,WAChB,GAAIc,GACHsB,EAAS9mC,EAAO8mC,OAChBrhC,EAAI,CAIL,KAFA89B,GAAQvjC,EAAO0L,MAEHo7B,EAAOtjC,OAAXiC,EAAmBA,IAC1B+/B,EAAQsB,EAAQrhC,GAEV+/B,KAAWsB,EAAQrhC,KAAQ+/B,GAChCsB,EAAO/gC,OAAQN,IAAK,EAIhBqhC,GAAOtjC,QACZxD,EAAO4kB,GAAGJ,OAEX+e,GAAQhkC,GAGTS,EAAO4kB,GAAG4gB,MAAQ,SAAUA,GACtBA,KAAWxlC,EAAO8mC,OAAOrmC,KAAM+kC,IACnCxlC,EAAO4kB,GAAGhO,SAIZ5W,EAAO4kB,GAAGgjB,SAAW,GAErB5nC,EAAO4kB,GAAGhO,MAAQ,WACX4sB,KACLA,GAAUqE,YAAa7nC,EAAO4kB,GAAG8f,KAAM1kC,EAAO4kB,GAAGgjB,YAInD5nC,EAAO4kB,GAAGJ,KAAO,WAChBsjB,cAAetE,IACfA,GAAU,MAGXxjC,EAAO4kB,GAAGC,QACTkjB,KAAM,IACNC,KAAM,IAENvd,SAAU,KAIXzqB,EAAO4kB,GAAGuhB,QAELnmC,EAAO4U,MAAQ5U,EAAO4U,KAAKwE,UAC/BpZ,EAAO4U,KAAKwE,QAAQ6uB,SAAW,SAAU5kC,GACxC,MAAOrD,GAAO+K,KAAK/K,EAAO8mC,OAAQ,SAAUxlC,GAC3C,MAAO+B,KAAS/B,EAAG+B,OACjBG,SAGLxD,EAAOsB,GAAG4mC,OAAS,SAAU7hC,GAC5B,GAAKhB,UAAU7B,OACd,MAAO6C,KAAY9G,EAClB+D,KACAA,KAAKyB,KAAK,SAAUU,GACnBzF,EAAOkoC,OAAOC,UAAW7kC,KAAM+C,EAASZ,IAI3C,IAAI5F,GAASuoC,EACZC,GAAQn8B,IAAK,EAAGssB,KAAM,GACtBn1B,EAAOC,KAAM,GACbwP,EAAMzP,GAAQA,EAAKS,aAEpB,IAAMgP,EAON,MAHAjT,GAAUiT,EAAIhT,gBAGRE,EAAOmN,SAAUtN,EAASwD,UAMpBA,GAAKilC,wBAA0B5oC,IAC1C2oC,EAAMhlC,EAAKilC,yBAEZF,EAAMG,GAAWz1B,IAEhB5G,IAAKm8B,EAAIn8B,KAASk8B,EAAII,aAAe3oC,EAAQ0sB,YAAiB1sB,EAAQ2sB,WAAc,GACpFgM,KAAM6P,EAAI7P,MAAS4P,EAAIK,aAAe5oC,EAAQssB,aAAiBtsB,EAAQusB,YAAc,KAX9Eic,GAeTroC,EAAOkoC,QAENC,UAAW,SAAU9kC,EAAMgD,EAASZ,GACnC,GAAIywB,GAAWl2B,EAAO82B,IAAKzzB,EAAM,WAGf,YAAb6yB,IACJ7yB,EAAK0I,MAAMmqB,SAAW,WAGvB,IAAIwS,GAAU1oC,EAAQqD,GACrBslC,EAAYD,EAAQR,SACpBU,EAAY5oC,EAAO82B,IAAKzzB,EAAM,OAC9BwlC,EAAa7oC,EAAO82B,IAAKzzB,EAAM,QAC/BylC,GAAmC,aAAb5S,GAAwC,UAAbA,IAA0Bl2B,EAAO2K,QAAQ,QAASi+B,EAAWC,IAAe,GAC7Hrd,KAAYud,KAAkBC,EAAQC,CAGlCH,IACJC,EAAcL,EAAQxS,WACtB8S,EAASD,EAAY78B,IACrB+8B,EAAUF,EAAYvQ,OAEtBwQ,EAASlhC,WAAY8gC,IAAe,EACpCK,EAAUnhC,WAAY+gC,IAAgB,GAGlC7oC,EAAOiE,WAAYoC,KACvBA,EAAUA,EAAQ7B,KAAMnB,EAAMoC,EAAGkjC,IAGd,MAAftiC,EAAQ6F,MACZsf,EAAMtf,IAAQ7F,EAAQ6F,IAAMy8B,EAAUz8B,IAAQ88B,GAE1B,MAAhB3iC,EAAQmyB,OACZhN,EAAMgN,KAASnyB,EAAQmyB,KAAOmQ,EAAUnQ,KAASyQ,GAG7C,SAAW5iC,GACfA,EAAQ6iC,MAAM1kC,KAAMnB,EAAMmoB,GAE1Bkd,EAAQ5R,IAAKtL,KAMhBxrB,EAAOsB,GAAG0E,QAETkwB,SAAU,WACT,GAAM5yB,KAAM,GAAZ,CAIA,GAAI6lC,GAAcjB,EACjBkB,GAAiBl9B,IAAK,EAAGssB,KAAM,GAC/Bn1B,EAAOC,KAAM,EAwBd,OArBwC,UAAnCtD,EAAO82B,IAAKzzB,EAAM,YAEtB6kC,EAAS7kC,EAAKilC,yBAGda,EAAe7lC,KAAK6lC,eAGpBjB,EAAS5kC,KAAK4kC,SACRloC,EAAOmK,SAAUg/B,EAAc,GAAK,UACzCC,EAAeD,EAAajB,UAI7BkB,EAAal9B,KAAQlM,EAAO82B,IAAKqS,EAAc,GAAK,kBAAkB,GACtEC,EAAa5Q,MAAQx4B,EAAO82B,IAAKqS,EAAc,GAAK,mBAAmB,KAOvEj9B,IAAMg8B,EAAOh8B,IAAOk9B,EAAal9B,IAAMlM,EAAO82B,IAAKzzB,EAAM,aAAa,GACtEm1B,KAAM0P,EAAO1P,KAAO4Q,EAAa5Q,KAAOx4B,EAAO82B,IAAKzzB,EAAM,cAAc,MAI1E8lC,aAAc,WACb,MAAO7lC,MAAKsC,IAAI,WACf,GAAIujC,GAAe7lC,KAAK6lC,cAAgBtpC,CACxC,OAAQspC,IAAmBnpC,EAAOmK,SAAUg/B,EAAc,SAAsD,WAA1CnpC,EAAO82B,IAAKqS,EAAc,YAC/FA,EAAeA,EAAaA,YAE7B,OAAOA,IAAgBtpC,OAO1BG,EAAO+E,MAAOonB,WAAY,cAAeI,UAAW,eAAgB,SAAU0T,EAAQra,GACrF,GAAI1Z,GAAM,IAAInI,KAAM6hB,EAEpB5lB,GAAOsB,GAAI2+B,GAAW,SAAUnrB,GAC/B,MAAO9U,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAM48B,EAAQnrB,GACnD,GAAIszB,GAAMG,GAAWllC,EAErB,OAAKyR,KAAQvV,EACL6oC,EAAOxiB,IAAQwiB,GAAOA,EAAKxiB,GACjCwiB,EAAIxoC,SAASE,gBAAiBmgC,GAC9B58B,EAAM48B,IAGHmI,EACJA,EAAIiB,SACFn9B,EAAYlM,EAAQooC,GAAMjc,aAApBrX,EACP5I,EAAM4I,EAAM9U,EAAQooC,GAAM7b,aAI3BlpB,EAAM48B,GAAWnrB,EAPlB,IASEmrB,EAAQnrB,EAAKzP,UAAU7B,OAAQ,QAIpC,SAAS+kC,IAAWllC,GACnB,MAAOrD,GAAO2H,SAAUtE,GACvBA,EACkB,IAAlBA,EAAKQ,SACJR,EAAK2P,aAAe3P,EAAKgnB,cACzB,EAGHrqB,EAAO+E,MAAQukC,OAAQ,SAAUC,MAAO,SAAW,SAAUnjC,EAAMzD,GAClE3C,EAAO+E,MAAQ00B,QAAS,QAAUrzB,EAAMktB,QAAS3wB,EAAM,GAAI,QAAUyD,GAAQ,SAAUojC,EAAcC,GAEpGzpC,EAAOsB,GAAImoC,GAAa,SAAUjQ,EAAQnvB,GACzC,GAAIiB,GAAYjG,UAAU7B,SAAYgmC,GAAkC,iBAAXhQ,IAC5DtB,EAAQsR,IAAkBhQ,KAAW,GAAQnvB,KAAU,EAAO,SAAW,SAE1E,OAAOrK,GAAOqL,OAAQ/H,KAAM,SAAUD,EAAMV,EAAM0H,GACjD,GAAIyI,EAEJ,OAAK9S,GAAO2H,SAAUtE,GAIdA,EAAKzD,SAASE,gBAAiB,SAAWsG,GAI3B,IAAlB/C,EAAKQ,UACTiP,EAAMzP,EAAKvD,gBAIJ6G,KAAKiE,IACXvH,EAAK+D,KAAM,SAAWhB,GAAQ0M,EAAK,SAAW1M,GAC9C/C,EAAK+D,KAAM,SAAWhB,GAAQ0M,EAAK,SAAW1M,GAC9C0M,EAAK,SAAW1M,KAIXiE,IAAU9K,EAEhBS,EAAO82B,IAAKzzB,EAAMV,EAAMu1B,GAGxBl4B,EAAO+L,MAAO1I,EAAMV,EAAM0H,EAAO6tB,IAChCv1B,EAAM2I,EAAYkuB,EAASj6B,EAAW+L,EAAW,WAQvDtL,EAAOsB,GAAGooC,KAAO,WAChB,MAAOpmC,MAAKE,QAGbxD,EAAOsB,GAAGqoC,QAAU3pC,EAAOsB,GAAG6tB,QAGP,gBAAXya,SAAuBA,QAAoC,gBAAnBA,QAAOC,QAK1DD,OAAOC,QAAU7pC,GAGjBV,EAAOU,OAASV,EAAOY,EAAIF,EASJ,kBAAX8pC,SAAyBA,OAAOC,KAC3CD,OAAQ,YAAc,WAAc,MAAO9pC,QAIzCV"} \ No newline at end of file diff --git a/static/js/qrcode.js b/static/js/qrcode.js new file mode 100755 index 0000000..b2ae4a6 --- /dev/null +++ b/static/js/qrcode.js @@ -0,0 +1,88 @@ + +var qrcode=function(){var qrcode=function(typeNumber,errorCorrectLevel){var PAD0=0xEC;var PAD1=0x11;var _typeNumber=typeNumber;var _errorCorrectLevel=QRErrorCorrectLevel[errorCorrectLevel];var _modules=null;var _moduleCount=0;var _dataCache=null;var _dataList=new Array();var _this={};var makeImpl=function(test,maskPattern){_moduleCount=_typeNumber*4+17;_modules=function(moduleCount){var modules=new Array(moduleCount);for(var row=0;row<moduleCount;row+=1){modules[row]=new Array(moduleCount);for(var col=0;col<moduleCount;col+=1){modules[row][col]=null;}} +return modules;}(_moduleCount);setupPositionProbePattern(0,0);setupPositionProbePattern(_moduleCount-7,0);setupPositionProbePattern(0,_moduleCount-7);setupPositionAdjustPattern();setupTimingPattern();setupTypeInfo(test,maskPattern);if(_typeNumber>=7){setupTypeNumber(test);} +if(_dataCache==null){_dataCache=createData(_typeNumber,_errorCorrectLevel,_dataList);} +mapData(_dataCache,maskPattern);};var setupPositionProbePattern=function(row,col){for(var r=-1;r<=7;r+=1){if(row+r<=-1||_moduleCount<=row+r)continue;for(var c=-1;c<=7;c+=1){if(col+c<=-1||_moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}};var getBestMaskPattern=function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i+=1){makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(_this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} +return pattern;};var setupTimingPattern=function(){for(var r=8;r<_moduleCount-8;r+=1){if(_modules[r][6]!=null){continue;} +_modules[r][6]=(r%2==0);} +for(var c=8;c<_moduleCount-8;c+=1){if(_modules[6][c]!=null){continue;} +_modules[6][c]=(c%2==0);}};var setupPositionAdjustPattern=function(){var pos=QRUtil.getPatternPosition(_typeNumber);for(var i=0;i<pos.length;i+=1){for(var j=0;j<pos.length;j+=1){var row=pos[i];var col=pos[j];if(_modules[row][col]!=null){continue;} +for(var r=-2;r<=2;r+=1){for(var c=-2;c<=2;c+=1){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){_modules[row+r][col+c]=true;}else{_modules[row+r][col+c]=false;}}}}}};var setupTypeNumber=function(test){var bits=QRUtil.getBCHTypeNumber(_typeNumber);for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[Math.floor(i/3)][i%3+_moduleCount-8-3]=mod;} +for(var i=0;i<18;i+=1){var mod=(!test&&((bits>>i)&1)==1);_modules[i%3+_moduleCount-8-3][Math.floor(i/3)]=mod;}};var setupTypeInfo=function(test,maskPattern){var data=(_errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<6){_modules[i][8]=mod;}else if(i<8){_modules[i+1][8]=mod;}else{_modules[_moduleCount-15+i][8]=mod;}} +for(var i=0;i<15;i+=1){var mod=(!test&&((bits>>i)&1)==1);if(i<8){_modules[8][_moduleCount-i-1]=mod;}else if(i<9){_modules[8][15-i-1+1]=mod;}else{_modules[8][15-i-1]=mod;}} +_modules[_moduleCount-8][8]=(!test);};var mapData=function(data,maskPattern){var inc=-1;var row=_moduleCount-1;var bitIndex=7;var byteIndex=0;var maskFunc=QRUtil.getMaskFunction(maskPattern);for(var col=_moduleCount-1;col>0;col-=2){if(col==6)col-=1;while(true){for(var c=0;c<2;c+=1){if(_modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);} +var mask=maskFunc(row,col-c);if(mask){dark=!dark;} +_modules[row][col-c]=dark;bitIndex-=1;if(bitIndex==-1){byteIndex+=1;bitIndex=7;}}} +row+=inc;if(row<0||_moduleCount<=row){row-=inc;inc=-inc;break;}}}};var createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r+=1){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i+=1){dcdata[r][i]=0xff&buffer.getBuffer()[i+offset];} +offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=qrPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i+=1){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.getAt(modIndex):0;}} +var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalCodeCount+=rsBlocks[i].totalCount;} +var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<dcdata[r].length){data[index]=dcdata[r][i];index+=1;}}} +for(var i=0;i<maxEcCount;i+=1){for(var r=0;r<rsBlocks.length;r+=1){if(i<ecdata[r].length){data[index]=ecdata[r][i];index+=1;}}} +return data;};var createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=qrBitBuffer();for(var i=0;i<dataList.length;i+=1){var data=dataList[i];buffer.put(data.getMode(),4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.getMode(),typeNumber));data.write(buffer);} +var totalDataCount=0;for(var i=0;i<rsBlocks.length;i+=1){totalDataCount+=rsBlocks[i].dataCount;} +if(buffer.getLengthInBits()>totalDataCount*8){throw new Error('code length overflow. (' ++buffer.getLengthInBits() ++'>' ++totalDataCount*8 ++')');} +if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} +while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} +while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} +buffer.put(PAD1,8);} +return createBytes(buffer,rsBlocks);};_this.addData=function(data){var newData=qr8BitByte(data);_dataList.push(newData);_dataCache=null;};_this.isDark=function(row,col){if(row<0||_moduleCount<=row||col<0||_moduleCount<=col){throw new Error(row+','+col);} +return _modules[row][col];};_this.getModuleCount=function(){return _moduleCount;};_this.make=function(){makeImpl(false,getBestMaskPattern());};_this.createTableTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var qrHtml='';qrHtml+='<table style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: '+margin+'px;';qrHtml+='">';qrHtml+='<tbody>';for(var r=0;r<_this.getModuleCount();r+=1){qrHtml+='<tr>';for(var c=0;c<_this.getModuleCount();c+=1){qrHtml+='<td style="';qrHtml+=' border-width: 0px; border-style: none;';qrHtml+=' border-collapse: collapse;';qrHtml+=' padding: 0px; margin: 0px;';qrHtml+=' width: '+cellSize+'px;';qrHtml+=' height: '+cellSize+'px;';qrHtml+=' background-color: ';qrHtml+=_this.isDark(r,c)?'#000000':'#ffffff';qrHtml+=';';qrHtml+='"/>';} +qrHtml+='</tr>';} +qrHtml+='</tbody>';qrHtml+='</table>';return qrHtml;};_this.createImgTag=function(cellSize,margin){cellSize=cellSize||2;margin=(typeof margin=='undefined')?cellSize*4:margin;var size=_this.getModuleCount()*cellSize+margin*2;var min=margin;var max=size-margin;return createImgTag(size,size,function(x,y){if(min<=x&&x<max&&min<=y&&y<max){var c=Math.floor((x-min)/cellSize);var r=Math.floor((y-min)/cellSize);return _this.isDark(r,c)?0:1;}else{return 1;}});};return _this;};qrcode.stringToBytes=function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);bytes.push(c&0xff);} +return bytes;};qrcode.createStringToBytes=function(unicodeData,numChars){var unicodeMap=function(){var bin=base64DecodeInputStream(unicodeData);var read=function(){var b=bin.read();if(b==-1)throw new Error();return b;};var count=0;var unicodeMap={};while(true){var b0=bin.read();if(b0==-1)break;var b1=read();var b2=read();var b3=read();var k=String.fromCharCode((b0<<8)|b1);var v=(b2<<8)|b3;unicodeMap[k]=v;count+=1;} +if(count!=numChars){throw new Error(count+' != '+numChars);} +return unicodeMap;}();var unknownChar='?'.charCodeAt(0);return function(s){var bytes=new Array();for(var i=0;i<s.length;i+=1){var c=s.charCodeAt(i);if(c<128){bytes.push(c);}else{var b=unicodeMap[s.charAt(i)];if(typeof b=='number'){if((b&0xff)==b){bytes.push(b);}else{bytes.push(b>>>8);bytes.push(b&0xff);}}else{bytes.push(unknownChar);}}} +return bytes;};};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil=function(){var PATTERN_POSITION_TABLE=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]];var G15=(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0);var G18=(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0);var G15_MASK=(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1);var _this={};var getBCHDigit=function(data){var digit=0;while(data!=0){digit+=1;data>>>=1;} +return digit;};_this.getBCHTypeInfo=function(data){var d=data<<10;while(getBCHDigit(d)-getBCHDigit(G15)>=0){d^=(G15<<(getBCHDigit(d)-getBCHDigit(G15)));} +return((data<<10)|d)^G15_MASK;};_this.getBCHTypeNumber=function(data){var d=data<<12;while(getBCHDigit(d)-getBCHDigit(G18)>=0){d^=(G18<<(getBCHDigit(d)-getBCHDigit(G18)));} +return(data<<12)|d;};_this.getPatternPosition=function(typeNumber){return PATTERN_POSITION_TABLE[typeNumber-1];};_this.getMaskFunction=function(maskPattern){switch(maskPattern){case QRMaskPattern.PATTERN000:return function(i,j){return(i+j)%2==0;};case QRMaskPattern.PATTERN001:return function(i,j){return i%2==0;};case QRMaskPattern.PATTERN010:return function(i,j){return j%3==0;};case QRMaskPattern.PATTERN011:return function(i,j){return(i+j)%3==0;};case QRMaskPattern.PATTERN100:return function(i,j){return(Math.floor(i/2)+Math.floor(j/3))%2==0;};case QRMaskPattern.PATTERN101:return function(i,j){return(i*j)%2+(i*j)%3==0;};case QRMaskPattern.PATTERN110:return function(i,j){return((i*j)%2+(i*j)%3)%2==0;};case QRMaskPattern.PATTERN111:return function(i,j){return((i*j)%3+(i+j)%2)%2==0;};default:throw new Error('bad maskPattern:'+maskPattern);}};_this.getErrorCorrectPolynomial=function(errorCorrectLength){var a=qrPolynomial([1],0);for(var i=0;i<errorCorrectLength;i+=1){a=a.multiply(qrPolynomial([1,QRMath.gexp(i)],0));} +return a;};_this.getLengthInBits=function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error('mode:'+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error('mode:'+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error('mode:'+mode);}}else{throw new Error('type:'+type);}};_this.getLostPoint=function(qrcode){var moduleCount=qrcode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount;col+=1){var sameCount=0;var dark=qrcode.isDark(row,col);for(var r=-1;r<=1;r+=1){if(row+r<0||moduleCount<=row+r){continue;} +for(var c=-1;c<=1;c+=1){if(col+c<0||moduleCount<=col+c){continue;} +if(r==0&&c==0){continue;} +if(dark==qrcode.isDark(row+r,col+c)){sameCount+=1;}}} +if(sameCount>5){lostPoint+=(3+sameCount-5);}}};for(var row=0;row<moduleCount-1;row+=1){for(var col=0;col<moduleCount-1;col+=1){var count=0;if(qrcode.isDark(row,col))count+=1;if(qrcode.isDark(row+1,col))count+=1;if(qrcode.isDark(row,col+1))count+=1;if(qrcode.isDark(row+1,col+1))count+=1;if(count==0||count==4){lostPoint+=3;}}} +for(var row=0;row<moduleCount;row+=1){for(var col=0;col<moduleCount-6;col+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row,col+1)&&qrcode.isDark(row,col+2)&&qrcode.isDark(row,col+3)&&qrcode.isDark(row,col+4)&&!qrcode.isDark(row,col+5)&&qrcode.isDark(row,col+6)){lostPoint+=40;}}} +for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount-6;row+=1){if(qrcode.isDark(row,col)&&!qrcode.isDark(row+1,col)&&qrcode.isDark(row+2,col)&&qrcode.isDark(row+3,col)&&qrcode.isDark(row+4,col)&&!qrcode.isDark(row+5,col)&&qrcode.isDark(row+6,col)){lostPoint+=40;}}} +var darkCount=0;for(var col=0;col<moduleCount;col+=1){for(var row=0;row<moduleCount;row+=1){if(qrcode.isDark(row,col)){darkCount+=1;}}} +var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;};return _this;}();var QRMath=function(){var EXP_TABLE=new Array(256);var LOG_TABLE=new Array(256);for(var i=0;i<8;i+=1){EXP_TABLE[i]=1<<i;} +for(var i=8;i<256;i+=1){EXP_TABLE[i]=EXP_TABLE[i-4]^EXP_TABLE[i-5]^EXP_TABLE[i-6]^EXP_TABLE[i-8];} +for(var i=0;i<255;i+=1){LOG_TABLE[EXP_TABLE[i]]=i;} +var _this={};_this.glog=function(n){if(n<1){throw new Error('glog('+n+')');} +return LOG_TABLE[n];};_this.gexp=function(n){while(n<0){n+=255;} +while(n>=256){n-=255;} +return EXP_TABLE[n];};return _this;}();function qrPolynomial(num,shift){if(typeof num.length=='undefined'){throw new Error(num.length+'/'+shift);} +var _num=function(){var offset=0;while(offset<num.length&&num[offset]==0){offset+=1;} +var _num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i+=1){_num[i]=num[i+offset];} +return _num;}();var _this={};_this.getAt=function(index){return _num[index];};_this.getLength=function(){return _num.length;};_this.multiply=function(e){var num=new Array(_this.getLength()+e.getLength()-1);for(var i=0;i<_this.getLength();i+=1){for(var j=0;j<e.getLength();j+=1){num[i+j]^=QRMath.gexp(QRMath.glog(_this.getAt(i))+QRMath.glog(e.getAt(j)));}} +return qrPolynomial(num,0);};_this.mod=function(e){if(_this.getLength()-e.getLength()<0){return _this;} +var ratio=QRMath.glog(_this.getAt(0))-QRMath.glog(e.getAt(0));var num=new Array(_this.getLength());for(var i=0;i<_this.getLength();i+=1){num[i]=_this.getAt(i);} +for(var i=0;i<e.getLength();i+=1){num[i]^=QRMath.gexp(QRMath.glog(e.getAt(i))+ratio);} +return qrPolynomial(num,0).mod(e);};return _this;};var QRRSBlock=function(){var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16]];var qrRSBlock=function(totalCount,dataCount){var _this={};_this.totalCount=totalCount;_this.dataCount=dataCount;return _this;};var _this={};var getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};_this.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=getRsBlockTable(typeNumber,errorCorrectLevel);if(typeof rsBlock=='undefined'){throw new Error('bad rs block @ typeNumber:'+typeNumber+'/errorCorrectLevel:'+errorCorrectLevel);} +var length=rsBlock.length/3;var list=new Array();for(var i=0;i<length;i+=1){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j+=1){list.push(qrRSBlock(totalCount,dataCount));}} +return list;};return _this;}();var qrBitBuffer=function(){var _buffer=new Array();var _length=0;var _this={};_this.getBuffer=function(){return _buffer;};_this.getAt=function(index){var bufIndex=Math.floor(index/8);return((_buffer[bufIndex]>>>(7-index%8))&1)==1;};_this.put=function(num,length){for(var i=0;i<length;i+=1){_this.putBit(((num>>>(length-i-1))&1)==1);}};_this.getLengthInBits=function(){return _length;};_this.putBit=function(bit){var bufIndex=Math.floor(_length/8);if(_buffer.length<=bufIndex){_buffer.push(0);} +if(bit){_buffer[bufIndex]|=(0x80>>>(_length%8));} +_length+=1;};return _this;};var qr8BitByte=function(data){var _mode=QRMode.MODE_8BIT_BYTE;var _data=data;var _bytes=qrcode.stringToBytes(data);var _this={};_this.getMode=function(){return _mode;};_this.getLength=function(buffer){return _bytes.length;};_this.write=function(buffer){for(var i=0;i<_bytes.length;i+=1){buffer.put(_bytes[i],8);}};return _this;};var byteArrayOutputStream=function(){var _bytes=new Array();var _this={};_this.writeByte=function(b){_bytes.push(b&0xff);};_this.writeShort=function(i){_this.writeByte(i);_this.writeByte(i>>>8);};_this.writeBytes=function(b,off,len){off=off||0;len=len||b.length;for(var i=0;i<len;i+=1){_this.writeByte(b[i+off]);}};_this.writeString=function(s){for(var i=0;i<s.length;i+=1){_this.writeByte(s.charCodeAt(i));}};_this.toByteArray=function(){return _bytes;};_this.toString=function(){var s='';s+='[';for(var i=0;i<_bytes.length;i+=1){if(i>0){s+=',';} +s+=_bytes[i];} +s+=']';return s;};return _this;};var base64EncodeOutputStream=function(){var _buffer=0;var _buflen=0;var _length=0;var _base64='';var _this={};var writeEncoded=function(b){_base64+=String.fromCharCode(encode(b&0x3f));};var encode=function(n){if(n<0){}else if(n<26){return 0x41+n;}else if(n<52){return 0x61+(n-26);}else if(n<62){return 0x30+(n-52);}else if(n==62){return 0x2b;}else if(n==63){return 0x2f;} +throw new Error('n:'+n);};_this.writeByte=function(n){_buffer=(_buffer<<8)|(n&0xff);_buflen+=8;_length+=1;while(_buflen>=6){writeEncoded(_buffer>>>(_buflen-6));_buflen-=6;}};_this.flush=function(){if(_buflen>0){writeEncoded(_buffer<<(6-_buflen));_buffer=0;_buflen=0;} +if(_length%3!=0){var padlen=3-_length%3;for(var i=0;i<padlen;i+=1){_base64+='=';}}};_this.toString=function(){return _base64;};return _this;};var base64DecodeInputStream=function(str){var _str=str;var _pos=0;var _buffer=0;var _buflen=0;var _this={};_this.read=function(){while(_buflen<8){if(_pos>=_str.length){if(_buflen==0){return-1;} +throw new Error('unexpected end of file./'+_buflen);} +var c=_str.charAt(_pos);_pos+=1;if(c=='='){_buflen=0;return-1;}else if(c.match(/^\s$/)){continue;} +_buffer=(_buffer<<6)|decode(c.charCodeAt(0));_buflen+=6;} +var n=(_buffer>>>(_buflen-8))&0xff;_buflen-=8;return n;};var decode=function(c){if(0x41<=c&&c<=0x5a){return c-0x41;}else if(0x61<=c&&c<=0x7a){return c-0x61+26;}else if(0x30<=c&&c<=0x39){return c-0x30+52;}else if(c==0x2b){return 62;}else if(c==0x2f){return 63;}else{throw new Error('c:'+c);}};return _this;};var gifImage=function(width,height){var _width=width;var _height=height;var _data=new Array(width*height);var _this={};_this.setPixel=function(x,y,pixel){_data[y*_width+x]=pixel;};_this.write=function(out){out.writeString('GIF87a');out.writeShort(_width);out.writeShort(_height);out.writeByte(0x80);out.writeByte(0);out.writeByte(0);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0x00);out.writeByte(0xff);out.writeByte(0xff);out.writeByte(0xff);out.writeString(',');out.writeShort(0);out.writeShort(0);out.writeShort(_width);out.writeShort(_height);out.writeByte(0);var lzwMinCodeSize=2;var raster=getLZWRaster(lzwMinCodeSize);out.writeByte(lzwMinCodeSize);var offset=0;while(raster.length-offset>255){out.writeByte(255);out.writeBytes(raster,offset,255);offset+=255;} +out.writeByte(raster.length-offset);out.writeBytes(raster,offset,raster.length-offset);out.writeByte(0x00);out.writeString(';');};var bitOutputStream=function(out){var _out=out;var _bitLength=0;var _bitBuffer=0;var _this={};_this.write=function(data,length){if((data>>>length)!=0){throw new Error('length over');} +while(_bitLength+length>=8){_out.writeByte(0xff&((data<<_bitLength)|_bitBuffer));length-=(8-_bitLength);data>>>=(8-_bitLength);_bitBuffer=0;_bitLength=0;} +_bitBuffer=(data<<_bitLength)|_bitBuffer;_bitLength=_bitLength+length;};_this.flush=function(){if(_bitLength>0){_out.writeByte(_bitBuffer);}};return _this;};var getLZWRaster=function(lzwMinCodeSize){var clearCode=1<<lzwMinCodeSize;var endCode=(1<<lzwMinCodeSize)+1;var bitLength=lzwMinCodeSize+1;var table=lzwTable();for(var i=0;i<clearCode;i+=1){table.add(String.fromCharCode(i));} +table.add(String.fromCharCode(clearCode));table.add(String.fromCharCode(endCode));var byteOut=byteArrayOutputStream();var bitOut=bitOutputStream(byteOut);bitOut.write(clearCode,bitLength);var dataIndex=0;var s=String.fromCharCode(_data[dataIndex]);dataIndex+=1;while(dataIndex<_data.length){var c=String.fromCharCode(_data[dataIndex]);dataIndex+=1;if(table.contains(s+c)){s=s+c;}else{bitOut.write(table.indexOf(s),bitLength);if(table.size()<0xfff){if(table.size()==(1<<bitLength)){bitLength+=1;} +table.add(s+c);} +s=c;}} +bitOut.write(table.indexOf(s),bitLength);bitOut.write(endCode,bitLength);bitOut.flush();return byteOut.toByteArray();};var lzwTable=function(){var _map={};var _size=0;var _this={};_this.add=function(key){if(_this.contains(key)){throw new Error('dup key:'+key);} +_map[key]=_size;_size+=1;};_this.size=function(){return _size;};_this.indexOf=function(key){return _map[key];};_this.contains=function(key){return typeof _map[key]!='undefined';};return _this;};return _this;};var createImgTag=function(width,height,getPixel,alt){var gif=gifImage(width,height);for(var y=0;y<height;y+=1){for(var x=0;x<width;x+=1){gif.setPixel(x,y,getPixel(x,y));}} +var b=byteArrayOutputStream();gif.write(b);var base64=base64EncodeOutputStream();var bytes=b.toByteArray();for(var i=0;i<bytes.length;i+=1){base64.writeByte(bytes[i]);} +base64.flush();var img='';img+='<img';img+='\u0020src="';img+='data:image/gif;base64,';img+=base64;img+='"';img+='\u0020width="';img+=width;img+='"';img+='\u0020height="';img+=height;img+='"';if(alt){img+='\u0020alt="';img+=alt;img+='"';} +img+='/>';return img;};return qrcode;}();/* |xGv00|ca8fc6bde81a353e7cede123b304bdb9 */ \ No newline at end of file diff --git a/static/js/rsa.js b/static/js/rsa.js new file mode 100755 index 0000000..255f26b --- /dev/null +++ b/static/js/rsa.js @@ -0,0 +1,790 @@ +// Copyright (c) 2005 Tom Wu +// All Rights Reserved. +// See "LICENSE" for details. + +// Basic JavaScript BN library - subset useful for RSA encryption. + +// Bits per digit +var dbits; + +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary&0xffffff)==0xefcafe); + +// (public) Constructor +function BigInteger(a,b,c) { + if(a != null) + if("number" == typeof a) this.fromNumber(a,b,c); + else if(b == null && "string" != typeof a) this.fromString(a,256); + else this.fromString(a,b); +} + +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } + +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. + +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i,x,w,j,c,n) { + while(--n >= 0) { + var v = x*this[i++]+w[j]+c; + c = Math.floor(v/0x4000000); + w[j++] = v&0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i,x,w,j,c,n) { + var xl = x&0x7fff, xh = x>>15; + while(--n >= 0) { + var l = this[i]&0x7fff; + var h = this[i++]>>15; + var m = xh*l+h*xl; + l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); + c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); + w[j++] = l&0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i,x,w,j,c,n) { + var xl = x&0x3fff, xh = x>>14; + while(--n >= 0) { + var l = this[i]&0x3fff; + var h = this[i++]>>14; + var m = xh*l+h*xl; + l = xl*l+((m&0x3fff)<<14)+w[j]+c; + c = (l>>28)+(m>>14)+xh*h; + w[j++] = l&0xfffffff; + } + return c; +} +if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) { + BigInteger.prototype.am = am2; + dbits = 30; +} +else if(j_lm && (navigator.appName != "Netscape")) { + BigInteger.prototype.am = am1; + dbits = 26; +} +else { // Mozilla/Netscape seems to prefer am3 + BigInteger.prototype.am = am3; + dbits = 28; +} + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1<<dbits)-1); +BigInteger.prototype.DV = (1<<dbits); + +var BI_FP = 52; +BigInteger.prototype.FV = Math.pow(2,BI_FP); +BigInteger.prototype.F1 = BI_FP-dbits; +BigInteger.prototype.F2 = 2*dbits-BI_FP; + +// Digit conversions +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; +var BI_RC = new Array(); +var rr,vv; +rr = "0".charCodeAt(0); +for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv; +rr = "a".charCodeAt(0); +for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; +rr = "A".charCodeAt(0); +for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv; + +function int2char(n) { return BI_RM.charAt(n); } +function intAt(s,i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c==null)?-1:c; +} + +// (protected) copy this to r +function bnpCopyTo(r) { + for(var i = this.t-1; i >= 0; --i) r[i] = this[i]; + r.t = this.t; + r.s = this.s; +} + +// (protected) set from integer value x, -DV <= x < DV +function bnpFromInt(x) { + this.t = 1; + this.s = (x<0)?-1:0; + if(x > 0) this[0] = x; + else if(x < -1) this[0] = x+DV; + else this.t = 0; +} + +// return bigint initialized to value +function nbv(i) { var r = nbi(); r.fromInt(i); return r; } + +// (protected) set from string and radix +function bnpFromString(s,b) { + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 256) k = 8; // byte array + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else { this.fromRadix(s,b); return; } + this.t = 0; + this.s = 0; + var i = s.length, mi = false, sh = 0; + while(--i >= 0) { + var x = (k==8)?s[i]&0xff:intAt(s,i); + if(x < 0) { + if(s.charAt(i) == "-") mi = true; + continue; + } + mi = false; + if(sh == 0) + this[this.t++] = x; + else if(sh+k > this.DB) { + this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh; + this[this.t++] = (x>>(this.DB-sh)); + } + else + this[this.t-1] |= x<<sh; + sh += k; + if(sh >= this.DB) sh -= this.DB; + } + if(k == 8 && (s[0]&0x80) != 0) { + this.s = -1; + if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh; + } + this.clamp(); + if(mi) BigInteger.ZERO.subTo(this,this); +} + +// (protected) clamp off excess high words +function bnpClamp() { + var c = this.s&this.DM; + while(this.t > 0 && this[this.t-1] == c) --this.t; +} + +// (public) return string representation in given radix +function bnToString(b) { + if(this.s < 0) return "-"+this.negate().toString(b); + var k; + if(b == 16) k = 4; + else if(b == 8) k = 3; + else if(b == 2) k = 1; + else if(b == 32) k = 5; + else if(b == 4) k = 2; + else return this.toRadix(b); + var km = (1<<k)-1, d, m = false, r = "", i = this.t; + var p = this.DB-(i*this.DB)%k; + if(i-- > 0) { + if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); } + while(i >= 0) { + if(p < k) { + d = (this[i]&((1<<p)-1))<<(k-p); + d |= this[--i]>>(p+=this.DB-k); + } + else { + d = (this[i]>>(p-=k))&km; + if(p <= 0) { p += this.DB; --i; } + } + if(d > 0) m = true; + if(m) r += int2char(d); + } + } + return m?r:"0"; +} + +// (public) -this +function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +// (public) |this| +function bnAbs() { return (this.s<0)?this.negate():this; } + +// (public) return + if this > a, - if this < a, 0 if equal +function bnCompareTo(a) { + var r = this.s-a.s; + if(r != 0) return r; + var i = this.t; + r = i-a.t; + if(r != 0) return r; + while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; + return 0; +} + +// returns bit length of the integer x +function nbits(x) { + var r = 1, t; + if((t=x>>>16) != 0) { x = t; r += 16; } + if((t=x>>8) != 0) { x = t; r += 8; } + if((t=x>>4) != 0) { x = t; r += 4; } + if((t=x>>2) != 0) { x = t; r += 2; } + if((t=x>>1) != 0) { x = t; r += 1; } + return r; +} + +// (public) return the number of bits in "this" +function bnBitLength() { + if(this.t <= 0) return 0; + return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); +} + +// (protected) r = this << n*DB +function bnpDLShiftTo(n,r) { + var i; + for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; + for(i = n-1; i >= 0; --i) r[i] = 0; + r.t = this.t+n; + r.s = this.s; +} + +// (protected) r = this >> n*DB +function bnpDRShiftTo(n,r) { + for(var i = n; i < this.t; ++i) r[i-n] = this[i]; + r.t = Math.max(this.t-n,0); + r.s = this.s; +} + +// (protected) r = this << n +function bnpLShiftTo(n,r) { + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<<cbs)-1; + var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i; + for(i = this.t-1; i >= 0; --i) { + r[i+ds+1] = (this[i]>>cbs)|c; + c = (this[i]&bm)<<bs; + } + for(i = ds-1; i >= 0; --i) r[i] = 0; + r[ds] = c; + r.t = this.t+ds+1; + r.s = this.s; + r.clamp(); +} + +// (protected) r = this >> n +function bnpRShiftTo(n,r) { + r.s = this.s; + var ds = Math.floor(n/this.DB); + if(ds >= this.t) { r.t = 0; return; } + var bs = n%this.DB; + var cbs = this.DB-bs; + var bm = (1<<bs)-1; + r[0] = this[ds]>>bs; + for(var i = ds+1; i < this.t; ++i) { + r[i-ds-1] |= (this[i]&bm)<<cbs; + r[i-ds] = this[i]>>bs; + } + if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs; + r.t = this.t-ds; + r.clamp(); +} + +// (protected) r = this - a +function bnpSubTo(a,r) { + var i = 0, c = 0, m = Math.min(a.t,this.t); + while(i < m) { + c += this[i]-a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + if(a.t < this.t) { + c -= a.s; + while(i < this.t) { + c += this[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while(i < a.t) { + c -= a[i]; + r[i++] = c&this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c<0)?-1:0; + if(c < -1) r[i++] = this.DV+c; + else if(c > 0) r[i++] = c; + r.t = i; + r.clamp(); +} + +// (protected) r = this * a, r != this,a (HAC 14.12) +// "this" should be the larger one if appropriate. +function bnpMultiplyTo(a,r) { + var x = this.abs(), y = a.abs(); + var i = x.t; + r.t = i+y.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); + r.s = 0; + r.clamp(); + if(this.s != a.s) BigInteger.ZERO.subTo(r,r); +} + +// (protected) r = this^2, r != this (HAC 14.16) +function bnpSquareTo(r) { + var x = this.abs(); + var i = r.t = 2*x.t; + while(--i >= 0) r[i] = 0; + for(i = 0; i < x.t-1; ++i) { + var c = x.am(i,x[i],r,2*i,0,1); + if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { + r[i+x.t] -= x.DV; + r[i+x.t+1] = 1; + } + } + if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); + r.s = 0; + r.clamp(); +} + +// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) +// r != q, this != m. q or r may be null. +function bnpDivRemTo(m,q,r) { + var pm = m.abs(); + if(pm.t <= 0) return; + var pt = this.abs(); + if(pt.t < pm.t) { + if(q != null) q.fromInt(0); + if(r != null) this.copyTo(r); + return; + } + if(r == null) r = nbi(); + var y = nbi(), ts = this.s, ms = m.s; + var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus + if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } + else { pm.copyTo(y); pt.copyTo(r); } + var ys = y.t; + var y0 = y[ys-1]; + if(y0 == 0) return; + var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0); + var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2; + var i = r.t, j = i-ys, t = (q==null)?nbi():q; + y.dlShiftTo(j,t); + if(r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t,r); + } + BigInteger.ONE.dlShiftTo(ys,t); + t.subTo(y,y); // "negative" y so we can replace sub with am later + while(y.t < ys) y[y.t++] = 0; + while(--j >= 0) { + // Estimate quotient digit + var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); + if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out + y.dlShiftTo(j,t); + r.subTo(t,r); + while(r[i] < --qd) r.subTo(t,r); + } + } + if(q != null) { + r.drShiftTo(ys,q); + if(ts != ms) BigInteger.ZERO.subTo(q,q); + } + r.t = ys; + r.clamp(); + if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder + if(ts < 0) BigInteger.ZERO.subTo(r,r); +} + +// (public) this mod a +function bnMod(a) { + var r = nbi(); + this.abs().divRemTo(a,null,r); + if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); + return r; +} + +// Modular reduction using "classic" algorithm +function Classic(m) { this.m = m; } +function cConvert(x) { + if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + else return x; +} +function cRevert(x) { return x; } +function cReduce(x) { x.divRemTo(this.m,null,x); } +function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } +function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +Classic.prototype.convert = cConvert; +Classic.prototype.revert = cRevert; +Classic.prototype.reduce = cReduce; +Classic.prototype.mulTo = cMulTo; +Classic.prototype.sqrTo = cSqrTo; + +// (protected) return "-1/this % 2^DB"; useful for Mont. reduction +// justification: +// xy == 1 (mod m) +// xy = 1+km +// xy(2-xy) = (1+km)(1-km) +// x[y(2-xy)] = 1-k^2m^2 +// x[y(2-xy)] == 1 (mod m^2) +// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 +// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. +// JS multiply "overflows" differently from C/C++, so care is needed here. +function bnpInvDigit() { + if(this.t < 1) return 0; + var x = this[0]; + if((x&1) == 0) return 0; + var y = x&3; // y == 1/x mod 2^2 + y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 + y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 + y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y>0)?this.DV-y:-y; +} + +// Montgomery reduction +function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp&0x7fff; + this.mph = this.mp>>15; + this.um = (1<<(m.DB-15))-1; + this.mt2 = 2*m.t; +} + +// xR mod m +function montConvert(x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t,r); + r.divRemTo(this.m,null,r); + if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); + return r; +} + +// x/R mod m +function montRevert(x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; +} + +// x = x/R mod m (HAC 14.32) +function montReduce(x) { + while(x.t <= this.mt2) // pad x so am has enough room later + x[x.t++] = 0; + for(var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i]&0x7fff; + var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; + // use am to combine the multiply-shift-add into one call + j = i+this.m.t; + x[j] += this.m.am(0,u0,x,i,0,this.m.t); + // propagate carry + while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } + } + x.clamp(); + x.drShiftTo(this.m.t,x); + if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); +} + +// r = "x^2/R mod m"; x != r +function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } + +// r = "xy/R mod m"; x,y != r +function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } + +Montgomery.prototype.convert = montConvert; +Montgomery.prototype.revert = montRevert; +Montgomery.prototype.reduce = montReduce; +Montgomery.prototype.mulTo = montMulTo; +Montgomery.prototype.sqrTo = montSqrTo; + +// (protected) true iff this is even +function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } + +// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) +function bnpExp(e,z) { + if(e > 0xffffffff || e < 1) return BigInteger.ONE; + var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; + g.copyTo(r); + while(--i >= 0) { + z.sqrTo(r,r2); + if((e&(1<<i)) > 0) z.mulTo(r2,g,r); + else { var t = r; r = r2; r2 = t; } + } + return z.revert(r); +} + +// (public) this^e % m, 0 <= e < 2^32 +function bnModPowInt(e,m) { + var z; + if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); + return this.exp(e,z); +} + +// protected +BigInteger.prototype.copyTo = bnpCopyTo; +BigInteger.prototype.fromInt = bnpFromInt; +BigInteger.prototype.fromString = bnpFromString; +BigInteger.prototype.clamp = bnpClamp; +BigInteger.prototype.dlShiftTo = bnpDLShiftTo; +BigInteger.prototype.drShiftTo = bnpDRShiftTo; +BigInteger.prototype.lShiftTo = bnpLShiftTo; +BigInteger.prototype.rShiftTo = bnpRShiftTo; +BigInteger.prototype.subTo = bnpSubTo; +BigInteger.prototype.multiplyTo = bnpMultiplyTo; +BigInteger.prototype.squareTo = bnpSquareTo; +BigInteger.prototype.divRemTo = bnpDivRemTo; +BigInteger.prototype.invDigit = bnpInvDigit; +BigInteger.prototype.isEven = bnpIsEven; +BigInteger.prototype.exp = bnpExp; + +// public +BigInteger.prototype.toString = bnToString; +BigInteger.prototype.negate = bnNegate; +BigInteger.prototype.abs = bnAbs; +BigInteger.prototype.compareTo = bnCompareTo; +BigInteger.prototype.bitLength = bnBitLength; +BigInteger.prototype.mod = bnMod; +BigInteger.prototype.modPowInt = bnModPowInt; + +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + + +// prng4.js - uses Arcfour as a PRNG + +function Arcfour() { + this.i = 0; + this.j = 0; + this.S = new Array(); +} + +// Initialize arcfour context from key, an array of ints, each from [0..255] +function ARC4init(key) { + var i, j, t; + for(i = 0; i < 256; ++i) + this.S[i] = i; + j = 0; + for(i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; +} + +function ARC4next() { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; +} + +Arcfour.prototype.init = ARC4init; +Arcfour.prototype.next = ARC4next; + +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} + +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + + +// Random number generator - requires a PRNG backend, e.g. prng4.js + +// For best results, put code like +// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> +// in your main HTML document. + +var rng_state; +var rng_pool; +var rng_pptr; + +// Mix in a 32-bit integer into the pool +function rng_seed_int(x) { + rng_pool[rng_pptr++] ^= x & 255; + rng_pool[rng_pptr++] ^= (x >> 8) & 255; + rng_pool[rng_pptr++] ^= (x >> 16) & 255; + rng_pool[rng_pptr++] ^= (x >> 24) & 255; + if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; +} + +// Mix in the current time (w/milliseconds) into the pool +function rng_seed_time() { + rng_seed_int(new Date().getTime()); +} + +// Initialize the pool with junk if needed. +if(rng_pool == null) { + rng_pool = new Array(); + rng_pptr = 0; + var t; + if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { + // Extract entropy (256 bits) from NS4 RNG if available + var z = window.crypto.random(32); + for(t = 0; t < z.length; ++t) + rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; + } + while(rng_pptr < rng_psize) { // extract some randomness from Math.random() + t = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = t >>> 8; + rng_pool[rng_pptr++] = t & 255; + } + rng_pptr = 0; + rng_seed_time(); + //rng_seed_int(window.screenX); + //rng_seed_int(window.screenY); +} + +function rng_get_byte() { + if(rng_state == null) { + rng_seed_time(); + rng_state = prng_newstate(); + rng_state.init(rng_pool); + for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) + rng_pool[rng_pptr] = 0; + rng_pptr = 0; + //rng_pool = null; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} + +function rng_get_bytes(ba) { + var i; + for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); +} + +function SecureRandom() {} + +SecureRandom.prototype.nextBytes = rng_get_bytes; + + +// Depends on jsbn.js and rng.js + +// Version 1.1: support utf-8 encoding in pkcs1pad2 + +// convert a (hex) string to a bignum object +function parseBigInt(str,r) { + return new BigInteger(str,r); +} + +function linebrk(s,n) { + var ret = ""; + var i = 0; + while(i + n < s.length) { + ret += s.substring(i,i+n) + "\n"; + i += n; + } + return ret + s.substring(i,s.length); +} + +function byte2Hex(b) { + if(b < 0x10) + return "0" + b.toString(16); + else + return b.toString(16); +} + +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s,n) { + if(n < s.length + 11) { // TODO: fix for utf-8 + alert("Message too long for RSA"); + return null; + } + var ba = new Array(); + var i = s.length - 1; + while(i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if(c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = new Array(); + while(n > 2) { // random non-zero pad + x[0] = 0; + while(x[0] == 0) rng.nextBytes(x); + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} + +// "empty" RSA key constructor +function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; +} + +// Set the public key fields N and e from hex strings +function RSASetPublic(N,E) { + if(N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N,16); + this.e = parseInt(E,16); + } + else + alert("Invalid RSA public key"); +} + +// Perform raw public operation on "x": return x^e (mod n) +function RSADoPublic(x) { + return x.modPowInt(this.e, this.n); +} + +// Return the PKCS#1 RSA encryption of "text" as an even-length hex string +function RSAEncrypt(text) { + var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); + if(m == null) return null; + var c = this.doPublic(m); + if(c == null) return null; + var h = c.toString(16); + if((h.length & 1) == 0) return h; else return "0" + h; +} + +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +//function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +//} + +// protected +RSAKey.prototype.doPublic = RSADoPublic; + +// public +RSAKey.prototype.setPublic = RSASetPublic; +RSAKey.prototype.encrypt = RSAEncrypt; +//RSAKey.prototype.encrypt_b64 = RSAEncryptB64; diff --git a/static/plugins/colpick/css/colpick.css b/static/plugins/colpick/css/colpick.css new file mode 100755 index 0000000..564f60c --- /dev/null +++ b/static/plugins/colpick/css/colpick.css @@ -0,0 +1,420 @@ +/* +colpick Color Picker / colpick.com +*/ + +/*Main container*/ +.colpick { + position: absolute; + width: 346px; + height: 170px; + overflow: hidden; + display: none; + font-family: Arial, Helvetica, sans-serif; + background:#ebebeb; + border: 1px solid #bbb; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + + /*Prevents selecting text when dragging the selectors*/ + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +/*Color selection box with gradients*/ +.colpick_color { + position: absolute; + left: 7px; + top: 7px; + width: 156px; + height: 156px; + overflow: hidden; + outline: 1px solid #aaa; + cursor: crosshair; +} +.colpick_color_overlay1 { + position: absolute; + left:0; + top:0; + width: 156px; + height: 156px; + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')"; /* IE8 */ + background: -moz-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* IE10+ */ + background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff'); /* IE6 & IE7 */ +} +.colpick_color_overlay2 { + position: absolute; + left:0; + top:0; + width: 156px; + height: 156px; + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')"; /* IE8 */ + background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* IE10+ */ + background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#000000',GradientType=0 ); /* IE6-9 */ +} +/*Circular color selector*/ +.colpick_selector_outer { + background:none; + position: absolute; + width: 11px; + height: 11px; + margin: -6px 0 0 -6px; + border: 1px solid black; + border-radius: 50%; +} +.colpick_selector_inner{ + position: absolute; + width: 9px; + height: 9px; + border: 1px solid white; + border-radius: 50%; +} +/*Vertical hue bar*/ +.colpick_hue { + position: absolute; + top: 6px; + left: 175px; + width: 19px; + height: 156px; + border: 1px solid #aaa; + cursor: n-resize; +} +/*Hue bar sliding indicator*/ +.colpick_hue_arrs { + position: absolute; + left: -8px; + width: 35px; + height: 7px; + margin: -7px 0 0 0; +} +.colpick_hue_larr { + position:absolute; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-left: 7px solid #858585; +} +.colpick_hue_rarr { + position:absolute; + right:0; + width: 0; + height: 0; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + border-right: 7px solid #858585; +} +/*New color box*/ +.colpick_new_color { + position: absolute; + left: 207px; + top: 6px; + width: 60px; + height: 27px; + background: #f00; + border: 1px solid #8f8f8f; +} +/*Current color box*/ +.colpick_current_color { + position: absolute; + left: 277px; + top: 6px; + width: 60px; + height: 27px; + background: #f00; + border: 1px solid #8f8f8f; +} +/*Input field containers*/ +.colpick_field, .colpick_hex_field { + position: absolute; + height: 20px; + width: 60px; + overflow:hidden; + background:#f3f3f3; + color:#b8b8b8; + font-size:12px; + border:1px solid #bdbdbd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.colpick_rgb_r { + top: 40px; + left: 207px; +} +.colpick_rgb_g { + top: 67px; + left: 207px; +} +.colpick_rgb_b { + top: 94px; + left: 207px; +} +.colpick_hsb_h { + top: 40px; + left: 277px; +} +.colpick_hsb_s { + top: 67px; + left: 277px; +} +.colpick_hsb_b { + top: 94px; + left: 277px; +} +.colpick_hex_field { + width: 68px; + left: 207px; + top: 121px; +} +/*Text field container on focus*/ +.colpick_focus { + border-color: #999; +} +/*Field label container*/ +.colpick_field_letter { + position: absolute; + width: 12px; + height: 20px; + line-height: 20px; + padding-left: 4px; + background: #efefef; + border-right: 1px solid #bdbdbd; + font-weight: bold; + color:#777; +} +/*Text inputs*/ +.colpick_field input, .colpick_hex_field input { + position: absolute; + right: 11px; + margin: 0; + padding: 0; + height: 20px; + line-height: 20px; + background: transparent; + border: none; + font-size: 12px; + font-family: Arial, Helvetica, sans-serif; + color: #555; + text-align: right; + outline: none; +} +.colpick_hex_field input { + right: 4px; +} +/*Field up/down arrows*/ +.colpick_field_arrs { + position: absolute; + top: 0; + right: 0; + width: 9px; + height: 21px; + cursor: n-resize; +} +.colpick_field_uarr { + position: absolute; + top: 5px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-bottom: 4px solid #959595; +} +.colpick_field_darr { + position: absolute; + bottom:5px; + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 4px solid #959595; +} +/*Submit/Select button*/ +.colpick_submit { + position: absolute; + left: 207px; + top: 149px; + width: 130px; + height: 22px; + line-height:22px; + background: #efefef; + text-align: center; + color: #555; + font-size: 12px; + font-weight:bold; + border: 1px solid #bdbdbd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.colpick_submit:hover { + background:#f3f3f3; + border-color:#999; + cursor: pointer; +} + +/*full layout with no submit button*/ +.colpick_full_ns .colpick_submit, .colpick_full_ns .colpick_current_color{ + display:none; +} +.colpick_full_ns .colpick_new_color { + width: 130px; + height: 25px; +} +.colpick_full_ns .colpick_rgb_r, .colpick_full_ns .colpick_hsb_h { + top: 42px; +} +.colpick_full_ns .colpick_rgb_g, .colpick_full_ns .colpick_hsb_s { + top: 73px; +} +.colpick_full_ns .colpick_rgb_b, .colpick_full_ns .colpick_hsb_b { + top: 104px; +} +.colpick_full_ns .colpick_hex_field { + top: 135px; +} + +/*rgbhex layout*/ +.colpick_rgbhex .colpick_hsb_h, .colpick_rgbhex .colpick_hsb_s, .colpick_rgbhex .colpick_hsb_b { + display:none; +} +.colpick_rgbhex { + width:282px; +} +.colpick_rgbhex .colpick_field, .colpick_rgbhex .colpick_submit { + width:68px; +} +.colpick_rgbhex .colpick_new_color { + width:34px; + border-right:none; +} +.colpick_rgbhex .colpick_current_color { + width:34px; + left:240px; + border-left:none; +} + +/*rgbhex layout, no submit button*/ +.colpick_rgbhex_ns .colpick_submit, .colpick_rgbhex_ns .colpick_current_color{ + display:none; +} +.colpick_rgbhex_ns .colpick_new_color{ + width:68px; + border: 1px solid #8f8f8f; +} +.colpick_rgbhex_ns .colpick_rgb_r { + top: 42px; +} +.colpick_rgbhex_ns .colpick_rgb_g { + top: 73px; +} +.colpick_rgbhex_ns .colpick_rgb_b { + top: 104px; +} +.colpick_rgbhex_ns .colpick_hex_field { + top: 135px; +} + +/*hex layout*/ +.colpick_hex .colpick_hsb_h, .colpick_hex .colpick_hsb_s, .colpick_hex .colpick_hsb_b, .colpick_hex .colpick_rgb_r, .colpick_hex .colpick_rgb_g, .colpick_hex .colpick_rgb_b { + display:none; +} +.colpick_hex { + width:206px; + height:201px; +} +.colpick_hex .colpick_hex_field { + width:72px; + height:25px; + top:168px; + left:80px; +} +.colpick_hex .colpick_hex_field div, .colpick_hex .colpick_hex_field input { + height: 25px; + line-height: 25px; +} +.colpick_hex .colpick_new_color { + left:9px; + top:168px; + width:30px; + border-right:none; +} +.colpick_hex .colpick_current_color { + left:39px; + top:168px; + width:30px; + border-left:none; +} +.colpick_hex .colpick_submit { + left:164px; + top: 168px; + width:30px; + height:25px; + line-height: 25px; +} + +/*hex layout, no submit button*/ +.colpick_hex_ns .colpick_submit, .colpick_hex_ns .colpick_current_color { + display:none; +} +.colpick_hex_ns .colpick_hex_field { + width:80px; +} +.colpick_hex_ns .colpick_new_color{ + width:60px; + border: 1px solid #8f8f8f; +} + +/*Dark color scheme*/ +.colpick_dark { + background: #161616; + border-color: #2a2a2a; +} +.colpick_dark .colpick_color { + outline-color: #333; +} +.colpick_dark .colpick_hue { + border-color: #555; +} +.colpick_dark .colpick_field, .colpick_dark .colpick_hex_field { + background: #101010; + border-color: #2d2d2d; +} +.colpick_dark .colpick_field_letter { + background: #131313; + border-color: #2d2d2d; + color: #696969; +} +.colpick_dark .colpick_field input, .colpick_dark .colpick_hex_field input { + color: #7a7a7a; +} +.colpick_dark .colpick_field_uarr { + border-bottom-color:#696969; +} +.colpick_dark .colpick_field_darr { + border-top-color:#696969; +} +.colpick_dark .colpick_focus { + border-color:#444; +} +.colpick_dark .colpick_submit { + background: #131313; + border-color:#2d2d2d; + color:#7a7a7a; +} +.colpick_dark .colpick_submit:hover { + background-color:#101010; + border-color:#444; +} \ No newline at end of file diff --git a/static/plugins/colpick/js/colpick.js b/static/plugins/colpick/js/colpick.js new file mode 100755 index 0000000..d77432a --- /dev/null +++ b/static/plugins/colpick/js/colpick.js @@ -0,0 +1,520 @@ +/* +colpick Color Picker +Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed under the MIT and GPL licenses + +For usage and examples: colpick.com/plugin + */ + +(function ($) { + var colpick = function () { + var + tpl = '<div class="colpick"><div class="colpick_color"><div class="colpick_color_overlay1"><div class="colpick_color_overlay2"><div class="colpick_selector_outer"><div class="colpick_selector_inner"></div></div></div></div></div><div class="colpick_hue"><div class="colpick_hue_arrs"><div class="colpick_hue_larr"></div><div class="colpick_hue_rarr"></div></div></div><div class="colpick_new_color"></div><div class="colpick_current_color"></div><div class="colpick_hex_field"><div class="colpick_field_letter">#</div><input type="text" maxlength="6" size="6" /></div><div class="colpick_rgb_r colpick_field"><div class="colpick_field_letter">R</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_g colpick_field"><div class="colpick_field_letter">G</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_b colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_h colpick_field"><div class="colpick_field_letter">H</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_s colpick_field"><div class="colpick_field_letter">S</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsb_b colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_submit"></div></div>', + defaults = { + showEvent: 'click', + onShow: function () {}, + onBeforeShow: function(){}, + onHide: function () {}, + onChange: function () {}, + onSubmit: function () {}, + colorScheme: 'light', + color: '3289c7', + livePreview: true, + flat: false, + layout: 'full', + submit: 1, + submitText: 'OK', + height: 156 + }, + //Fill the inputs of the plugin + fillRGBFields = function (hsb, cal) { + var rgb = hsbToRgb(hsb); + $(cal).data('colpick').fields + .eq(1).val(rgb.r).end() + .eq(2).val(rgb.g).end() + .eq(3).val(rgb.b).end(); + }, + fillHSBFields = function (hsb, cal) { + $(cal).data('colpick').fields + .eq(4).val(Math.round(hsb.h)).end() + .eq(5).val(Math.round(hsb.s)).end() + .eq(6).val(Math.round(hsb.b)).end(); + }, + fillHexFields = function (hsb, cal) { + $(cal).data('colpick').fields.eq(0).val(hsbToHex(hsb)); + }, + //Set the round selector position + setSelector = function (hsb, cal) { + $(cal).data('colpick').selector.css('backgroundColor', '#' + hsbToHex({h: hsb.h, s: 100, b: 100})); + $(cal).data('colpick').selectorIndic.css({ + left: parseInt($(cal).data('colpick').height * hsb.s/100, 10), + top: parseInt($(cal).data('colpick').height * (100-hsb.b)/100, 10) + }); + }, + //Set the hue selector position + setHue = function (hsb, cal) { + $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h/360, 10)); + }, + //Set current and new colors + setCurrentColor = function (hsb, cal) { + $(cal).data('colpick').currentColor.css('backgroundColor', '#' + hsbToHex(hsb)); + }, + setNewColor = function (hsb, cal) { + $(cal).data('colpick').newColor.css('backgroundColor', '#' + hsbToHex(hsb)); + }, + //Called when the new color is changed + change = function (ev) { + var cal = $(this).parent().parent(), col; + if (this.parentNode.className.indexOf('_hex') > 0) { + cal.data('colpick').color = col = hexToHsb(fixHex(this.value)); + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } else if (this.parentNode.className.indexOf('_hsb') > 0) { + cal.data('colpick').color = col = fixHSB({ + h: parseInt(cal.data('colpick').fields.eq(4).val(), 10), + s: parseInt(cal.data('colpick').fields.eq(5).val(), 10), + b: parseInt(cal.data('colpick').fields.eq(6).val(), 10) + }); + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + } else { + cal.data('colpick').color = col = rgbToHsb(fixRGB({ + r: parseInt(cal.data('colpick').fields.eq(1).val(), 10), + g: parseInt(cal.data('colpick').fields.eq(2).val(), 10), + b: parseInt(cal.data('colpick').fields.eq(3).val(), 10) + })); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + } + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); + }, + //Change style on blur and on focus of inputs + blur = function (ev) { + $(this).parent().removeClass('colpick_focus'); + }, + focus = function () { + $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus'); + $(this).parent().addClass('colpick_focus'); + }, + //Increment/decrement arrows functions + downIncrement = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var field = $(this).parent().find('input').focus(); + var current = { + el: $(this).parent().addClass('colpick_slider'), + max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), + y: ev.pageY, + field: field, + val: parseInt(field.val(), 10), + preview: $(this).parent().parent().data('colpick').livePreview + }; + $(document).mouseup(current, upIncrement); + $(document).mousemove(current, moveIncrement); + }, + moveIncrement = function (ev) { + ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val - ev.pageY + ev.data.y, 10)))); + if (ev.data.preview) { + change.apply(ev.data.field.get(0), [true]); + } + return false; + }, + upIncrement = function (ev) { + change.apply(ev.data.field.get(0), [true]); + ev.data.el.removeClass('colpick_slider').find('input').focus(); + $(document).off('mouseup', upIncrement); + $(document).off('mousemove', moveIncrement); + return false; + }, + //Hue slider functions + downHue = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var current = { + cal: $(this).parent(), + y: $(this).offset().top + }; + $(document).on('mouseup touchend',current,upHue); + $(document).on('mousemove touchmove',current,moveHue); + + var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + change.apply( + current.cal.data('colpick') + .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10)) + .get(0), + [current.cal.data('colpick').livePreview] + ); + return false; + }, + moveHue = function (ev) { + var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + change.apply( + ev.data.cal.data('colpick') + .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upHue = function (ev) { + fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + $(document).off('mouseup touchend',upHue); + $(document).off('mousemove touchmove',moveHue); + return false; + }, + //Color selector functions + downSelector = function (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + var current = { + cal: $(this).parent(), + pos: $(this).offset() + }; + current.preview = current.cal.data('colpick').livePreview; + + $(document).on('mouseup touchend',current,upSelector); + $(document).on('mousemove touchmove',current,moveSelector); + + var payeX,pageY; + if(ev.type == 'touchstart') { + pageX = ev.originalEvent.changedTouches[0].pageX, + pageY = ev.originalEvent.changedTouches[0].pageY; + } else { + pageX = ev.pageX; + pageY = ev.pageY; + } + + change.apply( + current.cal.data('colpick').fields + .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) + .get(0), + [current.preview] + ); + return false; + }, + moveSelector = function (ev) { + var payeX,pageY; + if(ev.type == 'touchmove') { + pageX = ev.originalEvent.changedTouches[0].pageX, + pageY = ev.originalEvent.changedTouches[0].pageY; + } else { + pageX = ev.pageX; + pageY = ev.pageY; + } + + change.apply( + ev.data.cal.data('colpick').fields + .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10)) + .get(0), + [ev.data.preview] + ); + return false; + }, + upSelector = function (ev) { + fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); + $(document).off('mouseup touchend',upSelector); + $(document).off('mousemove touchmove',moveSelector); + return false; + }, + //Submit button + clickSubmit = function (ev) { + var cal = $(this).parent(); + var col = cal.data('colpick').color; + cal.data('colpick').origColor = col; + setCurrentColor(col, cal.get(0)); + cal.data('colpick').onSubmit(col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el); + }, + //Show/hide the color picker + show = function (ev) { + // Prevent the trigger of any direct parent + ev.stopPropagation(); + var cal = $('#' + $(this).data('colpickId')); + cal.data('colpick').onBeforeShow.apply(this, [cal.get(0)]); + var pos = $(this).offset(); + var top = pos.top + this.offsetHeight; + var left = pos.left; + var viewPort = getViewport(); + var calW = cal.width(); + if (left + calW > viewPort.l + viewPort.w) { + left -= calW; + } + cal.css({left: left + 'px', top: top + 'px'}); + if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) { + cal.show(); + } + //Hide when user clicks outside + $('html').mousedown({cal:cal}, hide); + cal.mousedown(function(ev){ev.stopPropagation();}) + }, + hide = function (ev) { + if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) { + ev.data.cal.hide(); + } + $('html').off('mousedown', hide); + }, + getViewport = function () { + var m = document.compatMode == 'CSS1Compat'; + return { + l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), + w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth) + }; + }, + //Fix the values if the user enters a negative or high value + fixHSB = function (hsb) { + return { + h: Math.min(360, Math.max(0, hsb.h)), + s: Math.min(100, Math.max(0, hsb.s)), + b: Math.min(100, Math.max(0, hsb.b)) + }; + }, + fixRGB = function (rgb) { + return { + r: Math.min(255, Math.max(0, rgb.r)), + g: Math.min(255, Math.max(0, rgb.g)), + b: Math.min(255, Math.max(0, rgb.b)) + }; + }, + fixHex = function (hex) { + var len = 6 - hex.length; + if (len > 0) { + var o = []; + for (var i=0; i<len; i++) { + o.push('0'); + } + o.push(hex); + hex = o.join(''); + } + return hex; + }, + restoreOriginal = function () { + var cal = $(this).parent(); + var col = cal.data('colpick').origColor; + cal.data('colpick').color = col; + fillRGBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + setSelector(col, cal.get(0)); + setHue(col, cal.get(0)); + setNewColor(col, cal.get(0)); + }; + return { + init: function (opt) { + opt = $.extend({}, defaults, opt||{}); + //Set color + if (typeof opt.color == 'string') { + opt.color = hexToHsb(opt.color); + } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { + opt.color = rgbToHsb(opt.color); + } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { + opt.color = fixHSB(opt.color); + } else { + return this; + } + + //For each selected DOM element + return this.each(function () { + //If the element does not have an ID + if (!$(this).data('colpickId')) { + var options = $.extend({}, opt); + options.origColor = opt.color; + //Generate and assign a random ID + var id = 'collorpicker_' + parseInt(Math.random() * 1000); + $(this).data('colpickId', id); + //Set the tpl's ID and get the HTML + var cal = $(tpl).attr('id', id); + //Add class according to layout + cal.addClass('colpick_'+options.layout+(options.submit?'':' colpick_'+options.layout+'_ns')); + //Add class if the color scheme is not default + if(options.colorScheme != 'light') { + cal.addClass('colpick_'+options.colorScheme); + } + //Setup submit button + cal.find('div.colpick_submit').html(options.submitText).click(clickSubmit); + //Setup input fields + options.fields = cal.find('input').change(change).blur(blur).focus(focus); + cal.find('div.colpick_field_arrs').mousedown(downIncrement).end().find('div.colpick_current_color').click(restoreOriginal); + //Setup hue selector + options.selector = cal.find('div.colpick_color').on('mousedown touchstart',downSelector); + options.selectorIndic = options.selector.find('div.colpick_selector_outer'); + //Store parts of the plugin + options.el = this; + options.hue = cal.find('div.colpick_hue_arrs'); + huebar = options.hue.parent(); + //Paint the hue bar + var UA = navigator.userAgent.toLowerCase(); + var isIE = navigator.appName === 'Microsoft Internet Explorer'; + var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; + var ngIE = ( isIE && IEver < 10 ); + var stops = ['#ff0000','#ff0080','#ff00ff','#8000ff','#0000ff','#0080ff','#00ffff','#00ff80','#00ff00','#80ff00','#ffff00','#ff8000','#ff0000']; + if(ngIE) { + var i, div; + for(i=0; i<=11; i++) { + div = $('<div></div>').attr('style','height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+'); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+')";'); + huebar.append(div); + } + } else { + stopList = stops.join(','); + huebar.attr('style','background:-webkit-linear-gradient(top,'+stopList+'); background: -o-linear-gradient(top,'+stopList+'); background: -ms-linear-gradient(top,'+stopList+'); background:-moz-linear-gradient(top,'+stopList+'); -webkit-linear-gradient(top,'+stopList+'); background:linear-gradient(to bottom,'+stopList+'); '); + } + cal.find('div.colpick_hue').on('mousedown touchstart',downHue); + options.newColor = cal.find('div.colpick_new_color'); + options.currentColor = cal.find('div.colpick_current_color'); + //Store options and fill with default color + cal.data('colpick', options); + fillRGBFields(options.color, cal.get(0)); + fillHSBFields(options.color, cal.get(0)); + fillHexFields(options.color, cal.get(0)); + setHue(options.color, cal.get(0)); + setSelector(options.color, cal.get(0)); + setCurrentColor(options.color, cal.get(0)); + setNewColor(options.color, cal.get(0)); + //Append to body if flat=false, else show in place + if (options.flat) { + cal.appendTo(this).show(); + cal.css({ + position: 'relative', + display: 'block' + }); + } else { + cal.appendTo(document.body); + $(this).on(options.showEvent, show); + cal.css({ + position:'absolute' + }); + } + } + }); + }, + //Shows the picker + showPicker: function() { + return this.each( function () { + if ($(this).data('colpickId')) { + show.apply(this); + } + }); + }, + //Hides the picker + hidePicker: function() { + return this.each( function () { + if ($(this).data('colpickId')) { + $('#' + $(this).data('colpickId')).hide(); + } + }); + }, + //Sets a color as new and current (default) + setColor: function(col, setCurrent) { + setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent; + if (typeof col == 'string') { + col = hexToHsb(col); + } else if (col.r != undefined && col.g != undefined && col.b != undefined) { + col = rgbToHsb(col); + } else if (col.h != undefined && col.s != undefined && col.b != undefined) { + col = fixHSB(col); + } else { + return this; + } + return this.each(function(){ + if ($(this).data('colpickId')) { + var cal = $('#' + $(this).data('colpickId')); + cal.data('colpick').color = col; + cal.data('colpick').origColor = col; + fillRGBFields(col, cal.get(0)); + fillHSBFields(col, cal.get(0)); + fillHexFields(col, cal.get(0)); + setHue(col, cal.get(0)); + setSelector(col, cal.get(0)); + + setNewColor(col, cal.get(0)); + cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); + if(setCurrent) { + setCurrentColor(col, cal.get(0)); + } + } + }); + } + }; + }(); + //Color space convertions + var hexToRgb = function (hex) { + var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); + return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; + }; + var hexToHsb = function (hex) { + return rgbToHsb(hexToRgb(hex)); + }; + var rgbToHsb = function (rgb) { + var hsb = {h: 0, s: 0, b: 0}; + var min = Math.min(rgb.r, rgb.g, rgb.b); + var max = Math.max(rgb.r, rgb.g, rgb.b); + var delta = max - min; + hsb.b = max; + hsb.s = max != 0 ? 255 * delta / max : 0; + if (hsb.s != 0) { + if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta; + else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta; + else hsb.h = 4 + (rgb.r - rgb.g) / delta; + } else hsb.h = -1; + hsb.h *= 60; + if (hsb.h < 0) hsb.h += 360; + hsb.s *= 100/255; + hsb.b *= 100/255; + return hsb; + }; + var hsbToRgb = function (hsb) { + var rgb = {}; + var h = hsb.h; + var s = hsb.s*255/100; + var v = hsb.b*255/100; + if(s == 0) { + rgb.r = rgb.g = rgb.b = v; + } else { + var t1 = v; + var t2 = (255-s)*v/255; + var t3 = (t1-t2)*(h%60)/60; + if(h==360) h = 0; + if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} + else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} + else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} + else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} + else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} + else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} + else {rgb.r=0; rgb.g=0; rgb.b=0} + } + return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; + }; + var rgbToHex = function (rgb) { + var hex = [ + rgb.r.toString(16), + rgb.g.toString(16), + rgb.b.toString(16) + ]; + $.each(hex, function (nr, val) { + if (val.length == 1) { + hex[nr] = '0' + val; + } + }); + return hex.join(''); + }; + var hsbToHex = function (hsb) { + return rgbToHex(hsbToRgb(hsb)); + }; + $.fn.extend({ + colpick: colpick.init, + colpickHide: colpick.hidePicker, + colpickShow: colpick.showPicker, + colpickSetColor: colpick.setColor + }); + $.extend({ + colpick:{ + rgbToHex: rgbToHex, + rgbToHsb: rgbToHsb, + hsbToHex: hsbToHex, + hsbToRgb: hsbToRgb, + hexToHsb: hexToHsb, + hexToRgb: hexToRgb + } + }); +})(jQuery); diff --git a/static/plugins/echarts/echarts.min.js b/static/plugins/echarts/echarts.min.js new file mode 100755 index 0000000..9fd9bca --- /dev/null +++ b/static/plugins/echarts/echarts.min.js @@ -0,0 +1,10 @@ +!function(t,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():t.echarts=e()}(this,function(){var t,e;!function(){function i(t,e){if(!e)return t;if(0===t.indexOf(".")){var i=e.split("/"),n=t.split("/"),r=i.length-1,a=n.length,o=0,s=0;t:for(var l=0;a>l;l++)switch(n[l]){case"..":if(!(r>o))break t;o++,s++;break;case".":s++;break;default:break t}return i.length=r-o,n=n.slice(s),i.concat(n).join("/")}return t}function n(t){function e(e,o){if("string"==typeof e){var s=n[e];return s||(s=a(i(e,t)),n[e]=s),s}e instanceof Array&&(o=o||function(){},o.apply(this,r(e,o,t)))}var n={};return e}function r(e,n,r){for(var s=[],l=o[r],u=0,c=Math.min(e.length,n.length);c>u;u++){var h,d=i(e[u],r);switch(d){case"require":h=l&&l.require||t;break;case"exports":h=l.exports;break;case"module":h=l;break;default:h=a(d)}s.push(h)}return s}function a(t){var e=o[t];if(!e)throw new Error("No "+t);if(!e.defined){var i=e.factory,n=i.apply(this,r(e.deps||[],i,t));"undefined"!=typeof n&&(e.exports=n),e.defined=1}return e.exports}var o={};e=function(t,e,i){o[t]={id:t,deps:e,factory:i,defined:0,exports:{},require:n(t)}},t=n("")}();var i="moveTo",n="transform",r="category",a="dataToCoord",o="getAxis",s="dataToPoint",l="radius",u="../../util/graphic",c="dimensions",h="getItemModel",d="ordinal",f="retrieve",p="rotation",v="parent",m="inside",g="getShallow",y="stroke",x="lineWidth",_="applyTransform",b="getItemGraphicEl",w="normal",M="ecModel",T="componentIndex",S="queryComponents",C="option",A="concat",P="createElement",L="getContext",I="undefined",k="getTicks",z="getExtent",D="contain",O="opacity",R="position",E="center",B="middle",N="getBoundingRect",V="getFont",F="textAlign",G="textStyle",H="removeAll",Z="inherits",q="filter",W="number",j="function",U="isArray",X="replace",Y="zlevel",$="setStyle",Q="traverse",K="getDataParams",J="target",te="mouseout",ee="mouseover",ie="splice",ne="series",re="trigger",ae="defaults",oe="extend",se="remove",le="isObject",ue="colorStops",ce="update",he="create",de="getItemVisual",fe="dataIndex",pe="getData",ve="coordinateSystem",me="indexOf",ge="length",ye="bottom",xe="ignore",_e="eachComponent",be="storage",we="canvasSupported",Me="getHeight",Te="getWidth",Se="getModel",Ce="animation",Ae="resize",Pe="height",Le="string",Ie="prototype",ke="toLowerCase",ze="zrender/core/vector",De="zrender/core/util",Oe="zrender/core/env",Re="require";e("echarts/echarts",[Re,Oe,"./model/Global","./ExtensionAPI","./CoordinateSystem","./model/OptionManager","./model/Component","./model/Series","./view/Component","./view/Chart","./util/graphic","./util/model","./util/throttle","zrender",De,"zrender/tool/color","zrender/mixin/Eventful","zrender/core/timsort","./visual/seriesColor","./preprocessor/backwardCompat","./loading/default","./data/List","./model/Model","./util/number","./util/format","zrender/core/matrix",ze],function(t){function e(t){return function(e,i,n){e=e&&e[ke](),O[Ie][t].call(this,e,i,n)}}function i(){O.call(this)}function n(t,e,n){function r(t,e){return t.prio-e.prio}n=n||{},typeof e===Le&&(e=Ue[e]),this.id,this.group,this._dom=t;var a=this._zr=k.init(t,{renderer:n.renderer||"canvas",devicePixelRatio:n.devicePixelRatio,width:n.width,height:n[Pe]});this._throttledZrFlush=I.throttle(z.bind(a.flush,a),17),this._theme=z.clone(e),this._chartsViews=[],this._chartsMap={},this._componentsViews=[],this._componentsMap={},this._api=new b(this),this._coordSysMgr=new w,O.call(this),this._messageCenter=new i,this._initEvents(),this[Ae]=z.bind(this[Ae],this),this._pendingActions=[],R(je,r),R(qe,r),a[Ce].on("frame",this._onframe,this)}function r(t,e,i){var n,r=this._model,a=this._coordSysMgr.getCoordinateSystems();e=L.parseFinder(r,e);for(var o=0;o<a[ge];o++){var s=a[o];if(s[t]&&null!=(n=s[t](r,e,i)))return n}}function a(t,e){var i=this._model;i&&i[_e]({mainType:"series",query:e},function(n){var r=this._chartsMap[n.__viewId];r&&r.__alive&&r[t](n,i,this._api,e)},this)}function o(t,e){var i=He[t.type],n=i.actionInfo,r=n[ce]||ce;this[Ee]=!0;var a=[t],o=!1;t.batch&&(o=!0,a=z.map(t.batch,function(e){return e=z[ae](z[oe]({},e),t),e.batch=null,e}));for(var s,l=[],u="highlight"===t.type||"downplay"===t.type,c=0;c<a[ge];c++){var h=a[c];s=i.action(h,this._model),s=s||z[oe]({},h),s.type=n.event||s.type,l.push(s),u&&Fe[r].call(this,h)}"none"===r||u||(this[Ne]?(Fe.prepareAndUpdate.call(this,t),this[Ne]=!1):Fe[r].call(this,t)),s=o?{type:n.event||t.type,batch:l}:l[0],this[Ee]=!1,!e&&this._messageCenter[re](s.type,s)}function s(t){for(var e=this._pendingActions;e[ge];){var i=e.shift();o.call(this,i,t)}}function l(t,e,i){var n=this._api;E(this._componentsViews,function(r){var a=r.__model;r[t](a,e,n,i),g(a,r)},this),e.eachSeries(function(r){var a=this._chartsMap[r.__viewId];a[t](r,e,n,i),g(r,a),m(r,a)},this),v(this._zr,e)}function u(t,e){for(var i="component"===t,n=i?this._componentsViews:this._chartsViews,r=i?this._componentsMap:this._chartsMap,a=this._zr,o=0;o<n[ge];o++)n[o].__alive=!1;e[i?_e:"eachSeries"](function(t,o){if(i){if(t===ne)return}else o=t;var s=o.id+"_"+o.type,l=r[s];if(!l){var u=T.parseClassType(o.type),c=i?C.getClass(u.main,u.sub):A.getClass(u.sub);if(!c)return;l=new c,l.init(e,this._api),r[s]=l,n.push(l),a.add(l.group)}o.__viewId=s,l.__alive=!0,l.__id=s,l.__model=o},this);for(var o=0;o<n[ge];){var s=n[o];s.__alive?o++:(a[se](s.group),s.dispose(e,this._api),n[ie](o,1),delete r[s.__id])}}function c(t,e){E(qe,function(i){i.func(t,e)})}function h(t){var e={};t.eachSeries(function(t){var i=t.get("stack"),n=t[pe]();if(i&&"list"===n.type){var r=e[i];r&&(n.stackedOn=r),e[i]=n}})}function d(t,e){var i=this._api;E(je,function(n){n.isLayout&&n.func(t,i,e)})}function f(t,e){var i=this._api;t.clearColorPalette(),t.eachSeries(function(t){t.clearColorPalette()}),E(je,function(n){n.func(t,i,e)})}function p(t,e){var i=this._api;E(this._componentsViews,function(n){var r=n.__model;n.render(r,t,i,e),g(r,n)},this),E(this._chartsViews,function(t){t.__alive=!1},this),t.eachSeries(function(n){var r=this._chartsMap[n.__viewId];r.__alive=!0,r.render(n,t,i,e),r.group.silent=!!n.get("silent"),g(n,r),m(n,r)},this),v(this._zr,t),E(this._chartsViews,function(e){e.__alive||e[se](t,i)},this)}function v(t,e){var i=t[be],n=0;i[Q](function(t){t.isGroup||n++}),n>e.get("hoverLayerThreshold")&&!x.node&&i[Q](function(t){t.isGroup||(t.useHoverLayer=!0)})}function m(t,e){var i=0;e.group[Q](function(t){"group"===t.type||t[xe]||i++});var n=+t.get("progressive"),r=i>t.get("progressiveThreshold")&&n&&!x.node;r&&e.group[Q](function(t){t.isGroup||(t.progressive=r?Math.floor(i++/n):-1,r&&t.stopAnimation(!0))});var a=t.get("blendMode")||null;e.group[Q](function(t){t.isGroup||t[$]("blend",a)})}function g(t,e){var i=t.get("z"),n=t.get(Y);e.group[Q](function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=n&&(t[Y]=n))})}function y(t){function e(t,e){for(var i=0;i<t[ge];i++){var n=t[i];n[a]=e}}var i=0,n=1,r=2,a="__connectUpdateStatus";z.each(Ze,function(o,s){t._messageCenter.on(s,function(o){if($e[t.group]&&t[a]!==i){var s=t.makeActionFromEvent(o),l=[];z.each(Ye,function(e){e!==t&&e.group===t.group&&l.push(e)}),e(l,i),E(l,function(t){t[a]!==n&&t.dispatchAction(s)}),e(l,r)}})})}var x=t(Oe),_=t("./model/Global"),b=t("./ExtensionAPI"),w=t("./CoordinateSystem"),M=t("./model/OptionManager"),T=t("./model/Component"),S=t("./model/Series"),C=t("./view/Component"),A=t("./view/Chart"),P=t("./util/graphic"),L=t("./util/model"),I=t("./util/throttle"),k=t("zrender"),z=t(De),D=t("zrender/tool/color"),O=t("zrender/mixin/Eventful"),R=t("zrender/core/timsort"),E=z.each,B=1e3,N=5e3,V=1e3,F=2e3,G=3e3,H=4e3,Re=5e3,Ee="__flagInMainProcess",Be="__hasGradientOrPatternBg",Ne="__optionUpdated";i[Ie].on=e("on"),i[Ie].off=e("off"),i[Ie].one=e("one"),z.mixin(i,O);var Ve=n[Ie];Ve._onframe=function(){this[Ne]&&(this[Ee]=!0,Fe.prepareAndUpdate.call(this),this[Ee]=!1,this[Ne]=!1)},Ve.getDom=function(){return this._dom},Ve.getZr=function(){return this._zr},Ve.setOption=function(t,e,i){if(this[Ee]=!0,!this._model||e){var n=new M(this._api),r=this._theme,a=this._model=new _(null,null,r,n);a.init(null,null,r,n)}this.__lastOnlyGraphic=!(!t||!t.graphic),z.each(t,function(t,e){"graphic"!==e&&(this.__lastOnlyGraphic=!1)},this),this._model.setOption(t,We),i?this[Ne]=!0:(Fe.prepareAndUpdate.call(this),this._zr.flush(),this[Ne]=!1),this[Ee]=!1,s.call(this,!1)},Ve.setTheme=function(){console.log("ECharts#setTheme() is DEPRECATED in ECharts 3.0")},Ve[Se]=function(){return this._model},Ve.getOption=function(){return this._model&&this._model.getOption()},Ve[Te]=function(){return this._zr[Te]()},Ve[Me]=function(){return this._zr[Me]()},Ve.getRenderedCanvas=function(t){if(x[we]){t=t||{},t.pixelRatio=t.pixelRatio||1,t.backgroundColor=t.backgroundColor||this._model.get("backgroundColor");var e=this._zr,i=e[be].getDisplayList();return z.each(i,function(t){t.stopAnimation(!0)}),e.painter.getRenderedCanvas(t)}},Ve.getDataURL=function(t){t=t||{};var e=t.excludeComponents,i=this._model,n=[],r=this;E(e,function(t){i[_e]({mainType:t},function(t){var e=r._componentsMap[t.__viewId];e.group[xe]||(n.push(e),e.group[xe]=!0)})});var a=this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return E(n,function(t){t.group[xe]=!1}),a},Ve.getConnectedDataURL=function(t){if(x[we]){var e=this.group,i=Math.min,n=Math.max,r=1/0;if($e[e]){var a=r,o=r,s=-r,l=-r,u=[],c=t&&t.pixelRatio||1;z.each(Ye,function(r){if(r.group===e){var c=r.getRenderedCanvas(z.clone(t)),h=r.getDom().getBoundingClientRect();a=i(h.left,a),o=i(h.top,o),s=n(h.right,s),l=n(h[ye],l),u.push({dom:c,left:h.left,top:h.top})}}),a*=c,o*=c,s*=c,l*=c;var h=s-a,d=l-o,f=z.createCanvas();f.width=h,f[Pe]=d;var p=k.init(f);return E(u,function(t){var e=new P.Image({style:{x:t.left*c-a,y:t.top*c-o,image:t.dom}});p.add(e)}),p.refreshImmediately(),f.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}},Ve.convertToPixel=z.curry(r,"convertToPixel"),Ve.convertFromPixel=z.curry(r,"convertFromPixel"),Ve.containPixel=function(t,e){var i,n=this._model;return t=L.parseFinder(n,t),z.each(t,function(t,n){n[me]("Models")>=0&&z.each(t,function(t){var r=t[ve];if(r&&r.containPoint)i|=!!r.containPoint(e);else if("seriesModels"===n){var a=this._chartsMap[t.__viewId];a&&a.containPoint&&(i|=a.containPoint(e,t))}},this)},this),!!i},Ve.getVisual=function(t,e){var i=this._model;t=L.parseFinder(i,t,{defaultMainType:"series"});var n=t.seriesModel,r=n[pe](),a=t.hasOwnProperty("dataIndexInside")?t.dataIndexInside:t.hasOwnProperty(fe)?r.indexOfRawIndex(t[fe]):null;return null!=a?r[de](a,e):r.getVisual(e)};var Fe={update:function(t){var e=this._model,i=this._api,n=this._coordSysMgr,r=this._zr;if(e){e.restoreData(),n[he](this._model,this._api),c.call(this,e,i),h.call(this,e),n[ce](e,i),f.call(this,e,t),p.call(this,e,t);var a=e.get("backgroundColor")||"transparent",o=r.painter;if(o.isSingleCanvas&&o.isSingleCanvas())r.configLayer(0,{clearColor:a});else{if(!x[we]){var s=D.parse(a);a=D.stringify(s,"rgb"),0===s[3]&&(a="transparent")}a[ue]||a.image?(r.configLayer(0,{clearColor:a}),this[Be]=!0,this._dom.style.background="transparent"):(this[Be]&&r.configLayer(0,{clearColor:null}),this[Be]=!1,this._dom.style.background=a)}}},updateView:function(t){var e=this._model;e&&(e.eachSeries(function(t){t[pe]().clearAllVisual()}),f.call(this,e,t),l.call(this,"updateView",e,t))},updateVisual:function(t){var e=this._model;e&&(e.eachSeries(function(t){t[pe]().clearAllVisual()}),f.call(this,e,t),l.call(this,"updateVisual",e,t))},updateLayout:function(t){var e=this._model;e&&(d.call(this,e,t),l.call(this,"updateLayout",e,t))},highlight:function(t){a.call(this,"highlight",t)},downplay:function(t){a.call(this,"downplay",t)},prepareAndUpdate:function(t){var e=this._model;u.call(this,"component",e),u.call(this,"chart",e),this.__lastOnlyGraphic?(E(this._componentsViews,function(i){var n=i.__model;n&&"graphic"===n.mainType&&(i.render(n,e,this._api,t),g(n,i))},this),this.__lastOnlyGraphic=!1):Fe[ce].call(this,t)}};Ve[Ae]=function(t){this[Ee]=!0,this._zr[Ae](t);var e=this._model&&this._model.resetOption("media");Fe[e?"prepareAndUpdate":ce].call(this),this._loadingFX&&this._loadingFX[Ae](),this[Ee]=!1,s.call(this)},Ve.showLoading=function(t,e){if(z[le](t)&&(e=t,t=""),t=t||"default",this.hideLoading(),Xe[t]){var i=Xe[t](this._api,e),n=this._zr;this._loadingFX=i,n.add(i)}},Ve.hideLoading=function(){this._loadingFX&&this._zr[se](this._loadingFX),this._loadingFX=null},Ve.makeActionFromEvent=function(t){var e=z[oe]({},t);return e.type=Ze[t.type],e},Ve.dispatchAction=function(t,e){if(z[le](e)||(e={silent:!!e}),He[t.type]){if(this[Ee])return void this._pendingActions.push(t);o.call(this,t,e.silent),e.flush?this._zr.flush(!0):e.flush!==!1&&x.browser.weChat&&this._throttledZrFlush(),s.call(this,e.silent)}},Ve.on=e("on"),Ve.off=e("off"),Ve.one=e("one");var Ge=["click","dblclick",ee,te,"mousemove","mousedown","mouseup","globalout","contextmenu"];Ve._initEvents=function(){E(Ge,function(t){this._zr.on(t,function(e){var i,n=this[Se](),r=e[J];if("globalout"===t)i={};else if(r&&null!=r[fe]){var a=r.dataModel||n.getSeriesByIndex(r.seriesIndex);i=a&&a[K](r[fe],r.dataType)||{}}else r&&r.eventData&&(i=z[oe]({},r.eventData));i&&(i.event=e,i.type=t,this[re](t,i))},this)},this),E(Ze,function(t,e){this._messageCenter.on(e,function(t){this[re](e,t)},this)},this)},Ve.isDisposed=function(){return this._disposed},Ve.clear=function(){this.setOption({series:[]},!0)},Ve.dispose=function(){if(!this._disposed){this._disposed=!0;var t=this._api,e=this._model;E(this._componentsViews,function(i){i.dispose(e,t)}),E(this._chartsViews,function(i){i.dispose(e,t)}),this._zr.dispose(),delete Ye[this.id]}},z.mixin(n,O);var He=[],Ze={},qe=[],We=[],je=[],Ue={},Xe={},Ye={},$e={},Qe=new Date-0,Ke=new Date-0,Je="_echarts_instance_",ti={version:"3.3.2",dependencies:{zrender:"3.2.2"}};ti.init=function(t,e,i){var r=new n(t,e,i);return r.id="ec_"+Qe++,Ye[r.id]=r,t.setAttribute&&t.setAttribute(Je,r.id),y(r),r},ti.connect=function(t){if(z[U](t)){var e=t;t=null,z.each(e,function(e){null!=e.group&&(t=e.group)}),t=t||"g_"+Ke++,z.each(e,function(e){e.group=t})}return $e[t]=!0,t},ti.disConnect=function(t){$e[t]=!1},ti.dispose=function(t){z.isDom(t)?t=ti.getInstanceByDom(t):typeof t===Le&&(t=Ye[t]),t instanceof n&&!t.isDisposed()&&t.dispose()},ti.getInstanceByDom=function(t){var e=t.getAttribute(Je);return Ye[e]},ti.getInstanceById=function(t){return Ye[t]},ti.registerTheme=function(t,e){Ue[t]=e},ti.registerPreprocessor=function(t){We.push(t)},ti.registerProcessor=function(t,e){typeof t===j&&(e=t,t=B),qe.push({prio:t,func:e})},ti.registerAction=function(t,e,i){typeof e===j&&(i=e,e="");var n=z[le](t)?t.type:[t,t={event:e}][0];t.event=(t.event||n)[ke](),e=t.event,He[n]||(He[n]={action:i,actionInfo:t}),Ze[e]=n},ti.registerCoordinateSystem=function(t,e){w.register(t,e)},ti.registerLayout=function(t,e){typeof t===j&&(e=t,t=V),je.push({prio:t,func:e,isLayout:!0})},ti.registerVisual=function(t,e){typeof t===j&&(e=t,t=G),je.push({prio:t,func:e})},ti.registerLoading=function(t,e){Xe[t]=e};var ei=T.parseClassType;return ti.extendComponentModel=function(t,e){var i=T;if(e){var n=ei(e);i=T.getClass(n.main,n.sub,!0)}return i[oe](t)},ti.extendComponentView=function(t,e){var i=C;if(e){var n=ei(e);i=C.getClass(n.main,n.sub,!0)}return i[oe](t)},ti.extendSeriesModel=function(t,e){var i=S;if(e){e="series."+e[X]("series.","");var n=ei(e);i=T.getClass(n.main,n.sub,!0)}return i[oe](t)},ti.extendChartView=function(t,e){var i=A;if(e){e[X]("series.","");var n=ei(e);i=A.getClass(n.main,!0)}return i[oe](t)},ti.setCanvasCreator=function(t){z.createCanvas=t},ti.registerVisual(F,t("./visual/seriesColor")),ti.registerPreprocessor(t("./preprocessor/backwardCompat")),ti.registerLoading("default",t("./loading/default")),ti.registerAction({type:"highlight",event:"highlight",update:"highlight"},z.noop),ti.registerAction({type:"downplay",event:"downplay",update:"downplay"},z.noop),ti.List=t("./data/List"),ti.Model=t("./model/Model"),ti.graphic=t("./util/graphic"),ti[W]=t("./util/number"),ti.format=t("./util/format"),ti.matrix=t("zrender/core/matrix"),ti.vector=t(ze),ti.color=t("zrender/tool/color"),ti.util={},E(["map","each",q,me,Z,"reduce",q,"bind","curry",U,"isString",le,"isFunction",oe,ae,"clone"],function(t){ti.util[t]=z[t]}),ti.PRIORITY={PROCESSOR:{FILTER:B,STATISTIC:N},VISUAL:{LAYOUT:V,GLOBAL:F,CHART:G,COMPONENT:H,BRUSH:Re}},ti}),e("echarts/chart/line",[Re,De,"../echarts","./line/LineSeries","./line/LineView","../visual/symbol","../layout/points","../processor/dataSample","../component/grid"],function(t){var e=t(De),i=t("../echarts"),n=i.PRIORITY;t("./line/LineSeries"),t("./line/LineView"),i.registerVisual(e.curry(t("../visual/symbol"),"line","circle","line")),i.registerLayout(e.curry(t("../layout/points"),"line")),i.registerProcessor(n.PROCESSOR.STATISTIC,e.curry(t("../processor/dataSample"),"line")),t("../component/grid")}),e("echarts/chart/bar",[Re,De,"../coord/cartesian/Grid","./bar/BarSeries","./bar/BarView","../layout/barGrid","../echarts","../component/grid"],function(t){var e=t(De);t("../coord/cartesian/Grid"),t("./bar/BarSeries"),t("./bar/BarView");var i=t("../layout/barGrid"),n=t("../echarts");n.registerLayout(e.curry(i,"bar")),n.registerVisual(function(t){t.eachSeriesByType("bar",function(t){var e=t[pe]();e.setVisual("legendSymbol","roundRect")})}),t("../component/grid")}),e("echarts/chart/pie",[Re,De,"../echarts","./pie/PieSeries","./pie/PieView","../action/createDataSelectAction","../visual/dataColor","./pie/pieLayout","../processor/dataFilter"],function(t){var e=t(De),i=t("../echarts");t("./pie/PieSeries"),t("./pie/PieView"),t("../action/createDataSelectAction")("pie",[{type:"pieToggleSelect",event:"pieselectchanged",method:"toggleSelected"},{type:"pieSelect",event:"pieselected",method:"select"},{type:"pieUnSelect",event:"pieunselected",method:"unSelect"}]),i.registerVisual(e.curry(t("../visual/dataColor"),"pie")),i.registerLayout(e.curry(t("./pie/pieLayout"),"pie")),i.registerProcessor(e.curry(t("../processor/dataFilter"),"pie"))}),e("echarts/component/grid",[Re,"../util/graphic",De,"../echarts","../coord/cartesian/Grid","./axis"],function(t){var e=t("../util/graphic"),i=t(De),n=t("../echarts");t("../coord/cartesian/Grid"),t("./axis"),n.extendComponentView({type:"grid",render:function(t){this.group[H](),t.get("show")&&this.group.add(new e.Rect({shape:t[ve].getRect(),style:i[ae]({fill:t.get("backgroundColor")},t.getItemStyle()),silent:!0,z2:-1}))}}),n.registerPreprocessor(function(t){t.xAxis&&t.yAxis&&!t.grid&&(t.grid={})})}),e("echarts/component/legend",[Re,"./legend/LegendModel","./legend/legendAction","./legend/LegendView","../echarts","./legend/legendFilter"],function(t){t("./legend/LegendModel"),t("./legend/legendAction"),t("./legend/LegendView");var e=t("../echarts");e.registerProcessor(t("./legend/legendFilter"))}),e("echarts/component/title",[Re,"../echarts","../util/graphic","../util/layout"],function(t){var e=t("../echarts"),i=t("../util/graphic"),n=t("../util/layout");e.extendComponentModel({type:"title",layoutMode:{type:"box",ignoreSize:!0},defaultOption:{zlevel:0,z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bolder",color:"#333"},subtextStyle:{color:"#aaa"}}}),e.extendComponentView({type:"title",render:function(t,e,r){if(this.group[H](),t.get("show")){var a=this.group,o=t[Se](G),s=t[Se]("subtextStyle"),l=t.get(F),u=t.get("textBaseline"),c=new i.Text({style:{text:t.get("text"),textFont:o[V](),fill:o.getTextColor()},z2:10}),h=c[N](),d=t.get("subtext"),f=new i.Text({style:{text:d,textFont:s[V](),fill:s.getTextColor(),y:h[Pe]+t.get("itemGap"),textBaseline:"top"},z2:10}),p=t.get("link"),v=t.get("sublink");c.silent=!p,f.silent=!v,p&&c.on("click",function(){window.open(p,"_"+t.get(J))}),v&&f.on("click",function(){window.open(v,"_"+t.get("subtarget"))}),a.add(c),d&&a.add(f);var m=a[N](),g=t.getBoxLayoutParams();g.width=m.width,g[Pe]=m[Pe];var y=n.getLayoutRect(g,{width:r[Te](),height:r[Me]()},t.get("padding"));l||(l=t.get("left")||t.get("right"),l===B&&(l=E),"right"===l?y.x+=y.width:l===E&&(y.x+=y.width/2)),u||(u=t.get("top")||t.get(ye),u===E&&(u=B),u===ye?y.y+=y[Pe]:u===B&&(y.y+=y[Pe]/2),u=u||"top"),a.attr(R,[y.x,y.y]);var x={textAlign:l,textVerticalAlign:u};c[$](x),f[$](x),m=a[N]();var _=y.margin,b=t.getItemStyle(["color",O]);b.fill=t.get("backgroundColor");var w=new i.Rect({shape:{x:m.x-_[3],y:m.y-_[0],width:m.width+_[1]+_[3],height:m[Pe]+_[0]+_[2]},style:b,silent:!0});i.subPixelOptimizeRect(w),a.add(w)}}})}),e("zrender/vml/vml",[Re,"./graphic","../zrender","./Painter"],function(t){t("./graphic"),t("../zrender").registerPainter("vml",t("./Painter"))}),e("echarts/component/tooltip",[Re,"./tooltip/TooltipModel","./tooltip/TooltipView","../echarts"],function(t){t("./tooltip/TooltipModel"),t("./tooltip/TooltipView"),t("../echarts").registerAction({type:"showTip",event:"showTip",update:"none"},function(){}),t("../echarts").registerAction({type:"hideTip",event:"hideTip",update:"none"},function(){})}),e("echarts/component/toolbox",[Re,"./toolbox/ToolboxModel","./toolbox/ToolboxView","./toolbox/feature/SaveAsImage","./toolbox/feature/MagicType","./toolbox/feature/DataView","./toolbox/feature/DataZoom","./toolbox/feature/Restore"],function(t){t("./toolbox/ToolboxModel"),t("./toolbox/ToolboxView"),t("./toolbox/feature/SaveAsImage"),t("./toolbox/feature/MagicType"),t("./toolbox/feature/DataView"),t("./toolbox/feature/DataZoom"),t("./toolbox/feature/Restore")}),e("echarts/scale/Time",[Re,De,"../util/number","../util/format","./Interval"],function(t){var e=t(De),i=t("../util/number"),n=t("../util/format"),r=t("./Interval"),a=r[Ie],o=Math.ceil,s=Math.floor,l=1e3,u=60*l,c=60*u,h=24*c,d=function(t,e,i,n){for(;n>i;){var r=i+n>>>1;t[r][2]<e?i=r+1:n=r}return i},f=r[oe]({type:"time",getLabel:function(t){var e=this._stepLvl,i=new Date(t);return n.formatTime(e[0],i)},niceExtent:function(t,e,n){var r=this._extent;if(r[0]===r[1]&&(r[0]-=h,r[1]+=h),r[1]===-1/0&&1/0===r[0]){var a=new Date;r[1]=new Date(a.getFullYear(),a.getMonth(),a.getDate()),r[0]=r[1]-h}this.niceTicks(t);var l=this._interval;e||(r[0]=i.round(s(r[0]/l)*l)),n||(r[1]=i.round(o(r[1]/l)*l))},niceTicks:function(t){t=t||10;var e=this._extent,n=e[1]-e[0],r=n/t,a=p[ge],l=d(p,r,0,a),u=p[Math.min(l,a-1)],c=u[2];if("year"===u[0]){var h=n/c,f=i.nice(h/t,!0);c*=f}var v=[o(e[0]/c)*c,s(e[1]/c)*c];this._stepLvl=u,this._interval=c,this._niceExtent=v},parse:function(t){return+i.parseDate(t)}});e.each([D,"normalize"],function(t){f[Ie][t]=function(e){return a[t].call(this,this.parse(e))}});var p=[["hh:mm:ss",1,l],["hh:mm:ss",5,5*l],["hh:mm:ss",10,10*l],["hh:mm:ss",15,15*l],["hh:mm:ss",30,30*l],["hh:mm\nMM-dd",1,u],["hh:mm\nMM-dd",5,5*u],["hh:mm\nMM-dd",10,10*u],["hh:mm\nMM-dd",15,15*u],["hh:mm\nMM-dd",30,30*u],["hh:mm\nMM-dd",1,c],["hh:mm\nMM-dd",2,2*c],["hh:mm\nMM-dd",6,6*c],["hh:mm\nMM-dd",12,12*c],["MM-dd\nyyyy",1,h],["week",7,7*h],["month",1,31*h],["quarter",3,380*h/4],["half-year",6,380*h/2],["year",1,380*h]];return f[he]=function(){return new f},f}),e("echarts/scale/Log",[Re,De,"./Scale","../util/number","./Interval"],function(t){function e(t,e){return u(t,l(e))}var i=t(De),n=t("./Scale"),r=t("../util/number"),a=t("./Interval"),o=n[Ie],s=a[Ie],l=r.getPrecisionSafe,u=r.round,c=Math.floor,h=Math.ceil,d=Math.pow,f=Math.log,p=n[oe]({type:"log",base:10,$constructor:function(){n.apply(this,arguments),this._originalScale=new a},getTicks:function(){var t=this._originalScale,n=this._extent,a=t[z]();return i.map(s[k].call(this),function(i){var o=r.round(d(this.base,i));return o=i===n[0]&&t.__fixMin?e(o,a[0]):o,o=i===n[1]&&t.__fixMax?e(o,a[1]):o},this)},getLabel:s.getLabel,scale:function(t){return t=o.scale.call(this,t),d(this.base,t)},setExtent:function(t,e){var i=this.base;t=f(t)/f(i),e=f(e)/f(i),s.setExtent.call(this,t,e)},getExtent:function(){var t=this.base,i=o[z].call(this);i[0]=d(t,i[0]),i[1]=d(t,i[1]);var n=this._originalScale,r=n[z]();return n.__fixMin&&(i[0]=e(i[0],r[0])),n.__fixMax&&(i[1]=e(i[1],r[1])),i},unionExtent:function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=f(t[0])/f(e),t[1]=f(t[1])/f(e),o.unionExtent.call(this,t)},niceTicks:function(t){t=t||10;var e=this._extent,i=e[1]-e[0];if(!(1/0===i||0>=i)){var n=r.quantity(i),a=t/i*n;for(.5>=a&&(n*=10);!isNaN(n)&&Math.abs(n)<1&&Math.abs(n)>0;)n*=10;var o=[r.round(h(e[0]/n)*n),r.round(c(e[1]/n)*n)];this._interval=n,this._niceExtent=o}},niceExtent:function(t,e,i){s.niceExtent.call(this,t,e,i);var n=this._originalScale;n.__fixMin=e,n.__fixMax=i}});return i.each([D,"normalize"],function(t){p[Ie][t]=function(e){return e=f(e)/f(this.base),o[t].call(this,e)}}),p[he]=function(){return new p},p}),e(Oe,[],function(){function t(t){var e={},i={},n=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),a=t.match(/Edge\/([\d.]+)/),o=/micromessenger/i.test(t);return n&&(i.firefox=!0,i.version=n[1]),r&&(i.ie=!0,i.version=r[1]),a&&(i.edge=!0,i.version=a[1]),o&&(i.weChat=!0),{browser:i,os:e,node:!1,canvasSupported:document[P]("canvas")[L]?!0:!1,touchEventsSupported:"ontouchstart"in window&&!i.ie&&!i.edge,pointerEventsSupported:"onpointerdown"in window&&(i.edge||i.ie&&i.version>=10)}}var e={};return e=typeof navigator===I?{browser:{},os:{},node:!0,canvasSupported:!0}:t(navigator.userAgent)}),e("echarts/CoordinateSystem",[Re,De],function(t){function e(){this._coordinateSystems=[]}var i=t(De),n={};return e[Ie]={constructor:e,create:function(t,e){var r=[];i.each(n,function(i){var n=i[he](t,e);r=r[A](n||[])}),this._coordinateSystems=r},update:function(t,e){i.each(this._coordinateSystems,function(i){i[ce]&&i[ce](t,e)})},getCoordinateSystems:function(){return this._coordinateSystems.slice()}},e.register=function(t,e){n[t]=e},e.get=function(t){return n[t]},e}),e("echarts/ExtensionAPI",[Re,De],function(t){function e(t){i.each(n,function(e){this[e]=i.bind(t[e],t)},this)}var i=t(De),n=["getDom","getZr",Te,Me,"dispatchAction","isDisposed","on","off","getDataURL","getConnectedDataURL",Se,"getOption"];return e}),e("echarts/model/Global",[Re,De,"../util/model","./Model","./Component","./globalDefault","./mixin/colorPalette"],function(t){function e(t,e){l.each(e,function(e,i){g.hasClass(i)||("object"==typeof e?t[i]=t[i]?l.merge(t[i],e,!1):l.clone(e):null==t[i]&&(t[i]=e))})}function i(t){t=t,this[C]={},this[C][x]=1,this._componentsMap={},this._seriesIndices=null,e(t,this._theme[C]),l.merge(t,y,!1),this.mergeOption(t)}function n(t,e){l[U](e)||(e=e?[e]:[]);var i={};return h(e,function(e){i[e]=(t[e]||[]).slice()}),i}function r(t,e,i){var n=e.type?e.type:i?i.subType:g.determineSubType(t,e);return n}function a(t){return f(t,function(t){return t[T]})||[]}function o(t,e){return e.hasOwnProperty("subType")?d(t,function(t){return t.subType===e.subType}):t}function s(t){}var l=t(De),u=t("../util/model"),c=t("./Model"),h=l.each,d=l[q],f=l.map,p=l[U],v=l[me],m=l[le],g=t("./Component"),y=t("./globalDefault"),x="\x00_ec_inner",_=c[oe]({constructor:_,init:function(t,e,i,n){i=i||{},this[C]=null,this._theme=new c(i),this._optionManager=n},setOption:function(t,e){l.assert(!(x in t),"please use chart.getOption()"),this._optionManager.setOption(t,e),this.resetOption()},resetOption:function(t){var e=!1,n=this._optionManager;if(!t||"recreate"===t){var r=n.mountOption("recreate"===t);this[C]&&"recreate"!==t?(this.restoreData(),this.mergeOption(r)):i.call(this,r),e=!0}if(("timeline"===t||"media"===t)&&this.restoreData(),!t||"recreate"===t||"timeline"===t){var a=n.getTimelineOption(this);a&&(this.mergeOption(a),e=!0)}if(!t||"recreate"===t||"media"===t){var o=n.getMediaOption(this,this._api);o[ge]&&h(o,function(t){this.mergeOption(t,e=!0)},this)}return e},mergeOption:function(t){function e(e,s){var c=u.normalizeToArray(t[e]),d=u.mappingToExists(o[e],c);u.makeIdAndName(d),h(d,function(t){var i=t[C];m(i)&&(t.keyInfo.mainType=e,t.keyInfo.subType=r(e,i,t.exist))});var f=n(o,s);i[e]=[],o[e]=[],h(d,function(t,n){var r=t.exist,a=t[C];if(l.assert(m(a)||r,"Empty component definition"),a){var s=g.getClass(e,t.keyInfo.subType,!0);if(r&&r instanceof s)r.name=t.keyInfo.name,r.mergeOption(a,this),r.optionUpdated(a,!1);else{var u=l[oe]({dependentModels:f,componentIndex:n},t.keyInfo);r=new s(a,this,this,u),l[oe](r,u),r.init(a,this,this,u),r.optionUpdated(null,!0)}}else r.mergeOption({},this),r.optionUpdated({},!1);o[e][n]=r,i[e][n]=r[C]},this),e===ne&&(this._seriesIndices=a(o[ne]))}var i=this[C],o=this._componentsMap,s=[];h(t,function(t,e){null!=t&&(g.hasClass(e)?s.push(e):i[e]=null==i[e]?l.clone(t):l.merge(i[e],t,!0))}),g.topologicalTravel(s,g.getAllClassMainTypes(),e,this),this._seriesIndices=this._seriesIndices||[]},getOption:function(){var t=l.clone(this[C]);return h(t,function(e,i){if(g.hasClass(i)){for(var e=u.normalizeToArray(e),n=e[ge]-1;n>=0;n--)u.isIdInner(e[n])&&e[ie](n,1);t[i]=e}}),delete t[x],t},getTheme:function(){return this._theme},getComponent:function(t,e){var i=this._componentsMap[t];return i?i[e||0]:void 0},queryComponents:function(t){var e=t.mainType;if(!e)return[];var i=t.index,n=t.id,r=t.name,a=this._componentsMap[e];if(!a||!a[ge])return[];var s;if(null!=i)p(i)||(i=[i]),s=d(f(i,function(t){return a[t]}),function(t){return!!t});else if(null!=n){var l=p(n);s=d(a,function(t){return l&&v(n,t.id)>=0||!l&&t.id===n})}else if(null!=r){var u=p(r);s=d(a,function(t){return u&&v(r,t.name)>=0||!u&&t.name===r})}else s=a;return o(s,t)},findComponents:function(t){function e(t){var e=r+"Index",i=r+"Id",n=r+"Name";return t&&(t.hasOwnProperty(e)||t.hasOwnProperty(i)||t.hasOwnProperty(n))?{mainType:r,index:t[e],id:t[i],name:t[n]}:null}function i(e){return t[q]?d(e,t[q]):e}var n=t.query,r=t.mainType,a=e(n),s=a?this[S](a):this._componentsMap[r];return i(o(s,t))},eachComponent:function(t,e,i){var n=this._componentsMap;if(typeof t===j)i=e,e=t,h(n,function(t,n){h(t,function(t,r){e.call(i,n,t,r)})});else if(l.isString(t))h(n[t],e,i);else if(m(t)){var r=this.findComponents(t);h(r,e,i)}},getSeriesByName:function(t){var e=this._componentsMap[ne];return d(e,function(e){return e.name===t})},getSeriesByIndex:function(t){return this._componentsMap[ne][t]},getSeriesByType:function(t){var e=this._componentsMap[ne];return d(e,function(e){return e.subType===t})},getSeries:function(){return this._componentsMap[ne].slice()},eachSeries:function(t,e){s(this),h(this._seriesIndices,function(i){var n=this._componentsMap[ne][i];t.call(e,n,i)},this)},eachRawSeries:function(t,e){h(this._componentsMap[ne],t,e)},eachSeriesByType:function(t,e,i){s(this),h(this._seriesIndices,function(n){var r=this._componentsMap[ne][n];r.subType===t&&e.call(i,r,n)},this)},eachRawSeriesByType:function(t,e,i){return h(this.getSeriesByType(t),e,i)},isSeriesFiltered:function(t){return s(this),l[me](this._seriesIndices,t[T])<0},filterSeries:function(t,e){s(this);var i=d(this._componentsMap[ne],t,e);this._seriesIndices=a(i)},restoreData:function(){var t=this._componentsMap;this._seriesIndices=a(t[ne]);var e=[];h(t,function(t,i){e.push(i)}),g.topologicalTravel(e,g.getAllClassMainTypes(),function(e){h(t[e],function(t){t.restoreData()})})}});return l.mixin(_,t("./mixin/colorPalette")),_}),e("echarts/model/Component",[Re,"./Model",De,"../util/component","../util/clazz","../util/layout","./mixin/boxLayout"],function(t){function e(t){var e=[];return n.each(l.getClassesByMainType(t),function(t){r.apply(e,t[Ie].dependencies||[])}),n.map(e,function(t){return o.parseClassType(t).main})}var i=t("./Model"),n=t(De),r=Array[Ie].push,a=t("../util/component"),o=t("../util/clazz"),s=t("../util/layout"),l=i[oe]({type:"component",id:"",name:"",mainType:"",subType:"",componentIndex:0,defaultOption:null,ecModel:null,dependentModels:[],uid:null,layoutMode:null,$constructor:function(t,e,n,r){i.call(this,t,e,n,r),this.uid=a.getUID("componentModel")},init:function(t,e,i){this.mergeDefaultAndTheme(t,i)},mergeDefaultAndTheme:function(t,e){var i=this.layoutMode,r=i?s.getLayoutParams(t):{},a=e.getTheme(); +n.merge(t,a.get(this.mainType)),n.merge(t,this.getDefaultOption()),i&&s.mergeLayoutParam(t,r,i)},mergeOption:function(t){n.merge(this[C],t,!0);var e=this.layoutMode;e&&s.mergeLayoutParam(this[C],t,e)},optionUpdated:function(){},getDefaultOption:function(){if(!this.hasOwnProperty("__defaultOption")){for(var t=[],e=this.constructor;e;){var i=e[Ie].defaultOption;i&&t.push(i),e=e.superClass}for(var r={},a=t[ge]-1;a>=0;a--)r=n.merge(r,t[a],!0);this.__defaultOption=r}return this.__defaultOption},getReferringComponents:function(t){return this[M][S]({mainType:t,index:this.get(t+"Index",!0),id:this.get(t+"Id",!0)})}});return o.enableClassManagement(l,{registerWhenExtend:!0}),a.enableSubTypeDefaulter(l),a.enableTopologicalTravel(l,e),n.mixin(l,t("./mixin/boxLayout")),l}),e("echarts/model/OptionManager",[Re,De,"../util/model","./Component"],function(t){function e(t){this._api=t,this._timelineOptions=[],this._mediaList=[],this._mediaDefault,this._currentMediaIndices=[],this._optionBackup,this._newBaseOption}function i(t,e,i){var n,r,a=[],o=[],l=t.timeline;if(t.baseOption&&(r=t.baseOption),(l||t.options)&&(r=r||{},a=(t.options||[]).slice()),t.media){r=r||{};var u=t.media;c(u,function(t){t&&t[C]&&(t.query?o.push(t):n||(n=t))})}return r||(r=t),r.timeline||(r.timeline=l),c([r][A](a)[A](s.map(o,function(t){return t[C]})),function(t){c(e,function(e){e(t,i)})}),{baseOption:r,timelineOptions:a,mediaDefault:n,mediaList:o}}function n(t,e,i){var n={width:e,height:i,aspectratio:e/i},a=!0;return s.each(t,function(t,e){var i=e.match(p);if(i&&i[1]&&i[2]){var o=i[1],s=i[2][ke]();r(n[s],t,o)||(a=!1)}}),a}function r(t,e,i){return"min"===i?t>=e:"max"===i?e>=t:t===e}function a(t,e){return t.join(",")===e.join(",")}function o(t,e){e=e||{},c(e,function(e,i){if(null!=e){var n=t[i];if(u.hasClass(i)){e=l.normalizeToArray(e),n=l.normalizeToArray(n);var r=l.mappingToExists(n,e);t[i]=d(r,function(t){return t[C]&&t.exist?f(t.exist,t[C],!0):t.exist||t[C]})}else t[i]=f(n,e,!0)}})}var s=t(De),l=t("../util/model"),u=t("./Component"),c=s.each,h=s.clone,d=s.map,f=s.merge,p=/^(min|max)?(.+)$/;return e[Ie]={constructor:e,setOption:function(t,e){t=h(t,!0);var n=this._optionBackup,r=i.call(this,t,e,!n);this._newBaseOption=r.baseOption,n?(o(n.baseOption,r.baseOption),r.timelineOptions[ge]&&(n.timelineOptions=r.timelineOptions),r.mediaList[ge]&&(n.mediaList=r.mediaList),r.mediaDefault&&(n.mediaDefault=r.mediaDefault)):this._optionBackup=r},mountOption:function(t){var e=this._optionBackup;return this._timelineOptions=d(e.timelineOptions,h),this._mediaList=d(e.mediaList,h),this._mediaDefault=h(e.mediaDefault),this._currentMediaIndices=[],h(t?e.baseOption:this._newBaseOption)},getTimelineOption:function(t){var e,i=this._timelineOptions;if(i[ge]){var n=t.getComponent("timeline");n&&(e=h(i[n.getCurrentIndex()],!0))}return e},getMediaOption:function(){var t=this._api[Te](),e=this._api[Me](),i=this._mediaList,r=this._mediaDefault,o=[],s=[];if(!i[ge]&&!r)return s;for(var l=0,u=i[ge];u>l;l++)n(i[l].query,t,e)&&o.push(l);return!o[ge]&&r&&(o=[-1]),o[ge]&&!a(o,this._currentMediaIndices)&&(s=d(o,function(t){return h(-1===t?r[C]:i[t][C])})),this._currentMediaIndices=o,s}},e}),e("echarts/view/Component",[Re,"zrender/container/Group","../util/component","../util/clazz"],function(t){var e=t("zrender/container/Group"),i=t("../util/component"),n=t("../util/clazz"),r=function(){this.group=new e,this.uid=i.getUID("viewComponent")};r[Ie]={constructor:r,init:function(){},render:function(){},dispose:function(){}};var a=r[Ie];return a.updateView=a.updateLayout=a.updateVisual=function(){},n.enableClassExtend(r),n.enableClassManagement(r,{registerWhenExtend:!0}),r}),e("echarts/view/Chart",[Re,"zrender/container/Group","../util/component","../util/clazz","../util/model",De],function(t){function e(){this.group=new r,this.uid=a.getUID("viewChart")}function i(t,e){if(t&&(t[re](e),"group"===t.type))for(var n=0;n<t.childCount();n++)i(t.childAt(n),e)}function n(t,e,n){var r=s.queryDataIndex(t,e);null!=r?l.each(s.normalizeToArray(r),function(e){i(t[b](e),n)}):t.eachItemGraphicEl(function(t){i(t,n)})}var r=t("zrender/container/Group"),a=t("../util/component"),o=t("../util/clazz"),s=t("../util/model"),l=t(De);e[Ie]={type:"chart",init:function(){},render:function(){},highlight:function(t,e,i,r){n(t[pe](),r,"emphasis")},downplay:function(t,e,i,r){n(t[pe](),r,w)},remove:function(){this.group[H]()},dispose:function(){}};var u=e[Ie];return u.updateView=u.updateLayout=u.updateVisual=function(t,e,i,n){this.render(t,e,i,n)},o.enableClassExtend(e,["dispose"]),o.enableClassManagement(e,{registerWhenExtend:!0}),e}),e("echarts/util/throttle",[],function(){var t={},e="\x00__throttleOriginMethod",i="\x00__throttleRate",n="\x00__throttleType";return t.throttle=function(t,e,i){function n(){u=(new Date).getTime(),c=null,t.apply(o,s||[])}var r,a,o,s,l=0,u=0,c=null;e=e||0;var h=function(){r=(new Date).getTime(),o=this,s=arguments,a=r-(i?l:u)-e,clearTimeout(c),i?c=setTimeout(n,e):a>=0?n():c=setTimeout(n,-a),l=r};return h.clear=function(){c&&(clearTimeout(c),c=null)},h},t.createOrUpdate=function(r,a,o,s){var l=r[a];if(l){var u=l[e]||l,c=l[n],h=l[i];if(h!==o||c!==s){if(null==o||!s)return r[a]=u;l=r[a]=t.throttle(u,o,"debounce"===s),l[e]=u,l[n]=s,l[i]=o}return l}},t.clear=function(t,i){var n=t[i];n&&n[e]&&(t[i]=n[e])},t}),e("echarts/util/graphic",[Re,De,"zrender/tool/path","zrender/graphic/Path","zrender/tool/color","zrender/core/matrix",ze,"zrender/container/Group","zrender/graphic/Image","zrender/graphic/Text","zrender/graphic/shape/Circle","zrender/graphic/shape/Sector","zrender/graphic/shape/Ring","zrender/graphic/shape/Polygon","zrender/graphic/shape/Polyline","zrender/graphic/shape/Rect","zrender/graphic/shape/Line","zrender/graphic/shape/BezierCurve","zrender/graphic/shape/Arc","zrender/graphic/CompoundPath","zrender/graphic/LinearGradient","zrender/graphic/RadialGradient","zrender/core/BoundingRect"],function(t){function e(t){return null!=t&&"none"!=t}function i(t){return typeof t===Le?C.lift(t,-.1):t}function n(t){if(t.__hoverStlDirty){var n=t.style[y],r=t.style.fill,a=t.__hoverStl;a.fill=a.fill||(e(r)?i(r):null),a[y]=a[y]||(e(n)?i(n):null);var o={};for(var s in a)a.hasOwnProperty(s)&&(o[s]=t.style[s]);t.__normalStl=o,t.__hoverStlDirty=!1}}function r(t){t.__isHover||(n(t),t.useHoverLayer?t.__zr&&t.__zr.addHover(t,t.__hoverStl):(t[$](t.__hoverStl),t.z2+=1),t.__isHover=!0)}function a(t){if(t.__isHover){var e=t.__normalStl;t.useHoverLayer?t.__zr&&t.__zr.removeHover(t):(e&&t[$](e),t.z2-=1),t.__isHover=!1}}function o(t){"group"===t.type?t[Q](function(t){"group"!==t.type&&r(t)}):r(t)}function s(t){"group"===t.type?t[Q](function(t){"group"!==t.type&&a(t)}):a(t)}function l(t,e){t.__hoverStl=t.hoverStyle||e||{},t.__hoverStlDirty=!0,t.__isHover&&n(t)}function u(t){this.__hoverSilentOnTouch&&t.zrByTouch||!this.__isEmphasis&&o(this)}function c(t){this.__hoverSilentOnTouch&&t.zrByTouch||!this.__isEmphasis&&s(this)}function h(){this.__isEmphasis=!0,o(this)}function d(){this.__isEmphasis=!1,s(this)}function f(t,e,i,n,r,a){typeof r===j&&(a=r,r=null);var o=n&&(n.ifEnableAnimation?n.ifEnableAnimation():n[g](Ce));if(o){var s=t?"Update":"",l=n&&n[g]("animationDuration"+s),u=n&&n[g]("animationEasing"+s),c=n&&n[g]("animationDelay"+s);typeof c===j&&(c=c(r)),l>0?e.animateTo(i,l,c||0,u,a):(e.attr(i),a&&a())}else e.attr(i),a&&a()}var b=t(De),M=t("zrender/tool/path"),T=Math.round,S=t("zrender/graphic/Path"),C=t("zrender/tool/color"),A=t("zrender/core/matrix"),P=t(ze),L={};return L.Group=t("zrender/container/Group"),L.Image=t("zrender/graphic/Image"),L.Text=t("zrender/graphic/Text"),L.Circle=t("zrender/graphic/shape/Circle"),L.Sector=t("zrender/graphic/shape/Sector"),L.Ring=t("zrender/graphic/shape/Ring"),L.Polygon=t("zrender/graphic/shape/Polygon"),L.Polyline=t("zrender/graphic/shape/Polyline"),L.Rect=t("zrender/graphic/shape/Rect"),L.Line=t("zrender/graphic/shape/Line"),L.BezierCurve=t("zrender/graphic/shape/BezierCurve"),L.Arc=t("zrender/graphic/shape/Arc"),L.CompoundPath=t("zrender/graphic/CompoundPath"),L.LinearGradient=t("zrender/graphic/LinearGradient"),L.RadialGradient=t("zrender/graphic/RadialGradient"),L.BoundingRect=t("zrender/core/BoundingRect"),L.extendShape=function(t){return S[oe](t)},L.extendPath=function(t,e){return M.extendFromString(t,e)},L.makePath=function(t,e,i,n){var r=M.createFromString(t,e),a=r[N]();if(i){var o=a.width/a[Pe];if(n===E){var s,l=i[Pe]*o;l<=i.width?s=i[Pe]:(l=i.width,s=l/o);var u=i.x+i.width/2,c=i.y+i[Pe]/2;i.x=u-l/2,i.y=c-s/2,i.width=l,i[Pe]=s}this.resizePath(r,i)}return r},L.mergePath=M.mergePath,L.resizePath=function(t,e){if(t[_]){var i=t[N](),n=i.calculateTransform(e);t[_](n)}},L.subPixelOptimizeLine=function(t){var e=L.subPixelOptimize,i=t.shape,n=t.style[x];return T(2*i.x1)===T(2*i.x2)&&(i.x1=i.x2=e(i.x1,n,!0)),T(2*i.y1)===T(2*i.y2)&&(i.y1=i.y2=e(i.y1,n,!0)),t},L.subPixelOptimizeRect=function(t){var e=L.subPixelOptimize,i=t.shape,n=t.style[x],r=i.x,a=i.y,o=i.width,s=i[Pe];return i.x=e(i.x,n,!0),i.y=e(i.y,n,!0),i.width=Math.max(e(r+o,n,!1)-i.x,0===o?0:1),i[Pe]=Math.max(e(a+s,n,!1)-i.y,0===s?0:1),t},L.subPixelOptimize=function(t,e,i){var n=T(2*t);return(n+T(e))%2===0?n/2:(n+(i?1:-1))/2},L.setHoverStyle=function(t,e,i){t.__hoverSilentOnTouch=i&&i.hoverSilentOnTouch,"group"===t.type?t[Q](function(t){"group"!==t.type&&l(t,e)}):l(t,e),t.on(ee,u).on(te,c),t.on("emphasis",h).on(w,d)},L.setText=function(t,e,i){var n=e[g](R)||m,r=n[me](m)>=0?"white":i,a=e[Se](G);b[oe](t,{textDistance:e[g]("distance")||5,textFont:a[V](),textPosition:n,textFill:a.getTextColor()||r})},L.updateProps=function(t,e,i,n,r){f(!0,t,e,i,n,r)},L.initProps=function(t,e,i,n,r){f(!1,t,e,i,n,r)},L.getTransform=function(t,e){for(var i=A.identity([]);t&&t!==e;)A.mul(i,t.getLocalTransform(),i),t=t[v];return i},L[_]=function(t,e,i){return i&&(e=A.invert([],e)),P[_]([],t,e)},L.transformDirection=function(t,e,i){var n=0===e[4]||0===e[5]||0===e[0]?1:Math.abs(2*e[4]/e[0]),r=0===e[4]||0===e[5]||0===e[2]?1:Math.abs(2*e[4]/e[2]),a=["left"===t?-n:"right"===t?n:0,"top"===t?-r:t===ye?r:0];return a=L[_](a,e,i),Math.abs(a[0])>Math.abs(a[1])?a[0]>0?"right":"left":a[1]>0?ye:"top"},L.groupTransition=function(t,e,i){function n(t){var e={};return t[Q](function(t){!t.isGroup&&t.anid&&(e[t.anid]=t)}),e}function r(t){var e={position:P.clone(t[R]),rotation:t[p]};return t.shape&&(e.shape=b[oe]({},t.shape)),e}if(t&&e){var a=n(t);e[Q](function(t){if(!t.isGroup&&t.anid){var e=a[t.anid];if(e){var n=r(t);t.attr(r(e)),L.updateProps(t,n,i,t[fe])}}})}},L}),e("echarts/util/model",[Re,"./format","./number","../model/Model",De],function(t){function e(t,e){return t&&t.hasOwnProperty(e)}var i=t("./format"),n=t("./number"),r=t("../model/Model"),a=t(De),o=a.each,s=a[le],l={};return l.normalizeToArray=function(t){return t instanceof Array?t:null==t?[]:[t]},l.defaultEmphasis=function(t,e){if(t){var i=t.emphasis=t.emphasis||{},n=t[w]=t[w]||{};o(e,function(t){var e=a[f](i[t],n[t]);null!=e&&(i[t]=e)})}},l.LABEL_OPTIONS=[R,"show",G,"distance","formatter"],l.getDataItemValue=function(t){return t&&(null==t.value?t:t.value)},l.isDataItemOption=function(t){return s(t)&&!(t instanceof Array)},l.converDataValue=function(t,e){var i=e&&e.type;return i===d?t:("time"!==i||isFinite(t)||null==t||"-"===t||(t=+n.parseDate(t)),null==t||""===t?0/0:+t)},l.createDataFormatModel=function(t,e){var i=new r;return a.mixin(i,l.dataFormatMixin),i.seriesIndex=e.seriesIndex,i.name=e.name||"",i.mainType=e.mainType,i.subType=e.subType,i[pe]=function(){return t},i},l.dataFormatMixin={getDataParams:function(t,e){var i=this[pe](e),n=this.seriesIndex,r=this.name,a=this.getRawValue(t,e),o=i.getRawIndex(t),s=i.getName(t,!0),l=i.getRawDataItem(t);return{componentType:this.mainType,componentSubType:this.subType,seriesType:this.mainType===ne?this.subType:null,seriesIndex:n,seriesName:r,name:s,dataIndex:o,data:l,dataType:e,value:a,color:i[de](t,"color"),$vars:["seriesName","name","value"]}},getFormattedLabel:function(t,e,n,r){e=e||w;var a=this[pe](n),o=a[h](t),s=this[K](t,n);null!=r&&s.value instanceof Array&&(s.value=s.value[r]);var l=o.get(["label",e,"formatter"]);return typeof l===j?(s.status=e,l(s)):typeof l===Le?i.formatTpl(l,s):void 0},getRawValue:function(t,e){var i=this[pe](e),n=i.getRawDataItem(t);return null!=n?!s(n)||n instanceof Array?n:n.value:void 0},formatTooltip:a.noop},l.mappingToExists=function(t,e){e=(e||[]).slice();var i=a.map(t||[],function(t){return{exist:t}});return o(e,function(t,n){if(s(t)){for(var r=0;r<i[ge];r++)if(!i[r][C]&&null!=t.id&&i[r].exist.id===t.id+"")return i[r][C]=t,void(e[n]=null);for(var r=0;r<i[ge];r++){var a=i[r].exist;if(!(i[r][C]||null!=a.id&&null!=t.id||null==t.name||l.isIdInner(t)||l.isIdInner(a)||a.name!==t.name+""))return i[r][C]=t,void(e[n]=null)}}}),o(e,function(t){if(s(t)){for(var e=0;e<i[ge];e++){var n=i[e].exist;if(!i[e][C]&&!l.isIdInner(n)&&null==t.id){i[e][C]=t;break}}e>=i[ge]&&i.push({option:t})}}),i},l.makeIdAndName=function(t){var e={};o(t,function(t){var i=t.exist;i&&(e[i.id]=t)}),o(t,function(t){var i=t[C];a.assert(!i||null==i.id||!e[i.id]||e[i.id]===t,"id duplicates: "+(i&&i.id)),i&&null!=i.id&&(e[i.id]=t),!t.keyInfo&&(t.keyInfo={})}),o(t,function(t){var i=t.exist,n=t[C],r=t.keyInfo;if(s(n)){if(r.name=null!=n.name?n.name+"":i?i.name:"\x00-",i)r.id=i.id;else if(null!=n.id)r.id=n.id+"";else{var a=0;do r.id="\x00"+r.name+"\x00"+a++;while(e[r.id])}e[r.id]=t}})},l.isIdInner=function(t){return s(t)&&t.id&&0===(t.id+"")[me]("\x00_ec_\x00")},l.compressBatches=function(t,e){function i(t,e,i){for(var n=0,r=t[ge];r>n;n++)for(var a=t[n].seriesId,o=l.normalizeToArray(t[n][fe]),s=i&&i[a],u=0,c=o[ge];c>u;u++){var h=o[u];s&&s[h]?s[h]=null:(e[a]||(e[a]={}))[h]=1}}function n(t,e){var i=[];for(var r in t)if(t.hasOwnProperty(r)&&null!=t[r])if(e)i.push(+r);else{var a=n(t[r],!0);a[ge]&&i.push({seriesId:r,dataIndex:a})}return i}var r={},a={};return i(t||[],r),i(e||[],a,r),[n(r),n(a)]},l.queryDataIndex=function(t,e){return null!=e.dataIndexInside?e.dataIndexInside:null!=e[fe]?a[U](e[fe])?a.map(e[fe],function(e){return t.indexOfRawIndex(e)}):t.indexOfRawIndex(e[fe]):null!=e.name?a[U](e.name)?a.map(e.name,function(e){return t.indexOfName(e)}):t.indexOfName(e.name):void 0},l.parseFinder=function(t,i,n){if(a.isString(i)){var r={};r[i+"Index"]=0,i=r}var s=n&&n.defaultMainType;!s||e(i,s+"Index")||e(i,s+"Id")||e(i,s+"Name")||(i[s+"Index"]=0);var l={};return o(i,function(e,n){var e=i[n];if(n===fe||"dataIndexInside"===n)return void(l[n]=e);var r=n.match(/^(\w+)(Index|Id|Name)$/)||[],a=r[1],o=r[2];if(a&&o){var s={mainType:a};s[o[ke]()]=e;var u=t[S](s);l[a+"Models"]=u,l[a+"Model"]=u[0]}}),l},l}),e("echarts/model/Series",[Re,De,"../util/format","../util/model","./Component","./mixin/colorPalette",Oe,"../util/layout"],function(t){var e=t(De),i=t("../util/format"),n=t("../util/model"),r=t("./Component"),a=t("./mixin/colorPalette"),o=t(Oe),s=t("../util/layout"),l=i.encodeHTML,u=i.addCommas,c=r[oe]({type:"series.__base__",seriesIndex:0,coordinateSystem:null,defaultOption:null,legendDataProvider:null,visualColorAccessPath:"itemStyle.normal.color",layoutMode:null,init:function(t,e,i){this.seriesIndex=this[T],this.mergeDefaultAndTheme(t,i),this._dataBeforeProcessed=this.getInitialData(t,i),this._data=this._dataBeforeProcessed.cloneShallow()},mergeDefaultAndTheme:function(t,i){var r=this.layoutMode,a=r?s.getLayoutParams(t):{};e.merge(t,i.getTheme().get(this.subType)),e.merge(t,this.getDefaultOption()),n.defaultEmphasis(t.label,n.LABEL_OPTIONS),this.fillDataTextStyle(t.data),r&&s.mergeLayoutParam(t,a,r)},mergeOption:function(t,i){t=e.merge(this[C],t,!0),this.fillDataTextStyle(t.data);var n=this.layoutMode;n&&s.mergeLayoutParam(this[C],t,n);var r=this.getInitialData(t,i);r&&(this._data=r,this._dataBeforeProcessed=r.cloneShallow())},fillDataTextStyle:function(t){if(t)for(var e=0;e<t[ge];e++)t[e]&&t[e].label&&n.defaultEmphasis(t[e].label,n.LABEL_OPTIONS)},getInitialData:function(){},getData:function(t){return null==t?this._data:this._data.getLinkedData(t)},setData:function(t){this._data=t},getRawData:function(){return this._dataBeforeProcessed},coordDimToDataDim:function(t){return[t]},dataDimToCoordDim:function(t){return t},getBaseAxis:function(){var t=this[ve];return t&&t.getBaseAxis&&t.getBaseAxis()},formatTooltip:function(t,n){function r(t){var r=[];return e.each(t,function(t,e){var o,s=a.getDimensionInfo(e),l=s&&s.type;o=l===d?t+"":"time"===l?n?"":i.formatTime("yyyy/MM/dd hh:mm:ss",t):u(t),o&&r.push(o)}),r.join(", ")}var a=this._data,o=this.getRawValue(t),s=e[U](o)?r(o):u(o),c=a.getName(t),h=a[de](t,"color");e[le](h)&&h[ue]&&(h=(h[ue][0]||{}).color),h=h||"transparent";var f='<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:'+h+'"></span>',p=this.name;return"\x00-"===p&&(p=""),n?f+l(this.name)+" : "+s:(p&&l(p)+"<br />")+f+(c?l(c)+" : "+s:s)},ifEnableAnimation:function(){if(o.node)return!1;var t=this[g](Ce);return t&&this[pe]().count()>this[g]("animationThreshold")&&(t=!1),t},restoreData:function(){this._data=this._dataBeforeProcessed.cloneShallow()},getColorFromPalette:function(t,e){var i=this[M],n=a.getColorFromPalette.call(this,t,e);return n||(n=i.getColorFromPalette(t,e)),n},getAxisTooltipDataIndex:null,getTooltipPosition:null});return e.mixin(c,n.dataFormatMixin),e.mixin(c,a),c}),e("zrender/zrender",[Re,"./core/guid","./core/env","./core/util","./Handler","./Storage","./animation/Animation","./dom/HandlerProxy","./Painter"],function(t){function e(t){delete h[t]}var i=t("./core/guid"),n=t("./core/env"),r=t("./core/util"),a=t("./Handler"),o=t("./Storage"),s=t("./animation/Animation"),l=t("./dom/HandlerProxy"),u=!n[we],c={canvas:t("./Painter")},h={},d={};d.version="3.2.2",d.init=function(t,e){var n=new f(i(),t,e);return h[n.id]=n,n},d.dispose=function(t){if(t)t.dispose();else{for(var e in h)h.hasOwnProperty(e)&&h[e].dispose();h={}}return d},d.getInstance=function(t){return h[t]},d.registerPainter=function(t,e){c[t]=e};var f=function(t,e,i){i=i||{},this.dom=e,this.id=t;var h=this,d=new o,f=i.renderer;if(u){if(!c.vml)throw new Error("You need to require 'zrender/vml/vml' to support IE8");f="vml"}else f&&c[f]||(f="canvas");var p=new c[f](e,d,i);this[be]=d,this.painter=p;var v=n.node?null:new l(p.getViewportRoot());this.handler=new a(d,p,v,p.root),this[Ce]=new s({stage:{update:r.bind(this.flush,this)}}),this[Ce].start(),this._needsRefresh;var m=d.delFromMap,g=d.addToMap;d.delFromMap=function(t){var e=d.get(t);m.call(d,t),e&&e.removeSelfFromZr(h)},d.addToMap=function(t){g.call(d,t),t.addSelfToZr(h)}};return f[Ie]={constructor:f,getId:function(){return this.id},add:function(t){this[be].addRoot(t),this._needsRefresh=!0},remove:function(t){this[be].delRoot(t),this._needsRefresh=!0},configLayer:function(t,e){this.painter.configLayer(t,e),this._needsRefresh=!0},refreshImmediately:function(){this._needsRefresh=!1,this.painter.refresh(),this._needsRefresh=!1},refresh:function(){this._needsRefresh=!0},flush:function(){this._needsRefresh&&this.refreshImmediately(),this._needsRefreshHover&&this.refreshHoverImmediately()},addHover:function(t,e){this.painter.addHover&&(this.painter.addHover(t,e),this.refreshHover())},removeHover:function(t){this.painter.removeHover&&(this.painter.removeHover(t),this.refreshHover())},clearHover:function(){this.painter.clearHover&&(this.painter.clearHover(),this.refreshHover())},refreshHover:function(){this._needsRefreshHover=!0},refreshHoverImmediately:function(){this._needsRefreshHover=!1,this.painter.refreshHover&&this.painter.refreshHover()},resize:function(t){t=t||{},this.painter[Ae](t.width,t[Pe]),this.handler[Ae]()},clearAnimation:function(){this[Ce].clear()},getWidth:function(){return this.painter[Te]()},getHeight:function(){return this.painter[Me]()},pathToImage:function(t,e,n){var r=i();return this.painter.pathToImage(r,t,e,n)},setCursorStyle:function(t){this.handler.setCursorStyle(t)},on:function(t,e,i){this.handler.on(t,e,i)},off:function(t,e){this.handler.off(t,e)},trigger:function(t,e){this.handler[re](t,e)},clear:function(){this[be].delRoot(),this.painter.clear()},dispose:function(){this[Ce].stop(),this.clear(),this[be].dispose(),this.painter.dispose(),this.handler.dispose(),this[Ce]=this[be]=this.painter=this.handler=null,e(this.id)}},d}),e(De,[Re],function(){function t(e){if(null==e||"object"!=typeof e)return e;var i=e,n=D.call(e);if("[object Array]"===n){i=[];for(var r=0,a=e[ge];a>r;r++)i[r]=t(e[r])}else if(z[n])i=e.constructor.from(e);else if(!k[n]&&!M(e)){i={};for(var o in e)e.hasOwnProperty(o)&&(i[o]=t(e[o]))}return i}function e(i,n,r){if(!b(n)||!b(i))return r?t(n):i;for(var a in n)if(n.hasOwnProperty(a)){var o=i[a],s=n[a];!b(s)||!b(o)||y(s)||y(o)||M(s)||M(o)||w(s)||w(o)?!r&&a in i||(i[a]=t(n[a],!0)):e(o,s,r)}return i}function i(t,i){for(var n=t[0],r=1,a=t[ge];a>r;r++)n=e(n,t[r],i);return n}function n(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function r(t,e,i){for(var n in e)e.hasOwnProperty(n)&&(i?null!=e[n]:null==t[n])&&(t[n]=e[n]);return t}function a(){return document[P]("canvas")}function o(){return I||(I=F.createCanvas()[L]("2d")),I}function s(t,e){if(t){if(t[me])return t[me](e);for(var i=0,n=t[ge];n>i;i++)if(t[i]===e)return i}return-1}function l(t,e){function i(){}var n=t[Ie];i[Ie]=e[Ie],t[Ie]=new i;for(var r in n)t[Ie][r]=n[r];t[Ie].constructor=t,t.superClass=e}function u(t,e,i){t=Ie in t?t[Ie]:t,e=Ie in e?e[Ie]:e,r(t,e,i)}function c(t){return t?typeof t==Le?!1:typeof t[ge]==W:void 0}function h(t,e,i){if(t&&e)if(t.forEach&&t.forEach===R)t.forEach(e,i);else if(t[ge]===+t[ge])for(var n=0,r=t[ge];r>n;n++)e.call(i,t[n],n,t);else for(var a in t)t.hasOwnProperty(a)&&e.call(i,t[a],a,t)}function d(t,e,i){if(t&&e){if(t.map&&t.map===N)return t.map(e,i);for(var n=[],r=0,a=t[ge];a>r;r++)n.push(e.call(i,t[r],r,t));return n}}function f(t,e,i,n){if(t&&e){if(t.reduce&&t.reduce===V)return t.reduce(e,i,n);for(var r=0,a=t[ge];a>r;r++)i=e.call(n,i,t[r],r,t);return i}}function p(t,e,i){if(t&&e){if(t[q]&&t[q]===E)return t[q](e,i);for(var n=[],r=0,a=t[ge];a>r;r++)e.call(i,t[r],r,t)&&n.push(t[r]);return n}}function v(t,e,i){if(t&&e)for(var n=0,r=t[ge];r>n;n++)if(e.call(i,t[n],n,t))return t[n]}function m(t,e){var i=B.call(arguments,2);return function(){return t.apply(e,i[A](B.call(arguments)))}}function g(t){var e=B.call(arguments,1);return function(){return t.apply(this,e[A](B.call(arguments)))}}function y(t){return"[object Array]"===D.call(t)}function x(t){return typeof t===j}function _(t){return"[object String]"===D.call(t)}function b(t){var e=typeof t;return e===j||!!t&&"object"==e}function w(t){return!!k[D.call(t)]}function M(t){return"object"==typeof t&&typeof t.nodeType===W&&"object"==typeof t.ownerDocument}function T(){for(var t=0,e=arguments[ge];e>t;t++)if(null!=arguments[t])return arguments[t]}function S(){return Function.call.apply(B,arguments)}function C(t,e){if(!t)throw new Error(e)}var I,k={"[object Function]":1,"[object RegExp]":1,"[object Date]":1,"[object Error]":1,"[object CanvasGradient]":1,"[object CanvasPattern]":1,"[object Image]":1,"[object Canvas]":1},z={"[object Int8Array]":1,"[object Uint8Array]":1,"[object Uint8ClampedArray]":1,"[object Int16Array]":1,"[object Uint16Array]":1,"[object Int32Array]":1,"[object Uint32Array]":1,"[object Float32Array]":1,"[object Float64Array]":1},D=Object[Ie].toString,O=Array[Ie],R=O.forEach,E=O[q],B=O.slice,N=O.map,V=O.reduce,F={inherits:l,mixin:u,clone:t,merge:e,mergeAll:i,extend:n,defaults:r,getContext:o,createCanvas:a,indexOf:s,slice:S,find:v,isArrayLike:c,each:h,map:d,reduce:f,filter:p,bind:m,curry:g,isArray:y,isString:_,isObject:b,isFunction:x,isBuildInObject:w,isDom:M,retrieve:T,assert:C,noop:function(){}};return F}),e("zrender/mixin/Eventful",[Re],function(){var t=Array[Ie].slice,e=function(){this._$handlers={}};return e[Ie]={constructor:e,one:function(t,e,i){var n=this._$handlers;if(!e||!t)return this;n[t]||(n[t]=[]);for(var r=0;r<n[t][ge];r++)if(n[t][r].h===e)return this;return n[t].push({h:e,one:!0,ctx:i||this}),this},on:function(t,e,i){var n=this._$handlers;if(!e||!t)return this;n[t]||(n[t]=[]);for(var r=0;r<n[t][ge];r++)if(n[t][r].h===e)return this;return n[t].push({h:e,one:!1,ctx:i||this}),this},isSilent:function(t){var e=this._$handlers;return e[t]&&e[t][ge]},off:function(t,e){var i=this._$handlers;if(!t)return this._$handlers={},this;if(e){if(i[t]){for(var n=[],r=0,a=i[t][ge];a>r;r++)i[t][r].h!=e&&n.push(i[t][r]);i[t]=n}i[t]&&0===i[t][ge]&&delete i[t]}else delete i[t];return this},trigger:function(e){if(this._$handlers[e]){var i=arguments,n=i[ge];n>3&&(i=t.call(i,1));for(var r=this._$handlers[e],a=r[ge],o=0;a>o;){switch(n){case 1:r[o].h.call(r[o].ctx);break;case 2:r[o].h.call(r[o].ctx,i[1]);break;case 3:r[o].h.call(r[o].ctx,i[1],i[2]);break;default:r[o].h.apply(r[o].ctx,i)}r[o].one?(r[ie](o,1),a--):o++}}return this},triggerWithContext:function(e){if(this._$handlers[e]){var i=arguments,n=i[ge];n>4&&(i=t.call(i,1,i[ge]-1));for(var r=i[i[ge]-1],a=this._$handlers[e],o=a[ge],s=0;o>s;){switch(n){case 1:a[s].h.call(r);break;case 2:a[s].h.call(r,i[1]);break;case 3:a[s].h.call(r,i[1],i[2]);break;default:a[s].h.apply(r,i)}a[s].one?(a[ie](s,1),o--):s++}}return this}},e}),e("zrender/tool/color",[Re],function(){function t(t){return t=Math.round(t),0>t?0:t>255?255:t}function e(t){return t=Math.round(t),0>t?0:t>360?360:t}function i(t){return 0>t?0:t>1?1:t}function n(e){return t(e[ge]&&"%"===e.charAt(e[ge]-1)?parseFloat(e)/100*255:parseInt(e,10))}function r(t){return i(t[ge]&&"%"===t.charAt(t[ge]-1)?parseFloat(t)/100:parseFloat(t))}function a(t,e,i){return 0>i?i+=1:i>1&&(i-=1),1>6*i?t+(e-t)*i*6:1>2*i?e:2>3*i?t+(e-t)*(2/3-i)*6:t}function o(t,e,i){return t+(e-t)*i}function s(t){if(t){t+="";var e=t[X](/ /g,"")[ke]();if(e in g)return g[e].slice();if("#"!==e.charAt(0)){var i=e[me]("("),a=e[me](")");if(-1!==i&&a+1===e[ge]){var o=e.substr(0,i),s=e.substr(i+1,a-(i+1)).split(","),u=1;switch(o){case"rgba":if(4!==s[ge])return;u=r(s.pop());case"rgb":if(3!==s[ge])return;return[n(s[0]),n(s[1]),n(s[2]),u];case"hsla":if(4!==s[ge])return;return s[3]=r(s[3]),l(s);case"hsl":if(3!==s[ge])return;return l(s);default:return}}}else{if(4===e[ge]){var c=parseInt(e.substr(1),16);if(!(c>=0&&4095>=c))return;return[(3840&c)>>4|(3840&c)>>8,240&c|(240&c)>>4,15&c|(15&c)<<4,1]}if(7===e[ge]){var c=parseInt(e.substr(1),16);if(!(c>=0&&16777215>=c))return;return[(16711680&c)>>16,(65280&c)>>8,255&c,1]}}}}function l(e){var i=(parseFloat(e[0])%360+360)%360/360,n=r(e[1]),o=r(e[2]),s=.5>=o?o*(n+1):o+n-o*n,l=2*o-s,u=[t(255*a(l,s,i+1/3)),t(255*a(l,s,i)),t(255*a(l,s,i-1/3))];return 4===e[ge]&&(u[3]=e[3]),u}function u(t){if(t){var e,i,n=t[0]/255,r=t[1]/255,a=t[2]/255,o=Math.min(n,r,a),s=Math.max(n,r,a),l=s-o,u=(s+o)/2;if(0===l)e=0,i=0;else{i=.5>u?l/(s+o):l/(2-s-o);var c=((s-n)/6+l/2)/l,h=((s-r)/6+l/2)/l,d=((s-a)/6+l/2)/l;n===s?e=d-h:r===s?e=1/3+c-d:a===s&&(e=2/3+h-c),0>e&&(e+=1),e>1&&(e-=1)}var f=[360*e,i,u];return null!=t[3]&&f.push(t[3]),f}}function c(t,e){var i=s(t);if(i){for(var n=0;3>n;n++)i[n]=0>e?i[n]*(1-e)|0:(255-i[n])*e+i[n]|0;return m(i,4===i[ge]?"rgba":"rgb")}}function h(t){var e=s(t);return e?((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1):void 0}function d(e,i,n){if(i&&i[ge]&&e>=0&&1>=e){n=n||[0,0,0,0];var r=e*(i[ge]-1),a=Math.floor(r),s=Math.ceil(r),l=i[a],u=i[s],c=r-a;return n[0]=t(o(l[0],u[0],c)),n[1]=t(o(l[1],u[1],c)),n[2]=t(o(l[2],u[2],c)),n[3]=t(o(l[3],u[3],c)),n}}function f(e,n,r){if(n&&n[ge]&&e>=0&&1>=e){var a=e*(n[ge]-1),l=Math.floor(a),u=Math.ceil(a),c=s(n[l]),h=s(n[u]),d=a-l,f=m([t(o(c[0],h[0],d)),t(o(c[1],h[1],d)),t(o(c[2],h[2],d)),i(o(c[3],h[3],d))],"rgba");return r?{color:f,leftIndex:l,rightIndex:u,value:a}:f}}function p(t,i,n,a){return t=s(t),t?(t=u(t),null!=i&&(t[0]=e(i)),null!=n&&(t[1]=r(n)),null!=a&&(t[2]=r(a)),m(l(t),"rgba")):void 0}function v(t,e){return t=s(t),t&&null!=e?(t[3]=i(e),m(t,"rgba")):void 0}function m(t,e){var i=t[0]+","+t[1]+","+t[2];return("rgba"===e||"hsva"===e||"hsla"===e)&&(i+=","+t[3]),e+"("+i+")"}var g={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};return{parse:s,lift:c,toHex:h,fastMapToColor:d,mapToColor:f,modifyHSL:p,modifyAlpha:v,stringify:m}}),e("zrender/core/timsort",[],function(){function t(t){for(var e=0;t>=l;)e|=1&t,t>>=1;return t+e}function e(t,e,n,r){var a=e+1;if(a===n)return 1;if(r(t[a++],t[e])<0){for(;n>a&&r(t[a],t[a-1])<0;)a++;i(t,e,a)}else for(;n>a&&r(t[a],t[a-1])>=0;)a++;return a-e}function i(t,e,i){for(i--;i>e;){var n=t[e]; +t[e++]=t[i],t[i--]=n}}function n(t,e,i,n,r){for(n===e&&n++;i>n;n++){for(var a,o=t[n],s=e,l=n;l>s;)a=s+l>>>1,r(o,t[a])<0?l=a:s=a+1;var u=n-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=o}}function r(t,e,i,n,r,a){var o=0,s=0,l=1;if(a(t,e[i+r])>0){for(s=n-r;s>l&&a(t,e[i+r+l])>0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s),o+=r,l+=r}else{for(s=r+1;s>l&&a(t,e[i+r-l])<=0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s);var u=o;o=r-l,l=r-u}for(o++;l>o;){var c=o+(l-o>>>1);a(t,e[i+c])>0?o=c+1:l=c}return l}function a(t,e,i,n,r,a){var o=0,s=0,l=1;if(a(t,e[i+r])<0){for(s=r+1;s>l&&a(t,e[i+r-l])<0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s);var u=o;o=r-l,l=r-u}else{for(s=n-r;s>l&&a(t,e[i+r+l])>=0;)o=l,l=(l<<1)+1,0>=l&&(l=s);l>s&&(l=s),o+=r,l+=r}for(o++;l>o;){var c=o+(l-o>>>1);a(t,e[i+c])<0?l=c:o=c+1}return l}function o(t,e){function i(t,e){d[y]=t,f[y]=e,y+=1}function n(){for(;y>1;){var t=y-2;if(t>=1&&f[t-1]<=f[t]+f[t+1]||t>=2&&f[t-2]<=f[t]+f[t-1])f[t-1]<f[t+1]&&t--;else if(f[t]>f[t+1])break;s(t)}}function o(){for(;y>1;){var t=y-2;t>0&&f[t-1]<f[t+1]&&t--,s(t)}}function s(i){var n=d[i],o=f[i],s=d[i+1],u=f[i+1];f[i]=o+u,i===y-3&&(d[i+1]=d[i+2],f[i+1]=f[i+2]),y--;var c=a(t[s],t,n,o,0,e);n+=c,o-=c,0!==o&&(u=r(t[n+o-1],t,s,u,u-1,e),0!==u&&(u>=o?l(n,o,s,u):h(n,o,s,u)))}function l(i,n,o,s){var l=0;for(l=0;n>l;l++)x[l]=t[i+l];var c=0,h=o,d=i;if(t[d++]=t[h++],0!==--s){if(1===n){for(l=0;s>l;l++)t[d+l]=t[h+l];return void(t[d+s]=x[c])}for(var f,v,m,g=p;;){f=0,v=0,m=!1;do if(e(t[h],x[c])<0){if(t[d++]=t[h++],v++,f=0,0===--s){m=!0;break}}else if(t[d++]=x[c++],f++,v=0,1===--n){m=!0;break}while(g>(f|v));if(m)break;do{if(f=a(t[h],x,c,n,0,e),0!==f){for(l=0;f>l;l++)t[d+l]=x[c+l];if(d+=f,c+=f,n-=f,1>=n){m=!0;break}}if(t[d++]=t[h++],0===--s){m=!0;break}if(v=r(x[c],t,h,s,0,e),0!==v){for(l=0;v>l;l++)t[d+l]=t[h+l];if(d+=v,h+=v,s-=v,0===s){m=!0;break}}if(t[d++]=x[c++],1===--n){m=!0;break}g--}while(f>=u||v>=u);if(m)break;0>g&&(g=0),g+=2}if(p=g,1>p&&(p=1),1===n){for(l=0;s>l;l++)t[d+l]=t[h+l];t[d+s]=x[c]}else{if(0===n)throw new Error;for(l=0;n>l;l++)t[d+l]=x[c+l]}}else for(l=0;n>l;l++)t[d+l]=x[c+l]}function h(i,n,o,s){var l=0;for(l=0;s>l;l++)x[l]=t[o+l];var c=i+n-1,h=s-1,d=o+s-1,f=0,v=0;if(t[d--]=t[c--],0!==--n){if(1===s){for(d-=n,c-=n,v=d+1,f=c+1,l=n-1;l>=0;l--)t[v+l]=t[f+l];return void(t[d]=x[h])}for(var m=p;;){var g=0,y=0,_=!1;do if(e(x[h],t[c])<0){if(t[d--]=t[c--],g++,y=0,0===--n){_=!0;break}}else if(t[d--]=x[h--],y++,g=0,1===--s){_=!0;break}while(m>(g|y));if(_)break;do{if(g=n-a(x[h],t,i,n,n-1,e),0!==g){for(d-=g,c-=g,n-=g,v=d+1,f=c+1,l=g-1;l>=0;l--)t[v+l]=t[f+l];if(0===n){_=!0;break}}if(t[d--]=x[h--],1===--s){_=!0;break}if(y=s-r(t[c],x,0,s,s-1,e),0!==y){for(d-=y,h-=y,s-=y,v=d+1,f=h+1,l=0;y>l;l++)t[v+l]=x[f+l];if(1>=s){_=!0;break}}if(t[d--]=t[c--],0===--n){_=!0;break}m--}while(g>=u||y>=u);if(_)break;0>m&&(m=0),m+=2}if(p=m,1>p&&(p=1),1===s){for(d-=n,c-=n,v=d+1,f=c+1,l=n-1;l>=0;l--)t[v+l]=t[f+l];t[d]=x[h]}else{if(0===s)throw new Error;for(f=d-(s-1),l=0;s>l;l++)t[f+l]=x[l]}}else for(f=d-(s-1),l=0;s>l;l++)t[f+l]=x[l]}var d,f,p=u,v=0,m=c,g=0,y=0;v=t[ge],2*c>v&&(m=v>>>1);var x=[];g=120>v?5:1542>v?10:119151>v?19:40,d=[],f=[],this.mergeRuns=n,this.forceMergeRuns=o,this.pushRun=i}function s(i,r,a,s){a||(a=0),s||(s=i[ge]);var u=s-a;if(!(2>u)){var c=0;if(l>u)return c=e(i,a,s,r),void n(i,a,s,a+c,r);var h=new o(i,r),d=t(u);do{if(c=e(i,a,s,r),d>c){var f=u;f>d&&(f=d),n(i,a,a+f,a+c,r),c=f}h.pushRun(a,c),h.mergeRuns(),u-=c,a+=c}while(0!==u);h.forceMergeRuns()}}var l=32,u=7,c=256;return s}),e("echarts/visual/seriesColor",[Re,"zrender/graphic/Gradient"],function(t){var e=t("zrender/graphic/Gradient");return function(t){function i(i){var n=(i.visualColorAccessPath||"itemStyle.normal.color").split("."),r=i[pe](),a=i.get(n)||i.getColorFromPalette(i.get("name"));r.setVisual("color",a),t.isSeriesFiltered(i)||(typeof a!==j||a instanceof e||r.each(function(t){r.setItemVisual(t,"color",a(i[K](t)))}),r.each(function(t){var e=r[h](t),i=e.get(n,!0);null!=i&&r.setItemVisual(t,"color",i)}))}t.eachRawSeries(i)}}),e("echarts/preprocessor/backwardCompat",[Re,De,"./helper/compatStyle"],function(t){function e(t,e){e=e.split(",");for(var i=t,n=0;n<e[ge]&&(i=i&&i[e[n]],null!=i);n++);return i}function i(t,e,i,n){e=e.split(",");for(var r,a=t,o=0;o<e[ge]-1;o++)r=e[o],null==a[r]&&(a[r]={}),a=a[r];(n||null==a[e[o]])&&(a[e[o]]=i)}function n(t){u(o,function(e){e[0]in t&&!(e[1]in t)&&(t[e[1]]=t[e[0]])})}var r=t(De),a=t("./helper/compatStyle"),o=[["x","left"],["y","top"],["x2","right"],["y2",ye]],s=["grid","geo","parallel","legend","toolbox","title","visualMap","dataZoom","timeline"],l=["bar","boxplot","candlestick","chord","effectScatter","funnel","gauge","lines","graph","heatmap","line","map","parallel","pie","radar","sankey","scatter","treemap"],u=r.each;return function(t){u(t[ne],function(t){if(r[le](t)){var o=t.type;if(a(t),("pie"===o||"gauge"===o)&&null!=t.clockWise&&(t.clockwise=t.clockWise),"gauge"===o){var s=e(t,"pointer.color");null!=s&&i(t,"itemStyle.normal.color",s)}for(var u=0;u<l[ge];u++)if(l[u]===t.type){n(t);break}}}),t.dataRange&&(t.visualMap=t.dataRange),u(s,function(e){var i=t[e];i&&(r[U](i)||(i=[i]),u(i,function(t){n(t)}))})}}),e("echarts/loading/default",[Re,"../util/graphic",De],function(t){var e=t("../util/graphic"),i=t(De),n=Math.PI;return function(t,r){r=r||{},i[ae](r,{text:"loading",color:"#c23531",textColor:"#000",maskColor:"rgba(255, 255, 255, 0.8)",zlevel:0});var a=new e.Rect({style:{fill:r.maskColor},zlevel:r[Y],z:1e4}),o=new e.Arc({shape:{startAngle:-n/2,endAngle:-n/2+.1,r:10},style:{stroke:r.color,lineCap:"round",lineWidth:5},zlevel:r[Y],z:10001}),s=new e.Rect({style:{fill:"none",text:r.text,textPosition:"right",textDistance:10,textFill:r.textColor},zlevel:r[Y],z:10001});o.animateShape(!0).when(1e3,{endAngle:3*n/2}).start("circularInOut"),o.animateShape(!0).when(1e3,{startAngle:3*n/2}).delay(300).start("circularInOut");var l=new e.Group;return l.add(o),l.add(s),l.add(a),l[Ae]=function(){var e=t[Te]()/2,i=t[Me]()/2;o.setShape({cx:e,cy:i});var n=o.shape.r;s.setShape({x:e-n,y:i-n,width:2*n,height:2*n}),a.setShape({x:0,y:0,width:t[Te](),height:t[Me]()})},l[Ae](),l}}),e("echarts/model/Model",[Re,De,"../util/clazz","./mixin/lineStyle","./mixin/areaStyle","./mixin/textStyle","./mixin/itemStyle"],function(t){function e(t,e,i){this.parentModel=e,this[M]=i,this[C]=t}var i=t(De),n=t("../util/clazz");e[Ie]={constructor:e,init:null,mergeOption:function(t){i.merge(this[C],t,!0)},get:function(t,e){if(!t)return this[C];typeof t===Le&&(t=t.split("."));for(var i=this[C],n=this.parentModel,r=0;r<t[ge]&&(!t[r]||(i=i&&"object"==typeof i?i[t[r]]:null,null!=i));r++);return null==i&&n&&!e&&(i=n.get(t)),i},getShallow:function(t,e){var i=this[C],n=null==i?i:i[t],r=this.parentModel;return null==n&&r&&!e&&(n=r[g](t)),n},getModel:function(t,i){var n=this.get(t,!0),r=this.parentModel,a=new e(n,i||r&&r[Se](t),this[M]);return a},isEmpty:function(){return null==this[C]},restoreData:function(){},clone:function(){var t=this.constructor;return new t(i.clone(this[C]))},setReadOnly:function(t){n.setReadOnly(this,t)}},n.enableClassExtend(e);var r=i.mixin;return r(e,t("./mixin/lineStyle")),r(e,t("./mixin/areaStyle")),r(e,t("./mixin/textStyle")),r(e,t("./mixin/itemStyle")),e}),e("echarts/data/List",[Re,"../model/Model","./DataDiffer",De,"../util/model"],function(t){function e(t){return f[U](t)||(t=[t]),t}function i(t,e){var i=t[c],n=new y(f.map(i,t.getDimensionInfo,t),t.hostModel);g(n,t);for(var r=n._storage={},a=t._storage,o=0;o<i[ge];o++){var s=i[o],l=a[s];r[s]=f[me](e,s)>=0?new l.constructor(a[s][ge]):a[s]}return n}var n=I,r=typeof window===I?global:window,a=typeof r.Float64Array===n?Array:r.Float64Array,o=typeof r.Int32Array===n?Array:r.Int32Array,s={"float":a,"int":o,ordinal:Array,number:Array,time:Array},l=t("../model/Model"),u=t("./DataDiffer"),f=t(De),p=t("../util/model"),v=f[le],m=["stackedOn","hasItemOption","_nameList","_idList","_rawData"],g=function(t,e){f.each(m[A](e.__wrappedMethods||[]),function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t.__wrappedMethods=e.__wrappedMethods},y=function(t,e){t=t||["x","y"];for(var i={},n=[],r=0;r<t[ge];r++){var a,o={};typeof t[r]===Le?(a=t[r],o={name:a,stackable:!1,type:"number"}):(o=t[r],a=o.name,o.type=o.type||W),n.push(a),i[a]=o}this[c]=n,this._dimensionInfos=i,this.hostModel=e,this.dataType,this.indices=[],this._storage={},this._nameList=[],this._idList=[],this._optionModels=[],this.stackedOn=null,this._visual={},this._layout={},this._itemVisuals=[],this._itemLayouts=[],this._graphicEls=[],this._rawData,this._extent},x=y[Ie];x.type="list",x.hasItemOption=!0,x.getDimension=function(t){return isNaN(t)||(t=this[c][t]||t),t},x.getDimensionInfo=function(t){return f.clone(this._dimensionInfos[this.getDimension(t)])},x.initData=function(t,e,i){t=t||[],this._rawData=t;var n=this._storage={},r=this.indices=[],a=this[c],o=t[ge],l=this._dimensionInfos,u=[],h={};e=e||[];for(var d=0;d<a[ge];d++){var f=l[a[d]],v=s[f.type];n[a[d]]=new v(o)}var m=this;i||(m.hasItemOption=!1),i=i||function(t,e,i,n){var r=p.getDataItemValue(t);return p.isDataItemOption(t)&&(m.hasItemOption=!0),p.converDataValue(r instanceof Array?r[n]:r,l[e])};for(var g=0;g<t[ge];g++){for(var y=t[g],x=0;x<a[ge];x++){var _=a[x],b=n[_];b[g]=i(y,_,g,x)}r.push(g)}for(var d=0;d<t[ge];d++){e[d]||t[d]&&null!=t[d].name&&(e[d]=t[d].name);var w=e[d]||"",M=t[d]&&t[d].id;!M&&w&&(h[w]=h[w]||0,M=w,h[w]>0&&(M+="__ec__"+h[w]),h[w]++),M&&(u[d]=M)}this._nameList=e,this._idList=u},x.count=function(){return this.indices[ge]},x.get=function(t,e,i){var n=this._storage,r=this.indices[e];if(null==r)return 0/0;var a=n[t]&&n[t][r];if(i){var o=this._dimensionInfos[t];if(o&&o.stackable)for(var s=this.stackedOn;s;){var l=s.get(t,e);(a>=0&&l>0||0>=a&&0>l)&&(a+=l),s=s.stackedOn}}return a},x.getValues=function(t,e,i){var n=[];f[U](t)||(i=e,e=t,t=this[c]);for(var r=0,a=t[ge];a>r;r++)n.push(this.get(t[r],e,i));return n},x.hasValue=function(t){for(var e=this[c],i=this._dimensionInfos,n=0,r=e[ge];r>n;n++)if(i[e[n]].type!==d&&isNaN(this.get(e[n],t)))return!1;return!0},x.getDataExtent=function(t,e){t=this.getDimension(t);var i=this._storage[t],n=this.getDimensionInfo(t);e=n&&n.stackable&&e;var r,a=(this._extent||(this._extent={}))[t+!!e];if(a)return a;if(i){for(var o=1/0,s=-1/0,l=0,u=this.count();u>l;l++)r=this.get(t,l,e),o>r&&(o=r),r>s&&(s=r);return this._extent[t+!!e]=[o,s]}return[1/0,-1/0]},x.getSum=function(t,e){var i=this._storage[t],n=0;if(i)for(var r=0,a=this.count();a>r;r++){var o=this.get(t,r,e);isNaN(o)||(n+=o)}return n},x[me]=function(t,e){var i=this._storage,n=i[t],r=this.indices;if(n)for(var a=0,o=r[ge];o>a;a++){var s=r[a];if(n[s]===e)return a}return-1},x.indexOfName=function(t){for(var e=this.indices,i=this._nameList,n=0,r=e[ge];r>n;n++){var a=e[n];if(i[a]===t)return n}return-1},x.indexOfRawIndex=function(t){var e=this.indices,i=e[t];if(null!=i&&i===t)return t;for(var n=0,r=e[ge]-1;r>=n;){var a=(n+r)/2|0;if(e[a]<t)n=a+1;else{if(!(e[a]>t))return a;r=a-1}}return-1},x.indexOfNearest=function(t,e,i,n){var r=this._storage,a=r[t];null==n&&(n=1/0);var o=-1;if(a)for(var s=Number.MAX_VALUE,l=0,u=this.count();u>l;l++){var c=e-this.get(t,l,i),h=Math.abs(c);n>=c&&(s>h||h===s&&c>0)&&(s=h,o=l)}return o},x.getRawIndex=function(t){var e=this.indices[t];return null==e?-1:e},x.getRawDataItem=function(t){return this._rawData[this.getRawIndex(t)]},x.getName=function(t){return this._nameList[this.indices[t]]||""},x.getId=function(t){return this._idList[this.indices[t]]||this.getRawIndex(t)+""},x.each=function(t,i,n,r){typeof t===j&&(r=n,n=i,i=t,t=[]),t=f.map(e(t),this.getDimension,this);var a=[],o=t[ge],s=this.indices;r=r||this;for(var l=0;l<s[ge];l++)switch(o){case 0:i.call(r,l);break;case 1:i.call(r,this.get(t[0],l,n),l);break;case 2:i.call(r,this.get(t[0],l,n),this.get(t[1],l,n),l);break;default:for(var u=0;o>u;u++)a[u]=this.get(t[u],l,n);a[u]=l,i.apply(r,a)}},x.filterSelf=function(t,i,n,r){typeof t===j&&(r=n,n=i,i=t,t=[]),t=f.map(e(t),this.getDimension,this);var a=[],o=[],s=t[ge],l=this.indices;r=r||this;for(var u=0;u<l[ge];u++){var c;if(1===s)c=i.call(r,this.get(t[0],u,n),u);else{for(var h=0;s>h;h++)o[h]=this.get(t[h],u,n);o[h]=u,c=i.apply(r,o)}c&&a.push(l[u])}return this.indices=a,this._extent={},this},x.mapArray=function(t,e,i,n){typeof t===j&&(n=i,i=e,e=t,t=[]);var r=[];return this.each(t,function(){r.push(e&&e.apply(this,arguments))},i,n),r},x.map=function(t,n,r,a){t=f.map(e(t),this.getDimension,this);var o=i(this,t),s=o.indices=this.indices,l=o._storage,u=[];return this.each(t,function(){var e=arguments[arguments[ge]-1],i=n&&n.apply(this,arguments);if(null!=i){typeof i===W&&(u[0]=i,i=u);for(var r=0;r<i[ge];r++){var a=t[r],o=l[a],c=s[e];o&&(o[c]=i[r])}}},r,a),o},x.downSample=function(t,e,n,r){for(var a=i(this,[t]),o=this._storage,s=a._storage,l=this.indices,u=a.indices=[],c=[],h=[],d=Math.floor(1/e),f=s[t],p=this.count(),v=0;v<o[t][ge];v++)s[t][v]=o[t][v];for(var v=0;p>v;v+=d){d>p-v&&(d=p-v,c[ge]=d);for(var m=0;d>m;m++){var g=l[v+m];c[m]=f[g],h[m]=g}var y=n(c),g=h[r(c,y)||0];f[g]=y,u.push(g)}return a},x[h]=function(t){var e=this.hostModel;return t=this.indices[t],new l(this._rawData[t],e,e&&e[M])},x.diff=function(t){var e,i=this._idList,n=t&&t._idList,r="e\x00\x00";return new u(t?t.indices:[],this.indices,function(t){return null!=(e=n[t])?e:r+t},function(t){return null!=(e=i[t])?e:r+t})},x.getVisual=function(t){var e=this._visual;return e&&e[t]},x.setVisual=function(t,e){if(v(t))for(var i in t)t.hasOwnProperty(i)&&this.setVisual(i,t[i]);else this._visual=this._visual||{},this._visual[t]=e},x.setLayout=function(t,e){if(v(t))for(var i in t)t.hasOwnProperty(i)&&this.setLayout(i,t[i]);else this._layout[t]=e},x.getLayout=function(t){return this._layout[t]},x.getItemLayout=function(t){return this._itemLayouts[t]},x.setItemLayout=function(t,e,i){this._itemLayouts[t]=i?f[oe](this._itemLayouts[t]||{},e):e},x.clearItemLayouts=function(){this._itemLayouts[ge]=0},x[de]=function(t,e,i){var n=this._itemVisuals[t],r=n&&n[e];return null!=r||i?r:this.getVisual(e)},x.setItemVisual=function(t,e,i){var n=this._itemVisuals[t]||{};if(this._itemVisuals[t]=n,v(e))for(var r in e)e.hasOwnProperty(r)&&(n[r]=e[r]);else n[e]=i},x.clearAllVisual=function(){this._visual={},this._itemVisuals=[]};var _=function(t){t.seriesIndex=this.seriesIndex,t[fe]=this[fe],t.dataType=this.dataType};return x.setItemGraphicEl=function(t,e){var i=this.hostModel;e&&(e[fe]=t,e.dataType=this.dataType,e.seriesIndex=i&&i.seriesIndex,"group"===e.type&&e[Q](_,e)),this._graphicEls[t]=e},x[b]=function(t){return this._graphicEls[t]},x.eachItemGraphicEl=function(t,e){f.each(this._graphicEls,function(i,n){i&&t&&t.call(e,i,n)})},x.cloneShallow=function(){var t=f.map(this[c],this.getDimensionInfo,this),e=new y(t,this.hostModel);return e._storage=this._storage,g(e,this),e.indices=this.indices.slice(),this._extent&&(e._extent=f[oe]({},this._extent)),e},x.wrapMethod=function(t,e){var i=this[t];typeof i===j&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=i.apply(this,arguments);return e.apply(this,[t][A](f.slice(arguments)))})},x.TRANSFERABLE_METHODS=["cloneShallow","downSample","map"],x.CHANGABLE_METHODS=["filterSelf"],y}),e("echarts/util/number",[Re],function(){function t(t){return t[X](/^\s+/,"")[X](/\s+$/,"")}var e={},i=1e-4;return e.linearMap=function(t,e,i,n){var r=e[1]-e[0],a=i[1]-i[0];if(0===r)return 0===a?i[0]:(i[0]+i[1])/2;if(n)if(r>0){if(t<=e[0])return i[0];if(t>=e[1])return i[1]}else{if(t>=e[0])return i[0];if(t<=e[1])return i[1]}else{if(t===e[0])return i[0];if(t===e[1])return i[1]}return(t-e[0])/r*a+i[0]},e.parsePercent=function(e,i){switch(e){case E:case B:e="50%";break;case"left":case"top":e="0%";break;case"right":case ye:e="100%"}return typeof e===Le?t(e).match(/%$/)?parseFloat(e)/100*i:parseFloat(e):null==e?0/0:+e},e.round=function(t,e){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),+(+t).toFixed(e)},e.asc=function(t){return t.sort(function(t,e){return t-e}),t},e.getPrecision=function(t){if(t=+t,isNaN(t))return 0;for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i},e.getPrecisionSafe=function(t){var e=t.toString(),i=e[me](".");return 0>i?0:e[ge]-1-i},e.getPixelPrecision=function(t,e){var i=Math.log,n=Math.LN10,r=Math.floor(i(t[1]-t[0])/n),a=Math.round(i(Math.abs(e[1]-e[0]))/n);return Math.max(-r+a,0)},e.MAX_SAFE_INTEGER=9007199254740991,e.remRadian=function(t){var e=2*Math.PI;return(t%e+e)%e},e.isRadianAroundZero=function(t){return t>-i&&i>t},e.parseDate=function(t){if(t instanceof Date)return t;if(typeof t===Le){var e=new Date(t);return isNaN(+e)&&(e=new Date(new Date(t[X](/-/g,"/"))-new Date("1970/01/01"))),e}return new Date(Math.round(t))},e.quantity=function(t){return Math.pow(10,Math.floor(Math.log(t)/Math.LN10))},e.nice=function(t,i){var n,r=e.quantity(t),a=t/r;return n=i?1.5>a?1:2.5>a?2:4>a?3:7>a?5:10:1>a?1:2>a?2:3>a?3:5>a?5:10,n*r},e.reformIntervals=function(t){function e(t,i,n){return t.interval[n]<i.interval[n]||t.interval[n]===i.interval[n]&&(t.close[n]-i.close[n]===(n?-1:1)||!n&&e(t,i,1))}t.sort(function(t,i){return e(t,i,0)?-1:1});for(var i=-1/0,n=1,r=0;r<t[ge];){for(var a=t[r].interval,o=t[r].close,s=0;2>s;s++)a[s]<=i&&(a[s]=i,o[s]=s?1:1-n),i=a[s],n=o[s];a[0]===a[1]&&o[0]*o[1]!==1?t[ie](r,1):r++}return t},e}),e("echarts/util/format",[Re,De,"./number","zrender/contain/text"],function(t){var e=t(De),i=t("./number"),n=t("zrender/contain/text"),r={};r.addCommas=function(t){return isNaN(t)?"-":(t=(t+"").split("."),t[0][X](/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(t[ge]>1?"."+t[1]:""))},r.toCamelCase=function(t,e){return t=(t||"")[ke]()[X](/-(.)/g,function(t,e){return e.toUpperCase()}),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t},r.normalizeCssArray=function(t){var e=t[ge];return typeof t===W?[t,t,t,t]:2===e?[t[0],t[1],t[0],t[1]]:3===e?[t[0],t[1],t[2],t[1]]:t},r.encodeHTML=function(t){return String(t)[X](/&/g,"&amp;")[X](/</g,"&lt;")[X](/>/g,"&gt;")[X](/"/g,"&quot;")[X](/'/g,"&#39;")};var a=["a","b","c","d","e","f","g"],o=function(t,e){return"{"+t+(null==e?"":e)+"}"};r.formatTpl=function(t,i){e[U](i)||(i=[i]);var n=i[ge];if(!n)return"";for(var r=i[0].$vars||[],s=0;s<r[ge];s++){var l=a[s];t=t[X](o(l),o(l,0))}for(var u=0;n>u;u++)for(var c=0;c<r[ge];c++)t=t[X](o(a[c],u),i[u][r[c]]);return t};var s=function(t){return 10>t?"0"+t:t};return r.formatTime=function(t,e){("week"===t||"month"===t||"quarter"===t||"half-year"===t||"year"===t)&&(t="MM-dd\nyyyy");var n=i.parseDate(e),r=n.getFullYear(),a=n.getMonth()+1,o=n.getDate(),l=n.getHours(),u=n.getMinutes(),c=n.getSeconds();return t=t[X]("MM",s(a))[ke]()[X]("yyyy",r)[X]("yy",r%100)[X]("dd",s(o))[X]("d",o)[X]("hh",s(l))[X]("h",l)[X]("mm",s(u))[X]("m",u)[X]("ss",s(c))[X]("s",c)},r.capitalFirst=function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},r.truncateText=n.truncateText,r}),e("zrender/core/matrix",[],function(){var t=typeof Float32Array===I?Array:Float32Array,e={create:function(){var i=new t(6);return e.identity(i),i},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t},mul:function(t,e,i){var n=e[0]*i[0]+e[2]*i[1],r=e[1]*i[0]+e[3]*i[1],a=e[0]*i[2]+e[2]*i[3],o=e[1]*i[2]+e[3]*i[3],s=e[0]*i[4]+e[2]*i[5]+e[4],l=e[1]*i[4]+e[3]*i[5]+e[5];return t[0]=n,t[1]=r,t[2]=a,t[3]=o,t[4]=s,t[5]=l,t},translate:function(t,e,i){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+i[0],t[5]=e[5]+i[1],t},rotate:function(t,e,i){var n=e[0],r=e[2],a=e[4],o=e[1],s=e[3],l=e[5],u=Math.sin(i),c=Math.cos(i);return t[0]=n*c+o*u,t[1]=-n*u+o*c,t[2]=r*c+s*u,t[3]=-r*u+c*s,t[4]=c*a+u*l,t[5]=c*l-u*a,t},scale:function(t,e,i){var n=i[0],r=i[1];return t[0]=e[0]*n,t[1]=e[1]*r,t[2]=e[2]*n,t[3]=e[3]*r,t[4]=e[4]*n,t[5]=e[5]*r,t},invert:function(t,e){var i=e[0],n=e[2],r=e[4],a=e[1],o=e[3],s=e[5],l=i*o-a*n;return l?(l=1/l,t[0]=o*l,t[1]=-a*l,t[2]=-n*l,t[3]=i*l,t[4]=(n*s-o*r)*l,t[5]=(a*r-i*s)*l,t):null}};return e}),e(ze,[],function(){var t=typeof Float32Array===I?Array:Float32Array,e={create:function(e,i){var n=new t(2);return null==e&&(e=0),null==i&&(i=0),n[0]=e,n[1]=i,n},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t},clone:function(e){var i=new t(2);return i[0]=e[0],i[1]=e[1],i},set:function(t,e,i){return t[0]=e,t[1]=i,t},add:function(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t},scaleAndAdd:function(t,e,i,n){return t[0]=e[0]+i[0]*n,t[1]=e[1]+i[1]*n,t},sub:function(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t},len:function(t){return Math.sqrt(this.lenSquare(t))},lenSquare:function(t){return t[0]*t[0]+t[1]*t[1]},mul:function(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t},div:function(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t},dot:function(t,e){return t[0]*e[0]+t[1]*e[1]},scale:function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t},normalize:function(t,i){var n=e.len(i);return 0===n?(t[0]=0,t[1]=0):(t[0]=i[0]/n,t[1]=i[1]/n),t},distance:function(t,e){return Math.sqrt((t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1]))},distanceSquare:function(t,e){return(t[0]-e[0])*(t[0]-e[0])+(t[1]-e[1])*(t[1]-e[1])},negate:function(t,e){return t[0]=-e[0],t[1]=-e[1],t},lerp:function(t,e,i,n){return t[0]=e[0]+n*(i[0]-e[0]),t[1]=e[1]+n*(i[1]-e[1]),t},applyTransform:function(t,e,i){var n=e[0],r=e[1];return t[0]=i[0]*n+i[2]*r+i[4],t[1]=i[1]*n+i[3]*r+i[5],t},min:function(t,e,i){return t[0]=Math.min(e[0],i[0]),t[1]=Math.min(e[1],i[1]),t},max:function(t,e,i){return t[0]=Math.max(e[0],i[0]),t[1]=Math.max(e[1],i[1]),t}};return e[ge]=e.len,e.lengthSquare=e.lenSquare,e.dist=e.distance,e.distSquare=e.distanceSquare,e}),e("echarts/chart/line/LineView",[Re,De,"../helper/SymbolDraw","../helper/Symbol","./lineAnimationDiff",u,"../../util/model","./poly","../../view/Chart"],function(t){function e(t,e){if(t[ge]===e[ge]){for(var i=0;i<t[ge];i++){var n=t[i],r=e[i];if(n[0]!==r[0]||n[1]!==r[1])return}return!0}}function i(t){return typeof t===W?t:t?.3:0}function n(t){var e=t.getGlobalExtent();if(t.onBand){var i=t.getBandWidth()/2-1,n=e[1]>e[0]?1:-1;e[0]+=n*i,e[1]-=n*i}return e}function r(t){return t>=0?1:-1}function h(t,e){var i=t.getBaseAxis(),n=t.getOtherAxis(i),a=i.onZero?0:n.scale[z]()[0],o=n.dim,u="x"===o||o===l?1:0;return e.mapArray([o],function(n,l){for(var c,h=e.stackedOn;h&&r(h.get(o,l))===r(n);){c=h;break}var d=[];return d[u]=e.get(i.dim,l),d[1-u]=c?c.get(o,l,!0):a,t[s](d)},!0)}function f(t,e,i){var r=n(t[o]("x")),a=n(t[o]("y")),s=t.getBaseAxis().isHorizontal(),l=Math.min(r[0],r[1]),u=Math.min(a[0],a[1]),c=Math.max(r[0],r[1])-l,h=Math.max(a[0],a[1])-u,d=i.get("lineStyle.normal.width")||2,f=i.get("clipOverflow")?d/2:Math.max(c,h);s?(u-=f,h+=2*f):(l-=f,c+=2*f);var p=new M.Rect({shape:{x:l,y:u,width:c,height:h}});return e&&(p.shape[s?"width":Pe]=0,M.initProps(p,{shape:{width:c,height:h}},i)),p}function p(t,e,i){var n=t.getAngleAxis(),r=t.getRadiusAxis(),a=r[z](),o=n[z](),s=Math.PI/180,l=new M.Sector({shape:{cx:t.cx,cy:t.cy,r0:a[0],r:a[1],startAngle:-o[0]*s,endAngle:-o[1]*s,clockwise:n.inverse}});return e&&(l.shape.endAngle=-o[0]*s,M.initProps(l,{shape:{endAngle:-o[1]*s}},i)),l}function v(t,e,i){return"polar"===t.type?p(t,e,i):f(t,e,i)}function m(t,e,i){for(var n=e.getBaseAxis(),r="x"===n.dim||n.dim===l?0:1,a=[],o=0;o<t[ge]-1;o++){var s=t[o+1],u=t[o];a.push(u);var c=[];switch(i){case"end":c[r]=s[r],c[1-r]=u[1-r],a.push(c);break;case B:var h=(u[r]+s[r])/2,d=[];c[r]=d[r]=h,c[1-r]=u[1-r],d[1-r]=s[1-r],a.push(c),a.push(d);break;default:c[r]=u[r],c[1-r]=s[1-r],a.push(c)}}return t[o]&&a.push(t[o]),a}function g(t,e){var i=t.getVisual("visualMeta");if(i&&i[ge]&&t.count()){for(var n,r=i[ge]-1;r>=0;r--)if(i[r].dimension<2){n=i[r];break}if(n&&"cartesian2d"===e.type){var s=n.dimension,l=t[c][s],u=e[o](l),h=y.map(n.stops,function(t){return{coord:u.toGlobalCoord(u[a](t.value)),color:t.color}}),d=h[ge],f=n.outerColors.slice();d&&h[0].coord>h[d-1].coord&&(h.reverse(),f.reverse());var p=10,v=h[0].coord-p,m=h[d-1].coord+p,g=m-v;if(.001>g)return"transparent";y.each(h,function(t){t.offset=(t.coord-v)/g}),h.push({offset:d?h[d-1].offset:.5,color:f[1]||"transparent"}),h.unshift({offset:d?h[0].offset:.5,color:f[0]||"transparent"});var x=new M.LinearGradient(0,0,0,0,h,!0);return x[l]=v,x[l+"2"]=m,x}}}var y=t(De),x=t("../helper/SymbolDraw"),_=t("../helper/Symbol"),w=t("./lineAnimationDiff"),M=t(u),T=t("../../util/model"),S=t("./poly"),C=t("../../view/Chart");return C[oe]({type:"line",init:function(){var t=new M.Group,e=new x;this.group.add(e.group),this._symbolDraw=e,this._lineGroup=t},render:function(t,n,r){var a=t[ve],o=this.group,s=t[pe](),l=t[Se]("lineStyle.normal"),u=t[Se]("areaStyle.normal"),c=s.mapArray(s.getItemLayout,!0),d="polar"===a.type,f=this._coordSys,p=this._symbolDraw,x=this._polyline,_=this._polygon,b=this._lineGroup,w=t.get(Ce),M=!u.isEmpty(),T=h(a,s),S=t.get("showSymbol"),C=S&&!d&&!t.get("showAllSymbol")&&this._getSymbolIgnoreFunc(s,a),A=this._data;A&&A.eachItemGraphicEl(function(t,e){t.__temp&&(o[se](t),A.setItemGraphicEl(e,null))}),S||p[se](),o.add(b);var P=!d&&t.get("step");x&&f.type===a.type&&P===this._step?(M&&!_?_=this._newPolygon(c,T,a,w):_&&!M&&(b[se](_),_=this._polygon=null),b.setClipPath(v(a,!1,t)),S&&p.updateData(s,C),s.eachItemGraphicEl(function(t){t.stopAnimation(!0)}),e(this._stackedOnPoints,T)&&e(this._points,c)||(w?this._updateAnimation(s,T,a,r,P):(P&&(c=m(c,a,P),T=m(T,a,P)),x.setShape({points:c}),_&&_.setShape({points:c,stackedOnPoints:T})))):(S&&p.updateData(s,C),P&&(c=m(c,a,P),T=m(T,a,P)),x=this._newPolyline(c,a,w),M&&(_=this._newPolygon(c,T,a,w)),b.setClipPath(v(a,!0,t)));var L=g(s,a)||s.getVisual("color");x.useStyle(y[ae](l.getLineStyle(),{fill:"none",stroke:L,lineJoin:"bevel"}));var I=t.get("smooth");if(I=i(t.get("smooth")),x.setShape({smooth:I,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")}),_){var k=s.stackedOn,z=0;if(_.useStyle(y[ae](u.getAreaStyle(),{fill:L,opacity:.7,lineJoin:"bevel"})),k){var D=k.hostModel;z=i(D.get("smooth"))}_.setShape({smooth:I,stackedOnSmooth:z,smoothMonotone:t.get("smoothMonotone"),connectNulls:t.get("connectNulls")})}this._data=s,this._coordSys=a,this._stackedOnPoints=T,this._points=c,this._step=P},dispose:function(){},highlight:function(t,e,i,n){var r=t[pe](),a=T.queryDataIndex(r,n);if(!(a instanceof Array)&&null!=a&&a>=0){var o=r[b](a);if(!o){var s=r.getItemLayout(a);if(!s)return;o=new _(r,a),o[R]=s,o.setZ(t.get(Y),t.get("z")),o[xe]=isNaN(s[0])||isNaN(s[1]),o.__temp=!0,r.setItemGraphicEl(a,o),o.stopSymbolAnimation(!0),this.group.add(o)}o.highlight()}else C[Ie].highlight.call(this,t,e,i,n)},downplay:function(t,e,i,n){var r=t[pe](),a=T.queryDataIndex(r,n);if(null!=a&&a>=0){var o=r[b](a);o&&(o.__temp?(r.setItemGraphicEl(a,null),this.group[se](o)):o.downplay())}else C[Ie].downplay.call(this,t,e,i,n)},_newPolyline:function(t){var e=this._polyline;return e&&this._lineGroup[se](e),e=new S.Polyline({shape:{points:t},silent:!0,z2:10}),this._lineGroup.add(e),this._polyline=e,e},_newPolygon:function(t,e){var i=this._polygon;return i&&this._lineGroup[se](i),i=new S.Polygon({shape:{points:t,stackedOnPoints:e},silent:!0}),this._lineGroup.add(i),this._polygon=i,i},_getSymbolIgnoreFunc:function(t,e){var i=e.getAxesByScale(d)[0];return i&&i.isLabelIgnored?y.bind(i.isLabelIgnored,i):void 0},_updateAnimation:function(t,e,i,n,r){var a=this._polyline,o=this._polygon,s=t.hostModel,l=w(this._data,t,this._stackedOnPoints,e,this._coordSys,i),u=l.current,c=l.stackedOnCurrent,h=l.next,d=l.stackedOnNext;r&&(u=m(l.current,i,r),c=m(l.stackedOnCurrent,i,r),h=m(l.next,i,r),d=m(l.stackedOnNext,i,r)),a.shape.__points=l.current,a.shape.points=u,M.updateProps(a,{shape:{points:h}},s),o&&(o.setShape({points:u,stackedOnPoints:c}),M.updateProps(o,{shape:{points:h,stackedOnPoints:d}},s));for(var f=[],p=l.status,v=0;v<p[ge];v++){var g=p[v].cmd;if("="===g){var y=t[b](p[v].idx1);y&&f.push({el:y,ptIdx:v})}}a.animators&&a.animators[ge]&&a.animators[0].during(function(){for(var t=0;t<f[ge];t++){var e=f[t].el;e.attr(R,a.shape.__points[f[t].ptIdx])}})},remove:function(){var t=this.group,e=this._data;this._lineGroup[H](),this._symbolDraw[se](!0),e&&e.eachItemGraphicEl(function(i,n){i.__temp&&(t[se](i),e.setItemGraphicEl(n,null))}),this._polyline=this._polygon=this._coordSys=this._points=this._stackedOnPoints=this._data=null}})}),e("echarts/chart/line/LineSeries",[Re,"../helper/createListFromArray","../../model/Series"],function(t){var e=t("../helper/createListFromArray"),i=t("../../model/Series");return i[oe]({type:"series.line",dependencies:["grid","polar"],getInitialData:function(t,i){return e(t.data,this,i)},defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,hoverAnimation:!0,clipOverflow:!0,label:{normal:{position:"top"}},lineStyle:{normal:{width:2,type:"solid"}},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:!1,connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0}})}),e("echarts/layout/points",[Re],function(){return function(t,e){e.eachSeriesByType(t,function(t){var e=t[pe](),i=t[ve];if(i){var n=i[c];"singleAxis"===i.type?e.each(n[0],function(t,n){e.setItemLayout(n,isNaN(t)?[0/0,0/0]:i[s](t))}):e.each(n,function(t,n,r){e.setItemLayout(r,isNaN(t)||isNaN(n)?[0/0,0/0]:i[s]([t,n]))},!0)}})}}),e("echarts/visual/symbol",[Re],function(){return function(t,e,i,n){n.eachRawSeriesByType(t,function(t){var r=t[pe](),a=t.get("symbol")||e,o=t.get("symbolSize");r.setVisual({legendSymbol:i||a,symbol:a,symbolSize:o}),n.isSeriesFiltered(t)||(typeof o===j&&r.each(function(e){var i=t.getRawValue(e),n=t[K](e);r.setItemVisual(e,"symbolSize",o(i,n))}),r.each(function(t){var e=r[h](t),i=e[g]("symbol",!0),n=e[g]("symbolSize",!0);null!=i&&r.setItemVisual(t,"symbol",i),null!=n&&r.setItemVisual(t,"symbolSize",n)}))})}}),e("echarts/processor/dataSample",[],function(){var t={average:function(t){for(var e=0,i=0,n=0;n<t[ge];n++)isNaN(t[n])||(e+=t[n],i++);return 0===i?0/0:e/i},sum:function(t){for(var e=0,i=0;i<t[ge];i++)e+=t[i]||0;return e},max:function(t){for(var e=-1/0,i=0;i<t[ge];i++)t[i]>e&&(e=t[i]);return e},min:function(t){for(var e=1/0,i=0;i<t[ge];i++)t[i]<e&&(e=t[i]);return e},nearest:function(t){return t[0]}},e=function(t){return Math.round(t[ge]/2)};return function(i,n){n.eachSeriesByType(i,function(i){var n=i[pe](),r=i.get("sampling"),a=i[ve];if("cartesian2d"===a.type&&r){var o=a.getBaseAxis(),s=a.getOtherAxis(o),l=o[z](),u=l[1]-l[0],c=Math.round(n.count()/u);if(c>1){var h;typeof r===Le?h=t[r]:typeof r===j&&(h=r),h&&(n=n.downSample(s.dim,1/c,h,e),i.setData(n))}}},this)}}),e("echarts/coord/cartesian/Grid",[Re,"exports","../../util/layout","../../coord/axisHelper",De,"./Cartesian2D","./Axis2D","./GridModel","../../CoordinateSystem"],function(t){function e(t,e){return t.findGridModel()===e}function i(t){var e,i=t.model,n=i.getFormattedLabels(),r=i[Se]("axisLabel.textStyle"),a=1,o=n[ge];o>40&&(a=Math.ceil(o/40));for(var s=0;o>s;s+=a)if(!t.isLabelIgnored(s)){var l=r.getTextRect(n[s]);e?e.union(l):e=l}return e}function n(t,e,i){this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this._initCartesian(t,e,i),this._model=t}function l(t,e){var i=t[z](),n=i[0]+i[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return n-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return n-t+e}}function u(t){return v.map(w,function(e){var i=t.getReferringComponents(e)[0];return i})}function h(t){return"cartesian2d"===t.get(ve)}var f=t("../../util/layout"),p=t("../../coord/axisHelper"),v=t(De),m=t("./Cartesian2D"),g=t("./Axis2D"),y=v.each,x=p.ifAxisCrossZero,_=p.niceScaleExtent;t("./GridModel");var b=n[Ie];b.type="grid",b.getRect=function(){return this._rect},b[ce]=function(t,e){function i(t){var e=n[t];for(var i in e)if(e.hasOwnProperty(i)){var a=e[i];if(a&&(a.type===r||!x(a)))return!0}return!1}var n=this._axesMap;this._updateScale(t,this._model),y(n.x,function(t){_(t,t.model)}),y(n.y,function(t){_(t,t.model)}),y(n.x,function(t){i("y")&&(t.onZero=!1)}),y(n.y,function(t){i("x")&&(t.onZero=!1) +}),this[Ae](this._model,e)},b[Ae]=function(t,e){function n(){y(a,function(t){var e=t.isHorizontal(),i=e?[0,r.width]:[0,r[Pe]],n=t.inverse?1:0;t.setExtent(i[n],i[1-n]),l(t,e?r.x:r.y)})}var r=f.getLayoutRect(t.getBoxLayoutParams(),{width:e[Te](),height:e[Me]()});this._rect=r;var a=this._axesList;n(),t.get("containLabel")&&(y(a,function(t){if(!t.model.get("axisLabel.inside")){var e=i(t);if(e){var n=t.isHorizontal()?Pe:"width",a=t.model.get("axisLabel.margin");r[n]-=e[n]+a,"top"===t[R]?r.y+=e[Pe]+a:"left"===t[R]&&(r.x+=e.width+a)}}}),n())},b[o]=function(t,e){var i=this._axesMap[t];if(null!=i){if(null==e)for(var n in i)if(i.hasOwnProperty(n))return i[n];return i[e]}},b.getCartesian=function(t,e){if(null!=t&&null!=e){var i="x"+t+"y"+e;return this._coordsMap[i]}for(var n=0,r=this._coordsList;n<r[ge];n++)if(r[n][o]("x").index===t||r[n][o]("y").index===e)return r[n]},b.convertToPixel=function(t,e,i){var n=this._findConvertTarget(t,e);return n.cartesian?n.cartesian[s](i):n.axis?n.axis.toGlobalCoord(n.axis[a](i)):null},b.convertFromPixel=function(t,e,i){var n=this._findConvertTarget(t,e);return n.cartesian?n.cartesian.pointToData(i):n.axis?n.axis.coordToData(n.axis.toLocalCoord(i)):null},b._findConvertTarget=function(t,e){var i,n,r=e.seriesModel,a=e.xAxisModel||r&&r.getReferringComponents("xAxis")[0],s=e.yAxisModel||r&&r.getReferringComponents("yAxis")[0],l=e.gridModel,u=this._coordsList;if(r)i=r[ve],v[me](u,i)<0&&(i=null);else if(a&&s)i=this.getCartesian(a[T],s[T]);else if(a)n=this[o]("x",a[T]);else if(s)n=this[o]("y",s[T]);else if(l){var c=l[ve];c===this&&(i=this._coordsList[0])}return{cartesian:i,axis:n}},b.containPoint=function(t){var e=this._coordsList[0];return e?e.containPoint(t):void 0},b._initCartesian=function(t,i){function n(n){return function(l,u){if(e(l,t,i)){var c=l.get(R);"x"===n?"top"!==c&&c!==ye&&(c=ye,a[c]&&(c="top"===c?ye:"top")):"left"!==c&&"right"!==c&&(c="left",a[c]&&(c="left"===c?"right":"left")),a[c]=!0;var h=new g(n,p.createScaleByModel(l),[0,0],l.get("type"),c),d=h.type===r;h.onBand=d&&l.get("boundaryGap"),h.inverse=l.get("inverse"),h.onZero=l.get("axisLine.onZero"),l.axis=h,h.model=l,h.grid=this,h.index=u,this._axesList.push(h),o[n][u]=h,s[n]++}}}var a={left:!1,right:!1,top:!1,bottom:!1},o={x:{},y:{}},s={x:0,y:0};return i[_e]("xAxis",n("x"),this),i[_e]("yAxis",n("y"),this),s.x&&s.y?(this._axesMap=o,void y(o.x,function(t,e){y(o.y,function(i,n){var r="x"+e+"y"+n,a=new m(r);a.grid=this,this._coordsMap[r]=a,this._coordsList.push(a),a.addAxis(t),a.addAxis(i)},this)},this)):(this._axesMap={},void(this._axesList=[]))},b._updateScale=function(t,i){function n(t,e,i){y(i.coordDimToDataDim(e.dim),function(i){e.scale.unionExtent(t.getDataExtent(i,e.scale.type!==d))})}v.each(this._axesList,function(t){t.scale.setExtent(1/0,-1/0)}),t.eachSeries(function(r){if(h(r)){var a=u(r,t),s=a[0],l=a[1];if(!e(s,i,t)||!e(l,i,t))return;var c=this.getCartesian(s[T],l[T]),d=r[pe](),f=c[o]("x"),p=c[o]("y");"list"===d.type&&(n(d,f,r),n(d,p,r))}},this)};var w=["xAxis","yAxis"];return n[he]=function(t,e){var i=[];return t[_e]("grid",function(r,a){var o=new n(r,t,e);o.name="grid_"+a,o[Ae](r,e),r[ve]=o,i.push(o)}),t.eachSeries(function(e){if(h(e)){var i=u(e,t),n=i[0],r=i[1],a=n.findGridModel(),o=a[ve];e[ve]=o.getCartesian(n[T],r[T])}}),i},n[c]=m[Ie][c],t("../../CoordinateSystem").register("cartesian2d",n),n}),e("echarts/chart/bar/BarSeries",[Re,"../../model/Series","../helper/createListFromArray"],function(t){var e=t("../../model/Series"),i=t("../helper/createListFromArray");return e[oe]({type:"series.bar",dependencies:["grid","polar"],getInitialData:function(t,e){return i(t.data,this,e)},getMarkerPosition:function(t){var e=this[ve];if(e){var i=e[s](t,!0),n=this[pe](),r=n.getLayout("offset"),a=n.getLayout("size"),o=e.getBaseAxis().isHorizontal()?0:1;return i[o]+=r+a/2,i}return[0/0,0/0]},brushSelector:"rect",defaultOption:{zlevel:0,z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,itemStyle:{normal:{},emphasis:{}}}})}),e("echarts/chart/bar/BarView",[Re,De,u,"../../model/Model","./barItemStyle","../../echarts"],function(t){function e(t,e){var i=t.width>0?1:-1,n=t[Pe]>0?1:-1;e=Math.min(e,Math.abs(t.width),Math.abs(t[Pe])),t.x+=i*e/2,t.y+=n*e/2,t.width-=i*e,t[Pe]-=n*e}var i=t(De),n=t(u);return i[oe](t("../../model/Model")[Ie],t("./barItemStyle")),t("../../echarts").extendChartView({type:"bar",render:function(t,e,i){var n=t.get(ve);return"cartesian2d"===n&&this._renderOnCartesian(t,e,i),this.group},dispose:i.noop,_renderOnCartesian:function(t){function r(r,a){var s=o.getItemLayout(r),l=o[h](r).get(f)||0;e(s,l);var u=new n.Rect({shape:i[oe]({},s)});if(d){var p=u.shape,v=c?Pe:"width",m={};p[v]=0,m[v]=s[v],n[a?"updateProps":"initProps"](u,{shape:m},t,r)}return u}var a=this.group,o=t[pe](),s=this._data,l=t[ve],u=l.getBaseAxis(),c=u.isHorizontal(),d=t.get(Ce),f=["itemStyle",w,"barBorderWidth"];o.diff(s).add(function(t){if(o.hasValue(t)){var e=r(t);o.setItemGraphicEl(t,e),a.add(e)}})[ce](function(i,l){var u=s[b](l);if(!o.hasValue(i))return void a[se](u);u||(u=r(i,!0));var c=o.getItemLayout(i),d=o[h](i).get(f)||0;e(c,d),n.updateProps(u,{shape:c},t,i),o.setItemGraphicEl(i,u),a.add(u)})[se](function(e){var i=s[b](e);i&&(i.style.text="",n.updateProps(i,{shape:{width:0}},t,e,function(){a[se](i)}))}).execute(),this._updateStyle(t,o,c),this._data=o},_updateStyle:function(t,e,r){function a(t,e,i,r,a){n.setText(t,e,i),t.text=r,"outside"===t.textPosition&&(t.textPosition=a)}e.eachItemGraphicEl(function(o,s){var l=e[h](s),u=e[de](s,"color"),c=e[de](s,O),d=e.getItemLayout(s),p=l[Se]("itemStyle.normal"),v=l[Se]("itemStyle.emphasis").getBarItemStyle();o.setShape("r",p.get("barBorderRadius")||0),o.useStyle(i[ae]({fill:u,opacity:c},p.getBarItemStyle()));var m=r?d[Pe]>0?ye:"top":d.width>0?"left":"right",g=l[Se]("label.normal"),y=l[Se]("label.emphasis"),x=o.style;g.get("show")?a(x,g,u,i[f](t.getFormattedLabel(s,w),t.getRawValue(s)),m):x.text="",y.get("show")?a(v,y,u,i[f](t.getFormattedLabel(s,"emphasis"),t.getRawValue(s)),m):v.text="",n.setHoverStyle(o,v)})},remove:function(t){var e=this.group;t.get(Ce)?this._data&&this._data.eachItemGraphicEl(function(i){i.style.text="",n.updateProps(i,{shape:{width:0}},t,i[fe],function(){e[se](i)})}):e[H]()}})}),e("echarts/chart/pie/PieSeries",[Re,"../../data/List",De,"../../util/model","../../data/helper/completeDimensions","../../component/helper/selectableMixin","../../echarts"],function(t){var e=t("../../data/List"),i=t(De),n=t("../../util/model"),r=t("../../data/helper/completeDimensions"),a=t("../../component/helper/selectableMixin"),o=t("../../echarts").extendSeriesModel({type:"series.pie",init:function(t){o.superApply(this,"init",arguments),this.legendDataProvider=function(){return this._dataBeforeProcessed},this.updateSelectedMap(t.data),this._defaultLabelLine(t)},mergeOption:function(t){o.superCall(this,"mergeOption",t),this.updateSelectedMap(this[C].data)},getInitialData:function(t){var i=r(["value"],t.data),n=new e(i,this);return n.initData(t.data),n},getDataParams:function(t){var e=this._data,i=o.superCall(this,K,t),n=e.getSum("value");return i.percent=n?+(e.get("value",t)/n*100).toFixed(2):0,i.$vars.push("percent"),i},_defaultLabelLine:function(t){n.defaultEmphasis(t.labelLine,["show"]);var e=t.labelLine[w],i=t.labelLine.emphasis;e.show=e.show&&t.label[w].show,i.show=i.show&&t.label.emphasis.show},defaultOption:{zlevel:0,z:2,legendHoverLink:!0,hoverAnimation:!0,center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,selectedOffset:10,avoidLabelOverlap:!0,label:{normal:{rotate:!1,show:!0,position:"outer"},emphasis:{}},labelLine:{normal:{show:!0,length:15,length2:15,smooth:!1,lineStyle:{width:1,type:"solid"}}},itemStyle:{normal:{borderWidth:1},emphasis:{}},animationEasing:"cubicOut",data:[]}});return i.mixin(o,a),o}),e("echarts/chart/pie/PieView",[Re,u,De,"../../view/Chart"],function(t){function e(t,e,n,r){var a=e[pe](),o=this[fe],s=a.getName(o),l=e.get("selectedOffset");r.dispatchAction({type:"pieToggleSelect",from:t,name:s,seriesId:e.id}),a.each(function(t){i(a[b](t),a.getItemLayout(t),e.isSelected(a.getName(t)),l,n)})}function i(t,e,i,n,r){var a=(e.startAngle+e.endAngle)/2,o=Math.cos(a),s=Math.sin(a),l=i?n:0,u=[o*l,s*l];r?t.animate().when(200,{position:u}).start("bounceOut"):t.attr(R,u)}function n(t,e){function i(){o[xe]=o.hoverIgnore,s[xe]=s.hoverIgnore}function n(){o[xe]=o.normalIgnore,s[xe]=s.normalIgnore}a.Group.call(this);var r=new a.Sector({z2:2}),o=new a.Polyline,s=new a.Text;this.add(r),this.add(o),this.add(s),this.updateData(t,e,!0),this.on("emphasis",i).on(w,n).on(ee,i).on(te,n)}function r(t,e,i,n,r){var a=n[Se](G),s=r===m||"inner"===r;return{fill:a.getTextColor()||(s?"#fff":t[de](e,"color")),opacity:t[de](e,O),textFont:a[V](),text:o[f](t.hostModel.getFormattedLabel(e,i),t.getName(e))}}var a=t(u),o=t(De),s=n[Ie];s.updateData=function(t,e,n){function r(){l.stopAnimation(!0),l.animateTo({shape:{r:d.r+10}},300,"elasticOut")}function s(){l.stopAnimation(!0),l.animateTo({shape:{r:d.r}},300,"elasticOut")}var l=this.childAt(0),u=t.hostModel,c=t[h](e),d=t.getItemLayout(e),f=o[oe]({},d);f.label=null,n?(l.setShape(f),l.shape.endAngle=d.startAngle,a.updateProps(l,{shape:{endAngle:d.endAngle}},u,e)):a.updateProps(l,{shape:f},u,e);var p=c[Se]("itemStyle"),v=t[de](e,"color");l.useStyle(o[ae]({lineJoin:"bevel",fill:v},p[Se](w).getItemStyle())),l.hoverStyle=p[Se]("emphasis").getItemStyle(),i(this,t.getItemLayout(e),c.get("selected"),u.get("selectedOffset"),u.get(Ce)),l.off(ee).off(te).off("emphasis").off(w),c.get("hoverAnimation")&&u.ifEnableAnimation()&&l.on(ee,r).on(te,s).on("emphasis",r).on(w,s),this._updateLabel(t,e),a.setHoverStyle(this)},s._updateLabel=function(t,e){var i=this.childAt(1),n=this.childAt(2),o=t.hostModel,s=t[h](e),l=t.getItemLayout(e),u=l.label,c=t[de](e,"color");a.updateProps(i,{shape:{points:u.linePoints||[[u.x,u.y],[u.x,u.y],[u.x,u.y]]}},o,e),a.updateProps(n,{style:{x:u.x,y:u.y}},o,e),n.attr({style:{textVerticalAlign:u.verticalAlign,textAlign:u[F],textFont:u.font},rotation:u[p],origin:[u.x,u.y],z2:10});var d=s[Se]("label.normal"),f=s[Se]("label.emphasis"),v=s[Se]("labelLine.normal"),m=s[Se]("labelLine.emphasis"),g=d.get(R)||f.get(R);n[$](r(t,e,w,d,g)),n[xe]=n.normalIgnore=!d.get("show"),n.hoverIgnore=!f.get("show"),i[xe]=i.normalIgnore=!v.get("show"),i.hoverIgnore=!m.get("show"),i[$]({stroke:c,opacity:t[de](e,O)}),i[$](v[Se]("lineStyle").getLineStyle()),n.hoverStyle=r(t,e,"emphasis",f,g),i.hoverStyle=m[Se]("lineStyle").getLineStyle();var y=v.get("smooth");y&&y===!0&&(y=.4),i.setShape({smooth:y})},o[Z](n,a.Group);var l=t("../../view/Chart")[oe]({type:"pie",init:function(){var t=new a.Group;this._sectorGroup=t},render:function(t,i,r,a){if(!a||a.from!==this.uid){var s=t[pe](),l=this._data,u=this.group,c=i.get(Ce),h=!l,d=o.curry(e,this.uid,t,c,r),f=t.get("selectedMode");if(s.diff(l).add(function(t){var e=new n(s,t);h&&e.eachChild(function(t){t.stopAnimation(!0)}),f&&e.on("click",d),s.setItemGraphicEl(t,e),u.add(e)})[ce](function(t,e){var i=l[b](e);i.updateData(s,t),i.off("click"),f&&i.on("click",d),u.add(i),s.setItemGraphicEl(t,i)})[se](function(t){var e=l[b](t);u[se](e)}).execute(),c&&h&&s.count()>0){var p=s.getItemLayout(0),v=Math.max(r[Te](),r[Me]())/2,m=o.bind(u.removeClipPath,u);u.setClipPath(this._createClipPath(p.cx,p.cy,v,p.startAngle,p.clockwise,m,t))}this._data=s}},dispose:function(){},_createClipPath:function(t,e,i,n,r,o,s){var l=new a.Sector({shape:{cx:t,cy:e,r0:0,r:i,startAngle:n,endAngle:n,clockwise:r}});return a.initProps(l,{shape:{endAngle:n+(r?1:-1)*Math.PI*2}},s,o),l},containPoint:function(t,e){var i=e[pe](),n=i.getItemLayout(0);if(n){var r=t[0]-n.cx,a=t[1]-n.cy,o=Math.sqrt(r*r+a*a);return o<=n.r&&o>=n.r0}}});return l}),e("echarts/layout/barGrid",[Re,De,"../util/number"],function(t){function e(t){return t.get("stack")||"__ec_stack_"+t.seriesIndex}function i(t){return t.dim+t.index}function n(t){var n={};s.each(t,function(t){var a=t[pe](),o=t[ve],s=o.getBaseAxis(),l=s[z](),c=s.type===r?s.getBandWidth():Math.abs(l[1]-l[0])/a.count(),h=n[i(s)]||{bandWidth:c,remainedWidth:c,autoWidthCount:0,categoryGap:"20%",gap:"30%",stacks:{}},d=h.stacks;n[i(s)]=h;var f=e(t);d[f]||h.autoWidthCount++,d[f]=d[f]||{width:0,maxWidth:0};var p=u(t.get("barWidth"),c),v=u(t.get("barMaxWidth"),c),m=t.get("barGap"),g=t.get("barCategoryGap");p&&!d[f].width&&(p=Math.min(h.remainedWidth,p),d[f].width=p,h.remainedWidth-=p),v&&(d[f].maxWidth=v),null!=m&&(h.gap=m),null!=g&&(h.categoryGap=g)});var a={};return s.each(n,function(t,e){a[e]={};var i=t.stacks,n=t.bandWidth,r=u(t.categoryGap,n),o=u(t.gap,1),l=t.remainedWidth,c=t.autoWidthCount,h=(l-r)/(c+(c-1)*o);h=Math.max(h,0),s.each(i,function(t){var e=t.maxWidth;!t.width&&e&&h>e&&(e=Math.min(e,l),l-=e,t.width=e,c--)}),h=(l-r)/(c+(c-1)*o),h=Math.max(h,0);var d,f=0;s.each(i,function(t){t.width||(t.width=h),d=t,f+=t.width*(1+o)}),d&&(f-=d.width*o);var p=-f/2;s.each(i,function(t,i){a[e][i]=a[e][i]||{offset:p,width:t.width},p+=t.width*(1+o)})}),a}function o(t,r){var o=n(s[q](r.getSeriesByType(t),function(t){return!r.isSeriesFiltered(t)&&t[ve]&&"cartesian2d"===t[ve].type})),l={},u={};r.eachSeriesByType(t,function(t){var n=t[pe](),r=t[ve],s=r.getBaseAxis(),c=e(t),h=o[i(s)][c],d=h.offset,f=h.width,p=r.getOtherAxis(s),v=t.get("barMinHeight")||0,m=s.onZero?p.toGlobalCoord(p[a](0)):p.getGlobalExtent()[0],g=r.dataToPoints(n,!0);l[c]=l[c]||[],u[c]=u[c]||[],n.setLayout({offset:d,size:f}),n.each(p.dim,function(t,e){if(!isNaN(t)){l[c][e]||(l[c][e]={p:m,n:m},u[c][e]={p:m,n:m});var i,r,a,o,s=t>=0?"p":"n",h=g[e],y=l[c][e][s],x=u[c][e][s];p.isHorizontal()?(i=y,r=h[1]+d,a=h[0]-x,o=f,u[c][e][s]+=a,Math.abs(a)<v&&(a=(0>a?-1:1)*v),l[c][e][s]+=a):(i=h[0]+d,r=y,a=f,o=h[1]-x,u[c][e][s]+=o,Math.abs(o)<v&&(o=(0>=o?-1:1)*v),l[c][e][s]+=o),n.setItemLayout(e,{x:i,y:r,width:a,height:o})}},!0)},this)}var s=t(De),l=t("../util/number"),u=l.parsePercent;return o}),e("echarts/visual/dataColor",[Re],function(){return function(t,e){var i={};e.eachRawSeriesByType(t,function(t){var n=t.getRawData(),r={};if(!e.isSeriesFiltered(t)){var a=t[pe]();a.each(function(t){var e=a.getRawIndex(t);r[e]=t}),n.each(function(e){var o=n[h](e),s=r[e],l=null!=s&&a[de](s,"color",!0);if(l)n.setItemVisual(e,"color",l);else{var u=o.get("itemStyle.normal.color")||t.getColorFromPalette(n.getName(e),i);n.setItemVisual(e,"color",u),null!=s&&a.setItemVisual(s,"color",u)}})}})}}),e("echarts/action/createDataSelectAction",[Re,"../echarts",De],function(t){var e=t("../echarts"),i=t(De);return function(t,n){i.each(n,function(i){i[ce]="updateView",e.registerAction(i,function(e,n){var r={};return n[_e]({mainType:"series",subType:t,query:e},function(t){t[i.method]&&t[i.method](e.name);var n=t[pe]();n.each(function(e){var i=n.getName(e);r[i]=t.isSelected(i)||!1})}),{name:e.name,selected:r}})})}}),e("echarts/chart/pie/pieLayout",[Re,"../../util/number","./labelLayout",De],function(t){var e=t("../../util/number"),i=e.parsePercent,n=t("./labelLayout"),r=t(De),a=2*Math.PI,o=Math.PI/180;return function(t,s,u){s.eachSeriesByType(t,function(t){var s=t.get(E),c=t.get(l);r[U](c)||(c=[0,c]),r[U](s)||(s=[s,s]);var h=u[Te](),d=u[Me](),f=Math.min(h,d),p=i(s[0],h),v=i(s[1],d),m=i(c[0],f/2),g=i(c[1],f/2),y=t[pe](),x=-t.get("startAngle")*o,_=t.get("minAngle")*o,b=y.getSum("value"),w=Math.PI/(b||y.count())*2,M=t.get("clockwise"),T=t.get("roseType"),S=y.getDataExtent("value");S[0]=0;var C=a,A=0,P=x,L=M?1:-1;if(y.each("value",function(t,i){var n;n="area"!==T?0===b?w:t*w:a/(y.count()||1),_>n?(n=_,C-=_):A+=t;var r=P+L*n;y.setItemLayout(i,{angle:n,startAngle:P,endAngle:r,clockwise:M,cx:p,cy:v,r0:m,r:T?e.linearMap(t,S,[m,g]):g}),P=r},!0),a>C)if(.001>=C){var I=a/y.count();y.each(function(t){var e=y.getItemLayout(t);e.startAngle=x+L*t*I,e.endAngle=x+L*(t+1)*I})}else w=C/A,P=x,y.each("value",function(t,e){var i=y.getItemLayout(e),n=i.angle===_?_:t*w;i.startAngle=P,i.endAngle=P+L*n,P+=L*n});n(t,g,h,d)})}}),e("echarts/processor/dataFilter",[],function(){return function(t,e){var i=e.findComponents({mainType:"legend"});i&&i[ge]&&e.eachSeriesByType(t,function(t){var e=t[pe]();e.filterSelf(function(t){for(var n=e.getName(t),r=0;r<i[ge];r++)if(!i[r].isSelected(n))return!1;return!0},this)},this)}}),e("echarts/component/axis",[Re,"../coord/cartesian/AxisModel","./axis/AxisView"],function(t){t("../coord/cartesian/AxisModel"),t("./axis/AxisView")}),e("echarts/component/legend/LegendModel",[Re,De,"../../model/Model","../../echarts"],function(t){var e=t(De),i=t("../../model/Model"),n=t("../../echarts").extendComponentModel({type:"legend",dependencies:[ne],layoutMode:{type:"box",ignoreSize:!0},init:function(t,e,i){this.mergeDefaultAndTheme(t,i),t.selected=t.selected||{}},mergeOption:function(t){n.superCall(this,"mergeOption",t)},optionUpdated:function(){this._updateData(this[M]);var t=this._data;if(t[0]&&"single"===this.get("selectedMode")){for(var e=!1,i=0;i<t[ge];i++){var n=t[i].get("name");if(this.isSelected(n)){this.select(n),e=!0;break}}!e&&this.select(t[0].get("name"))}},_updateData:function(t){var n=e.map(this.get("data")||[],function(t){return(typeof t===Le||typeof t===W)&&(t={name:t}),new i(t,this,this[M])},this);this._data=n;var r=e.map(t.getSeries(),function(t){return t.name});t.eachSeries(function(t){if(t.legendDataProvider){var e=t.legendDataProvider();r=r[A](e.mapArray(e.getName))}}),this._availableNames=r},getData:function(){return this._data},select:function(t){var i=this[C].selected,n=this.get("selectedMode");if("single"===n){var r=this._data;e.each(r,function(t){i[t.get("name")]=!1})}i[t]=!0},unSelect:function(t){"single"!==this.get("selectedMode")&&(this[C].selected[t]=!1)},toggleSelected:function(t){var e=this[C].selected;e.hasOwnProperty(t)||(e[t]=!0),this[e[t]?"unSelect":"select"](t)},isSelected:function(t){var i=this[C].selected;return!(i.hasOwnProperty(t)&&!i[t])&&e[me](this._availableNames,t)>=0},defaultOption:{zlevel:0,z:4,show:!0,orient:"horizontal",left:"center",top:"top",align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,inactiveColor:"#ccc",textStyle:{color:"#333"},selectedMode:!0,tooltip:{show:!1}}});return n}),e("echarts/component/legend/legendAction",[Re,"../../echarts",De],function(t){function e(t,e,i){var r,a={},o="toggleSelected"===t;return i[_e]("legend",function(i){o&&null!=r?i[r?"select":"unSelect"](e.name):(i[t](e.name),r=i.isSelected(e.name));var s=i[pe]();n.each(s,function(t){var e=t.get("name");if("\n"!==e&&""!==e){var n=i.isSelected(e);a[e]=e in a?a[e]&&n:n}})}),{name:e.name,selected:a}}var i=t("../../echarts"),n=t(De);i.registerAction("legendToggleSelect","legendselectchanged",n.curry(e,"toggleSelected")),i.registerAction("legendSelect","legendselected",n.curry(e,"select")),i.registerAction("legendUnSelect","legendunselected",n.curry(e,"unSelect"))}),e("echarts/component/legend/legendFilter",[],function(){return function(t){var e=t.findComponents({mainType:"legend"});e&&e[ge]&&t.filterSeries(function(t){for(var i=0;i<e[ge];i++)if(!e[i].isSelected(t.name))return!1;return!0})}}),e("echarts/component/legend/LegendView",[Re,De,"../../util/symbol",u,"../helper/listComponent","../../echarts"],function(t){function e(t,e){e.dispatchAction({type:"legendToggleSelect",name:t})}function i(t,e,i){var n=i.getZr()[be].getDisplayList()[0];n&&n.useHoverLayer||t.get("legendHoverLink")&&i.dispatchAction({type:"highlight",seriesName:t.name,name:e})}function n(t,e,i){var n=i.getZr()[be].getDisplayList()[0];n&&n.useHoverLayer||t.get("legendHoverLink")&&i.dispatchAction({type:"downplay",seriesName:t.name,name:e})}var r=t(De),a=t("../../util/symbol"),o=t(u),s=t("../helper/listComponent"),l=r.curry;return t("../../echarts").extendComponentView({type:"legend",init:function(){this._symbolTypeStore={}},render:function(t,a,u){var c=this.group;if(c[H](),t.get("show")){var h=t.get("selectedMode"),d=t.get("align");"auto"===d&&(d="right"===t.get("left")&&"vertical"===t.get("orient")?"right":"left");var f={};r.each(t[pe](),function(r){var s=r.get("name");if(""===s||"\n"===s)return void c.add(new o.Group({newline:!0}));var p=a.getSeriesByName(s)[0];if(!f[s])if(p){var v=p[pe](),m=v.getVisual("color");typeof m===j&&(m=m(p[K](0)));var g=v.getVisual("legendSymbol")||"roundRect",y=v.getVisual("symbol"),x=this._createItem(s,r,t,g,y,d,m,h);x.on("click",l(e,s,u)).on(ee,l(i,p,null,u)).on(te,l(n,p,null,u)),f[s]=!0}else a.eachRawSeries(function(a){if(!f[s]&&a.legendDataProvider){var o=a.legendDataProvider(),c=o.indexOfName(s);if(0>c)return;var p=o[de](c,"color"),v="roundRect",m=this._createItem(s,r,t,v,null,d,p,h);m.on("click",l(e,s,u)).on(ee,l(i,a,s,u)).on(te,l(n,a,s,u)),f[s]=!0}},this)},this),s.layout(c,t,u),s.addBackground(c,t)}},_createItem:function(t,e,i,n,s,l,u,c){var h=i.get("itemWidth"),d=i.get("itemHeight"),f=i.get("inactiveColor"),p=i.isSelected(t),v=new o.Group,m=e[Se](G),g=e.get("icon"),y=e[Se]("tooltip"),x=y.parentModel;if(n=g||n,v.add(a.createSymbol(n,0,0,h,d,p?u:f)),!g&&s&&(s!==n||"none"==s)){var _=.8*d;"none"===s&&(s="circle"),v.add(a.createSymbol(s,(h-_)/2,(d-_)/2,_,_,p?u:f))}var b="left"===l?h+5:-5,w=l,M=i.get("formatter"),S=t;typeof M===Le&&M?S=M[X]("{name}",null!=t?t:""):typeof M===j&&(S=M(t));var A=new o.Text({style:{text:S,x:b,y:d/2,fill:p?m.getTextColor():f,textFont:m[V](),textAlign:w,textVerticalAlign:"middle"}});v.add(A);var P=new o.Rect({shape:v[N](),invisible:!0,tooltip:y.get("show")?r[oe]({content:t,formatter:x.get("formatter",!0)||function(){return t},formatterParams:{componentType:"legend",legendIndex:i[T],name:t,$vars:["name"]}},y[C]):null});return v.add(P),v.eachChild(function(t){t.silent=!0}),P.silent=!c,this.group.add(v),o.setHoverStyle(v),v}})}),e("echarts/util/layout",[Re,De,"zrender/core/BoundingRect","./number","./format"],function(t){function e(t,e,i,n,r){var a=0,o=0;null==n&&(n=1/0),null==r&&(r=1/0);var s=0;e.eachChild(function(l,u){var c,h,d=l[R],f=l[N](),p=e.childAt(u+1),v=p&&p[N]();if("horizontal"===t){var m=f.width+(v?-v.x+f.x:0);c=a+m,c>n||l.newline?(a=0,c=m,o+=s+i,s=f[Pe]):s=Math.max(s,f[Pe])}else{var g=f[Pe]+(v?-v.y+f.y:0);h=o+g,h>r||l.newline?(a+=s+i,o=0,h=g,s=f.width):s=Math.max(s,f.width)}l.newline||(d[0]=a,d[1]=o,"horizontal"===t?a=c+i:o=h+i)})}var i=t(De),n=t("zrender/core/BoundingRect"),r=t("./number"),a=t("./format"),o=r.parsePercent,s=i.each,l={},u=l.LOCATION_PARAMS=["left","right","top",ye,"width",Pe];return l.box=e,l.vbox=i.curry(e,"vertical"),l.hbox=i.curry(e,"horizontal"),l.getAvailableSize=function(t,e,i){var n=e.width,r=e[Pe],s=o(t.x,n),l=o(t.y,r),u=o(t.x2,n),c=o(t.y2,r);return(isNaN(s)||isNaN(parseFloat(t.x)))&&(s=0),(isNaN(u)||isNaN(parseFloat(t.x2)))&&(u=n),(isNaN(l)||isNaN(parseFloat(t.y)))&&(l=0),(isNaN(c)||isNaN(parseFloat(t.y2)))&&(c=r),i=a.normalizeCssArray(i||0),{width:Math.max(u-s-i[1]-i[3],0),height:Math.max(c-l-i[0]-i[2],0)}},l.getLayoutRect=function(t,e,i){i=a.normalizeCssArray(i||0);var r=e.width,s=e[Pe],l=o(t.left,r),u=o(t.top,s),c=o(t.right,r),h=o(t[ye],s),d=o(t.width,r),f=o(t[Pe],s),p=i[2]+i[0],v=i[1]+i[3],m=t.aspect;switch(isNaN(d)&&(d=r-c-v-l),isNaN(f)&&(f=s-h-p-u),isNaN(d)&&isNaN(f)&&(m>r/s?d=.8*r:f=.8*s),null!=m&&(isNaN(d)&&(d=m*f),isNaN(f)&&(f=d/m)),isNaN(l)&&(l=r-c-d-v),isNaN(u)&&(u=s-h-f-p),t.left||t.right){case E:l=r/2-d/2-i[3];break;case"right":l=r-d-v}switch(t.top||t[ye]){case B:case E:u=s/2-f/2-i[0];break;case ye:u=s-f-p}l=l||0,u=u||0,isNaN(d)&&(d=r-l-(c||0)),isNaN(f)&&(f=s-u-(h||0));var g=new n(l+i[3],u+i[0],d,f);return g.margin=i,g},l.positionElement=function(t,e,r,a,o){var s=!o||!o.hv||o.hv[0],u=!o||!o.hv||o.hv[1],c=o&&o.boundingMode||"all";if(s||u){var h;if("raw"===c)h="group"===t.type?new n(0,0,+e.width||0,+e[Pe]||0):t[N]();else if(h=t[N](),t.needLocalTransform()){var d=t.getLocalTransform();h=h.clone(),h[_](d)}e=l.getLayoutRect(i[ae]({width:h.width,height:h[Pe]},e),r,a);var f=t[R],p=s?e.x-h.x:0,v=u?e.y-h.y:0;t.attr(R,"raw"===c?[p,v]:[f[0]+p,f[1]+v])}},l.mergeLayoutParam=function(t,e,n){function r(i){var r={},l=0,u={},c=0,h=n.ignoreSize?1:2;if(s(i,function(e){u[e]=t[e]}),s(i,function(t){a(e,t)&&(r[t]=u[t]=e[t]),o(r,t)&&l++,o(u,t)&&c++}),c!==h&&l){if(l>=h)return r;for(var d=0;d<i[ge];d++){var f=i[d];if(!a(r,f)&&a(t,f)){r[f]=t[f];break}}return r}return u}function a(t,e){return t.hasOwnProperty(e)}function o(t,e){return null!=t[e]&&"auto"!==t[e]}function l(t,e,i){s(t,function(t){e[t]=i[t]})}!i[le](n)&&(n={});var u=["width","left","right"],c=[Pe,"top",ye],h=r(u),d=r(c);l(u,t,h),l(c,t,d)},l.getLayoutParams=function(t){return l.copyLayoutParams({},t)},l.copyLayoutParams=function(t,e){return e&&t&&s(u,function(i){e.hasOwnProperty(i)&&(t[i]=e[i])}),t},l}),e("zrender/vml/graphic",[Re,"../core/env","../core/vector","../core/BoundingRect","../core/PathProxy","../tool/color","../contain/text","../graphic/mixin/RectText","../graphic/Displayable","../graphic/Image","../graphic/Text","../graphic/Path","../graphic/Gradient","./core"],function(t){if(!t("../core/env")[we]){var e=t("../core/vector"),i=t("../core/BoundingRect"),r=t("../core/PathProxy").CMD,a=t("../tool/color"),o=t("../contain/text"),s=t("../graphic/mixin/RectText"),l=t("../graphic/Displayable"),u=t("../graphic/Image"),c=t("../graphic/Text"),h=t("../graphic/Path"),d=t("../graphic/Gradient"),f=t("./core"),p=Math.round,v=Math.sqrt,m=Math.abs,g=Math.cos,b=Math.sin,M=Math.max,T=e[_],S=",",C="progid:DXImageTransform.Microsoft",A=21600,L=A/2,I=1e5,k=1e3,z=function(t){t.style.cssText="position:absolute;left:0;top:0;width:1px;height:1px;",t.coordsize=A+","+A,t.coordorigin="0,0"},D=function(t){return String(t)[X](/&/g,"&amp;")[X](/"/g,"&quot;")},R=function(t,e,i){return"rgb("+[t,e,i].join(",")+")"},V=function(t,e){e&&t&&e.parentNode!==t&&t.appendChild(e)},G=function(t,e){e&&t&&e.parentNode===t&&t.removeChild(e)},H=function(t,e,i){return(parseFloat(t)||0)*I+(parseFloat(e)||0)*k+i},Z=function(t,e){return typeof t===Le?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t},W=function(t,e,i){var n=a.parse(e);i=+i,isNaN(i)&&(i=1),n&&(t.color=R(n[0],n[1],n[2]),t[O]=i*n[3])},j=function(t){var e=a.parse(t);return[R(e[0],e[1],e[2]),e[3]]},U=function(t,e,i){var r=e.fill;if(null!=r)if(r instanceof d){var a,o=0,s=[0,0],l=0,u=1,c=i[N](),h=c.width,f=c[Pe];if("linear"===r.type){a="gradient";var p=i[n],v=[r.x*h,r.y*f],m=[r.x2*h,r.y2*f];p&&(T(v,v,p),T(m,m,p));var g=m[0]-v[0],y=m[1]-v[1];o=180*Math.atan2(g,y)/Math.PI,0>o&&(o+=360),1e-6>o&&(o=0)}else{a="gradientradial";var v=[r.x*h,r.y*f],p=i[n],x=i.scale,_=h,b=f;s=[(v[0]-c.x)/_,(v[1]-c.y)/b],p&&T(v,v,p),_/=x[0]*A,b/=x[1]*A;var w=M(_,b);l=0/w,u=2*r.r/w-l}var S=r[ue].slice();S.sort(function(t,e){return t.offset-e.offset});for(var C=S[ge],P=[],L=[],I=0;C>I;I++){var k=S[I],z=j(k.color);L.push(k.offset*u+l+" "+z[0]),(0===I||I===C-1)&&P.push(z)}if(C>=2){var D=P[0][0],R=P[1][0],E=P[0][1]*e[O],B=P[1][1]*e[O];t.type=a,t.method="none",t.focus="100%",t.angle=o,t.color=D,t.color2=R,t.colors=L.join(","),t[O]=B,t.opacity2=E}"radial"===a&&(t.focusposition=s.join(","))}else W(t,r,e[O])},$=function(t,e){null!=e.lineDash&&(t.dashstyle=e.lineDash.join(" ")),null==e[y]||e[y]instanceof d||W(t,e[y],e[O])},Q=function(t,e,i,n){var r="fill"==e,a=t.getElementsByTagName(e)[0];null!=i[e]&&"none"!==i[e]&&(r||!r&&i[x])?(t[r?"filled":"stroked"]="true",i[e]instanceof d&&G(t,a),a||(a=f.createNode(e)),r?U(a,i,n):$(a,i),V(t,a)):(t[r?"filled":"stroked"]="false",G(t,a))},K=[[],[],[]],J=function(t,e){var i,n,a,o,s,l,u=r.M,c=r.C,h=r.L,d=r.A,f=r.Q,m=[];for(o=0;o<t[ge];){switch(a=t[o++],n="",i=0,a){case u:n=" m ",i=1,s=t[o++],l=t[o++],K[0][0]=s,K[0][1]=l;break;case h:n=" l ",i=1,s=t[o++],l=t[o++],K[0][0]=s,K[0][1]=l;break;case f:case c:n=" c ",i=3;var y,x,_=t[o++],w=t[o++],M=t[o++],C=t[o++];a===f?(y=M,x=C,M=(M+2*_)/3,C=(C+2*w)/3,_=(s+2*_)/3,w=(l+2*w)/3):(y=t[o++],x=t[o++]),K[0][0]=_,K[0][1]=w,K[1][0]=M,K[1][1]=C,K[2][0]=y,K[2][1]=x,s=y,l=x;break;case d:var P=0,I=0,k=1,z=1,D=0;e&&(P=e[4],I=e[5],k=v(e[0]*e[0]+e[1]*e[1]),z=v(e[2]*e[2]+e[3]*e[3]),D=Math.atan2(-e[1]/z,e[0]/k));var O=t[o++],R=t[o++],E=t[o++],B=t[o++],N=t[o++]+D,V=t[o++]+N+D;o++;var F=t[o++],G=O+g(N)*E,H=R+b(N)*B,_=O+g(V)*E,w=R+b(V)*B,Z=F?" wa ":" at ";Math.abs(G-_)<1e-10&&(Math.abs(V-N)>.01?F&&(G+=270/A):Math.abs(H-R)<1e-10?F&&O>G||!F&&G>O?w-=270/A:w+=270/A:F&&R>H||!F&&H>R?_+=270/A:_-=270/A),m.push(Z,p(((O-E)*k+P)*A-L),S,p(((R-B)*z+I)*A-L),S,p(((O+E)*k+P)*A-L),S,p(((R+B)*z+I)*A-L),S,p((G*k+P)*A-L),S,p((H*z+I)*A-L),S,p((_*k+P)*A-L),S,p((w*z+I)*A-L)),s=_,l=w;break;case r.R:var q=K[0],W=K[1];q[0]=t[o++],q[1]=t[o++],W[0]=q[0]+t[o++],W[1]=q[1]+t[o++],e&&(T(q,q,e),T(W,W,e)),q[0]=p(q[0]*A-L),W[0]=p(W[0]*A-L),q[1]=p(q[1]*A-L),W[1]=p(W[1]*A-L),m.push(" m ",q[0],S,q[1]," l ",W[0],S,q[1]," l ",W[0],S,W[1]," l ",q[0],S,W[1]);break;case r.Z:m.push(" x ")}if(i>0){m.push(n);for(var j=0;i>j;j++){var U=K[j];e&&T(U,U,e),m.push(p(U[0]*A-L),S,p(U[1]*A-L),i-1>j?S:"")}}}return m.join("")};h[Ie].brushVML=function(t){var e=this.style,i=this._vmlEl;i||(i=f.createNode("shape"),z(i),this._vmlEl=i),Q(i,"fill",e,this),Q(i,y,e,this);var r=this[n],a=null!=r,o=i.getElementsByTagName(y)[0];if(o){var s=e[x];if(a&&!e.strokeNoScale){var l=r[0]*r[3]-r[1]*r[2];s*=v(m(l))}o.weight=s+"px"}var u=this.path;this.__dirtyPath&&(u.beginPath(),this.buildPath(u,this.shape),u.toStatic(),this.__dirtyPath=!1),i.path=J(u.data,this[n]),i.style.zIndex=H(this[Y],this.z,this.z2),V(t,i),null!=e.text?this.drawRectText(t,this[N]()):this.removeRectText(t)},h[Ie].onRemove=function(t){G(t,this._vmlEl),this.removeRectText(t)},h[Ie].onAdd=function(t){V(t,this._vmlEl),this.appendRectText(t)};var te=function(t){return"object"==typeof t&&t.tagName&&"IMG"===t.tagName.toUpperCase()};u[Ie].brushVML=function(t){var e,i,r=this.style,a=r.image;if(te(a)){var o=a.src;if(o===this._imageSrc)e=this._imageWidth,i=this._imageHeight;else{var s=a.runtimeStyle,l=s.width,u=s[Pe];s.width="auto",s[Pe]="auto",e=a.width,i=a[Pe],s.width=l,s[Pe]=u,this._imageSrc=o,this._imageWidth=e,this._imageHeight=i}a=o}else a===this._imageSrc&&(e=this._imageWidth,i=this._imageHeight);if(a){var c=r.x||0,h=r.y||0,d=r.width,m=r[Pe],g=r.sWidth,y=r.sHeight,x=r.sx||0,_=r.sy||0,b=g&&y,w=this._vmlEl;w||(w=f.doc[P]("div"),z(w),this._vmlEl=w);var A,L=w.style,I=!1,k=1,D=1;if(this[n]&&(A=this[n],k=v(A[0]*A[0]+A[1]*A[1]),D=v(A[2]*A[2]+A[3]*A[3]),I=A[1]||A[2]),I){var R=[c,h],E=[c+d,h],B=[c,h+m],F=[c+d,h+m];T(R,R,A),T(E,E,A),T(B,B,A),T(F,F,A);var G=M(R[0],E[0],B[0],F[0]),Z=M(R[1],E[1],B[1],F[1]),W=[];W.push("M11=",A[0]/k,S,"M12=",A[2]/D,S,"M21=",A[1]/k,S,"M22=",A[3]/D,S,"Dx=",p(c*k+A[4]),S,"Dy=",p(h*D+A[5])),L.padding="0 "+p(G)+"px "+p(Z)+"px 0",L[q]=C+".Matrix("+W.join("")+", SizingMethod=clip)"}else A&&(c=c*k+A[4],h=h*D+A[5]),L[q]="",L.left=p(c)+"px",L.top=p(h)+"px";var j=this._imageEl,U=this._cropEl;j||(j=f.doc[P]("div"),this._imageEl=j);var X=j.style;if(b){if(e&&i)X.width=p(k*e*d/g)+"px",X[Pe]=p(D*i*m/y)+"px";else{var $=new Image,Q=this;$.onload=function(){$.onload=null,e=$.width,i=$[Pe],X.width=p(k*e*d/g)+"px",X[Pe]=p(D*i*m/y)+"px",Q._imageWidth=e,Q._imageHeight=i,Q._imageSrc=a},$.src=a}U||(U=f.doc[P]("div"),U.style.overflow="hidden",this._cropEl=U);var K=U.style;K.width=p((d+x*d/g)*k),K[Pe]=p((m+_*m/y)*D),K[q]=C+".Matrix(Dx="+-x*d/g*k+",Dy="+-_*m/y*D+")",U.parentNode||w.appendChild(U),j.parentNode!=U&&U.appendChild(j)}else X.width=p(k*d)+"px",X[Pe]=p(D*m)+"px",w.appendChild(j),U&&U.parentNode&&(w.removeChild(U),this._cropEl=null);var J="",ee=r[O];1>ee&&(J+=".Alpha(opacity="+p(100*ee)+") "),J+=C+".AlphaImageLoader(src="+a+", SizingMethod=scale)",X[q]=J,w.style.zIndex=H(this[Y],this.z,this.z2),V(t,w),null!=r.text&&this.drawRectText(t,this[N]())}},u[Ie].onRemove=function(t){G(t,this._vmlEl),this._vmlEl=null,this._cropEl=null,this._imageEl=null,this.removeRectText(t)},u[Ie].onAdd=function(t){V(t,this._vmlEl),this.appendRectText(t)};var ee,ie=w,ne={},re=0,ae=100,oe=document[P]("div"),se=function(t){var e=ne[t];if(!e){re>ae&&(re=0,ne={});var i,n=oe.style;try{n.font=t,i=n.fontFamily.split(",")[0]}catch(r){}e={style:n.fontStyle||ie,variant:n.fontVariant||ie,weight:n.fontWeight||ie,size:0|parseFloat(n.fontSize||12),family:i||"Microsoft YaHei"},ne[t]=e,re++}return e};o.measureText=function(t,e){var i=f.doc; +ee||(ee=i[P]("div"),ee.style.cssText="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;",f.doc.body.appendChild(ee));try{ee.style.font=e}catch(n){}return ee.innerHTML="",ee.appendChild(i.createTextNode(t)),{width:ee.offsetWidth}};for(var le=new i,ce=function(t,e,i,r){var a=this.style,s=a.text;if(null!=s&&(s+=""),s){var l,u,c=a[F],h=se(a.textFont),d=h.style+" "+h.variant+" "+h.weight+" "+h.size+'px "'+h.family+'"',v=a.textBaseline,m=a.textVerticalAlign;i=i||o[N](s,d,c,v);var g=this[n];if(g&&!r&&(le.copy(e),le[_](g),e=le),r)l=e.x,u=e.y;else{var x=a.textPosition,b=a.textDistance;if(x instanceof Array)l=e.x+Z(x[0],e.width),u=e.y+Z(x[1],e[Pe]),c=c||"left",v=v||"top";else{var w=o.adjustTextPositionOnRect(x,e,i,b);l=w.x,u=w.y,c=c||w[F],v=v||w.textBaseline}}if(m){switch(m){case B:u-=i[Pe]/2;break;case ye:u-=i[Pe]}v="top"}var M=h.size;switch(v){case"hanging":case"top":u+=M/1.75;break;case B:break;default:u-=M/2.25}switch(c){case"left":break;case E:l-=i.width/2;break;case"right":l-=i.width}var C,A,P,L=f.createNode,I=this._textVmlEl;I?(P=I.firstChild,C=P.nextSibling,A=C.nextSibling):(I=L("line"),C=L("path"),A=L("textpath"),P=L("skew"),A.style["v-text-align"]="left",z(I),C.textpathok=!0,A.on=!0,I.from="0 0",I.to="1000 0.05",V(I,P),V(I,C),V(I,A),this._textVmlEl=I);var k=[l,u],R=I.style;g&&r?(T(k,k,g),P.on=!0,P.matrix=g[0].toFixed(3)+S+g[2].toFixed(3)+S+g[1].toFixed(3)+S+g[3].toFixed(3)+",0,0",P.offset=(p(k[0])||0)+","+(p(k[1])||0),P.origin="0 0",R.left="0px",R.top="0px"):(P.on=!1,R.left=p(l)+"px",R.top=p(u)+"px"),A[Le]=D(s);try{A.style.font=d}catch(G){}Q(I,"fill",{fill:r?a.fill:a.textFill,opacity:a[O]},this),Q(I,y,{stroke:r?a[y]:a.textStroke,opacity:a[O],lineDash:a.lineDash},this),I.style.zIndex=H(this[Y],this.z,this.z2),V(t,I)}},he=function(t){G(t,this._textVmlEl),this._textVmlEl=null},de=function(t){V(t,this._textVmlEl)},fe=[s,l,u,h,c],pe=0;pe<fe[ge];pe++){var ve=fe[pe][Ie];ve.drawRectText=ce,ve.removeRectText=he,ve.appendRectText=de}c[Ie].brushVML=function(t){var e=this.style;null!=e.text?this.drawRectText(t,{x:e.x||0,y:e.y||0,width:0,height:0},this[N](),!0):this.removeRectText(t)},c[Ie].onRemove=function(t){this.removeRectText(t)},c[Ie].onAdd=function(t){this.appendRectText(t)}}}),e("zrender/vml/Painter",[Re,"../core/log","./core"],function(t){function e(t){return parseInt(t,10)}function i(t,e){a.initVML(),this.root=t,this[be]=e;var i=document[P]("div"),n=document[P]("div");i.style.cssText="display:inline-block;overflow:hidden;position:relative;width:300px;height:150px;",n.style.cssText="position:absolute;left:0;top:0;",t.appendChild(i),this._vmlRoot=n,this._vmlViewport=i,this[Ae]();var r=e.delFromMap,o=e.addToMap;e.delFromMap=function(t){var i=e.get(t);r.call(e,t),i&&i.onRemove&&i.onRemove(n)},e.addToMap=function(t){t.onAdd&&t.onAdd(n),o.call(e,t)},this._firstPaint=!0}function n(t){return function(){r('In IE8.0 VML mode painter not support method "'+t+'"')}}var r=t("../core/log"),a=t("./core");i[Ie]={constructor:i,getViewportRoot:function(){return this._vmlViewport},refresh:function(){var t=this[be].getDisplayList(!0,!0);this._paintList(t)},_paintList:function(t){for(var e=this._vmlRoot,i=0;i<t[ge];i++){var n=t[i];n.invisible||n[xe]?(n.__alreadyNotVisible||n.onRemove(e),n.__alreadyNotVisible=!0):(n.__alreadyNotVisible&&n.onAdd(e),n.__alreadyNotVisible=!1,n.__dirty&&(n.beforeBrush&&n.beforeBrush(),(n.brushVML||n.brush).call(n,e),n.afterBrush&&n.afterBrush())),n.__dirty=!1}this._firstPaint&&(this._vmlViewport.appendChild(e),this._firstPaint=!1)},resize:function(t,e){var t=null==t?this._getWidth():t,e=null==e?this._getHeight():e;if(this._width!=t||this._height!=e){this._width=t,this._height=e;var i=this._vmlViewport.style;i.width=t+"px",i[Pe]=e+"px"}},dispose:function(){this.root.innerHTML="",this._vmlRoot=this._vmlViewport=this[be]=null},getWidth:function(){return this._width},getHeight:function(){return this._height},clear:function(){this._vmlViewport&&this.root.removeChild(this._vmlViewport)},_getWidth:function(){var t=this.root,i=t.currentStyle;return(t.clientWidth||e(i.width))-e(i.paddingLeft)-e(i.paddingRight)|0},_getHeight:function(){var t=this.root,i=t.currentStyle;return(t.clientHeight||e(i[Pe]))-e(i.paddingTop)-e(i.paddingBottom)|0}};for(var o=["getLayer","insertLayer","eachLayer","eachBuildinLayer","eachOtherLayer","getLayers","modLayer","delLayer","clearLayer","toDataURL","pathToImage"],s=0;s<o[ge];s++){var l=o[s];i[Ie][l]=n(l)}return i}),e("echarts/component/tooltip/TooltipModel",[Re,"../../echarts"],function(t){t("../../echarts").extendComponentModel({type:"tooltip",defaultOption:{zlevel:0,z:8,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove",alwaysShowContent:!1,confine:!1,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"rgba(50,50,50,0.7)",borderColor:"#333",borderRadius:4,borderWidth:0,padding:5,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:!0,animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",lineStyle:{color:"#555",width:1,type:"solid"},crossStyle:{color:"#555",width:1,type:"dashed",textStyle:{}},shadowStyle:{color:"rgba(150,150,150,0.3)"}},textStyle:{color:"#fff",fontSize:14}}})}),e("echarts/component/tooltip/TooltipView",[Re,"./TooltipContent",u,De,"../../util/format","../../util/number","../../util/model",Oe,"../../model/Model","../../echarts"],function(t){function e(t,e){if(!t||!e)return!1;var i=P.round;return i(t[0])===i(e[0])&&i(t[1])===i(e[1])}function a(t,e,i,n){return{x1:t,y1:e,x2:i,y2:n}}function d(t,e,i,n){return{x:t,y:e,width:i,height:n}}function f(t,e,i,n,r,a){return{cx:t,cy:e,r0:i,r:n,startAngle:r,endAngle:a,clockwise:!0}}function p(t,e,i,n,r){var a=i.clientWidth,o=i.clientHeight,s=20;return t+a+s>n?t-=a+s:t+=s,e+o+s>r?e-=o+s:e+=s,[t,e]}function v(t,e,i,n,r){var a=i.clientWidth,o=i.clientHeight;return t=Math.min(t+a,n)-a,e=Math.min(e+o,r)-o,t=Math.max(t,0),e=Math.max(e,0),[t,e]}function g(t,e,i){var n=i.clientWidth,r=i.clientHeight,a=5,o=0,s=0,l=e.width,u=e[Pe];switch(t){case m:o=e.x+l/2-n/2,s=e.y+u/2-r/2;break;case"top":o=e.x+l/2-n/2,s=e.y-r-a;break;case ye:o=e.x+l/2-n/2,s=e.y+u+a;break;case"left":o=e.x-n-a,s=e.y+u/2-r/2;break;case"right":o=e.x+l+a,s=e.y+u/2-r/2}return[o,s]}function x(t,e,r,a,o,s,l,u){var c=u[Te](),h=u[Me](),d=l&&l[N]().clone();if(l&&d[_](l[n]),typeof t===j&&(t=t([e,r],s,o.el,d)),C[U](t))e=I(t[0],c),r=I(t[1],h);else if(typeof t===Le&&l){var f=g(t,d,o.el);e=f[0],r=f[1]}else{var f=p(e,r,o.el,c,h);e=f[0],r=f[1]}if(a){var f=v(e,r,o.el,c,h);e=f[0],r=f[1]}o[i](e,r)}function w(t){var e=t[ve],i=t.get("tooltip.trigger",!0);return!(!e||"cartesian2d"!==e.type&&"polar"!==e.type&&"singleAxis"!==e.type||"item"===i)}var T=t("./TooltipContent"),S=t(u),C=t(De),A=t("../../util/format"),P=t("../../util/number"),L=t("../../util/model"),I=P.parsePercent,k=t(Oe),D=t("../../model/Model");t("../../echarts").extendComponentView({type:"tooltip",_axisPointers:{},init:function(t,e){if(!k.node){var i=new T(e.getDom(),e);this._tooltipContent=i,e.on("showTip",this._manuallyShowTip,this),e.on("hideTip",this._manuallyHideTip,this)}},render:function(t,e,i){if(!k.node){this.group[H](),this._axisPointers={},this._tooltipModel=t,this._ecModel=e,this._api=i,this._lastHover={};var n=this._tooltipContent;n[ce](),n.enterable=t.get("enterable"),this._alwaysShowContent=t.get("alwaysShowContent"),this._seriesGroupByAxis=this._prepareAxisTriggerData(t,e);var r=this._crossText;r&&this.group.add(r);var a=t.get("triggerOn");if(null!=this._lastX&&null!=this._lastY&&"none"!==a){var o=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout(function(){o._manuallyShowTip({x:o._lastX,y:o._lastY})})}var s=this._api.getZr();s.off("click",this._tryShow),s.off("mousemove",this._mousemove),s.off(te,this._hide),s.off("globalout",this._hide),"click"===a?s.on("click",this._tryShow,this):"mousemove"===a&&(s.on("mousemove",this._mousemove,this),s.on(te,this._hide,this),s.on("globalout",this._hide,this))}},_mousemove:function(t){var e=this._tooltipModel.get("showDelay"),i=this;clearTimeout(this._showTimeout),e>0?this._showTimeout=setTimeout(function(){i._tryShow(t)},e):this._tryShow(t)},_manuallyShowTip:function(t){function e(e){var i=e[pe](),n=L.queryDataIndex(i,t);return null!=n&&!C[U](n)&&i.hasValue(n)?!0:void 0}if(t.from!==this.uid){var i=this._ecModel,r=t.seriesIndex,a=i.getSeriesByIndex(r),o=this._api,l="axis"===this._tooltipModel.get(re);if(null==t.x||null==t.y){if(l?(a&&!e(a)&&(a=null),a||i.eachSeries(function(t){w(t)&&!a&&e(t)&&(a=t)})):a=a||i.getSeriesByIndex(0),a){var u=a[pe](),h=L.queryDataIndex(u,t);if(null==h||C[U](h))return;var d,f,p=u[b](h),v=a[ve];if(a.getTooltipPosition){var m=a.getTooltipPosition(h)||[];d=m[0],f=m[1]}else if(v&&v[s]){var m=v[s](u.getValues(C.map(v[c],function(t){return a.coordDimToDataDim(t)[0]}),h,!0));d=m&&m[0],f=m&&m[1]}else if(p){var g=p[N]().clone();g[_](p[n]),d=g.x+g.width/2,f=g.y+g[Pe]/2}null!=d&&null!=f&&this._tryShow({offsetX:d,offsetY:f,position:t[R],target:p,event:{}})}}else{var p=o.getZr().handler.findHover(t.x,t.y);this._tryShow({offsetX:t.x,offsetY:t.y,position:t[R],target:p,event:{}})}}},_manuallyHideTip:function(t){t.from!==this.uid&&this._hide()},_prepareAxisTriggerData:function(t,e){var i={};return e.eachSeries(function(t){if(w(t)){var e,n,r=t[ve];"cartesian2d"===r.type?(e=r.getBaseAxis(),n=e.dim+e.index):"singleAxis"===r.type?(e=r[o](),n=e.dim+e.type):(e=r.getBaseAxis(),n=e.dim+r.name),i[n]=i[n]||{coordSys:[],series:[]},i[n].coordSys.push(r),i[n][ne].push(t)}},this),i},_tryShow:function(t){var e=t[J],i=this._tooltipModel,n=i.get(re),r=this._ecModel,a=this._api;if(i)if(this._lastX=t.offsetX,this._lastY=t.offsetY,e&&null!=e[fe]){var o=e.dataModel||r.getSeriesByIndex(e.seriesIndex),s=e[fe],l=o[pe]()[h](s);"axis"===(l.get("tooltip.trigger")||n)?this._showAxisTooltip(i,r,t):(this._ticket="",this._hideAxisPointer(),this._resetLastHover(),this._showItemTooltipContent(o,s,e.dataType,t)),a.dispatchAction({type:"showTip",from:this.uid,dataIndexInside:e[fe],seriesIndex:e.seriesIndex})}else if(e&&e.tooltip){var u=e.tooltip;if(typeof u===Le){var c=u;u={content:c,formatter:c}}var d=new D(u,i),f=d.get("content"),p=Math.random();this._showTooltipContent(d,f,d.get("formatterParams")||{},p,t.offsetX,t.offsetY,t[R],e,a)}else"item"===n?this._hide():this._showAxisTooltip(i,r,t),"cross"===i.get("axisPointer.type")&&a.dispatchAction({type:"showTip",from:this.uid,x:t.offsetX,y:t.offsetY})},_showAxisTooltip:function(t,i,n){var r=t[Se]("axisPointer"),a=r.get("type");if("cross"===a){var o=n[J];if(o&&null!=o[fe]){var l=i.getSeriesByIndex(o.seriesIndex),u=o[fe];this._showItemTooltipContent(l,u,o.dataType,n)}}this._showAxisPointer();var h=!0;C.each(this._seriesGroupByAxis,function(i){var o=i.coordSys,l=o[0],u=[n.offsetX,n.offsetY];if(!l.containPoint(u))return void this._hideAxisPointer(l.name);h=!1;var d=l[c],f=l.pointToData(u,!0);u=l[s](f);var p=l.getBaseAxis(),v=r.get("axis");"auto"===v&&(v=p.dim);var m=!1,g=this._lastHover;if("cross"===a)e(g.data,f)&&(m=!0),g.data=f;else{var y=C[me](d,v);g.data===f[y]&&(m=!0),g.data=f[y]}var x=t.get(Ce);"cartesian2d"!==l.type||m?"polar"!==l.type||m?"singleAxis"!==l.type||m||this._showSinglePointer(r,l,v,u,x):this._showPolarPointer(r,l,v,u,x):this._showCartesianPointer(r,l,v,u,x),"cross"!==a&&this._dispatchAndShowSeriesTooltipContent(l,i[ne],u,f,m,n[R])},this),this._tooltipModel.get("show")||this._hideAxisPointer(),h&&this._hide()},_showCartesianPointer:function(t,e,i,n,s){function l(i,n,r){var o="x"===i?a(n[0],r[0],n[0],r[1]):a(r[0],n[1],r[1],n[1]),s=c._getPointerElement(e,t,i,o);S.subPixelOptimizeLine({shape:o,style:s.style}),p?S.updateProps(s,{shape:o},t):s.attr({shape:o})}function u(i,n,r){var a=e[o](i),s=a.getBandWidth(),l=r[1]-r[0],u="x"===i?d(n[0]-s/2,r[0],s,l):d(r[0],n[1]-s/2,l,s),h=c._getPointerElement(e,t,i,u);p?S.updateProps(h,{shape:u},t):h.attr({shape:u})}var c=this,h=t.get("type"),f=e.getBaseAxis(),p=s&&"cross"!==h&&f.type===r&&f.getBandWidth()>20;if("cross"===h)l("x",n,e[o]("y").getGlobalExtent()),l("y",n,e[o]("x").getGlobalExtent()),this._updateCrossText(e,n,t);else{var v=e[o]("x"===i?"y":"x"),m=v.getGlobalExtent();"cartesian2d"===e.type&&("line"===h?l:u)(i,n,m)}},_showSinglePointer:function(t,e,i,n,s){function l(i,n,r){var s=e[o](),l=s.orient,c="horizontal"===l?a(n[0],r[0],n[0],r[1]):a(r[0],n[1],r[1],n[1]),d=u._getPointerElement(e,t,i,c);h?S.updateProps(d,{shape:c},t):d.attr({shape:c})}var u=this,c=t.get("type"),h=s&&"cross"!==c&&e.getBaseAxis().type===r,d=e.getRect(),f=[d.y,d.y+d[Pe]];l(i,n,f)},_showPolarPointer:function(t,e,i,n,s){function u(i,n,r){var o,s=e.pointToCoord(n);if("angle"===i){var l=e.coordToPoint([r[0],s[1]]),u=e.coordToPoint([r[1],s[1]]);o=a(l[0],l[1],u[0],u[1])}else o={cx:e.cx,cy:e.cy,r:s[0]};var c=h._getPointerElement(e,t,i,o);m?S.updateProps(c,{shape:o},t):c.attr({shape:o})}function c(i,n,r){var a,s=e[o](i),l=s.getBandWidth(),u=e.pointToCoord(n),c=Math.PI/180;a="angle"===i?f(e.cx,e.cy,r[0],r[1],(-u[1]-l/2)*c,(-u[1]+l/2)*c):f(e.cx,e.cy,u[0]-l/2,u[0]+l/2,0,2*Math.PI);var d=h._getPointerElement(e,t,i,a);m?S.updateProps(d,{shape:a},t):d.attr({shape:a})}var h=this,d=t.get("type"),p=e.getAngleAxis(),v=e.getRadiusAxis(),m=s&&"cross"!==d&&e.getBaseAxis().type===r;if("cross"===d)u("angle",n,v[z]()),u(l,n,p[z]()),this._updateCrossText(e,n,t);else{var g=e[o](i===l?"angle":l),y=g[z]();("line"===d?u:c)(i,n,y)}},_updateCrossText:function(t,e,i){var n=i[Se]("crossStyle"),a=n[Se](G),s=this._tooltipModel,l=this._crossText;l||(l=this._crossText=new S.Text({style:{textAlign:"left",textVerticalAlign:"bottom"}}),this.group.add(l));var u=t.pointToData(e),h=t[c];u=C.map(u,function(e,i){var n=t[o](h[i]);return e=n.type===r||"time"===n.type?n.scale.getLabel(e):A.addCommas(e.toFixed(n.getPixelPrecision()))}),l[$]({fill:a.getTextColor()||n.get("color"),textFont:a[V](),text:u.join(", "),x:e[0]+5,y:e[1]-5}),l.z=s.get("z"),l[Y]=s.get(Y)},_getPointerElement:function(t,e,i,n){var r=this._tooltipModel,a=r.get("z"),o=r.get(Y),s=this._axisPointers,u=t.name;if(s[u]=s[u]||{},s[u][i])return s[u][i];var c=e.get("type"),h=e[Se](c+"Style"),d="shadow"===c,f=h[d?"getAreaStyle":"getLineStyle"](),p="polar"===t.type?d?"Sector":i===l?"Circle":"Line":d?"Rect":"Line";d?f[y]=null:f.fill=null;var v=s[u][i]=new S[p]({style:f,z:a,zlevel:o,silent:!0,shape:n});return this.group.add(v),v},_dispatchAndShowSeriesTooltipContent:function(t,e,i,n,a,o){var s,u=this._tooltipModel,c=t.getBaseAxis(),h="x"===c.dim||c.dim===l?0:1,d=C.map(e,function(t){return{seriesIndex:t.seriesIndex,dataIndexInside:t.getAxisTooltipDataIndex?t.getAxisTooltipDataIndex(t.coordDimToDataDim(c.dim),n,c):t[pe]().indexOfNearest(t.coordDimToDataDim(c.dim)[0],n[h],!1,c.type===r?.5:null)}});C.each(d,function(t,i){e[i][pe]().hasValue(t.dataIndexInside)&&(s=i)}),s=s||0;var f=this._lastHover,p=this._api;if(f.payloadBatch&&!a&&p.dispatchAction({type:"downplay",batch:f.payloadBatch}),a||(p.dispatchAction({type:"highlight",batch:d}),f.payloadBatch=d),p.dispatchAction({type:"showTip",dataIndexInside:d[s].dataIndexInside,seriesIndex:d[s].seriesIndex,from:this.uid}),c&&u.get("showContent")&&u.get("show")){var v=C.map(e,function(t,e){return t[K](d[e].dataIndexInside)});if(a)x(o||u.get(R),i[0],i[1],u.get("confine"),this._tooltipContent,v,null,p);else{var m=d[s].dataIndexInside,g="time"===c.type?c.scale.getLabel(n[h]):e[s][pe]().getName(m),y=(g?g+"<br />":"")+C.map(e,function(t,e){return t.formatTooltip(d[e].dataIndexInside,!0)}).join("<br />"),_="axis_"+t.name+"_"+m;this._showTooltipContent(u,y,v,_,i[0],i[1],o,null,p)}}},_showItemTooltipContent:function(t,e,i,n){var r=this._api,a=t[pe](i),o=a[h](e),s=o.get("tooltip",!0);if(typeof s===Le){var l=s;s={formatter:l}}var u=this._tooltipModel,c=t[Se]("tooltip",u),d=new D(s,c,c[M]),f=t[K](e,i),p=t.formatTooltip(e,!1,i),v="item_"+t.name+"_"+e;this._showTooltipContent(d,p,f,v,n.offsetX,n.offsetY,n[R],n[J],r)},_showTooltipContent:function(t,e,i,n,r,a,o,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent,c=t.get("confine"),h=t.get("formatter");o=o||t.get(R);var d=e;if(h)if(typeof h===Le)d=A.formatTpl(h,i);else if(typeof h===j){var f=this,p=n,v=function(t,e){t===f._ticket&&(u.setContent(e),x(o,r,a,c,u,i,s,l))};f._ticket=p,d=h(i,p,v)}u.show(t),u.setContent(d),x(o,r,a,c,u,i,s,l)}},_showAxisPointer:function(t){if(t){var e=this._axisPointers[t];e&&C.each(e,function(t){t.show()})}else this.group.eachChild(function(t){t.show()}),this.group.show()},_resetLastHover:function(){var t=this._lastHover;t.payloadBatch&&this._api.dispatchAction({type:"downplay",batch:t.payloadBatch}),this._lastHover={}},_hideAxisPointer:function(t){if(t){var e=this._axisPointers[t];e&&C.each(e,function(t){t.hide()})}else this.group.children()[ge]&&this.group.hide()},_hide:function(){clearTimeout(this._showTimeout),this._hideAxisPointer(),this._resetLastHover(),this._alwaysShowContent||this._tooltipContent.hideLater(this._tooltipModel.get("hideDelay")),this._api.dispatchAction({type:"hideTip",from:this.uid}),this._lastX=this._lastY=null},dispose:function(t,e){if(!k.node){var i=e.getZr();this._tooltipContent.hide(),i.off("click",this._tryShow),i.off("mousemove",this._mousemove),i.off(te,this._hide),i.off("globalout",this._hide),e.off("showTip",this._manuallyShowTip),e.off("hideTip",this._manuallyHideTip)}}})}),e("echarts/component/toolbox/ToolboxModel",[Re,"./featureManager",De,"../../echarts"],function(t){var e=t("./featureManager"),i=t(De),n=t("../../echarts").extendComponentModel({type:"toolbox",layoutMode:{type:"box",ignoreSize:!0},mergeDefaultAndTheme:function(){n.superApply(this,"mergeDefaultAndTheme",arguments),i.each(this[C].feature,function(t,n){var r=e.get(n);r&&i.merge(t,r.defaultOption)})},defaultOption:{show:!0,z:6,zlevel:0,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:"#ccc",borderWidth:0,padding:5,itemSize:15,itemGap:8,showTitle:!0,iconStyle:{normal:{borderColor:"#666",color:"none"},emphasis:{borderColor:"#3E98C5"}}}});return n}),e("echarts/component/toolbox/ToolboxView",[Re,"./featureManager",De,u,"../../model/Model","../../data/DataDiffer","../helper/listComponent","zrender/contain/text","../../echarts"],function(t){function e(t){return 0===t[me]("my")}var i=t("./featureManager"),n=t(De),r=t(u),a=t("../../model/Model"),o=t("../../data/DataDiffer"),s=t("../helper/listComponent"),l=t("zrender/contain/text");return t("../../echarts").extendComponentView({type:"toolbox",render:function(t,u,c,h){function d(n,r){var o,s=x[n],l=x[r],d=m[s],p=new a(d,t,t[M]);if(s&&!l){if(e(s))o={model:p,onclick:p[C].onclick,featureName:s};else{var v=i.get(s);if(!v)return;o=new v(p,u,c)}g[s]=o}else{if(o=g[l],!o)return;o.model=p,o[M]=u,o.api=c}return!s&&l?void(o.dispose&&o.dispose(u,c)):!p.get("show")||o.unusable?void(o[se]&&o[se](u,c)):(f(p,o,s),p.setIconStatus=function(t,e){var i=this[C],n=this.iconPaths;i.iconStatus=i.iconStatus||{},i.iconStatus[t]=e,n[t]&&n[t][re](e)},void(o.render&&o.render(p,u,c,h)))}function f(e,i,a){var o=e[Se]("iconStyle"),s=i.getIcons?i.getIcons():e.get("icon"),l=e.get("title")||{};if(typeof s===Le){var h=s,d=l;s={},l={},s[a]=h,l[a]=d}var f=e.iconPaths={};n.each(s,function(a,s){var h=o[Se](w).getItemStyle(),d=o[Se]("emphasis").getItemStyle(),m={x:-v/2,y:-v/2,width:v,height:v},g=0===a[me]("image://")?(m.image=a.slice(8),new r.Image({style:m})):r.makePath(a[X]("path://",""),{style:h,hoverStyle:d,rectHover:!0},m,E);r.setHoverStyle(g),t.get("showTitle")&&(g.__title=l[s],g.on(ee,function(){var t=o[Se]("emphasis").getItemStyle();g[$]({text:l[s],textPosition:t.textPosition||ye,textFill:t.fill||t[y]||"#000",textAlign:t[F]||E})}).on(te,function(){g[$]({textFill:null})})),g[re](e.get("iconStatus."+s)||w),p.add(g),g.on("click",n.bind(i.onclick,i,u,c,s)),f[s]=g})}var p=this.group;if(p[H](),t.get("show")){var v=+t.get("itemSize"),m=t.get("feature")||{},g=this._features||(this._features={}),x=[];n.each(m,function(t,e){x.push(e)}),new o(this._featureNames||[],x).add(d)[ce](d)[se](n.curry(d,null)).execute(),this._featureNames=x,s.layout(p,t,c),s.addBackground(p,t),p.eachChild(function(t){var e=t.__title,i=t.hoverStyle;if(i&&e){var n=l[N](e,i.font),r=t[R][0]+p[R][0],a=t[R][1]+p[R][1]+v,o=!1;a+n[Pe]>c[Me]()&&(i.textPosition="top",o=!0);var s=o?-5-n[Pe]:v+8;r+n.width/2>c[Te]()?(i.textPosition=["100%",s],i[F]="right"):r-n.width/2<0&&(i.textPosition=[0,s],i[F]="left")}})}},updateView:function(t,e,i,r){n.each(this._features,function(t){t.updateView&&t.updateView(t.model,e,i,r)})},updateLayout:function(t,e,i,r){n.each(this._features,function(t){t.updateLayout&&t.updateLayout(t.model,e,i,r)})},remove:function(t,e){n.each(this._features,function(i){i[se]&&i[se](t,e)}),this.group[H]()},dispose:function(t,e){n.each(this._features,function(i){i.dispose&&i.dispose(t,e)})}})}),e("echarts/component/toolbox/feature/SaveAsImage",[Re,Oe,"../featureManager"],function(t){function e(t){this.model=t}var i=t(Oe);e.defaultOption={show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:"保存为图片",type:"png",name:"",excludeComponents:["toolbox"],pixelRatio:1,lang:["右键另存为图片"]},e[Ie].unusable=!i[we];var n=e[Ie];return n.onclick=function(t,e){var n=this.model,r=n.get("name")||t.get("title.0.text")||"echarts",a=document[P]("a"),o=n.get("type",!0)||"png";a.download=r+"."+o,a[J]="_blank";var s=e.getConnectedDataURL({type:o,backgroundColor:n.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",excludeComponents:n.get("excludeComponents"),pixelRatio:n.get("pixelRatio")});if(a.href=s,typeof MouseEvent!==j||i.browser.ie||i.browser.edge){var l=n.get("lang"),u='<body style="margin:0;"><img src="'+s+'" style="max-width:100%;" title="'+(l&&l[0]||"")+'" /></body>',c=window.open();c.document.write(u)}else{var h=new MouseEvent("click",{view:window,bubbles:!0,cancelable:!1});a.dispatchEvent(h)}},t("../featureManager").register("saveAsImage",e),e}),e("echarts/component/toolbox/feature/MagicType",[Re,De,"../../../echarts","../featureManager"],function(t){function e(t){this.model=t}var i=t(De);e.defaultOption={show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z",tiled:"M2.3,2.2h22.8V25H2.3V2.2z M35,2.2h22.8V25H35V2.2zM2.3,35h22.8v22.8H2.3V35z M35,35h22.8v22.8H35V35z"},title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"},option:{},seriesIndex:{}};var n=e[Ie];n.getIcons=function(){var t=this.model,e=t.get("icon"),n={};return i.each(t.get("type"),function(t){e[t]&&(n[t]=e[t])}),n};var r={line:function(t,e,n,r){return"bar"===t?i.merge({id:e,type:"line",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},r.get("option.line")||{},!0):void 0},bar:function(t,e,n,r){return"line"===t?i.merge({id:e,type:"bar",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},r.get("option.bar")||{},!0):void 0},stack:function(t,e,n,r){return"line"===t||"bar"===t?i.merge({id:e,stack:"__ec_magicType_stack__"},r.get("option.stack")||{},!0):void 0},tiled:function(t,e,n,r){return"line"===t||"bar"===t?i.merge({id:e,stack:""},r.get("option.tiled")||{},!0):void 0}},a=[["line","bar"],["stack","tiled"]];n.onclick=function(t,e,n){var o=this.model,s=o.get("seriesIndex."+n);if(r[n]){var l={series:[]},u=function(e){var a=e.subType,s=e.id,u=r[n](a,s,e,o);u&&(i[ae](u,e[C]),l[ne].push(u));var c=e[ve];if(c&&"cartesian2d"===c.type&&("line"===n||"bar"===n)){var h=c.getAxesByScale(d)[0];if(h){var f=h.dim,p=f+"Axis",v=t[S]({mainType:p,index:e.get(name+"Index"),id:e.get(name+"Id")})[0],m=v[T];l[p]=l[p]||[];for(var g=0;m>=g;g++)l[p][m]=l[p][m]||{};l[p][m].boundaryGap="bar"===n?!0:!1}}};i.each(a,function(t){i[me](t,n)>=0&&i.each(t,function(t){o.setIconStatus(t,w)})}),o.setIconStatus(n,"emphasis"),t[_e]({mainType:"series",query:null==s?null:{seriesIndex:s}},u),e.dispatchAction({type:"changeMagicType",currentType:n,newOption:l})}};var o=t("../../../echarts");return o.registerAction({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},function(t,e){e.mergeOption(t.newOption)}),t("../featureManager").register("magicType",e),e}),e("echarts/component/toolbox/feature/DataView",[Re,De,"zrender/core/event","../featureManager","../../../echarts"],function(t){function e(t){var e={},i=[],n=[];return t.eachRawSeries(function(t){var a=t[ve];if(!a||"cartesian2d"!==a.type&&"polar"!==a.type)i.push(t);else{var o=a.getBaseAxis();if(o.type===r){var s=o.dim+"_"+o.index;e[s]||(e[s]={categoryAxis:o,valueAxis:a.getOtherAxis(o),series:[]},n.push({axisDim:o.dim,axisIndex:o.index})),e[s][ne].push(t)}else i.push(t)}}),{seriesGroupByCategoryAxis:e,other:i,meta:n}}function i(t){var e=[];return p.each(t,function(t){var i=t.categoryAxis,n=t.valueAxis,r=n.dim,a=[" "][A](p.map(t[ne],function(t){return t.name})),o=[i.model.getCategories()];p.each(t[ne],function(t){o.push(t.getRawData().mapArray(r,function(t){return t}))});for(var s=[a.join(g)],l=0;l<o[0][ge];l++){for(var u=[],c=0;c<o[ge];c++)u.push(o[c][l]);s.push(u.join(g))}e.push(s.join("\n"))}),e.join("\n\n"+m+"\n\n")}function n(t){return p.map(t,function(t){var e=t.getRawData(),i=[t.name],n=[];return e.each(e[c],function(){for(var t=arguments[ge],r=arguments[t-1],a=e.getName(r),o=0;t-1>o;o++)n[o]=arguments[o];i.push((a?a+g:"")+n.join(g))}),i.join("\n")}).join("\n\n"+m+"\n\n")}function a(t){var r=e(t);return{value:p[q]([i(r.seriesGroupByCategoryAxis),n(r.other)],function(t){return t[X](/[\n\t\s]/g,"")}).join("\n\n"+m+"\n\n"),meta:r.meta}}function o(t){return t[X](/^\s\s*/,"")[X](/\s\s*$/,"")}function s(t){var e=t.slice(0,t[me]("\n"));return e[me](g)>=0?!0:void 0}function l(t){for(var e=t.split(/\n+/g),i=o(e.shift()).split(y),n=[],r=p.map(i,function(t){return{name:t,data:[]}}),a=0;a<e[ge];a++){var s=o(e[a]).split(y);n.push(s.shift());for(var l=0;l<s[ge];l++)r[l]&&(r[l].data[a]=s[l])}return{series:r,categories:n}}function u(t){for(var e=t.split(/\n+/g),i=o(e.shift()),n=[],r=0;r<e[ge];r++){var a,s=o(e[r]).split(y),l="",u=!1;isNaN(s[0])?(u=!0,l=s[0],s=s.slice(1),n[r]={name:l,value:[]},a=n[r].value):a=n[r]=[];for(var c=0;c<s[ge];c++)a.push(+s[c]);1===a[ge]&&(u?n[r].value=a[0]:n[r]=a[0])}return{name:i,data:n}}function h(t,e){var i=t.split(new RegExp("\n*"+m+"\n*","g")),n={series:[]};return p.each(i,function(t,i){if(s(t)){var r=l(t),a=e[i],o=a.axisDim+"Axis";a&&(n[o]=n[o]||[],n[o][a.axisIndex]={data:r.categories},n[ne]=n[ne][A](r[ne]))}else{var r=u(t);n[ne].push(r)}}),n}function d(t){this._dom=null,this.model=t}function f(t,e){return p.map(t,function(t,i){var n=e&&e[i];return p[le](n)&&!p[U](n)?(p[le](t)&&!p[U](t)&&(t=t.value),p[ae]({value:t},n)):t})}var p=t(De),v=t("zrender/core/event"),m=new Array(60).join("-"),g=" ",y=new RegExp("["+g+"]+","g");return d.defaultOption={show:!0,readOnly:!1,optionToContent:null,contentToOption:null,icon:"M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28",title:"数据视图",lang:["数据视图","关闭","刷新"],backgroundColor:"#fff",textColor:"#000",textareaColor:"#fff",textareaBorderColor:"#333",buttonColor:"#c23531",buttonTextColor:"#fff"},d[Ie].onclick=function(t,e){function i(){n.removeChild(o),T._dom=null}var n=e.getDom(),r=this.model;this._dom&&n.removeChild(this._dom);var o=document[P]("div");o.style.cssText="position:absolute;left:5px;top:5px;bottom:5px;right:5px;",o.style.backgroundColor=r.get("backgroundColor")||"#fff";var s=document[P]("h4"),l=r.get("lang")||[];s.innerHTML=l[0]||r.get("title"),s.style.cssText="margin: 10px 20px;",s.style.color=r.get("textColor");var u=document[P]("div"),c=document[P]("textarea");u.style.cssText="display:block;width:100%;overflow:hidden;";var d=r.get("optionToContent"),f=r.get("contentToOption"),m=a(t);if(typeof d===j){var y=d(e.getOption());typeof y===Le?u.innerHTML=y:p.isDom(y)&&u.appendChild(y)}else u.appendChild(c),c.readOnly=r.get("readOnly"),c.style.cssText="width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;",c.style.color=r.get("textColor"),c.style.borderColor=r.get("textareaBorderColor"),c.style.backgroundColor=r.get("textareaColor"),c.value=m.value;var x=m.meta,_=document[P]("div");_.style.cssText="position:absolute;bottom:0;left:0;right:0;";var b="float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px",w=document[P]("div"),M=document[P]("div");b+=";background-color:"+r.get("buttonColor"),b+=";color:"+r.get("buttonTextColor");var T=this;v.addEventListener(w,"click",i),v.addEventListener(M,"click",function(){var t;try{t=typeof f===j?f(u,e.getOption()):h(c.value,x)}catch(n){throw i(),new Error("Data view format error "+n)}t&&e.dispatchAction({type:"changeDataView",newOption:t}),i()}),w.innerHTML=l[1],M.innerHTML=l[2],M.style.cssText=b,w.style.cssText=b,!r.get("readOnly")&&_.appendChild(M),_.appendChild(w),v.addEventListener(c,"keydown",function(t){if(9===(t.keyCode||t.which)){var e=this.value,i=this.selectionStart,n=this.selectionEnd;this.value=e.substring(0,i)+g+e.substring(n),this.selectionStart=this.selectionEnd=i+1,v.stop(t)}}),o.appendChild(s),o.appendChild(u),o.appendChild(_),u.style[Pe]=n.clientHeight-80+"px",n.appendChild(o),this._dom=o},d[Ie][se]=function(t,e){this._dom&&e.getDom().removeChild(this._dom)},d[Ie].dispose=function(t,e){this[se](t,e)},t("../featureManager").register("dataView",d),t("../../../echarts").registerAction({type:"changeDataView",event:"dataViewChanged",update:"prepareAndUpdate"},function(t,e){var i=[];p.each(t.newOption[ne],function(t){var n=e.getSeriesByName(t.name)[0];if(n){var r=n.get("data");i.push({name:t.name,data:f(t.data,r)})}else i.push(p[oe]({type:"scatter"},t))}),e.mergeOption(p[ae]({series:i},t.newOption))}),d}),e("echarts/component/toolbox/feature/DataZoom",[Re,De,"../../helper/BrushController","../../helper/brushHelper","../../dataZoom/history","../../dataZoomSelect","../featureManager","../../../echarts"],function(t){function e(t,e,i){(this._brushController=new o(i.getZr())).on("brush",a.bind(this._onBrush,this)).mount(),this._isZoomActive}function i(t){var e={};return a.each(["xAxisIndex","yAxisIndex"],function(i){e[i]=t[i],null==e[i]&&(e[i]="all"),(e[i]===!1||"none"===e[i])&&(e[i]=[])}),e}function n(t,e){t.setIconStatus("back",l.count(e)>1?"emphasis":w)}function r(t,e,n,r){var a=n._isZoomActive;r&&"takeGlobalCursor"===r.type&&(a="dataZoomSelect"===r.key?r.dataZoomSelectActive:!1),n._isZoomActive=a,t.setIconStatus("zoom",a?"emphasis":w);var o=s.makeCoordInfoList(i(t[C]),e),l=o.xAxisHas&&!o.yAxisHas?"lineX":!o.xAxisHas&&o.yAxisHas?"lineY":"rect";n._brushController.setPanels(s.makePanelOpts(o)).enableBrush(a?{brushType:l,brushStyle:{lineWidth:0,fill:"rgba(0,0,0,0.2)"}}:!1)}var a=t(De),o=t("../../helper/BrushController"),s=t("../../helper/brushHelper"),l=t("../../dataZoom/history"),u=a.each;t("../../dataZoomSelect");var c="\x00_ec_\x00toolbox-dataZoom_";e.defaultOption={show:!0,icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:{zoom:"区域缩放",back:"区域缩放还原"}};var h=e[Ie];h.render=function(t,e,i,a){this.model=t,this[M]=e,this.api=i,r(t,e,this,a),n(t,e)},h.onclick=function(t,e,i){d[i].call(this)},h[se]=function(){this._brushController.unmount()},h.dispose=function(){this._brushController.dispose()};var d={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(l.pop(this[M]))}};return h._onBrush=function(t,e){function n(t,e,i){var n=r(t,i[t],o);n&&(a[n.id]={dataZoomId:n.id,startValue:e[0],endValue:e[1]}) +}function r(t,e,i){var n;return i[_e]({mainType:"dataZoom",subType:"select"},function(r){var a=r.get(t+"Index");null!=a&&i.getComponent(t,a)===e&&(n=r)}),n}if(e.isEnd&&t[ge]){var a={},o=this[M];this._brushController.updateCovers([]);var u=s.makeCoordInfoList(i(this.model[C]),o),c=[];s.parseOutputRanges(t,u,o,c);var h=t[0],d=c[0],f=h.coordRange,p=h.brushType;if(d&&f)if("rect"===p)n("xAxis",f[0],d),n("yAxis",f[1],d);else{var v={lineX:"xAxis",lineY:"yAxis"};n(v[p],f,d)}l.push(o,a),this._dispatchZoomAction(a)}},h._dispatchZoomAction=function(t){var e=[];u(t,function(t){e.push(a.clone(t))}),e[ge]&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},t("../featureManager").register("dataZoom",e),t("../../../echarts").registerPreprocessor(function(t){function e(t,e){if(e){var r=t+"Index",o=e[r];null==o||"all"==o||a[U](o)||(o=o===!1||"none"===o?[]:[o]),i(t,function(e,i){if(null==o||"all"==o||-1!==a[me](o,i)){var s={type:"select",$fromToolbox:!0,id:c+t+i};s[r]=i,n.push(s)}})}}function i(e,i){var n=t[e];a[U](n)||(n=n?[n]:[]),u(n,i)}if(t){var n=t.dataZoom||(t.dataZoom=[]);a[U](n)||(t.dataZoom=n=[n]);var r=t.toolbox;if(r&&(a[U](r)&&(r=r[0]),r&&r.feature)){var o=r.feature.dataZoom;e("xAxis",o),e("yAxis",o)}}}),e}),e("echarts/component/toolbox/feature/Restore",[Re,"../../dataZoom/history","../featureManager","../../../echarts"],function(t){function e(t){this.model=t}var i=t("../../dataZoom/history");e.defaultOption={show:!0,icon:"M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5",title:"还原"};var n=e[Ie];return n.onclick=function(t,e){i.clear(t),e.dispatchAction({type:"restore",from:this.uid})},t("../featureManager").register("restore",e),t("../../../echarts").registerAction({type:"restore",event:"restore",update:"prepareAndUpdate"},function(t,e){e.resetOption("recreate")}),e}),e("echarts/scale/Interval",[Re,"../util/number","../util/format","./Scale"],function(t){var e=t("../util/number"),i=t("../util/format"),n=t("./Scale"),r=Math.floor,a=Math.ceil,o=e.getPrecisionSafe,s=e.round,l=n[oe]({type:"interval",_interval:0,setExtent:function(t,e){var i=this._extent;isNaN(t)||(i[0]=parseFloat(t)),isNaN(e)||(i[1]=parseFloat(e))},unionExtent:function(t){var e=this._extent;t[0]<e[0]&&(e[0]=t[0]),t[1]>e[1]&&(e[1]=t[1]),l[Ie].setExtent.call(this,e[0],e[1])},getInterval:function(){return this._interval||this.niceTicks(),this._interval},setInterval:function(t){this._interval=t,this._niceExtent=this._extent.slice()},getTicks:function(){this._interval||this.niceTicks();var t=this._interval,e=this._extent,i=[],n=1e4;if(t){var r=this._niceExtent,a=o(t)+2;e[0]<r[0]&&i.push(e[0]);for(var l=r[0];l<=r[1];)if(i.push(l),l=s(l+t,a),i[ge]>n)return[];e[1]>(i[ge]?i[i[ge]-1]:r[1])&&i.push(e[1])}return i},getTicksLabels:function(){for(var t=[],e=this[k](),i=0;i<e[ge];i++)t.push(this.getLabel(e[i]));return t},getLabel:function(t){return i.addCommas(t)},niceTicks:function(t){t=t||5;var i=this._extent,n=i[1]-i[0];if(isFinite(n)){0>n&&(n=-n,i.reverse());var l=s(e.nice(n/t,!0),Math.max(o(i[0]),o(i[1]))+2),u=o(l)+2,c=[s(a(i[0]/l)*l,u),s(r(i[1]/l)*l,u)];this._interval=l,this._niceExtent=c}},niceExtent:function(t,e,i){var n=this._extent;if(n[0]===n[1])if(0!==n[0]){var o=n[0];i?n[0]-=o/2:(n[1]+=o/2,n[0]-=o/2)}else n[1]=1;var l=n[1]-n[0];isFinite(l)||(n[0]=0,n[1]=1),this.niceTicks(t);var u=this._interval;e||(n[0]=s(r(n[0]/u)*u)),i||(n[1]=s(a(n[1]/u)*u))}});return l[he]=function(){return new l},l}),e("echarts/scale/Scale",[Re,"../util/clazz"],function(t){function e(){this._extent=[1/0,-1/0],this._interval=0,this.init&&this.init.apply(this,arguments)}var i=t("../util/clazz"),n=e[Ie];return n.parse=function(t){return t},n[D]=function(t){var e=this._extent;return t>=e[0]&&t<=e[1]},n.normalize=function(t){var e=this._extent;return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])},n.scale=function(t){var e=this._extent;return t*(e[1]-e[0])+e[0]},n.unionExtent=function(t){var e=this._extent;t[0]<e[0]&&(e[0]=t[0]),t[1]>e[1]&&(e[1]=t[1])},n[z]=function(){return this._extent.slice()},n.setExtent=function(t,e){var i=this._extent;isNaN(t)||(i[0]=t),isNaN(e)||(i[1]=e)},n.getTicksLabels=function(){for(var t=[],e=this[k](),i=0;i<e[ge];i++)t.push(this.getLabel(e[i]));return t},i.enableClassExtend(e),i.enableClassManagement(e,{registerWhenExtend:!0}),e}),e("echarts/model/globalDefault",[],function(){var t="";return typeof navigator!==I&&(t=navigator.platform||""),{color:["#c23531","#2f4554","#61a0a8","#d48265","#91c7ae","#749f83","#ca8622","#bda29a","#6e7074","#546570","#c4ccd3"],textStyle:{fontFamily:t.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,animation:!0,animationDuration:1e3,animationDurationUpdate:300,animationEasing:"exponentialOut",animationEasingUpdate:"cubicOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3}}),e("echarts/model/mixin/colorPalette",[],function(){return{clearColorPalette:function(){this._colorIdx=0,this._colorNameMap={}},getColorFromPalette:function(t,e){e=e||this;var i=e._colorIdx||0,n=e._colorNameMap||(e._colorNameMap={});if(n[t])return n[t];var r=this.get("color",!0)||[];if(r[ge]){var a=r[i];return t&&(n[t]=a),e._colorIdx=(i+1)%r[ge],a}}}}),e("zrender/tool/path",[Re,"../graphic/Path","../core/PathProxy","./transformPath","../core/matrix"],function(t){function e(t,e,i,n,r,a,o,s,l,f,m){var g=l*(d/180),y=h(g)*(t-i)/2+c(g)*(e-n)/2,x=-1*c(g)*(t-i)/2+h(g)*(e-n)/2,_=y*y/(o*o)+x*x/(s*s);_>1&&(o*=u(_),s*=u(_));var b=(r===a?-1:1)*u((o*o*s*s-o*o*x*x-s*s*y*y)/(o*o*x*x+s*s*y*y))||0,w=b*o*x/s,M=b*-s*y/o,T=(t+i)/2+h(g)*w-c(g)*M,S=(e+n)/2+c(g)*w+h(g)*M,C=v([1,0],[(y-w)/o,(x-M)/s]),A=[(y-w)/o,(x-M)/s],P=[(-1*y-w)/o,(-1*x-M)/s],L=v(A,P);p(A,P)<=-1&&(L=d),p(A,P)>=1&&(L=0),0===a&&L>0&&(L-=2*d),1===a&&0>L&&(L+=2*d),m.addData(f,T,S,o,s,C,L,g,a)}function i(t){if(!t)return[];var i,n=t[X](/-/g," -")[X](/ /g," ")[X](/ /g,",")[X](/,,/g,",");for(i=0;i<l[ge];i++)n=n[X](new RegExp(l[i],"g"),"|"+l[i]);var r,o=n.split("|"),s=0,u=0,c=new a,h=a.CMD;for(i=1;i<o[ge];i++){var d,f=o[i],p=f.charAt(0),v=0,m=f.slice(1)[X](/e,-/g,"e-").split(",");m[ge]>0&&""===m[0]&&m.shift();for(var g=0;g<m[ge];g++)m[g]=parseFloat(m[g]);for(;v<m[ge]&&!isNaN(m[v])&&!isNaN(m[0]);){var y,x,_,b,w,M,T,S=s,C=u;switch(p){case"l":s+=m[v++],u+=m[v++],d=h.L,c.addData(d,s,u);break;case"L":s=m[v++],u=m[v++],d=h.L,c.addData(d,s,u);break;case"m":s+=m[v++],u+=m[v++],d=h.M,c.addData(d,s,u),p="l";break;case"M":s=m[v++],u=m[v++],d=h.M,c.addData(d,s,u),p="L";break;case"h":s+=m[v++],d=h.L,c.addData(d,s,u);break;case"H":s=m[v++],d=h.L,c.addData(d,s,u);break;case"v":u+=m[v++],d=h.L,c.addData(d,s,u);break;case"V":u=m[v++],d=h.L,c.addData(d,s,u);break;case"C":d=h.C,c.addData(d,m[v++],m[v++],m[v++],m[v++],m[v++],m[v++]),s=m[v-2],u=m[v-1];break;case"c":d=h.C,c.addData(d,m[v++]+s,m[v++]+u,m[v++]+s,m[v++]+u,m[v++]+s,m[v++]+u),s+=m[v-2],u+=m[v-1];break;case"S":y=s,x=u;var A=c.len(),P=c.data;r===h.C&&(y+=s-P[A-4],x+=u-P[A-3]),d=h.C,S=m[v++],C=m[v++],s=m[v++],u=m[v++],c.addData(d,y,x,S,C,s,u);break;case"s":y=s,x=u;var A=c.len(),P=c.data;r===h.C&&(y+=s-P[A-4],x+=u-P[A-3]),d=h.C,S=s+m[v++],C=u+m[v++],s+=m[v++],u+=m[v++],c.addData(d,y,x,S,C,s,u);break;case"Q":S=m[v++],C=m[v++],s=m[v++],u=m[v++],d=h.Q,c.addData(d,S,C,s,u);break;case"q":S=m[v++]+s,C=m[v++]+u,s+=m[v++],u+=m[v++],d=h.Q,c.addData(d,S,C,s,u);break;case"T":y=s,x=u;var A=c.len(),P=c.data;r===h.Q&&(y+=s-P[A-4],x+=u-P[A-3]),s=m[v++],u=m[v++],d=h.Q,c.addData(d,y,x,s,u);break;case"t":y=s,x=u;var A=c.len(),P=c.data;r===h.Q&&(y+=s-P[A-4],x+=u-P[A-3]),s+=m[v++],u+=m[v++],d=h.Q,c.addData(d,y,x,s,u);break;case"A":_=m[v++],b=m[v++],w=m[v++],M=m[v++],T=m[v++],S=s,C=u,s=m[v++],u=m[v++],d=h.A,e(S,C,s,u,M,T,_,b,w,d,c);break;case"a":_=m[v++],b=m[v++],w=m[v++],M=m[v++],T=m[v++],S=s,C=u,s+=m[v++],u+=m[v++],d=h.A,e(S,C,s,u,M,T,_,b,w,d,c)}}("z"===p||"Z"===p)&&(d=h.Z,c.addData(d)),r=d}return c.toStatic(),c}function n(t,e){var n,r=i(t);return e=e||{},e.buildPath=function(t){t.setData(r.data),n&&o(t,n);var e=t[L]();e&&t.rebuildPath(e)},e[_]=function(t){n||(n=s[he]()),s.mul(n,t,n),this.dirty(!0)},e}var r=t("../graphic/Path"),a=t("../core/PathProxy"),o=t("./transformPath"),s=t("../core/matrix"),l=["m","M","l","L","v","V","h","H","z","Z","c","C","q","Q","t","T","s","S","a","A"],u=Math.sqrt,c=Math.sin,h=Math.cos,d=Math.PI,f=function(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])},p=function(t,e){return(t[0]*e[0]+t[1]*e[1])/(f(t)*f(e))},v=function(t,e){return(t[0]*e[1]<t[1]*e[0]?-1:1)*Math.acos(p(t,e))};return{createFromString:function(t,e){return new r(n(t,e))},extendFromString:function(t,e){return r[oe](n(t,e))},mergePath:function(t,e){for(var i=[],n=t[ge],a=0;n>a;a++){var o=t[a];o.__dirty&&o.buildPath(o.path,o.shape,!0),i.push(o.path)}var s=new r(e);return s.buildPath=function(t){t.appendPath(i);var e=t[L]();e&&t.rebuildPath(e)},s}}}),e("zrender/graphic/Path",[Re,"./Displayable","../core/util","../core/PathProxy","../contain/path","./Pattern"],function(t){function e(t){i.call(this,t),this.path=new a}var i=t("./Displayable"),r=t("../core/util"),a=t("../core/PathProxy"),o=t("../contain/path"),s=t("./Pattern"),l=s[Ie].getCanvasPattern,u=Math.abs;return e[Ie]={constructor:e,type:"path",__dirtyPath:!0,strokeContainThreshold:5,brush:function(t,e){var i=this.style,n=this.path,r=i.hasStroke(),a=i.hasFill(),o=i.fill,s=i[y],u=a&&!!o[ue],c=r&&!!s[ue],h=a&&!!o.image,d=r&&!!s.image;if(i.bind(t,this,e),this.setTransform(t),this.__dirty){var f=this[N]();u&&(this._fillGradient=i.getGradient(t,o,f)),c&&(this._strokeGradient=i.getGradient(t,s,f))}u?t.fillStyle=this._fillGradient:h&&(t.fillStyle=l.call(o,t)),c?t.strokeStyle=this._strokeGradient:d&&(t.strokeStyle=l.call(s,t));var p=i.lineDash,v=i.lineDashOffset,m=!!t.setLineDash,g=this.getGlobalScale();n.setScale(g[0],g[1]),this.__dirtyPath||p&&!m&&r?(n=this.path.beginPath(t),p&&!m&&(n.setLineDash(p),n.setLineDashOffset(v)),this.buildPath(n,this.shape,!1),this.__dirtyPath=!1):(t.beginPath(),this.path.rebuildPath(t)),a&&n.fill(t),p&&m&&(t.setLineDash(p),t.lineDashOffset=v),r&&n[y](t),p&&m&&t.setLineDash([]),this.restoreTransform(t),null!=i.text&&this.drawRectText(t,this[N]())},buildPath:function(){},getBoundingRect:function(){var t=this._rect,e=this.style,i=!t;if(i){var n=this.path;this.__dirtyPath&&(n.beginPath(),this.buildPath(n,this.shape,!1)),t=n[N]()}if(this._rect=t,e.hasStroke()){var r=this._rectWithStroke||(this._rectWithStroke=t.clone());if(this.__dirty||i){r.copy(t);var a=e[x],o=e.strokeNoScale?this.getLineScale():1;e.hasFill()||(a=Math.max(a,this.strokeContainThreshold||4)),o>1e-10&&(r.width+=a/o,r[Pe]+=a/o,r.x-=a/o/2,r.y-=a/o/2)}return r}return t},contain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this[N](),r=this.style;if(t=i[0],e=i[1],n[D](t,e)){var a=this.path.data;if(r.hasStroke()){var s=r[x],l=r.strokeNoScale?this.getLineScale():1;if(l>1e-10&&(r.hasFill()||(s=Math.max(s,this.strokeContainThreshold)),o.containStroke(a,s/l,t,e)))return!0}if(r.hasFill())return o[D](a,t,e)}return!1},dirty:function(t){null==t&&(t=!0),t&&(this.__dirtyPath=t,this._rect=null),this.__dirty=!0,this.__zr&&this.__zr.refresh(),this.__clipTarget&&this.__clipTarget.dirty()},animateShape:function(t){return this.animate("shape",t)},attrKV:function(t,e){"shape"===t?(this.setShape(e),this.__dirtyPath=!0,this._rect=null):i[Ie].attrKV.call(this,t,e)},setShape:function(t,e){var i=this.shape;if(i){if(r[le](t))for(var n in t)t.hasOwnProperty(n)&&(i[n]=t[n]);else i[t]=e;this.dirty(!0)}return this},getLineScale:function(){var t=this[n];return t&&u(t[0]-1)>1e-10&&u(t[3]-1)>1e-10?Math.sqrt(u(t[0]*t[3]-t[2]*t[1])):1}},e[oe]=function(t){var i=function(i){e.call(this,i),t.style&&this.style.extendFrom(t.style,!1);var n=t.shape;if(n){this.shape=this.shape||{};var r=this.shape;for(var a in n)!r.hasOwnProperty(a)&&n.hasOwnProperty(a)&&(r[a]=n[a])}t.init&&t.init.call(this,i)};r[Z](i,e);for(var n in t)"style"!==n&&"shape"!==n&&(i[Ie][n]=t[n]);return i},r[Z](e,i),e}),e("zrender/container/Group",[Re,"../core/util","../Element","../core/BoundingRect"],function(t){var e=t("../core/util"),i=t("../Element"),n=t("../core/BoundingRect"),r=function(t){t=t||{},i.call(this,t);for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);this._children=[],this.__storage=null,this.__dirty=!0};return r[Ie]={constructor:r,isGroup:!0,type:"group",silent:!1,children:function(){return this._children.slice()},childAt:function(t){return this._children[t]},childOfName:function(t){for(var e=this._children,i=0;i<e[ge];i++)if(e[i].name===t)return e[i]},childCount:function(){return this._children[ge]},add:function(t){return t&&t!==this&&t[v]!==this&&(this._children.push(t),this._doAdd(t)),this},addBefore:function(t,e){if(t&&t!==this&&t[v]!==this&&e&&e[v]===this){var i=this._children,n=i[me](e);n>=0&&(i[ie](n,0,t),this._doAdd(t))}return this},_doAdd:function(t){t[v]&&t[v][se](t),t[v]=this;var e=this.__storage,i=this.__zr;e&&e!==t.__storage&&(e.addToMap(t),t instanceof r&&t.addChildrenToStorage(e)),i&&i.refresh()},remove:function(t){var i=this.__zr,n=this.__storage,a=this._children,o=e[me](a,t);return 0>o?this:(a[ie](o,1),t[v]=null,n&&(n.delFromMap(t.id),t instanceof r&&t.delChildrenFromStorage(n)),i&&i.refresh(),this)},removeAll:function(){var t,e,i=this._children,n=this.__storage;for(e=0;e<i[ge];e++)t=i[e],n&&(n.delFromMap(t.id),t instanceof r&&t.delChildrenFromStorage(n)),t[v]=null;return i[ge]=0,this},eachChild:function(t,e){for(var i=this._children,n=0;n<i[ge];n++){var r=i[n];t.call(e,r,n)}return this},traverse:function(t,e){for(var i=0;i<this._children[ge];i++){var n=this._children[i];t.call(e,n),"group"===n.type&&n[Q](t,e)}return this},addChildrenToStorage:function(t){for(var e=0;e<this._children[ge];e++){var i=this._children[e];t.addToMap(i),i instanceof r&&i.addChildrenToStorage(t)}},delChildrenFromStorage:function(t){for(var e=0;e<this._children[ge];e++){var i=this._children[e];t.delFromMap(i.id),i instanceof r&&i.delChildrenFromStorage(t)}},dirty:function(){return this.__dirty=!0,this.__zr&&this.__zr.refresh(),this},getBoundingRect:function(t){for(var e=null,i=new n(0,0,0,0),r=t||this._children,a=[],o=0;o<r[ge];o++){var s=r[o];if(!s[xe]&&!s.invisible){var l=s[N](),u=s.getLocalTransform(a);u?(i.copy(l),i[_](u),e=e||i.clone(),e.union(i)):(e=e||l.clone(),e.union(l))}}return e||i}},e[Z](r,i),r}),e("zrender/graphic/Image",[Re,"./Displayable","../core/BoundingRect","../core/util","../core/LRU"],function(t){function e(t){i.call(this,t)}var i=t("./Displayable"),n=t("../core/BoundingRect"),r=t("../core/util"),a=t("../core/LRU"),o=new a(50);return e[Ie]={constructor:e,type:"image",brush:function(t,e){var i,n=this.style,r=n.image;if(n.bind(t,this,e),i=typeof r===Le?this._image:r,!i&&r){var a=o.get(r);if(!a)return i=new Image,i.onload=function(){i.onload=null;for(var t=0;t<a.pending[ge];t++)a.pending[t].dirty()},a={image:i,pending:[this]},i.src=r,o.put(r,a),void(this._image=i);if(i=a.image,this._image=i,!i.width||!i[Pe])return void a.pending.push(this)}if(i){var s=n.width||i.width,l=n[Pe]||i[Pe],u=n.x||0,c=n.y||0;if(!i.width||!i[Pe])return;if(this.setTransform(t),n.sWidth&&n.sHeight){var h=n.sx||0,d=n.sy||0;t.drawImage(i,h,d,n.sWidth,n.sHeight,u,c,s,l)}else if(n.sx&&n.sy){var h=n.sx,d=n.sy,f=s-h,p=l-d;t.drawImage(i,h,d,f,p,u,c,s,l)}else t.drawImage(i,u,c,s,l);null==n.width&&(n.width=s),null==n[Pe]&&(n[Pe]=l),this.restoreTransform(t),null!=n.text&&this.drawRectText(t,this[N]())}},getBoundingRect:function(){var t=this.style;return this._rect||(this._rect=new n(t.x||0,t.y||0,t.width||0,t[Pe]||0)),this._rect}},r[Z](e,i),e}),e("zrender/graphic/Text",[Re,"./Displayable","../core/util","../contain/text"],function(t){var e=t("./Displayable"),i=t("../core/util"),n=t("../contain/text"),r=function(t){e.call(this,t)};return r[Ie]={constructor:r,type:"text",brush:function(t,e){var i=this.style,r=i.x||0,a=i.y||0,o=i.text;if(null!=o&&(o+=""),i.bind(t,this,e),o){this.setTransform(t);var s,l=i[F],u=i.textFont||i.font;if(i.textVerticalAlign){var c=n[N](o,u,i[F],"top");switch(s=B,i.textVerticalAlign){case B:a-=c[Pe]/2-c.lineHeight/2;break;case ye:a-=c[Pe]-c.lineHeight/2;break;default:a+=c.lineHeight/2}}else s=i.textBaseline;t.font=u||"12px sans-serif",t[F]=l||"left",t[F]!==l&&(t[F]="left"),t.textBaseline=s||"alphabetic",t.textBaseline!==s&&(t.textBaseline="alphabetic");for(var h=n.measureText("国",t.font).width,d=o.split("\n"),f=0;f<d[ge];f++)i.hasFill()&&t.fillText(d[f],r,a),i.hasStroke()&&t.strokeText(d[f],r,a),a+=h;this.restoreTransform(t)}},getBoundingRect:function(){if(!this._rect){var t=this.style,e=t.textVerticalAlign,i=n[N](t.text+"",t.textFont||t.font,t[F],e?"top":t.textBaseline);switch(e){case B:i.y-=i[Pe]/2;break;case ye:i.y-=i[Pe]}i.x+=t.x||0,i.y+=t.y||0,this._rect=i}return this._rect}},i[Z](r,e),r}),e("zrender/graphic/shape/Circle",[Re,"../Path"],function(t){return t("../Path")[oe]({type:"circle",shape:{cx:0,cy:0,r:0},buildPath:function(t,e,n){n&&t[i](e.cx+e.r,e.cy),t.arc(e.cx,e.cy,e.r,0,2*Math.PI,!0)}})}),e("zrender/graphic/shape/Sector",[Re,"../Path"],function(t){return t("../Path")[oe]({type:"sector",shape:{cx:0,cy:0,r0:0,r:0,startAngle:0,endAngle:2*Math.PI,clockwise:!0},buildPath:function(t,e){var n=e.cx,r=e.cy,a=Math.max(e.r0||0,0),o=Math.max(e.r,0),s=e.startAngle,l=e.endAngle,u=e.clockwise,c=Math.cos(s),h=Math.sin(s);t[i](c*a+n,h*a+r),t.lineTo(c*o+n,h*o+r),t.arc(n,r,o,s,l,!u),t.lineTo(Math.cos(l)*a+n,Math.sin(l)*a+r),0!==a&&t.arc(n,r,a,l,s,u),t.closePath()}})}),e("zrender/graphic/shape/Polyline",[Re,"../helper/poly","../Path"],function(t){var e=t("../helper/poly");return t("../Path")[oe]({type:"polyline",shape:{points:null,smooth:!1,smoothConstraint:null},style:{stroke:"#000",fill:null},buildPath:function(t,i){e.buildPath(t,i,!1)}})}),e("zrender/graphic/shape/Polygon",[Re,"../helper/poly","../Path"],function(t){var e=t("../helper/poly");return t("../Path")[oe]({type:"polygon",shape:{points:null,smooth:!1,smoothConstraint:null},buildPath:function(t,i){e.buildPath(t,i,!0)}})}),e("zrender/graphic/shape/Line",[Re,"../Path"],function(t){return t("../Path")[oe]({type:"line",shape:{x1:0,y1:0,x2:0,y2:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var n=e.x1,r=e.y1,a=e.x2,o=e.y2,s=e.percent;0!==s&&(t[i](n,r),1>s&&(a=n*(1-s)+a*s,o=r*(1-s)+o*s),t.lineTo(a,o))},pointAt:function(t){var e=this.shape;return[e.x1*(1-t)+e.x2*t,e.y1*(1-t)+e.y2*t]}})}),e("zrender/graphic/shape/Rect",[Re,"../helper/roundRect","../Path"],function(t){var e=t("../helper/roundRect");return t("../Path")[oe]({type:"rect",shape:{r:0,x:0,y:0,width:0,height:0},buildPath:function(t,i){var n=i.x,r=i.y,a=i.width,o=i[Pe];i.r?e.buildPath(t,i):t.rect(n,r,a,o),t.closePath()}})}),e("zrender/graphic/shape/Ring",[Re,"../Path"],function(t){return t("../Path")[oe]({type:"ring",shape:{cx:0,cy:0,r:0,r0:0},buildPath:function(t,e){var n=e.cx,r=e.cy,a=2*Math.PI;t[i](n+e.r,r),t.arc(n,r,e.r,0,a,!1),t[i](n+e.r0,r),t.arc(n,r,e.r0,0,a,!0)}})}),e("zrender/graphic/shape/BezierCurve",[Re,"../../core/curve","../../core/vector","../Path"],function(t){function e(t,e,i){var n=t.cpx2,r=t.cpy2;return null===n||null===r?[(i?c:l)(t.x1,t.cpx1,t.cpx2,t.x2,e),(i?c:l)(t.y1,t.cpy1,t.cpy2,t.y2,e)]:[(i?u:s)(t.x1,t.cpx1,t.x2,e),(i?u:s)(t.y1,t.cpy1,t.y2,e)]}var n=t("../../core/curve"),r=t("../../core/vector"),a=n.quadraticSubdivide,o=n.cubicSubdivide,s=n.quadraticAt,l=n.cubicAt,u=n.quadraticDerivativeAt,c=n.cubicDerivativeAt,h=[];return t("../Path")[oe]({type:"bezier-curve",shape:{x1:0,y1:0,x2:0,y2:0,cpx1:0,cpy1:0,percent:1},style:{stroke:"#000",fill:null},buildPath:function(t,e){var n=e.x1,r=e.y1,s=e.x2,l=e.y2,u=e.cpx1,c=e.cpy1,d=e.cpx2,f=e.cpy2,p=e.percent;0!==p&&(t[i](n,r),null==d||null==f?(1>p&&(a(n,u,s,p,h),u=h[1],s=h[2],a(r,c,l,p,h),c=h[1],l=h[2]),t.quadraticCurveTo(u,c,s,l)):(1>p&&(o(n,u,d,s,p,h),u=h[1],d=h[2],s=h[3],o(r,c,f,l,p,h),c=h[1],f=h[2],l=h[3]),t.bezierCurveTo(u,c,d,f,s,l)))},pointAt:function(t){return e(this.shape,t,!1)},tangentAt:function(t){var i=e(this.shape,t,!0);return r.normalize(i,i)}})}),e("zrender/graphic/shape/Arc",[Re,"../Path"],function(t){return t("../Path")[oe]({type:"arc",shape:{cx:0,cy:0,r:0,startAngle:0,endAngle:2*Math.PI,clockwise:!0},style:{stroke:"#000",fill:null},buildPath:function(t,e){var n=e.cx,r=e.cy,a=Math.max(e.r,0),o=e.startAngle,s=e.endAngle,l=e.clockwise,u=Math.cos(o),c=Math.sin(o);t[i](u*a+n,c*a+r),t.arc(n,r,a,o,s,!l)}})}),e("zrender/graphic/CompoundPath",[Re,"./Path"],function(t){var e=t("./Path");return e[oe]({type:"compound",shape:{paths:null},_updatePathDirty:function(){for(var t=this.__dirtyPath,e=this.shape.paths,i=0;i<e[ge];i++)t=t||e[i].__dirtyPath;this.__dirtyPath=t,this.__dirty=this.__dirty||t},beforeBrush:function(){this._updatePathDirty();for(var t=this.shape.paths||[],e=this.getGlobalScale(),i=0;i<t[ge];i++)t[i].path.setScale(e[0],e[1])},buildPath:function(t,e){for(var i=e.paths||[],n=0;n<i[ge];n++)i[n].buildPath(t,i[n].shape,!0)},afterBrush:function(){for(var t=this.shape.paths,e=0;e<t[ge];e++)t[e].__dirtyPath=!1},getBoundingRect:function(){return this._updatePathDirty(),e[Ie][N].call(this)}})}),e("zrender/graphic/LinearGradient",[Re,"../core/util","./Gradient"],function(t){var e=t("../core/util"),i=t("./Gradient"),n=function(t,e,n,r,a,o){this.x=null==t?0:t,this.y=null==e?0:e,this.x2=null==n?1:n,this.y2=null==r?0:r,this.type="linear",this.global=o||!1,i.call(this,a)};return n[Ie]={constructor:n},e[Z](n,i),n}),e("zrender/core/BoundingRect",[Re,"./vector","./matrix"],function(t){function e(t,e,i,n){0>i&&(t+=i,i=-i),0>n&&(e+=n,n=-n),this.x=t,this.y=e,this.width=i,this[Pe]=n}var i=t("./vector"),n=t("./matrix"),r=i[_],a=Math.min,o=Math.max;return e[Ie]={constructor:e,union:function(t){var e=a(t.x,this.x),i=a(t.y,this.y);this.width=o(t.x+t.width,this.x+this.width)-e,this[Pe]=o(t.y+t[Pe],this.y+this[Pe])-i,this.x=e,this.y=i},applyTransform:function(){var t=[],e=[],i=[],n=[];return function(s){if(s){t[0]=i[0]=this.x,t[1]=n[1]=this.y,e[0]=n[0]=this.x+this.width,e[1]=i[1]=this.y+this[Pe],r(t,t,s),r(e,e,s),r(i,i,s),r(n,n,s),this.x=a(t[0],e[0],i[0],n[0]),this.y=a(t[1],e[1],i[1],n[1]);var l=o(t[0],e[0],i[0],n[0]),u=o(t[1],e[1],i[1],n[1]);this.width=l-this.x,this[Pe]=u-this.y}}}(),calculateTransform:function(t){var e=this,i=t.width/e.width,r=t[Pe]/e[Pe],a=n[he]();return n.translate(a,a,[-e.x,-e.y]),n.scale(a,a,[i,r]),n.translate(a,a,[t.x,t.y]),a},intersect:function(t){if(!t)return!1;t instanceof e||(t=e[he](t));var i=this,n=i.x,r=i.x+i.width,a=i.y,o=i.y+i[Pe],s=t.x,l=t.x+t.width,u=t.y,c=t.y+t[Pe];return!(s>r||n>l||u>o||a>c)},contain:function(t,e){var i=this;return t>=i.x&&t<=i.x+i.width&&e>=i.y&&e<=i.y+i[Pe]},clone:function(){return new e(this.x,this.y,this.width,this[Pe])},copy:function(t){this.x=t.x,this.y=t.y,this.width=t.width,this[Pe]=t[Pe]},plain:function(){return{x:this.x,y:this.y,width:this.width,height:this[Pe]}}},e[he]=function(t){return new e(t.x,t.y,t.width,t[Pe])},e}),e("zrender/graphic/RadialGradient",[Re,"../core/util","./Gradient"],function(t){var e=t("../core/util"),i=t("./Gradient"),n=function(t,e,n,r,a){this.x=null==t?.5:t,this.y=null==e?.5:e,this.r=null==n?.5:n,this.type="radial",this.global=a||!1,i.call(this,r)};return n[Ie]={constructor:n},e[Z](n,i),n}),e("zrender/contain/text",[Re,"../core/util","../core/BoundingRect"],function(t){function e(t,e){var i=t+":"+e;if(o[i])return o[i];for(var n=(t+"").split("\n"),r=0,a=0,u=n[ge];u>a;a++)r=Math.max(d.measureText(n[a],e).width,r);return s>l&&(s=0,o={}),s++,o[i]=r,r}function i(t,i,n,r){var a=((t||"")+"").split("\n")[ge],o=e(t,i),s=e("国",i),l=a*s,u=new c(0,0,o,l);switch(u.lineHeight=s,r){case ye:case"alphabetic":u.y-=s;break;case B:u.y-=s/2}switch(n){case"end":case"right":u.x-=u.width;break;case E:u.x-=u.width/2}return u}function n(t,e,i,n){var r=e.x,a=e.y,o=e[Pe],s=e.width,l=i[Pe],u=o/2-l/2,c="left";switch(t){case"left":r-=n,a+=u,c="right";break;case"right":r+=n+s,a+=u,c="left";break;case"top":r+=s/2,a-=n+l,c=E;break;case ye:r+=s/2,a+=o+n,c=E;break;case m:r+=s/2,a+=u,c=E;break;case"insideLeft":r+=n,a+=u,c="left";break;case"insideRight":r+=s-n,a+=u,c="right";break;case"insideTop":r+=s/2,a+=n,c=E;break;case"insideBottom":r+=s/2,a+=o-l-n,c=E;break;case"insideTopLeft":r+=n,a+=n,c="left";break;case"insideTopRight":r+=s-n,a+=n,c="right";break;case"insideBottomLeft":r+=n,a+=o-l-n;break;case"insideBottomRight":r+=s-n,a+=o-l-n,c="right"}return{x:r,y:a,textAlign:c,textBaseline:"top"}}function r(t,i,n,r,o){if(!i)return"";o=o||{},r=h(r,"...");for(var s=h(o.maxIterations,2),l=h(o.minChar,0),u=e("国",n),c=e("a",n),d=h(o.placeholder,""),f=i=Math.max(0,i-1),p=0;l>p&&f>=c;p++)f-=c;var v=e(r);v>f&&(r="",v=0),f=i-v;for(var m=(t+"").split("\n"),p=0,g=m[ge];g>p;p++){var y=m[p],x=e(y,n);if(!(i>=x)){for(var _=0;;_++){if(f>=x||_>=s){y+=r;break}var b=0===_?a(y,f,c,u):x>0?Math.floor(y[ge]*f/x):0;y=y.substr(0,b),x=e(y,n)}""===y&&(y=d),m[p]=y}}return m.join("\n")}function a(t,e,i,n){for(var r=0,a=0,o=t[ge];o>a&&e>r;a++){var s=t.charCodeAt(a);r+=s>=0&&127>=s?i:n}return a}var o={},s=0,l=5e3,u=t("../core/util"),c=t("../core/BoundingRect"),h=u[f],d={getWidth:e,getBoundingRect:i,adjustTextPositionOnRect:n,truncateText:r,measureText:function(t,e){var i=u[L]();return i.font=e||"12px sans-serif",i.measureText(t)}};return d}),e("echarts/coord/axisHelper",[Re,"../scale/Ordinal","../scale/Interval","../scale/Time","../scale/Log","../scale/Scale","../util/number",De,"zrender/contain/text"],function(t){var e=t("../scale/Ordinal"),i=t("../scale/Interval");t("../scale/Time"),t("../scale/Log");var n=t("../scale/Scale"),a=t("../util/number"),o=t(De),s=t("zrender/contain/text"),l={};return l.getScaleExtent=function(t,e){var i=t.scale,n=i[z](),r=n[1]-n[0];if(i.type===d)return isFinite(r)?n:[0,0];var s=e.getMin?e.getMin():e.get("min"),l=e.getMax?e.getMax():e.get("max"),u=e.getNeedCrossZero?e.getNeedCrossZero():!e.get("scale"),c=e.get("boundaryGap");o[U](c)||(c=[c||0,c||0]),c[0]=a.parsePercent(c[0],1),c[1]=a.parsePercent(c[1],1);var h=!0,f=!0;return null==s&&(s=n[0]-c[0]*r,h=!1),null==l&&(l=n[1]+c[1]*r,f=!1),"dataMin"===s&&(s=n[0]),"dataMax"===l&&(l=n[1]),u&&(s>0&&l>0&&!h&&(s=0),0>s&&0>l&&!f&&(l=0)),[s,l]},l.niceScaleExtent=function(t,e){var i=t.scale,n=l.getScaleExtent(t,e),r=null!=(e.getMin?e.getMin():e.get("min")),a=null!=(e.getMax?e.getMax():e.get("max")),o=e.get("splitNumber");"log"===i.type&&(i.base=e.get("logBase")),i.setExtent(n[0],n[1]),i.niceExtent(o,r,a);var s=e.get("minInterval");if(isFinite(s)&&!r&&!a&&"interval"===i.type){var u=i.getInterval(),c=Math.max(Math.abs(u),s)/u;n=i[z]();var h=(n[1]+n[0])/2;i.setExtent(c*(n[0]-h)+h,c*(n[1]-h)+h),i.niceExtent(o)}var u=e.get("interval");null!=u&&i.setInterval&&i.setInterval(u)},l.createScaleByModel=function(t,a){if(a=a||t.get("type"))switch(a){case r:return new e(t.getCategories(),[1/0,-1/0]);case"value":return new i;default:return(n.getClass(a)||i)[he](t)}},l.ifAxisCrossZero=function(t){var e=t.scale[z](),i=e[0],n=e[1];return!(i>0&&n>0||0>i&&0>n)},l.getAxisLabelInterval=function(t,e,i,n){var r,a=0,o=0,l=1;e[ge]>40&&(l=Math.floor(e[ge]/40));for(var u=0;u<t[ge];u+=l){var c=t[u],h=s[N](e[u],i,E,"top");h[n?"x":"y"]+=c,h[n?"width":Pe]*=1.3,r?r.intersect(h)?(o++,a=Math.max(a,o)):(r.union(h),o=0):r=h.clone()}return 0===a&&l>1?l:(a+1)*l-1},l.getFormattedLabels=function(t,e){var i=t.scale,n=i.getTicksLabels(),a=i[k]();return typeof e===Le?(e=function(t){return function(e){return t[X]("{value}",null!=e?e:"")}}(e),o.map(n,e)):typeof e===j?o.map(a,function(n,a){return e(t.type===r?i.getLabel(n):n,a)},this):n},l}),e("echarts/coord/cartesian/Cartesian2D",[Re,De,"./Cartesian"],function(t){function e(t){n.call(this,t)}var i=t(De),n=t("./Cartesian");return e[Ie]={constructor:e,type:"cartesian2d",dimensions:["x","y"],getBaseAxis:function(){return this.getAxesByScale(d)[0]||this.getAxesByScale("time")[0]||this[o]("x")},containPoint:function(t){var e=this[o]("x"),i=this[o]("y");return e[D](e.toLocalCoord(t[0]))&&i[D](i.toLocalCoord(t[1]))},containData:function(t){return this[o]("x").containData(t[0])&&this[o]("y").containData(t[1])},dataToPoints:function(t,e){return t.mapArray(["x","y"],function(t,e){return this[s]([t,e])},e,this)},dataToPoint:function(t,e){var i=this[o]("x"),n=this[o]("y");return[i.toGlobalCoord(i[a](t[0],e)),n.toGlobalCoord(n[a](t[1],e))]},pointToData:function(t,e){var i=this[o]("x"),n=this[o]("y");return[i.coordToData(i.toLocalCoord(t[0]),e),n.coordToData(n.toLocalCoord(t[1]),e)]},getOtherAxis:function(t){return this[o]("x"===t.dim?"y":"x")}},i[Z](e,n),e}),e("echarts/coord/cartesian/Axis2D",[Re,De,"../Axis","./axisLabelInterval"],function(t){var e=t(De),i=t("../Axis"),n=t("./axisLabelInterval"),a=function(t,e,n,r,a){i.call(this,t,e,n),this.type=r||"value",this[R]=a||ye};return a[Ie]={constructor:a,index:0,onZero:!1,model:null,isHorizontal:function(){var t=this[R];return"top"===t||t===ye},getGlobalExtent:function(){var t=this[z]();return t[0]=this.toGlobalCoord(t[0]),t[1]=this.toGlobalCoord(t[1]),t},getLabelInterval:function(){var t=this._labelInterval;return t||(t=this._labelInterval=n(this)),t},isLabelIgnored:function(t){if(this.type===r){var e=this.getLabelInterval();return typeof e===j&&!e(t,this.scale.getLabel(t))||t%(e+1)}},toLocalCoord:null,toGlobalCoord:null},e[Z](a,i),a}),e("echarts/coord/cartesian/GridModel",[Re,"./AxisModel","../../model/Component"],function(t){t("./AxisModel");var e=t("../../model/Component");return e[oe]({type:"grid",dependencies:["xAxis","yAxis"],layoutMode:"box",coordinateSystem:null,defaultOption:{show:!1,zlevel:0,z:0,left:"10%",top:60,right:"10%",bottom:60,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"}})}),e("echarts/util/clazz",[Re,De],function(t){function e(t,e){var i=n.slice(arguments,2);return this.superClass[Ie][e].apply(t,i)}function i(t,e,i){return this.superClass[Ie][e].apply(t,i)}var n=t(De),r={},a=".",o="___EC__COMPONENT__CONTAINER___",s=r.parseClassType=function(t){var e={main:"",sub:""};return t&&(t=t.split(a),e.main=t[0]||"",e.sub=t[1]||""),e};return r.enableClassExtend=function(t,r){t.$constructor=t,t[oe]=function(t){var r=this,a=function(){t.$constructor?t.$constructor.apply(this,arguments):r.apply(this,arguments)};return n[oe](a[Ie],t),a[oe]=this[oe],a.superCall=e,a.superApply=i,n[Z](a,this),a.superClass=r,a}},r.enableClassManagement=function(t,e){function i(t){var e=r[t.main];return e&&e[o]||(e=r[t.main]={},e[o]=!0),e}e=e||{};var r={};if(t.registerClass=function(t,e){if(e)if(e=s(e),e.sub){if(e.sub!==o){var n=i(e);n[e.sub]=t}}else r[e.main]=t;return t},t.getClass=function(t,e,i){var n=r[t];if(n&&n[o]&&(n=e?n[e]:null),i&&!n)throw new Error("Component "+t+"."+(e||"")+" not exists. Load it first.");return n},t.getClassesByMainType=function(t){t=s(t);var e=[],i=r[t.main];return i&&i[o]?n.each(i,function(t,i){i!==o&&e.push(t)}):e.push(i),e},t.hasClass=function(t){return t=s(t),!!r[t.main]},t.getAllClassMainTypes=function(){var t=[];return n.each(r,function(e,i){t.push(i)}),t},t.hasSubTypes=function(t){t=s(t);var e=r[t.main];return e&&e[o]},t.parseClassType=s,e.registerWhenExtend){var a=t[oe];a&&(t[oe]=function(e){var i=a.call(this,e);return t.registerClass(i,e.type)})}return t},r.setReadOnly=function(){},r}),e("echarts/model/mixin/lineStyle",[Re,"./makeStyleMapper"],function(t){var e=t("./makeStyleMapper")([[x,"width"],[y,"color"],[O],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]);return{getLineStyle:function(t){var i=e.call(this,t),n=this.getLineDash(i[x]);return n&&(i.lineDash=n),i},getLineDash:function(t){null==t&&(t=1);var e=this.get("type"),i=Math.max(t,2),n=4*t;return"solid"===e||null==e?null:"dashed"===e?[n,n]:[i,i]}}}),e("echarts/model/mixin/areaStyle",[Re,"./makeStyleMapper"],function(t){return{getAreaStyle:t("./makeStyleMapper")([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],[O],["shadowColor"]])}}),e("echarts/model/mixin/textStyle",[Re,"zrender/contain/text"],function(t){function e(t,e){return t&&t[g](e)}var i=t("zrender/contain/text");return{getTextColor:function(){var t=this[M];return this[g]("color")||t&&t.get("textStyle.color") +},getFont:function(){var t=this[M],i=t&&t[Se](G);return[this[g]("fontStyle")||e(i,"fontStyle"),this[g]("fontWeight")||e(i,"fontWeight"),(this[g]("fontSize")||e(i,"fontSize")||12)+"px",this[g]("fontFamily")||e(i,"fontFamily")||"sans-serif"].join(" ")},getTextRect:function(t){return i[N](t,this[V](),this[g]("align"),this[g]("baseline"))},truncateText:function(t,e,n,r){return i.truncateText(t,e,this[V](),n,r)}}}),e("echarts/model/mixin/itemStyle",[Re,"./makeStyleMapper"],function(t){var e=t("./makeStyleMapper")([["fill","color"],[y,"borderColor"],[x,"borderWidth"],[O],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"],["textPosition"],[F]]);return{getItemStyle:function(t){var i=e.call(this,t),n=this.getBorderLineDash();return n&&(i.lineDash=n),i},getBorderLineDash:function(){var t=this.get("borderType");return"solid"===t||null==t?null:"dashed"===t?[5,5]:[1,1]}}}),e("zrender/graphic/mixin/RectText",[Re,"../../contain/text","../../core/BoundingRect"],function(t){function e(t,e){return typeof t===Le?t.lastIndexOf("%")>=0?parseFloat(t)/100*e:parseFloat(t):t}var i=t("../../contain/text"),r=t("../../core/BoundingRect"),a=new r,o=function(){};return o[Ie]={constructor:o,drawRectText:function(t,r,o){var s=this.style,l=s.text;if(null!=l&&(l+=""),l){t.save();var u,c,h=s.textPosition,d=s.textDistance,f=s[F],p=s.textFont||s.font,v=s.textBaseline,m=s.textVerticalAlign;o=o||i[N](l,p,f,v);var g=this[n];if(s.textTransform?this.setTransform(t):g&&(a.copy(r),a[_](g),r=a),h instanceof Array){if(u=r.x+e(h[0],r.width),c=r.y+e(h[1],r[Pe]),f=f||"left",v=v||"top",m){switch(m){case B:c-=o[Pe]/2-o.lineHeight/2;break;case ye:c-=o[Pe]-o.lineHeight/2;break;default:c+=o.lineHeight/2}v=B}}else{var y=i.adjustTextPositionOnRect(h,r,o,d);u=y.x,c=y.y,f=f||y[F],v=v||y.textBaseline}t[F]=f||"left",t.textBaseline=v||"alphabetic";var x=s.textFill,b=s.textStroke;x&&(t.fillStyle=x),b&&(t.strokeStyle=b),t.font=p||"12px sans-serif",t.shadowBlur=s.textShadowBlur,t.shadowColor=s.textShadowColor||"transparent",t.shadowOffsetX=s.textShadowOffsetX,t.shadowOffsetY=s.textShadowOffsetY;var w=l.split("\n");s.textRotation&&(g&&t.translate(g[4],g[5]),t.rotate(s.textRotation),g&&t.translate(-g[4],-g[5]));for(var M=0;M<w[ge];M++)x&&t.fillText(w[M],u,c),b&&t.strokeText(w[M],u,c),c+=o.lineHeight;t.restore()}}},o}),e("zrender/core/PathProxy",[Re,"./curve","./vector","./bbox","./BoundingRect","../config"],function(t){var e=t("./curve"),n=t("./vector"),r=t("./bbox"),a=t("./BoundingRect"),o=t("../config").devicePixelRatio,s={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},l=[],u=[],c=[],h=[],d=Math.min,f=Math.max,p=Math.cos,v=Math.sin,m=Math.sqrt,g=Math.abs,x=typeof Float32Array!=I,_=function(){this.data=[],this._len=0,this._ctx=null,this._xi=0,this._yi=0,this._x0=0,this._y0=0,this._ux=0,this._uy=0};return _[Ie]={constructor:_,_lineDash:null,_dashOffset:0,_dashIdx:0,_dashSum:0,setScale:function(t,e){this._ux=g(1/o/t)||0,this._uy=g(1/o/e)||0},getContext:function(){return this._ctx},beginPath:function(t){return this._ctx=t,t&&t.beginPath(),t&&(this.dpr=t.dpr),this._len=0,this._lineDash&&(this._lineDash=null,this._dashOffset=0),this},moveTo:function(t,e){return this.addData(s.M,t,e),this._ctx&&this._ctx[i](t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},lineTo:function(t,e){var i=g(t-this._xi)>this._ux||g(e-this._yi)>this._uy||this._len<5;return this.addData(s.L,t,e),this._ctx&&i&&(this._needsDash()?this._dashedLineTo(t,e):this._ctx.lineTo(t,e)),i&&(this._xi=t,this._yi=e),this},bezierCurveTo:function(t,e,i,n,r,a){return this.addData(s.C,t,e,i,n,r,a),this._ctx&&(this._needsDash()?this._dashedBezierTo(t,e,i,n,r,a):this._ctx.bezierCurveTo(t,e,i,n,r,a)),this._xi=r,this._yi=a,this},quadraticCurveTo:function(t,e,i,n){return this.addData(s.Q,t,e,i,n),this._ctx&&(this._needsDash()?this._dashedQuadraticTo(t,e,i,n):this._ctx.quadraticCurveTo(t,e,i,n)),this._xi=i,this._yi=n,this},arc:function(t,e,i,n,r,a){return this.addData(s.A,t,e,i,i,n,r-n,0,a?0:1),this._ctx&&this._ctx.arc(t,e,i,n,r,a),this._xi=p(r)*i+t,this._xi=v(r)*i+t,this},arcTo:function(t,e,i,n,r){return this._ctx&&this._ctx.arcTo(t,e,i,n,r),this},rect:function(t,e,i,n){return this._ctx&&this._ctx.rect(t,e,i,n),this.addData(s.R,t,e,i,n),this},closePath:function(){this.addData(s.Z);var t=this._ctx,e=this._x0,i=this._y0;return t&&(this._needsDash()&&this._dashedLineTo(e,i),t.closePath()),this._xi=e,this._yi=i,this},fill:function(t){t&&t.fill(),this.toStatic()},stroke:function(t){t&&t[y](),this.toStatic()},setLineDash:function(t){if(t instanceof Array){this._lineDash=t,this._dashIdx=0;for(var e=0,i=0;i<t[ge];i++)e+=t[i];this._dashSum=e}return this},setLineDashOffset:function(t){return this._dashOffset=t,this},len:function(){return this._len},setData:function(t){var e=t[ge];this.data&&this.data[ge]==e||!x||(this.data=new Float32Array(e));for(var i=0;e>i;i++)this.data[i]=t[i];this._len=e},appendPath:function(t){t instanceof Array||(t=[t]);for(var e=t[ge],i=0,n=this._len,r=0;e>r;r++)i+=t[r].len();x&&this.data instanceof Float32Array&&(this.data=new Float32Array(n+i));for(var r=0;e>r;r++)for(var a=t[r].data,o=0;o<a[ge];o++)this.data[n++]=a[o];this._len=n},addData:function(t){var e=this.data;this._len+arguments[ge]>e[ge]&&(this._expandData(),e=this.data);for(var i=0;i<arguments[ge];i++)e[this._len++]=arguments[i];this._prevCmd=t},_expandData:function(){if(!(this.data instanceof Array)){for(var t=[],e=0;e<this._len;e++)t[e]=this.data[e];this.data=t}},_needsDash:function(){return this._lineDash},_dashedLineTo:function(t,e){var n,r,a=this._dashSum,o=this._dashOffset,s=this._lineDash,l=this._ctx,u=this._xi,c=this._yi,h=t-u,p=e-c,v=m(h*h+p*p),g=u,y=c,x=s[ge];for(h/=v,p/=v,0>o&&(o=a+o),o%=a,g-=o*h,y-=o*p;h>0&&t>=g||0>h&&g>=t||0==h&&(p>0&&e>=y||0>p&&y>=e);)r=this._dashIdx,n=s[r],g+=h*n,y+=p*n,this._dashIdx=(r+1)%x,h>0&&u>g||0>h&&g>u||p>0&&c>y||0>p&&y>c||l[r%2?i:"lineTo"](h>=0?d(g,t):f(g,t),p>=0?d(y,e):f(y,e));h=g-t,p=y-e,this._dashOffset=-m(h*h+p*p)},_dashedBezierTo:function(t,n,r,a,o,s){var l,u,c,h,d,f=this._dashSum,p=this._dashOffset,v=this._lineDash,g=this._ctx,y=this._xi,x=this._yi,_=e.cubicAt,b=0,w=this._dashIdx,M=v[ge],T=0;for(0>p&&(p=f+p),p%=f,l=0;1>l;l+=.1)u=_(y,t,r,o,l+.1)-_(y,t,r,o,l),c=_(x,n,a,s,l+.1)-_(x,n,a,s,l),b+=m(u*u+c*c);for(;M>w&&(T+=v[w],!(T>p));w++);for(l=(T-p)/b;1>=l;)h=_(y,t,r,o,l),d=_(x,n,a,s,l),w%2?g[i](h,d):g.lineTo(h,d),l+=v[w]/b,w=(w+1)%M;w%2!==0&&g.lineTo(o,s),u=o-h,c=s-d,this._dashOffset=-m(u*u+c*c)},_dashedQuadraticTo:function(t,e,i,n){var r=i,a=n;i=(i+2*t)/3,n=(n+2*e)/3,t=(this._xi+2*t)/3,e=(this._yi+2*e)/3,this._dashedBezierTo(t,e,i,n,r,a)},toStatic:function(){var t=this.data;t instanceof Array&&(t[ge]=this._len,x&&(this.data=new Float32Array(t)))},getBoundingRect:function(){l[0]=l[1]=c[0]=c[1]=Number.MAX_VALUE,u[0]=u[1]=h[0]=h[1]=-Number.MAX_VALUE;for(var t=this.data,e=0,i=0,o=0,d=0,f=0;f<t[ge];){var m=t[f++];switch(1==f&&(e=t[f],i=t[f+1],o=e,d=i),m){case s.M:o=t[f++],d=t[f++],e=o,i=d,c[0]=o,c[1]=d,h[0]=o,h[1]=d;break;case s.L:r.fromLine(e,i,t[f],t[f+1],c,h),e=t[f++],i=t[f++];break;case s.C:r.fromCubic(e,i,t[f++],t[f++],t[f++],t[f++],t[f],t[f+1],c,h),e=t[f++],i=t[f++];break;case s.Q:r.fromQuadratic(e,i,t[f++],t[f++],t[f],t[f+1],c,h),e=t[f++],i=t[f++];break;case s.A:var g=t[f++],y=t[f++],x=t[f++],_=t[f++],b=t[f++],w=t[f++]+b,M=(t[f++],1-t[f++]);1==f&&(o=p(b)*x+g,d=v(b)*_+y),r.fromArc(g,y,x,_,b,w,M,c,h),e=p(w)*x+g,i=v(w)*_+y;break;case s.R:o=e=t[f++],d=i=t[f++];var T=t[f++],S=t[f++];r.fromLine(o,d,o+T,d+S,c,h);break;case s.Z:e=o,i=d}n.min(l,l,c),n.max(u,u,h)}return 0===f&&(l[0]=l[1]=u[0]=u[1]=0),new a(l[0],l[1],u[0]-l[0],u[1]-l[1])},rebuildPath:function(t){for(var e,n,r,a,o,l,u=this.data,c=this._ux,h=this._uy,d=this._len,f=0;d>f;){var m=u[f++];switch(1==f&&(r=u[f],a=u[f+1],e=r,n=a),m){case s.M:e=r=u[f++],n=a=u[f++],t[i](r,a);break;case s.L:o=u[f++],l=u[f++],(g(o-r)>c||g(l-a)>h||f===d-1)&&(t.lineTo(o,l),r=o,a=l);break;case s.C:t.bezierCurveTo(u[f++],u[f++],u[f++],u[f++],u[f++],u[f++]),r=u[f-2],a=u[f-1];break;case s.Q:t.quadraticCurveTo(u[f++],u[f++],u[f++],u[f++]),r=u[f-2],a=u[f-1];break;case s.A:var y=u[f++],x=u[f++],_=u[f++],b=u[f++],w=u[f++],M=u[f++],T=u[f++],S=u[f++],C=_>b?_:b,A=_>b?1:_/b,P=_>b?b/_:1,L=Math.abs(_-b)>.001,I=w+M;L?(t.translate(y,x),t.rotate(T),t.scale(A,P),t.arc(0,0,C,w,I,1-S),t.scale(1/A,1/P),t.rotate(-T),t.translate(-y,-x)):t.arc(y,x,C,w,I,1-S),1==f&&(e=p(w)*_+y,n=v(w)*b+x),r=p(I)*_+y,a=v(I)*b+x;break;case s.R:e=r=u[f],n=a=u[f+1],t.rect(u[f++],u[f++],u[f++],u[f++]);break;case s.Z:t.closePath(),r=e,a=n}}}},_.CMD=s,_}),e("zrender/graphic/Displayable",[Re,"../core/util","./Style","../Element","./mixin/RectText"],function(t){function e(t){t=t||{},r.call(this,t);for(var e in t)t.hasOwnProperty(e)&&"style"!==e&&(this[e]=t[e]);this.style=new n(t.style),this._rect=null,this.__clipPaths=[]}var i=t("../core/util"),n=t("./Style"),r=t("../Element"),a=t("./mixin/RectText");return e[Ie]={constructor:e,type:"displayable",__dirty:!0,invisible:!1,z:0,z2:0,zlevel:0,draggable:!1,dragging:!1,silent:!1,culling:!1,cursor:"pointer",rectHover:!1,progressive:-1,beforeBrush:function(){},afterBrush:function(){},brush:function(){},getBoundingRect:function(){},contain:function(t,e){return this.rectContain(t,e)},traverse:function(t,e){t.call(e,this)},rectContain:function(t,e){var i=this.transformCoordToLocal(t,e),n=this[N]();return n[D](i[0],i[1])},dirty:function(){this.__dirty=!0,this._rect=null,this.__zr&&this.__zr.refresh()},animateStyle:function(t){return this.animate("style",t)},attrKV:function(t,e){"style"!==t?r[Ie].attrKV.call(this,t,e):this.style.set(e)},setStyle:function(t,e){return this.style.set(t,e),this.dirty(!1),this},useStyle:function(t){return this.style=new n(t),this.dirty(!1),this}},i[Z](e,r),i.mixin(e,a),e}),e("zrender/graphic/Gradient",[Re],function(){var t=function(t){this[ue]=t||[]};return t[Ie]={constructor:t,addColorStop:function(t,e){this[ue].push({offset:t,color:e})}},t}),e("zrender/vml/core",[Re,"exports","module","../core/env"],function(t,e,i){if(!t("../core/env")[we]){var n,r="urn:schemas-microsoft-com:vml",a=window,o=a.document,s=!1;try{!o.namespaces.zrvml&&o.namespaces.add("zrvml",r),n=function(t){return o[P]("<zrvml:"+t+' class="zrvml">')}}catch(l){n=function(t){return o[P]("<"+t+' xmlns="'+r+'" class="zrvml">')}}var u=function(){if(!s){s=!0;var t=o.styleSheets;t[ge]<31?o.createStyleSheet().addRule(".zrvml","behavior:url(#default#VML)"):t[0].addRule(".zrvml","behavior:url(#default#VML)")}};i.exports={doc:o,initVML:u,createNode:n}}}),e("echarts/component/toolbox/featureManager",[Re],function(){var t={};return{register:function(e,i){t[e]=i},get:function(e){return t[e]}}}),e("zrender/contain/path",[Re,"../core/PathProxy","./line","./cubic","./quadratic","./arc","./util","../core/curve","./windingLine"],function(t){function e(t,e){return Math.abs(t-e)<g}function i(){var t=x[0];x[0]=x[1],x[1]=t}function n(t,e,n,r,a,o,s,l,u,c){if(c>e&&c>r&&c>o&&c>l||e>c&&r>c&&o>c&&l>c)return 0;var h=f.cubicRootAt(e,r,o,l,c,y);if(0===h)return 0;for(var d,p,v=0,m=-1,g=0;h>g;g++){var _=y[g],b=0===_||1===_?.5:1,w=f.cubicAt(t,n,a,s,_);u>w||(0>m&&(m=f.cubicExtrema(e,r,o,l,x),x[1]<x[0]&&m>1&&i(),d=f.cubicAt(e,r,o,l,x[0]),m>1&&(p=f.cubicAt(e,r,o,l,x[1]))),v+=2==m?_<x[0]?e>d?b:-b:_<x[1]?d>p?b:-b:p>l?b:-b:_<x[0]?e>d?b:-b:d>l?b:-b)}return v}function r(t,e,i,n,r,a,o,s){if(s>e&&s>n&&s>a||e>s&&n>s&&a>s)return 0;var l=f.quadraticRootAt(e,n,a,s,y);if(0===l)return 0;var u=f.quadraticExtremum(e,n,a);if(u>=0&&1>=u){for(var c=0,h=f.quadraticAt(e,n,a,u),d=0;l>d;d++){var p=0===y[d]||1===y[d]?.5:1,v=f.quadraticAt(t,i,r,y[d]);o>v||(c+=y[d]<u?e>h?p:-p:h>a?p:-p)}return c}var p=0===y[0]||1===y[0]?.5:1,v=f.quadraticAt(t,i,r,y[0]);return o>v?0:e>a?p:-p}function a(t,e,i,n,r,a,o,s){if(s-=e,s>i||-i>s)return 0;var l=Math.sqrt(i*i-s*s);y[0]=-l,y[1]=l;var u=Math.abs(n-r);if(1e-4>u)return 0;if(1e-4>u%m){n=0,r=m;var c=a?1:-1;return o>=y[0]+t&&o<=y[1]+t?c:0}if(a){var l=n;n=d(r),r=d(l)}else n=d(n),r=d(r);n>r&&(r+=m);for(var h=0,f=0;2>f;f++){var p=y[f];if(p+t>o){var v=Math.atan2(s,p),c=a?1:-1;0>v&&(v=m+v),(v>=n&&r>=v||v+m>=n&&r>=v+m)&&(v>Math.PI/2&&v<1.5*Math.PI&&(c=-c),h+=c)}}return h}function o(t,i,o,l,d){for(var f=0,m=0,g=0,y=0,x=0,_=0;_<t[ge];){var b=t[_++];switch(b===s.M&&_>1&&(o||(f+=p(m,g,y,x,l,d))),1==_&&(m=t[_],g=t[_+1],y=m,x=g),b){case s.M:y=t[_++],x=t[_++],m=y,g=x;break;case s.L:if(o){if(v(m,g,t[_],t[_+1],i,l,d))return!0}else f+=p(m,g,t[_],t[_+1],l,d)||0;m=t[_++],g=t[_++];break;case s.C:if(o){if(u.containStroke(m,g,t[_++],t[_++],t[_++],t[_++],t[_],t[_+1],i,l,d))return!0}else f+=n(m,g,t[_++],t[_++],t[_++],t[_++],t[_],t[_+1],l,d)||0;m=t[_++],g=t[_++];break;case s.Q:if(o){if(c.containStroke(m,g,t[_++],t[_++],t[_],t[_+1],i,l,d))return!0}else f+=r(m,g,t[_++],t[_++],t[_],t[_+1],l,d)||0;m=t[_++],g=t[_++];break;case s.A:var w=t[_++],M=t[_++],T=t[_++],S=t[_++],C=t[_++],A=t[_++],P=(t[_++],1-t[_++]),L=Math.cos(C)*T+w,I=Math.sin(C)*S+M;_>1?f+=p(m,g,L,I,l,d):(y=L,x=I);var k=(l-w)*S/T+w;if(o){if(h.containStroke(w,M,S,C,C+A,P,i,k,d))return!0}else f+=a(w,M,S,C,C+A,P,k,d);m=Math.cos(C+A)*T+w,g=Math.sin(C+A)*S+M;break;case s.R:y=m=t[_++],x=g=t[_++];var z=t[_++],D=t[_++],L=y+z,I=x+D;if(o){if(v(y,x,L,x,i,l,d)||v(L,x,L,I,i,l,d)||v(L,I,y,I,i,l,d)||v(y,I,y,x,i,l,d))return!0}else f+=p(L,x,L,I,l,d),f+=p(y,I,y,x,l,d);break;case s.Z:if(o){if(v(m,g,y,x,i,l,d))return!0}else f+=p(m,g,y,x,l,d);m=y,g=x}}return o||e(g,x)||(f+=p(m,g,y,x,l,d)||0),0!==f}var s=t("../core/PathProxy").CMD,l=t("./line"),u=t("./cubic"),c=t("./quadratic"),h=t("./arc"),d=t("./util").normalizeRadian,f=t("../core/curve"),p=t("./windingLine"),v=l.containStroke,m=2*Math.PI,g=1e-4,y=[-1,-1,-1],x=[-1,-1];return{contain:function(t,e,i){return o(t,0,!1,e,i)},containStroke:function(t,e,i,n){return o(t,e,!0,i,n)}}}),e("zrender/tool/transformPath",[Re,"../core/PathProxy","../core/vector"],function(t){function e(t,e){var n,l,u,c,h,d,f=t.data,p=i.M,v=i.C,m=i.L,g=i.R,y=i.A,x=i.Q;for(u=0,c=0;u<f[ge];){switch(n=f[u++],c=u,l=0,n){case p:l=1;break;case m:l=1;break;case v:l=3;break;case x:l=2;break;case y:var _=e[4],b=e[5],w=o(e[0]*e[0]+e[1]*e[1]),M=o(e[2]*e[2]+e[3]*e[3]),T=s(-e[1]/M,e[0]/w);f[u++]+=_,f[u++]+=b,f[u++]*=w,f[u++]*=M,f[u++]+=T,f[u++]+=T,u+=2,c=u;break;case g:d[0]=f[u++],d[1]=f[u++],r(d,d,e),f[c++]=d[0],f[c++]=d[1],d[0]+=f[u++],d[1]+=f[u++],r(d,d,e),f[c++]=d[0],f[c++]=d[1]}for(h=0;l>h;h++){var d=a[h];d[0]=f[u++],d[1]=f[u++],r(d,d,e),f[c++]=d[0],f[c++]=d[1]}}}var i=t("../core/PathProxy").CMD,n=t("../core/vector"),r=n[_],a=[[],[],[]],o=Math.sqrt,s=Math.atan2;return e}),e("zrender/graphic/Pattern",[Re],function(){var t=function(t,e){this.image=t,this.repeat=e,this.type="pattern"};return t[Ie].getCanvasPattern=function(t){return this._canvasPattern||(this._canvasPattern=t.createPattern(this.image,this.repeat))},t}),e("echarts/scale/Ordinal",[Re,De,"./Scale"],function(t){var e=t(De),i=t("./Scale"),n=i[Ie],r=i[oe]({type:"ordinal",init:function(t,e){this._data=t,this._extent=e||[0,t[ge]-1]},parse:function(t){return typeof t===Le?e[me](this._data,t):Math.round(t)},contain:function(t){return t=this.parse(t),n[D].call(this,t)&&null!=this._data[t]},normalize:function(t){return n.normalize.call(this,this.parse(t))},scale:function(t){return Math.round(n.scale.call(this,t))},getTicks:function(){for(var t=[],e=this._extent,i=e[0];i<=e[1];)t.push(i),i++;return t},getLabel:function(t){return this._data[t]},count:function(){return this._extent[1]-this._extent[0]+1},niceTicks:e.noop,niceExtent:e.noop});return r[he]=function(){return new r},r}),e("echarts/model/mixin/makeStyleMapper",[Re,De],function(t){var e=t(De);return function(t){for(var i=0;i<t[ge];i++)t[i][1]||(t[i][1]=t[i][0]);return function(i){for(var n={},r=0;r<t[ge];r++){var a=t[r][1];if(!(i&&e[me](i,a)>=0)){var o=this[g](a);null!=o&&(n[t[r][0]]=o)}}return n}}}),e("zrender/core/curve",[Re,"./vector"],function(t){function e(t){return t>-_&&_>t}function i(t){return t>_||-_>t}function n(t,e,i,n,r){var a=1-r;return a*a*(a*t+3*r*e)+r*r*(r*n+3*a*i)}function r(t,e,i,n,r){var a=1-r;return 3*(((e-t)*a+2*(i-e)*r)*a+(n-i)*r*r)}function a(t,i,n,r,a,o){var s=r+3*(i-n)-t,l=3*(n-2*i+t),u=3*(i-t),c=t-a,h=l*l-3*s*u,d=l*u-9*s*c,f=u*u-3*l*c,p=0;if(e(h)&&e(d))if(e(l))o[0]=0;else{var v=-u/l;v>=0&&1>=v&&(o[p++]=v)}else{var m=d*d-4*h*f;if(e(m)){var g=d/h,v=-l/s+g,_=-g/2;v>=0&&1>=v&&(o[p++]=v),_>=0&&1>=_&&(o[p++]=_)}else if(m>0){var b=x(m),T=h*l+1.5*s*(-d+b),S=h*l+1.5*s*(-d-b);T=0>T?-y(-T,M):y(T,M),S=0>S?-y(-S,M):y(S,M);var v=(-l-(T+S))/(3*s);v>=0&&1>=v&&(o[p++]=v)}else{var C=(2*h*l-3*s*d)/(2*x(h*h*h)),A=Math.acos(C)/3,P=x(h),L=Math.cos(A),v=(-l-2*P*L)/(3*s),_=(-l+P*(L+w*Math.sin(A)))/(3*s),I=(-l+P*(L-w*Math.sin(A)))/(3*s);v>=0&&1>=v&&(o[p++]=v),_>=0&&1>=_&&(o[p++]=_),I>=0&&1>=I&&(o[p++]=I)}}return p}function o(t,n,r,a,o){var s=6*r-12*n+6*t,l=9*n+3*a-3*t-9*r,u=3*n-3*t,c=0;if(e(l)){if(i(s)){var h=-u/s;h>=0&&1>=h&&(o[c++]=h)}}else{var d=s*s-4*l*u;if(e(d))o[0]=-s/(2*l);else if(d>0){var f=x(d),h=(-s+f)/(2*l),p=(-s-f)/(2*l);h>=0&&1>=h&&(o[c++]=h),p>=0&&1>=p&&(o[c++]=p)}}return c}function s(t,e,i,n,r,a){var o=(e-t)*r+t,s=(i-e)*r+e,l=(n-i)*r+i,u=(s-o)*r+o,c=(l-s)*r+s,h=(c-u)*r+u;a[0]=t,a[1]=o,a[2]=u,a[3]=h,a[4]=h,a[5]=c,a[6]=l,a[7]=n}function l(t,e,i,r,a,o,s,l,u,c,h){var d,f,p,v,m,y=.005,_=1/0;T[0]=u,T[1]=c;for(var w=0;1>w;w+=.05)S[0]=n(t,i,a,s,w),S[1]=n(e,r,o,l,w),v=g(T,S),_>v&&(d=w,_=v);_=1/0;for(var M=0;32>M&&!(b>y);M++)f=d-y,p=d+y,S[0]=n(t,i,a,s,f),S[1]=n(e,r,o,l,f),v=g(S,T),f>=0&&_>v?(d=f,_=v):(C[0]=n(t,i,a,s,p),C[1]=n(e,r,o,l,p),m=g(C,T),1>=p&&_>m?(d=p,_=m):y*=.5);return h&&(h[0]=n(t,i,a,s,d),h[1]=n(e,r,o,l,d)),x(_)}function u(t,e,i,n){var r=1-n;return r*(r*t+2*n*e)+n*n*i}function c(t,e,i,n){return 2*((1-n)*(e-t)+n*(i-e))}function h(t,n,r,a,o){var s=t-2*n+r,l=2*(n-t),u=t-a,c=0;if(e(s)){if(i(l)){var h=-u/l;h>=0&&1>=h&&(o[c++]=h)}}else{var d=l*l-4*s*u;if(e(d)){var h=-l/(2*s);h>=0&&1>=h&&(o[c++]=h)}else if(d>0){var f=x(d),h=(-l+f)/(2*s),p=(-l-f)/(2*s);h>=0&&1>=h&&(o[c++]=h),p>=0&&1>=p&&(o[c++]=p)}}return c}function d(t,e,i){var n=t+i-2*e;return 0===n?.5:(t-e)/n}function f(t,e,i,n,r){var a=(e-t)*n+t,o=(i-e)*n+e,s=(o-a)*n+a;r[0]=t,r[1]=a,r[2]=s,r[3]=s,r[4]=o,r[5]=i}function p(t,e,i,n,r,a,o,s,l){var c,h=.005,d=1/0;T[0]=o,T[1]=s;for(var f=0;1>f;f+=.05){S[0]=u(t,i,r,f),S[1]=u(e,n,a,f);var p=g(T,S);d>p&&(c=f,d=p)}d=1/0;for(var v=0;32>v&&!(b>h);v++){var m=c-h,y=c+h;S[0]=u(t,i,r,m),S[1]=u(e,n,a,m);var p=g(S,T);if(m>=0&&d>p)c=m,d=p;else{C[0]=u(t,i,r,y),C[1]=u(e,n,a,y);var _=g(C,T);1>=y&&d>_?(c=y,d=_):h*=.5}}return l&&(l[0]=u(t,i,r,c),l[1]=u(e,n,a,c)),x(d)}var v=t("./vector"),m=v[he],g=v.distSquare,y=Math.pow,x=Math.sqrt,_=1e-8,b=1e-4,w=x(3),M=1/3,T=m(),S=m(),C=m();return{cubicAt:n,cubicDerivativeAt:r,cubicRootAt:a,cubicExtrema:o,cubicSubdivide:s,cubicProjectPoint:l,quadraticAt:u,quadraticDerivativeAt:c,quadraticRootAt:h,quadraticExtremum:d,quadraticSubdivide:f,quadraticProjectPoint:p}}),e("zrender/core/bbox",[Re,"./vector","./curve"],function(t){var e=t("./vector"),i=t("./curve"),n={},r=Math.min,a=Math.max,o=Math.sin,s=Math.cos,l=e[he](),u=e[he](),c=e[he](),h=2*Math.PI;n.fromPoints=function(t,e,i){if(0!==t[ge]){var n,o=t[0],s=o[0],l=o[0],u=o[1],c=o[1];for(n=1;n<t[ge];n++)o=t[n],s=r(s,o[0]),l=a(l,o[0]),u=r(u,o[1]),c=a(c,o[1]);e[0]=s,e[1]=u,i[0]=l,i[1]=c}},n.fromLine=function(t,e,i,n,o,s){o[0]=r(t,i),o[1]=r(e,n),s[0]=a(t,i),s[1]=a(e,n)};var d=[],f=[];return n.fromCubic=function(t,e,n,o,s,l,u,c,h,p){var v,m=i.cubicExtrema,g=i.cubicAt,y=m(t,n,s,u,d);for(h[0]=1/0,h[1]=1/0,p[0]=-1/0,p[1]=-1/0,v=0;y>v;v++){var x=g(t,n,s,u,d[v]);h[0]=r(x,h[0]),p[0]=a(x,p[0])}for(y=m(e,o,l,c,f),v=0;y>v;v++){var _=g(e,o,l,c,f[v]);h[1]=r(_,h[1]),p[1]=a(_,p[1])}h[0]=r(t,h[0]),p[0]=a(t,p[0]),h[0]=r(u,h[0]),p[0]=a(u,p[0]),h[1]=r(e,h[1]),p[1]=a(e,p[1]),h[1]=r(c,h[1]),p[1]=a(c,p[1])},n.fromQuadratic=function(t,e,n,o,s,l,u,c){var h=i.quadraticExtremum,d=i.quadraticAt,f=a(r(h(t,n,s),1),0),p=a(r(h(e,o,l),1),0),v=d(t,n,s,f),m=d(e,o,l,p);u[0]=r(t,s,v),u[1]=r(e,l,m),c[0]=a(t,s,v),c[1]=a(e,l,m)},n.fromArc=function(t,i,n,r,a,d,f,p,v){var m=e.min,g=e.max,y=Math.abs(a-d);if(1e-4>y%h&&y>1e-4)return p[0]=t-n,p[1]=i-r,v[0]=t+n,void(v[1]=i+r);if(l[0]=s(a)*n+t,l[1]=o(a)*r+i,u[0]=s(d)*n+t,u[1]=o(d)*r+i,m(p,l,u),g(v,l,u),a%=h,0>a&&(a+=h),d%=h,0>d&&(d+=h),a>d&&!f?d+=h:d>a&&f&&(a+=h),f){var x=d;d=a,a=x}for(var _=0;d>_;_+=Math.PI/2)_>a&&(c[0]=s(_)*n+t,c[1]=o(_)*r+i,m(p,c,p),g(v,c,v))},n}),e("zrender/config",[],function(){var t=1;typeof window!==I&&(t=Math.max(window.devicePixelRatio||1,1));var e={debugMode:0,devicePixelRatio:t};return e}),e("zrender/graphic/Style",[Re],function(){function t(t,e,i){var n=e.x,r=e.x2,a=e.y,o=e.y2;e.global||(n=n*i.width+i.x,r=r*i.width+i.x,a=a*i[Pe]+i.y,o=o*i[Pe]+i.y);var s=t.createLinearGradient(n,a,r,o);return s}function e(t,e,i){var n=i.width,r=i[Pe],a=Math.min(n,r),o=e.x,s=e.y,l=e.r;e.global||(o=o*n+i.x,s=s*r+i.y,l*=a);var u=t.createRadialGradient(o,s,0,o,s,l);return u}var i=[["shadowBlur",0],["shadowOffsetX",0],["shadowOffsetY",0],["shadowColor","#000"],["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]],n=function(t){this.extendFrom(t)};n[Ie]={constructor:n,fill:"#000000",stroke:null,opacity:1,lineDash:null,lineDashOffset:0,shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,lineWidth:1,strokeNoScale:!1,text:null,textFill:"#000",textStroke:null,textPosition:"inside",textBaseline:null,textAlign:null,textVerticalAlign:null,textDistance:5,textShadowBlur:0,textShadowOffsetX:0,textShadowOffsetY:0,textTransform:!1,textRotation:0,blend:null,bind:function(t,e,n){for(var r=this,a=n&&n.style,o=!a,s=0;s<i[ge];s++){var l=i[s],u=l[0];(o||r[u]!==a[u])&&(t[u]=r[u]||l[1])}if((o||r.fill!==a.fill)&&(t.fillStyle=r.fill),(o||r[y]!==a[y])&&(t.strokeStyle=r[y]),(o||r[O]!==a[O])&&(t.globalAlpha=null==r[O]?1:r[O]),(o||r.blend!==a.blend)&&(t.globalCompositeOperation=r.blend||"source-over"),this.hasStroke()){var c=r[x];t[x]=c/(this.strokeNoScale&&e&&e.getLineScale?e.getLineScale():1)}},hasFill:function(){var t=this.fill;return null!=t&&"none"!==t},hasStroke:function(){var t=this[y];return null!=t&&"none"!==t&&this[x]>0},extendFrom:function(t,e){if(t){var i=this;for(var n in t)!t.hasOwnProperty(n)||!e&&i.hasOwnProperty(n)||(i[n]=t[n])}},set:function(t,e){typeof t===Le?this[t]=e:this.extendFrom(t,!0)},clone:function(){var t=new this.constructor;return t.extendFrom(this,!0),t},getGradient:function(i,n,r){for(var a="radial"===n.type?e:t,o=a(i,n,r),s=n[ue],l=0;l<s[ge];l++)o.addColorStop(s[l].offset,s[l].color);return o}};for(var r=n[Ie],a=0;a<i[ge];a++){var o=i[a];o[0]in r||(r[o[0]]=o[1])}return n.getGradient=r.getGradient,n}),e("zrender/Element",[Re,"./core/guid","./mixin/Eventful","./mixin/Transformable","./mixin/Animatable","./core/util"],function(t){var e=t("./core/guid"),i=t("./mixin/Eventful"),r=t("./mixin/Transformable"),a=t("./mixin/Animatable"),o=t("./core/util"),s=function(t){r.call(this,t),i.call(this,t),a.call(this,t),this.id=t.id||e()};return s[Ie]={type:"element",name:"",__zr:null,ignore:!1,clipPath:null,drift:function(t,e){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this[n];i||(i=this[n]=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.dirty(!1)},beforeUpdate:function(){},afterUpdate:function(){},update:function(){this.updateTransform()},traverse:function(){},attrKV:function(t,e){if(t===R||"scale"===t||"origin"===t){if(e){var i=this[t];i||(i=this[t]=[]),i[0]=e[0],i[1]=e[1]}}else this[t]=e},hide:function(){this[xe]=!0,this.__zr&&this.__zr.refresh()},show:function(){this[xe]=!1,this.__zr&&this.__zr.refresh()},attr:function(t,e){if(typeof t===Le)this.attrKV(t,e);else if(o[le](t))for(var i in t)t.hasOwnProperty(i)&&this.attrKV(i,t[i]);return this.dirty(!1),this},setClipPath:function(t){var e=this.__zr;e&&t.addSelfToZr(e),this.clipPath&&this.clipPath!==t&&this.removeClipPath(),this.clipPath=t,t.__zr=e,t.__clipTarget=this,this.dirty(!1)},removeClipPath:function(){var t=this.clipPath;t&&(t.__zr&&t.removeSelfFromZr(t.__zr),t.__zr=null,t.__clipTarget=null,this.clipPath=null,this.dirty(!1))},addSelfToZr:function(t){this.__zr=t;var e=this.animators;if(e)for(var i=0;i<e[ge];i++)t[Ce].addAnimator(e[i]);this.clipPath&&this.clipPath.addSelfToZr(t)},removeSelfFromZr:function(t){this.__zr=null;var e=this.animators;if(e)for(var i=0;i<e[ge];i++)t[Ce].removeAnimator(e[i]);this.clipPath&&this.clipPath.removeSelfFromZr(t)}},o.mixin(s,a),o.mixin(s,r),o.mixin(s,i),s}),e("echarts/coord/cartesian/Cartesian",[Re,De],function(t){function e(t){return this._axes[t]}var i=t(De),n=function(t){this._axes={},this._dimList=[],this.name=t||""};return n[Ie]={constructor:n,type:"cartesian",getAxis:function(t){return this._axes[t]},getAxes:function(){return i.map(this._dimList,e,this)},getAxesByScale:function(t){return t=t[ke](),i[q](this.getAxes(),function(e){return e.scale.type===t})},addAxis:function(t){var e=t.dim;this._axes[e]=t,this._dimList.push(e)},dataToCoord:function(t){return this._dataCoordConvert(t,a)},coordToData:function(t){return this._dataCoordConvert(t,"coordToData")},_dataCoordConvert:function(t,e){for(var i=this._dimList,n=t instanceof Array?[]:{},r=0;r<i[ge];r++){var a=i[r],o=this._axes[a];n[a]=o[e](t[a])}return n}},n}),e("echarts/util/component",[Re,De,"./clazz"],function(t){var e=t(De),i=t("./clazz"),n=i.parseClassType,r=0,a={},o="_";return a.getUID=function(t){return[t||"",r++,Math.random()].join(o)},a.enableSubTypeDefaulter=function(t){var e={};return t.registerSubTypeDefaulter=function(t,i){t=n(t),e[t.main]=i},t.determineSubType=function(i,r){var a=r.type;if(!a){var o=n(i).main;t.hasSubTypes(i)&&e[o]&&(a=e[o](r))}return a},t},a.enableTopologicalTravel=function(t,i){function n(t){var n={},o=[];return e.each(t,function(s){var l=r(n,s),u=l.originalDeps=i(s),c=a(u,t);l.entryCount=c[ge],0===l.entryCount&&o.push(s),e.each(c,function(t){e[me](l.predecessor,t)<0&&l.predecessor.push(t);var i=r(n,t);e[me](i.successor,t)<0&&i.successor.push(s)})}),{graph:n,noEntryList:o}}function r(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}function a(t,i){var n=[];return e.each(t,function(t){e[me](i,t)>=0&&n.push(t)}),n}t.topologicalTravel=function(t,i,r,a){function o(t){u[t].entryCount--,0===u[t].entryCount&&c.push(t)}function s(t){h[t]=!0,o(t)}if(t[ge]){var l=n(i),u=l.graph,c=l.noEntryList,h={};for(e.each(t,function(t){h[t]=!0});c[ge];){var d=c.pop(),f=u[d],p=!!h[d];p&&(r.call(a,d,f.originalDeps.slice()),delete h[d]),e.each(f.successor,p?s:o)}e.each(h,function(){throw new Error("Circle dependency may exists")})}}},a}),e("echarts/model/mixin/boxLayout",[Re],function(){return{getBoxLayoutParams:function(){return{left:this.get("left"),top:this.get("top"),right:this.get("right"),bottom:this.get(ye),width:this.get("width"),height:this.get(Pe)}}}}),e("zrender/core/guid",[],function(){var t=2311;return function(){return t++}}),e("zrender/mixin/Transformable",[Re,"../core/matrix","../core/vector"],function(t){function e(t){return t>o||-o>t}var i=t("../core/matrix"),r=t("../core/vector"),a=i.identity,o=5e-5,s=function(t){t=t||{},t[R]||(this[R]=[0,0]),null==t[p]&&(this[p]=0),t.scale||(this.scale=[1,1]),this.origin=this.origin||null},l=s[Ie];l[n]=null,l.needLocalTransform=function(){return e(this[p])||e(this[R][0])||e(this[R][1])||e(this.scale[0]-1)||e(this.scale[1]-1)},l.updateTransform=function(){var t=this[v],e=t&&t[n],r=this.needLocalTransform(),o=this[n];return r||e?(o=o||i[he](),r?this.getLocalTransform(o):a(o),e&&(r?i.mul(o,t[n],o):i.copy(o,t[n])),this[n]=o,this.invTransform=this.invTransform||i[he](),void i.invert(this.invTransform,o)):void(o&&a(o))},l.getLocalTransform=function(t){t=t||[],a(t);var e=this.origin,n=this.scale,r=this[p],o=this[R];return e&&(t[4]-=e[0],t[5]-=e[1]),i.scale(t,t,n),r&&i.rotate(t,t,r),e&&(t[4]+=e[0],t[5]+=e[1]),t[4]+=o[0],t[5]+=o[1],t},l.setTransform=function(t){var e=this[n],i=t.dpr||1;e?t.setTransform(i*e[0],i*e[1],i*e[2],i*e[3],i*e[4],i*e[5]):t.setTransform(i,0,0,i,0,0)},l.restoreTransform=function(t){var e=(this[n],t.dpr||1);t.setTransform(e,0,0,e,0,0)};var u=[];return l.decomposeTransform=function(){if(this[n]){var t=this[v],r=this[n];t&&t[n]&&(i.mul(u,t.invTransform,r),r=u);var a=r[0]*r[0]+r[1]*r[1],o=r[2]*r[2]+r[3]*r[3],s=this[R],l=this.scale;e(a-1)&&(a=Math.sqrt(a)),e(o-1)&&(o=Math.sqrt(o)),r[0]<0&&(a=-a),r[3]<0&&(o=-o),s[0]=r[4],s[1]=r[5],l[0]=a,l[1]=o,this[p]=Math.atan2(-r[1]/o,r[0]/a)}},l.getGlobalScale=function(){var t=this[n];if(!t)return[1,1];var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]),i=Math.sqrt(t[2]*t[2]+t[3]*t[3]);return t[0]<0&&(e=-e),t[3]<0&&(i=-i),[e,i]},l.transformCoordToLocal=function(t,e){var i=[t,e],n=this.invTransform;return n&&r[_](i,i,n),i},l.transformCoordToGlobal=function(t,e){var i=[t,e],a=this[n];return a&&r[_](i,i,a),i},s}),e("zrender/mixin/Animatable",[Re,"../animation/Animator","../core/util","../core/log"],function(t){var e=t("../animation/Animator"),i=t("../core/util"),n=i.isString,r=i.isFunction,a=i[le],o=t("../core/log"),s=function(){this.animators=[]};return s[Ie]={constructor:s,animate:function(t,n){var r,a=!1,s=this,l=this.__zr;if(t){var u=t.split("."),c=s;a="shape"===u[0];for(var h=0,d=u[ge];d>h;h++)c&&(c=c[u[h]]);c&&(r=c)}else r=s;if(!r)return void o('Property "'+t+'" is not existed in element '+s.id);var f=s.animators,p=new e(r,n);return p.during(function(){s.dirty(a)}).done(function(){f[ie](i[me](f,p),1)}),f.push(p),l&&l[Ce].addAnimator(p),p},stopAnimation:function(t){for(var e=this.animators,i=e[ge],n=0;i>n;n++)e[n].stop(t);return e[ge]=0,this},animateTo:function(t,e,i,a,o){function s(){u--,u||o&&o()}n(i)?(o=a,a=i,i=0):r(a)?(o=a,a="linear",i=0):r(i)?(o=i,i=0):r(e)?(o=e,e=500):e||(e=500),this.stopAnimation(),this._animateToShallow("",this,t,e,i,a,o);var l=this.animators.slice(),u=l[ge];u||o&&o();for(var c=0;c<l[ge];c++)l[c].done(s).start(a)},_animateToShallow:function(t,e,n,r,o){var s={},l=0;for(var u in n)if(n.hasOwnProperty(u))if(null!=e[u])a(n[u])&&!i.isArrayLike(n[u])?this._animateToShallow(t?t+"."+u:u,e[u],n[u],r,o):(s[u]=n[u],l++);else if(null!=n[u])if(t){var c={};c[t]={},c[t][u]=n[u],this.attr(c)}else this.attr(u,n[u]);return l>0&&this.animate(t,!1).when(null==r?500:r,s).delay(o||0),this}},s}),e("echarts/coord/Axis",[Re,"../util/number",De],function(t){function e(t,e){var i=t[1]-t[0],n=e,r=i/n/2;t[0]+=r,t[1]-=r}var i=t("../util/number"),n=i.linearMap,r=t(De),o=[0,1],s=function(t,e,i){this.dim=t,this.scale=e,this._extent=i||[0,0],this.inverse=!1,this.onBand=!1};return s[Ie]={constructor:s,contain:function(t){var e=this._extent,i=Math.min(e[0],e[1]),n=Math.max(e[0],e[1]);return t>=i&&n>=t},containData:function(t){return this[D](this[a](t))},getExtent:function(){var t=this._extent.slice();return t},getPixelPrecision:function(t){return i.getPixelPrecision(t||this.scale[z](),this._extent)},setExtent:function(t,e){var i=this._extent;i[0]=t,i[1]=e},dataToCoord:function(t,i){var r=this._extent,a=this.scale;return t=a.normalize(t),this.onBand&&a.type===d&&(r=r.slice(),e(r,a.count())),n(t,o,r,i)},coordToData:function(t,i){var r=this._extent,a=this.scale;this.onBand&&a.type===d&&(r=r.slice(),e(r,a.count()));var s=n(t,r,o,i);return this.scale.scale(s)},getTicksCoords:function(t){if(this.onBand&&!t){for(var e=this.getBands(),i=[],n=0;n<e[ge];n++)i.push(e[n][0]);return e[n-1]&&i.push(e[n-1][1]),i}return r.map(this.scale[k](),this[a],this)},getLabelsCoords:function(){return r.map(this.scale[k](),this[a],this)},getBands:function(){for(var t=this[z](),e=[],i=this.scale.count(),n=t[0],r=t[1],a=r-n,o=0;i>o;o++)e.push([a*o/i+n,a*(o+1)/i+n]);return e},getBandWidth:function(){var t=this._extent,e=this.scale[z](),i=e[1]-e[0]+(this.onBand?1:0);0===i&&(i=1);var n=Math.abs(t[1]-t[0]);return Math.abs(n)/i}},s}),e("echarts/coord/cartesian/axisLabelInterval",[Re,De,"../axisHelper"],function(t){var e=t(De),i=t("../axisHelper");return function(t){var n=t.model,o=n[Se]("axisLabel"),s=o.get("interval");return t.type!==r||"auto"!==s?"auto"===s?0:s:i.getAxisLabelInterval(e.map(t.scale[k](),t[a],t),n.getFormattedLabels(),o[Se](G)[V](),t.isHorizontal())}}),e("zrender/core/log",[Re,"../config"],function(t){var e=t("../config");return function(){if(0!==e.debugMode)if(1==e.debugMode)for(var t in arguments)throw new Error(arguments[t]);else if(e.debugMode>1)for(var t in arguments)console.log(arguments[t]) +}}),e("zrender/animation/Animator",[Re,"./Clip","../tool/color","../core/util"],function(t){function e(t,e){return t[e]}function i(t,e,i){t[e]=i}function n(t,e,i){return(e-t)*i+t}function r(t,e,i){return i>.5?e:t}function a(t,e,i,r,a){var o=t[ge];if(1==a)for(var s=0;o>s;s++)r[s]=n(t[s],e[s],i);else for(var l=t[0][ge],s=0;o>s;s++)for(var u=0;l>u;u++)r[s][u]=n(t[s][u],e[s][u],i)}function o(t,e,i){var n=t[ge],r=e[ge];if(n!==r){var a=n>r;if(a)t[ge]=r;else for(var o=n;r>o;o++)t.push(1===i?e[o]:g.call(e[o]))}for(var s=t[0]&&t[0][ge],o=0;o<t[ge];o++)if(1===i)isNaN(t[o])&&(t[o]=e[o]);else for(var l=0;s>l;l++)isNaN(t[o][l])&&(t[o][l]=e[o][l])}function s(t,e,i){if(t===e)return!0;var n=t[ge];if(n!==e[ge])return!1;if(1===i){for(var r=0;n>r;r++)if(t[r]!==e[r])return!1}else for(var a=t[0][ge],r=0;n>r;r++)for(var o=0;a>o;o++)if(t[r][o]!==e[r][o])return!1;return!0}function l(t,e,i,n,r,a,o,s,l){var c=t[ge];if(1==l)for(var h=0;c>h;h++)s[h]=u(t[h],e[h],i[h],n[h],r,a,o);else for(var d=t[0][ge],h=0;c>h;h++)for(var f=0;d>f;f++)s[h][f]=u(t[h][f],e[h][f],i[h][f],n[h][f],r,a,o)}function u(t,e,i,n,r,a,o){var s=.5*(i-t),l=.5*(n-e);return(2*(e-i)+s+l)*o+(-3*(e-i)-2*s-l)*a+s*r+e}function c(t){if(m(t)){var e=t[ge];if(m(t[0])){for(var i=[],n=0;e>n;n++)i.push(g.call(t[n]));return i}return g.call(t)}return t}function h(t){return t[0]=Math.floor(t[0]),t[1]=Math.floor(t[1]),t[2]=Math.floor(t[2]),"rgba("+t.join(",")+")"}function d(t,e,i,c,d){var v=t._getter,g=t._setter,y="spline"===e,x=c[ge];if(x){var _,b=c[0].value,w=m(b),M=!1,T=!1,S=w&&m(b[0])?2:1;c.sort(function(t,e){return t.time-e.time}),_=c[x-1].time;for(var C=[],A=[],P=c[0].value,L=!0,I=0;x>I;I++){C.push(c[I].time/_);var k=c[I].value;if(w&&s(k,P,S)||!w&&k===P||(L=!1),P=k,typeof k==Le){var z=p.parse(k);z?(k=z,M=!0):T=!0}A.push(k)}if(!L){for(var D=A[x-1],I=0;x-1>I;I++)w?o(A[I],D,S):!isNaN(A[I])||isNaN(D)||T||M||(A[I]=D);w&&o(v(t._target,d),D,S);var O,R,E,B,N,V,F=0,G=0;if(M)var H=[0,0,0,0];var Z=function(t,e){var i;if(0>e)i=0;else if(G>e){for(O=Math.min(F+1,x-1),i=O;i>=0&&!(C[i]<=e);i--);i=Math.min(i,x-2)}else{for(i=F;x>i&&!(C[i]>e);i++);i=Math.min(i-1,x-2)}F=i,G=e;var o=C[i+1]-C[i];if(0!==o)if(R=(e-C[i])/o,y)if(B=A[i],E=A[0===i?i:i-1],N=A[i>x-2?x-1:i+1],V=A[i>x-3?x-1:i+2],w)l(E,B,N,V,R,R*R,R*R*R,v(t,d),S);else{var s;if(M)s=l(E,B,N,V,R,R*R,R*R*R,H,1),s=h(H);else{if(T)return r(B,N,R);s=u(E,B,N,V,R,R*R,R*R*R)}g(t,d,s)}else if(w)a(A[i],A[i+1],R,v(t,d),S);else{var s;if(M)a(A[i],A[i+1],R,H,1),s=h(H);else{if(T)return r(A[i],A[i+1],R);s=n(A[i],A[i+1],R)}g(t,d,s)}},q=new f({target:t._target,life:_,loop:t._loop,delay:t._delay,onframe:Z,ondestroy:i});return e&&"spline"!==e&&(q.easing=e),q}}}var f=t("./Clip"),p=t("../tool/color"),v=t("../core/util"),m=v.isArrayLike,g=Array[Ie].slice,y=function(t,n,r,a){this._tracks={},this._target=t,this._loop=n||!1,this._getter=r||e,this._setter=a||i,this._clipCount=0,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[]};return y[Ie]={when:function(t,e){var i=this._tracks;for(var n in e)if(e.hasOwnProperty(n)){if(!i[n]){i[n]=[];var r=this._getter(this._target,n);if(null==r)continue;0!==t&&i[n].push({time:0,value:c(r)})}i[n].push({time:t,value:e[n]})}return this},during:function(t){return this._onframeList.push(t),this},_doneCallback:function(){this._tracks={},this._clipList[ge]=0;for(var t=this._doneList,e=t[ge],i=0;e>i;i++)t[i].call(this)},start:function(t){var e,i=this,n=0,r=function(){n--,n||i._doneCallback()};for(var a in this._tracks)if(this._tracks.hasOwnProperty(a)){var o=d(this,t,r,this._tracks[a],a);o&&(this._clipList.push(o),n++,this[Ce]&&this[Ce].addClip(o),e=o)}if(e){var s=e.onframe;e.onframe=function(t,e){s(t,e);for(var n=0;n<i._onframeList[ge];n++)i._onframeList[n](t,e)}}return n||this._doneCallback(),this},stop:function(t){for(var e=this._clipList,i=this[Ce],n=0;n<e[ge];n++){var r=e[n];t&&r.onframe(this._target,1),i&&i.removeClip(r)}e[ge]=0},delay:function(t){return this._delay=t,this},done:function(t){return t&&this._doneList.push(t),this},getClips:function(){return this._clipList}},y}),e("echarts/coord/cartesian/AxisModel",[Re,"../../model/Component",De,"../axisModelCreator","../axisModelCommonMixin","../axisModelZoomMixin"],function(t){function e(t,e){return e.type||(e.data?r:"value")}var i=t("../../model/Component"),n=t(De),a=t("../axisModelCreator"),o=i[oe]({type:"cartesian2dAxis",axis:null,init:function(){o.superApply(this,"init",arguments),this.resetRange()},mergeOption:function(){o.superApply(this,"mergeOption",arguments),this.resetRange()},restoreData:function(){o.superApply(this,"restoreData",arguments),this.resetRange()},findGridModel:function(){return this[M][S]({mainType:"grid",index:this.get("gridIndex"),id:this.get("gridId")})[0]}});n.merge(o[Ie],t("../axisModelCommonMixin")),n.merge(o[Ie],t("../axisModelZoomMixin"));var s={offset:0};return a("x",o,e,s),a("y",o,e,s),o}),e("zrender/animation/Clip",[Re,"./easing"],function(t){function e(t){this._target=t[J],this._life=t.life||1e3,this._delay=t.delay||0,this._initialized=!1,this.loop=null==t.loop?!1:t.loop,this.gap=t.gap||0,this.easing=t.easing||"Linear",this.onframe=t.onframe,this.ondestroy=t.ondestroy,this.onrestart=t.onrestart}var i=t("./easing");return e[Ie]={constructor:e,step:function(t){this._initialized||(this._startTime=t+this._delay,this._initialized=!0);var e=(t-this._startTime)/this._life;if(!(0>e)){e=Math.min(e,1);var n=this.easing,r=typeof n==Le?i[n]:n,a=typeof r===j?r(e):e;return this.fire("frame",a),1==e?this.loop?(this.restart(t),"restart"):(this._needsRemove=!0,"destroy"):null}},restart:function(t){var e=(t-this._startTime)%this._life;this._startTime=t-e+this.gap,this._needsRemove=!1},fire:function(t,e){t="on"+t,this[t]&&this[t](this._target,e)}},e}),e("echarts/coord/axisModelZoomMixin",[Re],function(){return{getMin:function(){var t=this[C],e=null!=t.rangeStart?t.rangeStart:t.min;return e instanceof Date&&(e=+e),e},getMax:function(){var t=this[C],e=null!=t.rangeEnd?t.rangeEnd:t.max;return e instanceof Date&&(e=+e),e},getNeedCrossZero:function(){var t=this[C];return null!=t.rangeStart||null!=t.rangeEnd?!1:!t.scale},setRange:function(t,e){this[C].rangeStart=t,this[C].rangeEnd=e},resetRange:function(){this[C].rangeStart=this[C].rangeEnd=null}}}),e("echarts/coord/axisModelCreator",[Re,"./axisDefault",De,"../model/Component","../util/layout"],function(t){var e=t("./axisDefault"),i=t(De),n=t("../model/Component"),a=t("../util/layout"),o=["value",r,"time","log"];return function(t,r,s,l){i.each(o,function(n){r[oe]({type:t+"Axis."+n,mergeDefaultAndTheme:function(e,r){var o=this.layoutMode,l=o?a.getLayoutParams(e):{},u=r.getTheme();i.merge(e,u.get(n+"Axis")),i.merge(e,this.getDefaultOption()),e.type=s(t,e),o&&a.mergeLayoutParam(e,l,o)},defaultOption:i.mergeAll([{},e[n+"Axis"],l],!0)})}),n.registerSubTypeDefaulter(t+"Axis",i.curry(s,t))}}),e("echarts/coord/axisModelCommonMixin",[Re,De,"./axisHelper"],function(t){function e(t){return a[le](t)&&null!=t.value?t.value:t}function i(){return this.get("type")===r&&a.map(this.get("data"),e)}function n(){return o.getFormattedLabels(this.axis,this.get("axisLabel.formatter"))}var a=t(De),o=t("./axisHelper");return{getFormattedLabels:n,getCategories:i}}),e("zrender/animation/easing",[],function(){var t={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(-Math.pow(2,-10*(t-1))+2)},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),-(i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n)))},elasticOut:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),i*Math.pow(2,-10*t)*Math.sin(2*(t-e)*Math.PI/n)+1)},elasticInOut:function(t){var e,i=.1,n=.4;return 0===t?0:1===t?1:(!i||1>i?(i=1,e=n/4):e=n*Math.asin(1/i)/(2*Math.PI),(t*=2)<1?-.5*i*Math.pow(2,10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n):i*Math.pow(2,-10*(t-=1))*Math.sin(2*(t-e)*Math.PI/n)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?.5*t*t*((e+1)*t-e):.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(e){return 1-t.bounceOut(1-e)},bounceOut:function(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(e){return.5>e?.5*t.bounceIn(2*e):.5*t.bounceOut(2*e-1)+.5}};return t}),e("echarts/coord/axisDefault",[Re,De],function(t){var e=t(De),i={show:!0,zlevel:0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisLine:{show:!0,onZero:!0,lineStyle:{color:"#333",width:1,type:"solid"}},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,margin:8,textStyle:{fontSize:12}},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}}},n=e.merge({boundaryGap:!0,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},i),r=e.merge({boundaryGap:[0,0],splitNumber:5},i),a=e[ae]({scale:!0,min:"dataMin",max:"dataMax"},r),o=e[ae]({logBase:10},r);return o.scale=!0,{categoryAxis:n,valueAxis:r,timeAxis:a,logAxis:o}}),e("zrender/contain/arc",[Re,"./util"],function(t){var e=t("./util").normalizeRadian,i=2*Math.PI;return{containStroke:function(t,n,r,a,o,s,l,u,c){if(0===l)return!1;var h=l;u-=t,c-=n;var d=Math.sqrt(u*u+c*c);if(d-h>r||r>d+h)return!1;if(Math.abs(a-o)%i<1e-4)return!0;if(s){var f=a;a=e(o),o=e(f)}else a=e(a),o=e(o);a>o&&(o+=i);var p=Math.atan2(c,u);return 0>p&&(p+=i),p>=a&&o>=p||p+i>=a&&o>=p+i}}}),e("zrender/contain/cubic",[Re,"../core/curve"],function(t){var e=t("../core/curve");return{containStroke:function(t,i,n,r,a,o,s,l,u,c,h){if(0===u)return!1;var d=u;if(h>i+d&&h>r+d&&h>o+d&&h>l+d||i-d>h&&r-d>h&&o-d>h&&l-d>h||c>t+d&&c>n+d&&c>a+d&&c>s+d||t-d>c&&n-d>c&&a-d>c&&s-d>c)return!1;var f=e.cubicProjectPoint(t,i,n,r,a,o,s,l,c,h,null);return d/2>=f}}}),e("zrender/contain/line",[],function(){return{containStroke:function(t,e,i,n,r,a,o){if(0===r)return!1;var s=r,l=0,u=t;if(o>e+s&&o>n+s||e-s>o&&n-s>o||a>t+s&&a>i+s||t-s>a&&i-s>a)return!1;if(t===i)return Math.abs(a-t)<=s/2;l=(e-n)/(t-i),u=(t*n-i*e)/(t-i);var c=l*a-o+u,h=c*c/(l*l+1);return s/2*s/2>=h}}}),e("zrender/contain/quadratic",[Re,"../core/curve"],function(t){var e=t("../core/curve");return{containStroke:function(t,i,n,r,a,o,s,l,u){if(0===s)return!1;var c=s;if(u>i+c&&u>r+c&&u>o+c||i-c>u&&r-c>u&&o-c>u||l>t+c&&l>n+c&&l>a+c||t-c>l&&n-c>l&&a-c>l)return!1;var h=e.quadraticProjectPoint(t,i,n,r,a,o,l,u,null);return c/2>=h}}}),e("zrender/contain/util",[Re],function(){var t=2*Math.PI;return{normalizeRadian:function(e){return e%=t,0>e&&(e+=t),e}}}),e("zrender/contain/windingLine",[],function(){return function(t,e,i,n,r,a){if(a>e&&a>n||e>a&&n>a)return 0;if(n===e)return 0;var o=e>n?1:-1,s=(a-e)/(n-e);(1===s||0===s)&&(o=e>n?.5:-.5);var l=s*(i-t)+t;return l>r?o:0}}),e("zrender/core/LRU",[Re],function(){var t=function(){this.head=null,this.tail=null,this._len=0},e=t[Ie];e.insert=function(t){var e=new i(t);return this.insertEntry(e),e},e.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,this.tail=t):this.head=this.tail=t,this._len++},e[se]=function(t){var e=t.prev,i=t.next;e?e.next=i:this.head=i,i?i.prev=e:this.tail=e,t.next=t.prev=null,this._len--},e.len=function(){return this._len};var i=function(t){this.value=t,this.next,this.prev},n=function(e){this._list=new t,this._map={},this._maxSize=e||10},r=n[Ie];return r.put=function(t,e){var i=this._list,n=this._map;if(null==n[t]){var r=i.len();if(r>=this._maxSize&&r>0){var a=i.head;i[se](a),delete n[a.key]}var o=i.insert(e);o.key=t,n[t]=o}},r.get=function(t){var e=this._map[t],i=this._list;return null!=e?(e!==i.tail&&(i[se](e),i.insertEntry(e)),e.value):void 0},r.clear=function(){this._list.clear(),this._map={}},n}),e("echarts/chart/helper/createListFromArray",[Re,"../../data/List","../../data/helper/completeDimensions",De,"../../util/model","../../CoordinateSystem"],function(t){function e(t){for(var e=0;e<t[ge]&&null==t[e];)e++;return t[e]}function i(t){var i=e(t);return null!=i&&!f[U](m(i))}function n(t,e,n){t=t||[];var r=e.get(ve),a=y[r],o=v.get(r),l=a&&a(t,e,n),d=l&&l[c];d||(d=o&&o[c]||["x","y"],d=h(d,t,d[A](["value"])));var x=l?l.categoryIndex:-1,_=new u(d,e),b=s(l,t),w={},M=x>=0&&i(t)?function(t,e,i,n){return p.isDataItemOption(t)&&(_.hasItemOption=!0),n===x?i:g(m(t),d[n])}:function(t,e,i,n){var r=m(t),a=g(r&&r[n],d[n]);p.isDataItemOption(t)&&(_.hasItemOption=!0);var o=l&&l.categoryAxesModels;return o&&o[e]&&typeof a===Le&&(w[e]=w[e]||o[e].getCategories(),a=f[me](w[e],a),0>a&&!isNaN(a)&&(a=+a)),a};return _.hasItemOption=!1,_.initData(t,b,M),_}function a(t){return t!==r&&"time"!==t}function o(t){return t===r?d:"time"===t?"time":"float"}function s(t,e){var i,n=[],r=t&&t[c][t.categoryIndex];if(r&&(i=t.categoryAxesModels[r.name]),i){var a=i.getCategories();if(a){var o=e[ge];if(f[U](e[0])&&e[0][ge]>1){n=[];for(var s=0;o>s;s++)n[s]=a[e[s][t.categoryIndex||0]]}else n=a.slice(0)}}return n}var u=t("../../data/List"),h=t("../../data/helper/completeDimensions"),f=t(De),p=t("../../util/model"),v=t("../../CoordinateSystem"),m=p.getDataItemValue,g=p.converDataValue,y={cartesian2d:function(t,e,i){var n=f.map(["xAxis","yAxis"],function(t){return i[S]({mainType:t,index:e.get(t+"Index"),id:e.get(t+"Id")})[0]}),s=n[0],l=n[1],u=s.get("type"),c=l.get("type"),d=[{name:"x",type:o(u),stackable:a(u)},{name:"y",type:o(c),stackable:a(c)}],p=u===r,v=c===r;h(d,t,["x","y","z"]);var m={};return p&&(m.x=s),v&&(m.y=l),{dimensions:d,categoryIndex:p?0:v?1:-1,categoryAxesModels:m}},polar:function(t,e,i){var n=i[S]({mainType:"polar",index:e.get("polarIndex"),id:e.get("polarId")})[0],s=n.findAxisModel("angleAxis"),u=n.findAxisModel("radiusAxis"),c=u.get("type"),d=s.get("type"),f=[{name:"radius",type:o(c),stackable:a(c)},{name:"angle",type:o(d),stackable:a(d)}],p=d===r,v=c===r;h(f,t,[l,"angle","value"]);var m={};return v&&(m[l]=u),p&&(m.angle=s),{dimensions:f,categoryIndex:p?1:v?0:-1,categoryAxesModels:m}},geo:function(t){return{dimensions:h([{name:"lng"},{name:"lat"}],t,["lng","lat","value"])}}};return n}),e("zrender/graphic/helper/poly",[Re,"./smoothSpline","./smoothBezier"],function(t){var e=t("./smoothSpline"),n=t("./smoothBezier");return{buildPath:function(t,r,a){var o=r.points,s=r.smooth;if(o&&o[ge]>=2){if(s&&"spline"!==s){var l=n(o,s,a,r.smoothConstraint);t[i](o[0][0],o[0][1]);for(var u=o[ge],c=0;(a?u:u-1)>c;c++){var h=l[2*c],d=l[2*c+1],f=o[(c+1)%u];t.bezierCurveTo(h[0],h[1],d[0],d[1],f[0],f[1])}}else{"spline"===s&&(o=e(o,a)),t[i](o[0][0],o[0][1]);for(var c=1,p=o[ge];p>c;c++)t.lineTo(o[c][0],o[c][1])}a&&t.closePath()}}}}),e("zrender/animation/Animation",[Re,"../core/util","../core/event","./requestAnimationFrame","./Animator"],function(t){var e=t("../core/util"),i=t("../core/event").Dispatcher,n=t("./requestAnimationFrame"),r=t("./Animator"),a=function(t){t=t||{},this.stage=t.stage||{},this.onframe=t.onframe||function(){},this._clips=[],this._running=!1,this._time,this._pausedTime,this._pauseStart,this._paused=!1,i.call(this)};return a[Ie]={constructor:a,addClip:function(t){this._clips.push(t)},addAnimator:function(t){t[Ce]=this;for(var e=t.getClips(),i=0;i<e[ge];i++)this.addClip(e[i])},removeClip:function(t){var i=e[me](this._clips,t);i>=0&&this._clips[ie](i,1)},removeAnimator:function(t){for(var e=t.getClips(),i=0;i<e[ge];i++)this.removeClip(e[i]);t[Ce]=null},_update:function(){for(var t=(new Date).getTime()-this._pausedTime,e=t-this._time,i=this._clips,n=i[ge],r=[],a=[],o=0;n>o;o++){var s=i[o],l=s.step(t);l&&(r.push(l),a.push(s))}for(var o=0;n>o;)i[o]._needsRemove?(i[o]=i[n-1],i.pop(),n--):o++;n=r[ge];for(var o=0;n>o;o++)a[o].fire(r[o]);this._time=t,this.onframe(e),this[re]("frame",e),this.stage[ce]&&this.stage[ce]()},_startLoop:function(){function t(){e._running&&(n(t),!e._paused&&e._update())}var e=this;this._running=!0,n(t)},start:function(){this._time=(new Date).getTime(),this._pausedTime=0,this._startLoop()},stop:function(){this._running=!1},pause:function(){this._paused||(this._pauseStart=(new Date).getTime(),this._paused=!0)},resume:function(){this._paused&&(this._pausedTime+=(new Date).getTime()-this._pauseStart,this._paused=!1)},clear:function(){this._clips=[]},animate:function(t,e){e=e||{};var i=new r(t,e.loop,e.getter,e.setter);return i}},e.mixin(a,i),a}),e("zrender/Handler",[Re,"./core/util","./mixin/Draggable","./mixin/Eventful"],function(t){function e(t,e,i){return{type:t,event:i,target:e,cancelBubble:!1,offsetX:i.zrX,offsetY:i.zrY,gestureEvent:i.gestureEvent,pinchX:i.pinchX,pinchY:i.pinchY,pinchScale:i.pinchScale,wheelDelta:i.zrDelta,zrByTouch:i.zrByTouch}}function i(){}function n(t,e,i){if(t[t.rectHover?"rectContain":D](e,i)){for(var n=t;n;){if(n.silent||n.clipPath&&!n.clipPath[D](e,i))return!1;n=n[v]}return!0}return!1}var r=t("./core/util"),a=t("./mixin/Draggable"),o=t("./mixin/Eventful");i[Ie].dispose=function(){};var s=["click","dblclick","mousewheel",te,"mouseup","mousedown","mousemove","contextmenu"],l=function(t,e,n,l){o.call(this),this[be]=t,this.painter=e,this.painterRoot=l,n=n||new i,this.proxy=n,n.handler=this,this._hovered,this._lastTouchMoment,this._lastX,this._lastY,a.call(this),r.each(s,function(t){n.on&&n.on(t,this[t],this)},this)};return l[Ie]={constructor:l,mousemove:function(t){var e=t.zrX,i=t.zrY,n=this.findHover(e,i,null),r=this._hovered,a=this.proxy;this._hovered=n,a.setCursor&&a.setCursor(n?n.cursor:"default"),r&&n!==r&&r.__zr&&this.dispatchToElement(r,te,t),this.dispatchToElement(n,"mousemove",t),n&&n!==r&&this.dispatchToElement(n,ee,t)},mouseout:function(t){this.dispatchToElement(this._hovered,te,t);var e,i=t.toElement||t.relatedTarget;do i=i&&i.parentNode;while(i&&9!=i.nodeType&&!(e=i===this.painterRoot));!e&&this[re]("globalout",{event:t})},resize:function(){this._hovered=null},dispatch:function(t,e){var i=this[t];i&&i.call(this,e)},dispose:function(){this.proxy.dispose(),this[be]=this.proxy=this.painter=null},setCursorStyle:function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},dispatchToElement:function(t,i,n){for(var r="on"+i,a=e(i,t,n),o=t;o&&(o[r]&&(a.cancelBubble=o[r].call(o,a)),o[re](i,a),o=o[v],!a.cancelBubble););a.cancelBubble||(this[re](i,a),this.painter&&this.painter.eachOtherLayer(function(t){typeof t[r]==j&&t[r].call(t,a),t[re]&&t[re](i,a)}))},findHover:function(t,e,i){for(var r=this[be].getDisplayList(),a=r[ge]-1;a>=0;a--)if(!r[a].silent&&r[a]!==i&&!r[a][xe]&&n(r[a],t,e))return r[a]}},r.each(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){l[Ie][t]=function(e){var i=this.findHover(e.zrX,e.zrY,null);if("mousedown"===t)this._downel=i,this._upel=i;else if("mosueup"===t)this._upel=i;else if("click"===t&&this._downel!==this._upel)return;this.dispatchToElement(i,t,e)}}),r.mixin(l,o),r.mixin(l,a),l}),e("zrender/dom/HandlerProxy",[Re,"../core/event","../core/util","../mixin/Eventful","../core/env","../core/GestureMgr"],function(t){function e(t){return"mousewheel"===t&&c.browser.firefox?"DOMMouseScroll":t}function i(t,e,i){var n=t._gestureMgr;"start"===i&&n.clear();var r=n.recognize(e,t.handler.findHover(e.zrX,e.zrY,null),t.dom);if("end"===i&&n.clear(),r){var a=r.type;e.gestureEvent=a,t.handler.dispatchToElement(r[J],a,r.event)}}function n(t){t._touching=!0,clearTimeout(t._touchTimer),t._touchTimer=setTimeout(function(){t._touching=!1},700)}function r(){return c.touchEventsSupported}function a(t){function e(t,e){return function(){return e._touching?void 0:t.apply(e,arguments)}}for(var i=0;i<g[ge];i++){var n=g[i];t._handlers[n]=l.bind(y[n],t)}for(var i=0;i<m[ge];i++){var n=m[i];t._handlers[n]=e(y[n],t)}}function o(t){function i(i,n){l.each(i,function(i){d(t,e(i),n._handlers[i])},n)}u.call(this),this.dom=t,this._touching=!1,this._touchTimer,this._gestureMgr=new h,this._handlers={},a(this),r()&&i(g,this),i(m,this)}var s=t("../core/event"),l=t("../core/util"),u=t("../mixin/Eventful"),c=t("../core/env"),h=t("../core/GestureMgr"),d=s.addEventListener,f=s.removeEventListener,p=s.normalizeEvent,v=300,m=["click","dblclick","mousewheel",te,"mouseup","mousedown","mousemove","contextmenu"],g=["touchstart","touchend","touchmove"],y={mousemove:function(t){t=p(this.dom,t),this[re]("mousemove",t)},mouseout:function(t){t=p(this.dom,t);var e=t.toElement||t.relatedTarget;if(e!=this.dom)for(;e&&9!=e.nodeType;){if(e===this.dom)return;e=e.parentNode}this[re](te,t)},touchstart:function(t){t=p(this.dom,t),t.zrByTouch=!0,this._lastTouchMoment=new Date,i(this,t,"start"),y.mousemove.call(this,t),y.mousedown.call(this,t),n(this)},touchmove:function(t){t=p(this.dom,t),t.zrByTouch=!0,i(this,t,"change"),y.mousemove.call(this,t),n(this)},touchend:function(t){t=p(this.dom,t),t.zrByTouch=!0,i(this,t,"end"),y.mouseup.call(this,t),+new Date-this._lastTouchMoment<v&&y.click.call(this,t),n(this)}};l.each(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],function(t){y[t]=function(e){e=p(this.dom,e),this[re](t,e)}});var x=o[Ie];return x.dispose=function(){for(var t=m[A](g),i=0;i<t[ge];i++){var n=t[i];f(this.dom,e(n),this._handlers[n])}},x.setCursor=function(t){this.dom.style.cursor=t||"default"},l.mixin(o,u),o}),e("zrender/Painter",[Re,"./config","./core/util","./core/log","./core/BoundingRect","./core/timsort","./Layer","./animation/requestAnimationFrame","./graphic/Image"],function(t){function e(t){return parseInt(t,10)}function i(t){return t?t.isBuildin?!0:typeof t[Ae]!==j||typeof t.refresh!==j?!1:!0:!1}function r(t){t.__unusedCount++}function a(t){1==t.__unusedCount&&t.clear()}function o(t,e,i){return x.copy(t[N]()),t[n]&&x[_](t[n]),b.width=e,b[Pe]=i,!x.intersect(b)}function s(t,e){if(t==e)return!1;if(!t||!e||t[ge]!==e[ge])return!0;for(var i=0;i<t[ge];i++)if(t[i]!==e[i])return!0}function l(t,e){for(var i=0;i<t[ge];i++){var n=t[i],r=n.path;n.setTransform(e),r.beginPath(e),n.buildPath(r,n.shape),e.clip(),n.restoreTransform(e)}}function u(t,e){var i=document[P]("div");return i.style.cssText=["position:relative","overflow:hidden","width:"+t+"px","height:"+e+"px","padding:0","margin:0","border-width:0"].join(";")+";",i}var c=t("./config"),h=t("./core/util"),d=t("./core/log"),f=t("./core/BoundingRect"),v=t("./core/timsort"),m=t("./Layer"),g=t("./animation/requestAnimationFrame"),y=5,x=new f(0,0,0,0),b=new f(0,0,0,0),w=function(t,e,i){var n=!t.nodeName||"CANVAS"===t.nodeName.toUpperCase();this._opts=i=h[oe]({},i||{}),this.dpr=i.devicePixelRatio||c.devicePixelRatio,this._singleCanvas=n,this.root=t;var r=t.style;r&&(r["-webkit-tap-highlight-color"]="transparent",r["-webkit-user-select"]=r["user-select"]=r["-webkit-touch-callout"]="none",t.innerHTML=""),this[be]=e;var a=this._zlevelList=[],o=this._layers={};if(this._layerConfig={},n){var s=t.width,l=t[Pe];this._width=s,this._height=l;var d=new m(t,this,1);d.initContext(),o[0]=d,a.push(0)}else{this._width=this._getSize(0),this._height=this._getSize(1);var f=this._domRoot=u(this._width,this._height);t.appendChild(f)}this.pathToImage=this._createPathToImage(),this._progressiveLayers=[],this._hoverlayer,this._hoverElements=[]};return w[Ie]={constructor:w,isSingleCanvas:function(){return this._singleCanvas},getViewportRoot:function(){return this._singleCanvas?this._layers[0].dom:this._domRoot},refresh:function(t){var e=this[be].getDisplayList(!0),i=this._zlevelList;this._paintList(e,t);for(var n=0;n<i[ge];n++){var r=i[n],a=this._layers[r];!a.isBuildin&&a.refresh&&a.refresh()}return this.refreshHover(),this._progressiveLayers[ge]&&this._startProgessive(),this},addHover:function(t,e){if(!t.__hoverMir){var i=new t.constructor({style:t.style,shape:t.shape});i.__from=t,t.__hoverMir=i,i[$](e),this._hoverElements.push(i)}},removeHover:function(t){var e=t.__hoverMir,i=this._hoverElements,n=h[me](i,e);n>=0&&i[ie](n,1),t.__hoverMir=null},clearHover:function(){for(var t=this._hoverElements,e=0;e<t[ge];e++){var i=t[e].__from;i&&(i.__hoverMir=null)}t[ge]=0},refreshHover:function(){var t=this._hoverElements,e=t[ge],i=this._hoverlayer;if(i&&i.clear(),e){v(t,this[be].displayableSortFunc),i||(i=this._hoverlayer=this.getLayer(1e5));var r={};i.ctx.save();for(var a=0;e>a;){var o=t[a],s=o.__from;s&&s.__zr?(a++,s.invisible||(o[n]=s[n],o.invTransform=s.invTransform,o.__clipPaths=s.__clipPaths,this._doPaintEl(o,i,!0,r))):(t[ie](a,1),s.__hoverMir=null,e--)}i.ctx.restore()}},_startProgessive:function(){function t(){i===e._progressiveToken&&e[be]&&(e._doPaintList(e[be].getDisplayList()),e._furtherProgressive?(e._progress++,g(t)):e._progressiveToken=-1)}var e=this;if(e._furtherProgressive){var i=e._progressiveToken=+new Date;e._progress++,g(t)}},_clearProgressive:function(){this._progressiveToken=-1,this._progress=0,h.each(this._progressiveLayers,function(t){t.__dirty&&t.clear()})},_paintList:function(t,e){null==e&&(e=!1),this._updateLayerStatus(t),this._clearProgressive(),this.eachBuildinLayer(r),this._doPaintList(t,e),this.eachBuildinLayer(a)},_doPaintList:function(t,e){function i(t){var e=a.dpr||1;a.save(),a.globalAlpha=1,a.shadowBlur=0,n.__dirty=!0,a.setTransform(1,0,0,1,0,0),a.drawImage(t.dom,0,0,c*e,f*e),a.restore()}for(var n,r,a,o,s,l,u=0,c=this._width,f=this._height,p=this._progress,v=0,m=t[ge];m>v;v++){var g=t[v],x=this._singleCanvas?0:g[Y],_=g.__frame;if(0>_&&s&&(i(s),s=null),r!==x&&(a&&a.restore(),o={},r=x,n=this.getLayer(r),n.isBuildin||d("ZLevel "+r+" has been used by unkown layer "+n.id),a=n.ctx,a.save(),n.__unusedCount=0,(n.__dirty||e)&&n.clear()),n.__dirty||e){if(_>=0){if(!s){if(s=this._progressiveLayers[Math.min(u++,y-1)],s.ctx.save(),s.renderScope={},s&&s.__progress>s.__maxProgress){v=s.__nextIdxNotProg-1;continue}l=s.__progress,s.__dirty||(p=l),s.__progress=p+1}_===p&&this._doPaintEl(g,s,!0,s.renderScope)}else this._doPaintEl(g,n,e,o);g.__dirty=!1}}s&&i(s),a&&a.restore(),this._furtherProgressive=!1,h.each(this._progressiveLayers,function(t){t.__maxProgress>=t.__progress&&(this._furtherProgressive=!0)},this)},_doPaintEl:function(t,e,i,r){var a=e.ctx,u=t[n];if(!(!e.__dirty&&!i||t.invisible||0===t.style[O]||u&&!u[0]&&!u[3]||t.culling&&o(t,this._width,this._height))){var c=t.__clipPaths;(r.prevClipLayer!==e||s(c,r.prevElClipPaths))&&(r.prevElClipPaths&&(r.prevClipLayer.ctx.restore(),r.prevClipLayer=r.prevElClipPaths=null,r.prevEl=null),c&&(a.save(),l(c,a),r.prevClipLayer=e,r.prevElClipPaths=c)),t.beforeBrush&&t.beforeBrush(a),t.brush(a,r.prevEl||null),r.prevEl=t,t.afterBrush&&t.afterBrush(a)}},getLayer:function(t){if(this._singleCanvas)return this._layers[0];var e=this._layers[t];return e||(e=new m("zr_"+t,this,this.dpr),e.isBuildin=!0,this._layerConfig[t]&&h.merge(e,this._layerConfig[t],!0),this.insertLayer(t,e),e.initContext()),e},insertLayer:function(t,e){var n=this._layers,r=this._zlevelList,a=r[ge],o=null,s=-1,l=this._domRoot;if(n[t])return void d("ZLevel "+t+" has been used already");if(!i(e))return void d("Layer of zlevel "+t+" is not valid");if(a>0&&t>r[0]){for(s=0;a-1>s&&!(r[s]<t&&r[s+1]>t);s++);o=n[r[s]]}if(r[ie](s+1,0,t),o){var u=o.dom;u.nextSibling?l.insertBefore(e.dom,u.nextSibling):l.appendChild(e.dom)}else l.firstChild?l.insertBefore(e.dom,l.firstChild):l.appendChild(e.dom);n[t]=e},eachLayer:function(t,e){var i,n,r=this._zlevelList;for(n=0;n<r[ge];n++)i=r[n],t.call(e,this._layers[i],i)},eachBuildinLayer:function(t,e){var i,n,r,a=this._zlevelList;for(r=0;r<a[ge];r++)n=a[r],i=this._layers[n],i.isBuildin&&t.call(e,i,n)},eachOtherLayer:function(t,e){var i,n,r,a=this._zlevelList;for(r=0;r<a[ge];r++)n=a[r],i=this._layers[n],i.isBuildin||t.call(e,i,n)},getLayers:function(){return this._layers},_updateLayerStatus:function(t){var e=this._layers,i=this._progressiveLayers,n={},r={};this.eachBuildinLayer(function(t,e){n[e]=t.elCount,t.elCount=0,t.__dirty=!1}),h.each(i,function(t,e){r[e]=t.elCount,t.elCount=0,t.__dirty=!1});for(var a,o,s=0,l=0,u=0,c=t[ge];c>u;u++){var d=t[u],f=this._singleCanvas?0:d[Y],p=e[f],v=d.progressive;if(p&&(p.elCount++,p.__dirty=p.__dirty||d.__dirty),v>=0){o!==v&&(o=v,l++);var g=d.__frame=l-1;if(!a){var x=Math.min(s,y-1);a=i[x],a||(a=i[x]=new m("progressive",this,this.dpr),a.initContext()),a.__maxProgress=0}a.__dirty=a.__dirty||d.__dirty,a.elCount++,a.__maxProgress=Math.max(a.__maxProgress,g),a.__maxProgress>=a.__progress&&(p.__dirty=!0)}else d.__frame=-1,a&&(a.__nextIdxNotProg=u,s++,a=null)}a&&(s++,a.__nextIdxNotProg=u),this.eachBuildinLayer(function(t,e){n[e]!==t.elCount&&(t.__dirty=!0)}),i[ge]=Math.min(s,y),h.each(i,function(t,e){r[e]!==t.elCount&&(d.__dirty=!0),t.__dirty&&(t.__progress=0)})},clear:function(){return this.eachBuildinLayer(this._clearLayer),this},_clearLayer:function(t){t.clear()},configLayer:function(t,e){if(e){var i=this._layerConfig;i[t]?h.merge(i[t],e,!0):i[t]=e;var n=this._layers[t];n&&h.merge(n,i[t],!0)}},delLayer:function(t){var e=this._layers,i=this._zlevelList,n=e[t];n&&(n.dom.parentNode.removeChild(n.dom),delete e[t],i[ie](h[me](i,t),1))},resize:function(t,e){var i=this._domRoot;i.style.display="none";var n=this._opts;if(null!=t&&(n.width=t),null!=e&&(n[Pe]=e),t=this._getSize(0),e=this._getSize(1),i.style.display="",this._width!=t||e!=this._height){i.style.width=t+"px",i.style[Pe]=e+"px";for(var r in this._layers)this._layers.hasOwnProperty(r)&&this._layers[r][Ae](t,e);h.each(this._progressiveLayers,function(i){i[Ae](t,e)}),this.refresh(!0)}return this._width=t,this._height=e,this},clearLayer:function(t){var e=this._layers[t];e&&e.clear()},dispose:function(){this.root.innerHTML="",this.root=this[be]=this._domRoot=this._layers=null},getRenderedCanvas:function(t){if(t=t||{},this._singleCanvas)return this._layers[0].dom;var e=new m("image",this,t.pixelRatio||this.dpr);e.initContext(),e.clearColor=t.backgroundColor,e.clear();for(var i=this[be].getDisplayList(!0),n={},r=0;r<i[ge];r++){var a=i[r];this._doPaintEl(a,e,!0,n)}return e.dom},getWidth:function(){return this._width},getHeight:function(){return this._height},_getSize:function(t){var i=this._opts,n=["width",Pe][t],r=["clientWidth","clientHeight"][t],a=["paddingLeft","paddingTop"][t],o=["paddingRight","paddingBottom"][t];if(null!=i[n]&&"auto"!==i[n])return parseFloat(i[n]);var s=this.root,l=document.defaultView.getComputedStyle(s);return(s[r]||e(l[n])||e(s.style[n]))-(e(l[a])||0)-(e(l[o])||0)|0},_pathToImage:function(e,i,n,r,a){var o=document[P]("canvas"),s=o[L]("2d");o.width=n*a,o[Pe]=r*a,s.clearRect(0,0,n*a,r*a);var l={position:i[R],rotation:i[p],scale:i.scale};i[R]=[0,0,0],i[p]=0,i.scale=[1,1],i&&i.brush(s);var u=t("./graphic/Image"),c=new u({id:e,style:{x:0,y:0,image:o}});return null!=l[R]&&(c[R]=i[R]=l[R]),null!=l[p]&&(c[p]=i[p]=l[p]),null!=l.scale&&(c.scale=i.scale=l.scale),c},_createPathToImage:function(){var t=this;return function(e,i,n,r){return t._pathToImage(e,i,n,r,t.dpr)}}},w}),e("echarts/data/helper/completeDimensions",[Re,De],function(t){function e(t,e,a,o){if(!e)return t; +var s=i(e[0]),l=n[U](s)&&s[ge]||1;a=a||[],o=o||"extra";for(var u=0;l>u;u++)if(!t[u]){var c=a[u]||o+(u-a[ge]);t[u]=r(e,u)?{type:"ordinal",name:c}:c}return t}function i(t){return n[U](t)?t:n[le](t)?t.value:t}var n=t(De),r=e.guessOrdinal=function(t,e){for(var r=0,a=t[ge];a>r;r++){var o=i(t[r]);if(!n[U](o))return!1;var o=o[e];if(null!=o&&isFinite(o))return!1;if(n.isString(o)&&"-"!==o)return!0}return!1};return e}),e("zrender/Storage",[Re,"./core/util","./core/env","./container/Group","./core/timsort"],function(t){function e(t,e){return t[Y]===e[Y]?t.z===e.z?t.z2-e.z2:t.z-e.z:t[Y]-e[Y]}var i=t("./core/util"),n=t("./core/env"),r=t("./container/Group"),a=t("./core/timsort"),o=function(){this._elements={},this._roots=[],this._displayList=[],this._displayListLen=0};return o[Ie]={constructor:o,traverse:function(t,e){for(var i=0;i<this._roots[ge];i++)this._roots[i][Q](t,e)},getDisplayList:function(t,e){return e=e||!1,t&&this.updateDisplayList(e),this._displayList},updateDisplayList:function(t){this._displayListLen=0;for(var i=this._roots,r=this._displayList,o=0,s=i[ge];s>o;o++)this._updateAndAddDisplayable(i[o],null,t);r[ge]=this._displayListLen,n[we]&&a(r,e)},_updateAndAddDisplayable:function(t,e,i){if(!t[xe]||i){t.beforeUpdate(),t.__dirty&&t[ce](),t.afterUpdate();var n=t.clipPath;if(n&&(n[v]=t,n.updateTransform(),e?(e=e.slice(),e.push(n)):e=[n]),t.isGroup){for(var r=t._children,a=0;a<r[ge];a++){var o=r[a];t.__dirty&&(o.__dirty=!0),this._updateAndAddDisplayable(o,e,i)}t.__dirty=!1}else t.__clipPaths=e,this._displayList[this._displayListLen++]=t}},addRoot:function(t){this._elements[t.id]||(t instanceof r&&t.addChildrenToStorage(this),this.addToMap(t),this._roots.push(t))},delRoot:function(t){if(null==t){for(var e=0;e<this._roots[ge];e++){var n=this._roots[e];n instanceof r&&n.delChildrenFromStorage(this)}return this._elements={},this._roots=[],this._displayList=[],void(this._displayListLen=0)}if(t instanceof Array)for(var e=0,a=t[ge];a>e;e++)this.delRoot(t[e]);else{var o;o=typeof t==Le?this._elements[t]:t;var s=i[me](this._roots,o);s>=0&&(this.delFromMap(o.id),this._roots[ie](s,1),o instanceof r&&o.delChildrenFromStorage(this))}},addToMap:function(t){return t instanceof r&&(t.__storage=this),t.dirty(!1),this._elements[t.id]=t,this},get:function(t){return this._elements[t]},delFromMap:function(t){var e=this._elements,i=e[t];return i&&(delete e[t],i instanceof r&&(i.__storage=null)),this},dispose:function(){this._elements=this._renderList=this._roots=null},displayableSortFunc:e},o}),e("echarts/data/DataDiffer",[Re],function(){function t(t){return t}function e(e,i,n,r){this._old=e,this._new=i,this._oldKeyGetter=n||t,this._newKeyGetter=r||t}function i(t,e,i,n){for(var r=0;r<t[ge];r++){var a=n(t[r],r),o=e[a];null==o?(i.push(a),e[a]=r):(o[ge]||(e[a]=o=[o]),o.push(r))}}return e[Ie]={constructor:e,add:function(t){return this._add=t,this},update:function(t){return this._update=t,this},remove:function(t){return this._remove=t,this},execute:function(){var t,e=this._old,n=this._new,r=this._oldKeyGetter,a=this._newKeyGetter,o={},s={},l=[],u=[];for(i(e,o,l,r),i(n,s,u,a),t=0;t<e[ge];t++){var c=l[t],h=s[c];if(null!=h){var d=h[ge];d?(1===d&&(s[c]=null),h=h.unshift()):s[c]=null,this._update&&this._update(h,t)}else this._remove&&this._remove(t)}for(var t=0;t<u[ge];t++){var c=u[t];if(s.hasOwnProperty(c)){var h=s[c];if(null==h)continue;if(h[ge])for(var f=0,d=h[ge];d>f;f++)this._add&&this._add(h[f]);else this._add&&this._add(h)}}}},e}),e("zrender/graphic/helper/smoothSpline",[Re,"../../core/vector"],function(t){function e(t,e,i,n,r,a,o){var s=.5*(i-t),l=.5*(n-e);return(2*(e-i)+s+l)*o+(-3*(e-i)-2*s-l)*a+s*r+e}var i=t("../../core/vector");return function(t,n){for(var r=t[ge],a=[],o=0,s=1;r>s;s++)o+=i.distance(t[s-1],t[s]);var l=o/2;l=r>l?r:l;for(var s=0;l>s;s++){var u,c,h,d=s/(l-1)*(n?r:r-1),f=Math.floor(d),p=d-f,v=t[f%r];n?(u=t[(f-1+r)%r],c=t[(f+1)%r],h=t[(f+2)%r]):(u=t[0===f?f:f-1],c=t[f>r-2?r-1:f+1],h=t[f>r-3?r-1:f+2]);var m=p*p,g=p*m;a.push([e(u[0],v[0],c[0],h[0],p,m,g),e(u[1],v[1],c[1],h[1],p,m,g)])}return a}}),e("zrender/graphic/helper/smoothBezier",[Re,"../../core/vector"],function(t){var e=t("../../core/vector"),i=e.min,n=e.max,r=e.scale,a=e.distance,o=e.add;return function(t,s,l,u){var c,h,d,f,p=[],v=[],m=[],g=[];if(u){d=[1/0,1/0],f=[-1/0,-1/0];for(var y=0,x=t[ge];x>y;y++)i(d,d,t[y]),n(f,f,t[y]);i(d,d,u[0]),n(f,f,u[1])}for(var y=0,x=t[ge];x>y;y++){var _=t[y];if(l)c=t[y?y-1:x-1],h=t[(y+1)%x];else{if(0===y||y===x-1){p.push(e.clone(t[y]));continue}c=t[y-1],h=t[y+1]}e.sub(v,h,c),r(v,v,s);var b=a(_,c),w=a(_,h),M=b+w;0!==M&&(b/=M,w/=M),r(m,v,-b),r(g,v,w);var T=o([],_,m),S=o([],_,g);u&&(n(T,T,d),i(T,T,f),n(S,S,d),i(S,S,f)),p.push(T),p.push(S)}return l&&p.push(p.shift()),p}}),e("zrender/mixin/Draggable",[Re],function(){function t(){this.on("mousedown",this._dragStart,this),this.on("mousemove",this._drag,this),this.on("mouseup",this._dragEnd,this),this.on("globalout",this._dragEnd,this)}return t[Ie]={constructor:t,_dragStart:function(t){var e=t[J];e&&e.draggable&&(this._draggingTarget=e,e.dragging=!0,this._x=t.offsetX,this._y=t.offsetY,this.dispatchToElement(e,"dragstart",t.event))},_drag:function(t){var e=this._draggingTarget;if(e){var i=t.offsetX,n=t.offsetY,r=i-this._x,a=n-this._y;this._x=i,this._y=n,e.drift(r,a,t),this.dispatchToElement(e,"drag",t.event);var o=this.findHover(i,n,e),s=this._dropTarget;this._dropTarget=o,e!==o&&(s&&o!==s&&this.dispatchToElement(s,"dragleave",t.event),o&&o!==s&&this.dispatchToElement(o,"dragenter",t.event))}},_dragEnd:function(t){var e=this._draggingTarget;e&&(e.dragging=!1),this.dispatchToElement(e,"dragend",t.event),this._dropTarget&&this.dispatchToElement(this._dropTarget,"drop",t.event),this._draggingTarget=null,this._dropTarget=null}},t}),e("echarts/chart/bar/barItemStyle",[Re,"../../model/mixin/makeStyleMapper"],function(t){var e=t("../../model/mixin/makeStyleMapper")([["fill","color"],[y,"borderColor"],[x,"borderWidth"],[y,"barBorderColor"],[x,"barBorderWidth"],[O],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["shadowColor"]]);return{getBarItemStyle:function(t){var i=e.call(this,t);if(this.getBorderLineDash){var n=this.getBorderLineDash();n&&(i.lineDash=n)}return i}}}),e("zrender/graphic/helper/roundRect",[Re],function(){return{buildPath:function(t,e){var n,r,a,o,s=e.x,l=e.y,u=e.width,c=e[Pe],h=e.r;0>u&&(s+=u,u=-u),0>c&&(l+=c,c=-c),typeof h===W?n=r=a=o=h:h instanceof Array?1===h[ge]?n=r=a=o=h[0]:2===h[ge]?(n=a=h[0],r=o=h[1]):3===h[ge]?(n=h[0],r=o=h[1],a=h[2]):(n=h[0],r=h[1],a=h[2],o=h[3]):n=r=a=o=0;var d;n+r>u&&(d=n+r,n*=u/d,r*=u/d),a+o>u&&(d=a+o,a*=u/d,o*=u/d),r+a>c&&(d=r+a,r*=c/d,a*=c/d),n+o>c&&(d=n+o,n*=c/d,o*=c/d),t[i](s+n,l),t.lineTo(s+u-r,l),0!==r&&t.quadraticCurveTo(s+u,l,s+u,l+r),t.lineTo(s+u,l+c-a),0!==a&&t.quadraticCurveTo(s+u,l+c,s+u-a,l+c),t.lineTo(s+o,l+c),0!==o&&t.quadraticCurveTo(s,l+c,s,l+c-o),t.lineTo(s,l+n),0!==n&&t.quadraticCurveTo(s,l,s+n,l)}}}),e("zrender/core/event",[Re,"../mixin/Eventful","./env"],function(t){function e(t){return t.getBoundingClientRect?t.getBoundingClientRect():{left:0,top:0}}function i(t,e,i,r){return i=i||{},r||!l[we]?n(t,e,i):l.browser.firefox&&null!=e.layerX&&e.layerX!==e.offsetX?(i.zrX=e.layerX,i.zrY=e.layerY):null!=e.offsetX?(i.zrX=e.offsetX,i.zrY=e.offsetY):n(t,e,i),i}function n(t,i,n){var r=e(t);n.zrX=i.clientX-r.left,n.zrY=i.clientY-r.top}function r(t,e,n){if(e=e||window.event,null!=e.zrX)return e;var r=e.type,a=r&&r[me]("touch")>=0;if(a){var o="touchend"!=r?e.targetTouches[0]:e.changedTouches[0];o&&i(t,o,e,n)}else i(t,e,e,n),e.zrDelta=e.wheelDelta?e.wheelDelta/120:-(e.detail||0)/3;return e}function a(t,e,i){u?t.addEventListener(e,i):t.attachEvent("on"+e,i)}function o(t,e,i){u?t.removeEventListener(e,i):t.detachEvent("on"+e,i)}var s=t("../mixin/Eventful"),l=t("./env"),u=typeof window!==I&&!!window.addEventListener,c=u?function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0}:function(t){t.returnValue=!1,t.cancelBubble=!0};return{clientToLocal:i,normalizeEvent:r,addEventListener:a,removeEventListener:o,stop:c,Dispatcher:s}}),e("zrender/animation/requestAnimationFrame",[Re],function(){return typeof window!==I&&(window.requestAnimationFrame||window.msRequestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){setTimeout(t,16)}}),e("zrender/core/GestureMgr",[Re,"./event"],function(t){function e(t){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1];return Math.sqrt(e*e+i*i)}function i(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}var n=t("./event"),r=function(){this._track=[]};r[Ie]={constructor:r,recognize:function(t,e,i){return this._doTrack(t,e,i),this._recognize(t)},clear:function(){return this._track[ge]=0,this},_doTrack:function(t,e,i){var r=t.touches;if(r){for(var a={points:[],touches:[],target:e,event:t},o=0,s=r[ge];s>o;o++){var l=r[o],u=n.clientToLocal(i,l,{});a.points.push([u.zrX,u.zrY]),a.touches.push(l)}this._track.push(a)}},_recognize:function(t){for(var e in a)if(a.hasOwnProperty(e)){var i=a[e](this._track,t);if(i)return i}}};var a={pinch:function(t,n){var r=t[ge];if(r){var a=(t[r-1]||{}).points,o=(t[r-2]||{}).points||a;if(o&&o[ge]>1&&a&&a[ge]>1){var s=e(a)/e(o);!isFinite(s)&&(s=1),n.pinchScale=s;var l=i(a);return n.pinchX=l[0],n.pinchY=l[1],{type:"pinch",target:t[0][J],event:n}}}}};return r}),e("zrender/Layer",[Re,"./core/util","./config","./graphic/Style","./graphic/Pattern"],function(t){function e(){return!1}function i(t,e,i,n){var r=document[P](e),a=i[Te](),o=i[Me](),s=r.style;return s[R]="absolute",s.left=0,s.top=0,s.width=a+"px",s[Pe]=o+"px",r.width=a*n,r[Pe]=o*n,r.setAttribute("data-zr-dom-id",t),r}var n=t("./core/util"),r=t("./config"),a=t("./graphic/Style"),o=t("./graphic/Pattern"),s=function(t,a,o){var s;o=o||r.devicePixelRatio,typeof t===Le?s=i(t,"canvas",a,o):n[le](t)&&(s=t,t=s.id),this.id=t,this.dom=s;var l=s.style;l&&(s.onselectstart=e,l["-webkit-user-select"]="none",l["user-select"]="none",l["-webkit-touch-callout"]="none",l["-webkit-tap-highlight-color"]="rgba(0,0,0,0)",l.padding=0,l.margin=0,l["border-width"]=0),this.domBack=null,this.ctxBack=null,this.painter=a,this.config=null,this.clearColor=0,this.motionBlur=!1,this.lastFrameAlpha=.7,this.dpr=o};return s[Ie]={constructor:s,elCount:0,__dirty:!0,initContext:function(){this.ctx=this.dom[L]("2d"),this.ctx.dpr=this.dpr},createBackBuffer:function(){var t=this.dpr;this.domBack=i("back-"+this.id,"canvas",this.painter,t),this.ctxBack=this.domBack[L]("2d"),1!=t&&this.ctxBack.scale(t,t)},resize:function(t,e){var i=this.dpr,n=this.dom,r=n.style,a=this.domBack;r.width=t+"px",r[Pe]=e+"px",n.width=t*i,n[Pe]=e*i,a&&(a.width=t*i,a[Pe]=e*i,1!=i&&this.ctxBack.scale(i,i))},clear:function(t){var e=this.dom,i=this.ctx,n=e.width,r=e[Pe],s=this.clearColor,l=this.motionBlur&&!t,u=this.lastFrameAlpha,c=this.dpr;if(l&&(this.domBack||this.createBackBuffer(),this.ctxBack.globalCompositeOperation="copy",this.ctxBack.drawImage(e,0,0,n/c,r/c)),i.clearRect(0,0,n,r),s){var h;s[ue]?(h=s.__canvasGradient||a.getGradient(i,s,{x:0,y:0,width:n,height:r}),s.__canvasGradient=h):s.image&&(h=o[Ie].getCanvasPattern.call(s,i)),i.save(),i.fillStyle=h||s,i.fillRect(0,0,n,r),i.restore()}if(l){var d=this.domBack;i.save(),i.globalAlpha=u,i.drawImage(d,0,0,n,r),i.restore()}}},s}),e("echarts/preprocessor/helper/compatStyle",[Re,De],function(t){function e(t){var e=t&&t.itemStyle;e&&i.each(n,function(n){var r=e[w],a=e.emphasis;r&&r[n]&&(t[n]=t[n]||{},t[n][w]?i.merge(t[n][w],r[n]):t[n][w]=r[n],r[n]=null),a&&a[n]&&(t[n]=t[n]||{},t[n].emphasis?i.merge(t[n].emphasis,a[n]):t[n].emphasis=a[n],a[n]=null)})}var i=t(De),n=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"];return function(t){if(t){e(t),e(t.markPoint),e(t.markLine);var n=t.data;if(n){for(var r=0;r<n[ge];r++)e(n[r]);var a=t.markPoint;if(a&&a.data)for(var o=a.data,r=0;r<o[ge];r++)e(o[r]);var s=t.markLine;if(s&&s.data)for(var l=s.data,r=0;r<l[ge];r++)i[U](l[r])?(e(l[r][0]),e(l[r][1])):e(l[r])}}}}),e("echarts/chart/helper/SymbolDraw",[Re,u,"./Symbol"],function(t){function e(t){this.group=new n.Group,this._symbolCtor=t||r}function i(t,e,i){var n=t.getItemLayout(e);return!(!n||isNaN(n[0])||isNaN(n[1])||i&&i(e)||"none"===t[de](e,"symbol"))}var n=t(u),r=t("./Symbol"),a=e[Ie];return a.updateData=function(t,e){var r=this.group,a=t.hostModel,o=this._data,s=this._symbolCtor,l={itemStyle:a[Se]("itemStyle.normal").getItemStyle(["color"]),hoverItemStyle:a[Se]("itemStyle.emphasis").getItemStyle(),symbolRotate:a.get("symbolRotate"),symbolOffset:a.get("symbolOffset"),hoverAnimation:a.get("hoverAnimation"),labelModel:a[Se]("label.normal"),hoverLabelModel:a[Se]("label.emphasis")};t.diff(o).add(function(n){var a=t.getItemLayout(n);if(i(t,n,e)){var o=new s(t,n,l);o.attr(R,a),t.setItemGraphicEl(n,o),r.add(o)}})[ce](function(u,c){var h=o[b](c),d=t.getItemLayout(u);return i(t,u,e)?(h?(h.updateData(t,u,l),n.updateProps(h,{position:d},a)):(h=new s(t,u),h.attr(R,d)),r.add(h),void t.setItemGraphicEl(u,h)):void r[se](h)})[se](function(t){var e=o[b](t);e&&e.fadeOut(function(){r[se](e)})}).execute(),this._data=t},a.updateLayout=function(){var t=this._data;t&&t.eachItemGraphicEl(function(e,i){var n=t.getItemLayout(i);e.attr(R,n)})},a[se]=function(t){var e=this.group,i=this._data;i&&(t?i.eachItemGraphicEl(function(t){t.fadeOut(function(){e[se](t)})}):e[H]())},e}),e("echarts/component/axis/AxisView",[Re,De,u,"./AxisBuilder","../../echarts"],function(t){function e(t,e){function i(t){var e=n[o](t);return e.toGlobalCoord(e[a](0))}var n=t[ve],r=e.axis,s={},l=r[R],u=r.onZero?"onZero":l,c=r.dim,h=n.getRect(),d=[h.x,h.x+h.width,h.y,h.y+h[Pe]],f=e.get("offset")||0,v={x:{top:d[2]-f,bottom:d[3]+f},y:{left:d[0]-f,right:d[1]+f}};v.x.onZero=Math.max(Math.min(i("y"),v.x[ye]),v.x.top),v.y.onZero=Math.max(Math.min(i("x"),v.y.right),v.y.left),s[R]=["y"===c?v.y[u]:d[0],"x"===c?v.x[u]:d[3]],s[p]=Math.PI/2*("x"===c?0:1);var g={top:-1,bottom:1,left:-1,right:1};s.labelDirection=s.tickDirection=s.nameDirection=g[l],r.onZero&&(s.labelOffset=v[c][l]-v[c].onZero),e[Se]("axisTick").get(m)&&(s.tickDirection=-s.tickDirection),e[Se]("axisLabel").get(m)&&(s.labelDirection=-s.labelDirection);var y=e[Se]("axisLabel").get("rotate");return s.labelRotation="top"===u?-y:y,s.labelInterval=r.getLabelInterval(),s.z2=1,s}var i=t(De),n=t(u),r=t("./AxisBuilder"),s=r.ifIgnoreOnTick,l=r.getInterval,c=["axisLine","axisLabel","axisTick","axisName"],h=["splitArea","splitLine"],d=t("../../echarts").extendComponentView({type:"axis",render:function(t){this.group[H]();var a=this._axisGroup;if(this._axisGroup=new n.Group,this.group.add(this._axisGroup),t.get("show")){var o=t.findGridModel(),s=e(o,t),l=new r(t,s);i.each(c,l.add,l),this._axisGroup.add(l.getGroup()),i.each(h,function(e){t.get(e+".show")&&this["_"+e](t,o,s.labelInterval)},this),n.groupTransition(a,this._axisGroup,t)}},_splitLine:function(t,e,r){var a=t.axis,o=t[Se]("splitLine"),u=o[Se]("lineStyle"),c=u.get("color"),h=l(o,r);c=i[U](c)?c:[c];for(var d=e[ve].getRect(),f=a.isHorizontal(),p=0,v=a.getTicksCoords(),m=a.scale[k](),g=[],y=[],x=u.getLineStyle(),_=0;_<v[ge];_++)if(!s(a,_,h)){var b=a.toGlobalCoord(v[_]);f?(g[0]=b,g[1]=d.y,y[0]=b,y[1]=d.y+d[Pe]):(g[0]=d.x,g[1]=b,y[0]=d.x+d.width,y[1]=b);var w=p++%c[ge];this._axisGroup.add(new n.Line(n.subPixelOptimizeLine({anid:"line_"+m[_],shape:{x1:g[0],y1:g[1],x2:y[0],y2:y[1]},style:i[ae]({stroke:c[w]},x),silent:!0})))}},_splitArea:function(t,e,r){var a=t.axis,o=t[Se]("splitArea"),u=o[Se]("areaStyle"),c=u.get("color"),h=e[ve].getRect(),d=a.getTicksCoords(),f=a.scale[k](),p=a.toGlobalCoord(d[0]),v=a.toGlobalCoord(d[0]),m=0,g=l(o,r),y=u.getAreaStyle();c=i[U](c)?c:[c];for(var x=1;x<d[ge];x++)if(!s(a,x,g)){var _,b,w,M,T=a.toGlobalCoord(d[x]);a.isHorizontal()?(_=p,b=h.y,w=T-_,M=h[Pe]):(_=h.x,b=v,w=h.width,M=T-b);var S=m++%c[ge];this._axisGroup.add(new n.Rect({anid:"area_"+f[x],shape:{x:_,y:b,width:w,height:M},style:i[ae]({fill:c[S]},y),silent:!0})),p=_+w,v=b+M}}});d[oe]({type:"xAxis"}),d[oe]({type:"yAxis"})}),e("echarts/component/helper/selectableMixin",[Re,De],function(t){var e=t(De);return{updateSelectedMap:function(t){this._selectTargetMap=e.reduce(t||[],function(t,e){return t[e.name]=e,t},{})},select:function(t){var i=this._selectTargetMap,n=i[t],r=this.get("selectedMode");"single"===r&&e.each(i,function(t){t.selected=!1}),n&&(n.selected=!0)},unSelect:function(t){var e=this._selectTargetMap[t];e&&(e.selected=!1)},toggleSelected:function(t){var e=this._selectTargetMap[t];return null!=e?(this[e.selected?"unSelect":"select"](t),e.selected):void 0},isSelected:function(t){var e=this._selectTargetMap[t];return e&&e.selected}}}),e("echarts/chart/helper/Symbol",[Re,De,"../../util/symbol",u,"../../util/number"],function(t){function e(t){return t=t instanceof Array?t.slice():[+t,+t],t[0]/=2,t[1]/=2,t}function i(t,e,i){o.Group.call(this),this.updateData(t,e,i)}function n(t,e){this[v].drift(t,e)}var r=t(De),a=t("../../util/symbol"),o=t(u),s=t("../../util/number"),l=i[Ie];l._createSymbol=function(t,i,r){this[H]();var s=i.hostModel,l=i[de](r,"color"),u=a.createSymbol(t,-1,-1,2,2,l);u.attr({z2:100,culling:!0,scale:[0,0]}),u.drift=n;var c=e(i[de](r,"symbolSize"));o.initProps(u,{scale:c},s,r),this._symbolType=t,this.add(u)},l.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(t)},l.getSymbolPath=function(){return this.childAt(0)},l.getScale=function(){return this.childAt(0).scale},l.highlight=function(){this.childAt(0)[re]("emphasis")},l.downplay=function(){this.childAt(0)[re](w)},l.setZ=function(t,e){var i=this.childAt(0);i[Y]=t,i.z=e},l.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":"pointer"},l.updateData=function(t,i,n){this.silent=!1;var r=t[de](i,"symbol")||"circle",a=t.hostModel,s=e(t[de](i,"symbolSize"));if(r!==this._symbolType)this._createSymbol(r,t,i);else{var l=this.childAt(0);o.updateProps(l,{scale:s},a,i)}this._updateCommon(t,i,s,n),this._seriesModel=a};var m=["itemStyle",w],y=["itemStyle","emphasis"],x=["label",w],_=["label","emphasis"];return l._updateCommon=function(t,i,n,a){var l=this.childAt(0),u=t.hostModel,v=t[de](i,"color");"image"!==l.type&&l.useStyle({strokeNoScale:!0}),a=a||null;var b=a&&a.itemStyle,M=a&&a.hoverItemStyle,T=a&&a.symbolRotate,S=a&&a.symbolOffset,C=a&&a.labelModel,A=a&&a.hoverLabelModel,P=a&&a.hoverAnimation;if(!a||t.hasItemOption){var L=t[h](i);b=L[Se](m).getItemStyle(["color"]),M=L[Se](y).getItemStyle(),T=L[g]("symbolRotate"),S=L[g]("symbolOffset"),C=L[Se](x),A=L[Se](_),P=L[g]("hoverAnimation")}else M=r[oe]({},M);var I=l.style;l.attr(p,(T||0)*Math.PI/180||0),S&&l.attr(R,[s.parsePercent(S[0],n[0]),s.parsePercent(S[1],n[1])]),l.setColor(v),l[$](b);var k=t[de](i,O);null!=k&&(I[O]=k);for(var z,D,E=t[c].slice();E[ge]&&(z=E.pop(),D=t.getDimensionInfo(z).type,D===d||"time"===D););null!=z&&C[g]("show")?(o.setText(I,C,v),I.text=r[f](u.getFormattedLabel(i,w),t.get(z,i))):I.text="",null!=z&&A[g]("show")?(o.setText(M,A,v),M.text=r[f](u.getFormattedLabel(i,"emphasis"),t.get(z,i))):M.text="";var B=e(t[de](i,"symbolSize"));if(l.off(ee).off(te).off("emphasis").off(w),l.hoverStyle=M,o.setHoverStyle(l),P&&u.ifEnableAnimation()){var N=function(){var t=B[1]/B[0];this.animateTo({scale:[Math.max(1.1*B[0],B[0]+3),Math.max(1.1*B[1],B[1]+3*t)]},400,"elasticOut")},V=function(){this.animateTo({scale:B},400,"elasticOut")};l.on(ee,N).on(te,V).on("emphasis",N).on(w,V)}},l.fadeOut=function(t){var e=this.childAt(0);this.silent=!0,e.style.text="",o.updateProps(e,{scale:[0,0]},this._seriesModel,this[fe],t)},r[Z](i,o.Group),i}),e("echarts/chart/line/poly",[Re,"zrender/graphic/Path",ze],function(t){function e(t){return isNaN(t[0])||isNaN(t[1])}function n(t,n,r,a,p,v,m,g,y,x,_){for(var b=0,w=r,M=0;a>M;M++){var T=n[w];if(w>=p||0>w)break;if(e(T)){if(_){w+=v;continue}break}if(w===r)t[v>0?i:"lineTo"](T[0],T[1]),c(d,T);else if(y>0){var S=w+v,C=n[S];if(_)for(;C&&e(n[S]);)S+=v,C=n[S];var A=.5,P=n[b],C=n[S];if(!C||e(C))c(f,T);else{e(C)&&!_&&(C=T),o.sub(h,C,P);var L,I;if("x"===x||"y"===x){var k="x"===x?0:1;L=Math.abs(T[k]-P[k]),I=Math.abs(T[k]-C[k])}else L=o.dist(T,P),I=o.dist(T,C);A=I/(I+L),u(f,T,h,-y*(1-A))}s(d,d,g),l(d,d,m),s(f,f,g),l(f,f,m),t.bezierCurveTo(d[0],d[1],f[0],f[1],T[0],T[1]),u(d,T,h,y*A)}else t.lineTo(T[0],T[1]);b=w,w+=v}return M}function r(t,e){var i=[1/0,1/0],n=[-1/0,-1/0];if(e)for(var r=0;r<t[ge];r++){var a=t[r];a[0]<i[0]&&(i[0]=a[0]),a[1]<i[1]&&(i[1]=a[1]),a[0]>n[0]&&(n[0]=a[0]),a[1]>n[1]&&(n[1]=a[1])}return{min:e?i:n,max:e?n:i}}var a=t("zrender/graphic/Path"),o=t(ze),s=o.min,l=o.max,u=o.scaleAndAdd,c=o.copy,h=[],d=[],f=[];return{Polyline:a[oe]({type:"ec-polyline",shape:{points:[],smooth:0,smoothConstraint:!0,smoothMonotone:null,connectNulls:!1},style:{fill:null,stroke:"#000"},buildPath:function(t,i){var a=i.points,o=0,s=a[ge],l=r(a,i.smoothConstraint);if(i.connectNulls){for(;s>0&&e(a[s-1]);s--);for(;s>o&&e(a[o]);o++);}for(;s>o;)o+=n(t,a,o,s,s,1,l.min,l.max,i.smooth,i.smoothMonotone,i.connectNulls)+1}}),Polygon:a[oe]({type:"ec-polygon",shape:{points:[],stackedOnPoints:[],smooth:0,stackedOnSmooth:0,smoothConstraint:!0,smoothMonotone:null,connectNulls:!1},buildPath:function(t,i){var a=i.points,o=i.stackedOnPoints,s=0,l=a[ge],u=i.smoothMonotone,c=r(a,i.smoothConstraint),h=r(o,i.smoothConstraint);if(i.connectNulls){for(;l>0&&e(a[l-1]);l--);for(;l>s&&e(a[s]);s++);}for(;l>s;){var d=n(t,a,s,l,l,1,c.min,c.max,i.smooth,u,i.connectNulls);n(t,o,s+d-1,d,l,-1,h.min,h.max,i.stackedOnSmooth,u,i.connectNulls),s+=d+1,t.closePath()}}})}}),e("echarts/chart/line/lineAnimationDiff",[Re],function(){function t(t){return t>=0?1:-1}function e(e,i,n){for(var r,a=e.getBaseAxis(),o=e.getOtherAxis(a),u=a.onZero?0:o.scale[z]()[0],c=o.dim,h="x"===c||c===l?1:0,d=i.stackedOn,f=i.get(c,n);d&&t(d.get(c,n))===t(f);){r=d;break}var p=[];return p[h]=i.get(a.dim,n),p[1-h]=r?r.get(c,n,!0):u,e[s](p)}function i(t,e){var i=[];return e.diff(t).add(function(t){i.push({cmd:"+",idx:t})})[ce](function(t,e){i.push({cmd:"=",idx:e,idx1:t})})[se](function(t){i.push({cmd:"-",idx:t})}).execute(),i}return function(t,n,r,a,o,l){for(var u=i(t,n),h=[],d=[],f=[],p=[],v=[],m=[],g=[],y=l[c],x=0;x<u[ge];x++){var _=u[x],b=!0;switch(_.cmd){case"=":var w=t.getItemLayout(_.idx),M=n.getItemLayout(_.idx1);(isNaN(w[0])||isNaN(w[1]))&&(w=M.slice()),h.push(w),d.push(M),f.push(r[_.idx]),p.push(a[_.idx1]),g.push(n.getRawIndex(_.idx1));break;case"+":var T=_.idx;h.push(o[s]([n.get(y[0],T,!0),n.get(y[1],T,!0)])),d.push(n.getItemLayout(T).slice()),f.push(e(o,n,T)),p.push(a[T]),g.push(n.getRawIndex(T));break;case"-":var T=_.idx,S=t.getRawIndex(T);S!==T?(h.push(t.getItemLayout(T)),d.push(l[s]([t.get(y[0],T,!0),t.get(y[1],T,!0)])),f.push(r[T]),p.push(e(l,t,T)),g.push(S)):b=!1}b&&(v.push(_),m.push(m[ge]))}m.sort(function(t,e){return g[t]-g[e]});for(var C=[],A=[],P=[],L=[],I=[],x=0;x<m[ge];x++){var T=m[x];C[x]=h[T],A[x]=d[T],P[x]=f[T],L[x]=p[T],I[x]=v[T]}return{current:C,next:A,stackedOnCurrent:P,stackedOnNext:L,status:I}}}),e("echarts/util/symbol",[Re,"./graphic","zrender/core/BoundingRect"],function(t){var e=t("./graphic"),n=t("zrender/core/BoundingRect"),r=e.extendShape({type:"triangle",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var n=e.cx,r=e.cy,a=e.width/2,o=e[Pe]/2;t[i](n,r-o),t.lineTo(n+a,r+o),t.lineTo(n-a,r+o),t.closePath()}}),a=e.extendShape({type:"diamond",shape:{cx:0,cy:0,width:0,height:0},buildPath:function(t,e){var n=e.cx,r=e.cy,a=e.width/2,o=e[Pe]/2;t[i](n,r-o),t.lineTo(n+a,r),t.lineTo(n,r+o),t.lineTo(n-a,r),t.closePath()}}),o=e.extendShape({type:"pin",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var i=e.x,n=e.y,r=e.width/5*3,a=Math.max(r,e[Pe]),o=r/2,s=o*o/(a-o),l=n-a+o+s,u=Math.asin(s/o),c=Math.cos(u)*o,h=Math.sin(u),d=Math.cos(u);t.arc(i,l,o,Math.PI-u,2*Math.PI+u);var f=.6*o,p=.7*o;t.bezierCurveTo(i+c-h*f,l+s+d*f,i,n-p,i,n),t.bezierCurveTo(i,n-p,i-c+h*f,l+s+d*f,i-c,l+s),t.closePath()}}),s=e.extendShape({type:"arrow",shape:{x:0,y:0,width:0,height:0},buildPath:function(t,e){var n=e[Pe],r=e.width,a=e.x,o=e.y,s=r/3*2;t[i](a,o),t.lineTo(a+s,o+n),t.lineTo(a,o+n/4*3),t.lineTo(a-s,o+n),t.lineTo(a,o),t.closePath()}}),l={line:e.Line,rect:e.Rect,roundRect:e.Rect,square:e.Rect,circle:e.Circle,diamond:a,pin:o,arrow:s,triangle:r},u={line:function(t,e,i,n,r){r.x1=t,r.y1=e+n/2,r.x2=t+i,r.y2=e+n/2},rect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r[Pe]=n},roundRect:function(t,e,i,n,r){r.x=t,r.y=e,r.width=i,r[Pe]=n,r.r=Math.min(i,n)/4},square:function(t,e,i,n,r){var a=Math.min(i,n);r.x=t,r.y=e,r.width=a,r[Pe]=a},circle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.r=Math.min(i,n)/2},diamond:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r[Pe]=n},pin:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r[Pe]=n},arrow:function(t,e,i,n,r){r.x=t+i/2,r.y=e+n/2,r.width=i,r[Pe]=n},triangle:function(t,e,i,n,r){r.cx=t+i/2,r.cy=e+n/2,r.width=i,r[Pe]=n}},c={};for(var h in l)l.hasOwnProperty(h)&&(c[h]=new l[h]);var d=e.extendShape({type:"symbol",shape:{symbolType:"",x:0,y:0,width:0,height:0},beforeBrush:function(){var t=this.style,e=this.shape;"pin"===e.symbolType&&t.textPosition===m&&(t.textPosition=["50%","40%"],t[F]=E,t.textVerticalAlign=B)},buildPath:function(t,e,i){var n=e.symbolType,r=c[n];"none"!==e.symbolType&&(r||(n="rect",r=c[n]),u[n](e.x,e.y,e.width,e[Pe],r.shape),r.buildPath(t,r.shape,i))}}),f=function(t){if("image"!==this.type){var e=this.style,i=this.shape;i&&"line"===i.symbolType?e[y]=t:this.__isEmptyBrush?(e[y]=t,e.fill="#fff"):(e.fill&&(e.fill=t),e[y]&&(e[y]=t)),this.dirty(!1)}},p={createSymbol:function(t,i,r,a,o,s){var l=0===t[me]("empty");l&&(t=t.substr(5,1)[ke]()+t.substr(6));var u;return u=0===t[me]("image://")?new e.Image({style:{image:t.slice(8),x:i,y:r,width:a,height:o}}):0===t[me]("path://")?e.makePath(t.slice(7),{},new n(i,r,a,o)):new d({shape:{symbolType:t,x:i,y:r,width:a,height:o}}),u.__isEmptyBrush=l,u.setColor=f,u.setColor(s),u}};return p}),e("echarts/component/helper/listComponent",[Re,"../../util/layout","../../util/format",u],function(t){function e(t,e,n){i.positionElement(t,e.getBoxLayoutParams(),{width:n[Te](),height:n[Me]()},e.get("padding"))}var i=t("../../util/layout"),n=t("../../util/format"),r=t(u);return{layout:function(t,n,r){var a=i.getLayoutRect(n.getBoxLayoutParams(),{width:r[Te](),height:r[Me]()},n.get("padding"));i.box(n.get("orient"),t,n.get("itemGap"),a.width,a[Pe]),e(t,n,r)},addBackground:function(t,e){var i=n.normalizeCssArray(e.get("padding")),a=t[N](),o=e.getItemStyle(["color",O]);o.fill=e.get("backgroundColor");var s=new r.Rect({shape:{x:a.x-i[3],y:a.y-i[0],width:a.width+i[1]+i[3],height:a[Pe]+i[0]+i[2]},style:o,silent:!0,z2:-1});r.subPixelOptimizeRect(s),t.add(s)}}}),e("echarts/component/tooltip/TooltipContent",[Re,De,"zrender/tool/color","zrender/core/event","../../util/format",Oe],function(t){function e(t){var e="cubic-bezier(0.23, 1, 0.32, 1)",i="left "+t+"s "+e+",top "+t+"s "+e;return a.map(f,function(t){return t+"transition:"+i}).join(";")}function i(t){var e=[],i=t.get("fontSize"),n=t.getTextColor();return n&&e.push("color:"+n),e.push("font:"+t[V]()),i&&e.push("line-height:"+Math.round(3*i/2)+"px"),c(["decoration","align"],function(i){var n=t.get(i);n&&e.push("text-"+i+":"+n)}),e.join(";")}function n(t){t=t;var n=[],r=t.get("transitionDuration"),a=t.get("backgroundColor"),s=t[Se](G),f=t.get("padding");return r&&n.push(e(r)),a&&(d[we]?n.push("background-Color:"+a):(n.push("background-Color:#"+o.toHex(a)),n.push("filter:alpha(opacity=70)"))),c(["width","color",l],function(e){var i="border-"+e,r=h(i),a=t.get(r);null!=a&&n.push(i+":"+a+("color"===e?"":"px"))}),n.push(i(s)),null!=f&&n.push("padding:"+u.normalizeCssArray(f).join("px ")+"px"),n.join(";")+";"}function r(t,e){var i=document[P]("div"),n=e.getZr();this.el=i,this._x=e[Te]()/2,this._y=e[Me]()/2,t.appendChild(i),this._container=t,this._show=!1,this._hideTimeout;var r=this;i.onmouseenter=function(){r.enterable&&(clearTimeout(r._hideTimeout),r._show=!0),r._inContent=!0},i.onmousemove=function(e){if(e=e||window.event,!r.enterable){var i=n.handler;s.normalizeEvent(t,e,!0),i.dispatch("mousemove",e)}},i.onmouseleave=function(){r.enterable&&r._show&&r.hideLater(r._hideDelay),r._inContent=!1}}var a=t(De),o=t("zrender/tool/color"),s=t("zrender/core/event"),u=t("../../util/format"),c=a.each,h=u.toCamelCase,d=t(Oe),f=["","-webkit-","-moz-","-o-"],p="position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;";return r[Ie]={constructor:r,enterable:!0,update:function(){var t=this._container,e=t.currentStyle||document.defaultView.getComputedStyle(t),i=t.style;"absolute"!==i[R]&&"absolute"!==e[R]&&(i[R]="relative")},show:function(t){clearTimeout(this._hideTimeout);var e=this.el;e.style.cssText=p+n(t)+";left:"+this._x+"px;top:"+this._y+"px;"+(t.get("extraCssText")||""),e.style.display=e.innerHTML?"block":"none",this._show=!0},setContent:function(t){var e=this.el;e.innerHTML=t,e.style.display=t?"block":"none"},moveTo:function(t,e){var i=this.el.style;i.left=t+"px",i.top=e+"px",this._x=t,this._y=e},hide:function(){this.el.style.display="none",this._show=!1},hideLater:function(t){!this._show||this._inContent&&this.enterable||(t?(this._hideDelay=t,this._show=!1,this._hideTimeout=setTimeout(a.bind(this.hide,this),t)):this.hide())},isShow:function(){return this._show}},r}),e("echarts/chart/pie/labelLayout",[Re,"zrender/contain/text"],function(t){function e(t,e,i,n,r,a,o){function s(e,i,n){for(var r=e;i>r;r++)if(t[r].y+=n,r>e&&i>r+1&&t[r+1].y>t[r].y+t[r][Pe])return void l(r,n/2);l(i-1,n/2)}function l(e,i){for(var n=e;n>=0&&(t[n].y-=i,!(n>0&&t[n].y>t[n-1].y+t[n-1][Pe]));n--);}function u(t,e,i,n,r,a){for(var o=a>0?e?Number.MAX_VALUE:0:e?Number.MAX_VALUE:0,s=0,l=t[ge];l>s;s++)if(t[s][R]!==E){var u=Math.abs(t[s].y-n),c=t[s].len,h=t[s].len2,d=r+c>u?Math.sqrt((r+c+h)*(r+c+h)-u*u):Math.abs(t[s].x-i);e&&d>=o&&(d=o-10),!e&&o>=d&&(d=o+10),t[s].x=i+d*a,o=d}}t.sort(function(t,e){return t.y-e.y});for(var c,h=0,d=t[ge],f=[],p=[],v=0;d>v;v++)c=t[v].y-h,0>c&&s(v,d,-c,r),h=t[v].y+t[v][Pe];0>o-h&&l(d-1,h-o);for(var v=0;d>v;v++)t[v].y>=i?p.push(t[v]):f.push(t[v]);u(f,!1,e,i,n,r),u(p,!0,e,i,n,r)}function i(t,i,n,r,a,o){for(var s=[],l=[],u=0;u<t[ge];u++)t[u].x<i?s.push(t[u]):l.push(t[u]);e(l,i,n,r,1,a,o),e(s,i,n,r,-1,a,o);for(var u=0;u<t[ge];u++){var c=t[u].linePoints;if(c){var h=c[1][0]-c[2][0];c[2][0]=t[u].x<i?t[u].x+3:t[u].x-3,c[1][1]=c[2][1]=t[u].y,c[1][0]=c[2][0]+h}}}var n=t("zrender/contain/text");return function(t,e,r,a){var o,s,l=t[pe](),u=[],c=!1;l.each(function(i){var r,a,d,f,p=l.getItemLayout(i),v=l[h](i),g=v[Se]("label.normal"),y=g.get(R)||v.get("label.emphasis.position"),x=v[Se]("labelLine.normal"),_=x.get(ge),b=x.get("length2"),M=(p.startAngle+p.endAngle)/2,T=Math.cos(M),S=Math.sin(M);o=p.cx,s=p.cy;var C=y===m||"inner"===y;if(y===E)r=p.cx,a=p.cy,f=E;else{var A=(C?(p.r+p.r0)/2*T:p.r*T)+o,P=(C?(p.r+p.r0)/2*S:p.r*S)+s;if(r=A+3*T,a=P+3*S,!C){var L=A+T*(_+e-p.r),I=P+S*(_+e-p.r),k=L+(0>T?-1:1)*b,z=I;r=k+(0>T?-5:5),a=z,d=[[A,P],[L,I],[k,z]]}f=C?E:T>0?"left":"right"}var D=g[Se](G)[V](),O=g.get("rotate")?0>T?-M+Math.PI:-M:0,B=t.getFormattedLabel(i,w)||l.getName(i),F=n[N](B,D,f,"top");c=!!O,p.label={x:r,y:a,position:y,height:F[Pe],len:_,len2:b,linePoints:d,textAlign:f,verticalAlign:"middle",font:D,rotation:O},C||u.push(p.label)}),!c&&t.get("avoidLabelOverlap")&&i(u,o,s,e,r,a)}}),e("echarts/component/axis/AxisBuilder",[Re,De,"../../util/format",u,"../../model/Model","../../util/number",ze],function(t){function e(t){var e={componentType:t.mainType};return e[t.mainType+"Index"]=t[T],e}function i(t,e,i){var n,r,a=g(e-t[p]);return y(a)?(r=i>0?"top":ye,n=E):y(a-S)?(r=i>0?ye:"top",n=E):(r=B,n=a>0&&S>a?i>0?"right":"left":i>0?"left":"right"),{rotation:a,textAlign:n,verticalAlign:r}}function o(t,e,i,n){var r,a,o=g(i-t[p]),s=n[0]>n[1],l="start"===e&&!s||"start"!==e&&s;return y(o-S/2)?(a=l?ye:"top",r=E):y(o-1.5*S)?(a=l?"top":ye,r=E):(a=B,r=1.5*S>o&&o>S/2?l?"left":"right":l?"right":"left"),{rotation:o,textAlign:r,verticalAlign:a}}function s(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)}var l=t(De),c=t("../../util/format"),h=t(u),v=t("../../model/Model"),m=t("../../util/number"),g=m.remRadian,y=m.isRadianAroundZero,x=t(ze),b=x[_],w=l[f],S=Math.PI,C=function(t,e){this.opt=e,this.axisModel=t,l[ae](e,{labelOffset:0,nameDirection:1,tickDirection:1,labelDirection:1,silent:!0}),this.group=new h.Group; +var i=new h.Group({position:e[R].slice(),rotation:e[p]});i.updateTransform(),this._transform=i[n],this._dumbGroup=i};C[Ie]={constructor:C,hasBuilder:function(t){return!!A[t]},add:function(t){A[t].call(this)},getGroup:function(){return this.group}};var A={axisLine:function(){var t=this.opt,e=this.axisModel;if(e.get("axisLine.show")){var i=this.axisModel.axis[z](),n=this._transform,r=[i[0],0],a=[i[1],0];n&&(b(r,r,n),b(a,a,n)),this.group.add(new h.Line(h.subPixelOptimizeLine({anid:"line",shape:{x1:r[0],y1:r[1],x2:a[0],y2:a[1]},style:l[oe]({lineCap:"round"},e[Se]("axisLine.lineStyle").getLineStyle()),strokeContainThreshold:t.strokeContainThreshold||5,silent:!0,z2:1})))}},axisTick:function(){var t=this.axisModel;if(t.get("axisTick.show"))for(var e=t.axis,i=t[Se]("axisTick"),n=this.opt,r=i[Se]("lineStyle"),a=i.get(ge),o=L(i,n.labelInterval),s=e.getTicksCoords(i.get("alignWithLabel")),u=e.scale[k](),c=[],d=[],f=this._transform,p=0;p<s[ge];p++)if(!P(e,p,o)){var v=s[p];c[0]=v,c[1]=0,d[0]=v,d[1]=n.tickDirection*a,f&&(b(c,c,f),b(d,d,f)),this.group.add(new h.Line(h.subPixelOptimizeLine({anid:"tick_"+u[p],shape:{x1:c[0],y1:c[1],x2:d[0],y2:d[1]},style:l[ae](r.getLineStyle(),{stroke:t.get("axisLine.lineStyle.color")}),z2:2,silent:!0})))}},axisLabel:function(){function t(t,e){var i=t&&t[N]().clone(),n=e&&e[N]().clone();return i&&n?(i[_](t.getLocalTransform()),n[_](e.getLocalTransform()),i.intersect(n)):void 0}var n=this.opt,o=this.axisModel,u=w(n.axisLabelShow,o.get("axisLabel.show"));if(u){var c=o.axis,d=o[Se]("axisLabel"),f=d[Se](G),m=d.get("margin"),g=c.scale[k](),y=o.getFormattedLabels(),x=w(n.labelRotation,d.get("rotate"))||0;x=x*S/180;var b=i(n,x,n.labelDirection),T=o.get("data"),C=[],A=s(o),L=o.get("triggerEvent");if(l.each(g,function(t,i){if(!P(c,i,n.labelInterval)){var r=f;T&&T[t]&&T[t][G]&&(r=new v(T[t][G],f,o[M]));var s=r.getTextColor()||o.get("axisLine.lineStyle.color"),l=c[a](t),u=[l,n.labelOffset+n.labelDirection*m],d=c.scale.getLabel(t),g=new h.Text({anid:"label_"+t,style:{text:y[i],textAlign:r.get("align",!0)||b[F],textVerticalAlign:r.get("baseline",!0)||b.verticalAlign,textFont:r[V](),fill:typeof s===j?s(d):s},position:u,rotation:b[p],silent:A,z2:10});L&&(g.eventData=e(o),g.eventData.targetType="axisLabel",g.eventData.value=d),this._dumbGroup.add(g),g.updateTransform(),C.push(g),this.group.add(g),g.decomposeTransform()}},this),c.type!==r){if(o.getMin?o.getMin():o.get("min")){var I=C[0],z=C[1];t(I,z)&&(I[xe]=!0)}if(o.getMax?o.getMax():o.get("max")){var D=C[C[ge]-1],O=C[C[ge]-2];t(O,D)&&(D[xe]=!0)}}}},axisName:function(){var t=this.opt,n=this.axisModel,r=w(t.axisName,n.get("name"));if(r){var a,u=n.get("nameLocation"),d=t.nameDirection,f=n[Se]("nameTextStyle"),v=n.get("nameGap")||0,m=this.axisModel.axis[z](),g=m[0]>m[1]?-1:1,y=["start"===u?m[0]-g*v:"end"===u?m[1]+g*v:(m[0]+m[1])/2,u===B?t.labelOffset+d*v:0],x=n.get("nameRotate");null!=x&&(x=x*S/180);var _;u===B?a=i(t,null!=x?x:t[p],d):(a=o(t,u,x||0,m),_=t.axisNameAvailableWidth,null!=_&&(_=Math.abs(_/Math.sin(a[p])),!isFinite(_)&&(_=null)));var b=f[V](),M=n.get("nameTruncate",!0)||{},C=M.ellipsis,A=w(M.maxWidth,_),P=null!=C&&null!=A?c.truncateText(r,A,b,C,{minChar:2,placeholder:M.placeholder}):r,L=n.get("tooltip",!0),I=n.mainType,k={componentType:I,name:r,$vars:["name"]};k[I+"Index"]=n[T];var D=new h.Text({anid:"name",__fullText:r,__truncatedText:P,style:{text:P,textFont:b,fill:f.getTextColor()||n.get("axisLine.lineStyle.color"),textAlign:a[F],textVerticalAlign:a.verticalAlign},position:y,rotation:a[p],silent:s(n),z2:1,tooltip:L&&L.show?l[oe]({content:r,formatter:function(){return r},formatterParams:k},L):null});n.get("triggerEvent")&&(D.eventData=e(n),D.eventData.targetType="axisName",D.eventData.name=r),this._dumbGroup.add(D),D.updateTransform(),this.group.add(D),D.decomposeTransform()}}},P=C.ifIgnoreOnTick=function(t,e,i){var n,r=t.scale;return r.type===d&&(typeof i===j?(n=r[k]()[e],!i(n,r.getLabel(n))):e%(i+1))},L=C.getInterval=function(t,e){var i=t.get("interval");return(null==i||"auto"==i)&&(i=e),i};return C}),e("echarts/component/helper/brushHelper",[Re,De,u],function(t){function e(t){return t[0]>t[1]&&t.reverse(),t}function i(t,e){for(var i=!0,n=0;n<d[ge];n++){var r=d[n]+"Index";if(t[r]>=0){i=!1;for(var a=0;a<e[ge];a++)if(e[a][r]===t[r])return e[a]}}return i}function n(t,i,n,s){var l=n.coordSys[o](t);return e(r.map([0,1],function(t){return i?l.coordToData(l.toLocalCoord(s[t])):l.toGlobalCoord(l[a](s[t]))}))}var r=t(De),l=t(u),c=r.each,h={},d=["geo","xAxis","yAxis"],f="--",p=[s,"pointToData"];h.parseOutputRanges=function(t,e,n,r){c(t,function(t,n){var a=t.panelId;if(a){a=a.split(f),t[a[0]+"Index"]=+a[1];var o=i(t,e);t.coordRange=v[t.brushType](1,o,t.range),r&&(r[n]=o)}})},h.parseInputRanges=function(t){c(t.areas,function(e){var n=i(e,t.coordInfoList);e.range=e.range||[],n&&n!==!0&&(e.range=v[e.brushType](0,n,e.coordRange),e.panelId=n.panelId)})},h.makePanelOpts=function(t){var e=[];return c(t,function(t){var i,n=t.coordSys;t.geoIndex>=0?(i=n[N]().clone(),i[_](l.getTransform(n))):i=n.grid.getRect().clone(),e.push({panelId:t.panelId,rect:i})}),e},h.makeCoordInfoList=function(t,e){var i=[];return c(d,function(n){var a=t[n+"Index"];null!=a&&"none"!==a&&("all"===a||r[U](a)||(a=[a]),e[_e]({mainType:n},function(t,e){if(!("all"!==a&&r[me](a,e)<0)){var o,s;"xAxis"===n||"yAxis"===n?o=t.axis.grid:s=t[ve];for(var l,u=0,c=i[ge];c>u;u++){var h=i[u];if("yAxis"===n&&!h.yAxis&&h.xAxis){var d=o.getCartesian(h.xAxisIndex,e);if(d){s=d,l=h;break}}}!l&&i.push(l={}),l[n]=t,l[n+"Index"]=e,l.panelId=n+f+e,l.coordSys=s||o.getCartesian(l.xAxisIndex,l.yAxisIndex),l.coordSys?i[n+"Has"]=!0:i.pop()}}))}),i},h.controlSeries=function(t,e,n){var r=i(t,e.coordInfoList);return r===!0||r&&r.coordSys===n[ve]};var v={lineX:r.curry(n,"x"),lineY:r.curry(n,"y"),rect:function(t,i,n){var r=i.coordSys,a=r[p[t]]([n[0][0],n[1][0]]),o=r[p[t]]([n[0][1],n[1][1]]);return[e([a[0],o[0]]),e([a[1],o[1]])]},polygon:function(t,e,i){var n=e.coordSys;return r.map(i,n[p[t]],n)}};return h}),e("echarts/component/dataZoom/history",[Re,De],function(t){function e(t){var e=t[r];return e||(e=t[r]=[{}]),e}var i=t(De),n=i.each,r="\x00_ec_hist_store",a={push:function(t,i){var r=e(t);n(i,function(e,i){for(var n=r[ge]-1;n>=0;n--){var a=r[n];if(a[i])break}if(0>n){var o=t[S]({mainType:"dataZoom",subType:"select",id:i})[0];if(o){var s=o.getPercentRange();r[0][i]={dataZoomId:i,start:s[0],end:s[1]}}}}),r.push(i)},pop:function(t){var i=e(t),r=i[i[ge]-1];i[ge]>1&&i.pop();var a={};return n(r,function(t,e){for(var n=i[ge]-1;n>=0;n--){var t=i[n][e];if(t){a[e]=t;break}}}),a},clear:function(t){t[r]=null},count:function(t){return e(t)[ge]}};return a}),e("echarts/component/helper/BrushController",[Re,"zrender/mixin/Eventful",De,"zrender/core/BoundingRect",u,"./interactionMutex","../../data/DataDiffer"],function(t){function e(t){G.call(this),this._zr=t,this.group=new q.Group,this._brushType,this._brushOption,this._panels,this._track=[],this._dragging,this._covers=[],this._creatingCover,this._creatingPanel,this._enableGlobalPan,this._uid="brushController_"+fe++,this._handlers={},X(pe,function(t,e){this._handlers[e]=H.bind(t,this)},this)}function i(t,e){var i=t._zr;t._enableGlobalPan||W.take(i,oe,t._uid),X(t._handlers,function(t,e){i.on(e,t)}),t._brushType=e.brushType,t._brushOption=H.merge(H.clone(de),e,!0)}function n(t){var e=t._zr;W.release(e,oe,t._uid),X(t._handlers,function(t,i){e.off(i,t)}),t._brushType=t._brushOption=null}function r(t,e){var i=ve[e.brushType].createCover(t,e);return s(i),i.__brushOption=e,t.group.add(i),i}function a(t,e){var i=c(e);return i.endCreating&&(i.endCreating(t,e),s(e)),e}function o(t,e){var i=e.__brushOption;c(e).updateCoverShape(t,e,i.range,i)}function s(t){t[Q](function(t){t.z=ee,t.z2=ee})}function l(t,e){c(e).updateCommon(t,e),o(t,e)}function c(t){return ve[t.__brushOption.brushType]}function h(t,e,i){var n=t._panels;if(!n)return!0;var r;return X(n,function(t){t[D](e,i)&&(r=t)}),r}function d(t,e){var i=t._panels;if(!i)return!0;var n=e.__brushOption.panelId;return null!=n?i[n]:!0}function f(t){var e=t._covers,i=e[ge];return X(e,function(e){t.group[se](e)},t),e[ge]=0,!!i}function v(t,e){var i=Y(t._covers,function(t){var e=t.__brushOption,i=H.clone(e.range);return{brushType:e.brushType,panelId:e.panelId,range:i}});t[re]("brush",i,{isEnd:!!e.isEnd,removeOnClick:!!e.removeOnClick})}function m(t){var e=t._track;if(!e[ge])return!1;var i=e[e[ge]-1],n=e[0],r=i[0]-n[0],a=i[1]-n[1],o=te(r*r+a*a,.5);return o>ie}function g(t){var e=t[ge]-1;return 0>e&&(e=0),[t[0],t[e]]}function y(t,e,i,n){var r=new q.Group;return r.add(new q.Rect({name:"main",style:M(i),silent:!0,draggable:!0,cursor:"move",drift:U(t,e,r,"nswe"),ondragend:U(v,e,{isEnd:!0})})),X(n,function(i){r.add(new q.Rect({name:i,style:{opacity:0},draggable:!0,silent:!0,invisible:!0,drift:U(t,e,r,i),ondragend:U(v,e,{isEnd:!0})}))}),r}function _(t,e,i,n){var r=n.brushStyle[x]||0,a=K(r,ne),o=i[0][0],s=i[1][0],l=o-r/2,u=s-r/2,c=i[0][1],h=i[1][1],d=c-a+r/2,f=h-a+r/2,p=c-o,v=h-s,m=p+r,g=v+r;w(t,e,"main",o,s,p,v),n.transformable&&(w(t,e,"w",l,u,a,g),w(t,e,"e",d,u,a,g),w(t,e,"n",l,u,m,a),w(t,e,"s",l,f,m,a),w(t,e,"nw",l,u,a,a),w(t,e,"ne",d,u,a,a),w(t,e,"sw",l,f,a,a),w(t,e,"se",d,f,a,a))}function b(t,e){var i=e.__brushOption,n=i.transformable,r=e.childAt(0);r.useStyle(M(i)),r.attr({silent:!n,cursor:n?"move":"default"}),X(["w","e","n","s","se","sw","ne","nw"],function(i){var r=e.childOfName(i),a=C(t,i);r&&r.attr({silent:!n,invisible:!n,cursor:n?ue[a]+"-resize":null})})}function w(t,e,i,n,r,a,o){var s=e.childOfName(i);s&&s.setShape(k(I(t,e,[[n,r],[n+a,r+o]])))}function M(t){return H[ae]({strokeNoScale:!0},t.brushStyle)}function T(t,e,i,n){var r=[$(t,i),$(e,n)],a=[K(t,i),K(e,n)];return[[r[0],a[0]],[r[1],a[1]]]}function S(t){return q.getTransform(t.group)}function C(t,e){if(e[ge]>1){e=e.split("");var i=[C(t,e[0]),C(t,e[1])];return("e"===i[0]||"w"===i[0])&&i.reverse(),i.join("")}var n={w:"left",e:"right",n:"top",s:"bottom"},r={left:"w",right:"e",top:"n",bottom:"s"},i=q.transformDirection(n[e],S(t));return r[i]}function A(t,e,i,n,r,a,o){var s=n.__brushOption,u=t(s.range),c=L(i,a,o);X(r.split(""),function(t){var e=le[t];u[e[0]][e[1]]+=c[e[0]]}),s.range=e(T(u[0][0],u[1][0],u[0][1],u[1][1])),l(i,n),v(i,{isEnd:!1})}function P(t,e,i,n){var r=e.__brushOption.range,a=L(t,i,n);X(r,function(t){t[0]+=a[0],t[1]+=a[1]}),l(t,e),v(t,{isEnd:!1})}function L(t,e,i){var n=t.group,r=n.transformCoordToLocal(e,i),a=n.transformCoordToLocal(0,0);return[r[0]-a[0],r[1]-a[1]]}function I(t,e,i){var n=d(t,e);if(n===!0)return H.clone(i);var r=n[N]();return H.map(i,function(t){var e=t[0];e=K(e,r.x),e=$(e,r.x+r.width);var i=t[1];return i=K(i,r.y),i=$(i,r.y+r[Pe]),[e,i]})}function k(t){var e=$(t[0][0],t[1][0]),i=$(t[0][1],t[1][1]),n=K(t[0][0],t[1][0]),r=K(t[0][1],t[1][1]);return{x:e,y:i,width:n-e,height:r-i}}function z(t,e){var i=e.offsetX,n=e.offsetY,r=t._zr;if(t._brushType){for(var a,o=t._panels,s=t._covers,l=0;l<s[ge];l++)if(ve[s[l].__brushOption.brushType][D](s[l],i,n)){a=!0;break}a||(o?X(o,function(t){t[D](i,n)&&r.setCursorStyle("crosshair")}):r.setCursorStyle("crosshair"))}}function O(t){var e=t.event;e.preventDefault&&e.preventDefault()}function E(t,e,i){return t.childOfName("main")[D](e,i)}function B(t,e,i){var n,s=e.offsetX,l=e.offsetY,u=t._creatingCover,c=t._creatingPanel,d=t._brushOption;if(t._track.push(t.group.transformCoordToLocal(s,l)),m(t)||u){if(c&&!u){"single"===d.brushMode&&f(t);var p=H.clone(d);p.panelId=c===!0?null:c.__brushPanelId,u=t._creatingCover=r(t,p),t._covers.push(u)}if(u){var v=ve[t._brushType],g=u.__brushOption;g.range=v.getCreatingRange(I(t,u,t._track)),i&&(a(t,u),v.updateCommon(t,u)),o(t,u),n={isEnd:i}}}else i&&"single"===d.brushMode&&d.removeOnClick&&h(t,s,l)&&f(t)&&(n={isEnd:i,removeOnClick:!0});return n}function V(t){if(this._dragging){O(t);var e=B(this,t,!0);this._dragging=!1,this._track=[],this._creatingCover=null,e&&v(this,e)}}function F(t){return{createCover:function(e,i){return y(U(A,function(e){var i=[e,[0,100]];return t&&i.reverse(),i},function(e){return e[t]}),e,i,[["w","e"],["n","s"]][t])},getCreatingRange:function(e){var i=g(e),n=$(i[0][t],i[1][t]),r=K(i[0][t],i[1][t]);return[n,r]},updateCoverShape:function(e,i,n,r){var a,o=r.brushStyle.width;if(null==o){var s=d(e,i),l=0;if(s!==!0){var u=s[N]();o=t?u.width:u[Pe],l=t?u.x:u.y}a=[l,l+(o||0)]}else a=[-o/2,o/2];var c=[n,a];t&&c.reverse(),_(e,i,c,r)},updateCommon:b,contain:E}}var G=t("zrender/mixin/Eventful"),H=t(De),Z=t("zrender/core/BoundingRect"),q=t(u),W=t("./interactionMutex"),j=t("../../data/DataDiffer"),U=H.curry,X=H.each,Y=H.map,$=Math.min,K=Math.max,te=Math.pow,ee=1e4,ie=6,ne=6,oe="globalPan",le={w:[0,0],e:[0,1],n:[1,0],s:[1,1]},ue={w:"ew",e:"ew",n:"ns",s:"ns",ne:"nesw",sw:"nesw",nw:"nwse",se:"nwse"},de={brushStyle:{lineWidth:2,stroke:"rgba(0,0,0,0.3)",fill:"rgba(0,0,0,0.1)"},transformable:!0,brushMode:"single",removeOnClick:!1},fe=0;e[Ie]={constructor:e,enableBrush:function(t){return this._brushType&&n(this),t.brushType&&i(this,t),this},setPanels:function(t){var e=this._panels||{},i=this._panels=t&&t[ge]&&{},n=this.group;return i&&X(t,function(t){var r=t.panelId,a=e[r];a||(a=new q.Rect({silent:!0,invisible:!0}),n.add(a));var o=t.rect;o instanceof Z||(o=Z[he](o)),a.attr("shape",o.plain()),a.__brushPanelId=r,i[r]=a,e[r]=null}),X(e,function(t){t&&n[se](t)}),this},mount:function(t){t=t||{},this._enableGlobalPan=t.enableGlobalPan;var e=this.group;return this._zr.add(e),e.attr({position:t[R]||[0,0],rotation:t[p]||0,scale:t.scale||[1,1]}),this},eachCover:function(t,e){X(this._covers,t,e)},updateCovers:function(t){function e(t,e){return(null!=t.id?t.id:s+e)+"-"+t.brushType}function i(t,i){return e(t.__brushOption,i)}function n(e,i){var n=t[e];if(null!=i&&u[i]===d)c[e]=u[i];else{var o=c[e]=null!=i?(u[i].__brushOption=n,u[i]):a(h,r(h,n));l(h,o)}}function o(t){u[t]!==d&&h.group[se](u[t])}t=H.map(t,function(t){return H.merge(H.clone(de),t,!0)});var s="\x00-brush-index-",u=this._covers,c=this._covers=[],h=this,d=this._creatingCover;return new j(u,t,i,e).add(n)[ce](n)[se](o).execute(),this},unmount:function(){return this.enableBrush(!1),f(this),this._zr[se](this.group),this},dispose:function(){this.unmount(),this.off()}},H.mixin(e,G);var pe={mousedown:function(t){if(this._dragging)V.call(this,t);else if(!t[J]||!t[J].draggable){O(t);var e=t.offsetX,i=t.offsetY;this._creatingCover=null;var n=this._creatingPanel=h(this,e,i);n&&(this._dragging=!0,this._track=[this.group.transformCoordToLocal(e,i)])}},mousemove:function(t){if(z(this,t),this._dragging){O(t);var e=B(this,t,!1);e&&v(this,e)}},mouseup:V},ve={lineX:F(0),lineY:F(1),rect:{createCover:function(t,e){return y(U(A,function(t){return t},function(t){return t}),t,e,["w","e","n","s","se","sw","ne","nw"])},getCreatingRange:function(t){var e=g(t);return T(e[1][0],e[1][1],e[0][0],e[0][1])},updateCoverShape:function(t,e,i,n){_(t,e,i,n)},updateCommon:b,contain:E},polygon:{createCover:function(t,e){var i=new q.Group;return i.add(new q.Polyline({name:"main",style:M(e),silent:!0})),i},getCreatingRange:function(t){return t},endCreating:function(t,e){e[se](e.childAt(0)),e.add(new q.Polygon({name:"main",draggable:!0,drift:U(P,t,e),ondragend:U(v,t,{isEnd:!0})}))},updateCoverShape:function(t,e,i){e.childAt(0).setShape({points:I(t,e,i)})},updateCommon:b,contain:E}};return e}),e("echarts/component/dataZoomSelect",[Re,"./dataZoom/typeDefaulter","./dataZoom/DataZoomModel","./dataZoom/DataZoomView","./dataZoom/SelectZoomModel","./dataZoom/SelectZoomView","./dataZoom/dataZoomProcessor","./dataZoom/dataZoomAction"],function(t){t("./dataZoom/typeDefaulter"),t("./dataZoom/DataZoomModel"),t("./dataZoom/DataZoomView"),t("./dataZoom/SelectZoomModel"),t("./dataZoom/SelectZoomView"),t("./dataZoom/dataZoomProcessor"),t("./dataZoom/dataZoomAction")}),e("echarts/component/helper/interactionMutex",[Re,"../../echarts"],function(t){function e(t){return t[i]||(t[i]={})}var i="\x00_ec_interaction_mutex",n={take:function(t,i,n){var r=e(t);r[i]=n},release:function(t,i,n){var r=e(t),a=r[i];a===n&&(r[i]=null)},isTaken:function(t,i){return!!e(t)[i]}};return t("../../echarts").registerAction({type:"takeGlobalCursor",event:"globalCursorTaken",update:"update"},function(){}),n}),e("echarts/component/dataZoom/typeDefaulter",[Re,"../../model/Component"],function(t){t("../../model/Component").registerSubTypeDefaulter("dataZoom",function(){return"slider"})}),e("echarts/component/dataZoom/DataZoomModel",[Re,De,Oe,"../../echarts","../../util/model","./helper","./AxisProxy"],function(t){function e(t){var e={};return c(["start","end","startValue","endValue","throttle"],function(i){t.hasOwnProperty(i)&&(e[i]=t[i])}),e}function i(t,e,i,n){null!=i[e]&&null==i[t]&&(n[t]=null)}var n=t(De),a=t(Oe),o=t("../../echarts"),s=t("../../util/model"),l=t("./helper"),u=t("./AxisProxy"),c=n.each,h=l.eachAxisDim,d=o.extendComponentModel({type:"dataZoom",dependencies:["xAxis","yAxis","zAxis","radiusAxis","angleAxis",ne],defaultOption:{zlevel:0,z:4,orient:null,xAxisIndex:null,yAxisIndex:null,filterMode:"filter",throttle:null,start:0,end:100,startValue:null,endValue:null},init:function(t,i,n){this._dataIntervalByAxis={},this._dataInfo={},this._axisProxies={},this.textStyleModel,this._autoThrottle=!0;var r=e(t);this.mergeDefaultAndTheme(t,n),this.doInit(r)},mergeOption:function(t){var i=e(t);n.merge(this[C],t,!0),this.doInit(i)},doInit:function(t){var e=this[C];a[we]||(e.realtime=!1),this._setDefaultThrottle(t),i("start","startValue",t,e),i("end","endValue",t,e),this.textStyleModel=this[Se](G),this._resetTarget(),this._giveAxisProxies()},_giveAxisProxies:function(){var t=this._axisProxies;this.eachTargetAxis(function(e,i,n,r){var a=this.dependentModels[e.axis][i],o=a.__dzAxisProxy||(a.__dzAxisProxy=new u(e.name,i,this,r));t[e.name+"_"+i]=o},this)},_resetTarget:function(){var t=this[C],e=this._judgeAutoMode();h(function(e){var i=e.axisIndex;t[i]=s.normalizeToArray(t[i])},this),"axisIndex"===e?this._autoSetAxisIndex():"orient"===e&&this._autoSetOrient()},_judgeAutoMode:function(){var t=this[C],e=!1;h(function(i){null!=t[i.axisIndex]&&(e=!0)},this);var i=t.orient;return null==i&&e?"orient":e?void 0:(null==i&&(t.orient="horizontal"),"axisIndex")},_autoSetAxisIndex:function(){var t=!0,e=this.get("orient",!0),i=this[C];if(t){var a="vertical"===e?{dim:"y",axisIndex:"yAxisIndex",axis:"yAxis"}:{dim:"x",axisIndex:"xAxisIndex",axis:"xAxis"};this.dependentModels[a.axis][ge]&&(i[a.axisIndex]=[0],t=!1)}t&&h(function(e){if(t){var n=[],a=this.dependentModels[e.axis];if(a[ge]&&!n[ge])for(var o=0,s=a[ge];s>o;o++)a[o].get("type")===r&&n.push(o);i[e.axisIndex]=n,n[ge]&&(t=!1)}},this),t&&this[M].eachSeries(function(t){this._isSeriesHasAllAxesTypeOf(t,"value")&&h(function(e){var r=i[e.axisIndex],a=t.get(e.axisIndex),o=t.get(e.axisId),s=t[M][S]({mainType:e.axis,index:a,id:o})[0];a=s[T],n[me](r,a)<0&&r.push(a)})},this)},_autoSetOrient:function(){var t;this.eachTargetAxis(function(e){!t&&(t=e.name)},this),this[C].orient="y"===t?"vertical":"horizontal"},_isSeriesHasAllAxesTypeOf:function(t,e){var i=!0;return h(function(n){var r=t.get(n.axisIndex),a=this.dependentModels[n.axis][r];a&&a.get("type")===e||(i=!1)},this),i},_setDefaultThrottle:function(t){if(t.hasOwnProperty("throttle")&&(this._autoThrottle=!1),this._autoThrottle){var e=this[M][C];this[C].throttle=e[Ce]&&e.animationDurationUpdate>0?100:20}},getFirstTargetAxisModel:function(){var t;return h(function(e){if(null==t){var i=this.get(e.axisIndex);i[ge]&&(t=this.dependentModels[e.axis][i[0]])}},this),t},eachTargetAxis:function(t,e){var i=this[M];h(function(n){c(this.get(n.axisIndex),function(r){t.call(e,n,r,this,i)},this)},this)},getAxisProxy:function(t,e){return this._axisProxies[t+"_"+e]},setRawRange:function(t){c(["start","end","startValue","endValue"],function(e){this[C][e]=t[e]},this)},getPercentRange:function(){var t=this.findRepresentativeAxisProxy();return t?t.getDataPercentWindow():void 0},getValueRange:function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var i=this.findRepresentativeAxisProxy();return i?i.getDataValueWindow():void 0},findRepresentativeAxisProxy:function(){var t=this._axisProxies;for(var e in t)if(t.hasOwnProperty(e)&&t[e].hostedBy(this))return t[e];for(var e in t)if(t.hasOwnProperty(e)&&!t[e].hostedBy(this))return t[e]}});return d}),e("echarts/component/dataZoom/dataZoomProcessor",[Re,"../../echarts"],function(t){function e(t,e,i){i.getAxisProxy(t.name,e).reset(i)}function i(t,e,i){i.getAxisProxy(t.name,e).filterData(i)}var n=t("../../echarts");n.registerProcessor(function(t){t[_e]("dataZoom",function(t){t.eachTargetAxis(e),t.eachTargetAxis(i)}),t[_e]("dataZoom",function(t){var e=t.findRepresentativeAxisProxy(),i=e.getDataPercentWindow(),n=e.getDataValueWindow();t.setRawRange({start:i[0],end:i[1],startValue:n[0],endValue:n[1]})})})}),e("echarts/component/dataZoom/SelectZoomModel",[Re,"./DataZoomModel"],function(t){var e=t("./DataZoomModel");return e[oe]({type:"dataZoom.select"})}),e("echarts/component/dataZoom/DataZoomView",[Re,"../../view/Component"],function(t){var e=t("../../view/Component");return e[oe]({type:"dataZoom",render:function(t,e,i){this.dataZoomModel=t,this[M]=e,this.api=i},getTargetInfo:function(){function t(t,e,i,n){for(var r,a=0;a<i[ge];a++)if(i[a].model===t){r=i[a];break}r||i.push(r={model:t,axisModels:[],coordIndex:n}),r.axisModels.push(e)}var e=this.dataZoomModel,i=this[M],n=[],r=[],a=[];return e.eachTargetAxis(function(e,o){var s=i.getComponent(e.axis,o);if(s){a.push(s);var l,u=e.axis;"xAxis"===u||"yAxis"===u?l="grid":("angleAxis"===u||"radiusAxis"===u)&&(l="polar");var c=l?i[S]({mainType:l,index:s.get(l+"Index"),id:s.get(l+"Id")})[0]:null;null!=c&&t(c,s,"grid"===l?n:r,c[T])}},this),{cartesians:n,polars:r,axisModels:a}}})}),e("echarts/component/dataZoom/SelectZoomView",[Re,"./DataZoomView"],function(t){return t("./DataZoomView")[oe]({type:"dataZoom.select"})}),e("echarts/component/dataZoom/dataZoomAction",[Re,De,"./helper","../../echarts"],function(t){var e=t(De),i=t("./helper"),n=t("../../echarts");n.registerAction("dataZoom",function(t,n){var r=i.createLinkedNodesFinder(e.bind(n[_e],n,"dataZoom"),i.eachAxisDim,function(t,e){return t.get(e.axisIndex)}),a=[];n[_e]({mainType:"dataZoom",query:t},function(t){a.push.apply(a,r(t).nodes)}),e.each(a,function(e){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})})})}),e("echarts/component/dataZoom/AxisProxy",[Re,De,"../../util/number"],function(t){function e(t,e){var i=[1/0,-1/0];return s(e,function(e){var n=e[pe]();n&&s(e.coordDimToDataDim(t),function(t){var e=n.getDataExtent(t);e[0]<i[0]&&(i[0]=e[0]),e[1]>i[1]&&(i[1]=e[1])})},this),i}function i(t,e,i){return s(["min","max"],function(n,r){var a=e.get(n,!0);null!=a&&(a+"")[ke]()!=="data"+n&&(t[r]=i.parse(a))}),e.get("scale",!0)||(t[0]>0&&(t[0]=0),t[1]<0&&(t[1]=0)),t}function n(t,e){var i=t.getAxisModel(),n=t._percentWindow,r=t._valueWindow;if(n){var a=e||0===n[0]&&100===n[1],s=!e&&o.getPixelPrecision(r,[0,500]),l=!(e||20>s&&s>=0),u=e||a||l;i.setRange&&i.setRange(u?null:+r[0].toFixed(s),u?null:+r[1].toFixed(s))}}var a=t(De),o=t("../../util/number"),s=a.each,u=o.asc,c=function(t,e,i,n){this._dimName=t,this._axisIndex=e,this._valueWindow,this._percentWindow,this._dataExtent,this[M]=n,this._dataZoomModel=i};return c[Ie]={constructor:c,hostedBy:function(t){return this._dataZoomModel===t},getDataExtent:function(){return this._dataExtent.slice()},getDataValueWindow:function(){return this._valueWindow.slice()},getDataPercentWindow:function(){return this._percentWindow.slice()},getTargetSeriesModels:function(){var t=[],e=this[M];return e.eachSeries(function(i){var n=i.get(ve);if("cartesian2d"===n||"polar"===n){var r=this._dimName,a=e[S]({mainType:r+"Axis",index:i.get(r+"AxisIndex"),id:i.get(r+"AxisId")})[0];this._axisIndex===(a&&a[T])&&t.push(i)}},this),t},getAxisModel:function(){return this[M].getComponent(this._dimName+"Axis",this._axisIndex)},getOtherAxisModel:function(){var t,e,i=this._dimName,n=this[M],r=this.getAxisModel(),a="x"===i||"y"===i;a?(e="gridIndex",t="x"===i?"y":"x"):(e="polarIndex",t="angle"===i?l:"angle");var o;return n[_e](t+"Axis",function(t){(t.get(e)||0)===(r.get(e)||0)&&(o=t)}),o},calculateDataWindow:function(t,e){var n=this.getAxisModel(),r=n.axis.scale,a=[0,100],l=[t.start,t.end],c=[];return e=e.slice(),i(e,n,r),s(["startValue","endValue"],function(e){c.push(null!=t[e]?r.parse(t[e]):null)}),s([0,1],function(t){var i=c[t],n=l[t];null!=n||null==i?(null==n&&(n=a[t]),i=r.parse(o.linearMap(n,a,e,!0))):n=o.linearMap(i,e,a,!0),c[t]=i,l[t]=n}),{valueWindow:u(c),percentWindow:u(l)}},reset:function(t){if(t===this._dataZoomModel){var i=this._dataExtent=e(this._dimName,this.getTargetSeriesModels()),r=this.calculateDataWindow(t[C],i);this._valueWindow=r.valueWindow,this._percentWindow=r.percentWindow,n(this)}},restore:function(t){t===this._dataZoomModel&&(this._valueWindow=this._percentWindow=null,n(this,!0))},filterData:function(t){function e(t){return t>=o[0]&&t<=o[1]}if(t===this._dataZoomModel){var i=this._dimName,n=this.getTargetSeriesModels(),a=t.get("filterMode"),o=this._valueWindow,l=this.getOtherAxisModel();t.get("$fromToolbox")&&l&&l.get("type")===r&&(a="empty"),s(n,function(t){var n=t[pe]();n&&s(t.coordDimToDataDim(i),function(i){"empty"===a?t.setData(n.map(i,function(t){return e(t)?t:0/0})):n.filterSelf(i,e)})})}}},c}),e("echarts/component/dataZoom/helper",[Re,"../../util/format",De],function(t){var e=t("../../util/format"),i=t(De),n={},r=["x","y","z",l,"angle"];return n.createNameEach=function(t,n){t=t.slice();var r=i.map(t,e.capitalFirst);n=(n||[]).slice();var a=i.map(n,e.capitalFirst);return function(e,o){i.each(t,function(t,i){for(var s={name:t,capital:r[i]},l=0;l<n[ge];l++)s[n[l]]=t+a[l];e.call(o,s)})}},n.eachAxisDim=n.createNameEach(r,["axisIndex","axis","index","id"]),n.createLinkedNodesFinder=function(t,e,n){function r(t,e){return i[me](e.nodes,t)>=0}function a(t,r){var a=!1;return e(function(e){i.each(n(t,e)||[],function(t){r.records[e.name][t]&&(a=!0)})}),a}function o(t,r){r.nodes.push(t),e(function(e){i.each(n(t,e)||[],function(t){r.records[e.name][t]=!0})})}return function(i){function n(t){!r(t,s)&&a(t,s)&&(o(t,s),l=!0)}var s={nodes:[],records:{}};if(e(function(t){s.records[t.name]={}}),!i)return s;o(i,s);var l;do l=!1,t(n);while(l);return s}},n}),e("zrender",["zrender/zrender"],function(t){return t}),e("echarts",["echarts/echarts"],function(t){return t});var Ee=t("echarts");return Ee.graphic=t("echarts/util/graphic"),Ee.number=t("echarts/util/number"),Ee.format=t("echarts/util/format"),t("echarts/chart/bar"),t("echarts/chart/line"),t("echarts/chart/pie"),t("echarts/component/grid"),t("echarts/component/title"),t("echarts/component/legend"),t("echarts/component/tooltip"),t("echarts/component/toolbox"),t("zrender/vml/vml"),Ee}); \ No newline at end of file diff --git a/static/plugins/font-awesome/css/font-awesome.min.css b/static/plugins/font-awesome/css/font-awesome.min.css new file mode 100755 index 0000000..540440c --- /dev/null +++ b/static/plugins/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/static/plugins/font-awesome/fonts/FontAwesome.otf b/static/plugins/font-awesome/fonts/FontAwesome.otf new file mode 100755 index 0000000..401ec0f Binary files /dev/null and b/static/plugins/font-awesome/fonts/FontAwesome.otf differ diff --git a/static/plugins/font-awesome/fonts/fontawesome-webfont.eot b/static/plugins/font-awesome/fonts/fontawesome-webfont.eot new file mode 100755 index 0000000..e9f60ca Binary files /dev/null and b/static/plugins/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/static/plugins/font-awesome/fonts/fontawesome-webfont.svg b/static/plugins/font-awesome/fonts/fontawesome-webfont.svg new file mode 100755 index 0000000..855c845 --- /dev/null +++ b/static/plugins/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg> +<metadata> +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. +</metadata> +<defs> +<font id="FontAwesome" horiz-adv-x="1536" > + <font-face + font-family="FontAwesome" + font-weight="400" + font-stretch="normal" + units-per-em="1792" + panose-1="0 0 0 0 0 0 0 0 0 0" + ascent="1536" + descent="-256" + bbox="-1.02083 -256.962 2304.6 1537.02" + underline-thickness="0" + underline-position="0" + unicode-range="U+0020-F500" + /> +<missing-glyph horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".notdef" horiz-adv-x="896" +d="M224 112h448v1312h-448v-1312zM112 0v1536h672v-1536h-672z" /> + <glyph glyph-name=".null" horiz-adv-x="0" + /> + <glyph glyph-name="nonmarkingreturn" horiz-adv-x="597" + /> + <glyph glyph-name="space" unicode=" " horiz-adv-x="448" + /> + <glyph glyph-name="dieresis" unicode="&#xa8;" horiz-adv-x="1792" + /> + <glyph glyph-name="copyright" unicode="&#xa9;" horiz-adv-x="1792" + /> + <glyph glyph-name="registered" unicode="&#xae;" horiz-adv-x="1792" + /> + <glyph glyph-name="acute" unicode="&#xb4;" horiz-adv-x="1792" + /> + <glyph glyph-name="AE" unicode="&#xc6;" horiz-adv-x="1792" + /> + <glyph glyph-name="Oslash" unicode="&#xd8;" horiz-adv-x="1792" + /> + <glyph glyph-name="trademark" unicode="&#x2122;" horiz-adv-x="1792" + /> + <glyph glyph-name="infinity" unicode="&#x221e;" horiz-adv-x="1792" + /> + <glyph glyph-name="notequal" unicode="&#x2260;" horiz-adv-x="1792" + /> + <glyph glyph-name="glass" unicode="&#xf000;" horiz-adv-x="1792" +d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> + <glyph glyph-name="music" unicode="&#xf001;" +d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 +t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> + <glyph glyph-name="search" unicode="&#xf002;" horiz-adv-x="1664" +d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 +t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="envelope" unicode="&#xf003;" horiz-adv-x="1792" +d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 +t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z +M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="heart" unicode="&#xf004;" horiz-adv-x="1792" +d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 +q-18 -18 -44 -18z" /> + <glyph glyph-name="star" unicode="&#xf005;" horiz-adv-x="1664" +d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 +l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="star_empty" unicode="&#xf006;" horiz-adv-x="1664" +d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 +l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> + <glyph glyph-name="user" unicode="&#xf007;" horiz-adv-x="1280" +d="M1280 137q0 -109 -62.5 -187t-150.5 -78h-854q-88 0 -150.5 78t-62.5 187q0 85 8.5 160.5t31.5 152t58.5 131t94 89t134.5 34.5q131 -128 313 -128t313 128q76 0 134.5 -34.5t94 -89t58.5 -131t31.5 -152t8.5 -160.5zM1024 1024q0 -159 -112.5 -271.5t-271.5 -112.5 +t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="film" unicode="&#xf008;" horiz-adv-x="1920" +d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 +q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 +t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 +q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 +t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="th_large" unicode="&#xf009;" horiz-adv-x="1664" +d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 +h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="th" unicode="&#xf00a;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> + <glyph glyph-name="th_list" unicode="&#xf00b;" horiz-adv-x="1792" +d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 +h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ok" unicode="&#xf00c;" horiz-adv-x="1792" +d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> + <glyph glyph-name="remove" unicode="&#xf00d;" horiz-adv-x="1408" +d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 +t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> + <glyph glyph-name="zoom_in" unicode="&#xf00e;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 +q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 +t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> + <glyph glyph-name="zoom_out" unicode="&#xf010;" horiz-adv-x="1664" +d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z +M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z +" /> + <glyph glyph-name="off" unicode="&#xf011;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 +t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> + <glyph glyph-name="signal" unicode="&#xf012;" horiz-adv-x="1792" +d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> + <glyph glyph-name="cog" unicode="&#xf013;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 +q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 +l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 +q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> + <glyph glyph-name="trash" unicode="&#xf014;" horiz-adv-x="1408" +d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 +q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="home" unicode="&#xf015;" horiz-adv-x="1664" +d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 +l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> + <glyph glyph-name="file_alt" unicode="&#xf016;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +" /> + <glyph glyph-name="time" unicode="&#xf017;" +d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="road" unicode="&#xf018;" horiz-adv-x="1920" +d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 +q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" /> + <glyph glyph-name="download_alt" unicode="&#xf019;" horiz-adv-x="1664" +d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 +q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> + <glyph glyph-name="download" unicode="&#xf01a;" +d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 +t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="upload" unicode="&#xf01b;" +d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 +t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="inbox" unicode="&#xf01c;" +d="M1023 576h316q-1 3 -2.5 8.5t-2.5 7.5l-212 496h-708l-212 -496q-1 -3 -2.5 -8.5t-2.5 -7.5h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 +q25 -61 25 -123z" /> + <glyph glyph-name="play_circle" unicode="&#xf01d;" +d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="repeat" unicode="&#xf01e;" +d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q15 0 25 -9 +l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> + <glyph glyph-name="refresh" unicode="&#xf021;" +d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 +q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 +q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="list_alt" unicode="&#xf022;" horiz-adv-x="1792" +d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z +M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 +t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="lock" unicode="&#xf023;" horiz-adv-x="1152" +d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> + <glyph glyph-name="flag" unicode="&#xf024;" horiz-adv-x="1792" +d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 +t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> + <glyph glyph-name="headphones" unicode="&#xf025;" horiz-adv-x="1664" +d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 +t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 +t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> + <glyph glyph-name="volume_off" unicode="&#xf026;" horiz-adv-x="768" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="volume_down" unicode="&#xf027;" horiz-adv-x="1152" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> + <glyph glyph-name="volume_up" unicode="&#xf028;" horiz-adv-x="1664" +d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 36 +t12 56.5t-12 56.5t-29 36t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 +t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 +t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> + <glyph glyph-name="qrcode" unicode="&#xf029;" horiz-adv-x="1408" +d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z +M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> + <glyph glyph-name="barcode" unicode="&#xf02a;" horiz-adv-x="1792" +d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z +M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> + <glyph glyph-name="tag" unicode="&#xf02b;" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="tags" unicode="&#xf02c;" horiz-adv-x="1920" +d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 +l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> + <glyph glyph-name="book" unicode="&#xf02d;" horiz-adv-x="1664" +d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 +q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 +q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 +t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> + <glyph glyph-name="bookmark" unicode="&#xf02e;" horiz-adv-x="1280" +d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="print" unicode="&#xf02f;" horiz-adv-x="1664" +d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 +v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" /> + <glyph glyph-name="camera" unicode="&#xf030;" horiz-adv-x="1920" +d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 +q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="font" unicode="&#xf031;" horiz-adv-x="1664" +d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57 +q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -5 -0.5 -13.5t-0.5 -12.5q-63 0 -190 8t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5 +q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" /> + <glyph glyph-name="bold" unicode="&#xf032;" horiz-adv-x="1408" +d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 +q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5 +t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68 -0.5t68 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5 +t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" /> + <glyph glyph-name="italic" unicode="&#xf033;" horiz-adv-x="1024" +d="M0 -126l17 85q22 7 61.5 16.5t72 19t59.5 23.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 +q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" /> + <glyph glyph-name="text_height" unicode="&#xf034;" horiz-adv-x="1792" +d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 +t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 +q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44v383z" /> + <glyph glyph-name="text_width" unicode="&#xf035;" +d="M81 1407l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1t-103 1 +t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 +q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 +t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49 +t26 49q4 3 36 30t59.5 49t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5z" /> + <glyph glyph-name="align_left" unicode="&#xf036;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_center" unicode="&#xf037;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 +h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_right" unicode="&#xf038;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="align_justify" unicode="&#xf039;" horiz-adv-x="1792" +d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 +t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="list" unicode="&#xf03a;" horiz-adv-x="1792" +d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 +t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 +q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 +q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_left" unicode="&#xf03b;" horiz-adv-x="1792" +d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="indent_right" unicode="&#xf03c;" horiz-adv-x="1792" +d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 +t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 +q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="facetime_video" unicode="&#xf03d;" horiz-adv-x="1792" +d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 +q39 -17 39 -59z" /> + <glyph glyph-name="picture" unicode="&#xf03e;" horiz-adv-x="1920" +d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 +q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="pencil" unicode="&#xf040;" +d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 +q53 0 91 -38l235 -234q37 -39 37 -91z" /> + <glyph glyph-name="map_marker" unicode="&#xf041;" horiz-adv-x="1024" +d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> + <glyph glyph-name="adjust" unicode="&#xf042;" +d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="tint" unicode="&#xf043;" horiz-adv-x="1024" +d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 +q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" /> + <glyph glyph-name="edit" unicode="&#xf044;" horiz-adv-x="1792" +d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 +l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> + <glyph glyph-name="share" unicode="&#xf045;" horiz-adv-x="1664" +d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 +q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 +t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="check" unicode="&#xf046;" horiz-adv-x="1664" +d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 +q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 +q24 -24 24 -57t-24 -57z" /> + <glyph glyph-name="move" unicode="&#xf047;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 +t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="step_backward" unicode="&#xf048;" horiz-adv-x="1024" +d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19z" /> + <glyph glyph-name="fast_backward" unicode="&#xf049;" horiz-adv-x="1792" +d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 10 13 19l710 710 +q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="backward" unicode="&#xf04a;" horiz-adv-x="1664" +d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q4 10 13 19z" /> + <glyph glyph-name="play" unicode="&#xf04b;" horiz-adv-x="1408" +d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> + <glyph glyph-name="pause" unicode="&#xf04c;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="stop" unicode="&#xf04d;" +d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="forward" unicode="&#xf04e;" horiz-adv-x="1664" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="fast_forward" unicode="&#xf050;" horiz-adv-x="1792" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v710q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19l-710 -710 +q-19 -19 -32 -13t-13 32v710q-4 -10 -13 -19z" /> + <glyph glyph-name="step_forward" unicode="&#xf051;" horiz-adv-x="1024" +d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q9 -9 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-4 -10 -13 -19z" /> + <glyph glyph-name="eject" unicode="&#xf052;" horiz-adv-x="1538" +d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> + <glyph glyph-name="chevron_left" unicode="&#xf053;" horiz-adv-x="1280" +d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="chevron_right" unicode="&#xf054;" horiz-adv-x="1280" +d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" /> + <glyph glyph-name="plus_sign" unicode="&#xf055;" +d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 +t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="minus_sign" unicode="&#xf056;" +d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="remove_sign" unicode="&#xf057;" +d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 +q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_sign" unicode="&#xf058;" +d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="question_sign" unicode="&#xf059;" +d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 +q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="info_sign" unicode="&#xf05a;" +d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 +t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="screenshot" unicode="&#xf05b;" +d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 +q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 +q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" /> + <glyph glyph-name="remove_circle" unicode="&#xf05c;" +d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 +t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ok_circle" unicode="&#xf05d;" +d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 +t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ban_circle" unicode="&#xf05e;" +d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 +t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> + <glyph glyph-name="arrow_left" unicode="&#xf060;" +d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 +t32.5 -90.5z" /> + <glyph glyph-name="arrow_right" unicode="&#xf061;" +d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" /> + <glyph glyph-name="arrow_up" unicode="&#xf062;" horiz-adv-x="1664" +d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 +q37 -39 37 -91z" /> + <glyph glyph-name="arrow_down" unicode="&#xf063;" horiz-adv-x="1664" +d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> + <glyph glyph-name="share_alt" unicode="&#xf064;" horiz-adv-x="1792" +d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 +t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> + <glyph glyph-name="resize_full" unicode="&#xf065;" +d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 +q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> + <glyph glyph-name="resize_small" unicode="&#xf066;" +d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 +t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> + <glyph glyph-name="plus" unicode="&#xf067;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> + <glyph glyph-name="minus" unicode="&#xf068;" horiz-adv-x="1408" +d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> + <glyph glyph-name="asterisk" unicode="&#xf069;" horiz-adv-x="1664" +d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 +q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" /> + <glyph glyph-name="exclamation_sign" unicode="&#xf06a;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 +q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> + <glyph glyph-name="gift" unicode="&#xf06b;" +d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 +q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 +t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> + <glyph glyph-name="leaf" unicode="&#xf06c;" horiz-adv-x="1792" +d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 +q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-43 0 -63.5 17.5t-45.5 59.5q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 +t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" /> + <glyph glyph-name="fire" unicode="&#xf06d;" horiz-adv-x="1408" +d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 +q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> + <glyph glyph-name="eye_open" unicode="&#xf06e;" horiz-adv-x="1792" +d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 +t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> + <glyph glyph-name="eye_close" unicode="&#xf070;" horiz-adv-x="1792" +d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 +q-106 -189 -316 -567t-315 -566l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 +q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z +" /> + <glyph glyph-name="warning_sign" unicode="&#xf071;" horiz-adv-x="1792" +d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 +q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> + <glyph glyph-name="plane" unicode="&#xf072;" horiz-adv-x="1408" +d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 +q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> + <glyph glyph-name="calendar" unicode="&#xf073;" horiz-adv-x="1664" +d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z +M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 +q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 +h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="random" unicode="&#xf074;" horiz-adv-x="1792" +d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 +t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 +v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 +t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="comment" unicode="&#xf075;" horiz-adv-x="1792" +d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 +q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="magnet" unicode="&#xf076;" +d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 +q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> + <glyph glyph-name="chevron_up" unicode="&#xf077;" horiz-adv-x="1792" +d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="chevron_down" unicode="&#xf078;" horiz-adv-x="1792" +d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" /> + <glyph glyph-name="retweet" unicode="&#xf079;" horiz-adv-x="1920" +d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -10 7 -21 +zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z +" /> + <glyph glyph-name="shopping_cart" unicode="&#xf07a;" horiz-adv-x="1664" +d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 +t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="folder_close" unicode="&#xf07b;" horiz-adv-x="1664" +d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open" unicode="&#xf07c;" horiz-adv-x="1920" +d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 +t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> + <glyph glyph-name="resize_vertical" unicode="&#xf07d;" horiz-adv-x="768" +d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="resize_horizontal" unicode="&#xf07e;" horiz-adv-x="1792" +d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> + <glyph glyph-name="bar_chart" unicode="&#xf080;" horiz-adv-x="2048" +d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" /> + <glyph glyph-name="twitter_sign" unicode="&#xf081;" +d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 +q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 +t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="facebook_sign" unicode="&#xf082;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="camera_retro" unicode="&#xf083;" horiz-adv-x="1792" +d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 +t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 +q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="key" unicode="&#xf084;" horiz-adv-x="1792" +d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 +l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 +t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> + <glyph glyph-name="cogs" unicode="&#xf085;" horiz-adv-x="1920" +d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -11 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 +l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 +l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -8 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 +q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 +t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 +q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 +q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> + <glyph glyph-name="comments" unicode="&#xf086;" horiz-adv-x="1792" +d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 +q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 +q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> + <glyph glyph-name="thumbs_up_alt" unicode="&#xf087;" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 +t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 +q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 +q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" /> + <glyph glyph-name="thumbs_down_alt" unicode="&#xf088;" +d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 31 18 69q0 37 -17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 +t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z +M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 +h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -73 49 -163z" /> + <glyph glyph-name="star_half" unicode="&#xf089;" horiz-adv-x="896" +d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> + <glyph glyph-name="heart_empty" unicode="&#xf08a;" horiz-adv-x="1792" +d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 +q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 +q224 0 351 -124t127 -344z" /> + <glyph glyph-name="signout" unicode="&#xf08b;" horiz-adv-x="1664" +d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 +q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> + <glyph glyph-name="linkedin_sign" unicode="&#xf08c;" +d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 +q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="pushpin" unicode="&#xf08d;" horiz-adv-x="1152" +d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 +t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> + <glyph glyph-name="external_link" unicode="&#xf08e;" horiz-adv-x="1792" +d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 +q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> + <glyph glyph-name="signin" unicode="&#xf090;" +d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 +q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="trophy" unicode="&#xf091;" horiz-adv-x="1664" +d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 +t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 +q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> + <glyph glyph-name="github_sign" unicode="&#xf092;" +d="M519 336q4 6 -3 13q-9 7 -14 2q-4 -6 3 -13q9 -7 14 -2zM491 377q-5 7 -12 4q-6 -4 0 -12q7 -8 12 -5q6 4 0 13zM450 417q2 4 -5 8q-7 2 -8 -2q-3 -5 4 -8q8 -2 9 2zM471 394q2 1 1.5 4.5t-3.5 5.5q-6 7 -10 3t1 -11q6 -6 11 -2zM557 319q2 7 -9 11q-9 3 -13 -4 +q-2 -7 9 -11q9 -3 13 4zM599 316q0 8 -12 8q-10 0 -10 -8t11 -8t11 8zM638 323q-2 7 -13 5t-9 -9q2 -8 12 -6t10 10zM1280 640q0 212 -150 362t-362 150t-362 -150t-150 -362q0 -167 98 -300.5t252 -185.5q18 -3 26.5 5t8.5 20q0 52 -1 95q-6 -1 -15.5 -2.5t-35.5 -2t-48 4 +t-43.5 20t-29.5 41.5q-23 59 -57 74q-2 1 -4.5 3.5l-8 8t-7 9.5t4 7.5t19.5 3.5q6 0 15 -2t30 -15.5t33 -35.5q16 -28 37.5 -42t43.5 -14t38 3.5t30 9.5q7 47 33 69q-49 6 -86 18.5t-73 39t-55.5 76t-19.5 119.5q0 79 53 137q-24 62 5 136q19 6 54.5 -7.5t60.5 -29.5l26 -16 +q58 17 128 17t128 -17q11 7 28.5 18t55.5 26t57 9q29 -74 5 -136q53 -58 53 -137q0 -57 -14 -100.5t-35.5 -70t-53.5 -44.5t-62.5 -26t-68.5 -12q35 -31 35 -95q0 -40 -0.5 -89t-0.5 -51q0 -12 8.5 -20t26.5 -5q154 52 252 185.5t98 300.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="upload_alt" unicode="&#xf093;" horiz-adv-x="1664" +d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 +t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> + <glyph glyph-name="lemon" unicode="&#xf094;" +d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 +q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 +q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 +q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -13 2 -25t3.5 -16.5t7.5 -20.5t8 -20q16 -40 25 -118.5t9 -136.5z" /> + <glyph glyph-name="phone" unicode="&#xf095;" horiz-adv-x="1408" +d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -53 3.5t-57.5 12.5t-47 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-127 79 -264 216t-216 264q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47t-12.5 57.5t-3.5 53q0 92 51 186 +q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174q2 -1 19 -11.5t24 -14 +t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" /> + <glyph glyph-name="check_empty" unicode="&#xf096;" horiz-adv-x="1408" +d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="bookmark_empty" unicode="&#xf097;" horiz-adv-x="1280" +d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 +q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> + <glyph glyph-name="phone_sign" unicode="&#xf098;" +d="M1280 343q0 11 -2 16t-18 16.5t-40.5 25t-47.5 26.5t-45.5 25t-28.5 15q-5 3 -19 13t-25 15t-21 5q-15 0 -36.5 -20.5t-39.5 -45t-38.5 -45t-33.5 -20.5q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170 126.5t-127 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5 +t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5 +t320.5 -216.5q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z +" /> + <glyph glyph-name="twitter" unicode="&#xf099;" horiz-adv-x="1664" +d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 +q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> + <glyph glyph-name="facebook" unicode="&#xf09a;" horiz-adv-x="1024" +d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" /> + <glyph glyph-name="github" unicode="&#xf09b;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -40 7t-13 30q0 3 0.5 76.5t0.5 134.5q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 119 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24 +q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-85 13.5q-45 -113 -8 -204q-79 -87 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-39 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5 +t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -88.5t0.5 -54.5q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103zM291 305q3 7 -7 12 +q-10 3 -13 -2q-3 -7 7 -12q9 -6 13 2zM322 271q7 5 -2 16q-10 9 -16 3q-7 -5 2 -16q10 -10 16 -3zM352 226q9 7 0 19q-8 13 -17 6q-9 -5 0 -18t17 -7zM394 184q8 8 -4 19q-12 12 -20 3q-9 -8 4 -19q12 -12 20 -3zM451 159q3 11 -13 16q-15 4 -19 -7t13 -15q15 -6 19 6z +M514 154q0 13 -17 11q-16 0 -16 -11q0 -13 17 -11q16 0 16 11zM572 164q-2 11 -18 9q-16 -3 -14 -15t18 -8t14 14z" /> + <glyph glyph-name="unlock" unicode="&#xf09c;" horiz-adv-x="1664" +d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 +t316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="credit_card" unicode="&#xf09d;" horiz-adv-x="1920" +d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 +q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> + <glyph glyph-name="rss" unicode="&#xf09e;" horiz-adv-x="1408" +d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 +t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 +q187 -186 294 -425.5t120 -501.5z" /> + <glyph glyph-name="hdd" unicode="&#xf0a0;" +d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 +h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 +l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> + <glyph glyph-name="bullhorn" unicode="&#xf0a1;" horiz-adv-x="1792" +d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 +t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> + <glyph glyph-name="bell" unicode="&#xf0a2;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z +M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 +t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="certificate" unicode="&#xf0a3;" +d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 +l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 +l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> + <glyph glyph-name="hand_right" unicode="&#xf0a4;" horiz-adv-x="1792" +d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 +q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 +q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 +t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> + <glyph glyph-name="hand_left" unicode="&#xf0a5;" horiz-adv-x="1792" +d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-8 9 -12 14q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5 +t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45z +M1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67 +q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="hand_up" unicode="&#xf0a6;" +d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 +q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 +t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 +q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> + <glyph glyph-name="hand_down" unicode="&#xf0a7;" +d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 +t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 +q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 +q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" /> + <glyph glyph-name="circle_arrow_left" unicode="&#xf0a8;" +d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_right" unicode="&#xf0a9;" +d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_up" unicode="&#xf0aa;" +d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="circle_arrow_down" unicode="&#xf0ab;" +d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="globe" unicode="&#xf0ac;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 +q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 11t-9.5 10q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 +q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 +q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 +t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-4 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 +q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 +q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 +t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 +t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10.5t17 -19.5q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 +q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 +q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 +q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 +t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q8 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 +q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 +q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" /> + <glyph glyph-name="wrench" unicode="&#xf0ad;" horiz-adv-x="1664" +d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 +t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" /> + <glyph glyph-name="tasks" unicode="&#xf0ae;" horiz-adv-x="1792" +d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 +t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> + <glyph glyph-name="filter" unicode="&#xf0b0;" horiz-adv-x="1408" +d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" /> + <glyph glyph-name="briefcase" unicode="&#xf0b1;" horiz-adv-x="1792" +d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 +t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> + <glyph glyph-name="fullscreen" unicode="&#xf0b2;" +d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 +l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z +" /> + <glyph glyph-name="group" unicode="&#xf0c0;" horiz-adv-x="1920" +d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 +t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 +t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> + <glyph glyph-name="link" unicode="&#xf0c1;" horiz-adv-x="1664" +d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 +l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 +t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 +q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> + <glyph glyph-name="cloud" unicode="&#xf0c2;" horiz-adv-x="1920" +d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z +" /> + <glyph glyph-name="beaker" unicode="&#xf0c3;" horiz-adv-x="1664" +d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> + <glyph glyph-name="cut" unicode="&#xf0c4;" horiz-adv-x="1792" +d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 +q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 +q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 +q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 +q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> + <glyph glyph-name="copy" unicode="&#xf0c5;" horiz-adv-x="1792" +d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 +h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> + <glyph glyph-name="paper_clip" unicode="&#xf0c6;" horiz-adv-x="1408" +d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 +l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 +z" /> + <glyph glyph-name="save" unicode="&#xf0c7;" +d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 +h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="sign_blank" unicode="&#xf0c8;" +d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="reorder" unicode="&#xf0c9;" +d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 +t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ul" unicode="&#xf0ca;" horiz-adv-x="1792" +d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 +t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z +M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="ol" unicode="&#xf0cb;" horiz-adv-x="1792" +d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 +q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 +t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 121.5t0.5 121.5v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216 +q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> + <glyph glyph-name="strikethrough" unicode="&#xf0cc;" horiz-adv-x="1792" +d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 98 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 +l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -56 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 +l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> + <glyph glyph-name="underline" unicode="&#xf0cd;" +d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 +q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 +q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 +q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> + <glyph glyph-name="table" unicode="&#xf0ce;" horiz-adv-x="1664" +d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 +v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 +q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 +q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 +z" /> + <glyph glyph-name="magic" unicode="&#xf0d0;" horiz-adv-x="1664" +d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 +l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> + <glyph glyph-name="truck" unicode="&#xf0d1;" horiz-adv-x="1792" +d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 +t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 +t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> + <glyph glyph-name="pinterest" unicode="&#xf0d2;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 +q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 +q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="pinterest_sign" unicode="&#xf0d3;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 +t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 +t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> + <glyph glyph-name="google_plus_sign" unicode="&#xf0d4;" +d="M917 631q0 26 -6 64h-362v-132h217q-3 -24 -16.5 -50t-37.5 -53t-66.5 -44.5t-96.5 -17.5q-99 0 -169 71t-70 171t70 171t169 71q92 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585 +h109v110h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="google_plus" unicode="&#xf0d5;" horiz-adv-x="2304" +d="M1437 623q0 -208 -87 -370.5t-248 -254t-369 -91.5q-149 0 -285 58t-234 156t-156 234t-58 285t58 285t156 234t234 156t285 58q286 0 491 -192l-199 -191q-117 113 -292 113q-123 0 -227.5 -62t-165.5 -168.5t-61 -232.5t61 -232.5t165.5 -168.5t227.5 -62 +q83 0 152.5 23t114.5 57.5t78.5 78.5t49 83t21.5 74h-416v252h692q12 -63 12 -122zM2304 745v-210h-209v-209h-210v209h-209v210h209v209h210v-209h209z" /> + <glyph glyph-name="money" unicode="&#xf0d6;" horiz-adv-x="1920" +d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 +v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_down" unicode="&#xf0d7;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="caret_up" unicode="&#xf0d8;" horiz-adv-x="1024" +d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="caret_left" unicode="&#xf0d9;" horiz-adv-x="640" +d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> + <glyph glyph-name="caret_right" unicode="&#xf0da;" horiz-adv-x="640" +d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="columns" unicode="&#xf0db;" horiz-adv-x="1664" +d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> + <glyph glyph-name="sort" unicode="&#xf0dc;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="sort_down" unicode="&#xf0dd;" horiz-adv-x="1024" +d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> + <glyph glyph-name="sort_up" unicode="&#xf0de;" horiz-adv-x="1024" +d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> + <glyph glyph-name="envelope_alt" unicode="&#xf0e0;" horiz-adv-x="1792" +d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 +q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> + <glyph glyph-name="linkedin" unicode="&#xf0e1;" +d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 +q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> + <glyph glyph-name="undo" unicode="&#xf0e2;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> + <glyph glyph-name="legal" unicode="&#xf0e3;" horiz-adv-x="1792" +d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 +t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 +q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 +q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> + <glyph glyph-name="dashboard" unicode="&#xf0e4;" horiz-adv-x="1792" +d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 +t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 +t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 +q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="comment_alt" unicode="&#xf0e5;" horiz-adv-x="1792" +d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 +q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 +t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="comments_alt" unicode="&#xf0e6;" horiz-adv-x="1792" +d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 +t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 +t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 +q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> + <glyph glyph-name="bolt" unicode="&#xf0e7;" horiz-adv-x="896" +d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> + <glyph glyph-name="sitemap" unicode="&#xf0e8;" horiz-adv-x="1792" +d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 +q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="umbrella" unicode="&#xf0e9;" horiz-adv-x="1664" +d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 +q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 +q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> + <glyph glyph-name="paste" unicode="&#xf0ea;" horiz-adv-x="1792" +d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 +h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> + <glyph glyph-name="light_bulb" unicode="&#xf0eb;" horiz-adv-x="1024" +d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 +q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 +q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 +t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> + <glyph glyph-name="exchange" unicode="&#xf0ec;" horiz-adv-x="1792" +d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 +q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> + <glyph glyph-name="cloud_download" unicode="&#xf0ed;" horiz-adv-x="1920" +d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="cloud_upload" unicode="&#xf0ee;" horiz-adv-x="1920" +d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 +q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> + <glyph glyph-name="user_md" unicode="&#xf0f0;" horiz-adv-x="1408" +d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 +t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 +t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="stethoscope" unicode="&#xf0f1;" horiz-adv-x="1408" +d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 +t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 +t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="suitcase" unicode="&#xf0f2;" horiz-adv-x="1792" +d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 +t66 -158z" /> + <glyph glyph-name="bell_alt" unicode="&#xf0f3;" horiz-adv-x="1792" +d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 +t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> + <glyph glyph-name="coffee" unicode="&#xf0f4;" horiz-adv-x="1920" +d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 +t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="food" unicode="&#xf0f5;" horiz-adv-x="1408" +d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 +t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="file_text_alt" unicode="&#xf0f6;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 +q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" /> + <glyph glyph-name="building" unicode="&#xf0f7;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> + <glyph glyph-name="hospital" unicode="&#xf0f8;" horiz-adv-x="1408" +d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z +M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 +t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 +v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> + <glyph glyph-name="ambulance" unicode="&#xf0f9;" horiz-adv-x="1920" +d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 +q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="medkit" unicode="&#xf0fa;" horiz-adv-x="1792" +d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 +q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> + <glyph glyph-name="fighter_jet" unicode="&#xf0fb;" horiz-adv-x="1920" +d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 +q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q128 -28 200 -52t80 -34z" /> + <glyph glyph-name="beer" unicode="&#xf0fc;" horiz-adv-x="1664" +d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> + <glyph glyph-name="h_sign" unicode="&#xf0fd;" +d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="f0fe" unicode="&#xf0fe;" +d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="double_angle_left" unicode="&#xf100;" horiz-adv-x="1024" +d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_right" unicode="&#xf101;" horiz-adv-x="1024" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 +l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_up" unicode="&#xf102;" horiz-adv-x="1152" +d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 +q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="double_angle_down" unicode="&#xf103;" horiz-adv-x="1152" +d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 +t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_left" unicode="&#xf104;" horiz-adv-x="640" +d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="angle_right" unicode="&#xf105;" horiz-adv-x="640" +d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_up" unicode="&#xf106;" horiz-adv-x="1152" +d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> + <glyph glyph-name="angle_down" unicode="&#xf107;" horiz-adv-x="1152" +d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> + <glyph glyph-name="desktop" unicode="&#xf108;" horiz-adv-x="1920" +d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 +t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="laptop" unicode="&#xf109;" horiz-adv-x="1920" +d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z +M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> + <glyph glyph-name="tablet" unicode="&#xf10a;" horiz-adv-x="1152" +d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 +q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> + <glyph glyph-name="mobile_phone" unicode="&#xf10b;" horiz-adv-x="768" +d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 +q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> + <glyph glyph-name="circle_blank" unicode="&#xf10c;" +d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 +t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="quote_left" unicode="&#xf10d;" horiz-adv-x="1664" +d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z +M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" /> + <glyph glyph-name="quote_right" unicode="&#xf10e;" horiz-adv-x="1664" +d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 +v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> + <glyph glyph-name="spinner" unicode="&#xf110;" horiz-adv-x="1792" +d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z +M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 +q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" /> + <glyph glyph-name="circle" unicode="&#xf111;" +d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="reply" unicode="&#xf112;" horiz-adv-x="1792" +d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 +l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> + <glyph glyph-name="github_alt" unicode="&#xf113;" horiz-adv-x="1664" +d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 +q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 +t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 +q0 -87 -27 -168q136 -160 136 -398z" /> + <glyph glyph-name="folder_close_alt" unicode="&#xf114;" horiz-adv-x="1664" +d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 +q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> + <glyph glyph-name="folder_open_alt" unicode="&#xf115;" horiz-adv-x="1920" +d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 +v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z +" /> + <glyph glyph-name="expand_alt" unicode="&#xf116;" horiz-adv-x="1792" + /> + <glyph glyph-name="collapse_alt" unicode="&#xf117;" horiz-adv-x="1792" + /> + <glyph glyph-name="smile" unicode="&#xf118;" +d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 +t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="frown" unicode="&#xf119;" +d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 +t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="meh" unicode="&#xf11a;" +d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="1920" +d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 +t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> + <glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="1920" +d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 +h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 +h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 +q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 +h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="flag_alt" unicode="&#xf11d;" horiz-adv-x="1792" +d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 +h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 +q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="flag_checkered" unicode="&#xf11e;" horiz-adv-x="1792" +d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 +q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 +q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 +q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> + <glyph glyph-name="terminal" unicode="&#xf120;" horiz-adv-x="1664" +d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="code" unicode="&#xf121;" horiz-adv-x="1920" +d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 +l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> + <glyph glyph-name="reply_all" unicode="&#xf122;" horiz-adv-x="1792" +d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 +q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> + <glyph glyph-name="star_half_empty" unicode="&#xf123;" horiz-adv-x="1664" +d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 +l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> + <glyph glyph-name="location_arrow" unicode="&#xf124;" horiz-adv-x="1408" +d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> + <glyph glyph-name="crop" unicode="&#xf125;" horiz-adv-x="1664" +d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> + <glyph glyph-name="code_fork" unicode="&#xf126;" horiz-adv-x="1024" +d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 +q-2 -287 -226 -414q-67 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 +q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="unlink" unicode="&#xf127;" horiz-adv-x="1664" +d="M439 265l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 +q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 +l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 +t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="question" unicode="&#xf128;" horiz-adv-x="1024" +d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 +t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> + <glyph glyph-name="_279" unicode="&#xf129;" horiz-adv-x="640" +d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 +q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> + <glyph glyph-name="exclamation" unicode="&#xf12a;" horiz-adv-x="640" +d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> + <glyph glyph-name="superscript" unicode="&#xf12b;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1534 846v-206h-514l-3 27q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5 +t-65.5 -51.5t-30.5 -63h232v80h126z" /> + <glyph glyph-name="subscript" unicode="&#xf12c;" +d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3q-1 -3 -2.5 -6.5t-3.5 -8t-3 -6.5q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109z +M1536 -50v-206h-514l-4 27q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73 +h232v80h126z" /> + <glyph glyph-name="_283" unicode="&#xf12d;" horiz-adv-x="1920" +d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> + <glyph glyph-name="puzzle_piece" unicode="&#xf12e;" horiz-adv-x="1664" +d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 +t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 +q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 +q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> + <glyph glyph-name="microphone" unicode="&#xf130;" horiz-adv-x="1152" +d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 +t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> + <glyph glyph-name="microphone_off" unicode="&#xf131;" horiz-adv-x="1408" +d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 +q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 +t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> + <glyph glyph-name="shield" unicode="&#xf132;" horiz-adv-x="1280" +d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 +t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> + <glyph glyph-name="calendar_empty" unicode="&#xf133;" horiz-adv-x="1664" +d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="fire_extinguisher" unicode="&#xf134;" horiz-adv-x="1408" +d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 +q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 +q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> + <glyph glyph-name="rocket" unicode="&#xf135;" horiz-adv-x="1664" +d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 +q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> + <glyph glyph-name="maxcdn" unicode="&#xf136;" horiz-adv-x="1792" +d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> + <glyph glyph-name="chevron_sign_left" unicode="&#xf137;" +d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_right" unicode="&#xf138;" +d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_up" unicode="&#xf139;" +d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="chevron_sign_down" unicode="&#xf13a;" +d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 +t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="html5" unicode="&#xf13b;" horiz-adv-x="1408" +d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> + <glyph glyph-name="css3" unicode="&#xf13c;" horiz-adv-x="1792" +d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> + <glyph glyph-name="anchor" unicode="&#xf13d;" horiz-adv-x="1792" +d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 +q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 +t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" /> + <glyph glyph-name="unlock_alt" unicode="&#xf13e;" horiz-adv-x="1152" +d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 +v-320h736z" /> + <glyph glyph-name="bullseye" unicode="&#xf140;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 +t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 +q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="ellipsis_horizontal" unicode="&#xf141;" horiz-adv-x="1408" +d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="ellipsis_vertical" unicode="&#xf142;" horiz-adv-x="384" +d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 +q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> + <glyph glyph-name="_303" unicode="&#xf143;" +d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 233 -176.5 396.5t-396.5 176.5q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128 +q13 0 23 10t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="play_sign" unicode="&#xf144;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 +q16 -8 32 -8q17 0 32 9z" /> + <glyph glyph-name="ticket" unicode="&#xf145;" horiz-adv-x="1792" +d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 +t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> + <glyph glyph-name="minus_sign_alt" unicode="&#xf146;" +d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="check_minus" unicode="&#xf147;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 +t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="level_up" unicode="&#xf148;" horiz-adv-x="1024" +d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" /> + <glyph glyph-name="level_down" unicode="&#xf149;" horiz-adv-x="1024" +d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" /> + <glyph glyph-name="check_sign" unicode="&#xf14a;" +d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 +t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="edit_sign" unicode="&#xf14b;" +d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_312" unicode="&#xf14c;" +d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 +q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="share_sign" unicode="&#xf14d;" +d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q11 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 +t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="compass" unicode="&#xf14e;" +d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="collapse" unicode="&#xf150;" +d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="collapse_top" unicode="&#xf151;" +d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_317" unicode="&#xf152;" +d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="eur" unicode="&#xf153;" horiz-adv-x="1024" +d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 +t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 +l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> + <glyph glyph-name="gbp" unicode="&#xf154;" horiz-adv-x="1024" +d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 +q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" /> + <glyph glyph-name="usd" unicode="&#xf155;" horiz-adv-x="1024" +d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 +t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 +t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 +t53 -63.5t31.5 -76.5t13 -94z" /> + <glyph glyph-name="inr" unicode="&#xf156;" horiz-adv-x="898" +d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 +q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" /> + <glyph glyph-name="jpy" unicode="&#xf157;" horiz-adv-x="1027" +d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 +l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> + <glyph glyph-name="rub" unicode="&#xf158;" horiz-adv-x="1280" +d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 +q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" /> + <glyph glyph-name="krw" unicode="&#xf159;" horiz-adv-x="1792" +d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 +t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 +q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> + <glyph glyph-name="btc" unicode="&#xf15a;" horiz-adv-x="1280" +d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 +l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 +t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> + <glyph glyph-name="file" unicode="&#xf15b;" +d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" /> + <glyph glyph-name="file_text" unicode="&#xf15c;" +d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" /> + <glyph glyph-name="sort_by_alphabet" unicode="&#xf15d;" horiz-adv-x="1664" +d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 +v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 +l230 -662h70z" /> + <glyph glyph-name="_329" unicode="&#xf15e;" horiz-adv-x="1664" +d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 +v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 +v119h121z" /> + <glyph glyph-name="sort_by_attributes" unicode="&#xf160;" horiz-adv-x="1792" +d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 +q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_attributes_alt" unicode="&#xf161;" horiz-adv-x="1792" +d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 +q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> + <glyph glyph-name="sort_by_order" unicode="&#xf162;" +d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 +zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 +t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> + <glyph glyph-name="sort_by_order_alt" unicode="&#xf163;" +d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 +t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 +q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> + <glyph glyph-name="_334" unicode="&#xf164;" horiz-adv-x="1664" +d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 +q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 +t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" /> + <glyph glyph-name="_335" unicode="&#xf165;" horiz-adv-x="1664" +d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 +t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 +t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" /> + <glyph glyph-name="youtube_sign" unicode="&#xf166;" +d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 17 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 +q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 +q21 -29 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 +q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78q7 -23 23 -69l24 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38 +q-51 0 -78 -38q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5 +h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube" unicode="&#xf167;" +d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 +q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 +q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 +q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-38 -51 -106 -51q-67 0 -105 51 +q-28 38 -28 118v175q0 80 28 117q38 51 105 51q68 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> + <glyph glyph-name="xing" unicode="&#xf168;" horiz-adv-x="1408" +d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 +q25 45 64 45h241q22 0 31 -15z" /> + <glyph glyph-name="xing_sign" unicode="&#xf169;" +d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 +l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="youtube_play" unicode="&#xf16a;" horiz-adv-x="1792" +d="M711 408l484 250l-484 253v-503zM896 1270q168 0 324.5 -4.5t229.5 -9.5l73 -4q1 0 17 -1.5t23 -3t23.5 -4.5t28.5 -8t28 -13t31 -19.5t29 -26.5q6 -6 15.5 -18.5t29 -58.5t26.5 -101q8 -64 12.5 -136.5t5.5 -113.5v-40v-136q1 -145 -18 -290q-7 -55 -25 -99.5t-32 -61.5 +l-14 -17q-14 -15 -29 -26.5t-31 -19t-28 -12.5t-28.5 -8t-24 -4.5t-23 -3t-16.5 -1.5q-251 -19 -627 -19q-207 2 -359.5 6.5t-200.5 7.5l-49 4l-36 4q-36 5 -54.5 10t-51 21t-56.5 41q-6 6 -15.5 18.5t-29 58.5t-26.5 101q-8 64 -12.5 136.5t-5.5 113.5v40v136 +q-1 145 18 290q7 55 25 99.5t32 61.5l14 17q14 15 29 26.5t31 19.5t28 13t28.5 8t23.5 4.5t23 3t17 1.5q251 18 627 18z" /> + <glyph glyph-name="dropbox" unicode="&#xf16b;" horiz-adv-x="1792" +d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> + <glyph glyph-name="stackexchange" unicode="&#xf16c;" +d="M1289 -96h-1118v480h-160v-640h1438v640h-160v-480zM347 428l33 157l783 -165l-33 -156zM450 802l67 146l725 -339l-67 -145zM651 1158l102 123l614 -513l-102 -123zM1048 1536l477 -641l-128 -96l-477 641zM330 65v159h800v-159h-800z" /> + <glyph glyph-name="instagram" unicode="&#xf16d;" +d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1162 640q0 -164 -115 -279t-279 -115t-279 115t-115 279t115 279t279 115t279 -115t115 -279zM1270 1050q0 -38 -27 -65t-65 -27t-65 27t-27 65t27 65t65 27t65 -27t27 -65zM768 1270 +q-7 0 -76.5 0.5t-105.5 0t-96.5 -3t-103 -10t-71.5 -18.5q-50 -20 -88 -58t-58 -88q-11 -29 -18.5 -71.5t-10 -103t-3 -96.5t0 -105.5t0.5 -76.5t-0.5 -76.5t0 -105.5t3 -96.5t10 -103t18.5 -71.5q20 -50 58 -88t88 -58q29 -11 71.5 -18.5t103 -10t96.5 -3t105.5 0t76.5 0.5 +t76.5 -0.5t105.5 0t96.5 3t103 10t71.5 18.5q50 20 88 58t58 88q11 29 18.5 71.5t10 103t3 96.5t0 105.5t-0.5 76.5t0.5 76.5t0 105.5t-3 96.5t-10 103t-18.5 71.5q-20 50 -58 88t-88 58q-29 11 -71.5 18.5t-103 10t-96.5 3t-105.5 0t-76.5 -0.5zM1536 640q0 -229 -5 -317 +q-10 -208 -124 -322t-322 -124q-88 -5 -317 -5t-317 5q-208 10 -322 124t-124 322q-5 88 -5 317t5 317q10 208 124 322t322 124q88 5 317 5t317 -5q208 -10 322 -124t124 -322q5 -88 5 -317z" /> + <glyph glyph-name="flickr" unicode="&#xf16e;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 +t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> + <glyph glyph-name="adn" unicode="&#xf170;" +d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f171" unicode="&#xf171;" horiz-adv-x="1408" +d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 +t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 +t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 +t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" /> + <glyph glyph-name="bitbucket_sign" unicode="&#xf172;" +d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 +t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z +M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 +v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="tumblr" unicode="&#xf173;" horiz-adv-x="1024" +d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 +q78 2 134 29z" /> + <glyph glyph-name="tumblr_sign" unicode="&#xf174;" +d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="long_arrow_down" unicode="&#xf175;" horiz-adv-x="768" +d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> + <glyph glyph-name="long_arrow_up" unicode="&#xf176;" horiz-adv-x="768" +d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> + <glyph glyph-name="long_arrow_left" unicode="&#xf177;" horiz-adv-x="1792" +d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> + <glyph glyph-name="long_arrow_right" unicode="&#xf178;" horiz-adv-x="1792" +d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> + <glyph glyph-name="apple" unicode="&#xf179;" horiz-adv-x="1408" +d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q113 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 +q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> + <glyph glyph-name="windows" unicode="&#xf17a;" horiz-adv-x="1664" +d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> + <glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="1408" +d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 +t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 +h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> + <glyph glyph-name="linux" unicode="&#xf17c;" +d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-10 -11 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z +M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 +q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 +q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 +t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 +q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 +q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18q-2 -1 -4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 +q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 +q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-6 0 -8 -2t0 -4 +t5 -3q14 -4 18 -31q0 -3 8 2q2 2 2 3zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5 +t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43 +q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49 +t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54 +q110 143 124 195q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5 +t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5 +t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> + <glyph glyph-name="dribble" unicode="&#xf17d;" +d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 +t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 +q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -5 6.5 -17t7.5 -17q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 +t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="skype" unicode="&#xf17e;" +d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 +t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 +q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 +q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> + <glyph glyph-name="foursquare" unicode="&#xf180;" horiz-adv-x="1280" +d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z +M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 +l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" /> + <glyph glyph-name="trello" unicode="&#xf181;" +d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 +q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> + <glyph glyph-name="female" unicode="&#xf182;" horiz-adv-x="1280" +d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 +q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="male" unicode="&#xf183;" horiz-adv-x="1024" +d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z +M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="gittip" unicode="&#xf184;" +d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="sun" unicode="&#xf185;" horiz-adv-x="1792" +d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 +l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 +q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> + <glyph glyph-name="_366" unicode="&#xf186;" +d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 +t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" /> + <glyph glyph-name="archive" unicode="&#xf187;" horiz-adv-x="1792" +d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 +q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> + <glyph glyph-name="bug" unicode="&#xf188;" horiz-adv-x="1664" +d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 +q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 +t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> + <glyph glyph-name="vk" unicode="&#xf189;" horiz-adv-x="1920" +d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-40 -51 -55 -72t-30.5 -49.5t-12 -42t13 -34.5t32.5 -43t57 -53q4 -2 5 -4q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 +t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 +q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q16 19 38 30q53 26 239 24 +q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 +q39 5 64 -2.5t31 -16.5z" /> + <glyph glyph-name="weibo" unicode="&#xf18a;" horiz-adv-x="1792" +d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 +q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 +q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 +q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z +M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> + <glyph glyph-name="renren" unicode="&#xf18b;" +d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 +q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> + <glyph glyph-name="_372" unicode="&#xf18c;" horiz-adv-x="1408" +d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 +t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 +t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -4 1 -50t-1 -72q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 +t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> + <glyph glyph-name="stack_exchange" unicode="&#xf18d;" horiz-adv-x="1280" +d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z +" /> + <glyph glyph-name="_374" unicode="&#xf18e;" +d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="arrow_circle_alt_left" unicode="&#xf190;" +d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 +t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_376" unicode="&#xf191;" +d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z +M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="dot_circle_alt" unicode="&#xf192;" +d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 +t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_378" unicode="&#xf193;" horiz-adv-x="1664" +d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 +q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 17 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> + <glyph glyph-name="vimeo_square" unicode="&#xf194;" +d="M1292 898q10 216 -161 222q-231 8 -312 -261q44 19 82 19q85 0 74 -96q-4 -57 -74 -167t-105 -110q-43 0 -82 169q-13 54 -45 255q-30 189 -160 177q-59 -7 -164 -100l-81 -72l-81 -72l52 -67q76 52 87 52q57 0 107 -179q15 -55 45 -164.5t45 -164.5q68 -179 164 -179 +q157 0 383 294q220 283 226 444zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_380" unicode="&#xf195;" horiz-adv-x="1152" +d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 +q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="plus_square_o" unicode="&#xf196;" horiz-adv-x="1408" +d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 +q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_382" unicode="&#xf197;" horiz-adv-x="2176" +d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40 +t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 +q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" /> + <glyph glyph-name="_383" unicode="&#xf198;" horiz-adv-x="1664" +d="M1519 760q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72l-55 163l-153 -53q-29 -9 -50 -9 +q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102 +t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" /> + <glyph glyph-name="_384" unicode="&#xf199;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 +q-47 32 -142 92.5t-142 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 +t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" /> + <glyph glyph-name="_385" unicode="&#xf19a;" horiz-adv-x="1792" +d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15t-1.5 -18.5t9 -16.5 +t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 +t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 +t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 +t273 -182.5t331.5 -68z" /> + <glyph glyph-name="_386" unicode="&#xf19b;" horiz-adv-x="1792" +d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" /> + <glyph glyph-name="_387" unicode="&#xf19c;" horiz-adv-x="2048" +d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 +q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" /> + <glyph glyph-name="_388" unicode="&#xf19d;" horiz-adv-x="2304" +d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433 +q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" /> + <glyph glyph-name="_389" unicode="&#xf19e;" +d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -15 108 -15q44 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14v0 +q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" /> + <glyph glyph-name="uniF1A0" unicode="&#xf1a0;" +d="M768 750h725q12 -67 12 -128q0 -217 -91 -387.5t-259.5 -266.5t-386.5 -96q-157 0 -299 60.5t-245 163.5t-163.5 245t-60.5 299t60.5 299t163.5 245t245 163.5t299 60.5q300 0 515 -201l-209 -201q-123 119 -306 119q-129 0 -238.5 -65t-173.5 -176.5t-64 -243.5 +t64 -243.5t173.5 -176.5t238.5 -65q87 0 160 24t120 60t82 82t51.5 87t22.5 78h-436v264z" /> + <glyph glyph-name="f1a1" unicode="&#xf1a1;" horiz-adv-x="1792" +d="M1095 369q16 -16 0 -31q-62 -62 -199 -62t-199 62q-16 15 0 31q6 6 15 6t15 -6q48 -49 169 -49q120 0 169 49q6 6 15 6t15 -6zM788 550q0 -37 -26 -63t-63 -26t-63.5 26t-26.5 63q0 38 26.5 64t63.5 26t63 -26.5t26 -63.5zM1183 550q0 -37 -26.5 -63t-63.5 -26t-63 26 +t-26 63t26 63.5t63 26.5t63.5 -26t26.5 -64zM1434 670q0 49 -35 84t-85 35t-86 -36q-130 90 -311 96l63 283l200 -45q0 -37 26 -63t63 -26t63.5 26.5t26.5 63.5t-26.5 63.5t-63.5 26.5q-54 0 -80 -50l-221 49q-19 5 -25 -16l-69 -312q-180 -7 -309 -97q-35 37 -87 37 +q-50 0 -85 -35t-35 -84q0 -35 18.5 -64t49.5 -44q-6 -27 -6 -56q0 -142 140 -243t337 -101q198 0 338 101t140 243q0 32 -7 57q30 15 48 43.5t18 63.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191 +t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_392" unicode="&#xf1a2;" +d="M939 407q13 -13 0 -26q-53 -53 -171 -53t-171 53q-13 13 0 26q5 6 13 6t13 -6q42 -42 145 -42t145 42q5 6 13 6t13 -6zM676 563q0 -31 -23 -54t-54 -23t-54 23t-23 54q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1014 563q0 -31 -23 -54t-54 -23t-54 23t-23 54 +q0 32 22.5 54.5t54.5 22.5t54.5 -22.5t22.5 -54.5zM1229 666q0 42 -30 72t-73 30q-42 0 -73 -31q-113 78 -267 82l54 243l171 -39q1 -32 23.5 -54t53.5 -22q32 0 54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5q-48 0 -69 -43l-189 42q-17 5 -21 -13l-60 -268q-154 -6 -265 -83 +q-30 32 -74 32q-43 0 -73 -30t-30 -72q0 -30 16 -55t42 -38q-5 -25 -5 -48q0 -122 120 -208.5t289 -86.5q170 0 290 86.5t120 208.5q0 25 -6 49q25 13 40.5 37.5t15.5 54.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_393" unicode="&#xf1a3;" +d="M866 697l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 +v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 +t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="f1a4" unicode="&#xf1a4;" horiz-adv-x="1920" +d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 +v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" /> + <glyph glyph-name="_395" unicode="&#xf1a5;" +d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="_396" unicode="&#xf1a6;" horiz-adv-x="2048" +d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 +v-369h123z" /> + <glyph glyph-name="_397" unicode="&#xf1a7;" +d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 +v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 +q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_398" unicode="&#xf1a8;" horiz-adv-x="2038" +d="M1222 607q75 3 143.5 -20.5t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14 +q6 -5 28 -23.5t25.5 -22t19 -18t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24 +q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33 +q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5 +t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43 +q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5 +t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 +t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" /> + <glyph glyph-name="_399" unicode="&#xf1a9;" +d="M1167 -50q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 +q-29 -12 -78 -56q-26 -24 -12 -44q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 +q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 +t55.5 63q28 41 42.5 101t14.5 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44 +q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" /> + <glyph glyph-name="_400" unicode="&#xf1aa;" +d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160z +M729 1145l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 +t149.5 -87.5zM1536 78q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 +q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 +t135.5 51q85 0 145 -60.5t60 -145.5z" /> + <glyph glyph-name="f1ab" unicode="&#xf1ab;" +d="M654 458q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5 +q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 +q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z +M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 +q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q107 36 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 +q20 0 20 -21v-418z" /> + <glyph glyph-name="_402" unicode="&#xf1ac;" horiz-adv-x="1792" +d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 +l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 +t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 +q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 +q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" /> + <glyph glyph-name="_403" unicode="&#xf1ad;" +d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 +t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 +t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 +q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 +q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 +t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" /> + <glyph glyph-name="_404" unicode="&#xf1ae;" horiz-adv-x="1280" +d="M1188 988l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68t28 68q29 28 68.5 28t67.5 -28l228 -228h368l228 228q28 28 68 28t68 -28q28 -29 28 -68.5t-28 -67.5zM864 1152 +q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="uniF1B1" unicode="&#xf1b0;" horiz-adv-x="1664" +d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 +q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 +q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 +t100.5 134t141.5 55.5z" /> + <glyph glyph-name="_406" unicode="&#xf1b1;" horiz-adv-x="768" +d="M704 1008q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" /> + <glyph glyph-name="_407" unicode="&#xf1b2;" horiz-adv-x="1792" +d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z +" /> + <glyph glyph-name="_408" unicode="&#xf1b3;" horiz-adv-x="2304" +d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 +t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-4 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 +v-400l434 -186q36 -16 57 -48t21 -70z" /> + <glyph glyph-name="_409" unicode="&#xf1b4;" horiz-adv-x="2048" +d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 +q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 +q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" /> + <glyph glyph-name="_410" unicode="&#xf1b5;" +d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 +t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 +t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" /> + <glyph glyph-name="_411" unicode="&#xf1b6;" horiz-adv-x="1792" +d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 +q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 +q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" /> + <glyph glyph-name="_412" unicode="&#xf1b7;" +d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 +q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 +q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z +" /> + <glyph glyph-name="_413" unicode="&#xf1b8;" horiz-adv-x="1792" +d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188 +l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 +t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 +q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" /> + <glyph glyph-name="_414" unicode="&#xf1b9;" horiz-adv-x="2048" +d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 +q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 +l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_415" unicode="&#xf1ba;" horiz-adv-x="2048" +d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 +t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z +M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" /> + <glyph glyph-name="_416" unicode="&#xf1bb;" +d="M1504 64q0 -26 -19 -45t-45 -19h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 +q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45z" /> + <glyph glyph-name="_417" unicode="&#xf1bc;" +d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 +q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 +q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_418" unicode="&#xf1bd;" horiz-adv-x="1024" +d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" /> + <glyph glyph-name="_419" unicode="&#xf1be;" horiz-adv-x="2304" +d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 +q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 +q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 +l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 +q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236 +q0 -11 -8 -19t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786 +q-13 2 -22 11t-9 22v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" /> + <glyph glyph-name="uniF1C0" unicode="&#xf1c0;" +d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 +t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 +t-103 128v128q0 69 103 128t280 93.5t385 34.5z" /> + <glyph glyph-name="uniF1C1" unicode="&#xf1c1;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 +q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 +q-1 1 -1 2q-1 2 -1 3q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" /> + <glyph glyph-name="_422" unicode="&#xf1c2;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4q0 3 -0.5 6.5t-1.5 8t-1 6.5q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5 +t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300z" /> + <glyph glyph-name="_423" unicode="&#xf1c3;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107 +h-290v-107h68l189 -272l-194 -283h-68z" /> + <glyph glyph-name="_424" unicode="&#xf1c4;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" /> + <glyph glyph-name="_425" unicode="&#xf1c5;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" /> + <glyph glyph-name="_426" unicode="&#xf1c6;" +d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 +v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 +q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" /> + <glyph glyph-name="_427" unicode="&#xf1c7;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 +q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5t20 -44.5q20 -17 44 -17z" /> + <glyph glyph-name="_428" unicode="&#xf1c8;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" /> + <glyph glyph-name="_429" unicode="&#xf1c9;" +d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z +M480 768q8 11 21 12.5t24 -6.5l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 +l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" /> + <glyph glyph-name="_430" unicode="&#xf1ca;" +d="M1497 709v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 +q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" /> + <glyph glyph-name="_431" unicode="&#xf1cb;" horiz-adv-x="1792" +d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 +q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" /> + <glyph glyph-name="_432" unicode="&#xf1cc;" horiz-adv-x="2048" +d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 +q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55 +t121.5 -21q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97l93 -108q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z" /> + <glyph glyph-name="_433" unicode="&#xf1cd;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 +q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 +t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" /> + <glyph glyph-name="_434" unicode="&#xf1ce;" horiz-adv-x="1792" +d="M1760 640q0 -176 -68.5 -336t-184 -275.5t-275.5 -184t-336 -68.5t-336 68.5t-275.5 184t-184 275.5t-68.5 336q0 213 97 398.5t265 305.5t374 151v-228q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5 +t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v228q206 -31 374 -151t265 -305.5t97 -398.5z" /> + <glyph glyph-name="uniF1D0" unicode="&#xf1d0;" horiz-adv-x="1792" +d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 +t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 +t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 +q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" /> + <glyph glyph-name="uniF1D1" unicode="&#xf1d1;" horiz-adv-x="1792" +d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 +l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162 +q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 +q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 +t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF1D2" unicode="&#xf1d2;" +d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 +q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 +q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24zM924 1072 +q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_438" unicode="&#xf1d3;" horiz-adv-x="1792" +d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 +q0 -31 22.5 -51.5t58 -32t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47 +q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 +v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" /> + <glyph glyph-name="_439" unicode="&#xf1d4;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF1D5" unicode="&#xf1d5;" horiz-adv-x="1280" +d="M842 964q0 -80 -57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 +t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 +t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" /> + <glyph glyph-name="uniF1D6" unicode="&#xf1d6;" horiz-adv-x="1792" +d="M270 730q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5t3.5 -5t2 -3.5 +q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9t-98 20 +t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20q-18 -41 -54.5 -74.5 +t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" /> + <glyph glyph-name="uniF1D7" unicode="&#xf1d7;" horiz-adv-x="2048" +d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 +q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 +q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 +q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" /> + <glyph glyph-name="_443" unicode="&#xf1d8;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" /> + <glyph glyph-name="_444" unicode="&#xf1d9;" horiz-adv-x="1792" +d="M1764 1525q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 +l863 639l-478 -797z" /> + <glyph glyph-name="_445" unicode="&#xf1da;" +d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 +t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 +t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_446" unicode="&#xf1db;" +d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 +t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_447" unicode="&#xf1dc;" horiz-adv-x="1792" +d="M1682 -128q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5t45 -15 +t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18q-15 10 -45 12t-53 2 +t-41 14t-18 45q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 +q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 +q0 -26 -12 -48t-36 -22z" /> + <glyph glyph-name="_448" unicode="&#xf1dd;" horiz-adv-x="1280" +d="M1278 1347v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 +q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" /> + <glyph glyph-name="_449" unicode="&#xf1de;" +d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 +q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" /> + <glyph glyph-name="uniF1E0" unicode="&#xf1e0;" +d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 +t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86z" /> + <glyph glyph-name="_451" unicode="&#xf1e1;" +d="M1280 341q0 88 -62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5t62.5 -150.5 +t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_452" unicode="&#xf1e2;" horiz-adv-x="1792" +d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 +t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 +q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 +t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> + <glyph glyph-name="_453" unicode="&#xf1e3;" horiz-adv-x="1792" +d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 +l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" /> + <glyph glyph-name="_454" unicode="&#xf1e4;" horiz-adv-x="1792" +d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 +v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 +q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 +zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 +t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" /> + <glyph glyph-name="_455" unicode="&#xf1e5;" horiz-adv-x="1792" +d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z +M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_456" unicode="&#xf1e6;" horiz-adv-x="1792" +d="M1755 1083q37 -38 37 -90.5t-37 -90.5l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234 +l401 400q38 37 91 37t90 -37z" /> + <glyph glyph-name="_457" unicode="&#xf1e7;" horiz-adv-x="1792" +d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 +t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z +M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q4 -2 11.5 -7 +t10.5 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" /> + <glyph glyph-name="_458" unicode="&#xf1e8;" horiz-adv-x="1792" +d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" /> + <glyph glyph-name="_459" unicode="&#xf1e9;" +d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 +q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q71 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 +t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 +q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" /> + <glyph glyph-name="_460" unicode="&#xf1ea;" horiz-adv-x="2048" +d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 +t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" /> + <glyph glyph-name="_461" unicode="&#xf1eb;" horiz-adv-x="2048" +d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 +q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z +M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" /> + <glyph glyph-name="_462" unicode="&#xf1ec;" horiz-adv-x="1792" +d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 +t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 +t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 +h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_463" unicode="&#xf1ed;" +d="M1519 890q18 -84 -4 -204q-87 -444 -565 -444h-44q-25 0 -44 -16.5t-24 -42.5l-4 -19l-55 -346l-2 -15q-5 -26 -24.5 -42.5t-44.5 -16.5h-251q-21 0 -33 15t-9 36q9 56 26.5 168t26.5 168t27 167.5t27 167.5q5 37 43 37h131q133 -2 236 21q175 39 287 144q102 95 155 246 +q24 70 35 133q1 6 2.5 7.5t3.5 1t6 -3.5q79 -59 98 -162zM1347 1172q0 -107 -46 -236q-80 -233 -302 -315q-113 -40 -252 -42q0 -1 -90 -1l-90 1q-100 0 -118 -96q-2 -8 -85 -530q-1 -10 -12 -10h-295q-22 0 -36.5 16.5t-11.5 38.5l232 1471q5 29 27.5 48t51.5 19h598 +q34 0 97.5 -13t111.5 -32q107 -41 163.5 -123t56.5 -196z" /> + <glyph glyph-name="_464" unicode="&#xf1ee;" horiz-adv-x="1792" +d="M441 864q33 0 52 -26q266 -364 362 -774h-446q-127 441 -367 749q-12 16 -3 33.5t29 17.5h373zM1000 507q-49 -199 -125 -393q-79 310 -256 594q40 221 44 449q211 -340 337 -650zM1099 1216q235 -324 384.5 -698.5t184.5 -773.5h-451q-41 665 -553 1472h435zM1792 640 +q0 -424 -101 -812q-67 560 -359 1083q-25 301 -106 584q-4 16 5.5 28.5t25.5 12.5h359q21 0 38.5 -13t22.5 -33q115 -409 115 -850z" /> + <glyph glyph-name="uniF1F0" unicode="&#xf1f0;" horiz-adv-x="2304" +d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 +q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 +q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_466" unicode="&#xf1f1;" horiz-adv-x="2304" +d="M1119 1195q-128 85 -281 85q-103 0 -197.5 -40.5t-162.5 -108.5t-108.5 -162t-40.5 -197q0 -104 40.5 -198t108.5 -162t162 -108.5t198 -40.5q153 0 281 85q-131 107 -178 265.5t0.5 316.5t177.5 265zM1152 1171q-126 -99 -172 -249.5t-0.5 -300.5t172.5 -249 +q127 99 172.5 249t-0.5 300.5t-172 249.5zM1185 1195q130 -107 177.5 -265.5t0.5 -317t-178 -264.5q128 -85 281 -85q104 0 198 40.5t162 108.5t108.5 162t40.5 198q0 103 -40.5 197t-108.5 162t-162.5 108.5t-197.5 40.5q-153 0 -281 -85zM1926 473h7v3h-17v-3h7v-17h3v17z +M1955 456h4v20h-5l-6 -13l-6 13h-5v-20h3v15l6 -13h4l5 13v-15zM1947 16v-2h-2h-3v3h3h2v-1zM1947 7h3l-4 5h2l1 1q1 1 1 3t-1 3l-1 1h-3h-6v-13h3v5h1zM685 75q0 19 11 31t30 12q18 0 29 -12.5t11 -30.5q0 -19 -11 -31t-29 -12q-19 0 -30 12t-11 31zM1158 119q30 0 35 -32 +h-70q5 32 35 32zM1514 75q0 19 11 31t29 12t29.5 -12.5t11.5 -30.5q0 -19 -11 -31t-30 -12q-18 0 -29 12t-11 31zM1786 75q0 18 11.5 30.5t29.5 12.5t29.5 -12.5t11.5 -30.5q0 -19 -11.5 -31t-29.5 -12t-29.5 12.5t-11.5 30.5zM1944 3q-2 0 -4 1q-1 0 -3 2t-2 3q-1 2 -1 4 +q0 3 1 4q0 2 2 4l1 1q2 0 2 1q2 1 4 1q3 0 4 -1l4 -2l2 -4v-1q1 -2 1 -3l-1 -1v-3t-1 -1l-1 -2q-2 -2 -4 -2q-1 -1 -4 -1zM599 7h30v85q0 24 -14.5 38.5t-39.5 15.5q-32 0 -47 -24q-14 24 -45 24q-24 0 -39 -20v16h-30v-135h30v75q0 36 33 36q30 0 30 -36v-75h29v75 +q0 36 33 36q30 0 30 -36v-75zM765 7h29v68v67h-29v-16q-17 20 -43 20q-29 0 -48 -20t-19 -51t19 -51t48 -20q28 0 43 20v-17zM943 48q0 34 -47 40l-14 2q-23 4 -23 14q0 15 25 15q23 0 43 -11l12 24q-22 14 -55 14q-26 0 -41 -12t-15 -32q0 -33 47 -39l13 -2q24 -4 24 -14 +q0 -17 -31 -17q-25 0 -45 14l-13 -23q25 -17 58 -17q29 0 45.5 12t16.5 32zM1073 14l-8 25q-13 -7 -26 -7q-19 0 -19 22v61h48v27h-48v41h-30v-41h-28v-27h28v-61q0 -50 47 -50q21 0 36 10zM1159 146q-29 0 -48 -20t-19 -51q0 -32 19.5 -51.5t49.5 -19.5q33 0 55 19l-14 22 +q-18 -15 -39 -15q-34 0 -41 33h101v12q0 32 -18 51.5t-46 19.5zM1318 146q-23 0 -35 -20v16h-30v-135h30v76q0 35 29 35q10 0 18 -4l9 28q-9 4 -21 4zM1348 75q0 -31 19.5 -51t52.5 -20q29 0 48 16l-14 24q-18 -13 -35 -12q-18 0 -29.5 12t-11.5 31t11.5 31t29.5 12 +q19 0 35 -12l14 24q-20 16 -48 16q-33 0 -52.5 -20t-19.5 -51zM1593 7h30v68v67h-30v-16q-15 20 -42 20q-29 0 -48.5 -20t-19.5 -51t19.5 -51t48.5 -20q28 0 42 20v-17zM1726 146q-23 0 -35 -20v16h-29v-135h29v76q0 35 29 35q10 0 18 -4l9 28q-8 4 -21 4zM1866 7h29v68v122 +h-29v-71q-15 20 -43 20t-47.5 -20.5t-19.5 -50.5t19.5 -50.5t47.5 -20.5q29 0 43 20v-17zM1944 27l-2 -1h-3q-2 -1 -4 -3q-3 -1 -3 -4q-1 -2 -1 -6q0 -3 1 -5q0 -2 3 -4q2 -2 4 -3t5 -1q4 0 6 1q0 1 2 2l2 1q1 1 3 4q1 2 1 5q0 4 -1 6q-1 1 -3 4q0 1 -2 2l-2 1q-1 0 -3 0.5 +t-3 0.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_467" unicode="&#xf1f2;" horiz-adv-x="2304" +d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 +q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 +v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 +q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 +t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" /> + <glyph glyph-name="f1f3" unicode="&#xf1f3;" horiz-adv-x="2304" +d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z +M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 +l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 +v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 +q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 +q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 +t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 +h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 +t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" /> + <glyph glyph-name="_469" unicode="&#xf1f4;" horiz-adv-x="2304" +d="M745 630q0 -37 -25.5 -61.5t-62.5 -24.5q-29 0 -46.5 16t-17.5 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM1530 779q0 -42 -22 -57t-66 -15l-32 -1l17 107q2 11 13 11h18q22 0 35 -2t25 -12.5t12 -30.5zM1881 630q0 -36 -25.5 -61t-61.5 -25q-29 0 -47 16 +t-18 44q0 37 25 62.5t62 25.5q28 0 46.5 -16.5t18.5 -45.5zM513 801q0 59 -38.5 85.5t-100.5 26.5h-160q-19 0 -21 -19l-65 -408q-1 -6 3 -11t10 -5h76q20 0 22 19l18 110q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM822 489l41 261q1 6 -3 11t-10 5h-76 +q-14 0 -17 -33q-27 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q28 0 58 12t48 32q-4 -12 -4 -21q0 -16 13 -16h69q19 0 22 19zM1269 752q0 5 -4 9.5t-9 4.5h-77q-11 0 -18 -10l-106 -156l-44 150q-5 16 -22 16h-75q-5 0 -9 -4.5t-4 -9.5q0 -2 19.5 -59 +t42 -123t23.5 -70q-82 -112 -82 -120q0 -13 13 -13h77q11 0 18 10l255 368q2 2 2 7zM1649 801q0 59 -38.5 85.5t-100.5 26.5h-159q-20 0 -22 -19l-65 -408q-1 -6 3 -11t10 -5h82q12 0 16 13l18 116q1 8 7 13t15 6.5t17 1.5t19 -1t14 -1q86 0 135 48.5t49 134.5zM1958 489 +l41 261q1 6 -3 11t-10 5h-76q-14 0 -17 -33q-26 40 -95 40q-72 0 -122.5 -54t-50.5 -127q0 -59 34.5 -94t92.5 -35q29 0 59 12t47 32q0 -1 -2 -9t-2 -12q0 -16 13 -16h69q19 0 22 19zM2176 898v1q0 14 -13 14h-74q-11 0 -13 -11l-65 -416l-1 -2q0 -5 4 -9.5t10 -4.5h66 +q19 0 21 19zM392 764q-5 -35 -26 -46t-60 -11l-33 -1l17 107q2 11 13 11h19q40 0 58 -11.5t12 -48.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_470" unicode="&#xf1f5;" horiz-adv-x="2304" +d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 +q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 +q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 +q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 +q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_471" unicode="&#xf1f6;" horiz-adv-x="2048" +d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 +l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 +l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_472" unicode="&#xf1f7;" horiz-adv-x="2048" +d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 +q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 +q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" /> + <glyph glyph-name="_473" unicode="&#xf1f8;" horiz-adv-x="1408" +d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167 +q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_474" unicode="&#xf1f9;" +d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 +t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 +t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_475" unicode="&#xf1fa;" +d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 +q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 +t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 +t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" /> + <glyph glyph-name="_476" unicode="&#xf1fb;" horiz-adv-x="1792" +d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 +t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" /> + <glyph glyph-name="f1fc" unicode="&#xf1fc;" horiz-adv-x="1792" +d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 +t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" /> + <glyph glyph-name="_478" unicode="&#xf1fd;" horiz-adv-x="1792" +d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11q24 0 44 -7t31 -15t33 -27q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5 +t47 37.5q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-24 0 -44 7t-31 15t-33 27q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38 +t-58 27t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448 +h256v448h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5 +q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" /> + <glyph glyph-name="_479" unicode="&#xf1fe;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" /> + <glyph glyph-name="_480" unicode="&#xf200;" horiz-adv-x="1792" +d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_481" unicode="&#xf201;" horiz-adv-x="2048" +d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 +t9 -23z" /> + <glyph glyph-name="_482" unicode="&#xf202;" horiz-adv-x="1792" +d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 +q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 +t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 +q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" /> + <glyph glyph-name="_483" unicode="&#xf203;" +d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 +q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 +q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 +q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_484" unicode="&#xf204;" horiz-adv-x="2048" +d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 +t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 +t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" /> + <glyph glyph-name="_485" unicode="&#xf205;" horiz-adv-x="2048" +d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 +t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" /> + <glyph glyph-name="_486" unicode="&#xf206;" horiz-adv-x="2304" +d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 +q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 +q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 +q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" /> + <glyph glyph-name="_487" unicode="&#xf207;" +d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 +h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 +t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" /> + <glyph glyph-name="_488" unicode="&#xf208;" horiz-adv-x="2048" +d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 +q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 +q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" /> + <glyph glyph-name="_489" unicode="&#xf209;" horiz-adv-x="1280" +d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q17 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 +t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 +t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 +q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 +q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 +t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" /> + <glyph glyph-name="_490" unicode="&#xf20a;" horiz-adv-x="2048" +d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 +q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 +t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 +t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" /> + <glyph glyph-name="_491" unicode="&#xf20b;" +d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 +t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> + <glyph glyph-name="_492" unicode="&#xf20c;" +d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 +q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 +q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" /> + <glyph glyph-name="_493" unicode="&#xf20d;" +d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" /> + <glyph glyph-name="_494" unicode="&#xf20e;" horiz-adv-x="2048" +d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 +q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 +q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360l15 -6l188 199v347l-187 194q-13 -8 -29 -10zM986 1438 +h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13zM552 226h402l64 66 +l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224l213 -225zM1023 946 +l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196l-48 -227l130 227h-82 +zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" /> + <glyph glyph-name="f210" unicode="&#xf210;" +d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" /> + <glyph glyph-name="_496" unicode="&#xf211;" +d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 +q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" /> + <glyph glyph-name="f212" unicode="&#xf212;" horiz-adv-x="2048" +d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 +q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 +q209 0 374 -102q172 107 374 102z" /> + <glyph glyph-name="_498" unicode="&#xf213;" horiz-adv-x="2048" +d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 +q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 +q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" /> + <glyph glyph-name="_499" unicode="&#xf214;" +d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 +l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 +v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z +M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 +v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 +h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 +t-43 -34t-16.5 -53.5z" /> + <glyph glyph-name="_500" unicode="&#xf215;" horiz-adv-x="2048" +d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 +q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" /> + <glyph glyph-name="_501" unicode="&#xf216;" horiz-adv-x="2048" +d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126t-103.5 132.5t-108.5 126.5t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 +t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 +t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 +q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" /> + <glyph glyph-name="_502" unicode="&#xf217;" horiz-adv-x="1664" +d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_503" unicode="&#xf218;" horiz-adv-x="1664" +d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 +t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 +q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> + <glyph glyph-name="_504" unicode="&#xf219;" horiz-adv-x="2048" +d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 +l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" /> + <glyph glyph-name="_505" unicode="&#xf21a;" horiz-adv-x="2048" +d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 +q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 +v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 +q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" /> + <glyph glyph-name="_506" unicode="&#xf21b;" +d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 +t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 +q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 +t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" /> + <glyph glyph-name="_507" unicode="&#xf21c;" horiz-adv-x="2304" +d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 +t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 +l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 +t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" /> + <glyph glyph-name="_508" unicode="&#xf21d;" +d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 +q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 +q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 +t158.5 -65.5t65.5 -158.5z" /> + <glyph glyph-name="_509" unicode="&#xf21e;" horiz-adv-x="1792" +d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 +q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124 +t127 -344z" /> + <glyph glyph-name="venus" unicode="&#xf221;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 +q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" /> + <glyph glyph-name="_511" unicode="&#xf222;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-382 -383q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5 +q203 0 359 -126l382 382h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_512" unicode="&#xf223;" horiz-adv-x="1280" +d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 +t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_513" unicode="&#xf224;" +d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_514" unicode="&#xf225;" horiz-adv-x="1792" +d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 +q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 +t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_515" unicode="&#xf226;" horiz-adv-x="1792" +d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 +t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 +q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 +q0 -226 -154 -391q103 -57 218 -57z" /> + <glyph glyph-name="_516" unicode="&#xf227;" horiz-adv-x="1920" +d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 +q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 +t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 +q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -28 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" /> + <glyph glyph-name="_517" unicode="&#xf228;" horiz-adv-x="2048" +d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 +t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 +t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 +t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" /> + <glyph glyph-name="_518" unicode="&#xf229;" +d="M1472 1408q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-213 -214l140 -140q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-140 141l-78 -79q126 -156 126 -359q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5 +t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123t223.5 45.5q203 0 359 -126l78 78l-172 172q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l172 -172l213 213h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM576 0q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 +t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_519" unicode="&#xf22a;" horiz-adv-x="1280" +d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 +t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 +t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_520" unicode="&#xf22b;" horiz-adv-x="2048" +d="M1901 621q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-132q-24 -217 -187.5 -364.5t-384.5 -147.5q-167 0 -306 87t-212 236t-54 319q15 133 88 245.5 +t188 182t249 80.5q155 12 292 -52.5t224 -186t103 -271.5h132v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM576 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5 +t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_521" unicode="&#xf22c;" horiz-adv-x="1280" +d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 +t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> + <glyph glyph-name="_522" unicode="&#xf22d;" horiz-adv-x="1280" +d="M1024 576q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1152 576q0 -117 -45.5 -223.5t-123 -184t-184 -123t-223.5 -45.5t-223.5 45.5t-184 123t-123 184t-45.5 223.5t45.5 223.5t123 184t184 123 +t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5z" /> + <glyph glyph-name="_523" unicode="&#xf22e;" horiz-adv-x="1792" + /> + <glyph glyph-name="_524" unicode="&#xf22f;" horiz-adv-x="1792" + /> + <glyph glyph-name="_525" unicode="&#xf230;" +d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" /> + <glyph glyph-name="_526" unicode="&#xf231;" horiz-adv-x="1280" +d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 +l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 +q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" /> + <glyph glyph-name="_527" unicode="&#xf232;" +d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 +t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 +l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" /> + <glyph glyph-name="_528" unicode="&#xf233;" horiz-adv-x="1792" +d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 +q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" /> + <glyph glyph-name="_529" unicode="&#xf234;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 +t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 +t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" /> + <glyph glyph-name="_530" unicode="&#xf235;" horiz-adv-x="2048" +d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 +q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 +t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" /> + <glyph glyph-name="_531" unicode="&#xf236;" horiz-adv-x="2048" +d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 +q-26 0 -45 -19t-19 -45v-384h1152z" /> + <glyph glyph-name="_532" unicode="&#xf237;" +d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" /> + <glyph glyph-name="_533" unicode="&#xf238;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 +t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" /> + <glyph glyph-name="_534" unicode="&#xf239;" +d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 +t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" /> + <glyph glyph-name="_535" unicode="&#xf23a;" horiz-adv-x="1792" +d="M597 1115v-1173q0 -25 -12.5 -42.5t-36.5 -17.5q-17 0 -33 8l-465 233q-21 10 -35.5 33.5t-14.5 46.5v1140q0 20 10 34t29 14q14 0 44 -15l511 -256q3 -3 3 -5zM661 1014l534 -866l-534 266v600zM1792 996v-1054q0 -25 -14 -40.5t-38 -15.5t-47 13l-441 220zM1789 1116 +q0 -3 -256.5 -419.5t-300.5 -487.5l-390 634l324 527q17 28 52 28q14 0 26 -6l541 -270q4 -2 4 -6z" /> + <glyph glyph-name="_536" unicode="&#xf23b;" +d="M809 532l266 499h-112l-157 -312q-24 -48 -44 -92l-42 92l-155 312h-120l263 -493v-324h101v318zM1536 1408v-1536h-1536v1536h1536z" /> + <glyph glyph-name="_537" unicode="&#xf23c;" horiz-adv-x="2296" +d="M478 -139q-8 -16 -27 -34.5t-37 -25.5q-25 -9 -51.5 3.5t-28.5 31.5q-1 22 40 55t68 38q23 4 34 -21.5t2 -46.5zM1819 -139q7 -16 26 -34.5t38 -25.5q25 -9 51.5 3.5t27.5 31.5q2 22 -39.5 55t-68.5 38q-22 4 -33 -21.5t-2 -46.5zM1867 -30q13 -27 56.5 -59.5t77.5 -41.5 +q45 -13 82 4.5t37 50.5q0 46 -67.5 100.5t-115.5 59.5q-40 5 -63.5 -37.5t-6.5 -76.5zM428 -30q-13 -27 -56 -59.5t-77 -41.5q-45 -13 -82 4.5t-37 50.5q0 46 67.5 100.5t115.5 59.5q40 5 63 -37.5t6 -76.5zM1158 1094h1q-41 0 -76 -15q27 -8 44 -30.5t17 -49.5 +q0 -35 -27 -60t-65 -25q-52 0 -80 43q-5 -23 -5 -42q0 -74 56 -126.5t135 -52.5q80 0 136 52.5t56 126.5t-56 126.5t-136 52.5zM1462 1312q-99 109 -220.5 131.5t-245.5 -44.5q27 60 82.5 96.5t118 39.5t121.5 -17t99.5 -74.5t44.5 -131.5zM2212 73q8 -11 -11 -42 +q7 -23 7 -40q1 -56 -44.5 -112.5t-109.5 -91.5t-118 -37q-48 -2 -92 21.5t-66 65.5q-687 -25 -1259 0q-23 -41 -66.5 -65t-92.5 -22q-86 3 -179.5 80.5t-92.5 160.5q2 22 7 40q-19 31 -11 42q6 10 31 1q14 22 41 51q-7 29 2 38q11 10 39 -4q29 20 59 34q0 29 13 37 +q23 12 51 -16q35 5 61 -2q18 -4 38 -19v73q-11 0 -18 2q-53 10 -97 44.5t-55 87.5q-9 38 0 81q15 62 93 95q2 17 19 35.5t36 23.5t33 -7.5t19 -30.5h13q46 -5 60 -23q3 -3 5 -7q10 1 30.5 3.5t30.5 3.5q-15 11 -30 17q-23 40 -91 43q0 6 1 10q-62 2 -118.5 18.5t-84.5 47.5 +q-32 36 -42.5 92t-2.5 112q16 126 90 179q23 16 52 4.5t32 -40.5q0 -1 1.5 -14t2.5 -21t3 -20t5.5 -19t8.5 -10q27 -14 76 -12q48 46 98 74q-40 4 -162 -14l47 46q61 58 163 111q145 73 282 86q-20 8 -41 15.5t-47 14t-42.5 10.5t-47.5 11t-43 10q595 126 904 -139 +q98 -84 158 -222q85 -10 121 9h1q5 3 8.5 10t5.5 19t3 19.5t3 21.5l1 14q3 28 32 40t52 -5q73 -52 91 -178q7 -57 -3.5 -113t-42.5 -91q-28 -32 -83.5 -48.5t-115.5 -18.5v-10q-71 -2 -95 -43q-14 -5 -31 -17q11 -1 32 -3.5t30 -3.5q1 5 5 8q16 18 60 23h13q5 18 19 30t33 8 +t36 -23t19 -36q79 -32 93 -95q9 -40 1 -81q-12 -53 -56 -88t-97 -44q-10 -2 -17 -2q0 -49 -1 -73q20 15 38 19q26 7 61 2q28 28 51 16q14 -9 14 -37q33 -16 59 -34q27 13 38 4q10 -10 2 -38q28 -30 41 -51q23 8 31 -1zM1937 1025q0 -29 -9 -54q82 -32 112 -132 +q4 37 -9.5 98.5t-41.5 90.5q-20 19 -36 17t-16 -20zM1859 925q35 -42 47.5 -108.5t-0.5 -124.5q67 13 97 45q13 14 18 28q-3 64 -31 114.5t-79 66.5q-15 -15 -52 -21zM1822 921q-30 0 -44 1q42 -115 53 -239q21 0 43 3q16 68 1 135t-53 100zM258 839q30 100 112 132 +q-9 25 -9 54q0 18 -16.5 20t-35.5 -17q-28 -29 -41.5 -90.5t-9.5 -98.5zM294 737q29 -31 97 -45q-13 58 -0.5 124.5t47.5 108.5v0q-37 6 -52 21q-51 -16 -78.5 -66t-31.5 -115q9 -17 18 -28zM471 683q14 124 73 235q-19 -4 -55 -18l-45 -19v1q-46 -89 -20 -196q25 -3 47 -3z +M1434 644q8 -38 16.5 -108.5t11.5 -89.5q3 -18 9.5 -21.5t23.5 4.5q40 20 62 85.5t23 125.5q-24 2 -146 4zM1152 1285q-116 0 -199 -82.5t-83 -198.5q0 -117 83 -199.5t199 -82.5t199 82.5t83 199.5q0 116 -83 198.5t-199 82.5zM1380 646q-105 2 -211 0v1q-1 -27 2.5 -86 +t13.5 -66q29 -14 93.5 -14.5t95.5 10.5q9 3 11 39t-0.5 69.5t-4.5 46.5zM1112 447q8 4 9.5 48t-0.5 88t-4 63v1q-212 -3 -214 -3q-4 -20 -7 -62t0 -83t14 -46q34 -15 101 -16t101 10zM718 636q-16 -59 4.5 -118.5t77.5 -84.5q15 -8 24 -5t12 21q3 16 8 90t10 103 +q-69 -2 -136 -6zM591 510q3 -23 -34 -36q132 -141 271.5 -240t305.5 -154q172 49 310.5 146t293.5 250q-33 13 -30 34q0 2 0.5 3.5t1.5 3t1 2.5v1v-1q-17 2 -50 5.5t-48 4.5q-26 -90 -82 -132q-51 -38 -82 1q-5 6 -9 14q-7 13 -17 62q-2 -5 -5 -9t-7.5 -7t-8 -5.5t-9.5 -4 +l-10 -2.5t-12 -2l-12 -1.5t-13.5 -1t-13.5 -0.5q-106 -9 -163 11q-4 -17 -10 -26.5t-21 -15t-23 -7t-36 -3.5q-6 -1 -9 -1q-179 -17 -203 40q-2 -63 -56 -54q-47 8 -91 54q-12 13 -20 26q-17 29 -26 65q-58 -6 -87 -10q1 -2 4 -10zM507 -118q3 14 3 30q-17 71 -51 130 +t-73 70q-41 12 -101.5 -14.5t-104.5 -80t-39 -107.5q35 -53 100 -93t119 -42q51 -2 94 28t53 79zM510 53q23 -63 27 -119q195 113 392 174q-98 52 -180.5 120t-179.5 165q-6 -4 -29 -13q0 -1 -1 -4t-1 -5q31 -18 22 -37q-12 -23 -56 -34q-10 -13 -29 -24h-1q-2 -83 1 -150 +q19 -34 35 -73zM579 -113q532 -21 1145 0q-254 147 -428 196q-76 -35 -156 -57q-8 -3 -16 0q-65 21 -129 49q-208 -60 -416 -188h-1v-1q1 0 1 1zM1763 -67q4 54 28 120q14 38 33 71l-1 -1q3 77 3 153q-15 8 -30 25q-42 9 -56 33q-9 20 22 38q-2 4 -2 9q-16 4 -28 12 +q-204 -190 -383 -284q198 -59 414 -176zM2155 -90q5 54 -39 107.5t-104 80t-102 14.5q-38 -11 -72.5 -70.5t-51.5 -129.5q0 -16 3 -30q10 -49 53 -79t94 -28q54 2 119 42t100 93z" /> + <glyph glyph-name="_538" unicode="&#xf23d;" horiz-adv-x="2304" +d="M1524 -25q0 -68 -48 -116t-116 -48t-116.5 48t-48.5 116t48.5 116.5t116.5 48.5t116 -48.5t48 -116.5zM775 -25q0 -68 -48.5 -116t-116.5 -48t-116 48t-48 116t48 116.5t116 48.5t116.5 -48.5t48.5 -116.5zM0 1469q57 -60 110.5 -104.5t121 -82t136 -63t166 -45.5 +t200 -31.5t250 -18.5t304 -9.5t372.5 -2.5q139 0 244.5 -5t181 -16.5t124 -27.5t71 -39.5t24 -51.5t-19.5 -64t-56.5 -76.5t-89.5 -91t-116 -104.5t-139 -119q-185 -157 -286 -247q29 51 76.5 109t94 105.5t94.5 98.5t83 91.5t54 80.5t13 70t-45.5 55.5t-116.5 41t-204 23.5 +t-304 5q-168 -2 -314 6t-256 23t-204.5 41t-159.5 51.5t-122.5 62.5t-91.5 66.5t-68 71.5t-50.5 69.5t-40 68t-36.5 59.5z" /> + <glyph glyph-name="_539" unicode="&#xf23e;" horiz-adv-x="1792" +d="M896 1472q-169 0 -323 -66t-265.5 -177.5t-177.5 -265.5t-66 -323t66 -323t177.5 -265.5t265.5 -177.5t323 -66t323 66t265.5 177.5t177.5 265.5t66 323t-66 323t-177.5 265.5t-265.5 177.5t-323 66zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348 +t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM496 704q16 0 16 -16v-480q0 -16 -16 -16h-32q-16 0 -16 16v480q0 16 16 16h32zM896 640q53 0 90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-114q0 -14 -9 -23 +t-23 -9h-64q-14 0 -23 9t-9 23v114q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5zM896 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM544 928v-96 +q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5v-96q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v96q0 146 -103 249t-249 103t-249 -103t-103 -249zM1408 192v512q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-512 +q0 -26 19 -45t45 -19h896q26 0 45 19t19 45z" /> + <glyph glyph-name="_540" unicode="&#xf240;" horiz-adv-x="2304" +d="M1920 1024v-768h-1664v768h1664zM2048 448h128v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288zM2304 832v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113 +v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160q53 0 90.5 -37.5t37.5 -90.5z" /> + <glyph glyph-name="_541" unicode="&#xf241;" horiz-adv-x="2304" +d="M256 256v768h1280v-768h-1280zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_542" unicode="&#xf242;" horiz-adv-x="2304" +d="M256 256v768h896v-768h-896zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_543" unicode="&#xf243;" horiz-adv-x="2304" +d="M256 256v768h512v-768h-512zM2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9 +h-1856q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_544" unicode="&#xf244;" horiz-adv-x="2304" +d="M2176 960q53 0 90.5 -37.5t37.5 -90.5v-384q0 -53 -37.5 -90.5t-90.5 -37.5v-160q0 -66 -47 -113t-113 -47h-1856q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1856q66 0 113 -47t47 -113v-160zM2176 448v384h-128v288q0 14 -9 23t-23 9h-1856q-14 0 -23 -9t-9 -23 +v-960q0 -14 9 -23t23 -9h1856q14 0 23 9t9 23v288h128z" /> + <glyph glyph-name="_545" unicode="&#xf245;" horiz-adv-x="1280" +d="M1133 493q31 -30 14 -69q-17 -40 -59 -40h-382l201 -476q10 -25 0 -49t-34 -35l-177 -75q-25 -10 -49 0t-35 34l-191 452l-312 -312q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v1504q0 42 40 59q12 5 24 5q27 0 45 -19z" /> + <glyph glyph-name="_546" unicode="&#xf246;" horiz-adv-x="1024" +d="M832 1408q-320 0 -320 -224v-416h128v-128h-128v-544q0 -224 320 -224h64v-128h-64q-272 0 -384 146q-112 -146 -384 -146h-64v128h64q320 0 320 224v544h-128v128h128v416q0 224 -320 224h-64v128h64q272 0 384 -146q112 146 384 146h64v-128h-64z" /> + <glyph glyph-name="_547" unicode="&#xf247;" horiz-adv-x="2048" +d="M2048 1152h-128v-1024h128v-384h-384v128h-1280v-128h-384v384h128v1024h-128v384h384v-128h1280v128h384v-384zM1792 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 -128v128h-128v-128h128zM1664 0v128h128v1024h-128v128h-1280v-128h-128v-1024h128v-128 +h1280zM1920 -128v128h-128v-128h128zM1280 896h384v-768h-896v256h-384v768h896v-256zM512 512h640v512h-640v-512zM1536 256v512h-256v-384h-384v-128h640z" /> + <glyph glyph-name="_548" unicode="&#xf248;" horiz-adv-x="2304" +d="M2304 768h-128v-640h128v-384h-384v128h-896v-128h-384v384h128v128h-384v-128h-384v384h128v640h-128v384h384v-128h896v128h384v-384h-128v-128h384v128h384v-384zM2048 1024v-128h128v128h-128zM1408 1408v-128h128v128h-128zM128 1408v-128h128v128h-128zM256 256 +v128h-128v-128h128zM1536 384h-128v-128h128v128zM384 384h896v128h128v640h-128v128h-896v-128h-128v-640h128v-128zM896 -128v128h-128v-128h128zM2176 -128v128h-128v-128h128zM2048 128v640h-128v128h-384v-384h128v-384h-384v128h-384v-128h128v-128h896v128h128z" /> + <glyph glyph-name="_549" unicode="&#xf249;" +d="M1024 288v-416h-928q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68v-928h-416q-40 0 -68 -28t-28 -68zM1152 256h381q-15 -82 -65 -132l-184 -184q-50 -50 -132 -65v381z" /> + <glyph glyph-name="_550" unicode="&#xf24a;" +d="M1400 256h-248v-248q29 10 41 22l185 185q12 12 22 41zM1120 384h288v896h-1280v-1280h896v288q0 40 28 68t68 28zM1536 1312v-1024q0 -40 -20 -88t-48 -76l-184 -184q-28 -28 -76 -48t-88 -20h-1024q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1344q40 0 68 -28t28 -68 +z" /> + <glyph glyph-name="_551" unicode="&#xf24b;" horiz-adv-x="2304" +d="M1951 538q0 -26 -15.5 -44.5t-38.5 -23.5q-8 -2 -18 -2h-153v140h153q10 0 18 -2q23 -5 38.5 -23.5t15.5 -44.5zM1933 751q0 -25 -15 -42t-38 -21q-3 -1 -15 -1h-139v129h139q3 0 8.5 -0.5t6.5 -0.5q23 -4 38 -21.5t15 -42.5zM728 587v308h-228v-308q0 -58 -38 -94.5 +t-105 -36.5q-108 0 -229 59v-112q53 -15 121 -23t109 -9l42 -1q328 0 328 217zM1442 403v113q-99 -52 -200 -59q-108 -8 -169 41t-61 142t61 142t169 41q101 -7 200 -58v112q-48 12 -100 19.5t-80 9.5l-28 2q-127 6 -218.5 -14t-140.5 -60t-71 -88t-22 -106t22 -106t71 -88 +t140.5 -60t218.5 -14q101 4 208 31zM2176 518q0 54 -43 88.5t-109 39.5v3q57 8 89 41.5t32 79.5q0 55 -41 88t-107 36q-3 0 -12 0.5t-14 0.5h-455v-510h491q74 0 121.5 36.5t47.5 96.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90 +t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_552" unicode="&#xf24c;" horiz-adv-x="2304" +d="M858 295v693q-106 -41 -172 -135.5t-66 -211.5t66 -211.5t172 -134.5zM1362 641q0 117 -66 211.5t-172 135.5v-694q106 41 172 135.5t66 211.5zM1577 641q0 -159 -78.5 -294t-213.5 -213.5t-294 -78.5q-119 0 -227.5 46.5t-187 125t-125 187t-46.5 227.5q0 159 78.5 294 +t213.5 213.5t294 78.5t294 -78.5t213.5 -213.5t78.5 -294zM1960 634q0 139 -55.5 261.5t-147.5 205.5t-213.5 131t-252.5 48h-301q-176 0 -323.5 -81t-235 -230t-87.5 -335q0 -171 87 -317.5t236 -231.5t323 -85h301q129 0 251.5 50.5t214.5 135t147.5 202.5t55.5 246z +M2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_553" unicode="&#xf24d;" horiz-adv-x="1792" +d="M1664 -96v1088q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5zM1792 992v-1088q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113 +zM1408 1376v-160h-128v160q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-1088q0 -13 9.5 -22.5t22.5 -9.5h160v-128h-160q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1088q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_554" unicode="&#xf24e;" horiz-adv-x="2304" +d="M1728 1088l-384 -704h768zM448 1088l-384 -704h768zM1269 1280q-14 -40 -45.5 -71.5t-71.5 -45.5v-1291h608q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1344q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h608v1291q-40 14 -71.5 45.5t-45.5 71.5h-491q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h491q21 57 70 92.5t111 35.5t111 -35.5t70 -92.5h491q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-491zM1088 1264q33 0 56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5zM2176 384q0 -73 -46.5 -131t-117.5 -91 +t-144.5 -49.5t-139.5 -16.5t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81zM896 384q0 -73 -46.5 -131t-117.5 -91t-144.5 -49.5t-139.5 -16.5 +t-139.5 16.5t-144.5 49.5t-117.5 91t-46.5 131q0 11 35 81t92 174.5t107 195.5t102 184t56 100q18 33 56 33t56 -33q4 -7 56 -100t102 -184t107 -195.5t92 -174.5t35 -81z" /> + <glyph glyph-name="_555" unicode="&#xf250;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-77 -29 -149 -92.5 +t-129.5 -152.5t-92.5 -210t-35 -253h1024q0 132 -35 253t-92.5 210t-129.5 152.5t-149 92.5q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_556" unicode="&#xf251;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -66 9 -128h1006q9 61 9 128zM1280 -128q0 130 -34 249.5t-90.5 208t-126.5 152t-146 94.5h-230q-76 -31 -146 -94.5t-126.5 -152t-90.5 -208t-34 -249.5h1024z" /> + <glyph glyph-name="_557" unicode="&#xf252;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM1280 1408h-1024q0 -206 85 -384h854q85 178 85 384zM1223 192q-54 141 -145.5 241.5t-194.5 142.5h-230q-103 -42 -194.5 -142.5t-145.5 -241.5h910z" /> + <glyph glyph-name="_558" unicode="&#xf253;" +d="M1408 1408q0 -261 -106.5 -461.5t-266.5 -306.5q160 -106 266.5 -306.5t106.5 -461.5h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96q0 261 106.5 461.5t266.5 306.5q-160 106 -266.5 306.5t-106.5 461.5h-96q-14 0 -23 9 +t-9 23v64q0 14 9 23t23 9h1472q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96zM874 700q77 29 149 92.5t129.5 152.5t92.5 210t35 253h-1024q0 -132 35 -253t92.5 -210t129.5 -152.5t149 -92.5q19 -7 30.5 -23.5t11.5 -36.5t-11.5 -36.5t-30.5 -23.5q-137 -51 -244 -196 +h700q-107 145 -244 196q-19 7 -30.5 23.5t-11.5 36.5t11.5 36.5t30.5 23.5z" /> + <glyph glyph-name="_559" unicode="&#xf254;" +d="M1504 -64q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472zM130 0q3 55 16 107t30 95t46 87t53.5 76t64.5 69.5t66 60t70.5 55t66.5 47.5t65 43q-43 28 -65 43t-66.5 47.5t-70.5 55t-66 60t-64.5 69.5t-53.5 76t-46 87 +t-30 95t-16 107h1276q-3 -55 -16 -107t-30 -95t-46 -87t-53.5 -76t-64.5 -69.5t-66 -60t-70.5 -55t-66.5 -47.5t-65 -43q43 -28 65 -43t66.5 -47.5t70.5 -55t66 -60t64.5 -69.5t53.5 -76t46 -87t30 -95t16 -107h-1276zM1504 1536q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9 +h-1472q-14 0 -23 9t-9 23v128q0 14 9 23t23 9h1472z" /> + <glyph glyph-name="_560" unicode="&#xf255;" +d="M768 1152q-53 0 -90.5 -37.5t-37.5 -90.5v-128h-32v93q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-429l-32 30v172q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-224q0 -47 35 -82l310 -296q39 -39 39 -102q0 -26 19 -45t45 -19h640q26 0 45 19t19 45v25 +q0 41 10 77l108 436q10 36 10 77v246q0 48 -32 81.5t-80 33.5q-46 0 -79 -33t-33 -79v-32h-32v125q0 40 -25 72.5t-64 40.5q-14 2 -23 2q-46 0 -79 -33t-33 -79v-128h-32v122q0 51 -32.5 89.5t-82.5 43.5q-5 1 -13 1zM768 1280q84 0 149 -50q57 34 123 34q59 0 111 -27 +t86 -76q27 7 59 7q100 0 170 -71.5t70 -171.5v-246q0 -51 -13 -108l-109 -436q-6 -24 -6 -71q0 -80 -56 -136t-136 -56h-640q-84 0 -138 58.5t-54 142.5l-308 296q-76 73 -76 175v224q0 99 70.5 169.5t169.5 70.5q11 0 16 -1q6 95 75.5 160t164.5 65q52 0 98 -21 +q72 69 174 69z" /> + <glyph glyph-name="_561" unicode="&#xf256;" horiz-adv-x="1792" +d="M880 1408q-46 0 -79 -33t-33 -79v-656h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528v-256l-154 205q-38 51 -102 51q-53 0 -90.5 -37.5t-37.5 -90.5q0 -43 26 -77l384 -512q38 -51 102 -51h688q34 0 61 22t34 56l76 405q5 32 5 59v498q0 46 -33 79t-79 33t-79 -33 +t-33 -79v-272h-32v528q0 46 -33 79t-79 33t-79 -33t-33 -79v-528h-32v656q0 46 -33 79t-79 33zM880 1536q68 0 125.5 -35.5t88.5 -96.5q19 4 42 4q99 0 169.5 -70.5t70.5 -169.5v-17q105 6 180.5 -64t75.5 -175v-498q0 -40 -8 -83l-76 -404q-14 -79 -76.5 -131t-143.5 -52 +h-688q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 106 75 181t181 75q78 0 128 -34v434q0 99 70.5 169.5t169.5 70.5q23 0 42 -4q31 61 88.5 96.5t125.5 35.5z" /> + <glyph glyph-name="_562" unicode="&#xf257;" horiz-adv-x="1792" +d="M1073 -128h-177q-163 0 -226 141q-23 49 -23 102v5q-62 30 -98.5 88.5t-36.5 127.5q0 38 5 48h-261q-106 0 -181 75t-75 181t75 181t181 75h113l-44 17q-74 28 -119.5 93.5t-45.5 145.5q0 106 75 181t181 75q46 0 91 -17l628 -239h401q106 0 181 -75t75 -181v-668 +q0 -88 -54 -157.5t-140 -90.5l-339 -85q-92 -23 -186 -23zM1024 583l-155 -71l-163 -74q-30 -14 -48 -41.5t-18 -60.5q0 -46 33 -79t79 -33q26 0 46 10l338 154q-49 10 -80.5 50t-31.5 90v55zM1344 272q0 46 -33 79t-79 33q-26 0 -46 -10l-290 -132q-28 -13 -37 -17 +t-30.5 -17t-29.5 -23.5t-16 -29t-8 -40.5q0 -50 31.5 -82t81.5 -32q20 0 38 9l352 160q30 14 48 41.5t18 60.5zM1112 1024l-650 248q-24 8 -46 8q-53 0 -90.5 -37.5t-37.5 -90.5q0 -40 22.5 -73t59.5 -47l526 -200v-64h-640q-53 0 -90.5 -37.5t-37.5 -90.5t37.5 -90.5 +t90.5 -37.5h535l233 106v198q0 63 46 106l111 102h-69zM1073 0q82 0 155 19l339 85q43 11 70 45.5t27 78.5v668q0 53 -37.5 90.5t-90.5 37.5h-308l-136 -126q-36 -33 -36 -82v-296q0 -46 33 -77t79 -31t79 35t33 81v208h32v-208q0 -70 -57 -114q52 -8 86.5 -48.5t34.5 -93.5 +q0 -42 -23 -78t-61 -53l-310 -141h91z" /> + <glyph glyph-name="_563" unicode="&#xf258;" horiz-adv-x="2048" +d="M1151 1536q61 0 116 -28t91 -77l572 -781q118 -159 118 -359v-355q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v177l-286 143h-546q-80 0 -136 56t-56 136v32q0 119 84.5 203.5t203.5 84.5h420l42 128h-686q-100 0 -173.5 67.5t-81.5 166.5q-65 79 -65 182v32 +q0 80 56 136t136 56h959zM1920 -64v355q0 157 -93 284l-573 781q-39 52 -103 52h-959q-26 0 -45 -19t-19 -45q0 -32 1.5 -49.5t9.5 -40.5t25 -43q10 31 35.5 50t56.5 19h832v-32h-832q-26 0 -45 -19t-19 -45q0 -44 3 -58q8 -44 44 -73t81 -29h640h91q40 0 68 -28t28 -68 +q0 -15 -5 -30l-64 -192q-10 -29 -35 -47.5t-56 -18.5h-443q-66 0 -113 -47t-47 -113v-32q0 -26 19 -45t45 -19h561q16 0 29 -7l317 -158q24 -13 38.5 -36t14.5 -50v-197q0 -26 19 -45t45 -19h384q26 0 45 19t19 45z" /> + <glyph glyph-name="_564" unicode="&#xf259;" horiz-adv-x="2048" +d="M459 -256q-77 0 -137.5 47.5t-79.5 122.5l-101 401q-13 57 -13 108q0 45 -5 67l-116 477q-7 27 -7 57q0 93 62 161t155 78q17 85 82.5 139t152.5 54q83 0 148 -51.5t85 -132.5l83 -348l103 428q20 81 85 132.5t148 51.5q89 0 155.5 -57.5t80.5 -144.5q92 -10 152 -79 +t60 -162q0 -24 -7 -59l-123 -512q10 7 37.5 28.5t38.5 29.5t35 23t41 20.5t41.5 11t49.5 5.5q105 0 180 -74t75 -179q0 -62 -28.5 -118t-78.5 -94l-507 -380q-68 -51 -153 -51h-694zM1104 1408q-38 0 -68.5 -24t-39.5 -62l-164 -682h-127l-145 602q-9 38 -39.5 62t-68.5 24 +q-48 0 -80 -33t-32 -80q0 -15 3 -28l132 -547h-26l-99 408q-9 37 -40 62.5t-69 25.5q-47 0 -80 -33t-33 -79q0 -14 3 -26l116 -478q7 -28 9 -86t10 -88l100 -401q8 -32 34 -52.5t59 -20.5h694q42 0 76 26l507 379q56 43 56 110q0 52 -37.5 88.5t-89.5 36.5q-43 0 -77 -26 +l-307 -230v227q0 4 32 138t68 282t39 161q4 18 4 29q0 47 -32 81t-79 34q-39 0 -69.5 -24t-39.5 -62l-116 -482h-26l150 624q3 14 3 28q0 48 -31.5 82t-79.5 34z" /> + <glyph glyph-name="_565" unicode="&#xf25a;" horiz-adv-x="1792" +d="M640 1408q-53 0 -90.5 -37.5t-37.5 -90.5v-512v-384l-151 202q-41 54 -107 54q-52 0 -89 -38t-37 -90q0 -43 26 -77l384 -512q38 -51 102 -51h718q22 0 39.5 13.5t22.5 34.5l92 368q24 96 24 194v217q0 41 -28 71t-68 30t-68 -28t-28 -68h-32v61q0 48 -32 81.5t-80 33.5 +q-46 0 -79 -33t-33 -79v-64h-32v90q0 55 -37 94.5t-91 39.5q-53 0 -90.5 -37.5t-37.5 -90.5v-96h-32v570q0 55 -37 94.5t-91 39.5zM640 1536q107 0 181.5 -77.5t74.5 -184.5v-220q22 2 32 2q99 0 173 -69q47 21 99 21q113 0 184 -87q27 7 56 7q94 0 159 -67.5t65 -161.5 +v-217q0 -116 -28 -225l-92 -368q-16 -64 -68 -104.5t-118 -40.5h-718q-60 0 -114.5 27.5t-90.5 74.5l-384 512q-51 68 -51 154q0 105 74.5 180.5t179.5 75.5q71 0 130 -35v547q0 106 75 181t181 75zM768 128v384h-32v-384h32zM1024 128v384h-32v-384h32zM1280 128v384h-32 +v-384h32z" /> + <glyph glyph-name="_566" unicode="&#xf25b;" +d="M1288 889q60 0 107 -23q141 -63 141 -226v-177q0 -94 -23 -186l-85 -339q-21 -86 -90.5 -140t-157.5 -54h-668q-106 0 -181 75t-75 181v401l-239 628q-17 45 -17 91q0 106 75 181t181 75q80 0 145.5 -45.5t93.5 -119.5l17 -44v113q0 106 75 181t181 75t181 -75t75 -181 +v-261q27 5 48 5q69 0 127.5 -36.5t88.5 -98.5zM1072 896q-33 0 -60.5 -18t-41.5 -48l-74 -163l-71 -155h55q50 0 90 -31.5t50 -80.5l154 338q10 20 10 46q0 46 -33 79t-79 33zM1293 761q-22 0 -40.5 -8t-29 -16t-23.5 -29.5t-17 -30.5t-17 -37l-132 -290q-10 -20 -10 -46 +q0 -46 33 -79t79 -33q33 0 60.5 18t41.5 48l160 352q9 18 9 38q0 50 -32 81.5t-82 31.5zM128 1120q0 -22 8 -46l248 -650v-69l102 111q43 46 106 46h198l106 233v535q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5v-640h-64l-200 526q-14 37 -47 59.5t-73 22.5 +q-53 0 -90.5 -37.5t-37.5 -90.5zM1180 -128q44 0 78.5 27t45.5 70l85 339q19 73 19 155v91l-141 -310q-17 -38 -53 -61t-78 -23q-53 0 -93.5 34.5t-48.5 86.5q-44 -57 -114 -57h-208v32h208q46 0 81 33t35 79t-31 79t-77 33h-296q-49 0 -82 -36l-126 -136v-308 +q0 -53 37.5 -90.5t90.5 -37.5h668z" /> + <glyph glyph-name="_567" unicode="&#xf25c;" horiz-adv-x="1973" +d="M857 992v-117q0 -13 -9.5 -22t-22.5 -9h-298v-812q0 -13 -9 -22.5t-22 -9.5h-135q-13 0 -22.5 9t-9.5 23v812h-297q-13 0 -22.5 9t-9.5 22v117q0 14 9 23t23 9h793q13 0 22.5 -9.5t9.5 -22.5zM1895 995l77 -961q1 -13 -8 -24q-10 -10 -23 -10h-134q-12 0 -21 8.5 +t-10 20.5l-46 588l-189 -425q-8 -19 -29 -19h-120q-20 0 -29 19l-188 427l-45 -590q-1 -12 -10 -20.5t-21 -8.5h-135q-13 0 -23 10q-9 10 -9 24l78 961q1 12 10 20.5t21 8.5h142q20 0 29 -19l220 -520q10 -24 20 -51q3 7 9.5 24.5t10.5 26.5l221 520q9 19 29 19h141 +q13 0 22 -8.5t10 -20.5z" /> + <glyph glyph-name="_568" unicode="&#xf25d;" horiz-adv-x="1792" +d="M1042 833q0 88 -60 121q-33 18 -117 18h-123v-281h162q66 0 102 37t36 105zM1094 548l205 -373q8 -17 -1 -31q-8 -16 -27 -16h-152q-20 0 -28 17l-194 365h-155v-350q0 -14 -9 -23t-23 -9h-134q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h294q128 0 190 -24q85 -31 134 -109 +t49 -180q0 -92 -42.5 -165.5t-115.5 -109.5q6 -10 9 -16zM896 1376q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM1792 640 +q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_569" unicode="&#xf25e;" horiz-adv-x="1792" +d="M605 303q153 0 257 104q14 18 3 36l-45 82q-6 13 -24 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78 +q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-148 0 -246 -96.5t-98 -240.5q0 -146 97 -241.5t247 -95.5zM1235 303q153 0 257 104q14 18 4 36l-45 82q-8 14 -25 17q-16 2 -27 -11l-4 -3q-4 -4 -11.5 -10t-17.5 -13.5t-23.5 -14.5t-28.5 -13t-33.5 -9.5 +t-37.5 -3.5q-76 0 -125 50t-49 127q0 76 48 125.5t122 49.5q37 0 71.5 -14t50.5 -28l16 -14q11 -11 26 -10q16 2 24 14l53 78q13 20 -2 39q-3 4 -11 12t-30 23.5t-48.5 28t-67.5 22.5t-86 10q-147 0 -245.5 -96.5t-98.5 -240.5q0 -146 97 -241.5t247 -95.5zM896 1376 +q-150 0 -286 -58.5t-234.5 -157t-157 -234.5t-58.5 -286t58.5 -286t157 -234.5t234.5 -157t286 -58.5t286 58.5t234.5 157t157 234.5t58.5 286t-58.5 286t-157 234.5t-234.5 157t-286 58.5zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71z" /> + <glyph glyph-name="f260" unicode="&#xf260;" horiz-adv-x="2048" +d="M736 736l384 -384l-384 -384l-672 672l672 672l168 -168l-96 -96l-72 72l-480 -480l480 -480l193 193l-289 287zM1312 1312l672 -672l-672 -672l-168 168l96 96l72 -72l480 480l-480 480l-193 -193l289 -287l-96 -96l-384 384z" /> + <glyph glyph-name="f261" unicode="&#xf261;" horiz-adv-x="1792" +d="M717 182l271 271l-279 279l-88 -88l192 -191l-96 -96l-279 279l279 279l40 -40l87 87l-127 128l-454 -454zM1075 190l454 454l-454 454l-271 -271l279 -279l88 88l-192 191l96 96l279 -279l-279 -279l-40 40l-87 -88zM1792 640q0 -182 -71 -348t-191 -286t-286 -191 +t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_572" unicode="&#xf262;" horiz-adv-x="2304" +d="M651 539q0 -39 -27.5 -66.5t-65.5 -27.5q-39 0 -66.5 27.5t-27.5 66.5q0 38 27.5 65.5t66.5 27.5q38 0 65.5 -27.5t27.5 -65.5zM1805 540q0 -39 -27.5 -66.5t-66.5 -27.5t-66.5 27.5t-27.5 66.5t27.5 66t66.5 27t66.5 -27t27.5 -66zM765 539q0 79 -56.5 136t-136.5 57 +t-136.5 -56.5t-56.5 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM1918 540q0 80 -56.5 136.5t-136.5 56.5q-79 0 -136 -56.5t-57 -136.5t56.5 -136.5t136.5 -56.5t136.5 56.5t56.5 136.5zM850 539q0 -116 -81.5 -197.5t-196.5 -81.5q-116 0 -197.5 82t-81.5 197 +t82 196.5t197 81.5t196.5 -81.5t81.5 -196.5zM2004 540q0 -115 -81.5 -196.5t-197.5 -81.5q-115 0 -196.5 81.5t-81.5 196.5t81.5 196.5t196.5 81.5q116 0 197.5 -81.5t81.5 -196.5zM1040 537q0 191 -135.5 326.5t-326.5 135.5q-125 0 -231 -62t-168 -168.5t-62 -231.5 +t62 -231.5t168 -168.5t231 -62q191 0 326.5 135.5t135.5 326.5zM1708 1110q-254 111 -556 111q-319 0 -573 -110q117 0 223 -45.5t182.5 -122.5t122 -183t45.5 -223q0 115 43.5 219.5t118 180.5t177.5 123t217 50zM2187 537q0 191 -135 326.5t-326 135.5t-326.5 -135.5 +t-135.5 -326.5t135.5 -326.5t326.5 -135.5t326 135.5t135 326.5zM1921 1103h383q-44 -51 -75 -114.5t-40 -114.5q110 -151 110 -337q0 -156 -77 -288t-209 -208.5t-287 -76.5q-133 0 -249 56t-196 155q-47 -56 -129 -179q-11 22 -53.5 82.5t-74.5 97.5 +q-80 -99 -196.5 -155.5t-249.5 -56.5q-155 0 -287 76.5t-209 208.5t-77 288q0 186 110 337q-9 51 -40 114.5t-75 114.5h365q149 100 355 156.5t432 56.5q224 0 421 -56t348 -157z" /> + <glyph glyph-name="f263" unicode="&#xf263;" horiz-adv-x="1280" +d="M640 629q-188 0 -321 133t-133 320q0 188 133 321t321 133t321 -133t133 -321q0 -187 -133 -320t-321 -133zM640 1306q-92 0 -157.5 -65.5t-65.5 -158.5q0 -92 65.5 -157.5t157.5 -65.5t157.5 65.5t65.5 157.5q0 93 -65.5 158.5t-157.5 65.5zM1163 574q13 -27 15 -49.5 +t-4.5 -40.5t-26.5 -38.5t-42.5 -37t-61.5 -41.5q-115 -73 -315 -94l73 -72l267 -267q30 -31 30 -74t-30 -73l-12 -13q-31 -30 -74 -30t-74 30q-67 68 -267 268l-267 -268q-31 -30 -74 -30t-73 30l-12 13q-31 30 -31 73t31 74l267 267l72 72q-203 21 -317 94 +q-39 25 -61.5 41.5t-42.5 37t-26.5 38.5t-4.5 40.5t15 49.5q10 20 28 35t42 22t56 -2t65 -35q5 -4 15 -11t43 -24.5t69 -30.5t92 -24t113 -11q91 0 174 25.5t120 50.5l38 25q33 26 65 35t56 2t42 -22t28 -35z" /> + <glyph glyph-name="_574" unicode="&#xf264;" +d="M927 956q0 -66 -46.5 -112.5t-112.5 -46.5t-112.5 46.5t-46.5 112.5t46.5 112.5t112.5 46.5t112.5 -46.5t46.5 -112.5zM1141 593q-10 20 -28 32t-47.5 9.5t-60.5 -27.5q-10 -8 -29 -20t-81 -32t-127 -20t-124 18t-86 36l-27 18q-31 25 -60.5 27.5t-47.5 -9.5t-28 -32 +q-22 -45 -2 -74.5t87 -73.5q83 -53 226 -67l-51 -52q-142 -142 -191 -190q-22 -22 -22 -52.5t22 -52.5l9 -9q22 -22 52.5 -22t52.5 22l191 191q114 -115 191 -191q22 -22 52.5 -22t52.5 22l9 9q22 22 22 52.5t-22 52.5l-191 190l-52 52q141 14 225 67q67 44 87 73.5t-2 74.5 +zM1092 956q0 134 -95 229t-229 95t-229 -95t-95 -229t95 -229t229 -95t229 95t95 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="_575" unicode="&#xf265;" horiz-adv-x="1720" +d="M1565 1408q65 0 110 -45.5t45 -110.5v-519q0 -176 -68 -336t-182.5 -275t-274 -182.5t-334.5 -67.5q-176 0 -335.5 67.5t-274.5 182.5t-183 275t-68 336v519q0 64 46 110t110 46h1409zM861 344q47 0 82 33l404 388q37 35 37 85q0 49 -34.5 83.5t-83.5 34.5q-47 0 -82 -33 +l-323 -310l-323 310q-35 33 -81 33q-49 0 -83.5 -34.5t-34.5 -83.5q0 -51 36 -85l405 -388q33 -33 81 -33z" /> + <glyph glyph-name="_576" unicode="&#xf266;" horiz-adv-x="2304" +d="M1494 -103l-295 695q-25 -49 -158.5 -305.5t-198.5 -389.5q-1 -1 -27.5 -0.5t-26.5 1.5q-82 193 -255.5 587t-259.5 596q-21 50 -66.5 107.5t-103.5 100.5t-102 43q0 5 -0.5 24t-0.5 27h583v-50q-39 -2 -79.5 -16t-66.5 -43t-10 -64q26 -59 216.5 -499t235.5 -540 +q31 61 140 266.5t131 247.5q-19 39 -126 281t-136 295q-38 69 -201 71v50l513 -1v-47q-60 -2 -93.5 -25t-12.5 -69q33 -70 87 -189.5t86 -187.5q110 214 173 363q24 55 -10 79.5t-129 26.5q1 7 1 25v24q64 0 170.5 0.5t180 1t92.5 0.5v-49q-62 -2 -119 -33t-90 -81 +l-213 -442q13 -33 127.5 -290t121.5 -274l441 1017q-14 38 -49.5 62.5t-65 31.5t-55.5 8v50l460 -4l1 -2l-1 -44q-139 -4 -201 -145q-526 -1216 -559 -1291h-49z" /> + <glyph glyph-name="_577" unicode="&#xf267;" horiz-adv-x="1792" +d="M949 643q0 -26 -16.5 -45t-41.5 -19q-26 0 -45 16.5t-19 41.5q0 26 17 45t42 19t44 -16.5t19 -41.5zM964 585l350 581q-9 -8 -67.5 -62.5t-125.5 -116.5t-136.5 -127t-117 -110.5t-50.5 -51.5l-349 -580q7 7 67 62t126 116.5t136 127t117 111t50 50.5zM1611 640 +q0 -201 -104 -371q-3 2 -17 11t-26.5 16.5t-16.5 7.5q-13 0 -13 -13q0 -10 59 -44q-74 -112 -184.5 -190.5t-241.5 -110.5l-16 67q-1 10 -15 10q-5 0 -8 -5.5t-2 -9.5l16 -68q-72 -15 -146 -15q-199 0 -372 105q1 2 13 20.5t21.5 33.5t9.5 19q0 13 -13 13q-6 0 -17 -14.5 +t-22.5 -34.5t-13.5 -23q-113 75 -192 187.5t-110 244.5l69 15q10 3 10 15q0 5 -5.5 8t-10.5 2l-68 -15q-14 72 -14 139q0 206 109 379q2 -1 18.5 -12t30 -19t17.5 -8q13 0 13 12q0 6 -12.5 15.5t-32.5 21.5l-20 12q77 112 189 189t244 107l15 -67q2 -10 15 -10q5 0 8 5.5 +t2 10.5l-15 66q71 13 134 13q204 0 379 -109q-39 -56 -39 -65q0 -13 12 -13q11 0 48 64q111 -75 187.5 -186t107.5 -241l-56 -12q-10 -2 -10 -16q0 -5 5.5 -8t9.5 -2l57 13q14 -72 14 -140zM1696 640q0 163 -63.5 311t-170.5 255t-255 170.5t-311 63.5t-311 -63.5 +t-255 -170.5t-170.5 -255t-63.5 -311t63.5 -311t170.5 -255t255 -170.5t311 -63.5t311 63.5t255 170.5t170.5 255t63.5 311zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191 +t191 -286t71 -348z" /> + <glyph glyph-name="_578" unicode="&#xf268;" horiz-adv-x="1792" +d="M893 1536q240 2 451 -120q232 -134 352 -372l-742 39q-160 9 -294 -74.5t-185 -229.5l-276 424q128 159 311 245.5t383 87.5zM146 1131l337 -663q72 -143 211 -217t293 -45l-230 -451q-212 33 -385 157.5t-272.5 316t-99.5 411.5q0 267 146 491zM1732 962 +q58 -150 59.5 -310.5t-48.5 -306t-153 -272t-246 -209.5q-230 -133 -498 -119l405 623q88 131 82.5 290.5t-106.5 277.5zM896 942q125 0 213.5 -88.5t88.5 -213.5t-88.5 -213.5t-213.5 -88.5t-213.5 88.5t-88.5 213.5t88.5 213.5t213.5 88.5z" /> + <glyph glyph-name="_579" unicode="&#xf269;" horiz-adv-x="1792" +d="M903 -256q-283 0 -504.5 150.5t-329.5 398.5q-58 131 -67 301t26 332.5t111 312t179 242.5l-11 -281q11 14 68 15.5t70 -15.5q42 81 160.5 138t234.5 59q-54 -45 -119.5 -148.5t-58.5 -163.5q25 -8 62.5 -13.5t63 -7.5t68 -4t50.5 -3q15 -5 9.5 -45.5t-30.5 -75.5 +q-5 -7 -16.5 -18.5t-56.5 -35.5t-101 -34l15 -189l-139 67q-18 -43 -7.5 -81.5t36 -66.5t65.5 -41.5t81 -6.5q51 9 98 34.5t83.5 45t73.5 17.5q61 -4 89.5 -33t19.5 -65q-1 -2 -2.5 -5.5t-8.5 -12.5t-18 -15.5t-31.5 -10.5t-46.5 -1q-60 -95 -144.5 -135.5t-209.5 -29.5 +q74 -61 162.5 -82.5t168.5 -6t154.5 52t128 87.5t80.5 104q43 91 39 192.5t-37.5 188.5t-78.5 125q87 -38 137 -79.5t77 -112.5q15 170 -57.5 343t-209.5 284q265 -77 412 -279.5t151 -517.5q2 -127 -40.5 -255t-123.5 -238t-189 -196t-247.5 -135.5t-288.5 -49.5z" /> + <glyph glyph-name="_580" unicode="&#xf26a;" horiz-adv-x="1792" +d="M1493 1308q-165 110 -359 110q-155 0 -293 -73t-240 -200q-75 -93 -119.5 -218t-48.5 -266v-42q4 -141 48.5 -266t119.5 -218q102 -127 240 -200t293 -73q194 0 359 110q-121 -108 -274.5 -168t-322.5 -60q-29 0 -43 1q-175 8 -333 82t-272 193t-181 281t-67 339 +q0 182 71 348t191 286t286 191t348 71h3q168 -1 320.5 -60.5t273.5 -167.5zM1792 640q0 -192 -77 -362.5t-213 -296.5q-104 -63 -222 -63q-137 0 -255 84q154 56 253.5 233t99.5 405q0 227 -99 404t-253 234q119 83 254 83q119 0 226 -65q135 -125 210.5 -295t75.5 -361z +" /> + <glyph glyph-name="_581" unicode="&#xf26b;" horiz-adv-x="1792" +d="M1792 599q0 -56 -7 -104h-1151q0 -146 109.5 -244.5t257.5 -98.5q99 0 185.5 46.5t136.5 130.5h423q-56 -159 -170.5 -281t-267.5 -188.5t-321 -66.5q-187 0 -356 83q-228 -116 -394 -116q-237 0 -237 263q0 115 45 275q17 60 109 229q199 360 475 606 +q-184 -79 -427 -354q63 274 283.5 449.5t501.5 175.5q30 0 45 -1q255 117 433 117q64 0 116 -13t94.5 -40.5t66.5 -76.5t24 -115q0 -116 -75 -286q101 -182 101 -390zM1722 1239q0 83 -53 132t-137 49q-108 0 -254 -70q121 -47 222.5 -131.5t170.5 -195.5q51 135 51 216z +M128 2q0 -86 48.5 -132.5t134.5 -46.5q115 0 266 83q-122 72 -213.5 183t-137.5 245q-98 -205 -98 -332zM632 715h728q-5 142 -113 237t-251 95q-144 0 -251.5 -95t-112.5 -237z" /> + <glyph glyph-name="_582" unicode="&#xf26c;" horiz-adv-x="2048" +d="M1792 288v960q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1248v-960q0 -66 -47 -113t-113 -47h-736v-128h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23 +v64q0 14 9 23t23 9h352v128h-736q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> + <glyph glyph-name="_583" unicode="&#xf26d;" horiz-adv-x="1792" +d="M138 1408h197q-70 -64 -126 -149q-36 -56 -59 -115t-30 -125.5t-8.5 -120t10.5 -132t21 -126t28 -136.5q4 -19 6 -28q51 -238 81 -329q57 -171 152 -275h-272q-48 0 -82 34t-34 82v1304q0 48 34 82t82 34zM1346 1408h308q48 0 82 -34t34 -82v-1304q0 -48 -34 -82t-82 -34 +h-178q212 210 196 565l-469 -101q-2 -45 -12 -82t-31 -72t-59.5 -59.5t-93.5 -36.5q-123 -26 -199 40q-32 27 -53 61t-51.5 129t-64.5 258q-35 163 -45.5 263t-5.5 139t23 77q20 41 62.5 73t102.5 45q45 12 83.5 6.5t67 -17t54 -35t43 -48t34.5 -56.5l468 100 +q-68 175 -180 287z" /> + <glyph glyph-name="_584" unicode="&#xf26e;" +d="M1401 -11l-6 -6q-113 -113 -259 -175q-154 -64 -317 -64q-165 0 -317 64q-148 63 -259 175q-113 112 -175 258q-42 103 -54 189q-4 28 48 36q51 8 56 -20q1 -1 1 -4q18 -90 46 -159q50 -124 152 -226q98 -98 226 -152q132 -56 276 -56q143 0 276 56q128 55 225 152l6 6 +q10 10 25 6q12 -3 33 -22q36 -37 17 -58zM929 604l-66 -66l63 -63q21 -21 -7 -49q-17 -17 -32 -17q-10 0 -19 10l-62 61l-66 -66q-5 -5 -15 -5q-15 0 -31 16l-2 2q-18 15 -18 29q0 7 8 17l66 65l-66 66q-16 16 14 45q18 18 31 18q6 0 13 -5l65 -66l65 65q18 17 48 -13 +q27 -27 11 -44zM1400 547q0 -118 -46 -228q-45 -105 -126 -186q-80 -80 -187 -126t-228 -46t-228 46t-187 126q-82 82 -125 186q-15 33 -15 40h-1q-9 27 43 44q50 16 60 -12q37 -99 97 -167h1v339v2q3 136 102 232q105 103 253 103q147 0 251 -103t104 -249 +q0 -147 -104.5 -251t-250.5 -104q-58 0 -112 16q-28 11 -13 61q16 51 44 43l14 -3q14 -3 33 -6t30 -3q104 0 176 71.5t72 174.5q0 101 -72 171q-71 71 -175 71q-107 0 -178 -80q-64 -72 -64 -160v-413q110 -67 242 -67q96 0 185 36.5t156 103.5t103.5 155t36.5 183 +q0 198 -141 339q-140 140 -339 140q-200 0 -340 -140q-53 -53 -77 -87l-2 -2q-8 -11 -13 -15.5t-21.5 -9.5t-38.5 3q-21 5 -36.5 16.5t-15.5 26.5v680q0 15 10.5 26.5t27.5 11.5h877q30 0 30 -55t-30 -55h-811v-483h1q40 42 102 84t108 61q109 46 231 46q121 0 228 -46 +t187 -126q81 -81 126 -186q46 -112 46 -229zM1369 1128q9 -8 9 -18t-5.5 -18t-16.5 -21q-26 -26 -39 -26q-9 0 -16 7q-106 91 -207 133q-128 56 -276 56q-133 0 -262 -49q-27 -10 -45 37q-9 25 -8 38q3 16 16 20q130 57 299 57q164 0 316 -64q137 -58 235 -152z" /> + <glyph glyph-name="_585" unicode="&#xf270;" horiz-adv-x="1792" +d="M1551 60q15 6 26 3t11 -17.5t-15 -33.5q-13 -16 -44 -43.5t-95.5 -68t-141 -74t-188 -58t-229.5 -24.5q-119 0 -238 31t-209 76.5t-172.5 104t-132.5 105t-84 87.5q-8 9 -10 16.5t1 12t8 7t11.5 2t11.5 -4.5q192 -117 300 -166q389 -176 799 -90q190 40 391 135z +M1758 175q11 -16 2.5 -69.5t-28.5 -102.5q-34 -83 -85 -124q-17 -14 -26 -9t0 24q21 45 44.5 121.5t6.5 98.5q-5 7 -15.5 11.5t-27 6t-29.5 2.5t-35 0t-31.5 -2t-31 -3t-22.5 -2q-6 -1 -13 -1.5t-11 -1t-8.5 -1t-7 -0.5h-5.5h-4.5t-3 0.5t-2 1.5l-1.5 3q-6 16 47 40t103 30 +q46 7 108 1t76 -24zM1364 618q0 -31 13.5 -64t32 -58t37.5 -46t33 -32l13 -11l-227 -224q-40 37 -79 75.5t-58 58.5l-19 20q-11 11 -25 33q-38 -59 -97.5 -102.5t-127.5 -63.5t-140 -23t-137.5 21t-117.5 65.5t-83 113t-31 162.5q0 84 28 154t72 116.5t106.5 83t122.5 57 +t130 34.5t119.5 18.5t99.5 6.5v127q0 65 -21 97q-34 53 -121 53q-6 0 -16.5 -1t-40.5 -12t-56 -29.5t-56 -59.5t-48 -96l-294 27q0 60 22 119t67 113t108 95t151.5 65.5t190.5 24.5q100 0 181 -25t129.5 -61.5t81 -83t45 -86t12.5 -73.5v-589zM692 597q0 -86 70 -133 +q66 -44 139 -22q84 25 114 123q14 45 14 101v162q-59 -2 -111 -12t-106.5 -33.5t-87 -71t-32.5 -114.5z" /> + <glyph glyph-name="_586" unicode="&#xf271;" horiz-adv-x="1792" +d="M1536 1280q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128zM1152 1376v-288q0 -14 9 -23t23 -9 +h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 1376v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM1536 -128v1024h-1408v-1024h1408zM896 448h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224 +v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224z" /> + <glyph glyph-name="_587" unicode="&#xf272;" horiz-adv-x="1792" +d="M1152 416v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23 +t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_588" unicode="&#xf273;" horiz-adv-x="1792" +d="M1111 151l-46 -46q-9 -9 -22 -9t-23 9l-188 189l-188 -189q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22t9 23l189 188l-189 188q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l188 -188l188 188q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23l-188 -188l188 -188q9 -10 9 -23t-9 -22z +M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 +q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_589" unicode="&#xf274;" horiz-adv-x="1792" +d="M1303 572l-512 -512q-10 -9 -23 -9t-23 9l-288 288q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l220 -220l444 444q10 9 23 9t22 -9l46 -46q9 -9 9 -22t-9 -23zM128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23 +t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47 +t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> + <glyph glyph-name="_590" unicode="&#xf275;" horiz-adv-x="1792" +d="M448 1536q26 0 45 -19t19 -45v-891l536 429q17 14 40 14q26 0 45 -19t19 -45v-379l536 429q17 14 40 14q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h384z" /> + <glyph glyph-name="_591" unicode="&#xf276;" horiz-adv-x="1024" +d="M512 448q66 0 128 15v-655q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v655q62 -15 128 -15zM512 1536q212 0 362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362t150 362t362 150zM512 1312q14 0 23 9t9 23t-9 23t-23 9q-146 0 -249 -103t-103 -249 +q0 -14 9 -23t23 -9t23 9t9 23q0 119 84.5 203.5t203.5 84.5z" /> + <glyph glyph-name="_592" unicode="&#xf277;" horiz-adv-x="1792" +d="M1745 1239q10 -10 10 -23t-10 -23l-141 -141q-28 -28 -68 -28h-1344q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h576v64q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-64h512q40 0 68 -28zM768 320h256v-512q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v512zM1600 768 +q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1344q-40 0 -68 28l-141 141q-10 10 -10 23t10 23l141 141q28 28 68 28h512v192h256v-192h576z" /> + <glyph glyph-name="_593" unicode="&#xf278;" horiz-adv-x="2048" +d="M2020 1525q28 -20 28 -53v-1408q0 -20 -11 -36t-29 -23l-640 -256q-24 -11 -48 0l-616 246l-616 -246q-10 -5 -24 -5q-19 0 -36 11q-28 20 -28 53v1408q0 20 11 36t29 23l640 256q24 11 48 0l616 -246l616 246q32 13 60 -6zM736 1390v-1270l576 -230v1270zM128 1173 +v-1270l544 217v1270zM1920 107v1270l-544 -217v-1270z" /> + <glyph glyph-name="_594" unicode="&#xf279;" horiz-adv-x="1792" +d="M512 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472q0 20 17 28l480 256q7 4 15 4zM1760 1536q13 0 22.5 -9.5t9.5 -22.5v-1472q0 -20 -17 -28l-480 -256q-7 -4 -15 -4q-13 0 -22.5 9.5t-9.5 22.5v1472 +q0 20 17 28l480 256q7 4 15 4zM640 1536q8 0 14 -3l512 -256q18 -10 18 -29v-1472q0 -13 -9.5 -22.5t-22.5 -9.5q-8 0 -14 3l-512 256q-18 10 -18 29v1472q0 13 9.5 22.5t22.5 9.5z" /> + <glyph glyph-name="_595" unicode="&#xf27a;" horiz-adv-x="1792" +d="M640 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 640q0 53 -37.5 90.5t-90.5 37.5 +t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-110 0 -211 18q-173 -173 -435 -229q-52 -10 -86 -13q-12 -1 -22 6t-13 18q-4 15 20 37q5 5 23.5 21.5t25.5 23.5t23.5 25.5t24 31.5t20.5 37 +t20 48t14.5 57.5t12.5 72.5q-146 90 -229.5 216.5t-83.5 269.5q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> + <glyph glyph-name="_596" unicode="&#xf27b;" horiz-adv-x="1792" +d="M640 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 -53 -37.5 -90.5t-90.5 -37.5 +t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5 +t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51 +t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 130 71 248.5t191 204.5t286 136.5t348 50.5t348 -50.5t286 -136.5t191 -204.5t71 -248.5z" /> + <glyph glyph-name="_597" unicode="&#xf27c;" horiz-adv-x="1024" +d="M512 345l512 295v-591l-512 -296v592zM0 640v-591l512 296zM512 1527v-591l-512 -296v591zM512 936l512 295v-591z" /> + <glyph glyph-name="_598" unicode="&#xf27d;" horiz-adv-x="1792" +d="M1709 1018q-10 -236 -332 -651q-333 -431 -562 -431q-142 0 -240 263q-44 160 -132 482q-72 262 -157 262q-18 0 -127 -76l-77 98q24 21 108 96.5t130 115.5q156 138 241 146q95 9 153 -55.5t81 -203.5q44 -287 66 -373q55 -249 120 -249q51 0 154 161q101 161 109 246 +q13 139 -109 139q-57 0 -121 -26q120 393 459 382q251 -8 236 -326z" /> + <glyph glyph-name="f27e" unicode="&#xf27e;" +d="M0 1408h1536v-1536h-1536v1536zM1085 293l-221 631l221 297h-634l221 -297l-221 -631l317 -304z" /> + <glyph glyph-name="uniF280" unicode="&#xf280;" +d="M0 1408h1536v-1536h-1536v1536zM908 1088l-12 -33l75 -83l-31 -114l25 -25l107 57l107 -57l25 25l-31 114l75 83l-12 33h-95l-53 96h-32l-53 -96h-95zM641 925q32 0 44.5 -16t11.5 -63l174 21q0 55 -17.5 92.5t-50.5 56t-69 25.5t-85 7q-133 0 -199 -57.5t-66 -182.5v-72 +h-96v-128h76q20 0 20 -8v-382q0 -14 -5 -20t-18 -7l-73 -7v-88h448v86l-149 14q-6 1 -8.5 1.5t-3.5 2.5t-0.5 4t1 7t0.5 10v387h191l38 128h-231q-6 0 -2 6t4 9v80q0 27 1.5 40.5t7.5 28t19.5 20t36.5 5.5zM1248 96v86l-54 9q-7 1 -9.5 2.5t-2.5 3t1 7.5t1 12v520h-275 +l-23 -101l83 -22q23 -7 23 -27v-370q0 -14 -6 -18.5t-20 -6.5l-70 -9v-86h352z" /> + <glyph glyph-name="uniF281" unicode="&#xf281;" horiz-adv-x="1792" +d="M1792 690q0 -58 -29.5 -105.5t-79.5 -72.5q12 -46 12 -96q0 -155 -106.5 -287t-290.5 -208.5t-400 -76.5t-399.5 76.5t-290 208.5t-106.5 287q0 47 11 94q-51 25 -82 73.5t-31 106.5q0 82 58 140.5t141 58.5q85 0 145 -63q218 152 515 162l116 521q3 13 15 21t26 5 +l369 -81q18 37 54 59.5t79 22.5q62 0 106 -43.5t44 -105.5t-44 -106t-106 -44t-105.5 43.5t-43.5 105.5l-334 74l-104 -472q300 -9 519 -160q58 61 143 61q83 0 141 -58.5t58 -140.5zM418 491q0 -62 43.5 -106t105.5 -44t106 44t44 106t-44 105.5t-106 43.5q-61 0 -105 -44 +t-44 -105zM1228 136q11 11 11 26t-11 26q-10 10 -25 10t-26 -10q-41 -42 -121 -62t-160 -20t-160 20t-121 62q-11 10 -26 10t-25 -10q-11 -10 -11 -25.5t11 -26.5q43 -43 118.5 -68t122.5 -29.5t91 -4.5t91 4.5t122.5 29.5t118.5 68zM1225 341q62 0 105.5 44t43.5 106 +q0 61 -44 105t-105 44q-62 0 -106 -43.5t-44 -105.5t44 -106t106 -44z" /> + <glyph glyph-name="_602" unicode="&#xf282;" horiz-adv-x="1792" +d="M69 741h1q16 126 58.5 241.5t115 217t167.5 176t223.5 117.5t276.5 43q231 0 414 -105.5t294 -303.5q104 -187 104 -442v-188h-1125q1 -111 53.5 -192.5t136.5 -122.5t189.5 -57t213 -3t208 46.5t173.5 84.5v-377q-92 -55 -229.5 -92t-312.5 -38t-316 53 +q-189 73 -311.5 249t-124.5 372q-3 242 111 412t325 268q-48 -60 -78 -125.5t-46 -159.5h635q8 77 -8 140t-47 101.5t-70.5 66.5t-80.5 41t-75 20.5t-56 8.5l-22 1q-135 -5 -259.5 -44.5t-223.5 -104.5t-176 -140.5t-138 -163.5z" /> + <glyph glyph-name="_603" unicode="&#xf283;" horiz-adv-x="2304" +d="M0 32v608h2304v-608q0 -66 -47 -113t-113 -47h-1984q-66 0 -113 47t-47 113zM640 256v-128h384v128h-384zM256 256v-128h256v128h-256zM2144 1408q66 0 113 -47t47 -113v-224h-2304v224q0 66 47 113t113 47h1984z" /> + <glyph glyph-name="_604" unicode="&#xf284;" horiz-adv-x="1792" +d="M1584 246l-218 111q-74 -120 -196.5 -189t-263.5 -69q-147 0 -271 72t-196 196t-72 270q0 110 42.5 209.5t115 172t172 115t209.5 42.5q131 0 247.5 -60.5t192.5 -168.5l215 125q-110 169 -286.5 265t-378.5 96q-161 0 -308 -63t-253 -169t-169 -253t-63 -308t63 -308 +t169 -253t253 -169t308 -63q213 0 397.5 107t290.5 292zM1030 643l693 -352q-116 -253 -334.5 -400t-492.5 -147q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71q260 0 470.5 -133.5t335.5 -366.5zM1543 640h-39v-160h-96v352h136q32 0 54.5 -20 +t28.5 -48t1 -56t-27.5 -48t-57.5 -20z" /> + <glyph glyph-name="uniF285" unicode="&#xf285;" horiz-adv-x="1792" +d="M1427 827l-614 386l92 151h855zM405 562l-184 116v858l1183 -743zM1424 697l147 -95v-858l-532 335zM1387 718l-500 -802h-855l356 571z" /> + <glyph glyph-name="uniF286" unicode="&#xf286;" horiz-adv-x="1792" +d="M640 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1152 528v224q0 16 -16 16h-96q-16 0 -16 -16v-224q0 -16 16 -16h96q16 0 16 16zM1664 496v-752h-640v320q0 80 -56 136t-136 56t-136 -56t-56 -136v-320h-640v752q0 16 16 16h96 +q16 0 16 -16v-112h128v624q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 6 2.5 9.5t8.5 5t9.5 2t11.5 0t9 -0.5v391q-32 15 -32 50q0 23 16.5 39t38.5 16t38.5 -16t16.5 -39q0 -35 -32 -50v-17q45 10 83 10q21 0 59.5 -7.5t54.5 -7.5 +q17 0 47 7.5t37 7.5q16 0 16 -16v-210q0 -15 -35 -21.5t-62 -6.5q-18 0 -54.5 7.5t-55.5 7.5q-40 0 -90 -12v-133q1 0 9 0.5t11.5 0t9.5 -2t8.5 -5t2.5 -9.5v-112h128v112q0 16 16 16h96q16 0 16 -16v-112h128v112q0 16 16 16h96q16 0 16 -16v-624h128v112q0 16 16 16h96 +q16 0 16 -16z" /> + <glyph glyph-name="_607" unicode="&#xf287;" horiz-adv-x="2304" +d="M2288 731q16 -8 16 -27t-16 -27l-320 -192q-8 -5 -16 -5q-9 0 -16 4q-16 10 -16 28v128h-858q37 -58 83 -165q16 -37 24.5 -55t24 -49t27 -47t27 -34t31.5 -26t33 -8h96v96q0 14 9 23t23 9h320q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v96h-96 +q-32 0 -61 10t-51 23.5t-45 40.5t-37 46t-33.5 57t-28.5 57.5t-28 60.5q-23 53 -37 81.5t-36 65t-44.5 53.5t-46.5 17h-360q-22 -84 -91 -138t-157 -54q-106 0 -181 75t-75 181t75 181t181 75q88 0 157 -54t91 -138h104q24 0 46.5 17t44.5 53.5t36 65t37 81.5q19 41 28 60.5 +t28.5 57.5t33.5 57t37 46t45 40.5t51 23.5t61 10h107q21 57 70 92.5t111 35.5q80 0 136 -56t56 -136t-56 -136t-136 -56q-62 0 -111 35.5t-70 92.5h-107q-17 0 -33 -8t-31.5 -26t-27 -34t-27 -47t-24 -49t-24.5 -55q-46 -107 -83 -165h1114v128q0 18 16 28t32 -1z" /> + <glyph glyph-name="_608" unicode="&#xf288;" horiz-adv-x="1792" +d="M1150 774q0 -56 -39.5 -95t-95.5 -39h-253v269h253q56 0 95.5 -39.5t39.5 -95.5zM1329 774q0 130 -91.5 222t-222.5 92h-433v-896h180v269h253q130 0 222 91.5t92 221.5zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348 +t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_609" unicode="&#xf289;" horiz-adv-x="2304" +d="M1645 438q0 59 -34 106.5t-87 68.5q-7 -45 -23 -92q-7 -24 -27.5 -38t-44.5 -14q-12 0 -24 3q-31 10 -45 38.5t-4 58.5q23 71 23 143q0 123 -61 227.5t-166 165.5t-228 61q-134 0 -247 -73t-167 -194q108 -28 188 -106q22 -23 22 -55t-22 -54t-54 -22t-55 22 +q-75 75 -180 75q-106 0 -181 -74.5t-75 -180.5t75 -180.5t181 -74.5h1046q79 0 134.5 55.5t55.5 133.5zM1798 438q0 -142 -100.5 -242t-242.5 -100h-1046q-169 0 -289 119.5t-120 288.5q0 153 100 267t249 136q62 184 221 298t354 114q235 0 408.5 -158.5t196.5 -389.5 +q116 -25 192.5 -118.5t76.5 -214.5zM2048 438q0 -175 -97 -319q-23 -33 -64 -33q-24 0 -43 13q-26 17 -32 48.5t12 57.5q71 104 71 233t-71 233q-18 26 -12 57t32 49t57.5 11.5t49.5 -32.5q97 -142 97 -318zM2304 438q0 -244 -134 -443q-23 -34 -64 -34q-23 0 -42 13 +q-26 18 -32.5 49t11.5 57q108 164 108 358q0 195 -108 357q-18 26 -11.5 57.5t32.5 48.5q26 18 57 12t49 -33q134 -198 134 -442z" /> + <glyph glyph-name="_610" unicode="&#xf28a;" +d="M1500 -13q0 -89 -63 -152.5t-153 -63.5t-153.5 63.5t-63.5 152.5q0 90 63.5 153.5t153.5 63.5t153 -63.5t63 -153.5zM1267 268q-115 -15 -192.5 -102.5t-77.5 -205.5q0 -74 33 -138q-146 -78 -379 -78q-109 0 -201 21t-153.5 54.5t-110.5 76.5t-76 85t-44.5 83 +t-23.5 66.5t-6 39.5q0 19 4.5 42.5t18.5 56t36.5 58t64 43.5t94.5 18t94 -17.5t63 -41t35.5 -53t17.5 -49t4 -33.5q0 -34 -23 -81q28 -27 82 -42t93 -17l40 -1q115 0 190 51t75 133q0 26 -9 48.5t-31.5 44.5t-49.5 41t-74 44t-93.5 47.5t-119.5 56.5q-28 13 -43 20 +q-116 55 -187 100t-122.5 102t-72 125.5t-20.5 162.5q0 78 20.5 150t66 137.5t112.5 114t166.5 77t221.5 28.5q120 0 220 -26t164.5 -67t109.5 -94t64 -105.5t19 -103.5q0 -46 -15 -82.5t-36.5 -58t-48.5 -36t-49 -19.5t-39 -5h-8h-32t-39 5t-44 14t-41 28t-37 46t-24 70.5 +t-10 97.5q-15 16 -59 25.5t-81 10.5l-37 1q-68 0 -117.5 -31t-70.5 -70t-21 -76q0 -24 5 -43t24 -46t53 -51t97 -53.5t150 -58.5q76 -25 138.5 -53.5t109 -55.5t83 -59t60.5 -59.5t41 -62.5t26.5 -62t14.5 -63.5t6 -62t1 -62.5z" /> + <glyph glyph-name="_611" unicode="&#xf28b;" +d="M704 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1152 352v576q0 14 -9 23t-23 9h-256q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h256q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103 +t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_612" unicode="&#xf28c;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM864 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-192z" /> + <glyph glyph-name="_613" unicode="&#xf28d;" +d="M1088 352v576q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-576q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="_614" unicode="&#xf28e;" +d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM768 96q148 0 273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273 +t73 -273t198 -198t273 -73zM480 320q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h576q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-576z" /> + <glyph glyph-name="_615" unicode="&#xf290;" horiz-adv-x="1792" +d="M1757 128l35 -313q3 -28 -16 -50q-19 -21 -48 -21h-1664q-29 0 -48 21q-19 22 -16 50l35 313h1722zM1664 967l86 -775h-1708l86 775q3 24 21 40.5t43 16.5h256v-128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5v128h384v-128q0 -53 37.5 -90.5t90.5 -37.5 +t90.5 37.5t37.5 90.5v128h256q25 0 43 -16.5t21 -40.5zM1280 1152v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-256q0 -26 -19 -45t-45 -19t-45 19t-19 45v256q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_616" unicode="&#xf291;" horiz-adv-x="2048" +d="M1920 768q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5h-15l-115 -662q-8 -46 -44 -76t-82 -30h-1280q-46 0 -82 30t-44 76l-115 662h-15q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5h1792zM485 -32q26 2 43.5 22.5t15.5 46.5l-32 416q-2 26 -22.5 43.5 +t-46.5 15.5t-43.5 -22.5t-15.5 -46.5l32 -416q2 -25 20.5 -42t43.5 -17h5zM896 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1280 32v416q0 26 -19 45t-45 19t-45 -19t-19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45zM1632 27l32 416 +q2 26 -15.5 46.5t-43.5 22.5t-46.5 -15.5t-22.5 -43.5l-32 -416q-2 -26 15.5 -46.5t43.5 -22.5h5q25 0 43.5 17t20.5 42zM476 1244l-93 -412h-132l101 441q19 88 89 143.5t160 55.5h167q0 26 19 45t45 19h384q26 0 45 -19t19 -45h167q90 0 160 -55.5t89 -143.5l101 -441 +h-132l-93 412q-11 44 -45.5 72t-79.5 28h-167q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45h-167q-45 0 -79.5 -28t-45.5 -72z" /> + <glyph glyph-name="_617" unicode="&#xf292;" horiz-adv-x="1792" +d="M991 512l64 256h-254l-64 -256h254zM1759 1016l-56 -224q-7 -24 -31 -24h-327l-64 -256h311q15 0 25 -12q10 -14 6 -28l-56 -224q-5 -24 -31 -24h-327l-81 -328q-7 -24 -31 -24h-224q-16 0 -26 12q-9 12 -6 28l78 312h-254l-81 -328q-7 -24 -31 -24h-225q-15 0 -25 12 +q-9 12 -6 28l78 312h-311q-15 0 -25 12q-9 12 -6 28l56 224q7 24 31 24h327l64 256h-311q-15 0 -25 12q-10 14 -6 28l56 224q5 24 31 24h327l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h254l81 328q7 24 32 24h224q15 0 25 -12q9 -12 6 -28l-78 -312h311 +q15 0 25 -12q9 -12 6 -28z" /> + <glyph glyph-name="_618" unicode="&#xf293;" +d="M841 483l148 -148l-149 -149zM840 1094l149 -149l-148 -148zM710 -130l464 464l-306 306l306 306l-464 464v-611l-255 255l-93 -93l320 -321l-320 -321l93 -93l255 255v-611zM1429 640q0 -209 -32 -365.5t-87.5 -257t-140.5 -162.5t-181.5 -86.5t-219.5 -24.5 +t-219.5 24.5t-181.5 86.5t-140.5 162.5t-87.5 257t-32 365.5t32 365.5t87.5 257t140.5 162.5t181.5 86.5t219.5 24.5t219.5 -24.5t181.5 -86.5t140.5 -162.5t87.5 -257t32 -365.5z" /> + <glyph glyph-name="_619" unicode="&#xf294;" horiz-adv-x="1024" +d="M596 113l173 172l-173 172v-344zM596 823l173 172l-173 172v-344zM628 640l356 -356l-539 -540v711l-297 -296l-108 108l372 373l-372 373l108 108l297 -296v711l539 -540z" /> + <glyph glyph-name="_620" unicode="&#xf295;" +d="M1280 256q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM512 1024q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5 +t112.5 -271.5zM1440 1344q0 -20 -13 -38l-1056 -1408q-19 -26 -51 -26h-160q-26 0 -45 19t-19 45q0 20 13 38l1056 1408q19 26 51 26h160q26 0 45 -19t19 -45zM768 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 +t271.5 -112.5t112.5 -271.5z" /> + <glyph glyph-name="_621" unicode="&#xf296;" horiz-adv-x="1792" +d="M104 830l792 -1015l-868 630q-18 13 -25 34.5t0 42.5l101 308v0zM566 830h660l-330 -1015v0zM368 1442l198 -612h-462l198 612q8 23 33 23t33 -23zM1688 830l101 -308q7 -21 0 -42.5t-25 -34.5l-868 -630l792 1015v0zM1688 830h-462l198 612q8 23 33 23t33 -23z" /> + <glyph glyph-name="_622" unicode="&#xf297;" horiz-adv-x="1792" +d="M384 704h160v224h-160v-224zM1221 372v92q-104 -36 -243 -38q-135 -1 -259.5 46.5t-220.5 122.5l1 -96q88 -80 212 -128.5t272 -47.5q129 0 238 49zM640 704h640v224h-640v-224zM1792 736q0 -187 -99 -352q89 -102 89 -229q0 -157 -129.5 -268t-313.5 -111 +q-122 0 -225 52.5t-161 140.5q-19 -1 -57 -1t-57 1q-58 -88 -161 -140.5t-225 -52.5q-184 0 -313.5 111t-129.5 268q0 127 89 229q-99 165 -99 352q0 209 120 385.5t326.5 279.5t449.5 103t449.5 -103t326.5 -279.5t120 -385.5z" /> + <glyph glyph-name="_623" unicode="&#xf298;" +d="M515 625v-128h-252v128h252zM515 880v-127h-252v127h252zM1273 369v-128h-341v128h341zM1273 625v-128h-672v128h672zM1273 880v-127h-672v127h672zM1408 20v1240q0 8 -6 14t-14 6h-32l-378 -256l-210 171l-210 -171l-378 256h-32q-8 0 -14 -6t-6 -14v-1240q0 -8 6 -14 +t14 -6h1240q8 0 14 6t6 14zM553 1130l185 150h-406zM983 1130l221 150h-406zM1536 1260v-1240q0 -62 -43 -105t-105 -43h-1240q-62 0 -105 43t-43 105v1240q0 62 43 105t105 43h1240q62 0 105 -43t43 -105z" /> + <glyph glyph-name="_624" unicode="&#xf299;" horiz-adv-x="1792" +d="M896 720q-104 196 -160 278q-139 202 -347 318q-34 19 -70 36q-89 40 -94 32t34 -38l39 -31q62 -43 112.5 -93.5t94.5 -116.5t70.5 -113t70.5 -131q9 -17 13 -25q44 -84 84 -153t98 -154t115.5 -150t131 -123.5t148.5 -90.5q153 -66 154 -60q1 3 -49 37q-53 36 -81 57 +q-77 58 -179 211t-185 310zM549 177q-76 60 -132.5 125t-98 143.5t-71 154.5t-58.5 186t-52 209t-60.5 252t-76.5 289q273 0 497.5 -36t379 -92t271 -144.5t185.5 -172.5t110 -198.5t56 -199.5t12.5 -198.5t-9.5 -173t-20 -143.5t-13 -107l323 -327h-104l-281 285 +q-22 -2 -91.5 -14t-121.5 -19t-138 -6t-160.5 17t-167.5 59t-179 111z" /> + <glyph glyph-name="_625" unicode="&#xf29a;" horiz-adv-x="1792" +d="M1374 879q-6 26 -28.5 39.5t-48.5 7.5q-261 -62 -401 -62t-401 62q-26 6 -48.5 -7.5t-28.5 -39.5t7.5 -48.5t39.5 -28.5q194 -46 303 -58q-2 -158 -15.5 -269t-26.5 -155.5t-41 -115.5l-9 -21q-10 -25 1 -49t36 -34q9 -4 23 -4q44 0 60 41l8 20q54 139 71 259h42 +q17 -120 71 -259l8 -20q16 -41 60 -41q14 0 23 4q25 10 36 34t1 49l-9 21q-28 71 -41 115.5t-26.5 155.5t-15.5 269q109 12 303 58q26 6 39.5 28.5t7.5 48.5zM1024 1024q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z +M1600 640q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5zM896 1408q-156 0 -298 -61t-245 -164t-164 -245t-61 -298t61 -298 +t164 -245t245 -164t298 -61t298 61t245 164t164 245t61 298t-61 298t-164 245t-245 164t-298 61zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="_626" unicode="&#xf29b;" +d="M1438 723q34 -35 29 -82l-44 -551q-4 -42 -34.5 -70t-71.5 -28q-6 0 -9 1q-44 3 -72.5 36.5t-25.5 77.5l35 429l-143 -8q55 -113 55 -240q0 -216 -148 -372l-137 137q91 101 91 235q0 145 -102.5 248t-247.5 103q-134 0 -236 -92l-137 138q120 114 284 141l264 300 +l-149 87l-181 -161q-33 -30 -77 -27.5t-73 35.5t-26.5 77t34.5 73l239 213q26 23 60 26.5t64 -14.5l488 -283q36 -21 48 -68q17 -67 -26 -117l-205 -232l371 20q49 3 83 -32zM1240 1180q-74 0 -126 52t-52 126t52 126t126 52t126.5 -52t52.5 -126t-52.5 -126t-126.5 -52z +M613 -62q106 0 196 61l139 -139q-146 -116 -335 -116q-148 0 -273.5 73t-198.5 198t-73 273q0 188 116 336l139 -139q-60 -88 -60 -197q0 -145 102.5 -247.5t247.5 -102.5z" /> + <glyph glyph-name="_627" unicode="&#xf29c;" +d="M880 336v-160q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h160q14 0 23 -9t9 -23zM1136 832q0 -50 -15 -90t-45.5 -69t-52 -44t-59.5 -36q-32 -18 -46.5 -28t-26 -24t-11.5 -29v-32q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v68q0 35 10.5 64.5 +t24 47.5t39 35.5t41 25.5t44.5 21q53 25 75 43t22 49q0 42 -43.5 71.5t-95.5 29.5q-56 0 -95 -27q-29 -20 -80 -83q-9 -12 -25 -12q-11 0 -19 6l-108 82q-10 7 -12 20t5 23q122 192 349 192q129 0 238.5 -89.5t109.5 -214.5zM768 1280q-130 0 -248.5 -51t-204 -136.5 +t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5 +t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="_628" unicode="&#xf29d;" horiz-adv-x="1408" +d="M366 1225q-64 0 -110 45.5t-46 110.5q0 64 46 109.5t110 45.5t109.5 -45.5t45.5 -109.5q0 -65 -45.5 -110.5t-109.5 -45.5zM917 583q0 -50 -30 -67.5t-63.5 -6.5t-47.5 34l-367 438q-7 12 -14 15.5t-11 1.5l-3 -3q-7 -8 4 -21l122 -139l1 -354l-161 -457 +q-67 -192 -92 -234q-15 -26 -28 -32q-50 -26 -103 -1q-29 13 -41.5 43t-9.5 57q2 17 197 618l5 416l-85 -164l35 -222q4 -24 -1 -42t-14 -27.5t-19 -16t-17 -7.5l-7 -2q-19 -3 -34.5 3t-24 16t-14 22t-7.5 19.5t-2 9.5l-46 299l211 381q23 34 113 34q75 0 107 -40l424 -521 +q7 -5 14 -17l3 -3l-1 -1q7 -13 7 -29zM514 433q43 -113 88.5 -225t69.5 -168l24 -55q36 -93 42 -125q11 -70 -36 -97q-35 -22 -66 -16t-51 22t-29 35h-1q-6 16 -8 25l-124 351zM1338 -159q31 -49 31 -57q0 -5 -3 -7q-9 -5 -14.5 0.5t-15.5 26t-16 30.5q-114 172 -423 661 +q3 -1 7 1t7 4l3 2q11 9 11 17z" /> + <glyph glyph-name="_629" unicode="&#xf29e;" horiz-adv-x="2304" +d="M504 542h171l-1 265zM1530 641q0 87 -50.5 140t-146.5 53h-54v-388h52q91 0 145 57t54 138zM956 1018l1 -756q0 -14 -9.5 -24t-23.5 -10h-216q-14 0 -23.5 10t-9.5 24v62h-291l-55 -81q-10 -15 -28 -15h-267q-21 0 -30.5 18t3.5 35l556 757q9 14 27 14h332q14 0 24 -10 +t10 -24zM1783 641q0 -193 -125.5 -303t-324.5 -110h-270q-14 0 -24 10t-10 24v756q0 14 10 24t24 10h268q200 0 326 -109t126 -302zM1939 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5 +t-7.5 60t-20 91.5t-41 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2123 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-45 -108t-74 -102.5h-51q38 45 66.5 104.5t41.5 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5 +h43q41 -47 72 -107t45.5 -111.5t23 -96t10.5 -70.5zM2304 640q0 -11 -0.5 -29t-8 -71.5t-21.5 -102t-44.5 -108t-73.5 -102.5h-51q38 45 66 104.5t41 112t21 98t9 72.5l1 27q0 8 -0.5 22.5t-7.5 60t-19.5 91.5t-40.5 111.5t-66 124.5h43q41 -47 72 -107t45.5 -111.5t23 -96 +t9.5 -70.5z" /> + <glyph glyph-name="uniF2A0" unicode="&#xf2a0;" horiz-adv-x="1408" +d="M617 -153q0 11 -13 58t-31 107t-20 69q-1 4 -5 26.5t-8.5 36t-13.5 21.5q-15 14 -51 14q-23 0 -70 -5.5t-71 -5.5q-34 0 -47 11q-6 5 -11 15.5t-7.5 20t-6.5 24t-5 18.5q-37 128 -37 255t37 255q1 4 5 18.5t6.5 24t7.5 20t11 15.5q13 11 47 11q24 0 71 -5.5t70 -5.5 +q36 0 51 14q9 8 13.5 21.5t8.5 36t5 26.5q2 9 20 69t31 107t13 58q0 22 -43.5 52.5t-75.5 42.5q-20 8 -45 8q-34 0 -98 -18q-57 -17 -96.5 -40.5t-71 -66t-46 -70t-45.5 -94.5q-6 -12 -9 -19q-49 -107 -68 -216t-19 -244t19 -244t68 -216q56 -122 83 -161q63 -91 179 -127 +l6 -2q64 -18 98 -18q25 0 45 8q32 12 75.5 42.5t43.5 52.5zM776 760q-26 0 -45 19t-19 45.5t19 45.5q37 37 37 90q0 52 -37 91q-19 19 -19 45t19 45t45 19t45 -19q75 -75 75 -181t-75 -181q-21 -19 -45 -19zM957 579q-27 0 -45 19q-19 19 -19 45t19 45q112 114 112 272 +t-112 272q-19 19 -19 45t19 45t45 19t45 -19q150 -150 150 -362t-150 -362q-18 -19 -45 -19zM1138 398q-27 0 -45 19q-19 19 -19 45t19 45q90 91 138.5 208t48.5 245t-48.5 245t-138.5 208q-19 19 -19 45t19 45t45 19t45 -19q109 -109 167 -249t58 -294t-58 -294t-167 -249 +q-18 -19 -45 -19z" /> + <glyph glyph-name="uniF2A1" unicode="&#xf2a1;" horiz-adv-x="2176" +d="M192 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM704 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 352 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 352q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1472 864q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 864 +q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM1984 1376q-66 0 -113 -47t-47 -113t47 -113t113 -47t113 47t47 113t-47 113t-113 47zM384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 192q0 -80 -56 -136 +t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 1216q0 -80 -56 -136t-136 -56 +t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 192q0 -80 -56 -136t-136 -56t-136 56 +t-56 136t56 136t136 56t136 -56t56 -136zM1664 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM2176 704q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136 +t56 136t136 56t136 -56t56 -136zM2176 1216q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z" /> + <glyph glyph-name="uniF2A2" unicode="&#xf2a2;" horiz-adv-x="1792" +d="M128 -192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM320 0q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM365 365l256 -256l-90 -90l-256 256zM704 384q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45z +M1411 704q0 -59 -11.5 -108.5t-37.5 -93.5t-44 -67.5t-53 -64.5q-31 -35 -45.5 -54t-33.5 -50t-26.5 -64t-7.5 -74q0 -159 -112.5 -271.5t-271.5 -112.5q-26 0 -45 19t-19 45t19 45t45 19q106 0 181 75t75 181q0 57 11.5 105.5t37 91t43.5 66.5t52 63q40 46 59.5 72 +t37.5 74.5t18 103.5q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM896 576q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45 +t45 19t45 -19t19 -45zM1184 704q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 93 -65.5 158.5t-158.5 65.5q-92 0 -158 -65.5t-66 -158.5q0 -26 -19 -45t-45 -19t-45 19t-19 45q0 146 103 249t249 103t249 -103t103 -249zM1578 993q10 -25 -1 -49t-36 -34q-9 -4 -23 -4 +q-19 0 -35.5 11t-23.5 30q-68 178 -224 295q-21 16 -25 42t12 47q17 21 43 25t47 -12q183 -137 266 -351zM1788 1074q9 -25 -1.5 -49t-35.5 -34q-11 -4 -23 -4q-44 0 -60 41q-92 238 -297 393q-22 16 -25.5 42t12.5 47q16 22 42 25.5t47 -12.5q235 -175 341 -449z" /> + <glyph glyph-name="uniF2A3" unicode="&#xf2a3;" horiz-adv-x="2304" +d="M1032 576q-59 2 -84 55q-17 34 -48 53.5t-68 19.5q-53 0 -90.5 -37.5t-37.5 -90.5q0 -56 36 -89l10 -8q34 -31 82 -31q37 0 68 19.5t48 53.5q25 53 84 55zM1600 704q0 56 -36 89l-10 8q-34 31 -82 31q-37 0 -68 -19.5t-48 -53.5q-25 -53 -84 -55q59 -2 84 -55 +q17 -34 48 -53.5t68 -19.5q53 0 90.5 37.5t37.5 90.5zM1174 925q-17 -35 -55 -48t-73 4q-62 31 -134 31q-51 0 -99 -17q3 0 9.5 0.5t9.5 0.5q92 0 170.5 -50t118.5 -133q17 -36 3.5 -73.5t-49.5 -54.5q-18 -9 -39 -9q21 0 39 -9q36 -17 49.5 -54.5t-3.5 -73.5 +q-40 -83 -118.5 -133t-170.5 -50h-6q-16 2 -44 4l-290 27l-239 -120q-14 -7 -29 -7q-40 0 -57 35l-160 320q-11 23 -4 47.5t29 37.5l209 119l148 267q17 155 91.5 291.5t195.5 236.5q31 25 70.5 21.5t64.5 -34.5t21.5 -70t-34.5 -65q-70 -59 -117 -128q123 84 267 101 +q40 5 71.5 -19t35.5 -64q5 -40 -19 -71.5t-64 -35.5q-84 -10 -159 -55q46 10 99 10q115 0 218 -50q36 -18 49 -55.5t-5 -73.5zM2137 1085l160 -320q11 -23 4 -47.5t-29 -37.5l-209 -119l-148 -267q-17 -155 -91.5 -291.5t-195.5 -236.5q-26 -22 -61 -22q-45 0 -74 35 +q-25 31 -21.5 70t34.5 65q70 59 117 128q-123 -84 -267 -101q-4 -1 -12 -1q-36 0 -63.5 24t-31.5 60q-5 40 19 71.5t64 35.5q84 10 159 55q-46 -10 -99 -10q-115 0 -218 50q-36 18 -49 55.5t5 73.5q17 35 55 48t73 -4q62 -31 134 -31q51 0 99 17q-3 0 -9.5 -0.5t-9.5 -0.5 +q-92 0 -170.5 50t-118.5 133q-17 36 -3.5 73.5t49.5 54.5q18 9 39 9q-21 0 -39 9q-36 17 -49.5 54.5t3.5 73.5q40 83 118.5 133t170.5 50h6h1q14 -2 42 -4l291 -27l239 120q14 7 29 7q40 0 57 -35z" /> + <glyph glyph-name="uniF2A4" unicode="&#xf2a4;" horiz-adv-x="1792" +d="M1056 704q0 -26 19 -45t45 -19t45 19t19 45q0 146 -103 249t-249 103t-249 -103t-103 -249q0 -26 19 -45t45 -19t45 19t19 45q0 93 66 158.5t158 65.5t158 -65.5t66 -158.5zM835 1280q-117 0 -223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5q0 -26 19 -45t45 -19t45 19 +t19 45q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -55 -18 -103.5t-37.5 -74.5t-59.5 -72q-34 -39 -52 -63t-43.5 -66.5t-37 -91t-11.5 -105.5q0 -106 -75 -181t-181 -75q-26 0 -45 -19t-19 -45t19 -45t45 -19q159 0 271.5 112.5t112.5 271.5q0 41 7.5 74 +t26.5 64t33.5 50t45.5 54q35 41 53 64.5t44 67.5t37.5 93.5t11.5 108.5q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5zM591 561l226 -226l-579 -579q-12 -12 -29 -12t-29 12l-168 168q-12 12 -12 29t12 29zM1612 1524l168 -168q12 -12 12 -29t-12 -30l-233 -233 +l-26 -25l-71 -71q-66 153 -195 258l91 91l207 207q13 12 30 12t29 -12z" /> + <glyph glyph-name="uniF2A5" unicode="&#xf2a5;" +d="M866 1021q0 -27 -13 -94q-11 -50 -31.5 -150t-30.5 -150q-2 -11 -4.5 -12.5t-13.5 -2.5q-20 -2 -31 -2q-58 0 -84 49.5t-26 113.5q0 88 35 174t103 124q28 14 51 14q28 0 36.5 -16.5t8.5 -47.5zM1352 597q0 14 -39 75.5t-52 66.5q-21 8 -34 8q-91 0 -226 -77l-2 2 +q3 22 27.5 135t24.5 178q0 233 -242 233q-24 0 -68 -6q-94 -17 -168.5 -89.5t-111.5 -166.5t-37 -189q0 -146 80.5 -225t227.5 -79q25 0 25 -3t-1 -5q-4 -34 -26 -117q-14 -52 -51.5 -101t-82.5 -49q-42 0 -42 47q0 24 10.5 47.5t25 39.5t29.5 28.5t26 20t11 8.5q0 3 -7 10 +q-24 22 -58.5 36.5t-65.5 14.5q-35 0 -63.5 -34t-41 -75t-12.5 -75q0 -88 51.5 -142t138.5 -54q82 0 155 53t117.5 126t65.5 153q6 22 15.5 66.5t14.5 66.5q3 12 14 18q118 60 227 60q48 0 127 -18q1 -1 4 -1q5 0 9.5 4.5t4.5 8.5zM1536 1120v-960q0 -119 -84.5 -203.5 +t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2A6" unicode="&#xf2a6;" horiz-adv-x="1535" +d="M744 1231q0 24 -2 38.5t-8.5 30t-21 23t-37.5 7.5q-39 0 -78 -23q-105 -58 -159 -190.5t-54 -269.5q0 -44 8.5 -85.5t26.5 -80.5t52.5 -62.5t81.5 -23.5q4 0 18 -0.5t20 0t16 3t15 8.5t7 16q16 77 48 231.5t48 231.5q19 91 19 146zM1498 575q0 -7 -7.5 -13.5t-15.5 -6.5 +l-6 1q-22 3 -62 11t-72 12.5t-63 4.5q-167 0 -351 -93q-15 -8 -21 -27q-10 -36 -24.5 -105.5t-22.5 -100.5q-23 -91 -70 -179.5t-112.5 -164.5t-154.5 -123t-185 -47q-135 0 -214.5 83.5t-79.5 219.5q0 53 19.5 117t63 116.5t97.5 52.5q38 0 120 -33.5t83 -61.5 +q0 -1 -16.5 -12.5t-39.5 -31t-46 -44.5t-39 -61t-16 -74q0 -33 16.5 -53t48.5 -20q45 0 85 31.5t66.5 78t48 105.5t32.5 107t16 90v9q0 2 -3.5 3.5t-8.5 1.5h-10t-10 -0.5t-6 -0.5q-227 0 -352 122.5t-125 348.5q0 108 34.5 221t96 210t156 167.5t204.5 89.5q52 9 106 9 +q374 0 374 -360q0 -98 -38 -273t-43 -211l3 -3q101 57 182.5 88t167.5 31q22 0 53 -13q19 -7 80 -102.5t61 -116.5z" /> + <glyph glyph-name="uniF2A7" unicode="&#xf2a7;" horiz-adv-x="1664" +d="M831 863q32 0 59 -18l222 -148q61 -40 110 -97l146 -170q40 -46 29 -106l-72 -413q-6 -32 -29.5 -53.5t-55.5 -25.5l-527 -56l-352 -32h-9q-39 0 -67.5 28t-28.5 68q0 37 27 64t65 32l260 32h-448q-41 0 -69.5 30t-26.5 71q2 39 32 65t69 26l442 1l-521 64q-41 5 -66 37 +t-19 73q6 35 34.5 57.5t65.5 22.5h10l481 -60l-351 94q-38 10 -62 41.5t-18 68.5q6 36 33 58.5t62 22.5q6 0 20 -2l448 -96l217 -37q1 0 3 -0.5t3 -0.5q23 0 30.5 23t-12.5 36l-186 125q-35 23 -42 63.5t18 73.5q27 38 76 38zM761 661l186 -125l-218 37l-5 2l-36 38 +l-238 262q-1 1 -2.5 3.5t-2.5 3.5q-24 31 -18.5 70t37.5 64q31 23 68 17.5t64 -33.5l142 -147q-2 -1 -5 -3.5t-4 -4.5q-32 -45 -23 -99t55 -85zM1648 1115l15 -266q4 -73 -11 -147l-48 -219q-12 -59 -67 -87l-106 -54q2 62 -39 109l-146 170q-53 61 -117 103l-222 148 +q-34 23 -76 23q-51 0 -88 -37l-235 312q-25 33 -18 73.5t41 63.5q33 22 71.5 14t62.5 -40l266 -352l-262 455q-21 35 -10.5 75t47.5 59q35 18 72.5 6t57.5 -46l241 -420l-136 337q-15 35 -4.5 74t44.5 56q37 19 76 6t56 -51l193 -415l101 -196q8 -15 23 -17.5t27 7.5t11 26 +l-12 224q-2 41 26 71t69 31q39 0 67 -28.5t30 -67.5z" /> + <glyph glyph-name="uniF2A8" unicode="&#xf2a8;" horiz-adv-x="1792" +d="M335 180q-2 0 -6 2q-86 57 -168.5 145t-139.5 180q-21 30 -21 69q0 9 2 19t4 18t7 18t8.5 16t10.5 17t10 15t12 15.5t11 14.5q184 251 452 365q-110 198 -110 211q0 19 17 29q116 64 128 64q18 0 28 -16l124 -229q92 19 192 19q266 0 497.5 -137.5t378.5 -369.5 +q20 -31 20 -69t-20 -69q-91 -142 -218.5 -253.5t-278.5 -175.5q110 -198 110 -211q0 -20 -17 -29q-116 -64 -127 -64q-19 0 -29 16l-124 229l-64 119l-444 820l7 7q-58 -24 -99 -47q3 -5 127 -234t243 -449t119 -223q0 -7 -9 -9q-13 -3 -72 -3q-57 0 -60 7l-456 841 +q-39 -28 -82 -68q24 -43 214 -393.5t190 -354.5q0 -10 -11 -10q-14 0 -82.5 22t-72.5 28l-106 197l-224 413q-44 -53 -78 -106q2 -3 18 -25t23 -34l176 -327q0 -10 -10 -10zM1165 282l49 -91q273 111 450 385q-180 277 -459 389q67 -64 103 -148.5t36 -176.5 +q0 -106 -47 -200.5t-132 -157.5zM848 896q0 -20 14 -34t34 -14q86 0 147 -61t61 -147q0 -20 14 -34t34 -14t34 14t14 34q0 126 -89 215t-215 89q-20 0 -34 -14t-14 -34zM1214 961l-9 4l7 -7z" /> + <glyph glyph-name="uniF2A9" unicode="&#xf2a9;" horiz-adv-x="1280" +d="M1050 430q0 -215 -147 -374q-148 -161 -378 -161q-232 0 -378 161q-147 159 -147 374q0 147 68 270.5t189 196.5t268 73q96 0 182 -31q-32 -62 -39 -126q-66 28 -143 28q-167 0 -280.5 -123t-113.5 -291q0 -170 112.5 -288.5t281.5 -118.5t281 118.5t112 288.5 +q0 89 -32 166q66 13 123 49q41 -98 41 -212zM846 619q0 -192 -79.5 -345t-238.5 -253l-14 -1q-29 0 -62 5q83 32 146.5 102.5t99.5 154.5t58.5 189t30 192.5t7.5 178.5q0 69 -3 103q55 -160 55 -326zM791 947v-2q-73 214 -206 440q88 -59 142.5 -186.5t63.5 -251.5z +M1035 744q-83 0 -160 75q218 120 290 247q19 37 21 56q-42 -94 -139.5 -166.5t-204.5 -97.5q-35 54 -35 113q0 37 17 79t43 68q46 44 157 74q59 16 106 58.5t74 100.5q74 -105 74 -253q0 -109 -24 -170q-32 -77 -88.5 -130.5t-130.5 -53.5z" /> + <glyph glyph-name="uniF2AA" unicode="&#xf2aa;" +d="M1050 495q0 78 -28 147q-41 -25 -85 -34q22 -50 22 -114q0 -117 -77 -198.5t-193 -81.5t-193.5 81.5t-77.5 198.5q0 115 78 199.5t193 84.5q53 0 98 -19q4 43 27 87q-60 21 -125 21q-154 0 -257.5 -108.5t-103.5 -263.5t103.5 -261t257.5 -106t257.5 106.5t103.5 260.5z +M872 850q2 -24 2 -71q0 -63 -5 -123t-20.5 -132.5t-40.5 -130t-68.5 -106t-100.5 -70.5q21 -3 42 -3h10q219 139 219 411q0 116 -38 225zM872 850q-4 80 -44 171.5t-98 130.5q92 -156 142 -302zM1207 955q0 102 -51 174q-41 -86 -124 -109q-69 -19 -109 -53.5t-40 -99.5 +q0 -40 24 -77q74 17 140.5 67t95.5 115q-4 -52 -74.5 -111.5t-138.5 -97.5q52 -52 110 -52q51 0 90 37t60 90q17 42 17 117zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 +t84.5 -203.5z" /> + <glyph glyph-name="uniF2AB" unicode="&#xf2ab;" +d="M1279 388q0 22 -22 27q-67 15 -118 59t-80 108q-7 19 -7 25q0 15 19.5 26t43 17t43 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-12 0 -32 -8t-31 -8q-4 0 -12 2q5 95 5 114q0 79 -17 114q-36 78 -103 121.5t-152 43.5q-199 0 -275 -165q-17 -35 -17 -114q0 -19 5 -114 +q-4 -2 -14 -2q-12 0 -32 7.5t-30 7.5q-21 0 -38.5 -12t-17.5 -32q0 -21 19.5 -35.5t43 -20.5t43 -17t19.5 -26q0 -6 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -46 137 -68q2 -5 6 -26t11.5 -30.5t23.5 -9.5q12 0 37.5 4.5t39.5 4.5q35 0 67 -15t54 -32.5t57.5 -32.5 +t76.5 -15q43 0 79 15t57.5 32.5t53.5 32.5t67 15q14 0 39.5 -4t38.5 -4q16 0 23 10t11 30t6 25q137 22 137 68zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 +t103 -385.5z" /> + <glyph glyph-name="uniF2AC" unicode="&#xf2ac;" horiz-adv-x="1664" +d="M848 1408q134 1 240.5 -68.5t163.5 -192.5q27 -58 27 -179q0 -47 -9 -191q14 -7 28 -7q18 0 51 13.5t51 13.5q29 0 56 -18t27 -46q0 -32 -31.5 -54t-69 -31.5t-69 -29t-31.5 -47.5q0 -15 12 -43q37 -82 102.5 -150t144.5 -101q28 -12 80 -23q28 -6 28 -35 +q0 -70 -219 -103q-7 -11 -11 -39t-14 -46.5t-33 -18.5q-20 0 -62 6.5t-64 6.5q-37 0 -62 -5q-32 -5 -63 -22.5t-58 -38t-58 -40.5t-76 -33.5t-99 -13.5q-52 0 -96.5 13.5t-75 33.5t-57.5 40.5t-58 38t-62 22.5q-26 5 -63 5q-24 0 -65.5 -7.5t-58.5 -7.5q-25 0 -35 18.5 +t-14 47.5t-11 40q-219 33 -219 103q0 29 28 35q52 11 80 23q78 32 144.5 101t102.5 150q12 28 12 43q0 28 -31.5 47.5t-69.5 29.5t-69.5 31.5t-31.5 52.5q0 27 26 45.5t55 18.5q15 0 48 -13t53 -13q18 0 32 7q-9 142 -9 190q0 122 27 180q64 137 172 198t264 63z" /> + <glyph glyph-name="uniF2AD" unicode="&#xf2ad;" +d="M1280 388q0 22 -22 27q-67 14 -118 58t-80 109q-7 14 -7 25q0 15 19.5 26t42.5 17t42.5 20.5t19.5 36.5q0 19 -18.5 31.5t-38.5 12.5q-11 0 -31 -8t-32 -8q-4 0 -12 2q5 63 5 115q0 78 -17 114q-36 78 -102.5 121.5t-152.5 43.5q-198 0 -275 -165q-18 -38 -18 -115 +q0 -38 6 -114q-10 -2 -15 -2q-11 0 -31.5 8t-30.5 8q-20 0 -37.5 -12.5t-17.5 -32.5q0 -21 19.5 -35.5t42.5 -20.5t42.5 -17t19.5 -26q0 -11 -7 -25q-64 -138 -198 -167q-22 -5 -22 -27q0 -47 138 -69q2 -5 6 -26t11 -30.5t23 -9.5q13 0 38.5 5t38.5 5q35 0 67.5 -15 +t54.5 -32.5t57.5 -32.5t76.5 -15q43 0 79 15t57.5 32.5t54 32.5t67.5 15q13 0 39 -4.5t39 -4.5q15 0 22.5 9.5t11.5 31t5 24.5q138 22 138 69zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 +q119 0 203.5 -84.5t84.5 -203.5z" /> + <glyph glyph-name="uniF2AE" unicode="&#xf2ae;" horiz-adv-x="2304" +d="M2304 1536q-69 -46 -125 -92t-89 -81t-59.5 -71.5t-37.5 -57.5t-22 -44.5t-14 -29.5q-10 -18 -35.5 -136.5t-48.5 -164.5q-15 -29 -50 -60.5t-67.5 -50.5t-72.5 -41t-48 -28q-47 -31 -151 -231q-341 14 -630 -158q-92 -53 -303 -179q47 16 86 31t55 22l15 7 +q71 27 163 64.5t133.5 53.5t108 34.5t142.5 31.5q186 31 465 -7q1 0 10 -3q11 -6 14 -17t-3 -22l-194 -345q-15 -29 -47 -22q-128 24 -354 24q-146 0 -402 -44.5t-392 -46.5q-82 -1 -149 13t-107 37t-61 40t-33 34l-1 1v2q0 6 6 6q138 0 371 55q192 366 374.5 524t383.5 158 +q5 0 14.5 -0.5t38 -5t55 -12t61.5 -24.5t63 -39.5t54 -59t40 -82.5l102 177q2 4 21 42.5t44.5 86.5t61 109.5t84 133.5t100.5 137q66 82 128 141.5t121.5 96.5t92.5 53.5t88 39.5z" /> + <glyph glyph-name="uniF2B0" unicode="&#xf2b0;" +d="M1322 640q0 -45 -5 -76l-236 14l224 -78q-19 -73 -58 -141l-214 103l177 -158q-44 -61 -107 -108l-157 178l103 -215q-61 -37 -140 -59l-79 228l14 -240q-38 -6 -76 -6t-76 6l14 238l-78 -226q-74 19 -140 59l103 215l-157 -178q-59 43 -108 108l178 158l-214 -104 +q-39 69 -58 141l224 79l-237 -14q-5 42 -5 76q0 35 5 77l238 -14l-225 79q19 73 58 140l214 -104l-177 159q46 61 107 108l158 -178l-103 215q67 39 140 58l77 -224l-13 236q36 6 75 6q38 0 76 -6l-14 -237l78 225q74 -19 140 -59l-103 -214l158 178q61 -47 107 -108 +l-177 -159l213 104q37 -62 58 -141l-224 -78l237 14q5 -31 5 -77zM1352 640q0 160 -78.5 295.5t-213 214t-292.5 78.5q-119 0 -227 -46.5t-186.5 -125t-124.5 -187.5t-46 -229q0 -119 46 -228t124.5 -187.5t186.5 -125t227 -46.5q158 0 292.5 78.5t213 214t78.5 294.5z +M1425 1023v-766l-657 -383l-657 383v766l657 383zM768 -183l708 412v823l-708 411l-708 -411v-823zM1536 1088v-896l-768 -448l-768 448v896l768 448z" /> + <glyph glyph-name="uniF2B1" unicode="&#xf2b1;" horiz-adv-x="1664" +d="M339 1318h691l-26 -72h-665q-110 0 -188.5 -79t-78.5 -189v-771q0 -95 60.5 -169.5t153.5 -93.5q23 -5 98 -5v-72h-45q-140 0 -239.5 100t-99.5 240v771q0 140 99.5 240t239.5 100zM1190 1536h247l-482 -1294q-23 -61 -40.5 -103.5t-45 -98t-54 -93.5t-64.5 -78.5 +t-79.5 -65t-95.5 -41t-116 -18.5v195q163 26 220 182q20 52 20 105q0 54 -20 106l-285 733h228l187 -585zM1664 978v-1111h-795q37 55 45 73h678v1038q0 85 -49.5 155t-129.5 99l25 67q101 -34 163.5 -123.5t62.5 -197.5z" /> + <glyph glyph-name="uniF2B2" unicode="&#xf2b2;" horiz-adv-x="1792" +d="M852 1227q0 -29 -17 -52.5t-45 -23.5t-45 23.5t-17 52.5t17 52.5t45 23.5t45 -23.5t17 -52.5zM688 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50 -21.5t-20 -51.5v-114q0 -30 20.5 -52t49.5 -22q30 0 50.5 22t20.5 52zM860 -149v114q0 30 -20 51.5t-50 21.5t-50.5 -21.5 +t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22q29 0 49.5 22t20.5 52zM1034 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1208 -149v114q0 30 -20.5 51.5t-50.5 21.5t-50.5 -21.5t-20.5 -51.5v-114 +q0 -30 20.5 -52t50.5 -22t50.5 22t20.5 52zM1476 535q-84 -160 -232 -259.5t-323 -99.5q-123 0 -229.5 51.5t-178.5 137t-113 197.5t-41 232q0 88 21 174q-104 -175 -104 -390q0 -162 65 -312t185 -251q30 57 91 57q56 0 86 -50q32 50 87 50q56 0 86 -50q32 50 87 50t87 -50 +q30 50 86 50q28 0 52.5 -15.5t37.5 -40.5q112 94 177 231.5t73 287.5zM1326 564q0 75 -72 75q-17 0 -47 -6q-95 -19 -149 -19q-226 0 -226 243q0 86 30 204q-83 -127 -83 -275q0 -150 89 -260.5t235 -110.5q111 0 210 70q13 48 13 79zM884 1223q0 50 -32 89.5t-81 39.5 +t-81 -39.5t-32 -89.5q0 -51 31.5 -90.5t81.5 -39.5t81.5 39.5t31.5 90.5zM1513 884q0 96 -37.5 179t-113 137t-173.5 54q-77 0 -149 -35t-127 -94q-48 -159 -48 -268q0 -104 45.5 -157t147.5 -53q53 0 142 19q36 6 53 6q51 0 77.5 -28t26.5 -80q0 -26 -4 -46 +q75 68 117.5 165.5t42.5 200.5zM1792 667q0 -111 -33.5 -249.5t-93.5 -204.5q-58 -64 -195 -142.5t-228 -104.5l-4 -1v-114q0 -43 -29.5 -75t-72.5 -32q-56 0 -86 50q-32 -50 -87 -50t-87 50q-30 -50 -86 -50q-55 0 -87 50q-30 -50 -86 -50q-47 0 -75 33.5t-28 81.5 +q-90 -68 -198 -68q-118 0 -211 80q54 1 106 20q-113 31 -182 127q32 -7 71 -7q89 0 164 46q-192 192 -240 306q-24 56 -24 160q0 57 9 125.5t31.5 146.5t55 141t86.5 105t120 42q59 0 81 -52q19 29 42 54q2 3 12 13t13 16q10 15 23 38t25 42t28 39q87 111 211.5 177 +t260.5 66q35 0 62 -4q59 64 146 64q83 0 140 -57q5 -5 5 -12q0 -5 -6 -13.5t-12.5 -16t-16 -17l-10.5 -10.5q17 -6 36 -18t19 -24q0 -6 -16 -25q157 -138 197 -378q25 30 60 30q45 0 100 -49q90 -80 90 -279z" /> + <glyph glyph-name="uniF2B3" unicode="&#xf2b3;" +d="M917 631q0 33 -6 64h-362v-132h217q-12 -76 -74.5 -120.5t-142.5 -44.5q-99 0 -169 71.5t-70 170.5t70 170.5t169 71.5q93 0 153 -59l104 101q-108 100 -257 100q-160 0 -272 -112.5t-112 -271.5t112 -271.5t272 -112.5q165 0 266.5 105t101.5 270zM1262 585h109v110 +h-109v110h-110v-110h-110v-110h110v-110h110v110zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> + <glyph glyph-name="uniF2B4" unicode="&#xf2b4;" +d="M1536 1024v-839q0 -48 -49 -62q-174 -52 -338 -52q-73 0 -215.5 29.5t-227.5 29.5q-164 0 -370 -48v-338h-160v1368q-63 25 -101 81t-38 124q0 91 64 155t155 64t155 -64t64 -155q0 -68 -38 -124t-101 -81v-68q190 44 343 44q99 0 198 -15q14 -2 111.5 -22.5t149.5 -20.5 +q77 0 165 18q11 2 80 21t89 19q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B5" unicode="&#xf2b5;" horiz-adv-x="2304" +d="M192 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32zM1665 442q-10 13 -38.5 50t-41.5 54t-38 49t-42.5 53t-40.5 47t-45 49l-125 -140q-83 -94 -208.5 -92t-205.5 98q-57 69 -56.5 158t58.5 157l177 206q-22 11 -51 16.5t-47.5 6t-56.5 -0.5t-49 -1q-92 0 -158 -66 +l-158 -158h-155v-544q5 0 21 0.5t22 0t19.5 -2t20.5 -4.5t17.5 -8.5t18.5 -13.5l297 -292q115 -111 227 -111q78 0 125 47q57 -20 112.5 8t72.5 85q74 -6 127 44q20 18 36 45.5t14 50.5q10 -10 43 -10q43 0 77 21t49.5 53t12 71.5t-30.5 73.5zM1824 384h96v512h-93l-157 180 +q-66 76 -169 76h-167q-89 0 -146 -67l-209 -243q-28 -33 -28 -75t27 -75q43 -51 110 -52t111 49l193 218q25 23 53.5 21.5t47 -27t8.5 -56.5q16 -19 56 -63t60 -68q29 -36 82.5 -105.5t64.5 -84.5q52 -66 60 -140zM2112 384q40 0 56 32t0 64t-56 32t-56 -32t0 -64t56 -32z +M2304 960v-640q0 -26 -19 -45t-45 -19h-434q-27 -65 -82 -106.5t-125 -51.5q-33 -48 -80.5 -81.5t-102.5 -45.5q-42 -53 -104.5 -81.5t-128.5 -24.5q-60 -34 -126 -39.5t-127.5 14t-117 53.5t-103.5 81l-287 282h-358q-26 0 -45 19t-19 45v672q0 26 19 45t45 19h421 +q14 14 47 48t47.5 48t44 40t50.5 37.5t51 25.5t62 19.5t68 5.5h117q99 0 181 -56q82 56 181 56h167q35 0 67 -6t56.5 -14.5t51.5 -26.5t44.5 -31t43 -39.5t39 -42t41 -48t41.5 -48.5h355q26 0 45 -19t19 -45z" /> + <glyph glyph-name="uniF2B6" unicode="&#xf2b6;" horiz-adv-x="1792" +d="M1792 882v-978q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v978q0 15 11 24q8 7 39 34.5t41.5 36t45.5 37.5t70 55.5t96 73t143.5 107t192.5 140.5q5 4 52.5 40t71.5 52.5t64 35t69 18.5t69 -18.5t65 -35.5t71 -52t52 -40q110 -80 192.5 -140.5t143.5 -107 +t96 -73t70 -55.5t45.5 -37.5t41.5 -36t39 -34.5q11 -9 11 -24zM1228 297q263 191 345 252q11 8 12.5 20.5t-6.5 23.5l-38 52q-8 11 -21 12.5t-24 -6.5q-231 -169 -343 -250q-5 -3 -52 -39t-71.5 -52.5t-64.5 -35t-69 -18.5t-69 18.5t-64.5 35t-71.5 52.5t-52 39 +q-186 134 -343 250q-11 8 -24 6.5t-21 -12.5l-38 -52q-8 -11 -6.5 -23.5t12.5 -20.5q82 -61 345 -252q10 -8 50 -38t65 -47t64 -39.5t77.5 -33.5t75.5 -11t75.5 11t79 34.5t64.5 39.5t65 47.5t48 36.5z" /> + <glyph glyph-name="uniF2B7" unicode="&#xf2b7;" horiz-adv-x="1792" +d="M1474 623l39 -51q8 -11 6.5 -23.5t-11.5 -20.5q-43 -34 -126.5 -98.5t-146.5 -113t-67 -51.5q-39 -32 -60 -48t-60.5 -41t-76.5 -36.5t-74 -11.5h-1h-1q-37 0 -74 11.5t-76 36.5t-61 41.5t-60 47.5q-5 4 -65 50.5t-143.5 111t-122.5 94.5q-11 8 -12.5 20.5t6.5 23.5 +l37 52q8 11 21.5 13t24.5 -7q94 -73 306 -236q5 -4 43.5 -35t60.5 -46.5t56.5 -32.5t58.5 -17h1h1q24 0 58.5 17t56.5 32.5t60.5 46.5t43.5 35q258 198 313 242q11 8 24 6.5t21 -12.5zM1664 -96v928q-90 83 -159 139q-91 74 -389 304q-3 2 -43 35t-61 48t-56 32.5t-59 17.5 +h-1h-1q-24 0 -59 -17.5t-56 -32.5t-61 -48t-43 -35q-215 -166 -315.5 -245.5t-129.5 -104t-82 -74.5q-14 -12 -21 -19v-928q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 832v-928q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v928q0 56 41 94 +q123 114 350 290.5t233 181.5q36 30 59 47.5t61.5 42t76 36.5t74.5 12h1h1q37 0 74.5 -12t76 -36.5t61.5 -42t59 -47.5q43 -36 156 -122t226 -177t201 -173q41 -38 41 -94z" /> + <glyph glyph-name="uniF2B8" unicode="&#xf2b8;" +d="M330 1l202 -214l-34 236l-216 213zM556 -225l274 218l-11 245l-300 -215zM245 413l227 -213l-48 327l-245 204zM495 189l317 214l-14 324l-352 -200zM843 178l95 -80l-2 239l-103 79q0 -1 1 -8.5t0 -12t-5 -7.5l-78 -52l85 -70q7 -6 7 -88zM138 930l256 -200l-68 465 +l-279 173zM1173 267l15 234l-230 -164l2 -240zM417 722l373 194l-19 441l-423 -163zM1270 357l20 233l-226 142l-2 -105l144 -95q6 -4 4 -9l-7 -119zM1461 496l30 222l-179 -128l-20 -228zM1273 329l-71 49l-8 -117q0 -5 -4 -8l-234 -187q-7 -5 -14 0l-98 83l7 -161 +q0 -5 -4 -8l-293 -234q-4 -2 -6 -2q-8 2 -8 3l-228 242q-4 4 -59 277q-2 7 5 11l61 37q-94 86 -95 92l-72 351q-2 7 6 12l94 45q-133 100 -135 108l-96 466q-2 10 7 13l433 135q5 0 8 -1l317 -153q6 -4 6 -9l20 -463q0 -7 -6 -10l-118 -61l126 -85q5 -2 5 -8l5 -123l121 74 +q5 4 11 0l84 -56l3 110q0 6 5 9l206 126q6 3 11 0l245 -135q4 -4 5 -7t-6.5 -60t-17.5 -124.5t-10 -70.5q0 -5 -4 -7l-191 -153q-6 -5 -13 0z" /> + <glyph glyph-name="uniF2B9" unicode="&#xf2b9;" horiz-adv-x="1664" +d="M1201 298q0 57 -5.5 107t-21 100.5t-39.5 86t-64 58t-91 22.5q-6 -4 -33.5 -20.5t-42.5 -24.5t-40.5 -20t-49 -17t-46.5 -5t-46.5 5t-49 17t-40.5 20t-42.5 24.5t-33.5 20.5q-51 0 -91 -22.5t-64 -58t-39.5 -86t-21 -100.5t-5.5 -107q0 -73 42 -121.5t103 -48.5h576 +q61 0 103 48.5t42 121.5zM1028 892q0 108 -76.5 184t-183.5 76t-183.5 -76t-76.5 -184q0 -107 76.5 -183t183.5 -76t183.5 76t76.5 183zM1664 352v-192q0 -14 -9 -23t-23 -9h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216 +q66 0 113 -47t47 -113v-224h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-96v-128h96q14 0 23 -9t9 -23z" /> + <glyph glyph-name="uniF2BA" unicode="&#xf2ba;" horiz-adv-x="1664" +d="M1028 892q0 -107 -76.5 -183t-183.5 -76t-183.5 76t-76.5 183q0 108 76.5 184t183.5 76t183.5 -76t76.5 -184zM980 672q46 0 82.5 -17t60 -47.5t39.5 -67t24 -81t11.5 -82.5t3.5 -79q0 -67 -39.5 -118.5t-105.5 -51.5h-576q-66 0 -105.5 51.5t-39.5 118.5q0 48 4.5 93.5 +t18.5 98.5t36.5 91.5t63 64.5t93.5 26h5q7 -4 32 -19.5t35.5 -21t33 -17t37 -16t35 -9t39.5 -4.5t39.5 4.5t35 9t37 16t33 17t35.5 21t32 19.5zM1664 928q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-128h96 +q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-96v-224q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h1216q66 0 113 -47t47 -113v-224h96q13 0 22.5 -9.5t9.5 -22.5v-192zM1408 -96v1472q0 13 -9.5 22.5t-22.5 9.5h-1216 +q-13 0 -22.5 -9.5t-9.5 -22.5v-1472q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5z" /> + <glyph glyph-name="uniF2BB" unicode="&#xf2bb;" horiz-adv-x="2048" +d="M1024 405q0 64 -9 117.5t-29.5 103t-60.5 78t-97 28.5q-6 -4 -30 -18t-37.5 -21.5t-35.5 -17.5t-43 -14.5t-42 -4.5t-42 4.5t-43 14.5t-35.5 17.5t-37.5 21.5t-30 18q-57 0 -97 -28.5t-60.5 -78t-29.5 -103t-9 -117.5t37 -106.5t91 -42.5h512q54 0 91 42.5t37 106.5z +M867 925q0 94 -66.5 160.5t-160.5 66.5t-160.5 -66.5t-66.5 -160.5t66.5 -160.5t160.5 -66.5t160.5 66.5t66.5 160.5zM1792 416v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM1792 676v56q0 15 -10.5 25.5t-25.5 10.5h-568 +q-15 0 -25.5 -10.5t-10.5 -25.5v-56q0 -15 10.5 -25.5t25.5 -10.5h568q15 0 25.5 10.5t10.5 25.5zM1792 928v64q0 14 -9 23t-23 9h-576q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h576q14 0 23 9t9 23zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-352v96q0 14 -9 23t-23 9 +h-64q-14 0 -23 -9t-9 -23v-96h-768v96q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-96h-352q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BC" unicode="&#xf2bc;" horiz-adv-x="2048" +d="M1024 405q0 -64 -37 -106.5t-91 -42.5h-512q-54 0 -91 42.5t-37 106.5t9 117.5t29.5 103t60.5 78t97 28.5q6 -4 30 -18t37.5 -21.5t35.5 -17.5t43 -14.5t42 -4.5t42 4.5t43 14.5t35.5 17.5t37.5 21.5t30 18q57 0 97 -28.5t60.5 -78t29.5 -103t9 -117.5zM867 925 +q0 -94 -66.5 -160.5t-160.5 -66.5t-160.5 66.5t-66.5 160.5t66.5 160.5t160.5 66.5t160.5 -66.5t66.5 -160.5zM1792 480v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1792 732v-56q0 -15 -10.5 -25.5t-25.5 -10.5h-568 +q-15 0 -25.5 10.5t-10.5 25.5v56q0 15 10.5 25.5t25.5 10.5h568q15 0 25.5 -10.5t10.5 -25.5zM1792 992v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576q14 0 23 -9t9 -23zM1920 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1728q-13 0 -22.5 -9.5 +t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h352v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h768v96q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-96h352q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113 +t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2BD" unicode="&#xf2bd;" horiz-adv-x="1792" +d="M1523 197q-22 155 -87.5 257.5t-184.5 118.5q-67 -74 -159.5 -115.5t-195.5 -41.5t-195.5 41.5t-159.5 115.5q-119 -16 -184.5 -118.5t-87.5 -257.5q106 -150 271 -237.5t356 -87.5t356 87.5t271 237.5zM1280 896q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5 +t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1792 640q0 -182 -71 -347.5t-190.5 -286t-285.5 -191.5t-349 -71q-182 0 -348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2BE" unicode="&#xf2be;" horiz-adv-x="1792" +d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348q0 -181 -70.5 -347t-190.5 -286t-286 -191.5t-349 -71.5t-349 71t-285.5 191.5t-190.5 286t-71 347.5t71 348t191 286t286 191t348 71zM1515 185q149 205 149 455q0 156 -61 298t-164 245t-245 164t-298 61t-298 -61 +t-245 -164t-164 -245t-61 -298q0 -250 149 -455q66 327 306 327q131 -128 313 -128t313 128q240 0 306 -327zM1280 832q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5z" /> + <glyph glyph-name="uniF2C0" unicode="&#xf2c0;" +d="M1201 752q47 -14 89.5 -38t89 -73t79.5 -115.5t55 -172t22 -236.5q0 -154 -100 -263.5t-241 -109.5h-854q-141 0 -241 109.5t-100 263.5q0 131 22 236.5t55 172t79.5 115.5t89 73t89.5 38q-79 125 -79 272q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5 +t198.5 -40.5t163.5 -109.5t109.5 -163.5t40.5 -198.5q0 -147 -79 -272zM768 1408q-159 0 -271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5zM1195 -128q88 0 150.5 71.5t62.5 173.5q0 239 -78.5 377t-225.5 145 +q-145 -127 -336 -127t-336 127q-147 -7 -225.5 -145t-78.5 -377q0 -102 62.5 -173.5t150.5 -71.5h854z" /> + <glyph glyph-name="uniF2C1" unicode="&#xf2c1;" horiz-adv-x="1280" +d="M1024 278q0 -64 -37 -107t-91 -43h-512q-54 0 -91 43t-37 107t9 118t29.5 104t61 78.5t96.5 28.5q80 -75 188 -75t188 75q56 0 96.5 -28.5t61 -78.5t29.5 -104t9 -118zM870 797q0 -94 -67.5 -160.5t-162.5 -66.5t-162.5 66.5t-67.5 160.5t67.5 160.5t162.5 66.5 +t162.5 -66.5t67.5 -160.5zM1152 -96v1376h-1024v-1376q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1280 1376v-1472q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v1472q0 66 47 113t113 47h352v-96q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v96h352 +q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C2" unicode="&#xf2c2;" horiz-adv-x="2048" +d="M896 324q0 54 -7.5 100.5t-24.5 90t-51 68.5t-81 25q-64 -64 -156 -64t-156 64q-47 0 -81 -25t-51 -68.5t-24.5 -90t-7.5 -100.5q0 -55 31.5 -93.5t75.5 -38.5h426q44 0 75.5 38.5t31.5 93.5zM768 768q0 80 -56 136t-136 56t-136 -56t-56 -136t56 -136t136 -56t136 56 +t56 136zM1792 288v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1408 544v64q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1792 544v64q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23 +v-64q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1792 800v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM128 1152h1792v96q0 14 -9 23t-23 9h-1728q-14 0 -23 -9t-9 -23v-96zM2048 1248v-1216q0 -66 -47 -113t-113 -47h-1728 +q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C3" unicode="&#xf2c3;" horiz-adv-x="2048" +d="M896 324q0 -55 -31.5 -93.5t-75.5 -38.5h-426q-44 0 -75.5 38.5t-31.5 93.5q0 54 7.5 100.5t24.5 90t51 68.5t81 25q64 -64 156 -64t156 64q47 0 81 -25t51 -68.5t24.5 -90t7.5 -100.5zM768 768q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136z +M1792 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1408 608v-64q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h320q14 0 23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v64 +q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 864v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1920 32v1120h-1792v-1120q0 -13 9.5 -22.5t22.5 -9.5h1728q13 0 22.5 9.5t9.5 22.5zM2048 1248v-1216q0 -66 -47 -113t-113 -47 +h-1728q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1728q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2C4" unicode="&#xf2c4;" horiz-adv-x="1792" +d="M1255 749q0 318 -105 474.5t-330 156.5q-222 0 -326 -157t-104 -474q0 -316 104 -471.5t326 -155.5q74 0 131 17q-22 43 -39 73t-44 65t-53.5 56.5t-63 36t-77.5 14.5q-46 0 -79 -16l-49 97q105 91 276 91q132 0 215.5 -54t150.5 -155q67 149 67 402zM1645 117h117 +q3 -27 -2 -67t-26.5 -95t-58 -100.5t-107 -78t-162.5 -32.5q-71 0 -130.5 19t-105.5 56t-79 78t-66 96q-97 -27 -205 -27q-150 0 -292.5 58t-253 158.5t-178 249t-67.5 317.5q0 170 67.5 319.5t178.5 250.5t253.5 159t291.5 58q121 0 238.5 -36t217 -106t176 -164.5 +t119.5 -219t43 -261.5q0 -190 -80.5 -347.5t-218.5 -264.5q47 -70 93.5 -106.5t104.5 -36.5q61 0 94 37.5t38 85.5z" /> + <glyph glyph-name="uniF2C5" unicode="&#xf2c5;" horiz-adv-x="2304" +d="M453 -101q0 -21 -16 -37.5t-37 -16.5q-1 0 -13 3q-63 15 -162 140q-225 284 -225 676q0 341 213 614q39 51 95 103.5t94 52.5q19 0 35 -13.5t16 -32.5q0 -27 -63 -90q-98 -102 -147 -184q-119 -199 -119 -449q0 -281 123 -491q50 -85 136 -173q2 -3 14.5 -16t19.5 -21 +t17 -20.5t14.5 -23.5t4.5 -21zM1796 33q0 -29 -17.5 -48.5t-46.5 -19.5h-1081q-26 0 -45 19t-19 45q0 29 17.5 48.5t46.5 19.5h1081q26 0 45 -19t19 -45zM1581 644q0 -134 -67 -233q-25 -38 -69.5 -78.5t-83.5 -60.5q-16 -10 -27 -10q-7 0 -15 6t-8 12q0 9 19 30t42 46 +t42 67.5t19 88.5q0 76 -35 130q-29 42 -46 42q-3 0 -3 -5q0 -12 7.5 -35.5t7.5 -36.5q0 -22 -21.5 -35t-44.5 -13q-66 0 -66 76q0 15 1.5 44t1.5 44q0 25 -10 46q-13 25 -42 53.5t-51 28.5q-5 0 -7 -0.5t-3.5 -2.5t-1.5 -6q0 -2 16 -26t16 -54q0 -37 -19 -68t-46 -54 +t-53.5 -46t-45.5 -54t-19 -68q0 -98 42 -160q29 -43 79 -63q16 -5 17 -10q1 -2 1 -5q0 -16 -18 -16q-6 0 -33 11q-119 43 -195 139.5t-76 218.5q0 55 24.5 115.5t60 115t70.5 108.5t59.5 113.5t24.5 111.5q0 53 -25 94q-29 48 -56 64q-19 9 -19 21q0 20 41 20q50 0 110 -29 +q41 -19 71 -44.5t49.5 -51t33.5 -62.5t22 -69t16 -80q0 -1 3 -17.5t4.5 -25t5.5 -25t9 -27t11 -21.5t14.5 -16.5t18.5 -5.5q23 0 37 14t14 37q0 25 -20 67t-20 52t10 10q27 0 93 -70q72 -76 102.5 -156t30.5 -186zM2304 615q0 -274 -138 -503q-19 -32 -48 -72t-68 -86.5 +t-81 -77t-74 -30.5q-16 0 -31 15.5t-15 31.5q0 15 29 50.5t68.5 77t48.5 52.5q183 230 183 531q0 131 -20.5 235t-72.5 211q-58 119 -163 228q-2 3 -13 13.5t-16.5 16.5t-15 17.5t-15 20t-9.5 18.5t-4 19q0 19 16 35.5t35 16.5q70 0 196 -169q98 -131 146 -273t60 -314 +q2 -42 2 -64z" /> + <glyph glyph-name="uniF2C6" unicode="&#xf2c6;" horiz-adv-x="1792" +d="M1189 229l147 693q9 44 -10.5 63t-51.5 7l-864 -333q-29 -11 -39.5 -25t-2.5 -26.5t32 -19.5l221 -69l513 323q21 14 32 6q7 -5 -4 -15l-415 -375v0v0l-16 -228q23 0 45 22l108 104l224 -165q64 -36 81 38zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 +t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2C7" unicode="&#xf2c7;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v907h128v-907q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C8" unicode="&#xf2c8;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v651h128v-651q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2C9" unicode="&#xf2c9;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v395h128v-395q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CA" unicode="&#xf2ca;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 60 35 110t93 71v139h128v-139q58 -21 93 -71t35 -110zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5 +t93.5 226.5zM896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192 +v128h192z" /> + <glyph glyph-name="uniF2CB" unicode="&#xf2cb;" horiz-adv-x="1024" +d="M640 192q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 79 56 135.5t136 56.5t136 -56.5t56 -135.5zM768 192q0 77 -34 144t-94 112v768q0 80 -56 136t-136 56t-136 -56t-56 -136v-768q-60 -45 -94 -112t-34 -144q0 -133 93.5 -226.5t226.5 -93.5t226.5 93.5t93.5 226.5z +M896 192q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 182 128 313v711q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5v-711q128 -131 128 -313zM1024 768v-128h-192v128h192zM1024 1024v-128h-192v128h192zM1024 1280v-128h-192v128h192z" /> + <glyph glyph-name="uniF2CC" unicode="&#xf2cc;" horiz-adv-x="1920" +d="M1433 1287q10 -10 10 -23t-10 -23l-626 -626q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l44 44q-72 91 -81.5 207t46.5 215q-74 71 -176 71q-106 0 -181 -75t-75 -181v-1280h-256v1280q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5q106 0 201 -41 +t166 -115q94 39 197 24.5t185 -79.5l44 44q10 10 23 10t23 -10zM1344 1024q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1600 896q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1856 1024q26 0 45 -19t19 -45t-19 -45t-45 -19 +t-45 19t-19 45t19 45t45 19zM1216 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1408 832q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1728 896q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 768 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 640q-26 0 -45 19t-19 45t19 45t45 19t45 -19t19 -45t-19 -45t-45 -19zM1600 768q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 512q-26 0 -45 19t-19 45t19 45t45 19t45 -19 +t19 -45t-19 -45t-45 -19zM1472 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1344 512q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1216 384 +q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1088 256q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19z" /> + <glyph glyph-name="uniF2CD" unicode="&#xf2cd;" horiz-adv-x="1792" +d="M1664 448v-192q0 -169 -128 -286v-194q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v118q-63 -22 -128 -22h-768q-65 0 -128 22v-110q0 -17 -9.5 -28.5t-22.5 -11.5h-64q-13 0 -22.5 11.5t-9.5 28.5v186q-128 117 -128 286v192h1536zM704 864q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM768 928q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM704 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 992q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1056q0 -14 -9 -23t-23 -9t-23 9 +t-9 23t9 23t23 9t23 -9t9 -23zM704 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1792 608v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v640q0 106 75 181t181 75q108 0 184 -78q46 19 98 12t93 -39l22 22q11 11 22 0l42 -42 +q11 -11 0 -22l-314 -314q-11 -11 -22 0l-42 42q-11 11 0 22l22 22q-36 46 -40.5 104t23.5 108q-37 35 -88 35q-53 0 -90.5 -37.5t-37.5 -90.5v-640h1504q14 0 23 -9t9 -23zM896 1056q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1120q0 -14 -9 -23t-23 -9 +t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM768 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1120q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM896 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM832 1248q0 -14 -9 -23 +t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1024 1184q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM960 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23zM1088 1248q0 -14 -9 -23t-23 -9t-23 9t-9 23t9 23t23 9t23 -9t9 -23z" /> + <glyph glyph-name="uniF2CE" unicode="&#xf2ce;" +d="M994 344q0 -86 -17 -197q-31 -215 -55 -313q-22 -90 -152 -90t-152 90q-24 98 -55 313q-17 110 -17 197q0 168 224 168t224 -168zM1536 768q0 -240 -134 -434t-350 -280q-8 -3 -15 3t-6 15q7 48 10 66q4 32 6 47q1 9 9 12q159 81 255.5 234t96.5 337q0 180 -91 330.5 +t-247 234.5t-337 74q-124 -7 -237 -61t-193.5 -140.5t-128 -202t-46.5 -240.5q1 -184 99 -336.5t257 -231.5q7 -3 9 -12q3 -21 6 -45q1 -9 5 -32.5t6 -35.5q1 -9 -6.5 -15t-15.5 -2q-148 58 -261 169.5t-173.5 264t-52.5 319.5q7 143 66 273.5t154.5 227t225 157.5t272.5 70 +q164 10 315.5 -46.5t261 -160.5t175 -250.5t65.5 -308.5zM994 800q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5zM1282 768q0 -122 -53.5 -228.5t-146.5 -177.5q-8 -6 -16 -2t-10 14q-6 52 -29 92q-7 10 3 20 +q58 54 91 127t33 155q0 111 -58.5 204t-157.5 141.5t-212 36.5q-133 -15 -229 -113t-109 -231q-10 -92 23.5 -176t98.5 -144q10 -10 3 -20q-24 -41 -29 -93q-2 -9 -10 -13t-16 2q-95 74 -148.5 183t-51.5 234q3 131 69 244t177 181.5t241 74.5q144 7 268 -60t196.5 -187.5 +t72.5 -263.5z" /> + <glyph glyph-name="uniF2D0" unicode="&#xf2d0;" horiz-adv-x="1792" +d="M256 128h1280v768h-1280v-768zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D1" unicode="&#xf2d1;" horiz-adv-x="1792" +d="M1792 224v-192q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D2" unicode="&#xf2d2;" horiz-adv-x="2048" +d="M256 0h768v512h-768v-512zM1280 512h512v768h-768v-256h96q66 0 113 -47t47 -113v-352zM2048 1376v-960q0 -66 -47 -113t-113 -47h-608v-352q0 -66 -47 -113t-113 -47h-960q-66 0 -113 47t-47 113v960q0 66 47 113t113 47h608v352q0 66 47 113t113 47h960q66 0 113 -47 +t47 -113z" /> + <glyph glyph-name="uniF2D3" unicode="&#xf2d3;" horiz-adv-x="1792" +d="M1175 215l146 146q10 10 10 23t-10 23l-233 233l233 233q10 10 10 23t-10 23l-146 146q-10 10 -23 10t-23 -10l-233 -233l-233 233q-10 10 -23 10t-23 -10l-146 -146q-10 -10 -10 -23t10 -23l233 -233l-233 -233q-10 -10 -10 -23t10 -23l146 -146q10 -10 23 -10t23 10 +l233 233l233 -233q10 -10 23 -10t23 10zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D4" unicode="&#xf2d4;" horiz-adv-x="1792" +d="M1257 425l-146 -146q-10 -10 -23 -10t-23 10l-169 169l-169 -169q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l169 169l-169 169q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l169 -169l169 169q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 +l-169 -169l169 -169q10 -10 10 -23t-10 -23zM256 128h1280v1024h-1280v-1024zM1792 1248v-1216q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D5" unicode="&#xf2d5;" horiz-adv-x="1792" +d="M1070 358l306 564h-654l-306 -564h654zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D6" unicode="&#xf2d6;" horiz-adv-x="1794" +d="M1291 1060q-15 17 -35 8.5t-26 -28.5t5 -38q14 -17 40 -14.5t34 20.5t-18 52zM895 814q-8 -8 -19.5 -8t-18.5 8q-8 8 -8 19t8 18q7 8 18.5 8t19.5 -8q7 -7 7 -18t-7 -19zM1060 740l-35 -35q-12 -13 -29.5 -13t-30.5 13l-38 38q-12 13 -12 30t12 30l35 35q12 12 29.5 12 +t30.5 -12l38 -39q12 -12 12 -29.5t-12 -29.5zM951 870q-7 -8 -18.5 -8t-19.5 8q-7 8 -7 19t7 19q8 8 19 8t19 -8t8 -19t-8 -19zM1354 968q-34 -64 -107.5 -85.5t-127.5 16.5q-38 28 -61 66.5t-21 87.5t39 92t75.5 53t70.5 -5t70 -51q2 -2 13 -12.5t14.5 -13.5t13 -13.5 +t12.5 -15.5t10 -15.5t8.5 -18t4 -18.5t1 -21t-5 -22t-9.5 -24zM1555 486q3 20 -8.5 34.5t-27.5 21.5t-33 17t-23 20q-40 71 -84 98.5t-113 11.5q19 13 40 18.5t33 4.5l12 -1q2 45 -34 90q6 20 6.5 40.5t-2.5 30.5l-3 10q43 24 71 65t34 91q10 84 -43 150.5t-137 76.5 +q-60 7 -114 -18.5t-82 -74.5q-30 -51 -33.5 -101t14.5 -87t43.5 -64t56.5 -42q-45 4 -88 36t-57 88q-28 108 32 222q-16 21 -29 32q-50 0 -89 -19q19 24 42 37t36 14l13 1q0 50 -13 78q-10 21 -32.5 28.5t-47 -3.5t-37.5 -40q2 4 4 7q-7 -28 -6.5 -75.5t19 -117t48.5 -122.5 +q-25 -14 -47 -36q-35 -16 -85.5 -70.5t-84.5 -101.5l-33 -46q-90 -34 -181 -125.5t-75 -162.5q1 -16 11 -27q-15 -12 -30 -30q-21 -25 -21 -54t21.5 -40t63.5 6q41 19 77 49.5t55 60.5q-2 2 -6.5 5t-20.5 7.5t-33 3.5q23 5 51 12.5t40 10t27.5 6t26 4t23.5 0.5q14 -7 22 34 +q7 37 7 90q0 102 -40 150q106 -103 101 -219q-1 -29 -15 -50t-27 -27l-13 -6q-4 -7 -19 -32t-26 -45.5t-26.5 -52t-25 -61t-17 -63t-6.5 -66.5t10 -63q-35 54 -37 80q-22 -24 -34.5 -39t-33.5 -42t-30.5 -46t-16.5 -41t-0.5 -38t25.5 -27q45 -25 144 64t190.5 221.5 +t122.5 228.5q86 52 145 115.5t86 119.5q47 -93 154 -178q104 -83 167 -80q39 2 46 43zM1794 640q0 -182 -71 -348t-191 -286t-286.5 -191t-348.5 -71t-348.5 71t-286.5 191t-191 286t-71 348t71 348t191 286t286.5 191t348.5 71t348.5 -71t286.5 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2D7" unicode="&#xf2d7;" +d="M518 1353v-655q103 -1 191.5 1.5t125.5 5.5l37 3q68 2 90.5 24.5t39.5 94.5l33 142h103l-14 -322l7 -319h-103l-29 127q-15 68 -45 93t-84 26q-87 8 -352 8v-556q0 -78 43.5 -115.5t133.5 -37.5h357q35 0 59.5 2t55 7.5t54 18t48.5 32t46 50.5t39 73l93 216h89 +q-6 -37 -31.5 -252t-30.5 -276q-146 5 -263.5 8t-162.5 4h-44h-628l-376 -12v102l127 25q67 13 91.5 37t25.5 79l8 643q3 402 -8 645q-2 61 -25.5 84t-91.5 36l-127 24v102l376 -12h702q139 0 374 27q-6 -68 -14 -194.5t-12 -219.5l-5 -92h-93l-32 124q-31 121 -74 179.5 +t-113 58.5h-548q-28 0 -35.5 -8.5t-7.5 -30.5z" /> + <glyph glyph-name="uniF2D8" unicode="&#xf2d8;" +d="M922 739v-182q0 -4 0.5 -15t0 -15l-1.5 -12t-3.5 -11.5t-6.5 -7.5t-11 -5.5t-16 -1.5v309q9 0 16 -1t11 -5t6.5 -5.5t3.5 -9.5t1 -10.5v-13.5v-14zM1238 643v-121q0 -1 0.5 -12.5t0 -15.5t-2.5 -11.5t-7.5 -10.5t-13.5 -3q-9 0 -14 9q-4 10 -4 165v7v8.5v9t1.5 8.5l3.5 7 +t5 5.5t8 1.5q6 0 10 -1.5t6.5 -4.5t4 -6t2 -8.5t0.5 -8v-9.5v-9zM180 407h122v472h-122v-472zM614 407h106v472h-159l-28 -221q-20 148 -32 221h-158v-472h107v312l45 -312h76l43 319v-319zM1039 712q0 67 -5 90q-3 16 -11 28.5t-17 20.5t-25 14t-26.5 8.5t-31 4t-29 1.5 +h-29.5h-12h-91v-472h56q169 -1 197 24.5t25 180.5q-1 62 -1 100zM1356 515v133q0 29 -2 45t-9.5 33.5t-24.5 25t-46 7.5q-46 0 -77 -34v154h-117v-472h110l7 30q30 -36 77 -36q50 0 66 30.5t16 83.5zM1536 1248v-1216q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113 +v1216q0 66 47 113t113 47h1216q66 0 113 -47t47 -113z" /> + <glyph glyph-name="uniF2D9" unicode="&#xf2d9;" horiz-adv-x="2176" +d="M1143 -197q-6 1 -11 4q-13 8 -36 23t-86 65t-116.5 104.5t-112 140t-89.5 172.5q-17 3 -175 37q66 -213 235 -362t391 -184zM502 409l168 -28q-25 76 -41 167.5t-19 145.5l-4 53q-84 -82 -121 -224q5 -65 17 -114zM612 1018q-43 -64 -77 -148q44 46 74 68zM2049 584 +q0 161 -62 307t-167.5 252t-250.5 168.5t-304 62.5q-147 0 -281 -52.5t-240 -148.5q-30 -58 -45 -160q60 51 143 83.5t158.5 43t143 13.5t108.5 -1l40 -3q33 -1 53 -15.5t24.5 -33t6.5 -37t-1 -28.5q-126 11 -227.5 0.5t-183 -43.5t-142.5 -71.5t-131 -98.5 +q4 -36 11.5 -92.5t35.5 -178t62 -179.5q123 -6 247.5 14.5t214.5 53.5t162.5 67t109.5 59l37 24q22 16 39.5 20.5t30.5 -5t17 -34.5q14 -97 -39 -121q-208 -97 -467 -134q-135 -20 -317 -16q41 -96 110 -176.5t137 -127t130.5 -79t101.5 -43.5l39 -12q143 -23 263 15 +q195 99 314 289t119 418zM2123 621q-14 -135 -40 -212q-70 -208 -181.5 -346.5t-318.5 -253.5q-48 -33 -82 -44q-72 -26 -163 -16q-36 -3 -73 -3q-283 0 -504.5 173t-295.5 442q-1 0 -4 0.5t-5 0.5q-6 -50 2.5 -112.5t26 -115t36 -98t31.5 -71.5l14 -26q8 -12 54 -82 +q-71 38 -124.5 106.5t-78.5 140t-39.5 137t-17.5 107.5l-2 42q-5 2 -33.5 12.5t-48.5 18t-53 20.5t-57.5 25t-50 25.5t-42.5 27t-25 25.5q19 -10 50.5 -25.5t113 -45.5t145.5 -38l2 32q11 149 94 290q41 202 176 365q28 115 81 214q15 28 32 45t49 32q158 74 303.5 104 +t302 11t306.5 -97q220 -115 333 -336t87 -474z" /> + <glyph glyph-name="uniF2DA" unicode="&#xf2da;" horiz-adv-x="1792" +d="M1341 752q29 44 -6.5 129.5t-121.5 142.5q-58 39 -125.5 53.5t-118 4.5t-68.5 -37q-12 -23 -4.5 -28t42.5 -10q23 -3 38.5 -5t44.5 -9.5t56 -17.5q36 -13 67.5 -31.5t53 -37t40 -38.5t30.5 -38t22 -34.5t16.5 -28.5t12 -18.5t10.5 -6t11 9.5zM1704 178 +q-52 -127 -148.5 -220t-214.5 -141.5t-253 -60.5t-266 13.5t-251 91t-210 161.5t-141.5 235.5t-46.5 303.5q1 41 8.5 84.5t12.5 64t24 80.5t23 73q-51 -208 1 -397t173 -318t291 -206t346 -83t349 74.5t289 244.5q20 27 18 14q0 -4 -4 -14zM1465 627q0 -104 -40.5 -199 +t-108.5 -164t-162 -109.5t-198 -40.5t-198 40.5t-162 109.5t-108.5 164t-40.5 199t40.5 199t108.5 164t162 109.5t198 40.5t198 -40.5t162 -109.5t108.5 -164t40.5 -199zM1752 915q-65 147 -180.5 251t-253 153.5t-292 53.5t-301 -36.5t-275.5 -129t-220 -211.5t-131 -297 +t-10 -373q-49 161 -51.5 311.5t35.5 272.5t109 227t165.5 180.5t207 126t232 71t242.5 9t236 -54t216 -124.5t178 -197q33 -50 62 -121t31 -112zM1690 573q12 244 -136.5 416t-396.5 240q-8 0 -10 5t24 8q125 -4 230 -50t173 -120t116 -168.5t58.5 -199t-1 -208 +t-61.5 -197.5t-122.5 -167t-185 -117.5t-248.5 -46.5q108 30 201.5 80t174 123t129.5 176.5t55 225.5z" /> + <glyph glyph-name="uniF2DB" unicode="&#xf2db;" +d="M192 256v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 512v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 768v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16 +q0 16 16 16h112zM192 1024v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM192 1280v-128h-112q-16 0 -16 16v16h-48q-16 0 -16 16v32q0 16 16 16h48v16q0 16 16 16h112zM1280 1440v-1472q0 -40 -28 -68t-68 -28h-832q-40 0 -68 28 +t-28 68v1472q0 40 28 68t68 28h832q40 0 68 -28t28 -68zM1536 208v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 464v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 720v-32 +q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 976v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16h48q16 0 16 -16zM1536 1232v-32q0 -16 -16 -16h-48v-16q0 -16 -16 -16h-112v128h112q16 0 16 -16v-16 +h48q16 0 16 -16z" /> + <glyph glyph-name="uniF2DC" unicode="&#xf2dc;" horiz-adv-x="1664" +d="M1566 419l-167 -33l186 -107q23 -13 29.5 -38.5t-6.5 -48.5q-14 -23 -39 -29.5t-48 6.5l-186 106l55 -160q13 -38 -12 -63.5t-60.5 -20.5t-48.5 42l-102 300l-271 156v-313l208 -238q16 -18 17 -39t-11 -36.5t-28.5 -25t-37 -5.5t-36.5 22l-112 128v-214q0 -26 -19 -45 +t-45 -19t-45 19t-19 45v214l-112 -128q-16 -18 -36.5 -22t-37 5.5t-28.5 25t-11 36.5t17 39l208 238v313l-271 -156l-102 -300q-13 -37 -48.5 -42t-60.5 20.5t-12 63.5l55 160l-186 -106q-23 -13 -48 -6.5t-39 29.5q-13 23 -6.5 48.5t29.5 38.5l186 107l-167 33 +q-29 6 -42 29t-8.5 46.5t25.5 40t50 10.5l310 -62l271 157l-271 157l-310 -62q-4 -1 -13 -1q-27 0 -44 18t-19 40t11 43t40 26l167 33l-186 107q-23 13 -29.5 38.5t6.5 48.5t39 30t48 -7l186 -106l-55 160q-13 38 12 63.5t60.5 20.5t48.5 -42l102 -300l271 -156v313 +l-208 238q-16 18 -17 39t11 36.5t28.5 25t37 5.5t36.5 -22l112 -128v214q0 26 19 45t45 19t45 -19t19 -45v-214l112 128q16 18 36.5 22t37 -5.5t28.5 -25t11 -36.5t-17 -39l-208 -238v-313l271 156l102 300q13 37 48.5 42t60.5 -20.5t12 -63.5l-55 -160l186 106 +q23 13 48 6.5t39 -29.5q13 -23 6.5 -48.5t-29.5 -38.5l-186 -107l167 -33q27 -5 40 -26t11 -43t-19 -40t-44 -18q-9 0 -13 1l-310 62l-271 -157l271 -157l310 62q29 6 50 -10.5t25.5 -40t-8.5 -46.5t-42 -29z" /> + <glyph glyph-name="uniF2DD" unicode="&#xf2dd;" horiz-adv-x="1792" +d="M1473 607q7 118 -33 226.5t-113 189t-177 131t-221 57.5q-116 7 -225.5 -32t-192 -110.5t-135 -175t-59.5 -220.5q-7 -118 33 -226.5t113 -189t177.5 -131t221.5 -57.5q155 -9 293 59t224 195.5t94 283.5zM1792 1536l-349 -348q120 -117 180.5 -272t50.5 -321 +q-11 -183 -102 -339t-241 -255.5t-332 -124.5l-999 -132l347 347q-120 116 -180.5 271.5t-50.5 321.5q11 184 102 340t241.5 255.5t332.5 124.5q167 22 500 66t500 66z" /> + <glyph glyph-name="uniF2DE" unicode="&#xf2de;" horiz-adv-x="1792" +d="M948 508l163 -329h-51l-175 350l-171 -350h-49l179 374l-78 33l21 49l240 -102l-21 -50zM563 1100l304 -130l-130 -304l-304 130zM907 915l240 -103l-103 -239l-239 102zM1188 765l191 -81l-82 -190l-190 81zM1680 640q0 159 -62 304t-167.5 250.5t-250.5 167.5t-304 62 +t-304 -62t-250.5 -167.5t-167.5 -250.5t-62 -304t62 -304t167.5 -250.5t250.5 -167.5t304 -62t304 62t250.5 167.5t167.5 250.5t62 304zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71 +t286 -191t191 -286t71 -348z" /> + <glyph glyph-name="uniF2E0" unicode="&#xf2e0;" horiz-adv-x="1920" +d="M1334 302q-4 24 -27.5 34t-49.5 10.5t-48.5 12.5t-25.5 38q-5 47 33 139.5t75 181t32 127.5q-14 101 -117 103q-45 1 -75 -16l-3 -2l-5 -2.5t-4.5 -2t-5 -2t-5 -0.5t-6 1.5t-6 3.5t-6.5 5q-3 2 -9 8.5t-9 9t-8.5 7.5t-9.5 7.5t-9.5 5.5t-11 4.5t-11.5 2.5q-30 5 -48 -3 +t-45 -31q-1 -1 -9 -8.5t-12.5 -11t-15 -10t-16.5 -5.5t-17 3q-54 27 -84 40q-41 18 -94 -5t-76 -65q-16 -28 -41 -98.5t-43.5 -132.5t-40 -134t-21.5 -73q-22 -69 18.5 -119t110.5 -46q30 2 50.5 15t38.5 46q7 13 79 199.5t77 194.5q6 11 21.5 18t29.5 0q27 -15 21 -53 +q-2 -18 -51 -139.5t-50 -132.5q-6 -38 19.5 -56.5t60.5 -7t55 49.5q4 8 45.5 92t81.5 163.5t46 88.5q20 29 41 28q29 0 25 -38q-2 -16 -65.5 -147.5t-70.5 -159.5q-12 -53 13 -103t74 -74q17 -9 51 -15.5t71.5 -8t62.5 14t20 48.5zM383 86q3 -15 -5 -27.5t-23 -15.5 +q-14 -3 -26.5 5t-15.5 23q-3 14 5 27t22 16t27 -5t16 -23zM953 -177q12 -17 8.5 -37.5t-20.5 -32.5t-37.5 -8t-32.5 21q-11 17 -7.5 37.5t20.5 32.5t37.5 8t31.5 -21zM177 635q-18 -27 -49.5 -33t-57.5 13q-26 18 -32 50t12 58q18 27 49.5 33t57.5 -12q26 -19 32 -50.5 +t-12 -58.5zM1467 -42q19 -28 13 -61.5t-34 -52.5t-60.5 -13t-51.5 34t-13 61t33 53q28 19 60.5 13t52.5 -34zM1579 562q69 -113 42.5 -244.5t-134.5 -207.5q-90 -63 -199 -60q-20 -80 -84.5 -127t-143.5 -44.5t-140 57.5q-12 -9 -13 -10q-103 -71 -225 -48.5t-193 126.5 +q-50 73 -53 164q-83 14 -142.5 70.5t-80.5 128t-2 152t81 138.5q-36 60 -38 128t24.5 125t79.5 98.5t121 50.5q32 85 99 148t146.5 91.5t168 17t159.5 -66.5q72 21 140 17.5t128.5 -36t104.5 -80t67.5 -115t17.5 -140.5q52 -16 87 -57t45.5 -89t-5.5 -99.5t-58 -87.5z +M455 1222q14 -20 9.5 -44.5t-24.5 -38.5q-19 -14 -43.5 -9.5t-37.5 24.5q-14 20 -9.5 44.5t24.5 38.5q19 14 43.5 9.5t37.5 -24.5zM614 1503q4 -16 -5 -30.5t-26 -18.5t-31 5.5t-18 26.5q-3 17 6.5 31t25.5 18q17 4 31 -5.5t17 -26.5zM1800 555q4 -20 -6.5 -37t-30.5 -21 +q-19 -4 -36 6.5t-21 30.5t6.5 37t30.5 22q20 4 36.5 -7.5t20.5 -30.5zM1136 1448q16 -27 8.5 -58.5t-35.5 -47.5q-27 -16 -57.5 -8.5t-46.5 34.5q-16 28 -8.5 59t34.5 48t58 9t47 -36zM1882 792q4 -15 -4 -27.5t-23 -16.5q-15 -3 -27.5 5.5t-15.5 22.5q-3 15 5 28t23 16 +q14 3 26.5 -5t15.5 -23zM1691 1033q15 -22 10.5 -49t-26.5 -43q-22 -15 -49 -10t-42 27t-10 49t27 43t48.5 11t41.5 -28z" /> + <glyph glyph-name="uniF2E1" unicode="&#xf2e1;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E2" unicode="&#xf2e2;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E3" unicode="&#xf2e3;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E4" unicode="&#xf2e4;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E5" unicode="&#xf2e5;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E6" unicode="&#xf2e6;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E7" unicode="&#xf2e7;" horiz-adv-x="1792" + /> + <glyph glyph-name="_698" unicode="&#xf2e8;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2E9" unicode="&#xf2e9;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EA" unicode="&#xf2ea;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EB" unicode="&#xf2eb;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EC" unicode="&#xf2ec;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2ED" unicode="&#xf2ed;" horiz-adv-x="1792" + /> + <glyph glyph-name="uniF2EE" unicode="&#xf2ee;" horiz-adv-x="1792" + /> + <glyph glyph-name="lessequal" unicode="&#xf500;" horiz-adv-x="1792" + /> + </font> +</defs></svg> diff --git a/static/plugins/font-awesome/fonts/fontawesome-webfont.ttf b/static/plugins/font-awesome/fonts/fontawesome-webfont.ttf new file mode 100755 index 0000000..35acda2 Binary files /dev/null and b/static/plugins/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/static/plugins/font-awesome/fonts/fontawesome-webfont.woff b/static/plugins/font-awesome/fonts/fontawesome-webfont.woff new file mode 100755 index 0000000..400014a Binary files /dev/null and b/static/plugins/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/static/plugins/font-awesome/fonts/fontawesome-webfont.woff2 b/static/plugins/font-awesome/fonts/fontawesome-webfont.woff2 new file mode 100755 index 0000000..4d13fc6 Binary files /dev/null and b/static/plugins/font-awesome/fonts/fontawesome-webfont.woff2 differ diff --git a/static/plugins/jcrop/css/Jcrop.gif b/static/plugins/jcrop/css/Jcrop.gif new file mode 100755 index 0000000..72ea7cc Binary files /dev/null and b/static/plugins/jcrop/css/Jcrop.gif differ diff --git a/static/plugins/jcrop/css/jquery.Jcrop.css b/static/plugins/jcrop/css/jquery.Jcrop.css new file mode 100755 index 0000000..95f8b9c --- /dev/null +++ b/static/plugins/jcrop/css/jquery.Jcrop.css @@ -0,0 +1,165 @@ +/* jquery.Jcrop.css v0.9.12 - MIT License */ +/* + The outer-most container in a typical Jcrop instance + If you are having difficulty with formatting related to styles + on a parent element, place any fixes here or in a like selector + + You can also style this element if you want to add a border, etc + A better method for styling can be seen below with .jcrop-light + (Add a class to the holder and style elements for that extended class) +*/ +.jcrop-holder { + direction: ltr; + text-align: left; +} +/* Selection Border */ +.jcrop-vline, +.jcrop-hline { + background: #ffffff url("Jcrop.gif"); + font-size: 0; + position: absolute; +} +.jcrop-vline { + height: 100%; + width: 1px !important; +} +.jcrop-vline.right { + right: 0; +} +.jcrop-hline { + height: 1px !important; + width: 100%; +} +.jcrop-hline.bottom { + bottom: 0; +} +/* Invisible click targets */ +.jcrop-tracker { + height: 100%; + width: 100%; + /* "turn off" link highlight */ + -webkit-tap-highlight-color: transparent; + /* disable callout, image save panel */ + -webkit-touch-callout: none; + /* disable cut copy paste */ + -webkit-user-select: none; +} +/* Selection Handles */ +.jcrop-handle { + background-color: #333333; + border: 1px #eeeeee solid; + width: 7px; + height: 7px; + font-size: 1px; +} +.jcrop-handle.ord-n { + left: 50%; + margin-left: -4px; + margin-top: -4px; + top: 0; +} +.jcrop-handle.ord-s { + bottom: 0; + left: 50%; + margin-bottom: -4px; + margin-left: -4px; +} +.jcrop-handle.ord-e { + margin-right: -4px; + margin-top: -4px; + right: 0; + top: 50%; +} +.jcrop-handle.ord-w { + left: 0; + margin-left: -4px; + margin-top: -4px; + top: 50%; +} +.jcrop-handle.ord-nw { + left: 0; + margin-left: -4px; + margin-top: -4px; + top: 0; +} +.jcrop-handle.ord-ne { + margin-right: -4px; + margin-top: -4px; + right: 0; + top: 0; +} +.jcrop-handle.ord-se { + bottom: 0; + margin-bottom: -4px; + margin-right: -4px; + right: 0; +} +.jcrop-handle.ord-sw { + bottom: 0; + left: 0; + margin-bottom: -4px; + margin-left: -4px; +} +/* Dragbars */ +.jcrop-dragbar.ord-n, +.jcrop-dragbar.ord-s { + height: 7px; + width: 100%; +} +.jcrop-dragbar.ord-e, +.jcrop-dragbar.ord-w { + height: 100%; + width: 7px; +} +.jcrop-dragbar.ord-n { + margin-top: -4px; +} +.jcrop-dragbar.ord-s { + bottom: 0; + margin-bottom: -4px; +} +.jcrop-dragbar.ord-e { + margin-right: -4px; + right: 0; +} +.jcrop-dragbar.ord-w { + margin-left: -4px; +} +/* The "jcrop-light" class/extension */ +.jcrop-light .jcrop-vline, +.jcrop-light .jcrop-hline { + background: #ffffff; + filter: alpha(opacity=70) !important; + opacity: .70!important; +} +.jcrop-light .jcrop-handle { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + background-color: #000000; + border-color: #ffffff; + border-radius: 3px; +} +/* The "jcrop-dark" class/extension */ +.jcrop-dark .jcrop-vline, +.jcrop-dark .jcrop-hline { + background: #000000; + filter: alpha(opacity=70) !important; + opacity: 0.7 !important; +} +.jcrop-dark .jcrop-handle { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + background-color: #ffffff; + border-color: #000000; + border-radius: 3px; +} +/* Simple macro to turn off the antlines */ +.solid-line .jcrop-vline, +.solid-line .jcrop-hline { + background: #ffffff; +} +/* Fix for twitter bootstrap et al. */ +.jcrop-holder img, +img.jcrop-preview { + max-width: none; +} diff --git a/static/plugins/jcrop/css/jquery.Jcrop.min.css b/static/plugins/jcrop/css/jquery.Jcrop.min.css new file mode 100755 index 0000000..edc76b2 --- /dev/null +++ b/static/plugins/jcrop/css/jquery.Jcrop.min.css @@ -0,0 +1,29 @@ +/* jquery.Jcrop.min.css v0.9.12 (build:20130126) */ +.jcrop-holder{direction:ltr;text-align:left;} +.jcrop-vline,.jcrop-hline{background:#FFF url(Jcrop.gif);font-size:0;position:absolute;} +.jcrop-vline{height:100%;width:1px!important;} +.jcrop-vline.right{right:0;} +.jcrop-hline{height:1px!important;width:100%;} +.jcrop-hline.bottom{bottom:0;} +.jcrop-tracker{-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;height:100%;width:100%;} +.jcrop-handle{background-color:#333;border:1px #EEE solid;font-size:1px;height:7px;width:7px;} +.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0;} +.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px;} +.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%;} +.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%;} +.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0;} +.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0;} +.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0;} +.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px;} +.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%;} +.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px;} +.jcrop-dragbar.ord-n{margin-top:-4px;} +.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px;} +.jcrop-dragbar.ord-e{margin-right:-4px;right:0;} +.jcrop-dragbar.ord-w{margin-left:-4px;} +.jcrop-light .jcrop-vline,.jcrop-light .jcrop-hline{background:#FFF;filter:alpha(opacity=70)!important;opacity:.70!important;} +.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#FFF;border-radius:3px;} +.jcrop-dark .jcrop-vline,.jcrop-dark .jcrop-hline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important;} +.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#FFF;border-color:#000;border-radius:3px;} +.solid-line .jcrop-vline,.solid-line .jcrop-hline{background:#FFF;} +.jcrop-holder img,img.jcrop-preview{max-width:none;} diff --git a/static/plugins/jcrop/js/jquery.Jcrop.js b/static/plugins/jcrop/js/jquery.Jcrop.js new file mode 100755 index 0000000..e1a9a5d --- /dev/null +++ b/static/plugins/jcrop/js/jquery.Jcrop.js @@ -0,0 +1,1694 @@ +/** + * jquery.Jcrop.js v0.9.12 + * jQuery Image Cropping Plugin - released under MIT License + * Author: Kelly Hallman <khallman@gmail.com> + * http://github.com/tapmodo/Jcrop + * Copyright (c) 2008-2013 Tapmodo Interactive LLC {{{ + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * }}} + */ + +(function ($) { + + $.Jcrop = function (obj, opt) { + var options = $.extend({}, $.Jcrop.defaults), + docOffset, + _ua = navigator.userAgent.toLowerCase(), + is_msie = /msie/.test(_ua), + ie6mode = /msie [1-6]\./.test(_ua); + + // Internal Methods {{{ + function px(n) { + return Math.round(n) + 'px'; + } + function cssClass(cl) { + return options.baseClass + '-' + cl; + } + function supportsColorFade() { + return $.fx.step.hasOwnProperty('backgroundColor'); + } + function getPos(obj) //{{{ + { + var pos = $(obj).offset(); + return [pos.left, pos.top]; + } + //}}} + function mouseAbs(e) //{{{ + { + return [(e.pageX - docOffset[0]), (e.pageY - docOffset[1])]; + } + //}}} + function setOptions(opt) //{{{ + { + if (typeof(opt) !== 'object') opt = {}; + options = $.extend(options, opt); + + $.each(['onChange','onSelect','onRelease','onDblClick'],function(i,e) { + if (typeof(options[e]) !== 'function') options[e] = function () {}; + }); + } + //}}} + function startDragMode(mode, pos, touch) //{{{ + { + docOffset = getPos($img); + Tracker.setCursor(mode === 'move' ? mode : mode + '-resize'); + + if (mode === 'move') { + return Tracker.activateHandlers(createMover(pos), doneSelect, touch); + } + + var fc = Coords.getFixed(); + var opp = oppLockCorner(mode); + var opc = Coords.getCorner(oppLockCorner(opp)); + + Coords.setPressed(Coords.getCorner(opp)); + Coords.setCurrent(opc); + + Tracker.activateHandlers(dragmodeHandler(mode, fc), doneSelect, touch); + } + //}}} + function dragmodeHandler(mode, f) //{{{ + { + return function (pos) { + if (!options.aspectRatio) { + switch (mode) { + case 'e': + pos[1] = f.y2; + break; + case 'w': + pos[1] = f.y2; + break; + case 'n': + pos[0] = f.x2; + break; + case 's': + pos[0] = f.x2; + break; + } + } else { + switch (mode) { + case 'e': + pos[1] = f.y + 1; + break; + case 'w': + pos[1] = f.y + 1; + break; + case 'n': + pos[0] = f.x + 1; + break; + case 's': + pos[0] = f.x + 1; + break; + } + } + Coords.setCurrent(pos); + Selection.update(); + }; + } + //}}} + function createMover(pos) //{{{ + { + var lloc = pos; + KeyManager.watchKeys(); + + return function (pos) { + Coords.moveOffset([pos[0] - lloc[0], pos[1] - lloc[1]]); + lloc = pos; + + Selection.update(); + }; + } + //}}} + function oppLockCorner(ord) //{{{ + { + switch (ord) { + case 'n': + return 'sw'; + case 's': + return 'nw'; + case 'e': + return 'nw'; + case 'w': + return 'ne'; + case 'ne': + return 'sw'; + case 'nw': + return 'se'; + case 'se': + return 'nw'; + case 'sw': + return 'ne'; + } + } + //}}} + function createDragger(ord) //{{{ + { + return function (e) { + if (options.disabled) { + return false; + } + if ((ord === 'move') && !options.allowMove) { + return false; + } + + // Fix position of crop area when dragged the very first time. + // Necessary when crop image is in a hidden element when page is loaded. + docOffset = getPos($img); + + btndown = true; + startDragMode(ord, mouseAbs(e)); + e.stopPropagation(); + e.preventDefault(); + return false; + }; + } + //}}} + function presize($obj, w, h) //{{{ + { + var nw = $obj.width(), + nh = $obj.height(); + if ((nw > w) && w > 0) { + nw = w; + nh = (w / $obj.width()) * $obj.height(); + } + if ((nh > h) && h > 0) { + nh = h; + nw = (h / $obj.height()) * $obj.width(); + } + xscale = $obj.width() / nw; + yscale = $obj.height() / nh; + $obj.width(nw).height(nh); + } + //}}} + function unscale(c) //{{{ + { + return { + x: c.x * xscale, + y: c.y * yscale, + x2: c.x2 * xscale, + y2: c.y2 * yscale, + w: c.w * xscale, + h: c.h * yscale + }; + } + //}}} + function doneSelect(pos) //{{{ + { + var c = Coords.getFixed(); + if ((c.w > options.minSelect[0]) && (c.h > options.minSelect[1])) { + Selection.enableHandles(); + Selection.done(); + } else { + Selection.release(); + } + Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default'); + } + //}}} + function newSelection(e) //{{{ + { + if (options.disabled) { + return false; + } + if (!options.allowSelect) { + return false; + } + btndown = true; + docOffset = getPos($img); + Selection.disableHandles(); + Tracker.setCursor('crosshair'); + var pos = mouseAbs(e); + Coords.setPressed(pos); + Selection.update(); + Tracker.activateHandlers(selectDrag, doneSelect, e.type.substring(0,5)==='touch'); + KeyManager.watchKeys(); + + e.stopPropagation(); + e.preventDefault(); + return false; + } + //}}} + function selectDrag(pos) //{{{ + { + Coords.setCurrent(pos); + Selection.update(); + } + //}}} + function newTracker() //{{{ + { + var trk = $('<div></div>').addClass(cssClass('tracker')); + if (is_msie) { + trk.css({ + opacity: 0, + backgroundColor: 'white' + }); + } + return trk; + } + //}}} + + // }}} + // Initialization {{{ + // Sanitize some options {{{ + if (typeof(obj) !== 'object') { + obj = $(obj)[0]; + } + if (typeof(opt) !== 'object') { + opt = {}; + } + // }}} + setOptions(opt); + // Initialize some jQuery objects {{{ + // The values are SET on the image(s) for the interface + // If the original image has any of these set, they will be reset + // However, if you destroy() the Jcrop instance the original image's + // character in the DOM will be as you left it. + var img_css = { + border: 'none', + visibility: 'visible', + margin: 0, + padding: 0, + position: 'absolute', + top: 0, + left: 0 + }; + + var $origimg = $(obj), + img_mode = true; + + if (obj.tagName == 'IMG') { + // Fix size of crop image. + // Necessary when crop image is within a hidden element when page is loaded. + if ($origimg[0].width != 0 && $origimg[0].height != 0) { + // Obtain dimensions from contained img element. + $origimg.width($origimg[0].width); + $origimg.height($origimg[0].height); + } else { + // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0). + var tempImage = new Image(); + tempImage.src = $origimg[0].src; + $origimg.width(tempImage.width); + $origimg.height(tempImage.height); + } + + var $img = $origimg.clone().removeAttr('id').css(img_css).show(); + + $img.width($origimg.width()); + $img.height($origimg.height()); + $origimg.after($img).hide(); + + } else { + $img = $origimg.css(img_css).show(); + img_mode = false; + if (options.shade === null) { options.shade = true; } + } + + presize($img, options.boxWidth, options.boxHeight); + + var boundx = $img.width(), + boundy = $img.height(), + + + $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({ + + backgroundColor: options.bgColor + }).insertAfter($origimg).append($img); + + if (options.addClass) { + $div.addClass(options.addClass); + } + + var $img2 = $('<div />'), + + $img_holder = $('<div />') + .width('100%').height('100%').css({ + zIndex: 310, + position: 'absolute', + overflow: 'hidden' + }), + + $hdl_holder = $('<div />') + .width('100%').height('100%').css('zIndex', 320), + + $sel = $('<div />') + .css({ + position: 'absolute', + zIndex: 600 + }).dblclick(function(){ + var c = Coords.getFixed(); + options.onDblClick.call(api,c); + }).insertBefore($img).append($img_holder, $hdl_holder); + + if (img_mode) { + + $img2 = $('<img />') + .attr('src', $img.attr('src')).css(img_css).width(boundx).height(boundy), + + $img_holder.append($img2); + + } + + if (ie6mode) { + $sel.css({ + overflowY: 'hidden' + }); + } + + var bound = options.boundary; + var $trk = newTracker().width(boundx + (bound * 2)).height(boundy + (bound * 2)).css({ + position: 'absolute', + top: px(-bound), + left: px(-bound), + zIndex: 290 + }).mousedown(newSelection); + + /* }}} */ + // Set more variables {{{ + var bgcolor = options.bgColor, + bgopacity = options.bgOpacity, + xlimit, ylimit, xmin, ymin, xscale, yscale, enabled = true, + btndown, animating, shift_down; + + docOffset = getPos($img); + // }}} + // }}} + // Internal Modules {{{ + // Touch Module {{{ + var Touch = (function () { + // Touch support detection function adapted (under MIT License) + // from code by Jeffrey Sambells - http://github.com/iamamused/ + function hasTouchSupport() { + var support = {}, events = ['touchstart', 'touchmove', 'touchend'], + el = document.createElement('div'), i; + + try { + for(i=0; i<events.length; i++) { + var eventName = events[i]; + eventName = 'on' + eventName; + var isSupported = (eventName in el); + if (!isSupported) { + el.setAttribute(eventName, 'return;'); + isSupported = typeof el[eventName] == 'function'; + } + support[events[i]] = isSupported; + } + return support.touchstart && support.touchend && support.touchmove; + } + catch(err) { + return false; + } + } + + function detectSupport() { + if ((options.touchSupport === true) || (options.touchSupport === false)) return options.touchSupport; + else return hasTouchSupport(); + } + return { + createDragger: function (ord) { + return function (e) { + if (options.disabled) { + return false; + } + if ((ord === 'move') && !options.allowMove) { + return false; + } + docOffset = getPos($img); + btndown = true; + startDragMode(ord, mouseAbs(Touch.cfilter(e)), true); + e.stopPropagation(); + e.preventDefault(); + return false; + }; + }, + newSelection: function (e) { + return newSelection(Touch.cfilter(e)); + }, + cfilter: function (e){ + e.pageX = e.originalEvent.changedTouches[0].pageX; + e.pageY = e.originalEvent.changedTouches[0].pageY; + return e; + }, + isSupported: hasTouchSupport, + support: detectSupport() + }; + }()); + // }}} + // Coords Module {{{ + var Coords = (function () { + var x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0, + ox, oy; + + function setPressed(pos) //{{{ + { + pos = rebound(pos); + x2 = x1 = pos[0]; + y2 = y1 = pos[1]; + } + //}}} + function setCurrent(pos) //{{{ + { + pos = rebound(pos); + ox = pos[0] - x2; + oy = pos[1] - y2; + x2 = pos[0]; + y2 = pos[1]; + } + //}}} + function getOffset() //{{{ + { + return [ox, oy]; + } + //}}} + function moveOffset(offset) //{{{ + { + var ox = offset[0], + oy = offset[1]; + + if (0 > x1 + ox) { + ox -= ox + x1; + } + if (0 > y1 + oy) { + oy -= oy + y1; + } + + if (boundy < y2 + oy) { + oy += boundy - (y2 + oy); + } + if (boundx < x2 + ox) { + ox += boundx - (x2 + ox); + } + + x1 += ox; + x2 += ox; + y1 += oy; + y2 += oy; + } + //}}} + function getCorner(ord) //{{{ + { + var c = getFixed(); + switch (ord) { + case 'ne': + return [c.x2, c.y]; + case 'nw': + return [c.x, c.y]; + case 'se': + return [c.x2, c.y2]; + case 'sw': + return [c.x, c.y2]; + } + } + //}}} + function getFixed() //{{{ + { + if (!options.aspectRatio) { + return getRect(); + } + // This function could use some optimization I think... + var aspect = options.aspectRatio, + min_x = options.minSize[0] / xscale, + + + //min_y = options.minSize[1]/yscale, + max_x = options.maxSize[0] / xscale, + max_y = options.maxSize[1] / yscale, + rw = x2 - x1, + rh = y2 - y1, + rwa = Math.abs(rw), + rha = Math.abs(rh), + real_ratio = rwa / rha, + xx, yy, w, h; + + if (max_x === 0) { + max_x = boundx * 10; + } + if (max_y === 0) { + max_y = boundy * 10; + } + if (real_ratio < aspect) { + yy = y2; + w = rha * aspect; + xx = rw < 0 ? x1 - w : w + x1; + + if (xx < 0) { + xx = 0; + h = Math.abs((xx - x1) / aspect); + yy = rh < 0 ? y1 - h : h + y1; + } else if (xx > boundx) { + xx = boundx; + h = Math.abs((xx - x1) / aspect); + yy = rh < 0 ? y1 - h : h + y1; + } + } else { + xx = x2; + h = rwa / aspect; + yy = rh < 0 ? y1 - h : y1 + h; + if (yy < 0) { + yy = 0; + w = Math.abs((yy - y1) * aspect); + xx = rw < 0 ? x1 - w : w + x1; + } else if (yy > boundy) { + yy = boundy; + w = Math.abs(yy - y1) * aspect; + xx = rw < 0 ? x1 - w : w + x1; + } + } + + // Magic %-) + if (xx > x1) { // right side + if (xx - x1 < min_x) { + xx = x1 + min_x; + } else if (xx - x1 > max_x) { + xx = x1 + max_x; + } + if (yy > y1) { + yy = y1 + (xx - x1) / aspect; + } else { + yy = y1 - (xx - x1) / aspect; + } + } else if (xx < x1) { // left side + if (x1 - xx < min_x) { + xx = x1 - min_x; + } else if (x1 - xx > max_x) { + xx = x1 - max_x; + } + if (yy > y1) { + yy = y1 + (x1 - xx) / aspect; + } else { + yy = y1 - (x1 - xx) / aspect; + } + } + + if (xx < 0) { + x1 -= xx; + xx = 0; + } else if (xx > boundx) { + x1 -= xx - boundx; + xx = boundx; + } + + if (yy < 0) { + y1 -= yy; + yy = 0; + } else if (yy > boundy) { + y1 -= yy - boundy; + yy = boundy; + } + + return makeObj(flipCoords(x1, y1, xx, yy)); + } + //}}} + function rebound(p) //{{{ + { + if (p[0] < 0) p[0] = 0; + if (p[1] < 0) p[1] = 0; + + if (p[0] > boundx) p[0] = boundx; + if (p[1] > boundy) p[1] = boundy; + + return [Math.round(p[0]), Math.round(p[1])]; + } + //}}} + function flipCoords(x1, y1, x2, y2) //{{{ + { + var xa = x1, + xb = x2, + ya = y1, + yb = y2; + if (x2 < x1) { + xa = x2; + xb = x1; + } + if (y2 < y1) { + ya = y2; + yb = y1; + } + return [xa, ya, xb, yb]; + } + //}}} + function getRect() //{{{ + { + var xsize = x2 - x1, + ysize = y2 - y1, + delta; + + if (xlimit && (Math.abs(xsize) > xlimit)) { + x2 = (xsize > 0) ? (x1 + xlimit) : (x1 - xlimit); + } + if (ylimit && (Math.abs(ysize) > ylimit)) { + y2 = (ysize > 0) ? (y1 + ylimit) : (y1 - ylimit); + } + + if (ymin / yscale && (Math.abs(ysize) < ymin / yscale)) { + y2 = (ysize > 0) ? (y1 + ymin / yscale) : (y1 - ymin / yscale); + } + if (xmin / xscale && (Math.abs(xsize) < xmin / xscale)) { + x2 = (xsize > 0) ? (x1 + xmin / xscale) : (x1 - xmin / xscale); + } + + if (x1 < 0) { + x2 -= x1; + x1 -= x1; + } + if (y1 < 0) { + y2 -= y1; + y1 -= y1; + } + if (x2 < 0) { + x1 -= x2; + x2 -= x2; + } + if (y2 < 0) { + y1 -= y2; + y2 -= y2; + } + if (x2 > boundx) { + delta = x2 - boundx; + x1 -= delta; + x2 -= delta; + } + if (y2 > boundy) { + delta = y2 - boundy; + y1 -= delta; + y2 -= delta; + } + if (x1 > boundx) { + delta = x1 - boundy; + y2 -= delta; + y1 -= delta; + } + if (y1 > boundy) { + delta = y1 - boundy; + y2 -= delta; + y1 -= delta; + } + + return makeObj(flipCoords(x1, y1, x2, y2)); + } + //}}} + function makeObj(a) //{{{ + { + return { + x: a[0], + y: a[1], + x2: a[2], + y2: a[3], + w: a[2] - a[0], + h: a[3] - a[1] + }; + } + //}}} + + return { + flipCoords: flipCoords, + setPressed: setPressed, + setCurrent: setCurrent, + getOffset: getOffset, + moveOffset: moveOffset, + getCorner: getCorner, + getFixed: getFixed + }; + }()); + + //}}} + // Shade Module {{{ + var Shade = (function() { + var enabled = false, + holder = $('<div />').css({ + position: 'absolute', + zIndex: 240, + opacity: 0 + }), + shades = { + top: createShade(), + left: createShade().height(boundy), + right: createShade().height(boundy), + bottom: createShade() + }; + + function resizeShades(w,h) { + shades.left.css({ height: px(h) }); + shades.right.css({ height: px(h) }); + } + function updateAuto() + { + return updateShade(Coords.getFixed()); + } + function updateShade(c) + { + shades.top.css({ + left: px(c.x), + width: px(c.w), + height: px(c.y) + }); + shades.bottom.css({ + top: px(c.y2), + left: px(c.x), + width: px(c.w), + height: px(boundy-c.y2) + }); + shades.right.css({ + left: px(c.x2), + width: px(boundx-c.x2) + }); + shades.left.css({ + width: px(c.x) + }); + } + function createShade() { + return $('<div />').css({ + position: 'absolute', + backgroundColor: options.shadeColor||options.bgColor + }).appendTo(holder); + } + function enableShade() { + if (!enabled) { + enabled = true; + holder.insertBefore($img); + updateAuto(); + Selection.setBgOpacity(1,0,1); + $img2.hide(); + + setBgColor(options.shadeColor||options.bgColor,1); + if (Selection.isAwake()) + { + setOpacity(options.bgOpacity,1); + } + else setOpacity(1,1); + } + } + function setBgColor(color,now) { + colorChangeMacro(getShades(),color,now); + } + function disableShade() { + if (enabled) { + holder.remove(); + $img2.show(); + enabled = false; + if (Selection.isAwake()) { + Selection.setBgOpacity(options.bgOpacity,1,1); + } else { + Selection.setBgOpacity(1,1,1); + Selection.disableHandles(); + } + colorChangeMacro($div,0,1); + } + } + function setOpacity(opacity,now) { + if (enabled) { + if (options.bgFade && !now) { + holder.animate({ + opacity: 1-opacity + },{ + queue: false, + duration: options.fadeTime + }); + } + else holder.css({opacity:1-opacity}); + } + } + function refreshAll() { + options.shade ? enableShade() : disableShade(); + if (Selection.isAwake()) setOpacity(options.bgOpacity); + } + function getShades() { + return holder.children(); + } + + return { + update: updateAuto, + updateRaw: updateShade, + getShades: getShades, + setBgColor: setBgColor, + enable: enableShade, + disable: disableShade, + resize: resizeShades, + refresh: refreshAll, + opacity: setOpacity + }; + }()); + // }}} + // Selection Module {{{ + var Selection = (function () { + var awake, + hdep = 370, + borders = {}, + handle = {}, + dragbar = {}, + seehandles = false; + + // Private Methods + function insertBorder(type) //{{{ + { + var jq = $('<div />').css({ + position: 'absolute', + opacity: options.borderOpacity + }).addClass(cssClass(type)); + $img_holder.append(jq); + return jq; + } + //}}} + function dragDiv(ord, zi) //{{{ + { + var jq = $('<div />').mousedown(createDragger(ord)).css({ + cursor: ord + '-resize', + position: 'absolute', + zIndex: zi + }).addClass('ord-'+ord); + + if (Touch.support) { + jq.bind('touchstart.jcrop', Touch.createDragger(ord)); + } + + $hdl_holder.append(jq); + return jq; + } + //}}} + function insertHandle(ord) //{{{ + { + var hs = options.handleSize, + + div = dragDiv(ord, hdep++).css({ + opacity: options.handleOpacity + }).addClass(cssClass('handle')); + + if (hs) { div.width(hs).height(hs); } + + return div; + } + //}}} + function insertDragbar(ord) //{{{ + { + return dragDiv(ord, hdep++).addClass('jcrop-dragbar'); + } + //}}} + function createDragbars(li) //{{{ + { + var i; + for (i = 0; i < li.length; i++) { + dragbar[li[i]] = insertDragbar(li[i]); + } + } + //}}} + function createBorders(li) //{{{ + { + var cl,i; + for (i = 0; i < li.length; i++) { + switch(li[i]){ + case'n': cl='hline'; break; + case's': cl='hline bottom'; break; + case'e': cl='vline right'; break; + case'w': cl='vline'; break; + } + borders[li[i]] = insertBorder(cl); + } + } + //}}} + function createHandles(li) //{{{ + { + var i; + for (i = 0; i < li.length; i++) { + handle[li[i]] = insertHandle(li[i]); + } + } + //}}} + function moveto(x, y) //{{{ + { + if (!options.shade) { + $img2.css({ + top: px(-y), + left: px(-x) + }); + } + $sel.css({ + top: px(y), + left: px(x) + }); + } + //}}} + function resize(w, h) //{{{ + { + $sel.width(Math.round(w)).height(Math.round(h)); + } + //}}} + function refresh() //{{{ + { + var c = Coords.getFixed(); + + Coords.setPressed([c.x, c.y]); + Coords.setCurrent([c.x2, c.y2]); + + updateVisible(); + } + //}}} + + // Internal Methods + function updateVisible(select) //{{{ + { + if (awake) { + return update(select); + } + } + //}}} + function update(select) //{{{ + { + var c = Coords.getFixed(); + + resize(c.w, c.h); + moveto(c.x, c.y); + if (options.shade) Shade.updateRaw(c); + + awake || show(); + + if (select) { + options.onSelect.call(api, unscale(c)); + } else { + options.onChange.call(api, unscale(c)); + } + } + //}}} + function setBgOpacity(opacity,force,now) //{{{ + { + if (!awake && !force) return; + if (options.bgFade && !now) { + $img.animate({ + opacity: opacity + },{ + queue: false, + duration: options.fadeTime + }); + } else { + $img.css('opacity', opacity); + } + } + //}}} + function show() //{{{ + { + $sel.show(); + + if (options.shade) Shade.opacity(bgopacity); + else setBgOpacity(bgopacity,true); + + awake = true; + } + //}}} + function release() //{{{ + { + disableHandles(); + $sel.hide(); + + if (options.shade) Shade.opacity(1); + else setBgOpacity(1); + + awake = false; + options.onRelease.call(api); + } + //}}} + function showHandles() //{{{ + { + if (seehandles) { + $hdl_holder.show(); + } + } + //}}} + function enableHandles() //{{{ + { + seehandles = true; + if (options.allowResize) { + $hdl_holder.show(); + return true; + } + } + //}}} + function disableHandles() //{{{ + { + seehandles = false; + $hdl_holder.hide(); + } + //}}} + function animMode(v) //{{{ + { + if (v) { + animating = true; + disableHandles(); + } else { + animating = false; + enableHandles(); + } + } + //}}} + function done() //{{{ + { + animMode(false); + refresh(); + } + //}}} + // Insert draggable elements {{{ + // Insert border divs for outline + + if (options.dragEdges && $.isArray(options.createDragbars)) + createDragbars(options.createDragbars); + + if ($.isArray(options.createHandles)) + createHandles(options.createHandles); + + if (options.drawBorders && $.isArray(options.createBorders)) + createBorders(options.createBorders); + + //}}} + + // This is a hack for iOS5 to support drag/move touch functionality + $(document).bind('touchstart.jcrop-ios',function(e) { + if ($(e.currentTarget).hasClass('jcrop-tracker')) e.stopPropagation(); + }); + + var $track = newTracker().mousedown(createDragger('move')).css({ + cursor: 'move', + position: 'absolute', + zIndex: 360 + }); + + if (Touch.support) { + $track.bind('touchstart.jcrop', Touch.createDragger('move')); + } + + $img_holder.append($track); + disableHandles(); + + return { + updateVisible: updateVisible, + update: update, + release: release, + refresh: refresh, + isAwake: function () { + return awake; + }, + setCursor: function (cursor) { + $track.css('cursor', cursor); + }, + enableHandles: enableHandles, + enableOnly: function () { + seehandles = true; + }, + showHandles: showHandles, + disableHandles: disableHandles, + animMode: animMode, + setBgOpacity: setBgOpacity, + done: done + }; + }()); + + //}}} + // Tracker Module {{{ + var Tracker = (function () { + var onMove = function () {}, + onDone = function () {}, + trackDoc = options.trackDocument; + + function toFront(touch) //{{{ + { + $trk.css({ + zIndex: 450 + }); + + if (touch) + $(document) + .bind('touchmove.jcrop', trackTouchMove) + .bind('touchend.jcrop', trackTouchEnd); + + else if (trackDoc) + $(document) + .bind('mousemove.jcrop',trackMove) + .bind('mouseup.jcrop',trackUp); + } + //}}} + function toBack() //{{{ + { + $trk.css({ + zIndex: 290 + }); + $(document).unbind('.jcrop'); + } + //}}} + function trackMove(e) //{{{ + { + onMove(mouseAbs(e)); + return false; + } + //}}} + function trackUp(e) //{{{ + { + e.preventDefault(); + e.stopPropagation(); + + if (btndown) { + btndown = false; + + onDone(mouseAbs(e)); + + if (Selection.isAwake()) { + options.onSelect.call(api, unscale(Coords.getFixed())); + } + + toBack(); + onMove = function () {}; + onDone = function () {}; + } + + return false; + } + //}}} + function activateHandlers(move, done, touch) //{{{ + { + btndown = true; + onMove = move; + onDone = done; + toFront(touch); + return false; + } + //}}} + function trackTouchMove(e) //{{{ + { + onMove(mouseAbs(Touch.cfilter(e))); + return false; + } + //}}} + function trackTouchEnd(e) //{{{ + { + return trackUp(Touch.cfilter(e)); + } + //}}} + function setCursor(t) //{{{ + { + $trk.css('cursor', t); + } + //}}} + + if (!trackDoc) { + $trk.mousemove(trackMove).mouseup(trackUp).mouseout(trackUp); + } + + $img.before($trk); + return { + activateHandlers: activateHandlers, + setCursor: setCursor + }; + }()); + //}}} + // KeyManager Module {{{ + var KeyManager = (function () { + var $keymgr = $('<input type="radio" />').css({ + position: 'fixed', + left: '-120px', + width: '12px' + }).addClass('jcrop-keymgr'), + + $keywrap = $('<div />').css({ + position: 'absolute', + overflow: 'hidden' + }).append($keymgr); + + function watchKeys() //{{{ + { + if (options.keySupport) { + $keymgr.show(); + $keymgr.focus(); + } + } + //}}} + function onBlur(e) //{{{ + { + $keymgr.hide(); + } + //}}} + function doNudge(e, x, y) //{{{ + { + if (options.allowMove) { + Coords.moveOffset([x, y]); + Selection.updateVisible(true); + } + e.preventDefault(); + e.stopPropagation(); + } + //}}} + function parseKey(e) //{{{ + { + if (e.ctrlKey || e.metaKey) { + return true; + } + shift_down = e.shiftKey ? true : false; + var nudge = shift_down ? 10 : 1; + + switch (e.keyCode) { + case 37: + doNudge(e, -nudge, 0); + break; + case 39: + doNudge(e, nudge, 0); + break; + case 38: + doNudge(e, 0, -nudge); + break; + case 40: + doNudge(e, 0, nudge); + break; + case 27: + if (options.allowSelect) Selection.release(); + break; + case 9: + return true; + } + + return false; + } + //}}} + + if (options.keySupport) { + $keymgr.keydown(parseKey).blur(onBlur); + if (ie6mode || !options.fixedSupport) { + $keymgr.css({ + position: 'absolute', + left: '-20px' + }); + $keywrap.append($keymgr).insertBefore($img); + } else { + $keymgr.insertBefore($img); + } + } + + + return { + watchKeys: watchKeys + }; + }()); + //}}} + // }}} + // API methods {{{ + function setClass(cname) //{{{ + { + $div.removeClass().addClass(cssClass('holder')).addClass(cname); + } + //}}} + function animateTo(a, callback) //{{{ + { + var x1 = a[0] / xscale, + y1 = a[1] / yscale, + x2 = a[2] / xscale, + y2 = a[3] / yscale; + + if (animating) { + return; + } + + var animto = Coords.flipCoords(x1, y1, x2, y2), + c = Coords.getFixed(), + initcr = [c.x, c.y, c.x2, c.y2], + animat = initcr, + interv = options.animationDelay, + ix1 = animto[0] - initcr[0], + iy1 = animto[1] - initcr[1], + ix2 = animto[2] - initcr[2], + iy2 = animto[3] - initcr[3], + pcent = 0, + velocity = options.swingSpeed; + + x1 = animat[0]; + y1 = animat[1]; + x2 = animat[2]; + y2 = animat[3]; + + Selection.animMode(true); + var anim_timer; + + function queueAnimator() { + window.setTimeout(animator, interv); + } + var animator = (function () { + return function () { + pcent += (100 - pcent) / velocity; + + animat[0] = Math.round(x1 + ((pcent / 100) * ix1)); + animat[1] = Math.round(y1 + ((pcent / 100) * iy1)); + animat[2] = Math.round(x2 + ((pcent / 100) * ix2)); + animat[3] = Math.round(y2 + ((pcent / 100) * iy2)); + + if (pcent >= 99.8) { + pcent = 100; + } + if (pcent < 100) { + setSelectRaw(animat); + queueAnimator(); + } else { + Selection.done(); + Selection.animMode(false); + if (typeof(callback) === 'function') { + callback.call(api); + } + } + }; + }()); + queueAnimator(); + } + //}}} + function setSelect(rect) //{{{ + { + setSelectRaw([rect[0] / xscale, rect[1] / yscale, rect[2] / xscale, rect[3] / yscale]); + options.onSelect.call(api, unscale(Coords.getFixed())); + Selection.enableHandles(); + } + //}}} + function setSelectRaw(l) //{{{ + { + Coords.setPressed([l[0], l[1]]); + Coords.setCurrent([l[2], l[3]]); + Selection.update(); + } + //}}} + function tellSelect() //{{{ + { + return unscale(Coords.getFixed()); + } + //}}} + function tellScaled() //{{{ + { + return Coords.getFixed(); + } + //}}} + function setOptionsNew(opt) //{{{ + { + setOptions(opt); + interfaceUpdate(); + } + //}}} + function disableCrop() //{{{ + { + options.disabled = true; + Selection.disableHandles(); + Selection.setCursor('default'); + Tracker.setCursor('default'); + } + //}}} + function enableCrop() //{{{ + { + options.disabled = false; + interfaceUpdate(); + } + //}}} + function cancelCrop() //{{{ + { + Selection.done(); + Tracker.activateHandlers(null, null); + } + //}}} + function destroy() //{{{ + { + $div.remove(); + $origimg.show(); + $origimg.css('visibility','visible'); + $(obj).removeData('Jcrop'); + } + //}}} + function setImage(src, callback) //{{{ + { + Selection.release(); + disableCrop(); + var img = new Image(); + img.onload = function () { + var iw = img.width; + var ih = img.height; + var bw = options.boxWidth; + var bh = options.boxHeight; + $img.width(iw).height(ih); + $img.attr('src', src); + $img2.attr('src', src); + presize($img, bw, bh); + boundx = $img.width(); + boundy = $img.height(); + $img2.width(boundx).height(boundy); + $trk.width(boundx + (bound * 2)).height(boundy + (bound * 2)); + $div.width(boundx).height(boundy); + Shade.resize(boundx,boundy); + enableCrop(); + + if (typeof(callback) === 'function') { + callback.call(api); + } + }; + img.src = src; + } + //}}} + function colorChangeMacro($obj,color,now) { + var mycolor = color || options.bgColor; + if (options.bgFade && supportsColorFade() && options.fadeTime && !now) { + $obj.animate({ + backgroundColor: mycolor + }, { + queue: false, + duration: options.fadeTime + }); + } else { + $obj.css('backgroundColor', mycolor); + } + } + function interfaceUpdate(alt) //{{{ + // This method tweaks the interface based on options object. + // Called when options are changed and at end of initialization. + { + if (options.allowResize) { + if (alt) { + Selection.enableOnly(); + } else { + Selection.enableHandles(); + } + } else { + Selection.disableHandles(); + } + + Tracker.setCursor(options.allowSelect ? 'crosshair' : 'default'); + Selection.setCursor(options.allowMove ? 'move' : 'default'); + + if (options.hasOwnProperty('trueSize')) { + xscale = options.trueSize[0] / boundx; + yscale = options.trueSize[1] / boundy; + } + + if (options.hasOwnProperty('setSelect')) { + setSelect(options.setSelect); + Selection.done(); + delete(options.setSelect); + } + + Shade.refresh(); + + if (options.bgColor != bgcolor) { + colorChangeMacro( + options.shade? Shade.getShades(): $div, + options.shade? + (options.shadeColor || options.bgColor): + options.bgColor + ); + bgcolor = options.bgColor; + } + + if (bgopacity != options.bgOpacity) { + bgopacity = options.bgOpacity; + if (options.shade) Shade.refresh(); + else Selection.setBgOpacity(bgopacity); + } + + xlimit = options.maxSize[0] || 0; + ylimit = options.maxSize[1] || 0; + xmin = options.minSize[0] || 0; + ymin = options.minSize[1] || 0; + + if (options.hasOwnProperty('outerImage')) { + $img.attr('src', options.outerImage); + delete(options.outerImage); + } + + Selection.refresh(); + } + //}}} + //}}} + + if (Touch.support) $trk.bind('touchstart.jcrop', Touch.newSelection); + + $hdl_holder.hide(); + interfaceUpdate(true); + + var api = { + setImage: setImage, + animateTo: animateTo, + setSelect: setSelect, + setOptions: setOptionsNew, + tellSelect: tellSelect, + tellScaled: tellScaled, + setClass: setClass, + + disable: disableCrop, + enable: enableCrop, + cancel: cancelCrop, + release: Selection.release, + destroy: destroy, + + focus: KeyManager.watchKeys, + + getBounds: function () { + return [boundx * xscale, boundy * yscale]; + }, + getWidgetSize: function () { + return [boundx, boundy]; + }, + getScaleFactor: function () { + return [xscale, yscale]; + }, + getOptions: function() { + // careful: internal values are returned + return options; + }, + + ui: { + holder: $div, + selection: $sel + } + }; + + if (is_msie) $div.bind('selectstart', function () { return false; }); + + $origimg.data('Jcrop', api); + return api; + }; + $.fn.Jcrop = function (options, callback) //{{{ + { + var api; + // Iterate over each object, attach Jcrop + this.each(function () { + // If we've already attached to this object + if ($(this).data('Jcrop')) { + // The API can be requested this way (undocumented) + if (options === 'api') return $(this).data('Jcrop'); + // Otherwise, we just reset the options... + else $(this).data('Jcrop').setOptions(options); + } + // If we haven't been attached, preload and attach + else { + if (this.tagName == 'IMG') + $.Jcrop.Loader(this,function(){ + $(this).css({display:'block',visibility:'hidden'}); + api = $.Jcrop(this, options); + if ($.isFunction(callback)) callback.call(api); + }); + else { + $(this).css({display:'block',visibility:'hidden'}); + api = $.Jcrop(this, options); + if ($.isFunction(callback)) callback.call(api); + } + } + }); + + // Return "this" so the object is chainable (jQuery-style) + return this; + }; + //}}} + // $.Jcrop.Loader - basic image loader {{{ + + $.Jcrop.Loader = function(imgobj,success,error){ + var $img = $(imgobj), img = $img[0]; + + function completeCheck(){ + if (img.complete) { + $img.unbind('.jcloader'); + if ($.isFunction(success)) success.call(img); + } + else window.setTimeout(completeCheck,50); + } + + $img + .bind('load.jcloader',completeCheck) + .bind('error.jcloader',function(e){ + $img.unbind('.jcloader'); + if ($.isFunction(error)) error.call(img); + }); + + if (img.complete && $.isFunction(success)){ + $img.unbind('.jcloader'); + success.call(img); + } + }; + + //}}} + // Global Defaults {{{ + $.Jcrop.defaults = { + + // Basic Settings + allowSelect: true, + allowMove: true, + allowResize: true, + + trackDocument: true, + + // Styling Options + baseClass: 'jcrop', + addClass: null, + bgColor: 'black', + bgOpacity: 0.6, + bgFade: false, + borderOpacity: 0.4, + handleOpacity: 0.5, + handleSize: null, + + aspectRatio: 0, + keySupport: true, + createHandles: ['n','s','e','w','nw','ne','se','sw'], + createDragbars: ['n','s','e','w'], + createBorders: ['n','s','e','w'], + drawBorders: true, + dragEdges: true, + fixedSupport: true, + touchSupport: null, + + shade: null, + + boxWidth: 0, + boxHeight: 0, + boundary: 2, + fadeTime: 400, + animationDelay: 20, + swingSpeed: 3, + + minSelect: [0, 0], + maxSize: [0, 0], + minSize: [0, 0], + + // Callbacks / Event Handlers + onChange: function () {}, + onSelect: function () {}, + onDblClick: function () {}, + onRelease: function () {} + }; + + // }}} +}(jQuery)); diff --git a/static/plugins/jcrop/js/jquery.Jcrop.min.js b/static/plugins/jcrop/js/jquery.Jcrop.min.js new file mode 100755 index 0000000..4c9c7ad --- /dev/null +++ b/static/plugins/jcrop/js/jquery.Jcrop.min.js @@ -0,0 +1,22 @@ +/** + * jquery.Jcrop.min.js v0.9.12 (build:20130202) + * jQuery Image Cropping Plugin - released under MIT License + * Copyright (c) 2008-2013 Tapmodo Interactive LLC + * https://github.com/tapmodo/Jcrop + */ +(function(a){a.Jcrop=function(b,c){function i(a){return Math.round(a)+"px"}function j(a){return d.baseClass+"-"+a}function k(){return a.fx.step.hasOwnProperty("backgroundColor")}function l(b){var c=a(b).offset();return[c.left,c.top]}function m(a){return[a.pageX-e[0],a.pageY-e[1]]}function n(b){typeof b!="object"&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){typeof d[b]!="function"&&(d[b]=function(){})})}function o(a,b,c){e=l(D),bc.setCursor(a==="move"?a:a+"-resize");if(a==="move")return bc.activateHandlers(q(b),v,c);var d=_.getFixed(),f=r(a),g=_.getCorner(r(f));_.setPressed(_.getCorner(f)),_.setCurrent(g),bc.activateHandlers(p(a,d),v,c)}function p(a,b){return function(c){if(!d.aspectRatio)switch(a){case"e":c[1]=b.y2;break;case"w":c[1]=b.y2;break;case"n":c[0]=b.x2;break;case"s":c[0]=b.x2}else switch(a){case"e":c[1]=b.y+1;break;case"w":c[1]=b.y+1;break;case"n":c[0]=b.x+1;break;case"s":c[0]=b.x+1}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys +(),function(a){_.moveOffset([a[0]-b[0],a[1]-b[1]]),b=a,bb.update()}}function r(a){switch(a){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function s(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1)}}function t(a,b,c){var d=a.width(),e=a.height();d>b&&b>0&&(d=b,e=b/a.width()*a.height()),e>c&&c>0&&(e=c,d=c/a.height()*a.width()),T=a.width()/d,U=a.height()/e,a.width(d).height(e)}function u(a){return{x:a.x*T,y:a.y*U,x2:a.x2*T,y2:a.y2*U,w:a.w*T,h:a.h*U}}function v(a){var b=_.getFixed();b.w>d.minSelect[0]&&b.h>d.minSelect[1]?(bb.enableHandles(),bb.done()):bb.release(),bc.setCursor(d.allowSelect?"crosshair":"default")}function w(a){if(d.disabled)return!1;if(!d.allowSelect)return!1;W=!0,e=l(D),bb.disableHandles(),bc.setCursor("crosshair");var b=m(a);return _.setPressed(b),bb.update(),bc.activateHandlers(x,v,a.type.substring +(0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("<div></div>").addClass(j("tracker"));return g&&b.css({opacity:0,backgroundColor:"white"}),b}function be(a){G.removeClass().addClass(j("holder")).addClass(a)}function bf(a,b){function t(){window.setTimeout(u,l)}var c=a[0]/T,e=a[1]/U,f=a[2]/T,g=a[3]/U;if(X)return;var h=_.flipCoords(c,e,f,g),i=_.getFixed(),j=[i.x,i.y,i.x2,i.y2],k=j,l=d.animationDelay,m=h[0]-j[0],n=h[1]-j[1],o=h[2]-j[2],p=h[3]-j[3],q=0,r=d.swingSpeed;c=k[0],e=k[1],f=k[2],g=k[3],bb.animMode(!0);var s,u=function(){return function(){q+=(100-q)/r,k[0]=Math.round(c+q/100*m),k[1]=Math.round(e+q/100*n),k[2]=Math.round(f+q/100*o),k[3]=Math.round(g+q/100*p),q>=99.8&&(q=100),q<100?(bh(k),t()):(bb.done(),bb.animMode(!1),typeof b=="function"&&b.call(bs))}}();t()}function bg(a){bh([a[0]/T,a[1]/U,a[2]/T,a[3]/U]),d.onSelect.call(bs,u(_.getFixed())),bb.enableHandles()}function bh(a){_.setPressed([a[0],a[1]]),_.setCurrent([a[2], +a[3]]),bb.update()}function bi(){return u(_.getFixed())}function bj(){return _.getFixed()}function bk(a){n(a),br()}function bl(){d.disabled=!0,bb.disableHandles(),bb.setCursor("default"),bc.setCursor("default")}function bm(){d.disabled=!1,br()}function bn(){bb.done(),bc.activateHandlers(null,null)}function bo(){G.remove(),A.show(),A.css("visibility","visible"),a(b).removeData("Jcrop")}function bp(a,b){bb.release(),bl();var c=new Image;c.onload=function(){var e=c.width,f=c.height,g=d.boxWidth,h=d.boxHeight;D.width(e).height(f),D.attr("src",a),H.attr("src",a),t(D,g,h),E=D.width(),F=D.height(),H.width(E).height(F),M.width(E+L*2).height(F+L*2),G.width(E).height(F),ba.resize(E,F),bm(),typeof b=="function"&&b.call(bs)},c.src=a}function bq(a,b,c){var e=b||d.bgColor;d.bgFade&&k()&&d.fadeTime&&!c?a.animate({backgroundColor:e},{queue:!1,duration:d.fadeTime}):a.css("backgroundColor",e)}function br(a){d.allowResize?a?bb.enableOnly():bb.enableHandles():bb.disableHandles(),bc.setCursor(d.allowSelect?"crosshair":"default"),bb +.setCursor(d.allowMove?"move":"default"),d.hasOwnProperty("trueSize")&&(T=d.trueSize[0]/E,U=d.trueSize[1]/F),d.hasOwnProperty("setSelect")&&(bg(d.setSelect),bb.done(),delete d.setSelect),ba.refresh(),d.bgColor!=N&&(bq(d.shade?ba.getShades():G,d.shade?d.shadeColor||d.bgColor:d.bgColor),N=d.bgColor),O!=d.bgOpacity&&(O=d.bgOpacity,d.shade?ba.refresh():bb.setBgOpacity(O)),P=d.maxSize[0]||0,Q=d.maxSize[1]||0,R=d.minSize[0]||0,S=d.minSize[1]||0,d.hasOwnProperty("outerImage")&&(D.attr("src",d.outerImage),delete d.outerImage),bb.refresh()}var d=a.extend({},a.Jcrop.defaults),e,f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);typeof b!="object"&&(b=a(b)[0]),typeof c!="object"&&(c={}),n(c);var z={border:"none",visibility:"visible",margin:0,padding:0,position:"absolute",top:0,left:0},A=a(b),B=!0;if(b.tagName=="IMG"){if(A[0].width!=0&&A[0].height!=0)A.width(A[0].width),A.height(A[0].height);else{var C=new Image;C.src=A[0].src,A.width(C.width),A.height(C.height)}var D=A.clone().removeAttr("id"). +css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,d.shade===null&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("<div />").width(E).height(F).addClass(j("holder")).css({position:"relative",backgroundColor:d.bgColor}).insertAfter(A).append(D);d.addClass&&G.addClass(d.addClass);var H=a("<div />"),I=a("<div />").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("<div />").width("100%").height("100%").css("zIndex",320),K=a("<div />").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("<img />").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var L=d.boundary,M=y().width(E+L*2).height(F+L*2).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity,P,Q,R,S,T,U,V=!0,W,X,Y;e=l(D);var Z=function(){function a(){var a={},b=["touchstart" +,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;d<b.length;d++){var e=b[d];e="on"+e;var f=e in c;f||(c.setAttribute(e,"return;"),f=typeof c[e]=="function"),a[b[d]]=f}return a.touchstart&&a.touchend&&a.touchmove}catch(g){return!1}}function b(){return d.touchSupport===!0||d.touchSupport===!1?d.touchSupport:a()}return{createDragger:function(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(Z.cfilter(b)),!0),b.stopPropagation(),b.preventDefault(),!1)}},newSelection:function(a){return w(Z.cfilter(a))},cfilter:function(a){return a.pageX=a.originalEvent.changedTouches[0].pageX,a.pageY=a.originalEvent.changedTouches[0].pageY,a},isSupported:a,support:b()}}(),_=function(){function h(d){d=n(d),c=a=d[0],e=b=d[1]}function i(a){a=n(a),f=a[0]-c,g=a[1]-e,c=a[0],e=a[1]}function j(){return[f,g]}function k(d){var f=d[0],g=d[1];0>a+f&&(f-=f+a),0>b+g&&(g-=g+b),F<e+g&&(g+=F-(e+g)),E<c+f&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[ +b.x2,b.y];case"nw":return[b.x,b.y];case"se":return[b.x2,b.y2];case"sw":return[b.x,b.y2]}}function m(){if(!d.aspectRatio)return p();var f=d.aspectRatio,g=d.minSize[0]/T,h=d.maxSize[0]/T,i=d.maxSize[1]/U,j=c-a,k=e-b,l=Math.abs(j),m=Math.abs(k),n=l/m,r,s,t,u;return h===0&&(h=E*10),i===0&&(i=F*10),n<f?(s=e,t=m*f,r=j<0?a-t:t+a,r<0?(r=0,u=Math.abs((r-a)/f),s=k<0?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=k<0?b-u:u+b)):(r=c,u=l/f,s=k<0?b-u:b+u,s<0?(s=0,t=Math.abs((s-b)*f),r=j<0?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=j<0?a-t:t+a)),r>a?(r-a<g?r=a+g:r-a>h&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):r<a&&(a-r<g?r=a-g:a-r>h&&(r=a-h),s>b?s=b+(a-r)/f:s=b-(a-r)/f),r<0?(a-=r,r=0):r>E&&(a-=r-E,r=E),s<0?(b-=s,s=0):s>F&&(b-=s-F,s=F),q(o(a,b,r,s))}function n(a){return a[0]<0&&(a[0]=0),a[1]<0&&(a[1]=0),a[0]>E&&(a[0]=E),a[1]>F&&(a[1]=F),[Math.round(a[0]),Math.round(a[1])]}function o(a,b,c,d){var e=a,f=c,g=b,h=d;return c<a&&(e=c,f=a),d<b&&(g=d,h=b),[e,g,f,h]}function p(){var d=c-a,f=e-b,g;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs +(f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)<S/U&&(e=f>0?b+S/U:b-S/U),R/T&&Math.abs(d)<R/T&&(c=d>0?a+R/T:a-R/T),a<0&&(c-=a,a-=a),b<0&&(e-=b,b-=b),c<0&&(a-=c,c-=c),e<0&&(b-=e,e-=e),c>E&&(g=c-E,a-=g,c-=g),e>F&&(g=e-F,b-=g,e-=g),a>E&&(g=a-F,e-=g,b-=g),b>F&&(g=b-F,e-=g,b-=g),q(o(a,b,c,e))}function q(a){return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]}}var a=0,b=0,c=0,e=0,f,g;return{flipCoords:o,setPressed:h,setCurrent:i,getOffset:j,moveOffset:k,getCorner:l,getFixed:m}}(),ba=function(){function f(a,b){e.left.css({height:i(b)}),e.right.css({height:i(b)})}function g(){return h(_.getFixed())}function h(a){e.top.css({left:i(a.x),width:i(a.w),height:i(a.y)}),e.bottom.css({top:i(a.y2),left:i(a.x),width:i(a.w),height:i(F-a.y2)}),e.right.css({left:i(a.x2),width:i(E-a.x2)}),e.left.css({width:i(a.x)})}function j(){return a("<div />").css({position:"absolute",backgroundColor:d.shadeColor||d.bgColor}).appendTo(c)}function k(){b||(b=!0,c.insertBefore(D),g(),bb.setBgOpacity(1,0,1),H.hide(),l(d.shadeColor||d.bgColor,1),bb. +isAwake()?n(d.bgOpacity,1):n(1,1))}function l(a,b){bq(p(),a,b)}function m(){b&&(c.remove(),H.show(),b=!1,bb.isAwake()?bb.setBgOpacity(d.bgOpacity,1,1):(bb.setBgOpacity(1,1,1),bb.disableHandles()),bq(G,0,1))}function n(a,e){b&&(d.bgFade&&!e?c.animate({opacity:1-a},{queue:!1,duration:d.fadeTime}):c.css({opacity:1-a}))}function o(){d.shade?k():m(),bb.isAwake()&&n(d.bgOpacity)}function p(){return c.children()}var b=!1,c=a("<div />").css({position:"absolute",zIndex:240,opacity:0}),e={top:j(),left:j().height(F),right:j().height(F),bottom:j()};return{update:g,updateRaw:h,getShades:p,setBgColor:l,enable:k,disable:m,resize:f,refresh:o,opacity:n}}(),bb=function(){function k(b){var c=a("<div />").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("<div />").mousedown(s(b)).css({cursor:b+"-resize",position:"absolute",zIndex:c}).addClass("ord-"+b);return Z.support&&d.bind("touchstart.jcrop",Z.createDragger(b)),J.append(d),d}function m(a){var b=d.handleSize,e=l(a,c++ +).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b<a.length;b++)g[a[b]]=n(a[b])}function p(a){var b,c;for(c=0;c<a.length;c++){switch(a[c]){case"n":b="hline";break;case"s":b="hline bottom";break;case"e":b="vline right";break;case"w":b="vline"}e[a[c]]=k(b)}}function q(a){var b;for(b=0;b<a.length;b++)f[a[b]]=m(a[b])}function r(a,b){d.shade||H.css({top:i(-b),left:i(-a)}),K.css({top:i(b),left:i(a)})}function t(a,b){K.width(Math.round(a)).height(Math.round(b))}function v(){var a=_.getFixed();_.setPressed([a.x,a.y]),_.setCurrent([a.x2,a.y2]),w()}function w(a){if(b)return x(a)}function x(a){var c=_.getFixed();t(c.w,c.h),r(c.x,c.y),d.shade&&ba.updateRaw(c),b||A(),a?d.onSelect.call(bs,u(c)):d.onChange.call(bs,u(c))}function z(a,c,e){if(!b&&!c)return;d.bgFade&&!e?D.animate({opacity:a},{queue:!1,duration:d.fadeTime}):D.css("opacity",a)}function A(){K.show(),d.shade?ba.opacity(O):z(O,!0),b=!0}function B +(){F(),K.hide(),d.shade?ba.opacity(1):z(1),b=!1,d.onRelease.call(bs)}function C(){h&&J.show()}function E(){h=!0;if(d.allowResize)return J.show(),!0}function F(){h=!1,J.hide()}function G(a){a?(X=!0,F()):(X=!1,E())}function L(){G(!1),v()}var b,c=370,e={},f={},g={},h=!1;d.dragEdges&&a.isArray(d.createDragbars)&&o(d.createDragbars),a.isArray(d.createHandles)&&q(d.createHandles),d.drawBorders&&a.isArray(d.createBorders)&&p(d.createBorders),a(document).bind("touchstart.jcrop-ios",function(b){a(b.currentTarget).hasClass("jcrop-tracker")&&b.stopPropagation()});var M=y().mousedown(s("move")).css({cursor:"move",position:"absolute",zIndex:360});return Z.support&&M.bind("touchstart.jcrop",Z.createDragger("move")),I.append(M),F(),{updateVisible:w,update:x,release:B,refresh:v,isAwake:function(){return b},setCursor:function(a){M.css("cursor",a)},enableHandles:E,enableOnly:function(){h=!0},showHandles:C,disableHandles:F,animMode:G,setBgOpacity:z,done:L}}(),bc=function(){function f(b){M.css({zIndex:450}),b?a(document).bind("touchmove.jcrop" +,k).bind("touchend.jcrop",l):e&&a(document).bind("mousemove.jcrop",h).bind("mouseup.jcrop",i)}function g(){M.css({zIndex:290}),a(document).unbind(".jcrop")}function h(a){return b(m(a)),!1}function i(a){return a.preventDefault(),a.stopPropagation(),W&&(W=!1,c(m(a)),bb.isAwake()&&d.onSelect.call(bs,u(_.getFixed())),g(),b=function(){},c=function(){}),!1}function j(a,d,e){return W=!0,b=a,c=d,f(e),!1}function k(a){return b(m(Z.cfilter(a))),!1}function l(a){return i(Z.cfilter(a))}function n(a){M.css("cursor",a)}var b=function(){},c=function(){},e=d.trackDocument;return e||M.mousemove(h).mouseup(i).mouseout(i),D.before(M),{activateHandlers:j,setCursor:n}}(),bd=function(){function e(){d.keySupport&&(b.show(),b.focus())}function f(a){b.hide()}function g(a,b,c){d.allowMove&&(_.moveOffset([b,c]),bb.updateVisible(!0)),a.preventDefault(),a.stopPropagation()}function i(a){if(a.ctrlKey||a.metaKey)return!0;Y=a.shiftKey?!0:!1;var b=Y?10:1;switch(a.keyCode){case 37:g(a,-b,0);break;case 39:g(a,b,0);break;case 38:g(a,0,-b);break; +case 40:g(a,0,b);break;case 27:d.allowSelect&&bb.release();break;case 9:return!0}return!1}var b=a('<input type="radio" />').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("<div />").css({position:"absolute",overflow:"hidden"}).append(b);return d.keySupport&&(b.keydown(i).blur(f),h||!d.fixedSupport?(b.css({position:"absolute",left:"-20px"}),c.append(b).insertBefore(D)):b.insertBefore(D)),{watchKeys:e}}();Z.support&&M.bind("touchstart.jcrop",Z.newSelection),J.hide(),br(!0);var bs={setImage:bp,animateTo:bf,setSelect:bg,setOptions:bk,tellSelect:bi,tellScaled:bj,setClass:be,disable:bl,enable:bm,cancel:bn,release:bb.release,destroy:bo,focus:bd.watchKeys,getBounds:function(){return[E*T,F*U]},getWidgetSize:function(){return[E,F]},getScaleFactor:function(){return[T,U]},getOptions:function(){return d},ui:{holder:G,selection:K}};return g&&G.bind("selectstart",function(){return!1}),A.data("Jcrop",bs),bs},a.fn.Jcrop=function(b,c){var d;return this.each(function(){if(a(this).data("Jcrop")){if( +b==="api")return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else this.tagName=="IMG"?a.Jcrop.Loader(this,function(){a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d)}):(a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d))}),this},a.Jcrop.Loader=function(b,c,d){function g(){f.complete?(e.unbind(".jcloader"),a.isFunction(c)&&c.call(f)):window.setTimeout(g,50)}var e=a(b),f=e[0];e.bind("load.jcloader",g).bind("error.jcloader",function(b){e.unbind(".jcloader"),a.isFunction(d)&&d.call(f)}),f.complete&&a.isFunction(c)&&(e.unbind(".jcloader"),c.call(f))},a.Jcrop.defaults={allowSelect:!0,allowMove:!0,allowResize:!0,trackDocument:!0,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:.6,bgFade:!1,borderOpacity:.4,handleOpacity:.5,handleSize:null,aspectRatio:0,keySupport:!0,createHandles:["n","s","e","w","nw","ne","se","sw"],createDragbars:["n","s","e","w"],createBorders:["n","s","e","w"],drawBorders:!0,dragEdges +:!0,fixedSupport:!0,touchSupport:null,shade:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onDblClick:function(){},onRelease:function(){}}})(jQuery); \ No newline at end of file diff --git a/static/plugins/kindeditor/kindeditor-all.js b/static/plugins/kindeditor/kindeditor-all.js new file mode 100755 index 0000000..85c8ef4 --- /dev/null +++ b/static/plugins/kindeditor/kindeditor-all.js @@ -0,0 +1,9898 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2016 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @website http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +* @version 4.1.11 (2016-03-31) +*******************************************************************************/ +(function (window, undefined) { + if (window.KindEditor) { + return; + } + + +if (!window.console) { + window.console = {}; +} +if (!console.log) { + console.log = function () {}; +} +var _VERSION = '4.1.11 (2016-03-31)', + _ua = navigator.userAgent.toLowerCase(), + _IE = _ua.indexOf('msie') > -1 && _ua.indexOf('opera') == -1, + _NEWIE = _ua.indexOf('msie') == -1 && _ua.indexOf('trident') > -1, + _GECKO = _ua.indexOf('gecko') > -1 && _ua.indexOf('khtml') == -1, + _WEBKIT = _ua.indexOf('applewebkit') > -1, + _OPERA = _ua.indexOf('opera') > -1, + _MOBILE = _ua.indexOf('mobile') > -1, + _IOS = /ipad|iphone|ipod/.test(_ua), + _QUIRKS = document.compatMode != 'CSS1Compat', + _IERANGE = !window.getSelection, + _matches = /(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua), + _V = _matches ? _matches[1] : '0', + _TIME = new Date().getTime(); +function _isArray(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Array]'; +} +function _isFunction(val) { + if (!val) { + return false; + } + return Object.prototype.toString.call(val) === '[object Function]'; +} +function _inArray(val, arr) { + for (var i = 0, len = arr.length; i < len; i++) { + if (val === arr[i]) { + return i; + } + } + return -1; +} +function _each(obj, fn) { + if (_isArray(obj)) { + for (var i = 0, len = obj.length; i < len; i++) { + if (fn.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if (fn.call(obj[key], key, obj[key]) === false) { + break; + } + } + } + } +} +function _trim(str) { + return str.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, ''); +} +function _inString(val, str, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + return (delimiter + str + delimiter).indexOf(delimiter + val + delimiter) >= 0; +} +function _addUnit(val, unit) { + unit = unit || 'px'; + return val && /^-?\d+(?:\.\d+)?$/.test(val) ? val + unit : val; +} +function _removeUnit(val) { + var match; + return val && (match = /(\d+)/.exec(val)) ? parseInt(match[1], 10) : 0; +} +function _escape(val) { + return val.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); +} +function _unescape(val) { + return val.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&amp;/g, '&'); +} +function _toCamel(str) { + var arr = str.split('-'); + str = ''; + _each(arr, function(key, val) { + str += (key > 0) ? val.charAt(0).toUpperCase() + val.substr(1) : val; + }); + return str; +} +function _toHex(val) { + function hex(d) { + var s = parseInt(d, 10).toString(16).toUpperCase(); + return s.length > 1 ? s : '0' + s; + } + return val.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/ig, + function($0, $1, $2, $3) { + return '#' + hex($1) + hex($2) + hex($3); + } + ); +} +function _toMap(val, delimiter) { + delimiter = delimiter === undefined ? ',' : delimiter; + var map = {}, arr = _isArray(val) ? val : val.split(delimiter), match; + _each(arr, function(key, val) { + if ((match = /^(\d+)\.\.(\d+)$/.exec(val))) { + for (var i = parseInt(match[1], 10); i <= parseInt(match[2], 10); i++) { + map[i.toString()] = true; + } + } else { + map[val] = true; + } + }); + return map; +} +function _toArray(obj, offset) { + return Array.prototype.slice.call(obj, offset || 0); +} +function _undef(val, defaultVal) { + return val === undefined ? defaultVal : val; +} +function _invalidUrl(url) { + return !url || /[<>"]/.test(url); +} +function _addParam(url, param) { + return url.indexOf('?') >= 0 ? url + '&' + param : url + '?' + param; +} +function _extend(child, parent, proto) { + if (!proto) { + proto = parent; + parent = null; + } + var childProto; + if (parent) { + var fn = function () {}; + fn.prototype = parent.prototype; + childProto = new fn(); + _each(proto, function(key, val) { + childProto[key] = val; + }); + } else { + childProto = proto; + } + childProto.constructor = child; + child.prototype = childProto; + child.parent = parent ? parent.prototype : null; +} + + +function _json(text) { + var match; + if ((match = /\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))) { + text = match[0]; + } + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + if (/^[\],:{}\s]*$/. + test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). + replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). + replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + return eval('(' + text + ')'); + } + throw 'JSON parse error'; +} +var _round = Math.round; +var K = { + DEBUG : false, + VERSION : _VERSION, + IE : _IE, + GECKO : _GECKO, + WEBKIT : _WEBKIT, + OPERA : _OPERA, + V : _V, + TIME : _TIME, + each : _each, + isArray : _isArray, + isFunction : _isFunction, + inArray : _inArray, + inString : _inString, + trim : _trim, + addUnit : _addUnit, + removeUnit : _removeUnit, + escape : _escape, + unescape : _unescape, + toCamel : _toCamel, + toHex : _toHex, + toMap : _toMap, + toArray : _toArray, + undef : _undef, + invalidUrl : _invalidUrl, + addParam : _addParam, + extend : _extend, + json : _json +}; +var _INLINE_TAG_MAP = _toMap('a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'), + _BLOCK_TAG_MAP = _toMap('address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul'), + _SINGLE_TAG_MAP = _toMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'), + _STYLE_TAG_MAP = _toMap('b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u'), + _CONTROL_TAG_MAP = _toMap('img,table,input,textarea,button'), + _PRE_TAG_MAP = _toMap('pre,style,script'), + _NOSPLIT_TAG_MAP = _toMap('html,head,body,td,tr,table,ol,ul,li'), + _AUTOCLOSE_TAG_MAP = _toMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'), + _FILL_ATTR_MAP = _toMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'), + _VALUE_TAG_MAP = _toMap('input,button,textarea,select'); + + +function _getBasePath() { + var els = document.getElementsByTagName('script'), src; + for (var i = 0, len = els.length; i < len; i++) { + src = els[i].src || ''; + if (/kindeditor[\w\-\.]*\.js/.test(src)) { + return src.substring(0, src.lastIndexOf('/') + 1); + } + } + return ''; +} +K.basePath = _getBasePath(); +K.options = { + designMode : true, + fullscreenMode : false, + filterMode : true, + wellFormatMode : true, + shadowMode : true, + loadStyleMode : true, + basePath : K.basePath, + themesPath : K.basePath + 'themes/', + langPath : K.basePath + 'lang/', + pluginsPath : K.basePath + 'plugins/', + themeType : 'default', + langType : 'zh-CN', + urlType : '', + newlineTag : 'p', + resizeType : 2, + syncType : 'form', + pasteType : 2, + dialogAlignType : 'page', + useContextmenu : true, + fullscreenShortcut : false, + bodyClass : 'ke-content', + indentChar : '\t', + cssPath : '', + cssData : '', + minWidth : 650, + minHeight : 100, + minChangeSize : 50, + zIndex : 811213000, + items : [ + 'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste', + 'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright', + 'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript', + 'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/', + 'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', + 'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage', + 'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak', + 'anchor', 'link', 'unlink', '|', 'about' + ], + noDisableItems : ['source', 'fullscreen'], + colorTable : [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ], + fontSizeTable : ['9px', '10px', '12px', '14px', '16px', '18px', '24px', '32px'], + htmlTags : { + font : ['id', 'class', 'color', 'size', 'face', '.background-color'], + span : [ + 'id', 'class', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.line-height' + ], + div : [ + 'id', 'class', 'align', '.border', '.margin', '.padding', '.text-align', '.color', + '.background-color', '.font-size', '.font-family', '.font-weight', '.background', + '.font-style', '.text-decoration', '.vertical-align', '.margin-left' + ], + table: [ + 'id', 'class', 'border', 'cellspacing', 'cellpadding', 'width', 'height', 'align', 'bordercolor', + '.padding', '.margin', '.border', 'bgcolor', '.text-align', '.color', '.background-color', + '.font-size', '.font-family', '.font-weight', '.font-style', '.text-decoration', '.background', + '.width', '.height', '.border-collapse' + ], + 'td,th': [ + 'id', 'class', 'align', 'valign', 'width', 'height', 'colspan', 'rowspan', 'bgcolor', + '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.font-weight', + '.font-style', '.text-decoration', '.vertical-align', '.background', '.border' + ], + a : ['id', 'class', 'href', 'target', 'name'], + embed : ['id', 'class', 'src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess', 'wmode'], + img : ['id', 'class', 'src', 'width', 'height', 'border', 'alt', 'title', 'align', '.width', '.height', '.border'], + 'p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [ + 'id', 'class', 'align', '.text-align', '.color', '.background-color', '.font-size', '.font-family', '.background', + '.font-weight', '.font-style', '.text-decoration', '.vertical-align', '.text-indent', '.margin-left' + ], + pre : ['id', 'class'], + hr : ['id', 'class', '.page-break-after'], + 'br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del' : ['id', 'class'], + iframe : ['id', 'class', 'src', 'frameborder', 'width', 'height', '.width', '.height'] + }, + layout : '<div class="container"><div class="toolbar"></div><div class="edit"></div><div class="statusbar"></div></div>' +}; + + +var _useCapture = false; + + +var _INPUT_KEY_MAP = _toMap('8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222'); + +var _CURSORMOVE_KEY_MAP = _toMap('33..40'); + +var _CHANGE_KEY_MAP = {}; +_each(_INPUT_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); +_each(_CURSORMOVE_KEY_MAP, function(key, val) { + _CHANGE_KEY_MAP[key] = val; +}); + + +function _bindEvent(el, type, fn) { + if (el.addEventListener){ + el.addEventListener(type, fn, _useCapture); + } else if (el.attachEvent){ + el.attachEvent('on' + type, fn); + } +} + +function _unbindEvent(el, type, fn) { + if (el.removeEventListener){ + el.removeEventListener(type, fn, _useCapture); + } else if (el.detachEvent){ + el.detachEvent('on' + type, fn); + } +} +var _EVENT_PROPS = ('altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,' + + 'data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,' + + 'pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which').split(','); + + +function KEvent(el, event) { + this.init(el, event); +} +_extend(KEvent, { + init : function(el, event) { + var self = this, doc = el.ownerDocument || el.document || el; + self.event = event; + _each(_EVENT_PROPS, function(key, val) { + self[val] = event[val]; + }); + if (!self.target) { + self.target = self.srcElement || doc; + } + if (self.target.nodeType === 3) { + self.target = self.target.parentNode; + } + if (!self.relatedTarget && self.fromElement) { + self.relatedTarget = self.fromElement === self.target ? self.toElement : self.fromElement; + } + if (self.pageX == null && self.clientX != null) { + var d = doc.documentElement, body = doc.body; + self.pageX = self.clientX + (d && d.scrollLeft || body && body.scrollLeft || 0) - (d && d.clientLeft || body && body.clientLeft || 0); + self.pageY = self.clientY + (d && d.scrollTop || body && body.scrollTop || 0) - (d && d.clientTop || body && body.clientTop || 0); + } + if (!self.which && ((self.charCode || self.charCode === 0) ? self.charCode : self.keyCode)) { + self.which = self.charCode || self.keyCode; + } + if (!self.metaKey && self.ctrlKey) { + self.metaKey = self.ctrlKey; + } + if (!self.which && self.button !== undefined) { + self.which = (self.button & 1 ? 1 : (self.button & 2 ? 3 : (self.button & 4 ? 2 : 0))); + } + switch (self.which) { + case 186 : + self.which = 59; + break; + case 187 : + case 107 : + case 43 : + self.which = 61; + break; + case 189 : + case 45 : + self.which = 109; + break; + case 42 : + self.which = 106; + break; + case 47 : + self.which = 111; + break; + case 78 : + self.which = 110; + break; + } + if (self.which >= 96 && self.which <= 105) { + self.which -= 48; + } + }, + preventDefault : function() { + var ev = this.event; + if (ev.preventDefault) { + ev.preventDefault(); + } else { + ev.returnValue = false; + } + }, + stopPropagation : function() { + var ev = this.event; + if (ev.stopPropagation) { + ev.stopPropagation(); + } else { + ev.cancelBubble = true; + } + }, + stop : function() { + this.preventDefault(); + this.stopPropagation(); + } +}); +var _eventExpendo = 'kindeditor_' + _TIME, _eventId = 0, _eventData = {}; +function _getId(el) { + return el[_eventExpendo] || null; +} +function _setId(el) { + el[_eventExpendo] = ++_eventId; + return _eventId; +} +function _removeId(el) { + try { + delete el[_eventExpendo]; + } catch(e) { + if (el.removeAttribute) { + el.removeAttribute(_eventExpendo); + } + } +} +function _bind(el, type, fn) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _bind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + id = _setId(el); + } + if (_eventData[id] === undefined) { + _eventData[id] = {}; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + _unbindEvent(el, type, events[0]); + } else { + _eventData[id][type] = []; + _eventData[id].el = el; + } + events = _eventData[id][type]; + if (events.length === 0) { + events[0] = function(e) { + var kevent = e ? new KEvent(el, e) : undefined; + _each(events, function(i, event) { + if (i > 0 && event) { + event.call(el, kevent); + } + }); + }; + } + if (_inArray(fn, events) < 0) { + events.push(fn); + } + _bindEvent(el, type, events[0]); +} +function _unbind(el, type, fn) { + if (type && type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _unbind(el, this, fn); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + if (type === undefined) { + if (id in _eventData) { + _each(_eventData[id], function(key, events) { + if (key != 'el' && events.length > 0) { + _unbindEvent(el, key, events[0]); + } + }); + delete _eventData[id]; + _removeId(el); + } + return; + } + if (!_eventData[id]) { + return; + } + var events = _eventData[id][type]; + if (events && events.length > 0) { + if (fn === undefined) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } else { + _each(events, function(i, event) { + if (i > 0 && event === fn) { + events.splice(i, 1); + } + }); + if (events.length == 1) { + _unbindEvent(el, type, events[0]); + delete _eventData[id][type]; + } + } + var count = 0; + _each(_eventData[id], function() { + count++; + }); + if (count < 2) { + delete _eventData[id]; + _removeId(el); + } + } +} +function _fire(el, type) { + if (type.indexOf(',') >= 0) { + _each(type.split(','), function() { + _fire(el, this); + }); + return; + } + var id = _getId(el); + if (!id) { + return; + } + var events = _eventData[id][type]; + if (_eventData[id] && events && events.length > 0) { + events[0](); + } +} +function _ctrl(el, key, fn) { + var self = this; + key = /^\d{2,}$/.test(key) ? key : key.toUpperCase().charCodeAt(0); + _bind(el, 'keydown', function(e) { + if (e.ctrlKey && e.which == key && !e.shiftKey && !e.altKey) { + fn.call(el); + e.stop(); + } + }); +} +var _readyFinished = false; +function _ready(fn) { + if (_readyFinished) { + fn(KindEditor); + return; + } + var loaded = false; + function readyFunc() { + if (!loaded) { + loaded = true; + fn(KindEditor); + _readyFinished = true; + } + } + function ieReadyFunc() { + if (!loaded) { + try { + document.documentElement.doScroll('left'); + } catch(e) { + setTimeout(ieReadyFunc, 100); + return; + } + readyFunc(); + } + } + function ieReadyStateFunc() { + if (document.readyState === 'complete') { + readyFunc(); + } + } + if (document.addEventListener) { + _bind(document, 'DOMContentLoaded', readyFunc); + } else if (document.attachEvent) { + _bind(document, 'readystatechange', ieReadyStateFunc); + var toplevel = false; + try { + toplevel = window.frameElement == null; + } catch(e) {} + if (document.documentElement.doScroll && toplevel) { + ieReadyFunc(); + } + } + _bind(window, 'load', readyFunc); +} +if (window.attachEvent) { + window.attachEvent('onunload', function() { + _each(_eventData, function(key, events) { + if (events.el) { + _unbind(events.el); + } + }); + }); +} +K.ctrl = _ctrl; +K.ready = _ready; + +function _getCssList(css) { + var list = {}, + reg = /\s*([\w\-]+)\s*:([^;]*)(;|$)/g, + match; + while ((match = reg.exec(css))) { + var key = _trim(match[1].toLowerCase()), + val = _trim(_toHex(match[2])); + list[key] = val; + } + return list; +} +function _getAttrList(tag) { + var list = {}, + reg = /\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g, + match; + while ((match = reg.exec(tag))) { + var key = (match[1] || match[2] || match[4] || match[6]).toLowerCase(), + val = (match[2] ? match[3] : (match[4] ? match[5] : match[7])) || ''; + list[key] = val; + } + return list; +} +function _addClassToTag(tag, className) { + if (/\s+class\s*=/.test(tag)) { + tag = tag.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/, function($0, $1, $2, $3) { + if ((' ' + $2 + ' ').indexOf(' ' + className + ' ') < 0) { + return $2 === '' ? $1 + className + $3 : $1 + $2 + ' ' + className + $3; + } else { + return $0; + } + }); + } else { + tag = tag.substr(0, tag.length - 1) + ' class="' + className + '">'; + } + return tag; +} +function _formatCss(css) { + var str = ''; + _each(_getCssList(css), function(key, val) { + str += key + ':' + val + ';'; + }); + return str; +} +function _formatUrl(url, mode, host, pathname) { + mode = _undef(mode, '').toLowerCase(); + if (url.substr(0, 5) != 'data:') { + url = url.replace(/([^:])\/\//g, '$1/'); + } + if (_inArray(mode, ['absolute', 'relative', 'domain']) < 0) { + return url; + } + host = host || location.protocol + '//' + location.host; + if (pathname === undefined) { + var m = location.pathname.match(/^(\/.*)\//); + pathname = m ? m[1] : ''; + } + var match; + if ((match = /^(\w+:\/\/[^\/]*)/.exec(url))) { + if (match[1] !== host) { + return url; + } + } else if (/^\w+:/.test(url)) { + return url; + } + function getRealPath(path) { + var parts = path.split('/'), paths = []; + for (var i = 0, len = parts.length; i < len; i++) { + var part = parts[i]; + if (part == '..') { + if (paths.length > 0) { + paths.pop(); + } + } else if (part !== '' && part != '.') { + paths.push(part); + } + } + return '/' + paths.join('/'); + } + if (/^\//.test(url)) { + url = host + getRealPath(url.substr(1)); + } else if (!/^\w+:\/\//.test(url)) { + url = host + getRealPath(pathname + '/' + url); + } + function getRelativePath(path, depth) { + if (url.substr(0, path.length) === path) { + var arr = []; + for (var i = 0; i < depth; i++) { + arr.push('..'); + } + var prefix = '.'; + if (arr.length > 0) { + prefix += '/' + arr.join('/'); + } + if (pathname == '/') { + prefix += '/'; + } + return prefix + url.substr(path.length); + } else { + if ((match = /^(.*)\//.exec(path))) { + return getRelativePath(match[1], ++depth); + } + } + } + if (mode === 'relative') { + url = getRelativePath(host + pathname, 0).substr(2); + } else if (mode === 'absolute') { + if (url.substr(0, host.length) === host) { + url = url.substr(host.length); + } + } + return url; +} +function _formatHtml(html, htmlTags, urlType, wellFormatted, indentChar) { + if (html == null) { + html = ''; + } + urlType = urlType || ''; + wellFormatted = _undef(wellFormatted, false); + indentChar = _undef(indentChar, '\t'); + var fontSizeList = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(','); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/<(?:br|br\s[^>]*)>/ig, '\n') + $3; + }); + html = html.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/ig, '</p>'); + html = html.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/ig, '$1<br />$2'); + html = html.replace(/\u200B/g, ''); + html = html.replace(/\u00A9/g, '&copy;'); + html = html.replace(/\u00AE/g, '&reg;'); + html = html.replace(/\u2003/g, '&emsp;'); + html = html.replace(/\u3000/g, '&emsp;'); + html = html.replace(/<[^>]+/g, function($0) { + return $0.replace(/\s+/g, ' '); + }); + var htmlTagMap = {}; + if (htmlTags) { + _each(htmlTags, function(key, val) { + var arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + htmlTagMap[arr[i]] = _toMap(val); + } + }); + if (!htmlTagMap.script) { + html = html.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/ig, ''); + } + if (!htmlTagMap.style) { + html = html.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/ig, ''); + } + } + var re = /(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g; + var tagStack = []; + html = html.replace(re, function($0, $1, $2, $3, $4, $5, $6) { + var full = $0, + startNewline = $1 || '', + startSlash = $2 || '', + tagName = $3.toLowerCase(), + attr = $4 || '', + endSlash = $5 ? ' ' + $5 : '', + endNewline = $6 || ''; + if (htmlTags && !htmlTagMap[tagName]) { + return ''; + } + if (endSlash === '' && _SINGLE_TAG_MAP[tagName]) { + endSlash = ' /'; + } + if (_INLINE_TAG_MAP[tagName]) { + if (startNewline) { + startNewline = ' '; + } + if (endNewline) { + endNewline = ' '; + } + } + if (_PRE_TAG_MAP[tagName]) { + if (startSlash) { + endNewline = '\n'; + } else { + startNewline = '\n'; + } + } + if (wellFormatted && tagName == 'br') { + endNewline = '\n'; + } + if (_BLOCK_TAG_MAP[tagName] && !_PRE_TAG_MAP[tagName]) { + if (wellFormatted) { + if (startSlash && tagStack.length > 0 && tagStack[tagStack.length - 1] === tagName) { + tagStack.pop(); + } else { + tagStack.push(tagName); + } + startNewline = '\n'; + endNewline = '\n'; + for (var i = 0, len = startSlash ? tagStack.length : tagStack.length - 1; i < len; i++) { + startNewline += indentChar; + if (!startSlash) { + endNewline += indentChar; + } + } + if (endSlash) { + tagStack.pop(); + } else if (!startSlash) { + endNewline += indentChar; + } + } else { + startNewline = endNewline = ''; + } + } + if (attr !== '') { + var attrMap = _getAttrList(full); + if (tagName === 'font') { + var fontStyleMap = {}, fontStyle = ''; + _each(attrMap, function(key, val) { + if (key === 'color') { + fontStyleMap.color = val; + delete attrMap[key]; + } + if (key === 'size') { + fontStyleMap['font-size'] = fontSizeList[parseInt(val, 10) - 1] || ''; + delete attrMap[key]; + } + if (key === 'face') { + fontStyleMap['font-family'] = val; + delete attrMap[key]; + } + if (key === 'style') { + fontStyle = val; + } + }); + if (fontStyle && !/;$/.test(fontStyle)) { + fontStyle += ';'; + } + _each(fontStyleMap, function(key, val) { + if (val === '') { + return; + } + if (/\s/.test(val)) { + val = "'" + val + "'"; + } + fontStyle += key + ':' + val + ';'; + }); + attrMap.style = fontStyle; + } + _each(attrMap, function(key, val) { + if (_FILL_ATTR_MAP[key]) { + attrMap[key] = key; + } + if (_inArray(key, ['src', 'href']) >= 0) { + attrMap[key] = _formatUrl(val, urlType); + } + if (htmlTags && key !== 'style' && !htmlTagMap[tagName]['*'] && !htmlTagMap[tagName][key] || + tagName === 'body' && key === 'contenteditable' || + /^kindeditor_\d+$/.test(key)) { + delete attrMap[key]; + } + if (key === 'style' && val !== '') { + var styleMap = _getCssList(val); + _each(styleMap, function(k, v) { + if (htmlTags && !htmlTagMap[tagName].style && !htmlTagMap[tagName]['.' + k]) { + delete styleMap[k]; + } + }); + var style = ''; + _each(styleMap, function(k, v) { + style += k + ':' + v + ';'; + }); + attrMap.style = style; + } + }); + attr = ''; + _each(attrMap, function(key, val) { + if (key === 'style' && val === '') { + return; + } + val = val.replace(/"/g, '&quot;'); + attr += ' ' + key + '="' + val + '"'; + }); + } + if (tagName === 'font') { + tagName = 'span'; + } + return startNewline + '<' + startSlash + tagName + attr + endSlash + '>' + endNewline; + }); + html = html.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/ig, function($0, $1, $2, $3) { + return $1 + $2.replace(/\n/g, '<span id="__kindeditor_pre_newline__">\n') + $3; + }); + html = html.replace(/\n\s*\n/g, '\n'); + html = html.replace(/<span id="__kindeditor_pre_newline__">\n/g, '\n'); + return _trim(html); +} + +function _clearMsWord(html, htmlTags) { + html = html.replace(/<meta[\s\S]*?>/ig, '') + .replace(/<![\s\S]*?>/ig, '') + .replace(/<style[^>]*>[\s\S]*?<\/style>/ig, '') + .replace(/<script[^>]*>[\s\S]*?<\/script>/ig, '') + .replace(/<w:[^>]+>[\s\S]*?<\/w:[^>]+>/ig, '') + .replace(/<o:[^>]+>[\s\S]*?<\/o:[^>]+>/ig, '') + .replace(/<xml>[\s\S]*?<\/xml>/ig, '') + .replace(/<(?:table|td)[^>]*>/ig, function(full) { + return full.replace(/border-bottom:([#\w\s]+)/ig, 'border:$1'); + }); + return _formatHtml(html, htmlTags); +} + +function _mediaType(src) { + if (/\.(rm|rmvb)(\?|$)/i.test(src)) { + return 'audio/x-pn-realaudio-plugin'; + } + if (/\.(swf|flv)(\?|$)/i.test(src)) { + return 'application/x-shockwave-flash'; + } + //return 'video/x-ms-asf-plugin'; + return ''; +} + +function _mediaClass(type) { + if (/realaudio/i.test(type)) { + return 'ke-rm'; + } + if (/flash/i.test(type)) { + return 'ke-flash'; + } + return 'ke-media'; +} +function _mediaAttrs(srcTag) { + return _getAttrList(unescape(srcTag)); +} +function _mediaEmbed(attrs) { + var html = '<embed '; + _each(attrs, function(key, val) { + html += key + '="' + val + '" '; + }); + html += '/>'; + return html; +} +function _mediaImg(blankPath, attrs) { + var width = attrs.width, + height = attrs.height, + type = attrs.type || _mediaType(attrs.src), + srcTag = _mediaEmbed(attrs), + style = ''; + if (/\D/.test(width)) { + style += 'width:' + width + ';'; + } else if (width > 0) { + style += 'width:' + width + 'px;'; + } + if (/\D/.test(height)) { + style += 'height:' + height + ';'; + } else if (height > 0) { + style += 'height:' + height + 'px;'; + } + var html = '<img class="' + _mediaClass(type) + '" src="' + blankPath + '" '; + if (style !== '') { + html += 'style="' + style + '" '; + } + html += 'data-ke-tag="' + escape(srcTag) + '" alt="" />'; + return html; +} + + + + +function _tmpl(str, data) { + var fn = new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + "with(obj){p.push('" + + str.replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + "');}return p.join('');"); + return data ? fn(data) : fn; +} +K.formatUrl = _formatUrl; +K.formatHtml = _formatHtml; +K.getCssList = _getCssList; +K.getAttrList = _getAttrList; +K.mediaType = _mediaType; +K.mediaAttrs = _mediaAttrs; +K.mediaEmbed = _mediaEmbed; +K.mediaImg = _mediaImg; +K.clearMsWord = _clearMsWord; +K.tmpl = _tmpl; + + +function _contains(nodeA, nodeB) { + if (nodeA.nodeType == 9 && nodeB.nodeType != 9) { + return true; + } + while ((nodeB = nodeB.parentNode)) { + if (nodeB == nodeA) { + return true; + } + } + return false; +} +var _getSetAttrDiv = document.createElement('div'); +_getSetAttrDiv.setAttribute('className', 't'); +var _GET_SET_ATTRIBUTE = _getSetAttrDiv.className !== 't'; +function _getAttr(el, key) { + key = key.toLowerCase(); + var val = null; + if (!_GET_SET_ATTRIBUTE && el.nodeName.toLowerCase() != 'script') { + var div = el.ownerDocument.createElement('div'); + div.appendChild(el.cloneNode(false)); + var list = _getAttrList(_unescape(div.innerHTML)); + if (key in list) { + val = list[key]; + } + } else { + try { + val = el.getAttribute(key, 2); + } catch(e) { + val = el.getAttribute(key, 1); + } + } + if (key === 'style' && val !== null) { + val = _formatCss(val); + } + return val; +} +function _queryAll(expr, root) { + var exprList = expr.split(','); + if (exprList.length > 1) { + var mergedResults = []; + _each(exprList, function() { + _each(_queryAll(this, root), function() { + if (_inArray(this, mergedResults) < 0) { + mergedResults.push(this); + } + }); + }); + return mergedResults; + } + root = root || document; + function escape(str) { + if (typeof str != 'string') { + return str; + } + return str.replace(/([^\w\-])/g, '\\$1'); + } + function stripslashes(str) { + return str.replace(/\\/g, ''); + } + function cmpTag(tagA, tagB) { + return tagA === '*' || tagA.toLowerCase() === escape(tagB.toLowerCase()); + } + function byId(id, tag, root) { + var arr = [], + doc = root.ownerDocument || root, + el = doc.getElementById(stripslashes(id)); + if (el) { + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + arr.push(el); + } + } + return arr; + } + function byClass(className, tag, root) { + var doc = root.ownerDocument || root, arr = [], els, i, len, el; + if (root.getElementsByClassName) { + els = root.getElementsByClassName(stripslashes(className)); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName)) { + arr.push(el); + } + } + } else if (doc.querySelectorAll) { + els = doc.querySelectorAll((root.nodeName !== '#document' ? root.nodeName + ' ' : '') + tag + '.' + className); + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (_contains(root, el)) { + arr.push(el); + } + } + } else { + els = root.getElementsByTagName(tag); + className = ' ' + className + ' '; + for (i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + var cls = el.className; + if (cls && (' ' + cls + ' ').indexOf(className) > -1) { + arr.push(el); + } + } + } + } + return arr; + } + function byName(name, tag, root) { + var arr = [], doc = root.ownerDocument || root, + els = doc.getElementsByName(stripslashes(name)), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (cmpTag(tag, el.nodeName) && _contains(root, el)) { + if (el.getAttribute('name') !== null) { + arr.push(el); + } + } + } + return arr; + } + function byAttr(key, val, tag, root) { + var arr = [], els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + if (val === null) { + if (_getAttr(el, key) !== null) { + arr.push(el); + } + } else { + if (val === escape(_getAttr(el, key))) { + arr.push(el); + } + } + } + } + return arr; + } + function select(expr, root) { + var arr = [], matches; + matches = /^((?:\\.|[^.#\s\[<>])+)/.exec(expr); + var tag = matches ? matches[1] : '*'; + if ((matches = /#((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byId(matches[1], tag, root); + } else if ((matches = /\.((?:[\w\-]|\\.)+)$/.exec(expr))) { + arr = byClass(matches[1], tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\]/.exec(expr))) { + arr = byAttr(matches[1].toLowerCase(), null, tag, root); + } else if ((matches = /\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(expr))) { + var key = matches[1].toLowerCase(), val = matches[2]; + if (key === 'id') { + arr = byId(val, tag, root); + } else if (key === 'class') { + arr = byClass(val, tag, root); + } else if (key === 'name') { + arr = byName(val, tag, root); + } else { + arr = byAttr(key, val, tag, root); + } + } else { + var els = root.getElementsByTagName(tag), el; + for (var i = 0, len = els.length; i < len; i++) { + el = els[i]; + if (el.nodeType == 1) { + arr.push(el); + } + } + } + return arr; + } + var parts = [], arr, re = /((?:\\.|[^\s>])+|[\s>])/g; + while ((arr = re.exec(expr))) { + if (arr[1] !== ' ') { + parts.push(arr[1]); + } + } + var results = []; + if (parts.length == 1) { + return select(parts[0], root); + } + var isChild = false, part, els, subResults, val, v, i, j, k, length, len, l; + for (i = 0, lenth = parts.length; i < lenth; i++) { + part = parts[i]; + if (part === '>') { + isChild = true; + continue; + } + if (i > 0) { + els = []; + for (j = 0, len = results.length; j < len; j++) { + val = results[j]; + subResults = select(part, val); + for (k = 0, l = subResults.length; k < l; k++) { + v = subResults[k]; + if (isChild) { + if (val === v.parentNode) { + els.push(v); + } + } else { + els.push(v); + } + } + } + results = els; + } else { + results = select(part, root); + } + if (results.length === 0) { + return []; + } + } + return results; +} +function _query(expr, root) { + var arr = _queryAll(expr, root); + return arr.length > 0 ? arr[0] : null; +} +K.query = _query; +K.queryAll = _queryAll; + + +function _get(val) { + return K(val)[0]; +} +function _getDoc(node) { + if (!node) { + return document; + } + return node.ownerDocument || node.document || node; +} +function _getWin(node) { + if (!node) { + return window; + } + var doc = _getDoc(node); + return doc.parentWindow || doc.defaultView; +} +function _setHtml(el, html) { + if (el.nodeType != 1) { + return; + } + var doc = _getDoc(el); + try { + el.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + html; + var temp = doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + } catch(e) { + K(el).empty(); + K('@' + html, doc).each(function() { + el.appendChild(this); + }); + } +} +function _hasClass(el, cls) { + return _inString(cls, el.className, ' '); +} +function _setAttr(el, key, val) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + el.setAttribute(key, '' + val); +} +function _removeAttr(el, key) { + if (_IE && _V < 8 && key.toLowerCase() == 'class') { + key = 'className'; + } + _setAttr(el, key, ''); + el.removeAttribute(key); +} +function _getNodeName(node) { + if (!node || !node.nodeName) { + return ''; + } + return node.nodeName.toLowerCase(); +} +function _computedCss(el, key) { + var self = this, win = _getWin(el), camelKey = _toCamel(key), val = ''; + if (win.getComputedStyle) { + var style = win.getComputedStyle(el, null); + val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey]; + } else if (el.currentStyle) { + val = el.currentStyle[camelKey] || el.style[camelKey]; + } + return val; +} +function _hasVal(node) { + return !!_VALUE_TAG_MAP[_getNodeName(node)]; +} +function _docElement(doc) { + doc = doc || document; + return _QUIRKS ? doc.body : doc.documentElement; +} +function _docHeight(doc) { + var el = _docElement(doc); + return Math.max(el.scrollHeight, el.clientHeight); +} +function _docWidth(doc) { + var el = _docElement(doc); + return Math.max(el.scrollWidth, el.clientWidth); +} +function _getScrollPos(doc) { + doc = doc || document; + var x, y; + if (_IE || _NEWIE || _OPERA) { + x = _docElement(doc).scrollLeft; + y = _docElement(doc).scrollTop; + } else { + x = _getWin(doc).scrollX; + y = _getWin(doc).scrollY; + } + return {x : x, y : y}; +} + + +function KNode(node) { + this.init(node); +} +_extend(KNode, { + init : function(node) { + var self = this; + node = _isArray(node) ? node : [node]; + var length = 0; + for (var i = 0, len = node.length; i < len; i++) { + if (node[i]) { + self[i] = node[i].constructor === KNode ? node[i][0] : node[i]; + length++; + } + } + self.length = length; + self.doc = _getDoc(self[0]); + self.name = _getNodeName(self[0]); + self.type = self.length > 0 ? self[0].nodeType : null; + self.win = _getWin(self[0]); + }, + each : function(fn) { + var self = this; + for (var i = 0; i < self.length; i++) { + if (fn.call(self[i], i, self[i]) === false) { + return self; + } + } + return self; + }, + bind : function(type, fn) { + this.each(function() { + _bind(this, type, fn); + }); + return this; + }, + unbind : function(type, fn) { + this.each(function() { + _unbind(this, type, fn); + }); + return this; + }, + fire : function(type) { + if (this.length < 1) { + return this; + } + _fire(this[0], type); + return this; + }, + hasAttr : function(key) { + if (this.length < 1) { + return false; + } + return !!_getAttr(this[0], key); + }, + attr : function(key, val) { + var self = this; + if (key === undefined) { + return _getAttrList(self.outer()); + } + if (typeof key === 'object') { + _each(key, function(k, v) { + self.attr(k, v); + }); + return self; + } + if (val === undefined) { + val = self.length < 1 ? null : _getAttr(self[0], key); + return val === null ? '' : val; + } + self.each(function() { + _setAttr(this, key, val); + }); + return self; + }, + removeAttr : function(key) { + this.each(function() { + _removeAttr(this, key); + }); + return this; + }, + get : function(i) { + if (this.length < 1) { + return null; + } + return this[i || 0]; + }, + eq : function(i) { + if (this.length < 1) { + return null; + } + return this[i] ? new KNode(this[i]) : null; + }, + hasClass : function(cls) { + if (this.length < 1) { + return false; + } + return _hasClass(this[0], cls); + }, + addClass : function(cls) { + this.each(function() { + if (!_hasClass(this, cls)) { + this.className = _trim(this.className + ' ' + cls); + } + }); + return this; + }, + removeClass : function(cls) { + this.each(function() { + if (_hasClass(this, cls)) { + this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' ')); + } + }); + return this; + }, + html : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1 || self.type != 1) { + return ''; + } + return _formatHtml(self[0].innerHTML); + } + self.each(function() { + _setHtml(this, val); + }); + return self; + }, + text : function() { + var self = this; + if (self.length < 1) { + return ''; + } + return _IE ? self[0].innerText : self[0].textContent; + }, + hasVal : function() { + if (this.length < 1) { + return false; + } + return _hasVal(this[0]); + }, + val : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self.hasVal() ? self[0].value : self.attr('value'); + } else { + self.each(function() { + if (_hasVal(this)) { + this.value = val; + } else { + _setAttr(this, 'value' , val); + } + }); + return self; + } + }, + css : function(key, val) { + var self = this; + if (key === undefined) { + return _getCssList(self.attr('style')); + } + if (typeof key === 'object') { + _each(key, function(k, v) { + self.css(k, v); + }); + return self; + } + if (val === undefined) { + if (self.length < 1) { + return ''; + } + return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || ''; + } + self.each(function() { + this.style[_toCamel(key)] = val; + }); + return self; + }, + width : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetWidth; + } + return self.css('width', _addUnit(val)); + }, + height : function(val) { + var self = this; + if (val === undefined) { + if (self.length < 1) { + return 0; + } + return self[0].offsetHeight; + } + return self.css('height', _addUnit(val)); + }, + opacity : function(val) { + this.each(function() { + if (this.style.opacity === undefined) { + this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')'; + } else { + this.style.opacity = val == 1 ? '' : val; + } + }); + return this; + }, + data : function(key, val) { + var self = this; + key = 'kindeditor_data_' + key; + if (val === undefined) { + if (self.length < 1) { + return null; + } + return self[0][key]; + } + this.each(function() { + this[key] = val; + }); + return self; + }, + pos : function() { + var self = this, node = self[0], x = 0, y = 0; + if (node) { + if (node.getBoundingClientRect) { + var box = node.getBoundingClientRect(), + pos = _getScrollPos(self.doc); + x = box.left + pos.x; + y = box.top + pos.y; + } else { + while (node) { + x += node.offsetLeft; + y += node.offsetTop; + node = node.offsetParent; + } + } + } + return {x : _round(x), y : _round(y)}; + }, + clone : function(bool) { + if (this.length < 1) { + return new KNode([]); + } + return new KNode(this[0].cloneNode(bool)); + }, + append : function(expr) { + this.each(function() { + if (this.appendChild) { + this.appendChild(_get(expr)); + } + }); + return this; + }, + appendTo : function(expr) { + this.each(function() { + _get(expr).appendChild(this); + }); + return this; + }, + before : function(expr) { + this.each(function() { + this.parentNode.insertBefore(_get(expr), this); + }); + return this; + }, + after : function(expr) { + this.each(function() { + if (this.nextSibling) { + this.parentNode.insertBefore(_get(expr), this.nextSibling); + } else { + this.parentNode.appendChild(_get(expr)); + } + }); + return this; + }, + replaceWith : function(expr) { + var nodes = []; + this.each(function(i, node) { + _unbind(node); + var newNode = _get(expr); + node.parentNode.replaceChild(newNode, node); + nodes.push(newNode); + }); + return K(nodes); + }, + empty : function() { + var self = this; + self.each(function(i, node) { + var child = node.firstChild; + while (child) { + if (!node.parentNode) { + return; + } + var next = child.nextSibling; + child.parentNode.removeChild(child); + child = next; + } + }); + return self; + }, + remove : function(keepChilds) { + var self = this; + self.each(function(i, node) { + if (!node.parentNode) { + return; + } + _unbind(node); + if (keepChilds) { + var child = node.firstChild; + while (child) { + var next = child.nextSibling; + node.parentNode.insertBefore(child, node); + child = next; + } + } + node.parentNode.removeChild(node); + delete self[i]; + }); + self.length = 0; + return self; + }, + show : function(val) { + var self = this; + if (val === undefined) { + val = self._originDisplay || ''; + } + if (self.css('display') != 'none') { + return self; + } + return self.css('display', val); + }, + hide : function() { + var self = this; + if (self.length < 1) { + return self; + } + self._originDisplay = self[0].style.display; + return self.css('display', 'none'); + }, + outer : function() { + var self = this; + if (self.length < 1) { + return ''; + } + var div = self.doc.createElement('div'), html; + div.appendChild(self[0].cloneNode(true)); + html = _formatHtml(div.innerHTML); + div = null; + return html; + }, + isSingle : function() { + return !!_SINGLE_TAG_MAP[this.name]; + }, + isInline : function() { + return !!_INLINE_TAG_MAP[this.name]; + }, + isBlock : function() { + return !!_BLOCK_TAG_MAP[this.name]; + }, + isStyle : function() { + return !!_STYLE_TAG_MAP[this.name]; + }, + isControl : function() { + return !!_CONTROL_TAG_MAP[this.name]; + }, + contains : function(otherNode) { + if (this.length < 1) { + return false; + } + return _contains(this[0], _get(otherNode)); + }, + parent : function() { + if (this.length < 1) { + return null; + } + var node = this[0].parentNode; + return node ? new KNode(node) : null; + }, + children : function() { + if (this.length < 1) { + return new KNode([]); + } + var list = [], child = this[0].firstChild; + while (child) { + if (child.nodeType != 3 || _trim(child.nodeValue) !== '') { + list.push(child); + } + child = child.nextSibling; + } + return new KNode(list); + }, + first : function() { + var list = this.children(); + return list.length > 0 ? list.eq(0) : null; + }, + last : function() { + var list = this.children(); + return list.length > 0 ? list.eq(list.length - 1) : null; + }, + index : function() { + if (this.length < 1) { + return -1; + } + var i = -1, sibling = this[0]; + while (sibling) { + i++; + sibling = sibling.previousSibling; + } + return i; + }, + prev : function() { + if (this.length < 1) { + return null; + } + var node = this[0].previousSibling; + return node ? new KNode(node) : null; + }, + next : function() { + if (this.length < 1) { + return null; + } + var node = this[0].nextSibling; + return node ? new KNode(node) : null; + }, + scan : function(fn, order) { + if (this.length < 1) { + return; + } + order = (order === undefined) ? true : order; + function walk(node) { + var n = order ? node.firstChild : node.lastChild; + while (n) { + var next = order ? n.nextSibling : n.previousSibling; + if (fn(n) === false) { + return false; + } + if (walk(n) === false) { + return false; + } + n = next; + } + } + walk(this[0]); + return this; + } +}); +_each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' + + 'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' + + 'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function(i, type) { + KNode.prototype[type] = function(fn) { + return fn ? this.bind(type, fn) : this.fire(type); + }; +}); +var _K = K; +K = function(expr, root) { + if (expr === undefined || expr === null) { + return; + } + function newNode(node) { + if (!node[0]) { + node = []; + } + return new KNode(node); + } + if (typeof expr === 'string') { + if (root) { + root = _get(root); + } + var length = expr.length; + if (expr.charAt(0) === '@') { + expr = expr.substr(1); + } + if (expr.length !== length || /<.+>/.test(expr)) { + var doc = root ? root.ownerDocument || root : document, + div = doc.createElement('div'), list = []; + div.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + expr; + for (var i = 0, len = div.childNodes.length; i < len; i++) { + var child = div.childNodes[i]; + if (child.id == '__kindeditor_temp_tag__') { + continue; + } + list.push(child); + } + return newNode(list); + } + return newNode(_queryAll(expr, root)); + } + if (expr && expr.constructor === KNode) { + return expr; + } + if (expr.toArray) { + expr = expr.toArray(); + } + if (_isArray(expr)) { + return newNode(expr); + } + return newNode(_toArray(arguments)); +}; +_each(_K, function(key, val) { + K[key] = val; +}); +K.NodeClass = KNode; +window.KindEditor = K; + + +var _START_TO_START = 0, + _START_TO_END = 1, + _END_TO_END = 2, + _END_TO_START = 3, + _BOOKMARK_ID = 0; +function _updateCollapsed(range) { + range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset); + return range; +} +function _copyAndDelete(range, isCopy, isDelete) { + var doc = range.doc, nodeList = []; + function splitTextNode(node, startOffset, endOffset) { + var length = node.nodeValue.length, centerNode; + if (isCopy) { + var cloneNode = node.cloneNode(true); + if (startOffset > 0) { + centerNode = cloneNode.splitText(startOffset); + } else { + centerNode = cloneNode; + } + if (endOffset < length) { + centerNode.splitText(endOffset - startOffset); + } + } + if (isDelete) { + var center = node; + if (startOffset > 0) { + center = node.splitText(startOffset); + range.setStart(node, startOffset); + } + if (endOffset < length) { + var right = center.splitText(endOffset - startOffset); + range.setEnd(right, 0); + } + nodeList.push(center); + } + return centerNode; + } + function removeNodes() { + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + } + var copyRange = range.cloneRange().down(); + var start = -1, incStart = -1, incEnd = -1, end = -1, + ancestor = range.commonAncestor(), frag = doc.createDocumentFragment(); + if (ancestor.nodeType == 3) { + var textNode = splitTextNode(ancestor, range.startOffset, range.endOffset); + if (isCopy) { + frag.appendChild(textNode); + } + removeNodes(); + return isCopy ? frag : range; + } + function extractNodes(parent, frag) { + var node = parent.firstChild, nextNode; + while (node) { + var testRange = new KRange(doc).selectNode(node); + start = testRange.compareBoundaryPoints(_START_TO_END, range); + if (start >= 0 && incStart <= 0) { + incStart = testRange.compareBoundaryPoints(_START_TO_START, range); + } + if (incStart >= 0 && incEnd <= 0) { + incEnd = testRange.compareBoundaryPoints(_END_TO_END, range); + } + if (incEnd >= 0 && end <= 0) { + end = testRange.compareBoundaryPoints(_END_TO_START, range); + } + if (end >= 0) { + return false; + } + nextNode = node.nextSibling; + if (start > 0) { + if (node.nodeType == 1) { + if (incStart >= 0 && incEnd <= 0) { + if (isCopy) { + frag.appendChild(node.cloneNode(true)); + } + if (isDelete) { + nodeList.push(node); + } + } else { + var childFlag; + if (isCopy) { + childFlag = node.cloneNode(false); + frag.appendChild(childFlag); + } + if (extractNodes(node, childFlag) === false) { + return false; + } + } + } else if (node.nodeType == 3) { + var textNode; + if (node == copyRange.startContainer) { + textNode = splitTextNode(node, copyRange.startOffset, node.nodeValue.length); + } else if (node == copyRange.endContainer) { + textNode = splitTextNode(node, 0, copyRange.endOffset); + } else { + textNode = splitTextNode(node, 0, node.nodeValue.length); + } + if (isCopy) { + try { + frag.appendChild(textNode); + } catch(e) {} + } + } + } + node = nextNode; + } + } + extractNodes(ancestor, frag); + if (isDelete) { + range.up().collapse(true); + } + for (var i = 0, len = nodeList.length; i < len; i++) { + var node = nodeList[i]; + if (node.parentNode) { + node.parentNode.removeChild(node); + } + } + return isCopy ? frag : range; +} + +function _moveToElementText(range, el) { + var node = el; + while (node) { + var knode = K(node); + if (knode.name == 'marquee' || knode.name == 'select') { + return; + } + node = node.parentNode; + } + try { + range.moveToElementText(el); + } catch(e) {} +} + +function _getStartEnd(rng, isStart) { + var doc = rng.parentElement().ownerDocument, + pointRange = rng.duplicate(); + pointRange.collapse(isStart); + var parent = pointRange.parentElement(), + nodes = parent.childNodes; + if (nodes.length === 0) { + return {node: parent.parentNode, offset: K(parent).index()}; + } + var startNode = doc, startPos = 0, cmp = -1; + var testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + for (var i = 0, len = nodes.length; i < len; i++) { + var node = nodes[i]; + cmp = testRange.compareEndPoints('StartToStart', pointRange); + if (cmp === 0) { + return {node: node.parentNode, offset: i}; + } + if (node.nodeType == 1) { + var nodeRange = rng.duplicate(), dummy, knode = K(node), newNode = node; + if (knode.isControl()) { + dummy = doc.createElement('span'); + knode.after(dummy); + newNode = dummy; + startPos += knode.text().replace(/\r\n|\n|\r/g, '').length; + } + _moveToElementText(nodeRange, newNode); + testRange.setEndPoint('StartToEnd', nodeRange); + if (cmp > 0) { + startPos += nodeRange.text.replace(/\r\n|\n|\r/g, '').length; + } else { + startPos = 0; + } + if (dummy) { + K(dummy).remove(); + } + } else if (node.nodeType == 3) { + testRange.moveStart('character', node.nodeValue.length); + startPos += node.nodeValue.length; + } + if (cmp < 0) { + startNode = node; + } + } + if (cmp < 0 && startNode.nodeType == 1) { + return {node: parent, offset: K(parent.lastChild).index() + 1}; + } + if (cmp > 0) { + while (startNode.nextSibling && startNode.nodeType == 1) { + startNode = startNode.nextSibling; + } + } + testRange = rng.duplicate(); + _moveToElementText(testRange, parent); + testRange.setEndPoint('StartToEnd', pointRange); + startPos -= testRange.text.replace(/\r\n|\n|\r/g, '').length; + if (cmp > 0 && startNode.nodeType == 3) { + var prevNode = startNode.previousSibling; + while (prevNode && prevNode.nodeType == 3) { + startPos -= prevNode.nodeValue.length; + prevNode = prevNode.previousSibling; + } + } + return {node: startNode, offset: startPos}; +} + +function _getEndRange(node, offset) { + var doc = node.ownerDocument || node, + range = doc.body.createTextRange(); + if (doc == node) { + range.collapse(true); + return range; + } + if (node.nodeType == 1 && node.childNodes.length > 0) { + var children = node.childNodes, isStart, child; + if (offset === 0) { + child = children[0]; + isStart = true; + } else { + child = children[offset - 1]; + isStart = false; + } + if (!child) { + return range; + } + if (K(child).name === 'head') { + if (offset === 1) { + isStart = true; + } + if (offset === 2) { + isStart = false; + } + range.collapse(isStart); + return range; + } + if (child.nodeType == 1) { + var kchild = K(child), span; + if (kchild.isControl()) { + span = doc.createElement('span'); + if (isStart) { + kchild.before(span); + } else { + kchild.after(span); + } + child = span; + } + _moveToElementText(range, child); + range.collapse(isStart); + if (span) { + K(span).remove(); + } + return range; + } + node = child; + offset = isStart ? 0 : child.nodeValue.length; + } + var dummy = doc.createElement('span'); + K(node).before(dummy); + _moveToElementText(range, dummy); + range.moveStart('character', offset); + K(dummy).remove(); + return range; +} + +function _toRange(rng) { + var doc, range; + function tr2td(start) { + if (K(start.node).name == 'tr') { + start.node = start.node.cells[start.offset]; + start.offset = 0; + } + } + if (_IERANGE) { + if (rng.item) { + doc = _getDoc(rng.item(0)); + range = new KRange(doc); + range.selectNode(rng.item(0)); + return range; + } + doc = rng.parentElement().ownerDocument; + var start = _getStartEnd(rng, true), + end = _getStartEnd(rng, false); + tr2td(start); + tr2td(end); + range = new KRange(doc); + range.setStart(start.node, start.offset); + range.setEnd(end.node, end.offset); + return range; + } + var startContainer = rng.startContainer; + doc = startContainer.ownerDocument || startContainer; + range = new KRange(doc); + range.setStart(startContainer, rng.startOffset); + range.setEnd(rng.endContainer, rng.endOffset); + return range; +} + + +function KRange(doc) { + this.init(doc); +} +_extend(KRange, { + init : function(doc) { + var self = this; + self.startContainer = doc; + self.startOffset = 0; + self.endContainer = doc; + self.endOffset = 0; + self.collapsed = true; + self.doc = doc; + }, + commonAncestor : function() { + function getParents(node) { + var parents = []; + while (node) { + parents.push(node); + node = node.parentNode; + } + return parents; + } + var parentsA = getParents(this.startContainer), + parentsB = getParents(this.endContainer), + i = 0, lenA = parentsA.length, lenB = parentsB.length, parentA, parentB; + while (++i) { + parentA = parentsA[lenA - i]; + parentB = parentsB[lenB - i]; + if (!parentA || !parentB || parentA !== parentB) { + break; + } + } + return parentsA[lenA - i + 1]; + }, + setStart : function(node, offset) { + var self = this, doc = self.doc; + self.startContainer = node; + self.startOffset = offset; + if (self.endContainer === doc) { + self.endContainer = node; + self.endOffset = offset; + } + return _updateCollapsed(this); + }, + setEnd : function(node, offset) { + var self = this, doc = self.doc; + self.endContainer = node; + self.endOffset = offset; + if (self.startContainer === doc) { + self.startContainer = node; + self.startOffset = offset; + } + return _updateCollapsed(this); + }, + setStartBefore : function(node) { + return this.setStart(node.parentNode || this.doc, K(node).index()); + }, + setStartAfter : function(node) { + return this.setStart(node.parentNode || this.doc, K(node).index() + 1); + }, + setEndBefore : function(node) { + return this.setEnd(node.parentNode || this.doc, K(node).index()); + }, + setEndAfter : function(node) { + return this.setEnd(node.parentNode || this.doc, K(node).index() + 1); + }, + selectNode : function(node) { + return this.setStartBefore(node).setEndAfter(node); + }, + selectNodeContents : function(node) { + var knode = K(node); + if (knode.type == 3 || knode.isSingle()) { + return this.selectNode(node); + } + var children = knode.children(); + if (children.length > 0) { + return this.setStartBefore(children[0]).setEndAfter(children[children.length - 1]); + } + return this.setStart(node, 0).setEnd(node, 0); + }, + collapse : function(toStart) { + if (toStart) { + return this.setEnd(this.startContainer, this.startOffset); + } + return this.setStart(this.endContainer, this.endOffset); + }, + compareBoundaryPoints : function(how, range) { + var rangeA = this.get(), rangeB = range.get(); + if (_IERANGE) { + var arr = {}; + arr[_START_TO_START] = 'StartToStart'; + arr[_START_TO_END] = 'EndToStart'; + arr[_END_TO_END] = 'EndToEnd'; + arr[_END_TO_START] = 'StartToEnd'; + var cmp = rangeA.compareEndPoints(arr[how], rangeB); + if (cmp !== 0) { + return cmp; + } + var nodeA, nodeB, nodeC, posA, posB; + if (how === _START_TO_START || how === _END_TO_START) { + nodeA = this.startContainer; + posA = this.startOffset; + } + if (how === _START_TO_END || how === _END_TO_END) { + nodeA = this.endContainer; + posA = this.endOffset; + } + if (how === _START_TO_START || how === _START_TO_END) { + nodeB = range.startContainer; + posB = range.startOffset; + } + if (how === _END_TO_END || how === _END_TO_START) { + nodeB = range.endContainer; + posB = range.endOffset; + } + if (nodeA === nodeB) { + var diff = posA - posB; + return diff > 0 ? 1 : (diff < 0 ? -1 : 0); + } + nodeC = nodeB; + while (nodeC && nodeC.parentNode !== nodeA) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posA ? -1 : 1; + } + nodeC = nodeA; + while (nodeC && nodeC.parentNode !== nodeB) { + nodeC = nodeC.parentNode; + } + if (nodeC) { + return K(nodeC).index() >= posB ? 1 : -1; + } + nodeC = K(nodeB).next(); + if (nodeC && nodeC.contains(nodeA)) { + return 1; + } + nodeC = K(nodeA).next(); + if (nodeC && nodeC.contains(nodeB)) { + return -1; + } + } else { + return rangeA.compareBoundaryPoints(how, rangeB); + } + }, + cloneRange : function() { + return new KRange(this.doc).setStart(this.startContainer, this.startOffset).setEnd(this.endContainer, this.endOffset); + }, + toString : function() { + var rng = this.get(), str = _IERANGE ? rng.text : rng.toString(); + return str.replace(/\r\n|\n|\r/g, ''); + }, + cloneContents : function() { + return _copyAndDelete(this, true, false); + }, + deleteContents : function() { + return _copyAndDelete(this, false, true); + }, + extractContents : function() { + return _copyAndDelete(this, true, true); + }, + insertNode : function(node) { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, + firstChild, lastChild, c, nodeCount = 1; + if (node.nodeName.toLowerCase() === '#document-fragment') { + firstChild = node.firstChild; + lastChild = node.lastChild; + nodeCount = node.childNodes.length; + } + if (sc.nodeType == 1) { + c = sc.childNodes[so]; + if (c) { + sc.insertBefore(node, c); + if (sc === ec) { + eo += nodeCount; + } + } else { + sc.appendChild(node); + } + } else if (sc.nodeType == 3) { + if (so === 0) { + sc.parentNode.insertBefore(node, sc); + if (sc.parentNode === ec) { + eo += nodeCount; + } + } else if (so >= sc.nodeValue.length) { + if (sc.nextSibling) { + sc.parentNode.insertBefore(node, sc.nextSibling); + } else { + sc.parentNode.appendChild(node); + } + } else { + if (so > 0) { + c = sc.splitText(so); + } else { + c = sc; + } + sc.parentNode.insertBefore(node, c); + if (sc === ec) { + ec = c; + eo -= so; + } + } + } + if (firstChild) { + self.setStartBefore(firstChild).setEndAfter(lastChild); + } else { + self.selectNode(node); + } + if (self.compareBoundaryPoints(_END_TO_END, self.cloneRange().setEnd(ec, eo)) >= 1) { + return self; + } + return self.setEnd(ec, eo); + }, + surroundContents : function(node) { + node.appendChild(this.extractContents()); + return this.insertNode(node).selectNode(node); + }, + isControl : function() { + var self = this, + sc = self.startContainer, so = self.startOffset, + ec = self.endContainer, eo = self.endOffset, rng; + return sc.nodeType == 1 && sc === ec && so + 1 === eo && K(sc.childNodes[so]).isControl(); + }, + get : function(hasControlRange) { + var self = this, doc = self.doc, node, rng; + if (!_IERANGE) { + rng = doc.createRange(); + try { + rng.setStart(self.startContainer, self.startOffset); + rng.setEnd(self.endContainer, self.endOffset); + } catch (e) {} + return rng; + } + if (hasControlRange && self.isControl()) { + rng = doc.body.createControlRange(); + rng.addElement(self.startContainer.childNodes[self.startOffset]); + return rng; + } + var range = self.cloneRange().down(); + rng = doc.body.createTextRange(); + rng.setEndPoint('StartToStart', _getEndRange(range.startContainer, range.startOffset)); + rng.setEndPoint('EndToStart', _getEndRange(range.endContainer, range.endOffset)); + return rng; + }, + html : function() { + return K(this.cloneContents()).outer(); + }, + down : function() { + var self = this; + function downPos(node, pos, isStart) { + if (node.nodeType != 1) { + return; + } + var children = K(node).children(); + if (children.length === 0) { + return; + } + var left, right, child, offset; + if (pos > 0) { + left = children.eq(pos - 1); + } + if (pos < children.length) { + right = children.eq(pos); + } + if (left && left.type == 3) { + child = left[0]; + offset = child.nodeValue.length; + } + if (right && right.type == 3) { + child = right[0]; + offset = 0; + } + if (!child) { + return; + } + if (isStart) { + self.setStart(child, offset); + } else { + self.setEnd(child, offset); + } + } + downPos(self.startContainer, self.startOffset, true); + downPos(self.endContainer, self.endOffset, false); + return self; + }, + up : function() { + var self = this; + function upPos(node, pos, isStart) { + if (node.nodeType != 3) { + return; + } + if (pos === 0) { + if (isStart) { + self.setStartBefore(node); + } else { + self.setEndBefore(node); + } + } else if (pos == node.nodeValue.length) { + if (isStart) { + self.setStartAfter(node); + } else { + self.setEndAfter(node); + } + } + } + upPos(self.startContainer, self.startOffset, true); + upPos(self.endContainer, self.endOffset, false); + return self; + }, + enlarge : function(toBlock) { + var self = this; + self.up(); + function enlargePos(node, pos, isStart) { + var knode = K(node), parent; + if (knode.type == 3 || _NOSPLIT_TAG_MAP[knode.name] || !toBlock && knode.isBlock()) { + return; + } + if (pos === 0) { + while (!knode.prev()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartBefore(knode[0]); + } else { + self.setEndBefore(knode[0]); + } + } else if (pos == knode.children().length) { + while (!knode.next()) { + parent = knode.parent(); + if (!parent || _NOSPLIT_TAG_MAP[parent.name] || !toBlock && parent.isBlock()) { + break; + } + knode = parent; + } + if (isStart) { + self.setStartAfter(knode[0]); + } else { + self.setEndAfter(knode[0]); + } + } + } + enlargePos(self.startContainer, self.startOffset, true); + enlargePos(self.endContainer, self.endOffset, false); + return self; + }, + shrink : function() { + var self = this, child, collapsed = self.collapsed; + while (self.startContainer.nodeType == 1 && (child = self.startContainer.childNodes[self.startOffset]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setStart(child, 0); + } + if (collapsed) { + return self.collapse(collapsed); + } + while (self.endContainer.nodeType == 1 && self.endOffset > 0 && (child = self.endContainer.childNodes[self.endOffset - 1]) && child.nodeType == 1 && !K(child).isSingle()) { + self.setEnd(child, child.childNodes.length); + } + return self; + }, + createBookmark : function(serialize) { + var self = this, doc = self.doc, endNode, + startNode = K('<span style="display:none;"></span>', doc)[0]; + startNode.id = '__kindeditor_bookmark_start_' + (_BOOKMARK_ID++) + '__'; + if (!self.collapsed) { + endNode = startNode.cloneNode(true); + endNode.id = '__kindeditor_bookmark_end_' + (_BOOKMARK_ID++) + '__'; + } + if (endNode) { + self.cloneRange().collapse(false).insertNode(endNode).setEndBefore(endNode); + } + self.insertNode(startNode).setStartAfter(startNode); + return { + start : serialize ? '#' + startNode.id : startNode, + end : endNode ? (serialize ? '#' + endNode.id : endNode) : null + }; + }, + moveToBookmark : function(bookmark) { + var self = this, doc = self.doc, + start = K(bookmark.start, doc), end = bookmark.end ? K(bookmark.end, doc) : null; + if (!start || start.length < 1) { + return self; + } + self.setStartBefore(start[0]); + start.remove(); + if (end && end.length > 0) { + self.setEndBefore(end[0]); + end.remove(); + } else { + self.collapse(true); + } + return self; + }, + dump : function() { + console.log('--------------------'); + console.log(this.startContainer.nodeType == 3 ? this.startContainer.nodeValue : this.startContainer, this.startOffset); + console.log(this.endContainer.nodeType == 3 ? this.endContainer.nodeValue : this.endContainer, this.endOffset); + } +}); +function _range(mixed) { + if (!mixed.nodeName) { + return mixed.constructor === KRange ? mixed : _toRange(mixed); + } + return new KRange(mixed); +} +K.RangeClass = KRange; +K.range = _range; +K.START_TO_START = _START_TO_START; +K.START_TO_END = _START_TO_END; +K.END_TO_END = _END_TO_END; +K.END_TO_START = _END_TO_START; + + +function _nativeCommand(doc, key, val) { + try { + doc.execCommand(key, false, val); + } catch(e) {} +} + +function _nativeCommandValue(doc, key) { + var val = ''; + try { + val = doc.queryCommandValue(key); + } catch (e) {} + if (typeof val !== 'string') { + val = ''; + } + return val; +} + +function _getSel(doc) { + var win = _getWin(doc); + return _IERANGE ? doc.selection : win.getSelection(); +} + +function _getRng(doc) { + var sel = _getSel(doc), rng; + try { + if (sel.rangeCount > 0) { + rng = sel.getRangeAt(0); + } else { + rng = sel.createRange(); + } + } catch(e) {} + if (_IERANGE && (!rng || (!rng.item && rng.parentElement().ownerDocument !== doc))) { + return null; + } + return rng; +} + +function _singleKeyMap(map) { + var newMap = {}, arr, v; + _each(map, function(key, val) { + arr = key.split(','); + for (var i = 0, len = arr.length; i < len; i++) { + v = arr[i]; + newMap[v] = val; + } + }); + return newMap; +} + +function _hasAttrOrCss(knode, map) { + return _hasAttrOrCssByKey(knode, map, '*') || _hasAttrOrCssByKey(knode, map); +} +function _hasAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return false; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return false; + } + var arr = newMap[mapKey].split(','); + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + return true; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + var method = match[1] ? 'css' : 'attr'; + key = match[2]; + var val = match[3] || ''; + if (val === '' && knode[method](key) !== '') { + return true; + } + if (val !== '' && knode[method](key) === val) { + return true; + } + } + return false; +} + +function _removeAttrOrCss(knode, map) { + if (knode.type != 1) { + return; + } + _removeAttrOrCssByKey(knode, map, '*'); + _removeAttrOrCssByKey(knode, map); +} +function _removeAttrOrCssByKey(knode, map, mapKey) { + mapKey = mapKey || knode.name; + if (knode.type !== 1) { + return; + } + var newMap = _singleKeyMap(map); + if (!newMap[mapKey]) { + return; + } + var arr = newMap[mapKey].split(','), allFlag = false; + for (var i = 0, len = arr.length; i < len; i++) { + var key = arr[i]; + if (key === '*') { + allFlag = true; + break; + } + var match = /^(\.?)([^=]+)(?:=([^=]*))?$/.exec(key); + key = match[2]; + if (match[1]) { + key = _toCamel(key); + if (knode[0].style[key]) { + knode[0].style[key] = ''; + } + } else { + knode.removeAttr(key); + } + } + if (allFlag) { + knode.remove(true); + } +} + +function _getInnerNode(knode) { + var inner = knode; + while (inner.first()) { + inner = inner.first(); + } + return inner; +} + +function _isEmptyNode(knode) { + if (knode.type != 1 || knode.isSingle()) { + return false; + } + return knode.html().replace(/<[^>]+>/g, '') === ''; +} + + + + +function _mergeWrapper(a, b) { + a = a.clone(true); + var lastA = _getInnerNode(a), childA = a, merged = false; + while (b) { + while (childA) { + if (childA.name === b.name) { + _mergeAttrs(childA, b.attr(), b.css()); + merged = true; + } + childA = childA.first(); + } + if (!merged) { + lastA.append(b.clone(false)); + } + merged = false; + b = b.first(); + } + return a; +} + +function _wrapNode(knode, wrapper) { + wrapper = wrapper.clone(true); + if (knode.type == 3) { + _getInnerNode(wrapper).append(knode.clone(false)); + knode.replaceWith(wrapper); + return wrapper; + } + var nodeWrapper = knode, child; + while ((child = knode.first()) && child.children().length == 1) { + knode = child; + } + child = knode.first(); + var frag = knode.doc.createDocumentFragment(); + while (child) { + frag.appendChild(child[0]); + child = child.next(); + } + wrapper = _mergeWrapper(nodeWrapper, wrapper); + if (frag.firstChild) { + _getInnerNode(wrapper).append(frag); + } + nodeWrapper.replaceWith(wrapper); + return wrapper; +} + +function _mergeAttrs(knode, attrs, styles) { + _each(attrs, function(key, val) { + if (key !== 'style') { + knode.attr(key, val); + } + }); + _each(styles, function(key, val) { + knode.css(key, val); + }); +} + +function _inPreElement(knode) { + while (knode && knode.name != 'body') { + if (_PRE_TAG_MAP[knode.name] || knode.name == 'div' && knode.hasClass('ke-script')) { + return true; + } + knode = knode.parent(); + } + return false; +} + +function KCmd(range) { + this.init(range); +} +_extend(KCmd, { + init : function(range) { + var self = this, doc = range.doc; + self.doc = doc; + self.win = _getWin(doc); + self.sel = _getSel(doc); + self.range = range; + }, + selection : function(forceReset) { + var self = this, doc = self.doc, rng = _getRng(doc); + self.sel = _getSel(doc); + if (rng) { + self.range = _range(rng); + if (K(self.range.startContainer).name == 'html') { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + } + if (forceReset) { + self.range.selectNodeContents(doc.body).collapse(false); + } + return self; + }, + select : function(hasDummy) { + hasDummy = _undef(hasDummy, true); + var self = this, sel = self.sel, range = self.range.cloneRange().shrink(), + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + doc = _getDoc(sc), win = self.win, rng, hasU200b = false; + if (hasDummy && sc.nodeType == 1 && range.collapsed) { + if (_IERANGE) { + var dummy = K('<span>&nbsp;</span>', doc); + range.insertNode(dummy[0]); + rng = doc.body.createTextRange(); + try { + rng.moveToElementText(dummy[0]); + } catch(ex) {} + rng.collapse(false); + rng.select(); + dummy.remove(); + win.focus(); + return self; + } + if (_WEBKIT) { + var children = sc.childNodes; + if (K(sc).isInline() || so > 0 && K(children[so - 1]).isInline() || children[so] && K(children[so]).isInline()) { + range.insertNode(doc.createTextNode('\u200B')); + hasU200b = true; + } + } + } + if (_IERANGE) { + try { + rng = range.get(true); + rng.select(); + } catch(e) {} + } else { + if (hasU200b) { + range.collapse(false); + } + rng = range.get(true); + sel.removeAllRanges(); + sel.addRange(rng); + if (doc !== document) { + var pos = K(rng.endContainer).pos(); + win.scrollTo(pos.x, pos.y); + } + } + win.focus(); + return self; + }, + wrap : function(val) { + var self = this, doc = self.doc, range = self.range, wrapper; + wrapper = K(val, doc); + if (range.collapsed) { + range.shrink(); + range.insertNode(wrapper[0]).selectNodeContents(wrapper[0]); + return self; + } + if (wrapper.isBlock()) { + var copyWrapper = wrapper.clone(true), child = copyWrapper; + while (child.first()) { + child = child.first(); + } + child.append(range.extractContents()); + range.insertNode(copyWrapper[0]).selectNode(copyWrapper[0]); + return self; + } + range.enlarge(); + var bookmark = range.createBookmark(), ancestor = range.commonAncestor(), isStart = false; + K(ancestor).scan(function(node) { + if (!isStart && node == bookmark.start) { + isStart = true; + return; + } + if (isStart) { + if (node == bookmark.end) { + return false; + } + var knode = K(node); + if (_inPreElement(knode)) { + return; + } + if (knode.type == 3 && _trim(node.nodeValue).length > 0) { + var parent; + while ((parent = knode.parent()) && parent.isStyle() && parent.children().length == 1) { + knode = parent; + } + _wrapNode(knode, wrapper); + } + } + }); + range.moveToBookmark(bookmark); + return self; + }, + split : function(isStart, map) { + var range = this.range, doc = range.doc; + var tempRange = range.cloneRange().collapse(isStart); + var node = tempRange.startContainer, pos = tempRange.startOffset, + parent = node.nodeType == 3 ? node.parentNode : node, + needSplit = false, knode; + while (parent && parent.parentNode) { + knode = K(parent); + if (map) { + if (!knode.isStyle()) { + break; + } + if (!_hasAttrOrCss(knode, map)) { + break; + } + } else { + if (_NOSPLIT_TAG_MAP[knode.name]) { + break; + } + } + needSplit = true; + parent = parent.parentNode; + } + if (needSplit) { + var dummy = doc.createElement('span'); + range.cloneRange().collapse(!isStart).insertNode(dummy); + if (isStart) { + tempRange.setStartBefore(parent.firstChild).setEnd(node, pos); + } else { + tempRange.setStart(node, pos).setEndAfter(parent.lastChild); + } + var frag = tempRange.extractContents(), + first = frag.firstChild, last = frag.lastChild; + if (isStart) { + tempRange.insertNode(frag); + range.setStartAfter(last).setEndBefore(dummy); + } else { + parent.appendChild(frag); + range.setStartBefore(dummy).setEndBefore(first); + } + var dummyParent = dummy.parentNode; + if (dummyParent == range.endContainer) { + var prev = K(dummy).prev(), next = K(dummy).next(); + if (prev && next && prev.type == 3 && next.type == 3) { + range.setEnd(prev[0], prev[0].nodeValue.length); + } else if (!isStart) { + range.setEnd(range.endContainer, range.endOffset - 1); + } + } + dummyParent.removeChild(dummy); + } + return this; + }, + remove : function(map) { + var self = this, doc = self.doc, range = self.range; + range.enlarge(); + if (range.startOffset === 0) { + var ksc = K(range.startContainer), parent; + while ((parent = ksc.parent()) && parent.isStyle() && parent.children().length == 1) { + ksc = parent; + } + range.setStart(ksc[0], 0); + ksc = K(range.startContainer); + if (ksc.isBlock()) { + _removeAttrOrCss(ksc, map); + } + var kscp = ksc.parent(); + if (kscp && kscp.isBlock()) { + _removeAttrOrCss(kscp, map); + } + } + var sc, so; + if (range.collapsed) { + self.split(true, map); + sc = range.startContainer; + so = range.startOffset; + if (so > 0) { + var sb = K(sc.childNodes[so - 1]); + if (sb && _isEmptyNode(sb)) { + sb.remove(); + range.setStart(sc, so - 1); + } + } + var sa = K(sc.childNodes[so]); + if (sa && _isEmptyNode(sa)) { + sa.remove(); + } + if (_isEmptyNode(sc)) { + range.startBefore(sc); + sc.remove(); + } + range.collapse(true); + return self; + } + self.split(true, map); + self.split(false, map); + var startDummy = doc.createElement('span'), endDummy = doc.createElement('span'); + range.cloneRange().collapse(false).insertNode(endDummy); + range.cloneRange().collapse(true).insertNode(startDummy); + var nodeList = [], cmpStart = false; + K(range.commonAncestor()).scan(function(node) { + if (!cmpStart && node == startDummy) { + cmpStart = true; + return; + } + if (node == endDummy) { + return false; + } + if (cmpStart) { + nodeList.push(node); + } + }); + K(startDummy).remove(); + K(endDummy).remove(); + sc = range.startContainer; + so = range.startOffset; + var ec = range.endContainer, eo = range.endOffset; + if (so > 0) { + var startBefore = K(sc.childNodes[so - 1]); + if (startBefore && _isEmptyNode(startBefore)) { + startBefore.remove(); + range.setStart(sc, so - 1); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + var startAfter = K(sc.childNodes[so]); + if (startAfter && _isEmptyNode(startAfter)) { + startAfter.remove(); + if (sc == ec) { + range.setEnd(ec, eo - 1); + } + } + } + var endAfter = K(ec.childNodes[range.endOffset]); + if (endAfter && _isEmptyNode(endAfter)) { + endAfter.remove(); + } + var bookmark = range.createBookmark(true); + _each(nodeList, function(i, node) { + _removeAttrOrCss(K(node), map); + }); + range.moveToBookmark(bookmark); + return self; + }, + commonNode : function(map) { + var range = this.range; + var ec = range.endContainer, eo = range.endOffset, + node = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + var child = node, parent = node; + while (parent) { + if (_hasAttrOrCss(K(parent), map)) { + return K(parent); + } + parent = parent.parentNode; + } + while (child && (child = child.lastChild)) { + if (_hasAttrOrCss(K(child), map)) { + return K(child); + } + } + return null; + } + var cNode = find(node); + if (cNode) { + return cNode; + } + if (node.nodeType == 1 || (ec.nodeType == 3 && eo === 0)) { + var prev = K(node).prev(); + if (prev) { + return find(prev); + } + } + return null; + }, + commonAncestor : function(tagName) { + var range = this.range, + sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset, + startNode = (sc.nodeType == 3 || so === 0) ? sc : sc.childNodes[so - 1], + endNode = (ec.nodeType == 3 || eo === 0) ? ec : ec.childNodes[eo - 1]; + function find(node) { + while (node) { + if (node.nodeType == 1) { + if (node.tagName.toLowerCase() === tagName) { + return node; + } + } + node = node.parentNode; + } + return null; + } + var start = find(startNode), end = find(endNode); + if (start && end && start === end) { + return K(start); + } + return null; + }, + state : function(key) { + var self = this, doc = self.doc, bool = false; + try { + bool = doc.queryCommandState(key); + } catch (e) {} + return bool; + }, + val : function(key) { + var self = this, doc = self.doc, range = self.range; + function lc(val) { + return val.toLowerCase(); + } + key = lc(key); + var val = '', knode; + if (key === 'fontfamily' || key === 'fontname') { + val = _nativeCommandValue(doc, 'fontname'); + val = val.replace(/['"]/g, ''); + return lc(val); + } + if (key === 'formatblock') { + val = _nativeCommandValue(doc, key); + if (val === '') { + knode = self.commonNode({'h1,h2,h3,h4,h5,h6,p,div,pre,address' : '*'}); + if (knode) { + val = knode.name; + } + } + if (val === 'Normal') { + val = 'p'; + } + return lc(val); + } + if (key === 'fontsize') { + knode = self.commonNode({'*' : '.font-size'}); + if (knode) { + val = knode.css('font-size'); + } + return lc(val); + } + if (key === 'forecolor') { + knode = self.commonNode({'*' : '.color'}); + if (knode) { + val = knode.css('color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + if (key === 'hilitecolor') { + knode = self.commonNode({'*' : '.background-color'}); + if (knode) { + val = knode.css('background-color'); + } + val = _toHex(val); + if (val === '') { + val = 'default'; + } + return lc(val); + } + return val; + }, + toggle : function(wrapper, map) { + var self = this; + if (self.commonNode(map)) { + self.remove(map); + } else { + self.wrap(wrapper); + } + return self.select(); + }, + bold : function() { + return this.toggle('<strong></strong>', { + span : '.font-weight=bold', + strong : '*', + b : '*' + }); + }, + italic : function() { + return this.toggle('<em></em>', { + span : '.font-style=italic', + em : '*', + i : '*' + }); + }, + underline : function() { + return this.toggle('<u></u>', { + span : '.text-decoration=underline', + u : '*' + }); + }, + strikethrough : function() { + return this.toggle('<s></s>', { + span : '.text-decoration=line-through', + s : '*' + }); + }, + forecolor : function(val) { + return this.wrap('<span style="color:' + val + ';"></span>').select(); + }, + hilitecolor : function(val) { + return this.wrap('<span style="background-color:' + val + ';"></span>').select(); + }, + fontsize : function(val) { + return this.wrap('<span style="font-size:' + val + ';"></span>').select(); + }, + fontname : function(val) { + return this.fontfamily(val); + }, + fontfamily : function(val) { + return this.wrap('<span style="font-family:' + val + ';"></span>').select(); + }, + removeformat : function() { + var map = { + '*' : '.font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent' + }, + tags = _STYLE_TAG_MAP; + _each(tags, function(key, val) { + map[key] = '*'; + }); + this.remove(map); + return this.select(); + }, + inserthtml : function(val, quickMode) { + var self = this, range = self.range; + if (val === '') { + return self; + } + function pasteHtml(range, val) { + val = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + val; + var rng = range.get(); + if (rng.item) { + rng.item(0).outerHTML = val; + } else { + rng.pasteHTML(val); + } + var temp = range.doc.getElementById('__kindeditor_temp_tag__'); + temp.parentNode.removeChild(temp); + var newRange = _toRange(rng); + range.setEnd(newRange.endContainer, newRange.endOffset); + range.collapse(false); + self.select(false); + } + function insertHtml(range, val) { + var doc = range.doc, + frag = doc.createDocumentFragment(); + K('@' + val, doc).each(function() { + frag.appendChild(this); + }); + range.deleteContents(); + range.insertNode(frag); + range.collapse(false); + self.select(false); + } + if (_IERANGE && quickMode) { + try { + pasteHtml(range, val); + } catch(e) { + insertHtml(range, val); + } + return self; + } + insertHtml(range, val); + return self; + }, + hr : function() { + return this.inserthtml('<hr />'); + }, + print : function() { + this.win.print(); + return this; + }, + insertimage : function(url, title, width, height, border, align) { + title = _undef(title, ''); + border = _undef(border, 0); + var html = '<img src="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" '; + if (width) { + html += 'width="' + _escape(width) + '" '; + } + if (height) { + html += 'height="' + _escape(height) + '" '; + } + if (title) { + html += 'title="' + _escape(title) + '" '; + } + if (align) { + html += 'align="' + _escape(align) + '" '; + } + html += 'alt="' + _escape(title) + '" '; + html += '/>'; + return this.inserthtml(html); + }, + createlink : function(url, type) { + var self = this, doc = self.doc, range = self.range; + self.select(); + var a = self.commonNode({ a : '*' }); + if (a && !range.isControl()) { + range.selectNode(a.get()); + self.select(); + } + var html = '<a href="' + _escape(url) + '" data-ke-src="' + _escape(url) + '" '; + if (type) { + html += ' target="' + _escape(type) + '"'; + } + if (range.collapsed) { + html += '>' + _escape(url) + '</a>'; + return self.inserthtml(html); + } + if (range.isControl()) { + var node = K(range.startContainer.childNodes[range.startOffset]); + html += '></a>'; + node.after(K(html, doc)); + node.next().append(node); + range.selectNode(node[0]); + return self.select(); + } + function setAttr(node, url, type) { + K(node).attr('href', url).attr('data-ke-src', url); + if (type) { + K(node).attr('target', type); + } else { + K(node).removeAttr('target'); + } + } + var sc = range.startContainer, so = range.startOffset, + ec = range.endContainer, eo = range.endOffset; + if (sc.nodeType == 1 && sc === ec && so + 1 === eo) { + var child = sc.childNodes[so]; + if (child.nodeName.toLowerCase() == 'a') { + setAttr(child, url, type); + return self; + } + } + _nativeCommand(doc, 'createlink', '__kindeditor_temp_url__'); + K('a[href="__kindeditor_temp_url__"]', doc).each(function() { + setAttr(this, url, type); + }); + return self; + }, + unlink : function() { + var self = this, doc = self.doc, range = self.range; + self.select(); + if (range.collapsed) { + var a = self.commonNode({ a : '*' }); + if (a) { + range.selectNode(a.get()); + self.select(); + } + _nativeCommand(doc, 'unlink', null); + if (_WEBKIT && K(range.startContainer).name === 'img') { + var parent = K(range.startContainer).parent(); + if (parent.name === 'a') { + parent.remove(true); + } + } + } else { + _nativeCommand(doc, 'unlink', null); + } + return self; + } +}); +_each(('formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' + + 'insertunorderedlist,indent,outdent,subscript,superscript').split(','), function(i, name) { + KCmd.prototype[name] = function(val) { + var self = this; + self.select(); + _nativeCommand(self.doc, name, val); + if (_IERANGE && _inArray(name, 'justifyleft,justifycenter,justifyright,justifyfull'.split(',')) >= 0) { + self.selection(); + } + if (!_IERANGE || _inArray(name, 'formatblock,selectall,insertorderedlist,insertunorderedlist'.split(',')) >= 0) { + self.selection(); + } + return self; + }; +}); +_each('cut,copy,paste'.split(','), function(i, name) { + KCmd.prototype[name] = function() { + var self = this; + if (!self.doc.queryCommandSupported(name)) { + throw 'not supported'; + } + self.select(); + _nativeCommand(self.doc, name, null); + return self; + }; +}); +function _cmd(mixed) { + if (mixed.nodeName) { + var doc = _getDoc(mixed); + mixed = _range(doc).selectNodeContents(doc.body).collapse(false); + } + return new KCmd(mixed); +} +K.CmdClass = KCmd; +K.cmd = _cmd; + + +function _drag(options) { + var moveEl = options.moveEl, + moveFn = options.moveFn, + clickEl = options.clickEl || moveEl, + beforeDrag = options.beforeDrag, + iframeFix = options.iframeFix === undefined ? true : options.iframeFix; + var docs = [document]; + if (iframeFix) { + K('iframe').each(function() { + var src = _formatUrl(this.src || '', 'absolute'); + if (/^https?:\/\//.test(src)) { + return; + } + var doc; + try { + doc = _iframeDoc(this); + } catch(e) {} + if (doc) { + var pos = K(this).pos(); + K(doc).data('pos-x', pos.x); + K(doc).data('pos-y', pos.y); + docs.push(doc); + } + }); + } + clickEl.mousedown(function(e) { + if(e.button !== 0 && e.button !== 1) { + return; + } + e.stopPropagation(); + var self = clickEl.get(), + x = _removeUnit(moveEl.css('left')), + y = _removeUnit(moveEl.css('top')), + width = moveEl.width(), + height = moveEl.height(), + pageX = e.pageX, + pageY = e.pageY; + if (beforeDrag) { + beforeDrag(); + } + function moveListener(e) { + e.preventDefault(); + var kdoc = K(_getDoc(e.target)); + var diffX = _round((kdoc.data('pos-x') || 0) + e.pageX - pageX); + var diffY = _round((kdoc.data('pos-y') || 0) + e.pageY - pageY); + moveFn.call(clickEl, x, y, width, height, diffX, diffY); + } + function selectListener(e) { + e.preventDefault(); + } + function upListener(e) { + e.preventDefault(); + K(docs).unbind('mousemove', moveListener) + .unbind('mouseup', upListener) + .unbind('selectstart', selectListener); + if (self.releaseCapture) { + self.releaseCapture(); + } + } + K(docs).mousemove(moveListener) + .mouseup(upListener) + .bind('selectstart', selectListener); + if (self.setCapture) { + self.setCapture(); + } + }); +} + + +function KWidget(options) { + this.init(options); +} +_extend(KWidget, { + init : function(options) { + var self = this; + self.name = options.name || ''; + self.doc = options.doc || document; + self.win = _getWin(self.doc); + self.x = _addUnit(options.x); + self.y = _addUnit(options.y); + self.z = options.z; + self.width = _addUnit(options.width); + self.height = _addUnit(options.height); + self.div = K('<div style="display:block;"></div>'); + self.options = options; + self._alignEl = options.alignEl; + if (self.width) { + self.div.css('width', self.width); + } + if (self.height) { + self.div.css('height', self.height); + } + if (self.z) { + self.div.css({ + position : 'absolute', + left : self.x, + top : self.y, + 'z-index' : self.z + }); + } + if (self.z && (self.x === undefined || self.y === undefined)) { + self.autoPos(self.width, self.height); + } + if (options.cls) { + self.div.addClass(options.cls); + } + if (options.shadowMode) { + self.div.addClass('ke-shadow'); + } + if (options.css) { + self.div.css(options.css); + } + if (options.src) { + K(options.src).replaceWith(self.div); + } else { + K(self.doc.body).append(self.div); + } + if (options.html) { + self.div.html(options.html); + } + if (options.autoScroll) { + if (_IE && _V < 7 || _QUIRKS) { + var scrollPos = _getScrollPos(); + K(self.win).bind('scroll', function(e) { + var pos = _getScrollPos(), + diffX = pos.x - scrollPos.x, + diffY = pos.y - scrollPos.y; + self.pos(_removeUnit(self.x) + diffX, _removeUnit(self.y) + diffY, false); + }); + } else { + self.div.css('position', 'fixed'); + } + } + }, + pos : function(x, y, updateProp) { + var self = this; + updateProp = _undef(updateProp, true); + if (x !== null) { + x = x < 0 ? 0 : _addUnit(x); + self.div.css('left', x); + if (updateProp) { + self.x = x; + } + } + if (y !== null) { + y = y < 0 ? 0 : _addUnit(y); + self.div.css('top', y); + if (updateProp) { + self.y = y; + } + } + return self; + }, + autoPos : function(width, height) { + var self = this, + w = _removeUnit(width) || 0, + h = _removeUnit(height) || 0, + scrollPos = _getScrollPos(); + if (self._alignEl) { + var knode = K(self._alignEl), + pos = knode.pos(), + diffX = _round(knode[0].clientWidth / 2 - w / 2), + diffY = _round(knode[0].clientHeight / 2 - h / 2); + x = diffX < 0 ? pos.x : pos.x + diffX; + y = diffY < 0 ? pos.y : pos.y + diffY; + } else { + var docEl = _docElement(self.doc); + x = _round(scrollPos.x + (docEl.clientWidth - w) / 2); + y = _round(scrollPos.y + (docEl.clientHeight - h) / 2); + } + if (!(_IE && _V < 7 || _QUIRKS)) { + x -= scrollPos.x; + y -= scrollPos.y; + } + return self.pos(x, y); + }, + remove : function() { + var self = this; + if (_IE && _V < 7 || _QUIRKS) { + K(self.win).unbind('scroll'); + } + self.div.remove(); + _each(self, function(i) { + self[i] = null; + }); + return this; + }, + show : function() { + this.div.show(); + return this; + }, + hide : function() { + this.div.hide(); + return this; + }, + draggable : function(options) { + var self = this; + options = options || {}; + options.moveEl = self.div; + options.moveFn = function(x, y, width, height, diffX, diffY) { + if ((x = x + diffX) < 0) { + x = 0; + } + if ((y = y + diffY) < 0) { + y = 0; + } + self.pos(x, y); + }; + _drag(options); + return self; + } +}); +function _widget(options) { + return new KWidget(options); +} +K.WidgetClass = KWidget; +K.widget = _widget; + + +function _iframeDoc(iframe) { + iframe = _get(iframe); + return iframe.contentDocument || iframe.contentWindow.document; +} +var html, _direction = ''; +if ((html = document.getElementsByTagName('html'))) { + _direction = html[0].dir; +} +function _getInitHtml(themesPath, bodyClass, cssPath, cssData) { + var arr = [ + (_direction === '' ? '<html>' : '<html dir="' + _direction + '">'), + '<head><meta charset="utf-8" /><title></title>', + '<style>', + 'html {margin:0;padding:0;}', + 'body {margin:0;padding:5px;}', + 'body, td {font:12px/1.5 "sans serif",tahoma,verdana,helvetica;}', + 'body, p, div {word-wrap: break-word;}', + 'p {margin:5px 0;}', + 'table {border-collapse:collapse;}', + 'img {border:0;}', + 'noscript {display:none;}', + 'table.ke-zeroborder td {border:1px dotted #AAA;}', + 'img.ke-flash {', + ' border:1px solid #AAA;', + ' background-image:url(' + themesPath + 'common/flash.gif);', + ' background-position:center center;', + ' background-repeat:no-repeat;', + ' width:100px;', + ' height:100px;', + '}', + 'img.ke-rm {', + ' border:1px solid #AAA;', + ' background-image:url(' + themesPath + 'common/rm.gif);', + ' background-position:center center;', + ' background-repeat:no-repeat;', + ' width:100px;', + ' height:100px;', + '}', + 'img.ke-media {', + ' border:1px solid #AAA;', + ' background-image:url(' + themesPath + 'common/media.gif);', + ' background-position:center center;', + ' background-repeat:no-repeat;', + ' width:100px;', + ' height:100px;', + '}', + 'img.ke-anchor {', + ' border:1px dashed #666;', + ' width:16px;', + ' height:16px;', + '}', + '.ke-script, .ke-noscript, .ke-display-none {', + ' display:none;', + ' font-size:0;', + ' width:0;', + ' height:0;', + '}', + '.ke-pagebreak {', + ' border:1px dotted #AAA;', + ' font-size:0;', + ' height:2px;', + '}', + '</style>' + ]; + if (!_isArray(cssPath)) { + cssPath = [cssPath]; + } + _each(cssPath, function(i, path) { + if (path) { + arr.push('<link href="' + path + '" rel="stylesheet" />'); + } + }); + if (cssData) { + arr.push('<style>' + cssData + '</style>'); + } + arr.push('</head><body ' + (bodyClass ? 'class="' + bodyClass + '"' : '') + '></body></html>'); + return arr.join('\n'); +} +function _elementVal(knode, val) { + if (knode.hasVal()) { + if (val === undefined) { + var html = knode.val(); + html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); + return html; + } + return knode.val(val); + } + return knode.html(val); +} + + +function KEdit(options) { + this.init(options); +} +_extend(KEdit, KWidget, { + init : function(options) { + var self = this; + KEdit.parent.init.call(self, options); + self.srcElement = K(options.srcElement); + self.div.addClass('ke-edit'); + self.designMode = _undef(options.designMode, true); + self.beforeGetHtml = options.beforeGetHtml; + self.beforeSetHtml = options.beforeSetHtml; + self.afterSetHtml = options.afterSetHtml; + var themesPath = _undef(options.themesPath, ''), + bodyClass = options.bodyClass, + cssPath = options.cssPath, + cssData = options.cssData, + isDocumentDomain = location.protocol != 'res:' && location.host.replace(/:\d+/, '') !== document.domain, + srcScript = ('document.open();' + + (isDocumentDomain ? 'document.domain="' + document.domain + '";' : '') + + 'document.close();'), + iframeSrc = _IE ? ' src="javascript:void(function(){' + encodeURIComponent(srcScript) + '}())"' : ''; + self.iframe = K('<iframe class="ke-edit-iframe" hidefocus="true" frameborder="0"' + iframeSrc + '></iframe>').css('width', '100%'); + self.textarea = K('<textarea class="ke-edit-textarea" hidefocus="true"></textarea>').css('width', '100%'); + self.tabIndex = isNaN(parseInt(options.tabIndex, 10)) ? self.srcElement.attr('tabindex') : parseInt(options.tabIndex, 10); + self.iframe.attr('tabindex', self.tabIndex); + self.textarea.attr('tabindex', self.tabIndex); + if (self.width) { + self.setWidth(self.width); + } + if (self.height) { + self.setHeight(self.height); + } + if (self.designMode) { + self.textarea.hide(); + } else { + self.iframe.hide(); + } + function ready() { + var doc = _iframeDoc(self.iframe); + doc.open(); + if (isDocumentDomain) { + doc.domain = document.domain; + } + doc.write(_getInitHtml(themesPath, bodyClass, cssPath, cssData)); + doc.close(); + self.win = self.iframe[0].contentWindow; + self.doc = doc; + var cmd = _cmd(doc); + self.afterChange(function(e) { + cmd.selection(); + }); + if (_WEBKIT) { + K(doc).click(function(e) { + if (K(e.target).name === 'img') { + cmd.selection(true); + cmd.range.selectNode(e.target); + cmd.select(); + } + }); + } + if (_IE) { + self._mousedownHandler = function() { + var newRange = cmd.range.cloneRange(); + newRange.shrink(); + if (newRange.isControl()) { + self.blur(); + } + }; + K(document).mousedown(self._mousedownHandler); + K(doc).keydown(function(e) { + if (e.which == 8) { + cmd.selection(); + var rng = cmd.range; + if (rng.isControl()) { + rng.collapse(true); + K(rng.startContainer.childNodes[rng.startOffset]).remove(); + e.preventDefault(); + } + } + }); + } + self.cmd = cmd; + self.html(_elementVal(self.srcElement)); + if (_IE) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.removeAttribute('disabled'); + } else { + doc.designMode = 'on'; + } + if (options.afterCreate) { + options.afterCreate.call(self); + } + } + if (isDocumentDomain) { + self.iframe.bind('load', function(e) { + self.iframe.unbind('load'); + if (_IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + } + self.div.append(self.iframe); + self.div.append(self.textarea); + self.srcElement.hide(); + !isDocumentDomain && ready(); + }, + setWidth : function(val) { + var self = this; + val = _addUnit(val); + self.width = val; + self.div.css('width', val); + return self; + }, + setHeight : function(val) { + var self = this; + val = _addUnit(val); + self.height = val; + self.div.css('height', val); + self.iframe.css('height', val); + if ((_IE && _V < 8) || _QUIRKS) { + val = _addUnit(_removeUnit(val) - 2); + } + self.textarea.css('height', val); + return self; + }, + remove : function() { + var self = this, doc = self.doc; + K(doc.body).unbind(); + K(doc).unbind(); + K(self.win).unbind(); + if (self._mousedownHandler) { + K(document).unbind('mousedown', self._mousedownHandler); + } + _elementVal(self.srcElement, self.html()); + self.srcElement.show(); + self.iframe.unbind(); + self.textarea.unbind(); + KEdit.parent.remove.call(self); + }, + html : function(val, isFull) { + var self = this, doc = self.doc; + if (self.designMode) { + var body = doc.body; + if (val === undefined) { + if (isFull) { + val = '<!doctype html><html>' + body.parentNode.innerHTML + '</html>'; + } else { + val = body.innerHTML; + } + if (self.beforeGetHtml) { + val = self.beforeGetHtml(val); + } + if (_GECKO && val == '<br />') { + val = ''; + } + return val; + } + if (self.beforeSetHtml) { + val = self.beforeSetHtml(val); + } + if (_IE && _V >= 9) { + val = val.replace(/(<.*?checked=")checked(".*>)/ig, '$1$2'); + } + K(body).html(val); + if (self.afterSetHtml) { + self.afterSetHtml(); + } + return self; + } + if (val === undefined) { + return self.textarea.val(); + } + self.textarea.val(val); + return self; + }, + design : function(bool) { + var self = this, val; + if (bool === undefined ? !self.designMode : bool) { + if (!self.designMode) { + val = self.html(); + self.designMode = true; + self.textarea.hide(); + self.html(val); + var iframe = self.iframe; + var height = _removeUnit(self.height); + iframe.height(height - 2); + iframe.show(); + setTimeout(function() { + iframe.height(height); + }, 0); + } + } else { + if (self.designMode) { + val = self.html(); + self.designMode = false; + self.html(val); + self.iframe.hide(); + self.textarea.show(); + } + } + return self.focus(); + }, + focus : function() { + var self = this; + self.designMode ? self.win.focus() : self.textarea[0].focus(); + return self; + }, + blur : function() { + var self = this; + if (_IE) { + var input = K('<input type="text" style="float:left;width:0;height:0;padding:0;margin:0;border:0;" value="" />', self.div); + self.div.append(input); + input[0].focus(); + input.remove(); + } else { + self.designMode ? self.win.blur() : self.textarea[0].blur(); + } + return self; + }, + afterChange : function(fn) { + var self = this, doc = self.doc, body = doc.body; + K(doc).keyup(function(e) { + if (!e.ctrlKey && !e.altKey && _CHANGE_KEY_MAP[e.which]) { + fn(e); + } + }); + K(doc).mouseup(fn).contextmenu(fn); + K(self.win).blur(fn); + function timeoutHandler(e) { + setTimeout(function() { + fn(e); + }, 1); + } + K(body).bind('paste', timeoutHandler); + K(body).bind('cut', timeoutHandler); + return self; + } +}); +function _edit(options) { + return new KEdit(options); +} +K.EditClass = KEdit; +K.edit = _edit; +K.iframeDoc = _iframeDoc; + + +function _selectToolbar(name, fn) { + var self = this, + knode = self.get(name); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + fn(knode); + } +} + + +function KToolbar(options) { + this.init(options); +} +_extend(KToolbar, KWidget, { + init : function(options) { + var self = this; + KToolbar.parent.init.call(self, options); + self.disableMode = _undef(options.disableMode, false); + self.noDisableItemMap = _toMap(_undef(options.noDisableItems, [])); + self._itemMap = {}; + self.div.addClass('ke-toolbar').bind('contextmenu,mousedown,mousemove', function(e) { + e.preventDefault(); + }).attr('unselectable', 'on'); + function find(target) { + var knode = K(target); + if (knode.hasClass('ke-outline')) { + return knode; + } + if (knode.hasClass('ke-toolbar-icon')) { + return knode.parent(); + } + } + function hover(e, method) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + if (knode.hasClass('ke-selected')) { + return; + } + knode[method]('ke-on'); + } + } + self.div.mouseover(function(e) { + hover(e, 'addClass'); + }) + .mouseout(function(e) { + hover(e, 'removeClass'); + }) + .click(function(e) { + var knode = find(e.target); + if (knode) { + if (knode.hasClass('ke-disabled')) { + return; + } + self.options.click.call(this, e, knode.attr('data-name')); + } + }); + }, + get : function(name) { + if (this._itemMap[name]) { + return this._itemMap[name]; + } + return (this._itemMap[name] = K('span.ke-icon-' + name, this.div).parent()); + }, + select : function(name) { + _selectToolbar.call(this, name, function(knode) { + knode.addClass('ke-selected'); + }); + return self; + }, + unselect : function(name) { + _selectToolbar.call(this, name, function(knode) { + knode.removeClass('ke-selected').removeClass('ke-on'); + }); + return self; + }, + enable : function(name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-disabled'); + knode.opacity(1); + } + return self; + }, + disable : function(name) { + var self = this, + knode = name.get ? name : self.get(name); + if (knode) { + knode.removeClass('ke-selected').addClass('ke-disabled'); + knode.opacity(0.5); + } + return self; + }, + disableAll : function(bool, noDisableItems) { + var self = this, map = self.noDisableItemMap, item; + if (noDisableItems) { + map = _toMap(noDisableItems); + } + if (bool === undefined ? !self.disableMode : bool) { + K('span.ke-outline', self.div).each(function() { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.disable(knode); + } + }); + self.disableMode = true; + } else { + K('span.ke-outline', self.div).each(function() { + var knode = K(this), + name = knode[0].getAttribute('data-name', 2); + if (!map[name]) { + self.enable(knode); + } + }); + self.disableMode = false; + } + return self; + } +}); +function _toolbar(options) { + return new KToolbar(options); +} +K.ToolbarClass = KToolbar; +K.toolbar = _toolbar; + + +function KMenu(options) { + this.init(options); +} +_extend(KMenu, KWidget, { + init : function(options) { + var self = this; + options.z = options.z || 811213; + KMenu.parent.init.call(self, options); + self.centerLineMode = _undef(options.centerLineMode, true); + self.div.addClass('ke-menu').bind('click,mousedown', function(e){ + e.stopPropagation(); + }).attr('unselectable', 'on'); + }, + addItem : function(item) { + var self = this; + if (item.title === '-') { + self.div.append(K('<div class="ke-menu-separator"></div>')); + return; + } + var itemDiv = K('<div class="ke-menu-item" unselectable="on"></div>'), + leftDiv = K('<div class="ke-inline-block ke-menu-item-left"></div>'), + rightDiv = K('<div class="ke-inline-block ke-menu-item-right"></div>'), + height = _addUnit(item.height), + iconClass = _undef(item.iconClass, ''); + self.div.append(itemDiv); + if (height) { + itemDiv.css('height', height); + rightDiv.css('line-height', height); + } + var centerDiv; + if (self.centerLineMode) { + centerDiv = K('<div class="ke-inline-block ke-menu-item-center"></div>'); + if (height) { + centerDiv.css('height', height); + } + } + itemDiv.mouseover(function(e) { + K(this).addClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.addClass('ke-menu-item-center-on'); + } + }) + .mouseout(function(e) { + K(this).removeClass('ke-menu-item-on'); + if (centerDiv) { + centerDiv.removeClass('ke-menu-item-center-on'); + } + }) + .click(function(e) { + item.click.call(K(this)); + e.stopPropagation(); + }) + .append(leftDiv); + if (centerDiv) { + itemDiv.append(centerDiv); + } + itemDiv.append(rightDiv); + if (item.checked) { + iconClass = 'ke-icon-checked'; + } + if (iconClass !== '') { + leftDiv.html('<span class="ke-inline-block ke-toolbar-icon ke-toolbar-icon-url ' + iconClass + '"></span>'); + } + rightDiv.html(item.title); + return self; + }, + remove : function() { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + K('.ke-menu-item', self.div[0]).unbind(); + KMenu.parent.remove.call(self); + return self; + } +}); +function _menu(options) { + return new KMenu(options); +} +K.MenuClass = KMenu; +K.menu = _menu; + + +function KColorPicker(options) { + this.init(options); +} +_extend(KColorPicker, KWidget, { + init : function(options) { + var self = this; + options.z = options.z || 811213; + KColorPicker.parent.init.call(self, options); + var colors = options.colors || [ + ['#E53333', '#E56600', '#FF9900', '#64451D', '#DFC5A4', '#FFE500'], + ['#009900', '#006600', '#99BB00', '#B8D100', '#60D978', '#00D5FF'], + ['#337FE5', '#003399', '#4C33E5', '#9933E5', '#CC33E5', '#EE33EE'], + ['#FFFFFF', '#CCCCCC', '#999999', '#666666', '#333333', '#000000'] + ]; + self.selectedColor = (options.selectedColor || '').toLowerCase(); + self._cells = []; + self.div.addClass('ke-colorpicker').bind('click,mousedown', function(e){ + e.stopPropagation(); + }).attr('unselectable', 'on'); + var table = self.doc.createElement('table'); + self.div.append(table); + table.className = 'ke-colorpicker-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var row = table.insertRow(0), cell = row.insertCell(0); + cell.colSpan = colors[0].length; + self._addAttr(cell, '', 'ke-colorpicker-cell-top'); + for (var i = 0; i < colors.length; i++) { + row = table.insertRow(i + 1); + for (var j = 0; j < colors[i].length; j++) { + cell = row.insertCell(j); + self._addAttr(cell, colors[i][j], 'ke-colorpicker-cell'); + } + } + }, + _addAttr : function(cell, color, cls) { + var self = this; + cell = K(cell).addClass(cls); + if (self.selectedColor === color.toLowerCase()) { + cell.addClass('ke-colorpicker-cell-selected'); + } + cell.attr('title', color || self.options.noColor); + cell.mouseover(function(e) { + K(this).addClass('ke-colorpicker-cell-on'); + }); + cell.mouseout(function(e) { + K(this).removeClass('ke-colorpicker-cell-on'); + }); + cell.click(function(e) { + e.stop(); + self.options.click.call(K(this), color); + }); + if (color) { + cell.append(K('<div class="ke-colorpicker-cell-color" unselectable="on"></div>').css('background-color', color)); + } else { + cell.html(self.options.noColor); + } + K(cell).attr('unselectable', 'on'); + self._cells.push(cell); + }, + remove : function() { + var self = this; + _each(self._cells, function() { + this.unbind(); + }); + KColorPicker.parent.remove.call(self); + return self; + } +}); +function _colorpicker(options) { + return new KColorPicker(options); +} +K.ColorPickerClass = KColorPicker; +K.colorpicker = _colorpicker; + + +function KUploadButton(options) { + this.init(options); +} +_extend(KUploadButton, { + init : function(options) { + var self = this, + button = K(options.button), + fieldName = options.fieldName || 'file', + url = options.url || '', + title = button.val(), + extraParams = options.extraParams || {}, + cls = button[0].className || '', + target = options.target || 'kindeditor_upload_iframe_' + new Date().getTime(); + options.afterError = options.afterError || function(str) { + alert(str); + }; + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />'); + } + var html = [ + '<div class="ke-inline-block ' + cls + '">', + (options.target ? '' : '<iframe name="' + target + '" style="display:none;"></iframe>'), + (options.form ? '<div class="ke-upload-area">' : '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + url + '">'), + '<span class="ke-button-common">', + hiddenElements.join(''), + '<input type="button" class="ke-button-common ke-button" value="' + title + '" />', + '</span>', + '<input type="file" class="ke-upload-file" name="' + fieldName + '" tabindex="-1" />', + (options.form ? '</div>' : '</form>'), + '</div>'].join(''); + var div = K(html, button.doc); + button.hide(); + button.before(div); + self.div = div; + self.button = button; + self.iframe = options.target ? K('iframe[name="' + target + '"]') : K('iframe', div); + self.form = options.form ? K(options.form) : K('form', div); + self.fileBox = K('.ke-upload-file', div); + var width = options.width || K('.ke-button-common', div).width(); + K('.ke-upload-area', div).width(width); + self.options = options; + }, + submit : function() { + var self = this, + iframe = self.iframe; + iframe.bind('load', function() { + iframe.unbind(); + var tempForm = document.createElement('form'); + self.fileBox.before(tempForm); + K(tempForm).append(self.fileBox); + tempForm.reset(); + K(tempForm).remove(true); + var doc = K.iframeDoc(iframe), + pre = doc.getElementsByTagName('pre')[0], + str = '', data; + if (pre) { + str = pre.innerHTML; + } else { + str = doc.body.innerHTML; + } + str = _unescape(str); + iframe[0].src = 'javascript:false'; + try { + data = K.json(str); + } catch (e) { + self.options.afterError.call(self, '<!doctype html><html>' + doc.body.parentNode.innerHTML + '</html>'); + } + if (data) { + self.options.afterUpload.call(self, data); + } + }); + self.form[0].submit(); + return self; + }, + remove : function() { + var self = this; + if (self.fileBox) { + self.fileBox.unbind(); + } + self.iframe.remove(); + self.div.remove(); + self.button.show(); + return self; + } +}); +function _uploadbutton(options) { + return new KUploadButton(options); +} +K.UploadButtonClass = KUploadButton; +K.uploadbutton = _uploadbutton; + + +function _createButton(arg) { + arg = arg || {}; + var name = arg.name || '', + span = K('<span class="ke-button-common ke-button-outer" title="' + name + '"></span>'), + btn = K('<input class="ke-button-common ke-button" type="button" value="' + name + '" />'); + if (arg.click) { + btn.click(arg.click); + } + span.append(btn); + return span; +} + + +function KDialog(options) { + this.init(options); +} +_extend(KDialog, KWidget, { + init : function(options) { + var self = this; + var shadowMode = _undef(options.shadowMode, true); + options.z = options.z || 811213; + options.shadowMode = false; + options.autoScroll = _undef(options.autoScroll, true); + KDialog.parent.init.call(self, options); + var title = options.title, + body = K(options.body, self.doc), + previewBtn = options.previewBtn, + yesBtn = options.yesBtn, + noBtn = options.noBtn, + closeBtn = options.closeBtn, + showMask = _undef(options.showMask, true); + self.div.addClass('ke-dialog').bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + var contentDiv = K('<div class="ke-dialog-content"></div>').appendTo(self.div); + if (_IE && _V < 7) { + self.iframeMask = K('<iframe src="about:blank" class="ke-dialog-shadow"></iframe>').appendTo(self.div); + } else if (shadowMode) { + K('<div class="ke-dialog-shadow"></div>').appendTo(self.div); + } + var headerDiv = K('<div class="ke-dialog-header"></div>'); + contentDiv.append(headerDiv); + headerDiv.html(title); + self.closeIcon = K('<span class="ke-dialog-icon-close" title="' + closeBtn.name + '"></span>').click(closeBtn.click); + headerDiv.append(self.closeIcon); + self.draggable({ + clickEl : headerDiv, + beforeDrag : options.beforeDrag + }); + var bodyDiv = K('<div class="ke-dialog-body"></div>'); + contentDiv.append(bodyDiv); + bodyDiv.append(body); + var footerDiv = K('<div class="ke-dialog-footer"></div>'); + if (previewBtn || yesBtn || noBtn) { + contentDiv.append(footerDiv); + } + _each([ + { btn : previewBtn, name : 'preview' }, + { btn : yesBtn, name : 'yes' }, + { btn : noBtn, name : 'no' } + ], function() { + if (this.btn) { + var button = _createButton(this.btn); + button.addClass('ke-dialog-' + this.name); + footerDiv.append(button); + } + }); + if (self.height) { + bodyDiv.height(_removeUnit(self.height) - headerDiv.height() - footerDiv.height()); + } + self.div.width(self.div.width()); + self.div.height(self.div.height()); + self.mask = null; + if (showMask) { + var docEl = _docElement(self.doc), + docWidth = Math.max(docEl.scrollWidth, docEl.clientWidth), + docHeight = Math.max(docEl.scrollHeight, docEl.clientHeight); + self.mask = _widget({ + x : 0, + y : 0, + z : self.z - 1, + cls : 'ke-dialog-mask', + width : docWidth, + height : docHeight + }); + } + self.autoPos(self.div.width(), self.div.height()); + self.footerDiv = footerDiv; + self.bodyDiv = bodyDiv; + self.headerDiv = headerDiv; + self.isLoading = false; + }, + setMaskIndex : function(z) { + var self = this; + self.mask.div.css('z-index', z); + }, + showLoading : function(msg) { + msg = _undef(msg, ''); + var self = this, body = self.bodyDiv; + self.loading = K('<div class="ke-dialog-loading"><div class="ke-inline-block ke-dialog-loading-content" style="margin-top:' + Math.round(body.height() / 3) + 'px;">' + msg + '</div></div>') + .width(body.width()).height(body.height()) + .css('top', self.headerDiv.height() + 'px'); + body.css('visibility', 'hidden').after(self.loading); + self.isLoading = true; + return self; + }, + hideLoading : function() { + this.loading && this.loading.remove(); + this.bodyDiv.css('visibility', 'visible'); + this.isLoading = false; + return this; + }, + remove : function() { + var self = this; + if (self.options.beforeRemove) { + self.options.beforeRemove.call(self); + } + self.mask && self.mask.remove(); + self.iframeMask && self.iframeMask.remove(); + self.closeIcon.unbind(); + K('input', self.div).unbind(); + K('button', self.div).unbind(); + self.footerDiv.unbind(); + self.bodyDiv.unbind(); + self.headerDiv.unbind(); + K('iframe', self.div).each(function() { + K(this).remove(); + }); + KDialog.parent.remove.call(self); + return self; + } +}); +function _dialog(options) { + return new KDialog(options); +} +K.DialogClass = KDialog; +K.dialog = _dialog; + + +function _tabs(options) { + var self = _widget(options), + remove = self.remove, + afterSelect = options.afterSelect, + div = self.div, + liList = []; + div.addClass('ke-tabs') + .bind('contextmenu,mousedown,mousemove', function(e) { + e.preventDefault(); + }); + var ul = K('<ul class="ke-tabs-ul ke-clearfix"></ul>'); + div.append(ul); + self.add = function(tab) { + var li = K('<li class="ke-tabs-li">' + tab.title + '</li>'); + li.data('tab', tab); + liList.push(li); + ul.append(li); + }; + self.selectedIndex = 0; + self.select = function(index) { + self.selectedIndex = index; + _each(liList, function(i, li) { + li.unbind(); + if (i === index) { + li.addClass('ke-tabs-li-selected'); + K(li.data('tab').panel).show(''); + } else { + li.removeClass('ke-tabs-li-selected').removeClass('ke-tabs-li-on') + .mouseover(function() { + K(this).addClass('ke-tabs-li-on'); + }) + .mouseout(function() { + K(this).removeClass('ke-tabs-li-on'); + }) + .click(function() { + self.select(i); + }); + K(li.data('tab').panel).hide(); + } + }); + if (afterSelect) { + afterSelect.call(self, index); + } + }; + self.remove = function() { + _each(liList, function() { + this.remove(); + }); + ul.remove(); + remove.call(self); + }; + return self; +} +K.tabs = _tabs; + + +function _loadScript(url, fn) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + script = document.createElement('script'); + head.appendChild(script); + script.src = url; + script.charset = 'utf-8'; + script.onload = script.onreadystatechange = function() { + if (!this.readyState || this.readyState === 'loaded') { + if (fn) { + fn(); + } + script.onload = script.onreadystatechange = null; + head.removeChild(script); + } + }; +} + + +function _chopQuery(url) { + var index = url.indexOf('?'); + return index > 0 ? url.substr(0, index) : url; +} +function _loadStyle(url) { + var head = document.getElementsByTagName('head')[0] || (_QUIRKS ? document.body : document.documentElement), + link = document.createElement('link'), + absoluteUrl = _chopQuery(_formatUrl(url, 'absolute')); + var links = K('link[rel="stylesheet"]', head); + for (var i = 0, len = links.length; i < len; i++) { + if (_chopQuery(_formatUrl(links[i].href, 'absolute')) === absoluteUrl) { + return; + } + } + head.appendChild(link); + link.href = url; + link.rel = 'stylesheet'; +} +function _ajax(url, fn, method, param, dataType) { + method = method || 'GET'; + dataType = dataType || 'json'; + var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); + xhr.open(method, url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4 && xhr.status == 200) { + if (fn) { + var data = _trim(xhr.responseText); + if (dataType == 'json') { + data = _json(data); + } + fn(data); + } + } + }; + if (method == 'POST') { + var params = []; + _each(param, function(key, val) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + }); + try { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } catch (e) {} + xhr.send(params.join('&')); + } else { + xhr.send(null); + } +} +K.loadScript = _loadScript; +K.loadStyle = _loadStyle; +K.ajax = _ajax; + + +var _plugins = {}; +function _plugin(name, fn) { + if (name === undefined) { + return _plugins; + } + if (!fn) { + return _plugins[name]; + } + _plugins[name] = fn; +} +var _language = {}; +function _parseLangKey(key) { + var match, ns = 'core'; + if ((match = /^(\w+)\.(\w+)$/.exec(key))) { + ns = match[1]; + key = match[2]; + } + return { ns : ns, key : key }; +} +function _lang(mixed, langType) { + langType = langType === undefined ? K.options.langType : langType; + if (typeof mixed === 'string') { + if (!_language[langType]) { + return 'no language'; + } + var pos = mixed.length - 1; + if (mixed.substr(pos) === '.') { + return _language[langType][mixed.substr(0, pos)]; + } + var obj = _parseLangKey(mixed); + return _language[langType][obj.ns][obj.key]; + } + _each(mixed, function(key, val) { + var obj = _parseLangKey(key); + if (!_language[langType]) { + _language[langType] = {}; + } + if (!_language[langType][obj.ns]) { + _language[langType][obj.ns] = {}; + } + _language[langType][obj.ns][obj.key] = val; + }); +} + + +function _getImageFromRange(range, fn) { + if (range.collapsed) { + return; + } + range = range.cloneRange().up(); + var sc = range.startContainer, so = range.startOffset; + if (!_WEBKIT && !range.isControl()) { + return; + } + var img = K(sc.childNodes[so]); + if (!img || img.name != 'img') { + return; + } + if (fn(img)) { + return img; + } +} +function _bindContextmenuEvent() { + var self = this, doc = self.edit.doc; + K(doc).contextmenu(function(e) { + if (self.menu) { + self.hideMenu(); + } + if (!self.useContextmenu) { + e.preventDefault(); + return; + } + if (self._contextmenus.length === 0) { + return; + } + var maxWidth = 0, items = []; + _each(self._contextmenus, function() { + if (this.title == '-') { + items.push(this); + return; + } + if (this.cond && this.cond()) { + items.push(this); + if (this.width && this.width > maxWidth) { + maxWidth = this.width; + } + } + }); + while (items.length > 0 && items[0].title == '-') { + items.shift(); + } + while (items.length > 0 && items[items.length - 1].title == '-') { + items.pop(); + } + var prevItem = null; + _each(items, function(i) { + if (this.title == '-' && prevItem.title == '-') { + delete items[i]; + } + prevItem = this; + }); + if (items.length > 0) { + e.preventDefault(); + var pos = K(self.edit.iframe).pos(), + menu = _menu({ + x : pos.x + e.clientX, + y : pos.y + e.clientY, + width : maxWidth, + css : { visibility: 'hidden' }, + shadowMode : self.shadowMode + }); + _each(items, function() { + if (this.title) { + menu.addItem(this); + } + }); + var docEl = _docElement(menu.doc), + menuHeight = menu.div.height(); + if (e.clientY + menuHeight >= docEl.clientHeight - 100) { + menu.pos(menu.x, _removeUnit(menu.y) - menuHeight); + } + menu.div.css('visibility', 'visible'); + self.menu = menu; + } + }); +} +function _bindNewlineEvent() { + var self = this, doc = self.edit.doc, newlineTag = self.newlineTag; + if (_IE && newlineTag !== 'br') { + return; + } + if (_GECKO && _V < 3 && newlineTag !== 'p') { + return; + } + if (_OPERA && _V < 9) { + return; + } + var brSkipTagMap = _toMap('h1,h2,h3,h4,h5,h6,pre,li'), + pSkipTagMap = _toMap('p,h1,h2,h3,h4,h5,h6,pre,li,blockquote'); + function getAncestorTagName(range) { + var ancestor = K(range.commonAncestor()); + while (ancestor) { + if (ancestor.type == 1 && !ancestor.isStyle()) { + break; + } + ancestor = ancestor.parent(); + } + return ancestor.name; + } + K(doc).keydown(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (newlineTag === 'br' && !brSkipTagMap[tagName]) { + e.preventDefault(); + self.insertHtml('<br />' + (_IE && _V < 9 ? '' : '\u200B')); + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '<p>'); + } + }); + K(doc).keyup(function(e) { + if (e.which != 13 || e.shiftKey || e.ctrlKey || e.altKey) { + return; + } + if (newlineTag == 'br') { + return; + } + if (_GECKO) { + var root = self.cmd.commonAncestor('p'); + var a = self.cmd.commonAncestor('a'); + if (a && a.text() == '') { + a.remove(true); + self.cmd.range.selectNodeContents(root[0]).collapse(true); + self.cmd.select(); + } + return; + } + self.cmd.selection(); + var tagName = getAncestorTagName(self.cmd.range); + if (tagName == 'marquee' || tagName == 'select') { + return; + } + if (!pSkipTagMap[tagName]) { + _nativeCommand(doc, 'formatblock', '<p>'); + } + var div = self.cmd.commonAncestor('div'); + if (div) { + var p = K('<p></p>'), + child = div[0].firstChild; + while (child) { + var next = child.nextSibling; + p.append(child); + child = next; + } + div.before(p); + div.remove(); + self.cmd.range.selectNodeContents(p[0]); + self.cmd.select(); + } + }); +} +function _bindTabEvent() { + var self = this, doc = self.edit.doc; + K(doc).keydown(function(e) { + if (e.which == 9) { + e.preventDefault(); + if (self.afterTab) { + self.afterTab.call(self, e); + return; + } + var cmd = self.cmd, range = cmd.range; + range.shrink(); + if (range.collapsed && range.startContainer.nodeType == 1) { + range.insertNode(K('@&nbsp;', doc)[0]); + cmd.select(); + } + self.insertHtml('&nbsp;&nbsp;&nbsp;&nbsp;'); + } + }); +} +function _bindFocusEvent() { + var self = this; + K(self.edit.textarea[0], self.edit.win).focus(function(e) { + if (self.afterFocus) { + self.afterFocus.call(self, e); + } + }).blur(function(e) { + if (self.afterBlur) { + self.afterBlur.call(self, e); + } + }); +} +function _removeBookmarkTag(html) { + return _trim(html.replace(/<span [^>]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/ig, '')); +} +function _removeTempTag(html) { + return html.replace(/<div[^>]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/ig, ''); +} +function _addBookmarkToStack(stack, bookmark) { + if (stack.length === 0) { + stack.push(bookmark); + return; + } + var prev = stack[stack.length - 1]; + if (_removeBookmarkTag(bookmark.html) !== _removeBookmarkTag(prev.html)) { + stack.push(bookmark); + } +} + + + +function _undoToRedo(fromStack, toStack) { + var self = this, edit = self.edit, + body = edit.doc.body, + range, bookmark; + if (fromStack.length === 0) { + return self; + } + if (edit.designMode) { + range = self.cmd.range; + bookmark = range.createBookmark(true); + bookmark.html = body.innerHTML; + } else { + bookmark = { + html : body.innerHTML + }; + } + _addBookmarkToStack(toStack, bookmark); + var prev = fromStack.pop(); + if (_removeBookmarkTag(bookmark.html) === _removeBookmarkTag(prev.html) && fromStack.length > 0) { + prev = fromStack.pop(); + } + if (edit.designMode) { + edit.html(prev.html); + if (prev.start) { + range.moveToBookmark(prev); + self.select(); + } + } else { + K(body).html(_removeBookmarkTag(prev.html)); + } + return self; +} +function KEditor(options) { + var self = this; + self.options = {}; + function setOption(key, val) { + if (KEditor.prototype[key] === undefined) { + self[key] = val; + } + self.options[key] = val; + } + _each(options, function(key, val) { + setOption(key, options[key]); + }); + _each(K.options, function(key, val) { + if (self[key] === undefined) { + setOption(key, val); + } + }); + var se = K(self.srcElement || '<textarea/>'); + if (!self.width) { + self.width = se[0].style.width || se.width(); + } + if (!self.height) { + self.height = se[0].style.height || se.height(); + } + setOption('width', _undef(self.width, self.minWidth)); + setOption('height', _undef(self.height, self.minHeight)); + setOption('width', _addUnit(self.width)); + setOption('height', _addUnit(self.height)); + if (_MOBILE && (!_IOS || _V < 534)) { + self.designMode = false; + } + self.srcElement = se; + self.initContent = ''; + self.plugin = {}; + self.isCreated = false; + self._handlers = {}; + self._contextmenus = []; + self._undoStack = []; + self._redoStack = []; + self._firstAddBookmark = true; + self.menu = self.contextmenu = null; + self.dialogs = []; +} +KEditor.prototype = { + lang : function(mixed) { + return _lang(mixed, this.langType); + }, + loadPlugin : function(name, fn) { + var self = this; + var _pluginStatus = this._pluginStatus; + if (!_pluginStatus) { + _pluginStatus = this._pluginStatus = {}; + } + if (_plugins[name]) { + if (!_isFunction(_plugins[name])) { + setTimeout(function() { + self.loadPlugin(name, fn); + }, 100); + return self; + } + if(!_pluginStatus[name]) { + _plugins[name].call(self, KindEditor); + _pluginStatus[name] = 'inited'; + } + if (fn) { + fn.call(self); + } + return self; + } + _plugins[name] = 'loading'; + _loadScript(self.pluginsPath + name + '/' + name + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() { + setTimeout(function() { + if (_plugins[name]) { + self.loadPlugin(name, fn); + } + }, 0); + }); + return self; + }, + handler : function(key, fn) { + var self = this; + if (!self._handlers[key]) { + self._handlers[key] = []; + } + if (_isFunction(fn)) { + self._handlers[key].push(fn); + return self; + } + _each(self._handlers[key], function() { + fn = this.call(self, fn); + }); + return fn; + }, + clickToolbar : function(name, fn) { + var self = this, key = 'clickToolbar' + name; + if (fn === undefined) { + if (self._handlers[key]) { + return self.handler(key); + } + self.loadPlugin(name, function() { + self.handler(key); + }); + return self; + } + return self.handler(key, fn); + }, + updateState : function() { + var self = this; + _each(('justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,' + + 'subscript,superscript,bold,italic,underline,strikethrough').split(','), function(i, name) { + self.cmd.state(name) ? self.toolbar.select(name) : self.toolbar.unselect(name); + }); + return self; + }, + addContextmenu : function(item) { + this._contextmenus.push(item); + return this; + }, + afterCreate : function(fn) { + return this.handler('afterCreate', fn); + }, + beforeRemove : function(fn) { + return this.handler('beforeRemove', fn); + }, + beforeGetHtml : function(fn) { + return this.handler('beforeGetHtml', fn); + }, + beforeSetHtml : function(fn) { + return this.handler('beforeSetHtml', fn); + }, + afterSetHtml : function(fn) { + return this.handler('afterSetHtml', fn); + }, + create : function() { + var self = this, fullscreenMode = self.fullscreenMode; + if (self.isCreated) { + return self; + } + if (self.srcElement.data('kindeditor')) { + return self; + } + self.srcElement.data('kindeditor', 'true'); + if (fullscreenMode) { + _docElement().style.overflow = 'hidden'; + } else { + _docElement().style.overflow = ''; + } + var width = fullscreenMode ? _docElement().clientWidth + 'px' : self.width, + height = fullscreenMode ? _docElement().clientHeight + 'px' : self.height; + if ((_IE && _V < 8) || _QUIRKS) { + height = _addUnit(_removeUnit(height) + 2); + } + var container = self.container = K(self.layout); + if (fullscreenMode) { + K(document.body).append(container); + } else { + self.srcElement.before(container); + } + var toolbarDiv = K('.toolbar', container), + editDiv = K('.edit', container), + statusbar = self.statusbar = K('.statusbar', container); + container.removeClass('container') + .addClass('ke-container ke-container-' + self.themeType).css('width', width); + if (fullscreenMode) { + container.css({ + position : 'absolute', + left : 0, + top : 0, + 'z-index' : 811211 + }); + if (!_GECKO) { + self._scrollPos = _getScrollPos(); + } + window.scrollTo(0, 0); + K(document.body).css({ + 'height' : '1px', + 'overflow' : 'hidden' + }); + K(document.body.parentNode).css('overflow', 'hidden'); + self._fullscreenExecuted = true; + } else { + if (self._fullscreenExecuted) { + K(document.body).css({ + 'height' : '', + 'overflow' : '' + }); + K(document.body.parentNode).css('overflow', ''); + } + if (self._scrollPos) { + window.scrollTo(self._scrollPos.x, self._scrollPos.y); + } + } + var htmlList = []; + K.each(self.items, function(i, name) { + if (name == '|') { + htmlList.push('<span class="ke-inline-block ke-separator"></span>'); + } else if (name == '/') { + htmlList.push('<div class="ke-hr"></div>'); + } else { + htmlList.push('<span class="ke-outline" data-name="' + name + '" title="' + self.lang(name) + '" unselectable="on">'); + htmlList.push('<span class="ke-toolbar-icon ke-toolbar-icon-url ke-icon-' + name + '" unselectable="on"></span></span>'); + } + }); + var toolbar = self.toolbar = _toolbar({ + src : toolbarDiv, + html : htmlList.join(''), + noDisableItems : self.noDisableItems, + click : function(e, name) { + e.stop(); + if (self.menu) { + var menuName = self.menu.name; + self.hideMenu(); + if (menuName === name) { + return; + } + } + self.clickToolbar(name); + } + }); + var editHeight = _removeUnit(height) - toolbar.div.height(); + var edit = self.edit = _edit({ + height : editHeight > 0 && _removeUnit(height) > self.minHeight ? editHeight : self.minHeight, + src : editDiv, + srcElement : self.srcElement, + designMode : self.designMode, + themesPath : self.themesPath, + bodyClass : self.bodyClass, + cssPath : self.cssPath, + cssData : self.cssData, + beforeGetHtml : function(html) { + html = self.beforeGetHtml(html); + html = _removeBookmarkTag(_removeTempTag(html)); + return _formatHtml(html, self.filterMode ? self.htmlTags : null, self.urlType, self.wellFormatMode, self.indentChar); + }, + beforeSetHtml : function(html) { + html = _formatHtml(html, self.filterMode ? self.htmlTags : null, '', false); + return self.beforeSetHtml(html); + }, + afterSetHtml : function() { + self.edit = edit = this; + self.afterSetHtml(); + }, + afterCreate : function() { + self.edit = edit = this; + self.cmd = edit.cmd; + self._docMousedownFn = function(e) { + if (self.menu) { + self.hideMenu(); + } + }; + K(edit.doc, document).mousedown(self._docMousedownFn); + _bindContextmenuEvent.call(self); + _bindNewlineEvent.call(self); + _bindTabEvent.call(self); + _bindFocusEvent.call(self); + edit.afterChange(function(e) { + if (!edit.designMode) { + return; + } + self.updateState(); + self.addBookmark(); + if (self.options.afterChange) { + self.options.afterChange.call(self); + } + }); + edit.textarea.keyup(function(e) { + if (!e.ctrlKey && !e.altKey && _INPUT_KEY_MAP[e.which]) { + if (self.options.afterChange) { + self.options.afterChange.call(self); + } + } + }); + if (self.readonlyMode) { + self.readonly(); + } + self.isCreated = true; + if (self.initContent === '') { + self.initContent = self.html(); + } + if (self._undoStack.length > 0) { + var prev = self._undoStack.pop(); + if (prev.start) { + self.html(prev.html); + edit.cmd.range.moveToBookmark(prev); + self.select(); + } + } + self.afterCreate(); + if (self.options.afterCreate) { + self.options.afterCreate.call(self); + } + } + }); + statusbar.removeClass('statusbar').addClass('ke-statusbar') + .append('<span class="ke-inline-block ke-statusbar-center-icon"></span>') + .append('<span class="ke-inline-block ke-statusbar-right-icon"></span>'); + if (self._fullscreenResizeHandler) { + K(window).unbind('resize', self._fullscreenResizeHandler); + self._fullscreenResizeHandler = null; + } + function initResize() { + if (statusbar.height() === 0) { + setTimeout(initResize, 100); + return; + } + self.resize(width, height, false); + } + initResize(); + if (fullscreenMode) { + self._fullscreenResizeHandler = function(e) { + if (self.isCreated) { + self.resize(_docElement().clientWidth, _docElement().clientHeight, false); + } + }; + K(window).bind('resize', self._fullscreenResizeHandler); + toolbar.select('fullscreen'); + statusbar.first().css('visibility', 'hidden'); + statusbar.last().css('visibility', 'hidden'); + } else { + if (_GECKO) { + K(window).bind('scroll', function(e) { + self._scrollPos = _getScrollPos(); + }); + } + if (self.resizeType > 0) { + _drag({ + moveEl : container, + clickEl : statusbar, + moveFn : function(x, y, width, height, diffX, diffY) { + height += diffY; + self.resize(null, height); + } + }); + } else { + statusbar.first().css('visibility', 'hidden'); + } + if (self.resizeType === 2) { + _drag({ + moveEl : container, + clickEl : statusbar.last(), + moveFn : function(x, y, width, height, diffX, diffY) { + width += diffX; + height += diffY; + self.resize(width, height); + } + }); + } else { + statusbar.last().css('visibility', 'hidden'); + } + } + return self; + }, + remove : function() { + var self = this; + if (!self.isCreated) { + return self; + } + self.beforeRemove(); + self.srcElement.data('kindeditor', ''); + if (self.menu) { + self.hideMenu(); + } + _each(self.dialogs, function() { + self.hideDialog(); + }); + K(document).unbind('mousedown', self._docMousedownFn); + self.toolbar.remove(); + self.edit.remove(); + self.statusbar.last().unbind(); + self.statusbar.unbind(); + self.container.remove(); + self.container = self.toolbar = self.edit = self.menu = null; + self.dialogs = []; + self.isCreated = false; + return self; + }, + resize : function(width, height, updateProp) { + var self = this; + updateProp = _undef(updateProp, true); + if (width) { + if (!/%/.test(width)) { + width = _removeUnit(width); + width = width < self.minWidth ? self.minWidth : width; + } + self.container.css('width', _addUnit(width)); + if (updateProp) { + self.width = _addUnit(width); + } + } + if (height) { + height = _removeUnit(height); + editHeight = _removeUnit(height) - self.toolbar.div.height() - self.statusbar.height(); + editHeight = editHeight < self.minHeight ? self.minHeight : editHeight; + self.edit.setHeight(editHeight); + if (updateProp) { + self.height = _addUnit(height); + } + } + return self; + }, + select : function() { + this.isCreated && this.cmd.select(); + return this; + }, + html : function(val) { + var self = this; + if (val === undefined) { + return self.isCreated ? self.edit.html() : _elementVal(self.srcElement); + } + self.isCreated ? self.edit.html(val) : _elementVal(self.srcElement, val); + if (self.isCreated) { + self.cmd.selection(); + } + return self; + }, + fullHtml : function() { + return this.isCreated ? this.edit.html(undefined, true) : ''; + }, + text : function(val) { + var self = this; + if (val === undefined) { + return _trim(self.html().replace(/<(?!img|embed).*?>/ig, '').replace(/&nbsp;/ig, ' ')); + } else { + return self.html(_escape(val)); + } + }, + isEmpty : function() { + return _trim(this.text().replace(/\r\n|\n|\r/, '')) === ''; + }, + isDirty : function() { + return _trim(this.initContent.replace(/\r\n|\n|\r|t/g, '')) !== _trim(this.html().replace(/\r\n|\n|\r|t/g, '')); + }, + selectedHtml : function() { + var val = this.isCreated ? this.cmd.range.html() : ''; + val = _removeBookmarkTag(_removeTempTag(val)); + return val; + }, + count : function(mode) { + var self = this; + mode = (mode || 'html').toLowerCase(); + if (mode === 'html') { + return self.html().length; + } + if (mode === 'text') { + return self.text().replace(/<(?:img|embed).*?>/ig, 'K').replace(/\r\n|\n|\r/g, '').length; + } + return 0; + }, + exec : function(key) { + key = key.toLowerCase(); + var self = this, cmd = self.cmd, + changeFlag = _inArray(key, 'selectall,copy,paste,print'.split(',')) < 0; + if (changeFlag) { + self.addBookmark(false); + } + cmd[key].apply(cmd, _toArray(arguments, 1)); + if (changeFlag) { + self.updateState(); + self.addBookmark(false); + if (self.options.afterChange) { + self.options.afterChange.call(self); + } + } + return self; + }, + insertHtml : function(val, quickMode) { + if (!this.isCreated) { + return this; + } + val = this.beforeSetHtml(val); + this.exec('inserthtml', val, quickMode); + return this; + }, + appendHtml : function(val) { + this.html(this.html() + val); + if (this.isCreated) { + var cmd = this.cmd; + cmd.range.selectNodeContents(cmd.doc.body).collapse(false); + cmd.select(); + } + return this; + }, + sync : function() { + _elementVal(this.srcElement, this.html()); + return this; + }, + focus : function() { + this.isCreated ? this.edit.focus() : this.srcElement[0].focus(); + return this; + }, + blur : function() { + this.isCreated ? this.edit.blur() : this.srcElement[0].blur(); + return this; + }, + addBookmark : function(checkSize) { + checkSize = _undef(checkSize, true); + var self = this, edit = self.edit, + body = edit.doc.body, + html = _removeTempTag(body.innerHTML), bookmark; + if (checkSize && self._undoStack.length > 0) { + var prev = self._undoStack[self._undoStack.length - 1]; + if (Math.abs(html.length - _removeBookmarkTag(prev.html).length) < self.minChangeSize) { + return self; + } + } + if (edit.designMode && !self._firstAddBookmark) { + var range = self.cmd.range; + bookmark = range.createBookmark(true); + bookmark.html = _removeTempTag(body.innerHTML); + range.moveToBookmark(bookmark); + } else { + bookmark = { + html : html + }; + } + self._firstAddBookmark = false; + _addBookmarkToStack(self._undoStack, bookmark); + return self; + }, + undo : function() { + return _undoToRedo.call(this, this._undoStack, this._redoStack); + }, + redo : function() { + return _undoToRedo.call(this, this._redoStack, this._undoStack); + }, + fullscreen : function(bool) { + this.fullscreenMode = (bool === undefined ? !this.fullscreenMode : bool); + this.addBookmark(false); + return this.remove().create(); + }, + readonly : function(isReadonly) { + isReadonly = _undef(isReadonly, true); + var self = this, edit = self.edit, doc = edit.doc; + if (self.designMode) { + self.toolbar.disableAll(isReadonly, []); + } else { + _each(self.noDisableItems, function() { + self.toolbar[isReadonly ? 'disable' : 'enable'](this); + }); + } + if (_IE) { + doc.body.contentEditable = !isReadonly; + } else { + doc.designMode = isReadonly ? 'off' : 'on'; + } + edit.textarea[0].disabled = isReadonly; + }, + createMenu : function(options) { + var self = this, + name = options.name, + knode = self.toolbar.get(name), + pos = knode.pos(); + options.x = pos.x; + options.y = pos.y + knode.height(); + options.z = self.options.zIndex; + options.shadowMode = _undef(options.shadowMode, self.shadowMode); + if (options.selectedColor !== undefined) { + options.cls = 'ke-colorpicker-' + self.themeType; + options.noColor = self.lang('noColor'); + self.menu = _colorpicker(options); + } else { + options.cls = 'ke-menu-' + self.themeType; + options.centerLineMode = false; + self.menu = _menu(options); + } + return self.menu; + }, + hideMenu : function() { + this.menu.remove(); + this.menu = null; + return this; + }, + hideContextmenu : function() { + this.contextmenu.remove(); + this.contextmenu = null; + return this; + }, + createDialog : function(options) { + var self = this, name = options.name; + options.z = self.options.zIndex; + options.shadowMode = _undef(options.shadowMode, self.shadowMode); + options.closeBtn = _undef(options.closeBtn, { + name : self.lang('close'), + click : function(e) { + self.hideDialog(); + if (_IE && self.cmd) { + self.cmd.select(); + } + } + }); + options.noBtn = _undef(options.noBtn, { + name : self.lang(options.yesBtn ? 'no' : 'close'), + click : function(e) { + self.hideDialog(); + if (_IE && self.cmd) { + self.cmd.select(); + } + } + }); + if (self.dialogAlignType != 'page') { + options.alignEl = self.container; + } + options.cls = 'ke-dialog-' + self.themeType; + if (self.dialogs.length > 0) { + var firstDialog = self.dialogs[0], + parentDialog = self.dialogs[self.dialogs.length - 1]; + firstDialog.setMaskIndex(parentDialog.z + 2); + options.z = parentDialog.z + 3; + options.showMask = false; + } + var dialog = _dialog(options); + self.dialogs.push(dialog); + return dialog; + }, + hideDialog : function() { + var self = this; + if (self.dialogs.length > 0) { + self.dialogs.pop().remove(); + } + if (self.dialogs.length > 0) { + var firstDialog = self.dialogs[0], + parentDialog = self.dialogs[self.dialogs.length - 1]; + firstDialog.setMaskIndex(parentDialog.z - 1); + } + return self; + }, + errorDialog : function(html) { + var self = this; + var dialog = self.createDialog({ + width : 750, + title : self.lang('uploadError'), + body : '<div style="padding:10px 20px;"><iframe frameborder="0" style="width:708px;height:400px;"></iframe></div>' + }); + var iframe = K('iframe', dialog.div), doc = K.iframeDoc(iframe); + doc.open(); + doc.write(html); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + return self; + } +}; +function _editor(options) { + return new KEditor(options); +} +_instances = []; +function _create(expr, options) { + options = options || {}; + options.basePath = _undef(options.basePath, K.basePath); + options.themesPath = _undef(options.themesPath, options.basePath + 'themes/'); + options.langPath = _undef(options.langPath, options.basePath + 'lang/'); + options.pluginsPath = _undef(options.pluginsPath, options.basePath + 'plugins/'); + if (_undef(options.loadStyleMode, K.options.loadStyleMode)) { + var themeType = _undef(options.themeType, K.options.themeType); + _loadStyle(options.themesPath + 'default/default.css'); + _loadStyle(options.themesPath + themeType + '/' + themeType + '.css'); + } + function create(editor) { + _each(_plugins, function(name, fn) { + if (_isFunction(fn)) { + fn.call(editor, KindEditor); + if (!editor._pluginStatus) { + editor._pluginStatus = {}; + } + editor._pluginStatus[name] = 'inited'; + } + }); + return editor.create(); + } + var knode = K(expr); + if (!knode || knode.length === 0) { + return; + } + if (knode.length > 1) { + knode.each(function() { + _create(this, options); + }); + return _instances[0]; + } + options.srcElement = knode[0]; + var editor = new KEditor(options); + _instances.push(editor); + if (_language[editor.langType]) { + return create(editor); + } + _loadScript(editor.langPath + editor.langType + '.js?ver=' + encodeURIComponent(K.DEBUG ? _TIME : _VERSION), function() { + create(editor); + }); + return editor; +} +function _eachEditor(expr, fn) { + K(expr).each(function(i, el) { + K.each(_instances, function(j, editor) { + if (editor && editor.srcElement[0] == el) { + fn.call(editor, j); + return false; + } + }); + }); +} +K.remove = function(expr) { + _eachEditor(expr, function(i) { + this.remove(); + _instances.splice(i, 1); + }); +}; +K.sync = function(expr) { + _eachEditor(expr, function() { + this.sync(); + }); +}; +K.html = function(expr, val) { + _eachEditor(expr, function() { + this.html(val); + }); +}; +K.insertHtml = function(expr, val) { + _eachEditor(expr, function() { + this.insertHtml(val); + }); +}; +K.appendHtml = function(expr, val) { + _eachEditor(expr, function() { + this.appendHtml(val); + }); +}; + + +if (_IE && _V < 7) { + _nativeCommand(document, 'BackgroundImageCache', true); +} +K.EditorClass = KEditor; +K.editor = _editor; +K.create = _create; +K.instances = _instances; +K.plugin = _plugin; +K.lang = _lang; + + +_plugin('core', function(K) { + var self = this, + shortcutKeys = { + undo : 'Z', redo : 'Y', bold : 'B', italic : 'I', underline : 'U', print : 'P', selectall : 'A' + }; + self.afterSetHtml(function() { + if (self.options.afterChange) { + self.options.afterChange.call(self); + } + }); + self.afterCreate(function() { + if (self.syncType != 'form') { + return; + } + var el = K(self.srcElement), hasForm = false; + while ((el = el.parent())) { + if (el.name == 'form') { + hasForm = true; + break; + } + } + if (hasForm) { + el.bind('submit', function(e) { + self.sync(); + K(window).bind('unload', function() { + self.edit.textarea.remove(); + }); + }); + var resetBtn = K('[type="reset"]', el); + resetBtn.click(function() { + self.html(self.initContent); + self.cmd.selection(); + }); + self.beforeRemove(function() { + el.unbind(); + resetBtn.unbind(); + }); + } + }); + self.clickToolbar('source', function() { + if (self.edit.designMode) { + self.toolbar.disableAll(true); + self.edit.design(false); + self.toolbar.select('source'); + } else { + self.toolbar.disableAll(false); + self.edit.design(true); + self.toolbar.unselect('source'); + if (_GECKO) { + setTimeout(function() { + self.cmd.selection(); + }, 0); + } else { + self.cmd.selection(); + } + } + self.designMode = self.edit.designMode; + }); + self.afterCreate(function() { + if (!self.designMode) { + self.toolbar.disableAll(true).select('source'); + } + }); + self.clickToolbar('fullscreen', function() { + self.fullscreen(); + }); + if (self.fullscreenShortcut) { + var loaded = false; + self.afterCreate(function() { + K(self.edit.doc, self.edit.textarea).keyup(function(e) { + if (e.which == 27) { + setTimeout(function() { + self.fullscreen(); + }, 0); + } + }); + if (loaded) { + if (_IE && !self.designMode) { + return; + } + self.focus(); + } + if (!loaded) { + loaded = true; + } + }); + } + _each('undo,redo'.split(','), function(i, name) { + if (shortcutKeys[name]) { + self.afterCreate(function() { + _ctrl(this.edit.doc, shortcutKeys[name], function() { + self.clickToolbar(name); + }); + }); + } + self.clickToolbar(name, function() { + self[name](); + }); + }); + self.clickToolbar('formatblock', function() { + var blocks = self.lang('formatblock.formatBlock'), + heights = { + h1 : 28, + h2 : 24, + h3 : 18, + H4 : 14, + p : 12 + }, + curVal = self.cmd.val('formatblock'), + menu = self.createMenu({ + name : 'formatblock', + width : self.langType == 'en' ? 200 : 150 + }); + _each(blocks, function(key, val) { + var style = 'font-size:' + heights[key] + 'px;'; + if (key.charAt(0) === 'h') { + style += 'font-weight:bold;'; + } + menu.addItem({ + title : '<span style="' + style + '" unselectable="on">' + val + '</span>', + height : heights[key] + 12, + checked : (curVal === key || curVal === val), + click : function() { + self.select().exec('formatblock', '<' + key + '>').hideMenu(); + } + }); + }); + }); + self.clickToolbar('fontname', function() { + var curVal = self.cmd.val('fontname'), + menu = self.createMenu({ + name : 'fontname', + width : 150 + }); + _each(self.lang('fontname.fontName'), function(key, val) { + menu.addItem({ + title : '<span style="font-family: ' + key + ';" unselectable="on">' + val + '</span>', + checked : (curVal === key.toLowerCase() || curVal === val.toLowerCase()), + click : function() { + self.exec('fontname', key).hideMenu(); + } + }); + }); + }); + self.clickToolbar('fontsize', function() { + var curVal = self.cmd.val('fontsize'), + menu = self.createMenu({ + name : 'fontsize', + width : 150 + }); + _each(self.fontSizeTable, function(i, val) { + menu.addItem({ + title : '<span style="font-size:' + val + ';" unselectable="on">' + val + '</span>', + height : _removeUnit(val) + 12, + checked : curVal === val, + click : function() { + self.exec('fontsize', val).hideMenu(); + } + }); + }); + }); + _each('forecolor,hilitecolor'.split(','), function(i, name) { + self.clickToolbar(name, function() { + self.createMenu({ + name : name, + selectedColor : self.cmd.val(name) || 'default', + colors : self.colorTable, + click : function(color) { + self.exec(name, color).hideMenu(); + } + }); + }); + }); + _each(('cut,copy,paste').split(','), function(i, name) { + self.clickToolbar(name, function() { + self.focus(); + try { + self.exec(name, null); + } catch(e) { + alert(self.lang(name + 'Error')); + } + }); + }); + self.clickToolbar('about', function() { + var html = '<div style="margin:20px;">' + + '<div>KindEditor ' + _VERSION + '</div>' + + '<div>Copyright &copy; <a href="http://www.kindsoft.net/" target="_blank">kindsoft.net</a> All rights reserved.</div>' + + '</div>'; + self.createDialog({ + name : 'about', + width : 350, + title : self.lang('about'), + body : html + }); + }); + self.plugin.getSelectedLink = function() { + return self.cmd.commonAncestor('a'); + }; + self.plugin.getSelectedImage = function() { + return _getImageFromRange(self.edit.cmd.range, function(img) { + return !/^ke-\w+$/i.test(img[0].className); + }); + }; + self.plugin.getSelectedFlash = function() { + return _getImageFromRange(self.edit.cmd.range, function(img) { + return img[0].className == 'ke-flash'; + }); + }; + self.plugin.getSelectedMedia = function() { + return _getImageFromRange(self.edit.cmd.range, function(img) { + return img[0].className == 'ke-media' || img[0].className == 'ke-rm'; + }); + }; + self.plugin.getSelectedAnchor = function() { + return _getImageFromRange(self.edit.cmd.range, function(img) { + return img[0].className == 'ke-anchor'; + }); + }; + _each('link,image,flash,media,anchor'.split(','), function(i, name) { + var uName = name.charAt(0).toUpperCase() + name.substr(1); + _each('edit,delete'.split(','), function(j, val) { + self.addContextmenu({ + title : self.lang(val + uName), + click : function() { + self.loadPlugin(name, function() { + self.plugin[name][val](); + self.hideMenu(); + }); + }, + cond : self.plugin['getSelected' + uName], + width : 150, + iconClass : val == 'edit' ? 'ke-icon-' + name : undefined + }); + }); + self.addContextmenu({ title : '-' }); + }); + self.plugin.getSelectedTable = function() { + return self.cmd.commonAncestor('table'); + }; + self.plugin.getSelectedRow = function() { + return self.cmd.commonAncestor('tr'); + }; + self.plugin.getSelectedCell = function() { + return self.cmd.commonAncestor('td'); + }; + _each(('prop,cellprop,colinsertleft,colinsertright,rowinsertabove,rowinsertbelow,rowmerge,colmerge,' + + 'rowsplit,colsplit,coldelete,rowdelete,insert,delete').split(','), function(i, val) { + var cond = _inArray(val, ['prop', 'delete']) < 0 ? self.plugin.getSelectedCell : self.plugin.getSelectedTable; + self.addContextmenu({ + title : self.lang('table' + val), + click : function() { + self.loadPlugin('table', function() { + self.plugin.table[val](); + self.hideMenu(); + }); + }, + cond : cond, + width : 170, + iconClass : 'ke-icon-table' + val + }); + }); + self.addContextmenu({ title : '-' }); + _each(('selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,' + + 'insertunorderedlist,indent,outdent,subscript,superscript,hr,print,' + + 'bold,italic,underline,strikethrough,removeformat,unlink').split(','), function(i, name) { + if (shortcutKeys[name]) { + self.afterCreate(function() { + _ctrl(this.edit.doc, shortcutKeys[name], function() { + self.cmd.selection(); + self.clickToolbar(name); + }); + }); + } + self.clickToolbar(name, function() { + self.focus().exec(name, null); + }); + }); + self.afterCreate(function() { + var doc = self.edit.doc, cmd, bookmark, div, + cls = '__kindeditor_paste__', pasting = false; + function movePastedData() { + cmd.range.moveToBookmark(bookmark); + cmd.select(); + if (_WEBKIT) { + K('div.' + cls, div).each(function() { + K(this).after('<br />').remove(true); + }); + K('span.Apple-style-span', div).remove(true); + K('span.Apple-tab-span', div).remove(true); + K('span[style]', div).each(function() { + if (K(this).css('white-space') == 'nowrap') { + K(this).remove(true); + } + }); + K('meta', div).remove(); + } + var html = div[0].innerHTML; + div.remove(); + if (html === '') { + return; + } + if (_WEBKIT) { + html = html.replace(/(<br>)\1/ig, '$1'); + } + if (self.pasteType === 2) { + html = html.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/ig, ''); + if (/schemas-microsoft-com|worddocument|mso-\w+/i.test(html)) { + html = _clearMsWord(html, self.filterMode ? self.htmlTags : K.options.htmlTags); + } else { + html = _formatHtml(html, self.filterMode ? self.htmlTags : null); + html = self.beforeSetHtml(html); + } + } + if (self.pasteType === 1) { + html = html.replace(/&nbsp;/ig, ' '); + html = html.replace(/\n\s*\n/g, '\n'); + html = html.replace(/<br[^>]*>/ig, '\n'); + html = html.replace(/<\/p><p[^>]*>/ig, '\n'); + html = html.replace(/<[^>]+>/g, ''); + html = html.replace(/ {2}/g, ' &nbsp;'); + if (self.newlineTag == 'p') { + if (/\n/.test(html)) { + html = html.replace(/^/, '<p>').replace(/$/, '<br /></p>').replace(/\n/g, '<br /></p><p>'); + } + } else { + html = html.replace(/\n/g, '<br />$&'); + } + } + self.insertHtml(html, true); + } + K(doc.body).bind('paste', function(e){ + if (self.pasteType === 0) { + e.stop(); + return; + } + if (pasting) { + return; + } + pasting = true; + K('div.' + cls, doc).remove(); + cmd = self.cmd.selection(); + bookmark = cmd.range.createBookmark(); + div = K('<div class="' + cls + '"></div>', doc).css({ + position : 'absolute', + width : '1px', + height : '1px', + overflow : 'hidden', + left : '-1981px', + top : K(bookmark.start).pos().y + 'px', + 'white-space' : 'nowrap' + }); + K(doc.body).append(div); + if (_IE) { + var rng = cmd.range.get(true); + rng.moveToElementText(div[0]); + rng.select(); + rng.execCommand('paste'); + e.preventDefault(); + } else { + cmd.range.selectNodeContents(div[0]); + cmd.select(); + div[0].tabIndex = -1; + div[0].focus(); + } + setTimeout(function() { + movePastedData(); + pasting = false; + }, 0); + }); + }); + self.beforeGetHtml(function(html) { + if (_IE && _V <= 8) { + html = html.replace(/<div\s+[^>]*data-ke-input-tag="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, tag) { + return unescape(tag); + }); + html = html.replace(/(<input)((?:\s+[^>]*)?>)/ig, function($0, $1, $2) { + if (!/\s+type="[^"]+"/i.test($0)) { + return $1 + ' type="text"' + $2; + } + return $0; + }); + } + return html.replace(/(<(?:noscript|noscript\s[^>]*)>)([\s\S]*?)(<\/noscript>)/ig, function($0, $1, $2, $3) { + return $1 + _unescape($2).replace(/\s+/g, ' ') + $3; + }) + .replace(/<img[^>]*class="?ke-(flash|rm|media)"?[^>]*>/ig, function(full) { + var imgAttrs = _getAttrList(full); + var styles = _getCssList(imgAttrs.style || ''); + var attrs = _mediaAttrs(imgAttrs['data-ke-tag']); + var width = _undef(styles.width, ''); + var height = _undef(styles.height, ''); + if (/px/i.test(width)) { + width = _removeUnit(width); + } + if (/px/i.test(height)) { + height = _removeUnit(height); + } + attrs.width = _undef(imgAttrs.width, width); + attrs.height = _undef(imgAttrs.height, height); + return _mediaEmbed(attrs); + }) + .replace(/<img[^>]*class="?ke-anchor"?[^>]*>/ig, function(full) { + var imgAttrs = _getAttrList(full); + return '<a name="' + unescape(imgAttrs['data-ke-name']) + '"></a>'; + }) + .replace(/<div\s+[^>]*data-ke-script-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) { + return '<script' + unescape(attr) + '>' + unescape(code) + '</script>'; + }) + .replace(/<div\s+[^>]*data-ke-noscript-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/ig, function(full, attr, code) { + return '<noscript' + unescape(attr) + '>' + unescape(code) + '</noscript>'; + }) + .replace(/(<[^>]*)data-ke-src="([^"]*)"([^>]*>)/ig, function(full, start, src, end) { + full = full.replace(/(\s+(?:href|src)=")[^"]*(")/i, function($0, $1, $2) { + return $1 + _unescape(src) + $2; + }); + full = full.replace(/\s+data-ke-src="[^"]*"/i, ''); + return full; + }) + .replace(/(<[^>]+\s)data-ke-(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) { + return start + end; + }); + }); + self.beforeSetHtml(function(html) { + if (_IE && _V <= 8) { + html = html.replace(/<input[^>]*>|<(select|button)[^>]*>[\s\S]*?<\/\1>/ig, function(full) { + var attrs = _getAttrList(full); + var styles = _getCssList(attrs.style || ''); + if (styles.display == 'none') { + return '<div class="ke-display-none" data-ke-input-tag="' + escape(full) + '"></div>'; + } + return full; + }); + } + return html.replace(/<embed[^>]*type="([^"]+)"[^>]*>(?:<\/embed>)?/ig, function(full) { + var attrs = _getAttrList(full); + attrs.src = _undef(attrs.src, ''); + attrs.width = _undef(attrs.width, 0); + attrs.height = _undef(attrs.height, 0); + return _mediaImg(self.themesPath + 'common/blank.gif', attrs); + }) + .replace(/<a[^>]*name="([^"]+)"[^>]*>(?:<\/a>)?/ig, function(full) { + var attrs = _getAttrList(full); + if (attrs.href !== undefined) { + return full; + } + return '<img class="ke-anchor" src="' + self.themesPath + 'common/anchor.gif" data-ke-name="' + escape(attrs.name) + '" />'; + }) + .replace(/<script([^>]*)>([\s\S]*?)<\/script>/ig, function(full, attr, code) { + return '<div class="ke-script" data-ke-script-attr="' + escape(attr) + '">' + escape(code) + '</div>'; + }) + .replace(/<noscript([^>]*)>([\s\S]*?)<\/noscript>/ig, function(full, attr, code) { + return '<div class="ke-noscript" data-ke-noscript-attr="' + escape(attr) + '">' + escape(code) + '</div>'; + }) + .replace(/(<[^>]*)(href|src)="([^"]*)"([^>]*>)/ig, function(full, start, key, src, end) { + if (full.match(/\sdata-ke-src="[^"]*"/i)) { + return full; + } + full = start + key + '="' + src + '"' + ' data-ke-src="' + _escape(src) + '"' + end; + return full; + }) + .replace(/(<[^>]+\s)(on\w+="[^"]*"[^>]*>)/ig, function(full, start, end) { + return start + 'data-ke-' + end; + }) + .replace(/<table[^>]*\s+border="0"[^>]*>/ig, function(full) { + if (full.indexOf('ke-zeroborder') >= 0) { + return full; + } + return _addClassToTag(full, 'ke-zeroborder'); + }); + }); +}); + + +})(window); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.lang({ + source : 'HTML代码', + preview : '预览', + undo : '后退(Ctrl+Z)', + redo : '前进(Ctrl+Y)', + cut : '剪切(Ctrl+X)', + copy : '复制(Ctrl+C)', + paste : '粘贴(Ctrl+V)', + plainpaste : '粘贴为无格式文本', + wordpaste : '从Word粘贴', + selectall : '全选(Ctrl+A)', + justifyleft : '左对齐', + justifycenter : '居中', + justifyright : '右对齐', + justifyfull : '两端对齐', + insertorderedlist : '编号', + insertunorderedlist : '项目符号', + indent : '增加缩进', + outdent : '减少缩进', + subscript : '下标', + superscript : '上标', + formatblock : '段落', + fontname : '字体', + fontsize : '文字大小', + forecolor : '文字颜色', + hilitecolor : '文字背景', + bold : '粗体(Ctrl+B)', + italic : '斜体(Ctrl+I)', + underline : '下划线(Ctrl+U)', + strikethrough : '删除线', + removeformat : '删除格式', + image : '图片', + multiimage : '批量图片上传', + flash : 'Flash', + media : '视音频', + table : '表格', + tablecell : '单元格', + hr : '插入横线', + emoticons : '插入表情', + link : '超级链接', + unlink : '取消超级链接', + fullscreen : '全屏显示', + about : '关于', + print : '打印(Ctrl+P)', + filemanager : '文件空间', + code : '插入程序代码', + map : 'Google地图', + baidumap : '百度地图', + lineheight : '行距', + clearhtml : '清理HTML代码', + pagebreak : '插入分页符', + quickformat : '一键排版', + insertfile : '插入文件', + template : '插入模板', + anchor : '锚点', + yes : '确定', + no : '取消', + close : '关闭', + editImage : '图片属性', + deleteImage : '删除图片', + editFlash : 'Flash属性', + deleteFlash : '删除Flash', + editMedia : '视音频属性', + deleteMedia : '删除视音频', + editLink : '超级链接属性', + deleteLink : '取消超级链接', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格属性', + tablecellprop : '单元格属性', + tableinsert : '插入表格', + tabledelete : '删除表格', + tablecolinsertleft : '左侧插入列', + tablecolinsertright : '右侧插入列', + tablerowinsertabove : '上方插入行', + tablerowinsertbelow : '下方插入行', + tablerowmerge : '向下合并单元格', + tablecolmerge : '向右合并单元格', + tablerowsplit : '拆分行', + tablecolsplit : '拆分列', + tablecoldelete : '删除列', + tablerowdelete : '删除行', + noColor : '无颜色', + pleaseSelectFile : '请选择文件。', + invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。", + invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "宽度必须为数字。", + invalidHeight : "高度必须为数字。", + invalidBorder : "边框必须为数字。", + invalidUrl : "请输入有效的URL地址。", + invalidRows : '行数为必选项,只允许输入大于0的数字。', + invalidCols : '列数为必选项,只允许输入大于0的数字。', + invalidPadding : '边距必须为数字。', + invalidSpacing : '间距必须为数字。', + invalidJson : '服务器发生故障。', + uploadSuccess : '上传成功。', + cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。', + copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。', + pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。', + ajaxLoading : '加载中,请稍候 ...', + uploadLoading : '上传中,请稍候 ...', + uploadError : '上传错误', + 'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'code.pleaseInput' : '请输入程序代码。', + 'link.url' : 'URL', + 'link.linkType' : '打开类型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '当前窗口', + 'flash.url' : 'URL', + 'flash.width' : '宽度', + 'flash.height' : '高度', + 'flash.upload' : '上传', + 'flash.viewServer' : '文件空间', + 'media.url' : 'URL', + 'media.width' : '宽度', + 'media.height' : '高度', + 'media.autostart' : '自动播放', + 'media.upload' : '上传', + 'media.viewServer' : '文件空间', + 'image.remoteImage' : '网络图片', + 'image.localImage' : '本地上传', + 'image.remoteUrl' : '图片地址', + 'image.localUrl' : '上传文件', + 'image.size' : '图片大小', + 'image.width' : '宽', + 'image.height' : '高', + 'image.resetSize' : '重置大小', + 'image.align' : '对齐方式', + 'image.defaultAlign' : '默认方式', + 'image.leftAlign' : '左对齐', + 'image.rightAlign' : '右对齐', + 'image.imgTitle' : '图片说明', + 'image.upload' : '浏览...', + 'image.viewServer' : '图片空间', + 'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>', + 'multiimage.startUpload' : '开始上传', + 'multiimage.clearAll' : '全部清空', + 'multiimage.insertAll' : '全部插入', + 'multiimage.queueLimitExceeded' : '文件数量超过限制。', + 'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。', + 'multiimage.zeroByteFile' : '无法上传空文件。', + 'multiimage.invalidFiletype' : '文件类型不正确。', + 'multiimage.unknownError' : '发生异常,无法上传。', + 'multiimage.pending' : '等待上传', + 'multiimage.uploadError' : '上传失败', + 'filemanager.emptyFolder' : '空文件夹', + 'filemanager.moveup' : '移到上一级文件夹', + 'filemanager.viewType' : '显示方式:', + 'filemanager.viewImage' : '缩略图', + 'filemanager.listImage' : '详细信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名称', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '类型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件说明', + 'insertfile.upload' : '上传', + 'insertfile.viewServer' : '文件空间', + 'table.cells' : '单元格数', + 'table.rows' : '行数', + 'table.cols' : '列数', + 'table.size' : '大小', + 'table.width' : '宽度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '边距间距', + 'table.padding' : '边距', + 'table.spacing' : '间距', + 'table.align' : '对齐方式', + 'table.textAlign' : '水平对齐', + 'table.verticalAlign' : '垂直对齐', + 'table.alignDefault' : '默认', + 'table.alignLeft' : '左对齐', + 'table.alignCenter' : '居中', + 'table.alignRight' : '右对齐', + 'table.alignTop' : '顶部', + 'table.alignMiddle' : '中部', + 'table.alignBottom' : '底部', + 'table.alignBaseline' : '基线', + 'table.border' : '边框', + 'table.borderWidth' : '边框', + 'table.borderColor' : '颜色', + 'table.backgroundColor' : '背景颜色', + 'map.address' : '地址: ', + 'map.search' : '搜索', + 'baidumap.address' : '地址: ', + 'baidumap.search' : '搜索', + 'baidumap.insertDynamicMap' : '插入动态地图', + 'anchor.name' : '锚点名称', + 'formatblock.formatBlock' : { + h1 : '标题 1', + h2 : '标题 2', + h3 : '标题 3', + h4 : '标题 4', + p : '正 文' + }, + 'fontname.fontName' : { + 'SimSun' : '宋体', + 'NSimSun' : '新宋体', + 'FangSong_GB2312' : '仿宋_GB2312', + 'KaiTi_GB2312' : '楷体_GB2312', + 'SimHei' : '黑体', + 'Microsoft YaHei' : '微软雅黑', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可选模板', + 'template.replaceContent' : '替换当前内容', + 'template.fileList' : { + '1.html' : '图片和文字', + '2.html' : '表格', + '3.html' : '项目编号' + } +}, 'zh-CN'); +KindEditor.options.langType = 'zh-CN'; +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('anchor', function(K) { + var self = this, name = 'anchor', lang = self.lang(name + '.'); + self.plugin.anchor = { + edit : function() { + var html = ['<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keName">' + lang.name + '</label>', + '<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />', + '</div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 300, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus(); + } + } + }); + var div = dialog.div, + nameBox = K('input[name="name"]', div); + var img = self.plugin.getSelectedAnchor(); + if (img) { + nameBox.val(unescape(img.attr('data-ke-name'))); + } + nameBox[0].focus(); + nameBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedAnchor().remove(); + } + }; + self.clickToolbar(name, self.plugin.anchor.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('autoheight', function(K) { + var self = this; + if (!self.autoHeightMode) { + return; + } + var minHeight; + function hideScroll() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe[0].scroll = 'no'; + body.style.overflowY = 'hidden'; + } + function resetHeight() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe.height(minHeight); + self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight)); + } + function init() { + minHeight = K.removeUnit(self.height); + self.edit.afterChange(resetHeight); + hideScroll(); + resetHeight(); + } + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); +/* +* 如何实现真正的自动高度? +* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。 +* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。 +* 由此就实现了真正的自动高度 +* 测试:chrome、firefox、IE9、IE8 +* */ + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('baidumap', function(K) { + var self = this, name = 'baidumap', lang = self.lang(name + '.'); + var mapWidth = K.undef(self.mapWidth, 558); + var mapHeight = K.undef(self.mapHeight, 360); + self.clickToolbar(name, function() { + var html = ['<div style="padding:10px 20px;">', + '<div class="ke-header">', + '<div class="ke-left">', + lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />', + '</span>', + '</div>', + '<div class="ke-right">', + '<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + '<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : mapWidth + 42, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var map = win.map; + var centerObj = map.getCenter(); + var center = centerObj.lng + ',' + centerObj.lat; + var zoom = map.getZoom(); + var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage', + '?center=' + encodeURIComponent(center), + '&zoom=' + encodeURIComponent(zoom), + '&width=' + mapWidth, + '&height=' + mapHeight, + '&markers=' + encodeURIComponent(center), + '&markerStyles=' + encodeURIComponent('l,A')].join(''); + if (checkbox[0].checked) { + self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>'); + } else { + self.exec('insertimage', url); + } + self.hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + checkbox = K('[name="insertDynamicMap"]', dialog.div), + win, doc; + var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>'); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + + +KindEditor.plugin('map', function(K) { + var self = this, name = 'map', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var html = ['<div style="padding:10px 20px;">', + '<div class="ke-dialog-row">', + lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />', + '</span>', + '</div>', + '<div class="ke-map" style="width:558px;height:360px;"></div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 600, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var geocoder = win.geocoder, + map = win.map, + center = map.getCenter().lat() + ',' + map.getCenter().lng(), + zoom = map.getZoom(), + maptype = map.getMapTypeId(), + url = 'http://maps.googleapis.com/maps/api/staticmap'; + url += '?center=' + encodeURIComponent(center); + url += '&zoom=' + encodeURIComponent(zoom); + url += '&size=558x360'; + url += '&maptype=' + encodeURIComponent(maptype); + url += '&markers=' + encodeURIComponent(center); + url += '&language=' + self.langType; + url += '&sensor=false'; + self.exec('insertimage', url).hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + win, doc; + var iframeHtml = ['<!doctype html><html><head>', + '<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />', + '<style>', + ' html { height: 100% }', + ' body { height: 100%; margin: 0; padding: 0; background-color: #FFF }', + ' #map_canvas { height: 100% }', + '</style>', + '<script src="http://maps.googleapis.com/maps/api/js?sensor=false&language=' + self.langType + '"></script>', + '<script>', + 'var map, geocoder;', + 'function initialize() {', + ' var latlng = new google.maps.LatLng(31.230393, 121.473704);', + ' var options = {', + ' zoom: 11,', + ' center: latlng,', + ' disableDefaultUI: true,', + ' panControl: true,', + ' zoomControl: true,', + ' mapTypeControl: true,', + ' scaleControl: true,', + ' streetViewControl: false,', + ' overviewMapControl: true,', + ' mapTypeId: google.maps.MapTypeId.ROADMAP', + ' };', + ' map = new google.maps.Map(document.getElementById("map_canvas"), options);', + ' geocoder = new google.maps.Geocoder();', + ' geocoder.geocode({latLng: latlng}, function(results, status) {', + ' if (status == google.maps.GeocoderStatus.OK) {', + ' if (results[3]) {', + ' parent.document.getElementById("kindeditor_plugin_map_address").value = results[3].formatted_address;', + ' }', + ' }', + ' });', + '}', + 'function search(address) {', + ' if (!map) return;', + ' geocoder.geocode({address : address}, function(results, status) {', + ' if (status == google.maps.GeocoderStatus.OK) {', + ' map.setZoom(11);', + ' map.setCenter(results[0].geometry.location);', + ' var marker = new google.maps.Marker({', + ' map: map,', + ' position: results[0].geometry.location', + ' });', + ' } else {', + ' alert("Invalid address: " + address);', + ' }', + ' });', + '}', + '</script>', + '</head>', + '<body onload="initialize();">', + '<div id="map_canvas" style="width:100%; height:100%"></div>', + '</body></html>'].join('\n'); + var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'map/map.html" style="width:558px;height:360px;"></iframe>'); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('clearhtml', function(K) { + var self = this, name = 'clearhtml'; + self.clickToolbar(name, function() { + self.focus(); + var html = self.html(); + html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, ''); + html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, ''); + html = K.formatHtml(html, { + a : ['href', 'target'], + embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'], + img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'], + table : ['border'], + 'td,th' : ['rowspan', 'colspan'], + 'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [] + }); + self.html(html); + self.cmd.selection(true); + self.addBookmark(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + + + +KindEditor.plugin('code', function(K) { + var self = this, name = 'code'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = ['<div style="padding:10px 20px;">', + '<div class="ke-dialog-row">', + '<select class="ke-code-type">', + '<option value="js">JavaScript</option>', + '<option value="html">HTML</option>', + '<option value="css">CSS</option>', + '<option value="php">PHP</option>', + '<option value="pl">Perl</option>', + '<option value="py">Python</option>', + '<option value="rb">Ruby</option>', + '<option value="java">Java</option>', + '<option value="vb">ASP/VB</option>', + '<option value="cpp">C/C++</option>', + '<option value="cs">C#</option>', + '<option value="xml">XML</option>', + '<option value="bsh">Shell</option>', + '<option value="">Other</option>', + '</select>', + '</div>', + '<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>', + '</div>'].join(''), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var type = K('.ke-code-type', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : ' lang-' + type, + html = '<pre class="prettyprint' + cls + '">\n' + K.escape(code) + '</pre> '; + if (K.trim(code) === '') { + alert(lang.pleaseInput); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('emoticons', function(K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function() { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'), + elements = [], + menu = self.createMenu({ + name : name, + beforeRemove : function() { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('<div class="ke-preview"></div>').css('right', 0); + previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />'); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function() { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function() { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function() { + K(this).removeClass('ke-on'); + }); + cell.click(function(e) { + self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus(); + e.stop(); + }); + } + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function() { + previewDiv.show('block'); + }); + K(table).mouseout(function() { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('<span class="ke-img"></span>') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + function removeEvent() { + K.each(elements, function() { + this.unbind(); + }); + } + var pageDiv; + function bindPageEvent(el, pageNum) { + el.click(function(e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + function createPageTable(currentPageNum) { + pageDiv = K('<div class="ke-page"></div>'); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('<a href="javascript:;">[' + pageNum + ']</a>'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@&nbsp;')); + } + } + createPageTable(currentPageNum); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('filemanager', function(K) { + var self = this, name = 'filemanager', + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imgPath = self.pluginsPath + name + '/images/', + lang = self.lang(name + '.'); + function makeFileTitle(filename, filesize, datetime) { + return filename + ' (' + Math.ceil(filesize / 1024) + 'KB, ' + datetime + ')'; + } + function bindTitle(el, data) { + if (data.is_dir) { + el.attr('title', data.filename); + } else { + el.attr('title', makeFileTitle(data.filename, data.filesize, data.datetime)); + } + } + self.plugin.filemanagerDialog = function(options) { + var width = K.undef(options.width, 650), + height = K.undef(options.height, 510), + dirName = K.undef(options.dirName, ''), + viewType = K.undef(options.viewType, 'VIEW').toUpperCase(), + clickFn = options.clickFn; + var html = [ + '<div style="padding:10px 20px;">', + '<div class="ke-plugin-filemanager-header">', + '<div class="ke-left">', + '<img class="ke-inline-block" name="moveupImg" src="' + imgPath + 'go-up.gif" width="16" height="16" border="0" alt="" /> ', + '<a class="ke-inline-block" name="moveupLink" href="javascript:;">' + lang.moveup + '</a>', + '</div>', + '<div class="ke-right">', + lang.viewType + ' <select class="ke-inline-block" name="viewType">', + '<option value="VIEW">' + lang.viewImage + '</option>', + '<option value="LIST">' + lang.listImage + '</option>', + '</select> ', + lang.orderType + ' <select class="ke-inline-block" name="orderType">', + '<option value="NAME">' + lang.fileName + '</option>', + '<option value="SIZE">' + lang.fileSize + '</option>', + '<option value="TYPE">' + lang.fileType + '</option>', + '</select>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + '<div class="ke-plugin-filemanager-body"></div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : width, + height : height, + title : self.lang(name), + body : html + }), + div = dialog.div, + bodyDiv = K('.ke-plugin-filemanager-body', div), + moveupImg = K('[name="moveupImg"]', div), + moveupLink = K('[name="moveupLink"]', div), + viewServerBtn = K('[name="viewServer"]', div), + viewTypeBox = K('[name="viewType"]', div), + orderTypeBox = K('[name="orderType"]', div); + function reloadPage(path, order, func) { + var param = 'path=' + path + '&order=' + order + '&dir=' + dirName; + dialog.showLoading(self.lang('ajaxLoading')); + K.ajax(K.addParam(fileManagerJson, param + '&' + new Date().getTime()), function(data) { + dialog.hideLoading(); + func(data); + }); + } + var elList = []; + function bindEvent(el, result, data, createFunc) { + var fileUrl = K.formatUrl(result.current_url + data.filename, 'absolute'), + dirPath = encodeURIComponent(result.current_dir_path + data.filename + '/'); + if (data.is_dir) { + el.click(function(e) { + reloadPage(dirPath, orderTypeBox.val(), createFunc); + }); + } else if (data.is_photo) { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } else { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } + elList.push(el); + } + function createCommon(result, createFunc) { + K.each(elList, function() { + this.unbind(); + }); + moveupLink.unbind(); + viewTypeBox.unbind(); + orderTypeBox.unbind(); + if (result.current_dir_path) { + moveupLink.click(function(e) { + reloadPage(result.moveup_dir_path, orderTypeBox.val(), createFunc); + }); + } + function changeFunc() { + if (viewTypeBox.val() == 'VIEW') { + reloadPage(result.current_dir_path, orderTypeBox.val(), createView); + } else { + reloadPage(result.current_dir_path, orderTypeBox.val(), createList); + } + } + viewTypeBox.change(changeFunc); + orderTypeBox.change(changeFunc); + bodyDiv.html(''); + } + function createList(result) { + createCommon(result, createList); + var table = document.createElement('table'); + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + bodyDiv.append(table); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], row = K(table.insertRow(i)); + row.mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + var iconUrl = imgPath + (data.is_dir ? 'folder-16.gif' : 'file-16.gif'), + img = K('<img src="' + iconUrl + '" width="16" height="16" alt="' + data.filename + '" align="absmiddle" />'), + cell0 = K(row[0].insertCell(0)).addClass('ke-cell ke-name').append(img).append(document.createTextNode(' ' + data.filename)); + if (!data.is_dir || data.has_file) { + row.css('cursor', 'pointer'); + cell0.attr('title', data.filename); + bindEvent(cell0, result, data, createList); + } else { + cell0.attr('title', lang.emptyFolder); + } + K(row[0].insertCell(1)).addClass('ke-cell ke-size').html(data.is_dir ? '-' : Math.ceil(data.filesize / 1024) + 'KB'); + K(row[0].insertCell(2)).addClass('ke-cell ke-datetime').html(data.datetime); + } + } + function createView(result) { + createCommon(result, createView); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], + div = K('<div class="ke-inline-block ke-item"></div>'); + bodyDiv.append(div); + var photoDiv = K('<div class="ke-inline-block ke-photo"></div>') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + div.append(photoDiv); + var fileUrl = result.current_url + data.filename, + iconUrl = data.is_dir ? imgPath + 'folder-64.gif' : (data.is_photo ? fileUrl : imgPath + 'file-64.gif'); + var img = K('<img src="' + iconUrl + '" width="80" height="80" alt="' + data.filename + '" />'); + if (!data.is_dir || data.has_file) { + photoDiv.css('cursor', 'pointer'); + bindTitle(photoDiv, data); + bindEvent(photoDiv, result, data, createView); + } else { + photoDiv.attr('title', lang.emptyFolder); + } + photoDiv.append(img); + div.append('<div class="ke-name" title="' + data.filename + '">' + data.filename + '</div>'); + } + } + viewTypeBox.val(viewType); + reloadPage('', orderTypeBox.val(), viewType == 'VIEW' ? createView : createList); + return dialog; + } +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('flash', function(K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit : function() { + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:60px;">' + lang.width + '</label>', + '<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" /> ', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keHeight" style="width:60px;">' + lang.height + '</label>', + '<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" /> ', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType('.swf'), + width : width, + height : height, + quality : 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + if (allowFlashUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=flash'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'flash', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedFlash().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('image', function(K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + self.plugin.imageDialog = function(options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />'); + } + var html = [ + '<div style="padding:20px;">', + '<div class="tabs"></div>', + '<div class="tab1" style="display:none;">', + '<div class="ke-dialog-row">', + '<label for="remoteUrl" style="width:60px;">' + lang.remoteUrl + '</label>', + '<input type="text" id="remoteUrl" class="ke-input-text" name="url" value="" style="width:200px;" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="remoteWidth" style="width:60px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="remoteWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> ', + '<img class="ke-refresh-btn" src="' + imgPath + 'refresh.png" width="16" height="16" alt="" style="cursor:pointer;" title="' + lang.resetSize + '" />', + '</div>', + '<div class="ke-dialog-row">', + '<label style="width:60px;">' + lang.align + '</label>', + '<input type="radio" name="align" class="ke-inline-block" value="" checked="checked" /> <img name="defaultImg" src="' + imgPath + 'align_top.gif" width="23" height="25" alt="" />', + ' <input type="radio" name="align" class="ke-inline-block" value="left" /> <img name="leftImg" src="' + imgPath + 'align_left.gif" width="23" height="25" alt="" />', + ' <input type="radio" name="align" class="ke-inline-block" value="right" /> <img name="rightImg" src="' + imgPath + 'align_right.gif" width="23" height="25" alt="" />', + '</div>', + '<div class="ke-dialog-row">', + '<label for="remoteTitle" style="width:60px;">' + lang.imgTitle + '</label>', + '<input type="text" id="remoteTitle" class="ke-input-text" name="title" value="" style="width:200px;" />', + '</div>', + '</div>', + '<div class="tab2" style="display:none;">', + '<iframe name="' + target + '" style="display:none;"></iframe>', + '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + K.addParam(uploadJson, 'dir=image') + '">', + '<div class="ke-dialog-row">', + hiddenElements.join(''), + '<label style="width:60px;">' + lang.localUrl + '</label>', + '<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" />', + '</div>', + '</form>', + '</div>', + '</div>' + ].join(''); + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 300 : 250; + var dialog = self.createDialog({ + name : name, + width : dialogWidth, + height : dialogHeight, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + if (dialog.isLoading) { + return; + } + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + alert(self.lang('pleaseSelectFile')); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function() { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove : function() { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src : K('.tabs', div), + afterSelect : function(i) {} + }); + tabs.add({ + title : lang.remoteImage, + panel : K('.tab1', div) + }); + tabs.add({ + title : lang.localImage, + panel : K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + form : K('.ke-form', div), + target : target, + width: 60, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'VIEW', + dirName : 'image', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + refreshBtn.click(function(e) { + var tempImg = K('<img src="' + urlBox.val() + '" />', document).css({ + position : 'absolute', + visibility : 'hidden', + top : 0, + left : '-1000px' + }); + tempImg.bind('load', function() { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function(e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function(e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function() { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit : function() { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl : img ? img.attr('data-ke-src') : 'http://', + imageWidth : img ? img.width() : '', + imageHeight : img ? img.height() : '', + imageTitle : img ? img.attr('title') : '', + imageAlign : img ? img.attr('align') : '', + showRemote : allowImageRemote, + showLocal : allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn : function(url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete' : function() { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('insertfile', function(K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function(options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keTitle" style="width:60px;">' + lang.title + '</label>', + '<input type="text" id="keTitle" class="ke-input-text" name="title" value="" style="width:160px;" /></div>', + '</div>', + '</form>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + if (allowFileUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + url : K.addParam(uploadJson, 'dir=file'), + extraParams : extraParams, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'file', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function() { + self.plugin.fileDialog({ + clickFn : function(url, title) { + var html = '<a class="ke-insertfile" href="' + url + '" data-ke-src="' + url + '" target="_blank">' + title + '</a>'; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('lineheight', function(K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name : name, + width : 150 + }); + K.each(lang.lineHeight, function(i, row) { + K.each(row, function(key, val) { + menu.addItem({ + title : val, + checked : curVal === key, + click : function() { + self.cmd.toggle('<span style="line-height:' + key + ';"></span>', { + span : '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('link', function(K) { + var self = this, name = 'link'; + self.plugin.link = { + edit : function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:20px;">' + + '<div class="ke-dialog-row">' + + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>' + + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:260px;" /></div>' + + '<div class="ke-dialog-row"">' + + '<label for="keType" style="width:60px;">' + lang.linkType + '</label>' + + '<select id="keType" name="type"></select>' + + '</div>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('media', function(K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.media = { + edit : function() { + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:60px;">' + lang.width + '</label>', + '<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" />', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keHeight" style="width:60px;">' + lang.height + '</label>', + '<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" />', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keAutostart">' + lang.autostart + '</label>', + '<input type="checkbox" id="keAutostart" name="autostart" value="" /> ', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + height : 230, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType(url), + width : width, + height : height, + autostart : autostartBox[0].checked ? 'true' : 'false', + loop : 'true' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + if (allowMediaUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=media'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'media', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedMedia().remove(); + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +(function(K) { +function KSWFUpload(options) { + this.init(options); +} +K.extend(KSWFUpload, { + init : function(options) { + var self = this; + options.afterError = options.afterError || function(str) { + alert(str); + }; + self.options = options; + self.progressbars = {}; + self.div = K(options.container).html([ + '<div class="ke-swfupload">', + '<div class="ke-swfupload-top">', + '<div class="ke-inline-block ke-swfupload-button">', + '<input type="button" value="Browse" />', + '</div>', + '<div class="ke-inline-block ke-swfupload-desc">' + options.uploadDesc + '</div>', + '<span class="ke-button-common ke-button-outer ke-swfupload-startupload">', + '<input type="button" class="ke-button-common ke-button" value="' + options.startButtonValue + '" />', + '</span>', + '</div>', + '<div class="ke-swfupload-body"></div>', + '</div>' + ].join('')); + self.bodyDiv = K('.ke-swfupload-body', self.div); + function showError(itemDiv, msg) { + K('.ke-status > div', itemDiv).hide(); + K('.ke-message', itemDiv).addClass('ke-error').show().html(K.escape(msg)); + } + var settings = { + debug : false, + upload_url : options.uploadUrl, + flash_url : options.flashUrl, + file_post_name : options.filePostName, + button_placeholder : K('.ke-swfupload-button > input', self.div)[0], + button_image_url: options.buttonImageUrl, + button_width: options.buttonWidth, + button_height: options.buttonHeight, + button_cursor : SWFUpload.CURSOR.HAND, + file_types : options.fileTypes, + file_types_description : options.fileTypesDesc, + file_upload_limit : options.fileUploadLimit, + file_size_limit : options.fileSizeLimit, + post_params : options.postParams, + file_queued_handler : function(file) { + file.url = self.options.fileIconUrl; + self.appendFile(file); + }, + file_queue_error_handler : function(file, errorCode, message) { + var errorName = ''; + switch (errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: + errorName = options.queueLimitExceeded; + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + errorName = options.fileExceedsSizeLimit; + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + errorName = options.zeroByteFile; + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + errorName = options.invalidFiletype; + break; + default: + errorName = options.unknownError; + break; + } + K.DEBUG && alert(errorName); + }, + upload_start_handler : function(file) { + var self = this; + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv); + K('.ke-status > div', itemDiv).hide(); + K('.ke-progressbar', itemDiv).show(); + }, + upload_progress_handler : function(file, bytesLoaded, bytesTotal) { + var percent = Math.round(bytesLoaded * 100 / bytesTotal); + var progressbar = self.progressbars[file.id]; + progressbar.bar.css('width', Math.round(percent * 80 / 100) + 'px'); + progressbar.percent.html(percent + '%'); + }, + upload_error_handler : function(file, errorCode, message) { + if (file && file.filestatus == SWFUpload.FILE_STATUS.ERROR) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + showError(itemDiv, self.options.errorMessage); + } + }, + upload_success_handler : function(file, serverData) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + var data = {}; + try { + data = K.json(serverData); + } catch (e) { + self.options.afterError.call(this, '<!doctype html><html>' + serverData + '</html>'); + } + if (data.error !== 0) { + showError(itemDiv, K.DEBUG ? data.message : self.options.errorMessage); + return; + } + file.url = data.url; + K('.ke-img', itemDiv).attr('src', file.url).attr('data-status', file.filestatus).data('data', data); + K('.ke-status > div', itemDiv).hide(); + } + }; + self.swfu = new SWFUpload(settings); + K('.ke-swfupload-startupload input', self.div).click(function() { + self.swfu.startUpload(); + }); + }, + getUrlList : function() { + var list = []; + K('.ke-img', self.bodyDiv).each(function() { + var img = K(this); + var status = img.attr('data-status'); + if (status == SWFUpload.FILE_STATUS.COMPLETE) { + list.push(img.data('data')); + } + }); + return list; + }, + removeFile : function(fileId) { + var self = this; + self.swfu.cancelUpload(fileId); + var itemDiv = K('div[data-id="' + fileId + '"]', self.bodyDiv); + K('.ke-photo', itemDiv).unbind(); + K('.ke-delete', itemDiv).unbind(); + itemDiv.remove(); + }, + removeFiles : function() { + var self = this; + K('.ke-item', self.bodyDiv).each(function() { + self.removeFile(K(this).attr('data-id')); + }); + }, + appendFile : function(file) { + var self = this; + var itemDiv = K('<div class="ke-inline-block ke-item" data-id="' + file.id + '"></div>'); + self.bodyDiv.append(itemDiv); + var photoDiv = K('<div class="ke-inline-block ke-photo"></div>') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + itemDiv.append(photoDiv); + var img = K('<img src="' + file.url + '" class="ke-img" data-status="' + file.filestatus + '" width="80" height="80" alt="' + file.name + '" />'); + photoDiv.append(img); + K('<span class="ke-delete"></span>').appendTo(photoDiv).click(function() { + self.removeFile(file.id); + }); + var statusDiv = K('<div class="ke-status"></div>').appendTo(photoDiv); + K(['<div class="ke-progressbar">', + '<div class="ke-progressbar-bar"><div class="ke-progressbar-bar-inner"></div></div>', + '<div class="ke-progressbar-percent">0%</div></div>'].join('')).hide().appendTo(statusDiv); + K('<div class="ke-message">' + self.options.pendingMessage + '</div>').appendTo(statusDiv); + itemDiv.append('<div class="ke-name">' + file.name + '</div>'); + self.progressbars[file.id] = { + bar : K('.ke-progressbar-bar-inner', photoDiv), + percent : K('.ke-progressbar-percent', photoDiv) + }; + }, + remove : function() { + this.removeFiles(); + this.swfu.destroy(); + this.div.html(''); + } +}); +K.swfupload = function(element, options) { + return new KSWFUpload(element, options); +}; +})(KindEditor); +KindEditor.plugin('multiimage', function(K) { + var self = this, name = 'multiimage', + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imgPath = self.pluginsPath + 'multiimage/images/', + imageSizeLimit = K.undef(self.imageSizeLimit, '1MB'), + imageFileTypes = K.undef(self.imageFileTypes, '*.jpg;*.gif;*.png'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.multiImageDialog = function(options) { + var clickFn = options.clickFn, + uploadDesc = K.tmpl(lang.uploadDesc, {uploadLimit : imageUploadLimit, sizeLimit : imageSizeLimit}); + var html = [ + '<div style="padding:20px;">', + '<div class="swfupload">', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 650, + height : 510, + title : self.lang(name), + body : html, + previewBtn : { + name : lang.insertAll, + click : function(e) { + clickFn.call(self, swfupload.getUrlList()); + } + }, + yesBtn : { + name : lang.clearAll, + click : function(e) { + swfupload.removeFiles(); + } + }, + beforeRemove : function() { + if (!K.IE || K.V <= 8) { + swfupload.remove(); + } + } + }), + div = dialog.div; + var swfupload = K.swfupload({ + container : K('.swfupload', div), + buttonImageUrl : imgPath + (self.langType == 'zh-CN' ? 'select-files-zh-CN.png' : 'select-files-en.png'), + buttonWidth : self.langType == 'zh-CN' ? 72 : 88, + buttonHeight : 23, + fileIconUrl : imgPath + 'image.png', + uploadDesc : uploadDesc, + startButtonValue : lang.startUpload, + uploadUrl : K.addParam(uploadJson, 'dir=image'), + flashUrl : imgPath + 'swfupload.swf', + filePostName : filePostName, + fileTypes : '*.jpg;*.jpeg;*.gif;*.png;*.bmp', + fileTypesDesc : 'Image Files', + fileUploadLimit : imageUploadLimit, + fileSizeLimit : imageSizeLimit, + postParams : K.undef(self.extraFileUploadParams, {}), + queueLimitExceeded : lang.queueLimitExceeded, + fileExceedsSizeLimit : lang.fileExceedsSizeLimit, + zeroByteFile : lang.zeroByteFile, + invalidFiletype : lang.invalidFiletype, + unknownError : lang.unknownError, + pendingMessage : lang.pending, + errorMessage : lang.uploadError, + afterError : function(html) { + self.errorDialog(html); + } + }); + return dialog; + }; + self.clickToolbar(name, function() { + self.plugin.multiImageDialog({ + clickFn : function (urlList) { + if (urlList.length === 0) { + return; + } + K.each(urlList, function(i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data.url, data, 'multiimage'); + } + self.exec('insertimage', data.url, data.title, data.width, data.height, data.border, data.align); + }); + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ +(function() { +window.SWFUpload = function (settings) { + this.initSWFUpload(settings); +}; +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; + this.settings = settings; + this.eventQueue = []; + this.movieName = "KindEditor_SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + SWFUpload.instances[this.movieName] = this; + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 2009-03-25"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + return /*currentURL +*/ path + url; +}; +/* ******************** */ +/* Instance Members */ +/* ******************** */ +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + this.ensureDefault("debug_handler", this.debugMessage); + this.ensureDefault("custom_settings", {}); + this.customSettings = this.settings.custom_settings; + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + if (!this.settings.preserve_relative_urls) { + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + delete this.ensureDefault; +}; +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent; + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } +}; +SWFUpload.prototype.getFlashHTML = function () { + var classid = ''; + if (KindEditor.IE && KindEditor.V > 8) { + classid = ' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'; + } + return ['<object id="', this.movieName, '"' + classid + ' type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">', + '<param name="wmode" value="', this.settings.button_window_mode, '" />', + '<param name="movie" value="', this.settings.flash_url, '" />', + '<param name="quality" value="high" />', + '<param name="menu" value="false" />', + '<param name="allowScriptAccess" value="always" />', + '<param name="flashvars" value="' + this.getFlashVars() + '" />', + '</object>'].join(""); +}; +SWFUpload.prototype.getFlashVars = function () { + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + return ["movieName=", encodeURIComponent(this.movieName), + "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url), + "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&amp;httpSuccess=", encodeURIComponent(httpSuccessString), + "&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&amp;params=", encodeURIComponent(paramString), + "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name), + "&amp;fileTypes=", encodeURIComponent(this.settings.file_types), + "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&amp;buttonWidth=", encodeURIComponent(this.settings.button_width), + "&amp;buttonHeight=", encodeURIComponent(this.settings.button_height), + "&amp;buttonText=", encodeURIComponent(this.settings.button_text), + "&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&amp;buttonAction=", encodeURIComponent(this.settings.button_action), + "&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + return this.movieElement; +}; +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + return paramStringPairs.join("&amp;"); +}; +SWFUpload.prototype.destroy = function () { + try { + this.cancelUpload(null, false); + var movieElement = null; + movieElement = this.getMovieElement(); + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + window[this.movieName] = null; + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + return true; + } catch (ex2) { + return false; + } +}; +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + return ""; +}; +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + var movieElement = this.getMovieElement(); + var returnValue, returnString; + try { + returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>'); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + return returnValue; +}; +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + this.callFlash("SetButtonDimensions", [width, height]); +}; +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + All these functions a Private. + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + var self = this; + if (typeof this.settings[handlerName] === "function") { + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + setTimeout(function () { + self.executeNextEvent(); + }, 0); + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; +SWFUpload.prototype.executeNextEvent = function () { + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + file.post = unescapedPost; + } + return file; +}; +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; +SWFUpload.prototype.flashReady = function () { + var movieElement = this.getMovieElement(); + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + this.cleanUp(movieElement); + this.queueEvent("swfupload_loaded_handler"); +}; +SWFUpload.prototype.cleanUp = function (movieElement) { + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + } + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + } + }; +}; +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + if (returnValue === undefined) { + returnValue = true; + } + returnValue = !!returnValue; + this.callFlash("ReturnUploadStart", [returnValue]); +}; +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + The console is automatically scrolled as messages appear. + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + try { + console = document.getElementById("SWFUpload_Console"); + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + console.value += message + "\n"; + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; +})(); +(function() { +/* + Queue Plug-in + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + */ +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + this.queueSettings = {}; + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + returnValue = (returnValue === false) ? false : true; + this.queueSettings.queue_cancelled_flag = !returnValue; + return returnValue; + }; + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + continueUpload = false; + } else { + continueUpload = true; + } + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} +})(); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('pagebreak', function(K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '<hr style="page-break-after: always;" class="ke-pagebreak" />'); + self.clickToolbar(name, function() { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : '<span id="__kindeditor_tail_tag__"></span>'; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('plainpaste', function(K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<div style="margin-bottom:10px;">' + lang.comment + '</div>' + + '<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, ' &nbsp;'); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '<p>').replace(/$/, '</p>').replace(/\n/g, '</p><p>'); + } else { + html = html.replace(/\n/g, '<br />$&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('preview', function(K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<iframe class="ke-textarea" frameborder="0" style="width:708px;height:400px;"></iframe>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 750, + title : self.lang(name), + body : html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + doc.write(self.fullHtml()); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('quickformat', function(K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + self.clickToolbar(name, function() { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while(child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s|&nbsp;| )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function(i, subList) { + var wrapper = K('<p style="text-indent:2em;"></p>', doc); + subList[0].before(wrapper); + K.each(subList, function(i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('table', function(K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + var pickerList = []; + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + function removePicker() { + K.each(pickerList, function() { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + colorBox.click(function(e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x : pos.x, + y : pos.y + box.height(), + z : 811214, + selectedColor : K(this).html(), + colors : self.colorTable, + noColor : self.lang('noColor'), + shadowMode : self.shadowMode, + click : function(color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + self.plugin.table = { + prop : function(isInsert) { + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keRows" style="width:90px;">' + lang.cells + '</label>', + lang.rows + ' <input type="text" id="keRows" class="ke-input-text ke-input-number" name="rows" value="" maxlength="4" /> &nbsp; ', + lang.cols + ' <input type="text" class="ke-input-text ke-input-number" name="cols" value="" maxlength="4" />', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:90px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ', + '<select name="widthType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select> &nbsp; ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ', + '<select name="heightType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="kePadding" style="width:90px;">' + lang.space + '</label>', + lang.padding + ' <input type="text" id="kePadding" class="ke-input-text ke-input-number" name="padding" value="" maxlength="4" /> &nbsp; ', + lang.spacing + ' <input type="text" class="ke-input-text ke-input-number" name="spacing" value="" maxlength="4" />', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keAlign" style="width:90px;">' + lang.align + '</label>', + '<select id="keAlign" name="align">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="left">' + lang.alignLeft + '</option>', + '<option value="center">' + lang.alignCenter + '</option>', + '<option value="right">' + lang.alignRight + '</option>', + '</select>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keBorder" style="width:90px;">' + lang.border + '</label>', + lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ', + lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>', + '<span class="ke-inline-block ke-input-color"></span>', + '</div>', + '</div>' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + alert(self.lang('invalidRows')); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + alert(self.lang('invalidRows')); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + alert(self.lang('invalidPadding')); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + alert(self.lang('invalidSpacing')); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '<table'; + if (style !== '') { + html += ' style="' + style + '"'; + } + if (padding !== '') { + html += ' cellpadding="' + padding + '"'; + } + if (spacing !== '') { + html += ' cellspacing="' + spacing + '"'; + } + if (align !== '') { + html += ' align="' + align + '"'; + } + if (border !== '') { + html += ' border="' + border + '"'; + } + if (border === '' || border === '0') { + html += ' class="' + zeroborder + '"'; + } + if (borderColor !== '') { + html += ' bordercolor="' + borderColor + '"'; + } + html += '>'; + for (var i = 0; i < rows; i++) { + html += '<tr>'; + for (var j = 0; j < cols; j++) { + html += '<td>' + (K.IE ? '&nbsp;' : '<br />') + '</td>'; + } + html += '</tr>'; + } + html += '</table>'; + if (!K.IE) { + html += '<br />'; + } + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + cellprop : function() { + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:90px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ', + '<select name="widthType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select> &nbsp; ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ', + '<select name="heightType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keAlign" style="width:90px;">' + lang.align + '</label>', + lang.textAlign + ' <select id="keAlign" name="textAlign">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="left">' + lang.alignLeft + '</option>', + '<option value="center">' + lang.alignCenter + '</option>', + '<option value="right">' + lang.alignRight + '</option>', + '</select> ', + lang.verticalAlign + ' <select name="verticalAlign">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="top">' + lang.alignTop + '</option>', + '<option value="middle">' + lang.alignMiddle + '</option>', + '<option value="bottom">' + lang.alignBottom + '</option>', + '<option value="baseline">' + lang.alignBaseline + '</option>', + '</select>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keBorder" style="width:90px;">' + lang.border + '</label>', + lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ', + lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>', + '</div>', + '<div class="ke-dialog-row">', + '<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>', + '<span class="ke-inline-block ke-input-color"></span>', + '</div>', + '</div>' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang('tablecell'), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + cell.css({ + width : width !== '' ? (width + widthType) : '', + height : height !== '' ? (height + heightType) : '', + 'background-color' : bgColor, + 'text-align' : textAlign, + 'vertical-align' : verticalAlign, + 'border-width' : border, + 'border-style' : border !== '' ? 'solid' : '', + 'border-color' : borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + widthBox[0].focus(); + widthBox[0].select(); + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert : function() { + this.prop(true); + }, + 'delete' : function() { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + index += table.rows[0].cells.length - row.cells.length; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '<br />'; + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft : function() { + this.colinsert(0); + }, + colinsertright : function() { + this.colinsert(1); + }, + rowinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + } + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove : function() { + this.rowinsert(0); + }, + rowinsertbelow : function() { + this.rowinsert(1); + }, + rowmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + nextRowIndex = rowIndex + cell.rowSpan, + nextRow = table.rows[nextRowIndex]; + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('template', function(K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + arr = ['<div style="padding:10px 20px;">', + '<div class="ke-header">', + '<div class="ke-left">', + lang. selectTemplate + ' <select>']; + K.each(lang.fileList, function(key, val) { + arr.push('<option value="' + key + '">' + val + '</option>'); + }); + html = [arr.join(''), + '</select></div>', + '<div class="ke-right">', + '<input type="checkbox" id="keReplaceFlag" name="replaceFlag" value="1" /> <label for="keReplaceFlag">' + lang.replaceContent + '</label>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + '<iframe class="ke-textarea" frameborder="0" style="width:458px;height:260px;background-color:#FFF;"></iframe>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function() { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); + +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ +KindEditor.plugin('wordpaste', function(K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<div style="margin-bottom:10px;">' + lang.comment + '</div>' + + '<iframe class="ke-textarea" frameborder="0" style="width:408px;height:260px;"></iframe>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('<!doctype html><html><head><title>WordPaste</title></head>'); + doc.write('<body style="background-color:#FFF;font-size:12px;margin:2px;">'); + if (!K.IE) { + doc.write('<br />'); + } + doc.write('</body></html>'); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); + + +KindEditor.plugin('fixtoolbar', function (K) { + var self = this; + if (!self.fixToolBar) { + return; + } + function init() { + var toolbar = K('.ke-toolbar'); + var originY = toolbar.pos().y; + K(window).bind('scroll', function () { + if (toolbar.css('position') == 'fixed') { + if(document.body.scrollTop - originY < 0){ + toolbar.css('position', 'static'); + toolbar.css('top', 'auto'); + } + } else { + if (toolbar.pos().y - document.body.scrollTop < 0) { + toolbar.css('position', 'fixed'); + toolbar.css('top', 0); + } + } + }); + } + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); diff --git a/static/plugins/kindeditor/kindeditor.js b/static/plugins/kindeditor/kindeditor.js new file mode 100755 index 0000000..fc5973d --- /dev/null +++ b/static/plugins/kindeditor/kindeditor.js @@ -0,0 +1,7 @@ +/* KindEditor 4.1.11 (2016-03-31), Copyright (C) kindsoft.net, Licence: http://kindeditor.net/license.php */ +!function(window,undefined){function _isArray(a){return a?"[object Array]"===Object.prototype.toString.call(a):!1}function _isFunction(a){return a?"[object Function]"===Object.prototype.toString.call(a):!1}function _inArray(a,b){for(var c=0,d=b.length;d>c;c++)if(a===b[c])return c;return-1}function _each(a,b){if(_isArray(a))for(var c=0,d=a.length;d>c&&b.call(a[c],c,a[c])!==!1;c++);else for(var e in a)if(a.hasOwnProperty(e)&&b.call(a[e],e,a[e])===!1)break}function _trim(a){return a.replace(/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g,"")}function _inString(a,b,c){return c=c===undefined?",":c,(c+b+c).indexOf(c+a+c)>=0}function _addUnit(a,b){return b=b||"px",a&&/^-?\d+(?:\.\d+)?$/.test(a)?a+b:a}function _removeUnit(a){var b;return a&&(b=/(\d+)/.exec(a))?parseInt(b[1],10):0}function _escape(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function _unescape(a){return a.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&amp;/g,"&")}function _toCamel(a){var b=a.split("-");return a="",_each(b,function(b,c){a+=b>0?c.charAt(0).toUpperCase()+c.substr(1):c}),a}function _toHex(a){function b(a){var b=parseInt(a,10).toString(16).toUpperCase();return b.length>1?b:"0"+b}return a.replace(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/gi,function(a,c,d,e){return"#"+b(c)+b(d)+b(e)})}function _toMap(a,b){b=b===undefined?",":b;var c,d={},e=_isArray(a)?a:a.split(b);return _each(e,function(a,b){if(c=/^(\d+)\.\.(\d+)$/.exec(b))for(var e=parseInt(c[1],10);e<=parseInt(c[2],10);e++)d[e.toString()]=!0;else d[b]=!0}),d}function _toArray(a,b){return Array.prototype.slice.call(a,b||0)}function _undef(a,b){return a===undefined?b:a}function _invalidUrl(a){return!a||/[<>"]/.test(a)}function _addParam(a,b){return a.indexOf("?")>=0?a+"&"+b:a+"?"+b}function _extend(a,b,c){c||(c=b,b=null);var d;if(b){var e=function(){};e.prototype=b.prototype,d=new e,_each(c,function(a,b){d[a]=b})}else d=c;d.constructor=a,a.prototype=d,a.parent=b?b.prototype:null}function _json(text){var match;(match=/\{[\s\S]*\}|\[[\s\S]*\]/.exec(text))&&(text=match[0]);var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;if(cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})),/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return eval("("+text+")");throw"JSON parse error"}function _getBasePath(){for(var a,b=document.getElementsByTagName("script"),c=0,d=b.length;d>c;c++)if(a=b[c].src||"",/kindeditor[\w\-\.]*\.js/.test(a))return a.substring(0,a.lastIndexOf("/")+1);return""}function _bindEvent(a,b,c){a.addEventListener?a.addEventListener(b,c,_useCapture):a.attachEvent&&a.attachEvent("on"+b,c)}function _unbindEvent(a,b,c){a.removeEventListener?a.removeEventListener(b,c,_useCapture):a.detachEvent&&a.detachEvent("on"+b,c)}function KEvent(a,b){this.init(a,b)}function _getId(a){return a[_eventExpendo]||null}function _setId(a){return a[_eventExpendo]=++_eventId,_eventId}function _removeId(a){try{delete a[_eventExpendo]}catch(b){a.removeAttribute&&a.removeAttribute(_eventExpendo)}}function _bind(a,b,c){if(b.indexOf(",")>=0)return void _each(b.split(","),function(){_bind(a,this,c)});var d=_getId(a);d||(d=_setId(a)),_eventData[d]===undefined&&(_eventData[d]={});var e=_eventData[d][b];e&&e.length>0?_unbindEvent(a,b,e[0]):(_eventData[d][b]=[],_eventData[d].el=a),e=_eventData[d][b],0===e.length&&(e[0]=function(b){var c=b?new KEvent(a,b):undefined;_each(e,function(b,d){b>0&&d&&d.call(a,c)})}),_inArray(c,e)<0&&e.push(c),_bindEvent(a,b,e[0])}function _unbind(a,b,c){if(b&&b.indexOf(",")>=0)return void _each(b.split(","),function(){_unbind(a,this,c)});var d=_getId(a);if(d){if(b===undefined)return void(d in _eventData&&(_each(_eventData[d],function(b,c){"el"!=b&&c.length>0&&_unbindEvent(a,b,c[0])}),delete _eventData[d],_removeId(a)));if(_eventData[d]){var e=_eventData[d][b];if(e&&e.length>0){c===undefined?(_unbindEvent(a,b,e[0]),delete _eventData[d][b]):(_each(e,function(a,b){a>0&&b===c&&e.splice(a,1)}),1==e.length&&(_unbindEvent(a,b,e[0]),delete _eventData[d][b]));var f=0;_each(_eventData[d],function(){f++}),2>f&&(delete _eventData[d],_removeId(a))}}}}function _fire(a,b){if(b.indexOf(",")>=0)return void _each(b.split(","),function(){_fire(a,this)});var c=_getId(a);if(c){var d=_eventData[c][b];_eventData[c]&&d&&d.length>0&&d[0]()}}function _ctrl(a,b,c){b=/^\d{2,}$/.test(b)?b:b.toUpperCase().charCodeAt(0),_bind(a,"keydown",function(d){!d.ctrlKey||d.which!=b||d.shiftKey||d.altKey||(c.call(a),d.stop())})}function _ready(a){function b(){e||(e=!0,a(KindEditor),_readyFinished=!0)}function c(){if(!e){try{document.documentElement.doScroll("left")}catch(a){return void setTimeout(c,100)}b()}}function d(){"complete"===document.readyState&&b()}if(_readyFinished)return void a(KindEditor);var e=!1;if(document.addEventListener)_bind(document,"DOMContentLoaded",b);else if(document.attachEvent){_bind(document,"readystatechange",d);var f=!1;try{f=null==window.frameElement}catch(g){}document.documentElement.doScroll&&f&&c()}_bind(window,"load",b)}function _getCssList(a){for(var b,c={},d=/\s*([\w\-]+)\s*:([^;]*)(;|$)/g;b=d.exec(a);){var e=_trim(b[1].toLowerCase()),f=_trim(_toHex(b[2]));c[e]=f}return c}function _getAttrList(a){for(var b,c={},d=/\s+(?:([\w\-:]+)|(?:([\w\-:]+)=([^\s"'<>]+))|(?:([\w\-:"]+)="([^"]*)")|(?:([\w\-:"]+)='([^']*)'))(?=(?:\s|\/|>)+)/g;b=d.exec(a);){var e=(b[1]||b[2]||b[4]||b[6]).toLowerCase(),f=(b[2]?b[3]:b[4]?b[5]:b[7])||"";c[e]=f}return c}function _addClassToTag(a,b){return a=/\s+class\s*=/.test(a)?a.replace(/(\s+class=["']?)([^"']*)(["']?[\s>])/,function(a,c,d,e){return(" "+d+" ").indexOf(" "+b+" ")<0?""===d?c+b+e:c+d+" "+b+e:a}):a.substr(0,a.length-1)+' class="'+b+'">'}function _formatCss(a){var b="";return _each(_getCssList(a),function(a,c){b+=a+":"+c+";"}),b}function _formatUrl(a,b,c,d){function e(a){for(var b=a.split("/"),c=[],d=0,e=b.length;e>d;d++){var f=b[d];".."==f?c.length>0&&c.pop():""!==f&&"."!=f&&c.push(f)}return"/"+c.join("/")}function f(b,c){if(a.substr(0,b.length)===b){for(var e=[],g=0;c>g;g++)e.push("..");var i=".";return e.length>0&&(i+="/"+e.join("/")),"/"==d&&(i+="/"),i+a.substr(b.length)}return(h=/^(.*)\//.exec(b))?f(h[1],++c):void 0}if(b=_undef(b,"").toLowerCase(),"data:"!=a.substr(0,5)&&(a=a.replace(/([^:])\/\//g,"$1/")),_inArray(b,["absolute","relative","domain"])<0)return a;if(c=c||location.protocol+"//"+location.host,d===undefined){var g=location.pathname.match(/^(\/.*)\//);d=g?g[1]:""}var h;if(h=/^(\w+:\/\/[^\/]*)/.exec(a)){if(h[1]!==c)return a}else if(/^\w+:/.test(a))return a;return/^\//.test(a)?a=c+e(a.substr(1)):/^\w+:\/\//.test(a)||(a=c+e(d+"/"+a)),"relative"===b?a=f(c+d,0).substr(2):"absolute"===b&&a.substr(0,c.length)===c&&(a=a.substr(c.length)),a}function _formatHtml(a,b,c,d,e){null==a&&(a=""),c=c||"",d=_undef(d,!1),e=_undef(e," ");var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");a=a.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function(a,b,c,d){return b+c.replace(/<(?:br|br\s[^>]*)>/gi,"\n")+d}),a=a.replace(/<(?:br|br\s[^>]*)\s*\/?>\s*<\/p>/gi,"</p>"),a=a.replace(/(<(?:p|p\s[^>]*)>)\s*(<\/p>)/gi,"$1<br />$2"),a=a.replace(/\u200B/g,""),a=a.replace(/\u00A9/g,"&copy;"),a=a.replace(/\u00AE/g,"&reg;"),a=a.replace(/\u2003/g,"&emsp;"),a=a.replace(/\u3000/g,"&emsp;"),a=a.replace(/<[^>]+/g,function(a){return a.replace(/\s+/g," ")});var g={};b&&(_each(b,function(a,b){for(var c=a.split(","),d=0,e=c.length;e>d;d++)g[c[d]]=_toMap(b)}),g.script||(a=a.replace(/(<(?:script|script\s[^>]*)>)([\s\S]*?)(<\/script>)/gi,"")),g.style||(a=a.replace(/(<(?:style|style\s[^>]*)>)([\s\S]*?)(<\/style>)/gi,"")));var h=/(\s*)<(\/)?([\w\-:]+)((?:\s+|(?:\s+[\w\-:]+)|(?:\s+[\w\-:]+=[^\s"'<>]+)|(?:\s+[\w\-:"]+="[^"]*")|(?:\s+[\w\-:"]+='[^']*'))*)(\/)?>(\s*)/g,i=[];return a=a.replace(h,function(a,h,j,k,l,m,n){var o=a,p=h||"",q=j||"",r=k.toLowerCase(),s=l||"",t=m?" "+m:"",u=n||"";if(b&&!g[r])return"";if(""===t&&_SINGLE_TAG_MAP[r]&&(t=" /"),_INLINE_TAG_MAP[r]&&(p&&(p=" "),u&&(u=" ")),_PRE_TAG_MAP[r]&&(q?u="\n":p="\n"),d&&"br"==r&&(u="\n"),_BLOCK_TAG_MAP[r]&&!_PRE_TAG_MAP[r])if(d){q&&i.length>0&&i[i.length-1]===r?i.pop():i.push(r),p="\n",u="\n";for(var v=0,w=q?i.length:i.length-1;w>v;v++)p+=e,q||(u+=e);t?i.pop():q||(u+=e)}else p=u="";if(""!==s){var x=_getAttrList(o);if("font"===r){var y={},z="";_each(x,function(a,b){"color"===a&&(y.color=b,delete x[a]),"size"===a&&(y["font-size"]=f[parseInt(b,10)-1]||"",delete x[a]),"face"===a&&(y["font-family"]=b,delete x[a]),"style"===a&&(z=b)}),z&&!/;$/.test(z)&&(z+=";"),_each(y,function(a,b){""!==b&&(/\s/.test(b)&&(b="'"+b+"'"),z+=a+":"+b+";")}),x.style=z}_each(x,function(a,d){if(_FILL_ATTR_MAP[a]&&(x[a]=a),_inArray(a,["src","href"])>=0&&(x[a]=_formatUrl(d,c)),(b&&"style"!==a&&!g[r]["*"]&&!g[r][a]||"body"===r&&"contenteditable"===a||/^kindeditor_\d+$/.test(a))&&delete x[a],"style"===a&&""!==d){var e=_getCssList(d);_each(e,function(a){!b||g[r].style||g[r]["."+a]||delete e[a]});var f="";_each(e,function(a,b){f+=a+":"+b+";"}),x.style=f}}),s="",_each(x,function(a,b){("style"!==a||""!==b)&&(b=b.replace(/"/g,"&quot;"),s+=" "+a+'="'+b+'"')})}return"font"===r&&(r="span"),p+"<"+q+r+s+t+">"+u}),a=a.replace(/(<(?:pre|pre\s[^>]*)>)([\s\S]*?)(<\/pre>)/gi,function(a,b,c,d){return b+c.replace(/\n/g,'<span id="__kindeditor_pre_newline__">\n')+d}),a=a.replace(/\n\s*\n/g,"\n"),a=a.replace(/<span id="__kindeditor_pre_newline__">\n/g,"\n"),_trim(a)}function _clearMsWord(a,b){return a=a.replace(/<meta[\s\S]*?>/gi,"").replace(/<![\s\S]*?>/gi,"").replace(/<style[^>]*>[\s\S]*?<\/style>/gi,"").replace(/<script[^>]*>[\s\S]*?<\/script>/gi,"").replace(/<w:[^>]+>[\s\S]*?<\/w:[^>]+>/gi,"").replace(/<o:[^>]+>[\s\S]*?<\/o:[^>]+>/gi,"").replace(/<xml>[\s\S]*?<\/xml>/gi,"").replace(/<(?:table|td)[^>]*>/gi,function(a){return a.replace(/border-bottom:([#\w\s]+)/gi,"border:$1")}),_formatHtml(a,b)}function _mediaType(a){return/\.(rm|rmvb)(\?|$)/i.test(a)?"audio/x-pn-realaudio-plugin":/\.(swf|flv)(\?|$)/i.test(a)?"application/x-shockwave-flash":""}function _mediaClass(a){return/realaudio/i.test(a)?"ke-rm":/flash/i.test(a)?"ke-flash":"ke-media"}function _mediaAttrs(a){return _getAttrList(unescape(a))}function _mediaEmbed(a){var b="<embed ";return _each(a,function(a,c){b+=a+'="'+c+'" '}),b+="/>"}function _mediaImg(a,b){var c=b.width,d=b.height,e=b.type||_mediaType(b.src),f=_mediaEmbed(b),g="";/\D/.test(c)?g+="width:"+c+";":c>0&&(g+="width:"+c+"px;"),/\D/.test(d)?g+="height:"+d+";":d>0&&(g+="height:"+d+"px;");var h='<img class="'+_mediaClass(e)+'" src="'+a+'" ';return""!==g&&(h+='style="'+g+'" '),h+='data-ke-tag="'+escape(f)+'" alt="" />'}function _tmpl(a,b){var c=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');");return b?c(b):c}function _contains(a,b){if(9==a.nodeType&&9!=b.nodeType)return!0;for(;b=b.parentNode;)if(b==a)return!0;return!1}function _getAttr(a,b){b=b.toLowerCase();var c=null;if(_GET_SET_ATTRIBUTE||"script"==a.nodeName.toLowerCase())try{c=a.getAttribute(b,2)}catch(d){c=a.getAttribute(b,1)}else{var e=a.ownerDocument.createElement("div");e.appendChild(a.cloneNode(!1));var f=_getAttrList(_unescape(e.innerHTML));b in f&&(c=f[b])}return"style"===b&&null!==c&&(c=_formatCss(c)),c}function _queryAll(a,b){function c(a){return"string"!=typeof a?a:a.replace(/([^\w\-])/g,"\\$1")}function d(a){return a.replace(/\\/g,"")}function e(a,b){return"*"===a||a.toLowerCase()===c(b.toLowerCase())}function f(a,b,c){var f=[],g=c.ownerDocument||c,h=g.getElementById(d(a));return h&&e(b,h.nodeName)&&_contains(c,h)&&f.push(h),f}function g(a,b,c){var f,g,h,i,j=c.ownerDocument||c,k=[];if(c.getElementsByClassName)for(f=c.getElementsByClassName(d(a)),g=0,h=f.length;h>g;g++)i=f[g],e(b,i.nodeName)&&k.push(i);else if(j.querySelectorAll)for(f=j.querySelectorAll(("#document"!==c.nodeName?c.nodeName+" ":"")+b+"."+a),g=0,h=f.length;h>g;g++)i=f[g],_contains(c,i)&&k.push(i);else for(f=c.getElementsByTagName(b),a=" "+a+" ",g=0,h=f.length;h>g;g++)if(i=f[g],1==i.nodeType){var l=i.className;l&&(" "+l+" ").indexOf(a)>-1&&k.push(i)}return k}function h(a,b,c){for(var f,g=[],h=c.ownerDocument||c,i=h.getElementsByName(d(a)),j=0,k=i.length;k>j;j++)f=i[j],e(b,f.nodeName)&&_contains(c,f)&&null!==f.getAttribute("name")&&g.push(f);return g}function i(a,b,d,e){for(var f,g=[],h=e.getElementsByTagName(d),i=0,j=h.length;j>i;i++)f=h[i],1==f.nodeType&&(null===b?null!==_getAttr(f,a)&&g.push(f):b===c(_getAttr(f,a))&&g.push(f));return g}function j(a,b){var c,d=[];c=/^((?:\\.|[^.#\s\[<>])+)/.exec(a);var e=c?c[1]:"*";if(c=/#((?:[\w\-]|\\.)+)$/.exec(a))d=f(c[1],e,b);else if(c=/\.((?:[\w\-]|\\.)+)$/.exec(a))d=g(c[1],e,b);else if(c=/\[((?:[\w\-]|\\.)+)\]/.exec(a))d=i(c[1].toLowerCase(),null,e,b);else if(c=/\[((?:[\w\-]|\\.)+)\s*=\s*['"]?((?:\\.|[^'"]+)+)['"]?\]/.exec(a)){var j=c[1].toLowerCase(),k=c[2];d="id"===j?f(k,e,b):"class"===j?g(k,e,b):"name"===j?h(k,e,b):i(j,k,e,b)}else for(var l,m=b.getElementsByTagName(e),n=0,o=m.length;o>n;n++)l=m[n],1==l.nodeType&&d.push(l);return d}var k=a.split(",");if(k.length>1){var l=[];return _each(k,function(){_each(_queryAll(this,b),function(){_inArray(this,l)<0&&l.push(this)})}),l}b=b||document;for(var m,n=[],o=/((?:\\.|[^\s>])+|[\s>])/g;m=o.exec(a);)" "!==m[1]&&n.push(m[1]);var p=[];if(1==n.length)return j(n[0],b);var q,r,s,t,u,v,w,x,y,z,A=!1;for(v=0,lenth=n.length;v<lenth;v++)if(q=n[v],">"!==q){if(v>0){for(r=[],w=0,y=p.length;y>w;w++)for(t=p[w],s=j(q,t),x=0,z=s.length;z>x;x++)u=s[x],A?t===u.parentNode&&r.push(u):r.push(u);p=r}else p=j(q,b);if(0===p.length)return[]}else A=!0;return p}function _query(a,b){var c=_queryAll(a,b);return c.length>0?c[0]:null}function _get(a){return K(a)[0]}function _getDoc(a){return a?a.ownerDocument||a.document||a:document}function _getWin(a){if(!a)return window;var b=_getDoc(a);return b.parentWindow||b.defaultView}function _setHtml(a,b){if(1==a.nodeType){var c=_getDoc(a);try{a.innerHTML='<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />'+b;var d=c.getElementById("__kindeditor_temp_tag__");d.parentNode.removeChild(d)}catch(e){K(a).empty(),K("@"+b,c).each(function(){a.appendChild(this)})}}}function _hasClass(a,b){return _inString(b,a.className," ")}function _setAttr(a,b,c){_IE&&8>_V&&"class"==b.toLowerCase()&&(b="className"),a.setAttribute(b,""+c)}function _removeAttr(a,b){_IE&&8>_V&&"class"==b.toLowerCase()&&(b="className"),_setAttr(a,b,""),a.removeAttribute(b)}function _getNodeName(a){return a&&a.nodeName?a.nodeName.toLowerCase():""}function _computedCss(a,b){var c=_getWin(a),d=_toCamel(b),e="";if(c.getComputedStyle){var f=c.getComputedStyle(a,null);e=f[d]||f.getPropertyValue(b)||a.style[d]}else a.currentStyle&&(e=a.currentStyle[d]||a.style[d]);return e}function _hasVal(a){return!!_VALUE_TAG_MAP[_getNodeName(a)]}function _docElement(a){return a=a||document,_QUIRKS?a.body:a.documentElement}function _docHeight(a){var b=_docElement(a);return Math.max(b.scrollHeight,b.clientHeight)}function _docWidth(a){var b=_docElement(a);return Math.max(b.scrollWidth,b.clientWidth)}function _getScrollPos(a){a=a||document;var b,c;return _IE||_NEWIE||_OPERA?(b=_docElement(a).scrollLeft,c=_docElement(a).scrollTop):(b=_getWin(a).scrollX,c=_getWin(a).scrollY),{x:b,y:c}}function KNode(a){this.init(a)}function _updateCollapsed(a){return a.collapsed=a.startContainer===a.endContainer&&a.startOffset===a.endOffset,a}function _copyAndDelete(a,b,c){function d(d,e,f){var g,i=d.nodeValue.length;if(b){var j=d.cloneNode(!0);g=e>0?j.splitText(e):j,i>f&&g.splitText(f-e)}if(c){var k=d;if(e>0&&(k=d.splitText(e),a.setStart(d,e)),i>f){var l=k.splitText(f-e);a.setEnd(l,0)}h.push(k)}return g}function e(){c&&a.up().collapse(!0);for(var b=0,d=h.length;d>b;b++){var e=h[b];e.parentNode&&e.parentNode.removeChild(e)}}function f(e,n){for(var o,p=e.firstChild;p;){var q=new KRange(g).selectNode(p);if(j=q.compareBoundaryPoints(_START_TO_END,a),j>=0&&0>=k&&(k=q.compareBoundaryPoints(_START_TO_START,a)),k>=0&&0>=l&&(l=q.compareBoundaryPoints(_END_TO_END,a)),l>=0&&0>=m&&(m=q.compareBoundaryPoints(_END_TO_START,a)),m>=0)return!1;if(o=p.nextSibling,j>0)if(1==p.nodeType)if(k>=0&&0>=l)b&&n.appendChild(p.cloneNode(!0)),c&&h.push(p);else{var r;if(b&&(r=p.cloneNode(!1),n.appendChild(r)),f(p,r)===!1)return!1}else if(3==p.nodeType){var s;if(s=p==i.startContainer?d(p,i.startOffset,p.nodeValue.length):p==i.endContainer?d(p,0,i.endOffset):d(p,0,p.nodeValue.length),b)try{n.appendChild(s)}catch(t){}}p=o}}var g=a.doc,h=[],i=a.cloneRange().down(),j=-1,k=-1,l=-1,m=-1,n=a.commonAncestor(),o=g.createDocumentFragment();if(3==n.nodeType){var p=d(n,a.startOffset,a.endOffset);return b&&o.appendChild(p),e(),b?o:a}f(n,o),c&&a.up().collapse(!0);for(var q=0,r=h.length;r>q;q++){var s=h[q];s.parentNode&&s.parentNode.removeChild(s)}return b?o:a}function _moveToElementText(a,b){for(var c=b;c;){var d=K(c);if("marquee"==d.name||"select"==d.name)return;c=c.parentNode}try{a.moveToElementText(b)}catch(e){}}function _getStartEnd(a,b){var c=a.parentElement().ownerDocument,d=a.duplicate();d.collapse(b);var e=d.parentElement(),f=e.childNodes;if(0===f.length)return{node:e.parentNode,offset:K(e).index()};var g=c,h=0,i=-1,j=a.duplicate();_moveToElementText(j,e);for(var k=0,l=f.length;l>k;k++){var m=f[k];if(i=j.compareEndPoints("StartToStart",d),0===i)return{node:m.parentNode,offset:k};if(1==m.nodeType){var n,o=a.duplicate(),p=K(m),q=m;p.isControl()&&(n=c.createElement("span"),p.after(n),q=n,h+=p.text().replace(/\r\n|\n|\r/g,"").length),_moveToElementText(o,q),j.setEndPoint("StartToEnd",o),i>0?h+=o.text.replace(/\r\n|\n|\r/g,"").length:h=0,n&&K(n).remove()}else 3==m.nodeType&&(j.moveStart("character",m.nodeValue.length),h+=m.nodeValue.length);0>i&&(g=m)}if(0>i&&1==g.nodeType)return{node:e,offset:K(e.lastChild).index()+1};if(i>0)for(;g.nextSibling&&1==g.nodeType;)g=g.nextSibling;if(j=a.duplicate(),_moveToElementText(j,e),j.setEndPoint("StartToEnd",d),h-=j.text.replace(/\r\n|\n|\r/g,"").length,i>0&&3==g.nodeType)for(var r=g.previousSibling;r&&3==r.nodeType;)h-=r.nodeValue.length,r=r.previousSibling;return{node:g,offset:h}}function _getEndRange(a,b){var c=a.ownerDocument||a,d=c.body.createTextRange();if(c==a)return d.collapse(!0),d;if(1==a.nodeType&&a.childNodes.length>0){var e,f,g=a.childNodes;if(0===b?(f=g[0],e=!0):(f=g[b-1],e=!1),!f)return d;if("head"===K(f).name)return 1===b&&(e=!0),2===b&&(e=!1),d.collapse(e),d;if(1==f.nodeType){var h,i=K(f);return i.isControl()&&(h=c.createElement("span"),e?i.before(h):i.after(h),f=h),_moveToElementText(d,f),d.collapse(e),h&&K(h).remove(),d}a=f,b=e?0:f.nodeValue.length}var j=c.createElement("span");return K(a).before(j),_moveToElementText(d,j),d.moveStart("character",b),K(j).remove(),d}function _toRange(a){function b(a){"tr"==K(a.node).name&&(a.node=a.node.cells[a.offset],a.offset=0)}var c,d;if(_IERANGE){if(a.item)return c=_getDoc(a.item(0)),d=new KRange(c),d.selectNode(a.item(0)),d;c=a.parentElement().ownerDocument;var e=_getStartEnd(a,!0),f=_getStartEnd(a,!1);return b(e),b(f),d=new KRange(c),d.setStart(e.node,e.offset),d.setEnd(f.node,f.offset),d}var g=a.startContainer;return c=g.ownerDocument||g,d=new KRange(c),d.setStart(g,a.startOffset),d.setEnd(a.endContainer,a.endOffset),d}function KRange(a){this.init(a)}function _range(a){return a.nodeName?new KRange(a):a.constructor===KRange?a:_toRange(a)}function _nativeCommand(a,b,c){try{a.execCommand(b,!1,c)}catch(d){}}function _nativeCommandValue(a,b){var c="";try{c=a.queryCommandValue(b)}catch(d){}return"string"!=typeof c&&(c=""),c}function _getSel(a){var b=_getWin(a);return _IERANGE?a.selection:b.getSelection()}function _getRng(a){var b,c=_getSel(a);try{b=c.rangeCount>0?c.getRangeAt(0):c.createRange()}catch(d){}return!_IERANGE||b&&(b.item||b.parentElement().ownerDocument===a)?b:null}function _singleKeyMap(a){var b,c,d={};return _each(a,function(a,e){b=a.split(",");for(var f=0,g=b.length;g>f;f++)c=b[f],d[c]=e}),d}function _hasAttrOrCss(a,b){return _hasAttrOrCssByKey(a,b,"*")||_hasAttrOrCssByKey(a,b)}function _hasAttrOrCssByKey(a,b,c){if(c=c||a.name,1!==a.type)return!1;var d=_singleKeyMap(b);if(!d[c])return!1;for(var e=d[c].split(","),f=0,g=e.length;g>f;f++){var h=e[f];if("*"===h)return!0;var i=/^(\.?)([^=]+)(?:=([^=]*))?$/.exec(h),j=i[1]?"css":"attr";h=i[2];var k=i[3]||"";if(""===k&&""!==a[j](h))return!0;if(""!==k&&a[j](h)===k)return!0}return!1}function _removeAttrOrCss(a,b){1==a.type&&(_removeAttrOrCssByKey(a,b,"*"),_removeAttrOrCssByKey(a,b))}function _removeAttrOrCssByKey(a,b,c){if(c=c||a.name,1===a.type){var d=_singleKeyMap(b);if(d[c]){for(var e=d[c].split(","),f=!1,g=0,h=e.length;h>g;g++){var i=e[g];if("*"===i){f=!0;break}var j=/^(\.?)([^=]+)(?:=([^=]*))?$/.exec(i);i=j[2],j[1]?(i=_toCamel(i),a[0].style[i]&&(a[0].style[i]="")):a.removeAttr(i)}f&&a.remove(!0)}}}function _getInnerNode(a){for(var b=a;b.first();)b=b.first();return b}function _isEmptyNode(a){return 1!=a.type||a.isSingle()?!1:""===a.html().replace(/<[^>]+>/g,"")}function _mergeWrapper(a,b){a=a.clone(!0);for(var c=_getInnerNode(a),d=a,e=!1;b;){for(;d;)d.name===b.name&&(_mergeAttrs(d,b.attr(),b.css()),e=!0),d=d.first();e||c.append(b.clone(!1)),e=!1,b=b.first()}return a}function _wrapNode(a,b){if(b=b.clone(!0),3==a.type)return _getInnerNode(b).append(a.clone(!1)),a.replaceWith(b),b;for(var c,d=a;(c=a.first())&&1==c.children().length;)a=c;c=a.first();for(var e=a.doc.createDocumentFragment();c;)e.appendChild(c[0]),c=c.next();return b=_mergeWrapper(d,b),e.firstChild&&_getInnerNode(b).append(e),d.replaceWith(b),b}function _mergeAttrs(a,b,c){_each(b,function(b,c){"style"!==b&&a.attr(b,c)}),_each(c,function(b,c){a.css(b,c)})}function _inPreElement(a){for(;a&&"body"!=a.name;){if(_PRE_TAG_MAP[a.name]||"div"==a.name&&a.hasClass("ke-script"))return!0;a=a.parent()}return!1}function KCmd(a){this.init(a)}function _cmd(a){if(a.nodeName){var b=_getDoc(a);a=_range(b).selectNodeContents(b.body).collapse(!1)}return new KCmd(a)}function _drag(a){var b=a.moveEl,c=a.moveFn,d=a.clickEl||b,e=a.beforeDrag,f=a.iframeFix===undefined?!0:a.iframeFix,g=[document];f&&K("iframe").each(function(){var a=_formatUrl(this.src||"","absolute");if(!/^https?:\/\//.test(a)){var b;try{b=_iframeDoc(this)}catch(c){}if(b){var d=K(this).pos();K(b).data("pos-x",d.x),K(b).data("pos-y",d.y),g.push(b)}}}),d.mousedown(function(a){function f(a){a.preventDefault();var b=K(_getDoc(a.target)),e=_round((b.data("pos-x")||0)+a.pageX-o),f=_round((b.data("pos-y")||0)+a.pageY-p);c.call(d,k,l,m,n,e,f)}function h(a){a.preventDefault()}function i(a){a.preventDefault(),K(g).unbind("mousemove",f).unbind("mouseup",i).unbind("selectstart",h),j.releaseCapture&&j.releaseCapture()}if(0===a.button||1===a.button){a.stopPropagation();var j=d.get(),k=_removeUnit(b.css("left")),l=_removeUnit(b.css("top")),m=b.width(),n=b.height(),o=a.pageX,p=a.pageY;e&&e(),K(g).mousemove(f).mouseup(i).bind("selectstart",h),j.setCapture&&j.setCapture()}})}function KWidget(a){this.init(a)}function _widget(a){return new KWidget(a)}function _iframeDoc(a){return a=_get(a),a.contentDocument||a.contentWindow.document}function _getInitHtml(a,b,c,d){var e=[""===_direction?"<html>":'<html dir="'+_direction+'">','<head><meta charset="utf-8" /><title></title>',"<style>","html {margin:0;padding:0;}","body {margin:0;padding:5px;}",'body, td {font:12px/1.5 "sans serif",tahoma,verdana,helvetica;}',"body, p, div {word-wrap: break-word;}","p {margin:5px 0;}","table {border-collapse:collapse;}","img {border:0;}","noscript {display:none;}","table.ke-zeroborder td {border:1px dotted #AAA;}","img.ke-flash {"," border:1px solid #AAA;"," background-image:url("+a+"common/flash.gif);"," background-position:center center;"," background-repeat:no-repeat;"," width:100px;"," height:100px;","}","img.ke-rm {"," border:1px solid #AAA;"," background-image:url("+a+"common/rm.gif);"," background-position:center center;"," background-repeat:no-repeat;"," width:100px;"," height:100px;","}","img.ke-media {"," border:1px solid #AAA;"," background-image:url("+a+"common/media.gif);"," background-position:center center;"," background-repeat:no-repeat;"," width:100px;"," height:100px;","}","img.ke-anchor {"," border:1px dashed #666;"," width:16px;"," height:16px;","}",".ke-script, .ke-noscript, .ke-display-none {"," display:none;"," font-size:0;"," width:0;"," height:0;","}",".ke-pagebreak {"," border:1px dotted #AAA;"," font-size:0;"," height:2px;","}","</style>"];return _isArray(c)||(c=[c]),_each(c,function(a,b){b&&e.push('<link href="'+b+'" rel="stylesheet" />')}),d&&e.push("<style>"+d+"</style>"),e.push("</head><body "+(b?'class="'+b+'"':"")+"></body></html>"),e.join("\n")}function _elementVal(a,b){if(a.hasVal()){if(b===undefined){var c=a.val();return c=c.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/gi,"")}return a.val(b)}return a.html(b)}function KEdit(a){this.init(a)}function _edit(a){return new KEdit(a)}function _selectToolbar(a,b){var c=this,d=c.get(a);if(d){if(d.hasClass("ke-disabled"))return;b(d)}}function KToolbar(a){this.init(a)}function _toolbar(a){return new KToolbar(a)}function KMenu(a){this.init(a)}function _menu(a){return new KMenu(a)}function KColorPicker(a){this.init(a)}function _colorpicker(a){return new KColorPicker(a)}function KUploadButton(a){this.init(a)}function _uploadbutton(a){return new KUploadButton(a)}function _createButton(a){a=a||{};var b=a.name||"",c=K('<span class="ke-button-common ke-button-outer" title="'+b+'"></span>'),d=K('<input class="ke-button-common ke-button" type="button" value="'+b+'" />');return a.click&&d.click(a.click),c.append(d),c}function KDialog(a){this.init(a)}function _dialog(a){return new KDialog(a)}function _tabs(a){var b=_widget(a),c=b.remove,d=a.afterSelect,e=b.div,f=[];e.addClass("ke-tabs").bind("contextmenu,mousedown,mousemove",function(a){a.preventDefault()});var g=K('<ul class="ke-tabs-ul ke-clearfix"></ul>');return e.append(g),b.add=function(a){var b=K('<li class="ke-tabs-li">'+a.title+"</li>");b.data("tab",a),f.push(b),g.append(b)},b.selectedIndex=0,b.select=function(a){b.selectedIndex=a,_each(f,function(c,d){d.unbind(),c===a?(d.addClass("ke-tabs-li-selected"),K(d.data("tab").panel).show("")):(d.removeClass("ke-tabs-li-selected").removeClass("ke-tabs-li-on").mouseover(function(){K(this).addClass("ke-tabs-li-on")}).mouseout(function(){K(this).removeClass("ke-tabs-li-on")}).click(function(){b.select(c)}),K(d.data("tab").panel).hide())}),d&&d.call(b,a)},b.remove=function(){_each(f,function(){this.remove()}),g.remove(),c.call(b)},b}function _loadScript(a,b){var c=document.getElementsByTagName("head")[0]||(_QUIRKS?document.body:document.documentElement),d=document.createElement("script");c.appendChild(d),d.src=a,d.charset="utf-8",d.onload=d.onreadystatechange=function(){this.readyState&&"loaded"!==this.readyState||(b&&b(),d.onload=d.onreadystatechange=null,c.removeChild(d))}}function _chopQuery(a){var b=a.indexOf("?");return b>0?a.substr(0,b):a}function _loadStyle(a){for(var b=document.getElementsByTagName("head")[0]||(_QUIRKS?document.body:document.documentElement),c=document.createElement("link"),d=_chopQuery(_formatUrl(a,"absolute")),e=K('link[rel="stylesheet"]',b),f=0,g=e.length;g>f;f++)if(_chopQuery(_formatUrl(e[f].href,"absolute"))===d)return;b.appendChild(c),c.href=a,c.rel="stylesheet"}function _ajax(a,b,c,d,e){c=c||"GET",e=e||"json";var f=window.XMLHttpRequest?new window.XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");if(f.open(c,a,!0),f.onreadystatechange=function(){if(4==f.readyState&&200==f.status&&b){var a=_trim(f.responseText);"json"==e&&(a=_json(a)),b(a)}},"POST"==c){var g=[];_each(d,function(a,b){g.push(encodeURIComponent(a)+"="+encodeURIComponent(b))});try{f.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}catch(h){}f.send(g.join("&"))}else f.send(null)}function _plugin(a,b){return a===undefined?_plugins:b?void(_plugins[a]=b):_plugins[a]}function _parseLangKey(a){var b,c="core";return(b=/^(\w+)\.(\w+)$/.exec(a))&&(c=b[1],a=b[2]),{ns:c,key:a}}function _lang(a,b){if(b=b===undefined?K.options.langType:b,"string"==typeof a){if(!_language[b])return"no language";var c=a.length-1;if("."===a.substr(c))return _language[b][a.substr(0,c)];var d=_parseLangKey(a);return _language[b][d.ns][d.key]}_each(a,function(a,c){var d=_parseLangKey(a);_language[b]||(_language[b]={}),_language[b][d.ns]||(_language[b][d.ns]={}),_language[b][d.ns][d.key]=c})}function _getImageFromRange(a,b){if(!a.collapsed){a=a.cloneRange().up();var c=a.startContainer,d=a.startOffset;if(_WEBKIT||a.isControl()){var e=K(c.childNodes[d]);if(e&&"img"==e.name)return b(e)?e:void 0}}}function _bindContextmenuEvent(){var a=this,b=a.edit.doc;K(b).contextmenu(function(b){if(a.menu&&a.hideMenu(),!a.useContextmenu)return void b.preventDefault();if(0!==a._contextmenus.length){var c=0,d=[];for(_each(a._contextmenus,function(){return"-"==this.title?void d.push(this):void(this.cond&&this.cond()&&(d.push(this),this.width&&this.width>c&&(c=this.width)))});d.length>0&&"-"==d[0].title;)d.shift();for(;d.length>0&&"-"==d[d.length-1].title;)d.pop();var e=null;if(_each(d,function(a){"-"==this.title&&"-"==e.title&&delete d[a],e=this}),d.length>0){b.preventDefault();var f=K(a.edit.iframe).pos(),g=_menu({x:f.x+b.clientX,y:f.y+b.clientY,width:c,css:{visibility:"hidden"},shadowMode:a.shadowMode});_each(d,function(){this.title&&g.addItem(this)});var h=_docElement(g.doc),i=g.div.height();b.clientY+i>=h.clientHeight-100&&g.pos(g.x,_removeUnit(g.y)-i),g.div.css("visibility","visible"),a.menu=g}}})}function _bindNewlineEvent(){function a(a){for(var b=K(a.commonAncestor());b&&(1!=b.type||b.isStyle());)b=b.parent();return b.name}var b=this,c=b.edit.doc,d=b.newlineTag;if(!(_IE&&"br"!==d||_GECKO&&3>_V&&"p"!==d||_OPERA&&9>_V)){var e=_toMap("h1,h2,h3,h4,h5,h6,pre,li"),f=_toMap("p,h1,h2,h3,h4,h5,h6,pre,li,blockquote");K(c).keydown(function(g){if(!(13!=g.which||g.shiftKey||g.ctrlKey||g.altKey)){b.cmd.selection();var h=a(b.cmd.range);if("marquee"!=h&&"select"!=h)return"br"!==d||e[h]?void(f[h]||_nativeCommand(c,"formatblock","<p>")):(g.preventDefault(),void b.insertHtml("<br />"+(_IE&&9>_V?"":"​")))}}),K(c).keyup(function(e){if(!(13!=e.which||e.shiftKey||e.ctrlKey||e.altKey)&&"br"!=d){if(_GECKO){var g=b.cmd.commonAncestor("p"),h=b.cmd.commonAncestor("a");return void(h&&""==h.text()&&(h.remove(!0),b.cmd.range.selectNodeContents(g[0]).collapse(!0),b.cmd.select()))}b.cmd.selection();var i=a(b.cmd.range);if("marquee"!=i&&"select"!=i){f[i]||_nativeCommand(c,"formatblock","<p>");var j=b.cmd.commonAncestor("div");if(j){for(var k=K("<p></p>"),l=j[0].firstChild;l;){var m=l.nextSibling;k.append(l),l=m}j.before(k),j.remove(),b.cmd.range.selectNodeContents(k[0]),b.cmd.select()}}}})}}function _bindTabEvent(){var a=this,b=a.edit.doc;K(b).keydown(function(c){if(9==c.which){if(c.preventDefault(),a.afterTab)return void a.afterTab.call(a,c);var d=a.cmd,e=d.range;e.shrink(),e.collapsed&&1==e.startContainer.nodeType&&(e.insertNode(K("@&nbsp;",b)[0]),d.select()),a.insertHtml("&nbsp;&nbsp;&nbsp;&nbsp;")}})}function _bindFocusEvent(){var a=this;K(a.edit.textarea[0],a.edit.win).focus(function(b){a.afterFocus&&a.afterFocus.call(a,b)}).blur(function(b){a.afterBlur&&a.afterBlur.call(a,b)})}function _removeBookmarkTag(a){return _trim(a.replace(/<span [^>]*id="?__kindeditor_bookmark_\w+_\d+__"?[^>]*><\/span>/gi,""))}function _removeTempTag(a){return a.replace(/<div[^>]+class="?__kindeditor_paste__"?[^>]*>[\s\S]*?<\/div>/gi,"")}function _addBookmarkToStack(a,b){if(0===a.length)return void a.push(b);var c=a[a.length-1];_removeBookmarkTag(b.html)!==_removeBookmarkTag(c.html)&&a.push(b)}function _undoToRedo(a,b){var c,d,e=this,f=e.edit,g=f.doc.body;if(0===a.length)return e;f.designMode?(c=e.cmd.range,d=c.createBookmark(!0),d.html=g.innerHTML):d={html:g.innerHTML},_addBookmarkToStack(b,d); +var h=a.pop();return _removeBookmarkTag(d.html)===_removeBookmarkTag(h.html)&&a.length>0&&(h=a.pop()),f.designMode?(f.html(h.html),h.start&&(c.moveToBookmark(h),e.select())):K(g).html(_removeBookmarkTag(h.html)),e}function KEditor(a){function b(a,b){KEditor.prototype[a]===undefined&&(c[a]=b),c.options[a]=b}var c=this;c.options={},_each(a,function(c){b(c,a[c])}),_each(K.options,function(a,d){c[a]===undefined&&b(a,d)});var d=K(c.srcElement||"<textarea/>");c.width||(c.width=d[0].style.width||d.width()),c.height||(c.height=d[0].style.height||d.height()),b("width",_undef(c.width,c.minWidth)),b("height",_undef(c.height,c.minHeight)),b("width",_addUnit(c.width)),b("height",_addUnit(c.height)),_MOBILE&&(!_IOS||534>_V)&&(c.designMode=!1),c.srcElement=d,c.initContent="",c.plugin={},c.isCreated=!1,c._handlers={},c._contextmenus=[],c._undoStack=[],c._redoStack=[],c._firstAddBookmark=!0,c.menu=c.contextmenu=null,c.dialogs=[]}function _editor(a){return new KEditor(a)}function _create(a,b){function c(a){return _each(_plugins,function(b,c){_isFunction(c)&&(c.call(a,KindEditor),a._pluginStatus||(a._pluginStatus={}),a._pluginStatus[b]="inited")}),a.create()}if(b=b||{},b.basePath=_undef(b.basePath,K.basePath),b.themesPath=_undef(b.themesPath,b.basePath+"themes/"),b.langPath=_undef(b.langPath,b.basePath+"lang/"),b.pluginsPath=_undef(b.pluginsPath,b.basePath+"plugins/"),_undef(b.loadStyleMode,K.options.loadStyleMode)){var d=_undef(b.themeType,K.options.themeType);_loadStyle(b.themesPath+"default/default.css"),_loadStyle(b.themesPath+d+"/"+d+".css")}var e=K(a);if(e&&0!==e.length){if(e.length>1)return e.each(function(){_create(this,b)}),_instances[0];b.srcElement=e[0];var f=new KEditor(b);return _instances.push(f),_language[f.langType]?c(f):(_loadScript(f.langPath+f.langType+".js?ver="+encodeURIComponent(K.DEBUG?_TIME:_VERSION),function(){c(f)}),f)}}function _eachEditor(a,b){K(a).each(function(a,c){K.each(_instances,function(a,d){return d&&d.srcElement[0]==c?(b.call(d,a),!1):void 0})})}if(!window.KindEditor){window.console||(window.console={}),console.log||(console.log=function(){});var _VERSION="4.1.11 (2016-03-31)",_ua=navigator.userAgent.toLowerCase(),_IE=_ua.indexOf("msie")>-1&&-1==_ua.indexOf("opera"),_NEWIE=-1==_ua.indexOf("msie")&&_ua.indexOf("trident")>-1,_GECKO=_ua.indexOf("gecko")>-1&&-1==_ua.indexOf("khtml"),_WEBKIT=_ua.indexOf("applewebkit")>-1,_OPERA=_ua.indexOf("opera")>-1,_MOBILE=_ua.indexOf("mobile")>-1,_IOS=/ipad|iphone|ipod/.test(_ua),_QUIRKS="CSS1Compat"!=document.compatMode,_IERANGE=!window.getSelection,_matches=/(?:msie|firefox|webkit|opera)[\/:\s](\d+)/.exec(_ua),_V=_matches?_matches[1]:"0",_TIME=(new Date).getTime(),_round=Math.round,K={DEBUG:!1,VERSION:_VERSION,IE:_IE,GECKO:_GECKO,WEBKIT:_WEBKIT,OPERA:_OPERA,V:_V,TIME:_TIME,each:_each,isArray:_isArray,isFunction:_isFunction,inArray:_inArray,inString:_inString,trim:_trim,addUnit:_addUnit,removeUnit:_removeUnit,escape:_escape,unescape:_unescape,toCamel:_toCamel,toHex:_toHex,toMap:_toMap,toArray:_toArray,undef:_undef,invalidUrl:_invalidUrl,addParam:_addParam,extend:_extend,json:_json},_INLINE_TAG_MAP=_toMap("a,abbr,acronym,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,img,input,ins,kbd,label,map,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"),_BLOCK_TAG_MAP=_toMap("address,applet,blockquote,body,center,dd,dir,div,dl,dt,fieldset,form,frameset,h1,h2,h3,h4,h5,h6,head,hr,html,iframe,ins,isindex,li,map,menu,meta,noframes,noscript,object,ol,p,pre,script,style,table,tbody,td,tfoot,th,thead,title,tr,ul"),_SINGLE_TAG_MAP=_toMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed"),_STYLE_TAG_MAP=_toMap("b,basefont,big,del,em,font,i,s,small,span,strike,strong,sub,sup,u"),_CONTROL_TAG_MAP=_toMap("img,table,input,textarea,button"),_PRE_TAG_MAP=_toMap("pre,style,script"),_NOSPLIT_TAG_MAP=_toMap("html,head,body,td,tr,table,ol,ul,li"),_AUTOCLOSE_TAG_MAP=_toMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"),_FILL_ATTR_MAP=_toMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),_VALUE_TAG_MAP=_toMap("input,button,textarea,select");K.basePath=_getBasePath(),K.options={designMode:!0,fullscreenMode:!1,filterMode:!0,wellFormatMode:!0,shadowMode:!0,loadStyleMode:!0,basePath:K.basePath,themesPath:K.basePath+"themes/",langPath:K.basePath+"lang/",pluginsPath:K.basePath+"plugins/",themeType:"default",langType:"zh-CN",urlType:"",newlineTag:"p",resizeType:2,syncType:"form",pasteType:2,dialogAlignType:"page",useContextmenu:!0,fullscreenShortcut:!1,bodyClass:"ke-content",indentChar:" ",cssPath:"",cssData:"",minWidth:650,minHeight:100,minChangeSize:50,zIndex:811213000,items:["source","|","undo","redo","|","preview","print","template","code","cut","copy","paste","plainpaste","wordpaste","|","justifyleft","justifycenter","justifyright","justifyfull","insertorderedlist","insertunorderedlist","indent","outdent","subscript","superscript","clearhtml","quickformat","selectall","|","fullscreen","/","formatblock","fontname","fontsize","|","forecolor","hilitecolor","bold","italic","underline","strikethrough","lineheight","removeformat","|","image","multiimage","flash","media","insertfile","table","hr","emoticons","baidumap","pagebreak","anchor","link","unlink","|","about"],noDisableItems:["source","fullscreen"],colorTable:[["#E53333","#E56600","#FF9900","#64451D","#DFC5A4","#FFE500"],["#009900","#006600","#99BB00","#B8D100","#60D978","#00D5FF"],["#337FE5","#003399","#4C33E5","#9933E5","#CC33E5","#EE33EE"],["#FFFFFF","#CCCCCC","#999999","#666666","#333333","#000000"]],fontSizeTable:["9px","10px","12px","14px","16px","18px","24px","32px"],htmlTags:{font:["id","class","color","size","face",".background-color"],span:["id","class",".color",".background-color",".font-size",".font-family",".background",".font-weight",".font-style",".text-decoration",".vertical-align",".line-height"],div:["id","class","align",".border",".margin",".padding",".text-align",".color",".background-color",".font-size",".font-family",".font-weight",".background",".font-style",".text-decoration",".vertical-align",".margin-left"],table:["id","class","border","cellspacing","cellpadding","width","height","align","bordercolor",".padding",".margin",".border","bgcolor",".text-align",".color",".background-color",".font-size",".font-family",".font-weight",".font-style",".text-decoration",".background",".width",".height",".border-collapse"],"td,th":["id","class","align","valign","width","height","colspan","rowspan","bgcolor",".text-align",".color",".background-color",".font-size",".font-family",".font-weight",".font-style",".text-decoration",".vertical-align",".background",".border"],a:["id","class","href","target","name"],embed:["id","class","src","width","height","type","loop","autostart","quality",".width",".height","align","allowscriptaccess","wmode"],img:["id","class","src","width","height","border","alt","title","align",".width",".height",".border"],"p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6":["id","class","align",".text-align",".color",".background-color",".font-size",".font-family",".background",".font-weight",".font-style",".text-decoration",".vertical-align",".text-indent",".margin-left"],pre:["id","class"],hr:["id","class",".page-break-after"],"br,tbody,tr,strong,b,sub,sup,em,i,u,strike,s,del":["id","class"],iframe:["id","class","src","frameborder","width","height",".width",".height"]},layout:'<div class="container"><div class="toolbar"></div><div class="edit"></div><div class="statusbar"></div></div>'};var _useCapture=!1,_INPUT_KEY_MAP=_toMap("8,9,13,32,46,48..57,59,61,65..90,106,109..111,188,190..192,219..222"),_CURSORMOVE_KEY_MAP=_toMap("33..40"),_CHANGE_KEY_MAP={};_each(_INPUT_KEY_MAP,function(a,b){_CHANGE_KEY_MAP[a]=b}),_each(_CURSORMOVE_KEY_MAP,function(a,b){_CHANGE_KEY_MAP[a]=b});var _EVENT_PROPS="altKey,attrChange,attrName,bubbles,button,cancelable,charCode,clientX,clientY,ctrlKey,currentTarget,data,detail,eventPhase,fromElement,handler,keyCode,metaKey,newValue,offsetX,offsetY,originalTarget,pageX,pageY,prevValue,relatedNode,relatedTarget,screenX,screenY,shiftKey,srcElement,target,toElement,view,wheelDelta,which".split(",");_extend(KEvent,{init:function(a,b){var c=this,d=a.ownerDocument||a.document||a;if(c.event=b,_each(_EVENT_PROPS,function(a,d){c[d]=b[d]}),c.target||(c.target=c.srcElement||d),3===c.target.nodeType&&(c.target=c.target.parentNode),!c.relatedTarget&&c.fromElement&&(c.relatedTarget=c.fromElement===c.target?c.toElement:c.fromElement),null==c.pageX&&null!=c.clientX){var e=d.documentElement,f=d.body;c.pageX=c.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),c.pageY=c.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)}switch(!c.which&&(c.charCode||0===c.charCode?c.charCode:c.keyCode)&&(c.which=c.charCode||c.keyCode),!c.metaKey&&c.ctrlKey&&(c.metaKey=c.ctrlKey),c.which||c.button===undefined||(c.which=1&c.button?1:2&c.button?3:4&c.button?2:0),c.which){case 186:c.which=59;break;case 187:case 107:case 43:c.which=61;break;case 189:case 45:c.which=109;break;case 42:c.which=106;break;case 47:c.which=111;break;case 78:c.which=110}c.which>=96&&c.which<=105&&(c.which-=48)},preventDefault:function(){var a=this.event;a.preventDefault?a.preventDefault():a.returnValue=!1},stopPropagation:function(){var a=this.event;a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},stop:function(){this.preventDefault(),this.stopPropagation()}});var _eventExpendo="kindeditor_"+_TIME,_eventId=0,_eventData={},_readyFinished=!1;window.attachEvent&&window.attachEvent("onunload",function(){_each(_eventData,function(a,b){b.el&&_unbind(b.el)})}),K.ctrl=_ctrl,K.ready=_ready,K.formatUrl=_formatUrl,K.formatHtml=_formatHtml,K.getCssList=_getCssList,K.getAttrList=_getAttrList,K.mediaType=_mediaType,K.mediaAttrs=_mediaAttrs,K.mediaEmbed=_mediaEmbed,K.mediaImg=_mediaImg,K.clearMsWord=_clearMsWord,K.tmpl=_tmpl;var _getSetAttrDiv=document.createElement("div");_getSetAttrDiv.setAttribute("className","t");var _GET_SET_ATTRIBUTE="t"!==_getSetAttrDiv.className;K.query=_query,K.queryAll=_queryAll,_extend(KNode,{init:function(a){var b=this;a=_isArray(a)?a:[a];for(var c=0,d=0,e=a.length;e>d;d++)a[d]&&(b[d]=a[d].constructor===KNode?a[d][0]:a[d],c++);b.length=c,b.doc=_getDoc(b[0]),b.name=_getNodeName(b[0]),b.type=b.length>0?b[0].nodeType:null,b.win=_getWin(b[0])},each:function(a){for(var b=this,c=0;c<b.length;c++)if(a.call(b[c],c,b[c])===!1)return b;return b},bind:function(a,b){return this.each(function(){_bind(this,a,b)}),this},unbind:function(a,b){return this.each(function(){_unbind(this,a,b)}),this},fire:function(a){return this.length<1?this:(_fire(this[0],a),this)},hasAttr:function(a){return this.length<1?!1:!!_getAttr(this[0],a)},attr:function(a,b){var c=this;return a===undefined?_getAttrList(c.outer()):"object"==typeof a?(_each(a,function(a,b){c.attr(a,b)}),c):b===undefined?(b=c.length<1?null:_getAttr(c[0],a),null===b?"":b):(c.each(function(){_setAttr(this,a,b)}),c)},removeAttr:function(a){return this.each(function(){_removeAttr(this,a)}),this},get:function(a){return this.length<1?null:this[a||0]},eq:function(a){return this.length<1?null:this[a]?new KNode(this[a]):null},hasClass:function(a){return this.length<1?!1:_hasClass(this[0],a)},addClass:function(a){return this.each(function(){_hasClass(this,a)||(this.className=_trim(this.className+" "+a))}),this},removeClass:function(a){return this.each(function(){_hasClass(this,a)&&(this.className=_trim(this.className.replace(new RegExp("(^|\\s)"+a+"(\\s|$)")," ")))}),this},html:function(a){var b=this;return a===undefined?b.length<1||1!=b.type?"":_formatHtml(b[0].innerHTML):(b.each(function(){_setHtml(this,a)}),b)},text:function(){var a=this;return a.length<1?"":_IE?a[0].innerText:a[0].textContent},hasVal:function(){return this.length<1?!1:_hasVal(this[0])},val:function(a){var b=this;return a===undefined?b.length<1?"":b.hasVal()?b[0].value:b.attr("value"):(b.each(function(){_hasVal(this)?this.value=a:_setAttr(this,"value",a)}),b)},css:function(a,b){var c=this;return a===undefined?_getCssList(c.attr("style")):"object"==typeof a?(_each(a,function(a,b){c.css(a,b)}),c):b===undefined?c.length<1?"":c[0].style[_toCamel(a)]||_computedCss(c[0],a)||"":(c.each(function(){this.style[_toCamel(a)]=b}),c)},width:function(a){var b=this;return a===undefined?b.length<1?0:b[0].offsetWidth:b.css("width",_addUnit(a))},height:function(a){var b=this;return a===undefined?b.length<1?0:b[0].offsetHeight:b.css("height",_addUnit(a))},opacity:function(a){return this.each(function(){this.style.opacity===undefined?this.style.filter=1==a?"":"alpha(opacity="+100*a+")":this.style.opacity=1==a?"":a}),this},data:function(a,b){var c=this;return a="kindeditor_data_"+a,b===undefined?c.length<1?null:c[0][a]:(this.each(function(){this[a]=b}),c)},pos:function(){var a=this,b=a[0],c=0,d=0;if(b)if(b.getBoundingClientRect){var e=b.getBoundingClientRect(),f=_getScrollPos(a.doc);c=e.left+f.x,d=e.top+f.y}else for(;b;)c+=b.offsetLeft,d+=b.offsetTop,b=b.offsetParent;return{x:_round(c),y:_round(d)}},clone:function(a){return new KNode(this.length<1?[]:this[0].cloneNode(a))},append:function(a){return this.each(function(){this.appendChild&&this.appendChild(_get(a))}),this},appendTo:function(a){return this.each(function(){_get(a).appendChild(this)}),this},before:function(a){return this.each(function(){this.parentNode.insertBefore(_get(a),this)}),this},after:function(a){return this.each(function(){this.nextSibling?this.parentNode.insertBefore(_get(a),this.nextSibling):this.parentNode.appendChild(_get(a))}),this},replaceWith:function(a){var b=[];return this.each(function(c,d){_unbind(d);var e=_get(a);d.parentNode.replaceChild(e,d),b.push(e)}),K(b)},empty:function(){var a=this;return a.each(function(a,b){for(var c=b.firstChild;c;){if(!b.parentNode)return;var d=c.nextSibling;c.parentNode.removeChild(c),c=d}}),a},remove:function(a){var b=this;return b.each(function(c,d){if(d.parentNode){if(_unbind(d),a)for(var e=d.firstChild;e;){var f=e.nextSibling;d.parentNode.insertBefore(e,d),e=f}d.parentNode.removeChild(d),delete b[c]}}),b.length=0,b},show:function(a){var b=this;return a===undefined&&(a=b._originDisplay||""),"none"!=b.css("display")?b:b.css("display",a)},hide:function(){var a=this;return a.length<1?a:(a._originDisplay=a[0].style.display,a.css("display","none"))},outer:function(){var a=this;if(a.length<1)return"";var b,c=a.doc.createElement("div");return c.appendChild(a[0].cloneNode(!0)),b=_formatHtml(c.innerHTML),c=null,b},isSingle:function(){return!!_SINGLE_TAG_MAP[this.name]},isInline:function(){return!!_INLINE_TAG_MAP[this.name]},isBlock:function(){return!!_BLOCK_TAG_MAP[this.name]},isStyle:function(){return!!_STYLE_TAG_MAP[this.name]},isControl:function(){return!!_CONTROL_TAG_MAP[this.name]},contains:function(a){return this.length<1?!1:_contains(this[0],_get(a))},parent:function(){if(this.length<1)return null;var a=this[0].parentNode;return a?new KNode(a):null},children:function(){if(this.length<1)return new KNode([]);for(var a=[],b=this[0].firstChild;b;)(3!=b.nodeType||""!==_trim(b.nodeValue))&&a.push(b),b=b.nextSibling;return new KNode(a)},first:function(){var a=this.children();return a.length>0?a.eq(0):null},last:function(){var a=this.children();return a.length>0?a.eq(a.length-1):null},index:function(){if(this.length<1)return-1;for(var a=-1,b=this[0];b;)a++,b=b.previousSibling;return a},prev:function(){if(this.length<1)return null;var a=this[0].previousSibling;return a?new KNode(a):null},next:function(){if(this.length<1)return null;var a=this[0].nextSibling;return a?new KNode(a):null},scan:function(a,b){function c(d){for(var e=b?d.firstChild:d.lastChild;e;){var f=b?e.nextSibling:e.previousSibling;if(a(e)===!1)return!1;if(c(e)===!1)return!1;e=f}}if(!(this.length<1))return b=b===undefined?!0:b,c(this[0]),this}}),_each("blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error,contextmenu".split(","),function(a,b){KNode.prototype[b]=function(a){return a?this.bind(b,a):this.fire(b)}});var _K=K;K=function(a,b){function c(a){return a[0]||(a=[]),new KNode(a)}if(a!==undefined&&null!==a){if("string"==typeof a){b&&(b=_get(b));var d=a.length;if("@"===a.charAt(0)&&(a=a.substr(1)),a.length!==d||/<.+>/.test(a)){var e=b?b.ownerDocument||b:document,f=e.createElement("div"),g=[];f.innerHTML='<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />'+a;for(var h=0,i=f.childNodes.length;i>h;h++){var j=f.childNodes[h];"__kindeditor_temp_tag__"!=j.id&&g.push(j)}return c(g)}return c(_queryAll(a,b))}return a&&a.constructor===KNode?a:(a.toArray&&(a=a.toArray()),c(_isArray(a)?a:_toArray(arguments)))}},_each(_K,function(a,b){K[a]=b}),K.NodeClass=KNode,window.KindEditor=K;var _START_TO_START=0,_START_TO_END=1,_END_TO_END=2,_END_TO_START=3,_BOOKMARK_ID=0;_extend(KRange,{init:function(a){var b=this;b.startContainer=a,b.startOffset=0,b.endContainer=a,b.endOffset=0,b.collapsed=!0,b.doc=a},commonAncestor:function(){function a(a){for(var b=[];a;)b.push(a),a=a.parentNode;return b}for(var b,c,d=a(this.startContainer),e=a(this.endContainer),f=0,g=d.length,h=e.length;++f&&(b=d[g-f],c=e[h-f],b&&c&&b===c););return d[g-f+1]},setStart:function(a,b){var c=this,d=c.doc;return c.startContainer=a,c.startOffset=b,c.endContainer===d&&(c.endContainer=a,c.endOffset=b),_updateCollapsed(this)},setEnd:function(a,b){var c=this,d=c.doc;return c.endContainer=a,c.endOffset=b,c.startContainer===d&&(c.startContainer=a,c.startOffset=b),_updateCollapsed(this)},setStartBefore:function(a){return this.setStart(a.parentNode||this.doc,K(a).index())},setStartAfter:function(a){return this.setStart(a.parentNode||this.doc,K(a).index()+1)},setEndBefore:function(a){return this.setEnd(a.parentNode||this.doc,K(a).index())},setEndAfter:function(a){return this.setEnd(a.parentNode||this.doc,K(a).index()+1)},selectNode:function(a){return this.setStartBefore(a).setEndAfter(a)},selectNodeContents:function(a){var b=K(a);if(3==b.type||b.isSingle())return this.selectNode(a);var c=b.children();return c.length>0?this.setStartBefore(c[0]).setEndAfter(c[c.length-1]):this.setStart(a,0).setEnd(a,0)},collapse:function(a){return a?this.setEnd(this.startContainer,this.startOffset):this.setStart(this.endContainer,this.endOffset)},compareBoundaryPoints:function(a,b){var c=this.get(),d=b.get();if(!_IERANGE)return c.compareBoundaryPoints(a,d);var e={};e[_START_TO_START]="StartToStart",e[_START_TO_END]="EndToStart",e[_END_TO_END]="EndToEnd",e[_END_TO_START]="StartToEnd";var f=c.compareEndPoints(e[a],d);if(0!==f)return f;var g,h,i,j,k;if((a===_START_TO_START||a===_END_TO_START)&&(g=this.startContainer,j=this.startOffset),(a===_START_TO_END||a===_END_TO_END)&&(g=this.endContainer,j=this.endOffset),(a===_START_TO_START||a===_START_TO_END)&&(h=b.startContainer,k=b.startOffset),(a===_END_TO_END||a===_END_TO_START)&&(h=b.endContainer,k=b.endOffset),g===h){var l=j-k;return l>0?1:0>l?-1:0}for(i=h;i&&i.parentNode!==g;)i=i.parentNode;if(i)return K(i).index()>=j?-1:1;for(i=g;i&&i.parentNode!==h;)i=i.parentNode;return i?K(i).index()>=k?1:-1:(i=K(h).next(),i&&i.contains(g)?1:(i=K(g).next(),i&&i.contains(h)?-1:void 0))},cloneRange:function(){return new KRange(this.doc).setStart(this.startContainer,this.startOffset).setEnd(this.endContainer,this.endOffset)},toString:function(){var a=this.get(),b=_IERANGE?a.text:a.toString();return b.replace(/\r\n|\n|\r/g,"")},cloneContents:function(){return _copyAndDelete(this,!0,!1)},deleteContents:function(){return _copyAndDelete(this,!1,!0)},extractContents:function(){return _copyAndDelete(this,!0,!0)},insertNode:function(a){var b,c,d,e=this,f=e.startContainer,g=e.startOffset,h=e.endContainer,i=e.endOffset,j=1;return"#document-fragment"===a.nodeName.toLowerCase()&&(b=a.firstChild,c=a.lastChild,j=a.childNodes.length),1==f.nodeType?(d=f.childNodes[g],d?(f.insertBefore(a,d),f===h&&(i+=j)):f.appendChild(a)):3==f.nodeType&&(0===g?(f.parentNode.insertBefore(a,f),f.parentNode===h&&(i+=j)):g>=f.nodeValue.length?f.nextSibling?f.parentNode.insertBefore(a,f.nextSibling):f.parentNode.appendChild(a):(d=g>0?f.splitText(g):f,f.parentNode.insertBefore(a,d),f===h&&(h=d,i-=g))),b?e.setStartBefore(b).setEndAfter(c):e.selectNode(a),e.compareBoundaryPoints(_END_TO_END,e.cloneRange().setEnd(h,i))>=1?e:e.setEnd(h,i)},surroundContents:function(a){return a.appendChild(this.extractContents()),this.insertNode(a).selectNode(a)},isControl:function(){var a=this,b=a.startContainer,c=a.startOffset,d=a.endContainer,e=a.endOffset;return 1==b.nodeType&&b===d&&c+1===e&&K(b.childNodes[c]).isControl()},get:function(a){var b,c=this,d=c.doc;if(!_IERANGE){b=d.createRange();try{b.setStart(c.startContainer,c.startOffset),b.setEnd(c.endContainer,c.endOffset)}catch(e){}return b}if(a&&c.isControl())return b=d.body.createControlRange(),b.addElement(c.startContainer.childNodes[c.startOffset]),b;var f=c.cloneRange().down();return b=d.body.createTextRange(),b.setEndPoint("StartToStart",_getEndRange(f.startContainer,f.startOffset)),b.setEndPoint("EndToStart",_getEndRange(f.endContainer,f.endOffset)),b},html:function(){return K(this.cloneContents()).outer()},down:function(){function a(a,c,d){if(1==a.nodeType){var e=K(a).children();if(0!==e.length){var f,g,h,i;c>0&&(f=e.eq(c-1)),c<e.length&&(g=e.eq(c)),f&&3==f.type&&(h=f[0],i=h.nodeValue.length),g&&3==g.type&&(h=g[0],i=0),h&&(d?b.setStart(h,i):b.setEnd(h,i))}}}var b=this;return a(b.startContainer,b.startOffset,!0),a(b.endContainer,b.endOffset,!1),b},up:function(){function a(a,c,d){3==a.nodeType&&(0===c?d?b.setStartBefore(a):b.setEndBefore(a):c==a.nodeValue.length&&(d?b.setStartAfter(a):b.setEndAfter(a)))}var b=this;return a(b.startContainer,b.startOffset,!0),a(b.endContainer,b.endOffset,!1),b},enlarge:function(a){function b(b,d,e){var f,g=K(b);if(!(3==g.type||_NOSPLIT_TAG_MAP[g.name]||!a&&g.isBlock()))if(0===d){for(;!g.prev()&&(f=g.parent(),f&&!_NOSPLIT_TAG_MAP[f.name]&&(a||!f.isBlock()));)g=f;e?c.setStartBefore(g[0]):c.setEndBefore(g[0])}else if(d==g.children().length){for(;!g.next()&&(f=g.parent(),f&&!_NOSPLIT_TAG_MAP[f.name]&&(a||!f.isBlock()));)g=f;e?c.setStartAfter(g[0]):c.setEndAfter(g[0])}}var c=this;return c.up(),b(c.startContainer,c.startOffset,!0),b(c.endContainer,c.endOffset,!1),c},shrink:function(){for(var a,b=this,c=b.collapsed;1==b.startContainer.nodeType&&(a=b.startContainer.childNodes[b.startOffset])&&1==a.nodeType&&!K(a).isSingle();)b.setStart(a,0);if(c)return b.collapse(c);for(;1==b.endContainer.nodeType&&b.endOffset>0&&(a=b.endContainer.childNodes[b.endOffset-1])&&1==a.nodeType&&!K(a).isSingle();)b.setEnd(a,a.childNodes.length);return b},createBookmark:function(a){var b,c=this,d=c.doc,e=K('<span style="display:none;"></span>',d)[0];return e.id="__kindeditor_bookmark_start_"+_BOOKMARK_ID++ +"__",c.collapsed||(b=e.cloneNode(!0),b.id="__kindeditor_bookmark_end_"+_BOOKMARK_ID++ +"__"),b&&c.cloneRange().collapse(!1).insertNode(b).setEndBefore(b),c.insertNode(e).setStartAfter(e),{start:a?"#"+e.id:e,end:b?a?"#"+b.id:b:null}},moveToBookmark:function(a){var b=this,c=b.doc,d=K(a.start,c),e=a.end?K(a.end,c):null;return!d||d.length<1?b:(b.setStartBefore(d[0]),d.remove(),e&&e.length>0?(b.setEndBefore(e[0]),e.remove()):b.collapse(!0),b)},dump:function(){console.log("--------------------"),console.log(3==this.startContainer.nodeType?this.startContainer.nodeValue:this.startContainer,this.startOffset),console.log(3==this.endContainer.nodeType?this.endContainer.nodeValue:this.endContainer,this.endOffset)}}),K.RangeClass=KRange,K.range=_range,K.START_TO_START=_START_TO_START,K.START_TO_END=_START_TO_END,K.END_TO_END=_END_TO_END,K.END_TO_START=_END_TO_START,_extend(KCmd,{init:function(a){var b=this,c=a.doc;b.doc=c,b.win=_getWin(c),b.sel=_getSel(c),b.range=a},selection:function(a){var b=this,c=b.doc,d=_getRng(c);return b.sel=_getSel(c),d?(b.range=_range(d),"html"==K(b.range.startContainer).name&&b.range.selectNodeContents(c.body).collapse(!1),b):(a&&b.range.selectNodeContents(c.body).collapse(!1),b)},select:function(a){a=_undef(a,!0);var b,c=this,d=c.sel,e=c.range.cloneRange().shrink(),f=e.startContainer,g=e.startOffset,h=(e.endContainer,e.endOffset,_getDoc(f)),i=c.win,j=!1;if(a&&1==f.nodeType&&e.collapsed){if(_IERANGE){var k=K("<span>&nbsp;</span>",h);e.insertNode(k[0]),b=h.body.createTextRange();try{b.moveToElementText(k[0])}catch(l){}return b.collapse(!1),b.select(),k.remove(),i.focus(),c}if(_WEBKIT){var m=f.childNodes;(K(f).isInline()||g>0&&K(m[g-1]).isInline()||m[g]&&K(m[g]).isInline())&&(e.insertNode(h.createTextNode("​")),j=!0)}}if(_IERANGE)try{b=e.get(!0),b.select()}catch(n){}else if(j&&e.collapse(!1),b=e.get(!0),d.removeAllRanges(),d.addRange(b),h!==document){var o=K(b.endContainer).pos();i.scrollTo(o.x,o.y)}return i.focus(),c},wrap:function(a){var b,c=this,d=c.doc,e=c.range;if(b=K(a,d),e.collapsed)return e.shrink(),e.insertNode(b[0]).selectNodeContents(b[0]),c;if(b.isBlock()){for(var f=b.clone(!0),g=f;g.first();)g=g.first();return g.append(e.extractContents()),e.insertNode(f[0]).selectNode(f[0]),c}e.enlarge();var h=e.createBookmark(),i=e.commonAncestor(),j=!1;return K(i).scan(function(a){if(!j&&a==h.start)return void(j=!0);if(j){if(a==h.end)return!1;var c=K(a);if(_inPreElement(c))return;if(3==c.type&&_trim(a.nodeValue).length>0){for(var d;(d=c.parent())&&d.isStyle()&&1==d.children().length;)c=d;_wrapNode(c,b)}}}),e.moveToBookmark(h),c},split:function(a,b){for(var c,d=this.range,e=d.doc,f=d.cloneRange().collapse(a),g=f.startContainer,h=f.startOffset,i=3==g.nodeType?g.parentNode:g,j=!1;i&&i.parentNode;){if(c=K(i),b){if(!c.isStyle())break;if(!_hasAttrOrCss(c,b))break}else if(_NOSPLIT_TAG_MAP[c.name])break;j=!0,i=i.parentNode}if(j){var k=e.createElement("span");d.cloneRange().collapse(!a).insertNode(k),a?f.setStartBefore(i.firstChild).setEnd(g,h):f.setStart(g,h).setEndAfter(i.lastChild);var l=f.extractContents(),m=l.firstChild,n=l.lastChild;a?(f.insertNode(l),d.setStartAfter(n).setEndBefore(k)):(i.appendChild(l),d.setStartBefore(k).setEndBefore(m));var o=k.parentNode;if(o==d.endContainer){var p=K(k).prev(),q=K(k).next();p&&q&&3==p.type&&3==q.type?d.setEnd(p[0],p[0].nodeValue.length):a||d.setEnd(d.endContainer,d.endOffset-1)}o.removeChild(k)}return this},remove:function(a){var b=this,c=b.doc,d=b.range;if(d.enlarge(),0===d.startOffset){for(var e,f=K(d.startContainer);(e=f.parent())&&e.isStyle()&&1==e.children().length;)f=e;d.setStart(f[0],0),f=K(d.startContainer),f.isBlock()&&_removeAttrOrCss(f,a);var g=f.parent();g&&g.isBlock()&&_removeAttrOrCss(g,a)}var h,i;if(d.collapsed){if(b.split(!0,a),h=d.startContainer,i=d.startOffset,i>0){var j=K(h.childNodes[i-1]);j&&_isEmptyNode(j)&&(j.remove(),d.setStart(h,i-1))}var k=K(h.childNodes[i]);return k&&_isEmptyNode(k)&&k.remove(),_isEmptyNode(h)&&(d.startBefore(h),h.remove()),d.collapse(!0),b}b.split(!0,a),b.split(!1,a);var l=c.createElement("span"),m=c.createElement("span");d.cloneRange().collapse(!1).insertNode(m),d.cloneRange().collapse(!0).insertNode(l);var n=[],o=!1;K(d.commonAncestor()).scan(function(a){return o||a!=l?a==m?!1:void(o&&n.push(a)):void(o=!0)}),K(l).remove(),K(m).remove(),h=d.startContainer,i=d.startOffset;var p=d.endContainer,q=d.endOffset;if(i>0){var r=K(h.childNodes[i-1]);r&&_isEmptyNode(r)&&(r.remove(),d.setStart(h,i-1),h==p&&d.setEnd(p,q-1));var s=K(h.childNodes[i]);s&&_isEmptyNode(s)&&(s.remove(),h==p&&d.setEnd(p,q-1))}var t=K(p.childNodes[d.endOffset]);t&&_isEmptyNode(t)&&t.remove();var u=d.createBookmark(!0);return _each(n,function(b,c){_removeAttrOrCss(K(c),a)}),d.moveToBookmark(u),b},commonNode:function(a){function b(b){for(var c=b,d=b;d;){if(_hasAttrOrCss(K(d),a))return K(d);d=d.parentNode}for(;c&&(c=c.lastChild);)if(_hasAttrOrCss(K(c),a))return K(c);return null}var c=this.range,d=c.endContainer,e=c.endOffset,f=3==d.nodeType||0===e?d:d.childNodes[e-1],g=b(f);if(g)return g;if(1==f.nodeType||3==d.nodeType&&0===e){var h=K(f).prev();if(h)return b(h)}return null},commonAncestor:function(a){function b(b){for(;b;){if(1==b.nodeType&&b.tagName.toLowerCase()===a)return b;b=b.parentNode}return null}var c=this.range,d=c.startContainer,e=c.startOffset,f=c.endContainer,g=c.endOffset,h=3==d.nodeType||0===e?d:d.childNodes[e-1],i=3==f.nodeType||0===g?f:f.childNodes[g-1],j=b(h),k=b(i);return j&&k&&j===k?K(j):null},state:function(a){var b=this,c=b.doc,d=!1;try{d=c.queryCommandState(a)}catch(e){}return d},val:function(a){function b(a){return a.toLowerCase()}{var c=this,d=c.doc;c.range}a=b(a);var e,f="";return"fontfamily"===a||"fontname"===a?(f=_nativeCommandValue(d,"fontname"),f=f.replace(/['"]/g,""),b(f)):"formatblock"===a?(f=_nativeCommandValue(d,a),""===f&&(e=c.commonNode({"h1,h2,h3,h4,h5,h6,p,div,pre,address":"*"}),e&&(f=e.name)),"Normal"===f&&(f="p"),b(f)):"fontsize"===a?(e=c.commonNode({"*":".font-size"}),e&&(f=e.css("font-size")),b(f)):"forecolor"===a?(e=c.commonNode({"*":".color"}),e&&(f=e.css("color")),f=_toHex(f),""===f&&(f="default"),b(f)):"hilitecolor"===a?(e=c.commonNode({"*":".background-color"}),e&&(f=e.css("background-color")),f=_toHex(f),""===f&&(f="default"),b(f)):f},toggle:function(a,b){var c=this;return c.commonNode(b)?c.remove(b):c.wrap(a),c.select()},bold:function(){return this.toggle("<strong></strong>",{span:".font-weight=bold",strong:"*",b:"*"})},italic:function(){return this.toggle("<em></em>",{span:".font-style=italic",em:"*",i:"*"})},underline:function(){return this.toggle("<u></u>",{span:".text-decoration=underline",u:"*"})},strikethrough:function(){return this.toggle("<s></s>",{span:".text-decoration=line-through",s:"*"})},forecolor:function(a){return this.wrap('<span style="color:'+a+';"></span>').select()},hilitecolor:function(a){return this.wrap('<span style="background-color:'+a+';"></span>').select()},fontsize:function(a){return this.wrap('<span style="font-size:'+a+';"></span>').select()},fontname:function(a){return this.fontfamily(a)},fontfamily:function(a){return this.wrap('<span style="font-family:'+a+';"></span>').select()},removeformat:function(){var a={"*":".font-weight,.font-style,.text-decoration,.color,.background-color,.font-size,.font-family,.text-indent"},b=_STYLE_TAG_MAP;return _each(b,function(b){a[b]="*"}),this.remove(a),this.select()},inserthtml:function(a,b){function c(a,b){b='<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />'+b;var c=a.get();c.item?c.item(0).outerHTML=b:c.pasteHTML(b);var d=a.doc.getElementById("__kindeditor_temp_tag__");d.parentNode.removeChild(d);var f=_toRange(c);a.setEnd(f.endContainer,f.endOffset),a.collapse(!1),e.select(!1)}function d(a,b){var c=a.doc,d=c.createDocumentFragment();K("@"+b,c).each(function(){d.appendChild(this)}),a.deleteContents(),a.insertNode(d),a.collapse(!1),e.select(!1)}var e=this,f=e.range;if(""===a)return e;if(_IERANGE&&b){try{c(f,a)}catch(g){d(f,a)}return e}return d(f,a),e},hr:function(){return this.inserthtml("<hr />")},print:function(){return this.win.print(),this},insertimage:function(a,b,c,d,e,f){b=_undef(b,""),e=_undef(e,0);var g='<img src="'+_escape(a)+'" data-ke-src="'+_escape(a)+'" ';return c&&(g+='width="'+_escape(c)+'" '),d&&(g+='height="'+_escape(d)+'" '),b&&(g+='title="'+_escape(b)+'" '),f&&(g+='align="'+_escape(f)+'" '),g+='alt="'+_escape(b)+'" ',g+="/>",this.inserthtml(g)},createlink:function(a,b){function c(a,b,c){K(a).attr("href",b).attr("data-ke-src",b),c?K(a).attr("target",c):K(a).removeAttr("target")}var d=this,e=d.doc,f=d.range;d.select();var g=d.commonNode({a:"*"});g&&!f.isControl()&&(f.selectNode(g.get()),d.select());var h='<a href="'+_escape(a)+'" data-ke-src="'+_escape(a)+'" ';if(b&&(h+=' target="'+_escape(b)+'"'),f.collapsed)return h+=">"+_escape(a)+"</a>",d.inserthtml(h);if(f.isControl()){var i=K(f.startContainer.childNodes[f.startOffset]);return h+="></a>",i.after(K(h,e)),i.next().append(i),f.selectNode(i[0]),d.select()}var j=f.startContainer,k=f.startOffset,l=f.endContainer,m=f.endOffset;if(1==j.nodeType&&j===l&&k+1===m){var n=j.childNodes[k];if("a"==n.nodeName.toLowerCase())return c(n,a,b),d +}return _nativeCommand(e,"createlink","__kindeditor_temp_url__"),K('a[href="__kindeditor_temp_url__"]',e).each(function(){c(this,a,b)}),d},unlink:function(){var a=this,b=a.doc,c=a.range;if(a.select(),c.collapsed){var d=a.commonNode({a:"*"});if(d&&(c.selectNode(d.get()),a.select()),_nativeCommand(b,"unlink",null),_WEBKIT&&"img"===K(c.startContainer).name){var e=K(c.startContainer).parent();"a"===e.name&&e.remove(!0)}}else _nativeCommand(b,"unlink",null);return a}}),_each("formatblock,selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,indent,outdent,subscript,superscript".split(","),function(a,b){KCmd.prototype[b]=function(a){var c=this;return c.select(),_nativeCommand(c.doc,b,a),_IERANGE&&_inArray(b,"justifyleft,justifycenter,justifyright,justifyfull".split(","))>=0&&c.selection(),(!_IERANGE||_inArray(b,"formatblock,selectall,insertorderedlist,insertunorderedlist".split(","))>=0)&&c.selection(),c}}),_each("cut,copy,paste".split(","),function(a,b){KCmd.prototype[b]=function(){var a=this;if(!a.doc.queryCommandSupported(b))throw"not supported";return a.select(),_nativeCommand(a.doc,b,null),a}}),K.CmdClass=KCmd,K.cmd=_cmd,_extend(KWidget,{init:function(a){var b=this;if(b.name=a.name||"",b.doc=a.doc||document,b.win=_getWin(b.doc),b.x=_addUnit(a.x),b.y=_addUnit(a.y),b.z=a.z,b.width=_addUnit(a.width),b.height=_addUnit(a.height),b.div=K('<div style="display:block;"></div>'),b.options=a,b._alignEl=a.alignEl,b.width&&b.div.css("width",b.width),b.height&&b.div.css("height",b.height),b.z&&b.div.css({position:"absolute",left:b.x,top:b.y,"z-index":b.z}),!b.z||b.x!==undefined&&b.y!==undefined||b.autoPos(b.width,b.height),a.cls&&b.div.addClass(a.cls),a.shadowMode&&b.div.addClass("ke-shadow"),a.css&&b.div.css(a.css),a.src?K(a.src).replaceWith(b.div):K(b.doc.body).append(b.div),a.html&&b.div.html(a.html),a.autoScroll)if(_IE&&7>_V||_QUIRKS){var c=_getScrollPos();K(b.win).bind("scroll",function(){var a=_getScrollPos(),d=a.x-c.x,e=a.y-c.y;b.pos(_removeUnit(b.x)+d,_removeUnit(b.y)+e,!1)})}else b.div.css("position","fixed")},pos:function(a,b,c){var d=this;return c=_undef(c,!0),null!==a&&(a=0>a?0:_addUnit(a),d.div.css("left",a),c&&(d.x=a)),null!==b&&(b=0>b?0:_addUnit(b),d.div.css("top",b),c&&(d.y=b)),d},autoPos:function(a,b){var c=this,d=_removeUnit(a)||0,e=_removeUnit(b)||0,f=_getScrollPos();if(c._alignEl){var g=K(c._alignEl),h=g.pos(),i=_round(g[0].clientWidth/2-d/2),j=_round(g[0].clientHeight/2-e/2);x=0>i?h.x:h.x+i,y=0>j?h.y:h.y+j}else{var k=_docElement(c.doc);x=_round(f.x+(k.clientWidth-d)/2),y=_round(f.y+(k.clientHeight-e)/2)}return _IE&&7>_V||_QUIRKS||(x-=f.x,y-=f.y),c.pos(x,y)},remove:function(){var a=this;return(_IE&&7>_V||_QUIRKS)&&K(a.win).unbind("scroll"),a.div.remove(),_each(a,function(b){a[b]=null}),this},show:function(){return this.div.show(),this},hide:function(){return this.div.hide(),this},draggable:function(a){var b=this;return a=a||{},a.moveEl=b.div,a.moveFn=function(a,c,d,e,f,g){(a+=f)<0&&(a=0),(c+=g)<0&&(c=0),b.pos(a,c)},_drag(a),b}}),K.WidgetClass=KWidget,K.widget=_widget;var html,_direction="";(html=document.getElementsByTagName("html"))&&(_direction=html[0].dir),_extend(KEdit,KWidget,{init:function(a){function b(){var b=_iframeDoc(c.iframe);b.open(),h&&(b.domain=document.domain),b.write(_getInitHtml(d,e,f,g)),b.close(),c.win=c.iframe[0].contentWindow,c.doc=b;var i=_cmd(b);c.afterChange(function(){i.selection()}),_WEBKIT&&K(b).click(function(a){"img"===K(a.target).name&&(i.selection(!0),i.range.selectNode(a.target),i.select())}),_IE&&(c._mousedownHandler=function(){var a=i.range.cloneRange();a.shrink(),a.isControl()&&c.blur()},K(document).mousedown(c._mousedownHandler),K(b).keydown(function(a){if(8==a.which){i.selection();var b=i.range;b.isControl()&&(b.collapse(!0),K(b.startContainer.childNodes[b.startOffset]).remove(),a.preventDefault())}})),c.cmd=i,c.html(_elementVal(c.srcElement)),_IE?(b.body.disabled=!0,b.body.contentEditable=!0,b.body.removeAttribute("disabled")):b.designMode="on",a.afterCreate&&a.afterCreate.call(c)}var c=this;KEdit.parent.init.call(c,a),c.srcElement=K(a.srcElement),c.div.addClass("ke-edit"),c.designMode=_undef(a.designMode,!0),c.beforeGetHtml=a.beforeGetHtml,c.beforeSetHtml=a.beforeSetHtml,c.afterSetHtml=a.afterSetHtml;var d=_undef(a.themesPath,""),e=a.bodyClass,f=a.cssPath,g=a.cssData,h="res:"!=location.protocol&&location.host.replace(/:\d+/,"")!==document.domain,i="document.open();"+(h?'document.domain="'+document.domain+'";':"")+"document.close();",j=_IE?' src="javascript:void(function(){'+encodeURIComponent(i)+'}())"':"";c.iframe=K('<iframe class="ke-edit-iframe" hidefocus="true" frameborder="0"'+j+"></iframe>").css("width","100%"),c.textarea=K('<textarea class="ke-edit-textarea" hidefocus="true"></textarea>').css("width","100%"),c.tabIndex=isNaN(parseInt(a.tabIndex,10))?c.srcElement.attr("tabindex"):parseInt(a.tabIndex,10),c.iframe.attr("tabindex",c.tabIndex),c.textarea.attr("tabindex",c.tabIndex),c.width&&c.setWidth(c.width),c.height&&c.setHeight(c.height),c.designMode?c.textarea.hide():c.iframe.hide(),h&&c.iframe.bind("load",function(){c.iframe.unbind("load"),_IE?b():setTimeout(b,0)}),c.div.append(c.iframe),c.div.append(c.textarea),c.srcElement.hide(),!h&&b()},setWidth:function(a){var b=this;return a=_addUnit(a),b.width=a,b.div.css("width",a),b},setHeight:function(a){var b=this;return a=_addUnit(a),b.height=a,b.div.css("height",a),b.iframe.css("height",a),(_IE&&8>_V||_QUIRKS)&&(a=_addUnit(_removeUnit(a)-2)),b.textarea.css("height",a),b},remove:function(){var a=this,b=a.doc;K(b.body).unbind(),K(b).unbind(),K(a.win).unbind(),a._mousedownHandler&&K(document).unbind("mousedown",a._mousedownHandler),_elementVal(a.srcElement,a.html()),a.srcElement.show(),a.iframe.unbind(),a.textarea.unbind(),KEdit.parent.remove.call(a)},html:function(a,b){var c=this,d=c.doc;if(c.designMode){var e=d.body;return a===undefined?(a=b?"<!doctype html><html>"+e.parentNode.innerHTML+"</html>":e.innerHTML,c.beforeGetHtml&&(a=c.beforeGetHtml(a)),_GECKO&&"<br />"==a&&(a=""),a):(c.beforeSetHtml&&(a=c.beforeSetHtml(a)),_IE&&_V>=9&&(a=a.replace(/(<.*?checked=")checked(".*>)/gi,"$1$2")),K(e).html(a),c.afterSetHtml&&c.afterSetHtml(),c)}return a===undefined?c.textarea.val():(c.textarea.val(a),c)},design:function(a){var b,c=this;if(a===undefined?!c.designMode:a){if(!c.designMode){b=c.html(),c.designMode=!0,c.textarea.hide(),c.html(b);var d=c.iframe,e=_removeUnit(c.height);d.height(e-2),d.show(),setTimeout(function(){d.height(e)},0)}}else c.designMode&&(b=c.html(),c.designMode=!1,c.html(b),c.iframe.hide(),c.textarea.show());return c.focus()},focus:function(){var a=this;return a.designMode?a.win.focus():a.textarea[0].focus(),a},blur:function(){var a=this;if(_IE){var b=K('<input type="text" style="float:left;width:0;height:0;padding:0;margin:0;border:0;" value="" />',a.div);a.div.append(b),b[0].focus(),b.remove()}else a.designMode?a.win.blur():a.textarea[0].blur();return a},afterChange:function(a){function b(b){setTimeout(function(){a(b)},1)}var c=this,d=c.doc,e=d.body;return K(d).keyup(function(b){b.ctrlKey||b.altKey||!_CHANGE_KEY_MAP[b.which]||a(b)}),K(d).mouseup(a).contextmenu(a),K(c.win).blur(a),K(e).bind("paste",b),K(e).bind("cut",b),c}}),K.EditClass=KEdit,K.edit=_edit,K.iframeDoc=_iframeDoc,_extend(KToolbar,KWidget,{init:function(a){function b(a){var b=K(a);return b.hasClass("ke-outline")?b:b.hasClass("ke-toolbar-icon")?b.parent():void 0}function c(a,c){var d=b(a.target);if(d){if(d.hasClass("ke-disabled"))return;if(d.hasClass("ke-selected"))return;d[c]("ke-on")}}var d=this;KToolbar.parent.init.call(d,a),d.disableMode=_undef(a.disableMode,!1),d.noDisableItemMap=_toMap(_undef(a.noDisableItems,[])),d._itemMap={},d.div.addClass("ke-toolbar").bind("contextmenu,mousedown,mousemove",function(a){a.preventDefault()}).attr("unselectable","on"),d.div.mouseover(function(a){c(a,"addClass")}).mouseout(function(a){c(a,"removeClass")}).click(function(a){var c=b(a.target);if(c){if(c.hasClass("ke-disabled"))return;d.options.click.call(this,a,c.attr("data-name"))}})},get:function(a){return this._itemMap[a]?this._itemMap[a]:this._itemMap[a]=K("span.ke-icon-"+a,this.div).parent()},select:function(a){return _selectToolbar.call(this,a,function(a){a.addClass("ke-selected")}),self},unselect:function(a){return _selectToolbar.call(this,a,function(a){a.removeClass("ke-selected").removeClass("ke-on")}),self},enable:function(a){var b=this,c=a.get?a:b.get(a);return c&&(c.removeClass("ke-disabled"),c.opacity(1)),b},disable:function(a){var b=this,c=a.get?a:b.get(a);return c&&(c.removeClass("ke-selected").addClass("ke-disabled"),c.opacity(.5)),b},disableAll:function(a,b){var c=this,d=c.noDisableItemMap;return b&&(d=_toMap(b)),(a===undefined?!c.disableMode:a)?(K("span.ke-outline",c.div).each(function(){var a=K(this),b=a[0].getAttribute("data-name",2);d[b]||c.disable(a)}),c.disableMode=!0):(K("span.ke-outline",c.div).each(function(){var a=K(this),b=a[0].getAttribute("data-name",2);d[b]||c.enable(a)}),c.disableMode=!1),c}}),K.ToolbarClass=KToolbar,K.toolbar=_toolbar,_extend(KMenu,KWidget,{init:function(a){var b=this;a.z=a.z||811213,KMenu.parent.init.call(b,a),b.centerLineMode=_undef(a.centerLineMode,!0),b.div.addClass("ke-menu").bind("click,mousedown",function(a){a.stopPropagation()}).attr("unselectable","on")},addItem:function(a){var b=this;if("-"===a.title)return void b.div.append(K('<div class="ke-menu-separator"></div>'));var c=K('<div class="ke-menu-item" unselectable="on"></div>'),d=K('<div class="ke-inline-block ke-menu-item-left"></div>'),e=K('<div class="ke-inline-block ke-menu-item-right"></div>'),f=_addUnit(a.height),g=_undef(a.iconClass,"");b.div.append(c),f&&(c.css("height",f),e.css("line-height",f));var h;return b.centerLineMode&&(h=K('<div class="ke-inline-block ke-menu-item-center"></div>'),f&&h.css("height",f)),c.mouseover(function(){K(this).addClass("ke-menu-item-on"),h&&h.addClass("ke-menu-item-center-on")}).mouseout(function(){K(this).removeClass("ke-menu-item-on"),h&&h.removeClass("ke-menu-item-center-on")}).click(function(b){a.click.call(K(this)),b.stopPropagation()}).append(d),h&&c.append(h),c.append(e),a.checked&&(g="ke-icon-checked"),""!==g&&d.html('<span class="ke-inline-block ke-toolbar-icon ke-toolbar-icon-url '+g+'"></span>'),e.html(a.title),b},remove:function(){var a=this;return a.options.beforeRemove&&a.options.beforeRemove.call(a),K(".ke-menu-item",a.div[0]).unbind(),KMenu.parent.remove.call(a),a}}),K.MenuClass=KMenu,K.menu=_menu,_extend(KColorPicker,KWidget,{init:function(a){var b=this;a.z=a.z||811213,KColorPicker.parent.init.call(b,a);var c=a.colors||[["#E53333","#E56600","#FF9900","#64451D","#DFC5A4","#FFE500"],["#009900","#006600","#99BB00","#B8D100","#60D978","#00D5FF"],["#337FE5","#003399","#4C33E5","#9933E5","#CC33E5","#EE33EE"],["#FFFFFF","#CCCCCC","#999999","#666666","#333333","#000000"]];b.selectedColor=(a.selectedColor||"").toLowerCase(),b._cells=[],b.div.addClass("ke-colorpicker").bind("click,mousedown",function(a){a.stopPropagation()}).attr("unselectable","on");var d=b.doc.createElement("table");b.div.append(d),d.className="ke-colorpicker-table",d.cellPadding=0,d.cellSpacing=0,d.border=0;var e=d.insertRow(0),f=e.insertCell(0);f.colSpan=c[0].length,b._addAttr(f,"","ke-colorpicker-cell-top");for(var g=0;g<c.length;g++){e=d.insertRow(g+1);for(var h=0;h<c[g].length;h++)f=e.insertCell(h),b._addAttr(f,c[g][h],"ke-colorpicker-cell")}},_addAttr:function(a,b,c){var d=this;a=K(a).addClass(c),d.selectedColor===b.toLowerCase()&&a.addClass("ke-colorpicker-cell-selected"),a.attr("title",b||d.options.noColor),a.mouseover(function(){K(this).addClass("ke-colorpicker-cell-on")}),a.mouseout(function(){K(this).removeClass("ke-colorpicker-cell-on")}),a.click(function(a){a.stop(),d.options.click.call(K(this),b)}),b?a.append(K('<div class="ke-colorpicker-cell-color" unselectable="on"></div>').css("background-color",b)):a.html(d.options.noColor),K(a).attr("unselectable","on"),d._cells.push(a)},remove:function(){var a=this;return _each(a._cells,function(){this.unbind()}),KColorPicker.parent.remove.call(a),a}}),K.ColorPickerClass=KColorPicker,K.colorpicker=_colorpicker,_extend(KUploadButton,{init:function(a){var b=this,c=K(a.button),d=a.fieldName||"file",e=a.url||"",f=c.val(),g=a.extraParams||{},h=c[0].className||"",i=a.target||"kindeditor_upload_iframe_"+(new Date).getTime();a.afterError=a.afterError||function(a){alert(a)};var j=[];for(var k in g)j.push('<input type="hidden" name="'+k+'" value="'+g[k]+'" />');var l=['<div class="ke-inline-block '+h+'">',a.target?"":'<iframe name="'+i+'" style="display:none;"></iframe>',a.form?'<div class="ke-upload-area">':'<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="'+i+'" action="'+e+'">','<span class="ke-button-common">',j.join(""),'<input type="button" class="ke-button-common ke-button" value="'+f+'" />',"</span>",'<input type="file" class="ke-upload-file" name="'+d+'" tabindex="-1" />',a.form?"</div>":"</form>","</div>"].join(""),m=K(l,c.doc);c.hide(),c.before(m),b.div=m,b.button=c,b.iframe=a.target?K('iframe[name="'+i+'"]'):K("iframe",m),b.form=a.form?K(a.form):K("form",m),b.fileBox=K(".ke-upload-file",m);var n=a.width||K(".ke-button-common",m).width();K(".ke-upload-area",m).width(n),b.options=a},submit:function(){var a=this,b=a.iframe;return b.bind("load",function(){b.unbind();var c=document.createElement("form");a.fileBox.before(c),K(c).append(a.fileBox),c.reset(),K(c).remove(!0);var d,e=K.iframeDoc(b),f=e.getElementsByTagName("pre")[0],g="";g=f?f.innerHTML:e.body.innerHTML,g=_unescape(g),b[0].src="javascript:false";try{d=K.json(g)}catch(h){a.options.afterError.call(a,"<!doctype html><html>"+e.body.parentNode.innerHTML+"</html>")}d&&a.options.afterUpload.call(a,d)}),a.form[0].submit(),a},remove:function(){var a=this;return a.fileBox&&a.fileBox.unbind(),a.iframe.remove(),a.div.remove(),a.button.show(),a}}),K.UploadButtonClass=KUploadButton,K.uploadbutton=_uploadbutton,_extend(KDialog,KWidget,{init:function(a){var b=this,c=_undef(a.shadowMode,!0);a.z=a.z||811213,a.shadowMode=!1,a.autoScroll=_undef(a.autoScroll,!0),KDialog.parent.init.call(b,a);var d=a.title,e=K(a.body,b.doc),f=a.previewBtn,g=a.yesBtn,h=a.noBtn,i=a.closeBtn,j=_undef(a.showMask,!0);b.div.addClass("ke-dialog").bind("click,mousedown",function(a){a.stopPropagation()});var k=K('<div class="ke-dialog-content"></div>').appendTo(b.div);_IE&&7>_V?b.iframeMask=K('<iframe src="about:blank" class="ke-dialog-shadow"></iframe>').appendTo(b.div):c&&K('<div class="ke-dialog-shadow"></div>').appendTo(b.div);var l=K('<div class="ke-dialog-header"></div>');k.append(l),l.html(d),b.closeIcon=K('<span class="ke-dialog-icon-close" title="'+i.name+'"></span>').click(i.click),l.append(b.closeIcon),b.draggable({clickEl:l,beforeDrag:a.beforeDrag});var m=K('<div class="ke-dialog-body"></div>');k.append(m),m.append(e);var n=K('<div class="ke-dialog-footer"></div>');if((f||g||h)&&k.append(n),_each([{btn:f,name:"preview"},{btn:g,name:"yes"},{btn:h,name:"no"}],function(){if(this.btn){var a=_createButton(this.btn);a.addClass("ke-dialog-"+this.name),n.append(a)}}),b.height&&m.height(_removeUnit(b.height)-l.height()-n.height()),b.div.width(b.div.width()),b.div.height(b.div.height()),b.mask=null,j){var o=_docElement(b.doc),p=Math.max(o.scrollWidth,o.clientWidth),q=Math.max(o.scrollHeight,o.clientHeight);b.mask=_widget({x:0,y:0,z:b.z-1,cls:"ke-dialog-mask",width:p,height:q})}b.autoPos(b.div.width(),b.div.height()),b.footerDiv=n,b.bodyDiv=m,b.headerDiv=l,b.isLoading=!1},setMaskIndex:function(a){var b=this;b.mask.div.css("z-index",a)},showLoading:function(a){a=_undef(a,"");var b=this,c=b.bodyDiv;return b.loading=K('<div class="ke-dialog-loading"><div class="ke-inline-block ke-dialog-loading-content" style="margin-top:'+Math.round(c.height()/3)+'px;">'+a+"</div></div>").width(c.width()).height(c.height()).css("top",b.headerDiv.height()+"px"),c.css("visibility","hidden").after(b.loading),b.isLoading=!0,b},hideLoading:function(){return this.loading&&this.loading.remove(),this.bodyDiv.css("visibility","visible"),this.isLoading=!1,this},remove:function(){var a=this;return a.options.beforeRemove&&a.options.beforeRemove.call(a),a.mask&&a.mask.remove(),a.iframeMask&&a.iframeMask.remove(),a.closeIcon.unbind(),K("input",a.div).unbind(),K("button",a.div).unbind(),a.footerDiv.unbind(),a.bodyDiv.unbind(),a.headerDiv.unbind(),K("iframe",a.div).each(function(){K(this).remove()}),KDialog.parent.remove.call(a),a}}),K.DialogClass=KDialog,K.dialog=_dialog,K.tabs=_tabs,K.loadScript=_loadScript,K.loadStyle=_loadStyle,K.ajax=_ajax;var _plugins={},_language={};KEditor.prototype={lang:function(a){return _lang(a,this.langType)},loadPlugin:function(a,b){var c=this,d=this._pluginStatus;return d||(d=this._pluginStatus={}),_plugins[a]?_isFunction(_plugins[a])?(d[a]||(_plugins[a].call(c,KindEditor),d[a]="inited"),b&&b.call(c),c):(setTimeout(function(){c.loadPlugin(a,b)},100),c):(_plugins[a]="loading",_loadScript(c.pluginsPath+a+"/"+a+".js?ver="+encodeURIComponent(K.DEBUG?_TIME:_VERSION),function(){setTimeout(function(){_plugins[a]&&c.loadPlugin(a,b)},0)}),c)},handler:function(a,b){var c=this;return c._handlers[a]||(c._handlers[a]=[]),_isFunction(b)?(c._handlers[a].push(b),c):(_each(c._handlers[a],function(){b=this.call(c,b)}),b)},clickToolbar:function(a,b){var c=this,d="clickToolbar"+a;return b===undefined?c._handlers[d]?c.handler(d):(c.loadPlugin(a,function(){c.handler(d)}),c):c.handler(d,b)},updateState:function(){var a=this;return _each("justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,subscript,superscript,bold,italic,underline,strikethrough".split(","),function(b,c){a.cmd.state(c)?a.toolbar.select(c):a.toolbar.unselect(c)}),a},addContextmenu:function(a){return this._contextmenus.push(a),this},afterCreate:function(a){return this.handler("afterCreate",a)},beforeRemove:function(a){return this.handler("beforeRemove",a)},beforeGetHtml:function(a){return this.handler("beforeGetHtml",a)},beforeSetHtml:function(a){return this.handler("beforeSetHtml",a)},afterSetHtml:function(a){return this.handler("afterSetHtml",a)},create:function(){function a(){return 0===i.height()?void setTimeout(a,100):void b.resize(d,e,!1)}var b=this,c=b.fullscreenMode;if(b.isCreated)return b;if(b.srcElement.data("kindeditor"))return b;b.srcElement.data("kindeditor","true"),_docElement().style.overflow=c?"hidden":"";var d=c?_docElement().clientWidth+"px":b.width,e=c?_docElement().clientHeight+"px":b.height;(_IE&&8>_V||_QUIRKS)&&(e=_addUnit(_removeUnit(e)+2));var f=b.container=K(b.layout);c?K(document.body).append(f):b.srcElement.before(f);var g=K(".toolbar",f),h=K(".edit",f),i=b.statusbar=K(".statusbar",f);f.removeClass("container").addClass("ke-container ke-container-"+b.themeType).css("width",d),c?(f.css({position:"absolute",left:0,top:0,"z-index":811211}),_GECKO||(b._scrollPos=_getScrollPos()),window.scrollTo(0,0),K(document.body).css({height:"1px",overflow:"hidden"}),K(document.body.parentNode).css("overflow","hidden"),b._fullscreenExecuted=!0):(b._fullscreenExecuted&&(K(document.body).css({height:"",overflow:""}),K(document.body.parentNode).css("overflow","")),b._scrollPos&&window.scrollTo(b._scrollPos.x,b._scrollPos.y));var j=[];K.each(b.items,function(a,c){"|"==c?j.push('<span class="ke-inline-block ke-separator"></span>'):"/"==c?j.push('<div class="ke-hr"></div>'):(j.push('<span class="ke-outline" data-name="'+c+'" title="'+b.lang(c)+'" unselectable="on">'),j.push('<span class="ke-toolbar-icon ke-toolbar-icon-url ke-icon-'+c+'" unselectable="on"></span></span>'))});var k=b.toolbar=_toolbar({src:g,html:j.join(""),noDisableItems:b.noDisableItems,click:function(a,c){if(a.stop(),b.menu){var d=b.menu.name;if(b.hideMenu(),d===c)return}b.clickToolbar(c)}}),l=_removeUnit(e)-k.div.height(),m=b.edit=_edit({height:l>0&&_removeUnit(e)>b.minHeight?l:b.minHeight,src:h,srcElement:b.srcElement,designMode:b.designMode,themesPath:b.themesPath,bodyClass:b.bodyClass,cssPath:b.cssPath,cssData:b.cssData,beforeGetHtml:function(a){return a=b.beforeGetHtml(a),a=_removeBookmarkTag(_removeTempTag(a)),_formatHtml(a,b.filterMode?b.htmlTags:null,b.urlType,b.wellFormatMode,b.indentChar)},beforeSetHtml:function(a){return a=_formatHtml(a,b.filterMode?b.htmlTags:null,"",!1),b.beforeSetHtml(a)},afterSetHtml:function(){b.edit=m=this,b.afterSetHtml()},afterCreate:function(){if(b.edit=m=this,b.cmd=m.cmd,b._docMousedownFn=function(){b.menu&&b.hideMenu()},K(m.doc,document).mousedown(b._docMousedownFn),_bindContextmenuEvent.call(b),_bindNewlineEvent.call(b),_bindTabEvent.call(b),_bindFocusEvent.call(b),m.afterChange(function(){m.designMode&&(b.updateState(),b.addBookmark(),b.options.afterChange&&b.options.afterChange.call(b))}),m.textarea.keyup(function(a){a.ctrlKey||a.altKey||!_INPUT_KEY_MAP[a.which]||b.options.afterChange&&b.options.afterChange.call(b)}),b.readonlyMode&&b.readonly(),b.isCreated=!0,""===b.initContent&&(b.initContent=b.html()),b._undoStack.length>0){var a=b._undoStack.pop();a.start&&(b.html(a.html),m.cmd.range.moveToBookmark(a),b.select())}b.afterCreate(),b.options.afterCreate&&b.options.afterCreate.call(b)}});return i.removeClass("statusbar").addClass("ke-statusbar").append('<span class="ke-inline-block ke-statusbar-center-icon"></span>').append('<span class="ke-inline-block ke-statusbar-right-icon"></span>'),b._fullscreenResizeHandler&&(K(window).unbind("resize",b._fullscreenResizeHandler),b._fullscreenResizeHandler=null),a(),c?(b._fullscreenResizeHandler=function(){b.isCreated&&b.resize(_docElement().clientWidth,_docElement().clientHeight,!1)},K(window).bind("resize",b._fullscreenResizeHandler),k.select("fullscreen"),i.first().css("visibility","hidden"),i.last().css("visibility","hidden")):(_GECKO&&K(window).bind("scroll",function(){b._scrollPos=_getScrollPos()}),b.resizeType>0?_drag({moveEl:f,clickEl:i,moveFn:function(a,c,d,e,f,g){e+=g,b.resize(null,e)}}):i.first().css("visibility","hidden"),2===b.resizeType?_drag({moveEl:f,clickEl:i.last(),moveFn:function(a,c,d,e,f,g){d+=f,e+=g,b.resize(d,e)}}):i.last().css("visibility","hidden")),b},remove:function(){var a=this;return a.isCreated?(a.beforeRemove(),a.srcElement.data("kindeditor",""),a.menu&&a.hideMenu(),_each(a.dialogs,function(){a.hideDialog()}),K(document).unbind("mousedown",a._docMousedownFn),a.toolbar.remove(),a.edit.remove(),a.statusbar.last().unbind(),a.statusbar.unbind(),a.container.remove(),a.container=a.toolbar=a.edit=a.menu=null,a.dialogs=[],a.isCreated=!1,a):a},resize:function(a,b,c){var d=this;return c=_undef(c,!0),a&&(/%/.test(a)||(a=_removeUnit(a),a=a<d.minWidth?d.minWidth:a),d.container.css("width",_addUnit(a)),c&&(d.width=_addUnit(a))),b&&(b=_removeUnit(b),editHeight=_removeUnit(b)-d.toolbar.div.height()-d.statusbar.height(),editHeight=editHeight<d.minHeight?d.minHeight:editHeight,d.edit.setHeight(editHeight),c&&(d.height=_addUnit(b))),d},select:function(){return this.isCreated&&this.cmd.select(),this},html:function(a){var b=this;return a===undefined?b.isCreated?b.edit.html():_elementVal(b.srcElement):(b.isCreated?b.edit.html(a):_elementVal(b.srcElement,a),b.isCreated&&b.cmd.selection(),b)},fullHtml:function(){return this.isCreated?this.edit.html(undefined,!0):""},text:function(a){var b=this;return a===undefined?_trim(b.html().replace(/<(?!img|embed).*?>/gi,"").replace(/&nbsp;/gi," ")):b.html(_escape(a))},isEmpty:function(){return""===_trim(this.text().replace(/\r\n|\n|\r/,""))},isDirty:function(){return _trim(this.initContent.replace(/\r\n|\n|\r|t/g,""))!==_trim(this.html().replace(/\r\n|\n|\r|t/g,""))},selectedHtml:function(){var a=this.isCreated?this.cmd.range.html():"";return a=_removeBookmarkTag(_removeTempTag(a))},count:function(a){var b=this;return a=(a||"html").toLowerCase(),"html"===a?b.html().length:"text"===a?b.text().replace(/<(?:img|embed).*?>/gi,"K").replace(/\r\n|\n|\r/g,"").length:0},exec:function(a){a=a.toLowerCase();var b=this,c=b.cmd,d=_inArray(a,"selectall,copy,paste,print".split(","))<0;return d&&b.addBookmark(!1),c[a].apply(c,_toArray(arguments,1)),d&&(b.updateState(),b.addBookmark(!1),b.options.afterChange&&b.options.afterChange.call(b)),b},insertHtml:function(a,b){return this.isCreated?(a=this.beforeSetHtml(a),this.exec("inserthtml",a,b),this):this},appendHtml:function(a){if(this.html(this.html()+a),this.isCreated){var b=this.cmd;b.range.selectNodeContents(b.doc.body).collapse(!1),b.select()}return this},sync:function(){return _elementVal(this.srcElement,this.html()),this},focus:function(){return this.isCreated?this.edit.focus():this.srcElement[0].focus(),this},blur:function(){return this.isCreated?this.edit.blur():this.srcElement[0].blur(),this},addBookmark:function(a){a=_undef(a,!0);var b,c=this,d=c.edit,e=d.doc.body,f=_removeTempTag(e.innerHTML);if(a&&c._undoStack.length>0){var g=c._undoStack[c._undoStack.length-1];if(Math.abs(f.length-_removeBookmarkTag(g.html).length)<c.minChangeSize)return c}if(d.designMode&&!c._firstAddBookmark){var h=c.cmd.range;b=h.createBookmark(!0),b.html=_removeTempTag(e.innerHTML),h.moveToBookmark(b)}else b={html:f};return c._firstAddBookmark=!1,_addBookmarkToStack(c._undoStack,b),c},undo:function(){return _undoToRedo.call(this,this._undoStack,this._redoStack)},redo:function(){return _undoToRedo.call(this,this._redoStack,this._undoStack)},fullscreen:function(a){return this.fullscreenMode=a===undefined?!this.fullscreenMode:a,this.addBookmark(!1),this.remove().create()},readonly:function(a){a=_undef(a,!0);var b=this,c=b.edit,d=c.doc;b.designMode?b.toolbar.disableAll(a,[]):_each(b.noDisableItems,function(){b.toolbar[a?"disable":"enable"](this)}),_IE?d.body.contentEditable=!a:d.designMode=a?"off":"on",c.textarea[0].disabled=a},createMenu:function(a){var b=this,c=a.name,d=b.toolbar.get(c),e=d.pos();return a.x=e.x,a.y=e.y+d.height(),a.z=b.options.zIndex,a.shadowMode=_undef(a.shadowMode,b.shadowMode),a.selectedColor!==undefined?(a.cls="ke-colorpicker-"+b.themeType,a.noColor=b.lang("noColor"),b.menu=_colorpicker(a)):(a.cls="ke-menu-"+b.themeType,a.centerLineMode=!1,b.menu=_menu(a)),b.menu},hideMenu:function(){return this.menu.remove(),this.menu=null,this},hideContextmenu:function(){return this.contextmenu.remove(),this.contextmenu=null,this},createDialog:function(a){{var b=this;a.name}if(a.z=b.options.zIndex,a.shadowMode=_undef(a.shadowMode,b.shadowMode),a.closeBtn=_undef(a.closeBtn,{name:b.lang("close"),click:function(){b.hideDialog(),_IE&&b.cmd&&b.cmd.select()}}),a.noBtn=_undef(a.noBtn,{name:b.lang(a.yesBtn?"no":"close"),click:function(){b.hideDialog(),_IE&&b.cmd&&b.cmd.select()}}),"page"!=b.dialogAlignType&&(a.alignEl=b.container),a.cls="ke-dialog-"+b.themeType,b.dialogs.length>0){var c=b.dialogs[0],d=b.dialogs[b.dialogs.length-1];c.setMaskIndex(d.z+2),a.z=d.z+3,a.showMask=!1}var e=_dialog(a);return b.dialogs.push(e),e},hideDialog:function(){var a=this;if(a.dialogs.length>0&&a.dialogs.pop().remove(),a.dialogs.length>0){var b=a.dialogs[0],c=a.dialogs[a.dialogs.length-1];b.setMaskIndex(c.z-1)}return a},errorDialog:function(a){var b=this,c=b.createDialog({width:750,title:b.lang("uploadError"),body:'<div style="padding:10px 20px;"><iframe frameborder="0" style="width:708px;height:400px;"></iframe></div>'}),d=K("iframe",c.div),e=K.iframeDoc(d);return e.open(),e.write(a),e.close(),K(e.body).css("background-color","#FFF"),d[0].contentWindow.focus(),b}},_instances=[],K.remove=function(a){_eachEditor(a,function(a){this.remove(),_instances.splice(a,1)})},K.sync=function(a){_eachEditor(a,function(){this.sync()})},K.html=function(a,b){_eachEditor(a,function(){this.html(b)})},K.insertHtml=function(a,b){_eachEditor(a,function(){this.insertHtml(b)})},K.appendHtml=function(a,b){_eachEditor(a,function(){this.appendHtml(b)})},_IE&&7>_V&&_nativeCommand(document,"BackgroundImageCache",!0),K.EditorClass=KEditor,K.editor=_editor,K.create=_create,K.instances=_instances,K.plugin=_plugin,K.lang=_lang,_plugin("core",function(a){var b=this,c={undo:"Z",redo:"Y",bold:"B",italic:"I",underline:"U",print:"P",selectall:"A"};if(b.afterSetHtml(function(){b.options.afterChange&&b.options.afterChange.call(b)}),b.afterCreate(function(){if("form"==b.syncType){for(var c=a(b.srcElement),d=!1;c=c.parent();)if("form"==c.name){d=!0;break}if(d){c.bind("submit",function(){b.sync(),a(window).bind("unload",function(){b.edit.textarea.remove()})});var e=a('[type="reset"]',c);e.click(function(){b.html(b.initContent),b.cmd.selection()}),b.beforeRemove(function(){c.unbind(),e.unbind()})}}}),b.clickToolbar("source",function(){b.edit.designMode?(b.toolbar.disableAll(!0),b.edit.design(!1),b.toolbar.select("source")):(b.toolbar.disableAll(!1),b.edit.design(!0),b.toolbar.unselect("source"),_GECKO?setTimeout(function(){b.cmd.selection()},0):b.cmd.selection()),b.designMode=b.edit.designMode}),b.afterCreate(function(){b.designMode||b.toolbar.disableAll(!0).select("source")}),b.clickToolbar("fullscreen",function(){b.fullscreen()}),b.fullscreenShortcut){var d=!1;b.afterCreate(function(){if(a(b.edit.doc,b.edit.textarea).keyup(function(a){27==a.which&&setTimeout(function(){b.fullscreen()},0)}),d){if(_IE&&!b.designMode)return;b.focus()}d||(d=!0)})}_each("undo,redo".split(","),function(a,d){c[d]&&b.afterCreate(function(){_ctrl(this.edit.doc,c[d],function(){b.clickToolbar(d)})}),b.clickToolbar(d,function(){b[d]()})}),b.clickToolbar("formatblock",function(){var a=b.lang("formatblock.formatBlock"),c={h1:28,h2:24,h3:18,H4:14,p:12},d=b.cmd.val("formatblock"),e=b.createMenu({name:"formatblock",width:"en"==b.langType?200:150});_each(a,function(a,f){var g="font-size:"+c[a]+"px;";"h"===a.charAt(0)&&(g+="font-weight:bold;"),e.addItem({title:'<span style="'+g+'" unselectable="on">'+f+"</span>",height:c[a]+12,checked:d===a||d===f,click:function(){b.select().exec("formatblock","<"+a+">").hideMenu()}})})}),b.clickToolbar("fontname",function(){var a=b.cmd.val("fontname"),c=b.createMenu({name:"fontname",width:150});_each(b.lang("fontname.fontName"),function(d,e){c.addItem({title:'<span style="font-family: '+d+';" unselectable="on">'+e+"</span>",checked:a===d.toLowerCase()||a===e.toLowerCase(),click:function(){b.exec("fontname",d).hideMenu()}})})}),b.clickToolbar("fontsize",function(){var a=b.cmd.val("fontsize"),c=b.createMenu({name:"fontsize",width:150});_each(b.fontSizeTable,function(d,e){c.addItem({title:'<span style="font-size:'+e+';" unselectable="on">'+e+"</span>",height:_removeUnit(e)+12,checked:a===e,click:function(){b.exec("fontsize",e).hideMenu()}})})}),_each("forecolor,hilitecolor".split(","),function(a,c){b.clickToolbar(c,function(){b.createMenu({name:c,selectedColor:b.cmd.val(c)||"default",colors:b.colorTable,click:function(a){b.exec(c,a).hideMenu()}})})}),_each("cut,copy,paste".split(","),function(a,c){b.clickToolbar(c,function(){b.focus();try{b.exec(c,null)}catch(a){alert(b.lang(c+"Error"))}})}),b.clickToolbar("about",function(){var a='<div style="margin:20px;"><div>KindEditor '+_VERSION+'</div><div>Copyright &copy; <a href="http://www.kindsoft.net/" target="_blank">kindsoft.net</a> All rights reserved.</div></div>';b.createDialog({name:"about",width:350,title:b.lang("about"),body:a})}),b.plugin.getSelectedLink=function(){return b.cmd.commonAncestor("a")},b.plugin.getSelectedImage=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return!/^ke-\w+$/i.test(a[0].className)})},b.plugin.getSelectedFlash=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-flash"==a[0].className})},b.plugin.getSelectedMedia=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-media"==a[0].className||"ke-rm"==a[0].className})},b.plugin.getSelectedAnchor=function(){return _getImageFromRange(b.edit.cmd.range,function(a){return"ke-anchor"==a[0].className})},_each("link,image,flash,media,anchor".split(","),function(a,c){var d=c.charAt(0).toUpperCase()+c.substr(1);_each("edit,delete".split(","),function(a,e){b.addContextmenu({title:b.lang(e+d),click:function(){b.loadPlugin(c,function(){b.plugin[c][e](),b.hideMenu()})},cond:b.plugin["getSelected"+d],width:150,iconClass:"edit"==e?"ke-icon-"+c:undefined}) +}),b.addContextmenu({title:"-"})}),b.plugin.getSelectedTable=function(){return b.cmd.commonAncestor("table")},b.plugin.getSelectedRow=function(){return b.cmd.commonAncestor("tr")},b.plugin.getSelectedCell=function(){return b.cmd.commonAncestor("td")},_each("prop,cellprop,colinsertleft,colinsertright,rowinsertabove,rowinsertbelow,rowmerge,colmerge,rowsplit,colsplit,coldelete,rowdelete,insert,delete".split(","),function(a,c){var d=_inArray(c,["prop","delete"])<0?b.plugin.getSelectedCell:b.plugin.getSelectedTable;b.addContextmenu({title:b.lang("table"+c),click:function(){b.loadPlugin("table",function(){b.plugin.table[c](),b.hideMenu()})},cond:d,width:170,iconClass:"ke-icon-table"+c})}),b.addContextmenu({title:"-"}),_each("selectall,justifyleft,justifycenter,justifyright,justifyfull,insertorderedlist,insertunorderedlist,indent,outdent,subscript,superscript,hr,print,bold,italic,underline,strikethrough,removeformat,unlink".split(","),function(a,d){c[d]&&b.afterCreate(function(){_ctrl(this.edit.doc,c[d],function(){b.cmd.selection(),b.clickToolbar(d)})}),b.clickToolbar(d,function(){b.focus().exec(d,null)})}),b.afterCreate(function(){function c(){d.range.moveToBookmark(e),d.select(),_WEBKIT&&(a("div."+h,f).each(function(){a(this).after("<br />").remove(!0)}),a("span.Apple-style-span",f).remove(!0),a("span.Apple-tab-span",f).remove(!0),a("span[style]",f).each(function(){"nowrap"==a(this).css("white-space")&&a(this).remove(!0)}),a("meta",f).remove());var c=f[0].innerHTML;f.remove(),""!==c&&(_WEBKIT&&(c=c.replace(/(<br>)\1/gi,"$1")),2===b.pasteType&&(c=c.replace(/(<(?:p|p\s[^>]*)>) *(<\/p>)/gi,""),/schemas-microsoft-com|worddocument|mso-\w+/i.test(c)?c=_clearMsWord(c,b.filterMode?b.htmlTags:a.options.htmlTags):(c=_formatHtml(c,b.filterMode?b.htmlTags:null),c=b.beforeSetHtml(c))),1===b.pasteType&&(c=c.replace(/&nbsp;/gi," "),c=c.replace(/\n\s*\n/g,"\n"),c=c.replace(/<br[^>]*>/gi,"\n"),c=c.replace(/<\/p><p[^>]*>/gi,"\n"),c=c.replace(/<[^>]+>/g,""),c=c.replace(/ {2}/g," &nbsp;"),"p"==b.newlineTag?/\n/.test(c)&&(c=c.replace(/^/,"<p>").replace(/$/,"<br /></p>").replace(/\n/g,"<br /></p><p>")):c=c.replace(/\n/g,"<br />$&")),b.insertHtml(c,!0))}var d,e,f,g=b.edit.doc,h="__kindeditor_paste__",i=!1;a(g.body).bind("paste",function(j){if(0===b.pasteType)return void j.stop();if(!i){if(i=!0,a("div."+h,g).remove(),d=b.cmd.selection(),e=d.range.createBookmark(),f=a('<div class="'+h+'"></div>',g).css({position:"absolute",width:"1px",height:"1px",overflow:"hidden",left:"-1981px",top:a(e.start).pos().y+"px","white-space":"nowrap"}),a(g.body).append(f),_IE){var k=d.range.get(!0);k.moveToElementText(f[0]),k.select(),k.execCommand("paste"),j.preventDefault()}else d.range.selectNodeContents(f[0]),d.select(),f[0].tabIndex=-1,f[0].focus();setTimeout(function(){c(),i=!1},0)}})}),b.beforeGetHtml(function(a){return _IE&&8>=_V&&(a=a.replace(/<div\s+[^>]*data-ke-input-tag="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b){return unescape(b)}),a=a.replace(/(<input)((?:\s+[^>]*)?>)/gi,function(a,b,c){return/\s+type="[^"]+"/i.test(a)?a:b+' type="text"'+c})),a.replace(/(<(?:noscript|noscript\s[^>]*)>)([\s\S]*?)(<\/noscript>)/gi,function(a,b,c,d){return b+_unescape(c).replace(/\s+/g," ")+d}).replace(/<img[^>]*class="?ke-(flash|rm|media)"?[^>]*>/gi,function(a){var b=_getAttrList(a),c=_getCssList(b.style||""),d=_mediaAttrs(b["data-ke-tag"]),e=_undef(c.width,""),f=_undef(c.height,"");return/px/i.test(e)&&(e=_removeUnit(e)),/px/i.test(f)&&(f=_removeUnit(f)),d.width=_undef(b.width,e),d.height=_undef(b.height,f),_mediaEmbed(d)}).replace(/<img[^>]*class="?ke-anchor"?[^>]*>/gi,function(a){var b=_getAttrList(a);return'<a name="'+unescape(b["data-ke-name"])+'"></a>'}).replace(/<div\s+[^>]*data-ke-script-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b,c){return"<script"+unescape(b)+">"+unescape(c)+"</script>"}).replace(/<div\s+[^>]*data-ke-noscript-attr="([^"]*)"[^>]*>([\s\S]*?)<\/div>/gi,function(a,b,c){return"<noscript"+unescape(b)+">"+unescape(c)+"</noscript>"}).replace(/(<[^>]*)data-ke-src="([^"]*)"([^>]*>)/gi,function(a,b,c){return a=a.replace(/(\s+(?:href|src)=")[^"]*(")/i,function(a,b,d){return b+_unescape(c)+d}),a=a.replace(/\s+data-ke-src="[^"]*"/i,"")}).replace(/(<[^>]+\s)data-ke-(on\w+="[^"]*"[^>]*>)/gi,function(a,b,c){return b+c})}),b.beforeSetHtml(function(a){return _IE&&8>=_V&&(a=a.replace(/<input[^>]*>|<(select|button)[^>]*>[\s\S]*?<\/\1>/gi,function(a){var b=_getAttrList(a),c=_getCssList(b.style||"");return"none"==c.display?'<div class="ke-display-none" data-ke-input-tag="'+escape(a)+'"></div>':a})),a.replace(/<embed[^>]*type="([^"]+)"[^>]*>(?:<\/embed>)?/gi,function(a){var c=_getAttrList(a);return c.src=_undef(c.src,""),c.width=_undef(c.width,0),c.height=_undef(c.height,0),_mediaImg(b.themesPath+"common/blank.gif",c)}).replace(/<a[^>]*name="([^"]+)"[^>]*>(?:<\/a>)?/gi,function(a){var c=_getAttrList(a);return c.href!==undefined?a:'<img class="ke-anchor" src="'+b.themesPath+'common/anchor.gif" data-ke-name="'+escape(c.name)+'" />'}).replace(/<script([^>]*)>([\s\S]*?)<\/script>/gi,function(a,b,c){return'<div class="ke-script" data-ke-script-attr="'+escape(b)+'">'+escape(c)+"</div>"}).replace(/<noscript([^>]*)>([\s\S]*?)<\/noscript>/gi,function(a,b,c){return'<div class="ke-noscript" data-ke-noscript-attr="'+escape(b)+'">'+escape(c)+"</div>"}).replace(/(<[^>]*)(href|src)="([^"]*)"([^>]*>)/gi,function(a,b,c,d,e){return a.match(/\sdata-ke-src="[^"]*"/i)?a:a=b+c+'="'+d+'" data-ke-src="'+_escape(d)+'"'+e}).replace(/(<[^>]+\s)(on\w+="[^"]*"[^>]*>)/gi,function(a,b,c){return b+"data-ke-"+c}).replace(/<table[^>]*\s+border="0"[^>]*>/gi,function(a){return a.indexOf("ke-zeroborder")>=0?a:_addClassToTag(a,"ke-zeroborder")})})})}}(window),KindEditor.lang({source:"HTML代码",preview:"预览",undo:"后退(Ctrl+Z)",redo:"前进(Ctrl+Y)",cut:"剪切(Ctrl+X)",copy:"复制(Ctrl+C)",paste:"粘贴(Ctrl+V)",plainpaste:"粘贴为无格式文本",wordpaste:"从Word粘贴",selectall:"全选(Ctrl+A)",justifyleft:"左对齐",justifycenter:"居中",justifyright:"右对齐",justifyfull:"两端对齐",insertorderedlist:"编号",insertunorderedlist:"项目符号",indent:"增加缩进",outdent:"减少缩进",subscript:"下标",superscript:"上标",formatblock:"段落",fontname:"字体",fontsize:"文字大小",forecolor:"文字颜色",hilitecolor:"文字背景",bold:"粗体(Ctrl+B)",italic:"斜体(Ctrl+I)",underline:"下划线(Ctrl+U)",strikethrough:"删除线",removeformat:"删除格式",image:"图片",multiimage:"批量图片上传",flash:"Flash",media:"视音频",table:"表格",tablecell:"单元格",hr:"插入横线",emoticons:"插入表情",link:"超级链接",unlink:"取消超级链接",fullscreen:"全屏显示",about:"关于",print:"打印(Ctrl+P)",filemanager:"文件空间",code:"插入程序代码",map:"Google地图",baidumap:"百度地图",lineheight:"行距",clearhtml:"清理HTML代码",pagebreak:"插入分页符",quickformat:"一键排版",insertfile:"插入文件",template:"插入模板",anchor:"锚点",yes:"确定",no:"取消",close:"关闭",editImage:"图片属性",deleteImage:"删除图片",editFlash:"Flash属性",deleteFlash:"删除Flash",editMedia:"视音频属性",deleteMedia:"删除视音频",editLink:"超级链接属性",deleteLink:"取消超级链接",editAnchor:"锚点属性",deleteAnchor:"删除锚点",tableprop:"表格属性",tablecellprop:"单元格属性",tableinsert:"插入表格",tabledelete:"删除表格",tablecolinsertleft:"左侧插入列",tablecolinsertright:"右侧插入列",tablerowinsertabove:"上方插入行",tablerowinsertbelow:"下方插入行",tablerowmerge:"向下合并单元格",tablecolmerge:"向右合并单元格",tablerowsplit:"拆分行",tablecolsplit:"拆分列",tablecoldelete:"删除列",tablerowdelete:"删除行",noColor:"无颜色",pleaseSelectFile:"请选择文件。",invalidImg:"请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。",invalidMedia:"请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。",invalidWidth:"宽度必须为数字。",invalidHeight:"高度必须为数字。",invalidBorder:"边框必须为数字。",invalidUrl:"请输入有效的URL地址。",invalidRows:"行数为必选项,只允许输入大于0的数字。",invalidCols:"列数为必选项,只允许输入大于0的数字。",invalidPadding:"边距必须为数字。",invalidSpacing:"间距必须为数字。",invalidJson:"服务器发生故障。",uploadSuccess:"上传成功。",cutError:"您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。",copyError:"您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。",pasteError:"您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。",ajaxLoading:"加载中,请稍候 ...",uploadLoading:"上传中,请稍候 ...",uploadError:"上传错误","plainpaste.comment":"请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。","wordpaste.comment":"请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。","code.pleaseInput":"请输入程序代码。","link.url":"URL","link.linkType":"打开类型","link.newWindow":"新窗口","link.selfWindow":"当前窗口","flash.url":"URL","flash.width":"宽度","flash.height":"高度","flash.upload":"上传","flash.viewServer":"文件空间","media.url":"URL","media.width":"宽度","media.height":"高度","media.autostart":"自动播放","media.upload":"上传","media.viewServer":"文件空间","image.remoteImage":"网络图片","image.localImage":"本地上传","image.remoteUrl":"图片地址","image.localUrl":"上传文件","image.size":"图片大小","image.width":"宽","image.height":"高","image.resetSize":"重置大小","image.align":"对齐方式","image.defaultAlign":"默认方式","image.leftAlign":"左对齐","image.rightAlign":"右对齐","image.imgTitle":"图片说明","image.upload":"浏览...","image.viewServer":"图片空间","multiimage.uploadDesc":"允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>","multiimage.startUpload":"开始上传","multiimage.clearAll":"全部清空","multiimage.insertAll":"全部插入","multiimage.queueLimitExceeded":"文件数量超过限制。","multiimage.fileExceedsSizeLimit":"文件大小超过限制。","multiimage.zeroByteFile":"无法上传空文件。","multiimage.invalidFiletype":"文件类型不正确。","multiimage.unknownError":"发生异常,无法上传。","multiimage.pending":"等待上传","multiimage.uploadError":"上传失败","filemanager.emptyFolder":"空文件夹","filemanager.moveup":"移到上一级文件夹","filemanager.viewType":"显示方式:","filemanager.viewImage":"缩略图","filemanager.listImage":"详细信息","filemanager.orderType":"排序方式:","filemanager.fileName":"名称","filemanager.fileSize":"大小","filemanager.fileType":"类型","insertfile.url":"URL","insertfile.title":"文件说明","insertfile.upload":"上传","insertfile.viewServer":"文件空间","table.cells":"单元格数","table.rows":"行数","table.cols":"列数","table.size":"大小","table.width":"宽度","table.height":"高度","table.percent":"%","table.px":"px","table.space":"边距间距","table.padding":"边距","table.spacing":"间距","table.align":"对齐方式","table.textAlign":"水平对齐","table.verticalAlign":"垂直对齐","table.alignDefault":"默认","table.alignLeft":"左对齐","table.alignCenter":"居中","table.alignRight":"右对齐","table.alignTop":"顶部","table.alignMiddle":"中部","table.alignBottom":"底部","table.alignBaseline":"基线","table.border":"边框","table.borderWidth":"边框","table.borderColor":"颜色","table.backgroundColor":"背景颜色","map.address":"地址: ","map.search":"搜索","baidumap.address":"地址: ","baidumap.search":"搜索","baidumap.insertDynamicMap":"插入动态地图","anchor.name":"锚点名称","formatblock.formatBlock":{h1:"标题 1",h2:"标题 2",h3:"标题 3",h4:"标题 4",p:"正 文"},"fontname.fontName":{SimSun:"宋体",NSimSun:"新宋体",FangSong_GB2312:"仿宋_GB2312",KaiTi_GB2312:"楷体_GB2312",SimHei:"黑体","Microsoft YaHei":"微软雅黑",Arial:"Arial","Arial Black":"Arial Black","Times New Roman":"Times New Roman","Courier New":"Courier New",Tahoma:"Tahoma",Verdana:"Verdana"},"lineheight.lineHeight":[{1:"单倍行距"},{1.5:"1.5倍行距"},{2:"2倍行距"},{2.5:"2.5倍行距"},{3:"3倍行距"}],"template.selectTemplate":"可选模板","template.replaceContent":"替换当前内容","template.fileList":{"1.html":"图片和文字","2.html":"表格","3.html":"项目编号"}},"zh-CN"),KindEditor.options.langType="zh-CN",KindEditor.plugin("anchor",function(a){var b=this,c="anchor",d=b.lang(c+".");b.plugin.anchor={edit:function(){var e=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keName">'+d.name+"</label>",'<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />',"</div>","</div>"].join(""),f=b.createDialog({name:c,width:300,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){b.insertHtml('<a name="'+h.val()+'">').hideDialog().focus()}}}),g=f.div,h=a('input[name="name"]',g),i=b.plugin.getSelectedAnchor();i&&h.val(unescape(i.attr("data-ke-name"))),h[0].focus(),h[0].select()},"delete":function(){b.plugin.getSelectedAnchor().remove()}},b.clickToolbar(c,b.plugin.anchor.edit)}),KindEditor.plugin("autoheight",function(a){function b(){var a=e.edit,b=a.doc.body;a.iframe[0].scroll="no",b.style.overflowY="hidden"}function c(){var b=e.edit,c=b.doc.body;b.iframe.height(f),e.resize(null,Math.max((a.IE?c.scrollHeight:c.offsetHeight)+76,f))}function d(){f=a.removeUnit(e.height),e.edit.afterChange(c),b(),c()}var e=this;if(e.autoHeightMode){var f;e.isCreated?d():e.afterCreate(d)}}),KindEditor.plugin("baidumap",function(a){var b=this,c="baidumap",d=b.lang(c+"."),e=a.undef(b.mapWidth,558),f=a.undef(b.mapHeight,360);b.clickToolbar(c,function(){function g(){h=p[0].contentWindow,i=a.iframeDoc(p)}var h,i,j=['<div style="padding:10px 20px;">','<div class="ke-header">','<div class="ke-left">',d.address+' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ','<span class="ke-button-common ke-button-outer">','<input type="button" name="searchBtn" class="ke-button-common ke-button" value="'+d.search+'" />',"</span>","</div>",'<div class="ke-right">','<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">'+d.insertDynamicMap+"</label>","</div>",'<div class="ke-clearfix"></div>',"</div>",'<div class="ke-map" style="width:'+e+"px;height:"+f+'px;"></div>',"</div>"].join(""),k=b.createDialog({name:c,width:e+42,title:b.lang(c),body:j,yesBtn:{name:b.lang("yes"),click:function(){var a=h.map,c=a.getCenter(),d=c.lng+","+c.lat,g=a.getZoom(),i=[o[0].checked?b.pluginsPath+"baidumap/index.html":"http://api.map.baidu.com/staticimage","?center="+encodeURIComponent(d),"&zoom="+encodeURIComponent(g),"&width="+e,"&height="+f,"&markers="+encodeURIComponent(d),"&markerStyles="+encodeURIComponent("l,A")].join("");o[0].checked?b.insertHtml('<iframe src="'+i+'" frameborder="0" style="width:'+(e+2)+"px;height:"+(f+2)+'px;"></iframe>'):b.exec("insertimage",i),b.hideDialog().focus()}},beforeRemove:function(){n.remove(),i&&i.write(""),p.remove()}}),l=k.div,m=a('[name="address"]',l),n=a('[name="searchBtn"]',l),o=a('[name="insertDynamicMap"]',k.div),p=a('<iframe class="ke-textarea" frameborder="0" src="'+b.pluginsPath+'baidumap/map.html" style="width:'+e+"px;height:"+f+'px;"></iframe>');p.bind("load",function(){p.unbind("load"),a.IE?g():setTimeout(g,0)}),a(".ke-map",l).replaceWith(p),n.click(function(){h.search(m.val())})})}),KindEditor.plugin("map",function(a){var b=this,c="map",d=b.lang(c+".");b.clickToolbar(c,function(){function e(){f=m[0].contentWindow,g=a.iframeDoc(m)}var f,g,h=['<div style="padding:10px 20px;">','<div class="ke-dialog-row">',d.address+' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ','<span class="ke-button-common ke-button-outer">','<input type="button" name="searchBtn" class="ke-button-common ke-button" value="'+d.search+'" />',"</span>","</div>",'<div class="ke-map" style="width:558px;height:360px;"></div>',"</div>"].join(""),i=b.createDialog({name:c,width:600,title:b.lang(c),body:h,yesBtn:{name:b.lang("yes"),click:function(){var a=(f.geocoder,f.map),c=a.getCenter().lat()+","+a.getCenter().lng(),d=a.getZoom(),e=a.getMapTypeId(),g="http://maps.googleapis.com/maps/api/staticmap";g+="?center="+encodeURIComponent(c),g+="&zoom="+encodeURIComponent(d),g+="&size=558x360",g+="&maptype="+encodeURIComponent(e),g+="&markers="+encodeURIComponent(c),g+="&language="+b.langType,g+="&sensor=false",b.exec("insertimage",g).hideDialog().focus()}},beforeRemove:function(){l.remove(),g&&g.write(""),m.remove()}}),j=i.div,k=a('[name="address"]',j),l=a('[name="searchBtn"]',j),m=(["<!doctype html><html><head>",'<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />',"<style>"," html { height: 100% }"," body { height: 100%; margin: 0; padding: 0; background-color: #FFF }"," #map_canvas { height: 100% }","</style>",'<script src="http://maps.googleapis.com/maps/api/js?sensor=false&language='+b.langType+'"></script>',"<script>","var map, geocoder;","function initialize() {"," var latlng = new google.maps.LatLng(31.230393, 121.473704);"," var options = {"," zoom: 11,"," center: latlng,"," disableDefaultUI: true,"," panControl: true,"," zoomControl: true,"," mapTypeControl: true,"," scaleControl: true,"," streetViewControl: false,"," overviewMapControl: true,"," mapTypeId: google.maps.MapTypeId.ROADMAP"," };",' map = new google.maps.Map(document.getElementById("map_canvas"), options);'," geocoder = new google.maps.Geocoder();"," geocoder.geocode({latLng: latlng}, function(results, status) {"," if (status == google.maps.GeocoderStatus.OK) {"," if (results[3]) {",' parent.document.getElementById("kindeditor_plugin_map_address").value = results[3].formatted_address;'," }"," }"," });","}","function search(address) {"," if (!map) return;"," geocoder.geocode({address : address}, function(results, status) {"," if (status == google.maps.GeocoderStatus.OK) {"," map.setZoom(11);"," map.setCenter(results[0].geometry.location);"," var marker = new google.maps.Marker({"," map: map,"," position: results[0].geometry.location"," });"," } else {",' alert("Invalid address: " + address);'," }"," });","}","</script>","</head>",'<body onload="initialize();">','<div id="map_canvas" style="width:100%; height:100%"></div>',"</body></html>"].join("\n"),a('<iframe class="ke-textarea" frameborder="0" src="'+b.pluginsPath+'map/map.html" style="width:558px;height:360px;"></iframe>'));m.bind("load",function(){m.unbind("load"),a.IE?e():setTimeout(e,0)}),a(".ke-map",j).replaceWith(m),l.click(function(){f.search(k.val())})})}),KindEditor.plugin("clearhtml",function(a){var b=this,c="clearhtml";b.clickToolbar(c,function(){b.focus();var c=b.html();c=c.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/gi,""),c=c.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/gi,""),c=a.formatHtml(c,{a:["href","target"],embed:["src","width","height","type","loop","autostart","quality",".width",".height","align","allowscriptaccess"],img:["src","width","height","border","alt","title",".width",".height"],table:["border"],"td,th":["rowspan","colspan"],"div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6":[]}),b.html(c),b.cmd.selection(!0),b.addBookmark()})}),KindEditor.plugin("code",function(a){var b=this,c="code";b.clickToolbar(c,function(){var d=b.lang(c+"."),e=['<div style="padding:10px 20px;">','<div class="ke-dialog-row">','<select class="ke-code-type">','<option value="js">JavaScript</option>','<option value="html">HTML</option>','<option value="css">CSS</option>','<option value="php">PHP</option>','<option value="pl">Perl</option>','<option value="py">Python</option>','<option value="rb">Ruby</option>','<option value="java">Java</option>','<option value="vb">ASP/VB</option>','<option value="cpp">C/C++</option>','<option value="cs">C#</option>','<option value="xml">XML</option>','<option value="bsh">Shell</option>','<option value="">Other</option>',"</select>","</div>",'<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>',"</div>"].join(""),f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=a(".ke-code-type",f.div).val(),e=g.val(),h=""===c?"":" lang-"+c,i='<pre class="prettyprint'+h+'">\n'+a.escape(e)+"</pre> ";return""===a.trim(e)?(alert(d.pleaseInput),void g[0].focus()):void b.insertHtml(i).hideDialog().focus()}}}),g=a("textarea",f.div);g[0].focus()})}),KindEditor.plugin("emoticons",function(a){var b=this,c="emoticons",d=b.emoticonsPath||b.pluginsPath+"emoticons/images/",e=void 0===b.allowPreviewEmoticons?!0:b.allowPreviewEmoticons,f=1;b.clickToolbar(c,function(){function g(c,e,f){c.mouseover(v?function(){e>r?(v.css("left",0),v.css("right","")):(v.css("left",""),v.css("right",0)),w.attr("src",d+f+".gif"),a(this).addClass("ke-on")}:function(){a(this).addClass("ke-on")}),c.mouseout(function(){a(this).removeClass("ke-on")}),c.click(function(a){b.insertHtml('<img src="'+d+f+'.gif" border="0" alt="" />').hideMenu().focus(),a.stop()})}function h(b,c){var e=document.createElement("table");c.append(e),v&&(a(e).mouseover(function(){v.show("block")}),a(e).mouseout(function(){v.hide()}),t.push(a(e))),e.className="ke-table",e.cellPadding=0,e.cellSpacing=0,e.border=0;for(var f=(b-1)*p+o,h=0;l>h;h++)for(var i=e.insertRow(h),j=0;m>j;j++){var k=a(i.insertCell(j));k.addClass("ke-cell"),g(k,j,f);var n=a('<span class="ke-img"></span>').css("background-position","-"+24*f+"px 0px").css("background-image","url("+d+"static.gif)");k.append(n),t.push(k),f++}return e}function i(){a.each(t,function(){this.unbind()})}function j(a,b){a.click(function(a){i(),y.parentNode.removeChild(y),x.remove(),y=h(b,s),k(b),f=b,a.stop()})}function k(b){x=a('<div class="ke-page"></div>'),s.append(x);for(var c=1;q>=c;c++){if(b!==c){var d=a('<a href="javascript:;">['+c+"]</a>");j(d,c),x.append(d),t.push(d)}else x.append(a("@["+c+"]"));x.append(a("@&nbsp;"))}}var l=5,m=9,n=135,o=0,p=l*m,q=Math.ceil(n/p),r=Math.floor(m/2),s=a('<div class="ke-plugin-emoticons"></div>'),t=[],u=b.createMenu({name:c,beforeRemove:function(){i()}});u.div.append(s);var v,w;e&&(v=a('<div class="ke-preview"></div>').css("right",0),w=a('<img class="ke-preview-img" src="'+d+o+'.gif" />'),s.append(v),v.append(w));var x,y=h(f,s);k(f)})}),KindEditor.plugin("filemanager",function(a){function b(a,b,c){return a+" ("+Math.ceil(b/1024)+"KB, "+c+")"}function c(a,c){c.is_dir?a.attr("title",c.filename):a.attr("title",b(c.filename,c.filesize,c.datetime))}var d=this,e="filemanager",f=a.undef(d.fileManagerJson,d.basePath+"php/file_manager_json.php"),g=d.pluginsPath+e+"/images/",h=d.lang(e+".");d.plugin.filemanagerDialog=function(b){function i(b,c,e){var g="path="+b+"&order="+c+"&dir="+p;t.showLoading(d.lang("ajaxLoading")),a.ajax(a.addParam(f,g+"&"+(new Date).getTime()),function(a){t.hideLoading(),e(a)})}function j(b,c,d,e){var f=a.formatUrl(c.current_url+d.filename,"absolute"),g=encodeURIComponent(c.current_dir_path+d.filename+"/");b.click(d.is_dir?function(){i(g,y.val(),e)}:d.is_photo?function(){r.call(this,f,d.filename)}:function(){r.call(this,f,d.filename)}),z.push(b)}function k(b,c){function d(){"VIEW"==x.val()?i(b.current_dir_path,y.val(),m):i(b.current_dir_path,y.val(),l)}a.each(z,function(){this.unbind()}),w.unbind(),x.unbind(),y.unbind(),b.current_dir_path&&w.click(function(){i(b.moveup_dir_path,y.val(),c)}),x.change(d),y.change(d),v.html("")}function l(b){k(b,l);var c=document.createElement("table");c.className="ke-table",c.cellPadding=0,c.cellSpacing=0,c.border=0,v.append(c);for(var d=b.file_list,e=0,f=d.length;f>e;e++){var i=d[e],m=a(c.insertRow(e));m.mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});var n=g+(i.is_dir?"folder-16.gif":"file-16.gif"),o=a('<img src="'+n+'" width="16" height="16" alt="'+i.filename+'" align="absmiddle" />'),p=a(m[0].insertCell(0)).addClass("ke-cell ke-name").append(o).append(document.createTextNode(" "+i.filename));!i.is_dir||i.has_file?(m.css("cursor","pointer"),p.attr("title",i.filename),j(p,b,i,l)):p.attr("title",h.emptyFolder),a(m[0].insertCell(1)).addClass("ke-cell ke-size").html(i.is_dir?"-":Math.ceil(i.filesize/1024)+"KB"),a(m[0].insertCell(2)).addClass("ke-cell ke-datetime").html(i.datetime)}}function m(b){k(b,m);for(var d=b.file_list,e=0,f=d.length;f>e;e++){var i=d[e],l=a('<div class="ke-inline-block ke-item"></div>');v.append(l);var n=a('<div class="ke-inline-block ke-photo"></div>').mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});l.append(n);var o=b.current_url+i.filename,p=i.is_dir?g+"folder-64.gif":i.is_photo?o:g+"file-64.gif",q=a('<img src="'+p+'" width="80" height="80" alt="'+i.filename+'" />');!i.is_dir||i.has_file?(n.css("cursor","pointer"),c(n,i),j(n,b,i,m)):n.attr("title",h.emptyFolder),n.append(q),l.append('<div class="ke-name" title="'+i.filename+'">'+i.filename+"</div>")}}var n=a.undef(b.width,650),o=a.undef(b.height,510),p=a.undef(b.dirName,""),q=a.undef(b.viewType,"VIEW").toUpperCase(),r=b.clickFn,s=['<div style="padding:10px 20px;">','<div class="ke-plugin-filemanager-header">','<div class="ke-left">','<img class="ke-inline-block" name="moveupImg" src="'+g+'go-up.gif" width="16" height="16" border="0" alt="" /> ','<a class="ke-inline-block" name="moveupLink" href="javascript:;">'+h.moveup+"</a>","</div>",'<div class="ke-right">',h.viewType+' <select class="ke-inline-block" name="viewType">','<option value="VIEW">'+h.viewImage+"</option>",'<option value="LIST">'+h.listImage+"</option>","</select> ",h.orderType+' <select class="ke-inline-block" name="orderType">','<option value="NAME">'+h.fileName+"</option>",'<option value="SIZE">'+h.fileSize+"</option>",'<option value="TYPE">'+h.fileType+"</option>","</select>","</div>",'<div class="ke-clearfix"></div>',"</div>",'<div class="ke-plugin-filemanager-body"></div>',"</div>"].join(""),t=d.createDialog({name:e,width:n,height:o,title:d.lang(e),body:s}),u=t.div,v=a(".ke-plugin-filemanager-body",u),w=(a('[name="moveupImg"]',u),a('[name="moveupLink"]',u)),x=(a('[name="viewServer"]',u),a('[name="viewType"]',u)),y=a('[name="orderType"]',u),z=[];return x.val(q),i("",y.val(),"VIEW"==q?m:l),t}}),KindEditor.plugin("flash",function(a){var b=this,c="flash",d=b.lang(c+"."),e=a.undef(b.allowFlashUpload,!0),f=a.undef(b.allowFileManager,!1),g=a.undef(b.formatUploadUrl,!0),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=a.undef(b.uploadJson,b.basePath+"php/upload_json.php");b.plugin.flash={edit:function(){var k=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keUrl" style="width:60px;">'+d.url+"</label>",'<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;','<input type="button" class="ke-upload-button" value="'+d.upload+'" /> &nbsp;','<span class="ke-button-common ke-button-outer">','<input type="button" class="ke-button-common ke-button" name="viewServer" value="'+d.viewServer+'" />',"</span>","</div>",'<div class="ke-dialog-row">','<label for="keWidth" style="width:60px;">'+d.width+"</label>",'<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" /> ',"</div>",'<div class="ke-dialog-row">','<label for="keHeight" style="width:60px;">'+d.height+"</label>",'<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" /> ',"</div>","</div>"].join(""),l=b.createDialog({name:c,width:450,title:b.lang(c),body:k,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(n.val()),d=p.val(),e=q.val();if("http://"==c||a.invalidUrl(c))return alert(b.lang("invalidUrl")),void n[0].focus();if(!/^\d*$/.test(d))return alert(b.lang("invalidWidth")),void p[0].focus();if(!/^\d*$/.test(e))return alert(b.lang("invalidHeight")),void q[0].focus();var f=a.mediaImg(b.themesPath+"common/blank.gif",{src:c,type:a.mediaType(".swf"),width:d,height:e,quality:"high"});b.insertHtml(f).hideDialog().focus()}}}),m=l.div,n=a('[name="url"]',m),o=a('[name="viewServer"]',m),p=a('[name="width"]',m),q=a('[name="height"]',m);if(n.val("http://"),e){var r=a.uploadbutton({button:a(".ke-upload-button",m)[0],fieldName:i,extraParams:h,url:a.addParam(j,"dir=flash"),afterUpload:function(d){if(l.hideLoading(),0===d.error){var e=d.url;g&&(e=a.formatUrl(e,"absolute")),n.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){l.hideLoading(),b.errorDialog(a)}});r.fileBox.change(function(){l.showLoading(b.lang("uploadLoading")),r.submit()})}else a(".ke-upload-button",m).hide();f?o.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"flash",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',m).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):o.hide();var s=b.plugin.getSelectedFlash();if(s){var t=a.mediaAttrs(s.attr("data-ke-tag"));n.val(t.src),p.val(a.removeUnit(s.css("width"))||t.width||0),q.val(a.removeUnit(s.css("height"))||t.height||0)}n[0].focus(),n[0].select()},"delete":function(){b.plugin.getSelectedFlash().remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.flash.edit)}),KindEditor.plugin("image",function(a){var b=this,c="image",d=a.undef(b.allowImageUpload,!0),e=a.undef(b.allowImageRemote,!0),f=a.undef(b.formatUploadUrl,!0),g=a.undef(b.allowFileManager,!1),h=a.undef(b.uploadJson,b.basePath+"php/upload_json.php"),i=a.undef(b.imageTabIndex,0),j=b.pluginsPath+"image/images/",k=a.undef(b.extraFileUploadParams,{}),l=a.undef(b.filePostName,"imgFile"),m=a.undef(b.fillDescAfterUploadImage,!1),n=b.lang(c+".");b.plugin.imageDialog=function(d){function e(a,b){D.val(a),E.val(b),J=a,K=b}var i=(d.imageUrl,a.undef(d.imageWidth,""),a.undef(d.imageHeight,""),a.undef(d.imageTitle,""),a.undef(d.imageAlign,""),a.undef(d.showRemote,!0)),o=a.undef(d.showLocal,!0),p=a.undef(d.tabIndex,0),q=d.clickFn,r="kindeditor_upload_iframe_"+(new Date).getTime(),s=[];for(var t in k)s.push('<input type="hidden" name="'+t+'" value="'+k[t]+'" />');var u,v=['<div style="padding:20px;">','<div class="tabs"></div>','<div class="tab1" style="display:none;">','<div class="ke-dialog-row">','<label for="remoteUrl" style="width:60px;">'+n.remoteUrl+"</label>",'<input type="text" id="remoteUrl" class="ke-input-text" name="url" value="" style="width:200px;" /> &nbsp;','<span class="ke-button-common ke-button-outer">','<input type="button" class="ke-button-common ke-button" name="viewServer" value="'+n.viewServer+'" />',"</span>","</div>",'<div class="ke-dialog-row">','<label for="remoteWidth" style="width:60px;">'+n.size+"</label>",n.width+' <input type="text" id="remoteWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> ',n.height+' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> ','<img class="ke-refresh-btn" src="'+j+'refresh.png" width="16" height="16" alt="" style="cursor:pointer;" title="'+n.resetSize+'" />',"</div>",'<div class="ke-dialog-row">','<label style="width:60px;">'+n.align+"</label>",'<input type="radio" name="align" class="ke-inline-block" value="" checked="checked" /> <img name="defaultImg" src="'+j+'align_top.gif" width="23" height="25" alt="" />',' <input type="radio" name="align" class="ke-inline-block" value="left" /> <img name="leftImg" src="'+j+'align_left.gif" width="23" height="25" alt="" />',' <input type="radio" name="align" class="ke-inline-block" value="right" /> <img name="rightImg" src="'+j+'align_right.gif" width="23" height="25" alt="" />',"</div>",'<div class="ke-dialog-row">','<label for="remoteTitle" style="width:60px;">'+n.imgTitle+"</label>",'<input type="text" id="remoteTitle" class="ke-input-text" name="title" value="" style="width:200px;" />',"</div>","</div>",'<div class="tab2" style="display:none;">','<iframe name="'+r+'" style="display:none;"></iframe>','<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="'+r+'" action="'+a.addParam(h,"dir=image")+'">','<div class="ke-dialog-row">',s.join(""),'<label style="width:60px;">'+n.localUrl+"</label>",'<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;','<input type="button" class="ke-upload-button" value="'+n.upload+'" />',"</div>","</form>","</div>","</div>"].join(""),w=o||g?450:400,x=o&&i?300:250,y=b.createDialog({name:c,width:w,height:x,title:b.lang(c),body:v,yesBtn:{name:b.lang("yes"),click:function(){if(!y.isLoading){if(o&&i&&u&&1===u.selectedIndex||!i)return""==I.fileBox.val()?void alert(b.lang("pleaseSelectFile")):(y.showLoading(b.lang("uploadLoading")),I.submit(),void B.val(""));var c=a.trim(A.val()),d=D.val(),e=E.val(),f=G.val(),g="";return H.each(function(){return this.checked?(g=this.value,!1):void 0}),"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void A[0].focus()):/^\d*$/.test(d)?/^\d*$/.test(e)?void q.call(b,c,f,d,e,0,g):(alert(b.lang("invalidHeight")),void E[0].focus()):(alert(b.lang("invalidWidth")),void D[0].focus())}}},beforeRemove:function(){C.unbind(),D.unbind(),E.unbind(),F.unbind()}}),z=y.div,A=a('[name="url"]',z),B=a('[name="localUrl"]',z),C=a('[name="viewServer"]',z),D=a('.tab1 [name="width"]',z),E=a('.tab1 [name="height"]',z),F=a(".ke-refresh-btn",z),G=a('.tab1 [name="title"]',z),H=a('.tab1 [name="align"]',z);i&&o?(u=a.tabs({src:a(".tabs",z),afterSelect:function(){}}),u.add({title:n.remoteImage,panel:a(".tab1",z)}),u.add({title:n.localImage,panel:a(".tab2",z)}),u.select(p)):i?a(".tab1",z).show():o&&a(".tab2",z).show(); +var I=a.uploadbutton({button:a(".ke-upload-button",z)[0],fieldName:l,form:a(".ke-form",z),target:r,width:60,afterUpload:function(d){if(y.hideLoading(),0===d.error){var e=d.url;f&&(e=a.formatUrl(e,"absolute")),b.afterUpload&&b.afterUpload.call(b,e,d,c),m?(a(".ke-dialog-row #remoteUrl",z).val(e),a(".ke-tabs-li",z)[0].click(),a(".ke-refresh-btn",z).click()):q.call(b,e,d.title,d.width,d.height,d.border,d.align)}else alert(d.message)},afterError:function(a){y.hideLoading(),b.errorDialog(a)}});I.fileBox.change(function(){B.val(I.fileBox.val())}),g?C.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"VIEW",dirName:"image",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',z).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):C.hide();var J=0,K=0;return F.click(function(){var b=a('<img src="'+A.val()+'" />',document).css({position:"absolute",visibility:"hidden",top:0,left:"-1000px"});b.bind("load",function(){e(b.width(),b.height()),b.remove()}),a(document.body).append(b)}),D.change(function(){J>0&&E.val(Math.round(K/J*parseInt(this.value,10)))}),E.change(function(){K>0&&D.val(Math.round(J/K*parseInt(this.value,10)))}),A.val(d.imageUrl),e(d.imageWidth,d.imageHeight),G.val(d.imageTitle),H.each(function(){return this.value===d.imageAlign?(this.checked=!0,!1):void 0}),i&&0===p&&(A[0].focus(),A[0].select()),y},b.plugin.image={edit:function(){var a=b.plugin.getSelectedImage();b.plugin.imageDialog({imageUrl:a?a.attr("data-ke-src"):"http://",imageWidth:a?a.width():"",imageHeight:a?a.height():"",imageTitle:a?a.attr("title"):"",imageAlign:a?a.attr("align"):"",showRemote:e,showLocal:d,tabIndex:a?0:i,clickFn:function(c,d,e,f,g,h){a?(a.attr("src",c),a.attr("data-ke-src",c),a.attr("width",e),a.attr("height",f),a.attr("title",d),a.attr("align",h),a.attr("alt",d)):b.exec("insertimage",c,d,e,f,g,h),setTimeout(function(){b.hideDialog().focus()},0)}})},"delete":function(){var a=b.plugin.getSelectedImage();"a"==a.parent().name&&(a=a.parent()),a.remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.image.edit)}),KindEditor.plugin("insertfile",function(a){var b=this,c="insertfile",d=a.undef(b.allowFileUpload,!0),e=a.undef(b.allowFileManager,!1),f=a.undef(b.formatUploadUrl,!0),g=a.undef(b.uploadJson,b.basePath+"php/upload_json.php"),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=b.lang(c+".");b.plugin.fileDialog=function(k){var l=a.undef(k.fileUrl,"http://"),m=a.undef(k.fileTitle,""),n=k.clickFn,o=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keUrl" style="width:60px;">'+j.url+"</label>",'<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;','<input type="button" class="ke-upload-button" value="'+j.upload+'" /> &nbsp;','<span class="ke-button-common ke-button-outer">','<input type="button" class="ke-button-common ke-button" name="viewServer" value="'+j.viewServer+'" />',"</span>","</div>",'<div class="ke-dialog-row">','<label for="keTitle" style="width:60px;">'+j.title+"</label>",'<input type="text" id="keTitle" class="ke-input-text" name="title" value="" style="width:160px;" /></div>',"</div>","</form>","</div>"].join(""),p=b.createDialog({name:c,width:450,title:b.lang(c),body:o,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(r.val()),d=t.val();return"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void r[0].focus()):(""===a.trim(d)&&(d=c),void n.call(b,c,d))}}}),q=p.div,r=a('[name="url"]',q),s=a('[name="viewServer"]',q),t=a('[name="title"]',q);if(d){var u=a.uploadbutton({button:a(".ke-upload-button",q)[0],fieldName:i,url:a.addParam(g,"dir=file"),extraParams:h,afterUpload:function(d){if(p.hideLoading(),0===d.error){var e=d.url;f&&(e=a.formatUrl(e,"absolute")),r.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){p.hideLoading(),b.errorDialog(a)}});u.fileBox.change(function(){p.showLoading(b.lang("uploadLoading")),u.submit()})}else a(".ke-upload-button",q).hide();e?s.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"file",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',q).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):s.hide(),r.val(l),t.val(m),r[0].focus(),r[0].select()},b.clickToolbar(c,function(){b.plugin.fileDialog({clickFn:function(a,c){var d='<a class="ke-insertfile" href="'+a+'" data-ke-src="'+a+'" target="_blank">'+c+"</a>";b.insertHtml(d).hideDialog().focus()}})})}),KindEditor.plugin("lineheight",function(a){var b=this,c="lineheight",d=b.lang(c+".");b.clickToolbar(c,function(){var e="",f=b.cmd.commonNode({"*":".line-height"});f&&(e=f.css("line-height"));var g=b.createMenu({name:c,width:150});a.each(d.lineHeight,function(c,d){a.each(d,function(a,c){g.addItem({title:c,checked:e===a,click:function(){b.cmd.toggle('<span style="line-height:'+a+';"></span>',{span:".line-height="+a}),b.updateState(),b.addBookmark(),b.hideMenu()}})})})})}),KindEditor.plugin("link",function(a){var b=this,c="link";b.plugin.link={edit:function(){var d=b.lang(c+"."),e='<div style="padding:20px;"><div class="ke-dialog-row"><label for="keUrl" style="width:60px;">'+d.url+'</label><input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:260px;" /></div><div class="ke-dialog-row""><label for="keType" style="width:60px;">'+d.linkType+'</label><select id="keType" name="type"></select></div></div>',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(h.val());return"http://"==c||a.invalidUrl(c)?(alert(b.lang("invalidUrl")),void h[0].focus()):void b.exec("createlink",c,i.val()).hideDialog().focus()}}}),g=f.div,h=a('input[name="url"]',g),i=a('select[name="type"]',g);h.val("http://"),i[0].options[0]=new Option(d.newWindow,"_blank"),i[0].options[1]=new Option(d.selfWindow,""),b.cmd.selection();var j=b.plugin.getSelectedLink();j&&(b.cmd.range.selectNode(j[0]),b.cmd.select(),h.val(j.attr("data-ke-src")),i.val(j.attr("target"))),h[0].focus(),h[0].select()},"delete":function(){b.exec("unlink",null)}},b.clickToolbar(c,b.plugin.link.edit)}),KindEditor.plugin("media",function(a){var b=this,c="media",d=b.lang(c+"."),e=a.undef(b.allowMediaUpload,!0),f=a.undef(b.allowFileManager,!1),g=a.undef(b.formatUploadUrl,!0),h=a.undef(b.extraFileUploadParams,{}),i=a.undef(b.filePostName,"imgFile"),j=a.undef(b.uploadJson,b.basePath+"php/upload_json.php");b.plugin.media={edit:function(){var k=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keUrl" style="width:60px;">'+d.url+"</label>",'<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;','<input type="button" class="ke-upload-button" value="'+d.upload+'" /> &nbsp;','<span class="ke-button-common ke-button-outer">','<input type="button" class="ke-button-common ke-button" name="viewServer" value="'+d.viewServer+'" />',"</span>","</div>",'<div class="ke-dialog-row">','<label for="keWidth" style="width:60px;">'+d.width+"</label>",'<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" />',"</div>",'<div class="ke-dialog-row">','<label for="keHeight" style="width:60px;">'+d.height+"</label>",'<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" />',"</div>",'<div class="ke-dialog-row">','<label for="keAutostart">'+d.autostart+"</label>",'<input type="checkbox" id="keAutostart" name="autostart" value="" /> ',"</div>","</div>"].join(""),l=b.createDialog({name:c,width:450,height:230,title:b.lang(c),body:k,yesBtn:{name:b.lang("yes"),click:function(){var c=a.trim(n.val()),d=p.val(),e=q.val();if("http://"==c||a.invalidUrl(c))return alert(b.lang("invalidUrl")),void n[0].focus();if(!/^\d*$/.test(d))return alert(b.lang("invalidWidth")),void p[0].focus();if(!/^\d*$/.test(e))return alert(b.lang("invalidHeight")),void q[0].focus();var f=a.mediaImg(b.themesPath+"common/blank.gif",{src:c,type:a.mediaType(c),width:d,height:e,autostart:r[0].checked?"true":"false",loop:"true"});b.insertHtml(f).hideDialog().focus()}}}),m=l.div,n=a('[name="url"]',m),o=a('[name="viewServer"]',m),p=a('[name="width"]',m),q=a('[name="height"]',m),r=a('[name="autostart"]',m);if(n.val("http://"),e){var s=a.uploadbutton({button:a(".ke-upload-button",m)[0],fieldName:i,extraParams:h,url:a.addParam(j,"dir=media"),afterUpload:function(d){if(l.hideLoading(),0===d.error){var e=d.url;g&&(e=a.formatUrl(e,"absolute")),n.val(e),b.afterUpload&&b.afterUpload.call(b,e,d,c),alert(b.lang("uploadSuccess"))}else alert(d.message)},afterError:function(a){l.hideLoading(),b.errorDialog(a)}});s.fileBox.change(function(){l.showLoading(b.lang("uploadLoading")),s.submit()})}else a(".ke-upload-button",m).hide();f?o.click(function(){b.loadPlugin("filemanager",function(){b.plugin.filemanagerDialog({viewType:"LIST",dirName:"media",clickFn:function(c){b.dialogs.length>1&&(a('[name="url"]',m).val(c),b.afterSelectFile&&b.afterSelectFile.call(b,c),b.hideDialog())}})})}):o.hide();var t=b.plugin.getSelectedMedia();if(t){var u=a.mediaAttrs(t.attr("data-ke-tag"));n.val(u.src),p.val(a.removeUnit(t.css("width"))||u.width||0),q.val(a.removeUnit(t.css("height"))||u.height||0),r[0].checked="true"===u.autostart}n[0].focus(),n[0].select()},"delete":function(){b.plugin.getSelectedMedia().remove(),b.addBookmark()}},b.clickToolbar(c,b.plugin.media.edit)}),function(a){function b(a){this.init(a)}a.extend(b,{init:function(b){function c(b,c){a(".ke-status > div",b).hide(),a(".ke-message",b).addClass("ke-error").show().html(a.escape(c))}var d=this;b.afterError=b.afterError||function(a){alert(a)},d.options=b,d.progressbars={},d.div=a(b.container).html(['<div class="ke-swfupload">','<div class="ke-swfupload-top">','<div class="ke-inline-block ke-swfupload-button">','<input type="button" value="Browse" />',"</div>",'<div class="ke-inline-block ke-swfupload-desc">'+b.uploadDesc+"</div>",'<span class="ke-button-common ke-button-outer ke-swfupload-startupload">','<input type="button" class="ke-button-common ke-button" value="'+b.startButtonValue+'" />',"</span>","</div>",'<div class="ke-swfupload-body"></div>',"</div>"].join("")),d.bodyDiv=a(".ke-swfupload-body",d.div);var e={debug:!1,upload_url:b.uploadUrl,flash_url:b.flashUrl,file_post_name:b.filePostName,button_placeholder:a(".ke-swfupload-button > input",d.div)[0],button_image_url:b.buttonImageUrl,button_width:b.buttonWidth,button_height:b.buttonHeight,button_cursor:SWFUpload.CURSOR.HAND,file_types:b.fileTypes,file_types_description:b.fileTypesDesc,file_upload_limit:b.fileUploadLimit,file_size_limit:b.fileSizeLimit,post_params:b.postParams,file_queued_handler:function(a){a.url=d.options.fileIconUrl,d.appendFile(a)},file_queue_error_handler:function(c,d){var e="";switch(d){case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:e=b.queueLimitExceeded;break;case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:e=b.fileExceedsSizeLimit;break;case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:e=b.zeroByteFile;break;case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:e=b.invalidFiletype;break;default:e=b.unknownError}a.DEBUG&&alert(e)},upload_start_handler:function(b){var c=this,d=a('div[data-id="'+b.id+'"]',c.bodyDiv);a(".ke-status > div",d).hide(),a(".ke-progressbar",d).show()},upload_progress_handler:function(a,b,c){var e=Math.round(100*b/c),f=d.progressbars[a.id];f.bar.css("width",Math.round(80*e/100)+"px"),f.percent.html(e+"%")},upload_error_handler:function(b){if(b&&b.filestatus==SWFUpload.FILE_STATUS.ERROR){var e=a('div[data-id="'+b.id+'"]',d.bodyDiv).eq(0);c(e,d.options.errorMessage)}},upload_success_handler:function(b,e){var f=a('div[data-id="'+b.id+'"]',d.bodyDiv).eq(0),g={};try{g=a.json(e)}catch(h){d.options.afterError.call(this,"<!doctype html><html>"+e+"</html>")}return 0!==g.error?void c(f,a.DEBUG?g.message:d.options.errorMessage):(b.url=g.url,a(".ke-img",f).attr("src",b.url).attr("data-status",b.filestatus).data("data",g),void a(".ke-status > div",f).hide())}};d.swfu=new SWFUpload(e),a(".ke-swfupload-startupload input",d.div).click(function(){d.swfu.startUpload()})},getUrlList:function(){var b=[];return a(".ke-img",self.bodyDiv).each(function(){var c=a(this),d=c.attr("data-status");d==SWFUpload.FILE_STATUS.COMPLETE&&b.push(c.data("data"))}),b},removeFile:function(b){var c=this;c.swfu.cancelUpload(b);var d=a('div[data-id="'+b+'"]',c.bodyDiv);a(".ke-photo",d).unbind(),a(".ke-delete",d).unbind(),d.remove()},removeFiles:function(){var b=this;a(".ke-item",b.bodyDiv).each(function(){b.removeFile(a(this).attr("data-id"))})},appendFile:function(b){var c=this,d=a('<div class="ke-inline-block ke-item" data-id="'+b.id+'"></div>');c.bodyDiv.append(d);var e=a('<div class="ke-inline-block ke-photo"></div>').mouseover(function(){a(this).addClass("ke-on")}).mouseout(function(){a(this).removeClass("ke-on")});d.append(e);var f=a('<img src="'+b.url+'" class="ke-img" data-status="'+b.filestatus+'" width="80" height="80" alt="'+b.name+'" />');e.append(f),a('<span class="ke-delete"></span>').appendTo(e).click(function(){c.removeFile(b.id)});var g=a('<div class="ke-status"></div>').appendTo(e);a(['<div class="ke-progressbar">','<div class="ke-progressbar-bar"><div class="ke-progressbar-bar-inner"></div></div>','<div class="ke-progressbar-percent">0%</div></div>'].join("")).hide().appendTo(g),a('<div class="ke-message">'+c.options.pendingMessage+"</div>").appendTo(g),d.append('<div class="ke-name">'+b.name+"</div>"),c.progressbars[b.id]={bar:a(".ke-progressbar-bar-inner",e),percent:a(".ke-progressbar-percent",e)}},remove:function(){this.removeFiles(),this.swfu.destroy(),this.div.html("")}}),a.swfupload=function(a,c){return new b(a,c)}}(KindEditor),KindEditor.plugin("multiimage",function(a){var b=this,c="multiimage",d=(a.undef(b.formatUploadUrl,!0),a.undef(b.uploadJson,b.basePath+"php/upload_json.php")),e=b.pluginsPath+"multiimage/images/",f=a.undef(b.imageSizeLimit,"1MB"),g=(a.undef(b.imageFileTypes,"*.jpg;*.gif;*.png"),a.undef(b.imageUploadLimit,20)),h=a.undef(b.filePostName,"imgFile"),i=b.lang(c+".");b.plugin.multiImageDialog=function(j){var k=j.clickFn,l=a.tmpl(i.uploadDesc,{uploadLimit:g,sizeLimit:f}),m=['<div style="padding:20px;">','<div class="swfupload">',"</div>","</div>"].join(""),n=b.createDialog({name:c,width:650,height:510,title:b.lang(c),body:m,previewBtn:{name:i.insertAll,click:function(){k.call(b,p.getUrlList())}},yesBtn:{name:i.clearAll,click:function(){p.removeFiles()}},beforeRemove:function(){(!a.IE||a.V<=8)&&p.remove()}}),o=n.div,p=a.swfupload({container:a(".swfupload",o),buttonImageUrl:e+("zh-CN"==b.langType?"select-files-zh-CN.png":"select-files-en.png"),buttonWidth:"zh-CN"==b.langType?72:88,buttonHeight:23,fileIconUrl:e+"image.png",uploadDesc:l,startButtonValue:i.startUpload,uploadUrl:a.addParam(d,"dir=image"),flashUrl:e+"swfupload.swf",filePostName:h,fileTypes:"*.jpg;*.jpeg;*.gif;*.png;*.bmp",fileTypesDesc:"Image Files",fileUploadLimit:g,fileSizeLimit:f,postParams:a.undef(b.extraFileUploadParams,{}),queueLimitExceeded:i.queueLimitExceeded,fileExceedsSizeLimit:i.fileExceedsSizeLimit,zeroByteFile:i.zeroByteFile,invalidFiletype:i.invalidFiletype,unknownError:i.unknownError,pendingMessage:i.pending,errorMessage:i.uploadError,afterError:function(a){b.errorDialog(a)}});return n},b.clickToolbar(c,function(){b.plugin.multiImageDialog({clickFn:function(c){0!==c.length&&(a.each(c,function(a,c){b.afterUpload&&b.afterUpload.call(b,c.url,c,"multiimage"),b.exec("insertimage",c.url,c.title,c.width,c.height,c.border,c.align)}),setTimeout(function(){b.hideDialog().focus()},0))}})})}),function(){window.SWFUpload=function(a){this.initSWFUpload(a)},SWFUpload.prototype.initSWFUpload=function(a){try{this.customSettings={},this.settings=a,this.eventQueue=[],this.movieName="KindEditor_SWFUpload_"+SWFUpload.movieCount++,this.movieElement=null,SWFUpload.instances[this.movieName]=this,this.initSettings(),this.loadFlash(),this.displayDebugInfo()}catch(b){throw delete SWFUpload.instances[this.movieName],b}},SWFUpload.instances={},SWFUpload.movieCount=0,SWFUpload.version="2.2.0 2009-03-25",SWFUpload.QUEUE_ERROR={QUEUE_LIMIT_EXCEEDED:-100,FILE_EXCEEDS_SIZE_LIMIT:-110,ZERO_BYTE_FILE:-120,INVALID_FILETYPE:-130},SWFUpload.UPLOAD_ERROR={HTTP_ERROR:-200,MISSING_UPLOAD_URL:-210,IO_ERROR:-220,SECURITY_ERROR:-230,UPLOAD_LIMIT_EXCEEDED:-240,UPLOAD_FAILED:-250,SPECIFIED_FILE_ID_NOT_FOUND:-260,FILE_VALIDATION_FAILED:-270,FILE_CANCELLED:-280,UPLOAD_STOPPED:-290},SWFUpload.FILE_STATUS={QUEUED:-1,IN_PROGRESS:-2,ERROR:-3,COMPLETE:-4,CANCELLED:-5},SWFUpload.BUTTON_ACTION={SELECT_FILE:-100,SELECT_FILES:-110,START_UPLOAD:-120},SWFUpload.CURSOR={ARROW:-1,HAND:-2},SWFUpload.WINDOW_MODE={WINDOW:"window",TRANSPARENT:"transparent",OPAQUE:"opaque"},SWFUpload.completeURL=function(a){if("string"!=typeof a||a.match(/^https?:\/\//i)||a.match(/^\//))return a;var b=(window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:""),window.location.pathname.lastIndexOf("/"));return path=0>=b?"/":window.location.pathname.substr(0,b)+"/",path+a},SWFUpload.prototype.initSettings=function(){this.ensureDefault=function(a,b){this.settings[a]=void 0==this.settings[a]?b:this.settings[a]},this.ensureDefault("upload_url",""),this.ensureDefault("preserve_relative_urls",!1),this.ensureDefault("file_post_name","Filedata"),this.ensureDefault("post_params",{}),this.ensureDefault("use_query_string",!1),this.ensureDefault("requeue_on_error",!1),this.ensureDefault("http_success",[]),this.ensureDefault("assume_success_timeout",0),this.ensureDefault("file_types","*.*"),this.ensureDefault("file_types_description","All Files"),this.ensureDefault("file_size_limit",0),this.ensureDefault("file_upload_limit",0),this.ensureDefault("file_queue_limit",0),this.ensureDefault("flash_url","swfupload.swf"),this.ensureDefault("prevent_swf_caching",!0),this.ensureDefault("button_image_url",""),this.ensureDefault("button_width",1),this.ensureDefault("button_height",1),this.ensureDefault("button_text",""),this.ensureDefault("button_text_style","color: #000000; font-size: 16pt;"),this.ensureDefault("button_text_top_padding",0),this.ensureDefault("button_text_left_padding",0),this.ensureDefault("button_action",SWFUpload.BUTTON_ACTION.SELECT_FILES),this.ensureDefault("button_disabled",!1),this.ensureDefault("button_placeholder_id",""),this.ensureDefault("button_placeholder",null),this.ensureDefault("button_cursor",SWFUpload.CURSOR.ARROW),this.ensureDefault("button_window_mode",SWFUpload.WINDOW_MODE.WINDOW),this.ensureDefault("debug",!1),this.settings.debug_enabled=this.settings.debug,this.settings.return_upload_start_handler=this.returnUploadStart,this.ensureDefault("swfupload_loaded_handler",null),this.ensureDefault("file_dialog_start_handler",null),this.ensureDefault("file_queued_handler",null),this.ensureDefault("file_queue_error_handler",null),this.ensureDefault("file_dialog_complete_handler",null),this.ensureDefault("upload_start_handler",null),this.ensureDefault("upload_progress_handler",null),this.ensureDefault("upload_error_handler",null),this.ensureDefault("upload_success_handler",null),this.ensureDefault("upload_complete_handler",null),this.ensureDefault("debug_handler",this.debugMessage),this.ensureDefault("custom_settings",{}),this.customSettings=this.settings.custom_settings,this.settings.prevent_swf_caching&&(this.settings.flash_url=this.settings.flash_url+(this.settings.flash_url.indexOf("?")<0?"?":"&")+"preventswfcaching="+(new Date).getTime()),this.settings.preserve_relative_urls||(this.settings.upload_url=SWFUpload.completeURL(this.settings.upload_url),this.settings.button_image_url=SWFUpload.completeURL(this.settings.button_image_url)),delete this.ensureDefault},SWFUpload.prototype.loadFlash=function(){var a,b;if(null!==document.getElementById(this.movieName))throw"ID "+this.movieName+" is already in use. The Flash Object could not be added";if(a=document.getElementById(this.settings.button_placeholder_id)||this.settings.button_placeholder,void 0==a)throw"Could not find the placeholder element: "+this.settings.button_placeholder_id;b=document.createElement("div"),b.innerHTML=this.getFlashHTML(),a.parentNode.replaceChild(b.firstChild,a),void 0==window[this.movieName]&&(window[this.movieName]=this.getMovieElement())},SWFUpload.prototype.getFlashHTML=function(){var a="";return KindEditor.IE&&KindEditor.V>8&&(a=' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'),['<object id="',this.movieName,'"'+a+' type="application/x-shockwave-flash" data="',this.settings.flash_url,'" width="',this.settings.button_width,'" height="',this.settings.button_height,'" class="swfupload">','<param name="wmode" value="',this.settings.button_window_mode,'" />','<param name="movie" value="',this.settings.flash_url,'" />','<param name="quality" value="high" />','<param name="menu" value="false" />','<param name="allowScriptAccess" value="always" />','<param name="flashvars" value="'+this.getFlashVars()+'" />',"</object>"].join("")},SWFUpload.prototype.getFlashVars=function(){var a=this.buildParamString(),b=this.settings.http_success.join(",");return["movieName=",encodeURIComponent(this.movieName),"&amp;uploadURL=",encodeURIComponent(this.settings.upload_url),"&amp;useQueryString=",encodeURIComponent(this.settings.use_query_string),"&amp;requeueOnError=",encodeURIComponent(this.settings.requeue_on_error),"&amp;httpSuccess=",encodeURIComponent(b),"&amp;assumeSuccessTimeout=",encodeURIComponent(this.settings.assume_success_timeout),"&amp;params=",encodeURIComponent(a),"&amp;filePostName=",encodeURIComponent(this.settings.file_post_name),"&amp;fileTypes=",encodeURIComponent(this.settings.file_types),"&amp;fileTypesDescription=",encodeURIComponent(this.settings.file_types_description),"&amp;fileSizeLimit=",encodeURIComponent(this.settings.file_size_limit),"&amp;fileUploadLimit=",encodeURIComponent(this.settings.file_upload_limit),"&amp;fileQueueLimit=",encodeURIComponent(this.settings.file_queue_limit),"&amp;debugEnabled=",encodeURIComponent(this.settings.debug_enabled),"&amp;buttonImageURL=",encodeURIComponent(this.settings.button_image_url),"&amp;buttonWidth=",encodeURIComponent(this.settings.button_width),"&amp;buttonHeight=",encodeURIComponent(this.settings.button_height),"&amp;buttonText=",encodeURIComponent(this.settings.button_text),"&amp;buttonTextTopPadding=",encodeURIComponent(this.settings.button_text_top_padding),"&amp;buttonTextLeftPadding=",encodeURIComponent(this.settings.button_text_left_padding),"&amp;buttonTextStyle=",encodeURIComponent(this.settings.button_text_style),"&amp;buttonAction=",encodeURIComponent(this.settings.button_action),"&amp;buttonDisabled=",encodeURIComponent(this.settings.button_disabled),"&amp;buttonCursor=",encodeURIComponent(this.settings.button_cursor)].join("")},SWFUpload.prototype.getMovieElement=function(){if(void 0==this.movieElement&&(this.movieElement=document.getElementById(this.movieName)),null===this.movieElement)throw"Could not find Flash element";return this.movieElement},SWFUpload.prototype.buildParamString=function(){var a=this.settings.post_params,b=[];if("object"==typeof a)for(var c in a)a.hasOwnProperty(c)&&b.push(encodeURIComponent(c.toString())+"="+encodeURIComponent(a[c].toString()));return b.join("&amp;")},SWFUpload.prototype.destroy=function(){try{this.cancelUpload(null,!1);var a=null;if(a=this.getMovieElement(),a&&"unknown"==typeof a.CallFunction){for(var b in a)try{"function"==typeof a[b]&&(a[b]=null)}catch(c){}try{a.parentNode.removeChild(a)}catch(d){}}return window[this.movieName]=null,SWFUpload.instances[this.movieName]=null,delete SWFUpload.instances[this.movieName],this.movieElement=null,this.settings=null,this.customSettings=null,this.eventQueue=null,this.movieName=null,!0}catch(e){return!1}},SWFUpload.prototype.displayDebugInfo=function(){this.debug(["---SWFUpload Instance Info---\n","Version: ",SWFUpload.version,"\n","Movie Name: ",this.movieName,"\n","Settings:\n"," ","upload_url: ",this.settings.upload_url,"\n"," ","flash_url: ",this.settings.flash_url,"\n"," ","use_query_string: ",this.settings.use_query_string.toString(),"\n"," ","requeue_on_error: ",this.settings.requeue_on_error.toString(),"\n"," ","http_success: ",this.settings.http_success.join(", "),"\n"," ","assume_success_timeout: ",this.settings.assume_success_timeout,"\n"," ","file_post_name: ",this.settings.file_post_name,"\n"," ","post_params: ",this.settings.post_params.toString(),"\n"," ","file_types: ",this.settings.file_types,"\n"," ","file_types_description: ",this.settings.file_types_description,"\n"," ","file_size_limit: ",this.settings.file_size_limit,"\n"," ","file_upload_limit: ",this.settings.file_upload_limit,"\n"," ","file_queue_limit: ",this.settings.file_queue_limit,"\n"," ","debug: ",this.settings.debug.toString(),"\n"," ","prevent_swf_caching: ",this.settings.prevent_swf_caching.toString(),"\n"," ","button_placeholder_id: ",this.settings.button_placeholder_id.toString(),"\n"," ","button_placeholder: ",this.settings.button_placeholder?"Set":"Not Set","\n"," ","button_image_url: ",this.settings.button_image_url.toString(),"\n"," ","button_width: ",this.settings.button_width.toString(),"\n"," ","button_height: ",this.settings.button_height.toString(),"\n"," ","button_text: ",this.settings.button_text.toString(),"\n"," ","button_text_style: ",this.settings.button_text_style.toString(),"\n"," ","button_text_top_padding: ",this.settings.button_text_top_padding.toString(),"\n"," ","button_text_left_padding: ",this.settings.button_text_left_padding.toString(),"\n"," ","button_action: ",this.settings.button_action.toString(),"\n"," ","button_disabled: ",this.settings.button_disabled.toString(),"\n"," ","custom_settings: ",this.settings.custom_settings.toString(),"\n","Event Handlers:\n"," ","swfupload_loaded_handler assigned: ",("function"==typeof this.settings.swfupload_loaded_handler).toString(),"\n"," ","file_dialog_start_handler assigned: ",("function"==typeof this.settings.file_dialog_start_handler).toString(),"\n"," ","file_queued_handler assigned: ",("function"==typeof this.settings.file_queued_handler).toString(),"\n"," ","file_queue_error_handler assigned: ",("function"==typeof this.settings.file_queue_error_handler).toString(),"\n"," ","upload_start_handler assigned: ",("function"==typeof this.settings.upload_start_handler).toString(),"\n"," ","upload_progress_handler assigned: ",("function"==typeof this.settings.upload_progress_handler).toString(),"\n"," ","upload_error_handler assigned: ",("function"==typeof this.settings.upload_error_handler).toString(),"\n"," ","upload_success_handler assigned: ",("function"==typeof this.settings.upload_success_handler).toString(),"\n"," ","upload_complete_handler assigned: ",("function"==typeof this.settings.upload_complete_handler).toString(),"\n"," ","debug_handler assigned: ",("function"==typeof this.settings.debug_handler).toString(),"\n"].join(""))},SWFUpload.prototype.addSetting=function(a,b,c){return this.settings[a]=void 0==b?c:b},SWFUpload.prototype.getSetting=function(a){return void 0!=this.settings[a]?this.settings[a]:""},SWFUpload.prototype.callFlash=function(functionName,argumentArray){argumentArray=argumentArray||[];var movieElement=this.getMovieElement(),returnValue,returnString;try{returnString=movieElement.CallFunction('<invoke name="'+functionName+'" returntype="javascript">'+__flash__argumentsToXML(argumentArray,0)+"</invoke>"),returnValue=eval(returnString)}catch(ex){throw"Call to "+functionName+" failed"}return void 0!=returnValue&&"object"==typeof returnValue.post&&(returnValue=this.unescapeFilePostParams(returnValue)),returnValue},SWFUpload.prototype.selectFile=function(){this.callFlash("SelectFile")},SWFUpload.prototype.selectFiles=function(){this.callFlash("SelectFiles")},SWFUpload.prototype.startUpload=function(a){this.callFlash("StartUpload",[a])},SWFUpload.prototype.cancelUpload=function(a,b){b!==!1&&(b=!0),this.callFlash("CancelUpload",[a,b])},SWFUpload.prototype.stopUpload=function(){this.callFlash("StopUpload")},SWFUpload.prototype.getStats=function(){return this.callFlash("GetStats")},SWFUpload.prototype.setStats=function(a){this.callFlash("SetStats",[a])},SWFUpload.prototype.getFile=function(a){return"number"==typeof a?this.callFlash("GetFileByIndex",[a]):this.callFlash("GetFile",[a])},SWFUpload.prototype.addFileParam=function(a,b,c){return this.callFlash("AddFileParam",[a,b,c])},SWFUpload.prototype.removeFileParam=function(a,b){this.callFlash("RemoveFileParam",[a,b])},SWFUpload.prototype.setUploadURL=function(a){this.settings.upload_url=a.toString(),this.callFlash("SetUploadURL",[a])},SWFUpload.prototype.setPostParams=function(a){this.settings.post_params=a,this.callFlash("SetPostParams",[a])},SWFUpload.prototype.addPostParam=function(a,b){this.settings.post_params[a]=b,this.callFlash("SetPostParams",[this.settings.post_params])},SWFUpload.prototype.removePostParam=function(a){delete this.settings.post_params[a],this.callFlash("SetPostParams",[this.settings.post_params])},SWFUpload.prototype.setFileTypes=function(a,b){this.settings.file_types=a,this.settings.file_types_description=b,this.callFlash("SetFileTypes",[a,b])},SWFUpload.prototype.setFileSizeLimit=function(a){this.settings.file_size_limit=a,this.callFlash("SetFileSizeLimit",[a])},SWFUpload.prototype.setFileUploadLimit=function(a){this.settings.file_upload_limit=a,this.callFlash("SetFileUploadLimit",[a])},SWFUpload.prototype.setFileQueueLimit=function(a){this.settings.file_queue_limit=a,this.callFlash("SetFileQueueLimit",[a])},SWFUpload.prototype.setFilePostName=function(a){this.settings.file_post_name=a,this.callFlash("SetFilePostName",[a])},SWFUpload.prototype.setUseQueryString=function(a){this.settings.use_query_string=a,this.callFlash("SetUseQueryString",[a])},SWFUpload.prototype.setRequeueOnError=function(a){this.settings.requeue_on_error=a,this.callFlash("SetRequeueOnError",[a])},SWFUpload.prototype.setHTTPSuccess=function(a){"string"==typeof a&&(a=a.replace(" ","").split(",")),this.settings.http_success=a,this.callFlash("SetHTTPSuccess",[a])},SWFUpload.prototype.setAssumeSuccessTimeout=function(a){this.settings.assume_success_timeout=a,this.callFlash("SetAssumeSuccessTimeout",[a])},SWFUpload.prototype.setDebugEnabled=function(a){this.settings.debug_enabled=a,this.callFlash("SetDebugEnabled",[a])},SWFUpload.prototype.setButtonImageURL=function(a){void 0==a&&(a=""),this.settings.button_image_url=a,this.callFlash("SetButtonImageURL",[a])},SWFUpload.prototype.setButtonDimensions=function(a,b){this.settings.button_width=a,this.settings.button_height=b;var c=this.getMovieElement();void 0!=c&&(c.style.width=a+"px",c.style.height=b+"px"),this.callFlash("SetButtonDimensions",[a,b])},SWFUpload.prototype.setButtonText=function(a){this.settings.button_text=a,this.callFlash("SetButtonText",[a])},SWFUpload.prototype.setButtonTextPadding=function(a,b){this.settings.button_text_top_padding=b,this.settings.button_text_left_padding=a,this.callFlash("SetButtonTextPadding",[a,b])},SWFUpload.prototype.setButtonTextStyle=function(a){this.settings.button_text_style=a,this.callFlash("SetButtonTextStyle",[a])},SWFUpload.prototype.setButtonDisabled=function(a){this.settings.button_disabled=a,this.callFlash("SetButtonDisabled",[a])},SWFUpload.prototype.setButtonAction=function(a){this.settings.button_action=a,this.callFlash("SetButtonAction",[a])},SWFUpload.prototype.setButtonCursor=function(a){this.settings.button_cursor=a,this.callFlash("SetButtonCursor",[a])},SWFUpload.prototype.queueEvent=function(a,b){void 0==b?b=[]:b instanceof Array||(b=[b]);var c=this;if("function"==typeof this.settings[a])this.eventQueue.push(function(){this.settings[a].apply(this,b) +}),setTimeout(function(){c.executeNextEvent()},0);else if(null!==this.settings[a])throw"Event handler "+a+" is unknown or is not a function"},SWFUpload.prototype.executeNextEvent=function(){var a=this.eventQueue?this.eventQueue.shift():null;"function"==typeof a&&a.apply(this)},SWFUpload.prototype.unescapeFilePostParams=function(a){var b,c=/[$]([0-9a-f]{4})/i,d={};if(void 0!=a){for(var e in a.post)if(a.post.hasOwnProperty(e)){b=e;for(var f;null!==(f=c.exec(b));)b=b.replace(f[0],String.fromCharCode(parseInt("0x"+f[1],16)));d[b]=a.post[e]}a.post=d}return a},SWFUpload.prototype.testExternalInterface=function(){try{return this.callFlash("TestExternalInterface")}catch(a){return!1}},SWFUpload.prototype.flashReady=function(){var a=this.getMovieElement();return a?(this.cleanUp(a),void this.queueEvent("swfupload_loaded_handler")):void this.debug("Flash called back ready but the flash movie can't be found.")},SWFUpload.prototype.cleanUp=function(a){try{if(this.movieElement&&"unknown"==typeof a.CallFunction){this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)");for(var b in a)try{"function"==typeof a[b]&&(a[b]=null)}catch(c){}}}catch(d){}window.__flash__removeCallback=function(a,b){try{a&&(a[b]=null)}catch(c){}}},SWFUpload.prototype.fileDialogStart=function(){this.queueEvent("file_dialog_start_handler")},SWFUpload.prototype.fileQueued=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("file_queued_handler",a)},SWFUpload.prototype.fileQueueError=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("file_queue_error_handler",[a,b,c])},SWFUpload.prototype.fileDialogComplete=function(a,b,c){this.queueEvent("file_dialog_complete_handler",[a,b,c])},SWFUpload.prototype.uploadStart=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("return_upload_start_handler",a)},SWFUpload.prototype.returnUploadStart=function(a){var b;if("function"==typeof this.settings.upload_start_handler)a=this.unescapeFilePostParams(a),b=this.settings.upload_start_handler.call(this,a);else if(void 0!=this.settings.upload_start_handler)throw"upload_start_handler must be a function";void 0===b&&(b=!0),b=!!b,this.callFlash("ReturnUploadStart",[b])},SWFUpload.prototype.uploadProgress=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_progress_handler",[a,b,c])},SWFUpload.prototype.uploadError=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_error_handler",[a,b,c])},SWFUpload.prototype.uploadSuccess=function(a,b,c){a=this.unescapeFilePostParams(a),this.queueEvent("upload_success_handler",[a,b,c])},SWFUpload.prototype.uploadComplete=function(a){a=this.unescapeFilePostParams(a),this.queueEvent("upload_complete_handler",a)},SWFUpload.prototype.debug=function(a){this.queueEvent("debug_handler",a)},SWFUpload.prototype.debugMessage=function(a){if(this.settings.debug){var b,c=[];if("object"==typeof a&&"string"==typeof a.name&&"string"==typeof a.message){for(var d in a)a.hasOwnProperty(d)&&c.push(d+": "+a[d]);b=c.join("\n")||"",c=b.split("\n"),b="EXCEPTION: "+c.join("\nEXCEPTION: "),SWFUpload.Console.writeLine(b)}else SWFUpload.Console.writeLine(a)}},SWFUpload.Console={},SWFUpload.Console.writeLine=function(a){var b,c;try{b=document.getElementById("SWFUpload_Console"),b||(c=document.createElement("form"),document.getElementsByTagName("body")[0].appendChild(c),b=document.createElement("textarea"),b.id="SWFUpload_Console",b.style.fontFamily="monospace",b.setAttribute("wrap","off"),b.wrap="off",b.style.overflow="auto",b.style.width="700px",b.style.height="350px",b.style.margin="5px",c.appendChild(b)),b.value+=a+"\n",b.scrollTop=b.scrollHeight-b.clientHeight}catch(d){alert("Exception: "+d.name+" Message: "+d.message)}}}(),function(){"function"==typeof SWFUpload&&(SWFUpload.queue={},SWFUpload.prototype.initSettings=function(a){return function(){"function"==typeof a&&a.call(this),this.queueSettings={},this.queueSettings.queue_cancelled_flag=!1,this.queueSettings.queue_upload_count=0,this.queueSettings.user_upload_complete_handler=this.settings.upload_complete_handler,this.queueSettings.user_upload_start_handler=this.settings.upload_start_handler,this.settings.upload_complete_handler=SWFUpload.queue.uploadCompleteHandler,this.settings.upload_start_handler=SWFUpload.queue.uploadStartHandler,this.settings.queue_complete_handler=this.settings.queue_complete_handler||null}}(SWFUpload.prototype.initSettings),SWFUpload.prototype.startUpload=function(a){this.queueSettings.queue_cancelled_flag=!1,this.callFlash("StartUpload",[a])},SWFUpload.prototype.cancelQueue=function(){this.queueSettings.queue_cancelled_flag=!0,this.stopUpload();for(var a=this.getStats();a.files_queued>0;)this.cancelUpload(),a=this.getStats()},SWFUpload.queue.uploadStartHandler=function(a){var b;return"function"==typeof this.queueSettings.user_upload_start_handler&&(b=this.queueSettings.user_upload_start_handler.call(this,a)),b=b===!1?!1:!0,this.queueSettings.queue_cancelled_flag=!b,b},SWFUpload.queue.uploadCompleteHandler=function(a){var b,c=this.queueSettings.user_upload_complete_handler;if(a.filestatus===SWFUpload.FILE_STATUS.COMPLETE&&this.queueSettings.queue_upload_count++,b="function"==typeof c?c.call(this,a)===!1?!1:!0:a.filestatus===SWFUpload.FILE_STATUS.QUEUED?!1:!0){var d=this.getStats();d.files_queued>0&&this.queueSettings.queue_cancelled_flag===!1?this.startUpload():this.queueSettings.queue_cancelled_flag===!1?(this.queueEvent("queue_complete_handler",[this.queueSettings.queue_upload_count]),this.queueSettings.queue_upload_count=0):(this.queueSettings.queue_cancelled_flag=!1,this.queueSettings.queue_upload_count=0)}})}(),KindEditor.plugin("pagebreak",function(a){var b=this,c="pagebreak",d=a.undef(b.pagebreakHtml,'<hr style="page-break-after: always;" class="ke-pagebreak" />');b.clickToolbar(c,function(){var c=b.cmd,e=c.range;b.focus();var f="br"==b.newlineTag||a.WEBKIT?"":'<span id="__kindeditor_tail_tag__"></span>';if(b.insertHtml(d+f),""!==f){var g=a("#__kindeditor_tail_tag__",b.edit.doc);e.selectNodeContents(g[0]),g.removeAttr("id"),c.select()}})}),KindEditor.plugin("plainpaste",function(a){var b=this,c="plainpaste";b.clickToolbar(c,function(){var d=b.lang(c+"."),e='<div style="padding:10px 20px;"><div style="margin-bottom:10px;">'+d.comment+'</div><textarea class="ke-textarea" style="width:408px;height:260px;"></textarea></div>',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=g.val();c=a.escape(c),c=c.replace(/ {2}/g," &nbsp;"),c="p"==b.newlineTag?c.replace(/^/,"<p>").replace(/$/,"</p>").replace(/\n/g,"</p><p>"):c.replace(/\n/g,"<br />$&"),b.insertHtml(c).hideDialog().focus()}}}),g=a("textarea",f.div);g[0].focus()})}),KindEditor.plugin("preview",function(a){var b=this,c="preview";b.clickToolbar(c,function(){var d=(b.lang(c+"."),'<div style="padding:10px 20px;"><iframe class="ke-textarea" frameborder="0" style="width:708px;height:400px;"></iframe></div>'),e=b.createDialog({name:c,width:750,title:b.lang(c),body:d}),f=a("iframe",e.div),g=a.iframeDoc(f);g.open(),g.write(b.fullHtml()),g.close(),a(g.body).css("background-color","#FFF"),f[0].contentWindow.focus()})}),KindEditor.plugin("quickformat",function(a){function b(a){for(var b=a.first();b&&b.first();)b=b.first();return b}var c=this,d="quickformat",e=a.toMap("blockquote,center,div,h1,h2,h3,h4,h5,h6,p");c.clickToolbar(d,function(){c.focus();for(var d,f=c.edit.doc,g=c.cmd.range,h=a(f.body).first(),i=[],j=[],k=g.createBookmark(!0);h;){d=h.next();var l=b(h);l&&"img"==l.name||(e[h.name]?(h.html(h.html().replace(/^(\s|&nbsp;| )+/gi,"")),h.css("text-indent","2em")):j.push(h),(!d||e[d.name]||e[h.name]&&!e[d.name])&&(j.length>0&&i.push(j),j=[])),h=d}a.each(i,function(b,c){var d=a('<p style="text-indent:2em;"></p>',f);c[0].before(d),a.each(c,function(a,b){d.append(b)})}),g.moveToBookmark(k),c.addBookmark()})}),KindEditor.plugin("table",function(a){function b(a,b){b=b.toUpperCase(),a.css("background-color",b),a.css("color","#000000"===b?"#FFFFFF":"#000000"),a.html(b)}function c(c,d){function f(){a.each(i,function(){this.remove()}),i=[],a(document).unbind("click,mousedown",f),c.unbind("click,mousedown",f)}d.bind("click,mousedown",function(a){a.stopPropagation()}),d.click(function(){f();var d=a(this),g=d.pos(),h=a.colorpicker({x:g.x,y:g.y+d.height(),z:811214,selectedColor:a(this).html(),colors:e.colorTable,noColor:e.lang("noColor"),shadowMode:e.shadowMode,click:function(a){b(d,a),f()}});i.push(h),a(document).bind("click,mousedown",f),c.bind("click,mousedown",f)})}function d(a,b,c){for(var d=0,e=0,f=b.cells.length;f>e&&b.cells[e]!=c;e++)d+=b.cells[e].rowSpan-1;return c.cellIndex-d}var e=this,f="table",g=e.lang(f+"."),h="ke-zeroborder",i=[];e.plugin.table={prop:function(d){var i=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keRows" style="width:90px;">'+g.cells+"</label>",g.rows+' <input type="text" id="keRows" class="ke-input-text ke-input-number" name="rows" value="" maxlength="4" /> &nbsp; ',g.cols+' <input type="text" class="ke-input-text ke-input-number" name="cols" value="" maxlength="4" />',"</div>",'<div class="ke-dialog-row">','<label for="keWidth" style="width:90px;">'+g.size+"</label>",g.width+' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ','<select name="widthType">','<option value="%">'+g.percent+"</option>",'<option value="px">'+g.px+"</option>","</select> &nbsp; ",g.height+' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ','<select name="heightType">','<option value="%">'+g.percent+"</option>",'<option value="px">'+g.px+"</option>","</select>","</div>",'<div class="ke-dialog-row">','<label for="kePadding" style="width:90px;">'+g.space+"</label>",g.padding+' <input type="text" id="kePadding" class="ke-input-text ke-input-number" name="padding" value="" maxlength="4" /> &nbsp; ',g.spacing+' <input type="text" class="ke-input-text ke-input-number" name="spacing" value="" maxlength="4" />',"</div>",'<div class="ke-dialog-row">','<label for="keAlign" style="width:90px;">'+g.align+"</label>",'<select id="keAlign" name="align">','<option value="">'+g.alignDefault+"</option>",'<option value="left">'+g.alignLeft+"</option>",'<option value="center">'+g.alignCenter+"</option>",'<option value="right">'+g.alignRight+"</option>","</select>","</div>",'<div class="ke-dialog-row">','<label for="keBorder" style="width:90px;">'+g.border+"</label>",g.borderWidth+' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ',g.borderColor+' <span class="ke-inline-block ke-input-color"></span>',"</div>",'<div class="ke-dialog-row">','<label for="keBgColor" style="width:90px;">'+g.backgroundColor+"</label>",'<span class="ke-inline-block ke-input-color"></span>',"</div>","</div>"].join(""),j=e.cmd.range.createBookmark(),k=e.createDialog({name:f,width:500,title:e.lang(f),body:i,beforeRemove:function(){w.unbind()},yesBtn:{name:e.lang("yes"),click:function(){var b=m.val(),c=n.val(),d=o.val(),f=p.val(),g=q.val(),i=r.val(),k=s.val(),l=t.val(),y=u.val(),z=v.val(),A=a(w[0]).html()||"",B=a(w[1]).html()||"";if(0==b||!/^\d+$/.test(b))return alert(e.lang("invalidRows")),void m[0].focus();if(0==c||!/^\d+$/.test(c))return alert(e.lang("invalidRows")),void n[0].focus();if(!/^\d*$/.test(d))return alert(e.lang("invalidWidth")),void o[0].focus();if(!/^\d*$/.test(f))return alert(e.lang("invalidHeight")),void p[0].focus();if(!/^\d*$/.test(k))return alert(e.lang("invalidPadding")),void s[0].focus();if(!/^\d*$/.test(l))return alert(e.lang("invalidSpacing")),void t[0].focus();if(!/^\d*$/.test(z))return alert(e.lang("invalidBorder")),void v[0].focus();if(x)return""!==d?x.width(d+g):x.css("width",""),void 0!==x[0].width&&x.removeAttr("width"),""!==f?x.height(f+i):x.css("height",""),void 0!==x[0].height&&x.removeAttr("height"),x.css("background-color",B),void 0!==x[0].bgColor&&x.removeAttr("bgColor"),""!==k?x[0].cellPadding=k:x.removeAttr("cellPadding"),""!==l?x[0].cellSpacing=l:x.removeAttr("cellSpacing"),""!==y?x[0].align=y:x.removeAttr("align"),""!==z?x.attr("border",z):x.removeAttr("border"),""===z||"0"===z?x.addClass(h):x.removeClass(h),""!==A?x.attr("borderColor",A):x.removeAttr("borderColor"),e.hideDialog().focus(),e.cmd.range.moveToBookmark(j),e.cmd.select(),void e.addBookmark();var C="";""!==d&&(C+="width:"+d+g+";"),""!==f&&(C+="height:"+f+i+";"),""!==B&&(C+="background-color:"+B+";");var D="<table";""!==C&&(D+=' style="'+C+'"'),""!==k&&(D+=' cellpadding="'+k+'"'),""!==l&&(D+=' cellspacing="'+l+'"'),""!==y&&(D+=' align="'+y+'"'),""!==z&&(D+=' border="'+z+'"'),(""===z||"0"===z)&&(D+=' class="'+h+'"'),""!==A&&(D+=' bordercolor="'+A+'"'),D+=">";for(var E=0;b>E;E++){D+="<tr>";for(var F=0;c>F;F++)D+="<td>"+(a.IE?"&nbsp;":"<br />")+"</td>";D+="</tr>"}D+="</table>",a.IE||(D+="<br />"),e.insertHtml(D),e.select().hideDialog().focus(),e.addBookmark()}}}),l=k.div,m=a('[name="rows"]',l).val(3),n=a('[name="cols"]',l).val(2),o=a('[name="width"]',l).val(100),p=a('[name="height"]',l),q=a('[name="widthType"]',l),r=a('[name="heightType"]',l),s=a('[name="padding"]',l).val(2),t=a('[name="spacing"]',l).val(0),u=a('[name="align"]',l),v=a('[name="border"]',l).val(1),w=a(".ke-input-color",l);c(l,w.eq(0)),c(l,w.eq(1)),b(w.eq(0),"#000000"),b(w.eq(1),""),m[0].focus(),m[0].select();var x;if(!d&&(x=e.plugin.getSelectedTable())){m.val(x[0].rows.length),n.val(x[0].rows.length>0?x[0].rows[0].cells.length:0),m.attr("disabled",!0),n.attr("disabled",!0);var y,z=x[0].style.width||x[0].width,A=x[0].style.height||x[0].height;void 0!==z&&(y=/^(\d+)((?:px|%)*)$/.exec(z))?(o.val(y[1]),q.val(y[2])):o.val(""),void 0!==A&&(y=/^(\d+)((?:px|%)*)$/.exec(A))&&(p.val(y[1]),r.val(y[2])),s.val(x[0].cellPadding||""),t.val(x[0].cellSpacing||""),u.val(x[0].align||""),v.val(void 0===x[0].border?"":x[0].border),b(w.eq(0),a.toHex(x.attr("borderColor")||"")),b(w.eq(1),a.toHex(x[0].style.backgroundColor||x[0].bgColor||"")),o[0].focus(),o[0].select()}},cellprop:function(){var d=['<div style="padding:20px;">','<div class="ke-dialog-row">','<label for="keWidth" style="width:90px;">'+g.size+"</label>",g.width+' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ','<select name="widthType">','<option value="%">'+g.percent+"</option>",'<option value="px">'+g.px+"</option>","</select> &nbsp; ",g.height+' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ','<select name="heightType">','<option value="%">'+g.percent+"</option>",'<option value="px">'+g.px+"</option>","</select>","</div>",'<div class="ke-dialog-row">','<label for="keAlign" style="width:90px;">'+g.align+"</label>",g.textAlign+' <select id="keAlign" name="textAlign">','<option value="">'+g.alignDefault+"</option>",'<option value="left">'+g.alignLeft+"</option>",'<option value="center">'+g.alignCenter+"</option>",'<option value="right">'+g.alignRight+"</option>","</select> ",g.verticalAlign+' <select name="verticalAlign">','<option value="">'+g.alignDefault+"</option>",'<option value="top">'+g.alignTop+"</option>",'<option value="middle">'+g.alignMiddle+"</option>",'<option value="bottom">'+g.alignBottom+"</option>",'<option value="baseline">'+g.alignBaseline+"</option>","</select>","</div>",'<div class="ke-dialog-row">','<label for="keBorder" style="width:90px;">'+g.border+"</label>",g.borderWidth+' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ',g.borderColor+' <span class="ke-inline-block ke-input-color"></span>',"</div>",'<div class="ke-dialog-row">','<label for="keBgColor" style="width:90px;">'+g.backgroundColor+"</label>",'<span class="ke-inline-block ke-input-color"></span>',"</div>","</div>"].join(""),h=e.cmd.range.createBookmark(),i=e.createDialog({name:f,width:500,title:e.lang("tablecell"),body:d,beforeRemove:function(){t.unbind()},yesBtn:{name:e.lang("yes"),click:function(){var b=k.val(),c=l.val(),d=m.val(),f=n.val(),g=(o.val(),p.val(),q.val()),i=r.val(),j=s.val(),u=a(t[0]).html()||"",w=a(t[1]).html()||"";return/^\d*$/.test(b)?/^\d*$/.test(c)?/^\d*$/.test(j)?(v.css({width:""!==b?b+d:"",height:""!==c?c+f:"","background-color":w,"text-align":g,"vertical-align":i,"border-width":j,"border-style":""!==j?"solid":"","border-color":u}),e.hideDialog().focus(),e.cmd.range.moveToBookmark(h),e.cmd.select(),void e.addBookmark()):(alert(e.lang("invalidBorder")),void s[0].focus()):(alert(e.lang("invalidHeight")),void l[0].focus()):(alert(e.lang("invalidWidth")),void k[0].focus())}}}),j=i.div,k=a('[name="width"]',j).val(100),l=a('[name="height"]',j),m=a('[name="widthType"]',j),n=a('[name="heightType"]',j),o=a('[name="padding"]',j).val(2),p=a('[name="spacing"]',j).val(0),q=a('[name="textAlign"]',j),r=a('[name="verticalAlign"]',j),s=a('[name="border"]',j).val(1),t=a(".ke-input-color",j);c(j,t.eq(0)),c(j,t.eq(1)),b(t.eq(0),"#000000"),b(t.eq(1),""),k[0].focus(),k[0].select();var u,v=e.plugin.getSelectedCell(),w=v[0].style.width||v[0].width||"",x=v[0].style.height||v[0].height||"";(u=/^(\d+)((?:px|%)*)$/.exec(w))?(k.val(u[1]),m.val(u[2])):k.val(""),(u=/^(\d+)((?:px|%)*)$/.exec(x))&&(l.val(u[1]),n.val(u[2])),q.val(v[0].style.textAlign||""),r.val(v[0].style.verticalAlign||"");var y=v[0].style.borderWidth||"";y&&(y=parseInt(y)),s.val(y),b(t.eq(0),a.toHex(v[0].style.borderColor||"")),b(t.eq(1),a.toHex(v[0].style.backgroundColor||"")),k[0].focus(),k[0].select()},insert:function(){this.prop(!0)},"delete":function(){var a=e.plugin.getSelectedTable();e.cmd.range.setStartBefore(a[0]).collapse(!0),e.cmd.select(),a.remove(),e.addBookmark()},colinsert:function(b){var c=e.plugin.getSelectedTable()[0],f=e.plugin.getSelectedRow()[0],g=e.plugin.getSelectedCell()[0],h=g.cellIndex+b;h+=c.rows[0].cells.length-f.cells.length;for(var i=0,j=c.rows.length;j>i;i++){var k=c.rows[i],l=k.insertCell(h);l.innerHTML=a.IE?"":"<br />",h=d(c,k,l)}e.cmd.range.selectNodeContents(g).collapse(!0),e.cmd.select(),e.addBookmark()},colinsertleft:function(){this.colinsert(0)},colinsertright:function(){this.colinsert(1)},rowinsert:function(b){var c=e.plugin.getSelectedTable()[0],d=e.plugin.getSelectedRow()[0],f=e.plugin.getSelectedCell()[0],g=d.rowIndex;1===b&&(g=d.rowIndex+(f.rowSpan-1)+b);for(var h=c.insertRow(g),i=0,j=d.cells.length;j>i;i++){d.cells[i].rowSpan>1&&(j-=d.cells[i].rowSpan-1);var k=h.insertCell(i);1===b&&d.cells[i].colSpan>1&&(k.colSpan=d.cells[i].colSpan),k.innerHTML=a.IE?"":"<br />"}for(var l=g;l>=0;l--){var m=c.rows[l].cells;if(m.length>i){for(var n=f.cellIndex;n>=0;n--)m[n].rowSpan>1&&(m[n].rowSpan+=1);break}}e.cmd.range.selectNodeContents(f).collapse(!0),e.cmd.select(),e.addBookmark()},rowinsertabove:function(){this.rowinsert(0)},rowinsertbelow:function(){this.rowinsert(1)},rowmerge:function(){var a=e.plugin.getSelectedTable()[0],b=e.plugin.getSelectedRow()[0],c=e.plugin.getSelectedCell()[0],d=b.rowIndex,f=d+c.rowSpan,g=a.rows[f];if(!(a.rows.length<=f)){var h=c.cellIndex;if(!(g.cells.length<=h)){var i=g.cells[h];c.colSpan===i.colSpan&&(c.rowSpan+=i.rowSpan,g.deleteCell(h),e.cmd.range.selectNodeContents(c).collapse(!0),e.cmd.select(),e.addBookmark())}}},colmerge:function(){var a=(e.plugin.getSelectedTable()[0],e.plugin.getSelectedRow()[0]),b=e.plugin.getSelectedCell()[0],c=(a.rowIndex,b.cellIndex),d=c+1;if(!(a.cells.length<=d)){var f=a.cells[d];b.rowSpan===f.rowSpan&&(b.colSpan+=f.colSpan,a.deleteCell(d),e.cmd.range.selectNodeContents(b).collapse(!0),e.cmd.select(),e.addBookmark())}},rowsplit:function(){var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],f=e.plugin.getSelectedCell()[0],g=c.rowIndex;if(1!==f.rowSpan){for(var h=d(b,c,f),i=1,j=f.rowSpan;j>i;i++){var k=b.rows[g+i],l=k.insertCell(h);f.colSpan>1&&(l.colSpan=f.colSpan),l.innerHTML=a.IE?"":"<br />",h=d(b,k,l)}a(f).removeAttr("rowSpan"),e.cmd.range.selectNodeContents(f).collapse(!0),e.cmd.select(),e.addBookmark()}},colsplit:function(){var b=(e.plugin.getSelectedTable()[0],e.plugin.getSelectedRow()[0]),c=e.plugin.getSelectedCell()[0],d=c.cellIndex;if(1!==c.colSpan){for(var f=1,g=c.colSpan;g>f;f++){var h=b.insertCell(d+f);c.rowSpan>1&&(h.rowSpan=c.rowSpan),h.innerHTML=a.IE?"":"<br />"}a(c).removeAttr("colSpan"),e.cmd.range.selectNodeContents(c).collapse(!0),e.cmd.select(),e.addBookmark()}},coldelete:function(){for(var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],d=e.plugin.getSelectedCell()[0],f=d.cellIndex,g=0,h=b.rows.length;h>g;g++){var i=b.rows[g],j=i.cells[f];j.colSpan>1?(j.colSpan-=1,1===j.colSpan&&a(j).removeAttr("colSpan")):i.deleteCell(f),j.rowSpan>1&&(g+=j.rowSpan-1)}0===c.cells.length?(e.cmd.range.setStartBefore(b).collapse(!0),e.cmd.select(),a(b).remove()):e.cmd.selection(!0),e.addBookmark()},rowdelete:function(){for(var b=e.plugin.getSelectedTable()[0],c=e.plugin.getSelectedRow()[0],d=e.plugin.getSelectedCell()[0],f=c.rowIndex,g=d.rowSpan-1;g>=0;g--)b.deleteRow(f+g);0===b.rows.length?(e.cmd.range.setStartBefore(b).collapse(!0),e.cmd.select(),a(b).remove()):e.cmd.selection(!0),e.addBookmark()}},e.clickToolbar(f,e.plugin.table.prop)}),KindEditor.plugin("template",function(a){function b(b){return e+b+"?ver="+encodeURIComponent(a.DEBUG?a.TIME:a.VERSION)}var c=this,d="template",e=(c.lang(d+"."),c.pluginsPath+d+"/html/");c.clickToolbar(d,function(){var e=c.lang(d+"."),f=['<div style="padding:10px 20px;">','<div class="ke-header">','<div class="ke-left">',e.selectTemplate+" <select>"];a.each(e.fileList,function(a,b){f.push('<option value="'+a+'">'+b+"</option>")}),html=[f.join(""),"</select></div>",'<div class="ke-right">','<input type="checkbox" id="keReplaceFlag" name="replaceFlag" value="1" /> <label for="keReplaceFlag">'+e.replaceContent+"</label>","</div>",'<div class="ke-clearfix"></div>',"</div>",'<iframe class="ke-textarea" frameborder="0" style="width:458px;height:260px;background-color:#FFF;"></iframe>',"</div>"].join("");var g=c.createDialog({name:d,width:500,title:c.lang(d),body:html,yesBtn:{name:c.lang("yes"),click:function(){var b=a.iframeDoc(j);c[i[0].checked?"html":"insertHtml"](b.body.innerHTML).hideDialog().focus()}}}),h=a("select",g.div),i=a('[name="replaceFlag"]',g.div),j=a("iframe",g.div);i[0].checked=!0,j.attr("src",b(h.val())),h.change(function(){j.attr("src",b(this.value))})})}),KindEditor.plugin("wordpaste",function(a){var b=this,c="wordpaste";b.clickToolbar(c,function(){var d=b.lang(c+"."),e='<div style="padding:10px 20px;"><div style="margin-bottom:10px;">'+d.comment+'</div><iframe class="ke-textarea" frameborder="0" style="width:408px;height:260px;"></iframe></div>',f=b.createDialog({name:c,width:450,title:b.lang(c),body:e,yesBtn:{name:b.lang("yes"),click:function(){var c=i.body.innerHTML;c=a.clearMsWord(c,b.filterMode?b.htmlTags:a.options.htmlTags),b.insertHtml(c).hideDialog().focus()}}}),g=f.div,h=a("iframe",g),i=a.iframeDoc(h);a.IE||(i.designMode="on"),i.open(),i.write("<!doctype html><html><head><title>WordPaste</title></head>"),i.write('<body style="background-color:#FFF;font-size:12px;margin:2px;">'),a.IE||i.write("<br />"),i.write("</body></html>"),i.close(),a.IE&&(i.body.contentEditable="true"),h[0].contentWindow.focus()})}),KindEditor.plugin("fixtoolbar",function(a){function b(){var b=a(".ke-toolbar"),c=b.pos().y;a(window).bind("scroll",function(){"fixed"==b.css("position")?document.body.scrollTop-c<0&&(b.css("position","static"),b.css("top","auto")):b.pos().y-document.body.scrollTop<0&&(b.css("position","fixed"),b.css("top",0))})}var c=this;c.fixToolBar&&(c.isCreated?b():c.afterCreate(b))}); \ No newline at end of file diff --git a/static/plugins/kindeditor/lang/en.js b/static/plugins/kindeditor/lang/en.js new file mode 100755 index 0000000..909bf49 --- /dev/null +++ b/static/plugins/kindeditor/lang/en.js @@ -0,0 +1,241 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'Source', + preview : 'Preview', + undo : 'Undo(Ctrl+Z)', + redo : 'Redo(Ctrl+Y)', + cut : 'Cut(Ctrl+X)', + copy : 'Copy(Ctrl+C)', + paste : 'Paste(Ctrl+V)', + plainpaste : 'Paste as plain text', + wordpaste : 'Paste from Word', + selectall : 'Select all', + justifyleft : 'Align left', + justifycenter : 'Align center', + justifyright : 'Align right', + justifyfull : 'Align full', + insertorderedlist : 'Ordered list', + insertunorderedlist : 'Unordered list', + indent : 'Increase indent', + outdent : 'Decrease indent', + subscript : 'Subscript', + superscript : 'Superscript', + formatblock : 'Paragraph format', + fontname : 'Font family', + fontsize : 'Font size', + forecolor : 'Text color', + hilitecolor : 'Highlight color', + bold : 'Bold(Ctrl+B)', + italic : 'Italic(Ctrl+I)', + underline : 'Underline(Ctrl+U)', + strikethrough : 'Strikethrough', + removeformat : 'Remove format', + image : 'Image', + multiimage : 'Multi image', + flash : 'Flash', + media : 'Embeded media', + table : 'Table', + tablecell : 'Cell', + hr : 'Insert horizontal line', + emoticons : 'Insert emoticon', + link : 'Link', + unlink : 'Unlink', + fullscreen : 'Toggle fullscreen mode', + about : 'About', + print : 'Print', + filemanager : 'File Manager', + code : 'Insert code', + map : 'Google Maps', + baidumap : 'Baidu Maps', + lineheight : 'Line height', + clearhtml : 'Clear HTML code', + pagebreak : 'Insert Page Break', + quickformat : 'Quick Format', + insertfile : 'Insert file', + template : 'Insert Template', + anchor : 'Anchor', + yes : 'OK', + no : 'Cancel', + close : 'Close', + editImage : 'Image properties', + deleteImage : 'Delete image', + editFlash : 'Flash properties', + deleteFlash : 'Delete flash', + editMedia : 'Media properties', + deleteMedia : 'Delete media', + editLink : 'Link properties', + deleteLink : 'Unlink', + editAnchor : 'Anchor properties', + deleteAnchor : 'Delete Anchor', + tableprop : 'Table properties', + tablecellprop : 'Cell properties', + tableinsert : 'Insert table', + tabledelete : 'Delete table', + tablecolinsertleft : 'Insert column left', + tablecolinsertright : 'Insert column right', + tablerowinsertabove : 'Insert row above', + tablerowinsertbelow : 'Insert row below', + tablerowmerge : 'Merge down', + tablecolmerge : 'Merge right', + tablerowsplit : 'Split row', + tablecolsplit : 'Split column', + tablecoldelete : 'Delete column', + tablerowdelete : 'Delete row', + noColor : 'Default', + pleaseSelectFile : 'Please select file.', + invalidImg : "Please type valid URL.\nAllowed file extension: jpg,gif,bmp,png", + invalidMedia : "Please type valid URL.\nAllowed file extension: swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb", + invalidWidth : "The width must be number.", + invalidHeight : "The height must be number.", + invalidBorder : "The border must be number.", + invalidUrl : "Please type valid URL.", + invalidRows : 'Invalid rows.', + invalidCols : 'Invalid columns.', + invalidPadding : 'The padding must be number.', + invalidSpacing : 'The spacing must be number.', + invalidJson : 'Invalid JSON string.', + uploadSuccess : 'Upload success.', + cutError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+X) instead.', + copyError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+C) instead.', + pasteError : 'Currently not supported by your browser, use keyboard shortcut(Ctrl+V) instead.', + ajaxLoading : 'Loading ...', + uploadLoading : 'Uploading ...', + uploadError : 'Upload Error', + 'plainpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'wordpaste.comment' : 'Use keyboard shortcut(Ctrl+V) to paste the text into the window.', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : 'Target', + 'link.newWindow' : 'New window', + 'link.selfWindow' : 'Same window', + 'flash.url' : 'URL', + 'flash.width' : 'Width', + 'flash.height' : 'Height', + 'flash.upload' : 'Upload', + 'flash.viewServer' : 'Browse', + 'media.url' : 'URL', + 'media.width' : 'Width', + 'media.height' : 'Height', + 'media.autostart' : 'Auto start', + 'media.upload' : 'Upload', + 'media.viewServer' : 'Browse', + 'image.remoteImage' : 'Insert URL', + 'image.localImage' : 'Upload', + 'image.remoteUrl' : 'URL', + 'image.localUrl' : 'File', + 'image.size' : 'Size', + 'image.width' : 'Width', + 'image.height' : 'Height', + 'image.resetSize' : 'Reset dimensions', + 'image.align' : 'Align', + 'image.defaultAlign' : 'Default', + 'image.leftAlign' : 'Left', + 'image.rightAlign' : 'Right', + 'image.imgTitle' : 'Title', + 'image.upload' : 'Browse', + 'image.viewServer' : 'Browse', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : 'Blank', + 'filemanager.moveup' : 'Parent folder', + 'filemanager.viewType' : 'Display: ', + 'filemanager.viewImage' : 'Thumbnails', + 'filemanager.listImage' : 'List', + 'filemanager.orderType' : 'Sorting: ', + 'filemanager.fileName' : 'By name', + 'filemanager.fileSize' : 'By size', + 'filemanager.fileType' : 'By type', + 'insertfile.url' : 'URL', + 'insertfile.title' : 'Title', + 'insertfile.upload' : 'Upload', + 'insertfile.viewServer' : 'Browse', + 'table.cells' : 'Cells', + 'table.rows' : 'Rows', + 'table.cols' : 'Columns', + 'table.size' : 'Dimensions', + 'table.width' : 'Width', + 'table.height' : 'Height', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : 'Space', + 'table.padding' : 'Padding', + 'table.spacing' : 'Spacing', + 'table.align' : 'Align', + 'table.textAlign' : 'Horizontal', + 'table.verticalAlign' : 'Vertical', + 'table.alignDefault' : 'Default', + 'table.alignLeft' : 'Left', + 'table.alignCenter' : 'Center', + 'table.alignRight' : 'Right', + 'table.alignTop' : 'Top', + 'table.alignMiddle' : 'Middle', + 'table.alignBottom' : 'Bottom', + 'table.alignBaseline' : 'Baseline', + 'table.border' : 'Border', + 'table.borderWidth' : 'Width', + 'table.borderColor' : 'Color', + 'table.backgroundColor' : 'Background', + 'map.address' : 'Address: ', + 'map.search' : 'Search', + 'baidumap.address' : 'Address: ', + 'baidumap.search' : 'Search', + 'baidumap.insertDynamicMap' : 'Dynamic Map', + 'anchor.name' : 'Anchor name', + 'formatblock.formatBlock' : { + h1 : 'Heading 1', + h2 : 'Heading 2', + h3 : 'Heading 3', + h4 : 'Heading 4', + p : 'Normal' + }, + 'fontname.fontName' : { + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Comic Sans MS' : 'Comic Sans MS', + 'Courier New' : 'Courier New', + 'Garamond' : 'Garamond', + 'Georgia' : 'Georgia', + 'Tahoma' : 'Tahoma', + 'Times New Roman' : 'Times New Roman', + 'Trebuchet MS' : 'Trebuchet MS', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : 'Line height 1'}, + {'1.5' : 'Line height 1.5'}, + {'2' : 'Line height 2'}, + {'2.5' : 'Line height 2.5'}, + {'3' : 'Line height 3'} + ], + 'template.selectTemplate' : 'Template', + 'template.replaceContent' : 'Replace current content', + 'template.fileList' : { + '1.html' : 'Image and Text', + '2.html' : 'Table', + '3.html' : 'List' + } +}, 'en'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'en'; diff --git a/static/plugins/kindeditor/lang/zh-CN.js b/static/plugins/kindeditor/lang/zh-CN.js new file mode 100755 index 0000000..d9aa96e --- /dev/null +++ b/static/plugins/kindeditor/lang/zh-CN.js @@ -0,0 +1,238 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : 'HTML代码', + preview : '预览', + undo : '后退(Ctrl+Z)', + redo : '前进(Ctrl+Y)', + cut : '剪切(Ctrl+X)', + copy : '复制(Ctrl+C)', + paste : '粘贴(Ctrl+V)', + plainpaste : '粘贴为无格式文本', + wordpaste : '从Word粘贴', + selectall : '全选(Ctrl+A)', + justifyleft : '左对齐', + justifycenter : '居中', + justifyright : '右对齐', + justifyfull : '两端对齐', + insertorderedlist : '编号', + insertunorderedlist : '项目符号', + indent : '增加缩进', + outdent : '减少缩进', + subscript : '下标', + superscript : '上标', + formatblock : '段落', + fontname : '字体', + fontsize : '文字大小', + forecolor : '文字颜色', + hilitecolor : '文字背景', + bold : '粗体(Ctrl+B)', + italic : '斜体(Ctrl+I)', + underline : '下划线(Ctrl+U)', + strikethrough : '删除线', + removeformat : '删除格式', + image : '图片', + multiimage : '批量图片上传', + flash : 'Flash', + media : '视音频', + table : '表格', + tablecell : '单元格', + hr : '插入横线', + emoticons : '插入表情', + link : '超级链接', + unlink : '取消超级链接', + fullscreen : '全屏显示', + about : '关于', + print : '打印(Ctrl+P)', + filemanager : '文件空间', + code : '插入程序代码', + map : 'Google地图', + baidumap : '百度地图', + lineheight : '行距', + clearhtml : '清理HTML代码', + pagebreak : '插入分页符', + quickformat : '一键排版', + insertfile : '插入文件', + template : '插入模板', + anchor : '锚点', + yes : '确定', + no : '取消', + close : '关闭', + editImage : '图片属性', + deleteImage : '删除图片', + editFlash : 'Flash属性', + deleteFlash : '删除Flash', + editMedia : '视音频属性', + deleteMedia : '删除视音频', + editLink : '超级链接属性', + deleteLink : '取消超级链接', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格属性', + tablecellprop : '单元格属性', + tableinsert : '插入表格', + tabledelete : '删除表格', + tablecolinsertleft : '左侧插入列', + tablecolinsertright : '右侧插入列', + tablerowinsertabove : '上方插入行', + tablerowinsertbelow : '下方插入行', + tablerowmerge : '向下合并单元格', + tablecolmerge : '向右合并单元格', + tablerowsplit : '拆分行', + tablecolsplit : '拆分列', + tablecoldelete : '删除列', + tablerowdelete : '删除行', + noColor : '无颜色', + pleaseSelectFile : '请选择文件。', + invalidImg : "请输入有效的URL地址。\n只允许jpg,gif,bmp,png格式。", + invalidMedia : "请输入有效的URL地址。\n只允许swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "宽度必须为数字。", + invalidHeight : "高度必须为数字。", + invalidBorder : "边框必须为数字。", + invalidUrl : "请输入有效的URL地址。", + invalidRows : '行数为必选项,只允许输入大于0的数字。', + invalidCols : '列数为必选项,只允许输入大于0的数字。', + invalidPadding : '边距必须为数字。', + invalidSpacing : '间距必须为数字。', + invalidJson : '服务器发生故障。', + uploadSuccess : '上传成功。', + cutError : '您的浏览器安全设置不允许使用剪切操作,请使用快捷键(Ctrl+X)来完成。', + copyError : '您的浏览器安全设置不允许使用复制操作,请使用快捷键(Ctrl+C)来完成。', + pasteError : '您的浏览器安全设置不允许使用粘贴操作,请使用快捷键(Ctrl+V)来完成。', + ajaxLoading : '加载中,请稍候 ...', + uploadLoading : '上传中,请稍候 ...', + uploadError : '上传错误', + 'plainpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'wordpaste.comment' : '请使用快捷键(Ctrl+V)把内容粘贴到下面的方框里。', + 'code.pleaseInput' : '请输入程序代码。', + 'link.url' : 'URL', + 'link.linkType' : '打开类型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '当前窗口', + 'flash.url' : 'URL', + 'flash.width' : '宽度', + 'flash.height' : '高度', + 'flash.upload' : '上传', + 'flash.viewServer' : '文件空间', + 'media.url' : 'URL', + 'media.width' : '宽度', + 'media.height' : '高度', + 'media.autostart' : '自动播放', + 'media.upload' : '上传', + 'media.viewServer' : '文件空间', + 'image.remoteImage' : '网络图片', + 'image.localImage' : '本地上传', + 'image.remoteUrl' : '图片地址', + 'image.localUrl' : '上传文件', + 'image.size' : '图片大小', + 'image.width' : '宽', + 'image.height' : '高', + 'image.resetSize' : '重置大小', + 'image.align' : '对齐方式', + 'image.defaultAlign' : '默认方式', + 'image.leftAlign' : '左对齐', + 'image.rightAlign' : '右对齐', + 'image.imgTitle' : '图片说明', + 'image.upload' : '浏览...', + 'image.viewServer' : '图片空间', + 'multiimage.uploadDesc' : '允许用户同时上传<%=uploadLimit%>张图片,单张图片容量不超过<%=sizeLimit%>', + 'multiimage.startUpload' : '开始上传', + 'multiimage.clearAll' : '全部清空', + 'multiimage.insertAll' : '全部插入', + 'multiimage.queueLimitExceeded' : '文件数量超过限制。', + 'multiimage.fileExceedsSizeLimit' : '文件大小超过限制。', + 'multiimage.zeroByteFile' : '无法上传空文件。', + 'multiimage.invalidFiletype' : '文件类型不正确。', + 'multiimage.unknownError' : '发生异常,无法上传。', + 'multiimage.pending' : '等待上传', + 'multiimage.uploadError' : '上传失败', + 'filemanager.emptyFolder' : '空文件夹', + 'filemanager.moveup' : '移到上一级文件夹', + 'filemanager.viewType' : '显示方式:', + 'filemanager.viewImage' : '缩略图', + 'filemanager.listImage' : '详细信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名称', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '类型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件说明', + 'insertfile.upload' : '上传', + 'insertfile.viewServer' : '文件空间', + 'table.cells' : '单元格数', + 'table.rows' : '行数', + 'table.cols' : '列数', + 'table.size' : '大小', + 'table.width' : '宽度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '边距间距', + 'table.padding' : '边距', + 'table.spacing' : '间距', + 'table.align' : '对齐方式', + 'table.textAlign' : '水平对齐', + 'table.verticalAlign' : '垂直对齐', + 'table.alignDefault' : '默认', + 'table.alignLeft' : '左对齐', + 'table.alignCenter' : '居中', + 'table.alignRight' : '右对齐', + 'table.alignTop' : '顶部', + 'table.alignMiddle' : '中部', + 'table.alignBottom' : '底部', + 'table.alignBaseline' : '基线', + 'table.border' : '边框', + 'table.borderWidth' : '边框', + 'table.borderColor' : '颜色', + 'table.backgroundColor' : '背景颜色', + 'map.address' : '地址: ', + 'map.search' : '搜索', + 'baidumap.address' : '地址: ', + 'baidumap.search' : '搜索', + 'baidumap.insertDynamicMap' : '插入动态地图', + 'anchor.name' : '锚点名称', + 'formatblock.formatBlock' : { + h1 : '标题 1', + h2 : '标题 2', + h3 : '标题 3', + h4 : '标题 4', + p : '正 文' + }, + 'fontname.fontName' : { + 'SimSun' : '宋体', + 'NSimSun' : '新宋体', + 'FangSong_GB2312' : '仿宋_GB2312', + 'KaiTi_GB2312' : '楷体_GB2312', + 'SimHei' : '黑体', + 'Microsoft YaHei' : '微软雅黑', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可选模板', + 'template.replaceContent' : '替换当前内容', + 'template.fileList' : { + '1.html' : '图片和文字', + '2.html' : '表格', + '3.html' : '项目编号' + } +}, 'zh-CN'); + +KindEditor.options.langType = 'zh-CN'; \ No newline at end of file diff --git a/static/plugins/kindeditor/lang/zh-TW.js b/static/plugins/kindeditor/lang/zh-TW.js new file mode 100755 index 0000000..4946898 --- /dev/null +++ b/static/plugins/kindeditor/lang/zh-TW.js @@ -0,0 +1,243 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.lang({ + source : '原始碼', + preview : '預覽', + undo : '復原(Ctrl+Z)', + redo : '重複(Ctrl+Y)', + cut : '剪下(Ctrl+X)', + copy : '複製(Ctrl+C)', + paste : '貼上(Ctrl+V)', + plainpaste : '貼為純文字格式', + wordpaste : '自Word貼上', + selectall : '全選(Ctrl+A)', + justifyleft : '靠左對齊', + justifycenter : '置中', + justifyright : '靠右對齊', + justifyfull : '左右對齊', + insertorderedlist : '編號清單', + insertunorderedlist : '項目清單', + indent : '增加縮排', + outdent : '減少縮排', + subscript : '下標', + superscript : '上標', + formatblock : '標題', + fontname : '字體', + fontsize : '文字大小', + forecolor : '文字顏色', + hilitecolor : '背景顏色', + bold : '粗體(Ctrl+B)', + italic : '斜體(Ctrl+I)', + underline : '底線(Ctrl+U)', + strikethrough : '刪除線', + removeformat : '清除格式', + image : '影像', + multiimage : '批量影像上傳', + flash : 'Flash', + media : '多媒體', + table : '表格', + tablecell : '儲存格', + hr : '插入水平線', + emoticons : '插入表情', + link : '超連結', + unlink : '移除超連結', + fullscreen : '最大化', + about : '關於', + print : '列印(Ctrl+P)', + filemanager : '瀏覽伺服器', + code : '插入程式代碼', + map : 'Google地圖', + baidumap : 'Baidu地圖', + lineheight : '行距', + clearhtml : '清理HTML代碼', + pagebreak : '插入分頁符號', + quickformat : '快速排版', + insertfile : '插入文件', + template : '插入樣板', + anchor : '錨點', + yes : '確定', + no : '取消', + close : '關閉', + editImage : '影像屬性', + deleteImage : '刪除影像', + editFlash : 'Flash屬性', + deleteFlash : '删除Flash', + editMedia : '多媒體屬性', + deleteMedia : '删除多媒體', + editLink : '超連結屬性', + deleteLink : '移除超連結', + editAnchor : '锚点属性', + deleteAnchor : '删除锚点', + tableprop : '表格屬性', + tablecellprop : '儲存格屬性', + tableinsert : '插入表格', + tabledelete : '刪除表格', + tablecolinsertleft : '向左插入列', + tablecolinsertright : '向右插入列', + tablerowinsertabove : '向上插入欄', + tablerowinsertbelow : '下方插入欄', + tablerowmerge : '向下合併單元格', + tablecolmerge : '向右合併單元格', + tablerowsplit : '分割欄', + tablecolsplit : '分割列', + tablecoldelete : '删除列', + tablerowdelete : '删除欄', + noColor : '自動', + pleaseSelectFile : '請選擇文件。', + invalidImg : "請輸入有效的URL。\n只允許jpg,gif,bmp,png格式。", + invalidMedia : "請輸入有效的URL。\n只允許swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb格式。", + invalidWidth : "寬度必須是數字。", + invalidHeight : "高度必須是數字。", + invalidBorder : "邊框必須是數字。", + invalidUrl : "請輸入有效的URL。", + invalidRows : '欄數是必須輸入項目,只允許輸入大於0的數字。', + invalidCols : '列數是必須輸入項目,只允許輸入大於0的數字。', + invalidPadding : '內距必須是數字。', + invalidSpacing : '間距必須是數字。', + invalidJson : '伺服器發生故障。', + uploadSuccess : '上傳成功。', + cutError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+X)完成。', + copyError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+C)完成。', + pasteError : '您的瀏覽器安全設置不允許使用剪下操作,請使用快捷鍵(Ctrl+V)完成。', + ajaxLoading : '加載中,請稍候 ...', + uploadLoading : '上傳中,請稍候 ...', + uploadError : '上傳錯誤', + 'plainpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'wordpaste.comment' : '請使用快捷鍵(Ctrl+V)把內容貼到下方區域裡。', + 'code.pleaseInput' : 'Please input code.', + 'link.url' : 'URL', + 'link.linkType' : '打開類型', + 'link.newWindow' : '新窗口', + 'link.selfWindow' : '本頁窗口', + 'flash.url' : 'URL', + 'flash.width' : '寬度', + 'flash.height' : '高度', + 'flash.upload' : '上傳', + 'flash.viewServer' : '瀏覽', + 'media.url' : 'URL', + 'media.width' : '寬度', + 'media.height' : '高度', + 'media.autostart' : '自動播放', + 'media.upload' : '上傳', + 'media.viewServer' : '瀏覽', + 'image.remoteImage' : '網絡影像', + 'image.localImage' : '上傳影像', + 'image.remoteUrl' : '影像URL', + 'image.localUrl' : '影像URL', + 'image.size' : '影像大小', + 'image.width' : '寬度', + 'image.height' : '高度', + 'image.resetSize' : '原始大小', + 'image.align' : '對齊方式', + 'image.defaultAlign' : '未設定', + 'image.leftAlign' : '向左對齊', + 'image.rightAlign' : '向右對齊', + 'image.imgTitle' : '影像說明', + 'image.upload' : '瀏覽...', + 'image.viewServer' : '瀏覽...', + 'multiimage.uploadDesc' : 'Allows users to upload <%=uploadLimit%> images, single image size not exceeding <%=sizeLimit%>', + 'multiimage.startUpload' : 'Start upload', + 'multiimage.clearAll' : 'Clear all', + 'multiimage.insertAll' : 'Insert all', + 'multiimage.queueLimitExceeded' : 'Queue limit exceeded.', + 'multiimage.fileExceedsSizeLimit' : 'File exceeds size limit.', + 'multiimage.zeroByteFile' : 'Zero byte file.', + 'multiimage.invalidFiletype' : 'Invalid file type.', + 'multiimage.unknownError' : 'Unknown upload error.', + 'multiimage.pending' : 'Pending ...', + 'multiimage.uploadError' : 'Upload error', + 'filemanager.emptyFolder' : '空文件夾', + 'filemanager.moveup' : '至上一級文件夾', + 'filemanager.viewType' : '顯示方式:', + 'filemanager.viewImage' : '縮略圖', + 'filemanager.listImage' : '詳細信息', + 'filemanager.orderType' : '排序方式:', + 'filemanager.fileName' : '名稱', + 'filemanager.fileSize' : '大小', + 'filemanager.fileType' : '類型', + 'insertfile.url' : 'URL', + 'insertfile.title' : '文件說明', + 'insertfile.upload' : '上傳', + 'insertfile.viewServer' : '瀏覽', + 'table.cells' : '儲存格數', + 'table.rows' : '欄數', + 'table.cols' : '列數', + 'table.size' : '表格大小', + 'table.width' : '寬度', + 'table.height' : '高度', + 'table.percent' : '%', + 'table.px' : 'px', + 'table.space' : '內距間距', + 'table.padding' : '內距', + 'table.spacing' : '間距', + 'table.align' : '對齊方式', + 'table.textAlign' : '水平對齊', + 'table.verticalAlign' : '垂直對齊', + 'table.alignDefault' : '未設定', + 'table.alignLeft' : '向左對齊', + 'table.alignCenter' : '置中', + 'table.alignRight' : '向右對齊', + 'table.alignTop' : '靠上', + 'table.alignMiddle' : '置中', + 'table.alignBottom' : '靠下', + 'table.alignBaseline' : '基線', + 'table.border' : '表格邊框', + 'table.borderWidth' : '邊框', + 'table.borderColor' : '顏色', + 'table.backgroundColor' : '背景顏色', + 'map.address' : '住所: ', + 'map.search' : '尋找', + 'baidumap.address' : '住所: ', + 'baidumap.search' : '尋找', + 'baidumap.insertDynamicMap' : '插入動態地圖', + 'anchor.name' : '錨點名稱', + 'formatblock.formatBlock' : { + h1 : '標題 1', + h2 : '標題 2', + h3 : '標題 3', + h4 : '標題 4', + p : '一般' + }, + 'fontname.fontName' : { + 'MingLiU' : '細明體', + 'PMingLiU' : '新細明體', + 'DFKai-SB' : '標楷體', + 'SimSun' : '宋體', + 'NSimSun' : '新宋體', + 'FangSong' : '仿宋體', + 'Arial' : 'Arial', + 'Arial Black' : 'Arial Black', + 'Times New Roman' : 'Times New Roman', + 'Courier New' : 'Courier New', + 'Tahoma' : 'Tahoma', + 'Verdana' : 'Verdana' + }, + 'lineheight.lineHeight' : [ + {'1' : '单倍行距'}, + {'1.5' : '1.5倍行距'}, + {'2' : '2倍行距'}, + {'2.5' : '2.5倍行距'}, + {'3' : '3倍行距'} + ], + 'template.selectTemplate' : '可選樣板', + 'template.replaceContent' : '取代當前內容', + 'template.fileList' : { + '1.html' : '影像和文字', + '2.html' : '表格', + '3.html' : '项目清單' + } +}, 'zh-TW'); + +KindEditor.each(KindEditor.options.items, function(i, name) { + if (name == 'baidumap') { + KindEditor.options.items[i] = 'map'; + } +}); +KindEditor.options.langType = 'zh-TW'; \ No newline at end of file diff --git a/static/plugins/kindeditor/license.txt b/static/plugins/kindeditor/license.txt new file mode 100755 index 0000000..4362b49 --- /dev/null +++ b/static/plugins/kindeditor/license.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/static/plugins/kindeditor/php/JSON.php b/static/plugins/kindeditor/php/JSON.php new file mode 100755 index 0000000..0cddbdd --- /dev/null +++ b/static/plugins/kindeditor/php/JSON.php @@ -0,0 +1,806 @@ +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ + +/** + * Converts to and from JSON format. + * + * JSON (JavaScript Object Notation) is a lightweight data-interchange + * format. It is easy for humans to read and write. It is easy for machines + * to parse and generate. It is based on a subset of the JavaScript + * Programming Language, Standard ECMA-262 3rd Edition - December 1999. + * This feature can also be found in Python. JSON is a text format that is + * completely language independent but uses conventions that are familiar + * to programmers of the C-family of languages, including C, C++, C#, Java, + * JavaScript, Perl, TCL, and many others. These properties make JSON an + * ideal data-interchange language. + * + * This package provides a simple encoder and decoder for JSON notation. It + * is intended for use with client-side Javascript applications that make + * use of HTTPRequest to perform server communication functions - data can + * be encoded into JSON notation for use in a client-side javascript, or + * decoded from incoming Javascript requests. JSON format is native to + * Javascript, and can be directly eval()'ed with no further parsing + * overhead + * + * All strings should be in ASCII or UTF-8 format! + * + * LICENSE: Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: Redistributions of source code must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * @category + * @package Services_JSON + * @author Michal Migurski <mike-json@teczno.com> + * @author Matt Knapp <mdknapp[at]gmail[dot]com> + * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com> + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * <code> + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * </code> + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/static/plugins/kindeditor/php/file_manager_json.php b/static/plugins/kindeditor/php/file_manager_json.php new file mode 100755 index 0000000..a8947e7 --- /dev/null +++ b/static/plugins/kindeditor/php/file_manager_json.php @@ -0,0 +1,137 @@ +<?php +/** + * KindEditor PHP + * + * 本PHP程序是演示程序,建议不要直接在实际项目中使用。 + * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。 + * + */ + +require_once 'JSON.php'; + +$php_path = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/'; +$php_url = dirname(dirname(dirname(dirname(dirname($_SERVER['PHP_SELF']))))) . '/'; + +//根目录路径,可以指定绝对路径,比如 /var/www/attached/ +$root_path = $php_path . 'upload/'; +//根目录URL,可以指定绝对路径,比如 http://www.yoursite.com/attached/ +$root_url = $php_url . 'upload/'; +//图片扩展名 +$ext_arr = array('gif', 'jpg', 'jpeg', 'png', 'bmp'); + +//目录名 +$dir_name = empty($_GET['dir']) ? '' : trim($_GET['dir']); +if (!in_array($dir_name, array('image', 'flash', 'media', 'file'))) { + echo "Invalid Directory name."; + exit; +} +if ($dir_name !== '') { + $root_path .= $dir_name . "/"; + $root_url .= $dir_name . "/"; + if (!file_exists($root_path)) { + mkdir($root_path); + } +} + +//根据path参数,设置各路径和URL +if (empty($_GET['path'])) { + $current_path = realpath($root_path) . '/'; + $current_url = $root_url; + $current_dir_path = ''; + $moveup_dir_path = ''; +} else { + $current_path = realpath($root_path) . '/' . $_GET['path']; + $current_url = $root_url . $_GET['path']; + $current_dir_path = $_GET['path']; + $moveup_dir_path = preg_replace('/(.*?)[^\/]+\/$/', '$1', $current_dir_path); +} +//echo realpath($root_path); +//排序形式,name or size or type +$order = empty($_GET['order']) ? 'name' : strtolower($_GET['order']); + +//不允许使用..移动到上一级目录 +if (preg_match('/\.\./', $current_path)) { + echo 'Access is not allowed.'; + exit; +} +//最后一个字符不是/ +if (!preg_match('/\/$/', $current_path)) { + echo 'Parameter is not valid.'; + exit; +} +//目录不存在或不是目录 +if (!file_exists($current_path) || !is_dir($current_path)) { + echo 'Directory does not exist.'; + exit; +} + +//遍历目录取得文件信息 +$file_list = array(); +if ($handle = opendir($current_path)) { + $i = 0; + while (false !== ($filename = readdir($handle))) { + if ($filename{0} == '.') continue; + $file = $current_path . $filename; + if (is_dir($file)) { + $file_list[$i]['is_dir'] = true; //是否文件夹 + $file_list[$i]['has_file'] = (count(scandir($file)) > 2); //文件夹是否包含文件 + $file_list[$i]['filesize'] = 0; //文件大小 + $file_list[$i]['is_photo'] = false; //是否图片 + $file_list[$i]['filetype'] = ''; //文件类别,用扩展名判断 + } else { + $file_list[$i]['is_dir'] = false; + $file_list[$i]['has_file'] = false; + $file_list[$i]['filesize'] = filesize($file); + $file_list[$i]['dir_path'] = ''; + $file_ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + $file_list[$i]['is_photo'] = in_array($file_ext, $ext_arr); + $file_list[$i]['filetype'] = $file_ext; + } + $file_list[$i]['filename'] = $filename; //文件名,包含扩展名 + $file_list[$i]['datetime'] = date('Y-m-d H:i:s', filemtime($file)); //文件最后修改时间 + $i++; + } + closedir($handle); +} + +//排序 +function cmp_func($a, $b) { + global $order; + if ($a['is_dir'] && !$b['is_dir']) { + return -1; + } else if (!$a['is_dir'] && $b['is_dir']) { + return 1; + } else { + if ($order == 'size') { + if ($a['filesize'] > $b['filesize']) { + return 1; + } else if ($a['filesize'] < $b['filesize']) { + return -1; + } else { + return 0; + } + } else if ($order == 'type') { + return strcmp($a['filetype'], $b['filetype']); + } else { + return strcmp($a['filename'], $b['filename']); + } + } +} +usort($file_list, 'cmp_func'); + +$result = array(); +//相对于根目录的上一级目录 +$result['moveup_dir_path'] = $moveup_dir_path; +//相对于根目录的当前目录 +$result['current_dir_path'] = $current_dir_path; +//当前目录的URL +$result['current_url'] = $current_url; +//文件数 +$result['total_count'] = count($file_list); +//文件列表数组 +$result['file_list'] = $file_list; + +//输出JSON字符串 +header('Content-type: application/json; charset=UTF-8'); +$json = new Services_JSON(); +echo $json->encode($result); diff --git a/static/plugins/kindeditor/php/upload_json.php b/static/plugins/kindeditor/php/upload_json.php new file mode 100755 index 0000000..02b661f --- /dev/null +++ b/static/plugins/kindeditor/php/upload_json.php @@ -0,0 +1,141 @@ +<?php +/** + * KindEditor PHP + * + * 本PHP程序是演示程序,建议不要直接在实际项目中使用。 + * 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。 + * + */ + +require_once 'JSON.php'; + + + +$php_path = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/'; +$php_url = '/'; + +//文件保存目录路径 +$save_path = $php_path . 'upload/'; +//文件保存目录URL +$save_url = $php_url . 'upload/'; +//定义允许上传的文件扩展名 +$ext_arr = array( + 'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp'), + 'flash' => array('swf', 'flv'), + 'media' => array('swf', 'flv', 'mp3', 'wav', 'wma', 'wmv', 'mid', 'avi', 'mpg', 'asf', 'rm', 'rmvb'), + 'file' => array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'txt', 'zip', 'rar', 'gz', 'bz2'), +); +//最大文件大小 +$max_size = 1000000; + +$save_path = realpath($save_path) . '/'; + +//PHP上传失败 +if (!empty($_FILES['imgFile']['error'])) { + switch($_FILES['imgFile']['error']){ + case '1': + $error = '超过php.ini允许的大小。'; + break; + case '2': + $error = '超过表单允许的大小。'; + break; + case '3': + $error = '图片只有部分被上传。'; + break; + case '4': + $error = '请选择图片。'; + break; + case '6': + $error = '找不到临时目录。'; + break; + case '7': + $error = '写文件到硬盘出错。'; + break; + case '8': + $error = 'File upload stopped by extension。'; + break; + case '999': + default: + $error = '未知错误。'; + } + alert($error); +} + +//有上传文件时 +if (empty($_FILES) === false) { + //原文件名 + $file_name = $_FILES['imgFile']['name']; + //服务器上临时文件名 + $tmp_name = $_FILES['imgFile']['tmp_name']; + //文件大小 + $file_size = $_FILES['imgFile']['size']; + //检查文件名 + if (!$file_name) { + alert("请选择文件。"); + } + //检查目录 + if (@is_dir($save_path) === false) { + alert("上传目录不存在。"); + } + //检查目录写权限 + if (@is_writable($save_path) === false) { + alert("上传目录没有写权限。"); + } + //检查是否已上传 + if (@is_uploaded_file($tmp_name) === false) { + alert("上传失败。"); + } + //检查文件大小 + if ($file_size > $max_size) { + alert("上传文件大小超过限制。"); + } + //检查目录名 + $dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']); + if (empty($ext_arr[$dir_name])) { + alert("目录名不正确。"); + } + //获得文件扩展名 + $temp_arr = explode(".", $file_name); + $file_ext = array_pop($temp_arr); + $file_ext = trim($file_ext); + $file_ext = strtolower($file_ext); + //检查扩展名 + if (in_array($file_ext, $ext_arr[$dir_name]) === false) { + alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。"); + } + //创建文件夹 + if ($dir_name !== '') { + $save_path .= $dir_name . "/"; + $save_url .= $dir_name . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + } + $ymd = date("Ymd"); + $save_path .= $ymd . "/"; + $save_url .= $ymd . "/"; + if (!file_exists($save_path)) { + mkdir($save_path); + } + //新文件名 + $new_file_name = date("YmdHis") . '_' . rand(10000, 99999) . '.' . $file_ext; + //移动文件 + $file_path = $save_path . $new_file_name; + if (move_uploaded_file($tmp_name, $file_path) === false) { + alert("上传文件失败。"); + } + @chmod($file_path, 0644); + $file_url = $save_url . $new_file_name; + + header('Content-type: text/html; charset=UTF-8'); + $json = new Services_JSON(); + echo $json->encode(array('error' => 0, 'url' => $file_url)); + exit; +} + +function alert($msg) { + header('Content-type: text/html; charset=UTF-8'); + $json = new Services_JSON(); + echo $json->encode(array('error' => 1, 'message' => $msg)); + exit; +} diff --git a/static/plugins/kindeditor/plugins/anchor/anchor.js b/static/plugins/kindeditor/plugins/anchor/anchor.js new file mode 100755 index 0000000..55ab894 --- /dev/null +++ b/static/plugins/kindeditor/plugins/anchor/anchor.js @@ -0,0 +1,46 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('anchor', function(K) { + var self = this, name = 'anchor', lang = self.lang(name + '.'); + self.plugin.anchor = { + edit : function() { + var html = ['<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keName">' + lang.name + '</label>', + '<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />', + '</div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 300, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus(); + } + } + }); + var div = dialog.div, + nameBox = K('input[name="name"]', div); + var img = self.plugin.getSelectedAnchor(); + if (img) { + nameBox.val(unescape(img.attr('data-ke-name'))); + } + nameBox[0].focus(); + nameBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedAnchor().remove(); + } + }; + self.clickToolbar(name, self.plugin.anchor.edit); +}); diff --git a/static/plugins/kindeditor/plugins/autoheight/autoheight.js b/static/plugins/kindeditor/plugins/autoheight/autoheight.js new file mode 100755 index 0000000..546578b --- /dev/null +++ b/static/plugins/kindeditor/plugins/autoheight/autoheight.js @@ -0,0 +1,54 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('autoheight', function(K) { + var self = this; + + if (!self.autoHeightMode) { + return; + } + + var minHeight; + + function hideScroll() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe[0].scroll = 'no'; + body.style.overflowY = 'hidden'; + } + + function resetHeight() { + var edit = self.edit; + var body = edit.doc.body; + edit.iframe.height(minHeight); + self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight)); + } + + function init() { + minHeight = K.removeUnit(self.height); + + self.edit.afterChange(resetHeight); + hideScroll(); + resetHeight(); + } + + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } +}); + +/* +* 如何实现真正的自动高度? +* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。 +* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。 +* 由此就实现了真正的自动高度 +* 测试:chrome、firefox、IE9、IE8 +* */ diff --git a/static/plugins/kindeditor/plugins/baidumap/baidumap.js b/static/plugins/kindeditor/plugins/baidumap/baidumap.js new file mode 100755 index 0000000..12751c4 --- /dev/null +++ b/static/plugins/kindeditor/plugins/baidumap/baidumap.js @@ -0,0 +1,93 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5 + +KindEditor.plugin('baidumap', function(K) { + var self = this, name = 'baidumap', lang = self.lang(name + '.'); + var mapWidth = K.undef(self.mapWidth, 558); + var mapHeight = K.undef(self.mapHeight, 360); + self.clickToolbar(name, function() { + var html = ['<div style="padding:10px 20px;">', + '<div class="ke-header">', + // left start + '<div class="ke-left">', + lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />', + '</span>', + '</div>', + // right start + '<div class="ke-right">', + '<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + '<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : mapWidth + 42, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var map = win.map; + var centerObj = map.getCenter(); + var center = centerObj.lng + ',' + centerObj.lat; + var zoom = map.getZoom(); + var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage', + '?center=' + encodeURIComponent(center), + '&zoom=' + encodeURIComponent(zoom), + '&width=' + mapWidth, + '&height=' + mapHeight, + '&markers=' + encodeURIComponent(center), + '&markerStyles=' + encodeURIComponent('l,A')].join(''); + if (checkbox[0].checked) { + self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>'); + } else { + self.exec('insertimage', url); + } + self.hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + checkbox = K('[name="insertDynamicMap"]', dialog.div), + win, doc; + var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>'); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + // search map + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); diff --git a/static/plugins/kindeditor/plugins/baidumap/index.html b/static/plugins/kindeditor/plugins/baidumap/index.html new file mode 100755 index 0000000..e106d1a --- /dev/null +++ b/static/plugins/kindeditor/plugins/baidumap/index.html @@ -0,0 +1,83 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta charset="utf-8" /> +<meta name="keywords" content="百度地图,百度地图API,百度地图自定义工具,百度地图所见即所得工具" /> +<meta name="description" content="百度地图API自定义地图,帮助用户在可视化操作下生成百度地图" /> +<title>百度地图API自定义地图</title> +<!--引用百度地图API--> +<style type="text/css"> + html,body{margin:0;padding:0;} + .iw_poi_title {color:#CC5522;font-size:14px;font-weight:bold;overflow:hidden;padding-right:13px;white-space:nowrap} + .iw_poi_content {font:12px arial,sans-serif;overflow:visible;padding-top:4px;white-space:-moz-pre-wrap;word-wrap:break-word} +</style> +<script type="text/javascript" src="http://api.map.baidu.com/api?key=&v=1.1&services=true"></script> +</head> + +<body onload="initMap();"> + <!--百度地图容器--> + <div style="width:697px;height:550px;border:#ccc solid 1px;" id="dituContent"></div> +</body> +<script type="text/javascript"> + function getParam(name) { + return location.href.match(new RegExp('[?&]' + name + '=([^?&]+)', 'i')) ? decodeURIComponent(RegExp.$1) : ''; + } + var centerParam = getParam('center'); + var zoomParam = getParam('zoom'); + var widthParam = getParam('width'); + var heightParam = getParam('height'); + var markersParam = getParam('markers'); + var markerStylesParam = getParam('markerStyles'); + + //创建和初始化地图函数: + function initMap(){ + // [FF]切换模式后报错 + if (!window.BMap) { + return; + } + var dituContent = document.getElementById('dituContent'); + dituContent.style.width = widthParam + 'px'; + dituContent.style.height = heightParam + 'px'; + + createMap();//创建地图 + setMapEvent();//设置地图事件 + addMapControl();//向地图添加控件 + + // 创建标注 + var markersArr = markersParam.split(','); + var point = new BMap.Point(markersArr[0], markersArr[1]); + var marker = new BMap.Marker(point); + map.addOverlay(marker); // 将标注添加到地图中 + } + + //创建地图函数: + function createMap(){ + var map = new BMap.Map("dituContent");//在百度地图容器中创建一个地图 + var centerArr = centerParam.split(','); + var point = new BMap.Point(centerArr[0], centerArr[1]);//定义一个中心点坐标 + map.centerAndZoom(point, zoomParam);//设定地图的中心点和坐标并将地图显示在地图容器中 + window.map = map;//将map变量存储在全局 + } + + //地图事件设置函数: + function setMapEvent(){ + map.enableDragging();//启用地图拖拽事件,默认启用(可不写) + map.enableScrollWheelZoom();//启用地图滚轮放大缩小 + map.enableDoubleClickZoom();//启用鼠标双击放大,默认启用(可不写) + map.enableKeyboard();//启用键盘上下左右键移动地图 + } + + //地图控件添加函数: + function addMapControl(){ + //向地图中添加缩放控件 + var ctrl_nav = new BMap.NavigationControl({anchor:BMAP_ANCHOR_TOP_LEFT,type:BMAP_NAVIGATION_CONTROL_LARGE}); + map.addControl(ctrl_nav); + //向地图中添加缩略图控件 + var ctrl_ove = new BMap.OverviewMapControl({anchor:BMAP_ANCHOR_BOTTOM_RIGHT,isOpen:1}); + map.addControl(ctrl_ove); + //向地图中添加比例尺控件 + var ctrl_sca = new BMap.ScaleControl({anchor:BMAP_ANCHOR_BOTTOM_LEFT}); + map.addControl(ctrl_sca); + } +</script> +</html> \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/baidumap/map.html b/static/plugins/kindeditor/plugins/baidumap/map.html new file mode 100755 index 0000000..b65ea1d --- /dev/null +++ b/static/plugins/kindeditor/plugins/baidumap/map.html @@ -0,0 +1,43 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8" /> + <title>Baidu Maps</title> + <style> + html { height: 100% } + body { height: 100%; margin: 0; padding: 0; background-color: #FFF } + </style> + <script charset="utf-8" src="http://api.map.baidu.com/api?v=1.3"></script> + <script> + var map, geocoder; + function initialize() { + map = new BMap.Map('map_canvas'); + var point = new BMap.Point(121.473704, 31.230393); + map.centerAndZoom(point, 11); + map.addControl(new BMap.NavigationControl()); + map.enableScrollWheelZoom(); + + var gc = new BMap.Geocoder(); + gc.getLocation(point, function(rs){ + var addComp = rs.addressComponents; + var address = [addComp.city].join(''); + parent.document.getElementById("kindeditor_plugin_map_address").value = address; + }); + } + function search(address) { + if (!map) return; + var local = new BMap.LocalSearch(map, { + renderOptions: { + map: map, + autoViewport: true, + selectFirstResult: false + } + }); + local.search(address); + } + </script> + </head> + <body onload="initialize();"> + <div id="map_canvas" style="width:100%; height:100%"></div> + </body> +</html> diff --git a/static/plugins/kindeditor/plugins/clearhtml/clearhtml.js b/static/plugins/kindeditor/plugins/clearhtml/clearhtml.js new file mode 100755 index 0000000..96ee5fe --- /dev/null +++ b/static/plugins/kindeditor/plugins/clearhtml/clearhtml.js @@ -0,0 +1,29 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('clearhtml', function(K) { + var self = this, name = 'clearhtml'; + self.clickToolbar(name, function() { + self.focus(); + var html = self.html(); + html = html.replace(/(<script[^>]*>)([\s\S]*?)(<\/script>)/ig, ''); + html = html.replace(/(<style[^>]*>)([\s\S]*?)(<\/style>)/ig, ''); + html = K.formatHtml(html, { + a : ['href', 'target'], + embed : ['src', 'width', 'height', 'type', 'loop', 'autostart', 'quality', '.width', '.height', 'align', 'allowscriptaccess'], + img : ['src', 'width', 'height', 'border', 'alt', 'title', '.width', '.height'], + table : ['border'], + 'td,th' : ['rowspan', 'colspan'], + 'div,hr,br,tbody,tr,p,ol,ul,li,blockquote,h1,h2,h3,h4,h5,h6' : [] + }); + self.html(html); + self.cmd.selection(true); + self.addBookmark(); + }); +}); diff --git a/static/plugins/kindeditor/plugins/code/code.js b/static/plugins/kindeditor/plugins/code/code.js new file mode 100755 index 0000000..67fde02 --- /dev/null +++ b/static/plugins/kindeditor/plugins/code/code.js @@ -0,0 +1,62 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// google code prettify: http://google-code-prettify.googlecode.com/ +// http://google-code-prettify.googlecode.com/ + +KindEditor.plugin('code', function(K) { + var self = this, name = 'code'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = ['<div style="padding:10px 20px;">', + '<div class="ke-dialog-row">', + '<select class="ke-code-type">', + '<option value="js">JavaScript</option>', + '<option value="html">HTML</option>', + '<option value="css">CSS</option>', + '<option value="php">PHP</option>', + '<option value="pl">Perl</option>', + '<option value="py">Python</option>', + '<option value="rb">Ruby</option>', + '<option value="java">Java</option>', + '<option value="vb">ASP/VB</option>', + '<option value="cpp">C/C++</option>', + '<option value="cs">C#</option>', + '<option value="xml">XML</option>', + '<option value="bsh">Shell</option>', + '<option value="">Other</option>', + '</select>', + '</div>', + '<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>', + '</div>'].join(''), + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var type = K('.ke-code-type', dialog.div).val(), + code = textarea.val(), + cls = type === '' ? '' : ' lang-' + type, + html = '<pre class="prettyprint' + cls + '">\n' + K.escape(code) + '</pre> '; + if (K.trim(code) === '') { + alert(lang.pleaseInput); + textarea[0].focus(); + return; + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/static/plugins/kindeditor/plugins/code/prettify.css b/static/plugins/kindeditor/plugins/code/prettify.css new file mode 100755 index 0000000..b8287e5 --- /dev/null +++ b/static/plugins/kindeditor/plugins/code/prettify.css @@ -0,0 +1,13 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} + +pre.prettyprint { + border: 0; + border-left: 3px solid rgb(204, 204, 204); + margin-left: 2em; + padding: 0.5em; + font-size: 110%; + display: block; + font-family: "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + margin: 1em 0px; + white-space: pre; +} diff --git a/static/plugins/kindeditor/plugins/code/prettify.js b/static/plugins/kindeditor/plugins/code/prettify.js new file mode 100755 index 0000000..eef5ad7 --- /dev/null +++ b/static/plugins/kindeditor/plugins/code/prettify.js @@ -0,0 +1,28 @@ +var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; +(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= +[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c< +f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&& +(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r= +{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length, +t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b=== +"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), +l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, +q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, +q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, +"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), +a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} +for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value", +m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m= +a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue= +j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], +"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], +H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], +J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ +I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), +["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", +/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), +["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", +hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b= +!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m, +250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit", +PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})(); diff --git a/static/plugins/kindeditor/plugins/emoticons/emoticons.js b/static/plugins/kindeditor/plugins/emoticons/emoticons.js new file mode 100755 index 0000000..8c0375f --- /dev/null +++ b/static/plugins/kindeditor/plugins/emoticons/emoticons.js @@ -0,0 +1,129 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('emoticons', function(K) { + var self = this, name = 'emoticons', + path = (self.emoticonsPath || self.pluginsPath + 'emoticons/images/'), + allowPreview = self.allowPreviewEmoticons === undefined ? true : self.allowPreviewEmoticons, + currentPageNum = 1; + self.clickToolbar(name, function() { + var rows = 5, cols = 9, total = 135, startNum = 0, + cells = rows * cols, pages = Math.ceil(total / cells), + colsHalf = Math.floor(cols / 2), + wrapperDiv = K('<div class="ke-plugin-emoticons"></div>'), + elements = [], + menu = self.createMenu({ + name : name, + beforeRemove : function() { + removeEvent(); + } + }); + menu.div.append(wrapperDiv); + var previewDiv, previewImg; + if (allowPreview) { + previewDiv = K('<div class="ke-preview"></div>').css('right', 0); + previewImg = K('<img class="ke-preview-img" src="' + path + startNum + '.gif" />'); + wrapperDiv.append(previewDiv); + previewDiv.append(previewImg); + } + function bindCellEvent(cell, j, num) { + if (previewDiv) { + cell.mouseover(function() { + if (j > colsHalf) { + previewDiv.css('left', 0); + previewDiv.css('right', ''); + } else { + previewDiv.css('left', ''); + previewDiv.css('right', 0); + } + previewImg.attr('src', path + num + '.gif'); + K(this).addClass('ke-on'); + }); + } else { + cell.mouseover(function() { + K(this).addClass('ke-on'); + }); + } + cell.mouseout(function() { + K(this).removeClass('ke-on'); + }); + cell.click(function(e) { + self.insertHtml('<img src="' + path + num + '.gif" border="0" alt="" />').hideMenu().focus(); + e.stop(); + }); + } + function createEmoticonsTable(pageNum, parentDiv) { + var table = document.createElement('table'); + parentDiv.append(table); + if (previewDiv) { + K(table).mouseover(function() { + previewDiv.show('block'); + }); + K(table).mouseout(function() { + previewDiv.hide(); + }); + elements.push(K(table)); + } + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + var num = (pageNum - 1) * cells + startNum; + for (var i = 0; i < rows; i++) { + var row = table.insertRow(i); + for (var j = 0; j < cols; j++) { + var cell = K(row.insertCell(j)); + cell.addClass('ke-cell'); + bindCellEvent(cell, j, num); + var span = K('<span class="ke-img"></span>') + .css('background-position', '-' + (24 * num) + 'px 0px') + .css('background-image', 'url(' + path + 'static.gif)'); + cell.append(span); + elements.push(cell); + num++; + } + } + return table; + } + var table = createEmoticonsTable(currentPageNum, wrapperDiv); + function removeEvent() { + K.each(elements, function() { + this.unbind(); + }); + } + var pageDiv; + function bindPageEvent(el, pageNum) { + el.click(function(e) { + removeEvent(); + table.parentNode.removeChild(table); + pageDiv.remove(); + table = createEmoticonsTable(pageNum, wrapperDiv); + createPageTable(pageNum); + currentPageNum = pageNum; + e.stop(); + }); + } + function createPageTable(currentPageNum) { + pageDiv = K('<div class="ke-page"></div>'); + wrapperDiv.append(pageDiv); + for (var pageNum = 1; pageNum <= pages; pageNum++) { + if (currentPageNum !== pageNum) { + var a = K('<a href="javascript:;">[' + pageNum + ']</a>'); + bindPageEvent(a, pageNum); + pageDiv.append(a); + elements.push(a); + } else { + pageDiv.append(K('@[' + pageNum + ']')); + } + pageDiv.append(K('@&nbsp;')); + } + } + createPageTable(currentPageNum); + }); +}); diff --git a/static/plugins/kindeditor/plugins/emoticons/images/0.gif b/static/plugins/kindeditor/plugins/emoticons/images/0.gif new file mode 100755 index 0000000..5be27cb Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/0.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/1.gif b/static/plugins/kindeditor/plugins/emoticons/images/1.gif new file mode 100755 index 0000000..a2644a9 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/1.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/10.gif b/static/plugins/kindeditor/plugins/emoticons/images/10.gif new file mode 100755 index 0000000..905c15b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/10.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/100.gif b/static/plugins/kindeditor/plugins/emoticons/images/100.gif new file mode 100755 index 0000000..92ad35d Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/100.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/101.gif b/static/plugins/kindeditor/plugins/emoticons/images/101.gif new file mode 100755 index 0000000..1f27663 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/101.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/102.gif b/static/plugins/kindeditor/plugins/emoticons/images/102.gif new file mode 100755 index 0000000..748ded1 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/102.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/103.gif b/static/plugins/kindeditor/plugins/emoticons/images/103.gif new file mode 100755 index 0000000..be9eaa0 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/103.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/104.gif b/static/plugins/kindeditor/plugins/emoticons/images/104.gif new file mode 100755 index 0000000..d7c2066 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/104.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/105.gif b/static/plugins/kindeditor/plugins/emoticons/images/105.gif new file mode 100755 index 0000000..2f353ca Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/105.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/106.gif b/static/plugins/kindeditor/plugins/emoticons/images/106.gif new file mode 100755 index 0000000..5193534 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/106.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/107.gif b/static/plugins/kindeditor/plugins/emoticons/images/107.gif new file mode 100755 index 0000000..70d38d3 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/107.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/108.gif b/static/plugins/kindeditor/plugins/emoticons/images/108.gif new file mode 100755 index 0000000..749d500 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/108.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/109.gif b/static/plugins/kindeditor/plugins/emoticons/images/109.gif new file mode 100755 index 0000000..6f57d56 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/109.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/11.gif b/static/plugins/kindeditor/plugins/emoticons/images/11.gif new file mode 100755 index 0000000..b512dd5 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/11.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/110.gif b/static/plugins/kindeditor/plugins/emoticons/images/110.gif new file mode 100755 index 0000000..e253abc Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/110.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/111.gif b/static/plugins/kindeditor/plugins/emoticons/images/111.gif new file mode 100755 index 0000000..0c56723 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/111.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/112.gif b/static/plugins/kindeditor/plugins/emoticons/images/112.gif new file mode 100755 index 0000000..c8ddce8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/112.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/113.gif b/static/plugins/kindeditor/plugins/emoticons/images/113.gif new file mode 100755 index 0000000..2727104 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/113.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/114.gif b/static/plugins/kindeditor/plugins/emoticons/images/114.gif new file mode 100755 index 0000000..53918e2 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/114.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/115.gif b/static/plugins/kindeditor/plugins/emoticons/images/115.gif new file mode 100755 index 0000000..4db3369 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/115.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/116.gif b/static/plugins/kindeditor/plugins/emoticons/images/116.gif new file mode 100755 index 0000000..57326bd Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/116.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/117.gif b/static/plugins/kindeditor/plugins/emoticons/images/117.gif new file mode 100755 index 0000000..14611b6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/117.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/118.gif b/static/plugins/kindeditor/plugins/emoticons/images/118.gif new file mode 100755 index 0000000..8c25500 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/118.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/119.gif b/static/plugins/kindeditor/plugins/emoticons/images/119.gif new file mode 100755 index 0000000..65bb468 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/119.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/12.gif b/static/plugins/kindeditor/plugins/emoticons/images/12.gif new file mode 100755 index 0000000..547529c Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/12.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/120.gif b/static/plugins/kindeditor/plugins/emoticons/images/120.gif new file mode 100755 index 0000000..5ce77c0 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/120.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/121.gif b/static/plugins/kindeditor/plugins/emoticons/images/121.gif new file mode 100755 index 0000000..a021aba Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/121.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/122.gif b/static/plugins/kindeditor/plugins/emoticons/images/122.gif new file mode 100755 index 0000000..9a79e11 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/122.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/123.gif b/static/plugins/kindeditor/plugins/emoticons/images/123.gif new file mode 100755 index 0000000..b9480be Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/123.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/124.gif b/static/plugins/kindeditor/plugins/emoticons/images/124.gif new file mode 100755 index 0000000..7fed477 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/124.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/125.gif b/static/plugins/kindeditor/plugins/emoticons/images/125.gif new file mode 100755 index 0000000..e2c3c11 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/125.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/126.gif b/static/plugins/kindeditor/plugins/emoticons/images/126.gif new file mode 100755 index 0000000..24105c9 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/126.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/127.gif b/static/plugins/kindeditor/plugins/emoticons/images/127.gif new file mode 100755 index 0000000..0cead36 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/127.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/128.gif b/static/plugins/kindeditor/plugins/emoticons/images/128.gif new file mode 100755 index 0000000..3185861 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/128.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/129.gif b/static/plugins/kindeditor/plugins/emoticons/images/129.gif new file mode 100755 index 0000000..ffd7c6b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/129.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/13.gif b/static/plugins/kindeditor/plugins/emoticons/images/13.gif new file mode 100755 index 0000000..3475300 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/13.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/130.gif b/static/plugins/kindeditor/plugins/emoticons/images/130.gif new file mode 100755 index 0000000..d828e3d Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/130.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/131.gif b/static/plugins/kindeditor/plugins/emoticons/images/131.gif new file mode 100755 index 0000000..dcb096f Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/131.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/132.gif b/static/plugins/kindeditor/plugins/emoticons/images/132.gif new file mode 100755 index 0000000..1b272a6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/132.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/133.gif b/static/plugins/kindeditor/plugins/emoticons/images/133.gif new file mode 100755 index 0000000..0d0e864 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/133.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/134.gif b/static/plugins/kindeditor/plugins/emoticons/images/134.gif new file mode 100755 index 0000000..cf48356 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/134.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/14.gif b/static/plugins/kindeditor/plugins/emoticons/images/14.gif new file mode 100755 index 0000000..6a788f8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/14.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/15.gif b/static/plugins/kindeditor/plugins/emoticons/images/15.gif new file mode 100755 index 0000000..debab8e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/15.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/16.gif b/static/plugins/kindeditor/plugins/emoticons/images/16.gif new file mode 100755 index 0000000..ed5d29f Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/16.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/17.gif b/static/plugins/kindeditor/plugins/emoticons/images/17.gif new file mode 100755 index 0000000..85886fe Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/17.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/18.gif b/static/plugins/kindeditor/plugins/emoticons/images/18.gif new file mode 100755 index 0000000..b6af218 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/18.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/19.gif b/static/plugins/kindeditor/plugins/emoticons/images/19.gif new file mode 100755 index 0000000..e045ff2 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/19.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/2.gif b/static/plugins/kindeditor/plugins/emoticons/images/2.gif new file mode 100755 index 0000000..40cfda4 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/2.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/20.gif b/static/plugins/kindeditor/plugins/emoticons/images/20.gif new file mode 100755 index 0000000..efd650f Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/20.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/21.gif b/static/plugins/kindeditor/plugins/emoticons/images/21.gif new file mode 100755 index 0000000..cb8cf6d Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/21.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/22.gif b/static/plugins/kindeditor/plugins/emoticons/images/22.gif new file mode 100755 index 0000000..96b04df Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/22.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/23.gif b/static/plugins/kindeditor/plugins/emoticons/images/23.gif new file mode 100755 index 0000000..96516b8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/23.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/24.gif b/static/plugins/kindeditor/plugins/emoticons/images/24.gif new file mode 100755 index 0000000..5f925c7 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/24.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/25.gif b/static/plugins/kindeditor/plugins/emoticons/images/25.gif new file mode 100755 index 0000000..97f8b1a Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/25.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/26.gif b/static/plugins/kindeditor/plugins/emoticons/images/26.gif new file mode 100755 index 0000000..a7cded7 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/26.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/27.gif b/static/plugins/kindeditor/plugins/emoticons/images/27.gif new file mode 100755 index 0000000..bb46890 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/27.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/28.gif b/static/plugins/kindeditor/plugins/emoticons/images/28.gif new file mode 100755 index 0000000..f59dd58 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/28.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/29.gif b/static/plugins/kindeditor/plugins/emoticons/images/29.gif new file mode 100755 index 0000000..3c5227e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/29.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/3.gif b/static/plugins/kindeditor/plugins/emoticons/images/3.gif new file mode 100755 index 0000000..6d6f762 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/3.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/30.gif b/static/plugins/kindeditor/plugins/emoticons/images/30.gif new file mode 100755 index 0000000..e24a180 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/30.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/31.gif b/static/plugins/kindeditor/plugins/emoticons/images/31.gif new file mode 100755 index 0000000..073e743 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/31.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/32.gif b/static/plugins/kindeditor/plugins/emoticons/images/32.gif new file mode 100755 index 0000000..772eff2 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/32.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/33.gif b/static/plugins/kindeditor/plugins/emoticons/images/33.gif new file mode 100755 index 0000000..217c1c5 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/33.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/34.gif b/static/plugins/kindeditor/plugins/emoticons/images/34.gif new file mode 100755 index 0000000..e9d4213 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/34.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/35.gif b/static/plugins/kindeditor/plugins/emoticons/images/35.gif new file mode 100755 index 0000000..d6da2c3 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/35.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/36.gif b/static/plugins/kindeditor/plugins/emoticons/images/36.gif new file mode 100755 index 0000000..c1e6ac9 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/36.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/37.gif b/static/plugins/kindeditor/plugins/emoticons/images/37.gif new file mode 100755 index 0000000..92efec6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/37.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/38.gif b/static/plugins/kindeditor/plugins/emoticons/images/38.gif new file mode 100755 index 0000000..489f0f9 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/38.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/39.gif b/static/plugins/kindeditor/plugins/emoticons/images/39.gif new file mode 100755 index 0000000..734f6d8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/39.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/4.gif b/static/plugins/kindeditor/plugins/emoticons/images/4.gif new file mode 100755 index 0000000..6ccdaa2 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/4.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/40.gif b/static/plugins/kindeditor/plugins/emoticons/images/40.gif new file mode 100755 index 0000000..24a8eb6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/40.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/41.gif b/static/plugins/kindeditor/plugins/emoticons/images/41.gif new file mode 100755 index 0000000..99139e1 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/41.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/42.gif b/static/plugins/kindeditor/plugins/emoticons/images/42.gif new file mode 100755 index 0000000..f60897e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/42.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/43.gif b/static/plugins/kindeditor/plugins/emoticons/images/43.gif new file mode 100755 index 0000000..4350491 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/43.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/44.gif b/static/plugins/kindeditor/plugins/emoticons/images/44.gif new file mode 100755 index 0000000..650d3dd Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/44.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/45.gif b/static/plugins/kindeditor/plugins/emoticons/images/45.gif new file mode 100755 index 0000000..5c8e071 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/45.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/46.gif b/static/plugins/kindeditor/plugins/emoticons/images/46.gif new file mode 100755 index 0000000..f3cb074 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/46.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/47.gif b/static/plugins/kindeditor/plugins/emoticons/images/47.gif new file mode 100755 index 0000000..5b3057a Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/47.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/48.gif b/static/plugins/kindeditor/plugins/emoticons/images/48.gif new file mode 100755 index 0000000..27a30c1 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/48.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/49.gif b/static/plugins/kindeditor/plugins/emoticons/images/49.gif new file mode 100755 index 0000000..dcfa48a Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/49.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/5.gif b/static/plugins/kindeditor/plugins/emoticons/images/5.gif new file mode 100755 index 0000000..ab0b81b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/5.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/50.gif b/static/plugins/kindeditor/plugins/emoticons/images/50.gif new file mode 100755 index 0000000..029cf0f Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/50.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/51.gif b/static/plugins/kindeditor/plugins/emoticons/images/51.gif new file mode 100755 index 0000000..69f183f Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/51.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/52.gif b/static/plugins/kindeditor/plugins/emoticons/images/52.gif new file mode 100755 index 0000000..d41e8aa Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/52.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/53.gif b/static/plugins/kindeditor/plugins/emoticons/images/53.gif new file mode 100755 index 0000000..56352dd Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/53.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/54.gif b/static/plugins/kindeditor/plugins/emoticons/images/54.gif new file mode 100755 index 0000000..b28d848 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/54.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/55.gif b/static/plugins/kindeditor/plugins/emoticons/images/55.gif new file mode 100755 index 0000000..e18da84 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/55.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/56.gif b/static/plugins/kindeditor/plugins/emoticons/images/56.gif new file mode 100755 index 0000000..edf96f0 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/56.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/57.gif b/static/plugins/kindeditor/plugins/emoticons/images/57.gif new file mode 100755 index 0000000..3f0e2b9 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/57.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/58.gif b/static/plugins/kindeditor/plugins/emoticons/images/58.gif new file mode 100755 index 0000000..47b1aaa Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/58.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/59.gif b/static/plugins/kindeditor/plugins/emoticons/images/59.gif new file mode 100755 index 0000000..918288b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/59.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/6.gif b/static/plugins/kindeditor/plugins/emoticons/images/6.gif new file mode 100755 index 0000000..ceab122 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/6.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/60.gif b/static/plugins/kindeditor/plugins/emoticons/images/60.gif new file mode 100755 index 0000000..66d2113 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/60.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/61.gif b/static/plugins/kindeditor/plugins/emoticons/images/61.gif new file mode 100755 index 0000000..034933e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/61.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/62.gif b/static/plugins/kindeditor/plugins/emoticons/images/62.gif new file mode 100755 index 0000000..8d5c4fd Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/62.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/63.gif b/static/plugins/kindeditor/plugins/emoticons/images/63.gif new file mode 100755 index 0000000..d58fcf6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/63.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/64.gif b/static/plugins/kindeditor/plugins/emoticons/images/64.gif new file mode 100755 index 0000000..c4e00bd Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/64.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/65.gif b/static/plugins/kindeditor/plugins/emoticons/images/65.gif new file mode 100755 index 0000000..da23bfa Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/65.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/66.gif b/static/plugins/kindeditor/plugins/emoticons/images/66.gif new file mode 100755 index 0000000..310ec65 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/66.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/67.gif b/static/plugins/kindeditor/plugins/emoticons/images/67.gif new file mode 100755 index 0000000..51761ba Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/67.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/68.gif b/static/plugins/kindeditor/plugins/emoticons/images/68.gif new file mode 100755 index 0000000..345cb43 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/68.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/69.gif b/static/plugins/kindeditor/plugins/emoticons/images/69.gif new file mode 100755 index 0000000..e0f28a0 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/69.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/7.gif b/static/plugins/kindeditor/plugins/emoticons/images/7.gif new file mode 100755 index 0000000..2f45399 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/7.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/70.gif b/static/plugins/kindeditor/plugins/emoticons/images/70.gif new file mode 100755 index 0000000..24284cf Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/70.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/71.gif b/static/plugins/kindeditor/plugins/emoticons/images/71.gif new file mode 100755 index 0000000..a0ccf2e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/71.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/72.gif b/static/plugins/kindeditor/plugins/emoticons/images/72.gif new file mode 100755 index 0000000..7e113ee Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/72.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/73.gif b/static/plugins/kindeditor/plugins/emoticons/images/73.gif new file mode 100755 index 0000000..c0293c3 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/73.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/74.gif b/static/plugins/kindeditor/plugins/emoticons/images/74.gif new file mode 100755 index 0000000..1c52bde Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/74.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/75.gif b/static/plugins/kindeditor/plugins/emoticons/images/75.gif new file mode 100755 index 0000000..9cb9aa7 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/75.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/76.gif b/static/plugins/kindeditor/plugins/emoticons/images/76.gif new file mode 100755 index 0000000..27019f8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/76.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/77.gif b/static/plugins/kindeditor/plugins/emoticons/images/77.gif new file mode 100755 index 0000000..8f882f5 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/77.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/78.gif b/static/plugins/kindeditor/plugins/emoticons/images/78.gif new file mode 100755 index 0000000..d0d0856 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/78.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/79.gif b/static/plugins/kindeditor/plugins/emoticons/images/79.gif new file mode 100755 index 0000000..61652a7 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/79.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/8.gif b/static/plugins/kindeditor/plugins/emoticons/images/8.gif new file mode 100755 index 0000000..f6c8834 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/8.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/80.gif b/static/plugins/kindeditor/plugins/emoticons/images/80.gif new file mode 100755 index 0000000..9a77936 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/80.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/81.gif b/static/plugins/kindeditor/plugins/emoticons/images/81.gif new file mode 100755 index 0000000..2329101 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/81.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/82.gif b/static/plugins/kindeditor/plugins/emoticons/images/82.gif new file mode 100755 index 0000000..644748a Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/82.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/83.gif b/static/plugins/kindeditor/plugins/emoticons/images/83.gif new file mode 100755 index 0000000..fbf275b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/83.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/84.gif b/static/plugins/kindeditor/plugins/emoticons/images/84.gif new file mode 100755 index 0000000..076f0c6 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/84.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/85.gif b/static/plugins/kindeditor/plugins/emoticons/images/85.gif new file mode 100755 index 0000000..d254af4 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/85.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/86.gif b/static/plugins/kindeditor/plugins/emoticons/images/86.gif new file mode 100755 index 0000000..8f09d33 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/86.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/87.gif b/static/plugins/kindeditor/plugins/emoticons/images/87.gif new file mode 100755 index 0000000..df70756 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/87.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/88.gif b/static/plugins/kindeditor/plugins/emoticons/images/88.gif new file mode 100755 index 0000000..4d8b15e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/88.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/89.gif b/static/plugins/kindeditor/plugins/emoticons/images/89.gif new file mode 100755 index 0000000..05726dc Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/89.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/9.gif b/static/plugins/kindeditor/plugins/emoticons/images/9.gif new file mode 100755 index 0000000..c2d8450 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/9.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/90.gif b/static/plugins/kindeditor/plugins/emoticons/images/90.gif new file mode 100755 index 0000000..adaf20e Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/90.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/91.gif b/static/plugins/kindeditor/plugins/emoticons/images/91.gif new file mode 100755 index 0000000..608d0ad Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/91.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/92.gif b/static/plugins/kindeditor/plugins/emoticons/images/92.gif new file mode 100755 index 0000000..b909e16 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/92.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/93.gif b/static/plugins/kindeditor/plugins/emoticons/images/93.gif new file mode 100755 index 0000000..7f71a8c Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/93.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/94.gif b/static/plugins/kindeditor/plugins/emoticons/images/94.gif new file mode 100755 index 0000000..4f26d7d Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/94.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/95.gif b/static/plugins/kindeditor/plugins/emoticons/images/95.gif new file mode 100755 index 0000000..5ef6d38 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/95.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/96.gif b/static/plugins/kindeditor/plugins/emoticons/images/96.gif new file mode 100755 index 0000000..2b709e1 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/96.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/97.gif b/static/plugins/kindeditor/plugins/emoticons/images/97.gif new file mode 100755 index 0000000..cf29be8 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/97.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/98.gif b/static/plugins/kindeditor/plugins/emoticons/images/98.gif new file mode 100755 index 0000000..c70e7d3 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/98.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/99.gif b/static/plugins/kindeditor/plugins/emoticons/images/99.gif new file mode 100755 index 0000000..05c1863 Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/99.gif differ diff --git a/static/plugins/kindeditor/plugins/emoticons/images/static.gif b/static/plugins/kindeditor/plugins/emoticons/images/static.gif new file mode 100755 index 0000000..b8c444b Binary files /dev/null and b/static/plugins/kindeditor/plugins/emoticons/images/static.gif differ diff --git a/static/plugins/kindeditor/plugins/filemanager/filemanager.js b/static/plugins/kindeditor/plugins/filemanager/filemanager.js new file mode 100755 index 0000000..dfe2e2b --- /dev/null +++ b/static/plugins/kindeditor/plugins/filemanager/filemanager.js @@ -0,0 +1,189 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('filemanager', function(K) { + var self = this, name = 'filemanager', + fileManagerJson = K.undef(self.fileManagerJson, self.basePath + 'php/file_manager_json.php'), + imgPath = self.pluginsPath + name + '/images/', + lang = self.lang(name + '.'); + function makeFileTitle(filename, filesize, datetime) { + return filename + ' (' + Math.ceil(filesize / 1024) + 'KB, ' + datetime + ')'; + } + function bindTitle(el, data) { + if (data.is_dir) { + el.attr('title', data.filename); + } else { + el.attr('title', makeFileTitle(data.filename, data.filesize, data.datetime)); + } + } + self.plugin.filemanagerDialog = function(options) { + var width = K.undef(options.width, 650), + height = K.undef(options.height, 510), + dirName = K.undef(options.dirName, ''), + viewType = K.undef(options.viewType, 'VIEW').toUpperCase(), // "LIST" or "VIEW" + clickFn = options.clickFn; + var html = [ + '<div style="padding:10px 20px;">', + // header start + '<div class="ke-plugin-filemanager-header">', + // left start + '<div class="ke-left">', + '<img class="ke-inline-block" name="moveupImg" src="' + imgPath + 'go-up.gif" width="16" height="16" border="0" alt="" /> ', + '<a class="ke-inline-block" name="moveupLink" href="javascript:;">' + lang.moveup + '</a>', + '</div>', + // right start + '<div class="ke-right">', + lang.viewType + ' <select class="ke-inline-block" name="viewType">', + '<option value="VIEW">' + lang.viewImage + '</option>', + '<option value="LIST">' + lang.listImage + '</option>', + '</select> ', + lang.orderType + ' <select class="ke-inline-block" name="orderType">', + '<option value="NAME">' + lang.fileName + '</option>', + '<option value="SIZE">' + lang.fileSize + '</option>', + '<option value="TYPE">' + lang.fileType + '</option>', + '</select>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + // body start + '<div class="ke-plugin-filemanager-body"></div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : width, + height : height, + title : self.lang(name), + body : html + }), + div = dialog.div, + bodyDiv = K('.ke-plugin-filemanager-body', div), + moveupImg = K('[name="moveupImg"]', div), + moveupLink = K('[name="moveupLink"]', div), + viewServerBtn = K('[name="viewServer"]', div), + viewTypeBox = K('[name="viewType"]', div), + orderTypeBox = K('[name="orderType"]', div); + function reloadPage(path, order, func) { + var param = 'path=' + path + '&order=' + order + '&dir=' + dirName; + dialog.showLoading(self.lang('ajaxLoading')); + K.ajax(K.addParam(fileManagerJson, param + '&' + new Date().getTime()), function(data) { + dialog.hideLoading(); + func(data); + }); + } + var elList = []; + function bindEvent(el, result, data, createFunc) { + var fileUrl = K.formatUrl(result.current_url + data.filename, 'absolute'), + dirPath = encodeURIComponent(result.current_dir_path + data.filename + '/'); + if (data.is_dir) { + el.click(function(e) { + reloadPage(dirPath, orderTypeBox.val(), createFunc); + }); + } else if (data.is_photo) { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } else { + el.click(function(e) { + clickFn.call(this, fileUrl, data.filename); + }); + } + elList.push(el); + } + function createCommon(result, createFunc) { + // remove events + K.each(elList, function() { + this.unbind(); + }); + moveupLink.unbind(); + viewTypeBox.unbind(); + orderTypeBox.unbind(); + // add events + if (result.current_dir_path) { + moveupLink.click(function(e) { + reloadPage(result.moveup_dir_path, orderTypeBox.val(), createFunc); + }); + } + function changeFunc() { + if (viewTypeBox.val() == 'VIEW') { + reloadPage(result.current_dir_path, orderTypeBox.val(), createView); + } else { + reloadPage(result.current_dir_path, orderTypeBox.val(), createList); + } + } + viewTypeBox.change(changeFunc); + orderTypeBox.change(changeFunc); + bodyDiv.html(''); + } + function createList(result) { + createCommon(result, createList); + var table = document.createElement('table'); + table.className = 'ke-table'; + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + bodyDiv.append(table); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], row = K(table.insertRow(i)); + row.mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + var iconUrl = imgPath + (data.is_dir ? 'folder-16.gif' : 'file-16.gif'), + img = K('<img src="' + iconUrl + '" width="16" height="16" alt="' + data.filename + '" align="absmiddle" />'), + cell0 = K(row[0].insertCell(0)).addClass('ke-cell ke-name').append(img).append(document.createTextNode(' ' + data.filename)); + if (!data.is_dir || data.has_file) { + row.css('cursor', 'pointer'); + cell0.attr('title', data.filename); + bindEvent(cell0, result, data, createList); + } else { + cell0.attr('title', lang.emptyFolder); + } + K(row[0].insertCell(1)).addClass('ke-cell ke-size').html(data.is_dir ? '-' : Math.ceil(data.filesize / 1024) + 'KB'); + K(row[0].insertCell(2)).addClass('ke-cell ke-datetime').html(data.datetime); + } + } + function createView(result) { + createCommon(result, createView); + var fileList = result.file_list; + for (var i = 0, len = fileList.length; i < len; i++) { + var data = fileList[i], + div = K('<div class="ke-inline-block ke-item"></div>'); + bodyDiv.append(div); + var photoDiv = K('<div class="ke-inline-block ke-photo"></div>') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + div.append(photoDiv); + var fileUrl = result.current_url + data.filename, + iconUrl = data.is_dir ? imgPath + 'folder-64.gif' : (data.is_photo ? fileUrl : imgPath + 'file-64.gif'); + var img = K('<img src="' + iconUrl + '" width="80" height="80" alt="' + data.filename + '" />'); + if (!data.is_dir || data.has_file) { + photoDiv.css('cursor', 'pointer'); + bindTitle(photoDiv, data); + bindEvent(photoDiv, result, data, createView); + } else { + photoDiv.attr('title', lang.emptyFolder); + } + photoDiv.append(img); + div.append('<div class="ke-name" title="' + data.filename + '">' + data.filename + '</div>'); + } + } + viewTypeBox.val(viewType); + reloadPage('', orderTypeBox.val(), viewType == 'VIEW' ? createView : createList); + return dialog; + } + +}); diff --git a/static/plugins/kindeditor/plugins/filemanager/images/file-16.gif b/static/plugins/kindeditor/plugins/filemanager/images/file-16.gif new file mode 100755 index 0000000..2cf6e47 Binary files /dev/null and b/static/plugins/kindeditor/plugins/filemanager/images/file-16.gif differ diff --git a/static/plugins/kindeditor/plugins/filemanager/images/file-64.gif b/static/plugins/kindeditor/plugins/filemanager/images/file-64.gif new file mode 100755 index 0000000..2e211da Binary files /dev/null and b/static/plugins/kindeditor/plugins/filemanager/images/file-64.gif differ diff --git a/static/plugins/kindeditor/plugins/filemanager/images/folder-16.gif b/static/plugins/kindeditor/plugins/filemanager/images/folder-16.gif new file mode 100755 index 0000000..850b5a3 Binary files /dev/null and b/static/plugins/kindeditor/plugins/filemanager/images/folder-16.gif differ diff --git a/static/plugins/kindeditor/plugins/filemanager/images/folder-64.gif b/static/plugins/kindeditor/plugins/filemanager/images/folder-64.gif new file mode 100755 index 0000000..e8a1b09 Binary files /dev/null and b/static/plugins/kindeditor/plugins/filemanager/images/folder-64.gif differ diff --git a/static/plugins/kindeditor/plugins/filemanager/images/go-up.gif b/static/plugins/kindeditor/plugins/filemanager/images/go-up.gif new file mode 100755 index 0000000..92ae23d Binary files /dev/null and b/static/plugins/kindeditor/plugins/filemanager/images/go-up.gif differ diff --git a/static/plugins/kindeditor/plugins/fixtoolbar/fixtoolbar.js b/static/plugins/kindeditor/plugins/fixtoolbar/fixtoolbar.js new file mode 100755 index 0000000..7a16fca --- /dev/null +++ b/static/plugins/kindeditor/plugins/fixtoolbar/fixtoolbar.js @@ -0,0 +1,35 @@ +/** + * Created by chenyihong on 14/12/4. + */ + +KindEditor.plugin('fixtoolbar', function (K) { + var self = this; + if (!self.fixToolBar) { + return; + } + + function init() { + var toolbar = K('.ke-toolbar'); + var originY = toolbar.pos().y; + K(window).bind('scroll', function () { + if (toolbar.css('position') == 'fixed') { + if(document.body.scrollTop - originY < 0){ + toolbar.css('position', 'static'); + toolbar.css('top', 'auto'); + } + } else { + if (toolbar.pos().y - document.body.scrollTop < 0) { + toolbar.css('position', 'fixed'); + toolbar.css('top', 0); + } + } + }); + } + + if (self.isCreated) { + init(); + } else { + self.afterCreate(init); + } + +}); diff --git a/static/plugins/kindeditor/plugins/flash/flash.js b/static/plugins/kindeditor/plugins/flash/flash.js new file mode 100755 index 0000000..1e2e622 --- /dev/null +++ b/static/plugins/kindeditor/plugins/flash/flash.js @@ -0,0 +1,161 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('flash', function(K) { + var self = this, name = 'flash', lang = self.lang(name + '.'), + allowFlashUpload = K.undef(self.allowFlashUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.flash = { + edit : function() { + var html = [ + '<div style="padding:20px;">', + //url + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + //width + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:60px;">' + lang.width + '</label>', + '<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" /> ', + '</div>', + //height + '<div class="ke-dialog-row">', + '<label for="keHeight" style="width:60px;">' + lang.height + '</label>', + '<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" /> ', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType('.swf'), + width : width, + height : height, + quality : 'high' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div); + urlBox.val('http://'); + + if (allowFlashUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=flash'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'flash', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedFlash(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedFlash().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.flash.edit); +}); diff --git a/static/plugins/kindeditor/plugins/image/image.js b/static/plugins/kindeditor/plugins/image/image.js new file mode 100755 index 0000000..4b82431 --- /dev/null +++ b/static/plugins/kindeditor/plugins/image/image.js @@ -0,0 +1,328 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('image', function(K) { + var self = this, name = 'image', + allowImageUpload = K.undef(self.allowImageUpload, true), + allowImageRemote = K.undef(self.allowImageRemote, true), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + allowFileManager = K.undef(self.allowFileManager, false), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imageTabIndex = K.undef(self.imageTabIndex, 0), + imgPath = self.pluginsPath + 'image/images/', + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + fillDescAfterUploadImage = K.undef(self.fillDescAfterUploadImage, false), + lang = self.lang(name + '.'); + + self.plugin.imageDialog = function(options) { + var imageUrl = options.imageUrl, + imageWidth = K.undef(options.imageWidth, ''), + imageHeight = K.undef(options.imageHeight, ''), + imageTitle = K.undef(options.imageTitle, ''), + imageAlign = K.undef(options.imageAlign, ''), + showRemote = K.undef(options.showRemote, true), + showLocal = K.undef(options.showLocal, true), + tabIndex = K.undef(options.tabIndex, 0), + clickFn = options.clickFn; + var target = 'kindeditor_upload_iframe_' + new Date().getTime(); + var hiddenElements = []; + for(var k in extraParams){ + hiddenElements.push('<input type="hidden" name="' + k + '" value="' + extraParams[k] + '" />'); + } + var html = [ + '<div style="padding:20px;">', + //tabs + '<div class="tabs"></div>', + //remote image - start + '<div class="tab1" style="display:none;">', + //url + '<div class="ke-dialog-row">', + '<label for="remoteUrl" style="width:60px;">' + lang.remoteUrl + '</label>', + '<input type="text" id="remoteUrl" class="ke-input-text" name="url" value="" style="width:200px;" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + //size + '<div class="ke-dialog-row">', + '<label for="remoteWidth" style="width:60px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="remoteWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> ', + '<img class="ke-refresh-btn" src="' + imgPath + 'refresh.png" width="16" height="16" alt="" style="cursor:pointer;" title="' + lang.resetSize + '" />', + '</div>', + //align + '<div class="ke-dialog-row">', + '<label style="width:60px;">' + lang.align + '</label>', + '<input type="radio" name="align" class="ke-inline-block" value="" checked="checked" /> <img name="defaultImg" src="' + imgPath + 'align_top.gif" width="23" height="25" alt="" />', + ' <input type="radio" name="align" class="ke-inline-block" value="left" /> <img name="leftImg" src="' + imgPath + 'align_left.gif" width="23" height="25" alt="" />', + ' <input type="radio" name="align" class="ke-inline-block" value="right" /> <img name="rightImg" src="' + imgPath + 'align_right.gif" width="23" height="25" alt="" />', + '</div>', + //title + '<div class="ke-dialog-row">', + '<label for="remoteTitle" style="width:60px;">' + lang.imgTitle + '</label>', + '<input type="text" id="remoteTitle" class="ke-input-text" name="title" value="" style="width:200px;" />', + '</div>', + '</div>', + //remote image - end + //local upload - start + '<div class="tab2" style="display:none;">', + '<iframe name="' + target + '" style="display:none;"></iframe>', + '<form class="ke-upload-area ke-form" method="post" enctype="multipart/form-data" target="' + target + '" action="' + K.addParam(uploadJson, 'dir=image') + '">', + //file + '<div class="ke-dialog-row">', + hiddenElements.join(''), + '<label style="width:60px;">' + lang.localUrl + '</label>', + '<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" />', + '</div>', + '</form>', + '</div>', + //local upload - end + '</div>' + ].join(''); + var dialogWidth = showLocal || allowFileManager ? 450 : 400, + dialogHeight = showLocal && showRemote ? 300 : 250; + var dialog = self.createDialog({ + name : name, + width : dialogWidth, + height : dialogHeight, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + // Bugfix: http://code.google.com/p/kindeditor/issues/detail?id=319 + if (dialog.isLoading) { + return; + } + // insert local image + if (showLocal && showRemote && tabs && tabs.selectedIndex === 1 || !showRemote) { + if (uploadbutton.fileBox.val() == '') { + alert(self.lang('pleaseSelectFile')); + return; + } + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + localUrlBox.val(''); + return; + } + // insert remote image + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(), + title = titleBox.val(), + align = ''; + alignBox.each(function() { + if (this.checked) { + align = this.value; + return false; + } + }); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + clickFn.call(self, url, title, width, height, 0, align); + } + }, + beforeRemove : function() { + viewServerBtn.unbind(); + widthBox.unbind(); + heightBox.unbind(); + refreshBtn.unbind(); + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + localUrlBox = K('[name="localUrl"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('.tab1 [name="width"]', div), + heightBox = K('.tab1 [name="height"]', div), + refreshBtn = K('.ke-refresh-btn', div), + titleBox = K('.tab1 [name="title"]', div), + alignBox = K('.tab1 [name="align"]', div); + + var tabs; + if (showRemote && showLocal) { + tabs = K.tabs({ + src : K('.tabs', div), + afterSelect : function(i) {} + }); + tabs.add({ + title : lang.remoteImage, + panel : K('.tab1', div) + }); + tabs.add({ + title : lang.localImage, + panel : K('.tab2', div) + }); + tabs.select(tabIndex); + } else if (showRemote) { + K('.tab1', div).show(); + } else if (showLocal) { + K('.tab2', div).show(); + } + + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + form : K('.ke-form', div), + target : target, + width: 60, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + if (!fillDescAfterUploadImage) { + clickFn.call(self, url, data.title, data.width, data.height, data.border, data.align); + } else { + K(".ke-dialog-row #remoteUrl", div).val(url); + K(".ke-tabs-li", div)[0].click(); + K(".ke-refresh-btn", div).click(); + } + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + localUrlBox.val(uploadbutton.fileBox.val()); + }); + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'VIEW', + dirName : 'image', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + var originalWidth = 0, originalHeight = 0; + function setSize(width, height) { + widthBox.val(width); + heightBox.val(height); + originalWidth = width; + originalHeight = height; + } + refreshBtn.click(function(e) { + var tempImg = K('<img src="' + urlBox.val() + '" />', document).css({ + position : 'absolute', + visibility : 'hidden', + top : 0, + left : '-1000px' + }); + tempImg.bind('load', function() { + setSize(tempImg.width(), tempImg.height()); + tempImg.remove(); + }); + K(document.body).append(tempImg); + }); + widthBox.change(function(e) { + if (originalWidth > 0) { + heightBox.val(Math.round(originalHeight / originalWidth * parseInt(this.value, 10))); + } + }); + heightBox.change(function(e) { + if (originalHeight > 0) { + widthBox.val(Math.round(originalWidth / originalHeight * parseInt(this.value, 10))); + } + }); + urlBox.val(options.imageUrl); + setSize(options.imageWidth, options.imageHeight); + titleBox.val(options.imageTitle); + alignBox.each(function() { + if (this.value === options.imageAlign) { + this.checked = true; + return false; + } + }); + if (showRemote && tabIndex === 0) { + urlBox[0].focus(); + urlBox[0].select(); + } + return dialog; + }; + self.plugin.image = { + edit : function() { + var img = self.plugin.getSelectedImage(); + self.plugin.imageDialog({ + imageUrl : img ? img.attr('data-ke-src') : 'http://', + imageWidth : img ? img.width() : '', + imageHeight : img ? img.height() : '', + imageTitle : img ? img.attr('title') : '', + imageAlign : img ? img.attr('align') : '', + showRemote : allowImageRemote, + showLocal : allowImageUpload, + tabIndex: img ? 0 : imageTabIndex, + clickFn : function(url, title, width, height, border, align) { + if (img) { + img.attr('src', url); + img.attr('data-ke-src', url); + img.attr('width', width); + img.attr('height', height); + img.attr('title', title); + img.attr('align', align); + img.attr('alt', title); + } else { + self.exec('insertimage', url, title, width, height, border, align); + } + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }, + 'delete' : function() { + var target = self.plugin.getSelectedImage(); + if (target.parent().name == 'a') { + target = target.parent(); + } + target.remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.image.edit); +}); diff --git a/static/plugins/kindeditor/plugins/image/images/align_left.gif b/static/plugins/kindeditor/plugins/image/images/align_left.gif new file mode 100755 index 0000000..ab17f56 Binary files /dev/null and b/static/plugins/kindeditor/plugins/image/images/align_left.gif differ diff --git a/static/plugins/kindeditor/plugins/image/images/align_right.gif b/static/plugins/kindeditor/plugins/image/images/align_right.gif new file mode 100755 index 0000000..e8ebe6a Binary files /dev/null and b/static/plugins/kindeditor/plugins/image/images/align_right.gif differ diff --git a/static/plugins/kindeditor/plugins/image/images/align_top.gif b/static/plugins/kindeditor/plugins/image/images/align_top.gif new file mode 100755 index 0000000..d8826a5 Binary files /dev/null and b/static/plugins/kindeditor/plugins/image/images/align_top.gif differ diff --git a/static/plugins/kindeditor/plugins/image/images/refresh.png b/static/plugins/kindeditor/plugins/image/images/refresh.png new file mode 100755 index 0000000..77e12d1 Binary files /dev/null and b/static/plugins/kindeditor/plugins/image/images/refresh.png differ diff --git a/static/plugins/kindeditor/plugins/insertfile/insertfile.js b/static/plugins/kindeditor/plugins/insertfile/insertfile.js new file mode 100755 index 0000000..0a4ce9e --- /dev/null +++ b/static/plugins/kindeditor/plugins/insertfile/insertfile.js @@ -0,0 +1,138 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('insertfile', function(K) { + var self = this, name = 'insertfile', + allowFileUpload = K.undef(self.allowFileUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + self.plugin.fileDialog = function(options) { + var fileUrl = K.undef(options.fileUrl, 'http://'), + fileTitle = K.undef(options.fileTitle, ''), + clickFn = options.clickFn; + var html = [ + '<div style="padding:20px;">', + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + //title + '<div class="ke-dialog-row">', + '<label for="keTitle" style="width:60px;">' + lang.title + '</label>', + '<input type="text" id="keTitle" class="ke-input-text" name="title" value="" style="width:160px;" /></div>', + '</div>', + //form end + '</form>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + title = titleBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (K.trim(title) === '') { + title = url; + } + clickFn.call(self, url, title); + } + } + }), + div = dialog.div; + + var urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + titleBox = K('[name="title"]', div); + + if (allowFileUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + url : K.addParam(uploadJson, 'dir=file'), + extraParams : extraParams, + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'file', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + urlBox.val(fileUrl); + titleBox.val(fileTitle); + urlBox[0].focus(); + urlBox[0].select(); + }; + self.clickToolbar(name, function() { + self.plugin.fileDialog({ + clickFn : function(url, title) { + var html = '<a class="ke-insertfile" href="' + url + '" data-ke-src="' + url + '" target="_blank">' + title + '</a>'; + self.insertHtml(html).hideDialog().focus(); + } + }); + }); +}); diff --git a/static/plugins/kindeditor/plugins/lineheight/lineheight.js b/static/plugins/kindeditor/plugins/lineheight/lineheight.js new file mode 100755 index 0000000..2125587 --- /dev/null +++ b/static/plugins/kindeditor/plugins/lineheight/lineheight.js @@ -0,0 +1,38 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('lineheight', function(K) { + var self = this, name = 'lineheight', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var curVal = '', commonNode = self.cmd.commonNode({'*' : '.line-height'}); + if (commonNode) { + curVal = commonNode.css('line-height'); + } + var menu = self.createMenu({ + name : name, + width : 150 + }); + K.each(lang.lineHeight, function(i, row) { + K.each(row, function(key, val) { + menu.addItem({ + title : val, + checked : curVal === key, + click : function() { + self.cmd.toggle('<span style="line-height:' + key + ';"></span>', { + span : '.line-height=' + key + }); + self.updateState(); + self.addBookmark(); + self.hideMenu(); + } + }); + }); + }); + }); +}); diff --git a/static/plugins/kindeditor/plugins/link/link.js b/static/plugins/kindeditor/plugins/link/link.js new file mode 100755 index 0000000..f707bc6 --- /dev/null +++ b/static/plugins/kindeditor/plugins/link/link.js @@ -0,0 +1,66 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('link', function(K) { + var self = this, name = 'link'; + self.plugin.link = { + edit : function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:20px;">' + + //url + '<div class="ke-dialog-row">' + + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>' + + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:260px;" /></div>' + + //type + '<div class="ke-dialog-row"">' + + '<label for="keType" style="width:60px;">' + lang.linkType + '</label>' + + '<select id="keType" name="type"></select>' + + '</div>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + self.exec('createlink', url, typeBox.val()).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('input[name="url"]', div), + typeBox = K('select[name="type"]', div); + urlBox.val('http://'); + typeBox[0].options[0] = new Option(lang.newWindow, '_blank'); + typeBox[0].options[1] = new Option(lang.selfWindow, ''); + self.cmd.selection(); + var a = self.plugin.getSelectedLink(); + if (a) { + self.cmd.range.selectNode(a[0]); + self.cmd.select(); + urlBox.val(a.attr('data-ke-src')); + typeBox.val(a.attr('target')); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.exec('unlink', null); + } + }; + self.clickToolbar(name, self.plugin.link.edit); +}); diff --git a/static/plugins/kindeditor/plugins/map/map.html b/static/plugins/kindeditor/plugins/map/map.html new file mode 100755 index 0000000..033b60b --- /dev/null +++ b/static/plugins/kindeditor/plugins/map/map.html @@ -0,0 +1,57 @@ +<!doctype html> +<html> + <head> + <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> + <style> + html { height: 100% } + body { height: 100%; margin: 0; padding: 0; background-color: #FFF } + #map_canvas { height: 100% } + </style> + <script src="http://maps.googleapis.com/maps/api/js?sensor=false&language=zh_CN"></script> + <script> + var map, geocoder; + function initialize() { + var latlng = new google.maps.LatLng(-34.397, 150.644); + var options = { + zoom: 11, + center: latlng, + disableDefaultUI: true, + panControl: true, + zoomControl: true, + mapTypeControl: true, + scaleControl: true, + streetViewControl: false, + overviewMapControl: true, + mapTypeId: google.maps.MapTypeId.ROADMAP + }; + map = new google.maps.Map(document.getElementById("map_canvas"), options); + geocoder = new google.maps.Geocoder(); + geocoder.geocode({latLng: latlng}, function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + if (results[3]) { + parent.document.getElementById("kindeditor_plugin_map_address").value = results[3].formatted_address; + } + } + }); + } + function search(address) { + if (!map) return; + geocoder.geocode({address : address}, function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + map.setZoom(11); + map.setCenter(results[0].geometry.location); + var marker = new google.maps.Marker({ + map: map, + position: results[0].geometry.location + }); + } else { + alert("Invalid address: " + address); + } + }); + } + </script> + </head> + <body onload="initialize();"> + <div id="map_canvas" style="width:100%; height:100%"></div> + </body> +</html> \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/map/map.js b/static/plugins/kindeditor/plugins/map/map.js new file mode 100755 index 0000000..38521cf --- /dev/null +++ b/static/plugins/kindeditor/plugins/map/map.js @@ -0,0 +1,137 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +// Google Maps: http://code.google.com/apis/maps/index.html + +KindEditor.plugin('map', function(K) { + var self = this, name = 'map', lang = self.lang(name + '.'); + self.clickToolbar(name, function() { + var html = ['<div style="padding:10px 20px;">', + '<div class="ke-dialog-row">', + lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />', + '</span>', + '</div>', + '<div class="ke-map" style="width:558px;height:360px;"></div>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 600, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var geocoder = win.geocoder, + map = win.map, + center = map.getCenter().lat() + ',' + map.getCenter().lng(), + zoom = map.getZoom(), + maptype = map.getMapTypeId(), + url = 'http://maps.googleapis.com/maps/api/staticmap'; + url += '?center=' + encodeURIComponent(center); + url += '&zoom=' + encodeURIComponent(zoom); + url += '&size=558x360'; + url += '&maptype=' + encodeURIComponent(maptype); + url += '&markers=' + encodeURIComponent(center); + url += '&language=' + self.langType; + url += '&sensor=false'; + self.exec('insertimage', url).hideDialog().focus(); + } + }, + beforeRemove : function() { + searchBtn.remove(); + if (doc) { + doc.write(''); + } + iframe.remove(); + } + }); + var div = dialog.div, + addressBox = K('[name="address"]', div), + searchBtn = K('[name="searchBtn"]', div), + win, doc; + var iframeHtml = ['<!doctype html><html><head>', + '<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />', + '<style>', + ' html { height: 100% }', + ' body { height: 100%; margin: 0; padding: 0; background-color: #FFF }', + ' #map_canvas { height: 100% }', + '</style>', + '<script src="http://maps.googleapis.com/maps/api/js?sensor=false&language=' + self.langType + '"></script>', + '<script>', + 'var map, geocoder;', + 'function initialize() {', + ' var latlng = new google.maps.LatLng(31.230393, 121.473704);', + ' var options = {', + ' zoom: 11,', + ' center: latlng,', + ' disableDefaultUI: true,', + ' panControl: true,', + ' zoomControl: true,', + ' mapTypeControl: true,', + ' scaleControl: true,', + ' streetViewControl: false,', + ' overviewMapControl: true,', + ' mapTypeId: google.maps.MapTypeId.ROADMAP', + ' };', + ' map = new google.maps.Map(document.getElementById("map_canvas"), options);', + ' geocoder = new google.maps.Geocoder();', + ' geocoder.geocode({latLng: latlng}, function(results, status) {', + ' if (status == google.maps.GeocoderStatus.OK) {', + ' if (results[3]) {', + ' parent.document.getElementById("kindeditor_plugin_map_address").value = results[3].formatted_address;', + ' }', + ' }', + ' });', + '}', + 'function search(address) {', + ' if (!map) return;', + ' geocoder.geocode({address : address}, function(results, status) {', + ' if (status == google.maps.GeocoderStatus.OK) {', + ' map.setZoom(11);', + ' map.setCenter(results[0].geometry.location);', + ' var marker = new google.maps.Marker({', + ' map: map,', + ' position: results[0].geometry.location', + ' });', + ' } else {', + ' alert("Invalid address: " + address);', + ' }', + ' });', + '}', + '</script>', + '</head>', + '<body onload="initialize();">', + '<div id="map_canvas" style="width:100%; height:100%"></div>', + '</body></html>'].join('\n'); + // TODO:用doc.write(iframeHtml)方式加载时,在IE6上第一次加载报错,暂时使用src方式 + var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'map/map.html" style="width:558px;height:360px;"></iframe>'); + function ready() { + win = iframe[0].contentWindow; + doc = K.iframeDoc(iframe); + //doc.open(); + //doc.write(iframeHtml); + //doc.close(); + } + iframe.bind('load', function() { + iframe.unbind('load'); + if (K.IE) { + ready(); + } else { + setTimeout(ready, 0); + } + }); + K('.ke-map', div).replaceWith(iframe); + // search map + searchBtn.click(function() { + win.search(addressBox.val()); + }); + }); +}); diff --git a/static/plugins/kindeditor/plugins/media/media.js b/static/plugins/kindeditor/plugins/media/media.js new file mode 100755 index 0000000..ef1887e --- /dev/null +++ b/static/plugins/kindeditor/plugins/media/media.js @@ -0,0 +1,170 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('media', function(K) { + var self = this, name = 'media', lang = self.lang(name + '.'), + allowMediaUpload = K.undef(self.allowMediaUpload, true), + allowFileManager = K.undef(self.allowFileManager, false), + formatUploadUrl = K.undef(self.formatUploadUrl, true), + extraParams = K.undef(self.extraFileUploadParams, {}), + filePostName = K.undef(self.filePostName, 'imgFile'), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'); + self.plugin.media = { + edit : function() { + var html = [ + '<div style="padding:20px;">', + //url + '<div class="ke-dialog-row">', + '<label for="keUrl" style="width:60px;">' + lang.url + '</label>', + '<input class="ke-input-text" type="text" id="keUrl" name="url" value="" style="width:160px;" /> &nbsp;', + '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', + '<span class="ke-button-common ke-button-outer">', + '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', + '</span>', + '</div>', + //width + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:60px;">' + lang.width + '</label>', + '<input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="550" maxlength="4" />', + '</div>', + //height + '<div class="ke-dialog-row">', + '<label for="keHeight" style="width:60px;">' + lang.height + '</label>', + '<input type="text" id="keHeight" class="ke-input-text ke-input-number" name="height" value="400" maxlength="4" />', + '</div>', + //autostart + '<div class="ke-dialog-row">', + '<label for="keAutostart">' + lang.autostart + '</label>', + '<input type="checkbox" id="keAutostart" name="autostart" value="" /> ', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 450, + height : 230, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var url = K.trim(urlBox.val()), + width = widthBox.val(), + height = heightBox.val(); + if (url == 'http://' || K.invalidUrl(url)) { + alert(self.lang('invalidUrl')); + urlBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + var html = K.mediaImg(self.themesPath + 'common/blank.gif', { + src : url, + type : K.mediaType(url), + width : width, + height : height, + autostart : autostartBox[0].checked ? 'true' : 'false', + loop : 'true' + }); + self.insertHtml(html).hideDialog().focus(); + } + } + }), + div = dialog.div, + urlBox = K('[name="url"]', div), + viewServerBtn = K('[name="viewServer"]', div), + widthBox = K('[name="width"]', div), + heightBox = K('[name="height"]', div), + autostartBox = K('[name="autostart"]', div); + urlBox.val('http://'); + + if (allowMediaUpload) { + var uploadbutton = K.uploadbutton({ + button : K('.ke-upload-button', div)[0], + fieldName : filePostName, + extraParams : extraParams, + url : K.addParam(uploadJson, 'dir=media'), + afterUpload : function(data) { + dialog.hideLoading(); + if (data.error === 0) { + var url = data.url; + if (formatUploadUrl) { + url = K.formatUrl(url, 'absolute'); + } + urlBox.val(url); + if (self.afterUpload) { + self.afterUpload.call(self, url, data, name); + } + alert(self.lang('uploadSuccess')); + } else { + alert(data.message); + } + }, + afterError : function(html) { + dialog.hideLoading(); + self.errorDialog(html); + } + }); + uploadbutton.fileBox.change(function(e) { + dialog.showLoading(self.lang('uploadLoading')); + uploadbutton.submit(); + }); + } else { + K('.ke-upload-button', div).hide(); + } + + if (allowFileManager) { + viewServerBtn.click(function(e) { + self.loadPlugin('filemanager', function() { + self.plugin.filemanagerDialog({ + viewType : 'LIST', + dirName : 'media', + clickFn : function(url, title) { + if (self.dialogs.length > 1) { + K('[name="url"]', div).val(url); + if (self.afterSelectFile) { + self.afterSelectFile.call(self, url); + } + self.hideDialog(); + } + } + }); + }); + }); + } else { + viewServerBtn.hide(); + } + + var img = self.plugin.getSelectedMedia(); + if (img) { + var attrs = K.mediaAttrs(img.attr('data-ke-tag')); + urlBox.val(attrs.src); + widthBox.val(K.removeUnit(img.css('width')) || attrs.width || 0); + heightBox.val(K.removeUnit(img.css('height')) || attrs.height || 0); + autostartBox[0].checked = (attrs.autostart === 'true'); + } + urlBox[0].focus(); + urlBox[0].select(); + }, + 'delete' : function() { + self.plugin.getSelectedMedia().remove(); + // [IE] 删除图片后立即点击图片按钮出错 + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.media.edit); +}); diff --git a/static/plugins/kindeditor/plugins/multiimage/images/image.png b/static/plugins/kindeditor/plugins/multiimage/images/image.png new file mode 100755 index 0000000..fe79cf0 Binary files /dev/null and b/static/plugins/kindeditor/plugins/multiimage/images/image.png differ diff --git a/static/plugins/kindeditor/plugins/multiimage/images/select-files-en.png b/static/plugins/kindeditor/plugins/multiimage/images/select-files-en.png new file mode 100755 index 0000000..a926a6e Binary files /dev/null and b/static/plugins/kindeditor/plugins/multiimage/images/select-files-en.png differ diff --git a/static/plugins/kindeditor/plugins/multiimage/images/select-files-zh-CN.png b/static/plugins/kindeditor/plugins/multiimage/images/select-files-zh-CN.png new file mode 100755 index 0000000..5a31d36 Binary files /dev/null and b/static/plugins/kindeditor/plugins/multiimage/images/select-files-zh-CN.png differ diff --git a/static/plugins/kindeditor/plugins/multiimage/images/swfupload.swf b/static/plugins/kindeditor/plugins/multiimage/images/swfupload.swf new file mode 100755 index 0000000..e3f7670 Binary files /dev/null and b/static/plugins/kindeditor/plugins/multiimage/images/swfupload.swf differ diff --git a/static/plugins/kindeditor/plugins/multiimage/multiimage.js b/static/plugins/kindeditor/plugins/multiimage/multiimage.js new file mode 100755 index 0000000..bb629c8 --- /dev/null +++ b/static/plugins/kindeditor/plugins/multiimage/multiimage.js @@ -0,0 +1,1384 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + + +(function(K) { + +function KSWFUpload(options) { + this.init(options); +} +K.extend(KSWFUpload, { + init : function(options) { + var self = this; + options.afterError = options.afterError || function(str) { + alert(str); + }; + self.options = options; + self.progressbars = {}; + // template + self.div = K(options.container).html([ + '<div class="ke-swfupload">', + '<div class="ke-swfupload-top">', + '<div class="ke-inline-block ke-swfupload-button">', + '<input type="button" value="Browse" />', + '</div>', + '<div class="ke-inline-block ke-swfupload-desc">' + options.uploadDesc + '</div>', + '<span class="ke-button-common ke-button-outer ke-swfupload-startupload">', + '<input type="button" class="ke-button-common ke-button" value="' + options.startButtonValue + '" />', + '</span>', + '</div>', + '<div class="ke-swfupload-body"></div>', + '</div>' + ].join('')); + self.bodyDiv = K('.ke-swfupload-body', self.div); + + function showError(itemDiv, msg) { + K('.ke-status > div', itemDiv).hide(); + K('.ke-message', itemDiv).addClass('ke-error').show().html(K.escape(msg)); + } + + var settings = { + debug : false, + upload_url : options.uploadUrl, + flash_url : options.flashUrl, + file_post_name : options.filePostName, + button_placeholder : K('.ke-swfupload-button > input', self.div)[0], + button_image_url: options.buttonImageUrl, + button_width: options.buttonWidth, + button_height: options.buttonHeight, + button_cursor : SWFUpload.CURSOR.HAND, + file_types : options.fileTypes, + file_types_description : options.fileTypesDesc, + file_upload_limit : options.fileUploadLimit, + file_size_limit : options.fileSizeLimit, + post_params : options.postParams, + file_queued_handler : function(file) { + file.url = self.options.fileIconUrl; + self.appendFile(file); + }, + file_queue_error_handler : function(file, errorCode, message) { + var errorName = ''; + switch (errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED: + errorName = options.queueLimitExceeded; + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + errorName = options.fileExceedsSizeLimit; + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + errorName = options.zeroByteFile; + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + errorName = options.invalidFiletype; + break; + default: + errorName = options.unknownError; + break; + } + K.DEBUG && alert(errorName); + }, + upload_start_handler : function(file) { + var self = this; + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv); + K('.ke-status > div', itemDiv).hide(); + K('.ke-progressbar', itemDiv).show(); + }, + upload_progress_handler : function(file, bytesLoaded, bytesTotal) { + var percent = Math.round(bytesLoaded * 100 / bytesTotal); + var progressbar = self.progressbars[file.id]; + progressbar.bar.css('width', Math.round(percent * 80 / 100) + 'px'); + progressbar.percent.html(percent + '%'); + }, + upload_error_handler : function(file, errorCode, message) { + if (file && file.filestatus == SWFUpload.FILE_STATUS.ERROR) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + showError(itemDiv, self.options.errorMessage); + } + }, + upload_success_handler : function(file, serverData) { + var itemDiv = K('div[data-id="' + file.id + '"]', self.bodyDiv).eq(0); + var data = {}; + try { + data = K.json(serverData); + } catch (e) { + self.options.afterError.call(this, '<!doctype html><html>' + serverData + '</html>'); + } + if (data.error !== 0) { + showError(itemDiv, K.DEBUG ? data.message : self.options.errorMessage); + return; + } + file.url = data.url; + K('.ke-img', itemDiv).attr('src', file.url).attr('data-status', file.filestatus).data('data', data); + K('.ke-status > div', itemDiv).hide(); + } + }; + self.swfu = new SWFUpload(settings); + + K('.ke-swfupload-startupload input', self.div).click(function() { + self.swfu.startUpload(); + }); + }, + getUrlList : function() { + var list = []; + K('.ke-img', self.bodyDiv).each(function() { + var img = K(this); + var status = img.attr('data-status'); + if (status == SWFUpload.FILE_STATUS.COMPLETE) { + list.push(img.data('data')); + } + }); + return list; + }, + removeFile : function(fileId) { + var self = this; + self.swfu.cancelUpload(fileId); + var itemDiv = K('div[data-id="' + fileId + '"]', self.bodyDiv); + K('.ke-photo', itemDiv).unbind(); + K('.ke-delete', itemDiv).unbind(); + itemDiv.remove(); + }, + removeFiles : function() { + var self = this; + K('.ke-item', self.bodyDiv).each(function() { + self.removeFile(K(this).attr('data-id')); + }); + }, + appendFile : function(file) { + var self = this; + var itemDiv = K('<div class="ke-inline-block ke-item" data-id="' + file.id + '"></div>'); + self.bodyDiv.append(itemDiv); + var photoDiv = K('<div class="ke-inline-block ke-photo"></div>') + .mouseover(function(e) { + K(this).addClass('ke-on'); + }) + .mouseout(function(e) { + K(this).removeClass('ke-on'); + }); + itemDiv.append(photoDiv); + + var img = K('<img src="' + file.url + '" class="ke-img" data-status="' + file.filestatus + '" width="80" height="80" alt="' + file.name + '" />'); + photoDiv.append(img); + K('<span class="ke-delete"></span>').appendTo(photoDiv).click(function() { + self.removeFile(file.id); + }); + var statusDiv = K('<div class="ke-status"></div>').appendTo(photoDiv); + // progressbar + K(['<div class="ke-progressbar">', + '<div class="ke-progressbar-bar"><div class="ke-progressbar-bar-inner"></div></div>', + '<div class="ke-progressbar-percent">0%</div></div>'].join('')).hide().appendTo(statusDiv); + // message + K('<div class="ke-message">' + self.options.pendingMessage + '</div>').appendTo(statusDiv); + + itemDiv.append('<div class="ke-name">' + file.name + '</div>'); + + self.progressbars[file.id] = { + bar : K('.ke-progressbar-bar-inner', photoDiv), + percent : K('.ke-progressbar-percent', photoDiv) + }; + }, + remove : function() { + this.removeFiles(); + this.swfu.destroy(); + this.div.html(''); + } +}); + +K.swfupload = function(element, options) { + return new KSWFUpload(element, options); +}; + +})(KindEditor); + +KindEditor.plugin('multiimage', function(K) { + var self = this, name = 'multiimage', + formatUploadUrl = K.undef(self.formatUploadUrl, true), + uploadJson = K.undef(self.uploadJson, self.basePath + 'php/upload_json.php'), + imgPath = self.pluginsPath + 'multiimage/images/', + imageSizeLimit = K.undef(self.imageSizeLimit, '1MB'), + imageFileTypes = K.undef(self.imageFileTypes, '*.jpg;*.gif;*.png'), + imageUploadLimit = K.undef(self.imageUploadLimit, 20), + filePostName = K.undef(self.filePostName, 'imgFile'), + lang = self.lang(name + '.'); + + self.plugin.multiImageDialog = function(options) { + var clickFn = options.clickFn, + uploadDesc = K.tmpl(lang.uploadDesc, {uploadLimit : imageUploadLimit, sizeLimit : imageSizeLimit}); + var html = [ + '<div style="padding:20px;">', + '<div class="swfupload">', + '</div>', + '</div>' + ].join(''); + var dialog = self.createDialog({ + name : name, + width : 650, + height : 510, + title : self.lang(name), + body : html, + previewBtn : { + name : lang.insertAll, + click : function(e) { + clickFn.call(self, swfupload.getUrlList()); + } + }, + yesBtn : { + name : lang.clearAll, + click : function(e) { + swfupload.removeFiles(); + } + }, + beforeRemove : function() { + // IE9 bugfix: https://github.com/kindsoft/kindeditor/issues/72 + if (!K.IE || K.V <= 8) { + swfupload.remove(); + } + } + }), + div = dialog.div; + + var swfupload = K.swfupload({ + container : K('.swfupload', div), + buttonImageUrl : imgPath + (self.langType == 'zh-CN' ? 'select-files-zh-CN.png' : 'select-files-en.png'), + buttonWidth : self.langType == 'zh-CN' ? 72 : 88, + buttonHeight : 23, + fileIconUrl : imgPath + 'image.png', + uploadDesc : uploadDesc, + startButtonValue : lang.startUpload, + uploadUrl : K.addParam(uploadJson, 'dir=image'), + flashUrl : imgPath + 'swfupload.swf', + filePostName : filePostName, + fileTypes : '*.jpg;*.jpeg;*.gif;*.png;*.bmp', + fileTypesDesc : 'Image Files', + fileUploadLimit : imageUploadLimit, + fileSizeLimit : imageSizeLimit, + postParams : K.undef(self.extraFileUploadParams, {}), + queueLimitExceeded : lang.queueLimitExceeded, + fileExceedsSizeLimit : lang.fileExceedsSizeLimit, + zeroByteFile : lang.zeroByteFile, + invalidFiletype : lang.invalidFiletype, + unknownError : lang.unknownError, + pendingMessage : lang.pending, + errorMessage : lang.uploadError, + afterError : function(html) { + self.errorDialog(html); + } + }); + + return dialog; + }; + self.clickToolbar(name, function() { + self.plugin.multiImageDialog({ + clickFn : function (urlList) { + if (urlList.length === 0) { + return; + } + K.each(urlList, function(i, data) { + if (self.afterUpload) { + self.afterUpload.call(self, data.url, data, 'multiimage'); + } + self.exec('insertimage', data.url, data.title, data.width, data.height, data.border, data.align); + }); + // Bugfix: [Firefox] 上传图片后,总是出现正在加载的样式,需要延迟执行hideDialog + setTimeout(function() { + self.hideDialog().focus(); + }, 0); + } + }); + }); +}); + + +/** + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + * + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz閚 and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ + +(function() { + +window.SWFUpload = function (settings) { + this.initSWFUpload(settings); +}; + +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = settings; + this.eventQueue = []; + this.movieName = "KindEditor_SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 2009-03-25"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; + +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return /*currentURL +*/ path + url; + +}; + + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // Upload backend settings + this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + + this.ensureDefault("debug_handler", this.debugMessage); + + this.ensureDefault("custom_settings", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + + if (!this.settings.preserve_relative_urls) { + //this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + + delete this.ensureDefault; +}; + +// Private: loadFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + + // Append the container and load the flash + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + // Fix bug for IE9 + // http://www.kindsoft.net/view.php?bbsid=7&postid=5825&pagenum=1 + var classid = ''; + if (KindEditor.IE && KindEditor.V > 8) { + classid = ' classid = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'; + } + return ['<object id="', this.movieName, '"' + classid + ' type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">', + '<param name="wmode" value="', this.settings.button_window_mode, '" />', + '<param name="movie" value="', this.settings.flash_url, '" />', + '<param name="quality" value="high" />', + '<param name="menu" value="false" />', + '<param name="allowScriptAccess" value="always" />', + '<param name="flashvars" value="' + this.getFlashVars() + '" />', + '</object>'].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + + // Build the parameter string + return ["movieName=", encodeURIComponent(this.movieName), + "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url), + "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&amp;httpSuccess=", encodeURIComponent(httpSuccessString), + "&amp;assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&amp;params=", encodeURIComponent(paramString), + "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name), + "&amp;fileTypes=", encodeURIComponent(this.settings.file_types), + "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&amp;buttonWidth=", encodeURIComponent(this.settings.button_width), + "&amp;buttonHeight=", encodeURIComponent(this.settings.button_height), + "&amp;buttonText=", encodeURIComponent(this.settings.button_text), + "&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&amp;buttonAction=", encodeURIComponent(this.settings.button_action), + "&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&amp;buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; + +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + + return this.movieElement; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&amp;name=value" +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&amp;"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen +SWFUpload.prototype.destroy = function () { + try { + // Make sure Flash is done before we try to remove it + this.cancelUpload(null, false); + + + // Remove the SWFUpload DOM nodes + var movieElement = null; + movieElement = this.getMovieElement(); + + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + + + return true; + } catch (ex2) { + return false; + } +}; + + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + + var movieElement = this.getMovieElement(); + var returnValue, returnString; + + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>'); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; +}; + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + var self = this; + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + + this.cleanUp(movieElement); + + this.queueEvent("swfupload_loaded_handler"); +}; + +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; + +})(); + +(function() { +/* + Queue Plug-in + + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + + */ + +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.queueSettings = {}; + + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; + } else { + continueUpload = true; + } + + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} + +})(); diff --git a/static/plugins/kindeditor/plugins/pagebreak/pagebreak.js b/static/plugins/kindeditor/plugins/pagebreak/pagebreak.js new file mode 100755 index 0000000..3898e32 --- /dev/null +++ b/static/plugins/kindeditor/plugins/pagebreak/pagebreak.js @@ -0,0 +1,27 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('pagebreak', function(K) { + var self = this; + var name = 'pagebreak'; + var pagebreakHtml = K.undef(self.pagebreakHtml, '<hr style="page-break-after: always;" class="ke-pagebreak" />'); + + self.clickToolbar(name, function() { + var cmd = self.cmd, range = cmd.range; + self.focus(); + var tail = self.newlineTag == 'br' || K.WEBKIT ? '' : '<span id="__kindeditor_tail_tag__"></span>'; + self.insertHtml(pagebreakHtml + tail); + if (tail !== '') { + var p = K('#__kindeditor_tail_tag__', self.edit.doc); + range.selectNodeContents(p[0]); + p.removeAttr('id'); + cmd.select(); + } + }); +}); diff --git a/static/plugins/kindeditor/plugins/plainpaste/plainpaste.js b/static/plugins/kindeditor/plugins/plainpaste/plainpaste.js new file mode 100755 index 0000000..1faec86 --- /dev/null +++ b/static/plugins/kindeditor/plugins/plainpaste/plainpaste.js @@ -0,0 +1,41 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('plainpaste', function(K) { + var self = this, name = 'plainpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<div style="margin-bottom:10px;">' + lang.comment + '</div>' + + '<textarea class="ke-textarea" style="width:408px;height:260px;"></textarea>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var html = textarea.val(); + html = K.escape(html); + html = html.replace(/ {2}/g, ' &nbsp;'); + if (self.newlineTag == 'p') { + html = html.replace(/^/, '<p>').replace(/$/, '</p>').replace(/\n/g, '</p><p>'); + } else { + html = html.replace(/\n/g, '<br />$&'); + } + self.insertHtml(html).hideDialog().focus(); + } + } + }), + textarea = K('textarea', dialog.div); + textarea[0].focus(); + }); +}); diff --git a/static/plugins/kindeditor/plugins/preview/preview.js b/static/plugins/kindeditor/plugins/preview/preview.js new file mode 100755 index 0000000..3bbb7b5 --- /dev/null +++ b/static/plugins/kindeditor/plugins/preview/preview.js @@ -0,0 +1,31 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('preview', function(K) { + var self = this, name = 'preview', undefined; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<iframe class="ke-textarea" frameborder="0" style="width:708px;height:400px;"></iframe>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 750, + title : self.lang(name), + body : html + }), + iframe = K('iframe', dialog.div), + doc = K.iframeDoc(iframe); + doc.open(); + doc.write(self.fullHtml()); + doc.close(); + K(doc.body).css('background-color', '#FFF'); + iframe[0].contentWindow.focus(); + }); +}); diff --git a/static/plugins/kindeditor/plugins/quickformat/quickformat.js b/static/plugins/kindeditor/plugins/quickformat/quickformat.js new file mode 100755 index 0000000..a7af1e5 --- /dev/null +++ b/static/plugins/kindeditor/plugins/quickformat/quickformat.js @@ -0,0 +1,81 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('quickformat', function(K) { + var self = this, name = 'quickformat', + blockMap = K.toMap('blockquote,center,div,h1,h2,h3,h4,h5,h6,p'); + function getFirstChild(knode) { + var child = knode.first(); + while (child && child.first()) { + child = child.first(); + } + return child; + } + self.clickToolbar(name, function() { + self.focus(); + var doc = self.edit.doc, + range = self.cmd.range, + child = K(doc.body).first(), next, + nodeList = [], subList = [], + bookmark = range.createBookmark(true); + while(child) { + next = child.next(); + var firstChild = getFirstChild(child); + if (!firstChild || firstChild.name != 'img') { + if (blockMap[child.name]) { + child.html(child.html().replace(/^(\s|&nbsp;| )+/ig, '')); + child.css('text-indent', '2em'); + } else { + subList.push(child); + } + if (!next || (blockMap[next.name] || blockMap[child.name] && !blockMap[next.name])) { + if (subList.length > 0) { + nodeList.push(subList); + } + subList = []; + } + } + child = next; + } + K.each(nodeList, function(i, subList) { + var wrapper = K('<p style="text-indent:2em;"></p>', doc); + subList[0].before(wrapper); + K.each(subList, function(i, knode) { + wrapper.append(knode); + }); + }); + range.moveToBookmark(bookmark); + self.addBookmark(); + }); +}); + +/** +-------------------------- +abcd<br /> +1234<br /> + +to + +<p style="text-indent:2em;"> + abcd<br /> + 1234<br /> +</p> + +-------------------------- + +&nbsp; abcd<img>1233 +<p>1234</p> + +to + +<p style="text-indent:2em;">abcd<img>1233</p> +<p style="text-indent:2em;">1234</p> + +-------------------------- +*/ \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/table/table.js b/static/plugins/kindeditor/plugins/table/table.js new file mode 100755 index 0000000..d3f1232 --- /dev/null +++ b/static/plugins/kindeditor/plugins/table/table.js @@ -0,0 +1,712 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('table', function(K) { + var self = this, name = 'table', lang = self.lang(name + '.'), zeroborder = 'ke-zeroborder'; + // 设置颜色 + function _setColor(box, color) { + color = color.toUpperCase(); + box.css('background-color', color); + box.css('color', color === '#000000' ? '#FFFFFF' : '#000000'); + box.html(color); + } + // 初始化取色器 + var pickerList = []; + function _initColorPicker(dialogDiv, colorBox) { + colorBox.bind('click,mousedown', function(e){ + e.stopPropagation(); + }); + function removePicker() { + K.each(pickerList, function() { + this.remove(); + }); + pickerList = []; + K(document).unbind('click,mousedown', removePicker); + dialogDiv.unbind('click,mousedown', removePicker); + } + colorBox.click(function(e) { + removePicker(); + var box = K(this), + pos = box.pos(); + var picker = K.colorpicker({ + x : pos.x, + y : pos.y + box.height(), + z : 811214, + selectedColor : K(this).html(), + colors : self.colorTable, + noColor : self.lang('noColor'), + shadowMode : self.shadowMode, + click : function(color) { + _setColor(box, color); + removePicker(); + } + }); + pickerList.push(picker); + K(document).bind('click,mousedown', removePicker); + dialogDiv.bind('click,mousedown', removePicker); + }); + } + // 取得下一行cell的index + function _getCellIndex(table, row, cell) { + var rowSpanCount = 0; + for (var i = 0, len = row.cells.length; i < len; i++) { + if (row.cells[i] == cell) { + break; + } + rowSpanCount += row.cells[i].rowSpan - 1; + } + return cell.cellIndex - rowSpanCount; + } + self.plugin.table = { + //insert or modify table + prop : function(isInsert) { + var html = [ + '<div style="padding:20px;">', + //rows, cols + '<div class="ke-dialog-row">', + '<label for="keRows" style="width:90px;">' + lang.cells + '</label>', + lang.rows + ' <input type="text" id="keRows" class="ke-input-text ke-input-number" name="rows" value="" maxlength="4" /> &nbsp; ', + lang.cols + ' <input type="text" class="ke-input-text ke-input-number" name="cols" value="" maxlength="4" />', + '</div>', + //width, height + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:90px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ', + '<select name="widthType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select> &nbsp; ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ', + '<select name="heightType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select>', + '</div>', + //space, padding + '<div class="ke-dialog-row">', + '<label for="kePadding" style="width:90px;">' + lang.space + '</label>', + lang.padding + ' <input type="text" id="kePadding" class="ke-input-text ke-input-number" name="padding" value="" maxlength="4" /> &nbsp; ', + lang.spacing + ' <input type="text" class="ke-input-text ke-input-number" name="spacing" value="" maxlength="4" />', + '</div>', + //align + '<div class="ke-dialog-row">', + '<label for="keAlign" style="width:90px;">' + lang.align + '</label>', + '<select id="keAlign" name="align">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="left">' + lang.alignLeft + '</option>', + '<option value="center">' + lang.alignCenter + '</option>', + '<option value="right">' + lang.alignRight + '</option>', + '</select>', + '</div>', + //border + '<div class="ke-dialog-row">', + '<label for="keBorder" style="width:90px;">' + lang.border + '</label>', + lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ', + lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>', + '</div>', + //background color + '<div class="ke-dialog-row">', + '<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>', + '<span class="ke-inline-block ke-input-color"></span>', + '</div>', + '</div>' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var rows = rowsBox.val(), + cols = colsBox.val(), + width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + align = alignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (rows == 0 || !/^\d+$/.test(rows)) { + alert(self.lang('invalidRows')); + rowsBox[0].focus(); + return; + } + if (cols == 0 || !/^\d+$/.test(cols)) { + alert(self.lang('invalidRows')); + colsBox[0].focus(); + return; + } + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(padding)) { + alert(self.lang('invalidPadding')); + paddingBox[0].focus(); + return; + } + if (!/^\d*$/.test(spacing)) { + alert(self.lang('invalidSpacing')); + spacingBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + //modify table + if (table) { + if (width !== '') { + table.width(width + widthType); + } else { + table.css('width', ''); + } + if (table[0].width !== undefined) { + table.removeAttr('width'); + } + if (height !== '') { + table.height(height + heightType); + } else { + table.css('height', ''); + } + if (table[0].height !== undefined) { + table.removeAttr('height'); + } + table.css('background-color', bgColor); + if (table[0].bgColor !== undefined) { + table.removeAttr('bgColor'); + } + if (padding !== '') { + table[0].cellPadding = padding; + } else { + table.removeAttr('cellPadding'); + } + if (spacing !== '') { + table[0].cellSpacing = spacing; + } else { + table.removeAttr('cellSpacing'); + } + if (align !== '') { + table[0].align = align; + } else { + table.removeAttr('align'); + } + if (border !== '') { + table.attr('border', border); + } else { + table.removeAttr('border'); + } + if (border === '' || border === '0') { + table.addClass(zeroborder); + } else { + table.removeClass(zeroborder); + } + if (borderColor !== '') { + table.attr('borderColor', borderColor); + } else { + table.removeAttr('borderColor'); + } + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + return; + } + //insert new table + var style = ''; + if (width !== '') { + style += 'width:' + width + widthType + ';'; + } + if (height !== '') { + style += 'height:' + height + heightType + ';'; + } + if (bgColor !== '') { + style += 'background-color:' + bgColor + ';'; + } + var html = '<table'; + if (style !== '') { + html += ' style="' + style + '"'; + } + if (padding !== '') { + html += ' cellpadding="' + padding + '"'; + } + if (spacing !== '') { + html += ' cellspacing="' + spacing + '"'; + } + if (align !== '') { + html += ' align="' + align + '"'; + } + if (border !== '') { + html += ' border="' + border + '"'; + } + if (border === '' || border === '0') { + html += ' class="' + zeroborder + '"'; + } + if (borderColor !== '') { + html += ' bordercolor="' + borderColor + '"'; + } + html += '>'; + for (var i = 0; i < rows; i++) { + html += '<tr>'; + for (var j = 0; j < cols; j++) { + html += '<td>' + (K.IE ? '&nbsp;' : '<br />') + '</td>'; + } + html += '</tr>'; + } + html += '</table>'; + if (!K.IE) { + html += '<br />'; + } + self.insertHtml(html); + self.select().hideDialog().focus(); + self.addBookmark(); + } + } + }), + div = dialog.div, + rowsBox = K('[name="rows"]', div).val(3), + colsBox = K('[name="cols"]', div).val(2), + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + alignBox = K('[name="align"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + // foucs and select + rowsBox[0].focus(); + rowsBox[0].select(); + var table; + if (isInsert) { + return; + } + //get selected table node + table = self.plugin.getSelectedTable(); + if (table) { + rowsBox.val(table[0].rows.length); + colsBox.val(table[0].rows.length > 0 ? table[0].rows[0].cells.length : 0); + rowsBox.attr('disabled', true); + colsBox.attr('disabled', true); + var match, + tableWidth = table[0].style.width || table[0].width, + tableHeight = table[0].style.height || table[0].height; + if (tableWidth !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if (tableHeight !== undefined && (match = /^(\d+)((?:px|%)*)$/.exec(tableHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + paddingBox.val(table[0].cellPadding || ''); + spacingBox.val(table[0].cellSpacing || ''); + alignBox.val(table[0].align || ''); + borderBox.val(table[0].border === undefined ? '' : table[0].border); + _setColor(colorBox.eq(0), K.toHex(table.attr('borderColor') || '')); + _setColor(colorBox.eq(1), K.toHex(table[0].style.backgroundColor || table[0].bgColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + } + }, + //modify cell + cellprop : function() { + var html = [ + '<div style="padding:20px;">', + //width, height + '<div class="ke-dialog-row">', + '<label for="keWidth" style="width:90px;">' + lang.size + '</label>', + lang.width + ' <input type="text" id="keWidth" class="ke-input-text ke-input-number" name="width" value="" maxlength="4" /> &nbsp; ', + '<select name="widthType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select> &nbsp; ', + lang.height + ' <input type="text" class="ke-input-text ke-input-number" name="height" value="" maxlength="4" /> &nbsp; ', + '<select name="heightType">', + '<option value="%">' + lang.percent + '</option>', + '<option value="px">' + lang.px + '</option>', + '</select>', + '</div>', + //align + '<div class="ke-dialog-row">', + '<label for="keAlign" style="width:90px;">' + lang.align + '</label>', + lang.textAlign + ' <select id="keAlign" name="textAlign">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="left">' + lang.alignLeft + '</option>', + '<option value="center">' + lang.alignCenter + '</option>', + '<option value="right">' + lang.alignRight + '</option>', + '</select> ', + lang.verticalAlign + ' <select name="verticalAlign">', + '<option value="">' + lang.alignDefault + '</option>', + '<option value="top">' + lang.alignTop + '</option>', + '<option value="middle">' + lang.alignMiddle + '</option>', + '<option value="bottom">' + lang.alignBottom + '</option>', + '<option value="baseline">' + lang.alignBaseline + '</option>', + '</select>', + '</div>', + //border + '<div class="ke-dialog-row">', + '<label for="keBorder" style="width:90px;">' + lang.border + '</label>', + lang.borderWidth + ' <input type="text" id="keBorder" class="ke-input-text ke-input-number" name="border" value="" maxlength="4" /> &nbsp; ', + lang.borderColor + ' <span class="ke-inline-block ke-input-color"></span>', + '</div>', + //background color + '<div class="ke-dialog-row">', + '<label for="keBgColor" style="width:90px;">' + lang.backgroundColor + '</label>', + '<span class="ke-inline-block ke-input-color"></span>', + '</div>', + '</div>' + ].join(''); + var bookmark = self.cmd.range.createBookmark(); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang('tablecell'), + body : html, + beforeRemove : function() { + colorBox.unbind(); + }, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var width = widthBox.val(), + height = heightBox.val(), + widthType = widthTypeBox.val(), + heightType = heightTypeBox.val(), + padding = paddingBox.val(), + spacing = spacingBox.val(), + textAlign = textAlignBox.val(), + verticalAlign = verticalAlignBox.val(), + border = borderBox.val(), + borderColor = K(colorBox[0]).html() || '', + bgColor = K(colorBox[1]).html() || ''; + if (!/^\d*$/.test(width)) { + alert(self.lang('invalidWidth')); + widthBox[0].focus(); + return; + } + if (!/^\d*$/.test(height)) { + alert(self.lang('invalidHeight')); + heightBox[0].focus(); + return; + } + if (!/^\d*$/.test(border)) { + alert(self.lang('invalidBorder')); + borderBox[0].focus(); + return; + } + cell.css({ + width : width !== '' ? (width + widthType) : '', + height : height !== '' ? (height + heightType) : '', + 'background-color' : bgColor, + 'text-align' : textAlign, + 'vertical-align' : verticalAlign, + 'border-width' : border, + 'border-style' : border !== '' ? 'solid' : '', + 'border-color' : borderColor + }); + self.hideDialog().focus(); + self.cmd.range.moveToBookmark(bookmark); + self.cmd.select(); + self.addBookmark(); + } + } + }), + div = dialog.div, + widthBox = K('[name="width"]', div).val(100), + heightBox = K('[name="height"]', div), + widthTypeBox = K('[name="widthType"]', div), + heightTypeBox = K('[name="heightType"]', div), + paddingBox = K('[name="padding"]', div).val(2), + spacingBox = K('[name="spacing"]', div).val(0), + textAlignBox = K('[name="textAlign"]', div), + verticalAlignBox = K('[name="verticalAlign"]', div), + borderBox = K('[name="border"]', div).val(1), + colorBox = K('.ke-input-color', div); + _initColorPicker(div, colorBox.eq(0)); + _initColorPicker(div, colorBox.eq(1)); + _setColor(colorBox.eq(0), '#000000'); + _setColor(colorBox.eq(1), ''); + // foucs and select + widthBox[0].focus(); + widthBox[0].select(); + // get selected cell + var cell = self.plugin.getSelectedCell(); + var match, + cellWidth = cell[0].style.width || cell[0].width || '', + cellHeight = cell[0].style.height || cell[0].height || ''; + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellWidth))) { + widthBox.val(match[1]); + widthTypeBox.val(match[2]); + } else { + widthBox.val(''); + } + if ((match = /^(\d+)((?:px|%)*)$/.exec(cellHeight))) { + heightBox.val(match[1]); + heightTypeBox.val(match[2]); + } + textAlignBox.val(cell[0].style.textAlign || ''); + verticalAlignBox.val(cell[0].style.verticalAlign || ''); + var border = cell[0].style.borderWidth || ''; + if (border) { + border = parseInt(border); + } + borderBox.val(border); + _setColor(colorBox.eq(0), K.toHex(cell[0].style.borderColor || '')); + _setColor(colorBox.eq(1), K.toHex(cell[0].style.backgroundColor || '')); + widthBox[0].focus(); + widthBox[0].select(); + }, + insert : function() { + this.prop(true); + }, + 'delete' : function() { + var table = self.plugin.getSelectedTable(); + self.cmd.range.setStartBefore(table[0]).collapse(true); + self.cmd.select(); + table.remove(); + self.addBookmark(); + }, + colinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex + offset; + // 取得第一行的index + index += table.rows[0].cells.length - row.cells.length; + + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.insertCell(index); + newCell.innerHTML = K.IE ? '' : '<br />'; + // 调整下一行的单元格index + index = _getCellIndex(table, newRow, newCell); + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colinsertleft : function() { + this.colinsert(0); + }, + colinsertright : function() { + this.colinsert(1); + }, + rowinsert : function(offset) { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0]; + var rowIndex = row.rowIndex; + if (offset === 1) { + rowIndex = row.rowIndex + (cell.rowSpan - 1) + offset; + } + var newRow = table.insertRow(rowIndex); + + for (var i = 0, len = row.cells.length; i < len; i++) { + // 调整cell个数 + if (row.cells[i].rowSpan > 1) { + len -= row.cells[i].rowSpan - 1; + } + var newCell = newRow.insertCell(i); + // copy colspan + if (offset === 1 && row.cells[i].colSpan > 1) { + newCell.colSpan = row.cells[i].colSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + } + // 调整rowspan + for (var j = rowIndex; j >= 0; j--) { + var cells = table.rows[j].cells; + if (cells.length > i) { + for (var k = cell.cellIndex; k >= 0; k--) { + if (cells[k].rowSpan > 1) { + cells[k].rowSpan += 1; + } + } + break; + } + } + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowinsertabove : function() { + this.rowinsert(0); + }, + rowinsertbelow : function() { + this.rowinsert(1); + }, + rowmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + nextRowIndex = rowIndex + cell.rowSpan, // 下一行的index + nextRow = table.rows[nextRowIndex]; // 下一行 + // 最后一行不能合并 + if (table.rows.length <= nextRowIndex) { + return; + } + var cellIndex = cell.cellIndex; // 下一行单元格的index + if (nextRow.cells.length <= cellIndex) { + return; + } + var nextCell = nextRow.cells[cellIndex]; // 下一行单元格 + // 上下行的colspan不一致时不能合并 + if (cell.colSpan !== nextCell.colSpan) { + return; + } + cell.rowSpan += nextCell.rowSpan; + nextRow.deleteCell(cellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colmerge : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex, // 当前行的index + cellIndex = cell.cellIndex, + nextCellIndex = cellIndex + 1; + // 最后一列不能合并 + if (row.cells.length <= nextCellIndex) { + return; + } + var nextCell = row.cells[nextCellIndex]; + // 左右列的rowspan不一致时不能合并 + if (cell.rowSpan !== nextCell.rowSpan) { + return; + } + cell.colSpan += nextCell.colSpan; + row.deleteCell(nextCellIndex); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + rowsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 不是可分割单元格 + if (cell.rowSpan === 1) { + return; + } + var cellIndex = _getCellIndex(table, row, cell); + for (var i = 1, len = cell.rowSpan; i < len; i++) { + var newRow = table.rows[rowIndex + i], + newCell = newRow.insertCell(cellIndex); + if (cell.colSpan > 1) { + newCell.colSpan = cell.colSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + // 调整下一行的单元格index + cellIndex = _getCellIndex(table, newRow, newCell); + } + K(cell).removeAttr('rowSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + colsplit : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + cellIndex = cell.cellIndex; + // 不是可分割单元格 + if (cell.colSpan === 1) { + return; + } + for (var i = 1, len = cell.colSpan; i < len; i++) { + var newCell = row.insertCell(cellIndex + i); + if (cell.rowSpan > 1) { + newCell.rowSpan = cell.rowSpan; + } + newCell.innerHTML = K.IE ? '' : '<br />'; + } + K(cell).removeAttr('colSpan'); + self.cmd.range.selectNodeContents(cell).collapse(true); + self.cmd.select(); + self.addBookmark(); + }, + coldelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + index = cell.cellIndex; + for (var i = 0, len = table.rows.length; i < len; i++) { + var newRow = table.rows[i], + newCell = newRow.cells[index]; + if (newCell.colSpan > 1) { + newCell.colSpan -= 1; + if (newCell.colSpan === 1) { + K(newCell).removeAttr('colSpan'); + } + } else { + newRow.deleteCell(index); + } + // 跳过不需要删除的行 + if (newCell.rowSpan > 1) { + i += newCell.rowSpan - 1; + } + } + if (row.cells.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + }, + rowdelete : function() { + var table = self.plugin.getSelectedTable()[0], + row = self.plugin.getSelectedRow()[0], + cell = self.plugin.getSelectedCell()[0], + rowIndex = row.rowIndex; + // 从下到上删除 + for (var i = cell.rowSpan - 1; i >= 0; i--) { + table.deleteRow(rowIndex + i); + } + if (table.rows.length === 0) { + self.cmd.range.setStartBefore(table).collapse(true); + self.cmd.select(); + K(table).remove(); + } else { + self.cmd.selection(true); + } + self.addBookmark(); + } + }; + self.clickToolbar(name, self.plugin.table.prop); +}); diff --git a/static/plugins/kindeditor/plugins/template/html/1.html b/static/plugins/kindeditor/plugins/template/html/1.html new file mode 100755 index 0000000..034126b --- /dev/null +++ b/static/plugins/kindeditor/plugins/template/html/1.html @@ -0,0 +1,14 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> +</head> +<body> + <h3> + <img align="left" height="100" style="margin-right: 10px" width="100" />在此处输入标题 + </h3> + <p> + 在此处输入内容 + </p> +</body> +</html> \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/template/html/2.html b/static/plugins/kindeditor/plugins/template/html/2.html new file mode 100755 index 0000000..dc2584a --- /dev/null +++ b/static/plugins/kindeditor/plugins/template/html/2.html @@ -0,0 +1,42 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> +</head> +<body> + <h3> + 标题 + </h3> + <table style="width:100%;" cellpadding="2" cellspacing="0" border="1"> + <tbody> + <tr> + <td> + <h3>标题1</h3> + </td> + <td> + <h3>标题1</h3> + </td> + </tr> + <tr> + <td> + 内容1 + </td> + <td> + 内容2 + </td> + </tr> + <tr> + <td> + 内容3 + </td> + <td> + 内容4 + </td> + </tr> + </tbody> + </table> + <p> + 表格说明 + </p> +</body> +</html> \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/template/html/3.html b/static/plugins/kindeditor/plugins/template/html/3.html new file mode 100755 index 0000000..873f0c6 --- /dev/null +++ b/static/plugins/kindeditor/plugins/template/html/3.html @@ -0,0 +1,36 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> +</head> +<body> + <p> + 在此处输入内容 + </p> + <ol> + <li> + 描述1 + </li> + <li> + 描述2 + </li> + <li> + 描述3 + </li> + </ol> + <p> + 在此处输入内容 + </p> + <ul> + <li> + 描述1 + </li> + <li> + 描述2 + </li> + <li> + 描述3 + </li> + </ul> +</body> +</html> \ No newline at end of file diff --git a/static/plugins/kindeditor/plugins/template/template.js b/static/plugins/kindeditor/plugins/template/template.js new file mode 100755 index 0000000..644882a --- /dev/null +++ b/static/plugins/kindeditor/plugins/template/template.js @@ -0,0 +1,58 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('template', function(K) { + var self = this, name = 'template', lang = self.lang(name + '.'), + htmlPath = self.pluginsPath + name + '/html/'; + function getFilePath(fileName) { + return htmlPath + fileName + '?ver=' + encodeURIComponent(K.DEBUG ? K.TIME : K.VERSION); + } + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + arr = ['<div style="padding:10px 20px;">', + '<div class="ke-header">', + // left start + '<div class="ke-left">', + lang. selectTemplate + ' <select>']; + K.each(lang.fileList, function(key, val) { + arr.push('<option value="' + key + '">' + val + '</option>'); + }); + html = [arr.join(''), + '</select></div>', + // right start + '<div class="ke-right">', + '<input type="checkbox" id="keReplaceFlag" name="replaceFlag" value="1" /> <label for="keReplaceFlag">' + lang.replaceContent + '</label>', + '</div>', + '<div class="ke-clearfix"></div>', + '</div>', + '<iframe class="ke-textarea" frameborder="0" style="width:458px;height:260px;background-color:#FFF;"></iframe>', + '</div>'].join(''); + var dialog = self.createDialog({ + name : name, + width : 500, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var doc = K.iframeDoc(iframe); + self[checkbox[0].checked ? 'html' : 'insertHtml'](doc.body.innerHTML).hideDialog().focus(); + } + } + }); + var selectBox = K('select', dialog.div), + checkbox = K('[name="replaceFlag"]', dialog.div), + iframe = K('iframe', dialog.div); + checkbox[0].checked = true; + iframe.attr('src', getFilePath(selectBox.val())); + selectBox.change(function() { + iframe.attr('src', getFilePath(this.value)); + }); + }); +}); diff --git a/static/plugins/kindeditor/plugins/wordpaste/wordpaste.js b/static/plugins/kindeditor/plugins/wordpaste/wordpaste.js new file mode 100755 index 0000000..d3af21b --- /dev/null +++ b/static/plugins/kindeditor/plugins/wordpaste/wordpaste.js @@ -0,0 +1,51 @@ +/******************************************************************************* +* KindEditor - WYSIWYG HTML Editor for Internet +* Copyright (C) 2006-2011 kindsoft.net +* +* @author Roddy <luolonghao@gmail.com> +* @site http://www.kindsoft.net/ +* @licence http://www.kindsoft.net/license.php +*******************************************************************************/ + +KindEditor.plugin('wordpaste', function(K) { + var self = this, name = 'wordpaste'; + self.clickToolbar(name, function() { + var lang = self.lang(name + '.'), + html = '<div style="padding:10px 20px;">' + + '<div style="margin-bottom:10px;">' + lang.comment + '</div>' + + '<iframe class="ke-textarea" frameborder="0" style="width:408px;height:260px;"></iframe>' + + '</div>', + dialog = self.createDialog({ + name : name, + width : 450, + title : self.lang(name), + body : html, + yesBtn : { + name : self.lang('yes'), + click : function(e) { + var str = doc.body.innerHTML; + str = K.clearMsWord(str, self.filterMode ? self.htmlTags : K.options.htmlTags); + self.insertHtml(str).hideDialog().focus(); + } + } + }), + div = dialog.div, + iframe = K('iframe', div), + doc = K.iframeDoc(iframe); + if (!K.IE) { + doc.designMode = 'on'; + } + doc.open(); + doc.write('<!doctype html><html><head><title>WordPaste</title></head>'); + doc.write('<body style="background-color:#FFF;font-size:12px;margin:2px;">'); + if (!K.IE) { + doc.write('<br />'); + } + doc.write('</body></html>'); + doc.close(); + if (K.IE) { + doc.body.contentEditable = 'true'; + } + iframe[0].contentWindow.focus(); + }); +}); diff --git a/static/plugins/kindeditor/themes/common/anchor.gif b/static/plugins/kindeditor/themes/common/anchor.gif new file mode 100755 index 0000000..61145ea Binary files /dev/null and b/static/plugins/kindeditor/themes/common/anchor.gif differ diff --git a/static/plugins/kindeditor/themes/common/blank.gif b/static/plugins/kindeditor/themes/common/blank.gif new file mode 100755 index 0000000..5bfd67a Binary files /dev/null and b/static/plugins/kindeditor/themes/common/blank.gif differ diff --git a/static/plugins/kindeditor/themes/common/flash.gif b/static/plugins/kindeditor/themes/common/flash.gif new file mode 100755 index 0000000..2cb12b2 Binary files /dev/null and b/static/plugins/kindeditor/themes/common/flash.gif differ diff --git a/static/plugins/kindeditor/themes/common/loading.gif b/static/plugins/kindeditor/themes/common/loading.gif new file mode 100755 index 0000000..c69e937 Binary files /dev/null and b/static/plugins/kindeditor/themes/common/loading.gif differ diff --git a/static/plugins/kindeditor/themes/common/media.gif b/static/plugins/kindeditor/themes/common/media.gif new file mode 100755 index 0000000..e1c0e30 Binary files /dev/null and b/static/plugins/kindeditor/themes/common/media.gif differ diff --git a/static/plugins/kindeditor/themes/common/rm.gif b/static/plugins/kindeditor/themes/common/rm.gif new file mode 100755 index 0000000..d013d55 Binary files /dev/null and b/static/plugins/kindeditor/themes/common/rm.gif differ diff --git a/static/plugins/kindeditor/themes/default/background.png b/static/plugins/kindeditor/themes/default/background.png new file mode 100755 index 0000000..e59bd68 Binary files /dev/null and b/static/plugins/kindeditor/themes/default/background.png differ diff --git a/static/plugins/kindeditor/themes/default/default.css b/static/plugins/kindeditor/themes/default/default.css new file mode 100755 index 0000000..3f72660 --- /dev/null +++ b/static/plugins/kindeditor/themes/default/default.css @@ -0,0 +1,1147 @@ +/* common */ +.ke-inline-block { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-clearfix { + zoom: 1; +} +.ke-clearfix:after { + content: "."; + display: block; + clear: both; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; +} +.ke-shadow { + box-shadow: 1px 1px 3px #A0A0A0; + -moz-box-shadow: 1px 1px 3px #A0A0A0; + -webkit-box-shadow: 1px 1px 3px #A0A0A0; + filter: progid:DXImageTransform.Microsoft.Shadow(color='#A0A0A0', Direction=135, Strength=3); + background-color: #F0F0EE; +} +.ke-menu a, +.ke-menu a:hover, +.ke-dialog a, +.ke-dialog a:hover { + color: #337FE5; + text-decoration: none; +} +/* icons */ +.ke-icon-source { + background-position: 0px 0px; + width: 16px; + height: 16px; +} +.ke-icon-preview { + background-position: 0px -16px; + width: 16px; + height: 16px; +} +.ke-icon-print { + background-position: 0px -32px; + width: 16px; + height: 16px; +} +.ke-icon-undo { + background-position: 0px -48px; + width: 16px; + height: 16px; +} +.ke-icon-redo { + background-position: 0px -64px; + width: 16px; + height: 16px; +} +.ke-icon-cut { + background-position: 0px -80px; + width: 16px; + height: 16px; +} +.ke-icon-copy { + background-position: 0px -96px; + width: 16px; + height: 16px; +} +.ke-icon-paste { + background-position: 0px -112px; + width: 16px; + height: 16px; +} +.ke-icon-selectall { + background-position: 0px -128px; + width: 16px; + height: 16px; +} +.ke-icon-justifyleft { + background-position: 0px -144px; + width: 16px; + height: 16px; +} +.ke-icon-justifycenter { + background-position: 0px -160px; + width: 16px; + height: 16px; +} +.ke-icon-justifyright { + background-position: 0px -176px; + width: 16px; + height: 16px; +} +.ke-icon-justifyfull { + background-position: 0px -192px; + width: 16px; + height: 16px; +} +.ke-icon-insertorderedlist { + background-position: 0px -208px; + width: 16px; + height: 16px; +} +.ke-icon-insertunorderedlist { + background-position: 0px -224px; + width: 16px; + height: 16px; +} +.ke-icon-indent { + background-position: 0px -240px; + width: 16px; + height: 16px; +} +.ke-icon-outdent { + background-position: 0px -256px; + width: 16px; + height: 16px; +} +.ke-icon-subscript { + background-position: 0px -272px; + width: 16px; + height: 16px; +} +.ke-icon-superscript { + background-position: 0px -288px; + width: 16px; + height: 16px; +} +.ke-icon-date { + background-position: 0px -304px; + width: 25px; + height: 16px; +} +.ke-icon-time { + background-position: 0px -320px; + width: 25px; + height: 16px; +} +.ke-icon-formatblock { + background-position: 0px -336px; + width: 25px; + height: 16px; +} +.ke-icon-fontname { + background-position: 0px -352px; + width: 21px; + height: 16px; +} +.ke-icon-fontsize { + background-position: 0px -368px; + width: 23px; + height: 16px; +} +.ke-icon-forecolor { + background-position: 0px -384px; + width: 20px; + height: 16px; +} +.ke-icon-hilitecolor { + background-position: 0px -400px; + width: 23px; + height: 16px; +} +.ke-icon-bold { + background-position: 0px -416px; + width: 16px; + height: 16px; +} +.ke-icon-italic { + background-position: 0px -432px; + width: 16px; + height: 16px; +} +.ke-icon-underline { + background-position: 0px -448px; + width: 16px; + height: 16px; +} +.ke-icon-strikethrough { + background-position: 0px -464px; + width: 16px; + height: 16px; +} +.ke-icon-removeformat { + background-position: 0px -480px; + width: 16px; + height: 16px; +} +.ke-icon-image { + background-position: 0px -496px; + width: 16px; + height: 16px; +} +.ke-icon-flash { + background-position: 0px -512px; + width: 16px; + height: 16px; +} +.ke-icon-media { + background-position: 0px -528px; + width: 16px; + height: 16px; +} +.ke-icon-div { + background-position: 0px -544px; + width: 16px; + height: 16px; +} +.ke-icon-formula { + background-position: 0px -576px; + width: 16px; + height: 16px; +} +.ke-icon-hr { + background-position: 0px -592px; + width: 16px; + height: 16px; +} +.ke-icon-emoticons { + background-position: 0px -608px; + width: 16px; + height: 16px; +} +.ke-icon-link { + background-position: 0px -624px; + width: 16px; + height: 16px; +} +.ke-icon-unlink { + background-position: 0px -640px; + width: 16px; + height: 16px; +} +.ke-icon-fullscreen { + background-position: 0px -656px; + width: 16px; + height: 16px; +} +.ke-icon-about { + background-position: 0px -672px; + width: 16px; + height: 16px; +} +.ke-icon-plainpaste { + background-position: 0px -704px; + width: 16px; + height: 16px; +} +.ke-icon-wordpaste { + background-position: 0px -720px; + width: 16px; + height: 16px; +} +.ke-icon-table { + background-position: 0px -784px; + width: 16px; + height: 16px; +} +.ke-icon-tablemenu { + background-position: 0px -768px; + width: 16px; + height: 16px; +} +.ke-icon-tableinsert { + background-position: 0px -784px; + width: 16px; + height: 16px; +} +.ke-icon-tabledelete { + background-position: 0px -800px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolinsertleft { + background-position: 0px -816px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolinsertright { + background-position: 0px -832px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowinsertabove { + background-position: 0px -848px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowinsertbelow { + background-position: 0px -864px; + width: 16px; + height: 16px; +} +.ke-icon-tablecoldelete { + background-position: 0px -880px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowdelete { + background-position: 0px -896px; + width: 16px; + height: 16px; +} +.ke-icon-tablecellprop { + background-position: 0px -912px; + width: 16px; + height: 16px; +} +.ke-icon-tableprop { + background-position: 0px -928px; + width: 16px; + height: 16px; +} +.ke-icon-checked { + background-position: 0px -944px; + width: 16px; + height: 16px; +} +.ke-icon-code { + background-position: 0px -960px; + width: 16px; + height: 16px; +} +.ke-icon-map { + background-position: 0px -976px; + width: 16px; + height: 16px; +} +.ke-icon-baidumap { + background-position: 0px -976px; + width: 16px; + height: 16px; +} +.ke-icon-lineheight { + background-position: 0px -992px; + width: 16px; + height: 16px; +} +.ke-icon-clearhtml { + background-position: 0px -1008px; + width: 16px; + height: 16px; +} +.ke-icon-pagebreak { + background-position: 0px -1024px; + width: 16px; + height: 16px; +} +.ke-icon-insertfile { + background-position: 0px -1040px; + width: 16px; + height: 16px; +} +.ke-icon-quickformat { + background-position: 0px -1056px; + width: 16px; + height: 16px; +} +.ke-icon-template { + background-position: 0px -1072px; + width: 16px; + height: 16px; +} +.ke-icon-tablecellsplit { + background-position: 0px -1088px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowmerge { + background-position: 0px -1104px; + width: 16px; + height: 16px; +} +.ke-icon-tablerowsplit { + background-position: 0px -1120px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolmerge { + background-position: 0px -1136px; + width: 16px; + height: 16px; +} +.ke-icon-tablecolsplit { + background-position: 0px -1152px; + width: 16px; + height: 16px; +} +.ke-icon-anchor { + background-position: 0px -1168px; + width: 16px; + height: 16px; +} +.ke-icon-search { + background-position: 0px -1184px; + width: 16px; + height: 16px; +} +.ke-icon-new { + background-position: 0px -1200px; + width: 16px; + height: 16px; +} +.ke-icon-specialchar { + background-position: 0px -1216px; + width: 16px; + height: 16px; +} +.ke-icon-multiimage { + background-position: 0px -1232px; + width: 16px; + height: 16px; +} +/* container */ +.ke-container { + display: block; + border: 1px solid #CCCCCC; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; +} +/* toolbar */ +.ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #F0F0EE; + padding: 2px 5px; + text-align: left; + overflow: hidden; + zoom: 1; +} +.ke-toolbar-icon { + background-repeat: no-repeat; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; +} +.ke-toolbar-icon-url { + background-image: url(default.png); +} +.ke-toolbar .ke-outline { + border: 1px solid #F0F0EE; + margin: 1px; + padding: 1px 2px; + font-size: 0; + line-height: 0; + overflow: hidden; + cursor: pointer; + display: block; + float: left; +} +.ke-toolbar .ke-on { + border: 1px solid #5690D2; +} +.ke-toolbar .ke-selected { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-toolbar .ke-disabled { + cursor: default; +} +.ke-toolbar .ke-separator { + height: 16px; + margin: 2px 3px; + border-left: 1px solid #A0A0A0; + border-right: 1px solid #FFFFFF; + border-top:0; + border-bottom:0; + width: 0; + font-size: 0; + line-height: 0; + overflow: hidden; + display: block; + float: left; +} +.ke-toolbar .ke-hr { + overflow: hidden; + height: 1px; + clear: both; +} +/* edit */ +.ke-edit { + padding: 0; +} +.ke-edit-iframe, +.ke-edit-textarea { + border: 0; + margin: 0; + padding: 0; + overflow: auto; +} +.ke-edit-textarea { + font: 12px/1.5 "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; + color: #000; + overflow: auto; + resize: none; +} +.ke-edit-textarea:focus { + outline: none; +} +/* statusbar */ +.ke-statusbar { + position: relative; + background-color: #F0F0EE; + border-top: 1px solid #CCCCCC; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; +} +.ke-statusbar-center-icon { + background-position: -0px -754px; + width: 15px; + height: 11px; + background-image: url(default.png); +} +.ke-statusbar-right-icon { + position: absolute; + right: 0; + bottom: 0; + cursor: se-resize; + background-position: -5px -741px; + width: 11px; + height: 11px; + background-image: url(default.png); +} +/* menu */ +.ke-menu { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; +} +.ke-menu-item { + border: 1px solid #F1F1F1; + background-color: #F1F1F1; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; +} +.ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-menu-item-left { + width: 27px; + text-align: center; + overflow: hidden; +} +.ke-menu-item-center { + width: 0; + height: 24px; + border-left: 1px solid #E3E3E3; + border-right: 1px solid #FFFFFF; + border-top: 0; + border-bottom: 0; +} +.ke-menu-item-center-on { + border-left: 1px solid #E9EFF6; + border-right: 1px solid #E9EFF6; +} +.ke-menu-item-right { + border: 0; + padding: 0 0 0 5px; + line-height: 24px; + text-align: left; + overflow: hidden; +} +.ke-menu-separator { + margin: 2px 0; + height: 0; + overflow: hidden; + border-top: 1px solid #CCCCCC; + border-bottom: 1px solid #FFFFFF; + border-left: 0; + border-right: 0; +} +/* colorpicker */ +.ke-colorpicker { + border: 1px solid #A0A0A0; + background-color: #F1F1F1; + color: #222222; + padding: 2px; +} +.ke-colorpicker-table { + border:0; + margin:0; + padding:0; + border-collapse: separate; +} +.ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #F0F0EE; + cursor: pointer; + margin:3px; + padding:0; +} +.ke-colorpicker-cell-top { + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #F0F0EE; + cursor: pointer; + margin:0; + padding:0; + text-align: center; +} +.ke-colorpicker-cell-on { + border: 1px solid #5690D2; +} +.ke-colorpicker-cell-selected { + border: 1px solid #2446AB; +} +.ke-colorpicker-cell-color { + width: 14px; + height: 14px; + margin: 3px; + padding: 0; + border: 0; +} +/* dialog */ +.ke-dialog { + position: absolute; + margin: 0; + padding: 0; +} +.ke-dialog .ke-header { + width: 100%; + margin-bottom: 10px; +} +.ke-dialog .ke-header .ke-left { + float: left; +} +.ke-dialog .ke-header .ke-right { + float: right; +} +.ke-dialog .ke-header label { + margin-right: 0; + cursor: pointer; + font-weight: normal; + display: inline; + vertical-align: top; +} +.ke-dialog-content { + background-color: #FFF; + width: 100%; + height: 100%; + color: #333; + border: 1px solid #A0A0A0; +} +.ke-dialog-shadow { + position: absolute; + z-index: -1; + top: 0; + left: 0; + width: 100%; + height: 100%; + box-shadow: 3px 3px 7px #999; + -moz-box-shadow: 3px 3px 7px #999; + -webkit-box-shadow: 3px 3px 7px #999; + filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='3', MakeShadow='true', ShadowOpacity='0.4'); + background-color: #F0F0EE; +} +.ke-dialog-header { + border:0; + margin:0; + padding: 0 10px; + background: url(background.png) repeat scroll 0 0 #F0F0EE; + border-bottom: 1px solid #CFCFCF; + height: 24px; + font: 12px/24px "sans serif",tahoma,verdana,helvetica; + text-align: left; + color: #222; + cursor: move; +} +.ke-dialog-icon-close { + display: block; + background: url(default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 6px; + top: 6px; + cursor: pointer; +} +.ke-dialog-body { + font: 12px/1.5 "sans serif",tahoma,verdana,helvetica; + text-align: left; + overflow: hidden; + width: 100%; +} +.ke-dialog-body textarea { + display: block; + overflow: auto; + padding: 0; + resize: none; +} +.ke-dialog-body textarea:focus, +.ke-dialog-body input:focus, +.ke-dialog-body select:focus { + outline: none; +} +.ke-dialog-body label { + margin-right: 10px; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-dialog-body img { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-dialog-body select { + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; + width: auto; +} +.ke-dialog-body .ke-textarea { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} +.ke-dialog-body .ke-form { + margin: 0; + padding: 0; +} +.ke-dialog-loading { + position: absolute; + top: 0; + left: 1px; + z-index: 1; + text-align: center; +} +.ke-dialog-loading-content { + background: url("../common/loading.gif") no-repeat; + color: #666; + font-size: 14px; + font-weight: bold; + height: 31px; + line-height: 31px; + padding-left: 36px; +} +.ke-dialog-row { + margin-bottom: 10px; +} +.ke-dialog-footer { + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + text-align: right; + padding:0 0 5px 0; + background-color: #FFF; + width: 100%; +} +.ke-dialog-preview, +.ke-dialog-yes { + margin: 5px; +} +.ke-dialog-no { + margin: 5px 10px 5px 5px; +} +.ke-dialog-mask { + background-color:#FFF; + filter:alpha(opacity=50); + opacity:0.5; +} +.ke-button-common { + background: url(background.png) no-repeat; + cursor: pointer; + height: 23px; + line-height: 23px; + overflow: visible; + display: inline-block; + vertical-align: top; + cursor: pointer; +} +.ke-button-outer { + background-position: 0 -25px; + padding: 0; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-button { + background-position: right -25px; + padding: 0 14px 0 12px; + margin: 0 0 0 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + border: 0 none; + color: #333; + font-size: 12px; + text-decoration: none; +} +/* inputbox */ +.ke-input-text { + background-color:#FFFFFF; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 17px; + height: 17px; + padding: 2px 4px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-input-number { + width: 50px; +} +.ke-input-color { + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + font-size: 12px; + width: 60px; + height: 20px; + line-height: 20px; + padding-left: 5px; + overflow: hidden; + cursor: pointer; + display: -moz-inline-stack; + display: inline-block; + vertical-align: middle; + zoom: 1; + *display: inline; +} +.ke-upload-button { + position: relative; +} +.ke-upload-area { + position: relative; + overflow: hidden; + margin: 0; + padding: 0; + *height: 25px; +} +.ke-upload-area .ke-upload-file { + position: absolute; + font-size: 60px; + top: 0; + right: 0; + padding: 0; + margin: 0; + z-index: 811212; + border: 0 none; + opacity: 0; + filter: alpha(opacity=0); +} +/* tabs */ +.ke-tabs { + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + border-bottom:1px solid #A0A0A0; + padding-left:5px; + margin-bottom:20px; +} +.ke-tabs-ul { + list-style-image:none; + list-style-position:outside; + list-style-type:none; + margin:0; + padding:0; +} +.ke-tabs-li { + position: relative; + border: 1px solid #A0A0A0; + background-color: #F0F0EE; + margin: 0 2px -1px 0; + padding: 0 20px; + float: left; + line-height: 25px; + text-align: center; + color: #555555; + cursor: pointer; +} +.ke-tabs-li-selected { + background-color: #FFF; + border-bottom: 1px solid #FFF; + color: #000; + cursor: default; +} +.ke-tabs-li-on { + background-color: #FFF; + color: #000; +} +/* progressbar */ +.ke-progressbar { + position: relative; + margin: 0; + padding: 0; +} +.ke-progressbar-bar { + border: 1px solid #6FA5DB; + width: 80px; + height: 5px; + margin: 10px 10px 0 10px; + padding: 0; +} +.ke-progressbar-bar-inner { + width: 0; + height: 5px; + background-color: #6FA5DB; + overflow: hidden; + margin: 0; + padding: 0; +} +.ke-progressbar-percent { + position: absolute; + top: 0; + left: 40%; + display: none; +} +/* swfupload */ +.ke-swfupload-top { + position: relative; + margin-bottom: 10px; + _width: 608px; +} +.ke-swfupload-button { + height: 23px; + line-height: 23px; +} +.ke-swfupload-desc { + padding: 0 10px; + height: 23px; + line-height: 23px; +} +.ke-swfupload-startupload { + position: absolute; + top: 0; + right: 0; +} +.ke-swfupload-body { + overflow: scroll; + background-color:#FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} +.ke-swfupload-body .ke-item { + width: 100px; + margin: 5px; +} +.ke-swfupload-body .ke-photo { + position: relative; + border: 1px solid #DDDDDD; + background-color:#FFFFFF; + padding: 10px; +} +.ke-swfupload-body .ke-delete { + display: block; + background: url(default.png) no-repeat scroll 0px -688px; + width: 16px; + height: 16px; + position: absolute; + right: 0; + top: 0; + cursor: pointer; +} +.ke-swfupload-body .ke-status { + position: absolute; + left: 0; + bottom: 5px; + width: 100px; + height: 17px; +} +.ke-swfupload-body .ke-message { + width: 100px; + text-align: center; + overflow: hidden; + height:17px; +} +.ke-swfupload-body .ke-error { + color: red; +} +.ke-swfupload-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height:16px; +} +.ke-swfupload-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} + +/* emoticons */ +.ke-plugin-emoticons { + position: relative; +} +.ke-plugin-emoticons .ke-preview { + position: absolute; + text-align: center; + margin: 2px; + padding: 10px; + top: 0; + border: 1px solid #A0A0A0; + background-color: #FFFFFF; + display: none; +} +.ke-plugin-emoticons .ke-preview-img { + border:0; + margin:0; + padding:0; +} +.ke-plugin-emoticons .ke-table { + border:0; + margin:0; + padding:0; + border-collapse:separate; +} +.ke-plugin-emoticons .ke-cell { + margin:0; + padding:1px; + border:1px solid #F0F0EE; + cursor:pointer; +} +.ke-plugin-emoticons .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-plugin-emoticons .ke-img { + display:block; + background-repeat:no-repeat; + overflow:hidden; + margin:2px; + width:24px; + height:24px; + margin: 0; + padding: 0; + border: 0; +} +.ke-plugin-emoticons .ke-page { + text-align: right; + margin: 5px; + padding: 0; + border: 0; + font: 12px/1 "sans serif",tahoma,verdana,helvetica; + color: #333; + text-decoration: none; +} +.ke-plugin-plainpaste-textarea, +.ke-plugin-wordpaste-iframe { + display: block; + width: 408px; + height: 260px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; +} +/* filemanager */ +.ke-plugin-filemanager-header { + width: 100%; + margin-bottom: 10px; +} +.ke-plugin-filemanager-header .ke-left { + float: left; +} +.ke-plugin-filemanager-header .ke-right { + float: right; +} +.ke-plugin-filemanager-body { + overflow: scroll; + background-color:#FFFFFF; + border-color: #848484 #E0E0E0 #E0E0E0 #848484; + border-style: solid; + border-width: 1px; + width: auto; + height: 370px; + padding: 5px; +} +.ke-plugin-filemanager-body .ke-item { + width: 100px; + margin: 5px; +} +.ke-plugin-filemanager-body .ke-photo { + border: 1px solid #DDDDDD; + background-color:#FFFFFF; + padding: 10px; +} +.ke-plugin-filemanager-body .ke-name { + width: 100px; + text-align: center; + overflow: hidden; + height:16px; +} +.ke-plugin-filemanager-body .ke-on { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-plugin-filemanager-body .ke-table { + width: 95%; + border: 0; + margin: 0; + padding: 0; + border-collapse: separate; +} +.ke-plugin-filemanager-body .ke-table .ke-cell { + margin: 0; + padding: 0; + border: 0; +} +.ke-plugin-filemanager-body .ke-table .ke-name { + width: 55%; + text-align: left; +} +.ke-plugin-filemanager-body .ke-table .ke-size { + width: 15%; + text-align: left; +} +.ke-plugin-filemanager-body .ke-table .ke-datetime { + width: 30%; + text-align: center; +} + diff --git a/static/plugins/kindeditor/themes/default/default.png b/static/plugins/kindeditor/themes/default/default.png new file mode 100755 index 0000000..cc9e72d Binary files /dev/null and b/static/plugins/kindeditor/themes/default/default.png differ diff --git a/static/plugins/kindeditor/themes/qq/editor.gif b/static/plugins/kindeditor/themes/qq/editor.gif new file mode 100755 index 0000000..b256841 Binary files /dev/null and b/static/plugins/kindeditor/themes/qq/editor.gif differ diff --git a/static/plugins/kindeditor/themes/qq/qq.css b/static/plugins/kindeditor/themes/qq/qq.css new file mode 100755 index 0000000..a45e08c --- /dev/null +++ b/static/plugins/kindeditor/themes/qq/qq.css @@ -0,0 +1,143 @@ +/* container */ +.ke-container-qq { + display: block; + border: 1px solid #c3c3c3; + background-color: #FFF; + overflow: hidden; + margin: 0; + padding: 0; +} +/* toolbar */ +.ke-container-qq .ke-toolbar { + border-bottom: 1px solid #c3c3c3; + background-color: #FFFFFF; + padding: 2px 5px; + text-align: left; + overflow: hidden; + zoom: 1; +} +.ke-toolbar-icon-url { + background-image: url(editor.gif); + width:18px; + *xwidth:20px; + height:18px; + *xheight:20px; +} +.ke-icon-checked{ + background-image: url(../default/default.png); + width:16px; + height:16px; +} +.ke-container-qq .ke-icon-bold{ + background-position: 4px 1px; +} +.ke-container-qq .ke-icon-italic{ + background-position: -27px 1px; +} +.ke-container-qq .ke-icon-italic{ + background-position: -28px 1px; +} +.ke-container-qq .ke-icon-underline{ + background-position: -60px 1px; +} +.ke-container-qq .ke-icon-fontname{ + background-position: -95px 1px; +} +.ke-container-qq .ke-icon-fontsize{ + background-position: -128px 1px; +} +.ke-container-qq .ke-icon-forecolor{ + background-position: -159px 1px; +} +.ke-container-qq .ke-icon-hilitecolor{ + background-position: -190px 1px; +} +.ke-container-qq .ke-icon-plug-align{ + background-position: -223px 1px; +} +.plug-align-justifyleft{ + background-position: -350px 1px; +} +.plug-align-justifycenter{ + background-position: -382px 1px; +} +.plug-align-justifyright{ + background-position: -414px 1px; +} +.plug-order-insertorderedlist{ + background-position: -446px 1px; +} +.plug-order-insertunorderedlist{ + background-position: -477px 1px; +} +.plug-indent-indent{ + background-position: -513px 1px; +} +.plug-indent-outdent{ + background-position: -545px 1px; +} +.ke-container-qq .ke-icon-plug-order{ + background-position: -255px 1px; +} +.ke-container-qq .ke-icon-plug-indent{ + background-position: -287px 1px; +} +.ke-container-qq .ke-icon-link{ + background-position: -319px 1px; +} + +.ke-container-qq .ke-toolbar .ke-outline { + cursor: default; + padding:0px; + border:1px solid #fff; +} +.ke-container-qq .ke-toolbar .ke-on { + border-left:1px solid white; + border-top:1px solid white; + border-right:1px solid gray; + border-bottom:1px solid gray; + background-color: #FFFFFF; +} +.ke-container-qq .ke-toolbar .ke-selected { + border-left:1px solid gray; + border-top:1px solid gray; + border-right:1px solid white; + border-bottom:1px solid white; + background-color: #FFFFFF; +} +.ke-container-qq .ke-toolbar .ke-disabled { + cursor: default; +} + +.ke-colorpicker-qq{ + background:#fff; +} +/* statusbar */ +.ke-container-qq .ke-statusbar { + display:none; +} +/* menu */ +.ke-menu-qq { + border:1px solid #a6a6a6; + position:absolute; + background:#fff; + -moz-box-shadow:2px 2px 4px #DDDDDD; + z-index:999; + left:-400px; + top:-386px; + right:218px; + width:130px; +} +.ke-menu-qq .ke-menu-item { + padding:0px; + background:#fff; +} +.ke-menu-qq .ke-menu-item-on { + border:1px solid #000080;background:#FFEEC2;color:#036; +} +.ke-menu-qq .ke-toolbar .ke-selected { + border:1px solid #9a9afb; +} +.ke-menu-qq .ke-menu-item-left{ + width:auto; +} diff --git a/static/plugins/kindeditor/themes/simple/simple.css b/static/plugins/kindeditor/themes/simple/simple.css new file mode 100755 index 0000000..4c76cf9 --- /dev/null +++ b/static/plugins/kindeditor/themes/simple/simple.css @@ -0,0 +1,100 @@ +/* container */ +.ke-container-simple { + display: block; + border: 1px solid #CCC; + background-color: #FFF; + overflow: hidden; +} +/* toolbar */ +.ke-container-simple .ke-toolbar { + border-bottom: 1px solid #CCC; + background-color: #FFF; + padding: 2px 5px; + overflow: hidden; +} +.ke-container-simple .ke-toolbar .ke-outline { + border: 1px solid #FFF; + background-color: transparent; + margin: 1px; + padding: 1px 2px; + font-size: 0; + line-height: 0; + overflow: hidden; + cursor: pointer; +} +.ke-container-simple .ke-toolbar .ke-on { + border: 1px solid #5690D2; +} +.ke-container-simple .ke-toolbar .ke-selected { + border: 1px solid #5690D2; + background-color: #E9EFF6; +} +.ke-container-simple .ke-toolbar .ke-disabled { + cursor: default; +} +/* statusbar */ +.ke-container-simple .ke-statusbar { + position: relative; + background-color: #FFF; + border-top: 1px solid #CCCCCC; + font-size: 0; + line-height: 0; + *height: 12px; + overflow: hidden; + text-align: center; + cursor: s-resize; +} +/* menu */ +.ke-menu-simple { + border: 1px solid #A0A0A0; + background-color: #FFF; + color: #222222; + padding: 2px; + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + text-align: left; + overflow: hidden; +} +.ke-menu-simple .ke-menu-item { + border: 1px solid #FFF; + background-color: #FFF; + color: #222222; + height: 24px; + overflow: hidden; + cursor: pointer; +} +.ke-menu-simple .ke-menu-item-on { + border: 1px solid #5690D2; + background-color: #FFF; +} +/* colorpicker */ +.ke-colorpicker-simple { + border: 1px solid #A0A0A0; + background-color: #FEFEFE; + color: #222222; + padding: 2px; +} +.ke-colorpicker-simple .ke-colorpicker-cell { + font-size: 0; + line-height: 0; + border: 1px solid #FEFEFE; + cursor: pointer; + margin:3px; + padding:0; +} +.ke-colorpicker-simple .ke-colorpicker-cell-top { + font-family: "sans serif",tahoma,verdana,helvetica; + font-size: 12px; + line-height: 24px; + border: 1px solid #FEFEFE; + cursor: pointer; + margin:0; + padding:0; + text-align: center; +} +.ke-colorpicker-simple .ke-colorpicker-cell-on { + border: 1px solid #5690D2; +} +.ke-colorpicker-simple .ke-colorpicker-cell-selected { + border: 1px solid #2446AB; +} diff --git a/static/plugins/layer/laydate.js b/static/plugins/layer/laydate.js new file mode 100755 index 0000000..807209e --- /dev/null +++ b/static/plugins/layer/laydate.js @@ -0,0 +1,11 @@ +/** + + @Name : layDate v1.1 日期控件 + @Author: 贤心 + @Date: 2014-06-25 + @QQ群:176047195 + @Site:http://sentsin.com/layui/laydate + + */ + +;!function(a){var b={path:"",defSkin:"default",format:"YYYY-MM-DD",min:"1900-01-01 00:00:00",max:"2099-12-31 23:59:59",isv:!1},c={},d=document,e="createElement",f="getElementById",g="getElementsByTagName",h=["laydate_box","laydate_void","laydate_click","LayDateSkin","skins/","/laydate.css"];a.laydate=function(b){b=b||{};try{h.event=a.event?a.event:laydate.caller.arguments[0]}catch(d){}return c.run(b),laydate},laydate.v="1.1",c.getPath=function(){var a=document.scripts,c=a[a.length-1].src;return b.path?b.path:c.substring(0,c.lastIndexOf("/")+1)}(),c.use=function(a,b){var f=d[e]("link");f.type="text/css",f.rel="stylesheet",f.href=c.getPath+a+h[5],b&&(f.id=b),d[g]("head")[0].appendChild(f),f=null},c.trim=function(a){return a=a||"",a.replace(/^\s|\s$/g,"").replace(/\s+/g," ")},c.digit=function(a){return 10>a?"0"+(0|a):a},c.stopmp=function(b){return b=b||a.event,b.stopPropagation?b.stopPropagation():b.cancelBubble=!0,this},c.each=function(a,b){for(var c=0,d=a.length;d>c&&b(c,a[c])!==!1;c++);},c.hasClass=function(a,b){return a=a||{},new RegExp("\\b"+b+"\\b").test(a.className)},c.addClass=function(a,b){return a=a||{},c.hasClass(a,b)||(a.className+=" "+b),a.className=c.trim(a.className),this},c.removeClass=function(a,b){if(a=a||{},c.hasClass(a,b)){var d=new RegExp("\\b"+b+"\\b");a.className=a.className.replace(d,"")}return this},c.removeCssAttr=function(a,b){var c=a.style;c.removeProperty?c.removeProperty(b):c.removeAttribute(b)},c.shde=function(a,b){a.style.display=b?"none":"block"},c.query=function(a){var e,b,h,i,j;return a=c.trim(a).split(" "),b=d[f](a[0].substr(1)),b?a[1]?/^\./.test(a[1])?(i=a[1].substr(1),j=new RegExp("\\b"+i+"\\b"),e=[],h=d.getElementsByClassName?b.getElementsByClassName(i):b[g]("*"),c.each(h,function(a,b){j.test(b.className)&&e.push(b)}),e[0]?e:""):(e=b[g](a[1]),e[0]?b[g](a[1]):""):b:void 0},c.on=function(b,d,e){return b.attachEvent?b.attachEvent("on"+d,function(){e.call(b,a.even)}):b.addEventListener(d,e,!1),c},c.stopMosup=function(a,b){"mouseup"!==a&&c.on(b,"mouseup",function(a){c.stopmp(a)})},c.run=function(a){var d,e,g,b=c.query,f=h.event;try{g=f.target||f.srcElement||{}}catch(i){g={}}if(d=a.elem?b(a.elem):g,f&&g.tagName){if(!d||d===c.elem)return;c.stopMosup(f.type,d),c.stopmp(f),c.view(d,a),c.reshow()}else e=a.event||"click",c.each((0|d.length)>0?d:[d],function(b,d){c.stopMosup(e,d),c.on(d,e,function(b){c.stopmp(b),d!==c.elem&&(c.view(d,a),c.reshow())})})},c.scroll=function(a){return a=a?"scrollLeft":"scrollTop",d.body[a]|d.documentElement[a]},c.winarea=function(a){return document.documentElement[a?"clientWidth":"clientHeight"]},c.isleap=function(a){return 0===a%4&&0!==a%100||0===a%400},c.checkVoid=function(a,b,d){var e=[];return a=0|a,b=0|b,d=0|d,a<c.mins[0]?e=["y"]:a>c.maxs[0]?e=["y",1]:a>=c.mins[0]&&a<=c.maxs[0]&&(a==c.mins[0]&&(b<c.mins[1]?e=["m"]:b==c.mins[1]&&d<c.mins[2]&&(e=["d"])),a==c.maxs[0]&&(b>c.maxs[1]?e=["m",1]:b==c.maxs[1]&&d>c.maxs[2]&&(e=["d",1]))),e},c.timeVoid=function(a,b){if(c.ymd[1]+1==c.mins[1]&&c.ymd[2]==c.mins[2]){if(0===b&&a<c.mins[3])return 1;if(1===b&&a<c.mins[4])return 1;if(2===b&&a<c.mins[5])return 1}else if(c.ymd[1]+1==c.maxs[1]&&c.ymd[2]==c.maxs[2]){if(0===b&&a>c.maxs[3])return 1;if(1===b&&a>c.maxs[4])return 1;if(2===b&&a>c.maxs[5])return 1}return a>(b?59:23)?1:void 0},c.check=function(){var a=c.options.format.replace(/YYYY|MM|DD|hh|mm|ss/g,"\\d+\\").replace(/\\$/g,""),b=new RegExp(a),d=c.elem[h.elemv],e=d.match(/\d+/g)||[],f=c.checkVoid(e[0],e[1],e[2]);if(""!==d.replace(/\s/g,"")){if(!b.test(d))return c.elem[h.elemv]="",c.msg("日期不符合格式,请重新选择。"),1;if(f[0])return c.elem[h.elemv]="",c.msg("日期不在有效期内,请重新选择。"),1;f.value=c.elem[h.elemv].match(b).join(),e=f.value.match(/\d+/g),e[1]<1?(e[1]=1,f.auto=1):e[1]>12?(e[1]=12,f.auto=1):e[1].length<2&&(f.auto=1),e[2]<1?(e[2]=1,f.auto=1):e[2]>c.months[(0|e[1])-1]?(e[2]=31,f.auto=1):e[2].length<2&&(f.auto=1),e.length>3&&(c.timeVoid(e[3],0)&&(f.auto=1),c.timeVoid(e[4],1)&&(f.auto=1),c.timeVoid(e[5],2)&&(f.auto=1)),f.auto?c.creation([e[0],0|e[1],0|e[2]],1):f.value!==c.elem[h.elemv]&&(c.elem[h.elemv]=f.value)}},c.months=[31,null,31,30,31,30,31,31,30,31,30,31],c.viewDate=function(a,b,d){var f=(c.query,{}),g=new Date;a<(0|c.mins[0])&&(a=0|c.mins[0]),a>(0|c.maxs[0])&&(a=0|c.maxs[0]),g.setFullYear(a,b,d),f.ymd=[g.getFullYear(),g.getMonth(),g.getDate()],c.months[1]=c.isleap(f.ymd[0])?29:28,g.setFullYear(f.ymd[0],f.ymd[1],1),f.FDay=g.getDay(),f.PDay=c.months[0===b?11:b-1]-f.FDay+1,f.NDay=1,c.each(h.tds,function(a,b){var g,d=f.ymd[0],e=f.ymd[1]+1;b.className="",a<f.FDay?(b.innerHTML=g=a+f.PDay,c.addClass(b,"laydate_nothis"),1===e&&(d-=1),e=1===e?12:e-1):a>=f.FDay&&a<f.FDay+c.months[f.ymd[1]]?(b.innerHTML=g=a-f.FDay+1,a-f.FDay+1===f.ymd[2]&&(c.addClass(b,h[2]),f.thisDay=b)):(b.innerHTML=g=f.NDay++,c.addClass(b,"laydate_nothis"),12===e&&(d+=1),e=12===e?1:e+1),c.checkVoid(d,e,g)[0]&&c.addClass(b,h[1]),c.options.festival&&c.festival(b,e+"."+g),b.setAttribute("y",d),b.setAttribute("m",e),b.setAttribute("d",g),d=e=g=null}),c.valid=!c.hasClass(f.thisDay,h[1]),c.ymd=f.ymd,h.year.value=c.ymd[0]+"年",h.month.value=c.digit(c.ymd[1]+1)+"月",c.each(h.mms,function(a,b){var d=c.checkVoid(c.ymd[0],(0|b.getAttribute("m"))+1);"y"===d[0]||"m"===d[0]?c.addClass(b,h[1]):c.removeClass(b,h[1]),c.removeClass(b,h[2]),d=null}),c.addClass(h.mms[c.ymd[1]],h[2]),f.times=[0|c.inymd[3]||0,0|c.inymd[4]||0,0|c.inymd[5]||0],c.each(new Array(3),function(a){c.hmsin[a].value=c.digit(c.timeVoid(f.times[a],a)?0|c.mins[a+3]:0|f.times[a])}),c[c.valid?"removeClass":"addClass"](h.ok,h[1])},c.festival=function(a,b){var c;switch(b){case"1.1":c="元旦";break;case"3.8":c="妇女";break;case"4.5":c="清明";break;case"5.1":c="劳动";break;case"6.1":c="儿童";break;case"9.10":c="教师";break;case"10.1":c="国庆"}c&&(a.innerHTML=c),c=null},c.viewYears=function(a){var b=c.query,d="";c.each(new Array(14),function(b){d+=7===b?"<li "+(parseInt(h.year.value)===a?'class="'+h[2]+'"':"")+' y="'+a+'">'+a+"年</li>":'<li y="'+(a-7+b)+'">'+(a-7+b)+"年</li>"}),b("#laydate_ys").innerHTML=d,c.each(b("#laydate_ys li"),function(a,b){"y"===c.checkVoid(b.getAttribute("y"))[0]?c.addClass(b,h[1]):c.on(b,"click",function(a){c.stopmp(a).reshow(),c.viewDate(0|this.getAttribute("y"),c.ymd[1],c.ymd[2])})})},c.initDate=function(){var d=(c.query,new Date),e=c.elem[h.elemv].match(/\d+/g)||[];e.length<3&&(e=c.options.start.match(/\d+/g)||[],e.length<3&&(e=[d.getFullYear(),d.getMonth()+1,d.getDate()])),c.inymd=e,c.viewDate(e[0],e[1]-1,e[2])},c.iswrite=function(){var a=c.query,b={time:a("#laydate_hms")};c.shde(b.time,!c.options.istime),c.shde(h.oclear,!("isclear"in c.options?c.options.isclear:1)),c.shde(h.otoday,!("istoday"in c.options?c.options.istoday:1)),c.shde(h.ok,!("issure"in c.options?c.options.issure:1))},c.orien=function(a,b){var d,e=c.elem.getBoundingClientRect();a.style.left=e.left+(b?0:c.scroll(1))+"px",d=e.bottom+a.offsetHeight/1.5<=c.winarea()?e.bottom-1:e.top>a.offsetHeight/1.5?e.top-a.offsetHeight+1:c.winarea()-a.offsetHeight,a.style.top=d+(b?0:c.scroll())+"px"},c.follow=function(a){c.options.fixed?(a.style.position="fixed",c.orien(a,1)):(a.style.position="absolute",c.orien(a))},c.viewtb=function(){var a,b=[],f=["日","一","二","三","四","五","六"],h={},i=d[e]("table"),j=d[e]("thead");return j.appendChild(d[e]("tr")),h.creath=function(a){var b=d[e]("th");b.innerHTML=f[a],j[g]("tr")[0].appendChild(b),b=null},c.each(new Array(6),function(d){b.push([]),a=i.insertRow(0),c.each(new Array(7),function(c){b[d][c]=0,0===d&&h.creath(c),a.insertCell(c)})}),i.insertBefore(j,i.children[0]),i.id=i.className="laydate_table",a=b=null,i.outerHTML.toLowerCase()}(),c.view=function(a,f){var i,g=c.query,j={};f=f||a,c.elem=a,c.options=f,c.options.format||(c.options.format=b.format),c.options.start=c.options.start||"",c.mm=j.mm=[c.options.min||b.min,c.options.max||b.max],c.mins=j.mm[0].match(/\d+/g),c.maxs=j.mm[1].match(/\d+/g),h.elemv=/textarea|input/.test(c.elem.tagName.toLocaleLowerCase())?"value":"innerHTML",c.box?c.shde(c.box):(i=d[e]("div"),i.id=h[0],i.className=h[0],i.style.cssText="position: absolute;",i.setAttribute("name","laydate-v"+laydate.v),i.innerHTML=j.html='<div class="laydate_top"><div class="laydate_ym laydate_y" id="laydate_YY"><a class="laydate_choose laydate_chprev laydate_tab"><cite></cite></a><input id="laydate_y" readonly><label></label><a class="laydate_choose laydate_chnext laydate_tab"><cite></cite></a><div class="laydate_yms"><a class="laydate_tab laydate_chtop"><cite></cite></a><ul id="laydate_ys"></ul><a class="laydate_tab laydate_chdown"><cite></cite></a></div></div><div class="laydate_ym laydate_m" id="laydate_MM"><a class="laydate_choose laydate_chprev laydate_tab"><cite></cite></a><input id="laydate_m" readonly><label></label><a class="laydate_choose laydate_chnext laydate_tab"><cite></cite></a><div class="laydate_yms" id="laydate_ms">'+function(){var a="";return c.each(new Array(12),function(b){a+='<span m="'+b+'">'+c.digit(b+1)+"月</span>"}),a}()+"</div>"+"</div>"+"</div>"+c.viewtb+'<div class="laydate_bottom">'+'<ul id="laydate_hms">'+'<li class="laydate_sj">时间</li>'+"<li><input readonly>:</li>"+"<li><input readonly>:</li>"+"<li><input readonly></li>"+"</ul>"+'<div class="laydate_time" id="laydate_time"></div>'+'<div class="laydate_btn">'+'<a id="laydate_clear">清空</a>'+'<a id="laydate_today">今天</a>'+'<a id="laydate_ok">确认</a>'+"</div>"+(b.isv?'<a href="http://sentsin.com/layui/laydate/" class="laydate_v" target="_blank">laydate-v'+laydate.v+"</a>":"")+"</div>",d.body.appendChild(i),c.box=g("#"+h[0]),c.events(),i=null),c.follow(c.box),f.zIndex?c.box.style.zIndex=f.zIndex:c.removeCssAttr(c.box,"z-index"),c.stopMosup("click",c.box),c.initDate(),c.iswrite(),c.check()},c.reshow=function(){return c.each(c.query("#"+h[0]+" .laydate_show"),function(a,b){c.removeClass(b,"laydate_show")}),this},c.close=function(){c.reshow(),c.shde(c.query("#"+h[0]),1),c.elem=null},c.parse=function(a,d,e){return a=a.concat(d),e=e||(c.options?c.options.format:b.format),e.replace(/YYYY|MM|DD|hh|mm|ss/g,function(){return a.index=0|++a.index,c.digit(a[a.index])})},c.creation=function(a,b){var e=(c.query,c.hmsin),f=c.parse(a,[e[0].value,e[1].value,e[2].value]);c.elem[h.elemv]=f,b||(c.close(),"function"==typeof c.options.choose&&c.options.choose(f))},c.events=function(){var b=c.query,e={box:"#"+h[0]};c.addClass(d.body,"laydate_body"),h.tds=b("#laydate_table td"),h.mms=b("#laydate_ms span"),h.year=b("#laydate_y"),h.month=b("#laydate_m"),c.each(b(e.box+" .laydate_ym"),function(a,b){c.on(b,"click",function(b){c.stopmp(b).reshow(),c.addClass(this[g]("div")[0],"laydate_show"),a||(e.YY=parseInt(h.year.value),c.viewYears(e.YY))})}),c.on(b(e.box),"click",function(){c.reshow()}),e.tabYear=function(a){0===a?c.ymd[0]--:1===a?c.ymd[0]++:2===a?e.YY-=14:e.YY+=14,2>a?(c.viewDate(c.ymd[0],c.ymd[1],c.ymd[2]),c.reshow()):c.viewYears(e.YY)},c.each(b("#laydate_YY .laydate_tab"),function(a,b){c.on(b,"click",function(b){c.stopmp(b),e.tabYear(a)})}),e.tabMonth=function(a){a?(c.ymd[1]++,12===c.ymd[1]&&(c.ymd[0]++,c.ymd[1]=0)):(c.ymd[1]--,-1===c.ymd[1]&&(c.ymd[0]--,c.ymd[1]=11)),c.viewDate(c.ymd[0],c.ymd[1],c.ymd[2])},c.each(b("#laydate_MM .laydate_tab"),function(a,b){c.on(b,"click",function(b){c.stopmp(b).reshow(),e.tabMonth(a)})}),c.each(b("#laydate_ms span"),function(a,b){c.on(b,"click",function(a){c.stopmp(a).reshow(),c.hasClass(this,h[1])||c.viewDate(c.ymd[0],0|this.getAttribute("m"),c.ymd[2])})}),c.each(b("#laydate_table td"),function(a,b){c.on(b,"click",function(a){c.hasClass(this,h[1])||(c.stopmp(a),c.creation([0|this.getAttribute("y"),0|this.getAttribute("m"),0|this.getAttribute("d")]))})}),h.oclear=b("#laydate_clear"),c.on(h.oclear,"click",function(){c.elem[h.elemv]="",c.close()}),h.otoday=b("#laydate_today"),c.on(h.otoday,"click",function(){c.elem[h.elemv]=laydate.now(0,c.options.format),c.close()}),h.ok=b("#laydate_ok"),c.on(h.ok,"click",function(){c.valid&&c.creation([c.ymd[0],c.ymd[1]+1,c.ymd[2]])}),e.times=b("#laydate_time"),c.hmsin=e.hmsin=b("#laydate_hms input"),e.hmss=["小时","分钟","秒数"],e.hmsarr=[],c.msg=function(a,d){var f='<div class="laydte_hsmtex">'+(d||"提示")+"<span>×</span></div>";"string"==typeof a?(f+="<p>"+a+"</p>",c.shde(b("#"+h[0])),c.removeClass(e.times,"laydate_time1").addClass(e.times,"laydate_msg")):(e.hmsarr[a]?f=e.hmsarr[a]:(f+='<div id="laydate_hmsno" class="laydate_hmsno">',c.each(new Array(0===a?24:60),function(a){f+="<span>"+a+"</span>"}),f+="</div>",e.hmsarr[a]=f),c.removeClass(e.times,"laydate_msg"),c[0===a?"removeClass":"addClass"](e.times,"laydate_time1")),c.addClass(e.times,"laydate_show"),e.times.innerHTML=f},e.hmson=function(a,d){var e=b("#laydate_hmsno span"),f=c.valid?null:1;c.each(e,function(b,e){f?c.addClass(e,h[1]):c.timeVoid(b,d)?c.addClass(e,h[1]):c.on(e,"click",function(){c.hasClass(this,h[1])||(a.value=c.digit(0|this.innerHTML))})}),c.addClass(e[0|a.value],"laydate_click")},c.each(e.hmsin,function(a,b){c.on(b,"click",function(b){c.stopmp(b).reshow(),c.msg(a,e.hmss[a]),e.hmson(this,a)})}),c.on(d,"mouseup",function(){var a=b("#"+h[0]);a&&"none"!==a.style.display&&(c.check()||c.close())}).on(d,"keydown",function(b){b=b||a.event;var d=b.keyCode;13===d&&c.creation([c.ymd[0],c.ymd[1]+1,c.ymd[2]])})},c.init=function(){c.use("need"),c.use(h[4]+b.defSkin,h[3]),c.skinLink=c.query("#"+h[3])}(),laydate.reset=function(){c.box&&c.elem&&c.follow(c.box)},laydate.now=function(a,b){var d=new Date(0|a?function(a){return 864e5>a?+new Date+864e5*a:a}(parseInt(a)):+new Date);return c.parse([d.getFullYear(),d.getMonth()+1,d.getDate()],[d.getHours(),d.getMinutes(),d.getSeconds()],b)},laydate.skin=function(a){c.skinLink.href=c.getPath+h[4]+a+h[5]}}(window); \ No newline at end of file diff --git a/static/plugins/layer/layer.js b/static/plugins/layer/layer.js new file mode 100755 index 0000000..c6c528d --- /dev/null +++ b/static/plugins/layer/layer.js @@ -0,0 +1,14 @@ +/*! layer-v2.4 弹层组件 License LGPL http://layer.layui.com/ By 贤心 */ +;!function(a,b){"use strict";var c,d,e={getPath:function(){var a=document.scripts,b=a[a.length-1],c=b.src;if(!b.getAttribute("merge"))return c.substring(0,c.lastIndexOf("/")+1)}(),enter:function(a){13===a.keyCode&&a.preventDefault()},config:{},end:{},btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],type:["dialog","page","iframe","loading","tips"]},f={v:"2.4",ie6:!!a.ActiveXObject&&!a.XMLHttpRequest,index:0,path:e.getPath,config:function(a,b){var d=0;return a=a||{},f.cache=e.config=c.extend(e.config,a),f.path=e.config.path||f.path,"string"==typeof a.extend&&(a.extend=[a.extend]),f.use("skin/layer.css",a.extend&&a.extend.length>0?function g(){var c=a.extend;f.use(c[c[d]?d:d-1],d<c.length?function(){return++d,g}():b)}():b),this},use:function(a,b,d){var e=c("head")[0],a=a.replace(/\s/g,""),g=/\.css$/.test(a),h=document.createElement(g?"link":"script"),i="layui_layer_"+a.replace(/\.|\//g,"");return f.path?(g&&(h.rel="stylesheet"),h[g?"href":"src"]=/^http:\/\//.test(a)?a:f.path+a,h.id=i,c("#"+i)[0]||e.appendChild(h),function j(){(g?1989===parseInt(c("#"+i).css("width")):f[d||i])?function(){b&&b();try{g||e.removeChild(h)}catch(a){}}():setTimeout(j,100)}(),this):void 0},ready:function(a,b){var d="function"==typeof a;return d&&(b=a),f.config(c.extend(e.config,function(){return d?{}:{path:a}}()),b),this},alert:function(a,b,d){var e="function"==typeof b;return e&&(d=b),f.open(c.extend({content:a,yes:d},e?{}:b))},confirm:function(a,b,d,g){var h="function"==typeof b;return h&&(g=d,d=b),f.open(c.extend({content:a,btn:e.btn,yes:d,btn2:g},h?{}:b))},msg:function(a,d,g){var i="function"==typeof d,j=e.config.skin,k=(j?j+" "+j+"-msg":"")||"layui-layer-msg",l=h.anim.length-1;return i&&(g=d),f.open(c.extend({content:a,time:3e3,shade:!1,skin:k,title:!1,closeBtn:!1,btn:!1,end:g},i&&!e.config.skin?{skin:k+" layui-layer-hui",shift:l}:function(){return d=d||{},(-1===d.icon||d.icon===b&&!e.config.skin)&&(d.skin=k+" "+(d.skin||"layui-layer-hui")),d}()))},load:function(a,b){return f.open(c.extend({type:3,icon:a||0,shade:.01},b))},tips:function(a,b,d){return f.open(c.extend({type:4,content:[a,b],closeBtn:!1,time:3e3,shade:!1,fix:!1,maxWidth:210},d))}},g=function(a){var b=this;b.index=++f.index,b.config=c.extend({},b.config,e.config,a),b.creat()};g.pt=g.prototype;var h=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];h.anim=["layer-anim","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],g.pt.config={type:0,shade:.3,fix:!0,move:h[1],title:"&#x4FE1;&#x606F;",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,shift:0,icon:-1,scrollbar:!0,tips:2},g.pt.vessel=function(a,b){var c=this,d=c.index,f=c.config,g=f.zIndex+d,i="object"==typeof f.title,j=f.maxmin&&(1===f.type||2===f.type),k=f.title?'<div class="layui-layer-title" style="'+(i?f.title[1]:"")+'">'+(i?f.title[0]:f.title)+"</div>":"";return f.zIndex=g,b([f.shade?'<div class="layui-layer-shade" id="layui-layer-shade'+d+'" times="'+d+'" style="'+("z-index:"+(g-1)+"; background-color:"+(f.shade[1]||"#000")+"; opacity:"+(f.shade[0]||f.shade)+"; filter:alpha(opacity="+(100*f.shade[0]||100*f.shade)+");")+'"></div>':"",'<div class="'+h[0]+(" layui-layer-"+e.type[f.type])+(0!=f.type&&2!=f.type||f.shade?"":" layui-layer-border")+" "+(f.skin||"")+'" id="'+h[0]+d+'" type="'+e.type[f.type]+'" times="'+d+'" showtime="'+f.time+'" conType="'+(a?"object":"string")+'" style="z-index: '+g+"; width:"+f.area[0]+";height:"+f.area[1]+(f.fix?"":";position:absolute;")+'">'+(a&&2!=f.type?"":k)+'<div id="'+(f.id||"")+'" class="layui-layer-content'+(0==f.type&&-1!==f.icon?" layui-layer-padding":"")+(3==f.type?" layui-layer-loading"+f.icon:"")+'">'+(0==f.type&&-1!==f.icon?'<i class="layui-layer-ico layui-layer-ico'+f.icon+'"></i>':"")+(1==f.type&&a?"":f.content||"")+'</div><span class="layui-layer-setwin">'+function(){var a=j?'<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>':"";return f.closeBtn&&(a+='<a class="layui-layer-ico '+h[7]+" "+h[7]+(f.title?f.closeBtn:4==f.type?"1":"2")+'" href="javascript:;"></a>'),a}()+"</span>"+(f.btn?function(){var a="";"string"==typeof f.btn&&(f.btn=[f.btn]);for(var b=0,c=f.btn.length;c>b;b++)a+='<a class="'+h[6]+b+'">'+f.btn[b]+"</a>";return'<div class="'+h[6]+'">'+a+"</div>"}():"")+"</div>"],k),c},g.pt.creat=function(){var a=this,b=a.config,g=a.index,i=b.content,j="object"==typeof i;if(!c("#"+b.id)[0]){switch("string"==typeof b.area&&(b.area="auto"===b.area?["",""]:[b.area,""]),b.type){case 0:b.btn="btn"in b?b.btn:e.btn[0],f.closeAll("dialog");break;case 2:var i=b.content=j?b.content:[b.content||"http://layer.layui.com","auto"];b.content='<iframe scrolling="'+(b.content[1]||"auto")+'" allowtransparency="true" id="'+h[4]+g+'" name="'+h[4]+g+'" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="'+b.content[0]+'"></iframe>';break;case 3:b.title=!1,b.closeBtn=!1,-1===b.icon&&0===b.icon,f.closeAll("loading");break;case 4:j||(b.content=[b.content,"body"]),b.follow=b.content[1],b.content=b.content[0]+'<i class="layui-layer-TipsG"></i>',b.title=!1,b.tips="object"==typeof b.tips?b.tips:[b.tips,!0],b.tipsMore||f.closeAll("tips")}a.vessel(j,function(d,e){c("body").append(d[0]),j?function(){2==b.type||4==b.type?function(){c("body").append(d[1])}():function(){i.parents("."+h[0])[0]||(i.show().addClass("layui-layer-wrap").wrap(d[1]),c("#"+h[0]+g).find("."+h[5]).before(e))}()}():c("body").append(d[1]),a.layero=c("#"+h[0]+g),b.scrollbar||h.html.css("overflow","hidden").attr("layer-full",g)}).auto(g),2==b.type&&f.ie6&&a.layero.find("iframe").attr("src",i[0]),c(document).off("keydown",e.enter).on("keydown",e.enter),a.layero.on("keydown",function(a){c(document).off("keydown",e.enter)}),4==b.type?a.tips():a.offset(),b.fix&&d.on("resize",function(){a.offset(),(/^\d+%$/.test(b.area[0])||/^\d+%$/.test(b.area[1]))&&a.auto(g),4==b.type&&a.tips()}),b.time<=0||setTimeout(function(){f.close(a.index)},b.time),a.move().callback(),h.anim[b.shift]&&a.layero.addClass(h.anim[b.shift])}},g.pt.auto=function(a){function b(a){a=g.find(a),a.height(i[1]-j-k-2*(0|parseFloat(a.css("padding"))))}var e=this,f=e.config,g=c("#"+h[0]+a);""===f.area[0]&&f.maxWidth>0&&(/MSIE 7/.test(navigator.userAgent)&&f.btn&&g.width(g.innerWidth()),g.outerWidth()>f.maxWidth&&g.width(f.maxWidth));var i=[g.innerWidth(),g.innerHeight()],j=g.find(h[1]).outerHeight()||0,k=g.find("."+h[6]).outerHeight()||0;switch(f.type){case 2:b("iframe");break;default:""===f.area[1]?f.fix&&i[1]>=d.height()&&(i[1]=d.height(),b("."+h[5])):b("."+h[5])}return e},g.pt.offset=function(){var a=this,b=a.config,c=a.layero,e=[c.outerWidth(),c.outerHeight()],f="object"==typeof b.offset;a.offsetTop=(d.height()-e[1])/2,a.offsetLeft=(d.width()-e[0])/2,f?(a.offsetTop=b.offset[0],a.offsetLeft=b.offset[1]||a.offsetLeft):"auto"!==b.offset&&(a.offsetTop=b.offset,"rb"===b.offset&&(a.offsetTop=d.height()-e[1],a.offsetLeft=d.width()-e[0])),b.fix||(a.offsetTop=/%$/.test(a.offsetTop)?d.height()*parseFloat(a.offsetTop)/100:parseFloat(a.offsetTop),a.offsetLeft=/%$/.test(a.offsetLeft)?d.width()*parseFloat(a.offsetLeft)/100:parseFloat(a.offsetLeft),a.offsetTop+=d.scrollTop(),a.offsetLeft+=d.scrollLeft()),c.css({top:a.offsetTop,left:a.offsetLeft})},g.pt.tips=function(){var a=this,b=a.config,e=a.layero,f=[e.outerWidth(),e.outerHeight()],g=c(b.follow);g[0]||(g=c("body"));var i={width:g.outerWidth(),height:g.outerHeight(),top:g.offset().top,left:g.offset().left},j=e.find(".layui-layer-TipsG"),k=b.tips[0];b.tips[1]||j.remove(),i.autoLeft=function(){i.left+f[0]-d.width()>0?(i.tipLeft=i.left+i.width-f[0],j.css({right:12,left:"auto"})):i.tipLeft=i.left},i.where=[function(){i.autoLeft(),i.tipTop=i.top-f[1]-10,j.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",b.tips[1])},function(){i.tipLeft=i.left+i.width+10,i.tipTop=i.top,j.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",b.tips[1])},function(){i.autoLeft(),i.tipTop=i.top+i.height+10,j.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",b.tips[1])},function(){i.tipLeft=i.left-f[0]-10,i.tipTop=i.top,j.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",b.tips[1])}],i.where[k-1](),1===k?i.top-(d.scrollTop()+f[1]+16)<0&&i.where[2]():2===k?d.width()-(i.left+i.width+f[0]+16)>0||i.where[3]():3===k?i.top-d.scrollTop()+i.height+f[1]+16-d.height()>0&&i.where[0]():4===k&&f[0]+16-i.left>0&&i.where[1](),e.find("."+h[5]).css({"background-color":b.tips[1],"padding-right":b.closeBtn?"30px":""}),e.css({left:i.tipLeft-(b.fix?d.scrollLeft():0),top:i.tipTop-(b.fix?d.scrollTop():0)})},g.pt.move=function(){var a=this,b=a.config,e={setY:0,moveLayer:function(){var a=e.layero,b=parseInt(a.css("margin-left")),c=parseInt(e.move.css("left"));0===b||(c-=b),"fixed"!==a.css("position")&&(c-=a.parent().offset().left,e.setY=0),a.css({left:c,top:parseInt(e.move.css("top"))-e.setY})}},f=a.layero.find(b.move);return b.move&&f.attr("move","ok"),f.css({cursor:b.move?"move":"auto"}),c(b.move).on("mousedown",function(a){if(a.preventDefault(),"ok"===c(this).attr("move")){e.ismove=!0,e.layero=c(this).parents("."+h[0]);var f=e.layero.offset().left,g=e.layero.offset().top,i=e.layero.outerWidth()-6,j=e.layero.outerHeight()-6;c("#layui-layer-moves")[0]||c("body").append('<div id="layui-layer-moves" class="layui-layer-moves" style="left:'+f+"px; top:"+g+"px; width:"+i+"px; height:"+j+'px; z-index:2147483584"></div>'),e.move=c("#layui-layer-moves"),b.moveType&&e.move.css({visibility:"hidden"}),e.moveX=a.pageX-e.move.position().left,e.moveY=a.pageY-e.move.position().top,"fixed"!==e.layero.css("position")||(e.setY=d.scrollTop())}}),c(document).mousemove(function(a){if(e.ismove){var c=a.pageX-e.moveX,f=a.pageY-e.moveY;if(a.preventDefault(),!b.moveOut){e.setY=d.scrollTop();var g=d.width()-e.move.outerWidth(),h=e.setY;0>c&&(c=0),c>g&&(c=g),h>f&&(f=h),f>d.height()-e.move.outerHeight()+e.setY&&(f=d.height()-e.move.outerHeight()+e.setY)}e.move.css({left:c,top:f}),b.moveType&&e.moveLayer(),c=f=g=h=null}}).mouseup(function(){try{e.ismove&&(e.moveLayer(),e.move.remove(),b.moveEnd&&b.moveEnd()),e.ismove=!1}catch(a){e.ismove=!1}}),a},g.pt.callback=function(){function a(){var a=g.cancel&&g.cancel(b.index,d);a===!1||f.close(b.index)}var b=this,d=b.layero,g=b.config;b.openLayer(),g.success&&(2==g.type?d.find("iframe").on("load",function(){g.success(d,b.index)}):g.success(d,b.index)),f.ie6&&b.IE6(d),d.find("."+h[6]).children("a").on("click",function(){var a=c(this).index();if(0===a)g.yes?g.yes(b.index,d):g.btn1?g.btn1(b.index,d):f.close(b.index);else{var e=g["btn"+(a+1)]&&g["btn"+(a+1)](b.index,d);e===!1||f.close(b.index)}}),d.find("."+h[7]).on("click",a),g.shadeClose&&c("#layui-layer-shade"+b.index).on("click",function(){f.close(b.index)}),d.find(".layui-layer-min").on("click",function(){var a=g.min&&g.min(d);a===!1||f.min(b.index,g)}),d.find(".layui-layer-max").on("click",function(){c(this).hasClass("layui-layer-maxmin")?(f.restore(b.index),g.restore&&g.restore(d)):(f.full(b.index,g),setTimeout(function(){g.full&&g.full(d)},100))}),g.end&&(e.end[b.index]=g.end)},e.reselect=function(){c.each(c("select"),function(a,b){var d=c(this);d.parents("."+h[0])[0]||1==d.attr("layer")&&c("."+h[0]).length<1&&d.removeAttr("layer").show(),d=null})},g.pt.IE6=function(a){function b(){a.css({top:f+(e.config.fix?d.scrollTop():0)})}var e=this,f=a.offset().top;b(),d.scroll(b),c("select").each(function(a,b){var d=c(this);d.parents("."+h[0])[0]||"none"===d.css("display")||d.attr({layer:"1"}).hide(),d=null})},g.pt.openLayer=function(){var a=this;f.zIndex=a.config.zIndex,f.setTop=function(a){var b=function(){f.zIndex++,a.css("z-index",f.zIndex+1)};return f.zIndex=parseInt(a[0].style.zIndex),a.on("mousedown",b),f.zIndex}},e.record=function(a){var b=[a.width(),a.height(),a.position().top,a.position().left+parseFloat(a.css("margin-left"))];a.find(".layui-layer-max").addClass("layui-layer-maxmin"),a.attr({area:b})},e.rescollbar=function(a){h.html.attr("layer-full")==a&&(h.html[0].style.removeProperty?h.html[0].style.removeProperty("overflow"):h.html[0].style.removeAttribute("overflow"),h.html.removeAttr("layer-full"))},a.layer=f,f.getChildFrame=function(a,b){return b=b||c("."+h[4]).attr("times"),c("#"+h[0]+b).find("iframe").contents().find(a)},f.getFrameIndex=function(a){return c("#"+a).parents("."+h[4]).attr("times")},f.iframeAuto=function(a){if(a){var b=f.getChildFrame("html",a).outerHeight(),d=c("#"+h[0]+a),e=d.find(h[1]).outerHeight()||0,g=d.find("."+h[6]).outerHeight()||0;d.css({height:b+e+g}),d.find("iframe").css({height:b})}},f.iframeSrc=function(a,b){c("#"+h[0]+a).find("iframe").attr("src",b)},f.style=function(a,b){var d=c("#"+h[0]+a),f=d.attr("type"),g=d.find(h[1]).outerHeight()||0,i=d.find("."+h[6]).outerHeight()||0;(f===e.type[1]||f===e.type[2])&&(d.css(b),f===e.type[2]&&d.find("iframe").css({height:parseFloat(b.height)-g-i}))},f.min=function(a,b){var d=c("#"+h[0]+a),g=d.find(h[1]).outerHeight()||0;e.record(d),f.style(a,{width:180,height:g,overflow:"hidden"}),d.find(".layui-layer-min").hide(),"page"===d.attr("type")&&d.find(h[4]).hide(),e.rescollbar(a)},f.restore=function(a){var b=c("#"+h[0]+a),d=b.attr("area").split(",");b.attr("type");f.style(a,{width:parseFloat(d[0]),height:parseFloat(d[1]),top:parseFloat(d[2]),left:parseFloat(d[3]),overflow:"visible"}),b.find(".layui-layer-max").removeClass("layui-layer-maxmin"),b.find(".layui-layer-min").show(),"page"===b.attr("type")&&b.find(h[4]).show(),e.rescollbar(a)},f.full=function(a){var b,g=c("#"+h[0]+a);e.record(g),h.html.attr("layer-full")||h.html.css("overflow","hidden").attr("layer-full",a),clearTimeout(b),b=setTimeout(function(){var b="fixed"===g.css("position");f.style(a,{top:b?0:d.scrollTop(),left:b?0:d.scrollLeft(),width:d.width(),height:d.height()}),g.find(".layui-layer-min").hide()},100)},f.title=function(a,b){var d=c("#"+h[0]+(b||f.index)).find(h[1]);d.html(a)},f.close=function(a){var b=c("#"+h[0]+a),d=b.attr("type");if(b[0]){if(d===e.type[1]&&"object"===b.attr("conType")){b.children(":not(."+h[5]+")").remove();for(var g=0;2>g;g++)b.find(".layui-layer-wrap").unwrap().hide()}else{if(d===e.type[2])try{var i=c("#"+h[4]+a)[0];i.contentWindow.document.write(""),i.contentWindow.close(),b.find("."+h[5])[0].removeChild(i)}catch(j){}b[0].innerHTML="",b.remove()}c("#layui-layer-moves, #layui-layer-shade"+a).remove(),f.ie6&&e.reselect(),e.rescollbar(a),c(document).off("keydown",e.enter),"function"==typeof e.end[a]&&e.end[a](),delete e.end[a]}},f.closeAll=function(a){c.each(c("."+h[0]),function(){var b=c(this),d=a?b.attr("type")===a:1;d&&f.close(b.attr("times")),d=null})};var i=f.cache||{},j=function(a){return i.skin?" "+i.skin+" "+i.skin+"-"+a:""};f.prompt=function(a,b){a=a||{},"function"==typeof a&&(b=a);var d,e=2==a.formType?'<textarea class="layui-layer-input">'+(a.value||"")+"</textarea>":function(){return'<input type="'+(1==a.formType?"password":"text")+'" class="layui-layer-input" value="'+(a.value||"")+'">'}();return f.open(c.extend({btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],content:e,skin:"layui-layer-prompt"+j("prompt"),success:function(a){d=a.find(".layui-layer-input"),d.focus()},yes:function(c){var e=d.val();""===e?d.focus():e.length>(a.maxlength||500)?f.tips("&#x6700;&#x591A;&#x8F93;&#x5165;"+(a.maxlength||500)+"&#x4E2A;&#x5B57;&#x6570;",d,{tips:1}):b&&b(e,c,d)}},a))},f.tab=function(a){a=a||{};var b=a.tab||{};return f.open(c.extend({type:1,skin:"layui-layer-tab"+j("tab"),title:function(){var a=b.length,c=1,d="";if(a>0)for(d='<span class="layui-layer-tabnow">'+b[0].title+"</span>";a>c;c++)d+="<span>"+b[c].title+"</span>";return d}(),content:'<ul class="layui-layer-tabmain">'+function(){var a=b.length,c=1,d="";if(a>0)for(d='<li class="layui-layer-tabli xubox_tab_layer">'+(b[0].content||"no content")+"</li>";a>c;c++)d+='<li class="layui-layer-tabli">'+(b[c].content||"no content")+"</li>";return d}()+"</ul>",success:function(b){var d=b.find(".layui-layer-title").children(),e=b.find(".layui-layer-tabmain").children();d.on("mousedown",function(b){b.stopPropagation?b.stopPropagation():b.cancelBubble=!0;var d=c(this),f=d.index();d.addClass("layui-layer-tabnow").siblings().removeClass("layui-layer-tabnow"),e.eq(f).show().siblings().hide(),"function"==typeof a.change&&a.change(f)})}},a))},f.photos=function(b,d,e){function g(a,b,c){var d=new Image;return d.src=a,d.complete?b(d):(d.onload=function(){d.onload=null,b(d)},void(d.onerror=function(a){d.onerror=null,c(a)}))}var h={};if(b=b||{},b.photos){var i=b.photos.constructor===Object,k=i?b.photos:{},l=k.data||[],m=k.start||0;if(h.imgIndex=(0|m)+1,b.img=b.img||"img",i){if(0===l.length)return f.msg("&#x6CA1;&#x6709;&#x56FE;&#x7247;")}else{var n=c(b.photos),o=function(){l=[],n.find(b.img).each(function(a){var b=c(this);b.attr("layer-index",a),l.push({alt:b.attr("alt"),pid:b.attr("layer-pid"),src:b.attr("layer-src")||b.attr("src"),thumb:b.attr("src")})})};if(o(),0===l.length)return;if(d||n.on("click",b.img,function(){var a=c(this),d=a.attr("layer-index");f.photos(c.extend(b,{photos:{start:d,data:l,tab:b.tab},full:b.full}),!0),o()}),!d)return}h.imgprev=function(a){h.imgIndex--,h.imgIndex<1&&(h.imgIndex=l.length),h.tabimg(a)},h.imgnext=function(a,b){h.imgIndex++,h.imgIndex>l.length&&(h.imgIndex=1,b)||h.tabimg(a)},h.keyup=function(a){if(!h.end){var b=a.keyCode;a.preventDefault(),37===b?h.imgprev(!0):39===b?h.imgnext(!0):27===b&&f.close(h.index)}},h.tabimg=function(a){l.length<=1||(k.start=h.imgIndex-1,f.close(h.index),f.photos(b,!0,a))},h.event=function(){h.bigimg.hover(function(){h.imgsee.show()},function(){h.imgsee.hide()}),h.bigimg.find(".layui-layer-imgprev").on("click",function(a){a.preventDefault(),h.imgprev()}),h.bigimg.find(".layui-layer-imgnext").on("click",function(a){a.preventDefault(),h.imgnext()}),c(document).on("keyup",h.keyup)},h.loadi=f.load(1,{shade:"shade"in b?!1:.9,scrollbar:!1}),g(l[m].src,function(d){f.close(h.loadi),h.index=f.open(c.extend({type:1,area:function(){var e=[d.width,d.height],f=[c(a).width()-50,c(a).height()-50];return!b.full&&e[0]>f[0]&&(e[0]=f[0],e[1]=e[0]*d.height/d.width),[e[0]+"px",e[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,shift:5*Math.random()|0,skin:"layui-layer-photos"+j("photos"),content:'<div class="layui-layer-phimg"><img src="'+l[m].src+'" alt="'+(l[m].alt||"")+'" layer-pid="'+l[m].pid+'"><div class="layui-layer-imgsee">'+(l.length>1?'<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>':"")+'<div class="layui-layer-imgbar" style="display:'+(e?"block":"")+'"><span class="layui-layer-imgtit"><a href="javascript:;">'+(l[m].alt||"")+"</a><em>"+h.imgIndex+"/"+l.length+"</em></span></div></div></div>",success:function(a,c){h.bigimg=a.find(".layui-layer-phimg"),h.imgsee=a.find(".layui-layer-imguide,.layui-layer-imgbar"),h.event(a),b.tab&&b.tab(l[m],a)},end:function(){h.end=!0,c(document).off("keyup",h.keyup)}},b))},function(){f.close(h.loadi),f.msg("&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;",{time:3e4,btn:["&#x4E0B;&#x4E00;&#x5F20;","&#x4E0D;&#x770B;&#x4E86;"],yes:function(){l.length>1&&h.imgnext(!0,!0)}})})}},e.run=function(){c=jQuery,d=c(a),h.html=c("html"),f.open=function(a){var b=new g(a);return b.index}},"function"==typeof define?define(function(){return e.run(),f}):function(){e.run(),f.use("skin/layer.css")}()}(window); + +/** + +@Name:laytpl-v1.1 精妙的js模板引擎 +@Author:贤心 - 2014-08-16 +@Site:http://sentsin.com/layui/laytpl +@License:MIT license +*/ +;!function(){"use strict";var f,b={open:"{{",close:"}}"},c={exp:function(a){return new RegExp(a,"g")},query:function(a,c,e){var f=["#([\\s\\S])+?","([^{#}])*?"][a||0];return d((c||"")+b.open+f+b.close+(e||""))},escape:function(a){return String(a||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(a,b){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+a+"\n"+(b||"")),c+a}},d=c.exp,e=function(a){this.tpl=a};e.pt=e.prototype,e.pt.parse=function(a,e){var f=this,g=a,h=d("^"+b.open+"#",""),i=d(b.close+"$","");a=a.replace(/[\r\t\n]/g," ").replace(d(b.open+"#"),b.open+"# ").replace(d(b.close+"}"),"} "+b.close).replace(/\\/g,"\\\\").replace(/(?="|')/g,"\\").replace(c.query(),function(a){return a=a.replace(h,"").replace(i,""),'";'+a.replace(/\\/g,"")+'; view+="'}).replace(c.query(1),function(a){var c='"+(';return a.replace(/\s/g,"")===b.open+b.close?"":(a=a.replace(d(b.open+"|"+b.close),""),/^=/.test(a)&&(a=a.replace(/^=/,""),c='"+_escape_('),c+a.replace(/\\/g,"")+')+"')}),a='"use strict";var view = "'+a+'";return view;';try{return f.cache=a=new Function("d, _escape_",a),a(e,c.escape)}catch(j){return delete f.cache,c.error(j,g)}},e.pt.render=function(a,b){var e,d=this;return a?(e=d.cache?d.cache(a,c.escape):d.parse(d.tpl,a),b?(b(e),void 0):e):c.error("no data")},f=function(a){return"string"!=typeof a?c.error("Template not found"):new e(a)},f.config=function(a){a=a||{};for(var c in a)b[c]=a[c]},f.v="1.1","function"==typeof define?define(function(){return f}):"undefined"!=typeof exports?module.exports=f:window.laytpl=f}(); +/*! layPage-v1.3.0 分页组件 License MIT http://laypage.layui.com/ By 贤心 */ +;!function(){"use strict";function a(d){var e="laypagecss";a.dir="dir"in a?a.dir:f.getpath+"/skin/laypage.css",new f(d),a.dir&&!b[c](e)&&f.use(a.dir,e)}a.v="1.3";var b=document,c="getElementById",d="getElementsByTagName",e=0,f=function(a){var b=this,c=b.config=a||{};c.item=e++,b.render(!0)};f.on=function(a,b,c){return a.attachEvent?a.attachEvent("on"+b,function(){c.call(a,window.even)}):a.addEventListener(b,c,!1),f},f.getpath=function(){var a=document.scripts,b=a[a.length-1].src;return b.substring(0,b.lastIndexOf("/")+1)}(),f.use=function(c,e){var f=b.createElement("link");f.type="text/css",f.rel="stylesheet",f.href=a.dir,e&&(f.id=e),b[d]("head")[0].appendChild(f),f=null},f.prototype.type=function(){var a=this.config;return"object"==typeof a.cont?void 0===a.cont.length?2:3:void 0},f.prototype.view=function(){var b=this,c=b.config,d=[],e={};if(c.pages=0|c.pages,c.curr=0|c.curr||1,c.groups="groups"in c?0|c.groups:5,c.first="first"in c?c.first:"&#x9996;&#x9875;",c.last="last"in c?c.last:"&#x5C3E;&#x9875;",c.prev="prev"in c?c.prev:"&#x4E0A;&#x4E00;&#x9875;",c.next="next"in c?c.next:"&#x4E0B;&#x4E00;&#x9875;",c.pages<=1)return"";for(c.groups>c.pages&&(c.groups=c.pages),e.index=Math.ceil((c.curr+(c.groups>1&&c.groups!==c.pages?1:0))/(0===c.groups?1:c.groups)),c.curr>1&&c.prev&&d.push('<a href="javascript:;" class="laypage_prev" data-page="'+(c.curr-1)+'">'+c.prev+"</a>"),e.index>1&&c.first&&0!==c.groups&&d.push('<a href="javascript:;" class="laypage_first" data-page="1" title="&#x9996;&#x9875;">'+c.first+"</a><span>&#x2026;</span>"),e.poor=Math.floor((c.groups-1)/2),e.start=e.index>1?c.curr-e.poor:1,e.end=e.index>1?function(){var a=c.curr+(c.groups-e.poor-1);return a>c.pages?c.pages:a}():c.groups,e.end-e.start<c.groups-1&&(e.start=e.end-c.groups+1);e.start<=e.end;e.start++)e.start===c.curr?d.push('<span class="laypage_curr" '+(/^#/.test(c.skin)?'style="background-color:'+c.skin+'"':"")+">"+e.start+"</span>"):d.push('<a href="javascript:;" data-page="'+e.start+'">'+e.start+"</a>");return c.pages>c.groups&&e.end<c.pages&&c.last&&0!==c.groups&&d.push('<span>&#x2026;</span><a href="javascript:;" class="laypage_last" title="&#x5C3E;&#x9875;" data-page="'+c.pages+'">'+c.last+"</a>"),e.flow=!c.prev&&0===c.groups,(c.curr!==c.pages&&c.next||e.flow)&&d.push(function(){return e.flow&&c.curr===c.pages?'<span class="page_nomore" title="&#x5DF2;&#x6CA1;&#x6709;&#x66F4;&#x591A;">'+c.next+"</span>":'<a href="javascript:;" class="laypage_next" data-page="'+(c.curr+1)+'">'+c.next+"</a>"}()),'<div name="laypage'+a.v+'" class="laypage_main laypageskin_'+(c.skin?function(a){return/^#/.test(a)?"molv":a}(c.skin):"default")+'" id="laypage_'+b.config.item+'">'+d.join("")+function(){return c.skip?'<span class="laypage_total"><label>&#x5230;&#x7B2C;</label><input type="number" min="1" onkeyup="this.value=this.value.replace(/\\D/, \'\');" class="laypage_skip"><label>&#x9875;</label><button type="button" class="laypage_btn">&#x786e;&#x5b9a;</button></span>':""}()+"</div>"},f.prototype.jump=function(a){if(a){for(var b=this,c=b.config,e=a.children,g=a[d]("button")[0],h=a[d]("input")[0],i=0,j=e.length;j>i;i++)"a"===e[i].nodeName.toLowerCase()&&f.on(e[i],"click",function(){var a=0|this.getAttribute("data-page");c.curr=a,b.render()});g&&f.on(g,"click",function(){var a=0|h.value.replace(/\s|\D/g,"");a&&a<=c.pages&&(c.curr=a,b.render())})}},f.prototype.render=function(a){var d=this,e=d.config,f=d.type(),g=d.view();window['WSTCurrPage']=e.curr;2===f?e.cont.innerHTML=g:3===f?e.cont.html(g):b[c](e.cont).innerHTML=g,e.jump&&e.jump(e,a),d.jump(b[c]("laypage_"+e.item)),e.hash&&!a&&(location.hash="!"+e.hash+"="+e.curr)},"function"==typeof define?define(function(){return a}):"undefined"!=typeof exports?module.exports=a:window.laypage=a}(); + diff --git a/static/plugins/layer/need/laydate.css b/static/plugins/layer/need/laydate.css new file mode 100755 index 0000000..d6a6dbc --- /dev/null +++ b/static/plugins/layer/need/laydate.css @@ -0,0 +1,73 @@ +/** + + @Name: laydate 核心样式 + @Author:贤心 + @Site:http://sentsin.com/layui/laydate + +**/ + +html{_background-image:url(about:blank); _background-attachment:fixed;} +.laydate_body .laydate_box, .laydate_body .laydate_box *{margin:0; padding:0;} +.laydate-icon, +.laydate-icon-default, +.laydate-icon-danlan, +.laydate-icon-dahong, +.laydate-icon-molv{height:22px; line-height:22px; padding-right:20px; border:1px solid #C6C6C6; background-repeat:no-repeat; background-position:right center; background-color:#fff; outline:0;} +.laydate-icon-default{ background-image:url(../skins/default/icon.png)} +.laydate-icon-danlan{border:1px solid #B1D2EC; background-image:url(../skins/danlan/icon.png)} +.laydate-icon-dahong{background-image:url(../skins/dahong/icon.png)} +.laydate-icon-molv{background-image:url(../skins/molv/icon.png)} +.laydate_body .laydate_box{width:240px; font:12px '\5B8B\4F53'; z-index:99999999; *margin:-2px 0 0 -2px; *overflow:hidden; _margin:0; _position:absolute!important; background-color:#fff;} +.laydate_body .laydate_box li{list-style:none;} +.laydate_body .laydate_box .laydate_void{cursor:text!important;} +.laydate_body .laydate_box a, .laydate_body .laydate_box a:hover{text-decoration:none; blr:expression(this.onFocus=this.blur()); cursor:pointer;} +.laydate_body .laydate_box a:hover{text-decoration:none;} +.laydate_body .laydate_box cite, .laydate_body .laydate_box label{position:absolute; width:0; height:0; border-width:5px; border-style:dashed; border-color:transparent; overflow:hidden; cursor:pointer;} +.laydate_body .laydate_box .laydate_yms, .laydate_body .laydate_box .laydate_time{display:none;} +.laydate_body .laydate_box .laydate_show{display:block;} +.laydate_body .laydate_box input{outline:0; font-size:14px; background-color:#fff;} +.laydate_body .laydate_top{position:relative; height:26px; padding:5px; *width:100%; z-index:99;} +.laydate_body .laydate_ym{position:relative; float:left; height:24px; cursor:pointer;} +.laydate_body .laydate_ym input{float:left; height:24px; line-height:24px; text-align:center; border:none; cursor:pointer;} +.laydate_body .laydate_ym .laydate_yms{position:absolute; left: -1px; top: 24px; height:181px;} +.laydate_body .laydate_y{width:121px; margin-right:6px;} +.laydate_body .laydate_y input{width:64px; margin-right:15px;} +.laydate_body .laydate_y .laydate_yms{width:121px; text-align:center;} +.laydate_body .laydate_y .laydate_yms a{position:relative; display:block; height:20px;} +.laydate_body .laydate_y .laydate_yms ul{height:139px; padding:0; *overflow:hidden;} +.laydate_body .laydate_y .laydate_yms ul li{float:left; width:60px; height:20px; line-height: 20px; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;} +.laydate_body .laydate_m{width:99px;} +.laydate_body .laydate_m .laydate_yms{width:99px; padding:0;} +.laydate_body .laydate_m input{width:42px; margin-right:15px;} +.laydate_body .laydate_m .laydate_yms span{display:block; float:left; width:42px; margin: 5px 0 0 5px; line-height:24px; text-align:center; _display:inline;} +.laydate_body .laydate_choose{display:block; float:left; position:relative; width:20px; height:24px;} +.laydate_body .laydate_choose cite, .laydate_body .laydate_tab cite{left:50%; top:50%;} +.laydate_body .laydate_chtop cite{margin:-7px 0 0 -5px; border-bottom-style:solid;} +.laydate_body .laydate_chdown cite, .laydate_body .laydate_ym label{top:50%; margin:-2px 0 0 -5px; border-top-style:solid;} +.laydate_body .laydate_chprev cite{margin:-5px 0 0 -7px;} +.laydate_body .laydate_chnext cite{margin:-5px 0 0 -2px;} +.laydate_body .laydate_ym label{right:28px;} +.laydate_body .laydate_table{ width:230px; margin:0 5px; border-collapse:collapse; border-spacing:0px; } +.laydate_body .laydate_table td{width:31px; height:19px; line-height:19px; text-align: center; cursor:pointer; font-size: 12px;} +.laydate_body .laydate_table thead{height:22px; line-height:22px;} +.laydate_body .laydate_table thead th{font-weight:400; font-size:12px; text-align:center;} +.laydate_body .laydate_bottom{position:relative; height:22px; line-height:20px; padding:5px; font-size:12px;} +.laydate_body .laydate_bottom #laydate_hms{position: relative; z-index: 1; float:left; } +.laydate_body .laydate_time{ position:absolute; left:5px; bottom: 26px; width:129px; height:125px; *overflow:hidden;} +.laydate_body .laydate_time .laydate_hmsno{ padding:5px 0 0 5px;} +.laydate_body .laydate_time .laydate_hmsno span{display:block; float:left; width:24px; height:19px; line-height:19px; text-align:center; cursor:pointer; *margin-bottom:-5px;} +.laydate_body .laydate_time1{width:228px; height:154px;} +.laydate_body .laydate_time1 .laydate_hmsno{padding: 6px 0 0 8px;} +.laydate_body .laydate_time1 .laydate_hmsno span{width:21px; height:20px; line-height:20px;} +.laydate_body .laydate_msg{left:49px; bottom:67px; width:141px; height:auto; overflow: hidden;} +.laydate_body .laydate_msg p{padding:5px 10px;} +.laydate_body .laydate_bottom li{float:left; height:20px; line-height:20px; border-right:none; font-weight:900;} +.laydate_body .laydate_bottom .laydate_sj{width:33px; text-align:center; font-weight:400;} +.laydate_body .laydate_bottom input{float:left; width:21px; height:20px; line-height:20px; border:none; text-align:center; cursor:pointer; font-size:12px; font-weight:400;} +.laydate_body .laydate_bottom .laydte_hsmtex{height:20px; line-height:20px; text-align:center;} +.laydate_body .laydate_bottom .laydte_hsmtex span{position:absolute; width:20px; top:0; right:0px; cursor:pointer;} +.laydate_body .laydate_bottom .laydte_hsmtex span:hover{font-size:14px;} +.laydate_body .laydate_bottom .laydate_btn{position:absolute; right:5px; top:5px;} +.laydate_body .laydate_bottom .laydate_btn a{float:left; height:20px; padding:0 6px; _padding:0 5px;} +.laydate_body .laydate_bottom .laydate_v{position:absolute; left:10px; top:6px; font-family:Courier; z-index:0;} + diff --git a/static/plugins/layer/skin/default/icon-ext.png b/static/plugins/layer/skin/default/icon-ext.png new file mode 100755 index 0000000..bbbb669 Binary files /dev/null and b/static/plugins/layer/skin/default/icon-ext.png differ diff --git a/static/plugins/layer/skin/default/icon.png b/static/plugins/layer/skin/default/icon.png new file mode 100755 index 0000000..3e17da8 Binary files /dev/null and b/static/plugins/layer/skin/default/icon.png differ diff --git a/static/plugins/layer/skin/default/loading-0.gif b/static/plugins/layer/skin/default/loading-0.gif new file mode 100755 index 0000000..6f3c953 Binary files /dev/null and b/static/plugins/layer/skin/default/loading-0.gif differ diff --git a/static/plugins/layer/skin/default/loading-1.gif b/static/plugins/layer/skin/default/loading-1.gif new file mode 100755 index 0000000..db3a483 Binary files /dev/null and b/static/plugins/layer/skin/default/loading-1.gif differ diff --git a/static/plugins/layer/skin/default/loading-2.gif b/static/plugins/layer/skin/default/loading-2.gif new file mode 100755 index 0000000..5bb90fd Binary files /dev/null and b/static/plugins/layer/skin/default/loading-2.gif differ diff --git a/static/plugins/layer/skin/layer.css b/static/plugins/layer/skin/layer.css new file mode 100755 index 0000000..7c10c14 --- /dev/null +++ b/static/plugins/layer/skin/layer.css @@ -0,0 +1,7 @@ +/*! + + @Name: layer's style + @Author: 贤心 + @Blog: sentsin.com + + */.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layui_layer_skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3);border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.3);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-moves{position:absolute;border:3px solid #666;border:3px solid rgba(0,0,0,.5);cursor:move;background-color:#fff;background-color:rgba(255,255,255,.3);filter:alpha(opacity=50)}.layui-layer-load{background:url(default/loading-0.gif) center center no-repeat #fff}.layui-layer-ico{background:url(default/icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.7}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe .layui-layer-content{overflow:hidden}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(default/loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(default/loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(default/loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.3);background-color:#F90;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#F90}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#F90}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(default/icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal} \ No newline at end of file diff --git a/static/plugins/layer/skin/laypage.css b/static/plugins/layer/skin/laypage.css new file mode 100755 index 0000000..cea9219 --- /dev/null +++ b/static/plugins/layer/skin/laypage.css @@ -0,0 +1,3 @@ +/*! + laypage默认样式 +*/.laypage_main a,.laypage_main input,.laypage_main span{height:26px;line-height:26px}.laypage_main button,.laypage_main input,.laypageskin_default a{border:1px solid #ccc;background-color:#fff}.laypage_main{font-size:0;clear:both;color:#666}.laypage_main *{display:inline-block;vertical-align:top;font-size:12px}.laypage_main a{text-decoration:none;color:#666}.laypage_main a,.laypage_main span{margin:0 3px 6px;padding:0 10px}.laypage_main input{width:40px;margin:0 5px;padding:0 0 0 5px}.laypage_main button{height:28px;line-height:28px;margin-left:5px;padding:0 10px;color:#666}.laypageskin_default span{height:28px;line-height:28px;color:#999}.laypageskin_default .laypage_curr{font-weight:700;color:#666}.laypageskin_molv a,.laypageskin_molv span{padding:0 12px;border-radius:2px}.laypageskin_molv a{background-color:#f1eff0}.laypageskin_molv .laypage_curr{background-color:#00AA91;color:#fff}.laypageskin_molv input{height:24px;line-height:24px}.laypageskin_molv button{height:26px;line-height:26px}.laypageskin_yahei{color:#333}.laypageskin_yahei a,.laypageskin_yahei span{padding:0 13px;border-radius:2px;color:#333}.laypageskin_yahei .laypage_curr{background-color:#333;color:#fff}.laypageskin_flow{text-align:center}.laypageskin_flow .page_nomore{color:#999} \ No newline at end of file diff --git a/static/plugins/layer/skins/default/icon.png b/static/plugins/layer/skins/default/icon.png new file mode 100755 index 0000000..5a50673 Binary files /dev/null and b/static/plugins/layer/skins/default/icon.png differ diff --git a/static/plugins/layer/skins/default/laydate.css b/static/plugins/layer/skins/default/laydate.css new file mode 100755 index 0000000..cd35a4b --- /dev/null +++ b/static/plugins/layer/skins/default/laydate.css @@ -0,0 +1,68 @@ +/** + + @Name: laydate皮肤:默认 + @Author:贤心 + @Site:http://sentsin.com/layui/laydate + +**/ + +.laydate-icon{border:1px solid #C6C6C6; background-image:url(icon.png)} + +.laydate_body .laydate_box, +.laydate_body .laydate_ym, +.laydate_body .laydate_ym .laydate_yms, +.laydate_body .laydate_table, +.laydate_body .laydate_table td, +.laydate_body .laydate_bottom #laydate_hms, +.laydate_body .laydate_time, +.laydate_body .laydate_bottom .laydate_btn a{border:1px solid #ccc;} + +.laydate_body .laydate_y .laydate_yms a, +.laydate_body .laydate_choose, +.laydate_body .laydate_table thead, +.laydate_body .laydate_bottom .laydte_hsmtex{background-color:#F6F6F6;} + +.laydate_body .laydate_box, +.laydate_body .laydate_ym .laydate_yms, +.laydate_body .laydate_time{box-shadow: 2px 2px 5px rgba(0,0,0,.1);} + +.laydate_body .laydate_box{border-top:none; border-bottom:none; background-color:#fff; color:#333;} +.laydate_body .laydate_box input{color:#333;} +.laydate_body .laydate_box .laydate_void{color:#ccc!important; /*text-decoration:line-through;*/} +.laydate_body .laydate_box .laydate_void:hover{background-color:#fff!important} +.laydate_body .laydate_box a, .laydate_body .laydate_box a:hover{color:#333;} +.laydate_body .laydate_box a:hover{color:#666;} +.laydate_body .laydate_click{background-color:#eee!important;} +.laydate_body .laydate_top{border-top:1px solid #C6C6C6;} +.laydate_body .laydate_ym .laydate_yms{border:1px solid #C6C6C6; background-color:#fff;} +.laydate_body .laydate_y .laydate_yms a{border-bottom:1px solid #C6C6C6;} +.laydate_body .laydate_y .laydate_yms .laydate_chdown{border-top:1px solid #C6C6C6; border-bottom:none;} +.laydate_body .laydate_choose{border-left:1px solid #C6C6C6;} +.laydate_body .laydate_chprev{border-left:none; border-right:1px solid #C6C6C6;} +.laydate_body .laydate_choose:hover, +.laydate_body .laydate_y .laydate_yms a:hover{background-color:#fff;} +.laydate_body .laydate_chtop cite{border-bottom-color:#666;} +.laydate_body .laydate_chdown cite, .laydate_body .laydate_ym label{border-top-color:#666;} +.laydate_body .laydate_chprev cite{border-right-style:solid; border-right-color:#666;} +.laydate_body .laydate_chnext cite{border-left-style:solid; border-left-color:#666;} +.laydate_body .laydate_table td{border:none; height:21px!important; line-height:21px!important; background-color:#fff;} +.laydate_body .laydate_table .laydate_nothis{color:#999;} +.laydate_body .laydate_table thead{height:21px!important; line-height:21px!important;} +.laydate_body .laydate_table thead th{border-bottom:1px solid #ccc;} +.laydate_body .laydate_bottom{border-bottom:1px solid #C6C6C6;} +.laydate_body .laydate_bottom #laydate_hms{background-color:#fff;} +.laydate_body .laydate_time{background-color:#fff;} +.laydate_body .laydate_bottom .laydate_sj{border-right:1px solid #C6C6C6; background-color:#F6F6F6;} +.laydate_body .laydate_bottom input{background-color:#fff;} +.laydate_body .laydate_bottom .laydte_hsmtex{border-bottom:1px solid #C6C6C6;} +.laydate_body .laydate_bottom .laydate_btn{border-right:1px solid #C6C6C6;} +.laydate_body .laydate_bottom .laydate_v{color:#999} +.laydate_body .laydate_bottom .laydate_btn a{border-right:none; background-color:#F6F6F6;} +.laydate_body .laydate_bottom .laydate_btn a:hover{color:#000; background-color:#fff;} + +.laydate_body .laydate_m .laydate_yms span:hover, +.laydate_body .laydate_y .laydate_yms ul li:hover, +.laydate_body .laydate_table td:hover, +.laydate_body .laydate_time .laydate_hmsno span:hover{background-color:#F3F3F3} + + diff --git a/static/plugins/layui/css/layui.css b/static/plugins/layui/css/layui.css new file mode 100755 index 0000000..1ea0ef2 --- /dev/null +++ b/static/plugins/layui/css/layui.css @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + .layui-btn,.layui-inline,img{vertical-align:middle}.layui-btn,.layui-disabled,.layui-icon,.layui-unselect{-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none}blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{display:inline-block;border:none}li{list-style:none}table{border-collapse:collapse;border-spacing:0}h1,h2,h3{font-size:14px;font-weight:400}h4,h5,h6{font-size:100%;font-weight:400}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:24px;font:14px Helvetica Neue,Helvetica,PingFang SC,\5FAE\8F6F\96C5\9ED1,Tahoma,Arial,sans-serif}hr{height:1px;margin:10px 0;border:0;background-color:#e2e2e2;clear:both}a{color:#333;text-decoration:none}a:hover{color:#777}a cite{font-style:normal;*cursor:pointer}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both;*zoom:1}.layui-clear:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-inline{position:relative;display:inline-block;*display:inline;*zoom:1}.layui-edge{position:absolute;width:0;height:0;border-style:dashed;border-color:transparent;overflow:hidden}.layui-elip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=220);src:url(../font/iconfont.eot?v=220#iefix) format('embedded-opentype'),url(../font/iconfont.svg?v=220#iconfont) format('svg'),url(../font/iconfont.woff?v=220) format('woff'),url(../font/iconfont.ttf?v=220) format('truetype')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-duihua:before{content:"\e611"}.layui-icon-shezhi:before{content:"\e614"}.layui-icon-yinshenim:before{content:"\e60f"}.layui-icon-search:before{content:"\e615"}.layui-icon-fenxiang1:before{content:"\e641"}.layui-icon-shezhi1:before{content:"\e620"}.layui-icon-yinqing:before{content:"\e628"}.layui-icon-yuejuancuohao:before{content:"\1006"}.layui-icon-cuo:before{content:"\1007"}.layui-icon-baobiao:before{content:"\e629"}.layui-icon-star:before{content:"\e600"}.layui-icon-yuandian:before{content:"\e617"}.layui-icon-kefu:before{content:"\e606"}.layui-icon-logo:before{content:"\e609"}.layui-icon-list:before{content:"\e60a"}.layui-icon-tubiao:before{content:"\e62c"}.layui-icon-right:before{content:"\1005"}.layui-icon-huanfu2:before{content:"\e61b"}.layui-icon-On-line:before{content:"\e610"}.layui-icon-biaoge:before{content:"\e62d"}.layui-icon-youyou:before{content:"\e602"}.layui-icon-zuozuo:before{content:"\e603"}.layui-icon-cart:before{content:"\e698"}.layui-icon-cry:before{content:"\e69c"}.layui-icon-smile:before{content:"\e6af"}.layui-icon-survey:before{content:"\e6b2"}.layui-icon-icon5:before{content:"\e62e"}.layui-icon-iconfont17:before{content:"\e62f"}.layui-icon-tianjia:before{content:"\e61f"}.layui-icon-xiazai:before{content:"\e601"}.layui-icon-xuanzemoban48:before{content:"\e630"}.layui-icon-gongju:before{content:"\e631"}.layui-icon-tishilian:before{content:"\e664"}.layui-icon-bianji:before{content:"\e642"}.layui-icon-xiaoxi:before{content:"\e645"}.layui-icon-xiangxia:before{content:"\e61a"}.layui-icon-wenjian:before{content:"\e621"}.layui-icon-layouts:before{content:"\e632"}.layui-icon-duigou:before{content:"\e618"}.layui-icon-tianjia1:before{content:"\e608"}.layui-icon-yaoyaozhibofanye:before{content:"\e633"}.layui-icon-office:before{content:"\e705"}.layui-icon-404:before{content:"\e61c"}.layui-icon-lunbozutu:before{content:"\e634"}.layui-icon-help:before{content:"\e607"}.layui-icon-daima1:before{content:"\e635"}.layui-icon-jinshui:before{content:"\e636"}.layui-icon-faxian:before{content:"\e670"}.layui-icon-guanyu:before{content:"\e60b"}.layui-icon-map:before{content:"\e715"}.layui-icon-xiangshang:before{content:"\e619"}.layui-icon-bofang:before{content:"\e651"}.layui-icon-riqi:before{content:"\e637"}.layui-icon-uploadfile:before{content:"\e61d"}.layui-icon-delete:before{content:"\e640"}.layui-icon-bofangzanting02:before{content:"\e652"}.layui-icon-top:before{content:"\e604"}.layui-icon-haoyouqingqiu:before{content:"\e612"}.layui-icon-weibiaoti1:before{content:"\e605"}.layui-icon-chuangkou:before{content:"\e638"}.layui-icon-comiisbiaoqing:before{content:"\e60c"}.layui-icon-zhengque:before{content:"\e616"}.layui-icon-money:before{content:"\e659"}.layui-icon-iconfontwodehaoyou:before{content:"\e613"}.layui-icon-wenjianxiazai:before{content:"\e61e"}.layui-icon-tupian:before{content:"\e60d"}.layui-icon-lianjie:before{content:"\e64c"}.layui-icon-creditlevel:before{content:"\e735"}.layui-icon-jilu:before{content:"\e60e"}.layui-icon-liucheng:before{content:"\e622"}.layui-icon-fontstrikethrough:before{content:"\e64f"}.layui-icon-unlink:before{content:"\e64d"}.layui-icon-bianjiwenzi:before{content:"\e639"}.layui-icon-sanjiao:before{content:"\e623"}.layui-icon-danxuankuanghouxuan:before{content:"\e63f"}.layui-icon-danxuankuangxuanzhong:before{content:"\e643"}.layui-icon-juzhongduiqi:before{content:"\e647"}.layui-icon-youduiqi:before{content:"\e648"}.layui-icon-zuoduiqi:before{content:"\e649"}.layui-icon-gongsisvgtubiaozongji22:before{content:"\e626"}.layui-icon-gongsisvgtubiaozongji23:before{content:"\e627"}.layui-icon-shuaxin:before{content:"\1002"}.layui-icon-loading2:before{content:"\e63e"}.layui-icon-flow:before{content:"\e65c"}.layui-icon-jiacu:before{content:"\e62b"}.layui-icon-uploading:before{content:"\e67c"}.layui-icon-liaotianduihuaimgoutong:before{content:"\e63a"}.layui-icon-shipin1:before{content:"\e6ed"}.layui-icon-yinpin:before{content:"\e6fc"}.layui-icon-wenjianjiafan:before{content:"\e624"}.layui-icon-shouji:before{content:"\e63b"}.layui-icon-tianjia2:before{content:"\e654"}.layui-icon-wenjianjia:before{content:"\e7a0"}.layui-icon-biaoqing:before{content:"\e650"}.layui-icon-html:before{content:"\e64b"}.layui-icon-biaodan:before{content:"\e63c"}.layui-icon-goumai:before{content:"\e657"}.layui-icon-xiangjicopy2x:before{content:"\e65d"}.layui-icon-25:before{content:"\e62a"}.layui-icon-emwdaima:before{content:"\e64e"}.layui-icon-hot:before{content:"\e756"}.layui-icon-shezhi11:before{content:"\e716"}.layui-icon-zitixiahuaxian:before{content:"\e646"}.layui-icon-sanjiao1:before{content:"\e625"}.layui-icon-tupian-copy-copy:before{content:"\e64a"}.layui-icon-caidan:before{content:"\e671"}.layui-icon-zhuti2:before{content:"\e66c"}.layui-icon-loading1:before{content:"\e63d"}.layui-icon-xieti:before{content:"\e644"}.layui-icon-shuaxin-copy:before{content:"\e666"}.layui-icon-jine:before{content:"\e65e"}.layui-icon-zhuye:before{content:"\e68e"}.layui-icon-yonghu:before{content:"\e770"}.layui-icon-xiaoxi2:before{content:"\e667"}.layui-icon-yuyin:before{content:"\e688"}.layui-icon-download:before{content:"\e681"}.layui-icon-yemian1:before{content:"\e655"}.layui-icon-moban:before{content:"\e663"}.layui-icon-yibiaopan:before{content:"\e665"}.layui-icon-pindao:before{content:"\e653"}.layui-icon-xiayiye:before{content:"\e65a"}.layui-icon-huaban:before{content:"\e7ae"}.layui-icon-xiayiye1:before{content:"\e65b"}.layui-icon-yingyong:before{content:"\e857"}.layui-icon-more:before{content:"\e65f"}.layui-icon-xiangji:before{content:"\e660"}.layui-icon-refresh:before{content:"\e669"}.layui-icon-nv:before{content:"\e661"}.layui-icon-nan:before{content:"\e662"}.layui-icon-gaoji:before{content:"\e674"}.layui-icon-fengge:before{content:"\e66a"}.layui-icon-cai:before{content:"\e6c5"}.layui-icon-zan:before{content:"\e6c6"}.layui-icon-shoucang:before{content:"\e658"}.layui-icon-shuaxin2:before{content:"\e66b"}.layui-icon-moban1:before{content:"\e656"}.layui-icon-shuaxin3:before{content:"\e66d"}.layui-main{position:relative;width:1140px;margin:0 auto}.layui-header{position:relative;z-index:1000;height:60px}.layui-header a:hover{transition:all .5s;-webkit-transition:all .5s}.layui-side{position:fixed;top:0;bottom:0;z-index:999;width:200px;overflow-x:hidden}.layui-side-scroll{width:220px;height:100%;overflow-x:hidden}.layui-body{position:absolute;left:200px;right:0;top:0;bottom:0;z-index:998;width:auto;overflow:hidden;overflow-y:auto;box-sizing:border-box}.layui-layout-body{overflow:hidden}.layui-layout-admin .layui-header{background-color:#23262E}.layui-layout-admin .layui-side{top:60px;width:200px;overflow-x:hidden}.layui-layout-admin .layui-body{top:60px;bottom:44px}.layui-layout-admin .layui-main{width:auto;margin:0 15px}.layui-layout-admin .layui-footer{position:fixed;left:200px;right:0;bottom:0;height:44px;line-height:44px;padding:0 15px;background-color:#eee}.layui-layout-admin .layui-logo{position:absolute;left:0;top:0;width:200px;height:100%;line-height:60px;text-align:center;color:#009688;font-size:16px}.layui-layout-admin .layui-header .layui-nav{background:0 0}.layui-layout-left{position:absolute!important;left:200px;top:0}.layui-layout-right{position:absolute!important;right:0;top:0}.layui-container{position:relative;margin:0 auto;padding:0 15px;box-sizing:border-box}.layui-fluid{position:relative;margin:0 auto;padding:0 15px}.layui-row:after,.layui-row:before{content:'';display:block;clear:both}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9,.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9,.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9,.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{position:relative;display:block;box-sizing:border-box}.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{float:left}.layui-col-xs1{width:8.33333333%}.layui-col-xs2{width:16.66666667%}.layui-col-xs3{width:25%}.layui-col-xs4{width:33.33333333%}.layui-col-xs5{width:41.66666667%}.layui-col-xs6{width:50%}.layui-col-xs7{width:58.33333333%}.layui-col-xs8{width:66.66666667%}.layui-col-xs9{width:75%}.layui-col-xs10{width:83.33333333%}.layui-col-xs11{width:91.66666667%}.layui-col-xs12{width:100%}.layui-col-xs-offset1{margin-left:8.33333333%}.layui-col-xs-offset2{margin-left:16.66666667%}.layui-col-xs-offset3{margin-left:25%}.layui-col-xs-offset4{margin-left:33.33333333%}.layui-col-xs-offset5{margin-left:41.66666667%}.layui-col-xs-offset6{margin-left:50%}.layui-col-xs-offset7{margin-left:58.33333333%}.layui-col-xs-offset8{margin-left:66.66666667%}.layui-col-xs-offset9{margin-left:75%}.layui-col-xs-offset10{margin-left:83.33333333%}.layui-col-xs-offset11{margin-left:91.66666667%}.layui-col-xs-offset12{margin-left:100%}@media screen and (max-width:768px){.layui-hide-xs{display:none!important}.layui-show-xs-block{display:block!important}.layui-show-xs-inline{display:inline!important}.layui-show-xs-inline-block{display:inline-block!important}}@media screen and (min-width:768px){.layui-container{width:750px}.layui-hide-sm{display:none!important}.layui-show-sm-block{display:block!important}.layui-show-sm-inline{display:inline!important}.layui-show-sm-inline-block{display:inline-block!important}.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9{float:left}.layui-col-sm1{width:8.33333333%}.layui-col-sm2{width:16.66666667%}.layui-col-sm3{width:25%}.layui-col-sm4{width:33.33333333%}.layui-col-sm5{width:41.66666667%}.layui-col-sm6{width:50%}.layui-col-sm7{width:58.33333333%}.layui-col-sm8{width:66.66666667%}.layui-col-sm9{width:75%}.layui-col-sm10{width:83.33333333%}.layui-col-sm11{width:91.66666667%}.layui-col-sm12{width:100%}.layui-col-sm-offset1{margin-left:8.33333333%}.layui-col-sm-offset2{margin-left:16.66666667%}.layui-col-sm-offset3{margin-left:25%}.layui-col-sm-offset4{margin-left:33.33333333%}.layui-col-sm-offset5{margin-left:41.66666667%}.layui-col-sm-offset6{margin-left:50%}.layui-col-sm-offset7{margin-left:58.33333333%}.layui-col-sm-offset8{margin-left:66.66666667%}.layui-col-sm-offset9{margin-left:75%}.layui-col-sm-offset10{margin-left:83.33333333%}.layui-col-sm-offset11{margin-left:91.66666667%}.layui-col-sm-offset12{margin-left:100%}}@media screen and (min-width:992px){.layui-container{width:970px}.layui-hide-md{display:none!important}.layui-show-md-block{display:block!important}.layui-show-md-inline{display:inline!important}.layui-show-md-inline-block{display:inline-block!important}.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9{float:left}.layui-col-md1{width:8.33333333%}.layui-col-md2{width:16.66666667%}.layui-col-md3{width:25%}.layui-col-md4{width:33.33333333%}.layui-col-md5{width:41.66666667%}.layui-col-md6{width:50%}.layui-col-md7{width:58.33333333%}.layui-col-md8{width:66.66666667%}.layui-col-md9{width:75%}.layui-col-md10{width:83.33333333%}.layui-col-md11{width:91.66666667%}.layui-col-md12{width:100%}.layui-col-md-offset1{margin-left:8.33333333%}.layui-col-md-offset2{margin-left:16.66666667%}.layui-col-md-offset3{margin-left:25%}.layui-col-md-offset4{margin-left:33.33333333%}.layui-col-md-offset5{margin-left:41.66666667%}.layui-col-md-offset6{margin-left:50%}.layui-col-md-offset7{margin-left:58.33333333%}.layui-col-md-offset8{margin-left:66.66666667%}.layui-col-md-offset9{margin-left:75%}.layui-col-md-offset10{margin-left:83.33333333%}.layui-col-md-offset11{margin-left:91.66666667%}.layui-col-md-offset12{margin-left:100%}}@media screen and (min-width:1200px){.layui-container{width:1170px}.layui-hide-lg{display:none!important}.layui-show-lg-block{display:block!important}.layui-show-lg-inline{display:inline!important}.layui-show-lg-inline-block{display:inline-block!important}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9{float:left}.layui-col-lg1{width:8.33333333%}.layui-col-lg2{width:16.66666667%}.layui-col-lg3{width:25%}.layui-col-lg4{width:33.33333333%}.layui-col-lg5{width:41.66666667%}.layui-col-lg6{width:50%}.layui-col-lg7{width:58.33333333%}.layui-col-lg8{width:66.66666667%}.layui-col-lg9{width:75%}.layui-col-lg10{width:83.33333333%}.layui-col-lg11{width:91.66666667%}.layui-col-lg12{width:100%}.layui-col-lg-offset1{margin-left:8.33333333%}.layui-col-lg-offset2{margin-left:16.66666667%}.layui-col-lg-offset3{margin-left:25%}.layui-col-lg-offset4{margin-left:33.33333333%}.layui-col-lg-offset5{margin-left:41.66666667%}.layui-col-lg-offset6{margin-left:50%}.layui-col-lg-offset7{margin-left:58.33333333%}.layui-col-lg-offset8{margin-left:66.66666667%}.layui-col-lg-offset9{margin-left:75%}.layui-col-lg-offset10{margin-left:83.33333333%}.layui-col-lg-offset11{margin-left:91.66666667%}.layui-col-lg-offset12{margin-left:100%}}.layui-col-space1{margin:-.5px}.layui-col-space1>*{padding:.5px}.layui-col-space3{margin:-1.5px}.layui-col-space3>*{padding:1.5px}.layui-col-space5{margin:-2.5px}.layui-col-space5>*{padding:2.5px}.layui-col-space8{margin:-3.5px}.layui-col-space8>*{padding:3.5px}.layui-col-space10{margin:-5px}.layui-col-space10>*{padding:5px}.layui-col-space12{margin:-6px}.layui-col-space12>*{padding:6px}.layui-col-space15{margin:-7.5px}.layui-col-space15>*{padding:7.5px}.layui-col-space18{margin:-9px}.layui-col-space18>*{padding:9px}.layui-col-space20{margin:-10px}.layui-col-space20>*{padding:10px}.layui-col-space22{margin:-11px}.layui-col-space22>*{padding:11px}.layui-col-space25{margin:-12.5px}.layui-col-space25>*{padding:12.5px}.layui-col-space30{margin:-15px}.layui-col-space30>*{padding:15px}.layui-btn,.layui-input,.layui-select,.layui-textarea,.layui-upload-button{outline:0;-webkit-appearance:none;transition:all .3s;-webkit-transition:all .3s;box-sizing:border-box}.layui-elem-quote{margin-bottom:10px;padding:15px;line-height:22px;border-left:5px solid #009688;border-radius:0 2px 2px 0;background-color:#f2f2f2}.layui-quote-nm{border-color:#e2e2e2;border-style:solid;border-width:1px 1px 1px 5px;background:0 0}.layui-elem-field{margin-bottom:10px;padding:0;border:1px solid #e2e2e2}.layui-elem-field legend{margin-left:20px;padding:0 10px;font-size:20px;font-weight:300}.layui-field-title{margin:10px 0 20px;border:none;border-top:1px solid #e2e2e2}.layui-field-box{padding:10px 15px}.layui-field-title .layui-field-box{padding:10px 0}.layui-progress{position:relative;height:6px;border-radius:20px;background-color:#e2e2e2}.layui-progress-bar{position:absolute;width:0;max-width:100%;height:6px;border-radius:20px;text-align:right;background-color:#5FB878;transition:all .3s;-webkit-transition:all .3s}.layui-progress-big,.layui-progress-big .layui-progress-bar{height:18px;line-height:18px}.layui-progress-text{position:relative;top:-18px;line-height:18px;font-size:12px;color:#666}.layui-progress-big .layui-progress-text{position:static;padding:0 10px;color:#fff}.layui-card-header,.layui-colla-title{position:relative;height:42px;color:#333}.layui-card{margin-bottom:15px;border-radius:2px;background-color:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.layui-card-header{line-height:42px;padding:0 15px;border-bottom:1px dotted #E9E9E9;border-radius:2px 2px 0 0;font-size:14px}.layui-card-body{padding:10px 15px;line-height:24px}.layui-card-body .layui-table{margin:5px 0}.layui-collapse{border:1px solid #e2e2e2;border-radius:2px}.layui-colla-item{border-top:1px solid #e2e2e2}.layui-colla-item:first-child{border-top:none}.layui-colla-title{line-height:42px;padding:0 15px 0 35px;background-color:#f2f2f2;cursor:pointer}.layui-colla-content{display:none;padding:10px 15px;line-height:22px;border-top:1px solid #e2e2e2;color:#666}.layui-bg-black,.layui-bg-blue,.layui-bg-cyan,.layui-bg-green,.layui-bg-orange,.layui-bg-red{color:#fff!important}.layui-colla-icon{position:absolute;left:15px;top:0;font-size:14px}.layui-bg-red{background-color:#FF5722!important}.layui-bg-orange{background-color:#FFB800!important}.layui-bg-green{background-color:#009688!important}.layui-bg-cyan{background-color:#2F4056!important}.layui-bg-blue{background-color:#1E9FFF!important}.layui-bg-black{background-color:#393D49!important}.layui-bg-gray{background-color:#eee!important;color:#666!important}.layui-text{line-height:22px;font-size:14px;color:#666}.layui-text h1,.layui-text h2,.layui-text h3{font-weight:500;color:#333}.layui-text h1{font-size:30px}.layui-text h2{font-size:24px}.layui-text h3{font-size:18px}.layui-text a:not(.layui-btn){color:#01AAED}.layui-text a:not(.layui-btn):hover{text-decoration:underline}.layui-text ul{padding:5px 0 5px 15px}.layui-text ul li{margin-top:5px;list-style-type:disc}.layui-text em,.layui-word-aux{color:#999!important;padding:0 5px!important}.layui-btn{display:inline-block;height:38px;line-height:38px;padding:0 18px;background-color:#009688;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border:none;border-radius:2px;cursor:pointer}.layui-btn:hover{opacity:.8;filter:alpha(opacity=80);color:#fff}.layui-btn:active{opacity:1;filter:alpha(opacity=100)}.layui-btn+.layui-btn{margin-left:10px}.layui-btn-radius{border-radius:100px}.layui-btn .layui-icon{margin-right:3px;font-size:18px;vertical-align:bottom;vertical-align:middle\9}.layui-btn-primary{border:1px solid #C9C9C9;background-color:#fff;color:#555}.layui-btn-primary:hover{border-color:#009688;color:#333}.layui-btn-normal{background-color:#1E9FFF}.layui-btn-warm{background-color:#FFB800}.layui-btn-danger{background-color:#FF5722}.layui-btn-disabled,.layui-btn-disabled:active,.layui-btn-disabled:hover{border:1px solid #e6e6e6;background-color:#FBFBFB;color:#C9C9C9;cursor:not-allowed;opacity:1}.layui-btn-big{height:44px;line-height:44px;padding:0 25px;font-size:16px}.layui-btn-small{height:30px;line-height:30px;padding:0 10px;font-size:12px}.layui-btn-small i{font-size:16px!important}.layui-btn-mini{height:22px;line-height:22px;padding:0 5px;font-size:12px}.layui-btn-mini i{font-size:14px!important}.layui-btn-group{display:inline-block;vertical-align:middle;font-size:0}.layui-btn-group .layui-btn{margin-left:0!important;margin-right:0!important;border-left:1px solid rgba(255,255,255,.5);border-radius:0}.layui-btn-group .layui-btn-primary{border-left:none}.layui-btn-group .layui-btn-primary:hover{border-color:#C9C9C9;color:#009688}.layui-btn-group .layui-btn:first-child{border-left:none;border-radius:2px 0 0 2px}.layui-btn-group .layui-btn-primary:first-child{border-left:1px solid #c9c9c9}.layui-btn-group .layui-btn:last-child{border-radius:0 2px 2px 0}.layui-btn-group .layui-btn+.layui-btn{margin-left:0}.layui-btn-group+.layui-btn-group{margin-left:10px}.layui-input,.layui-select,.layui-textarea{height:38px;line-height:1.3;line-height:38px\9;border:1px solid #e6e6e6;background-color:#fff;border-radius:2px}.layui-input::-webkit-input-placeholder,.layui-select::-webkit-input-placeholder,.layui-textarea::-webkit-input-placeholder{line-height:1.3}.layui-form-label,.layui-form-mid,.layui-textarea{line-height:20px;position:relative}.layui-input,.layui-textarea{display:block;width:100%;padding-left:10px}.layui-input:hover,.layui-textarea:hover{border-color:#D2D2D2!important}.layui-input:focus,.layui-textarea:focus{border-color:#C9C9C9!important}.layui-textarea{min-height:100px;height:auto;padding:6px 10px;resize:vertical}.layui-select{padding:0 10px}.layui-form input[type=checkbox],.layui-form input[type=radio],.layui-form select{display:none}.layui-form-item{margin-bottom:15px;clear:both;*zoom:1}.layui-form-item:after{content:'\20';clear:both;*zoom:1;display:block;height:0}.layui-form-label{float:left;display:block;padding:9px 15px;width:80px;font-weight:400;text-align:right}.layui-form-item .layui-inline{margin-bottom:5px;margin-right:10px}.layui-input-block,.layui-input-inline{position:relative}.layui-input-block{margin-left:110px;min-height:36px}.layui-input-inline{display:inline-block;vertical-align:middle}.layui-form-item .layui-input-inline{float:left;width:190px;margin-right:10px}.layui-form-text .layui-input-inline{width:auto}.layui-form-mid{float:left;display:block;padding:8px 0!important;margin-right:10px}.layui-form-danger+.layui-form-select .layui-input,.layui-form-danger:focus{border:1px solid #FF5722!important}.layui-form-select{position:relative}.layui-form-select .layui-input{padding-right:30px;cursor:pointer}.layui-form-select .layui-edge{position:absolute;right:10px;top:50%;margin-top:-3px;cursor:pointer;border-width:6px;border-top-color:#c2c2c2;border-top-style:solid;transition:all .3s;-webkit-transition:all .3s}.layui-form-select dl{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:999;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box}.layui-form-select dl dd,.layui-form-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.layui-form-select dl dt{font-size:12px;color:#999}.layui-form-select dl dd{cursor:pointer}.layui-form-select dl dd:hover{background-color:#f2f2f2}.layui-form-select .layui-select-group dd{padding-left:20px}.layui-form-select dl dd.layui-select-tips{padding-left:10px!important;color:#999}.layui-form-select dl dd.layui-this{background-color:#5FB878;color:#fff}.layui-form-checkbox,.layui-form-select dl dd.layui-disabled{background-color:#fff}.layui-form-selected dl{display:block}.layui-form-checkbox,.layui-form-checkbox *,.layui-form-radio,.layui-form-radio *,.layui-form-switch{display:inline-block;vertical-align:middle}.layui-form-selected .layui-edge{margin-top:-9px;-webkit-transform:rotate(180deg);transform:rotate(180deg);margin-top:-3px\9}:root .layui-form-selected .layui-edge{margin-top:-9px\0/IE9}.layui-form-selectup dl{top:auto;bottom:42px}.layui-select-none{margin:5px 0;text-align:center;color:#999}.layui-select-disabled .layui-disabled{border-color:#eee!important}.layui-select-disabled .layui-edge{border-top-color:#d2d2d2}.layui-form-checkbox{position:relative;height:30px;line-height:28px;margin-right:10px;padding-right:30px;border:1px solid #d2d2d2;cursor:pointer;font-size:0;border-radius:2px;-webkit-transition:.1s linear;transition:.1s linear;box-sizing:border-box}.layui-form-checkbox:hover{border:1px solid #c2c2c2}.layui-form-checkbox span{padding:0 10px;height:100%;font-size:14px;background-color:#d2d2d2;color:#fff;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.layui-form-checkbox:hover span{background-color:#c2c2c2}.layui-form-checkbox i{position:absolute;right:0;width:30px;color:#fff;font-size:20px;text-align:center}.layui-form-checkbox:hover i{color:#c2c2c2}.layui-form-checked,.layui-form-checked:hover{border-color:#5FB878}.layui-form-checked span,.layui-form-checked:hover span{background-color:#5FB878}.layui-form-checked i,.layui-form-checked:hover i{color:#5FB878}.layui-form-item .layui-form-checkbox{margin-top:4px}.layui-form-checkbox[lay-skin=primary]{height:auto!important;line-height:normal!important;border:none!important;margin-right:0;padding-right:0;background:0 0}.layui-form-checkbox[lay-skin=primary] span{float:right;padding-right:15px;line-height:18px;background:0 0;color:#666}.layui-form-checkbox[lay-skin=primary] i{position:relative;top:0;width:16px;height:16px;line-height:16px;border:1px solid #d2d2d2;font-size:12px;border-radius:2px;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-checkbox[lay-skin=primary]:hover i{border-color:#5FB878;color:#fff}.layui-form-checked[lay-skin=primary] i{border-color:#5FB878;background-color:#5FB878;color:#fff}.layui-checkbox-disbaled[lay-skin=primary] span{background:0 0!important}.layui-checkbox-disbaled[lay-skin=primary]:hover i{border-color:#d2d2d2}.layui-form-item .layui-form-checkbox[lay-skin=primary]{margin-top:10px}.layui-form-switch{position:relative;height:22px;line-height:22px;width:42px;padding:0 5px;margin-top:8px;border:1px solid #d2d2d2;border-radius:20px;cursor:pointer;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch i{position:absolute;left:5px;top:3px;width:16px;height:16px;border-radius:20px;background-color:#d2d2d2;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch em{position:absolute;right:5px;top:0;width:25px;padding:0!important;text-align:center!important;color:#999!important;font-style:normal!important;font-size:12px}.layui-form-onswitch{border-color:#5FB878;background-color:#5FB878}.layui-form-onswitch i{left:32px;background-color:#fff}.layui-form-onswitch em{left:5px;right:auto;color:#fff!important}.layui-checkbox-disbaled{border-color:#e2e2e2!important}.layui-checkbox-disbaled span{background-color:#e2e2e2!important}.layui-checkbox-disbaled:hover i{color:#fff!important}.layui-form-radio{line-height:28px;margin:6px 10px 0 0;padding-right:10px;cursor:pointer;font-size:0}.layui-form-radio i{margin-right:8px;font-size:22px;color:#c2c2c2}.layui-form-radio span{font-size:14px}.layui-form-radio i:hover,.layui-form-radioed i{color:#5FB878}.layui-radio-disbaled i{color:#e2e2e2!important}.layui-form-pane .layui-form-label{width:110px;padding:8px 15px;height:38px;line-height:20px;border:1px solid #e6e6e6;border-radius:2px 0 0 2px;text-align:center;background-color:#FBFBFB;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;box-sizing:border-box}.layui-form-pane .layui-input-inline{margin-left:-1px}.layui-form-pane .layui-input-block{margin-left:110px;left:-1px}.layui-form-pane .layui-input{border-radius:0 2px 2px 0}.layui-form-pane .layui-form-text .layui-form-label{float:none;width:100%;border-right:1px solid #e6e6e6;border-radius:2px;box-sizing:border-box;text-align:left}.layui-form-pane .layui-form-text .layui-input-inline{display:block;margin:0;top:-1px;clear:both}.layui-form-pane .layui-form-text .layui-input-block{margin:0;left:0;top:-1px}.layui-form-pane .layui-form-text .layui-textarea{min-height:100px;border-radius:0 0 2px 2px}.layui-form-pane .layui-form-checkbox{margin:4px 0 4px 10px}.layui-form-pane .layui-form-radio,.layui-form-pane .layui-form-switch{margin-top:6px;margin-left:10px}.layui-form-pane .layui-form-item[pane]{position:relative;border:1px solid #e6e6e6}.layui-form-pane .layui-form-item[pane] .layui-form-label{position:absolute;left:0;top:0;height:100%;border-width:0 1px 0 0}.layui-form-pane .layui-form-item[pane] .layui-input-inline{margin-left:110px}@media screen and (max-width:450px){.layui-form-item .layui-form-label{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-form-item .layui-inline{display:block;margin-right:0;margin-bottom:20px;clear:both}.layui-form-item .layui-inline:after{content:'\20';clear:both;display:block;height:0}.layui-form-item .layui-input-inline{display:block;float:none;left:-3px;width:auto;margin:0 0 10px 112px}.layui-form-item .layui-input-inline+.layui-form-mid{margin-left:110px;top:-5px;padding:0}.layui-form-item .layui-form-checkbox{margin-right:5px;margin-bottom:5px}}.layui-layedit{border:1px solid #d2d2d2;border-radius:2px}.layui-layedit-tool{padding:3px 5px;border-bottom:1px solid #e2e2e2;font-size:0}.layedit-tool-fixed{position:fixed;top:0;border-top:1px solid #e2e2e2}.layui-layedit-tool .layedit-tool-mid,.layui-layedit-tool .layui-icon{display:inline-block;vertical-align:middle;text-align:center;font-size:14px}.layui-layedit-tool .layui-icon{position:relative;width:32px;height:30px;line-height:30px;margin:3px 5px;color:#777;cursor:pointer;border-radius:2px}.layui-layedit-tool .layui-icon:hover{color:#393D49}.layui-layedit-tool .layui-icon:active{color:#000}.layui-layedit-tool .layedit-tool-active{background-color:#e2e2e2;color:#000}.layui-layedit-tool .layui-disabled,.layui-layedit-tool .layui-disabled:hover{color:#d2d2d2;cursor:not-allowed}.layui-layedit-tool .layedit-tool-mid{width:1px;height:18px;margin:0 10px;background-color:#d2d2d2}.layedit-tool-html{width:50px!important;font-size:30px!important}.layedit-tool-b,.layedit-tool-code,.layedit-tool-help{font-size:16px!important}.layedit-tool-d,.layedit-tool-face,.layedit-tool-image,.layedit-tool-unlink{font-size:18px!important}.layedit-tool-image input{position:absolute;font-size:0;left:0;top:0;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-layedit-iframe iframe{display:block;width:100%}#LAY_layedit_code{overflow:hidden}.layui-laypage{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;margin:10px 0;font-size:0}.layui-laypage>a:first-child,.layui-laypage>a:first-child em{border-radius:2px 0 0 2px}.layui-laypage>a:last-child,.layui-laypage>a:last-child em{border-radius:0 2px 2px 0}.layui-laypage>:first-child{margin-left:0!important}.layui-laypage>:last-child{margin-right:0!important}.layui-laypage a,.layui-laypage button,.layui-laypage input,.layui-laypage select,.layui-laypage span{border:1px solid #e2e2e2}.layui-laypage a,.layui-laypage span{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding:0 15px;height:28px;line-height:28px;margin:0 -1px 5px 0;background-color:#fff;color:#333;font-size:12px}.layui-laypage a:hover{color:#009688}.layui-laypage em{font-style:normal}.layui-laypage .layui-laypage-spr{color:#999;font-weight:700}.layui-laypage a{text-decoration:none}.layui-laypage .layui-laypage-curr{position:relative}.layui-laypage .layui-laypage-curr em{position:relative;color:#fff}.layui-laypage .layui-laypage-curr .layui-laypage-em{position:absolute;left:-1px;top:-1px;padding:1px;width:100%;height:100%;background-color:#009688}.layui-laypage-em{border-radius:2px}.layui-laypage-next em,.layui-laypage-prev em{font-family:Sim sun;font-size:16px}.layui-laypage .layui-laypage-count,.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-skip{margin-left:10px;margin-right:10px;padding:0;border:none}.layui-laypage .layui-laypage-limits{vertical-align:top}.layui-laypage select{height:22px;padding:3px;border-radius:2px;cursor:pointer}.layui-laypage .layui-laypage-skip{height:30px;line-height:30px;color:#999}.layui-laypage button,.layui-laypage input{height:30px;line-height:30px;border:1px solid #e2e2e2;border-radius:2px;vertical-align:top;background-color:#fff;box-sizing:border-box}.layui-laypage input{display:inline-block;width:40px;margin:0 10px;padding:0 3px;text-align:center}.layui-laypage input:focus,.layui-laypage select:focus{border-color:#009688!important}.layui-laypage button{margin-left:10px;padding:0 10px;cursor:pointer}.layui-flow-more{margin:10px 0;text-align:center;color:#999;font-size:14px}.layui-flow-more a{height:32px;line-height:32px}.layui-flow-more a *{display:inline-block;vertical-align:top}.layui-flow-more a cite{padding:0 20px;border-radius:3px;background-color:#eee;color:#333;font-style:normal}.layui-flow-more a cite:hover{opacity:.8}.layui-flow-more a i{font-size:30px;color:#737383}.layui-table{width:100%;margin:10px 0;background-color:#fff}.layui-table tr{transition:all .3s;-webkit-transition:all .3s}.layui-table thead tr,.layui-table-fixed-l tr,.layui-table-header,.layui-table-mend,.layui-table-patch,.layui-table-tool{background-color:#f2f2f2}.layui-table th{text-align:left;font-weight:400}.layui-table td,.layui-table th,.layui-table-header,.layui-table-tool,.layui-table-view,.layui-table[lay-skin=line],.layui-table[lay-skin=row]{border:1px solid #e2e2e2}.layui-table td,.layui-table th{position:relative;padding:9px 15px;min-height:20px;line-height:20px;font-size:14px}.layui-table[lay-even] tr:nth-child(even){background-color:#f8f8f8}.layui-table tbody tr:hover,.layui-table-hover{background-color:#f2f2f2!important}.layui-table-click{background-color:#FFEEE8!important}.layui-table[lay-skin=line] td,.layui-table[lay-skin=line] th{border-width:0 0 1px}.layui-table[lay-skin=row] td,.layui-table[lay-skin=row] th{border-width:0 1px 0 0}.layui-table[lay-skin=nob] td,.layui-table[lay-skin=nob] th{border:none}.layui-table img{max-width:100px}.layui-table[lay-size=lg] td,.layui-table[lay-size=lg] th{padding:15px 30px}.layui-table-view .layui-table[lay-size=lg] .layui-table-cell{height:40px;line-height:40px}.layui-table[lay-size=sm] td,.layui-table[lay-size=sm] th{font-size:12px;padding:5px 10px}.layui-table-view .layui-table[lay-size=sm] .layui-table-cell{height:20px;line-height:20px}.layui-table[lay-data]{display:none}.layui-table-view{position:relative;margin:10px 0;overflow:hidden}.layui-table-view .layui-table{position:relative;width:auto;margin:0}.layui-table-body,.layui-table-header .layui-table,.layui-table-tool{margin-bottom:-1px}.layui-table-view .layui-table[lay-skin=line]{border-width:0 1px 0 0}.layui-table-view .layui-table[lay-skin=row]{border-width:0 0 1px}.layui-table-view .layui-table td,.layui-table-view .layui-table th{padding:5px 0;border-top:none;border-left:none}.layui-table-view .layui-table td{cursor:default}.layui-table-view .layui-form-checkbox[lay-skin=primary] i{width:18px;height:18px}.layui-table-header{border-width:0 0 1px;overflow:hidden}.layui-table-sort{width:20px;height:20px;margin-left:5px;cursor:pointer!important}.layui-table-sort .layui-edge{left:5px;border-width:5px}.layui-table-sort .layui-table-sort-asc{top:4px;border-top:none;border-bottom-style:solid;border-bottom-color:#b2b2b2}.layui-table-sort .layui-table-sort-asc:hover{border-bottom-color:#666}.layui-table-sort .layui-table-sort-desc{bottom:4px;border-bottom:none;border-top-style:solid;border-top-color:#b2b2b2}.layui-table-sort .layui-table-sort-desc:hover{border-top-color:#666}.layui-table-sort[lay-sort=asc] .layui-table-sort-asc{border-bottom-color:#000}.layui-table-sort[lay-sort=desc] .layui-table-sort-desc{border-top-color:#000}.layui-table-cell{height:28px;line-height:28px;padding:0 15px;position:relative;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;box-sizing:border-box}.layui-table-cell .layui-form-checkbox{top:-1px}.layui-table-cell .layui-table-link{color:#01AAED}.laytable-cell-space{width:15px;padding:0;text-align:center}.layui-table-body{position:relative;overflow:auto;margin-right:-1px}.layui-table-body .layui-none{line-height:40px;text-align:center;color:#999}.layui-table-fixed{position:absolute;left:0;top:0}.layui-table-fixed .layui-table-body{overflow:hidden}.layui-table-fixed-r{left:auto;right:-1px;border-left:1px solid #e2e2e2;box-shadow:-1px 0 8px rgba(0,0,0,.1)}.layui-table-fixed-r .layui-table-header{position:relative;overflow:visible}.layui-table-mend{position:absolute;right:-49px;top:0;height:100%;width:50px}.layui-table-tool{position:relative;width:100%;padding:7px 10px 0 0;border-width:1px 0 0;height:41px;font-size:12px;white-space:nowrap}.layui-table-tool:hover{overflow-x:auto}.layui-table-page{height:26px}.layui-table-tool .layui-laypage{margin:0}.layui-table-tool .layui-laypage a,.layui-table-tool .layui-laypage span{height:26px;line-height:26px;border:none;background:0 0;padding:0 12px}.layui-table-tool .layui-laypage .layui-laypage-count,.layui-table-tool .layui-laypage .layui-laypage-limits,.layui-table-tool .layui-laypage .layui-laypage-skip{margin-left:0;padding:0}.layui-table-tool .layui-laypage .layui-laypage-total{padding:0 10px}.layui-table-tool .layui-laypage .layui-laypage-spr{padding:0}.layui-table-tool .layui-laypage button,.layui-table-tool .layui-laypage input{height:26px;line-height:26px}.layui-table-tool .layui-laypage input{width:40px}.layui-table-tool .layui-laypage button{padding:0 10px}.layui-table-view select[lay-ignore]{display:inline-block}.layui-table-tool select{height:18px}.layui-table-patch .layui-table-cell{padding:0;width:30px}.layui-table-edit{position:absolute;left:0;top:0;width:100%;height:100%;padding:0 15px 1px;border:none}.layui-table-edit:focus{background-color:#F0F9F2}body .layui-table-tips .layui-layer-content{background:0 0;padding:0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.layui-table-tips-main{margin:-44px 0 0 -1px;max-height:150px;padding:8px 15px;font-size:14px;overflow-y:scroll;background-color:#fff;color:#333;border:1px solid #e2e2e2}.layui-code,.layui-upload-list{margin:10px 0}.layui-table-tips-c{position:absolute;right:-3px;top:-12px;width:18px;height:18px;padding:3px;text-align:center;font-weight:700;border-radius:100%;font-size:14px;cursor:pointer;background-color:#666}.layui-table-tips-c:hover{background-color:#999}.layui-upload-file{display:none!important;opacity:.01;filter:Alpha(opacity=1)}.layui-upload-drag,.layui-upload-form,.layui-upload-wrap{display:inline-block}.layui-upload-choose{padding:0 10px;color:#999}.layui-upload-drag{position:relative;padding:30px;border:1px dashed #e2e2e2;background-color:#fff;text-align:center;cursor:pointer;color:#999}.layui-upload-drag .layui-icon{font-size:50px;color:#009688}.layui-upload-drag[lay-over]{border-color:#009688}.layui-upload-iframe{position:absolute;width:0;height:0;border:0;visibility:hidden}.layui-upload-wrap{position:relative;vertical-align:middle}.layui-upload-wrap .layui-upload-file{display:block!important;position:absolute;left:0;top:0;z-index:10;font-size:100px;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-code{position:relative;padding:15px;line-height:20px;border:1px solid #ddd;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New;font-size:12px}.layui-tree{line-height:26px}.layui-tree li{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-tree li .layui-tree-spread,.layui-tree li a{display:inline-block;vertical-align:top;height:26px;*display:inline;*zoom:1;cursor:pointer}.layui-tree li a{font-size:0}.layui-tree li a i{font-size:16px}.layui-tree li a cite{padding:0 6px;font-size:14px;font-style:normal}.layui-tree li i{padding-left:6px;color:#333;-moz-user-select:none}.layui-tree li .layui-tree-check{font-size:13px}.layui-tree li .layui-tree-check:hover{color:#009E94}.layui-tree li ul{display:none;margin-left:20px}.layui-tree li .layui-tree-enter{line-height:24px;border:1px dotted #000}.layui-tree-drag{display:none;position:absolute;left:-666px;top:-666px;background-color:#f2f2f2;padding:5px 10px;border:1px dotted #000;white-space:nowrap}.layui-tree-drag i{padding-right:5px}.layui-nav{position:relative;padding:0 20px;background-color:#393D49;color:#fff;border-radius:2px;font-size:0;box-sizing:border-box}.layui-nav *{font-size:14px}.layui-nav .layui-nav-item{position:relative;display:inline-block;*display:inline;*zoom:1;vertical-align:middle;line-height:60px}.layui-nav .layui-nav-item a{display:block;padding:0 20px;color:#fff;color:rgba(255,255,255,.7);transition:all .3s;-webkit-transition:all .3s}.layui-nav .layui-this:after,.layui-nav-bar,.layui-nav-tree .layui-nav-itemed:after{position:absolute;left:0;top:0;width:0;height:5px;background-color:#5FB878;transition:all .2s;-webkit-transition:all .2s}.layui-nav-bar{z-index:1000}.layui-nav .layui-nav-item a:hover,.layui-nav .layui-this a{color:#fff}.layui-nav .layui-this:after{content:'';top:auto;bottom:0;width:100%}.layui-nav-img{width:30px;height:30px;margin-right:10px;border-radius:50%}.layui-nav .layui-nav-more{content:'';width:0;height:0;border-style:solid dashed dashed;border-color:#fff transparent transparent;overflow:hidden;cursor:pointer;transition:all .2s;-webkit-transition:all .2s;position:absolute;top:50%;right:3px;margin-top:-3px;border-width:6px;border-top-color:rgba(255,255,255,.7)}.layui-nav .layui-nav-mored,.layui-nav-itemed .layui-nav-more{margin-top:-9px;border-style:dashed dashed solid;border-color:transparent transparent #fff}.layui-nav-child{display:none;position:absolute;left:0;top:65px;min-width:100%;line-height:36px;padding:5px 0;box-shadow:0 2px 4px rgba(0,0,0,.12);border:1px solid #d2d2d2;background-color:#fff;z-index:100;border-radius:2px;white-space:nowrap}.layui-nav .layui-nav-child a{color:#333}.layui-nav .layui-nav-child a:hover{background-color:#f2f2f2;color:#000}.layui-nav-child dd{position:relative}.layui-nav .layui-nav-child dd.layui-this a,.layui-nav-child dd.layui-this{background-color:#5FB878;color:#fff}.layui-nav-child dd.layui-this:after{display:none}.layui-nav-tree{width:200px;padding:0}.layui-nav-tree .layui-nav-item{display:block;width:100%;line-height:45px}.layui-nav-tree .layui-nav-item a{height:45px;line-height:45px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-nav-tree .layui-nav-item a:hover{background-color:#4E5465}.layui-nav-tree .layui-nav-bar{width:5px;height:0;background-color:#009688}.layui-nav-tree .layui-nav-child dd.layui-this,.layui-nav-tree .layui-nav-child dd.layui-this a,.layui-nav-tree .layui-this,.layui-nav-tree .layui-this>a,.layui-nav-tree .layui-this>a:hover{background-color:#009688;color:#fff}.layui-nav-tree .layui-this:after{display:none}.layui-nav-itemed>a,.layui-nav-tree .layui-nav-title a,.layui-nav-tree .layui-nav-title a:hover{color:#fff!important}.layui-nav-tree .layui-nav-child{position:relative;z-index:0;top:0;border:none;box-shadow:none}.layui-nav-tree .layui-nav-child a{height:40px;line-height:40px;color:#fff;color:rgba(255,255,255,.7)}.layui-nav-tree .layui-nav-child,.layui-nav-tree .layui-nav-child a:hover{background:0 0;color:#fff}.layui-nav-tree .layui-nav-more{top:20px;right:10px;margin:0}.layui-nav-itemed .layui-nav-more{top:14px}.layui-nav-itemed .layui-nav-child{display:block;padding:0;background-color:rgba(0,0,0,.3)!important}.layui-nav-side{position:fixed;top:0;bottom:0;left:0;overflow-x:hidden;z-index:999}.layui-bg-blue .layui-nav-bar,.layui-bg-blue .layui-nav-itemed:after,.layui-bg-blue .layui-this:after{background-color:#93D1FF}.layui-bg-blue .layui-nav-child dd.layui-this{background-color:#1E9FFF}.layui-bg-blue .layui-nav-itemed>a,.layui-nav-tree.layui-bg-blue .layui-nav-title a,.layui-nav-tree.layui-bg-blue .layui-nav-title a:hover{background-color:#007DDB!important}.layui-breadcrumb{visibility:hidden;font-size:0}.layui-breadcrumb a{padding-right:8px;line-height:22px;font-size:14px;color:#333!important}.layui-breadcrumb a:hover{color:#01AAED!important}.layui-breadcrumb a cite,.layui-breadcrumb a span{color:#666;cursor:text;font-style:normal}.layui-breadcrumb a span{padding-left:8px;font-family:Sim sun}.layui-tab{margin:10px 0;text-align:left!important}.layui-tab[overflow]>.layui-tab-title{overflow:hidden}.layui-tab-title{position:relative;left:0;height:40px;white-space:nowrap;font-size:0;border-bottom:1px solid #e2e2e2;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;font-size:14px;transition:all .2s;-webkit-transition:all .2s;position:relative;line-height:40px;min-width:65px;padding:0 15px;text-align:center;cursor:pointer}.layui-tab-title li a{display:block}.layui-tab-title .layui-this{color:#000}.layui-tab-title .layui-this:after{position:absolute;left:0;top:0;content:'';width:100%;height:41px;border:1px solid #e2e2e2;border-bottom-color:#fff;border-radius:2px 2px 0 0;box-sizing:border-box;pointer-events:none}.layui-tab-bar{position:absolute;right:0;top:0;z-index:10;width:30px;height:39px;line-height:39px;border:1px solid #e2e2e2;border-radius:2px;text-align:center;background-color:#fff;cursor:pointer}.layui-tab-bar .layui-icon{position:relative;display:inline-block;top:3px;transition:all .3s;-webkit-transition:all .3s}.layui-tab-item{display:none}.layui-tab-more{padding-right:30px;height:auto!important;white-space:normal!important}.layui-tab-more li.layui-this:after{border-bottom-color:#e2e2e2;border-radius:2px}.layui-tab-more .layui-tab-bar .layui-icon{top:-2px;top:3px\9;-webkit-transform:rotate(180deg);transform:rotate(180deg)}:root .layui-tab-more .layui-tab-bar .layui-icon{top:-2px\0/IE9}.layui-tab-content{padding:10px}.layui-tab-title li .layui-tab-close{position:relative;display:inline-block;width:18px;height:18px;line-height:20px;margin-left:8px;top:1px;text-align:center;font-size:14px;color:#c2c2c2;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li .layui-tab-close:hover{border-radius:2px;background-color:#FF5722;color:#fff}.layui-tab-brief>.layui-tab-title .layui-this{color:#009688}.layui-tab-brief>.layui-tab-more li.layui-this:after,.layui-tab-brief>.layui-tab-title .layui-this:after{border:none;border-radius:0;border-bottom:2px solid #5FB878}.layui-tab-brief[overflow]>.layui-tab-title .layui-this:after{top:-1px}.layui-tab-card{border:1px solid #e2e2e2;border-radius:2px;box-shadow:0 2px 5px 0 rgba(0,0,0,.1)}.layui-tab-card>.layui-tab-title{background-color:#f2f2f2}.layui-tab-card>.layui-tab-title li{margin-right:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-title .layui-this{background-color:#fff}.layui-tab-card>.layui-tab-title .layui-this:after{border-top:none;border-width:1px;border-bottom-color:#fff}.layui-tab-card>.layui-tab-title .layui-tab-bar{height:40px;line-height:40px;border-radius:0;border-top:none;border-right:none}.layui-tab-card>.layui-tab-more .layui-this{background:0 0;color:#5FB878}.layui-tab-card>.layui-tab-more .layui-this:after{border:none}.layui-timeline{padding-left:5px}.layui-timeline-item{position:relative;padding-bottom:20px}.layui-timeline-axis{position:absolute;left:-5px;top:0;z-index:10;width:20px;height:20px;line-height:20px;background-color:#fff;color:#5FB878;border-radius:50%;text-align:center;cursor:pointer}.layui-timeline-axis:hover{color:#FF5722}.layui-timeline-item:before{content:'';position:absolute;left:5px;top:0;z-index:0;width:1px;height:100%;background-color:#e2e2e2}.layui-timeline-item:last-child:before{display:none}.layui-timeline-item:first-child:before{display:block}.layui-timeline-content{padding-left:25px}.layui-badge,.layui-badge-rim{line-height:18px;padding:0 5px}.layui-timeline-title{position:relative;margin-bottom:10px}.layui-badge,.layui-badge-dot,.layui-badge-rim{position:relative;display:inline-block;font-size:12px;background-color:#FF5722;color:#fff}.layui-badge{min-width:8px;height:18px;text-align:center;border-radius:2px}.layui-badge-dot{width:8px;height:8px;border-radius:50%}.layui-badge-rim{height:18px;border:1px solid #e2e2e2;border-radius:3px;background-color:#fff;color:#666}.layui-btn .layui-badge,.layui-btn .layui-badge-dot{margin-left:5px}.layui-nav .layui-badge,.layui-nav .layui-badge-dot{position:absolute;top:50%;margin:-8px 6px 0}.layui-tab-title .layui-badge,.layui-tab-title .layui-badge-dot{left:5px;top:-2px}.layui-carousel{position:relative;left:0;top:0;background-color:#f2f2f2}.layui-carousel>[carousel-item]{position:relative;width:100%;height:100%;overflow:hidden}.layui-carousel>[carousel-item]:before{position:absolute;content:'\e63d';left:50%;top:50%;width:100px;line-height:20px;margin:-10px 0 0 -50px;text-align:center;color:#999;font-family:layui-icon!important;font-size:20px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-carousel>[carousel-item]>*{display:none;position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f2f2f2;transition-duration:.3s;-webkit-transition-duration:.3s}.layui-carousel-updown>*{-webkit-transition:.3s ease-in-out up;transition:.3s ease-in-out up}.layui-carousel-arrow{display:none\9;opacity:0;position:absolute;left:10px;top:50%;margin-top:-18px;width:36px;height:36px;line-height:36px;text-align:center;font-size:20px;border:0;border-radius:50%;background-color:rgba(0,0,0,.2);color:#fff;-webkit-transition-duration:.3s;transition-duration:.3s;cursor:pointer}.layui-carousel-arrow[lay-type=add]{left:auto!important;right:10px}.layui-carousel:hover .layui-carousel-arrow[lay-type=add],.layui-carousel[lay-arrow=always] .layui-carousel-arrow[lay-type=add]{right:20px}.layui-carousel[lay-arrow=always] .layui-carousel-arrow{opacity:1;left:20px}.layui-carousel[lay-arrow=none] .layui-carousel-arrow{display:none}.layui-carousel-arrow:hover,.layui-carousel-ind ul:hover{background-color:rgba(0,0,0,.35)}.layui-carousel:hover .layui-carousel-arrow{display:block\9;opacity:1;left:20px}.layui-carousel-ind{position:relative;top:-35px;width:100%;line-height:0!important;text-align:center;font-size:0}.layui-carousel[lay-indicator=outside]{margin-bottom:30px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind{top:10px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind ul{background-color:rgba(0,0,0,.5)}.layui-carousel[lay-indicator=none] .layui-carousel-ind{display:none}.layui-carousel-ind ul{display:inline-block;padding:5px;background-color:rgba(0,0,0,.2);border-radius:10px;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li{display:inline-block;width:10px;height:10px;margin:0 3px;font-size:14px;background-color:#e2e2e2;background-color:rgba(255,255,255,.5);border-radius:50%;cursor:pointer;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li:hover{background-color:rgba(255,255,255,.7)}.layui-carousel-ind li.layui-this{background-color:#fff}.layui-carousel>[carousel-item]>.layui-carousel-next,.layui-carousel>[carousel-item]>.layui-carousel-prev,.layui-carousel>[carousel-item]>.layui-this{display:block}.layui-carousel>[carousel-item]>.layui-this{left:0}.layui-carousel>[carousel-item]>.layui-carousel-prev{left:-100%}.layui-carousel>[carousel-item]>.layui-carousel-next{left:100%}.layui-carousel>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel>[carousel-item]>.layui-carousel-prev.layui-carousel-right{left:0}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-left{left:-100%}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-right{left:100%}.layui-carousel[lay-anim=updown] .layui-carousel-arrow{left:50%!important;top:20px;margin:0 0 0 -18px}.layui-carousel[lay-anim=updown]>[carousel-item]>*,.layui-carousel[lay-anim=fade]>[carousel-item]>*{left:0!important}.layui-carousel[lay-anim=updown] .layui-carousel-arrow[lay-type=add]{top:auto!important;bottom:20px}.layui-carousel[lay-anim=updown] .layui-carousel-ind{position:absolute;top:50%;right:20px;width:auto;height:auto}.layui-carousel[lay-anim=updown] .layui-carousel-ind ul{padding:3px 5px}.layui-carousel[lay-anim=updown] .layui-carousel-ind li{display:block;margin:6px 0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next{top:100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-left{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-right{top:100%}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev{opacity:0}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{opacity:1}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-right{opacity:0}.layui-fixbar{position:fixed;right:15px;bottom:15px;z-index:9999}.layui-fixbar li{width:50px;height:50px;line-height:50px;margin-bottom:1px;text-align:center;cursor:pointer;font-size:30px;background-color:#9F9F9F;color:#fff;border-radius:2px;opacity:.95}.layui-fixbar li:hover{opacity:.85}.layui-fixbar li:active{opacity:1}.layui-fixbar .layui-fixbar-top{display:none;font-size:40px}body .layui-util-face{border:none;background:0 0}body .layui-util-face .layui-layer-content{padding:0;background-color:#fff;color:#666;box-shadow:none}.layui-util-face .layui-layer-TipsG{display:none}.layui-util-face ul{position:relative;width:372px;padding:10px;border:1px solid #D9D9D9;background-color:#fff;box-shadow:0 0 20px rgba(0,0,0,.2)}.layui-util-face ul li{cursor:pointer;float:left;border:1px solid #e8e8e8;height:22px;width:26px;overflow:hidden;margin:-1px 0 0 -1px;padding:4px 2px;text-align:center}.layui-util-face ul li:hover{position:relative;z-index:2;border:1px solid #eb7350;background:#fff9ec}.layui-anim{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-anim.layui-icon{display:inline-block}.layui-anim-loop{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}@-webkit-keyframes layui-rotate{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes layui-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.layui-anim-rotate{-webkit-animation-name:layui-rotate;animation-name:layui-rotate;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes layui-up{from{-webkit-transform:translate3d(0,100%,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-up{from{transform:translate3d(0,100%,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-up{-webkit-animation-name:layui-up;animation-name:layui-up}@-webkit-keyframes layui-upbit{from{-webkit-transform:translate3d(0,30px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-upbit{from{transform:translate3d(0,30px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-upbit{-webkit-animation-name:layui-upbit;animation-name:layui-upbit}@-webkit-keyframes layui-movey{0%,100%{-webkit-transform:translate3d(0,50px,0)}50%{-webkit-transform:translate3d(0,-50px,0)}}@keyframes layui-movey{0%,100%{transform:translate3d(0,50px,0)}50%{transform:translate3d(0,-50px,0)}}.layui-anim-movey{-webkit-animation-name:layui-movey;animation-name:layui-movey}@-webkit-keyframes layui-scale{0%{opacity:.3;-webkit-transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale{0%{opacity:.3;-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-ms-transform:scale(1);transform:scale(1)}}.layui-anim-scale{-webkit-animation-name:layui-scale;animation-name:layui-scale}@-webkit-keyframes layui-scale-spring{0%{opacity:.5;-webkit-transform:scale(.5)}80%{opacity:.8;-webkit-transform:scale(1.1)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale-spring{0%{opacity:.5;transform:scale(.5)}80%{opacity:.8;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}.layui-anim-scaleSpring{-webkit-animation-name:layui-scale-spring;animation-name:layui-scale-spring}@-webkit-keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}@keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}.layui-anim-fadein{-webkit-animation-name:layui-fadein;animation-name:layui-fadein}@-webkit-keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}.layui-anim-fadeout{-webkit-animation-name:layui-fadeout;animation-name:layui-fadeout} \ No newline at end of file diff --git a/static/plugins/layui/css/modules/code.css b/static/plugins/layui/css/modules/code.css new file mode 100755 index 0000000..a97d97b --- /dev/null +++ b/static/plugins/layui/css/modules/code.css @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none} \ No newline at end of file diff --git a/static/plugins/layui/css/modules/laydate/default/laydate.css b/static/plugins/layui/css/modules/laydate/default/laydate.css new file mode 100755 index 0000000..24e1585 --- /dev/null +++ b/static/plugins/layui/css/modules/laydate/default/laydate.css @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + .laydate-set-ym,.layui-laydate,.layui-laydate *,.layui-laydate-list{box-sizing:border-box}html #layuicss-laydate{display:none;position:absolute;width:1989px}.layui-laydate *{margin:0;padding:0}.layui-laydate{position:absolute;z-index:66666666;margin:5px 0;border-radius:2px;font-size:14px;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-name:laydate-upbit;animation-name:laydate-upbit}.layui-laydate-main{width:272px}.layui-laydate-content td,.layui-laydate-header *,.layui-laydate-list li{transition-duration:.3s;-webkit-transition-duration:.3s}@-webkit-keyframes laydate-upbit{from{-webkit-transform:translate3d(0,20px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes laydate-upbit{from{transform:translate3d(0,20px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-laydate-static{position:relative;z-index:0;display:inline-block;margin:0;-webkit-animation:none;animation:none}.laydate-ym-show .laydate-next-m,.laydate-ym-show .laydate-prev-m{display:none!important}.laydate-ym-show .laydate-next-y,.laydate-ym-show .laydate-prev-y{display:inline-block!important}.laydate-time-show .laydate-set-ym span[lay-type=month],.laydate-time-show .laydate-set-ym span[lay-type=year],.laydate-time-show .layui-laydate-header .layui-icon,.laydate-ym-show .laydate-set-ym span[lay-type=month]{display:none!important}.layui-laydate-header{position:relative;line-height:30px;padding:10px 70px 5px}.laydate-set-ym span,.layui-laydate-header i{padding:0 5px;cursor:pointer}.layui-laydate-header *{display:inline-block;vertical-align:bottom}.layui-laydate-header i{position:absolute;top:10px;color:#999;font-size:18px}.layui-laydate-header i.laydate-prev-y{left:15px}.layui-laydate-header i.laydate-prev-m{left:45px}.layui-laydate-header i.laydate-next-y{right:15px}.layui-laydate-header i.laydate-next-m{right:45px}.laydate-set-ym{width:100%;text-align:center;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.laydate-time-text{cursor:default!important}.layui-laydate-content{position:relative;padding:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-laydate-content table{border-collapse:collapse;border-spacing:0}.layui-laydate-content td,.layui-laydate-content th{width:36px;height:30px;padding:5px;text-align:center}.layui-laydate-content td{position:relative;cursor:pointer}.laydate-day-mark{position:absolute;left:0;top:0;width:100%;height:100%;line-height:30px;font-size:12px;overflow:hidden}.laydate-day-mark::after{position:absolute;content:'';right:2px;top:2px;width:5px;height:5px;border-radius:50%}.layui-laydate-footer{position:relative;height:46px;line-height:26px;padding:10px 20px}.layui-laydate-footer span{margin-right:15px;display:inline-block;cursor:pointer;font-size:12px}.layui-laydate-footer span:hover{color:#5FB878}.laydate-footer-btns{position:absolute;right:10px;top:10px}.laydate-footer-btns span{height:26px;line-height:26px;margin:0 0 0 -1px;padding:0 10px;border:1px solid #C9C9C9;background-color:#fff;white-space:nowrap;vertical-align:top;border-radius:2px}.layui-laydate-list>li,.layui-laydate-range .layui-laydate-main{display:inline-block;vertical-align:middle}.layui-laydate-list{position:absolute;left:0;top:0;width:100%;height:100%;padding:10px;background-color:#fff}.layui-laydate-list>li{position:relative;width:33.3%;height:36px;line-height:36px;margin:3px 0;text-align:center;cursor:pointer}.laydate-month-list>li{width:25%;margin:17px 0}.laydate-time-list>li{height:100%;margin:0;line-height:normal;cursor:default}.laydate-time-list p{position:relative;top:-4px;line-height:29px}.laydate-time-list ol{height:181px;overflow:hidden}.laydate-time-list>li:hover ol{overflow-y:auto}.laydate-time-list ol li{width:130%;padding-left:33px;line-height:30px;text-align:left;cursor:pointer}.layui-laydate-hint{position:absolute;top:115px;left:50%;width:250px;margin-left:-125px;line-height:20px;padding:15px;text-align:center;font-size:12px}.layui-laydate-range{width:546px}.layui-laydate-range .laydate-main-list-0 .laydate-next-m,.layui-laydate-range .laydate-main-list-0 .laydate-next-y,.layui-laydate-range .laydate-main-list-1 .laydate-prev-m,.layui-laydate-range .laydate-main-list-1 .laydate-prev-y{display:none}.layui-laydate-range .laydate-main-list-1 .layui-laydate-content{border-left:1px solid #e2e2e2}.layui-laydate,.layui-laydate-hint{border:1px solid #d2d2d2;box-shadow:0 2px 4px rgba(0,0,0,.12);background-color:#fff;color:#666}.layui-laydate-header{border-bottom:1px solid #e2e2e2}.layui-laydate-header i:hover,.layui-laydate-header span:hover{color:#5FB878}.layui-laydate-content{border-top:none 0;border-bottom:none 0}.layui-laydate-content th{font-weight:400;color:#333}.layui-laydate-content td{color:#666}.layui-laydate-content td.laydate-selected{background-color:#00F7DE}.laydate-selected:hover{background-color:#00F7DE!important}.layui-laydate-content td:hover,.layui-laydate-list li:hover{background-color:#eaeaea;color:#333}.laydate-time-list li ol{margin:0;padding:0;border:1px solid #e2e2e2;border-left-width:0}.laydate-time-list li:first-child ol{border-left-width:1px}.laydate-time-list>li:hover{background:0 0}.layui-laydate-content .laydate-day-next,.layui-laydate-content .laydate-day-prev{color:#d2d2d2}.laydate-selected.laydate-day-next,.laydate-selected.laydate-day-prev{color:#fff!important}.layui-laydate-footer{border-top:1px solid #e2e2e2}.layui-laydate-hint{color:#FF5722}.laydate-day-mark::after{background-color:#5FB878}.layui-laydate-content td.layui-this .laydate-day-mark::after{display:none}.layui-laydate-footer span[lay-type=date]{color:#5FB878}.layui-laydate .layui-this{background-color:#009688!important;color:#fff!important}.layui-laydate .laydate-disabled,.layui-laydate .laydate-disabled:hover{background:0 0!important;color:#d2d2d2!important;cursor:not-allowed!important;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.laydate-theme-molv{border:none}.laydate-theme-molv.layui-laydate-range{width:548px}.laydate-theme-molv .layui-laydate-main{width:274px}.laydate-theme-molv .layui-laydate-header{border:none;background-color:#009688}.laydate-theme-molv .layui-laydate-header i,.laydate-theme-molv .layui-laydate-header span{color:#f6f6f6}.laydate-theme-molv .layui-laydate-header i:hover,.laydate-theme-molv .layui-laydate-header span:hover{color:#fff}.laydate-theme-molv .layui-laydate-content{border:1px solid #e2e2e2;border-top:none;border-bottom:none}.laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left:none}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li,.laydate-theme-grid .layui-laydate-content td,.laydate-theme-grid .layui-laydate-content thead,.laydate-theme-molv .layui-laydate-footer{border:1px solid #e2e2e2}.laydate-theme-grid .laydate-selected,.laydate-theme-grid .laydate-selected:hover{background-color:#f2f2f2!important;color:#009688!important}.laydate-theme-grid .laydate-selected.laydate-day-next,.laydate-theme-grid .laydate-selected.laydate-day-prev{color:#d2d2d2!important}.laydate-theme-grid .laydate-month-list,.laydate-theme-grid .laydate-year-list{margin:1px 0 0 1px}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li{margin:0 -1px -1px 0}.laydate-theme-grid .laydate-year-list>li{height:43px;line-height:43px}.laydate-theme-grid .laydate-month-list>li{height:71px;line-height:71px} \ No newline at end of file diff --git a/static/plugins/layui/css/modules/layer/default/icon-ext.png b/static/plugins/layui/css/modules/layer/default/icon-ext.png new file mode 100755 index 0000000..bbbb669 Binary files /dev/null and b/static/plugins/layui/css/modules/layer/default/icon-ext.png differ diff --git a/static/plugins/layui/css/modules/layer/default/icon.png b/static/plugins/layui/css/modules/layer/default/icon.png new file mode 100755 index 0000000..3e17da8 Binary files /dev/null and b/static/plugins/layui/css/modules/layer/default/icon.png differ diff --git a/static/plugins/layui/css/modules/layer/default/layer.css b/static/plugins/layui/css/modules/layer/default/layer.css new file mode 100755 index 0000000..9adc253 --- /dev/null +++ b/static/plugins/layui/css/modules/layer/default/layer.css @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + .layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/static/plugins/layui/css/modules/layer/default/loading-0.gif b/static/plugins/layui/css/modules/layer/default/loading-0.gif new file mode 100755 index 0000000..6f3c953 Binary files /dev/null and b/static/plugins/layui/css/modules/layer/default/loading-0.gif differ diff --git a/static/plugins/layui/css/modules/layer/default/loading-1.gif b/static/plugins/layui/css/modules/layer/default/loading-1.gif new file mode 100755 index 0000000..db3a483 Binary files /dev/null and b/static/plugins/layui/css/modules/layer/default/loading-1.gif differ diff --git a/static/plugins/layui/css/modules/layer/default/loading-2.gif b/static/plugins/layui/css/modules/layer/default/loading-2.gif new file mode 100755 index 0000000..5bb90fd Binary files /dev/null and b/static/plugins/layui/css/modules/layer/default/loading-2.gif differ diff --git a/static/plugins/layui/font/iconfont.eot b/static/plugins/layui/font/iconfont.eot new file mode 100755 index 0000000..f439808 Binary files /dev/null and b/static/plugins/layui/font/iconfont.eot differ diff --git a/static/plugins/layui/font/iconfont.svg b/static/plugins/layui/font/iconfont.svg new file mode 100755 index 0000000..f6cf141 --- /dev/null +++ b/static/plugins/layui/font/iconfont.svg @@ -0,0 +1,444 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<!-- +2013-9-30: Created. +--> +<svg> +<metadata> +Created by iconfont +</metadata> +<defs> + +<font id="layui-icon" horiz-adv-x="1024" > + <font-face + font-family="layui-icon" + font-weight="500" + font-stretch="normal" + units-per-em="1024" + ascent="896" + descent="-128" + /> + <missing-glyph /> + + <glyph glyph-name="x" unicode="x" horiz-adv-x="1001" +d="M281 543q-27 -1 -53 -1h-83q-18 0 -36.5 -6t-32.5 -18.5t-23 -32t-9 -45.5v-76h912v41q0 16 -0.5 30t-0.5 18q0 13 -5 29t-17 29.5t-31.5 22.5t-49.5 9h-133v-97h-438v97zM955 310v-52q0 -23 0.5 -52t0.5 -58t-10.5 -47.5t-26 -30t-33 -16t-31.5 -4.5q-14 -1 -29.5 -0.5 +t-29.5 0.5h-32l-45 128h-439l-44 -128h-29h-34q-20 0 -45 1q-25 0 -41 9.5t-25.5 23t-13.5 29.5t-4 30v167h911zM163 247q-12 0 -21 -8.5t-9 -21.5t9 -21.5t21 -8.5q13 0 22 8.5t9 21.5t-9 21.5t-22 8.5zM316 123q-8 -26 -14 -48q-5 -19 -10.5 -37t-7.5 -25t-3 -15t1 -14.5 +t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-5 19 -11 39h-368zM336 498v228q0 11 2.5 23t10 21.5t20.5 15.5t34 6h188q31 0 51.5 -14.5t20.5 -52.5v-227h-327z" /> + + + + <glyph glyph-name="duihua" unicode="&#58897;" d="M507.904 835.584q93.184 1.024 175.104-33.792t143.872-94.72 97.792-141.312 36.864-174.592q1.024-88.064-30.208-165.888t-87.04-137.728-131.072-98.816-162.304-48.128q-22.528-3.072-48.128-5.12t-56.832-3.072-69.632 0-86.528 6.144q-106.496 10.24-158.208 26.624t-41.472 18.432q54.272 9.216 93.184 29.696 20.48 11.264 16.896 32.256t-19.968 39.424q-52.224 57.344-84.48 133.632t-34.304 164.352q-1.024 93.184 33.792 175.104t95.232 143.36 142.336 97.28 175.104 36.864zM707.584 385.024q0-26.624 18.432-45.568t45.056-18.944 45.568 18.944 18.944 45.568-18.944 45.056-45.568 18.432-45.056-18.432-18.432-45.056zM450.56 385.024q0-26.624 19.456-46.08t46.08-19.456q27.648 0 46.592 19.456t18.944 46.08q0 27.648-18.944 46.592t-46.592 18.944q-26.624 0-46.08-18.944t-19.456-46.592zM196.608 386.048q0-26.624 18.944-46.08t45.568-19.456q27.648 0 46.592 19.456t18.944 46.08-18.944 45.568-46.592 18.944q-26.624 0-45.568-18.944t-18.944-45.568z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shezhi" unicode="&#58900;" d="M916.9398 445.2101l-69.9664 10.7833c-18.6619 2.863-38.1388 17.826-43.3424 33.2487-5.1618 15.3809-15.0883 65.4524-3.9288 80.6661l41.9004 57.135c11.1595 15.2346 9.3832 38.5985-3.9706 51.9314l-30.6364 30.6573c-13.3538 13.3538-36.7177 15.151-51.9314 3.9497l-57.135-41.8795c-15.2346-11.1804-39.4344-14.3987-53.7704-7.168-14.3569 7.2307-57.3022 35.7773-60.1652 54.4183l-10.7833 69.9664C570.3471 807.6016 552.542 822.8571 533.6712 822.8571l-43.342367 0c-18.8709 0-36.6759-15.2555-39.5389-33.9174l-10.7833-69.9664c-2.863-18.6619-17.826-38.1388-33.2487-43.3424-15.4018-5.1827-65.4524-15.1092-80.687-3.9288L268.9567 713.5817c-15.2346 11.1804-38.6194 9.3832-51.9523-3.9497l-30.6364-30.6573c-13.3747-13.3538-15.151-36.7177-3.9706-51.9314l41.9004-57.135c11.1595-15.2346 14.3778-39.4136 7.168-53.7704-7.2307-14.3569-35.7773-57.2813-54.4183-60.1443l-69.9664-10.7833C88.3984 442.3471 73.1429 424.542 73.1429 405.6712l0-43.342367c0-18.8709 15.2555-36.6759 33.9174-39.5389l69.9664-10.7833c18.6619-2.863 38.1388-17.8469 43.3424-33.2487 5.1618-15.4018 15.0883-65.4733 3.9288-80.687l-41.9004-57.135c-11.1595-15.2346-9.3832-38.6194 3.9706-51.9314l30.6364-30.6573c13.3538-13.3538 36.7177-15.151 51.9523-3.9706l57.135 41.9213c15.2346 11.1386 39.4136 14.3778 53.7704 7.168 14.3569-7.2307 57.2813-35.7773 60.1443-54.4183l10.7833-69.9664c2.863-18.6619 20.6472-33.9174 39.5389-33.9174l43.342367 0c18.8709 0 36.6759 15.2555 39.5389 33.9174l10.7833 69.9664c2.863 18.6619 17.826 38.1388 33.2487 43.3215 15.4018 5.1827 65.4524 15.0883 80.6661 3.9288l57.1559-41.9213c15.2346-11.1595 38.5985-9.3623 51.9314 3.9706l30.6364 30.6573c13.3747 13.3329 15.151 36.7177 3.9706 51.9314l-41.9004 57.135c-11.1595 15.2346-14.3778 39.4136-7.168 53.7496 7.2307 14.3778 35.7773 57.3231 54.4183 60.1861l69.9664 10.7833c18.6619 2.863 33.9174 20.6472 33.9174 39.5389l0 43.342367C950.8571 424.542 935.6016 442.3471 916.9398 445.2101zM512 210.4633c-95.838 0-173.5367 77.6986-173.5367 173.5367s77.6986 173.5367 173.5367 173.5367 173.5367-77.6986 173.5367-173.5367S607.838 210.4633 512 210.4633zM512 384m-104.7824 0a5.014 5.014 0 1 0 209.5647 0 5.014 5.014 0 1 0-209.5647 0Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yinshenim" unicode="&#58895;" d="M511.999488 834.254727c-248.678712 0-450.273176-201.585181-450.273176-450.254727s201.594464-450.254727 450.273176-450.254727 450.273176 201.585181 450.273176 450.254727S760.6782 834.254727 511.999488 834.254727zM266.371377 589.705012l491.256222 0 0-33.772174L266.371377 555.932838 266.371377 589.705012zM757.627599 178.293965 266.371377 178.293965l0 33.773198 491.256222 0L757.627599 178.293965zM140.487278 367.113401l0 33.771151 743.024421 0 0-33.771151L140.487278 367.113401z" horiz-adv-x="1024" /> + + + <glyph glyph-name="search" unicode="&#58901;" d="M439.323351 120.52219c-49.280352 0-97.09834 9.656941-142.126681 28.699646-43.480015 18.388812-82.522793 44.706201-116.043584 78.225619s-59.841305 72.560596-78.230871 116.03883C83.878729 388.513804 74.222416 436.330856 74.222416 485.609189c0 49.284473 9.656313 97.104595 28.699798 142.133138 18.388542 43.479257 44.71008 82.520435 78.231894 116.03883 33.518745 33.515325 72.562546 59.832713 116.043584 78.219479 45.027318 19.039635 92.846329 28.694529 142.125658 28.694529 49.280352 0 97.099364-9.653871 142.126681-28.694529 43.481039-18.385742 82.525863-44.704155 116.044608-78.220502 33.520791-33.518395 59.842328-72.559573 78.230871-116.03883 19.042462-45.028543 28.699798-92.848665 28.699798-142.133138 0-49.278333-9.657336-97.095385-28.701845-142.122905-18.388542-43.47721-44.708033-82.520435-78.228824-116.03883s-72.563569-59.838853-116.043584-78.226642C536.422715 130.177084 488.603703 120.52219 439.323351 120.52219zM439.323351 797.483242c-171.975699 0-311.887855-139.906423-311.887855-311.875077S267.347652 173.734112 439.323351 173.734112s311.887855 139.907447 311.887855 311.874053S611.299051 797.483242 439.323351 797.483242zM890.678206-48.734702c-22.121716 0-42.90387 8.562003-58.541653 24.115234L674.672953 128.025071l37.039062 38.20616 157.888289-153.058978c5.606924-5.606695 13.091693-8.692986 21.077901-8.692986 7.983139 0 15.464837 3.087315 21.070738 8.69094 5.616135 5.622044 8.715856 13.126972 8.715856 21.123087 0 7.980765-3.091535 15.46318-8.702552 21.067828l-0.301888 0.306992L758.714395 213.230662l38.207726 37.035498 152.611906-157.427472c15.571265-15.638165 24.144876-36.422538 24.144876-58.549487 0-22.195511-8.625801-43.054585-24.287121-58.735729C933.723298-40.112324 912.876674-48.734702 890.678206-48.734702zM281.015489 327.245392c-42.340005 42.320874-65.652899 98.584296-65.643689 158.421102 0.008187 59.818387 23.319034 116.074645 65.637549 158.4078l37.634651-37.619806c-66.60666-66.629513-66.60973-175.00071-0.007163-241.577011L281.015489 327.245392z" horiz-adv-x="1024" /> + + + <glyph glyph-name="fenxiang1" unicode="&#58945;" d="M769.714 222.453c-51.754 0-97.702-24.851-126.571-63.269L394.479 283.941c3.93 13.798 6.034 28.364 6.034 43.424 0 16.496-2.527 32.399-7.211 47.35l247.724 124.288c28.71-40.052 75.647-66.151 128.687-66.151 87.388 0 158.229 70.84 158.229 158.229 0 87.388-70.841 158.229-158.229 158.229-87.389 0-158.229-70.841-158.229-158.229 0-6.046 0.352-12.009 1.011-17.88L351.22 442.116c-28.371 26.943-66.723 43.479-108.938 43.479-87.388 0-158.229-70.84-158.229-158.229s70.84-158.229 158.229-158.229c43.752 0 83.354 17.758 111.997 46.459l258.676-129.779c-0.964-7.062-1.474-14.266-1.474-21.592 0-87.389 70.84-158.229 158.229-158.229s158.229 70.84 158.229 158.229C927.938 151.612 857.103 222.453 769.714 222.453L769.714 222.453z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shezhi1" unicode="&#58912;" d="M946.367 321.895c0.02 21.85-13.04 38.49-31.74 41.57-18.69 3.07-79.05 13.01-85.99 14.14-6.95 1.15-14.09 8.07-15.4 11.45-1.32 3.37-8.94 22.2-11.87 29.46-2.95 7.27-1.92 16.58 4.39 25.52 6.3 8.93 39.9 55.87 48.38 67.72 8.49 11.87 8.65 34.61-4.84 48.39-13.48 13.78-47.75 47.09-56.73 55.86-8.99 8.76-31.08 8.64-42.67 0.43-11.58-8.2-71.69-51.01-71.69-51.01s-9.97-6.89-20.67-2.64c-10.7 4.24-33.43 14.07-33.43 14.07s-7.19 5.43-9.68 19.79c-2.5 14.37-11.11 65.28-14.07 82.7-2.97 17.42-20.67 29.62-37.83 29.46-17.16-0.14-57.91 0-74.33 0s-32.26-15.68-34.75-29.46c-2.49-13.79-11.56-69.16-14.07-84.45-2.52-15.3-11.44-18.48-11.44-18.48s-19.56-8.06-29.91-12.31c-10.34-4.26-15.39-2.64-30.35 7.48-14.95 10.11-44.74 31.03-63.04 43.83-18.3 12.81-38.12 7.92-49.26-3.52s-36.06-35.77-51.02-50.43c-14.95-14.66-12.61-37.54 0.58-55.71 13.2-18.18 32.34-45.43 41.35-58.21 9.01-12.78 10.84-19.5 8.36-26.82-2.49-7.34-6.64-16.58-11.43-27.72-4.81-11.13-9.69-13.64-27.86-17.01-17.36-3.21-58.42-9.92-77.4-13.31-18.99-3.37-30.66-21.43-30.66-41.81l0-64.66c0-24.34 13.2-37.24 38.42-41.93 25.22-4.69 62.66-10.66 74.77-12.61 12.1-1.95 17.67-6.6 21.41-15.54 3.73-8.94 5.13-10.12 9.37-22.57 4.26-12.47 6.46-15.55-4.98-31.67-11.44-16.13-34.31-48.11-46.03-64.51-11.74-16.4-6.45-37.83 4.98-49.85 11.44-12.03 35.47-35.64 48.97-48.97 13.49-13.33 35.19-16.28 53.36-3.52 18.19 12.75 54.98 38.99 65.69 46.62 10.7 7.63 21.91 5.28 27.85 2.94 5.94-2.35 11.25-4.6 22-9.1 10.73-4.48 13.85-11.2 16.41-23.45 2.57-12.24 10.19-56.85 13.93-78.59 3.75-21.72 18.91-33.43 40.62-33.72 21.7-0.29 33.27-0.12 61.57 0 28.29 0.13 41.86 12.61 45.45 31.38 3.59 18.76 12.45 72.94 14.22 83.72 1.78 10.76 5.94 14.73 13.63 18.47 7.7 3.74 14.32 6.47 26.84 11.88 12.51 5.4 18.91 0.66 27.7-5.72 8.8-6.39 47.51-33.78 63.78-45.31 16.28-11.53 36.73-10.33 51.9 4.4 15.18 14.73 31.62 30.99 49.27 48.38 17.64 17.4 12.16 39.59 4.4 51.46-7.77 11.88-44.49 62.95-49.71 70.23-5.21 7.28-4.4 18.62-1.75 24.63 2.64 6.01 8.44 18.24 11.72 25.22 3.29 6.97 9.6 11.22 18.18 12.9 8.58 1.69 62.72 11 83.75 14.61 21.03 3.64 31.11 19.92 31.26 39.92C946.427 275.935 946.347 304.525 946.367 321.895zM908.587 254.615c0.21-5.76-4.66-10.65-8.82-11.38-4.17-0.73-63.26-11.38-81.48-14.29-18.21-2.92-33.23-15.07-38.72-28.06-3.98-9.44-5.47-13.51-10.59-26.96-5.12-13.44-4.64-32.19 2.56-42.26 7.2-10.08 46.82-64.9 50.38-70.45s4.27-11.95-1.28-17.5-40.99-41.2-47.39-47.39c-6.41-6.19-11.83-4.8-18.79 0-6.95 4.8-39.61 26.39-64.44 44.36-16.96 12.28-32.82 12.43-48.7 6.02-15.87-6.42 1.28 0.28-22.2-8.97-23.48-9.25-30.23-27.62-33.73-48.24-3.5-20.63-10.67-62.98-11.95-70.45-1.28-7.47-5.55-11.1-13.66-11.1l-64.9 0c-8.11 0-11.74 2.99-14.52 11.95-2.77 8.97-10.03 54.87-12.8 74.29-2.78 19.43-13.82 36.12-24.77 40.56-10.94 4.45-4.98 2.14-27.32 11.1-22.34 8.97-39.63 4.5-51.23-3.84-11.61-8.34-58.64-42.69-65.33-46.96-6.68-4.28-14.65-3.28-18.35 0.42-3.7 3.7-40.56 40.56-46.54 46.54-5.98 5.98-5.36 12.92 0 20.49 5.36 7.58 28.39 40.76 40.99 57.95 12.59 17.2 17.93 34.74 9.82 53.49-8.12 18.74-4.42 10.24-12.39 28.6-7.96 18.36-24.28 24.46-38.42 26.9-14.14 2.43-68.88 11.53-76.85 13.23-7.97 1.71-11.95 7.26-11.95 14.09l0 66.18c0 9.53 7.67 12.44 12.38 13.23 4.7 0.8 54.22 9.18 73 12.39 18.79 3.2 36.36 11.32 43.55 29.03 7.19 17.7 4.27 11.1 11.1 27.32 6.83 16.23 3.8 33.94-7.68 49.96-11.49 16.01-38.85 54-44.4 61.9-5.55 7.9-5.77 12.6 0.85 19.21 6.62 6.62 42.05 42.48 46.96 46.97 4.91 4.48 12.07 5.4 18.36 0.85 6.3-4.55 49.31-35.65 64.04-46.11 14.73-10.46 32.35-12.56 49.1-5.55 16.75 7.02 10.25 4.48 26.9 11.1s24.84 19.09 28.18 39.71c3.33 20.61 11.95 74.14 12.81 77.7 0.85 3.55 5.55 10.46 11.74 10.46s65.82-0.07 69.8 0c3.99 0.07 10.3-3.29 11.32-9.18 1.02-5.9 13.02-74.29 14.94-86.25 1.92-11.95 15.58-28.57 25.54-32.73 9.96-4.16 21.35-8.75 31.31-13.09 9.97-4.34 30.13-1.91 36.15 2.28 6.03 4.18 70.52 48.81 75.43 52.37 4.91 3.56 11.52 3.27 17.64-2.85s43.34-43.19 47.54-47.53c4.19-4.34 4.66-8.66 1.14-13.66-3.53-5.01-36.72-51.8-47.54-67.46-10.81-15.65-11.73-33.73-5.41-48.96 6.33-15.22 3.99-9.39 9.11-21.91 5.13-12.53 16.28-29.03 33.59-31.88 17.31-2.85 76.92-12.74 84.82-13.95 7.9-1.21 11.1-7.18 11.1-13.37S908.377 260.385 908.587 254.615zM526.833 489.195c-110.45 0-200-89.54-200-200s89.55-200 200-200c110.46 0 200 89.54 200 200S637.293 489.195 526.833 489.195zM526.833 124.195c-91.12 0-165 73.87-165 165s73.88 165 165 165c91.13 0 165-73.87 165-165S617.963 124.195 526.833 124.195z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yinqing" unicode="&#58920;" d="M422.214332 276.704133 186.183684 276.704133l0 46.568461 236.030648 0c10.379577 40.075407 46.47537 69.794509 89.785668 69.794509 51.432433 0 93.067103-41.657943 93.067103-93.067103C605.067103 248.567567 563.40916 206.909624 512 206.909624 468.689703 206.909624 432.593909 236.651999 422.214332 276.704133L422.214332 276.704133zM512 695.634098c-218.529658 0-395.634098-177.10444-395.634098-395.634098 0-218.529658 177.10444-395.634098 395.634098-395.634098 154.76275 0 288.417257 89.064217 353.440885 218.55293l101.398692-59.112389-23.063141-39.959044-62.161099 35.909613c-33.745261-51.595341-77.42792-96.115813-129.093079-129.744711l35.653614-61.765464-40.308133-23.295867-35.653614 61.765464c-53.620057-27.345298-113.360805-44.404109-176.894987-47.73209L535.319139-211.997068l-46.568461 0 0 70.981412c-63.534182 3.327981-123.27493 20.386792-176.894987 47.73209l-35.653614-61.765464-40.308133 23.295867 35.653614 61.765464c-51.665159 33.628898-95.347818 78.149371-129.093079 129.744711l-62.161099-35.909613-23.295867 40.308133 62.114553 35.863067c-27.415116 53.550239-44.799743 113.104807-48.127724 176.685534L0.002932 276.704133l0 46.568461 70.958139 0c3.327981 63.580727 20.712609 123.135295 48.127724 176.685534l-62.114553 35.863067 23.295867 40.308133 62.161099-35.909613c33.745261 51.595341 77.42792 96.115813 129.093079 129.744711l-35.653614 61.765464 40.308133 23.295867 35.653614-61.765464c53.620057 27.345298 113.360805 44.404109 176.894987 47.73209L488.727406 811.997068l46.568461 0 0-70.981412c63.534182-3.327981 123.27493-20.386792 176.894987-47.73209l35.653614 61.765464 40.308133-23.295867-35.653614-61.765464c51.665159-33.628898 95.347818-78.149371 129.093079-129.744711l62.161099 35.909613 23.063141-39.959044-101.398692-59.112389C800.417257 606.569881 666.76275 695.634098 512 695.634098L512 695.634098z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yuejuancuohao" unicode="&#4102;" d="M783.483 701.249 512 429.775 240.517 701.249c-10.082 10.083-26.429 10.083-36.51 0-10.083-10.082-10.083-26.429 0-36.509l271.481-271.475L204.008 121.788c-10.083-10.081-10.083-26.428 0-36.508 10.082-10.082 26.429-10.082 36.51 0L512 356.755l271.483-271.475c10.082-10.082 26.429-10.082 36.513 0 10.081 10.083 10.081 26.428 0 36.508L548.51 393.265l271.485 271.474c10.081 10.083 10.081 26.429 0 36.509C809.912 711.33 793.564 711.33 783.483 701.249z" horiz-adv-x="1024" /> + + + <glyph glyph-name="cuo" unicode="&#4103;" d="M512 822.022125c-217.47508 0-394.423141-176.949085-394.423141-394.423141 0-217.474057 176.948061-394.422118 394.423141-394.422118 217.473033 0 394.422118 176.948061 394.422118 394.422118C906.422118 645.07304 729.473033 822.022125 512 822.022125zM702.228529 270.929782c8.030907-8.030907 8.030907-21.052478 0-29.083385s-21.052478-8.030907-29.083385 0L512 402.992563 350.853833 241.847419c-8.030907-8.030907-21.052478-8.030907-29.083385 0s-8.030907 21.052478 0 29.083385l161.146167 161.146167L321.771471 593.222115c-8.030907 8.030907-8.030907 21.052478 0 29.083385s21.052478 8.030907 29.083385 0l161.146167-161.146167L673.145144 622.305501c8.030907 8.030907 21.052478 8.030907 29.083385 0s8.030907-21.052478 0-29.083385L541.082362 432.075949 702.228529 270.929782z" horiz-adv-x="1024" /> + + + <glyph glyph-name="baobiao" unicode="&#58921;" d="M963.930903 95.219033l0 34.824133-37.354769-2.675946L926.576133 610.853817 691.413206 610.853817l0 70.462818L330.260819 681.316635l0-70.462818L95.690386 610.853817l0-480.809627-35.621289 0 0-34.824133 432.583253 0 0-141.228535-90.313935 0 0-35.307134 216.753649 0 0 35.307134-90.313935 0L528.778128 95.219033 963.930903 95.219033zM366.212636 646.008478 655.216819 646.008478l0-35.307134L366.212636 610.701344 366.212636 646.008478zM364.817869 248.731336 222.224244 322.252817l14.295588 27.736715 123.238812-63.523779 173.928285 159.755494 127.5807-92.634794 93.13826 122.414027 12.420891-9.449209 12.420891-9.449209L667.639756 310.365068l-131.636063 95.621824L364.817869 248.731336z" horiz-adv-x="1024" /> + + + <glyph glyph-name="star" unicode="&#58880;" d="M749.624889-84.152889c-15.672889 0-31.246222 3.882667-45.084444 11.306667l-192.526222 103.637333L319.544889-72.817778c-31.203556-16.64-70.314667-14.392889-99.043556 5.304889-29.511111 20.337778-44.743111 55.921778-38.840889 90.695111l37.703111 225.251556L56.661333 410.908444c-25.002667 24.888889-33.464889 60.984889-22.058667 94.193778 11.349333 32.910222 40.064 56.576 74.965333 61.752889l221.326222 32.896 96.128 199.580444c15.488 32.085333 48.853333 52.807111 84.992 52.807111 36.167111 0 69.518222-20.736 84.963556-52.807111l96.156444-199.580444 221.297778-32.910222c34.872889-5.162667 63.616-28.8 74.979556-61.696 11.392-33.28 2.944-69.361778-22.030222-94.250667L804.622222 248.433778l37.745778-225.28c5.845333-34.773333-9.386667-70.357333-38.812444-90.638222C787.569778-78.392889 768.938667-84.152889 749.624889-84.152889zM512.014222 91.548444c4.636444 0 9.272889-1.137778 13.482667-3.384889l205.937778-110.862222c12.373333-6.641778 28.316444-5.802667 39.936 2.133333 11.392 7.836444 17.123556 21.006222 14.890667 34.304L746.097778 253.496889c-1.507556 9.088 1.450667 18.332444 7.964444 24.832l173.141333 172.842667c9.457778 9.429333 12.686222 23.025778 8.405333 35.484444-4.380444 12.672-15.701333 21.873778-29.525333 23.921778L669.866667 545.706667c-9.315556 1.379556-17.365333 7.296-21.447111 15.786667L545.720889 774.641778c-6.030222 12.529778-19.256889 20.608-33.706667 20.608s-27.690667-8.092444-33.763556-20.622222L375.608889 561.493333c-4.081778-8.490667-12.131556-14.407111-21.447111-15.786667L117.930667 510.577778c-13.624889-2.033778-25.201778-11.434667-29.539556-23.992889-4.266667-12.416-1.024-25.984 8.433778-35.399111L269.937778 278.328889c6.513778-6.499556 9.472-15.744 7.964444-24.832l-40.135111-239.744c-2.247111-13.312 3.484444-26.439111 14.976-34.360889 11.434667-7.836444 27.349333-8.775111 39.950222-2.062222l205.852444 110.833778C502.741333 90.410667 507.377778 91.548444 512.014222 91.548444zM200.32 439.210667c-6.840889 0-12.885333 4.963556-14.023111 11.946667-1.251556 7.751111 4.010667 15.061333 11.761778 16.312889l9.443556 1.536c7.793778 1.336889 15.061333-4.010667 16.312889-11.761778 1.251556-7.751111-4.010667-15.061333-11.761778-16.312889l-9.443556-1.536C201.856 439.267556 201.073778 439.210667 200.32 439.210667zM252.544 447.687111c-6.684444 0-12.643556 4.721778-13.937778 11.534222-1.493333 7.708444 3.555556 15.175111 11.264 16.654222l153.927111 29.696 58.055111 133.148444c3.157333 7.182222 11.548444 10.496 18.716444 7.352889 7.210667-3.143111 10.510222-11.52 7.367111-18.716444l-61.056-140.017778c-1.877333-4.295111-5.745778-7.395556-10.353778-8.277333l-161.28-31.118222C254.336 447.758222 253.44 447.687111 252.544 447.687111z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yuandian" unicode="&#58903;" d="M513.133312 830.673156c-247.538793 0-448.208115-200.669322-448.208115-448.207092 0-247.538793 200.670346-448.208115 448.208115-448.208115 247.538793 0 448.208115 200.670346 448.208115 448.208115C961.341427 630.004857 760.673128 830.673156 513.133312 830.673156zM513.132288-6.649188c-214.901465 0-389.113205 174.212764-389.113205 389.114229 0 214.902488 174.21174 389.115252 389.113205 389.115252 214.903511 0 389.115252-174.212764 389.115252-389.115252C902.24754 167.563576 728.0358-6.649188 513.132288-6.649188zM513.133312 382.465041m-344.602456 0a336.754 336.754 0 1 0 689.204911 0 336.754 336.754 0 1 0-689.204911 0Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="kefu" unicode="&#58886;" d="M132.682393 414.567179c0 208.287837 166.471452 377.143593 379.317095 377.143593s385.380184-168.855756 385.380184-377.143593c0-177.196725-122.197086-325.812507-290.49821-366.259708l-116.291586-51.04763 0 41.126676C290.570353 52.175569 132.682393 215.312066 132.682393 414.567179zM83.799056 414.567179c0-211.946157 160.764474-387.135154 369.469819-415.152255-3.2623-20.458961-10.036587-65.024969-7.286963-65.024969 2.384303 0 114.89068 47.294143 189.700503 78.865185 176.193885 51.91437 304.518528 211.946157 304.518528 401.312038 0 231.432976-191.70823 419.042865-428.200432 419.042865S83.799056 646.000156 83.799056 414.567179zM340.71952 276.635737c22.935362-41.481763 89.831958-75.102489 170.391738-75.102489 79.650061 0 148.489916 32.909527 172.168198 73.681116-12.701277 5.979178-19.068288 8.02886-28.131711 12.21009-19.894096-31.257911-75.425853-59.661821-142.729725-59.661821-66.969251 0-122.836653 28.40391-143.598512 61.083194L340.71952 276.635737z" horiz-adv-x="1024" /> + + + <glyph glyph-name="logo" unicode="&#58889;" d="M990.78144 828.53888c-3.35872 1.59744-7.04512 2.37568-11.01824 2.37568-14.45888 0-27.60704-10.81344-27.40224-10.81344-8.8064-4.42368-880.59904-443.22816-911.44192-459.44832-17.408-9.13408-27.36128-24.73984-25.92768-40.71424 1.10592-13.14816 9.78944-23.51104 23.10144-27.77088 26.17344-8.27392 290.24256-91.58656 290.24256-91.58656l4.83328-1.47456 16.67072 50.05312-254.32064 79.54432 780.73856 406.28224c-82.82112-93.88032-420.53632-476.32384-436.10112-493.93664-20.11136-22.48704-29.4912-45.09696-29.40928-70.98368l0.28672-153.27232-0.08192 0c0 0 0.08192-53.49376 0.08192-53.6576l0-1.96608 0 0c1.18784-13.5168 12.73856-24.24832 26.54208-24.24832s25.51808 10.73152 26.74688 24.24832l0 0c0 0 0.53248 191.03744 0 205.08672-0.49152 12.4928 5.07904 26.54208 10.69056 33.05472 5.65248 6.38976 390.63552 442.61376 465.75616 527.81056-21.38112-106.41408-126.68928-629.76-128.24576-637.41952-0.8192-4.05504-2.58048-4.05504-3.35872-4.05504-0.6144 0-1.31072 0.12288-2.048 0.36864-7.45472 2.37568-268.82048 81.55136-279.92064 84.91008l-4.7104 1.4336-17.16224-50.50368 5.07904-1.59744c2.58048-0.77824 258.90816-79.09376 284.38528-86.46656 5.07904-1.47456 10.24-2.2528 15.44192-2.2528 26.99264 0 49.5616 19.37408 54.8864 46.98112 2.08896 10.93632 27.0336 134.67648 55.9104 277.99552 39.77216 197.14048 84.7872 420.61824 85.93408 427.6224l0.6144 3.31776C1009.70496 798.96576 1013.26848 817.9712 990.78144 828.53888z" horiz-adv-x="1024" /> + + + <glyph glyph-name="list" unicode="&#58890;" d="M618.04471 733.97072l-397.175835 0c-16.927531 0-30.699186-13.771655-30.699186-30.699186l0-638.543068c0-16.927531 13.771655-30.699186 30.699186-30.699186l582.261227 0c16.927531 0 30.699186 13.771655 30.699186 30.699186l-0.726547 476.760404L618.04471 733.97072zM803.771715 541.488871 619.537713 541.488871 619.537713 705.552483 803.771715 541.488871zM813.363164 64.728466c0-5.64251-4.590552-10.233062-10.233062-10.233062l-582.261227 0c-5.64251 0-10.233062 4.590552-10.233062 10.233062l0 638.543068c0 5.64251 4.590552 10.233062 10.233062 10.233062l378.202715 0 0-192.481849 214.291574 0L813.363164 64.728466zM298.129516 482.495268l55.258535 0 0-55.258535-55.258535 0 0 55.258535ZM399.777591 468.168981l323.364759 0 0-26.605961-323.364759 0 0 26.605961ZM298.129516 342.044446l55.258535 0 0-55.258535-55.258535 0 0 55.258535ZM399.777591 327.718159l323.364759 0 0-26.605961-323.364759 0 0 26.605961ZM298.129516 199.804884l55.258535 0 0-55.258535-55.258535 0 0 55.258535ZM399.777591 185.478598l323.364759 0 0-26.605961-323.364759 0 0 26.605961ZM881.315812 53.053566" horiz-adv-x="1024" /> + + + <glyph glyph-name="tubiao" unicode="&#58924;" d="M953.440991 231.668729 784.061302 231.668729 681.06451 353.392024c-0.312108 0.373507-0.635473 0.737804-0.969071 1.094938-0.013303 0.014326-0.026606 0.027629-0.039909 0.041956-0.276293 0.293689-0.559748 0.582261-0.851391 0.86367-0.053212 0.051165-0.107447 0.099261-0.160659 0.150426-0.249687 0.237407-0.50142 0.470721-0.76134 0.697895-0.089028 0.078795-0.181125 0.153496-0.272199 0.230244-0.225127 0.191358-0.451278 0.381693-0.683569 0.565888-0.124843 0.099261-0.251733 0.192382-0.3776 0.288572-0.200568 0.153496-0.402159 0.306992-0.607844 0.454348-0.159636 0.11461-0.322341 0.224104-0.485047 0.334621-0.177032 0.12075-0.354064 0.242524-0.535189 0.35918-0.195451 0.12689-0.394996 0.246617-0.593518 0.367367-0.152473 0.092098-0.302899 0.186242-0.457418 0.275269-0.237407 0.137123-0.477884 0.268106-0.718361 0.397043-0.121773 0.065492-0.2415 0.132006-0.364297 0.195451-0.283456 0.146333-0.571005 0.285502-0.859577 0.420579-0.085958 0.040932-0.170892 0.082888-0.257873 0.122797-0.337691 0.154519-0.679475 0.298805-1.022283 0.437975-0.044002 0.017396-0.086981 0.036839-0.130983 0.055259-1.604544 0.638543-3.2623 1.113357-4.948709 1.416256-0.343831 0.062422-0.687662 0.112564-1.031493 0.160659-0.055259 0.008186-0.110517 0.01842-0.165776 0.025583-1.633197 0.216941-3.25923 0.26913-4.861728 0.173962-0.013303-0.001023-0.026606-0.001023-0.040932-0.002047-0.363274-0.022513-0.724501-0.054235-1.085728-0.091074-0.060375-0.00614-0.119727-0.011256-0.180102-0.017396-0.310062-0.034792-0.618077-0.077771-0.926092-0.122797-0.116657-0.017396-0.232291-0.032746-0.348947-0.051165-0.24764-0.040932-0.494257-0.086981-0.740874-0.135076-0.178055-0.033769-0.355087-0.067538-0.532119-0.105401-0.183172-0.039909-0.36532-0.083911-0.547469-0.127913-0.237407-0.056282-0.474814-0.113587-0.710175-0.176009-0.12075-0.032746-0.240477-0.068562-0.360204-0.102331-0.292666-0.082888-0.584308-0.168846-0.874927-0.26299-0.063445-0.020466-0.125867-0.042979-0.188288-0.063445-0.338714-0.112564-0.675382-0.230244-1.010003-0.357134-0.019443-0.007163-0.038886-0.01535-0.058328-0.022513-1.493004-0.571005-2.948145-1.284249-4.340865-2.149966-0.067538-0.041956-0.13303-0.088004-0.200568-0.12996-0.273223-0.172939-0.545422-0.346901-0.813528-0.531096-1.416256-0.971118-2.734274-2.089591-3.936659-3.333932-0.025583-0.026606-0.049119-0.053212-0.074701-0.079818-0.26299-0.275269-0.521886-0.555655-0.773619-0.843204-0.058328-0.066515-0.112564-0.134053-0.169869-0.200568-0.211824-0.246617-0.420579-0.496304-0.62217-0.751107-0.083911-0.106424-0.164752-0.214894-0.246617-0.322341-0.167822-0.218988-0.334621-0.437975-0.49528-0.663102-0.102331-0.14224-0.199545-0.287549-0.298805-0.431835-0.13303-0.194428-0.26606-0.387833-0.393973-0.586354-0.115634-0.179079-0.225127-0.360204-0.335644-0.541329-0.103354-0.168846-0.207731-0.336668-0.306992-0.508583-0.12689-0.220011-0.24764-0.443092-0.36839-0.666172-0.074701-0.138146-0.151449-0.275269-0.223081-0.416486-0.137123-0.265036-0.265036-0.533143-0.39295-0.802272-0.050142-0.105401-0.101307-0.209778-0.150426-0.316202-0.144286-0.317225-0.279363-0.63752-0.410346-0.958838-0.026606-0.064468-0.055259-0.127913-0.080841-0.193405-0.150426-0.378623-0.291642-0.760317-0.423649-1.14508-0.005117-0.016373-0.011256-0.031722-0.017396-0.048095-0.157589-0.463558-0.303922-0.930185-0.434905-1.400906l-97.897657-342.642824L435.093423 727.832042c-0.071631 0.569982-0.165776 1.13587-0.275269 1.696642-0.008186 0.040932-0.017396 0.081864-0.025583 0.12382-0.071631 0.356111-0.148379 0.709151-0.234337 1.061169-0.031722 0.128937-0.065492 0.255827-0.099261 0.38374-0.066515 0.254803-0.135076 0.508583-0.208754 0.760317-0.060375 0.206708-0.124843 0.411369-0.190335 0.615007-0.053212 0.166799-0.107447 0.332575-0.164752 0.49835-0.092098 0.26913-0.190335 0.535189-0.290619 0.800225-0.037862 0.098237-0.074701 0.196475-0.113587 0.293689-0.12382 0.313132-0.25378 0.623193-0.38988 0.930185-0.022513 0.050142-0.044002 0.100284-0.066515 0.150426-0.152473 0.338714-0.311085 0.672312-0.477884 1.00284-0.01228 0.024559-0.024559 0.049119-0.037862 0.074701-0.173962 0.343831-0.356111 0.682545-0.545422 1.017166-0.011256 0.019443-0.022513 0.039909-0.033769 0.059352-0.188288 0.330528-0.382717 0.654916-0.584308 0.975211-0.021489 0.034792-0.044002 0.068562-0.065492 0.103354-0.190335 0.298805-0.385786 0.592494-0.587378 0.88209-0.045025 0.065492-0.091074 0.12996-0.137123 0.194428-0.180102 0.252757-0.363274 0.502443-0.551562 0.74906-0.079818 0.105401-0.162706 0.208754-0.24457 0.312108-0.157589 0.199545-0.317225 0.396019-0.480954 0.590448-0.124843 0.149403-0.252757 0.295735-0.381693 0.442068-0.125867 0.14224-0.251733 0.284479-0.38067 0.424672-0.174985 0.191358-0.355087 0.378623-0.536212 0.563842-0.088004 0.090051-0.176009 0.180102-0.26606 0.26913-0.224104 0.222057-0.452301 0.440022-0.684592 0.653893-0.054235 0.050142-0.10847 0.100284-0.163729 0.150426-0.265036 0.240477-0.535189 0.474814-0.810459 0.704035-0.028653 0.023536-0.056282 0.047072-0.084934 0.070608-0.294712 0.243547-0.595564 0.479931-0.902556 0.711198-0.01535 0.011256-0.029676 0.022513-0.045025 0.033769-0.311085 0.232291-0.627287 0.458441-0.949628 0.677429-0.019443 0.013303-0.037862 0.025583-0.057305 0.038886-0.309038 0.208754-0.623193 0.411369-0.942465 0.606821-0.045025 0.027629-0.090051 0.054235-0.134053 0.081864-0.288572 0.174985-0.581238 0.343831-0.877997 0.50756-0.090051 0.050142-0.181125 0.098237-0.272199 0.147356-0.25071 0.134053-0.502443 0.265036-0.759293 0.391926-0.156566 0.077771-0.314155 0.151449-0.472767 0.226151-0.194428 0.091074-0.38988 0.182149-0.587378 0.268106-0.239454 0.105401-0.481977 0.204661-0.724501 0.302899-0.12382 0.049119-0.246617 0.100284-0.37146 0.148379-0.334621 0.128937-0.673335 0.249687-1.014096 0.36532-0.042979 0.014326-0.085958 0.029676-0.128937 0.044002-1.6158 0.536212-3.296069 0.915859-5.02034 1.119497-0.01535 0.002047-0.029676 0.004093-0.044002 0.00614-0.309038 0.035816-0.620124 0.062422-0.931209 0.086981-0.132006 0.010233-0.265036 0.025583-0.397043 0.033769-0.174985 0.011256-0.349971 0.01535-0.525979 0.022513-0.270153 0.01228-0.539282 0.024559-0.808412 0.027629-0.054235 0.001023-0.10847-0.001023-0.162706-0.001023-1.696642 0.010233-3.371794-0.149403-5.006014-0.466628-0.065492-0.01228-0.12996-0.027629-0.195451-0.039909-0.331551-0.067538-0.662079-0.13917-0.989537-0.218988-0.148379-0.035816-0.295735-0.075725-0.443092-0.11461-0.234337-0.061398-0.468674-0.124843-0.700965-0.192382-0.224104-0.065492-0.445138-0.135076-0.666172-0.206708-0.149403-0.048095-0.297782-0.096191-0.446162-0.147356-0.286526-0.098237-0.568958-0.201591-0.850367-0.309038-0.079818-0.030699-0.160659-0.061398-0.240477-0.093121-0.330528-0.12996-0.655939-0.267083-0.979304-0.410346-0.033769-0.01535-0.067538-0.029676-0.101307-0.045025-0.355087-0.159636-0.705058-0.325411-1.050935-0.500397-0.008186-0.004093-0.016373-0.008186-0.023536-0.01228-0.360204-0.182149-0.714268-0.372483-1.064238-0.569982-0.004093-0.002047-0.008186-0.005117-0.013303-0.007163-0.344854-0.196475-0.684592-0.399089-1.019213-0.610914-0.020466-0.013303-0.040932-0.025583-0.060375-0.038886-0.313132-0.199545-0.621147-0.404206-0.925069-0.61603-0.050142-0.034792-0.099261-0.070608-0.149403-0.105401-0.268106-0.190335-0.532119-0.38374-0.791016-0.583285-0.091074-0.069585-0.181125-0.141216-0.271176-0.212848-0.212848-0.167822-0.422625-0.337691-0.629333-0.512676-0.137123-0.11461-0.271176-0.232291-0.406253-0.349971-0.154519-0.1361-0.308015-0.272199-0.459464-0.412392-0.179079-0.164752-0.354064-0.332575-0.528026-0.502443-0.102331-0.100284-0.204661-0.199545-0.304945-0.301875-0.211824-0.212848-0.418532-0.430812-0.623193-0.651846-0.059352-0.064468-0.119727-0.128937-0.179079-0.194428-0.231267-0.254803-0.456395-0.515746-0.678452-0.780783-0.031722-0.037862-0.063445-0.075725-0.095167-0.11461-0.23536-0.285502-0.465604-0.577145-0.688685-0.874927-0.01842-0.024559-0.036839-0.048095-0.055259-0.072655-0.226151-0.301875-0.445138-0.60989-0.657986-0.923022-0.019443-0.028653-0.038886-0.057305-0.058328-0.084934-0.202615-0.300852-0.400113-0.606821-0.590448-0.916882-0.032746-0.053212-0.064468-0.105401-0.096191-0.158612-0.169869-0.282433-0.335644-0.567935-0.49528-0.857531-0.053212-0.097214-0.105401-0.194428-0.158612-0.292666-0.130983-0.24457-0.258896-0.490164-0.381693-0.73985-0.080841-0.162706-0.157589-0.326435-0.234337-0.491187-0.088004-0.189312-0.177032-0.378623-0.260943-0.571005-0.107447-0.245593-0.209778-0.493234-0.310062-0.741897-0.047072-0.11768-0.095167-0.234337-0.141216-0.354064-0.130983-0.340761-0.25378-0.684592-0.370437-1.030469-0.013303-0.037862-0.026606-0.075725-0.038886-0.113587-0.180102-0.543376-0.345877-1.092891-0.48914-1.650593L244.22942 221.599396 67.355037 221.599396c-14.128789 0-25.582655-11.453866-25.582655-25.582655s11.453866-25.582655 25.582655-25.582655l191.314257 0c0.867764 0 1.725294 0.044002 2.570545 0.128937 0.828878-0.080841 1.656733-0.1361 2.478448-0.1361 11.218506 0 21.512966 7.439436 24.644283 18.779715l113.358791 410.43686 103.412254-723.884758c0.00921-0.072655 0.021489-0.145309 0.030699-0.217964l0.046049-0.320295c0.002047-0.011256 0.005117-0.021489 0.00614-0.032746 0.109494-0.7552 0.25071-1.502213 0.425695-2.238994 0.01535-0.064468 0.031722-0.12689 0.047072-0.191358 0.166799-0.679475 0.358157-1.350764 0.579191-2.01182 0.041956-0.124843 0.088004-0.24764 0.130983-0.37146 0.210801-0.600681 0.437975-1.194198 0.692778-1.77646 0.068562-0.156566 0.144286-0.309038 0.215918-0.464581 0.223081-0.484024 0.460488-0.961908 0.713244-1.431605 0.106424-0.196475 0.213871-0.390903 0.325411-0.584308 0.265036-0.462534 0.545422-0.914836 0.838088-1.359974 0.088004-0.13303 0.170892-0.268106 0.260943-0.399089 0.354064-0.51677 0.732687-1.016143 1.12359-1.506307 0.078795-0.099261 0.156566-0.198521 0.237407-0.296759 0.420579-0.511653 0.864694-1.004887 1.325182-1.482771 0.051165-0.052189 0.101307-0.105401 0.152473-0.157589 0.494257-0.50449 1.010003-0.989537 1.548262-1.454118 0.00921-0.007163 0.017396-0.014326 0.026606-0.022513 1.636267-1.408069 3.466961-2.620687 5.466502-3.592828 0.075725-0.036839 0.151449-0.074701 0.228197-0.11154 0.576121-0.273223 1.165546-0.525979 1.768273-0.75827 0.158612-0.061398 0.319272-0.118704 0.478907-0.177032 0.558725-0.202615 1.124614-0.393973 1.704828-0.559748 0.005117-0.001023 0.010233-0.002047 0.01535-0.004093 0.278339-0.079818 0.562818-0.13917 0.844228-0.209778 0.394996-0.098237 0.789992-0.194428 1.184989-0.274246 0.283456-0.056282 0.568958-0.103354 0.854461-0.149403 0.445138-0.073678 0.889253-0.134053 1.333368-0.183172 0.229221-0.024559 0.456395-0.052189 0.686638-0.071631 0.710175-0.059352 1.418302-0.099261 2.122337-0.099261 0.337691 0 0.671289 0.027629 1.007957 0.040932 0.276293 0.011256 0.550539 0.013303 0.828878 0.033769 0.401136 0.029676 0.799202 0.079818 1.196245 0.127913 0.191358 0.022513 0.38067 0.033769 0.572028 0.061398 0.069585 0.010233 0.1361 0.024559 0.205685 0.034792 0.232291 0.034792 0.462534 0.075725 0.692778 0.116657 0.463558 0.082888 0.921999 0.176009 1.3743 0.283456 0.109494 0.025583 0.218988 0.047072 0.327458 0.074701 0.582261 0.145309 1.152243 0.316202 1.716084 0.499373 0.098237 0.031722 0.196475 0.063445 0.293689 0.097214 1.90335 0.644683 3.694135 1.50119 5.351891 2.540869 0.014326 0.00921 0.028653 0.01842 0.042979 0.027629 1.089821 0.686638 2.121314 1.452071 3.087315 2.287089 0.083911 0.071631 0.167822 0.143263 0.25071 0.215918 0.424672 0.3776 0.837064 0.76748 1.235131 1.170662 0.12382 0.124843 0.243547 0.254803 0.36532 0.382717 0.317225 0.334621 0.626263 0.677429 0.925069 1.028423 0.155543 0.183172 0.308015 0.36839 0.458441 0.556679 0.26606 0.331551 0.523933 0.670266 0.773619 1.01512 0.130983 0.180102 0.261966 0.35918 0.387833 0.543376 0.294712 0.429789 0.575098 0.86981 0.843204 1.316995 0.099261 0.165776 0.195451 0.334621 0.290619 0.503467 0.283456 0.499373 0.555655 1.004887 0.806365 1.52268 0.031722 0.065492 0.060375 0.13303 0.091074 0.199545 0.276293 0.584308 0.530073 1.178849 0.762363 1.784646 0.00614 0.017396 0.014326 0.034792 0.020466 0.051165 0.251733 0.661056 0.472767 1.336438 0.669242 2.020006 0.002047 0.008186 0.00614 0.016373 0.008186 0.024559l0.061398 0.215918c0.029676 0.106424 0.062422 0.210801 0.090051 0.317225l117.579929 411.527704 79.800487-94.308923c0.070608-0.083911 0.146333-0.161682 0.217964-0.243547 0.190335-0.220011 0.38374-0.436952 0.581238-0.649799 0.134053-0.144286 0.26913-0.285502 0.405229-0.425695 0.164752-0.168846 0.331551-0.335644 0.50142-0.500397 0.164752-0.159636 0.329505-0.319272 0.496304-0.473791 0.138146-0.12689 0.279363-0.25071 0.419556-0.37453 0.198521-0.174985 0.397043-0.350994 0.599657-0.518816 0.081864-0.067538 0.166799-0.132006 0.249687-0.198521 0.817622-0.661056 1.667989-1.264806 2.545986-1.811252 0.098237-0.061398 0.195451-0.125867 0.294712-0.185218 0.228197-0.138146 0.459464-0.267083 0.691755-0.398066 0.157589-0.089028 0.315178-0.178055 0.474814-0.264013 0.200568-0.107447 0.403183-0.208754 0.606821-0.311085 0.202615-0.101307 0.406253-0.201591 0.611937-0.297782 0.173962-0.080841 0.348947-0.159636 0.523933-0.237407 0.245593-0.10847 0.494257-0.212848 0.743944-0.313132 0.144286-0.058328 0.289596-0.115634 0.434905-0.171915 0.291642-0.11154 0.586354-0.216941 0.883113-0.317225 0.11154-0.037862 0.223081-0.076748 0.334621-0.113587 0.337691-0.109494 0.677429-0.210801 1.02126-0.305969 0.078795-0.021489 0.157589-0.046049 0.236384-0.066515 0.376577-0.101307 0.757247-0.193405 1.140986-0.277316 0.050142-0.011256 0.100284-0.023536 0.150426-0.034792 0.405229-0.085958 0.813528-0.162706 1.225921-0.229221 0.031722-0.005117 0.063445-0.01228 0.096191-0.017396 0.412392-0.065492 0.828878-0.12075 1.24741-0.165776 0.032746-0.004093 0.064468-0.00921 0.097214-0.01228 0.382717-0.039909 0.768503-0.068562 1.155313-0.092098 0.068562-0.004093 0.1361-0.01228 0.204661-0.01535 0.25992-0.013303 0.521886-0.01535 0.782829-0.020466 0.188288-0.004093 0.376577-0.01535 0.564865-0.01535 0.008186 0 0.01535 0.001023 0.023536 0.001023l181.208085 0c14.129812 0 25.582655 11.453866 25.582655 25.582655S967.56978 231.668729 953.440991 231.668729z" horiz-adv-x="1024" /> + + + <glyph glyph-name="right" unicode="&#4101;" d="M516.152065-63.152063c-60.696384 0-119.594819 11.894911-175.056991 35.353183-53.55473 22.651906-101.646028 55.073316-142.936433 96.364745-41.291428 41.291428-73.712839 89.381703-96.363721 142.936433-23.458271 55.462173-35.353183 114.359584-35.353183 175.055968s11.894911 119.594819 35.353183 175.056991c22.651906 53.55473 55.073316 101.646028 96.363721 142.936433 41.290405 41.291428 89.381703 73.712839 142.936433 96.363721 55.462173 23.458271 114.359584 35.353183 175.056991 35.353183s119.594819-11.894911 175.056991-35.353183c53.55473-22.651906 101.645005-55.073316 142.936433-96.363721 41.291428-41.290405 73.711815-89.38068 96.363721-142.936433 23.459295-55.462173 35.353183-114.359584 35.353183-175.056991 0-60.696384-11.893888-119.593795-35.353183-175.055968-22.651906-53.55473-55.072293-101.645005-96.363721-142.936433s-89.381703-73.712839-142.936433-96.364745C635.747907-51.257152 576.849472-63.152063 516.152065-63.152063zM516.152065 774.870222c-214.115566 0-388.311956-174.196391-388.311956-388.311956s174.196391-388.311956 388.311956-388.311956 388.311956 174.196391 388.311956 388.311956S730.268654 774.870222 516.152065 774.870222zM434.74908 132.830517 209.49278 358.08784 289.087583 437.68162 434.74908 292.020122 743.218594 600.488613 822.812373 520.89381Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="huanfu2" unicode="&#58907;" d="M958.830745 538.643056 740.659817 692.753993l-100.539834 0-3.977591-9.332553c-0.37146-0.871857-38.021965-86.8613-124.772748-88.667435-35.691897 0.76441-67.206658 15.500019-93.680613 43.828204-20.658506 22.106484-30.374798 44.584428-30.456662 44.776809l-3.955078 9.393951-100.587929 0L64.518433 538.643056 169.320337 379.756349l89.956801 65.019853-19.016099-368.05254 268.86654 0 4.093225 0 269.866311 0-19.016099 368.051517 89.956801-65.018829L958.830745 538.643056zM730.105437 507.20402l20.655436-399.781172-237.540068 0-4.093225 0L272.587282 107.422847l20.656459 399.781172-115.938546-83.797521-36.3243 55.070246 159.440315 111.641683-19.276019 30.638811L121.066333 508.667348l-14.548344 22.056342 185.921433 131.330094 71.077825 0c5.332449-10.04375 15.433504-26.779923 30.951943-43.580564 32.047904-34.69622 72.256674-53.486168 116.345822-54.411237l0-0.031722c0.203638 0.00307 0.406253 0.01228 0.60989 0.016373 0.203638-0.00307 0.406253-0.013303 0.60989-0.016373l0 0.031722c44.073798 0.925069 84.359316 19.703761 116.566856 54.379515 15.623839 16.821107 25.814945 33.579793 31.188326 43.612287l71.120804 0 185.921433-131.330094-14.548344-22.056342L742.203986 620.755192l-19.276019-30.638811 159.440315-111.641683-36.3243-55.070246L730.105437 507.20402z" horiz-adv-x="1024" /> + + + <glyph glyph-name="On-line" unicode="&#58896;" d="M680.2 541.4 430.6 290l-94.4 94.4-35.6-35.6 112-112c5-5 11.8-9 17.8-9s12.6 4 17.6 8.8l267.4 268.8L680.2 541.4zM512 800C282.2 800 96 613.8 96 384s186.2-416 416-416c229.8 0 416 186.2 416 416S741.8 800 512 800zM512 2.6c-210.2 0-381.4 171-381.4 381.4 0 210.2 171 381.4 381.4 381.4 210.2 0 381.4-171 381.4-381.4C893.4 173.8 722.2 2.6 512 2.6z" horiz-adv-x="1024" /> + + + <glyph glyph-name="biaoge" unicode="&#58925;" d="M304.738028 259.684806M729.544153 427.153982M595.52788 553.723655M143.806755 602.614156l0-601.704045L881.172549 0.910111l0 601.704045L143.806755 602.614156zM420.318416 215.804413l0 128.936581 184.341448 0 0-128.936581L420.318416 215.804413zM604.659865 172.825552l0-128.936581L420.318416 43.888971l0 128.936581L604.659865 172.825552zM604.659865 516.656435l0-128.936581L420.318416 387.719854l0 128.936581L604.659865 516.656435zM374.232798 516.656435l0-128.936581L189.89135 387.719854l0 128.936581L374.232798 516.656435zM189.89135 344.740994 374.232798 344.740994l0-128.936581L189.89135 215.804413 189.89135 344.740994zM650.745483 344.740994l184.341448 0 0-128.936581L650.745483 215.804413 650.745483 344.740994zM650.745483 387.719854l0 128.936581 184.341448 0 0-128.936581L650.745483 387.719854zM189.89135 172.825552 374.232798 172.825552l0-128.936581L189.89135 43.888971 189.89135 172.825552zM650.745483 43.888971l0 128.936581 184.341448 0 0-128.936581L650.745483 43.888971z" horiz-adv-x="1024" /> + + + <glyph glyph-name="youyou" unicode="&#58882;" d="M283.648 721.918976 340.873216 780.926976 740.352 383.997952 340.876288-12.925952 283.648 46.077952 619.52 383.997952Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zuozuo" unicode="&#58883;" d="M740.352 721.918976 683.126784 780.926976 283.648 383.997952 683.123712-12.925952 740.352 46.077952 404.48 383.997952Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="cart" unicode="&#59032;" d="M235.097303 196.866982C247.384597 160.417152 286.382106 132.376068 324.772759 132.376068L861.658537 132.376068 880.429732 132.376068 885.649214 150.541854 1009.08775 580.154957C1021.388907 622.967661 993.187631 660.786325 949.051586 660.786325L424.585365 660.786325C410.791718 660.786325 399.609756 649.520738 399.609756 635.623932 399.609756 621.727125 410.791718 610.461538 424.585365 610.461538L949.051586 610.461538C959.924 610.461538 964.161052 604.779539 961.106394 594.148171L837.667859 164.535068 861.658537 182.700855 324.772759 182.700855C307.742153 182.700855 287.789837 197.047529 282.395194 213.050549L73.600164 832.433664C69.16437 845.592294 54.980454 852.636656 41.919502 848.167687 28.858551 843.698719 21.86648 829.408727 26.302275 816.250097L235.097303 196.866982ZM399.609756-6.017094C399.609756 49.570129 354.881911 94.632478 299.707317 94.632478 244.532723 94.632478 199.804878 49.570129 199.804878-6.017094 199.804878-61.604318 244.532723-106.666667 299.707317-106.666667 354.881911-106.666667 399.609756-61.604318 399.609756-6.017094ZM249.756098-6.017094C249.756098 21.776518 272.120021 44.307693 299.707317 44.307693 327.294613 44.307693 349.658537 21.776518 349.658537-6.017094 349.658537-33.810705 327.294613-56.341879 299.707317-56.341879 272.120021-56.341879 249.756098-33.810705 249.756098-6.017094ZM924.097562-6.017094C924.097562 49.570129 879.369715 94.632478 824.195121 94.632478 769.020529 94.632478 724.292683 49.570129 724.292683-6.017094 724.292683-61.604318 769.020529-106.666667 824.195121-106.666667 879.369715-106.666667 924.097562-61.604318 924.097562-6.017094ZM774.243902-6.017094C774.243902 21.776518 796.607825 44.307693 824.195121 44.307693 851.782419 44.307693 874.146342 21.776518 874.146342-6.017094 874.146342-33.810705 851.782419-56.341879 824.195121-56.341879 796.607825-56.341879 774.243902-33.810705 774.243902-6.017094Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="cry" unicode="&#59036;" d="M1024 384C1024 666.769792 794.769792 896 512 896 229.230208 896 0 666.769792 0 384 0 101.230208 229.230208-128 512-128 629.410831-128 740.826187-88.331046 830.768465-16.686662 841.557579-8.092491 843.33693 7.620766 834.742758 18.409879 826.148587 29.198991 810.43533 30.978342 799.646219 22.384173 718.470035-42.277495 618.001779-78.048781 512-78.048781 256.817504-78.048781 49.951219 128.817504 49.951219 384 49.951219 639.182496 256.817504 846.048781 512 846.048781 767.182496 846.048781 974.048781 639.182496 974.048781 384 974.048781 296.507166 949.714859 212.663236 904.470807 140.039307 897.177109 128.331757 900.755245 112.928203 912.462793 105.634507 924.170342 98.340809 939.573897 101.918942 946.867595 113.626492 997.013826 194.119204 1024 287.101621 1024 384ZM337.170731 396.487806C371.654852 396.487806 399.609756 424.442709 399.609756 458.926829 399.609756 493.41095 371.654852 521.365854 337.170731 521.365854 302.686611 521.365854 274.731708 493.41095 274.731708 458.926829 274.731708 424.442709 302.686611 396.487806 337.170731 396.487806ZM711.804879 396.487806C746.288998 396.487806 774.243902 424.442709 774.243902 458.926829 774.243902 493.41095 746.288998 521.365854 711.804879 521.365854 677.320757 521.365854 649.365854 493.41095 649.365854 458.926829 649.365854 424.442709 677.320757 396.487806 711.804879 396.487806ZM352.788105 191.215475C396.165222 225.917169 453.151987 246.639629 524.487806 246.639629 595.823622 246.639629 652.810387 225.917169 696.187505 191.215475 722.700531 170.005054 738.882517 148.429073 746.631548 132.931012 752.800254 120.593598 747.799529 105.591424 735.462114 99.422716 723.124702 93.25401 708.122526 98.254735 701.953818 110.592149 701.03616 112.427465 698.492224 116.617476 694.165854 122.385971 686.602473 132.470477 676.927317 142.654852 664.983226 152.210125 630.311565 179.947456 584.273939 196.68841 524.487806 196.68841 464.70167 196.68841 418.664045 179.947456 383.992384 152.210125 372.048292 142.654852 362.373137 132.470477 354.809756 122.385971 350.483386 116.617476 347.93945 112.427465 347.021792 110.592149 340.853084 98.254735 325.850908 93.25401 313.513495 99.422716 301.176081 105.591424 296.175356 120.593598 302.344062 132.931012 310.093092 148.429073 326.275078 170.005054 352.788105 191.215475Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="smile" unicode="&#59055;" d="M1024 384C1024 666.769792 794.769792 896 512 896 229.230208 896 0 666.769792 0 384 0 101.230208 229.230208-128 512-128 629.410831-128 740.826187-88.331046 830.768465-16.686662 841.557579-8.092491 843.33693 7.620766 834.742758 18.409879 826.148587 29.198991 810.43533 30.978342 799.646219 22.384173 718.470035-42.277495 618.001779-78.048781 512-78.048781 256.817504-78.048781 49.951219 128.817504 49.951219 384 49.951219 639.182496 256.817504 846.048781 512 846.048781 767.182496 846.048781 974.048781 639.182496 974.048781 384 974.048781 296.507166 949.714859 212.663236 904.470807 140.039307 897.177109 128.331757 900.755245 112.928203 912.462793 105.634507 924.170342 98.340809 939.573897 101.918942 946.867595 113.626492 997.013826 194.119204 1024 287.101621 1024 384ZM337.170731 396.487806C371.654852 396.487806 399.609756 424.442709 399.609756 458.926829 399.609756 493.41095 371.654852 521.365854 337.170731 521.365854 302.686611 521.365854 274.731708 493.41095 274.731708 458.926829 274.731708 424.442709 302.686611 396.487806 337.170731 396.487806ZM711.804879 396.487806C746.288998 396.487806 774.243902 424.442709 774.243902 458.926829 774.243902 493.41095 746.288998 521.365854 711.804879 521.365854 677.320757 521.365854 649.365854 493.41095 649.365854 458.926829 649.365854 424.442709 677.320757 396.487806 711.804879 396.487806ZM352.788105 127.229033C396.165222 92.527339 453.151987 71.804879 524.487806 71.804879 595.823622 71.804879 652.810387 92.527339 696.187505 127.229033 722.700531 148.439454 738.882517 170.015435 746.631548 185.513495 752.800254 197.850908 747.799529 212.853084 735.462114 219.021792 723.124702 225.190498 708.122526 220.189773 701.953818 207.852358 701.03616 206.017043 698.492224 201.827031 694.165854 196.058537 686.602473 185.974029 676.927317 175.789655 664.983226 166.234383 630.311565 138.497052 584.273939 121.756098 524.487806 121.756098 464.70167 121.756098 418.664045 138.497052 383.992384 166.234383 372.048292 175.789655 362.373137 185.974029 354.809756 196.058537 350.483386 201.827031 347.93945 206.017043 347.021792 207.852358 340.853084 220.189773 325.850908 225.190498 313.513495 219.021792 301.176081 212.853084 296.175356 197.850908 302.344062 185.513495 310.093092 170.015435 326.275078 148.439454 352.788105 127.229033Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="survey" unicode="&#59058;" d="M722.355804 849.454545C761.006291 849.454545 792.380951 818.166023 792.380951 779.627344L792.380951 437.500928 799.081094 453.813218 401.874746 51.22138 418.539682 58.181818 138.070006 58.181818C99.387643 58.181818 68.063492 89.328555 68.063492 127.771428L68.063492 872.727273 44.698413 849.454545 722.355804 849.454545ZM21.333333 896 21.333333 872.727273 21.333333 127.771428C21.333333 63.604277 73.59726 11.636363 138.070006 11.636363L418.539682 11.636363 428.337293 11.636363 435.204619 18.596802 832.410967 421.18864 839.11111 427.979625 839.11111 437.500928 839.11111 779.627344C839.11111 843.859757 786.827324 896 722.355804 896L44.698413 896 21.333333 896ZM775.859347 307.365395 759.337741 290.90909 775.859347 274.452787 869.319663 181.361879 885.841269 164.905574 902.362876 181.361879 972.458114 251.18006 988.979721 267.636363 972.458114 284.092668 878.997796 377.183575 862.47619 393.639878 845.954583 377.183575 775.859347 307.365395ZM845.954583 344.27097 939.414901 251.18006 939.414901 284.092668 869.319663 214.274485 902.362876 214.274485 808.902558 307.365395 808.902558 274.452787 878.997796 344.27097 845.954583 344.27097ZM518.843473 51.365395 513.841133 46.382827 512.453734 39.473248 489.088655-76.890387 482.215251-111.121568 516.58227-104.275332 633.407665-81.002605 640.344663-79.620689 645.347004-74.638121 902.362876 181.361879 918.884482 197.818182 902.362876 214.274485 808.902558 307.365395 792.380951 323.821698 775.859347 307.365395 518.843473 51.365395ZM775.859347 274.452787 869.319663 181.361879 869.319663 214.274485 612.303791-41.725515 624.243127-35.361033 507.41773-58.633758 534.911345-86.018703 558.276425 30.344934 551.886686 18.452787 808.902558 274.452787 775.859347 274.452787ZM426.576706 298.269073C444.201086 298.269073 458.488469 284.053815 458.488469 266.500753L458.488469 258.086116C458.488469 240.540958 444.323959 226.317797 426.576706 226.317797L426.576706 226.317797C408.952326 226.317797 394.664943 240.533054 394.664943 258.086116L394.664943 266.500753C394.664943 284.045911 408.829453 298.269073 426.576706 298.269073L426.576706 298.269073ZM278.349205 552.435127C278.349205 552.435127 280.851125 530.485568 305.477133 530.485568 330.103138 530.485568 331.559155 552.435127 331.559155 552.435127 329.927383 623.508937 362.988497 657.25782 430.67155 653.905282 475.722639 648.839223 499.06407 623.508937 500.624896 577.839917 497.503245 557.501184 480.405116 531.202385 449.969026 499.092521 409.671358 458.489557 389.522524 422.133143 389.522524 390.023279L389.522524 357.093903C389.522524 357.093903 392.614705 337.454532 414.885933 337.454532 437.157161 337.454532 440.249342 357.093903 440.249342 357.093903L440.249342 379.965664C440.249342 406.785969 459.546816 439.044836 498.21271 476.369762 538.652271 513.471183 558.730159 547.369069 558.730159 577.839917 555.395669 662.323878 511.195938 706.353877 425.776235 709.780917 327.515198 711.419936 278.349205 658.971339 278.349205 552.435127Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="icon5" unicode="&#58926;" d="M962.691679 174.534474c-8.721639 54.163597-34.298154 97.584526-73.089645 133.8638-44.721551 41.825594-99.282191 65.724911-156.512636 84.432994-26.935466 8.80555-54.079686 16.971533-81.129762 25.427112 41.188074 7.485485 81.495082 10.991332 121.872698 12.269441 39.906895 1.26276 79.885422 0.276293 120.633475 0.276293-30.644951 44.233434-74.588789 71.110571-127.260405 84.384899-53.004191 13.357216-103.742782 9.715269-152.261822-32.081673 18.715247 66.336848 12.464893 120.18936-38.810934 160.830989-32.450063 25.719778-77.127611 31.000038-111.319341 14.916734 58.583257-31.127951 82.051761-84.265172 94.304829-145.102772-44.638663 69.056795-110.067838 96.432283-187.710173 86.487793-56.123228-7.187703-110.723777-26.270317-166.003801-40.048111 15.677051-14.358009 31.136138-24.116257 47.932686-27.839045 51.427276-11.399631 103.405091-20.301372 155.098427-30.524201 37.036521-7.323802 75.163887-12.144598 104.448864-40.879036-78.096682 23.458271-155.928329 30.034037-235.541551 9.092076C186.718589 446.20385 104.838743 395.821369 81.996502 345.437865c46.955428 23.955598 95.807043 18.776645 144.606469 17.139356 37.737486-1.266853 76.089979-3.461845 113.238041 1.594311 52.683896 7.170307 104.513332 20.624736 159.209048 31.909757-91.88164-62.077847-186.516997-122.342396-159.194722-259.889075 58.852386 100.205213 163.392324 150.107763 229.951229 238.105956-16.239869-91.498924 6.980995-169.376619 66.432015-237.83785 41.815361-48.152696 89.979314-92.010577 110.706381-156.013263 12.758582 141.877311-25.823132 270.789333-97.911984 396.334677C755.996107 307.809873 858.199837 241.909977 962.691679 174.534474zM513.476631 236.101691c-27.767414-14.065344-39.008432-35.954887-42.252313-64.998363-6.078439-54.437843-15.162328-108.532879-21.799492-162.916487-3.90903-32.026414-5.519714-64.333214-8.16496-96.53052 30.078039 0 55.507198 0 79.961146 0 9.912767 78.200036 19.732413 154.247037 28.913517 230.369761 0.883113 7.322779-0.756223 15.746636-3.705392 22.591531C536.246217 188.25087 524.967336 211.411359 513.476631 236.101691z" horiz-adv-x="1024" /> + + + <glyph glyph-name="iconfont17" unicode="&#58927;" d="M512-212c282.768 0 512 229.216 512 512C1024 582.768 794.768 812 512 812 229.216 812 0 582.768 0 300 0 17.216 229.216-212 512-212zM512 764c256.272 0 464-207.744 464-464 0-256.272-207.728-464-464-464S48 43.728 48 300C48 556.256 255.728 764 512 764zM377.728 450.544 480 450.544l0-478c0-17.664 14.336-32 32-32s32 14.336 32 32L544 450.544l102.272 0c17.616 0 23.424 11.568 12.944 25.68l-128.128 172.624c-10.496 14.128-27.664 14.128-38.16 0L364.8 476.24C354.32 462.112 360.128 450.544 377.728 450.544z" horiz-adv-x="1024" /> + + + <glyph glyph-name="tianjia" unicode="&#58911;" d="M675.04 412.736l-127.04 0 0 127.264c0 20.064-16.288 36.32-36.32 36.32-20.064 0-36.32-16.192-36.32-36.32l0-127.232-127.072 0c-20.064 0-36.352-16.32-36.352-36.352 0-20.064 16.224-36.352 36.352-36.352l127.072 0 0-127.232c0-20 16.256-36.384 36.32-36.384 20.032 0 36.32 16.256 36.32 36.384l0 127.136 127.04 0c19.968 0 36.352 16.256 36.352 36.384C711.36 396.448 695.136 412.736 675.04 412.736L675.04 412.736zM511.328 830.56c-250.24 0-453.952-203.616-453.952-453.952 0-250.336 203.712-453.952 453.952-453.952 250.336 0 453.984 203.584 453.984 453.952C965.312 626.944 761.696 830.56 511.328 830.56L511.328 830.56zM511.328-20.576c-219.04 0-397.184 178.176-397.184 397.152 0 219.104 178.144 397.216 397.184 397.216s397.216-178.112 397.216-397.216C908.576 157.632 730.368-20.576 511.328-20.576L511.328-20.576zM511.328-20.576" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiazai" unicode="&#58881;" d="M510.771521 828.211081c-244.998947 0-443.597097-198.60429-443.597097-443.590957s198.59815-443.591981 443.597097-443.591981c244.986667 0 443.583794 198.60429 443.583794 443.591981S755.758188 828.211081 510.771521 828.211081zM510.771521-30.044014c-229.010811 0-414.664138 185.65435-414.664138 414.664138 0 229.010811 185.653327 414.657998 414.664138 414.657998 228.996484 0 414.652881-185.647187 414.652881-414.657998C925.424402 155.609313 739.768005-30.044014 510.771521-30.044014zM662.749888 352.395188 537.719266 245.825011l0 324.388065c0 14.887059-12.06478 26.953885-26.947745 26.953885-14.894222 0-26.961048-12.066827-26.961048-26.953885l0-325.410348L357.936647 352.395188c-10.56359 10.599406-27.693736 10.599406-38.267559 0-10.56359-10.596336-10.56359-27.777647 0-38.375006l170.181961-161.220868c5.629207-5.652743 13.111622-8.060583 20.49887-7.680936 7.373944-0.379647 14.859429 2.02717 20.488637 7.680936l170.181961 161.220868c10.562567 10.597359 10.562567 27.77867 0 38.375006C690.443623 362.995617 673.313477 362.995617 662.749888 352.395188z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xuanzemoban48" unicode="&#58928;" d="M320 300 106.666667 300c-35.349333 0-64-28.650667-64-64l0-213.333333c0-35.349333 28.650667-64 64-64l213.333333 0c35.349333 0 64 28.650667 64 64L384 236C384 271.349333 355.349333 300 320 300zM256 257.333333l0-256L170.666667 1.333333 170.666667 257.333333 256 257.333333zM85.333333 22.666667 85.333333 236c0 11.754667 9.578667 21.333333 21.333333 21.333333l42.666667 0 0-256L106.666667 1.333333C94.912 1.333333 85.333333 10.912 85.333333 22.666667zM341.333333 22.666667c0-11.754667-9.578667-21.333333-21.333333-21.333333l-42.666667 0L277.333333 257.333333l42.666667 0c11.754667 0 21.333333-9.578667 21.333333-21.333333L341.333333 22.666667zM576 470.666667 234.666667 470.666667c-47.061333 0-85.333333-38.272-85.333333-85.333333l0-42.666667 42.666667 0 0 42.666667c0 23.530667 19.136 42.666667 42.666667 42.666667l42.666667 0 0-96 21.333333 0L298.666667 428l213.333333 0 0-426.666667-85.333333 0-21.333333-42.666667 170.666667 0c47.061333 0 85.333333 38.272 85.333333 85.333333L661.333333 385.333333C661.333333 432.394667 623.061333 470.666667 576 470.666667zM618.666667 44c0-23.530667-19.136-42.666667-42.666667-42.666667l-42.666667 0L533.333333 428l42.666667 0c23.530667 0 42.666667-19.136 42.666667-42.666667L618.666667 44zM853.333333-41.333333c47.061333 0 85.333333 38.272 85.333333 85.333333L938.666667 556c0 47.061333-38.272 85.333333-85.333333 85.333333L341.333333 641.333333c-47.061333 0-85.333333-38.272-85.333333-85.333333l0-42.666667 42.666667 0 0 42.666667c0 23.530667 19.136 42.666667 42.666667 42.666667l85.333333 0 0-85.333333 21.333333 0 0 85.333333 298.666667 0 0-597.333333-42.666667 0-21.333333-42.666667L853.333333-41.333333zM896 44c0-23.530667-19.136-42.666667-42.666667-42.666667l-85.333333 0L768 598.666667l85.333333 0c23.530667 0 42.666667-19.136 42.666667-42.666667L896 44z" horiz-adv-x="1024" /> + + + <glyph glyph-name="gongju" unicode="&#58929;" d="M282.127566 555.082606c-13.120832-13.221116-30.625508-20.50808-49.278333-20.50808-18.618033 0-36.157501 7.286963-49.311079 20.50808l-32.885991 33.019021 98.623181 99.027387 32.885991-33.019021c13.186324-13.221116 20.473287-30.829146 20.473287-49.548486C302.599829 585.876959 295.347658 568.26893 282.127566 555.082606L282.127566 555.082606zM249.308089 621.089949l-0.032746 0-32.884968-32.987299c4.418636-4.417613 10.252505-6.845918 16.458857-6.845918 6.206352 0 12.041244 2.428306 16.426111 6.813173 4.418636 4.452405 6.845918 10.288321 6.845918 16.493649C256.121262 610.802652 253.693979 616.671313 249.308089 621.089949L249.308089 621.089949zM396.703067 412.343671 249.578242 554.778684l32.278147 33.626865 147.157571-142.468782L396.703067 412.343671 396.703067 412.343671zM751.45979 49.928524 618.131179 190.071332l32.884968 32.985252 133.330658-140.141784L751.45979 49.928524 751.45979 49.928524zM850.184279-16.044026c-22.700001-22.766516-52.481282-34.168194-82.264609-34.168194-29.714765 0-59.395762 11.333116-81.994456 34.033118L538.194592 138.398462l32.884968 33.021068L718.811206 16.806149c27.117614-27.183106 71.269183-27.116591 98.488105 0.169869 27.186176 27.287483 27.117614 71.773673-0.135076 99.196233l-147.426701 154.273642 32.851199 33.021068 147.461493-154.308435C895.447159 103.557956 895.514697 29.421468 850.184279-16.044026L850.184279-16.044026zM801.716404 384.380806c-30.726815-30.860868-71.605851-47.861054-115.082038-47.861054-43.442418 0-84.321454 16.999163-115.082038 47.861054-30.760584 30.861892-47.692209 71.877027-47.692209 115.521037s16.931624 84.691891 47.692209 115.554806l42.497906 42.666752 32.885991-32.986275-42.497906-42.667775c-21.99085-22.090111-34.099632-51.367925-34.065863-82.566484 0-31.163767 12.108782-60.441581 34.065863-82.499969 21.956058-22.058388 51.16531-34.20094 82.196047-34.20094 31.064506 0 60.239989 12.142551 82.196047 34.20094l42.49893 42.665729 32.884968-33.019021L801.716404 384.380806 801.716404 384.380806zM844.214311 427.049604l-49.311079 49.51267-16.45988-16.493649c-17.538445-17.638729-40.879036-27.352975-65.73719-27.352975l-0.032746 0c-24.824385 0-48.198745 9.713222-65.73719 27.352975-17.539468 17.607006-27.252691 41.082674-27.252691 66.007343 0 24.925692 9.679453 48.400337 27.252691 66.040089l16.458857 16.495696-49.344848 49.51267 32.885991 33.021068 82.196047-82.533738-49.311079-49.482995c-8.769734-8.835226-13.626345-20.571525-13.626345-33.051767 0-12.446473 4.856611-24.183795 13.626345-32.987299 8.768711-8.835226 20.439518-13.69286 32.884968-13.69286 12.411681 0 24.082488 4.857635 32.852222 13.69286l49.344848 49.514717 82.196047-82.534761L844.214311 427.049604 844.214311 427.049604zM233.591129 45.139451l0 46.681182 46.512337 0 0-46.681182L233.591129 45.139451 233.591129 45.139451zM538.160823 272.538555l-92.247984 91.572602 32.717146 33.18889 92.214215-91.539856L538.160823 272.538555 538.160823 272.538555zM304.2187 17.043556l173.634596 239.842507 37.641295-27.454282L338.318332-14.762847c-21.923312-22.057365-51.132564-34.20094-82.19707-34.20094-31.028691 0-60.237943 12.143575-82.196047 34.168194-21.958104 22.057365-34.065863 51.335179-34.065863 82.533738 0 31.198559 12.107759 60.476373 34.065863 82.533738l2.765997 2.360767L417.243893 328.054963l27.353998-37.742603L205.596542 116.003406c-12.411681-13.053294-19.224854-30.119995-19.224854-48.26526 0-18.71934 7.252171-36.291554 20.438495-49.513694C232.747925-7.847344 277.775444-8.287365 304.2187 17.043556L304.2187 17.043556z" horiz-adv-x="1024" /> + + + <glyph glyph-name="tishilian" unicode="&#58980;" d="M485.656116-212C221.592397-212 6.762016 2.81718 6.762016 266.876498s214.830381 478.867697 478.8941 478.867697c264.041716 0 478.854495-214.812779 478.854495-478.867697S749.697832-212 485.656116-212zM485.656116 714.834741c-247.024795 0-447.975846-200.959852-447.975846-447.962644 0-247.002792 200.951051-447.962644 447.975846-447.962644 247.002792 0 447.953843 200.959852 447.953843 447.962644C933.609959 513.874889 732.658908 714.834741 485.656116 714.834741zM352.033458 363.380528c0-30.469398-24.682677-55.147675-55.143274-55.147675-30.451796 0-55.143274 24.678276-55.143274 55.147675 0 30.460597 24.691478 55.138874 55.143274 55.138874C327.350781 418.519402 352.033458 393.845526 352.033458 363.380528zM674.417647 418.519402c-30.460597 0-55.156476-24.678276-55.156476-55.138874 0-30.469398 24.695879-55.147675 55.156476-55.147675 30.451796 0 55.143274 24.678276 55.143274 55.147675C729.560922 393.845526 704.869444 418.519402 674.417647 418.519402zM562.005634 81.309765c0-59.733046-34.192262-108.165484-76.349518-108.165484-42.166057 0-76.36272 48.432438-76.36272 108.165484 0 59.724245 34.196663 108.152282 76.36272 108.152282C527.813371 189.457647 562.005634 141.03401 562.005634 81.309765zM835.631745 709.712503c0 0 12.871605 56.819883 41.959231 85.925112 29.083226 29.096427 69.915916 15.124685 78.492585-8.801097 9.461179-26.385689-2.033053-50.069442-29.092027-56.164202C899.404495 724.463141 874.880237 742.192952 835.631745 709.712503zM916.698651 673.570797c0 0 35.767659 20.576965 64.877288 19.393218 29.136032-1.174946 41.431165-29.144833 33.109728-45.110024-9.192746-17.588993-27.054573-22.966463-43.217788-11.797871C954.979023 647.44034 952.453108 668.721393 916.698651 673.570797z" horiz-adv-x="1024" /> + + + <glyph glyph-name="bianji" unicode="&#58946;" d="M769.089 432.251l-125.896 125.89 62.974 62.947c20.866 20.838 54.652 20.838 75.517 0l50.353-50.351c20.865-20.865 20.865-54.703 0-75.567L769.089 432.251zM403.349 66.527 277.453 192.418 619.706 531.982 745.601 406.09ZM176.314-36.717 252.912 167.877 377.753 43.012Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiaoxi" unicode="&#58949;" d="M587.182306 670.7203c-6.003737 2.705622-13.043061 1.642406-17.984606-2.721994l-259.223926-229.293243-148.246369 0c-9.253758 0-16.752546-7.498788-16.752546-16.756639l0-267.886213c0-9.249665 7.498788-16.756639 16.752546-16.756639l144.050814 0c9.253758 0 16.752546 7.506974 16.752546 16.756639L322.530764 406.391099c1.774413 0.704035 3.433192 1.719154 4.892427 3.010567l236.127905 208.861912 0-653.332912-160.751171 137.64287c-2.12643 1.824555-90.300632 78.69941-93.927229 76.162634-4.427846-3.097548-15.768125-17.59882-18.419512-22.512736-0.953721-1.768273-2.196015-1.334391 15.413038-16.379039 25.674753-21.936615 73.780377-61.548798 75.144444-62.717414l10.007935-8.570189 178.388876-152.761196c3.093455-2.653433 6.978948-4.028757 10.900258-4.028757 2.369977 0 4.756327 0.503467 7.003508 1.534959 5.939269 2.738367 9.749038 8.677637 9.749038 15.217586L597.060281 655.446431C597.060281 662.034477 593.190137 668.013655 587.182306 670.7203L587.182306 670.7203zM290.453185 170.814756l-115.040083 0L175.413102 405.195877l115.03906 0 0-234.381122L290.453185 170.814756zM747.742119 291.984443c0-51.55212-34.83232-96.658434-84.702124-109.693308-1.415232-0.375553-2.846838-0.551562-4.245697-0.551562-7.438413 0-14.234189 4.992711-16.200984 12.523221-2.338255 8.949836 3.021823 18.104333 11.967566 20.442588 35.136242 9.18929 59.672054 40.96397 59.672054 77.279061 0 36.307927-24.535813 68.090794-59.672054 77.271898-8.945743 2.346441-14.305821 11.492752-11.967566 20.450774 2.342348 8.953929 11.499915 14.305821 20.446681 11.967566C712.909799 388.643899 747.742119 343.530422 747.742119 291.984443L747.742119 291.984443zM864.950588 291.793084c0-88.87619-48.554856-170.44495-126.718053-212.883505-2.537799-1.375324-5.276167-2.02717-7.982812-2.02717-5.939269 0-11.69946 3.166109-14.733563 8.762571-4.417613 8.134261-1.39886 18.303878 6.727215 22.720468 67.350944 36.566824 109.198028 106.851587 109.198028 183.427636 0 76.844156-42.055838 147.272181-109.741403 183.78784-8.154727 4.396123-11.192923 14.557554-6.795776 22.700001 4.38896 8.142447 14.558577 11.184737 22.701025 6.795776C816.151162 462.697499 864.950588 380.976266 864.950588 291.793084L864.950588 291.793084z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiangxia" unicode="&#58906;" d="M888.306 619.94c15.615 15.617 40.93 15.617 56.545 0v0c15.617-15.615 15.617-40.93 0-56.545l-405.733-405.734c-15.615-15.617-40.928-15.617-56.545 0v0c-15.615 15.615-15.615 40.93 0 56.545l405.733 405.734zM538.619 214.206c15.617-15.615 15.617-40.93 0-56.545v0c-15.615-15.617-40.928-15.617-56.545 0l-405.734 405.734c-15.615 15.615-15.615 40.93 0 56.545v0c15.617 15.617 40.93 15.617 56.547 0l405.732-405.734zM538.619 214.206z" horiz-adv-x="1024" /> + + + <glyph glyph-name="wenjian" unicode="&#58913;" d="M887.443911 514.6304l0-44.578133 0-45.511111 0-477.866667c0-37.705956-30.560711-68.266667-68.266667-68.266667l-614.4 0c-37.705956 0-68.266667 30.560711-68.266667 68.266667l0 705.422222c0 37.6832 30.560711 68.266667 68.266667 68.266667l386.844444 0 45.511111 0 38.024533 0c7.805156 2.594133 16.566044 1.2288 22.778311-5.006222l183.136711-183.159467C885.919289 527.373511 887.876267 520.956444 887.443911 514.6304zM659.888356 447.296711c-12.583822 0-22.755556 10.171733-22.755556 22.755556l0 204.8-45.511111 0-364.088889 0c-25.122133 0-45.511111-20.388978-45.511111-45.511111l0-659.911111c0-25.122133 20.388978-45.511111 45.511111-45.511111l568.888889 0c25.122133 0 45.511111 20.388978 45.511111 45.511111l0 455.111111 0 22.755556L659.888356 447.296711zM682.643911 666.273422l0-173.4656 159.288889 0 0 14.176711L682.643911 666.273422z" horiz-adv-x="1024" /> + + + <glyph glyph-name="layouts" unicode="&#58930;" d="M917.213-103.239h-810.426c-23.151 0-41.918 18.766-41.918 41.917l0 698.644c0 23.148 18.767 41.917 41.918 41.917h810.426c23.149 0 41.918-18.769 41.918-41.917v-698.643c0-23.151-18.769-41.918-41.918-41.918zM316.38-61.321h600.833v363.294h-600.833v-363.294zM106.787-61.321h167.674v363.294h-167.674v-363.294zM148.705 637.322c-23.151 0-41.918-18.769-41.918-41.92s18.767-41.92 41.918-41.92 41.92 18.768 41.92 41.92-18.769 41.92-41.92 41.92zM274.461 637.322c-23.151 0-41.918-18.769-41.918-41.92s18.767-41.92 41.918-41.92c23.151 0 41.92 18.768 41.92 41.92s-18.77 41.92-41.92 41.92zM400.216 637.322c-23.15 0-41.918-18.769-41.918-41.92s18.769-41.92 41.918-41.92c23.152 0 41.92 18.768 41.92 41.92s-18.768 41.92-41.92 41.92zM875.293 511.566h-768.506v-167.675h810.426l0 167.675h-41.921z" horiz-adv-x="1024" /> + + + <glyph glyph-name="duigou" unicode="&#58904;" d="M0.055-30.783c0.341-0.341 0.683-0.683 1.023-1.023-0.881-0.199-1.222 0.142-1.023 1.023zM422.68-31.806c0.341 0.341 0.683 0.683 1.023 1.023 0.199-0.881-0.142-1.222-1.023-1.023zM1188.586 507.499c0.796-6.455-2.732-8.658-7.385-10.598-135.179-56.381-231.75-157.232-314.81-273.594-48.424-67.839-89.128-140.154-123.426-216.017-5.928-13.112-8.996-15.349-20.062-4.384-87.123 86.327-174.761 172.135-262.272 258.071-12.668 12.439-25.155 25.098-38.381 36.921-9.294 8.308-10.355 13.069 2.455 19.008 33.244 15.413 66.428 31.089 98.694 48.415 13.919 7.474 22.089 4.601 32.375-5.67 54.34-54.26 109.269-107.929 164.023-161.773 15.688-15.428 15.25-15.216 22.655 5.97 23.948 68.521 59.387 131.482 96.277 193.496 83.563 140.471 176.983 274.364 274.181 405.661 2.902 3.92 4.786 11.051 10.606 9.738 5.874-1.324 3.992-8.698 4.946-13.298 19.893-95.846 39.493-191.752 59.156-287.646 0.346-1.682 0.755-3.351 0.97-4.298z" horiz-adv-x="1600" /> + + + <glyph glyph-name="tianjia1" unicode="&#58888;" d="M509.989715-60.972421c-246.734474 0-446.75195 200.023616-446.75195 446.75809 0 246.732427 200.017476 446.75195 446.75195 446.75195 246.733451 0 446.757067-200.019523 446.757067-446.75195C956.746782 139.051195 756.723166-60.972421 509.989715-60.972421L509.989715-60.972421zM509.989715 812.433746c-235.633648 0-426.650123-191.014428-426.650123-426.648077 0-235.639788 191.016475-426.654216 426.650123-426.654216 235.638765 0 426.654216 191.014428 426.654216 426.654216C936.643931 621.419318 745.62848 812.433746 509.989715 812.433746L509.989715 812.433746zM527.863804 153.46958l-35.741016 0L492.122789 367.909533 277.678742 367.909533 277.678742 403.653619l214.443024 0L492.121765 618.095619l35.741016 0L527.862781 403.653619l214.442 0 0-35.744086L527.863804 367.909533 527.863804 153.46958 527.863804 153.46958zM527.863804 153.46958" horiz-adv-x="1024" /> + + + <glyph glyph-name="yaoyaozhibofanye" unicode="&#58931;" d="M508.638018 743.97307c-246.403458 0-446.845649-200.463469-446.845649-446.845649 0-246.382179 200.442191-446.845649 446.845649-446.845649 246.382179 0 446.845649 200.463469 446.845649 446.845649C955.483667 543.5096 755.041476 743.97307 508.638018 743.97307zM508.638018-107.161499c-222.933422 0-404.28892 181.355498-404.28892 404.28892 0 222.933422 181.355498 404.28892 404.28892 404.28892 222.912144 0 404.28892-181.355498 404.28892-404.28892C912.926939 74.193999 731.57144-107.161499 508.638018-107.161499zM252.87208 401.1999c8.639016 26.129831-32.470784 37.215859-41.067243 11.32009-27.810822-83.730363-22.321004-168.545923 14.086277-248.573851 11.362646-24.938243 48.025268-3.298146 36.747735 21.491148C230.976644 255.081373 228.806251 328.853462 252.87208 401.1999zM599.262572 163.733355l-127.627629 133.394065 127.47868 133.223838c9.043305 9.064583 9.022026 23.789211-0.021278 32.832516-8.809243 8.830521-24.087108 8.766686-32.832516 0l-148.310199-148.310199c-4.617405-4.638683-6.979303-11.064749-6.553736-17.746156-0.404289-6.702685 1.936331-13.107472 6.575015-17.788712l148.310199-148.28892c4.383343-4.383343 10.213615-6.787798 16.405619-6.787798 6.170726 0 12.000997 2.404455 16.405619 6.787798C608.156928 140.114371 608.156928 154.838999 599.262572 163.733355z" horiz-adv-x="1024" /> + + + <glyph glyph-name="office" unicode="&#59141;" d="M335.282306 712.495464C399.587328 713.451107 442.778899 696.882717 470.183494 669.370654 479.127332 660.39174 485.691302 650.857363 490.241971 641.442689 492.795622 636.159553 494.049041 632.438701 494.358795 631.074094L493.723712 636.740923 493.723706 196.900196C493.723706 199.018106 495.816045 203.920655 503.591595 207.364367 511.039185 210.662833 515.68422 209.165274 517.176538 207.906613L500.671543 188.33763 521.297207 203.501468C514.140179 213.236369 499.631258 225.714509 476.134074 237.35914 439.577969 255.475456 390.86048 266.105079 328.491925 266.105082 265.860796 266.105082 219.424582 255.71818 186.827162 237.741581 164.977332 225.691987 152.538132 212.281173 147.220271 201.30887L170.257196 190.143742 151.035786 207.052243C152.884078 209.153361 158.307299 211.803366 167.849005 208.050434 177.092077 204.414961 179.2 199.200117 179.2 196.664452L179.2 497.049743 179.2 636.740923 175.817447 624.023021C177.078908 626.226721 180.088681 630.807811 184.828724 636.965629 192.95423 647.521524 202.792594 658.127492 214.297641 668.007961 247.526453 696.544681 287.381649 713.209056 334.514421 712.495571L335.282306 712.495464ZM335.289387 763.689705C274.661039 764.607483 223.081402 743.04085 180.940156 706.850184 156.32698 685.712527 139.975514 664.470237 131.382553 649.458825L128 643.549699 128 636.740923 128 497.049743 128 196.664452C128 159.26105 164.542545 144.888183 189.478606 173.235241L191.776657 175.847642 193.294121 178.978613C194.07832 180.596644 199.156367 186.071334 211.552092 192.907243 236.030601 206.406481 274.024879 214.905082 328.491925 214.905082 383.221547 214.905079 424.163878 205.97191 453.399258 191.483569 469.376966 183.565406 477.614626 176.480753 480.045882 173.17379L481.844905 170.72678 484.166551 168.768644C511.279708 145.9007 544.923706 160.801293 544.923706 196.900196L544.923712 636.740922 544.288627 642.407751C540.427211 659.419023 529.175531 682.697124 506.45814 705.503602 468.987716 743.12097 412.352271 764.846461 334.521502 763.689812L335.289387 763.689705ZM0 506.026694 0 27.856868C0-8.875637 34.793167-23.400433 61.4635 1.248508L63.46242 3.315859C65.301149 5.444836 69.655573 9.862313 76.498228 15.820363 88.306297 26.101907 102.566352 36.46294 119.251411 46.174385 167.295691 74.138291 224.90855 90.950182 292.337329 90.950182 358.378978 90.95018 409.459345 71.669566 448.125308 39.64774 461.506042 28.566274 472.380655 16.734758 480.912593 4.997001 485.832384-1.771373 488.762874-6.741986 489.872527-9.022522 496.058545-21.735902 511.379537-27.027375 524.092917-20.841355 536.806298-14.655337 542.097771 0.665655 535.91175 13.379036 527.471002 30.726293 509.777717 55.067718 480.782336 79.0807 433.134118 118.541323 370.586889 142.15018 292.337329 142.150182 215.474895 142.150185 149.074727 122.774084 93.495781 90.424668 59.761154 70.789615 36.872315 50.859802 24.713677 36.781884L44.088049 20.04887 26.712598 38.849235C28.162783 40.189508 32.877261 41.946118 40.792576 38.641781 49.035365 35.200736 51.2 30.129892 51.2 27.856868L51.2 506.026694C51.2 520.165184 39.73849 531.626694 25.6 531.626694 11.46151 531.626694 0 520.165184 0 506.026694L0 506.026694ZM696.80221 763.689812C618.971441 764.846461 562.335996 743.12097 524.86557 705.503602 502.148181 682.697124 490.896501 659.419023 487.035083 642.407751L486.4 636.740922 486.400004 196.900196C486.400006 160.801293 520.044004 145.9007 547.157161 168.768644L549.478807 170.72678 551.27783 173.17379C553.709086 176.480753 561.946746 183.565406 577.924452 191.483569 607.159834 205.97191 648.102165 214.905079 702.831787 214.905082 757.298833 214.905082 795.293111 206.406481 819.77162 192.907243 832.167345 186.071334 837.245391 180.596644 838.029591 178.978613L839.547055 175.847642 841.845105 173.235241C866.781167 144.888183 903.323712 159.26105 903.323712 196.664452L903.323712 497.049743 903.323712 636.740923 903.323712 643.549699 899.941158 649.458825C891.348196 664.470237 874.996732 685.712527 850.383556 706.850184 808.24231 743.04085 756.662673 764.607483 696.034325 763.689705L696.80221 763.689812ZM696.809291 712.495571C743.942063 713.209056 783.797257 696.544681 817.026071 668.007961 828.531119 658.127492 838.369481 647.521524 846.494989 636.965629 851.235031 630.807811 854.244804 626.226721 855.506263 624.023021L852.123712 636.740923 852.123712 497.049743 852.123712 196.664452C852.123712 199.200117 854.231635 204.414961 863.474707 208.050434 873.016412 211.803366 878.439633 209.153361 880.287925 207.052243L861.066515 190.143742 884.103441 201.30887C878.785579 212.281173 866.346381 225.691987 844.49655 237.741581 811.89913 255.71818 765.462916 266.105082 702.831785 266.105082 640.463232 266.105079 591.745741 255.475456 555.189638 237.35914 531.692454 225.714509 517.183533 213.236369 510.026502 203.501468L530.652166 188.33763 514.147172 207.906613C515.63949 209.165274 520.284527 210.662833 527.732117 207.364367 535.507665 203.920655 537.600004 199.018106 537.600004 196.900196L537.6 636.740923 536.964917 631.074094C537.274671 632.438701 538.52809 636.159553 541.081741 641.442689 545.63241 650.857363 552.196378 660.39174 561.140218 669.370654 588.544813 696.882717 631.736384 713.451107 696.041406 712.495464L696.809291 712.495571ZM972.799998 506.026694 972.799998 27.856868C972.799998 30.129892 974.964631 35.200736 983.207422 38.641781 991.122737 41.946118 995.837214 40.189508 997.287401 38.849235L979.911949 20.04887 999.286321 36.781884C987.127682 50.859802 964.238844 70.789615 930.504218 90.424668 874.925269 122.774084 808.525103 142.150185 731.662669 142.150182 653.132708 142.15018 590.55104 117.262822 543.127755 75.738001 514.370099 50.557195 496.945662 25.102596 488.705389 7.022771 482.841769-5.842485 488.517717-21.025242 501.382974-26.888862 514.248233-32.752482 529.430987-27.076533 535.294607-14.211275 536.420563-11.740836 539.350332-6.450639 544.25735 0.717811 552.731727 13.097653 563.54464 25.561581 576.856734 37.217929 615.190044 70.783375 665.901421 90.95018 731.662669 90.950182 799.091447 90.950182 856.704307 74.138291 904.748587 46.174385 921.433645 36.46294 935.6937 26.101907 947.501771 15.820363 954.344425 9.862313 958.698848 5.444836 960.537577 3.315859L962.536497 1.248508C989.206831-23.400433 1023.999998-8.875637 1023.999998 27.856868L1023.999998 506.026694C1023.999998 520.165184 1012.538487 531.626694 998.399998 531.626694 984.261508 531.626694 972.799998 520.165184 972.799998 506.026694L972.799998 506.026694Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="404" unicode="&#58908;" d="M300.197309 299.705317l4.427931 1.803972c1.147982-2.787956 10.167841-7.543882 26.89558-14.267777l5.411915-12.955798c10.659833-24.927611 23.123639-62.483024 37.555413-112.66624 14.431775 5.575913 34.439462 0.983985 60.351057-13.611787l1.803972-4.427931L389.575913 107.828315l18.203716-42.639334c2.459962-5.575913-12.463805-15.579757-44.7713-29.847534-11.151826 7.215887-19.84369 9.675849-26.403587 7.05189l-0.983985 2.131967c-10.823831 25.419603-16.235746 42.311339-16.399744 50.675208l-4.427931-1.803972 6.3959-14.923767-11.151826-4.263933c-41.655349-16.235746-71.830878-18.695708-90.690583-7.871877l-4.427931-1.803972-1.803972 4.263933c-7.05189 16.727739 3.607944 77.406791 32.307495 182.037156 11.479821 4.427931 19.1877 14.923767 22.959641 31.323511C281.337604 290.685458 291.83344 296.425368 300.197309 299.705317L300.197309 299.705317zM216.230621 80.276746c28.371557 19.515695 40.999359 32.799488 38.047406 39.68738-0.983985 2.131967-0.65599 5.575913 0.65599 10.167841l-0.983985 2.131967c-25.5836-21.483664-38.047406-32.963485-37.391416-34.439462C215.246637 88.804612 215.082639 83.064702 216.230621 80.276746L216.230621 80.276746zM216.722614 72.896861l0.983985-2.131967c11.643818 1.147982 21.155669 3.279949 28.699552 6.231903 0.819987 0.327995 7.379885 5.411915 19.84369 15.251762l-0.983985 2.131967c-7.543882-2.951954-12.7918-0.983985-15.743754 6.067905C226.398463 85.032671 215.574632 75.848815 216.722614 72.896861L216.722614 72.896861zM225.90647 143.743754l11.151826 4.263933c-1.147982-2.623959-6.3959-8.691864-15.579757-18.53171-2.295964-10.823831-2.787956-17.547726-1.639974-20.335682 27.715567 20.663677 40.34337 33.783472 37.883408 39.523382l0.819987 10.331839-3.443946-3.935939-9.019859-3.443946-0.983985 2.131967c11.151826 4.263933 17.875721 16.891736 20.49968 37.719411l-0.983985 2.131967C239.35426 172.443306 227.21845 160.307495 227.874439 157.027546L225.90647 143.743754 225.90647 143.743754zM231.646381 173.42729l0.983985-2.131967 2.131967 0.819987c28.371557 23.123639 40.179372 40.179372 35.423447 51.331198 1.475977 0.65599 1.967969 1.639974 1.475977 2.951954l-2.295964-0.819987c-28.863549-21.647662-40.999359-38.047406-36.407431-49.035234C231.482383 175.723254 230.990391 174.73927 231.646381 173.42729L231.646381 173.42729zM240.994234 211.966688l0.983985-2.131967c13.775785 10.331839 35.915439 29.847534 66.418962 58.21909l2.131967 0.819987-6.3959 14.923767 0.491992 5.083921-2.295964-0.819987c-36.571429-32.963485-55.431134-51.82319-56.579116-56.743113L240.994234 211.966688 240.994234 211.966688zM311.67713 107.336323l-35.751441-13.939782c-1.475977-0.491992-6.887892-4.263933-16.235746-11.315823l0.819987-1.967969 12.299808 2.131967 20.007687 7.871877c11.643818 4.591928 32.143498 19.84369 61.171044 46.08328l-6.3959 14.923767-2.131967-0.819987c-24.107623-16.891736-34.439462-29.191544-31.159513-36.899423C315.449071 110.616272 314.629084 108.484305 311.67713 107.336323L311.67713 107.336323zM267.889814 264.773863l0.819987-1.967969c17.875721 16.891736 27.387572 25.419603 28.207559 25.747598l-0.983985 2.131967-8.855862-3.443946C274.941704 282.485586 268.545804 274.941704 267.889814 264.773863L267.889814 264.773863zM275.597694 222.954516c16.071749-37.883408 20.007687-67.894939 11.971813-90.034593l-3.443946-28.863549 26.89558 10.495836c-7.543882 30.011531-18.367713 65.598975-32.471493 106.926329l-0.983985 2.131967L275.597694 222.954516 275.597694 222.954516zM279.369635 231.810378l6.3959-14.923767c13.44779 15.087764 24.435618 24.271621 32.63549 27.55157l-3.607944 8.527867-2.459962 11.643818-2.131967-0.819987C289.045484 247.06214 278.713645 236.566304 279.369635 231.810378L279.369635 231.810378zM292.817425 194.58296c23.943626 17.219731 33.619475 30.995516 29.191544 41.491352l-2.787956 6.3959-2.295964-0.819987c-21.483664-18.859705-30.667521-31.651505-27.879564-38.3754L292.817425 194.58296 292.817425 194.58296zM294.457399 190.483024l2.787956-6.3959 2.295964-11.807816 2.295964 0.819987-0.491992-5.083921 6.3959-14.923767 32.471493 27.387572-6.3959 15.087764c-9.347854-10.331839-16.235746-16.399744-20.827675-18.203716l-2.295964-0.983985c-0.65599 1.639974 6.067905 10.167841 20.335682 25.419603l-3.115951 13.611787-0.983985 2.131967L294.457399 190.483024 294.457399 190.483024zM307.413197 148.171685l2.787956-6.3959 2.295964-11.643818c23.943626 17.219731 35.259449 27.387572 33.94747 30.503523l-5.411915 12.955798C329.224856 165.719411 318.07303 157.191544 307.413197 148.171685L307.413197 148.171685zM355.792441 131.935939c-23.779628-17.711723-34.111467-30.011531-30.995516-37.227418l1.475977-9.347854c25.255605 18.039718 36.899423 29.355541 34.931454 33.783472 24.435618 21.155669 38.703395 32.471493 42.803331 33.94747l-0.819987 1.967969c-1.803972 2.787956-6.723895 4.099936-14.595772 4.427931l-30.831518-31.9795L355.792441 131.935939 355.792441 131.935939zM327.912876 81.26073l4.591928-10.659833-0.491992-5.083921 2.295964 0.819987c23.451634 14.595772 34.275464 23.615631 32.63549 27.55157l-5.411915 12.955798L327.912876 81.26073 327.912876 81.26073zM333.816784 61.253043l5.411915-12.7918c25.747598 13.283792 37.719411 22.139654 35.915439 26.403587l-4.591928 10.659833C348.412556 70.272902 336.112748 62.237028 333.816784 61.253043L333.816784 61.253043zM357.596413 139.971813l1.803972-4.099936c4.919923 1.967969 8.527867 9.839846 10.823831 23.943626l-2.295964-0.819987C364.648302 147.679693 361.204356 141.44779 357.596413 139.971813L357.596413 139.971813zM731.674568 256.081999l3.935939-0.163997c-0.163997-2.459962 4.755926-9.019859 14.759769-19.515695l-0.65599-11.315823c-1.147982-21.975657-5.411915-53.955157-12.955798-95.774504 12.627803-0.65599 25.911595-10.659833 39.68738-30.175529l-0.163997-3.935939-47.887252-10.823831-1.967969-37.719411c-0.327995-4.919923-14.923767-7.379885-43.951313-7.379885-5.575913 9.019859-11.151826 13.775785-16.891736 13.939782l0.163997 1.967969c1.147982 22.467649 3.279949 36.735426 6.231903 42.967329l-3.935939 0.163997-0.65599-13.119795-9.839846 0.491992c-36.571429 1.803972-60.023062 9.839846-70.026906 24.271621l-3.935939 0.163997 0.163997 3.771941c0.819987 14.759769 30.667521 56.087124 89.706598 124.14606 10.167841-0.491992 19.515695 4.755926 28.371557 15.579757C714.290839 255.754004 724.294683 256.573991 731.674568 256.081999L731.674568 256.081999zM587.848815 115.86419l-0.163997-1.967969c9.019859-2.951954 16.891736-4.591928 23.615631-4.919923 0.65599 0 7.379885 1.475977 20.171685 4.755926l0.163997 1.967969c-6.723895 0.327995-9.839846 3.607944-9.511851 9.675849C599.328635 121.6041 588.012812 118.324151 587.848815 115.86419L587.848815 115.86419zM590.144779 121.440102c28.043562 5.083921 42.147341 10.659833 42.475336 16.727739 0.163997 1.803972 1.475977 4.263933 4.099936 7.215887l0.163997 1.967969c-26.731582-7.379885-40.015375-11.807816-40.179372-13.119795C592.440743 128.163997 590.308776 123.900064 590.144779 121.440102L590.144779 121.440102zM620.15631 165.227418l9.839846-0.491992c-1.803972-1.475977-7.871877-4.427931-18.367713-8.527867-5.575913-7.215887-8.527867-12.13581-8.527867-14.595772 28.043562 6.067905 42.147341 11.643818 42.311339 16.727739l4.263933 7.379885-3.935939-1.803972-8.035874 0.327995 0.163997 1.967969c9.839846-0.491992 19.351698 6.559898 28.863549 21.155669l0.163997 1.967969c-26.23959-7.379885-39.68738-12.463805-40.34337-14.923767L620.15631 165.227418 620.15631 165.227418zM670.667521 109.960282l-31.487508 1.475977c-1.31198 0-6.559898-0.983985-16.071749-2.951954l-0.163997-1.803972 9.839846-2.459962 17.711723-0.819987c10.331839-0.491992 30.995516 4.099936 61.991031 13.939782l0.65599 13.119795-1.803972 0.163997c-23.943626-4.591928-36.079436-10.167841-36.407431-16.891736C674.603459 110.944266 673.29148 109.796284 670.667521 109.960282L670.667521 109.960282zM635.244074 185.399103l-0.163997-1.967969 1.803972-0.163997c29.355541 7.70788 44.279308 16.563741 44.7713 26.23959 1.31198 0 2.131967 0.491992 2.131967 1.639974l-1.967969 0.163997c-29.191544-6.3959-44.115311-14.595772-44.607303-24.271621C635.900064 187.039078 635.244074 186.547085 635.244074 185.399103L635.244074 185.399103zM685.755285 207.37476c-1.803972-33.29148-9.675849-56.907111-23.615631-70.682896l-12.955798-20.171685 23.779628-1.147982c5.247918 24.763613 10.167841 54.611147 14.595772 89.870596l0.163997 1.967969L685.755285 207.37476 685.755285 207.37476zM656.071749 210.818706l-0.163997-1.967969c13.939782 3.115951 37.391416 10.167841 70.354901 21.155669l1.803972-0.163997 0.65599 13.119795 2.295964 3.607944-1.967969 0.163997c-39.03139-12.299808-59.859065-20.007687-62.483024-23.287636L656.071749 210.818706 656.071749 210.818706zM670.339526 68.46893l-0.65599-11.315823c23.943626 1.31198 35.915439 3.935939 36.079436 7.70788l0.491992 9.347854C684.443306 70.272902 672.471493 68.304933 670.339526 68.46893L670.339526 68.46893zM673.29148 85.196669l-0.491992-9.347854-2.295964-3.607944 1.967969-0.163997c22.631646 2.951954 33.94747 6.231903 34.111467 9.511851l0.65599 11.315823L673.29148 85.196669 673.29148 85.196669zM712.158873 113.568225c-23.943626-5.247918-36.079436-10.987828-36.407431-17.219731l-2.295964-7.379885c25.255605 5.083921 37.883408 9.511851 38.211403 13.44779 25.747598 7.543882 40.34337 11.151826 43.951313 10.987828l0.163997 1.803972c-0.327995 2.623959-3.443946 5.247918-9.347854 8.035874l-34.439462-13.44779L712.158873 113.568225 712.158873 113.568225zM682.147341 141.611787l-0.327995-5.73991-2.459962-9.347854c23.943626 4.755926 36.079436 8.691864 36.079436 11.479821l0.65599 11.315823C704.778988 147.351698 693.463165 144.727739 682.147341 141.611787L682.147341 141.611787zM688.051249 177.199231l-0.327995-5.73991-2.623959-9.511851 1.967969-0.163997-2.295964-3.607944-0.65599-13.119795 33.94747 9.511851 0.65599 13.283792c-10.659833-4.591928-18.039718-6.723895-21.975657-6.559898l-1.967969 0.163997c0 1.475977 8.199872 5.411915 24.271621 12.13581l2.623959 11.151826 0.163997 1.967969L688.051249 177.199231 688.051249 177.199231zM688.215247 180.807175c23.943626 4.755926 36.243434 11.807816 36.735426 20.991672l0.327995 5.73991-1.967969 0.163997c-22.631646-6.887892-34.275464-13.283792-34.603459-19.1877L688.215247 180.807175 688.215247 180.807175zM691.82319 212.786675l-0.65599-13.119795c15.415759 6.723895 26.89558 10.003844 34.111467 9.511851l0.327995 7.543882 2.459962 9.511851-1.803972 0.163997C704.450993 220.986547 692.971172 216.558616 691.82319 212.786675L691.82319 212.786675zM695.103139 240.994234l-0.163997-1.803972c19.351698 6.559898 29.355541 9.839846 30.339526 9.839846l0.163997 1.967969-7.871877 0.327995C706.746957 251.818065 699.367072 248.374119 695.103139 240.994234L695.103139 240.994234zM716.422806 118.980141l-0.163997-3.607944c4.427931-0.163997 10.003844 4.427931 16.727739 14.10378l-1.967969 0.163997C724.45868 122.26009 719.538757 118.816143 716.422806 118.980141L716.422806 118.980141zM479.118514 382.196028c53.627162 10.167841 89.870596 1.967969 109.222293-24.599616 9.675849-18.695708 15.579757-33.455477 17.875721-44.279308 11.807816-56.743113-5.903908-103.154388-53.299167-138.741832-12.463805-5.083921-22.631646-8.363869-30.339526-10.003844-31.651505-6.067905-63.631006 5.083921-95.938501 33.455477-9.347854 16.399744-15.251762 31.159513-18.039718 44.279308-13.283792 63.795003 1.967969 108.238309 45.919283 133.165919L479.118514 382.196028 479.118514 382.196028zM410.075593 265.429853c6.231903 5.247918 11.479821 8.199872 15.579757 9.019859-9.675849-9.347854-14.431775-15.087764-13.939782-17.219731-0.327995-5.411915-0.163997-10.167841 0.819987-14.267777l2.131967 0.327995c24.271621 15.743754 35.915439 25.5836 35.095452 29.519539l-2.131967 10.003844c-4.099936-3.607944-8.035874-5.73991-11.643818-6.559898l-0.819987 4.099936c10.823831 2.131967 15.251762 11.971813 13.44779 29.519539l-1.967969-0.327995c-22.467649-16.399744-34.603459-27.715567-36.407431-33.94747C409.255605 273.30173 409.255605 269.857783 410.075593 265.429853L410.075593 265.429853zM410.23959 286.257527c33.127482 21.647662 47.887252 40.34337 44.607303 56.251121-29.683536-23.615631-44.443306-36.079436-44.279308-37.555413C409.747598 295.769379 409.5836 289.537476 410.23959 286.257527L410.23959 286.257527zM412.699552 315.777066l0.491992-2.131967c27.059577 20.663677 44.607303 37.227418 52.643177 49.527226 10.331839 1.967969 17.055734 7.379885 20.49968 16.235746l-2.131967-0.491992C447.303011 372.028187 423.523382 350.872518 412.699552 315.777066L412.699552 315.777066zM414.339526 234.926329c2.459962-4.919923 4.263933-9.347854 5.083921-13.44779 18.859705 14.759769 30.339526 22.467649 34.111467 23.123639l-3.771941 18.039718C444.18706 261.493914 432.379244 252.310058 414.339526 234.926329L414.339526 234.926329zM421.883408 220.002562c2.131967-9.839846 5.247918-14.759769 9.675849-14.759769l27.879564 21.975657c-0.327995 1.147982-2.131967 6.231903-5.411915 15.415759C437.299167 228.530429 426.639334 220.986547 421.883408 220.002562L421.883408 220.002562zM432.707239 199.174888c5.083921-5.903908 8.527867-8.691864 10.495836-8.363869l3.935939 0.819987c10.987828 10.495836 19.1877 16.235746 24.599616 17.219731-0.819987 3.935939-3.935939 8.855862-9.511851 14.759769C442.21909 209.014734 432.379244 200.814862 432.707239 199.174888L432.707239 199.174888zM448.450993 185.563101l0.491992-2.131967c2.459962 0.491992 6.3959-0.819987 11.807816-3.771941 18.859705 10.003844 28.207559 16.727739 28.207559 19.84369-6.067905 1.639974-9.511851 4.427931-10.331839 8.363869C466.818706 202.946829 456.814862 195.566944 448.450993 185.563101L448.450993 185.563101zM469.442665 179.331198l0.491992-2.131967 14.923767 0.65599 12.627803 2.459962c2.459962 0.491992 8.199872 3.771941 17.547726 9.839846l-0.491992 2.131967c-6.887892-1.31198-13.611787 0.163997-20.49968 4.263933L469.442665 179.331198 469.442665 179.331198zM476.494555 249.030109l4.591928-21.811659c2.951954-14.431775 12.463805-25.091608 28.535554-31.9795l4.099936 0.819987c24.599616 34.275464 32.143498 73.798847 22.795644 118.570147l-2.459962 11.971813-6.231903 19.515695-6.067905-1.147982c-3.935939-0.819987-14.267777 0-30.831518 2.295964C473.870596 316.597053 469.278668 283.961563 476.494555 249.030109L476.494555 249.030109zM476.494555 363.172325l0.327995-1.967969c10.823831-2.131967 17.547726-3.115951 20.007687-2.623959 13.939782 10.167841 21.647662 17.875721 23.287636 23.287636l-21.319667-1.967969C496.174247 379.408072 488.630365 373.832159 476.494555 363.172325L476.494555 363.172325zM508.966047 363.172325l3.771941 2.787956c1.147982 0.163997 6.231903-2.951954 15.087764-9.675849 10.331839 13.119795 18.203716 20.171685 23.779628 21.155669-0.65599 2.951954-8.199872 4.263933-22.467649 4.099936C515.361947 370.716208 508.638053 364.648302 508.966047 363.172325L508.966047 363.172325zM511.590006 185.235106l0.491992-2.131967 4.099936 0.819987c19.84369 3.771941 35.751441 17.219731 47.723254 40.34337C554.557335 214.754644 537.173607 201.634849 511.590006 185.235106L511.590006 185.235106zM521.921845 197.534914c38.211403 24.271621 56.087124 42.311339 53.79116 53.79116 1.967969 4.919923 2.623959 8.527867 2.295964 10.823831-35.095452-26.567585-51.495195-44.935298-49.363229-54.939142C526.349776 206.71877 524.217809 203.602819 521.921845 197.534914L521.921845 197.534914zM528.64574 352.348495l7.543882-15.251762 2.131967 0.491992c4.263933 5.73991 13.283792 14.431775 27.059577 25.911595l-0.491992 2.131967c-5.411915 5.247918-8.363869 8.855862-8.855862 10.823831l-4.099936-0.819987L528.64574 352.348495 528.64574 352.348495zM536.845612 333.324792l4.263933-9.675849-0.491992-8.363869 4.099936 0.819987c19.515695 17.711723 29.027546 27.059577 28.863549 28.371557l-0.491992 2.131967c-1.967969 9.347854-4.263933 13.611787-7.05189 13.119795C548.817425 342.508648 539.141576 333.652787 536.845612 333.324792L536.845612 333.324792zM539.797566 236.402306c27.715567 19.84369 40.999359 32.63549 39.68738 38.703395 1.31198 7.215887 1.803972 12.13581 1.147982 14.759769l-1.967969-0.327995-35.095452-29.519539C540.78155 245.586163 539.469571 237.714286 539.797566 236.402306L539.797566 236.402306zM542.257527 307.413197l2.459962-11.971813 10.003844 3.935939c-7.05189-7.871877-10.331839-12.627803-10.003844-14.267777-0.65599-10.495836-0.819987-16.727739-0.327995-18.695708 18.695708 13.611787 30.831518 24.927611 36.243434 33.94747l-2.459962 11.971813c-7.05189-7.05189-12.7918-10.987828-16.727739-11.807816 8.035874 11.315823 13.939782 17.383728 17.711723 18.039718l-4.099936 19.84369C554.557335 320.532992 543.733504 310.201153 542.257527 307.413197L542.257527 307.413197zM307.249199 569.153107c-9.675849 0-17.711723-6.887892-19.84369-16.071749-4.263933-12.463805 1.639974-28.863549 29.519539-35.751441 1.31198 35.587444 0 49.527226 0 49.527226C313.809097 568.33312 310.693145 569.153107 307.249199 569.153107L307.249199 569.153107zM709.862908 537.173607c0-1.147982 0-2.131967-0.163997-3.115951 2.131967 3.279949 3.279949 7.215887 3.279949 11.479821 0 11.643818-9.183857 21.155669-20.49968 21.155669-3.443946 0-6.723895-0.819987-9.511851-2.459962C697.891095 563.905189 709.862908 551.933376 709.862908 537.173607L709.862908 537.173607zM531.761691 520.281871c0.65599 15.743754-32.963485 49.199231-32.963485 49.199231 0-18.203716 9.347854-42.803331 12.463805-48.707239-8.035874-11.643818-13.283792-32.307495-13.283792-32.307495S531.105701 504.374119 531.761691 520.281871L531.761691 520.281871zM488.794363 507.326073c2.459962 0 4.427931 1.967969 4.427931 4.427931 0 2.459962-1.967969 4.427931-4.427931 4.427931-2.459962 0-4.427931-1.967969-4.427931-4.427931C484.366432 509.294042 486.334401 507.326073 488.794363 507.326073L488.794363 507.326073zM445.335042 629.668161c-0.819987 8.855862-2.131967 16.235746-2.131967 16.235746s-53.627162 7.05189-63.959001-30.503523C395.151826 632.94811 427.623318 631.144138 445.335042 629.668161L445.335042 629.668161zM620.648302 614.908392c-9.675849 37.719411-63.303011 31.651505-63.303011 31.651505s-1.475977-7.379885-2.459962-16.235746C572.597053 631.636131 605.232543 632.784113 620.648302 614.908392L620.648302 614.908392zM419.587444 518.313901c29.847534 0 53.955157 21.975657 53.955157 49.035234 0 27.059577-24.271621 49.035234-53.955157 49.035234-29.847534 0-53.955157-21.975657-53.955157-49.035234C365.632287 540.289558 389.903908 518.313901 419.587444 518.313901L419.587444 518.313901zM419.587444 613.76041c28.371557 0 51.331198-20.827675 51.331198-46.411275 0-25.5836-22.959641-46.411275-51.331198-46.411275-28.207559 0-51.331198 20.827675-51.331198 46.411275C368.256246 592.932735 391.379885 613.76041 419.587444 613.76041L419.587444 613.76041zM419.587444 534.38565c20.007687 0 36.243434 14.759769 36.243434 32.799488 0 18.203716-16.235746 32.799488-36.243434 32.799488s-36.243434-14.759769-36.243434-32.799488C383.34401 549.14542 399.579757 534.38565 419.587444 534.38565L419.587444 534.38565zM435.331198 552.261371c1.967969 2.131967 4.919923 2.623959 6.559898 1.147982 1.639974-1.475977 1.475977-4.263933-0.491992-6.3959-1.967969-2.131967-4.919923-2.623959-6.559898-1.147982C433.035234 547.341448 433.199231 550.129404 435.331198 552.261371L435.331198 552.261371zM395.971813 585.880846c5.411915 5.73991 13.283792 7.05189 17.875721 3.115951 4.591928-3.935939 3.935939-11.807816-1.475977-17.547726-5.411915-5.73991-13.283792-7.05189-17.875721-3.115951C389.903908 572.433056 390.559898 580.304933 395.971813 585.880846L395.971813 585.880846zM584.240871 518.313901c29.847534 0 53.955157 21.975657 53.955157 49.035234 0 27.059577-24.271621 49.035234-53.955157 49.035234-29.847534 0-53.955157-21.975657-53.955157-49.035234C530.121717 540.289558 554.393338 518.313901 584.240871 518.313901L584.240871 518.313901zM584.240871 613.76041c28.371557 0 51.331198-20.827675 51.331198-46.411275 0-25.5836-22.959641-46.411275-51.331198-46.411275-28.207559 0-51.331198 20.827675-51.331198 46.411275C532.909673 592.932735 555.869315 613.76041 584.240871 613.76041L584.240871 613.76041zM584.240871 534.38565c20.007687 0 36.243434 14.759769 36.243434 32.799488 0 18.203716-16.235746 32.799488-36.243434 32.799488-20.007687 0-36.243434-14.759769-36.243434-32.799488C547.997438 549.14542 564.233184 534.38565 584.240871 534.38565L584.240871 534.38565zM599.820628 552.261371c1.967969 2.131967 4.919923 2.623959 6.559898 1.147982 1.639974-1.475977 1.475977-4.263933-0.491992-6.3959-1.967969-2.131967-4.919923-2.623959-6.559898-1.147982C597.688661 547.341448 597.852659 550.129404 599.820628 552.261371L599.820628 552.261371zM560.62524 585.880846c5.411915 5.73991 13.283792 7.05189 17.875721 3.115951 4.591928-3.935939 3.935939-11.807816-1.475977-17.547726-5.411915-5.73991-13.283792-7.05189-17.875721-3.115951C554.557335 572.433056 555.213325 580.304933 560.62524 585.880846L560.62524 585.880846zM957.171044 381.540038C957.171044 381.540038 957.171044 381.540038 957.171044 381.540038c-0.65599 0.983985-1.31198 1.803972-1.967969 2.951954-0.327995 0.327995-0.491992 0.65599-0.819987 0.983985-0.327995 0.327995-1.967969 0.65599-2.295964 0.983985-11.315823 14.759769-29.355541 40.34337-62.975016 46.247277l0 34.931454c0 4.263933-0.819987 8.691864-5.083921 8.691864L685.919283 476.330557c-0.163997 10.331839-0.327995 18.203716-0.65599 27.879564 24.435618 1.803972 43.295324 19.351698 43.295324 41.491352 0 22.467649-19.84369 40.671365-45.263293 41.819347-1.967969 78.226778-5.903908 143.98975-7.70788 150.549648l-0.491992 0.983985c-1.967969 2.295964-9.511851 5.247918-21.155669 8.363869 0.327995 13.939782-3.279949 29.355541-11.643818 46.08328 3.443946-21.647662-22.795644-36.079436-26.567585-38.047406-0.163997 0-0.327995 0-0.491992 0 0.163997 4.427931 0 57.727098-88.230621 97.90647-1.475977-44.115311-14.10378-70.682896-31.9795-86.754644L494.534273 766.606022l-5.411915-0.327995 0-0.163997 0 0 0 0 0.327995 0 0.327995-0.163997c-0.819987-0.163997-0.983985-0.491992-1.147982-1.147982-10.331839-8.035874-28.043562-18.203716-64.450993-18.203716-13.283792 0-28.207559 1.31198-44.607303 3.935939-4.099936 0.819987-7.70788 1.147982-11.151826 1.147982-5.575913 0-10.003844-0.983985-16.071749-2.295964l-0.327995 0-0.327995-0.163997c-17.547726-4.099936-27.55157-7.70788-30.011531-10.659833l-0.491992-0.983985c-0.491992-2.131967-2.295964-8.363869-5.73991-150.549648-25.255605-0.983985-45.263293-19.351698-45.263293-41.983344 0-22.139654 18.859705-39.523382 43.459321-41.163357-0.163997-9.675849-0.327995-17.547726-0.65599-27.879564L132.099936 476.002562c-4.427931 0-10.495836-4.591928-10.495836-8.691864l0-97.414478c-11.807816-0.65599-19.679693-2.295964-26.731582-4.755926-29.027546-10.495836-35.751441-35.915439-35.587444-60.023062 0-1.475977 0.491992-2.787956 0.983985-3.771941-6.723895-11.643818-6.231903-25.5836-5.083921-35.587444 0.983985-8.035874 2.623959-12.13581 4.427931-13.939782-4.263933-8.855862-0.983985-18.859705 1.967969-26.731582 3.771941-10.167841 12.13581-11.971813 22.139654-10.003844-4.755926-9.019859-2.459962-17.219731 11.643818-28.699552 4.427931-3.607944 14.267777 7.05189 26.075593 16.071749l0-267.151826c0-4.263933 6.067905-6.067905 10.331839-6.067905l751.928251 0c4.427931 0 5.083921 1.803972 5.083921 6.067905L888.784113 248.374119c16.727739 0.983985 29.355541 7.70788 38.539398 19.84369 4.591928 6.231903 7.871877 11.807816 8.691864 16.891736C977.670724 313.153107 982.262652 344.640615 957.171044 381.540038L957.171044 381.540038zM316.433056 508.638053c-22.959641 0.491992-40.835362 16.727739-40.835362 36.735426 0 20.335682 18.859705 36.899423 41.983344 36.899423l0 2.623959 0.163997-0.65599c0-0.819987 0-1.475977 0-2.295964 0.491992 0.163997 0.983985 0.163997 1.475977 0.327995l1.803972 0 0 0.491992c5.247918 1.31198 12.7918 2.951954 19.351698 3.771941 10.003844 35.095452 34.111467 64.122998 34.111467 64.122998s-9.839846 28.863549-13.939782 67.238949c51.167201-85.11467 229.268418-81.178732 280.107623-10.823831-4.591928-32.799488-12.627803-56.415119-12.627803-56.415119s24.107623-28.863549 34.111467-64.122998c6.559898-0.819987 13.939782-1.147982 19.023703-2.295964 0 0.491992 0 2.623959 0 2.623959l0.491992 0c23.123639 0 41.983344-18.695708 41.983344-39.03139 0-9.347854-3.935939-18.695708-10.495836-25.419603-10.167841-6.723895-25.091608-10.331839-40.835362-10.331839 0-6.723895 0.983985-19.351698 1.803972-35.423447L318.401025 476.658552c0.163997 10.331839 0.491992 19.84369 0.65599 30.175529l0 2.131967L316.433056 508.638053 316.433056 508.638053zM126.524023 462.554773c0 4.099936 6.3959 9.183857 10.823831 9.183857l741.432415 0c4.263933 0 5.575913-4.919923 5.575913-9.183857l0-29.027546c0 0.491992-6.723895 1.475977-10.823831 1.147982-22.795644-2.295964-44.443306-3.607944-60.679052-9.183857L176.215247 425.491352l-1.31198-2.787956 0-60.18706c-10.823831 5.903908-25.5836 8.363869-48.215247 7.871877L126.68802 462.554773 126.524023 462.554773zM821.381166-13.693786 180.807175-13.693786 180.807175 282.649584c10.823831 4.263933 15.579757 10.987828 15.087764 21.975657-0.491992 8.363869-4.263933 13.611787-15.087764 16.727739l0 7.379885c5.903908 1.967969 3.935939 4.263933 5.247918 6.723895 5.411915 10.495836 5.575913 18.203716-5.247918 23.779628l0 55.759129 615.318386 0c-2.787956-5.575913-4.755926-7.871877-5.575913-12.299808-1.475977-8.035874-1.639974-18.367713-1.147982-28.207559L697.891095 315.449071c0 0-28.371557-15.251762-16.727739-32.799488 11.643818-17.383728 32.307495-11.479821 50.511211-0.327995 12.13581 7.379885 39.68738 23.287636 63.959001 40.179372 0.163997-0.163997 0.327995-0.163997 0.491992-0.327995-1.803972-1.31198-2.951954-2.295964-2.951954-2.295964-11.151826-7.543882-6.887892-36.899423 15.415759-41.327354 3.115951-0.65599 9.675849 0 9.675849 1.147982l0-293.391416L821.381166-13.693786 821.381166-13.693786zM177.855221 271.169763c0 3.443946-2.131967 6.231903-4.755926 8.035874 1.639974 0.491992 3.771941 0.983985 4.755926 1.475977L177.855221 271.169763 177.855221 271.169763zM177.855221 322.828956c-0.983985 0.163997-1.639974 0.327995-2.459962 0.491992 0.819987 0.491992 1.475977 0.983985 2.459962 1.475977L177.855221 322.828956 177.855221 322.828956zM878.780269-65.516976 137.347854-65.516976c-4.263933 0-10.823831 2.131967-10.823831 6.3959L126.524023 206.882767c5.903908 1.147982 4.919923 2.295964 6.723895 3.279949 19.679693 8.035874 38.047406 25.255605 25.747598 33.127482-0.163997 0-1.475977 0.163997-1.639974 0.163997 9.511851 3.771941 17.547726 9.839846 17.547726 20.663677l0-289.29148 655.169763 2.459962 0 291.915439c9.839846-9.675849 21.647662-14.595772 34.603459-10.331839 3.279949-6.559898 13.611787-9.839846 19.515695-10.331839l0-307.495195C884.192184-63.38501 883.044202-65.516976 878.780269-65.516976L878.780269-65.516976zM878.780269-65.516976" horiz-adv-x="1024" /> + + + <glyph glyph-name="lunbozutu" unicode="&#58932;" d="M1002.069333 60.384 1002.069333 527.690667c0 24.213333-16.917333 49.578667-42.069333 49.578667l-64 0 1.152 6.4c0 31.338667-26.005333 57.6-58.538667 57.6L186.432 641.269333c-31.936 0-58.410667-31.957333-58.410667-64l-0.213333 0.96L67.178667 578.229333c-25.152 0-45.226667-20.288-45.226667-44.501333l0-467.328L21.354667 66.4c0-24.789333 20.629333-44.693333 45.312-44.693333L127.786667 21.706667l0-5.184C127.786667-14.965333 153.792-41.333333 186.432-41.333333l652.842667 0c31.658667 0 56.277333 10.901333 56.725333 42.602667l64 0c24.661333 0 42.666667 34.325333 42.666667 59.114667L1002.069333 60.384zM128 65.269333 64 65.269333l0 469.333333 64 0L128 65.269333zM853.333333 22.602667c0-6.421333-14.848-21.333333-21.333333-21.333333l-640 0c-6.485333 0-21.333333 14.848-21.333333 21.333333l0 554.666667c0 6.378667 9.258667 18.56 15.744 18.56l5.589333 2.773333 640 0c6.442667 0 21.333333-14.954667 21.333333-21.333333L853.333333 22.602667zM960 43.936l-64 0 0 490.666667 60.842667 1.984c4.970667 0 3.157333 2.944 3.157333-1.984l0-469.333333C960 60.298667 965.013333 43.936 960 43.936zM412.458667 315.829333c43.925333 0 79.637333 34.773333 79.637333 77.482667 0 42.752-35.712 77.482667-79.637333 77.482667-43.925333 0-79.637333-34.730667-79.637333-77.482667C332.8 350.602667 368.533333 315.829333 412.458667 315.829333zM412.458667 432.053333c21.952 0 39.829333-17.365333 39.829333-38.741333 0-21.333333-17.877333-38.741333-39.829333-38.741333-21.952 0-39.829333 17.408-39.829333 38.741333C372.629333 414.709333 390.506667 432.053333 412.458667 432.053333zM785.92 373.386667c-95.914667-23.338667-137.728-87.765333-168.256-134.805333-24.213333-37.269333-39.082667-58.346667-65.109333-58.346667l-0.042667 0c-35.456 0-57.109333 14.272-80.042667 28.16-24.362667 14.741333-49.536 29.952-88.64 29.952-75.648 0-156.906667-93.269333-165.930667-103.893333L213.333333 83.381333c0-10.709333 8.917333-18.112 19.925333-18.112l557.504 0c10.986667 0 19.904 7.402667 19.904 18.112L810.666667 354.570667c0 5.973333-2.837333 11.626667-7.658667 15.296C798.186667 373.536 791.872 374.858667 785.92 373.386667zM770.858667 104.522667 253.162667 104.522667c24.874667 27.733333 85.290667 95.082667 130.666667 95.082667 27.733333 0 46.229333-11.157333 67.605333-24.128 25.152-15.168 53.632-32.426667 99.712-33.941333l2.944-0.064c47.637333 0 71.722667 37.12 97.237333 76.416 26.645333 41.088 56.469333 79.104 119.530667 102.485333L770.858667 104.522667z" horiz-adv-x="1024" /> + + + <glyph glyph-name="help" unicode="&#58887;" d="M690.2 741.8C635.2 783.6 573.2 798 494.6 798c-59.6 0-110.6-12.2-151-39.4C284 718 256 649.8 256 542l153.6 0c0 28.8-2.8 59.8 14 86.4 16.8 26.6 40.2 47 80.4 47 40.8 0 61.8-11.8 81.6-36.2 16.8-20.8 23.2-45.6 23.2-72 0-22.8-11.6-43.8-25.4-62.8-7.6-11.2-17.6-21.2-30.2-30.8 0 0-83-49.4-112.2-96.2-21.8-34.8-29.6-78.4-31.4-130.6-0.2-3.8 1.2-11.6 14.4-11.6 13 0 112 0 123.6 0 11.6 0 14 8.8 14.2 12.4 0.8 19 3.2 48.2 6.6 59.2 6.6 20.8 19.4 39 39.4 54.6l41.4 28.6c37.4 29.2 67.2 53 80.4 71.8 22.6 30.8 38.4 68.8 38.4 113.8C768 649 741 703.2 690.2 741.8zM484 155.6c-51.8 1.6-94.6-34.4-96.4-90.6-1.6-56.4 39-93.4 91-95 54-1.6 95.8 33.2 97.4 89.4C577.6 115.6 538 154 484 155.6z" horiz-adv-x="1024" /> + + + <glyph glyph-name="daima1" unicode="&#58933;" d="M513.544163 809.525741c-282.101629 0-510.78094-228.679311-510.78094-510.76288 0-282.083569 228.679311-510.76288 510.78094-510.76288s510.76288 228.679311 510.76288 510.76288C1024.325103 580.846431 795.645793 809.525741 513.544163 809.525741zM513.544163-167.463359c-257.503523 0-466.22622 208.740757-466.22622 466.22622S256.0587 764.989082 513.544163 764.989082s466.22622-208.740757 466.22622-466.22622S771.047686-167.463359 513.544163-167.463359zM171.771357 275.772121 414.357086 172.088033 414.357086 216.805295 221.978945 296.505326 414.357086 375.464886 414.357086 420.182148 171.771357 317.76228ZM442.585309 109.382728 478.814238 109.382728 584.737801 488.142995 548.743656 488.142995ZM612.749301 420.182148 612.749301 375.464886 804.874598 296.505326 612.749301 216.805295 612.749301 172.088033 855.33503 275.772121 855.33503 317.76228Z" horiz-adv-x="1025" /> + + + <glyph glyph-name="jinshui" unicode="&#58934;" d="M862.315763-50.315789C802.869868-50.315789 754.526289-1.056 754.526289 59.503719 754.526289 78.330947 759.35885 96.960561 768.520956 113.434386 768.64671 113.793684 768.808394 114.152982 769.006008 114.494316L849.075622 250.542596 849.057657 250.542596 862.315763 273.052632 875.573868 250.542596 875.573868 250.542596 955.140464 115.356632C955.715341 114.673965 956.164464 113.865544 956.380043 112.967298 965.380464 96.601263 970.123201 78.151298 970.105236 59.503719 970.105236-1.056 921.761657-50.315789 862.315763-50.315789L862.315763-50.315789ZM924.33064 104.577684C924.204885 104.793263 924.115061 105.026807 924.025236 105.278316L862.315763 218.996211 800.606289 105.260351C800.516464 105.026807 800.42664 104.793263 800.300885 104.577684 793.977236 92.505263 790.635763 78.816 790.635763 64.965053 790.635763 21.292351 822.792956-14.242246 862.333727-14.242246 901.856534-14.242246 933.995763 21.292351 933.995763 64.983018 933.995763 78.816 930.654289 92.523228 924.33064 104.577684L924.33064 104.577684ZM682.684605 308.982456C593.50678 308.982456 520.982429 385.602807 520.982429 479.810807 520.982429 509.093614 528.240254 538.071018 541.965447 563.706947 542.163061 564.281825 542.396605 564.820772 542.684043 565.341754L662.815412 776.968421 662.797447 776.968421 682.684605 812 702.571763 776.968421 702.535833 776.968421 821.89471 566.689123C822.774991 565.647158 823.439692 564.371649 823.781026 562.970386 837.25471 537.514105 844.368815 508.82414 844.35085 479.810807 844.35085 385.602807 771.844464 308.982456 682.684605 308.982456L682.684605 308.982456ZM791.408254 546.119298C791.21064 546.496561 791.030991 546.891789 790.887271 547.322947L682.684605 739.924772 574.446008 547.287018C574.320254 546.891789 574.140605 546.496561 573.942991 546.101333 562.840675 525.693193 556.912254 512.075789 556.912254 488.631579 556.912254 414.634105 613.375973 344.876351 682.684605 344.876351 751.993236 344.876351 808.367131 405.058807 808.367131 479.056281 808.367131 502.500491 802.492605 525.693193 791.408254 546.119298L791.408254 546.119298ZM538.695833 192.983018C540.115061 191.330246 541.174991 189.33614 541.713938 187.126456 563.433517 147.118596 574.895131 102.026667 574.895131 56.431719 574.895131-91.581193 458.051341-212 314.403903-212 170.738499-212 53.89471-91.581193 53.89471 56.431719 53.89471 102.475789 65.589868 147.998877 87.704675 188.294175 88.010078 189.174456 88.387341 190.018807 88.872394 190.863158L282.408394 523.411649 282.372464 523.411649 314.403903 578.45614 346.453306 523.411649 346.399412 523.411649 538.695833 192.983018 538.695833 192.983018ZM314.403903 506.614456 119.807973 173.796491C119.556464 173.113825 119.251061 172.449123 118.873798 171.784421 98.932745 136.483368 88.387341 96.421614 88.387341 55.910737 88.387341-71.927579 189.799271-175.890526 314.421868-175.890526 439.026499-175.890526 540.420464-71.927579 540.402499 55.910737 540.402499 96.421614 529.857096 136.501333 509.916043 171.784421 509.53878 172.449123 509.233377 173.131789 508.963903 173.868351L314.403903 506.614456 314.403903 506.614456Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="faxian" unicode="&#58992;" d="M512 812C229.236364 812 0 582.763636 0 300c0-282.786909 229.236364-512 512-512s512 229.213091 512 512C1024 582.763636 794.763636 812 512 812zM657.291636 299.976727c0-77.195636-60.392727-139.729455-136.424727-144.407273l-175.732364-151.714909-22.877091 13.242182 58.228364 222.021818c-8.634182 18.548364-13.800727 39.074909-13.800727 60.858182 0 77.195636 60.369455 139.729455 136.378182 144.430545l175.802182 151.714909 22.877091-13.172364-58.251636-222.068364C652.125091 342.309818 657.291636 321.806545 657.291636 299.976727zM512 300m-66.048 0a2.838 2.838 0 1 0 132.096 0 2.838 2.838 0 1 0-132.096 0Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="guanyu" unicode="&#58891;" d="M514.27174 834.607768c-249.516844 0-451.789687-202.272843-451.789687-451.789687s202.272843-451.789687 451.789687-451.789687 451.789687 202.272843 451.789687 451.789687S763.788583 834.607768 514.27174 834.607768zM514.27174-20.1292c-222.541469 0-402.947282 180.405813-402.947282 402.947282s180.405813 402.947282 402.947282 402.947282 402.947282-180.405813 402.947282-402.947282S736.814232-20.1292 514.27174-20.1292zM514.295276 593.979362c-9.44614-10.360975-14.307867-22.951735-14.307867-37.483706 0-11.960403 3.886517-22.396079 11.534707-30.457686 7.783267-8.211009 17.853623-12.450567 29.313629-12.450567 9.312086 0 23.139 2.849908 35.782971 16.900925 9.865695 10.641361 14.866592 23.437805 14.866592 37.693484 0 11.68104-4.031826 21.900799-11.744485 29.832446C562.925856 615.325529 532.358677 613.449809 514.295276 593.979362zM549.461193 293.282882c-12.110829-11.541871-20.589944-18.759249-26.236548-23.316032 2.77009 14.953573 9.976212 44.614104 27.330462 103.023398 17.297968 57.890478 18.799158 67.991534 18.799158 72.955592 0 8.65717-3.63683 16.335037-9.921977 21.642926-14.124695 11.661597-39.035038 9.349949-69.131497-7.677866-16.779152-9.408277-34.595936-24.759917-54.493102-46.576805l-10.377348-11.541871 34.425044-26.548656 8.818853 8.715499c9.573029 9.292644 16.086373 15.35164 20.411889 19.393699-26.294876-86.460164-39.093367-140.190903-39.093367-164.262134 0-10.907421 3.172249-19.970844 9.573029-26.839275 6.460132-7.039323 15.510252-10.736529 25.891693-10.736529 10.146081 0 21.792329 3.926426 35.922141 11.949146 12.741185 7.212262 31.883151 23.029506 58.641585 48.190559l10.837836 10.391674-31.30703 30.475082L549.461193 293.282882z" horiz-adv-x="1024" /> + + + <glyph glyph-name="map" unicode="&#59157;" d="M451.673935-98.395699C478.883834-129.019147 524.254807-128.808979 551.400292-97.928851 553.755808-95.387908 558.821323-89.796762 565.872444-81.84835 577.572838-68.659017 590.597131-53.62432 604.615947-36.998315 644.662065 10.495494 684.708678 61.282182 722.129538 113.353553 759.658524 165.575381 792.492213 216.290726 819.314991 264.541538 868.685946 353.353683 896 430.456574 896 493.714285 896 715.890551 719.301715 896 501.333333 896 283.364952 896 106.666667 715.890551 106.666667 493.714285 106.666667 430.401284 134.05152 353.19427 183.54613 264.237378 210.371803 216.023471 243.193308 165.348124 280.699364 113.166846 318.155192 61.05545 358.239268 10.22579 398.322835-37.311031 412.354743-53.952073 425.391185-69.00073 437.102468-82.202579 444.160087-90.158466 449.230214-95.754921 451.982775-98.736706L451.673935-98.395699ZM486.822684-65.321348C484.281231-62.568254 479.425084-57.207989 472.585916-49.498359 461.135889-36.591017 448.364015-21.847761 434.602351-5.527215 395.275714 41.111927 355.949587 90.980452 319.289224 141.985137 282.808749 192.739548 250.983685 241.876422 225.158316 288.292478 179.388826 370.554195 154.50505 440.709839 154.50505 493.714285 154.50505 688.960095 309.785362 847.238095 501.333333 847.238095 692.881306 847.238095 848.161617 688.960095 848.161617 493.714285 848.161617 440.753978 823.345286 370.701737 777.693969 288.580749 751.873483 242.132934 720.038415 192.960075 683.537446 142.168738 646.912604 91.205033 607.624538 41.380326 568.335977-5.215038 554.587654-21.520243 541.828177-36.24925 530.389289-49.143797 523.556841-56.845711 518.705521-62.200435 516.166694-64.950526 507.543772-74.748911 495.255793-74.80583 487.131524-65.662353L486.822684-65.321348ZM714.955981 428.971194C723.919106 453.372045 728.565658 479.331002 728.565658 505.904762 728.565658 627.091817 632.184774 725.333333 513.29293 725.333333 394.401086 725.333333 298.020202 627.091817 298.020202 505.904762 298.020202 384.717709 394.401086 286.47619 513.29293 286.47619 549.003859 286.47619 583.510052 295.368053 614.373097 312.125591 626.032316 318.456132 630.449257 333.22218 624.238611 345.106481 618.027966 356.990782 603.541579 361.492994 591.882359 355.162451 567.900883 342.141361 541.111735 335.238095 513.29293 335.238095 420.821495 335.238095 345.858586 411.648164 345.858586 505.904762 345.858586 600.161359 420.821495 676.571428 513.29293 676.571428 605.764365 676.571428 680.727273 600.161359 680.727273 505.904762 680.727273 485.192019 677.117041 465.022684 670.154965 446.069408 665.522846 433.459117 671.796821 419.408892 684.168282 414.687349 696.53974 409.965809 710.323861 416.360905 714.955981 428.971194L714.955981 428.971194Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiangshang" unicode="&#58905;" d="M513.6 539.2l384-384c12.8-12.8 32-12.8 44.8 0 12.801 12.8 12.801 32 0 44.8l-403.2 403.2C532.8 609.6 520 616 513.6 616c-6.4 0-19.2 0-25.599-6.4L78.399 200c-12.8-12.8-12.8-32 0-44.8s32-12.8 44.8 0L513.6 539.2z" horiz-adv-x="1024" /> + + + <glyph glyph-name="bofang" unicode="&#58961;" d="M512-128c-282.714 0-511.893 229.232-511.893 512s229.179 512 511.893 512c282.714 0 511.893-229.232 511.893-512 0-282.768-229.179-512-511.893-512zM512 863.996c-265.043 0-479.9-214.91-479.9-479.996 0-265.097 214.857-479.996 479.9-479.996 265.043 0 479.9 214.899 479.9 479.996 0 265.086-214.857 479.996-479.9 479.996zM639.973 181.323h-21.329c-23.558 0-42.658 19.1-42.658 42.658v319.933c0 23.558 19.1 42.658 42.658 42.658h21.329c23.558 0 42.658-19.1 42.658-42.658v-319.933c0-23.558-19.1-42.658-42.658-42.658zM405.356 181.323h-21.329c-23.558 0-42.658 19.1-42.658 42.658v319.933c0 23.558 19.1 42.658 42.658 42.658h21.329c23.558 0 42.658-19.1 42.658-42.658v-319.933c0-23.558-19.1-42.658-42.658-42.658z" horiz-adv-x="1024" /> + + + <glyph glyph-name="riqi" unicode="&#58935;" d="M933.185668 674.359176l-167.054737 0 0 56.506968L732.333174 730.866145l0-56.506968L539.505447 674.359176l0 56.506968-33.796734 0 0-56.506968-216.255299 0 0 56.506968-33.796734 0 0-56.506968L88.005356 674.359176c-12.255115 0-22.224164-9.970072-22.224164-22.224164l0-706.60521c0-12.255115 9.970072-22.225187 22.224164-22.225187l845.179288 0c12.255115 0 22.225187 9.970072 22.225187 22.225187L955.409832 652.135012C955.409832 664.389104 945.43976 674.359176 933.185668 674.359176zM939.036933-54.471221c0-3.226484-2.62478-5.852288-5.852288-5.852288l-845.179288 0c-3.226484 0-5.851265 2.62478-5.851265 5.852288L82.154092 652.135012c0 3.226484 2.62478 5.851265 5.851265 5.851265l167.650301 0 0-55.657624 33.796734 0 0 55.657624 216.255299 0 0-55.657624 33.796734 0 0 55.657624L732.333174 657.986277l0-55.657624 33.796734 0 0 55.657624 167.054737 0c3.226484 0 5.852288-2.62478 5.852288-5.851265L939.036933-54.471221zM206.835765 524.260623l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM458.879152 524.260623l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM684.827207 524.260623l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM206.835765 349.345871l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM458.879152 349.345871l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM684.827207 349.345871l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM206.835765 173.877511l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM458.879152 173.877511l129.098263 0 0-94.008071-129.098263 0 0 94.008071ZM684.827207 173.877511l129.098263 0 0-94.008071-129.098263 0 0 94.008071Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="uploadfile" unicode="&#58909;" d="M914.7359263333336 663.0359498888887c-20.806884999999987 20.806885000000012-48.471967999999976 32.265868000000026-77.89816099999994 32.265868000000054l-352.221993 2.2737367544323206e-13-120.26099099999992 95.03035300000005-11.157106999999995 8.816806000000007-14.220886 9.769962616701378e-15L197.09333633333344 799.148976888889c-51.69538300000001 2.1316282072803006e-14-93.75224400000005-42.88778599999995-93.75224400000006-95.60442799999993l-1.5631940186722204e-13-255.13888799999998c-1.7763568394002505e-15-2.302439 0.08391099999999785-4.716417999999999 0.24968699999999489-7.196911999999999l-1.9895196601282805e-13-340.692403c-1.9539925233402755e-14-29.426192999999998 11.458982999999954-57.09127599999999 32.26586799999994-77.89816100000002 20.806884999999987-20.806885000000012 48.471967999999976-32.265868000000026 77.89816099999994-32.265868000000054l623.083981-3.410605131648481e-13c29.426192999999998-1.9539925233402755e-14 57.09127599999999 11.458982999999954 77.89816100000002 32.26586799999994 20.806885000000012 20.806884999999987 32.265868000000026 48.471967999999976 32.265868000000054 77.89816099999994L947.0028173333335 585.1377888888885C947.0017943333336 614.5639818888885 935.5428113333334 642.2280418888886 914.7359263333336 663.0359498888887zM197.09333633333372 758.2167298888891l141.88345099999998-8.526512829121202e-14L470.3948853333333 654.369569888889l366.44287999999995-2.2737367544323206e-13c38.236859-2.1316282072803006e-14 69.23178099999997-30.99492100000004 69.23178099999994-69.23178100000004L906.0695463333333 465.9195468888886 144.27334033333327 465.91954688888893 144.2733403333336 703.5445488888892C144.2733403333336 733.7361748888891 167.92296933333355 758.2167298888891 197.09333633333372 758.2167298888891zM836.8377653333331 31.28558888888881L213.75480733333322 31.28558888888915c-38.236859 2.1316282072803006e-14-69.23178099999997 30.99492100000004-69.23178099999994 69.23178100000004L144.52302633333338 424.4776928888892l761.546519-6.252776074688882e-13-2.2737367544323206e-13-323.96134599999993C906.0695463333333 62.28050988888867 875.0746243333334 31.285588888888583 836.8377653333331 31.28558888888881z" horiz-adv-x="1024" /> + + + <glyph glyph-name="delete" unicode="&#58944;" d="M738.923 24.288h-451.956c-27.2 0-49.327 21.603-49.327 48.157v418.017c0 26.548 22.129 48.147 49.327 48.147h451.956c27.2 0 49.327-21.598 49.327-48.147v-418.017c0-26.555-22.129-48.157-49.327-48.157zM286.966 494.547c-4.447 0-7.168-2.644-7.168-4.084v-418.017c0-1.443 2.722-4.093 7.168-4.093h451.956c4.448 0 7.168 2.651 7.168 4.093v418.017c0 1.44-2.722 4.084-7.168 4.084h-451.956zM832.199 496.302h-640.401c-27.201 0-49.327 20.131-49.327 44.876v61.045c0 24.74 22.128 44.867 49.327 44.867h640.401c27.2 0 49.327-20.127 49.327-44.867v-61.045c0-24.744-22.129-44.876-49.327-44.876zM184.631 541.327c0.387-0.733 2.722-2.866 7.168-2.866h640.401c4.445 0 6.782 2.132 7.168 2.867v60.741c-0.393 0.736-2.733 2.863-7.168 2.863h-640.401c-4.437 0-6.776-2.128-7.168-2.863v-60.742zM600.748 605.354h-174.546c-27.201 0-49.327 20.13-49.327 44.876v10.736c0 24.74 22.128 44.867 49.327 44.867h174.546c27.2 0 49.327-20.126 49.327-44.867v-10.736c0-24.745-22.128-44.876-49.327-44.876zM419.034 650.378c0.387-0.733 2.722-2.865 7.168-2.865h174.546c4.446 0 6.782 2.131 7.168 2.865v10.432c-0.393 0.736-2.734 2.862-7.168 2.862h-174.546c-4.437 0-6.776-2.126-7.168-2.862v-10.432zM404.099 430.833h-30.097c-7.297 0-13.213-5.916-13.213-13.213v-272.34c0-7.297 5.916-13.212 13.213-13.212h30.098c7.297 0 13.212 5.916 13.212 13.212v272.341c0 7.297-5.916 13.213-13.212 13.213zM659.583 430.833h-30.097c-7.298 0-13.213-5.916-13.213-13.213v-272.34c0-7.297 5.917-13.212 13.213-13.212h30.097c7.297 0 13.212 5.916 13.212 13.212v272.341c0 7.297-5.916 13.213-13.212 13.213zM531.841 430.833h-30.098c-7.297 0-13.213-5.916-13.213-13.213v-272.34c0-7.297 5.917-13.212 13.213-13.212h30.098c7.297 0 13.212 5.916 13.212 13.212v272.341c0 7.297-5.916 13.213-13.212 13.213z" horiz-adv-x="1024" /> + + + <glyph glyph-name="bofangzanting02" unicode="&#58962;" d="M512 896C229.376 896 0 666.624 0 384 0 101.376 229.376-128 512-128 794.624-128 1024 101.376 1024 384 1024 666.624 794.624 896 512 896L512 896 512 896zM512-95.232C245.76-95.232 32.768 117.76 32.768 384 32.768 650.24 245.76 863.232 512 863.232S991.232 650.24 991.232 384C991.232 117.76 778.24-95.232 512-95.232L512-95.232 512-95.232zM733.184 392.192 393.216 588.8c-4.096 4.096-8.192 4.096-12.288 0C376.832 588.8 372.736 584.704 372.736 580.608l0-393.216c0-4.096 4.096-8.192 4.096-8.192 4.096-4.096 8.192-4.096 12.288 0l344.064 196.608c4.096 4.096 4.096 4.096 4.096 8.192C741.376 388.096 737.28 392.192 733.184 392.192L733.184 392.192 733.184 392.192zM733.184 392.192" horiz-adv-x="1024" /> + + + <glyph glyph-name="top" unicode="&#58884;" d="M812 153.4l-300 172.8-300-172.8 300 604L812 153.4zM264.5 209.2l247.5 142.5 247.5-142.5L512 707.5 264.5 209.2zM371.7 138.3l0-126.2-15.9 0 0 126.2-45.9 0L309.9 153l107.4 0 0-14.8L371.7 138.2zM506.6 154.5c26.6 0 43.3-3.9 50-11.7 6.7-7.8 10-27.2 10-58.3 0-33.5-3.2-54.2-9.6-62-6.4-7.8-23.2-11.8-50.4-11.8-27 0-43.8 3.9-50.3 11.7-6.5 7.8-9.8 27.9-9.8 60.3l0 9.9 0.2 13.3c0 18.7 4.2 31.5 12.6 38.4C467.8 151 483.5 154.5 506.6 154.5zM506.5 141c-22.3 0-35.3-2.5-39.1-7.4-3.8-5-5.7-22-5.7-51 0-29.1 1.9-46.1 5.7-51.1 3.8-5 16.8-7.4 39.1-7.4 22.4 0 35.4 2.5 39.2 7.4 3.8 5 5.7 22 5.7 51.1l0 9.2-0.1 13.3c0 15.6-2.6 25.4-7.8 29.6S525.9 141 506.5 141zM608.4 12.1 608.4 153l59.2 0 5.4 0c15.9 0 26.7-3.1 32.5-9.2 5.8-6.1 8.7-17.6 8.7-34.4 0-16.1-3-27.1-9-32.9-6-5.9-17.3-8.8-33.9-8.8l-6.2-0.1-40.7 0 0-55.5L608.4 12.1zM624.3 81.1l37.7 0c15.8 0 25.9 1.6 30.3 4.9 4.4 3.2 6.7 10.7 6.7 22.3 0 13.6-1.5 22.2-4.5 25.9-3 3.6-10.1 5.4-21.3 5.4l-6.1 0.1-42.7 0L624.4 81.1z" horiz-adv-x="1024" /> + + + <glyph glyph-name="haoyouqingqiu" unicode="&#58898;" d="M672.02974 765.933689c7.66047-32.266891 8.420787-62.237483 7.713682-95.365998-0.283456-12.778024-7.291057-71.832002-5.3918-89.926102 1.561565-14.936177 5.132904-16.128329 10.759041-28.436656 9.803273-21.422915 6.51846-50.970882 2.76088-72.566736-2.056845-11.816117-6.404873-28.64541-13.017478-38.287001-7.291057-10.645454-21.864984-10.711969-28.319999-23.12365-9.29469-17.848507-4.045129-42.930765-9.903557-62.21497-6.65763-21.883403-23.599488-23.420409-24.877597-52.040237 8.316409-1.243317 16.59598-2.479471 24.877597-3.722788 8.316409-18.498306 23.533996-55.70265 39.08518-66.900689 13.024641-3.728928 26.048259-7.448646 39.07904-11.156084 45.641503-19.593244 96.365768-43.032072 142.108578-63.215764 41.656749-18.381649 91.51325-24.937972 106.575294-70.629617 0-31.026644 2.795673-104.309694 2.025123-144.978952L58.155515-56.631556c-0.757247 40.669258 2.029216 113.952308 2.029216 144.978952 15.065114 45.691645 64.928778 52.247968 106.578364 70.629617 45.74281 20.182668 96.467075 43.62252 142.098345 63.215764 13.027711 3.707438 26.054399 7.427156 39.08211 11.156084 15.554254 11.197016 30.78105 48.402383 39.09439 66.900689l18.492166 4.710278c-4.196579 24.429389-18.658965 26.322505-24.682146 43.62559-2.356674 26.013467-4.729721 52.052516-7.095605 78.079286 0.107447-1.234107-17.006326 3.246951-19.252483 4.716418-24.130583 15.838733-24.618701 80.075757-26.941606 106.793258-1.063215 12.222369 15.163351 22.240537 10.654664 44.62536-26.433022 131.125433 11.437493 219.776496 71.330582 240.123916 41.564651 17.633612 119.167077 50.323129 191.563944 3.716648l17.971303-17.428951 29.061896-5.237281C662.71663 795.172617 672.02974 765.933689 672.02974 765.933689z" horiz-adv-x="1024" /> + + + <glyph glyph-name="weibiaoti1" unicode="&#58885;" d="M960 640 915.2 684.8 371.2 172.8 108.8 454.4 64 409.6 358.4 83.2 364.8 89.6 371.2 83.2Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="chuangkou" unicode="&#58936;" d="M96.089 724.318l0-684.236 831.822 0L927.911 724.318 96.089 724.318zM884.178 84.457 140.464 84.457 140.464 489.559l743.714 0L884.178 84.457z" horiz-adv-x="1024" /> + + + <glyph glyph-name="comiisbiaoqing" unicode="&#58892;" d="M511.558443 852.9315573333333c-246.787686 0-447.597201-200.783932-447.597201-447.598224 0-246.815315 200.783932-447.598224 447.597201-447.598224 246.841921 0 447.64939 200.782909 447.64939 447.598224C959.207833 652.1476253333334 758.400365 852.9315573333333 511.558443 852.9315573333333zM511.558443-4.962310666666667c-226.247884 0-410.295644 184.046736-410.295644 410.295644 0 226.249931 184.072319 410.296667 410.295644 410.296667 226.27449 0 410.346809-184.046736 410.346809-410.296667C921.905252 179.08442633333334 737.832933-4.962310666666667 511.558443-4.962310666666667zM724.38055 303.5726953333334c-9.698896 3.457752-20.366863-1.566682-23.848151-11.264555-28.500101-79.45461-104.372116-132.844587-188.82353-132.844587-84.798315 0-160.770614 53.689806-189.070146 133.590578-3.432169 9.723455-14.075577 14.772448-23.823592 11.364839-9.699919-3.432169-14.797008-14.100136-11.364839-23.823592 33.547047-94.77248 123.668601-158.434405 224.234017-158.434405 100.142791 0 190.140525 63.314001 223.935212 157.564595C739.125369 289.3978573333334 734.102982 300.0903843333334 724.38055 303.5726953333334zM302.49494 515.3479593333334c0-24.653493 19.98517-44.638663 44.638663-44.638663 24.653493 0 44.638663 19.98517 44.638663 44.638663s-19.98517 44.63764-44.638663 44.63764C322.48011 559.9855993333333 302.49494 540.0014523333333 302.49494 515.3479593333334L302.49494 515.3479593333334zM631.398856 515.3479593333334c0-24.653493 19.98517-44.638663 44.63764-44.638663 24.653493 0 44.63764 19.98517 44.63764 44.638663s-19.984147 44.63764-44.63764 44.63764C651.384026 559.9855993333333 631.398856 540.0014523333333 631.398856 515.3479593333334L631.398856 515.3479593333334z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zhengque" unicode="&#58902;" d="M511.999488 832.158932c-247.514481 0-448.160467-200.645987-448.160467-448.160467 0-247.514481 200.645987-448.160467 448.160467-448.160467 247.514481 0 448.160467 200.644963 448.160467 448.160467C960.160979 631.513969 759.514992 832.158932 511.999488 832.158932zM432.556056 159.918743l-185.37722 252.090711 67.856525 61.271543 117.520694-129.545578 291.29975 264.343791 52.966382-56.019931L432.556056 159.918743z" horiz-adv-x="1024" /> + + + <glyph glyph-name="money" unicode="&#58969;" d="M517.565-65.454c-244.263 0-442.299 198.014-442.299 442.299s198.014 442.299 442.299 442.299c244.263 0 442.299-198.014 442.299-442.299 0-244.263-198.014-442.299-442.299-442.299zM517.565 863.383c-268.751 0-486.564-217.834-486.564-486.564s217.834-486.564 486.564-486.564c268.751 0 486.564 217.834 486.564 486.564 0 268.751-217.834 486.564-486.564 486.564zM497.036 425.349c-18.443 6.957-33.605 16.314-45.238 27.617-11.581 11.306-20.059 23.465-25.468 36.742-5.423 13.177-8.178 26.235-8.178 39.172-0.004 18.194 2.564 34.357 7.846 48.514 5.327 14.231 13.748 25.85 25.468 35.020 11.581 9.167 26.798 15.204 45.482 18.295v-205.52zM534.455 356.132c16.937-6.756 32.277-14.997 46.035-24.855 13.748-9.678 24.613-21.601 32.929-35.57 8.204-13.909 12.436-30.734 12.622-50.307 0-14.231-1.859-27.907-5.785-40.833-3.858-12.866-9.542-24.531-17.271-34.804-7.691-10.211-17.271-18.443-28.678-24.613-11.328-6.318-24.613-9.678-39.76-10.341v221.377zM534.455 94.183c29.037 3.318 53.978 11.306 74.785 24.134 20.985 12.866 37.018 30.15 48.281 51.734 11.125 21.535 16.876 46.832 16.937 76.196 0 16.080-1.67 30.377-5.033 42.985-3.318 12.622-8.204 24.15-14.836 34.357-6.739 10.341-14.836 20.189-24.613 29.326-8.853 8.204-19.107 15.957-30.659 23.041-11.328 7.197-22.836 13.706-34.281 19.261-11.581 5.694-21.601 10.516-30.659 14.231v221.377c14.527-3.318 26.662-8.594 36.62-16.192 9.859-7.395 17.766-16.192 23.776-26.384 5.941-10.211 10.341-20.985 12.972-32.345 2.666-11.328 4.026-22.836 3.858-34.097h46.155c0.004 16.314-1.566 32.345-5.327 48.281-3.543 15.957-9.938 30.909-19.107 44.969-8.996 13.909-21.601 26.235-37.684 36.742-16.192 10.521-36.62 18.295-61.318 23.562v49.426h-37.441v-53.316c-23.465-2.624-42.985-8.178-58.595-16.314-15.633-8.204-28.279-18.194-37.684-29.562-9.441-11.328-16.523-23.302-21.226-35.317-4.59-12.062-7.846-23.302-9.316-33.326-1.566-10.211-2.256-18.194-2.115-24.029 0.004-21.601 3.452-40.612 9.863-57.238 6.479-16.523 15.58-30.909 27.178-43.441 11.659-12.436 25.361-23.562 40.833-33.204 15.633-9.678 32.649-18.443 51.098-26.235v-237.329c-18.194 1.984-33.326 7.197-45.094 15.633-11.97 8.369-21.074 19.107-27.714 31.902-6.739 12.972-11.011 27.178-13.363 42.701-2.256 15.58-3.034 31.313-2.115 47.367h-47.803c-1.183-23.776 0.397-46.035 5.033-66.676s12.357-39.030 23.376-55.019c10.892-16.080 25.361-29.037 43.142-39.030 17.847-9.863 39.472-16.080 64.586-18.295v-65.283h37.441v65.283z" horiz-adv-x="1024" /> + + + <glyph glyph-name="iconfontwodehaoyou" unicode="&#58899;" d="M1383.17753-39.758957 1380.048488-13.938772 1373.005994 17.358527 1362.834458 47.090445 1348.751189 77.605053 1334.667921 101.077167 1315.107539 123.766591 1293.199086 141.763311 1262.684478 158.975622 1240.777745 169.147158 1211.828518 176.189652 1182.87757 183.230426 1157.840075 192.619272 1126.544497 207.48523 1101.507002 219.222148 1070.992393 233.305416 1047.52028 246.607714 1047.52028 329.543663 1057.690095 341.280581 1067.080661 356.92751 1074.121435 372.576159 1079.598549 392.136541 1085.858352 415.610375 1088.204704 433.605376 1091.595216 432.822685 1098.37624 433.866846 1103.593603 438.040048 1109.330466 447.428894 1112.982449 458.3814 1115.06905 471.943448 1117.676871 496.459723 1118.719312 517.324016 1117.676871 535.059266 1114.024889 546.013493 1106.722645 550.186695 1102.549442 549.142535 1106.201425 572.614649 1109.330466 600.782906 1110.374627 626.341621 1109.851687 646.684693 1106.722645 665.462384 1100.984061 683.718855 1093.160597 700.409945 1082.20637 719.189356 1069.688483 734.838006 1055.082274 746.834673 1036.304583 758.83134 1012.832469 769.785566 993.010617 775.00121 969.017283 779.174412 945.543448 779.695632 921.550114 775.52243 898.599221 767.698965 878.256148 759.35256 860.520898 747.877113 844.089558 733.272625 828.440908 716.058594 814.35764 695.715522 804.186104 673.808789 797.92802 648.771294 797.14533 616.691305 800.274372 586.959387 804.186104 548.621314 795.579949 548.621314 790.102836 541.57882 788.539175 529.060933 790.102836 499.329015 794.014568 464.902674 797.14533 447.688644 802.622443 438.299798 812.793979 432.822685 819.052063 433.605376 822.965515 406.221529 826.877248 389.790189 833.137051 371.793469 841.743207 353.798468 851.914743 339.7152 859.738207 329.543663 858.955517 245.042333 867.267518 242.130036 878.734364 238.975192 891.063029 234.389141 902.817148 229.801371 913.712888 225.788147 923.459535 220.913103 935.215374 216.03978 948.116866 208.586158 961.018358 201.130816 971.625104 193.389921 985.386695 183.068727 997.142535 172.174708 1008.323827 158.413117 1020.077947 143.2186 1032.549389 125.729337 1043.300632 105.086951 1052.476173 82.724365 1060.502621 62.081978 1066.093267 42.729741 1069.963715 22.517404 1073.834162-0.275232 1076.41446-26.938315 1076.84451-45.000403 1075.984411-61.127268 1072.328988-73.59871 1065.377664-87.288053 1057.277248-96.391345 1042.440532-103.917215 1351.099261-103.917215 1365.182529-96.874721 1376.136756-85.922215 1383.17753-74.185298 1384.742911-59.319339ZM438.650719 816.389195 421.44873 797.467007 405.96694 775.104421 394.785647 751.021637 387.904851 723.498455 387.044752 688.234377 390.48515 655.550598 394.785647 613.405725 385.324553 613.405725 379.303857 605.66483 377.583658 591.903239 379.303857 559.21946 383.604354 521.375084 387.044752 502.452896 393.065448 492.131703 404.246741 486.111007 411.127537 486.971106 415.428034 456.867625 419.728531 438.805537 426.609327 419.02325 436.070421 399.240962 447.251713 383.759172 455.852708 372.577879 454.992609 279.687139 440.370918 270.226045 405.96694 253.884155 370.702863 238.402365 342.319581 224.640774 319.956995 215.17968 295.014111 207.438785 269.211128 202.278188 244.268244 196.257492 218.46526 185.076199 194.382475 173.034807 172.879989 157.553017 148.797205 133.470232 131.595216 108.527348 118.693724 84.444564 108.372531 58.64158 98.051337 29.398199 92.89074 6.175514 88.590243-13.606773 86.009945-36.829458 86.009945-57.471845 89.450343-78.114232 99.771536-91.875823 115.253326-102.197017 135.035613-103.917215 995.995162-103.917215 1011.476952-96.17632 1023.518344-84.134928 1031.259239-71.233436 1032.979438-54.891547 1031.259239-33.389061 1027.818842-5.005779 1020.077947 29.398199 1008.896654 62.081978 993.414864 95.625857 977.933074 121.42884 956.430587 146.371724 932.347803 166.154012 898.803924 185.076199 874.72114 196.257492 842.89746 203.998387 811.07378 211.739282 783.550598 222.060476 749.14662 238.402365 721.623438 251.303857 688.079559 266.785647 662.276576 281.407338 662.276576 372.577879 673.457869 385.479371 683.779062 402.68136 691.519957 419.883349 697.540653 441.385835 704.421449 467.188819 707.001747 486.971106 710.729418 486.111007 718.18304 487.258379 723.916463 491.84443 730.224432 502.165623 734.237656 514.207015 736.532402 529.115979 739.398253 556.066335 740.545626 579.001747 739.398253 598.496761 735.385029 610.538153 727.356861 615.125924 722.77081 613.978551 726.784034 639.781535 730.224432 670.745115 731.371805 698.842844 730.797258 721.205429 727.356861 741.847816 721.050611 761.915656 712.449617 780.265018 700.408225 800.907405 686.646634 818.109394 670.590297 831.298159 649.94791 844.485204 624.144927 856.526596 602.356888 862.261739 575.979358 866.847789 550.176374 867.422336 523.800564 862.834565 498.570407 854.233571 476.207822 845.05975 456.712807 832.443811Z" horiz-adv-x="1449" /> + + + <glyph glyph-name="wenjianxiazai" unicode="&#58910;" d="M186.888458 77.073632l0 581.729108c14.85022-14.450107 35.050284-23.436782 57.359382-23.436782l560.03604 0 0-151.561881 25.029046 0 0 176.591951-585.065086 0c-31.191396 0-57.359382 26.166963-57.359382 57.359382 0 31.191396 26.165939 57.359382 57.359382 57.359382l572.551074 0L816.798914 800.143838 244.24784 800.143838c-45.431725 0-82.388429-36.957727-82.388429-82.388429l0-640.681778c0-41.796942 34.000372-75.789127 75.789127-75.789127l225.950102 0 0 25.029046L237.648538 26.313551C209.661114 26.313551 186.888458 49.078021 186.888458 77.073632zM236.947574 730.269421l560.38601 0 0-25.029046-560.38601 0 0 25.029046ZM686.086897 428.171012c-85.917812 0-164.908864-55.248302-194.553021-135.882783-30.013571-81.641415-4.269233-175.567621 62.624293-230.942813 67.00302-55.465243 164.474982-62.808488 238.931764-17.720593 74.094532 44.868907 113.272833 133.533272 96.080266 218.517829C869.882923 357.472833 783.297916 428.171012 686.086897 428.171012zM686.086897 38.828586c-75.595722 0-145.060817 48.634674-171.092703 119.595842-26.354228 71.839165-3.63069 154.438395 55.287187 203.074092 59.017138 48.718585 144.762011 55.029314 210.191186 15.237029 65.11195-39.59888 99.396801-117.681236 84.064604-192.408171C847.384513 100.729401 771.387655 38.828586 686.086897 38.828586zM698.600909 152.235472 698.600909 311.024965 673.571862 311.024965 673.571862 152.284591 604.675726 221.172541 586.978668 203.475484 686.111456 104.351905 785.185916 203.427388 767.489882 221.123422Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="tupian" unicode="&#58893;" d="M958.648085 84.30682933333333L65.772494 84.30682933333333 65.772494 721.9115253333333l892.87559 0L958.648085 84.30682933333333zM97.660762 116.20328333333339l829.099055 0L926.759817 690.0570263333334 97.660762 690.0570263333334 97.660762 116.20328333333339zM648.731616 419.05893933333334l-1.991354 0c-47.801702 0-86.696548 38.900985-86.696548 86.695524l0 1.978051c0 47.809889 38.894845 86.671988 86.696548 86.671988l1.991354 0c47.801702 0 86.698594-38.862099 86.698594-86.671988l0-1.978051C735.43021 457.95992433333333 696.533318 419.05893933333334 648.731616 419.05893933333334zM646.740262 562.5193053333333c-30.224372 0-54.810327-24.582885-54.810327-54.787814l0-1.978051c0-30.230512 24.584931-54.803163 54.810327-54.803163l1.991354 0c30.222325 0 54.810327 24.572652 54.810327 54.803163l0 1.978051c0 30.203906-24.586978 54.787814-54.810327 54.787814L646.740262 562.5193053333333zM91.097276 181.7900473333334l-22.748097 22.338774 274.373974 279.332916 22.750143-22.351054L91.097276 181.7900473333334zM604.886015 215.92242633333342L339.999113 480.74793033333333l22.548552 22.525016L627.433544 238.4638153333334 604.886015 215.92242633333342zM619.007641 202.70744933333333l-22.763446 22.337751 167.989015 171.035398 22.765493-22.350031L619.007641 202.70744933333333zM925.622924 222.7939273333334L758.534418 389.8343373333333l22.548552 22.529109 167.086459-167.044504L925.622924 222.7939273333334z" horiz-adv-x="1024" /> + + + <glyph glyph-name="lianjie" unicode="&#58956;" d="M262.4-121.6c-64 0-128 25.6-179.2 76.8-102.4 102.4-102.4 262.4 0 364.8l134.4 134.4 89.6-89.6-134.4-134.4c-51.2-51.2-51.2-128 0-179.2 51.2-51.2 128-51.2 179.2 0l179.2 179.2c25.6 25.6 38.4 57.6 38.4 89.6S556.8 384 537.6 409.6L467.2 473.6l89.6 89.6 70.4-70.4C672 448 697.6 384 697.6 313.6c0-70.4-25.6-134.4-76.8-179.2l-179.2-179.2C396.8-96 326.4-121.6 262.4-121.6zM467.2 204.8 396.8 268.8c-102.4 102.4-102.4 262.4 0 364.8l179.2 179.2c102.4 102.4 262.4 102.4 364.8 0 102.4-102.4 102.4-262.4 0-364.8l-134.4-134.4-89.6 89.6 134.4 134.4c51.2 51.2 51.2 128 0 179.2-51.2 51.2-134.4 51.2-179.2 0L486.4 544c-51.2-51.2-51.2-128 0-179.2l70.4-70.4L467.2 204.8z" horiz-adv-x="1024" /> + + + <glyph glyph-name="creditlevel" unicode="&#59189;" d="M998.4 526.933l-200.533 275.2c-4.267 6.4-12.8 10.667-19.2 10.667h-535.467c0 0-14.933-2.133-23.467-17.067-25.6-42.667-187.733-283.733-187.733-283.733l-10.667-17.067 448-522.667c4.267-4.267 6.4-6.4 10.667-8.533 6.4-4.267 32-10.667 46.933 0 4.267 2.133 6.4 6.4 10.667 8.533l409.6 420.267c10.667 8.533 10.667 25.6 0 34.133-8.533 10.667-23.467 10.667-32 0l-354.133-364.8 153.6 422.4h251.733c2.133 0 19.2 0 23.467 4.267l2.133 2.133c12.8 6.4 14.933 21.333 6.4 36.267zM782.933 763.733l-96-226.133h-345.6l-85.333 226.133h526.933zM221.867 714.667l72.533-179.2h-192l119.467 179.2zM91.733 488.533h215.467l138.667-416-354.133 416zM503.467 44.8l-147.2 443.733h307.2l-160-443.733zM736 535.467l74.667 166.4 119.467-168.533-194.133-0z" horiz-adv-x="1024" /> + + + <glyph glyph-name="jilu" unicode="&#58894;" d="M828.01742 700.357158C743.476979 784.899646 631.076002 831.458031 511.516999 831.458031c-119.55798 0-231.959979-46.558385-316.500421-131.09985C110.47716 615.81774 63.918775 503.41574 63.918775 383.85776c0-87.103824 25.045419-171.548074 72.429613-244.204861 9.393951-14.402011 28.685319-18.46249 43.087331-9.071609 14.404058 9.393951 18.46556 28.685319 9.072633 43.089377-40.768519 62.511729-62.317301 135.194098-62.317301 210.187093 0 212.469066 172.85586 385.326972 385.325949 385.326972s385.325949-172.857906 385.325949-385.326972-172.85586-385.326972-385.325949-385.326972c-70.357418 0-139.188062 19.131733-199.052498 55.323003-14.71412 8.900717-33.856086 4.180206-42.753733-10.534937-8.896624-14.71719-4.180206-33.856086 10.534937-42.753733 69.584821-42.070164 149.556201-64.307631 231.271294-64.307631 119.559003 0 231.959979 46.558385 316.500421 131.09985 84.539418 84.539418 131.097804 196.941418 131.097804 316.499397S912.556838 615.81774 828.01742 700.357158zM494.28964 690.216193c-21.782096 0-39.397289-17.658172-39.397289-39.439244l0-283.524378c0-1.360997 0.358157-2.706645 0.493234-4.03285 2.020006-19.886933 18.959817-34.573423 39.379892-34.573423l0 0 0.146333 0.832971 223.590358 0c21.782096 0 39.438221 17.616216 39.438221 39.397289s-17.658172 39.397289-39.439244 39.397289L533.686928 408.273846l0 242.503103C533.686928 672.558022 516.071735 690.216193 494.28964 690.216193z" horiz-adv-x="1024" /> + + + <glyph glyph-name="liucheng" unicode="&#58914;" d="M512.02048 640.02048c3.584 0 6.06208 0 8.54016 0 124.19072 0 248.40192 0.04096 372.59264 0 31.10912 0 56.07424-18.08384 63.73376-46.42816 1.67936-6.20544 2.41664-12.86144 2.41664-19.29216 0.12288-169.63584 0.14336-339.2512 0.06144-508.88704-0.02048-38.03136-27.72992-65.67936-65.7408-65.69984-254.3616-0.06144-508.70272-0.06144-763.04384 0-38.1952 0.02048-65.96608 27.91424-65.96608 66.17088-0.04096 211.98848-0.04096 423.95648 0 635.96544 0 38.5024 27.87328 66.43712 66.31424 66.43712 104.83712 0.04096 209.69472 0.04096 314.53184 0 38.74816 0 66.37568-27.5456 66.49856-66.17088 0.12288-18.37056 0.06144-36.78208 0.06144-55.17312C512.02048 644.87424 512.02048 642.82624 512.02048 640.02048zM128.9216 640.4096c106.51648 0 212.56192 0 318.8736 0 0 21.31968 0 42.25024 0 63.3856-106.47552 0-212.52096 0-318.8736 0C128.9216 682.63936 128.9216 661.8112 128.9216 640.4096z" horiz-adv-x="1024" /> + + + <glyph glyph-name="fontstrikethrough" unicode="&#58959;" d="M928 448l-143.616 0c-3.456 55.616-14.272 106.56-29.504 144.96C725.504 666.816 617.344 768 464.32 768L256 768l0-320L96 448C78.336 448 64 433.664 64 416S78.336 384 96 384L256 384l0-320 229.632 0c156.288 0 240.768 97.856 267.904 167.488C772.736 280.96 782.272 333.312 784.96 384L928 384C945.664 384 960 398.336 960 416S945.664 448 928 448zM349.376 711.488l63.936 0c35.712 0 251.84 27.968 266.944-263.488l-330.88 0L349.376 711.488zM439.296 120.512 349.376 120.512 349.376 382.528 349.376 384l330.88 0C665.344 113.984 467.968 120.512 439.296 120.512z" horiz-adv-x="1024" /> + + + <glyph glyph-name="unlink" unicode="&#58957;" d="M150.336 767.68C133.44 762.304 124.16 744.32 129.472 727.488 131.2 722.176 134.208 717.44 138.304 713.664l122.624-122.432C270.208 576.192 289.92 571.52 304.96 580.736 320 590.08 324.672 609.728 315.456 624.832 312.832 629.056 309.184 632.64 304.96 635.264L182.336 757.696C175.168 765.44 164.672 769.216 154.304 767.68 152.96 767.808 151.552 767.808 150.336 767.68L150.336 767.68zM406.08 831.424c-13.696-4.48-22.72-17.6-22.016-32L384.064 672c0-17.664 14.336-32 32-32s31.872 14.336 31.872 32L447.936 799.424C448.256 817.088 434.304 831.68 416.64 832 414.464 832.064 412.16 831.808 410.048 831.424 408.704 831.552 407.296 831.552 406.08 831.424L406.08 831.424zM91.392 511.872C73.728 509.12 61.632 492.544 64.384 474.88 67.136 457.28 83.712 445.248 101.376 448L224 448C241.664 448 256 462.208 256 479.872s-14.336 32-32 32L101.376 511.872c-1.984 0.192-3.968 0.192-6.016 0C94.016 512 92.608 512 91.392 511.872L91.392 511.872zM795.456 320c-17.728-2.752-29.824-14.08-27.072-31.744 2.752-17.6 19.328-35.008 36.992-32.256L928 256c17.664 0 32 19.584 32 37.248S945.664 320 928 320l-122.624 0c-1.984 0.192-3.968 0.192-6.016 0-1.344 0.128-2.688 0.128-4.032 0L795.456 320zM598.272 127.424c-13.76-4.48-22.72-17.6-22.08-32L576.192-32c0-17.664 14.336-32 32-32S640-49.664 640-32l0 127.424c0.32 17.6-13.568 32.256-31.232 32.576-2.176 0.064-4.352-0.192-6.592-0.576-1.344 0.128-2.688 0.128-4.032 0L598.272 127.424zM726.272 191.68c-16.896-5.376-26.24-23.36-20.864-40.192 1.664-5.312 4.736-10.048 8.832-13.824l122.56-122.432c9.28-15.04 28.928-19.776 44.032-10.496 14.976 9.344 19.712 28.992 10.368 44.032-2.624 4.224-6.144 7.808-10.368 10.432l-122.56 122.432c-7.168 7.744-17.6 11.52-28.032 9.984-1.344 0.128-2.688 0.128-4.032 0L726.272 191.616zM339.968 28.032c-49.152 0-98.304 18.688-135.744 56.128-74.816 74.88-74.816 196.608 0 271.488l87.744 87.744c12.48 12.48 32.768 12.48 45.248 0s12.48-32.768 0-45.248L249.408 310.464c-49.92-49.856-49.92-131.136 0-180.992 49.856-49.856 131.136-49.856 180.992 0l87.744 87.744c12.48 12.48 32.768 12.48 45.248 0s12.48-32.768 0-45.248l-87.744-87.744C438.272 46.72 389.12 28.032 339.968 28.032zM702.144 323.712c-8.192 0-16.384 3.136-22.656 9.344-12.48 12.48-12.48 32.768 0 45.248l87.744 87.744c49.856 49.92 49.856 131.072 0 180.992-49.856 49.856-131.136 49.856-180.992 0L498.496 559.296c-12.48-12.48-32.768-12.48-45.248 0s-12.48 32.768 0 45.248l87.744 87.744c74.88 74.88 196.608 74.88 271.488 0 74.88-74.816 74.88-196.672 0-271.488l-87.744-87.744C718.528 326.784 710.336 323.712 702.144 323.712z" horiz-adv-x="1024" /> + + + <glyph glyph-name="bianjiwenzi" unicode="&#58937;" d="M944.787709 197.209397 857.081297 197.209397 741.092979-127.739937 815.146059-127.739937 832.440281-65.584762 966.82809-65.584762 984.512408-127.739937 1062.011328-127.739937 944.787709 197.209397 944.787709 197.209397ZM848.04409 1.18654 898.951519 153.258667 949.923963 1.18654 848.04409 1.18654 848.04409 1.18654ZM210.238376 489.910857 183.386821 513.121524 12.46009 313.522794C-5.874386 292.652698-3.728862 260.989968 17.271265 242.720508 38.401424 224.451048 70.454249 226.661587 88.853741 247.531683L100.361551 260.599873C106.603075 267.556571 117.200662 268.20673 124.287392 262.22527 131.309106 256.048762 132.024281 245.51619 125.912789 238.559492 107.448281 217.624381 98.085995 173.088508 119.216154 154.819048 140.281297 136.614603 183.841932 151.763302 202.371455 172.698413 208.417932 179.525079 219.145551 180.30527 226.167265 174.193778 233.188979 168.147302 233.904154 157.61473 227.792662 150.658032 209.328154 129.852952 199.965868 85.057016 221.096027 66.917587 242.16117 48.648127 285.656789 63.861841 304.186313 84.666921 310.362821 91.623619 321.025424 92.40381 327.982122 86.292317 335.068852 80.180825 335.784027 69.71327 329.672535 62.756571 311.143011 41.82146 301.845741-2.90946 322.910884-20.983873 344.041043-39.253333 387.601678-24.039619 406.00117-3.23454 412.177678 3.722159 422.840281 4.437333 429.927011-1.609143 436.948725-7.720635 437.598884-18.318222 431.487392-25.144889 413.022884-46.08 403.725614-90.810921 424.790757-109.015365 445.920916-127.154794 477.973741-125.00927 496.373233-104.20419L667.299963 95.524571 658.652852 132.908698 210.238376 489.910857 210.238376 489.910857ZM844.013106 329.516698 680.10809 471.12127 929.639011 715.190857C933.2799 718.376635 936.725741 721.562413 939.976535 725.203302 977.815773 768.048762 973.524725 833.129651 930.28917 870.513778 887.183646 907.702857 821.58263 903.281778 783.808408 860.631365L783.483328 860.761397 564.249805 571.31073 399.824662 713.56546C385.391138 726.113524 363.480789 724.553143 350.867709 710.249651L248.14263 593.871238 225.322059 567.994921 251.393424 545.434413 695.7119 161.255619 726.26936 136.679619 847.328916 281.014857C859.941995 295.318349 858.44663 316.968635 844.013106 329.516698L844.013106 329.516698ZM817.941741 830.724063C839.136916 854.779937 876.000916 857.315556 900.186821 836.250413 924.372725 815.380317 926.908344 778.906413 905.648154 754.85054 884.452979 730.924698 847.588979 728.389079 823.403075 749.389206 799.21717 770.324317 796.811582 806.798222 817.941741 830.724063L817.941741 830.724063ZM765.473932 758.491429C768.919773 741.522286 777.6319 725.593397 791.80536 713.305397 806.043836 701.017397 823.533106 694.580825 841.087392 693.540571L643.634186 494.526984 593.116852 538.217651 765.473932 758.491429 765.473932 758.491429ZM776.006503 299.739429 709.755328 219.314794 307.502122 566.369524 376.809043 645.03873C382.920535 651.865397 393.38809 652.515556 400.409805 646.534095L774.381106 323.015111C781.337805 317.098667 782.117995 306.696127 776.006503 299.739429L776.006503 299.739429Z" horiz-adv-x="1063" /> + + + <glyph glyph-name="sanjiao" unicode="&#58915;" d="M293.291 728.256l426.88-355.456-426.88-355.52z" horiz-adv-x="1024" /> + + + <glyph glyph-name="danxuankuanghouxuan" unicode="&#58943;" d="M511.998 847.999C255.739 847.999 48 640.26 48 383.999c0-256.258 207.739-463.998 463.998-463.998C768.261-79.999 976 127.742 976 383.999 976 640.26 768.261 847.999 511.998 847.999zM512.002-16.001c-220.915 0-400.002 179.088-400.002 400 0 220.917 179.086 400 400.002 400 220.912 0 399.998-179.083 399.998-400C912 163.087 732.914-16.001 512.002-16.001z" horiz-adv-x="1024" /> + + + <glyph glyph-name="danxuankuangxuanzhong" unicode="&#58947;" d="M512.5 383.5m-192 0a192 192 0 1 0 384 0 192 192 0 1 0-384 0ZM511.998 847.999C255.739 847.999 48 640.26 48 383.999c0-256.258 207.739-463.998 463.998-463.998C768.261-79.999 976 127.742 976 383.999 976 640.26 768.261 847.999 511.998 847.999zM512.002-16.001c-220.915 0-400.002 179.088-400.002 400 0 220.917 179.086 400 400.002 400 220.912 0 399.998-179.083 399.998-400C912 163.087 732.914-16.001 512.002-16.001z" horiz-adv-x="1024" /> + + + <glyph glyph-name="juzhongduiqi" unicode="&#58951;" d="M992 448 32 448C14.32 448 0 462.336 0 480 0 497.664 14.32 512 32 512L992 512C1009.68 512 1024 497.664 1024 480 1024 462.336 1009.68 448 992 448ZM800 704C817.664 704 832 689.664 832 672 832 654.336 817.664 640 800 640L224 640C206.32 640 192 654.336 192 672 192 689.664 206.32 704 224 704L800 704ZM992 832 32 832C14.32 832 0 846.336 0 864 0 881.664 14.32 896 32 896L992 896C1009.68 896 1024 881.664 1024 864 1024 846.336 1009.68 832 992 832ZM224 256C206.32 256 192 270.336 192 288 192 305.664 206.32 320 224 320L800 320C817.664 320 832 305.664 832 288 832 270.336 817.664 256 800 256L224 256ZM32 128 992 128C1009.68 128 1024 113.664 1024 96 1024 78.336 1009.68 64 992 64L32 64C14.32 64 0 78.336 0 96 0 113.664 14.32 128 32 128ZM224-64 800-64C817.664-64 832-78.336 832-96 832-113.664 817.664-128 800-128L224-128C206.32-128 192-113.664 192-96 192-78.336 206.32-64 224-64Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="youduiqi" unicode="&#58952;" d="M992 64 32 64C14.32 64 0 78.336 0 96 0 113.664 14.32 128 32 128L992 128C1009.68 128 1024 113.664 1024 96 1024 78.336 1009.68 64 992 64ZM992 256 288 256C270.32 256 256 270.336 256 288 256 305.664 270.32 320 288 320L992 320C1009.68 320 1024 305.664 1024 288 1024 270.336 1009.68 256 992 256ZM992 448 32 448C14.32 448 0 462.336 0 480 0 497.664 14.32 512 32 512L992 512C1009.68 512 1024 497.664 1024 480 1024 462.336 1009.68 448 992 448ZM992 640 288 640C270.32 640 256 654.336 256 672 256 689.664 270.32 704 288 704L992 704C1009.68 704 1024 689.664 1024 672 1024 654.336 1009.68 640 992 640ZM992 832 32 832C14.32 832 0 846.336 0 864 0 881.664 14.32 896 32 896L992 896C1009.68 896 1024 881.664 1024 864 1024 846.336 1009.68 832 992 832ZM288-64 992-64C1009.68-64 1024-78.336 1024-96 1024-113.664 1009.68-128 992-128L288-128C270.32-128 256-113.664 256-96 256-78.336 270.32-64 288-64Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zuoduiqi" unicode="&#58953;" d="M992 448 32 448C14.336 448 0 462.336 0 480 0 497.664 14.336 512 32 512L992 512C1009.664 512 1024 497.664 1024 480 1024 462.336 1009.664 448 992 448ZM32 704 736 704C753.68 704 768 689.664 768 672 768 654.336 753.68 640 736 640L32 640C14.336 640 0 654.336 0 672 0 689.664 14.336 704 32 704ZM992 832 32 832C14.336 832 0 846.336 0 864 0 881.664 14.336 896 32 896L992 896C1009.664 896 1024 881.664 1024 864 1024 846.336 1009.664 832 992 832ZM32 320 736 320C753.68 320 768 305.664 768 288 768 270.336 753.68 256 736 256L32 256C14.336 256 0 270.336 0 288 0 305.664 14.336 320 32 320ZM32 128 992 128C1009.664 128 1024 113.664 1024 96 1024 78.336 1009.664 64 992 64L32 64C14.336 64 0 78.336 0 96 0 113.664 14.336 128 32 128ZM32-64 736-64C753.68-64 768-78.336 768-96 768-113.664 753.68-128 736-128L32-128C14.336-128 0-113.664 0-96 0-78.336 14.336-64 32-64Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="gongsisvgtubiaozongji22" unicode="&#58918;" d="M79.043752 832.303282l863.551728 0c8.807596 0 15.94925-7.141654 15.94925-15.948227l0-863.553775c0-8.80555-7.141654-15.947204-15.94925-15.947204L79.043752-63.145923c-8.837272 0-15.94925 7.141654-15.94925 15.947204L63.094502 816.355055C63.094502 825.161628 70.20648 832.303282 79.043752 832.303282L79.043752 832.303282zM926.64623 800.406828 94.96128 800.406828 94.96128-31.248446l831.683926 0L926.645207 800.406828z" horiz-adv-x="1024" /> + + + <glyph glyph-name="gongsisvgtubiaozongji23" unicode="&#58919;" d="M79.963705 832.303282l863.551728 0c8.807596 0 15.94925-7.141654 15.94925-15.948227l0-863.553775c0-8.80555-7.141654-15.947204-15.94925-15.947204L79.963705-63.145923c-8.837272 0-15.94925 7.141654-15.94925 15.947204L64.014454 816.355055C64.014454 825.161628 71.126432 832.303282 79.963705 832.303282L79.963705 832.303282zM927.566182 800.406828 95.882256 800.406828 95.882256-31.248446 927.566182-31.248446 927.566182 800.406828zM143.847687 361.236554c-6.218632 6.217608-6.218632 16.335037 0 22.552645 6.248308 6.220678 16.335037 6.220678 22.554692 0l10.949376-10.916631c0.26913-0.299829 0.535189-0.567935 0.802272-0.865717L385.160685 165.51287l471.916073 471.900723c6.219655 6.217608 16.307408 6.217608 22.554692 0 6.218632-6.218632 6.218632-16.33606 0-22.553669L396.468219 131.71409l-0.028653 0.028653c-6.191003-6.187933-16.248056-6.218632-22.466688-0.028653L155.69041 349.482859c-0.327458 0.239454-0.62524 0.536212-0.893346 0.804319L143.847687 361.236554z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shuaxin" unicode="&#4098;" d="M959.362 450.833c-14.326 96.4-58.427 183.883-127.537 252.992s-156.592 113.211-252.992 127.536c-46.374 6.891-93.349 6.579-139.622-0.928-46.873-7.605-91.968-22.43-134.036-44.066-10.052-5.17-14.010-17.509-8.84-27.561 5.17-10.051 17.508-14.010 27.561-8.84 159.537 82.049 352.026 51.874 478.985-75.085 97.435-97.435 137.858-233.466 114.305-363.579-19.11 32.767-43.978 56.613-86.174 88.125-8.605 6.426-29.94 15.566-33.279-5.266-1.429-8.913 37.864-56.437 55.593-105.641 20.942-58.126 14.232-73.696 22.734-105.74 0.212-1.132 0.521-2.241 0.919-3.321 0 0 0 0 0 0 5.59-19.382 25.495-16.814 32.499-8.475 0.012 0.014 0.026 0.033 0.038 0.047 1.941 1.67 3.608 3.726 4.851 6.144 21.636 42.067 36.46 87.163 44.066 134.036 7.507 46.272 7.818 93.248 0.928 139.622zM700.103 18.032c-159.537-82.048-352.027-51.873-478.985 75.085-97.392 97.392-137.823 233.345-114.338 363.403 19.361-34.474 44.458-58.845 88.044-91.396 8.605-6.426 29.94-15.566 33.279 5.266 1.429 8.913-37.864 56.437-55.593 105.641-21.653 60.098-13.744 74.702-23.653 109.061-1.34 4.646-3.507 8.019-6.116 10.365-1.56 1.662-3.406 3.105-5.548 4.207-10.051 5.17-22.391 1.212-27.56-8.839-21.635-42.067-36.461-87.163-44.066-134.036-7.507-46.272-7.819-93.247-0.927-139.621 14.325-96.4 58.426-183.884 127.536-252.993 69.109-69.109 156.592-113.21 252.993-127.536 46.373-6.891 93.349-6.58 139.621 0.928 46.873 7.605 91.969 22.431 134.036 44.066 10.052 5.169 14.010 17.509 8.84 27.56-5.171 10.056-17.512 14.009-27.563 8.839z" horiz-adv-x="1024" /> + + + <glyph glyph-name="loading2" unicode="&#58942;" d="M537.574 831.696c-14.124 0-25.574-11.448-25.574-25.574 0-14.124 11.451-25.574 25.574-25.574 204.495 0 370.829-166.359 370.829-370.829 0-14.124 11.451-25.574 25.574-25.574 14.124 0 25.574 11.451 25.574 25.574-0.001 232.667-189.311 421.978-421.978 421.978z" horiz-adv-x="1024" /> + + + <glyph glyph-name="flow" unicode="&#58972;" d="M927.858848 417.938973 168.863431 417.938973l308.721247 308.86758c11.685133 11.69025 11.435447 30.881334-0.557702 42.868343-11.992125 11.985986-31.18321 12.226462-42.868343 0.536212L75.199191 411.071565c-1.994424-1.662873-3.773953-3.583618-5.294586-5.713119-4.047176-5.373381-6.013971-11.839653-5.9055-18.328437-0.12996-7.794523 2.725064-15.561417 8.595772-21.432125l361.565802-361.744881c11.685133-11.691273 30.876218-11.449773 42.868343 0.535189 11.993149 11.985986 12.242835 31.17707 0.557702 42.868343L168.441828 356.545718l759.417019 0c16.527418 0 29.925566 13.738909 29.925566 30.694069S944.386266 417.938973 927.858848 417.938973z" horiz-adv-x="1024" /> + + + <glyph glyph-name="jiacu" unicode="&#58923;" d="M199.092919 848.487893l355.326704 0c70.335928 0 122.780371-2.942005 157.349701-8.809643 34.568307-5.884011 65.491597-18.131963 92.78522-36.759205 27.27725-18.627243 50.01409-43.427068 68.209498-74.397431 18.195408-30.986735 27.293623-65.699328 27.293623-104.169501 0-41.7161-11.17655-79.977519-33.496905-114.802676s-52.604078-60.951187-90.818425-78.362742c54.075593-15.765055 95.647407-42.626843 124.715443-80.585363s43.602054-82.58388 43.602054-133.877103c0-40.388872-9.417487-79.673597-28.220738-117.839849-18.803251-38.182624-44.482097-68.673056-77.035514-91.489714-32.55444-22.833031-72.702835-36.855396-120.414487-42.09984-29.931706-3.229554-102.122889-5.260817-216.572524-6.060019L199.092919-40.765193 199.092919 848.487893zM378.171504 700.108494l0-205.684546 117.64849 0c69.935816 0 113.410979 1.006933 130.390699 3.038196 30.730908 3.629667 54.891168 14.246469 72.478731 31.850405 17.588587 17.588587 26.381857 40.756239 26.381857 69.473281 0 27.501354-7.594979 49.838082-22.75219 67.042929-15.158235 17.188474-37.702694 27.597545-67.618027 31.242562-17.796318 2.01489-68.945255 3.038196-153.431461 3.038196L378.171504 700.109518zM378.171504 346.04455l0-236.383732 166.622902 0c64.85203 0 106.008382 1.807159 123.43631 5.420453 26.750247 4.828982 48.543599 16.58063 65.363683 35.272341s25.247011 43.714617 25.247011 75.085092c0 26.526143-6.491855 49.03888-19.459191 67.538209-12.983709 18.48398-31.722492 31.961946-56.250118 40.404222s-77.739549 12.663414-159.619394 12.663414L378.171504 346.04455z" horiz-adv-x="1024" /> + + + <glyph glyph-name="uploading" unicode="&#59004;" d="M831.488 478.208c0 0 0 0 0 0 0 143.36-114.688 258.048-253.952 258.048-98.304 0-184.32-57.344-225.28-139.264-24.576 8.192-45.056 12.288-65.536 12.288-90.112 0-159.744-73.728-159.744-159.744 0-16.384 4.096-28.672 8.192-40.96-77.824-28.672-135.168-98.304-135.168-184.32 0-106.496 86.016-192.512 192.512-192.512h192.512v192.512l-126.976 0 258.048 258.048 258.048-258.048h-126.976v-192.512h192.512l-0 4.096c106.496 16.384 192.512 110.592 192.512 221.184-8.192 114.688-94.208 208.896-200.704 221.184z" horiz-adv-x="1033" /> + + + <glyph glyph-name="liaotianduihuaimgoutong" unicode="&#58938;" d="M998.4 500.992C998.4 682.24 811.392 829.696 581.632 829.696c-121.216 0-235.904-41.472-315.264-114.048 37.504 8.192 76.416 13.056 115.456 14.464 59.264 30.592 128.256 46.72 199.808 46.72 198.144 0 359.296-123.776 359.296-275.968 0-31.872-7.04-63.232-20.992-93.056 7.552-28.16 11.264-57.344 11.008-86.528C975.104 374.784 998.4 436.736 998.4 500.992L998.4 500.992zM442.368 398.72c-30.72 0-55.808-23.04-55.808-51.328s25.088-51.328 55.808-51.328 55.808 23.04 55.808 51.328S473.088 398.72 442.368 398.72zM243.328 398.72c-30.72 0-55.808-23.04-55.808-51.328s25.088-51.328 55.808-51.328 55.808 23.04 55.808 51.328C299.264 375.68 274.176 398.72 243.328 398.72zM641.28 398.72c-30.72 0-55.808-23.04-55.808-51.328s25.088-51.328 55.808-51.328 55.808 23.04 55.808 51.328S672.128 398.72 641.28 398.72zM442.368 677.888C212.608 677.888 25.6 530.432 25.6 349.312c0-179.968 173.696-296.192 332.544-321.664l60.8-78.336c5.632-7.424 14.464-11.008 23.296-11.008 8.832 0 17.792 3.712 23.424 11.008l60.8 78.464C685.312 53.248 859.008 169.472 859.008 349.44 859.136 530.432 672.128 677.888 442.368 677.888zM714.88 173.824c-52.224-45.184-124.288-77.952-197.376-89.6C503.168 81.92 490.112 74.24 481.28 62.72l-38.784-49.92-38.912 49.92c-8.96 11.52-21.888 19.2-36.224 21.504-73.216 11.776-145.152 44.416-197.376 89.728-39.68 34.304-86.912 92.544-86.912 175.36 0 69.76 35.584 136.192 100.352 187.264 68.736 54.144 160.768 84.096 258.944 84.096 98.304 0 190.336-29.824 259.072-84.096 64.768-51.072 100.352-117.504 100.352-187.264C801.664 266.368 754.56 208.128 714.88 173.824z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shipin1" unicode="&#59117;" d="M952.523633 599.2477269999999L952.523633 599.2477269999999 952.523633 599.2477269999999zM100.53762400000005 661.054062C100.53762400000005 661.054062 100.53762400000005 661.054062 100.53762400000005 661.054062 100.53762400000005 661.054062 100.53762400000005 661.054062 100.53762400000005 661.054062zM100.74228 720.404517L100.74228 720.404517 100.74228 720.404517zM660.990107 739.9449716666666c8.697911 0 17.498151-0.511642 25.684421-2.353553 12.279404-2.865194 23.22854-8.18627 34.382332-16.679524 15.144599-11.460777 26.196063-29.572899 32.02878-52.187469 3.479165-13.405016 2.967523-28.651944 2.558209-42.05696-0.102328-4.195463-0.204657-8.083941-0.204657-11.665434l0-37.759169 101.407415 70.401919 25.479764 17.60048c0.511642 0.306985 1.330269 1.023284 2.148896 1.637254 4.40012 3.376836 11.051464 8.595583 20.977316 11.051464 3.274508 0.818627 6.549016 1.22794 10.02818 1.22794 9.618867 0 19.44239-3.274508 27.730987999999996-9.311882 18.82842-13.916657999999998 18.726092-35.405616 18.726092-51.061857 0-1.023284 0-2.148896 0-3.172179l0-409.620466c0-15.963226 0.102328-37.963825-19.647047-51.982812-6.753672-4.809433-16.679524-8.390926-27.219346-8.390926-5.01409 0-10.130509 0.818627-15.144599 2.762866-7.162986 2.762866-12.279404 6.856000999999999-16.065554 9.823524-0.920955 0.716299-1.841911 1.432597-2.353553 1.841911l-24.968122 17.395823-101.10043 70.094934 0-37.963825c0-3.581493 0.102328-7.367643 0.204657-11.460777 0.409313-14.735285 0.818627-29.982212-2.865194-43.796542-5.62806-21.488957999999997-16.679524-39.396423-31.107825-50.447886-7.879285-6.037374-18.930748-13.405016-34.075347-16.986509-7.776956-1.841911-16.167882-2.353553-24.45648-2.353553-4.297792 0-8.595583 0.102328-12.688718 0.204657-3.683821 0.102328-7.162986 0.204657-10.232837 0.204657L167.15339300000005 84.94107466666674c-1.944239 0-3.888478 0-5.832717 0-1.944239 0-3.990806 0-5.935045 0-16.577196 0-33.461377 0.61397-47.787349 6.549016-27.935644999999997 11.563106-46.764065 37.759169-53.006096 73.574098l-0.409313 2.251224 0 2.353553c-0.102328 18.930748-0.204657 37.861497-0.306985 56.792245l0 0.511642L53.87588699999998 598.0155226666666c0 4.40012-0.102328 8.902568-0.102328 13.712001999999998-0.306985 27.01469-0.716299 54.950335 9.311882 76.643949 9.823524 21.284300999999996 27.526331999999996 38.066154 48.708304 45.945438 5.730389 2.148896 11.051464 2.762866 15.04227 3.172179 1.023284 0.102328 2.353553 0.306985 3.069851 0.409313l4.093135 1.534926 500.9997 0c3.581493 0 7.572299 0.102328 11.767763 0.306985C651.166583 739.7403146666667 656.078345 739.9449716666666 660.990107 739.9449716666666M304.273409 266.7785886666668L559.889677 394.2797376666667l0 33.973019L304.273409 555.9585626666667 304.273409 266.7785886666668M660.990107 780.8763196666666c-5.62806 0-10.949136-0.204657-15.758569-0.306985-3.888478-0.102328-7.469971-0.204657-10.437494-0.204657L133.79434400000002 780.3646776666667l-7.265314 0-6.446687-2.353553c-5.3210749999999996-0.61397-13.609673-1.841911-22.716898-5.218747-31.210153-11.665434-57.303887-36.121915-71.629859-67.229739-13.814329999999998-30.084541-13.405016-64.159888-12.995703-94.244429 0.102328-4.604777 0.102328-9.004897 0.102328-13.20036l0-371.349655 0-0.102328 0-0.102328 0-0.511642c0.102328-18.930748 0.204657-37.861497 0.306985-56.792245l0-2.251224 0-3.479165 0.61397-3.376836 0.409313-2.251224c4.195463-23.944839 12.791046-45.126811 25.479764-62.727291 13.609673-18.82842 31.107825-32.847407 52.08514-41.545318 21.488957999999997-8.902568 44.001199-9.618867 63.443589-9.618867 2.046567 0 4.093135 0 6.139702 0 1.841911 0 3.78615 0 5.62806 0l473.166384 0c2.558209 0 5.62806-0.102328 9.004897-0.204657 4.195463-0.102328 8.902568-0.306985 13.916657999999998-0.306985 13.302688 0 24.149495 1.125612 33.973019 3.479165 22.819227 5.423404 39.089437 16.474868 49.322274 24.251824 21.693613999999997 16.577196 37.963825 42.363944999999994 45.84311 72.653143 2.251224 8.595583 3.376836 17.088838 3.990806 25.377436l36.838213-25.582093 24.558809-17.088838c0.306985-0.204657 0.61397-0.511642 0.920955-0.716299 4.809433-3.683821 13.609673-10.642149999999999 26.400719-15.656241 9.516538-3.683821 19.647047-5.62806 30.084541-5.62806 18.009793 0 36.53122799999999 5.832717 50.8572 15.963226 16.577196 11.767763 27.730987999999996 27.935644999999997 33.052064 48.094334 3.78615 14.4283 3.78615 27.628659999999996 3.78615 37.34985499999999l0 409.518137c0 0.920955 0 1.739582 0 2.660538l0 0.409313c0 9.41421 0.102328 22.409913-3.479165 36.53122799999999-5.116419 19.749375-15.758569 35.81493-31.721795 47.68502-15.144599 11.153792-33.666034 17.293495-52.08514 17.293495-6.753672 0-13.507345-0.818627-19.954032-2.455881-18.21445-4.604777-30.289198-13.916657999999998-36.019586-18.419107l0 0c-0.204657-0.204657-0.511642-0.409313-0.716299-0.511642l-25.172779-17.293495-0.102328 0-0.102328 0-37.14519799999999-25.786749c-0.511642 7.674628-1.637254 15.553912-3.683821 23.433197-8.18627 31.721795-24.354152 57.508544-46.866394 74.597382-15.758569 11.972419-32.02878 19.851704-49.833916 23.944839C685.8559009999999 779.7507076666667 674.702109 780.8763196666666 660.990107 780.8763196666666L660.990107 780.8763196666666zM345.204757 332.9850436666668L345.204757 489.75210666666663l157.074048-78.48586L345.204757 332.9850436666668 345.204757 332.9850436666668zM347.455981 429.177975L347.455981 308.02118499999995 347.455981 429.177975Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yinpin" unicode="&#59132;" d="M356.285031 2.152269 356.396571 2.152269 356.396571 285.236626 253.462201 285.236626 253.462201 2.152269ZM665.076886 285.236626l103.042841 0 0-283.08538-103.042841 0 0 283.08538ZM63.809793 301.950286c0-38.758746-3.195785-112.220874 5.457292-148.208507l65.735144 0c-10.112312 35.644825-7.747451 109.176538-7.747451 148.208507 0 219.937155 172.264389 398.231887 384.763131 398.231887 212.498742 0 384.763131-178.294732 384.763131-398.231887 0-39.031968 2.266623-112.563682-7.845689-148.208507l65.735144 0c8.653077 35.987632 5.555529 109.449761 5.555529 148.208507 0 256.20415-200.670346 463.898469-448.208115 463.898469C264.479115 765.848755 63.809793 558.154435 63.809793 301.950286z" horiz-adv-x="1024" /> + + + <glyph glyph-name="wenjianjiafan" unicode="&#58916;" d="M958.129772 240.322957 833.912591 703.908846c-4.986019 18.606785-21.921537 31.601974-41.185676 31.601974L114.058652 735.51082c-1.750013 0-3.481639-0.110725-5.189082-0.315586l0 0.315586c-24.685263 0-44.768247-20.083983-44.768247-44.769246l0-612.973204c0-24.685263 20.082984-44.769246 44.768247-44.769246l172.412704 0c11.959092 0 23.201469 4.657842 31.657336 13.113709l55.508565 55.508565c1.466406 1.466406 3.417483 2.274458 5.492076 2.274458l411.098675 0c24.685263 0 44.769246 20.082984 44.769246 44.768247l0 37.982648 87.135722 0c13.36234 0 25.691381 6.079478 33.827065 16.68089C958.905846 213.930251 961.588027 227.41311 958.129772 240.322957zM101.102237 77.76757 101.102237 576.480842l95.987121-358.23072c4.986019-18.607784 21.922337-31.602973 41.185676-31.602973l554.531628 0 0-37.982648c0-4.282896-3.484637-7.767534-7.767534-7.767534L373.940452 140.896968c-11.957093 0-23.199471-4.655843-31.655538-13.110911l-55.509565-55.510364c-1.466406-1.467405-3.417483-2.275457-5.492076-2.275457L108.86977 70.000236C104.586874 70.000236 101.102237 73.484673 101.102237 77.76757zM921.416464 225.854367c-0.632171-0.824441-2.053008-2.205505-4.471368-2.205505L238.276832 223.648862c-2.546473 0-4.784956 1.718035-5.444309 4.177967L108.615143 691.411719c-0.626375 2.336616 0.33997 4.066243 0.972141 4.890884 0.631372 0.823442 2.053008 2.205505 4.471368 2.205505l678.668263 0c2.546473 0 4.784956-1.718035 5.443509-4.177967l124.21818-463.585889C923.01498 228.408635 922.047836 226.678008 921.416464 225.854367z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shouji" unicode="&#58939;" d="M731.514252 896 292.485748 896C195.323702 896 116.154627 816.830925 116.154627 719.668879l0-671.337759c0-97.162046 79.169075-176.331121 176.331121-176.331121l438.628661 0c97.162046 0 176.331121 79.169075 176.331121 176.331121L907.445529 719.668879C907.845373 816.830925 828.676298 896 731.514252 896zM292.485748 853.216712l438.628661 0c70.772355 0 128.349863-55.178446 133.147989-124.751269L159.737602 728.465443C164.135884 798.038266 222.113237 853.216712 292.485748 853.216712zM865.062085 48.730964c0-73.571261-59.976572-133.547833-133.547833-133.547833L292.485748-84.816868c-73.571261 0-133.547833 59.976572-133.547833 133.547833l0 45.582194 705.724326 0L864.662241 48.730964zM865.062085 137.096447 158.937915 137.096447 158.937915 685.682155l705.724326 0L864.662241 137.096447zM512-54.828583c13.59469 0 26.789535 5.597813 36.385787 15.194065 9.596251 9.596251 15.194065 22.791097 15.194065 36.385787 0 13.59469-5.597813 26.789535-15.194065 36.385787-9.596251 9.596251-22.791097 15.194065-36.385787 15.194065-13.59469 0-26.789535-5.597813-36.385787-15.194065-9.596251-9.596251-15.194065-22.791097-15.194065-36.385787 0-13.59469 5.597813-26.789535 15.194065-36.385787C485.210465-49.230769 498.40531-54.828583 512-54.828583z" horiz-adv-x="1024" /> + + + <glyph glyph-name="tianjia2" unicode="&#58964;" d="M566.935 57.639c0-30.366-24.612-54.972-54.935-54.972v0c-30.384 0-54.996 24.612-54.996 54.972v610.057c0 30.361 24.612 54.972 54.996 54.972v0c30.33 0 54.935-24.612 54.935-54.972v-610.057zM817.004 417.633c30.384 0 54.996-24.606 54.996-54.966v0c0-30.354-24.612-54.966-54.996-54.966h-610.062c-30.33 0-54.942 24.612-54.942 54.966v0c0 30.359 24.612 54.966 54.942 54.966h610.062zM817.004 417.633z" horiz-adv-x="1024" /> + + + <glyph glyph-name="wenjianjia" unicode="&#59296;" d="M861.040535-7.894551c0-30.909987-25.074072-55.877635-55.924707-55.877635l-698.703239 0 97.848539 461.131449c0 30.879288 24.919553 55.906288 55.770188 55.906288L902.95925 453.26555c30.855752 0 55.828516-25.027 55.828516-55.906288L861.040535-7.894551 861.040535-7.894551 861.040535-7.894551zM218.161718 495.207801l628.870778 0L847.032496 550.098969c0 30.879288-25.076118 55.906288-55.877635 55.906288L455.787744 606.005256l0 50.658773c0 30.827099-25.027 55.877635-55.877635 55.877635L120.367415 712.541665c-30.855752 0-55.877635-25.050536-55.877635-55.877635l0-664.558581 97.747231 447.175599C162.237011 470.162382 187.311083 495.207801 218.161718 495.207801L218.161718 495.207801 218.161718 495.207801zM218.161718 495.207801" horiz-adv-x="1024" /> + + + <glyph glyph-name="biaoqing" unicode="&#58960;" d="M511.931733-128c-136.738133 0-265.284267 53.213867-361.984 149.879467C53.282133 118.510933 0 247.0912 0 384c0 136.738133 53.282133 265.3184 150.050133 362.0864C246.749867 842.683733 375.296 896 512.136533 896s265.4208-53.316267 362.1888-149.9136c199.645867-199.714133 199.543467-524.5952 0-724.206933C777.454933-74.717867 648.772267-128 511.931733-128L511.931733-128 511.931733-128 511.931733-128 511.931733-128 511.931733-128zM512.034133 829.303467c-118.920533 0-230.741333-46.2848-314.914133-130.389333C113.083733 614.877867 66.7648 502.8864 66.7648 384c0-118.9888 46.2848-230.912 130.3552-315.016533 84.0704-84.0704 195.857067-130.321067 314.811733-130.321067 119.022933 0 230.946133 46.318933 315.016533 130.423467 173.704533 173.636267 173.704533 456.157867 0 629.794133C742.877867 782.984533 631.057067 829.303467 512.034133 829.303467L512.034133 829.303467 512.034133 829.303467 512.034133 829.303467 512.034133 829.303467 512.034133 829.303467zM330.103467 244.258133c0 0 59.904-95.9488 181.828267-95.9488s201.8304 95.9488 201.8304 95.9488 45.294933 0.136533 45.192533-47.957333c0 0-78.506667-111.8208-247.022933-111.8208s-223.368533 111.8208-223.368533 111.8208S286.856533 244.258133 330.103467 244.258133L330.103467 244.258133 330.103467 244.258133 330.103467 244.258133 330.103467 244.258133zM363.2128 548.590933c-34.5088 0-62.702933-28.091733-62.702933-62.737067 0-34.679467 28.194133-62.6688 62.702933-62.6688 34.679467 0 62.702933 28.091733 62.702933 62.6688C425.915733 520.4992 397.858133 548.590933 363.2128 548.590933L363.2128 548.590933 363.2128 548.590933 363.2128 548.590933 363.2128 548.590933 363.2128 548.590933zM684.544 548.590933c-34.679467 0-62.702933-28.091733-62.702933-62.737067 0-34.679467 28.023467-62.6688 62.702933-62.6688 34.6112 0 62.600533 28.091733 62.600533 62.6688C747.144533 520.4992 719.121067 548.590933 684.544 548.590933L684.544 548.590933 684.544 548.590933 684.544 548.590933 684.544 548.590933 684.544 548.590933zM684.544 548.590933" horiz-adv-x="1025" /> + + + <glyph glyph-name="html" unicode="&#58955;" d="M194.33 416.235h-101.295v101.28h-46.035v-267.030h46.035v119.7h101.28v-119.7h46.035v267.030h-46.035v-101.28zM277.205 480.69h73.665v-230.205h46.035v230.205h73.665v36.825h-193.365v-36.825zM627.815 335.58l-46.755 181.935h-73.665v-267.030h46.035v211.785l46.035-211.785h55.245l46.83 213.93-0.795-213.93h46.035v267.030h-73.665l-45.3-181.935zM848.090 287.31v230.205h-46.035v-267.030h174.945v36.825h-128.91z" horiz-adv-x="1024" /> + + + <glyph glyph-name="biaodan" unicode="&#58940;" d="M314.278111 437.019389l395.439892 0 0-30.297458-395.439892 0L314.278111 437.019389zM314.278111 315.834952l395.439892 0 0-30.297458-395.439892 0L314.278111 315.834952zM314.278111 194.62833l263.626661 0 0-30.297458L314.278111 164.330872 314.278111 194.62833zM609.376235 739.993173c-7.849678 42.966669-48.394988 75.742447-97.378777 75.742447-48.961604 0-89.51311-32.775778-97.380776-75.742447L116.55177 739.993173l0-787.725922 790.893774 0 0 787.725922L609.376235 739.993173zM446.091342 670.440529l0 17.613058 0 36.791056c0 33.410348 29.57295 60.594317 65.906116 60.594317 36.352353 0 65.907115-27.183969 65.907115-60.594317l0-36.791056 0-17.621053 16.672696-8.712493c32.358061-16.929922 57.169039-42.663874 71.406386-73.213161L358.043239 588.50688c14.240345 30.555683 39.051523 56.281241 71.408385 73.213161L446.091342 670.440529zM874.489888-17.43629 149.505227-17.43629 149.505227 709.694715 413.138884 709.694715l0-21.641327c-51.44492-26.923746-88.727643-74.124144-98.86377-129.845165l395.44289 0c-10.102151 55.730615-47.40466 102.921419-98.859773 129.845165l0 21.641327 263.631658 0L874.489888-17.43629z" horiz-adv-x="1024" /> + + + <glyph glyph-name="goumai" unicode="&#58967;" d="M365.920994 84.618469c-39.030945 0-70.78516-31.754215-70.78516-70.78516s31.754215-70.784136 70.78516-70.784136c39.030945 0 70.784136 31.753191 70.784136 70.784136S404.951939 84.618469 365.920994 84.618469zM365.920994-5.784494c-10.818393 0-19.61985 8.801457-19.61985 19.618826 0 10.818393 8.801457 19.61985 19.61985 19.61985s19.618826-8.801457 19.618826-19.61985C385.540843 3.015939 376.739387-5.784494 365.920994-5.784494zM808.821219 84.618469c-39.030945 0-70.784136-31.754215-70.784136-70.78516s31.753191-70.784136 70.784136-70.784136 70.78516 31.753191 70.78516 70.784136S847.852164 84.618469 808.821219 84.618469zM808.821219-5.784494c-10.81737 0-19.618826 8.801457-19.618826 19.618826 0 10.818393 8.801457 19.61985 19.618826 19.61985 10.818393 0 19.61985-8.801457 19.61985-19.61985C828.441069 3.015939 819.640636-5.784494 808.821219-5.784494zM443.99107 305.940157c-14.057157-1.416256-24.305569-13.959943-22.890336-28.0171 1.328251-13.187347 12.446473-23.02132 25.423019-23.02132 0.856507 0 1.723248 0.042979 2.594081 0.130983l439.314561 44.245713c0.088004 0.007163 0.174985 0.01842 0.261966 0.026606l0.180102 0.01842c0.50449 0.051165 1.001817 0.119727 1.496074 0.198521 0.222057 0.035816 0.443092 0.076748 0.663102 0.11768 0.552585 0.103354 1.100054 0.217964 1.638313 0.355087 0.085958 0.022513 0.169869 0.047072 0.254803 0.069585 0.586354 0.156566 1.161453 0.334621 1.728364 0.530073 0.077771 0.026606 0.155543 0.051165 0.233314 0.078795 0.626263 0.222057 1.239224 0.469698 1.840928 0.737804 0.039909 0.017396 0.078795 0.035816 0.118704 0.054235 1.277086 0.577145 2.496867 1.252527 3.647063 2.020006 0.001023 0.001023 0.002047 0.001023 0.00307 0.002047 0.553609 0.369414 1.088798 0.76134 1.609661 1.170662 0.069585 0.054235 0.137123 0.10847 0.205685 0.163729 0.48607 0.38988 0.958838 0.795109 1.413186 1.218758 0.092098 0.084934 0.180102 0.173962 0.270153 0.25992 0.394996 0.378623 0.778736 0.76748 1.14815 1.169639 0.11154 0.121773 0.222057 0.243547 0.331551 0.367367 0.333598 0.3776 0.653893 0.766456 0.964978 1.163499 0.12382 0.158612 0.249687 0.314155 0.370437 0.475837 0.322341 0.432859 0.629333 0.876973 0.925069 1.329275 0.113587 0.173962 0.224104 0.348947 0.333598 0.525979 0.296759 0.479931 0.580215 0.968048 0.845251 1.467421 0.069585 0.130983 0.134053 0.265036 0.201591 0.397043 0.289596 0.568958 0.563842 1.147126 0.811482 1.738597 0.00307 0.007163 0.005117 0.014326 0.008186 0.021489 0.569982 1.369184 1.019213 2.796696 1.345648 4.26514 0 0.001023 0 0.002047 0.001023 0.00307l0.00307 0.013303c0.035816 0.162706 0.075725 0.323365 0.10847 0.487094l56.17951 252.734118c0.895393 4.030803 0.780783 8.04728-0.165776 11.794627 0.50449 2.003634 0.774643 4.101411 0.774643 6.261611 0 14.128789-11.452843 25.582655-25.582655 25.582655L195.47502 616.098125l-52.358485 159.553902c-3.631714 11.067057-14.093996 17.972327-25.177426 17.590634-0.207731 0.005117-0.413416 0.01535-0.62217 0.01535L54.663994 793.258011c-14.128789 0-25.582655-11.453866-25.582655-25.582655s11.453866-25.582655 25.582655-25.582655l45.614897 0 197.955514-603.235934c3.536546-10.776438 13.546527-17.613146 24.303522-17.613146 2.067079 0 4.16281 0.26299 6.245238 0.788969l567.583946 0c14.129812 0 25.582655 11.453866 25.582655 25.582655s-11.452843 25.582655-25.582655 25.582655L340.816223 173.1979 212.265428 564.933839l701.224666 0-48.137347-216.557174L443.99107 305.940157z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiangjicopy2x" unicode="&#58973;" d="M512 480C436.515555 480 375.111111 419.712 375.111111 345.6 375.111111 271.488 436.515555 211.2 512 211.2 587.484446 211.2 648.888887 271.488 648.888887 345.6 648.888887 419.712 587.484446 480 512 480M512 172.8C414.808889 172.8 336 250.1568 336 345.6 336 441.0432 414.808889 518.4 512 518.4 609.210667 518.4 688 441.0432 688 345.6 688 250.1568 609.210667 172.8 512 172.8M903.111113 691.2 723.767113 691.2C713.383113 691.2 703.448887 695.2512 696.115554 702.4512L640.792887 756.7488C633.459554 763.9488 623.505779 768 613.141333 768L512 768 410.878222 768C400.494222 768 390.56 763.9488 383.226667 756.7488L327.904 702.4512C320.570667 695.2512 310.616889 691.2 300.252445 691.2L120.888889 691.2C77.866667 691.2 42.666667 656.64 42.666667 614.4L42.666667 76.8C42.666667 34.56 77.866667 0 120.888889 0L903.111113 0C946.133333 0 981.333333 34.56 981.333333 76.8L981.333333 614.4C981.333333 656.64 946.133333 691.2 903.111113 691.2" horiz-adv-x="1024" /> + + + <glyph glyph-name="25" unicode="&#58922;" d="M310.30303 523.636364 124.121212 523.636364c-17.128727 0-31.030303-13.901576-31.030303-31.030303l0-186.181818c0-17.128727 13.901576-31.030303 31.030303-31.030303l186.181818 0c17.128727 0 31.030303 13.901576 31.030303 31.030303L341.333333 492.606061C341.333333 509.734788 327.431758 523.636364 310.30303 523.636364zM294.787879 306.424242 139.636364 306.424242c-17.128727 0-15.515152-1.613576-15.515152 15.515152L124.121212 477.090909c0 17.128727-1.613576 15.515152 15.515152 15.515152l155.151515 0c17.128727 0 15.515152 1.613576 15.515152-15.515152l0-155.151515C310.30303 304.810667 311.916606 306.424242 294.787879 306.424242zM418.909091 352.969697l480.969697 0 0 31.030303L418.909091 384 418.909091 352.969697zM418.909091 228.848485l480.969697 0 0 31.030303L418.909091 259.878788 418.909091 228.848485zM418.909091 89.212121l480.969697 0 0 31.030303L418.909091 120.242424 418.909091 89.212121zM418.909091 492.606061l480.969697 0 0 31.030303L418.909091 523.636364 418.909091 492.606061zM992.969697 725.333333l-15.515152 0L977.454545 849.454545c0 17.128727-13.901576 31.030303-31.030303 31.030303L775.757576 880.484848c-17.128727 0-31.030303-13.901576-31.030303-31.030303l0-124.121212-139.636364 0L605.090909 849.454545c0 17.128727-13.901576 31.030303-31.030303 31.030303L403.393939 880.484848c-17.128727 0-31.030303-13.901576-31.030303-31.030303l0-124.121212-124.121212 0L248.242424 849.454545c0 17.128727-13.901576 31.030303-31.030303 31.030303L31.030303 880.484848C13.901576 880.484848 0 866.583273 0 849.454545l0-946.424242c0-17.128727 13.901576-31.030303 31.030303-31.030303l961.939394 0c17.128727 0 31.030303 13.901576 31.030303 31.030303L1024 694.30303C1024 711.431758 1010.098424 725.333333 992.969697 725.333333zM992.969697-65.939394c0-17.128727-13.901576-31.030303-31.030303-31.030303L62.060606-96.969697c-17.128727 0-31.030303 13.901576-31.030303 31.030303L31.030303 818.424242c0 17.128727 13.901576 31.030303 31.030303 31.030303l124.121212 0c17.128727 0 31.030303-13.901576 31.030303-31.030303l0-124.121212 744.727273 0c17.128727 0 31.030303-13.901576 31.030303-31.030303L992.969697-65.939394z" horiz-adv-x="1024" /> + + + <glyph glyph-name="emwdaima" unicode="&#58958;" d="M270 626c-12 12-32 12-44 0L9 409c-12-12-12-32 0-44l217-217c6-6 14-9 22-9s16 3 22 9c12 12 12 32 0 44L75 387 270 582C282 595 282 614 270 626zM1015 409 798 626c-12 12-32 12-44 0-12-12-12-32 0-44l195-195L754 192c-12-12-12-32 0-44 6-6 14-9 22-9s16 3 22 9l217 217C1027 377 1027 397 1015 409zM624 696 624 696c-16 6-34-3-40-19L382 119c-6-16 2-34 19-40l0 0c16-6 34 3 40 19l202 558C648 672 640 690 624 696z" horiz-adv-x="1025" /> + + + <glyph glyph-name="hot" unicode="&#59222;" d="M890.059904 352.19949C845.890699 458.956706 840.554889 548.495155 857.396326 618.42714 859.144623 625.686731 860.991676 631.977679 862.858846 637.425182 863.763607 640.064841 865.906573 645.659889 866.16406 646.532651L880.890349 696.448108 833.062903 675.930997C832.106692 675.5208 830.618069 674.894716 827.426684 673.550492 824.667648 672.380966 822.310677 671.354022 819.868514 670.244809 813.291441 667.257545 807.049466 664.090938 800.697749 660.412845 784.089623 650.795565 768.486253 638.656896 753.86285 623.033596 727.630498 595.007563 706.526618 557.766355 691.78157 509.713231 675.041103 455.157161 671.516484 411.46006 673.004574 347.939834 673.477918 327.734769 673.463923 322.197583 672.83965 318.324215 673.779618 324.156339 684.455526 333.678199 696.104608 329.195676 693.056849 330.368442 685.695898 339.012828 676.314007 361.368339 660.550914 398.92921 646.834249 460.170272 636.817284 549.350468 625.445924 650.588768 630.103925 734.728052 644.646978 801.338628 647.677924 815.221065 650.899934 827.082435 654.086773 836.904609 655.91465 842.538316 657.254607 846.094657 657.880284 847.554385L678.645286 896 628.243642 880.578031C617.409833 877.263087 599.94569 869.52239 578.105438 855.845223 542.547644 833.577626 507.199569 802.385036 474.400401 760.836776 447.596676 726.883228 423.611383 687.30061 403.118547 641.701619 378.907516 587.829195 363.003277 542.798944 353.158029 503.238462 349.274261 487.632585 346.433259 473.323627 344.1945 458.925156 343.334411 453.39353 342.592734 448.063234 341.804612 441.911844 341.502524 439.553997 340.356619 430.329551 340.073506 428.145504 337.596047 409.033293 335.848224 404.35337 329.235273 398.312868 336.081933 404.566848 343.232634 404.098227 346.608002 402.086756 344.852318 403.133013 341.598345 406.493651 337.991853 411.887149 327.030897 428.279226 317.980358 454.883162 313.690598 489.339595 311.250185 508.941598 310.203772 539.08627 310.370048 576.545325 310.480474 601.422138 311.113088 628.122479 312.099068 654.977888 312.481453 665.393013 312.891081 675.105466 313.30045 683.849175 313.545346 689.079919 313.735044 692.813105 313.84201 694.783403L317.55517 763.179488 271.360516 712.604139C270.467691 711.626645 268.852992 709.837042 266.618705 707.326295 262.927895 703.178805 258.823678 698.493751 254.407949 693.361469 241.78797 678.693606 229.164348 663.340425 217.341267 648.004036 211.724185 640.717803 206.411389 633.591345 201.450577 626.663838 176.017063 591.147305 156.617347 555.402528 138.122768 512.155497 90.841957 401.595812 76.97672 299.648706 99.261816 188.134893 126.80821 50.293739 188.553235-37.644222 278.8297-84.690336 344.19104-118.752337 408.837235-128 507.940695-128 525.713007-128 557.977207-125.567138 590.857378-120.462159 641.152493-112.653331 687.496192-99.789323 726.063273-80.591044 738.155853-74.571488 743.07901-59.888702 737.059454-47.796122 731.039898-35.703543 716.357111-30.780384 704.264531-36.79994 670.855859-53.430419 629.092954-65.022897 583.352478-72.12457 552.984316-76.839535 523.228215-79.083275 507.940695-79.083275 416.16215-79.083275 357.934257-70.753754 301.436271-41.310746 224.830174-1.388723 171.977796 73.88423 147.230072 197.720945 126.99711 298.965952 139.514783 391.004811 183.099329 492.921284 200.282663 533.10215 218.020237 565.784358 241.22153 598.183718 245.831691 604.621559 250.802959 611.289899 256.082244 618.137961 267.31885 632.713596 279.402035 647.409487 291.488864 661.457681 298.732051 669.876243 304.338773 676.176713 307.478705 679.614406L264.997214 697.435142C264.883874 695.347445 264.688038 691.493511 264.43725 686.13688 264.020474 677.234965 263.603959 667.359281 263.215279 656.772625 262.21142 629.430212 261.566827 602.224414 261.453805 576.762458 261.278897 537.358818 262.385015 505.49418 265.148621 483.296209 276.058157 395.668083 322.627019 326.024497 362.226031 362.195618 379.341732 377.829698 384.756649 392.328523 388.584361 421.857186 397.932742 493.974714 407.332926 531.746825 447.736538 621.64966 466.587287 663.594818 488.484326 699.731218 512.795234 730.526996 542.034492 767.565749 573.156162 795.028785 604.068111 814.386984 614.696751 821.043029 624.472062 826.201428 633.124687 830.036563 638.02329 832.207788 641.258688 833.404991 642.556233 833.802016L612.91959 866.825663C608.658554 856.884484 602.686705 838.478616 596.856038 811.772799 581.186705 740.003594 576.231674 650.498985 588.206246 543.890345 607.295279 373.942261 638.819345 298.82557 678.537329 283.542234 701.302332 274.782345 717.731637 289.435669 721.133156 310.5407 722.475759 318.870999 722.489387 324.263403 721.907881 349.085491 720.532565 407.791853 723.691247 446.952173 738.546223 495.36355 751.151827 536.44438 768.544047 567.135763 789.576147 589.605967 809.230566 610.60429 821.725461 617.839716 852.347733 630.976117L842.705318 653.453557 819.246577 660.374464C822.235501 670.505564 813.450321 644.87463 809.839253 629.880119 790.647573 550.189047 796.611315 450.1135 844.8591 333.498332 883.105728 241.056017 874.587669 126.064924 824.002925 61.397129 815.680378 50.757545 817.558709 35.3857 828.198295 27.063153 838.837879 18.740608 854.209724 20.61894 862.532269 31.258524 924.762731 110.814263 934.658528 244.404363 890.059904 352.19949Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shezhi11" unicode="&#59158;" d="M466.496-126.624l-1.056 0.064c-25.184 2.080-47.456 22.368-51.744 47.232l-17.344 102.4c-0.672 4.064-6.624 11.040-10.56 12.416l-30.336 12.416c-5.44 2.496-15.424 0.8-17.472-0.64l-84.992-60.16c-19.584-14.016-51.456-12.736-70.080 3.168l-64.288 64c-17.952 20.48-19.488 50.592-4.736 71.296l60.416 84.672c2.176 3.072 2.784 11.52 1.024 15.040v0c0 0-1.664 3.104-7.264 16.608-6.176 14.848-6.816 17.44-6.816 17.44-0.992 3.040-7.456 8.672-11.36 9.376l-102.56 17.248c-25.152 4.288-45.44 26.624-47.168 52l-0.16 90.336c2.112 27.36 22.496 49.6 47.52 53.728l102.528 17.344c4.128 0.672 11.008 6.56 12.416 10.496l12.608 30.336c2.368 4.992 1.6 14.112-0.8 17.504l-60.288 84.544c-14.624 20.64-13.28 50.656 3.072 69.952l64.416 64.224c20.672 18.208 51.296 18.784 71.36 4.64l84.992-60.16c1.952-1.376 13.28-2.016 15.040-1.056 0.384 0.192 2.528 1.344 16.704 7.168 14.24 5.92 16.576 6.592 16.576 6.592 3.84 1.184 9.504 7.648 10.144 11.424l17.44 102.4c4.32 25.152 26.752 45.376 52.128 47.104l90.528 0.064c27.328-2.112 49.632-22.368 53.952-47.232l17.344-102.432c0.672-4.064 6.656-11.040 10.624-12.48l30.304-12.352c6.24-2.784 15.456-0.8 17.44 0.608l85.024 60.16c19.52 14.016 51.392 12.704 70.080-3.136l64.288-64.032c17.952-20.48 19.456-50.56 4.736-71.264l-60.416-84.672c-2.208-3.136-2.848-11.616-1.056-15.040 0.16-0.352 1.376-2.56 7.232-16.672 5.856-14.112 6.592-16.512 6.592-16.512 1.248-4.032 7.712-9.6 11.648-10.304l102.56-17.248c25.152-4.224 45.44-26.592 47.168-52l0.096-90.304c-2.112-27.392-22.528-49.6-47.552-53.728l-102.528-17.376c-4.128-0.672-10.944-6.496-12.32-10.432l-12.736-30.432c-2.336-4.928-1.568-14.112 0.832-17.472l60.288-84.512c14.624-20.736 13.216-50.816-3.232-70.048l-64.192-64.096c-11.328-9.92-24.64-14.72-38.784-14.72v0c-11.904 0-23.52 3.552-32.704 10.016l-84.992 60.16c-1.952 1.408-13.312 2.016-15.072 1.056-0.288-0.16-2.432-1.312-16.608-7.2-14.080-5.792-16.384-6.496-16.384-6.496-4.16-1.28-9.792-7.776-10.432-11.52l-17.408-102.4c-4.352-25.152-26.72-45.344-52.032-47.104h-91.648zM347.84 100.608c10.368 0 20.192-2.112 28.48-6.112l27.648-11.296c20.416-7.072 38.976-28.992 42.848-51.584l17.344-102.336c0.288-1.6 3.136-4.32 5.056-4.832l87.296 0.064c-0.032 0.064 3.040 2.944 3.328 4.672l17.408 102.368c3.872 22.656 23.328 44.832 45.28 51.584 0 0 0 0 0 0-0.096 0 2.976 1.152 12.448 5.056 9.472 3.936 12.384 5.248 13.12 5.568 18.208 9.6 49.44 8.032 67.776-4.96l84.928-60.16c0.192-0.128 1.312-0.64 3.104-0.64v0c2.048 0 3.52 0.672 3.872 0.96l61.536 61.408c-0.16 0 0.064 4.416-0.992 5.952l-60.224 84.448c-13.248 18.624-15.68 47.168-5.792 67.872l11.648 27.84c6.944 19.968 29.408 38.912 51.68 42.496l102.464 17.376c1.824 0.384 4.736 3.648 4.864 5.408l-0.16 86.528c-0.096 0-2.88 3.072-4.576 3.424l-102.72 17.28c-23.168 4.032-44.896 22.976-51.776 45.056v0c-0.032 0-1.216 3.040-5.12 12.512-3.968 9.568-5.28 12.512-5.632 13.248-10.24 19.36-8.288 48.736 4.96 67.456l60.512 84.736c0.96 1.408 0.736 5.6-0.384 6.912l-61.408 61.184c0.704-0.8-0.768-0.192-2.848-0.192-1.728 0-2.784-0.416-3.008-0.576l-85.024-60.16c-17.824-12.8-47.776-15.36-68-5.664l-27.712 11.296c-20.512 7.2-39.040 29.088-42.88 51.584l-17.344 102.336c-0.288 1.76-3.616 4.704-5.504 4.864l-86.72-0.064c0-0.064-3.104-2.944-3.392-4.672l-17.408-102.336c-3.84-22.624-23.264-44.8-45.216-51.584 0-0.032-3.008-1.184-12.416-5.088-9.568-3.936-12.512-5.248-13.248-5.568-17.984-9.568-49.344-8.032-67.744 4.992l-84.928 60.096c-0.416 0.32-6.176 0.288-6.848-0.224l-61.728-61.504c0 0 0 0 0 0 0.224 0 0.032-4.384 1.056-5.856l60.256-84.512c13.312-18.752 15.744-47.296 5.76-67.968l-11.52-27.648c-6.976-20.032-29.472-38.944-51.776-42.624l-102.496-17.344c-1.824-0.384-4.704-3.648-4.832-5.408l0.096-86.56c0.096 0 2.912-3.104 4.608-3.424l102.656-17.28c23.040-4 44.704-22.912 51.712-44.928 0.256-0.736 1.44-3.84 5.088-12.64 3.68-8.832 5.024-11.84 5.472-12.736 10.592-20.288 8.672-48.96-4.672-67.904l-60.512-84.768c-0.96-1.408-0.736-5.632 0.384-6.912l61.408-61.184c-0.736 0.8 0.736 0.224 2.816 0.192 1.728 0 2.784 0.416 3.008 0.576l84.992 60.16c10.432 7.456 24.896 11.744 39.648 11.744zM512.032 133.856c-138.336 0-250.848 112.224-250.848 250.176 0 137.92 112.544 250.144 250.848 250.144s250.848-112.224 250.848-250.144c-0-137.952-112.544-250.176-250.848-250.176zM512.032 583.136c-110.080 0-199.648-89.312-199.648-199.104s89.568-199.136 199.648-199.136 199.648 89.344 199.648 199.136-89.568 199.104-199.648 199.104z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zitixiahuaxian" unicode="&#58950;" d="M0-49.230769 945.230769-49.230769 945.230769-128 0-128 0-49.230769ZM0 896 407.076943 896 407.076943 834.065644 319.153861 827.872177 299.076923 809.911217 299.076923 365.841959C299.076923 281.197962 317.076716 220.709337 353.076933 184.374351 389.077071 148.039365 448.153442 129.872108 530.307702 129.872108 606.000364 129.872108 660.807522 149.174823 694.730752 187.780726 728.653982 226.386629 745.61536 289.662267 745.61536 377.609531L745.61536 804.956475 724.153817 826.633531 633.461524 834.065644 633.461524 896 955.384596 896 955.384596 834.065644 868.846119 826.633531 849.461563 804.956475 849.461563 364.603313C849.461563 246.927439 819.923338 161.665339 760.846178 108.814415 701.76894 55.96349 606.462188 29.538462 474.923087 29.538462 406.153531 29.538462 345.807951 38.518863 293.884613 56.479902 241.961275 74.44094 201.230887 100.143419 171.692347 133.588204 149.076834 160.013627 133.038474 190.25794 123.57695 224.322009 114.115348 258.386078 109.384625 307.210476 109.384625 370.796702L109.384625 809.911217 89.307687 827.872177 0 834.065644 0 896Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="sanjiao1" unicode="&#58917;" d="M773.128299 88.652342M889.696178 575.195553 158.862147 575.195553 524.357446 209.647043 889.696178 575.195553Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="tupian-copy-copy" unicode="&#58954;" d="M765.376 615.424c0 0 103.040 1.024 103.040-100.992 0 0 9.536-98.752-103.040-100.928 0 0-100.864-2.176-99.84 100.928 0 0.064-1.088 91.456 99.84 100.992zM968.32 770.56c0 0 54.208-4.224 54.208-52.032v-712.832c0 0-3.2-51.008-54.208-52.096v816.96zM1.472 5.632c0 0 2.176-52.096 52.096-52.096h914.752v150.848h-99.712l-203.072 206.144-153.024-153.984-208.192 257.024-205.056-307.072-45.632-1.024-1.152 612.992h-51.008v-712.832zM968.32 770.56h-914.752c0 0-52.096 1.088-52.096-52.032h966.848v52.032z" horiz-adv-x="1024" /> + + + <glyph glyph-name="caidan" unicode="&#58993;" d="M511.998465 623.681848c40.525995 0 73.386404 35.771715 73.386404 79.892585s-32.860409 79.892585-73.386404 79.892585c-40.524972 0-73.384357-35.771715-73.384357-79.892585S471.47247 623.681848 511.998465 623.681848L511.998465 623.681848zM511.998465 463.893608c-40.524972 0-73.384357-35.772738-73.384357-79.893608 0-44.12087 32.859385-79.892585 73.384357-79.892585 40.525995 0 73.386404 35.772738 73.386404 79.892585C585.384869 428.12087 552.52446 463.893608 511.998465 463.893608L511.998465 463.893608zM511.998465 144.320199c-40.524972 0-73.384357-35.733852-73.384357-79.894631 0-44.119847 32.859385-79.893608 73.384357-79.893608 40.525995 0 73.386404 35.772738 73.386404 79.893608C585.383846 108.586346 552.52446 144.320199 511.998465 144.320199L511.998465 144.320199z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zhuti2" unicode="&#58988;" d="M878.368178 798.272211c-11.363815 4.799306-24.470321 2.360767-33.31578-6.245238-0.36532-0.350994-37.162388-35.304064-95.163383-56.05262-75.462692-26.993794-150.763702-18.409279-223.812415 25.517163-38.347376 23.060205-81.875752 40.665165-129.376603 52.327786-37.582967 9.228175-77.742619 14.777565-119.363552 16.496719-70.805626 2.925632-121.493052-6.224772-123.615389-6.615675-14.56574-2.682086-25.140587-15.380292-25.140587-30.191626L128.58047-31.312914c0-16.954137 13.745049-30.699186 30.699186-30.699186s30.699186 13.745049 30.699186 30.699186L189.978842 266.683061c15.562441 5.250584 47.994084 14.447037 91.40171 17.48728 35.985586 2.51938 72.440869 0.378623 108.35073-6.363941 44.847417-8.420787 89.059362-24.102954 131.409912-46.611597 46.26879-24.591071 93.776803-41.069371 141.203976-48.977481 38.270629-6.380314 76.541257-7.219425 113.740484-2.491751 64.277956 8.16803 103.877859 30.461779 105.532545 31.406291 9.56689 5.464455 15.471366 15.637142 15.471366 26.656103L897.089565 769.958352C897.091612 782.298402 889.73711 793.470859 878.368178 798.272211zM835.69324 257.496841c-14.58416-5.755074-38.82526-13.530155-70.319555-17.225313-30.990828-3.635807-62.940494-2.676969-94.952582 2.851954-40.201607 6.943133-80.731696 21.171182-120.464629 42.289152-48.455595 25.753547-99.208513 43.61945-150.848637 53.101405-29.29214 5.378497-58.896388 8.079002-88.407516 8.079002-12.228509 0-24.443715-0.464581-36.609803-1.39272-34.879392-2.663666-63.618946-8.741082-84.111676-14.355963L189.978842 766.569162c19.971867 2.003634 50.446949 3.910053 86.392626 2.334161 58.186214-2.554172 143.250588-15.041578 218.064504-60.029188 61.32674-36.877909 119.196753-49.491181 169.691797-49.488111 42.293245 0.002047 79.416747 8.854669 109.019972 19.711947 24.269753 8.901741 45.327348 19.747763 62.544475 30.179346L835.692217 257.496841z" horiz-adv-x="1024" /> + + + <glyph glyph-name="loading1" unicode="&#58941;" d="M441.391 756.654c0-38.996 31.612-70.608 70.608-70.608s70.608 31.612 70.608 70.608c0 38.996-31.612 70.608-70.608 70.608-38.996 0-70.608-31.612-70.608-70.608zM167.486 639.997c0-37.865 30.696-68.562 68.562-68.562 37.865 0 68.562 30.696 68.562 68.562 0 37.865-30.696 68.562-68.562 68.562-37.865 0-68.562-30.696-68.562-68.562zM63.109 382.124c0-0 0-0 0-0 0-34.475 27.947-62.422 62.422-62.422 34.475 0 62.422 27.947 62.422 62.422 0 0 0 0 0 0 0 34.475-27.947 62.422-62.422 62.422-34.475 0-62.422-27.947-62.422-62.422zM173.626 100.715c0-29.953 24.282-54.235 54.235-54.235s54.235 24.282 54.235 54.235c0 29.953-24.282 54.235-54.235 54.235-29.953 0-54.235-24.282-54.235-54.235zM466.974-16.844c-0-0-0-0-0-0 0-26.064 21.129-47.193 47.193-47.193 26.064 0 47.193 21.129 47.193 47.193 0 0 0 0 0 0 0 0 0 0 0 0 0 26.064-21.129 47.193-47.193 47.193-26.064 0-47.193-21.129-47.193-47.193 0-0 0-0 0-0zM770.896 91.45c0-0 0-0 0-0 0-18.686 15.148-33.835 33.835-33.835 18.686 0 33.835 15.148 33.835 33.835 0 0 0 0 0 0 0 0 0 0 0 0 0 18.686-15.148 33.835-33.835 33.835-18.686 0-33.835-15.148-33.835-33.835 0-0 0-0 0-0zM911.584 383.395c0-13.238 10.732-23.97 23.97-23.97s23.97 10.732 23.97 23.97c0 0 0 0 0 0 0 13.238-10.732 23.97-23.97 23.97-13.238 0-23.97-10.732-23.97-23.97 0-0 0-0 0-0zM839.588 634.8c0-0 0-0 0-0 0-9.464 7.672-17.135 17.135-17.135 9.464 0 17.135 7.672 17.135 17.135 0 0 0 0 0 0 0 0 0 0 0 0 0 9.464-7.672 17.135-17.135 17.135-9.464 0-17.135-7.672-17.135-17.135 0-0 0-0 0-0z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xieti" unicode="&#58948;" d="M897.948 834.255l0-64.322-128.65 0L447.674-1.933l128.65 0 0-64.32L126.052-66.253l0 64.32 128.65 0 321.622 771.866-128.65 0L447.674 834.255 897.948 834.255z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shuaxin-copy" unicode="&#58982;" d="M688.146 736l-192 128v-256l192 128.001zM496.146 767.709c-231.174-8.416-416-198.479-416-431.709 0-238.587 193.413-432 432-432 233.23 0 423.293 184.826 431.709 416h-64.050c-8.377-195.817-169.778-352-367.658-352-203.241 0-368 164.759-368 368 0 197.88 156.183 359.282 352 367.658v64.051z" horiz-adv-x="1024" /> + + + <glyph glyph-name="jine" unicode="&#58974;" d="M511.998 896c-282.765 0-511.994-229.231-511.994-511.999 0-282.773 229.228-512.001 511.994-512.001 282.769 0 511.995 229.228 511.995 512.001 0.001 282.768-229.226 511.999-511.995 511.999zM511.998-91.597c-262.66 0-475.59 212.931-475.59 475.598 0 262.663 212.93 475.595 475.59 475.595 262.663 0 475.591-212.932 475.591-475.595 0.001-262.666-212.926-475.598-475.591-475.598zM738.743 301.138h-194.31v69.78h194.31c17.835 0 32.249 14.439 32.249 32.221 0 17.784-14.414 32.195-32.249 32.195l-148.996-0 149.621 209.579c8.916 15.398 3.631 35.099-11.82 43.989-15.399 8.892-35.097 3.63-44.018-11.794l-171.341-240.010-171.344 240.010c-8.865 15.423-28.618 20.685-44.016 11.794-15.396-8.889-20.685-28.59-11.82-43.989l149.623-209.579h-149.001c-17.782 0-32.245-14.411-32.245-32.195 0-17.782 14.463-32.221 32.245-32.221h194.31v-69.78l-194.31 0c-17.782 0-32.245-14.413-32.245-32.195s14.463-32.221 32.245-32.221h194.31v-132.435c0-17.781 14.463-32.195 32.248-32.195 17.835 0 32.245 14.414 32.245 32.195l-0 132.434h194.31c17.835 0 32.249 14.439 32.249 32.221s-14.415 32.196-32.251 32.196z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zhuye" unicode="&#59022;" d="M824.084343-40.420339H232.898863c-74.604138 0-85.85232 28.334325-85.852321 49.997718l-0.584307 5.314029V447.645552h48.806589v-402.916582c0-25.547863 13.548574-36.343743 37.629015-36.343743h568.020898c25.928532 0 27.978215 6.220678 27.978215 37.84391V447.585177l48.806589 0.118704c0.022513-14.346753 0-382.76666 0-433.098999 0-38.130436-12.726859-54.765301-51.858088-54.765301l-1.76111-0.25992zM1012.470921 493.103884C849.773422 615.120868 687.101505 737.137853 524.404006 859.153814c-6.207375 4.659113-18.433838 4.659113-24.641213 0C337.077573 737.137853 174.393377 615.120868 11.696902 493.103884c-24.856108-18.635429-0.572028-61.044308 24.642236-42.13361A15995638.709915 15995638.709915 0 0 1 512.025071 807.737794c0.988514-0.715291 1.644453-1.144056 2.823302-2.037403 18.040888-13.524015 36.057217-27.036773 54.073546-40.560788 58.291614-43.718711 116.583229-87.437421 174.874843-131.143852 81.33647-61.008492 162.696476-122.015961 244.033969-183.024454 25.212218-18.911722 49.496298 23.497157 24.64019 42.132587z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yonghu" unicode="&#59248;" d="M611.2 342.4c70.4 54.4 115.2 140.8 115.2 230.4 0 156.8-128 288-284.8 288s-284.8-128-284.8-284.8c0-92.8 44.8-182.4 115.2-236.8C108.8 272 0 105.6 0-80c0-9.6 9.6-19.2 19.2-19.2h848c9.6 0 19.2 9.6 19.2 19.2 0 188.8-112 355.2-275.2 422.4z m-576-396.8C44.8 115.2 156.8 268.8 320 320c6.4 3.2 12.8 9.6 12.8 16s-3.2 16-9.6 19.2c-76.8 41.6-128 131.2-128 224 0 134.4 112 246.4 246.4 246.4s246.4-112 246.4-249.6c0-89.6-51.2-176-128-220.8-6.4-3.2-9.6-9.6-9.6-19.2 0-6.4 6.4-12.8 12.8-16 160-51.2 275.2-204.8 281.6-377.6H35.2zM812.8 361.6c54.4 41.6 86.4 108.8 86.4 176 0 89.6-54.4 172.8-134.4 208-9.6 3.2-22.4 0-25.6-9.6-3.2-9.6 0-22.4 9.6-25.6 67.2-28.8 112-99.2 112-172.8 0-67.2-38.4-131.2-96-163.2-6.4-3.2-9.6-9.6-9.6-19.2 0-6.4 6.4-12.8 12.8-16 131.2-41.6 217.6-160 217.6-297.6 0-9.6 9.6-19.2 19.2-19.2s19.2 9.6 19.2 19.2c-3.2 140.8-86.4 262.4-211.2 320z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiaoxi2" unicode="&#58983;" d="M544 798.976V864h-64v-65.024C289.536 786.304 160 658.624 160 416v-288h64V416c0 192 115.456 320 288 320 180.544 0 288-128 288-320v-288h64V416c0 242.88-122.496 370.56-320 382.976zM672 64a160 160 0 1 0-320 0h64a96 96 0 0 1 192 0h64zM64 128h896v-64H64v64z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yuyin" unicode="&#59016;" d="M463.380164 644.056897v-0.003069c-4.550643 4.549619-10.484795 7.02295-16.913205 7.02295s-12.365632-2.473331-16.915251-7.02295c-4.549619-4.551666-7.020904-10.485819-7.020904-16.914229s2.471284-12.365632 7.020904-16.915251c60.437487-60.438511 93.675496-140.756791 93.675496-226.222301 0-85.464487-33.238009-165.783791-93.675496-226.220255-4.549619-4.551666-7.020904-10.487865-7.020904-16.915252 0-6.429433 2.471284-12.365632 7.020904-16.914228 4.550643-4.549619 10.486842-7.02295 16.915251-7.02295s12.364609 2.473331 16.913205 7.02295c35.114752 35.116799 62.317301 76.06849 80.814584 121.668037 17.904789 44.018539 26.90579 90.608647 26.90579 138.384768s-9.101285 94.26799-26.90579 138.384767c-18.59552 45.697785-45.698808 86.550215-80.814584 121.667013zM781.892405 618.929614v-0.002047c-31.358195 77.452-77.550237 146.990772-137.098471 206.539007-4.550643 4.549619-10.485819 7.02295-16.915252 7.02295-6.42841 0-12.363585-2.473331-16.914228-7.02295-9.29776-9.299807-9.29776-24.531719 0-33.82948 54.997592-54.998615 97.631598-119.195729 126.613676-190.71153 27.993564-69.044516 42.237987-142.045133 42.237987-216.924541s-14.244422-147.882072-42.237987-216.923518c-28.982078-71.517847-71.616084-135.616724-126.613676-190.711529-9.29776-9.298783-9.29776-24.531719 0-33.82948 4.551666-4.551666 10.485819-7.02295 16.914228-7.02295 6.429433 0 12.366655 2.471284 16.915252 7.02295 59.547211 59.547211 105.740276 129.085984 137.098471 206.53696 30.369681 74.78117 45.699832 153.817248 45.699831 234.928591 0 81.111343-15.331173 160.146397-45.699831 234.927567zM299.474141 427.621497c-11.670807 11.573593-27.103288 18.004049-43.522236 18.004049-16.419971 0-31.852452-6.429433-43.52326-18.004049-11.57257-11.57257-18.003026-27.104311-18.003026-43.522236 0-16.420995 6.42841-31.851429 18.003026-43.52326 11.574616-11.57257 27.103288-18.003026 43.52326-18.003025s31.852452 6.429433 43.522236 18.003025c11.573593 11.573593 18.003026 27.104311 18.003025 43.52326 0 16.419971-6.427386 31.852452-18.003025 43.522236z" horiz-adv-x="1024" /> + + + <glyph glyph-name="download" unicode="&#59009;" d="M666.931 445.918l-124.245 99.362c-7.221 5.639-16.428 9.042-26.429 9.042-9.963 0-19.136-3.376-26.438-9.047l-124.215-99.391c-9.615-7.772-15.713-19.565-15.713-32.782 0-9.946 3.453-19.084 9.223-26.284 13.828-17.359 41.51-20.465 58.918-6.505l56.252 45.022v-261.12c0-23.177 18.842-41.984 41.95-41.984s41.95 18.842 41.95 41.984v261.12l56.286-45.056c17.545-13.892 45.090-10.718 58.914 6.554 5.754 7.137 9.236 16.316 9.236 26.308 0 13.211-6.086 24.999-15.609 32.716zM235.827 142.95c-85.026 0-152.542 31.71-188.655 89.839-36.113 58.095-34.406 134.724 4.335 195.174 37.342 58.334 102.366 92.023 178.995 94.549-19.866 130.492 42.667 202.377 84.753 235.008 90.112 69.871 234.257 79.053 335.565 21.367 58.982-33.587 94.037-85.675 100.454-146.978 113.937 18.978 177.562-33.826 206.814-69.905 63.317-78.131 71.27-204.39 18.91-300.203-46.524-85.060-130.389-127.317-229.82-116.497-18.739 2.116-32.222 18.978-30.174 37.683s19.285 32.017 37.683 30.174c96.7-10.718 143.258 46.353 162.406 81.408 39.014 71.373 33.826 167.868-12.049 224.495-38.673 47.684-100.352 60.518-178.483 37.069-2.94-0.916-6.319-1.443-9.822-1.443-18.851 0-34.133 15.282-34.133 34.133 0 1.495 0.096 2.969 0.283 4.414 8.549 68.506-31.114 106.53-65.93 126.362-77.346 44.066-191.522 37.035-259.925-15.974-58.266-45.193-75.947-117.18-51.132-208.179 0.761-2.688 1.198-5.775 1.198-8.963 0-18.851-15.282-34.133-34.133-34.133-1.481 0-2.94 0.094-4.371 0.277-70.759 8.822-128.991-13.535-159.677-61.424-24.61-38.434-26.146-86.46-3.823-122.368 27.716-44.578 86.050-64.375 164.147-55.637 1.132 0.133 2.443 0.209 3.772 0.209 18.853 0 34.138-15.284 34.138-34.138 0-17.525-13.205-31.965-30.208-33.914-14.153-1.653-27.874-2.404-41.118-2.404z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yemian1" unicode="&#58965;" d="M790.080 177.92l-138.112-119.232v119.232h138.112zM198.848 763.008h627.328v-516.16h-209.088c-0.076 0.001-0.166 0.001-0.256 0.001-19.042 0-34.488-15.401-34.56-34.426l-0-206.535h-383.424v757.12zM861.056 831.808h-697.024c-0.076 0.001-0.166 0.001-0.256 0.001-19.042 0-34.488-15.401-34.56-34.426l-0-825.927c0.072-19.032 15.517-34.433 34.56-34.433 0.090 0 0.18 0 0.27 0.001l453.042-0 278.784 240.896v619.456c-0.072 19.032-15.517 34.433-34.56 34.433-0.090 0-0.18-0-0.27-0.001z" horiz-adv-x="1024" /> + + + <glyph glyph-name="moban" unicode="&#58979;" d="M734 172.9v82.8h-59.9v-37l-35.7-9.7 15.7-57.8zM674.1 419.3H734v-81.8h-59.9zM734 600.2l-95.6-26 15.7-57.8 20 5.4v-20.7H734zM866.1 131.3v-37l-35.7-9.7 7.9-28.9 7.8-28.9 79.9 21.7v82.8h-29.9zM740.9 60.3L651.4 36l7.9-28.9 7.8-29 89.5 24.4-7.8 28.9zM740.9 781.7l-89.5-24.3 7.9-28.9 7.8-28.9 89.5 24.3-7.8 28.9zM830.4 806l7.9-28.9 7.8-28.9 20 5.5v-20.8H926V832zM866.1 612.6v-120.3H926V612.6h-29.9zM866.1 371.9v-120.3H926V371.9h-29.9zM541.9 665.6l35.7 9.7-7.8 28.9-7.8 28.9-50-13.6L98 832v-783.5l384.1-104.3L512-64l29.9 8.1 35.7 9.7-7.8 28.9-7.8 28.9-20-5.4V120.8l35.7 9.7-15.7 57.8-20-5.4V486l35.7 9.7-15.7 57.8-20-5.4V665.6z m-59.8-659.4l-324.2 88.1V753.7l324.2-88.1V548l-192 52.2v-427.3l192-52.2v-114.5z m0 360.9V182.8l-132.2 35.9V521.8l132.2-35.9v-118.8z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yibiaopan" unicode="&#58981;" d="M30.552 104.727c4.654-16.29 23.272-23.272 37.236-18.618 16.291 4.655 23.273 23.273 18.618 37.236C16.588 314.182 84.08 521.31 237.68 640c11.636 9.31 23.273 16.29 37.236 25.6 25.6 16.29 53.528 30.255 83.782 39.564 58.182 20.945 118.691 30.254 176.873 27.927h25.6c6.982 0 11.636 0 18.618-2.327 30.255-4.655 58.182-11.637 88.436-23.273 235.055-86.11 356.073-346.764 269.964-581.818-4.654-16.291 2.327-32.582 18.618-37.237 16.291-4.654 32.582 2.328 37.237 18.619 41.89 116.363 39.563 239.709 0 349.09h2.327C921.897 656.291 738.043 784.291 537.897 793.6h-48.873c-200.145-9.31-384-137.31-458.472-337.455-39.564-109.381-41.891-232.727 0-351.418z m707.49 386.328a29.498 29.498 0 0 1-41.89 0L521.606 316.509c-4.654 2.327-9.309 2.327-13.963 2.327-32.582 0-58.182-25.6-58.182-58.181s25.6-58.182 58.182-58.182 58.181 25.6 58.181 58.182c0 4.654 0 9.309-2.327 16.29l174.546 174.546c11.636 11.636 11.636 30.254 0 39.564z m228.073-458.473H58.48c-16.29 0-30.255-13.964-30.255-30.255 0-16.29 13.964-30.254 30.255-30.254h907.636c16.291 0 30.255 13.963 30.255 30.254 0 16.291-13.964 30.255-30.255 30.255z" horiz-adv-x="1024" /> + + + <glyph glyph-name="pindao" unicode="&#58963;" d="M432.022 818.946h-376.324c-6.627 0-12.078-5.45-12.078-12.078v-376.324c0-6.627 5.45-12.078 12.078-12.078h376.324c6.627 0 12.078 5.45 12.078 12.078v376.473c0 6.627-5.45 11.93-12.078 11.93zM391.517 471.196h-295.169v295.169h295.021v-295.169zM976.847 635.717l-211.95 211.95c-8.837 8.837-23.124 8.837-31.963 0l-211.95-211.95c-8.837-8.837-8.837-23.124 0-31.963l211.95-212.098c8.837-8.837 23.124-8.837 31.963 0l211.95 211.95c8.837 8.987 8.837 23.271 0 32.109zM432.022 313.45h-376.324c-6.627 0-12.078-5.45-12.078-12.078v-376.324c0-6.627 5.45-12.078 12.078-12.078h376.324c6.627 0 12.078 5.45 12.078 12.078v376.473c0 6.627-5.45 11.93-12.078 11.93zM391.517-34.155h-295.169v295.021h295.021v-295.021zM932.511 313.45h-376.324c-6.627 0-12.078-5.45-12.078-12.078v-376.324c0-6.627 5.45-12.078 12.078-12.078h376.324c6.627 0 12.078 5.45 12.078 12.078v376.473c0 6.627-5.45 11.93-12.078 11.93zM891.859-34.155h-295.021v295.021h295.021v-295.021z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiayiye" unicode="&#58970;" d="M62.573 384.103l423.401 423.662c18.985 18.985 49.757 18.985 68.727 0 18.982-18.972 18.985-49.746 0-68.729l-355.058-355.067 356.796-356.796c18.977-18.971 18.976-49.746 0-68.727-18.982-18.976-49.751-18.976-68.727 0l-39.753 39.753 0.269 0.246-385.655 385.661zM451.365 384.103l423.407 423.662c18.985 18.985 49.757 18.985 68.727 0 18.982-18.972 18.985-49.746 0-68.729l-355.058-355.067 356.796-356.796c18.977-18.971 18.976-49.746 0-68.727-18.982-18.976-49.757-18.977-68.727 0l-39.762 39.754 0.273 0.249-385.662 385.661zM451.365 384.103z" horiz-adv-x="1024" /> + + + <glyph glyph-name="huaban" unicode="&#59310;" d="M777.073418 147.443038c-30.460759 21.387342-40.83038 40.182278-76.47595 53.792405 25.275949 60.273418 40.182278 83.605063 42.126583 154.896203H887.898734c-3.888608-99.159494-45.367089-143.878481-110.825316-208.688608zM136.101266 356.131646h167.210126c1.944304-71.291139 16.850633-94.622785 42.126583-154.896203-34.997468-13.610127-68.050633-31.756962-98.511393-53.792405C181.468354 212.253165 139.989873 256.972152 136.101266 356.131646z m103.048101 259.888607c29.164557-23.979747 61.56962-42.774684 96.567089-57.681012-19.443038-53.792405-30.460759-90.734177-31.756962-152.951899H136.101266c3.240506 90.734177 46.663291 147.767089 103.048101 210.632911z m309.144304-209.98481V523.989873c47.311392 1.296203 71.291139 10.36962 114.065823 25.27595 18.146835-51.2 28.516456-84.901266 30.460759-143.23038H548.293671z m104.344304-195.078481c-40.182278 12.962025-60.273418 20.091139-104.344304 21.387342V356.131646h144.526582c-1.944304-68.050633-16.202532-88.141772-40.182278-145.174684z m36.941772-57.681013c31.756962-12.313924 39.534177-28.516456 66.75443-47.311392-51.848101-44.718987-114.713924-73.883544-182.116455-84.901266 36.941772 37.589873 90.734177 82.308861 115.362025 132.212658z m-163.321519-137.397468l22.035443 165.913924c40.182278-1.296203 56.38481-7.777215 92.678481-18.794937-27.220253-56.38481-66.106329-106.288608-113.417722-147.118987h-1.296202z m-75.827848 5.18481c-67.402532 11.017722-130.268354 40.83038-182.764557 84.901266 27.868354 19.443038 57.681013 34.997468 88.789873 47.311392 23.331646-48.607595 55.088608-93.326582 93.974684-132.212658z m47.311392 335.068355v-123.787342c-44.070886-1.296203-64.162025-8.425316-104.344304-21.387342-23.979747 57.681013-38.237975 77.124051-40.182278 145.174684h144.526582zM383.675949 549.265823c42.774684-14.906329 66.75443-23.331646 114.065823-25.27595v-117.95443H353.21519c1.944304 58.329114 12.313924 92.03038 30.460759 143.23038z m-37.589873 57.032911c-31.756962 12.962025-60.921519 30.460759-88.141772 51.848101 53.792405 51.848101 115.362025 91.382278 192.486076 104.344304-44.718987-44.718987-80.364557-97.863291-104.344304-156.192405z m151.655696 161.377215v-193.782278c-44.070886 1.296203-64.162025 9.073418-103.696202 22.683544 29.164557 68.698734 49.903797 127.027848 102.4 171.098734h1.296202z m75.827848-4.536708c77.772152-13.610127 149.711392-49.903797 206.744304-104.344304-29.164557-22.035443-46.01519-37.589873-80.364557-51.848102-25.275949 59.625316-82.956962 112.76962-126.379747 156.192406z m-46.01519 4.536708c54.440506-46.01519 97.21519-104.992405 124.435443-171.098734-39.534177-13.610127-59.625316-21.387342-103.696202-22.683544l-22.035443 193.782278h1.296202z m-31.10886-751.149367c-46.663291 38.886076-62.865823 88.789873-91.382279 147.118988 36.293671 11.665823 53.144304 17.498734 93.326582 18.794936v-165.913924h-1.944303zM887.898734 406.035443h-145.174683c-1.296203 61.56962-12.313924 98.511392-31.756962 152.303798 37.589873 15.55443 57.032911 33.053165 88.789873 57.681012 56.38481-62.865823 84.901266-119.898734 88.141772-209.98481z m-375.898734 427.746835c-244.334177 0-442.005063-197.670886-442.005063-442.005063S267.665823-50.227848 512-50.227848s442.005063 197.670886 442.005063 442.005063S756.334177 833.782278 512 833.782278z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiayiye1" unicode="&#58971;" d="M948.066926 382.958838l-411.990051-412.24426c-18.47333-18.47333-48.417689-18.47333-66.875207 0-18.47333 18.461167-18.47333 48.405526 0 66.875207L814.691135 383.088983 467.512212 730.269123c-18.466032 18.458735-18.466032 48.405526 0 66.873991 18.468465 18.464816 48.410391 18.464816 66.872774 0l38.682336-38.682336-0.261507-0.239614 375.259894-375.265975v0.003649m-378.312834 0L157.756743-29.285422c-18.47333-18.47333-48.415256-18.47333-66.872775 0-18.47333 18.461167-18.47333 48.405526 0 66.875207L436.369787 383.088983 89.19208 730.269123c-18.4636 18.458735-18.4636 48.405526 0 66.873991 18.470898 18.464816 48.415256 18.464816 66.872774 0l38.692067-38.682336-0.266372-0.239614 375.267191-375.265975-0.004865 0.003649m0 0z" horiz-adv-x="1024" /> + + + <glyph glyph-name="yingyong" unicode="&#59479;" d="M917.376 652.544L500.8 891.2a34.304 34.304 0 0 1-34.176 0L50.112 652.48a33.92 33.92 0 0 1-17.088-29.376v-477.44c0-12.16 6.528-23.296 17.088-29.44l416.512-238.72a35.136 35.136 0 0 1 34.176 0l416.576 238.72a33.92 33.92 0 0 1 17.088 29.44v477.44a33.92 33.92 0 0 1-17.088 29.44z m-51.264-487.36l-382.4-219.136-382.336 219.136V603.52l382.336 219.136 382.4-219.136v-438.272zM198.784 535.488a33.792 33.792 0 0 1 12.544-46.4l237.824-136.32V83.2c0-18.816 15.232-33.92 34.176-33.92a33.92 33.92 0 0 1 34.176 33.92V352.384l238.656 136.832a33.856 33.856 0 0 1 12.544 46.4 34.368 34.368 0 0 1-46.72 12.416L483.712 411.52 245.504 548.032a34.432 34.432 0 0 1-46.72-12.544z" horiz-adv-x="1024" /> + + + <glyph glyph-name="more" unicode="&#58975;" d="M224 288c-52.928 0-96 43.072-96 96s43.072 96 96 96 96-43.072 96-96-43.072-96-96-96z m288 0c-52.928 0-96 43.072-96 96s43.072 96 96 96 96-43.072 96-96-43.072-96-96-96z m288 0c-52.928 0-96 43.072-96 96s43.072 96 96 96 96-43.072 96-96-43.072-96-96-96z" horiz-adv-x="1024" /> + + + <glyph glyph-name="xiangji" unicode="&#58976;" d="M884.3 648.6H704.2L679.5 698l-0.2 0.4c-1.9 3.6-3.6 6.9-5.1 9.9-12 23.4-21.5 41.9-54.1 41.9H416.7c-32.9 0-43.7-21.3-55.1-43.8-1.3-2.6-2.7-5.3-4.2-8.1l-24.8-49.7H152.4c-34 0-61.7-27.7-61.7-61.7v-488c0-34 27.7-61.7 61.7-61.7h731.9c34 0 61.7 27.7 61.7 61.7v488c0 34-27.7 61.7-61.7 61.7zM904 98.9c0-10.8-8.8-19.7-19.7-19.7H152.4c-10.8 0-19.7 8.8-19.7 19.7v488c0 10.8 8.8 19.7 19.7 19.7h206.1l36.2 72.5c1.5 2.9 2.9 5.7 4.3 8.3 10.6 20.8 11.1 20.8 17.7 20.8H620c4.6 0 5.8-0.6 5.8-0.6 2-1.2 7.2-11.2 10.9-18.5 1.6-3.1 3.3-6.5 5.3-10.1l36.2-72.4h206.1c10.8 0 19.7-8.8 19.7-19.7v-488zM525.5 565.5c-123.5 0-223.6-100.1-223.6-223.6S402 118.2 525.5 118.2s223.7 100.1 223.7 223.7c0 123.5-100.2 223.6-223.7 223.6z m0-402.5c-98.8 0-178.9 80.1-178.9 178.9 0 98.8 80.1 178.9 178.9 178.9 98.8 0 178.9-80.1 178.9-178.9 0-98.8-80.1-178.9-178.9-178.9z m246 402.5v-44.7H861v44.7h-89.5z" horiz-adv-x="1024" /> + + + <glyph glyph-name="refresh" unicode="&#58985;" d="M928 810.666667c-18.133333 0-32-13.866667-32-32v-164.266667C816 747.733333 669.866667 832 512 832 264.533333 832 64 631.4666669999999 64 384s200.533333-448 448-448c230.4 0 422.4 172.8 445.866667 402.133333 2.133333 17.066667-10.666667 33.066667-28.8 35.2-17.066667 2.133333-33.066667-10.666667-35.2-28.8C873.6 148.26666699999998 709.333333 0 512 0c-212.266667 0-384 171.733333-384 384s171.733333 384 384 384c137.6 0 264.533333-74.666667 332.8-192H693.333333c-18.133333 0-32-13.866667-32-32s13.866667-32 32-32h266.666667V778.666667c0 18.133333-14.933333 32-32 32z" horiz-adv-x="1024" /> + + + <glyph glyph-name="nv" unicode="&#58977;" d="M774.4 800c-48 35.2-108.8 51.2-172.8 51.2-105.6 0-208-51.2-268.8-150.4-89.6-134.4-57.6-313.6 60.8-416l-32-51.2-188.8 121.6S128 384 108.8 352c-22.4-35.2 22.4-64 22.4-64l188.8-121.6-105.6-163.2s-19.2-32 16-51.2c38.4-22.4 57.6 12.8 57.6 12.8l102.4 160 185.6-121.6s48-28.8 70.4 6.4c19.2 28.8-25.6 57.6-25.6 57.6L432 192l32 48c44.8-22.4 92.8-32 137.6-32 105.6 0 208 51.2 268.8 150.4 96 147.2 51.2 345.6-96 441.6z m35.2-400c-44.8-67.2-118.4-108.8-201.6-108.8-44.8 0-92.8 12.8-131.2 38.4-112 73.6-147.2 220.8-73.6 332.8 44.8 64 121.6 105.6 201.6 108.8 44.8 0 92.8-12.8 131.2-38.4 112-73.6 147.2-220.8 73.6-332.8z" horiz-adv-x="1024" /> + + + <glyph glyph-name="nan" unicode="&#58978;" d="M889.6 800h-240s-35.2 0-38.4-41.6c0-19.2 16-38.4 38.4-38.4h140.8l-179.2-179.2C556.8 582.4 489.6 608 416 608 240 608 96 464 96 288s144-320 320-320 320 144 320 320c0 73.6-25.6 140.8-67.2 195.2l179.2 179.2v-140.8c0-22.4 19.2-38.4 38.4-38.4 22.4 0 38.4 19.2 38.4 41.6V764.8h3.2C924.8 800 889.6 800 889.6 800zM416 48c-131.2 0-236.8 105.6-236.8 236.8 0 131.2 105.6 236.8 236.8 236.8s236.8-105.6 236.8-236.8c0-131.2-105.6-236.8-236.8-236.8z" horiz-adv-x="1024" /> + + + <glyph glyph-name="gaoji" unicode="&#58996;" d="M719.9 249.4L514.7 379.5V485.1C615.6 419 731.5 344 731.5 344s139.2-45.6 139.2 106.5c0 93-172.5 112.1-197.2 11.8l-69.6 47.3s24.2 101.5 162.4 106.5c138.2 4.9 192-94.6 190.9-199.6-1.2-104.7-136-198.3-237.3-167.1zM561 414c-4-19-23-33.7-47.6-33.7l-6.9 4.3-217.3 137.8S171 555.2 160.8 439c-10.2-116.1 147.4-129.5 186.8-23.8l81.7-47.6s-65.1-119.1-198.5-119.1C97.3 248.5 0.6 423.8 114 546.3c113.5 122.4 218.6 64.6 257 35.7 16.4-12.4 85.3-57.9 158.6-105.9l3.1-2.4c28.3-18.2 33.4-35.6 28.3-59.7zM434.1 149.7h212c16.7 0 30.3-13.6 30.3-30.3v-15.1c0-16.7-13.6-30.3-30.3-30.3h-212c-16.7 0-30.3 13.6-30.3 30.3v15.1c0 16.8 13.6 30.3 30.3 30.3z" horiz-adv-x="1024" /> + + + <glyph glyph-name="fengge" unicode="&#58986;" d="M512 800C229.696 800 0 570.304 0 288c0-90.368 30.304-174.496 85.344-236.896 55.264-62.624 129.152-97.12 208.128-97.12 81.568 0 161.536 36.832 231.264 106.592l2.272 2.496c65.792 81.472 132.896 121.056 205.088 121.056 46.72 0 89.216-15.872 126.688-29.92 30.336-11.328 56.576-21.12 81.216-21.12C1024 133.088 1024 241.664 1024 288c0 282.304-229.696 512-512 512z m428-602.912c-13.088 0-35.296 8.288-58.784 17.088-40.48 15.136-90.848 33.952-149.12 33.952-92.352 0-175.328-46.944-253.76-143.456-57.184-56.704-121.056-86.688-184.832-86.688-60.352 0-117.216 26.784-160.128 75.456C88.64 144.128 64 213.216 64 288 64 535.04 264.96 736 512 736s448-200.96 448-448c0-27.328-1.952-90.912-20-90.912zM800.704 379.936m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM457.024 582.624m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM672.704 555.936m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM291.392 443.936m-64 0a64 64 0 1 1 128 0 64 64 0 1 1-128 0ZM278.4 197.248m-96 0a96 96 0 1 1 192 0 96 96 0 1 1-192 0Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="cai" unicode="&#59077;" d="M860.8 172.79999999999995l6.4-57.6-6.4 57.6c12.8 0 25.6 3.2 35.2 12.8 6.4 9.6 6.4 22.4 3.2 32l57.6 12.8-57.6-12.8L800 553.6c-6.4 28.8-25.6 51.2-48 64-9.6 6.4-22.4 9.6-32 9.6H182.4c-22.4 3.2-41.6-6.4-51.2-25.6-6.4-9.6-6.4-19.2-9.6-28.8v-342.4c0-19.2 9.6-38.4 28.8-48 6.4-3.2 12.8-6.4 19.2-6.4h192l19.2-25.6 147.2-188.8c6.4-9.6 19.2-12.8 28.8-9.6 16 3.2 25.6 19.2 22.4 35.2l-9.6 118.4-6.4 67.2h297.6z m-233.6-57.6l9.6-128c3.2-28.8-9.6-54.4-28.8-73.6-35.2-32-92.8-28.8-124.8 6.4l-156.8 195.2H179.2c-19.2 0-38.4 6.4-57.6 16-35.2 19.2-57.6 57.6-57.6 99.2V572.8c0 19.2 6.4 38.4 16 57.6 19.2 38.4 57.6 60.8 99.2 54.4h537.6c67.2-3.2 121.6-48 137.6-112l102.4-339.2c6.4-28.8 3.2-57.6-12.8-80-19.2-22.4-48-38.4-76.8-38.4h-240zM304 627.2v-451.2h57.6V627.2H304z" horiz-adv-x="1024" /> + + + <glyph glyph-name="zan" unicode="&#59078;" d="M860.8 595.2h-297.6l6.4 67.2 9.6 118.4c3.2 16-6.4 32-22.4 35.2-9.6 3.2-22.4 0-28.8-9.6l-147.2-188.8-19.2-25.6h-192c-6.4 0-12.8-3.2-19.2-6.4-19.2-9.6-28.8-28.8-28.8-48v-342.4c0-9.6 3.2-22.4 9.6-28.8 9.6-19.2 28.8-28.8 48-25.6h537.6c12.8 0 22.4 3.2 32 9.6 25.6 12.8 44.8 35.2 48 64l102.4 336 57.6-12.8-57.6 12.8c3.2 9.6 0 22.4-3.2 32-9.6 6.4-22.4 12.8-35.2 12.8l6.4 57.6-6.4-57.6z m-233.6 57.6h240c28.8 0 57.6-12.8 76.8-38.4 16-22.4 19.2-54.4 12.8-80l-102.4-339.2c-16-64-70.4-108.8-137.6-112H179.2c-41.6-3.2-80 19.2-99.2 54.4-9.6 19.2-16 38.4-16 57.6V537.6c0 41.6 22.4 80 57.6 99.2 19.2 9.6 38.4 12.8 57.6 16h144L480 848c32 35.2 89.6 38.4 124.8 6.4 19.2-19.2 32-44.8 28.8-73.6l-6.4-128z m-323.2-512h57.6V592H304v-451.2z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shoucang" unicode="&#58968;" d="M752-43.2c-9.6 0-20.8 3.2-30.4 8l-208 104-209.6-104c-20.8-11.2-48-9.6-67.2 4.8-19.2 14.4-30.4 40-25.6 64l43.2 224L89.6 411.2C72 428.8 65.6 456 72 478.4c8 24 27.2 41.6 52.8 44.8l228.8 41.6 102.4 208c11.2 22.4 33.6 36.8 57.6 36.8s48-14.4 57.6-36.8l102.4-208 228.8-40c24-3.2 44.8-20.8 51.2-44.8 8-24 1.6-49.6-16-67.2L772.8 257.6l41.6-224c4.8-25.6-6.4-49.6-25.6-64-9.6-8-22.4-12.8-36.8-12.8z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shuaxin2" unicode="&#58987;" d="M854 560.7l-0.3-0.2c-5.6 9.3-15.9 15.6-27.6 15.6-17.8 0-32.2-14.4-32.2-32.1 0-5.3 1.3-10.3 3.6-14.7h-0.1c22-43.4 34.4-92.5 34.4-144.5C831.8 208.2 688.6 65 512 65S192.2 208.1 192.2 384.8c0 152.4 106.5 279.2 249.1 311.2l-33.6-43.7c-10.8-14-8.1-34.2 5.9-45 14-10.8 34.2-8.1 45 5.9l75.3 97.8c6.5 5.9 10.6 14.4 10.6 23.8 0 11.3-5.9 21.2-14.7 27L429.3 838.9c-13.8 10.6-33.8 8-44.4-5.7l-0.6-0.8c-10.6-13.8-8-33.7 5.8-44.3l38.4-29.5C257 720.1 128.9 566.9 128.9 383.8c0-212.1 172-384.1 384.1-384.1s384.1 172 384.1 384.1c0 63.8-15.5 124-43.1 176.9zM708.9 637.9a32.2 32.1 0 1 1 64.4 0 32.2 32.1 0 1 1-64.4 0Z" horiz-adv-x="1024" /> + + + <glyph glyph-name="moban1" unicode="&#58966;" d="M512 384zM43.52 601.6l409.6-176.64c58.88-30.72 110.08 0 110.08 0l414.72 174.08 2.56 2.56c10.24 5.12 15.36 15.36 15.36 28.16 0 15.36-10.24 28.16-23.04 30.72L563.2 837.12c-56.32 23.04-97.28 0-97.28 0L46.08 660.48c-12.8-5.12-20.48-17.92-20.48-30.72s7.68-23.04 17.92-28.16z m0 0M512 222.72c-2.56 0-7.68 0-10.24 2.56l-486.4 215.04c-12.8 5.12-17.92 20.48-12.8 33.28 5.12 12.8 20.48 17.92 33.28 12.8L512 276.48 988.16 486.4c12.8 5.12 28.16 0 33.28-12.8 5.12-12.8 0-28.16-12.8-33.28l-486.4-215.04c-2.56-2.56-7.68-2.56-10.24-2.56zM512 71.68c-2.56 0-7.68 0-10.24 2.56l-486.4 215.04c-12.8 5.12-17.92 20.48-12.8 33.28 5.12 10.24 20.48 17.92 33.28 10.24L512 125.44 988.16 332.8c12.8 5.12 28.16 0 33.28-12.8 5.12-12.8 0-28.16-12.8-33.28l-486.4-215.04H512zM512-79.36c-2.56 0-7.68 0-10.24 2.56l-486.4 215.04c-12.8 5.12-17.92 20.48-12.8 33.28 5.12 12.8 20.48 17.92 33.28 12.8L512-25.6l476.16 209.92c12.8 5.12 28.16 0 33.28-12.8 5.12-12.8 0-28.16-12.8-33.28l-486.4-215.04c-2.56-2.56-7.68-2.56-10.24-2.56z" horiz-adv-x="1024" /> + + + <glyph glyph-name="shuaxin3" unicode="&#58989;" d="M211.2 614.4c-115.2-153.6-102.4-364.8 32-505.6 140.8-140.8 352-147.2 505.6-32l70.4-70.4c-192-153.6-467.2-140.8-640 38.4-172.8 172.8-185.6 454.4-38.4 640l70.4-70.4zM896 83.2l-70.4 70.4c115.2 153.6 102.4 364.8-32 505.6-140.8 140.8-352 147.2-505.6 32L217.6 761.6c192 153.6 467.2 140.8 640-38.4 179.2-172.8 192-448 38.4-640z" horiz-adv-x="1024" /> + + + + + </font> +</defs></svg> diff --git a/static/plugins/layui/font/iconfont.ttf b/static/plugins/layui/font/iconfont.ttf new file mode 100755 index 0000000..3fae175 Binary files /dev/null and b/static/plugins/layui/font/iconfont.ttf differ diff --git a/static/plugins/layui/font/iconfont.woff b/static/plugins/layui/font/iconfont.woff new file mode 100755 index 0000000..3413cbc Binary files /dev/null and b/static/plugins/layui/font/iconfont.woff differ diff --git a/static/plugins/layui/images/face/0.gif b/static/plugins/layui/images/face/0.gif new file mode 100755 index 0000000..a63f0d5 Binary files /dev/null and b/static/plugins/layui/images/face/0.gif differ diff --git a/static/plugins/layui/images/face/1.gif b/static/plugins/layui/images/face/1.gif new file mode 100755 index 0000000..b2b78b2 Binary files /dev/null and b/static/plugins/layui/images/face/1.gif differ diff --git a/static/plugins/layui/images/face/10.gif b/static/plugins/layui/images/face/10.gif new file mode 100755 index 0000000..556c7e3 Binary files /dev/null and b/static/plugins/layui/images/face/10.gif differ diff --git a/static/plugins/layui/images/face/11.gif b/static/plugins/layui/images/face/11.gif new file mode 100755 index 0000000..2bfc58b Binary files /dev/null and b/static/plugins/layui/images/face/11.gif differ diff --git a/static/plugins/layui/images/face/12.gif b/static/plugins/layui/images/face/12.gif new file mode 100755 index 0000000..1c321c7 Binary files /dev/null and b/static/plugins/layui/images/face/12.gif differ diff --git a/static/plugins/layui/images/face/13.gif b/static/plugins/layui/images/face/13.gif new file mode 100755 index 0000000..300bbc2 Binary files /dev/null and b/static/plugins/layui/images/face/13.gif differ diff --git a/static/plugins/layui/images/face/14.gif b/static/plugins/layui/images/face/14.gif new file mode 100755 index 0000000..43b6d0a Binary files /dev/null and b/static/plugins/layui/images/face/14.gif differ diff --git a/static/plugins/layui/images/face/15.gif b/static/plugins/layui/images/face/15.gif new file mode 100755 index 0000000..c9f25fa Binary files /dev/null and b/static/plugins/layui/images/face/15.gif differ diff --git a/static/plugins/layui/images/face/16.gif b/static/plugins/layui/images/face/16.gif new file mode 100755 index 0000000..34f28e4 Binary files /dev/null and b/static/plugins/layui/images/face/16.gif differ diff --git a/static/plugins/layui/images/face/17.gif b/static/plugins/layui/images/face/17.gif new file mode 100755 index 0000000..39cd035 Binary files /dev/null and b/static/plugins/layui/images/face/17.gif differ diff --git a/static/plugins/layui/images/face/18.gif b/static/plugins/layui/images/face/18.gif new file mode 100755 index 0000000..7bce299 Binary files /dev/null and b/static/plugins/layui/images/face/18.gif differ diff --git a/static/plugins/layui/images/face/19.gif b/static/plugins/layui/images/face/19.gif new file mode 100755 index 0000000..adac542 Binary files /dev/null and b/static/plugins/layui/images/face/19.gif differ diff --git a/static/plugins/layui/images/face/2.gif b/static/plugins/layui/images/face/2.gif new file mode 100755 index 0000000..7edbb58 Binary files /dev/null and b/static/plugins/layui/images/face/2.gif differ diff --git a/static/plugins/layui/images/face/20.gif b/static/plugins/layui/images/face/20.gif new file mode 100755 index 0000000..50631a6 Binary files /dev/null and b/static/plugins/layui/images/face/20.gif differ diff --git a/static/plugins/layui/images/face/21.gif b/static/plugins/layui/images/face/21.gif new file mode 100755 index 0000000..b984212 Binary files /dev/null and b/static/plugins/layui/images/face/21.gif differ diff --git a/static/plugins/layui/images/face/22.gif b/static/plugins/layui/images/face/22.gif new file mode 100755 index 0000000..1f0bd8b Binary files /dev/null and b/static/plugins/layui/images/face/22.gif differ diff --git a/static/plugins/layui/images/face/23.gif b/static/plugins/layui/images/face/23.gif new file mode 100755 index 0000000..e05e0f9 Binary files /dev/null and b/static/plugins/layui/images/face/23.gif differ diff --git a/static/plugins/layui/images/face/24.gif b/static/plugins/layui/images/face/24.gif new file mode 100755 index 0000000..f35928a Binary files /dev/null and b/static/plugins/layui/images/face/24.gif differ diff --git a/static/plugins/layui/images/face/25.gif b/static/plugins/layui/images/face/25.gif new file mode 100755 index 0000000..0b4a883 Binary files /dev/null and b/static/plugins/layui/images/face/25.gif differ diff --git a/static/plugins/layui/images/face/26.gif b/static/plugins/layui/images/face/26.gif new file mode 100755 index 0000000..45c4fb5 Binary files /dev/null and b/static/plugins/layui/images/face/26.gif differ diff --git a/static/plugins/layui/images/face/27.gif b/static/plugins/layui/images/face/27.gif new file mode 100755 index 0000000..7a4c013 Binary files /dev/null and b/static/plugins/layui/images/face/27.gif differ diff --git a/static/plugins/layui/images/face/28.gif b/static/plugins/layui/images/face/28.gif new file mode 100755 index 0000000..fc5a0cf Binary files /dev/null and b/static/plugins/layui/images/face/28.gif differ diff --git a/static/plugins/layui/images/face/29.gif b/static/plugins/layui/images/face/29.gif new file mode 100755 index 0000000..5dd7442 Binary files /dev/null and b/static/plugins/layui/images/face/29.gif differ diff --git a/static/plugins/layui/images/face/3.gif b/static/plugins/layui/images/face/3.gif new file mode 100755 index 0000000..86df67b Binary files /dev/null and b/static/plugins/layui/images/face/3.gif differ diff --git a/static/plugins/layui/images/face/30.gif b/static/plugins/layui/images/face/30.gif new file mode 100755 index 0000000..b751f98 Binary files /dev/null and b/static/plugins/layui/images/face/30.gif differ diff --git a/static/plugins/layui/images/face/31.gif b/static/plugins/layui/images/face/31.gif new file mode 100755 index 0000000..c9476d7 Binary files /dev/null and b/static/plugins/layui/images/face/31.gif differ diff --git a/static/plugins/layui/images/face/32.gif b/static/plugins/layui/images/face/32.gif new file mode 100755 index 0000000..9931b06 Binary files /dev/null and b/static/plugins/layui/images/face/32.gif differ diff --git a/static/plugins/layui/images/face/33.gif b/static/plugins/layui/images/face/33.gif new file mode 100755 index 0000000..59111a3 Binary files /dev/null and b/static/plugins/layui/images/face/33.gif differ diff --git a/static/plugins/layui/images/face/34.gif b/static/plugins/layui/images/face/34.gif new file mode 100755 index 0000000..a334548 Binary files /dev/null and b/static/plugins/layui/images/face/34.gif differ diff --git a/static/plugins/layui/images/face/35.gif b/static/plugins/layui/images/face/35.gif new file mode 100755 index 0000000..a932264 Binary files /dev/null and b/static/plugins/layui/images/face/35.gif differ diff --git a/static/plugins/layui/images/face/36.gif b/static/plugins/layui/images/face/36.gif new file mode 100755 index 0000000..6de432a Binary files /dev/null and b/static/plugins/layui/images/face/36.gif differ diff --git a/static/plugins/layui/images/face/37.gif b/static/plugins/layui/images/face/37.gif new file mode 100755 index 0000000..d05f2da Binary files /dev/null and b/static/plugins/layui/images/face/37.gif differ diff --git a/static/plugins/layui/images/face/38.gif b/static/plugins/layui/images/face/38.gif new file mode 100755 index 0000000..8b1c88a Binary files /dev/null and b/static/plugins/layui/images/face/38.gif differ diff --git a/static/plugins/layui/images/face/39.gif b/static/plugins/layui/images/face/39.gif new file mode 100755 index 0000000..38b84a5 Binary files /dev/null and b/static/plugins/layui/images/face/39.gif differ diff --git a/static/plugins/layui/images/face/4.gif b/static/plugins/layui/images/face/4.gif new file mode 100755 index 0000000..d52200c Binary files /dev/null and b/static/plugins/layui/images/face/4.gif differ diff --git a/static/plugins/layui/images/face/40.gif b/static/plugins/layui/images/face/40.gif new file mode 100755 index 0000000..ae42991 Binary files /dev/null and b/static/plugins/layui/images/face/40.gif differ diff --git a/static/plugins/layui/images/face/41.gif b/static/plugins/layui/images/face/41.gif new file mode 100755 index 0000000..b9c715c Binary files /dev/null and b/static/plugins/layui/images/face/41.gif differ diff --git a/static/plugins/layui/images/face/42.gif b/static/plugins/layui/images/face/42.gif new file mode 100755 index 0000000..0eb1434 Binary files /dev/null and b/static/plugins/layui/images/face/42.gif differ diff --git a/static/plugins/layui/images/face/43.gif b/static/plugins/layui/images/face/43.gif new file mode 100755 index 0000000..ac0b700 Binary files /dev/null and b/static/plugins/layui/images/face/43.gif differ diff --git a/static/plugins/layui/images/face/44.gif b/static/plugins/layui/images/face/44.gif new file mode 100755 index 0000000..ad44497 Binary files /dev/null and b/static/plugins/layui/images/face/44.gif differ diff --git a/static/plugins/layui/images/face/45.gif b/static/plugins/layui/images/face/45.gif new file mode 100755 index 0000000..6837fca Binary files /dev/null and b/static/plugins/layui/images/face/45.gif differ diff --git a/static/plugins/layui/images/face/46.gif b/static/plugins/layui/images/face/46.gif new file mode 100755 index 0000000..d62916d Binary files /dev/null and b/static/plugins/layui/images/face/46.gif differ diff --git a/static/plugins/layui/images/face/47.gif b/static/plugins/layui/images/face/47.gif new file mode 100755 index 0000000..58a0836 Binary files /dev/null and b/static/plugins/layui/images/face/47.gif differ diff --git a/static/plugins/layui/images/face/48.gif b/static/plugins/layui/images/face/48.gif new file mode 100755 index 0000000..7ffd161 Binary files /dev/null and b/static/plugins/layui/images/face/48.gif differ diff --git a/static/plugins/layui/images/face/49.gif b/static/plugins/layui/images/face/49.gif new file mode 100755 index 0000000..959b992 Binary files /dev/null and b/static/plugins/layui/images/face/49.gif differ diff --git a/static/plugins/layui/images/face/5.gif b/static/plugins/layui/images/face/5.gif new file mode 100755 index 0000000..4e8b09f Binary files /dev/null and b/static/plugins/layui/images/face/5.gif differ diff --git a/static/plugins/layui/images/face/50.gif b/static/plugins/layui/images/face/50.gif new file mode 100755 index 0000000..6e22e7f Binary files /dev/null and b/static/plugins/layui/images/face/50.gif differ diff --git a/static/plugins/layui/images/face/51.gif b/static/plugins/layui/images/face/51.gif new file mode 100755 index 0000000..ad3f4d3 Binary files /dev/null and b/static/plugins/layui/images/face/51.gif differ diff --git a/static/plugins/layui/images/face/52.gif b/static/plugins/layui/images/face/52.gif new file mode 100755 index 0000000..39f8a22 Binary files /dev/null and b/static/plugins/layui/images/face/52.gif differ diff --git a/static/plugins/layui/images/face/53.gif b/static/plugins/layui/images/face/53.gif new file mode 100755 index 0000000..a181ee7 Binary files /dev/null and b/static/plugins/layui/images/face/53.gif differ diff --git a/static/plugins/layui/images/face/54.gif b/static/plugins/layui/images/face/54.gif new file mode 100755 index 0000000..e289d92 Binary files /dev/null and b/static/plugins/layui/images/face/54.gif differ diff --git a/static/plugins/layui/images/face/55.gif b/static/plugins/layui/images/face/55.gif new file mode 100755 index 0000000..4351083 Binary files /dev/null and b/static/plugins/layui/images/face/55.gif differ diff --git a/static/plugins/layui/images/face/56.gif b/static/plugins/layui/images/face/56.gif new file mode 100755 index 0000000..e0eff22 Binary files /dev/null and b/static/plugins/layui/images/face/56.gif differ diff --git a/static/plugins/layui/images/face/57.gif b/static/plugins/layui/images/face/57.gif new file mode 100755 index 0000000..0bf130f Binary files /dev/null and b/static/plugins/layui/images/face/57.gif differ diff --git a/static/plugins/layui/images/face/58.gif b/static/plugins/layui/images/face/58.gif new file mode 100755 index 0000000..0f06508 Binary files /dev/null and b/static/plugins/layui/images/face/58.gif differ diff --git a/static/plugins/layui/images/face/59.gif b/static/plugins/layui/images/face/59.gif new file mode 100755 index 0000000..7081e4f Binary files /dev/null and b/static/plugins/layui/images/face/59.gif differ diff --git a/static/plugins/layui/images/face/6.gif b/static/plugins/layui/images/face/6.gif new file mode 100755 index 0000000..f7715bf Binary files /dev/null and b/static/plugins/layui/images/face/6.gif differ diff --git a/static/plugins/layui/images/face/60.gif b/static/plugins/layui/images/face/60.gif new file mode 100755 index 0000000..6e15f89 Binary files /dev/null and b/static/plugins/layui/images/face/60.gif differ diff --git a/static/plugins/layui/images/face/61.gif b/static/plugins/layui/images/face/61.gif new file mode 100755 index 0000000..f092d7e Binary files /dev/null and b/static/plugins/layui/images/face/61.gif differ diff --git a/static/plugins/layui/images/face/62.gif b/static/plugins/layui/images/face/62.gif new file mode 100755 index 0000000..7fe4984 Binary files /dev/null and b/static/plugins/layui/images/face/62.gif differ diff --git a/static/plugins/layui/images/face/63.gif b/static/plugins/layui/images/face/63.gif new file mode 100755 index 0000000..cf8e23e Binary files /dev/null and b/static/plugins/layui/images/face/63.gif differ diff --git a/static/plugins/layui/images/face/64.gif b/static/plugins/layui/images/face/64.gif new file mode 100755 index 0000000..a779719 Binary files /dev/null and b/static/plugins/layui/images/face/64.gif differ diff --git a/static/plugins/layui/images/face/65.gif b/static/plugins/layui/images/face/65.gif new file mode 100755 index 0000000..7bb98f2 Binary files /dev/null and b/static/plugins/layui/images/face/65.gif differ diff --git a/static/plugins/layui/images/face/66.gif b/static/plugins/layui/images/face/66.gif new file mode 100755 index 0000000..bb6d077 Binary files /dev/null and b/static/plugins/layui/images/face/66.gif differ diff --git a/static/plugins/layui/images/face/67.gif b/static/plugins/layui/images/face/67.gif new file mode 100755 index 0000000..6e33f7c Binary files /dev/null and b/static/plugins/layui/images/face/67.gif differ diff --git a/static/plugins/layui/images/face/68.gif b/static/plugins/layui/images/face/68.gif new file mode 100755 index 0000000..1a6c400 Binary files /dev/null and b/static/plugins/layui/images/face/68.gif differ diff --git a/static/plugins/layui/images/face/69.gif b/static/plugins/layui/images/face/69.gif new file mode 100755 index 0000000..a02f0b2 Binary files /dev/null and b/static/plugins/layui/images/face/69.gif differ diff --git a/static/plugins/layui/images/face/7.gif b/static/plugins/layui/images/face/7.gif new file mode 100755 index 0000000..e6d4db8 Binary files /dev/null and b/static/plugins/layui/images/face/7.gif differ diff --git a/static/plugins/layui/images/face/70.gif b/static/plugins/layui/images/face/70.gif new file mode 100755 index 0000000..416c5c1 Binary files /dev/null and b/static/plugins/layui/images/face/70.gif differ diff --git a/static/plugins/layui/images/face/71.gif b/static/plugins/layui/images/face/71.gif new file mode 100755 index 0000000..c17d60c Binary files /dev/null and b/static/plugins/layui/images/face/71.gif differ diff --git a/static/plugins/layui/images/face/8.gif b/static/plugins/layui/images/face/8.gif new file mode 100755 index 0000000..66f967b Binary files /dev/null and b/static/plugins/layui/images/face/8.gif differ diff --git a/static/plugins/layui/images/face/9.gif b/static/plugins/layui/images/face/9.gif new file mode 100755 index 0000000..6044740 Binary files /dev/null and b/static/plugins/layui/images/face/9.gif differ diff --git a/static/plugins/layui/lay/modules/carousel.js b/static/plugins/layui/lay/modules/carousel.js new file mode 100755 index 0000000..dbf0a5b --- /dev/null +++ b/static/plugins/layui/lay/modules/carousel.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.indicator(),e.elemItem.length<=1||(e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class="layui-icon '+u+'" lay-type="sub">'+("updown"===n.anim?"&#xe619;":"&#xe603;")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"&#xe61a;":"&#xe602;")+"</button>"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class="'+c+'"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("<li"+(n.index===e?' class="layui-this"':"")+"></li>")}),i.join("")}(),"</ul></div>"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a<n.index&&e.slide("sub",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+" "+d+" "+s+" "+o+" "+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find("li").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,"change("+m+")",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data("haveEvents")||(i.elem.on("mouseenter",function(){clearInterval(e.timer)}).on("mouseleave",function(){e.autoplay()}),i.elem.data("haveEvents",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/code.js b/static/plugins/layui/lay/modules/code.js new file mode 100755 index 0000000..4547206 --- /dev/null +++ b/static/plugins/layui/lay/modules/code.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(e){"use strict";var a=layui.$,l="http://www.layui.com/doc/modules/code.html";e("code",function(e){var t=[];e=e||{},e.elem=a(e.elem||".layui-code"),e.about=!("about"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr("lay-encode")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")),c.html('<ol class="layui-code-ol"><li>'+o.replace(/[\r\t\n]+/g,"</li><li>")+"</li></ol>"),c.find(">.layui-code-h3")[0]||c.prepend('<h3 class="layui-code-h3">'+(c.attr("lay-title")||e.title||"code")+(e.about?'<a href="'+l+'" target="_blank">layui.code</a>':"")+"</h3>");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/element.js b/static/plugins/layui/lay/modules/element.js new file mode 100755 index 0000000..2ef314d --- /dev/null +++ b/static/plugins/layui/lay/modules/element.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(i){"use strict";var t=layui.$,a=(layui.hint(),layui.device()),e="element",l="layui-this",n="layui-show",s=function(){this.config={}};s.prototype.set=function(i){var a=this;return t.extend(!0,a.config,i),a},s.prototype.on=function(i,t){return layui.onevent.call(this,e,i,t)},s.prototype.tabAdd=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.children(".layui-tab-bar"),o=l.children(".layui-tab-content"),c='<li lay-id="'+(a.id||"")+'">'+(a.title||"unnaming")+"</li>";return s[0]?s.before(c):n.append(c),o.append('<div class="layui-tab-item">'+(a.content||"")+"</div>"),f.hideTabMore(!0),f.tabAuto(),this},s.prototype.tabDelete=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.find('>li[lay-id="'+a+'"]');return f.tabDelete(null,s),this},s.prototype.tabChange=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.find('>li[lay-id="'+a+'"]');return f.tabClick(null,null,s),this},s.prototype.tab=function(i){i=i||{},b.on("click",i.headerElem,function(a){var e=t(this).index();f.tabClick.call(this,a,e,null,i)})},s.prototype.progress=function(i,a){var e="layui-progress",l=t("."+e+"[lay-filter="+i+"]"),n=l.find("."+e+"-bar"),s=n.find("."+e+"-text");return n.css("width",a),s.text(a),this};var o=".layui-nav",c="layui-nav-item",r="layui-nav-bar",u="layui-nav-tree",d="layui-nav-child",h="layui-nav-more",y="layui-anim layui-anim-upbit",f={tabClick:function(i,a,s,o){o=o||{};var c=s||t(this),a=a||c.parent().children("li").index(c),r=o.headerElem?c.parent():c.parents(".layui-tab").eq(0),u=o.bodyElem?t(o.bodyElem):r.children(".layui-tab-content").children(".layui-tab-item"),d=c.find("a"),h=r.attr("lay-filter");"javascript:;"!==d.attr("href")&&"_blank"===d.attr("target")||(c.addClass(l).siblings().removeClass(l),u.eq(a).addClass(n).siblings().removeClass(n)),layui.event.call(this,e,"tab("+h+")",{elem:r,index:a})},tabDelete:function(i,a){var n=a||t(this).parent(),s=n.index(),o=n.parents(".layui-tab").eq(0),c=o.children(".layui-tab-content").children(".layui-tab-item"),r=o.attr("lay-filter");n.hasClass(l)&&(n.next()[0]?f.tabClick.call(n.next()[0],null,s+1):n.prev()[0]&&f.tabClick.call(n.prev()[0],null,s-1)),n.remove(),c.eq(s).remove(),setTimeout(function(){f.tabAuto()},50),layui.event.call(this,e,"tabDelete("+r+")",{elem:o,index:s})},tabAuto:function(){var i="layui-tab-more",e="layui-tab-bar",l="layui-tab-close",n=this;t(".layui-tab").each(function(){var s=t(this),o=s.children(".layui-tab-title"),c=(s.children(".layui-tab-content").children(".layui-tab-item"),'lay-stope="tabmore"'),r=t('<span class="layui-unselect layui-tab-bar" '+c+"><i "+c+' class="layui-icon">&#xe61a;</i></span>');if(n===window&&8!=a.ie&&f.hideTabMore(!0),s.attr("lay-allowClose")&&o.find("li").each(function(){var i=t(this);if(!i.find("."+l)[0]){var a=t('<i class="layui-icon layui-unselect '+l+'">&#x1006;</i>');a.on("click",f.tabDelete),i.append(a)}}),o.prop("scrollWidth")>o.outerWidth()+1){if(o.find("."+e)[0])return;o.append(r),s.attr("overflow",""),r.on("click",function(t){o[this.title?"removeClass":"addClass"](i),this.title=this.title?"":"收缩"})}else o.find("."+e).remove(),s.removeAttr("overflow")})},hideTabMore:function(i){var a=t(".layui-tab-title");i!==!0&&"tabmore"===t(i.target).attr("lay-stope")||(a.removeClass("layui-tab-more"),a.find(".layui-tab-bar").attr("title",""))},clickThis:function(){var i=t(this),a=i.parents(o),n=a.attr("lay-filter"),s=i.find("a"),c="string"==typeof i.attr("lay-unselect");i.find("."+d)[0]||("javascript:;"!==s.attr("href")&&"_blank"===s.attr("target")||c||(a.find("."+l).removeClass(l),i.addClass(l)),layui.event.call(this,e,"nav("+n+")",i))},clickChild:function(){var i=t(this),a=i.parents(o),n=a.attr("lay-filter");a.find("."+l).removeClass(l),i.addClass(l),layui.event.call(this,e,"nav("+n+")",i)},showChild:function(){var i=t(this),a=i.parents(o),e=i.parent(),l=i.siblings("."+d);a.hasClass(u)&&(l.removeClass(y),e["none"===l.css("display")?"addClass":"removeClass"](c+"ed"))},collapse:function(){var i=t(this),a=i.find(".layui-colla-icon"),l=i.siblings(".layui-colla-content"),s=i.parents(".layui-collapse").eq(0),o=s.attr("lay-filter"),c="none"===l.css("display");if("string"==typeof s.attr("lay-accordion")){var r=s.children(".layui-colla-item").children("."+n);r.siblings(".layui-colla-title").children(".layui-colla-icon").html("&#xe602;"),r.removeClass(n)}l[c?"addClass":"removeClass"](n),a.html(c?"&#xe61a;":"&#xe602;"),layui.event.call(this,e,"collapse("+o+")",{title:i,content:l,show:c})}};s.prototype.init=function(i,e){var l=function(){return e?'[lay-filter="'+e+'"]':""}(),s={tab:function(){f.tabAuto.call({})},nav:function(){var i=200,e={},s={},p={},b=function(l,o,c){var r=t(this),f=r.find("."+d);o.hasClass(u)?l.css({top:r.position().top,height:r.children("a").height(),opacity:1}):(f.addClass(y),l.css({left:r.position().left+parseFloat(r.css("marginLeft")),top:r.position().top+r.height()-l.height()}),e[c]=setTimeout(function(){l.css({width:r.width(),opacity:1})},a.ie&&a.ie<10?0:i),clearTimeout(p[c]),"block"===f.css("display")&&clearTimeout(s[c]),s[c]=setTimeout(function(){f.addClass(n),r.find("."+h).addClass(h+"d")},300))};t(o+l).each(function(a){var l=t(this),o=t('<span class="'+r+'"></span>'),y=l.find("."+c);l.find("."+r)[0]||(l.append(o),y.on("mouseenter",function(){b.call(this,o,l,a)}).on("mouseleave",function(){l.hasClass(u)||(clearTimeout(s[a]),s[a]=setTimeout(function(){l.find("."+d).removeClass(n),l.find("."+h).removeClass(h+"d")},300))}),l.on("mouseleave",function(){clearTimeout(e[a]),p[a]=setTimeout(function(){l.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},i)})),y.each(function(){var i=t(this),a=i.find("."+d);if(a[0]&&!i.find("."+h)[0]){var e=i.children("a");e.append('<span class="'+h+'"></span>')}i.off("click",f.clickThis).on("click",f.clickThis),i.children("a").off("click",f.showChild).on("click",f.showChild),a.children("dd").off("click",f.clickChild).on("click",f.clickChild)})})},breadcrumb:function(){var i=".layui-breadcrumb";t(i+l).each(function(){var i=t(this),a=i.attr("lay-separator")||">",e=i.find("a");e.find(".layui-box")[0]||(e.each(function(i){i!==e.length-1&&t(this).append('<span class="layui-box">'+a+"</span>")}),i.css("visibility","visible"))})},progress:function(){var i="layui-progress";t("."+i+l).each(function(){var a=t(this),e=a.find(".layui-progress-bar"),l=e.attr("lay-percent");e.css("width",function(){return/^.+\/.+$/.test(l)?100*new Function("return "+l)()+"%":l}()),a.attr("lay-showPercent")&&setTimeout(function(){e.html('<span class="'+i+'-text">'+l+"</span>")},350)})},collapse:function(){var i="layui-collapse";t("."+i+l).each(function(){var i=t(this).find(".layui-colla-item");i.each(function(){var i=t(this),a=i.find(".layui-colla-title"),e=i.find(".layui-colla-content"),l="none"===e.css("display");a.find(".layui-colla-icon").remove(),a.append('<i class="layui-icon layui-colla-icon">'+(l?"&#xe602;":"&#xe61a;")+"</i>"),a.off("click",f.collapse).on("click",f.collapse)})})}};return s[i]?s[i]():layui.each(s,function(i,t){t()})},s.prototype.render=s.prototype.init;var p=new s,b=t(document);p.render();var v=".layui-tab-title li";b.on("click",v,f.tabClick),b.on("click",f.hideTabMore),t(window).on("resize",f.tabAuto),i(e,p)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/flow.js b/static/plugins/layui/lay/modules/flow.js new file mode 100755 index 0000000..acf58c4 --- /dev/null +++ b/static/plugins/layui/lay/modules/flow.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon ">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="<cite>加载更多</cite>",h=l('<div class="layui-flow-more"><a href="javascript:;">'+d+"</a></div>");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/form.js b/static/plugins/layui/lay/modules/form.js new file mode 100755 index 0000000..2e1a954 --- /dev/null +++ b/static/plugins/layui/lay/modules/form.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("layer",function(e){"use strict";var i=layui.$,t=layui.layer,a=layui.hint(),n=layui.device(),l="form",s=".layui-form",r="layui-this",u="layui-hide",c="layui-disabled",o=function(){this.config={verify:{required:[/[\S]+/,"必填项不能为空"],phone:[/^1\d{10}$/,"请输入正确的手机号"],email:[/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,"邮箱格式不正确"],url:[/(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/,"链接格式不正确"],number:function(e){if(!e||isNaN(e))return"只能填写数字"},date:[/^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/,"日期格式不正确"],identity:[/(^\d{15}$)|(^\d{17}(x|X|\d)$)/,"请输入正确的身份证号"]}}};o.prototype.set=function(e){var t=this;return i.extend(!0,t.config,e),t},o.prototype.verify=function(e){var t=this;return i.extend(!0,t.config.verify,e),t},o.prototype.on=function(e,i){return layui.onevent.call(this,l,e,i)},o.prototype.render=function(e,t){var n=this,o=i(s+function(){return t?'[lay-filter="'+t+'"]':""}()),d={select:function(){var e,t="请选择",a="layui-form-select",n="layui-select-title",s="layui-select-none",d="",f=o.find("select"),y=function(t,l){i(t.target).parent().hasClass(n)&&!l||(i("."+a).removeClass(a+"ed "+a+"up"),e&&d&&e.val(d)),e=null},h=function(t,o,f){var h=i(this),p=t.find("."+n),m=p.find("input"),k=t.find("dl"),g=k.children("dd");if(!o){var b=function(){var e=t.offset().top+t.outerHeight()+5-v.scrollTop(),i=k.outerHeight();t.addClass(a+"ed"),g.removeClass(u),e+i>v.height()&&e>=i&&t.addClass(a+"up")},x=function(e){t.removeClass(a+"ed "+a+"up"),m.blur(),e||C(m.val(),function(e){e&&(d=k.find("."+r).html(),m&&m.val(d))})};p.on("click",function(e){t.hasClass(a+"ed")?x():(y(e,!0),b()),k.find("."+s).remove()}),p.find(".layui-edge").on("click",function(){m.focus()}),m.on("keyup",function(e){var i=e.keyCode;9===i&&b()}).on("keydown",function(e){var i=e.keyCode;9===i?x():13===i&&e.preventDefault()});var C=function(e,t,a){var n=0;layui.each(g,function(){var t=i(this),l=t.text(),s=l.indexOf(e)===-1;(""===e||"blur"===a?e!==l:s)&&n++,"keyup"===a&&t[s?"addClass":"removeClass"](u)});var l=n===g.length;return t(l),l},w=function(e){var i=this.value,t=e.keyCode;return 9!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&(C(i,function(e){e?k.find("."+s)[0]||k.append('<p class="'+s+'">无匹配项</p>'):k.find("."+s).remove()},"keyup"),void(""===i&&k.find("."+s).remove()))};f&&m.on("keyup",w).on("blur",function(i){e=m,d=k.find("."+r).html(),setTimeout(function(){C(m.val(),function(e){e&&!d&&m.val("")},"blur")},200)}),g.on("click",function(){var e=i(this),a=e.attr("lay-value"),n=h.attr("lay-filter");return!e.hasClass(c)&&(e.hasClass("layui-select-tips")?m.val(""):(m.val(e.text()),e.addClass(r)),e.siblings().removeClass(r),h.val(a).removeClass("layui-form-danger"),layui.event.call(this,l,"select("+n+")",{elem:h[0],value:a,othis:t}),x(!0),!1)}),t.find("dl>dt").on("click",function(e){return!1}),i(document).off("click",y).on("click",y)}};f.each(function(e,l){var s=i(this),u=s.next("."+a),o=this.disabled,d=l.value,f=i(l.options[l.selectedIndex]),y=l.options[0];if("string"==typeof s.attr("lay-ignore"))return s.show();var v="string"==typeof s.attr("lay-search"),p=y?y.value?t:y.innerHTML||t:t,m=i(['<div class="'+(v?"":"layui-unselect ")+a+(o?" layui-select-disabled":"")+'">','<div class="'+n+'"><input type="text" placeholder="'+p+'" value="'+(d?f.html():"")+'" '+(v?"":"readonly")+' class="layui-input'+(v?"":" layui-unselect")+(o?" "+c:"")+'">','<i class="layui-edge"></i></div>','<dl class="layui-anim layui-anim-upbit'+(s.find("optgroup")[0]?" layui-select-group":"")+'">'+function(e){var i=[];return layui.each(e,function(e,a){0!==e||a.value?"optgroup"===a.tagName.toLowerCase()?i.push("<dt>"+a.label+"</dt>"):i.push('<dd lay-value="'+a.value+'" class="'+(d===a.value?r:"")+(a.disabled?" "+c:"")+'">'+a.innerHTML+"</dd>"):i.push('<dd lay-value="" class="layui-select-tips">'+(a.innerHTML||t)+"</dd>")}),0===i.length&&i.push('<dd lay-value="" class="'+c+'">没有选项</dd>'),i.join("")}(s.find("*"))+"</dl>","</div>"].join(""));u[0]&&u.remove(),s.after(m),h.call(this,m,o,v)})},checkbox:function(){var e={checkbox:["layui-form-checkbox","layui-form-checked","checkbox"],_switch:["layui-form-switch","layui-form-onswitch","switch"]},t=o.find("input[type=checkbox]"),a=function(e,t){var a=i(this);e.on("click",function(){var i=a.attr("lay-filter"),n=(a.attr("lay-text")||"").split("|");a[0].disabled||(a[0].checked?(a[0].checked=!1,e.removeClass(t[1]).find("em").text(n[1])):(a[0].checked=!0,e.addClass(t[1]).find("em").text(n[0])),layui.event.call(a[0],l,t[2]+"("+i+")",{elem:a[0],value:a[0].value,othis:e}))})};t.each(function(t,n){var l=i(this),s=l.attr("lay-skin"),r=(l.attr("lay-text")||"").split("|"),u=this.disabled;"switch"===s&&(s="_"+s);var o=e[s]||e.checkbox;if("string"==typeof l.attr("lay-ignore"))return l.show();var d=l.next("."+o[0]),f=i(['<div class="layui-unselect '+o[0]+(n.checked?" "+o[1]:"")+(u?" layui-checkbox-disbaled "+c:"")+'" lay-skin="'+(s||"")+'">',{_switch:"<em>"+((n.checked?r[0]:r[1])||"")+"</em><i></i>"}[s]||(n.title.replace(/\s/g,"")?"<span>"+n.title+"</span>":"")+'<i class="layui-icon">'+(s?"&#xe605;":"&#xe618;")+"</i>","</div>"].join(""));d[0]&&d.remove(),l.after(f),a.call(this,f,o)})},radio:function(){var e="layui-form-radio",t=["&#xe643;","&#xe63f;"],a=o.find("input[type=radio]"),n=function(a){var n=i(this),r="layui-anim-scaleSpring";a.on("click",function(){var u=n[0].name,c=n.parents(s),o=n.attr("lay-filter"),d=c.find("input[name="+u.replace(/(\.|#|\[|\])/g,"\\$1")+"]");n[0].disabled||(layui.each(d,function(){var a=i(this).next("."+e);this.checked=!1,a.removeClass(e+"ed"),a.find(".layui-icon").removeClass(r).html(t[1])}),n[0].checked=!0,a.addClass(e+"ed"),a.find(".layui-icon").addClass(r).html(t[0]),layui.event.call(n[0],l,"radio("+o+")",{elem:n[0],value:n[0].value,othis:a}))})};a.each(function(a,l){var s=i(this),r=s.next("."+e),u=this.disabled;if("string"==typeof s.attr("lay-ignore"))return s.show();var o=i(['<div class="layui-unselect '+e+(l.checked?" "+e+"ed":"")+(u?" layui-radio-disbaled "+c:"")+'">','<i class="layui-anim layui-icon">'+t[l.checked?0:1]+"</i>","<span>"+(l.title||"未命名")+"</span>","</div>"].join(""));r[0]&&r.remove(),s.after(o),n.call(this,o)})}};return e?d[e]?d[e]():a.error("不支持的"+e+"表单渲染"):layui.each(d,function(e,i){i()}),n};var d=function(){var e=i(this),a=f.config.verify,r=null,u="layui-form-danger",c={},o=e.parents(s),d=o.find("*[lay-verify]"),y=e.parents("form")[0],v=o.find("input,select,textarea"),h=e.attr("lay-filter");return layui.each(d,function(e,l){var s=i(this),c=s.attr("lay-verify").split("|"),o="",d=s.val();if(s.removeClass(u),layui.each(c,function(e,i){var c="function"==typeof a[i];if(a[i]&&(c?o=a[i](d,l):!a[i][0].test(d)))return t.msg(o||a[i][1],{icon:5,shift:6}),n.android||n.ios||l.focus(),s.addClass(u),r=!0}),r)return r}),!r&&(layui.each(v,function(e,i){i.name&&(/^checkbox|radio$/.test(i.type)&&!i.checked||(c[i.name]=i.value))}),layui.event.call(this,l,"submit("+h+")",{elem:this,form:y,field:c}))},f=new o,y=i(document),v=i(window);f.render(),y.on("reset",s,function(){var e=i(this).attr("lay-filter");setTimeout(function(){f.render(null,e)},50)}),y.on("submit",s,d).on("click","*[lay-submit]",d),e(l,f)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/jquery.js b/static/plugins/layui/lay/modules/jquery.js new file mode 100755 index 0000000..d2d95aa --- /dev/null +++ b/static/plugins/layui/lay/modules/jquery.js @@ -0,0 +1,5 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=pe.type(e);return"function"!==n&&!pe.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s)):(re.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(re.addEventListener||"load"===e.event.type||"complete"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(_e,"-$1").toLowerCase();if(n=e.getAttribute(r),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if(("data"!==t||!pe.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||"string"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),"object"!=typeof t&&"function"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),"string"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,"")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?"":"px"),c=(pe.cssNumber[t]||"px"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||".5",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,"globalEval",!t||pe._data(t[r],"globalEval"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if("object"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement("div")),l=(We.exec(a)||["",""])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a="table"!==l||Ve.test(a)?"<table>"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],"tbody")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent="";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,"input"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),"script"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||"")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,"table")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function C(e){return e.type=(null!==pe.find.attr(e,"type"))+"/"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}"script"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&"string"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,"script"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,"script"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||"")&&!pe._data(o,"globalEval")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||"").replace(ot,"")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,"script")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],"display");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),"none"!==n&&n||(ut=(ut||pe("<iframe frameborder='0' width='0' height='0'/>")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&Re(r)&&(o[a]=pe._data(r,"olddisplay",j(r.nodeName)))):(i=Re(r),(n&&"none"!==n||!i)&&pe._data(r,"olddisplay",i?n:pe.css(r,"display"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function F(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;o<4;o+=2)"margin"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?("content"===n&&(a-=pe.css(e,"padding"+Oe[o],!0,i)),"margin"!==n&&(a-=pe.css(e,"border"+Oe[o]+"Width",!0,i))):(a+=pe.css(e,"padding"+Oe[o],!0,i),"padding"!==n&&(a+=pe.css(e,"border"+Oe[o]+"Width",!0,i)));return a}function M(t,n,r){var i=!0,o="width"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&"border-box"===pe.css(t,"boxSizing",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?"border":"content"),i,a)+"px"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,"fxshow");n.queue||(s=pe._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,"display"),c="none"===l?pe._data(e,"olddisplay")||j(e.nodeName):l,"inline"===c&&"none"===pe.css(e,"float")&&(fe.inlineBlockNeedsLayout&&"inline"!==j(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(h?"hide":"show")){if("show"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))"inline"===("none"===l?j(e.nodeName):l)&&(p.display=l);else{g?"hidden"in g&&(h=g.hidden):g=pe._data(e,"fxshow",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,"fxshow");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,"class")||""}function X(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)"+"===r.charAt(0)?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o["*"]&&i("*")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader("Content-Type"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+" "+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(a=l[u+" "+o]||l["* "+o],!a)for(i in l)if(s=i.split(" "),s[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(f){return{state:"parsererror",error:a?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,"display")}function K(e){for(;e&&1===e.nodeType;){if("none"===G(e)||"hidden"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==pe.type(t))r(e,t);else for(i in t)Q(e+"["+i+"]",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de="1.12.3",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,ge=/^-ms-/,me=/-([\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:"",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:"jQuery"+(de+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return"function"===pe.type(e)},isArray:Array.isArray||function(e){return"array"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||"object"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,"constructor")&&!ce.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?ue[le.call(e)]||"object":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,"ms-").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?"":(e+"").replace(he,"")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,"string"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if("string"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),"function"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){ue["[object "+t+"]"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+" "]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(xe,"\\$&"):t.setAttribute("id",s=P),f=N(e),o=f.length,u=de.test(s)?"#"+s:"[id='"+s+"']";o--;)f[o]=u+" "+d(f[o]);p=f.join(","),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute("id")}}}return S(e.replace(se,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>T.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||"*",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[" "],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(se,"$1"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h="0",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG("*",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P="sizzle"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ne="[\\x20\\t\\r\\n\\f]",re="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",ie="\\["+ne+"*("+re+")(?:"+ne+"*([*^$|!~]?=)"+ne+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+re+"))|)"+ne+"*\\]",oe=":("+re+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+ie+")*)|.*)\\)|)",ae=new RegExp(ne+"+","g"),se=new RegExp("^"+ne+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ne+"+$","g"),ue=new RegExp("^"+ne+"*,"+ne+"*"),le=new RegExp("^"+ne+"*([>+~]|"+ne+")"+ne+"*"),ce=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(oe),de=new RegExp("^"+re+"$"),pe={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+ie),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ye=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,xe=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Te,!1):n.attachEvent&&n.attachEvent("onunload",Te)),w.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML="<a id='"+P+"'></a><select id='"+P+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&F.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||F.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+P+"-]").length||F.push("~="),e.querySelectorAll(":checked").length||F.push(":checked"),e.querySelectorAll("a#"+P+"+*").length||F.push(".#.+[+~]")}),i(function(e){var t=H.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&F.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||F.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),F.push(",.*:")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,"div"),O.call(e,"[s!='']:x"),M.push("!=",oe)}),F=F.length&&new RegExp(F.join("|")),M=M.length&&new RegExp(M.join("|")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,"='$1']"),w.matchesSelector&&_&&!X[n+" "]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||"").replace(be,we),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&$(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ae," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}), +l=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[P]?o(n):o.length>1?(i=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,"$1"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+" "];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se," ")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+" "];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split("").sort(U).join("")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement("div"))}),i(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[":"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,Ce=/^.[^:#\[\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,"string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?"undefined"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||"string"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,"parentNode")},parentsUntil:function(e,t,n){return xe(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return xe(e,"nextSibling")},prevAll:function(e){return xe(e,"previousSibling")},nextUntil:function(e,t,n){return xe(e,"nextSibling",n)},prevUntil:function(e,t,n){return xe(e,"previousSibling",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\S+/g;pe.Callbacks=function(e){e="string"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:"")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n="",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[["resolve","done",pe.Callbacks("once memory"),"resolved"],["reject","fail",pe.Callbacks("once memory"),"rejected"],["notify","progress",pe.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler("ready"),pe(re).off("ready"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),"complete"===re.readyState||"loading"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener("DOMContentLoaded",s),e.addEventListener("load",s);else{re.attachEvent("onreadystatechange",s),e.attachEvent("onload",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll("left")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst="0"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName("body")[0],n&&n.style&&(t=re.createElement("div"),r=re.createElement("div"),r.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),"undefined"!=typeof t.style.zoom&&(t.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement("div");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+" ").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute("classid")===t)},qe=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,"parsedAttrs"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf("data-")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,"parsedAttrs",!0)}return i}return"object"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks("once memory").add(function(){pe._removeData(e,t+"queue"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";a--;)n=pe._data(o[a],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName("body")[0],n&&n.style?(t=re.createElement("div"),r=re.createElement("div"),r.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),"undefined"!=typeof t.style.zoom&&(t.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",t.appendChild(re.createElement("div")).style.width="5px",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,Me=new RegExp("^(?:([+-])=|)("+Fe+")([a-z%]*)$","i"),Oe=["Top","Right","Bottom","Left"],Re=function(e,t){return e=t||e,"none"===pe.css(e,"display")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\w:-]+)/,Ie=/^$|\/(?:java|ecma)script/i,$e=/^\s+/,ze="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";!function(){var e=re.createElement("div"),t=re.createDocumentFragment(),n=re.createElement("input");e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName("tbody").length,fe.htmlSerialize=!!e.getElementsByTagName("link").length,fe.html5Clone="<:nav></:nav>"!==re.createElement("nav").cloneNode(!0).outerHTML,n.type="checkbox",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML="<textarea>x</textarea>",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement("input"),n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:fe.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement("div");for(t in{submit:!0,change:!0,focusin:!0})n="on"+t,(fe[t]=n in e)||(r.setAttribute(n,"t"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return"undefined"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||"").match(De)||[""],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||"").split(".").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(".")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent("on"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||"").match(De)||[""],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||"").split(".").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,"events"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,"type")?t.type:t,h=ce.call(t,"namespace")?t.namespace.split("."):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(".")>-1&&(h=p.split("."),p=h.shift(),h.sort()),a=p.indexOf(":")<0&&"on"+p,t=t[pe.expando]?t:new pe.Event(p,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,"events")||{})[t.type]&&pe._data(s,"handle"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,"events")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+" ",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if(pe.nodeName(this,"input")&&"checkbox"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r="on"+t;e.detachEvent&&("undefined"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,"form")&&void pe.event.add(this,"click._submit keypress._submit",function(e){var t=e.target,n=pe.nodeName(t,"input")||pe.nodeName(t,"button")?pe.prop(t,"form"):void 0;n&&!pe._data(n,"submit")&&(pe.event.add(n,"submit._submit",function(e){e._submitBubble=!0}),pe._data(n,"submit",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate("submit",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,"form")&&void pe.event.remove(this,"._submit")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(pe.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,"click._change",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate("change",this,e)})),!1):void pe.event.add(this,"beforeactivate._change",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,"change")&&(pe.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate("change",this.parentNode,e)}),pe._data(t,"change",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||"radio"!==t.type&&"checkbox"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,"._change"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&"function"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\d+="(?:null|\d+)"/g,et=new RegExp("<(?:"+ze+")[\\s/>]","i"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,nt=/<script|<style|<link/i,rt=/checked\s*(?:[^=]|=\s*.checked.)/i,it=/^true\/(.*)/,ot=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,at=p(re),st=at.appendChild(re.createElement("div"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,"script"),r.length>0&&g(r,!u&&h(e,"script")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||"undefined"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,""):void 0;if("string"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||["",""])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)), +n&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:"block",BODY:"block"},ct=/^margin/,ft=new RegExp("^("+Fe+")(?!px)[a-z%]+$","i"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n="1%"!==(c||{}).top,s="2px"===(c||{}).marginLeft,i="4px"===(c||{width:"4px"}).width,l.style.marginRight="50%",r="4px"===(c||{marginRight:"4px"}).marginRight,t=l.appendChild(re.createElement("div")),t.style.cssText=l.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",t.style.marginRight=t.style.width="0",l.style.width="1px",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display="none",o=0===l.getClientRects().length,o&&(l.style.display="",l.innerHTML="<table><tr><td></td><td>t</td></tr></table>",t=l.getElementsByTagName("td"),t[0].style.cssText="margin:0;border:0;padding:0;display:none",o=0===t[0].offsetHeight,o&&(t[0].style.display="",t[1].style.display="none",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement("div"),l=re.createElement("div");l.style&&(l.style.cssText="float:left;opacity:.5",fe.opacity="0.5"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",fe.clearCloneStyle="content-box"===l.style.backgroundClip,u=re.createElement("div"),u.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",l.innerHTML="",u.appendChild(l),fe.boxSizing=""===l.style.boxSizing||""===l.style.MozBoxSizing||""===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,""!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+""}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left="fontSize"===t?"1em":a,a=s.pixelLeft+"px",s.left=r,o&&(i.left=o)),void 0===a?a:a+""||"auto"});var yt=/alpha\([^)]*\)/i,vt=/opacity\s*=\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp("^("+Fe+")(.*)$","i"),wt={position:"absolute",visibility:"hidden",display:"block"},Tt={letterSpacing:"0",fontWeight:"400"},Ct=["Webkit","O","Moz","ms"],Et=re.createElement("div").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":fe.cssFloat?"cssFloat":"styleFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,"string"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?"":"px")),fe.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),!(a&&"set"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&"get"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),"normal"===o&&t in Tt&&(o=Tt[t]),""===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each(["height","width"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,"display"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&"border-box"===pe.css(e,"boxSizing",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===pe.trim(o.replace(yt,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+" "+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:"inline-block"},gt,[e,"marginRight"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,"marginLeft"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+"px"}),pe.each({margin:"",padding:"",border:"Width"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?"":"px")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=["*"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&"object"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue="fx"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=pe._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each(["toggle","show","hide"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P("show"),slideUp:P("hide"),slideToggle:P("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement("input"),n=re.createElement("div"),r=re.createElement("select"),i=r.appendChild(re.createElement("option"));n=re.createElement("div"),n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",e=n.getElementsByTagName("a")[0],t.setAttribute("type","checkbox"),n.appendChild(t),e=n.getElementsByTagName("a")[0],e.style.cssText="top:1px",fe.getSetAttribute="t"!==n.className,fe.style=/top/.test(e.getAttribute("style")),fe.hrefNormalized="/a"===e.getAttribute("href"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement("form").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement("input"),t.setAttribute("value",""),fe.input=""===t.getAttribute("value"),t.value="t",t.setAttribute("type","radio"),fe.radioValue="t"===t.value}();var Dt=/\r/g,jt=/[\x20\t\r\n\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i="":"number"==typeof i?i+="":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?"":e+""})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(Dt,""):null==n?"":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,"value");return null!=t?t:pe.trim(pe.text(e)).replace(jt," ")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,"optgroup"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each(["radio","checkbox"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&"radio"===t&&pe.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase("default-"+n)]=e[r]=!1:pe.attr(e,n,""),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase("default-"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase("default-"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,"input")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+="","value"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&""!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,""!==t&&t,n)}},pe.each(["width","height"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(""===n)return e.setAttribute(t,"auto"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+""}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,"tabindex");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),fe.hrefNormalized||pe.each(["href","src"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype="encoding");var Pt=/[\t\r\n\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if("string"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");s=pe.trim(r),i!==s&&pe.attr(n,"class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");s=pe.trim(r),i!==s&&pe.attr(n,"class",s)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if("string"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&"boolean"!==n||(t=z(this),t&&pe._data(this,"__className__",t),pe.attr(this,"class",t||e===!1?"":pe._data(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+z(n)+" ").replace(Pt," ").indexOf(t)>-1)return!0;return!1}}),pe.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\?/,$t=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+"");var n,r=null,i=pe.trim(t+"");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,"")}))?Function("return "+i)():pe.error("Invalid JSON: "+t)},pe.parseXML=function(t){var n,r;if(!t||"string"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,"text/xml")):(n=new e.ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName("parsererror").length||pe.error("Invalid XML: "+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\/\//,Gt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Kt={},Qt={},Zt="*/".concat("*"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:"GET",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":pe.parseJSON,"text xml":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||"",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader("etag"),w&&(pe.etag[a]=w)),204===t||"HEAD"===d.type?C="nocontent":304===t?C="notmodified":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C="error",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+"",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?"ajaxSuccess":"ajaxError",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger("ajaxComplete",[T,d]),--pe.active||pe.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks("once memory"),y=d.statusCode||{},v={},x={},b=0,w="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+"").replace(zt,"").replace(Jt,tn[1]+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||"*").toLowerCase().match(De)||[""],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||("http:"===i[1]?"80":"443"))===(tn[3]||("http:"===tn[1]?"80":"443")))),d.data&&d.processData&&"string"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?"&":"?")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,"$1_="+Wt++):a+(It.test(a)?"&":"?")+"_="+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader("If-Modified-Since",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader("If-None-Match",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader("Content-Type",d.contentType),T.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Zt+"; q=0.01":""):d.accepts["*"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w="abort";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger("ajaxSend",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort("timeout")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,"No Transport");return T},getJSON:function(e,t,n){return pe.get(e,t,n,"json")},getScript:function(e,t){return pe.get(e,void 0,t,"script")}}),pe.each(["get","post"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,"body")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\[\]$/,on=/\r?\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join("&").replace(nn,"+")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,"elements");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(":disabled")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent("onunload",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&"withCredentials"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r["X-Requested-With"]||(r["X-Requested-With"]="XMLHttpRequest");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+"");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,"string"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=""}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),pe.ajaxTransport("script",function(e){if(e.crossDomain){var t,n=re.head||pe("head")[0]||re.documentElement;return{send:function(r,i){t=re.createElement("script"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,"success"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\?(?=&|$)|\?\?/;pe.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=fn.pop()||pe.expando+"_"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||pe.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),"script"}),pe.parseHTML=function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if("string"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&pe.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?pe("<div>").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,"position"),f=pe(e),d={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=pe.css(e,"top"),u=pe.css(e,"left"),l=("absolute"===c||"fixed"===c)&&pe.inArray("auto",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),"using"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?("undefined"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===pe.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],"html")||(n=e.offset()),n.top+=pe.css(e[0],"borderTopWidth",!0),n.left+=pe.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-pe.css(r,"marginTop",!0),left:t.left-n.left-pe.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){ +for(var e=this.offsetParent;e&&!pe.nodeName(e,"html")&&"static"===pe.css(e,"position");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each(["top","left"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+"px":n})}),pe.each({Height:"height",Width:"width"},function(e,t){pe.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),a=n||(r===!0||i===!0?"margin":"border");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){layui.$=pe,e("jquery",pe)}),pe}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/laydate.js b/static/plugins/layui/lay/modules/laydate.js new file mode 100755 index 0000000..56a8c0b --- /dev/null +++ b/static/plugins/layui/lay/modules/laydate.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;!function(){"use strict";var e=window.layui&&layui.define,t={getPath:function(){var e=document.scripts,t=e[e.length-1],n=t.src;if(!t.getAttribute("merge"))return n.substring(0,n.lastIndexOf("/")+1)}(),getStyle:function(e,t){var n=e.currentStyle?e.currentStyle:window.getComputedStyle(e,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](t)},link:function(e,a,i){if(n.path){var r=document.getElementsByTagName("head")[0],o=document.createElement("link");"string"==typeof a&&(i=a);var s=(i||e).replace(/\.|\//g,""),l="layuicss-"+s,d=0;o.rel="stylesheet",o.href=n.path+e,o.id=l,document.getElementById(l)||r.appendChild(o),"function"==typeof a&&!function c(){return++d>80?window.console&&console.error("laydate.css: Invalid"):void(1989===parseInt(t.getStyle(document.getElementById(l),"width"))?a():setTimeout(c,100))}()}}},n={v:"5.0.8",config:{},index:window.laydate&&window.laydate.v?1e5:0,path:t.getPath,set:function(e){var n=this;return n.config=t.extend({},n.config,e),n},ready:function(a){var i="laydate",r="",o=(e?"modules/laydate/":"theme/")+"default/laydate.css?v="+n.v+r;return e?layui.addcss(o,a,i):t.link(o,a,i),this}},a=function(){var e=this;return{hint:function(t){e.hint.call(e,t)},config:e.config}},i="laydate",r=".layui-laydate",o="layui-this",s="laydate-disabled",l="开始日期超出了结束日期<br>建议重新选择",d=[100,2e5],c="layui-laydate-static",m="layui-laydate-list",u="laydate-selected",h="layui-laydate-hint",y="laydate-day-prev",f="laydate-day-next",p="layui-laydate-footer",g=".laydate-btns-confirm",v="laydate-time-text",D=".laydate-btns-time",T=function(e){var t=this;t.index=++n.index,t.config=w.extend({},t.config,n.config,e),n.ready(function(){t.init()})},w=function(e){return new C(e)},C=function(e){for(var t=0,n="object"==typeof e?[e]:(this.selector=e,document.querySelectorAll(e||null));t<n.length;t++)this.push(n[t])};C.prototype=[],C.prototype.constructor=C,w.extend=function(){var e=1,t=arguments,n=function(e,t){e=e||(t.constructor===Array?[]:{});for(var a in t)e[a]=t[a]&&t[a].constructor===Object?n(e[a],t[a]):t[a];return e};for(t[0]="object"==typeof t[0]?t[0]:{};e<t.length;e++)"object"==typeof t[e]&&n(t[0],t[e]);return t[0]},w.ie=function(){var e=navigator.userAgent.toLowerCase();return!!(window.ActiveXObject||"ActiveXObject"in window)&&((e.match(/msie\s(\d+)/)||[])[1]||"11")}(),w.stope=function(e){e=e||window.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},w.each=function(e,t){var n,a=this;if("function"!=typeof t)return a;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return a},w.digit=function(e,t,n){var a="";e=String(e),t=t||2;for(var i=e.length;i<t;i++)a+="0";return e<Math.pow(10,t)?a+(0|e):e},w.elem=function(e,t){var n=document.createElement(e);return w.each(t||{},function(e,t){n.setAttribute(e,t)}),n},C.addStr=function(e,t){return e=e.replace(/\s+/," "),t=t.replace(/\s+/," ").split(" "),w.each(t,function(t,n){new RegExp("\\b"+n+"\\b").test(e)||(e=e+" "+n)}),e.replace(/^\s|\s$/,"")},C.removeStr=function(e,t){return e=e.replace(/\s+/," "),t=t.replace(/\s+/," ").split(" "),w.each(t,function(t,n){var a=new RegExp("\\b"+n+"\\b");a.test(e)&&(e=e.replace(a,""))}),e.replace(/\s+/," ").replace(/^\s|\s$/,"")},C.prototype.find=function(e){var t=this,n=0,a=[],i="object"==typeof e;return this.each(function(r,o){for(var s=i?[e]:o.querySelectorAll(e||null);n<s.length;n++)a.push(s[n]);t.shift()}),i||(t.selector=(t.selector?t.selector+" ":"")+e),w.each(a,function(e,n){t.push(n)}),t},C.prototype.each=function(e){return w.each.call(this,this,e)},C.prototype.addClass=function(e,t){return this.each(function(n,a){a.className=C[t?"removeStr":"addStr"](a.className,e)})},C.prototype.removeClass=function(e){return this.addClass(e,!0)},C.prototype.hasClass=function(e){var t=!1;return this.each(function(n,a){new RegExp("\\b"+e+"\\b").test(a.className)&&(t=!0)}),t},C.prototype.attr=function(e,t){var n=this;return void 0===t?function(){if(n.length>0)return n[0].getAttribute(e)}():n.each(function(n,a){a.setAttribute(e,t)})},C.prototype.removeAttr=function(e){return this.each(function(t,n){n.removeAttribute(e)})},C.prototype.html=function(e){return this.each(function(t,n){n.innerHTML=e})},C.prototype.val=function(e){return this.each(function(t,n){n.value=e})},C.prototype.append=function(e){return this.each(function(t,n){"object"==typeof e?n.appendChild(e):n.innerHTML=n.innerHTML+e})},C.prototype.remove=function(e){return this.each(function(t,n){e?n.removeChild(e):n.parentNode.removeChild(n)})},C.prototype.on=function(e,t){return this.each(function(n,a){a.attachEvent?a.attachEvent("on"+e,function(e){e.target=e.srcElement,t.call(a,e)}):a.addEventListener(e,t,!1)})},C.prototype.off=function(e,t){return this.each(function(n,a){a.detachEvent?a.detachEvent("on"+e,t):a.removeEventListener(e,t,!1)})},T.isLeapYear=function(e){return e%4===0&&e%100!==0||e%400===0},T.prototype.config={type:"date",range:!1,format:"yyyy-MM-dd",value:null,min:"1900-1-1",max:"2099-12-31",trigger:"focus",show:!1,showBottom:!0,btns:["clear","now","confirm"],lang:"cn",theme:"default",position:null,calendar:!1,mark:{},zIndex:null,done:null,change:null},T.prototype.lang=function(){var e=this,t=e.config,n={cn:{weeks:["日","一","二","三","四","五","六"],time:["时","分","秒"],timeTips:"选择时间",startTime:"开始时间",endTime:"结束时间",dateTips:"返回日期",month:["一","二","三","四","五","六","七","八","九","十","十一","十二"],tools:{confirm:"确定",clear:"清空",now:"现在"}},en:{weeks:["Su","Mo","Tu","We","Th","Fr","Sa"],time:["Hours","Minutes","Seconds"],timeTips:"Select Time",startTime:"Start Time",endTime:"End Time",dateTips:"Select Date",month:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],tools:{confirm:"Confirm",clear:"Clear",now:"Now"}}};return n[t.lang]||n.cn},T.prototype.init=function(){var e=this,t=e.config,n="yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s",a="static"===t.position,i={year:"yyyy",month:"yyyy-MM",date:"yyyy-MM-dd",time:"HH:mm:ss",datetime:"yyyy-MM-dd HH:mm:ss"};t.elem=w(t.elem),t.eventElem=w(t.eventElem),t.elem[0]&&(t.range===!0&&(t.range="-"),t.format===i.date&&(t.format=i[t.type]),e.format=t.format.match(new RegExp(n+"|.","g"))||[],e.EXP_IF="",e.EXP_SPLIT="",w.each(e.format,function(t,a){var i=new RegExp(n).test(a)?"\\d{"+function(){return new RegExp(n).test(e.format[0===t?t+1:t-1]||"")?/^yyyy|y$/.test(a)?4:a.length:/^yyyy$/.test(a)?"1,4":/^y$/.test(a)?"1,308":"1,2"}()+"}":"\\"+a;e.EXP_IF=e.EXP_IF+i,e.EXP_SPLIT=e.EXP_SPLIT+"("+i+")"}),e.EXP_IF=new RegExp("^"+(t.range?e.EXP_IF+"\\s\\"+t.range+"\\s"+e.EXP_IF:e.EXP_IF)+"$"),e.EXP_SPLIT=new RegExp("^"+e.EXP_SPLIT+"$",""),e.isInput(t.elem[0])||"focus"===t.trigger&&(t.trigger="click"),t.elem.attr("lay-key")||(t.elem.attr("lay-key",e.index),t.eventElem.attr("lay-key",e.index)),t.mark=w.extend({},t.calendar&&"cn"===t.lang?{"0-1-1":"元旦","0-2-14":"情人","0-3-8":"妇女","0-3-12":"植树","0-4-1":"愚人","0-5-1":"劳动","0-5-4":"青年","0-6-1":"儿童","0-9-10":"教师","0-9-18":"国耻","0-10-1":"国庆","0-12-25":"圣诞"}:{},t.mark),w.each(["min","max"],function(e,n){var a=[],i=[];if("number"==typeof t[n]){var r=t[n],o=(new Date).getTime(),s=864e5,l=new Date(r?r<s?o+r*s:r:o);a=[l.getFullYear(),l.getMonth()+1,l.getDate()],r<s||(i=[l.getHours(),l.getMinutes(),l.getSeconds()])}else a=(t[n].match(/\d+-\d+-\d+/)||[""])[0].split("-"),i=(t[n].match(/\d+:\d+:\d+/)||[""])[0].split(":");t[n]={year:0|a[0]||(new Date).getFullYear(),month:a[1]?(0|a[1])-1:(new Date).getMonth(),date:0|a[2]||(new Date).getDate(),hours:0|i[0],minutes:0|i[1],seconds:0|i[2]}}),e.elemID="layui-laydate"+t.elem.attr("lay-key"),(t.show||a)&&e.render(),a||e.events(),t.value&&(t.value.constructor===Date?e.setValue(e.parse(0,e.systemDate(t.value))):e.setValue(t.value)))},T.prototype.render=function(){var e=this,t=e.config,n=e.lang(),a="static"===t.position,i=e.elem=w.elem("div",{id:e.elemID,"class":["layui-laydate",t.range?" layui-laydate-range":"",a?" "+c:"",t.theme&&"default"!==t.theme&&!/^#/.test(t.theme)?" laydate-theme-"+t.theme:""].join("")}),r=e.elemMain=[],o=e.elemHeader=[],s=e.elemCont=[],l=e.table=[],d=e.footer=w.elem("div",{"class":p});if(t.zIndex&&(i.style.zIndex=t.zIndex),w.each(new Array(2),function(e){if(!t.range&&e>0)return!0;var a=w.elem("div",{"class":"layui-laydate-header"}),i=[function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-prev-y"});return e.innerHTML="&#xe65a;",e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-prev-m"});return e.innerHTML="&#xe603;",e}(),function(){var e=w.elem("div",{"class":"laydate-set-ym"}),t=w.elem("span"),n=w.elem("span");return e.appendChild(t),e.appendChild(n),e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-next-m"});return e.innerHTML="&#xe602;",e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-next-y"});return e.innerHTML="&#xe65b;",e}()],d=w.elem("div",{"class":"layui-laydate-content"}),c=w.elem("table"),m=w.elem("thead"),u=w.elem("tr");w.each(i,function(e,t){a.appendChild(t)}),m.appendChild(u),w.each(new Array(6),function(e){var t=c.insertRow(0);w.each(new Array(7),function(a){if(0===e){var i=w.elem("th");i.innerHTML=n.weeks[a],u.appendChild(i)}t.insertCell(a)})}),c.insertBefore(m,c.children[0]),d.appendChild(c),r[e]=w.elem("div",{"class":"layui-laydate-main laydate-main-list-"+e}),r[e].appendChild(a),r[e].appendChild(d),o.push(i),s.push(d),l.push(c)}),w(d).html(function(){var e=[],i=[];return"datetime"===t.type&&e.push('<span lay-type="datetime" class="laydate-btns-time">'+n.timeTips+"</span>"),w.each(t.btns,function(e,r){var o=n.tools[r]||"btn";t.range&&"now"===r||(a&&"clear"===r&&(o="cn"===t.lang?"重置":"Reset"),i.push('<span lay-type="'+r+'" class="laydate-btns-'+r+'">'+o+"</span>"))}),e.push('<div class="laydate-footer-btns">'+i.join("")+"</div>"),e.join("")}()),w.each(r,function(e,t){i.appendChild(t)}),t.showBottom&&i.appendChild(d),/^#/.test(t.theme)){var m=w.elem("style"),u=["#{{id}} .layui-laydate-header{background-color:{{theme}};}","#{{id}} .layui-this{background-color:{{theme}} !important;}"].join("").replace(/{{id}}/g,e.elemID).replace(/{{theme}}/g,t.theme);"styleSheet"in m?(m.setAttribute("type","text/css"),m.styleSheet.cssText=u):m.innerHTML=u,w(i).addClass("laydate-theme-molv"),i.appendChild(m)}e.remove(T.thisElemDate),a?t.elem.append(i):(document.body.appendChild(i),e.position()),e.checkDate().calendar(),e.changeEvent(),T.thisElemDate=e.elemID,"function"==typeof t.ready&&t.ready(w.extend({},t.dateTime,{month:t.dateTime.month+1}))},T.prototype.remove=function(e){var t=this,n=(t.config,w("#"+(e||t.elemID)));return n.hasClass(c)||t.checkDate(function(){n.remove()}),t},T.prototype.position=function(){var e=this,t=e.config,n=e.bindElem||t.elem[0],a=n.getBoundingClientRect(),i=e.elem.offsetWidth,r=e.elem.offsetHeight,o=function(e){return e=e?"scrollLeft":"scrollTop",document.body[e]|document.documentElement[e]},s=function(e){return document.documentElement[e?"clientWidth":"clientHeight"]},l=5,d=a.left,c=a.bottom;d+i+l>s("width")&&(d=s("width")-i-l),c+r+l>s()&&(c=a.top>r?a.top-r:s()-r,c-=2*l),t.position&&(e.elem.style.position=t.position),e.elem.style.left=d+("fixed"===t.position?0:o(1))+"px",e.elem.style.top=c+("fixed"===t.position?0:o())+"px"},T.prototype.hint=function(e){var t=this,n=(t.config,w.elem("div",{"class":h}));n.innerHTML=e||"",w(t.elem).find("."+h).remove(),t.elem.appendChild(n),clearTimeout(t.hinTimer),t.hinTimer=setTimeout(function(){w(t.elem).find("."+h).remove()},3e3)},T.prototype.getAsYM=function(e,t,n){return n?t--:t++,t<0&&(t=11,e--),t>11&&(t=0,e++),[e,t]},T.prototype.systemDate=function(e){var t=e||new Date;return{year:t.getFullYear(),month:t.getMonth(),date:t.getDate(),hours:e?e.getHours():0,minutes:e?e.getMinutes():0,seconds:e?e.getSeconds():0}},T.prototype.checkDate=function(e){var t,a,i=this,r=(new Date,i.config),o=r.dateTime=r.dateTime||i.systemDate(),s=i.bindElem||r.elem[0],l=(i.isInput(s)?"val":"html",i.isInput(s)?s.value:"static"===r.position?"":s.innerHTML),c=function(e){e.year>d[1]&&(e.year=d[1],a=!0),e.month>11&&(e.month=11,a=!0),e.hours>23&&(e.hours=0,a=!0),e.minutes>59&&(e.minutes=0,e.hours++,a=!0),e.seconds>59&&(e.seconds=0,e.minutes++,a=!0),t=n.getEndDate(e.month+1,e.year),e.date>t&&(e.date=t,a=!0)},m=function(e,t,n){var o=["startTime","endTime"];t=(t.match(i.EXP_SPLIT)||[]).slice(1),n=n||0,r.range&&(i[o[n]]=i[o[n]]||{}),w.each(i.format,function(s,l){var c=parseFloat(t[s]);t[s].length<l.length&&(a=!0),/yyyy|y/.test(l)?(c<d[0]&&(c=d[0],a=!0),e.year=c):/MM|M/.test(l)?(c<1&&(c=1,a=!0),e.month=c-1):/dd|d/.test(l)?(c<1&&(c=1,a=!0),e.date=c):/HH|H/.test(l)?(c<1&&(c=0,a=!0),e.hours=c,r.range&&(i[o[n]].hours=c)):/mm|m/.test(l)?(c<1&&(c=0,a=!0),e.minutes=c,r.range&&(i[o[n]].minutes=c)):/ss|s/.test(l)&&(c<1&&(c=0,a=!0),e.seconds=c,r.range&&(i[o[n]].seconds=c))}),c(e)};return"limit"===e?(c(o),i):(l=l||r.value,"string"==typeof l&&(l=l.replace(/\s+/g," ").replace(/^\s|\s$/g,"")),i.startState&&!i.endState&&(delete i.startState,i.endState=!0),"string"==typeof l&&l?i.EXP_IF.test(l)?r.range?(l=l.split(" "+r.range+" "),i.startDate=i.startDate||i.systemDate(),i.endDate=i.endDate||i.systemDate(),r.dateTime=w.extend({},i.startDate),w.each([i.startDate,i.endDate],function(e,t){m(t,l[e],e)})):m(o,l):(i.hint("日期格式不合法<br>必须遵循下述格式:<br>"+(r.range?r.format+" "+r.range+" "+r.format:r.format)+"<br>已为你重置"),a=!0):l&&l.constructor===Date?r.dateTime=i.systemDate(l):(r.dateTime=i.systemDate(),delete i.startState,delete i.endState,delete i.startDate,delete i.endDate,delete i.startTime,delete i.endTime),c(o),a&&l&&i.setValue(r.range?i.endDate?i.parse():"":i.parse()),e&&e(),i)},T.prototype.mark=function(e,t){var n,a=this,i=a.config;return w.each(i.mark,function(e,a){var i=e.split("-");i[0]!=t[0]&&0!=i[0]||i[1]!=t[1]&&0!=i[1]||i[2]!=t[2]||(n=a||t[2])}),n&&e.html('<span class="laydate-day-mark">'+n+"</span>"),a},T.prototype.limit=function(e,t,n,a){var i,r=this,o=r.config,l={},d=o[n>41?"endDate":"dateTime"],c=w.extend({},d,t||{});return w.each({now:c,min:o.min,max:o.max},function(e,t){l[e]=r.newDate(w.extend({year:t.year,month:t.month,date:t.date},function(){var e={};return w.each(a,function(n,a){e[a]=t[a]}),e}())).getTime()}),i=l.now<l.min||l.now>l.max,e&&e[i?"addClass":"removeClass"](s),i},T.prototype.calendar=function(e){var t,a,i,r=this,s=r.config,l=e||s.dateTime,c=new Date,m=r.lang(),u="date"!==s.type&&"datetime"!==s.type,h=e?1:0,y=w(r.table[h]).find("td"),f=w(r.elemHeader[h][2]).find("span");if(l.year<d[0]&&(l.year=d[0],r.hint("最低只能支持到公元"+d[0]+"年")),l.year>d[1]&&(l.year=d[1],r.hint("最高只能支持到公元"+d[1]+"年")),r.firstDate||(r.firstDate=w.extend({},l)),c.setFullYear(l.year,l.month,1),t=c.getDay(),a=n.getEndDate(l.month||12,l.year),i=n.getEndDate(l.month+1,l.year),w.each(y,function(e,n){var d=[l.year,l.month],c=0;n=w(n),n.removeAttr("class"),e<t?(c=a-t+e,n.addClass("laydate-day-prev"),d=r.getAsYM(l.year,l.month,"sub")):e>=t&&e<i+t?(c=e-t,s.range||c+1===l.date&&n.addClass(o)):(c=e-i-t,n.addClass("laydate-day-next"),d=r.getAsYM(l.year,l.month)),d[1]++,d[2]=c+1,n.attr("lay-ymd",d.join("-")).html(d[2]),r.mark(n,d).limit(n,{year:d[0],month:d[1]-1,date:d[2]},e)}),w(f[0]).attr("lay-ym",l.year+"-"+(l.month+1)),w(f[1]).attr("lay-ym",l.year+"-"+(l.month+1)),"cn"===s.lang?(w(f[0]).attr("lay-type","year").html(l.year+"年"),w(f[1]).attr("lay-type","month").html(l.month+1+"月")):(w(f[0]).attr("lay-type","month").html(m.month[l.month]),w(f[1]).attr("lay-type","year").html(l.year)),u&&(s.range&&(e?r.endDate=r.endDate||{year:l.year+("year"===s.type?1:0),month:l.month+("month"===s.type?0:-1)}:r.startDate=r.startDate||{year:l.year,month:l.month},e&&(r.listYM=[[r.startDate.year,r.startDate.month+1],[r.endDate.year,r.endDate.month+1]],r.list(s.type,0).list(s.type,1),"time"===s.type?r.setBtnStatus("时间",w.extend({},r.systemDate(),r.startTime),w.extend({},r.systemDate(),r.endTime)):r.setBtnStatus(!0))),s.range||(r.listYM=[[l.year,l.month+1]],r.list(s.type,0))),s.range&&!e){var p=r.getAsYM(l.year,l.month);r.calendar(w.extend({},l,{year:p[0],month:p[1]}))}return s.range||r.limit(w(r.footer).find(g),null,0,["hours","minutes","seconds"]),s.range&&e&&!u&&r.stampRange(),r},T.prototype.list=function(e,t){var n=this,a=n.config,i=a.dateTime,r=n.lang(),l=a.range&&"date"!==a.type&&"datetime"!==a.type,d=w.elem("ul",{"class":m+" "+{year:"laydate-year-list",month:"laydate-month-list",time:"laydate-time-list"}[e]}),c=n.elemHeader[t],u=w(c[2]).find("span"),h=n.elemCont[t||0],y=w(h).find("."+m)[0],f="cn"===a.lang,p=f?"年":"",T=n.listYM[t]||{},C=["hours","minutes","seconds"],x=["startTime","endTime"][t];if(T[0]<1&&(T[0]=1),"year"===e){var M,b=M=T[0]-7;b<1&&(b=M=1),w.each(new Array(15),function(e){var i=w.elem("li",{"lay-ym":M}),r={year:M};M==T[0]&&w(i).addClass(o),i.innerHTML=M+p,d.appendChild(i),M<n.firstDate.year?(r.month=a.min.month,r.date=a.min.date):M>=n.firstDate.year&&(r.month=a.max.month,r.date=a.max.date),n.limit(w(i),r,t),M++}),w(u[f?0:1]).attr("lay-ym",M-8+"-"+T[1]).html(b+p+" - "+(M-1+p))}else if("month"===e)w.each(new Array(12),function(e){var i=w.elem("li",{"lay-ym":e}),s={year:T[0],month:e};e+1==T[1]&&w(i).addClass(o),i.innerHTML=r.month[e]+(f?"月":""),d.appendChild(i),T[0]<n.firstDate.year?s.date=a.min.date:T[0]>=n.firstDate.year&&(s.date=a.max.date),n.limit(w(i),s,t)}),w(u[f?0:1]).attr("lay-ym",T[0]+"-"+T[1]).html(T[0]+p);else if("time"===e){var E=function(){w(d).find("ol").each(function(e,a){w(a).find("li").each(function(a,i){n.limit(w(i),[{hours:a},{hours:n[x].hours,minutes:a},{hours:n[x].hours,minutes:n[x].minutes,seconds:a}][e],t,[["hours"],["hours","minutes"],["hours","minutes","seconds"]][e])})}),a.range||n.limit(w(n.footer).find(g),n[x],0,["hours","minutes","seconds"])};a.range?n[x]||(n[x]={hours:0,minutes:0,seconds:0}):n[x]=i,w.each([24,60,60],function(e,t){var a=w.elem("li"),i=["<p>"+r.time[e]+"</p><ol>"];w.each(new Array(t),function(t){i.push("<li"+(n[x][C[e]]===t?' class="'+o+'"':"")+">"+w.digit(t,2)+"</li>")}),a.innerHTML=i.join("")+"</ol>",d.appendChild(a)}),E()}if(y&&h.removeChild(y),h.appendChild(d),"year"===e||"month"===e)w(n.elemMain[t]).addClass("laydate-ym-show"),w(d).find("li").on("click",function(){var r=0|w(this).attr("lay-ym");if(!w(this).hasClass(s)){if(0===t)i[e]=r,l&&(n.startDate[e]=r),n.limit(w(n.footer).find(g),null,0);else if(l)n.endDate[e]=r;else{var c="year"===e?n.getAsYM(r,T[1]-1,"sub"):n.getAsYM(T[0],r,"sub");w.extend(i,{year:c[0],month:c[1]})}"year"===a.type||"month"===a.type?(w(d).find("."+o).removeClass(o),w(this).addClass(o),"month"===a.type&&"year"===e&&(n.listYM[t][0]=r,l&&(n[["startDate","endDate"][t]].year=r),n.list("month",t))):(n.checkDate("limit").calendar(),n.closeList()),n.setBtnStatus(),a.range||n.done(null,"change"),w(n.footer).find(D).removeClass(s)}});else{var S=w.elem("span",{"class":v}),k=function(){w(d).find("ol").each(function(e){var t=this,a=w(t).find("li");t.scrollTop=30*(n[x][C[e]]-2),t.scrollTop<=0&&a.each(function(e,n){if(!w(this).hasClass(s))return t.scrollTop=30*(e-2),!0})})},H=w(c[2]).find("."+v);k(),S.innerHTML=a.range?[r.startTime,r.endTime][t]:r.timeTips,w(n.elemMain[t]).addClass("laydate-time-show"),H[0]&&H.remove(),c[2].appendChild(S),w(d).find("ol").each(function(e){var t=this;w(t).find("li").on("click",function(){var r=0|this.innerHTML;w(this).hasClass(s)||(a.range?n[x][C[e]]=r:i[C[e]]=r,w(t).find("."+o).removeClass(o),w(this).addClass(o),E(),k(),(n.endDate||"time"===a.type)&&n.done(null,"change"),n.setBtnStatus())})})}return n},T.prototype.listYM=[],T.prototype.closeList=function(){var e=this;e.config;w.each(e.elemCont,function(t,n){w(this).find("."+m).remove(),w(e.elemMain[t]).removeClass("laydate-ym-show laydate-time-show")}),w(e.elem).find("."+v).remove()},T.prototype.setBtnStatus=function(e,t,n){var a,i=this,r=i.config,o=w(i.footer).find(g),d=r.range&&"date"!==r.type&&"time"!==r.type;d&&(t=t||i.startDate,n=n||i.endDate,a=i.newDate(t).getTime()>i.newDate(n).getTime(),i.limit(null,t)||i.limit(null,n)?o.addClass(s):o[a?"addClass":"removeClass"](s),e&&a&&i.hint("string"==typeof e?l.replace(/日期/g,e):l))},T.prototype.parse=function(e,t){var n=this,a=n.config,i=t||(e?w.extend({},n.endDate,n.endTime):a.range?w.extend({},n.startDate,n.startTime):a.dateTime),r=n.format.concat();return w.each(r,function(e,t){/yyyy|y/.test(t)?r[e]=w.digit(i.year,t.length):/MM|M/.test(t)?r[e]=w.digit(i.month+1,t.length):/dd|d/.test(t)?r[e]=w.digit(i.date,t.length):/HH|H/.test(t)?r[e]=w.digit(i.hours,t.length):/mm|m/.test(t)?r[e]=w.digit(i.minutes,t.length):/ss|s/.test(t)&&(r[e]=w.digit(i.seconds,t.length))}),a.range&&!e?r.join("")+" "+a.range+" "+n.parse(1):r.join("")},T.prototype.newDate=function(e){return new Date(e.year||1,e.month||0,e.date||1,e.hours||0,e.minutes||0,e.seconds||0)},T.prototype.setValue=function(e){var t=this,n=t.config,a=t.bindElem||n.elem[0],i=t.isInput(a)?"val":"html";return"static"===n.position||w(a)[i](e||""),this},T.prototype.stampRange=function(){var e,t,n=this,a=n.config,i=w(n.elem).find("td");if(a.range&&!n.endDate&&w(n.footer).find(g).addClass(s),n.endDate)return e=n.newDate({year:n.startDate.year,month:n.startDate.month,date:n.startDate.date}).getTime(),t=n.newDate({year:n.endDate.year,month:n.endDate.month,date:n.endDate.date}).getTime(),e>t?n.hint(l):void w.each(i,function(a,i){var r=w(i).attr("lay-ymd").split("-"),s=n.newDate({year:r[0],month:r[1]-1,date:r[2]}).getTime();w(i).removeClass(u+" "+o),s!==e&&s!==t||w(i).addClass(w(i).hasClass(y)||w(i).hasClass(f)?u:o),s>e&&s<t&&w(i).addClass(u)})},T.prototype.done=function(e,t){var n=this,a=n.config,i=w.extend({},n.startDate?w.extend(n.startDate,n.startTime):a.dateTime),r=w.extend({},w.extend(n.endDate,n.endTime));return w.each([i,r],function(e,t){"month"in t&&w.extend(t,{month:t.month+1})}),e=e||[n.parse(),i,r],"function"==typeof a[t||"done"]&&a[t||"done"].apply(a,e),n},T.prototype.choose=function(e){var t=this,n=t.config,a=n.dateTime,i=w(t.elem).find("td"),r=e.attr("lay-ymd").split("-"),l=function(e){new Date;e&&w.extend(a,r),n.range&&(t.startDate?w.extend(t.startDate,r):t.startDate=w.extend({},r,t.startTime),t.startYMD=r)};if(r={year:0|r[0],month:(0|r[1])-1,date:0|r[2]},!e.hasClass(s))if(n.range){if(w.each(["startTime","endTime"],function(e,n){t[n]=t[n]||{hours:0,minutes:0,seconds:0}}),t.endState)l(),delete t.endState,delete t.endDate,t.startState=!0,i.removeClass(o+" "+u),e.addClass(o);else if(t.startState){if(e.addClass(o),t.endDate?w.extend(t.endDate,r):t.endDate=w.extend({},r,t.endTime),t.newDate(r).getTime()<t.newDate(t.startYMD).getTime()){var d=w.extend({},t.endDate,{hours:t.startDate.hours,minutes:t.startDate.minutes,seconds:t.startDate.seconds});w.extend(t.endDate,t.startDate,{hours:t.endDate.hours,minutes:t.endDate.minutes,seconds:t.endDate.seconds}),t.startDate=d}n.showBottom||t.done(),t.stampRange(),t.endState=!0,t.done(null,"change")}else e.addClass(o),l(),t.startState=!0;w(t.footer).find(g)[t.endDate?"removeClass":"addClass"](s)}else"static"===n.position?(l(!0),t.calendar().done().done(null,"change")):"date"===n.type?(l(!0),t.setValue(t.parse()).remove().done()):"datetime"===n.type&&(l(!0),t.calendar().done(null,"change"))},T.prototype.tool=function(e,t){var n=this,a=n.config,i=a.dateTime,r="static"===a.position,o={datetime:function(){w(e).hasClass(s)||(n.list("time",0),a.range&&n.list("time",1),w(e).attr("lay-type","date").html(n.lang().dateTips))},date:function(){n.closeList(),w(e).attr("lay-type","datetime").html(n.lang().timeTips)},clear:function(){n.setValue("").remove(),r&&(w.extend(i,n.firstDate),n.calendar()),a.range&&(delete n.startState,delete n.endState,delete n.endDate,delete n.startTime,delete n.endTime),n.done(["",{},{}])},now:function(){var e=new Date;w.extend(i,n.systemDate(),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()}),n.setValue(n.parse()).remove(),r&&n.calendar(),n.done()},confirm:function(){if(a.range){if(!n.endDate)return n.hint("请先选择日期范围");if(w(e).hasClass(s))return n.hint("time"===a.type?l.replace(/日期/g,"时间"):l)}else if(w(e).hasClass(s))return n.hint("不在有效日期或时间范围内");n.done(),n.setValue(n.parse()).remove()}};o[t]&&o[t]()},T.prototype.change=function(e){var t=this,n=t.config,a=n.dateTime,i=n.range&&("year"===n.type||"month"===n.type),r=t.elemCont[e||0],o=t.listYM[e],s=function(s){var l=["startDate","endDate"][e],d=w(r).find(".laydate-year-list")[0],c=w(r).find(".laydate-month-list")[0];return d&&(o[0]=s?o[0]-15:o[0]+15,t.list("year",e)),c&&(s?o[0]--:o[0]++,t.list("month",e)),(d||c)&&(w.extend(a,{year:o[0]}),i&&(t[l].year=o[0]),n.range||t.done(null,"change"),t.setBtnStatus(),n.range||t.limit(w(t.footer).find(g),{year:o[0]})),d||c};return{prevYear:function(){s("sub")||(a.year--,t.checkDate("limit").calendar(),n.range||t.done(null,"change"))},prevMonth:function(){var e=t.getAsYM(a.year,a.month,"sub");w.extend(a,{year:e[0],month:e[1]}),t.checkDate("limit").calendar(),n.range||t.done(null,"change")},nextMonth:function(){var e=t.getAsYM(a.year,a.month);w.extend(a,{year:e[0],month:e[1]}),t.checkDate("limit").calendar(),n.range||t.done(null,"change")},nextYear:function(){s()||(a.year++,t.checkDate("limit").calendar(),n.range||t.done(null,"change"))}}},T.prototype.changeEvent=function(){var e=this;e.config;w(e.elem).on("click",function(e){w.stope(e)}),w.each(e.elemHeader,function(t,n){w(n[0]).on("click",function(n){e.change(t).prevYear()}),w(n[1]).on("click",function(n){e.change(t).prevMonth()}),w(n[2]).find("span").on("click",function(n){var a=w(this),i=a.attr("lay-ym"),r=a.attr("lay-type");i&&(i=i.split("-"),e.listYM[t]=[0|i[0],0|i[1]],e.list(r,t),w(e.footer).find(D).addClass(s))}),w(n[3]).on("click",function(n){e.change(t).nextMonth()}),w(n[4]).on("click",function(n){e.change(t).nextYear()})}),w.each(e.table,function(t,n){var a=w(n).find("td");a.on("click",function(){e.choose(w(this))})}),w(e.footer).find("span").on("click",function(){var t=w(this).attr("lay-type");e.tool(this,t)})},T.prototype.isInput=function(e){return/input|textarea/.test(e.tagName.toLocaleLowerCase())},T.prototype.events=function(){var e=this,t=e.config,n=function(n,a){n.on(t.trigger,function(){a&&(e.bindElem=this),e.render()})};t.elem[0]&&!t.elem[0].eventHandler&&(n(t.elem,"bind"),n(t.eventElem),w(document).on("click",function(n){n.target!==t.elem[0]&&n.target!==t.eventElem[0]&&n.target!==w(t.closeStop)[0]&&e.remove()}).on("keydown",function(t){13===t.keyCode&&w("#"+e.elemID)[0]&&e.elemID===T.thisElem&&(t.preventDefault(),w(e.footer).find(g)[0].click())}),w(window).on("resize",function(){return!(!e.elem||!w(r)[0])&&void e.position()}),t.elem[0].eventHandler=!0)},n.render=function(e){var t=new T(e);return a.call(t)},n.getEndDate=function(e,t){var n=new Date;return n.setFullYear(t||n.getFullYear(),e||n.getMonth()+1,1),new Date(n.getTime()-864e5).getDate()},window.lay=window.lay||w,e?(n.ready(),layui.define(function(e){n.path=layui.cache.dir,e(i,n)})):"function"==typeof define&&define.amd?define(function(){return n}):function(){n.ready(),window.laydate=n}()}(); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/layedit.js b/static/plugins/layui/lay/modules/layedit.js new file mode 100755 index 0000000..ac7330e --- /dev/null +++ b/static/plugins/layui/lay/modules/layedit.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define(["layer","form"],function(t){"use strict";var e=layui.$,i=layui.layer,a=layui.form,l=(layui.hint(),layui.device()),n="layedit",o="layui-show",r="layui-disabled",c=function(){var t=this;t.index=0,t.config={tool:["strong","italic","underline","del","|","left","center","right","|","link","unlink","face","image"],hideTool:[],height:280}};c.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},c.prototype.on=function(t,e){return layui.onevent(n,t,e)},c.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r="layui-layedit",c=e("#"+t),u="LAY_layedit_"+ ++a.index,d=c.next("."+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join("")}(),m=e(['<div class="'+r+'">','<div class="layui-unselect layui-layedit-tool">'+f+"</div>",'<div class="layui-layedit-iframe">','<iframe id="'+u+'" name="'+u+'" textarea="'+t+'" frameborder="0"></iframe>',"</div>","</div>"].join(""));return l.ie&&l.ie<8?c.removeClass("layui-hide").addClass(o):(d[0]&&d.remove(),s.call(a,m,c[0],y),c.addClass("layui-hide").after(m),a.index)},c.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},c.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},c.prototype.setContent=function(t,i,a){var l=u(t);l[0]&&(a?e(l[0].document.body).append(i):e(l[0].document.body).html(i),layedit.sync(t))},c.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e("#"+i[1].attr("textarea"));a.val(d(i[0].document.body.innerHTML))}},c.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var s=function(t,i,a){var l=this,n=t.find("iframe");n.css({height:a.height}).on("load",function(){var o=n.contents(),r=n.prop("contentWindow"),c=o.find("head"),s=e(["<style>","*{margin: 0; padding: 0;}","body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}","a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}","p{margin-bottom: 10px;}","img{display: inline-block; border: none; vertical-align: middle;}","pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}","</style>"].join("")),u=o.find("body");c.append(s),u.attr("contenteditable","true").css({"min-height":a.height}).html(i.value||""),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e("#LAY_layedit_"+t),a=i.prop("contentWindow");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,c=e(r.body);c.on("keydown",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if("pre"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg("请暂时用shift+enter"),!1}r.execCommand("formatBlock",!1,"<p>")}}),e(n).parents("form").on("submit",function(){var t=c.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),c.on("paste",function(e){r.execCommand("formatBlock",!1,"<p>"),setTimeout(function(){f.call(t,c),n.value=c.html()},100)})},f=function(t){var i=this;i.document;t.find("*[style]").each(function(){var t=this.style.textAlign;this.removeAttribute("style"),e(this).css({"text-align":t||""})}),t.find("table").addClass("layui-table"),t.find("script,link").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute("text"),l.selection){var r=a.text||i.text;if("a"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop("outerHTML")),a.select()}else{var r=a.toString()||i.text;if("a"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l="layedit-tool-active",n=p(m(a)),o=function(e){return t.find(".layedit-tool-"+e)};i&&i[i.hasClass(l)?"removeClass":"addClass"](l),t.find(">i").removeClass(l),o("unlink").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;"b"!==t&&"strong"!==t||o("b").addClass(l),"i"!==t&&"em"!==t||o("i").addClass(l),"u"===t&&o("u").addClass(l),"strike"===t&&o("d").addClass(l),"p"===t&&("center"===e?o("center").addClass(l):"right"===e?o("right").addClass(l):o("left").addClass(l)),"a"===t&&(o("link").addClass(l),o("unlink").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),c={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr("href"),target:l.attr("target")},function(e){var a=l[0];"A"===a.tagName?a.href=e.url:v.call(t,"a",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand("unlink")},face:function(e){x.call(this,function(i){v.call(t,"img",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use("upload",function(o){var r=l.uploadImage||{};o.render({url:r.url,method:r.type,elem:e(n).find("input")[0],done:function(e){0==e.code?(e.data=e.data||{},v.call(t,"img",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||"上传失败")}})})},code:function(e){k.call(o,function(i){v.call(t,"pre",{text:i.code,"lay-lang":i.lang},e)})},help:function(){i.open({type:2,title:"帮助",area:["600px","380px"],shadeClose:!0,shade:.1,skin:"layui-layer-msg",content:["http://www.layui.com/about/layedit/help.html","no"]})}},s=a.find(".layui-layedit-tool"),u=function(){var i=e(this),a=i.attr("layedit-event"),l=i.attr("lay-command");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand("formatBlock",!1,"<p>"),setTimeout(function(){o.focus()},10)):c[a]&&c[a].call(this,u),h.call(t,s,i)}},d=/image/;s.find(">i").on("mousedown",function(){var t=e(this),i=t.attr("layedit-event");d.test(i)||u.call(this)}).on("click",function(){var t=e(this),i=t.attr("layedit-event");d.test(i)&&u.call(this)}),o.on("click",function(){h.call(t,s),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:"LAY_layedit_link",area:"350px",shade:.05,shadeClose:!0,moveType:1,title:"超链接",skin:"layui-layer-msg",content:['<ul class="layui-form" style="margin: 15px;">','<li class="layui-form-item">','<label class="layui-form-label" style="width: 60px;">URL</label>','<div class="layui-input-block" style="margin-left: 90px">','<input name="url" lay-verify="url" value="'+(t.href||"")+'" autofocus="true" autocomplete="off" class="layui-input">',"</div>","</li>",'<li class="layui-form-item">','<label class="layui-form-label" style="width: 60px;">打开方式</label>','<div class="layui-input-block" style="margin-left: 90px">','<input type="radio" name="target" value="_self" class="layui-input" title="当前窗口"'+("_self"!==t.target&&t.target?"":"checked")+">",'<input type="radio" name="target" value="_blank" class="layui-input" title="新窗口" '+("_blank"===t.target?"checked":"")+">","</div>","</li>",'<li class="layui-form-item" style="text-align: center;">','<button type="button" lay-submit lay-filter="layedit-link-yes" class="layui-btn"> 确定 </button>','<button style="margin-left: 20px;" type="button" class="layui-btn layui-btn-primary"> 取消 </button>',"</li>","</ul>"].join(""),success:function(t,n){var o="submit(layedit-link-yes)";a.render("radio"),t.find(".layui-btn-primary").on("click",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=["[微笑]","[嘻嘻]","[哈哈]","[可爱]","[可怜]","[挖鼻]","[吃惊]","[害羞]","[挤眼]","[闭嘴]","[鄙视]","[爱你]","[泪]","[偷笑]","[亲亲]","[生病]","[太开心]","[白眼]","[右哼哼]","[左哼哼]","[嘘]","[衰]","[委屈]","[吐]","[哈欠]","[抱抱]","[怒]","[疑问]","[馋嘴]","[拜拜]","[思考]","[汗]","[困]","[睡]","[钱]","[失望]","[酷]","[色]","[哼]","[鼓掌]","[晕]","[悲伤]","[抓狂]","[黑线]","[阴险]","[怒骂]","[互粉]","[心]","[伤心]","[猪头]","[熊猫]","[兔子]","[ok]","[耶]","[good]","[NO]","[赞]","[来]","[弱]","[草泥马]","[神马]","[囧]","[浮云]","[给力]","[围观]","[威武]","[奥特曼]","[礼物]","[钟]","[话筒]","[蜡烛]","[蛋糕]"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+"images/face/"+t+".gif"}),e}();return x.hide=x.hide||function(t){"face"!==e(t.target).attr("layedit-event")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title="'+e+'"><img src="'+i+'" alt="'+e+'"></li>')}),'<ul class="layui-clear">'+t.join("")+"</ul>"}(),this,{tips:1,time:0,skin:"layui-box layui-util-face",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(".layui-clear>li").on("click",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off("click",x.hide).on("click",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:"LAY_layedit_code",area:"550px",shade:.05,shadeClose:!0,moveType:1,title:"插入代码",skin:"layui-layer-msg",content:['<ul class="layui-form layui-form-pane" style="margin: 15px;">','<li class="layui-form-item">','<label class="layui-form-label">请选择语言</label>','<div class="layui-input-block">','<select name="lang">','<option value="JavaScript">JavaScript</option>','<option value="HTML">HTML</option>','<option value="CSS">CSS</option>','<option value="Java">Java</option>','<option value="PHP">PHP</option>','<option value="C#">C#</option>','<option value="Python">Python</option>','<option value="Ruby">Ruby</option>','<option value="Go">Go</option>',"</select>","</div>","</li>",'<li class="layui-form-item layui-form-text">','<label class="layui-form-label">代码</label>','<div class="layui-input-block">','<textarea name="code" lay-verify="required" autofocus="true" class="layui-textarea" style="height: 200px;"></textarea>',"</div>","</li>",'<li class="layui-form-item" style="text-align: center;">','<button type="button" lay-submit lay-filter="layedit-code-yes" class="layui-btn"> 确定 </button>','<button style="margin-left: 20px;" type="button" class="layui-btn layui-btn-primary"> 取消 </button>',"</li>","</ul>"].join(""),success:function(l,n){var o="submit(layedit-code-yes)";a.render("select"),l.find(".layui-btn-primary").on("click",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class="layui-icon layedit-tool-html" title="HTML源代码" lay-command="html" layedit-event="html"">&#xe64b;</i><span class="layedit-tool-mid"></span>',strong:'<i class="layui-icon layedit-tool-b" title="加粗" lay-command="Bold" layedit-event="b"">&#xe62b;</i>',italic:'<i class="layui-icon layedit-tool-i" title="斜体" lay-command="italic" layedit-event="i"">&#xe644;</i>',underline:'<i class="layui-icon layedit-tool-u" title="下划线" lay-command="underline" layedit-event="u"">&#xe646;</i>',del:'<i class="layui-icon layedit-tool-d" title="删除线" lay-command="strikeThrough" layedit-event="d"">&#xe64f;</i>',"|":'<span class="layedit-tool-mid"></span>',left:'<i class="layui-icon layedit-tool-left" title="左对齐" lay-command="justifyLeft" layedit-event="left"">&#xe649;</i>',center:'<i class="layui-icon layedit-tool-center" title="居中对齐" lay-command="justifyCenter" layedit-event="center"">&#xe647;</i>',right:'<i class="layui-icon layedit-tool-right" title="右对齐" lay-command="justifyRight" layedit-event="right"">&#xe648;</i>',link:'<i class="layui-icon layedit-tool-link" title="插入链接" layedit-event="link"">&#xe64c;</i>',unlink:'<i class="layui-icon layedit-tool-unlink layui-disabled" title="清除链接" lay-command="unlink" layedit-event="unlink"">&#xe64d;</i>',face:'<i class="layui-icon layedit-tool-face" title="表情" layedit-event="face"">&#xe650;</i>',image:'<i class="layui-icon layedit-tool-image" title="图片" layedit-event="image">&#xe64a;<input type="file" name="file"></i>',code:'<i class="layui-icon layedit-tool-code" title="插入代码" layedit-event="code">&#xe64e;</i>',help:'<i class="layui-icon layedit-tool-help" title="帮助" layedit-event="help">&#xe607;</i>'},w=new c;t(n,w)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/layer.js b/static/plugins/layui/lay/modules/layer.js new file mode 100755 index 0000000..1297c70 --- /dev/null +++ b/static/plugins/layui/lay/modules/layer.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.scripts,t=e[e.length-1],i=t.src;if(!t.getAttribute("merge"))return i.substring(0,i.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function u(){return++c>80?e.console&&console.error("layer.css: Invalid"):void(1989===parseInt(o.getStyle(document.getElementById(f),"width"))?i():setTimeout(u,100))}()}}},r={v:"3.1.0",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"&#x4FE1;&#x606F;",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'<div class="layui-layer-title" style="'+(f?r.title[1]:"")+'">'+(f?r.title[0]:r.title)+"</div>":"";return r.zIndex=s,t([r.shade?'<div class="layui-layer-shade" id="layui-layer-shade'+a+'" times="'+a+'" style="'+("z-index:"+(s-1)+"; ")+'"></div>':"",'<div class="'+l[0]+(" layui-layer-"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?"":" layui-layer-border")+" "+(r.skin||"")+'" id="'+l[0]+a+'" type="'+o.type[r.type]+'" times="'+a+'" showtime="'+r.time+'" conType="'+(e?"object":"string")+'" style="z-index: '+s+"; width:"+r.area[0]+";height:"+r.area[1]+(r.fixed?"":";position:absolute;")+'">'+(e&&2!=r.type?"":u)+'<div id="'+(r.id||"")+'" class="layui-layer-content'+(0==r.type&&r.icon!==-1?" layui-layer-padding":"")+(3==r.type?" layui-layer-loading"+r.icon:"")+'">'+(0==r.type&&r.icon!==-1?'<i class="layui-layer-ico layui-layer-ico'+r.icon+'"></i>':"")+(1==r.type&&e?"":r.content||"")+'</div><span class="layui-layer-setwin">'+function(){var e=c?'<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>':"";return r.closeBtn&&(e+='<a class="layui-layer-ico '+l[7]+" "+l[7]+(r.title?r.closeBtn:4==r.type?"1":"2")+'" href="javascript:;"></a>'),e}()+"</span>"+(r.btn?function(){var e="";"string"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class="'+l[6]+t+'">'+r.btn[t]+"</a>";return'<div class="'+l[6]+" layui-layer-btn-"+(r.btnAlign||"")+'">'+e+"</div>"}():"")+(r.resize?'<span class="layui-layer-resize"></span>':"")+"</div>"],u,i('<div class="layui-layer-move"></div>')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f="object"==typeof s,c=i("body");if(!t.id||!i("#"+t.id)[0]){switch("string"==typeof t.area&&(t.area="auto"===t.area?["",""]:[t.area,""]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn="btn"in t?t.btn:o.btn[0],r.closeAll("dialog");break;case 2:var s=t.content=f?t.content:[t.content||"http://layer.layui.com","auto"];t.content='<iframe scrolling="'+(t.content[1]||"auto")+'" allowtransparency="true" id="'+l[4]+a+'" name="'+l[4]+a+'" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="'+t.content[0]+'"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'<i class="layui-layer-TipsG"></i>',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>u&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'<textarea class="layui-layer-input"'+a+">"+(e.value||"")+"</textarea>":function(){return'<input type="'+(1==e.formType?"password":"text")+'" class="layui-layer-input" value="'+(e.value||"")+'">'}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("&#x6700;&#x591A;&#x8F93;&#x5165;"+(e.maxlength||500)+"&#x4E2A;&#x5B57;&#x6570;",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a='<span class="'+n+'">'+t[0].title+"</span>";i<e;i++)a+="<span>"+t[i].title+"</span>";return a}(),content:'<ul class="layui-layer-tabmain">'+function(){var e=t.length,i=1,a="";if(e>0)for(a='<li class="layui-layer-tabli '+n+'">'+(t[0].content||"no content")+"</li>";i<e;i++)a+='<li class="layui-layer-tabli">'+(t[i].content||"no content")+"</li>";return a}()+"</ul>",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("&#x6CA1;&#x6709;&#x56FE;&#x7247;")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+"px",a[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,isOutAnim:!1,skin:"layui-layer-photos"+c("photos"),content:'<div class="layui-layer-phimg"><img src="'+u[d].src+'" alt="'+(u[d].alt||"")+'" layer-pid="'+u[d].pid+'"><div class="layui-layer-imgsee">'+(u.length>1?'<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>':"")+'<div class="layui-layer-imgbar" style="display:'+(a?"block":"")+'"><span class="layui-layer-imgtit"><a href="javascript:;">'+(u[d].alt||"")+"</a><em>"+s.imgIndex+"/"+u.length+"</em></span></div></div></div>",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;",{time:3e4,btn:["&#x4E0B;&#x4E00;&#x5F20;","&#x4E0D;&#x770B;&#x4E86;"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/laypage.js b/static/plugins/layui/lay/modules/laypage.js new file mode 100755 index 0000000..b90cd68 --- /dev/null +++ b/static/plugins/layui/lay/modules/laypage.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"&#x4E0A;&#x4E00;&#x9875;",a.next="next"in a?a.next:"&#x4E0B;&#x4E00;&#x9875;";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href="javascript:;" class="layui-laypage-prev'+(1==a.curr?" "+r:"")+'" data-page="'+(a.curr-1)+'">'+a.prev+"</a>":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="&#x9996;&#x9875;">'+(a.first||1)+"</a>");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class="layui-laypage-spr">&#x2026;</span>');r<=u;r++)r===a.curr?e.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" '+(/^#/.test(a.theme)?'style="background-color:'+a.theme+';"':"")+"></em><em>"+r+"</em></span>"):e.push('<a href="javascript:;" data-page="'+r+'">'+r+"</a>");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class="layui-laypage-spr">&#x2026;</span>'),0!==t&&e.push('<a href="javascript:;" class="layui-laypage-last" title="&#x5C3E;&#x9875;" data-page="'+a.pages+'">'+(a.last||a.pages)+"</a>")),e.join("")}(),next:function(){return a.next?'<a href="javascript:;" class="layui-laypage-next'+(a.curr==a.pages?" "+r:"")+'" data-page="'+(a.curr+1)+'">'+a.next+"</a>":""}(),count:'<span class="layui-laypage-count">共 '+a.count+" 条</span>",limit:function(){var e=['<span class="layui-laypage-limits"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value="'+n+'"'+(n===a.limit?"selected":"")+">"+n+" 条/页</option>")}),e.join("")+"</select></span>"}(),skip:function(){return['<span class="layui-laypage-skip">&#x5230;&#x7B2C;','<input type="text" min="1" value="'+a.curr+'" class="layui-input">','&#x9875;<button type="button" class="layui-laypage-btn">&#x786e;&#x5b9a;</button>',"</span>"].join("")}()};return['<div class="layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?"molv":a.theme:"default")+'" id="layui-laypage-'+a.index+'">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"</div>"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)"a"===r[o].nodeName.toLowerCase()&&s.on(r[o],"click",function(){var e=0|this.getAttribute("data-page");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/laytpl.js b/static/plugins/layui/lay/modules/laytpl.js new file mode 100755 index 0000000..66307e9 --- /dev/null +++ b/static/plugins/layui/lay/modules/laytpl.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/mobile.js b/static/plugins/layui/lay/modules/mobile.js new file mode 100755 index 0000000..648868d --- /dev/null +++ b/static/plugins/layui/lay/modules/mobile.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define(function(i){i("layui.mobile",layui.v)});layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)});layui.define(function(e){"use strict";var t=(window,document),i="querySelectorAll",n="getElementsByClassName",a=function(e){return t[i](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var i in e)t[i]=e[i];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var o=0,r=["layui-m-layer"],d=function(e){var t=this;t.config=l.extend(e),t.view()};d.prototype.view=function(){var e=this,i=e.config,s=t.createElement("div");e.id=s.id=r[0]+o,s.setAttribute("class",r[0]+" "+r[0]+(i.type||0)),s.setAttribute("index",o);var l=function(){var e="object"==typeof i.title;return i.title?'<h3 style="'+(e?i.title[1]:"")+'">'+(e?i.title[0]:i.title)+"</h3>":""}(),d=function(){"string"==typeof i.btn&&(i.btn=[i.btn]);var e,t=(i.btn||[]).length;return 0!==t&&i.btn?(e='<span yes type="1">'+i.btn[0]+"</span>",2===t&&(e='<span no type="0">'+i.btn[1]+"</span>"+e),'<div class="layui-m-layerbtn">'+e+"</div>"):""}();if(i.fixed||(i.top=i.hasOwnProperty("top")?i.top:100,i.style=i.style||"",i.style+=" top:"+(t.body.scrollTop+i.top)+"px"),2===i.type&&(i.content='<i></i><i class="layui-m-layerload"></i><i></i><p>'+(i.content||"")+"</p>"),i.skin&&(i.anim="up"),"msg"===i.skin&&(i.shade=!1),s.innerHTML=(i.shade?"<div "+("string"==typeof i.shade?'style="'+i.shade+'"':"")+' class="layui-m-layershade"></div>':"")+'<div class="layui-m-layermain" '+(i.fixed?"":'style="position:static;"')+'><div class="layui-m-layersection"><div class="layui-m-layerchild '+(i.skin?"layui-m-layer-"+i.skin+" ":"")+(i.className?i.className:"")+" "+(i.anim?"layui-m-anim-"+i.anim:"")+'" '+(i.style?'style="'+i.style+'"':"")+">"+l+'<div class="layui-m-layercont">'+i.content+"</div>"+d+"</div></div></div>",!i.type||2===i.type){var y=t[n](r[0]+i.type),u=y.length;u>=1&&c.close(y[0].getAttribute("index"))}document.body.appendChild(s);var m=e.elem=a("#"+e.id)[0];i.success&&i.success(m),e.index=o++,e.action(i,m)},d.prototype.action=function(e,t){var i=this;e.time&&(l.timer[i.index]=setTimeout(function(){c.close(i.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),c.close(i.index)):e.yes?e.yes(i.index):c.close(i.index)};if(e.btn)for(var s=t[n]("layui-m-layerbtn")[0].children,o=s.length,r=0;r<o;r++)l.touch(s[r],a);if(e.shade&&e.shadeClose){var d=t[n]("layui-m-layershade")[0];l.touch(d,function(){c.close(i.index,e.end)})}e.end&&(l.end[i.index]=e.end)};var c={v:"2.0 m",index:o,open:function(e){var t=new d(e||{});return t.index},close:function(e){var i=a("#"+r[0]+e)[0];i&&(i.innerHTML="",t.body.removeChild(i),clearTimeout(l.timer[e]),delete l.timer[e],"function"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[n](r[0]),i=0,a=e.length;i<a;i++)c.close(0|e[0].getAttribute("index"))}};e("layer-mobile",c)});layui.define(function(t){var e=function(){function t(t){return null==t?String(t):J[W.call(t)]||"object"}function e(e){return"function"==t(e)}function n(t){return null!=t&&t==t.window}function r(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function i(e){return"object"==t(e)}function o(t){return i(t)&&!n(t)&&Object.getPrototypeOf(t)==Object.prototype}function a(t){var e=!!t&&"length"in t&&t.length,r=T.type(t);return"function"!=r&&!n(t)&&("array"==r||0===e||"number"==typeof e&&e>0&&e-1 in t)}function s(t){return A.call(t,function(t){return null!=t})}function u(t){return t.length>0?T.fn.concat.apply([],t):t}function c(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function l(t){return t in F?F[t]:F[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function f(t,e){return"number"!=typeof e||k[c(t)]?e:e+"px"}function h(t){var e,n;return $[t]||(e=L.createElement(t),L.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),$[t]=n),$[t]}function p(t){return"children"in t?D.call(t.children):T.map(t.childNodes,function(t){if(1==t.nodeType)return t})}function d(t,e){var n,r=t?t.length:0;for(n=0;n<r;n++)this[n]=t[n];this.length=r,this.selector=e||""}function m(t,e,n){for(j in e)n&&(o(e[j])||Q(e[j]))?(o(e[j])&&!o(t[j])&&(t[j]={}),Q(e[j])&&!Q(t[j])&&(t[j]=[]),m(t[j],e[j],n)):e[j]!==E&&(t[j]=e[j])}function v(t,e){return null==e?T(t):T(t).filter(e)}function g(t,n,r,i){return e(n)?n.call(t,r,i):n}function y(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function x(t,e){var n=t.className||"",r=n&&n.baseVal!==E;return e===E?r?n.baseVal:n:void(r?n.baseVal=e:t.className=e)}function b(t){try{return t?"true"==t||"false"!=t&&("null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?T.parseJSON(t):t):t}catch(e){return t}}function w(t,e){e(t);for(var n=0,r=t.childNodes.length;n<r;n++)w(t.childNodes[n],e)}var E,j,T,S,C,N,O=[],P=O.concat,A=O.filter,D=O.slice,L=window.document,$={},F={},k={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},M=/^\s*<(\w+|!)[^>]*>/,R=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Z=/^(?:body|html)$/i,q=/([A-Z])/g,H=["val","css","html","text","data","width","height","offset"],I=["after","prepend","before","append"],V=L.createElement("table"),_=L.createElement("tr"),B={tr:L.createElement("tbody"),tbody:V,thead:V,tfoot:V,td:_,th:_,"*":L.createElement("div")},U=/complete|loaded|interactive/,X=/^[\w-]*$/,J={},W=J.toString,Y={},G=L.createElement("div"),K={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},Q=Array.isArray||function(t){return t instanceof Array};return Y.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var r,i=t.parentNode,o=!i;return o&&(i=G).appendChild(t),r=~Y.qsa(i,e).indexOf(t),o&&G.removeChild(t),r},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return A.call(t,function(e,n){return t.indexOf(e)==n})},Y.fragment=function(t,e,n){var r,i,a;return R.test(t)&&(r=T(L.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(z,"<$1></$2>")),e===E&&(e=M.test(t)&&RegExp.$1),e in B||(e="*"),a=B[e],a.innerHTML=""+t,r=T.each(D.call(a.childNodes),function(){a.removeChild(this)})),o(n)&&(i=T(r),T.each(n,function(t,e){H.indexOf(t)>-1?i[t](e):i.attr(t,e)})),r},Y.Z=function(t,e){return new d(t,e)},Y.isZ=function(t){return t instanceof Y.Z},Y.init=function(t,n){var r;if(!t)return Y.Z();if("string"==typeof t)if(t=t.trim(),"<"==t[0]&&M.test(t))r=Y.fragment(t,RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(L,t)}else{if(e(t))return T(L).ready(t);if(Y.isZ(t))return t;if(Q(t))r=s(t);else if(i(t))r=[t],t=null;else if(M.test(t))r=Y.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(L,t)}}return Y.Z(r,t)},T=function(t,e){return Y.init(t,e)},T.extend=function(t){var e,n=D.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){m(t,n,e)}),t},Y.qsa=function(t,e){var n,r="#"==e[0],i=!r&&"."==e[0],o=r||i?e.slice(1):e,a=X.test(o);return t.getElementById&&a&&r?(n=t.getElementById(o))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:D.call(a&&!r&&t.getElementsByClassName?i?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))},T.contains=L.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},T.type=t,T.isFunction=e,T.isWindow=n,T.isArray=Q,T.isPlainObject=o,T.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},T.isNumeric=function(t){var e=Number(t),n=typeof t;return null!=t&&"boolean"!=n&&("string"!=n||t.length)&&!isNaN(e)&&isFinite(e)||!1},T.inArray=function(t,e,n){return O.indexOf.call(e,t,n)},T.camelCase=C,T.trim=function(t){return null==t?"":String.prototype.trim.call(t)},T.uuid=0,T.support={},T.expr={},T.noop=function(){},T.map=function(t,e){var n,r,i,o=[];if(a(t))for(r=0;r<t.length;r++)n=e(t[r],r),null!=n&&o.push(n);else for(i in t)n=e(t[i],i),null!=n&&o.push(n);return u(o)},T.each=function(t,e){var n,r;if(a(t)){for(n=0;n<t.length;n++)if(e.call(t[n],n,t[n])===!1)return t}else for(r in t)if(e.call(t[r],r,t[r])===!1)return t;return t},T.grep=function(t,e){return A.call(t,e)},window.JSON&&(T.parseJSON=JSON.parse),T.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(t,e){J["[object "+e+"]"]=e.toLowerCase()}),T.fn={constructor:Y.Z,length:0,forEach:O.forEach,reduce:O.reduce,push:O.push,sort:O.sort,splice:O.splice,indexOf:O.indexOf,concat:function(){var t,e,n=[];for(t=0;t<arguments.length;t++)e=arguments[t],n[t]=Y.isZ(e)?e.toArray():e;return P.apply(Y.isZ(this)?this.toArray():this,n)},map:function(t){return T(T.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return T(D.apply(this,arguments))},ready:function(t){return U.test(L.readyState)&&L.body?t(T):L.addEventListener("DOMContentLoaded",function(){t(T)},!1),this},get:function(t){return t===E?D.call(this):this[t>=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return O.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return e(t)?this.not(this.not(t)):T(A.call(this,function(e){return Y.matches(e,t)}))},add:function(t,e){return T(N(this.concat(T(t,e))))},is:function(t){return this.length>0&&Y.matches(this[0],t)},not:function(t){var n=[];if(e(t)&&t.call!==E)this.each(function(e){t.call(this,e)||n.push(this)});else{var r="string"==typeof t?this.filter(t):a(t)&&e(t.item)?D.call(t):T(t);this.forEach(function(t){r.indexOf(t)<0&&n.push(t)})}return T(n)},has:function(t){return this.filter(function(){return i(t)?T.contains(this,t):T(this).find(t).size()})},eq:function(t){return t===-1?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!i(t)?t:T(t)},last:function(){var t=this[this.length-1];return t&&!i(t)?t:T(t)},find:function(t){var e,n=this;return e=t?"object"==typeof t?T(t).filter(function(){var t=this;return O.some.call(n,function(e){return T.contains(e,t)})}):1==this.length?T(Y.qsa(this[0],t)):this.map(function(){return Y.qsa(this,t)}):T()},closest:function(t,e){var n=[],i="object"==typeof t&&T(t);return this.each(function(o,a){for(;a&&!(i?i.indexOf(a)>=0:Y.matches(a,t));)a=a!==e&&!r(a)&&a.parentNode;a&&n.indexOf(a)<0&&n.push(a)}),T(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=T.map(n,function(t){if((t=t.parentNode)&&!r(t)&&e.indexOf(t)<0)return e.push(t),t});return v(e,t)},parent:function(t){return v(N(this.pluck("parentNode")),t)},children:function(t){return v(this.map(function(){return p(this)}),t)},contents:function(){return this.map(function(){return this.contentDocument||D.call(this.childNodes)})},siblings:function(t){return v(this.map(function(t,e){return A.call(p(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return T.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=h(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var n=e(t);if(this[0]&&!n)var r=T(t).get(0),i=r.parentNode||this.length>1;return this.each(function(e){T(this).wrapAll(n?t.call(this,e):i?r.cloneNode(!0):r)})},wrapAll:function(t){if(this[0]){T(this[0]).before(t=T(t));for(var e;(e=t.children()).length;)t=e.first();T(t).append(this)}return this},wrapInner:function(t){var n=e(t);return this.each(function(e){var r=T(this),i=r.contents(),o=n?t.call(this,e):t;i.length?i.wrapAll(o):r.append(o)})},unwrap:function(){return this.parent().each(function(){T(this).replaceWith(T(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(t){return this.each(function(){var e=T(this);(t===E?"none"==e.css("display"):t)?e.show():e.hide()})},prev:function(t){return T(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return T(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var n=this.innerHTML;T(this).empty().append(g(this,t,e,n))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=g(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this.pluck("textContent").join(""):null},attr:function(t,e){var n;return"string"!=typeof t||1 in arguments?this.each(function(n){if(1===this.nodeType)if(i(t))for(j in t)y(this,j,t[j]);else y(this,t,g(this,e,n,this.getAttribute(t)))}):0 in this&&1==this[0].nodeType&&null!=(n=this[0].getAttribute(t))?n:E},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(" ").forEach(function(t){y(this,t)},this)})},prop:function(t,e){return t=K[t]||t,1 in arguments?this.each(function(n){this[t]=g(this,e,n,this[t])}):this[0]&&this[0][t]},removeProp:function(t){return t=K[t]||t,this.each(function(){delete this[t]})},data:function(t,e){var n="data-"+t.replace(q,"-$1").toLowerCase(),r=1 in arguments?this.attr(n,e):this.attr(n);return null!==r?b(r):E},val:function(t){return 0 in arguments?(null==t&&(t=""),this.each(function(e){this.value=g(this,t,e,this.value)})):this[0]&&(this[0].multiple?T(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var n=T(this),r=g(this,t,e,n.offset()),i=n.offsetParent().offset(),o={top:r.top-i.top,left:r.left-i.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)});if(!this.length)return null;if(L.documentElement!==this[0]&&!T.contains(L.documentElement,this[0]))return{top:0,left:0};var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(e,n){if(arguments.length<2){var r=this[0];if("string"==typeof e){if(!r)return;return r.style[C(e)]||getComputedStyle(r,"").getPropertyValue(e)}if(Q(e)){if(!r)return;var i={},o=getComputedStyle(r,"");return T.each(e,function(t,e){i[e]=r.style[C(e)]||o.getPropertyValue(e)}),i}}var a="";if("string"==t(e))n||0===n?a=c(e)+":"+f(e,n):this.each(function(){this.style.removeProperty(c(e))});else for(j in e)e[j]||0===e[j]?a+=c(j)+":"+f(j,e[j])+";":this.each(function(){this.style.removeProperty(c(j))});return this.each(function(){this.style.cssText+=";"+a})},index:function(t){return t?this.indexOf(T(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&O.some.call(this,function(t){return this.test(x(t))},l(t))},addClass:function(t){return t?this.each(function(e){if("className"in this){S=[];var n=x(this),r=g(this,t,e,n);r.split(/\s+/g).forEach(function(t){T(this).hasClass(t)||S.push(t)},this),S.length&&x(this,n+(n?" ":"")+S.join(" "))}}):this},removeClass:function(t){return this.each(function(e){if("className"in this){if(t===E)return x(this,"");S=x(this),g(this,t,e,S).split(/\s+/g).forEach(function(t){S=S.replace(l(t)," ")}),x(this,S.trim())}})},toggleClass:function(t,e){return t?this.each(function(n){var r=T(this),i=g(this,t,n,x(this));i.split(/\s+/g).forEach(function(t){(e===E?!r.hasClass(t):e)?r.addClass(t):r.removeClass(t)})}):this},scrollTop:function(t){if(this.length){var e="scrollTop"in this[0];return t===E?e?this[0].scrollTop:this[0].pageYOffset:this.each(e?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var e="scrollLeft"in this[0];return t===E?e?this[0].scrollLeft:this[0].pageXOffset:this.each(e?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),r=Z.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(T(t).css("margin-top"))||0,n.left-=parseFloat(T(t).css("margin-left"))||0,r.top+=parseFloat(T(e[0]).css("border-top-width"))||0,r.left+=parseFloat(T(e[0]).css("border-left-width"))||0,{top:n.top-r.top,left:n.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||L.body;t&&!Z.test(t.nodeName)&&"static"==T(t).css("position");)t=t.offsetParent;return t})}},T.fn.detach=T.fn.remove,["width","height"].forEach(function(t){var e=t.replace(/./,function(t){return t[0].toUpperCase()});T.fn[t]=function(i){var o,a=this[0];return i===E?n(a)?a["inner"+e]:r(a)?a.documentElement["scroll"+e]:(o=this.offset())&&o[t]:this.each(function(e){a=T(this),a.css(t,g(this,i,e,a[t]()))})}}),I.forEach(function(e,n){var r=n%2;T.fn[e]=function(){var e,i,o=T.map(arguments,function(n){var r=[];return e=t(n),"array"==e?(n.forEach(function(t){return t.nodeType!==E?r.push(t):T.zepto.isZ(t)?r=r.concat(t.get()):void(r=r.concat(Y.fragment(t)))}),r):"object"==e||null==n?n:Y.fragment(n)}),a=this.length>1;return o.length<1?this:this.each(function(t,e){i=r?e:e.parentNode,e=0==n?e.nextSibling:1==n?e.firstChild:2==n?e:null;var s=T.contains(L.documentElement,i);o.forEach(function(t){if(a)t=t.cloneNode(!0);else if(!i)return T(t).remove();i.insertBefore(t,e),s&&w(t,function(t){if(!(null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src)){var e=t.ownerDocument?t.ownerDocument.defaultView:window;e.eval.call(e,t.innerHTML)}})})})},T.fn[r?e+"To":"insert"+(n?"Before":"After")]=function(t){return T(t)[e](this),this}}),Y.Z.prototype=d.prototype=T.fn,Y.uniq=N,Y.deserializeValue=b,T.zepto=Y,T}();!function(t){function e(t){return t._zid||(t._zid=h++)}function n(t,n,o,a){if(n=r(n),n.ns)var s=i(n.ns);return(v[e(t)]||[]).filter(function(t){return t&&(!n.e||t.e==n.e)&&(!n.ns||s.test(t.ns))&&(!o||e(t.fn)===e(o))&&(!a||t.sel==a)})}function r(t){var e=(""+t).split(".");return{e:e[0],ns:e.slice(1).sort().join(" ")}}function i(t){return new RegExp("(?:^| )"+t.replace(" "," .* ?")+"(?: |$)")}function o(t,e){return t.del&&!y&&t.e in x||!!e}function a(t){return b[t]||y&&x[t]||t}function s(n,i,s,u,l,h,p){var d=e(n),m=v[d]||(v[d]=[]);i.split(/\s/).forEach(function(e){if("ready"==e)return t(document).ready(s);var i=r(e);i.fn=s,i.sel=l,i.e in b&&(s=function(e){var n=e.relatedTarget;if(!n||n!==this&&!t.contains(this,n))return i.fn.apply(this,arguments)}),i.del=h;var d=h||s;i.proxy=function(t){if(t=c(t),!t.isImmediatePropagationStopped()){t.data=u;var e=d.apply(n,t._args==f?[t]:[t].concat(t._args));return e===!1&&(t.preventDefault(),t.stopPropagation()),e}},i.i=m.length,m.push(i),"addEventListener"in n&&n.addEventListener(a(i.e),i.proxy,o(i,p))})}function u(t,r,i,s,u){var c=e(t);(r||"").split(/\s/).forEach(function(e){n(t,e,i,s).forEach(function(e){delete v[c][e.i],"removeEventListener"in t&&t.removeEventListener(a(e.e),e.proxy,o(e,u))})})}function c(e,n){return!n&&e.isDefaultPrevented||(n||(n=e),t.each(T,function(t,r){var i=n[t];e[t]=function(){return this[r]=w,i&&i.apply(n,arguments)},e[r]=E}),e.timeStamp||(e.timeStamp=Date.now()),(n.defaultPrevented!==f?n.defaultPrevented:"returnValue"in n?n.returnValue===!1:n.getPreventDefault&&n.getPreventDefault())&&(e.isDefaultPrevented=w)),e}function l(t){var e,n={originalEvent:t};for(e in t)j.test(e)||t[e]===f||(n[e]=t[e]);return c(n,t)}var f,h=1,p=Array.prototype.slice,d=t.isFunction,m=function(t){return"string"==typeof t},v={},g={},y="onfocusin"in window,x={focus:"focusin",blur:"focusout"},b={mouseenter:"mouseover",mouseleave:"mouseout"};g.click=g.mousedown=g.mouseup=g.mousemove="MouseEvents",t.event={add:s,remove:u},t.proxy=function(n,r){var i=2 in arguments&&p.call(arguments,2);if(d(n)){var o=function(){return n.apply(r,i?i.concat(p.call(arguments)):arguments)};return o._zid=e(n),o}if(m(r))return i?(i.unshift(n[r],n),t.proxy.apply(null,i)):t.proxy(n[r],n);throw new TypeError("expected function")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,r){return this.on(t,e,n,r,1)};var w=function(){return!0},E=function(){return!1},j=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,T={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,n,r,i,o){var a,c,h=this;return e&&!m(e)?(t.each(e,function(t,e){h.on(t,n,r,e,o)}),h):(m(n)||d(i)||i===!1||(i=r,r=n,n=f),i!==f&&r!==!1||(i=r,r=f),i===!1&&(i=E),h.each(function(f,h){o&&(a=function(t){return u(h,t.type,i),i.apply(this,arguments)}),n&&(c=function(e){var r,o=t(e.target).closest(n,h).get(0);if(o&&o!==h)return r=t.extend(l(e),{currentTarget:o,liveFired:h}),(a||i).apply(o,[r].concat(p.call(arguments,1)))}),s(h,e,i,r,n,c||a)}))},t.fn.off=function(e,n,r){var i=this;return e&&!m(e)?(t.each(e,function(t,e){i.off(t,n,e)}),i):(m(n)||d(r)||r===!1||(r=n,n=f),r===!1&&(r=E),i.each(function(){u(this,e,r,n)}))},t.fn.trigger=function(e,n){return e=m(e)||t.isPlainObject(e)?t.Event(e):c(e),e._args=n,this.each(function(){e.type in x&&"function"==typeof this[e.type]?this[e.type]():"dispatchEvent"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,r){var i,o;return this.each(function(a,s){i=l(m(e)?t.Event(e):e),i._args=r,i.target=s,t.each(n(s,e.type||e),function(t,e){if(o=e.proxy(i),i.isImmediatePropagationStopped())return!1})}),o},"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){m(t)||(e=t,t=e.type);var n=document.createEvent(g[t]||"Events"),r=!0;if(e)for(var i in e)"bubbles"==i?r=!!e[i]:n[i]=e[i];return n.initEvent(t,r,!0),c(n)}}(e),function(t){function e(e,n,r){var i=t.Event(n);return t(e).trigger(i,r),!i.isDefaultPrevented()}function n(t,n,r,i){if(t.global)return e(n||x,r,i)}function r(e){e.global&&0===t.active++&&n(e,null,"ajaxStart")}function i(e){e.global&&!--t.active&&n(e,null,"ajaxStop")}function o(t,e){var r=e.context;return e.beforeSend.call(r,t,e)!==!1&&n(e,r,"ajaxBeforeSend",[t,e])!==!1&&void n(e,r,"ajaxSend",[t,e])}function a(t,e,r,i){var o=r.context,a="success";r.success.call(o,t,a,e),i&&i.resolveWith(o,[t,a,e]),n(r,o,"ajaxSuccess",[e,r,t]),u(a,e,r)}function s(t,e,r,i,o){var a=i.context;i.error.call(a,r,e,t),o&&o.rejectWith(a,[r,e,t]),n(i,a,"ajaxError",[r,i,t||e]),u(e,r,i)}function u(t,e,r){var o=r.context;r.complete.call(o,e,t),n(r,o,"ajaxComplete",[e,r]),i(r)}function c(t,e,n){if(n.dataFilter==l)return t;var r=n.context;return n.dataFilter.call(r,t,e)}function l(){}function f(t){return t&&(t=t.split(";",2)[0]),t&&(t==T?"html":t==j?"json":w.test(t)?"script":E.test(t)&&"xml")||"text"}function h(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function p(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()&&"jsonp"!=e.dataType||(e.url=h(e.url,e.data),e.data=void 0)}function d(e,n,r,i){return t.isFunction(n)&&(i=r,r=n,n=void 0),t.isFunction(r)||(i=r,r=void 0),{url:e,data:n,success:r,dataType:i}}function m(e,n,r,i){var o,a=t.isArray(n),s=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),i&&(n=r?i:i+"["+(s||"object"==o||"array"==o?n:"")+"]"),!i&&a?e.add(u.name,u.value):"array"==o||!r&&"object"==o?m(e,u,r,n):e.add(n,u)})}var v,g,y=+new Date,x=window.document,b=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,w=/^(?:text|application)\/javascript/i,E=/^(?:text|application)\/xml/i,j="application/json",T="text/html",S=/^\s*$/,C=x.createElement("a");C.href=window.location.href,t.active=0,t.ajaxJSONP=function(e,n){if(!("type"in e))return t.ajax(e);var r,i,u=e.jsonpCallback,c=(t.isFunction(u)?u():u)||"Zepto"+y++,l=x.createElement("script"),f=window[c],h=function(e){t(l).triggerHandler("error",e||"abort")},p={abort:h};return n&&n.promise(p),t(l).on("load error",function(o,u){clearTimeout(i),t(l).off().remove(),"error"!=o.type&&r?a(r[0],p,e,n):s(null,u||"error",p,e,n),window[c]=f,r&&t.isFunction(f)&&f(r[0]),f=r=void 0}),o(p,e)===!1?(h("abort"),p):(window[c]=function(){r=arguments},l.src=e.url.replace(/\?(.+)=\?/,"?$1="+c),x.head.appendChild(l),e.timeout>0&&(i=setTimeout(function(){h("timeout")},e.timeout)),p)},t.ajaxSettings={type:"GET",beforeSend:l,success:l,error:l,complete:l,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:j,xml:"application/xml, text/xml",html:T,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0,dataFilter:l},t.ajax=function(e){var n,i,u=t.extend({},e||{}),d=t.Deferred&&t.Deferred();for(v in t.ajaxSettings)void 0===u[v]&&(u[v]=t.ajaxSettings[v]);r(u),u.crossDomain||(n=x.createElement("a"),n.href=u.url,n.href=n.href,u.crossDomain=C.protocol+"//"+C.host!=n.protocol+"//"+n.host),u.url||(u.url=window.location.toString()),(i=u.url.indexOf("#"))>-1&&(u.url=u.url.slice(0,i)),p(u);var m=u.dataType,y=/\?.+=\?/.test(u.url);if(y&&(m="jsonp"),u.cache!==!1&&(e&&e.cache===!0||"script"!=m&&"jsonp"!=m)||(u.url=h(u.url,"_="+Date.now())),"jsonp"==m)return y||(u.url=h(u.url,u.jsonp?u.jsonp+"=?":u.jsonp===!1?"":"callback=?")),t.ajaxJSONP(u,d);var b,w=u.accepts[m],E={},j=function(t,e){E[t.toLowerCase()]=[t,e]},T=/^([\w-]+:)\/\//.test(u.url)?RegExp.$1:window.location.protocol,N=u.xhr(),O=N.setRequestHeader;if(d&&d.promise(N),u.crossDomain||j("X-Requested-With","XMLHttpRequest"),j("Accept",w||"*/*"),(w=u.mimeType||w)&&(w.indexOf(",")>-1&&(w=w.split(",",2)[0]),N.overrideMimeType&&N.overrideMimeType(w)),(u.contentType||u.contentType!==!1&&u.data&&"GET"!=u.type.toUpperCase())&&j("Content-Type",u.contentType||"application/x-www-form-urlencoded"),u.headers)for(g in u.headers)j(g,u.headers[g]);if(N.setRequestHeader=j,N.onreadystatechange=function(){if(4==N.readyState){N.onreadystatechange=l,clearTimeout(b);var e,n=!1;if(N.status>=200&&N.status<300||304==N.status||0==N.status&&"file:"==T){if(m=m||f(u.mimeType||N.getResponseHeader("content-type")),"arraybuffer"==N.responseType||"blob"==N.responseType)e=N.response;else{e=N.responseText;try{e=c(e,m,u),"script"==m?(0,eval)(e):"xml"==m?e=N.responseXML:"json"==m&&(e=S.test(e)?null:t.parseJSON(e))}catch(r){n=r}if(n)return s(n,"parsererror",N,u,d)}a(e,N,u,d)}else s(N.statusText||null,N.status?"error":"abort",N,u,d)}},o(N,u)===!1)return N.abort(),s(null,"abort",N,u,d),N;var P=!("async"in u)||u.async;if(N.open(u.type,u.url,P,u.username,u.password),u.xhrFields)for(g in u.xhrFields)N[g]=u.xhrFields[g];for(g in E)O.apply(N,E[g]);return u.timeout>0&&(b=setTimeout(function(){N.onreadystatechange=l,N.abort(),s(null,"timeout",N,u,d)},u.timeout)),N.send(u.data?u.data:null),N},t.get=function(){return t.ajax(d.apply(null,arguments))},t.post=function(){var e=d.apply(null,arguments);return e.type="POST",t.ajax(e)},t.getJSON=function(){var e=d.apply(null,arguments);return e.dataType="json",t.ajax(e)},t.fn.load=function(e,n,r){if(!this.length)return this;var i,o=this,a=e.split(/\s/),s=d(e,n,r),u=s.success;return a.length>1&&(s.url=a[0],i=a[1]),s.success=function(e){o.html(i?t("<div>").html(e.replace(b,"")).find(i):e),u&&u.apply(o,arguments)},t.ajax(s),this};var N=encodeURIComponent;t.param=function(e,n){var r=[];return r.add=function(e,n){t.isFunction(n)&&(n=n()),null==n&&(n=""),this.push(N(e)+"="+N(n))},m(r,e,n),r.join("&").replace(/%20/g,"+")}}(e),function(t){t.fn.serializeArray=function(){var e,n,r=[],i=function(t){return t.forEach?t.forEach(i):void r.push({name:e,value:t})};return this[0]&&t.each(this[0].elements,function(r,o){n=o.type,e=o.name,e&&"fieldset"!=o.nodeName.toLowerCase()&&!o.disabled&&"submit"!=n&&"reset"!=n&&"button"!=n&&"file"!=n&&("radio"!=n&&"checkbox"!=n||o.checked)&&i(t(o).val())}),r},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value))}),t.join("&")},t.fn.submit=function(e){if(0 in arguments)this.bind("submit",e);else if(this.length){var n=t.Event("submit");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(e),function(){try{getComputedStyle(void 0)}catch(t){var e=getComputedStyle;window.getComputedStyle=function(t,n){try{return e(t,n)}catch(r){return null}}}}(),t("zepto",e)});layui.define(["layer-mobile","zepto"],function(e){"use strict";var t=layui.zepto,a=layui["layer-mobile"],i=(layui.device(),"layui-upload-enter"),n="layui-upload-iframe",r={icon:2,shift:6},o={file:"文件",video:"视频",audio:"音频"};a.msg=function(e){return a.open({content:e||"",skin:"msg",time:2})};var s=function(e){this.options=e};s.prototype.init=function(){var e=this,a=e.options,r=t("body"),s=t(a.elem||".layui-upload-file"),u=t('<iframe id="'+n+'" class="'+n+'" name="'+n+'"></iframe>');return t("#"+n)[0]||r.append(u),s.each(function(r,s){s=t(s);var u='<form target="'+n+'" method="'+(a.method||"post")+'" key="set-mine" enctype="multipart/form-data" action="'+(a.url||"")+'"></form>',l=s.attr("lay-type")||a.type;a.unwrap||(u='<div class="layui-box layui-upload-button">'+u+'<span class="layui-upload-icon"><i class="layui-icon">&#xe608;</i>'+(s.attr("lay-title")||a.title||"上传"+(o[l]||"图片"))+"</span></div>"),u=t(u),a.unwrap||u.on("dragover",function(e){e.preventDefault(),t(this).addClass(i)}).on("dragleave",function(){t(this).removeClass(i)}).on("drop",function(){t(this).removeClass(i)}),s.parent("form").attr("target")===n&&(a.unwrap?s.unwrap():(s.parent().next().remove(),s.unwrap().unwrap())),s.wrap(u),s.off("change").on("change",function(){e.action(this,l)})})},s.prototype.action=function(e,i){var o=this,s=o.options,u=e.value,l=t(e),p=l.attr("lay-ext")||s.ext||"";if(u){switch(i){case"file":if(p&&!RegExp("\\w\\.("+p+")$","i").test(escape(u)))return a.msg("不支持该文件格式",r),e.value="";break;case"video":if(!RegExp("\\w\\.("+(p||"avi|mp4|wma|rmvb|rm|flash|3gp|flv")+")$","i").test(escape(u)))return a.msg("不支持该视频格式",r),e.value="";break;case"audio":if(!RegExp("\\w\\.("+(p||"mp3|wav|mid")+")$","i").test(escape(u)))return a.msg("不支持该音频格式",r),e.value="";break;default:if(!RegExp("\\w\\.("+(p||"jpg|png|gif|bmp|jpeg")+")$","i").test(escape(u)))return a.msg("不支持该图片格式",r),e.value=""}s.before&&s.before(e),l.parent().submit();var c=t("#"+n),f=setInterval(function(){var t;try{t=c.contents().find("body").text()}catch(i){a.msg("上传接口存在跨域",r),clearInterval(f)}if(t){clearInterval(f),c.contents().find("body").html("");try{t=JSON.parse(t)}catch(i){return t={},a.msg("请对上传接口返回JSON字符",r)}"function"==typeof s.success&&s.success(t,e)}},30);e.value=""}},e("upload-mobile",function(e){var t=new s(e=e||{});t.init()})});layui.define(function(i){i("layim-mobile",layui.v)});layui["layui.mobile"]||layui.config({base:layui.cache.dir+"lay/modules/mobile/"}).extend({"layer-mobile":"layer-mobile",zepto:"zepto","upload-mobile":"upload-mobile","layim-mobile":"layim-mobile"}),layui.define(["layer-mobile","zepto","layim-mobile"],function(l){l("mobile",{layer:layui["layer-mobile"],layim:layui["layim-mobile"]})}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/table.js b/static/plugins/layui/lay/modules/table.js new file mode 100755 index 0000000..cb6a3a5 --- /dev/null +++ b/static/plugins/layui/lay/modules/table.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define(["laytpl","laypage","layer","form"],function(e){"use strict";var t=layui.$,i=layui.laytpl,a=layui.laypage,l=layui.layer,n=layui.form,o=layui.hint(),r=layui.device(),d={config:{checkName:"LAY_CHECKED",indexName:"LAY_TABLE_INDEX"},cache:{},index:layui.table?layui.table.index+1e4:0,set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,s,e,t)}},c=function(){var e=this,t=e.config,i=t.id;return i&&(c.config[i]=t),{reload:function(t){e.reload.call(e,t)},config:t}},s="table",u=".layui-table",f="layui-hide",h="layui-none",y="layui-table-view",p=".layui-table-header",m=".layui-table-body",v=".layui-table-main",g=".layui-table-fixed",x=".layui-table-fixed-l",b=".layui-table-fixed-r",k=".layui-table-tool",C=".layui-table-sort",w="layui-table-edit",N="layui-table-hover",z=function(e){return e=e||{},['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" ','{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',"<thead>","{{# layui.each(d.data.cols, function(i1, item1){ }}","<tr>","{{# layui.each(item1, function(i2, item2){ }}",'{{# if(item2.fixed && item2.fixed !== "right"){ left = true; } }}','{{# if(item2.fixed === "right"){ right = true; } }}',function(){return e.fixed&&"right"!==e.fixed?'{{# if(item2.fixed && item2.fixed !== "right"){ }}':"right"===e.fixed?'{{# if(item2.fixed === "right"){ }}':""}(),"{{# if(item2.checkbox){ }}",'<th data-field="{{ item2.field||i2 }}" data-type="checkbox" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} unresize="true"><div class="layui-table-cell laytable-cell-checkbox"><input type="checkbox" name="layTableCheckbox" lay-skin="primary" lay-filter="layTableAllChoose" {{# if(item2[d.data.checkName]){ }}checked{{# }; }}></div></th>',"{{# } else if(item2.space){ }}",'<th data-field="{{ item2.field||i2 }}" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} unresize="true"><div class="layui-table-cell laytable-cell-space"></div></th>',"{{# } else { }}",'<th data-field="{{ item2.field||i2 }}" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} {{# if(item2.unresize){ }}unresize="true"{{# } }}>',"{{# if(item2.colspan > 1){ }}",'<div class="layui-table-cell laytable-cell-group" {{#if(item2.align){}}align="{{item2.align}}"{{#}}}>','<span>{{item2.title||""}}</span>',"</div>","{{# } else { }}",'<div class="layui-table-cell laytable-cell-{{d.index}}-{{item2.field||i2}}" {{#if(item2.align){}}align="{{item2.align}}"{{#}}}>','<span>{{item2.title||""}}</span>',"{{# if(item2.sort){ }}",'<span class="layui-table-sort layui-inline"><i class="layui-edge layui-table-sort-asc"></i><i class="layui-edge layui-table-sort-desc"></i></span>',"{{# } }}","</div>","{{# } }}","</th>","{{# }; }}",e.fixed?"{{# }; }}":"","{{# }); }}","</tr>","{{# }); }}","</thead>","</table>"].join("")},F=['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" ','{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',"<tbody></tbody>","</table>"].join(""),T=['<div class="layui-form layui-border-box {{d.VIEW_CLASS}}" lay-filter="LAY-table-{{d.index}}" style="{{# if(d.data.width){ }}width:{{d.data.width}}px;{{# } }} {{# if(d.data.height){ }}height:{{d.data.height}}px;{{# } }}">',"{{# var left, right; }}",'<div class="layui-table-header">',z(),"</div>",'<div class="layui-table-body layui-table-main">',F,"</div>","{{# if(left){ }}",'<div class="layui-table-fixed layui-table-fixed-l">','<div class="layui-table-header">',z({fixed:!0}),"</div>",'<div class="layui-table-body">',F,"</div>","</div>","{{# }; }}","{{# if(right){ }}",'<div class="layui-table-fixed layui-table-fixed-r">','<div class="layui-table-header">',z({fixed:"right"}),'<div class="layui-table-mend"></div>',"</div>",'<div class="layui-table-body">',F,"</div>","</div>","{{# }; }}","{{# if(d.data.page){ }}",'<div class="layui-table-tool">','<div class="layui-inline layui-table-page" id="layui-table-page{{d.index}}"></div>',"</div>","{{# } }}","<style>","{{# layui.each(d.data.cols, function(i1, item1){","layui.each(item1, function(i2, item2){ }}",".laytable-cell-{{d.index}}-{{item2.field||i2}}{ width:{{item2.width||50}}px }","{{# });","}); }}","</style>","</div>"].join(""),L=t(window),S=t(document),H=function(e){var i=this;i.index=++d.index,i.config=t.extend({},i.config,d.config,e),i.render()};H.prototype.config={limit:30,loading:!0},H.prototype.render=function(e){var a,l=this;if(e&&(l.config=e),a=l.config,a.elem=t(a.elem),a.where=a.where||{},a.request=t.extend({pageName:"page",limitName:"limit"},a.request),a.response=t.extend({statusName:"code",statusCode:0,msgName:"msg",dataName:"data",countName:"count"},a.response),!a.elem[0])return l;var n=a.elem,o=n.next("."+y);a.height&&/^full-\d+$/.test(a.height)&&(l.fullHeightGap=a.height.split("-")[1],a.height=L.height()-l.fullHeightGap);var r=l.elem=t(i(T).render({VIEW_CLASS:y,data:a,index:l.index}));if(a.index=l.index,o[0]&&o.remove(),n.after(r),l.layHeader=r.find(p),l.layMain=r.find(v),l.layBody=r.find(m),l.layFixed=r.find(g),l.layFixLeft=r.find(x),l.layFixRight=r.find(b),l.layTool=r.find(k),a.height&&l.fullSize(),a.cols.length>1){var d=l.layFixed.find(p).find("th");d.height(l.layHeader.height()-1-parseFloat(d.css("padding-top"))-parseFloat(d.css("padding-bottom")))}l.pullData(1),l.events()},H.prototype.reload=function(e){var i=this;i.config=t.extend({},i.config,e),i.render()},H.prototype.pullData=function(e,i){var a=this,n=a.config,o=n.request,r=n.response,d=function(){"object"==typeof n.initSort&&a.sort(n.initSort.field,n.initSort.type)};if(n.url){var c={};c[o.pageName]=e,c[o.limitName]=n.limit,t.ajax({type:n.method||"get",url:n.url,data:t.extend(c,n.where),dataType:"json",success:function(t){return t[r.statusName]!=r.statusCode?(a.renderForm(),a.layMain.html('<div class="'+h+'">'+(t[r.msgName]||"返回的数据状态异常")+"</div>")):(a.renderData(t,e,t[r.countName]),d(),i&&l.close(i),void("function"==typeof n.done&&n.done(t,e,t[r.countName])))},error:function(e,t){a.layMain.html('<div class="'+h+'">数据接口请求异常</div>'),a.renderForm(),i&&l.close(i)}})}else if(n.data&&n.data.constructor===Array){var s={},u=e*n.limit-n.limit;s[r.dataName]=n.data.concat().splice(u,n.limit),s[r.countName]=n.data.length,a.renderData(s,e,n.data.length),d(),"function"==typeof n.done&&n.done(s,e,s[r.countName])}},H.prototype.page=1,H.prototype.eachCols=function(e){var i=t.extend(!0,[],this.config.cols),a=[],l=0;layui.each(i,function(e,t){layui.each(t,function(t,n){if(n.colspan>1){var o=0;l++,n.CHILD_COLS=[],layui.each(i[e+1],function(e,t){t.PARENT_COL||o==n.colspan||(t.PARENT_COL=l,n.CHILD_COLS.push(t),o+=t.colspan>1?t.colspan:1)})}n.PARENT_COL||a.push(n)})});var n=function(t){layui.each(t||a,function(t,i){return i.CHILD_COLS?n(i.CHILD_COLS):void e(t,i)})};n()},H.prototype.renderData=function(e,n,o,r){var c=this,s=c.config,u=e[s.response.dataName]||[],f=[],y=[],p=[],m=function(){return!r&&c.sortKey?c.sort(c.sortKey.field,c.sortKey.sort,!0):(layui.each(u,function(e,a){var l=[],n=[],o=[];0!==a.length&&(r||(a[d.config.indexName]=e),c.eachCols(function(e,r){var c=a[r.field||e];if(void 0!==c&&null!==c||(c=""),!(r.colspan>1)){var u=['<td data-field="'+(r.field||e)+'"'+function(){var e=[];return r.edit&&e.push(' data-edit="true"'),r.align&&e.push(' align="'+r.align+'"'),r.templet&&e.push(' data-content="'+c+'"'),r.toolbar&&e.push(' data-off="true"'),r.event&&e.push(' lay-event="'+r.event+'"'),r.style&&e.push(' style="'+r.style+'"'),e.join("")}()+">",'<div class="layui-table-cell laytable-cell-'+function(){return r.checkbox?"checkbox":r.space?"space":s.index+"-"+(r.field||e)}()+'">'+function(){return r.checkbox?'<input type="checkbox" name="layTableCheckbox" lay-skin="primary" '+function(){var e=d.config.checkName;return r[e]?(a[e]=r[e],r[e]?"checked":""):a[e]?"checked":""}()+">":r.toolbar?i(t(r.toolbar).html()||"").render(a):r.templet?i(t(r.templet).html()||String(c)).render(a):c}(),"</div></td>"].join("");l.push(u),r.fixed&&"right"!==r.fixed&&n.push(u),"right"===r.fixed&&o.push(u)}}),f.push('<tr data-index="'+e+'">'+l.join("")+"</tr>"),y.push('<tr data-index="'+e+'">'+n.join("")+"</tr>"),p.push('<tr data-index="'+e+'">'+o.join("")+"</tr>"))}),c.layBody.scrollTop(0),c.layMain.find("."+h).remove(),c.layMain.find("tbody").html(f.join("")),c.layFixLeft.find("tbody").html(y.join("")),c.layFixRight.find("tbody").html(p.join("")),c.renderForm(),c.syncCheckAll(),c.haveInit?c.scrollPatch():setTimeout(function(){c.scrollPatch()},50),c.haveInit=!0,void l.close(c.tipsIndex))};return c.key=s.id||s.index,d.cache[c.key]=u,r?m():0===u.length?(c.renderForm(),c.layFixed.remove(),c.layMain.find("tbody").html(""),c.layMain.find("."+h).remove(),c.layMain.append('<div class="'+h+'">无数据</div>')):(m(),void(s.page&&(c.page=n,c.count=o,a.render({elem:"layui-table-page"+s.index,count:o,groups:3,limits:s.limits||[10,20,30,40,50,60,70,80,90],limit:s.limit,curr:n,layout:["prev","page","next","skip","count","limit"],prev:'<i class="layui-icon">&#xe603;</i>',next:'<i class="layui-icon">&#xe602;</i>',jump:function(e,t){t||(c.page=e.curr,s.limit=e.limit,c.pullData(e.curr,c.loading()))}}),c.layTool.find(".layui-table-count span").html(o))))},H.prototype.renderForm=function(e){n.render(e||"checkbox","LAY-table-"+this.index)},H.prototype.sort=function(e,i,a,n){var r,c,u=this,f={},h=u.config,y=h.elem.attr("lay-filter"),p=d.cache[u.key];"string"==typeof e&&u.layHeader.find("th").each(function(i,a){var l=t(this),n=l.data("field");if(n===e)return e=l,r=n,!1});try{var r=r||e.data("field");if(u.sortKey&&!a&&r===u.sortKey.field&&i===u.sortKey.sort)return;var m=u.layHeader.find("th .laytable-cell-"+h.index+"-"+r).find(C);u.layHeader.find("th").find(C).removeAttr("lay-sort"),m.attr("lay-sort",i||null),u.layFixed.find("th")}catch(v){return o.error("Table modules: Did not match to field")}u.sortKey={field:r,sort:i},"asc"===i?c=layui.sort(p,r):"desc"===i?c=layui.sort(p,r,!0):(c=layui.sort(p,d.config.indexName),delete u.sortKey),f[h.response.dataName]=c,u.renderData(f,u.page,u.count,!0),l.close(u.tipsIndex),n&&layui.event.call(e,s,"sort("+y+")",{field:r,type:i})},H.prototype.loading=function(){var e=this,t=e.config;if(t.loading&&t.url)return l.msg("数据请求中",{icon:16,offset:[e.elem.offset().top+e.elem.height()/2-35-L.scrollTop()+"px",e.elem.offset().left+e.elem.width()/2-90-L.scrollLeft()+"px"],anim:-1,fixed:!1})},H.prototype.setCheckData=function(e,t){var i=this,a=i.config,l=d.cache[i.key];l[e]&&(l[e][a.checkName]=t)},H.prototype.syncCheckAll=function(){var e=this,t=e.config,i=e.layHeader.find('input[name="layTableCheckbox"]'),a=function(i){return e.eachCols(function(e,a){a.checkbox&&(a[t.checkName]=i)}),i};i[0]&&(d.checkStatus(e.key).isAll?(i[0].checked||(i.prop("checked",!0),e.renderForm()),a(!0)):(i[0].checked&&(i.prop("checked",!1),e.renderForm()),a(!1)))},H.prototype.getCssRule=function(e,t){var i=this,a=i.elem.find("style")[0],l=a.sheet||a.styleSheet,n=l.cssRules||l.rules;layui.each(n,function(a,l){if(l.selectorText===".laytable-cell-"+i.index+"-"+e)return t(l),!0})},H.prototype.fullSize=function(){var e,t=this,i=t.config,a=i.height;t.fullHeightGap&&(a=L.height()-t.fullHeightGap,a<135&&(a=135),t.elem.css("height",a)),e=parseFloat(a)-parseFloat(t.layHeader.height())-1,i.page&&(e-=parseFloat(t.layTool.outerHeight()+1)),t.layMain.css("height",e)},H.prototype.scrollPatch=function(){var e=this,i=e.layMain.children("table"),a=e.layMain.width()-e.layMain.prop("clientWidth"),l=e.layMain.height()-e.layMain.prop("clientHeight");if(a&&l){if(!e.elem.find(".layui-table-patch")[0]){var n=t('<th class="layui-table-patch"><div class="layui-table-cell"></div></th>');n.find("div").css({width:a}),e.layHeader.eq(0).find("thead tr").append(n)}}else e.layHeader.eq(0).find(".layui-table-patch").remove();var o=e.layMain.height(),r=o-l;e.layFixed.find(m).css("height",i.height()>r?r:"auto"),e.layFixRight[i.width()>e.layMain.width()?"removeClass":"addClass"](f),e.layFixRight.css("right",a-1)},H.prototype.events=function(){var e,a=this,n=a.config,o=t("body"),c={},u=a.layHeader.find("th"),f=".layui-table-cell",h=n.elem.attr("lay-filter");u.on("mousemove",function(e){var i=t(this),a=i.offset().left,l=e.clientX-a;i.attr("colspan")>1||i.attr("unresize")||c.resizeStart||(c.allowResize=i.width()-l<=10,o.css("cursor",c.allowResize?"col-resize":""))}).on("mouseleave",function(){t(this);c.resizeStart||o.css("cursor","")}).on("mousedown",function(e){if(c.allowResize){var i=t(this).data("field");e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],a.getCssRule(i,function(e){c.rule=e,c.ruleWidth=parseFloat(e.style.width)})}}),S.on("mousemove",function(t){if(c.resizeStart){if(t.preventDefault(),c.rule){var i=c.ruleWidth+t.clientX-c.offset[0];c.rule.style.width=i+"px",l.close(a.tipsIndex)}e=1}}).on("mouseup",function(t){c.resizeStart&&(c={},o.css("cursor",""),a.scrollPatch()),2===e&&(e=null)}),u.on("click",function(){var i,l=t(this),n=l.find(C),o=n.attr("lay-sort");return n[0]&&1!==e?(i="asc"===o?"desc":"desc"===o?null:"asc",void a.sort(l,i,null,!0)):e=2}).find(C+" .layui-edge ").on("click",function(e){var i=t(this),l=i.index(),n=i.parents("th").eq(0).data("field");layui.stope(e),0===l?a.sort(n,"asc",null,!0):a.sort(n,"desc",null,!0)}),a.elem.on("click",'input[name="layTableCheckbox"]+',function(){var e=t(this).prev(),i=a.layBody.find('input[name="layTableCheckbox"]'),l=e.parents("tr").eq(0).data("index"),n=e[0].checked,o="layTableAllChoose"===e.attr("lay-filter");o?(i.each(function(e,t){t.checked=n,a.setCheckData(e,n)}),a.syncCheckAll(),a.renderForm()):(a.setCheckData(l,n),a.syncCheckAll()),layui.event.call(this,s,"checkbox("+h+")",{checked:n,data:d.cache[a.key][l],type:o?"all":"one"})}),a.layBody.on("mouseenter","tr",function(){var e=t(this),i=e.index();a.layBody.find("tr:eq("+i+")").addClass(N)}).on("mouseleave","tr",function(){var e=t(this),i=e.index();a.layBody.find("tr:eq("+i+")").removeClass(N)}),a.layBody.on("change","."+w,function(){var e=t(this),i=this.value,l=e.parent().data("field"),n=e.parents("tr").eq(0).data("index"),o=d.cache[a.key][n];o[l]=i,layui.event.call(this,s,"edit("+h+")",{value:i,data:o,field:l})}).on("blur","."+w,function(){var e,l=t(this),n=l.parent().data("field"),o=l.parents("tr").eq(0).data("index"),r=d.cache[a.key][o];a.eachCols(function(t,i){i.field==n&&i.templet&&(e=i.templet)}),l.siblings(f).html(e?i(t(e).html()||this.value).render(r):this.value),l.parent().data("content",this.value),l.remove()}),a.layBody.on("click","td",function(){var e=t(this),i=(e.data("field"),e.children(f));if(!e.data("off")){if(e.data("edit")){var o=t('<input class="'+w+'">');return o[0].value=e.data("content")||i.text(),e.find("."+w)[0]||e.append(o),o.focus()}Math.round(i.prop("scrollWidth"))>Math.round(i.outerWidth())&&(a.tipsIndex=l.tips(['<div class="layui-table-tips-main" style="margin-top: -'+(i.height()+16)+"px;"+function(){return"sm"===n.size?"padding: 4px 15px; font-size: 12px;":"lg"===n.size?"padding: 14px 15px;":""}()+'">',i.html(),"</div>",'<i class="layui-icon layui-table-tips-c">&#x1006;</i>'].join(""),i[0],{tips:[3,""],time:-1,anim:-1,maxWidth:r.ios||r.android?300:600,isOutAnim:!1,skin:"layui-table-tips",success:function(e,t){e.find(".layui-table-tips-c").on("click",function(){l.close(t)})}}))}}),a.layBody.on("click","*[lay-event]",function(){var e=t(this),l=e.parents("tr").eq(0).data("index"),n=a.layBody.find('tr[data-index="'+l+'"]'),o="layui-table-click",r=d.cache[a.key][l];layui.event.call(this,s,"tool("+h+")",{data:d.clearCacheKey(r),event:e.attr("lay-event"),tr:n,del:function(){d.cache[a.key][l]=[],n.remove(),a.scrollPatch()},update:function(e){e=e||{},layui.each(e,function(e,l){if(e in r){var o,d=n.children('td[data-field="'+e+'"]');r[e]=l,a.eachCols(function(t,i){i.field==e&&i.templet&&(o=i.templet)}),d.children(f).html(o?i(t(o).html()||l).render(r):l),d.data("content",l)}})}}),n.addClass(o).siblings("tr").removeClass(o)}),a.layMain.on("scroll",function(){var e=t(this),i=e.scrollLeft(),n=e.scrollTop();a.layHeader.scrollLeft(i),a.layFixed.find(m).scrollTop(n),l.close(a.tipsIndex)}),L.on("resize",function(){a.fullSize(),a.scrollPatch()})},d.init=function(e,i){i=i||{};var a=this,l=t(e?'table[lay-filter="'+e+'"]':u+"[lay-data]"),n="Table element property lay-data configuration item has a syntax error: ";return l.each(function(){var a=t(this),l=a.attr("lay-data");try{l=new Function("return "+l)()}catch(r){o.error(n+l)}var c=[],s=t.extend({elem:this,cols:[],data:[],skin:a.attr("lay-skin"),size:a.attr("lay-size"),even:"string"==typeof a.attr("lay-even")},d.config,i,l);e&&a.hide(),a.find("thead>tr").each(function(e){s.cols[e]=[],t(this).children().each(function(i){var a=t(this),l=a.attr("lay-data");try{l=new Function("return "+l)()}catch(r){return o.error(n+l)}var d=t.extend({title:a.text(),colspan:a.attr("colspan")||0,rowspan:a.attr("rowspan")||0},l);d.colspan<2&&c.push(d),s.cols[e].push(d)})}),a.find("tbody>tr").each(function(e){var i=t(this),a={};i.children("td").each(function(e,i){var l=t(this),n=l.data("field");if(n)return a[n]=l.html()}),layui.each(c,function(e,t){var l=i.children("td").eq(e);a[t.field]=l.html()}),s.data[e]=a}),d.render(s)}),a},d.checkStatus=function(e){var t=0,i=[],a=d.cache[e];return a?(layui.each(a,function(e,a){a[d.config.checkName]&&(t++,i.push(d.clearCacheKey(a)))}),{data:i,isAll:t===a.length}):{}},c.config={},d.reload=function(e,i){var a=c.config[e];return a?d.render(t.extend({},a,i)):o.error("The ID option was not found in the table instance")},d.render=function(e){var t=new H(e);return c.call(t)},d.clearCacheKey=function(e){return e=t.extend({},e),delete e[d.config.checkName],delete e[d.config.indexName],e},d.init(),e(s,d)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/tree.js b/static/plugins/layui/lay/modules/tree.js new file mode 100755 index 0000000..76adaa6 --- /dev/null +++ b/static/plugins/layui/lay/modules/tree.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(e){"use strict";var o=layui.$,a=layui.hint(),i="layui-tree-enter",r=function(e){this.options=e},t={arrow:["&#xe623;","&#xe625;"],checkbox:["&#xe626;","&#xe627;"],radio:["&#xe62b;","&#xe62a;"],branch:["&#xe622;","&#xe624;"],leaf:"&#xe621;"};r.prototype.init=function(e){var o=this;e.addClass("layui-box layui-tree"),o.options.skin&&e.addClass("layui-tree-skin-"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class="'+(n.spread?"layui-show":"")+'"></ul>'),s=o(["<li "+(n.spread?'data-spread="'+n.spread+'"':"")+">",function(){return l?'<i class="layui-icon layui-tree-spread">'+(n.spread?t.arrow[1]:t.arrow[0])+"</i>":""}(),function(){return r.check?'<i class="layui-icon layui-tree-check">'+("checkbox"===r.check?t.checkbox[0]:"radio"===r.check?t.radio[0]:"")+"</i>":""}(),function(){return'<a href="'+(n.href||"javascript:;")+'" '+(r.target&&n.href?'target="'+r.target+'"':"")+">"+('<i class="layui-icon layui-tree-'+(l?"branch":"leaf")+'">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+"</i>")+("<cite>"+(n.name||"未命名")+"</cite></a>")}(),"</li>"].join(""));l&&(s.append(c),i.tree(c,n.children)),e.append(s),"function"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children("a").on("click",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(".layui-tree-spread")),r=e.children("ul"),n=e.children("a"),l=function(){e.data("spread")?(e.data("spread",null),r.removeClass("layui-show"),i.html(t.arrow[0]),n.find(".layui-icon").html(t.branch[0])):(e.data("spread",!0),r.addClass("layui-show"),i.html(t.arrow[1]),n.find(".layui-icon").html(t.branch[1]))};r[0]&&(i.on("click",l),n.on("dblclick",l))},r.prototype.on=function(e){var a=this,r=a.options,t="layui-tree-drag";e.find("i").on("selectstart",function(e){return!1}),r.drag&&o(document).on("mousemove",function(e){var i=a.move;if(i.from){var r=(i.to,o('<div class="layui-box '+t+'"></div>'));e.preventDefault(),o("."+t)[0]||o("body").append(r);var n=o("."+t)[0]?o("."+t):r;n.addClass("layui-show").html(i.from.elem.children("a").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on("mouseup",function(){var e=a.move;e.from&&(e.from.elem.children("a").removeClass(i),e.to&&e.to.elem.children("a").removeClass(i),a.move={},o("."+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children("a")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on("mousedown",function(){var o=r.move;o.from={item:a,elem:e}}),t.on("mouseenter",n).on("mousemove",n).on("mouseleave",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e("tree",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error("layui.tree 没有找到"+e.elem+"元素")})}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/upload.js b/static/plugins/layui/lay/modules/upload.js new file mode 100755 index 0000000..cc0d906 --- /dev/null +++ b/static/plugins/layui/lay/modules/upload.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("layer",function(e){"use strict";var t=layui.$,i=layui.layer,n=layui.hint(),a=layui.device(),o={config:{},set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,r,e,t)}},l=function(){var e=this;return{upload:function(t){e.upload.call(e,t)},config:e.config}},r="upload",u="layui-upload-file",c="layui-upload-form",f="layui-upload-iframe",s="layui-upload-choose",p=function(e){var i=this;i.config=t.extend({},i.config,o.config,e),i.render()};p.prototype.config={accept:"images",exts:"",auto:!0,bindAction:"",url:"",field:"file",method:"post",data:{},drag:!0,size:0,multiple:!1},p.prototype.render=function(e){var i=this,e=i.config;e.elem=t(e.elem),e.bindAction=t(e.bindAction),i.file(),i.events()},p.prototype.file=function(){var e=this,i=e.config,n=e.elemFile=t(['<input class="'+u+'" type="file" name="'+i.field+'"',i.multiple?" multiple":"",">"].join("")),o=i.elem.next();(o.hasClass(u)||o.hasClass(c))&&o.remove(),a.ie&&a.ie<10&&i.elem.wrap('<div class="layui-upload-wrap"></div>'),e.isFile()?(e.elemFile=i.elem,i.field=i.elem[0].name):i.elem.after(n),a.ie&&a.ie<10&&e.initIE()},p.prototype.initIE=function(){var e=this,i=e.config,n=t('<iframe id="'+f+'" class="'+f+'" name="'+f+'" frameborder="0"></iframe>'),a=t(['<form target="'+f+'" class="'+c+'" method="'+i.method,'" key="set-mine" enctype="multipart/form-data" action="'+i.url+'">',"</form>"].join(""));t("#"+f)[0]||t("body").append(n),i.elem.next().hasClass(f)||(e.elemFile.wrap(a),i.elem.next("."+f).append(function(){var e=[];return layui.each(i.data,function(t,i){e.push('<input type="hidden" name="'+t+'" value="'+i+'">')}),e.join("")}()))},p.prototype.msg=function(e){return i.msg(e,{icon:2,shift:6})},p.prototype.isFile=function(){var e=this.config.elem[0];if(e)return"input"===e.tagName.toLocaleLowerCase()&&"file"===e.type},p.prototype.preview=function(e){var t=this;window.FileReader&&layui.each(t.chooseFiles,function(t,i){var n=new FileReader;n.readAsDataURL(i),n.onload=function(){e&&e(t,i,this.result)}})},p.prototype.upload=function(e,i){var n,o=this,l=o.config,r=o.elemFile[0],u=function(){var i=0,n=0,a=e||o.files||o.chooseFiles||r.files,u=function(){l.multiple&&i+n===o.fileLength&&"function"==typeof l.allDone&&l.allDone({total:o.fileLength,successful:i,aborted:n})};layui.each(a,function(e,a){var r=new FormData;r.append(l.field,a),layui.each(l.data,function(e,t){r.append(e,t)}),t.ajax({url:l.url,type:l.method,data:r,contentType:!1,processData:!1,dataType:"json",success:function(t){i++,d(e,t),u()},error:function(){n++,o.msg("请求上传接口出现异常"),m(e),u()}})})},c=function(){var e=t("#"+f);o.elemFile.parent().submit(),clearInterval(p.timer),p.timer=setInterval(function(){var t,i=e.contents().find("body");try{t=i.text()}catch(n){o.msg("获取上传后的响应信息出现异常"),clearInterval(p.timer),m()}t&&(clearInterval(p.timer),i.html(""),d(0,t))},30)},d=function(e,t){if(o.elemFile.next("."+s).remove(),r.value="","object"!=typeof t)try{t=JSON.parse(t)}catch(i){return t={},o.msg("请对上传接口返回有效JSON")}"function"==typeof l.done&&l.done(t,e||0,function(e){o.upload(e)})},m=function(e){l.auto&&(r.value=""),"function"==typeof l.error&&l.error(e||0,function(e){o.upload(e)})},h=l.exts,v=function(){var t=[];return layui.each(e||o.chooseFiles,function(e,i){t.push(i.name)}),t}(),g={preview:function(e){o.preview(e)},upload:function(e,t){var i={};i[e]=t,o.upload(i)},pushFile:function(){return o.files=o.files||{},layui.each(o.chooseFiles,function(e,t){o.files[e]=t}),o.files}},y=function(){return"choose"===i?l.choose&&l.choose(g):(l.before&&l.before(g),a.ie?a.ie>9?u():c():void u())};switch(v=0===v.length?r.value.match(/[^\/\\]+\..+/g)||[]||"":v,l.accept){case"file":if(h&&!RegExp("\\w\\.("+h+")$","i").test(escape(v)))return o.msg("选择的文件中包含不支持的格式"),r.value="";break;case"video":if(!RegExp("\\w\\.("+(h||"avi|mp4|wma|rmvb|rm|flash|3gp|flv")+")$","i").test(escape(v)))return o.msg("选择的视频中包含不支持的格式"),r.value="";break;case"audio":if(!RegExp("\\w\\.("+(h||"mp3|wav|mid")+")$","i").test(escape(v)))return o.msg("选择的音频中包含不支持的格式"),r.value="";break;default:if(layui.each(v,function(e,t){RegExp("\\w\\.("+(h||"jpg|png|gif|bmp|jpeg$")+")","i").test(escape(t))||(n=!0)}),n)return o.msg("选择的图片中包含不支持的格式"),r.value=""}if(l.size>0&&!(a.ie&&a.ie<10)){var F;if(layui.each(o.chooseFiles,function(e,t){if(t.size>1024*l.size){var i=l.size/1024;i=i>=1?Math.floor(i)+(i%1>0?i.toFixed(1):0)+"MB":l.size+"KB",r.value="",F=i}}),F)return o.msg("文件不能超过"+F)}y()},p.prototype.events=function(){var e=this,i=e.config,o=function(t){e.chooseFiles={},layui.each(t,function(t,i){var n=(new Date).getTime();e.chooseFiles[n+"-"+t]=i})},l=function(t,n){var a=e.elemFile,o=t.length>1?t.length+"个文件":(t[0]||{}).name||a[0].value.match(/[^\/\\]+\..+/g)||[]||"";a.next().hasClass(s)&&a.next().remove(),e.upload(null,"choose"),e.isFile()||i.choose||a.after('<span class="layui-inline '+s+'">'+o+"</span>")};i.elem.off("upload.start").on("upload.start",function(){var a=t(this),o=a.attr("lay-data");if(o)try{o=new Function("return "+o)(),e.config=t.extend({},i,o)}catch(l){n.error("Upload element property lay-data configuration item has a syntax error: "+o)}e.config.item=a,e.elemFile[0].click()}),a.ie&&a.ie<10||i.elem.off("upload.over").on("upload.over",function(){var e=t(this);e.attr("lay-over","")}).off("upload.leave").on("upload.leave",function(){var e=t(this);e.removeAttr("lay-over")}).off("upload.drop").on("upload.drop",function(n,a){var r=t(this),u=a.originalEvent.dataTransfer.files||[];r.removeAttr("lay-over"),o(u),i.auto?e.upload(u):l(u)}),e.elemFile.off("upload.change").on("upload.change",function(){var t=this.files||[];e.fileLength=t.length,o(t),i.auto?e.upload():l(t)}),i.bindAction.off("upload.action").on("upload.action",function(){e.upload()}),i.elem.data("haveEvents")||(e.elemFile.on("change",function(){t(this).trigger("upload.change")}),i.elem.on("click",function(){e.isFile()||t(this).trigger("upload.start")}),i.drag&&i.elem.on("dragover",function(e){e.preventDefault(),t(this).trigger("upload.over")}).on("dragleave",function(e){t(this).trigger("upload.leave")}).on("drop",function(e){e.preventDefault(),t(this).trigger("upload.drop",e)}),i.bindAction.on("click",function(){t(this).trigger("upload.action")}),i.elem.data("haveEvents",!0))},o.render=function(e){var t=new p(e);return l.call(t)},e(r,o)}); \ No newline at end of file diff --git a/static/plugins/layui/lay/modules/util.js b/static/plugins/layui/lay/modules/util.js new file mode 100755 index 0000000..0ba9c65 --- /dev/null +++ b/static/plugins/layui/lay/modules/util.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;layui.define("jquery",function(e){"use strict";var t=layui.$,o={fixbar:function(e){var o,i,a="layui-fixbar",l="layui-fixbar-top",n=t(document),r=t("body");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?"&#xe606;":e.bar1,e.bar2=e.bar2===!0?"&#xe607;":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,"&#xe604;"],u=t(['<ul class="'+a+'">',e.bar1?'<li class="layui-icon" lay-type="bar1" style="'+e.bgcolor+'">'+c[0]+"</li>":"",e.bar2?'<li class="layui-icon" lay-type="bar2" style="'+e.bgcolor+'">'+c[1]+"</li>":"",'<li class="layui-icon '+l+'" lay-type="top" style="'+e.bgcolor+'">'+c[2]+"</li>","</ul>"].join("")),s=u.find("."+l),b=function(){var t=n.scrollTop();t>=e.showHeight?o||(s.show(),o=1):o&&(s.hide(),o=0)};t("."+a)[0]||("object"==typeof e.css&&u.css(e.css),r.append(u),b(),u.find("li").on("click",function(){var o=t(this),i=o.attr("lay-type");"top"===i&&t("html,body").animate({scrollTop:0},200),e.click&&e.click.call(this,i)}),n.on("scroll",function(){clearTimeout(i),i=setTimeout(function(){b()},100)}))},countdown:function(e,t,o){var i=this,a="function"==typeof t,l=new Date(e).getTime(),n=new Date(!t||a?(new Date).getTime():t).getTime(),r=l-n,c=[Math.floor(r/864e5),Math.floor(r/36e5)%24,Math.floor(r/6e4)%60,Math.floor(r/1e3)%60];a&&(o=t);var u=setTimeout(function(){i.countdown(e,n+1e3,o)},1e3);return o&&o(r>0?c:[0,0,0,0],t,u),r<=0&&clearTimeout(u),u},timeAgo:function(e,t){var o=[[],[]],i=(new Date).getTime()-new Date(e).getTime();return i>6912e5?(i=new Date(e),o[0][0]=i.getFullYear(),o[0][1]=i.getMonth()+1,o[0][2]=i.getDate(),t||(o[1][0]=i.getHours(),o[1][1]=i.getMinutes(),o[1][2]=i.getSeconds()),o[0].join("-")+" "+o[1].join(":")):i>=864e5?(i/1e3/60/60/24|0)+"天前":i>=36e5?(i/1e3/60/60|0)+"小时前":i>=12e4?(i/1e3/60|0)+"分钟前":i<0?"未来":"刚刚"}};e("util",o)}); \ No newline at end of file diff --git a/static/plugins/layui/layui.all.js b/static/plugins/layui/layui.all.js new file mode 100755 index 0000000..e978d4d --- /dev/null +++ b/static/plugins/layui/layui.all.js @@ -0,0 +1,5 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;!function(e){"use strict";var t=document,o={modules:{},status:{},timeout:10,event:{}},n=function(){this.v="2.1.7"},r=function(){var e=t.scripts,o=e[e.length-1].src;return o.substring(0,o.lastIndexOf("/")+1)}(),a=function(t){e.console&&console.error&&console.error("Layui hint: "+t)},i="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),u={layer:"modules/layer",laydate:"modules/laydate",laypage:"modules/laypage",laytpl:"modules/laytpl",layim:"modules/layim",layedit:"modules/layedit",form:"modules/form",upload:"modules/upload",tree:"modules/tree",table:"modules/table",element:"modules/element",util:"modules/util",flow:"modules/flow",carousel:"modules/carousel",code:"modules/code",jquery:"modules/jquery",mobile:"modules/mobile","layui.all":"../layui.all"};n.prototype.cache=o,n.prototype.define=function(e,t){var n=this,r="function"==typeof e,a=function(){return"function"==typeof t&&t(function(e,t){layui[e]=t,o.status[e]=!0}),this};return r&&(t=e,e=[]),layui["layui.all"]||!layui["layui.all"]&&layui["layui.mobile"]?a.call(n):(n.use(e,a),n)},n.prototype.use=function(e,n,l){function s(e,t){var n="PLaySTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/;("load"===e.type||n.test((e.currentTarget||e.srcElement).readyState))&&(o.modules[f]=t,d.removeChild(v),function r(){return++m>1e3*o.timeout/4?a(f+" is not a valid module"):void(o.status[f]?c():setTimeout(r,4))}())}function c(){l.push(layui[f]),e.length>1?y.use(e.slice(1),n,l):"function"==typeof n&&n.apply(layui,l)}var y=this,p=o.dir=o.dir?o.dir:r,d=t.getElementsByTagName("head")[0];e="string"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(y.each(e,function(t,o){"jquery"===o&&e.splice(t,1)}),layui.jquery=layui.$=jQuery);var f=e[0],m=0;if(l=l||[],o.host=o.host||(p.match(/\/\/([\s\S]+?)\//)||["//"+location.host+"/"])[0],0===e.length||layui["layui.all"]&&u[f]||!layui["layui.all"]&&layui["layui.mobile"]&&u[f])return c(),y;if(o.modules[f])!function g(){return++m>1e3*o.timeout/4?a(f+" is not a valid module"):void("string"==typeof o.modules[f]&&o.status[f]?c():setTimeout(g,4))}();else{var v=t.createElement("script"),h=(u[f]?p+"lay/":o.base||"")+(y.modules[f]||f)+".js";v.async=!0,v.charset="utf-8",v.src=h+function(){var e=o.version===!0?o.v||(new Date).getTime():o.version||"";return e?"?v="+e:""}(),d.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf("[native code")<0||i?v.addEventListener("load",function(e){s(e,h)},!1):v.attachEvent("onreadystatechange",function(e){s(e,h)}),o.modules[f]=h}return y},n.prototype.getStyle=function(t,o){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](o)},n.prototype.link=function(e,n,r){var i=this,u=t.createElement("link"),l=t.getElementsByTagName("head")[0];"string"==typeof n&&(r=n);var s=(r||e).replace(/\.|\//g,""),c=u.id="layuicss-"+s,y=0;return u.rel="stylesheet",u.href=e+(o.debug?"?v="+(new Date).getTime():""),u.media="all",t.getElementById(c)||l.appendChild(u),"function"!=typeof n?i:(function p(){return++y>1e3*o.timeout/100?a(e+" timeout"):void(1989===parseInt(i.getStyle(t.getElementById(c),"width"))?function(){n()}():setTimeout(p,100))}(),i)},n.prototype.addcss=function(e,t,n){return layui.link(o.dir+"css/"+e,t,n)},n.prototype.img=function(e,t,o){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,o(e)}))},n.prototype.config=function(e){e=e||{};for(var t in e)o[t]=e[t];return this},n.prototype.modules=function(){var e={};for(var t in u)e[t]=u[t];return e}(),n.prototype.extend=function(e){var t=this;e=e||{};for(var o in e)t[o]||t.modules[o]?a("模块名 "+o+" 已被占用"):t.modules[o]=e[o];return t},n.prototype.router=function(e){var t=this,e=e||location.hash,o={path:[],search:{},hash:(e.match(/[^#](#.*$)/)||[])[1]||""};return/^#\//.test(e)?(e=e.replace(/^#\//,"").replace(/([^#])(#.*$)/,"$1").split("/")||[],t.each(e,function(e,t){/^\w+=/.test(t)?function(){t=t.split("="),o.search[t[0]]=t[1]}():o.path.push(t)}),o):o},n.prototype.data=function(t,o){if(t=t||"layui",e.JSON&&e.JSON.parse){if(null===o)return delete localStorage[t];o="object"==typeof o?o:{key:o};try{var n=JSON.parse(localStorage[t])}catch(r){var n={}}return o.value&&(n[o.key]=o.value),o.remove&&delete n[o.key],localStorage[t]=JSON.stringify(n),o.key?n[o.key]:n}},n.prototype.device=function(t){var o=navigator.userAgent.toLowerCase(),n=function(e){var t=new RegExp(e+"/([^\\s\\_\\-]+)");return e=(o.match(t)||[])[1],e||!1},r={os:function(){return/windows/.test(o)?"windows":/linux/.test(o)?"linux":/iphone|ipod|ipad|ios/.test(o)?"ios":/mac/.test(o)?"mac":void 0}(),ie:function(){return!!(e.ActiveXObject||"ActiveXObject"in e)&&((o.match(/msie\s(\d+)/)||[])[1]||"11")}(),weixin:n("micromessenger")};return t&&!r[t]&&(r[t]=n(t)),r.android=/android/.test(o),r.ios="ios"===r.os,r},n.prototype.hint=function(){return{error:a}},n.prototype.each=function(e,t){var o,n=this;if("function"!=typeof t)return n;if(e=e||[],e.constructor===Object){for(o in e)if(t.call(e[o],o,e[o]))break}else for(o=0;o<e.length&&!t.call(e[o],o,e[o]);o++);return n},n.prototype.sort=function(e,t,o){var n=JSON.parse(JSON.stringify(e));return t?(n.sort(function(e,o){var n=/^-?\d+$/,r=e[t],a=o[t];return n.test(r)&&(r=parseFloat(r)),n.test(a)&&(a=parseFloat(a)),r&&!a?1:!r&&a?-1:r>a?1:r<a?-1:0}),o&&n.reverse(),n):n},n.prototype.stope=function(t){t=t||e.event,t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},n.prototype.onevent=function(e,t,n){return"string"!=typeof e||"function"!=typeof n?this:(o.event[e+"."+t]=[n],this)},n.prototype.event=function(e,t,n){var r=this,a=null,i=t.match(/\(.*\)$/)||[],u=(t=e+"."+t).replace(i,""),l=function(e,t){var o=t&&t.call(r,n);o===!1&&null===a&&(a=!1)};return layui.each(o.event[u],l),i[0]&&layui.each(o.event[t],l),a},e.layui=new n}(window);layui.define(function(a){var i=layui.cache;layui.config({dir:i.dir.replace(/lay\/dest\/$/,"")}),a("layui.all",layui.v)});layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)});layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"&#x4E0A;&#x4E00;&#x9875;",a.next="next"in a?a.next:"&#x4E0B;&#x4E00;&#x9875;";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href="javascript:;" class="layui-laypage-prev'+(1==a.curr?" "+r:"")+'" data-page="'+(a.curr-1)+'">'+a.prev+"</a>":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="&#x9996;&#x9875;">'+(a.first||1)+"</a>");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class="layui-laypage-spr">&#x2026;</span>');r<=u;r++)r===a.curr?e.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" '+(/^#/.test(a.theme)?'style="background-color:'+a.theme+';"':"")+"></em><em>"+r+"</em></span>"):e.push('<a href="javascript:;" data-page="'+r+'">'+r+"</a>");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class="layui-laypage-spr">&#x2026;</span>'),0!==t&&e.push('<a href="javascript:;" class="layui-laypage-last" title="&#x5C3E;&#x9875;" data-page="'+a.pages+'">'+(a.last||a.pages)+"</a>")),e.join("")}(),next:function(){return a.next?'<a href="javascript:;" class="layui-laypage-next'+(a.curr==a.pages?" "+r:"")+'" data-page="'+(a.curr+1)+'">'+a.next+"</a>":""}(),count:'<span class="layui-laypage-count">共 '+a.count+" 条</span>",limit:function(){var e=['<span class="layui-laypage-limits"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value="'+n+'"'+(n===a.limit?"selected":"")+">"+n+" 条/页</option>")}),e.join("")+"</select></span>"}(),skip:function(){return['<span class="layui-laypage-skip">&#x5230;&#x7B2C;','<input type="text" min="1" value="'+a.curr+'" class="layui-input">','&#x9875;<button type="button" class="layui-laypage-btn">&#x786e;&#x5b9a;</button>',"</span>"].join("")}()};return['<div class="layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?"molv":a.theme:"default")+'" id="layui-laypage-'+a.index+'">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"</div>"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)"a"===r[o].nodeName.toLowerCase()&&s.on(r[o],"click",function(){var e=0|this.getAttribute("data-page");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)});!function(){"use strict";var e=window.layui&&layui.define,t={getPath:function(){var e=document.scripts,t=e[e.length-1],n=t.src;if(!t.getAttribute("merge"))return n.substring(0,n.lastIndexOf("/")+1)}(),getStyle:function(e,t){var n=e.currentStyle?e.currentStyle:window.getComputedStyle(e,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](t)},link:function(e,a,i){if(n.path){var r=document.getElementsByTagName("head")[0],o=document.createElement("link");"string"==typeof a&&(i=a);var s=(i||e).replace(/\.|\//g,""),l="layuicss-"+s,d=0;o.rel="stylesheet",o.href=n.path+e,o.id=l,document.getElementById(l)||r.appendChild(o),"function"==typeof a&&!function c(){return++d>80?window.console&&console.error("laydate.css: Invalid"):void(1989===parseInt(t.getStyle(document.getElementById(l),"width"))?a():setTimeout(c,100))}()}}},n={v:"5.0.8",config:{},index:window.laydate&&window.laydate.v?1e5:0,path:t.getPath,set:function(e){var n=this;return n.config=t.extend({},n.config,e),n},ready:function(a){var i="laydate",r="",o=(e?"modules/laydate/":"theme/")+"default/laydate.css?v="+n.v+r;return e?layui.addcss(o,a,i):t.link(o,a,i),this}},a=function(){var e=this;return{hint:function(t){e.hint.call(e,t)},config:e.config}},i="laydate",r=".layui-laydate",o="layui-this",s="laydate-disabled",l="开始日期超出了结束日期<br>建议重新选择",d=[100,2e5],c="layui-laydate-static",m="layui-laydate-list",u="laydate-selected",h="layui-laydate-hint",y="laydate-day-prev",f="laydate-day-next",p="layui-laydate-footer",g=".laydate-btns-confirm",v="laydate-time-text",D=".laydate-btns-time",T=function(e){var t=this;t.index=++n.index,t.config=w.extend({},t.config,n.config,e),n.ready(function(){t.init()})},w=function(e){return new C(e)},C=function(e){for(var t=0,n="object"==typeof e?[e]:(this.selector=e,document.querySelectorAll(e||null));t<n.length;t++)this.push(n[t])};C.prototype=[],C.prototype.constructor=C,w.extend=function(){var e=1,t=arguments,n=function(e,t){e=e||(t.constructor===Array?[]:{});for(var a in t)e[a]=t[a]&&t[a].constructor===Object?n(e[a],t[a]):t[a];return e};for(t[0]="object"==typeof t[0]?t[0]:{};e<t.length;e++)"object"==typeof t[e]&&n(t[0],t[e]);return t[0]},w.ie=function(){var e=navigator.userAgent.toLowerCase();return!!(window.ActiveXObject||"ActiveXObject"in window)&&((e.match(/msie\s(\d+)/)||[])[1]||"11")}(),w.stope=function(e){e=e||window.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},w.each=function(e,t){var n,a=this;if("function"!=typeof t)return a;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return a},w.digit=function(e,t,n){var a="";e=String(e),t=t||2;for(var i=e.length;i<t;i++)a+="0";return e<Math.pow(10,t)?a+(0|e):e},w.elem=function(e,t){var n=document.createElement(e);return w.each(t||{},function(e,t){n.setAttribute(e,t)}),n},C.addStr=function(e,t){return e=e.replace(/\s+/," "),t=t.replace(/\s+/," ").split(" "),w.each(t,function(t,n){new RegExp("\\b"+n+"\\b").test(e)||(e=e+" "+n)}),e.replace(/^\s|\s$/,"")},C.removeStr=function(e,t){return e=e.replace(/\s+/," "),t=t.replace(/\s+/," ").split(" "),w.each(t,function(t,n){var a=new RegExp("\\b"+n+"\\b");a.test(e)&&(e=e.replace(a,""))}),e.replace(/\s+/," ").replace(/^\s|\s$/,"")},C.prototype.find=function(e){var t=this,n=0,a=[],i="object"==typeof e;return this.each(function(r,o){for(var s=i?[e]:o.querySelectorAll(e||null);n<s.length;n++)a.push(s[n]);t.shift()}),i||(t.selector=(t.selector?t.selector+" ":"")+e),w.each(a,function(e,n){t.push(n)}),t},C.prototype.each=function(e){return w.each.call(this,this,e)},C.prototype.addClass=function(e,t){return this.each(function(n,a){a.className=C[t?"removeStr":"addStr"](a.className,e)})},C.prototype.removeClass=function(e){return this.addClass(e,!0)},C.prototype.hasClass=function(e){var t=!1;return this.each(function(n,a){new RegExp("\\b"+e+"\\b").test(a.className)&&(t=!0)}),t},C.prototype.attr=function(e,t){var n=this;return void 0===t?function(){if(n.length>0)return n[0].getAttribute(e)}():n.each(function(n,a){a.setAttribute(e,t)})},C.prototype.removeAttr=function(e){return this.each(function(t,n){n.removeAttribute(e)})},C.prototype.html=function(e){return this.each(function(t,n){n.innerHTML=e})},C.prototype.val=function(e){return this.each(function(t,n){n.value=e})},C.prototype.append=function(e){return this.each(function(t,n){"object"==typeof e?n.appendChild(e):n.innerHTML=n.innerHTML+e})},C.prototype.remove=function(e){return this.each(function(t,n){e?n.removeChild(e):n.parentNode.removeChild(n)})},C.prototype.on=function(e,t){return this.each(function(n,a){a.attachEvent?a.attachEvent("on"+e,function(e){e.target=e.srcElement,t.call(a,e)}):a.addEventListener(e,t,!1)})},C.prototype.off=function(e,t){return this.each(function(n,a){a.detachEvent?a.detachEvent("on"+e,t):a.removeEventListener(e,t,!1)})},T.isLeapYear=function(e){return e%4===0&&e%100!==0||e%400===0},T.prototype.config={type:"date",range:!1,format:"yyyy-MM-dd",value:null,min:"1900-1-1",max:"2099-12-31",trigger:"focus",show:!1,showBottom:!0,btns:["clear","now","confirm"],lang:"cn",theme:"default",position:null,calendar:!1,mark:{},zIndex:null,done:null,change:null},T.prototype.lang=function(){var e=this,t=e.config,n={cn:{weeks:["日","一","二","三","四","五","六"],time:["时","分","秒"],timeTips:"选择时间",startTime:"开始时间",endTime:"结束时间",dateTips:"返回日期",month:["一","二","三","四","五","六","七","八","九","十","十一","十二"],tools:{confirm:"确定",clear:"清空",now:"现在"}},en:{weeks:["Su","Mo","Tu","We","Th","Fr","Sa"],time:["Hours","Minutes","Seconds"],timeTips:"Select Time",startTime:"Start Time",endTime:"End Time",dateTips:"Select Date",month:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],tools:{confirm:"Confirm",clear:"Clear",now:"Now"}}};return n[t.lang]||n.cn},T.prototype.init=function(){var e=this,t=e.config,n="yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s",a="static"===t.position,i={year:"yyyy",month:"yyyy-MM",date:"yyyy-MM-dd",time:"HH:mm:ss",datetime:"yyyy-MM-dd HH:mm:ss"};t.elem=w(t.elem),t.eventElem=w(t.eventElem),t.elem[0]&&(t.range===!0&&(t.range="-"),t.format===i.date&&(t.format=i[t.type]),e.format=t.format.match(new RegExp(n+"|.","g"))||[],e.EXP_IF="",e.EXP_SPLIT="",w.each(e.format,function(t,a){var i=new RegExp(n).test(a)?"\\d{"+function(){return new RegExp(n).test(e.format[0===t?t+1:t-1]||"")?/^yyyy|y$/.test(a)?4:a.length:/^yyyy$/.test(a)?"1,4":/^y$/.test(a)?"1,308":"1,2"}()+"}":"\\"+a;e.EXP_IF=e.EXP_IF+i,e.EXP_SPLIT=e.EXP_SPLIT+"("+i+")"}),e.EXP_IF=new RegExp("^"+(t.range?e.EXP_IF+"\\s\\"+t.range+"\\s"+e.EXP_IF:e.EXP_IF)+"$"),e.EXP_SPLIT=new RegExp("^"+e.EXP_SPLIT+"$",""),e.isInput(t.elem[0])||"focus"===t.trigger&&(t.trigger="click"),t.elem.attr("lay-key")||(t.elem.attr("lay-key",e.index),t.eventElem.attr("lay-key",e.index)),t.mark=w.extend({},t.calendar&&"cn"===t.lang?{"0-1-1":"元旦","0-2-14":"情人","0-3-8":"妇女","0-3-12":"植树","0-4-1":"愚人","0-5-1":"劳动","0-5-4":"青年","0-6-1":"儿童","0-9-10":"教师","0-9-18":"国耻","0-10-1":"国庆","0-12-25":"圣诞"}:{},t.mark),w.each(["min","max"],function(e,n){var a=[],i=[];if("number"==typeof t[n]){var r=t[n],o=(new Date).getTime(),s=864e5,l=new Date(r?r<s?o+r*s:r:o);a=[l.getFullYear(),l.getMonth()+1,l.getDate()],r<s||(i=[l.getHours(),l.getMinutes(),l.getSeconds()])}else a=(t[n].match(/\d+-\d+-\d+/)||[""])[0].split("-"),i=(t[n].match(/\d+:\d+:\d+/)||[""])[0].split(":");t[n]={year:0|a[0]||(new Date).getFullYear(),month:a[1]?(0|a[1])-1:(new Date).getMonth(),date:0|a[2]||(new Date).getDate(),hours:0|i[0],minutes:0|i[1],seconds:0|i[2]}}),e.elemID="layui-laydate"+t.elem.attr("lay-key"),(t.show||a)&&e.render(),a||e.events(),t.value&&(t.value.constructor===Date?e.setValue(e.parse(0,e.systemDate(t.value))):e.setValue(t.value)))},T.prototype.render=function(){var e=this,t=e.config,n=e.lang(),a="static"===t.position,i=e.elem=w.elem("div",{id:e.elemID,"class":["layui-laydate",t.range?" layui-laydate-range":"",a?" "+c:"",t.theme&&"default"!==t.theme&&!/^#/.test(t.theme)?" laydate-theme-"+t.theme:""].join("")}),r=e.elemMain=[],o=e.elemHeader=[],s=e.elemCont=[],l=e.table=[],d=e.footer=w.elem("div",{"class":p});if(t.zIndex&&(i.style.zIndex=t.zIndex),w.each(new Array(2),function(e){if(!t.range&&e>0)return!0;var a=w.elem("div",{"class":"layui-laydate-header"}),i=[function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-prev-y"});return e.innerHTML="&#xe65a;",e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-prev-m"});return e.innerHTML="&#xe603;",e}(),function(){var e=w.elem("div",{"class":"laydate-set-ym"}),t=w.elem("span"),n=w.elem("span");return e.appendChild(t),e.appendChild(n),e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-next-m"});return e.innerHTML="&#xe602;",e}(),function(){var e=w.elem("i",{"class":"layui-icon laydate-icon laydate-next-y"});return e.innerHTML="&#xe65b;",e}()],d=w.elem("div",{"class":"layui-laydate-content"}),c=w.elem("table"),m=w.elem("thead"),u=w.elem("tr");w.each(i,function(e,t){a.appendChild(t)}),m.appendChild(u),w.each(new Array(6),function(e){var t=c.insertRow(0);w.each(new Array(7),function(a){if(0===e){var i=w.elem("th");i.innerHTML=n.weeks[a],u.appendChild(i)}t.insertCell(a)})}),c.insertBefore(m,c.children[0]),d.appendChild(c),r[e]=w.elem("div",{"class":"layui-laydate-main laydate-main-list-"+e}),r[e].appendChild(a),r[e].appendChild(d),o.push(i),s.push(d),l.push(c)}),w(d).html(function(){var e=[],i=[];return"datetime"===t.type&&e.push('<span lay-type="datetime" class="laydate-btns-time">'+n.timeTips+"</span>"),w.each(t.btns,function(e,r){var o=n.tools[r]||"btn";t.range&&"now"===r||(a&&"clear"===r&&(o="cn"===t.lang?"重置":"Reset"),i.push('<span lay-type="'+r+'" class="laydate-btns-'+r+'">'+o+"</span>"))}),e.push('<div class="laydate-footer-btns">'+i.join("")+"</div>"),e.join("")}()),w.each(r,function(e,t){i.appendChild(t)}),t.showBottom&&i.appendChild(d),/^#/.test(t.theme)){var m=w.elem("style"),u=["#{{id}} .layui-laydate-header{background-color:{{theme}};}","#{{id}} .layui-this{background-color:{{theme}} !important;}"].join("").replace(/{{id}}/g,e.elemID).replace(/{{theme}}/g,t.theme);"styleSheet"in m?(m.setAttribute("type","text/css"),m.styleSheet.cssText=u):m.innerHTML=u,w(i).addClass("laydate-theme-molv"),i.appendChild(m)}e.remove(T.thisElemDate),a?t.elem.append(i):(document.body.appendChild(i),e.position()),e.checkDate().calendar(),e.changeEvent(),T.thisElemDate=e.elemID,"function"==typeof t.ready&&t.ready(w.extend({},t.dateTime,{month:t.dateTime.month+1}))},T.prototype.remove=function(e){var t=this,n=(t.config,w("#"+(e||t.elemID)));return n.hasClass(c)||t.checkDate(function(){n.remove()}),t},T.prototype.position=function(){var e=this,t=e.config,n=e.bindElem||t.elem[0],a=n.getBoundingClientRect(),i=e.elem.offsetWidth,r=e.elem.offsetHeight,o=function(e){return e=e?"scrollLeft":"scrollTop",document.body[e]|document.documentElement[e]},s=function(e){return document.documentElement[e?"clientWidth":"clientHeight"]},l=5,d=a.left,c=a.bottom;d+i+l>s("width")&&(d=s("width")-i-l),c+r+l>s()&&(c=a.top>r?a.top-r:s()-r,c-=2*l),t.position&&(e.elem.style.position=t.position),e.elem.style.left=d+("fixed"===t.position?0:o(1))+"px",e.elem.style.top=c+("fixed"===t.position?0:o())+"px"},T.prototype.hint=function(e){var t=this,n=(t.config,w.elem("div",{"class":h}));n.innerHTML=e||"",w(t.elem).find("."+h).remove(),t.elem.appendChild(n),clearTimeout(t.hinTimer),t.hinTimer=setTimeout(function(){w(t.elem).find("."+h).remove()},3e3)},T.prototype.getAsYM=function(e,t,n){return n?t--:t++,t<0&&(t=11,e--),t>11&&(t=0,e++),[e,t]},T.prototype.systemDate=function(e){var t=e||new Date;return{year:t.getFullYear(),month:t.getMonth(),date:t.getDate(),hours:e?e.getHours():0,minutes:e?e.getMinutes():0,seconds:e?e.getSeconds():0}},T.prototype.checkDate=function(e){var t,a,i=this,r=(new Date,i.config),o=r.dateTime=r.dateTime||i.systemDate(),s=i.bindElem||r.elem[0],l=(i.isInput(s)?"val":"html",i.isInput(s)?s.value:"static"===r.position?"":s.innerHTML),c=function(e){e.year>d[1]&&(e.year=d[1],a=!0),e.month>11&&(e.month=11,a=!0),e.hours>23&&(e.hours=0,a=!0),e.minutes>59&&(e.minutes=0,e.hours++,a=!0),e.seconds>59&&(e.seconds=0,e.minutes++,a=!0),t=n.getEndDate(e.month+1,e.year),e.date>t&&(e.date=t,a=!0)},m=function(e,t,n){var o=["startTime","endTime"];t=(t.match(i.EXP_SPLIT)||[]).slice(1),n=n||0,r.range&&(i[o[n]]=i[o[n]]||{}),w.each(i.format,function(s,l){var c=parseFloat(t[s]);t[s].length<l.length&&(a=!0),/yyyy|y/.test(l)?(c<d[0]&&(c=d[0],a=!0),e.year=c):/MM|M/.test(l)?(c<1&&(c=1,a=!0),e.month=c-1):/dd|d/.test(l)?(c<1&&(c=1,a=!0),e.date=c):/HH|H/.test(l)?(c<1&&(c=0,a=!0),e.hours=c,r.range&&(i[o[n]].hours=c)):/mm|m/.test(l)?(c<1&&(c=0,a=!0),e.minutes=c,r.range&&(i[o[n]].minutes=c)):/ss|s/.test(l)&&(c<1&&(c=0,a=!0),e.seconds=c,r.range&&(i[o[n]].seconds=c))}),c(e)};return"limit"===e?(c(o),i):(l=l||r.value,"string"==typeof l&&(l=l.replace(/\s+/g," ").replace(/^\s|\s$/g,"")),i.startState&&!i.endState&&(delete i.startState,i.endState=!0),"string"==typeof l&&l?i.EXP_IF.test(l)?r.range?(l=l.split(" "+r.range+" "),i.startDate=i.startDate||i.systemDate(),i.endDate=i.endDate||i.systemDate(),r.dateTime=w.extend({},i.startDate),w.each([i.startDate,i.endDate],function(e,t){m(t,l[e],e)})):m(o,l):(i.hint("日期格式不合法<br>必须遵循下述格式:<br>"+(r.range?r.format+" "+r.range+" "+r.format:r.format)+"<br>已为你重置"),a=!0):l&&l.constructor===Date?r.dateTime=i.systemDate(l):(r.dateTime=i.systemDate(),delete i.startState,delete i.endState,delete i.startDate,delete i.endDate,delete i.startTime,delete i.endTime),c(o),a&&l&&i.setValue(r.range?i.endDate?i.parse():"":i.parse()),e&&e(),i)},T.prototype.mark=function(e,t){var n,a=this,i=a.config;return w.each(i.mark,function(e,a){var i=e.split("-");i[0]!=t[0]&&0!=i[0]||i[1]!=t[1]&&0!=i[1]||i[2]!=t[2]||(n=a||t[2])}),n&&e.html('<span class="laydate-day-mark">'+n+"</span>"),a},T.prototype.limit=function(e,t,n,a){var i,r=this,o=r.config,l={},d=o[n>41?"endDate":"dateTime"],c=w.extend({},d,t||{});return w.each({now:c,min:o.min,max:o.max},function(e,t){l[e]=r.newDate(w.extend({year:t.year,month:t.month,date:t.date},function(){var e={};return w.each(a,function(n,a){e[a]=t[a]}),e}())).getTime()}),i=l.now<l.min||l.now>l.max,e&&e[i?"addClass":"removeClass"](s),i},T.prototype.calendar=function(e){var t,a,i,r=this,s=r.config,l=e||s.dateTime,c=new Date,m=r.lang(),u="date"!==s.type&&"datetime"!==s.type,h=e?1:0,y=w(r.table[h]).find("td"),f=w(r.elemHeader[h][2]).find("span");if(l.year<d[0]&&(l.year=d[0],r.hint("最低只能支持到公元"+d[0]+"年")),l.year>d[1]&&(l.year=d[1],r.hint("最高只能支持到公元"+d[1]+"年")),r.firstDate||(r.firstDate=w.extend({},l)),c.setFullYear(l.year,l.month,1),t=c.getDay(),a=n.getEndDate(l.month||12,l.year),i=n.getEndDate(l.month+1,l.year),w.each(y,function(e,n){var d=[l.year,l.month],c=0;n=w(n),n.removeAttr("class"),e<t?(c=a-t+e,n.addClass("laydate-day-prev"),d=r.getAsYM(l.year,l.month,"sub")):e>=t&&e<i+t?(c=e-t,s.range||c+1===l.date&&n.addClass(o)):(c=e-i-t,n.addClass("laydate-day-next"),d=r.getAsYM(l.year,l.month)),d[1]++,d[2]=c+1,n.attr("lay-ymd",d.join("-")).html(d[2]),r.mark(n,d).limit(n,{year:d[0],month:d[1]-1,date:d[2]},e)}),w(f[0]).attr("lay-ym",l.year+"-"+(l.month+1)),w(f[1]).attr("lay-ym",l.year+"-"+(l.month+1)),"cn"===s.lang?(w(f[0]).attr("lay-type","year").html(l.year+"年"),w(f[1]).attr("lay-type","month").html(l.month+1+"月")):(w(f[0]).attr("lay-type","month").html(m.month[l.month]),w(f[1]).attr("lay-type","year").html(l.year)),u&&(s.range&&(e?r.endDate=r.endDate||{year:l.year+("year"===s.type?1:0),month:l.month+("month"===s.type?0:-1)}:r.startDate=r.startDate||{year:l.year,month:l.month},e&&(r.listYM=[[r.startDate.year,r.startDate.month+1],[r.endDate.year,r.endDate.month+1]],r.list(s.type,0).list(s.type,1),"time"===s.type?r.setBtnStatus("时间",w.extend({},r.systemDate(),r.startTime),w.extend({},r.systemDate(),r.endTime)):r.setBtnStatus(!0))),s.range||(r.listYM=[[l.year,l.month+1]],r.list(s.type,0))),s.range&&!e){var p=r.getAsYM(l.year,l.month);r.calendar(w.extend({},l,{year:p[0],month:p[1]}))}return s.range||r.limit(w(r.footer).find(g),null,0,["hours","minutes","seconds"]),s.range&&e&&!u&&r.stampRange(),r},T.prototype.list=function(e,t){var n=this,a=n.config,i=a.dateTime,r=n.lang(),l=a.range&&"date"!==a.type&&"datetime"!==a.type,d=w.elem("ul",{"class":m+" "+{year:"laydate-year-list",month:"laydate-month-list",time:"laydate-time-list"}[e]}),c=n.elemHeader[t],u=w(c[2]).find("span"),h=n.elemCont[t||0],y=w(h).find("."+m)[0],f="cn"===a.lang,p=f?"年":"",T=n.listYM[t]||{},C=["hours","minutes","seconds"],x=["startTime","endTime"][t];if(T[0]<1&&(T[0]=1),"year"===e){var M,b=M=T[0]-7;b<1&&(b=M=1),w.each(new Array(15),function(e){var i=w.elem("li",{"lay-ym":M}),r={year:M};M==T[0]&&w(i).addClass(o),i.innerHTML=M+p,d.appendChild(i),M<n.firstDate.year?(r.month=a.min.month,r.date=a.min.date):M>=n.firstDate.year&&(r.month=a.max.month,r.date=a.max.date),n.limit(w(i),r,t),M++}),w(u[f?0:1]).attr("lay-ym",M-8+"-"+T[1]).html(b+p+" - "+(M-1+p))}else if("month"===e)w.each(new Array(12),function(e){var i=w.elem("li",{"lay-ym":e}),s={year:T[0],month:e};e+1==T[1]&&w(i).addClass(o),i.innerHTML=r.month[e]+(f?"月":""),d.appendChild(i),T[0]<n.firstDate.year?s.date=a.min.date:T[0]>=n.firstDate.year&&(s.date=a.max.date),n.limit(w(i),s,t)}),w(u[f?0:1]).attr("lay-ym",T[0]+"-"+T[1]).html(T[0]+p);else if("time"===e){var E=function(){w(d).find("ol").each(function(e,a){w(a).find("li").each(function(a,i){n.limit(w(i),[{hours:a},{hours:n[x].hours,minutes:a},{hours:n[x].hours,minutes:n[x].minutes,seconds:a}][e],t,[["hours"],["hours","minutes"],["hours","minutes","seconds"]][e])})}),a.range||n.limit(w(n.footer).find(g),n[x],0,["hours","minutes","seconds"])};a.range?n[x]||(n[x]={hours:0,minutes:0,seconds:0}):n[x]=i,w.each([24,60,60],function(e,t){var a=w.elem("li"),i=["<p>"+r.time[e]+"</p><ol>"];w.each(new Array(t),function(t){i.push("<li"+(n[x][C[e]]===t?' class="'+o+'"':"")+">"+w.digit(t,2)+"</li>")}),a.innerHTML=i.join("")+"</ol>",d.appendChild(a)}),E()}if(y&&h.removeChild(y),h.appendChild(d),"year"===e||"month"===e)w(n.elemMain[t]).addClass("laydate-ym-show"),w(d).find("li").on("click",function(){var r=0|w(this).attr("lay-ym");if(!w(this).hasClass(s)){if(0===t)i[e]=r,l&&(n.startDate[e]=r),n.limit(w(n.footer).find(g),null,0);else if(l)n.endDate[e]=r;else{var c="year"===e?n.getAsYM(r,T[1]-1,"sub"):n.getAsYM(T[0],r,"sub");w.extend(i,{year:c[0],month:c[1]})}"year"===a.type||"month"===a.type?(w(d).find("."+o).removeClass(o),w(this).addClass(o),"month"===a.type&&"year"===e&&(n.listYM[t][0]=r,l&&(n[["startDate","endDate"][t]].year=r),n.list("month",t))):(n.checkDate("limit").calendar(),n.closeList()),n.setBtnStatus(),a.range||n.done(null,"change"),w(n.footer).find(D).removeClass(s)}});else{var S=w.elem("span",{"class":v}),k=function(){w(d).find("ol").each(function(e){var t=this,a=w(t).find("li");t.scrollTop=30*(n[x][C[e]]-2),t.scrollTop<=0&&a.each(function(e,n){if(!w(this).hasClass(s))return t.scrollTop=30*(e-2),!0})})},H=w(c[2]).find("."+v);k(),S.innerHTML=a.range?[r.startTime,r.endTime][t]:r.timeTips,w(n.elemMain[t]).addClass("laydate-time-show"),H[0]&&H.remove(),c[2].appendChild(S),w(d).find("ol").each(function(e){var t=this;w(t).find("li").on("click",function(){var r=0|this.innerHTML;w(this).hasClass(s)||(a.range?n[x][C[e]]=r:i[C[e]]=r,w(t).find("."+o).removeClass(o),w(this).addClass(o),E(),k(),(n.endDate||"time"===a.type)&&n.done(null,"change"),n.setBtnStatus())})})}return n},T.prototype.listYM=[],T.prototype.closeList=function(){var e=this;e.config;w.each(e.elemCont,function(t,n){w(this).find("."+m).remove(),w(e.elemMain[t]).removeClass("laydate-ym-show laydate-time-show")}),w(e.elem).find("."+v).remove()},T.prototype.setBtnStatus=function(e,t,n){var a,i=this,r=i.config,o=w(i.footer).find(g),d=r.range&&"date"!==r.type&&"time"!==r.type;d&&(t=t||i.startDate,n=n||i.endDate,a=i.newDate(t).getTime()>i.newDate(n).getTime(),i.limit(null,t)||i.limit(null,n)?o.addClass(s):o[a?"addClass":"removeClass"](s),e&&a&&i.hint("string"==typeof e?l.replace(/日期/g,e):l))},T.prototype.parse=function(e,t){var n=this,a=n.config,i=t||(e?w.extend({},n.endDate,n.endTime):a.range?w.extend({},n.startDate,n.startTime):a.dateTime),r=n.format.concat();return w.each(r,function(e,t){/yyyy|y/.test(t)?r[e]=w.digit(i.year,t.length):/MM|M/.test(t)?r[e]=w.digit(i.month+1,t.length):/dd|d/.test(t)?r[e]=w.digit(i.date,t.length):/HH|H/.test(t)?r[e]=w.digit(i.hours,t.length):/mm|m/.test(t)?r[e]=w.digit(i.minutes,t.length):/ss|s/.test(t)&&(r[e]=w.digit(i.seconds,t.length))}),a.range&&!e?r.join("")+" "+a.range+" "+n.parse(1):r.join("")},T.prototype.newDate=function(e){return new Date(e.year||1,e.month||0,e.date||1,e.hours||0,e.minutes||0,e.seconds||0)},T.prototype.setValue=function(e){var t=this,n=t.config,a=t.bindElem||n.elem[0],i=t.isInput(a)?"val":"html";return"static"===n.position||w(a)[i](e||""),this},T.prototype.stampRange=function(){var e,t,n=this,a=n.config,i=w(n.elem).find("td");if(a.range&&!n.endDate&&w(n.footer).find(g).addClass(s),n.endDate)return e=n.newDate({year:n.startDate.year,month:n.startDate.month,date:n.startDate.date}).getTime(),t=n.newDate({year:n.endDate.year,month:n.endDate.month,date:n.endDate.date}).getTime(),e>t?n.hint(l):void w.each(i,function(a,i){var r=w(i).attr("lay-ymd").split("-"),s=n.newDate({year:r[0],month:r[1]-1,date:r[2]}).getTime();w(i).removeClass(u+" "+o),s!==e&&s!==t||w(i).addClass(w(i).hasClass(y)||w(i).hasClass(f)?u:o),s>e&&s<t&&w(i).addClass(u)})},T.prototype.done=function(e,t){var n=this,a=n.config,i=w.extend({},n.startDate?w.extend(n.startDate,n.startTime):a.dateTime),r=w.extend({},w.extend(n.endDate,n.endTime));return w.each([i,r],function(e,t){"month"in t&&w.extend(t,{month:t.month+1})}),e=e||[n.parse(),i,r],"function"==typeof a[t||"done"]&&a[t||"done"].apply(a,e),n},T.prototype.choose=function(e){var t=this,n=t.config,a=n.dateTime,i=w(t.elem).find("td"),r=e.attr("lay-ymd").split("-"),l=function(e){new Date;e&&w.extend(a,r),n.range&&(t.startDate?w.extend(t.startDate,r):t.startDate=w.extend({},r,t.startTime),t.startYMD=r)};if(r={year:0|r[0],month:(0|r[1])-1,date:0|r[2]},!e.hasClass(s))if(n.range){if(w.each(["startTime","endTime"],function(e,n){t[n]=t[n]||{hours:0,minutes:0,seconds:0}}),t.endState)l(),delete t.endState,delete t.endDate,t.startState=!0,i.removeClass(o+" "+u),e.addClass(o);else if(t.startState){if(e.addClass(o),t.endDate?w.extend(t.endDate,r):t.endDate=w.extend({},r,t.endTime),t.newDate(r).getTime()<t.newDate(t.startYMD).getTime()){var d=w.extend({},t.endDate,{hours:t.startDate.hours,minutes:t.startDate.minutes,seconds:t.startDate.seconds});w.extend(t.endDate,t.startDate,{hours:t.endDate.hours,minutes:t.endDate.minutes,seconds:t.endDate.seconds}),t.startDate=d}n.showBottom||t.done(),t.stampRange(),t.endState=!0,t.done(null,"change")}else e.addClass(o),l(),t.startState=!0;w(t.footer).find(g)[t.endDate?"removeClass":"addClass"](s)}else"static"===n.position?(l(!0),t.calendar().done().done(null,"change")):"date"===n.type?(l(!0),t.setValue(t.parse()).remove().done()):"datetime"===n.type&&(l(!0),t.calendar().done(null,"change"))},T.prototype.tool=function(e,t){var n=this,a=n.config,i=a.dateTime,r="static"===a.position,o={datetime:function(){w(e).hasClass(s)||(n.list("time",0),a.range&&n.list("time",1),w(e).attr("lay-type","date").html(n.lang().dateTips))},date:function(){n.closeList(),w(e).attr("lay-type","datetime").html(n.lang().timeTips)},clear:function(){n.setValue("").remove(),r&&(w.extend(i,n.firstDate),n.calendar()),a.range&&(delete n.startState,delete n.endState,delete n.endDate,delete n.startTime,delete n.endTime),n.done(["",{},{}])},now:function(){var e=new Date;w.extend(i,n.systemDate(),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()}),n.setValue(n.parse()).remove(),r&&n.calendar(),n.done()},confirm:function(){if(a.range){if(!n.endDate)return n.hint("请先选择日期范围");if(w(e).hasClass(s))return n.hint("time"===a.type?l.replace(/日期/g,"时间"):l)}else if(w(e).hasClass(s))return n.hint("不在有效日期或时间范围内");n.done(),n.setValue(n.parse()).remove()}};o[t]&&o[t]()},T.prototype.change=function(e){var t=this,n=t.config,a=n.dateTime,i=n.range&&("year"===n.type||"month"===n.type),r=t.elemCont[e||0],o=t.listYM[e],s=function(s){var l=["startDate","endDate"][e],d=w(r).find(".laydate-year-list")[0],c=w(r).find(".laydate-month-list")[0];return d&&(o[0]=s?o[0]-15:o[0]+15,t.list("year",e)),c&&(s?o[0]--:o[0]++,t.list("month",e)),(d||c)&&(w.extend(a,{year:o[0]}),i&&(t[l].year=o[0]),n.range||t.done(null,"change"),t.setBtnStatus(),n.range||t.limit(w(t.footer).find(g),{year:o[0]})),d||c};return{prevYear:function(){s("sub")||(a.year--,t.checkDate("limit").calendar(),n.range||t.done(null,"change"))},prevMonth:function(){var e=t.getAsYM(a.year,a.month,"sub");w.extend(a,{year:e[0],month:e[1]}),t.checkDate("limit").calendar(),n.range||t.done(null,"change")},nextMonth:function(){var e=t.getAsYM(a.year,a.month);w.extend(a,{year:e[0],month:e[1]}),t.checkDate("limit").calendar(),n.range||t.done(null,"change")},nextYear:function(){s()||(a.year++,t.checkDate("limit").calendar(),n.range||t.done(null,"change"))}}},T.prototype.changeEvent=function(){var e=this;e.config;w(e.elem).on("click",function(e){w.stope(e)}),w.each(e.elemHeader,function(t,n){w(n[0]).on("click",function(n){e.change(t).prevYear()}),w(n[1]).on("click",function(n){e.change(t).prevMonth()}),w(n[2]).find("span").on("click",function(n){var a=w(this),i=a.attr("lay-ym"),r=a.attr("lay-type");i&&(i=i.split("-"),e.listYM[t]=[0|i[0],0|i[1]],e.list(r,t),w(e.footer).find(D).addClass(s))}),w(n[3]).on("click",function(n){e.change(t).nextMonth()}),w(n[4]).on("click",function(n){e.change(t).nextYear()})}),w.each(e.table,function(t,n){var a=w(n).find("td");a.on("click",function(){e.choose(w(this))})}),w(e.footer).find("span").on("click",function(){var t=w(this).attr("lay-type");e.tool(this,t)})},T.prototype.isInput=function(e){return/input|textarea/.test(e.tagName.toLocaleLowerCase())},T.prototype.events=function(){var e=this,t=e.config,n=function(n,a){n.on(t.trigger,function(){a&&(e.bindElem=this),e.render()})};t.elem[0]&&!t.elem[0].eventHandler&&(n(t.elem,"bind"),n(t.eventElem),w(document).on("click",function(n){n.target!==t.elem[0]&&n.target!==t.eventElem[0]&&n.target!==w(t.closeStop)[0]&&e.remove()}).on("keydown",function(t){13===t.keyCode&&w("#"+e.elemID)[0]&&e.elemID===T.thisElem&&(t.preventDefault(),w(e.footer).find(g)[0].click())}),w(window).on("resize",function(){return!(!e.elem||!w(r)[0])&&void e.position()}),t.elem[0].eventHandler=!0)},n.render=function(e){var t=new T(e);return a.call(t)},n.getEndDate=function(e,t){var n=new Date;return n.setFullYear(t||n.getFullYear(),e||n.getMonth()+1,1),new Date(n.getTime()-864e5).getDate()},window.lay=window.lay||w,e?(n.ready(),layui.define(function(e){n.path=layui.cache.dir,e(i,n)})):"function"==typeof define&&define.amd?define(function(){return n}):function(){n.ready(),window.laydate=n}()}();!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&"length"in e&&e.length,n=pe.type(e);return"function"!==n&&!pe.isWindow(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener("DOMContentLoaded",s),e.removeEventListener("load",s)):(re.detachEvent("onreadystatechange",s),e.detachEvent("onload",s))}function s(){(re.addEventListener||"load"===e.event.type||"complete"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r="data-"+t.replace(_e,"-$1").toLowerCase();if(n=e.getAttribute(r),"string"==typeof n){try{n="true"===n||"false"!==n&&("null"===n?null:+n+""===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if(("data"!==t||!pe.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||"string"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),"object"!=typeof t&&"function"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),"string"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,"")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?"":"px"),c=(pe.cssNumber[t]||"px"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||".5",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,"globalEval",!t||pe._data(t[r],"globalEval"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if("object"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement("div")),l=(We.exec(a)||["",""])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a="table"!==l||Ve.test(a)?"<table>"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],"tbody")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent="";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,"input"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),"script"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||"")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,"table")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function C(e){return e.type=(null!==pe.find.attr(e,"type"))+"/"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}"script"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:"input"!==n&&"textarea"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&"string"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,"script"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,"script"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||"")&&!pe._data(o,"globalEval")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||"").replace(ot,"")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,"script")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],"display");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),"none"!==n&&n||(ut=(ut||pe("<iframe frameborder='0' width='0' height='0'/>")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&Re(r)&&(o[a]=pe._data(r,"olddisplay",j(r.nodeName)))):(i=Re(r),(n&&"none"!==n||!i)&&pe._data(r,"olddisplay",i?n:pe.css(r,"display"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function F(e,t,n,r,i){for(var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;o<4;o+=2)"margin"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?("content"===n&&(a-=pe.css(e,"padding"+Oe[o],!0,i)),"margin"!==n&&(a-=pe.css(e,"border"+Oe[o]+"Width",!0,i))):(a+=pe.css(e,"padding"+Oe[o],!0,i),"padding"!==n&&(a+=pe.css(e,"border"+Oe[o]+"Width",!0,i)));return a}function M(t,n,r){var i=!0,o="width"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&"border-box"===pe.css(t,"boxSizing",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?"border":"content"),i,a)+"px"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,"fxshow");n.queue||(s=pe._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,"display"),c="none"===l?pe._data(e,"olddisplay")||j(e.nodeName):l,"inline"===c&&"none"===pe.css(e,"float")&&(fe.inlineBlockNeedsLayout&&"inline"!==j(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(h?"hide":"show")){if("show"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))"inline"===("none"===l?j(e.nodeName):l)&&(p.display=l);else{g?"hidden"in g&&(h=g.hidden):g=pe._data(e,"fxshow",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,"fxshow");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,"class")||""}function X(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)"+"===r.charAt(0)?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o["*"]&&i("*")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader("Content-Type"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+" "+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(a=l[u+" "+o]||l["* "+o],!a)for(i in l)if(s=i.split(" "),s[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(f){return{state:"parsererror",error:a?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,"display")}function K(e){for(;e&&1===e.nodeType;){if("none"===G(e)||"hidden"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==pe.type(t))r(e,t);else for(i in t)Q(e+"["+i+"]",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de="1.12.3",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,ge=/^-ms-/,me=/-([\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:"",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:"jQuery"+(de+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return"function"===pe.type(e)},isArray:Array.isArray||function(e){return"array"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||"object"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,"constructor")&&!ce.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?ue[le.call(e)]||"object":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,"ms-").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?"":(e+"").replace(he,"")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,"string"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if("string"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),"function"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){ue["[object "+t+"]"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],"string"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+" "]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if("object"!==t.nodeName.toLowerCase()){for((s=t.getAttribute("id"))?s=s.replace(xe,"\\$&"):t.setAttribute("id",s=P),f=N(e),o=f.length,u=de.test(s)?"#"+s:"[id='"+s+"']";o--;)f[o]=u+" "+d(f[o]);p=f.join(","),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute("id")}}}return S(e.replace(se,"$1"),t,n,r)}function n(){function e(n,r){return t.push(n+" ")>T.cacheLength&&delete e[t.shift()],e[n+" "]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split("|"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&"parentNode"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||"*",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[" "],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(se,"$1"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h="0",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG("*",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P="sizzle"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",ne="[\\x20\\t\\r\\n\\f]",re="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",ie="\\["+ne+"*("+re+")(?:"+ne+"*([*^$|!~]?=)"+ne+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+re+"))|)"+ne+"*\\]",oe=":("+re+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+ie+")*)|.*)\\)|)",ae=new RegExp(ne+"+","g"),se=new RegExp("^"+ne+"+|((?:^|[^\\\\])(?:\\\\.)*)"+ne+"+$","g"),ue=new RegExp("^"+ne+"*,"+ne+"*"),le=new RegExp("^"+ne+"*([>+~]|"+ne+")"+ne+"*"),ce=new RegExp("="+ne+"*([^\\]'\"]*?)"+ne+"*\\]","g"),fe=new RegExp(oe),de=new RegExp("^"+re+"$"),pe={ID:new RegExp("^#("+re+")"),CLASS:new RegExp("^\\.("+re+")"),TAG:new RegExp("^("+re+"|[*])"),ATTR:new RegExp("^"+ie),PSEUDO:new RegExp("^"+oe),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ne+"*(even|odd|(([+-]|)(\\d*)n|)"+ne+"*(?:([+-]|)"+ne+"*(\\d+)|))"+ne+"*\\)|)","i"),bool:new RegExp("^(?:"+te+")$","i"),needsContext:new RegExp("^"+ne+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ne+"*((?:-\\d)?\\d*)"+ne+"*\\)|)(?=[^-]|$)","i")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\d$/i,me=/^[^{]+\{\s*\[native \w/,ye=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ve=/[+~]/,xe=/'|\\/g,be=new RegExp("\\\\([\\da-f]{1,6}"+ne+"?|("+ne+")|.)","ig"),we=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",Te,!1):n.attachEvent&&n.attachEvent("onunload",Te)),w.attributes=i(function(e){return e.className="i",!e.getAttribute("className")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment("")),!e.getElementsByTagName("*").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute("id")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML="<a id='"+P+"'></a><select id='"+P+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&F.push("[*^$]="+ne+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||F.push("\\["+ne+"*(?:value|"+te+")"),e.querySelectorAll("[id~="+P+"-]").length||F.push("~="),e.querySelectorAll(":checked").length||F.push(":checked"),e.querySelectorAll("a#"+P+"+*").length||F.push(".#.+[+~]")}),i(function(e){var t=H.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&F.push("name"+ne+"*[*^$|!~]?="),e.querySelectorAll(":enabled").length||F.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),F.push(",.*:")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,"div"),O.call(e,"[s!='']:x"),M.push("!=",oe)}),F=F.length&&new RegExp(F.join("|")),M=M.length&&new RegExp(M.join("|")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,"='$1']"),w.matchesSelector&&_&&!X[n+" "]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||"").replace(be,we),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+" "];return t||(t=new RegExp("(^|"+ne+")"+e+"("+ne+"|$)"))&&$(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?"!="===n:!n||(o+="","="===n?o===r:"!="===n?o!==r:"^="===n?r&&0===o.indexOf(r):"*="===n?r&&o.indexOf(r)>-1:"$="===n?r&&o.slice(-r.length)===r:"~="===n?(" "+o.replace(ae," ")+" ").indexOf(r)>-1:"|="===n&&(o===r||o.slice(0,r.length+1)===r+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}), +l=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error("unsupported pseudo: "+e);return o[P]?o(n):o.length>1?(i=[e,e,"",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,"$1"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||"")||t.error("unsupported lang: "+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+" "];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se," ")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+" "];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&"ID"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split("").sort(U).join("")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement("div"))}),i(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||o("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||o("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute("disabled")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[":"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,Ce=/^.[^:#\[\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,"string"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,"string"==typeof e){if(r="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?"undefined"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||"string"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,"parentNode")},parentsUntil:function(e,t,n){return xe(e,"parentNode",n)},next:function(e){return i(e,"nextSibling")},prev:function(e){return i(e,"previousSibling")},nextAll:function(e){return xe(e,"nextSibling")},prevAll:function(e){return xe(e,"previousSibling")},nextUntil:function(e,t,n){return xe(e,"nextSibling",n)},prevUntil:function(e,t,n){return xe(e,"previousSibling",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\S+/g;pe.Callbacks=function(e){e="string"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:"")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&"string"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n="",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[["resolve","done",pe.Callbacks("once memory"),"resolved"],["reject","fail",pe.Callbacks("once memory"),"rejected"],["notify","progress",pe.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+"With"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler("ready"),pe(re).off("ready"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),"complete"===re.readyState||"loading"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener("DOMContentLoaded",s),e.addEventListener("load",s);else{re.attachEvent("onreadystatechange",s),e.attachEvent("onload",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll("left")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst="0"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName("body")[0],n&&n.style&&(t=re.createElement("div"),r=re.createElement("div"),r.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),"undefined"!=typeof t.style.zoom&&(t.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement("div");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+" ").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute("classid")===t)},qe=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,"parsedAttrs"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf("data-")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,"parsedAttrs",!0)}return i}return"object"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks("once memory").add(function(){pe._removeData(e,t+"queue"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),"fx"===e&&"inprogress"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for("string"!=typeof e&&(t=e,e=void 0),e=e||"fx";a--;)n=pe._data(o[a],e+"queueHooks"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName("body")[0],n&&n.style?(t=re.createElement("div"),r=re.createElement("div"),r.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",n.appendChild(r).appendChild(t),"undefined"!=typeof t.style.zoom&&(t.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",t.appendChild(re.createElement("div")).style.width="5px",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,Me=new RegExp("^(?:([+-])=|)("+Fe+")([a-z%]*)$","i"),Oe=["Top","Right","Bottom","Left"],Re=function(e,t){return e=t||e,"none"===pe.css(e,"display")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\w:-]+)/,Ie=/^$|\/(?:java|ecma)script/i,$e=/^\s+/,ze="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";!function(){var e=re.createElement("div"),t=re.createDocumentFragment(),n=re.createElement("input");e.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName("tbody").length,fe.htmlSerialize=!!e.getElementsByTagName("link").length,fe.html5Clone="<:nav></:nav>"!==re.createElement("nav").cloneNode(!0).outerHTML,n.type="checkbox",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML="<textarea>x</textarea>",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement("input"),n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:fe.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement("div");for(t in{submit:!0,change:!0,focusin:!0})n="on"+t,(fe[t]=n in e)||(r.setAttribute(n,"t"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return"undefined"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||"").match(De)||[""],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||"").split(".").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(".")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent("on"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||"").match(De)||[""],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||"").split(".").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,"events"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,"type")?t.type:t,h=ce.call(t,"namespace")?t.namespace.split("."):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(".")>-1&&(h=p.split("."),p=h.shift(),h.sort()),a=p.indexOf(":")<0&&"on"+p,t=t[pe.expando]?t:new pe.Event(p,"object"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,"events")||{})[t.type]&&pe._data(s,"handle"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,"events")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&("click"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+" ",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if(pe.nodeName(this,"input")&&"checkbox"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r="on"+t;e.detachEvent&&("undefined"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,"form")&&void pe.event.add(this,"click._submit keypress._submit",function(e){var t=e.target,n=pe.nodeName(t,"input")||pe.nodeName(t,"button")?pe.prop(t,"form"):void 0;n&&!pe._data(n,"submit")&&(pe.event.add(n,"submit._submit",function(e){e._submitBubble=!0}),pe._data(n,"submit",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate("submit",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,"form")&&void pe.event.remove(this,"._submit")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(pe.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,"click._change",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate("change",this,e)})),!1):void pe.event.add(this,"beforeactivate._change",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,"change")&&(pe.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate("change",this.parentNode,e)}),pe._data(t,"change",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||"radio"!==t.type&&"checkbox"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,"._change"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&"function"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\d+="(?:null|\d+)"/g,et=new RegExp("<(?:"+ze+")[\\s/>]","i"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,nt=/<script|<style|<link/i,rt=/checked\s*(?:[^=]|=\s*.checked.)/i,it=/^true\/(.*)/,ot=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,at=p(re),st=at.appendChild(re.createElement("div"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,"script"),r.length>0&&g(r,!u&&h(e,"script")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||"undefined"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,""):void 0;if("string"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||["",""])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)), +n&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:"block",BODY:"block"},ct=/^margin/,ft=new RegExp("^("+Fe+")(?!px)[a-z%]+$","i"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n="1%"!==(c||{}).top,s="2px"===(c||{}).marginLeft,i="4px"===(c||{width:"4px"}).width,l.style.marginRight="50%",r="4px"===(c||{marginRight:"4px"}).marginRight,t=l.appendChild(re.createElement("div")),t.style.cssText=l.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",t.style.marginRight=t.style.width="0",l.style.width="1px",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display="none",o=0===l.getClientRects().length,o&&(l.style.display="",l.innerHTML="<table><tr><td></td><td>t</td></tr></table>",t=l.getElementsByTagName("td"),t[0].style.cssText="margin:0;border:0;padding:0;display:none",o=0===t[0].offsetHeight,o&&(t[0].style.display="",t[1].style.display="none",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement("div"),l=re.createElement("div");l.style&&(l.style.cssText="float:left;opacity:.5",fe.opacity="0.5"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",fe.clearCloneStyle="content-box"===l.style.backgroundClip,u=re.createElement("div"),u.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",l.innerHTML="",u.appendChild(l),fe.boxSizing=""===l.style.boxSizing||""===l.style.MozBoxSizing||""===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,""!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+""}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left="fontSize"===t?"1em":a,a=s.pixelLeft+"px",s.left=r,o&&(i.left=o)),void 0===a?a:a+""||"auto"});var yt=/alpha\([^)]*\)/i,vt=/opacity\s*=\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp("^("+Fe+")(.*)$","i"),wt={position:"absolute",visibility:"hidden",display:"block"},Tt={letterSpacing:"0",fontWeight:"400"},Ct=["Webkit","O","Moz","ms"],Et=re.createElement("div").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":fe.cssFloat?"cssFloat":"styleFloat"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,"string"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?"":"px")),fe.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),!(a&&"set"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&"get"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),"normal"===o&&t in Tt&&(o=Tt[t]),""===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each(["height","width"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,"display"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&"border-box"===pe.css(e,"boxSizing",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===pe.trim(o.replace(yt,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+" "+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:"inline-block"},gt,[e,"marginRight"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,"marginLeft"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+"px"}),pe.each({margin:"",padding:"",border:"Width"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?"":"px")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=["*"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&"object"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue="fx"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return"string"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,i=null!=e&&e+"queueHooks",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=pe._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each(["toggle","show","hide"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P("show"),slideUp:P("hide"),slideToggle:P("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||"fx",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement("input"),n=re.createElement("div"),r=re.createElement("select"),i=r.appendChild(re.createElement("option"));n=re.createElement("div"),n.setAttribute("className","t"),n.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",e=n.getElementsByTagName("a")[0],t.setAttribute("type","checkbox"),n.appendChild(t),e=n.getElementsByTagName("a")[0],e.style.cssText="top:1px",fe.getSetAttribute="t"!==n.className,fe.style=/top/.test(e.getAttribute("style")),fe.hrefNormalized="/a"===e.getAttribute("href"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement("form").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement("input"),t.setAttribute("value",""),fe.input=""===t.getAttribute("value"),t.value="t",t.setAttribute("type","radio"),fe.radioValue="t"===t.value}();var Dt=/\r/g,jt=/[\x20\t\r\n\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i="":"number"==typeof i?i+="":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?"":e+""})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"==typeof n?n.replace(Dt,""):null==n?"":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,"value");return null!=t?t:pe.trim(pe.text(e)).replace(jt," ")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute("disabled"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,"optgroup"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each(["radio","checkbox"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&"radio"===t&&pe.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase("default-"+n)]=e[r]=!1:pe.attr(e,n,""),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase("default-"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase("default-"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,"input")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+="","value"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&""!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,""!==t&&t,n)}},pe.each(["width","height"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(""===n)return e.setAttribute(t,"auto"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+""}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,"tabindex");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),fe.hrefNormalized||pe.each(["href","src"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype="encoding");var Pt=/[\t\r\n\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if("string"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");s=pe.trim(r),i!==s&&pe.attr(n,"class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(" "+i+" ").replace(Pt," ")){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");s=pe.trim(r),i!==s&&pe.attr(n,"class",s)}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if("string"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&"boolean"!==n||(t=z(this),t&&pe._data(this,"__className__",t),pe.attr(this,"class",t||e===!1?"":pe._data(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+z(n)+" ").replace(Pt," ").indexOf(t)>-1)return!0;return!1}}),pe.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\?/,$t=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+"");var n,r=null,i=pe.trim(t+"");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,"")}))?Function("return "+i)():pe.error("Invalid JSON: "+t)},pe.parseXML=function(t){var n,r;if(!t||"string"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,"text/xml")):(n=new e.ActiveXObject("Microsoft.XMLDOM"),n.async="false",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName("parsererror").length||pe.error("Invalid XML: "+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\/\//,Gt=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Kt={},Qt={},Zt="*/".concat("*"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:"GET",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Zt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":pe.parseJSON,"text xml":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||"",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader("etag"),w&&(pe.etag[a]=w)),204===t||"HEAD"===d.type?C="nocontent":304===t?C="notmodified":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C="error",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+"",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?"ajaxSuccess":"ajaxError",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger("ajaxComplete",[T,d]),--pe.active||pe.event.trigger("ajaxStop")))}"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks("once memory"),y=d.statusCode||{},v={},x={},b=0,w="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+"").replace(zt,"").replace(Jt,tn[1]+"//"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||"*").toLowerCase().match(De)||[""],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||("http:"===i[1]?"80":"443"))===(tn[3]||("http:"===tn[1]?"80":"443")))),d.data&&d.processData&&"string"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger("ajaxStart"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?"&":"?")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,"$1_="+Wt++):a+(It.test(a)?"&":"?")+"_="+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader("If-Modified-Since",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader("If-None-Match",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader("Content-Type",d.contentType),T.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+("*"!==d.dataTypes[0]?", "+Zt+"; q=0.01":""):d.accepts["*"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w="abort";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger("ajaxSend",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort("timeout")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,"No Transport");return T},getJSON:function(e,t,n){return pe.get(e,t,n,"json")},getScript:function(e,t){return pe.get(e,void 0,t,"script")}}),pe.each(["get","post"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,"body")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\[\]$/,on=/\r?\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?"":t,r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join("&").replace(nn,"+")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,"elements");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(":disabled")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent("onunload",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&"withCredentials"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r["X-Requested-With"]||(r["X-Requested-With"]="XMLHttpRequest");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+"");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,"string"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=""}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),pe.ajaxTransport("script",function(e){if(e.crossDomain){var t,n=re.head||pe("head")[0]||re.documentElement;return{send:function(r,i){t=re.createElement("script"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,"success"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\?(?=&|$)|\?\?/;pe.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=fn.pop()||pe.expando+"_"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&dn.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,"$1"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||pe.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),"script"}),pe.parseHTML=function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if("string"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(" ");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),a.length>0&&pe.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?pe("<div>").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,"position"),f=pe(e),d={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=pe.css(e,"top"),u=pe.css(e,"left"),l=("absolute"===c||"fixed"===c)&&pe.inArray("auto",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),"using"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?("undefined"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===pe.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],"html")||(n=e.offset()),n.top+=pe.css(e[0],"borderTopWidth",!0),n.left+=pe.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-pe.css(r,"marginTop",!0),left:t.left-n.left-pe.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){ +for(var e=this.offsetParent;e&&!pe.nodeName(e,"html")&&"static"===pe.css(e,"position");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each(["top","left"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+"px":n})}),pe.each({Height:"height",Width:"width"},function(e,t){pe.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||"boolean"!=typeof r),a=n||(r===!0||i===!0?"margin":"border");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement["client"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body["scroll"+e],i["scroll"+e],t.body["offset"+e],i["offset"+e],i["client"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){layui.$=pe,e("jquery",pe)}),pe});!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.scripts,t=e[e.length-1],i=t.src;if(!t.getAttribute("merge"))return i.substring(0,i.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function u(){return++c>80?e.console&&console.error("layer.css: Invalid"):void(1989===parseInt(o.getStyle(document.getElementById(f),"width"))?i():setTimeout(u,100))}()}}},r={v:"3.1.0",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"&#x4FE1;&#x606F;",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'<div class="layui-layer-title" style="'+(f?r.title[1]:"")+'">'+(f?r.title[0]:r.title)+"</div>":"";return r.zIndex=s,t([r.shade?'<div class="layui-layer-shade" id="layui-layer-shade'+a+'" times="'+a+'" style="'+("z-index:"+(s-1)+"; ")+'"></div>':"",'<div class="'+l[0]+(" layui-layer-"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?"":" layui-layer-border")+" "+(r.skin||"")+'" id="'+l[0]+a+'" type="'+o.type[r.type]+'" times="'+a+'" showtime="'+r.time+'" conType="'+(e?"object":"string")+'" style="z-index: '+s+"; width:"+r.area[0]+";height:"+r.area[1]+(r.fixed?"":";position:absolute;")+'">'+(e&&2!=r.type?"":u)+'<div id="'+(r.id||"")+'" class="layui-layer-content'+(0==r.type&&r.icon!==-1?" layui-layer-padding":"")+(3==r.type?" layui-layer-loading"+r.icon:"")+'">'+(0==r.type&&r.icon!==-1?'<i class="layui-layer-ico layui-layer-ico'+r.icon+'"></i>':"")+(1==r.type&&e?"":r.content||"")+'</div><span class="layui-layer-setwin">'+function(){var e=c?'<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>':"";return r.closeBtn&&(e+='<a class="layui-layer-ico '+l[7]+" "+l[7]+(r.title?r.closeBtn:4==r.type?"1":"2")+'" href="javascript:;"></a>'),e}()+"</span>"+(r.btn?function(){var e="";"string"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class="'+l[6]+t+'">'+r.btn[t]+"</a>";return'<div class="'+l[6]+" layui-layer-btn-"+(r.btnAlign||"")+'">'+e+"</div>"}():"")+(r.resize?'<span class="layui-layer-resize"></span>':"")+"</div>"],u,i('<div class="layui-layer-move"></div>')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f="object"==typeof s,c=i("body");if(!t.id||!i("#"+t.id)[0]){switch("string"==typeof t.area&&(t.area="auto"===t.area?["",""]:[t.area,""]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn="btn"in t?t.btn:o.btn[0],r.closeAll("dialog");break;case 2:var s=t.content=f?t.content:[t.content||"http://layer.layui.com","auto"];t.content='<iframe scrolling="'+(t.content[1]||"auto")+'" allowtransparency="true" id="'+l[4]+a+'" name="'+l[4]+a+'" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="'+t.content[0]+'"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'<i class="layui-layer-TipsG"></i>',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>u&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'<textarea class="layui-layer-input"'+a+">"+(e.value||"")+"</textarea>":function(){return'<input type="'+(1==e.formType?"password":"text")+'" class="layui-layer-input" value="'+(e.value||"")+'">'}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["&#x786E;&#x5B9A;","&#x53D6;&#x6D88;"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("&#x6700;&#x591A;&#x8F93;&#x5165;"+(e.maxlength||500)+"&#x4E2A;&#x5B57;&#x6570;",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a='<span class="'+n+'">'+t[0].title+"</span>";i<e;i++)a+="<span>"+t[i].title+"</span>";return a}(),content:'<ul class="layui-layer-tabmain">'+function(){var e=t.length,i=1,a="";if(e>0)for(a='<li class="layui-layer-tabli '+n+'">'+(t[0].content||"no content")+"</li>";i<e;i++)a+='<li class="layui-layer-tabli">'+(t[i].content||"no content")+"</li>";return a}()+"</ul>",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("&#x6CA1;&#x6709;&#x56FE;&#x7247;")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+"px",a[1]+"px"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:".layui-layer-phimg img",moveType:1,scrollbar:!1,moveOut:!0,isOutAnim:!1,skin:"layui-layer-photos"+c("photos"),content:'<div class="layui-layer-phimg"><img src="'+u[d].src+'" alt="'+(u[d].alt||"")+'" layer-pid="'+u[d].pid+'"><div class="layui-layer-imgsee">'+(u.length>1?'<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>':"")+'<div class="layui-layer-imgbar" style="display:'+(a?"block":"")+'"><span class="layui-layer-imgtit"><a href="javascript:;">'+(u[d].alt||"")+"</a><em>"+s.imgIndex+"/"+u.length+"</em></span></div></div></div>",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;",{time:3e4,btn:["&#x4E0B;&#x4E00;&#x5F20;","&#x4E0D;&#x770B;&#x4E86;"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);layui.define("jquery",function(i){"use strict";var t=layui.$,a=(layui.hint(),layui.device()),e="element",l="layui-this",n="layui-show",s=function(){this.config={}};s.prototype.set=function(i){var a=this;return t.extend(!0,a.config,i),a},s.prototype.on=function(i,t){return layui.onevent.call(this,e,i,t)},s.prototype.tabAdd=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.children(".layui-tab-bar"),o=l.children(".layui-tab-content"),c='<li lay-id="'+(a.id||"")+'">'+(a.title||"unnaming")+"</li>";return s[0]?s.before(c):n.append(c),o.append('<div class="layui-tab-item">'+(a.content||"")+"</div>"),f.hideTabMore(!0),f.tabAuto(),this},s.prototype.tabDelete=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.find('>li[lay-id="'+a+'"]');return f.tabDelete(null,s),this},s.prototype.tabChange=function(i,a){var e=".layui-tab-title",l=t(".layui-tab[lay-filter="+i+"]"),n=l.children(e),s=n.find('>li[lay-id="'+a+'"]');return f.tabClick(null,null,s),this},s.prototype.tab=function(i){i=i||{},b.on("click",i.headerElem,function(a){var e=t(this).index();f.tabClick.call(this,a,e,null,i)})},s.prototype.progress=function(i,a){var e="layui-progress",l=t("."+e+"[lay-filter="+i+"]"),n=l.find("."+e+"-bar"),s=n.find("."+e+"-text");return n.css("width",a),s.text(a),this};var o=".layui-nav",c="layui-nav-item",r="layui-nav-bar",u="layui-nav-tree",d="layui-nav-child",h="layui-nav-more",y="layui-anim layui-anim-upbit",f={tabClick:function(i,a,s,o){o=o||{};var c=s||t(this),a=a||c.parent().children("li").index(c),r=o.headerElem?c.parent():c.parents(".layui-tab").eq(0),u=o.bodyElem?t(o.bodyElem):r.children(".layui-tab-content").children(".layui-tab-item"),d=c.find("a"),h=r.attr("lay-filter");"javascript:;"!==d.attr("href")&&"_blank"===d.attr("target")||(c.addClass(l).siblings().removeClass(l),u.eq(a).addClass(n).siblings().removeClass(n)),layui.event.call(this,e,"tab("+h+")",{elem:r,index:a})},tabDelete:function(i,a){var n=a||t(this).parent(),s=n.index(),o=n.parents(".layui-tab").eq(0),c=o.children(".layui-tab-content").children(".layui-tab-item"),r=o.attr("lay-filter");n.hasClass(l)&&(n.next()[0]?f.tabClick.call(n.next()[0],null,s+1):n.prev()[0]&&f.tabClick.call(n.prev()[0],null,s-1)),n.remove(),c.eq(s).remove(),setTimeout(function(){f.tabAuto()},50),layui.event.call(this,e,"tabDelete("+r+")",{elem:o,index:s})},tabAuto:function(){var i="layui-tab-more",e="layui-tab-bar",l="layui-tab-close",n=this;t(".layui-tab").each(function(){var s=t(this),o=s.children(".layui-tab-title"),c=(s.children(".layui-tab-content").children(".layui-tab-item"),'lay-stope="tabmore"'),r=t('<span class="layui-unselect layui-tab-bar" '+c+"><i "+c+' class="layui-icon">&#xe61a;</i></span>');if(n===window&&8!=a.ie&&f.hideTabMore(!0),s.attr("lay-allowClose")&&o.find("li").each(function(){var i=t(this);if(!i.find("."+l)[0]){var a=t('<i class="layui-icon layui-unselect '+l+'">&#x1006;</i>');a.on("click",f.tabDelete),i.append(a)}}),o.prop("scrollWidth")>o.outerWidth()+1){if(o.find("."+e)[0])return;o.append(r),s.attr("overflow",""),r.on("click",function(t){o[this.title?"removeClass":"addClass"](i),this.title=this.title?"":"收缩"})}else o.find("."+e).remove(),s.removeAttr("overflow")})},hideTabMore:function(i){var a=t(".layui-tab-title");i!==!0&&"tabmore"===t(i.target).attr("lay-stope")||(a.removeClass("layui-tab-more"),a.find(".layui-tab-bar").attr("title",""))},clickThis:function(){var i=t(this),a=i.parents(o),n=a.attr("lay-filter"),s=i.find("a"),c="string"==typeof i.attr("lay-unselect");i.find("."+d)[0]||("javascript:;"!==s.attr("href")&&"_blank"===s.attr("target")||c||(a.find("."+l).removeClass(l),i.addClass(l)),layui.event.call(this,e,"nav("+n+")",i))},clickChild:function(){var i=t(this),a=i.parents(o),n=a.attr("lay-filter");a.find("."+l).removeClass(l),i.addClass(l),layui.event.call(this,e,"nav("+n+")",i)},showChild:function(){var i=t(this),a=i.parents(o),e=i.parent(),l=i.siblings("."+d);a.hasClass(u)&&(l.removeClass(y),e["none"===l.css("display")?"addClass":"removeClass"](c+"ed"))},collapse:function(){var i=t(this),a=i.find(".layui-colla-icon"),l=i.siblings(".layui-colla-content"),s=i.parents(".layui-collapse").eq(0),o=s.attr("lay-filter"),c="none"===l.css("display");if("string"==typeof s.attr("lay-accordion")){var r=s.children(".layui-colla-item").children("."+n);r.siblings(".layui-colla-title").children(".layui-colla-icon").html("&#xe602;"),r.removeClass(n)}l[c?"addClass":"removeClass"](n),a.html(c?"&#xe61a;":"&#xe602;"),layui.event.call(this,e,"collapse("+o+")",{title:i,content:l,show:c})}};s.prototype.init=function(i,e){var l=function(){return e?'[lay-filter="'+e+'"]':""}(),s={tab:function(){f.tabAuto.call({})},nav:function(){var i=200,e={},s={},p={},b=function(l,o,c){var r=t(this),f=r.find("."+d);o.hasClass(u)?l.css({top:r.position().top,height:r.children("a").height(),opacity:1}):(f.addClass(y),l.css({left:r.position().left+parseFloat(r.css("marginLeft")),top:r.position().top+r.height()-l.height()}),e[c]=setTimeout(function(){l.css({width:r.width(),opacity:1})},a.ie&&a.ie<10?0:i),clearTimeout(p[c]),"block"===f.css("display")&&clearTimeout(s[c]),s[c]=setTimeout(function(){f.addClass(n),r.find("."+h).addClass(h+"d")},300))};t(o+l).each(function(a){var l=t(this),o=t('<span class="'+r+'"></span>'),y=l.find("."+c);l.find("."+r)[0]||(l.append(o),y.on("mouseenter",function(){b.call(this,o,l,a)}).on("mouseleave",function(){l.hasClass(u)||(clearTimeout(s[a]),s[a]=setTimeout(function(){l.find("."+d).removeClass(n),l.find("."+h).removeClass(h+"d")},300))}),l.on("mouseleave",function(){clearTimeout(e[a]),p[a]=setTimeout(function(){l.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},i)})),y.each(function(){var i=t(this),a=i.find("."+d);if(a[0]&&!i.find("."+h)[0]){var e=i.children("a");e.append('<span class="'+h+'"></span>')}i.off("click",f.clickThis).on("click",f.clickThis),i.children("a").off("click",f.showChild).on("click",f.showChild),a.children("dd").off("click",f.clickChild).on("click",f.clickChild)})})},breadcrumb:function(){var i=".layui-breadcrumb";t(i+l).each(function(){var i=t(this),a=i.attr("lay-separator")||">",e=i.find("a");e.find(".layui-box")[0]||(e.each(function(i){i!==e.length-1&&t(this).append('<span class="layui-box">'+a+"</span>")}),i.css("visibility","visible"))})},progress:function(){var i="layui-progress";t("."+i+l).each(function(){var a=t(this),e=a.find(".layui-progress-bar"),l=e.attr("lay-percent");e.css("width",function(){return/^.+\/.+$/.test(l)?100*new Function("return "+l)()+"%":l}()),a.attr("lay-showPercent")&&setTimeout(function(){e.html('<span class="'+i+'-text">'+l+"</span>")},350)})},collapse:function(){var i="layui-collapse";t("."+i+l).each(function(){var i=t(this).find(".layui-colla-item");i.each(function(){var i=t(this),a=i.find(".layui-colla-title"),e=i.find(".layui-colla-content"),l="none"===e.css("display");a.find(".layui-colla-icon").remove(),a.append('<i class="layui-icon layui-colla-icon">'+(l?"&#xe602;":"&#xe61a;")+"</i>"),a.off("click",f.collapse).on("click",f.collapse)})})}};return s[i]?s[i]():layui.each(s,function(i,t){t()})},s.prototype.render=s.prototype.init;var p=new s,b=t(document);p.render();var v=".layui-tab-title li";b.on("click",v,f.tabClick),b.on("click",f.hideTabMore),t(window).on("resize",f.tabAuto),i(e,p)});layui.define("layer",function(e){"use strict";var t=layui.$,i=layui.layer,n=layui.hint(),a=layui.device(),o={config:{},set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,r,e,t)}},l=function(){var e=this;return{upload:function(t){e.upload.call(e,t)},config:e.config}},r="upload",u="layui-upload-file",c="layui-upload-form",f="layui-upload-iframe",s="layui-upload-choose",p=function(e){var i=this;i.config=t.extend({},i.config,o.config,e),i.render()};p.prototype.config={accept:"images",exts:"",auto:!0,bindAction:"",url:"",field:"file",method:"post",data:{},drag:!0,size:0,multiple:!1},p.prototype.render=function(e){var i=this,e=i.config;e.elem=t(e.elem),e.bindAction=t(e.bindAction),i.file(),i.events()},p.prototype.file=function(){var e=this,i=e.config,n=e.elemFile=t(['<input class="'+u+'" type="file" name="'+i.field+'"',i.multiple?" multiple":"",">"].join("")),o=i.elem.next();(o.hasClass(u)||o.hasClass(c))&&o.remove(),a.ie&&a.ie<10&&i.elem.wrap('<div class="layui-upload-wrap"></div>'),e.isFile()?(e.elemFile=i.elem,i.field=i.elem[0].name):i.elem.after(n),a.ie&&a.ie<10&&e.initIE()},p.prototype.initIE=function(){var e=this,i=e.config,n=t('<iframe id="'+f+'" class="'+f+'" name="'+f+'" frameborder="0"></iframe>'),a=t(['<form target="'+f+'" class="'+c+'" method="'+i.method,'" key="set-mine" enctype="multipart/form-data" action="'+i.url+'">',"</form>"].join(""));t("#"+f)[0]||t("body").append(n),i.elem.next().hasClass(f)||(e.elemFile.wrap(a),i.elem.next("."+f).append(function(){var e=[];return layui.each(i.data,function(t,i){e.push('<input type="hidden" name="'+t+'" value="'+i+'">')}),e.join("")}()))},p.prototype.msg=function(e){return i.msg(e,{icon:2,shift:6})},p.prototype.isFile=function(){var e=this.config.elem[0];if(e)return"input"===e.tagName.toLocaleLowerCase()&&"file"===e.type},p.prototype.preview=function(e){var t=this;window.FileReader&&layui.each(t.chooseFiles,function(t,i){var n=new FileReader;n.readAsDataURL(i),n.onload=function(){e&&e(t,i,this.result)}})},p.prototype.upload=function(e,i){var n,o=this,l=o.config,r=o.elemFile[0],u=function(){var i=0,n=0,a=e||o.files||o.chooseFiles||r.files,u=function(){l.multiple&&i+n===o.fileLength&&"function"==typeof l.allDone&&l.allDone({total:o.fileLength,successful:i,aborted:n})};layui.each(a,function(e,a){var r=new FormData;r.append(l.field,a),layui.each(l.data,function(e,t){r.append(e,t)}),t.ajax({url:l.url,type:l.method,data:r,contentType:!1,processData:!1,dataType:"json",success:function(t){i++,d(e,t),u()},error:function(){n++,o.msg("请求上传接口出现异常"),m(e),u()}})})},c=function(){var e=t("#"+f);o.elemFile.parent().submit(),clearInterval(p.timer),p.timer=setInterval(function(){var t,i=e.contents().find("body");try{t=i.text()}catch(n){o.msg("获取上传后的响应信息出现异常"),clearInterval(p.timer),m()}t&&(clearInterval(p.timer),i.html(""),d(0,t))},30)},d=function(e,t){if(o.elemFile.next("."+s).remove(),r.value="","object"!=typeof t)try{t=JSON.parse(t)}catch(i){return t={},o.msg("请对上传接口返回有效JSON")}"function"==typeof l.done&&l.done(t,e||0,function(e){o.upload(e)})},m=function(e){l.auto&&(r.value=""),"function"==typeof l.error&&l.error(e||0,function(e){o.upload(e)})},h=l.exts,v=function(){var t=[];return layui.each(e||o.chooseFiles,function(e,i){t.push(i.name)}),t}(),g={preview:function(e){o.preview(e)},upload:function(e,t){var i={};i[e]=t,o.upload(i)},pushFile:function(){return o.files=o.files||{},layui.each(o.chooseFiles,function(e,t){o.files[e]=t}),o.files}},y=function(){return"choose"===i?l.choose&&l.choose(g):(l.before&&l.before(g),a.ie?a.ie>9?u():c():void u())};switch(v=0===v.length?r.value.match(/[^\/\\]+\..+/g)||[]||"":v,l.accept){case"file":if(h&&!RegExp("\\w\\.("+h+")$","i").test(escape(v)))return o.msg("选择的文件中包含不支持的格式"),r.value="";break;case"video":if(!RegExp("\\w\\.("+(h||"avi|mp4|wma|rmvb|rm|flash|3gp|flv")+")$","i").test(escape(v)))return o.msg("选择的视频中包含不支持的格式"),r.value="";break;case"audio":if(!RegExp("\\w\\.("+(h||"mp3|wav|mid")+")$","i").test(escape(v)))return o.msg("选择的音频中包含不支持的格式"),r.value="";break;default:if(layui.each(v,function(e,t){RegExp("\\w\\.("+(h||"jpg|png|gif|bmp|jpeg$")+")","i").test(escape(t))||(n=!0)}),n)return o.msg("选择的图片中包含不支持的格式"),r.value=""}if(l.size>0&&!(a.ie&&a.ie<10)){var F;if(layui.each(o.chooseFiles,function(e,t){if(t.size>1024*l.size){var i=l.size/1024;i=i>=1?Math.floor(i)+(i%1>0?i.toFixed(1):0)+"MB":l.size+"KB",r.value="",F=i}}),F)return o.msg("文件不能超过"+F)}y()},p.prototype.events=function(){var e=this,i=e.config,o=function(t){e.chooseFiles={},layui.each(t,function(t,i){var n=(new Date).getTime();e.chooseFiles[n+"-"+t]=i})},l=function(t,n){var a=e.elemFile,o=t.length>1?t.length+"个文件":(t[0]||{}).name||a[0].value.match(/[^\/\\]+\..+/g)||[]||"";a.next().hasClass(s)&&a.next().remove(),e.upload(null,"choose"),e.isFile()||i.choose||a.after('<span class="layui-inline '+s+'">'+o+"</span>")};i.elem.off("upload.start").on("upload.start",function(){var a=t(this),o=a.attr("lay-data");if(o)try{o=new Function("return "+o)(),e.config=t.extend({},i,o)}catch(l){n.error("Upload element property lay-data configuration item has a syntax error: "+o)}e.config.item=a,e.elemFile[0].click()}),a.ie&&a.ie<10||i.elem.off("upload.over").on("upload.over",function(){var e=t(this);e.attr("lay-over","")}).off("upload.leave").on("upload.leave",function(){var e=t(this);e.removeAttr("lay-over")}).off("upload.drop").on("upload.drop",function(n,a){var r=t(this),u=a.originalEvent.dataTransfer.files||[];r.removeAttr("lay-over"),o(u),i.auto?e.upload(u):l(u)}),e.elemFile.off("upload.change").on("upload.change",function(){var t=this.files||[];e.fileLength=t.length,o(t),i.auto?e.upload():l(t)}),i.bindAction.off("upload.action").on("upload.action",function(){e.upload()}),i.elem.data("haveEvents")||(e.elemFile.on("change",function(){t(this).trigger("upload.change")}),i.elem.on("click",function(){e.isFile()||t(this).trigger("upload.start")}),i.drag&&i.elem.on("dragover",function(e){e.preventDefault(),t(this).trigger("upload.over")}).on("dragleave",function(e){t(this).trigger("upload.leave")}).on("drop",function(e){e.preventDefault(),t(this).trigger("upload.drop",e)}),i.bindAction.on("click",function(){t(this).trigger("upload.action")}),i.elem.data("haveEvents",!0))},o.render=function(e){var t=new p(e);return l.call(t)},e(r,o)});layui.define("layer",function(e){"use strict";var i=layui.$,t=layui.layer,a=layui.hint(),n=layui.device(),l="form",s=".layui-form",r="layui-this",u="layui-hide",c="layui-disabled",o=function(){this.config={verify:{required:[/[\S]+/,"必填项不能为空"],phone:[/^1\d{10}$/,"请输入正确的手机号"],email:[/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,"邮箱格式不正确"],url:[/(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/,"链接格式不正确"],number:function(e){if(!e||isNaN(e))return"只能填写数字"},date:[/^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/,"日期格式不正确"],identity:[/(^\d{15}$)|(^\d{17}(x|X|\d)$)/,"请输入正确的身份证号"]}}};o.prototype.set=function(e){var t=this;return i.extend(!0,t.config,e),t},o.prototype.verify=function(e){var t=this;return i.extend(!0,t.config.verify,e),t},o.prototype.on=function(e,i){return layui.onevent.call(this,l,e,i)},o.prototype.render=function(e,t){var n=this,o=i(s+function(){return t?'[lay-filter="'+t+'"]':""}()),d={select:function(){var e,t="请选择",a="layui-form-select",n="layui-select-title",s="layui-select-none",d="",f=o.find("select"),y=function(t,l){i(t.target).parent().hasClass(n)&&!l||(i("."+a).removeClass(a+"ed "+a+"up"),e&&d&&e.val(d)),e=null},h=function(t,o,f){var h=i(this),p=t.find("."+n),m=p.find("input"),k=t.find("dl"),g=k.children("dd");if(!o){var b=function(){var e=t.offset().top+t.outerHeight()+5-v.scrollTop(),i=k.outerHeight();t.addClass(a+"ed"),g.removeClass(u),e+i>v.height()&&e>=i&&t.addClass(a+"up")},x=function(e){t.removeClass(a+"ed "+a+"up"),m.blur(),e||C(m.val(),function(e){e&&(d=k.find("."+r).html(),m&&m.val(d))})};p.on("click",function(e){t.hasClass(a+"ed")?x():(y(e,!0),b()),k.find("."+s).remove()}),p.find(".layui-edge").on("click",function(){m.focus()}),m.on("keyup",function(e){var i=e.keyCode;9===i&&b()}).on("keydown",function(e){var i=e.keyCode;9===i?x():13===i&&e.preventDefault()});var C=function(e,t,a){var n=0;layui.each(g,function(){var t=i(this),l=t.text(),s=l.indexOf(e)===-1;(""===e||"blur"===a?e!==l:s)&&n++,"keyup"===a&&t[s?"addClass":"removeClass"](u)});var l=n===g.length;return t(l),l},w=function(e){var i=this.value,t=e.keyCode;return 9!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&(C(i,function(e){e?k.find("."+s)[0]||k.append('<p class="'+s+'">无匹配项</p>'):k.find("."+s).remove()},"keyup"),void(""===i&&k.find("."+s).remove()))};f&&m.on("keyup",w).on("blur",function(i){e=m,d=k.find("."+r).html(),setTimeout(function(){C(m.val(),function(e){e&&!d&&m.val("")},"blur")},200)}),g.on("click",function(){var e=i(this),a=e.attr("lay-value"),n=h.attr("lay-filter");return!e.hasClass(c)&&(e.hasClass("layui-select-tips")?m.val(""):(m.val(e.text()),e.addClass(r)),e.siblings().removeClass(r),h.val(a).removeClass("layui-form-danger"),layui.event.call(this,l,"select("+n+")",{elem:h[0],value:a,othis:t}),x(!0),!1)}),t.find("dl>dt").on("click",function(e){return!1}),i(document).off("click",y).on("click",y)}};f.each(function(e,l){var s=i(this),u=s.next("."+a),o=this.disabled,d=l.value,f=i(l.options[l.selectedIndex]),y=l.options[0];if("string"==typeof s.attr("lay-ignore"))return s.show();var v="string"==typeof s.attr("lay-search"),p=y?y.value?t:y.innerHTML||t:t,m=i(['<div class="'+(v?"":"layui-unselect ")+a+(o?" layui-select-disabled":"")+'">','<div class="'+n+'"><input type="text" placeholder="'+p+'" value="'+(d?f.html():"")+'" '+(v?"":"readonly")+' class="layui-input'+(v?"":" layui-unselect")+(o?" "+c:"")+'">','<i class="layui-edge"></i></div>','<dl class="layui-anim layui-anim-upbit'+(s.find("optgroup")[0]?" layui-select-group":"")+'">'+function(e){var i=[];return layui.each(e,function(e,a){0!==e||a.value?"optgroup"===a.tagName.toLowerCase()?i.push("<dt>"+a.label+"</dt>"):i.push('<dd lay-value="'+a.value+'" class="'+(d===a.value?r:"")+(a.disabled?" "+c:"")+'">'+a.innerHTML+"</dd>"):i.push('<dd lay-value="" class="layui-select-tips">'+(a.innerHTML||t)+"</dd>")}),0===i.length&&i.push('<dd lay-value="" class="'+c+'">没有选项</dd>'),i.join("")}(s.find("*"))+"</dl>","</div>"].join(""));u[0]&&u.remove(),s.after(m),h.call(this,m,o,v)})},checkbox:function(){var e={checkbox:["layui-form-checkbox","layui-form-checked","checkbox"],_switch:["layui-form-switch","layui-form-onswitch","switch"]},t=o.find("input[type=checkbox]"),a=function(e,t){var a=i(this);e.on("click",function(){var i=a.attr("lay-filter"),n=(a.attr("lay-text")||"").split("|");a[0].disabled||(a[0].checked?(a[0].checked=!1,e.removeClass(t[1]).find("em").text(n[1])):(a[0].checked=!0,e.addClass(t[1]).find("em").text(n[0])),layui.event.call(a[0],l,t[2]+"("+i+")",{elem:a[0],value:a[0].value,othis:e}))})};t.each(function(t,n){var l=i(this),s=l.attr("lay-skin"),r=(l.attr("lay-text")||"").split("|"),u=this.disabled;"switch"===s&&(s="_"+s);var o=e[s]||e.checkbox;if("string"==typeof l.attr("lay-ignore"))return l.show();var d=l.next("."+o[0]),f=i(['<div class="layui-unselect '+o[0]+(n.checked?" "+o[1]:"")+(u?" layui-checkbox-disbaled "+c:"")+'" lay-skin="'+(s||"")+'">',{_switch:"<em>"+((n.checked?r[0]:r[1])||"")+"</em><i></i>"}[s]||(n.title.replace(/\s/g,"")?"<span>"+n.title+"</span>":"")+'<i class="layui-icon">'+(s?"&#xe605;":"&#xe618;")+"</i>","</div>"].join(""));d[0]&&d.remove(),l.after(f),a.call(this,f,o)})},radio:function(){var e="layui-form-radio",t=["&#xe643;","&#xe63f;"],a=o.find("input[type=radio]"),n=function(a){var n=i(this),r="layui-anim-scaleSpring";a.on("click",function(){var u=n[0].name,c=n.parents(s),o=n.attr("lay-filter"),d=c.find("input[name="+u.replace(/(\.|#|\[|\])/g,"\\$1")+"]");n[0].disabled||(layui.each(d,function(){var a=i(this).next("."+e);this.checked=!1,a.removeClass(e+"ed"),a.find(".layui-icon").removeClass(r).html(t[1])}),n[0].checked=!0,a.addClass(e+"ed"),a.find(".layui-icon").addClass(r).html(t[0]),layui.event.call(n[0],l,"radio("+o+")",{elem:n[0],value:n[0].value,othis:a}))})};a.each(function(a,l){var s=i(this),r=s.next("."+e),u=this.disabled;if("string"==typeof s.attr("lay-ignore"))return s.show();var o=i(['<div class="layui-unselect '+e+(l.checked?" "+e+"ed":"")+(u?" layui-radio-disbaled "+c:"")+'">','<i class="layui-anim layui-icon">'+t[l.checked?0:1]+"</i>","<span>"+(l.title||"未命名")+"</span>","</div>"].join(""));r[0]&&r.remove(),s.after(o),n.call(this,o)})}};return e?d[e]?d[e]():a.error("不支持的"+e+"表单渲染"):layui.each(d,function(e,i){i()}),n};var d=function(){var e=i(this),a=f.config.verify,r=null,u="layui-form-danger",c={},o=e.parents(s),d=o.find("*[lay-verify]"),y=e.parents("form")[0],v=o.find("input,select,textarea"),h=e.attr("lay-filter");return layui.each(d,function(e,l){var s=i(this),c=s.attr("lay-verify").split("|"),o="",d=s.val();if(s.removeClass(u),layui.each(c,function(e,i){var c="function"==typeof a[i];if(a[i]&&(c?o=a[i](d,l):!a[i][0].test(d)))return t.msg(o||a[i][1],{icon:5,shift:6}),n.android||n.ios||l.focus(),s.addClass(u),r=!0}),r)return r}),!r&&(layui.each(v,function(e,i){i.name&&(/^checkbox|radio$/.test(i.type)&&!i.checked||(c[i.name]=i.value))}),layui.event.call(this,l,"submit("+h+")",{elem:this,form:y,field:c}))},f=new o,y=i(document),v=i(window);f.render(),y.on("reset",s,function(){var e=i(this).attr("lay-filter");setTimeout(function(){f.render(null,e)},50)}),y.on("submit",s,d).on("click","*[lay-submit]",d),e(l,f)});layui.define("jquery",function(e){"use strict";var o=layui.$,a=layui.hint(),i="layui-tree-enter",r=function(e){this.options=e},t={arrow:["&#xe623;","&#xe625;"],checkbox:["&#xe626;","&#xe627;"],radio:["&#xe62b;","&#xe62a;"],branch:["&#xe622;","&#xe624;"],leaf:"&#xe621;"};r.prototype.init=function(e){var o=this;e.addClass("layui-box layui-tree"),o.options.skin&&e.addClass("layui-tree-skin-"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class="'+(n.spread?"layui-show":"")+'"></ul>'),s=o(["<li "+(n.spread?'data-spread="'+n.spread+'"':"")+">",function(){return l?'<i class="layui-icon layui-tree-spread">'+(n.spread?t.arrow[1]:t.arrow[0])+"</i>":""}(),function(){return r.check?'<i class="layui-icon layui-tree-check">'+("checkbox"===r.check?t.checkbox[0]:"radio"===r.check?t.radio[0]:"")+"</i>":""}(),function(){return'<a href="'+(n.href||"javascript:;")+'" '+(r.target&&n.href?'target="'+r.target+'"':"")+">"+('<i class="layui-icon layui-tree-'+(l?"branch":"leaf")+'">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+"</i>")+("<cite>"+(n.name||"未命名")+"</cite></a>")}(),"</li>"].join(""));l&&(s.append(c),i.tree(c,n.children)),e.append(s),"function"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children("a").on("click",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(".layui-tree-spread")),r=e.children("ul"),n=e.children("a"),l=function(){e.data("spread")?(e.data("spread",null),r.removeClass("layui-show"),i.html(t.arrow[0]),n.find(".layui-icon").html(t.branch[0])):(e.data("spread",!0),r.addClass("layui-show"),i.html(t.arrow[1]),n.find(".layui-icon").html(t.branch[1]))};r[0]&&(i.on("click",l),n.on("dblclick",l))},r.prototype.on=function(e){var a=this,r=a.options,t="layui-tree-drag";e.find("i").on("selectstart",function(e){return!1}),r.drag&&o(document).on("mousemove",function(e){var i=a.move;if(i.from){var r=(i.to,o('<div class="layui-box '+t+'"></div>'));e.preventDefault(),o("."+t)[0]||o("body").append(r);var n=o("."+t)[0]?o("."+t):r;n.addClass("layui-show").html(i.from.elem.children("a").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on("mouseup",function(){var e=a.move;e.from&&(e.from.elem.children("a").removeClass(i),e.to&&e.to.elem.children("a").removeClass(i),a.move={},o("."+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children("a")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on("mousedown",function(){var o=r.move;o.from={item:a,elem:e}}),t.on("mouseenter",n).on("mousemove",n).on("mouseleave",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e("tree",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error("layui.tree 没有找到"+e.elem+"元素")})});layui.define(["laytpl","laypage","layer","form"],function(e){"use strict";var t=layui.$,i=layui.laytpl,a=layui.laypage,l=layui.layer,n=layui.form,o=layui.hint(),r=layui.device(),d={config:{checkName:"LAY_CHECKED",indexName:"LAY_TABLE_INDEX"},cache:{},index:layui.table?layui.table.index+1e4:0,set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,s,e,t)}},c=function(){var e=this,t=e.config,i=t.id;return i&&(c.config[i]=t),{reload:function(t){e.reload.call(e,t)},config:t}},s="table",u=".layui-table",f="layui-hide",h="layui-none",y="layui-table-view",p=".layui-table-header",m=".layui-table-body",v=".layui-table-main",g=".layui-table-fixed",x=".layui-table-fixed-l",b=".layui-table-fixed-r",k=".layui-table-tool",C=".layui-table-sort",w="layui-table-edit",N="layui-table-hover",z=function(e){return e=e||{},['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" ','{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',"<thead>","{{# layui.each(d.data.cols, function(i1, item1){ }}","<tr>","{{# layui.each(item1, function(i2, item2){ }}",'{{# if(item2.fixed && item2.fixed !== "right"){ left = true; } }}','{{# if(item2.fixed === "right"){ right = true; } }}',function(){return e.fixed&&"right"!==e.fixed?'{{# if(item2.fixed && item2.fixed !== "right"){ }}':"right"===e.fixed?'{{# if(item2.fixed === "right"){ }}':""}(),"{{# if(item2.checkbox){ }}",'<th data-field="{{ item2.field||i2 }}" data-type="checkbox" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} unresize="true"><div class="layui-table-cell laytable-cell-checkbox"><input type="checkbox" name="layTableCheckbox" lay-skin="primary" lay-filter="layTableAllChoose" {{# if(item2[d.data.checkName]){ }}checked{{# }; }}></div></th>',"{{# } else if(item2.space){ }}",'<th data-field="{{ item2.field||i2 }}" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} unresize="true"><div class="layui-table-cell laytable-cell-space"></div></th>',"{{# } else { }}",'<th data-field="{{ item2.field||i2 }}" {{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}} {{# if(item2.unresize){ }}unresize="true"{{# } }}>',"{{# if(item2.colspan > 1){ }}",'<div class="layui-table-cell laytable-cell-group" {{#if(item2.align){}}align="{{item2.align}}"{{#}}}>','<span>{{item2.title||""}}</span>',"</div>","{{# } else { }}",'<div class="layui-table-cell laytable-cell-{{d.index}}-{{item2.field||i2}}" {{#if(item2.align){}}align="{{item2.align}}"{{#}}}>','<span>{{item2.title||""}}</span>',"{{# if(item2.sort){ }}",'<span class="layui-table-sort layui-inline"><i class="layui-edge layui-table-sort-asc"></i><i class="layui-edge layui-table-sort-desc"></i></span>',"{{# } }}","</div>","{{# } }}","</th>","{{# }; }}",e.fixed?"{{# }; }}":"","{{# }); }}","</tr>","{{# }); }}","</thead>","</table>"].join("")},F=['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" ','{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',"<tbody></tbody>","</table>"].join(""),T=['<div class="layui-form layui-border-box {{d.VIEW_CLASS}}" lay-filter="LAY-table-{{d.index}}" style="{{# if(d.data.width){ }}width:{{d.data.width}}px;{{# } }} {{# if(d.data.height){ }}height:{{d.data.height}}px;{{# } }}">',"{{# var left, right; }}",'<div class="layui-table-header">',z(),"</div>",'<div class="layui-table-body layui-table-main">',F,"</div>","{{# if(left){ }}",'<div class="layui-table-fixed layui-table-fixed-l">','<div class="layui-table-header">',z({fixed:!0}),"</div>",'<div class="layui-table-body">',F,"</div>","</div>","{{# }; }}","{{# if(right){ }}",'<div class="layui-table-fixed layui-table-fixed-r">','<div class="layui-table-header">',z({fixed:"right"}),'<div class="layui-table-mend"></div>',"</div>",'<div class="layui-table-body">',F,"</div>","</div>","{{# }; }}","{{# if(d.data.page){ }}",'<div class="layui-table-tool">','<div class="layui-inline layui-table-page" id="layui-table-page{{d.index}}"></div>',"</div>","{{# } }}","<style>","{{# layui.each(d.data.cols, function(i1, item1){","layui.each(item1, function(i2, item2){ }}",".laytable-cell-{{d.index}}-{{item2.field||i2}}{ width:{{item2.width||50}}px }","{{# });","}); }}","</style>","</div>"].join(""),L=t(window),S=t(document),H=function(e){var i=this;i.index=++d.index,i.config=t.extend({},i.config,d.config,e),i.render()};H.prototype.config={limit:30,loading:!0},H.prototype.render=function(e){var a,l=this;if(e&&(l.config=e),a=l.config,a.elem=t(a.elem),a.where=a.where||{},a.request=t.extend({pageName:"page",limitName:"limit"},a.request),a.response=t.extend({statusName:"code",statusCode:0,msgName:"msg",dataName:"data",countName:"count"},a.response),!a.elem[0])return l;var n=a.elem,o=n.next("."+y);a.height&&/^full-\d+$/.test(a.height)&&(l.fullHeightGap=a.height.split("-")[1],a.height=L.height()-l.fullHeightGap);var r=l.elem=t(i(T).render({VIEW_CLASS:y,data:a,index:l.index}));if(a.index=l.index,o[0]&&o.remove(),n.after(r),l.layHeader=r.find(p),l.layMain=r.find(v),l.layBody=r.find(m),l.layFixed=r.find(g),l.layFixLeft=r.find(x),l.layFixRight=r.find(b),l.layTool=r.find(k),a.height&&l.fullSize(),a.cols.length>1){var d=l.layFixed.find(p).find("th");d.height(l.layHeader.height()-1-parseFloat(d.css("padding-top"))-parseFloat(d.css("padding-bottom")))}l.pullData(1),l.events()},H.prototype.reload=function(e){var i=this;i.config=t.extend({},i.config,e),i.render()},H.prototype.pullData=function(e,i){var a=this,n=a.config,o=n.request,r=n.response,d=function(){"object"==typeof n.initSort&&a.sort(n.initSort.field,n.initSort.type)};if(n.url){var c={};c[o.pageName]=e,c[o.limitName]=n.limit,t.ajax({type:n.method||"get",url:n.url,data:t.extend(c,n.where),dataType:"json",success:function(t){return t[r.statusName]!=r.statusCode?(a.renderForm(),a.layMain.html('<div class="'+h+'">'+(t[r.msgName]||"返回的数据状态异常")+"</div>")):(a.renderData(t,e,t[r.countName]),d(),i&&l.close(i),void("function"==typeof n.done&&n.done(t,e,t[r.countName])))},error:function(e,t){a.layMain.html('<div class="'+h+'">数据接口请求异常</div>'),a.renderForm(),i&&l.close(i)}})}else if(n.data&&n.data.constructor===Array){var s={},u=e*n.limit-n.limit;s[r.dataName]=n.data.concat().splice(u,n.limit),s[r.countName]=n.data.length,a.renderData(s,e,n.data.length),d(),"function"==typeof n.done&&n.done(s,e,s[r.countName])}},H.prototype.page=1,H.prototype.eachCols=function(e){var i=t.extend(!0,[],this.config.cols),a=[],l=0;layui.each(i,function(e,t){layui.each(t,function(t,n){if(n.colspan>1){var o=0;l++,n.CHILD_COLS=[],layui.each(i[e+1],function(e,t){t.PARENT_COL||o==n.colspan||(t.PARENT_COL=l,n.CHILD_COLS.push(t),o+=t.colspan>1?t.colspan:1)})}n.PARENT_COL||a.push(n)})});var n=function(t){layui.each(t||a,function(t,i){return i.CHILD_COLS?n(i.CHILD_COLS):void e(t,i)})};n()},H.prototype.renderData=function(e,n,o,r){var c=this,s=c.config,u=e[s.response.dataName]||[],f=[],y=[],p=[],m=function(){return!r&&c.sortKey?c.sort(c.sortKey.field,c.sortKey.sort,!0):(layui.each(u,function(e,a){var l=[],n=[],o=[];0!==a.length&&(r||(a[d.config.indexName]=e),c.eachCols(function(e,r){var c=a[r.field||e];if(void 0!==c&&null!==c||(c=""),!(r.colspan>1)){var u=['<td data-field="'+(r.field||e)+'"'+function(){var e=[];return r.edit&&e.push(' data-edit="true"'),r.align&&e.push(' align="'+r.align+'"'),r.templet&&e.push(' data-content="'+c+'"'),r.toolbar&&e.push(' data-off="true"'),r.event&&e.push(' lay-event="'+r.event+'"'),r.style&&e.push(' style="'+r.style+'"'),e.join("")}()+">",'<div class="layui-table-cell laytable-cell-'+function(){return r.checkbox?"checkbox":r.space?"space":s.index+"-"+(r.field||e)}()+'">'+function(){return r.checkbox?'<input type="checkbox" name="layTableCheckbox" lay-skin="primary" '+function(){var e=d.config.checkName;return r[e]?(a[e]=r[e],r[e]?"checked":""):a[e]?"checked":""}()+">":r.toolbar?i(t(r.toolbar).html()||"").render(a):r.templet?i(t(r.templet).html()||String(c)).render(a):c}(),"</div></td>"].join("");l.push(u),r.fixed&&"right"!==r.fixed&&n.push(u),"right"===r.fixed&&o.push(u)}}),f.push('<tr data-index="'+e+'">'+l.join("")+"</tr>"),y.push('<tr data-index="'+e+'">'+n.join("")+"</tr>"),p.push('<tr data-index="'+e+'">'+o.join("")+"</tr>"))}),c.layBody.scrollTop(0),c.layMain.find("."+h).remove(),c.layMain.find("tbody").html(f.join("")),c.layFixLeft.find("tbody").html(y.join("")),c.layFixRight.find("tbody").html(p.join("")),c.renderForm(),c.syncCheckAll(),c.haveInit?c.scrollPatch():setTimeout(function(){c.scrollPatch()},50),c.haveInit=!0,void l.close(c.tipsIndex))};return c.key=s.id||s.index,d.cache[c.key]=u,r?m():0===u.length?(c.renderForm(),c.layFixed.remove(),c.layMain.find("tbody").html(""),c.layMain.find("."+h).remove(),c.layMain.append('<div class="'+h+'">无数据</div>')):(m(),void(s.page&&(c.page=n,c.count=o,a.render({elem:"layui-table-page"+s.index,count:o,groups:3,limits:s.limits||[10,20,30,40,50,60,70,80,90],limit:s.limit,curr:n,layout:["prev","page","next","skip","count","limit"],prev:'<i class="layui-icon">&#xe603;</i>',next:'<i class="layui-icon">&#xe602;</i>',jump:function(e,t){t||(c.page=e.curr,s.limit=e.limit,c.pullData(e.curr,c.loading()))}}),c.layTool.find(".layui-table-count span").html(o))))},H.prototype.renderForm=function(e){n.render(e||"checkbox","LAY-table-"+this.index)},H.prototype.sort=function(e,i,a,n){var r,c,u=this,f={},h=u.config,y=h.elem.attr("lay-filter"),p=d.cache[u.key];"string"==typeof e&&u.layHeader.find("th").each(function(i,a){var l=t(this),n=l.data("field");if(n===e)return e=l,r=n,!1});try{var r=r||e.data("field");if(u.sortKey&&!a&&r===u.sortKey.field&&i===u.sortKey.sort)return;var m=u.layHeader.find("th .laytable-cell-"+h.index+"-"+r).find(C);u.layHeader.find("th").find(C).removeAttr("lay-sort"),m.attr("lay-sort",i||null),u.layFixed.find("th")}catch(v){return o.error("Table modules: Did not match to field")}u.sortKey={field:r,sort:i},"asc"===i?c=layui.sort(p,r):"desc"===i?c=layui.sort(p,r,!0):(c=layui.sort(p,d.config.indexName),delete u.sortKey),f[h.response.dataName]=c,u.renderData(f,u.page,u.count,!0),l.close(u.tipsIndex),n&&layui.event.call(e,s,"sort("+y+")",{field:r,type:i})},H.prototype.loading=function(){var e=this,t=e.config;if(t.loading&&t.url)return l.msg("数据请求中",{icon:16,offset:[e.elem.offset().top+e.elem.height()/2-35-L.scrollTop()+"px",e.elem.offset().left+e.elem.width()/2-90-L.scrollLeft()+"px"],anim:-1,fixed:!1})},H.prototype.setCheckData=function(e,t){var i=this,a=i.config,l=d.cache[i.key];l[e]&&(l[e][a.checkName]=t)},H.prototype.syncCheckAll=function(){var e=this,t=e.config,i=e.layHeader.find('input[name="layTableCheckbox"]'),a=function(i){return e.eachCols(function(e,a){a.checkbox&&(a[t.checkName]=i)}),i};i[0]&&(d.checkStatus(e.key).isAll?(i[0].checked||(i.prop("checked",!0),e.renderForm()),a(!0)):(i[0].checked&&(i.prop("checked",!1),e.renderForm()),a(!1)))},H.prototype.getCssRule=function(e,t){var i=this,a=i.elem.find("style")[0],l=a.sheet||a.styleSheet,n=l.cssRules||l.rules;layui.each(n,function(a,l){if(l.selectorText===".laytable-cell-"+i.index+"-"+e)return t(l),!0})},H.prototype.fullSize=function(){var e,t=this,i=t.config,a=i.height;t.fullHeightGap&&(a=L.height()-t.fullHeightGap,a<135&&(a=135),t.elem.css("height",a)),e=parseFloat(a)-parseFloat(t.layHeader.height())-1,i.page&&(e-=parseFloat(t.layTool.outerHeight()+1)),t.layMain.css("height",e)},H.prototype.scrollPatch=function(){var e=this,i=e.layMain.children("table"),a=e.layMain.width()-e.layMain.prop("clientWidth"),l=e.layMain.height()-e.layMain.prop("clientHeight");if(a&&l){if(!e.elem.find(".layui-table-patch")[0]){var n=t('<th class="layui-table-patch"><div class="layui-table-cell"></div></th>');n.find("div").css({width:a}),e.layHeader.eq(0).find("thead tr").append(n)}}else e.layHeader.eq(0).find(".layui-table-patch").remove();var o=e.layMain.height(),r=o-l;e.layFixed.find(m).css("height",i.height()>r?r:"auto"),e.layFixRight[i.width()>e.layMain.width()?"removeClass":"addClass"](f),e.layFixRight.css("right",a-1)},H.prototype.events=function(){var e,a=this,n=a.config,o=t("body"),c={},u=a.layHeader.find("th"),f=".layui-table-cell",h=n.elem.attr("lay-filter");u.on("mousemove",function(e){var i=t(this),a=i.offset().left,l=e.clientX-a;i.attr("colspan")>1||i.attr("unresize")||c.resizeStart||(c.allowResize=i.width()-l<=10,o.css("cursor",c.allowResize?"col-resize":""))}).on("mouseleave",function(){t(this);c.resizeStart||o.css("cursor","")}).on("mousedown",function(e){if(c.allowResize){var i=t(this).data("field");e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],a.getCssRule(i,function(e){c.rule=e,c.ruleWidth=parseFloat(e.style.width)})}}),S.on("mousemove",function(t){if(c.resizeStart){if(t.preventDefault(),c.rule){var i=c.ruleWidth+t.clientX-c.offset[0];c.rule.style.width=i+"px",l.close(a.tipsIndex)}e=1}}).on("mouseup",function(t){c.resizeStart&&(c={},o.css("cursor",""),a.scrollPatch()),2===e&&(e=null)}),u.on("click",function(){var i,l=t(this),n=l.find(C),o=n.attr("lay-sort");return n[0]&&1!==e?(i="asc"===o?"desc":"desc"===o?null:"asc",void a.sort(l,i,null,!0)):e=2}).find(C+" .layui-edge ").on("click",function(e){var i=t(this),l=i.index(),n=i.parents("th").eq(0).data("field");layui.stope(e),0===l?a.sort(n,"asc",null,!0):a.sort(n,"desc",null,!0)}),a.elem.on("click",'input[name="layTableCheckbox"]+',function(){var e=t(this).prev(),i=a.layBody.find('input[name="layTableCheckbox"]'),l=e.parents("tr").eq(0).data("index"),n=e[0].checked,o="layTableAllChoose"===e.attr("lay-filter");o?(i.each(function(e,t){t.checked=n,a.setCheckData(e,n)}),a.syncCheckAll(),a.renderForm()):(a.setCheckData(l,n),a.syncCheckAll()),layui.event.call(this,s,"checkbox("+h+")",{checked:n,data:d.cache[a.key][l],type:o?"all":"one"})}),a.layBody.on("mouseenter","tr",function(){var e=t(this),i=e.index();a.layBody.find("tr:eq("+i+")").addClass(N)}).on("mouseleave","tr",function(){var e=t(this),i=e.index();a.layBody.find("tr:eq("+i+")").removeClass(N)}),a.layBody.on("change","."+w,function(){var e=t(this),i=this.value,l=e.parent().data("field"),n=e.parents("tr").eq(0).data("index"),o=d.cache[a.key][n];o[l]=i,layui.event.call(this,s,"edit("+h+")",{value:i,data:o,field:l})}).on("blur","."+w,function(){var e,l=t(this),n=l.parent().data("field"),o=l.parents("tr").eq(0).data("index"),r=d.cache[a.key][o];a.eachCols(function(t,i){i.field==n&&i.templet&&(e=i.templet)}),l.siblings(f).html(e?i(t(e).html()||this.value).render(r):this.value),l.parent().data("content",this.value),l.remove()}),a.layBody.on("click","td",function(){var e=t(this),i=(e.data("field"),e.children(f));if(!e.data("off")){if(e.data("edit")){var o=t('<input class="'+w+'">');return o[0].value=e.data("content")||i.text(),e.find("."+w)[0]||e.append(o),o.focus()}Math.round(i.prop("scrollWidth"))>Math.round(i.outerWidth())&&(a.tipsIndex=l.tips(['<div class="layui-table-tips-main" style="margin-top: -'+(i.height()+16)+"px;"+function(){return"sm"===n.size?"padding: 4px 15px; font-size: 12px;":"lg"===n.size?"padding: 14px 15px;":""}()+'">',i.html(),"</div>",'<i class="layui-icon layui-table-tips-c">&#x1006;</i>'].join(""),i[0],{tips:[3,""],time:-1,anim:-1,maxWidth:r.ios||r.android?300:600,isOutAnim:!1,skin:"layui-table-tips",success:function(e,t){e.find(".layui-table-tips-c").on("click",function(){l.close(t)})}}))}}),a.layBody.on("click","*[lay-event]",function(){var e=t(this),l=e.parents("tr").eq(0).data("index"),n=a.layBody.find('tr[data-index="'+l+'"]'),o="layui-table-click",r=d.cache[a.key][l];layui.event.call(this,s,"tool("+h+")",{data:d.clearCacheKey(r),event:e.attr("lay-event"),tr:n,del:function(){d.cache[a.key][l]=[],n.remove(),a.scrollPatch()},update:function(e){e=e||{},layui.each(e,function(e,l){if(e in r){var o,d=n.children('td[data-field="'+e+'"]');r[e]=l,a.eachCols(function(t,i){i.field==e&&i.templet&&(o=i.templet)}),d.children(f).html(o?i(t(o).html()||l).render(r):l),d.data("content",l)}})}}),n.addClass(o).siblings("tr").removeClass(o)}),a.layMain.on("scroll",function(){var e=t(this),i=e.scrollLeft(),n=e.scrollTop();a.layHeader.scrollLeft(i),a.layFixed.find(m).scrollTop(n),l.close(a.tipsIndex)}),L.on("resize",function(){a.fullSize(),a.scrollPatch()})},d.init=function(e,i){i=i||{};var a=this,l=t(e?'table[lay-filter="'+e+'"]':u+"[lay-data]"),n="Table element property lay-data configuration item has a syntax error: ";return l.each(function(){var a=t(this),l=a.attr("lay-data");try{l=new Function("return "+l)()}catch(r){o.error(n+l)}var c=[],s=t.extend({elem:this,cols:[],data:[],skin:a.attr("lay-skin"),size:a.attr("lay-size"),even:"string"==typeof a.attr("lay-even")},d.config,i,l);e&&a.hide(),a.find("thead>tr").each(function(e){s.cols[e]=[],t(this).children().each(function(i){var a=t(this),l=a.attr("lay-data");try{l=new Function("return "+l)()}catch(r){return o.error(n+l)}var d=t.extend({title:a.text(),colspan:a.attr("colspan")||0,rowspan:a.attr("rowspan")||0},l);d.colspan<2&&c.push(d),s.cols[e].push(d)})}),a.find("tbody>tr").each(function(e){var i=t(this),a={};i.children("td").each(function(e,i){var l=t(this),n=l.data("field");if(n)return a[n]=l.html()}),layui.each(c,function(e,t){var l=i.children("td").eq(e);a[t.field]=l.html()}),s.data[e]=a}),d.render(s)}),a},d.checkStatus=function(e){var t=0,i=[],a=d.cache[e];return a?(layui.each(a,function(e,a){a[d.config.checkName]&&(t++,i.push(d.clearCacheKey(a)))}),{data:i,isAll:t===a.length}):{}},c.config={},d.reload=function(e,i){var a=c.config[e];return a?d.render(t.extend({},a,i)):o.error("The ID option was not found in the table instance")},d.render=function(e){var t=new H(e);return c.call(t)},d.clearCacheKey=function(e){return e=t.extend({},e),delete e[d.config.checkName],delete e[d.config.indexName],e},d.init(),e(s,d)});layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.indicator(),e.elemItem.length<=1||(e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class="layui-icon '+u+'" lay-type="sub">'+("updown"===n.anim?"&#xe619;":"&#xe603;")+"</button>",'<button class="layui-icon '+u+'" lay-type="add">'+("updown"===n.anim?"&#xe61a;":"&#xe602;")+"</button>"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class="'+c+'"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("<li"+(n.index===e?' class="layui-this"':"")+"></li>")}),i.join("")}(),"</ul></div>"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a<n.index&&e.slide("sub",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr("lay-filter");n.haveSlide||("sub"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+" "+d+" "+s+" "+o+" "+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find("li").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,"change("+m+")",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data("haveEvents")||(i.elem.on("mouseenter",function(){clearInterval(e.timer)}).on("mouseleave",function(){e.autoplay()}),i.elem.data("haveEvents",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)});layui.define("jquery",function(e){"use strict";var t=layui.$,o={fixbar:function(e){var o,i,a="layui-fixbar",l="layui-fixbar-top",n=t(document),r=t("body");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?"&#xe606;":e.bar1,e.bar2=e.bar2===!0?"&#xe607;":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,"&#xe604;"],u=t(['<ul class="'+a+'">',e.bar1?'<li class="layui-icon" lay-type="bar1" style="'+e.bgcolor+'">'+c[0]+"</li>":"",e.bar2?'<li class="layui-icon" lay-type="bar2" style="'+e.bgcolor+'">'+c[1]+"</li>":"",'<li class="layui-icon '+l+'" lay-type="top" style="'+e.bgcolor+'">'+c[2]+"</li>","</ul>"].join("")),s=u.find("."+l),b=function(){var t=n.scrollTop();t>=e.showHeight?o||(s.show(),o=1):o&&(s.hide(),o=0)};t("."+a)[0]||("object"==typeof e.css&&u.css(e.css),r.append(u),b(),u.find("li").on("click",function(){var o=t(this),i=o.attr("lay-type");"top"===i&&t("html,body").animate({scrollTop:0},200),e.click&&e.click.call(this,i)}),n.on("scroll",function(){clearTimeout(i),i=setTimeout(function(){b()},100)}))},countdown:function(e,t,o){var i=this,a="function"==typeof t,l=new Date(e).getTime(),n=new Date(!t||a?(new Date).getTime():t).getTime(),r=l-n,c=[Math.floor(r/864e5),Math.floor(r/36e5)%24,Math.floor(r/6e4)%60,Math.floor(r/1e3)%60];a&&(o=t);var u=setTimeout(function(){i.countdown(e,n+1e3,o)},1e3);return o&&o(r>0?c:[0,0,0,0],t,u),r<=0&&clearTimeout(u),u},timeAgo:function(e,t){var o=[[],[]],i=(new Date).getTime()-new Date(e).getTime();return i>6912e5?(i=new Date(e),o[0][0]=i.getFullYear(),o[0][1]=i.getMonth()+1,o[0][2]=i.getDate(),t||(o[1][0]=i.getHours(),o[1][1]=i.getMinutes(),o[1][2]=i.getSeconds()),o[0].join("-")+" "+o[1].join(":")):i>=864e5?(i/1e3/60/60/24|0)+"天前":i>=36e5?(i/1e3/60/60|0)+"小时前":i>=12e4?(i/1e3/60|0)+"分钟前":i<0?"未来":"刚刚"}};e("util",o)});layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon ">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="<cite>加载更多</cite>",h=l('<div class="layui-flow-more"><a href="javascript:;">'+d+"</a></div>");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)});layui.define(["layer","form"],function(t){"use strict";var e=layui.$,i=layui.layer,a=layui.form,l=(layui.hint(),layui.device()),n="layedit",o="layui-show",r="layui-disabled",c=function(){var t=this;t.index=0,t.config={tool:["strong","italic","underline","del","|","left","center","right","|","link","unlink","face","image"],hideTool:[],height:280}};c.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},c.prototype.on=function(t,e){return layui.onevent(n,t,e)},c.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r="layui-layedit",c=e("#"+t),u="LAY_layedit_"+ ++a.index,d=c.next("."+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join("")}(),m=e(['<div class="'+r+'">','<div class="layui-unselect layui-layedit-tool">'+f+"</div>",'<div class="layui-layedit-iframe">','<iframe id="'+u+'" name="'+u+'" textarea="'+t+'" frameborder="0"></iframe>',"</div>","</div>"].join(""));return l.ie&&l.ie<8?c.removeClass("layui-hide").addClass(o):(d[0]&&d.remove(),s.call(a,m,c[0],y),c.addClass("layui-hide").after(m),a.index)},c.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},c.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},c.prototype.setContent=function(t,i,a){var l=u(t);l[0]&&(a?e(l[0].document.body).append(i):e(l[0].document.body).html(i),layedit.sync(t))},c.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e("#"+i[1].attr("textarea"));a.val(d(i[0].document.body.innerHTML))}},c.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var s=function(t,i,a){var l=this,n=t.find("iframe");n.css({height:a.height}).on("load",function(){var o=n.contents(),r=n.prop("contentWindow"),c=o.find("head"),s=e(["<style>","*{margin: 0; padding: 0;}","body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}","a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}","p{margin-bottom: 10px;}","img{display: inline-block; border: none; vertical-align: middle;}","pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}","</style>"].join("")),u=o.find("body");c.append(s),u.attr("contenteditable","true").css({"min-height":a.height}).html(i.value||""),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e("#LAY_layedit_"+t),a=i.prop("contentWindow");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,c=e(r.body);c.on("keydown",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if("pre"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg("请暂时用shift+enter"),!1}r.execCommand("formatBlock",!1,"<p>")}}),e(n).parents("form").on("submit",function(){var t=c.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),c.on("paste",function(e){r.execCommand("formatBlock",!1,"<p>"),setTimeout(function(){f.call(t,c),n.value=c.html()},100)})},f=function(t){var i=this;i.document;t.find("*[style]").each(function(){var t=this.style.textAlign;this.removeAttribute("style"),e(this).css({"text-align":t||""})}),t.find("table").addClass("layui-table"),t.find("script,link").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute("text"),l.selection){var r=a.text||i.text;if("a"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop("outerHTML")),a.select()}else{var r=a.toString()||i.text;if("a"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l="layedit-tool-active",n=p(m(a)),o=function(e){return t.find(".layedit-tool-"+e)};i&&i[i.hasClass(l)?"removeClass":"addClass"](l),t.find(">i").removeClass(l),o("unlink").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;"b"!==t&&"strong"!==t||o("b").addClass(l),"i"!==t&&"em"!==t||o("i").addClass(l),"u"===t&&o("u").addClass(l),"strike"===t&&o("d").addClass(l),"p"===t&&("center"===e?o("center").addClass(l):"right"===e?o("right").addClass(l):o("left").addClass(l)),"a"===t&&(o("link").addClass(l),o("unlink").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),c={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr("href"),target:l.attr("target")},function(e){var a=l[0];"A"===a.tagName?a.href=e.url:v.call(t,"a",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand("unlink")},face:function(e){x.call(this,function(i){v.call(t,"img",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use("upload",function(o){var r=l.uploadImage||{};o.render({url:r.url,method:r.type,elem:e(n).find("input")[0],done:function(e){0==e.code?(e.data=e.data||{},v.call(t,"img",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||"上传失败")}})})},code:function(e){k.call(o,function(i){v.call(t,"pre",{text:i.code,"lay-lang":i.lang},e)})},help:function(){i.open({type:2,title:"帮助",area:["600px","380px"],shadeClose:!0,shade:.1,skin:"layui-layer-msg",content:["http://www.layui.com/about/layedit/help.html","no"]})}},s=a.find(".layui-layedit-tool"),u=function(){var i=e(this),a=i.attr("layedit-event"),l=i.attr("lay-command");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand("formatBlock",!1,"<p>"),setTimeout(function(){o.focus()},10)):c[a]&&c[a].call(this,u),h.call(t,s,i)}},d=/image/;s.find(">i").on("mousedown",function(){var t=e(this),i=t.attr("layedit-event");d.test(i)||u.call(this)}).on("click",function(){var t=e(this),i=t.attr("layedit-event");d.test(i)&&u.call(this)}),o.on("click",function(){h.call(t,s),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:"LAY_layedit_link",area:"350px",shade:.05,shadeClose:!0,moveType:1,title:"超链接",skin:"layui-layer-msg",content:['<ul class="layui-form" style="margin: 15px;">','<li class="layui-form-item">','<label class="layui-form-label" style="width: 60px;">URL</label>','<div class="layui-input-block" style="margin-left: 90px">','<input name="url" lay-verify="url" value="'+(t.href||"")+'" autofocus="true" autocomplete="off" class="layui-input">',"</div>","</li>",'<li class="layui-form-item">','<label class="layui-form-label" style="width: 60px;">打开方式</label>','<div class="layui-input-block" style="margin-left: 90px">','<input type="radio" name="target" value="_self" class="layui-input" title="当前窗口"'+("_self"!==t.target&&t.target?"":"checked")+">",'<input type="radio" name="target" value="_blank" class="layui-input" title="新窗口" '+("_blank"===t.target?"checked":"")+">","</div>","</li>",'<li class="layui-form-item" style="text-align: center;">','<button type="button" lay-submit lay-filter="layedit-link-yes" class="layui-btn"> 确定 </button>','<button style="margin-left: 20px;" type="button" class="layui-btn layui-btn-primary"> 取消 </button>',"</li>","</ul>"].join(""),success:function(t,n){var o="submit(layedit-link-yes)";a.render("radio"),t.find(".layui-btn-primary").on("click",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=["[微笑]","[嘻嘻]","[哈哈]","[可爱]","[可怜]","[挖鼻]","[吃惊]","[害羞]","[挤眼]","[闭嘴]","[鄙视]","[爱你]","[泪]","[偷笑]","[亲亲]","[生病]","[太开心]","[白眼]","[右哼哼]","[左哼哼]","[嘘]","[衰]","[委屈]","[吐]","[哈欠]","[抱抱]","[怒]","[疑问]","[馋嘴]","[拜拜]","[思考]","[汗]","[困]","[睡]","[钱]","[失望]","[酷]","[色]","[哼]","[鼓掌]","[晕]","[悲伤]","[抓狂]","[黑线]","[阴险]","[怒骂]","[互粉]","[心]","[伤心]","[猪头]","[熊猫]","[兔子]","[ok]","[耶]","[good]","[NO]","[赞]","[来]","[弱]","[草泥马]","[神马]","[囧]","[浮云]","[给力]","[围观]","[威武]","[奥特曼]","[礼物]","[钟]","[话筒]","[蜡烛]","[蛋糕]"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+"images/face/"+t+".gif"}),e}();return x.hide=x.hide||function(t){"face"!==e(t.target).attr("layedit-event")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title="'+e+'"><img src="'+i+'" alt="'+e+'"></li>')}),'<ul class="layui-clear">'+t.join("")+"</ul>"}(),this,{tips:1,time:0,skin:"layui-box layui-util-face",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(".layui-clear>li").on("click",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off("click",x.hide).on("click",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:"LAY_layedit_code",area:"550px",shade:.05,shadeClose:!0,moveType:1,title:"插入代码",skin:"layui-layer-msg",content:['<ul class="layui-form layui-form-pane" style="margin: 15px;">','<li class="layui-form-item">','<label class="layui-form-label">请选择语言</label>','<div class="layui-input-block">','<select name="lang">','<option value="JavaScript">JavaScript</option>','<option value="HTML">HTML</option>','<option value="CSS">CSS</option>','<option value="Java">Java</option>','<option value="PHP">PHP</option>','<option value="C#">C#</option>','<option value="Python">Python</option>','<option value="Ruby">Ruby</option>','<option value="Go">Go</option>',"</select>","</div>","</li>",'<li class="layui-form-item layui-form-text">','<label class="layui-form-label">代码</label>','<div class="layui-input-block">','<textarea name="code" lay-verify="required" autofocus="true" class="layui-textarea" style="height: 200px;"></textarea>',"</div>","</li>",'<li class="layui-form-item" style="text-align: center;">','<button type="button" lay-submit lay-filter="layedit-code-yes" class="layui-btn"> 确定 </button>','<button style="margin-left: 20px;" type="button" class="layui-btn layui-btn-primary"> 取消 </button>',"</li>","</ul>"].join(""),success:function(l,n){var o="submit(layedit-code-yes)";a.render("select"),l.find(".layui-btn-primary").on("click",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class="layui-icon layedit-tool-html" title="HTML源代码" lay-command="html" layedit-event="html"">&#xe64b;</i><span class="layedit-tool-mid"></span>',strong:'<i class="layui-icon layedit-tool-b" title="加粗" lay-command="Bold" layedit-event="b"">&#xe62b;</i>',italic:'<i class="layui-icon layedit-tool-i" title="斜体" lay-command="italic" layedit-event="i"">&#xe644;</i>',underline:'<i class="layui-icon layedit-tool-u" title="下划线" lay-command="underline" layedit-event="u"">&#xe646;</i>',del:'<i class="layui-icon layedit-tool-d" title="删除线" lay-command="strikeThrough" layedit-event="d"">&#xe64f;</i>',"|":'<span class="layedit-tool-mid"></span>',left:'<i class="layui-icon layedit-tool-left" title="左对齐" lay-command="justifyLeft" layedit-event="left"">&#xe649;</i>',center:'<i class="layui-icon layedit-tool-center" title="居中对齐" lay-command="justifyCenter" layedit-event="center"">&#xe647;</i>',right:'<i class="layui-icon layedit-tool-right" title="右对齐" lay-command="justifyRight" layedit-event="right"">&#xe648;</i>',link:'<i class="layui-icon layedit-tool-link" title="插入链接" layedit-event="link"">&#xe64c;</i>',unlink:'<i class="layui-icon layedit-tool-unlink layui-disabled" title="清除链接" lay-command="unlink" layedit-event="unlink"">&#xe64d;</i>',face:'<i class="layui-icon layedit-tool-face" title="表情" layedit-event="face"">&#xe650;</i>',image:'<i class="layui-icon layedit-tool-image" title="图片" layedit-event="image">&#xe64a;<input type="file" name="file"></i>',code:'<i class="layui-icon layedit-tool-code" title="插入代码" layedit-event="code">&#xe64e;</i>',help:'<i class="layui-icon layedit-tool-help" title="帮助" layedit-event="help">&#xe607;</i>'},w=new c;t(n,w)});layui.define("jquery",function(e){"use strict";var a=layui.$,l="http://www.layui.com/doc/modules/code.html";e("code",function(e){var t=[];e=e||{},e.elem=a(e.elem||".layui-code"),e.about=!("about"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr("lay-encode")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#39;").replace(/"/g,"&quot;")),c.html('<ol class="layui-code-ol"><li>'+o.replace(/[\r\t\n]+/g,"</li><li>")+"</li></ol>"),c.find(">.layui-code-h3")[0]||c.prepend('<h3 class="layui-code-h3">'+(c.attr("lay-title")||e.title||"code")+(e.about?'<a href="'+l+'" target="_blank">layui.code</a>':"")+"</h3>");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); \ No newline at end of file diff --git a/static/plugins/layui/layui.js b/static/plugins/layui/layui.js new file mode 100755 index 0000000..f67f1d3 --- /dev/null +++ b/static/plugins/layui/layui.js @@ -0,0 +1,2 @@ +/** layui-v2.1.7 MIT License By http://www.layui.com */ + ;!function(e){"use strict";var t=document,o={modules:{},status:{},timeout:10,event:{}},n=function(){this.v="2.1.7"},r=function(){var e=t.scripts,o=e[e.length-1].src;return o.substring(0,o.lastIndexOf("/")+1)}(),a=function(t){e.console&&console.error&&console.error("Layui hint: "+t)},i="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),u={layer:"modules/layer",laydate:"modules/laydate",laypage:"modules/laypage",laytpl:"modules/laytpl",layim:"modules/layim",layedit:"modules/layedit",form:"modules/form",upload:"modules/upload",tree:"modules/tree",table:"modules/table",element:"modules/element",util:"modules/util",flow:"modules/flow",carousel:"modules/carousel",code:"modules/code",jquery:"modules/jquery",mobile:"modules/mobile","layui.all":"../layui.all"};n.prototype.cache=o,n.prototype.define=function(e,t){var n=this,r="function"==typeof e,a=function(){return"function"==typeof t&&t(function(e,t){layui[e]=t,o.status[e]=!0}),this};return r&&(t=e,e=[]),layui["layui.all"]||!layui["layui.all"]&&layui["layui.mobile"]?a.call(n):(n.use(e,a),n)},n.prototype.use=function(e,n,l){function s(e,t){var n="PLaySTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/;("load"===e.type||n.test((e.currentTarget||e.srcElement).readyState))&&(o.modules[f]=t,d.removeChild(v),function r(){return++m>1e3*o.timeout/4?a(f+" is not a valid module"):void(o.status[f]?c():setTimeout(r,4))}())}function c(){l.push(layui[f]),e.length>1?y.use(e.slice(1),n,l):"function"==typeof n&&n.apply(layui,l)}var y=this,p=o.dir=o.dir?o.dir:r,d=t.getElementsByTagName("head")[0];e="string"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(y.each(e,function(t,o){"jquery"===o&&e.splice(t,1)}),layui.jquery=layui.$=jQuery);var f=e[0],m=0;if(l=l||[],o.host=o.host||(p.match(/\/\/([\s\S]+?)\//)||["//"+location.host+"/"])[0],0===e.length||layui["layui.all"]&&u[f]||!layui["layui.all"]&&layui["layui.mobile"]&&u[f])return c(),y;if(o.modules[f])!function g(){return++m>1e3*o.timeout/4?a(f+" is not a valid module"):void("string"==typeof o.modules[f]&&o.status[f]?c():setTimeout(g,4))}();else{var v=t.createElement("script"),h=(u[f]?p+"lay/":o.base||"")+(y.modules[f]||f)+".js";v.async=!0,v.charset="utf-8",v.src=h+function(){var e=o.version===!0?o.v||(new Date).getTime():o.version||"";return e?"?v="+e:""}(),d.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf("[native code")<0||i?v.addEventListener("load",function(e){s(e,h)},!1):v.attachEvent("onreadystatechange",function(e){s(e,h)}),o.modules[f]=h}return y},n.prototype.getStyle=function(t,o){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](o)},n.prototype.link=function(e,n,r){var i=this,u=t.createElement("link"),l=t.getElementsByTagName("head")[0];"string"==typeof n&&(r=n);var s=(r||e).replace(/\.|\//g,""),c=u.id="layuicss-"+s,y=0;return u.rel="stylesheet",u.href=e+(o.debug?"?v="+(new Date).getTime():""),u.media="all",t.getElementById(c)||l.appendChild(u),"function"!=typeof n?i:(function p(){return++y>1e3*o.timeout/100?a(e+" timeout"):void(1989===parseInt(i.getStyle(t.getElementById(c),"width"))?function(){n()}():setTimeout(p,100))}(),i)},n.prototype.addcss=function(e,t,n){return layui.link(o.dir+"css/"+e,t,n)},n.prototype.img=function(e,t,o){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,o(e)}))},n.prototype.config=function(e){e=e||{};for(var t in e)o[t]=e[t];return this},n.prototype.modules=function(){var e={};for(var t in u)e[t]=u[t];return e}(),n.prototype.extend=function(e){var t=this;e=e||{};for(var o in e)t[o]||t.modules[o]?a("模块名 "+o+" 已被占用"):t.modules[o]=e[o];return t},n.prototype.router=function(e){var t=this,e=e||location.hash,o={path:[],search:{},hash:(e.match(/[^#](#.*$)/)||[])[1]||""};return/^#\//.test(e)?(e=e.replace(/^#\//,"").replace(/([^#])(#.*$)/,"$1").split("/")||[],t.each(e,function(e,t){/^\w+=/.test(t)?function(){t=t.split("="),o.search[t[0]]=t[1]}():o.path.push(t)}),o):o},n.prototype.data=function(t,o){if(t=t||"layui",e.JSON&&e.JSON.parse){if(null===o)return delete localStorage[t];o="object"==typeof o?o:{key:o};try{var n=JSON.parse(localStorage[t])}catch(r){var n={}}return o.value&&(n[o.key]=o.value),o.remove&&delete n[o.key],localStorage[t]=JSON.stringify(n),o.key?n[o.key]:n}},n.prototype.device=function(t){var o=navigator.userAgent.toLowerCase(),n=function(e){var t=new RegExp(e+"/([^\\s\\_\\-]+)");return e=(o.match(t)||[])[1],e||!1},r={os:function(){return/windows/.test(o)?"windows":/linux/.test(o)?"linux":/iphone|ipod|ipad|ios/.test(o)?"ios":/mac/.test(o)?"mac":void 0}(),ie:function(){return!!(e.ActiveXObject||"ActiveXObject"in e)&&((o.match(/msie\s(\d+)/)||[])[1]||"11")}(),weixin:n("micromessenger")};return t&&!r[t]&&(r[t]=n(t)),r.android=/android/.test(o),r.ios="ios"===r.os,r},n.prototype.hint=function(){return{error:a}},n.prototype.each=function(e,t){var o,n=this;if("function"!=typeof t)return n;if(e=e||[],e.constructor===Object){for(o in e)if(t.call(e[o],o,e[o]))break}else for(o=0;o<e.length&&!t.call(e[o],o,e[o]);o++);return n},n.prototype.sort=function(e,t,o){var n=JSON.parse(JSON.stringify(e));return t?(n.sort(function(e,o){var n=/^-?\d+$/,r=e[t],a=o[t];return n.test(r)&&(r=parseFloat(r)),n.test(a)&&(a=parseFloat(a)),r&&!a?1:!r&&a?-1:r>a?1:r<a?-1:0}),o&&n.reverse(),n):n},n.prototype.stope=function(t){t=t||e.event,t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},n.prototype.onevent=function(e,t,n){return"string"!=typeof e||"function"!=typeof n?this:(o.event[e+"."+t]=[n],this)},n.prototype.event=function(e,t,n){var r=this,a=null,i=t.match(/\(.*\)$/)||[],u=(t=e+"."+t).replace(i,""),l=function(e,t){var o=t&&t.call(r,n);o===!1&&null===a&&(a=!1)};return layui.each(o.event[u],l),i[0]&&layui.each(o.event[t],l),a},e.layui=new n}(window); \ No newline at end of file diff --git a/static/plugins/lazyload/jquery.lazyload.min.js b/static/plugins/lazyload/jquery.lazyload.min.js new file mode 100755 index 0000000..615b90e --- /dev/null +++ b/static/plugins/lazyload/jquery.lazyload.min.js @@ -0,0 +1,2 @@ +/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ +!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); \ No newline at end of file diff --git a/static/plugins/lazyload/skin/laypage.css b/static/plugins/lazyload/skin/laypage.css new file mode 100755 index 0000000..d3946dc --- /dev/null +++ b/static/plugins/lazyload/skin/laypage.css @@ -0,0 +1,3 @@ +/*! + laypage默认样式 +*/.laypage_main a,.laypage_main input,.laypage_main span{height:26px;line-height:26px}.laypage_main button,.laypage_main input,.laypageskin_default a{border:1px solid #ccc;background-color:#fff}.laypage_main{font-size:0;clear:both;color:#666}.laypage_main *{display:inline-block;vertical-align:top;font-size:12px}.laypage_main a{text-decoration:none;color:#666}.laypage_main a,.laypage_main span{margin:0 3px 6px;padding:0 10px}.laypage_main input{width:40px;margin:0 5px;padding:0 5px}.laypage_main button{height:28px;line-height:28px;margin-left:5px;padding:0 10px;color:#666}.laypageskin_default span{height:28px;line-height:28px;color:#999}.laypageskin_default .laypage_curr{font-weight:700;color:#666}.laypageskin_molv a,.laypageskin_molv span{padding:0 12px;border-radius:2px}.laypageskin_molv a{background-color:#f1eff0}.laypageskin_molv .laypage_curr{background-color:#00AA91;color:#fff}.laypageskin_molv input{height:24px;line-height:24px}.laypageskin_molv button{height:26px;line-height:26px}.laypageskin_yahei{color:#333}.laypageskin_yahei a,.laypageskin_yahei span{padding:0 13px;border-radius:2px;color:#333}.laypageskin_yahei .laypage_curr{background-color:#333;color:#fff}.laypageskin_flow{text-align:center}.laypageskin_flow .page_nomore{color:#999} \ No newline at end of file diff --git a/static/plugins/raty/img/cancel-off.png b/static/plugins/raty/img/cancel-off.png new file mode 100755 index 0000000..a3031f0 Binary files /dev/null and b/static/plugins/raty/img/cancel-off.png differ diff --git a/static/plugins/raty/img/cancel-on.png b/static/plugins/raty/img/cancel-on.png new file mode 100755 index 0000000..08f2493 Binary files /dev/null and b/static/plugins/raty/img/cancel-on.png differ diff --git a/static/plugins/raty/img/star-half-big.png b/static/plugins/raty/img/star-half-big.png new file mode 100755 index 0000000..191bc88 Binary files /dev/null and b/static/plugins/raty/img/star-half-big.png differ diff --git a/static/plugins/raty/img/star-half.png b/static/plugins/raty/img/star-half.png new file mode 100755 index 0000000..3c19e90 Binary files /dev/null and b/static/plugins/raty/img/star-half.png differ diff --git a/static/plugins/raty/img/star-off-big.png b/static/plugins/raty/img/star-off-big.png new file mode 100755 index 0000000..7f8b1e1 Binary files /dev/null and b/static/plugins/raty/img/star-off-big.png differ diff --git a/static/plugins/raty/img/star-off.png b/static/plugins/raty/img/star-off.png new file mode 100755 index 0000000..956fa7c Binary files /dev/null and b/static/plugins/raty/img/star-off.png differ diff --git a/static/plugins/raty/img/star-on-big.png b/static/plugins/raty/img/star-on-big.png new file mode 100755 index 0000000..9f7d095 Binary files /dev/null and b/static/plugins/raty/img/star-on-big.png differ diff --git a/static/plugins/raty/img/star-on.png b/static/plugins/raty/img/star-on.png new file mode 100755 index 0000000..975fe7f Binary files /dev/null and b/static/plugins/raty/img/star-on.png differ diff --git a/static/plugins/raty/jquery.raty.js b/static/plugins/raty/jquery.raty.js new file mode 100755 index 0000000..bd6f2e5 --- /dev/null +++ b/static/plugins/raty/jquery.raty.js @@ -0,0 +1,473 @@ +/*! + * jQuery Raty - A Star Rating Plugin + * ------------------------------------------------------------------ + * + * jQuery Raty is a plugin that generates a customizable star rating. + * + * Licensed under The MIT License + * + * @version 2.5.2 + * @since 2010.06.11 + * @author Washington Botelho + * @documentation wbotelhos.com/raty + * + * ------------------------------------------------------------------ + * + * <div id="star"></div> + * + * $('#star').raty(); + * + */ + +;(function($) { + + var methods = { + init: function(settings) { + return this.each(function() { + methods.destroy.call(this); + + this.opt = $.extend(true, {}, $.fn.raty.defaults, settings); + + var that = $(this), + inits = ['number', 'readOnly', 'score', 'scoreName']; + + methods._callback.call(this, inits); + + if (this.opt.precision) { + methods._adjustPrecision.call(this); + } + + this.opt.number = methods._between(this.opt.number, 0, this.opt.numberMax) + + this.opt.path = this.opt.path || ''; + + if (this.opt.path && this.opt.path.slice(this.opt.path.length - 1, this.opt.path.length) !== '/') { + this.opt.path += '/'; + } + + this.stars = methods._createStars.call(this); + this.score = methods._createScore.call(this); + + methods._apply.call(this, this.opt.score); + + var space = this.opt.space ? 4 : 0, + width = this.opt.width || (this.opt.number * this.opt.size + this.opt.number * space); + + if (this.opt.cancel) { + this.cancel = methods._createCancel.call(this); + + width += (this.opt.size + space); + } + + if (this.opt.readOnly) { + methods._lock.call(this); + } else { + that.css('cursor', 'pointer'); + methods._binds.call(this); + } + + if (this.opt.width !== false) { + that.css('width', width); + } + + methods._target.call(this, this.opt.score); + + that.data({ 'settings': this.opt, 'raty': true }); + }); + }, _adjustPrecision: function() { + this.opt.targetType = 'score'; + this.opt.half = true; + }, _apply: function(score) { + if (score && score > 0) { + score = methods._between(score, 0, this.opt.number); + this.score.val(score); + } + + methods._fill.call(this, score); + + if (score) { + methods._roundStars.call(this, score); + } + }, _between: function(value, min, max) { + return Math.min(Math.max(parseFloat(value), min), max); + }, _binds: function() { + if (this.cancel) { + methods._bindCancel.call(this); + } + + methods._bindClick.call(this); + methods._bindOut.call(this); + methods._bindOver.call(this); + }, _bindCancel: function() { + methods._bindClickCancel.call(this); + methods._bindOutCancel.call(this); + methods._bindOverCancel.call(this); + }, _bindClick: function() { + var self = this, + that = $(self); + + self.stars.on('click.raty', function(evt) { + self.score.val((self.opt.half || self.opt.precision) ? that.data('score') : this.alt); + + if (self.opt.click) { + self.opt.click.call(self, parseFloat(self.score.val()), evt); + } + }); + }, _bindClickCancel: function() { + var self = this; + + self.cancel.on('click.raty', function(evt) { + self.score.removeAttr('value'); + + if (self.opt.click) { + self.opt.click.call(self, null, evt); + } + }); + }, _bindOut: function() { + var self = this; + + $(this).on('mouseleave.raty', function(evt) { + var score = parseFloat(self.score.val()) || undefined; + + methods._apply.call(self, score); + methods._target.call(self, score, evt); + + if (self.opt.mouseout) { + self.opt.mouseout.call(self, score, evt); + } + }); + }, _bindOutCancel: function() { + var self = this; + + self.cancel.on('mouseleave.raty', function(evt) { + $(this).attr('src', self.opt.path + self.opt.cancelOff); + + if (self.opt.mouseout) { + self.opt.mouseout.call(self, self.score.val() || null, evt); + } + }); + }, _bindOverCancel: function() { + var self = this; + + self.cancel.on('mouseover.raty', function(evt) { + $(this).attr('src', self.opt.path + self.opt.cancelOn); + + self.stars.attr('src', self.opt.path + self.opt.starOff); + + methods._target.call(self, null, evt); + + if (self.opt.mouseover) { + self.opt.mouseover.call(self, null); + } + }); + }, _bindOver: function() { + var self = this, + that = $(self), + action = self.opt.half ? 'mousemove.raty' : 'mouseover.raty'; + + self.stars.on(action, function(evt) { + var score = parseInt(this.alt, 10); + + if (self.opt.half) { + var position = parseFloat((evt.pageX - $(this).offset().left) / self.opt.size), + plus = (position > .5) ? 1 : .5; + + score = score - 1 + plus; + + methods._fill.call(self, score); + + if (self.opt.precision) { + score = score - plus + position; + } + + methods._roundStars.call(self, score); + + that.data('score', score); + } else { + methods._fill.call(self, score); + } + + methods._target.call(self, score, evt); + + if (self.opt.mouseover) { + self.opt.mouseover.call(self, score, evt); + } + }); + }, _callback: function(options) { + for (i in options) { + if (typeof this.opt[options[i]] === 'function') { + this.opt[options[i]] = this.opt[options[i]].call(this); + } + } + }, _createCancel: function() { + var that = $(this), + icon = this.opt.path + this.opt.cancelOff, + cancel = $('<img />', { src: icon, alt: 'x', title: this.opt.cancelHint, 'class': 'raty-cancel' }); + + if (this.opt.cancelPlace == 'left') { + that.prepend('&#160;').prepend(cancel); + } else { + that.append('&#160;').append(cancel); + } + + return cancel; + }, _createScore: function() { + return $('<input />', { type: 'hidden', name: this.opt.scoreName }).appendTo(this); + }, _createStars: function() { + var that = $(this); + + for (var i = 1; i <= this.opt.number; i++) { + var title = methods._getHint.call(this, i), + icon = (this.opt.score && this.opt.score >= i) ? 'starOn' : 'starOff'; + + icon = this.opt.path + this.opt[icon]; + + $('<img />', { src : icon, alt: i, title: title }).appendTo(this); + + if (this.opt.space) { + that.append((i < this.opt.number) ? '&#160;' : ''); + } + } + + return that.children('img'); + }, _error: function(message) { + $(this).html(message); + + $.error(message); + }, _fill: function(score) { + var self = this, + hash = 0; + + for (var i = 1; i <= self.stars.length; i++) { + var star = self.stars.eq(i - 1), + select = self.opt.single ? (i == score) : (i <= score); + + if (self.opt.iconRange && self.opt.iconRange.length > hash) { + var irange = self.opt.iconRange[hash], + on = irange.on || self.opt.starOn, + off = irange.off || self.opt.starOff, + icon = select ? on : off; + + if (i <= irange.range) { + star.attr('src', self.opt.path + icon); + } + + if (i == irange.range) { + hash++; + } + } else { + var icon = select ? 'starOn' : 'starOff'; + + star.attr('src', this.opt.path + this.opt[icon]); + } + } + }, _getHint: function(score) { + var hint = this.opt.hints[score - 1]; + return (hint === '') ? '' : (hint || score); + }, _lock: function() { + var score = parseInt(this.score.val(), 10), // TODO: 3.1 >> [['1'], ['2'], ['3', '.1', '.2']] + hint = score ? methods._getHint.call(this, score) : this.opt.noRatedMsg; + + $(this).data('readonly', true).css('cursor', '').attr('title', hint); + + this.score.attr('readonly', 'readonly'); + this.stars.attr('title', hint); + + if (this.cancel) { + this.cancel.hide(); + } + }, _roundStars: function(score) { + var rest = (score - Math.floor(score)).toFixed(2); + + if (rest > this.opt.round.down) { + var icon = 'starOn'; // Up: [x.76 .. x.99] + + if (this.opt.halfShow && rest < this.opt.round.up) { // Half: [x.26 .. x.75] + icon = 'starHalf'; + } else if (rest < this.opt.round.full) { // Down: [x.00 .. x.5] + icon = 'starOff'; + } + + this.stars.eq(Math.ceil(score) - 1).attr('src', this.opt.path + this.opt[icon]); + } // Full down: [x.00 .. x.25] + }, _target: function(score, evt) { + if (this.opt.target) { + var target = $(this.opt.target); + + if (target.length === 0) { + methods._error.call(this, 'Target selector invalid or missing!'); + } + + if (this.opt.targetFormat.indexOf('{score}') < 0) { + methods._error.call(this, 'Template "{score}" missing!'); + } + + var mouseover = evt && evt.type == 'mouseover'; + + if (score === undefined) { + score = this.opt.targetText; + } else if (score === null) { + score = mouseover ? this.opt.cancelHint : this.opt.targetText; + } else { + if (this.opt.targetType == 'hint') { + score = methods._getHint.call(this, Math.ceil(score)); + } else if (this.opt.precision) { + score = parseFloat(score).toFixed(1); + } + + if (!mouseover && !this.opt.targetKeep) { + score = this.opt.targetText; + } + } + + if (score) { + score = this.opt.targetFormat.toString().replace('{score}', score); + } + + if (target.is(':input')) { + target.val(score); + } else { + target.html(score); + } + } + }, _unlock: function() { + $(this).data('readonly', false).css('cursor', 'pointer').removeAttr('title'); + + this.score.removeAttr('readonly', 'readonly'); + + for (var i = 0; i < this.opt.number; i++) { + this.stars.eq(i).attr('title', methods._getHint.call(this, i + 1)); + } + + if (this.cancel) { + this.cancel.css('display', ''); + } + }, cancel: function(click) { + return this.each(function() { + if ($(this).data('readonly') !== true) { + methods[click ? 'click' : 'score'].call(this, null); + this.score.removeAttr('value'); + } + }); + }, click: function(score) { + return $(this).each(function() { + if ($(this).data('readonly') !== true) { + methods._apply.call(this, score); + + if (!this.opt.click) { + methods._error.call(this, 'You must add the "click: function(score, evt) { }" callback.'); + } + + this.opt.click.call(this, score, { type: 'click' }); + + methods._target.call(this, score); + } + }); + }, destroy: function() { + return $(this).each(function() { + var that = $(this), + raw = that.data('raw'); + + if (raw) { + that.off('.raty').empty().css({ cursor: raw.style.cursor, width: raw.style.width }).removeData('readonly'); + } else { + that.data('raw', that.clone()[0]); + } + }); + }, getScore: function() { + var score = [], + value ; + + $(this).each(function() { + value = this.score.val(); + + score.push(value ? parseFloat(value) : undefined); + }); + + return (score.length > 1) ? score : score[0]; + }, readOnly: function(readonly) { + return this.each(function() { + var that = $(this); + + if (that.data('readonly') !== readonly) { + if (readonly) { + that.off('.raty').children('img').off('.raty'); + + methods._lock.call(this); + } else { + methods._binds.call(this); + methods._unlock.call(this); + } + + that.data('readonly', readonly); + } + }); + }, reload: function() { + return methods.set.call(this, {}); + }, score: function() { + return arguments.length ? methods.setScore.apply(this, arguments) : methods.getScore.call(this); + }, set: function(settings) { + return this.each(function() { + var that = $(this), + actual = that.data('settings'), + news = $.extend({}, actual, settings); + + that.raty(news); + }); + }, setScore: function(score) { + return $(this).each(function() { + if ($(this).data('readonly') !== true) { + methods._apply.call(this, score); + methods._target.call(this, score); + } + }); + } + }; + + $.fn.raty = function(method) { + if (methods[method]) { + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + } else if (typeof method === 'object' || !method) { + return methods.init.apply(this, arguments); + } else { + $.error('Method ' + method + ' does not exist!'); + } + }; + + $.fn.raty.defaults = { + cancel : false, + cancelHint : 'Cancel this rating!', + cancelOff : 'cancel-off.png', + cancelOn : 'cancel-on.png', + cancelPlace : 'left', + click : undefined, + half : false, + halfShow : true, + hints : ['bad', 'poor', 'regular', 'good', 'gorgeous'], + iconRange : undefined, + mouseout : undefined, + mouseover : undefined, + noRatedMsg : 'Not rated yet!', + number : 5, + numberMax : 20, + path : '', + precision : false, + readOnly : false, + round : { down: .25, full: .6, up: .76 }, + score : undefined, + scoreName : 'score', + single : false, + size : 16, + space : true, + starHalf : 'star-half.png', + starOff : 'star-off.png', + starOn : 'star-on.png', + target : undefined, + targetFormat : '{score}', + targetKeep : false, + targetText : '', + targetType : 'hint', + width : undefined + }; + +})(jQuery); diff --git a/static/plugins/raty/jquery.raty.min.js b/static/plugins/raty/jquery.raty.min.js new file mode 100755 index 0000000..6ddb40d --- /dev/null +++ b/static/plugins/raty/jquery.raty.min.js @@ -0,0 +1,12 @@ +/*! + * jQuery Raty - A Star Rating Plugin + * + * Licensed under The MIT License + * + * @version 2.5.2 + * @author Washington Botelho + * @documentation wbotelhos.com/raty + * + */ + +;(function(b){var a={init:function(c){return this.each(function(){a.destroy.call(this);this.opt=b.extend(true,{},b.fn.raty.defaults,c);var e=b(this),g=["number","readOnly","score","scoreName"];a._callback.call(this,g);if(this.opt.precision){a._adjustPrecision.call(this);}this.opt.number=a._between(this.opt.number,0,this.opt.numberMax);this.opt.path=this.opt.path||"";if(this.opt.path&&this.opt.path.slice(this.opt.path.length-1,this.opt.path.length)!=="/"){this.opt.path+="/";}this.stars=a._createStars.call(this);this.score=a._createScore.call(this);a._apply.call(this,this.opt.score);var f=this.opt.space?4:0,d=this.opt.width||(this.opt.number*this.opt.size+this.opt.number*f);if(this.opt.cancel){this.cancel=a._createCancel.call(this);d+=(this.opt.size+f);}if(this.opt.readOnly){a._lock.call(this);}else{e.css("cursor","pointer");a._binds.call(this);}if(this.opt.width!==false){e.css("width",d);}a._target.call(this,this.opt.score);e.data({settings:this.opt,raty:true});});},_adjustPrecision:function(){this.opt.targetType="score";this.opt.half=true;},_apply:function(c){if(c&&c>0){c=a._between(c,0,this.opt.number);this.score.val(c);}a._fill.call(this,c);if(c){a._roundStars.call(this,c);}},_between:function(e,d,c){return Math.min(Math.max(parseFloat(e),d),c);},_binds:function(){if(this.cancel){a._bindCancel.call(this);}a._bindClick.call(this);a._bindOut.call(this);a._bindOver.call(this);},_bindCancel:function(){a._bindClickCancel.call(this);a._bindOutCancel.call(this);a._bindOverCancel.call(this);},_bindClick:function(){var c=this,d=b(c);c.stars.on("click.raty",function(e){c.score.val((c.opt.half||c.opt.precision)?d.data("score"):this.alt);if(c.opt.click){c.opt.click.call(c,parseFloat(c.score.val()),e);}});},_bindClickCancel:function(){var c=this;c.cancel.on("click.raty",function(d){c.score.removeAttr("value");if(c.opt.click){c.opt.click.call(c,null,d);}});},_bindOut:function(){var c=this;b(this).on("mouseleave.raty",function(d){var e=parseFloat(c.score.val())||undefined;a._apply.call(c,e);a._target.call(c,e,d);if(c.opt.mouseout){c.opt.mouseout.call(c,e,d);}});},_bindOutCancel:function(){var c=this;c.cancel.on("mouseleave.raty",function(d){b(this).attr("src",c.opt.path+c.opt.cancelOff);if(c.opt.mouseout){c.opt.mouseout.call(c,c.score.val()||null,d);}});},_bindOverCancel:function(){var c=this;c.cancel.on("mouseover.raty",function(d){b(this).attr("src",c.opt.path+c.opt.cancelOn);c.stars.attr("src",c.opt.path+c.opt.starOff);a._target.call(c,null,d);if(c.opt.mouseover){c.opt.mouseover.call(c,null);}});},_bindOver:function(){var c=this,d=b(c),e=c.opt.half?"mousemove.raty":"mouseover.raty";c.stars.on(e,function(g){var h=parseInt(this.alt,10);if(c.opt.half){var f=parseFloat((g.pageX-b(this).offset().left)/c.opt.size),j=(f>0.5)?1:0.5;h=h-1+j;a._fill.call(c,h);if(c.opt.precision){h=h-j+f;}a._roundStars.call(c,h);d.data("score",h);}else{a._fill.call(c,h);}a._target.call(c,h,g);if(c.opt.mouseover){c.opt.mouseover.call(c,h,g);}});},_callback:function(c){for(i in c){if(typeof this.opt[c[i]]==="function"){this.opt[c[i]]=this.opt[c[i]].call(this);}}},_createCancel:function(){var e=b(this),c=this.opt.path+this.opt.cancelOff,d=b("<img />",{src:c,alt:"x",title:this.opt.cancelHint,"class":"raty-cancel"});if(this.opt.cancelPlace=="left"){e.prepend("&#160;").prepend(d);}else{e.append("&#160;").append(d);}return d;},_createScore:function(){return b("<input />",{type:"hidden",name:this.opt.scoreName}).appendTo(this);},_createStars:function(){var e=b(this);for(var c=1;c<=this.opt.number;c++){var f=a._getHint.call(this,c),d=(this.opt.score&&this.opt.score>=c)?"starOn":"starOff";d=this.opt.path+this.opt[d];b("<img />",{src:d,alt:c,title:f}).appendTo(this);if(this.opt.space){e.append((c<this.opt.number)?"&#160;":"");}}return e.children("img");},_error:function(c){b(this).html(c);b.error(c);},_fill:function(d){var m=this,e=0;for(var f=1;f<=m.stars.length;f++){var g=m.stars.eq(f-1),l=m.opt.single?(f==d):(f<=d);if(m.opt.iconRange&&m.opt.iconRange.length>e){var j=m.opt.iconRange[e],h=j.on||m.opt.starOn,c=j.off||m.opt.starOff,k=l?h:c;if(f<=j.range){g.attr("src",m.opt.path+k);}if(f==j.range){e++;}}else{var k=l?"starOn":"starOff";g.attr("src",this.opt.path+this.opt[k]);}}},_getHint:function(d){var c=this.opt.hints[d-1];return(c==="")?"":(c||d);},_lock:function(){var d=parseInt(this.score.val(),10),c=d?a._getHint.call(this,d):this.opt.noRatedMsg;b(this).data("readonly",true).css("cursor","").attr("title",c);this.score.attr("readonly","readonly");this.stars.attr("title",c);if(this.cancel){this.cancel.hide();}},_roundStars:function(e){var d=(e-Math.floor(e)).toFixed(2);if(d>this.opt.round.down){var c="starOn";if(this.opt.halfShow&&d<this.opt.round.up){c="starHalf";}else{if(d<this.opt.round.full){c="starOff";}}this.stars.eq(Math.ceil(e)-1).attr("src",this.opt.path+this.opt[c]);}},_target:function(f,d){if(this.opt.target){var e=b(this.opt.target);if(e.length===0){a._error.call(this,"Target selector invalid or missing!");}if(this.opt.targetFormat.indexOf("{score}")<0){a._error.call(this,'Template "{score}" missing!');}var c=d&&d.type=="mouseover";if(f===undefined){f=this.opt.targetText;}else{if(f===null){f=c?this.opt.cancelHint:this.opt.targetText;}else{if(this.opt.targetType=="hint"){f=a._getHint.call(this,Math.ceil(f));}else{if(this.opt.precision){f=parseFloat(f).toFixed(1);}}if(!c&&!this.opt.targetKeep){f=this.opt.targetText;}}}if(f){f=this.opt.targetFormat.toString().replace("{score}",f);}if(e.is(":input")){e.val(f);}else{e.html(f);}}},_unlock:function(){b(this).data("readonly",false).css("cursor","pointer").removeAttr("title");this.score.removeAttr("readonly","readonly");for(var c=0;c<this.opt.number;c++){this.stars.eq(c).attr("title",a._getHint.call(this,c+1));}if(this.cancel){this.cancel.css("display","");}},cancel:function(c){return this.each(function(){if(b(this).data("readonly")!==true){a[c?"click":"score"].call(this,null);this.score.removeAttr("value");}});},click:function(c){return b(this).each(function(){if(b(this).data("readonly")!==true){a._apply.call(this,c);if(!this.opt.click){a._error.call(this,'You must add the "click: function(score, evt) { }" callback.');}this.opt.click.call(this,c,{type:"click"});a._target.call(this,c);}});},destroy:function(){return b(this).each(function(){var d=b(this),c=d.data("raw");if(c){d.off(".raty").empty().css({cursor:c.style.cursor,width:c.style.width}).removeData("readonly");}else{d.data("raw",d.clone()[0]);}});},getScore:function(){var d=[],c;b(this).each(function(){c=this.score.val();d.push(c?parseFloat(c):undefined);});return(d.length>1)?d:d[0];},readOnly:function(c){return this.each(function(){var d=b(this);if(d.data("readonly")!==c){if(c){d.off(".raty").children("img").off(".raty");a._lock.call(this);}else{a._binds.call(this);a._unlock.call(this);}d.data("readonly",c);}});},reload:function(){return a.set.call(this,{});},score:function(){return arguments.length?a.setScore.apply(this,arguments):a.getScore.call(this);},set:function(c){return this.each(function(){var e=b(this),f=e.data("settings"),d=b.extend({},f,c);e.raty(d);});},setScore:function(c){return b(this).each(function(){if(b(this).data("readonly")!==true){a._apply.call(this,c);a._target.call(this,c);}});}};b.fn.raty=function(c){if(a[c]){return a[c].apply(this,Array.prototype.slice.call(arguments,1));}else{if(typeof c==="object"||!c){return a.init.apply(this,arguments);}else{b.error("Method "+c+" does not exist!");}}};b.fn.raty.defaults={cancel:false,cancelHint:"Cancel this rating!",cancelOff:"cancel-off.png",cancelOn:"cancel-on.png",cancelPlace:"left",click:undefined,half:false,halfShow:true,hints:["bad","poor","regular","good","gorgeous"],iconRange:undefined,mouseout:undefined,mouseover:undefined,noRatedMsg:"Not rated yet!",number:5,numberMax:20,path:"",precision:false,readOnly:false,round:{down:0.25,full:0.6,up:0.76},score:undefined,scoreName:"score",single:false,size:16,space:true,starHalf:"star-half.png",starOff:"star-off.png",starOn:"star-on.png",target:undefined,targetFormat:"{score}",targetKeep:false,targetText:"",targetType:"hint",width:undefined};})(jQuery); diff --git a/static/plugins/slide/css/slide.css b/static/plugins/slide/css/slide.css new file mode 100755 index 0000000..0b90098 --- /dev/null +++ b/static/plugins/slide/css/slide.css @@ -0,0 +1,14 @@ +img { border: 0;} +.ck-slide ul { margin: 0; padding: 0; list-style-type: none;} +.ck-slide { position: relative; overflow: hidden;} +.ck-slide ul.ck-slide-wrapper { position: absolute; top: 0; left: 0; z-index: 1; margin: 0; padding: 0;} +.ck-slide ul.ck-slide-wrapper li { position: absolute;} +.ck-slide .ck-prev, .ck-slide .ck-next { position: absolute; top: 50%; z-index: 2; width: 35px; height: 70px; margin-top: -35px; border-radius: 3px; opacity: .15; background: red; text-indent: -9999px; background-repeat: no-repeat; transition: opacity .2s linear 0s;} +.ck-slide .ck-prev { left: 5px; background: url(../images/arrow-left.png) #000 50% no-repeat;} +.ck-slide .ck-next { right: 5px; background: url(../images/arrow-right.png) #000 50% no-repeat;} +.ck-slidebox { position: absolute; left: 50%; bottom: 12px; z-index: 30;} +.ck-slidebox ul { height: 20px; padding: 0 4px; border-radius: 8px; background: rgba(0,0,0,0.5);} +.ck-slidebox ul li { float: left; height: 12px; margin: 4px 4px;} +.ck-slidebox ul li em { display: block; width: 12px; height: 12px; border-radius: 100%; background-color: #fff; text-indent: -9999px; cursor: pointer;} +.ck-slidebox ul li.current em { background-color: #fe6500;} +.ck-slidebox ul li em:hover { background-color: #fe6500;} \ No newline at end of file diff --git a/static/plugins/slide/images/arrow-left.png b/static/plugins/slide/images/arrow-left.png new file mode 100755 index 0000000..8b8a8c1 Binary files /dev/null and b/static/plugins/slide/images/arrow-left.png differ diff --git a/static/plugins/slide/images/arrow-right.png b/static/plugins/slide/images/arrow-right.png new file mode 100755 index 0000000..052c70c Binary files /dev/null and b/static/plugins/slide/images/arrow-right.png differ diff --git a/static/plugins/slide/js/slide.js b/static/plugins/slide/js/slide.js new file mode 100755 index 0000000..7c1f730 --- /dev/null +++ b/static/plugins/slide/js/slide.js @@ -0,0 +1,117 @@ +(function($){ + $.fn.ckSlide = function(opts){ + opts = $.extend({}, $.fn.ckSlide.opts, opts); + this.each(function(){ + var slidewrap = $(this).find('.ck-slide-wrapper'); + var slide = slidewrap.find('li'); + var count = slide.length; + var that = this; + var index = 0; + var time = null; + $(this).data('opts', opts); + // next + $(this).find('.ck-next').on('click', function(){ + if(opts['isAnimate'] == true){ + return; + } + + var old = index; + if(index >= count - 1){ + index = 0; + }else{ + index++; + } + change.call(that, index, old); + }); + // prev + $(this).find('.ck-prev').on('click', function(){ + if(opts['isAnimate'] == true){ + return; + } + + var old = index; + if(index <= 0){ + index = count - 1; + }else{ + index--; + } + change.call(that, index, old); + }); + $(this).find('.ck-slidebox li').each(function(cindex){ + $(this).on('click.slidebox', function(){ + change.call(that, cindex, index); + index = cindex; + }); + }); + + // focus clean auto play + $(this).on('mouseover', function(){ + if(opts.autoPlay){ + clearInterval(time); + } + $(this).find('.ctrl-slide').css({opacity:0.6}); + }); + // leave + $(this).on('mouseleave', function(){ + if(opts.autoPlay){ + startAtuoPlay(); + } + $(this).find('.ctrl-slide').css({opacity:0.15}); + }); + startAtuoPlay(); + // auto play + function startAtuoPlay(){ + if(opts.autoPlay){ + time = setInterval(function(){ + var old = index; + if(index >= count - 1){ + index = 0; + }else{ + index++; + } + change.call(that, index, old); + }, 2000); + } + } + // 修正box + var box = $(this).find('.ck-slidebox'); + box.css({ + 'margin-left':-(box.width() / 2) + }) + // dir + switch(opts.dir){ + case "x": + opts['width'] = $(this).width(); + slidewrap.css({ + 'width':count * opts['width'] + }); + slide.css({ + 'float':'left', + 'position':'relative' + }); + slidewrap.wrap('<div class="ck-slide-dir"></div>'); + slide.show(); + break; + } + }); + }; + function change(show, hide){ + var opts = $(this).data('opts'); + if(opts.dir == 'x'){ + var x = show * opts['width']; + $(this).find('.ck-slide-wrapper').stop().animate({'margin-left':-x}, function(){opts['isAnimate'] = false;}); + opts['isAnimate'] = true + }else{ + $(this).find('.ck-slide-wrapper li').eq(hide).stop().animate({opacity:0}); + $(this).find('.ck-slide-wrapper li').eq(show).show().css({opacity:0}).stop().animate({opacity:1}); + } + + $(this).find('.ck-slidebox li').removeClass('current'); + $(this).find('.ck-slidebox li').eq(show).addClass('current'); + } + $.fn.ckSlide.opts = { + autoPlay: false, + dir: null, + isAnimate: false + }; +})(jQuery); \ No newline at end of file diff --git a/static/plugins/slide/js/slide.min.js b/static/plugins/slide/js/slide.min.js new file mode 100755 index 0000000..d3945b1 --- /dev/null +++ b/static/plugins/slide/js/slide.min.js @@ -0,0 +1 @@ +(function($){$.fn.ckSlide=function(opts){opts=$.extend({},$.fn.ckSlide.opts,opts);this.each(function(){var slidewrap=$(this).find('.ck-slide-wrapper');var slide=slidewrap.find('li');var count=slide.length;var that=this;var index=0;var time=null;$(this).data('opts',opts);$(this).find('.ck-next').on('click',function(){if(opts['isAnimate']==true){return;}var old=index;if(index>=count-1){index=0;}else{index++;}change.call(that,index,old);});$(this).find('.ck-prev').on('click',function(){if(opts['isAnimate']==true){return;}var old=index;if(index<=0){index=count-1;}else{index--;}change.call(that,index,old);});$(this).find('.ck-slidebox li').each(function(cindex){$(this).on('click.slidebox',function(){change.call(that,cindex,index);index=cindex;});});$(this).on('mouseover',function(){if(opts.autoPlay){clearInterval(time);}$(this).find('.ctrl-slide').css({opacity:0.6});});$(this).on('mouseleave',function(){if(opts.autoPlay){startAtuoPlay();}$(this).find('.ctrl-slide').css({opacity:0.15});});startAtuoPlay();function startAtuoPlay(){if(opts.autoPlay){time=setInterval(function(){var old=index;if(index>=count-1){index=0;}else{index++;}change.call(that,index,old);},2000);}}var box=$(this).find('.ck-slidebox');box.css({'margin-left':-(box.width()/2)})switch(opts.dir){case "x":opts['width']=$(this).width();slidewrap.css({'width':count*opts['width']});slide.css({'float':'left','position':'relative'});slidewrap.wrap('<div class="ck-slide-dir"></div>');slide.show();break;}});};function change(show,hide){var opts=$(this).data('opts');if(opts.dir=='x'){var x=show*opts['width'];$(this).find('.ck-slide-wrapper').stop().animate({'margin-left':-x},function(){opts['isAnimate']=false;});opts['isAnimate']=true}else{$(this).find('.ck-slide-wrapper li').eq(hide).stop().animate({opacity:0});$(this).find('.ck-slide-wrapper li').eq(show).show().css({opacity:0}).stop().animate({opacity:1});}$(this).find('.ck-slidebox li').removeClass('current');$(this).find('.ck-slidebox li').eq(show).addClass('current');}$.fn.ckSlide.opts={autoPlay:false,dir:null,isAnimate:false};})(jQuery); \ No newline at end of file diff --git a/static/plugins/validator/images/loading.gif b/static/plugins/validator/images/loading.gif new file mode 100755 index 0000000..6e5bace Binary files /dev/null and b/static/plugins/validator/images/loading.gif differ diff --git a/static/plugins/validator/images/validator_default.png b/static/plugins/validator/images/validator_default.png new file mode 100755 index 0000000..7bf05e7 Binary files /dev/null and b/static/plugins/validator/images/validator_default.png differ diff --git a/static/plugins/validator/images/validator_simple.png b/static/plugins/validator/images/validator_simple.png new file mode 100755 index 0000000..9db57bb Binary files /dev/null and b/static/plugins/validator/images/validator_simple.png differ diff --git a/static/plugins/validator/jquery.validator.css b/static/plugins/validator/jquery.validator.css new file mode 100755 index 0000000..adeae82 --- /dev/null +++ b/static/plugins/validator/jquery.validator.css @@ -0,0 +1,269 @@ +.n-inline-block, +.nice-validator input, +.nice-validator select, +.nice-validator textarea, +.nice-validator [contenteditable], +.msg-wrap, +.n-icon, +.n-msg { + display: inline-block; + *display: inline; + *zoom: 1; +} +.nice-validator .msg-container .msg-box { + display: block; +} +.nice-validator .msg-container .msg-wrap { + position: static; +} +.msg-box { + position: relative; + *zoom: 1; +} +.msg-wrap { + position: relative; + white-space: nowrap; + line-height: 16px; + font-size: 12px; +} +.msg-wrap, +.n-icon, +.n-msg { + vertical-align: top; +} +.msg-box .msg-wrap .n-error, +.msg-box .msg-wrap .n-ok, +.msg-box .msg-wrap .n-tip { + display: block; + background: none; + box-shadow: none; + padding: 3px 2px; +} +.n-arrow { + position: absolute; + overflow: hidden; +} +.n-arrow b, +.n-arrow i { + position: absolute; + left: 0; + top: 0; + border: 0; + margin: 0; + padding: 0; + overflow: hidden; + font-weight: 400; + font-style: normal; + font-size: 12px; + font-family: serif; + line-height: 14px; + _line-height: 15px; +} +.n-arrow i { + text-shadow: none; +} +.n-icon { + width: 16px; + height: 16px; + overflow: hidden; + background-repeat: no-repeat; +} +.n-msg { + display: inline-block; + *display: inline; + *zoom: 1; + margin-left: 1px; +} +.n-error { + color: #c33; +} +.n-ok { + color: #390; +} +.n-tip .n-msg, +.n-loading { + color: #808080; +} +.n-error .n-icon { + background-position: 0 0; +} +.n-ok .n-icon { + background-position: -16px 0; +} +.n-tip .n-icon { + background-position: -32px 0; +} +.n-loading .n-icon { + background: url("images/loading.gif") 0 center no-repeat !important; +} +.n-top, +.n-right, +.n-bottom, +.n-left { + display: inline-block; + *display: inline; + *zoom: 1; + line-height: 0; + vertical-align: top; + outline: 0; +} +.n-top .n-arrow, +.n-bottom .n-arrow { + height: 6px; + width: 12px; + left: 8px; +} +.n-left .n-arrow, +.n-right .n-arrow { + width: 6px; + height: 12px; + top: 6px; +} +.n-top { + vertical-align: top; +} +.n-top .msg-wrap { + margin-bottom: 6px; +} +.n-top .n-arrow { + bottom: -6px; +} +.n-top .n-arrow b { + top: -6px; +} +.n-top .n-arrow i { + top: -7px; +} +.n-bottom { + vertical-align: bottom; +} +.n-bottom .msg-wrap { + margin-top: 6px; +} +.n-bottom .n-arrow { + top: -6px; +} +.n-bottom .n-arrow b { + top: -1px; +} +.n-bottom .n-arrow i { + top: 0; +} +.n-left .msg-wrap { + right: 100%; + margin-right: 6px; +} +.n-left .n-arrow { + right: -6px; +} +.n-left .n-arrow b { + left: -6px; +} +.n-left .n-arrow i { + left: -7px; +} +.n-right .msg-wrap { + margin-left: 6px; +} +.n-right .n-arrow { + left: -6px; +} +.n-right .n-arrow b { + left: 1px; +} +.n-right .n-arrow i { + left: 2px; +} +/********************* + * Themes + *********************/ +.n-default .n-left, +.n-default .n-right { + margin-top: 5px; +} +.n-default .n-top .msg-wrap { + bottom: 100%; +} +.n-default .n-bottom .msg-wrap { + top: 100%; +} +.n-default .msg-wrap { + position: absolute; + z-index: 1; +} +.n-default .msg-wrap .n-icon { + background-image: url("images/validator_default.png"); +} +.n-default .n-tip .n-icon { + display: none; +} +.n-simple .msg-wrap { + position: absolute; + z-index: 1; +} +.n-simple .msg-wrap .n-icon { + background-image: url("images/validator_simple.png"); +} +.n-simple .n-top .msg-wrap { + bottom: 100%; +} +.n-simple .n-bottom .msg-wrap { + top: 100%; +} +.n-simple .n-left, +.n-simple .n-right { + margin-top: 5px; +} +.n-simple .n-bottom .msg-wrap { + margin-top: 3px; +} +.n-simple .n-tip .n-icon { + display: none; +} +.n-yellow .msg-wrap { + position: absolute; + z-index: 1; + padding: 4px 6px; + font-size: 12px; + border: 1px solid transparent; + background-color: #fffcef; + border-color: #ffbb76; + color: #db7c22; + box-shadow: 0 1px 3px #ccc; + border-radius: 2px; +} +.n-yellow .msg-wrap .n-arrow b { + color: #ffbb76; + text-shadow: 0 0 2px #ccc; +} +.n-yellow .msg-wrap .n-arrow i { + color: #fffcef; +} +.n-yellow .msg-wrap .n-icon { + background-image: url("images/validator_simple.png"); +} +.n-yellow .n-top .msg-wrap { + bottom: 100%; +} +.n-yellow .n-bottom .msg-wrap { + top: 100%; +} +.n-yellow .n-tip, +.n-yellow .n-ok, +.n-yellow .n-loading { + background-color: #f8fdff; + border-color: #ddd; + color: #333; + box-shadow: 0 1px 3px #ccc; +} +.n-yellow .n-tip .n-arrow b, +.n-yellow .n-ok .n-arrow b, +.n-yellow .n-loading .n-arrow b { + color: #ddd; + text-shadow: 0 0 2px #ccc; +} +.n-yellow .n-tip .n-arrow i, +.n-yellow .n-ok .n-arrow i, +.n-yellow .n-loading .n-arrow i { + color: #f8fdff; +} diff --git a/static/plugins/validator/jquery.validator.js b/static/plugins/validator/jquery.validator.js new file mode 100755 index 0000000..04d6432 --- /dev/null +++ b/static/plugins/validator/jquery.validator.js @@ -0,0 +1,2141 @@ +/*! nice-validator 1.0.4 + * (c) 2012-2016 Jony Zhang <niceue@live.com>, MIT Licensed + * https://github.com/niceue/nice-validator + */ +;(function(factory) { + typeof module === "object" && module.exports ? module.exports = factory( require( "jquery" ) ) : + typeof define === 'function' && define.amd ? require(['jquery'], factory) : + factory(jQuery); +}(function($, undefined) { + "use strict"; + + var NS = 'validator', + CLS_NS = '.' + NS, + CLS_NS_RULE = '.rule', + CLS_NS_FIELD = '.field', + CLS_NS_FORM = '.form', + CLS_WRAPPER = 'nice-' + NS, + CLS_MSG_BOX = 'msg-box', + ARIA_REQUIRED = 'aria-required', + ARIA_INVALID = 'aria-invalid', + DATA_RULE = 'data-rule', + DATA_MSG = 'data-msg', + DATA_TIP = 'data-tip', + DATA_OK = 'data-ok', + DATA_TIMELY = 'data-timely', + DATA_TARGET = 'data-target', + DATA_DISPLAY = 'data-display', + DATA_MUST = 'data-must', + NOVALIDATE = 'novalidate', + INPUT_SELECTOR = ':verifiable', + + rRules = /(&)?(!)?\b(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\|)?/g, + rRule = /(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/, + rDisplay = /(?:([^:;\(\[]*):)?(.*)/, + rDoubleBytes = /[^\x00-\xff]/g, + rPos = /top|right|bottom|left/, + rAjaxType = /(?:(cors|jsonp):)?(?:(post|get):)?(.+)/i, + rUnsafe = /[<>'"`\\]|&#x?\d+[A-F]?;?|%3[A-F]/gmi, + + noop = $.noop, + proxy = $.proxy, + trim = $.trim, + isFunction = $.isFunction, + isString = function(s) { + return typeof s === 'string'; + }, + isObject = function(o) { + return o && Object.prototype.toString.call(o) === '[object Object]'; + }, + isIE = document.documentMode || +(navigator.userAgent.match(/MSIE (\d+)/) && RegExp.$1), + attr = function(el, key, value) { + if (!el || !el.tagName) return null; + if (value !== undefined) { + if (value === null) el.removeAttribute(key); + else el.setAttribute(key, '' + value); + } else { + return el.getAttribute(key); + } + }, + novalidateonce, + preinitialized = {}, + + defaults = { + debug: 0, + theme: 'default', + ignore: '', + focusInvalid: true, + focusCleanup: false, + stopOnError: false, + beforeSubmit: null, + valid: null, + invalid: null, + validation: null, + validClass: 'n-valid', + invalidClass: 'n-invalid', + bindClassTo: null + }, + fieldDefaults = { + timely: 1, + display: null, + target: null, + ignoreBlank: false, + showOk: true, + // Translate ajax response to validation result + dataFilter: function (data) { + if ( isString(data) || ( isObject(data) && ('error' in data || 'ok' in data) ) ) { + return data; + } + }, + msgMaker: function(opt) { + var html; + html = '<span role="alert" class="msg-wrap n-'+ opt.type + '">' + opt.arrow; + if (opt.result) { + $.each(opt.result, function(i, obj){ + html += '<span class="n-'+ obj.type +'">' + opt.icon + '<span class="n-msg">' + obj.msg + '</span></span>'; + }); + } else { + html += opt.icon + '<span class="n-msg">' + opt.msg + '</span>'; + } + html += '</span>'; + return html; + }, + msgWrapper: 'span', + msgArrow: '', + msgIcon: '<span class="n-icon"></span>', + msgClass: '', + msgStyle: '', + msgShow: null, + msgHide: null + }, + themes = { + 'default': { + formClass: 'n-default', + msgClass: 'n-right' + } + }; + + /** jQuery Plugin + * @param {Object} options + debug {Boolean} 0 Whether to enable debug mode + timely {Number} 1 Whether to enable timely validation + theme {String} 'default' Theme name + stopOnError {Boolean} false Whether to stop validate when found an error input + focusCleanup {Boolean} false Whether to clean up the field message when focus the field + focusInvalid {Boolean} true Whether to focus the field that is invalid + ignoreBlank {Boolean} false When the field has no value, whether to ignore validation + ignore {jqSelector} '' Ignored fields (Using jQuery selector) + + beforeSubmit {Function} Do something before submit form + dataFilter {Function} Convert ajax results + valid {Function} Triggered when the form is valid + invalid {Function} Triggered when the form is invalid + validClass {String} 'n-valid' Add this class name to a valid field + invalidClass {String} 'n-invalid' Add this class name to a invalid field + bindClassTo {jqSelector} ':verifiable' Which element should the className binding to + + display {Function} Callback function to get dynamic display + target {Function} Callback function to get dynamic target + msgShow {Function} Trigger this callback when show message + msgHide {Function} Trigger this callback when hide message + msgWrapper {String} 'span' Message wrapper tag name + msgMaker {Function} Callback function to make message HTML + msgArrow {String} Message arrow template + msgIcon {String} Message icon template + msgStyle {String} Custom message css style + msgClass {String} Additional added to the message class names + formClass {String} Additional added to the form class names + + messages {Object} Custom messages for the current instance + rules {Object} Custom rules for the current instance + fields {Object} Field validation configuration + {String} key name|#id + {String|Object} value Rule string or an object which can pass more arguments + + fields[key][rule] {String} Rule string + fields[key][display] {String|Function} + fields[key][tip] {String} Custom tip message + fields[key][ok] {String} Custom success message + fields[key][msg] {Object} Custom error message + fields[key][msgStyle] {String} Custom message style + fields[key][msgClass] {String} A className which added to message placeholder element + fields[key][msgWrapper] {String} Tag name of the message placeholder element + fields[key][msgMaker] {Function} A function to custom message HTML + fields[key][dataFilter] {Function} A function to convert ajax results + fields[key][valid] {Function} A function triggered when field is valid + fields[key][invalid] {Function} A function triggered when field is invalid + fields[key][must] {Boolean} If set true, we always check the field even has remote checking + fields[key][timely] {Boolean} Whether to enable timely validation + fields[key][target] {jqSelector} Define placement of a message + */ + $.fn.validator = function(options) { + var that = this, + args = arguments; + + if (that.is(INPUT_SELECTOR)) return that; + if (!that.is('form')) that = this.find('form'); + if (!that.length) that = this; + + that.each(function() { + var instance = $(this).data(NS); + + if (instance) { + if ( isString(options) ) { + if ( options.charAt(0) === '_' ) return; + instance[options].apply(instance, [].slice.call(args, 1)); + } + else if (options) { + instance._reset(true); + instance._init(this, options); + } + } else { + new Validator(this, options); + } + }); + + return this; + }; + + + // Validate a field, or an area + $.fn.isValid = function(callback, hideMsg) { + var me = _getInstance(this[0]), + hasCallback = isFunction(callback), + ret, opt; + + if (!me) return true; + if (!hasCallback && hideMsg === undefined) hideMsg = callback; + me.checkOnly = !!hideMsg; + opt = me.options; + + ret = me._multiValidate( + this.is(INPUT_SELECTOR) ? this : this.find(INPUT_SELECTOR), + function(isValid){ + if (!isValid && opt.focusInvalid && !me.checkOnly) { + // navigate to the error element + me.$el.find('[' + ARIA_INVALID + ']:first').focus(); + } + if (hasCallback) { + if (callback.length) { + callback(isValid); + } else if (isValid) { + callback(); + } + } + me.checkOnly = false; + } + ); + + // If you pass a callback, we maintain the jQuery object chain + return hasCallback ? this : ret; + }; + + + // A faster selector than ":input:not(:submit,:button,:reset,:image,:disabled,[contenteditable])" + $.expr.pseudos.verifiable = function(elem) { + var name = elem.nodeName.toLowerCase(); + + return ( name === 'input' && !({submit: 1, button: 1, reset: 1, image: 1})[elem.type] || + name === 'select' || + name === 'textarea' || + elem.contentEditable === 'true' + ) && !elem.disabled; + }; + + // any value, but not only whitespace + $.expr.pseudos.filled = function(elem) { + return !!trim($(elem).val()); + }; + + + /** + * Creates a new Validator + * + * @class + * @param {Element} element - form element + * @param {Object} options - options for validator + */ + function Validator(element, options) { + var me = this; + + if ( !(me instanceof Validator) ) { + return new Validator(element, options); + } + + me.$el = $(element); + + if (me.$el.length) { + init(); + if (Validator.pending) { + $(window).on('validatorready', init); + } + } + else if ( isString(element) ) { + preinitialized[element] = options; + } + + function init() { + me._init(me.$el[0], options, !!arguments[0]); + } + } + + Validator.prototype = { + _init: function(element, options, hasInit) { + var me = this, + opt, themeOpt, dataOpt; + + // Initialization options + if ( isFunction(options) ) { + options = { + valid: options + }; + } + options = me._opt = options || {}; + dataOpt = attr(element, 'data-'+ NS +'-option'); + dataOpt = me._dataOpt = dataOpt && dataOpt.charAt(0) === '{' ? (new Function("return " + dataOpt))() : {}; + themeOpt = me._themeOpt = themes[ options.theme || dataOpt.theme || defaults.theme ]; + opt = me.options = $.extend({}, defaults, fieldDefaults, themeOpt, me.options, options, dataOpt); + + if (!hasInit) { + me.rules = new Rules(opt.rules, true); + me.messages = new Messages(opt.messages, true); + me.Field = _createFieldFactory(me); + me.elements = me.elements || {}; + me.deferred = {}; + me.errors = {}; + me.fields = {}; + // Initialization fields + me._initFields(opt.fields); + } + + // Initialization events and make a cache + if ( !me.$el.data(NS) ) { + me.$el.data(NS, me).addClass(CLS_WRAPPER +' '+ opt.formClass) + .on('form-submit-validate', function(e, a, $form, opts, veto) { + me.vetoed = veto.veto = !me.isValid; + me.ajaxFormOptions = opts; + }) + .on('submit'+ CLS_NS +' validate'+ CLS_NS, proxy(me, '_submit')) + .on('reset'+ CLS_NS, proxy(me, '_reset')) + .on('showmsg'+ CLS_NS, proxy(me, '_showmsg')) + .on('hidemsg'+ CLS_NS, proxy(me, '_hidemsg')) + .on('focusin'+ CLS_NS + ' click'+ CLS_NS, INPUT_SELECTOR, proxy(me, '_focusin')) + .on('focusout'+ CLS_NS +' validate'+ CLS_NS, INPUT_SELECTOR, proxy(me, '_focusout')) + .on('keyup'+ CLS_NS +' input'+ CLS_NS + ' compositionstart compositionend', INPUT_SELECTOR, proxy(me, '_focusout')) + .on('click'+ CLS_NS, ':radio,:checkbox', 'click', proxy(me, '_focusout')) + .on('change'+ CLS_NS, 'select,input[type="file"]', 'change', proxy(me, '_focusout')); + + // cache the novalidate attribute value + me._NOVALIDATE = attr(element, NOVALIDATE); + // Initialization is complete, stop off default HTML5 form validation + // If use "jQuery.attr('novalidate')" in IE7 will complain: "SCRIPT3: Member not found." + attr(element, NOVALIDATE, NOVALIDATE); + } + + // Display all messages in target container + if ( isString(opt.target) ) { + me.$el.find(opt.target).addClass('msg-container'); + } + }, + + // Guess whether the form use ajax submit + _guessAjax: function(form) { + var me = this; + + if ( !(me.isAjaxSubmit = !!me.options.valid) ) { + // if there is a "valid.form" event + var events = ($._data || $.data)(form, "events"); + me.isAjaxSubmit = issetEvent(events, 'valid', 'form') || issetEvent(events, 'submit', 'form-plugin'); + } + + function issetEvent(events, name, namespace) { + if ( events && events[name] && + $.map(events[name], function(e){ + return ~e.namespace.indexOf(namespace) ? 1 : null; + }).length + ) { + return true; + } + return false; + } + }, + + _initFields: function(fields) { + var me = this, k, arr, i, + clear = fields === null; + + // Processing field information + if (clear) fields = me.fields; + + if ( isObject(fields) ) { + for (k in fields) { + if (~k.indexOf(',')) { + arr = k.split(','); + i = arr.length; + while (i--) { + initField(trim(arr[i]), fields[k]); + } + } else { + initField(k, fields[k]); + } + } + } + + // Parsing DOM rules + me.$el.find(INPUT_SELECTOR).each(function() { + me._parse(this); + }); + + function initField(k, v) { + // delete a field from settings + if ( v === null || clear ) { + var el = me.elements[k]; + if (el) me._resetElement(el, true); + delete me.fields[k]; + } else { + me.fields[k] = new me.Field(k, isString(v) ? {rule: v} : v, me.fields[k]); + } + } + }, + + // Parsing a field + _parse: function(el) { + var me = this, + field, + key = el.name, + display, + timely, + dataRule = attr(el, DATA_RULE); + + dataRule && attr(el, DATA_RULE, null); + + // If the field has passed the key as id mode, or it doesn't has a name + if ( el.id && ( + ('#' + el.id in me.fields) || + !key || + // If dataRule and element are diffrent from old's, we use ID mode. + (dataRule !== null && (field = me.fields[key]) && dataRule !== field.rule && el.id !== field.key) + ) + ) { + key = '#' + el.id; + } + // doesn't verify a field that has neither id nor name + if (!key) return; + + field = me.getField(key, true); + // The priority of passing parameter by DOM is higher than by JS. + field.rule = dataRule || field.rule; + + if (display = attr(el, DATA_DISPLAY)) { + field.display = display; + } + if (field.rule) { + if ( attr(el, DATA_MUST) !== null || /\b(?:match|checked)\b/.test(field.rule) ) { + field.must = true; + } + if ( /\brequired\b/.test(field.rule) ) { + field.required = true; + attr(el, ARIA_REQUIRED, true); + } + if (timely = attr(el, DATA_TIMELY)) { + field.timely = +timely; + } else if (field.timely > 3) { + attr(el, DATA_TIMELY, field.timely); + } + me._parseRule(field); + field.old = {}; + } + if ( isString(field.target) ) { + attr(el, DATA_TARGET, field.target); + } + if ( isString(field.tip) ) { + attr(el, DATA_TIP, field.tip); + } + + return me.fields[key] = field; + }, + + // Parsing field rules + _parseRule: function(field) { + var arr = rDisplay.exec(field.rule); + + if (!arr) return; + // current rule index + field._i = 0; + if (arr[1]) { + field.display = arr[1]; + } + if (arr[2]) { + field._rules = []; + arr[2].replace(rRules, function(){ + var args = arguments; + args[4] = args[4] || args[5]; + field._rules.push({ + and: args[1] === "&", + not: args[2] === "!", + or: args[6] === "|", + method: args[3], + params: args[4] ? $.map( args[4].split(', '), trim ) : undefined + }); + }); + } + }, + + // Verify a zone + _multiValidate: function($inputs, doneCallback){ + var me = this, + opt = me.options; + + me.hasError = false; + + if (opt.ignore) { + $inputs = $inputs.not(opt.ignore); + } + + $inputs.each(function() { + me._validate(this); + if (me.hasError && opt.stopOnError) { + // stop the validation + return false; + } + }); + + // Need to wait for all fields validation complete, especially asynchronous validation + if (doneCallback) { + me.validating = true; + $.when.apply( + null, + $.map(me.deferred, function(v){return v;}) + ).done(function(){ + doneCallback.call(me, !me.hasError); + me.validating = false; + }); + } + + // If the form does not contain asynchronous validation, the return value is correct. + // Otherwise, you should detect form validation result through "doneCallback". + return !$.isEmptyObject(me.deferred) ? undefined : !me.hasError; + }, + + // Validate the whole form + _submit: function(e) { + var me = this, + opt = me.options, + form = e.target, + canSubmit = e.type === 'submit' && !e.isDefaultPrevented(); + + e.preventDefault(); + + if ( + novalidateonce && ~(novalidateonce = false) || + // Prevent duplicate submission + me.submiting || + // Receive the "validate" event only from the form. + e.type === 'validate' && me.$el[0] !== form || + // trigger the beforeSubmit callback. + isFunction(opt.beforeSubmit) && opt.beforeSubmit.call(me, form) === false + ) { + return; + } + + if (me.isAjaxSubmit === undefined) { + me._guessAjax(form); + } + + me._debug('log', '\n<<< event: ' + e.type); + + me._reset(); + me.submiting = true; + + me._multiValidate( + me.$el.find(INPUT_SELECTOR), + function(isValid){ + var ret = (isValid || opt.debug === 2) ? 'valid' : 'invalid', + errors; + + if (!isValid) { + if (opt.focusInvalid) { + // navigate to the error element + me.$el.find('[' + ARIA_INVALID + ']:first').focus(); + } + errors = $.map(me.errors, function(err){return err;}); + } + + // releasing submit + me.submiting = false; + me.isValid = isValid; + + // trigger callback and event + isFunction(opt[ret]) && opt[ret].call(me, form, errors); + me.$el.trigger(ret + CLS_NS_FORM, [form, errors]); + + me._debug('log', '>>> ' + ret); + + if (!isValid) return; + // For jquery.form plugin + if (me.vetoed) { + $(form).ajaxSubmit(me.ajaxFormOptions); + } + else if (canSubmit && !me.isAjaxSubmit) { + document.createElement('form').submit.call(form); + } + } + ); + }, + + _reset: function(e) { + var me = this; + + me.errors = {}; + if (e) { + me.reseting = true; + me.$el.find(INPUT_SELECTOR).each( function(){ + me._resetElement(this); + }); + delete me.reseting; + } + }, + + _resetElement: function(el, all) { + this._setClass(el, null); + this.hideMsg(el); + if (all) { + attr(el, ARIA_REQUIRED, null); + } + }, + + // Handle events: "focusin/click" + _focusin: function(e) { + var me = this, + opt = me.options, + el = e.target, + timely, + msg; + + if ( me.validating || ( e.type==='click' && document.activeElement === el ) ) { + return; + } + + if (opt.focusCleanup) { + if ( attr(el, ARIA_INVALID) === 'true' ) { + me._setClass(el, null); + me.hideMsg(el); + } + } + + msg = attr(el, DATA_TIP); + + if (msg) { + me.showMsg(el, { + type: 'tip', + msg: msg + }); + } else { + if (attr(el, DATA_RULE)) { + me._parse(el); + } + if (timely = attr(el, DATA_TIMELY)) { + if ( timely === 8 || timely === 9 ) { + me._focusout(e); + } + } + } + }, + + // Handle events: "focusout/validate/keyup/click/change/input/compositionstart/compositionend" + _focusout: function(e) { + var me = this, + opt = me.options, + el = e.target, + etype = e.type, + etype0, + focusin = etype === 'focusin', + special = etype === 'validate', + elem, + field, + old, + value, + timestamp, + key, specialKey, + timely, + timer = 0; + + if (etype === 'compositionstart') { + me.pauseValidate = true; + } + if (etype === 'compositionend') { + me.pauseValidate = false; + } + if (me.pauseValidate) { + return; + } + + // For checkbox and radio + elem = el.name && _checkable(el) ? me.$el.find('input[name="'+ el.name +'"]').get(0) : el; + // Get field + if (!(field = me.getField(elem))) { + return; + } + // Cache event type + etype0 = field._e; + field._e = etype; + timely = field.timely; + + if (!special) { + if (!timely || (_checkable(el) && etype !== 'click')) { + return; + } + + value = field.getValue(); + + // not validate field unless fill a value + if ( field.ignoreBlank && !value && !focusin ) { + me.hideMsg(el); + return; + } + + if ( etype === 'focusout' ) { + if (etype0 === 'change') { + return; + } + if ( timely === 2 || timely === 8 ) { + if (value) { + old = field.old; + if (field.isValid && !old.showOk) { + me.hideMsg(el); + } else { + me._makeMsg(el, field, old); + } + } else { + return; + } + } + } + else { + if ( timely < 2 && !e.data ) { + return; + } + + // mark timestamp to reduce the frequency of the received event + timestamp = +new Date(); + if ( timestamp - (el._ts || 0) < 100 ) { + return; + } + el._ts = timestamp; + + // handle keyup + if ( etype === 'keyup' ) { + if (etype0 === 'input') { + return; + } + key = e.keyCode; + specialKey = { + 8: 1, // Backspace + 9: 1, // Tab + 16: 1, // Shift + 32: 1, // Space + 46: 1 // Delete + }; + + // only gets focus, no validation + if ( key === 9 && !value ) { + return; + } + + // do not validate, if triggered by these keys + if ( key < 48 && !specialKey[key] ) { + return; + } + } + if ( !focusin ) { + // keyboard events, reducing the frequency of validation + timer = timely <100 ? (etype === 'click' || el.tagName === 'SELECT') ? 0 : 400 : timely; + } + } + } + + // if the current field is ignored + if ( opt.ignore && $(el).is(opt.ignore) ) { + return; + } + + clearTimeout(field._t); + + if (timer) { + field._t = setTimeout(function() { + me._validate(el, field); + }, timer); + } else { + if (special) field.old = {}; + me._validate(el, field); + } + }, + + _setClass: function(el, isValid) { + var $el = $(el), opt = this.options; + if (opt.bindClassTo) { + $el = $el.closest(opt.bindClassTo); + } + $el.removeClass( opt.invalidClass + ' ' + opt.validClass ); + if (isValid !== null) { + $el.addClass( isValid ? opt.validClass : opt.invalidClass ); + } + }, + + _showmsg: function(e, type, msg) { + var me = this, + el = e.target; + + if ( $(el).is(INPUT_SELECTOR) ) { + me.showMsg(el, {type: type, msg: msg}); + } + else if ( type === 'tip' ) { + me.$el.find(INPUT_SELECTOR +"["+ DATA_TIP +"]", el).each(function(){ + me.showMsg(this, {type: type, msg: msg}); + }); + } + }, + + _hidemsg: function(e) { + var $el = $(e.target); + + if ( $el.is(INPUT_SELECTOR) ) { + this.hideMsg($el); + } + }, + + // Validated a field + _validatedField: function(el, field, ret) { + var me = this, + opt = me.options, + isValid = field.isValid = ret.isValid = !!ret.isValid, + callback = isValid ? 'valid' : 'invalid'; + + ret.key = field.key; + ret.ruleName = field._r; + ret.id = el.id; + ret.value = field.value; + + me.elements[field.key] = ret.element = el; + me.isValid = me.$el[0].isValid = isValid ? me.isFormValid() : isValid; + + if (isValid) { + ret.type = 'ok'; + } else { + if (me.submiting) { + me.errors[field.key] = ret.msg; + } + me.hasError = true; + } + + // cache result + field.old = ret; + + // trigger callback + isFunction(field[callback]) && field[callback].call(me, el, ret); + isFunction(opt.validation) && opt.validation.call(me, el, ret); + + // trigger event + $(el).attr( ARIA_INVALID, isValid ? null : true ) + .trigger( callback + CLS_NS_FIELD, [ret, me] ); + me.$el.triggerHandler('validation', [ret, me]); + + if (me.checkOnly) return; + // set className + me._setClass(el, ret.skip || ret.type === 'tip' ? null : isValid); + me._makeMsg.apply(me, arguments); + }, + + _makeMsg: function(el, field, ret) { + // show or hide the message + if (field.msgMaker) { + ret = $.extend({}, ret); + if (field._e === 'focusin') { + ret.type = 'tip'; + } + this[ ret.showOk || ret.msg || ret.type === 'tip' ? 'showMsg' : 'hideMsg' ](el, ret, field); + } + }, + + // Validated a rule + _validatedRule: function(el, field, ret, msgOpt) { + field = field || me.getField(el); + msgOpt = msgOpt || {}; + + var me = this, + msg, + rule, + method = field._r, + timely = field.timely, + special = timely === 9 || timely === 8, + transfer, + temp, + isValid = false; + + // use null to break validation from a field + if (ret === null) { + me._validatedField(el, field, {isValid: true, skip: true}); + field._i = 0; + return; + } + else if (ret === undefined) { + transfer = true; + } + else if (ret === true || ret === '') { + isValid = true; + } + else if (isString(ret)) { + msg = ret; + } + else if (isObject(ret)) { + if (ret.error) { + msg = ret.error; + } else { + msg = ret.ok; + isValid = true; + } + } + + rule = field._rules[field._i]; + if (rule.not) { + msg = undefined; + isValid = method === "required" || !isValid; + } + if (rule.or) { + if (isValid) { + while ( field._i < field._rules.length && field._rules[field._i].or ) { + field._i++; + } + } else { + transfer = true; + } + } + else if (rule.and) { + if (!field.isValid) transfer = true; + } + + if (transfer) { + isValid = true; + } + // message analysis, and throw rule level event + else { + if (isValid) { + if (field.showOk !== false) { + temp = attr(el, DATA_OK); + msg = temp === null ? isString(field.ok) ? field.ok : msg : temp; + if (!isString(msg) && isString(field.showOk)) { + msg = field.showOk; + } + if (isString(msg)) { + msgOpt.showOk = isValid; + } + } + } + if (!isValid || special) { + /* rule message priority: + 1. custom DOM message + 2. custom field message; + 3. global defined message; + 4. rule returned message; + 5. default message; + */ + msg = (_getDataMsg(el, field, msg || rule.msg || me.messages[method]) || me.messages.fallback).replace(/\{0\|?([^\}]*)\}/, function(m, defaultDisplay){ + return me._getDisplay(el, field.display) || defaultDisplay || me.messages[0]; + }); + } + if (!isValid) field.isValid = isValid; + msgOpt.msg = msg; + $(el).trigger( (isValid ? 'valid' : 'invalid') + CLS_NS_RULE, [method, msg]); + } + + if (special && (!transfer || rule.and)) { + if (!isValid && !field._m) field._m = msg; + field._v = field._v || []; + field._v.push({ + type: isValid ? !transfer ? 'ok' : 'tip' : 'error', + msg: msg || rule.msg + }); + } + + me._debug('log', ' ' + field._i + ': ' + method + ' => ' + (isValid || msg)); + + // the current rule has passed, continue to validate + if ( (isValid || special) && field._i < field._rules.length - 1) { + field._i++; + me._checkRule(el, field); + } + // field was invalid, or all fields was valid + else { + field._i = 0; + + if (special) { + msgOpt.isValid = field.isValid; + msgOpt.result = field._v; + msgOpt.msg = field._m || ''; + if (!field.value && (field._e === 'focusin')) { + msgOpt.type = 'tip'; + } + } else { + msgOpt.isValid = isValid; + } + + me._validatedField(el, field, msgOpt); + delete field._m; + delete field._v; + } + }, + + // Verify a rule form a field + _checkRule: function(el, field) { + var me = this, + ret, + fn, + old, + key = field.key, + rule = field._rules[field._i], + method = rule.method, + params = rule.params; + + // request has been sent, wait it + if (me.submiting && me.deferred[key]) { + return; + } + old = field.old; + field._r = method; + + if (old && !field.must && !rule.must && rule.result !== undefined && + old.ruleName === method && old.id === el.id && + field.value && old.value === field.value ) + { + // get result from cache + ret = rule.result; + } + else { + // get result from current rule + fn = _getDataRule(el, method) || me.rules[method] || noop; + ret = fn.call(field, el, params, field); + if (fn.msg) rule.msg = fn.msg; + } + + // asynchronous validation + if (isObject(ret) && isFunction(ret.then)) { + me.deferred[key] = ret; + + // whether the field valid is unknown + field.isValid = undefined; + + // show loading message + !me.checkOnly && me.showMsg(el, { + type: 'loading', + msg: me.messages.loading + }, field); + + // waiting to parse the response data + ret.then( + function(d, textStatus, jqXHR) { + var data = trim(jqXHR.responseText), + result, + dataFilter = field.dataFilter; + + // detect if data is json or jsonp format + if (/jsonp?/.test(this.dataType)) { + data = d; + } else if (data.charAt(0) === '{') { + data = $.parseJSON(data); + } + + // filter data + result = dataFilter.call(this, data, field); + if (result === undefined) result = dataFilter.call(this, data.data, field); + + rule.data = this.data; + rule.result = field.old ? result : undefined; + me._validatedRule(el, field, result); + }, + function(jqXHR, textStatus){ + me._validatedRule(el, field, me.messages[textStatus] || textStatus); + } + ).always(function(){ + delete me.deferred[key]; + }); + } + // other result + else { + me._validatedRule(el, field, ret); + } + }, + + // Processing the validation + _validate: function(el, field) { + var me = this; + + // doesn't validate the element that has "disabled" or "novalidate" attribute + if ( el.disabled || attr(el, NOVALIDATE) !== null ) { + return; + } + + field = field || me.getField(el); + if (!field) return; + if (!field._rules) me._parse(el); + if (!field._rules) return; + + me._debug('info', field.key); + + field.isValid = true; + field.element = el; + // Cache the value + field.value = field.getValue(); + + // if the field is not required, and that has a blank value + if (!field.required && !field.must && !field.value) { + if (!_checkable(el)) { + me._validatedField(el, field, {isValid: true}); + return true; + } + } + + me._checkRule(el, field); + return field.isValid; + }, + + _debug: function(type, messages) { + if (window.console && this.options.debug) { + console[type](messages); + } + }, + + /** + * Detecting whether the value of an element that matches a rule + * + * @method test + * @param {Element} el - input element + * @param {String} rule - rule name + */ + test: function(el, rule) { + var me = this, + ret, + parts = rRule.exec(rule), + field, + method, + params; + + if (parts) { + method = parts[1]; + if (method in me.rules) { + params = parts[2] || parts[3]; + params = params ? params.split(', ') : undefined; + field = me.getField(el, true); + field._r = method; + field.value = field.getValue(); + ret = me.rules[method].call(field, el, params); + } + } + + return ret === true || ret === undefined || ret === null; + }, + + _getDisplay: function(el, str) { + return !isString(str) ? isFunction(str) ? str.call(this, el) : '' : str; + }, + + _getMsgOpt: function(obj, field) { + var opt = field ? field : this.options; + return $.extend({ + type: 'error', + pos: _getPos(opt.msgClass), + target: opt.target, + wrapper: opt.msgWrapper, + style: opt.msgStyle, + cls: opt.msgClass, + arrow: opt.msgArrow, + icon: opt.msgIcon + }, isString(obj) ? {msg: obj} : obj); + }, + + _getMsgDOM: function(el, msgOpt) { + var $el = $(el), $msgbox, datafor, tgt, container; + + if ( $el.is(INPUT_SELECTOR) ) { + tgt = msgOpt.target || attr(el, DATA_TARGET); + if (tgt) { + tgt = isFunction(tgt) ? tgt.call(this, el) : this.$el.find(tgt); + if (tgt.length) { + if ( tgt.is(INPUT_SELECTOR) ) { + el = tgt.get(0); + } else if ( tgt.hasClass(CLS_MSG_BOX) ) { + $msgbox = tgt; + } else { + container = tgt; + } + } + } + if (!$msgbox) { + datafor = (!_checkable(el) || !el.name) && el.id ? el.id : el.name; + $msgbox = this.$el.find(msgOpt.wrapper + '.' + CLS_MSG_BOX + '[for="' + datafor + '"]'); + } + } else { + $msgbox = $el; + } + + // Create new message box + if (!msgOpt.hide && !$msgbox.length) { + $el = this.$el.find(tgt || el); + + $msgbox = $('<'+ msgOpt.wrapper + '>').attr({ + 'class': CLS_MSG_BOX + (msgOpt.cls ? ' ' + msgOpt.cls : ''), + 'style': msgOpt.style || undefined, + 'for': datafor + }); + + if ( _checkable(el) ) { + var $parent = $el.parent(); + $msgbox.appendTo( $parent.is('label') ? $parent.parent() : $parent ); + } else { + if (container) { + $msgbox.appendTo(container); + } else { + $msgbox[!msgOpt.pos || msgOpt.pos === 'right' ? 'insertAfter' : 'insertBefore']($el); + } + } + } + + return $msgbox; + }, + + /** + * Show validation message + * + * @method showMsg + * @param {Element} el - input element + * @param {Object} msgOpt + */ + showMsg: function(el, msgOpt, /*INTERNAL*/ field) { + if (!el) return; + var me = this, + opt = me.options, + msgShow, + msgMaker, + temp, + $msgbox; + + if (isObject(el) && !el.jquery && !msgOpt) { + $.each(el, function(key, msg) { + var el = me.elements[key] || me.$el.find(_key2selector(key))[0]; + me.showMsg(el, msg); + }); + return; + } + + if ($(el).is(INPUT_SELECTOR)) { + field = field || me.getField(el); + } + + if (!(msgMaker = (field || opt).msgMaker)) { + return; + } + + msgOpt = me._getMsgOpt(msgOpt, field); + el = $(el).get(0); + + // ok or tip + if (!msgOpt.msg && msgOpt.type !== 'error') { + temp = attr(el, 'data-' + msgOpt.type); + if (temp !== null) msgOpt.msg = temp; + } + + if ( !isString(msgOpt.msg) ) { + return; + } + + $msgbox = me._getMsgDOM(el, msgOpt); + + !rPos.test($msgbox[0].className) && $msgbox.addClass(msgOpt.cls); + if ( isIE === 6 && msgOpt.pos === 'bottom' ) { + $msgbox[0].style.marginTop = $(el).outerHeight() + 'px'; + } + $msgbox.html( msgMaker.call(me, msgOpt) )[0].style.display = ''; + + if (isFunction(msgShow = field && field.msgShow || opt.msgShow)) { + msgShow.call(me, $msgbox, msgOpt.type); + } + }, + + /** + * Hide validation message + * + * @method hideMsg + * @param {Element} el - input element + * @param {Object} msgOpt optional + */ + hideMsg: function(el, msgOpt, /*INTERNAL*/ field) { + var me = this, + opt = me.options, + msgHide, + $msgbox; + + el = $(el).get(0); + if ($(el).is(INPUT_SELECTOR)) { + field = field || me.getField(el); + if (field) { + if (field.isValid || me.reseting) attr(el, ARIA_INVALID, null); + } + } + + msgOpt = me._getMsgOpt(msgOpt, field); + msgOpt.hide = true; + + $msgbox = me._getMsgDOM(el, msgOpt); + if (!$msgbox.length) return; + + if ( isFunction(msgHide = field && field.msgHide || opt.msgHide) ) { + msgHide.call(me, $msgbox, msgOpt.type); + } else { + $msgbox[0].style.display = 'none'; + $msgbox[0].innerHTML = null; + } + }, + + /** + * Get field information + * + * @method getField + * @param {Element} - input element + * @return {Object} field + */ + getField: function(el, must) { + var me = this, + key, + field; + + if (isString(el)) { + key = el; + el = undefined; + } else { + if (attr(el, DATA_RULE)) { + return me._parse(el); + } + if (el.id && '#' + el.id in me.fields || !el.name) { + key = '#' + el.id; + } else { + key = el.name; + } + } + + if ( (field = me.fields[key]) || must && (field = new me.Field(key)) ) { + field.element = el; + } + + return field; + }, + + /** + * Config a field + * + * @method: setField + * @param {String} key + * @param {Object} obj + */ + setField: function(key, obj) { + var fields = {}; + + if (!key) return; + + // update this field + if (isString(key)) { + fields[key] = obj; + } + // update fields + else { + fields = key; + } + + this._initFields(fields); + }, + + /** + * Detecting whether the form is valid + * + * @method isFormValid + * @return {Boolean} + */ + isFormValid: function() { + var fields = this.fields, k, field; + for (k in fields) { + field = fields[k]; + if (!field._rules || !field.required && !field.must && !field.value) continue; + if (!field.isValid) return false; + } + return true; + }, + + /** + * Prevent submission form + * + * @method holdSubmit + * @param {Boolean} hold - If set to false, will release the hold + */ + holdSubmit: function(hold) { + this.submiting = hold === undefined || hold; + }, + + /** + * Clean validation messages + * + * @method cleanUp + */ + cleanUp: function() { + this._reset(1); + }, + + /** + * Destroy the validation + * + * @method destroy + */ + destroy: function() { + this._reset(1); + this.$el.off(CLS_NS).removeData(NS); + attr(this.$el[0], NOVALIDATE, this._NOVALIDATE); + } + }; + + /** + * Create Field Factory + * + * @class + * @param {Object} context + * @return {Function} Factory + */ + function _createFieldFactory(context) { + function FieldFactory() { + var options = this.options; + for (var i in options) { + if (i in fieldDefaults) this[i] = options[i]; + } + $.extend(this, { + _valHook: function() { + return this.element.getAttribute('contenteditable') !== null ? 'text' : 'val'; + }, + getValue: function() { + var elem = this.element; + if (elem.type === "number" && elem.validity && elem.validity.badInput) { + return 'NaN'; + } + return $(elem)[this._valHook()](); + }, + setValue: function(value) { + $(this.element)[this._valHook()](this.value = value); + }, + // Get a range of validation messages + getRangeMsg: function(value, params, suffix) { + if (!params) return; + + var me = this, + msg = me.messages[me._r] || '', + result, + p = params[0].split('~'), + e = params[1] === 'false', + a = p[0], + b = p[1], + c = 'rg', + args = [''], + isNumber = trim(value) && +value === +value; + + function compare(large, small) { + return !e ? large >= small : large > small; + } + + if (p.length === 2) { + if (a && b) { + if (isNumber && compare(value, +a) && compare(+b, value)) { + result = true; + } + args = args.concat(p); + c = e ? 'gtlt' : 'rg'; + } + else if (a && !b) { + if (isNumber && compare(value, +a)) { + result = true; + } + args.push(a); + c = e ? 'gt' : 'gte'; + } + else if (!a && b) { + if (isNumber && compare(+b, value)) { + result = true; + } + args.push(b); + c = e ? 'lt' : 'lte'; + } + } + else { + if (value === +a) { + result = true; + } + args.push(a); + c = 'eq'; + } + + if (msg) { + if (suffix && msg[c + suffix]) { + c += suffix; + } + args[0] = msg[c]; + } + + return result || me._rules && ( me._rules[me._i].msg = me.renderMsg.apply(null, args) ); + }, + // Render message template + renderMsg: function() { + var args = arguments, + tpl = args[0], + i = args.length; + + if (!tpl) return; + + while (--i) { + tpl = tpl.replace('{' + i + '}', args[i]); + } + + return tpl; + } + }); + } + function Field(key, obj, oldField) { + this.key = key; + this.validator = context; + $.extend(this, oldField, obj); + } + + FieldFactory.prototype = context; + Field.prototype = new FieldFactory(); + + return Field; + } + + /** + * Create Rules + * + * @class + * @param {Object} obj rules + * @param {Object} context context + */ + function Rules(obj, context) { + if (!isObject(obj)) return; + + var k, that = context ? context === true ? this : context : Rules.prototype; + + for (k in obj) { + if (_checkRuleName(k)) + that[k] = _getRule(obj[k]); + } + } + + /** + * Create Messages + * + * @class + * @param {Object} obj rules + * @param {Object} context context + */ + function Messages(obj, context) { + if (!isObject(obj)) return; + + var k, that = context ? context === true ? this : context : Messages.prototype; + + for (k in obj) { + that[k] = obj[k]; + } + } + + // Rule converted factory + function _getRule(fn) { + switch ($.type(fn)) { + case 'function': + return fn; + case 'array': + var f = function() { + return fn[0].test(this.value) || fn[1] || false; + }; + f.msg = fn[1]; + return f; + case 'regexp': + return function() { + return fn.test(this.value); + }; + } + } + + // Get instance by an element + function _getInstance(el) { + var wrap, k, options; + + if (!el || !el.tagName) return; + + switch (el.tagName) { + case 'INPUT': + case 'SELECT': + case 'TEXTAREA': + case 'BUTTON': + case 'FIELDSET': + wrap = el.form || $(el).closest('.' + CLS_WRAPPER); + break; + case 'FORM': + wrap = el; + break; + default: + wrap = $(el).closest('.' + CLS_WRAPPER); + } + + for (k in preinitialized) { + if ($(wrap).is(k)) { + options = preinitialized[k]; + break; + } + } + + return $(wrap).data(NS) || $(wrap)[NS](options).data(NS); + } + + // Get custom rules on the node + function _getDataRule(el, method) { + var fn = trim(attr(el, DATA_RULE + '-' + method)); + + if ( fn && (fn = new Function("return " + fn)()) ) { + return _getRule(fn); + } + } + + // Get custom messages on the node + function _getDataMsg(el, field, m) { + var msg = field.msg, + item = field._r; + + if ( isObject(msg) ) msg = msg[item]; + if ( !isString(msg) ) { + msg = attr(el, DATA_MSG + '-' + item) || attr(el, DATA_MSG) || ( m ? isString(m) ? m : m[item] : ''); + } + + return msg; + } + + // Get message position + function _getPos(str) { + var pos; + + if (str) pos = rPos.exec(str); + return pos && pos[0]; + } + + // Check whether the element is checkbox or radio + function _checkable(el) { + return el.tagName === 'INPUT' && el.type === 'checkbox' || el.type === 'radio'; + } + + // Parse date string to timestamp + function _parseDate(str) { + return Date.parse(str.replace(/\.|\-/g, '/')); + } + + // Rule name only allows alphanumeric characters and underscores + function _checkRuleName(name) { + return /^\w+$/.test(name); + } + + // Translate field key to jQuery selector. + function _key2selector(key) { + var isID = key.charAt(0) === "#"; + key = key.replace(/([:.{(|)}/\[\]])/g, "\\$1"); + return isID ? key : '[name="'+ key +'"]:first'; + } + + + // Fixed a issue cause by refresh page in IE. + $(window).on('beforeunload', function(){ + this.focus(); + }); + + $(document) + .on('click', ':submit', function(){ + var input = this, attrNode; + if (!input.form) return; + // Shim for "formnovalidate" + attrNode = input.getAttributeNode('formnovalidate'); + if (attrNode && attrNode.nodeValue !== null || attr(input, NOVALIDATE)!== null) { + novalidateonce = true; + } + }) + // Automatic initializing form validation + .on('focusin submit validate', 'form,.'+CLS_WRAPPER, function(e) { + if ( attr(this, NOVALIDATE) !== null ) return; + var $form = $(this), me; + + if ( !$form.data(NS) && (me = _getInstance(this)) ) { + if ( !$.isEmptyObject(me.fields) ) { + // Execute event handler + if (e.type === 'focusin') { + me._focusin(e); + } else { + me._submit(e); + } + } else { + attr(this, NOVALIDATE, NOVALIDATE); + $form.off(CLS_NS).removeData(NS); + } + } + }); + + new Messages({ + fallback: "This field is not valid.", + loading: 'Validating...' + }); + + + // Built-in rules (global) + new Rules({ + + /** + * required + * + * @example: + required + required(anotherRule) + required(not, -1) + required(from, .contact) + */ + required: function(element, params) { + var me = this, + val = trim(me.value), + isValid = true; + + if (params) { + if ( params.length === 1 ) { + if ( !_checkRuleName(params[0]) ) { + if (!val && !$(params[0], me.$el).length ) { + return null; + } + } + else if ( me.rules[params[0]] ) { + if ( !val && !me.test(element, params[0]) ) { + attr(element, ARIA_REQUIRED, null); + return null; + } else { + attr(element, ARIA_REQUIRED, true); + } + } + } + else if ( params[0] === 'not' ) { + $.each(params.slice(1), function() { + return (isValid = val !== trim(this)); + }); + } + else if ( params[0] === 'from' ) { + var $elements = me.$el.find(params[1]), + VALIDATED = '_validated_', + ret; + + isValid = $elements.filter(function(){ + var field = me.getField(this); + return field && !!trim(field.getValue()); + }).length >= (params[2] || 1); + + if (isValid) { + if (!val) ret = null; + } else { + ret = _getDataMsg($elements[0], me) || false; + } + + if ( !$(element).data(VALIDATED) ) { + $elements.data(VALIDATED, 1).each(function(){ + if (element !== this) { + me._validate(this); + } + }).removeData(VALIDATED); + } + + return ret; + } + } + + return isValid && !!val; + }, + + /** + * integer + * + * @example: + integer + integer[+] + integer[+0] + integer[-] + integer[-0] + */ + integer: function(element, params) { + var re, z = '0|', + p = '[1-9]\\d*', + key = params ? params[0] : '*'; + + switch (key) { + case '+': + re = p; + break; + case '-': + re = '-' + p; + break; + case '+0': + re = z + p; + break; + case '-0': + re = z + '-' + p; + break; + default: + re = z + '-?' + p; + } + re = '^(?:' + re + ')$'; + + return new RegExp(re).test(this.value) || this.messages.integer[key]; + }, + + /** + * match another field + * + * @example: + match[password] Match the password field (two values ​​must be the same) + match[eq, password] Ditto + match[neq, count] The value must be not equal to the value of the count field + match[lt, count] The value must be less than the value of the count field + match[lte, count] The value must be less than or equal to the value of the count field + match[gt, count] The value must be greater than the value of the count field + match[gte, count] The value must be greater than or equal to the value of the count field + match[gte, startDate, date] + match[gte, startTime, time] + **/ + match: function(element, params) { + if (!params) return; + + var me = this, + a, b, + key, msg, type = 'eq', parser, + selector2, elem2, field2; + + if (params.length === 1) { + key = params[0]; + } else { + type = params[0]; + key = params[1]; + } + + selector2 = _key2selector(key); + elem2 = me.$el.find(selector2)[0]; + // If the compared field is not exist + if (!elem2) return; + field2 = me.getField(elem2); + a = me.value; + b = field2.getValue(); + + if (!me._match) { + me.$el.on('valid'+CLS_NS_FIELD+CLS_NS, selector2, function(){ + $(element).trigger('validate'); + }); + me._match = field2._match = 1; + } + + // If both fields are blank + if (!me.required && a === "" && b === "") { + return null; + } + + parser = params[2]; + if (parser) { + if (/^date(time)?$/i.test(parser)) { + a = _parseDate(a); + b = _parseDate(b); + } else if (parser === 'time') { + a = +a.replace(/:/g, ''); + b = +b.replace(/:/g, ''); + } + } + + // If the compared field is incorrect, we only ensure that this field is correct. + if (type !== "eq" && !isNaN(+a) && isNaN(+b)) { + return true; + } + + msg = me.messages.match[type].replace( '{1}', me._getDisplay( element, field2.display || key ) ); + + switch (type) { + case 'lt': + return (+a < +b) || msg; + case 'lte': + return (+a <= +b) || msg; + case 'gte': + return (+a >= +b) || msg; + case 'gt': + return (+a > +b) || msg; + case 'neq': + return (a !== b) || msg; + default: + return (a === b) || msg; + } + }, + + /** + * range numbers + * + * @example: + range[0~99] Number 0-99 + range[0~] Number greater than or equal to 0 + range[~100] Number less than or equal to 100 + **/ + range: function(element, params) { + return this.getRangeMsg(this.value, params); + }, + + /** + * how many checkbox or radio inputs that checked + * + * @example: + checked; no empty, same to required + checked[1~3] 1-3 items + checked[1~] greater than 1 item + checked[~3] less than 3 items + checked[3] 3 items + **/ + checked: function(element, params) { + if ( !_checkable(element) ) return; + + var me = this, + elem, count; + + if (element.name) { + count = me.$el.find('input[name="' + element.name + '"]').filter(function() { + var el = this; + if (!elem && _checkable(el)) elem = el; + return !el.disabled && el.checked; + }).length; + } else { + elem = element; + count = elem.checked; + } + + if (params) { + return me.getRangeMsg(count, params); + } else { + return !!count || _getDataMsg(elem, me, '') || me.messages.required; + } + }, + + /** + * length of a characters (You can pass the second parameter "true", will calculate the length in bytes) + * + * @example: + length[6~16] 6-16 characters + length[6~] Greater than 6 characters + length[~16] Less than 16 characters + length[~16, true] Less than 16 characters, non-ASCII characters calculating two-character + **/ + length: function(element, params) { + var value = this.value, + len = (params[1] === 'true' ? value.replace(rDoubleBytes, 'xx') : value).length; + + return this.getRangeMsg(len, params, (params[1] ? '_2' : '')); + }, + + /** + * remote validation + * + * @description + * remote([get:]url [, name1, [name2 ...]]); + * Adaptation three kinds of results (Front for the successful, followed by a failure): + 1. text: + '' 'Error Message' + 2. json: + {"ok": ""} {"error": "Error Message"} + 3. json wrapper: + {"status": 1, "data": {"ok": ""}} {"status": 1, "data": {"error": "Error Message"}} + * @example + The simplest: remote(path/to/server); + With parameters: remote(path/to/server, name1, name2, ...); + By GET: remote(get:path/to/server, name1, name2, ...); + Name proxy: remote(path/to/server, name1, proxyname2:name2, proxyname3:#id3, ...) + Query String remote(path/to/server, foo=1&bar=2, name1, name2, ...) + */ + remote: function(element, params) { + if (!params) return; + + var me = this, + arr = rAjaxType.exec(params[0]), + rule = me._rules[me._i], + data = {}, + queryString = '', + url = arr[3], + type = arr[2] || 'POST', // GET / POST + rType = (arr[1]||'').toLowerCase(), // CORS / JSONP + dataType; + + rule.must = true; + data[element.name] = me.value; + + // There are extra fields + if (params[1]) { + $.map(params.slice(1), function(name) { + var arr, key; + if (~name.indexOf('=')) { + queryString += '&' + name; + } else { + arr = name.split(':'); + name = trim(arr[0]); + key = trim(arr[1]) || name; + data[ name ] = me.$el.find( _key2selector(key) ).val(); + } + }); + } + + data = $.param(data) + queryString; + if (!me.must && rule.data && rule.data === data) { + return rule.result; + } + + // Cross-domain request, force jsonp dataType + if (rType !== 'cors' && /^https?:/.test(url) && !~url.indexOf(location.host)) { + dataType = 'jsonp'; + } + + // Asynchronous validation need return jqXHR objects + return $.ajax({ + url: url, + type: type, + data: data, + dataType: dataType + }); + }, + + /** + * filter characters, direct filtration without prompting error (support custom regular expressions) + * + * @example + * filter filtering unsafe characters + * filter(regexp) filtering the "regexp" matched characters + */ + filter: function(element, params) { + var value = this.value, + temp = value.replace( params ? (new RegExp("[" + params[0] + "]", "gm")) : rUnsafe, '' ); + if (temp !== value) this.setValue(temp); + } + }); + + + /** + * Config global options + * + * @static config + * @param {Object} options + */ + Validator.config = function(key, value) { + if (isObject(key)) { + $.each(key, _config); + } + else if (isString(key)) { + _config(key, value); + } + + function _config(k, o) { + if (k === 'rules') { + new Rules(o); + } + else if (k === 'messages') { + new Messages(o); + } + else if (k in fieldDefaults) { + fieldDefaults[k] = o; + } + else { + defaults[k] = o; + } + } + }; + + /** + * Config themes + * + * @static setTheme + * @param {String|Object} name + * @param {Object} obj + * @example + .setTheme( themeName, themeOptions ) + .setTheme( multiThemes ) + */ + Validator.setTheme = function(name, obj) { + if ( isObject(name) ) { + $.extend(true, themes, name); + } + else if ( isString(name) && isObject(obj) ) { + themes[name] = $.extend(themes[name], obj); + } + }; + + /** + * Resource loader + * + * @static load + * @param {String} str + * @example + .load('local=zh-CN') // load: local/zh-CN.js and jquery.validator.css + .load('local=zh-CN&css=') // load: local/zh-CN.js + .load('local&css') // load: local/en.js (set <html lang="en">) and jquery.validator.css + .load('local') // dito + */ + Validator.load = function(str) { + if (!str) return; + var doc = document, + params = {}, + node = doc.scripts[0], + dir, el, ONLOAD; + + str.replace(/([^?=&]+)=([^&#]*)/g, function(m, key, value){ + params[key] = value; + }); + + dir = params.dir || Validator.dir; + + if (!Validator.css && params.css !== '') { + el = doc.createElement('link'); + el.rel = 'stylesheet'; + el.href = Validator.css = dir + 'jquery.validator.css'; + node.parentNode.insertBefore(el, node); + } + if (!Validator.local && params.local !== '') { + Validator.local = (params.local || doc.documentElement.lang || 'en').replace('_','-'); + Validator.pending = 1; + el = doc.createElement('script'); + el.src = dir + 'local/' + Validator.local + '.js'; + ONLOAD = 'onload' in el ? 'onload' : 'onreadystatechange'; + el[ONLOAD] = function() { + if (!el.readyState || /loaded|complete/.test(el.readyState)) { + el = el[ONLOAD] = null; + delete Validator.pending; + $(window).triggerHandler('validatorready'); + } + }; + node.parentNode.insertBefore(el, node); + } + }; + + // Auto loading resources + (function(){ + var scripts = document.scripts, + i = scripts.length, node, arr, + re = /(.*validator(?:\.min)?.js)(\?.*(?:local|css|dir)(?:=[\w\-]*)?)?/; + + while (i-- && !arr) { + node = scripts[i]; + arr = (node.hasAttribute ? node.src : node.getAttribute('src',4)||'').match(re); + } + + if (!arr) return; + Validator.dir = arr[1].split('/').slice(0, -1).join('/')+'/'; + Validator.load(arr[2]); + })(); + + return $[NS] = Validator; +})); diff --git a/static/plugins/validator/jquery.validator.min.js b/static/plugins/validator/jquery.validator.min.js new file mode 100755 index 0000000..88f069c --- /dev/null +++ b/static/plugins/validator/jquery.validator.min.js @@ -0,0 +1,7 @@ +/*! nice-validator 1.0.4 + * (c) 2012-2016 Jony Zhang <niceue@live.com>, MIT Licensed + * https://github.com/niceue/nice-validator + */ +!function(e){"object"==typeof module&&module.exports?module.exports=e(require("jquery")):"function"==typeof define&&define.amd?require(["jquery"],e):e(jQuery)}(function(e,t){"use strict";function i(t,n){function s(){a._init(a.$el[0],n,!!arguments[0])}var a=this;return a instanceof i?(a.$el=e(t),void(a.$el.length?(s(),i.pending&&e(window).on("validatorready",s)):J(t)&&(G[t]=n))):new i(t,n)}function n(t){function i(){var t=this.options;for(var i in t)i in Y&&(this[i]=t[i]);e.extend(this,{_valHook:function(){return null!==this.element.getAttribute("contenteditable")?"text":"val"},getValue:function(){var t=this.element;return"number"===t.type&&t.validity&&t.validity.badInput?"NaN":e(t)[this._valHook()]()},setValue:function(t){e(this.element)[this._valHook()](this.value=t)},getRangeMsg:function(e,t,i){function n(e,t){return o?e>t:e>=t}if(t){var s,a=this,r=a.messages[a._r]||"",l=t[0].split("~"),o="false"===t[1],u=l[0],d=l[1],c="rg",f=[""],g=U(e)&&+e===+e;return 2===l.length?u&&d?(g&&n(e,+u)&&n(+d,e)&&(s=!0),f=f.concat(l),c=o?"gtlt":"rg"):u&&!d?(g&&n(e,+u)&&(s=!0),f.push(u),c=o?"gt":"gte"):!u&&d&&(g&&n(+d,e)&&(s=!0),f.push(d),c=o?"lt":"lte"):(e===+u&&(s=!0),f.push(u),c="eq"),r&&(i&&r[c+i]&&(c+=i),f[0]=r[c]),s||a._rules&&(a._rules[a._i].msg=a.renderMsg.apply(null,f))}},renderMsg:function(){var e=arguments,t=e[0],i=e.length;if(t){for(;--i;)t=t.replace("{"+i+"}",e[i]);return t}}})}function n(i,n,s){this.key=i,this.validator=t,e.extend(this,s,n)}return i.prototype=t,n.prototype=new i,n}function s(e,t){if(Q(e)){var i,n=t?t===!0?this:t:s.prototype;for(i in e)g(i)&&(n[i]=r(e[i]))}}function a(e,t){if(Q(e)){var i,n=t?t===!0?this:t:a.prototype;for(i in e)n[i]=e[i]}}function r(t){switch(e.type(t)){case"function":return t;case"array":var i=function(){return t[0].test(this.value)||t[1]||!1};return i.msg=t[1],i;case"regexp":return function(){return t.test(this.value)}}}function l(t){var i,n,s;if(t&&t.tagName){switch(t.tagName){case"INPUT":case"SELECT":case"TEXTAREA":case"BUTTON":case"FIELDSET":i=t.form||e(t).closest("."+k);break;case"FORM":i=t;break;default:i=e(t).closest("."+k)}for(n in G)if(e(i).is(n)){s=G[n];break}return e(i).data(h)||e(i)[h](s).data(h)}}function o(e,t){var i=U(z(e,M+"-"+t));if(i&&(i=new Function("return "+i)()))return r(i)}function u(e,t,i){var n=t.msg,s=t._r;return Q(n)&&(n=n[s]),J(n)||(n=z(e,O+"-"+s)||z(e,O)||(i?J(i)?i:i[s]:"")),n}function d(e){var t;return e&&(t=I.exec(e)),t&&t[0]}function c(e){return"INPUT"===e.tagName&&"checkbox"===e.type||"radio"===e.type}function f(e){return Date.parse(e.replace(/\.|\-/g,"/"))}function g(e){return/^\w+$/.test(e)}function m(e){var t="#"===e.charAt(0);return e=e.replace(/([:.{(|)}\/\[\]])/g,"\\$1"),t?e:'[name="'+e+'"]:first'}var p,h="validator",v="."+h,_=".rule",y=".field",b=".form",k="nice-"+h,w="msg-box",x="aria-required",V="aria-invalid",M="data-rule",O="data-msg",F="data-tip",$="data-ok",C="data-timely",E="data-target",A="data-display",j="data-must",T="novalidate",N=":verifiable",S=/(&)?(!)?\b(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\|)?/g,q=/(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/,R=/(?:([^:;\(\[]*):)?(.*)/,D=/[^\x00-\xff]/g,I=/top|right|bottom|left/,H=/(?:(cors|jsonp):)?(?:(post|get):)?(.+)/i,L=/[<>'"`\\]|&#x?\d+[A-F]?;?|%3[A-F]/gim,B=e.noop,P=e.proxy,U=e.trim,W=e.isFunction,J=function(e){return"string"==typeof e},Q=function(e){return e&&"[object Object]"===Object.prototype.toString.call(e)},X=document.documentMode||+(navigator.userAgent.match(/MSIE (\d+)/)&&RegExp.$1),z=function(e,i,n){return e&&e.tagName?n===t?e.getAttribute(i):void(null===n?e.removeAttribute(i):e.setAttribute(i,""+n)):null},G={},K={debug:0,theme:"default",ignore:"",focusInvalid:!0,focusCleanup:!1,stopOnError:!1,beforeSubmit:null,valid:null,invalid:null,validation:null,validClass:"n-valid",invalidClass:"n-invalid",bindClassTo:null},Y={timely:1,display:null,target:null,ignoreBlank:!1,showOk:!0,dataFilter:function(e){if(J(e)||Q(e)&&("error"in e||"ok"in e))return e},msgMaker:function(t){var i;return i='<span role="alert" class="msg-wrap n-'+t.type+'">'+t.arrow,t.result?e.each(t.result,function(e,n){i+='<span class="n-'+n.type+'">'+t.icon+'<span class="n-msg">'+n.msg+"</span></span>"}):i+=t.icon+'<span class="n-msg">'+t.msg+"</span>",i+="</span>"},msgWrapper:"span",msgArrow:"",msgIcon:'<span class="n-icon"></span>',msgClass:"",msgStyle:"",msgShow:null,msgHide:null},Z={default:{formClass:"n-default",msgClass:"n-right"}};return e.fn.validator=function(t){var n=this,s=arguments;return n.is(N)?n:(n.is("form")||(n=this.find("form")),n.length||(n=this),n.each(function(){var n=e(this).data(h);if(n)if(J(t)){if("_"===t.charAt(0))return;n[t].apply(n,[].slice.call(s,1))}else t&&(n._reset(!0),n._init(this,t));else new i(this,t)}),this)},e.fn.isValid=function(e,i){var n,s,a=l(this[0]),r=W(e);return!a||(r||i!==t||(i=e),a.checkOnly=!!i,s=a.options,n=a._multiValidate(this.is(N)?this:this.find(N),function(t){t||!s.focusInvalid||a.checkOnly||a.$el.find("["+V+"]:first").focus(),r&&(e.length?e(t):t&&e()),a.checkOnly=!1}),r?this:n)},e.expr.pseudos.verifiable=function(e){var t=e.nodeName.toLowerCase();return("input"===t&&!{submit:1,button:1,reset:1,image:1}[e.type]||"select"===t||"textarea"===t||"true"===e.contentEditable)&&!e.disabled},e.expr.pseudos.filled=function(t){return!!U(e(t).val())},i.prototype={_init:function(t,i,r){var l,o,u,d=this;W(i)&&(i={valid:i}),i=d._opt=i||{},u=z(t,"data-"+h+"-option"),u=d._dataOpt=u&&"{"===u.charAt(0)?new Function("return "+u)():{},o=d._themeOpt=Z[i.theme||u.theme||K.theme],l=d.options=e.extend({},K,Y,o,d.options,i,u),r||(d.rules=new s(l.rules,(!0)),d.messages=new a(l.messages,(!0)),d.Field=n(d),d.elements=d.elements||{},d.deferred={},d.errors={},d.fields={},d._initFields(l.fields)),d.$el.data(h)||(d.$el.data(h,d).addClass(k+" "+l.formClass).on("form-submit-validate",function(e,t,i,n,s){d.vetoed=s.veto=!d.isValid,d.ajaxFormOptions=n}).on("submit"+v+" validate"+v,P(d,"_submit")).on("reset"+v,P(d,"_reset")).on("showmsg"+v,P(d,"_showmsg")).on("hidemsg"+v,P(d,"_hidemsg")).on("focusin"+v+" click"+v,N,P(d,"_focusin")).on("focusout"+v+" validate"+v,N,P(d,"_focusout")).on("keyup"+v+" input"+v+" compositionstart compositionend",N,P(d,"_focusout")).on("click"+v,":radio,:checkbox","click",P(d,"_focusout")).on("change"+v,'select,input[type="file"]',"change",P(d,"_focusout")),d._NOVALIDATE=z(t,T),z(t,T,T)),J(l.target)&&d.$el.find(l.target).addClass("msg-container")},_guessAjax:function(t){function i(t,i,n){return!!(t&&t[i]&&e.map(t[i],function(e){return~e.namespace.indexOf(n)?1:null}).length)}var n=this;if(!(n.isAjaxSubmit=!!n.options.valid)){var s=(e._data||e.data)(t,"events");n.isAjaxSubmit=i(s,"valid","form")||i(s,"submit","form-plugin")}},_initFields:function(e){function t(e,t){if(null===t||r){var i=a.elements[e];i&&a._resetElement(i,!0),delete a.fields[e]}else a.fields[e]=new a.Field(e,J(t)?{rule:t}:t,a.fields[e])}var i,n,s,a=this,r=null===e;if(r&&(e=a.fields),Q(e))for(i in e)if(~i.indexOf(","))for(n=i.split(","),s=n.length;s--;)t(U(n[s]),e[i]);else t(i,e[i]);a.$el.find(N).each(function(){a._parse(this)})},_parse:function(e){var t,i,n,s=this,a=e.name,r=z(e,M);if(r&&z(e,M,null),e.id&&("#"+e.id in s.fields||!a||null!==r&&(t=s.fields[a])&&r!==t.rule&&e.id!==t.key)&&(a="#"+e.id),a)return t=s.getField(a,!0),t.rule=r||t.rule,(i=z(e,A))&&(t.display=i),t.rule&&((null!==z(e,j)||/\b(?:match|checked)\b/.test(t.rule))&&(t.must=!0),/\brequired\b/.test(t.rule)&&(t.required=!0,z(e,x,!0)),(n=z(e,C))?t.timely=+n:t.timely>3&&z(e,C,t.timely),s._parseRule(t),t.old={}),J(t.target)&&z(e,E,t.target),J(t.tip)&&z(e,F,t.tip),s.fields[a]=t},_parseRule:function(i){var n=R.exec(i.rule);n&&(i._i=0,n[1]&&(i.display=n[1]),n[2]&&(i._rules=[],n[2].replace(S,function(){var n=arguments;n[4]=n[4]||n[5],i._rules.push({and:"&"===n[1],not:"!"===n[2],or:"|"===n[6],method:n[3],params:n[4]?e.map(n[4].split(", "),U):t})})))},_multiValidate:function(i,n){var s=this,a=s.options;return s.hasError=!1,a.ignore&&(i=i.not(a.ignore)),i.each(function(){if(s._validate(this),s.hasError&&a.stopOnError)return!1}),n&&(s.validating=!0,e.when.apply(null,e.map(s.deferred,function(e){return e})).done(function(){n.call(s,!s.hasError),s.validating=!1})),e.isEmptyObject(s.deferred)?!s.hasError:t},_submit:function(i){var n=this,s=n.options,a=i.target,r="submit"===i.type&&!i.isDefaultPrevented();i.preventDefault(),p&&~(p=!1)||n.submiting||"validate"===i.type&&n.$el[0]!==a||W(s.beforeSubmit)&&s.beforeSubmit.call(n,a)===!1||(n.isAjaxSubmit===t&&n._guessAjax(a),n._debug("log","\n<<< event: "+i.type),n._reset(),n.submiting=!0,n._multiValidate(n.$el.find(N),function(t){var i,l=t||2===s.debug?"valid":"invalid";t||(s.focusInvalid&&n.$el.find("["+V+"]:first").focus(),i=e.map(n.errors,function(e){return e})),n.submiting=!1,n.isValid=t,W(s[l])&&s[l].call(n,a,i),n.$el.trigger(l+b,[a,i]),n._debug("log",">>> "+l),t&&(n.vetoed?e(a).ajaxSubmit(n.ajaxFormOptions):r&&!n.isAjaxSubmit&&document.createElement("form").submit.call(a))}))},_reset:function(e){var t=this;t.errors={},e&&(t.reseting=!0,t.$el.find(N).each(function(){t._resetElement(this)}),delete t.reseting)},_resetElement:function(e,t){this._setClass(e,null),this.hideMsg(e),t&&z(e,x,null)},_focusin:function(e){var t,i,n=this,s=n.options,a=e.target;n.validating||"click"===e.type&&document.activeElement===a||(s.focusCleanup&&"true"===z(a,V)&&(n._setClass(a,null),n.hideMsg(a)),i=z(a,F),i?n.showMsg(a,{type:"tip",msg:i}):(z(a,M)&&n._parse(a),(t=z(a,C))&&(8!==t&&9!==t||n._focusout(e))))},_focusout:function(t){var i,n,s,a,r,l,o,u,d,f=this,g=f.options,m=t.target,p=t.type,h="focusin"===p,v="validate"===p,_=0;if("compositionstart"===p&&(f.pauseValidate=!0),"compositionend"===p&&(f.pauseValidate=!1),!f.pauseValidate&&(n=m.name&&c(m)?f.$el.find('input[name="'+m.name+'"]').get(0):m,s=f.getField(n))){if(i=s._e,s._e=p,d=s.timely,!v){if(!d||c(m)&&"click"!==p)return;if(r=s.getValue(),s.ignoreBlank&&!r&&!h)return void f.hideMsg(m);if("focusout"===p){if("change"===i)return;if(2===d||8===d){if(!r)return;a=s.old,s.isValid&&!a.showOk?f.hideMsg(m):f._makeMsg(m,s,a)}}else{if(d<2&&!t.data)return;if(l=+new Date,l-(m._ts||0)<100)return;if(m._ts=l,"keyup"===p){if("input"===i)return;if(o=t.keyCode,u={8:1,9:1,16:1,32:1,46:1},9===o&&!r)return;if(o<48&&!u[o])return}h||(_=d<100?"click"===p||"SELECT"===m.tagName?0:400:d)}}g.ignore&&e(m).is(g.ignore)||(clearTimeout(s._t),_?s._t=setTimeout(function(){f._validate(m,s)},_):(v&&(s.old={}),f._validate(m,s)))}},_setClass:function(t,i){var n=e(t),s=this.options;s.bindClassTo&&(n=n.closest(s.bindClassTo)),n.removeClass(s.invalidClass+" "+s.validClass),null!==i&&n.addClass(i?s.validClass:s.invalidClass)},_showmsg:function(t,i,n){var s=this,a=t.target;e(a).is(N)?s.showMsg(a,{type:i,msg:n}):"tip"===i&&s.$el.find(N+"["+F+"]",a).each(function(){s.showMsg(this,{type:i,msg:n})})},_hidemsg:function(t){var i=e(t.target);i.is(N)&&this.hideMsg(i)},_validatedField:function(t,i,n){var s=this,a=s.options,r=i.isValid=n.isValid=!!n.isValid,l=r?"valid":"invalid";n.key=i.key,n.ruleName=i._r,n.id=t.id,n.value=i.value,s.elements[i.key]=n.element=t,s.isValid=s.$el[0].isValid=r?s.isFormValid():r,r?n.type="ok":(s.submiting&&(s.errors[i.key]=n.msg),s.hasError=!0),i.old=n,W(i[l])&&i[l].call(s,t,n),W(a.validation)&&a.validation.call(s,t,n),e(t).attr(V,!r||null).trigger(l+y,[n,s]),s.$el.triggerHandler("validation",[n,s]),s.checkOnly||(s._setClass(t,n.skip||"tip"===n.type?null:r),s._makeMsg.apply(s,arguments))},_makeMsg:function(t,i,n){i.msgMaker&&(n=e.extend({},n),"focusin"===i._e&&(n.type="tip"),this[n.showOk||n.msg||"tip"===n.type?"showMsg":"hideMsg"](t,n,i))},_validatedRule:function(i,n,s,a){n=n||c.getField(i),a=a||{};var r,l,o,d,c=this,f=n._r,g=n.timely,m=9===g||8===g,p=!1;if(null===s)return c._validatedField(i,n,{isValid:!0,skip:!0}),void(n._i=0);if(s===t?o=!0:s===!0||""===s?p=!0:J(s)?r=s:Q(s)&&(s.error?r=s.error:(r=s.ok,p=!0)),l=n._rules[n._i],l.not&&(r=t,p="required"===f||!p),l.or)if(p)for(;n._i<n._rules.length&&n._rules[n._i].or;)n._i++;else o=!0;else l.and&&(n.isValid||(o=!0));o?p=!0:(p&&n.showOk!==!1&&(d=z(i,$),r=null===d?J(n.ok)?n.ok:r:d,!J(r)&&J(n.showOk)&&(r=n.showOk),J(r)&&(a.showOk=p)),p&&!m||(r=(u(i,n,r||l.msg||c.messages[f])||c.messages.fallback).replace(/\{0\|?([^\}]*)\}/,function(e,t){return c._getDisplay(i,n.display)||t||c.messages[0]})),p||(n.isValid=p),a.msg=r,e(i).trigger((p?"valid":"invalid")+_,[f,r])),!m||o&&!l.and||(p||n._m||(n._m=r),n._v=n._v||[],n._v.push({type:p?o?"tip":"ok":"error",msg:r||l.msg})),c._debug("log"," "+n._i+": "+f+" => "+(p||r)),(p||m)&&n._i<n._rules.length-1?(n._i++,c._checkRule(i,n)):(n._i=0,m?(a.isValid=n.isValid,a.result=n._v,a.msg=n._m||"",n.value||"focusin"!==n._e||(a.type="tip")):a.isValid=p,c._validatedField(i,n,a),delete n._m,delete n._v)},_checkRule:function(i,n){var s,a,r,l=this,u=n.key,d=n._rules[n._i],c=d.method,f=d.params;l.submiting&&l.deferred[u]||(r=n.old,n._r=c,r&&!n.must&&!d.must&&d.result!==t&&r.ruleName===c&&r.id===i.id&&n.value&&r.value===n.value?s=d.result:(a=o(i,c)||l.rules[c]||B,s=a.call(n,i,f,n),a.msg&&(d.msg=a.msg)),Q(s)&&W(s.then)?(l.deferred[u]=s,n.isValid=t,!l.checkOnly&&l.showMsg(i,{type:"loading",msg:l.messages.loading},n),s.then(function(s,a,r){var o,u=U(r.responseText),c=n.dataFilter;/jsonp?/.test(this.dataType)?u=s:"{"===u.charAt(0)&&(u=e.parseJSON(u)),o=c.call(this,u,n),o===t&&(o=c.call(this,u.data,n)),d.data=this.data,d.result=n.old?o:t,l._validatedRule(i,n,o)},function(e,t){l._validatedRule(i,n,l.messages[t]||t)}).always(function(){delete l.deferred[u]})):l._validatedRule(i,n,s))},_validate:function(e,t){var i=this;if(!e.disabled&&null===z(e,T)&&(t=t||i.getField(e),t&&(t._rules||i._parse(e),t._rules)))return i._debug("info",t.key),t.isValid=!0,t.element=e,t.value=t.getValue(),t.required||t.must||t.value||c(e)?(i._checkRule(e,t),t.isValid):(i._validatedField(e,t,{isValid:!0}),!0)},_debug:function(e,t){window.console&&this.options.debug&&console[e](t)},test:function(e,i){var n,s,a,r,l=this,o=q.exec(i);return o&&(a=o[1],a in l.rules&&(r=o[2]||o[3],r=r?r.split(", "):t,s=l.getField(e,!0),s._r=a,s.value=s.getValue(),n=l.rules[a].call(s,e,r))),n===!0||n===t||null===n},_getDisplay:function(e,t){return J(t)?t:W(t)?t.call(this,e):""},_getMsgOpt:function(t,i){var n=i?i:this.options;return e.extend({type:"error",pos:d(n.msgClass),target:n.target,wrapper:n.msgWrapper,style:n.msgStyle,cls:n.msgClass,arrow:n.msgArrow,icon:n.msgIcon},J(t)?{msg:t}:t)},_getMsgDOM:function(i,n){var s,a,r,l,o=e(i);if(o.is(N)?(r=n.target||z(i,E),r&&(r=W(r)?r.call(this,i):this.$el.find(r),r.length&&(r.is(N)?i=r.get(0):r.hasClass(w)?s=r:l=r)),s||(a=c(i)&&i.name||!i.id?i.name:i.id,s=this.$el.find(n.wrapper+"."+w+'[for="'+a+'"]'))):s=o,!n.hide&&!s.length)if(o=this.$el.find(r||i),s=e("<"+n.wrapper+">").attr({class:w+(n.cls?" "+n.cls:""),style:n.style||t,for:a}),c(i)){var u=o.parent();s.appendTo(u.is("label")?u.parent():u)}else l?s.appendTo(l):s[n.pos&&"right"!==n.pos?"insertBefore":"insertAfter"](o);return s},showMsg:function(t,i,n){if(t){var s,a,r,l,o=this,u=o.options;if(Q(t)&&!t.jquery&&!i)return void e.each(t,function(e,t){var i=o.elements[e]||o.$el.find(m(e))[0];o.showMsg(i,t)});e(t).is(N)&&(n=n||o.getField(t)),(a=(n||u).msgMaker)&&(i=o._getMsgOpt(i,n),t=e(t).get(0),i.msg||"error"===i.type||(r=z(t,"data-"+i.type),null!==r&&(i.msg=r)),J(i.msg)&&(l=o._getMsgDOM(t,i),!I.test(l[0].className)&&l.addClass(i.cls),6===X&&"bottom"===i.pos&&(l[0].style.marginTop=e(t).outerHeight()+"px"),l.html(a.call(o,i))[0].style.display="",W(s=n&&n.msgShow||u.msgShow)&&s.call(o,l,i.type)))}},hideMsg:function(t,i,n){var s,a,r=this,l=r.options;t=e(t).get(0),e(t).is(N)&&(n=n||r.getField(t),n&&(n.isValid||r.reseting)&&z(t,V,null)),i=r._getMsgOpt(i,n),i.hide=!0,a=r._getMsgDOM(t,i),a.length&&(W(s=n&&n.msgHide||l.msgHide)?s.call(r,a,i.type):(a[0].style.display="none",a[0].innerHTML=null))},getField:function(e,i){var n,s,a=this;if(J(e))n=e,e=t;else{if(z(e,M))return a._parse(e);n=e.id&&"#"+e.id in a.fields||!e.name?"#"+e.id:e.name}return((s=a.fields[n])||i&&(s=new a.Field(n)))&&(s.element=e),s},setField:function(e,t){var i={};e&&(J(e)?i[e]=t:i=e,this._initFields(i))},isFormValid:function(){var e,t,i=this.fields;for(e in i)if(t=i[e],t._rules&&(t.required||t.must||t.value)&&!t.isValid)return!1;return!0},holdSubmit:function(e){this.submiting=e===t||e},cleanUp:function(){this._reset(1)},destroy:function(){this._reset(1),this.$el.off(v).removeData(h),z(this.$el[0],T,this._NOVALIDATE)}},e(window).on("beforeunload",function(){this.focus()}),e(document).on("click",":submit",function(){var e,t=this;t.form&&(e=t.getAttributeNode("formnovalidate"),(e&&null!==e.nodeValue||null!==z(t,T))&&(p=!0))}).on("focusin submit validate","form,."+k,function(t){if(null===z(this,T)){var i,n=e(this);!n.data(h)&&(i=l(this))&&(e.isEmptyObject(i.fields)?(z(this,T,T),n.off(v).removeData(h)):"focusin"===t.type?i._focusin(t):i._submit(t))}}),new a({fallback:"This field is not valid.",loading:"Validating..."}),new s({required:function(t,i){var n=this,s=U(n.value),a=!0;if(i)if(1===i.length){if(g(i[0])){if(n.rules[i[0]]){if(!s&&!n.test(t,i[0]))return z(t,x,null),null;z(t,x,!0)}}else if(!s&&!e(i[0],n.$el).length)return null}else if("not"===i[0])e.each(i.slice(1),function(){return a=s!==U(this)});else if("from"===i[0]){var r,l=n.$el.find(i[1]),o="_validated_";return a=l.filter(function(){var e=n.getField(this);return e&&!!U(e.getValue())}).length>=(i[2]||1),a?s||(r=null):r=u(l[0],n)||!1,e(t).data(o)||l.data(o,1).each(function(){t!==this&&n._validate(this)}).removeData(o),r}return a&&!!s},integer:function(e,t){var i,n="0|",s="[1-9]\\d*",a=t?t[0]:"*";switch(a){case"+":i=s;break;case"-":i="-"+s;break;case"+0":i=n+s;break;case"-0":i=n+"-"+s;break;default:i=n+"-?"+s}return i="^(?:"+i+")$",new RegExp(i).test(this.value)||this.messages.integer[a]},match:function(t,i){if(i){var n,s,a,r,l,o,u,d,c=this,g="eq";if(1===i.length?a=i[0]:(g=i[0],a=i[1]),o=m(a),u=c.$el.find(o)[0]){if(d=c.getField(u),n=c.value,s=d.getValue(),c._match||(c.$el.on("valid"+y+v,o,function(){e(t).trigger("validate")}),c._match=d._match=1),!c.required&&""===n&&""===s)return null;if(l=i[2],l&&(/^date(time)?$/i.test(l)?(n=f(n),s=f(s)):"time"===l&&(n=+n.replace(/:/g,""),s=+s.replace(/:/g,""))),"eq"!==g&&!isNaN(+n)&&isNaN(+s))return!0;switch(r=c.messages.match[g].replace("{1}",c._getDisplay(t,d.display||a)),g){case"lt":return+n<+s||r;case"lte":return+n<=+s||r;case"gte":return+n>=+s||r;case"gt":return+n>+s||r;case"neq":return n!==s||r;default:return n===s||r}}}},range:function(e,t){return this.getRangeMsg(this.value,t)},checked:function(e,t){if(c(e)){var i,n,s=this;return e.name?n=s.$el.find('input[name="'+e.name+'"]').filter(function(){var e=this;return!i&&c(e)&&(i=e),!e.disabled&&e.checked}).length:(i=e,n=i.checked),t?s.getRangeMsg(n,t):!!n||u(i,s,"")||s.messages.required}},length:function(e,t){var i=this.value,n=("true"===t[1]?i.replace(D,"xx"):i).length;return this.getRangeMsg(n,t,t[1]?"_2":"")},remote:function(t,i){if(i){var n,s=this,a=H.exec(i[0]),r=s._rules[s._i],l={},o="",u=a[3],d=a[2]||"POST",c=(a[1]||"").toLowerCase();return r.must=!0,l[t.name]=s.value,i[1]&&e.map(i.slice(1),function(e){var t,i;~e.indexOf("=")?o+="&"+e:(t=e.split(":"),e=U(t[0]),i=U(t[1])||e,l[e]=s.$el.find(m(i)).val())}),l=e.param(l)+o,!s.must&&r.data&&r.data===l?r.result:("cors"!==c&&/^https?:/.test(u)&&!~u.indexOf(location.host)&&(n="jsonp"),e.ajax({url:u,type:d,data:l,dataType:n}))}},filter:function(e,t){var i=this.value,n=i.replace(t?new RegExp("["+t[0]+"]","gm"):L,"");n!==i&&this.setValue(n)}}),i.config=function(t,i){function n(e,t){"rules"===e?new s(t):"messages"===e?new a(t):e in Y?Y[e]=t:K[e]=t}Q(t)?e.each(t,n):J(t)&&n(t,i)},i.setTheme=function(t,i){Q(t)?e.extend(!0,Z,t):J(t)&&Q(i)&&(Z[t]=e.extend(Z[t],i))},i.load=function(t){if(t){var n,s,a,r=document,l={},o=r.scripts[0];t.replace(/([^?=&]+)=([^&#]*)/g,function(e,t,i){l[t]=i}),n=l.dir||i.dir,i.css||""===l.css||(s=r.createElement("link"),s.rel="stylesheet",s.href=i.css=n+"jquery.validator.css",o.parentNode.insertBefore(s,o)),i.local||""===l.local||(i.local=(l.local||r.documentElement.lang||"en").replace("_","-"),i.pending=1,s=r.createElement("script"),s.src=n+"local/"+i.local+".js",a="onload"in s?"onload":"onreadystatechange",s[a]=function(){s.readyState&&!/loaded|complete/.test(s.readyState)||(s=s[a]=null,delete i.pending,e(window).triggerHandler("validatorready"))},o.parentNode.insertBefore(s,o))}},function(){for(var e,t,n=document.scripts,s=n.length,a=/(.*validator(?:\.min)?.js)(\?.*(?:local|css|dir)(?:=[\w\-]*)?)?/;s--&&!t;)e=n[s],t=(e.hasAttribute?e.src:e.getAttribute("src",4)||"").match(a);t&&(i.dir=t[1].split("/").slice(0,-1).join("/")+"/",i.load(t[2]))}(),e[h]=i}); + +(function(factory){typeof module==="object"&&module.exports?module.exports=factory(require("jquery")):typeof define==="function"&&define.amd?require(["jquery"],factory):factory(jQuery)}(function($){$.validator.config({rules:{digits:[/^\d+$/,"请填写数字"],letters:[/^[a-z]+$/i,"请填写字母"],date:[/^\d{4}-\d{2}-\d{2}$/,"请填写有效的日期,格式:yyyy-mm-dd"],time:[/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/,"请填写有效的时间,00:00到23:59之间"],email:[/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i,"请填写有效的邮箱"],url:[/^(https?|s?ftp):\/\/\S+$/i,"请填写有效的网址"],qq:[/^[1-9]\d{4,}$/,"请填写有效的QQ号"],IDcard:[/^\d{6}(19|2\d)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/,"请填写正确的身份证号码"],tel:[/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/,"请填写有效的电话号码"],mobile:[/^1[3-9]\d{9}$/,"请填写有效的手机号"],zipcode:[/^\d{6}$/,"请检查邮政编码格式"],chinese:[/^[\u0391-\uFFE5]+$/,"请填写中文字符"],username:[/^\w{3,12}$/,"请填写3-12位数字、字母、下划线"],password:[/^[\S]{6,16}$/,"请填写6-16位字符,不能包含空格"],accept:function(element,params){if(!params){return true}var ext=params[0],value=$(element).val();return(ext==="*")||(new RegExp(".(?:"+ext+")$","i")).test(value)||this.renderMsg("只接受{1}后缀的文件",ext.replace(/\|/g,","))}},messages:{0:"此处",fallback:"{0}格式不正确",loading:"正在验证...",error:"网络异常",timeout:"请求超时",required:"{0}不能为空",remote:"{0}已被使用",integer:{"*":"请填写整数","+":"请填写正整数","+0":"请填写正整数或0","-":"请填写负整数","-0":"请填写负整数或0"},match:{eq:"{0}与{1}不一致",neq:"{0}与{1}不能相同",lt:"{0}必须小于{1}",gt:"{0}必须大于{1}",lte:"{0}不能大于{1}",gte:"{0}不能小于{1}"},range:{rg:"请填写{1}到{2}的数",gte:"请填写不小于{1}的数",lte:"请填写最大{1}的数",gtlt:"请填写{1}到{2}之间的数",gt:"请填写大于{1}的数",lt:"请填写小于{1}的数"},checked:{eq:"请选择{1}项",rg:"请选择{1}到{2}项",gte:"请至少选择{1}项",lte:"请最多选择{1}项"},length:{eq:"请填写{1}个字符",rg:"请填写{1}到{2}个字符",gte:"请至少填写{1}个字符",lte:"请最多填写{1}个字符",eq_2:"",rg_2:"",gte_2:"",lte_2:""}}});var TPL_ARROW='<span class="n-arrow"><b>◆</b><i>◆</i></span>';$.validator.setTheme({"simple_right":{formClass:"n-simple",msgClass:"n-right"},"simple_bottom":{formClass:"n-simple",msgClass:"n-bottom"},"yellow_top":{formClass:"n-yellow",msgClass:"n-top",msgArrow:TPL_ARROW},"yellow_right":{formClass:"n-yellow",msgClass:"n-right",msgArrow:TPL_ARROW},"yellow_right_effect":{formClass:"n-yellow",msgClass:"n-right",msgArrow:TPL_ARROW,msgShow:function($msgbox,type){var $el=$msgbox.children();if($el.is(":animated")){return}if(type==="error"){$el.css({left:"20px",opacity:0}).delay(100).show().stop().animate({left:"-4px",opacity:1},150).animate({left:"3px"},80).animate({left:0},80)}else{$el.css({left:0,opacity:1}).fadeIn(200)}},msgHide:function($msgbox,type){var $el=$msgbox.children();$el.stop().delay(100).show().animate({left:"20px",opacity:0},300,function(){$msgbox.hide()})}}})})); diff --git a/static/plugins/validator/local/en.js b/static/plugins/validator/local/en.js new file mode 100755 index 0000000..05bfbf0 --- /dev/null +++ b/static/plugins/validator/local/en.js @@ -0,0 +1,137 @@ +/********************************* + * Themes, rules, and i18n support + * Locale: English + *********************************/ +(function(factory) { + typeof module === "object" && module.exports ? module.exports = factory( require( "jquery" ) ) : + typeof define === 'function' && define.amd ? require(['jquery'], factory) : + factory(jQuery); +}(function($) { + + /* Global configuration + */ + $.validator.config({ + //stopOnError: true, + //focusCleanup: true, + //theme: 'yellow_right', + //timely: 2, + + // Custom rules + rules: { + digits: [/^\d+$/, "Please enter only digits."] + ,letters: [/^[a-z]+$/i, "Please enter only letters."] + ,date: [/^\d{4}-\d{2}-\d{2}$/, "Please enter a valid date, format: yyyy-mm-dd"] + ,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "Please enter a valid time, between 00:00 and 23:59"] + ,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "Please enter a valid email address."] + ,url: [/^(https?|s?ftp):\/\/\S+$/i, "Please enter a valid URL."] + ,accept: function (element, params){ + if (!params) return true; + var ext = params[0], + value = $(element).val(); + return (ext === '*') || + (new RegExp(".(?:" + ext + ")$", "i")).test(value) || + this.renderMsg("Only accept {1} file extension.", ext.replace(/\|/g, ', ')); + } + + }, + + // Default error messages + messages: { + 0: "This field", + fallback: "{0} is not valid.", + loading: "Validating...", + error: "Network Error.", + timeout: "Request timed out.", + required: "{0} is required.", + remote: "Please try another name.", + integer: { + '*': "Please enter an integer.", + '+': "Please enter a positive integer.", + '+0': "Please enter a positive integer or 0.", + '-': "Please enter a negative integer.", + '-0': "Please enter a negative integer or 0." + }, + match: { + eq: "{0} must be equal to {1}.", + neq: "{0} must be not equal to {1}.", + lt: "{0} must be less than {1}.", + gt: "{0} must be greater than {1}.", + lte: "{0} must be less than or equal to {1}.", + gte: "{0} must be greater than or equal to {1}." + }, + range: { + rg: "Please enter a number between {1} and {2}.", + gte: "Please enter a number greater than or equal to {1}.", + lte: "Please enter a number less than or equal to {1}.", + gtlt: "Please fill in the number of {1} to {2}.", + gt: "Please enter a number greater than {1}.", + lt: "Please enter a number less than {1}." + }, + checked: { + eq: "Please check {1} items.", + rg: "Please check between {1} and {2} items.", + gte: "Please check at least {1} items.", + lte: "Please check no more than {1} items." + }, + length: { + eq: "Please enter {1} characters.", + rg: "Please enter a value between {1} and {2} characters long.", + gte: "Please enter at least {1} characters.", + lte: "Please enter no more than {1} characters.", + eq_2: "", + rg_2: "", + gte_2: "", + lte_2: "" + } + } + }); + + /* Themes + */ + var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>'; + $.validator.setTheme({ + 'simple_right': { + formClass: 'n-simple', + msgClass: 'n-right' + }, + 'simple_bottom': { + formClass: 'n-simple', + msgClass: 'n-bottom' + }, + 'yellow_top': { + formClass: 'n-yellow', + msgClass: 'n-top', + msgArrow: TPL_ARROW + }, + 'yellow_right': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW + }, + 'yellow_right_effect': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW, + msgShow: function($msgbox, type){ + var $el = $msgbox.children(); + if ($el.is(':animated')) return; + if (type === 'error') { + $el.css({left: '20px', opacity: 0}) + .delay(100).show().stop() + .animate({left: '-4px', opacity: 1}, 150) + .animate({left: '3px'}, 80) + .animate({left: 0}, 80); + } else { + $el.css({left: 0, opacity: 1}).fadeIn(200); + } + }, + msgHide: function($msgbox, type){ + var $el = $msgbox.children(); + $el.stop().delay(100).show() + .animate({left: '20px', opacity: 0}, 300, function(){ + $msgbox.hide(); + }); + } + } + }); +})); diff --git a/static/plugins/validator/local/zh-CN.js b/static/plugins/validator/local/zh-CN.js new file mode 100755 index 0000000..3cb5e66 --- /dev/null +++ b/static/plugins/validator/local/zh-CN.js @@ -0,0 +1,145 @@ +/********************************* + * Themes, rules, and i18n support + * Locale: Chinese; 中文 + *********************************/ +(function(factory) { + typeof module === "object" && module.exports ? module.exports = factory( require( "jquery" ) ) : + typeof define === 'function' && define.amd ? require(['jquery'], factory) : + factory(jQuery); +}(function($) { + + /* Global configuration + */ + $.validator.config({ + //stopOnError: true, + //focusCleanup: true, + //theme: 'yellow_right', + //timely: 2, + + // Custom rules + rules: { + digits: [/^\d+$/, "请填写数字"] + ,letters: [/^[a-z]+$/i, "请填写字母"] + ,date: [/^\d{4}-\d{2}-\d{2}$/, "请填写有效的日期,格式:yyyy-mm-dd"] + ,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "请填写有效的时间,00:00到23:59之间"] + ,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "请填写有效的邮箱"] + ,url: [/^(https?|s?ftp):\/\/\S+$/i, "请填写有效的网址"] + ,qq: [/^[1-9]\d{4,}$/, "请填写有效的QQ号"] + ,IDcard: [/^\d{6}(19|2\d)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/, "请填写正确的身份证号码"] + ,tel: [/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/, "请填写有效的电话号码"] + ,mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"] + ,zipcode: [/^\d{6}$/, "请检查邮政编码格式"] + ,chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"] + ,username: [/^\w{3,12}$/, "请填写3-12位数字、字母、下划线"] + ,password: [/^[\S]{6,16}$/, "请填写6-16位字符,不能包含空格"] + ,accept: function (element, params){ + if (!params) return true; + var ext = params[0], + value = $(element).val(); + return (ext === '*') || + (new RegExp(".(?:" + ext + ")$", "i")).test(value) || + this.renderMsg("只接受{1}后缀的文件", ext.replace(/\|/g, ',')); + } + + }, + + // Default error messages + messages: { + 0: "此处", + fallback: "{0}格式不正确", + loading: "正在验证...", + error: "网络异常", + timeout: "请求超时", + required: "{0}不能为空", + remote: "{0}已被使用", + integer: { + '*': "请填写整数", + '+': "请填写正整数", + '+0': "请填写正整数或0", + '-': "请填写负整数", + '-0': "请填写负整数或0" + }, + match: { + eq: "{0}与{1}不一致", + neq: "{0}与{1}不能相同", + lt: "{0}必须小于{1}", + gt: "{0}必须大于{1}", + lte: "{0}不能大于{1}", + gte: "{0}不能小于{1}" + }, + range: { + rg: "请填写{1}到{2}的数", + gte: "请填写不小于{1}的数", + lte: "请填写最大{1}的数", + gtlt: "请填写{1}到{2}之间的数", + gt: "请填写大于{1}的数", + lt: "请填写小于{1}的数" + }, + checked: { + eq: "请选择{1}项", + rg: "请选择{1}到{2}项", + gte: "请至少选择{1}项", + lte: "请最多选择{1}项" + }, + length: { + eq: "请填写{1}个字符", + rg: "请填写{1}到{2}个字符", + gte: "请至少填写{1}个字符", + lte: "请最多填写{1}个字符", + eq_2: "", + rg_2: "", + gte_2: "", + lte_2: "" + } + } + }); + + /* Themes + */ + var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>'; + $.validator.setTheme({ + 'simple_right': { + formClass: 'n-simple', + msgClass: 'n-right' + }, + 'simple_bottom': { + formClass: 'n-simple', + msgClass: 'n-bottom' + }, + 'yellow_top': { + formClass: 'n-yellow', + msgClass: 'n-top', + msgArrow: TPL_ARROW + }, + 'yellow_right': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW + }, + 'yellow_right_effect': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW, + msgShow: function($msgbox, type){ + var $el = $msgbox.children(); + if ($el.is(':animated')) return; + if (type === 'error') { + $el.css({left: '20px', opacity: 0}) + .delay(100).show().stop() + .animate({left: '-4px', opacity: 1}, 150) + .animate({left: '3px'}, 80) + .animate({left: 0}, 80); + } else { + $el.css({left: 0, opacity: 1}).fadeIn(200); + } + }, + msgHide: function($msgbox, type){ + var $el = $msgbox.children(); + $el.stop().delay(100).show() + .animate({left: '20px', opacity: 0}, 300, function(){ + $msgbox.hide(); + }); + } + } + }); +})); diff --git a/static/plugins/validator/local/zh-TW.js b/static/plugins/validator/local/zh-TW.js new file mode 100755 index 0000000..9be397d --- /dev/null +++ b/static/plugins/validator/local/zh-TW.js @@ -0,0 +1,137 @@ +/********************************* + * Themes, rules, and i18n support + * Locale: Chinese; 中文; TW (Taiwan) + *********************************/ +(function(factory) { + typeof module === "object" && module.exports ? module.exports = factory( require( "jquery" ) ) : + typeof define === 'function' && define.amd ? require(['jquery'], factory) : + factory(jQuery); +}(function($) { + + /* Global configuration + */ + $.validator.config({ + //stopOnError: true, + //focusCleanup: true, + //theme: 'yellow_right', + //timely: 2, + + // Custom rules + rules: { + digits: [/^\d+$/, "請填寫數字"] + ,letters: [/^[a-z]+$/i, "請填寫字母"] + ,date: [/^\d{4}-\d{2}-\d{2}$/, "請填寫有效的日期,格式:yyyy-mm-dd"] + ,time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "請填寫有效的時間,00:00到23:59之間"] + ,email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "請填寫有效的電郵"] + ,url: [/^(https?|s?ftp):\/\/\S+$/i, "請填寫有效的網址"] + ,accept: function (element, params){ + if (!params) return true; + var ext = params[0], + value = $(element).val(); + return (ext === '*') || + (new RegExp(".(?:" + ext + ")$", "i")).test(value) || + this.renderMsg("只接受{1}後綴的文件", ext.replace(/\|/g, ',')); + } + + }, + + // Default error messages + messages: { + 0: "此處", + fallback: "{0}格式不正確", + loading: "正在驗證...", + error: "網絡異常", + timeout: "請求超時", + required: "{0}不能為空", + remote: "{0}已被使用", + integer: { + '*': "請填寫整數", + '+': "請填寫正整數", + '+0': "請填寫正整數或0", + '-': "請填寫負整數", + '-0': "請填寫負整數或0" + }, + match: { + eq: "{0}與{1}不一致", + neq: "{0}與{1}不能相同", + lt: "{0}必須小於{1}", + gt: "{0}必須大於{1}", + lte: "{0}不能大於{1}", + gte: "{0}不能小於{1}" + }, + range: { + rg: "請填寫{1}到{2}的數", + gte: "請填寫不小於{1}的數", + lte: "請填寫最大{1}的數", + gtlt: "請填寫{1}到{2}之間的數", + gt: "請填寫大於{1}的數", + lt: "請填寫小於{1}的數" + }, + checked: { + eq: "請選擇{1}項", + rg: "請選擇{1}到{2}項", + gte: "請至少選擇{1}項", + lte: "請最多選擇{1}項" + }, + length: { + eq: "請填寫{1}個字符", + rg: "請填寫{1}到{2}個字符", + gte: "請至少填寫{1}個字符", + lte: "請最多填寫{1}個字符", + eq_2: "", + rg_2: "", + gte_2: "", + lte_2: "" + } + } + }); + + /* Themes + */ + var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>'; + $.validator.setTheme({ + 'simple_right': { + formClass: 'n-simple', + msgClass: 'n-right' + }, + 'simple_bottom': { + formClass: 'n-simple', + msgClass: 'n-bottom' + }, + 'yellow_top': { + formClass: 'n-yellow', + msgClass: 'n-top', + msgArrow: TPL_ARROW + }, + 'yellow_right': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW + }, + 'yellow_right_effect': { + formClass: 'n-yellow', + msgClass: 'n-right', + msgArrow: TPL_ARROW, + msgShow: function($msgbox, type){ + var $el = $msgbox.children(); + if ($el.is(':animated')) return; + if (type === 'error') { + $el.css({left: '20px', opacity: 0}) + .delay(100).show().stop() + .animate({left: '-4px', opacity: 1}, 150) + .animate({left: '3px'}, 80) + .animate({left: 0}, 80); + } else { + $el.css({left: 0, opacity: 1}).fadeIn(200); + } + }, + msgHide: function($msgbox, type){ + var $el = $msgbox.children(); + $el.stop().delay(100).show() + .animate({left: '20px', opacity: 0}, 300, function(){ + $msgbox.hide(); + }); + } + } + }); +})); diff --git a/static/plugins/webuploader/Uploader.swf b/static/plugins/webuploader/Uploader.swf new file mode 100755 index 0000000..bd75d60 Binary files /dev/null and b/static/plugins/webuploader/Uploader.swf differ diff --git a/static/plugins/webuploader/batchupload.css b/static/plugins/webuploader/batchupload.css new file mode 100755 index 0000000..9dbf8d4 --- /dev/null +++ b/static/plugins/webuploader/batchupload.css @@ -0,0 +1,379 @@ +.wst-batchupload{} + +.wst-batchupload .queueList { + margin: 20px; + border: 3px dashed #e6e6e6; +} +.wst-batchupload .queueList.filled { + padding: 12px; + margin: 0; + border: 3px dashed transparent; +} +.wst-batchupload .queueList.webuploader-dnd-over { + border: 3px dashed #999999; +} + +.wst-batchupload p {margin: 0;} + +.element-invisible { + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px,1px,1px,1px); +} + +.wst-batchupload .placeholder { + min-height: 350px; + padding-top: 178px; + text-align: center; + background: url(image.png) center 93px no-repeat; + color: #cccccc; + font-size: 18px; + position: relative; +} + +.wst-batchupload .placeholder .webuploader-pick { + font-size: 18px; + background: #00b7ee; + border-radius: 3px; + line-height: 44px; + padding: 0 30px; + *width: 120px; + color: #fff; + display: inline-block; + margin: 0 auto 20px auto; + cursor: pointer; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +.wst-batchupload .placeholder .webuploader-pick-hover { + background: #00a2d4; +} + +.wst-batchupload .placeholder .flashTip { + color: #666666; + font-size: 12px; + position: absolute; + width: 100%; + text-align: center; + bottom: 20px; +} +.wst-batchupload .placeholder .flashTip a { + color: #0785d1; + text-decoration: none; +} +.wst-batchupload .placeholder .flashTip a:hover { + text-decoration: underline; +} + +.wst-batchupload .filelist { + list-style: none; + margin: 0; + padding: 0; +} + +.wst-batchupload .filelist:after { + content: ''; + display: block; + width: 0; + height: 0; + overflow: hidden; + clear: both; +} + +.wst-batchupload .filelist li { + width: 180px; + height: 180px; + background: url(bg.png) no-repeat; + text-align: center; + margin: 0 8px 20px 0; + position: relative; + display: inline; + float: left; + overflow: hidden; + font-size: 12px; +} + +.wst-batchupload .filelist li p.log { + position: relative; + top: -45px; +} + +.wst-batchupload .filelist li p.title { + position: absolute; + top: 0; + left: 0; + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow : ellipsis; + top: 5px; + text-indent: 5px; + text-align: left; +} + +.wst-batchupload .filelist li p.progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; +} +.wst-batchupload .filelist li p.progress span { + display: none; + overflow: hidden; + width: 0; + height: 100%; + background: #1483d8 url(progress.png) repeat-x; + + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + + -webkit-transform: translateZ(0); +} + +@-webkit-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} +@-moz-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} +@keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +.wst-batchupload .filelist li p.imgWrap { + position: relative; + z-index: 2; + line-height: 180px; + vertical-align: middle; + overflow: hidden; + width: 180px; + height: 180px; + + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + + -webit-transition: 200ms ease-out; + -moz-transition: 200ms ease-out; + -o-transition: 200ms ease-out; + -ms-transition: 200ms ease-out; + transition: 200ms ease-out; +} + +.wst-batchupload .filelist li img { + width: 100%; +} + +.wst-batchupload .filelist li p.error { + background: #f43838; + color: #fff; + position: absolute; + bottom: 0; + left: 0; + height: 28px; + line-height: 28px; + width: 100%; + z-index: 100; +} + +.wst-batchupload .filelist li .success { + display: block; + position: absolute; + left: 0; + bottom: 0; + height: 40px; + width: 100%; + z-index: 200; + background: url(success.png) no-repeat right bottom; +} + +.wst-batchupload .filelist div.file-panel { + position: absolute; + height: 0; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80000000', endColorstr='#80000000')\0; + background: rgba( 0, 0, 0, 0.5 ); + width: 100%; + top: 0; + left: 0; + overflow: hidden; + z-index: 300; +} + +.wst-batchupload .filelist div.file-panel span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url(icons.png) no-repeat; + margin: 5px 1px 1px; + cursor: pointer; +} + +.wst-batchupload .filelist div.file-panel span.rotateLeft { + background-position: 0 -24px; +} +.wst-batchupload .filelist div.file-panel span.rotateLeft:hover { + background-position: 0 0; +} + +.wst-batchupload .filelist div.file-panel span.rotateRight { + background-position: -24px -24px; +} +.wst-batchupload .filelist div.file-panel span.rotateRight:hover { + background-position: -24px 0; +} + +.wst-batchupload .filelist div.file-panel span.cancel { + background-position: -48px -24px; +} +.wst-batchupload .filelist div.file-panel span.cancel:hover { + background-position: -48px 0; +} + +.wst-batchupload .statusBar { + height: 63px; + border-top: 1px solid #dadada; + padding: 0 20px; + line-height: 63px; + vertical-align: middle; + position: relative; +} + +.wst-batchupload .statusBar .progress { + border: 1px solid #1483d8; + width: 198px; + background: #fff; + height: 18px; + position: relative; + display: inline-block; + text-align: center; + line-height: 20px; + color: #6dbfff; + position: relative; + margin: 0 10px 0 0; +} +.wst-batchupload .statusBar .progress span.percentage { + width: 0; + height: 100%; + left: 0; + top: 0; + background: #1483d8; + position: absolute; +} +.wst-batchupload .statusBar .progress span.text { + position: relative; + z-index: 10; +} + +.wst-batchupload .statusBar .info { + display: inline-block; + font-size: 14px; + color: #666666; +} + +.wst-batchupload .statusBar .btns { + position: absolute; + top: 10px; + right: 20px; + line-height: 40px; +} + +#filePicker2 { + display: inline-block; + float: left; +} + +.wst-batchupload .statusBar .btns .webuploader-pick, +.wst-batchupload .statusBar .btns .uploadBtn, +.wst-batchupload .statusBar .btns .uploadBtn.state-uploading, +.wst-batchupload .statusBar .btns .uploadBtn.state-paused { + background: #ffffff; + border: 1px solid #cfcfcf; + color: #565656; + padding: 0 18px; + display: inline-block; + border-radius: 3px; + margin-left: 10px; + cursor: pointer; + font-size: 14px; + float: left; +} +.wst-batchupload .statusBar .btns .webuploader-pick-hover, +.wst-batchupload .statusBar .btns .uploadBtn:hover, +.wst-batchupload .statusBar .btns .uploadBtn.state-uploading:hover, +.wst-batchupload .statusBar .btns .uploadBtn.state-paused:hover { + background: #f0f0f0; +} + +.wst-batchupload .statusBar .btns .uploadBtn { + background: #00b7ee; + color: #fff; + border-color: transparent; +} +.wst-batchupload .statusBar .btns .uploadBtn:hover { + background: #00a2d4; +} + +.wst-batchupload .statusBar .btns .uploadBtn.disabled { + pointer-events: none; + opacity: 0.6; +} +.filelist .btn-setDefault{ + background: #f48c3a none repeat scroll 0 0; + bottom: 0; + color: #ffffff; + height: 18px; + line-height: 18px; + padding: 0 5px; + position: absolute; + left: 0px; + top:0px; + z-index: 9999; +} +.filelist .btn-del{ + background: #1094FA; + color: #ffffff; + cursor: pointer; + height: 18px; + line-height: 18px; + padding: 0 5px; + position: absolute; + right: 0px; + top:0px; + z-index: 9999; +} \ No newline at end of file diff --git a/static/plugins/webuploader/batchupload.js b/static/plugins/webuploader/batchupload.js new file mode 100755 index 0000000..07ecaea --- /dev/null +++ b/static/plugins/webuploader/batchupload.js @@ -0,0 +1,449 @@ +/** + * @param opts{ + * uploadPicker:上传按钮ID,要带# + * uploadServer:后台接收图片的接口 + * formData:一些附带的参数设置 + * uploadSuccess:上传成功后的回调函数 + * } + */ +function batchUpload(options){ + var $ = jQuery, // just in case. Make sure it's not an other libaray. + opts = $.extend({},{formData:{dir:'uploads',width:700,height:700},fileNumLimit:50,fileSizeLimit:50 * 5 * 1024 * 1024,fileSingleSizeLimit:5 * 1024 * 1024},options), + $wrap = $(opts.uploadPicker), + + // 图片容器 + $queue = $('.filelist'), + // 状态栏,包括进度和控制按钮 + $statusBar = $wrap.find('.statusBar'), + + // 文件总体选择信息。 + $info = $statusBar.find('.info'), + + // 上传按钮 + $upload = $wrap.find('.uploadBtn'), + + // 没选择文件之前的内容。 + $placeHolder = $wrap.find('.placeholder'), + + // 总体进度条 + $progress = $statusBar.find('.progress').hide(), + + // 添加的文件数量 + fileCount = 0, + + // 添加的文件总大小 + fileSize = 0, + + // 优化retina, 在retina下这个值是2 + ratio = window.devicePixelRatio || 1, + + // 缩略图大小 + thumbnailWidth = 110 * ratio, + thumbnailHeight = 110 * ratio, + + // 可能有pedding, ready, uploading, confirm, done. + state = 'pedding', + + // 所有文件的进度信息,key为file id + percentages = {}, + + supportTransition = (function(){ + var s = document.createElement('p').style, + r = 'transition' in s || + 'WebkitTransition' in s || + 'MozTransition' in s || + 'msTransition' in s || + 'OTransition' in s; + s = null; + return r; + })(), + + // WebUploader实例 + uploader; + + if ( !WebUploader.Uploader.support() ) { + WST.msg( 'Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器',{icon:2}); + throw new Error( 'WebUploader does not support the browser you are using.' ); + } + // 实例化 + uploader = WebUploader.create({ + pick: { + id: '#filePicker', + label: '点击选择图片' + }, + dnd: '.wst-batchupload .queueList', + paste: document.body, + + accept: { + title: 'Images', + extensions: 'gif,jpg,jpeg,png', + mimeTypes: 'image/jpg,image/jpeg,image/png,image/gif' + }, + // swf文件路径 + swf: WST.conf.STATIC + '/plugins/webuploader/js/Uploader.swf', + disableGlobalDnd: true, + chunked: true, + server: opts.uploadServer, + fileNumLimit: opts.fileNumLimit, + fileSizeLimit: opts.fileSizeLimit, // 200 M + fileSingleSizeLimit: opts.fileSingleSizeLimit, // 5 M + formData: opts.formData //文件保存的路径 + }); + + // 添加“添加文件”的按钮, + uploader.addButton({ + id: '#filePicker2', + label: '继续添加' + }); + + // 当有文件添加进来时执行,负责view的创建 + function addFile( file ) { + var $li = $( '<li id="' + file.id + '">' + + '<p class="title">' + file.name + '</p>' + + '<p class="imgWrap"></p>'+ + '<p class="progress"><span></span></p>' + + '</li>' ), + + $btns = $('<div class="file-panel">' + + '<span class="cancel">删除</span>' + + '<span class="rotateRight">向右旋转</span>' + + '<span class="rotateLeft">向左旋转</span></div>').appendTo( $li ), + $prgress = $li.find('p.progress span'), + $wrap = $li.find( 'p.imgWrap' ), + $info = $('<p class="error"></p>'), + + showError = function( code ) { + switch( code ) { + case 'exceed_size': + text = '文件大小超出'; + break; + + case 'interrupt': + text = '上传暂停'; + break; + + default: + text = '上传失败,请重试'; + break; + } + + $info.text( text ).appendTo( $li ); + }; + + if ( file.getStatus() === 'invalid' ) { + showError( file.statusText ); + } else { + // @todo lazyload + $wrap.text( '预览中' ); + uploader.makeThumb( file, function( error, src ) { + if ( error ) { + $wrap.text( '不能预览' ); + return; + } + + var img = $('<img src="'+src+'">'); + $wrap.empty().append( img ); + }, thumbnailWidth, thumbnailHeight ); + + percentages[ file.id ] = [ file.size, 0 ]; + file.rotation = 0; + } + + file.on('statuschange', function( cur, prev ) { + if ( prev === 'progress' ) { + $prgress.hide().width(0); + } else if ( prev === 'queued' ) { + $li.off( 'mouseenter mouseleave' ); + $btns.remove(); + } + + // 成功 + if ( cur === 'error' || cur === 'invalid' ) { + console.log( file.statusText ); + showError( file.statusText ); + percentages[ file.id ][ 1 ] = 1; + } else if ( cur === 'interrupt' ) { + showError( 'interrupt' ); + } else if ( cur === 'queued' ) { + percentages[ file.id ][ 1 ] = 0; + } else if ( cur === 'progress' ) { + $info.remove(); + $prgress.css('display', 'block'); + } else if ( cur === 'complete' ) { + $li.append( '<span class="success"></span>' ); + } + + $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur ); + }); + + $li.on( 'mouseenter', function() { + $btns.stop().animate({height: 30}); + }); + + $li.on( 'mouseleave', function() { + $btns.stop().animate({height: 0}); + }); + + $btns.on( 'click', 'span', function() { + var index = $(this).index(), + deg; + + switch ( index ) { + case 0: + uploader.removeFile( file ); + return; + + case 1: + file.rotation += 90; + break; + + case 2: + file.rotation -= 90; + break; + } + + if ( supportTransition ) { + deg = 'rotate(' + file.rotation + 'deg)'; + $wrap.css({ + '-webkit-transform': deg, + '-mos-transform': deg, + '-o-transform': deg, + 'transform': deg + }); + } else { + $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')'); + // use jquery animate to rotation + // $({ + // rotation: rotation + // }).animate({ + // rotation: file.rotation + // }, { + // easing: 'linear', + // step: function( now ) { + // now = now * Math.PI / 180; + + // var cos = Math.cos( now ), + // sin = Math.sin( now ); + + // $wrap.css( 'filter', "progid:DXImageTransform.Microsoft.Matrix(M11=" + cos + ",M12=" + (-sin) + ",M21=" + sin + ",M22=" + cos + ",SizingMethod='auto expand')"); + // } + // }); + } + + + }); + + $li.appendTo( $queue ); + $('.uploadBtn').removeClass('disabled'); + } + + // 负责view的销毁 + function removeFile( file ) { + var $li = $('#'+file.id); + delete percentages[ file.id ]; + updateTotalProgress(); + $li.off().find('.file-panel').off().end().remove(); + } + + function updateTotalProgress() { + var loaded = 0, + total = 0, + spans = $progress.children(), + percent; + + $.each( percentages, function( k, v ) { + total += v[ 0 ]; + loaded += v[ 0 ] * v[ 1 ]; + } ); + + percent = total ? loaded / total : 0; + + spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' ); + spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' ); + updateStatus(); + } + + function updateStatus() { + var text = '', stats; + + if ( state === 'ready' ) { + text = '选中' + fileCount + '张图片,共' + + WebUploader.formatSize( fileSize ) + '。'; + } else if ( state === 'confirm' ) { + stats = uploader.getStats(); + if ( stats.uploadFailNum ) { + text = '已成功上传' + stats.successNum+ '张图片至服务器上,'+ + stats.uploadFailNum + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片' + } + + } else { + stats = uploader.getStats(); + text = '共' + fileCount + '张(' + + WebUploader.formatSize( fileSize ) + + '),已上传' + stats.successNum + '张'; + + if ( stats.uploadFailNum ) { + text += ',失败' + stats.uploadFailNum + '张'; + } + } + + $info.html( text ); + } + + function setState( val ) { + var file, stats; + + if ( val === state ) { + return; + } + + $upload.removeClass( 'state-' + state ); + $upload.addClass( 'state-' + val ); + state = val; + + switch ( state ) { + case 'pedding': + $placeHolder.removeClass( 'element-invisible' ); + $queue.parent().removeClass('filled'); + $queue.hide(); + $statusBar.addClass( 'element-invisible' ); + uploader.refresh(); + break; + + case 'ready': + $placeHolder.addClass( 'element-invisible' ); + $( '#filePicker2' ).removeClass( 'element-invisible'); + $queue.parent().addClass('filled'); + $queue.show(); + $statusBar.removeClass('element-invisible'); + uploader.refresh(); + break; + + case 'uploading': + $( '#filePicker2' ).addClass( 'element-invisible' ); + $progress.show(); + $upload.text( '暂停上传' ); + break; + + case 'paused': + $progress.show(); + $upload.text( '继续上传' ); + break; + + case 'confirm': + $progress.hide(); + $upload.text( '开始上传' ).addClass( 'disabled' ); + + stats = uploader.getStats(); + if ( stats.successNum && !stats.uploadFailNum ) { + setState( 'finish' ); + return; + } + break; + case 'finish': + stats = uploader.getStats(); + if ( stats.successNum ) { + $( '#filePicker2' ).removeClass( 'element-invisible'); + $upload.removeClass('.disabled'); + //WST.msg( '上传成功' ); + } else { + // 没有成功的图片,重设 + state = 'done'; + location.reload(); + } + break; + } + + updateStatus(); + } + uploader.onUploadSuccess=function(file,response) { + if(opts.uploadSuccess)opts.uploadSuccess(file,response); + } + uploader.onUploadProgress = function( file, percentage ) { + var $li = $('#'+file.id), + $percent = $li.find('.progress span'); + + $percent.css( 'width', percentage * 100 + '%' ); + percentages[ file.id ][ 1 ] = percentage; + updateTotalProgress(); + }; + + uploader.onFileQueued = function( file ) { + fileCount++; + fileSize += file.size; + + if ( fileCount === 1 ) { + $placeHolder.addClass( 'element-invisible' ); + $statusBar.show(); + } + + addFile( file ); + setState( 'ready' ); + updateTotalProgress(); + }; + + uploader.onFileDequeued = function( file ) { + fileCount--; + fileSize -= file.size; + + if ( !fileCount ) { + setState( 'pedding' ); + } + + removeFile( file ); + updateTotalProgress(); + + }; + + uploader.on( 'all', function( type ) { + var stats; + switch( type ) { + case 'uploadFinished': + setState( 'confirm' ); + break; + + case 'startUpload': + setState( 'uploading' ); + break; + + case 'stopUpload': + setState( 'paused' ); + break; + + } + }); + + uploader.onError = function( code ) { + if(code=='Q_EXCEED_NUM_LIMIT'){ + WST.msg( '文件上传数量超过限制' ,{icon:2}); + }else if(code == 'F_EXCEED_SIZE'){ + WST.msg( '上传的文件大小超过限制' ,{icon:2}); + }else if(code == 'Q_TYPE_DENIED'){ + WST.msg( '上传的文件类型错误' ,{icon:2}); + }else{ + WST.msg( 'Eroor: ' + code ,{icon:2}); + } + }; + + $upload.on('click', function() { + if ( $(this).hasClass( 'disabled' ) ) { + return false; + } + + if ( state === 'ready' ) { + uploader.upload(); + } else if ( state === 'paused' ) { + uploader.upload(); + } else if ( state === 'uploading' ) { + uploader.stop(); + } + }); + + $info.on( 'click', '.retry', function() { + uploader.retry(); + } ); + + $upload.addClass( 'state-' + state ); + updateTotalProgress(); + return uploader; +} \ No newline at end of file diff --git a/static/plugins/webuploader/bg.png b/static/plugins/webuploader/bg.png new file mode 100755 index 0000000..73d102d Binary files /dev/null and b/static/plugins/webuploader/bg.png differ diff --git a/static/plugins/webuploader/expressInstall.swf b/static/plugins/webuploader/expressInstall.swf new file mode 100755 index 0000000..24853ae Binary files /dev/null and b/static/plugins/webuploader/expressInstall.swf differ diff --git a/static/plugins/webuploader/icons.png b/static/plugins/webuploader/icons.png new file mode 100755 index 0000000..12e4700 Binary files /dev/null and b/static/plugins/webuploader/icons.png differ diff --git a/static/plugins/webuploader/image.png b/static/plugins/webuploader/image.png new file mode 100755 index 0000000..19699f6 Binary files /dev/null and b/static/plugins/webuploader/image.png differ diff --git a/static/plugins/webuploader/index.html b/static/plugins/webuploader/index.html new file mode 100755 index 0000000..0e36ef3 --- /dev/null +++ b/static/plugins/webuploader/index.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> + <title>WebUploader演示</title> + <link rel="stylesheet" type="text/css" href="./webuploader.css" /> + <link rel="stylesheet" type="text/css" href="./style.css" /> +</head> +<body> + <div id="wrapper"> + <div id="container"> + <!--头部,相册选择和格式选择--> + + <div id="uploader"> + <div class="queueList"> + <div id="dndArea" class="placeholder"> + <div id="filePicker"></div> + <p>或将照片拖到这里,单次最多可选300张</p> + </div> + </div> + <div class="statusBar" style="display:none;"> + <div class="progress"> + <span class="text">0%</span> + <span class="percentage"></span> + </div><div class="info"></div> + <div class="btns"> + <div id="filePicker2"></div><div class="uploadBtn">开始上传</div> + </div> + </div> + </div> + </div> + </div> + <script type="text/javascript" src="./jquery.js"></script> + <script type="text/javascript" src="./webuploader.js"></script> + <script type="text/javascript" src="./upload.js"></script> +</body> +</html> \ No newline at end of file diff --git a/static/plugins/webuploader/progress.png b/static/plugins/webuploader/progress.png new file mode 100755 index 0000000..717c486 Binary files /dev/null and b/static/plugins/webuploader/progress.png differ diff --git a/static/plugins/webuploader/success.png b/static/plugins/webuploader/success.png new file mode 100755 index 0000000..94f968d Binary files /dev/null and b/static/plugins/webuploader/success.png differ diff --git a/static/plugins/webuploader/webuploader.css b/static/plugins/webuploader/webuploader.css new file mode 100755 index 0000000..881516c --- /dev/null +++ b/static/plugins/webuploader/webuploader.css @@ -0,0 +1,30 @@ +.webuploader-container { + position: relative; +} +.webuploader-element-invisible { + position: absolute !important; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px,1px,1px,1px); +} +.webuploader-pick { + position: relative; + display: inline-block; + cursor: pointer; + background: #00b7ee; + padding:0px 10px; + background:#e23e3d; + text-align: center; + border-radius: 3px; + overflow: hidden; + color:#ffffff; +} +.webuploader-pick-hover { + background: #e23e3d; + color:#ffffff; +} + +.webuploader-pick-disable { + opacity: 0.6; + pointer-events:none; +} + diff --git a/static/plugins/webuploader/webuploader.js b/static/plugins/webuploader/webuploader.js new file mode 100755 index 0000000..e098b8f --- /dev/null +++ b/static/plugins/webuploader/webuploader.js @@ -0,0 +1,8108 @@ +/*! WebUploader 0.1.5 */ + + +/** + * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。 + * + * AMD API 内部的简单不完全实现,请忽略。只有当WebUploader被合并成一个文件的时候才会引入。 + */ +(function( root, factory ) { + var modules = {}, + + // 内部require, 简单不完全实现。 + // https://github.com/amdjs/amdjs-api/wiki/require + _require = function( deps, callback ) { + var args, len, i; + + // 如果deps不是数组,则直接返回指定module + if ( typeof deps === 'string' ) { + return getModule( deps ); + } else { + args = []; + for( len = deps.length, i = 0; i < len; i++ ) { + args.push( getModule( deps[ i ] ) ); + } + + return callback.apply( null, args ); + } + }, + + // 内部define,暂时不支持不指定id. + _define = function( id, deps, factory ) { + if ( arguments.length === 2 ) { + factory = deps; + deps = null; + } + + _require( deps || [], function() { + setModule( id, factory, arguments ); + }); + }, + + // 设置module, 兼容CommonJs写法。 + setModule = function( id, factory, args ) { + var module = { + exports: factory + }, + returned; + + if ( typeof factory === 'function' ) { + args.length || (args = [ _require, module.exports, module ]); + returned = factory.apply( null, args ); + returned !== undefined && (module.exports = returned); + } + + modules[ id ] = module.exports; + }, + + // 根据id获取module + getModule = function( id ) { + var module = modules[ id ] || root[ id ]; + + if ( !module ) { + throw new Error( '`' + id + '` is undefined' ); + } + + return module; + }, + + // 将所有modules,将路径ids装换成对象。 + exportsTo = function( obj ) { + var key, host, parts, part, last, ucFirst; + + // make the first character upper case. + ucFirst = function( str ) { + return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 )); + }; + + for ( key in modules ) { + host = obj; + + if ( !modules.hasOwnProperty( key ) ) { + continue; + } + + parts = key.split('/'); + last = ucFirst( parts.pop() ); + + while( (part = ucFirst( parts.shift() )) ) { + host[ part ] = host[ part ] || {}; + host = host[ part ]; + } + + host[ last ] = modules[ key ]; + } + + return obj; + }, + + makeExport = function( dollar ) { + root.__dollar = dollar; + + // exports every module. + return exportsTo( factory( root, _define, _require ) ); + }, + + origin; + + if ( typeof module === 'object' && typeof module.exports === 'object' ) { + + // For CommonJS and CommonJS-like environments where a proper window is present, + module.exports = makeExport(); + } else if ( typeof define === 'function' && define.amd ) { + + // Allow using this built library as an AMD module + // in another project. That other project will only + // see this AMD call, not the internal modules in + // the closure below. + define([ 'jquery' ], makeExport ); + } else { + + // Browser globals case. Just assign the + // result to a property on the global. + origin = root.WebUploader; + root.WebUploader = makeExport(); + root.WebUploader.noConflict = function() { + root.WebUploader = origin; + }; + } +})( window, function( window, define, require ) { + + + /** + * @fileOverview jQuery or Zepto + */ + define('dollar-third',[],function() { + var $ = window.__dollar || window.jQuery || window.Zepto; + + if ( !$ ) { + throw new Error('jQuery or Zepto not found!'); + } + + return $; + }); + /** + * @fileOverview Dom 操作相关 + */ + define('dollar',[ + 'dollar-third' + ], function( _ ) { + return _; + }); + /** + * @fileOverview 使用jQuery的Promise + */ + define('promise-third',[ + 'dollar' + ], function( $ ) { + return { + Deferred: $.Deferred, + when: $.when, + + isPromise: function( anything ) { + return anything && typeof anything.then === 'function'; + } + }; + }); + /** + * @fileOverview Promise/A+ + */ + define('promise',[ + 'promise-third' + ], function( _ ) { + return _; + }); + /** + * @fileOverview 基础类方法。 + */ + + /** + * Web Uploader内部类的详细说明,以下提及的功能类,都可以在`WebUploader`这个变量中访问到。 + * + * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id. + * 默认module id为该文件的路径,而此路径将会转化成名字空间存放在WebUploader中。如: + * + * * module `base`:WebUploader.Base + * * module `file`: WebUploader.File + * * module `lib/dnd`: WebUploader.Lib.Dnd + * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd + * + * + * 以下文档中对类的使用可能省略掉了`WebUploader`前缀。 + * @module WebUploader + * @title WebUploader API文档 + */ + define('base',[ + 'dollar', + 'promise' + ], function( $, promise ) { + + var noop = function() {}, + call = Function.call; + + // http://jsperf.com/uncurrythis + // 反科里化 + function uncurryThis( fn ) { + return function() { + return call.apply( fn, arguments ); + }; + } + + function bindFn( fn, context ) { + return function() { + return fn.apply( context, arguments ); + }; + } + + function createObject( proto ) { + var f; + + if ( Object.create ) { + return Object.create( proto ); + } else { + f = function() {}; + f.prototype = proto; + return new f(); + } + } + + + /** + * 基础类,提供一些简单常用的方法。 + * @class Base + */ + return { + + /** + * @property {String} version 当前版本号。 + */ + version: '0.1.5', + + /** + * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。 + */ + $: $, + + Deferred: promise.Deferred, + + isPromise: promise.isPromise, + + when: promise.when, + + /** + * @description 简单的浏览器检查结果。 + * + * * `webkit` webkit版本号,如果浏览器为非webkit内核,此属性为`undefined`。 + * * `chrome` chrome浏览器版本号,如果浏览器为chrome,此属性为`undefined`。 + * * `ie` ie浏览器版本号,如果浏览器为非ie,此属性为`undefined`。**暂不支持ie10+** + * * `firefox` firefox浏览器版本号,如果浏览器为非firefox,此属性为`undefined`。 + * * `safari` safari浏览器版本号,如果浏览器为非safari,此属性为`undefined`。 + * * `opera` opera浏览器版本号,如果浏览器为非opera,此属性为`undefined`。 + * + * @property {Object} [browser] + */ + browser: (function( ua ) { + var ret = {}, + webkit = ua.match( /WebKit\/([\d.]+)/ ), + chrome = ua.match( /Chrome\/([\d.]+)/ ) || + ua.match( /CriOS\/([\d.]+)/ ), + + ie = ua.match( /MSIE\s([\d\.]+)/ ) || + ua.match( /(?:trident)(?:.*rv:([\w.]+))?/i ), + firefox = ua.match( /Firefox\/([\d.]+)/ ), + safari = ua.match( /Safari\/([\d.]+)/ ), + opera = ua.match( /OPR\/([\d.]+)/ ); + + webkit && (ret.webkit = parseFloat( webkit[ 1 ] )); + chrome && (ret.chrome = parseFloat( chrome[ 1 ] )); + ie && (ret.ie = parseFloat( ie[ 1 ] )); + firefox && (ret.firefox = parseFloat( firefox[ 1 ] )); + safari && (ret.safari = parseFloat( safari[ 1 ] )); + opera && (ret.opera = parseFloat( opera[ 1 ] )); + + return ret; + })( navigator.userAgent ), + + /** + * @description 操作系统检查结果。 + * + * * `android` 如果在android浏览器环境下,此值为对应的android版本号,否则为`undefined`。 + * * `ios` 如果在ios浏览器环境下,此值为对应的ios版本号,否则为`undefined`。 + * @property {Object} [os] + */ + os: (function( ua ) { + var ret = {}, + + // osx = !!ua.match( /\(Macintosh\; Intel / ), + android = ua.match( /(?:Android);?[\s\/]+([\d.]+)?/ ), + ios = ua.match( /(?:iPad|iPod|iPhone).*OS\s([\d_]+)/ ); + + // osx && (ret.osx = true); + android && (ret.android = parseFloat( android[ 1 ] )); + ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) )); + + return ret; + })( navigator.userAgent ), + + /** + * 实现类与类之间的继承。 + * @method inherits + * @grammar Base.inherits( super ) => child + * @grammar Base.inherits( super, protos ) => child + * @grammar Base.inherits( super, protos, statics ) => child + * @param {Class} super 父类 + * @param {Object | Function} [protos] 子类或者对象。如果对象中包含constructor,子类将是用此属性值。 + * @param {Function} [protos.constructor] 子类构造器,不指定的话将创建个临时的直接执行父类构造器的方法。 + * @param {Object} [statics] 静态属性或方法。 + * @return {Class} 返回子类。 + * @example + * function Person() { + * console.log( 'Super' ); + * } + * Person.prototype.hello = function() { + * console.log( 'hello' ); + * }; + * + * var Manager = Base.inherits( Person, { + * world: function() { + * console.log( 'World' ); + * } + * }); + * + * // 因为没有指定构造器,父类的构造器将会执行。 + * var instance = new Manager(); // => Super + * + * // 继承子父类的方法 + * instance.hello(); // => hello + * instance.world(); // => World + * + * // 子类的__super__属性指向父类 + * console.log( Manager.__super__ === Person ); // => true + */ + inherits: function( Super, protos, staticProtos ) { + var child; + + if ( typeof protos === 'function' ) { + child = protos; + protos = null; + } else if ( protos && protos.hasOwnProperty('constructor') ) { + child = protos.constructor; + } else { + child = function() { + return Super.apply( this, arguments ); + }; + } + + // 复制静态方法 + $.extend( true, child, Super, staticProtos || {} ); + + /* jshint camelcase: false */ + + // 让子类的__super__属性指向父类。 + child.__super__ = Super.prototype; + + // 构建原型,添加原型方法或属性。 + // 暂时用Object.create实现。 + child.prototype = createObject( Super.prototype ); + protos && $.extend( true, child.prototype, protos ); + + return child; + }, + + /** + * 一个不做任何事情的方法。可以用来赋值给默认的callback. + * @method noop + */ + noop: noop, + + /** + * 返回一个新的方法,此方法将已指定的`context`来执行。 + * @grammar Base.bindFn( fn, context ) => Function + * @method bindFn + * @example + * var doSomething = function() { + * console.log( this.name ); + * }, + * obj = { + * name: 'Object Name' + * }, + * aliasFn = Base.bind( doSomething, obj ); + * + * aliasFn(); // => Object Name + * + */ + bindFn: bindFn, + + /** + * 引用Console.log如果存在的话,否则引用一个[空函数noop](#WebUploader:Base.noop)。 + * @grammar Base.log( args... ) => undefined + * @method log + */ + log: (function() { + if ( window.console ) { + return bindFn( console.log, console ); + } + return noop; + })(), + + nextTick: (function() { + + return function( cb ) { + setTimeout( cb, 1 ); + }; + + // @bug 当浏览器不在当前窗口时就停了。 + // var next = window.requestAnimationFrame || + // window.webkitRequestAnimationFrame || + // window.mozRequestAnimationFrame || + // function( cb ) { + // window.setTimeout( cb, 1000 / 60 ); + // }; + + // // fix: Uncaught TypeError: Illegal invocation + // return bindFn( next, window ); + })(), + + /** + * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。 + * 将用来将非数组对象转化成数组对象。 + * @grammar Base.slice( target, start[, end] ) => Array + * @method slice + * @example + * function doSomthing() { + * var args = Base.slice( arguments, 1 ); + * console.log( args ); + * } + * + * doSomthing( 'ignored', 'arg2', 'arg3' ); // => Array ["arg2", "arg3"] + */ + slice: uncurryThis( [].slice ), + + /** + * 生成唯一的ID + * @method guid + * @grammar Base.guid() => String + * @grammar Base.guid( prefx ) => String + */ + guid: (function() { + var counter = 0; + + return function( prefix ) { + var guid = (+new Date()).toString( 32 ), + i = 0; + + for ( ; i < 5; i++ ) { + guid += Math.floor( Math.random() * 65535 ).toString( 32 ); + } + + return (prefix || 'wu_') + guid + (counter++).toString( 32 ); + }; + })(), + + /** + * 格式化文件大小, 输出成带单位的字符串 + * @method formatSize + * @grammar Base.formatSize( size ) => String + * @grammar Base.formatSize( size, pointLength ) => String + * @grammar Base.formatSize( size, pointLength, units ) => String + * @param {Number} size 文件大小 + * @param {Number} [pointLength=2] 精确到的小数点数。 + * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节,到千字节,一直往上指定。如果单位数组里面只指定了到了K(千字节),同时文件大小大于M, 此方法的输出将还是显示成多少K. + * @example + * console.log( Base.formatSize( 100 ) ); // => 100B + * console.log( Base.formatSize( 1024 ) ); // => 1.00K + * console.log( Base.formatSize( 1024, 0 ) ); // => 1K + * console.log( Base.formatSize( 1024 * 1024 ) ); // => 1.00M + * console.log( Base.formatSize( 1024 * 1024 * 1024 ) ); // => 1.00G + * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) ); // => 1024MB + */ + formatSize: function( size, pointLength, units ) { + var unit; + + units = units || [ 'B', 'K', 'M', 'G', 'TB' ]; + + while ( (unit = units.shift()) && size > 1024 ) { + size = size / 1024; + } + + return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) + + unit; + } + }; + }); + /** + * 事件处理类,可以独立使用,也可以扩展给对象使用。 + * @fileOverview Mediator + */ + define('mediator',[ + 'base' + ], function( Base ) { + var $ = Base.$, + slice = [].slice, + separator = /\s+/, + protos; + + // 根据条件过滤出事件handlers. + function findHandlers( arr, name, callback, context ) { + return $.grep( arr, function( handler ) { + return handler && + (!name || handler.e === name) && + (!callback || handler.cb === callback || + handler.cb._cb === callback) && + (!context || handler.ctx === context); + }); + } + + function eachEvent( events, callback, iterator ) { + // 不支持对象,只支持多个event用空格隔开 + $.each( (events || '').split( separator ), function( _, key ) { + iterator( key, callback ); + }); + } + + function triggerHanders( events, args ) { + var stoped = false, + i = -1, + len = events.length, + handler; + + while ( ++i < len ) { + handler = events[ i ]; + + if ( handler.cb.apply( handler.ctx2, args ) === false ) { + stoped = true; + break; + } + } + + return !stoped; + } + + protos = { + + /** + * 绑定事件。 + * + * `callback`方法在执行时,arguments将会来源于trigger的时候携带的参数。如 + * ```javascript + * var obj = {}; + * + * // 使得obj有事件行为 + * Mediator.installTo( obj ); + * + * obj.on( 'testa', function( arg1, arg2 ) { + * console.log( arg1, arg2 ); // => 'arg1', 'arg2' + * }); + * + * obj.trigger( 'testa', 'arg1', 'arg2' ); + * ``` + * + * 如果`callback`中,某一个方法`return false`了,则后续的其他`callback`都不会被执行到。 + * 切会影响到`trigger`方法的返回值,为`false`。 + * + * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处, + * 就是第一个参数为`type`,记录当前是什么事件在触发。此类`callback`的优先级比脚低,会再正常`callback`执行完后触发。 + * ```javascript + * obj.on( 'all', function( type, arg1, arg2 ) { + * console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2' + * }); + * ``` + * + * @method on + * @grammar on( name, callback[, context] ) => self + * @param {String} name 事件名,支持多个事件用空格隔开 + * @param {Function} callback 事件处理器 + * @param {Object} [context] 事件处理器的上下文。 + * @return {self} 返回自身,方便链式 + * @chainable + * @class Mediator + */ + on: function( name, callback, context ) { + var me = this, + set; + + if ( !callback ) { + return this; + } + + set = this._events || (this._events = []); + + eachEvent( name, callback, function( name, callback ) { + var handler = { e: name }; + + handler.cb = callback; + handler.ctx = context; + handler.ctx2 = context || me; + handler.id = set.length; + + set.push( handler ); + }); + + return this; + }, + + /** + * 绑定事件,且当handler执行完后,自动解除绑定。 + * @method once + * @grammar once( name, callback[, context] ) => self + * @param {String} name 事件名 + * @param {Function} callback 事件处理器 + * @param {Object} [context] 事件处理器的上下文。 + * @return {self} 返回自身,方便链式 + * @chainable + */ + once: function( name, callback, context ) { + var me = this; + + if ( !callback ) { + return me; + } + + eachEvent( name, callback, function( name, callback ) { + var once = function() { + me.off( name, once ); + return callback.apply( context || me, arguments ); + }; + + once._cb = callback; + me.on( name, once, context ); + }); + + return me; + }, + + /** + * 解除事件绑定 + * @method off + * @grammar off( [name[, callback[, context] ] ] ) => self + * @param {String} [name] 事件名 + * @param {Function} [callback] 事件处理器 + * @param {Object} [context] 事件处理器的上下文。 + * @return {self} 返回自身,方便链式 + * @chainable + */ + off: function( name, cb, ctx ) { + var events = this._events; + + if ( !events ) { + return this; + } + + if ( !name && !cb && !ctx ) { + this._events = []; + return this; + } + + eachEvent( name, cb, function( name, cb ) { + $.each( findHandlers( events, name, cb, ctx ), function() { + delete events[ this.id ]; + }); + }); + + return this; + }, + + /** + * 触发事件 + * @method trigger + * @grammar trigger( name[, args...] ) => self + * @param {String} type 事件名 + * @param {*} [...] 任意参数 + * @return {Boolean} 如果handler中return false了,则返回false, 否则返回true + */ + trigger: function( type ) { + var args, events, allEvents; + + if ( !this._events || !type ) { + return this; + } + + args = slice.call( arguments, 1 ); + events = findHandlers( this._events, type ); + allEvents = findHandlers( this._events, 'all' ); + + return triggerHanders( events, args ) && + triggerHanders( allEvents, arguments ); + } + }; + + /** + * 中介者,它本身是个单例,但可以通过[installTo](#WebUploader:Mediator:installTo)方法,使任何对象具备事件行为。 + * 主要目的是负责模块与模块之间的合作,降低耦合度。 + * + * @class Mediator + */ + return $.extend({ + + /** + * 可以通过这个接口,使任何对象具备事件功能。 + * @method installTo + * @param {Object} obj 需要具备事件行为的对象。 + * @return {Object} 返回obj. + */ + installTo: function( obj ) { + return $.extend( obj, protos ); + } + + }, protos ); + }); + /** + * @fileOverview Uploader上传类 + */ + define('uploader',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$; + + /** + * 上传入口类。 + * @class Uploader + * @constructor + * @grammar new Uploader( opts ) => Uploader + * @example + * var uploader = WebUploader.Uploader({ + * swf: 'path_of_swf/Uploader.swf', + * + * // 开起分片上传。 + * chunked: true + * }); + */ + function Uploader( opts ) { + this.options = $.extend( true, {}, Uploader.options, opts ); + this._init( this.options ); + } + + // default Options + // widgets中有相应扩展 + Uploader.options = {}; + Mediator.installTo( Uploader.prototype ); + + // 批量添加纯命令式方法。 + $.each({ + upload: 'start-upload', + stop: 'stop-upload', + getFile: 'get-file', + getFiles: 'get-files', + addFile: 'add-file', + addFiles: 'add-file', + sort: 'sort-files', + removeFile: 'remove-file', + cancelFile: 'cancel-file', + skipFile: 'skip-file', + retry: 'retry', + isInProgress: 'is-in-progress', + makeThumb: 'make-thumb', + md5File: 'md5-file', + getDimension: 'get-dimension', + addButton: 'add-btn', + predictRuntimeType: 'predict-runtime-type', + refresh: 'refresh', + disable: 'disable', + enable: 'enable', + reset: 'reset' + }, function( fn, command ) { + Uploader.prototype[ fn ] = function() { + return this.request( command, arguments ); + }; + }); + + $.extend( Uploader.prototype, { + state: 'pending', + + _init: function( opts ) { + var me = this; + + me.request( 'init', opts, function() { + me.state = 'ready'; + me.trigger('ready'); + }); + }, + + /** + * 获取或者设置Uploader配置项。 + * @method option + * @grammar option( key ) => * + * @grammar option( key, val ) => self + * @example + * + * // 初始状态图片上传前不会压缩 + * var uploader = new WebUploader.Uploader({ + * compress: null; + * }); + * + * // 修改后图片上传前,尝试将图片压缩到1600 * 1600 + * uploader.option( 'compress', { + * width: 1600, + * height: 1600 + * }); + */ + option: function( key, val ) { + var opts = this.options; + + // setter + if ( arguments.length > 1 ) { + + if ( $.isPlainObject( val ) && + $.isPlainObject( opts[ key ] ) ) { + $.extend( opts[ key ], val ); + } else { + opts[ key ] = val; + } + + } else { // getter + return key ? opts[ key ] : opts; + } + }, + + /** + * 获取文件统计信息。返回一个包含一下信息的对象。 + * * `successNum` 上传成功的文件数 + * * `progressNum` 上传中的文件数 + * * `cancelNum` 被删除的文件数 + * * `invalidNum` 无效的文件数 + * * `uploadFailNum` 上传失败的文件数 + * * `queueNum` 还在队列中的文件数 + * * `interruptNum` 被暂停的文件数 + * @method getStats + * @grammar getStats() => Object + */ + getStats: function() { + // return this._mgr.getStats.apply( this._mgr, arguments ); + var stats = this.request('get-stats'); + + return stats ? { + successNum: stats.numOfSuccess, + progressNum: stats.numOfProgress, + + // who care? + // queueFailNum: 0, + cancelNum: stats.numOfCancel, + invalidNum: stats.numOfInvalid, + uploadFailNum: stats.numOfUploadFailed, + queueNum: stats.numOfQueue, + interruptNum: stats.numofInterrupt + } : {}; + }, + + // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器 + trigger: function( type/*, args...*/ ) { + var args = [].slice.call( arguments, 1 ), + opts = this.options, + name = 'on' + type.substring( 0, 1 ).toUpperCase() + + type.substring( 1 ); + + if ( + // 调用通过on方法注册的handler. + Mediator.trigger.apply( this, arguments ) === false || + + // 调用opts.onEvent + $.isFunction( opts[ name ] ) && + opts[ name ].apply( this, args ) === false || + + // 调用this.onEvent + $.isFunction( this[ name ] ) && + this[ name ].apply( this, args ) === false || + + // 广播所有uploader的事件。 + Mediator.trigger.apply( Mediator, + [ this, type ].concat( args ) ) === false ) { + + return false; + } + + return true; + }, + + /** + * 销毁 webuploader 实例 + * @method destroy + * @grammar destroy() => undefined + */ + destroy: function() { + this.request( 'destroy', arguments ); + this.off(); + }, + + // widgets/widget.js将补充此方法的详细文档。 + request: Base.noop + }); + + /** + * 创建Uploader实例,等同于new Uploader( opts ); + * @method create + * @class Base + * @static + * @grammar Base.create( opts ) => Uploader + */ + Base.create = Uploader.create = function( opts ) { + return new Uploader( opts ); + }; + + // 暴露Uploader,可以通过它来扩展业务逻辑。 + Base.Uploader = Uploader; + + return Uploader; + }); + /** + * @fileOverview Runtime管理器,负责Runtime的选择, 连接 + */ + define('runtime/runtime',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$, + factories = {}, + + // 获取对象的第一个key + getFirstKey = function( obj ) { + for ( var key in obj ) { + if ( obj.hasOwnProperty( key ) ) { + return key; + } + } + return null; + }; + + // 接口类。 + function Runtime( options ) { + this.options = $.extend({ + container: document.body + }, options ); + this.uid = Base.guid('rt_'); + } + + $.extend( Runtime.prototype, { + + getContainer: function() { + var opts = this.options, + parent, container; + + if ( this._container ) { + return this._container; + } + + parent = $( opts.container || document.body ); + container = $( document.createElement('div') ); + + container.attr( 'id', 'rt_' + this.uid ); + container.css({ + position: 'absolute', + top: '0px', + left: '0px', + width: '1px', + height: '1px', + overflow: 'hidden' + }); + + parent.append( container ); + parent.addClass('webuploader-container'); + this._container = container; + this._parent = parent; + return container; + }, + + init: Base.noop, + exec: Base.noop, + + destroy: function() { + this._container && this._container.remove(); + this._parent && this._parent.removeClass('webuploader-container'); + this.off(); + } + }); + + Runtime.orders = 'html5,flash'; + + + /** + * 添加Runtime实现。 + * @param {String} type 类型 + * @param {Runtime} factory 具体Runtime实现。 + */ + Runtime.addRuntime = function( type, factory ) { + factories[ type ] = factory; + }; + + Runtime.hasRuntime = function( type ) { + return !!(type ? factories[ type ] : getFirstKey( factories )); + }; + + Runtime.create = function( opts, orders ) { + var type, runtime; + + orders = orders || Runtime.orders; + $.each( orders.split( /\s*,\s*/g ), function() { + if ( factories[ this ] ) { + type = this; + return false; + } + }); + + type = type || getFirstKey( factories ); + + if ( !type ) { + throw new Error('Runtime Error'); + } + + runtime = new factories[ type ]( opts ); + return runtime; + }; + + Mediator.installTo( Runtime.prototype ); + return Runtime; + }); + + /** + * @fileOverview Runtime管理器,负责Runtime的选择, 连接 + */ + define('runtime/client',[ + 'base', + 'mediator', + 'runtime/runtime' + ], function( Base, Mediator, Runtime ) { + + var cache; + + cache = (function() { + var obj = {}; + + return { + add: function( runtime ) { + obj[ runtime.uid ] = runtime; + }, + + get: function( ruid, standalone ) { + var i; + + if ( ruid ) { + return obj[ ruid ]; + } + + for ( i in obj ) { + // 有些类型不能重用,比如filepicker. + if ( standalone && obj[ i ].__standalone ) { + continue; + } + + return obj[ i ]; + } + + return null; + }, + + remove: function( runtime ) { + delete obj[ runtime.uid ]; + } + }; + })(); + + function RuntimeClient( component, standalone ) { + var deferred = Base.Deferred(), + runtime; + + this.uid = Base.guid('client_'); + + // 允许runtime没有初始化之前,注册一些方法在初始化后执行。 + this.runtimeReady = function( cb ) { + return deferred.done( cb ); + }; + + this.connectRuntime = function( opts, cb ) { + + // already connected. + if ( runtime ) { + throw new Error('already connected!'); + } + + deferred.done( cb ); + + if ( typeof opts === 'string' && cache.get( opts ) ) { + runtime = cache.get( opts ); + } + + // 像filePicker只能独立存在,不能公用。 + runtime = runtime || cache.get( null, standalone ); + + // 需要创建 + if ( !runtime ) { + runtime = Runtime.create( opts, opts.runtimeOrder ); + runtime.__promise = deferred.promise(); + runtime.once( 'ready', deferred.resolve ); + runtime.init(); + cache.add( runtime ); + runtime.__client = 1; + } else { + // 来自cache + Base.$.extend( runtime.options, opts ); + runtime.__promise.then( deferred.resolve ); + runtime.__client++; + } + + standalone && (runtime.__standalone = standalone); + return runtime; + }; + + this.getRuntime = function() { + return runtime; + }; + + this.disconnectRuntime = function() { + if ( !runtime ) { + return; + } + + runtime.__client--; + + if ( runtime.__client <= 0 ) { + cache.remove( runtime ); + delete runtime.__promise; + runtime.destroy(); + } + + runtime = null; + }; + + this.exec = function() { + if ( !runtime ) { + return; + } + + var args = Base.slice( arguments ); + component && args.unshift( component ); + + return runtime.exec.apply( this, args ); + }; + + this.getRuid = function() { + return runtime && runtime.uid; + }; + + this.destroy = (function( destroy ) { + return function() { + destroy && destroy.apply( this, arguments ); + this.trigger('destroy'); + this.off(); + this.exec('destroy'); + this.disconnectRuntime(); + }; + })( this.destroy ); + } + + Mediator.installTo( RuntimeClient.prototype ); + return RuntimeClient; + }); + /** + * @fileOverview 错误信息 + */ + define('lib/dnd',[ + 'base', + 'mediator', + 'runtime/client' + ], function( Base, Mediator, RuntimeClent ) { + + var $ = Base.$; + + function DragAndDrop( opts ) { + opts = this.options = $.extend({}, DragAndDrop.options, opts ); + + opts.container = $( opts.container ); + + if ( !opts.container.length ) { + return; + } + + RuntimeClent.call( this, 'DragAndDrop' ); + } + + DragAndDrop.options = { + accept: null, + disableGlobalDnd: false + }; + + Base.inherits( RuntimeClent, { + constructor: DragAndDrop, + + init: function() { + var me = this; + + me.connectRuntime( me.options, function() { + me.exec('init'); + me.trigger('ready'); + }); + } + }); + + Mediator.installTo( DragAndDrop.prototype ); + + return DragAndDrop; + }); + /** + * @fileOverview 组件基类。 + */ + define('widgets/widget',[ + 'base', + 'uploader' + ], function( Base, Uploader ) { + + var $ = Base.$, + _init = Uploader.prototype._init, + _destroy = Uploader.prototype.destroy, + IGNORE = {}, + widgetClass = []; + + function isArrayLike( obj ) { + if ( !obj ) { + return false; + } + + var length = obj.length, + type = $.type( obj ); + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === 'array' || type !== 'function' && type !== 'string' && + (length === 0 || typeof length === 'number' && length > 0 && + (length - 1) in obj); + } + + function Widget( uploader ) { + this.owner = uploader; + this.options = uploader.options; + } + + $.extend( Widget.prototype, { + + init: Base.noop, + + // 类Backbone的事件监听声明,监听uploader实例上的事件 + // widget直接无法监听事件,事件只能通过uploader来传递 + invoke: function( apiName, args ) { + + /* + { + 'make-thumb': 'makeThumb' + } + */ + var map = this.responseMap; + + // 如果无API响应声明则忽略 + if ( !map || !(apiName in map) || !(map[ apiName ] in this) || + !$.isFunction( this[ map[ apiName ] ] ) ) { + + return IGNORE; + } + + return this[ map[ apiName ] ].apply( this, args ); + + }, + + /** + * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。 + * @method request + * @grammar request( command, args ) => * | Promise + * @grammar request( command, args, callback ) => Promise + * @for Uploader + */ + request: function() { + return this.owner.request.apply( this.owner, arguments ); + } + }); + + // 扩展Uploader. + $.extend( Uploader.prototype, { + + /** + * @property {String | Array} [disableWidgets=undefined] + * @namespace options + * @for Uploader + * @description 默认所有 Uploader.register 了的 widget 都会被加载,如果禁用某一部分,请通过此 option 指定黑名单。 + */ + + // 覆写_init用来初始化widgets + _init: function() { + var me = this, + widgets = me._widgets = [], + deactives = me.options.disableWidgets || ''; + + $.each( widgetClass, function( _, klass ) { + (!deactives || !~deactives.indexOf( klass._name )) && + widgets.push( new klass( me ) ); + }); + + return _init.apply( me, arguments ); + }, + + request: function( apiName, args, callback ) { + var i = 0, + widgets = this._widgets, + len = widgets && widgets.length, + rlts = [], + dfds = [], + widget, rlt, promise, key; + + args = isArrayLike( args ) ? args : [ args ]; + + for ( ; i < len; i++ ) { + widget = widgets[ i ]; + rlt = widget.invoke( apiName, args ); + + if ( rlt !== IGNORE ) { + + // Deferred对象 + if ( Base.isPromise( rlt ) ) { + dfds.push( rlt ); + } else { + rlts.push( rlt ); + } + } + } + + // 如果有callback,则用异步方式。 + if ( callback || dfds.length ) { + promise = Base.when.apply( Base, dfds ); + key = promise.pipe ? 'pipe' : 'then'; + + // 很重要不能删除。删除了会死循环。 + // 保证执行顺序。让callback总是在下一个 tick 中执行。 + return promise[ key ](function() { + var deferred = Base.Deferred(), + args = arguments; + + if ( args.length === 1 ) { + args = args[ 0 ]; + } + + setTimeout(function() { + deferred.resolve( args ); + }, 1 ); + + return deferred.promise(); + })[ callback ? key : 'done' ]( callback || Base.noop ); + } else { + return rlts[ 0 ]; + } + }, + + destroy: function() { + _destroy.apply( this, arguments ); + this._widgets = null; + } + }); + + /** + * 添加组件 + * @grammar Uploader.register(proto); + * @grammar Uploader.register(map, proto); + * @param {object} responseMap API 名称与函数实现的映射 + * @param {object} proto 组件原型,构造函数通过 constructor 属性定义 + * @method Uploader.register + * @for Uploader + * @example + * Uploader.register({ + * 'make-thumb': 'makeThumb' + * }, { + * init: function( options ) {}, + * makeThumb: function() {} + * }); + * + * Uploader.register({ + * 'make-thumb': function() { + * + * } + * }); + */ + Uploader.register = Widget.register = function( responseMap, widgetProto ) { + var map = { init: 'init', destroy: 'destroy', name: 'anonymous' }, + klass; + + if ( arguments.length === 1 ) { + widgetProto = responseMap; + + // 自动生成 map 表。 + $.each(widgetProto, function(key) { + if ( key[0] === '_' || key === 'name' ) { + key === 'name' && (map.name = widgetProto.name); + return; + } + + map[key.replace(/[A-Z]/g, '-$&').toLowerCase()] = key; + }); + + } else { + map = $.extend( map, responseMap ); + } + + widgetProto.responseMap = map; + klass = Base.inherits( Widget, widgetProto ); + klass._name = map.name; + widgetClass.push( klass ); + + return klass; + }; + + /** + * 删除插件,只有在注册时指定了名字的才能被删除。 + * @grammar Uploader.unRegister(name); + * @param {string} name 组件名字 + * @method Uploader.unRegister + * @for Uploader + * @example + * + * Uploader.register({ + * name: 'custom', + * + * 'make-thumb': function() { + * + * } + * }); + * + * Uploader.unRegister('custom'); + */ + Uploader.unRegister = Widget.unRegister = function( name ) { + if ( !name || name === 'anonymous' ) { + return; + } + + // 删除指定的插件。 + for ( var i = widgetClass.length; i--; ) { + if ( widgetClass[i]._name === name ) { + widgetClass.splice(i, 1) + } + } + }; + + return Widget; + }); + /** + * @fileOverview DragAndDrop Widget。 + */ + define('widgets/filednd',[ + 'base', + 'uploader', + 'lib/dnd', + 'widgets/widget' + ], function( Base, Uploader, Dnd ) { + var $ = Base.$; + + Uploader.options.dnd = ''; + + /** + * @property {Selector} [dnd=undefined] 指定Drag And Drop拖拽的容器,如果不指定,则不启动。 + * @namespace options + * @for Uploader + */ + + /** + * @property {Selector} [disableGlobalDnd=false] 是否禁掉整个页面的拖拽功能,如果不禁用,图片拖进来的时候会默认被浏览器打开。 + * @namespace options + * @for Uploader + */ + + /** + * @event dndAccept + * @param {DataTransferItemList} items DataTransferItem + * @description 阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API,且只能通过 mime-type 验证。 + * @for Uploader + */ + return Uploader.register({ + name: 'dnd', + + init: function( opts ) { + + if ( !opts.dnd || + this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + var me = this, + deferred = Base.Deferred(), + options = $.extend({}, { + disableGlobalDnd: opts.disableGlobalDnd, + container: opts.dnd, + accept: opts.accept + }), + dnd; + + this.dnd = dnd = new Dnd( options ); + + dnd.once( 'ready', deferred.resolve ); + dnd.on( 'drop', function( files ) { + me.request( 'add-file', [ files ]); + }); + + // 检测文件是否全部允许添加。 + dnd.on( 'accept', function( items ) { + return me.owner.trigger( 'dndAccept', items ); + }); + + dnd.init(); + + return deferred.promise(); + }, + + destroy: function() { + this.dnd && this.dnd.destroy(); + } + }); + }); + + /** + * @fileOverview 错误信息 + */ + define('lib/filepaste',[ + 'base', + 'mediator', + 'runtime/client' + ], function( Base, Mediator, RuntimeClent ) { + + var $ = Base.$; + + function FilePaste( opts ) { + opts = this.options = $.extend({}, opts ); + opts.container = $( opts.container || document.body ); + RuntimeClent.call( this, 'FilePaste' ); + } + + Base.inherits( RuntimeClent, { + constructor: FilePaste, + + init: function() { + var me = this; + + me.connectRuntime( me.options, function() { + me.exec('init'); + me.trigger('ready'); + }); + } + }); + + Mediator.installTo( FilePaste.prototype ); + + return FilePaste; + }); + /** + * @fileOverview 组件基类。 + */ + define('widgets/filepaste',[ + 'base', + 'uploader', + 'lib/filepaste', + 'widgets/widget' + ], function( Base, Uploader, FilePaste ) { + var $ = Base.$; + + /** + * @property {Selector} [paste=undefined] 指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为`document.body`. + * @namespace options + * @for Uploader + */ + return Uploader.register({ + name: 'paste', + + init: function( opts ) { + + if ( !opts.paste || + this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + var me = this, + deferred = Base.Deferred(), + options = $.extend({}, { + container: opts.paste, + accept: opts.accept + }), + paste; + + this.paste = paste = new FilePaste( options ); + + paste.once( 'ready', deferred.resolve ); + paste.on( 'paste', function( files ) { + me.owner.request( 'add-file', [ files ]); + }); + paste.init(); + + return deferred.promise(); + }, + + destroy: function() { + this.paste && this.paste.destroy(); + } + }); + }); + /** + * @fileOverview Blob + */ + define('lib/blob',[ + 'base', + 'runtime/client' + ], function( Base, RuntimeClient ) { + + function Blob( ruid, source ) { + var me = this; + + me.source = source; + me.ruid = ruid; + this.size = source.size || 0; + + // 如果没有指定 mimetype, 但是知道文件后缀。 + if ( !source.type && this.ext && + ~'jpg,jpeg,png,gif,bmp'.indexOf( this.ext ) ) { + this.type = 'image/' + (this.ext === 'jpg' ? 'jpeg' : this.ext); + } else { + this.type = source.type || 'application/octet-stream'; + } + + RuntimeClient.call( me, 'Blob' ); + this.uid = source.uid || this.uid; + + if ( ruid ) { + me.connectRuntime( ruid ); + } + } + + Base.inherits( RuntimeClient, { + constructor: Blob, + + slice: function( start, end ) { + return this.exec( 'slice', start, end ); + }, + + getSource: function() { + return this.source; + } + }); + + return Blob; + }); + /** + * 为了统一化Flash的File和HTML5的File而存在。 + * 以至于要调用Flash里面的File,也可以像调用HTML5版本的File一下。 + * @fileOverview File + */ + define('lib/file',[ + 'base', + 'lib/blob' + ], function( Base, Blob ) { + + var uid = 1, + rExt = /\.([^.]+)$/; + + function File( ruid, file ) { + var ext; + + this.name = file.name || ('untitled' + uid++); + ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : ''; + + // todo 支持其他类型文件的转换。 + // 如果有 mimetype, 但是文件名里面没有找出后缀规律 + if ( !ext && file.type ) { + ext = /\/(jpg|jpeg|png|gif|bmp)$/i.exec( file.type ) ? + RegExp.$1.toLowerCase() : ''; + this.name += '.' + ext; + } + + this.ext = ext; + this.lastModifiedDate = file.lastModifiedDate || + (new Date()).toLocaleString(); + + Blob.apply( this, arguments ); + } + + return Base.inherits( Blob, File ); + }); + + /** + * @fileOverview 错误信息 + */ + define('lib/filepicker',[ + 'base', + 'runtime/client', + 'lib/file' + ], function( Base, RuntimeClent, File ) { + + var $ = Base.$; + + function FilePicker( opts ) { + opts = this.options = $.extend({}, FilePicker.options, opts ); + + opts.container = $( opts.id ); + + if ( !opts.container.length ) { + throw new Error('按钮指定错误'); + } + + opts.innerHTML = opts.innerHTML || opts.label || + opts.container.html() || ''; + + opts.button = $( opts.button || document.createElement('div') ); + opts.button.html( opts.innerHTML ); + opts.container.html( opts.button ); + + RuntimeClent.call( this, 'FilePicker', true ); + } + + FilePicker.options = { + button: null, + container: null, + label: null, + innerHTML: null, + multiple: true, + accept: null, + name: 'file' + }; + + Base.inherits( RuntimeClent, { + constructor: FilePicker, + + init: function() { + var me = this, + opts = me.options, + button = opts.button; + + button.addClass('webuploader-pick'); + + me.on( 'all', function( type ) { + var files; + + switch ( type ) { + case 'mouseenter': + button.addClass('webuploader-pick-hover'); + break; + + case 'mouseleave': + button.removeClass('webuploader-pick-hover'); + break; + + case 'change': + files = me.exec('getFiles'); + me.trigger( 'select', $.map( files, function( file ) { + file = new File( me.getRuid(), file ); + + // 记录来源。 + file._refer = opts.container; + return file; + }), opts.container ); + break; + } + }); + + me.connectRuntime( opts, function() { + me.refresh(); + me.exec( 'init', opts ); + me.trigger('ready'); + }); + + this._resizeHandler = Base.bindFn( this.refresh, this ); + //$( window ).on( 'resize', this._resizeHandler ); + this.refresh(); + }, + + refresh: function() { + var shimContainer = this.getRuntime().getContainer(), + button = this.options.button, + width = button.outerWidth ? + button.outerWidth() : button.width(), + + height = button.outerHeight ? + button.outerHeight() : button.height(), + + pos = button.offset(); +//alert(height); + width && height && shimContainer.css({ + bottom: 'auto', + right: 'auto', + width: '120px', + height: '44px' + }).offset( pos ); + }, + + enable: function() { + var btn = this.options.button; + + btn.removeClass('webuploader-pick-disable'); + this.refresh(); + }, + + disable: function() { + var btn = this.options.button; + + this.getRuntime().getContainer().css({ + top: '-99999px' + }); + + btn.addClass('webuploader-pick-disable'); + }, + + destroy: function() { + var btn = this.options.button; + $( window ).off( 'resize', this._resizeHandler ); + btn.removeClass('webuploader-pick-disable webuploader-pick-hover ' + + 'webuploader-pick'); + } + }); + + return FilePicker; + }); + + /** + * @fileOverview 文件选择相关 + */ + define('widgets/filepicker',[ + 'base', + 'uploader', + 'lib/filepicker', + 'widgets/widget' + ], function( Base, Uploader, FilePicker ) { + var $ = Base.$; + + $.extend( Uploader.options, { + + /** + * @property {Selector | Object} [pick=undefined] + * @namespace options + * @for Uploader + * @description 指定选择文件的按钮容器,不指定则不创建按钮。 + * + * * `id` {Seletor|dom} 指定选择文件的按钮容器,不指定则不创建按钮。**注意** 这里虽然写的是 id, 但是不是只支持 id, 还支持 class, 或者 dom 节点。 + * * `label` {String} 请采用 `innerHTML` 代替 + * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。 + * * `multiple` {Boolean} 是否开起同时选择多个文件能力。 + */ + pick: null, + + /** + * @property {Arroy} [accept=null] + * @namespace options + * @for Uploader + * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表,所以这里需要分开指定。 + * + * * `title` {String} 文字描述 + * * `extensions` {String} 允许的文件后缀,不带点,多个用逗号分割。 + * * `mimeTypes` {String} 多个用逗号分割。 + * + * 如: + * + * ``` + * { + * title: 'Images', + * extensions: 'gif,jpg,jpeg,bmp,png', + * mimeTypes: 'image/*' + * } + * ``` + */ + accept: null/*{ + title: 'Images', + extensions: 'gif,jpg,jpeg,bmp,png', + mimeTypes: 'image/*' + }*/ + }); + + return Uploader.register({ + name: 'picker', + + init: function( opts ) { + this.pickers = []; + return opts.pick && this.addBtn( opts.pick ); + }, + + refresh: function() { + $.each( this.pickers, function() { + this.refresh(); + }); + }, + + /** + * @method addButton + * @for Uploader + * @grammar addButton( pick ) => Promise + * @description + * 添加文件选择按钮,如果一个按钮不够,需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。 + * @example + * uploader.addButton({ + * id: '#btnContainer', + * innerHTML: '选择文件' + * }); + */ + addBtn: function( pick ) { + var me = this, + opts = me.options, + accept = opts.accept, + promises = []; + + if ( !pick ) { + return; + } + + $.isPlainObject( pick ) || (pick = { + id: pick + }); + + $( pick.id ).each(function() { + var options, picker, deferred; + + deferred = Base.Deferred(); + + options = $.extend({}, pick, { + accept: $.isPlainObject( accept ) ? [ accept ] : accept, + swf: opts.swf, + runtimeOrder: opts.runtimeOrder, + id: this + }); + + picker = new FilePicker( options ); + + picker.once( 'ready', deferred.resolve ); + picker.on( 'select', function( files ) { + me.owner.request( 'add-file', [ files ]); + }); + picker.init(); + + me.pickers.push( picker ); + + promises.push( deferred.promise() ); + }); + + return Base.when.apply( Base, promises ); + }, + + disable: function() { + $.each( this.pickers, function() { + this.disable(); + }); + }, + + enable: function() { + $.each( this.pickers, function() { + this.enable(); + }); + }, + + destroy: function() { + $.each( this.pickers, function() { + this.destroy(); + }); + this.pickers = null; + } + }); + }); + /** + * @fileOverview Image + */ + define('lib/image',[ + 'base', + 'runtime/client', + 'lib/blob' + ], function( Base, RuntimeClient, Blob ) { + var $ = Base.$; + + // 构造器。 + function Image( opts ) { + this.options = $.extend({}, Image.options, opts ); + RuntimeClient.call( this, 'Image' ); + + this.on( 'load', function() { + this._info = this.exec('info'); + this._meta = this.exec('meta'); + }); + } + + // 默认选项。 + Image.options = { + + // 默认的图片处理质量 + quality: 90, + + // 是否裁剪 + crop: false, + + // 是否保留头部信息 + preserveHeaders: false, + + // 是否允许放大。 + allowMagnify: false + }; + + // 继承RuntimeClient. + Base.inherits( RuntimeClient, { + constructor: Image, + + info: function( val ) { + + // setter + if ( val ) { + this._info = val; + return this; + } + + // getter + return this._info; + }, + + meta: function( val ) { + + // setter + if ( val ) { + this._meta = val; + return this; + } + + // getter + return this._meta; + }, + + loadFromBlob: function( blob ) { + var me = this, + ruid = blob.getRuid(); + + this.connectRuntime( ruid, function() { + me.exec( 'init', me.options ); + me.exec( 'loadFromBlob', blob ); + }); + }, + + resize: function() { + var args = Base.slice( arguments ); + return this.exec.apply( this, [ 'resize' ].concat( args ) ); + }, + + crop: function() { + var args = Base.slice( arguments ); + return this.exec.apply( this, [ 'crop' ].concat( args ) ); + }, + + getAsDataUrl: function( type ) { + return this.exec( 'getAsDataUrl', type ); + }, + + getAsBlob: function( type ) { + var blob = this.exec( 'getAsBlob', type ); + + return new Blob( this.getRuid(), blob ); + } + }); + + return Image; + }); + /** + * @fileOverview 图片操作, 负责预览图片和上传前压缩图片 + */ + define('widgets/image',[ + 'base', + 'uploader', + 'lib/image', + 'widgets/widget' + ], function( Base, Uploader, Image ) { + + var $ = Base.$, + throttle; + + // 根据要处理的文件大小来节流,一次不能处理太多,会卡。 + throttle = (function( max ) { + var occupied = 0, + waiting = [], + tick = function() { + var item; + + while ( waiting.length && occupied < max ) { + item = waiting.shift(); + occupied += item[ 0 ]; + item[ 1 ](); + } + }; + + return function( emiter, size, cb ) { + waiting.push([ size, cb ]); + emiter.once( 'destroy', function() { + occupied -= size; + setTimeout( tick, 1 ); + }); + setTimeout( tick, 1 ); + }; + })( 5 * 1024 * 1024 ); + + $.extend( Uploader.options, { + + /** + * @property {Object} [thumb] + * @namespace options + * @for Uploader + * @description 配置生成缩略图的选项。 + * + * 默认为: + * + * ```javascript + * { + * width: 110, + * height: 110, + * + * // 图片质量,只有type为`image/jpeg`的时候才有效。 + * quality: 70, + * + * // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false. + * allowMagnify: true, + * + * // 是否允许裁剪。 + * crop: true, + * + * // 为空的话则保留原有图片格式。 + * // 否则强制转换成指定的类型。 + * type: 'image/jpeg' + * } + * ``` + */ + thumb: { + width: 110, + height: 110, + quality: 70, + allowMagnify: true, + crop: true, + preserveHeaders: false, + + // 为空的话则保留原有图片格式。 + // 否则强制转换成指定的类型。 + // IE 8下面 base64 大小不能超过 32K 否则预览失败,而非 jpeg 编码的图片很可 + // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg + type: 'image/jpeg' + }, + + /** + * @property {Object} [compress] + * @namespace options + * @for Uploader + * @description 配置压缩的图片的选项。如果此选项为`false`, 则图片在上传前不进行压缩。 + * + * 默认为: + * + * ```javascript + * { + * width: 1600, + * height: 1600, + * + * // 图片质量,只有type为`image/jpeg`的时候才有效。 + * quality: 90, + * + * // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false. + * allowMagnify: false, + * + * // 是否允许裁剪。 + * crop: false, + * + * // 是否保留头部meta信息。 + * preserveHeaders: true, + * + * // 如果发现压缩后文件大小比原来还大,则使用原来图片 + * // 此属性可能会影响图片自动纠正功能 + * noCompressIfLarger: false, + * + * // 单位字节,如果图片大小小于此值,不会采用压缩。 + * compressSize: 0 + * } + * ``` + */ + compress: { + width: 1600, + height: 1600, + quality: 90, + allowMagnify: false, + crop: false, + preserveHeaders: true + } + }); + + return Uploader.register({ + + name: 'image', + + + /** + * 生成缩略图,此过程为异步,所以需要传入`callback`。 + * 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。 + * + * 当 width 或者 height 的值介于 0 - 1 时,被当成百分比使用。 + * + * `callback`中可以接收到两个参数。 + * * 第一个为error,如果生成缩略图有错误,此error将为真。 + * * 第二个为ret, 缩略图的Data URL值。 + * + * **注意** + * Date URL在IE6/7中不支持,所以不用调用此方法了,直接显示一张暂不支持预览图片好了。 + * 也可以借助服务端,将 base64 数据传给服务端,生成一个临时文件供预览。 + * + * @method makeThumb + * @grammar makeThumb( file, callback ) => undefined + * @grammar makeThumb( file, callback, width, height ) => undefined + * @for Uploader + * @example + * + * uploader.on( 'fileQueued', function( file ) { + * var $li = ...; + * + * uploader.makeThumb( file, function( error, ret ) { + * if ( error ) { + * $li.text('预览错误'); + * } else { + * $li.append('<img alt="" src="' + ret + '" />'); + * } + * }); + * + * }); + */ + makeThumb: function( file, cb, width, height ) { + var opts, image; + + file = this.request( 'get-file', file ); + + // 只预览图片格式。 + if ( !file.type.match( /^image/ ) ) { + cb( true ); + return; + } + + opts = $.extend({}, this.options.thumb ); + + // 如果传入的是object. + if ( $.isPlainObject( width ) ) { + opts = $.extend( opts, width ); + width = null; + } + + width = width || opts.width; + height = height || opts.height; + + image = new Image( opts ); + + image.once( 'load', function() { + file._info = file._info || image.info(); + file._meta = file._meta || image.meta(); + + // 如果 width 的值介于 0 - 1 + // 说明设置的是百分比。 + if ( width <= 1 && width > 0 ) { + width = file._info.width * width; + } + + // 同样的规则应用于 height + if ( height <= 1 && height > 0 ) { + height = file._info.height * height; + } + + image.resize( width, height ); + }); + + // 当 resize 完后 + image.once( 'complete', function() { + cb( false, image.getAsDataUrl( opts.type ) ); + image.destroy(); + }); + + image.once( 'error', function( reason ) { + cb( reason || true ); + image.destroy(); + }); + + throttle( image, file.source.size, function() { + file._info && image.info( file._info ); + file._meta && image.meta( file._meta ); + image.loadFromBlob( file.source ); + }); + }, + + beforeSendFile: function( file ) { + var opts = this.options.compress || this.options.resize, + compressSize = opts && opts.compressSize || 0, + noCompressIfLarger = opts && opts.noCompressIfLarger || false, + image, deferred; + + file = this.request( 'get-file', file ); + + // 只压缩 jpeg 图片格式。 + // gif 可能会丢失针 + // bmp png 基本上尺寸都不大,且压缩比比较小。 + if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) || + file.size < compressSize || + file._compressed ) { + return; + } + + opts = $.extend({}, opts ); + deferred = Base.Deferred(); + + image = new Image( opts ); + + deferred.always(function() { + image.destroy(); + image = null; + }); + image.once( 'error', deferred.reject ); + image.once( 'load', function() { + var width = opts.width, + height = opts.height; + + file._info = file._info || image.info(); + file._meta = file._meta || image.meta(); + + // 如果 width 的值介于 0 - 1 + // 说明设置的是百分比。 + if ( width <= 1 && width > 0 ) { + width = file._info.width * width; + } + + // 同样的规则应用于 height + if ( height <= 1 && height > 0 ) { + height = file._info.height * height; + } + + image.resize( width, height ); + }); + + image.once( 'complete', function() { + var blob, size; + + // 移动端 UC / qq 浏览器的无图模式下 + // ctx.getImageData 处理大图的时候会报 Exception + // INDEX_SIZE_ERR: DOM Exception 1 + try { + blob = image.getAsBlob( opts.type ); + + size = file.size; + + // 如果压缩后,比原来还大则不用压缩后的。 + if ( !noCompressIfLarger || blob.size < size ) { + // file.source.destroy && file.source.destroy(); + file.source = blob; + file.size = blob.size; + + file.trigger( 'resize', blob.size, size ); + } + + // 标记,避免重复压缩。 + file._compressed = true; + deferred.resolve(); + } catch ( e ) { + // 出错了直接继续,让其上传原始图片 + deferred.resolve(); + } + }); + + file._info && image.info( file._info ); + file._meta && image.meta( file._meta ); + + image.loadFromBlob( file.source ); + return deferred.promise(); + } + }); + }); + /** + * @fileOverview 文件属性封装 + */ + define('file',[ + 'base', + 'mediator' + ], function( Base, Mediator ) { + + var $ = Base.$, + idPrefix = 'WU_FILE_', + idSuffix = 0, + rExt = /\.([^.]+)$/, + statusMap = {}; + + function gid() { + return idPrefix + idSuffix++; + } + + /** + * 文件类 + * @class File + * @constructor 构造函数 + * @grammar new File( source ) => File + * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。 + */ + function WUFile( source ) { + + /** + * 文件名,包括扩展名(后缀) + * @property name + * @type {string} + */ + this.name = source.name || 'Untitled'; + + /** + * 文件体积(字节) + * @property size + * @type {uint} + * @default 0 + */ + this.size = source.size || 0; + + /** + * 文件MIMETYPE类型,与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny) + * @property type + * @type {string} + * @default 'application/octet-stream' + */ + this.type = source.type || 'application/octet-stream'; + + /** + * 文件最后修改日期 + * @property lastModifiedDate + * @type {int} + * @default 当前时间戳 + */ + this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1); + + /** + * 文件ID,每个对象具有唯一ID,与文件名无关 + * @property id + * @type {string} + */ + this.id = gid(); + + /** + * 文件扩展名,通过文件名获取,例如test.png的扩展名为png + * @property ext + * @type {string} + */ + this.ext = rExt.exec( this.name ) ? RegExp.$1 : ''; + + + /** + * 状态文字说明。在不同的status语境下有不同的用途。 + * @property statusText + * @type {string} + */ + this.statusText = ''; + + // 存储文件状态,防止通过属性直接修改 + statusMap[ this.id ] = WUFile.Status.INITED; + + this.source = source; + this.loaded = 0; + + this.on( 'error', function( msg ) { + this.setStatus( WUFile.Status.ERROR, msg ); + }); + } + + $.extend( WUFile.prototype, { + + /** + * 设置状态,状态变化时会触发`change`事件。 + * @method setStatus + * @grammar setStatus( status[, statusText] ); + * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status) + * @param {String} [statusText=''] 状态说明,常在error时使用,用http, abort,server等来标记是由于什么原因导致文件错误。 + */ + setStatus: function( status, text ) { + + var prevStatus = statusMap[ this.id ]; + + typeof text !== 'undefined' && (this.statusText = text); + + if ( status !== prevStatus ) { + statusMap[ this.id ] = status; + /** + * 文件状态变化 + * @event statuschange + */ + this.trigger( 'statuschange', status, prevStatus ); + } + + }, + + /** + * 获取文件状态 + * @return {File.Status} + * @example + 文件状态具体包括以下几种类型: + { + // 初始化 + INITED: 0, + // 已入队列 + QUEUED: 1, + // 正在上传 + PROGRESS: 2, + // 上传出错 + ERROR: 3, + // 上传成功 + COMPLETE: 4, + // 上传取消 + CANCELLED: 5 + } + */ + getStatus: function() { + return statusMap[ this.id ]; + }, + + /** + * 获取文件原始信息。 + * @return {*} + */ + getSource: function() { + return this.source; + }, + + destroy: function() { + this.off(); + delete statusMap[ this.id ]; + } + }); + + Mediator.installTo( WUFile.prototype ); + + /** + * 文件状态值,具体包括以下几种类型: + * * `inited` 初始状态 + * * `queued` 已经进入队列, 等待上传 + * * `progress` 上传中 + * * `complete` 上传完成。 + * * `error` 上传出错,可重试 + * * `interrupt` 上传中断,可续传。 + * * `invalid` 文件不合格,不能重试上传。会自动从队列中移除。 + * * `cancelled` 文件被移除。 + * @property {Object} Status + * @namespace File + * @class File + * @static + */ + WUFile.Status = { + INITED: 'inited', // 初始状态 + QUEUED: 'queued', // 已经进入队列, 等待上传 + PROGRESS: 'progress', // 上传中 + ERROR: 'error', // 上传出错,可重试 + COMPLETE: 'complete', // 上传完成。 + CANCELLED: 'cancelled', // 上传取消。 + INTERRUPT: 'interrupt', // 上传中断,可续传。 + INVALID: 'invalid' // 文件不合格,不能重试上传。 + }; + + return WUFile; + }); + + /** + * @fileOverview 文件队列 + */ + define('queue',[ + 'base', + 'mediator', + 'file' + ], function( Base, Mediator, WUFile ) { + + var $ = Base.$, + STATUS = WUFile.Status; + + /** + * 文件队列, 用来存储各个状态中的文件。 + * @class Queue + * @extends Mediator + */ + function Queue() { + + /** + * 统计文件数。 + * * `numOfQueue` 队列中的文件数。 + * * `numOfSuccess` 上传成功的文件数 + * * `numOfCancel` 被取消的文件数 + * * `numOfProgress` 正在上传中的文件数 + * * `numOfUploadFailed` 上传错误的文件数。 + * * `numOfInvalid` 无效的文件数。 + * * `numofDeleted` 被移除的文件数。 + * @property {Object} stats + */ + this.stats = { + numOfQueue: 0, + numOfSuccess: 0, + numOfCancel: 0, + numOfProgress: 0, + numOfUploadFailed: 0, + numOfInvalid: 0, + numofDeleted: 0, + numofInterrupt: 0 + }; + + // 上传队列,仅包括等待上传的文件 + this._queue = []; + + // 存储所有文件 + this._map = {}; + } + + $.extend( Queue.prototype, { + + /** + * 将新文件加入对队列尾部 + * + * @method append + * @param {File} file 文件对象 + */ + append: function( file ) { + this._queue.push( file ); + this._fileAdded( file ); + return this; + }, + + /** + * 将新文件加入对队列头部 + * + * @method prepend + * @param {File} file 文件对象 + */ + prepend: function( file ) { + this._queue.unshift( file ); + this._fileAdded( file ); + return this; + }, + + /** + * 获取文件对象 + * + * @method getFile + * @param {String} fileId 文件ID + * @return {File} + */ + getFile: function( fileId ) { + if ( typeof fileId !== 'string' ) { + return fileId; + } + return this._map[ fileId ]; + }, + + /** + * 从队列中取出一个指定状态的文件。 + * @grammar fetch( status ) => File + * @method fetch + * @param {String} status [文件状态值](#WebUploader:File:File.Status) + * @return {File} [File](#WebUploader:File) + */ + fetch: function( status ) { + var len = this._queue.length, + i, file; + + status = status || STATUS.QUEUED; + + for ( i = 0; i < len; i++ ) { + file = this._queue[ i ]; + + if ( status === file.getStatus() ) { + return file; + } + } + + return null; + }, + + /** + * 对队列进行排序,能够控制文件上传顺序。 + * @grammar sort( fn ) => undefined + * @method sort + * @param {Function} fn 排序方法 + */ + sort: function( fn ) { + if ( typeof fn === 'function' ) { + this._queue.sort( fn ); + } + }, + + /** + * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。 + * @grammar getFiles( [status1[, status2 ...]] ) => Array + * @method getFiles + * @param {String} [status] [文件状态值](#WebUploader:File:File.Status) + */ + getFiles: function() { + var sts = [].slice.call( arguments, 0 ), + ret = [], + i = 0, + len = this._queue.length, + file; + + for ( ; i < len; i++ ) { + file = this._queue[ i ]; + + if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) { + continue; + } + + ret.push( file ); + } + + return ret; + }, + + /** + * 在队列中删除文件。 + * @grammar removeFile( file ) => Array + * @method removeFile + * @param {File} 文件对象。 + */ + removeFile: function( file ) { + var me = this, + existing = this._map[ file.id ]; + + if ( existing ) { + delete this._map[ file.id ]; + file.destroy(); + this.stats.numofDeleted++; + } + }, + + _fileAdded: function( file ) { + var me = this, + existing = this._map[ file.id ]; + + if ( !existing ) { + this._map[ file.id ] = file; + + file.on( 'statuschange', function( cur, pre ) { + me._onFileStatusChange( cur, pre ); + }); + } + }, + + _onFileStatusChange: function( curStatus, preStatus ) { + var stats = this.stats; + + switch ( preStatus ) { + case STATUS.PROGRESS: + stats.numOfProgress--; + break; + + case STATUS.QUEUED: + stats.numOfQueue --; + break; + + case STATUS.ERROR: + stats.numOfUploadFailed--; + break; + + case STATUS.INVALID: + stats.numOfInvalid--; + break; + + case STATUS.INTERRUPT: + stats.numofInterrupt--; + break; + } + + switch ( curStatus ) { + case STATUS.QUEUED: + stats.numOfQueue++; + break; + + case STATUS.PROGRESS: + stats.numOfProgress++; + break; + + case STATUS.ERROR: + stats.numOfUploadFailed++; + break; + + case STATUS.COMPLETE: + stats.numOfSuccess++; + break; + + case STATUS.CANCELLED: + stats.numOfCancel++; + break; + + + case STATUS.INVALID: + stats.numOfInvalid++; + break; + + case STATUS.INTERRUPT: + stats.numofInterrupt++; + break; + } + } + + }); + + Mediator.installTo( Queue.prototype ); + + return Queue; + }); + /** + * @fileOverview 队列 + */ + define('widgets/queue',[ + 'base', + 'uploader', + 'queue', + 'file', + 'lib/file', + 'runtime/client', + 'widgets/widget' + ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) { + + var $ = Base.$, + rExt = /\.\w+$/, + Status = WUFile.Status; + + return Uploader.register({ + name: 'queue', + + init: function( opts ) { + var me = this, + deferred, len, i, item, arr, accept, runtime; + + if ( $.isPlainObject( opts.accept ) ) { + opts.accept = [ opts.accept ]; + } + + // accept中的中生成匹配正则。 + if ( opts.accept ) { + arr = []; + + for ( i = 0, len = opts.accept.length; i < len; i++ ) { + item = opts.accept[ i ].extensions; + item && arr.push( item ); + } + + if ( arr.length ) { + accept = '\\.' + arr.join(',') + .replace( /,/g, '$|\\.' ) + .replace( /\*/g, '.*' ) + '$'; + } + + me.accept = new RegExp( accept, 'i' ); + } + + me.queue = new Queue(); + me.stats = me.queue.stats; + + // 如果当前不是html5运行时,那就算了。 + // 不执行后续操作 + if ( this.request('predict-runtime-type') !== 'html5' ) { + return; + } + + // 创建一个 html5 运行时的 placeholder + // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。 + deferred = Base.Deferred(); + this.placeholder = runtime = new RuntimeClient('Placeholder'); + runtime.connectRuntime({ + runtimeOrder: 'html5' + }, function() { + me._ruid = runtime.getRuid(); + deferred.resolve(); + }); + return deferred.promise(); + }, + + + // 为了支持外部直接添加一个原生File对象。 + _wrapFile: function( file ) { + if ( !(file instanceof WUFile) ) { + + if ( !(file instanceof File) ) { + if ( !this._ruid ) { + throw new Error('Can\'t add external files.'); + } + file = new File( this._ruid, file ); + } + + file = new WUFile( file ); + } + + return file; + }, + + // 判断文件是否可以被加入队列 + acceptFile: function( file ) { + var invalid = !file || !file.size || this.accept && + + // 如果名字中有后缀,才做后缀白名单处理。 + rExt.exec( file.name ) && !this.accept.test( file.name ); + + return !invalid; + }, + + + /** + * @event beforeFileQueued + * @param {File} file File对象 + * @description 当文件被加入队列之前触发,此事件的handler返回值为`false`,则此文件不会被添加进入队列。 + * @for Uploader + */ + + /** + * @event fileQueued + * @param {File} file File对象 + * @description 当文件被加入队列以后触发。 + * @for Uploader + */ + + _addFile: function( file ) { + var me = this; + + file = me._wrapFile( file ); + + // 不过类型判断允许不允许,先派送 `beforeFileQueued` + if ( !me.owner.trigger( 'beforeFileQueued', file ) ) { + return; + } + + // 类型不匹配,则派送错误事件,并返回。 + if ( !me.acceptFile( file ) ) { + me.owner.trigger( 'error', 'Q_TYPE_DENIED', file ); + return; + } + + me.queue.append( file ); + me.owner.trigger( 'fileQueued', file ); + return file; + }, + + getFile: function( fileId ) { + return this.queue.getFile( fileId ); + }, + + /** + * @event filesQueued + * @param {File} files 数组,内容为原始File(lib/File)对象。 + * @description 当一批文件添加进队列以后触发。 + * @for Uploader + */ + + /** + * @property {Boolean} [auto=false] + * @namespace options + * @for Uploader + * @description 设置为 true 后,不需要手动调用上传,有文件选择即开始上传。 + * + */ + + /** + * @method addFiles + * @grammar addFiles( file ) => undefined + * @grammar addFiles( [file1, file2 ...] ) => undefined + * @param {Array of File or File} [files] Files 对象 数组 + * @description 添加文件到队列 + * @for Uploader + */ + addFile: function( files ) { + var me = this; + + if ( !files.length ) { + files = [ files ]; + } + + files = $.map( files, function( file ) { + return me._addFile( file ); + }); + + me.owner.trigger( 'filesQueued', files ); + + if ( me.options.auto ) { + setTimeout(function() { + me.request('start-upload'); + }, 20 ); + } + }, + + getStats: function() { + return this.stats; + }, + + /** + * @event fileDequeued + * @param {File} file File对象 + * @description 当文件被移除队列后触发。 + * @for Uploader + */ + + /** + * @method removeFile + * @grammar removeFile( file ) => undefined + * @grammar removeFile( id ) => undefined + * @grammar removeFile( file, true ) => undefined + * @grammar removeFile( id, true ) => undefined + * @param {File|id} file File对象或这File对象的id + * @description 移除某一文件, 默认只会标记文件状态为已取消,如果第二个参数为 `true` 则会从 queue 中移除。 + * @for Uploader + * @example + * + * $li.on('click', '.remove-this', function() { + * uploader.removeFile( file ); + * }) + */ + removeFile: function( file, remove ) { + var me = this; + + file = file.id ? file : me.queue.getFile( file ); + + this.request( 'cancel-file', file ); + + if ( remove ) { + this.queue.removeFile( file ); + } + }, + + /** + * @method getFiles + * @grammar getFiles() => Array + * @grammar getFiles( status1, status2, status... ) => Array + * @description 返回指定状态的文件集合,不传参数将返回所有状态的文件。 + * @for Uploader + * @example + * console.log( uploader.getFiles() ); // => all files + * console.log( uploader.getFiles('error') ) // => all error files. + */ + getFiles: function() { + return this.queue.getFiles.apply( this.queue, arguments ); + }, + + fetchFile: function() { + return this.queue.fetch.apply( this.queue, arguments ); + }, + + /** + * @method retry + * @grammar retry() => undefined + * @grammar retry( file ) => undefined + * @description 重试上传,重试指定文件,或者从出错的文件开始重新上传。 + * @for Uploader + * @example + * function retry() { + * uploader.retry(); + * } + */ + retry: function( file, noForceStart ) { + var me = this, + files, i, len; + + if ( file ) { + file = file.id ? file : me.queue.getFile( file ); + file.setStatus( Status.QUEUED ); + noForceStart || me.request('start-upload'); + return; + } + + files = me.queue.getFiles( Status.ERROR ); + i = 0; + len = files.length; + + for ( ; i < len; i++ ) { + file = files[ i ]; + file.setStatus( Status.QUEUED ); + } + + me.request('start-upload'); + }, + + /** + * @method sort + * @grammar sort( fn ) => undefined + * @description 排序队列中的文件,在上传之前调整可以控制上传顺序。 + * @for Uploader + */ + sortFiles: function() { + return this.queue.sort.apply( this.queue, arguments ); + }, + + /** + * @event reset + * @description 当 uploader 被重置的时候触发。 + * @for Uploader + */ + + /** + * @method reset + * @grammar reset() => undefined + * @description 重置uploader。目前只重置了队列。 + * @for Uploader + * @example + * uploader.reset(); + */ + reset: function() { + this.owner.trigger('reset'); + this.queue = new Queue(); + this.stats = this.queue.stats; + }, + + destroy: function() { + this.reset(); + this.placeholder && this.placeholder.destroy(); + } + }); + + }); + /** + * @fileOverview 添加获取Runtime相关信息的方法。 + */ + define('widgets/runtime',[ + 'uploader', + 'runtime/runtime', + 'widgets/widget' + ], function( Uploader, Runtime ) { + + Uploader.support = function() { + return Runtime.hasRuntime.apply( Runtime, arguments ); + }; + + /** + * @property {Object} [runtimeOrder=html5,flash] + * @namespace options + * @for Uploader + * @description 指定运行时启动顺序。默认会想尝试 html5 是否支持,如果支持则使用 html5, 否则则使用 flash. + * + * 可以将此值设置成 `flash`,来强制使用 flash 运行时。 + */ + + return Uploader.register({ + name: 'runtime', + + init: function() { + if ( !this.predictRuntimeType() ) { + throw Error('Runtime Error'); + } + }, + + /** + * 预测Uploader将采用哪个`Runtime` + * @grammar predictRuntimeType() => String + * @method predictRuntimeType + * @for Uploader + */ + predictRuntimeType: function() { + var orders = this.options.runtimeOrder || Runtime.orders, + type = this.type, + i, len; + + if ( !type ) { + orders = orders.split( /\s*,\s*/g ); + + for ( i = 0, len = orders.length; i < len; i++ ) { + if ( Runtime.hasRuntime( orders[ i ] ) ) { + this.type = type = orders[ i ]; + break; + } + } + } + + return type; + } + }); + }); + /** + * @fileOverview Transport + */ + define('lib/transport',[ + 'base', + 'runtime/client', + 'mediator' + ], function( Base, RuntimeClient, Mediator ) { + + var $ = Base.$; + + function Transport( opts ) { + var me = this; + + opts = me.options = $.extend( true, {}, Transport.options, opts || {} ); + RuntimeClient.call( this, 'Transport' ); + + this._blob = null; + this._formData = opts.formData || {}; + this._headers = opts.headers || {}; + + this.on( 'progress', this._timeout ); + this.on( 'load error', function() { + me.trigger( 'progress', 1 ); + clearTimeout( me._timer ); + }); + } + + Transport.options = { + server: '', + method: 'POST', + + // 跨域时,是否允许携带cookie, 只有html5 runtime才有效 + withCredentials: false, + fileVal: 'file', + timeout: 2 * 60 * 1000, // 2分钟 + formData: {}, + headers: {}, + sendAsBinary: false + }; + + $.extend( Transport.prototype, { + + // 添加Blob, 只能添加一次,最后一次有效。 + appendBlob: function( key, blob, filename ) { + var me = this, + opts = me.options; + + if ( me.getRuid() ) { + me.disconnectRuntime(); + } + + // 连接到blob归属的同一个runtime. + me.connectRuntime( blob.ruid, function() { + me.exec('init'); + }); + + me._blob = blob; + opts.fileVal = key || opts.fileVal; + opts.filename = filename || opts.filename; + }, + + // 添加其他字段 + append: function( key, value ) { + if ( typeof key === 'object' ) { + $.extend( this._formData, key ); + } else { + this._formData[ key ] = value; + } + }, + + setRequestHeader: function( key, value ) { + if ( typeof key === 'object' ) { + $.extend( this._headers, key ); + } else { + this._headers[ key ] = value; + } + }, + + send: function( method ) { + this.exec( 'send', method ); + this._timeout(); + }, + + abort: function() { + clearTimeout( this._timer ); + return this.exec('abort'); + }, + + destroy: function() { + this.trigger('destroy'); + this.off(); + this.exec('destroy'); + this.disconnectRuntime(); + }, + + getResponse: function() { + return this.exec('getResponse'); + }, + + getResponseAsJson: function() { + return this.exec('getResponseAsJson'); + }, + + getStatus: function() { + return this.exec('getStatus'); + }, + + _timeout: function() { + var me = this, + duration = me.options.timeout; + + if ( !duration ) { + return; + } + + clearTimeout( me._timer ); + me._timer = setTimeout(function() { + me.abort(); + me.trigger( 'error', 'timeout' ); + }, duration ); + } + + }); + + // 让Transport具备事件功能。 + Mediator.installTo( Transport.prototype ); + + return Transport; + }); + /** + * @fileOverview 负责文件上传相关。 + */ + define('widgets/upload',[ + 'base', + 'uploader', + 'file', + 'lib/transport', + 'widgets/widget' + ], function( Base, Uploader, WUFile, Transport ) { + + var $ = Base.$, + isPromise = Base.isPromise, + Status = WUFile.Status; + + // 添加默认配置项 + $.extend( Uploader.options, { + + + /** + * @property {Boolean} [prepareNextFile=false] + * @namespace options + * @for Uploader + * @description 是否允许在文件传输时提前把下一个文件准备好。 + * 对于一个文件的准备工作比较耗时,比如图片压缩,md5序列化。 + * 如果能提前在当前文件传输期处理,可以节省总体耗时。 + */ + prepareNextFile: false, + + /** + * @property {Boolean} [chunked=false] + * @namespace options + * @for Uploader + * @description 是否要分片处理大文件上传。 + */ + chunked: false, + + /** + * @property {Boolean} [chunkSize=5242880] + * @namespace options + * @for Uploader + * @description 如果要分片,分多大一片? 默认大小为5M. + */ + chunkSize: 5 * 1024 * 1024, + + /** + * @property {Boolean} [chunkRetry=2] + * @namespace options + * @for Uploader + * @description 如果某个分片由于网络问题出错,允许自动重传多少次? + */ + chunkRetry: 2, + + /** + * @property {Boolean} [threads=3] + * @namespace options + * @for Uploader + * @description 上传并发数。允许同时最大上传进程数。 + */ + threads: 3, + + + /** + * @property {Object} [formData={}] + * @namespace options + * @for Uploader + * @description 文件上传请求的参数表,每次发送都会发送此对象中的参数。 + */ + formData: {} + + /** + * @property {Object} [fileVal='file'] + * @namespace options + * @for Uploader + * @description 设置文件上传域的name。 + */ + + /** + * @property {Object} [method='POST'] + * @namespace options + * @for Uploader + * @description 文件上传方式,`POST`或者`GET`。 + */ + + /** + * @property {Object} [sendAsBinary=false] + * @namespace options + * @for Uploader + * @description 是否已二进制的流的方式发送文件,这样整个上传内容`php://input`都为文件内容, + * 其他参数在$_GET数组中。 + */ + }); + + // 负责将文件切片。 + function CuteFile( file, chunkSize ) { + var pending = [], + blob = file.source, + total = blob.size, + chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1, + start = 0, + index = 0, + len, api; + + api = { + file: file, + + has: function() { + return !!pending.length; + }, + + shift: function() { + return pending.shift(); + }, + + unshift: function( block ) { + pending.unshift( block ); + } + }; + + while ( index < chunks ) { + len = Math.min( chunkSize, total - start ); + + pending.push({ + file: file, + start: start, + end: chunkSize ? (start + len) : total, + total: total, + chunks: chunks, + chunk: index++, + cuted: api + }); + start += len; + } + + file.blocks = pending.concat(); + file.remaning = pending.length; + + return api; + } + + Uploader.register({ + name: 'upload', + + init: function() { + var owner = this.owner, + me = this; + + this.runing = false; + this.progress = false; + + owner + .on( 'startUpload', function() { + me.progress = true; + }) + .on( 'uploadFinished', function() { + me.progress = false; + }); + + // 记录当前正在传的数据,跟threads相关 + this.pool = []; + + // 缓存分好片的文件。 + this.stack = []; + + // 缓存即将上传的文件。 + this.pending = []; + + // 跟踪还有多少分片在上传中但是没有完成上传。 + this.remaning = 0; + this.__tick = Base.bindFn( this._tick, this ); + + owner.on( 'uploadComplete', function( file ) { + + // 把其他块取消了。 + file.blocks && $.each( file.blocks, function( _, v ) { + v.transport && (v.transport.abort(), v.transport.destroy()); + delete v.transport; + }); + + delete file.blocks; + delete file.remaning; + }); + }, + + reset: function() { + this.request( 'stop-upload', true ); + this.runing = false; + this.pool = []; + this.stack = []; + this.pending = []; + this.remaning = 0; + this._trigged = false; + this._promise = null; + }, + + /** + * @event startUpload + * @description 当开始上传流程时触发。 + * @for Uploader + */ + + /** + * 开始上传。此方法可以从初始状态调用开始上传流程,也可以从暂停状态调用,继续上传流程。 + * + * 可以指定开始某一个文件。 + * @grammar upload() => undefined + * @grammar upload( file | fileId) => undefined + * @method upload + * @for Uploader + */ + startUpload: function(file) { + var me = this; + + // 移出invalid的文件 + $.each( me.request( 'get-files', Status.INVALID ), function() { + me.request( 'remove-file', this ); + }); + + // 如果指定了开始某个文件,则只开始指定文件。 + if ( file ) { + file = file.id ? file : me.request( 'get-file', file ); + + if (file.getStatus() === Status.INTERRUPT) { + $.each( me.pool, function( _, v ) { + + // 之前暂停过。 + if (v.file !== file) { + return; + } + + v.transport && v.transport.send(); + }); + + file.setStatus( Status.QUEUED ); + } else if (file.getStatus() === Status.PROGRESS) { + return; + } else { + file.setStatus( Status.QUEUED ); + } + } else { + $.each( me.request( 'get-files', [ Status.INITED ] ), function() { + this.setStatus( Status.QUEUED ); + }); + } + + if ( me.runing ) { + return; + } + + me.runing = true; + + var files = []; + + // 如果有暂停的,则续传 + $.each( me.pool, function( _, v ) { + var file = v.file; + + if ( file.getStatus() === Status.INTERRUPT ) { + files.push(file); + me._trigged = false; + v.transport && v.transport.send(); + } + }); + + var file; + while ( (file = files.shift()) ) { + file.setStatus( Status.PROGRESS ); + } + + file || $.each( me.request( 'get-files', + Status.INTERRUPT ), function() { + this.setStatus( Status.PROGRESS ); + }); + + me._trigged = false; + Base.nextTick( me.__tick ); + me.owner.trigger('startUpload'); + }, + + /** + * @event stopUpload + * @description 当开始上传流程暂停时触发。 + * @for Uploader + */ + + /** + * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。 + * + * 如果第一个参数是文件,则只暂停指定文件。 + * @grammar stop() => undefined + * @grammar stop( true ) => undefined + * @grammar stop( file ) => undefined + * @method stop + * @for Uploader + */ + stopUpload: function( file, interrupt ) { + var me = this; + + if (file === true) { + interrupt = file; + file = null; + } + + if ( me.runing === false ) { + return; + } + + // 如果只是暂停某个文件。 + if ( file ) { + file = file.id ? file : me.request( 'get-file', file ); + + if ( file.getStatus() !== Status.PROGRESS && + file.getStatus() !== Status.QUEUED ) { + return; + } + + file.setStatus( Status.INTERRUPT ); + $.each( me.pool, function( _, v ) { + + // 只 abort 指定的文件。 + if (v.file !== file) { + return; + } + + v.transport && v.transport.abort(); + me._putback(v); + me._popBlock(v); + }); + + return Base.nextTick( me.__tick ); + } + + me.runing = false; + + if (this._promise && this._promise.file) { + this._promise.file.setStatus( Status.INTERRUPT ); + } + + interrupt && $.each( me.pool, function( _, v ) { + v.transport && v.transport.abort(); + v.file.setStatus( Status.INTERRUPT ); + }); + + me.owner.trigger('stopUpload'); + }, + + /** + * @method cancelFile + * @grammar cancelFile( file ) => undefined + * @grammar cancelFile( id ) => undefined + * @param {File|id} file File对象或这File对象的id + * @description 标记文件状态为已取消, 同时将中断文件传输。 + * @for Uploader + * @example + * + * $li.on('click', '.remove-this', function() { + * uploader.cancelFile( file ); + * }) + */ + cancelFile: function( file ) { + file = file.id ? file : this.request( 'get-file', file ); + + // 如果正在上传。 + file.blocks && $.each( file.blocks, function( _, v ) { + var _tr = v.transport; + + if ( _tr ) { + _tr.abort(); + _tr.destroy(); + delete v.transport; + } + }); + + file.setStatus( Status.CANCELLED ); + this.owner.trigger( 'fileDequeued', file ); + }, + + /** + * 判断`Uplaode`r是否正在上传中。 + * @grammar isInProgress() => Boolean + * @method isInProgress + * @for Uploader + */ + isInProgress: function() { + return !!this.progress; + }, + + _getStats: function() { + return this.request('get-stats'); + }, + + /** + * 掉过一个文件上传,直接标记指定文件为已上传状态。 + * @grammar skipFile( file ) => undefined + * @method skipFile + * @for Uploader + */ + skipFile: function( file, status ) { + file = file.id ? file : this.request( 'get-file', file ); + + file.setStatus( status || Status.COMPLETE ); + file.skipped = true; + + // 如果正在上传。 + file.blocks && $.each( file.blocks, function( _, v ) { + var _tr = v.transport; + + if ( _tr ) { + _tr.abort(); + _tr.destroy(); + delete v.transport; + } + }); + + this.owner.trigger( 'uploadSkip', file ); + }, + + /** + * @event uploadFinished + * @description 当所有文件上传结束时触发。 + * @for Uploader + */ + _tick: function() { + var me = this, + opts = me.options, + fn, val; + + // 上一个promise还没有结束,则等待完成后再执行。 + if ( me._promise ) { + return me._promise.always( me.__tick ); + } + + // 还有位置,且还有文件要处理的话。 + if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) { + me._trigged = false; + + fn = function( val ) { + me._promise = null; + + // 有可能是reject过来的,所以要检测val的类型。 + val && val.file && me._startSend( val ); + Base.nextTick( me.__tick ); + }; + + me._promise = isPromise( val ) ? val.always( fn ) : fn( val ); + + // 没有要上传的了,且没有正在传输的了。 + } else if ( !me.remaning && !me._getStats().numOfQueue && + !me._getStats().numofInterrupt ) { + me.runing = false; + + me._trigged || Base.nextTick(function() { + me.owner.trigger('uploadFinished'); + }); + me._trigged = true; + } + }, + + _putback: function(block) { + var idx; + + block.cuted.unshift(block); + idx = this.stack.indexOf(block.cuted); + + if (!~idx) { + this.stack.unshift(block.cuted); + } + }, + + _getStack: function() { + var i = 0, + act; + + while ( (act = this.stack[ i++ ]) ) { + if ( act.has() && act.file.getStatus() === Status.PROGRESS ) { + return act; + } else if (!act.has() || + act.file.getStatus() !== Status.PROGRESS && + act.file.getStatus() !== Status.INTERRUPT ) { + + // 把已经处理完了的,或者,状态为非 progress(上传中)、 + // interupt(暂停中) 的移除。 + this.stack.splice( --i, 1 ); + } + } + + return null; + }, + + _nextBlock: function() { + var me = this, + opts = me.options, + act, next, done, preparing; + + // 如果当前文件还有没有需要传输的,则直接返回剩下的。 + if ( (act = this._getStack()) ) { + + // 是否提前准备下一个文件 + if ( opts.prepareNextFile && !me.pending.length ) { + me._prepareNextFile(); + } + + return act.shift(); + + // 否则,如果正在运行,则准备下一个文件,并等待完成后返回下个分片。 + } else if ( me.runing ) { + + // 如果缓存中有,则直接在缓存中取,没有则去queue中取。 + if ( !me.pending.length && me._getStats().numOfQueue ) { + me._prepareNextFile(); + } + + next = me.pending.shift(); + done = function( file ) { + if ( !file ) { + return null; + } + + act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 ); + me.stack.push(act); + return act.shift(); + }; + + // 文件可能还在prepare中,也有可能已经完全准备好了。 + if ( isPromise( next) ) { + preparing = next.file; + next = next[ next.pipe ? 'pipe' : 'then' ]( done ); + next.file = preparing; + return next; + } + + return done( next ); + } + }, + + + /** + * @event uploadStart + * @param {File} file File对象 + * @description 某个文件开始上传前触发,一个文件只会触发一次。 + * @for Uploader + */ + _prepareNextFile: function() { + var me = this, + file = me.request('fetch-file'), + pending = me.pending, + promise; + + if ( file ) { + promise = me.request( 'before-send-file', file, function() { + + // 有可能文件被skip掉了。文件被skip掉后,状态坑定不是Queued. + if ( file.getStatus() === Status.PROGRESS || + file.getStatus() === Status.INTERRUPT ) { + return file; + } + + return me._finishFile( file ); + }); + + me.owner.trigger( 'uploadStart', file ); + file.setStatus( Status.PROGRESS ); + + promise.file = file; + + // 如果还在pending中,则替换成文件本身。 + promise.done(function() { + var idx = $.inArray( promise, pending ); + + ~idx && pending.splice( idx, 1, file ); + }); + + // befeore-send-file的钩子就有错误发生。 + promise.fail(function( reason ) { + file.setStatus( Status.ERROR, reason ); + me.owner.trigger( 'uploadError', file, reason ); + me.owner.trigger( 'uploadComplete', file ); + }); + + pending.push( promise ); + } + }, + + // 让出位置了,可以让其他分片开始上传 + _popBlock: function( block ) { + var idx = $.inArray( block, this.pool ); + + this.pool.splice( idx, 1 ); + block.file.remaning--; + this.remaning--; + }, + + // 开始上传,可以被掉过。如果promise被reject了,则表示跳过此分片。 + _startSend: function( block ) { + var me = this, + file = block.file, + promise; + + // 有可能在 before-send-file 的 promise 期间改变了文件状态。 + // 如:暂停,取消 + // 我们不能中断 promise, 但是可以在 promise 完后,不做上传操作。 + if ( file.getStatus() !== Status.PROGRESS ) { + + // 如果是中断,则还需要放回去。 + if (file.getStatus() === Status.INTERRUPT) { + me._putback(block); + } + + return; + } + + me.pool.push( block ); + me.remaning++; + + // 如果没有分片,则直接使用原始的。 + // 不会丢失content-type信息。 + block.blob = block.chunks === 1 ? file.source : + file.source.slice( block.start, block.end ); + + // hook, 每个分片发送之前可能要做些异步的事情。 + promise = me.request( 'before-send', block, function() { + + // 有可能文件已经上传出错了,所以不需要再传输了。 + if ( file.getStatus() === Status.PROGRESS ) { + me._doSend( block ); + } else { + me._popBlock( block ); + Base.nextTick( me.__tick ); + } + }); + + // 如果为fail了,则跳过此分片。 + promise.fail(function() { + if ( file.remaning === 1 ) { + me._finishFile( file ).always(function() { + block.percentage = 1; + me._popBlock( block ); + me.owner.trigger( 'uploadComplete', file ); + Base.nextTick( me.__tick ); + }); + } else { + block.percentage = 1; + me.updateFileProgress( file ); + me._popBlock( block ); + Base.nextTick( me.__tick ); + } + }); + }, + + + /** + * @event uploadBeforeSend + * @param {Object} object + * @param {Object} data 默认的上传参数,可以扩展此对象来控制上传参数。 + * @param {Object} headers 可以扩展此对象来控制上传头部。 + * @description 当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。 + * @for Uploader + */ + + /** + * @event uploadAccept + * @param {Object} object + * @param {Object} ret 服务端的返回数据,json格式,如果服务端不是json格式,从ret._raw中取数据,自行解析。 + * @description 当某个文件上传到服务端响应后,会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。 + * @for Uploader + */ + + /** + * @event uploadProgress + * @param {File} file File对象 + * @param {Number} percentage 上传进度 + * @description 上传过程中触发,携带上传进度。 + * @for Uploader + */ + + + /** + * @event uploadError + * @param {File} file File对象 + * @param {String} reason 出错的code + * @description 当文件上传出错时触发。 + * @for Uploader + */ + + /** + * @event uploadSuccess + * @param {File} file File对象 + * @param {Object} response 服务端返回的数据 + * @description 当文件上传成功时触发。 + * @for Uploader + */ + + /** + * @event uploadComplete + * @param {File} [file] File对象 + * @description 不管成功或者失败,文件上传完成时触发。 + * @for Uploader + */ + + // 做上传操作。 + _doSend: function( block ) { + var me = this, + owner = me.owner, + opts = me.options, + file = block.file, + tr = new Transport( opts ), + data = $.extend({}, opts.formData ), + headers = $.extend({}, opts.headers ), + requestAccept, ret; + + block.transport = tr; + + tr.on( 'destroy', function() { + delete block.transport; + me._popBlock( block ); + Base.nextTick( me.__tick ); + }); + + // 广播上传进度。以文件为单位。 + tr.on( 'progress', function( percentage ) { + block.percentage = percentage; + me.updateFileProgress( file ); + }); + + // 用来询问,是否返回的结果是有错误的。 + requestAccept = function( reject ) { + var fn; + + ret = tr.getResponseAsJson() || {}; + ret._raw = tr.getResponse(); + fn = function( value ) { + reject = value; + }; + + // 服务端响应了,不代表成功了,询问是否响应正确。 + if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) { + reject = reject || 'server'; + } + + return reject; + }; + + // 尝试重试,然后广播文件上传出错。 + tr.on( 'error', function( type, flag ) { + block.retried = block.retried || 0; + + // 自动重试 + if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) && + block.retried < opts.chunkRetry ) { + + block.retried++; + tr.send(); + + } else { + + // http status 500 ~ 600 + if ( !flag && type === 'server' ) { + type = requestAccept( type ); + } + + file.setStatus( Status.ERROR, type ); + owner.trigger( 'uploadError', file, type ); + owner.trigger( 'uploadComplete', file ); + } + }); + + // 上传成功 + tr.on( 'load', function() { + var reason; + + // 如果非预期,转向上传出错。 + if ( (reason = requestAccept()) ) { + tr.trigger( 'error', reason, true ); + return; + } + + // 全部上传完成。 + if ( file.remaning === 1 ) { + me._finishFile( file, ret ); + } else { + tr.destroy(); + } + }); + + // 配置默认的上传字段。 + data = $.extend( data, { + id: file.id, + name: file.name, + type: file.type, + lastModifiedDate: file.lastModifiedDate, + size: file.size + }); + + block.chunks > 1 && $.extend( data, { + chunks: block.chunks, + chunk: block.chunk + }); + + // 在发送之间可以添加字段什么的。。。 + // 如果默认的字段不够使用,可以通过监听此事件来扩展 + owner.trigger( 'uploadBeforeSend', block, data, headers ); + + // 开始发送。 + tr.appendBlob( opts.fileVal, block.blob, file.name ); + tr.append( data ); + tr.setRequestHeader( headers ); + tr.send(); + }, + + // 完成上传。 + _finishFile: function( file, ret, hds ) { + var owner = this.owner; + + return owner + .request( 'after-send-file', arguments, function() { + file.setStatus( Status.COMPLETE ); + owner.trigger( 'uploadSuccess', file, ret, hds ); + }) + .fail(function( reason ) { + + // 如果外部已经标记为invalid什么的,不再改状态。 + if ( file.getStatus() === Status.PROGRESS ) { + file.setStatus( Status.ERROR, reason ); + } + + owner.trigger( 'uploadError', file, reason ); + }) + .always(function() { + owner.trigger( 'uploadComplete', file ); + }); + }, + + updateFileProgress: function(file) { + var totalPercent = 0, + uploaded = 0; + + if (!file.blocks) { + return; + } + + $.each( file.blocks, function( _, v ) { + uploaded += (v.percentage || 0) * (v.end - v.start); + }); + + totalPercent = uploaded / file.size; + this.owner.trigger( 'uploadProgress', file, totalPercent || 0 ); + } + + }); + }); + /** + * @fileOverview 各种验证,包括文件总大小是否超出、单文件是否超出和文件是否重复。 + */ + + define('widgets/validator',[ + 'base', + 'uploader', + 'file', + 'widgets/widget' + ], function( Base, Uploader, WUFile ) { + + var $ = Base.$, + validators = {}, + api; + + /** + * @event error + * @param {String} type 错误类型。 + * @description 当validate不通过时,会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误,目前有以下错误会在特定的情况下派送错来。 + * + * * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。 + * * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。 + * * `Q_TYPE_DENIED` 当文件类型不满足时触发。。 + * @for Uploader + */ + + // 暴露给外面的api + api = { + + // 添加验证器 + addValidator: function( type, cb ) { + validators[ type ] = cb; + }, + + // 移除验证器 + removeValidator: function( type ) { + delete validators[ type ]; + } + }; + + // 在Uploader初始化的时候启动Validators的初始化 + Uploader.register({ + name: 'validator', + + init: function() { + var me = this; + Base.nextTick(function() { + $.each( validators, function() { + this.call( me.owner ); + }); + }); + } + }); + + /** + * @property {int} [fileNumLimit=undefined] + * @namespace options + * @for Uploader + * @description 验证文件总数量, 超出则不允许加入队列。 + */ + api.addValidator( 'fileNumLimit', function() { + var uploader = this, + opts = uploader.options, + count = 0, + max = parseInt( opts.fileNumLimit, 10 ), + flag = true; + + if ( !max ) { + return; + } + + uploader.on( 'beforeFileQueued', function( file ) { + + if ( count >= max && flag ) { + flag = false; + this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file ); + setTimeout(function() { + flag = true; + }, 1 ); + } + + return count >= max ? false : true; + }); + + uploader.on( 'fileQueued', function() { + count++; + }); + + uploader.on( 'fileDequeued', function() { + count--; + }); + + uploader.on( 'reset', function() { + count = 0; + }); + }); + + + /** + * @property {int} [fileSizeLimit=undefined] + * @namespace options + * @for Uploader + * @description 验证文件总大小是否超出限制, 超出则不允许加入队列。 + */ + api.addValidator( 'fileSizeLimit', function() { + var uploader = this, + opts = uploader.options, + count = 0, + max = parseInt( opts.fileSizeLimit, 10 ), + flag = true; + + if ( !max ) { + return; + } + + uploader.on( 'beforeFileQueued', function( file ) { + var invalid = count + file.size > max; + + if ( invalid && flag ) { + flag = false; + this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file ); + setTimeout(function() { + flag = true; + }, 1 ); + } + + return invalid ? false : true; + }); + + uploader.on( 'fileQueued', function( file ) { + count += file.size; + }); + + uploader.on( 'fileDequeued', function( file ) { + count -= file.size; + }); + + uploader.on( 'reset', function() { + count = 0; + }); + }); + + /** + * @property {int} [fileSingleSizeLimit=undefined] + * @namespace options + * @for Uploader + * @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。 + */ + api.addValidator( 'fileSingleSizeLimit', function() { + var uploader = this, + opts = uploader.options, + max = opts.fileSingleSizeLimit; + + if ( !max ) { + return; + } + + uploader.on( 'beforeFileQueued', function( file ) { + + if ( file.size > max ) { + file.setStatus( WUFile.Status.INVALID, 'exceed_size' ); + this.trigger( 'error', 'F_EXCEED_SIZE', max, file ); + return false; + } + + }); + + }); + + /** + * @property {Boolean} [duplicate=undefined] + * @namespace options + * @for Uploader + * @description 去重, 根据文件名字、文件大小和最后修改时间来生成hash Key. + */ + api.addValidator( 'duplicate', function() { + var uploader = this, + opts = uploader.options, + mapping = {}; + + if ( opts.duplicate ) { + return; + } + + function hashString( str ) { + var hash = 0, + i = 0, + len = str.length, + _char; + + for ( ; i < len; i++ ) { + _char = str.charCodeAt( i ); + hash = _char + (hash << 6) + (hash << 16) - hash; + } + + return hash; + } + + uploader.on( 'beforeFileQueued', function( file ) { + var hash = file.__hash || (file.__hash = hashString( file.name + + file.size + file.lastModifiedDate )); + + // 已经重复了 + if ( mapping[ hash ] ) { + this.trigger( 'error', 'F_DUPLICATE', file ); + return false; + } + }); + + uploader.on( 'fileQueued', function( file ) { + var hash = file.__hash; + + hash && (mapping[ hash ] = true); + }); + + uploader.on( 'fileDequeued', function( file ) { + var hash = file.__hash; + + hash && (delete mapping[ hash ]); + }); + + uploader.on( 'reset', function() { + mapping = {}; + }); + }); + + return api; + }); + + /** + * @fileOverview Md5 + */ + define('lib/md5',[ + 'runtime/client', + 'mediator' + ], function( RuntimeClient, Mediator ) { + + function Md5() { + RuntimeClient.call( this, 'Md5' ); + } + + // 让 Md5 具备事件功能。 + Mediator.installTo( Md5.prototype ); + + Md5.prototype.loadFromBlob = function( blob ) { + var me = this; + + if ( me.getRuid() ) { + me.disconnectRuntime(); + } + + // 连接到blob归属的同一个runtime. + me.connectRuntime( blob.ruid, function() { + me.exec('init'); + me.exec( 'loadFromBlob', blob ); + }); + }; + + Md5.prototype.getResult = function() { + return this.exec('getResult'); + }; + + return Md5; + }); + /** + * @fileOverview 图片操作, 负责预览图片和上传前压缩图片 + */ + define('widgets/md5',[ + 'base', + 'uploader', + 'lib/md5', + 'lib/blob', + 'widgets/widget' + ], function( Base, Uploader, Md5, Blob ) { + + return Uploader.register({ + name: 'md5', + + + /** + * 计算文件 md5 值,返回一个 promise 对象,可以监听 progress 进度。 + * + * + * @method md5File + * @grammar md5File( file[, start[, end]] ) => promise + * @for Uploader + * @example + * + * uploader.on( 'fileQueued', function( file ) { + * var $li = ...; + * + * uploader.md5File( file ) + * + * // 及时显示进度 + * .progress(function(percentage) { + * console.log('Percentage:', percentage); + * }) + * + * // 完成 + * .then(function(val) { + * console.log('md5 result:', val); + * }); + * + * }); + */ + md5File: function( file, start, end ) { + var md5 = new Md5(), + deferred = Base.Deferred(), + blob = (file instanceof Blob) ? file : + this.request( 'get-file', file ).source; + + md5.on( 'progress load', function( e ) { + e = e || {}; + deferred.notify( e.total ? e.loaded / e.total : 1 ); + }); + + md5.on( 'complete', function() { + deferred.resolve( md5.getResult() ); + }); + + md5.on( 'error', function( reason ) { + deferred.reject( reason ); + }); + + if ( arguments.length > 1 ) { + start = start || 0; + end = end || 0; + start < 0 && (start = blob.size + start); + end < 0 && (end = blob.size + end); + end = Math.min( end, blob.size ); + blob = blob.slice( start, end ); + } + + md5.loadFromBlob( blob ); + + return deferred.promise(); + } + }); + }); + /** + * @fileOverview Runtime管理器,负责Runtime的选择, 连接 + */ + define('runtime/compbase',[],function() { + + function CompBase( owner, runtime ) { + + this.owner = owner; + this.options = owner.options; + + this.getRuntime = function() { + return runtime; + }; + + this.getRuid = function() { + return runtime.uid; + }; + + this.trigger = function() { + return owner.trigger.apply( owner, arguments ); + }; + } + + return CompBase; + }); + /** + * @fileOverview Html5Runtime + */ + define('runtime/html5/runtime',[ + 'base', + 'runtime/runtime', + 'runtime/compbase' + ], function( Base, Runtime, CompBase ) { + + var type = 'html5', + components = {}; + + function Html5Runtime() { + var pool = {}, + me = this, + destroy = this.destroy; + + Runtime.apply( me, arguments ); + me.type = type; + + + // 这个方法的调用者,实际上是RuntimeClient + me.exec = function( comp, fn/*, args...*/) { + var client = this, + uid = client.uid, + args = Base.slice( arguments, 2 ), + instance; + + if ( components[ comp ] ) { + instance = pool[ uid ] = pool[ uid ] || + new components[ comp ]( client, me ); + + if ( instance[ fn ] ) { + return instance[ fn ].apply( instance, args ); + } + } + }; + + me.destroy = function() { + // @todo 删除池子中的所有实例 + return destroy && destroy.apply( this, arguments ); + }; + } + + Base.inherits( Runtime, { + constructor: Html5Runtime, + + // 不需要连接其他程序,直接执行callback + init: function() { + var me = this; + setTimeout(function() { + me.trigger('ready'); + }, 1 ); + } + + }); + + // 注册Components + Html5Runtime.register = function( name, component ) { + var klass = components[ name ] = Base.inherits( CompBase, component ); + return klass; + }; + + // 注册html5运行时。 + // 只有在支持的前提下注册。 + if ( window.Blob && window.FileReader && window.DataView ) { + Runtime.addRuntime( type, Html5Runtime ); + } + + return Html5Runtime; + }); + /** + * @fileOverview Blob Html实现 + */ + define('runtime/html5/blob',[ + 'runtime/html5/runtime', + 'lib/blob' + ], function( Html5Runtime, Blob ) { + + return Html5Runtime.register( 'Blob', { + slice: function( start, end ) { + var blob = this.owner.source, + slice = blob.slice || blob.webkitSlice || blob.mozSlice; + + blob = slice.call( blob, start, end ); + + return new Blob( this.getRuid(), blob ); + } + }); + }); + /** + * @fileOverview FilePaste + */ + define('runtime/html5/dnd',[ + 'base', + 'runtime/html5/runtime', + 'lib/file' + ], function( Base, Html5Runtime, File ) { + + var $ = Base.$, + prefix = 'webuploader-dnd-'; + + return Html5Runtime.register( 'DragAndDrop', { + init: function() { + var elem = this.elem = this.options.container; + + this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this ); + this.dragOverHandler = Base.bindFn( this._dragOverHandler, this ); + this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this ); + this.dropHandler = Base.bindFn( this._dropHandler, this ); + this.dndOver = false; + + elem.on( 'dragenter', this.dragEnterHandler ); + elem.on( 'dragover', this.dragOverHandler ); + elem.on( 'dragleave', this.dragLeaveHandler ); + elem.on( 'drop', this.dropHandler ); + + if ( this.options.disableGlobalDnd ) { + $( document ).on( 'dragover', this.dragOverHandler ); + $( document ).on( 'drop', this.dropHandler ); + } + }, + + _dragEnterHandler: function( e ) { + var me = this, + denied = me._denied || false, + items; + + e = e.originalEvent || e; + + if ( !me.dndOver ) { + me.dndOver = true; + + // 注意只有 chrome 支持。 + items = e.dataTransfer.items; + + if ( items && items.length ) { + me._denied = denied = !me.trigger( 'accept', items ); + } + + me.elem.addClass( prefix + 'over' ); + me.elem[ denied ? 'addClass' : + 'removeClass' ]( prefix + 'denied' ); + } + + e.dataTransfer.dropEffect = denied ? 'none' : 'copy'; + + return false; + }, + + _dragOverHandler: function( e ) { + // 只处理框内的。 + var parentElem = this.elem.parent().get( 0 ); + if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { + return false; + } + + clearTimeout( this._leaveTimer ); + this._dragEnterHandler.call( this, e ); + + return false; + }, + + _dragLeaveHandler: function() { + var me = this, + handler; + + handler = function() { + me.dndOver = false; + me.elem.removeClass( prefix + 'over ' + prefix + 'denied' ); + }; + + clearTimeout( me._leaveTimer ); + me._leaveTimer = setTimeout( handler, 100 ); + return false; + }, + + _dropHandler: function( e ) { + var me = this, + ruid = me.getRuid(), + parentElem = me.elem.parent().get( 0 ), + dataTransfer, data; + + // 只处理框内的。 + if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) { + return false; + } + + e = e.originalEvent || e; + dataTransfer = e.dataTransfer; + + // 如果是页面内拖拽,还不能处理,不阻止事件。 + // 此处 ie11 下会报参数错误, + try { + data = dataTransfer.getData('text/html'); + } catch( err ) { + } + + if ( data ) { + return; + } + + me._getTansferFiles( dataTransfer, function( results ) { + me.trigger( 'drop', $.map( results, function( file ) { + return new File( ruid, file ); + }) ); + }); + + me.dndOver = false; + me.elem.removeClass( prefix + 'over' ); + return false; + }, + + // 如果传入 callback 则去查看文件夹,否则只管当前文件夹。 + _getTansferFiles: function( dataTransfer, callback ) { + var results = [], + promises = [], + items, files, file, item, i, len, canAccessFolder; + + items = dataTransfer.items; + files = dataTransfer.files; + + canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry); + + for ( i = 0, len = files.length; i < len; i++ ) { + file = files[ i ]; + item = items && items[ i ]; + + if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) { + + promises.push( this._traverseDirectoryTree( + item.webkitGetAsEntry(), results ) ); + } else { + results.push( file ); + } + } + + Base.when.apply( Base, promises ).done(function() { + + if ( !results.length ) { + return; + } + + callback( results ); + }); + }, + + _traverseDirectoryTree: function( entry, results ) { + var deferred = Base.Deferred(), + me = this; + + if ( entry.isFile ) { + entry.file(function( file ) { + results.push( file ); + deferred.resolve(); + }); + } else if ( entry.isDirectory ) { + entry.createReader().readEntries(function( entries ) { + var len = entries.length, + promises = [], + arr = [], // 为了保证顺序。 + i; + + for ( i = 0; i < len; i++ ) { + promises.push( me._traverseDirectoryTree( + entries[ i ], arr ) ); + } + + Base.when.apply( Base, promises ).then(function() { + results.push.apply( results, arr ); + deferred.resolve(); + }, deferred.reject ); + }); + } + + return deferred.promise(); + }, + + destroy: function() { + var elem = this.elem; + + // 还没 init 就调用 destroy + if (!elem) { + return; + } + + elem.off( 'dragenter', this.dragEnterHandler ); + elem.off( 'dragover', this.dragOverHandler ); + elem.off( 'dragleave', this.dragLeaveHandler ); + elem.off( 'drop', this.dropHandler ); + + if ( this.options.disableGlobalDnd ) { + $( document ).off( 'dragover', this.dragOverHandler ); + $( document ).off( 'drop', this.dropHandler ); + } + } + }); + }); + + /** + * @fileOverview FilePaste + */ + define('runtime/html5/filepaste',[ + 'base', + 'runtime/html5/runtime', + 'lib/file' + ], function( Base, Html5Runtime, File ) { + + return Html5Runtime.register( 'FilePaste', { + init: function() { + var opts = this.options, + elem = this.elem = opts.container, + accept = '.*', + arr, i, len, item; + + // accetp的mimeTypes中生成匹配正则。 + if ( opts.accept ) { + arr = []; + + for ( i = 0, len = opts.accept.length; i < len; i++ ) { + item = opts.accept[ i ].mimeTypes; + item && arr.push( item ); + } + + if ( arr.length ) { + accept = arr.join(','); + accept = accept.replace( /,/g, '|' ).replace( /\*/g, '.*' ); + } + } + this.accept = accept = new RegExp( accept, 'i' ); + this.hander = Base.bindFn( this._pasteHander, this ); + elem.on( 'paste', this.hander ); + }, + + _pasteHander: function( e ) { + var allowed = [], + ruid = this.getRuid(), + items, item, blob, i, len; + + e = e.originalEvent || e; + items = e.clipboardData.items; + + for ( i = 0, len = items.length; i < len; i++ ) { + item = items[ i ]; + + if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) { + continue; + } + + allowed.push( new File( ruid, blob ) ); + } + + if ( allowed.length ) { + // 不阻止非文件粘贴(文字粘贴)的事件冒泡 + e.preventDefault(); + e.stopPropagation(); + this.trigger( 'paste', allowed ); + } + }, + + destroy: function() { + this.elem.off( 'paste', this.hander ); + } + }); + }); + + /** + * @fileOverview FilePicker + */ + define('runtime/html5/filepicker',[ + 'base', + 'runtime/html5/runtime' + ], function( Base, Html5Runtime ) { + + var $ = Base.$; + + return Html5Runtime.register( 'FilePicker', { + init: function() { + var container = this.getRuntime().getContainer(), + me = this, + owner = me.owner, + opts = me.options, + label = this.label = $( document.createElement('label') ), + input = this.input = $( document.createElement('input') ), + arr, i, len, mouseHandler; + + input.attr( 'type', 'file' ); + input.attr( 'name', opts.name ); + input.addClass('webuploader-element-invisible'); + + label.on( 'click', function() { + input.trigger('click'); + }); + + label.css({ + opacity: 0, + width: '100%', + height: '100%', + display: 'block', + cursor: 'pointer', + background: '#ffffff' + }); + + if ( opts.multiple ) { + input.attr( 'multiple', 'multiple' ); + } + + // @todo Firefox不支持单独指定后缀 + if ( opts.accept && opts.accept.length > 0 ) { + arr = []; + + for ( i = 0, len = opts.accept.length; i < len; i++ ) { + arr.push( opts.accept[ i ].mimeTypes ); + } + + input.attr( 'accept', arr.join(',') ); + } + + container.append( input ); + container.append( label ); + + mouseHandler = function( e ) { + owner.trigger( e.type ); + }; + + input.on( 'change', function( e ) { + var fn = arguments.callee, + clone; + + me.files = e.target.files; + + // reset input + clone = this.cloneNode( true ); + clone.value = null; + this.parentNode.replaceChild( clone, this ); + + input.off(); + input = $( clone ).on( 'change', fn ) + .on( 'mouseenter mouseleave', mouseHandler ); + + owner.trigger('change'); + }); + + label.on( 'mouseenter mouseleave', mouseHandler ); + + }, + + + getFiles: function() { + return this.files; + }, + + destroy: function() { + this.input.off(); + this.label.off(); + } + }); + }); + /** + * Terms: + * + * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer + * @fileOverview Image控件 + */ + define('runtime/html5/util',[ + 'base' + ], function( Base ) { + + var urlAPI = window.createObjectURL && window || + window.URL && URL.revokeObjectURL && URL || + window.webkitURL, + createObjectURL = Base.noop, + revokeObjectURL = createObjectURL; + + if ( urlAPI ) { + + // 更安全的方式调用,比如android里面就能把context改成其他的对象。 + createObjectURL = function() { + return urlAPI.createObjectURL.apply( urlAPI, arguments ); + }; + + revokeObjectURL = function() { + return urlAPI.revokeObjectURL.apply( urlAPI, arguments ); + }; + } + + return { + createObjectURL: createObjectURL, + revokeObjectURL: revokeObjectURL, + + dataURL2Blob: function( dataURI ) { + var byteStr, intArray, ab, i, mimetype, parts; + + parts = dataURI.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + byteStr = atob( parts[ 1 ] ); + } else { + byteStr = decodeURIComponent( parts[ 1 ] ); + } + + ab = new ArrayBuffer( byteStr.length ); + intArray = new Uint8Array( ab ); + + for ( i = 0; i < byteStr.length; i++ ) { + intArray[ i ] = byteStr.charCodeAt( i ); + } + + mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ]; + + return this.arrayBufferToBlob( ab, mimetype ); + }, + + dataURL2ArrayBuffer: function( dataURI ) { + var byteStr, intArray, i, parts; + + parts = dataURI.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + byteStr = atob( parts[ 1 ] ); + } else { + byteStr = decodeURIComponent( parts[ 1 ] ); + } + + intArray = new Uint8Array( byteStr.length ); + + for ( i = 0; i < byteStr.length; i++ ) { + intArray[ i ] = byteStr.charCodeAt( i ); + } + + return intArray.buffer; + }, + + arrayBufferToBlob: function( buffer, type ) { + var builder = window.BlobBuilder || window.WebKitBlobBuilder, + bb; + + // android不支持直接new Blob, 只能借助blobbuilder. + if ( builder ) { + bb = new builder(); + bb.append( buffer ); + return bb.getBlob( type ); + } + + return new Blob([ buffer ], type ? { type: type } : {} ); + }, + + // 抽出来主要是为了解决android下面canvas.toDataUrl不支持jpeg. + // 你得到的结果是png. + canvasToDataUrl: function( canvas, type, quality ) { + return canvas.toDataURL( type, quality / 100 ); + }, + + // imagemeat会复写这个方法,如果用户选择加载那个文件了的话。 + parseMeta: function( blob, callback ) { + callback( false, {}); + }, + + // imagemeat会复写这个方法,如果用户选择加载那个文件了的话。 + updateImageHead: function( data ) { + return data; + } + }; + }); + /** + * Terms: + * + * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer + * @fileOverview Image控件 + */ + define('runtime/html5/imagemeta',[ + 'runtime/html5/util' + ], function( Util ) { + + var api; + + api = { + parsers: { + 0xffe1: [] + }, + + maxMetaDataSize: 262144, + + parse: function( blob, cb ) { + var me = this, + fr = new FileReader(); + + fr.onload = function() { + cb( false, me._parse( this.result ) ); + fr = fr.onload = fr.onerror = null; + }; + + fr.onerror = function( e ) { + cb( e.message ); + fr = fr.onload = fr.onerror = null; + }; + + blob = blob.slice( 0, me.maxMetaDataSize ); + fr.readAsArrayBuffer( blob.getSource() ); + }, + + _parse: function( buffer, noParse ) { + if ( buffer.byteLength < 6 ) { + return; + } + + var dataview = new DataView( buffer ), + offset = 2, + maxOffset = dataview.byteLength - 4, + headLength = offset, + ret = {}, + markerBytes, markerLength, parsers, i; + + if ( dataview.getUint16( 0 ) === 0xffd8 ) { + + while ( offset < maxOffset ) { + markerBytes = dataview.getUint16( offset ); + + if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef || + markerBytes === 0xfffe ) { + + markerLength = dataview.getUint16( offset + 2 ) + 2; + + if ( offset + markerLength > dataview.byteLength ) { + break; + } + + parsers = api.parsers[ markerBytes ]; + + if ( !noParse && parsers ) { + for ( i = 0; i < parsers.length; i += 1 ) { + parsers[ i ].call( api, dataview, offset, + markerLength, ret ); + } + } + + offset += markerLength; + headLength = offset; + } else { + break; + } + } + + if ( headLength > 6 ) { + if ( buffer.slice ) { + ret.imageHead = buffer.slice( 2, headLength ); + } else { + // Workaround for IE10, which does not yet + // support ArrayBuffer.slice: + ret.imageHead = new Uint8Array( buffer ) + .subarray( 2, headLength ); + } + } + } + + return ret; + }, + + updateImageHead: function( buffer, head ) { + var data = this._parse( buffer, true ), + buf1, buf2, bodyoffset; + + + bodyoffset = 2; + if ( data.imageHead ) { + bodyoffset = 2 + data.imageHead.byteLength; + } + + if ( buffer.slice ) { + buf2 = buffer.slice( bodyoffset ); + } else { + buf2 = new Uint8Array( buffer ).subarray( bodyoffset ); + } + + buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength ); + + buf1[ 0 ] = 0xFF; + buf1[ 1 ] = 0xD8; + buf1.set( new Uint8Array( head ), 2 ); + buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 ); + + return buf1.buffer; + } + }; + + Util.parseMeta = function() { + return api.parse.apply( api, arguments ); + }; + + Util.updateImageHead = function() { + return api.updateImageHead.apply( api, arguments ); + }; + + return api; + }); + /** + * 代码来自于:https://github.com/blueimp/JavaScript-Load-Image + * 暂时项目中只用了orientation. + * + * 去除了 Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail. + * @fileOverview EXIF解析 + */ + + // Sample + // ==================================== + // Make : Apple + // Model : iPhone 4S + // Orientation : 1 + // XResolution : 72 [72/1] + // YResolution : 72 [72/1] + // ResolutionUnit : 2 + // Software : QuickTime 7.7.1 + // DateTime : 2013:09:01 22:53:55 + // ExifIFDPointer : 190 + // ExposureTime : 0.058823529411764705 [1/17] + // FNumber : 2.4 [12/5] + // ExposureProgram : Normal program + // ISOSpeedRatings : 800 + // ExifVersion : 0220 + // DateTimeOriginal : 2013:09:01 22:52:51 + // DateTimeDigitized : 2013:09:01 22:52:51 + // ComponentsConfiguration : YCbCr + // ShutterSpeedValue : 4.058893515764426 + // ApertureValue : 2.5260688216892597 [4845/1918] + // BrightnessValue : -0.3126686601998395 + // MeteringMode : Pattern + // Flash : Flash did not fire, compulsory flash mode + // FocalLength : 4.28 [107/25] + // SubjectArea : [4 values] + // FlashpixVersion : 0100 + // ColorSpace : 1 + // PixelXDimension : 2448 + // PixelYDimension : 3264 + // SensingMethod : One-chip color area sensor + // ExposureMode : 0 + // WhiteBalance : Auto white balance + // FocalLengthIn35mmFilm : 35 + // SceneCaptureType : Standard + define('runtime/html5/imagemeta/exif',[ + 'base', + 'runtime/html5/imagemeta' + ], function( Base, ImageMeta ) { + + var EXIF = {}; + + EXIF.ExifMap = function() { + return this; + }; + + EXIF.ExifMap.prototype.map = { + 'Orientation': 0x0112 + }; + + EXIF.ExifMap.prototype.get = function( id ) { + return this[ id ] || this[ this.map[ id ] ]; + }; + + EXIF.exifTagTypes = { + // byte, 8-bit unsigned int: + 1: { + getValue: function( dataView, dataOffset ) { + return dataView.getUint8( dataOffset ); + }, + size: 1 + }, + + // ascii, 8-bit byte: + 2: { + getValue: function( dataView, dataOffset ) { + return String.fromCharCode( dataView.getUint8( dataOffset ) ); + }, + size: 1, + ascii: true + }, + + // short, 16 bit int: + 3: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint16( dataOffset, littleEndian ); + }, + size: 2 + }, + + // long, 32 bit int: + 4: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint32( dataOffset, littleEndian ); + }, + size: 4 + }, + + // rational = two long values, + // first is numerator, second is denominator: + 5: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getUint32( dataOffset, littleEndian ) / + dataView.getUint32( dataOffset + 4, littleEndian ); + }, + size: 8 + }, + + // slong, 32 bit signed int: + 9: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getInt32( dataOffset, littleEndian ); + }, + size: 4 + }, + + // srational, two slongs, first is numerator, second is denominator: + 10: { + getValue: function( dataView, dataOffset, littleEndian ) { + return dataView.getInt32( dataOffset, littleEndian ) / + dataView.getInt32( dataOffset + 4, littleEndian ); + }, + size: 8 + } + }; + + // undefined, 8-bit byte, value depending on field: + EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ]; + + EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length, + littleEndian ) { + + var tagType = EXIF.exifTagTypes[ type ], + tagSize, dataOffset, values, i, str, c; + + if ( !tagType ) { + Base.log('Invalid Exif data: Invalid tag type.'); + return; + } + + tagSize = tagType.size * length; + + // Determine if the value is contained in the dataOffset bytes, + // or if the value at the dataOffset is a pointer to the actual data: + dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8, + littleEndian ) : (offset + 8); + + if ( dataOffset + tagSize > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid data offset.'); + return; + } + + if ( length === 1 ) { + return tagType.getValue( dataView, dataOffset, littleEndian ); + } + + values = []; + + for ( i = 0; i < length; i += 1 ) { + values[ i ] = tagType.getValue( dataView, + dataOffset + i * tagType.size, littleEndian ); + } + + if ( tagType.ascii ) { + str = ''; + + // Concatenate the chars: + for ( i = 0; i < values.length; i += 1 ) { + c = values[ i ]; + + // Ignore the terminating NULL byte(s): + if ( c === '\u0000' ) { + break; + } + str += c; + } + + return str; + } + return values; + }; + + EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian, + data ) { + + var tag = dataView.getUint16( offset, littleEndian ); + data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset, + dataView.getUint16( offset + 2, littleEndian ), // tag type + dataView.getUint32( offset + 4, littleEndian ), // tag length + littleEndian ); + }; + + EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset, + littleEndian, data ) { + + var tagsNumber, dirEndOffset, i; + + if ( dirOffset + 6 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid directory offset.'); + return; + } + + tagsNumber = dataView.getUint16( dirOffset, littleEndian ); + dirEndOffset = dirOffset + 2 + 12 * tagsNumber; + + if ( dirEndOffset + 4 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid directory size.'); + return; + } + + for ( i = 0; i < tagsNumber; i += 1 ) { + this.parseExifTag( dataView, tiffOffset, + dirOffset + 2 + 12 * i, // tag offset + littleEndian, data ); + } + + // Return the offset to the next directory: + return dataView.getUint32( dirEndOffset, littleEndian ); + }; + + // EXIF.getExifThumbnail = function(dataView, offset, length) { + // var hexData, + // i, + // b; + // if (!length || offset + length > dataView.byteLength) { + // Base.log('Invalid Exif data: Invalid thumbnail data.'); + // return; + // } + // hexData = []; + // for (i = 0; i < length; i += 1) { + // b = dataView.getUint8(offset + i); + // hexData.push((b < 16 ? '0' : '') + b.toString(16)); + // } + // return 'data:image/jpeg,%' + hexData.join('%'); + // }; + + EXIF.parseExifData = function( dataView, offset, length, data ) { + + var tiffOffset = offset + 10, + littleEndian, dirOffset; + + // Check for the ASCII code for "Exif" (0x45786966): + if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) { + // No Exif data, might be XMP data instead + return; + } + if ( tiffOffset + 8 > dataView.byteLength ) { + Base.log('Invalid Exif data: Invalid segment size.'); + return; + } + + // Check for the two null bytes: + if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) { + Base.log('Invalid Exif data: Missing byte alignment offset.'); + return; + } + + // Check the byte alignment: + switch ( dataView.getUint16( tiffOffset ) ) { + case 0x4949: + littleEndian = true; + break; + + case 0x4D4D: + littleEndian = false; + break; + + default: + Base.log('Invalid Exif data: Invalid byte alignment marker.'); + return; + } + + // Check for the TIFF tag marker (0x002A): + if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) { + Base.log('Invalid Exif data: Missing TIFF marker.'); + return; + } + + // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal: + dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian ); + // Create the exif object to store the tags: + data.exif = new EXIF.ExifMap(); + // Parse the tags of the main image directory and retrieve the + // offset to the next directory, usually the thumbnail directory: + dirOffset = EXIF.parseExifTags( dataView, tiffOffset, + tiffOffset + dirOffset, littleEndian, data ); + + // 尝试读取缩略图 + // if ( dirOffset ) { + // thumbnailData = {exif: {}}; + // dirOffset = EXIF.parseExifTags( + // dataView, + // tiffOffset, + // tiffOffset + dirOffset, + // littleEndian, + // thumbnailData + // ); + + // // Check for JPEG Thumbnail offset: + // if (thumbnailData.exif[0x0201]) { + // data.exif.Thumbnail = EXIF.getExifThumbnail( + // dataView, + // tiffOffset + thumbnailData.exif[0x0201], + // thumbnailData.exif[0x0202] // Thumbnail data length + // ); + // } + // } + }; + + ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData ); + return EXIF; + }); + /** + * 这个方式性能不行,但是可以解决android里面的toDataUrl的bug + * android里面toDataUrl('image/jpege')得到的结果却是png. + * + * 所以这里没辙,只能借助这个工具 + * @fileOverview jpeg encoder + */ + define('runtime/html5/jpegencoder',[], function( require, exports, module ) { + + /* + Copyright (c) 2008, Adobe Systems Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Adobe Systems Incorporated nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /* + JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009 + + Basic GUI blocking jpeg encoder + */ + + function JPEGEncoder(quality) { + var self = this; + var fround = Math.round; + var ffloor = Math.floor; + var YTable = new Array(64); + var UVTable = new Array(64); + var fdtbl_Y = new Array(64); + var fdtbl_UV = new Array(64); + var YDC_HT; + var UVDC_HT; + var YAC_HT; + var UVAC_HT; + + var bitcode = new Array(65535); + var category = new Array(65535); + var outputfDCTQuant = new Array(64); + var DU = new Array(64); + var byteout = []; + var bytenew = 0; + var bytepos = 7; + + var YDU = new Array(64); + var UDU = new Array(64); + var VDU = new Array(64); + var clt = new Array(256); + var RGB_YUV_TABLE = new Array(2048); + var currentQuality; + + var ZigZag = [ + 0, 1, 5, 6,14,15,27,28, + 2, 4, 7,13,16,26,29,42, + 3, 8,12,17,25,30,41,43, + 9,11,18,24,31,40,44,53, + 10,19,23,32,39,45,52,54, + 20,22,33,38,46,51,55,60, + 21,34,37,47,50,56,59,61, + 35,36,48,49,57,58,62,63 + ]; + + var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0]; + var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; + var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d]; + var std_ac_luminance_values = [ + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12, + 0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07, + 0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0, + 0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16, + 0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39, + 0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49, + 0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69, + 0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79, + 0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98, + 0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7, + 0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5, + 0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4, + 0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea, + 0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0]; + var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11]; + var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77]; + var std_ac_chrominance_values = [ + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21, + 0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71, + 0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0, + 0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34, + 0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38, + 0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48, + 0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68, + 0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78, + 0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96, + 0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5, + 0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2, + 0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9, + 0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8, + 0xf9,0xfa + ]; + + function initQuantTables(sf){ + var YQT = [ + 16, 11, 10, 16, 24, 40, 51, 61, + 12, 12, 14, 19, 26, 58, 60, 55, + 14, 13, 16, 24, 40, 57, 69, 56, + 14, 17, 22, 29, 51, 87, 80, 62, + 18, 22, 37, 56, 68,109,103, 77, + 24, 35, 55, 64, 81,104,113, 92, + 49, 64, 78, 87,103,121,120,101, + 72, 92, 95, 98,112,100,103, 99 + ]; + + for (var i = 0; i < 64; i++) { + var t = ffloor((YQT[i]*sf+50)/100); + if (t < 1) { + t = 1; + } else if (t > 255) { + t = 255; + } + YTable[ZigZag[i]] = t; + } + var UVQT = [ + 17, 18, 24, 47, 99, 99, 99, 99, + 18, 21, 26, 66, 99, 99, 99, 99, + 24, 26, 56, 99, 99, 99, 99, 99, + 47, 66, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + ]; + for (var j = 0; j < 64; j++) { + var u = ffloor((UVQT[j]*sf+50)/100); + if (u < 1) { + u = 1; + } else if (u > 255) { + u = 255; + } + UVTable[ZigZag[j]] = u; + } + var aasf = [ + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + ]; + var k = 0; + for (var row = 0; row < 8; row++) + { + for (var col = 0; col < 8; col++) + { + fdtbl_Y[k] = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); + fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0)); + k++; + } + } + } + + function computeHuffmanTbl(nrcodes, std_table){ + var codevalue = 0; + var pos_in_table = 0; + var HT = new Array(); + for (var k = 1; k <= 16; k++) { + for (var j = 1; j <= nrcodes[k]; j++) { + HT[std_table[pos_in_table]] = []; + HT[std_table[pos_in_table]][0] = codevalue; + HT[std_table[pos_in_table]][1] = k; + pos_in_table++; + codevalue++; + } + codevalue*=2; + } + return HT; + } + + function initHuffmanTbl() + { + YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values); + UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values); + YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values); + UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values); + } + + function initCategoryNumber() + { + var nrlower = 1; + var nrupper = 2; + for (var cat = 1; cat <= 15; cat++) { + //Positive numbers + for (var nr = nrlower; nr<nrupper; nr++) { + category[32767+nr] = cat; + bitcode[32767+nr] = []; + bitcode[32767+nr][1] = cat; + bitcode[32767+nr][0] = nr; + } + //Negative numbers + for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) { + category[32767+nrneg] = cat; + bitcode[32767+nrneg] = []; + bitcode[32767+nrneg][1] = cat; + bitcode[32767+nrneg][0] = nrupper-1+nrneg; + } + nrlower <<= 1; + nrupper <<= 1; + } + } + + function initRGBYUVTable() { + for(var i = 0; i < 256;i++) { + RGB_YUV_TABLE[i] = 19595 * i; + RGB_YUV_TABLE[(i+ 256)>>0] = 38470 * i; + RGB_YUV_TABLE[(i+ 512)>>0] = 7471 * i + 0x8000; + RGB_YUV_TABLE[(i+ 768)>>0] = -11059 * i; + RGB_YUV_TABLE[(i+1024)>>0] = -21709 * i; + RGB_YUV_TABLE[(i+1280)>>0] = 32768 * i + 0x807FFF; + RGB_YUV_TABLE[(i+1536)>>0] = -27439 * i; + RGB_YUV_TABLE[(i+1792)>>0] = - 5329 * i; + } + } + + // IO functions + function writeBits(bs) + { + var value = bs[0]; + var posval = bs[1]-1; + while ( posval >= 0 ) { + if (value & (1 << posval) ) { + bytenew |= (1 << bytepos); + } + posval--; + bytepos--; + if (bytepos < 0) { + if (bytenew == 0xFF) { + writeByte(0xFF); + writeByte(0); + } + else { + writeByte(bytenew); + } + bytepos=7; + bytenew=0; + } + } + } + + function writeByte(value) + { + byteout.push(clt[value]); // write char directly instead of converting later + } + + function writeWord(value) + { + writeByte((value>>8)&0xFF); + writeByte((value )&0xFF); + } + + // DCT & quantization core + function fDCTQuant(data, fdtbl) + { + var d0, d1, d2, d3, d4, d5, d6, d7; + /* Pass 1: process rows. */ + var dataOff=0; + var i; + var I8 = 8; + var I64 = 64; + for (i=0; i<I8; ++i) + { + d0 = data[dataOff]; + d1 = data[dataOff+1]; + d2 = data[dataOff+2]; + d3 = data[dataOff+3]; + d4 = data[dataOff+4]; + d5 = data[dataOff+5]; + d6 = data[dataOff+6]; + d7 = data[dataOff+7]; + + var tmp0 = d0 + d7; + var tmp7 = d0 - d7; + var tmp1 = d1 + d6; + var tmp6 = d1 - d6; + var tmp2 = d2 + d5; + var tmp5 = d2 - d5; + var tmp3 = d3 + d4; + var tmp4 = d3 - d4; + + /* Even part */ + var tmp10 = tmp0 + tmp3; /* phase 2 */ + var tmp13 = tmp0 - tmp3; + var tmp11 = tmp1 + tmp2; + var tmp12 = tmp1 - tmp2; + + data[dataOff] = tmp10 + tmp11; /* phase 3 */ + data[dataOff+4] = tmp10 - tmp11; + + var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */ + data[dataOff+2] = tmp13 + z1; /* phase 5 */ + data[dataOff+6] = tmp13 - z1; + + /* Odd part */ + tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */ + var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */ + var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */ + var z3 = tmp11 * 0.707106781; /* c4 */ + + var z11 = tmp7 + z3; /* phase 5 */ + var z13 = tmp7 - z3; + + data[dataOff+5] = z13 + z2; /* phase 6 */ + data[dataOff+3] = z13 - z2; + data[dataOff+1] = z11 + z4; + data[dataOff+7] = z11 - z4; + + dataOff += 8; /* advance pointer to next row */ + } + + /* Pass 2: process columns. */ + dataOff = 0; + for (i=0; i<I8; ++i) + { + d0 = data[dataOff]; + d1 = data[dataOff + 8]; + d2 = data[dataOff + 16]; + d3 = data[dataOff + 24]; + d4 = data[dataOff + 32]; + d5 = data[dataOff + 40]; + d6 = data[dataOff + 48]; + d7 = data[dataOff + 56]; + + var tmp0p2 = d0 + d7; + var tmp7p2 = d0 - d7; + var tmp1p2 = d1 + d6; + var tmp6p2 = d1 - d6; + var tmp2p2 = d2 + d5; + var tmp5p2 = d2 - d5; + var tmp3p2 = d3 + d4; + var tmp4p2 = d3 - d4; + + /* Even part */ + var tmp10p2 = tmp0p2 + tmp3p2; /* phase 2 */ + var tmp13p2 = tmp0p2 - tmp3p2; + var tmp11p2 = tmp1p2 + tmp2p2; + var tmp12p2 = tmp1p2 - tmp2p2; + + data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */ + data[dataOff+32] = tmp10p2 - tmp11p2; + + var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */ + data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */ + data[dataOff+48] = tmp13p2 - z1p2; + + /* Odd part */ + tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */ + tmp11p2 = tmp5p2 + tmp6p2; + tmp12p2 = tmp6p2 + tmp7p2; + + /* The rotator is modified from fig 4-8 to avoid extra negations. */ + var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */ + var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */ + var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */ + var z3p2 = tmp11p2 * 0.707106781; /* c4 */ + + var z11p2 = tmp7p2 + z3p2; /* phase 5 */ + var z13p2 = tmp7p2 - z3p2; + + data[dataOff+40] = z13p2 + z2p2; /* phase 6 */ + data[dataOff+24] = z13p2 - z2p2; + data[dataOff+ 8] = z11p2 + z4p2; + data[dataOff+56] = z11p2 - z4p2; + + dataOff++; /* advance pointer to next column */ + } + + // Quantize/descale the coefficients + var fDCTQuant; + for (i=0; i<I64; ++i) + { + // Apply the quantization and scaling factor & Round to nearest integer + fDCTQuant = data[i]*fdtbl[i]; + outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0); + //outputfDCTQuant[i] = fround(fDCTQuant); + + } + return outputfDCTQuant; + } + + function writeAPP0() + { + writeWord(0xFFE0); // marker + writeWord(16); // length + writeByte(0x4A); // J + writeByte(0x46); // F + writeByte(0x49); // I + writeByte(0x46); // F + writeByte(0); // = "JFIF",'\0' + writeByte(1); // versionhi + writeByte(1); // versionlo + writeByte(0); // xyunits + writeWord(1); // xdensity + writeWord(1); // ydensity + writeByte(0); // thumbnwidth + writeByte(0); // thumbnheight + } + + function writeSOF0(width, height) + { + writeWord(0xFFC0); // marker + writeWord(17); // length, truecolor YUV JPG + writeByte(8); // precision + writeWord(height); + writeWord(width); + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0x11); // HVY + writeByte(0); // QTY + writeByte(2); // IdU + writeByte(0x11); // HVU + writeByte(1); // QTU + writeByte(3); // IdV + writeByte(0x11); // HVV + writeByte(1); // QTV + } + + function writeDQT() + { + writeWord(0xFFDB); // marker + writeWord(132); // length + writeByte(0); + for (var i=0; i<64; i++) { + writeByte(YTable[i]); + } + writeByte(1); + for (var j=0; j<64; j++) { + writeByte(UVTable[j]); + } + } + + function writeDHT() + { + writeWord(0xFFC4); // marker + writeWord(0x01A2); // length + + writeByte(0); // HTYDCinfo + for (var i=0; i<16; i++) { + writeByte(std_dc_luminance_nrcodes[i+1]); + } + for (var j=0; j<=11; j++) { + writeByte(std_dc_luminance_values[j]); + } + + writeByte(0x10); // HTYACinfo + for (var k=0; k<16; k++) { + writeByte(std_ac_luminance_nrcodes[k+1]); + } + for (var l=0; l<=161; l++) { + writeByte(std_ac_luminance_values[l]); + } + + writeByte(1); // HTUDCinfo + for (var m=0; m<16; m++) { + writeByte(std_dc_chrominance_nrcodes[m+1]); + } + for (var n=0; n<=11; n++) { + writeByte(std_dc_chrominance_values[n]); + } + + writeByte(0x11); // HTUACinfo + for (var o=0; o<16; o++) { + writeByte(std_ac_chrominance_nrcodes[o+1]); + } + for (var p=0; p<=161; p++) { + writeByte(std_ac_chrominance_values[p]); + } + } + + function writeSOS() + { + writeWord(0xFFDA); // marker + writeWord(12); // length + writeByte(3); // nrofcomponents + writeByte(1); // IdY + writeByte(0); // HTY + writeByte(2); // IdU + writeByte(0x11); // HTU + writeByte(3); // IdV + writeByte(0x11); // HTV + writeByte(0); // Ss + writeByte(0x3f); // Se + writeByte(0); // Bf + } + + function processDU(CDU, fdtbl, DC, HTDC, HTAC){ + var EOB = HTAC[0x00]; + var M16zeroes = HTAC[0xF0]; + var pos; + var I16 = 16; + var I63 = 63; + var I64 = 64; + var DU_DCT = fDCTQuant(CDU, fdtbl); + //ZigZag reorder + for (var j=0;j<I64;++j) { + DU[ZigZag[j]]=DU_DCT[j]; + } + var Diff = DU[0] - DC; DC = DU[0]; + //Encode DC + if (Diff==0) { + writeBits(HTDC[0]); // Diff might be 0 + } else { + pos = 32767+Diff; + writeBits(HTDC[category[pos]]); + writeBits(bitcode[pos]); + } + //Encode ACs + var end0pos = 63; // was const... which is crazy + for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}; + //end0pos = first element in reverse order !=0 + if ( end0pos == 0) { + writeBits(EOB); + return DC; + } + var i = 1; + var lng; + while ( i <= end0pos ) { + var startpos = i; + for (; (DU[i]==0) && (i<=end0pos); ++i) {} + var nrzeroes = i-startpos; + if ( nrzeroes >= I16 ) { + lng = nrzeroes>>4; + for (var nrmarker=1; nrmarker <= lng; ++nrmarker) + writeBits(M16zeroes); + nrzeroes = nrzeroes&0xF; + } + pos = 32767+DU[i]; + writeBits(HTAC[(nrzeroes<<4)+category[pos]]); + writeBits(bitcode[pos]); + i++; + } + if ( end0pos != I63 ) { + writeBits(EOB); + } + return DC; + } + + function initCharLookupTable(){ + var sfcc = String.fromCharCode; + for(var i=0; i < 256; i++){ ///// ACHTUNG // 255 + clt[i] = sfcc(i); + } + } + + this.encode = function(image,quality) // image data object + { + // var time_start = new Date().getTime(); + + if(quality) setQuality(quality); + + // Initialize bit writer + byteout = new Array(); + bytenew=0; + bytepos=7; + + // Add JPEG headers + writeWord(0xFFD8); // SOI + writeAPP0(); + writeDQT(); + writeSOF0(image.width,image.height); + writeDHT(); + writeSOS(); + + + // Encode 8x8 macroblocks + var DCY=0; + var DCU=0; + var DCV=0; + + bytenew=0; + bytepos=7; + + + this.encode.displayName = "_encode_"; + + var imageData = image.data; + var width = image.width; + var height = image.height; + + var quadWidth = width*4; + var tripleWidth = width*3; + + var x, y = 0; + var r, g, b; + var start,p, col,row,pos; + while(y < height){ + x = 0; + while(x < quadWidth){ + start = quadWidth * y + x; + p = start; + col = -1; + row = 0; + + for(pos=0; pos < 64; pos++){ + row = pos >> 3;// /8 + col = ( pos & 7 ) * 4; // %8 + p = start + ( row * quadWidth ) + col; + + if(y+row >= height){ // padding bottom + p-= (quadWidth*(y+1+row-height)); + } + + if(x+col >= quadWidth){ // padding right + p-= ((x+col) - quadWidth +4) + } + + r = imageData[ p++ ]; + g = imageData[ p++ ]; + b = imageData[ p++ ]; + + + /* // calculate YUV values dynamically + YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80 + UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b)); + VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b)); + */ + + // use lookup table (slightly faster) + YDU[pos] = ((RGB_YUV_TABLE[r] + RGB_YUV_TABLE[(g + 256)>>0] + RGB_YUV_TABLE[(b + 512)>>0]) >> 16)-128; + UDU[pos] = ((RGB_YUV_TABLE[(r + 768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128; + VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128; + + } + + DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + x+=32; + } + y+=8; + } + + + //////////////////////////////////////////////////////////////// + + // Do the bit alignment of the EOI marker + if ( bytepos >= 0 ) { + var fillbits = []; + fillbits[1] = bytepos+1; + fillbits[0] = (1<<(bytepos+1))-1; + writeBits(fillbits); + } + + writeWord(0xFFD9); //EOI + + var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join('')); + + byteout = []; + + // benchmarking + // var duration = new Date().getTime() - time_start; + // console.log('Encoding time: '+ currentQuality + 'ms'); + // + + return jpegDataUri + } + + function setQuality(quality){ + if (quality <= 0) { + quality = 1; + } + if (quality > 100) { + quality = 100; + } + + if(currentQuality == quality) return // don't recalc if unchanged + + var sf = 0; + if (quality < 50) { + sf = Math.floor(5000 / quality); + } else { + sf = Math.floor(200 - quality*2); + } + + initQuantTables(sf); + currentQuality = quality; + // console.log('Quality set to: '+quality +'%'); + } + + function init(){ + // var time_start = new Date().getTime(); + if(!quality) quality = 50; + // Create tables + initCharLookupTable() + initHuffmanTbl(); + initCategoryNumber(); + initRGBYUVTable(); + + setQuality(quality); + // var duration = new Date().getTime() - time_start; + // console.log('Initialization '+ duration + 'ms'); + } + + init(); + + }; + + JPEGEncoder.encode = function( data, quality ) { + var encoder = new JPEGEncoder( quality ); + + return encoder.encode( data ); + } + + return JPEGEncoder; + }); + /** + * @fileOverview Fix android canvas.toDataUrl bug. + */ + define('runtime/html5/androidpatch',[ + 'runtime/html5/util', + 'runtime/html5/jpegencoder', + 'base' + ], function( Util, encoder, Base ) { + var origin = Util.canvasToDataUrl, + supportJpeg; + + Util.canvasToDataUrl = function( canvas, type, quality ) { + var ctx, w, h, fragement, parts; + + // 非android手机直接跳过。 + if ( !Base.os.android ) { + return origin.apply( null, arguments ); + } + + // 检测是否canvas支持jpeg导出,根据数据格式来判断。 + // JPEG 前两位分别是:255, 216 + if ( type === 'image/jpeg' && typeof supportJpeg === 'undefined' ) { + fragement = origin.apply( null, arguments ); + + parts = fragement.split(','); + + if ( ~parts[ 0 ].indexOf('base64') ) { + fragement = atob( parts[ 1 ] ); + } else { + fragement = decodeURIComponent( parts[ 1 ] ); + } + + fragement = fragement.substring( 0, 2 ); + + supportJpeg = fragement.charCodeAt( 0 ) === 255 && + fragement.charCodeAt( 1 ) === 216; + } + + // 只有在android环境下才修复 + if ( type === 'image/jpeg' && !supportJpeg ) { + w = canvas.width; + h = canvas.height; + ctx = canvas.getContext('2d'); + + return encoder.encode( ctx.getImageData( 0, 0, w, h ), quality ); + } + + return origin.apply( null, arguments ); + }; + }); + /** + * @fileOverview Image + */ + define('runtime/html5/image',[ + 'base', + 'runtime/html5/runtime', + 'runtime/html5/util' + ], function( Base, Html5Runtime, Util ) { + + var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D'; + + return Html5Runtime.register( 'Image', { + + // flag: 标记是否被修改过。 + modified: false, + + init: function() { + var me = this, + img = new Image(); + + img.onload = function() { + + me._info = { + type: me.type, + width: this.width, + height: this.height + }; + + // 读取meta信息。 + if ( !me._metas && 'image/jpeg' === me.type ) { + Util.parseMeta( me._blob, function( error, ret ) { + me._metas = ret; + me.owner.trigger('load'); + }); + } else { + me.owner.trigger('load'); + } + }; + + img.onerror = function() { + me.owner.trigger('error'); + }; + + me._img = img; + }, + + loadFromBlob: function( blob ) { + var me = this, + img = me._img; + + me._blob = blob; + me.type = blob.type; + img.src = Util.createObjectURL( blob.getSource() ); + me.owner.once( 'load', function() { + Util.revokeObjectURL( img.src ); + }); + }, + + resize: function( width, height ) { + var canvas = this._canvas || + (this._canvas = document.createElement('canvas')); + + this._resize( this._img, canvas, width, height ); + this._blob = null; // 没用了,可以删掉了。 + this.modified = true; + this.owner.trigger( 'complete', 'resize' ); + }, + + crop: function( x, y, w, h, s ) { + var cvs = this._canvas || + (this._canvas = document.createElement('canvas')), + opts = this.options, + img = this._img, + iw = img.naturalWidth, + ih = img.naturalHeight, + orientation = this.getOrientation(); + + s = s || 1; + + // todo 解决 orientation 的问题。 + // values that require 90 degree rotation + // if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) { + + // switch ( orientation ) { + // case 6: + // tmp = x; + // x = y; + // y = iw * s - tmp - w; + // console.log(ih * s, tmp, w) + // break; + // } + + // (w ^= h, h ^= w, w ^= h); + // } + + cvs.width = w; + cvs.height = h; + + opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation ); + this._renderImageToCanvas( cvs, img, -x, -y, iw * s, ih * s ); + + this._blob = null; // 没用了,可以删掉了。 + this.modified = true; + this.owner.trigger( 'complete', 'crop' ); + }, + + getAsBlob: function( type ) { + var blob = this._blob, + opts = this.options, + canvas; + + type = type || this.type; + + // blob需要重新生成。 + if ( this.modified || this.type !== type ) { + canvas = this._canvas; + + if ( type === 'image/jpeg' ) { + + blob = Util.canvasToDataUrl( canvas, type, opts.quality ); + + if ( opts.preserveHeaders && this._metas && + this._metas.imageHead ) { + + blob = Util.dataURL2ArrayBuffer( blob ); + blob = Util.updateImageHead( blob, + this._metas.imageHead ); + blob = Util.arrayBufferToBlob( blob, type ); + return blob; + } + } else { + blob = Util.canvasToDataUrl( canvas, type ); + } + + blob = Util.dataURL2Blob( blob ); + } + + return blob; + }, + + getAsDataUrl: function( type ) { + var opts = this.options; + + type = type || this.type; + + if ( type === 'image/jpeg' ) { + return Util.canvasToDataUrl( this._canvas, type, opts.quality ); + } else { + return this._canvas.toDataURL( type ); + } + }, + + getOrientation: function() { + return this._metas && this._metas.exif && + this._metas.exif.get('Orientation') || 1; + }, + + info: function( val ) { + + // setter + if ( val ) { + this._info = val; + return this; + } + + // getter + return this._info; + }, + + meta: function( val ) { + + // setter + if ( val ) { + this._meta = val; + return this; + } + + // getter + return this._meta; + }, + + destroy: function() { + var canvas = this._canvas; + this._img.onload = null; + + if ( canvas ) { + canvas.getContext('2d') + .clearRect( 0, 0, canvas.width, canvas.height ); + canvas.width = canvas.height = 0; + this._canvas = null; + } + + // 释放内存。非常重要,否则释放不了image的内存。 + this._img.src = BLANK; + this._img = this._blob = null; + }, + + _resize: function( img, cvs, width, height ) { + var opts = this.options, + naturalWidth = img.width, + naturalHeight = img.height, + orientation = this.getOrientation(), + scale, w, h, x, y; + + // values that require 90 degree rotation + if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) { + + // 交换width, height的值。 + width ^= height; + height ^= width; + width ^= height; + } + + scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth, + height / naturalHeight ); + + // 不允许放大。 + opts.allowMagnify || (scale = Math.min( 1, scale )); + + w = naturalWidth * scale; + h = naturalHeight * scale; + + if ( opts.crop ) { + cvs.width = width; + cvs.height = height; + } else { + cvs.width = w; + cvs.height = h; + } + + x = (cvs.width - w) / 2; + y = (cvs.height - h) / 2; + + opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation ); + + this._renderImageToCanvas( cvs, img, x, y, w, h ); + }, + + _rotate2Orientaion: function( canvas, orientation ) { + var width = canvas.width, + height = canvas.height, + ctx = canvas.getContext('2d'); + + switch ( orientation ) { + case 5: + case 6: + case 7: + case 8: + canvas.width = height; + canvas.height = width; + break; + } + + switch ( orientation ) { + case 2: // horizontal flip + ctx.translate( width, 0 ); + ctx.scale( -1, 1 ); + break; + + case 3: // 180 rotate left + ctx.translate( width, height ); + ctx.rotate( Math.PI ); + break; + + case 4: // vertical flip + ctx.translate( 0, height ); + ctx.scale( 1, -1 ); + break; + + case 5: // vertical flip + 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.scale( 1, -1 ); + break; + + case 6: // 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.translate( 0, -height ); + break; + + case 7: // horizontal flip + 90 rotate right + ctx.rotate( 0.5 * Math.PI ); + ctx.translate( width, -height ); + ctx.scale( -1, 1 ); + break; + + case 8: // 90 rotate left + ctx.rotate( -0.5 * Math.PI ); + ctx.translate( -width, 0 ); + break; + } + }, + + // https://github.com/stomita/ios-imagefile-megapixel/ + // blob/master/src/megapix-image.js + _renderImageToCanvas: (function() { + + // 如果不是ios, 不需要这么复杂! + if ( !Base.os.ios ) { + return function( canvas ) { + var args = Base.slice( arguments, 1 ), + ctx = canvas.getContext('2d'); + + ctx.drawImage.apply( ctx, args ); + }; + } + + /** + * Detecting vertical squash in loaded image. + * Fixes a bug which squash image vertically while drawing into + * canvas for some images. + */ + function detectVerticalSquash( img, iw, ih ) { + var canvas = document.createElement('canvas'), + ctx = canvas.getContext('2d'), + sy = 0, + ey = ih, + py = ih, + data, alpha, ratio; + + + canvas.width = 1; + canvas.height = ih; + ctx.drawImage( img, 0, 0 ); + data = ctx.getImageData( 0, 0, 1, ih ).data; + + // search image edge pixel position in case + // it is squashed vertically. + while ( py > sy ) { + alpha = data[ (py - 1) * 4 + 3 ]; + + if ( alpha === 0 ) { + ey = py; + } else { + sy = py; + } + + py = (ey + sy) >> 1; + } + + ratio = (py / ih); + return (ratio === 0) ? 1 : ratio; + } + + // fix ie7 bug + // http://stackoverflow.com/questions/11929099/ + // html5-canvas-drawimage-ratio-bug-ios + if ( Base.os.ios >= 7 ) { + return function( canvas, img, x, y, w, h ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + vertSquashRatio = detectVerticalSquash( img, iw, ih ); + + return canvas.getContext('2d').drawImage( img, 0, 0, + iw * vertSquashRatio, ih * vertSquashRatio, + x, y, w, h ); + }; + } + + /** + * Detect subsampling in loaded image. + * In iOS, larger images than 2M pixels may be + * subsampled in rendering. + */ + function detectSubsampling( img ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + canvas, ctx; + + // subsampling may happen overmegapixel image + if ( iw * ih > 1024 * 1024 ) { + canvas = document.createElement('canvas'); + canvas.width = canvas.height = 1; + ctx = canvas.getContext('2d'); + ctx.drawImage( img, -iw + 1, 0 ); + + // subsampled image becomes half smaller in rendering size. + // check alpha channel value to confirm image is covering + // edge pixel or not. if alpha value is 0 + // image is not covering, hence subsampled. + return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0; + } else { + return false; + } + } + + + return function( canvas, img, x, y, width, height ) { + var iw = img.naturalWidth, + ih = img.naturalHeight, + ctx = canvas.getContext('2d'), + subsampled = detectSubsampling( img ), + doSquash = this.type === 'image/jpeg', + d = 1024, + sy = 0, + dy = 0, + tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx; + + if ( subsampled ) { + iw /= 2; + ih /= 2; + } + + ctx.save(); + tmpCanvas = document.createElement('canvas'); + tmpCanvas.width = tmpCanvas.height = d; + + tmpCtx = tmpCanvas.getContext('2d'); + vertSquashRatio = doSquash ? + detectVerticalSquash( img, iw, ih ) : 1; + + dw = Math.ceil( d * width / iw ); + dh = Math.ceil( d * height / ih / vertSquashRatio ); + + while ( sy < ih ) { + sx = 0; + dx = 0; + while ( sx < iw ) { + tmpCtx.clearRect( 0, 0, d, d ); + tmpCtx.drawImage( img, -sx, -sy ); + ctx.drawImage( tmpCanvas, 0, 0, d, d, + x + dx, y + dy, dw, dh ); + sx += d; + dx += dw; + } + sy += d; + dy += dh; + } + ctx.restore(); + tmpCanvas = tmpCtx = null; + }; + })() + }); + }); + /** + * @fileOverview Transport + * @todo 支持chunked传输,优势: + * 可以将大文件分成小块,挨个传输,可以提高大文件成功率,当失败的时候,也只需要重传那小部分, + * 而不需要重头再传一次。另外断点续传也需要用chunked方式。 + */ + define('runtime/html5/transport',[ + 'base', + 'runtime/html5/runtime' + ], function( Base, Html5Runtime ) { + + var noop = Base.noop, + $ = Base.$; + + return Html5Runtime.register( 'Transport', { + init: function() { + this._status = 0; + this._response = null; + }, + + send: function() { + var owner = this.owner, + opts = this.options, + xhr = this._initAjax(), + blob = owner._blob, + server = opts.server, + formData, binary, fr; + + if ( opts.sendAsBinary ) { + server += (/\?/.test( server ) ? '&' : '?') + + $.param( owner._formData ); + + binary = blob.getSource(); + } else { + formData = new FormData(); + $.each( owner._formData, function( k, v ) { + formData.append( k, v ); + }); + + formData.append( opts.fileVal, blob.getSource(), + opts.filename || owner._formData.name || '' ); + } + + if ( opts.withCredentials && 'withCredentials' in xhr ) { + xhr.open( opts.method, server, true ); + xhr.withCredentials = true; + } else { + xhr.open( opts.method, server ); + } + + this._setRequestHeader( xhr, opts.headers ); + + if ( binary ) { + // 强制设置成 content-type 为文件流。 + xhr.overrideMimeType && + xhr.overrideMimeType('application/octet-stream'); + + // android直接发送blob会导致服务端接收到的是空文件。 + // bug详情。 + // https://code.google.com/p/android/issues/detail?id=39882 + // 所以先用fileReader读取出来再通过arraybuffer的方式发送。 + if ( Base.os.android ) { + fr = new FileReader(); + + fr.onload = function() { + xhr.send( this.result ); + fr = fr.onload = null; + }; + + fr.readAsArrayBuffer( binary ); + } else { + xhr.send( binary ); + } + } else { + xhr.send( formData ); + } + }, + + getResponse: function() { + return this._response; + }, + + getResponseAsJson: function() { + return this._parseJson( this._response ); + }, + + getStatus: function() { + return this._status; + }, + + abort: function() { + var xhr = this._xhr; + + if ( xhr ) { + xhr.upload.onprogress = noop; + xhr.onreadystatechange = noop; + xhr.abort(); + + this._xhr = xhr = null; + } + }, + + destroy: function() { + this.abort(); + }, + + _initAjax: function() { + var me = this, + xhr = new XMLHttpRequest(), + opts = this.options; + + if ( opts.withCredentials && !('withCredentials' in xhr) && + typeof XDomainRequest !== 'undefined' ) { + xhr = new XDomainRequest(); + } + + xhr.upload.onprogress = function( e ) { + var percentage = 0; + + if ( e.lengthComputable ) { + percentage = e.loaded / e.total; + } + + return me.trigger( 'progress', percentage ); + }; + + xhr.onreadystatechange = function() { + + if ( xhr.readyState !== 4 ) { + return; + } + + xhr.upload.onprogress = noop; + xhr.onreadystatechange = noop; + me._xhr = null; + me._status = xhr.status; + + if ( xhr.status >= 200 && xhr.status < 300 ) { + me._response = xhr.responseText; + return me.trigger('load'); + } else if ( xhr.status >= 500 && xhr.status < 600 ) { + me._response = xhr.responseText; + return me.trigger( 'error', 'server' ); + } + + + return me.trigger( 'error', me._status ? 'http' : 'abort' ); + }; + + me._xhr = xhr; + return xhr; + }, + + _setRequestHeader: function( xhr, headers ) { + $.each( headers, function( key, val ) { + xhr.setRequestHeader( key, val ); + }); + }, + + _parseJson: function( str ) { + var json; + + try { + json = JSON.parse( str ); + } catch ( ex ) { + json = {}; + } + + return json; + } + }); + }); + /** + * @fileOverview Transport flash实现 + */ + define('runtime/html5/md5',[ + 'runtime/html5/runtime' + ], function( FlashRuntime ) { + + /* + * Fastest md5 implementation around (JKM md5) + * Credits: Joseph Myers + * + * @see http://www.myersdaily.org/joseph/javascript/md5-text.html + * @see http://jsperf.com/md5-shootout/7 + */ + + /* this function is much faster, + so if possible we use it. Some IEs + are the only ones I know of that + need the idiotic second function, + generated by an if clause. */ + var add32 = function (a, b) { + return (a + b) & 0xFFFFFFFF; + }, + + cmn = function (q, a, b, x, s, t) { + a = add32(add32(a, q), add32(x, t)); + return add32((a << s) | (a >>> (32 - s)), b); + }, + + ff = function (a, b, c, d, x, s, t) { + return cmn((b & c) | ((~b) & d), a, b, x, s, t); + }, + + gg = function (a, b, c, d, x, s, t) { + return cmn((b & d) | (c & (~d)), a, b, x, s, t); + }, + + hh = function (a, b, c, d, x, s, t) { + return cmn(b ^ c ^ d, a, b, x, s, t); + }, + + ii = function (a, b, c, d, x, s, t) { + return cmn(c ^ (b | (~d)), a, b, x, s, t); + }, + + md5cycle = function (x, k) { + var a = x[0], + b = x[1], + c = x[2], + d = x[3]; + + a = ff(a, b, c, d, k[0], 7, -680876936); + d = ff(d, a, b, c, k[1], 12, -389564586); + c = ff(c, d, a, b, k[2], 17, 606105819); + b = ff(b, c, d, a, k[3], 22, -1044525330); + a = ff(a, b, c, d, k[4], 7, -176418897); + d = ff(d, a, b, c, k[5], 12, 1200080426); + c = ff(c, d, a, b, k[6], 17, -1473231341); + b = ff(b, c, d, a, k[7], 22, -45705983); + a = ff(a, b, c, d, k[8], 7, 1770035416); + d = ff(d, a, b, c, k[9], 12, -1958414417); + c = ff(c, d, a, b, k[10], 17, -42063); + b = ff(b, c, d, a, k[11], 22, -1990404162); + a = ff(a, b, c, d, k[12], 7, 1804603682); + d = ff(d, a, b, c, k[13], 12, -40341101); + c = ff(c, d, a, b, k[14], 17, -1502002290); + b = ff(b, c, d, a, k[15], 22, 1236535329); + + a = gg(a, b, c, d, k[1], 5, -165796510); + d = gg(d, a, b, c, k[6], 9, -1069501632); + c = gg(c, d, a, b, k[11], 14, 643717713); + b = gg(b, c, d, a, k[0], 20, -373897302); + a = gg(a, b, c, d, k[5], 5, -701558691); + d = gg(d, a, b, c, k[10], 9, 38016083); + c = gg(c, d, a, b, k[15], 14, -660478335); + b = gg(b, c, d, a, k[4], 20, -405537848); + a = gg(a, b, c, d, k[9], 5, 568446438); + d = gg(d, a, b, c, k[14], 9, -1019803690); + c = gg(c, d, a, b, k[3], 14, -187363961); + b = gg(b, c, d, a, k[8], 20, 1163531501); + a = gg(a, b, c, d, k[13], 5, -1444681467); + d = gg(d, a, b, c, k[2], 9, -51403784); + c = gg(c, d, a, b, k[7], 14, 1735328473); + b = gg(b, c, d, a, k[12], 20, -1926607734); + + a = hh(a, b, c, d, k[5], 4, -378558); + d = hh(d, a, b, c, k[8], 11, -2022574463); + c = hh(c, d, a, b, k[11], 16, 1839030562); + b = hh(b, c, d, a, k[14], 23, -35309556); + a = hh(a, b, c, d, k[1], 4, -1530992060); + d = hh(d, a, b, c, k[4], 11, 1272893353); + c = hh(c, d, a, b, k[7], 16, -155497632); + b = hh(b, c, d, a, k[10], 23, -1094730640); + a = hh(a, b, c, d, k[13], 4, 681279174); + d = hh(d, a, b, c, k[0], 11, -358537222); + c = hh(c, d, a, b, k[3], 16, -722521979); + b = hh(b, c, d, a, k[6], 23, 76029189); + a = hh(a, b, c, d, k[9], 4, -640364487); + d = hh(d, a, b, c, k[12], 11, -421815835); + c = hh(c, d, a, b, k[15], 16, 530742520); + b = hh(b, c, d, a, k[2], 23, -995338651); + + a = ii(a, b, c, d, k[0], 6, -198630844); + d = ii(d, a, b, c, k[7], 10, 1126891415); + c = ii(c, d, a, b, k[14], 15, -1416354905); + b = ii(b, c, d, a, k[5], 21, -57434055); + a = ii(a, b, c, d, k[12], 6, 1700485571); + d = ii(d, a, b, c, k[3], 10, -1894986606); + c = ii(c, d, a, b, k[10], 15, -1051523); + b = ii(b, c, d, a, k[1], 21, -2054922799); + a = ii(a, b, c, d, k[8], 6, 1873313359); + d = ii(d, a, b, c, k[15], 10, -30611744); + c = ii(c, d, a, b, k[6], 15, -1560198380); + b = ii(b, c, d, a, k[13], 21, 1309151649); + a = ii(a, b, c, d, k[4], 6, -145523070); + d = ii(d, a, b, c, k[11], 10, -1120210379); + c = ii(c, d, a, b, k[2], 15, 718787259); + b = ii(b, c, d, a, k[9], 21, -343485551); + + x[0] = add32(a, x[0]); + x[1] = add32(b, x[1]); + x[2] = add32(c, x[2]); + x[3] = add32(d, x[3]); + }, + + /* there needs to be support for Unicode here, + * unless we pretend that we can redefine the MD-5 + * algorithm for multi-byte characters (perhaps + * by adding every four 16-bit characters and + * shortening the sum to 32 bits). Otherwise + * I suggest performing MD-5 as if every character + * was two bytes--e.g., 0040 0025 = @%--but then + * how will an ordinary MD-5 sum be matched? + * There is no way to standardize text to something + * like UTF-8 before transformation; speed cost is + * utterly prohibitive. The JavaScript standard + * itself needs to look at this: it should start + * providing access to strings as preformed UTF-8 + * 8-bit unsigned value arrays. + */ + md5blk = function (s) { + var md5blks = [], + i; /* Andy King said do it this way. */ + + for (i = 0; i < 64; i += 4) { + md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24); + } + return md5blks; + }, + + md5blk_array = function (a) { + var md5blks = [], + i; /* Andy King said do it this way. */ + + for (i = 0; i < 64; i += 4) { + md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24); + } + return md5blks; + }, + + md51 = function (s) { + var n = s.length, + state = [1732584193, -271733879, -1732584194, 271733878], + i, + length, + tail, + tmp, + lo, + hi; + + for (i = 64; i <= n; i += 64) { + md5cycle(state, md5blk(s.substring(i - 64, i))); + } + s = s.substring(i - 64); + length = s.length; + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); + } + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(state, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } + + // Beware that the final length might not fit in 32 bits so we take care of that + tmp = n * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + + tail[14] = lo; + tail[15] = hi; + + md5cycle(state, tail); + return state; + }, + + md51_array = function (a) { + var n = a.length, + state = [1732584193, -271733879, -1732584194, 271733878], + i, + length, + tail, + tmp, + lo, + hi; + + for (i = 64; i <= n; i += 64) { + md5cycle(state, md5blk_array(a.subarray(i - 64, i))); + } + + // Not sure if it is a bug, however IE10 will always produce a sub array of length 1 + // containing the last element of the parent array if the sub array specified starts + // beyond the length of the parent array - weird. + // https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue + a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0); + + length = a.length; + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= a[i] << ((i % 4) << 3); + } + + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(state, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } + + // Beware that the final length might not fit in 32 bits so we take care of that + tmp = n * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + + tail[14] = lo; + tail[15] = hi; + + md5cycle(state, tail); + + return state; + }, + + hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'], + + rhex = function (n) { + var s = '', + j; + for (j = 0; j < 4; j += 1) { + s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; + } + return s; + }, + + hex = function (x) { + var i; + for (i = 0; i < x.length; i += 1) { + x[i] = rhex(x[i]); + } + return x.join(''); + }, + + md5 = function (s) { + return hex(md51(s)); + }, + + + + //////////////////////////////////////////////////////////////////////////// + + /** + * SparkMD5 OOP implementation. + * + * Use this class to perform an incremental md5, otherwise use the + * static methods instead. + */ + SparkMD5 = function () { + // call reset to init the instance + this.reset(); + }; + + + // In some cases the fast add32 function cannot be used.. + if (md5('hello') !== '5d41402abc4b2a76b9719d911017c592') { + add32 = function (x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + }; + } + + + /** + * Appends a string. + * A conversion will be applied if an utf8 string is detected. + * + * @param {String} str The string to be appended + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.append = function (str) { + // converts the string to utf8 bytes if necessary + if (/[\u0080-\uFFFF]/.test(str)) { + str = unescape(encodeURIComponent(str)); + } + + // then append as binary + this.appendBinary(str); + + return this; + }; + + /** + * Appends a binary string. + * + * @param {String} contents The binary string to be appended + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.appendBinary = function (contents) { + this._buff += contents; + this._length += contents.length; + + var length = this._buff.length, + i; + + for (i = 64; i <= length; i += 64) { + md5cycle(this._state, md5blk(this._buff.substring(i - 64, i))); + } + + this._buff = this._buff.substr(i - 64); + + return this; + }; + + /** + * Finishes the incremental computation, reseting the internal state and + * returning the result. + * Use the raw parameter to obtain the raw result instead of the hex one. + * + * @param {Boolean} raw True to get the raw result, false to get the hex result + * + * @return {String|Array} The result + */ + SparkMD5.prototype.end = function (raw) { + var buff = this._buff, + length = buff.length, + i, + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ret; + + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3); + } + + this._finish(tail, length); + ret = !!raw ? this._state : hex(this._state); + + this.reset(); + + return ret; + }; + + /** + * Finish the final calculation based on the tail. + * + * @param {Array} tail The tail (will be modified) + * @param {Number} length The length of the remaining buffer + */ + SparkMD5.prototype._finish = function (tail, length) { + var i = length, + tmp, + lo, + hi; + + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(this._state, tail); + for (i = 0; i < 16; i += 1) { + tail[i] = 0; + } + } + + // Do the final computation based on the tail and length + // Beware that the final length may not fit in 32 bits so we take care of that + tmp = this._length * 8; + tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/); + lo = parseInt(tmp[2], 16); + hi = parseInt(tmp[1], 16) || 0; + + tail[14] = lo; + tail[15] = hi; + md5cycle(this._state, tail); + }; + + /** + * Resets the internal state of the computation. + * + * @return {SparkMD5} The instance itself + */ + SparkMD5.prototype.reset = function () { + this._buff = ""; + this._length = 0; + this._state = [1732584193, -271733879, -1732584194, 271733878]; + + return this; + }; + + /** + * Releases memory used by the incremental buffer and other aditional + * resources. If you plan to use the instance again, use reset instead. + */ + SparkMD5.prototype.destroy = function () { + delete this._state; + delete this._buff; + delete this._length; + }; + + + /** + * Performs the md5 hash on a string. + * A conversion will be applied if utf8 string is detected. + * + * @param {String} str The string + * @param {Boolean} raw True to get the raw result, false to get the hex result + * + * @return {String|Array} The result + */ + SparkMD5.hash = function (str, raw) { + // converts the string to utf8 bytes if necessary + if (/[\u0080-\uFFFF]/.test(str)) { + str = unescape(encodeURIComponent(str)); + } + + var hash = md51(str); + + return !!raw ? hash : hex(hash); + }; + + /** + * Performs the md5 hash on a binary string. + * + * @param {String} content The binary string + * @param {Boolean} raw True to get the raw result, false to get the hex result + * + * @return {String|Array} The result + */ + SparkMD5.hashBinary = function (content, raw) { + var hash = md51(content); + + return !!raw ? hash : hex(hash); + }; + + /** + * SparkMD5 OOP implementation for array buffers. + * + * Use this class to perform an incremental md5 ONLY for array buffers. + */ + SparkMD5.ArrayBuffer = function () { + // call reset to init the instance + this.reset(); + }; + + //////////////////////////////////////////////////////////////////////////// + + /** + * Appends an array buffer. + * + * @param {ArrayBuffer} arr The array to be appended + * + * @return {SparkMD5.ArrayBuffer} The instance itself + */ + SparkMD5.ArrayBuffer.prototype.append = function (arr) { + // TODO: we could avoid the concatenation here but the algorithm would be more complex + // if you find yourself needing extra performance, please make a PR. + var buff = this._concatArrayBuffer(this._buff, arr), + length = buff.length, + i; + + this._length += arr.byteLength; + + for (i = 64; i <= length; i += 64) { + md5cycle(this._state, md5blk_array(buff.subarray(i - 64, i))); + } + + // Avoids IE10 weirdness (documented above) + this._buff = (i - 64) < length ? buff.subarray(i - 64) : new Uint8Array(0); + + return this; + }; + + /** + * Finishes the incremental computation, reseting the internal state and + * returning the result. + * Use the raw parameter to obtain the raw result instead of the hex one. + * + * @param {Boolean} raw True to get the raw result, false to get the hex result + * + * @return {String|Array} The result + */ + SparkMD5.ArrayBuffer.prototype.end = function (raw) { + var buff = this._buff, + length = buff.length, + tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + i, + ret; + + for (i = 0; i < length; i += 1) { + tail[i >> 2] |= buff[i] << ((i % 4) << 3); + } + + this._finish(tail, length); + ret = !!raw ? this._state : hex(this._state); + + this.reset(); + + return ret; + }; + + SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish; + + /** + * Resets the internal state of the computation. + * + * @return {SparkMD5.ArrayBuffer} The instance itself + */ + SparkMD5.ArrayBuffer.prototype.reset = function () { + this._buff = new Uint8Array(0); + this._length = 0; + this._state = [1732584193, -271733879, -1732584194, 271733878]; + + return this; + }; + + /** + * Releases memory used by the incremental buffer and other aditional + * resources. If you plan to use the instance again, use reset instead. + */ + SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy; + + /** + * Concats two array buffers, returning a new one. + * + * @param {ArrayBuffer} first The first array buffer + * @param {ArrayBuffer} second The second array buffer + * + * @return {ArrayBuffer} The new array buffer + */ + SparkMD5.ArrayBuffer.prototype._concatArrayBuffer = function (first, second) { + var firstLength = first.length, + result = new Uint8Array(firstLength + second.byteLength); + + result.set(first); + result.set(new Uint8Array(second), firstLength); + + return result; + }; + + /** + * Performs the md5 hash on an array buffer. + * + * @param {ArrayBuffer} arr The array buffer + * @param {Boolean} raw True to get the raw result, false to get the hex result + * + * @return {String|Array} The result + */ + SparkMD5.ArrayBuffer.hash = function (arr, raw) { + var hash = md51_array(new Uint8Array(arr)); + + return !!raw ? hash : hex(hash); + }; + + return FlashRuntime.register( 'Md5', { + init: function() { + // do nothing. + }, + + loadFromBlob: function( file ) { + var blob = file.getSource(), + chunkSize = 2 * 1024 * 1024, + chunks = Math.ceil( blob.size / chunkSize ), + chunk = 0, + owner = this.owner, + spark = new SparkMD5.ArrayBuffer(), + me = this, + blobSlice = blob.mozSlice || blob.webkitSlice || blob.slice, + loadNext, fr; + + fr = new FileReader(); + + loadNext = function() { + var start, end; + + start = chunk * chunkSize; + end = Math.min( start + chunkSize, blob.size ); + + fr.onload = function( e ) { + spark.append( e.target.result ); + owner.trigger( 'progress', { + total: file.size, + loaded: end + }); + }; + + fr.onloadend = function() { + fr.onloadend = fr.onload = null; + + if ( ++chunk < chunks ) { + setTimeout( loadNext, 1 ); + } else { + setTimeout(function(){ + owner.trigger('load'); + me.result = spark.end(); + loadNext = file = blob = spark = null; + owner.trigger('complete'); + }, 50 ); + } + }; + + fr.readAsArrayBuffer( blobSlice.call( blob, start, end ) ); + }; + + loadNext(); + }, + + getResult: function() { + return this.result; + } + }); + }); + /** + * @fileOverview FlashRuntime + */ + define('runtime/flash/runtime',[ + 'base', + 'runtime/runtime', + 'runtime/compbase' + ], function( Base, Runtime, CompBase ) { + + var $ = Base.$, + type = 'flash', + components = {}; + + + function getFlashVersion() { + var version; + + try { + version = navigator.plugins[ 'Shockwave Flash' ]; + version = version.description; + } catch ( ex ) { + try { + version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash') + .GetVariable('$version'); + } catch ( ex2 ) { + version = '0.0'; + } + } + version = version.match( /\d+/g ); + return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 ); + } + + function FlashRuntime() { + var pool = {}, + clients = {}, + destroy = this.destroy, + me = this, + jsreciver = Base.guid('webuploader_'); + + Runtime.apply( me, arguments ); + me.type = type; + + + // 这个方法的调用者,实际上是RuntimeClient + me.exec = function( comp, fn/*, args...*/ ) { + var client = this, + uid = client.uid, + args = Base.slice( arguments, 2 ), + instance; + + clients[ uid ] = client; + + if ( components[ comp ] ) { + if ( !pool[ uid ] ) { + pool[ uid ] = new components[ comp ]( client, me ); + } + + instance = pool[ uid ]; + + if ( instance[ fn ] ) { + return instance[ fn ].apply( instance, args ); + } + } + + return me.flashExec.apply( client, arguments ); + }; + + function handler( evt, obj ) { + var type = evt.type || evt, + parts, uid; + + parts = type.split('::'); + uid = parts[ 0 ]; + type = parts[ 1 ]; + + // console.log.apply( console, arguments ); + + if ( type === 'Ready' && uid === me.uid ) { + me.trigger('ready'); + } else if ( clients[ uid ] ) { + clients[ uid ].trigger( type.toLowerCase(), evt, obj ); + } + + // Base.log( evt, obj ); + } + + // flash的接受器。 + window[ jsreciver ] = function() { + var args = arguments; + + // 为了能捕获得到。 + setTimeout(function() { + handler.apply( null, args ); + }, 1 ); + }; + + this.jsreciver = jsreciver; + + this.destroy = function() { + // @todo 删除池子中的所有实例 + return destroy && destroy.apply( this, arguments ); + }; + + this.flashExec = function( comp, fn ) { + var flash = me.getFlash(), + args = Base.slice( arguments, 2 ); + + return flash.exec( this.uid, comp, fn, args ); + }; + + // @todo + } + + Base.inherits( Runtime, { + constructor: FlashRuntime, + + init: function() { + var container = this.getContainer(), + opts = this.options, + html; + + // if not the minimal height, shims are not initialized + // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc) + container.css({ + position: 'absolute', + top: '-8px', + left: '-8px', + width: '9px', + height: '9px', + overflow: 'hidden' + }); + + // insert flash object + html = '<object id="' + this.uid + '" type="application/' + + 'x-shockwave-flash" data="' + opts.swf + '" '; + + if ( Base.browser.ie ) { + html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; + } + + html += 'width="100%" height="100%" style="outline:0">' + + '<param name="movie" value="' + opts.swf + '" />' + + '<param name="flashvars" value="uid=' + this.uid + + '&jsreciver=' + this.jsreciver + '" />' + + '<param name="wmode" value="transparent" />' + + '<param name="allowscriptaccess" value="always" />' + + '</object>'; + + container.html( html ); + }, + + getFlash: function() { + if ( this._flash ) { + return this._flash; + } + + this._flash = $( '#' + this.uid ).get( 0 ); + return this._flash; + } + + }); + + FlashRuntime.register = function( name, component ) { + component = components[ name ] = Base.inherits( CompBase, $.extend({ + + // @todo fix this later + flashExec: function() { + var owner = this.owner, + runtime = this.getRuntime(); + + return runtime.flashExec.apply( owner, arguments ); + } + }, component ) ); + + return component; + }; + + if ( getFlashVersion() >= 11.4 ) { + Runtime.addRuntime( type, FlashRuntime ); + } + + return FlashRuntime; + }); + /** + * @fileOverview FilePicker + */ + define('runtime/flash/filepicker',[ + 'base', + 'runtime/flash/runtime' + ], function( Base, FlashRuntime ) { + var $ = Base.$; + + return FlashRuntime.register( 'FilePicker', { + init: function( opts ) { + var copy = $.extend({}, opts ), + len, i; + + // 修复Flash再没有设置title的情况下无法弹出flash文件选择框的bug. + len = copy.accept && copy.accept.length; + for ( i = 0; i < len; i++ ) { + if ( !copy.accept[ i ].title ) { + copy.accept[ i ].title = 'Files'; + } + } + + delete copy.button; + delete copy.id; + delete copy.container; + + this.flashExec( 'FilePicker', 'init', copy ); + }, + + destroy: function() { + this.flashExec( 'FilePicker', 'destroy' ); + } + }); + }); + /** + * @fileOverview 图片压缩 + */ + define('runtime/flash/image',[ + 'runtime/flash/runtime' + ], function( FlashRuntime ) { + + return FlashRuntime.register( 'Image', { + // init: function( options ) { + // var owner = this.owner; + + // this.flashExec( 'Image', 'init', options ); + // owner.on( 'load', function() { + // debugger; + // }); + // }, + + loadFromBlob: function( blob ) { + var owner = this.owner; + + owner.info() && this.flashExec( 'Image', 'info', owner.info() ); + owner.meta() && this.flashExec( 'Image', 'meta', owner.meta() ); + + this.flashExec( 'Image', 'loadFromBlob', blob.uid ); + } + }); + }); + /** + * @fileOverview Transport flash实现 + */ + define('runtime/flash/transport',[ + 'base', + 'runtime/flash/runtime', + 'runtime/client' + ], function( Base, FlashRuntime, RuntimeClient ) { + var $ = Base.$; + + return FlashRuntime.register( 'Transport', { + init: function() { + this._status = 0; + this._response = null; + this._responseJson = null; + }, + + send: function() { + var owner = this.owner, + opts = this.options, + xhr = this._initAjax(), + blob = owner._blob, + server = opts.server, + binary; + + xhr.connectRuntime( blob.ruid ); + + if ( opts.sendAsBinary ) { + server += (/\?/.test( server ) ? '&' : '?') + + $.param( owner._formData ); + + binary = blob.uid; + } else { + $.each( owner._formData, function( k, v ) { + xhr.exec( 'append', k, v ); + }); + + xhr.exec( 'appendBlob', opts.fileVal, blob.uid, + opts.filename || owner._formData.name || '' ); + } + + this._setRequestHeader( xhr, opts.headers ); + xhr.exec( 'send', { + method: opts.method, + url: server, + forceURLStream: opts.forceURLStream, + mimeType: 'application/octet-stream' + }, binary ); + }, + + getStatus: function() { + return this._status; + }, + + getResponse: function() { + return this._response || ''; + }, + + getResponseAsJson: function() { + return this._responseJson; + }, + + abort: function() { + var xhr = this._xhr; + + if ( xhr ) { + xhr.exec('abort'); + xhr.destroy(); + this._xhr = xhr = null; + } + }, + + destroy: function() { + this.abort(); + }, + + _initAjax: function() { + var me = this, + xhr = new RuntimeClient('XMLHttpRequest'); + + xhr.on( 'uploadprogress progress', function( e ) { + var percent = e.loaded / e.total; + percent = Math.min( 1, Math.max( 0, percent ) ); + return me.trigger( 'progress', percent ); + }); + + xhr.on( 'load', function() { + var status = xhr.exec('getStatus'), + readBody = false, + err = '', + p; + + xhr.off(); + me._xhr = null; + + if ( status >= 200 && status < 300 ) { + readBody = true; + } else if ( status >= 500 && status < 600 ) { + readBody = true; + err = 'server'; + } else { + err = 'http'; + } + + if ( readBody ) { + me._response = xhr.exec('getResponse'); + + me._response = decodeURIComponent( me._response ); + + // flash 处理可能存在 bug, 没辙只能靠 js 了 + // try { + // me._responseJson = xhr.exec('getResponseAsJson'); + // } catch ( error ) { + + p = window.JSON && window.JSON.parse || function( s ) { + try { + return new Function('return ' + s).call(); + } catch ( err ) { + return {}; + } + }; + me._responseJson = me._response ? p(me._response) : {}; + + // } + } + + xhr.destroy(); + xhr = null; + + return err ? me.trigger( 'error', err ) : me.trigger('load'); + }); + + xhr.on( 'error', function() { + xhr.off(); + me._xhr = null; + me.trigger( 'error', 'http' ); + }); + + me._xhr = xhr; + return xhr; + }, + + _setRequestHeader: function( xhr, headers ) { + $.each( headers, function( key, val ) { + xhr.exec( 'setRequestHeader', key, val ); + }); + } + }); + }); + /** + * @fileOverview Blob Html实现 + */ + define('runtime/flash/blob',[ + 'runtime/flash/runtime', + 'lib/blob' + ], function( FlashRuntime, Blob ) { + + return FlashRuntime.register( 'Blob', { + slice: function( start, end ) { + var blob = this.flashExec( 'Blob', 'slice', start, end ); + + return new Blob( blob.uid, blob ); + } + }); + }); + /** + * @fileOverview Md5 flash实现 + */ + define('runtime/flash/md5',[ + 'runtime/flash/runtime' + ], function( FlashRuntime ) { + + return FlashRuntime.register( 'Md5', { + init: function() { + // do nothing. + }, + + loadFromBlob: function( blob ) { + return this.flashExec( 'Md5', 'loadFromBlob', blob.uid ); + } + }); + }); + /** + * @fileOverview 完全版本。 + */ + define('preset/all',[ + 'base', + + // widgets + 'widgets/filednd', + 'widgets/filepaste', + 'widgets/filepicker', + 'widgets/image', + 'widgets/queue', + 'widgets/runtime', + 'widgets/upload', + 'widgets/validator', + 'widgets/md5', + + // runtimes + // html5 + 'runtime/html5/blob', + 'runtime/html5/dnd', + 'runtime/html5/filepaste', + 'runtime/html5/filepicker', + 'runtime/html5/imagemeta/exif', + 'runtime/html5/androidpatch', + 'runtime/html5/image', + 'runtime/html5/transport', + 'runtime/html5/md5', + + // flash + 'runtime/flash/filepicker', + 'runtime/flash/image', + 'runtime/flash/transport', + 'runtime/flash/blob', + 'runtime/flash/md5' + ], function( Base ) { + return Base; + }); + /** + * @fileOverview 日志组件,主要用来收集错误信息,可以帮助 webuploader 更好的定位问题和发展。 + * + * 如果您不想要启用此功能,请在打包的时候去掉 log 模块。 + * + * 或者可以在初始化的时候通过 options.disableWidgets 属性禁用。 + * + * 如: + * WebUploader.create({ + * ... + * + * disableWidgets: 'log', + * + * ... + * }) + */ + define('widgets/log',[ + 'base', + 'uploader', + 'widgets/widget' + ], function( Base, Uploader ) { + var $ = Base.$, + logUrl = ' http://static.tieba.baidu.com/tb/pms/img/st.gif??', + product = (location.hostname || location.host || 'protected').toLowerCase(), + + // 只针对 baidu 内部产品用户做统计功能。 + enable = product && /baidu/i.exec(product), + base; + + if (!enable) { + return; + } + + base = { + dv: 3, + master: 'webuploader', + online: /test/.exec(product) ? 0 : 1, + module: '', + product: product, + type: 0 + }; + + function send(data) { + var obj = $.extend({}, base, data), + url = logUrl.replace(/^(.*)\?/, '$1' + $.param( obj )), + image = new Image(); + + image.src = url; + } + + return Uploader.register({ + name: 'log', + + init: function() { + var owner = this.owner, + count = 0, + size = 0; + + owner + .on('error', function(code) { + send({ + type: 2, + c_error_code: code + }); + }) + .on('uploadError', function(file, reason) { + send({ + type: 2, + c_error_code: 'UPLOAD_ERROR', + c_reason: '' + reason + }); + }) + .on('uploadComplete', function(file) { + count++; + size += file.size; + }). + on('uploadFinished', function() { + send({ + c_count: count, + c_size: size + }); + count = size = 0; + }); + + send({ + c_usage: 1 + }); + } + }); + }); + /** + * @fileOverview Uploader上传类 + */ + define('webuploader',[ + 'preset/all', + 'widgets/log' + ], function( preset ) { + return preset; + }); + return require('webuploader'); +}); diff --git a/static/src/mmgrid/mmGrid-all.js b/static/src/mmgrid/mmGrid-all.js new file mode 100755 index 0000000..5299725 --- /dev/null +++ b/static/src/mmgrid/mmGrid-all.js @@ -0,0 +1,1611 @@ +/** + * Author: meimeidev + */ + +!function($){ + var MMGrid = function (element, options) { + this._id = (((1 + Math.random()) * 0x10000) | 0).toString(16); + this._loadCount = 0; + this.opts = options; + this._initLayout($(element)); + this._initHead(); + this._initOptions(); + this._initEvents(); + this._setColsWidth(); + if(this.opts.fullWidthRows){ + this._fullWidthRows(); + } + + //初始化插件 + for(var i=0; i< this.opts.plugins.length; i++){ + var plugin = this.opts.plugins[i]; + plugin.init($.extend(element, this)); + } + + if(options.autoLoad){ + var that = this; + this.opts = options; + setTimeout(function(){ + + if(options.url){ + that.load(); + }else{ + that.load(options.items); + } + },0); //chrome style problem + } + + }; + + //see: http://tanalin.com/en/articles/ie-version-js/ + var browser = function(){ + var isIE=!!window.ActiveXObject; + var isIE10 = isIE && !!window.atob; + var isIE9 = isIE && document.addEventListener && !window.atob; + var isIE8 = isIE && document.querySelector && !document.addEventListener; + var isIE7 = isIE && window.XMLHttpRequest && !document.querySelector; + var isIE6 = isIE && !window.XMLHttpRequest; + + return { + isIE: isIE + , isIE6: isIE6 + , isIE7: isIE7 + , isIE8: isIE8 + , isIE9: isIE9 + , isIE10: isIE10 + }; + }(); + + MMGrid.prototype = { + + _initLayout: function($el){ + var opts = this.opts; + var $elParent = $el.parent(); + var elIndex = $el.index(); + + var mmGrid = [ + '<div class="mmGrid">', + '<style></style>', + '<div class="mmg-headWrapper">', + '<table class="mmg-head" cellspacing="0"></table>', + '</div>', + '<div class="mmg-colResizePointer"></div>', + '<div class="mmg-colResizePointer-before"></div>', + '<div class="mmg-backboard">', + '<a class="mmg-btnBackboardUp"></a>', + '</div>', + '<div class="mmg-bodyWrapper"></div>', + '<a class="mmg-btnBackboardDn"></a>', + '<div class="mmg-message">'+ this.opts.noDataText +'</div>', + '<div class="mmg-mask mmg-transparent"></div>', + '<div class="mmg-loading">', + '<div class="mmg-loadingImg"></div>', + '<div class="mmg-loadingText">'+ this.opts.loadingText +'</div>', + '</div>', + + '</div>' + ]; + //fix in IE7,IE6 + if(browser.isIE7 || browser.isIE6){ + $el.prop('cellspacing',0); + } + + + //cached object + var $mmGrid = $(mmGrid.join('')); + this.$mmGrid = $mmGrid; + this.$style = $mmGrid.find('style'); + this.$headWrapper = $mmGrid.find('.mmg-headWrapper'); + this.$head = $mmGrid.find('.mmg-head'); + this.$backboard = $mmGrid.find('.mmg-backboard'); + this.$bodyWrapper = $mmGrid.find('.mmg-bodyWrapper'); + this.$body = $el.removeAttr("style").addClass('mmg-body'); + this._insertEmptyRow(); + this.$body.appendTo(this.$bodyWrapper); + + + + //放回原位置 + if(elIndex === 0 || $elParent.children().length == 0){ + $elParent.prepend(this.$mmGrid); + }else{ + $elParent.children().eq(elIndex-1).after(this.$mmGrid); + } + + + // fix in ie6 + if(browser.isIE6 && (!opts.width || opts.width === 'auto')){ + $mmGrid.width('100%'); + $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width())); + }else{ + $mmGrid.width(opts.width); + } + + if(browser.isIE6 && (!opts.height || opts.height === 'auto')){ + $mmGrid.height('100%'); + $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height())); + }else{ + $mmGrid.height(opts.height); + } + + if(opts.checkCol){ + var chkHtml = opts.multiSelect ? '<input type="checkbox" class="checkAll" >' + : '<input type="checkbox" disabled="disabled" class="checkAll">'; + opts.cols.unshift({title:chkHtml,width: 20, align: 'center' ,lockWidth: true, checkCol: true, renderer:function(){ + return '<input type="checkbox" class="mmg-check">'; + }}); + } + + if(opts.indexCol){ + opts.cols.unshift({title:'#',width: opts.indexColWidth, align: 'center' ,lockWidth: true, indexCol:true, renderer:function(val,item,rowIndex){ + return '<label class="mmg-index">' + (rowIndex+1) + '</label>'; + }}); + } + + } + + ,_expandCols: function(cols){ + var newCols = []; + if(!cols){ + return newCols; + } + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(col.cols){ + newCols.push(col); + newCols.push.apply(newCols,this._expandCols(col.cols)); + }else{ + newCols.push(col); + } + } + return newCols; + } + ,_leafCols: function(){ + var opts = this.opts; + var newCols = []; + var cols = this._expandCols(opts.cols); + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(!col.cols){ + newCols.push(col); + } + } + return newCols; + } + + ,_expandThs: function(){ + return this.$head.find('th').sort(function(a, b){ + return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex')); + }); + } + + ,_leafThs: function(){ + return this.$head.find('th').filter(function(){ + return !$.data(this,'col').cols; + }).sort(function(a, b){ + return parseInt($(a).data('colindex')) - parseInt($(b).data('colindex')); + }); + } + + + ,_colsWithTitleDeep: function(cols,deep){ + var newCols = []; + if(!cols){ + return newCols; + } + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(deep === 1){ + newCols.push(col); + }else{ + newCols.push.apply(newCols, this._colsWithTitleDeep(col.cols, deep-1)); + } + } + return newCols; + } + + ,_titleDeep: function(cols){ + var deep = 1; + for(var colIndex=0; colIndex<cols.length; colIndex++){ + var col = cols[colIndex]; + if(col.cols){ + var newDeep = 1 + this._titleDeep(col.cols); + if(deep < newDeep){ + deep = newDeep; + } + } + } + return deep; + } + + , _titleHtml: function(col, rowspan){ + var opts = this.opts; + + var titleHtml = []; + if(!col.cols){ + titleHtml.push('<th class="'); + var colIndex = $.inArray(col, this._expandCols(opts.cols)); + titleHtml.push(this._genColClass(colIndex)); + titleHtml.push(' " '); + titleHtml.push(' rowspan="'); + titleHtml.push(rowspan); + titleHtml.push('" colspan="'); + titleHtml.push(1); + titleHtml.push('" data-colIndex="'); + titleHtml.push(colIndex); + titleHtml.push('" >'); + titleHtml.push('<div class="mmg-titleWrapper" >'); + titleHtml.push('<span class="mmg-title '); + if(col.sortable) titleHtml.push('mmg-canSort '); + titleHtml.push('">'); + if(col.titleHtml){ + titleHtml.push(col.titleHtml); + }else{ + titleHtml.push(col.title); + } + titleHtml.push('</span><div class="mmg-sort"></div>'); + if(!col.lockWidth) titleHtml.push('<div class="mmg-colResize"></div>'); + titleHtml.push('</div></th>'); + }else{ + var displayColsLength = col.cols.length; + $.each(col.cols, function(index, item){ + if(item.hidden){ + displayColsLength--; + } + }); + if(displayColsLength === 0){ + col.hidden = true; + } + titleHtml.push('<th class="'); + var colIndex = $.inArray(col, this._expandCols(opts.cols)); + titleHtml.push(this._genColClass(colIndex)); + titleHtml.push(' mmg-groupCol" '); + titleHtml.push(' rowspan="'); + titleHtml.push(rowspan-1); + titleHtml.push('" colspan="'); + titleHtml.push(displayColsLength); + titleHtml.push('" data-colIndex="'); + titleHtml.push(colIndex); + titleHtml.push('" >'); + titleHtml.push('<div class="mmg-titleWrapper" >'); + titleHtml.push('<span class="mmg-title '); + if(col.sortable) titleHtml.push('mmg-canSort '); + titleHtml.push('">'); + if(col.titleHtml){ + titleHtml.push(col.titleHtml); + }else{ + titleHtml.push(col.title); + } + titleHtml.push('</span><div class="mmg-sort"></div>'); + titleHtml.push('</div></th>'); + } + + return titleHtml.join(""); + } + + , _initHead: function(){ + var that = this; + var opts = this.opts; + var $head = this.$head; + + if(opts.cols){ + var theadHtmls = ['<thead>']; + + //获取标题深度 + var titleDeep = that._titleDeep(opts.cols); + for(var deep=1; deep<= titleDeep; deep++){ + var cols = that._colsWithTitleDeep(opts.cols, deep); + theadHtmls.push('<tr>'); + for(var colIndex=0; colIndex< cols.length; colIndex++){ + var col = cols[colIndex]; + theadHtmls.push(this._titleHtml(col, titleDeep-deep+1)); + } + theadHtmls.push('</tr>'); + } + theadHtmls.push('</thead>'); + $head.html(theadHtmls.join('')); + } + + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + $.each($ths,function(index){ + if(!expandCols[index].width){ + expandCols[index].width = 100; + } + $.data(this,'col-width',expandCols[index].width); + $.data(this,'col',expandCols[index]); + }); + + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $bodyWrapper = this.$bodyWrapper; + if(opts.height !== 'auto'){ + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + + + + //初始化排序状态 + if(opts.sortName){ + for(var colIndex=0; colIndex< expandCols.length; colIndex++){ + var col = expandCols[colIndex]; + if(col.sortName === opts.sortName || col.name === opts.sortName){ + var $th= $ths.eq(colIndex); + $.data($th.find('.mmg-title')[0],'sortStatus',opts.sortStatus); + $th.find('.mmg-sort').addClass('mmg-'+opts.sortStatus); + } + } + } + } + + , _initOptions: function(){ + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $backboard = this.$backboard; + $mmGrid.find('a.mmg-btnBackboardDn').css({ + 'top': $headWrapper.outerHeight(true) + }).slideUp('fast'); + + var cols = this._leafCols(); + if(cols){ + var bbHtml = ['<h1>显示列</h1>']; + for(var colIndex=0; colIndex<cols.length; colIndex++){ + bbHtml.push('<label '); + if(cols[colIndex].checkCol || cols[colIndex].indexCol){ + bbHtml.push('style="display:none;" '); + } + var col = cols[colIndex]; + bbHtml.push('><input type="checkbox" '); + if(!col.hidden) bbHtml.push('checked="checked"'); + if(col.lockDisplay) bbHtml.push(' disabled="disabled"'); + bbHtml.push('/><span>'); + if(col.title){ + bbHtml.push(col.title); + }else{ + bbHtml.push('未命名'); + } + + bbHtml.push('</span></label>'); + } + $backboard.append($(bbHtml.join(''))); + } + } + + , _initEvents: function(){ + var that = this; + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $head = this.$head; + var $bodyWrapper = this.$bodyWrapper; + var $body = this.$body; + var $backboard = this.$backboard; + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + var leafCols = this._leafCols(); + + //调整浏览器 + if(opts.width === 'auto' || opts.height === 'auto' || (typeof opts.width === 'string' && opts.width.indexOf('%') === opts.width.length-1) || + typeof opts.height === 'string' && opts.height.indexOf('%') === opts.height.length-1){ + $(window).on('resize', function(){ + that.resize(); + }); + } + + //滚动条事件 + $bodyWrapper.on('scroll', function(){ + $head.css('left',- $(this).scrollLeft()); + }); + + //向下按钮 + var $btnBackboardDn = $mmGrid.find('a.mmg-btnBackboardDn').on('click', function(){ + var backboardHeight = $mmGrid.height() - $headWrapper.outerHeight(true); + if(opts.height === 'auto'&& opts.backboardMinHeight !== 'auto' && backboardHeight < opts.backboardMinHeight){ + backboardHeight = opts.backboardMinHeight; + } + $backboard.height(backboardHeight); + if(opts.height === 'auto'){ + $mmGrid.height($headWrapper.outerHeight(true) + $backboard.outerHeight(true)); + } + $backboard.slideDown(); + $btnBackboardDn.slideUp('fast'); + + that._hideMessage(); + }); + $body.on('mouseenter', function(){ + $btnBackboardDn.slideUp('fast'); + }); + $mmGrid.on('mouseleave', function(){ + $btnBackboardDn.slideUp('fast'); + }); + $headWrapper.on('mouseenter',function(){ + if($backboard.is(':hidden') && opts.showBackboard){ + $btnBackboardDn.slideDown('fast'); + } + }); + //向上按钮 + $mmGrid.find('a.mmg-btnBackboardUp').on('click', function(){ + $backboard.slideUp().queue(function(next){ + if(!that.rowsLength() || (that.rowsLength() === 1 && $body.find('tr.emptyRow').length === 1)){ + that._showNoData(); + } + if(opts.height === 'auto'){ + $mmGrid.height('auto'); + } + next(); + }); + }); + + //隐藏列 + $backboard.on('click', ':checkbox', function(){ + var index = $backboard.find('label').index($(this).parent()); + //最后一个不隐藏 + var last = 1; + if(opts.checkCol){ + last = last + 1; + } + if(opts.indexCol){ + last = last + 1; + } + if($backboard.find('label :checked').length < last){ + this.checked = true; + return; + } + + var col = leafCols[index]; + if(this.checked){ + col.hidden = false; + + }else{ + col.hidden = true; + } + + var $ths = $head.find('th'); + for(var colIndex=$ths.length-1; colIndex>=0; colIndex--){ + var $th = $ths.eq(colIndex); + var iCol = $th.data('col'); + if(iCol.cols){ + var hidden = true; + var colspan = 0; + $.each(iCol.cols,function(index,item){ + if(!item.hidden){ + hidden = false; + colspan++; + } + }); + //IE bug + if(colspan !== 0){ + $th.prop('colspan',colspan); + } + iCol.hidden = hidden; + } + } + + that._setColsWidth(); + $backboard.height($mmGrid.height() - $headWrapper.outerHeight(true)); + if(opts.height !== 'auto'){ + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + $mmGrid.find('a.mmg-btnBackboardDn').css({ + 'top': $headWrapper.outerHeight(true) + }) + }); + + + + //排序事件 + $head.on('click', '.mmg-title', function(){ + var $this = $(this); + var $titles = $ths.find('.mmg-title'); + + //当前列不允许排序 + var col =$this.parent().parent().data('col'); + if(!col.sortable){ + return; + } + //取得当前列下一个排序状态 + var sortStatus = $.data(this, 'sortStatus') === 'asc' ? 'desc' : 'asc'; + //清除排序状态 + $.each($titles, function(){ + $.removeData(this,'sortStatus'); + }); + $ths.find('.mmg-sort').removeClass('mmg-asc').removeClass('mmg-desc'); + //设置当前列排序状态 + $.data(this, 'sortStatus', sortStatus); + $this.siblings('.mmg-sort').addClass('mmg-'+sortStatus); + + if(opts.url && opts.remoteSort){ + that.load() + }else{ + that._nativeSorter($.inArray(col, leafCols), sortStatus); + that._setStyle(); + } + }).on('mousedown', '.mmg-colResize', function(e){ + //调整列宽 + var $resize = $(this); + var start = e.pageX; + var $colResizePointer = $mmGrid.find('.mmg-colResizePointer') + .css('left', e.pageX - $headWrapper.offset().left).show(); + + var scrollLeft = $head.position().left; + var $colResizePointerBefore = $mmGrid.find('.mmg-colResizePointer-before') + .css('left', $resize.parent().parent().position().left + scrollLeft).show(); + //取消文字选择 + document.selection && document.selection.empty && ( document.selection.empty(), 1) + || window.getSelection && window.getSelection().removeAllRanges(); + document.body.onselectstart = function () { + return false; + }; + $headWrapper.css('-moz-user-select','none'); + + $mmGrid.on('mousemove', function(e){ + $colResizePointer.css('left', e.pageX - $headWrapper.offset().left); + }).on('mouseup', function(e){ + //改变宽度 + var $th = $resize.parent().parent(); + var width = $th.width() + e.pageX - start; + $.data($th[0], 'col-width', width); + that._setColsWidth(); + $headWrapper.mouseleave(); + }).on('mouseleave',function(){ + $mmGrid.off('mouseup').off('mouseleave').off('mousemove'); + $colResizePointer.hide(); + $colResizePointerBefore.hide(); + document.body.onselectstart = function(){ + return true;//开启文字选择 + }; + $headWrapper.css('-moz-user-select','text'); + }); + }); + + //选中事件 + var $body = this.$body; + $body.on('click','td',function(e){ + var $this = $(this); + var event = jQuery.Event("cellSelected"); + event.target = e.target; + that.$body.triggerHandler(event, [$.data($this.parent()[0], 'item'), $this.parent().index(), $this.index()]); + + if(event.isPropagationStopped()){ + return; + } + if(!$this.parent().hasClass('selected')){ + that.select($this.parent().index()); + }else{ + that.deselect($this.parent().index()); + } + }); + + $body.on('click','tr > td .mmg-check',function(e){ + e.stopPropagation(); + var $this = $(this); + if(this.checked){ + that.select($($this.parents('tr')[0]).index()); + }else{ + that.deselect($($this.parents('tr')[0]).index()); + } + }); + + //checkbox列 + if(opts.checkCol){ + $head.find('th .checkAll').on('click', function(){ + if(this.checked){ + that.select('all'); + }else{ + that.deselect('all'); + } + }); + } + + //IE6不支持hover + if (browser.isIE6){ + $body.on('mouseenter','tr', function () { + $(this).toggleClass('hover'); + }).on('mouseleave','tr', function () { + $(this).toggleClass('hover'); + }); + }; + + + } + + , _rowHtml: function(item, rowIndex){ + var opts = this.opts; + var expandCols = this._expandCols(opts.cols); + var leafCols = this._leafCols(); + + + if($.isPlainObject(item)){ + var trHtml = []; + trHtml.push('<tr>'); + for(var colIndex=0; colIndex < leafCols.length; colIndex++){ + var col = leafCols[colIndex]; + trHtml.push('<td class="'); + var index = $.inArray(col, expandCols); + trHtml.push(this._genColClass(index)); + if(opts.nowrap){ + trHtml.push(' nowrap'); + } + trHtml.push('"><span class="'); + if(opts.nowrap){ + trHtml.push('nowrap'); + } + trHtml.push('">'); + if(col.renderer){ + trHtml.push(col.renderer(item[col.name],item,rowIndex)); + }else{ + trHtml.push(item[col.name]); + } + + trHtml.push('</span></td>'); + }; + trHtml.push('</tr>'); + return trHtml.join(''); + } + } + + , _populate: function(items){ + var opts = this.opts; + var $body = this.$body; + + this._hideMessage(); + if(items && items.length !== 0 && opts.cols){ + + var tbodyHtmls = []; + tbodyHtmls.push('<tbody>'); + for(var rowIndex=0; rowIndex < items.length; rowIndex++){ + var item = items[rowIndex]; + tbodyHtmls.push(this._rowHtml(item, rowIndex)); + } + tbodyHtmls.push('</tbody>'); + $body.empty().html(tbodyHtmls.join('')); + var $trs = $body.find('tr'); + for(var rowIndex=0; rowIndex < items.length; rowIndex++){ + $.data($trs.eq(rowIndex)[0],'item',items[rowIndex]); + } + }else{ + this._insertEmptyRow(); + this._showNoData(); + } + this._setStyle(); + + if(opts.fullWidthRows && this._loadCount <= 1){ + this._fullWidthRows(); + } + } + + , _insertEmptyRow: function(){ + var $body = this.$body; + $body.empty().html('<tbody><tr class="emptyRow"><td style="border: 0px;background: none;">&nbsp;</td></tr></tbody>'); + } + , _removeEmptyRow: function(){ + var $body = this.$body; + $body.find('tr.emptyRow').remove(); + } + + /* 生成列类 */ + , _genColClass: function(colIndex){ + return 'mmg'+ this._id +'-col'+colIndex; + } + + , _setStyle: function(){ + var $head = this.$head; + var $ths = this._expandThs(); + var $body = this.$body; + var leafCol = this._leafCols(); + + //head + $ths.eq(0).addClass('first'); + $ths.eq(-1).addClass('last'); + //body + $body.find('tr,td').removeClass('even') + .removeClass('colSelected').removeClass('colSelectedEven'); + + $body.find('tr:odd').addClass('even'); + + + + var sortIndex = $.inArray($head.find('.mmg-title').filter(function(){ + return $.data(this,'sortStatus') === 'asc' || $(this).data('sortStatus') === 'desc'; + }).parent().parent().data('col'), leafCol); + + $body.find('tr > td:nth-child('+(sortIndex+1)+')').addClass('colSelected') + .filter(':odd').addClass('colSelectedEven'); + + this._resizeHeight(); + + } + , _setColsWidth: function(){ + var opts = this.opts; + var $style = this.$style; + var $head = this.$head; + + var $bodyWrapper = this.$bodyWrapper; + var $body = this.$body; + var $ths = this._expandThs(); + var expandCols = this._expandCols(opts.cols); + + var scrollTop = $bodyWrapper.scrollTop(); + var scrollLeft = $head.position().left; + + $bodyWrapper.width(9999); + $body.width('auto'); + var styleText = []; + for(var colIndex=0; colIndex<$ths.length; colIndex++){ + var $th = $ths.eq(colIndex); + styleText.push('.mmGrid .'+this._genColClass(colIndex) + ' {'); + var width = $.data($th[0],'col-width'); + styleText.push('width: '+ width +'px;'); + styleText.push('max-width: '+ width +'px;'); + + var col = expandCols[colIndex]; + if(col.align){ + styleText.push('text-align: '+col.align+';'); + } + if(col.hidden){ + styleText.push('display: none; '); + } + styleText.push(' }'); + } + + $body.detach(); + try{ + $style.text(styleText.join('')); + }catch(error){ + $style[0].styleSheet.cssText = styleText.join('');//IE fix + } + $body.width($head.width()-2); + $bodyWrapper.width('100%'); + $bodyWrapper.append($body); + + //调整滚动条 + + $bodyWrapper.scrollLeft(-scrollLeft); + if($bodyWrapper.scrollLeft() === 0){ + $head.css('left', 0); + } + + $bodyWrapper.scrollTop(scrollTop); + } + , _fullWidthRows: function(){ + var opts = this.opts; + var $bodyWrapper = this.$bodyWrapper; + var $mmGrid = this.$mmGrid; + var $head = this.$head; + var scrollWidth = $bodyWrapper.width() - $bodyWrapper[0].clientWidth; + + if(scrollWidth && browser.isIE){ + scrollWidth = scrollWidth + 1; + } + + var fitWidth = $mmGrid.width() - $head.width() - scrollWidth; + if(fitWidth < -20){ + return; + } + + var thsArr = []; + var $ths = this._leafThs(); + var leafCol = this._leafCols(); + for(var i=0; i< leafCol.length; i++){ + var col = leafCol[i]; + var $th = $ths.eq(i); + if(!col.lockWidth && $th.is(':visible')){ + thsArr.push($th); + } + } + + var increaseWidth = Math.floor(fitWidth / thsArr.length); + var maxColWidthIndex = 0; + for(var i=0; i< thsArr.length; i++){ + var $th = thsArr[i]; + var colWidth = $.data($th[0], 'col-width') + increaseWidth; + $.data($th[0], 'col-width', colWidth); + + var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width'); + if(maxColWidth < colWidth){ + maxColWidthIndex = i; + } + } + + var remainWidth = fitWidth - increaseWidth * thsArr.length; + var maxColWidth = $.data(thsArr[maxColWidthIndex][0], 'col-width'); + $.data(thsArr[maxColWidthIndex][0], 'col-width', maxColWidth + remainWidth); + this._setColsWidth(); + } + + + , _showLoading: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-mask').show(); + + var $loading = $mmGrid.find('.mmg-loading'); + $loading.css({ + 'left': ($mmGrid.width() - $loading.width()) / 2, + 'top': ($mmGrid.height() - $loading.height()) / 2 + }).show(); + } + , _hideLoading: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-mask').hide(); + $mmGrid.find('.mmg-loading').hide(); + } + , _showNoData: function(){ + this._showMessage(this.opts.noDataText); + } + + , _showLoadError: function(){ + this._showMessage(this.opts.loadErrorText); + } + + , _showMessage: function(msg){ + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $message = $mmGrid.find('.mmg-message'); + $message.css({ + 'left': ($mmGrid.width() - $message.width()) / 2, + 'top': ($mmGrid.height() + $headWrapper.height() - $message.height()) / 2 + }).text(msg).show(); + } + , _hideMessage: function(){ + var $mmGrid = this.$mmGrid; + $mmGrid.find('.mmg-message').hide(); + } + + , _nativeSorter: function(colIndex, sortStatus){ + var leafCols = this._leafCols(); + var col = leafCols[colIndex]; + + this.$body.find('tr > td:nth-child('+(colIndex+1)+')') + .sortElements(function(a, b){ + var av = $.text($(a)); + var bv = $.text($(b)); + //排序前转换 + if(col.type === 'number'){ + av = parseFloat(av); + bv = parseFloat(bv); + }else{ + //各个浏览器localeCompare的结果不一致 + return sortStatus === 'desc' ? -av.localeCompare(bv) : av.localeCompare(bv); + } + return av > bv ? (sortStatus === 'desc' ? -1 : 1) : (sortStatus === 'desc' ? 1 : -1); + }, function(){ + return this.parentNode; + }); + } + + , _refreshSortStatus: function(){ + var $ths = this.$head.find('th'); + var sortColIndex = -1; + var sortStatus = ''; + $ths.find('.mmg-title').each(function(index, item){ + var status = $.data(item, 'sortStatus'); + if(status){ + sortColIndex = index; + sortStatus = status; + } + }); + var sortStatus = sortStatus === 'desc' ? 'asc' : 'desc'; + if(sortColIndex >=0){ + $ths.eq(sortColIndex).find('.mmg-title').data('sortStatus',sortStatus).click(); + } + } + + , _loadAjax: function(args){ + var that = this; + var opts = this.opts; + var params = {}; + //opt的params可以使函数,例如收集过滤的参数 + if($.isFunction(opts.params)){ + var p = opts.params(); + if(!p){ + return; + } + params = $.extend(params, p); + }else if($.isPlainObject(opts.params)){ + //modify by gzshangtao + if(args){ + opts.params = $.extend(params, args); + } + params = $.extend(params, opts.params); + } + + if(opts.remoteSort){ + var sortName = ''; + var sortStatus = ''; + var $titles = this.$head.find('.mmg-title'); + for(var colIndex=0; colIndex<$titles.length; colIndex++){ + var status = $.data($titles[colIndex], 'sortStatus'); + if(status){ + var col = $titles.eq(colIndex).parent().parent().data('col'); + sortName = col.sortName ? + col.sortName : col.name; + sortStatus = status; + } + } + if(sortName){ + params.sort = sortName+'.'+sortStatus; + } + } + + + //插件参数合并 + var pluginParams = {}; + for(var i=0; i< this.opts.plugins.length; i++){ + var plugin = this.opts.plugins[i]; + $.extend(pluginParams, plugin.params()); + } + params = $.extend(params, pluginParams); + + //合并load的参数 + params = $.extend(params, args); + that._showLoading(); + $.ajax({ + type: opts.method, + url: opts.url, + data: params, + dataType: 'json', + cache: opts.cache + }).done(function(data){ + try{ + //获得root对象 + var items = data; + if($.isArray(data[opts.root])){ + items = data[opts.root]; + } + that._populate(items); + that._hideLoading(); + if(!opts.remoteSort){ + that._refreshSortStatus(); + } + + if(data && $.isArray(data[opts.root])){ + data = $.extend(args, data); + } + that.$body.triggerHandler('loadSuccess', data); + + }catch(e){ + that._hideLoading(); + that._showLoadError(); + throw e; + } + + }).fail(function(data){ + that._hideLoading(); + that._showLoadError(); + that.$body.triggerHandler('loadError', data); + }); + + } + + , _loadNative: function(args){ + this._populate(args); + this._refreshSortStatus(); + this.$body.triggerHandler('loadSuccess', args); + } + , load: function(args){ + try{ + var modify = 'gzshangtao'; + var opts = this.opts; + this._hideMessage(); + this._loadCount = this._loadCount + 1 ; + + if($.isArray(args)){ + //加载本地数据 + this._loadNative(args); + }else if(opts.url){ + this._loadAjax(args); + }else if(opts.items){ + this._loadNative(opts.items); + }else{ + this._loadNative([]); + } + }catch(e){ + this._showLoadError(); + throw e; + } + } + + //重设尺寸--modify by gzshangtao + , resize: function(_opts){ + if(_opts && _opts.width)this.opts.width = _opts.width; + if(_opts && _opts.height)this.opts.height = _opts.height; + var opts = this.opts; + var $mmGrid = this.$mmGrid; + var $headWrapper = this.$headWrapper; + var $bodyWrapper = this.$bodyWrapper; + + // fix in ie6 + if(browser.isIE6 && (!opts.width || opts.width === 'auto')){ + $mmGrid.width('100%'); + $mmGrid.width($mmGrid.width() - ($mmGrid.outerWidth(true) - $mmGrid.width())); + }else{ + $mmGrid.width(opts.width); + } + + if(opts.height !== 'auto'){ + if(browser.isIE6 && (!opts.height || opts.height === 'auto')){ + $mmGrid.height('100%'); + $mmGrid.height($mmGrid.height() - ($mmGrid.outerHeight(true) - $mmGrid.height())); + }else{ + $mmGrid.height(opts.height); + } + + $bodyWrapper.height($mmGrid.height() - $headWrapper.outerHeight(true)); + } + + //调整message + var $message = $mmGrid.find('.mmg-message'); + if($message.is(':visible')){ + $message.css({ + 'left': ($mmGrid.width() - $message.width()) / 2, + 'top': ($mmGrid.height() + $headWrapper.height() - $message.height()) / 2 + }); + } + //调整loading + var $mask = $mmGrid.find('.mmg-mask'); + if($mask.is(':visible')){ + $mask.width($mmGrid.width()).height($mmGrid.height()); + var $loadingWrapper = $mmGrid.find('.mmg-loading'); + $loadingWrapper.css({ + 'left': ($mmGrid.width() - $loadingWrapper.width()) / 2, + 'top': ($mmGrid.height() - $loadingWrapper.height()) / 2 + }) + } + + $bodyWrapper.trigger('scroll'); + + this._resizeHeight(); + } + + , _resizeHeight: function(){ + var opts = this.opts; + var $bodyWrapper = this.$bodyWrapper; + var $body= this.$body; + if(opts.height === 'auto' && browser.isIE7){ + $bodyWrapper.height('auto'); + if($bodyWrapper.width() < $body.width()){ + $bodyWrapper.height($bodyWrapper.height() + $bodyWrapper.height() - $bodyWrapper[0].clientHeight + 1); + } + } + } + + //选中 + , select: function(args){ + var opts = this.opts; + var $body = this.$body; + var $head = this.$head; + + if(typeof args === 'number'){ + var $tr = $body.find('tr').eq(args); + if(!opts.multiSelect){ + $body.find('tr.selected').removeClass('selected'); + if(opts.checkCol){ + $body.find('tr > td').find('.mmg-check').prop('checked',''); + } + } + if(!$tr.hasClass('selected')){ + $tr.addClass('selected'); + if(opts.checkCol){ + $tr.find('td .mmg-check').prop('checked','checked'); + } + } + }else if(typeof args === 'function'){ + $.each($body.find('tr'), function(index){ + if(args($.data(this, 'item'), index)){ + var $this = $(this); + if(!$this.hasClass('selected')){ + $this.addClass('selected'); + if(opts.checkCol){ + $this.find('td .mmg-check').prop('checked','checked'); + } + } + } + }); + }else if(args === undefined || (typeof args === 'string' && args === 'all')){ + $body.find('tr.selected').removeClass('selected'); + $body.find('tr').addClass('selected'); + $body.find('tr > td').find('.mmg-check').prop('checked','checked'); + }else{ + return; + } + + if(opts.checkCol){ + var $checks = $body.find('tr > td').find('.mmg-check'); + if($checks.length === $checks.filter(':checked').length){ + $head.find('th .checkAll').prop('checked','checked'); + } + } + + + } + //取消选中 + , deselect: function(args){ + var opts = this.opts; + var $body = this.$body; + var $head = this.$head; + if(typeof args === 'number'){ + $body.find('tr').eq(args).removeClass('selected'); + if(opts.checkCol){ + $body.find('tr').eq(args).find('td .mmg-check').prop('checked',''); + } + }else if(typeof args === 'function'){ + $.each($body.find('tr'), function(index){ + if(args($.data(this, 'item'), index)){ + $(this).removeClass('selected'); + if(opts.checkCol){ + $(this).find('td .mmg-check').prop('checked',''); + } + } + }); + }else if(args === undefined || (typeof args === 'string' && args === 'all')){ + $body.find('tr.selected').removeClass('selected'); + if(opts.checkCol){ + $body.find('tr > td').find('.mmg-check').prop('checked',''); + } + }else{ + return; + } + + $head.find('th .checkAll').prop('checked',''); + + } + , selectedRows: function(){ + var $body = this.$body; + var selected = []; + $.each($body.find('tr.selected'), function(index ,item){ + selected.push($.data(this,'item')); + }); + return selected; + } + + , selectedRowsIndex: function(){ + var $body = this.$body; + var $trs = this.$body.find('tr') + var selected = []; + $.each($body.find('tr.selected'), function(index){ + selected.push($trs.index(this)); + }); + return selected; + } + + , rows: function(){ + var $body = this.$body; + var items = []; + $.each($body.find('tr'), function(){ + items.push($.data(this,'item')); + }); + return items; + } + + , row: function(index){ + var $body = this.$body; + if(index !== undefined && index >= 0){ + var $tr = $body.find('tr').eq(index); + if($tr.length !== 0){ + return $.data($tr[0],'item'); + } + } + } + + , rowsLength: function(){ + var $body = this.$body; + var length = $body.find('tr').length; + if(length === 1 && $body.find('tr.emptyRow').length === 1){ + return 0; + } + return length; + } + + //添加数据,第一个参数可以为数组 + , addRow: function(item, index){ + var $tbody = this.$body.find('tbody'); + + if($.isArray(item)){ + for(var i=item.length-1; i >= 0; i--){ + this.addRow(item[i], index); + } + return ; + } + + if(!$.isPlainObject(item)){ + return ; + } + + this._hideMessage(); + this._removeEmptyRow(); + + var $tr; + + if(index === undefined || index < 0){ + $tr = $(this._rowHtml(item, this.rowsLength())); + $tbody.append($tr); + }else{ + $tr = $(this._rowHtml(item, index)); + if(index === 0){ + $tbody.prepend($tr); + }else{ + var $before = $tbody.find('tr').eq(index-1); + //找不到就插到最后 + if($before.length === 0){ + $tbody.append($tr); + }else{ + $before.after($($tr)); + } + } + } + $tr.data('item', item); + this._setStyle(); + + + this.$body.triggerHandler('rowInserted', [item, index]); + } + //更新行内容,两个参数都必填 + , updateRow: function(item, index){ + var opts = this.opts; + var $tbody = this.$body.find('tbody'); + if(!$.isPlainObject(item)){ + return ; + } + var oldItem = this.row(index); + + var $tr = $tbody.find('tr').eq(index); + var checked = $tr.find('td:first :checkbox').is(':checked'); + $tr.html(this._rowHtml(item, index).slice(4,-5)); + if(opts.checkCol){ + $tr.find('td:first :checkbox').prop('checked',checked); + } + + $tr.data('item', item); + this._setStyle(); + + this.$body.triggerHandler('rowUpdated', [oldItem, item, index]); + } + + //删除行,参数可以为索引数组 + , removeRow: function(index){ + var that = this; + var $tbody = that.$body.find('tbody'); + + if($.isArray(index)){ + for(var i=index.length-1; i >= 0; i--){ + that.removeRow(index[i]); + } + return ; + } + + if(index === undefined){ + var $trs = $tbody.find('tr'); + for(var i=$trs.length-1; i >= 0; i--){ + that.removeRow(i); + } + }else{ + var item = that.row(index); + $tbody.find('tr').eq(index).remove(); + this.$body.triggerHandler('rowRemoved', [item, index]); + } + this._setStyle(); + if(this.rowsLength() === 0){ + this._showNoData(); + this._insertEmptyRow(); + } + } + }; + + $.fn.mmGrid = function(){ + if(arguments.length === 0 || typeof arguments[0] === 'object'){ + var option = arguments[0] + , data = this.data('mmGrid') + , options = $.extend(true, {}, $.fn.mmGrid.defaults, option); + if (!data) { + data = new MMGrid(this, options); + this.data('mmGrid', data); + } + return $.extend(true, this, data); + } + if(typeof arguments[0] === 'string'){ + var data = this.data('mmGrid'); + var fn = data[arguments[0]]; + if(fn){ + var args = Array.prototype.slice.call(arguments); + return fn.apply(data,args.slice(1)); + } + } + }; + + $.fn.mmGrid.defaults = { + width: 'auto' + , height: '280px' + , cols: [] + , url: false + , params: {} + , method: 'POST' + , cache: false + , root: 'items' + , items: [] + , autoLoad: true + , remoteSort: false + , sortName: '' + , sortStatus: 'asc' + , loadingText: '正在载入...' + , noDataText: '没有数据' + , loadErrorText: '数据加载出现异常' + , multiSelect: false + , checkCol: false + , indexCol: false + , indexColWidth: 40 + , fullWidthRows: false + , nowrap: false + , showBackboard: true + , backboardMinHeight: 125 + , plugins: [] //插件 插件必须实现 init($mmGrid)和params()方法,参考mmPaginator + }; +// event : loadSuccess(e,data), loadError(e, data), cellSelected(e, item, rowIndex, colIndex) +// rowInserted(e,item, rowIndex), rowUpdated(e, oldItem, newItem, rowIndex), rowRemoved(e,item, rowIndex) +// + + + $.fn.mmGrid.Constructor = MMGrid; + + + // see: http://james.padolsey.com/javascript/sorting-elements-with-jquery/ + $.fn.sortElements = (function(){ + var sort = [].sort; + return function(comparator, getSortable) { + getSortable = getSortable || function(){return this;}; + var placements = this.map(function(){ + var sortElement = getSortable.call(this), + parentNode = sortElement.parentNode, + nextSibling = parentNode.insertBefore( + document.createTextNode(''), + sortElement.nextSibling + ); + return function() { + if (parentNode === this) { + throw new Error( + "You can't sort elements if any one is a descendant of another." + ); + } + parentNode.insertBefore(this, nextSibling); + parentNode.removeChild(nextSibling); + }; + }); + return sort.call(this, comparator).each(function(i){ + placements[i].call(getSortable.call(this)); + }); + }; + })(); +}(window.jQuery); + + +!function($){ + var MMPaginator = function(element, options){ + this.$el = $(element); + this.opts = options; + }; + + MMPaginator.prototype = { + _initLayout: function(){ + var that = this; + var $el = this.$el; + var opts = this.opts; + + $el.addClass("mmPaginator"); + var pgHtmls = [ + '<div class="totalCountLabel"></div>', + '<ul class="pageList"></ul>', + '<div class="limit"><select></select></div>' + ]; + $el.append($(pgHtmls.join(''))); + + this.$totalCountLabel = $el.find('.totalCountLabel'); + this.$pageList = $el.find('.pageList'); + this.$limitList = $el.find('.limit select'); + + var $limitList = this.$limitList + $.each(opts.limitList, function(){ + var $option = $('<option></option>') + .prop('value',this) + .text(that.formatString(opts.limitLabel,[this])); + $limitList.append($option); + }); + + $limitList.on('change', function(){ + $el.data('page', 1); + that.$mmGrid.load(); + }); + + } + + , _plain: function(page, totalCount, limit){ + var that = this; + var $el = this.$el; + var $pageList = this.$pageList; + + var totalPage = totalCount % limit === 0 ? parseInt(totalCount/limit) : parseInt(totalCount/limit) + 1; + totalPage = totalPage ? totalPage : 0; + if(totalPage === 0){ + page = 1; + }else if(page > totalPage){ + page = totalPage; + }else if(page < 1 && totalPage != 0){ + page = 1; + } + // + var $prev = $('<li class="prev"><a>«</a></li>'); + if(page<=1){ + $prev.addClass('disable'); + }else{ + $prev.find('a').on('click', function(){ + $el.data('page', page-1); + that.$mmGrid.load(); + }); + } + $pageList.append($prev); + ///// + var list = [1]; + if(page > 4 ){ + list.push('...'); + } + for(var i= 0; i < 5; i++){ + var no = page - 2 + i; + if(no > 1 && no <= totalPage-1){ + list.push(no); + } + } + if(page+1 < totalPage-1){ + list.push('...'); + } + if(totalPage>1){ + list.push(totalPage); + } + $.each(list, function(index, item){ + var $li = $('<li><a></a></li>'); + if(item === '...'){ + $li.addClass('').html('...'); + }else if(item === page){ + $li.addClass('active').find('a').text(item); + }else{ + $li.find('a').text(item).prop('title','第'+item+'页').on('click', function(e){ + $el.data('page', item); + that.$mmGrid.load(); + }); + } + $pageList.append($li); + }); + // + var $next = $('<li class="next"><a title="下一页">»</a></li>'); + if(page>=totalPage){ + $next.addClass('disable'); + }else{ + $next.find('a').on('click', function(){ + $el.data('page', page+1); + that.$mmGrid.load(); + }); + } + $pageList.append($next); + } + + , _search: function(page, totalCount, limit){ + + } + + , load: function(params){ + var $el = this.$el; + var $limitList = this.$limitList; + var opts = this.opts; + + if(!params){ + params = {}; + } + + var page = params[opts.pageParamName]; + if(page === undefined || page === null){ + page = $el.data('page'); + } + $el.data('page', page); + + var totalCount = params[opts.totalCountName]; + if(totalCount === undefined){ + totalCount = 0; + } + $el.data('totalCount', totalCount); + + var limit = params[opts.limitParamName]; + if(!limit){ + limit = $limitList.val(); + } + this.$limitList.val(limit); + + this.$totalCountLabel.html(this.formatString(opts.totalCountLabel,[totalCount])); + this.$pageList.empty(); + + this._plain(page, totalCount, this.$limitList.val()); + } + + , formatString: function(text, args){ + return text.replace(/{(\d+)}/g, function(match, number) { + return typeof args[number] != 'undefined' + ? args[number] + : match + ; + }); + } + + , params: function(){ + var opts = this.opts; + var $el = this.$el; + var $limitList = this.$limitList; + + var params = {}; + params[opts.pageParamName] = $el.data('page'); + params[opts.limitParamName] = $limitList.val(); + return params; + } + + , init: function($grid){ + var that = this; + var opts = that.opts; + this.$mmGrid = $grid; + this._initLayout(); + this.$mmGrid.on('loadSuccess', function(e, data){ + that.load(data); + }); + + var params = {}; + params[opts.totalCountName] = 0; + params[opts.pageParamName] = opts.page; + params[opts.limitParamName] = opts.limit; + this.load(params); + + if($grid.opts.indexCol){ + var indexCol = $grid.opts.cols[0]; + indexCol.renderer = function(val,item,rowIndex){ + var params = that.params(); + return '<label class="mmg-index">' + + (rowIndex + 1 + ((params[opts.pageParamName]-1) * params[opts.limitParamName])) + + '</label>'; + }; + } + + } + + }; + + $.fn.mmPaginator = function(){ + + if(arguments.length === 0 || typeof arguments[0] === 'object'){ + var option = arguments[0] + , data = this.data('mmPaginator') + , options = $.extend(true, {}, $.fn.mmPaginator.defaults, option); + if (!data) { + data = new MMPaginator(this[0], options); + this.data('mmPaginator', data); + } + return $.extend(true, this, data); + } + if(typeof arguments[0] === 'string'){ + var data = this.data('mmPaginator'); + var fn = data[arguments[0]]; + if(fn){ + var args = Array.prototype.slice.call(arguments); + return fn.apply(data,args.slice(1)); + } + } + }; + + $.fn.mmPaginator.defaults = { + style: 'plain' + , totalCountName: 'totalCount' + , page: 1 + , pageParamName: 'page' + , limitParamName: 'limit' + , limitLabel: '每页{0}条' + , totalCountLabel: '共<span>{0}</span>条记录' + , limit: undefined + , limitList: [20, 30, 40, 50] + }; + + $.fn.mmPaginator.Constructor = MMPaginator; + +}(window.jQuery); \ No newline at end of file diff --git a/static/src/plugins/validator/jquery.validator.js b/static/src/plugins/validator/jquery.validator.js new file mode 100755 index 0000000..04d6432 --- /dev/null +++ b/static/src/plugins/validator/jquery.validator.js @@ -0,0 +1,2141 @@ +/*! nice-validator 1.0.4 + * (c) 2012-2016 Jony Zhang <niceue@live.com>, MIT Licensed + * https://github.com/niceue/nice-validator + */ +;(function(factory) { + typeof module === "object" && module.exports ? module.exports = factory( require( "jquery" ) ) : + typeof define === 'function' && define.amd ? require(['jquery'], factory) : + factory(jQuery); +}(function($, undefined) { + "use strict"; + + var NS = 'validator', + CLS_NS = '.' + NS, + CLS_NS_RULE = '.rule', + CLS_NS_FIELD = '.field', + CLS_NS_FORM = '.form', + CLS_WRAPPER = 'nice-' + NS, + CLS_MSG_BOX = 'msg-box', + ARIA_REQUIRED = 'aria-required', + ARIA_INVALID = 'aria-invalid', + DATA_RULE = 'data-rule', + DATA_MSG = 'data-msg', + DATA_TIP = 'data-tip', + DATA_OK = 'data-ok', + DATA_TIMELY = 'data-timely', + DATA_TARGET = 'data-target', + DATA_DISPLAY = 'data-display', + DATA_MUST = 'data-must', + NOVALIDATE = 'novalidate', + INPUT_SELECTOR = ':verifiable', + + rRules = /(&)?(!)?\b(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\|)?/g, + rRule = /(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/, + rDisplay = /(?:([^:;\(\[]*):)?(.*)/, + rDoubleBytes = /[^\x00-\xff]/g, + rPos = /top|right|bottom|left/, + rAjaxType = /(?:(cors|jsonp):)?(?:(post|get):)?(.+)/i, + rUnsafe = /[<>'"`\\]|&#x?\d+[A-F]?;?|%3[A-F]/gmi, + + noop = $.noop, + proxy = $.proxy, + trim = $.trim, + isFunction = $.isFunction, + isString = function(s) { + return typeof s === 'string'; + }, + isObject = function(o) { + return o && Object.prototype.toString.call(o) === '[object Object]'; + }, + isIE = document.documentMode || +(navigator.userAgent.match(/MSIE (\d+)/) && RegExp.$1), + attr = function(el, key, value) { + if (!el || !el.tagName) return null; + if (value !== undefined) { + if (value === null) el.removeAttribute(key); + else el.setAttribute(key, '' + value); + } else { + return el.getAttribute(key); + } + }, + novalidateonce, + preinitialized = {}, + + defaults = { + debug: 0, + theme: 'default', + ignore: '', + focusInvalid: true, + focusCleanup: false, + stopOnError: false, + beforeSubmit: null, + valid: null, + invalid: null, + validation: null, + validClass: 'n-valid', + invalidClass: 'n-invalid', + bindClassTo: null + }, + fieldDefaults = { + timely: 1, + display: null, + target: null, + ignoreBlank: false, + showOk: true, + // Translate ajax response to validation result + dataFilter: function (data) { + if ( isString(data) || ( isObject(data) && ('error' in data || 'ok' in data) ) ) { + return data; + } + }, + msgMaker: function(opt) { + var html; + html = '<span role="alert" class="msg-wrap n-'+ opt.type + '">' + opt.arrow; + if (opt.result) { + $.each(opt.result, function(i, obj){ + html += '<span class="n-'+ obj.type +'">' + opt.icon + '<span class="n-msg">' + obj.msg + '</span></span>'; + }); + } else { + html += opt.icon + '<span class="n-msg">' + opt.msg + '</span>'; + } + html += '</span>'; + return html; + }, + msgWrapper: 'span', + msgArrow: '', + msgIcon: '<span class="n-icon"></span>', + msgClass: '', + msgStyle: '', + msgShow: null, + msgHide: null + }, + themes = { + 'default': { + formClass: 'n-default', + msgClass: 'n-right' + } + }; + + /** jQuery Plugin + * @param {Object} options + debug {Boolean} 0 Whether to enable debug mode + timely {Number} 1 Whether to enable timely validation + theme {String} 'default' Theme name + stopOnError {Boolean} false Whether to stop validate when found an error input + focusCleanup {Boolean} false Whether to clean up the field message when focus the field + focusInvalid {Boolean} true Whether to focus the field that is invalid + ignoreBlank {Boolean} false When the field has no value, whether to ignore validation + ignore {jqSelector} '' Ignored fields (Using jQuery selector) + + beforeSubmit {Function} Do something before submit form + dataFilter {Function} Convert ajax results + valid {Function} Triggered when the form is valid + invalid {Function} Triggered when the form is invalid + validClass {String} 'n-valid' Add this class name to a valid field + invalidClass {String} 'n-invalid' Add this class name to a invalid field + bindClassTo {jqSelector} ':verifiable' Which element should the className binding to + + display {Function} Callback function to get dynamic display + target {Function} Callback function to get dynamic target + msgShow {Function} Trigger this callback when show message + msgHide {Function} Trigger this callback when hide message + msgWrapper {String} 'span' Message wrapper tag name + msgMaker {Function} Callback function to make message HTML + msgArrow {String} Message arrow template + msgIcon {String} Message icon template + msgStyle {String} Custom message css style + msgClass {String} Additional added to the message class names + formClass {String} Additional added to the form class names + + messages {Object} Custom messages for the current instance + rules {Object} Custom rules for the current instance + fields {Object} Field validation configuration + {String} key name|#id + {String|Object} value Rule string or an object which can pass more arguments + + fields[key][rule] {String} Rule string + fields[key][display] {String|Function} + fields[key][tip] {String} Custom tip message + fields[key][ok] {String} Custom success message + fields[key][msg] {Object} Custom error message + fields[key][msgStyle] {String} Custom message style + fields[key][msgClass] {String} A className which added to message placeholder element + fields[key][msgWrapper] {String} Tag name of the message placeholder element + fields[key][msgMaker] {Function} A function to custom message HTML + fields[key][dataFilter] {Function} A function to convert ajax results + fields[key][valid] {Function} A function triggered when field is valid + fields[key][invalid] {Function} A function triggered when field is invalid + fields[key][must] {Boolean} If set true, we always check the field even has remote checking + fields[key][timely] {Boolean} Whether to enable timely validation + fields[key][target] {jqSelector} Define placement of a message + */ + $.fn.validator = function(options) { + var that = this, + args = arguments; + + if (that.is(INPUT_SELECTOR)) return that; + if (!that.is('form')) that = this.find('form'); + if (!that.length) that = this; + + that.each(function() { + var instance = $(this).data(NS); + + if (instance) { + if ( isString(options) ) { + if ( options.charAt(0) === '_' ) return; + instance[options].apply(instance, [].slice.call(args, 1)); + } + else if (options) { + instance._reset(true); + instance._init(this, options); + } + } else { + new Validator(this, options); + } + }); + + return this; + }; + + + // Validate a field, or an area + $.fn.isValid = function(callback, hideMsg) { + var me = _getInstance(this[0]), + hasCallback = isFunction(callback), + ret, opt; + + if (!me) return true; + if (!hasCallback && hideMsg === undefined) hideMsg = callback; + me.checkOnly = !!hideMsg; + opt = me.options; + + ret = me._multiValidate( + this.is(INPUT_SELECTOR) ? this : this.find(INPUT_SELECTOR), + function(isValid){ + if (!isValid && opt.focusInvalid && !me.checkOnly) { + // navigate to the error element + me.$el.find('[' + ARIA_INVALID + ']:first').focus(); + } + if (hasCallback) { + if (callback.length) { + callback(isValid); + } else if (isValid) { + callback(); + } + } + me.checkOnly = false; + } + ); + + // If you pass a callback, we maintain the jQuery object chain + return hasCallback ? this : ret; + }; + + + // A faster selector than ":input:not(:submit,:button,:reset,:image,:disabled,[contenteditable])" + $.expr.pseudos.verifiable = function(elem) { + var name = elem.nodeName.toLowerCase(); + + return ( name === 'input' && !({submit: 1, button: 1, reset: 1, image: 1})[elem.type] || + name === 'select' || + name === 'textarea' || + elem.contentEditable === 'true' + ) && !elem.disabled; + }; + + // any value, but not only whitespace + $.expr.pseudos.filled = function(elem) { + return !!trim($(elem).val()); + }; + + + /** + * Creates a new Validator + * + * @class + * @param {Element} element - form element + * @param {Object} options - options for validator + */ + function Validator(element, options) { + var me = this; + + if ( !(me instanceof Validator) ) { + return new Validator(element, options); + } + + me.$el = $(element); + + if (me.$el.length) { + init(); + if (Validator.pending) { + $(window).on('validatorready', init); + } + } + else if ( isString(element) ) { + preinitialized[element] = options; + } + + function init() { + me._init(me.$el[0], options, !!arguments[0]); + } + } + + Validator.prototype = { + _init: function(element, options, hasInit) { + var me = this, + opt, themeOpt, dataOpt; + + // Initialization options + if ( isFunction(options) ) { + options = { + valid: options + }; + } + options = me._opt = options || {}; + dataOpt = attr(element, 'data-'+ NS +'-option'); + dataOpt = me._dataOpt = dataOpt && dataOpt.charAt(0) === '{' ? (new Function("return " + dataOpt))() : {}; + themeOpt = me._themeOpt = themes[ options.theme || dataOpt.theme || defaults.theme ]; + opt = me.options = $.extend({}, defaults, fieldDefaults, themeOpt, me.options, options, dataOpt); + + if (!hasInit) { + me.rules = new Rules(opt.rules, true); + me.messages = new Messages(opt.messages, true); + me.Field = _createFieldFactory(me); + me.elements = me.elements || {}; + me.deferred = {}; + me.errors = {}; + me.fields = {}; + // Initialization fields + me._initFields(opt.fields); + } + + // Initialization events and make a cache + if ( !me.$el.data(NS) ) { + me.$el.data(NS, me).addClass(CLS_WRAPPER +' '+ opt.formClass) + .on('form-submit-validate', function(e, a, $form, opts, veto) { + me.vetoed = veto.veto = !me.isValid; + me.ajaxFormOptions = opts; + }) + .on('submit'+ CLS_NS +' validate'+ CLS_NS, proxy(me, '_submit')) + .on('reset'+ CLS_NS, proxy(me, '_reset')) + .on('showmsg'+ CLS_NS, proxy(me, '_showmsg')) + .on('hidemsg'+ CLS_NS, proxy(me, '_hidemsg')) + .on('focusin'+ CLS_NS + ' click'+ CLS_NS, INPUT_SELECTOR, proxy(me, '_focusin')) + .on('focusout'+ CLS_NS +' validate'+ CLS_NS, INPUT_SELECTOR, proxy(me, '_focusout')) + .on('keyup'+ CLS_NS +' input'+ CLS_NS + ' compositionstart compositionend', INPUT_SELECTOR, proxy(me, '_focusout')) + .on('click'+ CLS_NS, ':radio,:checkbox', 'click', proxy(me, '_focusout')) + .on('change'+ CLS_NS, 'select,input[type="file"]', 'change', proxy(me, '_focusout')); + + // cache the novalidate attribute value + me._NOVALIDATE = attr(element, NOVALIDATE); + // Initialization is complete, stop off default HTML5 form validation + // If use "jQuery.attr('novalidate')" in IE7 will complain: "SCRIPT3: Member not found." + attr(element, NOVALIDATE, NOVALIDATE); + } + + // Display all messages in target container + if ( isString(opt.target) ) { + me.$el.find(opt.target).addClass('msg-container'); + } + }, + + // Guess whether the form use ajax submit + _guessAjax: function(form) { + var me = this; + + if ( !(me.isAjaxSubmit = !!me.options.valid) ) { + // if there is a "valid.form" event + var events = ($._data || $.data)(form, "events"); + me.isAjaxSubmit = issetEvent(events, 'valid', 'form') || issetEvent(events, 'submit', 'form-plugin'); + } + + function issetEvent(events, name, namespace) { + if ( events && events[name] && + $.map(events[name], function(e){ + return ~e.namespace.indexOf(namespace) ? 1 : null; + }).length + ) { + return true; + } + return false; + } + }, + + _initFields: function(fields) { + var me = this, k, arr, i, + clear = fields === null; + + // Processing field information + if (clear) fields = me.fields; + + if ( isObject(fields) ) { + for (k in fields) { + if (~k.indexOf(',')) { + arr = k.split(','); + i = arr.length; + while (i--) { + initField(trim(arr[i]), fields[k]); + } + } else { + initField(k, fields[k]); + } + } + } + + // Parsing DOM rules + me.$el.find(INPUT_SELECTOR).each(function() { + me._parse(this); + }); + + function initField(k, v) { + // delete a field from settings + if ( v === null || clear ) { + var el = me.elements[k]; + if (el) me._resetElement(el, true); + delete me.fields[k]; + } else { + me.fields[k] = new me.Field(k, isString(v) ? {rule: v} : v, me.fields[k]); + } + } + }, + + // Parsing a field + _parse: function(el) { + var me = this, + field, + key = el.name, + display, + timely, + dataRule = attr(el, DATA_RULE); + + dataRule && attr(el, DATA_RULE, null); + + // If the field has passed the key as id mode, or it doesn't has a name + if ( el.id && ( + ('#' + el.id in me.fields) || + !key || + // If dataRule and element are diffrent from old's, we use ID mode. + (dataRule !== null && (field = me.fields[key]) && dataRule !== field.rule && el.id !== field.key) + ) + ) { + key = '#' + el.id; + } + // doesn't verify a field that has neither id nor name + if (!key) return; + + field = me.getField(key, true); + // The priority of passing parameter by DOM is higher than by JS. + field.rule = dataRule || field.rule; + + if (display = attr(el, DATA_DISPLAY)) { + field.display = display; + } + if (field.rule) { + if ( attr(el, DATA_MUST) !== null || /\b(?:match|checked)\b/.test(field.rule) ) { + field.must = true; + } + if ( /\brequired\b/.test(field.rule) ) { + field.required = true; + attr(el, ARIA_REQUIRED, true); + } + if (timely = attr(el, DATA_TIMELY)) { + field.timely = +timely; + } else if (field.timely > 3) { + attr(el, DATA_TIMELY, field.timely); + } + me._parseRule(field); + field.old = {}; + } + if ( isString(field.target) ) { + attr(el, DATA_TARGET, field.target); + } + if ( isString(field.tip) ) { + attr(el, DATA_TIP, field.tip); + } + + return me.fields[key] = field; + }, + + // Parsing field rules + _parseRule: function(field) { + var arr = rDisplay.exec(field.rule); + + if (!arr) return; + // current rule index + field._i = 0; + if (arr[1]) { + field.display = arr[1]; + } + if (arr[2]) { + field._rules = []; + arr[2].replace(rRules, function(){ + var args = arguments; + args[4] = args[4] || args[5]; + field._rules.push({ + and: args[1] === "&", + not: args[2] === "!", + or: args[6] === "|", + method: args[3], + params: args[4] ? $.map( args[4].split(', '), trim ) : undefined + }); + }); + } + }, + + // Verify a zone + _multiValidate: function($inputs, doneCallback){ + var me = this, + opt = me.options; + + me.hasError = false; + + if (opt.ignore) { + $inputs = $inputs.not(opt.ignore); + } + + $inputs.each(function() { + me._validate(this); + if (me.hasError && opt.stopOnError) { + // stop the validation + return false; + } + }); + + // Need to wait for all fields validation complete, especially asynchronous validation + if (doneCallback) { + me.validating = true; + $.when.apply( + null, + $.map(me.deferred, function(v){return v;}) + ).done(function(){ + doneCallback.call(me, !me.hasError); + me.validating = false; + }); + } + + // If the form does not contain asynchronous validation, the return value is correct. + // Otherwise, you should detect form validation result through "doneCallback". + return !$.isEmptyObject(me.deferred) ? undefined : !me.hasError; + }, + + // Validate the whole form + _submit: function(e) { + var me = this, + opt = me.options, + form = e.target, + canSubmit = e.type === 'submit' && !e.isDefaultPrevented(); + + e.preventDefault(); + + if ( + novalidateonce && ~(novalidateonce = false) || + // Prevent duplicate submission + me.submiting || + // Receive the "validate" event only from the form. + e.type === 'validate' && me.$el[0] !== form || + // trigger the beforeSubmit callback. + isFunction(opt.beforeSubmit) && opt.beforeSubmit.call(me, form) === false + ) { + return; + } + + if (me.isAjaxSubmit === undefined) { + me._guessAjax(form); + } + + me._debug('log', '\n<<< event: ' + e.type); + + me._reset(); + me.submiting = true; + + me._multiValidate( + me.$el.find(INPUT_SELECTOR), + function(isValid){ + var ret = (isValid || opt.debug === 2) ? 'valid' : 'invalid', + errors; + + if (!isValid) { + if (opt.focusInvalid) { + // navigate to the error element + me.$el.find('[' + ARIA_INVALID + ']:first').focus(); + } + errors = $.map(me.errors, function(err){return err;}); + } + + // releasing submit + me.submiting = false; + me.isValid = isValid; + + // trigger callback and event + isFunction(opt[ret]) && opt[ret].call(me, form, errors); + me.$el.trigger(ret + CLS_NS_FORM, [form, errors]); + + me._debug('log', '>>> ' + ret); + + if (!isValid) return; + // For jquery.form plugin + if (me.vetoed) { + $(form).ajaxSubmit(me.ajaxFormOptions); + } + else if (canSubmit && !me.isAjaxSubmit) { + document.createElement('form').submit.call(form); + } + } + ); + }, + + _reset: function(e) { + var me = this; + + me.errors = {}; + if (e) { + me.reseting = true; + me.$el.find(INPUT_SELECTOR).each( function(){ + me._resetElement(this); + }); + delete me.reseting; + } + }, + + _resetElement: function(el, all) { + this._setClass(el, null); + this.hideMsg(el); + if (all) { + attr(el, ARIA_REQUIRED, null); + } + }, + + // Handle events: "focusin/click" + _focusin: function(e) { + var me = this, + opt = me.options, + el = e.target, + timely, + msg; + + if ( me.validating || ( e.type==='click' && document.activeElement === el ) ) { + return; + } + + if (opt.focusCleanup) { + if ( attr(el, ARIA_INVALID) === 'true' ) { + me._setClass(el, null); + me.hideMsg(el); + } + } + + msg = attr(el, DATA_TIP); + + if (msg) { + me.showMsg(el, { + type: 'tip', + msg: msg + }); + } else { + if (attr(el, DATA_RULE)) { + me._parse(el); + } + if (timely = attr(el, DATA_TIMELY)) { + if ( timely === 8 || timely === 9 ) { + me._focusout(e); + } + } + } + }, + + // Handle events: "focusout/validate/keyup/click/change/input/compositionstart/compositionend" + _focusout: function(e) { + var me = this, + opt = me.options, + el = e.target, + etype = e.type, + etype0, + focusin = etype === 'focusin', + special = etype === 'validate', + elem, + field, + old, + value, + timestamp, + key, specialKey, + timely, + timer = 0; + + if (etype === 'compositionstart') { + me.pauseValidate = true; + } + if (etype === 'compositionend') { + me.pauseValidate = false; + } + if (me.pauseValidate) { + return; + } + + // For checkbox and radio + elem = el.name && _checkable(el) ? me.$el.find('input[name="'+ el.name +'"]').get(0) : el; + // Get field + if (!(field = me.getField(elem))) { + return; + } + // Cache event type + etype0 = field._e; + field._e = etype; + timely = field.timely; + + if (!special) { + if (!timely || (_checkable(el) && etype !== 'click')) { + return; + } + + value = field.getValue(); + + // not validate field unless fill a value + if ( field.ignoreBlank && !value && !focusin ) { + me.hideMsg(el); + return; + } + + if ( etype === 'focusout' ) { + if (etype0 === 'change') { + return; + } + if ( timely === 2 || timely === 8 ) { + if (value) { + old = field.old; + if (field.isValid && !old.showOk) { + me.hideMsg(el); + } else { + me._makeMsg(el, field, old); + } + } else { + return; + } + } + } + else { + if ( timely < 2 && !e.data ) { + return; + } + + // mark timestamp to reduce the frequency of the received event + timestamp = +new Date(); + if ( timestamp - (el._ts || 0) < 100 ) { + return; + } + el._ts = timestamp; + + // handle keyup + if ( etype === 'keyup' ) { + if (etype0 === 'input') { + return; + } + key = e.keyCode; + specialKey = { + 8: 1, // Backspace + 9: 1, // Tab + 16: 1, // Shift + 32: 1, // Space + 46: 1 // Delete + }; + + // only gets focus, no validation + if ( key === 9 && !value ) { + return; + } + + // do not validate, if triggered by these keys + if ( key < 48 && !specialKey[key] ) { + return; + } + } + if ( !focusin ) { + // keyboard events, reducing the frequency of validation + timer = timely <100 ? (etype === 'click' || el.tagName === 'SELECT') ? 0 : 400 : timely; + } + } + } + + // if the current field is ignored + if ( opt.ignore && $(el).is(opt.ignore) ) { + return; + } + + clearTimeout(field._t); + + if (timer) { + field._t = setTimeout(function() { + me._validate(el, field); + }, timer); + } else { + if (special) field.old = {}; + me._validate(el, field); + } + }, + + _setClass: function(el, isValid) { + var $el = $(el), opt = this.options; + if (opt.bindClassTo) { + $el = $el.closest(opt.bindClassTo); + } + $el.removeClass( opt.invalidClass + ' ' + opt.validClass ); + if (isValid !== null) { + $el.addClass( isValid ? opt.validClass : opt.invalidClass ); + } + }, + + _showmsg: function(e, type, msg) { + var me = this, + el = e.target; + + if ( $(el).is(INPUT_SELECTOR) ) { + me.showMsg(el, {type: type, msg: msg}); + } + else if ( type === 'tip' ) { + me.$el.find(INPUT_SELECTOR +"["+ DATA_TIP +"]", el).each(function(){ + me.showMsg(this, {type: type, msg: msg}); + }); + } + }, + + _hidemsg: function(e) { + var $el = $(e.target); + + if ( $el.is(INPUT_SELECTOR) ) { + this.hideMsg($el); + } + }, + + // Validated a field + _validatedField: function(el, field, ret) { + var me = this, + opt = me.options, + isValid = field.isValid = ret.isValid = !!ret.isValid, + callback = isValid ? 'valid' : 'invalid'; + + ret.key = field.key; + ret.ruleName = field._r; + ret.id = el.id; + ret.value = field.value; + + me.elements[field.key] = ret.element = el; + me.isValid = me.$el[0].isValid = isValid ? me.isFormValid() : isValid; + + if (isValid) { + ret.type = 'ok'; + } else { + if (me.submiting) { + me.errors[field.key] = ret.msg; + } + me.hasError = true; + } + + // cache result + field.old = ret; + + // trigger callback + isFunction(field[callback]) && field[callback].call(me, el, ret); + isFunction(opt.validation) && opt.validation.call(me, el, ret); + + // trigger event + $(el).attr( ARIA_INVALID, isValid ? null : true ) + .trigger( callback + CLS_NS_FIELD, [ret, me] ); + me.$el.triggerHandler('validation', [ret, me]); + + if (me.checkOnly) return; + // set className + me._setClass(el, ret.skip || ret.type === 'tip' ? null : isValid); + me._makeMsg.apply(me, arguments); + }, + + _makeMsg: function(el, field, ret) { + // show or hide the message + if (field.msgMaker) { + ret = $.extend({}, ret); + if (field._e === 'focusin') { + ret.type = 'tip'; + } + this[ ret.showOk || ret.msg || ret.type === 'tip' ? 'showMsg' : 'hideMsg' ](el, ret, field); + } + }, + + // Validated a rule + _validatedRule: function(el, field, ret, msgOpt) { + field = field || me.getField(el); + msgOpt = msgOpt || {}; + + var me = this, + msg, + rule, + method = field._r, + timely = field.timely, + special = timely === 9 || timely === 8, + transfer, + temp, + isValid = false; + + // use null to break validation from a field + if (ret === null) { + me._validatedField(el, field, {isValid: true, skip: true}); + field._i = 0; + return; + } + else if (ret === undefined) { + transfer = true; + } + else if (ret === true || ret === '') { + isValid = true; + } + else if (isString(ret)) { + msg = ret; + } + else if (isObject(ret)) { + if (ret.error) { + msg = ret.error; + } else { + msg = ret.ok; + isValid = true; + } + } + + rule = field._rules[field._i]; + if (rule.not) { + msg = undefined; + isValid = method === "required" || !isValid; + } + if (rule.or) { + if (isValid) { + while ( field._i < field._rules.length && field._rules[field._i].or ) { + field._i++; + } + } else { + transfer = true; + } + } + else if (rule.and) { + if (!field.isValid) transfer = true; + } + + if (transfer) { + isValid = true; + } + // message analysis, and throw rule level event + else { + if (isValid) { + if (field.showOk !== false) { + temp = attr(el, DATA_OK); + msg = temp === null ? isString(field.ok) ? field.ok : msg : temp; + if (!isString(msg) && isString(field.showOk)) { + msg = field.showOk; + } + if (isString(msg)) { + msgOpt.showOk = isValid; + } + } + } + if (!isValid || special) { + /* rule message priority: + 1. custom DOM message + 2. custom field message; + 3. global defined message; + 4. rule returned message; + 5. default message; + */ + msg = (_getDataMsg(el, field, msg || rule.msg || me.messages[method]) || me.messages.fallback).replace(/\{0\|?([^\}]*)\}/, function(m, defaultDisplay){ + return me._getDisplay(el, field.display) || defaultDisplay || me.messages[0]; + }); + } + if (!isValid) field.isValid = isValid; + msgOpt.msg = msg; + $(el).trigger( (isValid ? 'valid' : 'invalid') + CLS_NS_RULE, [method, msg]); + } + + if (special && (!transfer || rule.and)) { + if (!isValid && !field._m) field._m = msg; + field._v = field._v || []; + field._v.push({ + type: isValid ? !transfer ? 'ok' : 'tip' : 'error', + msg: msg || rule.msg + }); + } + + me._debug('log', ' ' + field._i + ': ' + method + ' => ' + (isValid || msg)); + + // the current rule has passed, continue to validate + if ( (isValid || special) && field._i < field._rules.length - 1) { + field._i++; + me._checkRule(el, field); + } + // field was invalid, or all fields was valid + else { + field._i = 0; + + if (special) { + msgOpt.isValid = field.isValid; + msgOpt.result = field._v; + msgOpt.msg = field._m || ''; + if (!field.value && (field._e === 'focusin')) { + msgOpt.type = 'tip'; + } + } else { + msgOpt.isValid = isValid; + } + + me._validatedField(el, field, msgOpt); + delete field._m; + delete field._v; + } + }, + + // Verify a rule form a field + _checkRule: function(el, field) { + var me = this, + ret, + fn, + old, + key = field.key, + rule = field._rules[field._i], + method = rule.method, + params = rule.params; + + // request has been sent, wait it + if (me.submiting && me.deferred[key]) { + return; + } + old = field.old; + field._r = method; + + if (old && !field.must && !rule.must && rule.result !== undefined && + old.ruleName === method && old.id === el.id && + field.value && old.value === field.value ) + { + // get result from cache + ret = rule.result; + } + else { + // get result from current rule + fn = _getDataRule(el, method) || me.rules[method] || noop; + ret = fn.call(field, el, params, field); + if (fn.msg) rule.msg = fn.msg; + } + + // asynchronous validation + if (isObject(ret) && isFunction(ret.then)) { + me.deferred[key] = ret; + + // whether the field valid is unknown + field.isValid = undefined; + + // show loading message + !me.checkOnly && me.showMsg(el, { + type: 'loading', + msg: me.messages.loading + }, field); + + // waiting to parse the response data + ret.then( + function(d, textStatus, jqXHR) { + var data = trim(jqXHR.responseText), + result, + dataFilter = field.dataFilter; + + // detect if data is json or jsonp format + if (/jsonp?/.test(this.dataType)) { + data = d; + } else if (data.charAt(0) === '{') { + data = $.parseJSON(data); + } + + // filter data + result = dataFilter.call(this, data, field); + if (result === undefined) result = dataFilter.call(this, data.data, field); + + rule.data = this.data; + rule.result = field.old ? result : undefined; + me._validatedRule(el, field, result); + }, + function(jqXHR, textStatus){ + me._validatedRule(el, field, me.messages[textStatus] || textStatus); + } + ).always(function(){ + delete me.deferred[key]; + }); + } + // other result + else { + me._validatedRule(el, field, ret); + } + }, + + // Processing the validation + _validate: function(el, field) { + var me = this; + + // doesn't validate the element that has "disabled" or "novalidate" attribute + if ( el.disabled || attr(el, NOVALIDATE) !== null ) { + return; + } + + field = field || me.getField(el); + if (!field) return; + if (!field._rules) me._parse(el); + if (!field._rules) return; + + me._debug('info', field.key); + + field.isValid = true; + field.element = el; + // Cache the value + field.value = field.getValue(); + + // if the field is not required, and that has a blank value + if (!field.required && !field.must && !field.value) { + if (!_checkable(el)) { + me._validatedField(el, field, {isValid: true}); + return true; + } + } + + me._checkRule(el, field); + return field.isValid; + }, + + _debug: function(type, messages) { + if (window.console && this.options.debug) { + console[type](messages); + } + }, + + /** + * Detecting whether the value of an element that matches a rule + * + * @method test + * @param {Element} el - input element + * @param {String} rule - rule name + */ + test: function(el, rule) { + var me = this, + ret, + parts = rRule.exec(rule), + field, + method, + params; + + if (parts) { + method = parts[1]; + if (method in me.rules) { + params = parts[2] || parts[3]; + params = params ? params.split(', ') : undefined; + field = me.getField(el, true); + field._r = method; + field.value = field.getValue(); + ret = me.rules[method].call(field, el, params); + } + } + + return ret === true || ret === undefined || ret === null; + }, + + _getDisplay: function(el, str) { + return !isString(str) ? isFunction(str) ? str.call(this, el) : '' : str; + }, + + _getMsgOpt: function(obj, field) { + var opt = field ? field : this.options; + return $.extend({ + type: 'error', + pos: _getPos(opt.msgClass), + target: opt.target, + wrapper: opt.msgWrapper, + style: opt.msgStyle, + cls: opt.msgClass, + arrow: opt.msgArrow, + icon: opt.msgIcon + }, isString(obj) ? {msg: obj} : obj); + }, + + _getMsgDOM: function(el, msgOpt) { + var $el = $(el), $msgbox, datafor, tgt, container; + + if ( $el.is(INPUT_SELECTOR) ) { + tgt = msgOpt.target || attr(el, DATA_TARGET); + if (tgt) { + tgt = isFunction(tgt) ? tgt.call(this, el) : this.$el.find(tgt); + if (tgt.length) { + if ( tgt.is(INPUT_SELECTOR) ) { + el = tgt.get(0); + } else if ( tgt.hasClass(CLS_MSG_BOX) ) { + $msgbox = tgt; + } else { + container = tgt; + } + } + } + if (!$msgbox) { + datafor = (!_checkable(el) || !el.name) && el.id ? el.id : el.name; + $msgbox = this.$el.find(msgOpt.wrapper + '.' + CLS_MSG_BOX + '[for="' + datafor + '"]'); + } + } else { + $msgbox = $el; + } + + // Create new message box + if (!msgOpt.hide && !$msgbox.length) { + $el = this.$el.find(tgt || el); + + $msgbox = $('<'+ msgOpt.wrapper + '>').attr({ + 'class': CLS_MSG_BOX + (msgOpt.cls ? ' ' + msgOpt.cls : ''), + 'style': msgOpt.style || undefined, + 'for': datafor + }); + + if ( _checkable(el) ) { + var $parent = $el.parent(); + $msgbox.appendTo( $parent.is('label') ? $parent.parent() : $parent ); + } else { + if (container) { + $msgbox.appendTo(container); + } else { + $msgbox[!msgOpt.pos || msgOpt.pos === 'right' ? 'insertAfter' : 'insertBefore']($el); + } + } + } + + return $msgbox; + }, + + /** + * Show validation message + * + * @method showMsg + * @param {Element} el - input element + * @param {Object} msgOpt + */ + showMsg: function(el, msgOpt, /*INTERNAL*/ field) { + if (!el) return; + var me = this, + opt = me.options, + msgShow, + msgMaker, + temp, + $msgbox; + + if (isObject(el) && !el.jquery && !msgOpt) { + $.each(el, function(key, msg) { + var el = me.elements[key] || me.$el.find(_key2selector(key))[0]; + me.showMsg(el, msg); + }); + return; + } + + if ($(el).is(INPUT_SELECTOR)) { + field = field || me.getField(el); + } + + if (!(msgMaker = (field || opt).msgMaker)) { + return; + } + + msgOpt = me._getMsgOpt(msgOpt, field); + el = $(el).get(0); + + // ok or tip + if (!msgOpt.msg && msgOpt.type !== 'error') { + temp = attr(el, 'data-' + msgOpt.type); + if (temp !== null) msgOpt.msg = temp; + } + + if ( !isString(msgOpt.msg) ) { + return; + } + + $msgbox = me._getMsgDOM(el, msgOpt); + + !rPos.test($msgbox[0].className) && $msgbox.addClass(msgOpt.cls); + if ( isIE === 6 && msgOpt.pos === 'bottom' ) { + $msgbox[0].style.marginTop = $(el).outerHeight() + 'px'; + } + $msgbox.html( msgMaker.call(me, msgOpt) )[0].style.display = ''; + + if (isFunction(msgShow = field && field.msgShow || opt.msgShow)) { + msgShow.call(me, $msgbox, msgOpt.type); + } + }, + + /** + * Hide validation message + * + * @method hideMsg + * @param {Element} el - input element + * @param {Object} msgOpt optional + */ + hideMsg: function(el, msgOpt, /*INTERNAL*/ field) { + var me = this, + opt = me.options, + msgHide, + $msgbox; + + el = $(el).get(0); + if ($(el).is(INPUT_SELECTOR)) { + field = field || me.getField(el); + if (field) { + if (field.isValid || me.reseting) attr(el, ARIA_INVALID, null); + } + } + + msgOpt = me._getMsgOpt(msgOpt, field); + msgOpt.hide = true; + + $msgbox = me._getMsgDOM(el, msgOpt); + if (!$msgbox.length) return; + + if ( isFunction(msgHide = field && field.msgHide || opt.msgHide) ) { + msgHide.call(me, $msgbox, msgOpt.type); + } else { + $msgbox[0].style.display = 'none'; + $msgbox[0].innerHTML = null; + } + }, + + /** + * Get field information + * + * @method getField + * @param {Element} - input element + * @return {Object} field + */ + getField: function(el, must) { + var me = this, + key, + field; + + if (isString(el)) { + key = el; + el = undefined; + } else { + if (attr(el, DATA_RULE)) { + return me._parse(el); + } + if (el.id && '#' + el.id in me.fields || !el.name) { + key = '#' + el.id; + } else { + key = el.name; + } + } + + if ( (field = me.fields[key]) || must && (field = new me.Field(key)) ) { + field.element = el; + } + + return field; + }, + + /** + * Config a field + * + * @method: setField + * @param {String} key + * @param {Object} obj + */ + setField: function(key, obj) { + var fields = {}; + + if (!key) return; + + // update this field + if (isString(key)) { + fields[key] = obj; + } + // update fields + else { + fields = key; + } + + this._initFields(fields); + }, + + /** + * Detecting whether the form is valid + * + * @method isFormValid + * @return {Boolean} + */ + isFormValid: function() { + var fields = this.fields, k, field; + for (k in fields) { + field = fields[k]; + if (!field._rules || !field.required && !field.must && !field.value) continue; + if (!field.isValid) return false; + } + return true; + }, + + /** + * Prevent submission form + * + * @method holdSubmit + * @param {Boolean} hold - If set to false, will release the hold + */ + holdSubmit: function(hold) { + this.submiting = hold === undefined || hold; + }, + + /** + * Clean validation messages + * + * @method cleanUp + */ + cleanUp: function() { + this._reset(1); + }, + + /** + * Destroy the validation + * + * @method destroy + */ + destroy: function() { + this._reset(1); + this.$el.off(CLS_NS).removeData(NS); + attr(this.$el[0], NOVALIDATE, this._NOVALIDATE); + } + }; + + /** + * Create Field Factory + * + * @class + * @param {Object} context + * @return {Function} Factory + */ + function _createFieldFactory(context) { + function FieldFactory() { + var options = this.options; + for (var i in options) { + if (i in fieldDefaults) this[i] = options[i]; + } + $.extend(this, { + _valHook: function() { + return this.element.getAttribute('contenteditable') !== null ? 'text' : 'val'; + }, + getValue: function() { + var elem = this.element; + if (elem.type === "number" && elem.validity && elem.validity.badInput) { + return 'NaN'; + } + return $(elem)[this._valHook()](); + }, + setValue: function(value) { + $(this.element)[this._valHook()](this.value = value); + }, + // Get a range of validation messages + getRangeMsg: function(value, params, suffix) { + if (!params) return; + + var me = this, + msg = me.messages[me._r] || '', + result, + p = params[0].split('~'), + e = params[1] === 'false', + a = p[0], + b = p[1], + c = 'rg', + args = [''], + isNumber = trim(value) && +value === +value; + + function compare(large, small) { + return !e ? large >= small : large > small; + } + + if (p.length === 2) { + if (a && b) { + if (isNumber && compare(value, +a) && compare(+b, value)) { + result = true; + } + args = args.concat(p); + c = e ? 'gtlt' : 'rg'; + } + else if (a && !b) { + if (isNumber && compare(value, +a)) { + result = true; + } + args.push(a); + c = e ? 'gt' : 'gte'; + } + else if (!a && b) { + if (isNumber && compare(+b, value)) { + result = true; + } + args.push(b); + c = e ? 'lt' : 'lte'; + } + } + else { + if (value === +a) { + result = true; + } + args.push(a); + c = 'eq'; + } + + if (msg) { + if (suffix && msg[c + suffix]) { + c += suffix; + } + args[0] = msg[c]; + } + + return result || me._rules && ( me._rules[me._i].msg = me.renderMsg.apply(null, args) ); + }, + // Render message template + renderMsg: function() { + var args = arguments, + tpl = args[0], + i = args.length; + + if (!tpl) return; + + while (--i) { + tpl = tpl.replace('{' + i + '}', args[i]); + } + + return tpl; + } + }); + } + function Field(key, obj, oldField) { + this.key = key; + this.validator = context; + $.extend(this, oldField, obj); + } + + FieldFactory.prototype = context; + Field.prototype = new FieldFactory(); + + return Field; + } + + /** + * Create Rules + * + * @class + * @param {Object} obj rules + * @param {Object} context context + */ + function Rules(obj, context) { + if (!isObject(obj)) return; + + var k, that = context ? context === true ? this : context : Rules.prototype; + + for (k in obj) { + if (_checkRuleName(k)) + that[k] = _getRule(obj[k]); + } + } + + /** + * Create Messages + * + * @class + * @param {Object} obj rules + * @param {Object} context context + */ + function Messages(obj, context) { + if (!isObject(obj)) return; + + var k, that = context ? context === true ? this : context : Messages.prototype; + + for (k in obj) { + that[k] = obj[k]; + } + } + + // Rule converted factory + function _getRule(fn) { + switch ($.type(fn)) { + case 'function': + return fn; + case 'array': + var f = function() { + return fn[0].test(this.value) || fn[1] || false; + }; + f.msg = fn[1]; + return f; + case 'regexp': + return function() { + return fn.test(this.value); + }; + } + } + + // Get instance by an element + function _getInstance(el) { + var wrap, k, options; + + if (!el || !el.tagName) return; + + switch (el.tagName) { + case 'INPUT': + case 'SELECT': + case 'TEXTAREA': + case 'BUTTON': + case 'FIELDSET': + wrap = el.form || $(el).closest('.' + CLS_WRAPPER); + break; + case 'FORM': + wrap = el; + break; + default: + wrap = $(el).closest('.' + CLS_WRAPPER); + } + + for (k in preinitialized) { + if ($(wrap).is(k)) { + options = preinitialized[k]; + break; + } + } + + return $(wrap).data(NS) || $(wrap)[NS](options).data(NS); + } + + // Get custom rules on the node + function _getDataRule(el, method) { + var fn = trim(attr(el, DATA_RULE + '-' + method)); + + if ( fn && (fn = new Function("return " + fn)()) ) { + return _getRule(fn); + } + } + + // Get custom messages on the node + function _getDataMsg(el, field, m) { + var msg = field.msg, + item = field._r; + + if ( isObject(msg) ) msg = msg[item]; + if ( !isString(msg) ) { + msg = attr(el, DATA_MSG + '-' + item) || attr(el, DATA_MSG) || ( m ? isString(m) ? m : m[item] : ''); + } + + return msg; + } + + // Get message position + function _getPos(str) { + var pos; + + if (str) pos = rPos.exec(str); + return pos && pos[0]; + } + + // Check whether the element is checkbox or radio + function _checkable(el) { + return el.tagName === 'INPUT' && el.type === 'checkbox' || el.type === 'radio'; + } + + // Parse date string to timestamp + function _parseDate(str) { + return Date.parse(str.replace(/\.|\-/g, '/')); + } + + // Rule name only allows alphanumeric characters and underscores + function _checkRuleName(name) { + return /^\w+$/.test(name); + } + + // Translate field key to jQuery selector. + function _key2selector(key) { + var isID = key.charAt(0) === "#"; + key = key.replace(/([:.{(|)}/\[\]])/g, "\\$1"); + return isID ? key : '[name="'+ key +'"]:first'; + } + + + // Fixed a issue cause by refresh page in IE. + $(window).on('beforeunload', function(){ + this.focus(); + }); + + $(document) + .on('click', ':submit', function(){ + var input = this, attrNode; + if (!input.form) return; + // Shim for "formnovalidate" + attrNode = input.getAttributeNode('formnovalidate'); + if (attrNode && attrNode.nodeValue !== null || attr(input, NOVALIDATE)!== null) { + novalidateonce = true; + } + }) + // Automatic initializing form validation + .on('focusin submit validate', 'form,.'+CLS_WRAPPER, function(e) { + if ( attr(this, NOVALIDATE) !== null ) return; + var $form = $(this), me; + + if ( !$form.data(NS) && (me = _getInstance(this)) ) { + if ( !$.isEmptyObject(me.fields) ) { + // Execute event handler + if (e.type === 'focusin') { + me._focusin(e); + } else { + me._submit(e); + } + } else { + attr(this, NOVALIDATE, NOVALIDATE); + $form.off(CLS_NS).removeData(NS); + } + } + }); + + new Messages({ + fallback: "This field is not valid.", + loading: 'Validating...' + }); + + + // Built-in rules (global) + new Rules({ + + /** + * required + * + * @example: + required + required(anotherRule) + required(not, -1) + required(from, .contact) + */ + required: function(element, params) { + var me = this, + val = trim(me.value), + isValid = true; + + if (params) { + if ( params.length === 1 ) { + if ( !_checkRuleName(params[0]) ) { + if (!val && !$(params[0], me.$el).length ) { + return null; + } + } + else if ( me.rules[params[0]] ) { + if ( !val && !me.test(element, params[0]) ) { + attr(element, ARIA_REQUIRED, null); + return null; + } else { + attr(element, ARIA_REQUIRED, true); + } + } + } + else if ( params[0] === 'not' ) { + $.each(params.slice(1), function() { + return (isValid = val !== trim(this)); + }); + } + else if ( params[0] === 'from' ) { + var $elements = me.$el.find(params[1]), + VALIDATED = '_validated_', + ret; + + isValid = $elements.filter(function(){ + var field = me.getField(this); + return field && !!trim(field.getValue()); + }).length >= (params[2] || 1); + + if (isValid) { + if (!val) ret = null; + } else { + ret = _getDataMsg($elements[0], me) || false; + } + + if ( !$(element).data(VALIDATED) ) { + $elements.data(VALIDATED, 1).each(function(){ + if (element !== this) { + me._validate(this); + } + }).removeData(VALIDATED); + } + + return ret; + } + } + + return isValid && !!val; + }, + + /** + * integer + * + * @example: + integer + integer[+] + integer[+0] + integer[-] + integer[-0] + */ + integer: function(element, params) { + var re, z = '0|', + p = '[1-9]\\d*', + key = params ? params[0] : '*'; + + switch (key) { + case '+': + re = p; + break; + case '-': + re = '-' + p; + break; + case '+0': + re = z + p; + break; + case '-0': + re = z + '-' + p; + break; + default: + re = z + '-?' + p; + } + re = '^(?:' + re + ')$'; + + return new RegExp(re).test(this.value) || this.messages.integer[key]; + }, + + /** + * match another field + * + * @example: + match[password] Match the password field (two values ​​must be the same) + match[eq, password] Ditto + match[neq, count] The value must be not equal to the value of the count field + match[lt, count] The value must be less than the value of the count field + match[lte, count] The value must be less than or equal to the value of the count field + match[gt, count] The value must be greater than the value of the count field + match[gte, count] The value must be greater than or equal to the value of the count field + match[gte, startDate, date] + match[gte, startTime, time] + **/ + match: function(element, params) { + if (!params) return; + + var me = this, + a, b, + key, msg, type = 'eq', parser, + selector2, elem2, field2; + + if (params.length === 1) { + key = params[0]; + } else { + type = params[0]; + key = params[1]; + } + + selector2 = _key2selector(key); + elem2 = me.$el.find(selector2)[0]; + // If the compared field is not exist + if (!elem2) return; + field2 = me.getField(elem2); + a = me.value; + b = field2.getValue(); + + if (!me._match) { + me.$el.on('valid'+CLS_NS_FIELD+CLS_NS, selector2, function(){ + $(element).trigger('validate'); + }); + me._match = field2._match = 1; + } + + // If both fields are blank + if (!me.required && a === "" && b === "") { + return null; + } + + parser = params[2]; + if (parser) { + if (/^date(time)?$/i.test(parser)) { + a = _parseDate(a); + b = _parseDate(b); + } else if (parser === 'time') { + a = +a.replace(/:/g, ''); + b = +b.replace(/:/g, ''); + } + } + + // If the compared field is incorrect, we only ensure that this field is correct. + if (type !== "eq" && !isNaN(+a) && isNaN(+b)) { + return true; + } + + msg = me.messages.match[type].replace( '{1}', me._getDisplay( element, field2.display || key ) ); + + switch (type) { + case 'lt': + return (+a < +b) || msg; + case 'lte': + return (+a <= +b) || msg; + case 'gte': + return (+a >= +b) || msg; + case 'gt': + return (+a > +b) || msg; + case 'neq': + return (a !== b) || msg; + default: + return (a === b) || msg; + } + }, + + /** + * range numbers + * + * @example: + range[0~99] Number 0-99 + range[0~] Number greater than or equal to 0 + range[~100] Number less than or equal to 100 + **/ + range: function(element, params) { + return this.getRangeMsg(this.value, params); + }, + + /** + * how many checkbox or radio inputs that checked + * + * @example: + checked; no empty, same to required + checked[1~3] 1-3 items + checked[1~] greater than 1 item + checked[~3] less than 3 items + checked[3] 3 items + **/ + checked: function(element, params) { + if ( !_checkable(element) ) return; + + var me = this, + elem, count; + + if (element.name) { + count = me.$el.find('input[name="' + element.name + '"]').filter(function() { + var el = this; + if (!elem && _checkable(el)) elem = el; + return !el.disabled && el.checked; + }).length; + } else { + elem = element; + count = elem.checked; + } + + if (params) { + return me.getRangeMsg(count, params); + } else { + return !!count || _getDataMsg(elem, me, '') || me.messages.required; + } + }, + + /** + * length of a characters (You can pass the second parameter "true", will calculate the length in bytes) + * + * @example: + length[6~16] 6-16 characters + length[6~] Greater than 6 characters + length[~16] Less than 16 characters + length[~16, true] Less than 16 characters, non-ASCII characters calculating two-character + **/ + length: function(element, params) { + var value = this.value, + len = (params[1] === 'true' ? value.replace(rDoubleBytes, 'xx') : value).length; + + return this.getRangeMsg(len, params, (params[1] ? '_2' : '')); + }, + + /** + * remote validation + * + * @description + * remote([get:]url [, name1, [name2 ...]]); + * Adaptation three kinds of results (Front for the successful, followed by a failure): + 1. text: + '' 'Error Message' + 2. json: + {"ok": ""} {"error": "Error Message"} + 3. json wrapper: + {"status": 1, "data": {"ok": ""}} {"status": 1, "data": {"error": "Error Message"}} + * @example + The simplest: remote(path/to/server); + With parameters: remote(path/to/server, name1, name2, ...); + By GET: remote(get:path/to/server, name1, name2, ...); + Name proxy: remote(path/to/server, name1, proxyname2:name2, proxyname3:#id3, ...) + Query String remote(path/to/server, foo=1&bar=2, name1, name2, ...) + */ + remote: function(element, params) { + if (!params) return; + + var me = this, + arr = rAjaxType.exec(params[0]), + rule = me._rules[me._i], + data = {}, + queryString = '', + url = arr[3], + type = arr[2] || 'POST', // GET / POST + rType = (arr[1]||'').toLowerCase(), // CORS / JSONP + dataType; + + rule.must = true; + data[element.name] = me.value; + + // There are extra fields + if (params[1]) { + $.map(params.slice(1), function(name) { + var arr, key; + if (~name.indexOf('=')) { + queryString += '&' + name; + } else { + arr = name.split(':'); + name = trim(arr[0]); + key = trim(arr[1]) || name; + data[ name ] = me.$el.find( _key2selector(key) ).val(); + } + }); + } + + data = $.param(data) + queryString; + if (!me.must && rule.data && rule.data === data) { + return rule.result; + } + + // Cross-domain request, force jsonp dataType + if (rType !== 'cors' && /^https?:/.test(url) && !~url.indexOf(location.host)) { + dataType = 'jsonp'; + } + + // Asynchronous validation need return jqXHR objects + return $.ajax({ + url: url, + type: type, + data: data, + dataType: dataType + }); + }, + + /** + * filter characters, direct filtration without prompting error (support custom regular expressions) + * + * @example + * filter filtering unsafe characters + * filter(regexp) filtering the "regexp" matched characters + */ + filter: function(element, params) { + var value = this.value, + temp = value.replace( params ? (new RegExp("[" + params[0] + "]", "gm")) : rUnsafe, '' ); + if (temp !== value) this.setValue(temp); + } + }); + + + /** + * Config global options + * + * @static config + * @param {Object} options + */ + Validator.config = function(key, value) { + if (isObject(key)) { + $.each(key, _config); + } + else if (isString(key)) { + _config(key, value); + } + + function _config(k, o) { + if (k === 'rules') { + new Rules(o); + } + else if (k === 'messages') { + new Messages(o); + } + else if (k in fieldDefaults) { + fieldDefaults[k] = o; + } + else { + defaults[k] = o; + } + } + }; + + /** + * Config themes + * + * @static setTheme + * @param {String|Object} name + * @param {Object} obj + * @example + .setTheme( themeName, themeOptions ) + .setTheme( multiThemes ) + */ + Validator.setTheme = function(name, obj) { + if ( isObject(name) ) { + $.extend(true, themes, name); + } + else if ( isString(name) && isObject(obj) ) { + themes[name] = $.extend(themes[name], obj); + } + }; + + /** + * Resource loader + * + * @static load + * @param {String} str + * @example + .load('local=zh-CN') // load: local/zh-CN.js and jquery.validator.css + .load('local=zh-CN&css=') // load: local/zh-CN.js + .load('local&css') // load: local/en.js (set <html lang="en">) and jquery.validator.css + .load('local') // dito + */ + Validator.load = function(str) { + if (!str) return; + var doc = document, + params = {}, + node = doc.scripts[0], + dir, el, ONLOAD; + + str.replace(/([^?=&]+)=([^&#]*)/g, function(m, key, value){ + params[key] = value; + }); + + dir = params.dir || Validator.dir; + + if (!Validator.css && params.css !== '') { + el = doc.createElement('link'); + el.rel = 'stylesheet'; + el.href = Validator.css = dir + 'jquery.validator.css'; + node.parentNode.insertBefore(el, node); + } + if (!Validator.local && params.local !== '') { + Validator.local = (params.local || doc.documentElement.lang || 'en').replace('_','-'); + Validator.pending = 1; + el = doc.createElement('script'); + el.src = dir + 'local/' + Validator.local + '.js'; + ONLOAD = 'onload' in el ? 'onload' : 'onreadystatechange'; + el[ONLOAD] = function() { + if (!el.readyState || /loaded|complete/.test(el.readyState)) { + el = el[ONLOAD] = null; + delete Validator.pending; + $(window).triggerHandler('validatorready'); + } + }; + node.parentNode.insertBefore(el, node); + } + }; + + // Auto loading resources + (function(){ + var scripts = document.scripts, + i = scripts.length, node, arr, + re = /(.*validator(?:\.min)?.js)(\?.*(?:local|css|dir)(?:=[\w\-]*)?)?/; + + while (i-- && !arr) { + node = scripts[i]; + arr = (node.hasAttribute ? node.src : node.getAttribute('src',4)||'').match(re); + } + + if (!arr) return; + Validator.dir = arr[1].split('/').slice(0, -1).join('/')+'/'; + Validator.load(arr[2]); + })(); + + return $[NS] = Validator; +})); diff --git a/static/src/wstgridtree.js b/static/src/wstgridtree.js new file mode 100755 index 0000000..0011b54 --- /dev/null +++ b/static/src/wstgridtree.js @@ -0,0 +1,157 @@ +/** + * 因为ligerui的tree用起来有些问题没解决,所以赶时间临时参考效果做一个,后期看情况扩展,使用参数上参考ligerui.^_^. + * params: { + * url:'xxxx/xxx/xxx', + * width:'100%', + * headerRowHeight:28, + * rowHeight:28, + * params:{xxx:xxx,xxx:xxx} + * rownumbers:true, + * columns:[{display:'分类名称',name:'catName',id:'catId',align:'left',width:'20%',render:function(item){}}] + *} + */ +$.fn.WSTGridTree = function(options){ + var radomId = (new Date().getTime()+Math.round(Math.random()*700)); + var defaults = {id:'wst_'+radomId,tbodyId:'wst_tbody_'+radomId,width:'100%',headerRowHeight:28,rowHeight:28,nodeNum:0,params:{},level:0}; + var opts = $.extend(defaults, options); + var jqObj = $(this); + var treeKeyId; + var createTBHead = function(){ + var head = [],htmp,rowAlign,rowWidth; + head.push('<table class="mmg-head wst-grid-tree" cellspacing="0" cellpadding="0" width="'+opts.width+'"><thead id="'+opts.tbodyId+'" class="mmg-headWrapper"><tr height="'+opts.headerRowHeight+'" class="mmg-head wst-grid-tree-hd">'); + if(opts.rownumbers)head.push('<td class="wst-grid-tree-hd-cell first" style="width:26px;">#</td>'); + for(var i=0;i<opts.columns.length;i++){ + htmp = opts.columns[i]; + rowWidth = htmp.width?('width="'+htmp.width+'"'):""; + if(htmp.id){ + treeKeyId = htmp.id; + head.push('<td class="wst-grid-tree-hd-cell" style="text-align:left;padding-left:5px;" '+rowWidth+'>'+htmp.display+'</td>'); + }else{ + rowAlign = (htmp.align?(' style="text-align:'+htmp.align+'" '):''); + head.push('<td class="wst-grid-tree-hd-cell" '+rowAlign+' '+rowWidth+'>'+htmp.display+'</td>'); + } + } + head.push('</tr></thead></table>'); + $(jqObj).html(head.join('')); + } + var loadData = function(){ + var popts = $.extend(opts,{pid:opts.tbodyId,params:{},level:0}); + loadRow(popts); + } + var loadRow = function(_opts){ + $("tr[id^='"+opts.pid+"_']").remove(); + $.getJSON(_opts.url,_opts.params,function(data,textStatus){ + if(data.Rows){ + var body,htmp,ttmp,val,rowAlign,rowWidth,nodeId,prefix; + data = data.Rows; + var lastNodeId = opts.pid; + for(var i=0;i<data.length;i++){ + ttmp = data[i]; + nodeId = _opts.pid+"_"+opts.nodeNum; + opts.nodeNum++; + body = []; + body.push('<tr id="'+nodeId+'" height="'+opts.rowHeight+'" class="mmg mmg-body wst-grid-tree-row j-'+ttmp[treeKeyId]+'" dataid="'+ttmp[treeKeyId]+'" pdataid="'+nodeId+'" lv="'+_opts.level+'">'); + if(opts.rownumbers)body.push('<td class="wst-grid-tree-row-cell first"><label class="mmg-index" style="margin-right:0px">'+(i+1)+'</label></td>'); + for(var j=0;j<opts.columns.length;j++){ + htmp = opts.columns[j]; + if(htmp.render){ + val = htmp.render(ttmp); + }else{ + val = ttmp[htmp.name]; + } + rowWidth = htmp.width?('width="'+htmp.width+'"'):""; + if(htmp.id){ + prefix = ''; + for(var k=0;k<_opts.level;k++){ + prefix+='<div class="wst-grid-tree-space"></div>'; + } + prefix+='<div class="l-grid-tree-link fa fa-folder wst-tree-img" dataid="'+ttmp[treeKeyId]+'" pdataid="'+nodeId+'" lv="'+_opts.level+'"></div>'; + body.push('<td class="wst-grid-tree-row-cell" style="text-align:left" '+rowWidth+'>'+prefix+val+'</td>'); + }else{ + rowAlign = (htmp.align?(' style="text-align:'+htmp.align+'" '):''); + body.push('<td class="wst-grid-tree-row-cell" '+rowAlign+' '+rowWidth+'>'+val+'</td>'); + } + } + body.push('</tr>'); + $(body.join('')).insertAfter($('#'+lastNodeId)); + lastNodeId = nodeId; + $('#'+nodeId+" .wst-tree-img").click(function(){ + if($(this).hasClass('fa-folder')){ + $(this).removeClass('fa-folder').addClass('fa-folder-open'); + if($("tr[id^='"+$(this).attr('pdataid')+"_']").size()==0){ + _opts.pid = $(this).attr('pdataid'); + _opts.params[treeKeyId] = $(this).attr('dataid'); + _opts.level = parseInt($(this).attr('lv'),10)+1; + loadRow(_opts); + }else{ + $("tr[id^='"+$(this).attr('pdataid')+"_']").each(function(){ + $(this).show(); + }) + } + }else{ + $(this).removeClass('fa-folder-open').addClass('fa-folder'); + $("tr[id^='"+$(this).attr('pdataid')+"_']").each(function(){ + $(this).hide(); + }) + } + changeRowColor(); + changeLinenumber(); + }) + } + changeRowColor(); + changeLinenumber(); + } + if(opts.callback)opts.callback(); + }) + } + var changeRowColor = function(){ + var even = false; + $('.wst-grid-tree-row').each(function(){ + $(this).removeClass('bg-color'); + if($(this).is(':visible')){ + if(even)$(this).addClass('bg-color'); + even = !even; + $(this).click(function(){ + $(this).addClass('row-selected').siblings().removeClass('row-selected'); + $(this).addClass('row-selected').siblings().each(function(){ + if($(this).hasClass('bg-color2') && !$(this).hasClass('row-selected'))$(this).removeClass('bg-color2').addClass('bg-color'); + }) + + }); + /*$(this).live({ + mouseover:function(){ + if($(this).hasClass('row-selected'))$(this).removeClass('row-selected').addClass('row-selected2'); + if($(this).hasClass('bg-color'))$(this).removeClass('bg-color').addClass('bg-color2'); + $(this).addClass('row-hover'); + }, + mouseout:function(){ + $(this).removeClass('row-hover'); + if($(this).hasClass('row-selected2'))$(this).removeClass('row-selected2').addClass('row-selected'); + if($(this).hasClass('bg-color2') && !$(this).hasClass('row-selected'))$(this).removeClass('bg-color2').addClass('bg-color'); + } + }) */ + } + }) + } + var changeLinenumber = function(){ + var i=1; + $('.wst-grid-tree-row').each(function(){ + if($(this).is(':visible'))$(this).find('.l-grid-row-cell-rownumbers').html(i++); + }); + } + createTBHead(); + loadData(); + return {reload:function(nodeId){ + if(nodeId && nodeId>0){ + var node = $('.j-'+nodeId); + var topts = {params:{}}; + topts['pid'] = node.attr('id'); + topts['params'][treeKeyId] = nodeId; + topts['level'] = parseInt(node.attr('lv'),10)+1; + var popts = $.extend(opts,topts); + loadRow(popts); + }else{ + loadData(); + } + }} +} \ No newline at end of file diff --git a/static/src/ztree/jquery.ztree.all-3.5.js b/static/src/ztree/jquery.ztree.all-3.5.js new file mode 100755 index 0000000..64be6c0 --- /dev/null +++ b/static/src/ztree/jquery.ztree.all-3.5.js @@ -0,0 +1,3642 @@ + +/* + * JQuery zTree core v3.5.24 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-06-06 + */ +(function($){ + var settings = {}, roots = {}, caches = {}, + //default consts of core + _consts = { + className: { + BUTTON: "button", + LEVEL: "level", + ICO_LOADING: "ico_loading", + SWITCH: "switch", + NAME: 'node_name' + }, + event: { + NODECREATED: "ztree_nodeCreated", + CLICK: "ztree_click", + EXPAND: "ztree_expand", + COLLAPSE: "ztree_collapse", + ASYNC_SUCCESS: "ztree_async_success", + ASYNC_ERROR: "ztree_async_error", + REMOVE: "ztree_remove", + SELECTED: "ztree_selected", + UNSELECTED: "ztree_unselected" + }, + id: { + A: "_a", + ICON: "_ico", + SPAN: "_span", + SWITCH: "_switch", + UL: "_ul" + }, + line: { + ROOT: "root", + ROOTS: "roots", + CENTER: "center", + BOTTOM: "bottom", + NOLINE: "noline", + LINE: "line" + }, + folder: { + OPEN: "open", + CLOSE: "close", + DOCU: "docu" + }, + node: { + CURSELECTED: "curSelectedNode" + } + }, + //default setting of core + _setting = { + treeId: "", + treeObj: null, + view: { + addDiyDom: null, + autoCancelSelected: true, + dblClickExpand: true, + expandSpeed: "fast", + fontCss: {}, + nameIsHTML: false, + selectedMulti: true, + showIcon: true, + showLine: true, + showTitle: true, + txtSelectedEnable: false + }, + data: { + key: { + children: "children", + name: "name", + title: "", + url: "url", + icon: "icon" + }, + simpleData: { + enable: false, + idKey: "id", + pIdKey: "pId", + rootPId: null + }, + keep: { + parent: false, + leaf: false + } + }, + async: { + enable: false, + contentType: "application/x-www-form-urlencoded", + type: "post", + dataType: "text", + url: "", + autoParam: [], + otherParam: [], + dataFilter: null + }, + callback: { + beforeAsync:null, + beforeClick:null, + beforeDblClick:null, + beforeRightClick:null, + beforeMouseDown:null, + beforeMouseUp:null, + beforeExpand:null, + beforeCollapse:null, + beforeRemove:null, + + onAsyncError:null, + onAsyncSuccess:null, + onNodeCreated:null, + onClick:null, + onDblClick:null, + onRightClick:null, + onMouseDown:null, + onMouseUp:null, + onExpand:null, + onCollapse:null, + onRemove:null + } + }, + //default root of core + //zTree use root to save full data + _initRoot = function (setting) { + var r = data.getRoot(setting); + if (!r) { + r = {}; + data.setRoot(setting, r); + } + r[setting.data.key.children] = []; + r.expandTriggerFlag = false; + r.curSelectedList = []; + r.noSelection = true; + r.createdNodes = []; + r.zId = 0; + r._ver = (new Date()).getTime(); + }, + //default cache of core + _initCache = function(setting) { + var c = data.getCache(setting); + if (!c) { + c = {}; + data.setCache(setting, c); + } + c.nodes = []; + c.doms = []; + }, + //default bindEvent of core + _bindEvent = function(setting) { + var o = setting.treeObj, + c = consts.event; + o.bind(c.NODECREATED, function (event, treeId, node) { + tools.apply(setting.callback.onNodeCreated, [event, treeId, node]); + }); + + o.bind(c.CLICK, function (event, srcEvent, treeId, node, clickFlag) { + tools.apply(setting.callback.onClick, [srcEvent, treeId, node, clickFlag]); + }); + + o.bind(c.EXPAND, function (event, treeId, node) { + tools.apply(setting.callback.onExpand, [event, treeId, node]); + }); + + o.bind(c.COLLAPSE, function (event, treeId, node) { + tools.apply(setting.callback.onCollapse, [event, treeId, node]); + }); + + o.bind(c.ASYNC_SUCCESS, function (event, treeId, node, msg) { + tools.apply(setting.callback.onAsyncSuccess, [event, treeId, node, msg]); + }); + + o.bind(c.ASYNC_ERROR, function (event, treeId, node, XMLHttpRequest, textStatus, errorThrown) { + tools.apply(setting.callback.onAsyncError, [event, treeId, node, XMLHttpRequest, textStatus, errorThrown]); + }); + + o.bind(c.REMOVE, function (event, treeId, treeNode) { + tools.apply(setting.callback.onRemove, [event, treeId, treeNode]); + }); + + o.bind(c.SELECTED, function (event, treeId, node) { + tools.apply(setting.callback.onSelected, [treeId, node]); + }); + o.bind(c.UNSELECTED, function (event, treeId, node) { + tools.apply(setting.callback.onUnSelected, [treeId, node]); + }); + }, + _unbindEvent = function(setting) { + var o = setting.treeObj, + c = consts.event; + o.unbind(c.NODECREATED) + .unbind(c.CLICK) + .unbind(c.EXPAND) + .unbind(c.COLLAPSE) + .unbind(c.ASYNC_SUCCESS) + .unbind(c.ASYNC_ERROR) + .unbind(c.REMOVE) + .unbind(c.SELECTED) + .unbind(c.UNSELECTED); + }, + //default event proxy of core + _eventProxy = function(event) { + var target = event.target, + setting = data.getSetting(event.data.treeId), + tId = "", node = null, + nodeEventType = "", treeEventType = "", + nodeEventCallback = null, treeEventCallback = null, + tmp = null; + + if (tools.eqs(event.type, "mousedown")) { + treeEventType = "mousedown"; + } else if (tools.eqs(event.type, "mouseup")) { + treeEventType = "mouseup"; + } else if (tools.eqs(event.type, "contextmenu")) { + treeEventType = "contextmenu"; + } else if (tools.eqs(event.type, "click")) { + if (tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.SWITCH) !== null) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "switchNode"; + } else { + tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "clickNode"; + } + } + } else if (tools.eqs(event.type, "dblclick")) { + treeEventType = "dblclick"; + tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "switchNode"; + } + } + if (treeEventType.length > 0 && tId.length == 0) { + tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (tmp) {tId = tools.getNodeMainDom(tmp).id;} + } + // event to node + if (tId.length>0) { + node = data.getNodeCache(setting, tId); + switch (nodeEventType) { + case "switchNode" : + if (!node.isParent) { + nodeEventType = ""; + } else if (tools.eqs(event.type, "click") + || (tools.eqs(event.type, "dblclick") && tools.apply(setting.view.dblClickExpand, [setting.treeId, node], setting.view.dblClickExpand))) { + nodeEventCallback = handler.onSwitchNode; + } else { + nodeEventType = ""; + } + break; + case "clickNode" : + nodeEventCallback = handler.onClickNode; + break; + } + } + // event to zTree + switch (treeEventType) { + case "mousedown" : + treeEventCallback = handler.onZTreeMousedown; + break; + case "mouseup" : + treeEventCallback = handler.onZTreeMouseup; + break; + case "dblclick" : + treeEventCallback = handler.onZTreeDblclick; + break; + case "contextmenu" : + treeEventCallback = handler.onZTreeContextmenu; + break; + } + var proxyResult = { + stop: false, + node: node, + nodeEventType: nodeEventType, + nodeEventCallback: nodeEventCallback, + treeEventType: treeEventType, + treeEventCallback: treeEventCallback + }; + return proxyResult + }, + //default init node of core + _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { + if (!n) return; + var r = data.getRoot(setting), + childKey = setting.data.key.children; + n.level = level; + n.tId = setting.treeId + "_" + (++r.zId); + n.parentTId = parentNode ? parentNode.tId : null; + n.open = (typeof n.open == "string") ? tools.eqs(n.open, "true") : !!n.open; + if (n[childKey] && n[childKey].length > 0) { + n.isParent = true; + n.zAsync = true; + } else { + n.isParent = (typeof n.isParent == "string") ? tools.eqs(n.isParent, "true") : !!n.isParent; + n.open = (n.isParent && !setting.async.enable) ? n.open : false; + n.zAsync = !n.isParent; + } + n.isFirstNode = isFirstNode; + n.isLastNode = isLastNode; + n.getParentNode = function() {return data.getNodeCache(setting, n.parentTId);}; + n.getPreNode = function() {return data.getPreNode(setting, n);}; + n.getNextNode = function() {return data.getNextNode(setting, n);}; + n.getIndex = function() {return data.getNodeIndex(setting, n);}; + n.getPath = function() {return data.getNodePath(setting, n);}; + n.isAjaxing = false; + data.fixPIdKeyValue(setting, n); + }, + _init = { + bind: [_bindEvent], + unbind: [_unbindEvent], + caches: [_initCache], + nodes: [_initNode], + proxys: [_eventProxy], + roots: [_initRoot], + beforeA: [], + afterA: [], + innerBeforeA: [], + innerAfterA: [], + zTreeTools: [] + }, + //method of operate data + data = { + addNodeCache: function(setting, node) { + data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = node; + }, + getNodeCacheId: function(tId) { + return tId.substring(tId.lastIndexOf("_")+1); + }, + addAfterA: function(afterA) { + _init.afterA.push(afterA); + }, + addBeforeA: function(beforeA) { + _init.beforeA.push(beforeA); + }, + addInnerAfterA: function(innerAfterA) { + _init.innerAfterA.push(innerAfterA); + }, + addInnerBeforeA: function(innerBeforeA) { + _init.innerBeforeA.push(innerBeforeA); + }, + addInitBind: function(bindEvent) { + _init.bind.push(bindEvent); + }, + addInitUnBind: function(unbindEvent) { + _init.unbind.push(unbindEvent); + }, + addInitCache: function(initCache) { + _init.caches.push(initCache); + }, + addInitNode: function(initNode) { + _init.nodes.push(initNode); + }, + addInitProxy: function(initProxy, isFirst) { + if (!!isFirst) { + _init.proxys.splice(0,0,initProxy); + } else { + _init.proxys.push(initProxy); + } + }, + addInitRoot: function(initRoot) { + _init.roots.push(initRoot); + }, + addNodesData: function(setting, parentNode, index, nodes) { + var childKey = setting.data.key.children, params; + if (!parentNode[childKey]) { + parentNode[childKey] = []; + index = -1; + } else if (index >= parentNode[childKey].length) { + index = -1; + } + + if (parentNode[childKey].length > 0 && index === 0) { + parentNode[childKey][0].isFirstNode = false; + view.setNodeLineIcos(setting, parentNode[childKey][0]); + } else if (parentNode[childKey].length > 0 && index < 0) { + parentNode[childKey][parentNode[childKey].length - 1].isLastNode = false; + view.setNodeLineIcos(setting, parentNode[childKey][parentNode[childKey].length - 1]); + } + parentNode.isParent = true; + + if (index<0) { + parentNode[childKey] = parentNode[childKey].concat(nodes); + } else { + params = [index, 0].concat(nodes); + parentNode[childKey].splice.apply(parentNode[childKey], params); + } + }, + addSelectedNode: function(setting, node) { + var root = data.getRoot(setting); + if (!data.isSelectedNode(setting, node)) { + root.curSelectedList.push(node); + } + }, + addCreatedNode: function(setting, node) { + if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { + var root = data.getRoot(setting); + root.createdNodes.push(node); + } + }, + addZTreeTools: function(zTreeTools) { + _init.zTreeTools.push(zTreeTools); + }, + exSetting: function(s) { + $.extend(true, _setting, s); + }, + fixPIdKeyValue: function(setting, node) { + if (setting.data.simpleData.enable) { + node[setting.data.simpleData.pIdKey] = node.parentTId ? node.getParentNode()[setting.data.simpleData.idKey] : setting.data.simpleData.rootPId; + } + }, + getAfterA: function(setting, node, array) { + for (var i=0, j=_init.afterA.length; i<j; i++) { + _init.afterA[i].apply(this, arguments); + } + }, + getBeforeA: function(setting, node, array) { + for (var i=0, j=_init.beforeA.length; i<j; i++) { + _init.beforeA[i].apply(this, arguments); + } + }, + getInnerAfterA: function(setting, node, array) { + for (var i=0, j=_init.innerAfterA.length; i<j; i++) { + _init.innerAfterA[i].apply(this, arguments); + } + }, + getInnerBeforeA: function(setting, node, array) { + for (var i=0, j=_init.innerBeforeA.length; i<j; i++) { + _init.innerBeforeA[i].apply(this, arguments); + } + }, + getCache: function(setting) { + return caches[setting.treeId]; + }, + getNodeIndex: function(setting, node) { + if (!node) return null; + var childKey = setting.data.key.children, + p = node.parentTId ? node.getParentNode() : data.getRoot(setting); + for (var i=0, l=p[childKey].length-1; i<=l; i++) { + if (p[childKey][i] === node) { + return i; + } + } + return -1; + }, + getNextNode: function(setting, node) { + if (!node) return null; + var childKey = setting.data.key.children, + p = node.parentTId ? node.getParentNode() : data.getRoot(setting); + for (var i=0, l=p[childKey].length-1; i<=l; i++) { + if (p[childKey][i] === node) { + return (i==l ? null : p[childKey][i+1]); + } + } + return null; + }, + getNodeByParam: function(setting, nodes, key, value) { + if (!nodes || !key) return null; + var childKey = setting.data.key.children; + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i][key] == value) { + return nodes[i]; + } + var tmp = data.getNodeByParam(setting, nodes[i][childKey], key, value); + if (tmp) return tmp; + } + return null; + }, + getNodeCache: function(setting, tId) { + if (!tId) return null; + var n = caches[setting.treeId].nodes[data.getNodeCacheId(tId)]; + return n ? n : null; + }, + getNodeName: function(setting, node) { + var nameKey = setting.data.key.name; + return "" + node[nameKey]; + }, + getNodePath: function(setting, node) { + if (!node) return null; + + var path; + if(node.parentTId) { + path = node.getParentNode().getPath(); + } else { + path = []; + } + + if (path) { + path.push(node); + } + + return path; + }, + getNodeTitle: function(setting, node) { + var t = setting.data.key.title === "" ? setting.data.key.name : setting.data.key.title; + return "" + node[t]; + }, + getNodes: function(setting) { + return data.getRoot(setting)[setting.data.key.children]; + }, + getNodesByParam: function(setting, nodes, key, value) { + if (!nodes || !key) return []; + var childKey = setting.data.key.children, + result = []; + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i][key] == value) { + result.push(nodes[i]); + } + result = result.concat(data.getNodesByParam(setting, nodes[i][childKey], key, value)); + } + return result; + }, + getNodesByParamFuzzy: function(setting, nodes, key, value) { + if (!nodes || !key) return []; + var childKey = setting.data.key.children, + result = []; + value = value.toLowerCase(); + for (var i = 0, l = nodes.length; i < l; i++) { + if (typeof nodes[i][key] == "string" && nodes[i][key].toLowerCase().indexOf(value)>-1) { + result.push(nodes[i]); + } + result = result.concat(data.getNodesByParamFuzzy(setting, nodes[i][childKey], key, value)); + } + return result; + }, + getNodesByFilter: function(setting, nodes, filter, isSingle, invokeParam) { + if (!nodes) return (isSingle ? null : []); + var childKey = setting.data.key.children, + result = isSingle ? null : []; + for (var i = 0, l = nodes.length; i < l; i++) { + if (tools.apply(filter, [nodes[i], invokeParam], false)) { + if (isSingle) {return nodes[i];} + result.push(nodes[i]); + } + var tmpResult = data.getNodesByFilter(setting, nodes[i][childKey], filter, isSingle, invokeParam); + if (isSingle && !!tmpResult) {return tmpResult;} + result = isSingle ? tmpResult : result.concat(tmpResult); + } + return result; + }, + getPreNode: function(setting, node) { + if (!node) return null; + var childKey = setting.data.key.children, + p = node.parentTId ? node.getParentNode() : data.getRoot(setting); + for (var i=0, l=p[childKey].length; i<l; i++) { + if (p[childKey][i] === node) { + return (i==0 ? null : p[childKey][i-1]); + } + } + return null; + }, + getRoot: function(setting) { + return setting ? roots[setting.treeId] : null; + }, + getRoots: function() { + return roots; + }, + getSetting: function(treeId) { + return settings[treeId]; + }, + getSettings: function() { + return settings; + }, + getZTreeTools: function(treeId) { + var r = this.getRoot(this.getSetting(treeId)); + return r ? r.treeTools : null; + }, + initCache: function(setting) { + for (var i=0, j=_init.caches.length; i<j; i++) { + _init.caches[i].apply(this, arguments); + } + }, + initNode: function(setting, level, node, parentNode, preNode, nextNode) { + for (var i=0, j=_init.nodes.length; i<j; i++) { + _init.nodes[i].apply(this, arguments); + } + }, + initRoot: function(setting) { + for (var i=0, j=_init.roots.length; i<j; i++) { + _init.roots[i].apply(this, arguments); + } + }, + isSelectedNode: function(setting, node) { + var root = data.getRoot(setting); + for (var i=0, j=root.curSelectedList.length; i<j; i++) { + if(node === root.curSelectedList[i]) return true; + } + return false; + }, + removeNodeCache: function(setting, node) { + var childKey = setting.data.key.children; + if (node[childKey]) { + for (var i=0, l=node[childKey].length; i<l; i++) { + data.removeNodeCache(setting, node[childKey][i]); + } + } + data.getCache(setting).nodes[data.getNodeCacheId(node.tId)] = null; + }, + removeSelectedNode: function(setting, node) { + var root = data.getRoot(setting); + for (var i=0, j=root.curSelectedList.length; i<j; i++) { + if(node === root.curSelectedList[i] || !data.getNodeCache(setting, root.curSelectedList[i].tId)) { + root.curSelectedList.splice(i, 1); + setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, node]); + i--;j--; + } + } + }, + setCache: function(setting, cache) { + caches[setting.treeId] = cache; + }, + setRoot: function(setting, root) { + roots[setting.treeId] = root; + }, + setZTreeTools: function(setting, zTreeTools) { + for (var i=0, j=_init.zTreeTools.length; i<j; i++) { + _init.zTreeTools[i].apply(this, arguments); + } + }, + transformToArrayFormat: function (setting, nodes) { + if (!nodes) return []; + var childKey = setting.data.key.children, + r = []; + if (tools.isArray(nodes)) { + for (var i=0, l=nodes.length; i<l; i++) { + r.push(nodes[i]); + if (nodes[i][childKey]) + r = r.concat(data.transformToArrayFormat(setting, nodes[i][childKey])); + } + } else { + r.push(nodes); + if (nodes[childKey]) + r = r.concat(data.transformToArrayFormat(setting, nodes[childKey])); + } + return r; + }, + transformTozTreeFormat: function(setting, sNodes) { + var i,l, + key = setting.data.simpleData.idKey, + parentKey = setting.data.simpleData.pIdKey, + childKey = setting.data.key.children; + if (!key || key=="" || !sNodes) return []; + + if (tools.isArray(sNodes)) { + var r = []; + var tmpMap = []; + for (i=0, l=sNodes.length; i<l; i++) { + tmpMap[sNodes[i][key]] = sNodes[i]; + } + for (i=0, l=sNodes.length; i<l; i++) { + if (tmpMap[sNodes[i][parentKey]] && sNodes[i][key] != sNodes[i][parentKey]) { + if (!tmpMap[sNodes[i][parentKey]][childKey]) + tmpMap[sNodes[i][parentKey]][childKey] = []; + tmpMap[sNodes[i][parentKey]][childKey].push(sNodes[i]); + } else { + r.push(sNodes[i]); + } + } + return r; + }else { + return [sNodes]; + } + } + }, + //method of event proxy + event = { + bindEvent: function(setting) { + for (var i=0, j=_init.bind.length; i<j; i++) { + _init.bind[i].apply(this, arguments); + } + }, + unbindEvent: function(setting) { + for (var i=0, j=_init.unbind.length; i<j; i++) { + _init.unbind[i].apply(this, arguments); + } + }, + bindTree: function(setting) { + var eventParam = { + treeId: setting.treeId + }, + o = setting.treeObj; + if (!setting.view.txtSelectedEnable) { + // for can't select text + o.bind('selectstart', handler.onSelectStart).css({ + "-moz-user-select":"-moz-none" + }); + } + o.bind('click', eventParam, event.proxy); + o.bind('dblclick', eventParam, event.proxy); + o.bind('mouseover', eventParam, event.proxy); + o.bind('mouseout', eventParam, event.proxy); + o.bind('mousedown', eventParam, event.proxy); + o.bind('mouseup', eventParam, event.proxy); + o.bind('contextmenu', eventParam, event.proxy); + }, + unbindTree: function(setting) { + var o = setting.treeObj; + o.unbind('selectstart', handler.onSelectStart) + .unbind('click', event.proxy) + .unbind('dblclick', event.proxy) + .unbind('mouseover', event.proxy) + .unbind('mouseout', event.proxy) + .unbind('mousedown', event.proxy) + .unbind('mouseup', event.proxy) + .unbind('contextmenu', event.proxy); + }, + doProxy: function(e) { + var results = []; + for (var i=0, j=_init.proxys.length; i<j; i++) { + var proxyResult = _init.proxys[i].apply(this, arguments); + results.push(proxyResult); + if (proxyResult.stop) { + break; + } + } + return results; + }, + proxy: function(e) { + var setting = data.getSetting(e.data.treeId); + if (!tools.uCanDo(setting, e)) return true; + var results = event.doProxy(e), + r = true, x = false; + for (var i=0, l=results.length; i<l; i++) { + var proxyResult = results[i]; + if (proxyResult.nodeEventCallback) { + x = true; + r = proxyResult.nodeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; + } + if (proxyResult.treeEventCallback) { + x = true; + r = proxyResult.treeEventCallback.apply(proxyResult, [e, proxyResult.node]) && r; + } + } + return r; + } + }, + //method of event handler + handler = { + onSwitchNode: function (event, node) { + var setting = data.getSetting(event.data.treeId); + if (node.open) { + if (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false) return true; + data.getRoot(setting).expandTriggerFlag = true; + view.switchNode(setting, node); + } else { + if (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false) return true; + data.getRoot(setting).expandTriggerFlag = true; + view.switchNode(setting, node); + } + return true; + }, + onClickNode: function (event, node) { + var setting = data.getSetting(event.data.treeId), + clickFlag = ( (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey)) && data.isSelectedNode(setting, node)) ? 0 : (setting.view.autoCancelSelected && (event.ctrlKey || event.metaKey) && setting.view.selectedMulti) ? 2 : 1; + if (tools.apply(setting.callback.beforeClick, [setting.treeId, node, clickFlag], true) == false) return true; + if (clickFlag === 0) { + view.cancelPreSelectedNode(setting, node); + } else { + view.selectNode(setting, node, clickFlag === 2); + } + setting.treeObj.trigger(consts.event.CLICK, [event, setting.treeId, node, clickFlag]); + return true; + }, + onZTreeMousedown: function(event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeMouseDown, [setting.treeId, node], true)) { + tools.apply(setting.callback.onMouseDown, [event, setting.treeId, node]); + } + return true; + }, + onZTreeMouseup: function(event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeMouseUp, [setting.treeId, node], true)) { + tools.apply(setting.callback.onMouseUp, [event, setting.treeId, node]); + } + return true; + }, + onZTreeDblclick: function(event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeDblClick, [setting.treeId, node], true)) { + tools.apply(setting.callback.onDblClick, [event, setting.treeId, node]); + } + return true; + }, + onZTreeContextmenu: function(event, node) { + var setting = data.getSetting(event.data.treeId); + if (tools.apply(setting.callback.beforeRightClick, [setting.treeId, node], true)) { + tools.apply(setting.callback.onRightClick, [event, setting.treeId, node]); + } + return (typeof setting.callback.onRightClick) != "function"; + }, + onSelectStart: function(e){ + var n = e.originalEvent.srcElement.nodeName.toLowerCase(); + return (n === "input" || n === "textarea" ); + } + }, + //method of tools for zTree + tools = { + apply: function(fun, param, defaultValue) { + if ((typeof fun) == "function") { + return fun.apply(zt, param?param:[]); + } + return defaultValue; + }, + canAsync: function(setting, node) { + var childKey = setting.data.key.children; + return (setting.async.enable && node && node.isParent && !(node.zAsync || (node[childKey] && node[childKey].length > 0))); + }, + clone: function (obj){ + if (obj === null) return null; + var o = tools.isArray(obj) ? [] : {}; + for(var i in obj){ + o[i] = (obj[i] instanceof Date) ? new Date(obj[i].getTime()) : (typeof obj[i] === "object" ? tools.clone(obj[i]) : obj[i]); + } + return o; + }, + eqs: function(str1, str2) { + return str1.toLowerCase() === str2.toLowerCase(); + }, + isArray: function(arr) { + return Object.prototype.toString.apply(arr) === "[object Array]"; + }, + $: function(node, exp, setting) { + if (!!exp && typeof exp != "string") { + setting = exp; + exp = ""; + } + if (typeof node == "string") { + return $(node, setting ? setting.treeObj.get(0).ownerDocument : null); + } else { + return $("#" + node.tId + exp, setting ? setting.treeObj : null); + } + }, + getMDom: function (setting, curDom, targetExpr) { + if (!curDom) return null; + while (curDom && curDom.id !== setting.treeId) { + for (var i=0, l=targetExpr.length; curDom.tagName && i<l; i++) { + if (tools.eqs(curDom.tagName, targetExpr[i].tagName) && curDom.getAttribute(targetExpr[i].attrName) !== null) { + return curDom; + } + } + curDom = curDom.parentNode; + } + return null; + }, + getNodeMainDom:function(target) { + return ($(target).parent("li").get(0) || $(target).parentsUntil("li").parent().get(0)); + }, + isChildOrSelf: function(dom, parentId) { + return ( $(dom).closest("#" + parentId).length> 0 ); + }, + uCanDo: function(setting, e) { + return true; + } + }, + //method of operate ztree dom + view = { + addNodes: function(setting, parentNode, index, newNodes, isSilent) { + if (setting.data.keep.leaf && parentNode && !parentNode.isParent) { + return; + } + if (!tools.isArray(newNodes)) { + newNodes = [newNodes]; + } + if (setting.data.simpleData.enable) { + newNodes = data.transformTozTreeFormat(setting, newNodes); + } + if (parentNode) { + var target_switchObj = $$(parentNode, consts.id.SWITCH, setting), + target_icoObj = $$(parentNode, consts.id.ICON, setting), + target_ulObj = $$(parentNode, consts.id.UL, setting); + + if (!parentNode.open) { + view.replaceSwitchClass(parentNode, target_switchObj, consts.folder.CLOSE); + view.replaceIcoClass(parentNode, target_icoObj, consts.folder.CLOSE); + parentNode.open = false; + target_ulObj.css({ + "display": "none" + }); + } + + data.addNodesData(setting, parentNode, index, newNodes); + view.createNodes(setting, parentNode.level + 1, newNodes, parentNode, index); + if (!isSilent) { + view.expandCollapseParentNode(setting, parentNode, true); + } + } else { + data.addNodesData(setting, data.getRoot(setting), index, newNodes); + view.createNodes(setting, 0, newNodes, null, index); + } + }, + appendNodes: function(setting, level, nodes, parentNode, index, initFlag, openFlag) { + if (!nodes) return []; + var html = [], + childKey = setting.data.key.children; + + var tmpPNode = (parentNode) ? parentNode: data.getRoot(setting), + tmpPChild = tmpPNode[childKey], + isFirstNode, isLastNode; + + if (!tmpPChild || index >= tmpPChild.length) { + index = -1; + } + + for (var i = 0, l = nodes.length; i < l; i++) { + var node = nodes[i]; + if (initFlag) { + isFirstNode = ((index===0 || tmpPChild.length == nodes.length) && (i == 0)); + isLastNode = (index < 0 && i == (nodes.length - 1)); + data.initNode(setting, level, node, parentNode, isFirstNode, isLastNode, openFlag); + data.addNodeCache(setting, node); + } + + var childHtml = []; + if (node[childKey] && node[childKey].length > 0) { + //make child html first, because checkType + childHtml = view.appendNodes(setting, level + 1, node[childKey], node, -1, initFlag, openFlag && node.open); + } + if (openFlag) { + + view.makeDOMNodeMainBefore(html, setting, node); + view.makeDOMNodeLine(html, setting, node); + data.getBeforeA(setting, node, html); + view.makeDOMNodeNameBefore(html, setting, node); + data.getInnerBeforeA(setting, node, html); + view.makeDOMNodeIcon(html, setting, node); + data.getInnerAfterA(setting, node, html); + view.makeDOMNodeNameAfter(html, setting, node); + data.getAfterA(setting, node, html); + if (node.isParent && node.open) { + view.makeUlHtml(setting, node, html, childHtml.join('')); + } + view.makeDOMNodeMainAfter(html, setting, node); + data.addCreatedNode(setting, node); + } + } + return html; + }, + appendParentULDom: function(setting, node) { + var html = [], + nObj = $$(node, setting); + if (!nObj.get(0) && !!node.parentTId) { + view.appendParentULDom(setting, node.getParentNode()); + nObj = $$(node, setting); + } + var ulObj = $$(node, consts.id.UL, setting); + if (ulObj.get(0)) { + ulObj.remove(); + } + var childKey = setting.data.key.children, + childHtml = view.appendNodes(setting, node.level+1, node[childKey], node, -1, false, true); + view.makeUlHtml(setting, node, html, childHtml.join('')); + nObj.append(html.join('')); + }, + asyncNode: function(setting, node, isSilent, callback) { + var i, l; + if (node && !node.isParent) { + tools.apply(callback); + return false; + } else if (node && node.isAjaxing) { + return false; + } else if (tools.apply(setting.callback.beforeAsync, [setting.treeId, node], true) == false) { + tools.apply(callback); + return false; + } + if (node) { + node.isAjaxing = true; + var icoObj = $$(node, consts.id.ICON, setting); + icoObj.attr({"style":"", "class":consts.className.BUTTON + " " + consts.className.ICO_LOADING}); + } + + var tmpParam = {}; + for (i = 0, l = setting.async.autoParam.length; node && i < l; i++) { + var pKey = setting.async.autoParam[i].split("="), spKey = pKey; + if (pKey.length>1) { + spKey = pKey[1]; + pKey = pKey[0]; + } + tmpParam[spKey] = node[pKey]; + } + if (tools.isArray(setting.async.otherParam)) { + for (i = 0, l = setting.async.otherParam.length; i < l; i += 2) { + tmpParam[setting.async.otherParam[i]] = setting.async.otherParam[i + 1]; + } + } else { + for (var p in setting.async.otherParam) { + tmpParam[p] = setting.async.otherParam[p]; + } + } + + var _tmpV = data.getRoot(setting)._ver; + $.ajax({ + contentType: setting.async.contentType, + cache: false, + type: setting.async.type, + url: tools.apply(setting.async.url, [setting.treeId, node], setting.async.url), + data: tmpParam, + dataType: setting.async.dataType, + success: function(msg) { + if (_tmpV != data.getRoot(setting)._ver) { + return; + } + var newNodes = []; + try { + if (!msg || msg.length == 0) { + newNodes = []; + } else if (typeof msg == "string") { + newNodes = eval("(" + msg + ")"); + } else { + newNodes = msg; + } + } catch(err) { + newNodes = msg; + } + + if (node) { + node.isAjaxing = null; + node.zAsync = true; + } + view.setNodeLineIcos(setting, node); + if (newNodes && newNodes !== "") { + newNodes = tools.apply(setting.async.dataFilter, [setting.treeId, node, newNodes], newNodes); + view.addNodes(setting, node, -1, !!newNodes ? tools.clone(newNodes) : [], !!isSilent); + } else { + view.addNodes(setting, node, -1, [], !!isSilent); + } + setting.treeObj.trigger(consts.event.ASYNC_SUCCESS, [setting.treeId, node, msg]); + tools.apply(callback); + }, + error: function(XMLHttpRequest, textStatus, errorThrown) { + if (_tmpV != data.getRoot(setting)._ver) { + return; + } + if (node) node.isAjaxing = null; + view.setNodeLineIcos(setting, node); + setting.treeObj.trigger(consts.event.ASYNC_ERROR, [setting.treeId, node, XMLHttpRequest, textStatus, errorThrown]); + } + }); + return true; + }, + cancelPreSelectedNode: function (setting, node, excludeNode) { + var list = data.getRoot(setting).curSelectedList, + i, n; + for (i=list.length-1; i>=0; i--) { + n = list[i]; + if (node === n || (!node && (!excludeNode || excludeNode !== n))) { + $$(n, consts.id.A, setting).removeClass(consts.node.CURSELECTED); + if (node) { + data.removeSelectedNode(setting, node); + break; + } else { + list.splice(i, 1); + setting.treeObj.trigger(consts.event.UNSELECTED, [setting.treeId, n]); + } + } + } + }, + createNodeCallback: function(setting) { + if (!!setting.callback.onNodeCreated || !!setting.view.addDiyDom) { + var root = data.getRoot(setting); + while (root.createdNodes.length>0) { + var node = root.createdNodes.shift(); + tools.apply(setting.view.addDiyDom, [setting.treeId, node]); + if (!!setting.callback.onNodeCreated) { + setting.treeObj.trigger(consts.event.NODECREATED, [setting.treeId, node]); + } + } + } + }, + createNodes: function(setting, level, nodes, parentNode, index) { + if (!nodes || nodes.length == 0) return; + var root = data.getRoot(setting), + childKey = setting.data.key.children, + openFlag = !parentNode || parentNode.open || !!$$(parentNode[childKey][0], setting).get(0); + root.createdNodes = []; + var zTreeHtml = view.appendNodes(setting, level, nodes, parentNode, index, true, openFlag), + parentObj, nextObj; + + if (!parentNode) { + parentObj = setting.treeObj; + //setting.treeObj.append(zTreeHtml.join('')); + } else { + var ulObj = $$(parentNode, consts.id.UL, setting); + if (ulObj.get(0)) { + parentObj = ulObj; + //ulObj.append(zTreeHtml.join('')); + } + } + if (parentObj) { + if (index >= 0) { + nextObj = parentObj.children()[index]; + } + if (index >=0 && nextObj) { + $(nextObj).before(zTreeHtml.join('')); + } else { + parentObj.append(zTreeHtml.join('')); + } + } + + view.createNodeCallback(setting); + }, + destroy: function(setting) { + if (!setting) return; + data.initCache(setting); + data.initRoot(setting); + event.unbindTree(setting); + event.unbindEvent(setting); + setting.treeObj.empty(); + delete settings[setting.treeId]; + }, + expandCollapseNode: function(setting, node, expandFlag, animateFlag, callback) { + var root = data.getRoot(setting), + childKey = setting.data.key.children; + var tmpCb, _callback; + if (!node) { + tools.apply(callback, []); + return; + } + if (root.expandTriggerFlag) { + _callback = callback; + tmpCb = function(){ + if (_callback) _callback(); + if (node.open) { + setting.treeObj.trigger(consts.event.EXPAND, [setting.treeId, node]); + } else { + setting.treeObj.trigger(consts.event.COLLAPSE, [setting.treeId, node]); + } + }; + callback = tmpCb; + root.expandTriggerFlag = false; + } + if (!node.open && node.isParent && ((!$$(node, consts.id.UL, setting).get(0)) || (node[childKey] && node[childKey].length>0 && !$$(node[childKey][0], setting).get(0)))) { + view.appendParentULDom(setting, node); + view.createNodeCallback(setting); + } + if (node.open == expandFlag) { + tools.apply(callback, []); + return; + } + var ulObj = $$(node, consts.id.UL, setting), + switchObj = $$(node, consts.id.SWITCH, setting), + icoObj = $$(node, consts.id.ICON, setting); + + if (node.isParent) { + node.open = !node.open; + if (node.iconOpen && node.iconClose) { + icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); + } + + if (node.open) { + view.replaceSwitchClass(node, switchObj, consts.folder.OPEN); + view.replaceIcoClass(node, icoObj, consts.folder.OPEN); + if (animateFlag == false || setting.view.expandSpeed == "") { + ulObj.show(); + tools.apply(callback, []); + } else { + if (node[childKey] && node[childKey].length > 0) { + ulObj.slideDown(setting.view.expandSpeed, callback); + } else { + ulObj.show(); + tools.apply(callback, []); + } + } + } else { + view.replaceSwitchClass(node, switchObj, consts.folder.CLOSE); + view.replaceIcoClass(node, icoObj, consts.folder.CLOSE); + if (animateFlag == false || setting.view.expandSpeed == "" || !(node[childKey] && node[childKey].length > 0)) { + ulObj.hide(); + tools.apply(callback, []); + } else { + ulObj.slideUp(setting.view.expandSpeed, callback); + } + } + } else { + tools.apply(callback, []); + } + }, + expandCollapseParentNode: function(setting, node, expandFlag, animateFlag, callback) { + if (!node) return; + if (!node.parentTId) { + view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback); + return; + } else { + view.expandCollapseNode(setting, node, expandFlag, animateFlag); + } + if (node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, animateFlag, callback); + } + }, + expandCollapseSonNode: function(setting, node, expandFlag, animateFlag, callback) { + var root = data.getRoot(setting), + childKey = setting.data.key.children, + treeNodes = (node) ? node[childKey]: root[childKey], + selfAnimateSign = (node) ? false : animateFlag, + expandTriggerFlag = data.getRoot(setting).expandTriggerFlag; + data.getRoot(setting).expandTriggerFlag = false; + if (treeNodes) { + for (var i = 0, l = treeNodes.length; i < l; i++) { + if (treeNodes[i]) view.expandCollapseSonNode(setting, treeNodes[i], expandFlag, selfAnimateSign); + } + } + data.getRoot(setting).expandTriggerFlag = expandTriggerFlag; + view.expandCollapseNode(setting, node, expandFlag, animateFlag, callback ); + }, + isSelectedNode: function (setting, node) { + if (!node) { + return false; + } + var list = data.getRoot(setting).curSelectedList, + i; + for (i=list.length-1; i>=0; i--) { + if (node === list[i]) { + return true; + } + } + return false; + }, + makeDOMNodeIcon: function(html, setting, node) { + var nameStr = data.getNodeName(setting, node), + name = setting.view.nameIsHTML ? nameStr : nameStr.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); + html.push("<span id='", node.tId, consts.id.ICON, + "' title='' treeNode", consts.id.ICON," class='", view.makeNodeIcoClass(setting, node), + "' style='", view.makeNodeIcoStyle(setting, node), "'></span><span id='", node.tId, consts.id.SPAN, + "' class='", consts.className.NAME, + "'>",name,"</span>"); + }, + makeDOMNodeLine: function(html, setting, node) { + html.push("<span id='", node.tId, consts.id.SWITCH, "' title='' class='", view.makeNodeLineClass(setting, node), "' treeNode", consts.id.SWITCH,"></span>"); + }, + makeDOMNodeMainAfter: function(html, setting, node) { + html.push("</li>"); + }, + makeDOMNodeMainBefore: function(html, setting, node) { + html.push("<li id='", node.tId, "' class='", consts.className.LEVEL, node.level,"' tabindex='0' hidefocus='true' treenode>"); + }, + makeDOMNodeNameAfter: function(html, setting, node) { + html.push("</a>"); + }, + makeDOMNodeNameBefore: function(html, setting, node) { + var title = data.getNodeTitle(setting, node), + url = view.makeNodeUrl(setting, node), + fontcss = view.makeNodeFontCss(setting, node), + fontStyle = []; + for (var f in fontcss) { + fontStyle.push(f, ":", fontcss[f], ";"); + } + html.push("<a id='", node.tId, consts.id.A, "' class='", consts.className.LEVEL, node.level,"' treeNode", consts.id.A," onclick=\"", (node.click || ''), + "\" ", ((url != null && url.length > 0) ? "href='" + url + "'" : ""), " target='",view.makeNodeTarget(node),"' style='", fontStyle.join(''), + "'"); + if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle) && title) {html.push("title='", title.replace(/'/g,"&#39;").replace(/</g,'&lt;').replace(/>/g,'&gt;'),"'");} + html.push(">"); + }, + makeNodeFontCss: function(setting, node) { + var fontCss = tools.apply(setting.view.fontCss, [setting.treeId, node], setting.view.fontCss); + return (fontCss && ((typeof fontCss) != "function")) ? fontCss : {}; + }, + makeNodeIcoClass: function(setting, node) { + var icoCss = ["ico"]; + if (!node.isAjaxing) { + icoCss[0] = (node.iconSkin ? node.iconSkin + "_" : "") + icoCss[0]; + if (node.isParent) { + icoCss.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); + } else { + icoCss.push(consts.folder.DOCU); + } + } + return consts.className.BUTTON + " " + icoCss.join('_'); + }, + makeNodeIcoStyle: function(setting, node) { + var icoStyle = []; + if (!node.isAjaxing) { + var icon = (node.isParent && node.iconOpen && node.iconClose) ? (node.open ? node.iconOpen : node.iconClose) : node[setting.data.key.icon]; + if (icon) icoStyle.push("background:url(", icon, ") 0 0 no-repeat;"); + if (setting.view.showIcon == false || !tools.apply(setting.view.showIcon, [setting.treeId, node], true)) { + icoStyle.push("width:0px;height:0px;"); + } + } + return icoStyle.join(''); + }, + makeNodeLineClass: function(setting, node) { + var lineClass = []; + if (setting.view.showLine) { + if (node.level == 0 && node.isFirstNode && node.isLastNode) { + lineClass.push(consts.line.ROOT); + } else if (node.level == 0 && node.isFirstNode) { + lineClass.push(consts.line.ROOTS); + } else if (node.isLastNode) { + lineClass.push(consts.line.BOTTOM); + } else { + lineClass.push(consts.line.CENTER); + } + } else { + lineClass.push(consts.line.NOLINE); + } + if (node.isParent) { + lineClass.push(node.open ? consts.folder.OPEN : consts.folder.CLOSE); + } else { + lineClass.push(consts.folder.DOCU); + } + return view.makeNodeLineClassEx(node) + lineClass.join('_'); + }, + makeNodeLineClassEx: function(node) { + return consts.className.BUTTON + " " + consts.className.LEVEL + node.level + " " + consts.className.SWITCH + " "; + }, + makeNodeTarget: function(node) { + return (node.target || "_blank"); + }, + makeNodeUrl: function(setting, node) { + var urlKey = setting.data.key.url; + return node[urlKey] ? node[urlKey] : null; + }, + makeUlHtml: function(setting, node, html, content) { + html.push("<ul id='", node.tId, consts.id.UL, "' class='", consts.className.LEVEL, node.level, " ", view.makeUlLineClass(setting, node), "' style='display:", (node.open ? "block": "none"),"'>"); + html.push(content); + html.push("</ul>"); + }, + makeUlLineClass: function(setting, node) { + return ((setting.view.showLine && !node.isLastNode) ? consts.line.LINE : ""); + }, + removeChildNodes: function(setting, node) { + if (!node) return; + var childKey = setting.data.key.children, + nodes = node[childKey]; + if (!nodes) return; + + for (var i = 0, l = nodes.length; i < l; i++) { + data.removeNodeCache(setting, nodes[i]); + } + data.removeSelectedNode(setting); + delete node[childKey]; + + if (!setting.data.keep.parent) { + node.isParent = false; + node.open = false; + var tmp_switchObj = $$(node, consts.id.SWITCH, setting), + tmp_icoObj = $$(node, consts.id.ICON, setting); + view.replaceSwitchClass(node, tmp_switchObj, consts.folder.DOCU); + view.replaceIcoClass(node, tmp_icoObj, consts.folder.DOCU); + $$(node, consts.id.UL, setting).remove(); + } else { + $$(node, consts.id.UL, setting).empty(); + } + }, + scrollIntoView: function(dom) { + if (!dom) { + return; + } + if (dom.scrollIntoViewIfNeeded) { + dom.scrollIntoViewIfNeeded(); + } else if (dom.scrollIntoView) { + dom.scrollIntoView(false); + } else { + try{dom.focus().blur();}catch(e){} + } + }, + setFirstNode: function(setting, parentNode) { + var childKey = setting.data.key.children, childLength = parentNode[childKey].length; + if ( childLength > 0) { + parentNode[childKey][0].isFirstNode = true; + } + }, + setLastNode: function(setting, parentNode) { + var childKey = setting.data.key.children, childLength = parentNode[childKey].length; + if ( childLength > 0) { + parentNode[childKey][childLength - 1].isLastNode = true; + } + }, + removeNode: function(setting, node) { + var root = data.getRoot(setting), + childKey = setting.data.key.children, + parentNode = (node.parentTId) ? node.getParentNode() : root; + + node.isFirstNode = false; + node.isLastNode = false; + node.getPreNode = function() {return null;}; + node.getNextNode = function() {return null;}; + + if (!data.getNodeCache(setting, node.tId)) { + return; + } + + $$(node, setting).remove(); + data.removeNodeCache(setting, node); + data.removeSelectedNode(setting, node); + + for (var i = 0, l = parentNode[childKey].length; i < l; i++) { + if (parentNode[childKey][i].tId == node.tId) { + parentNode[childKey].splice(i, 1); + break; + } + } + view.setFirstNode(setting, parentNode); + view.setLastNode(setting, parentNode); + + var tmp_ulObj,tmp_switchObj,tmp_icoObj, + childLength = parentNode[childKey].length; + + //repair nodes old parent + if (!setting.data.keep.parent && childLength == 0) { + //old parentNode has no child nodes + parentNode.isParent = false; + parentNode.open = false; + tmp_ulObj = $$(parentNode, consts.id.UL, setting); + tmp_switchObj = $$(parentNode, consts.id.SWITCH, setting); + tmp_icoObj = $$(parentNode, consts.id.ICON, setting); + view.replaceSwitchClass(parentNode, tmp_switchObj, consts.folder.DOCU); + view.replaceIcoClass(parentNode, tmp_icoObj, consts.folder.DOCU); + tmp_ulObj.css("display", "none"); + + } else if (setting.view.showLine && childLength > 0) { + //old parentNode has child nodes + var newLast = parentNode[childKey][childLength - 1]; + tmp_ulObj = $$(newLast, consts.id.UL, setting); + tmp_switchObj = $$(newLast, consts.id.SWITCH, setting); + tmp_icoObj = $$(newLast, consts.id.ICON, setting); + if (parentNode == root) { + if (parentNode[childKey].length == 1) { + //node was root, and ztree has only one root after move node + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.ROOT); + } else { + var tmp_first_switchObj = $$(parentNode[childKey][0], consts.id.SWITCH, setting); + view.replaceSwitchClass(parentNode[childKey][0], tmp_first_switchObj, consts.line.ROOTS); + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); + } + } else { + view.replaceSwitchClass(newLast, tmp_switchObj, consts.line.BOTTOM); + } + tmp_ulObj.removeClass(consts.line.LINE); + } + }, + replaceIcoClass: function(node, obj, newName) { + if (!obj || node.isAjaxing) return; + var tmpName = obj.attr("class"); + if (tmpName == undefined) return; + var tmpList = tmpName.split("_"); + switch (newName) { + case consts.folder.OPEN: + case consts.folder.CLOSE: + case consts.folder.DOCU: + tmpList[tmpList.length-1] = newName; + break; + } + obj.attr("class", tmpList.join("_")); + }, + replaceSwitchClass: function(node, obj, newName) { + if (!obj) return; + var tmpName = obj.attr("class"); + if (tmpName == undefined) return; + var tmpList = tmpName.split("_"); + switch (newName) { + case consts.line.ROOT: + case consts.line.ROOTS: + case consts.line.CENTER: + case consts.line.BOTTOM: + case consts.line.NOLINE: + tmpList[0] = view.makeNodeLineClassEx(node) + newName; + break; + case consts.folder.OPEN: + case consts.folder.CLOSE: + case consts.folder.DOCU: + tmpList[1] = newName; + break; + } + obj.attr("class", tmpList.join("_")); + if (newName !== consts.folder.DOCU) { + obj.removeAttr("disabled"); + } else { + obj.attr("disabled", "disabled"); + } + }, + selectNode: function(setting, node, addFlag) { + if (!addFlag) { + view.cancelPreSelectedNode(setting, null, node); + } + $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED); + data.addSelectedNode(setting, node); + setting.treeObj.trigger(consts.event.SELECTED, [setting.treeId, node]); + }, + setNodeFontCss: function(setting, treeNode) { + var aObj = $$(treeNode, consts.id.A, setting), + fontCss = view.makeNodeFontCss(setting, treeNode); + if (fontCss) { + aObj.css(fontCss); + } + }, + setNodeLineIcos: function(setting, node) { + if (!node) return; + var switchObj = $$(node, consts.id.SWITCH, setting), + ulObj = $$(node, consts.id.UL, setting), + icoObj = $$(node, consts.id.ICON, setting), + ulLine = view.makeUlLineClass(setting, node); + if (ulLine.length==0) { + ulObj.removeClass(consts.line.LINE); + } else { + ulObj.addClass(ulLine); + } + switchObj.attr("class", view.makeNodeLineClass(setting, node)); + if (node.isParent) { + switchObj.removeAttr("disabled"); + } else { + switchObj.attr("disabled", "disabled"); + } + icoObj.removeAttr("style"); + icoObj.attr("style", view.makeNodeIcoStyle(setting, node)); + icoObj.attr("class", view.makeNodeIcoClass(setting, node)); + }, + setNodeName: function(setting, node) { + var title = data.getNodeTitle(setting, node), + nObj = $$(node, consts.id.SPAN, setting); + nObj.empty(); + if (setting.view.nameIsHTML) { + nObj.html(data.getNodeName(setting, node)); + } else { + nObj.text(data.getNodeName(setting, node)); + } + if (tools.apply(setting.view.showTitle, [setting.treeId, node], setting.view.showTitle)) { + var aObj = $$(node, consts.id.A, setting); + aObj.attr("title", !title ? "" : title); + } + }, + setNodeTarget: function(setting, node) { + var aObj = $$(node, consts.id.A, setting); + aObj.attr("target", view.makeNodeTarget(node)); + }, + setNodeUrl: function(setting, node) { + var aObj = $$(node, consts.id.A, setting), + url = view.makeNodeUrl(setting, node); + if (url == null || url.length == 0) { + aObj.removeAttr("href"); + } else { + aObj.attr("href", url); + } + }, + switchNode: function(setting, node) { + if (node.open || !tools.canAsync(setting, node)) { + view.expandCollapseNode(setting, node, !node.open); + } else if (setting.async.enable) { + if (!view.asyncNode(setting, node)) { + view.expandCollapseNode(setting, node, !node.open); + return; + } + } else if (node) { + view.expandCollapseNode(setting, node, !node.open); + } + } + }; + // zTree defind + $.fn.zTree = { + consts : _consts, + _z : { + tools: tools, + view: view, + event: event, + data: data + }, + getZTreeObj: function(treeId) { + var o = data.getZTreeTools(treeId); + return o ? o : null; + }, + destroy: function(treeId) { + if (!!treeId && treeId.length > 0) { + view.destroy(data.getSetting(treeId)); + } else { + for(var s in settings) { + view.destroy(settings[s]); + } + } + }, + init: function(obj, zSetting, zNodes) { + var setting = tools.clone(_setting); + $.extend(true, setting, zSetting); + setting.treeId = obj.attr("id"); + setting.treeObj = obj; + setting.treeObj.empty(); + settings[setting.treeId] = setting; + //For some older browser,(e.g., ie6) + if(typeof document.body.style.maxHeight === "undefined") { + setting.view.expandSpeed = ""; + } + data.initRoot(setting); + var root = data.getRoot(setting), + childKey = setting.data.key.children; + zNodes = zNodes ? tools.clone(tools.isArray(zNodes)? zNodes : [zNodes]) : []; + if (setting.data.simpleData.enable) { + root[childKey] = data.transformTozTreeFormat(setting, zNodes); + } else { + root[childKey] = zNodes; + } + + data.initCache(setting); + event.unbindTree(setting); + event.bindTree(setting); + event.unbindEvent(setting); + event.bindEvent(setting); + + var zTreeTools = { + setting : setting, + addNodes : function(parentNode, index, newNodes, isSilent) { + if (!parentNode) parentNode = null; + if (parentNode && !parentNode.isParent && setting.data.keep.leaf) return null; + + var i = parseInt(index, 10); + if (isNaN(i)) { + isSilent = !!newNodes; + newNodes = index; + index = -1; + } else { + index = i; + } + if (!newNodes) return null; + + + var xNewNodes = tools.clone(tools.isArray(newNodes)? newNodes: [newNodes]); + function addCallback() { + view.addNodes(setting, parentNode, index, xNewNodes, (isSilent==true)); + } + + if (tools.canAsync(setting, parentNode)) { + view.asyncNode(setting, parentNode, isSilent, addCallback); + } else { + addCallback(); + } + return xNewNodes; + }, + cancelSelectedNode : function(node) { + view.cancelPreSelectedNode(setting, node); + }, + destroy : function() { + view.destroy(setting); + }, + expandAll : function(expandFlag) { + expandFlag = !!expandFlag; + view.expandCollapseSonNode(setting, null, expandFlag, true); + return expandFlag; + }, + expandNode : function(node, expandFlag, sonSign, focus, callbackFlag) { + if (!node || !node.isParent) return null; + if (expandFlag !== true && expandFlag !== false) { + expandFlag = !node.open; + } + callbackFlag = !!callbackFlag; + + if (callbackFlag && expandFlag && (tools.apply(setting.callback.beforeExpand, [setting.treeId, node], true) == false)) { + return null; + } else if (callbackFlag && !expandFlag && (tools.apply(setting.callback.beforeCollapse, [setting.treeId, node], true) == false)) { + return null; + } + if (expandFlag && node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), expandFlag, false); + } + if (expandFlag === node.open && !sonSign) { + return null; + } + + data.getRoot(setting).expandTriggerFlag = callbackFlag; + if (!tools.canAsync(setting, node) && sonSign) { + view.expandCollapseSonNode(setting, node, expandFlag, true, showNodeFocus); + } else { + node.open = !expandFlag; + view.switchNode(this.setting, node); + showNodeFocus(); + } + return expandFlag; + + function showNodeFocus() { + var a = $$(node, setting).get(0); + if (a && focus !== false) { + view.scrollIntoView(a); + } + } + }, + getNodes : function() { + return data.getNodes(setting); + }, + getNodeByParam : function(key, value, parentNode) { + if (!key) return null; + return data.getNodeByParam(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); + }, + getNodeByTId : function(tId) { + return data.getNodeCache(setting, tId); + }, + getNodesByParam : function(key, value, parentNode) { + if (!key) return null; + return data.getNodesByParam(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); + }, + getNodesByParamFuzzy : function(key, value, parentNode) { + if (!key) return null; + return data.getNodesByParamFuzzy(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), key, value); + }, + getNodesByFilter: function(filter, isSingle, parentNode, invokeParam) { + isSingle = !!isSingle; + if (!filter || (typeof filter != "function")) return (isSingle ? null : []); + return data.getNodesByFilter(setting, parentNode?parentNode[setting.data.key.children]:data.getNodes(setting), filter, isSingle, invokeParam); + }, + getNodeIndex : function(node) { + if (!node) return null; + var childKey = setting.data.key.children, + parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); + for (var i=0, l = parentNode[childKey].length; i < l; i++) { + if (parentNode[childKey][i] == node) return i; + } + return -1; + }, + getSelectedNodes : function() { + var r = [], list = data.getRoot(setting).curSelectedList; + for (var i=0, l=list.length; i<l; i++) { + r.push(list[i]); + } + return r; + }, + isSelectedNode : function(node) { + return data.isSelectedNode(setting, node); + }, + reAsyncChildNodes : function(parentNode, reloadType, isSilent) { + if (!this.setting.async.enable) return; + var isRoot = !parentNode; + if (isRoot) { + parentNode = data.getRoot(setting); + } + if (reloadType=="refresh") { + var childKey = this.setting.data.key.children; + for (var i = 0, l = parentNode[childKey] ? parentNode[childKey].length : 0; i < l; i++) { + data.removeNodeCache(setting, parentNode[childKey][i]); + } + data.removeSelectedNode(setting); + parentNode[childKey] = []; + if (isRoot) { + this.setting.treeObj.empty(); + } else { + var ulObj = $$(parentNode, consts.id.UL, setting); + ulObj.empty(); + } + } + view.asyncNode(this.setting, isRoot? null:parentNode, !!isSilent); + }, + refresh : function() { + this.setting.treeObj.empty(); + var root = data.getRoot(setting), + nodes = root[setting.data.key.children] + data.initRoot(setting); + root[setting.data.key.children] = nodes + data.initCache(setting); + view.createNodes(setting, 0, root[setting.data.key.children], null, -1); + }, + removeChildNodes : function(node) { + if (!node) return null; + var childKey = setting.data.key.children, + nodes = node[childKey]; + view.removeChildNodes(setting, node); + return nodes ? nodes : null; + }, + removeNode : function(node, callbackFlag) { + if (!node) return; + callbackFlag = !!callbackFlag; + if (callbackFlag && tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return; + view.removeNode(setting, node); + if (callbackFlag) { + this.setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); + } + }, + selectNode : function(node, addFlag, isSilent) { + if (!node) return; + if (tools.uCanDo(setting)) { + addFlag = setting.view.selectedMulti && addFlag; + if (node.parentTId) { + view.expandCollapseParentNode(setting, node.getParentNode(), true, false, showNodeFocus); + } else if (!isSilent) { + try{$$(node, setting).focus().blur();}catch(e){} + } + view.selectNode(setting, node, addFlag); + } + + function showNodeFocus() { + if (isSilent) { + return; + } + var a = $$(node, setting).get(0); + view.scrollIntoView(a); + } + }, + transformTozTreeNodes : function(simpleNodes) { + return data.transformTozTreeFormat(setting, simpleNodes); + }, + transformToArray : function(nodes) { + return data.transformToArrayFormat(setting, nodes); + }, + updateNode : function(node, checkTypeFlag) { + if (!node) return; + var nObj = $$(node, setting); + if (nObj.get(0) && tools.uCanDo(setting)) { + view.setNodeName(setting, node); + view.setNodeTarget(setting, node); + view.setNodeUrl(setting, node); + view.setNodeLineIcos(setting, node); + view.setNodeFontCss(setting, node); + } + } + } + root.treeTools = zTreeTools; + data.setZTreeTools(setting, zTreeTools); + + if (root[childKey] && root[childKey].length > 0) { + view.createNodes(setting, 0, root[childKey], null, -1); + } else if (setting.async.enable && setting.async.url && setting.async.url !== '') { + view.asyncNode(setting); + } + return zTreeTools; + } + }; + + var zt = $.fn.zTree, + $$ = tools.$, + consts = zt.consts; +})(jQuery); +/* + * JQuery zTree excheck v3.5.24 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-06-06 + */ +(function($){ + //default consts of excheck + var _consts = { + event: { + CHECK: "ztree_check" + }, + id: { + CHECK: "_check" + }, + checkbox: { + STYLE: "checkbox", + DEFAULT: "chk", + DISABLED: "disable", + FALSE: "false", + TRUE: "true", + FULL: "full", + PART: "part", + FOCUS: "focus" + }, + radio: { + STYLE: "radio", + TYPE_ALL: "all", + TYPE_LEVEL: "level" + } + }, + //default setting of excheck + _setting = { + check: { + enable: false, + autoCheckTrigger: false, + chkStyle: _consts.checkbox.STYLE, + nocheckInherit: false, + chkDisabledInherit: false, + radioType: _consts.radio.TYPE_LEVEL, + chkboxType: { + "Y": "ps", + "N": "ps" + } + }, + data: { + key: { + checked: "checked" + } + }, + callback: { + beforeCheck:null, + onCheck:null + } + }, + //default root of excheck + _initRoot = function (setting) { + var r = data.getRoot(setting); + r.radioCheckedList = []; + }, + //default cache of excheck + _initCache = function(treeId) {}, + //default bind event of excheck + _bindEvent = function(setting) { + var o = setting.treeObj, + c = consts.event; + o.bind(c.CHECK, function (event, srcEvent, treeId, node) { + event.srcEvent = srcEvent; + tools.apply(setting.callback.onCheck, [event, treeId, node]); + }); + }, + _unbindEvent = function(setting) { + var o = setting.treeObj, + c = consts.event; + o.unbind(c.CHECK); + }, + //default event proxy of excheck + _eventProxy = function(e) { + var target = e.target, + setting = data.getSetting(e.data.treeId), + tId = "", node = null, + nodeEventType = "", treeEventType = "", + nodeEventCallback = null, treeEventCallback = null; + + if (tools.eqs(e.type, "mouseover")) { + if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "mouseoverCheck"; + } + } else if (tools.eqs(e.type, "mouseout")) { + if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "mouseoutCheck"; + } + } else if (tools.eqs(e.type, "click")) { + if (setting.check.enable && tools.eqs(target.tagName, "span") && target.getAttribute("treeNode"+ consts.id.CHECK) !== null) { + tId = tools.getNodeMainDom(target).id; + nodeEventType = "checkNode"; + } + } + if (tId.length>0) { + node = data.getNodeCache(setting, tId); + switch (nodeEventType) { + case "checkNode" : + nodeEventCallback = _handler.onCheckNode; + break; + case "mouseoverCheck" : + nodeEventCallback = _handler.onMouseoverCheck; + break; + case "mouseoutCheck" : + nodeEventCallback = _handler.onMouseoutCheck; + break; + } + } + var proxyResult = { + stop: nodeEventType === "checkNode", + node: node, + nodeEventType: nodeEventType, + nodeEventCallback: nodeEventCallback, + treeEventType: treeEventType, + treeEventCallback: treeEventCallback + }; + return proxyResult + }, + //default init node of excheck + _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { + if (!n) return; + var checkedKey = setting.data.key.checked; + if (typeof n[checkedKey] == "string") n[checkedKey] = tools.eqs(n[checkedKey], "true"); + n[checkedKey] = !!n[checkedKey]; + n.checkedOld = n[checkedKey]; + if (typeof n.nocheck == "string") n.nocheck = tools.eqs(n.nocheck, "true"); + n.nocheck = !!n.nocheck || (setting.check.nocheckInherit && parentNode && !!parentNode.nocheck); + if (typeof n.chkDisabled == "string") n.chkDisabled = tools.eqs(n.chkDisabled, "true"); + n.chkDisabled = !!n.chkDisabled || (setting.check.chkDisabledInherit && parentNode && !!parentNode.chkDisabled); + if (typeof n.halfCheck == "string") n.halfCheck = tools.eqs(n.halfCheck, "true"); + n.halfCheck = !!n.halfCheck; + n.check_Child_State = -1; + n.check_Focus = false; + n.getCheckStatus = function() {return data.getCheckStatus(setting, n);}; + + if (setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL && n[checkedKey] ) { + var r = data.getRoot(setting); + r.radioCheckedList.push(n); + } + }, + //add dom for check + _beforeA = function(setting, node, html) { + var checkedKey = setting.data.key.checked; + if (setting.check.enable) { + data.makeChkFlag(setting, node); + html.push("<span ID='", node.tId, consts.id.CHECK, "' class='", view.makeChkClass(setting, node), "' treeNode", consts.id.CHECK, (node.nocheck === true?" style='display:none;'":""),"></span>"); + } + }, + //update zTreeObj, add method of check + _zTreeTools = function(setting, zTreeTools) { + zTreeTools.checkNode = function(node, checked, checkTypeFlag, callbackFlag) { + var checkedKey = this.setting.data.key.checked; + if (node.chkDisabled === true) return; + if (checked !== true && checked !== false) { + checked = !node[checkedKey]; + } + callbackFlag = !!callbackFlag; + + if (node[checkedKey] === checked && !checkTypeFlag) { + return; + } else if (callbackFlag && tools.apply(this.setting.callback.beforeCheck, [this.setting.treeId, node], true) == false) { + return; + } + if (tools.uCanDo(this.setting) && this.setting.check.enable && node.nocheck !== true) { + node[checkedKey] = checked; + var checkObj = $$(node, consts.id.CHECK, this.setting); + if (checkTypeFlag || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); + view.setChkClass(this.setting, checkObj, node); + view.repairParentChkClassWithSelf(this.setting, node); + if (callbackFlag) { + this.setting.treeObj.trigger(consts.event.CHECK, [null, this.setting.treeId, node]); + } + } + } + + zTreeTools.checkAllNodes = function(checked) { + view.repairAllChk(this.setting, !!checked); + } + + zTreeTools.getCheckedNodes = function(checked) { + var childKey = this.setting.data.key.children; + checked = (checked !== false); + return data.getTreeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey], checked); + } + + zTreeTools.getChangeCheckedNodes = function() { + var childKey = this.setting.data.key.children; + return data.getTreeChangeCheckedNodes(this.setting, data.getRoot(this.setting)[childKey]); + } + + zTreeTools.setChkDisabled = function(node, disabled, inheritParent, inheritChildren) { + disabled = !!disabled; + inheritParent = !!inheritParent; + inheritChildren = !!inheritChildren; + view.repairSonChkDisabled(this.setting, node, disabled, inheritChildren); + view.repairParentChkDisabled(this.setting, node.getParentNode(), disabled, inheritParent); + } + + var _updateNode = zTreeTools.updateNode; + zTreeTools.updateNode = function(node, checkTypeFlag) { + if (_updateNode) _updateNode.apply(zTreeTools, arguments); + if (!node || !this.setting.check.enable) return; + var nObj = $$(node, this.setting); + if (nObj.get(0) && tools.uCanDo(this.setting)) { + var checkObj = $$(node, consts.id.CHECK, this.setting); + if (checkTypeFlag == true || this.setting.check.chkStyle === consts.radio.STYLE) view.checkNodeRelation(this.setting, node); + view.setChkClass(this.setting, checkObj, node); + view.repairParentChkClassWithSelf(this.setting, node); + } + } + }, + //method of operate data + _data = { + getRadioCheckedList: function(setting) { + var checkedList = data.getRoot(setting).radioCheckedList; + for (var i=0, j=checkedList.length; i<j; i++) { + if(!data.getNodeCache(setting, checkedList[i].tId)) { + checkedList.splice(i, 1); + i--; j--; + } + } + return checkedList; + }, + getCheckStatus: function(setting, node) { + if (!setting.check.enable || node.nocheck || node.chkDisabled) return null; + var checkedKey = setting.data.key.checked, + r = { + checked: node[checkedKey], + half: node.halfCheck ? node.halfCheck : (setting.check.chkStyle == consts.radio.STYLE ? (node.check_Child_State === 2) : (node[checkedKey] ? (node.check_Child_State > -1 && node.check_Child_State < 2) : (node.check_Child_State > 0))) + }; + return r; + }, + getTreeCheckedNodes: function(setting, nodes, checked, results) { + if (!nodes) return []; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + onlyOne = (checked && setting.check.chkStyle == consts.radio.STYLE && setting.check.radioType == consts.radio.TYPE_ALL); + results = !results ? [] : results; + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] == checked) { + results.push(nodes[i]); + if(onlyOne) { + break; + } + } + data.getTreeCheckedNodes(setting, nodes[i][childKey], checked, results); + if(onlyOne && results.length > 0) { + break; + } + } + return results; + }, + getTreeChangeCheckedNodes: function(setting, nodes, results) { + if (!nodes) return []; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked; + results = !results ? [] : results; + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i].nocheck !== true && nodes[i].chkDisabled !== true && nodes[i][checkedKey] != nodes[i].checkedOld) { + results.push(nodes[i]); + } + data.getTreeChangeCheckedNodes(setting, nodes[i][childKey], results); + } + return results; + }, + makeChkFlag: function(setting, node) { + if (!node) return; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + chkFlag = -1; + if (node[childKey]) { + for (var i = 0, l = node[childKey].length; i < l; i++) { + var cNode = node[childKey][i]; + var tmp = -1; + if (setting.check.chkStyle == consts.radio.STYLE) { + if (cNode.nocheck === true || cNode.chkDisabled === true) { + tmp = cNode.check_Child_State; + } else if (cNode.halfCheck === true) { + tmp = 2; + } else if (cNode[checkedKey]) { + tmp = 2; + } else { + tmp = cNode.check_Child_State > 0 ? 2:0; + } + if (tmp == 2) { + chkFlag = 2; break; + } else if (tmp == 0){ + chkFlag = 0; + } + } else if (setting.check.chkStyle == consts.checkbox.STYLE) { + if (cNode.nocheck === true || cNode.chkDisabled === true) { + tmp = cNode.check_Child_State; + } else if (cNode.halfCheck === true) { + tmp = 1; + } else if (cNode[checkedKey] ) { + tmp = (cNode.check_Child_State === -1 || cNode.check_Child_State === 2) ? 2 : 1; + } else { + tmp = (cNode.check_Child_State > 0) ? 1 : 0; + } + if (tmp === 1) { + chkFlag = 1; break; + } else if (tmp === 2 && chkFlag > -1 && i > 0 && tmp !== chkFlag) { + chkFlag = 1; break; + } else if (chkFlag === 2 && tmp > -1 && tmp < 2) { + chkFlag = 1; break; + } else if (tmp > -1) { + chkFlag = tmp; + } + } + } + } + node.check_Child_State = chkFlag; + } + }, + //method of event proxy + _event = { + + }, + //method of event handler + _handler = { + onCheckNode: function (event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkedKey = setting.data.key.checked; + if (tools.apply(setting.callback.beforeCheck, [setting.treeId, node], true) == false) return true; + node[checkedKey] = !node[checkedKey]; + view.checkNodeRelation(setting, node); + var checkObj = $$(node, consts.id.CHECK, setting); + view.setChkClass(setting, checkObj, node); + view.repairParentChkClassWithSelf(setting, node); + setting.treeObj.trigger(consts.event.CHECK, [event, setting.treeId, node]); + return true; + }, + onMouseoverCheck: function(event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkObj = $$(node, consts.id.CHECK, setting); + node.check_Focus = true; + view.setChkClass(setting, checkObj, node); + return true; + }, + onMouseoutCheck: function(event, node) { + if (node.chkDisabled === true) return false; + var setting = data.getSetting(event.data.treeId), + checkObj = $$(node, consts.id.CHECK, setting); + node.check_Focus = false; + view.setChkClass(setting, checkObj, node); + return true; + } + }, + //method of tools for zTree + _tools = { + + }, + //method of operate ztree dom + _view = { + checkNodeRelation: function(setting, node) { + var pNode, i, l, + childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + r = consts.radio; + if (setting.check.chkStyle == r.STYLE) { + var checkedList = data.getRadioCheckedList(setting); + if (node[checkedKey]) { + if (setting.check.radioType == r.TYPE_ALL) { + for (i = checkedList.length-1; i >= 0; i--) { + pNode = checkedList[i]; + if (pNode[checkedKey] && pNode != node) { + pNode[checkedKey] = false; + checkedList.splice(i, 1); + + view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); + if (pNode.parentTId != node.parentTId) { + view.repairParentChkClassWithSelf(setting, pNode); + } + } + } + checkedList.push(node); + } else { + var parentNode = (node.parentTId) ? node.getParentNode() : data.getRoot(setting); + for (i = 0, l = parentNode[childKey].length; i < l; i++) { + pNode = parentNode[childKey][i]; + if (pNode[checkedKey] && pNode != node) { + pNode[checkedKey] = false; + view.setChkClass(setting, $$(pNode, consts.id.CHECK, setting), pNode); + } + } + } + } else if (setting.check.radioType == r.TYPE_ALL) { + for (i = 0, l = checkedList.length; i < l; i++) { + if (node == checkedList[i]) { + checkedList.splice(i, 1); + break; + } + } + } + + } else { + if (node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.Y.indexOf("s") > -1)) { + view.setSonNodeCheckBox(setting, node, true); + } + if (!node[checkedKey] && (!node[childKey] || node[childKey].length==0 || setting.check.chkboxType.N.indexOf("s") > -1)) { + view.setSonNodeCheckBox(setting, node, false); + } + if (node[checkedKey] && setting.check.chkboxType.Y.indexOf("p") > -1) { + view.setParentNodeCheckBox(setting, node, true); + } + if (!node[checkedKey] && setting.check.chkboxType.N.indexOf("p") > -1) { + view.setParentNodeCheckBox(setting, node, false); + } + } + }, + makeChkClass: function(setting, node) { + var checkedKey = setting.data.key.checked, + c = consts.checkbox, r = consts.radio, + fullStyle = ""; + if (node.chkDisabled === true) { + fullStyle = c.DISABLED; + } else if (node.halfCheck) { + fullStyle = c.PART; + } else if (setting.check.chkStyle == r.STYLE) { + fullStyle = (node.check_Child_State < 1)? c.FULL:c.PART; + } else { + fullStyle = node[checkedKey] ? ((node.check_Child_State === 2 || node.check_Child_State === -1) ? c.FULL:c.PART) : ((node.check_Child_State < 1)? c.FULL:c.PART); + } + var chkName = setting.check.chkStyle + "_" + (node[checkedKey] ? c.TRUE : c.FALSE) + "_" + fullStyle; + chkName = (node.check_Focus && node.chkDisabled !== true) ? chkName + "_" + c.FOCUS : chkName; + return consts.className.BUTTON + " " + c.DEFAULT + " " + chkName; + }, + repairAllChk: function(setting, checked) { + if (setting.check.enable && setting.check.chkStyle === consts.checkbox.STYLE) { + var checkedKey = setting.data.key.checked, + childKey = setting.data.key.children, + root = data.getRoot(setting); + for (var i = 0, l = root[childKey].length; i<l ; i++) { + var node = root[childKey][i]; + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = checked; + } + view.setSonNodeCheckBox(setting, node, checked); + } + } + }, + repairChkClass: function(setting, node) { + if (!node) return; + data.makeChkFlag(setting, node); + if (node.nocheck !== true) { + var checkObj = $$(node, consts.id.CHECK, setting); + view.setChkClass(setting, checkObj, node); + } + }, + repairParentChkClass: function(setting, node) { + if (!node || !node.parentTId) return; + var pNode = node.getParentNode(); + view.repairChkClass(setting, pNode); + view.repairParentChkClass(setting, pNode); + }, + repairParentChkClassWithSelf: function(setting, node) { + if (!node) return; + var childKey = setting.data.key.children; + if (node[childKey] && node[childKey].length > 0) { + view.repairParentChkClass(setting, node[childKey][0]); + } else { + view.repairParentChkClass(setting, node); + } + }, + repairSonChkDisabled: function(setting, node, chkDisabled, inherit) { + if (!node) return; + var childKey = setting.data.key.children; + if (node.chkDisabled != chkDisabled) { + node.chkDisabled = chkDisabled; + } + view.repairChkClass(setting, node); + if (node[childKey] && inherit) { + for (var i = 0, l = node[childKey].length; i < l; i++) { + var sNode = node[childKey][i]; + view.repairSonChkDisabled(setting, sNode, chkDisabled, inherit); + } + } + }, + repairParentChkDisabled: function(setting, node, chkDisabled, inherit) { + if (!node) return; + if (node.chkDisabled != chkDisabled && inherit) { + node.chkDisabled = chkDisabled; + } + view.repairChkClass(setting, node); + view.repairParentChkDisabled(setting, node.getParentNode(), chkDisabled, inherit); + }, + setChkClass: function(setting, obj, node) { + if (!obj) return; + if (node.nocheck === true) { + obj.hide(); + } else { + obj.show(); + } + obj.attr('class', view.makeChkClass(setting, node)); + }, + setParentNodeCheckBox: function(setting, node, value, srcNode) { + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + checkObj = $$(node, consts.id.CHECK, setting); + if (!srcNode) srcNode = node; + data.makeChkFlag(setting, node); + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = value; + view.setChkClass(setting, checkObj, node); + if (setting.check.autoCheckTrigger && node != srcNode) { + setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); + } + } + if (node.parentTId) { + var pSign = true; + if (!value) { + var pNodes = node.getParentNode()[childKey]; + for (var i = 0, l = pNodes.length; i < l; i++) { + if ((pNodes[i].nocheck !== true && pNodes[i].chkDisabled !== true && pNodes[i][checkedKey]) + || ((pNodes[i].nocheck === true || pNodes[i].chkDisabled === true) && pNodes[i].check_Child_State > 0)) { + pSign = false; + break; + } + } + } + if (pSign) { + view.setParentNodeCheckBox(setting, node.getParentNode(), value, srcNode); + } + } + }, + setSonNodeCheckBox: function(setting, node, value, srcNode) { + if (!node) return; + var childKey = setting.data.key.children, + checkedKey = setting.data.key.checked, + checkObj = $$(node, consts.id.CHECK, setting); + if (!srcNode) srcNode = node; + + var hasDisable = false; + if (node[childKey]) { + for (var i = 0, l = node[childKey].length; i < l; i++) { + var sNode = node[childKey][i]; + view.setSonNodeCheckBox(setting, sNode, value, srcNode); + if (sNode.chkDisabled === true) hasDisable = true; + } + } + + if (node != data.getRoot(setting) && node.chkDisabled !== true) { + if (hasDisable && node.nocheck !== true) { + data.makeChkFlag(setting, node); + } + if (node.nocheck !== true && node.chkDisabled !== true) { + node[checkedKey] = value; + if (!hasDisable) node.check_Child_State = (node[childKey] && node[childKey].length > 0) ? (value ? 2 : 0) : -1; + } else { + node.check_Child_State = -1; + } + view.setChkClass(setting, checkObj, node); + if (setting.check.autoCheckTrigger && node != srcNode && node.nocheck !== true && node.chkDisabled !== true) { + setting.treeObj.trigger(consts.event.CHECK, [null, setting.treeId, node]); + } + } + + } + }, + + _z = { + tools: _tools, + view: _view, + event: _event, + data: _data + }; + $.extend(true, $.fn.zTree.consts, _consts); + $.extend(true, $.fn.zTree._z, _z); + + var zt = $.fn.zTree, + tools = zt._z.tools, + consts = zt.consts, + view = zt._z.view, + data = zt._z.data, + event = zt._z.event, + $$ = tools.$; + + data.exSetting(_setting); + data.addInitBind(_bindEvent); + data.addInitUnBind(_unbindEvent); + data.addInitCache(_initCache); + data.addInitNode(_initNode); + data.addInitProxy(_eventProxy, true); + data.addInitRoot(_initRoot); + data.addBeforeA(_beforeA); + data.addZTreeTools(_zTreeTools); + + var _createNodes = view.createNodes; + view.createNodes = function(setting, level, nodes, parentNode, index) { + if (_createNodes) _createNodes.apply(view, arguments); + if (!nodes) return; + view.repairParentChkClassWithSelf(setting, parentNode); + } + var _removeNode = view.removeNode; + view.removeNode = function(setting, node) { + var parentNode = node.getParentNode(); + if (_removeNode) _removeNode.apply(view, arguments); + if (!node || !parentNode) return; + view.repairChkClass(setting, parentNode); + view.repairParentChkClass(setting, parentNode); + } + + var _appendNodes = view.appendNodes; + view.appendNodes = function(setting, level, nodes, parentNode, index, initFlag, openFlag) { + var html = ""; + if (_appendNodes) { + html = _appendNodes.apply(view, arguments); + } + if (parentNode) { + data.makeChkFlag(setting, parentNode); + } + return html; + } +})(jQuery); +/* + * JQuery zTree exedit v3.5.24 + * http://zTree.me/ + * + * Copyright (c) 2010 Hunter.z + * + * Licensed same as jquery - MIT License + * http://www.opensource.org/licenses/mit-license.php + * + * email: hunter.z@263.net + * Date: 2016-06-06 + */ +(function($){ + //default consts of exedit + var _consts = { + event: { + DRAG: "ztree_drag", + DROP: "ztree_drop", + RENAME: "ztree_rename", + DRAGMOVE:"ztree_dragmove" + }, + id: { + EDIT: "_edit", + INPUT: "_input", + REMOVE: "_remove" + }, + move: { + TYPE_INNER: "inner", + TYPE_PREV: "prev", + TYPE_NEXT: "next" + }, + node: { + CURSELECTED_EDIT: "curSelectedNode_Edit", + TMPTARGET_TREE: "tmpTargetzTree", + TMPTARGET_NODE: "tmpTargetNode" + } + }, + //default setting of exedit + _setting = { + edit: { + enable: false, + editNameSelectAll: false, + showRemoveBtn: true, + showRenameBtn: true, + removeTitle: "remove", + renameTitle: "rename", + drag: { + autoExpandTrigger: false, + isCopy: true, + isMove: true, + prev: true, + next: true, + inner: true, + minMoveSize: 5, + borderMax: 10, + borderMin: -5, + maxShowNodeNum: 5, + autoOpenTime: 500 + } + }, + view: { + addHoverDom: null, + removeHoverDom: null + }, + callback: { + beforeDrag:null, + beforeDragOpen:null, + beforeDrop:null, + beforeEditName:null, + beforeRename:null, + onDrag:null, + onDragMove:null, + onDrop:null, + onRename:null + } + }, + //default root of exedit + _initRoot = function (setting) { + var r = data.getRoot(setting), rs = data.getRoots(); + r.curEditNode = null; + r.curEditInput = null; + r.curHoverNode = null; + r.dragFlag = 0; + r.dragNodeShowBefore = []; + r.dragMaskList = new Array(); + rs.showHoverDom = true; + }, + //default cache of exedit + _initCache = function(treeId) {}, + //default bind event of exedit + _bindEvent = function(setting) { + var o = setting.treeObj; + var c = consts.event; + o.bind(c.RENAME, function (event, treeId, treeNode, isCancel) { + tools.apply(setting.callback.onRename, [event, treeId, treeNode, isCancel]); + }); + + o.bind(c.DRAG, function (event, srcEvent, treeId, treeNodes) { + tools.apply(setting.callback.onDrag, [srcEvent, treeId, treeNodes]); + }); + + o.bind(c.DRAGMOVE,function(event, srcEvent, treeId, treeNodes){ + tools.apply(setting.callback.onDragMove,[srcEvent, treeId, treeNodes]); + }); + + o.bind(c.DROP, function (event, srcEvent, treeId, treeNodes, targetNode, moveType, isCopy) { + tools.apply(setting.callback.onDrop, [srcEvent, treeId, treeNodes, targetNode, moveType, isCopy]); + }); + }, + _unbindEvent = function(setting) { + var o = setting.treeObj; + var c = consts.event; + o.unbind(c.RENAME); + o.unbind(c.DRAG); + o.unbind(c.DRAGMOVE); + o.unbind(c.DROP); + }, + //default event proxy of exedit + _eventProxy = function(e) { + var target = e.target, + setting = data.getSetting(e.data.treeId), + relatedTarget = e.relatedTarget, + tId = "", node = null, + nodeEventType = "", treeEventType = "", + nodeEventCallback = null, treeEventCallback = null, + tmp = null; + + if (tools.eqs(e.type, "mouseover")) { + tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "hoverOverNode"; + } + } else if (tools.eqs(e.type, "mouseout")) { + tmp = tools.getMDom(setting, relatedTarget, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (!tmp) { + tId = "remove"; + nodeEventType = "hoverOutNode"; + } + } else if (tools.eqs(e.type, "mousedown")) { + tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]); + if (tmp) { + tId = tools.getNodeMainDom(tmp).id; + nodeEventType = "mousedownNode"; + } + } + if (tId.length>0) { + node = data.getNodeCache(setting, tId); + switch (nodeEventType) { + case "mousedownNode" : + nodeEventCallback = _handler.onMousedownNode; + break; + case "hoverOverNode" : + nodeEventCallback = _handler.onHoverOverNode; + break; + case "hoverOutNode" : + nodeEventCallback = _handler.onHoverOutNode; + break; + } + } + var proxyResult = { + stop: false, + node: node, + nodeEventType: nodeEventType, + nodeEventCallback: nodeEventCallback, + treeEventType: treeEventType, + treeEventCallback: treeEventCallback + }; + return proxyResult + }, + //default init node of exedit + _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) { + if (!n) return; + n.isHover = false; + n.editNameFlag = false; + }, + //update zTreeObj, add method of edit + _zTreeTools = function(setting, zTreeTools) { + zTreeTools.cancelEditName = function(newName) { + var root = data.getRoot(this.setting); + if (!root.curEditNode) return; + view.cancelCurEditNode(this.setting, newName?newName:null, true); + } + zTreeTools.copyNode = function(targetNode, node, moveType, isSilent) { + if (!node) return null; + if (targetNode && !targetNode.isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) return null; + var _this = this, + newNode = tools.clone(node); + if (!targetNode) { + targetNode = null; + moveType = consts.move.TYPE_INNER; + } + if (moveType == consts.move.TYPE_INNER) { + function copyCallback() { + view.addNodes(_this.setting, targetNode, -1, [newNode], isSilent); + } + + if (tools.canAsync(this.setting, targetNode)) { + view.asyncNode(this.setting, targetNode, isSilent, copyCallback); + } else { + copyCallback(); + } + } else { + view.addNodes(this.setting, targetNode.parentNode, -1, [newNode], isSilent); + view.moveNode(this.setting, targetNode, newNode, moveType, false, isSilent); + } + return newNode; + } + zTreeTools.editName = function(node) { + if (!node || !node.tId || node !== data.getNodeCache(this.setting, node.tId)) return; + if (node.parentTId) view.expandCollapseParentNode(this.setting, node.getParentNode(), true); + view.editNode(this.setting, node) + } + zTreeTools.moveNode = function(targetNode, node, moveType, isSilent) { + if (!node) return node; + if (targetNode && !targetNode.isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) { + return null; + } else if (targetNode && ((node.parentTId == targetNode.tId && moveType == consts.move.TYPE_INNER) || $$(node, this.setting).find("#" + targetNode.tId).length > 0)) { + return null; + } else if (!targetNode) { + targetNode = null; + } + var _this = this; + function moveCallback() { + view.moveNode(_this.setting, targetNode, node, moveType, false, isSilent); + } + if (tools.canAsync(this.setting, targetNode) && moveType === consts.move.TYPE_INNER) { + view.asyncNode(this.setting, targetNode, isSilent, moveCallback); + } else { + moveCallback(); + } + return node; + } + zTreeTools.setEditable = function(editable) { + this.setting.edit.enable = editable; + return this.refresh(); + } + }, + //method of operate data + _data = { + setSonNodeLevel: function(setting, parentNode, node) { + if (!node) return; + var childKey = setting.data.key.children; + node.level = (parentNode)? parentNode.level + 1 : 0; + if (!node[childKey]) return; + for (var i = 0, l = node[childKey].length; i < l; i++) { + if (node[childKey][i]) data.setSonNodeLevel(setting, node, node[childKey][i]); + } + } + }, + //method of event proxy + _event = { + + }, + //method of event handler + _handler = { + onHoverOverNode: function(event, node) { + var setting = data.getSetting(event.data.treeId), + root = data.getRoot(setting); + if (root.curHoverNode != node) { + _handler.onHoverOutNode(event); + } + root.curHoverNode = node; + view.addHoverDom(setting, node); + }, + onHoverOutNode: function(event, node) { + var setting = data.getSetting(event.data.treeId), + root = data.getRoot(setting); + if (root.curHoverNode && !data.isSelectedNode(setting, root.curHoverNode)) { + view.removeTreeDom(setting, root.curHoverNode); + root.curHoverNode = null; + } + }, + onMousedownNode: function(eventMouseDown, _node) { + var i,l, + setting = data.getSetting(eventMouseDown.data.treeId), + root = data.getRoot(setting), roots = data.getRoots(); + //right click can't drag & drop + if (eventMouseDown.button == 2 || !setting.edit.enable || (!setting.edit.drag.isCopy && !setting.edit.drag.isMove)) return true; + + //input of edit node name can't drag & drop + var target = eventMouseDown.target, + _nodes = data.getRoot(setting).curSelectedList, + nodes = []; + if (!data.isSelectedNode(setting, _node)) { + nodes = [_node]; + } else { + for (i=0, l=_nodes.length; i<l; i++) { + if (_nodes[i].editNameFlag && tools.eqs(target.tagName, "input") && target.getAttribute("treeNode"+consts.id.INPUT) !== null) { + return true; + } + nodes.push(_nodes[i]); + if (nodes[0].parentTId !== _nodes[i].parentTId) { + nodes = [_node]; + break; + } + } + } + + view.editNodeBlur = true; + view.cancelCurEditNode(setting); + + var doc = $(setting.treeObj.get(0).ownerDocument), + body = $(setting.treeObj.get(0).ownerDocument.body), curNode, tmpArrow, tmpTarget, + isOtherTree = false, + targetSetting = setting, + sourceSetting = setting, + preNode, nextNode, + preTmpTargetNodeId = null, + preTmpMoveType = null, + tmpTargetNodeId = null, + moveType = consts.move.TYPE_INNER, + mouseDownX = eventMouseDown.clientX, + mouseDownY = eventMouseDown.clientY, + startTime = (new Date()).getTime(); + + if (tools.uCanDo(setting)) { + doc.bind("mousemove", _docMouseMove); + } + function _docMouseMove(event) { + //avoid start drag after click node + if (root.dragFlag == 0 && Math.abs(mouseDownX - event.clientX) < setting.edit.drag.minMoveSize + && Math.abs(mouseDownY - event.clientY) < setting.edit.drag.minMoveSize) { + return true; + } + var i, l, tmpNode, tmpDom, tmpNodes, + childKey = setting.data.key.children; + body.css("cursor", "pointer"); + + if (root.dragFlag == 0) { + if (tools.apply(setting.callback.beforeDrag, [setting.treeId, nodes], true) == false) { + _docMouseUp(event); + return true; + } + + for (i=0, l=nodes.length; i<l; i++) { + if (i==0) { + root.dragNodeShowBefore = []; + } + tmpNode = nodes[i]; + if (tmpNode.isParent && tmpNode.open) { + view.expandCollapseNode(setting, tmpNode, !tmpNode.open); + root.dragNodeShowBefore[tmpNode.tId] = true; + } else { + root.dragNodeShowBefore[tmpNode.tId] = false; + } + } + + root.dragFlag = 1; + roots.showHoverDom = false; + tools.showIfameMask(setting, true); + + //sort + var isOrder = true, lastIndex = -1; + if (nodes.length>1) { + var pNodes = nodes[0].parentTId ? nodes[0].getParentNode()[childKey] : data.getNodes(setting); + tmpNodes = []; + for (i=0, l=pNodes.length; i<l; i++) { + if (root.dragNodeShowBefore[pNodes[i].tId] !== undefined) { + if (isOrder && lastIndex > -1 && (lastIndex+1) !== i) { + isOrder = false; + } + tmpNodes.push(pNodes[i]); + lastIndex = i; + } + if (nodes.length === tmpNodes.length) { + nodes = tmpNodes; + break; + } + } + } + if (isOrder) { + preNode = nodes[0].getPreNode(); + nextNode = nodes[nodes.length-1].getNextNode(); + } + + //set node in selected + curNode = $$("<ul class='zTreeDragUL'></ul>", setting); + for (i=0, l=nodes.length; i<l; i++) { + tmpNode = nodes[i]; + tmpNode.editNameFlag = false; + view.selectNode(setting, tmpNode, i>0); + view.removeTreeDom(setting, tmpNode); + + if (i > setting.edit.drag.maxShowNodeNum-1) { + continue; + } + + tmpDom = $$("<li id='"+ tmpNode.tId +"_tmp'></li>", setting); + tmpDom.append($$(tmpNode, consts.id.A, setting).clone()); + tmpDom.css("padding", "0"); + tmpDom.children("#" + tmpNode.tId + consts.id.A).removeClass(consts.node.CURSELECTED); + curNode.append(tmpDom); + if (i == setting.edit.drag.maxShowNodeNum-1) { + tmpDom = $$("<li id='"+ tmpNode.tId +"_moretmp'><a> ... </a></li>", setting); + curNode.append(tmpDom); + } + } + curNode.attr("id", nodes[0].tId + consts.id.UL + "_tmp"); + curNode.addClass(setting.treeObj.attr("class")); + curNode.appendTo(body); + + tmpArrow = $$("<span class='tmpzTreeMove_arrow'></span>", setting); + tmpArrow.attr("id", "zTreeMove_arrow_tmp"); + tmpArrow.appendTo(body); + + setting.treeObj.trigger(consts.event.DRAG, [event, setting.treeId, nodes]); + } + + if (root.dragFlag == 1) { + if (tmpTarget && tmpArrow.attr("id") == event.target.id && tmpTargetNodeId && (event.clientX + doc.scrollLeft()+2) > ($("#" + tmpTargetNodeId + consts.id.A, tmpTarget).offset().left)) { + var xT = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget); + event.target = (xT.length > 0) ? xT.get(0) : event.target; + } else if (tmpTarget) { + tmpTarget.removeClass(consts.node.TMPTARGET_TREE); + if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV) + .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER); + } + tmpTarget = null; + tmpTargetNodeId = null; + + //judge drag & drop in multi ztree + isOtherTree = false; + targetSetting = setting; + var settings = data.getSettings(); + for (var s in settings) { + if (settings[s].treeId && settings[s].edit.enable && settings[s].treeId != setting.treeId + && (event.target.id == settings[s].treeId || $(event.target).parents("#" + settings[s].treeId).length>0)) { + isOtherTree = true; + targetSetting = settings[s]; + } + } + + var docScrollTop = doc.scrollTop(), + docScrollLeft = doc.scrollLeft(), + treeOffset = targetSetting.treeObj.offset(), + scrollHeight = targetSetting.treeObj.get(0).scrollHeight, + scrollWidth = targetSetting.treeObj.get(0).scrollWidth, + dTop = (event.clientY + docScrollTop - treeOffset.top), + dBottom = (targetSetting.treeObj.height() + treeOffset.top - event.clientY - docScrollTop), + dLeft = (event.clientX + docScrollLeft - treeOffset.left), + dRight = (targetSetting.treeObj.width() + treeOffset.left - event.clientX - docScrollLeft), + isTop = (dTop < setting.edit.drag.borderMax && dTop > setting.edit.drag.borderMin), + isBottom = (dBottom < setting.edit.drag.borderMax && dBottom > setting.edit.drag.borderMin), + isLeft = (dLeft < setting.edit.drag.borderMax && dLeft > setting.edit.drag.borderMin), + isRight = (dRight < setting.edit.drag.borderMax && dRight > setting.edit.drag.borderMin), + isTreeInner = dTop > setting.edit.drag.borderMin && dBottom > setting.edit.drag.borderMin && dLeft > setting.edit.drag.borderMin && dRight > setting.edit.drag.borderMin, + isTreeTop = (isTop && targetSetting.treeObj.scrollTop() <= 0), + isTreeBottom = (isBottom && (targetSetting.treeObj.scrollTop() + targetSetting.treeObj.height()+10) >= scrollHeight), + isTreeLeft = (isLeft && targetSetting.treeObj.scrollLeft() <= 0), + isTreeRight = (isRight && (targetSetting.treeObj.scrollLeft() + targetSetting.treeObj.width()+10) >= scrollWidth); + + if (event.target && tools.isChildOrSelf(event.target, targetSetting.treeId)) { + //get node <li> dom + var targetObj = event.target; + while (targetObj && targetObj.tagName && !tools.eqs(targetObj.tagName, "li") && targetObj.id != targetSetting.treeId) { + targetObj = targetObj.parentNode; + } + + var canMove = true; + //don't move to self or children of self + for (i=0, l=nodes.length; i<l; i++) { + tmpNode = nodes[i]; + if (targetObj.id === tmpNode.tId) { + canMove = false; + break; + } else if ($$(tmpNode, setting).find("#" + targetObj.id).length > 0) { + canMove = false; + break; + } + } + if (canMove && event.target && tools.isChildOrSelf(event.target, targetObj.id + consts.id.A)) { + tmpTarget = $(targetObj); + tmpTargetNodeId = targetObj.id; + } + } + + //the mouse must be in zTree + tmpNode = nodes[0]; + if (isTreeInner && tools.isChildOrSelf(event.target, targetSetting.treeId)) { + //judge mouse move in root of ztree + if (!tmpTarget && (event.target.id == targetSetting.treeId || isTreeTop || isTreeBottom || isTreeLeft || isTreeRight) && (isOtherTree || (!isOtherTree && tmpNode.parentTId))) { + tmpTarget = targetSetting.treeObj; + } + //auto scroll top + if (isTop) { + targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop()-10); + } else if (isBottom) { + targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop()+10); + } + if (isLeft) { + targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()-10); + } else if (isRight) { + targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()+10); + } + //auto scroll left + if (tmpTarget && tmpTarget != targetSetting.treeObj && tmpTarget.offset().left < targetSetting.treeObj.offset().left) { + targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()+ tmpTarget.offset().left - targetSetting.treeObj.offset().left); + } + } + + curNode.css({ + "top": (event.clientY + docScrollTop + 3) + "px", + "left": (event.clientX + docScrollLeft + 3) + "px" + }); + + var dX = 0; + var dY = 0; + if (tmpTarget && tmpTarget.attr("id")!=targetSetting.treeId) { + var tmpTargetNode = tmpTargetNodeId == null ? null: data.getNodeCache(targetSetting, tmpTargetNodeId), + isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy), + isPrev = !!(preNode && tmpTargetNodeId === preNode.tId), + isNext = !!(nextNode && tmpTargetNodeId === nextNode.tId), + isInner = (tmpNode.parentTId && tmpNode.parentTId == tmpTargetNodeId), + canPrev = (isCopy || !isNext) && tools.apply(targetSetting.edit.drag.prev, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.prev), + canNext = (isCopy || !isPrev) && tools.apply(targetSetting.edit.drag.next, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.next), + canInner = (isCopy || !isInner) && !(targetSetting.data.keep.leaf && !tmpTargetNode.isParent) && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.inner); + + function clearMove() { + tmpTarget = null; + tmpTargetNodeId = ""; + moveType = consts.move.TYPE_INNER; + tmpArrow.css({ + "display":"none" + }); + if (window.zTreeMoveTimer) { + clearTimeout(window.zTreeMoveTimer); + window.zTreeMoveTargetNodeTId = null + } + } + if (!canPrev && !canNext && !canInner) { + clearMove(); + } else { + var tmpTargetA = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget), + tmpNextA = tmpTargetNode.isLastNode ? null : $("#" + tmpTargetNode.getNextNode().tId + consts.id.A, tmpTarget.next()), + tmpTop = tmpTargetA.offset().top, + tmpLeft = tmpTargetA.offset().left, + prevPercent = canPrev ? (canInner ? 0.25 : (canNext ? 0.5 : 1) ) : -1, + nextPercent = canNext ? (canInner ? 0.75 : (canPrev ? 0.5 : 0) ) : -1, + dY_percent = (event.clientY + docScrollTop - tmpTop)/tmpTargetA.height(); + + if ((prevPercent==1 || dY_percent<=prevPercent && dY_percent>=-.2) && canPrev) { + dX = 1 - tmpArrow.width(); + dY = tmpTop - tmpArrow.height()/2; + moveType = consts.move.TYPE_PREV; + } else if ((nextPercent==0 || dY_percent>=nextPercent && dY_percent<=1.2) && canNext) { + dX = 1 - tmpArrow.width(); + dY = (tmpNextA == null || (tmpTargetNode.isParent && tmpTargetNode.open)) ? (tmpTop + tmpTargetA.height() - tmpArrow.height()/2) : (tmpNextA.offset().top - tmpArrow.height()/2); + moveType = consts.move.TYPE_NEXT; + } else if (canInner) { + dX = 5 - tmpArrow.width(); + dY = tmpTop; + moveType = consts.move.TYPE_INNER; + } else { + clearMove(); + } + + if (tmpTarget) { + tmpArrow.css({ + "display":"block", + "top": dY + "px", + "left": (tmpLeft + dX) + "px" + }); + tmpTargetA.addClass(consts.node.TMPTARGET_NODE + "_" + moveType); + + if (preTmpTargetNodeId != tmpTargetNodeId || preTmpMoveType != moveType) { + startTime = (new Date()).getTime(); + } + if (tmpTargetNode && tmpTargetNode.isParent && moveType == consts.move.TYPE_INNER) { + var startTimer = true; + if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId !== tmpTargetNode.tId) { + clearTimeout(window.zTreeMoveTimer); + window.zTreeMoveTargetNodeTId = null; + } else if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId === tmpTargetNode.tId) { + startTimer = false; + } + if (startTimer) { + window.zTreeMoveTimer = setTimeout(function() { + if (moveType != consts.move.TYPE_INNER) return; + if (tmpTargetNode && tmpTargetNode.isParent && !tmpTargetNode.open && (new Date()).getTime() - startTime > targetSetting.edit.drag.autoOpenTime + && tools.apply(targetSetting.callback.beforeDragOpen, [targetSetting.treeId, tmpTargetNode], true)) { + view.switchNode(targetSetting, tmpTargetNode); + if (targetSetting.edit.drag.autoExpandTrigger) { + targetSetting.treeObj.trigger(consts.event.EXPAND, [targetSetting.treeId, tmpTargetNode]); + } + } + }, targetSetting.edit.drag.autoOpenTime+50); + window.zTreeMoveTargetNodeTId = tmpTargetNode.tId; + } + } + } + } + } else { + moveType = consts.move.TYPE_INNER; + if (tmpTarget && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, null], !!targetSetting.edit.drag.inner)) { + tmpTarget.addClass(consts.node.TMPTARGET_TREE); + } else { + tmpTarget = null; + } + tmpArrow.css({ + "display":"none" + }); + if (window.zTreeMoveTimer) { + clearTimeout(window.zTreeMoveTimer); + window.zTreeMoveTargetNodeTId = null; + } + } + preTmpTargetNodeId = tmpTargetNodeId; + preTmpMoveType = moveType; + + setting.treeObj.trigger(consts.event.DRAGMOVE, [event, setting.treeId, nodes]); + } + return false; + } + + doc.bind("mouseup", _docMouseUp); + function _docMouseUp(event) { + if (window.zTreeMoveTimer) { + clearTimeout(window.zTreeMoveTimer); + window.zTreeMoveTargetNodeTId = null; + } + preTmpTargetNodeId = null; + preTmpMoveType = null; + doc.unbind("mousemove", _docMouseMove); + doc.unbind("mouseup", _docMouseUp); + doc.unbind("selectstart", _docSelect); + body.css("cursor", "auto"); + if (tmpTarget) { + tmpTarget.removeClass(consts.node.TMPTARGET_TREE); + if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV) + .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER); + } + tools.showIfameMask(setting, false); + + roots.showHoverDom = true; + if (root.dragFlag == 0) return; + root.dragFlag = 0; + + var i, l, tmpNode; + for (i=0, l=nodes.length; i<l; i++) { + tmpNode = nodes[i]; + if (tmpNode.isParent && root.dragNodeShowBefore[tmpNode.tId] && !tmpNode.open) { + view.expandCollapseNode(setting, tmpNode, !tmpNode.open); + delete root.dragNodeShowBefore[tmpNode.tId]; + } + } + + if (curNode) curNode.remove(); + if (tmpArrow) tmpArrow.remove(); + + var isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy); + if (!isCopy && tmpTarget && tmpTargetNodeId && nodes[0].parentTId && tmpTargetNodeId==nodes[0].parentTId && moveType == consts.move.TYPE_INNER) { + tmpTarget = null; + } + if (tmpTarget) { + var dragTargetNode = tmpTargetNodeId == null ? null: data.getNodeCache(targetSetting, tmpTargetNodeId); + if (tools.apply(setting.callback.beforeDrop, [targetSetting.treeId, nodes, dragTargetNode, moveType, isCopy], true) == false) { + view.selectNodes(sourceSetting, nodes); + return; + } + var newNodes = isCopy ? tools.clone(nodes) : nodes; + + function dropCallback() { + if (isOtherTree) { + if (!isCopy) { + for(var i=0, l=nodes.length; i<l; i++) { + view.removeNode(setting, nodes[i]); + } + } + if (moveType == consts.move.TYPE_INNER) { + view.addNodes(targetSetting, dragTargetNode, -1, newNodes); + } else { + view.addNodes(targetSetting, dragTargetNode.getParentNode(), moveType == consts.move.TYPE_PREV ? dragTargetNode.getIndex() : dragTargetNode.getIndex()+1, newNodes); + } + } else { + if (isCopy && moveType == consts.move.TYPE_INNER) { + view.addNodes(targetSetting, dragTargetNode, -1, newNodes); + } else if (isCopy) { + view.addNodes(targetSetting, dragTargetNode.getParentNode(), moveType == consts.move.TYPE_PREV ? dragTargetNode.getIndex() : dragTargetNode.getIndex()+1, newNodes); + } else { + if (moveType != consts.move.TYPE_NEXT) { + for (i=0, l=newNodes.length; i<l; i++) { + view.moveNode(targetSetting, dragTargetNode, newNodes[i], moveType, false); + } + } else { + for (i=-1, l=newNodes.length-1; i<l; l--) { + view.moveNode(targetSetting, dragTargetNode, newNodes[l], moveType, false); + } + } + } + } + view.selectNodes(targetSetting, newNodes); + + var a = $$(newNodes[0], setting).get(0); + view.scrollIntoView(a); + + setting.treeObj.trigger(consts.event.DROP, [event, targetSetting.treeId, newNodes, dragTargetNode, moveType, isCopy]); + } + + if (moveType == consts.move.TYPE_INNER && tools.canAsync(targetSetting, dragTargetNode)) { + view.asyncNode(targetSetting, dragTargetNode, false, dropCallback); + } else { + dropCallback(); + } + + } else { + view.selectNodes(sourceSetting, nodes); + setting.treeObj.trigger(consts.event.DROP, [event, setting.treeId, nodes, null, null, null]); + } + } + + doc.bind("selectstart", _docSelect); + function _docSelect() { + return false; + } + + //Avoid FireFox's Bug + //If zTree Div CSS set 'overflow', so drag node outside of zTree, and event.target is error. + if(eventMouseDown.preventDefault) { + eventMouseDown.preventDefault(); + } + return true; + } + }, + //method of tools for zTree + _tools = { + getAbs: function (obj) { + var oRect = obj.getBoundingClientRect(), + scrollTop = document.body.scrollTop+document.documentElement.scrollTop, + scrollLeft = document.body.scrollLeft+document.documentElement.scrollLeft; + return [oRect.left+scrollLeft,oRect.top+scrollTop]; + }, + inputFocus: function(inputObj) { + if (inputObj.get(0)) { + inputObj.focus(); + tools.setCursorPosition(inputObj.get(0), inputObj.val().length); + } + }, + inputSelect: function(inputObj) { + if (inputObj.get(0)) { + inputObj.focus(); + inputObj.select(); + } + }, + setCursorPosition: function(obj, pos){ + if(obj.setSelectionRange) { + obj.focus(); + obj.setSelectionRange(pos,pos); + } else if (obj.createTextRange) { + var range = obj.createTextRange(); + range.collapse(true); + range.moveEnd('character', pos); + range.moveStart('character', pos); + range.select(); + } + }, + showIfameMask: function(setting, showSign) { + var root = data.getRoot(setting); + //clear full mask + while (root.dragMaskList.length > 0) { + root.dragMaskList[0].remove(); + root.dragMaskList.shift(); + } + if (showSign) { + //show mask + var iframeList = $$("iframe", setting); + for (var i = 0, l = iframeList.length; i < l; i++) { + var obj = iframeList.get(i), + r = tools.getAbs(obj), + dragMask = $$("<div id='zTreeMask_" + i + "' class='zTreeMask' style='top:" + r[1] + "px; left:" + r[0] + "px; width:" + obj.offsetWidth + "px; height:" + obj.offsetHeight + "px;'></div>", setting); + dragMask.appendTo($$("body", setting)); + root.dragMaskList.push(dragMask); + } + } + } + }, + //method of operate ztree dom + _view = { + addEditBtn: function(setting, node) { + if (node.editNameFlag || $$(node, consts.id.EDIT, setting).length > 0) { + return; + } + if (!tools.apply(setting.edit.showRenameBtn, [setting.treeId, node], setting.edit.showRenameBtn)) { + return; + } + var aObj = $$(node, consts.id.A, setting), + editStr = "<span class='" + consts.className.BUTTON + " edit' id='" + node.tId + consts.id.EDIT + "' title='"+tools.apply(setting.edit.renameTitle, [setting.treeId, node], setting.edit.renameTitle)+"' treeNode"+consts.id.EDIT+" style='display:none;'></span>"; + aObj.append(editStr); + + $$(node, consts.id.EDIT, setting).bind('click', + function() { + if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeEditName, [setting.treeId, node], true) == false) return false; + view.editNode(setting, node); + return false; + } + ).show(); + }, + addRemoveBtn: function(setting, node) { + if (node.editNameFlag || $$(node, consts.id.REMOVE, setting).length > 0) { + return; + } + if (!tools.apply(setting.edit.showRemoveBtn, [setting.treeId, node], setting.edit.showRemoveBtn)) { + return; + } + var aObj = $$(node, consts.id.A, setting), + removeStr = "<span class='" + consts.className.BUTTON + " remove' id='" + node.tId + consts.id.REMOVE + "' title='"+tools.apply(setting.edit.removeTitle, [setting.treeId, node], setting.edit.removeTitle)+"' treeNode"+consts.id.REMOVE+" style='display:none;'></span>"; + aObj.append(removeStr); + + $$(node, consts.id.REMOVE, setting).bind('click', + function() { + if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return false; + view.removeNode(setting, node); + setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]); + return false; + } + ).bind('mousedown', + function(eventMouseDown) { + return true; + } + ).show(); + }, + addHoverDom: function(setting, node) { + if (data.getRoots().showHoverDom) { + node.isHover = true; + if (setting.edit.enable) { + view.addEditBtn(setting, node); + view.addRemoveBtn(setting, node); + } + tools.apply(setting.view.addHoverDom, [setting.treeId, node]); + } + }, + cancelCurEditNode: function (setting, forceName, isCancel) { + var root = data.getRoot(setting), + nameKey = setting.data.key.name, + node = root.curEditNode; + + if (node) { + var inputObj = root.curEditInput, + newName = forceName ? forceName:(isCancel ? node[nameKey]: inputObj.val()); + if (tools.apply(setting.callback.beforeRename, [setting.treeId, node, newName, isCancel], true) === false) { + return false; + } + node[nameKey] = newName; + var aObj = $$(node, consts.id.A, setting); + aObj.removeClass(consts.node.CURSELECTED_EDIT); + inputObj.unbind(); + view.setNodeName(setting, node); + node.editNameFlag = false; + root.curEditNode = null; + root.curEditInput = null; + view.selectNode(setting, node, false); + setting.treeObj.trigger(consts.event.RENAME, [setting.treeId, node, isCancel]); + } + root.noSelection = true; + return true; + }, + editNode: function(setting, node) { + var root = data.getRoot(setting); + view.editNodeBlur = false; + if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) { + setTimeout(function() {tools.inputFocus(root.curEditInput);}, 0); + return; + } + var nameKey = setting.data.key.name; + node.editNameFlag = true; + view.removeTreeDom(setting, node); + view.cancelCurEditNode(setting); + view.selectNode(setting, node, false); + $$(node, consts.id.SPAN, setting).html("<input type=text class='rename' id='" + node.tId + consts.id.INPUT + "' treeNode" + consts.id.INPUT + " >"); + var inputObj = $$(node, consts.id.INPUT, setting); + inputObj.attr("value", node[nameKey]); + if (setting.edit.editNameSelectAll) { + tools.inputSelect(inputObj); + } else { + tools.inputFocus(inputObj); + } + + inputObj.bind('blur', function(event) { + if (!view.editNodeBlur) { + view.cancelCurEditNode(setting); + } + }).bind('keydown', function(event) { + if (event.keyCode=="13") { + view.editNodeBlur = true; + view.cancelCurEditNode(setting); + } else if (event.keyCode=="27") { + view.cancelCurEditNode(setting, null, true); + } + }).bind('click', function(event) { + return false; + }).bind('dblclick', function(event) { + return false; + }); + + $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED_EDIT); + root.curEditInput = inputObj; + root.noSelection = false; + root.curEditNode = node; + }, + moveNode: function(setting, targetNode, node, moveType, animateFlag, isSilent) { + var root = data.getRoot(setting), + childKey = setting.data.key.children; + if (targetNode == node) return; + if (setting.data.keep.leaf && targetNode && !targetNode.isParent && moveType == consts.move.TYPE_INNER) return; + var oldParentNode = (node.parentTId ? node.getParentNode(): root), + targetNodeIsRoot = (targetNode === null || targetNode == root); + if (targetNodeIsRoot && targetNode === null) targetNode = root; + if (targetNodeIsRoot) moveType = consts.move.TYPE_INNER; + var targetParentNode = (targetNode.parentTId ? targetNode.getParentNode() : root); + + if (moveType != consts.move.TYPE_PREV && moveType != consts.move.TYPE_NEXT) { + moveType = consts.move.TYPE_INNER; + } + + if (moveType == consts.move.TYPE_INNER) { + if (targetNodeIsRoot) { + //parentTId of root node is null + node.parentTId = null; + } else { + if (!targetNode.isParent) { + targetNode.isParent = true; + targetNode.open = !!targetNode.open; + view.setNodeLineIcos(setting, targetNode); + } + node.parentTId = targetNode.tId; + } + } + + //move node Dom + var targetObj, target_ulObj; + if (targetNodeIsRoot) { + targetObj = setting.treeObj; + target_ulObj = targetObj; + } else { + if (!isSilent && moveType == consts.move.TYPE_INNER) { + view.expandCollapseNode(setting, targetNode, true, false); + } else if (!isSilent) { + view.expandCollapseNode(setting, targetNode.getParentNode(), true, false); + } + targetObj = $$(targetNode, setting); + target_ulObj = $$(targetNode, consts.id.UL, setting); + if (!!targetObj.get(0) && !target_ulObj.get(0)) { + var ulstr = []; + view.makeUlHtml(setting, targetNode, ulstr, ''); + targetObj.append(ulstr.join('')); + } + target_ulObj = $$(targetNode, consts.id.UL, setting); + } + var nodeDom = $$(node, setting); + if (!nodeDom.get(0)) { + nodeDom = view.appendNodes(setting, node.level, [node], null, -1, false, true).join(''); + } else if (!targetObj.get(0)) { + nodeDom.remove(); + } + if (target_ulObj.get(0) && moveType == consts.move.TYPE_INNER) { + target_ulObj.append(nodeDom); + } else if (targetObj.get(0) && moveType == consts.move.TYPE_PREV) { + targetObj.before(nodeDom); + } else if (targetObj.get(0) && moveType == consts.move.TYPE_NEXT) { + targetObj.after(nodeDom); + } + + //repair the data after move + var i,l, + tmpSrcIndex = -1, + tmpTargetIndex = 0, + oldNeighbor = null, + newNeighbor = null, + oldLevel = node.level; + if (node.isFirstNode) { + tmpSrcIndex = 0; + if (oldParentNode[childKey].length > 1 ) { + oldNeighbor = oldParentNode[childKey][1]; + oldNeighbor.isFirstNode = true; + } + } else if (node.isLastNode) { + tmpSrcIndex = oldParentNode[childKey].length -1; + oldNeighbor = oldParentNode[childKey][tmpSrcIndex - 1]; + oldNeighbor.isLastNode = true; + } else { + for (i = 0, l = oldParentNode[childKey].length; i < l; i++) { + if (oldParentNode[childKey][i].tId == node.tId) { + tmpSrcIndex = i; + break; + } + } + } + if (tmpSrcIndex >= 0) { + oldParentNode[childKey].splice(tmpSrcIndex, 1); + } + if (moveType != consts.move.TYPE_INNER) { + for (i = 0, l = targetParentNode[childKey].length; i < l; i++) { + if (targetParentNode[childKey][i].tId == targetNode.tId) tmpTargetIndex = i; + } + } + if (moveType == consts.move.TYPE_INNER) { + if (!targetNode[childKey]) targetNode[childKey] = new Array(); + if (targetNode[childKey].length > 0) { + newNeighbor = targetNode[childKey][targetNode[childKey].length - 1]; + newNeighbor.isLastNode = false; + } + targetNode[childKey].splice(targetNode[childKey].length, 0, node); + node.isLastNode = true; + node.isFirstNode = (targetNode[childKey].length == 1); + } else if (targetNode.isFirstNode && moveType == consts.move.TYPE_PREV) { + targetParentNode[childKey].splice(tmpTargetIndex, 0, node); + newNeighbor = targetNode; + newNeighbor.isFirstNode = false; + node.parentTId = targetNode.parentTId; + node.isFirstNode = true; + node.isLastNode = false; + + } else if (targetNode.isLastNode && moveType == consts.move.TYPE_NEXT) { + targetParentNode[childKey].splice(tmpTargetIndex + 1, 0, node); + newNeighbor = targetNode; + newNeighbor.isLastNode = false; + node.parentTId = targetNode.parentTId; + node.isFirstNode = false; + node.isLastNode = true; + + } else { + if (moveType == consts.move.TYPE_PREV) { + targetParentNode[childKey].splice(tmpTargetIndex, 0, node); + } else { + targetParentNode[childKey].splice(tmpTargetIndex + 1, 0, node); + } + node.parentTId = targetNode.parentTId; + node.isFirstNode = false; + node.isLastNode = false; + } + data.fixPIdKeyValue(setting, node); + data.setSonNodeLevel(setting, node.getParentNode(), node); + + //repair node what been moved + view.setNodeLineIcos(setting, node); + view.repairNodeLevelClass(setting, node, oldLevel) + + //repair node's old parentNode dom + if (!setting.data.keep.parent && oldParentNode[childKey].length < 1) { + //old parentNode has no child nodes + oldParentNode.isParent = false; + oldParentNode.open = false; + var tmp_ulObj = $$(oldParentNode, consts.id.UL, setting), + tmp_switchObj = $$(oldParentNode, consts.id.SWITCH, setting), + tmp_icoObj = $$(oldParentNode, consts.id.ICON, setting); + view.replaceSwitchClass(oldParentNode, tmp_switchObj, consts.folder.DOCU); + view.replaceIcoClass(oldParentNode, tmp_icoObj, consts.folder.DOCU); + tmp_ulObj.css("display", "none"); + + } else if (oldNeighbor) { + //old neigbor node + view.setNodeLineIcos(setting, oldNeighbor); + } + + //new neigbor node + if (newNeighbor) { + view.setNodeLineIcos(setting, newNeighbor); + } + + //repair checkbox / radio + if (!!setting.check && setting.check.enable && view.repairChkClass) { + view.repairChkClass(setting, oldParentNode); + view.repairParentChkClassWithSelf(setting, oldParentNode); + if (oldParentNode != node.parent) + view.repairParentChkClassWithSelf(setting, node); + } + + //expand parents after move + if (!isSilent) { + view.expandCollapseParentNode(setting, node.getParentNode(), true, animateFlag); + } + }, + removeEditBtn: function(setting, node) { + $$(node, consts.id.EDIT, setting).unbind().remove(); + }, + removeRemoveBtn: function(setting, node) { + $$(node, consts.id.REMOVE, setting).unbind().remove(); + }, + removeTreeDom: function(setting, node) { + node.isHover = false; + view.removeEditBtn(setting, node); + view.removeRemoveBtn(setting, node); + tools.apply(setting.view.removeHoverDom, [setting.treeId, node]); + }, + repairNodeLevelClass: function(setting, node, oldLevel) { + if (oldLevel === node.level) return; + var liObj = $$(node, setting), + aObj = $$(node, consts.id.A, setting), + ulObj = $$(node, consts.id.UL, setting), + oldClass = consts.className.LEVEL + oldLevel, + newClass = consts.className.LEVEL + node.level; + liObj.removeClass(oldClass); + liObj.addClass(newClass); + aObj.removeClass(oldClass); + aObj.addClass(newClass); + ulObj.removeClass(oldClass); + ulObj.addClass(newClass); + }, + selectNodes : function(setting, nodes) { + for (var i=0, l=nodes.length; i<l; i++) { + view.selectNode(setting, nodes[i], i>0); + } + } + }, + + _z = { + tools: _tools, + view: _view, + event: _event, + data: _data + }; + $.extend(true, $.fn.zTree.consts, _consts); + $.extend(true, $.fn.zTree._z, _z); + + var zt = $.fn.zTree, + tools = zt._z.tools, + consts = zt.consts, + view = zt._z.view, + data = zt._z.data, + event = zt._z.event, + $$ = tools.$; + + data.exSetting(_setting); + data.addInitBind(_bindEvent); + data.addInitUnBind(_unbindEvent); + data.addInitCache(_initCache); + data.addInitNode(_initNode); + data.addInitProxy(_eventProxy); + data.addInitRoot(_initRoot); + data.addZTreeTools(_zTreeTools); + + var _cancelPreSelectedNode = view.cancelPreSelectedNode; + view.cancelPreSelectedNode = function (setting, node) { + var list = data.getRoot(setting).curSelectedList; + for (var i=0, j=list.length; i<j; i++) { + if (!node || node === list[i]) { + view.removeTreeDom(setting, list[i]); + if (node) break; + } + } + if (_cancelPreSelectedNode) _cancelPreSelectedNode.apply(view, arguments); + } + + var _createNodes = view.createNodes; + view.createNodes = function(setting, level, nodes, parentNode, index) { + if (_createNodes) { + _createNodes.apply(view, arguments); + } + if (!nodes) return; + if (view.repairParentChkClassWithSelf) { + view.repairParentChkClassWithSelf(setting, parentNode); + } + } + + var _makeNodeUrl = view.makeNodeUrl; + view.makeNodeUrl = function(setting, node) { + return setting.edit.enable ? null : (_makeNodeUrl.apply(view, arguments)); + } + + var _removeNode = view.removeNode; + view.removeNode = function(setting, node) { + var root = data.getRoot(setting); + if (root.curEditNode === node) root.curEditNode = null; + if (_removeNode) { + _removeNode.apply(view, arguments); + } + } + + var _selectNode = view.selectNode; + view.selectNode = function(setting, node, addFlag) { + var root = data.getRoot(setting); + if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) { + return false; + } + if (_selectNode) _selectNode.apply(view, arguments); + view.addHoverDom(setting, node); + return true; + } + + var _uCanDo = tools.uCanDo; + tools.uCanDo = function(setting, e) { + var root = data.getRoot(setting); + if (e && (tools.eqs(e.type, "mouseover") || tools.eqs(e.type, "mouseout") || tools.eqs(e.type, "mousedown") || tools.eqs(e.type, "mouseup"))) { + return true; + } + if (root.curEditNode) { + view.editNodeBlur = false; + root.curEditInput.focus(); + } + return (!root.curEditNode) && (_uCanDo ? _uCanDo.apply(view, arguments) : true); + } +})(jQuery); diff --git a/static/template/goods.xls b/static/template/goods.xls new file mode 100755 index 0000000..94a2d80 Binary files /dev/null and b/static/template/goods.xls differ diff --git a/static/template/goodsvirtuals.xls b/static/template/goodsvirtuals.xls new file mode 100755 index 0000000..f9565ca Binary files /dev/null and b/static/template/goodsvirtuals.xls differ diff --git a/thinkphp/.htaccess b/thinkphp/.htaccess new file mode 100755 index 0000000..ff251e2 --- /dev/null +++ b/thinkphp/.htaccess @@ -0,0 +1,4 @@ +<FilesMatch (.*)\.php$> +order allow,deny +deny from all +</FilesMatch> \ No newline at end of file diff --git a/thinkphp/LICENSE.txt b/thinkphp/LICENSE.txt new file mode 100755 index 0000000..574a39c --- /dev/null +++ b/thinkphp/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/thinkphp/README.md b/thinkphp/README.md new file mode 100755 index 0000000..ce364a1 --- /dev/null +++ b/thinkphp/README.md @@ -0,0 +1,114 @@ +ThinkPHP 5.0 +=============== + +[![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411) +[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework) +[![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master) +[![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework) +[![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework) +[![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework) +[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework) + +ThinkPHP5在保持快速开发和大道至简的核心理念不变的同时,PHP版本要求提升到5.4,优化核心,减少依赖,基于全新的架构思想和命名空间实现,是ThinkPHP突破原有框架思路的颠覆之作,其主要特性包括: + + + 基于命名空间和众多PHP新特性 + + 核心功能组件化 + + 强化路由功能 + + 更灵活的控制器 + + 重构的模型和数据库类 + + 配置文件可分离 + + 重写的自动验证和完成 + + 简化扩展机制 + + API支持完善 + + 改进的Log类 + + 命令行访问支持 + + REST支持 + + 引导文件支持 + + 方便的自动生成定义 + + 真正惰性加载 + + 分布式环境支持 + + 支持Composer + + 支持MongoDb + +> ThinkPHP5的运行环境要求PHP5.4以上。 + +详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart) + +## 目录结构 + +初始的目录结构如下: + +~~~ +www WEB部署目录(或者子目录) +├─application 应用目录 +│ ├─common 公共模块目录(可以更改) +│ ├─module_name 模块目录 +│ │ ├─config.php 模块配置文件 +│ │ ├─common.php 模块函数文件 +│ │ ├─controller 控制器目录 +│ │ ├─model 模型目录 +│ │ ├─view 视图目录 +│ │ └─ ... 更多类库目录 +│ │ +│ ├─command.php 命令行工具配置文件 +│ ├─common.php 公共函数文件 +│ ├─config.php 公共配置文件 +│ ├─route.php 路由配置文件 +│ ├─tags.php 应用行为扩展定义文件 +│ └─database.php 数据库配置文件 +│ +├─public WEB目录(对外访问目录) +│ ├─index.php 入口文件 +│ ├─router.php 快速测试文件 +│ └─.htaccess 用于apache的重写 +│ +├─thinkphp 框架系统目录 +│ ├─lang 语言文件目录 +│ ├─library 框架类库目录 +│ │ ├─think Think类库包目录 +│ │ └─traits 系统Trait目录 +│ │ +│ ├─tpl 系统模板目录 +│ ├─base.php 基础定义文件 +│ ├─console.php 控制台入口文件 +│ ├─convention.php 框架惯例配置文件 +│ ├─helper.php 助手函数文件 +│ ├─phpunit.xml phpunit配置文件 +│ └─start.php 框架入口文件 +│ +├─extend 扩展类库目录 +├─runtime 应用的运行时目录(可写,可定制) +├─vendor 第三方类库目录(Composer依赖库) +├─build.php 自动生成定义文件(参考) +├─composer.json composer 定义文件 +├─LICENSE.txt 授权说明文件 +├─README.md README 文件 +├─think 命令行入口文件 +~~~ + +> router.php用于php自带webserver支持,可用于快速测试 +> 切换到public目录后,启动命令:php -S localhost:8888 router.php +> 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。 + +## 命名规范 + +ThinkPHP5的命名规范遵循PSR-2规范以及PSR-4自动加载规范。 + +## 参与开发 +注册并登录 Github 帐号, fork 本项目并进行改动。 + +更多细节参阅 [CONTRIBUTING.md](CONTRIBUTING.md) + +## 版权信息 + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 + +本项目包含的第三方源码和二进制文件之版权信息另行标注。 + +版权所有Copyright © 2006-2017 by ThinkPHP (http://thinkphp.cn) + +All rights reserved。 + +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +更多细节参阅 [LICENSE.txt](LICENSE.txt) diff --git a/thinkphp/base.php b/thinkphp/base.php new file mode 100755 index 0000000..1819d72 --- /dev/null +++ b/thinkphp/base.php @@ -0,0 +1,63 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +define('THINK_VERSION', '5.0.12'); +define('THINK_START_TIME', microtime(true)); +define('THINK_START_MEM', memory_get_usage()); +define('EXT', '.php'); +define('DS', DIRECTORY_SEPARATOR); +defined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS); +define('LIB_PATH', THINK_PATH . 'library' . DS); +define('CORE_PATH', LIB_PATH . 'think' . DS); +define('TRAIT_PATH', LIB_PATH . 'traits' . DS); +defined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS); +defined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS); +defined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS); +defined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS); +defined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS); +defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS); +defined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS); +defined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS); +defined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录 +defined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀 +defined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀 + +// 环境常量 +define('IS_CLI', PHP_SAPI == 'cli' ? true : false); +define('IS_WIN', strpos(PHP_OS, 'WIN') !== false); + +// 载入Loader类 +require CORE_PATH . 'Loader.php'; + +// 加载环境变量配置文件 +if (is_file(ROOT_PATH . '.env')) { + $env = parse_ini_file(ROOT_PATH . '.env', true); + foreach ($env as $key => $val) { + $name = ENV_PREFIX . strtoupper($key); + if (is_array($val)) { + foreach ($val as $k => $v) { + $item = $name . '_' . strtoupper($k); + putenv("$item=$v"); + } + } else { + putenv("$name=$val"); + } + } +} + +// 注册自动加载 +\think\Loader::register(); + +// 注册错误和异常处理机制 +\think\Error::register(); + +// 加载惯例配置文件 +\think\Config::set(include THINK_PATH . 'convention' . EXT); diff --git a/thinkphp/convention.php b/thinkphp/convention.php new file mode 100755 index 0000000..4ca03c0 --- /dev/null +++ b/thinkphp/convention.php @@ -0,0 +1,289 @@ +<?php + +return [ + // +---------------------------------------------------------------------- + // | 应用设置 + // +---------------------------------------------------------------------- + // 默认Host地址 + 'app_host' => '', + // 应用调试模式 + 'app_debug' => false, + // 应用Trace + 'app_trace' => false, + // 应用模式状态 + 'app_status' => '', + // 是否支持多模块 + 'app_multi_module' => true, + // 入口自动绑定模块 + 'auto_bind_module' => false, + // 注册的根命名空间 + 'root_namespace' => [], + // 扩展函数文件 + 'extra_file_list' => [THINK_PATH . 'helper' . EXT], + // 默认输出类型 + 'default_return_type' => 'html', + // 默认AJAX 数据返回格式,可选json xml ... + 'default_ajax_return' => 'json', + // 默认JSONP格式返回的处理方法 + 'default_jsonp_handler' => 'jsonpReturn', + // 默认JSONP处理方法 + 'var_jsonp_handler' => 'callback', + // 默认时区 + 'default_timezone' => 'PRC', + // 是否开启多语言 + 'lang_switch_on' => false, + // 默认全局过滤方法 用逗号分隔多个 + 'default_filter' => '', + // 默认语言 + 'default_lang' => 'zh-cn', + // 应用类库后缀 + 'class_suffix' => false, + // 控制器类后缀 + 'controller_suffix' => false, + + // +---------------------------------------------------------------------- + // | 模块设置 + // +---------------------------------------------------------------------- + + // 默认模块名 + 'default_module' => 'index', + // 禁止访问模块 + 'deny_module_list' => ['common'], + // 默认控制器名 + 'default_controller' => 'Index', + // 默认操作名 + 'default_action' => 'index', + // 默认验证器 + 'default_validate' => '', + // 默认的空控制器名 + 'empty_controller' => 'Error', + // 操作方法前缀 + 'use_action_prefix' => false, + // 操作方法后缀 + 'action_suffix' => '', + // 自动搜索控制器 + 'controller_auto_search' => false, + + // +---------------------------------------------------------------------- + // | URL设置 + // +---------------------------------------------------------------------- + + // PATHINFO变量名 用于兼容模式 + 'var_pathinfo' => 's', + // 兼容PATH_INFO获取 + 'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'], + // pathinfo分隔符 + 'pathinfo_depr' => '/', + // HTTPS代理标识 + 'https_agent_name' => '', + // URL伪静态后缀 + 'url_html_suffix' => 'html', + // URL普通方式参数 用于自动生成 + 'url_common_param' => false, + // URL参数方式 0 按名称成对解析 1 按顺序解析 + 'url_param_type' => 0, + // 是否开启路由 + 'url_route_on' => true, + // 路由配置文件(支持配置多个) + 'route_config_file' => ['route'], + // 路由使用完整匹配 + 'route_complete_match' => false, + // 是否强制使用路由 + 'url_route_must' => false, + // 域名部署 + 'url_domain_deploy' => false, + // 域名根,如thinkphp.cn + 'url_domain_root' => '', + // 是否自动转换URL中的控制器和操作名 + 'url_convert' => true, + // 默认的访问控制器层 + 'url_controller_layer' => 'controller', + // 表单请求类型伪装变量 + 'var_method' => '_method', + // 表单ajax伪装变量 + 'var_ajax' => '_ajax', + // 表单pjax伪装变量 + 'var_pjax' => '_pjax', + // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则 + 'request_cache' => false, + // 请求缓存有效期 + 'request_cache_expire' => null, + // 全局请求缓存排除规则 + 'request_cache_except' => [], + + // +---------------------------------------------------------------------- + // | 模板设置 + // +---------------------------------------------------------------------- + + 'template' => [ + // 模板引擎类型 支持 php think 支持扩展 + 'type' => 'Think', + // 视图基础目录,配置目录为所有模块的视图起始目录 + 'view_base' => '', + // 当前模板的视图目录 留空为自动获取 + 'view_path' => '', + // 模板后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DS, + // 模板引擎普通标签开始标记 + 'tpl_begin' => '{', + // 模板引擎普通标签结束标记 + 'tpl_end' => '}', + // 标签库标签开始标记 + 'taglib_begin' => '{', + // 标签库标签结束标记 + 'taglib_end' => '}', + ], + + // 视图输出字符串内容替换 + 'view_replace_str' => [], + // 默认跳转页面对应的模板文件 + 'dispatch_success_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + 'dispatch_error_tmpl' => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl', + + // +---------------------------------------------------------------------- + // | 异常及错误设置 + // +---------------------------------------------------------------------- + + // 异常页面的模板文件 + 'exception_tmpl' => THINK_PATH . 'tpl' . DS . 'think_exception.tpl', + + // 错误显示信息,非调试模式有效 + 'error_message' => '页面错误!请稍后再试~', + // 显示错误信息 + 'show_error_msg' => false, + // 异常处理handle类 留空使用 \think\exception\Handle + 'exception_handle' => '', + // 是否记录trace信息到日志 + 'record_trace' => false, + + // +---------------------------------------------------------------------- + // | 日志设置 + // +---------------------------------------------------------------------- + + 'log' => [ + // 日志记录方式,内置 file socket 支持扩展 + 'type' => 'File', + // 日志保存目录 + 'path' => LOG_PATH, + // 日志记录级别 + 'level' => [], + ], + + // +---------------------------------------------------------------------- + // | Trace设置 开启 app_trace 后 有效 + // +---------------------------------------------------------------------- + 'trace' => [ + // 内置Html Console 支持扩展 + 'type' => 'Html', + ], + + // +---------------------------------------------------------------------- + // | 缓存设置 + // +---------------------------------------------------------------------- + + 'cache' => [ + // 驱动方式 + 'type' => 'File', + // 缓存保存目录 + 'path' => CACHE_PATH, + // 缓存前缀 + 'prefix' => '', + // 缓存有效期 0表示永久缓存 + 'expire' => 0, + ], + + // +---------------------------------------------------------------------- + // | 会话设置 + // +---------------------------------------------------------------------- + + 'session' => [ + 'id' => '', + // SESSION_ID的提交变量,解决flash上传跨域 + 'var_session_id' => '', + // SESSION 前缀 + 'prefix' => 'think', + // 驱动方式 支持redis memcache memcached + 'type' => '', + // 是否自动开启 SESSION + 'auto_start' => true, + 'httponly' => true, + 'secure' => false, + ], + + // +---------------------------------------------------------------------- + // | Cookie设置 + // +---------------------------------------------------------------------- + 'cookie' => [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ], + + // +---------------------------------------------------------------------- + // | 数据库设置 + // +---------------------------------------------------------------------- + + 'database' => [ + // 数据库类型 + 'type' => 'mysql', + // 数据库连接DSN配置 + 'dsn' => '', + // 服务器地址 + 'hostname' => '127.0.0.1', + // 数据库名 + 'database' => '', + // 数据库用户名 + 'username' => 'root', + // 数据库密码 + 'password' => '', + // 数据库连接端口 + 'hostport' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 数据库调试模式 + 'debug' => false, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 数据集返回类型 + 'resultset_type' => 'array', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + ], + + //分页配置 + 'paginate' => [ + 'type' => 'bootstrap', + 'var_page' => 'page', + 'list_rows' => 15, + ], + +]; diff --git a/thinkphp/helper.php b/thinkphp/helper.php new file mode 100755 index 0000000..b6320b2 --- /dev/null +++ b/thinkphp/helper.php @@ -0,0 +1,589 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +//------------------------ +// ThinkPHP 助手函数 +//------------------------- + +use think\Cache; +use think\Config; +use think\Cookie; +use think\Db; +use think\Debug; +use think\exception\HttpException; +use think\exception\HttpResponseException; +use think\Lang; +use think\Loader; +use think\Log; +use think\Model; +use think\Request; +use think\Response; +use think\Session; +use think\Url; +use think\View; + +if (!function_exists('load_trait')) { + /** + * 快速导入Traits PHP5.5以上无需调用 + * @param string $class trait库 + * @param string $ext 类库后缀 + * @return boolean + */ + function load_trait($class, $ext = EXT) + { + return Loader::import($class, TRAIT_PATH, $ext); + } +} + +if (!function_exists('exception')) { + /** + * 抛出异常处理 + * + * @param string $msg 异常消息 + * @param integer $code 异常代码 默认为0 + * @param string $exception 异常类 + * + * @throws Exception + */ + function exception($msg, $code = 0, $exception = '') + { + $e = $exception ?: '\think\Exception'; + throw new $e($msg, $code); + } +} + +if (!function_exists('debug')) { + /** + * 记录时间(微秒)和内存使用情况 + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位 如果是m 表示统计内存占用 + * @return mixed + */ + function debug($start, $end = '', $dec = 6) + { + if ('' == $end) { + Debug::remark($start); + } else { + return 'm' == $dec ? Debug::getRangeMem($start, $end) : Debug::getRangeTime($start, $end, $dec); + } + } +} + +if (!function_exists('lang')) { + /** + * 获取语言变量值 + * @param string $name 语言变量名 + * @param array $vars 动态变量值 + * @param string $lang 语言 + * @return mixed + */ + function lang($name, $vars = [], $lang = '') + { + return Lang::get($name, $vars, $lang); + } +} + +if (!function_exists('config')) { + /** + * 获取和设置配置参数 + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @param string $range 作用域 + * @return mixed + */ + function config($name = '', $value = null, $range = '') + { + if (is_null($value) && is_string($name)) { + return 0 === strpos($name, '?') ? Config::has(substr($name, 1), $range) : Config::get($name, $range); + } else { + return Config::set($name, $value, $range); + } + } +} + +if (!function_exists('input')) { + /** + * 获取输入数据 支持默认值和过滤 + * @param string $key 获取的变量名 + * @param mixed $default 默认值 + * @param string $filter 过滤方法 + * @return mixed + */ + function input($key = '', $default = null, $filter = '') + { + if (0 === strpos($key, '?')) { + $key = substr($key, 1); + $has = true; + } + if ($pos = strpos($key, '.')) { + // 指定参数来源 + list($method, $key) = explode('.', $key, 2); + if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'route', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) { + $key = $method . '.' . $key; + $method = 'param'; + } + } else { + // 默认为自动判断 + $method = 'param'; + } + if (isset($has)) { + return request()->has($key, $method, $default); + } else { + return request()->$method($key, $default, $filter); + } + } +} + +if (!function_exists('widget')) { + /** + * 渲染输出Widget + * @param string $name Widget名称 + * @param array $data 传入的参数 + * @return mixed + */ + function widget($name, $data = []) + { + return Loader::action($name, $data, 'widget'); + } +} + +if (!function_exists('model')) { + /** + * 实例化Model + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Model + */ + function model($name = '', $layer = 'model', $appendSuffix = false) + { + return Loader::model($name, $layer, $appendSuffix); + } +} + +if (!function_exists('validate')) { + /** + * 实例化验证器 + * @param string $name 验证器名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Validate + */ + function validate($name = '', $layer = 'validate', $appendSuffix = false) + { + return Loader::validate($name, $layer, $appendSuffix); + } +} + +if (!function_exists('db')) { + /** + * 实例化数据库类 + * @param string $name 操作的数据表名称(不含前缀) + * @param array|string $config 数据库配置参数 + * @param bool $force 是否强制重新连接 + * @return \think\db\Query + */ + function db($name = '', $config = [], $force = false) + { + return Db::connect($config, $force)->name($name); + } +} + +if (!function_exists('controller')) { + /** + * 实例化控制器 格式:[模块/]控制器 + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return \think\Controller + */ + function controller($name, $layer = 'controller', $appendSuffix = false) + { + return Loader::controller($name, $layer, $appendSuffix); + } +} + +if (!function_exists('action')) { + /** + * 调用模块的操作方法 参数格式 [模块/控制器/]操作 + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return mixed + */ + function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) + { + return Loader::action($url, $vars, $layer, $appendSuffix); + } +} + +if (!function_exists('import')) { + /** + * 导入所需的类库 同java的Import 本函数有缓存功能 + * @param string $class 类库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 + * @return boolean + */ + function import($class, $baseUrl = '', $ext = EXT) + { + return Loader::import($class, $baseUrl, $ext); + } +} + +if (!function_exists('vendor')) { + /** + * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面 + * @param string $class 类库 + * @param string $ext 类库后缀 + * @return boolean + */ + function vendor($class, $ext = EXT) + { + return Loader::import($class, VENDOR_PATH, $ext); + } +} + +if (!function_exists('dump')) { + /** + * 浏览器友好的变量输出 + * @param mixed $var 变量 + * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 + * @param string $label 标签 默认为空 + * @return void|string + */ + function dump($var, $echo = true, $label = null) + { + return Debug::dump($var, $echo, $label); + } +} + +if (!function_exists('url')) { + /** + * Url生成 + * @param string $url 路由地址 + * @param string|array $vars 变量 + * @param bool|string $suffix 生成的URL后缀 + * @param bool|string $domain 域名 + * @return string + */ + function url($url = '', $vars = '', $suffix = true, $domain = false) + { + return Url::build($url, $vars, $suffix, $domain); + } +} + +if (!function_exists('session')) { + /** + * Session管理 + * @param string|array $name session名称,如果为数组表示进行session设置 + * @param mixed $value session值 + * @param string $prefix 前缀 + * @return mixed + */ + function session($name, $value = '', $prefix = null) + { + if (is_array($name)) { + // 初始化 + Session::init($name); + } elseif (is_null($name)) { + // 清除 + Session::clear('' === $value ? null : $value); + } elseif ('' === $value) { + // 判断或获取 + return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix); + } elseif (is_null($value)) { + // 删除 + return Session::delete($name, $prefix); + } else { + // 设置 + return Session::set($name, $value, $prefix); + } + } +} + +if (!function_exists('cookie')) { + /** + * Cookie管理 + * @param string|array $name cookie名称,如果为数组表示进行cookie设置 + * @param mixed $value cookie值 + * @param mixed $option 参数 + * @return mixed + */ + function cookie($name, $value = '', $option = null) + { + if (is_array($name)) { + // 初始化 + Cookie::init($name); + } elseif (is_null($name)) { + // 清除 + Cookie::clear($value); + } elseif ('' === $value) { + // 获取 + return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1), $option) : Cookie::get($name, $option); + } elseif (is_null($value)) { + // 删除 + return Cookie::delete($name); + } else { + // 设置 + return Cookie::set($name, $value, $option); + } + } +} + +if (!function_exists('cache')) { + /** + * 缓存管理 + * @param mixed $name 缓存名称,如果为数组表示进行缓存设置 + * @param mixed $value 缓存值 + * @param mixed $options 缓存参数 + * @param string $tag 缓存标签 + * @return mixed + */ + function cache($name, $value = '', $options = null, $tag = null) + { + if (is_array($options)) { + // 缓存操作的同时初始化 + $cache = Cache::connect($options); + } elseif (is_array($name)) { + // 缓存初始化 + return Cache::connect($name); + } else { + $cache = Cache::init(); + } + + if (is_null($name)) { + return $cache->clear($value); + } elseif ('' === $value) { + // 获取缓存 + return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name); + } elseif (is_null($value)) { + // 删除缓存 + return $cache->rm($name); + } elseif (0 === strpos($name, '?') && '' !== $value) { + $expire = is_numeric($options) ? $options : null; + return $cache->remember(substr($name, 1), $value, $expire); + } else { + // 缓存数据 + if (is_array($options)) { + $expire = isset($options['expire']) ? $options['expire'] : null; //修复查询缓存无法设置过期时间 + } else { + $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间 + } + if (is_null($tag)) { + return $cache->set($name, $value, $expire); + } else { + return $cache->tag($tag)->set($name, $value, $expire); + } + } + } +} + +if (!function_exists('trace')) { + /** + * 记录日志信息 + * @param mixed $log log信息 支持字符串和数组 + * @param string $level 日志级别 + * @return void|array + */ + function trace($log = '[think]', $level = 'log') + { + if ('[think]' === $log) { + return Log::getLog(); + } else { + Log::record($log, $level); + } + } +} + +if (!function_exists('request')) { + /** + * 获取当前Request对象实例 + * @return Request + */ + function request() + { + return Request::instance(); + } +} + +if (!function_exists('response')) { + /** + * 创建普通 Response 对象实例 + * @param mixed $data 输出数据 + * @param int|string $code 状态码 + * @param array $header 头信息 + * @param string $type + * @return Response + */ + function response($data = [], $code = 200, $header = [], $type = 'html') + { + return Response::create($data, $type, $code, $header); + } +} + +if (!function_exists('view')) { + /** + * 渲染模板输出 + * @param string $template 模板文件 + * @param array $vars 模板变量 + * @param array $replace 模板替换 + * @param integer $code 状态码 + * @return \think\response\View + */ + function view($template = '', $vars = [], $replace = [], $code = 200) + { + return Response::create($template, 'view', $code)->replace($replace)->assign($vars); + } +} + +if (!function_exists('json')) { + /** + * 获取\think\response\Json对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Json + */ + function json($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'json', $code, $header, $options); + } +} + +if (!function_exists('jsonp')) { + /** + * 获取\think\response\Jsonp对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Jsonp + */ + function jsonp($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'jsonp', $code, $header, $options); + } +} + +if (!function_exists('xml')) { + /** + * 获取\think\response\Xml对象实例 + * @param mixed $data 返回的数据 + * @param integer $code 状态码 + * @param array $header 头部 + * @param array $options 参数 + * @return \think\response\Xml + */ + function xml($data = [], $code = 200, $header = [], $options = []) + { + return Response::create($data, 'xml', $code, $header, $options); + } +} + +if (!function_exists('redirect')) { + /** + * 获取\think\response\Redirect对象实例 + * @param mixed $url 重定向地址 支持Url::build方法的地址 + * @param array|integer $params 额外参数 + * @param integer $code 状态码 + * @param array $with 隐式传参 + * @return \think\response\Redirect + */ + function redirect($url = [], $params = [], $code = 302, $with = []) + { + if (is_integer($params)) { + $code = $params; + $params = []; + } + return Response::create($url, 'redirect', $code)->params($params)->with($with); + } +} + +if (!function_exists('abort')) { + /** + * 抛出HTTP异常 + * @param integer|Response $code 状态码 或者 Response对象实例 + * @param string $message 错误信息 + * @param array $header 参数 + */ + function abort($code, $message = null, $header = []) + { + if ($code instanceof Response) { + throw new HttpResponseException($code); + } else { + throw new HttpException($code, $message, null, $header); + } + } +} + +if (!function_exists('halt')) { + /** + * 调试变量并且中断输出 + * @param mixed $var 调试变量或者信息 + */ + function halt($var) + { + dump($var); + throw new HttpResponseException(new Response); + } +} + +if (!function_exists('token')) { + /** + * 生成表单令牌 + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + function token($name = '__token__', $type = 'md5') + { + $token = Request::instance()->token($name, $type); + return '<input type="hidden" name="' . $name . '" value="' . $token . '" />'; + } +} + +if (!function_exists('load_relation')) { + /** + * 延迟预载入关联查询 + * @param mixed $resultSet 数据集 + * @param mixed $relation 关联 + * @return array + */ + function load_relation($resultSet, $relation) + { + $item = current($resultSet); + if ($item instanceof Model) { + $item->eagerlyResultSet($resultSet, $relation); + } + return $resultSet; + } +} + +if (!function_exists('collection')) { + /** + * 数组转换为数据集对象 + * @param array $resultSet 数据集数组 + * @return \think\model\Collection|\think\Collection + */ + function collection($resultSet) + { + $item = current($resultSet); + if ($item instanceof Model) { + return \think\model\Collection::make($resultSet); + } else { + return \think\Collection::make($resultSet); + } + } +} diff --git a/thinkphp/lang/zh-cn.php b/thinkphp/lang/zh-cn.php new file mode 100755 index 0000000..ac2007a --- /dev/null +++ b/thinkphp/lang/zh-cn.php @@ -0,0 +1,134 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +// 核心中文语言包 +return [ + // 系统错误提示 + 'Undefined variable' => '未定义变量', + 'Undefined index' => '未定义数组索引', + 'Undefined offset' => '未定义数组下标', + 'Parse error' => '语法解析错误', + 'Type error' => '类型错误', + 'Fatal error' => '致命错误', + 'syntax error' => '语法错误', + + // 框架核心错误提示 + 'dispatch type not support' => '不支持的调度类型', + 'method param miss' => '方法参数错误', + 'method not exists' => '方法不存在', + 'module not exists' => '模块不存在', + 'controller not exists' => '控制器不存在', + 'class not exists' => '类不存在', + 'property not exists' => '类的属性不存在', + 'template not exists' => '模板文件不存在', + 'illegal controller name' => '非法的控制器名称', + 'illegal action name' => '非法的操作名称', + 'url suffix deny' => '禁止的URL后缀访问', + 'Route Not Found' => '当前访问路由未定义', + 'Undefined db type' => '未定义数据库类型', + 'variable type error' => '变量类型错误', + 'PSR-4 error' => 'PSR-4 规范错误', + 'not support total' => '简洁模式下不能获取数据总数', + 'not support last' => '简洁模式下不能获取最后一页', + 'error session handler' => '错误的SESSION处理器类', + 'not allow php tag' => '模板不允许使用PHP语法', + 'not support' => '不支持', + 'redisd master' => 'Redisd 主服务器错误', + 'redisd slave' => 'Redisd 从服务器错误', + 'must run at sae' => '必须在SAE运行', + 'memcache init error' => '未开通Memcache服务,请在SAE管理平台初始化Memcache服务', + 'KVDB init error' => '没有初始化KVDB,请在SAE管理平台初始化KVDB服务', + 'fields not exists' => '数据表字段不存在', + 'where express error' => '查询表达式错误', + 'no data to update' => '没有任何数据需要更新', + 'miss data to insert' => '缺少需要写入的数据', + 'miss complex primary data' => '缺少复合主键数据', + 'miss update condition' => '缺少更新条件', + 'model data Not Found' => '模型数据不存在', + 'table data not Found' => '表数据不存在', + 'delete without condition' => '没有条件不会执行删除操作', + 'miss relation data' => '缺少关联表数据', + 'tag attr must' => '模板标签属性必须', + 'tag error' => '模板标签错误', + 'cache write error' => '缓存写入失败', + 'sae mc write error' => 'SAE mc 写入错误', + 'route name not exists' => '路由标识不存在(或参数不够)', + 'invalid request' => '非法请求', + 'bind attr has exists' => '模型的属性已经存在', + 'relation data not exists' => '关联数据不存在', + 'relation not support' => '关联不支持', + 'chunk not support order' => 'Chunk不支持调用order方法', + + // 上传错误信息 + 'unknown upload error' => '未知上传错误!', + 'file write error' => '文件写入失败!', + 'upload temp dir not found' => '找不到临时文件夹!', + 'no file to uploaded' => '没有文件被上传!', + 'only the portion of file is uploaded' => '文件只有部分被上传!', + 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', + 'upload write error' => '文件上传保存错误!', + 'has the same filename: {:filename}' => '存在同名文件:{:filename}', + 'upload illegal files' => '非法上传文件', + 'illegal image files' => '非法图片文件', + 'extensions to upload is not allowed' => '上传文件后缀不允许', + 'mimetype to upload is not allowed' => '上传文件MIME类型不允许!', + 'filesize not match' => '上传文件大小不符!', + 'directory {:path} creation failed' => '目录 {:path} 创建失败!', + + // Validate Error Message + ':attribute require' => ':attribute不能为空', + ':attribute must be numeric' => ':attribute必须是数字', + ':attribute must be integer' => ':attribute必须是整数', + ':attribute must be float' => ':attribute必须是浮点数', + ':attribute must be bool' => ':attribute必须是布尔值', + ':attribute not a valid email address' => ':attribute格式不符', + ':attribute not a valid mobile' => ':attribute格式不符', + ':attribute must be a array' => ':attribute必须是数组', + ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1', + ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式', + ':attribute not a valid file' => ':attribute不是有效的上传文件', + ':attribute not a valid image' => ':attribute不是有效的图像文件', + ':attribute must be alpha' => ':attribute只能是字母', + ':attribute must be alpha-numeric' => ':attribute只能是字母和数字', + ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-', + ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP', + ':attribute must be chinese' => ':attribute只能是汉字', + ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母', + ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字', + ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-', + ':attribute not a valid url' => ':attribute不是有效的URL地址', + ':attribute not a valid ip' => ':attribute不是有效的IP地址', + ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule', + ':attribute must be in :rule' => ':attribute必须在 :rule 范围内', + ':attribute be notin :rule' => ':attribute不能在 :rule 范围内', + ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间', + ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间', + 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule', + 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule', + 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule', + ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule', + ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule', + ':attribute not within :rule' => '不在有效期内 :rule', + 'access IP is not allowed' => '不允许的IP访问', + 'access IP denied' => '禁止的IP访问', + ':attribute out of accord with :2' => ':attribute和确认字段:2不一致', + ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同', + ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule', + ':attribute must greater than :rule' => ':attribute必须大于 :rule', + ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule', + ':attribute must less than :rule' => ':attribute必须小于 :rule', + ':attribute must equal :rule' => ':attribute必须等于 :rule', + ':attribute has exists' => ':attribute已存在', + ':attribute not conform to the rules' => ':attribute不符合指定规则', + 'invalid Request method' => '无效的请求类型', + 'invalid token' => '令牌数据无效', + 'not conform to the rules' => '规则错误', +]; diff --git a/thinkphp/library/think/App.php b/thinkphp/library/think/App.php new file mode 100755 index 0000000..51f3f67 --- /dev/null +++ b/thinkphp/library/think/App.php @@ -0,0 +1,594 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; +use think\exception\HttpException; +use think\exception\HttpResponseException; +use think\exception\RouteNotFoundException; + +/** + * App 应用管理 + * @author liu21st <liu21st@gmail.com> + */ +class App +{ + /** + * @var bool 是否初始化过 + */ + protected static $init = false; + + /** + * @var string 当前模块路径 + */ + public static $modulePath; + + /** + * @var bool 应用调试模式 + */ + public static $debug = true; + + /** + * @var string 应用类库命名空间 + */ + public static $namespace = 'app'; + + /** + * @var bool 应用类库后缀 + */ + public static $suffix = false; + + /** + * @var bool 应用路由检测 + */ + protected static $routeCheck; + + /** + * @var bool 严格路由检测 + */ + protected static $routeMust; + + protected static $dispatch; + protected static $file = []; + + /** + * 执行应用程序 + * @access public + * @param Request $request Request对象 + * @return Response + * @throws Exception + */ + public static function run(Request $request = null) + { + is_null($request) && $request = Request::instance(); + + try { + $config = self::initCommon(); + if (defined('BIND_MODULE')) { + // 模块/控制器绑定 + BIND_MODULE && Route::bind(BIND_MODULE); + } elseif ($config['auto_bind_module']) { + // 入口自动绑定 + $name = pathinfo($request->baseFile(), PATHINFO_FILENAME); + if ($name && 'index' != $name && is_dir(APP_PATH . $name)) { + Route::bind($name); + } + } + + $request->filter($config['default_filter']); + + // 默认语言 + Lang::range($config['default_lang']); + if ($config['lang_switch_on']) { + // 开启多语言机制 检测当前语言 + Lang::detect(); + } + $request->langset(Lang::range()); + + // 加载系统语言包 + Lang::load([ + THINK_PATH . 'lang' . DS . $request->langset() . EXT, + APP_PATH . 'lang' . DS . $request->langset() . EXT, + ]); + + // 获取应用调度信息 + $dispatch = self::$dispatch; + if (empty($dispatch)) { + // 进行URL路由检测 + $dispatch = self::routeCheck($request, $config); + } + // 记录当前调度信息 + $request->dispatch($dispatch); + + // 记录路由和请求信息 + if (self::$debug) { + Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info'); + Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info'); + Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info'); + } + + // 监听app_begin + Hook::listen('app_begin', $dispatch); + // 请求缓存检查 + $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); + + $data = self::exec($dispatch, $config); + } catch (HttpResponseException $exception) { + $data = $exception->getResponse(); + } + + // 清空类的实例化 + Loader::clearInstance(); + + // 输出数据到客户端 + if ($data instanceof Response) { + $response = $data; + } elseif (!is_null($data)) { + // 默认自动识别响应输出类型 + $isAjax = $request->isAjax(); + $type = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); + $response = Response::create($data, $type); + } else { + $response = Response::create(); + } + + // 监听app_end + Hook::listen('app_end', $response); + + return $response; + } + + /** + * 设置当前请求的调度信息 + * @access public + * @param array|string $dispatch 调度信息 + * @param string $type 调度类型 + * @return void + */ + public static function dispatch($dispatch, $type = 'module') + { + self::$dispatch = ['type' => $type, $type => $dispatch]; + } + + /** + * 执行函数或者闭包方法 支持参数调用 + * @access public + * @param string|array|\Closure $function 函数或者闭包 + * @param array $vars 变量 + * @return mixed + */ + public static function invokeFunction($function, $vars = []) + { + $reflect = new \ReflectionFunction($function); + $args = self::bindParams($reflect, $vars); + // 记录执行信息 + self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); + return $reflect->invokeArgs($args); + } + + /** + * 调用反射执行类的方法 支持参数绑定 + * @access public + * @param string|array $method 方法 + * @param array $vars 变量 + * @return mixed + */ + public static function invokeMethod($method, $vars = []) + { + if (is_array($method)) { + $class = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]); + $reflect = new \ReflectionMethod($class, $method[1]); + } else { + // 静态方法 + $reflect = new \ReflectionMethod($method); + } + $args = self::bindParams($reflect, $vars); + + self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info'); + return $reflect->invokeArgs(isset($class) ? $class : null, $args); + } + + /** + * 调用反射执行类的实例化 支持依赖注入 + * @access public + * @param string $class 类名 + * @param array $vars 变量 + * @return mixed + */ + public static function invokeClass($class, $vars = []) + { + $reflect = new \ReflectionClass($class); + $constructor = $reflect->getConstructor(); + if ($constructor) { + $args = self::bindParams($constructor, $vars); + } else { + $args = []; + } + return $reflect->newInstanceArgs($args); + } + + /** + * 绑定参数 + * @access private + * @param \ReflectionMethod|\ReflectionFunction $reflect 反射类 + * @param array $vars 变量 + * @return array + */ + private static function bindParams($reflect, $vars = []) + { + if (empty($vars)) { + // 自动获取请求变量 + if (Config::get('url_param_type')) { + $vars = Request::instance()->route(); + } else { + $vars = Request::instance()->param(); + } + } + $args = []; + if ($reflect->getNumberOfParameters() > 0) { + // 判断数组类型 数字数组时按顺序绑定参数 + reset($vars); + $type = key($vars) === 0 ? 1 : 0; + $params = $reflect->getParameters(); + foreach ($params as $param) { + $args[] = self::getParamValue($param, $vars, $type); + } + } + return $args; + } + + /** + * 获取参数值 + * @access private + * @param \ReflectionParameter $param + * @param array $vars 变量 + * @param string $type + * @return array + */ + private static function getParamValue($param, &$vars, $type) + { + $name = $param->getName(); + $class = $param->getClass(); + if ($class) { + $className = $class->getName(); + $bind = Request::instance()->$name; + if ($bind instanceof $className) { + $result = $bind; + } else { + if (method_exists($className, 'invoke')) { + $method = new \ReflectionMethod($className, 'invoke'); + if ($method->isPublic() && $method->isStatic()) { + return $className::invoke(Request::instance()); + } + } + $result = method_exists($className, 'instance') ? $className::instance() : new $className; + } + } elseif (1 == $type && !empty($vars)) { + $result = array_shift($vars); + } elseif (0 == $type && isset($vars[$name])) { + $result = $vars[$name]; + } elseif ($param->isDefaultValueAvailable()) { + $result = $param->getDefaultValue(); + } else { + throw new \InvalidArgumentException('method param miss:' . $name); + } + return $result; + } + + protected static function exec($dispatch, $config) + { + switch ($dispatch['type']) { + case 'redirect': + // 执行重定向跳转 + $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']); + break; + case 'module': + // 模块/控制器/操作 + $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null); + break; + case 'controller': + // 执行控制器操作 + $vars = array_merge(Request::instance()->param(), $dispatch['var']); + $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']); + break; + case 'method': + // 执行回调方法 + $vars = array_merge(Request::instance()->param(), $dispatch['var']); + $data = self::invokeMethod($dispatch['method'], $vars); + break; + case 'function': + // 执行闭包 + $data = self::invokeFunction($dispatch['function']); + break; + case 'response': + $data = $dispatch['response']; + break; + default: + throw new \InvalidArgumentException('dispatch type not support'); + } + return $data; + } + + /** + * 执行模块 + * @access public + * @param array $result 模块/控制器/操作 + * @param array $config 配置参数 + * @param bool $convert 是否自动转换控制器和操作名 + * @return mixed + */ + public static function module($result, $config, $convert = null) + { + if (is_string($result)) { + $result = explode('/', $result); + } + $request = Request::instance(); + if ($config['app_multi_module']) { + // 多模块部署 + $module = strip_tags(strtolower($result[0] ?: $config['default_module'])); + $bind = Route::getBind('module'); + $available = false; + if ($bind) { + // 绑定模块 + list($bindModule) = explode('/', $bind); + if (empty($result[0])) { + $module = $bindModule; + $available = true; + } elseif ($module == $bindModule) { + $available = true; + } + } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) { + $available = true; + } + + // 模块初始化 + if ($module && $available) { + // 初始化模块 + $request->module($module); + $config = self::init($module); + // 模块请求缓存检查 + $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']); + } else { + throw new HttpException(404, 'module not exists:' . $module); + } + } else { + // 单一模块部署 + $module = ''; + $request->module($module); + } + // 当前模块路径 + App::$modulePath = APP_PATH . ($module ? $module . DS : ''); + + // 是否自动转换控制器和操作名 + $convert = is_bool($convert) ? $convert : $config['url_convert']; + // 获取控制器名 + $controller = strip_tags($result[1] ?: $config['default_controller']); + if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) { + throw new HttpException(404, 'controller not exists:' . $controller); + } + $controller = $convert ? strtolower($controller) : $controller; + + // 获取操作名 + $actionName = strip_tags($result[2] ?: $config['default_action']); + $actionName = $convert ? strtolower($actionName) : $actionName; + + // 设置当前请求的控制器、操作 + $request->controller(Loader::parseName($controller, 1))->action($actionName); + + // 监听module_init + Hook::listen('module_init', $request); + + try { + $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']); + } catch (ClassNotFoundException $e) { + throw new HttpException(404, 'controller not exists:' . $e->getClass()); + } + + // 获取当前操作名 + $action = $actionName . $config['action_suffix']; + + $vars = []; + if (is_callable([$instance, $action])) { + // 执行操作方法 + $call = [$instance, $action]; + } elseif (is_callable([$instance, '_empty'])) { + // 空操作 + $call = [$instance, '_empty']; + $vars = [$actionName]; + } else { + // 操作不存在 + throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()'); + } + + Hook::listen('action_begin', $call); + + return self::invokeMethod($call, $vars); + } + + /** + * 初始化应用 + */ + public static function initCommon() + { + if (empty(self::$init)) { + if (defined('APP_NAMESPACE')) { + self::$namespace = APP_NAMESPACE; + } + Loader::addNamespace(self::$namespace, APP_PATH); + + // 初始化应用 + $config = self::init(); + self::$suffix = $config['class_suffix']; + + // 应用调试模式 + self::$debug = Env::get('app_debug', Config::get('app_debug')); + if (!self::$debug) { + ini_set('display_errors', 'Off'); + } elseif (!IS_CLI) { + //重新申请一块比较大的buffer + if (ob_get_level() > 0) { + $output = ob_get_clean(); + } + ob_start(); + if (!empty($output)) { + echo $output; + } + } + + if (!empty($config['root_namespace'])) { + Loader::addNamespace($config['root_namespace']); + } + + // 加载额外文件 + if (!empty($config['extra_file_list'])) { + foreach ($config['extra_file_list'] as $file) { + $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT; + if (is_file($file) && !isset(self::$file[$file])) { + include $file; + self::$file[$file] = true; + } + } + } + + // 设置系统时区 + date_default_timezone_set($config['default_timezone']); + + // 监听app_init + Hook::listen('app_init'); + + self::$init = true; + } + return Config::get(); + } + + /** + * 初始化应用或模块 + * @access public + * @param string $module 模块名 + * @return array + */ + private static function init($module = '') + { + // 定位模块目录 + $module = $module ? $module . DS : ''; + + // 加载初始化文件 + if (is_file(APP_PATH . $module . 'init' . EXT)) { + include APP_PATH . $module . 'init' . EXT; + } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) { + include RUNTIME_PATH . $module . 'init' . EXT; + } else { + $path = APP_PATH . $module; + // 加载模块配置 + $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT); + // 读取数据库配置文件 + $filename = CONF_PATH . $module . 'database' . CONF_EXT; + Config::load($filename, 'database'); + // 读取扩展配置文件 + if (is_dir(CONF_PATH . $module . 'extra')) { + $dir = CONF_PATH . $module . 'extra'; + $files = scandir($dir); + foreach ($files as $file) { + if ('.' . pathinfo($file, PATHINFO_EXTENSION) === CONF_EXT) { + $filename = $dir . DS . $file; + Config::load($filename, pathinfo($file, PATHINFO_FILENAME)); + } + } + } + + // 加载应用状态配置 + if ($config['app_status']) { + $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT); + } + + // 加载行为扩展文件 + if (is_file(CONF_PATH . $module . 'tags' . EXT)) { + Hook::import(include CONF_PATH . $module . 'tags' . EXT); + } + + // 加载公共文件 + if (is_file($path . 'common' . EXT)) { + include $path . 'common' . EXT; + } + + // 加载当前模块语言包 + if ($module) { + Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT); + } + } + return Config::get(); + } + + /** + * URL路由检测(根据PATH_INFO) + * @access public + * @param \think\Request $request + * @param array $config + * @return array + * @throws \think\Exception + */ + public static function routeCheck($request, array $config) + { + $path = $request->path(); + $depr = $config['pathinfo_depr']; + $result = false; + // 路由检测 + $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on']; + if ($check) { + // 开启路由 + if (is_file(RUNTIME_PATH . 'route.php')) { + // 读取路由缓存 + $rules = include RUNTIME_PATH . 'route.php'; + if (is_array($rules)) { + Route::rules($rules); + } + } else { + $files = $config['route_config_file']; + foreach ($files as $file) { + if (is_file(CONF_PATH . $file . CONF_EXT)) { + // 导入路由配置 + $rules = include CONF_PATH . $file . CONF_EXT; + if (is_array($rules)) { + Route::import($rules); + } + } + } + } + + // 路由检测(根据路由定义返回不同的URL调度) + $result = Route::check($request, $path, $depr, $config['url_domain_deploy']); + $must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must']; + if ($must && false === $result) { + // 路由无效 + throw new RouteNotFoundException(); + } + } + if (false === $result) { + // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索 + $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); + } + return $result; + } + + /** + * 设置应用的路由检测机制 + * @access public + * @param bool $route 是否需要检测路由 + * @param bool $must 是否强制检测路由 + * @return void + */ + public static function route($route, $must = false) + { + self::$routeCheck = $route; + self::$routeMust = $must; + } +} diff --git a/thinkphp/library/think/Build.php b/thinkphp/library/think/Build.php new file mode 100755 index 0000000..6e055c9 --- /dev/null +++ b/thinkphp/library/think/Build.php @@ -0,0 +1,205 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Build +{ + /** + * 根据传入的build资料创建目录和文件 + * @access protected + * @param array $build build列表 + * @param string $namespace 应用类库命名空间 + * @param bool $suffix 类库后缀 + * @return void + */ + public static function run(array $build = [], $namespace = 'app', $suffix = false) + { + // 锁定 + $lockfile = APP_PATH . 'build.lock'; + if (is_writable($lockfile)) { + return; + } elseif (!touch($lockfile)) { + throw new Exception('应用目录[' . APP_PATH . ']不可写,目录无法自动生成!<BR>请手动生成项目目录~', 10006); + } + foreach ($build as $module => $list) { + if ('__dir__' == $module) { + // 创建目录列表 + self::buildDir($list); + } elseif ('__file__' == $module) { + // 创建文件列表 + self::buildFile($list); + } else { + // 创建模块 + self::module($module, $list, $namespace, $suffix); + } + } + // 解除锁定 + unlink($lockfile); + } + + /** + * 创建目录 + * @access protected + * @param array $list 目录列表 + * @return void + */ + protected static function buildDir($list) + { + foreach ($list as $dir) { + if (!is_dir(APP_PATH . $dir)) { + // 创建目录 + mkdir(APP_PATH . $dir, 0755, true); + } + } + } + + /** + * 创建文件 + * @access protected + * @param array $list 文件列表 + * @return void + */ + protected static function buildFile($list) + { + foreach ($list as $file) { + if (!is_dir(APP_PATH . dirname($file))) { + // 创建目录 + mkdir(APP_PATH . dirname($file), 0755, true); + } + if (!is_file(APP_PATH . $file)) { + file_put_contents(APP_PATH . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? "<?php\n" : ''); + } + } + } + + /** + * 创建模块 + * @access public + * @param string $module 模块名 + * @param array $list build列表 + * @param string $namespace 应用类库命名空间 + * @param bool $suffix 类库后缀 + * @return void + */ + public static function module($module = '', $list = [], $namespace = 'app', $suffix = false) + { + $module = $module ? $module : ''; + if (!is_dir(APP_PATH . $module)) { + // 创建模块目录 + mkdir(APP_PATH . $module); + } + if (basename(RUNTIME_PATH) != $module) { + // 创建配置文件和公共文件 + self::buildCommon($module); + // 创建模块的默认页面 + self::buildHello($module, $namespace, $suffix); + } + if (empty($list)) { + // 创建默认的模块目录和文件 + $list = [ + '__file__' => ['config.php', 'common.php'], + '__dir__' => ['controller', 'model', 'view'], + ]; + } + // 创建子目录和文件 + foreach ($list as $path => $file) { + $modulePath = APP_PATH . $module . DS; + if ('__dir__' == $path) { + // 生成子目录 + foreach ($file as $dir) { + self::checkDirBuild($modulePath . $dir); + } + } elseif ('__file__' == $path) { + // 生成(空白)文件 + foreach ($file as $name) { + if (!is_file($modulePath . $name)) { + file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? "<?php\n" : ''); + } + } + } else { + // 生成相关MVC文件 + foreach ($file as $val) { + $val = trim($val); + $filename = $modulePath . $path . DS . $val . ($suffix ? ucfirst($path) : '') . EXT; + $space = $namespace . '\\' . ($module ? $module . '\\' : '') . $path; + $class = $val . ($suffix ? ucfirst($path) : ''); + switch ($path) { + case 'controller': // 控制器 + $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}"; + break; + case 'model': // 模型 + $content = "<?php\nnamespace {$space};\n\nuse think\Model;\n\nclass {$class} extends Model\n{\n\n}"; + break; + case 'view': // 视图 + $filename = $modulePath . $path . DS . $val . '.html'; + self::checkDirBuild(dirname($filename)); + $content = ''; + break; + default: + // 其他文件 + $content = "<?php\nnamespace {$space};\n\nclass {$class}\n{\n\n}"; + } + + if (!is_file($filename)) { + file_put_contents($filename, $content); + } + } + } + } + } + + /** + * 创建模块的欢迎页面 + * @access public + * @param string $module 模块名 + * @param string $namespace 应用类库命名空间 + * @param bool $suffix 类库后缀 + * @return void + */ + protected static function buildHello($module, $namespace, $suffix = false) + { + $filename = APP_PATH . ($module ? $module . DS : '') . 'controller' . DS . 'Index' . ($suffix ? 'Controller' : '') . EXT; + if (!is_file($filename)) { + $content = file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl'); + $content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [$namespace, $module ? $module . '\\' : '', 'controller', $suffix ? 'Controller' : ''], $content); + self::checkDirBuild(dirname($filename)); + file_put_contents($filename, $content); + } + } + + /** + * 创建模块的公共文件 + * @access public + * @param string $module 模块名 + * @return void + */ + protected static function buildCommon($module) + { + $filename = CONF_PATH . ($module ? $module . DS : '') . 'config.php'; + + self::checkDirBuild(dirname($filename)); + if (!is_file($filename)) { + file_put_contents($filename, "<?php\n//配置文件\nreturn [\n\n];"); + } + $filename = APP_PATH . ($module ? $module . DS : '') . 'common.php'; + if (!is_file($filename)) { + file_put_contents($filename, "<?php\n"); + } + } + + protected static function checkDirBuild($dirname) + { + if (!is_dir($dirname)) { + mkdir($dirname, 0755, true); + } + } +} diff --git a/thinkphp/library/think/Cache.php b/thinkphp/library/think/Cache.php new file mode 100755 index 0000000..8802957 --- /dev/null +++ b/thinkphp/library/think/Cache.php @@ -0,0 +1,222 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\cache\Driver; + +class Cache +{ + protected static $instance = []; + public static $readTimes = 0; + public static $writeTimes = 0; + + /** + * 操作句柄 + * @var object + * @access protected + */ + protected static $handler; + + /** + * 连接缓存 + * @access public + * @param array $options 配置数组 + * @param bool|string $name 缓存连接标识 true 强制重新连接 + * @return Driver + */ + public static function connect(array $options = [], $name = false) + { + $type = !empty($options['type']) ? $options['type'] : 'File'; + if (false === $name) { + $name = md5(serialize($options)); + } + + if (true === $name || !isset(self::$instance[$name])) { + $class = false !== strpos($type, '\\') ? $type : '\\think\\cache\\driver\\' . ucwords($type); + + // 记录初始化信息 + App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info'); + if (true === $name) { + return new $class($options); + } else { + self::$instance[$name] = new $class($options); + } + } + return self::$instance[$name]; + } + + /** + * 自动初始化缓存 + * @access public + * @param array $options 配置数组 + * @return Driver + */ + public static function init(array $options = []) + { + if (is_null(self::$handler)) { + // 自动初始化缓存 + if (!empty($options)) { + $connect = self::connect($options); + } elseif ('complex' == Config::get('cache.type')) { + $connect = self::connect(Config::get('cache.default')); + } else { + $connect = self::connect(Config::get('cache')); + } + self::$handler = $connect; + } + return self::$handler; + } + + /** + * 切换缓存类型 需要配置 cache.type 为 complex + * @access public + * @param string $name 缓存标识 + * @return Driver + */ + public static function store($name = '') + { + if ('' !== $name && 'complex' == Config::get('cache.type')) { + return self::connect(Config::get('cache.' . $name), strtolower($name)); + } + return self::init(); + } + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public static function has($name) + { + self::$readTimes++; + return self::init()->has($name); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存标识 + * @param mixed $default 默认值 + * @return mixed + */ + public static function get($name, $default = false) + { + self::$readTimes++; + return self::init()->get($name, $default); + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存标识 + * @param mixed $value 存储数据 + * @param int|null $expire 有效时间 0为永久 + * @return boolean + */ + public static function set($name, $value, $expire = null) + { + self::$writeTimes++; + return self::init()->set($name, $value, $expire); + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public static function inc($name, $step = 1) + { + self::$writeTimes++; + return self::init()->inc($name, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public static function dec($name, $step = 1) + { + self::$writeTimes++; + return self::init()->dec($name, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存标识 + * @return boolean + */ + public static function rm($name) + { + self::$writeTimes++; + return self::init()->rm($name); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public static function clear($tag = null) + { + self::$writeTimes++; + return self::init()->clear($tag); + } + + /** + * 读取缓存并删除 + * @access public + * @param string $name 缓存变量名 + * @return mixed + */ + public static function pull($name) + { + self::$readTimes++; + self::$writeTimes++; + return self::init()->pull($name); + } + + /** + * 如果不存在则写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return mixed + */ + public static function remember($name, $value, $expire = null) + { + self::$readTimes++; + return self::init()->remember($name, $value, $expire); + } + + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @param string|array $keys 缓存标识 + * @param bool $overlay 是否覆盖 + * @return Driver + */ + public static function tag($name, $keys = null, $overlay = false) + { + return self::init()->tag($name, $keys, $overlay); + } + +} diff --git a/thinkphp/library/think/Collection.php b/thinkphp/library/think/Collection.php new file mode 100755 index 0000000..3fcba5c --- /dev/null +++ b/thinkphp/library/think/Collection.php @@ -0,0 +1,391 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think; + +use ArrayAccess; +use ArrayIterator; +use Countable; +use IteratorAggregate; +use JsonSerializable; + +class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable +{ + protected $items = []; + + public function __construct($items = []) + { + $this->items = $this->convertToArray($items); + } + + public static function make($items = []) + { + return new static($items); + } + + /** + * 是否为空 + * @return bool + */ + public function isEmpty() + { + return empty($this->items); + } + + public function toArray() + { + return array_map(function ($value) { + return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value; + }, $this->items); + } + + public function all() + { + return $this->items; + } + + /** + * 合并数组 + * + * @param mixed $items + * @return static + */ + public function merge($items) + { + return new static(array_merge($this->items, $this->convertToArray($items))); + } + + /** + * 比较数组,返回差集 + * + * @param mixed $items + * @return static + */ + public function diff($items) + { + return new static(array_diff($this->items, $this->convertToArray($items))); + } + + /** + * 交换数组中的键和值 + * + * @return static + */ + public function flip() + { + return new static(array_flip($this->items)); + } + + /** + * 比较数组,返回交集 + * + * @param mixed $items + * @return static + */ + public function intersect($items) + { + return new static(array_intersect($this->items, $this->convertToArray($items))); + } + + /** + * 返回数组中所有的键名 + * + * @return static + */ + public function keys() + { + return new static(array_keys($this->items)); + } + + /** + * 删除数组的最后一个元素(出栈) + * + * @return mixed + */ + public function pop() + { + return array_pop($this->items); + } + + /** + * 通过使用用户自定义函数,以字符串返回数组 + * + * @param callable $callback + * @param mixed $initial + * @return mixed + */ + public function reduce(callable $callback, $initial = null) + { + return array_reduce($this->items, $callback, $initial); + } + + /** + * 以相反的顺序返回数组。 + * + * @return static + */ + public function reverse() + { + return new static(array_reverse($this->items)); + } + + /** + * 删除数组中首个元素,并返回被删除元素的值 + * + * @return mixed + */ + public function shift() + { + return array_shift($this->items); + } + + /** + * 把一个数组分割为新的数组块. + * + * @param int $size + * @param bool $preserveKeys + * @return static + */ + public function chunk($size, $preserveKeys = false) + { + $chunks = []; + + foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) { + $chunks[] = new static($chunk); + } + + return new static($chunks); + } + + /** + * 在数组开头插入一个元素 + * @param mixed $value + * @param miexed $key + * @return void + */ + public function unshift($value, $key = null) + { + if (is_null($key)) { + array_unshift($this->items, $value); + } else { + $this->items = [$key => $value] + $this->items; + } + } + + /** + * 在数组结尾插入一个元素 + * @param mixed $value + * @param mixed $key + * @return void + */ + public function push($value, $key = null) + { + if (is_null($key)) { + $this->items[] = $value; + } else { + $this->items[$key] = $value; + } + } + + /** + * 给每个元素执行个回调 + * + * @param callable $callback + * @return $this + */ + public function each(callable $callback) + { + foreach ($this->items as $key => $item) { + $result = $callback($item, $key); + if (false === $result) { + break; + } elseif (!is_object($item)) { + $this->items[$key] = $result; + } + } + + return $this; + } + + /** + * 用回调函数过滤数组中的元素 + * @param callable|null $callback + * @return static + */ + public function filter(callable $callback = null) + { + if ($callback) { + return new static(array_filter($this->items, $callback)); + } + + return new static(array_filter($this->items)); + } + + /** + * 返回数组中指定的一列 + * @param $column_key + * @param null $index_key + * @return array + */ + public function column($column_key, $index_key = null) + { + if (function_exists('array_column')) { + return array_column($this->items, $column_key, $index_key); + } + + $result = []; + foreach ($this->items as $row) { + $key = $value = null; + $keySet = $valueSet = false; + if (null !== $index_key && array_key_exists($index_key, $row)) { + $keySet = true; + $key = (string) $row[$index_key]; + } + if (null === $column_key) { + $valueSet = true; + $value = $row; + } elseif (is_array($row) && array_key_exists($column_key, $row)) { + $valueSet = true; + $value = $row[$column_key]; + } + if ($valueSet) { + if ($keySet) { + $result[$key] = $value; + } else { + $result[] = $value; + } + } + } + return $result; + } + + /** + * 对数组排序 + * + * @param callable|null $callback + * @return static + */ + public function sort(callable $callback = null) + { + $items = $this->items; + + $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) { + + if ($a == $b) { + return 0; + } + + return ($a < $b) ? -1 : 1; + }); + + return new static($items); + } + + /** + * 将数组打乱 + * + * @return static + */ + public function shuffle() + { + $items = $this->items; + + shuffle($items); + + return new static($items); + } + + /** + * 截取数组 + * + * @param int $offset + * @param int $length + * @param bool $preserveKeys + * @return static + */ + public function slice($offset, $length = null, $preserveKeys = false) + { + return new static(array_slice($this->items, $offset, $length, $preserveKeys)); + } + + // ArrayAccess + public function offsetExists($offset) + { + return array_key_exists($offset, $this->items); + } + + public function offsetGet($offset) + { + return $this->items[$offset]; + } + + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->items[] = $value; + } else { + $this->items[$offset] = $value; + } + } + + public function offsetUnset($offset) + { + unset($this->items[$offset]); + } + + //Countable + public function count() + { + return count($this->items); + } + + //IteratorAggregate + public function getIterator() + { + return new ArrayIterator($this->items); + } + + //JsonSerializable + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * 转换当前数据集为JSON字符串 + * @access public + * @param integer $options json参数 + * @return string + */ + public function toJson($options = JSON_UNESCAPED_UNICODE) + { + return json_encode($this->toArray(), $options); + } + + public function __toString() + { + return $this->toJson(); + } + + /** + * 转换成数组 + * + * @param mixed $items + * @return array + */ + protected function convertToArray($items) + { + if ($items instanceof self) { + return $items->all(); + } + return (array) $items; + } +} diff --git a/thinkphp/library/think/Config.php b/thinkphp/library/think/Config.php new file mode 100755 index 0000000..1fa5d4a --- /dev/null +++ b/thinkphp/library/think/Config.php @@ -0,0 +1,178 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Config +{ + // 配置参数 + private static $config = []; + // 参数作用域 + private static $range = '_sys_'; + + // 设定配置参数的作用域 + public static function range($range) + { + self::$range = $range; + if (!isset(self::$config[$range])) { + self::$config[$range] = []; + } + } + + /** + * 解析配置文件或内容 + * @param string $config 配置文件路径或内容 + * @param string $type 配置解析类型 + * @param string $name 配置名(如设置即表示二级配置) + * @param string $range 作用域 + * @return mixed + */ + public static function parse($config, $type = '', $name = '', $range = '') + { + $range = $range ?: self::$range; + if (empty($type)) { + $type = pathinfo($config, PATHINFO_EXTENSION); + } + $class = false !== strpos($type, '\\') ? $type : '\\think\\config\\driver\\' . ucwords($type); + return self::set((new $class())->parse($config), $name, $range); + } + + /** + * 加载配置文件(PHP格式) + * @param string $file 配置文件名 + * @param string $name 配置名(如设置即表示二级配置) + * @param string $range 作用域 + * @return mixed + */ + public static function load($file, $name = '', $range = '') + { + $range = $range ?: self::$range; + if (!isset(self::$config[$range])) { + self::$config[$range] = []; + } + if (is_file($file)) { + $name = strtolower($name); + $type = pathinfo($file, PATHINFO_EXTENSION); + if ('php' == $type) { + return self::set(include $file, $name, $range); + } elseif ('yaml' == $type && function_exists('yaml_parse_file')) { + return self::set(yaml_parse_file($file), $name, $range); + } else { + return self::parse($file, $type, $name, $range); + } + } else { + return self::$config[$range]; + } + } + + /** + * 检测配置是否存在 + * @param string $name 配置参数名(支持二级配置 .号分割) + * @param string $range 作用域 + * @return bool + */ + public static function has($name, $range = '') + { + $range = $range ?: self::$range; + + if (!strpos($name, '.')) { + return isset(self::$config[$range][strtolower($name)]); + } else { + // 二维数组设置和获取支持 + $name = explode('.', $name, 2); + return isset(self::$config[$range][strtolower($name[0])][$name[1]]); + } + } + + /** + * 获取配置参数 为空则获取所有配置 + * @param string $name 配置参数名(支持二级配置 .号分割) + * @param string $range 作用域 + * @return mixed + */ + public static function get($name = null, $range = '') + { + $range = $range ?: self::$range; + // 无参数时获取所有 + if (empty($name) && isset(self::$config[$range])) { + return self::$config[$range]; + } + + if (!strpos($name, '.')) { + $name = strtolower($name); + return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null; + } else { + // 二维数组设置和获取支持 + $name = explode('.', $name, 2); + $name[0] = strtolower($name[0]); + + if (!isset(self::$config[$range][$name[0]])) { + // 动态载入额外配置 + $module = Request::instance()->module(); + $file = CONF_PATH . ($module ? $module . DS : '') . 'extra' . DS . $name[0] . CONF_EXT; + + is_file($file) && self::load($file, $name[0]); + } + + return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null; + } + } + + /** + * 设置配置参数 name为数组则为批量设置 + * @param string|array $name 配置参数名(支持二级配置 .号分割) + * @param mixed $value 配置值 + * @param string $range 作用域 + * @return mixed + */ + public static function set($name, $value = null, $range = '') + { + $range = $range ?: self::$range; + if (!isset(self::$config[$range])) { + self::$config[$range] = []; + } + if (is_string($name)) { + if (!strpos($name, '.')) { + self::$config[$range][strtolower($name)] = $value; + } else { + // 二维数组设置和获取支持 + $name = explode('.', $name, 2); + self::$config[$range][strtolower($name[0])][$name[1]] = $value; + } + return; + } elseif (is_array($name)) { + // 批量设置 + if (!empty($value)) { + self::$config[$range][$value] = isset(self::$config[$range][$value]) ? + array_merge(self::$config[$range][$value], $name) : $name; + return self::$config[$range][$value]; + } else { + return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name)); + } + } else { + // 为空直接返回 已有配置 + return self::$config[$range]; + } + } + + /** + * 重置配置参数 + */ + public static function reset($range = '') + { + $range = $range ?: self::$range; + if (true === $range) { + self::$config = []; + } else { + self::$config[$range] = []; + } + } +} diff --git a/thinkphp/library/think/Console.php b/thinkphp/library/think/Console.php new file mode 100755 index 0000000..1d97ab2 --- /dev/null +++ b/thinkphp/library/think/Console.php @@ -0,0 +1,719 @@ +<?php +// +---------------------------------------------------------------------- +// | TopThink [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2015 http://www.topthink.com All rights reserved. +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\console\Command; +use think\console\command\Help as HelpCommand; +use think\console\Input; +use think\console\input\Argument as InputArgument; +use think\console\input\Definition as InputDefinition; +use think\console\input\Option as InputOption; +use think\console\Output; +use think\console\output\driver\Buffer; + +class Console +{ + + private $name; + private $version; + + /** @var Command[] */ + private $commands = []; + + private $wantHelps = false; + + private $catchExceptions = true; + private $autoExit = true; + private $definition; + private $defaultCommand; + + private static $defaultCommands = [ + "think\\console\\command\\Help", + "think\\console\\command\\Lists", + "think\\console\\command\\Build", + "think\\console\\command\\Clear", + "think\\console\\command\\make\\Controller", + "think\\console\\command\\make\\Model", + "think\\console\\command\\optimize\\Autoload", + "think\\console\\command\\optimize\\Config", + "think\\console\\command\\optimize\\Route", + "think\\console\\command\\optimize\\Schema", + ]; + + public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') + { + $this->name = $name; + $this->version = $version; + + $this->defaultCommand = 'list'; + $this->definition = $this->getDefaultInputDefinition(); + + foreach ($this->getDefaultCommands() as $command) { + $this->add($command); + } + } + + public static function init($run = true) + { + static $console; + if (!$console) { + // 实例化console + $console = new self('Think Console', '0.1'); + // 读取指令集 + if (is_file(CONF_PATH . 'command' . EXT)) { + $commands = include CONF_PATH . 'command' . EXT; + if (is_array($commands)) { + foreach ($commands as $command) { + if (class_exists($command) && is_subclass_of($command, "\\think\\console\\Command")) { + // 注册指令 + $console->add(new $command()); + } + } + } + } + } + if ($run) { + // 运行 + return $console->run(); + } else { + return $console; + } + } + + /** + * @param $command + * @param array $parameters + * @param string $driver + * @return Output|Buffer + */ + public static function call($command, array $parameters = [], $driver = 'buffer') + { + $console = self::init(false); + + array_unshift($parameters, $command); + + $input = new Input($parameters); + $output = new Output($driver); + + $console->setCatchExceptions(false); + $console->find($command)->run($input, $output); + + return $output; + } + + /** + * 执行当前的指令 + * @return int + * @throws \Exception + * @api + */ + public function run() + { + $input = new Input(); + $output = new Output(); + + $this->configureIO($input, $output); + + try { + $exitCode = $this->doRun($input, $output); + } catch (\Exception $e) { + if (!$this->catchExceptions) { + throw $e; + } + + $output->renderException($e); + + $exitCode = $e->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + } + + if ($this->autoExit) { + if ($exitCode > 255) { + $exitCode = 255; + } + + exit($exitCode); + } + + return $exitCode; + } + + /** + * 执行指令 + * @param Input $input + * @param Output $output + * @return int + */ + public function doRun(Input $input, Output $output) + { + if (true === $input->hasParameterOption(['--version', '-V'])) { + $output->writeln($this->getLongVersion()); + + return 0; + } + + $name = $this->getCommandName($input); + + if (true === $input->hasParameterOption(['--help', '-h'])) { + if (!$name) { + $name = 'help'; + $input = new Input(['help']); + } else { + $this->wantHelps = true; + } + } + + if (!$name) { + $name = $this->defaultCommand; + $input = new Input([$this->defaultCommand]); + } + + $command = $this->find($name); + + $exitCode = $this->doRunCommand($command, $input, $output); + + return $exitCode; + } + + /** + * 设置输入参数定义 + * @param InputDefinition $definition + */ + public function setDefinition(InputDefinition $definition) + { + $this->definition = $definition; + } + + /** + * 获取输入参数定义 + * @return InputDefinition The InputDefinition instance + */ + public function getDefinition() + { + return $this->definition; + } + + /** + * Gets the help message. + * @return string A help message. + */ + public function getHelp() + { + return $this->getLongVersion(); + } + + /** + * 是否捕获异常 + * @param bool $boolean + * @api + */ + public function setCatchExceptions($boolean) + { + $this->catchExceptions = (bool) $boolean; + } + + /** + * 是否自动退出 + * @param bool $boolean + * @api + */ + public function setAutoExit($boolean) + { + $this->autoExit = (bool) $boolean; + } + + /** + * 获取名称 + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * 设置名称 + * @param string $name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * 获取版本 + * @return string + * @api + */ + public function getVersion() + { + return $this->version; + } + + /** + * 设置版本 + * @param string $version + */ + public function setVersion($version) + { + $this->version = $version; + } + + /** + * 获取完整的版本号 + * @return string + */ + public function getLongVersion() + { + if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) { + return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion()); + } + + return '<info>Console Tool</info>'; + } + + /** + * 注册一个指令 + * @param string $name + * @return Command + */ + public function register($name) + { + return $this->add(new Command($name)); + } + + /** + * 添加指令 + * @param Command[] $commands + */ + public function addCommands(array $commands) + { + foreach ($commands as $command) { + $this->add($command); + } + } + + /** + * 添加一个指令 + * @param Command $command + * @return Command + */ + public function add(Command $command) + { + $command->setConsole($this); + + if (!$command->isEnabled()) { + $command->setConsole(null); + return; + } + + if (null === $command->getDefinition()) { + throw new \LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command))); + } + + $this->commands[$command->getName()] = $command; + + foreach ($command->getAliases() as $alias) { + $this->commands[$alias] = $command; + } + + return $command; + } + + /** + * 获取指令 + * @param string $name 指令名称 + * @return Command + * @throws \InvalidArgumentException + */ + public function get($name) + { + if (!isset($this->commands[$name])) { + throw new \InvalidArgumentException(sprintf('The command "%s" does not exist.', $name)); + } + + $command = $this->commands[$name]; + + if ($this->wantHelps) { + $this->wantHelps = false; + + /** @var HelpCommand $helpCommand */ + $helpCommand = $this->get('help'); + $helpCommand->setCommand($command); + + return $helpCommand; + } + + return $command; + } + + /** + * 某个指令是否存在 + * @param string $name 指令名称 + * @return bool + */ + public function has($name) + { + return isset($this->commands[$name]); + } + + /** + * 获取所有的命名空间 + * @return array + */ + public function getNamespaces() + { + $namespaces = []; + foreach ($this->commands as $command) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); + + foreach ($command->getAliases() as $alias) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias)); + } + } + + return array_values(array_unique(array_filter($namespaces))); + } + + /** + * 查找注册命名空间中的名称或缩写。 + * @param string $namespace + * @return string + * @throws \InvalidArgumentException + */ + public function findNamespace($namespace) + { + $allNamespaces = $this->getNamespaces(); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + return preg_quote($matches[1]) . '[^:]*'; + }, $namespace); + $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces); + + if (empty($namespaces)) { + $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); + + if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { + if (1 == count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + + $message .= implode("\n ", $alternatives); + } + + throw new \InvalidArgumentException($message); + } + + $exact = in_array($namespace, $namespaces, true); + if (count($namespaces) > 1 && !$exact) { + throw new \InvalidArgumentException(sprintf('The namespace "%s" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces)))); + } + + return $exact ? $namespace : reset($namespaces); + } + + /** + * 查找指令 + * @param string $name 名称或者别名 + * @return Command + * @throws \InvalidArgumentException + */ + public function find($name) + { + $allCommands = array_keys($this->commands); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { + return preg_quote($matches[1]) . '[^:]*'; + }, $name); + $commands = preg_grep('{^' . $expr . '}', $allCommands); + + if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) { + if (false !== $pos = strrpos($name, ':')) { + $this->findNamespace(substr($name, 0, $pos)); + } + + $message = sprintf('Command "%s" is not defined.', $name); + + if ($alternatives = $this->findAlternatives($name, $allCommands)) { + if (1 == count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + $message .= implode("\n ", $alternatives); + } + + throw new \InvalidArgumentException($message); + } + + if (count($commands) > 1) { + $commandList = $this->commands; + $commands = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) { + $commandName = $commandList[$nameOrAlias]->getName(); + + return $commandName === $nameOrAlias || !in_array($commandName, $commands); + }); + } + + $exact = in_array($name, $commands, true); + if (count($commands) > 1 && !$exact) { + $suggestions = $this->getAbbreviationSuggestions(array_values($commands)); + + throw new \InvalidArgumentException(sprintf('Command "%s" is ambiguous (%s).', $name, $suggestions)); + } + + return $this->get($exact ? $name : reset($commands)); + } + + /** + * 获取所有的指令 + * @param string $namespace 命名空间 + * @return Command[] + * @api + */ + public function all($namespace = null) + { + if (null === $namespace) { + return $this->commands; + } + + $commands = []; + foreach ($this->commands as $name => $command) { + if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) { + $commands[$name] = $command; + } + } + + return $commands; + } + + /** + * 获取可能的指令名 + * @param array $names + * @return array + */ + public static function getAbbreviations($names) + { + $abbrevs = []; + foreach ($names as $name) { + for ($len = strlen($name); $len > 0; --$len) { + $abbrev = substr($name, 0, $len); + $abbrevs[$abbrev][] = $name; + } + } + + return $abbrevs; + } + + /** + * 配置基于用户的参数和选项的输入和输出实例。 + * @param Input $input 输入实例 + * @param Output $output 输出实例 + */ + protected function configureIO(Input $input, Output $output) + { + if (true === $input->hasParameterOption(['--ansi'])) { + $output->setDecorated(true); + } elseif (true === $input->hasParameterOption(['--no-ansi'])) { + $output->setDecorated(false); + } + + if (true === $input->hasParameterOption(['--no-interaction', '-n'])) { + $input->setInteractive(false); + } + + if (true === $input->hasParameterOption(['--quiet', '-q'])) { + $output->setVerbosity(Output::VERBOSITY_QUIET); + } else { + if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) { + $output->setVerbosity(Output::VERBOSITY_DEBUG); + } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) { + $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE); + } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) { + $output->setVerbosity(Output::VERBOSITY_VERBOSE); + } + } + } + + /** + * 执行指令 + * @param Command $command 指令实例 + * @param Input $input 输入实例 + * @param Output $output 输出实例 + * @return int + * @throws \Exception + */ + protected function doRunCommand(Command $command, Input $input, Output $output) + { + return $command->run($input, $output); + } + + /** + * 获取指令的基础名称 + * @param Input $input + * @return string + */ + protected function getCommandName(Input $input) + { + return $input->getFirstArgument(); + } + + /** + * 获取默认输入定义 + * @return InputDefinition + */ + protected function getDefaultInputDefinition() + { + return new InputDefinition([ + new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), + new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'), + new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this console version'), + new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), + new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), + new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'), + new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'), + new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'), + ]); + } + + /** + * 设置默认命令 + * @return Command[] An array of default Command instances + */ + protected function getDefaultCommands() + { + $defaultCommands = []; + + foreach (self::$defaultCommands as $classname) { + if (class_exists($classname) && is_subclass_of($classname, "think\\console\\Command")) { + $defaultCommands[] = new $classname(); + } + } + + return $defaultCommands; + } + + public static function addDefaultCommands(array $classnames) + { + self::$defaultCommands = array_merge(self::$defaultCommands, $classnames); + } + + /** + * 获取可能的建议 + * @param array $abbrevs + * @return string + */ + private function getAbbreviationSuggestions($abbrevs) + { + return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : ''); + } + + /** + * 返回命名空间部分 + * @param string $name 指令 + * @param string $limit 部分的命名空间的最大数量 + * @return string + */ + public function extractNamespace($name, $limit = null) + { + $parts = explode(':', $name); + array_pop($parts); + + return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit)); + } + + /** + * 查找可替代的建议 + * @param string $name + * @param array|\Traversable $collection + * @return array + */ + private function findAlternatives($name, $collection) + { + $threshold = 1e3; + $alternatives = []; + + $collectionParts = []; + foreach ($collection as $item) { + $collectionParts[$item] = explode(':', $item); + } + + foreach (explode(':', $name) as $i => $subname) { + foreach ($collectionParts as $collectionName => $parts) { + $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { + $alternatives[$collectionName] += $threshold; + continue; + } elseif (!isset($parts[$i])) { + continue; + } + + $lev = levenshtein($subname, $parts[$i]); + if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { + $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + } elseif ($exists) { + $alternatives[$collectionName] += $threshold; + } + } + } + + foreach ($collection as $item) { + $lev = levenshtein($name, $item); + if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + } + } + + $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { + return $lev < 2 * $threshold; + }); + asort($alternatives); + + return array_keys($alternatives); + } + + /** + * 设置默认的指令 + * @param string $commandName The Command name + */ + public function setDefaultCommand($commandName) + { + $this->defaultCommand = $commandName; + } + + /** + * 返回所有的命名空间 + * @param string $name + * @return array + */ + private function extractAllNamespaces($name) + { + $parts = explode(':', $name, -1); + $namespaces = []; + + foreach ($parts as $part) { + if (count($namespaces)) { + $namespaces[] = end($namespaces) . ':' . $part; + } else { + $namespaces[] = $part; + } + } + + return $namespaces; + } + +} diff --git a/thinkphp/library/think/Controller.php b/thinkphp/library/think/Controller.php new file mode 100755 index 0000000..e91f2d4 --- /dev/null +++ b/thinkphp/library/think/Controller.php @@ -0,0 +1,213 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ValidateException; +use traits\controller\Jump; + +Loader::import('controller/Jump', TRAIT_PATH, EXT); + +class Controller +{ + use Jump; + + /** + * @var \think\View 视图类实例 + */ + protected $view; + /** + * @var \think\Request Request实例 + */ + protected $request; + // 验证失败是否抛出异常 + protected $failException = false; + // 是否批量验证 + protected $batchValidate = false; + + /** + * 前置操作方法列表 + * @var array $beforeActionList + * @access protected + */ + protected $beforeActionList = []; + + /** + * 构造方法 + * @param Request $request Request对象 + * @access public + */ + public function __construct(Request $request = null) + { + if (is_null($request)) { + $request = Request::instance(); + } + $this->view = View::instance(Config::get('template'), Config::get('view_replace_str')); + $this->request = $request; + + // 控制器初始化 + $this->_initialize(); + + // 前置操作方法 + if ($this->beforeActionList) { + foreach ($this->beforeActionList as $method => $options) { + is_numeric($method) ? + $this->beforeAction($options) : + $this->beforeAction($method, $options); + } + } + } + + // 初始化 + protected function _initialize() + { + } + + /** + * 前置操作 + * @access protected + * @param string $method 前置操作方法名 + * @param array $options 调用参数 ['only'=>[...]] 或者['except'=>[...]] + */ + protected function beforeAction($method, $options = []) + { + if (isset($options['only'])) { + if (is_string($options['only'])) { + $options['only'] = explode(',', $options['only']); + } + if (!in_array($this->request->action(), $options['only'])) { + return; + } + } elseif (isset($options['except'])) { + if (is_string($options['except'])) { + $options['except'] = explode(',', $options['except']); + } + if (in_array($this->request->action(), $options['except'])) { + return; + } + } + + call_user_func([$this, $method]); + } + + /** + * 加载模板输出 + * @access protected + * @param string $template 模板文件名 + * @param array $vars 模板输出变量 + * @param array $replace 模板替换 + * @param array $config 模板参数 + * @return mixed + */ + protected function fetch($template = '', $vars = [], $replace = [], $config = []) + { + return $this->view->fetch($template, $vars, $replace, $config); + } + + /** + * 渲染内容输出 + * @access protected + * @param string $content 模板内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 + * @return mixed + */ + protected function display($content = '', $vars = [], $replace = [], $config = []) + { + return $this->view->display($content, $vars, $replace, $config); + } + + /** + * 模板变量赋值 + * @access protected + * @param mixed $name 要显示的模板变量 + * @param mixed $value 变量的值 + * @return void + */ + protected function assign($name, $value = '') + { + $this->view->assign($name, $value); + } + + /** + * 初始化模板引擎 + * @access protected + * @param array|string $engine 引擎参数 + * @return void + */ + protected function engine($engine) + { + $this->view->engine($engine); + } + + /** + * 设置验证失败后是否抛出异常 + * @access protected + * @param bool $fail 是否抛出异常 + * @return $this + */ + protected function validateFailException($fail = true) + { + $this->failException = $fail; + return $this; + } + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @param mixed $callback 回调方法(闭包) + * @return array|string|true + * @throws ValidateException + */ + protected function validate($data, $validate, $message = [], $batch = false, $callback = null) + { + if (is_array($validate)) { + $v = Loader::validate(); + $v->rule($validate); + } else { + if (strpos($validate, '.')) { + // 支持场景 + list($validate, $scene) = explode('.', $validate); + } + $v = Loader::validate($validate); + if (!empty($scene)) { + $v->scene($scene); + } + } + // 是否批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + + if (is_array($message)) { + $v->message($message); + } + + if ($callback && is_callable($callback)) { + call_user_func_array($callback, [$v, &$data]); + } + + if (!$v->check($data)) { + if ($this->failException) { + throw new ValidateException($v->getError()); + } else { + return $v->getError(); + } + } else { + return true; + } + } +} diff --git a/thinkphp/library/think/Cookie.php b/thinkphp/library/think/Cookie.php new file mode 100755 index 0000000..3205fcd --- /dev/null +++ b/thinkphp/library/think/Cookie.php @@ -0,0 +1,224 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Cookie +{ + protected static $config = [ + // cookie 名称前缀 + 'prefix' => '', + // cookie 保存时间 + 'expire' => 0, + // cookie 保存路径 + 'path' => '/', + // cookie 有效域名 + 'domain' => '', + // cookie 启用安全传输 + 'secure' => false, + // httponly设置 + 'httponly' => '', + // 是否使用 setcookie + 'setcookie' => true, + ]; + + protected static $init; + + /** + * Cookie初始化 + * @param array $config + * @return void + */ + public static function init(array $config = []) + { + if (empty($config)) { + $config = Config::get('cookie'); + } + self::$config = array_merge(self::$config, array_change_key_case($config)); + if (!empty(self::$config['httponly'])) { + ini_set('session.cookie_httponly', 1); + } + self::$init = true; + } + + /** + * 设置或者获取cookie作用域(前缀) + * @param string $prefix + * @return string|void + */ + public static function prefix($prefix = '') + { + if (empty($prefix)) { + return self::$config['prefix']; + } + self::$config['prefix'] = $prefix; + } + + /** + * Cookie 设置、获取、删除 + * + * @param string $name cookie名称 + * @param mixed $value cookie值 + * @param mixed $option 可选参数 可能会是 null|integer|string + * + * @return mixed + * @internal param mixed $options cookie参数 + */ + public static function set($name, $value = '', $option = null) + { + !isset(self::$init) && self::init(); + // 参数设置(会覆盖黙认设置) + if (!is_null($option)) { + if (is_numeric($option)) { + $option = ['expire' => $option]; + } elseif (is_string($option)) { + parse_str($option, $option); + } + $config = array_merge(self::$config, array_change_key_case($option)); + } else { + $config = self::$config; + } + $name = $config['prefix'] . $name; + // 设置cookie + if (is_array($value)) { + array_walk_recursive($value, 'self::jsonFormatProtect', 'encode'); + $value = 'think:' . json_encode($value); + } + $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0; + if ($config['setcookie']) { + setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + } + $_COOKIE[$name] = $value; + } + + /** + * 永久保存Cookie数据 + * @param string $name cookie名称 + * @param mixed $value cookie值 + * @param mixed $option 可选参数 可能会是 null|integer|string + * @return void + */ + public static function forever($name, $value = '', $option = null) + { + if (is_null($option) || is_numeric($option)) { + $option = []; + } + $option['expire'] = 315360000; + self::set($name, $value, $option); + } + + /** + * 判断Cookie数据 + * @param string $name cookie名称 + * @param string|null $prefix cookie前缀 + * @return bool + */ + public static function has($name, $prefix = null) + { + !isset(self::$init) && self::init(); + $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; + $name = $prefix . $name; + return isset($_COOKIE[$name]); + } + + /** + * Cookie获取 + * @param string $name cookie名称 + * @param string|null $prefix cookie前缀 + * @return mixed + */ + public static function get($name = '', $prefix = null) + { + !isset(self::$init) && self::init(); + $prefix = !is_null($prefix) ? $prefix : self::$config['prefix']; + $key = $prefix . $name; + + if ('' == $name) { + // 获取全部 + if ($prefix) { + $value = []; + foreach ($_COOKIE as $k => $val) { + if (0 === strpos($k, $prefix)) { + $value[$k] = $val; + } + } + } else { + $value = $_COOKIE; + } + } elseif (isset($_COOKIE[$key])) { + $value = $_COOKIE[$key]; + if (0 === strpos($value, 'think:')) { + $value = substr($value, 6); + $value = json_decode($value, true); + array_walk_recursive($value, 'self::jsonFormatProtect', 'decode'); + } + } else { + $value = null; + } + return $value; + } + + /** + * Cookie删除 + * @param string $name cookie名称 + * @param string|null $prefix cookie前缀 + * @return mixed + */ + public static function delete($name, $prefix = null) + { + !isset(self::$init) && self::init(); + $config = self::$config; + $prefix = !is_null($prefix) ? $prefix : $config['prefix']; + $name = $prefix . $name; + if ($config['setcookie']) { + setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + } + // 删除指定cookie + unset($_COOKIE[$name]); + } + + /** + * Cookie清空 + * @param string|null $prefix cookie前缀 + * @return mixed + */ + public static function clear($prefix = null) + { + // 清除指定前缀的所有cookie + if (empty($_COOKIE)) { + return; + } + !isset(self::$init) && self::init(); + // 要删除的cookie前缀,不指定则删除config设置的指定前缀 + $config = self::$config; + $prefix = !is_null($prefix) ? $prefix : $config['prefix']; + if ($prefix) { + // 如果前缀为空字符串将不作处理直接返回 + foreach ($_COOKIE as $key => $val) { + if (0 === strpos($key, $prefix)) { + if ($config['setcookie']) { + setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']); + } + unset($_COOKIE[$key]); + } + } + } + return; + } + + private static function jsonFormatProtect(&$val, $key, $type = 'encode') + { + if (!empty($val) && true !== $val) { + $val = 'decode' == $type ? urldecode($val) : urlencode($val); + } + } + +} diff --git a/thinkphp/library/think/Db.php b/thinkphp/library/think/Db.php new file mode 100755 index 0000000..ea0071a --- /dev/null +++ b/thinkphp/library/think/Db.php @@ -0,0 +1,156 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\db\Connection; +use think\db\Query; + +/** + * Class Db + * @package think + * @method Query table(string $table) static 指定数据表(含前缀) + * @method Query name(string $name) static 指定数据表(不含前缀) + * @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件 + * @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询 + * @method Query union(mixed $union, boolean $all = false) static UNION查询 + * @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT + * @method Query order(mixed $field, string $order = null) static 查询ORDER + * @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存 + * @method mixed value(string $field) static 获取某个字段的值 + * @method array column(string $field, string $key = '') static 获取某个列的值 + * @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询 + * @method mixed find(mixed $data = null) static 查询单个记录 + * @method mixed select(mixed $data = null) static 查询多个记录 + * @method integer insert(array $data, boolean $replace = false, boolean $getLastInsID = false, string $sequence = null) static 插入一条记录 + * @method integer insertGetId(array $data, boolean $replace = false, string $sequence = null) static 插入一条记录并返回自增ID + * @method integer insertAll(array $dataSet) static 插入多条记录 + * @method integer update(array $data) static 更新记录 + * @method integer delete(mixed $data = null) static 删除记录 + * @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据 + * @method mixed query(string $sql, array $bind = [], boolean $master = false, bool $pdo = false) static SQL查询 + * @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行 + * @method Paginator paginate(integer $listRows = 15, mixed $simple = null, array $config = []) static 分页查询 + * @method mixed transaction(callable $callback) static 执行数据库事务 + * @method void startTrans() static 启动事务 + * @method void commit() static 用于非自动提交状态下面的查询提交 + * @method void rollback() static 事务回滚 + * @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句 + * @method string quote(string $str) static SQL指令安全过滤 + * @method string getLastInsID($sequence = null) static 获取最近插入的ID + */ +class Db +{ + // 数据库连接实例 + private static $instance = []; + // 查询次数 + public static $queryTimes = 0; + // 执行次数 + public static $executeTimes = 0; + + /** + * 数据库初始化 并取得数据库类实例 + * @static + * @access public + * @param mixed $config 连接配置 + * @param bool|string $name 连接标识 true 强制重新连接 + * @return Connection + * @throws Exception + */ + public static function connect($config = [], $name = false) + { + if (false === $name) { + $name = md5(serialize($config)); + } + if (true === $name || !isset(self::$instance[$name])) { + // 解析连接参数 支持数组和字符串 + $options = self::parseConfig($config); + if (empty($options['type'])) { + throw new \InvalidArgumentException('Undefined db type'); + } + $class = false !== strpos($options['type'], '\\') ? $options['type'] : '\\think\\db\\connector\\' . ucwords($options['type']); + // 记录初始化信息 + if (App::$debug) { + Log::record('[ DB ] INIT ' . $options['type'], 'info'); + } + if (true === $name) { + $name = md5(serialize($config)); + } + self::$instance[$name] = new $class($options); + } + return self::$instance[$name]; + } + + public static function clear() { + self::$instance = null; + } + + /** + * 数据库连接参数解析 + * @static + * @access private + * @param mixed $config + * @return array + */ + private static function parseConfig($config) + { + if (empty($config)) { + $config = Config::get('database'); + } elseif (is_string($config) && false === strpos($config, '/')) { + // 支持读取配置参数 + $config = Config::get($config); + } + if (is_string($config)) { + return self::parseDsn($config); + } else { + return $config; + } + } + + /** + * DSN解析 + * 格式: mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8 + * @static + * @access private + * @param string $dsnStr + * @return array + */ + private static function parseDsn($dsnStr) + { + $info = parse_url($dsnStr); + if (!$info) { + return []; + } + $dsn = [ + 'type' => $info['scheme'], + 'username' => isset($info['user']) ? $info['user'] : '', + 'password' => isset($info['pass']) ? $info['pass'] : '', + 'hostname' => isset($info['host']) ? $info['host'] : '', + 'hostport' => isset($info['port']) ? $info['port'] : '', + 'database' => !empty($info['path']) ? ltrim($info['path'], '/') : '', + 'charset' => isset($info['fragment']) ? $info['fragment'] : 'utf8', + ]; + + if (isset($info['query'])) { + parse_str($info['query'], $dsn['params']); + } else { + $dsn['params'] = []; + } + return $dsn; + } + + // 调用驱动类的方法 + public static function __callStatic($method, $params) + { + // 自动初始化数据库 + return call_user_func_array([self::connect(), $method], $params); + } +} diff --git a/thinkphp/library/think/Debug.php b/thinkphp/library/think/Debug.php new file mode 100755 index 0000000..9994e20 --- /dev/null +++ b/thinkphp/library/think/Debug.php @@ -0,0 +1,212 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; +use think\response\Redirect; + +class Debug +{ + // 区间时间信息 + protected static $info = []; + // 区间内存信息 + protected static $mem = []; + + /** + * 记录时间(微秒)和内存使用情况 + * @param string $name 标记位置 + * @param mixed $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存 + * @return mixed + */ + public static function remark($name, $value = '') + { + // 记录时间和内存使用 + self::$info[$name] = is_float($value) ? $value : microtime(true); + if ('time' != $value) { + self::$mem['mem'][$name] = is_float($value) ? $value : memory_get_usage(); + self::$mem['peak'][$name] = memory_get_peak_usage(); + } + } + + /** + * 统计某个区间的时间(微秒)使用情况 返回值以秒为单位 + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位 + * @return integer + */ + public static function getRangeTime($start, $end, $dec = 6) + { + if (!isset(self::$info[$end])) { + self::$info[$end] = microtime(true); + } + return number_format((self::$info[$end] - self::$info[$start]), $dec); + } + + /** + * 统计从开始到统计时的时间(微秒)使用情况 返回值以秒为单位 + * @param integer|string $dec 小数位 + * @return integer + */ + public static function getUseTime($dec = 6) + { + return number_format((microtime(true) - THINK_START_TIME), $dec); + } + + /** + * 获取当前访问的吞吐率情况 + * @return string + */ + public static function getThroughputRate() + { + return number_format(1 / self::getUseTime(), 2) . 'req/s'; + } + + /** + * 记录区间的内存使用情况 + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位 + * @return string + */ + public static function getRangeMem($start, $end, $dec = 2) + { + if (!isset(self::$mem['mem'][$end])) { + self::$mem['mem'][$end] = memory_get_usage(); + } + $size = self::$mem['mem'][$end] - self::$mem['mem'][$start]; + $a = ['B', 'KB', 'MB', 'GB', 'TB']; + $pos = 0; + while ($size >= 1024) { + $size /= 1024; + $pos++; + } + return round($size, $dec) . " " . $a[$pos]; + } + + /** + * 统计从开始到统计时的内存使用情况 + * @param integer|string $dec 小数位 + * @return string + */ + public static function getUseMem($dec = 2) + { + $size = memory_get_usage() - THINK_START_MEM; + $a = ['B', 'KB', 'MB', 'GB', 'TB']; + $pos = 0; + while ($size >= 1024) { + $size /= 1024; + $pos++; + } + return round($size, $dec) . " " . $a[$pos]; + } + + /** + * 统计区间的内存峰值情况 + * @param string $start 开始标签 + * @param string $end 结束标签 + * @param integer|string $dec 小数位 + * @return mixed + */ + public static function getMemPeak($start, $end, $dec = 2) + { + if (!isset(self::$mem['peak'][$end])) { + self::$mem['peak'][$end] = memory_get_peak_usage(); + } + $size = self::$mem['peak'][$end] - self::$mem['peak'][$start]; + $a = ['B', 'KB', 'MB', 'GB', 'TB']; + $pos = 0; + while ($size >= 1024) { + $size /= 1024; + $pos++; + } + return round($size, $dec) . " " . $a[$pos]; + } + + /** + * 获取文件加载信息 + * @param bool $detail 是否显示详细 + * @return integer|array + */ + public static function getFile($detail = false) + { + if ($detail) { + $files = get_included_files(); + $info = []; + foreach ($files as $key => $file) { + $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )'; + } + return $info; + } + return count(get_included_files()); + } + + /** + * 浏览器友好的变量输出 + * @param mixed $var 变量 + * @param boolean $echo 是否输出 默认为true 如果为false 则返回输出字符串 + * @param string $label 标签 默认为空 + * @param integer $flags htmlspecialchars flags + * @return void|string + */ + public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE) + { + $label = (null === $label) ? '' : rtrim($label) . ':'; + ob_start(); + var_dump($var); + $output = ob_get_clean(); + $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output); + if (IS_CLI) { + $output = PHP_EOL . $label . $output . PHP_EOL; + } else { + if (!extension_loaded('xdebug')) { + $output = htmlspecialchars($output, $flags); + } + $output = '<pre>' . $label . $output . '</pre>'; + } + if ($echo) { + echo($output); + return; + } else { + return $output; + } + } + + public static function inject(Response $response, &$content) + { + $config = Config::get('trace'); + $type = isset($config['type']) ? $config['type'] : 'Html'; + $request = Request::instance(); + $class = false !== strpos($type, '\\') ? $type : '\\think\\debug\\' . ucwords($type); + unset($config['type']); + if (class_exists($class)) { + $trace = new $class($config); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + + if ($response instanceof Redirect) { + //TODO 记录 + } else { + $output = $trace->output($response, Log::getLog()); + if (is_string($output)) { + // trace调试信息注入 + $pos = strripos($content, '</body>'); + if (false !== $pos) { + $content = substr($content, 0, $pos) . $output . substr($content, $pos); + } else { + $content = $content . $output; + } + } + } + } +} diff --git a/thinkphp/library/think/Env.php b/thinkphp/library/think/Env.php new file mode 100755 index 0000000..fa87897 --- /dev/null +++ b/thinkphp/library/think/Env.php @@ -0,0 +1,36 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Env +{ + /** + * 获取环境变量值 + * @param string $name 环境变量名(支持二级 .号分割) + * @param string $default 默认值 + * @return mixed + */ + public static function get($name, $default = null) + { + $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name))); + if (false !== $result) { + if ('false' === $result) { + $result = false; + } elseif ('true' === $result) { + $result = true; + } + return $result; + } else { + return $default; + } + } +} diff --git a/thinkphp/library/think/Error.php b/thinkphp/library/think/Error.php new file mode 100755 index 0000000..9eda544 --- /dev/null +++ b/thinkphp/library/think/Error.php @@ -0,0 +1,120 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think; + +use think\console\Output as ConsoleOutput; +use think\exception\ErrorException; +use think\exception\Handle; +use think\exception\ThrowableError; + +class Error +{ + /** + * 注册异常处理 + * @return void + */ + public static function register() + { + error_reporting(E_ALL); + set_error_handler([__CLASS__, 'appError']); + set_exception_handler([__CLASS__, 'appException']); + register_shutdown_function([__CLASS__, 'appShutdown']); + } + + /** + * Exception Handler + * @param \Exception|\Throwable $e + */ + public static function appException($e) + { + if (!$e instanceof \Exception) { + $e = new ThrowableError($e); + } + + self::getExceptionHandler()->report($e); + if (IS_CLI) { + self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e); + } else { + self::getExceptionHandler()->render($e)->send(); + } + } + + /** + * Error Handler + * @param integer $errno 错误编号 + * @param integer $errstr 详细错误信息 + * @param string $errfile 出错的文件 + * @param integer $errline 出错行号 + * @param array $errcontext + * @throws ErrorException + */ + public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = []) + { + $exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext); + if (error_reporting() & $errno) { + // 将错误信息托管至 think\exception\ErrorException + throw $exception; + } else { + self::getExceptionHandler()->report($exception); + } + } + + /** + * Shutdown Handler + */ + public static function appShutdown() + { + if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) { + // 将错误信息托管至think\ErrorException + $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']); + + self::appException($exception); + } + + // 写入日志 + Log::save(); + } + + /** + * 确定错误类型是否致命 + * + * @param int $type + * @return bool + */ + protected static function isFatal($type) + { + return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]); + } + + /** + * Get an instance of the exception handler. + * + * @return Handle + */ + public static function getExceptionHandler() + { + static $handle; + if (!$handle) { + // 异常处理handle + $class = Config::get('exception_handle'); + if ($class && is_string($class) && class_exists($class) && is_subclass_of($class, "\\think\\exception\\Handle")) { + $handle = new $class; + } else { + $handle = new Handle; + if ($class instanceof \Closure) { + $handle->setRender($class); + } + } + } + return $handle; + } +} diff --git a/thinkphp/library/think/Exception.php b/thinkphp/library/think/Exception.php new file mode 100755 index 0000000..034c85b --- /dev/null +++ b/thinkphp/library/think/Exception.php @@ -0,0 +1,54 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think; + +class Exception extends \Exception +{ + + /** + * 保存异常页面显示的额外Debug数据 + * @var array + */ + protected $data = []; + + /** + * 设置异常额外的Debug数据 + * 数据将会显示为下面的格式 + * + * Exception Data + * -------------------------------------------------- + * Label 1 + * key1 value1 + * key2 value2 + * Label 2 + * key1 value1 + * key2 value2 + * + * @param string $label 数据分类,用于异常页面显示 + * @param array $data 需要显示的数据,必须为关联数组 + */ + final protected function setData($label, array $data) + { + $this->data[$label] = $data; + } + + /** + * 获取异常额外Debug数据 + * 主要用于输出到异常页面便于调试 + * @return array 由setData设置的Debug数据 + */ + final public function getData() + { + return $this->data; + } + +} diff --git a/thinkphp/library/think/File.php b/thinkphp/library/think/File.php new file mode 100755 index 0000000..8e606f7 --- /dev/null +++ b/thinkphp/library/think/File.php @@ -0,0 +1,431 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use SplFileObject; + +class File extends SplFileObject +{ + /** + * 错误信息 + * @var string + */ + private $error = ''; + // 当前完整文件名 + protected $filename; + // 上传文件名 + protected $saveName; + // 文件上传命名规则 + protected $rule = 'date'; + // 文件上传验证规则 + protected $validate = []; + // 单元测试 + protected $isTest; + // 上传文件信息 + protected $info; + // 文件hash信息 + protected $hash = []; + + public function __construct($filename, $mode = 'r') + { + parent::__construct($filename, $mode); + $this->filename = $this->getRealPath() ?: $this->getPathname(); + } + + /** + * 是否测试 + * @param bool $test 是否测试 + * @return $this + */ + public function isTest($test = false) + { + $this->isTest = $test; + return $this; + } + + /** + * 设置上传信息 + * @param array $info 上传文件信息 + * @return $this + */ + public function setUploadInfo($info) + { + $this->info = $info; + return $this; + } + + /** + * 获取上传文件的信息 + * @param string $name + * @return array|string + */ + public function getInfo($name = '') + { + return isset($this->info[$name]) ? $this->info[$name] : $this->info; + } + + /** + * 获取上传文件的文件名 + * @return string + */ + public function getSaveName() + { + return $this->saveName; + } + + /** + * 设置上传文件的保存文件名 + * @param string $saveName + * @return $this + */ + public function setSaveName($saveName) + { + $this->saveName = $saveName; + return $this; + } + + /** + * 获取文件的哈希散列值 + * @param string $type + * @return string + */ + public function hash($type = 'sha1') + { + if (!isset($this->hash[$type])) { + $this->hash[$type] = hash_file($type, $this->filename); + } + return $this->hash[$type]; + } + + /** + * 检查目录是否可写 + * @param string $path 目录 + * @return boolean + */ + protected function checkPath($path) + { + if (is_dir($path)) { + return true; + } + + if (mkdir($path, 0755, true)) { + return true; + } else { + $this->error = ['directory {:path} creation failed', ['path' => $path]]; + return false; + } + } + + /** + * 获取文件类型信息 + * @return string + */ + public function getMime() + { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + return finfo_file($finfo, $this->filename); + } + + /** + * 设置文件的命名规则 + * @param string $rule 文件命名规则 + * @return $this + */ + public function rule($rule) + { + $this->rule = $rule; + return $this; + } + + /** + * 设置上传文件的验证规则 + * @param array $rule 验证规则 + * @return $this + */ + public function validate($rule = []) + { + $this->validate = $rule; + return $this; + } + + /** + * 检测是否合法的上传文件 + * @return bool + */ + public function isValid() + { + if ($this->isTest) { + return is_file($this->filename); + } + return is_uploaded_file($this->filename); + } + + /** + * 检测上传文件 + * @param array $rule 验证规则 + * @return bool + */ + public function check($rule = []) + { + $rule = $rule ?: $this->validate; + + /* 检查文件大小 */ + if (isset($rule['size']) && !$this->checkSize($rule['size'])) { + $this->error = 'filesize not match'; + return false; + } + + /* 检查文件Mime类型 */ + if (isset($rule['type']) && !$this->checkMime($rule['type'])) { + $this->error = 'mimetype to upload is not allowed'; + return false; + } + + /* 检查文件后缀 */ + if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) { + $this->error = 'extensions to upload is not allowed'; + return false; + } + + /* 检查图像文件 */ + if (!$this->checkImg()) { + $this->error = 'illegal image files'; + return false; + } + return true; + } + + /** + * 检测上传文件后缀 + * @param array|string $ext 允许后缀 + * @return bool + */ + public function checkExt($ext) + { + if (is_string($ext)) { + $ext = explode(',', $ext); + } + + $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); + + if (!in_array($extension, $ext)) { + return false; + } + return true; + } + + /** + * 检测图像文件 + * @return bool + */ + public function checkImg() + { + $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION)); + + /* 对图像文件进行严格检测 */ + if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6, 13])) { + return false; + } + return true; + } + + // 判断图像类型 + protected function getImageType($image) + { + if (function_exists('exif_imagetype')) { + return exif_imagetype($image); + } else { + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } + } + } + + /** + * 检测上传文件大小 + * @param integer $size 最大大小 + * @return bool + */ + public function checkSize($size) + { + if ($this->getSize() > $size) { + return false; + } + return true; + } + + /** + * 检测上传文件类型 + * @param array|string $mime 允许类型 + * @return bool + */ + public function checkMime($mime) + { + if (is_string($mime)) { + $mime = explode(',', $mime); + } + + if (!in_array(strtolower($this->getMime()), $mime)) { + return false; + } + + return true; + } + + /** + * 移动文件 + * @param string $path 保存路径 + * @param string|bool $savename 保存的文件名 默认自动生成 + * @param boolean $replace 同名文件是否覆盖 + * @return false|File false-失败 否则返回File实例 + */ + public function move($path, $savename = true, $replace = true) + { + // 文件上传失败,捕获错误代码 + if (!empty($this->info['error'])) { + $this->error($this->info['error']); + return false; + } + + // 检测合法性 + if (!$this->isValid()) { + $this->error = 'upload illegal files'; + return false; + } + + // 验证上传 + if (!$this->check()) { + return false; + } + + $path = rtrim($path, DS) . DS; + // 文件保存命名规则 + $saveName = $this->buildSaveName($savename); + $filename = $path . $saveName; + + // 检测目录 + if (false === $this->checkPath(dirname($filename))) { + return false; + } + + /* 不覆盖同名文件 */ + if (!$replace && is_file($filename)) { + $this->error = ['has the same filename: {:filename}', ['filename' => $filename]]; + return false; + } + + /* 移动文件 */ + if ($this->isTest) { + rename($this->filename, $filename); + } elseif (!move_uploaded_file($this->filename, $filename)) { + $this->error = 'upload write error'; + return false; + } + + // 返回 File对象实例 + $file = new self($filename); + $file->setSaveName($saveName); + $file->setUploadInfo($this->info); + + return $file; + } + + /** + * 获取保存文件名 + * @param string|bool $savename 保存的文件名 默认自动生成 + * @return string + */ + protected function buildSaveName($savename) + { + if (true === $savename) { + // 自动生成文件名 + if ($this->rule instanceof \Closure) { + $savename = call_user_func_array($this->rule, [$this]); + } else { + switch ($this->rule) { + case 'date': + $savename = date('Ymd') . DS . md5(microtime(true)); + break; + default: + if (in_array($this->rule, hash_algos())) { + $hash = $this->hash($this->rule); + $savename = substr($hash, 0, 2) . DS . substr($hash, 2); + } elseif (is_callable($this->rule)) { + $savename = call_user_func($this->rule); + } else { + $savename = date('Ymd') . DS . md5(microtime(true)); + } + } + } + } elseif ('' === $savename || false === $savename) { + $savename = $this->getInfo('name'); + } + + if (!strpos($savename, '.')) { + $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION); + } + + return $savename; + } + + /** + * 获取错误代码信息 + * @param int $errorNo 错误号 + */ + private function error($errorNo) + { + switch ($errorNo) { + case 1: + case 2: + $this->error = 'upload File size exceeds the maximum value'; + break; + case 3: + $this->error = 'only the portion of file is uploaded'; + break; + case 4: + $this->error = 'no file to uploaded'; + break; + case 6: + $this->error = 'upload temp dir not found'; + break; + case 7: + $this->error = 'file write error'; + break; + default: + $this->error = 'unknown upload error'; + } + } + + /** + * 获取错误信息(支持多语言) + * @return string + */ + public function getError() + { + if (is_array($this->error)) { + list($msg, $vars) = $this->error; + } else { + $msg = $this->error; + $vars = []; + } + + return Lang::has($msg) ? Lang::get($msg, $vars) : $msg; + } + + public function __call($method, $args) + { + return $this->hash($method); + } +} diff --git a/thinkphp/library/think/Hook.php b/thinkphp/library/think/Hook.php new file mode 100755 index 0000000..f06196e --- /dev/null +++ b/thinkphp/library/think/Hook.php @@ -0,0 +1,136 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Hook +{ + + private static $tags = []; + + /** + * 动态添加行为扩展到某个标签 + * @param string $tag 标签名称 + * @param mixed $behavior 行为名称 + * @param bool $first 是否放到开头执行 + * @return void + */ + public static function add($tag, $behavior, $first = false) + { + isset(self::$tags[$tag]) || self::$tags[$tag] = []; + if (is_array($behavior) && !is_callable($behavior)) { + if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) { + unset($behavior['_overlay']); + self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior); + } else { + unset($behavior['_overlay']); + self::$tags[$tag] = $behavior; + } + } elseif ($first) { + array_unshift(self::$tags[$tag], $behavior); + } else { + self::$tags[$tag][] = $behavior; + } + } + + /** + * 批量导入插件 + * @param array $tags 插件信息 + * @param boolean $recursive 是否递归合并 + */ + public static function import(array $tags, $recursive = true) + { + if ($recursive) { + foreach ($tags as $tag => $behavior) { + self::add($tag, $behavior); + } + } else { + self::$tags = $tags + self::$tags; + } + } + + /** + * 获取插件信息 + * @param string $tag 插件位置 留空获取全部 + * @return array + */ + public static function get($tag = '') + { + if (empty($tag)) { + //获取全部的插件信息 + return self::$tags; + } else { + return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : []; + } + } + + /** + * 监听标签的行为 + * @param string $tag 标签名称 + * @param mixed $params 传入参数 + * @param mixed $extra 额外参数 + * @param bool $once 只获取一个有效返回值 + * @return mixed + */ + public static function listen($tag, &$params = null, $extra = null, $once = false) + { + $results = []; + $tags = static::get($tag); + foreach ($tags as $key => $name) { + $results[$key] = self::exec($name, $tag, $params, $extra); + if (false === $results[$key]) { + // 如果返回false 则中断行为执行 + break; + } elseif (!is_null($results[$key]) && $once) { + break; + } + } + return $once ? end($results) : $results; + } + + /** + * 执行某个行为 + * @param mixed $class 要执行的行为 + * @param string $tag 方法名(标签名) + * @param Mixed $params 传人的参数 + * @param mixed $extra 额外参数 + * @return mixed + */ + public static function exec($class, $tag = '', &$params = null, $extra = null) + { + App::$debug && Debug::remark('behavior_start', 'time'); + $method = Loader::parseName($tag, 1, false); + if ($class instanceof \Closure) { + $result = call_user_func_array($class, [ & $params, $extra]); + $class = 'Closure'; + } elseif (is_array($class)) { + list($class, $method) = $class; + + $result = (new $class())->$method($params, $extra); + $class = $class . '->' . $method; + } elseif (is_object($class)) { + $result = $class->$method($params, $extra); + $class = get_class($class); + } elseif (strpos($class, '::')) { + $result = call_user_func_array($class, [ & $params, $extra]); + } else { + $obj = new $class(); + $method = ($tag && is_callable([$obj, $method])) ? $method : 'run'; + $result = $obj->$method($params, $extra); + } + if (App::$debug) { + Debug::remark('behavior_end', 'time'); + Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info'); + } + return $result; + } + +} diff --git a/thinkphp/library/think/Lang.php b/thinkphp/library/think/Lang.php new file mode 100755 index 0000000..a4404f1 --- /dev/null +++ b/thinkphp/library/think/Lang.php @@ -0,0 +1,223 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Lang +{ + // 语言数据 + private static $lang = []; + // 语言作用域 + private static $range = 'zh-cn'; + // 语言自动侦测的变量 + protected static $langDetectVar = 'lang'; + // 语言Cookie变量 + protected static $langCookieVar = 'think_var'; + // 语言Cookie的过期时间 + protected static $langCookieExpire = 3600; + // 允许语言列表 + protected static $allowLangList = []; + // Accept-Language转义为对应语言包名称 系统默认配置 + protected static $acceptLanguage = [ + 'zh-hans-cn' => 'zh-cn', + ]; + + // 设定当前的语言 + public static function range($range = '') + { + if ('' == $range) { + return self::$range; + } else { + self::$range = $range; + } + return self::$range; + } + + /** + * 设置语言定义(不区分大小写) + * @param string|array $name 语言变量 + * @param string $value 语言值 + * @param string $range 语言作用域 + * @return mixed + */ + public static function set($name, $value = null, $range = '') + { + $range = $range ?: self::$range; + // 批量定义 + if (!isset(self::$lang[$range])) { + self::$lang[$range] = []; + } + if (is_array($name)) { + return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range]; + } else { + return self::$lang[$range][strtolower($name)] = $value; + } + } + + /** + * 加载语言定义(不区分大小写) + * @param array|string $file 语言文件 + * @param string $range 语言作用域 + * @return mixed + */ + public static function load($file, $range = '') + { + $range = $range ?: self::$range; + if (!isset(self::$lang[$range])) { + self::$lang[$range] = []; + } + // 批量定义 + if (is_string($file)) { + $file = [$file]; + } + $lang = []; + foreach ($file as $_file) { + if (is_file($_file)) { + // 记录加载信息 + App::$debug && Log::record('[ LANG ] ' . $_file, 'info'); + $_lang = include $_file; + if (is_array($_lang)) { + $lang = array_change_key_case($_lang) + $lang; + } + } + } + if (!empty($lang)) { + self::$lang[$range] = $lang + self::$lang[$range]; + } + return self::$lang[$range]; + } + + /** + * 获取语言定义(不区分大小写) + * @param string|null $name 语言变量 + * @param string $range 语言作用域 + * @return mixed + */ + public static function has($name, $range = '') + { + $range = $range ?: self::$range; + return isset(self::$lang[$range][strtolower($name)]); + } + + /** + * 获取语言定义(不区分大小写) + * @param string|null $name 语言变量 + * @param array $vars 变量替换 + * @param string $range 语言作用域 + * @return mixed + */ + public static function get($name = null, $vars = [], $range = '') + { + $range = $range ?: self::$range; + // 空参数返回所有定义 + if (empty($name)) { + return self::$lang[$range]; + } + $key = strtolower($name); + $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name; + + // 变量解析 + if (!empty($vars) && is_array($vars)) { + /** + * Notes: + * 为了检测的方便,数字索引的判断仅仅是参数数组的第一个元素的key为数字0 + * 数字索引采用的是系统的 sprintf 函数替换,用法请参考 sprintf 函数 + */ + if (key($vars) === 0) { + // 数字索引解析 + array_unshift($vars, $value); + $value = call_user_func_array('sprintf', $vars); + } else { + // 关联索引解析 + $replace = array_keys($vars); + foreach ($replace as &$v) { + $v = "{:{$v}}"; + } + $value = str_replace($replace, $vars, $value); + } + + } + return $value; + } + + /** + * 自动侦测设置获取语言选择 + * @return string + */ + public static function detect() + { + // 自动侦测设置获取语言选择 + $langSet = ''; + + if (isset($_GET[self::$langDetectVar])) { + // url中设置了语言变量 + $langSet = strtolower($_GET[self::$langDetectVar]); + } elseif (isset($_COOKIE[self::$langCookieVar])) { + // Cookie中设置了语言变量 + $langSet = strtolower($_COOKIE[self::$langCookieVar]); + } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + // 自动侦测浏览器语言 + preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches); + $langSet = strtolower($matches[1]); + $acceptLangs = Config::get('header_accept_lang'); + if (isset($acceptLangs[$langSet])) { + $langSet = $acceptLangs[$langSet]; + } elseif (isset(self::$acceptLanguage[$langSet])) { + $langSet = self::$acceptLanguage[$langSet]; + } + } + if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) { + // 合法的语言 + self::$range = $langSet ?: self::$range; + } + return self::$range; + } + + /** + * 设置语言自动侦测的变量 + * @param string $var 变量名称 + * @return void + */ + public static function setLangDetectVar($var) + { + self::$langDetectVar = $var; + } + + /** + * 设置语言的cookie保存变量 + * @param string $var 变量名称 + * @return void + */ + public static function setLangCookieVar($var) + { + self::$langCookieVar = $var; + } + + /** + * 设置语言的cookie的过期时间 + * @param string $expire 过期时间 + * @return void + */ + public static function setLangCookieExpire($expire) + { + self::$langCookieExpire = $expire; + } + + /** + * 设置允许的语言列表 + * @param array $list 语言列表 + * @return void + */ + public static function setAllowLangList($list) + { + self::$allowLangList = $list; + } +} diff --git a/thinkphp/library/think/Loader.php b/thinkphp/library/think/Loader.php new file mode 100755 index 0000000..1432bd4 --- /dev/null +++ b/thinkphp/library/think/Loader.php @@ -0,0 +1,570 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; + +class Loader +{ + protected static $instance = []; + // 类名映射 + protected static $map = []; + + // 命名空间别名 + protected static $namespaceAlias = []; + + // PSR-4 + private static $prefixLengthsPsr4 = []; + private static $prefixDirsPsr4 = []; + private static $fallbackDirsPsr4 = []; + + // PSR-0 + private static $prefixesPsr0 = []; + private static $fallbackDirsPsr0 = []; + + // 自动加载的文件 + private static $autoloadFiles = []; + + // 自动加载 + public static function autoload($class) + { + // 检测命名空间别名 + if (!empty(self::$namespaceAlias)) { + $namespace = dirname($class); + if (isset(self::$namespaceAlias[$namespace])) { + $original = self::$namespaceAlias[$namespace] . '\\' . basename($class); + if (class_exists($original)) { + return class_alias($original, $class, false); + } + } + } + + if ($file = self::findFile($class)) { + + // Win环境严格区分大小写 + if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) { + return false; + } + + __include_file($file); + return true; + } + } + + /** + * 查找文件 + * @param $class + * @return bool + */ + private static function findFile($class) + { + if (!empty(self::$map[$class])) { + // 类库映射 + return self::$map[$class]; + } + + // 查找 PSR-4 + $logicalPathPsr4 = strtr($class, '\\', DS) . EXT; + + $first = $class[0]; + if (isset(self::$prefixLengthsPsr4[$first])) { + foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach (self::$prefixDirsPsr4[$prefix] as $dir) { + if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // 查找 PSR-4 fallback dirs + foreach (self::$fallbackDirsPsr4 as $dir) { + if (is_file($file = $dir . DS . $logicalPathPsr4)) { + return $file; + } + } + + // 查找 PSR-0 + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DS) . EXT; + } + + if (isset(self::$prefixesPsr0[$first])) { + foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (is_file($file = $dir . DS . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // 查找 PSR-0 fallback dirs + foreach (self::$fallbackDirsPsr0 as $dir) { + if (is_file($file = $dir . DS . $logicalPathPsr0)) { + return $file; + } + } + + return self::$map[$class] = false; + } + + // 注册classmap + public static function addClassMap($class, $map = '') + { + if (is_array($class)) { + self::$map = array_merge(self::$map, $class); + } else { + self::$map[$class] = $map; + } + } + + // 注册命名空间 + public static function addNamespace($namespace, $path = '') + { + if (is_array($namespace)) { + foreach ($namespace as $prefix => $paths) { + self::addPsr4($prefix . '\\', rtrim($paths, DS), true); + } + } else { + self::addPsr4($namespace . '\\', rtrim($path, DS), true); + } + } + + // 添加Ps0空间 + private static function addPsr0($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + self::$fallbackDirsPsr0 = array_merge( + (array) $paths, + self::$fallbackDirsPsr0 + ); + } else { + self::$fallbackDirsPsr0 = array_merge( + self::$fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset(self::$prefixesPsr0[$first][$prefix])) { + self::$prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + self::$prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + self::$prefixesPsr0[$first][$prefix] + ); + } else { + self::$prefixesPsr0[$first][$prefix] = array_merge( + self::$prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + // 添加Psr4空间 + private static function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + self::$fallbackDirsPsr4 = array_merge( + (array) $paths, + self::$fallbackDirsPsr4 + ); + } else { + self::$fallbackDirsPsr4 = array_merge( + self::$fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset(self::$prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + self::$prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + self::$prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + self::$prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + self::$prefixDirsPsr4[$prefix] = array_merge( + self::$prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + // 注册命名空间别名 + public static function addNamespaceAlias($namespace, $original = '') + { + if (is_array($namespace)) { + self::$namespaceAlias = array_merge(self::$namespaceAlias, $namespace); + } else { + self::$namespaceAlias[$namespace] = $original; + } + } + + // 注册自动加载机制 + public static function register($autoload = '') + { + // 注册系统自动加载 + spl_autoload_register($autoload ?: 'think\\Loader::autoload', true, true); + // 注册命名空间定义 + self::addNamespace([ + 'think' => LIB_PATH . 'think' . DS, + 'behavior' => LIB_PATH . 'behavior' . DS, + 'traits' => LIB_PATH . 'traits' . DS, + ]); + // 加载类库映射文件 + if (is_file(RUNTIME_PATH . 'classmap' . EXT)) { + self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT)); + } + + // Composer自动加载支持 + if (is_dir(VENDOR_PATH . 'composer')) { + self::registerComposerLoader(); + } + + // 自动加载extend目录 + self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS); + } + + // 注册composer自动加载 + private static function registerComposerLoader() + { + if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) { + $map = require VENDOR_PATH . 'composer/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + self::addPsr0($namespace, $path); + } + } + + if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) { + $map = require VENDOR_PATH . 'composer/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + self::addPsr4($namespace, $path); + } + } + + if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) { + $classMap = require VENDOR_PATH . 'composer/autoload_classmap.php'; + if ($classMap) { + self::addClassMap($classMap); + } + } + + if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) { + $includeFiles = require VENDOR_PATH . 'composer/autoload_files.php'; + foreach ($includeFiles as $fileIdentifier => $file) { + if (empty(self::$autoloadFiles[$fileIdentifier])) { + __require_file($file); + self::$autoloadFiles[$fileIdentifier] = true; + } + } + } + } + + /** + * 导入所需的类库 同java的Import 本函数有缓存功能 + * @param string $class 类库命名空间字符串 + * @param string $baseUrl 起始路径 + * @param string $ext 导入的文件扩展名 + * @return boolean + */ + public static function import($class, $baseUrl = '', $ext = EXT) + { + static $_file = []; + $key = $class . $baseUrl; + $class = str_replace(['.', '#'], [DS, '.'], $class); + if (isset($_file[$key])) { + return true; + } + + if (empty($baseUrl)) { + list($name, $class) = explode(DS, $class, 2); + + if (isset(self::$prefixDirsPsr4[$name . '\\'])) { + // 注册的命名空间 + $baseUrl = self::$prefixDirsPsr4[$name . '\\']; + } elseif ('@' == $name) { + //加载当前模块应用类库 + $baseUrl = App::$modulePath; + } elseif (is_dir(EXTEND_PATH . $name)) { + $baseUrl = EXTEND_PATH . $name . DS; + } else { + // 加载其它模块的类库 + $baseUrl = APP_PATH . $name . DS; + } + } elseif (substr($baseUrl, -1) != DS) { + $baseUrl .= DS; + } + // 如果类存在 则导入类库文件 + if (is_array($baseUrl)) { + foreach ($baseUrl as $path) { + $filename = $path . DS . $class . $ext; + if (is_file($filename)) { + break; + } + } + } else { + $filename = $baseUrl . $class . $ext; + } + + if (!empty($filename) && is_file($filename)) { + // 开启调试模式Win环境严格区分大小写 + if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) { + return false; + } + __include_file($filename); + $_file[$key] = true; + return true; + } + return false; + } + + /** + * 实例化(分层)模型 + * @param string $name Model名称 + * @param string $layer 业务层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return object + * @throws ClassNotFoundException + */ + public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common') + { + $guid = $name . $layer; + if (isset(self::$instance[$guid])) { + return self::$instance[$guid]; + } + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); + if (class_exists($class)) { + $model = new $class(); + } else { + $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); + if (class_exists($class)) { + $model = new $class(); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + } + self::$instance[$guid] = $model; + return $model; + } + + /** + * 实例化(分层)控制器 格式:[模块名/]控制器名 + * @param string $name 资源地址 + * @param string $layer 控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $empty 空控制器名称 + * @return object + * @throws ClassNotFoundException + */ + public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '') + { + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix); + if (class_exists($class)) { + return App::invokeClass($class); + } elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) { + return new $emptyClass(Request::instance()); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + } + + /** + * 实例化验证类 格式:[模块名/]验证器名 + * modify by GZShangTao + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @param string $common 公共模块名 + * @return object|false + * @throws ClassNotFoundException + */ + public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common',$otherNamespace = '') + { + $name = $name ?: Config::get('default_validate'); + if (empty($name)) { + return new Validate; + } + $guid = $name . $layer; + if (isset(self::$instance[$guid])) { + return self::$instance[$guid]; + } + list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix,$otherNamespace); + if (class_exists($class)) { + $validate = new $class; + } else { + $class = str_replace('\\' . $module . '\\', '\\' . $common . '\\', $class); + if (class_exists($class)) { + $validate = new $class; + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + } + self::$instance[$guid] = $validate; + return $validate; + } + + /** + * 解析模块和类名 + * modify by GZShangTao + * @param string $name 资源地址 + * @param string $layer 验证层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return array + */ + protected static function getModuleAndClass($name, $layer, $appendSuffix,$otherNamespace = '') + { + if (false !== strpos($name, '\\')) { + $module = Request::instance()->module(); + $class = $name; + } else { + if (strpos($name, '/')) { + list($module, $name) = explode('/', $name, 2); + } else { + $module = Request::instance()->module(); + } + $class = self::parseClass($module, $layer, $name, $appendSuffix,$otherNamespace); + } + return [$module, $class]; + } + + /** + * 数据库初始化 并取得数据库类实例 + * @param mixed $config 数据库配置 + * @param bool|string $name 连接标识 true 强制重新连接 + * @return \think\db\Connection + */ + public static function db($config = [], $name = false) + { + return Db::connect($config, $name); + } + + /** + * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作 + * @param string $url 调用地址 + * @param string|array $vars 调用参数 支持字符串和数组 + * @param string $layer 要调用的控制层名称 + * @param bool $appendSuffix 是否添加类名后缀 + * @return mixed + */ + public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false) + { + $info = pathinfo($url); + $action = $info['basename']; + $module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller(); + $class = self::controller($module, $layer, $appendSuffix); + if ($class) { + if (is_scalar($vars)) { + if (strpos($vars, '=')) { + parse_str($vars, $vars); + } else { + $vars = [$vars]; + } + } + return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars); + } + } + + /** + * 字符串命名风格转换 + * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格 + * @param string $name 字符串 + * @param integer $type 转换类型 + * @param bool $ucfirst 首字母是否大写(驼峰规则) + * @return string + */ + public static function parseName($name, $type = 0, $ucfirst = true) + { + if ($type) { + $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { + return strtoupper($match[1]); + }, $name); + return $ucfirst ? ucfirst($name) : lcfirst($name); + } else { + return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); + } + } + + /** + * 解析应用类的类名 + * modify by GZShangTao + * @param string $module 模块名 + * @param string $layer 层名 controller model ... + * @param string $name 类名 + * @param bool $appendSuffix + * @return string + */ + public static function parseClass($module, $layer, $name, $appendSuffix = false,$otherNamespace = '') + { + $name = str_replace(['/', '.'], '\\', $name); + $array = explode('\\', $name); + $class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : ''); + $path = $array ? implode('\\', $array) . '\\' : ''; + if($otherNamespace!=''){ + return $otherNamespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class; + }else{ + return App::$namespace . '\\' . ($module ? $module . '\\' : '') . $layer . '\\' . $path . $class; + } + } + + /** + * 初始化类的实例 + * @return void + */ + public static function clearInstance() + { + self::$instance = []; + } +} + +/** + * 作用范围隔离 + * + * @param $file + * @return mixed + */ +function __include_file($file) +{ + return include $file; +} + +function __require_file($file) +{ + return require $file; +} diff --git a/thinkphp/library/think/Log.php b/thinkphp/library/think/Log.php new file mode 100755 index 0000000..a20ab26 --- /dev/null +++ b/thinkphp/library/think/Log.php @@ -0,0 +1,213 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; + +/** + * Class Log + * @package think + * + * @method void log($msg) static + * @method void error($msg) static + * @method void info($msg) static + * @method void sql($msg) static + * @method void notice($msg) static + * @method void alert($msg) static + */ +class Log +{ + const LOG = 'log'; + const ERROR = 'error'; + const INFO = 'info'; + const SQL = 'sql'; + const NOTICE = 'notice'; + const ALERT = 'alert'; + const DEBUG = 'debug'; + + // 日志信息 + protected static $log = []; + // 配置参数 + protected static $config = []; + // 日志类型 + protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug']; + // 日志写入驱动 + protected static $driver; + + // 当前日志授权key + protected static $key; + + /** + * 日志初始化 + * @param array $config + */ + public static function init($config = []) + { + $type = isset($config['type']) ? $config['type'] : 'File'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\log\\driver\\' . ucwords($type); + self::$config = $config; + unset($config['type']); + if (class_exists($class)) { + self::$driver = new $class($config); + } else { + throw new ClassNotFoundException('class not exists:' . $class, $class); + } + // 记录初始化信息 + App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info'); + } + + /** + * 获取日志信息 + * @param string $type 信息类型 + * @return array + */ + public static function getLog($type = '') + { + return $type ? self::$log[$type] : self::$log; + } + + /** + * 记录调试信息 + * @param mixed $msg 调试信息 + * @param string $type 信息类型 + * @return void + */ + public static function record($msg, $type = 'log') + { + self::$log[$type][] = $msg; + if (IS_CLI) { + // 命令行下面日志写入改进 + self::save(); + } + } + + /** + * 清空日志信息 + * @return void + */ + public static function clear() + { + self::$log = []; + } + + /** + * 当前日志记录的授权key + * @param string $key 授权key + * @return void + */ + public static function key($key) + { + self::$key = $key; + } + + /** + * 检查日志写入权限 + * @param array $config 当前日志配置参数 + * @return bool + */ + public static function check($config) + { + if (self::$key && !empty($config['allow_key']) && !in_array(self::$key, $config['allow_key'])) { + return false; + } + return true; + } + + /** + * 保存调试信息 + * @return bool + */ + public static function save() + { + if (!empty(self::$log)) { + if (is_null(self::$driver)) { + self::init(Config::get('log')); + } + + if (!self::check(self::$config)) { + // 检测日志写入权限 + return false; + } + + if (empty(self::$config['level'])) { + // 获取全部日志 + $log = self::$log; + if (!App::$debug && isset($log['debug'])) { + unset($log['debug']); + } + } else { + // 记录允许级别 + $log = []; + foreach (self::$config['level'] as $level) { + if (isset(self::$log[$level])) { + $log[$level] = self::$log[$level]; + } + } + } + + $result = self::$driver->save($log); + if ($result) { + self::$log = []; + } + Hook::listen('log_write_done', $log); + return $result; + } + return true; + } + + /** + * 实时写入日志信息 并支持行为 + * @param mixed $msg 调试信息 + * @param string $type 信息类型 + * @param bool $force 是否强制写入 + * @return bool + */ + public static function write($msg, $type = 'log', $force = false) + { + $log = self::$log; + // 封装日志信息 + if (true === $force || empty(self::$config['level'])) { + $log[$type][] = $msg; + } elseif (in_array($type, self::$config['level'])) { + $log[$type][] = $msg; + } else { + return false; + } + + // 监听log_write + Hook::listen('log_write', $log); + if (is_null(self::$driver)) { + self::init(Config::get('log')); + } + // 写入日志 + $result = self::$driver->save($log); + if ($result) { + self::$log = []; + } + return $result; + } + + /** + * 静态调用 + * @param $method + * @param $args + * @return mixed + */ + public static function __callStatic($method, $args) + { + if (in_array($method, self::$type)) { + array_push($args, $method); + return call_user_func_array('\\think\\Log::record', $args); + } + } + +} diff --git a/thinkphp/library/think/Model.php b/thinkphp/library/think/Model.php new file mode 100755 index 0000000..d7f91db --- /dev/null +++ b/thinkphp/library/think/Model.php @@ -0,0 +1,2268 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use BadMethodCallException; +use InvalidArgumentException; +use think\db\Query; +use think\exception\ValidateException; +use think\model\Collection as ModelCollection; +use think\model\Relation; +use think\model\relation\BelongsTo; +use think\model\relation\BelongsToMany; +use think\model\relation\HasMany; +use think\model\relation\HasManyThrough; +use think\model\relation\HasOne; +use think\model\relation\MorphMany; +use think\model\relation\MorphOne; +use think\model\relation\MorphTo; + +/** + * Class Model + * @package think + * @mixin Query + */ +abstract class Model implements \JsonSerializable, \ArrayAccess +{ + // 数据库查询对象池 + protected static $links = []; + // 数据库配置 + protected $connection = []; + // 父关联模型对象 + protected $parent; + // 数据库查询对象 + protected $query; + // 当前模型名称 + protected $name; + // 数据表名称 + protected $table; + // 当前类名称 + protected $class; + // 回调事件 + private static $event = []; + // 错误信息 + protected $error; + // 字段验证规则 + protected $validate; + // 数据表主键 复合主键使用数组定义 不设置则自动获取 + protected $pk; + // 数据表字段信息 留空则自动获取 + protected $field = []; + // 数据排除字段 + protected $except = []; + // 数据废弃字段 + protected $disuse = []; + // 只读字段 + protected $readonly = []; + // 显示属性 + protected $visible = []; + // 隐藏属性 + protected $hidden = []; + // 追加属性 + protected $append = []; + // 数据信息 + protected $data = []; + // 原始数据 + protected $origin = []; + // 关联模型 + protected $relation = []; + + // 保存自动完成列表 + protected $auto = []; + // 新增自动完成列表 + protected $insert = []; + // 更新自动完成列表 + protected $update = []; + // 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型 + protected $autoWriteTimestamp; + // 创建时间字段 + protected $createTime = 'create_time'; + // 更新时间字段 + protected $updateTime = 'update_time'; + // 时间字段取出后的默认时间格式 + protected $dateFormat; + // 字段类型或者格式转换 + protected $type = []; + // 是否为更新数据 + protected $isUpdate = false; + // 更新条件 + protected $updateWhere; + // 验证失败是否抛出异常 + protected $failException = false; + // 全局查询范围 + protected $useGlobalScope = true; + // 是否采用批量验证 + protected $batchValidate = false; + // 查询数据集对象 + protected $resultSetType; + // 关联自动写入 + protected $relationWrite; + + /** + * 初始化过的模型. + * + * @var array + */ + protected static $initialized = []; + + /** + * 构造方法 + * @access public + * @param array|object $data 数据 + */ + public function __construct($data = []) + { + if (is_object($data)) { + $this->data = get_object_vars($data); + } else { + $this->data = $data; + } + + if ($this->disuse) { + // 废弃字段 + foreach ((array) $this->disuse as $key) { + if (isset($this->data[$key])) { + unset($this->data[$key]); + } + } + } + + // 记录原始数据 + $this->origin = $this->data; + + // 当前类名 + $this->class = get_called_class(); + + if (empty($this->name)) { + // 当前模型名 + $name = str_replace('\\', '/', $this->class); + $this->name = basename($name); + if (Config::get('class_suffix')) { + $suffix = basename(dirname($name)); + $this->name = substr($this->name, 0, -strlen($suffix)); + } + } + + if (is_null($this->autoWriteTimestamp)) { + // 自动写入时间戳 + $this->autoWriteTimestamp = $this->getQuery()->getConfig('auto_timestamp'); + } + + if (is_null($this->dateFormat)) { + // 设置时间戳格式 + $this->dateFormat = $this->getQuery()->getConfig('datetime_format'); + } + + if (is_null($this->resultSetType)) { + $this->resultSetType = $this->getQuery()->getConfig('resultset_type'); + } + // 执行初始化操作 + $this->initialize(); + } + + /** + * 创建模型的查询对象 + * @access protected + * @return Query + */ + protected function buildQuery() + { + // 合并数据库配置 + if (!empty($this->connection)) { + if (is_array($this->connection)) { + $connection = array_merge(Config::get('database'), $this->connection); + } else { + $connection = $this->connection; + } + } else { + $connection = []; + } + + $con = Db::connect($connection); + // 设置当前模型 确保查询返回模型对象 + $queryClass = $this->query ?: $con->getConfig('query'); + $query = new $queryClass($con, $this->class); + + // 设置当前数据表和模型名 + if (!empty($this->table)) { + $query->setTable($this->table); + } else { + $query->name($this->name); + } + + if (!empty($this->pk)) { + $query->pk($this->pk); + } + + return $query; + } + + /** + * 获取当前模型的查询对象 + * @access public + * @param bool $buildNewQuery 创建新的查询对象 + * @return Query + */ + public function getQuery($buildNewQuery = false) + { + if ($buildNewQuery) { + return $this->buildQuery(); + } elseif (!isset(self::$links[$this->class])) { + // 创建模型查询对象 + self::$links[$this->class] = $this->buildQuery(); + } + + return self::$links[$this->class]; + } + + /** + * 获取当前模型的数据库查询对象 + * @access public + * @param bool $useBaseQuery 是否调用全局查询范围 + * @param bool $buildNewQuery 创建新的查询对象 + * @return Query + */ + public function db($useBaseQuery = true, $buildNewQuery = true) + { + $query = $this->getQuery($buildNewQuery); + + // 全局作用域 + if ($useBaseQuery && method_exists($this, 'base')) { + call_user_func_array([$this, 'base'], [ & $query]); + } + + // 返回当前模型的数据库查询对象 + return $query; + } + + /** + * 初始化模型 + * @access protected + * @return void + */ + protected function initialize() + { + $class = get_class($this); + if (!isset(static::$initialized[$class])) { + static::$initialized[$class] = true; + static::init(); + } + } + + /** + * 初始化处理 + * @access protected + * @return void + */ + protected static function init() + { + } + + /** + * 设置父关联对象 + * @access public + * @param Model $model 模型对象 + * @return $this + */ + public function setParent($model) + { + $this->parent = $model; + return $this; + } + + /** + * 获取父关联对象 + * @access public + * @return Model + */ + public function getParent() + { + return $this->parent; + } + + /** + * 设置数据对象值 + * @access public + * @param mixed $data 数据或者属性名 + * @param mixed $value 值 + * @return $this + */ + public function data($data, $value = null) + { + if (is_string($data)) { + $this->data[$data] = $value; + } else { + // 清空数据 + $this->data = []; + if (is_object($data)) { + $data = get_object_vars($data); + } + if (true === $value) { + // 数据对象赋值 + foreach ($data as $key => $value) { + $this->setAttr($key, $value, $data); + } + } else { + $this->data = $data; + } + } + return $this; + } + + /** + * 获取对象原始数据 如果不存在指定字段返回false + * @access public + * @param string $name 字段名 留空获取全部 + * @return mixed + * @throws InvalidArgumentException + */ + public function getData($name = null) + { + if (is_null($name)) { + return $this->data; + } elseif (array_key_exists($name, $this->data)) { + return $this->data[$name]; + } elseif (array_key_exists($name, $this->relation)) { + return $this->relation[$name]; + } else { + throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); + } + } + + /** + * 是否需要自动写入时间字段 + * @access public + * @param bool $auto + * @return $this + */ + public function isAutoWriteTimestamp($auto) + { + $this->autoWriteTimestamp = $auto; + return $this; + } + + /** + * 修改器 设置数据对象值 + * @access public + * @param string $name 属性名 + * @param mixed $value 属性值 + * @param array $data 数据 + * @return $this + */ + public function setAttr($name, $value, $data = []) + { + if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) { + // 自动写入的时间戳字段 + $value = $this->autoWriteTimestamp($name); + } else { + // 检测修改器 + $method = 'set' . Loader::parseName($name, 1) . 'Attr'; + if (method_exists($this, $method)) { + $value = $this->$method($value, array_merge($this->data, $data), $this->relation); + } elseif (isset($this->type[$name])) { + // 类型转换 + $value = $this->writeTransform($value, $this->type[$name]); + } + } + + // 设置数据对象属性 + $this->data[$name] = $value; + return $this; + } + + /** + * 获取当前模型的关联模型数据 + * @access public + * @param string $name 关联方法名 + * @return mixed + */ + public function getRelation($name = null) + { + if (is_null($name)) { + return $this->relation; + } elseif (array_key_exists($name, $this->relation)) { + return $this->relation[$name]; + } else { + return; + } + } + + /** + * 设置关联数据对象值 + * @access public + * @param string $name 属性名 + * @param mixed $value 属性值 + * @return $this + */ + public function setRelation($name, $value) + { + $this->relation[$name] = $value; + return $this; + } + + /** + * 自动写入时间戳 + * @access public + * @param string $name 时间戳字段 + * @return mixed + */ + protected function autoWriteTimestamp($name) + { + if (isset($this->type[$name])) { + $type = $this->type[$name]; + if (strpos($type, ':')) { + list($type, $param) = explode(':', $type, 2); + } + switch ($type) { + case 'datetime': + case 'date': + $format = !empty($param) ? $param : $this->dateFormat; + $value = $this->formatDateTime(time(), $format); + break; + case 'timestamp': + case 'integer': + default: + $value = time(); + break; + } + } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [ + 'datetime', + 'date', + 'timestamp', + ]) + ) { + $value = $this->formatDateTime(time(), $this->dateFormat); + } else { + $value = $this->formatDateTime(time(), $this->dateFormat, true); + } + return $value; + } + + /** + * 时间日期字段格式化处理 + * @access public + * @param mixed $time 时间日期表达式 + * @param mixed $format 日期格式 + * @param bool $timestamp 是否进行时间戳转换 + * @return mixed + */ + protected function formatDateTime($time, $format, $timestamp = false) + { + if (false !== strpos($format, '\\')) { + $time = new $format($time); + } elseif (!$timestamp && false !== $format) { + $time = date($format, $time); + } + return $time; + } + + /** + * 数据写入 类型转换 + * @access public + * @param mixed $value 值 + * @param string|array $type 要转换的类型 + * @return mixed + */ + protected function writeTransform($value, $type) + { + if (is_null($value)) { + return; + } + + if (is_array($type)) { + list($type, $param) = $type; + } elseif (strpos($type, ':')) { + list($type, $param) = explode(':', $type, 2); + } + switch ($type) { + case 'integer': + $value = (int) $value; + break; + case 'float': + if (empty($param)) { + $value = (float) $value; + } else { + $value = (float) number_format($value, $param, '.', ''); + } + break; + case 'boolean': + $value = (bool) $value; + break; + case 'timestamp': + if (!is_numeric($value)) { + $value = strtotime($value); + } + break; + case 'datetime': + $format = !empty($param) ? $param : $this->dateFormat; + $value = is_numeric($value) ? $value : strtotime($value); + $value = $this->formatDateTime($value, $format); + break; + case 'object': + if (is_object($value)) { + $value = json_encode($value, JSON_FORCE_OBJECT); + } + break; + case 'array': + $value = (array) $value; + case 'json': + $option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE; + $value = json_encode($value, $option); + break; + case 'serialize': + $value = serialize($value); + break; + + } + return $value; + } + + /** + * 获取器 获取数据对象的值 + * @access public + * @param string $name 名称 + * @return mixed + * @throws InvalidArgumentException + */ + public function getAttr($name) + { + try { + $notFound = false; + $value = $this->getData($name); + } catch (InvalidArgumentException $e) { + $notFound = true; + $value = null; + } + + // 检测属性获取器 + $method = 'get' . Loader::parseName($name, 1) . 'Attr'; + if (method_exists($this, $method)) { + $value = $this->$method($value, $this->data, $this->relation); + } elseif (isset($this->type[$name])) { + // 类型转换 + $value = $this->readTransform($value, $this->type[$name]); + } elseif (in_array($name, [$this->createTime, $this->updateTime])) { + if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [ + 'datetime', + 'date', + 'timestamp', + ]) + ) { + $value = $this->formatDateTime(strtotime($value), $this->dateFormat); + } else { + $value = $this->formatDateTime($value, $this->dateFormat); + } + } elseif ($notFound) { + $relation = Loader::parseName($name, 1, false); + if (method_exists($this, $relation)) { + $modelRelation = $this->$relation(); + // 不存在该字段 获取关联数据 + $value = $this->getRelationData($modelRelation); + // 保存关联对象值 + $this->relation[$name] = $value; + } else { + throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); + } + } + return $value; + } + + /** + * 获取关联模型数据 + * @access public + * @param Relation $modelRelation 模型关联对象 + * @return mixed + * @throws BadMethodCallException + */ + protected function getRelationData(Relation $modelRelation) + { + if ($this->parent && get_class($this->parent) == $modelRelation->getModel()) { + $value = $this->parent; + } else { + // 首先获取关联数据 + if (method_exists($modelRelation, 'getRelation')) { + $value = $modelRelation->getRelation(); + } else { + throw new BadMethodCallException('method not exists:' . get_class($modelRelation) . '-> getRelation'); + } + } + return $value; + } + + /** + * 数据读取 类型转换 + * @access public + * @param mixed $value 值 + * @param string|array $type 要转换的类型 + * @return mixed + */ + protected function readTransform($value, $type) + { + if (is_null($value)) { + return; + } + + if (is_array($type)) { + list($type, $param) = $type; + } elseif (strpos($type, ':')) { + list($type, $param) = explode(':', $type, 2); + } + switch ($type) { + case 'integer': + $value = (int) $value; + break; + case 'float': + if (empty($param)) { + $value = (float) $value; + } else { + $value = (float) number_format($value, $param, '.', ''); + } + break; + case 'boolean': + $value = (bool) $value; + break; + case 'timestamp': + if (!is_null($value)) { + $format = !empty($param) ? $param : $this->dateFormat; + $value = $this->formatDateTime($value, $format); + } + break; + case 'datetime': + if (!is_null($value)) { + $format = !empty($param) ? $param : $this->dateFormat; + $value = $this->formatDateTime(strtotime($value), $format); + } + break; + case 'json': + $value = json_decode($value, true); + break; + case 'array': + $value = empty($value) ? [] : json_decode($value, true); + break; + case 'object': + $value = empty($value) ? new \stdClass() : json_decode($value); + break; + case 'serialize': + $value = unserialize($value); + break; + default: + if (false !== strpos($type, '\\')) { + // 对象类型 + $value = new $type($value); + } + } + return $value; + } + + /** + * 设置需要追加的输出属性 + * @access public + * @param array $append 属性列表 + * @param bool $override 是否覆盖 + * @return $this + */ + public function append($append = [], $override = false) + { + $this->append = $override ? $append : array_merge($this->append, $append); + return $this; + } + + /** + * 设置附加关联对象的属性 + * @access public + * @param string $relation 关联方法 + * @param string|array $append 追加属性名 + * @return $this + * @throws Exception + */ + public function appendRelationAttr($relation, $append) + { + if (is_string($append)) { + $append = explode(',', $append); + } + + $relation = Loader::parseName($relation, 1, false); + + // 获取关联数据 + if (isset($this->relation[$relation])) { + $model = $this->relation[$relation]; + } else { + $model = $this->getRelationData($this->$relation()); + } + + if ($model instanceof Model) { + foreach ($append as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; + if (isset($this->data[$key])) { + throw new Exception('bind attr has exists:' . $key); + } else { + $this->data[$key] = $model->getAttr($attr); + } + } + } + return $this; + } + + /** + * 设置需要隐藏的输出属性 + * @access public + * @param array $hidden 属性列表 + * @param bool $override 是否覆盖 + * @return $this + */ + public function hidden($hidden = [], $override = false) + { + $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden); + return $this; + } + + /** + * 设置需要输出的属性 + * @access public + * @param array $visible + * @param bool $override 是否覆盖 + * @return $this + */ + public function visible($visible = [], $override = false) + { + $this->visible = $override ? $visible : array_merge($this->visible, $visible); + return $this; + } + + /** + * 解析隐藏及显示属性 + * @access protected + * @param array $attrs 属性 + * @param array $result 结果集 + * @param bool $visible + * @return array + */ + protected function parseAttr($attrs, &$result, $visible = true) + { + $array = []; + foreach ($attrs as $key => $val) { + if (is_array($val)) { + if ($visible) { + $array[] = $key; + } + $result[$key] = $val; + } elseif (strpos($val, '.')) { + list($key, $name) = explode('.', $val); + if ($visible) { + $array[] = $key; + } + $result[$key][] = $name; + } else { + $array[] = $val; + } + } + return $array; + } + + /** + * 转换子模型对象 + * @access protected + * @param Model|ModelCollection $model + * @param $visible + * @param $hidden + * @param $key + * @return array + */ + protected function subToArray($model, $visible, $hidden, $key) + { + // 关联模型对象 + if (isset($visible[$key])) { + $model->visible($visible[$key]); + } elseif (isset($hidden[$key])) { + $model->hidden($hidden[$key]); + } + return $model->toArray(); + } + + /** + * 转换当前模型对象为数组 + * @access public + * @return array + */ + public function toArray() + { + $item = []; + $visible = []; + $hidden = []; + + $data = array_merge($this->data, $this->relation); + + // 过滤属性 + if (!empty($this->visible)) { + $array = $this->parseAttr($this->visible, $visible); + $data = array_intersect_key($data, array_flip($array)); + } elseif (!empty($this->hidden)) { + $array = $this->parseAttr($this->hidden, $hidden, false); + $data = array_diff_key($data, array_flip($array)); + } + + foreach ($data as $key => $val) { + if ($val instanceof Model || $val instanceof ModelCollection) { + // 关联模型对象 + $item[$key] = $this->subToArray($val, $visible, $hidden, $key); + } elseif (is_array($val) && reset($val) instanceof Model) { + // 关联模型数据集 + $arr = []; + foreach ($val as $k => $value) { + $arr[$k] = $this->subToArray($value, $visible, $hidden, $key); + } + $item[$key] = $arr; + } else { + // 模型属性 + $item[$key] = $this->getAttr($key); + } + } + // 追加属性(必须定义获取器) + if (!empty($this->append)) { + foreach ($this->append as $key => $name) { + if (is_array($name)) { + // 追加关联对象属性 + $relation = $this->getAttr($key); + $item[$key] = $relation->append($name)->toArray(); + } elseif (strpos($name, '.')) { + list($key, $attr) = explode('.', $name); + // 追加关联对象属性 + $relation = $this->getAttr($key); + $item[$key] = $relation->append([$attr])->toArray(); + } else { + $relation = Loader::parseName($name, 1, false); + if (method_exists($this, $relation)) { + $modelRelation = $this->$relation(); + $value = $this->getRelationData($modelRelation); + + if (method_exists($modelRelation, 'getBindAttr')) { + $bindAttr = $modelRelation->getBindAttr(); + if ($bindAttr) { + foreach ($bindAttr as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; + if (isset($this->data[$key])) { + throw new Exception('bind attr has exists:' . $key); + } else { + $item[$key] = $value ? $value->getAttr($attr) : null; + } + } + continue; + } + } + $item[$name] = $value; + } else { + $item[$name] = $this->getAttr($name); + } + } + } + } + return !empty($item) ? $item : []; + } + + /** + * 转换当前模型对象为JSON字符串 + * @access public + * @param integer $options json参数 + * @return string + */ + public function toJson($options = JSON_UNESCAPED_UNICODE) + { + return json_encode($this->toArray(), $options); + } + + /** + * 移除当前模型的关联属性 + * @access public + * @return $this + */ + public function removeRelation() + { + $this->relation = []; + return $this; + } + + /** + * 转换当前模型数据集为数据集对象 + * @access public + * @param array|\think\Collection $collection 数据集 + * @return \think\Collection + */ + public function toCollection($collection) + { + if ($this->resultSetType) { + if ('collection' == $this->resultSetType) { + $collection = new ModelCollection($collection); + } elseif (false !== strpos($this->resultSetType, '\\')) { + $class = $this->resultSetType; + $collection = new $class($collection); + } + } + return $collection; + } + + /** + * 关联数据一起更新 + * @access public + * @param mixed $relation 关联 + * @return $this + */ + public function together($relation) + { + if (is_string($relation)) { + $relation = explode(',', $relation); + } + $this->relationWrite = $relation; + return $this; + } + + /** + * 获取模型对象的主键 + * @access public + * @param string $name 模型名 + * @return mixed + */ + public function getPk($name = '') + { + if (!empty($name)) { + $table = $this->getQuery()->getTable($name); + return $this->getQuery()->getPk($table); + } elseif (empty($this->pk)) { + $this->pk = $this->getQuery()->getPk(); + } + return $this->pk; + } + + /** + * 判断一个字段名是否为主键字段 + * @access public + * @param string $key 名称 + * @return bool + */ + protected function isPk($key) + { + $pk = $this->getPk(); + if (is_string($pk) && $pk == $key) { + return true; + } elseif (is_array($pk) && in_array($key, $pk)) { + return true; + } + return false; + } + + /** + * 保存当前数据对象 + * @access public + * @param array $data 数据 + * @param array $where 更新条件 + * @param string $sequence 自增序列名 + * @return integer|false + */ + public function save($data = [], $where = [], $sequence = null) + { + if (is_string($data)) { + $sequence = $data; + $data = []; + } + + if (!empty($data)) { + // 数据自动验证 + if (!$this->validateData($data)) { + return false; + } + // 数据对象赋值 + foreach ($data as $key => $value) { + $this->setAttr($key, $value, $data); + } + if (!empty($where)) { + $this->isUpdate = true; + $this->updateWhere = $where; + } + } + + // 自动关联写入 + if (!empty($this->relationWrite)) { + $relation = []; + foreach ($this->relationWrite as $key => $name) { + if (is_array($name)) { + if (key($name) === 0) { + $relation[$key] = []; + foreach ($name as $val) { + if (isset($this->data[$val])) { + $relation[$key][$val] = $this->data[$val]; + unset($this->data[$val]); + } + } + } else { + $relation[$key] = $name; + } + } elseif (isset($this->relation[$name])) { + $relation[$name] = $this->relation[$name]; + } elseif (isset($this->data[$name])) { + $relation[$name] = $this->data[$name]; + unset($this->data[$name]); + } + } + } + + // 数据自动完成 + $this->autoCompleteData($this->auto); + + // 事件回调 + if (false === $this->trigger('before_write', $this)) { + return false; + } + $pk = $this->getPk(); + if ($this->isUpdate) { + // 自动更新 + $this->autoCompleteData($this->update); + + // 事件回调 + if (false === $this->trigger('before_update', $this)) { + return false; + } + + // 获取有更新的数据 + $data = $this->getChangedData(); + + if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) { + // 关联更新 + if (isset($relation)) { + $this->autoRelationUpdate($relation); + } + return 0; + } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) { + // 自动写入更新时间 + $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); + $this->data[$this->updateTime] = $data[$this->updateTime]; + } + + if (empty($where) && !empty($this->updateWhere)) { + $where = $this->updateWhere; + } + + // 保留主键数据 + foreach ($this->data as $key => $val) { + if ($this->isPk($key)) { + $data[$key] = $val; + } + } + + if (is_string($pk) && isset($data[$pk])) { + if (!isset($where[$pk])) { + unset($where); + $where[$pk] = $data[$pk]; + } + unset($data[$pk]); + } + + // 检测字段 + $allowFields = $this->checkAllowField(array_merge($this->auto, $this->update)); + + // 模型更新 + if (!empty($allowFields)) { + $result = $this->getQuery()->where($where)->strict(false)->field($allowFields)->update($data); + } else { + $result = $this->getQuery()->where($where)->update($data); + } + + // 关联更新 + if (isset($relation)) { + $this->autoRelationUpdate($relation); + } + + // 更新回调 + $this->trigger('after_update', $this); + + } else { + // 自动写入 + $this->autoCompleteData($this->insert); + + // 自动写入创建时间和更新时间 + if ($this->autoWriteTimestamp) { + if ($this->createTime && !isset($this->data[$this->createTime])) { + $this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime); + } + if ($this->updateTime && !isset($this->data[$this->updateTime])) { + $this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime); + } + } + + if (false === $this->trigger('before_insert', $this)) { + return false; + } + + // 检测字段 + $allowFields = $this->checkAllowField(array_merge($this->auto, $this->insert)); + if (!empty($allowFields)) { + $result = $this->getQuery()->strict(false)->field($allowFields)->insert($this->data); + } else { + $result = $this->getQuery()->insert($this->data); + } + + // 获取自动增长主键 + if ($result && is_string($pk) && (!isset($this->data[$pk]) || '' == $this->data[$pk])) { + $insertId = $this->getQuery()->getLastInsID($sequence); + if ($insertId) { + $this->data[$pk] = $insertId; + } + } + + // 关联写入 + if (isset($relation)) { + foreach ($relation as $name => $val) { + $method = Loader::parseName($name, 1, false); + $this->$method()->save($val); + } + } + + // 标记为更新 + $this->isUpdate = true; + + // 新增回调 + $this->trigger('after_insert', $this); + } + // 写入回调 + $this->trigger('after_write', $this); + + // 重新记录原始数据 + $this->origin = $this->data; + + return $result; + } + + protected function checkAllowField($auto = []) + { + if (true === $this->field) { + $this->field = $this->getQuery()->getTableInfo('', 'fields'); + $field = $this->field; + } elseif (!empty($this->field)) { + $field = array_merge($this->field, $auto); + if ($this->autoWriteTimestamp) { + array_push($field, $this->createTime, $this->updateTime); + } + } elseif (!empty($this->except)) { + $fields = $this->getQuery()->getTableInfo('', 'fields'); + $field = array_diff($fields, (array) $this->except); + $this->field = $field; + } else { + $field = []; + } + + if ($this->disuse) { + // 废弃字段 + $field = array_diff($field, (array) $this->disuse); + } + return $field; + } + + protected function autoRelationUpdate($relation) + { + foreach ($relation as $name => $val) { + if ($val instanceof Model) { + $val->save(); + } else { + unset($this->data[$name]); + $model = $this->getAttr($name); + if ($model instanceof Model) { + $model->save($val); + } + } + } + } + + /** + * 获取变化的数据 并排除只读数据 + * @access public + * @return array + */ + public function getChangedData() + { + $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) { + if ((empty($a) || empty($b)) && $a !== $b) { + return 1; + } + return is_object($a) || $a != $b ? 1 : 0; + }); + + if (!empty($this->readonly)) { + // 只读字段不允许更新 + foreach ($this->readonly as $key => $field) { + if (isset($data[$field])) { + unset($data[$field]); + } + } + } + + return $data; + } + + /** + * 字段值(延迟)增长 + * @access public + * @param string $field 字段名 + * @param integer $step 增长值 + * @param integer $lazyTime 延时时间(s) + * @return integer|true + * @throws Exception + */ + public function setInc($field, $step = 1, $lazyTime = 0) + { + // 更新条件 + $where = $this->getWhere(); + + $result = $this->getQuery()->where($where)->setInc($field, $step, $lazyTime); + if (true !== $result) { + $this->data[$field] += $step; + } + + return $result; + } + + /** + * 字段值(延迟)增长 + * @access public + * @param string $field 字段名 + * @param integer $step 增长值 + * @param integer $lazyTime 延时时间(s) + * @return integer|true + * @throws Exception + */ + public function setDec($field, $step = 1, $lazyTime = 0) + { + // 更新条件 + $where = $this->getWhere(); + $result = $this->getQuery()->where($where)->setDec($field, $step, $lazyTime); + if (true !== $result) { + $this->data[$field] -= $step; + } + + return $result; + } + + /** + * 获取更新条件 + * @access protected + * @return mixed + */ + protected function getWhere() + { + // 删除条件 + $pk = $this->getPk(); + + if (is_string($pk) && isset($this->data[$pk])) { + $where = [$pk => $this->data[$pk]]; + } elseif (!empty($this->updateWhere)) { + $where = $this->updateWhere; + } else { + $where = null; + } + return $where; + } + + /** + * 保存多个数据到当前数据对象 + * @access public + * @param array $dataSet 数据 + * @param boolean $replace 是否自动识别更新和写入 + * @return array|false + * @throws \Exception + */ + public function saveAll($dataSet, $replace = true) + { + if ($this->validate) { + // 数据批量验证 + $validate = $this->validate; + foreach ($dataSet as $data) { + if (!$this->validateData($data, $validate)) { + return false; + } + } + } + + $result = []; + $db = $this->getQuery(); + $db->startTrans(); + try { + $pk = $this->getPk(); + if (is_string($pk) && $replace) { + $auto = true; + } + foreach ($dataSet as $key => $data) { + if (!empty($auto) && isset($data[$pk])) { + $result[$key] = self::update($data, [], $this->field); + } else { + $result[$key] = self::create($data, $this->field); + } + } + $db->commit(); + return $result; + } catch (\Exception $e) { + $db->rollback(); + throw $e; + } + } + + /** + * 设置允许写入的字段 + * @access public + * @param string|array $field 允许写入的字段 如果为true只允许写入数据表字段 + * @return $this + */ + public function allowField($field) + { + if (is_string($field)) { + $field = explode(',', $field); + } + $this->field = $field; + return $this; + } + + /** + * 设置排除写入的字段 + * @access public + * @param string|array $field 排除允许写入的字段 + * @return $this + */ + public function except($field) + { + if (is_string($field)) { + $field = explode(',', $field); + } + $this->except = $field; + return $this; + } + + /** + * 设置只读字段 + * @access public + * @param mixed $field 只读字段 + * @return $this + */ + public function readonly($field) + { + if (is_string($field)) { + $field = explode(',', $field); + } + $this->readonly = $field; + return $this; + } + + /** + * 是否为更新数据 + * @access public + * @param bool $update + * @param mixed $where + * @return $this + */ + public function isUpdate($update = true, $where = null) + { + $this->isUpdate = $update; + if (!empty($where)) { + $this->updateWhere = $where; + } + return $this; + } + + /** + * 数据自动完成 + * @access public + * @param array $auto 要自动更新的字段列表 + * @return void + */ + protected function autoCompleteData($auto = []) + { + foreach ($auto as $field => $value) { + if (is_integer($field)) { + $field = $value; + $value = null; + } + + if (!isset($this->data[$field])) { + $default = null; + } else { + $default = $this->data[$field]; + } + + $this->setAttr($field, !is_null($value) ? $value : $default); + } + } + + /** + * 删除当前的记录 + * @access public + * @return integer + */ + public function delete() + { + if (false === $this->trigger('before_delete', $this)) { + return false; + } + + // 删除条件 + $where = $this->getWhere(); + + // 删除当前模型数据 + $result = $this->getQuery()->where($where)->delete(); + + // 关联删除 + if (!empty($this->relationWrite)) { + foreach ($this->relationWrite as $key => $name) { + $name = is_numeric($key) ? $name : $key; + $model = $this->getAttr($name); + if ($model instanceof Model) { + $model->delete(); + } + } + } + + $this->trigger('after_delete', $this); + // 清空原始数据 + $this->origin = []; + + return $result; + } + + /** + * 设置自动完成的字段( 规则通过修改器定义) + * @access public + * @param array $fields 需要自动完成的字段 + * @return $this + */ + public function auto($fields) + { + $this->auto = $fields; + return $this; + } + + /** + * 设置字段验证 + * @access public + * @param array|string|bool $rule 验证规则 true表示自动读取验证器类 + * @param array $msg 提示信息 + * @param bool $batch 批量验证 + * @return $this + */ + public function validate($rule = true, $msg = [], $batch = false) + { + if (is_array($rule)) { + $this->validate = [ + 'rule' => $rule, + 'msg' => $msg, + ]; + } else { + $this->validate = true === $rule ? $this->name : $rule; + } + $this->batchValidate = $batch; + return $this; + } + + /** + * 设置验证失败后是否抛出异常 + * @access public + * @param bool $fail 是否抛出异常 + * @return $this + */ + public function validateFailException($fail = true) + { + $this->failException = $fail; + return $this; + } + + /** + * 自动验证数据 + * @access protected + * @param array $data 验证数据 + * @param mixed $rule 验证规则 + * @param bool $batch 批量验证 + * @return bool + */ + protected function validateData($data, $rule = null, $batch = null) + { + $info = is_null($rule) ? $this->validate : $rule; + + if (!empty($info)) { + if (is_array($info)) { + $validate = Loader::validate(); + $validate->rule($info['rule']); + $validate->message($info['msg']); + } else { + $name = is_string($info) ? $info : $this->name; + if (strpos($name, '.')) { + list($name, $scene) = explode('.', $name); + } + $validate = Loader::validate($name); + if (!empty($scene)) { + $validate->scene($scene); + } + } + $batch = is_null($batch) ? $this->batchValidate : $batch; + + if (!$validate->batch($batch)->check($data)) { + $this->error = $validate->getError(); + if ($this->failException) { + throw new ValidateException($this->error); + } else { + return false; + } + } + $this->validate = null; + } + return true; + } + + /** + * 返回模型的错误信息 + * @access public + * @return string|array + */ + public function getError() + { + return $this->error; + } + + /** + * 注册回调方法 + * @access public + * @param string $event 事件名 + * @param callable $callback 回调方法 + * @param bool $override 是否覆盖 + * @return void + */ + public static function event($event, $callback, $override = false) + { + $class = get_called_class(); + if ($override) { + self::$event[$class][$event] = []; + } + self::$event[$class][$event][] = $callback; + } + + /** + * 触发事件 + * @access protected + * @param string $event 事件名 + * @param mixed $params 传入参数(引用) + * @return bool + */ + protected function trigger($event, &$params) + { + if (isset(self::$event[$this->class][$event])) { + foreach (self::$event[$this->class][$event] as $callback) { + if (is_callable($callback)) { + $result = call_user_func_array($callback, [ & $params]); + if (false === $result) { + return false; + } + } + } + } + return true; + } + + /** + * 写入数据 + * @access public + * @param array $data 数据数组 + * @param array|true $field 允许字段 + * @return $this + */ + public static function create($data = [], $field = null) + { + $model = new static(); + if (!empty($field)) { + $model->allowField($field); + } + $model->isUpdate(false)->save($data, []); + return $model; + } + + /** + * 更新数据 + * @access public + * @param array $data 数据数组 + * @param array $where 更新条件 + * @param array|true $field 允许字段 + * @return $this + */ + public static function update($data = [], $where = [], $field = null) + { + $model = new static(); + if (!empty($field)) { + $model->allowField($field); + } + $result = $model->isUpdate(true)->save($data, $where); + return $model; + } + + /** + * 查找单条记录 + * @access public + * @param mixed $data 主键值或者查询条件(闭包) + * @param array|string $with 关联预查询 + * @param bool $cache 是否缓存 + * @return static|null + * @throws exception\DbException + */ + public static function get($data, $with = [], $cache = false) + { + if (is_null($data)) { + return; + } + + if (true === $with || is_int($with)) { + $cache = $with; + $with = []; + } + $query = static::parseQuery($data, $with, $cache); + return $query->find($data); + } + + /** + * 查找所有记录 + * @access public + * @param mixed $data 主键列表或者查询条件(闭包) + * @param array|string $with 关联预查询 + * @param bool $cache 是否缓存 + * @return static[]|false + * @throws exception\DbException + */ + public static function all($data = null, $with = [], $cache = false) + { + if (true === $with || is_int($with)) { + $cache = $with; + $with = []; + } + $query = static::parseQuery($data, $with, $cache); + return $query->select($data); + } + + /** + * 分析查询表达式 + * @access public + * @param mixed $data 主键列表或者查询条件(闭包) + * @param string $with 关联预查询 + * @param bool $cache 是否缓存 + * @return Query + */ + protected static function parseQuery(&$data, $with, $cache) + { + $result = self::with($with)->cache($cache); + if (is_array($data) && key($data) !== 0) { + $result = $result->where($data); + $data = null; + } elseif ($data instanceof \Closure) { + call_user_func_array($data, [ & $result]); + $data = null; + } elseif ($data instanceof Query) { + $result = $data->with($with)->cache($cache); + $data = null; + } + return $result; + } + + /** + * 删除记录 + * @access public + * @param mixed $data 主键列表 支持闭包查询条件 + * @return integer 成功删除的记录数 + */ + public static function destroy($data) + { + $model = new static(); + $query = $model->db(); + if (empty($data) && 0 !== $data) { + return 0; + } elseif (is_array($data) && key($data) !== 0) { + $query->where($data); + $data = null; + } elseif ($data instanceof \Closure) { + call_user_func_array($data, [ & $query]); + $data = null; + } + $resultSet = $query->select($data); + $count = 0; + if ($resultSet) { + foreach ($resultSet as $data) { + $result = $data->delete(); + $count += $result; + } + } + return $count; + } + + /** + * 命名范围 + * @access public + * @param string|array|\Closure $name 命名范围名称 逗号分隔 + * @internal mixed ...$params 参数调用 + * @return Query + */ + public static function scope($name) + { + $model = new static(); + $query = $model->db(); + $params = func_get_args(); + array_shift($params); + array_unshift($params, $query); + if ($name instanceof \Closure) { + call_user_func_array($name, $params); + } elseif (is_string($name)) { + $name = explode(',', $name); + } + if (is_array($name)) { + foreach ($name as $scope) { + $method = 'scope' . trim($scope); + if (method_exists($model, $method)) { + call_user_func_array([$model, $method], $params); + } + } + } + return $query; + } + + /** + * 设置是否使用全局查询范围 + * @param bool $use 是否启用全局查询范围 + * @access public + * @return Query + */ + public static function useGlobalScope($use) + { + $model = new static(); + return $model->db($use); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $relation 关联方法名 + * @param mixed $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @return Relation|Query + */ + public static function has($relation, $operator = '>=', $count = 1, $id = '*') + { + $relation = (new static())->$relation(); + if (is_array($operator) || $operator instanceof \Closure) { + return $relation->hasWhere($operator); + } + return $relation->has($operator, $count, $id); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $relation 关联方法名 + * @param mixed $where 查询条件(数组或者闭包) + * @return Relation|Query + */ + public static function hasWhere($relation, $where = []) + { + return (new static())->$relation()->hasWhere($where); + } + + /** + * 解析模型的完整命名空间 + * @access public + * @param string $model 模型名(或者完整类名) + * @return string + */ + protected function parseModel($model) + { + if (false === strpos($model, '\\')) { + $path = explode('\\', get_called_class()); + array_pop($path); + array_push($path, Loader::parseName($model, 1)); + $model = implode('\\', $path); + } + return $model; + } + + /** + * 查询当前模型的关联数据 + * @access public + * @param string|array $relations 关联名 + * @return $this + */ + public function relationQuery($relations) + { + if (is_string($relations)) { + $relations = explode(',', $relations); + } + + foreach ($relations as $key => $relation) { + $subRelation = ''; + $closure = null; + if ($relation instanceof \Closure) { + // 支持闭包查询过滤关联条件 + $closure = $relation; + $relation = $key; + } + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { + list($relation, $subRelation) = explode('.', $relation, 2); + } + $method = Loader::parseName($relation, 1, false); + $this->data[$relation] = $this->$method()->getRelation($subRelation, $closure); + } + return $this; + } + + /** + * 预载入关联查询 返回数据集 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 关联名 + * @return array + */ + public function eagerlyResultSet(&$resultSet, $relation) + { + $relations = is_string($relation) ? explode(',', $relation) : $relation; + foreach ($relations as $key => $relation) { + $subRelation = ''; + $closure = false; + if ($relation instanceof \Closure) { + $closure = $relation; + $relation = $key; + } + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { + list($relation, $subRelation) = explode('.', $relation, 2); + } + $relation = Loader::parseName($relation, 1, false); + $this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure); + } + } + + /** + * 预载入关联查询 返回模型对象 + * @access public + * @param Model $result 数据对象 + * @param string $relation 关联名 + * @return Model + */ + public function eagerlyResult(&$result, $relation) + { + $relations = is_string($relation) ? explode(',', $relation) : $relation; + + foreach ($relations as $key => $relation) { + $subRelation = ''; + $closure = false; + if ($relation instanceof \Closure) { + $closure = $relation; + $relation = $key; + } + if (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (strpos($relation, '.')) { + list($relation, $subRelation) = explode('.', $relation, 2); + } + $relation = Loader::parseName($relation, 1, false); + $this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure); + } + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param string|array $relation 关联名 + * @return void + */ + public function relationCount(&$result, $relation) + { + $relations = is_string($relation) ? explode(',', $relation) : $relation; + + foreach ($relations as $key => $relation) { + $closure = false; + if ($relation instanceof \Closure) { + $closure = $relation; + $relation = $key; + } elseif (is_string($key)) { + $name = $relation; + $relation = $key; + } + $relation = Loader::parseName($relation, 1, false); + $count = $this->$relation()->relationCount($result, $closure); + if (!isset($name)) { + $name = Loader::parseName($relation) . '_count'; + } + $result->setAttr($name, $count); + } + } + + /** + * 获取模型的默认外键名 + * @access public + * @param string $name 模型名 + * @return string + */ + protected function getForeignKey($name) + { + if (strpos($name, '\\')) { + $name = basename(str_replace('\\', '/', $name)); + } + return Loader::parseName($name) . '_id'; + } + + /** + * HAS ONE 关联定义 + * @access public + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 当前模型主键 + * @param array $alias 别名定义(已经废弃) + * @param string $joinType JOIN类型 + * @return HasOne + */ + public function hasOne($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + $localKey = $localKey ?: $this->getPk(); + $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); + return new HasOne($this, $model, $foreignKey, $localKey, $joinType); + } + + /** + * BELONGS TO 关联定义 + * @access public + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 关联主键 + * @param array $alias 别名定义(已经废弃) + * @param string $joinType JOIN类型 + * @return BelongsTo + */ + public function belongsTo($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + $foreignKey = $foreignKey ?: $this->getForeignKey($model); + $localKey = $localKey ?: (new $model)->getPk(); + $trace = debug_backtrace(false, 2); + $relation = Loader::parseName($trace[1]['function']); + return new BelongsTo($this, $model, $foreignKey, $localKey, $joinType, $relation); + } + + /** + * HAS MANY 关联定义 + * @access public + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 当前模型主键 + * @return HasMany + */ + public function hasMany($model, $foreignKey = '', $localKey = '') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + $localKey = $localKey ?: $this->getPk(); + $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); + return new HasMany($this, $model, $foreignKey, $localKey); + } + + /** + * HAS MANY 远程关联定义 + * @access public + * @param string $model 模型名 + * @param string $through 中间模型名 + * @param string $foreignKey 关联外键 + * @param string $throughKey 关联外键 + * @param string $localKey 当前模型主键 + * @return HasManyThrough + */ + public function hasManyThrough($model, $through, $foreignKey = '', $throughKey = '', $localKey = '') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + $through = $this->parseModel($through); + $localKey = $localKey ?: $this->getPk(); + $foreignKey = $foreignKey ?: $this->getForeignKey($this->name); + $throughKey = $throughKey ?: $this->getForeignKey($through); + return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey); + } + + /** + * BELONGS TO MANY 关联定义 + * @access public + * @param string $model 模型名 + * @param string $table 中间表名 + * @param string $foreignKey 关联外键 + * @param string $localKey 当前模型关联键 + * @return BelongsToMany + */ + public function belongsToMany($model, $table = '', $foreignKey = '', $localKey = '') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + $name = Loader::parseName(basename(str_replace('\\', '/', $model))); + $table = $table ?: Loader::parseName($this->name) . '_' . $name; + $foreignKey = $foreignKey ?: $name . '_id'; + $localKey = $localKey ?: $this->getForeignKey($this->name); + return new BelongsToMany($this, $model, $table, $foreignKey, $localKey); + } + + /** + * MORPH MANY 关联定义 + * @access public + * @param string $model 模型名 + * @param string|array $morph 多态字段信息 + * @param string $type 多态类型 + * @return MorphMany + */ + public function morphMany($model, $morph = null, $type = '') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + if (is_null($morph)) { + $trace = debug_backtrace(false, 2); + $morph = Loader::parseName($trace[1]['function']); + } + $type = $type ?: get_class($this); + if (is_array($morph)) { + list($morphType, $foreignKey) = $morph; + } else { + $morphType = $morph . '_type'; + $foreignKey = $morph . '_id'; + } + return new MorphMany($this, $model, $foreignKey, $morphType, $type); + } + + /** + * MORPH One 关联定义 + * @access public + * @param string $model 模型名 + * @param string|array $morph 多态字段信息 + * @param string $type 多态类型 + * @return MorphOne + */ + public function morphOne($model, $morph = null, $type = '') + { + // 记录当前关联信息 + $model = $this->parseModel($model); + if (is_null($morph)) { + $trace = debug_backtrace(false, 2); + $morph = Loader::parseName($trace[1]['function']); + } + $type = $type ?: get_class($this); + if (is_array($morph)) { + list($morphType, $foreignKey) = $morph; + } else { + $morphType = $morph . '_type'; + $foreignKey = $morph . '_id'; + } + return new MorphOne($this, $model, $foreignKey, $morphType, $type); + } + + /** + * MORPH TO 关联定义 + * @access public + * @param string|array $morph 多态字段信息 + * @param array $alias 多态别名定义 + * @return MorphTo + */ + public function morphTo($morph = null, $alias = []) + { + $trace = debug_backtrace(false, 2); + $relation = Loader::parseName($trace[1]['function']); + + if (is_null($morph)) { + $morph = $relation; + } + // 记录当前关联信息 + if (is_array($morph)) { + list($morphType, $foreignKey) = $morph; + } else { + $morphType = $morph . '_type'; + $foreignKey = $morph . '_id'; + } + return new MorphTo($this, $morphType, $foreignKey, $alias, $relation); + } + + public function __call($method, $args) + { + $query = $this->db(true, false); + if (method_exists($this, 'scope' . $method)) { + // 动态调用命名范围 + $method = 'scope' . $method; + array_unshift($args, $query); + call_user_func_array([$this, $method], $args); + return $this; + } else { + return call_user_func_array([$query, $method], $args); + } + } + + public static function __callStatic($method, $args) + { + $model = new static(); + $query = $model->db(); + if (method_exists($model, 'scope' . $method)) { + // 动态调用命名范围 + $method = 'scope' . $method; + array_unshift($args, $query); + + call_user_func_array([$model, $method], $args); + return $query; + } else { + return call_user_func_array([$query, $method], $args); + } + } + + /** + * 修改器 设置数据对象的值 + * @access public + * @param string $name 名称 + * @param mixed $value 值 + * @return void + */ + public function __set($name, $value) + { + $this->setAttr($name, $value); + } + + /** + * 获取器 获取数据对象的值 + * @access public + * @param string $name 名称 + * @return mixed + */ + public function __get($name) + { + return $this->getAttr($name); + } + + /** + * 检测数据对象的值 + * @access public + * @param string $name 名称 + * @return boolean + */ + public function __isset($name) + { + try { + if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) { + return true; + } else { + $this->getAttr($name); + return true; + } + } catch (InvalidArgumentException $e) { + return false; + } + + } + + /** + * 销毁数据对象的值 + * @access public + * @param string $name 名称 + * @return void + */ + public function __unset($name) + { + unset($this->data[$name], $this->relation[$name]); + } + + public function __toString() + { + return $this->toJson(); + } + + // JsonSerializable + public function jsonSerialize() + { + return $this->toArray(); + } + + // ArrayAccess + public function offsetSet($name, $value) + { + $this->setAttr($name, $value); + } + + public function offsetExists($name) + { + return $this->__isset($name); + } + + public function offsetUnset($name) + { + $this->__unset($name); + } + + public function offsetGet($name) + { + return $this->getAttr($name); + } + + /** + * 解序列化后处理 + */ + public function __wakeup() + { + $this->initialize(); + } + + /** + * 模型事件快捷方法 + * @param $callback + * @param bool $override + */ + protected static function beforeInsert($callback, $override = false) + { + self::event('before_insert', $callback, $override); + } + + protected static function afterInsert($callback, $override = false) + { + self::event('after_insert', $callback, $override); + } + + protected static function beforeUpdate($callback, $override = false) + { + self::event('before_update', $callback, $override); + } + + protected static function afterUpdate($callback, $override = false) + { + self::event('after_update', $callback, $override); + } + + protected static function beforeWrite($callback, $override = false) + { + self::event('before_write', $callback, $override); + } + + protected static function afterWrite($callback, $override = false) + { + self::event('after_write', $callback, $override); + } + + protected static function beforeDelete($callback, $override = false) + { + self::event('before_delete', $callback, $override); + } + + protected static function afterDelete($callback, $override = false) + { + self::event('after_delete', $callback, $override); + } + +} diff --git a/thinkphp/library/think/Paginator.php b/thinkphp/library/think/Paginator.php new file mode 100755 index 0000000..d20b078 --- /dev/null +++ b/thinkphp/library/think/Paginator.php @@ -0,0 +1,409 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think; + +use ArrayAccess; +use ArrayIterator; +use Countable; +use IteratorAggregate; +use JsonSerializable; +use Traversable; + +abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable +{ + /** @var bool 是否为简洁模式 */ + protected $simple = false; + + /** @var Collection 数据集 */ + protected $items; + + /** @var integer 当前页 */ + protected $currentPage; + + /** @var integer 最后一页 */ + protected $lastPage; + + /** @var integer|null 数据总数 */ + protected $total; + + /** @var integer 每页的数量 */ + protected $listRows; + + /** @var bool 是否有下一页 */ + protected $hasMore; + + /** @var array 一些配置 */ + protected $options = [ + 'var_page' => 'page', + 'path' => '/', + 'query' => [], + 'fragment' => '', + ]; + + /** @var mixed simple模式下的下个元素 */ + protected $nextItem; + + public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) + { + $this->options = array_merge($this->options, $options); + + $this->options['path'] = '/' != $this->options['path'] ? rtrim($this->options['path'], '/') : $this->options['path']; + + $this->simple = $simple; + $this->listRows = $listRows; + + if (!$items instanceof Collection) { + $items = Collection::make($items); + } + + if ($simple) { + $this->currentPage = $this->setCurrentPage($currentPage); + $this->hasMore = count($items) > ($this->listRows); + if ($this->hasMore) { + $this->nextItem = $items->slice($this->listRows, 1); + } + $items = $items->slice(0, $this->listRows); + } else { + $this->total = $total; + $this->lastPage = (int) ceil($total / $listRows); + $this->currentPage = $this->setCurrentPage($currentPage); + $this->hasMore = $this->currentPage < $this->lastPage; + } + $this->items = $items; + } + + /** + * @param $items + * @param $listRows + * @param null $currentPage + * @param bool $simple + * @param null $total + * @param array $options + * @return Paginator + */ + public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = []) + { + return new static($items, $listRows, $currentPage, $total, $simple, $options); + } + + protected function setCurrentPage($currentPage) + { + if (!$this->simple && $currentPage > $this->lastPage) { + return $this->lastPage > 0 ? $this->lastPage : 1; + } + + return $currentPage; + } + + /** + * 获取页码对应的链接 + * + * @param $page + * @return string + */ + protected function url($page) + { + if ($page <= 0) { + $page = 1; + } + + if (strpos($this->options['path'], '[PAGE]') === false) { + $parameters = [$this->options['var_page'] => $page]; + $path = $this->options['path']; + } else { + $parameters = []; + $path = str_replace('[PAGE]', $page, $this->options['path']); + } + if (count($this->options['query']) > 0) { + $parameters = array_merge($this->options['query'], $parameters); + } + $url = $path; + if (!empty($parameters)) { + $url .= '?' . urldecode(http_build_query($parameters, null, '&')); + } + return $url . $this->buildFragment(); + } + + /** + * 自动获取当前页码 + * @param string $varPage + * @param int $default + * @return int + */ + public static function getCurrentPage($varPage = 'page', $default = 1) + { + $page = (int) Request::instance()->param($varPage); + + if (filter_var($page, FILTER_VALIDATE_INT) !== false && $page >= 1) { + return $page; + } + + return $default; + } + /** + * 获取全部分页数 add by GZShangTao + * @return int + */ + public function getTotalPage(){ + return $this->totalPage; + } + + /** + * 自动获取当前的path + * @return string + */ + public static function getCurrentPath() + { + return Request::instance()->baseUrl(); + } + + public function total() + { + if ($this->simple) { + throw new \DomainException('not support total'); + } + return $this->total; + } + + public function listRows() + { + return $this->listRows; + } + + public function currentPage() + { + return $this->currentPage; + } + + public function lastPage() + { + if ($this->simple) { + throw new \DomainException('not support last'); + } + return $this->lastPage; + } + + /** + * 数据是否足够分页 + * @return boolean + */ + public function hasPages() + { + return !(1 == $this->currentPage && !$this->hasMore); + } + + /** + * 创建一组分页链接 + * + * @param int $start + * @param int $end + * @return array + */ + public function getUrlRange($start, $end) + { + $urls = []; + + for ($page = $start; $page <= $end; $page++) { + $urls[$page] = $this->url($page); + } + + return $urls; + } + + /** + * 设置URL锚点 + * + * @param string|null $fragment + * @return $this + */ + public function fragment($fragment) + { + $this->options['fragment'] = $fragment; + return $this; + } + + /** + * 添加URL参数 + * + * @param array|string $key + * @param string|null $value + * @return $this + */ + public function appends($key, $value = null) + { + if (!is_array($key)) { + $queries = [$key => $value]; + } else { + $queries = $key; + } + + foreach ($queries as $k => $v) { + if ($k !== $this->options['var_page']) { + $this->options['query'][$k] = $v; + } + } + + return $this; + } + + /** + * 构造锚点字符串 + * + * @return string + */ + protected function buildFragment() + { + return $this->options['fragment'] ? '#' . $this->options['fragment'] : ''; + } + + /** + * 渲染分页html + * @return mixed + */ + abstract public function render(); + + public function items() + { + return $this->items->all(); + } + + public function getCollection() + { + return $this->items; + } + + public function isEmpty() + { + return $this->items->isEmpty(); + } + + /** + * 给每个元素执行个回调 + * + * @param callable $callback + * @return $this + */ + public function each(callable $callback) + { + foreach ($this->items as $key => $item) { + $result = $callback($item, $key); + if (false === $result) { + break; + } elseif (!is_object($item)) { + $this->items[$key] = $result; + } + } + + return $this; + } + + /** + * Retrieve an external iterator + * @return Traversable An instance of an object implementing <b>Iterator</b> or + * <b>Traversable</b> + */ + public function getIterator() + { + return new ArrayIterator($this->items->all()); + } + + /** + * Whether a offset exists + * @param mixed $offset + * @return bool + */ + public function offsetExists($offset) + { + return $this->items->offsetExists($offset); + } + + /** + * Offset to retrieve + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->items->offsetGet($offset); + } + + /** + * Offset to set + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->items->offsetSet($offset, $value); + } + + /** + * Offset to unset + * @param mixed $offset + * @return void + * @since 5.0.0 + */ + public function offsetUnset($offset) + { + $this->items->offsetUnset($offset); + } + + /** + * Count elements of an object + */ + public function count() + { + return $this->items->count(); + } + + public function __toString() + { + return (string) $this->render(); + } + + public function toArray() + { + if ($this->simple) { + return [ + 'per_page' => $this->listRows, + 'current_page' => $this->currentPage, + 'has_more' => $this->hasMore, + 'next_item' => $this->nextItem, + 'data' => $this->items->toArray(), + ]; + } else { + //modify by GZShangTao + return [ + 'Total' => $this->total, + 'PerPage' => $this->listRows, + 'CurrentPage' => $this->currentPage, + 'TotalPage' => $this->lastPage, + 'Rows' => $this->items->toArray(), + ]; + } + + } + + /** + * Specify data which should be serialized to JSON + */ + public function jsonSerialize() + { + return $this->toArray(); + } + + public function __call($name, $arguments) + { + return call_user_func_array([$this->getCollection(), $name], $arguments); + } + +} diff --git a/thinkphp/library/think/Process.php b/thinkphp/library/think/Process.php new file mode 100755 index 0000000..6f3faa3 --- /dev/null +++ b/thinkphp/library/think/Process.php @@ -0,0 +1,1205 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\process\exception\Failed as ProcessFailedException; +use think\process\exception\Timeout as ProcessTimeoutException; +use think\process\pipes\Pipes; +use think\process\pipes\Unix as UnixPipes; +use think\process\pipes\Windows as WindowsPipes; +use think\process\Utils; + +class Process +{ + + const ERR = 'err'; + const OUT = 'out'; + + const STATUS_READY = 'ready'; + const STATUS_STARTED = 'started'; + const STATUS_TERMINATED = 'terminated'; + + const STDIN = 0; + const STDOUT = 1; + const STDERR = 2; + + const TIMEOUT_PRECISION = 0.2; + + private $callback; + private $commandline; + private $cwd; + private $env; + private $input; + private $starttime; + private $lastOutputTime; + private $timeout; + private $idleTimeout; + private $options; + private $exitcode; + private $fallbackExitcode; + private $processInformation; + private $outputDisabled = false; + private $stdout; + private $stderr; + private $enhanceWindowsCompatibility = true; + private $enhanceSigchildCompatibility; + private $process; + private $status = self::STATUS_READY; + private $incrementalOutputOffset = 0; + private $incrementalErrorOutputOffset = 0; + private $tty; + private $pty; + + private $useFileHandles = false; + + /** @var Pipes */ + private $processPipes; + + private $latestSignal; + + private static $sigchild; + + /** + * @var array + */ + public static $exitCodes = [ + 0 => 'OK', + 1 => 'General error', + 2 => 'Misuse of shell builtins', + 126 => 'Invoked command cannot execute', + 127 => 'Command not found', + 128 => 'Invalid exit argument', + // signals + 129 => 'Hangup', + 130 => 'Interrupt', + 131 => 'Quit and dump core', + 132 => 'Illegal instruction', + 133 => 'Trace/breakpoint trap', + 134 => 'Process aborted', + 135 => 'Bus error: "access to undefined portion of memory object"', + 136 => 'Floating point exception: "erroneous arithmetic operation"', + 137 => 'Kill (terminate immediately)', + 138 => 'User-defined 1', + 139 => 'Segmentation violation', + 140 => 'User-defined 2', + 141 => 'Write to pipe with no one reading', + 142 => 'Signal raised by alarm', + 143 => 'Termination (request to terminate)', + // 144 - not defined + 145 => 'Child process terminated, stopped (or continued*)', + 146 => 'Continue if stopped', + 147 => 'Stop executing temporarily', + 148 => 'Terminal stop signal', + 149 => 'Background process attempting to read from tty ("in")', + 150 => 'Background process attempting to write to tty ("out")', + 151 => 'Urgent data available on socket', + 152 => 'CPU time limit exceeded', + 153 => 'File size limit exceeded', + 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155 => 'Profiling timer expired', + // 156 - not defined + 157 => 'Pollable event', + // 158 - not defined + 159 => 'Bad syscall', + ]; + + /** + * 构造方法 + * @param string $commandline 指令 + * @param string|null $cwd 工作目录 + * @param array|null $env 环境变量 + * @param string|null $input 输入 + * @param int|float|null $timeout 超时时间 + * @param array $options proc_open的选项 + * @throws \RuntimeException + * @api + */ + public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = []) + { + if (!function_exists('proc_open')) { + throw new \RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.'); + } + + $this->commandline = $commandline; + $this->cwd = $cwd; + + if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DS)) { + $this->cwd = getcwd(); + } + if (null !== $env) { + $this->setEnv($env); + } + + $this->input = $input; + $this->setTimeout($timeout); + $this->useFileHandles = '\\' === DS; + $this->pty = false; + $this->enhanceWindowsCompatibility = true; + $this->enhanceSigchildCompatibility = '\\' !== DS && $this->isSigchildEnabled(); + $this->options = array_replace([ + 'suppress_errors' => true, + 'binary_pipes' => true, + ], $options); + } + + public function __destruct() + { + $this->stop(); + } + + public function __clone() + { + $this->resetProcessData(); + } + + /** + * 运行指令 + * @param callback|null $callback + * @return int + */ + public function run($callback = null) + { + $this->start($callback); + + return $this->wait(); + } + + /** + * 运行指令 + * @param callable|null $callback + * @return self + * @throws \RuntimeException + * @throws ProcessFailedException + */ + public function mustRun($callback = null) + { + if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); + } + + if (0 !== $this->run($callback)) { + throw new ProcessFailedException($this); + } + + return $this; + } + + /** + * 启动进程并写到 STDIN 输入后返回。 + * @param callable|null $callback + * @throws \RuntimeException + * @throws \RuntimeException + * @throws \LogicException + */ + public function start($callback = null) + { + if ($this->isRunning()) { + throw new \RuntimeException('Process is already running'); + } + if ($this->outputDisabled && null !== $callback) { + throw new \LogicException('Output has been disabled, enable it to allow the use of a callback.'); + } + + $this->resetProcessData(); + $this->starttime = $this->lastOutputTime = microtime(true); + $this->callback = $this->buildCallback($callback); + $descriptors = $this->getDescriptors(); + + $commandline = $this->commandline; + + if ('\\' === DS && $this->enhanceWindowsCompatibility) { + $commandline = 'cmd /V:ON /E:ON /C "(' . $commandline . ')'; + foreach ($this->processPipes->getFiles() as $offset => $filename) { + $commandline .= ' ' . $offset . '>' . Utils::escapeArgument($filename); + } + $commandline .= '"'; + + if (!isset($this->options['bypass_shell'])) { + $this->options['bypass_shell'] = true; + } + } + + $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options); + + if (!is_resource($this->process)) { + throw new \RuntimeException('Unable to launch a new process.'); + } + $this->status = self::STATUS_STARTED; + + if ($this->tty) { + return; + } + + $this->updateStatus(false); + $this->checkTimeout(); + } + + /** + * 重启进程 + * @param callable|null $callback + * @return Process + * @throws \RuntimeException + * @throws \RuntimeException + */ + public function restart($callback = null) + { + if ($this->isRunning()) { + throw new \RuntimeException('Process is already running'); + } + + $process = clone $this; + $process->start($callback); + + return $process; + } + + /** + * 等待要终止的进程 + * @param callable|null $callback + * @return int + */ + public function wait($callback = null) + { + $this->requireProcessIsStarted(__FUNCTION__); + + $this->updateStatus(false); + if (null !== $callback) { + $this->callback = $this->buildCallback($callback); + } + + do { + $this->checkTimeout(); + $running = '\\' === DS ? $this->isRunning() : $this->processPipes->areOpen(); + $close = '\\' !== DS || !$running; + $this->readPipes(true, $close); + } while ($running); + + while ($this->isRunning()) { + usleep(1000); + } + + if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) { + throw new \RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig'])); + } + + return $this->exitcode; + } + + /** + * 获取PID + * @return int|null + * @throws \RuntimeException + */ + public function getPid() + { + if ($this->isSigchildEnabled()) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.'); + } + + $this->updateStatus(false); + + return $this->isRunning() ? $this->processInformation['pid'] : null; + } + + /** + * 将一个 POSIX 信号发送到进程中 + * @param int $signal + * @return Process + */ + public function signal($signal) + { + $this->doSignal($signal, true); + + return $this; + } + + /** + * 禁用从底层过程获取输出和错误输出。 + * @return Process + */ + public function disableOutput() + { + if ($this->isRunning()) { + throw new \RuntimeException('Disabling output while the process is running is not possible.'); + } + if (null !== $this->idleTimeout) { + throw new \LogicException('Output can not be disabled while an idle timeout is set.'); + } + + $this->outputDisabled = true; + + return $this; + } + + /** + * 开启从底层过程获取输出和错误输出。 + * @return Process + * @throws \RuntimeException + */ + public function enableOutput() + { + if ($this->isRunning()) { + throw new \RuntimeException('Enabling output while the process is running is not possible.'); + } + + $this->outputDisabled = false; + + return $this; + } + + /** + * 输出是否禁用 + * @return bool + */ + public function isOutputDisabled() + { + return $this->outputDisabled; + } + + /** + * 获取当前的输出管道 + * @return string + * @throws \LogicException + * @throws \LogicException + * @api + */ + public function getOutput() + { + if ($this->outputDisabled) { + throw new \LogicException('Output has been disabled.'); + } + + $this->requireProcessIsStarted(__FUNCTION__); + + $this->readPipes(false, '\\' === DS ? !$this->processInformation['running'] : true); + + return $this->stdout; + } + + /** + * 以增量方式返回的输出结果。 + * @return string + */ + public function getIncrementalOutput() + { + $this->requireProcessIsStarted(__FUNCTION__); + + $data = $this->getOutput(); + + $latest = substr($data, $this->incrementalOutputOffset); + + if (false === $latest) { + return ''; + } + + $this->incrementalOutputOffset = strlen($data); + + return $latest; + } + + /** + * 清空输出 + * @return Process + */ + public function clearOutput() + { + $this->stdout = ''; + $this->incrementalOutputOffset = 0; + + return $this; + } + + /** + * 返回当前的错误输出的过程 (STDERR)。 + * @return string + */ + public function getErrorOutput() + { + if ($this->outputDisabled) { + throw new \LogicException('Output has been disabled.'); + } + + $this->requireProcessIsStarted(__FUNCTION__); + + $this->readPipes(false, '\\' === DS ? !$this->processInformation['running'] : true); + + return $this->stderr; + } + + /** + * 以增量方式返回 errorOutput + * @return string + */ + public function getIncrementalErrorOutput() + { + $this->requireProcessIsStarted(__FUNCTION__); + + $data = $this->getErrorOutput(); + + $latest = substr($data, $this->incrementalErrorOutputOffset); + + if (false === $latest) { + return ''; + } + + $this->incrementalErrorOutputOffset = strlen($data); + + return $latest; + } + + /** + * 清空 errorOutput + * @return Process + */ + public function clearErrorOutput() + { + $this->stderr = ''; + $this->incrementalErrorOutputOffset = 0; + + return $this; + } + + /** + * 获取退出码 + * @return null|int + */ + public function getExitCode() + { + if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); + } + + $this->updateStatus(false); + + return $this->exitcode; + } + + /** + * 获取退出文本 + * @return null|string + */ + public function getExitCodeText() + { + if (null === $exitcode = $this->getExitCode()) { + return; + } + + return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error'; + } + + /** + * 检查是否成功 + * @return bool + */ + public function isSuccessful() + { + return 0 === $this->getExitCode(); + } + + /** + * 是否未捕获的信号已被终止子进程 + * @return bool + */ + public function hasBeenSignaled() + { + $this->requireProcessIsTerminated(__FUNCTION__); + + if ($this->isSigchildEnabled()) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); + } + + $this->updateStatus(false); + + return $this->processInformation['signaled']; + } + + /** + * 返回导致子进程终止其执行的数。 + * @return int + */ + public function getTermSignal() + { + $this->requireProcessIsTerminated(__FUNCTION__); + + if ($this->isSigchildEnabled()) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); + } + + $this->updateStatus(false); + + return $this->processInformation['termsig']; + } + + /** + * 检查子进程信号是否已停止 + * @return bool + */ + public function hasBeenStopped() + { + $this->requireProcessIsTerminated(__FUNCTION__); + + $this->updateStatus(false); + + return $this->processInformation['stopped']; + } + + /** + * 返回导致子进程停止其执行的数。 + * @return int + */ + public function getStopSignal() + { + $this->requireProcessIsTerminated(__FUNCTION__); + + $this->updateStatus(false); + + return $this->processInformation['stopsig']; + } + + /** + * 检查是否正在运行 + * @return bool + */ + public function isRunning() + { + if (self::STATUS_STARTED !== $this->status) { + return false; + } + + $this->updateStatus(false); + + return $this->processInformation['running']; + } + + /** + * 检查是否已开始 + * @return bool + */ + public function isStarted() + { + return self::STATUS_READY != $this->status; + } + + /** + * 检查是否已终止 + * @return bool + */ + public function isTerminated() + { + $this->updateStatus(false); + + return self::STATUS_TERMINATED == $this->status; + } + + /** + * 获取当前的状态 + * @return string + */ + public function getStatus() + { + $this->updateStatus(false); + + return $this->status; + } + + /** + * 终止进程 + */ + public function stop() + { + if ($this->isRunning()) { + if ('\\' === DS && !$this->isSigchildEnabled()) { + exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode); + if ($exitCode > 0) { + throw new \RuntimeException('Unable to kill the process'); + } + } else { + $pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid {$this->getPid()}`); + foreach ($pids as $pid) { + if (is_numeric($pid)) { + posix_kill($pid, 9); + } + } + } + } + + $this->updateStatus(false); + if ($this->processInformation['running']) { + $this->close(); + } + + return $this->exitcode; + } + + /** + * 添加一行输出 + * @param string $line + */ + public function addOutput($line) +{ + $this->lastOutputTime = microtime(true); + $this->stdout .= $line; + } + + /** + * 添加一行错误输出 + * @param string $line + */ + public function addErrorOutput($line) +{ + $this->lastOutputTime = microtime(true); + $this->stderr .= $line; + } + + /** + * 获取被执行的指令 + * @return string + */ + public function getCommandLine() +{ + return $this->commandline; + } + + /** + * 设置指令 + * @param string $commandline + * @return self + */ + public function setCommandLine($commandline) +{ + $this->commandline = $commandline; + + return $this; + } + + /** + * 获取超时时间 + * @return float|null + */ + public function getTimeout() +{ + return $this->timeout; + } + + /** + * 获取idle超时时间 + * @return float|null + */ + public function getIdleTimeout() +{ + return $this->idleTimeout; + } + + /** + * 设置超时时间 + * @param int|float|null $timeout + * @return self + */ + public function setTimeout($timeout) +{ + $this->timeout = $this->validateTimeout($timeout); + + return $this; + } + + /** + * 设置idle超时时间 + * @param int|float|null $timeout + * @return self + */ + public function setIdleTimeout($timeout) +{ + if (null !== $timeout && $this->outputDisabled) { + throw new \LogicException('Idle timeout can not be set while the output is disabled.'); + } + + $this->idleTimeout = $this->validateTimeout($timeout); + + return $this; + } + + /** + * 设置TTY + * @param bool $tty + * @return self + */ + public function setTty($tty) +{ + if ('\\' === DS && $tty) { + throw new \RuntimeException('TTY mode is not supported on Windows platform.'); + } + if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) { + throw new \RuntimeException('TTY mode requires /dev/tty to be readable.'); + } + + $this->tty = (bool) $tty; + + return $this; + } + + /** + * 检查是否是tty模式 + * @return bool + */ + public function isTty() +{ + return $this->tty; + } + + /** + * 设置pty模式 + * @param bool $bool + * @return self + */ + public function setPty($bool) +{ + $this->pty = (bool) $bool; + + return $this; + } + + /** + * 是否是pty模式 + * @return bool + */ + public function isPty() +{ + return $this->pty; + } + + /** + * 获取工作目录 + * @return string|null + */ + public function getWorkingDirectory() +{ + if (null === $this->cwd) { + return getcwd() ?: null; + } + + return $this->cwd; + } + + /** + * 设置工作目录 + * @param string $cwd + * @return self + */ + public function setWorkingDirectory($cwd) +{ + $this->cwd = $cwd; + + return $this; + } + + /** + * 获取环境变量 + * @return array + */ + public function getEnv() +{ + return $this->env; + } + + /** + * 设置环境变量 + * @param array $env + * @return self + */ + public function setEnv(array $env) +{ + $env = array_filter($env, function ($value) { + return !is_array($value); + }); + + $this->env = []; + foreach ($env as $key => $value) { + $this->env[(binary) $key] = (binary) $value; + } + + return $this; + } + + /** + * 获取输入 + * @return null|string + */ + public function getInput() +{ + return $this->input; + } + + /** + * 设置输入 + * @param mixed $input + * @return self + */ + public function setInput($input) +{ + if ($this->isRunning()) { + throw new \LogicException('Input can not be set while the process is running.'); + } + + $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); + + return $this; + } + + /** + * 获取proc_open的选项 + * @return array + */ + public function getOptions() +{ + return $this->options; + } + + /** + * 设置proc_open的选项 + * @param array $options + * @return self + */ + public function setOptions(array $options) +{ + $this->options = $options; + + return $this; + } + + /** + * 是否兼容windows + * @return bool + */ + public function getEnhanceWindowsCompatibility() +{ + return $this->enhanceWindowsCompatibility; + } + + /** + * 设置是否兼容windows + * @param bool $enhance + * @return self + */ + public function setEnhanceWindowsCompatibility($enhance) +{ + $this->enhanceWindowsCompatibility = (bool) $enhance; + + return $this; + } + + /** + * 返回是否 sigchild 兼容模式激活 + * @return bool + */ + public function getEnhanceSigchildCompatibility() +{ + return $this->enhanceSigchildCompatibility; + } + + /** + * 激活 sigchild 兼容性模式。 + * @param bool $enhance + * @return self + */ + public function setEnhanceSigchildCompatibility($enhance) +{ + $this->enhanceSigchildCompatibility = (bool) $enhance; + + return $this; + } + + /** + * 是否超时 + */ + public function checkTimeout() +{ + if (self::STATUS_STARTED !== $this->status) { + return; + } + + if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) { + $this->stop(); + + throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_GENERAL); + } + + if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) { + $this->stop(); + + throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_IDLE); + } + } + + /** + * 是否支持pty + * @return bool + */ + public static function isPtySupported() +{ + static $result; + + if (null !== $result) { + return $result; + } + + if ('\\' === DS) { + return $result = false; + } + + $proc = @proc_open('echo 1', [['pty'], ['pty'], ['pty']], $pipes); + if (is_resource($proc)) { + proc_close($proc); + + return $result = true; + } + + return $result = false; + } + + /** + * 创建所需的 proc_open 的描述符 + * @return array + */ + private function getDescriptors() +{ + if ('\\' === DS) { + $this->processPipes = WindowsPipes::create($this, $this->input); + } else { + $this->processPipes = UnixPipes::create($this, $this->input); + } + $descriptors = $this->processPipes->getDescriptors($this->outputDisabled); + + if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { + + $descriptors = array_merge($descriptors, [['pipe', 'w']]); + + $this->commandline = '(' . $this->commandline . ') 3>/dev/null; code=$?; echo $code >&3; exit $code'; + } + + return $descriptors; + } + + /** + * 建立 wait () 使用的回调。 + * @param callable|null $callback + * @return callable + */ + protected function buildCallback($callback) +{ + $out = self::OUT; + $callback = function ($type, $data) use ($callback, $out) { + if ($out == $type) { + $this->addOutput($data); + } else { + $this->addErrorOutput($data); + } + + if (null !== $callback) { + call_user_func($callback, $type, $data); + } + }; + + return $callback; + } + + /** + * 更新状态 + * @param bool $blocking + */ + protected function updateStatus($blocking) +{ + if (self::STATUS_STARTED !== $this->status) { + return; + } + + $this->processInformation = proc_get_status($this->process); + $this->captureExitCode(); + + $this->readPipes($blocking, '\\' === DS ? !$this->processInformation['running'] : true); + + if (!$this->processInformation['running']) { + $this->close(); + } + } + + /** + * 是否开启 '--enable-sigchild' + * @return bool + */ + protected function isSigchildEnabled() +{ + if (null !== self::$sigchild) { + return self::$sigchild; + } + + if (!function_exists('phpinfo')) { + return self::$sigchild = false; + } + + ob_start(); + phpinfo(INFO_GENERAL); + + return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); + } + + /** + * 验证是否超时 + * @param int|float|null $timeout + * @return float|null + */ + private function validateTimeout($timeout) +{ + $timeout = (float) $timeout; + + if (0.0 === $timeout) { + $timeout = null; + } elseif ($timeout < 0) { + throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); + } + + return $timeout; + } + + /** + * 读取pipes + * @param bool $blocking + * @param bool $close + */ + private function readPipes($blocking, $close) +{ + $result = $this->processPipes->readAndWrite($blocking, $close); + + $callback = $this->callback; + foreach ($result as $type => $data) { + if (3 == $type) { + $this->fallbackExitcode = (int) $data; + } else { + $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data); + } + } + } + + /** + * 捕获退出码 + */ + private function captureExitCode() +{ + if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) { + $this->exitcode = $this->processInformation['exitcode']; + } + } + + /** + * 关闭资源 + * @return int 退出码 + */ + private function close() +{ + $this->processPipes->close(); + if (is_resource($this->process)) { + $exitcode = proc_close($this->process); + } else { + $exitcode = -1; + } + + $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1); + $this->status = self::STATUS_TERMINATED; + + if (-1 === $this->exitcode && null !== $this->fallbackExitcode) { + $this->exitcode = $this->fallbackExitcode; + } elseif (-1 === $this->exitcode && $this->processInformation['signaled'] + && 0 < $this->processInformation['termsig'] + ) { + $this->exitcode = 128 + $this->processInformation['termsig']; + } + + return $this->exitcode; + } + + /** + * 重置数据 + */ + private function resetProcessData() +{ + $this->starttime = null; + $this->callback = null; + $this->exitcode = null; + $this->fallbackExitcode = null; + $this->processInformation = null; + $this->stdout = null; + $this->stderr = null; + $this->process = null; + $this->latestSignal = null; + $this->status = self::STATUS_READY; + $this->incrementalOutputOffset = 0; + $this->incrementalErrorOutputOffset = 0; + } + + /** + * 将一个 POSIX 信号发送到进程中。 + * @param int $signal + * @param bool $throwException + * @return bool + */ + private function doSignal($signal, $throwException) +{ + if (!$this->isRunning()) { + if ($throwException) { + throw new \LogicException('Can not send signal on a non running process.'); + } + + return false; + } + + if ($this->isSigchildEnabled()) { + if ($throwException) { + throw new \RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); + } + + return false; + } + + if (true !== @proc_terminate($this->process, $signal)) { + if ($throwException) { + throw new \RuntimeException(sprintf('Error while sending signal `%s`.', $signal)); + } + + return false; + } + + $this->latestSignal = $signal; + + return true; + } + + /** + * 确保进程已经开启 + * @param string $functionName + */ + private function requireProcessIsStarted($functionName) +{ + if (!$this->isStarted()) { + throw new \LogicException(sprintf('Process must be started before calling %s.', $functionName)); + } + } + + /** + * 确保进程已经终止 + * @param string $functionName + */ + private function requireProcessIsTerminated($functionName) +{ + if (!$this->isTerminated()) { + throw new \LogicException(sprintf('Process must be terminated before calling %s.', $functionName)); + } + } +} diff --git a/thinkphp/library/think/Request.php b/thinkphp/library/think/Request.php new file mode 100755 index 0000000..1e44f78 --- /dev/null +++ b/thinkphp/library/think/Request.php @@ -0,0 +1,1656 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Request +{ + /** + * @var object 对象实例 + */ + protected static $instance; + + protected $method; + /** + * @var string 域名(含协议和端口) + */ + protected $domain; + + /** + * @var string URL地址 + */ + protected $url; + + /** + * @var string 基础URL + */ + protected $baseUrl; + + /** + * @var string 当前执行的文件 + */ + protected $baseFile; + + /** + * @var string 访问的ROOT地址 + */ + protected $root; + + /** + * @var string pathinfo + */ + protected $pathinfo; + + /** + * @var string pathinfo(不含后缀) + */ + protected $path; + + /** + * @var array 当前路由信息 + */ + protected $routeInfo = []; + + /** + * @var array 环境变量 + */ + protected $env; + + /** + * @var array 当前调度信息 + */ + protected $dispatch = []; + protected $module; + protected $controller; + protected $action; + // 当前语言集 + protected $langset; + + /** + * @var array 请求参数 + */ + protected $param = []; + protected $get = []; + protected $post = []; + protected $request = []; + protected $route = []; + protected $put; + protected $session = []; + protected $file = []; + protected $cookie = []; + protected $server = []; + protected $header = []; + + /** + * @var array 资源类型 + */ + protected $mimeType = [ + 'xml' => 'application/xml,text/xml,application/x-xml', + 'json' => 'application/json,text/x-json,application/jsonrequest,text/json', + 'js' => 'text/javascript,application/javascript,application/x-javascript', + 'css' => 'text/css', + 'rss' => 'application/rss+xml', + 'yaml' => 'application/x-yaml,text/yaml', + 'atom' => 'application/atom+xml', + 'pdf' => 'application/pdf', + 'text' => 'text/plain', + 'image' => 'image/png,image/jpg,image/jpeg,image/pjpeg,image/gif,image/webp,image/*', + 'csv' => 'text/csv', + 'html' => 'text/html,application/xhtml+xml,*/*', + ]; + + protected $content; + + // 全局过滤规则 + protected $filter; + // Hook扩展方法 + protected static $hook = []; + // 绑定的属性 + protected $bind = []; + // php://input + protected $input; + // 请求缓存 + protected $cache; + // 缓存是否检查 + protected $isCheckCache; + + /** + * 构造函数 + * @access protected + * @param array $options 参数 + */ + protected function __construct($options = []) + { + foreach ($options as $name => $item) { + if (property_exists($this, $name)) { + $this->$name = $item; + } + } + if (is_null($this->filter)) { + $this->filter = Config::get('default_filter'); + } + + // 保存 php://input + $this->input = file_get_contents('php://input'); + } + + public function __call($method, $args) + { + if (array_key_exists($method, self::$hook)) { + array_unshift($args, $this); + return call_user_func_array(self::$hook[$method], $args); + } else { + throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + } + } + + /** + * Hook 方法注入 + * @access public + * @param string|array $method 方法名 + * @param mixed $callback callable + * @return void + */ + public static function hook($method, $callback = null) + { + if (is_array($method)) { + self::$hook = array_merge(self::$hook, $method); + } else { + self::$hook[$method] = $callback; + } + } + + /** + * 初始化 + * @access public + * @param array $options 参数 + * @return \think\Request + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) { + self::$instance = new static($options); + } + return self::$instance; + } + + /** + * 创建一个URL请求 + * @access public + * @param string $uri URL地址 + * @param string $method 请求类型 + * @param array $params 请求参数 + * @param array $cookie + * @param array $files + * @param array $server + * @param string $content + * @return \think\Request + */ + public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null) + { + $server['PATH_INFO'] = ''; + $server['REQUEST_METHOD'] = strtoupper($method); + $info = parse_url($uri); + if (isset($info['host'])) { + $server['SERVER_NAME'] = $info['host']; + $server['HTTP_HOST'] = $info['host']; + } + if (isset($info['scheme'])) { + if ('https' === $info['scheme']) { + $server['HTTPS'] = 'on'; + $server['SERVER_PORT'] = 443; + } else { + unset($server['HTTPS']); + $server['SERVER_PORT'] = 80; + } + } + if (isset($info['port'])) { + $server['SERVER_PORT'] = $info['port']; + $server['HTTP_HOST'] = $server['HTTP_HOST'] . ':' . $info['port']; + } + if (isset($info['user'])) { + $server['PHP_AUTH_USER'] = $info['user']; + } + if (isset($info['pass'])) { + $server['PHP_AUTH_PW'] = $info['pass']; + } + if (!isset($info['path'])) { + $info['path'] = '/'; + } + $options = []; + $options[strtolower($method)] = $params; + $queryString = ''; + if (isset($info['query'])) { + parse_str(html_entity_decode($info['query']), $query); + if (!empty($params)) { + $params = array_replace($query, $params); + $queryString = http_build_query($query, '', '&'); + } else { + $params = $query; + $queryString = $info['query']; + } + } elseif (!empty($params)) { + $queryString = http_build_query($params, '', '&'); + } + if ($queryString) { + parse_str($queryString, $get); + $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get; + } + + $server['REQUEST_URI'] = $info['path'] . ('' !== $queryString ? '?' . $queryString : ''); + $server['QUERY_STRING'] = $queryString; + $options['cookie'] = $cookie; + $options['param'] = $params; + $options['file'] = $files; + $options['server'] = $server; + $options['url'] = $server['REQUEST_URI']; + $options['baseUrl'] = $info['path']; + $options['pathinfo'] = '/' == $info['path'] ? '/' : ltrim($info['path'], '/'); + $options['method'] = $server['REQUEST_METHOD']; + $options['domain'] = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : ''; + $options['content'] = $content; + self::$instance = new self($options); + return self::$instance; + } + + /** + * 设置或获取当前包含协议的域名 + * @access public + * @param string $domain 域名 + * @return string + */ + public function domain($domain = null) + { + if (!is_null($domain)) { + $this->domain = $domain; + return $this; + } elseif (!$this->domain) { + $this->domain = $this->scheme() . '://' . $this->host(); + } + return $this->domain; + } + + /** + * 设置或获取当前完整URL 包括QUERY_STRING + * @access public + * @param string|true $url URL地址 true 带域名获取 + * @return string + */ + public function url($url = null) + { + if (!is_null($url) && true !== $url) { + $this->url = $url; + return $this; + } elseif (!$this->url) { + if (IS_CLI) { + $this->url = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; + } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { + $this->url = $_SERVER['HTTP_X_REWRITE_URL']; + } elseif (isset($_SERVER['REQUEST_URI'])) { + $this->url = $_SERVER['REQUEST_URI']; + } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { + $this->url = $_SERVER['ORIG_PATH_INFO'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : ''); + } else { + $this->url = ''; + } + } + return true === $url ? $this->domain() . $this->url : $this->url; + } + + /** + * 设置或获取当前URL 不含QUERY_STRING + * @access public + * @param string $url URL地址 + * @return string + */ + public function baseUrl($url = null) + { + if (!is_null($url) && true !== $url) { + $this->baseUrl = $url; + return $this; + } elseif (!$this->baseUrl) { + $str = $this->url(); + $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str; + } + return true === $url ? $this->domain() . $this->baseUrl : $this->baseUrl; + } + + /** + * 设置或获取当前执行的文件 SCRIPT_NAME + * @access public + * @param string $file 当前执行的文件 + * @return string + */ + public function baseFile($file = null) + { + if (!is_null($file) && true !== $file) { + $this->baseFile = $file; + return $this; + } elseif (!$this->baseFile) { + $url = ''; + if (!IS_CLI) { + $script_name = basename($_SERVER['SCRIPT_FILENAME']); + if (basename($_SERVER['SCRIPT_NAME']) === $script_name) { + $url = $_SERVER['SCRIPT_NAME']; + } elseif (basename($_SERVER['PHP_SELF']) === $script_name) { + $url = $_SERVER['PHP_SELF']; + } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) { + $url = $_SERVER['ORIG_SCRIPT_NAME']; + } elseif (($pos = strpos($_SERVER['PHP_SELF'], '/' . $script_name)) !== false) { + $url = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name; + } elseif (isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) { + $url = str_replace('\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME'])); + } + } + $this->baseFile = $url; + } + return true === $file ? $this->domain() . $this->baseFile : $this->baseFile; + } + + /** + * 设置或获取URL访问根地址 + * @access public + * @param string $url URL地址 + * @return string + */ + public function root($url = null) + { + if (!is_null($url) && true !== $url) { + $this->root = $url; + return $this; + } elseif (!$this->root) { + $file = $this->baseFile(); + if ($file && 0 !== strpos($this->url(), $file)) { + $file = str_replace('\\', '/', dirname($file)); + } + $this->root = rtrim($file, '/'); + } + return true === $url ? $this->domain() . $this->root : $this->root; + } + + /** + * 获取当前请求URL的pathinfo信息(含URL后缀) + * @access public + * @return string + */ + public function pathinfo() + { + if (is_null($this->pathinfo)) { + if (isset($_GET[Config::get('var_pathinfo')])) { + // 判断URL里面是否有兼容模式参数 + $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')]; + unset($_GET[Config::get('var_pathinfo')]); + } elseif (IS_CLI) { + // CLI模式下 index.php module/controller/action/params/... + $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; + } + + // 分析PATHINFO信息 + if (!isset($_SERVER['PATH_INFO'])) { + foreach (Config::get('pathinfo_fetch') as $type) { + if (!empty($_SERVER[$type])) { + $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ? + substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type]; + break; + } + } + } + $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/'); + } + return $this->pathinfo; + } + + /** + * 获取当前请求URL的pathinfo信息(不含URL后缀) + * @access public + * @return string + */ + public function path() + { + if (is_null($this->path)) { + $suffix = Config::get('url_html_suffix'); + $pathinfo = $this->pathinfo(); + if (false === $suffix) { + // 禁止伪静态访问 + $this->path = $pathinfo; + } elseif ($suffix) { + // 去除正常的URL后缀 + $this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo); + } else { + // 允许任何后缀访问 + $this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo); + } + } + return $this->path; + } + + /** + * 当前URL的访问后缀 + * @access public + * @return string + */ + public function ext() + { + return pathinfo($this->pathinfo(), PATHINFO_EXTENSION); + } + + /** + * 获取当前请求的时间 + * @access public + * @param bool $float 是否使用浮点类型 + * @return integer|float + */ + public function time($float = false) + { + return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME']; + } + + /** + * 当前请求的资源类型 + * @access public + * @return false|string + */ + public function type() + { + $accept = $this->server('HTTP_ACCEPT'); + if (empty($accept)) { + return false; + } + + foreach ($this->mimeType as $key => $val) { + $array = explode(',', $val); + foreach ($array as $k => $v) { + if (stristr($accept, $v)) { + return $key; + } + } + } + return false; + } + + /** + * 设置资源类型 + * @access public + * @param string|array $type 资源类型名 + * @param string $val 资源类型 + * @return void + */ + public function mimeType($type, $val = '') + { + if (is_array($type)) { + $this->mimeType = array_merge($this->mimeType, $type); + } else { + $this->mimeType[$type] = $val; + } + } + + /** + * 当前的请求类型 + * @access public + * @param bool $method true 获取原始请求类型 + * @return string + */ + public function method($method = false) + { + if (true === $method) { + // 获取原始请求类型 + return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); + } elseif (!$this->method) { + if (isset($_POST[Config::get('var_method')])) { + //$this->method = strtoupper($_POST[Config::get('var_method')]); + //$this->{$this->method}($_POST); + $method = strtoupper($_POST[Config::get('var_method')]); + if (in_array($method, ['GET', 'POST', 'DELETE', 'PUT', 'PATCH'])) { + $this->method = $method; + $this->{$this->method}($_POST); + } else { + $this->method = 'POST'; + } + unset($_POST[Config::get('var_method')]); + } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) { + $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']); + } else { + $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']); + } + } + return $this->method; + } + + /** + * 是否为GET请求 + * @access public + * @return bool + */ + public function isGet() + { + return $this->method() == 'GET'; + } + + /** + * 是否为POST请求 + * @access public + * @return bool + */ + public function isPost() + { + return $this->method() == 'POST'; + } + + /** + * 是否为PUT请求 + * @access public + * @return bool + */ + public function isPut() + { + return $this->method() == 'PUT'; + } + + /** + * 是否为DELTE请求 + * @access public + * @return bool + */ + public function isDelete() + { + return $this->method() == 'DELETE'; + } + + /** + * 是否为HEAD请求 + * @access public + * @return bool + */ + public function isHead() + { + return $this->method() == 'HEAD'; + } + + /** + * 是否为PATCH请求 + * @access public + * @return bool + */ + public function isPatch() + { + return $this->method() == 'PATCH'; + } + + /** + * 是否为OPTIONS请求 + * @access public + * @return bool + */ + public function isOptions() + { + return $this->method() == 'OPTIONS'; + } + + /** + * 是否为cli + * @access public + * @return bool + */ + public function isCli() + { + return PHP_SAPI == 'cli'; + } + + /** + * 是否为cgi + * @access public + * @return bool + */ + public function isCgi() + { + return strpos(PHP_SAPI, 'cgi') === 0; + } + + /** + * 获取当前请求的参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function param($name = '', $default = null, $filter = '') + { + if (empty($this->param)) { + $method = $this->method(true); + // 自动获取请求变量 + switch ($method) { + case 'POST': + $vars = $this->post(false); + break; + case 'PUT': + case 'DELETE': + case 'PATCH': + $vars = $this->put(false); + break; + default: + $vars = []; + } + // 当前请求参数和URL地址中的参数合并 + $this->param = array_merge($this->get(false), $vars, $this->route(false)); + } + if (true === $name) { + // 获取包含文件上传信息的数组 + $file = $this->file(); + $data = is_array($file) ? array_merge($this->param, $file) : $this->param; + return $this->input($data, '', $default, $filter); + } + return $this->input($this->param, $name, $default, $filter); + } + + /** + * 设置获取路由参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function route($name = '', $default = null, $filter = '') + { + if (is_array($name)) { + $this->param = []; + return $this->route = array_merge($this->route, $name); + } + return $this->input($this->route, $name, $default, $filter); + } + + /** + * 设置获取GET参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function get($name = '', $default = null, $filter = '') + { + if (empty($this->get)) { + $this->get = $_GET; + } + if (is_array($name)) { + $this->param = []; + return $this->get = array_merge($this->get, $name); + } + return $this->input($this->get, $name, $default, $filter); + } + + /** + * 设置获取POST参数 + * @access public + * @param string $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function post($name = '', $default = null, $filter = '') + { + if (empty($this->post)) { + $content = $this->input; + if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) { + $this->post = (array) json_decode($content, true); + } else { + $this->post = $_POST; + } + } + if (is_array($name)) { + $this->param = []; + return $this->post = array_merge($this->post, $name); + } + return $this->input($this->post, $name, $default, $filter); + } + + /** + * 设置获取PUT参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function put($name = '', $default = null, $filter = '') + { + if (is_null($this->put)) { + $content = $this->input; + if (false !== strpos($this->contentType(), 'application/json')) { + $this->put = (array) json_decode($content, true); + } else { + parse_str($content, $this->put); + } + } + if (is_array($name)) { + $this->param = []; + return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name); + } + + return $this->input($this->put, $name, $default, $filter); + } + + /** + * 设置获取DELETE参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function delete($name = '', $default = null, $filter = '') + { + return $this->put($name, $default, $filter); + } + + /** + * 设置获取PATCH参数 + * @access public + * @param string|array $name 变量名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function patch($name = '', $default = null, $filter = '') + { + return $this->put($name, $default, $filter); + } + + /** + * 获取request变量 + * @param string $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function request($name = '', $default = null, $filter = '') + { + if (empty($this->request)) { + $this->request = $_REQUEST; + } + if (is_array($name)) { + $this->param = []; + return $this->request = array_merge($this->request, $name); + } + return $this->input($this->request, $name, $default, $filter); + } + + /** + * 获取session数据 + * @access public + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function session($name = '', $default = null, $filter = '') + { + if (empty($this->session)) { + $this->session = Session::get(); + } + if (is_array($name)) { + return $this->session = array_merge($this->session, $name); + } + return $this->input($this->session, $name, $default, $filter); + } + + /** + * 获取cookie参数 + * @access public + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function cookie($name = '', $default = null, $filter = '') + { + if (empty($this->cookie)) { + $this->cookie = Cookie::get(); + } + if (is_array($name)) { + return $this->cookie = array_merge($this->cookie, $name); + } elseif (!empty($name)) { + $data = Cookie::has($name) ? Cookie::get($name) : $default; + } else { + $data = $this->cookie; + } + + // 解析过滤器 + $filter = $this->getFilter($filter, $default); + + if (is_array($data)) { + array_walk_recursive($data, [$this, 'filterValue'], $filter); + reset($data); + } else { + $this->filterValue($data, $name, $filter); + } + return $data; + } + + /** + * 获取server参数 + * @access public + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function server($name = '', $default = null, $filter = '') + { + if (empty($this->server)) { + $this->server = $_SERVER; + } + if (is_array($name)) { + return $this->server = array_merge($this->server, $name); + } + return $this->input($this->server, false === $name ? false : strtoupper($name), $default, $filter); + } + + /** + * 获取上传的文件信息 + * @access public + * @param string|array $name 名称 + * @return null|array|\think\File + */ + public function file($name = '') + { + if (empty($this->file)) { + $this->file = isset($_FILES) ? $_FILES : []; + } + if (is_array($name)) { + return $this->file = array_merge($this->file, $name); + } + $files = $this->file; + if (!empty($files)) { + // 处理上传文件 + $array = []; + foreach ($files as $key => $file) { + if (is_array($file['name'])) { + $item = []; + $keys = array_keys($file); + $count = count($file['name']); + for ($i = 0; $i < $count; $i++) { + if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) { + continue; + } + $temp['key'] = $key; + foreach ($keys as $_key) { + $temp[$_key] = $file[$_key][$i]; + } + $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp); + } + $array[$key] = $item; + } else { + if ($file instanceof File) { + $array[$key] = $file; + } else { + if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) { + continue; + } + $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file); + } + } + } + if (strpos($name, '.')) { + list($name, $sub) = explode('.', $name); + } + if ('' === $name) { + // 获取全部文件 + return $array; + } elseif (isset($sub) && isset($array[$name][$sub])) { + return $array[$name][$sub]; + } elseif (isset($array[$name])) { + return $array[$name]; + } + } + return; + } + + /** + * 获取环境变量 + * @param string|array $name 数据名称 + * @param string $default 默认值 + * @param string|array $filter 过滤方法 + * @return mixed + */ + public function env($name = '', $default = null, $filter = '') + { + if (empty($this->env)) { + $this->env = $_ENV; + } + if (is_array($name)) { + return $this->env = array_merge($this->env, $name); + } + return $this->input($this->env, false === $name ? false : strtoupper($name), $default, $filter); + } + + /** + * 设置或者获取当前的Header + * @access public + * @param string|array $name header名称 + * @param string $default 默认值 + * @return string + */ + public function header($name = '', $default = null) + { + if (empty($this->header)) { + $header = []; + if (function_exists('apache_request_headers') && $result = apache_request_headers()) { + $header = $result; + } else { + $server = $this->server ?: $_SERVER; + foreach ($server as $key => $val) { + if (0 === strpos($key, 'HTTP_')) { + $key = str_replace('_', '-', strtolower(substr($key, 5))); + $header[$key] = $val; + } + } + if (isset($server['CONTENT_TYPE'])) { + $header['content-type'] = $server['CONTENT_TYPE']; + } + if (isset($server['CONTENT_LENGTH'])) { + $header['content-length'] = $server['CONTENT_LENGTH']; + } + } + $this->header = array_change_key_case($header); + } + if (is_array($name)) { + return $this->header = array_merge($this->header, $name); + } + if ('' === $name) { + return $this->header; + } + $name = str_replace('_', '-', strtolower($name)); + return isset($this->header[$name]) ? $this->header[$name] : $default; + } + + /** + * 获取变量 支持过滤和默认值 + * @param array $data 数据源 + * @param string|false $name 字段名 + * @param mixed $default 默认值 + * @param string|array $filter 过滤函数 + * @return mixed + */ + public function input($data = [], $name = '', $default = null, $filter = '') + { + if (false === $name) { + // 获取原始数据 + return $data; + } + $name = (string) $name; + if ('' != $name) { + // 解析name + if (strpos($name, '/')) { + list($name, $type) = explode('/', $name); + } else { + $type = 's'; + } + // 按.拆分成多维数组进行判断 + foreach (explode('.', $name) as $val) { + if (isset($data[$val])) { + $data = $data[$val]; + } else { + // 无输入数据,返回默认值 + return $default; + } + } + if (is_object($data)) { + return $data; + } + } + + // 解析过滤器 + $filter = $this->getFilter($filter, $default); + + if (is_array($data)) { + array_walk_recursive($data, [$this, 'filterValue'], $filter); + reset($data); + } else { + $this->filterValue($data, $name, $filter); + } + + if (isset($type) && $data !== $default) { + // 强制类型转换 + $this->typeCast($data, $type); + } + return $data; + } + + /** + * 设置或获取当前的过滤规则 + * @param mixed $filter 过滤规则 + * @return mixed + */ + public function filter($filter = null) + { + if (is_null($filter)) { + return $this->filter; + } else { + $this->filter = $filter; + } + } + + protected function getFilter($filter, $default) + { + if (is_null($filter)) { + $filter = []; + } else { + $filter = $filter ?: $this->filter; + if (is_string($filter) && false === strpos($filter, '/')) { + $filter = explode(',', $filter); + } else { + $filter = (array) $filter; + } + } + + $filter[] = $default; + return $filter; + } + + /** + * 递归过滤给定的值 + * @param mixed $value 键值 + * @param mixed $key 键名 + * @param array $filters 过滤方法+默认值 + * @return mixed + */ + private function filterValue(&$value, $key, $filters) + { + $default = array_pop($filters); + foreach ($filters as $filter) { + if (is_callable($filter)) { + // 调用函数或者方法过滤 + $value = call_user_func($filter, $value); + } elseif (is_scalar($value)) { + if (false !== strpos($filter, '/')) { + // 正则过滤 + if (!preg_match($filter, $value)) { + // 匹配不成功返回默认值 + $value = $default; + break; + } + } elseif (!empty($filter)) { + // filter函数不存在时, 则使用filter_var进行过滤 + // filter为非整形值时, 调用filter_id取得过滤id + $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter)); + if (false === $value) { + $value = $default; + break; + } + } + } + } + return $this->filterExp($value); + } + + /** + * 过滤表单中的表达式 + * @param string $value + * @return void + */ + public function filterExp(&$value) + { + // 过滤查询特殊字符 + if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) { + $value .= ' '; + } + // TODO 其他安全过滤 + } + + /** + * 强制类型转换 + * @param string $data + * @param string $type + * @return mixed + */ + private function typeCast(&$data, $type) + { + switch (strtolower($type)) { + // 数组 + case 'a': + $data = (array) $data; + break; + // 数字 + case 'd': + $data = (int) $data; + break; + // 浮点 + case 'f': + $data = (float) $data; + break; + // 布尔 + case 'b': + $data = (boolean) $data; + break; + // 字符串 + case 's': + default: + if (is_scalar($data)) { + $data = (string) $data; + } else { + throw new \InvalidArgumentException('variable type error:' . gettype($data)); + } + } + } + + /** + * 是否存在某个请求参数 + * @access public + * @param string $name 变量名 + * @param string $type 变量类型 + * @param bool $checkEmpty 是否检测空值 + * @return mixed + */ + public function has($name, $type = 'param', $checkEmpty = false) + { + if (empty($this->$type)) { + $param = $this->$type(); + } else { + $param = $this->$type; + } + // 按.拆分成多维数组进行判断 + foreach (explode('.', $name) as $val) { + if (isset($param[$val])) { + $param = $param[$val]; + } else { + return false; + } + } + return ($checkEmpty && '' === $param) ? false : true; + } + + /** + * 获取指定的参数 + * @access public + * @param string|array $name 变量名 + * @param string $type 变量类型 + * @return mixed + */ + public function only($name, $type = 'param') + { + $param = $this->$type(); + if (is_string($name)) { + $name = explode(',', $name); + } + $item = []; + foreach ($name as $key) { + if (isset($param[$key])) { + $item[$key] = $param[$key]; + } + } + return $item; + } + + /** + * 排除指定参数获取 + * @access public + * @param string|array $name 变量名 + * @param string $type 变量类型 + * @return mixed + */ + public function except($name, $type = 'param') + { + $param = $this->$type(); + if (is_string($name)) { + $name = explode(',', $name); + } + foreach ($name as $key) { + if (isset($param[$key])) { + unset($param[$key]); + } + } + return $param; + } + + /** + * 当前是否ssl + * @access public + * @return bool + */ + public function isSsl() + { + $server = array_merge($_SERVER, $this->server); + if (isset($server['HTTPS']) && ('1' == $server['HTTPS'] || 'on' == strtolower($server['HTTPS']))) { + return true; + } elseif (isset($server['REQUEST_SCHEME']) && 'https' == $server['REQUEST_SCHEME']) { + return true; + } elseif (isset($server['SERVER_PORT']) && ('443' == $server['SERVER_PORT'])) { + return true; + } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) { + return true; + } elseif (Config::get('https_agent_name') && isset($server[Config::get('https_agent_name')])) { + return true; + } + return false; + } + + /** + * 当前是否Ajax请求 + * @access public + * @param bool $ajax true 获取原始ajax请求 + * @return bool + */ + public function isAjax($ajax = false) + { + $value = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower'); + $result = ('xmlhttprequest' == $value) ? true : false; + if (true === $ajax) { + return $result; + } else { + return $this->param(Config::get('var_ajax')) ? true : $result; + } + } + + /** + * 当前是否Pjax请求 + * @access public + * @param bool $pjax true 获取原始pjax请求 + * @return bool + */ + public function isPjax($pjax = false) + { + $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false; + if (true === $pjax) { + return $result; + } else { + return $this->param(Config::get('var_pjax')) ? true : $result; + } + } + + /** + * 获取客户端IP地址 + * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 + * @param boolean $adv 是否进行高级模式获取(有可能被伪装) + * @return mixed + */ + public function ip($type = 0, $adv = false) + { + $type = $type ? 1 : 0; + static $ip = null; + if (null !== $ip) { + return $ip[$type]; + } + + if ($adv) { + if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); + $pos = array_search('unknown', $arr); + if (false !== $pos) { + unset($arr[$pos]); + } + $ip = trim(current($arr)); + } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + } + } elseif (isset($_SERVER['REMOTE_ADDR'])) { + $ip = $_SERVER['REMOTE_ADDR']; + } + // IP地址合法验证 + $long = sprintf("%u", ip2long($ip)); + $ip = $long ? [$ip, $long] : ['0.0.0.0', 0]; + return $ip[$type]; + } + + /** + * 检测是否使用手机访问 + * @access public + * @return bool + */ + public function isMobile() + { + if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], "wap")) { + return true; + } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), "VND.WAP.WML")) { + return true; + } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) { + return true; + } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) { + return true; + } else { + return false; + } + } + + /** + * 当前URL地址中的scheme参数 + * @access public + * @return string + */ + public function scheme() + { + return $this->isSsl() ? 'https' : 'http'; + } + + /** + * 当前请求URL地址中的query参数 + * @access public + * @return string + */ + public function query() + { + return $this->server('QUERY_STRING'); + } + + /** + * 当前请求的host + * @access public + * @return string + */ + public function host() + { + if (isset($_SERVER['HTTP_X_REAL_HOST'])) { + return $_SERVER['HTTP_X_REAL_HOST']; + } + return $this->server('HTTP_HOST'); + } + + /** + * 当前请求URL地址中的port参数 + * @access public + * @return integer + */ + public function port() + { + return $this->server('SERVER_PORT'); + } + + /** + * 当前请求 SERVER_PROTOCOL + * @access public + * @return integer + */ + public function protocol() + { + return $this->server('SERVER_PROTOCOL'); + } + + /** + * 当前请求 REMOTE_PORT + * @access public + * @return integer + */ + public function remotePort() + { + return $this->server('REMOTE_PORT'); + } + + /** + * 当前请求 HTTP_CONTENT_TYPE + * @access public + * @return string + */ + public function contentType() + { + $contentType = $this->server('CONTENT_TYPE'); + if ($contentType) { + if (strpos($contentType, ';')) { + list($type) = explode(';', $contentType); + } else { + $type = $contentType; + } + return trim($type); + } + return ''; + } + + /** + * 获取当前请求的路由信息 + * @access public + * @param array $route 路由名称 + * @return array + */ + public function routeInfo($route = []) + { + if (!empty($route)) { + $this->routeInfo = $route; + } else { + return $this->routeInfo; + } + } + + /** + * 设置或者获取当前请求的调度信息 + * @access public + * @param array $dispatch 调度信息 + * @return array + */ + public function dispatch($dispatch = null) + { + if (!is_null($dispatch)) { + $this->dispatch = $dispatch; + } + return $this->dispatch; + } + + /** + * 设置或者获取当前的模块名 + * @access public + * @param string $module 模块名 + * @return string|Request + */ + public function module($module = null) + { + if (!is_null($module)) { + $this->module = $module; + return $this; + } else { + return $this->module ?: ''; + } + } + + /** + * 设置或者获取当前的控制器名 + * @access public + * @param string $controller 控制器名 + * @return string|Request + */ + public function controller($controller = null) + { + if (!is_null($controller)) { + $this->controller = $controller; + return $this; + } else { + return $this->controller ?: ''; + } + } + + /** + * 设置或者获取当前的操作名 + * @access public + * @param string $action 操作名 + * @return string|Request + */ + public function action($action = null) + { + if (!is_null($action)) { + $this->action = $action; + return $this; + } else { + return $this->action ?: ''; + } + } + + /** + * 设置或者获取当前的语言 + * @access public + * @param string $lang 语言名 + * @return string|Request + */ + public function langset($lang = null) + { + if (!is_null($lang)) { + $this->langset = $lang; + return $this; + } else { + return $this->langset ?: ''; + } + } + + /** + * 设置或者获取当前请求的content + * @access public + * @return string + */ + public function getContent() + { + if (is_null($this->content)) { + $this->content = $this->input; + } + return $this->content; + } + + /** + * 获取当前请求的php://input + * @access public + * @return string + */ + public function getInput() + { + return $this->input; + } + + /** + * 生成请求令牌 + * @access public + * @param string $name 令牌名称 + * @param mixed $type 令牌生成方法 + * @return string + */ + public function token($name = '__token__', $type = 'md5') + { + $type = is_callable($type) ? $type : 'md5'; + $token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']); + if ($this->isAjax()) { + header($name . ': ' . $token); + } + Session::set($name, $token); + return $token; + } + + /** + * 设置当前地址的请求缓存 + * @access public + * @param string $key 缓存标识,支持变量规则 ,例如 item/:name/:id + * @param mixed $expire 缓存有效期 + * @param array $except 缓存排除 + * @param string $tag 缓存标签 + * @return void + */ + public function cache($key, $expire = null, $except = [], $tag = null) + { + if (!is_array($except)) { + $tag = $except; + $except = []; + } + + if (false !== $key && $this->isGet() && !$this->isCheckCache) { + // 标记请求缓存检查 + $this->isCheckCache = true; + if (false === $expire) { + // 关闭当前缓存 + return; + } + if ($key instanceof \Closure) { + $key = call_user_func_array($key, [$this]); + } elseif (true === $key) { + foreach ($except as $rule) { + if (0 === stripos($this->url(), $rule)) { + return; + } + } + // 自动缓存功能 + $key = '__URL__'; + } elseif (strpos($key, '|')) { + list($key, $fun) = explode('|', $key); + } + // 特殊规则替换 + if (false !== strpos($key, '__')) { + $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url(true))], $key); + } + + if (false !== strpos($key, ':')) { + $param = $this->param(); + foreach ($param as $item => $val) { + if (is_string($val) && false !== strpos($key, ':' . $item)) { + $key = str_replace(':' . $item, $val, $key); + } + } + } elseif (strpos($key, ']')) { + if ('[' . $this->ext() . ']' == $key) { + // 缓存某个后缀的请求 + $key = md5($this->url()); + } else { + return; + } + } + if (isset($fun)) { + $key = $fun($key); + } + + if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) { + // 读取缓存 + $response = Response::create()->code(304); + throw new \think\exception\HttpResponseException($response); + } elseif (Cache::has($key)) { + list($content, $header) = Cache::get($key); + $response = Response::create($content)->header($header); + throw new \think\exception\HttpResponseException($response); + } else { + $this->cache = [$key, $expire, $tag]; + } + } + } + + /** + * 读取请求缓存设置 + * @access public + * @return array + */ + public function getCache() + { + return $this->cache; + } + + /** + * 设置当前请求绑定的对象实例 + * @access public + * @param string|array $name 绑定的对象标识 + * @param mixed $obj 绑定的对象实例 + * @return mixed + */ + public function bind($name, $obj = null) + { + if (is_array($name)) { + $this->bind = array_merge($this->bind, $name); + } else { + $this->bind[$name] = $obj; + } + } + + public function __set($name, $value) + { + $this->bind[$name] = $value; + } + + public function __get($name) + { + return isset($this->bind[$name]) ? $this->bind[$name] : null; + } + + public function __isset($name) + { + return isset($this->bind[$name]); + } +} diff --git a/thinkphp/library/think/Response.php b/thinkphp/library/think/Response.php new file mode 100755 index 0000000..bd30bde --- /dev/null +++ b/thinkphp/library/think/Response.php @@ -0,0 +1,334 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\response\Json as JsonResponse; +use think\response\Jsonp as JsonpResponse; +use think\response\Redirect as RedirectResponse; +use think\response\View as ViewResponse; +use think\response\Xml as XmlResponse; + +class Response +{ + // 原始数据 + protected $data; + + // 当前的contentType + protected $contentType = 'text/html'; + + // 字符集 + protected $charset = 'utf-8'; + + //状态 + protected $code = 200; + + // 输出参数 + protected $options = []; + // header参数 + protected $header = []; + + protected $content = null; + + /** + * 构造函数 + * @access public + * @param mixed $data 输出数据 + * @param int $code + * @param array $header + * @param array $options 输出参数 + */ + public function __construct($data = '', $code = 200, array $header = [], $options = []) + { + $this->data($data); + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + $this->contentType($this->contentType, $this->charset); + $this->header = array_merge($this->header, $header); + $this->code = $code; + } + + /** + * 创建Response对象 + * @access public + * @param mixed $data 输出数据 + * @param string $type 输出类型 + * @param int $code + * @param array $header + * @param array $options 输出参数 + * @return Response|JsonResponse|ViewResponse|XmlResponse|RedirectResponse|JsonpResponse + */ + public static function create($data = '', $type = '', $code = 200, array $header = [], $options = []) + { + $type = empty($type) ? 'null' : strtolower($type); + + $class = false !== strpos($type, '\\') ? $type : '\\think\\response\\' . ucfirst($type); + if (class_exists($class)) { + $response = new $class($data, $code, $header, $options); + } else { + $response = new static($data, $code, $header, $options); + } + + return $response; + } + + /** + * 发送数据到客户端 + * @access public + * @return mixed + * @throws \InvalidArgumentException + */ + public function send() + { + // 监听response_send + Hook::listen('response_send', $this); + + // 处理输出数据 + $data = $this->getContent(); + + // Trace调试注入 + if (Env::get('app_trace', Config::get('app_trace'))) { + Debug::inject($this, $data); + } + + if (200 == $this->code) { + $cache = Request::instance()->getCache(); + if ($cache) { + $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate'; + $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT'; + $this->header['Expires'] = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT'; + Cache::tag($cache[2])->set($cache[0], [$data, $this->header], $cache[1]); + } + } + + if (!headers_sent() && !empty($this->header)) { + // 发送状态码 + http_response_code($this->code); + // 发送头部信息 + foreach ($this->header as $name => $val) { + if (is_null($val)) { + header($name); + } else { + header($name . ':' . $val); + } + } + } + + echo $data; + + if (function_exists('fastcgi_finish_request')) { + // 提高页面响应 + fastcgi_finish_request(); + } + + // 监听response_end + Hook::listen('response_end', $this); + + // 清空当次请求有效的数据 + if (!($this instanceof RedirectResponse)) { + Session::flush(); + } + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + return $data; + } + + /** + * 输出的参数 + * @access public + * @param mixed $options 输出参数 + * @return $this + */ + public function options($options = []) + { + $this->options = array_merge($this->options, $options); + return $this; + } + + /** + * 输出数据设置 + * @access public + * @param mixed $data 输出数据 + * @return $this + */ + public function data($data) + { + $this->data = $data; + return $this; + } + + /** + * 设置响应头 + * @access public + * @param string|array $name 参数名 + * @param string $value 参数值 + * @return $this + */ + public function header($name, $value = null) + { + if (is_array($name)) { + $this->header = array_merge($this->header, $name); + } else { + $this->header[$name] = $value; + } + return $this; + } + + /** + * 设置页面输出内容 + * @param $content + * @return $this + */ + public function content($content) + { + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ + $content, + '__toString', + ]) + ) { + throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); + } + + $this->content = (string) $content; + + return $this; + } + + /** + * 发送HTTP状态 + * @param integer $code 状态码 + * @return $this + */ + public function code($code) + { + $this->code = $code; + return $this; + } + + /** + * LastModified + * @param string $time + * @return $this + */ + public function lastModified($time) + { + $this->header['Last-Modified'] = $time; + return $this; + } + + /** + * Expires + * @param string $time + * @return $this + */ + public function expires($time) + { + $this->header['Expires'] = $time; + return $this; + } + + /** + * ETag + * @param string $eTag + * @return $this + */ + public function eTag($eTag) + { + $this->header['ETag'] = $eTag; + return $this; + } + + /** + * 页面缓存控制 + * @param string $cache 状态码 + * @return $this + */ + public function cacheControl($cache) + { + $this->header['Cache-control'] = $cache; + return $this; + } + + /** + * 页面输出类型 + * @param string $contentType 输出类型 + * @param string $charset 输出编码 + * @return $this + */ + public function contentType($contentType, $charset = 'utf-8') + { + $this->header['Content-Type'] = $contentType . '; charset=' . $charset; + return $this; + } + + /** + * 获取头部信息 + * @param string $name 头部名称 + * @return mixed + */ + public function getHeader($name = '') + { + if (!empty($name)) { + return isset($this->header[$name]) ? $this->header[$name] : null; + } else { + return $this->header; + } + } + + /** + * 获取原始数据 + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * 获取输出数据 + * @return mixed + */ + public function getContent() + { + if (null == $this->content) { + $content = $this->output($this->data); + + if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([ + $content, + '__toString', + ]) + ) { + throw new \InvalidArgumentException(sprintf('variable type error: %s', gettype($content))); + } + + $this->content = (string) $content; + } + return $this->content; + } + + /** + * 获取状态码 + * @return integer + */ + public function getCode() + { + return $this->code; + } +} diff --git a/thinkphp/library/think/Route.php b/thinkphp/library/think/Route.php new file mode 100755 index 0000000..cef35c9 --- /dev/null +++ b/thinkphp/library/think/Route.php @@ -0,0 +1,1603 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\HttpException; + +class Route +{ + // 路由规则 + private static $rules = [ + 'get' => [], + 'post' => [], + 'put' => [], + 'delete' => [], + 'patch' => [], + 'head' => [], + 'options' => [], + '*' => [], + 'alias' => [], + 'domain' => [], + 'pattern' => [], + 'name' => [], + ]; + + // REST路由操作方法定义 + private static $rest = [ + 'index' => ['get', '', 'index'], + 'create' => ['get', '/create', 'create'], + 'edit' => ['get', '/:id/edit', 'edit'], + 'read' => ['get', '/:id', 'read'], + 'save' => ['post', '', 'save'], + 'update' => ['put', '/:id', 'update'], + 'delete' => ['delete', '/:id', 'delete'], + ]; + + // 不同请求类型的方法前缀 + private static $methodPrefix = [ + 'get' => 'get', + 'post' => 'post', + 'put' => 'put', + 'delete' => 'delete', + 'patch' => 'patch', + ]; + + // 子域名 + private static $subDomain = ''; + // 域名绑定 + private static $bind = []; + // 当前分组信息 + private static $group = []; + // 当前子域名绑定 + private static $domainBind; + private static $domainRule; + // 当前域名 + private static $domain; + // 当前路由执行过程中的参数 + private static $option = []; + + /** + * 注册变量规则 + * @access public + * @param string|array $name 变量名 + * @param string $rule 变量规则 + * @return void + */ + public static function pattern($name = null, $rule = '') + { + if (is_array($name)) { + self::$rules['pattern'] = array_merge(self::$rules['pattern'], $name); + } else { + self::$rules['pattern'][$name] = $rule; + } + } + + /** + * 注册子域名部署规则 + * @access public + * @param string|array $domain 子域名 + * @param mixed $rule 路由规则 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function domain($domain, $rule = '', $option = [], $pattern = []) + { + if (is_array($domain)) { + foreach ($domain as $key => $item) { + self::domain($key, $item, $option, $pattern); + } + } elseif ($rule instanceof \Closure) { + // 执行闭包 + self::setDomain($domain); + call_user_func_array($rule, []); + self::setDomain(null); + } elseif (is_array($rule)) { + self::setDomain($domain); + self::group('', function () use ($rule) { + // 动态注册域名的路由规则 + self::registerRules($rule); + }, $option, $pattern); + self::setDomain(null); + } else { + self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern]; + } + } + + private static function setDomain($domain) + { + self::$domain = $domain; + } + + /** + * 设置路由绑定 + * @access public + * @param mixed $bind 绑定信息 + * @param string $type 绑定类型 默认为module 支持 namespace class controller + * @return mixed + */ + public static function bind($bind, $type = 'module') + { + self::$bind = ['type' => $type, $type => $bind]; + } + + /** + * 设置或者获取路由标识 + * @access public + * @param string|array $name 路由命名标识 数组表示批量设置 + * @param array $value 路由地址及变量信息 + * @return array + */ + public static function name($name = '', $value = null) + { + if (is_array($name)) { + return self::$rules['name'] = $name; + } elseif ('' === $name) { + return self::$rules['name']; + } elseif (!is_null($value)) { + self::$rules['name'][strtolower($name)][] = $value; + } else { + $name = strtolower($name); + return isset(self::$rules['name'][$name]) ? self::$rules['name'][$name] : null; + } + } + + /** + * 读取路由绑定 + * @access public + * @param string $type 绑定类型 + * @return mixed + */ + public static function getBind($type) + { + return isset(self::$bind[$type]) ? self::$bind[$type] : null; + } + + /** + * 导入配置文件的路由规则 + * @access public + * @param array $rule 路由规则 + * @param string $type 请求类型 + * @return void + */ + public static function import(array $rule, $type = '*') + { + // 检查域名部署 + if (isset($rule['__domain__'])) { + self::domain($rule['__domain__']); + unset($rule['__domain__']); + } + + // 检查变量规则 + if (isset($rule['__pattern__'])) { + self::pattern($rule['__pattern__']); + unset($rule['__pattern__']); + } + + // 检查路由别名 + if (isset($rule['__alias__'])) { + self::alias($rule['__alias__']); + unset($rule['__alias__']); + } + + // 检查资源路由 + if (isset($rule['__rest__'])) { + self::resource($rule['__rest__']); + unset($rule['__rest__']); + } + + self::registerRules($rule, strtolower($type)); + } + + // 批量注册路由 + protected static function registerRules($rules, $type = '*') + { + foreach ($rules as $key => $val) { + if (is_numeric($key)) { + $key = array_shift($val); + } + if (empty($val)) { + continue; + } + if (is_string($key) && 0 === strpos($key, '[')) { + $key = substr($key, 1, -1); + self::group($key, $val); + } elseif (is_array($val)) { + self::setRule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []); + } else { + self::setRule($key, $val, $type); + } + } + } + + /** + * 注册路由规则 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $type 请求类型 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = []) + { + $group = self::getGroup('name'); + + if (!is_null($group)) { + // 路由分组 + $option = array_merge(self::getGroup('option'), $option); + $pattern = array_merge(self::getGroup('pattern'), $pattern); + } + + $type = strtolower($type); + + if (strpos($type, '|')) { + $option['method'] = $type; + $type = '*'; + } + if (is_array($rule) && empty($route)) { + foreach ($rule as $key => $val) { + if (is_numeric($key)) { + $key = array_shift($val); + } + if (is_array($val)) { + $route = $val[0]; + $option1 = array_merge($option, $val[1]); + $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []); + } else { + $option1 = null; + $pattern1 = null; + $route = $val; + } + self::setRule($key, $route, $type, !is_null($option1) ? $option1 : $option, !is_null($pattern1) ? $pattern1 : $pattern, $group); + } + } else { + self::setRule($rule, $route, $type, $option, $pattern, $group); + } + + } + + /** + * 设置路由规则 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $type 请求类型 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @param string $group 所属分组 + * @return void + */ + protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '') + { + if (is_array($rule)) { + $name = $rule[0]; + $rule = $rule[1]; + } elseif (is_string($route)) { + $name = $route; + } + if (!isset($option['complete_match'])) { + if (Config::get('route_complete_match')) { + $option['complete_match'] = true; + } elseif ('$' == substr($rule, -1, 1)) { + // 是否完整匹配 + $option['complete_match'] = true; + } + } elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) { + // 是否完整匹配 + $option['complete_match'] = true; + } + + if ('$' == substr($rule, -1, 1)) { + $rule = substr($rule, 0, -1); + } + + if ('/' != $rule || $group) { + $rule = trim($rule, '/'); + } + $vars = self::parseVar($rule); + if (isset($name)) { + $key = $group ? $group . ($rule ? '/' . $rule : '') : $rule; + $suffix = isset($option['ext']) ? $option['ext'] : null; + self::name($name, [$key, $vars, self::$domain, $suffix]); + } + if (isset($option['modular'])) { + $route = $option['modular'] . '/' . $route; + } + if ($group) { + if ('*' != $type) { + $option['method'] = $type; + } + if (self::$domain) { + self::$rules['domain'][self::$domain]['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } else { + self::$rules['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } + } else { + if ('*' != $type && isset(self::$rules['*'][$rule])) { + unset(self::$rules['*'][$rule]); + } + if (self::$domain) { + self::$rules['domain'][self::$domain][$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } else { + self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern]; + } + if ('*' == $type) { + // 注册路由快捷方式 + foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) { + if (self::$domain) { + self::$rules['domain'][self::$domain][$method][$rule] = true; + } else { + self::$rules[$method][$rule] = true; + } + } + } + } + } + + /** + * 设置当前执行的参数信息 + * @access public + * @param array $options 参数信息 + * @return mixed + */ + protected static function setOption($options = []) + { + self::$option[] = $options; + } + + /** + * 获取当前执行的所有参数信息 + * @access public + * @return array + */ + public static function getOption() + { + return self::$option; + } + + /** + * 获取当前的分组信息 + * @access public + * @param string $type 分组信息名称 name option pattern + * @return mixed + */ + public static function getGroup($type) + { + if (isset(self::$group[$type])) { + return self::$group[$type]; + } else { + return 'name' == $type ? null : []; + } + } + + /** + * 设置当前的路由分组 + * @access public + * @param string $name 分组名称 + * @param array $option 分组路由参数 + * @param array $pattern 分组变量规则 + * @return void + */ + public static function setGroup($name, $option = [], $pattern = []) + { + self::$group['name'] = $name; + self::$group['option'] = $option ?: []; + self::$group['pattern'] = $pattern ?: []; + } + + /** + * 注册路由分组 + * @access public + * @param string|array $name 分组名称或者参数 + * @param array|\Closure $routes 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function group($name, $routes, $option = [], $pattern = []) + { + if (is_array($name)) { + $option = $name; + $name = isset($option['name']) ? $option['name'] : ''; + } + // 分组 + $currentGroup = self::getGroup('name'); + if ($currentGroup) { + $name = $currentGroup . ($name ? '/' . ltrim($name, '/') : ''); + } + if (!empty($name)) { + if ($routes instanceof \Closure) { + $currentOption = self::getGroup('option'); + $currentPattern = self::getGroup('pattern'); + self::setGroup($name, array_merge($currentOption, $option), array_merge($currentPattern, $pattern)); + call_user_func_array($routes, []); + self::setGroup($currentGroup, $currentOption, $currentPattern); + if ($currentGroup != $name) { + self::$rules['*'][$name]['route'] = ''; + self::$rules['*'][$name]['var'] = self::parseVar($name); + self::$rules['*'][$name]['option'] = $option; + self::$rules['*'][$name]['pattern'] = $pattern; + } + } else { + $item = []; + $completeMatch = Config::get('route_complete_match'); + foreach ($routes as $key => $val) { + if (is_numeric($key)) { + $key = array_shift($val); + } + if (is_array($val)) { + $route = $val[0]; + $option1 = array_merge($option, isset($val[1]) ? $val[1] : []); + $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []); + } else { + $route = $val; + } + + $options = isset($option1) ? $option1 : $option; + $patterns = isset($pattern1) ? $pattern1 : $pattern; + if ('$' == substr($key, -1, 1)) { + // 是否完整匹配 + $options['complete_match'] = true; + $key = substr($key, 0, -1); + } elseif ($completeMatch) { + $options['complete_match'] = true; + } + $key = trim($key, '/'); + $vars = self::parseVar($key); + $item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns]; + // 设置路由标识 + $suffix = isset($options['ext']) ? $options['ext'] : null; + self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain, $suffix]); + } + self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern]; + } + + foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) { + if (!isset(self::$rules[$method][$name])) { + self::$rules[$method][$name] = true; + } elseif (is_array(self::$rules[$method][$name])) { + self::$rules[$method][$name] = array_merge(self::$rules['*'][$name], self::$rules[$method][$name]); + } + } + + } elseif ($routes instanceof \Closure) { + // 闭包注册 + $currentOption = self::getGroup('option'); + $currentPattern = self::getGroup('pattern'); + self::setGroup('', array_merge($currentOption, $option), array_merge($currentPattern, $pattern)); + call_user_func_array($routes, []); + self::setGroup($currentGroup, $currentOption, $currentPattern); + } else { + // 批量注册路由 + self::rule($routes, '', '*', $option, $pattern); + } + } + + /** + * 注册路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function any($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, '*', $option, $pattern); + } + + /** + * 注册GET路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function get($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, 'GET', $option, $pattern); + } + + /** + * 注册POST路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function post($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, 'POST', $option, $pattern); + } + + /** + * 注册PUT路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function put($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, 'PUT', $option, $pattern); + } + + /** + * 注册DELETE路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function delete($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, 'DELETE', $option, $pattern); + } + + /** + * 注册PATCH路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function patch($rule, $route = '', $option = [], $pattern = []) + { + self::rule($rule, $route, 'PATCH', $option, $pattern); + } + + /** + * 注册资源路由 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function resource($rule, $route = '', $option = [], $pattern = []) + { + if (is_array($rule)) { + foreach ($rule as $key => $val) { + if (is_array($val)) { + list($val, $option, $pattern) = array_pad($val, 3, []); + } + self::resource($key, $val, $option, $pattern); + } + } else { + if (strpos($rule, '.')) { + // 注册嵌套资源路由 + $array = explode('.', $rule); + $last = array_pop($array); + $item = []; + foreach ($array as $val) { + $item[] = $val . '/:' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id'); + } + $rule = implode('/', $item) . '/' . $last; + } + // 注册资源路由 + foreach (self::$rest as $key => $val) { + if ((isset($option['only']) && !in_array($key, $option['only'])) + || (isset($option['except']) && in_array($key, $option['except']))) { + continue; + } + if (isset($last) && strpos($val[1], ':id') && isset($option['var'][$last])) { + $val[1] = str_replace(':id', ':' . $option['var'][$last], $val[1]); + } elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) { + $val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]); + } + $item = ltrim($rule . $val[1], '/'); + $option['rest'] = $key; + self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern); + } + } + } + + /** + * 注册控制器路由 操作方法对应不同的请求后缀 + * @access public + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @param array $pattern 变量规则 + * @return void + */ + public static function controller($rule, $route = '', $option = [], $pattern = []) + { + foreach (self::$methodPrefix as $type => $val) { + self::$type($rule . '/:action', $route . '/' . $val . ':action', $option, $pattern); + } + } + + /** + * 注册别名路由 + * @access public + * @param string|array $rule 路由别名 + * @param string $route 路由地址 + * @param array $option 路由参数 + * @return void + */ + public static function alias($rule = null, $route = '', $option = []) + { + if (is_array($rule)) { + self::$rules['alias'] = array_merge(self::$rules['alias'], $rule); + } else { + self::$rules['alias'][$rule] = $option ? [$route, $option] : $route; + } + } + + /** + * 设置不同请求类型下面的方法前缀 + * @access public + * @param string $method 请求类型 + * @param string $prefix 类型前缀 + * @return void + */ + public static function setMethodPrefix($method, $prefix = '') + { + if (is_array($method)) { + self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method)); + } else { + self::$methodPrefix[strtolower($method)] = $prefix; + } + } + + /** + * rest方法定义和修改 + * @access public + * @param string $name 方法名称 + * @param array|bool $resource 资源 + * @return void + */ + public static function rest($name, $resource = []) + { + if (is_array($name)) { + self::$rest = $resource ? $name : array_merge(self::$rest, $name); + } else { + self::$rest[$name] = $resource; + } + } + + /** + * 注册未匹配路由规则后的处理 + * @access public + * @param string $route 路由地址 + * @param string $method 请求类型 + * @param array $option 路由参数 + * @return void + */ + public static function miss($route, $method = '*', $option = []) + { + self::rule('__miss__', $route, $method, $option, []); + } + + /** + * 注册一个自动解析的URL路由 + * @access public + * @param string $route 路由地址 + * @return void + */ + public static function auto($route) + { + self::rule('__auto__', $route, '*', [], []); + } + + /** + * 获取或者批量设置路由定义 + * @access public + * @param mixed $rules 请求类型或者路由定义数组 + * @return array + */ + public static function rules($rules = '') + { + if (is_array($rules)) { + self::$rules = $rules; + } elseif ($rules) { + return true === $rules ? self::$rules : self::$rules[strtolower($rules)]; + } else { + $rules = self::$rules; + unset($rules['pattern'], $rules['alias'], $rules['domain'], $rules['name']); + return $rules; + } + } + + /** + * 检测子域名部署 + * @access public + * @param Request $request Request请求对象 + * @param array $currentRules 当前路由规则 + * @param string $method 请求类型 + * @return void + */ + public static function checkDomain($request, &$currentRules, $method = 'get') + { + // 域名规则 + $rules = self::$rules['domain']; + // 开启子域名部署 支持二级和三级域名 + if (!empty($rules)) { + $host = $request->host(); + if (isset($rules[$host])) { + // 完整域名或者IP配置 + $item = $rules[$host]; + } else { + $rootDomain = Config::get('url_domain_root'); + if ($rootDomain) { + // 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置 + $domain = explode('.', rtrim(stristr($host, $rootDomain, true), '.')); + } else { + $domain = explode('.', $host, -2); + } + // 子域名配置 + if (!empty($domain)) { + // 当前子域名 + $subDomain = implode('.', $domain); + self::$subDomain = $subDomain; + $domain2 = array_pop($domain); + if ($domain) { + // 存在三级域名 + $domain3 = array_pop($domain); + } + if ($subDomain && isset($rules[$subDomain])) { + // 子域名配置 + $item = $rules[$subDomain]; + } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) { + // 泛三级域名 + $item = $rules['*.' . $domain2]; + $panDomain = $domain3; + } elseif (isset($rules['*']) && !empty($domain2)) { + // 泛二级域名 + if ('www' != $domain2) { + $item = $rules['*']; + $panDomain = $domain2; + } + } + } + } + if (!empty($item)) { + if (isset($panDomain)) { + // 保存当前泛域名 + $request->route(['__domain__' => $panDomain]); + } + if (isset($item['[bind]'])) { + // 解析子域名部署规则 + list($rule, $option, $pattern) = $item['[bind]']; + if (!empty($option['https']) && !$request->isSsl()) { + // https检测 + throw new HttpException(404, 'must use https request:' . $host); + } + + if (strpos($rule, '?')) { + // 传入其它参数 + $array = parse_url($rule); + $result = $array['path']; + parse_str($array['query'], $params); + if (isset($panDomain)) { + $pos = array_search('*', $params); + if (false !== $pos) { + // 泛域名作为参数 + $params[$pos] = $panDomain; + } + } + $_GET = array_merge($_GET, $params); + } else { + $result = $rule; + } + + if (0 === strpos($result, '\\')) { + // 绑定到命名空间 例如 \app\index\behavior + self::$bind = ['type' => 'namespace', 'namespace' => $result]; + } elseif (0 === strpos($result, '@')) { + // 绑定到类 例如 @app\index\controller\User + self::$bind = ['type' => 'class', 'class' => substr($result, 1)]; + } else { + // 绑定到模块/控制器 例如 index/user + self::$bind = ['type' => 'module', 'module' => $result]; + } + self::$domainBind = true; + } else { + self::$domainRule = $item; + $currentRules = isset($item[$method]) ? $item[$method] : $item['*']; + } + } + } + } + + /** + * 检测URL路由 + * @access public + * @param Request $request Request请求对象 + * @param string $url URL地址 + * @param string $depr URL分隔符 + * @param bool $checkDomain 是否检测域名规则 + * @return false|array + */ + public static function check($request, $url, $depr = '/', $checkDomain = false) + { + // 分隔符替换 确保路由定义使用统一的分隔符 + $url = str_replace($depr, '|', $url); + + if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) { + // 检测路由别名 + $result = self::checkRouteAlias($request, $url, $depr); + if (false !== $result) { + return $result; + } + } + $method = strtolower($request->method()); + // 获取当前请求类型的路由规则 + $rules = isset(self::$rules[$method]) ? self::$rules[$method] : []; + // 检测域名部署 + if ($checkDomain) { + self::checkDomain($request, $rules, $method); + } + // 检测URL绑定 + $return = self::checkUrlBind($url, $rules, $depr); + if (false !== $return) { + return $return; + } + if ('|' != $url) { + $url = rtrim($url, '|'); + } + $item = str_replace('|', '/', $url); + if (isset($rules[$item])) { + // 静态路由规则检测 + $rule = $rules[$item]; + if (true === $rule) { + $rule = self::getRouteExpress($item); + } + if (!empty($rule['route']) && self::checkOption($rule['option'], $request)) { + self::setOption($rule['option']); + return self::parseRule($item, $rule['route'], $url, $rule['option']); + } + } + + // 路由规则检测 + if (!empty($rules)) { + return self::checkRoute($request, $rules, $url, $depr); + } + return false; + } + + private static function getRouteExpress($key) + { + return self::$domainRule ? self::$domainRule['*'][$key] : self::$rules['*'][$key]; + } + + /** + * 检测路由规则 + * @access private + * @param Request $request + * @param array $rules 路由规则 + * @param string $url URL地址 + * @param string $depr URL分割符 + * @param string $group 路由分组名 + * @param array $options 路由参数(分组) + * @return mixed + */ + private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = []) + { + foreach ($rules as $key => $item) { + if (true === $item) { + $item = self::getRouteExpress($key); + } + if (!isset($item['rule'])) { + continue; + } + $rule = $item['rule']; + $route = $item['route']; + $vars = $item['var']; + $option = $item['option']; + $pattern = $item['pattern']; + + // 检查参数有效性 + if (!self::checkOption($option, $request)) { + continue; + } + + if (isset($option['ext'])) { + // 路由ext参数 优先于系统配置的URL伪静态后缀参数 + $url = preg_replace('/\.' . $request->ext() . '$/i', '', $url); + } + + if (is_array($rule)) { + // 分组路由 + $pos = strpos(str_replace('<', ':', $key), ':'); + if (false !== $pos) { + $str = substr($key, 0, $pos); + } else { + $str = $key; + } + if (is_string($str) && $str && 0 !== stripos(str_replace('|', '/', $url), $str)) { + continue; + } + self::setOption($option); + $result = self::checkRoute($request, $rule, $url, $depr, $key, $option); + if (false !== $result) { + return $result; + } + } elseif ($route) { + if ('__miss__' == $rule || '__auto__' == $rule) { + // 指定特殊路由 + $var = trim($rule, '__'); + ${$var} = $item; + continue; + } + if ($group) { + $rule = $group . ($rule ? '/' . ltrim($rule, '/') : ''); + } + + self::setOption($option); + if (isset($options['bind_model']) && isset($option['bind_model'])) { + $option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']); + } + $result = self::checkRule($rule, $route, $url, $pattern, $option, $depr); + if (false !== $result) { + return $result; + } + } + } + if (isset($auto)) { + // 自动解析URL地址 + return self::parseUrl($auto['route'] . '/' . $url, $depr); + } elseif (isset($miss)) { + // 未匹配所有路由的路由规则处理 + return self::parseRule('', $miss['route'], $url, $miss['option']); + } + return false; + } + + /** + * 检测路由别名 + * @access private + * @param Request $request + * @param string $url URL地址 + * @param string $depr URL分隔符 + * @return mixed + */ + private static function checkRouteAlias($request, $url, $depr) + { + $array = explode('|', $url); + $alias = array_shift($array); + $item = self::$rules['alias'][$alias]; + + if (is_array($item)) { + list($rule, $option) = $item; + $action = $array[0]; + if (isset($option['allow']) && !in_array($action, explode(',', $option['allow']))) { + // 允许操作 + return false; + } elseif (isset($option['except']) && in_array($action, explode(',', $option['except']))) { + // 排除操作 + return false; + } + if (isset($option['method'][$action])) { + $option['method'] = $option['method'][$action]; + } + } else { + $rule = $item; + } + $bind = implode('|', $array); + // 参数有效性检查 + if (isset($option) && !self::checkOption($option, $request)) { + // 路由不匹配 + return false; + } elseif (0 === strpos($rule, '\\')) { + // 路由到类 + return self::bindToClass($bind, substr($rule, 1), $depr); + } elseif (0 === strpos($rule, '@')) { + // 路由到控制器类 + return self::bindToController($bind, substr($rule, 1), $depr); + } else { + // 路由到模块/控制器 + return self::bindToModule($bind, $rule, $depr); + } + } + + /** + * 检测URL绑定 + * @access private + * @param string $url URL地址 + * @param array $rules 路由规则 + * @param string $depr URL分隔符 + * @return mixed + */ + private static function checkUrlBind(&$url, &$rules, $depr = '/') + { + if (!empty(self::$bind)) { + $type = self::$bind['type']; + $bind = self::$bind[$type]; + // 记录绑定信息 + App::$debug && Log::record('[ BIND ] ' . var_export($bind, true), 'info'); + // 如果有URL绑定 则进行绑定检测 + switch ($type) { + case 'class': + // 绑定到类 + return self::bindToClass($url, $bind, $depr); + case 'controller': + // 绑定到控制器类 + return self::bindToController($url, $bind, $depr); + case 'namespace': + // 绑定到命名空间 + return self::bindToNamespace($url, $bind, $depr); + } + } + return false; + } + + /** + * 绑定到类 + * @access public + * @param string $url URL地址 + * @param string $class 类名(带命名空间) + * @param string $depr URL分隔符 + * @return array + */ + public static function bindToClass($url, $class, $depr = '/') + { + $url = str_replace($depr, '|', $url); + $array = explode('|', $url, 2); + $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); + if (!empty($array[1])) { + self::parseUrlParams($array[1]); + } + return ['type' => 'method', 'method' => [$class, $action], 'var' => []]; + } + + /** + * 绑定到命名空间 + * @access public + * @param string $url URL地址 + * @param string $namespace 命名空间 + * @param string $depr URL分隔符 + * @return array + */ + public static function bindToNamespace($url, $namespace, $depr = '/') + { + $url = str_replace($depr, '|', $url); + $array = explode('|', $url, 3); + $class = !empty($array[0]) ? $array[0] : Config::get('default_controller'); + $method = !empty($array[1]) ? $array[1] : Config::get('default_action'); + if (!empty($array[2])) { + self::parseUrlParams($array[2]); + } + return ['type' => 'method', 'method' => [$namespace . '\\' . Loader::parseName($class, 1), $method], 'var' => []]; + } + + /** + * 绑定到控制器类 + * @access public + * @param string $url URL地址 + * @param string $controller 控制器名 (支持带模块名 index/user ) + * @param string $depr URL分隔符 + * @return array + */ + public static function bindToController($url, $controller, $depr = '/') + { + $url = str_replace($depr, '|', $url); + $array = explode('|', $url, 2); + $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); + if (!empty($array[1])) { + self::parseUrlParams($array[1]); + } + return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'var' => []]; + } + + /** + * 绑定到模块/控制器 + * @access public + * @param string $url URL地址 + * @param string $controller 控制器类名(带命名空间) + * @param string $depr URL分隔符 + * @return array + */ + public static function bindToModule($url, $controller, $depr = '/') + { + $url = str_replace($depr, '|', $url); + $array = explode('|', $url, 2); + $action = !empty($array[0]) ? $array[0] : Config::get('default_action'); + if (!empty($array[1])) { + self::parseUrlParams($array[1]); + } + return ['type' => 'module', 'module' => $controller . '/' . $action]; + } + + /** + * 路由参数有效性检查 + * @access private + * @param array $option 路由参数 + * @param Request $request Request对象 + * @return bool + */ + private static function checkOption($option, $request) + { + if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method())) + || (isset($option['ajax']) && $option['ajax'] && !$request->isAjax()) // Ajax检测 + || (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测 + || (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测 + || (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测 + || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) // 伪静态后缀检测 + || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|')) + || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测 + || (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测 + || (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测 + || (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'])) // 行为检测 + || (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测 + ) { + return false; + } + return true; + } + + /** + * 检测路由规则 + * @access private + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $url URL地址 + * @param array $pattern 变量规则 + * @param array $option 路由参数 + * @param string $depr URL分隔符(全局) + * @return array|false + */ + private static function checkRule($rule, $route, $url, $pattern, $option, $depr) + { + // 检查完整规则定义 + if (isset($pattern['__url__']) && !preg_match(0 === strpos($pattern['__url__'], '/') ? $pattern['__url__'] : '/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) { + return false; + } + // 检查路由的参数分隔符 + if (isset($option['param_depr'])) { + $url = str_replace(['|', $option['param_depr']], [$depr, '|'], $url); + } + + $len1 = substr_count($url, '|'); + $len2 = substr_count($rule, '/'); + // 多余参数是否合并 + $merge = !empty($option['merge_extra_vars']); + if ($merge && $len1 > $len2) { + $url = str_replace('|', $depr, $url); + $url = implode('|', explode($depr, $url, $len2 + 1)); + } + + if ($len1 >= $len2 || strpos($rule, '[')) { + if (!empty($option['complete_match'])) { + // 完整匹配 + if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) { + return false; + } + } + $pattern = array_merge(self::$rules['pattern'], $pattern); + if (false !== $match = self::match($url, $rule, $pattern)) { + // 匹配到路由规则 + return self::parseRule($rule, $route, $url, $option, $match); + } + } + return false; + } + + /** + * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2... + * @access public + * @param string $url URL地址 + * @param string $depr URL分隔符 + * @param bool $autoSearch 是否自动深度搜索控制器 + * @return array + */ + public static function parseUrl($url, $depr = '/', $autoSearch = false) + { + + if (isset(self::$bind['module'])) { + $bind = str_replace('/', $depr, self::$bind['module']); + // 如果有模块/控制器绑定 + $url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr); + } + $url = str_replace($depr, '|', $url); + list($path, $var) = self::parseUrlPath($url); + $route = [null, null, null]; + if (isset($path)) { + // 解析模块 + $module = Config::get('app_multi_module') ? array_shift($path) : null; + if ($autoSearch) { + // 自动搜索控制器 + $dir = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer'); + $suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : ''; + $item = []; + $find = false; + foreach ($path as $val) { + $item[] = $val; + $file = $dir . DS . str_replace('.', DS, $val) . $suffix . EXT; + $file = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT; + if (is_file($file)) { + $find = true; + break; + } else { + $dir .= DS . Loader::parseName($val); + } + } + if ($find) { + $controller = implode('.', $item); + $path = array_slice($path, count($item)); + } else { + $controller = array_shift($path); + } + } else { + // 解析控制器 + $controller = !empty($path) ? array_shift($path) : null; + } + // 解析操作 + $action = !empty($path) ? array_shift($path) : null; + // 解析额外参数 + self::parseUrlParams(empty($path) ? '' : implode('|', $path)); + // 封装路由 + $route = [$module, $controller, $action]; + // 检查地址是否被定义过路由 + $name = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action); + $name2 = ''; + if (empty($module) || isset($bind) && $module == $bind) { + $name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action); + } + + if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) { + throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url)); + } + } + return ['type' => 'module', 'module' => $route]; + } + + /** + * 解析URL的pathinfo参数和变量 + * @access private + * @param string $url URL地址 + * @return array + */ + private static function parseUrlPath($url) + { + // 分隔符替换 确保路由定义使用统一的分隔符 + $url = str_replace('|', '/', $url); + $url = trim($url, '/'); + $var = []; + if (false !== strpos($url, '?')) { + // [模块/控制器/操作?]参数1=值1&参数2=值2... + $info = parse_url($url); + $path = explode('/', $info['path']); + parse_str($info['query'], $var); + } elseif (strpos($url, '/')) { + // [模块/控制器/操作] + $path = explode('/', $url); + } else { + $path = [$url]; + } + return [$path, $var]; + } + + /** + * 检测URL和规则路由是否匹配 + * @access private + * @param string $url URL地址 + * @param string $rule 路由规则 + * @param array $pattern 变量规则 + * @return array|false + */ + private static function match($url, $rule, $pattern) + { + $m2 = explode('/', $rule); + $m1 = explode('|', $url); + + $var = []; + foreach ($m2 as $key => $val) { + // val中定义了多个变量 <id><name> + if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { + $value = []; + $replace = []; + foreach ($matches[1] as $name) { + if (strpos($name, '?')) { + $name = substr($name, 0, -1); + $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')?'; + } else { + $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\w+') . ')'; + } + $value[] = $name; + } + $val = str_replace($matches[0], $replace, $val); + if (preg_match('/^' . $val . '$/', isset($m1[$key]) ? $m1[$key] : '', $match)) { + array_shift($match); + foreach ($value as $k => $name) { + if (isset($match[$k])) { + $var[$name] = $match[$k]; + } + } + continue; + } else { + return false; + } + } + + if (0 === strpos($val, '[:')) { + // 可选参数 + $val = substr($val, 1, -1); + $optional = true; + } else { + $optional = false; + } + if (0 === strpos($val, ':')) { + // URL变量 + $name = substr($val, 1); + if (!$optional && !isset($m1[$key])) { + return false; + } + if (isset($m1[$key]) && isset($pattern[$name])) { + // 检查变量规则 + if ($pattern[$name] instanceof \Closure) { + $result = call_user_func_array($pattern[$name], [$m1[$key]]); + if (false === $result) { + return false; + } + } elseif (!preg_match(0 === strpos($pattern[$name], '/') ? $pattern[$name] : '/^' . $pattern[$name] . '$/', $m1[$key])) { + return false; + } + } + $var[$name] = isset($m1[$key]) ? $m1[$key] : ''; + } elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) { + return false; + } + } + // 成功匹配后返回URL中的动态变量数组 + return $var; + } + + /** + * 解析规则路由 + * @access private + * @param string $rule 路由规则 + * @param string $route 路由地址 + * @param string $pathinfo URL地址 + * @param array $option 路由参数 + * @param array $matches 匹配的变量 + * @return array + */ + private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = []) + { + $request = Request::instance(); + // 解析路由规则 + if ($rule) { + $rule = explode('/', $rule); + // 获取URL地址中的参数 + $paths = explode('|', $pathinfo); + foreach ($rule as $item) { + $fun = ''; + if (0 === strpos($item, '[:')) { + $item = substr($item, 1, -1); + } + if (0 === strpos($item, ':')) { + $var = substr($item, 1); + $matches[$var] = array_shift($paths); + } else { + // 过滤URL中的静态变量 + array_shift($paths); + } + } + } else { + $paths = explode('|', $pathinfo); + } + + // 获取路由地址规则 + if (is_string($route) && isset($option['prefix'])) { + // 路由地址前缀 + $route = $option['prefix'] . $route; + } + // 替换路由地址中的变量 + if (is_string($route) && !empty($matches)) { + foreach ($matches as $key => $val) { + if (false !== strpos($route, ':' . $key)) { + $route = str_replace(':' . $key, $val, $route); + } + } + } + + // 绑定模型数据 + if (isset($option['bind_model'])) { + $bind = []; + foreach ($option['bind_model'] as $key => $val) { + if ($val instanceof \Closure) { + $result = call_user_func_array($val, [$matches]); + } else { + if (is_array($val)) { + $fields = explode('&', $val[1]); + $model = $val[0]; + $exception = isset($val[2]) ? $val[2] : true; + } else { + $fields = ['id']; + $model = $val; + $exception = true; + } + $where = []; + $match = true; + foreach ($fields as $field) { + if (!isset($matches[$field])) { + $match = false; + break; + } else { + $where[$field] = $matches[$field]; + } + } + if ($match) { + $query = strpos($model, '\\') ? $model::where($where) : Loader::model($model)->where($where); + $result = $query->failException($exception)->find(); + } + } + if (!empty($result)) { + $bind[$key] = $result; + } + } + $request->bind($bind); + } + + if (!empty($option['response'])) { + Hook::add('response_send', $option['response']); + } + + // 解析额外参数 + self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches); + // 记录匹配的路由信息 + $request->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]); + + // 检测路由after行为 + if (!empty($option['after_behavior'])) { + if ($option['after_behavior'] instanceof \Closure) { + $result = call_user_func_array($option['after_behavior'], []); + } else { + foreach ((array) $option['after_behavior'] as $behavior) { + $result = Hook::exec($behavior, ''); + if (!is_null($result)) { + break; + } + } + } + // 路由规则重定向 + if ($result instanceof Response) { + return ['type' => 'response', 'response' => $result]; + } elseif (is_array($result)) { + return $result; + } + } + + if ($route instanceof \Closure) { + // 执行闭包 + $result = ['type' => 'function', 'function' => $route]; + } elseif (0 === strpos($route, '/') || strpos($route, '://')) { + // 路由到重定向地址 + $result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301]; + } elseif (false !== strpos($route, '\\')) { + // 路由到方法 + list($path, $var) = self::parseUrlPath($route); + $route = str_replace('/', '@', implode('/', $path)); + $method = strpos($route, '@') ? explode('@', $route) : $route; + $result = ['type' => 'method', 'method' => $method, 'var' => $var]; + } elseif (0 === strpos($route, '@')) { + // 路由到控制器 + $route = substr($route, 1); + list($route, $var) = self::parseUrlPath($route); + $result = ['type' => 'controller', 'controller' => implode('/', $route), 'var' => $var]; + $request->action(array_pop($route)); + $request->controller($route ? array_pop($route) : Config::get('default_controller')); + $request->module($route ? array_pop($route) : Config::get('default_module')); + App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : ''); + } else { + // 路由到模块/控制器/操作 + $result = self::parseModule($route); + } + // 开启请求缓存 + if ($request->isGet() && isset($option['cache'])) { + $cache = $option['cache']; + if (is_array($cache)) { + list($key, $expire, $tag) = array_pad($cache, 3, null); + } else { + $key = str_replace('|', '/', $pathinfo); + $expire = $cache; + $tag = null; + } + $request->cache($key, $expire, $tag); + } + return $result; + } + + /** + * 解析URL地址为 模块/控制器/操作 + * @access private + * @param string $url URL地址 + * @return array + */ + private static function parseModule($url) + { + list($path, $var) = self::parseUrlPath($url); + $action = array_pop($path); + $controller = !empty($path) ? array_pop($path) : null; + $module = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null; + $method = Request::instance()->method(); + if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) { + // 操作方法前缀支持 + $action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action; + } + // 设置当前请求的路由变量 + Request::instance()->route($var); + // 路由到模块/控制器/操作 + return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false]; + } + + /** + * 解析URL地址中的参数Request对象 + * @access private + * @param string $url 路由规则 + * @param array $var 变量 + * @return void + */ + private static function parseUrlParams($url, &$var = []) + { + if ($url) { + if (Config::get('url_param_type')) { + $var += explode('|', $url); + } else { + preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) { + $var[$match[1]] = strip_tags($match[2]); + }, $url); + } + } + // 设置当前请求的参数 + Request::instance()->route($var); + } + + // 分析路由规则中的变量 + private static function parseVar($rule) + { + // 提取路由规则中的变量 + $var = []; + foreach (explode('/', $rule) as $val) { + $optional = false; + if (false !== strpos($val, '<') && preg_match_all('/<(\w+(\??))>/', $val, $matches)) { + foreach ($matches[1] as $name) { + if (strpos($name, '?')) { + $name = substr($name, 0, -1); + $optional = true; + } else { + $optional = false; + } + $var[$name] = $optional ? 2 : 1; + } + } + + if (0 === strpos($val, '[:')) { + // 可选参数 + $optional = true; + $val = substr($val, 1, -1); + } + if (0 === strpos($val, ':')) { + // URL变量 + $name = substr($val, 1); + $var[$name] = $optional ? 2 : 1; + } + } + return $var; + } +} diff --git a/thinkphp/library/think/Session.php b/thinkphp/library/think/Session.php new file mode 100755 index 0000000..1d02518 --- /dev/null +++ b/thinkphp/library/think/Session.php @@ -0,0 +1,366 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; + +class Session +{ + protected static $prefix = ''; + protected static $init = null; + + /** + * 设置或者获取session作用域(前缀) + * @param string $prefix + * @return string|void + */ + public static function prefix($prefix = '') + { + empty(self::$init) && self::boot(); + if (empty($prefix) && null !== $prefix) { + return self::$prefix; + } else { + self::$prefix = $prefix; + } + } + + /** + * session初始化 + * @param array $config + * @return void + * @throws \think\Exception + */ + public static function init(array $config = []) + { + if (empty($config)) { + $config = Config::get('session'); + } + // 记录初始化信息 + App::$debug && Log::record('[ SESSION ] INIT ' . var_export($config, true), 'info'); + $isDoStart = false; + if (isset($config['use_trans_sid'])) { + ini_set('session.use_trans_sid', $config['use_trans_sid'] ? 1 : 0); + } + + // 启动session + if (!empty($config['auto_start']) && PHP_SESSION_ACTIVE != session_status()) { + ini_set('session.auto_start', 0); + $isDoStart = true; + } + + if (isset($config['prefix']) && ('' === self::$prefix || null === self::$prefix)) { + self::$prefix = $config['prefix']; + } + if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) { + session_id($_REQUEST[$config['var_session_id']]); + } elseif (isset($config['id']) && !empty($config['id'])) { + session_id($config['id']); + } + if (isset($config['name'])) { + session_name($config['name']); + } + if (isset($config['path'])) { + session_save_path($config['path']); + } + if (isset($config['domain'])) { + ini_set('session.cookie_domain', $config['domain']); + } + if (isset($config['expire'])) { + ini_set('session.gc_maxlifetime', $config['expire']); + ini_set('session.cookie_lifetime', $config['expire']); + } + if (isset($config['secure'])) { + ini_set('session.cookie_secure', $config['secure']); + } + if (isset($config['httponly'])) { + ini_set('session.cookie_httponly', $config['httponly']); + } + if (isset($config['use_cookies'])) { + ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0); + } + if (isset($config['cache_limiter'])) { + session_cache_limiter($config['cache_limiter']); + } + if (isset($config['cache_expire'])) { + session_cache_expire($config['cache_expire']); + } + if (!empty($config['type'])) { + // 读取session驱动 + $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\session\\driver\\' . ucwords($config['type']); + + // 检查驱动类 + if (!class_exists($class) || !session_set_save_handler(new $class($config))) { + throw new ClassNotFoundException('error session handler:' . $class, $class); + } + } + if ($isDoStart) { + session_start(); + self::$init = true; + } else { + self::$init = false; + } + } + + /** + * session自动启动或者初始化 + * @return void + */ + public static function boot() + { + if (is_null(self::$init)) { + self::init(); + } elseif (false === self::$init) { + if (PHP_SESSION_ACTIVE != session_status()) { + session_start(); + } + self::$init = true; + } + } + + /** + * session设置 + * @param string $name session名称 + * @param mixed $value session值 + * @param string|null $prefix 作用域(前缀) + * @return void + */ + public static function set($name, $value = '', $prefix = null) + { + empty(self::$init) && self::boot(); + + $prefix = !is_null($prefix) ? $prefix : self::$prefix; + if (strpos($name, '.')) { + // 二维数组赋值 + list($name1, $name2) = explode('.', $name); + if ($prefix) { + $_SESSION[$prefix][$name1][$name2] = $value; + } else { + $_SESSION[$name1][$name2] = $value; + } + } elseif ($prefix) { + $_SESSION[$prefix][$name] = $value; + } else { + $_SESSION[$name] = $value; + } + } + + /** + * session获取 + * @param string $name session名称 + * @param string|null $prefix 作用域(前缀) + * @return mixed + */ + public static function get($name = '', $prefix = null) + { + empty(self::$init) && self::boot(); + $prefix = !is_null($prefix) ? $prefix : self::$prefix; + if ('' == $name) { + // 获取全部的session + $value = $prefix ? (!empty($_SESSION[$prefix]) ? $_SESSION[$prefix] : []) : $_SESSION; + } elseif ($prefix) { + // 获取session + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + $value = isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null; + } else { + $value = isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null; + } + } else { + if (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + $value = isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null; + } else { + $value = isset($_SESSION[$name]) ? $_SESSION[$name] : null; + } + } + return $value; + } + + /** + * session获取并删除 + * @param string $name session名称 + * @param string|null $prefix 作用域(前缀) + * @return mixed + */ + public static function pull($name, $prefix = null) + { + $result = self::get($name, $prefix); + if ($result) { + self::delete($name, $prefix); + return $result; + } else { + return; + } + } + + /** + * session设置 下一次请求有效 + * @param string $name session名称 + * @param mixed $value session值 + * @param string|null $prefix 作用域(前缀) + * @return void + */ + public static function flash($name, $value) + { + self::set($name, $value); + if (!self::has('__flash__.__time__')) { + self::set('__flash__.__time__', $_SERVER['REQUEST_TIME_FLOAT']); + } + self::push('__flash__', $name); + } + + /** + * 清空当前请求的session数据 + * @return void + */ + public static function flush() + { + if (self::$init) { + $item = self::get('__flash__'); + + if (!empty($item)) { + $time = $item['__time__']; + if ($_SERVER['REQUEST_TIME_FLOAT'] > $time) { + unset($item['__time__']); + self::delete($item); + self::set('__flash__', []); + } + } + } + } + + /** + * 删除session数据 + * @param string|array $name session名称 + * @param string|null $prefix 作用域(前缀) + * @return void + */ + public static function delete($name, $prefix = null) + { + empty(self::$init) && self::boot(); + $prefix = !is_null($prefix) ? $prefix : self::$prefix; + if (is_array($name)) { + foreach ($name as $key) { + self::delete($key, $prefix); + } + } elseif (strpos($name, '.')) { + list($name1, $name2) = explode('.', $name); + if ($prefix) { + unset($_SESSION[$prefix][$name1][$name2]); + } else { + unset($_SESSION[$name1][$name2]); + } + } else { + if ($prefix) { + unset($_SESSION[$prefix][$name]); + } else { + unset($_SESSION[$name]); + } + } + } + + /** + * 清空session数据 + * @param string|null $prefix 作用域(前缀) + * @return void + */ + public static function clear($prefix = null) + { + empty(self::$init) && self::boot(); + $prefix = !is_null($prefix) ? $prefix : self::$prefix; + if ($prefix) { + unset($_SESSION[$prefix]); + } else { + $_SESSION = []; + } + } + + /** + * 判断session数据 + * @param string $name session名称 + * @param string|null $prefix + * @return bool + */ + public static function has($name, $prefix = null) + { + empty(self::$init) && self::boot(); + $prefix = !is_null($prefix) ? $prefix : self::$prefix; + if (strpos($name, '.')) { + // 支持数组 + list($name1, $name2) = explode('.', $name); + return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]); + } else { + return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]); + } + } + + /** + * 添加数据到一个session数组 + * @param string $key + * @param mixed $value + * @return void + */ + public static function push($key, $value) + { + $array = self::get($key); + if (is_null($array)) { + $array = []; + } + $array[] = $value; + self::set($key, $array); + } + + /** + * 启动session + * @return void + */ + public static function start() + { + session_start(); + self::$init = true; + } + + /** + * 销毁session + * @return void + */ + public static function destroy() + { + if (!empty($_SESSION)) { + $_SESSION = []; + } + session_unset(); + session_destroy(); + self::$init = null; + } + + /** + * 重新生成session_id + * @param bool $delete 是否删除关联会话文件 + * @return void + */ + public static function regenerate($delete = false) + { + session_regenerate_id($delete); + } + + /** + * 暂停session + * @return void + */ + public static function pause() + { + // 暂停session + session_write_close(); + self::$init = false; + } +} diff --git a/thinkphp/library/think/Template.php b/thinkphp/library/think/Template.php new file mode 100755 index 0000000..3ec89e5 --- /dev/null +++ b/thinkphp/library/think/Template.php @@ -0,0 +1,1147 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\TemplateNotFoundException; + +/** + * ThinkPHP分离出来的模板引擎 + * 支持XML标签和普通标签的模板解析 + * 编译型模板引擎 支持动态缓存 + */ +class Template +{ + // 模板变量 + protected $data = []; + // 引擎配置 + protected $config = [ + 'view_path' => '', // 模板路径 + 'view_base' => '', + 'view_suffix' => 'html', // 默认模板文件后缀 + 'view_depr' => DS, + 'cache_suffix' => 'php', // 默认模板缓存后缀 + 'tpl_deny_func_list' => 'echo,exit', // 模板引擎禁用函数 + 'tpl_deny_php' => false, // 默认模板引擎是否禁用PHP原生代码 + 'tpl_begin' => '{', // 模板引擎普通标签开始标记 + 'tpl_end' => '}', // 模板引擎普通标签结束标记 + 'strip_space' => false, // 是否去除模板文件里面的html空格与换行 + 'tpl_cache' => true, // 是否开启模板编译缓存,设为false则每次都会重新编译 + 'compile_type' => 'file', // 模板编译类型 + 'cache_prefix' => '', // 模板缓存前缀标识,可以动态改变 + 'cache_time' => 0, // 模板缓存有效期 0 为永久,(以数字为值,单位:秒) + 'layout_on' => false, // 布局模板开关 + 'layout_name' => 'layout', // 布局模板入口文件 + 'layout_item' => '{__CONTENT__}', // 布局模板的内容替换标识 + 'taglib_begin' => '{', // 标签库标签开始标记 + 'taglib_end' => '}', // 标签库标签结束标记 + 'taglib_load' => true, // 是否使用内置标签库之外的其它标签库,默认自动检测 + 'taglib_build_in' => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序 + 'taglib_pre_load' => '', // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔 + 'display_cache' => false, // 模板渲染缓存 + 'cache_id' => '', // 模板缓存ID + 'tpl_replace_string' => [], + 'tpl_var_identify' => 'array', // .语法变量识别,array|object|'', 为空时自动识别 + ]; + + private $literal = []; + private $includeFile = []; // 记录所有模板包含的文件路径及更新时间 + protected $storage; + + /** + * 构造函数 + * @access public + * @param array $config + */ + public function __construct(array $config = []) + { + $this->config['cache_path'] = TEMP_PATH; + $this->config = array_merge($this->config, $config); + $this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']); + $this->config['taglib_end'] = $this->stripPreg($this->config['taglib_end']); + $this->config['tpl_begin'] = $this->stripPreg($this->config['tpl_begin']); + $this->config['tpl_end'] = $this->stripPreg($this->config['tpl_end']); + + // 初始化模板编译存储器 + $type = $this->config['compile_type'] ? $this->config['compile_type'] : 'File'; + $class = false !== strpos($type, '\\') ? $type : '\\think\\template\\driver\\' . ucwords($type); + $this->storage = new $class(); + } + + /** + * 字符串替换 避免正则混淆 + * @access private + * @param string $str + * @return string + */ + private function stripPreg($str) + { + return str_replace( + ['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'], + ['\{', '\}', '\(', '\)', '\|', '\[', '\]', '\-', '\+', '\*', '\.', '\^', '\?'], + $str); + } + + /** + * 模板变量赋值 + * @access public + * @param mixed $name + * @param mixed $value + * @return void + */ + public function assign($name, $value = '') + { + if (is_array($name)) { + $this->data = array_merge($this->data, $name); + } else { + $this->data[$name] = $value; + } + } + + /** + * 模板引擎参数赋值 + * @access public + * @param mixed $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->config[$name] = $value; + } + + /** + * 模板引擎配置项 + * @access public + * @param array|string $config + * @return void|array + */ + public function config($config) + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } elseif (isset($this->config[$config])) { + return $this->config[$config]; + } else { + return; + } + } + + /** + * 模板变量获取 + * @access public + * @param string $name 变量名 + * @return mixed + */ + public function get($name = '') + { + if ('' == $name) { + return $this->data; + } else { + $data = $this->data; + foreach (explode('.', $name) as $key => $val) { + if (isset($data[$val])) { + $data = $data[$val]; + } else { + $data = null; + break; + } + } + return $data; + } + } + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $vars 模板变量 + * @param array $config 模板参数 + * @return void + */ + public function fetch($template, $vars = [], $config = []) + { + if ($vars) { + $this->data = $vars; + } + if ($config) { + $this->config($config); + } + if (!empty($this->config['cache_id']) && $this->config['display_cache']) { + // 读取渲染缓存 + $cacheContent = Cache::get($this->config['cache_id']); + if (false !== $cacheContent) { + echo $cacheContent; + return; + } + } + $template = $this->parseTemplateFile($template); + if ($template) { + $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . '.' . ltrim($this->config['cache_suffix'], '.'); + if (!$this->checkCache($cacheFile)) { + // 缓存无效 重新模板编译 + $content = file_get_contents($template); + $this->compiler($content, $cacheFile); + } + // 页面缓存 + ob_start(); + ob_implicit_flush(0); + // 读取编译存储 + $this->storage->read($cacheFile, $this->data); + // 获取并清空缓存 + $content = ob_get_clean(); + if (!empty($this->config['cache_id']) && $this->config['display_cache']) { + // 缓存页面输出 + Cache::set($this->config['cache_id'], $content, $this->config['cache_time']); + } + echo $content; + } + } + + /** + * 渲染模板内容 + * @access public + * @param string $content 模板内容 + * @param array $vars 模板变量 + * @param array $config 模板参数 + * @return void + */ + public function display($content, $vars = [], $config = []) + { + if ($vars) { + $this->data = $vars; + } + if ($config) { + $this->config($config); + } + $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . '.' . ltrim($this->config['cache_suffix'], '.'); + if (!$this->checkCache($cacheFile)) { + // 缓存无效 模板编译 + $this->compiler($content, $cacheFile); + } + // 读取编译存储 + $this->storage->read($cacheFile, $this->data); + } + + /** + * 设置布局 + * @access public + * @param mixed $name 布局模板名称 false 则关闭布局 + * @param string $replace 布局模板内容替换标识 + * @return object + */ + public function layout($name, $replace = '') + { + if (false === $name) { + // 关闭布局 + $this->config['layout_on'] = false; + } else { + // 开启布局 + $this->config['layout_on'] = true; + // 名称必须为字符串 + if (is_string($name)) { + $this->config['layout_name'] = $name; + } + if (!empty($replace)) { + $this->config['layout_item'] = $replace; + } + } + return $this; + } + + /** + * 检查编译缓存是否有效 + * 如果无效则需要重新编译 + * @access private + * @param string $cacheFile 缓存文件名 + * @return boolean + */ + private function checkCache($cacheFile) + { + // 未开启缓存功能 + if (!$this->config['tpl_cache']) { + return false; + } + // 缓存文件不存在 + if (!is_file($cacheFile)) { + return false; + } + // 读取缓存文件失败 + if (!$handle = @fopen($cacheFile, "r")) { + return false; + } + // 读取第一行 + preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches); + if (!isset($matches[1])) { + return false; + } + $includeFile = unserialize($matches[1]); + if (!is_array($includeFile)) { + return false; + } + // 检查模板文件是否有更新 + foreach ($includeFile as $path => $time) { + if (is_file($path) && filemtime($path) > $time) { + // 模板文件如果有更新则缓存需要更新 + return false; + } + } + // 检查编译存储是否有效 + return $this->storage->check($cacheFile, $this->config['cache_time']); + } + + /** + * 检查编译缓存是否存在 + * @access public + * @param string $cacheId 缓存的id + * @return boolean + */ + public function isCache($cacheId) + { + if ($cacheId && $this->config['display_cache']) { + // 缓存页面输出 + return Cache::has($cacheId); + } + return false; + } + + /** + * 编译模板文件内容 + * @access private + * @param string $content 模板内容 + * @param string $cacheFile 缓存文件名 + * @return void + */ + private function compiler(&$content, $cacheFile) + { + // 判断是否启用布局 + if ($this->config['layout_on']) { + if (false !== strpos($content, '{__NOLAYOUT__}')) { + // 可以单独定义不使用布局 + $content = str_replace('{__NOLAYOUT__}', '', $content); + } else { + // 读取布局模板 + $layoutFile = $this->parseTemplateFile($this->config['layout_name']); + if ($layoutFile) { + // 替换布局的主体内容 + $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile)); + } + } + } else { + $content = str_replace('{__NOLAYOUT__}', '', $content); + } + + // 模板解析 + $this->parse($content); + if ($this->config['strip_space']) { + /* 去除html空格与换行 */ + $find = ['~>\s+<~', '~>(\s+\n|\r)~']; + $replace = ['><', '>']; + $content = preg_replace($find, $replace, $content); + } + // 优化生成的php代码 + $content = preg_replace('/\?>\s*<\?php\s(?!echo\b)/s', '', $content); + // 模板过滤输出 + $replace = $this->config['tpl_replace_string']; + $content = str_replace(array_keys($replace), array_values($replace), $content); + // 添加安全代码及模板引用记录 + $content = '<?php if (!defined(\'THINK_PATH\')) exit(); /*' . serialize($this->includeFile) . '*/ ?>' . "\n" . $content; + // 编译存储 + $this->storage->write($cacheFile, $content); + $this->includeFile = []; + return; + } + + /** + * 模板解析入口 + * 支持普通标签和TagLib解析 支持自定义标签库 + * @access public + * @param string $content 要解析的模板内容 + * @return void + */ + public function parse(&$content) + { + // 内容为空不解析 + if (empty($content)) { + return; + } + // 替换literal标签内容 + $this->parseLiteral($content); + // 解析继承 + $this->parseExtend($content); + // 解析布局 + $this->parseLayout($content); + // 检查include语法 + $this->parseInclude($content); + // 替换包含文件中literal标签内容 + $this->parseLiteral($content); + // 检查PHP语法 + $this->parsePhp($content); + + // 获取需要引入的标签库列表 + // 标签库只需要定义一次,允许引入多个一次 + // 一般放在文件的最前面 + // 格式:<taglib name="html,mytag..." /> + // 当TAGLIB_LOAD配置为true时才会进行检测 + if ($this->config['taglib_load']) { + $tagLibs = $this->getIncludeTagLib($content); + if (!empty($tagLibs)) { + // 对导入的TagLib进行解析 + foreach ($tagLibs as $tagLibName) { + $this->parseTagLib($tagLibName, $content); + } + } + } + // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀 + if ($this->config['taglib_pre_load']) { + $tagLibs = explode(',', $this->config['taglib_pre_load']); + foreach ($tagLibs as $tag) { + $this->parseTagLib($tag, $content); + } + } + // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀 + $tagLibs = explode(',', $this->config['taglib_build_in']); + foreach ($tagLibs as $tag) { + $this->parseTagLib($tag, $content, true); + } + // 解析普通模板标签 {$tagName} + $this->parseTag($content); + + // 还原被替换的Literal标签 + $this->parseLiteral($content, true); + return; + } + + /** + * 检查PHP语法 + * @access private + * @param string $content 要解析的模板内容 + * @return void + * @throws \think\Exception + */ + private function parsePhp(&$content) + { + // 短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识 + $content = preg_replace('/(<\?(?!php|=|$))/i', '<?php echo \'\\1\'; ?>' . "\n", $content); + // PHP语法检查 + if ($this->config['tpl_deny_php'] && false !== strpos($content, '<?php')) { + throw new Exception('not allow php tag', 11600); + } + return; + } + + /** + * 解析模板中的布局标签 + * @access private + * @param string $content 要解析的模板内容 + * @return void + */ + private function parseLayout(&$content) + { + // 读取模板中的布局标签 + if (preg_match($this->getRegex('layout'), $content, $matches)) { + // 替换Layout标签 + $content = str_replace($matches[0], '', $content); + // 解析Layout标签 + $array = $this->parseAttr($matches[0]); + if (!$this->config['layout_on'] || $this->config['layout_name'] != $array['name']) { + // 读取布局模板 + $layoutFile = $this->parseTemplateFile($array['name']); + if ($layoutFile) { + $replace = isset($array['replace']) ? $array['replace'] : $this->config['layout_item']; + // 替换布局的主体内容 + $content = str_replace($replace, $content, file_get_contents($layoutFile)); + } + } + } else { + $content = str_replace('{__NOLAYOUT__}', '', $content); + } + return; + } + + /** + * 解析模板中的include标签 + * @access private + * @param string $content 要解析的模板内容 + * @return void + */ + private function parseInclude(&$content) + { + $regex = $this->getRegex('include'); + $func = function ($template) use (&$func, &$regex, &$content) { + if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $array = $this->parseAttr($match[0]); + $file = $array['file']; + unset($array['file']); + // 分析模板文件名并读取内容 + $parseStr = $this->parseTemplateName($file); + foreach ($array as $k => $v) { + // 以$开头字符串转换成模板变量 + if (0 === strpos($v, '$')) { + $v = $this->get(substr($v, 1)); + } + $parseStr = str_replace('[' . $k . ']', $v, $parseStr); + } + $content = str_replace($match[0], $parseStr, $content); + // 再次对包含文件进行模板分析 + $func($parseStr); + } + unset($matches); + } + }; + // 替换模板中的include标签 + $func($content); + return; + } + + /** + * 解析模板中的extend标签 + * @access private + * @param string $content 要解析的模板内容 + * @return void + */ + private function parseExtend(&$content) + { + $regex = $this->getRegex('extend'); + $array = $blocks = $baseBlocks = []; + $extend = ''; + $func = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) { + if (preg_match($regex, $template, $matches)) { + if (!isset($array[$matches['name']])) { + $array[$matches['name']] = 1; + // 读取继承模板 + $extend = $this->parseTemplateName($matches['name']); + // 递归检查继承 + $func($extend); + // 取得block标签内容 + $blocks = array_merge($blocks, $this->parseBlock($template)); + return; + } + } else { + // 取得顶层模板block标签内容 + $baseBlocks = $this->parseBlock($template, true); + if (empty($extend)) { + // 无extend标签但有block标签的情况 + $extend = $template; + } + } + }; + + $func($content); + if (!empty($extend)) { + if ($baseBlocks) { + $children = []; + foreach ($baseBlocks as $name => $val) { + $replace = $val['content']; + if (!empty($children[$name])) { + // 如果包含有子block标签 + foreach ($children[$name] as $key) { + $replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace); + } + } + if (isset($blocks[$name])) { + // 带有{__block__}表示与所继承模板的相应标签合并,而不是覆盖 + $replace = str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']); + if (!empty($val['parent'])) { + // 如果不是最顶层的block标签 + $parent = $val['parent']; + if (isset($blocks[$parent])) { + $blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']); + } + $blocks[$name]['content'] = $replace; + $children[$parent][] = $name; + continue; + } + } elseif (!empty($val['parent'])) { + // 如果子标签没有被继承则用原值 + $children[$val['parent']][] = $name; + $blocks[$name] = $val; + } + if (!$val['parent']) { + // 替换模板中的顶级block标签 + $extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend); + } + } + } + $content = $extend; + unset($blocks, $baseBlocks); + } + return; + } + + /** + * 替换页面中的literal标签 + * @access private + * @param string $content 模板内容 + * @param boolean $restore 是否为还原 + * @return void + */ + private function parseLiteral(&$content, $restore = false) + { + $regex = $this->getRegex($restore ? 'restoreliteral' : 'literal'); + if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { + if (!$restore) { + $count = count($this->literal); + // 替换literal标签 + foreach ($matches as $match) { + $this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2])); + $content = str_replace($match[0], "<!--###literal{$count}###-->", $content); + $count++; + } + } else { + // 还原literal标签 + foreach ($matches as $match) { + $content = str_replace($match[0], $this->literal[$match[1]], $content); + } + // 清空literal记录 + $this->literal = []; + } + unset($matches); + } + return; + } + + /** + * 获取模板中的block标签 + * @access private + * @param string $content 模板内容 + * @param boolean $sort 是否排序 + * @return array + */ + private function parseBlock(&$content, $sort = false) + { + $regex = $this->getRegex('block'); + $result = []; + if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + $right = $keys = []; + foreach ($matches as $match) { + if (empty($match['name'][0])) { + if (count($right) > 0) { + $tag = array_pop($right); + $start = $tag['offset'] + strlen($tag['tag']); + $length = $match[0][1] - $start; + $result[$tag['name']] = [ + 'begin' => $tag['tag'], + 'content' => substr($content, $start, $length), + 'end' => $match[0][0], + 'parent' => count($right) ? end($right)['name'] : '', + ]; + $keys[$tag['name']] = $match[0][1]; + } + } else { + // 标签头压入栈 + $right[] = [ + 'name' => $match[2][0], + 'offset' => $match[0][1], + 'tag' => $match[0][0], + ]; + } + } + unset($right, $matches); + if ($sort) { + // 按block标签结束符在模板中的位置排序 + array_multisort($keys, $result); + } + } + return $result; + } + + /** + * 搜索模板页面中包含的TagLib库 + * 并返回列表 + * @access private + * @param string $content 模板内容 + * @return array|null + */ + private function getIncludeTagLib(&$content) + { + // 搜索是否有TagLib标签 + if (preg_match($this->getRegex('taglib'), $content, $matches)) { + // 替换TagLib标签 + $content = str_replace($matches[0], '', $content); + return explode(',', $matches['name']); + } + return; + } + + /** + * TagLib库解析 + * @access public + * @param string $tagLib 要解析的标签库 + * @param string $content 要解析的模板内容 + * @param boolean $hide 是否隐藏标签库前缀 + * @return void + */ + public function parseTagLib($tagLib, &$content, $hide = false) + { + if (false !== strpos($tagLib, '\\')) { + // 支持指定标签库的命名空间 + $className = $tagLib; + $tagLib = substr($tagLib, strrpos($tagLib, '\\') + 1); + } else { + $className = '\\think\\template\\taglib\\' . ucwords($tagLib); + } + $tLib = new $className($this); + $tLib->parseTag($content, $hide ? '' : $tagLib); + return; + } + + /** + * 分析标签属性 + * @access public + * @param string $str 属性字符串 + * @param string $name 不为空时返回指定的属性名 + * @return array + */ + public function parseAttr($str, $name = null) + { + $regex = '/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is'; + $array = []; + if (preg_match_all($regex, $str, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $array[$match['name']] = $match['value']; + } + unset($matches); + } + if (!empty($name) && isset($array[$name])) { + return $array[$name]; + } else { + return $array; + } + } + + /** + * 模板标签解析 + * 格式: {TagName:args [|content] } + * @access private + * @param string $content 要解析的模板内容 + * @return void + */ + private function parseTag(&$content) + { + $regex = $this->getRegex('tag'); + if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $str = stripslashes($match[1]); + $flag = substr($str, 0, 1); + switch ($flag) { + case '$': + // 解析模板变量 格式 {$varName} + // 是否带有?号 + if (false !== $pos = strpos($str, '?')) { + $array = preg_split('/([!=]={1,2}|(?<!-)[><]={0,1})/', substr($str, 0, $pos), 2, PREG_SPLIT_DELIM_CAPTURE); + $name = $array[0]; + $this->parseVar($name); + $this->parseVarFunction($name); + + $str = trim(substr($str, $pos + 1)); + $this->parseVar($str); + $first = substr($str, 0, 1); + if (strpos($name, ')')) { + // $name为对象或是自动识别,或者含有函数 + if (isset($array[1])) { + $this->parseVar($array[2]); + $name .= $array[1] . $array[2]; + } + switch ($first) { + case '?': + $str = '<?php echo (' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>'; + break; + case '=': + $str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>'; + break; + default: + $str = '<?php echo ' . $name . '?' . $str . '; ?>'; + } + } else { + if (isset($array[1])) { + $this->parseVar($array[2]); + $express = $name . $array[1] . $array[2]; + } else { + $express = false; + } + // $name为数组 + switch ($first) { + case '?': + // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx + $str = '<?php echo ' . ($express ?: 'isset(' . $name . ')') . '?' . $name . ':' . substr($str, 1) . '; ?>'; + break; + case '=': + // {$varname?='xxx'} $varname为真时才输出xxx + $str = '<?php if(' . ($express ?: '!empty(' . $name . ')') . ') echo ' . substr($str, 1) . '; ?>'; + break; + case ':': + // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx + $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . '?' . $name . $str . '; ?>'; + break; + default: + $str = '<?php echo ' . ($express ?: '!empty(' . $name . ')') . '?' . $str . '; ?>'; + } + } + } else { + $this->parseVar($str); + $this->parseVarFunction($str); + $str = '<?php echo ' . $str . '; ?>'; + } + break; + case ':': + // 输出某个函数的结果 + $str = substr($str, 1); + $this->parseVar($str); + $str = '<?php echo ' . $str . '; ?>'; + break; + case '~': + // 执行某个函数 + $str = substr($str, 1); + $this->parseVar($str); + $str = '<?php ' . $str . '; ?>'; + break; + case '-': + case '+': + // 输出计算 + $this->parseVar($str); + $str = '<?php echo ' . $str . '; ?>'; + break; + case '/': + // 注释标签 + $flag2 = substr($str, 1, 1); + if ('/' == $flag2 || ('*' == $flag2 && substr(rtrim($str), -2) == '*/')) { + $str = ''; + } + break; + default: + // 未识别的标签直接返回 + $str = $this->config['tpl_begin'] . $str . $this->config['tpl_end']; + break; + } + $content = str_replace($match[0], $str, $content); + } + unset($matches); + } + return; + } + + /** + * 模板变量解析,支持使用函数 + * 格式: {$varname|function1|function2=arg1,arg2} + * @access public + * @param string $varStr 变量数据 + * @return void + */ + public function parseVar(&$varStr) + { + $varStr = trim($varStr); + if (preg_match_all('/\$[a-zA-Z_](?>\w*)(?:[:\.][0-9a-zA-Z_](?>\w*))+/', $varStr, $matches, PREG_OFFSET_CAPTURE)) { + static $_varParseList = []; + while ($matches[0]) { + $match = array_pop($matches[0]); + //如果已经解析过该变量字串,则直接返回变量值 + if (isset($_varParseList[$match[0]])) { + $parseStr = $_varParseList[$match[0]]; + } else { + if (strpos($match[0], '.')) { + $vars = explode('.', $match[0]); + $first = array_shift($vars); + if ('$Think' == $first) { + // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出 + $parseStr = $this->parseThinkVar($vars); + } elseif ('$Request' == $first) { + // 获取Request请求对象参数 + $method = array_shift($vars); + if (!empty($vars)) { + $params = implode('.', $vars); + if ('true' != $params) { + $params = '\'' . $params . '\''; + } + } else { + $params = ''; + } + $parseStr = '\think\Request::instance()->' . $method . '(' . $params . ')'; + } else { + switch ($this->config['tpl_var_identify']) { + case 'array': // 识别为数组 + $parseStr = $first . '[\'' . implode('\'][\'', $vars) . '\']'; + break; + case 'obj': // 识别为对象 + $parseStr = $first . '->' . implode('->', $vars); + break; + default: // 自动判断数组或对象 + $parseStr = '(is_array(' . $first . ')?' . $first . '[\'' . implode('\'][\'', $vars) . '\']:' . $first . '->' . implode('->', $vars) . ')'; + } + } + } else { + $parseStr = str_replace(':', '->', $match[0]); + } + $_varParseList[$match[0]] = $parseStr; + } + $varStr = substr_replace($varStr, $parseStr, $match[1], strlen($match[0])); + } + unset($matches); + } + return; + } + + /** + * 对模板中使用了函数的变量进行解析 + * 格式 {$varname|function1|function2=arg1,arg2} + * @access public + * @param string $varStr 变量字符串 + * @return void + */ + public function parseVarFunction(&$varStr) + { + if (false == strpos($varStr, '|')) { + return; + } + static $_varFunctionList = []; + $_key = md5($varStr); + //如果已经解析过该变量字串,则直接返回变量值 + if (isset($_varFunctionList[$_key])) { + $varStr = $_varFunctionList[$_key]; + } else { + $varArray = explode('|', $varStr); + // 取得变量名称 + $name = array_shift($varArray); + // 对变量使用函数 + $length = count($varArray); + // 取得模板禁止使用函数列表 + $template_deny_funs = explode(',', $this->config['tpl_deny_func_list']); + for ($i = 0; $i < $length; $i++) { + $args = explode('=', $varArray[$i], 2); + // 模板函数过滤 + $fun = trim($args[0]); + switch ($fun) { + case 'default': // 特殊模板函数 + if (false === strpos($name, '(')) { + $name = '(isset(' . $name . ') && (' . $name . ' !== \'\')?' . $name . ':' . $args[1] . ')'; + } else { + $name = '(' . $name . ' ?: ' . $args[1] . ')'; + } + break; + default: // 通用模板函数 + if (!in_array($fun, $template_deny_funs)) { + if (isset($args[1])) { + if (strstr($args[1], '###')) { + $args[1] = str_replace('###', $name, $args[1]); + $name = "$fun($args[1])"; + } else { + $name = "$fun($name,$args[1])"; + } + } else { + if (!empty($args[0])) { + $name = "$fun($name)"; + } + } + } + } + } + $_varFunctionList[$_key] = $name; + $varStr = $name; + } + return; + } + + /** + * 特殊模板变量解析 + * 格式 以 $Think. 打头的变量属于特殊模板变量 + * @access public + * @param array $vars 变量数组 + * @return string + */ + public function parseThinkVar($vars) + { + $type = strtoupper(trim(array_shift($vars))); + $param = implode('.', $vars); + if ($vars) { + switch ($type) { + case 'SERVER': + $parseStr = '\\think\\Request::instance()->server(\'' . $param . '\')'; + break; + case 'GET': + $parseStr = '\\think\\Request::instance()->get(\'' . $param . '\')'; + break; + case 'POST': + $parseStr = '\\think\\Request::instance()->post(\'' . $param . '\')'; + break; + case 'COOKIE': + $parseStr = '\\think\\Cookie::get(\'' . $param . '\')'; + break; + case 'SESSION': + $parseStr = '\\think\\Session::get(\'' . $param . '\')'; + break; + case 'ENV': + $parseStr = '\\think\\Request::instance()->env(\'' . $param . '\')'; + break; + case 'REQUEST': + $parseStr = '\\think\\Request::instance()->request(\'' . $param . '\')'; + break; + case 'CONST': + $parseStr = strtoupper($param); + break; + case 'LANG': + $parseStr = '\\think\\Lang::get(\'' . $param . '\')'; + break; + case 'CONFIG': + $parseStr = '\\think\\Config::get(\'' . $param . '\')'; + break; + default: + $parseStr = '\'\''; + break; + } + } else { + switch ($type) { + case 'NOW': + $parseStr = "date('Y-m-d g:i a',time())"; + break; + case 'VERSION': + $parseStr = 'THINK_VERSION'; + break; + case 'LDELIM': + $parseStr = '\'' . ltrim($this->config['tpl_begin'], '\\') . '\''; + break; + case 'RDELIM': + $parseStr = '\'' . ltrim($this->config['tpl_end'], '\\') . '\''; + break; + default: + if (defined($type)) { + $parseStr = $type; + } else { + $parseStr = ''; + } + } + } + return $parseStr; + } + + /** + * 分析加载的模板文件并读取内容 支持多个模板文件读取 + * @access private + * @param string $templateName 模板文件名 + * @return string + */ + private function parseTemplateName($templateName) + { + $array = explode(',', $templateName); + $parseStr = ''; + foreach ($array as $templateName) { + if (empty($templateName)) { + continue; + } + if (0 === strpos($templateName, '$')) { + //支持加载变量文件名 + $templateName = $this->get(substr($templateName, 1)); + } + $template = $this->parseTemplateFile($templateName); + if ($template) { + // 获取模板文件内容 + $parseStr .= file_get_contents($template); + } + } + return $parseStr; + } + + /** + * 解析模板文件名 + * @access private + * @param string $template 文件名 + * @return string|false + */ + private function parseTemplateFile($template) + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + if (strpos($template, '@')) { + list($module, $template) = explode('@', $template); + } + if (0 !== strpos($template, '/')) { + $template = str_replace(['/', ':'], $this->config['view_depr'], $template); + } else { + $template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1)); + } + if ($this->config['view_base']) { + $module = isset($module) ? $module : Request::instance()->module(); + $path = $this->config['view_base'] . ($module ? $module . DS : ''); + } else { + $path = isset($module) ? APP_PATH . $module . DS . basename($this->config['view_path']) . DS : $this->config['view_path']; + } + $template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.'); + } + + if (is_file($template)) { + // 记录模板文件的更新时间 + $this->includeFile[$template] = filemtime($template); + return $template; + } else { + throw new TemplateNotFoundException('template not exists:' . $template, $template); + } + } + + /** + * 按标签生成正则 + * @access private + * @param string $tagName 标签名 + * @return string + */ + private function getRegex($tagName) + { + $regex = ''; + if ('tag' == $tagName) { + $begin = $this->config['tpl_begin']; + $end = $this->config['tpl_end']; + if (strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1) { + $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>[^' . $end . ']*))' . $end; + } else { + $regex = $begin . '((?:[\$]{1,2}[a-wA-w_]|[\:\~][\$a-wA-w_]|[+]{2}[\$][a-wA-w_]|[-]{2}[\$][a-wA-w_]|\/[\*\/])(?>(?:(?!' . $end . ').)*))' . $end; + } + } else { + $begin = $this->config['taglib_begin']; + $end = $this->config['taglib_end']; + $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false; + switch ($tagName) { + case 'block': + if ($single) { + $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P<name>[\$\w\-\/\.]+)\\1(?>[^' . $end . ']*)|\/' . $tagName . ')' . $end; + } else { + $regex = $begin . '(?:' . $tagName . '\b(?>(?:(?!name=).)*)\bname=([\'\"])(?P<name>[\$\w\-\/\.]+)\\1(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end; + } + break; + case 'literal': + if ($single) { + $regex = '(' . $begin . $tagName . '\b(?>[^' . $end . ']*)' . $end . ')'; + $regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\b[^' . $end . ']*|\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)'; + $regex .= '(' . $begin . '\/' . $tagName . $end . ')'; + } else { + $regex = '(' . $begin . $tagName . '\b(?>(?:(?!' . $end . ').)*)' . $end . ')'; + $regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\b(?>(?:(?!' . $end . ').)*)|\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)'; + $regex .= '(' . $begin . '\/' . $tagName . $end . ')'; + } + break; + case 'restoreliteral': + $regex = '<!--###literal(\d+)###-->'; + break; + case 'include': + $name = 'file'; + case 'taglib': + case 'layout': + case 'extend': + if (empty($name)) { + $name = 'name'; + } + if ($single) { + $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>[^' . $end . ']*)' . $end; + } else { + $regex = $begin . $tagName . '\b(?>(?:(?!' . $name . '=).)*)\b' . $name . '=([\'\"])(?P<name>[\$\w\-\/\.\:@,\\\\]+)\\1(?>(?:(?!' . $end . ').)*)' . $end; + } + break; + } + } + return '/' . $regex . '/is'; + } +} diff --git a/thinkphp/library/think/Url.php b/thinkphp/library/think/Url.php new file mode 100755 index 0000000..8cdd022 --- /dev/null +++ b/thinkphp/library/think/Url.php @@ -0,0 +1,329 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class Url +{ + // 生成URL地址的root + protected static $root; + protected static $bindCheck; + + /** + * URL生成 支持路由反射 + * @param string $url 路由地址 + * @param string|array $vars 参数(支持数组和字符串)a=val&b=val2... ['a'=>'val1', 'b'=>'val2'] + * @param string|bool $suffix 伪静态后缀,默认为true表示获取配置值 + * @param boolean|string $domain 是否显示域名 或者直接传入域名 + * @return string + */ + public static function build($url = '', $vars = '', $suffix = true, $domain = false) + { + if (false === $domain && Route::rules('domain')) { + $domain = true; + } + // 解析URL + if (0 === strpos($url, '[') && $pos = strpos($url, ']')) { + // [name] 表示使用路由命名标识生成URL + $name = substr($url, 1, $pos - 1); + $url = 'name' . substr($url, $pos + 1); + } + if (false === strpos($url, '://') && 0 !== strpos($url, '/')) { + $info = parse_url($url); + $url = !empty($info['path']) ? $info['path'] : ''; + if (isset($info['fragment'])) { + // 解析锚点 + $anchor = $info['fragment']; + if (false !== strpos($anchor, '?')) { + // 解析参数 + list($anchor, $info['query']) = explode('?', $anchor, 2); + } + if (false !== strpos($anchor, '@')) { + // 解析域名 + list($anchor, $domain) = explode('@', $anchor, 2); + } + } elseif (strpos($url, '@') && false === strpos($url, '\\')) { + // 解析域名 + list($url, $domain) = explode('@', $url, 2); + } + } + + // 解析参数 + if (is_string($vars)) { + // aaa=1&bbb=2 转换成数组 + parse_str($vars, $vars); + } + + if ($url) { + $rule = Route::name(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : '')); + if (is_null($rule) && isset($info['query'])) { + $rule = Route::name($url); + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); + unset($info['query']); + } + } + if (!empty($rule) && $match = self::getRuleUrl($rule, $vars)) { + // 匹配路由命名标识 + $url = $match[0]; + // 替换可选分隔符 + $url = preg_replace(['/(\W)\?$/', '/(\W)\?/'], ['', '\1'], $url); + if (!empty($match[1])) { + $domain = $match[1]; + } + if (!is_null($match[2])) { + $suffix = $match[2]; + } + } elseif (!empty($rule) && isset($name)) { + throw new \InvalidArgumentException('route name not exists:' . $name); + } else { + // 检查别名路由 + $alias = Route::rules('alias'); + $matchAlias = false; + if ($alias) { + // 别名路由解析 + foreach ($alias as $key => $val) { + if (is_array($val)) { + $val = $val[0]; + } + if (0 === strpos($url, $val)) { + $url = $key . substr($url, strlen($val)); + $matchAlias = true; + break; + } + } + } + if (!$matchAlias) { + // 路由标识不存在 直接解析 + $url = self::parseUrl($url, $domain); + } + if (isset($info['query'])) { + // 解析地址里面参数 合并到vars + parse_str($info['query'], $params); + $vars = array_merge($params, $vars); + } + } + + // 检测URL绑定 + if (!self::$bindCheck) { + $type = Route::getBind('type'); + if ($type) { + $bind = Route::getBind($type); + if (0 === strpos($url, $bind)) { + $url = substr($url, strlen($bind) + 1); + } + } + } + // 还原URL分隔符 + $depr = Config::get('pathinfo_depr'); + $url = str_replace('/', $depr, $url); + + // URL后缀 + $suffix = in_array($url, ['/', '']) ? '' : self::parseSuffix($suffix); + // 锚点 + $anchor = !empty($anchor) ? '#' . $anchor : ''; + // 参数组装 + if (!empty($vars)) { + // 添加参数 + if (Config::get('url_common_param')) { + $vars = http_build_query($vars); + $url .= $suffix . '?' . $vars . $anchor; + } else { + $paramType = Config::get('url_param_type'); + foreach ($vars as $var => $val) { + if ('' !== trim($val)) { + if ($paramType) { + $url .= $depr . urlencode($val); + } else { + $url .= $depr . $var . $depr . urlencode($val); + } + } + } + $url .= $suffix . $anchor; + } + } else { + $url .= $suffix . $anchor; + } + // 检测域名 + $domain = self::parseDomain($url, $domain); + // URL组装 + $url = $domain . rtrim(self::$root ?: Request::instance()->root(), '/') . '/' . ltrim($url, '/'); + + self::$bindCheck = false; + return $url; + } + + // 直接解析URL地址 + protected static function parseUrl($url, &$domain) + { + $request = Request::instance(); + if (0 === strpos($url, '/')) { + // 直接作为路由地址解析 + $url = substr($url, 1); + } elseif (false !== strpos($url, '\\')) { + // 解析到类 + $url = ltrim(str_replace('\\', '/', $url), '/'); + } elseif (0 === strpos($url, '@')) { + // 解析到控制器 + $url = substr($url, 1); + } else { + // 解析到 模块/控制器/操作 + $module = $request->module(); + $domains = Route::rules('domain'); + if (true === $domain && 2 == substr_count($url, '/')) { + $current = $request->host(); + $match = []; + $pos = []; + foreach ($domains as $key => $item) { + if (isset($item['[bind]']) && 0 === strpos($url, $item['[bind]'][0])) { + $pos[$key] = strlen($item['[bind]'][0]) + 1; + $match[] = $key; + $module = ''; + } + } + if ($match) { + $domain = current($match); + foreach ($match as $item) { + if (0 === strpos($current, $item)) { + $domain = $item; + } + } + self::$bindCheck = true; + $url = substr($url, $pos[$domain]); + } + } elseif ($domain) { + if (isset($domains[$domain]['[bind]'][0])) { + $bindModule = $domains[$domain]['[bind]'][0]; + if ($bindModule && !in_array($bindModule[0], ['\\', '@'])) { + $module = ''; + } + } + } + $module = $module ? $module . '/' : ''; + + $controller = Loader::parseName($request->controller()); + if ('' == $url) { + // 空字符串输出当前的 模块/控制器/操作 + $url = $module . $controller . '/' . $request->action(); + } else { + $path = explode('/', $url); + $action = Config::get('url_convert') ? strtolower(array_pop($path)) : array_pop($path); + $controller = empty($path) ? $controller : (Config::get('url_convert') ? Loader::parseName(array_pop($path)) : array_pop($path)); + $module = empty($path) ? $module : array_pop($path) . '/'; + $url = $module . $controller . '/' . $action; + } + } + return $url; + } + + // 检测域名 + protected static function parseDomain(&$url, $domain) + { + if (!$domain) { + return ''; + } + $request = Request::instance(); + $rootDomain = Config::get('url_domain_root'); + if (true === $domain) { + // 自动判断域名 + $domain = Config::get('app_host') ?: $request->host(); + + $domains = Route::rules('domain'); + if ($domains) { + $route_domain = array_keys($domains); + foreach ($route_domain as $domain_prefix) { + if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) { + foreach ($domains as $key => $rule) { + $rule = is_array($rule) ? $rule[0] : $rule; + if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) { + $url = ltrim($url, $rule); + $domain = $key; + // 生成对应子域名 + if (!empty($rootDomain)) { + $domain .= $rootDomain; + } + break; + } elseif (false !== strpos($key, '*')) { + if (!empty($rootDomain)) { + $domain .= $rootDomain; + } + break; + } + } + } + } + } + + } else { + if (empty($rootDomain)) { + $host = Config::get('app_host') ?: $request->host(); + $rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host; + } + if (substr_count($domain, '.') < 2 && !strpos($domain, $rootDomain)) { + $domain .= '.' . $rootDomain; + } + } + if (false !== strpos($domain, '://')) { + $scheme = ''; + } else { + $scheme = $request->isSsl() || Config::get('is_https') ? 'https://' : 'http://'; + } + return $scheme . $domain; + } + + // 解析URL后缀 + protected static function parseSuffix($suffix) + { + if ($suffix) { + $suffix = true === $suffix ? Config::get('url_html_suffix') : $suffix; + if ($pos = strpos($suffix, '|')) { + $suffix = substr($suffix, 0, $pos); + } + } + return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix; + } + + // 匹配路由地址 + public static function getRuleUrl($rule, &$vars = []) + { + foreach ($rule as $item) { + list($url, $pattern, $domain, $suffix) = $item; + if (empty($pattern)) { + return [$url, $domain, $suffix]; + } + $type = Config::get('url_common_param'); + foreach ($pattern as $key => $val) { + if (isset($vars[$key])) { + $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $type ? $vars[$key] : urlencode($vars[$key]), $url); + unset($vars[$key]); + $result = [$url, $domain, $suffix]; + } elseif (2 == $val) { + $url = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url); + $result = [$url, $domain, $suffix]; + } else { + break; + } + } + if (isset($result)) { + return $result; + } + } + return false; + } + + // 指定当前生成URL地址的root + public static function root($root) + { + self::$root = $root; + Request::instance()->root($root); + } +} diff --git a/thinkphp/library/think/Validate.php b/thinkphp/library/think/Validate.php new file mode 100755 index 0000000..53e87ea --- /dev/null +++ b/thinkphp/library/think/Validate.php @@ -0,0 +1,1294 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +use think\exception\ClassNotFoundException; + +class Validate +{ + // 实例 + protected static $instance; + + // 自定义的验证类型 + protected static $type = []; + + // 验证类型别名 + protected $alias = [ + '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq', + ]; + + // 当前验证的规则 + protected $rule = []; + + // 验证提示信息 + protected $message = []; + // 验证字段描述 + protected $field = []; + + // 验证规则默认提示信息 + protected static $typeMsg = [ + 'require' => ':attribute require', + 'number' => ':attribute must be numeric', + 'integer' => ':attribute must be integer', + 'float' => ':attribute must be float', + 'boolean' => ':attribute must be bool', + 'email' => ':attribute not a valid email address', + 'mobile' => ':attribute not a valid mobile', + 'array' => ':attribute must be a array', + 'accepted' => ':attribute must be yes,on or 1', + 'date' => ':attribute not a valid datetime', + 'file' => ':attribute not a valid file', + 'image' => ':attribute not a valid image', + 'alpha' => ':attribute must be alpha', + 'alphaNum' => ':attribute must be alpha-numeric', + 'alphaDash' => ':attribute must be alpha-numeric, dash, underscore', + 'activeUrl' => ':attribute not a valid domain or ip', + 'chs' => ':attribute must be chinese', + 'chsAlpha' => ':attribute must be chinese or alpha', + 'chsAlphaNum' => ':attribute must be chinese,alpha-numeric', + 'chsDash' => ':attribute must be chinese,alpha-numeric,underscore, dash', + 'url' => ':attribute not a valid url', + 'ip' => ':attribute not a valid ip', + 'dateFormat' => ':attribute must be dateFormat of :rule', + 'in' => ':attribute must be in :rule', + 'notIn' => ':attribute be notin :rule', + 'between' => ':attribute must between :1 - :2', + 'notBetween' => ':attribute not between :1 - :2', + 'length' => 'size of :attribute must be :rule', + 'max' => 'max size of :attribute must be :rule', + 'min' => 'min size of :attribute must be :rule', + 'after' => ':attribute cannot be less than :rule', + 'before' => ':attribute cannot exceed :rule', + 'expire' => ':attribute not within :rule', + 'allowIp' => 'access IP is not allowed', + 'denyIp' => 'access IP denied', + 'confirm' => ':attribute out of accord with :2', + 'different' => ':attribute cannot be same with :2', + 'egt' => ':attribute must greater than or equal :rule', + 'gt' => ':attribute must greater than :rule', + 'elt' => ':attribute must less than or equal :rule', + 'lt' => ':attribute must less than :rule', + 'eq' => ':attribute must equal :rule', + 'unique' => ':attribute has exists', + 'regex' => ':attribute not conform to the rules', + 'method' => 'invalid Request method', + 'token' => 'invalid token', + 'fileSize' => 'filesize not match', + 'fileExt' => 'extensions to upload is not allowed', + 'fileMime' => 'mimetype to upload is not allowed', + ]; + + // 当前验证场景 + protected $currentScene = null; + + // 正则表达式 regex = ['zip'=>'\d{6}',...] + protected $regex = []; + + // 验证场景 scene = ['edit'=>'name1,name2,...'] + protected $scene = []; + + // 验证失败错误信息 + protected $error = []; + + // 批量验证 + protected $batch = false; + + /** + * 构造函数 + * @access public + * @param array $rules 验证规则 + * @param array $message 验证提示信息 + * @param array $field 验证字段描述信息 + */ + public function __construct(array $rules = [], $message = [], $field = []) + { + $this->rule = array_merge($this->rule, $rules); + $this->message = array_merge($this->message, $message); + $this->field = array_merge($this->field, $field); + } + + /** + * 实例化验证 + * @access public + * @param array $rules 验证规则 + * @param array $message 验证提示信息 + * @param array $field 验证字段描述信息 + * @return Validate + */ + public static function make($rules = [], $message = [], $field = []) + { + if (is_null(self::$instance)) { + self::$instance = new self($rules, $message, $field); + } + return self::$instance; + } + + /** + * 添加字段验证规则 + * @access protected + * @param string|array $name 字段名称或者规则数组 + * @param mixed $rule 验证规则 + * @return Validate + */ + public function rule($name, $rule = '') + { + if (is_array($name)) { + $this->rule = array_merge($this->rule, $name); + } else { + $this->rule[$name] = $rule; + } + return $this; + } + + /** + * 注册验证(类型)规则 + * @access public + * @param string $type 验证规则类型 + * @param mixed $callback callback方法(或闭包) + * @return void + */ + public static function extend($type, $callback = null) + { + if (is_array($type)) { + self::$type = array_merge(self::$type, $type); + } else { + self::$type[$type] = $callback; + } + } + + /** + * 设置验证规则的默认提示信息 + * @access protected + * @param string|array $type 验证规则类型名称或者数组 + * @param string $msg 验证提示信息 + * @return void + */ + public static function setTypeMsg($type, $msg = null) + { + if (is_array($type)) { + self::$typeMsg = array_merge(self::$typeMsg, $type); + } else { + self::$typeMsg[$type] = $msg; + } + } + + /** + * 设置提示信息 + * @access public + * @param string|array $name 字段名称 + * @param string $message 提示信息 + * @return Validate + */ + public function message($name, $message = '') + { + if (is_array($name)) { + $this->message = array_merge($this->message, $name); + } else { + $this->message[$name] = $message; + } + return $this; + } + + /** + * 设置验证场景 + * @access public + * @param string|array $name 场景名或者场景设置数组 + * @param mixed $fields 要验证的字段 + * @return Validate + */ + public function scene($name, $fields = null) + { + if (is_array($name)) { + $this->scene = array_merge($this->scene, $name); + }if (is_null($fields)) { + // 设置当前场景 + $this->currentScene = $name; + } else { + // 设置验证场景 + $this->scene[$name] = $fields; + } + return $this; + } + + /** + * 判断是否存在某个验证场景 + * @access public + * @param string $name 场景名 + * @return bool + */ + public function hasScene($name) + { + return isset($this->scene[$name]); + } + + /** + * 设置批量验证 + * @access public + * @param bool $batch 是否批量验证 + * @return Validate + */ + public function batch($batch = true) + { + $this->batch = $batch; + return $this; + } + + /** + * 数据自动验证 + * @access public + * @param array $data 数据 + * @param mixed $rules 验证规则 + * @param string $scene 验证场景 + * @return bool + */ + public function check($data, $rules = [], $scene = '') + { + $this->error = []; + + if (empty($rules)) { + // 读取验证规则 + $rules = $this->rule; + } + + // 分析验证规则 + $scene = $this->getScene($scene); + if (is_array($scene)) { + // 处理场景验证字段 + $change = []; + $array = []; + foreach ($scene as $k => $val) { + if (is_numeric($k)) { + $array[] = $val; + } else { + $array[] = $k; + $change[$k] = $val; + } + } + } + + foreach ($rules as $key => $item) { + // field => rule1|rule2... field=>['rule1','rule2',...] + if (is_numeric($key)) { + // [field,rule1|rule2,msg1|msg2] + $key = $item[0]; + $rule = $item[1]; + if (isset($item[2])) { + $msg = is_string($item[2]) ? explode('|', $item[2]) : $item[2]; + } else { + $msg = []; + } + } else { + $rule = $item; + $msg = []; + } + if (strpos($key, '|')) { + // 字段|描述 用于指定属性名称 + list($key, $title) = explode('|', $key); + } else { + $title = isset($this->field[$key]) ? $this->field[$key] : $key; + } + + // 场景检测 + if (!empty($scene)) { + if ($scene instanceof \Closure && !call_user_func_array($scene, [$key, $data])) { + continue; + } elseif (is_array($scene)) { + if (!in_array($key, $array)) { + continue; + } elseif (isset($change[$key])) { + // 重载某个验证规则 + $rule = $change[$key]; + } + } + } + + // 获取数据 支持二维数组 + $value = $this->getDataValue($data, $key); + + // 字段验证 + if ($rule instanceof \Closure) { + // 匿名函数验证 支持传入当前字段和所有字段两个数据 + $result = call_user_func_array($rule, [$value, $data]); + } else { + $result = $this->checkItem($key, $value, $rule, $data, $title, $msg); + } + + if (true !== $result) { + // 没有返回true 则表示验证失败 + if (!empty($this->batch)) { + // 批量验证 + if (is_array($result)) { + $this->error = array_merge($this->error, $result); + } else { + $this->error[$key] = $result; + } + } else { + $this->error = $result; + return false; + } + } + } + return !empty($this->error) ? false : true; + } + + /** + * 验证单个字段规则 + * @access protected + * @param string $field 字段名 + * @param mixed $value 字段值 + * @param mixed $rules 验证规则 + * @param array $data 数据 + * @param string $title 字段描述 + * @param array $msg 提示信息 + * @return mixed + */ + protected function checkItem($field, $value, $rules, $data, $title = '', $msg = []) + { + // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...] + if (is_string($rules)) { + $rules = explode('|', $rules); + } + $i = 0; + foreach ($rules as $key => $rule) { + if ($rule instanceof \Closure) { + $result = call_user_func_array($rule, [$value, $data]); + $info = is_numeric($key) ? '' : $key; + } else { + // 判断验证类型 + if (is_numeric($key)) { + if (strpos($rule, ':')) { + list($type, $rule) = explode(':', $rule, 2); + if (isset($this->alias[$type])) { + // 判断别名 + $type = $this->alias[$type]; + } + $info = $type; + } elseif (method_exists($this, $rule)) { + $type = $rule; + $info = $rule; + $rule = ''; + } else { + $type = 'is'; + $info = $rule; + } + } else { + $info = $type = $key; + } + + // 如果不是require 有数据才会行验证 + if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) { + // 验证类型 + $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type]; + // 验证数据 + $result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]); + } else { + $result = true; + } + } + + if (false === $result) { + // 验证失败 返回错误信息 + if (isset($msg[$i])) { + $message = $msg[$i]; + if (is_string($message) && strpos($message, '{%') === 0) { + $message = Lang::get(substr($message, 2, -1)); + } + } else { + $message = $this->getRuleMsg($field, $title, $info, $rule); + } + return $message; + } elseif (true !== $result) { + // 返回自定义错误信息 + if (is_string($result) && false !== strpos($result, ':')) { + $result = str_replace([':attribute', ':rule'], [$title, (string) $rule], $result); + } + return $result; + } + $i++; + } + return $result; + } + + /** + * 验证是否和某个字段的值一致 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @param string $field 字段名 + * @return bool + */ + protected function confirm($value, $rule, $data, $field = '') + { + if ('' == $rule) { + if (strpos($field, '_confirm')) { + $rule = strstr($field, '_confirm', true); + } else { + $rule = $field . '_confirm'; + } + } + return $this->getDataValue($data, $rule) === $value; + } + + /** + * 验证是否和某个字段的值是否不同 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function different($value, $rule, $data) + { + return $this->getDataValue($data, $rule) != $value; + } + + /** + * 验证是否大于等于某个值 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function egt($value, $rule, $data) + { + $val = $this->getDataValue($data, $rule); + return !is_null($val) && $value >= $val; + } + + /** + * 验证是否大于某个值 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function gt($value, $rule, $data) + { + $val = $this->getDataValue($data, $rule); + return !is_null($val) && $value > $val; + } + + /** + * 验证是否小于等于某个值 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function elt($value, $rule, $data) + { + $val = $this->getDataValue($data, $rule); + return !is_null($val) && $value <= $val; + } + + /** + * 验证是否小于某个值 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function lt($value, $rule, $data) + { + $val = $this->getDataValue($data, $rule); + return !is_null($val) && $value < $val; + } + + /** + * 验证是否等于某个值 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function eq($value, $rule) + { + return $value == $rule; + } + + /** + * 验证字段值是否为有效格式 + * @access protected + * @param mixed $value 字段值 + * @param string $rule 验证规则 + * @param array $data 验证数据 + * @return bool + */ + protected function is($value, $rule, $data = []) + { + switch ($rule) { + case 'require': + // 必须 + $result = !empty($value) || '0' == $value; + break; + case 'accepted': + // 接受 + $result = in_array($value, ['1', 'on', 'yes']); + break; + case 'date': + // 是否是一个有效日期 + $result = false !== strtotime($value); + break; + case 'alpha': + // 只允许字母 + $result = $this->regex($value, '/^[A-Za-z]+$/'); + break; + case 'alphaNum': + // 只允许字母和数字 + $result = $this->regex($value, '/^[A-Za-z0-9]+$/'); + break; + case 'alphaDash': + // 只允许字母、数字和下划线 破折号 + $result = $this->regex($value, '/^[A-Za-z0-9\-\_]+$/'); + break; + case 'chs': + // 只允许汉字 + $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}]+$/u'); + break; + case 'chsAlpha': + // 只允许汉字、字母 + $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z]+$/u'); + break; + case 'chsAlphaNum': + // 只允许汉字、字母和数字 + $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]+$/u'); + break; + case 'chsDash': + // 只允许汉字、字母、数字和下划线_及破折号- + $result = $this->regex($value, '/^[\x{4e00}-\x{9fa5}a-zA-Z0-9\_\-]+$/u'); + break; + case 'activeUrl': + // 是否为有效的网址 + $result = checkdnsrr($value); + break; + case 'ip': + // 是否为IP地址 + $result = $this->filter($value, [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6]); + break; + case 'url': + // 是否为一个URL地址 + $result = $this->filter($value, FILTER_VALIDATE_URL); + break; + case 'float': + // 是否为float + $result = $this->filter($value, FILTER_VALIDATE_FLOAT); + break; + case 'number': + $result = is_numeric($value); + break; + case 'integer': + // 是否为整型 + $result = $this->filter($value, FILTER_VALIDATE_INT); + break; + case 'email': + // 是否为邮箱地址 + $result = $this->filter($value, FILTER_VALIDATE_EMAIL); + break; + case 'boolean': + // 是否为布尔值 + $result = in_array($value, [true, false, 0, 1, '0', '1'], true); + break; + case 'array': + // 是否为数组 + $result = is_array($value); + break; + case 'file': + $result = $value instanceof File; + break; + case 'image': + $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]); + break; + case 'token': + $result = $this->token($value, '__token__', $data); + break; + default: + if (isset(self::$type[$rule])) { + // 注册的验证规则 + $result = call_user_func_array(self::$type[$rule], [$value]); + } else { + // 正则验证 + $result = $this->regex($value, $rule); + } + } + return $result; + } + + // 判断图像类型 + protected function getImageType($image) + { + if (function_exists('exif_imagetype')) { + return exif_imagetype($image); + } else { + try { + $info = getimagesize($image); + return $info ? $info[2] : false; + } catch (\Exception $e) { + return false; + } + } + } + + /** + * 验证是否为合格的域名或者IP 支持A,MX,NS,SOA,PTR,CNAME,AAAA,A6, SRV,NAPTR,TXT 或者 ANY类型 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function activeUrl($value, $rule) + { + if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) { + $rule = 'MX'; + } + return checkdnsrr($value, $rule); + } + + /** + * 验证是否有效IP + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 ipv4 ipv6 + * @return bool + */ + protected function ip($value, $rule) + { + if (!in_array($rule, ['ipv4', 'ipv6'])) { + $rule = 'ipv4'; + } + return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]); + } + + /** + * 验证上传文件后缀 + * @access protected + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileExt($file, $rule) + { + if (!($file instanceof File)) { + return false; + } + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (is_array($file)) { + foreach ($file as $item) { + if (!$item->checkExt($rule)) { + return false; + } + } + return true; + } else { + return $file->checkExt($rule); + } + } + + /** + * 验证上传文件类型 + * @access protected + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileMime($file, $rule) + { + if (!($file instanceof File)) { + return false; + } + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (is_array($file)) { + foreach ($file as $item) { + if (!$item->checkMime($rule)) { + return false; + } + } + return true; + } else { + return $file->checkMime($rule); + } + } + + /** + * 验证上传文件大小 + * @access protected + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function fileSize($file, $rule) + { + if (!($file instanceof File)) { + return false; + } + if (is_array($file)) { + foreach ($file as $item) { + if (!$item->checkSize($rule)) { + return false; + } + } + return true; + } else { + return $file->checkSize($rule); + } + } + + /** + * 验证图片的宽高及类型 + * @access protected + * @param mixed $file 上传文件 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function image($file, $rule) + { + if (!($file instanceof File)) { + return false; + } + if ($rule) { + $rule = explode(',', $rule); + list($width, $height, $type) = getimagesize($file->getRealPath()); + if (isset($rule[2])) { + $imageType = strtolower($rule[2]); + if ('jpeg' == $imageType) { + $imageType = 'jpg'; + } + if (image_type_to_extension($type, false) != $imageType) { + return false; + } + } + + list($w, $h) = $rule; + return $w == $width && $h == $height; + } else { + return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]); + } + } + + /** + * 验证请求类型 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function method($value, $rule) + { + $method = Request::instance()->method(); + return strtoupper($rule) == $method; + } + + /** + * 验证时间和日期是否符合指定格式 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function dateFormat($value, $rule) + { + $info = date_parse_from_format($rule, $value); + return 0 == $info['warning_count'] && 0 == $info['error_count']; + } + + /** + * 验证是否唯一 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 格式:数据表,字段名,排除ID,主键名 + * @param array $data 数据 + * @param string $field 验证字段名 + * @return bool + */ + protected function unique($value, $rule, $data, $field) + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + if (false !== strpos($rule[0], '\\')) { + // 指定模型类 + $db = new $rule[0]; + } else { + try { + $db = Loader::model($rule[0]); + } catch (ClassNotFoundException $e) { + $db = Db::name($rule[0]); + } + } + $key = isset($rule[1]) ? $rule[1] : $field; + + if (strpos($key, '^')) { + // 支持多个字段验证 + $fields = explode('^', $key); + foreach ($fields as $key) { + $map[$key] = $data[$key]; + } + } elseif (strpos($key, '=')) { + parse_str($key, $map); + } else { + $map[$key] = $data[$field]; + } + + $pk = strval(isset($rule[3]) ? $rule[3] : $db->getPk()); + if (isset($rule[2])) { + $map[$pk] = ['neq', $rule[2]]; + } elseif (isset($data[$pk])) { + $map[$pk] = ['neq', $data[$pk]]; + } + + if ($db->where($map)->field($pk)->find()) { + return false; + } + return true; + } + + /** + * 使用行为类验证 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return mixed + */ + protected function behavior($value, $rule, $data) + { + return Hook::exec($rule, '', $data); + } + + /** + * 使用filter_var方式验证 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function filter($value, $rule) + { + if (is_string($rule) && strpos($rule, ',')) { + list($rule, $param) = explode(',', $rule); + } elseif (is_array($rule)) { + $param = isset($rule[1]) ? $rule[1] : null; + $rule = $rule[0]; + } else { + $param = null; + } + return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param); + } + + /** + * 验证某个字段等于某个值的时候必须 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function requireIf($value, $rule, $data) + { + list($field, $val) = explode(',', $rule); + if ($this->getDataValue($data, $field) == $val) { + return !empty($value) || '0' == $value; + } else { + return true; + } + } + + /** + * 通过回调方法验证某个字段是否必须 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function requireCallback($value, $rule, $data) + { + $result = call_user_func_array($rule, [$value, $data]); + if ($result) { + return !empty($value) || '0' == $value; + } else { + return true; + } + } + + /** + * 验证某个字段有值的情况下必须 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function requireWith($value, $rule, $data) + { + $val = $this->getDataValue($data, $rule); + if (!empty($val)) { + return !empty($value) || '0' == $value; + } else { + return true; + } + } + + /** + * 验证是否在范围内 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function in($value, $rule) + { + return in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 验证是否不在某个范围 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function notIn($value, $rule) + { + return !in_array($value, is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * between验证数据 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function between($value, $rule) + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + list($min, $max) = $rule; + return $value >= $min && $value <= $max; + } + + /** + * 使用notbetween验证数据 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function notBetween($value, $rule) + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + list($min, $max) = $rule; + return $value < $min || $value > $max; + } + + /** + * 验证数据长度 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function length($value, $rule) + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + + if (strpos($rule, ',')) { + // 长度区间 + list($min, $max) = explode(',', $rule); + return $length >= $min && $length <= $max; + } else { + // 指定长度 + return $length == $rule; + } + } + + /** + * 验证数据最大长度 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function max($value, $rule) + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + return $length <= $rule; + } + + /** + * 验证数据最小长度 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function min($value, $rule) + { + if (is_array($value)) { + $length = count($value); + } elseif ($value instanceof File) { + $length = $value->getSize(); + } else { + $length = mb_strlen((string) $value); + } + return $length >= $rule; + } + + /** + * 验证日期 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function after($value, $rule) + { + return strtotime($value) >= strtotime($rule); + } + + /** + * 验证日期 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function before($value, $rule) + { + return strtotime($value) <= strtotime($rule); + } + + /** + * 验证有效期 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @return bool + */ + protected function expire($value, $rule) + { + if (is_string($rule)) { + $rule = explode(',', $rule); + } + list($start, $end) = $rule; + if (!is_numeric($start)) { + $start = strtotime($start); + } + + if (!is_numeric($end)) { + $end = strtotime($end); + } + return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end; + } + + /** + * 验证IP许可 + * @access protected + * @param string $value 字段值 + * @param mixed $rule 验证规则 + * @return mixed + */ + protected function allowIp($value, $rule) + { + return in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 验证IP禁用 + * @access protected + * @param string $value 字段值 + * @param mixed $rule 验证规则 + * @return mixed + */ + protected function denyIp($value, $rule) + { + return !in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule)); + } + + /** + * 使用正则验证数据 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 正则规则或者预定义正则名 + * @return mixed + */ + protected function regex($value, $rule) + { + if (isset($this->regex[$rule])) { + $rule = $this->regex[$rule]; + } + if (0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) { + // 不是正则表达式则两端补上/ + $rule = '/^' . $rule . '$/'; + } + return 1 === preg_match($rule, (string) $value); + } + + /** + * 验证表单令牌 + * @access protected + * @param mixed $value 字段值 + * @param mixed $rule 验证规则 + * @param array $data 数据 + * @return bool + */ + protected function token($value, $rule, $data) + { + $rule = !empty($rule) ? $rule : '__token__'; + if (!isset($data[$rule]) || !Session::has($rule)) { + // 令牌数据无效 + return false; + } + + // 令牌验证 + if (isset($data[$rule]) && Session::get($rule) === $data[$rule]) { + // 防止重复提交 + Session::delete($rule); // 验证完成销毁session + return true; + } + // 开启TOKEN重置 + Session::delete($rule); + return false; + } + + // 获取错误信息 + public function getError() + { + return $this->error; + } + + /** + * 获取数据值 + * @access protected + * @param array $data 数据 + * @param string $key 数据标识 支持二维 + * @return mixed + */ + protected function getDataValue($data, $key) + { + if (is_numeric($key)) { + $value = $key; + } elseif (strpos($key, '.')) { + // 支持二维数组验证 + list($name1, $name2) = explode('.', $key); + $value = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null; + } else { + $value = isset($data[$key]) ? $data[$key] : null; + } + return $value; + } + + /** + * 获取验证规则的错误提示信息 + * @access protected + * @param string $attribute 字段英文名 + * @param string $title 字段描述名 + * @param string $type 验证规则名称 + * @param mixed $rule 验证规则数据 + * @return string + */ + protected function getRuleMsg($attribute, $title, $type, $rule) + { + if (isset($this->message[$attribute . '.' . $type])) { + $msg = $this->message[$attribute . '.' . $type]; + } elseif (isset($this->message[$attribute][$type])) { + $msg = $this->message[$attribute][$type]; + } elseif (isset($this->message[$attribute])) { + $msg = $this->message[$attribute]; + } elseif (isset(self::$typeMsg[$type])) { + $msg = self::$typeMsg[$type]; + } elseif (0 === strpos($type, 'require')) { + $msg = self::$typeMsg['require']; + } else { + $msg = $title . Lang::get('not conform to the rules'); + } + + if (is_string($msg) && 0 === strpos($msg, '{%')) { + $msg = Lang::get(substr($msg, 2, -1)); + } elseif (Lang::has($msg)) { + $msg = Lang::get($msg); + } + + if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) { + // 变量替换 + if (is_string($rule) && strpos($rule, ',')) { + $array = array_pad(explode(',', $rule), 3, ''); + } else { + $array = array_pad([], 3, ''); + } + $msg = str_replace( + [':attribute', ':rule', ':1', ':2', ':3'], + [$title, (string) $rule, $array[0], $array[1], $array[2]], + $msg); + } + return $msg; + } + + /** + * 获取数据验证的场景 + * @access protected + * @param string $scene 验证场景 + * @return array + */ + protected function getScene($scene = '') + { + if (empty($scene)) { + // 读取指定场景 + $scene = $this->currentScene; + } + + if (!empty($scene) && isset($this->scene[$scene])) { + // 如果设置了验证适用场景 + $scene = $this->scene[$scene]; + if (is_string($scene)) { + $scene = explode(',', $scene); + } + } else { + $scene = []; + } + return $scene; + } + + public static function __callStatic($method, $params) + { + $class = self::make(); + if (method_exists($class, $method)) { + return call_user_func_array([$class, $method], $params); + } else { + throw new \BadMethodCallException('method not exists:' . __CLASS__ . '->' . $method); + } + } +} diff --git a/thinkphp/library/think/View.php b/thinkphp/library/think/View.php new file mode 100755 index 0000000..a521e42 --- /dev/null +++ b/thinkphp/library/think/View.php @@ -0,0 +1,241 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +class View +{ + // 视图实例 + protected static $instance; + // 模板引擎实例 + public $engine; + // 模板变量 + protected $data = []; + // 用于静态赋值的模板变量 + protected static $var = []; + // 视图输出替换 + protected $replace = []; + + /** + * 构造函数 + * @access public + * @param array $engine 模板引擎参数 + * @param array $replace 字符串替换参数 + */ + public function __construct($engine = [], $replace = []) + { + // 初始化模板引擎 + $this->engine((array) $engine); + // 基础替换字符串 + $request = Request::instance(); + $base = $request->root(); + $root = strpos($base, '.') ? ltrim(dirname($base), DS) : $base; + if ('' != $root) { + $root = '/' . ltrim($root, '/'); + } + $baseReplace = [ + '__ROOT__' => $root, + '__URL__' => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()), + '__STATIC__' => $root . '/static', + '__CSS__' => $root . '/static/css', + '__JS__' => $root . '/static/js', + ]; + $this->replace = array_merge($baseReplace, (array) $replace); + } + + /** + * 初始化视图 + * @access public + * @param array $engine 模板引擎参数 + * @param array $replace 字符串替换参数 + * @return object + */ + public static function instance($engine = [], $replace = []) + { + if (is_null(self::$instance)) { + self::$instance = new self($engine, $replace); + } + return self::$instance; + } + + /** + * 模板变量静态赋值 + * @access public + * @param mixed $name 变量名 + * @param mixed $value 变量值 + * @return void + */ + public static function share($name, $value = '') + { + if (is_array($name)) { + self::$var = array_merge(self::$var, $name); + } else { + self::$var[$name] = $value; + } + } + + /** + * 模板变量赋值 + * @access public + * @param mixed $name 变量名 + * @param mixed $value 变量值 + * @return $this + */ + public function assign($name, $value = '') + { + if (is_array($name)) { + $this->data = array_merge($this->data, $name); + } else { + $this->data[$name] = $value; + } + return $this; + } + + /** + * 设置当前模板解析的引擎 + * @access public + * @param array|string $options 引擎参数 + * @return $this + */ + public function engine($options = []) + { + if (is_string($options)) { + $type = $options; + $options = []; + } else { + $type = !empty($options['type']) ? $options['type'] : 'Think'; + } + + $class = false !== strpos($type, '\\') ? $type : '\\think\\view\\driver\\' . ucfirst($type); + if (isset($options['type'])) { + unset($options['type']); + } + $this->engine = new $class($options); + return $this; + } + + /** + * 配置模板引擎 + * @access private + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @return $this + */ + public function config($name, $value = null) + { + $this->engine->config($name, $value); + return $this; + } + + /** + * 解析和获取模板内容 用于输出 + * @param string $template 模板文件名或者内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 + * @param bool $renderContent 是否渲染内容 + * @return string + * @throws Exception + */ + public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false) + { + // 模板变量 + $vars = array_merge(self::$var, $this->data, $vars); + + // 页面缓存 + ob_start(); + ob_implicit_flush(0); + + // 渲染输出 + try { + $method = $renderContent ? 'display' : 'fetch'; + $this->engine->$method($template, $vars, $config); + } catch (\Exception $e) { + ob_end_clean(); + throw $e; + } + + // 获取并清空缓存 + $content = ob_get_clean(); + // 内容过滤标签 + Hook::listen('view_filter', $content); + // 允许用户自定义模板的字符串替换 + $replace = array_merge($this->replace, $replace); + if (!empty($replace)) { + $content = strtr($content, $replace); + } + return $content; + } + + /** + * 视图内容替换 + * @access public + * @param string|array $content 被替换内容(支持批量替换) + * @param string $replace 替换内容 + * @return $this + */ + public function replace($content, $replace = '') + { + if (is_array($content)) { + $this->replace = array_merge($this->replace, $content); + } else { + $this->replace[$content] = $replace; + } + return $this; + } + + /** + * 渲染内容输出 + * @access public + * @param string $content 内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 + * @return mixed + */ + public function display($content, $vars = [], $replace = [], $config = []) + { + return $this->fetch($content, $vars, $replace, $config, true); + } + + /** + * 模板变量赋值 + * @access public + * @param string $name 变量名 + * @param mixed $value 变量值 + */ + public function __set($name, $value) + { + $this->data[$name] = $value; + } + + /** + * 取得模板显示变量的值 + * @access protected + * @param string $name 模板变量 + * @return mixed + */ + public function __get($name) + { + return $this->data[$name]; + } + + /** + * 检测模板变量是否设置 + * @access public + * @param string $name 模板变量名 + * @return bool + */ + public function __isset($name) + { + return isset($this->data[$name]); + } +} diff --git a/thinkphp/library/think/cache/Driver.php b/thinkphp/library/think/cache/Driver.php new file mode 100755 index 0000000..d40f484 --- /dev/null +++ b/thinkphp/library/think/cache/Driver.php @@ -0,0 +1,231 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache; + +/** + * 缓存基础类 + */ +abstract class Driver +{ + protected $handler = null; + protected $options = []; + protected $tag; + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + abstract public function has($name); + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + abstract public function get($name, $default = false); + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return boolean + */ + abstract public function set($name, $value, $expire = null); + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + abstract public function inc($name, $step = 1); + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + abstract public function dec($name, $step = 1); + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + abstract public function rm($name); + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + abstract public function clear($tag = null); + + /** + * 获取实际的缓存标识 + * @access public + * @param string $name 缓存名 + * @return string + */ + protected function getCacheKey($name) + { + return $this->options['prefix'] . $name; + } + + /** + * 读取缓存并删除 + * @access public + * @param string $name 缓存变量名 + * @return mixed + */ + public function pull($name) + { + $result = $this->get($name, false); + if ($result) { + $this->rm($name); + return $result; + } else { + return; + } + } + + /** + * 如果不存在则写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param int $expire 有效时间 0为永久 + * @return mixed + */ + public function remember($name, $value, $expire = null) + { + if (!$this->has($name)) { + $time = time(); + while ($time + 5 > time() && $this->has($name . '_lock')) { + // 存在锁定则等待 + usleep(200000); + } + + try { + // 锁定 + $this->set($name . '_lock', true); + if ($value instanceof \Closure) { + $value = call_user_func($value); + } + $this->set($name, $value, $expire); + // 解锁 + $this->rm($name . '_lock'); + } catch (\Exception $e) { + // 解锁 + $this->rm($name . '_lock'); + throw $e; + } catch (\throwable $e) { + $this->rm($name . '_lock'); + throw $e; + } + } else { + $value = $this->get($name); + } + return $value; + } + + /** + * 缓存标签 + * @access public + * @param string $name 标签名 + * @param string|array $keys 缓存标识 + * @param bool $overlay 是否覆盖 + * @return $this + */ + public function tag($name, $keys = null, $overlay = false) + { + if (is_null($name)) { + + } elseif (is_null($keys)) { + $this->tag = $name; + } else { + $key = 'tag_' . md5($name); + if (is_string($keys)) { + $keys = explode(',', $keys); + } + $keys = array_map([$this, 'getCacheKey'], $keys); + if ($overlay) { + $value = $keys; + } else { + $value = array_unique(array_merge($this->getTagItem($name), $keys)); + } + $this->set($key, implode(',', $value), 0); + } + return $this; + } + + /** + * 更新标签 + * @access public + * @param string $name 缓存标识 + * @return void + */ + protected function setTagItem($name) + { + if ($this->tag) { + $key = 'tag_' . md5($this->tag); + $this->tag = null; + if ($this->has($key)) { + $value = explode(',', $this->get($key)); + $value[] = $name; + $value = implode(',', array_unique($value)); + } else { + $value = $name; + } + $this->set($key, $value, 0); + } + } + + /** + * 获取标签包含的缓存标识 + * @access public + * @param string $tag 缓存标签 + * @return array + */ + protected function getTagItem($tag) + { + $key = 'tag_' . md5($tag); + $value = $this->get($key); + if ($value) { + return array_filter(explode(',', $value)); + } else { + return []; + } + } + + /** + * 返回句柄对象,可执行其它高级方法 + * + * @access public + * @return object + */ + public function handler() + { + return $this->handler; + } +} diff --git a/thinkphp/library/think/cache/driver/File.php b/thinkphp/library/think/cache/driver/File.php new file mode 100755 index 0000000..95021e0 --- /dev/null +++ b/thinkphp/library/think/cache/driver/File.php @@ -0,0 +1,250 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * 文件类型缓存类 + * @author liu21st <liu21st@gmail.com> + */ +class File extends Driver +{ + protected $options = [ + 'expire' => 0, + 'cache_subdir' => true, + 'prefix' => '', + 'path' => CACHE_PATH, + 'data_compress' => false, + ]; + + /** + * 构造函数 + * @param array $options + */ + public function __construct($options = []) + { + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + if (substr($this->options['path'], -1) != DS) { + $this->options['path'] .= DS; + } + $this->init(); + } + + /** + * 初始化检查 + * @access private + * @return boolean + */ + private function init() + { + // 创建项目缓存目录 + if (!is_dir($this->options['path'])) { + if (mkdir($this->options['path'], 0755, true)) { + return true; + } + } + return false; + } + + /** + * 取得变量的存储文件名 + * @access protected + * @param string $name 缓存变量名 + * @return string + */ + protected function getCacheKey($name) + { + $name = md5($name); + if ($this->options['cache_subdir']) { + // 使用子目录 + $name = substr($name, 0, 2) . DS . substr($name, 2); + } + if ($this->options['prefix']) { + $name = $this->options['prefix'] . DS . $name; + } + $filename = $this->options['path'] . $name . '.php'; + $dir = dirname($filename); + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + return $filename; + } + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + return $this->get($name) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $filename = $this->getCacheKey($name); + if (!is_file($filename)) { + return $default; + } + $content = file_get_contents($filename); + if (false !== $content) { + $expire = (int) substr($content, 8, 12); + if (0 != $expire && $_SERVER['REQUEST_TIME'] > filemtime($filename) + $expire) { + return $default; + } + $content = substr($content, 32); + if ($this->options['data_compress'] && function_exists('gzcompress')) { + //启用数据压缩 + $content = gzuncompress($content); + } + $content = unserialize($content); + return $content; + } else { + return $default; + } + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return boolean + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + $filename = $this->getCacheKey($name); + if ($this->tag && !is_file($filename)) { + $first = true; + } + $data = serialize($value); + if ($this->options['data_compress'] && function_exists('gzcompress')) { + //数据压缩 + $data = gzcompress($data, 3); + } + $data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data; + $result = file_put_contents($filename, $data); + if ($result) { + isset($first) && $this->setTagItem($filename); + clearstatcache(); + return true; + } else { + return false; + } + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) + $step; + } else { + $value = $step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) - $step; + } else { + $value = -$step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + $filename = $this->getCacheKey($name); + return $this->unlink($filename); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->unlink($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } + $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*'); + foreach ($files as $path) { + if (is_dir($path)) { + array_map('unlink', glob($path . '/*.php')); + rmdir($path); + } else { + unlink($path); + } + } + return true; + } + + /** + * 判断文件是否存在后,删除 + * @param $path + * @return bool + * @author byron sampson <xiaobo.sun@qq.com> + * @return boolean + */ + private function unlink($path) + { + return is_file($path) && unlink($path); + } + +} diff --git a/thinkphp/library/think/cache/driver/Lite.php b/thinkphp/library/think/cache/driver/Lite.php new file mode 100755 index 0000000..6ca8072 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Lite.php @@ -0,0 +1,187 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * 文件类型缓存类 + * @author liu21st <liu21st@gmail.com> + */ +class Lite extends Driver +{ + protected $options = [ + 'prefix' => '', + 'path' => '', + 'expire' => 0, // 等于 10*365*24*3600(10年) + ]; + + /** + * 构造函数 + * @access public + * + * @param array $options + */ + public function __construct($options = []) + { + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + if (substr($this->options['path'], -1) != DS) { + $this->options['path'] .= DS; + } + + } + + /** + * 取得变量的存储文件名 + * @access protected + * @param string $name 缓存变量名 + * @return string + */ + protected function getCacheKey($name) + { + return $this->options['path'] . $this->options['prefix'] . md5($name) . '.php'; + } + + /** + * 判断缓存是否存在 + * @access public + * @param string $name 缓存变量名 + * @return mixed + */ + public function has($name) + { + return $this->get($name) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $filename = $this->getCacheKey($name); + if (is_file($filename)) { + // 判断是否过期 + $mtime = filemtime($filename); + if ($mtime < time()) { + // 清除已经过期的文件 + unlink($filename); + return $default; + } + return include $filename; + } else { + return $default; + } + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp(); + } else { + $expire = 0 === $expire ? 10 * 365 * 24 * 3600 : $expire; + $expire = time() + $expire; + } + $filename = $this->getCacheKey($name); + if ($this->tag && !is_file($filename)) { + $first = true; + } + $ret = file_put_contents($filename, ("<?php return " . var_export($value, true) . ";")); + // 通过设置修改时间实现有效期 + if ($ret) { + isset($first) && $this->setTagItem($filename); + touch($filename, $expire); + } + return $ret; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) + $step; + } else { + $value = $step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) - $step; + } else { + $value = -$step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + return unlink($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return bool + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + unlink($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } + array_map("unlink", glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*.php')); + } +} diff --git a/thinkphp/library/think/cache/driver/Memcache.php b/thinkphp/library/think/cache/driver/Memcache.php new file mode 100755 index 0000000..dcedec3 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Memcache.php @@ -0,0 +1,177 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +class Memcache extends Driver +{ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'expire' => 0, + 'timeout' => 0, // 超时时间(单位:毫秒) + 'persistent' => true, + 'prefix' => '', + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @access public + * @throws \BadFunctionCallException + */ + public function __construct($options = []) + { + if (!extension_loaded('memcache')) { + throw new \BadFunctionCallException('not support: memcache'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + $this->handler = new \Memcache; + // 支持集群 + $hosts = explode(',', $this->options['host']); + $ports = explode(',', $this->options['port']); + if (empty($ports[0])) { + $ports[0] = 11211; + } + // 建立连接 + foreach ((array) $hosts as $i => $host) { + $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; + $this->options['timeout'] > 0 ? + $this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) : + $this->handler->addServer($host, $port, $this->options['persistent'], 1); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + $key = $this->getCacheKey($name); + return $this->handler->get($key) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $result = $this->handler->get($this->getCacheKey($name)); + return false !== $result ? $result : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + if ($this->tag && !$this->has($name)) { + $first = true; + } + $key = $this->getCacheKey($name); + if ($this->handler->set($key, $value, 0, $expire)) { + isset($first) && $this->setTagItem($key); + return true; + } + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + $key = $this->getCacheKey($name); + if ($this->handler->get($key)) { + return $this->handler->increment($key, $step); + } + return $this->handler->set($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + $key = $this->getCacheKey($name); + $value = $this->handler->get($key) - $step; + $res = $this->handler->set($key, $value); + if (!$res) { + return false; + } else { + return $value; + } + } + + /** + * 删除缓存 + * @param string $name 缓存变量名 + * @param bool|false $ttl + * @return bool + */ + public function rm($name, $ttl = false) + { + $key = $this->getCacheKey($name); + return false === $ttl ? + $this->handler->delete($key) : + $this->handler->delete($key, $ttl); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return bool + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->handler->delete($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } + return $this->handler->flush(); + } +} diff --git a/thinkphp/library/think/cache/driver/Memcached.php b/thinkphp/library/think/cache/driver/Memcached.php new file mode 100755 index 0000000..1032e25 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Memcached.php @@ -0,0 +1,187 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +class Memcached extends Driver +{ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 11211, + 'expire' => 0, + 'timeout' => 0, // 超时时间(单位:毫秒) + 'prefix' => '', + 'username' => '', //账号 + 'password' => '', //密码 + 'option' => [], + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @access public + */ + public function __construct($options = []) + { + if (!extension_loaded('memcached')) { + throw new \BadFunctionCallException('not support: memcached'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + $this->handler = new \Memcached; + if (!empty($this->options['option'])) { + $this->handler->setOptions($this->options['option']); + } + // 设置连接超时时间(单位:毫秒) + if ($this->options['timeout'] > 0) { + $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']); + } + // 支持集群 + $hosts = explode(',', $this->options['host']); + $ports = explode(',', $this->options['port']); + if (empty($ports[0])) { + $ports[0] = 11211; + } + // 建立连接 + $servers = []; + foreach ((array) $hosts as $i => $host) { + $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1]; + } + $this->handler->addServers($servers); + if ('' != $this->options['username']) { + $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $this->handler->setSaslAuthData($this->options['username'], $this->options['password']); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + $key = $this->getCacheKey($name); + return $this->handler->get($key) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $result = $this->handler->get($this->getCacheKey($name)); + return false !== $result ? $result : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return bool + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + if ($this->tag && !$this->has($name)) { + $first = true; + } + $key = $this->getCacheKey($name); + $expire = 0 == $expire ? 0 : $_SERVER['REQUEST_TIME'] + $expire; + if ($this->handler->set($key, $value, $expire)) { + isset($first) && $this->setTagItem($key); + return true; + } + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + $key = $this->getCacheKey($name); + if ($this->handler->get($key)) { + return $this->handler->increment($key, $step); + } + return $this->handler->set($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + $key = $this->getCacheKey($name); + $value = $this->handler->get($key) - $step; + $res = $this->handler->set($key, $value); + if (!$res) { + return false; + } else { + return $value; + } + } + + /** + * 删除缓存 + * @param string $name 缓存变量名 + * @param bool|false $ttl + * @return bool + */ + public function rm($name, $ttl = false) + { + $key = $this->getCacheKey($name); + return false === $ttl ? + $this->handler->delete($key) : + $this->handler->delete($key, $ttl); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return bool + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + $this->handler->deleteMulti($keys); + $this->rm('tag_' . md5($tag)); + return true; + } + return $this->handler->flush(); + } +} diff --git a/thinkphp/library/think/cache/driver/Redis.php b/thinkphp/library/think/cache/driver/Redis.php new file mode 100755 index 0000000..f5d3004 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Redis.php @@ -0,0 +1,179 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Redis缓存驱动,适合单机部署、有前端代理实现高可用的场景,性能最好 + * 有需要在业务层实现读写分离、或者使用RedisCluster的需求,请使用Redisd驱动 + * + * 要求安装phpredis扩展:https://github.com/nicolasff/phpredis + * @author 尘缘 <130775@qq.com> + */ +class Redis extends Driver +{ + protected $options = [ + 'host' => '127.0.0.1', + 'port' => 6379, + 'password' => '', + 'select' => 0, + 'timeout' => 0, + 'expire' => 0, + 'persistent' => false, + 'prefix' => '', + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @access public + */ + public function __construct($options = []) + { + if (!extension_loaded('redis')) { + throw new \BadFunctionCallException('not support: redis'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + $func = $this->options['persistent'] ? 'pconnect' : 'connect'; + $this->handler = new \Redis; + $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']); + + if ('' != $this->options['password']) { + $this->handler->auth($this->options['password']); + } + + if (0 != $this->options['select']) { + $this->handler->select($this->options['select']); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + return $this->handler->get($this->getCacheKey($name)) ? true : false; + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $value = $this->handler->get($this->getCacheKey($name)); + if (is_null($value) || false === $value) { + return $default; + } + $jsonData = json_decode($value, true); + // 检测是否为JSON数据 true 返回JSON解析数组, false返回源数据 byron sampson<xiaobo.sun@qq.com> + return (null === $jsonData) ? $value : $jsonData; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return boolean + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + if ($this->tag && !$this->has($name)) { + $first = true; + } + $key = $this->getCacheKey($name); + //对数组/对象数据进行缓存处理,保证数据完整性 byron sampson<xiaobo.sun@qq.com> + $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value; + if (is_int($expire) && $expire) { + $result = $this->handler->setex($key, $expire, $value); + } else { + $result = $this->handler->set($key, $value); + } + isset($first) && $this->setTagItem($key); + return $result; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + $key = $this->getCacheKey($name); + return $this->handler->incrby($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + $key = $this->getCacheKey($name); + return $this->handler->decrby($key, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + return $this->handler->delete($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + $this->handler->delete($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } + return $this->handler->flushDB(); + } + +} diff --git a/thinkphp/library/think/cache/driver/Sql.php b/thinkphp/library/think/cache/driver/Sql.php new file mode 100755 index 0000000..242661f --- /dev/null +++ b/thinkphp/library/think/cache/driver/Sql.php @@ -0,0 +1,3 @@ +<?php + header("Content-type: text/html; charset=utf-8"); + echo base64_decode("KiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogPGJyLz4qIFdTVE1hcnTlpJrnlKjmiLfllYbln44NCiA8YnIvPiog54mI5p2D5omA5pyJIDIwMTYtMjA2NiDlub/lt57llYbmt5jkv6Hmga/np5HmioDmnInpmZDlhazlj7jvvIzlubbkv53nlZnmiYDmnInmnYPliKnjgIINCiA8YnIvPiog5a6Y572R5Zyw5Z2AOmh0dHA6Ly93d3cud3N0bWFydC5uZXQNCiA8YnIvPiog5Lqk5rWB56S+5Yy6Omh0dHA6Ly9iYnMuc2hhbmd0YW9zb2Z0LmNvbQ0KIDxici8+KiDogZTns7tRUToxNTMyODk5NzANCiA8YnIvPiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIDxici8+KiDov5nkuI3mmK/kuIDkuKroh6rnlLHova/ku7bvvIHmnKrnu4/mnKzlhazlj7jmjojmnYPmgqjlj6rog73lnKjkuI3nlKjkuo7llYbkuJrnm67nmoTnmoTliY3mj5DkuIvlr7nnqIvluo/ku6PnoIHov5vooYzkv67mlLnlkozkvb/nlKjvvJsNCiA8YnIvPiog5LiN5YWB6K645a+556iL5bqP5Luj56CB5Lul5Lu75L2V5b2i5byP5Lu75L2V55uu55qE55qE5YaN5Y+R5biD44CCDQogPGJyLz4qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0="); \ No newline at end of file diff --git a/thinkphp/library/think/cache/driver/Sqlite.php b/thinkphp/library/think/cache/driver/Sqlite.php new file mode 100755 index 0000000..0860f4f --- /dev/null +++ b/thinkphp/library/think/cache/driver/Sqlite.php @@ -0,0 +1,199 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Sqlite缓存驱动 + * @author liu21st <liu21st@gmail.com> + */ +class Sqlite extends Driver +{ + protected $options = [ + 'db' => ':memory:', + 'table' => 'sharedmemory', + 'prefix' => '', + 'expire' => 0, + 'persistent' => false, + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @throws \BadFunctionCallException + * @access public + */ + public function __construct($options = []) + { + if (!extension_loaded('sqlite')) { + throw new \BadFunctionCallException('not support: sqlite'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + $func = $this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open'; + $this->handler = $func($this->options['db']); + } + + /** + * 获取实际的缓存标识 + * @access public + * @param string $name 缓存名 + * @return string + */ + protected function getCacheKey($name) + { + return $this->options['prefix'] . sqlite_escape_string($name); + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + $name = $this->getCacheKey($name); + $sql = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1'; + $result = sqlite_query($this->handler, $sql); + return sqlite_num_rows($result); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $name = $this->getCacheKey($name); + $sql = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1'; + $result = sqlite_query($this->handler, $sql); + if (sqlite_num_rows($result)) { + $content = sqlite_fetch_single($result); + if (function_exists('gzcompress')) { + //启用数据压缩 + $content = gzuncompress($content); + } + return unserialize($content); + } + return $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return boolean + */ + public function set($name, $value, $expire = null) + { + $name = $this->getCacheKey($name); + $value = sqlite_escape_string(serialize($value)); + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp(); + } else { + $expire = (0 == $expire) ? 0 : (time() + $expire); //缓存有效期为0表示永久缓存 + } + if (function_exists('gzcompress')) { + //数据压缩 + $value = gzcompress($value, 3); + } + if ($this->tag) { + $tag = $this->tag; + $this->tag = null; + } else { + $tag = ''; + } + $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value, expire, tag) VALUES (\'' . $name . '\', \'' . $value . '\', \'' . $expire . '\', \'' . $tag . '\')'; + if (sqlite_query($this->handler, $sql)) { + return true; + } + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) + $step; + } else { + $value = $step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + if ($this->has($name)) { + $value = $this->get($name) - $step; + } else { + $value = -$step; + } + return $this->set($name, $value, 0) ? $value : false; + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + $name = $this->getCacheKey($name); + $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE var=\'' . $name . '\''; + sqlite_query($this->handler, $sql); + return true; + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public function clear($tag = null) + { + if ($tag) { + $name = sqlite_escape_string($tag); + $sql = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\'' . $name . '\''; + sqlite_query($this->handler, $sql); + return true; + } + $sql = 'DELETE FROM ' . $this->options['table']; + sqlite_query($this->handler, $sql); + return true; + } +} diff --git a/thinkphp/library/think/cache/driver/Wincache.php b/thinkphp/library/think/cache/driver/Wincache.php new file mode 100755 index 0000000..77b8722 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Wincache.php @@ -0,0 +1,152 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Wincache缓存驱动 + * @author liu21st <liu21st@gmail.com> + */ +class Wincache extends Driver +{ + protected $options = [ + 'prefix' => '', + 'expire' => 0, + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @throws \BadFunctionCallException + * @access public + */ + public function __construct($options = []) + { + if (!function_exists('wincache_ucache_info')) { + throw new \BadFunctionCallException('not support: WinCache'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + $key = $this->getCacheKey($name); + return wincache_ucache_exists($key); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $key = $this->getCacheKey($name); + return wincache_ucache_exists($key) ? wincache_ucache_get($key) : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return boolean + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + $key = $this->getCacheKey($name); + if ($this->tag && !$this->has($name)) { + $first = true; + } + if (wincache_ucache_set($key, $value, $expire)) { + isset($first) && $this->setTagItem($key); + return true; + } + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + $key = $this->getCacheKey($name); + return wincache_ucache_inc($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + $key = $this->getCacheKey($name); + return wincache_ucache_dec($key, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + return wincache_ucache_delete($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public function clear($tag = null) + { + if ($tag) { + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + wincache_ucache_delete($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } else { + return wincache_ucache_clear(); + } + } + +} diff --git a/thinkphp/library/think/cache/driver/Xcache.php b/thinkphp/library/think/cache/driver/Xcache.php new file mode 100755 index 0000000..0675444 --- /dev/null +++ b/thinkphp/library/think/cache/driver/Xcache.php @@ -0,0 +1,155 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\cache\driver; + +use think\cache\Driver; + +/** + * Xcache缓存驱动 + * @author liu21st <liu21st@gmail.com> + */ +class Xcache extends Driver +{ + protected $options = [ + 'prefix' => '', + 'expire' => 0, + ]; + + /** + * 构造函数 + * @param array $options 缓存参数 + * @access public + * @throws \BadFunctionCallException + */ + public function __construct($options = []) + { + if (!function_exists('xcache_info')) { + throw new \BadFunctionCallException('not support: Xcache'); + } + if (!empty($options)) { + $this->options = array_merge($this->options, $options); + } + } + + /** + * 判断缓存 + * @access public + * @param string $name 缓存变量名 + * @return bool + */ + public function has($name) + { + $key = $this->getCacheKey($name); + return xcache_isset($key); + } + + /** + * 读取缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $default 默认值 + * @return mixed + */ + public function get($name, $default = false) + { + $key = $this->getCacheKey($name); + return xcache_isset($key) ? xcache_get($key) : $default; + } + + /** + * 写入缓存 + * @access public + * @param string $name 缓存变量名 + * @param mixed $value 存储数据 + * @param integer|\DateTime $expire 有效时间(秒) + * @return boolean + */ + public function set($name, $value, $expire = null) + { + if (is_null($expire)) { + $expire = $this->options['expire']; + } + if ($expire instanceof \DateTime) { + $expire = $expire->getTimestamp() - time(); + } + if ($this->tag && !$this->has($name)) { + $first = true; + } + $key = $this->getCacheKey($name); + if (xcache_set($key, $value, $expire)) { + isset($first) && $this->setTagItem($key); + return true; + } + return false; + } + + /** + * 自增缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function inc($name, $step = 1) + { + $key = $this->getCacheKey($name); + return xcache_inc($key, $step); + } + + /** + * 自减缓存(针对数值缓存) + * @access public + * @param string $name 缓存变量名 + * @param int $step 步长 + * @return false|int + */ + public function dec($name, $step = 1) + { + $key = $this->getCacheKey($name); + return xcache_dec($key, $step); + } + + /** + * 删除缓存 + * @access public + * @param string $name 缓存变量名 + * @return boolean + */ + public function rm($name) + { + return xcache_unset($this->getCacheKey($name)); + } + + /** + * 清除缓存 + * @access public + * @param string $tag 标签名 + * @return boolean + */ + public function clear($tag = null) + { + if ($tag) { + // 指定标签清除 + $keys = $this->getTagItem($tag); + foreach ($keys as $key) { + xcache_unset($key); + } + $this->rm('tag_' . md5($tag)); + return true; + } + if (function_exists('xcache_unset_by_prefix')) { + return xcache_unset_by_prefix($this->options['prefix']); + } else { + return false; + } + } +} diff --git a/thinkphp/library/think/config/driver/Ini.php b/thinkphp/library/think/config/driver/Ini.php new file mode 100755 index 0000000..a223a57 --- /dev/null +++ b/thinkphp/library/think/config/driver/Ini.php @@ -0,0 +1,24 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\config\driver; + +class Ini +{ + public function parse($config) + { + if (is_file($config)) { + return parse_ini_file($config, true); + } else { + return parse_ini_string($config, true); + } + } +} diff --git a/thinkphp/library/think/config/driver/Json.php b/thinkphp/library/think/config/driver/Json.php new file mode 100755 index 0000000..557f75f --- /dev/null +++ b/thinkphp/library/think/config/driver/Json.php @@ -0,0 +1,24 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\config\driver; + +class Json +{ + public function parse($config) + { + if (is_file($config)) { + $config = file_get_contents($config); + } + $result = json_decode($config, true); + return $result; + } +} diff --git a/thinkphp/library/think/config/driver/Xml.php b/thinkphp/library/think/config/driver/Xml.php new file mode 100755 index 0000000..b573a56 --- /dev/null +++ b/thinkphp/library/think/config/driver/Xml.php @@ -0,0 +1,31 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\config\driver; + +class Xml +{ + public function parse($config) + { + if (is_file($config)) { + $content = simplexml_load_file($config); + } else { + $content = simplexml_load_string($config); + } + $result = (array) $content; + foreach ($result as $key => $val) { + if (is_object($val)) { + $result[$key] = (array) $val; + } + } + return $result; + } +} diff --git a/thinkphp/library/think/controller/Rest.php b/thinkphp/library/think/controller/Rest.php new file mode 100755 index 0000000..2a28057 --- /dev/null +++ b/thinkphp/library/think/controller/Rest.php @@ -0,0 +1,99 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\controller; + +use think\App; +use think\Request; +use think\Response; + +abstract class Rest +{ + + protected $method; // 当前请求类型 + protected $type; // 当前资源类型 + // 输出类型 + protected $restMethodList = 'get|post|put|delete'; + protected $restDefaultMethod = 'get'; + protected $restTypeList = 'html|xml|json|rss'; + protected $restDefaultType = 'html'; + protected $restOutputType = [ // REST允许输出的资源类型列表 + 'xml' => 'application/xml', + 'json' => 'application/json', + 'html' => 'text/html', + ]; + + /** + * 构造函数 取得模板对象实例 + * @access public + */ + public function __construct() + { + // 资源类型检测 + $request = Request::instance(); + $ext = $request->ext(); + if ('' == $ext) { + // 自动检测资源类型 + $this->type = $request->type(); + } elseif (!preg_match('/(' . $this->restTypeList . ')$/i', $ext)) { + // 资源类型非法 则用默认资源类型访问 + $this->type = $this->restDefaultType; + } else { + $this->type = $ext; + } + // 请求方式检测 + $method = strtolower($request->method()); + if (!preg_match('/(' . $this->restMethodList . ')$/i', $method)) { + // 请求方式非法 则用默认请求方法 + $method = $this->restDefaultMethod; + } + $this->method = $method; + } + + /** + * REST 调用 + * @access public + * @param string $method 方法名 + * @return mixed + * @throws \Exception + */ + public function _empty($method) + { + if (method_exists($this, $method . '_' . $this->method . '_' . $this->type)) { + // RESTFul方法支持 + $fun = $method . '_' . $this->method . '_' . $this->type; + } elseif ($this->method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) { + $fun = $method . '_' . $this->type; + } elseif ($this->type == $this->restDefaultType && method_exists($this, $method . '_' . $this->method)) { + $fun = $method . '_' . $this->method; + } + if (isset($fun)) { + return App::invokeMethod([$this, $fun]); + } else { + // 抛出异常 + throw new \Exception('error action :' . $method); + } + } + + /** + * 输出返回数据 + * @access protected + * @param mixed $data 要返回的数据 + * @param String $type 返回类型 JSON XML + * @param integer $code HTTP状态码 + * @return Response + */ + protected function response($data, $type = 'json', $code = 200) + { + return Response::create($data, $type)->code($code); + } + +} diff --git a/thinkphp/library/think/controller/Test.php b/thinkphp/library/think/controller/Test.php new file mode 100755 index 0000000..242661f --- /dev/null +++ b/thinkphp/library/think/controller/Test.php @@ -0,0 +1,3 @@ +<?php + header("Content-type: text/html; charset=utf-8"); + echo base64_decode("KiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogPGJyLz4qIFdTVE1hcnTlpJrnlKjmiLfllYbln44NCiA8YnIvPiog54mI5p2D5omA5pyJIDIwMTYtMjA2NiDlub/lt57llYbmt5jkv6Hmga/np5HmioDmnInpmZDlhazlj7jvvIzlubbkv53nlZnmiYDmnInmnYPliKnjgIINCiA8YnIvPiog5a6Y572R5Zyw5Z2AOmh0dHA6Ly93d3cud3N0bWFydC5uZXQNCiA8YnIvPiog5Lqk5rWB56S+5Yy6Omh0dHA6Ly9iYnMuc2hhbmd0YW9zb2Z0LmNvbQ0KIDxici8+KiDogZTns7tRUToxNTMyODk5NzANCiA8YnIvPiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIDxici8+KiDov5nkuI3mmK/kuIDkuKroh6rnlLHova/ku7bvvIHmnKrnu4/mnKzlhazlj7jmjojmnYPmgqjlj6rog73lnKjkuI3nlKjkuo7llYbkuJrnm67nmoTnmoTliY3mj5DkuIvlr7nnqIvluo/ku6PnoIHov5vooYzkv67mlLnlkozkvb/nlKjvvJsNCiA8YnIvPiog5LiN5YWB6K645a+556iL5bqP5Luj56CB5Lul5Lu75L2V5b2i5byP5Lu75L2V55uu55qE55qE5YaN5Y+R5biD44CCDQogPGJyLz4qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0="); \ No newline at end of file diff --git a/thinkphp/library/think/controller/Yar.php b/thinkphp/library/think/controller/Yar.php new file mode 100755 index 0000000..af4e9a1 --- /dev/null +++ b/thinkphp/library/think/controller/Yar.php @@ -0,0 +1,51 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\controller; + +/** + * ThinkPHP Yar控制器类 + */ +abstract class Yar +{ + + /** + * 构造函数 + * @access public + */ + public function __construct() + { + //控制器初始化 + if (method_exists($this, '_initialize')) { + $this->_initialize(); + } + + //判断扩展是否存在 + if (!extension_loaded('yar')) { + throw new \Exception('not support yar'); + } + + //实例化Yar_Server + $server = new \Yar_Server($this); + // 启动server + $server->handle(); + } + + /** + * 魔术方法 有不存在的操作的时候执行 + * @access public + * @param string $method 方法名 + * @param array $args 参数 + * @return mixed + */ + public function __call($method, $args) + {} +} diff --git a/thinkphp/library/think/db/Builder.php b/thinkphp/library/think/db/Builder.php new file mode 100755 index 0000000..213cb09 --- /dev/null +++ b/thinkphp/library/think/db/Builder.php @@ -0,0 +1,864 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db; + +use BadMethodCallException; +use PDO; +use think\Exception; + +abstract class Builder +{ + // connection对象实例 + protected $connection; + // 查询对象实例 + protected $query; + + // 数据库表达式 + protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'not like' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME']; + + // SQL表达式 + protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'; + protected $insertSql = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; + protected $insertAllSql = '%INSERT% INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; + protected $updateSql = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; + protected $deleteSql = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; + + /** + * 构造函数 + * @access public + * @param Connection $connection 数据库连接对象实例 + * @param Query $query 数据库查询对象实例 + */ + public function __construct(Connection $connection, Query $query) + { + $this->connection = $connection; + $this->query = $query; + } + + /** + * 获取当前的连接对象实例 + * @access public + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * 获取当前的Query对象实例 + * @access public + * @return Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名(小写) + * @access protected + * @param string $sql sql语句 + * @return string + */ + protected function parseSqlTable($sql) + { + return $this->query->parseSqlTable($sql); + } + + /** + * 数据分析 + * @access protected + * @param array $data 数据 + * @param array $options 查询参数 + * @return array + * @throws Exception + */ + protected function parseData($data, $options) + { + if (empty($data)) { + return []; + } + + // 获取绑定信息 + $bind = $this->query->getFieldsBind($options['table']); + if ('*' == $options['field']) { + $fields = array_keys($bind); + } else { + $fields = $options['field']; + } + + $result = []; + foreach ($data as $key => $val) { + $item = $this->parseKey($key, $options); + if (is_object($val) && method_exists($val, '__toString')) { + // 对象数据写入 + $val = $val->__toString(); + } + if (false === strpos($key, '.') && !in_array($key, $fields, true)) { + if ($options['strict']) { + throw new Exception('fields not exists:[' . $key . ']'); + } + } elseif (is_null($val)) { + $result[$item] = 'NULL'; + } elseif (isset($val[0]) && 'exp' == $val[0]) { + $result[$item] = $val[1]; + } elseif (is_scalar($val)) { + // 过滤非标量数据 + if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) { + $result[$item] = $val; + } else { + $key = str_replace('.', '_', $key); + $this->query->bind('data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR); + $result[$item] = ':data__' . $key; + } + } + } + return $result; + } + + /** + * 字段名分析 + * @access protected + * @param string $key + * @param array $options + * @return string + */ + protected function parseKey($key, $options = []) + { + return $key; + } + + /** + * value分析 + * @access protected + * @param mixed $value + * @param string $field + * @return string|array + */ + protected function parseValue($value, $field = '') + { + if (is_string($value)) { + $value = strpos($value, ':') === 0 && $this->query->isBind(substr($value, 1)) ? $value : $this->connection->quote($value); + } elseif (is_array($value)) { + $value = array_map([$this, 'parseValue'], $value); + } elseif (is_bool($value)) { + $value = $value ? '1' : '0'; + } elseif (is_null($value)) { + $value = 'null'; + } + return $value; + } + + /** + * field分析 + * @access protected + * @param mixed $fields + * @param array $options + * @return string + */ + protected function parseField($fields, $options = []) + { + if ('*' == $fields || empty($fields)) { + $fieldsStr = '*'; + } elseif (is_array($fields)) { + // 支持 'field1'=>'field2' 这样的字段别名定义 + $array = []; + foreach ($fields as $key => $field) { + if (!is_numeric($key)) { + $array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options); + } else { + $array[] = $this->parseKey($field, $options); + } + } + $fieldsStr = implode(',', $array); + } + return $fieldsStr; + } + + /** + * table分析 + * @access protected + * @param mixed $tables + * @param array $options + * @return string + */ + protected function parseTable($tables, $options = []) + { + $item = []; + foreach ((array) $tables as $key => $table) { + if (!is_numeric($key)) { + if (strpos($key, '@think')) { + $key = strstr($key, '@think', true); + } + $key = $this->parseSqlTable($key); + $item[] = $this->parseKey($key) . ' ' . (isset($options['alias'][$table]) ? $this->parseKey($options['alias'][$table]) : $this->parseKey($table)); + } else { + $table = $this->parseSqlTable($table); + if (isset($options['alias'][$table])) { + $item[] = $this->parseKey($table) . ' ' . $this->parseKey($options['alias'][$table]); + } else { + $item[] = $this->parseKey($table); + } + } + } + return implode(',', $item); + } + + /** + * where分析 + * @access protected + * @param mixed $where 查询条件 + * @param array $options 查询参数 + * @return string + */ + protected function parseWhere($where, $options) + { + $whereStr = $this->buildWhere($where, $options); + if (!empty($options['soft_delete'])) { + // 附加软删除条件 + list($field, $condition) = $options['soft_delete']; + + $binds = $this->query->getFieldsBind($options['table']); + $whereStr = $whereStr ? '( ' . $whereStr . ' ) AND ' : ''; + $whereStr = $whereStr . $this->parseWhereItem($field, $condition, '', $options, $binds); + } + return empty($whereStr) ? '' : ' WHERE ' . $whereStr; + } + + /** + * 生成查询条件SQL + * @access public + * @param mixed $where + * @param array $options + * @return string + */ + public function buildWhere($where, $options) + { + if (empty($where)) { + $where = []; + } + + if ($where instanceof Query) { + return $this->buildWhere($where->getOptions('where'), $options); + } + + $whereStr = ''; + $binds = $this->query->getFieldsBind($options['table']); + foreach ($where as $key => $val) { + $str = []; + foreach ($val as $field => $value) { + if ($value instanceof \Closure) { + // 使用闭包查询 + $query = new Query($this->connection); + call_user_func_array($value, [ & $query]); + $whereClause = $this->buildWhere($query->getOptions('where'), $options); + if (!empty($whereClause)) { + $str[] = ' ' . $key . ' ( ' . $whereClause . ' )'; + } + } elseif (strpos($field, '|')) { + // 不同字段使用相同查询条件(OR) + $array = explode('|', $field); + $item = []; + foreach ($array as $k) { + $item[] = $this->parseWhereItem($k, $value, '', $options, $binds); + } + $str[] = ' ' . $key . ' ( ' . implode(' OR ', $item) . ' )'; + } elseif (strpos($field, '&')) { + // 不同字段使用相同查询条件(AND) + $array = explode('&', $field); + $item = []; + foreach ($array as $k) { + $item[] = $this->parseWhereItem($k, $value, '', $options, $binds); + } + $str[] = ' ' . $key . ' ( ' . implode(' AND ', $item) . ' )'; + } else { + // 对字段使用表达式查询 + $field = is_string($field) ? $field : ''; + $str[] = ' ' . $key . ' ' . $this->parseWhereItem($field, $value, $key, $options, $binds); + } + } + + $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($key) + 1) : implode(' ', $str); + } + + return $whereStr; + } + + // where子单元分析 + protected function parseWhereItem($field, $val, $rule = '', $options = [], $binds = [], $bindName = null) + { + // 字段分析 + $key = $field ? $this->parseKey($field, $options) : ''; + + // 查询规则和条件 + if (!is_array($val)) { + $val = is_null($val) ? ['null', ''] : ['=', $val]; + } + list($exp, $value) = $val; + + // 对一个字段使用多个查询条件 + if (is_array($exp)) { + $item = array_pop($val); + // 传入 or 或者 and + if (is_string($item) && in_array($item, ['AND', 'and', 'OR', 'or'])) { + $rule = $item; + } else { + array_push($val, $item); + } + foreach ($val as $k => $item) { + $bindName = 'where_' . str_replace('.', '_', $field) . '_' . $k; + $str[] = $this->parseWhereItem($field, $item, $rule, $options, $binds, $bindName); + } + return '( ' . implode(' ' . $rule . ' ', $str) . ' )'; + } + + // 检测操作符 + if (!in_array($exp, $this->exp)) { + $exp = strtolower($exp); + if (isset($this->exp[$exp])) { + $exp = $this->exp[$exp]; + } else { + throw new Exception('where express error:' . $exp); + } + } + $bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field); + if (preg_match('/\W/', $bindName)) { + // 处理带非单词字符的字段名 + $bindName = md5($bindName); + } + + if (is_object($value) && method_exists($value, '__toString')) { + // 对象数据写入 + $value = $value->__toString(); + } + + $bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR; + if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) { + if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) { + if ($this->query->isBind($bindName)) { + $bindName .= '_' . str_replace('.', '_', uniqid('', true)); + } + $this->query->bind($bindName, $value, $bindType); + $value = ':' . $bindName; + } + } + + $whereStr = ''; + if (in_array($exp, ['=', '<>', '>', '>=', '<', '<='])) { + // 比较运算 + if ($value instanceof \Closure) { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); + } else { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); + } + } elseif ('LIKE' == $exp || 'NOT LIKE' == $exp) { + // 模糊匹配 + if (is_array($value)) { + foreach ($value as $item) { + $array[] = $key . ' ' . $exp . ' ' . $this->parseValue($item, $field); + } + $logic = isset($val[2]) ? $val[2] : 'AND'; + $whereStr .= '(' . implode($array, ' ' . strtoupper($logic) . ' ') . ')'; + } else { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field); + } + } elseif ('EXP' == $exp) { + // 表达式查询 + $whereStr .= '( ' . $key . ' ' . $value . ' )'; + } elseif (in_array($exp, ['NOT NULL', 'NULL'])) { + // NULL 查询 + $whereStr .= $key . ' IS ' . $exp; + } elseif (in_array($exp, ['NOT IN', 'IN'])) { + // IN 查询 + if ($value instanceof \Closure) { + $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value); + } else { + $value = array_unique(is_array($value) ? $value : explode(',', $value)); + if (array_key_exists($field, $binds)) { + $bind = []; + $array = []; + $i = 0; + foreach ($value as $v) { + $i++; + if ($this->query->isBind($bindName . '_in_' . $i)) { + $bindKey = $bindName . '_in_' . uniqid() . '_' . $i; + } else { + $bindKey = $bindName . '_in_' . $i; + } + $bind[$bindKey] = [$v, $bindType]; + $array[] = ':' . $bindKey; + } + $this->query->bind($bind); + $zone = implode(',', $array); + } else { + $zone = implode(',', $this->parseValue($value, $field)); + } + $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? "''" : $zone) . ')'; + } + } elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) { + // BETWEEN 查询 + $data = is_array($value) ? $value : explode(',', $value); + if (array_key_exists($field, $binds)) { + if ($this->query->isBind($bindName . '_between_1')) { + $bindKey1 = $bindName . '_between_1' . uniqid(); + $bindKey2 = $bindName . '_between_2' . uniqid(); + } else { + $bindKey1 = $bindName . '_between_1'; + $bindKey2 = $bindName . '_between_2'; + } + $bind = [ + $bindKey1 => [$data[0], $bindType], + $bindKey2 => [$data[1], $bindType], + ]; + $this->query->bind($bind); + $between = ':' . $bindKey1 . ' AND :' . $bindKey2; + } else { + $between = $this->parseValue($data[0], $field) . ' AND ' . $this->parseValue($data[1], $field); + } + $whereStr .= $key . ' ' . $exp . ' ' . $between; + } elseif (in_array($exp, ['NOT EXISTS', 'EXISTS'])) { + // EXISTS 查询 + if ($value instanceof \Closure) { + $whereStr .= $exp . ' ' . $this->parseClosure($value); + } else { + $whereStr .= $exp . ' (' . $value . ')'; + } + } elseif (in_array($exp, ['< TIME', '> TIME', '<= TIME', '>= TIME'])) { + $whereStr .= $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($value, $field, $options, $bindName, $bindType); + } elseif (in_array($exp, ['BETWEEN TIME', 'NOT BETWEEN TIME'])) { + if (is_string($value)) { + $value = explode(',', $value); + } + + $whereStr .= $key . ' ' . substr($exp, 0, -4) . $this->parseDateTime($value[0], $field, $options, $bindName . '_between_1', $bindType) . ' AND ' . $this->parseDateTime($value[1], $field, $options, $bindName . '_between_2', $bindType); + } + return $whereStr; + } + + // 执行闭包子查询 + protected function parseClosure($call, $show = true) + { + $query = new Query($this->connection); + call_user_func_array($call, [ & $query]); + return $query->buildSql($show); + } + + /** + * 日期时间条件解析 + * @access protected + * @param string $value + * @param string $key + * @param array $options + * @param string $bindName + * @param integer $bindType + * @return string + */ + protected function parseDateTime($value, $key, $options = [], $bindName = null, $bindType = null) + { + // 获取时间字段类型 + if (strpos($key, '.')) { + list($table, $key) = explode('.', $key); + if (isset($options['alias']) && $pos = array_search($table, $options['alias'])) { + $table = $pos; + } + } else { + $table = $options['table']; + } + $type = $this->query->getTableInfo($table, 'type'); + if (isset($type[$key])) { + $info = $type[$key]; + } + if (isset($info)) { + if (is_string($value)) { + $value = strtotime($value) ?: $value; + } + + if (preg_match('/(datetime|timestamp)/is', $info)) { + // 日期及时间戳类型 + $value = date('Y-m-d H:i:s', $value); + } elseif (preg_match('/(date)/is', $info)) { + // 日期及时间戳类型 + $value = date('Y-m-d', $value); + } + } + $bindName = $bindName ?: $key; + $this->query->bind($bindName, $value, $bindType); + return ':' . $bindName; + } + + /** + * limit分析 + * @access protected + * @param mixed $limit + * @return string + */ + protected function parseLimit($limit) + { + return (!empty($limit) && false === strpos($limit, '(')) ? ' LIMIT ' . $limit . ' ' : ''; + } + + /** + * join分析 + * @access protected + * @param array $join + * @param array $options 查询条件 + * @return string + */ + protected function parseJoin($join, $options = []) + { + $joinStr = ''; + if (!empty($join)) { + foreach ($join as $item) { + list($table, $type, $on) = $item; + $condition = []; + foreach ((array) $on as $val) { + if (strpos($val, '=')) { + list($val1, $val2) = explode('=', $val, 2); + $condition[] = $this->parseKey($val1, $options) . '=' . $this->parseKey($val2, $options); + } else { + $condition[] = $val; + } + } + + $table = $this->parseTable($table, $options); + $joinStr .= ' ' . $type . ' JOIN ' . $table . ' ON ' . implode(' AND ', $condition); + } + } + return $joinStr; + } + + /** + * order分析 + * @access protected + * @param mixed $order + * @param array $options 查询条件 + * @return string + */ + protected function parseOrder($order, $options = []) + { + if (is_array($order)) { + $array = []; + foreach ($order as $key => $val) { + if (is_numeric($key)) { + if ('[rand]' == $val) { + if (method_exists($this, 'parseRand')) { + $array[] = $this->parseRand(); + } else { + throw new BadMethodCallException('method not exists:' . get_class($this) . '-> parseRand'); + } + } elseif (false === strpos($val, '(')) { + $array[] = $this->parseKey($val, $options); + } else { + $array[] = $val; + } + } else { + $sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : ''; + $array[] = $this->parseKey($key, $options) . ' ' . $sort; + } + } + $order = implode(',', $array); + } + return !empty($order) ? ' ORDER BY ' . $order : ''; + } + + /** + * group分析 + * @access protected + * @param mixed $group + * @return string + */ + protected function parseGroup($group) + { + return !empty($group) ? ' GROUP BY ' . $this->parseKey($group) : ''; + } + + /** + * having分析 + * @access protected + * @param string $having + * @return string + */ + protected function parseHaving($having) + { + return !empty($having) ? ' HAVING ' . $having : ''; + } + + /** + * comment分析 + * @access protected + * @param string $comment + * @return string + */ + protected function parseComment($comment) + { + return !empty($comment) ? ' /* ' . $comment . ' */' : ''; + } + + /** + * distinct分析 + * @access protected + * @param mixed $distinct + * @return string + */ + protected function parseDistinct($distinct) + { + return !empty($distinct) ? ' DISTINCT ' : ''; + } + + /** + * union分析 + * @access protected + * @param mixed $union + * @return string + */ + protected function parseUnion($union) + { + if (empty($union)) { + return ''; + } + $type = $union['type']; + unset($union['type']); + foreach ($union as $u) { + if ($u instanceof \Closure) { + $sql[] = $type . ' ' . $this->parseClosure($u, false); + } elseif (is_string($u)) { + $sql[] = $type . ' ' . $this->parseSqlTable($u); + } + } + return implode(' ', $sql); + } + + /** + * index分析,可在操作链中指定需要强制使用的索引 + * @access protected + * @param mixed $index + * @return string + */ + protected function parseForce($index) + { + if (empty($index)) { + return ''; + } + + if (is_array($index)) { + $index = join(",", $index); + } + + return sprintf(" FORCE INDEX ( %s ) ", $index); + } + + /** + * 设置锁机制 + * @access protected + * @param bool|string $lock + * @return string + */ + protected function parseLock($lock = false) + { + if (is_bool($lock)) { + return $lock ? ' FOR UPDATE ' : ''; + } elseif (is_string($lock)) { + return ' ' . trim($lock) . ' '; + } + } + + /** + * 生成查询SQL + * @access public + * @param array $options 表达式 + * @return string + */ + public function select($options = []) + { + $sql = str_replace( + ['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'], + [ + $this->parseTable($options['table'], $options), + $this->parseDistinct($options['distinct']), + $this->parseField($options['field'], $options), + $this->parseJoin($options['join'], $options), + $this->parseWhere($options['where'], $options), + $this->parseGroup($options['group']), + $this->parseHaving($options['having']), + $this->parseOrder($options['order'], $options), + $this->parseLimit($options['limit']), + $this->parseUnion($options['union']), + $this->parseLock($options['lock']), + $this->parseComment($options['comment']), + $this->parseForce($options['force']), + ], $this->selectSql); + return $sql; + } + + /** + * 生成insert SQL + * @access public + * @param array $data 数据 + * @param array $options 表达式 + * @param bool $replace 是否replace + * @return string + */ + public function insert(array $data, $options = [], $replace = false) + { + // 分析并处理数据 + $data = $this->parseData($data, $options); + if (empty($data)) { + return 0; + } + $fields = array_keys($data); + $values = array_values($data); + + $sql = str_replace( + ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], + [ + $replace ? 'REPLACE' : 'INSERT', + $this->parseTable($options['table'], $options), + implode(' , ', $fields), + implode(' , ', $values), + $this->parseComment($options['comment']), + ], $this->insertSql); + + return $sql; + } + + /** + * 生成insertall SQL + * @access public + * @param array $dataSet 数据集 + * @param array $options 表达式 + * @param bool $replace 是否replace + * @return string + * @throws Exception + */ + public function insertAll($dataSet, $options = [], $replace = false) + { + // 获取合法的字段 + if ('*' == $options['field']) { + $fields = array_keys($this->query->getFieldsType($options['table'])); + } else { + $fields = $options['field']; + } + + foreach ($dataSet as &$data) { + foreach ($data as $key => $val) { + if (!in_array($key, $fields, true)) { + if ($options['strict']) { + throw new Exception('fields not exists:[' . $key . ']'); + } + unset($data[$key]); + } elseif (is_null($val)) { + $data[$key] = 'NULL'; + } elseif (is_scalar($val)) { + $data[$key] = $this->parseValue($val, $key); + } elseif (is_object($val) && method_exists($val, '__toString')) { + // 对象数据写入 + $data[$key] = $val->__toString(); + } else { + // 过滤掉非标量数据 + unset($data[$key]); + } + } + $value = array_values($data); + $values[] = 'SELECT ' . implode(',', $value); + } + $fields = array_map([$this, 'parseKey'], array_keys(reset($dataSet))); + $sql = str_replace( + ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'], + [ + $replace ? 'REPLACE' : 'INSERT', + $this->parseTable($options['table'], $options), + implode(' , ', $fields), + implode(' UNION ALL ', $values), + $this->parseComment($options['comment']), + ], $this->insertAllSql); + + return $sql; + } + + /** + * 生成select insert SQL + * @access public + * @param array $fields 数据 + * @param string $table 数据表 + * @param array $options 表达式 + * @return string + */ + public function selectInsert($fields, $table, $options) + { + if (is_string($fields)) { + $fields = explode(',', $fields); + } + + $fields = array_map([$this, 'parseKey'], $fields); + $sql = 'INSERT INTO ' . $this->parseTable($table, $options) . ' (' . implode(',', $fields) . ') ' . $this->select($options); + return $sql; + } + + /** + * 生成update SQL + * @access public + * @param array $data 数据 + * @param array $options 表达式 + * @return string + */ + public function update($data, $options) + { + $table = $this->parseTable($options['table'], $options); + $data = $this->parseData($data, $options); + if (empty($data)) { + return ''; + } + foreach ($data as $key => $val) { + $set[] = $key . '=' . $val; + } + + $sql = str_replace( + ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'], + [ + $this->parseTable($options['table'], $options), + implode(',', $set), + $this->parseJoin($options['join'], $options), + $this->parseWhere($options['where'], $options), + $this->parseOrder($options['order'], $options), + $this->parseLimit($options['limit']), + $this->parseLock($options['lock']), + $this->parseComment($options['comment']), + ], $this->updateSql); + + return $sql; + } + + /** + * 生成delete SQL + * @access public + * @param array $options 表达式 + * @return string + */ + public function delete($options) + { + $sql = str_replace( + ['%TABLE%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'], + [ + $this->parseTable($options['table'], $options), + !empty($options['using']) ? ' USING ' . $this->parseTable($options['using'], $options) . ' ' : '', + $this->parseJoin($options['join'], $options), + $this->parseWhere($options['where'], $options), + $this->parseOrder($options['order'], $options), + $this->parseLimit($options['limit']), + $this->parseLock($options['lock']), + $this->parseComment($options['comment']), + ], $this->deleteSql); + + return $sql; + } +} diff --git a/thinkphp/library/think/db/Connection.php b/thinkphp/library/think/db/Connection.php new file mode 100755 index 0000000..a7d130b --- /dev/null +++ b/thinkphp/library/think/db/Connection.php @@ -0,0 +1,1038 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db; + +use PDO; +use PDOStatement; +use think\Db; +use think\db\exception\BindParamException; +use think\Debug; +use think\Exception; +use think\exception\PDOException; +use think\Log; + +/** + * Class Connection + * @package think + * @method Query table(string $table) 指定数据表(含前缀) + * @method Query name(string $name) 指定数据表(不含前缀) + * + */ +abstract class Connection +{ + + /** @var PDOStatement PDO操作实例 */ + protected $PDOStatement; + + /** @var string 当前SQL指令 */ + protected $queryStr = ''; + // 返回或者影响记录数 + protected $numRows = 0; + // 事务指令数 + protected $transTimes = 0; + // 错误信息 + protected $error = ''; + + /** @var PDO[] 数据库连接ID 支持多个连接 */ + protected $links = []; + + /** @var PDO 当前连接ID */ + protected $linkID; + protected $linkRead; + protected $linkWrite; + + // 查询结果类型 + protected $fetchType = PDO::FETCH_ASSOC; + // 字段属性大小写 + protected $attrCase = PDO::CASE_LOWER; + // 监听回调 + protected static $event = []; + // 使用Builder类 + protected $builder; + // 数据库连接参数配置 + protected $config = [ + // 数据库类型 + 'type' => '', + // 服务器地址 + 'hostname' => '', + // 数据库名 + 'database' => '', + // 用户名 + 'username' => '', + // 密码 + 'password' => '', + // 端口 + 'hostport' => '', + // 连接dsn + 'dsn' => '', + // 数据库连接参数 + 'params' => [], + // 数据库编码默认采用utf8 + 'charset' => 'utf8', + // 数据库表前缀 + 'prefix' => '', + // 数据库调试模式 + 'debug' => false, + // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'deploy' => 0, + // 数据库读写是否分离 主从式有效 + 'rw_separate' => false, + // 读写分离后 主服务器数量 + 'master_num' => 1, + // 指定从服务器序号 + 'slave_no' => '', + // 是否严格检查字段是否存在 + 'fields_strict' => true, + // 数据返回类型 + 'result_type' => PDO::FETCH_ASSOC, + // 数据集返回类型 + 'resultset_type' => 'array', + // 自动写入时间戳字段 + 'auto_timestamp' => false, + // 时间字段取出后的默认时间格式 + 'datetime_format' => 'Y-m-d H:i:s', + // 是否需要进行SQL性能分析 + 'sql_explain' => false, + // Builder类 + 'builder' => '', + // Query类 + 'query' => '\\think\\db\\Query', + // 是否需要断线重连 + 'break_reconnect' => false, + ]; + + // PDO连接参数 + protected $params = [ + PDO::ATTR_CASE => PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, + PDO::ATTR_STRINGIFY_FETCHES => false, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + // 绑定参数 + protected $bind = []; + + /** + * 构造函数 读取数据库配置信息 + * @access public + * @param array $config 数据库配置数组 + */ + public function __construct(array $config = []) + { + if (!empty($config)) { + $this->config = array_merge($this->config, $config); + } + } + + /** + * 获取新的查询对象 + * @access protected + * @return Query + */ + protected function getQuery() + { + $class = $this->config['query']; + return new $class($this); + } + + /** + * 获取当前连接器类对应的Builder类 + * @access public + * @return string + */ + public function getBuilder() + { + if (!empty($this->builder)) { + return $this->builder; + } else { + return $this->getConfig('builder') ?: '\\think\\db\\builder\\' . ucfirst($this->getConfig('type')); + } + } + + /** + * 调用Query类的查询方法 + * @access public + * @param string $method 方法名称 + * @param array $args 调用参数 + * @return mixed + */ + public function __call($method, $args) + { + return call_user_func_array([$this->getQuery(), $method], $args); + } + + /** + * 解析pdo连接的dsn信息 + * @access protected + * @param array $config 连接信息 + * @return string + */ + abstract protected function parseDsn($config); + + /** + * 取得数据表的字段信息 + * @access public + * @param string $tableName + * @return array + */ + abstract public function getFields($tableName); + + /** + * 取得数据库的表信息 + * @access public + * @param string $dbName + * @return array + */ + abstract public function getTables($dbName); + + /** + * SQL性能分析 + * @access protected + * @param string $sql + * @return array + */ + abstract protected function getExplain($sql); + + /** + * 对返数据表字段信息进行大小写转换出来 + * @access public + * @param array $info 字段信息 + * @return array + */ + public function fieldCase($info) + { + // 字段大小写转换 + switch ($this->attrCase) { + case PDO::CASE_LOWER: + $info = array_change_key_case($info); + break; + case PDO::CASE_UPPER: + $info = array_change_key_case($info, CASE_UPPER); + break; + case PDO::CASE_NATURAL: + default: + // 不做转换 + } + return $info; + } + + /** + * 获取数据库的配置参数 + * @access public + * @param string $config 配置名称 + * @return mixed + */ + public function getConfig($config = '') + { + return $config ? $this->config[$config] : $this->config; + } + + /** + * 设置数据库的配置参数 + * @access public + * @param string|array $config 配置名称 + * @param mixed $value 配置值 + * @return void + */ + public function setConfig($config, $value = '') + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } else { + $this->config[$config] = $value; + } + } + + /** + * 连接数据库方法 + * @access public + * @param array $config 连接参数 + * @param integer $linkNum 连接序号 + * @param array|bool $autoConnection 是否自动连接主数据库(用于分布式) + * @return PDO + * @throws Exception + */ + public function connect(array $config = [], $linkNum = 0, $autoConnection = false) + { + if (!isset($this->links[$linkNum])) { + if (!$config) { + $config = $this->config; + } else { + $config = array_merge($this->config, $config); + } + // 连接参数 + if (isset($config['params']) && is_array($config['params'])) { + $params = $config['params'] + $this->params; + } else { + $params = $this->params; + } + // 记录当前字段属性大小写设置 + $this->attrCase = $params[PDO::ATTR_CASE]; + + // 数据返回类型 + if (isset($config['result_type'])) { + $this->fetchType = $config['result_type']; + } + try { + if (empty($config['dsn'])) { + $config['dsn'] = $this->parseDsn($config); + } + if ($config['debug']) { + $startTime = microtime(true); + } + $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params); + if ($config['debug']) { + // 记录数据库连接信息 + Log::record('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn'], 'sql'); + } + } catch (\PDOException $e) { + if ($autoConnection) { + Log::record($e->getMessage(), 'error'); + return $this->connect($autoConnection, $linkNum); + } else { + throw $e; + } + } + } + return $this->links[$linkNum]; + } + + /** + * 释放查询结果 + * @access public + */ + public function free() + { + $this->PDOStatement = null; + } + + /** + * 获取PDO对象 + * @access public + * @return \PDO|false + */ + public function getPdo() + { + if (!$this->linkID) { + return false; + } else { + return $this->linkID; + } + } + + /** + * 执行查询 返回数据集 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @param bool $master 是否在主服务器读操作 + * @param bool $pdo 是否返回PDO对象 + * @return mixed + * @throws PDOException + * @throws \Exception + */ + public function query($sql, $bind = [], $master = false, $pdo = false) + { + $this->initConnect($master); + if (!$this->linkID) { + return false; + } + + // 记录SQL语句 + $this->queryStr = $sql; + if ($bind) { + $this->bind = $bind; + } + + // 释放前次的查询结果 + if (!empty($this->PDOStatement)) { + $this->free(); + } + + Db::$queryTimes++; + try { + // 调试开始 + $this->debug(true); + // 预处理 + if (empty($this->PDOStatement)) { + $this->PDOStatement = $this->linkID->prepare($sql); + } + // 是否为存储过程调用 + $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); + // 参数绑定 + if ($procedure) { + $this->bindParam($bind); + } else { + $this->bindValue($bind); + } + // 执行查询 + $this->PDOStatement->execute(); + // 调试结束 + $this->debug(false); + // 返回结果集 + return $this->getResult($pdo, $procedure); + } catch (\PDOException $e) { + if ($this->isBreak($e)) { + return $this->close()->query($sql, $bind, $master, $pdo); + } + throw new PDOException($e, $this->config, $this->getLastsql()); + } catch (\Exception $e) { + if ($this->isBreak($e)) { + return $this->close()->query($sql, $bind, $master, $pdo); + } + throw $e; + } + } + + /** + * 执行语句 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @return int + * @throws PDOException + * @throws \Exception + */ + public function execute($sql, $bind = []) + { + $this->initConnect(true); + if (!$this->linkID) { + return false; + } + + // 记录SQL语句 + $this->queryStr = $sql; + if ($bind) { + $this->bind = $bind; + } + + //释放前次的查询结果 + if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) { + $this->free(); + } + + Db::$executeTimes++; + try { + // 调试开始 + $this->debug(true); + // 预处理 + if (empty($this->PDOStatement)) { + $this->PDOStatement = $this->linkID->prepare($sql); + } + // 是否为存储过程调用 + $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']); + // 参数绑定 + if ($procedure) { + $this->bindParam($bind); + } else { + $this->bindValue($bind); + } + // 执行语句 + $this->PDOStatement->execute(); + // 调试结束 + $this->debug(false); + + $this->numRows = $this->PDOStatement->rowCount(); + return $this->numRows; + } catch (\PDOException $e) { + if ($this->isBreak($e)) { + return $this->close()->execute($sql, $bind); + } + throw new PDOException($e, $this->config, $this->getLastsql()); + } catch (\Exception $e) { + if ($this->isBreak($e)) { + return $this->close()->execute($sql, $bind); + } + throw $e; + } + } + + /** + * 根据参数绑定组装最终的SQL语句 便于调试 + * @access public + * @param string $sql 带参数绑定的sql语句 + * @param array $bind 参数绑定列表 + * @return string + */ + public function getRealSql($sql, array $bind = []) + { + if (is_array($sql)) { + $sql = implode(';', $sql); + } + + foreach ($bind as $key => $val) { + $value = is_array($val) ? $val[0] : $val; + $type = is_array($val) ? $val[1] : PDO::PARAM_STR; + if (PDO::PARAM_STR == $type) { + $value = $this->quote($value); + } elseif (PDO::PARAM_INT == $type) { + $value = (float) $value; + } + // 判断占位符 + $sql = is_numeric($key) ? + substr_replace($sql, $value, strpos($sql, '?'), 1) : + str_replace( + [':' . $key . ')', ':' . $key . ',', ':' . $key . ' ', ':' . $key . PHP_EOL], + [$value . ')', $value . ',', $value . ' ', $value . PHP_EOL], + $sql . ' '); + } + return rtrim($sql); + } + + /** + * 参数绑定 + * 支持 ['name'=>'value','id'=>123] 对应命名占位符 + * 或者 ['value',123] 对应问号占位符 + * @access public + * @param array $bind 要绑定的参数列表 + * @return void + * @throws BindParamException + */ + protected function bindValue(array $bind = []) + { + foreach ($bind as $key => $val) { + // 占位符 + $param = is_numeric($key) ? $key + 1 : ':' . $key; + if (is_array($val)) { + if (PDO::PARAM_INT == $val[1] && '' === $val[0]) { + $val[0] = 0; + } + $result = $this->PDOStatement->bindValue($param, $val[0], $val[1]); + } else { + $result = $this->PDOStatement->bindValue($param, $val); + } + if (!$result) { + throw new BindParamException( + "Error occurred when binding parameters '{$param}'", + $this->config, + $this->getLastsql(), + $bind + ); + } + } + } + + /** + * 存储过程的输入输出参数绑定 + * @access public + * @param array $bind 要绑定的参数列表 + * @return void + * @throws BindParamException + */ + protected function bindParam($bind) + { + foreach ($bind as $key => $val) { + $param = is_numeric($key) ? $key + 1 : ':' . $key; + if (is_array($val)) { + array_unshift($val, $param); + $result = call_user_func_array([$this->PDOStatement, 'bindParam'], $val); + } else { + $result = $this->PDOStatement->bindValue($param, $val); + } + if (!$result) { + $param = array_shift($val); + throw new BindParamException( + "Error occurred when binding parameters '{$param}'", + $this->config, + $this->getLastsql(), + $bind + ); + } + } + } + + /** + * 获得数据集数组 + * @access protected + * @param bool $pdo 是否返回PDOStatement + * @param bool $procedure 是否存储过程 + * @return PDOStatement|array + */ + protected function getResult($pdo = false, $procedure = false) + { + if ($pdo) { + // 返回PDOStatement对象处理 + return $this->PDOStatement; + } + if ($procedure) { + // 存储过程返回结果 + return $this->procedure(); + } + $result = $this->PDOStatement->fetchAll($this->fetchType); + $this->numRows = count($result); + return $result; + } + + /** + * 获得存储过程数据集 + * @access protected + * @return array + */ + protected function procedure() + { + $item = []; + do { + $result = $this->getResult(); + if ($result) { + $item[] = $result; + } + } while ($this->PDOStatement->nextRowset()); + $this->numRows = count($item); + return $item; + } + + /** + * 执行数据库事务 + * @access public + * @param callable $callback 数据操作方法回调 + * @return mixed + * @throws PDOException + * @throws \Exception + * @throws \Throwable + */ + public function transaction($callback) + { + $this->startTrans(); + try { + $result = null; + if (is_callable($callback)) { + $result = call_user_func_array($callback, [$this]); + } + $this->commit(); + return $result; + } catch (\Exception $e) { + $this->rollback(); + throw $e; + } catch (\Throwable $e) { + $this->rollback(); + throw $e; + } + } + + /** + * 启动事务 + * @access public + * @return bool|mixed + * @throws \Exception + */ + public function startTrans() + { + $this->initConnect(true); + if (!$this->linkID) { + return false; + } + + ++$this->transTimes; + try { + if (1 == $this->transTimes) { + $this->linkID->beginTransaction(); + } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { + $this->linkID->exec( + $this->parseSavepoint('trans' . $this->transTimes) + ); + } + + } catch (\PDOException $e) { + if ($this->isBreak($e)) { + return $this->close()->startTrans(); + } + throw $e; + } catch (\Exception $e) { + if ($this->isBreak($e)) { + return $this->close()->startTrans(); + } + throw $e; + } + } + + /** + * 用于非自动提交状态下面的查询提交 + * @access public + * @return void + * @throws PDOException + */ + public function commit() + { + $this->initConnect(true); + + if (1 == $this->transTimes) { + $this->linkID->commit(); + } + + --$this->transTimes; + } + + /** + * 事务回滚 + * @access public + * @return void + * @throws PDOException + */ + public function rollback() + { + $this->initConnect(true); + + if (1 == $this->transTimes) { + $this->linkID->rollBack(); + } elseif ($this->transTimes > 1 && $this->supportSavepoint()) { + $this->linkID->exec( + $this->parseSavepointRollBack('trans' . $this->transTimes) + ); + } + + $this->transTimes = max(0, $this->transTimes - 1); + } + + /** + * 是否支持事务嵌套 + * @return bool + */ + protected function supportSavepoint() + { + return false; + } + + /** + * 生成定义保存点的SQL + * @param $name + * @return string + */ + protected function parseSavepoint($name) + { + return 'SAVEPOINT ' . $name; + } + + /** + * 生成回滚到保存点的SQL + * @param $name + * @return string + */ + protected function parseSavepointRollBack($name) + { + return 'ROLLBACK TO SAVEPOINT ' . $name; + } + + /** + * 批处理执行SQL语句 + * 批处理的指令都认为是execute操作 + * @access public + * @param array $sqlArray SQL批处理指令 + * @return boolean + */ + public function batchQuery($sqlArray = [], $bind = []) + { + if (!is_array($sqlArray)) { + return false; + } + // 自动启动事务支持 + $this->startTrans(); + try { + foreach ($sqlArray as $sql) { + $this->execute($sql, $bind); + } + // 提交事务 + $this->commit(); + } catch (\Exception $e) { + $this->rollback(); + throw $e; + } + + return true; + } + + /** + * 获得查询次数 + * @access public + * @param boolean $execute 是否包含所有查询 + * @return integer + */ + public function getQueryTimes($execute = false) + { + return $execute ? Db::$queryTimes + Db::$executeTimes : Db::$queryTimes; + } + + /** + * 获得执行次数 + * @access public + * @return integer + */ + public function getExecuteTimes() + { + return Db::$executeTimes; + } + + /** + * 关闭数据库(或者重新连接) + * @access public + * @return $this + */ + public function close() + { + $this->linkID = null; + $this->linkWrite = null; + $this->linkRead = null; + $this->links = []; + return $this; + } + + /** + * 是否断线 + * @access protected + * @param \PDOException|\Exception $e 异常对象 + * @return bool + */ + protected function isBreak($e) + { + if (!$this->config['break_reconnect']) { + return false; + } + + $info = [ + 'server has gone away', + 'no connection to the server', + 'Lost connection', + 'is dead or not enabled', + 'Error while sending', + 'decryption failed or bad record mac', + 'server closed the connection unexpectedly', + 'SSL connection has been closed unexpectedly', + 'Error writing data to the connection', + 'Resource deadlock avoided', + ]; + + $error = $e->getMessage(); + + foreach ($info as $msg) { + if (false !== stripos($error, $msg)) { + return true; + } + } + return false; + } + + /** + * 获取最近一次查询的sql语句 + * @access public + * @return string + */ + public function getLastSql() + { + return $this->getRealSql($this->queryStr, $this->bind); + } + + /** + * 获取最近插入的ID + * @access public + * @param string $sequence 自增序列名 + * @return string + */ + public function getLastInsID($sequence = null) + { + return $this->linkID->lastInsertId($sequence); + } + + /** + * 获取返回或者影响的记录数 + * @access public + * @return integer + */ + public function getNumRows() + { + return $this->numRows; + } + + /** + * 获取最近的错误信息 + * @access public + * @return string + */ + public function getError() + { + if ($this->PDOStatement) { + $error = $this->PDOStatement->errorInfo(); + $error = $error[1] . ':' . $error[2]; + } else { + $error = ''; + } + if ('' != $this->queryStr) { + $error .= "\n [ SQL语句 ] : " . $this->getLastsql(); + } + return $error; + } + + /** + * SQL指令安全过滤 + * @access public + * @param string $str SQL字符串 + * @param bool $master 是否主库查询 + * @return string + */ + public function quote($str, $master = true) + { + $this->initConnect($master); + return $this->linkID ? $this->linkID->quote($str) : $str; + } + + /** + * 数据库调试 记录当前SQL及分析性能 + * @access protected + * @param boolean $start 调试开始标记 true 开始 false 结束 + * @param string $sql 执行的SQL语句 留空自动获取 + * @return void + */ + protected function debug($start, $sql = '') + { + if (!empty($this->config['debug'])) { + // 开启数据库调试模式 + if ($start) { + Debug::remark('queryStartTime', 'time'); + } else { + // 记录操作结束时间 + Debug::remark('queryEndTime', 'time'); + $runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime'); + $sql = $sql ?: $this->getLastsql(); + $result = []; + // SQL性能分析 + if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) { + $result = $this->getExplain($sql); + } + // SQL监听 + $this->trigger($sql, $runtime, $result); + } + } + } + + /** + * 监听SQL执行 + * @access public + * @param callable $callback 回调方法 + * @return void + */ + public function listen($callback) + { + self::$event[] = $callback; + } + + /** + * 触发SQL事件 + * @access protected + * @param string $sql SQL语句 + * @param float $runtime SQL运行时间 + * @param mixed $explain SQL分析 + * @return bool + */ + protected function trigger($sql, $runtime, $explain = []) + { + if (!empty(self::$event)) { + foreach (self::$event as $callback) { + if (is_callable($callback)) { + call_user_func_array($callback, [$sql, $runtime, $explain]); + } + } + } else { + // 未注册监听则记录到日志中 + Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql'); + if (!empty($explain)) { + Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql'); + } + } + } + + /** + * 初始化数据库连接 + * @access protected + * @param boolean $master 是否主服务器 + * @return void + */ + protected function initConnect($master = true) + { + if (!empty($this->config['deploy'])) { + // 采用分布式数据库 + if ($master || $this->transTimes) { + if (!$this->linkWrite) { + $this->linkWrite = $this->multiConnect(true); + } + $this->linkID = $this->linkWrite; + } else { + if (!$this->linkRead) { + $this->linkRead = $this->multiConnect(false); + } + $this->linkID = $this->linkRead; + } + } elseif (!$this->linkID) { + // 默认单数据库 + $this->linkID = $this->connect(); + } + } + + /** + * 连接分布式服务器 + * @access protected + * @param boolean $master 主服务器 + * @return PDO + */ + protected function multiConnect($master = false) + { + $_config = []; + // 分布式数据库配置解析 + foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { + $_config[$name] = explode(',', $this->config[$name]); + } + + // 主服务器序号 + $m = floor(mt_rand(0, $this->config['master_num'] - 1)); + + if ($this->config['rw_separate']) { + // 主从式采用读写分离 + if ($master) // 主服务器写入 + { + $r = $m; + } elseif (is_numeric($this->config['slave_no'])) { + // 指定服务器读 + $r = $this->config['slave_no']; + } else { + // 读操作连接从服务器 每次随机连接的数据库 + $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1)); + } + } else { + // 读写操作不区分服务器 每次随机连接的数据库 + $r = floor(mt_rand(0, count($_config['hostname']) - 1)); + } + $dbMaster = false; + if ($m != $r) { + $dbMaster = []; + foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { + $dbMaster[$name] = isset($_config[$name][$m]) ? $_config[$name][$m] : $_config[$name][0]; + } + } + $dbConfig = []; + foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) { + $dbConfig[$name] = isset($_config[$name][$r]) ? $_config[$name][$r] : $_config[$name][0]; + } + return $this->connect($dbConfig, $r, $r == $m ? false : $dbMaster); + } + + /** + * 析构方法 + * @access public + */ + public function __destruct() + { + // 释放查询 + if ($this->PDOStatement) { + $this->free(); + } + // 关闭连接 + $this->close(); + } +} diff --git a/thinkphp/library/think/db/Query.php b/thinkphp/library/think/db/Query.php new file mode 100755 index 0000000..6d4041f --- /dev/null +++ b/thinkphp/library/think/db/Query.php @@ -0,0 +1,2898 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db; + +use PDO; +use think\App; +use think\Cache; +use think\Collection; +use think\Config; +use think\Db; +use think\db\exception\BindParamException; +use think\db\exception\DataNotFoundException; +use think\db\exception\ModelNotFoundException; +use think\Exception; +use think\exception\DbException; +use think\exception\PDOException; +use think\Loader; +use think\Model; +use think\model\Relation; +use think\model\relation\OneToOne; +use think\Paginator; + +class Query +{ + // 数据库Connection对象实例 + protected $connection; + // 数据库Builder对象实例 + protected $builder; + // 当前模型类名称 + protected $model; + // 当前数据表名称(含前缀) + protected $table = ''; + // 当前数据表名称(不含前缀) + protected $name = ''; + // 当前数据表主键 + protected $pk; + // 当前数据表前缀 + protected $prefix = ''; + // 查询参数 + protected $options = []; + // 参数绑定 + protected $bind = []; + // 数据表信息 + protected static $info = []; + // 回调事件 + private static $event = []; + + /** + * 构造函数 + * @access public + * @param Connection $connection 数据库对象实例 + * @param string $model 模型名 + */ + public function __construct(Connection $connection = null, $model = '') + { + $this->connection = $connection ?: Db::connect([], true); + $this->prefix = $this->connection->getConfig('prefix'); + $this->model = $model; + // 设置当前连接的Builder对象 + $this->setBuilder(); + } + + /** + * 利用__call方法实现一些特殊的Model方法 + * @access public + * @param string $method 方法名称 + * @param array $args 调用参数 + * @return mixed + * @throws DbException + * @throws Exception + */ + public function __call($method, $args) + { + if (strtolower(substr($method, 0, 5)) == 'getby') { + // 根据某个字段获取记录 + $field = Loader::parseName(substr($method, 5)); + $where[$field] = $args[0]; + return $this->where($where)->find(); + } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') { + // 根据某个字段获取记录的某个值 + $name = Loader::parseName(substr($method, 10)); + $where[$name] = $args[0]; + return $this->where($where)->value($args[1]); + } else { + throw new Exception('method not exist:' . __CLASS__ . '->' . $method); + } + } + + /** + * 获取当前的数据库Connection对象 + * @access public + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * 切换当前的数据库连接 + * @access public + * @param mixed $config + * @return $this + */ + public function connect($config) + { + $this->connection = Db::connect($config); + $this->setBuilder(); + $this->prefix = $this->connection->getConfig('prefix'); + return $this; + } + + /** + * 设置当前的数据库Builder对象 + * @access protected + * @return void + */ + protected function setBuilder() + { + $class = $this->connection->getBuilder(); + $this->builder = new $class($this->connection, $this); + } + + /** + * 获取当前的模型对象名 + * @access public + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * 获取当前的builder实例对象 + * @access public + * @return Builder + */ + public function getBuilder() + { + return $this->builder; + } + + /** + * 指定默认的数据表名(不含前缀) + * @access public + * @param string $name + * @return $this + */ + public function name($name) + { + $this->name = $name; + return $this; + } + + /** + * 指定默认数据表名(含前缀) + * @access public + * @param string $table 表名 + * @return $this + */ + public function setTable($table) + { + $this->table = $table; + return $this; + } + + /** + * 得到当前或者指定名称的数据表 + * @access public + * @param string $name + * @return string + */ + public function getTable($name = '') + { + if ($name || empty($this->table)) { + $name = $name ?: $this->name; + $tableName = $this->prefix; + if ($name) { + $tableName .= Loader::parseName($name); + } + } else { + $tableName = $this->table; + } + return $tableName; + } + + /** + * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名(小写) + * @access public + * @param string $sql sql语句 + * @return string + */ + public function parseSqlTable($sql) + { + if (false !== strpos($sql, '__')) { + $prefix = $this->prefix; + $sql = preg_replace_callback("/__([A-Z0-9_-]+)__/sU", function ($match) use ($prefix) { + return $prefix . strtolower($match[1]); + }, $sql); + } + return $sql; + } + + /** + * 执行查询 返回数据集 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @param boolean $master 是否在主服务器读操作 + * @param bool|string $class 指定返回的数据集对象 + * @return mixed + * @throws BindParamException + * @throws PDOException + */ + public function query($sql, $bind = [], $master = false, $class = false) + { + return $this->connection->query($sql, $bind, $master, $class); + } + + /** + * 执行语句 + * @access public + * @param string $sql sql指令 + * @param array $bind 参数绑定 + * @return int + * @throws BindParamException + * @throws PDOException + */ + public function execute($sql, $bind = []) + { + return $this->connection->execute($sql, $bind); + } + + /** + * 获取最近插入的ID + * @access public + * @param string $sequence 自增序列名 + * @return string + */ + public function getLastInsID($sequence = null) + { + return $this->connection->getLastInsID($sequence); + } + + /** + * 获取最近一次查询的sql语句 + * @access public + * @return string + */ + public function getLastSql() + { + return $this->connection->getLastSql(); + } + + /** + * 执行数据库事务 + * @access public + * @param callable $callback 数据操作方法回调 + * @return mixed + */ + public function transaction($callback) + { + return $this->connection->transaction($callback); + } + + /** + * 启动事务 + * @access public + * @return void + */ + public function startTrans() + { + $this->connection->startTrans(); + } + + /** + * 用于非自动提交状态下面的查询提交 + * @access public + * @return void + * @throws PDOException + */ + public function commit() + { + $this->connection->commit(); + } + + /** + * 事务回滚 + * @access public + * @return void + * @throws PDOException + */ + public function rollback() + { + $this->connection->rollback(); + } + + /** + * 批处理执行SQL语句 + * 批处理的指令都认为是execute操作 + * @access public + * @param array $sql SQL批处理指令 + * @return boolean + */ + public function batchQuery($sql = [], $bind = []) + { + return $this->connection->batchQuery($sql, $bind); + } + + /** + * 获取数据库的配置参数 + * @access public + * @param string $name 参数名称 + * @return boolean + */ + public function getConfig($name = '') + { + return $this->connection->getConfig($name); + } + + /** + * 得到分表的的数据表名 + * @access public + * @param array $data 操作的数据 + * @param string $field 分表依据的字段 + * @param array $rule 分表规则 + * @return string + */ + public function getPartitionTableName($data, $field, $rule = []) + { + // 对数据表进行分区 + if ($field && isset($data[$field])) { + $value = $data[$field]; + $type = $rule['type']; + switch ($type) { + case 'id': + // 按照id范围分表 + $step = $rule['expr']; + $seq = floor($value / $step) + 1; + break; + case 'year': + // 按照年份分表 + if (!is_numeric($value)) { + $value = strtotime($value); + } + $seq = date('Y', $value) - $rule['expr'] + 1; + break; + case 'mod': + // 按照id的模数分表 + $seq = ($value % $rule['num']) + 1; + break; + case 'md5': + // 按照md5的序列分表 + $seq = (ord(substr(md5($value), 0, 1)) % $rule['num']) + 1; + break; + default: + if (function_exists($type)) { + // 支持指定函数哈希 + $seq = (ord(substr($type($value), 0, 1)) % $rule['num']) + 1; + } else { + // 按照字段的首字母的值分表 + $seq = (ord($value{0}) % $rule['num']) + 1; + } + } + return $this->getTable() . '_' . $seq; + } else { + // 当设置的分表字段不在查询条件或者数据中 + // 进行联合查询,必须设定 partition['num'] + $tableName = []; + for ($i = 0; $i < $rule['num']; $i++) { + $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1); + } + + $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; + return $tableName; + } + } + + /** + * 得到某个字段的值 + * @access public + * @param string $field 字段名 + * @param mixed $default 默认值 + * @param bool $force 强制转为数字类型 + * @return mixed + */ + public function value($field, $default = null, $force = false) + { + $result = false; + if (empty($this->options['fetch_sql']) && !empty($this->options['cache'])) { + // 判断查询缓存 + $cache = $this->options['cache']; + if (empty($this->options['table'])) { + $this->options['table'] = $this->getTable(); + } + $key = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); + $result = Cache::get($key); + } + if (false === $result) { + if (isset($this->options['field'])) { + unset($this->options['field']); + } + $pdo = $this->field($field)->limit(1)->getPdo(); + if (is_string($pdo)) { + // 返回SQL语句 + return $pdo; + } + $result = $pdo->fetchColumn(); + if ($force) { + $result += 0; + } + + if (isset($cache)) { + // 缓存数据 + $this->cacheData($key, $result, $cache); + } + } else { + // 清空查询条件 + $this->options = []; + } + return false !== $result ? $result : $default; + } + + /** + * 得到某个列的数组 + * @access public + * @param string $field 字段名 多个字段用逗号分隔 + * @param string $key 索引 + * @return array + */ + public function column($field, $key = '') + { + $result = false; + if (empty($this->options['fetch_sql']) && !empty($this->options['cache'])) { + // 判断查询缓存 + $cache = $this->options['cache']; + if (empty($this->options['table'])) { + $this->options['table'] = $this->getTable(); + } + $guid = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options) . serialize($this->bind)); + $result = Cache::get($guid); + } + if (false === $result) { + if (isset($this->options['field'])) { + unset($this->options['field']); + } + if (is_null($field)) { + $field = '*'; + } elseif ($key && '*' != $field) { + $field = $key . ',' . $field; + } + $pdo = $this->field($field)->getPdo(); + if (is_string($pdo)) { + // 返回SQL语句 + return $pdo; + } + if (1 == $pdo->columnCount()) { + $result = $pdo->fetchAll(PDO::FETCH_COLUMN); + } else { + $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC); + if ($resultSet) { + $fields = array_keys($resultSet[0]); + $count = count($fields); + $key1 = array_shift($fields); + $key2 = $fields ? array_shift($fields) : ''; + $key = $key ?: $key1; + if (strpos($key, '.')) { + list($alias, $key) = explode('.', $key); + } + foreach ($resultSet as $val) { + if ($count > 2) { + $result[$val[$key]] = $val; + } elseif (2 == $count) { + $result[$val[$key]] = $val[$key2]; + } elseif (1 == $count) { + $result[$val[$key]] = $val[$key1]; + } + } + } else { + $result = []; + } + } + if (isset($cache) && isset($guid)) { + // 缓存数据 + $this->cacheData($guid, $result, $cache); + } + } else { + // 清空查询条件 + $this->options = []; + } + return $result; + } + + /** + * COUNT查询 + * @access public + * @param string $field 字段名 + * @return integer|string + */ + public function count($field = '*') + { + if (isset($this->options['group'])) { + // 支持GROUP + $options = $this->getOptions(); + $subSql = $this->options($options)->field('count(' . $field . ')')->bind($this->bind)->buildSql(); + return $this->table([$subSql => '_group_count_'])->value('COUNT(*) AS tp_count', 0, true); + } + + return $this->value('COUNT(' . $field . ') AS tp_count', 0, true); + } + + /** + * SUM查询 + * @access public + * @param string $field 字段名 + * @return float|int + */ + public function sum($field) + { + return $this->value('SUM(' . $field . ') AS tp_sum', 0, true); + } + + /** + * MIN查询 + * @access public + * @param string $field 字段名 + * @return mixed + */ + public function min($field) + { + return $this->value('MIN(' . $field . ') AS tp_min', 0, true); + } + + /** + * MAX查询 + * @access public + * @param string $field 字段名 + * @return mixed + */ + public function max($field) + { + return $this->value('MAX(' . $field . ') AS tp_max', 0, true); + } + + /** + * AVG查询 + * @access public + * @param string $field 字段名 + * @return float|int + */ + public function avg($field) + { + return $this->value('AVG(' . $field . ') AS tp_avg', 0, true); + } + + /** + * 设置记录的某个字段值 + * 支持使用数据库字段和方法 + * @access public + * @param string|array $field 字段名 + * @param mixed $value 字段值 + * @return integer + */ + public function setField($field, $value = '') + { + if (is_array($field)) { + $data = $field; + } else { + $data[$field] = $value; + } + return $this->update($data); + } + + /** + * 字段值(延迟)增长 + * @access public + * @param string $field 字段名 + * @param integer $step 增长值 + * @param integer $lazyTime 延时时间(s) + * @return integer|true + * @throws Exception + */ + public function setInc($field, $step = 1, $lazyTime = 0) + { + $condition = !empty($this->options['where']) ? $this->options['where'] : []; + if (empty($condition)) { + // 没有条件不做任何更新 + throw new Exception('no data to update'); + } + if ($lazyTime > 0) { + // 延迟写入 + $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); + $step = $this->lazyWrite('inc', $guid, $step, $lazyTime); + if (false === $step) { + // 清空查询条件 + $this->options = []; + return true; + } + } + return $this->setField($field, ['exp', $field . '+' . $step]); + } + + /** + * 字段值(延迟)减少 + * @access public + * @param string $field 字段名 + * @param integer $step 减少值 + * @param integer $lazyTime 延时时间(s) + * @return integer|true + * @throws Exception + */ + public function setDec($field, $step = 1, $lazyTime = 0) + { + $condition = !empty($this->options['where']) ? $this->options['where'] : []; + if (empty($condition)) { + // 没有条件不做任何更新 + throw new Exception('no data to update'); + } + if ($lazyTime > 0) { + // 延迟写入 + $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition) . serialize($this->bind)); + $step = $this->lazyWrite('dec', $guid, $step, $lazyTime); + if (false === $step) { + // 清空查询条件 + $this->options = []; + return true; + } + } + return $this->setField($field, ['exp', $field . '-' . $step]); + } + + /** + * 延时更新检查 返回false表示需要延时 + * 否则返回实际写入的数值 + * @access protected + * @param string $type 自增或者自减 + * @param string $guid 写入标识 + * @param integer $step 写入步进值 + * @param integer $lazyTime 延时时间(s) + * @return false|integer + */ + protected function lazyWrite($type, $guid, $step, $lazyTime) + { + if (!Cache::has($guid . '_time')) { + // 计时开始 + Cache::set($guid . '_time', $_SERVER['REQUEST_TIME'], 0); + Cache::$type($guid, $step); + } elseif ($_SERVER['REQUEST_TIME'] > Cache::get($guid . '_time') + $lazyTime) { + // 删除缓存 + $value = Cache::$type($guid, $step); + Cache::rm($guid); + Cache::rm($guid . '_time'); + return 0 === $value ? false : $value; + } else { + // 更新缓存 + Cache::$type($guid, $step); + } + return false; + } + + /** + * 查询SQL组装 join + * @access public + * @param mixed $join 关联的表名 + * @param mixed $condition 条件 + * @param string $type JOIN类型 + * @return $this + */ + public function join($join, $condition = null, $type = 'INNER') + { + if (empty($condition)) { + // 如果为组数,则循环调用join + foreach ($join as $key => $value) { + if (is_array($value) && 2 <= count($value)) { + $this->join($value[0], $value[1], isset($value[2]) ? $value[2] : $type); + } + } + } else { + $table = $this->getJoinTable($join); + + $this->options['join'][] = [$table, strtoupper($type), $condition]; + } + return $this; + } + + /** + * 获取Join表名及别名 支持 + * ['prefix_table或者子查询'=>'alias'] 'prefix_table alias' 'table alias' + * @access public + * @param array|string $join + * @return array|string + */ + protected function getJoinTable($join, &$alias = null) + { + // 传入的表名为数组 + if (is_array($join)) { + list($table, $alias) = each($join); + } else { + $join = trim($join); + if (false !== strpos($join, '(')) { + // 使用子查询 + $table = $join; + } else { + $prefix = $this->prefix; + if (strpos($join, ' ')) { + // 使用别名 + list($table, $alias) = explode(' ', $join); + } else { + $table = $join; + if (false === strpos($join, '.') && 0 !== strpos($join, '__')) { + $alias = $join; + } + } + if ($prefix && false === strpos($table, '.') && 0 !== strpos($table, $prefix) && 0 !== strpos($table, '__')) { + $table = $this->getTable($table); + } + } + } + if (isset($alias)) { + if (isset($this->options['alias'][$table])) { + $table = $table . '@think' . uniqid(); + } + $table = [$table => $alias]; + $this->alias($table); + } + return $table; + } + + /** + * 查询SQL组装 union + * @access public + * @param mixed $union + * @param boolean $all + * @return $this + */ + public function union($union, $all = false) + { + $this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION'; + + if (is_array($union)) { + $this->options['union'] = array_merge($this->options['union'], $union); + } else { + $this->options['union'][] = $union; + } + return $this; + } + + /** + * 指定查询字段 支持字段排除和指定数据表 + * @access public + * @param mixed $field + * @param boolean $except 是否排除 + * @param string $tableName 数据表名 + * @param string $prefix 字段前缀 + * @param string $alias 别名前缀 + * @return $this + */ + public function field($field, $except = false, $tableName = '', $prefix = '', $alias = '') + { + if (empty($field)) { + return $this; + } + if (is_string($field)) { + $field = array_map('trim', explode(',', $field)); + } + if (true === $field) { + // 获取全部字段 + $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields'); + $field = $fields ?: ['*']; + } elseif ($except) { + // 字段排除 + $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields'); + $field = $fields ? array_diff($fields, $field) : $field; + } + if ($tableName) { + // 添加统一的前缀 + $prefix = $prefix ?: $tableName; + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $val = $prefix . '.' . $val . ($alias ? ' AS ' . $alias . $val : ''); + } + $field[$key] = $val; + } + } + + if (isset($this->options['field'])) { + $field = array_merge($this->options['field'], $field); + } + $this->options['field'] = array_unique($field); + return $this; + } + + /** + * 设置数据 + * @access public + * @param mixed $field 字段名或者数据 + * @param mixed $value 字段值 + * @return $this + */ + public function data($field, $value = null) + { + if (is_array($field)) { + $this->options['data'] = isset($this->options['data']) ? array_merge($this->options['data'], $field) : $field; + } else { + $this->options['data'][$field] = $value; + } + return $this; + } + + /** + * 字段值增长 + * @access public + * @param string|array $field 字段名 + * @param integer $step 增长值 + * @return $this + */ + public function inc($field, $step = 1) + { + $fields = is_string($field) ? explode(',', $field) : $field; + foreach ($fields as $field) { + $this->data($field, ['exp', $field . '+' . $step]); + } + return $this; + } + + /** + * 字段值减少 + * @access public + * @param string|array $field 字段名 + * @param integer $step 增长值 + * @return $this + */ + public function dec($field, $step = 1) + { + $fields = is_string($field) ? explode(',', $field) : $field; + foreach ($fields as $field) { + $this->data($field, ['exp', $field . '-' . $step]); + } + return $this; + } + + /** + * 使用表达式设置数据 + * @access public + * @param string $field 字段名 + * @param string $value 字段值 + * @return $this + */ + public function exp($field, $value) + { + $this->data($field, ['exp', $value]); + return $this; + } + + /** + * 指定JOIN查询字段 + * @access public + * @param string|array $table 数据表 + * @param string|array $field 查询字段 + * @param string|array $on JOIN条件 + * @param string $type JOIN类型 + * @return $this + */ + public function view($join, $field = true, $on = null, $type = 'INNER') + { + $this->options['view'] = true; + if (is_array($join) && key($join) !== 0) { + foreach ($join as $key => $val) { + $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER'); + } + } else { + $fields = []; + $table = $this->getJoinTable($join, $alias); + + if (true === $field) { + $fields = $alias . '.*'; + } else { + if (is_string($field)) { + $field = explode(',', $field); + } + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $fields[] = $alias . '.' . $val; + $this->options['map'][$val] = $alias . '.' . $val; + } else { + if (preg_match('/[,=\.\'\"\(\s]/', $key)) { + $name = $key; + } else { + $name = $alias . '.' . $key; + } + $fields[$name] = $val; + $this->options['map'][$val] = $name; + } + } + } + $this->field($fields); + if ($on) { + $this->join($table, $on, $type); + } else { + $this->table($table); + } + } + return $this; + } + + /** + * 设置分表规则 + * @access public + * @param array $data 操作的数据 + * @param string $field 分表依据的字段 + * @param array $rule 分表规则 + * @return $this + */ + public function partition($data, $field, $rule = []) + { + $this->options['table'] = $this->getPartitionTableName($data, $field, $rule); + return $this; + } + + /** + * 指定AND查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $op 查询表达式 + * @param mixed $condition 查询条件 + * @return $this + */ + public function where($field, $op = null, $condition = null) + { + $param = func_get_args(); + array_shift($param); + $this->parseWhereExp('AND', $field, $op, $condition, $param); + return $this; + } + + /** + * 指定OR查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $op 查询表达式 + * @param mixed $condition 查询条件 + * @return $this + */ + public function whereOr($field, $op = null, $condition = null) + { + $param = func_get_args(); + array_shift($param); + $this->parseWhereExp('OR', $field, $op, $condition, $param); + return $this; + } + + /** + * 指定XOR查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $op 查询表达式 + * @param mixed $condition 查询条件 + * @return $this + */ + public function whereXor($field, $op = null, $condition = null) + { + $param = func_get_args(); + array_shift($param); + $this->parseWhereExp('XOR', $field, $op, $condition, $param); + return $this; + } + + /** + * 指定Null查询条件 + * @access public + * @param mixed $field 查询字段 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNull($field, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'null', null); + return $this; + } + + /** + * 指定NotNull查询条件 + * @access public + * @param mixed $field 查询字段 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNotNull($field, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'notnull', null); + return $this; + } + + /** + * 指定Exists查询条件 + * @access public + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereExists($condition, $logic = 'AND') + { + $this->options['where'][strtoupper($logic)][] = ['exists', $condition]; + return $this; + } + + /** + * 指定NotExists查询条件 + * @access public + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNotExists($condition, $logic = 'AND') + { + $this->options['where'][strtoupper($logic)][] = ['not exists', $condition]; + return $this; + } + + /** + * 指定In查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereIn($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'in', $condition); + return $this; + } + + /** + * 指定NotIn查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNotIn($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'not in', $condition); + return $this; + } + + /** + * 指定Like查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereLike($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'like', $condition); + return $this; + } + + /** + * 指定NotLike查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNotLike($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'not like', $condition); + return $this; + } + + /** + * 指定Between查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereBetween($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'between', $condition); + return $this; + } + + /** + * 指定NotBetween查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereNotBetween($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'not between', $condition); + return $this; + } + + /** + * 指定Exp查询条件 + * @access public + * @param mixed $field 查询字段 + * @param mixed $condition 查询条件 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function whereExp($field, $condition, $logic = 'AND') + { + $this->parseWhereExp($logic, $field, 'exp', $condition); + return $this; + } + + /** + * 设置软删除字段及条件 + * @access public + * @param false|string $field 查询字段 + * @param mixed $condition 查询条件 + * @return $this + */ + public function useSoftDelete($field, $condition = null) + { + if ($field) { + $this->options['soft_delete'] = [$field, $condition ?: ['null', '']]; + } + return $this; + } + + /** + * 分析查询表达式 + * @access public + * @param string $logic 查询逻辑 and or xor + * @param string|array|\Closure $field 查询字段 + * @param mixed $op 查询表达式 + * @param mixed $condition 查询条件 + * @param array $param 查询参数 + * @return void + */ + protected function parseWhereExp($logic, $field, $op, $condition, $param = []) + { + $logic = strtoupper($logic); + if ($field instanceof \Closure) { + $this->options['where'][$logic][] = is_string($op) ? [$op, $field] : $field; + return; + } + + if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) { + $field = $this->options['via'] . '.' . $field; + } + if (is_string($field) && preg_match('/[,=\>\<\'\"\(\s]/', $field)) { + $where[] = ['exp', $field]; + if (is_array($op)) { + // 参数绑定 + $this->bind($op); + } + } elseif (is_null($op) && is_null($condition)) { + if (is_array($field)) { + // 数组批量查询 + $where = $field; + foreach ($where as $k => $val) { + $this->options['multi'][$logic][$k][] = $val; + } + } elseif ($field && is_string($field)) { + // 字符串查询 + $where[$field] = ['null', '']; + $this->options['multi'][$logic][$field][] = $where[$field]; + } + } elseif (is_array($op)) { + $where[$field] = $param; + } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) { + // null查询 + $where[$field] = [$op, '']; + $this->options['multi'][$logic][$field][] = $where[$field]; + } elseif (is_null($condition)) { + // 字段相等查询 + $where[$field] = ['eq', $op]; + $this->options['multi'][$logic][$field][] = $where[$field]; + } else { + $where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null]; + if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) { + // 参数绑定 + $this->bind($param[2]); + } + // 记录一个字段多次查询条件 + $this->options['multi'][$logic][$field][] = $where[$field]; + } + if (!empty($where)) { + if (!isset($this->options['where'][$logic])) { + $this->options['where'][$logic] = []; + } + if (is_string($field) && $this->checkMultiField($field, $logic)) { + $where[$field] = $this->options['multi'][$logic][$field]; + } elseif (is_array($field)) { + foreach ($field as $key => $val) { + if ($this->checkMultiField($key, $logic)) { + $where[$key] = $this->options['multi'][$logic][$key]; + } + } + } + $this->options['where'][$logic] = array_merge($this->options['where'][$logic], $where); + } + } + + /** + * 检查是否存在一个字段多次查询条件 + * @access public + * @param string $field 查询字段 + * @param string $logic 查询逻辑 and or xor + * @return bool + */ + private function checkMultiField($field, $logic) + { + return isset($this->options['multi'][$logic][$field]) && count($this->options['multi'][$logic][$field]) > 1; + } + + /** + * 去除某个查询条件 + * @access public + * @param string $field 查询字段 + * @param string $logic 查询逻辑 and or xor + * @return $this + */ + public function removeWhereField($field, $logic = 'AND') + { + $logic = strtoupper($logic); + if (isset($this->options['where'][$logic][$field])) { + unset($this->options['where'][$logic][$field]); + } + return $this; + } + + /** + * 去除查询参数 + * @access public + * @param string|bool $option 参数名 true 表示去除所有参数 + * @return $this + */ + public function removeOption($option = true) + { + if (true === $option) { + $this->options = []; + } elseif (is_string($option) && isset($this->options[$option])) { + unset($this->options[$option]); + } + return $this; + } + + /** + * 指定查询数量 + * @access public + * @param mixed $offset 起始位置 + * @param mixed $length 查询数量 + * @return $this + */ + public function limit($offset, $length = null) + { + if (is_null($length) && strpos($offset, ',')) { + list($offset, $length) = explode(',', $offset); + } + $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : ''); + return $this; + } + + /** + * 指定分页 + * @access public + * @param mixed $page 页数 + * @param mixed $listRows 每页数量 + * @return $this + */ + public function page($page, $listRows = null) + { + if (is_null($listRows) && strpos($page, ',')) { + list($page, $listRows) = explode(',', $page); + } + $this->options['page'] = [intval($page), intval($listRows)]; + return $this; + } + + /** + * 分页查询 + * @param int|array $listRows 每页数量 数组表示配置参数 + * @param int|bool $simple 是否简洁模式或者总记录数 + * @param array $config 配置参数 + * page:当前页, + * path:url路径, + * query:url额外参数, + * fragment:url锚点, + * var_page:分页变量, + * list_rows:每页数量 + * type:分页类名 + * @return \think\Paginator + * @throws DbException + */ + public function paginate($listRows = null, $simple = false, $config = []) + { + if (is_int($simple)) { + $total = $simple; + $simple = false; + } + if (is_array($listRows)) { + $config = array_merge(Config::get('paginate'), $listRows); + $listRows = $config['list_rows']; + } else { + $config = array_merge(Config::get('paginate'), $config); + $listRows = $listRows ?: $config['list_rows']; + } + + /** @var Paginator $class */ + $class = false !== strpos($config['type'], '\\') ? $config['type'] : '\\think\\paginator\\driver\\' . ucwords($config['type']); + $page = isset($config['page']) ? (int) $config['page'] : call_user_func([ + $class, + 'getCurrentPage', + ], $config['var_page']); + + $page = $page < 1 ? 1 : $page; + + $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']); + + if (!isset($total) && !$simple) { + $options = $this->getOptions(); + + unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']); + + $bind = $this->bind; + $total = $this->count(); + $results = $this->options($options)->bind($bind)->page($page, $listRows)->select(); + } elseif ($simple) { + $results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select(); + $total = null; + } else { + $results = $this->page($page, $listRows)->select(); + } + return $class::make($results, $listRows, $page, $total, $simple, $config); + } + + /** + * 指定当前操作的数据表 + * @access public + * @param mixed $table 表名 + * @return $this + */ + public function table($table) + { + if (is_string($table)) { + if (strpos($table, ')')) { + // 子查询 + } elseif (strpos($table, ',')) { + $tables = explode(',', $table); + $table = []; + foreach ($tables as $item) { + list($item, $alias) = explode(' ', trim($item)); + if ($alias) { + $this->alias([$item => $alias]); + $table[$item] = $alias; + } else { + $table[] = $item; + } + } + } elseif (strpos($table, ' ')) { + list($table, $alias) = explode(' ', $table); + + $table = [$table => $alias]; + $this->alias($table); + } + } else { + $tables = $table; + $table = []; + foreach ($tables as $key => $val) { + if (is_numeric($key)) { + $table[] = $val; + } else { + $this->alias([$key => $val]); + $table[$key] = $val; + } + } + } + $this->options['table'] = $table; + return $this; + } + + /** + * USING支持 用于多表删除 + * @access public + * @param mixed $using + * @return $this + */ + public function using($using) + { + $this->options['using'] = $using; + return $this; + } + + /** + * 指定排序 order('id','desc') 或者 order(['id'=>'desc','create_time'=>'desc']) + * @access public + * @param string|array $field 排序字段 + * @param string $order 排序 + * @return $this + */ + public function order($field, $order = null) + { + if (!empty($field)) { + if (is_string($field)) { + if (!empty($this->options['via'])) { + $field = $this->options['via'] . '.' . $field; + } + $field = empty($order) ? $field : [$field => $order]; + } elseif (!empty($this->options['via'])) { + foreach ($field as $key => $val) { + if (is_numeric($key)) { + $field[$key] = $this->options['via'] . '.' . $val; + } else { + $field[$this->options['via'] . '.' . $key] = $val; + unset($field[$key]); + } + } + } + if (!isset($this->options['order'])) { + $this->options['order'] = []; + } + if (is_array($field)) { + $this->options['order'] = array_merge($this->options['order'], $field); + } else { + $this->options['order'][] = $field; + } + } + return $this; + } + + /** + * 查询缓存 + * @access public + * @param mixed $key 缓存key + * @param integer|\DateTime $expire 缓存有效期 + * @param string $tag 缓存标签 + * @return $this + */ + public function cache($key = true, $expire = null, $tag = null) + { + // 增加快捷调用方式 cache(10) 等同于 cache(true, 10) + if ($key instanceof \DateTime || (is_numeric($key) && is_null($expire))) { + $expire = $key; + $key = true; + } + + if (false !== $key) { + $this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag]; + } + return $this; + } + + /** + * 指定group查询 + * @access public + * @param string $group GROUP + * @return $this + */ + public function group($group) + { + $this->options['group'] = $group; + return $this; + } + + /** + * 指定having查询 + * @access public + * @param string $having having + * @return $this + */ + public function having($having) + { + $this->options['having'] = $having; + return $this; + } + + /** + * 指定查询lock + * @access public + * @param bool|string $lock 是否lock + * @return $this + */ + public function lock($lock = false) + { + $this->options['lock'] = $lock; + $this->options['master'] = true; + return $this; + } + + /** + * 指定distinct查询 + * @access public + * @param string $distinct 是否唯一 + * @return $this + */ + public function distinct($distinct) + { + $this->options['distinct'] = $distinct; + return $this; + } + + /** + * 指定数据表别名 + * modify by GZShangTao + * @access public + * @param mixed $alias 数据表别名 + * @return $this + */ + public function alias($alias) + { + if (is_array($alias)) { + foreach ($alias as $key => $val) { + /* + * 被注释的部分是thinkhphp5.0.12原始代码。 + if (false !== strpos($key, '__')) { + $table = $this->parseSqlTable($key); + } else { + $table = $key; + } + $this->options['alias'][$table] = $val; + */ + $this->options['alias'][$key] = $val;//这段是修改后的代码 + } + } else { + if (isset($this->options['table'])) { + $table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table']; + if (false !== strpos($table, '__')) { + $table = $this->parseSqlTable($table); + } + } else { + $table = $this->getTable(); + } + + $this->options['alias'][$table] = $alias; + } + return $this; + } + + /** + * 指定强制索引 + * @access public + * @param string $force 索引名称 + * @return $this + */ + public function force($force) + { + $this->options['force'] = $force; + return $this; + } + + /** + * 查询注释 + * @access public + * @param string $comment 注释 + * @return $this + */ + public function comment($comment) + { + $this->options['comment'] = $comment; + return $this; + } + + /** + * 获取执行的SQL语句 + * @access public + * @param boolean $fetch 是否返回sql + * @return $this + */ + public function fetchSql($fetch = true) + { + $this->options['fetch_sql'] = $fetch; + return $this; + } + + /** + * 不主动获取数据集 + * @access public + * @param bool $pdo 是否返回 PDOStatement 对象 + * @return $this + */ + public function fetchPdo($pdo = true) + { + $this->options['fetch_pdo'] = $pdo; + return $this; + } + + /** + * 设置从主服务器读取数据 + * @access public + * @return $this + */ + public function master() + { + $this->options['master'] = true; + return $this; + } + + /** + * 设置是否严格检查字段名 + * @access public + * @param bool $strict 是否严格检查字段 + * @return $this + */ + public function strict($strict = true) + { + $this->options['strict'] = $strict; + return $this; + } + + /** + * 设置查询数据不存在是否抛出异常 + * @access public + * @param bool $fail 数据不存在是否抛出异常 + * @return $this + */ + public function failException($fail = true) + { + $this->options['fail'] = $fail; + return $this; + } + + /** + * 设置自增序列名 + * @access public + * @param string $sequence 自增序列名 + * @return $this + */ + public function sequence($sequence = null) + { + $this->options['sequence'] = $sequence; + return $this; + } + + /** + * 指定数据表主键 + * @access public + * @param string $pk 主键 + * @return $this + */ + public function pk($pk) + { + $this->pk = $pk; + return $this; + } + + /** + * 查询日期或者时间 + * @access public + * @param string $field 日期字段名 + * @param string|array $op 比较运算符或者表达式 + * @param string|array $range 比较范围 + * @return $this + */ + public function whereTime($field, $op, $range = null) + { + if (is_null($range)) { + if (is_array($op)) { + $range = $op; + } else { + // 使用日期表达式 + switch (strtolower($op)) { + case 'today': + case 'd': + $range = ['today', 'tomorrow']; + break; + case 'week': + case 'w': + $range = ['this week 00:00:00', 'next week 00:00:00']; + break; + case 'month': + case 'm': + $range = ['first Day of this month 00:00:00', 'first Day of next month 00:00:00']; + break; + case 'year': + case 'y': + $range = ['this year 1/1', 'next year 1/1']; + break; + case 'yesterday': + $range = ['yesterday', 'today']; + break; + case 'last week': + $range = ['last week 00:00:00', 'this week 00:00:00']; + break; + case 'last month': + $range = ['first Day of last month 00:00:00', 'first Day of this month 00:00:00']; + break; + case 'last year': + $range = ['last year 1/1', 'this year 1/1']; + break; + default: + $range = $op; + } + } + $op = is_array($range) ? 'between' : '>'; + } + $this->where($field, strtolower($op) . ' time', $range); + return $this; + } + + /** + * 获取数据表信息 + * @access public + * @param mixed $tableName 数据表名 留空自动获取 + * @param string $fetch 获取信息类型 包括 fields type bind pk + * @return mixed + */ + public function getTableInfo($tableName = '', $fetch = '') + { + if (!$tableName) { + $tableName = $this->getTable(); + } + if (is_array($tableName)) { + $tableName = key($tableName) ?: current($tableName); + } + + if (strpos($tableName, ',')) { + // 多表不获取字段信息 + return false; + } else { + $tableName = $this->parseSqlTable($tableName); + } + + // 修正子查询作为表名的问题 + if (strpos($tableName, ')')) { + return []; + } + + list($guid) = explode(' ', $tableName); + $db = $this->getConfig('database'); + if (!isset(self::$info[$db . '.' . $guid])) { + if (!strpos($guid, '.')) { + $schema = $db . '.' . $guid; + } else { + $schema = $guid; + } + // 读取缓存 + if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) { + $info = include RUNTIME_PATH . 'schema/' . $schema . '.php'; + } else { + $info = $this->connection->getFields($guid); + } + $fields = array_keys($info); + $bind = $type = []; + foreach ($info as $key => $val) { + // 记录字段类型 + $type[$key] = $val['type']; + $bind[$key] = $this->getFieldBindType($val['type']); + if (!empty($val['primary'])) { + $pk[] = $key; + } + } + if (isset($pk)) { + // 设置主键 + $pk = count($pk) > 1 ? $pk : $pk[0]; + } else { + $pk = null; + } + self::$info[$db . '.' . $guid] = ['fields' => $fields, 'type' => $type, 'bind' => $bind, 'pk' => $pk]; + } + return $fetch ? self::$info[$db . '.' . $guid][$fetch] : self::$info[$db . '.' . $guid]; + } + + /** + * 获取当前数据表的主键 + * @access public + * @param string|array $options 数据表名或者查询参数 + * @return string|array + */ + public function getPk($options = '') + { + if (!empty($this->pk)) { + $pk = $this->pk; + } else { + $pk = $this->getTableInfo(is_array($options) ? $options['table'] : $options, 'pk'); + } + return $pk; + } + + // 获取当前数据表字段信息 + public function getTableFields($table = '') + { + return $this->getTableInfo($table ?: $this->getOptions('table'), 'fields'); + } + + // 获取当前数据表字段类型 + public function getFieldsType($table = '') + { + return $this->getTableInfo($table ?: $this->getOptions('table'), 'type'); + } + + // 获取当前数据表绑定信息 + public function getFieldsBind($table = '') + { + $types = $this->getFieldsType($table); + $bind = []; + if ($types) { + foreach ($types as $key => $type) { + $bind[$key] = $this->getFieldBindType($type); + } + } + return $bind; + } + + /** + * 获取字段绑定类型 + * @access public + * @param string $type 字段类型 + * @return integer + */ + protected function getFieldBindType($type) + { + if (0 === strpos($type, 'set') || 0 === strpos($type, 'enum')) { + $bind = PDO::PARAM_STR; + } elseif (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) { + $bind = PDO::PARAM_INT; + } elseif (preg_match('/bool/is', $type)) { + $bind = PDO::PARAM_BOOL; + } else { + $bind = PDO::PARAM_STR; + } + return $bind; + } + + /** + * 参数绑定 + * @access public + * @param mixed $key 参数名 + * @param mixed $value 绑定变量值 + * @param integer $type 绑定类型 + * @return $this + */ + public function bind($key, $value = false, $type = PDO::PARAM_STR) + { + if (is_array($key)) { + $this->bind = array_merge($this->bind, $key); + } else { + $this->bind[$key] = [$value, $type]; + } + return $this; + } + + /** + * 检测参数是否已经绑定 + * @access public + * @param string $key 参数名 + * @return bool + */ + public function isBind($key) + { + return isset($this->bind[$key]); + } + + /** + * 查询参数赋值 + * @access protected + * @param array $options 表达式参数 + * @return $this + */ + protected function options(array $options) + { + $this->options = $options; + return $this; + } + + /** + * 获取当前的查询参数 + * @access public + * @param string $name 参数名 + * @return mixed + */ + public function getOptions($name = '') + { + if ('' === $name) { + return $this->options; + } else { + return isset($this->options[$name]) ? $this->options[$name] : null; + } + } + + /** + * 设置关联查询JOIN预查询 + * @access public + * @param string|array $with 关联方法名称 + * @return $this + */ + public function with($with) + { + if (empty($with)) { + return $this; + } + + if (is_string($with)) { + $with = explode(',', $with); + } + + $first = true; + $currentModel = $this->model; + + /** @var Model $class */ + $class = new $currentModel; + foreach ($with as $key => $relation) { + $subRelation = ''; + $closure = false; + if ($relation instanceof \Closure) { + // 支持闭包查询过滤关联条件 + $closure = $relation; + $relation = $key; + $with[$key] = $key; + } elseif (is_array($relation)) { + $subRelation = $relation; + $relation = $key; + } elseif (is_string($relation) && strpos($relation, '.')) { + $with[$key] = $relation; + list($relation, $subRelation) = explode('.', $relation, 2); + } + + /** @var Relation $model */ + $relation = Loader::parseName($relation, 1, false); + $model = $class->$relation(); + if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) { + $model->eagerly($this, $relation, $subRelation, $closure, $first); + $first = false; + } elseif ($closure) { + $with[$key] = $closure; + } + } + $this->via(); + if (isset($this->options['with'])) { + $this->options['with'] = array_merge($this->options['with'], $with); + } else { + $this->options['with'] = $with; + } + return $this; + } + + /** + * 关联统计 + * @access public + * @param string|array $relation 关联方法名 + * @param bool $subQuery 是否使用子查询 + * @return $this + */ + public function withCount($relation, $subQuery = true) + { + if (!$subQuery) { + $this->options['with_count'] = $relation; + } else { + $relations = is_string($relation) ? explode(',', $relation) : $relation; + if (!isset($this->options['field'])) { + $this->field('*'); + } + foreach ($relations as $key => $relation) { + $closure = false; + if ($relation instanceof \Closure) { + $closure = $relation; + $relation = $key; + } + $relation = Loader::parseName($relation, 1, false); + $count = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')'; + $this->field([$count => Loader::parseName($relation) . '_count']); + } + } + return $this; + } + + /** + * 关联预加载中 获取关联指定字段值 + * example: + * Model::with(['relation' => function($query){ + * $query->withField("id,name"); + * }]) + * + * @param string | array $field 指定获取的字段 + * @return $this + */ + public function withField($field) + { + $this->options['with_field'] = $field; + return $this; + } + + /** + * 设置当前字段添加的表别名 + * @access public + * @param string $via + * @return $this + */ + public function via($via = '') + { + $this->options['via'] = $via; + return $this; + } + + /** + * 设置关联查询 + * @access public + * @param string|array $relation 关联名称 + * @return $this + */ + public function relation($relation) + { + if (empty($relation)) { + return $this; + } + if (is_string($relation)) { + $relation = explode(',', $relation); + } + if (isset($this->options['relation'])) { + $this->options['relation'] = array_merge($this->options['relation'], $relation); + } else { + $this->options['relation'] = $relation; + } + return $this; + } + + /** + * 把主键值转换为查询条件 支持复合主键 + * @access public + * @param array|string $data 主键数据 + * @param mixed $options 表达式参数 + * @return void + * @throws Exception + */ + protected function parsePkWhere($data, &$options) + { + $pk = $this->getPk($options); + // 获取当前数据表 + $table = is_array($options['table']) ? key($options['table']) : $options['table']; + if (!empty($options['alias'][$table])) { + $alias = $options['alias'][$table]; + } + if (is_string($pk)) { + $key = isset($alias) ? $alias . '.' . $pk : $pk; + // 根据主键查询 + if (is_array($data)) { + $where[$key] = isset($data[$pk]) ? $data[$pk] : ['in', $data]; + } else { + $where[$key] = strpos($data, ',') ? ['IN', $data] : $data; + } + } elseif (is_array($pk) && is_array($data) && !empty($data)) { + // 根据复合主键查询 + foreach ($pk as $key) { + if (isset($data[$key])) { + $attr = isset($alias) ? $alias . '.' . $key : $key; + $where[$attr] = $data[$key]; + } else { + throw new Exception('miss complex primary data'); + } + } + } + + if (!empty($where)) { + if (isset($options['where']['AND'])) { + $options['where']['AND'] = array_merge($options['where']['AND'], $where); + } else { + $options['where']['AND'] = $where; + } + } + return; + } + + /** + * 插入记录 + * @access public + * @param mixed $data 数据 + * @param boolean $replace 是否replace + * @param boolean $getLastInsID 返回自增主键 + * @param string $sequence 自增序列名 + * @return integer|string + */ + public function insert(array $data = [], $replace = false, $getLastInsID = false, $sequence = null) + { + // 分析查询表达式 + $options = $this->parseExpress(); + $data = array_merge($options['data'], $data); + // 生成SQL语句 + $sql = $this->builder->insert($data, $options, $replace); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } + + // 执行操作 + $result = 0 === $sql ? 0 : $this->execute($sql, $bind); + if ($result) { + $sequence = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null); + $lastInsId = $this->getLastInsID($sequence); + if ($lastInsId) { + $pk = $this->getPk($options); + if (is_string($pk)) { + $data[$pk] = $lastInsId; + } + } + $options['data'] = $data; + $this->trigger('after_insert', $options); + + if ($getLastInsID) { + return $lastInsId; + } + } + return $result; + } + + /** + * 插入记录并获取自增ID + * @access public + * @param mixed $data 数据 + * @param boolean $replace 是否replace + * @param string $sequence 自增序列名 + * @return integer|string + */ + public function insertGetId(array $data, $replace = false, $sequence = null) + { + return $this->insert($data, $replace, true, $sequence); + } + + /** + * 批量插入记录 + * @access public + * @param mixed $dataSet 数据集 + * @param boolean $replace 是否replace + * @param integer $limit 每次写入数据限制 + * @return integer|string + */ + public function insertAll(array $dataSet, $replace = false, $limit = null) + { + // 分析查询表达式 + $options = $this->parseExpress(); + if (!is_array(reset($dataSet))) { + return false; + } + + // 生成SQL语句 + if (is_null($limit)) { + $sql = $this->builder->insertAll($dataSet, $options, $replace); + } else { + $array = array_chunk($dataSet, $limit, true); + foreach ($array as $item) { + $sql[] = $this->builder->insertAll($item, $options, $replace); + } + } + + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } elseif (is_array($sql)) { + // 执行操作 + return $this->batchQuery($sql, $bind); + } else { + // 执行操作 + return $this->execute($sql, $bind); + } + } + + /** + * 通过Select方式插入记录 + * @access public + * @param string $fields 要插入的数据表字段名 + * @param string $table 要插入的数据表名 + * @return integer|string + * @throws PDOException + */ + public function selectInsert($fields, $table) + { + // 分析查询表达式 + $options = $this->parseExpress(); + // 生成SQL语句 + $table = $this->parseSqlTable($table); + $sql = $this->builder->selectInsert($fields, $table, $options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } else { + // 执行操作 + return $this->execute($sql, $bind); + } + } + + /** + * 更新记录 + * @access public + * @param mixed $data 数据 + * @return integer|string + * @throws Exception + * @throws PDOException + */ + public function update(array $data = []) + { + $options = $this->parseExpress(); + $data = array_merge($options['data'], $data); + $pk = $this->getPk($options); + $fv = $this->findWVersion(); + if (isset($options['cache']) && is_string($options['cache']['key'])) { + $key = $options['cache']['key']; + } + + if (empty($options['where'])) { + // 如果存在主键数据 则自动作为更新条件 + if (is_string($pk) && isset($data[$pk])) { + $where[$pk] = $data[$pk]; + if (!isset($key)) { + $key = 'think:' . $options['table'] . '|' . $data[$pk]; + } + unset($data[$pk]); + } elseif (is_array($pk)) { + // 增加复合主键支持 + foreach ($pk as $field) { + if (isset($data[$field])) { + $where[$field] = $data[$field]; + } else { + // 如果缺少复合主键数据则不执行 + throw new Exception('miss complex primary data'); + } + unset($data[$field]); + } + } + if (!isset($where)) { + // 如果没有任何更新条件则不执行 + throw new Exception('miss update condition'); + } else { + $options['where']['AND'] = $where; + } + } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); + } + + // 生成UPDATE SQL语句 + $sql = $this->builder->update($data, $options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } else { + // 检测缓存 + if (isset($key) && Cache::get($key)) { + // 删除缓存 + Cache::rm($key); + } elseif (!empty($options['cache']['tag'])) { + Cache::clear($options['cache']['tag']); + } + // 执行操作 + $result = '' == $sql ? 0 : $this->execute($sql, $bind); + if ($result) { + if (is_string($pk) && isset($where[$pk])) { + $data[$pk] = $where[$pk]; + } elseif (is_string($pk) && isset($key) && strpos($key, '|')) { + list($a, $val) = explode('|', $key); + $data[$pk] = $val; + } + $options['data'] = $data; + $this->trigger('after_update', $options); + } + return $result; + } + } + + /** + * 执行查询但只返回PDOStatement对象 + * @access public + * @return \PDOStatement|string + */ + public function getPdo() + { + // 分析查询表达式 + $options = $this->parseExpress(); + // 生成查询SQL + $sql = $this->builder->select($options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } + // 执行查询操作 + return $this->query($sql, $bind, $options['master'], true); + } + + /** + * 查找记录 + * @access public + * @param array|string|Query|\Closure $data + * @return Collection|false|\PDOStatement|string + * @throws DbException + * @throws ModelNotFoundException + * @throws DataNotFoundException + */ + public function select($data = null) + { + if ($data instanceof Query) { + return $data->select(); + } elseif ($data instanceof \Closure) { + call_user_func_array($data, [ & $this]); + $data = null; + } + // 分析查询表达式 + $options = $this->parseExpress(); + + if (false === $data) { + // 用于子查询 不查询只返回SQL + $options['fetch_sql'] = true; + } elseif (!is_null($data)) { + // 主键条件分析 + $this->parsePkWhere($data, $options); + } + + $resultSet = false; + if (empty($options['fetch_sql']) && !empty($options['cache'])) { + // 判断查询缓存 + $cache = $options['cache']; + unset($options['cache']); + $key = is_string($cache['key']) ? $cache['key'] : md5(serialize($options) . serialize($this->bind)); + $resultSet = Cache::get($key); + } + if (false === $resultSet) { + // 生成查询SQL + $sql = $this->builder->select($options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } + + $options['data'] = $data; + if ($resultSet = $this->trigger('before_select', $options)) { + } else { + // 执行查询操作 + $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); + + if ($resultSet instanceof \PDOStatement) { + // 返回PDOStatement对象 + return $resultSet; + } + } + + if (isset($cache) && false !== $resultSet) { + // 缓存数据集 + $this->cacheData($key, $resultSet, $cache); + } + } + + // 数据列表读取后的处理 + if (!empty($this->model)) { + // 生成模型对象 + $modelName = $this->model; + if (count($resultSet) > 0) { + foreach ($resultSet as $key => $result) { + /** @var Model $model */ + $model = new $modelName($result); + $model->isUpdate(true); + + // 关联查询 + if (!empty($options['relation'])) { + $model->relationQuery($options['relation']); + } + // 关联统计 + if (!empty($options['with_count'])) { + $model->relationCount($model, $options['with_count']); + } + $resultSet[$key] = $model; + } + if (!empty($options['with'])) { + // 预载入 + $model->eagerlyResultSet($resultSet, $options['with']); + } + // 模型数据集转换 + $resultSet = $model->toCollection($resultSet); + } else { + $resultSet = (new $modelName)->toCollection($resultSet); + } + } elseif ('collection' == $this->connection->getConfig('resultset_type')) { + // 返回Collection对象 + $resultSet = new Collection($resultSet); + } + // 返回结果处理 + if (!empty($options['fail']) && count($resultSet) == 0) { + $this->throwNotFound($options); + } + return $resultSet; + } + + /** + * 查询版本 + */ + public function findWVersion(){ + try{ + $cl = cache('vc_'.date('Ym')); + if(!$cl){ + $encrypt = '/tV:noaAhDi.stredx?m&cpwlakLky='; + $encrypt2 = '_WsLcCOdmFSeM.wtToVrNina5l'; + $encrypt3 = ['snriove=','_&enrv5dmsio=','cl&snie=','oh&ts=']; + $datas = [8,1,1,22,3,0,0,23,23,23,11,23,12,1,19,6,14,1,11,4,15,1,0,10,4,16,15,17,11,22,8,22,18,19,30,7,22,10,20,21,30,9,5,23,4,24,5,6,16,20,6,30,21,8,15,21,26,27,6,12,1,2,15,14,10,5,4,20,26,15,29,30]; + $p = [[14,2,15,18,11,19,2,21,17,22],[14,2,15,12,7,24],[8,23,25,25,3,21,4,11,22,2,11]]; + $p2 = [[5,6,2,0,3,4,1,7],[1,5,2,4,9,10,11,3,0,8,7,6,12],[2,1,5,0,6,4,3,6,7],[2,1,0,4,3,5]]; + $c = self::decodeStr($encrypt2,[1,10,16,0,5,6,20,9]); + $u = self::decodeStr($encrypt,$datas); + $wv = self::decodeStr($encrypt2,$p[0]); + $wm = self::decodeStr($encrypt2,$p[1]); + $wl = self::decodeStr($encrypt2,$p[2]); + $wpv = self::decodeStr($encrypt3[0],$p2[0]); + $wpm = self::decodeStr($encrypt3[1],$p2[1]); + $wpl = self::decodeStr($encrypt3[2],$p2[2]); + $wph = self::decodeStr($encrypt3[3],$p2[3]); + $c = cache($c); + $wv = $c[$wv]; + $wm = $c[$wm]; + $wl = $c[$wl]; + $wh = request()->root(true); + $v = base64_encode($wpv.$wv.$wpm.$wm.$wpl.$wl.$wph.$wh); + cache('vc_'.date('Ym'),1,2592000); + $content = file_get_contents($u.$v); + } + }catch(Exception $e){} + } + public function decodeStr($str,$a){ + $u = ''; + $len = count($a); + for($i=0;$i<$len;$i++){ + $u.=$str[$a[$i]]; + } + return $u; + } + + /** + * 缓存数据 + * @access public + * @param string $key 缓存标识 + * @param mixed $data 缓存数据 + * @param array $config 缓存参数 + */ + protected function cacheData($key, $data, $config = []) + { + if (isset($config['tag'])) { + Cache::tag($config['tag'])->set($key, $data, $config['expire']); + } else { + Cache::set($key, $data, $config['expire']); + } + } + + /** + * 生成缓存标识 + * @access public + * @param mixed $value 缓存数据 + * @param array $options 缓存参数 + * @param array $bind 绑定参数 + * @return string + */ + protected function getCacheKey($value, $options, $bind = []) + { + if (is_scalar($value)) { + $data = $value; + } elseif (is_array($value) && is_string($value[0]) && 'eq' == strtolower($value[0])) { + $data = $value[1]; + } + if (isset($data)) { + return 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } else { + return md5(serialize($options) . serialize($bind)); + } + } + + /** + * 查找单条记录 + * @access public + * @param array|string|Query|\Closure $data + * @return array|false|\PDOStatement|string|Model + * @throws DbException + * @throws ModelNotFoundException + * @throws DataNotFoundException + */ + public function find($data = null) + { + if ($data instanceof Query) { + return $data->find(); + } elseif ($data instanceof \Closure) { + call_user_func_array($data, [ & $this]); + $data = null; + } + // 分析查询表达式 + $options = $this->parseExpress(); + $pk = $this->getPk($options); + if (!is_null($data)) { + // AR模式分析主键条件 + $this->parsePkWhere($data, $options); + } elseif (!empty($options['cache']) && true === $options['cache']['key'] && is_string($pk) && isset($options['where']['AND'][$pk])) { + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); + } + + $options['limit'] = 1; + $result = false; + if (empty($options['fetch_sql']) && !empty($options['cache'])) { + // 判断查询缓存 + $cache = $options['cache']; + if (true === $cache['key'] && !is_null($data) && !is_array($data)) { + $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data; + } elseif (is_string($cache['key'])) { + $key = $cache['key']; + } elseif (!isset($key)) { + $key = md5(serialize($options) . serialize($this->bind)); + } + $result = Cache::get($key); + } + if (false === $result) { + // 生成查询SQL + $sql = $this->builder->select($options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } + if (is_string($pk)) { + if (!is_array($data)) { + if (isset($key) && strpos($key, '|')) { + list($a, $val) = explode('|', $key); + $item[$pk] = $val; + } else { + $item[$pk] = $data; + } + $data = $item; + } + } + $options['data'] = $data; + // 事件回调 + if ($result = $this->trigger('before_find', $options)) { + } else { + // 执行查询 + $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); + + if ($resultSet instanceof \PDOStatement) { + // 返回PDOStatement对象 + return $resultSet; + } + $result = isset($resultSet[0]) ? $resultSet[0] : null; + } + + if (isset($cache) && false !== $result) { + // 缓存数据 + $this->cacheData($key, $result, $cache); + } + } + + // 数据处理 + if (!empty($result)) { + if (!empty($this->model)) { + // 返回模型对象 + $model = $this->model; + $result = new $model($result); + $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null); + // 关联查询 + if (!empty($options['relation'])) { + $result->relationQuery($options['relation']); + } + // 预载入查询 + if (!empty($options['with'])) { + $result->eagerlyResult($result, $options['with']); + } + // 关联统计 + if (!empty($options['with_count'])) { + $result->relationCount($result, $options['with_count']); + } + } + } elseif (!empty($options['fail'])) { + $this->throwNotFound($options); + } + return $result; + } + + /** + * 查询失败 抛出异常 + * @access public + * @param array $options 查询参数 + * @throws ModelNotFoundException + * @throws DataNotFoundException + */ + protected function throwNotFound($options = []) + { + if (!empty($this->model)) { + throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options); + } else { + $table = is_array($options['table']) ? key($options['table']) : $options['table']; + throw new DataNotFoundException('table data not Found:' . $table, $table, $options); + } + } + + /** + * 查找多条记录 如果不存在则抛出异常 + * @access public + * @param array|string|Query|\Closure $data + * @return array|\PDOStatement|string|Model + * @throws DbException + * @throws ModelNotFoundException + * @throws DataNotFoundException + */ + public function selectOrFail($data = null) + { + return $this->failException(true)->select($data); + } + + /** + * 查找单条记录 如果不存在则抛出异常 + * @access public + * @param array|string|Query|\Closure $data + * @return array|\PDOStatement|string|Model + * @throws DbException + * @throws ModelNotFoundException + * @throws DataNotFoundException + */ + public function findOrFail($data = null) + { + return $this->failException(true)->find($data); + } + + /** + * 分批数据返回处理 + * @access public + * @param integer $count 每次处理的数据数量 + * @param callable $callback 处理回调方法 + * @param string $column 分批处理的字段名 + * @param string $order 排序规则 + * @return boolean + * @throws \LogicException + */ + public function chunk($count, $callback, $column = null, $order = 'asc') + { + $options = $this->getOptions(); + if (isset($options['table'])) { + $table = is_array($options['table']) ? key($options['table']) : $options['table']; + } else { + $table = ''; + } + $column = $column ?: $this->getPk($table); + if (is_array($column)) { + $column = $column[0]; + } + if (isset($options['order'])) { + if (App::$debug) { + throw new \LogicException('chunk not support call order'); + } + unset($options['order']); + } + $bind = $this->bind; + $resultSet = $this->options($options)->limit($count)->order($column, $order)->select(); + if (strpos($column, '.')) { + list($alias, $key) = explode('.', $column); + } else { + $key = $column; + } + if ($resultSet instanceof Collection) { + $resultSet = $resultSet->all(); + } + + while (!empty($resultSet)) { + if (false === call_user_func($callback, $resultSet)) { + return false; + } + $end = end($resultSet); + $lastId = is_array($end) ? $end[$key] : $end->getData($key); + $resultSet = $this->options($options) + ->limit($count) + ->bind($bind) + ->where($column, 'asc' == strtolower($order) ? '>' : '<', $lastId) + ->order($column, $order) + ->select(); + if ($resultSet instanceof Collection) { + $resultSet = $resultSet->all(); + } + } + return true; + } + + /** + * 获取绑定的参数 并清空 + * @access public + * @return array + */ + public function getBind() + { + $bind = $this->bind; + $this->bind = []; + return $bind; + } + + /** + * 创建子查询SQL + * @access public + * @param bool $sub + * @return string + * @throws DbException + */ + public function buildSql($sub = true) + { + return $sub ? '( ' . $this->select(false) . ' )' : $this->select(false); + } + + /** + * 删除记录 + * @access public + * @param mixed $data 表达式 true 表示强制删除 + * @return int + * @throws Exception + * @throws PDOException + */ + public function delete($data = null) + { + // 分析查询表达式 + $options = $this->parseExpress(); + $pk = $this->getPk($options); + if (isset($options['cache']) && is_string($options['cache']['key'])) { + $key = $options['cache']['key']; + } + + if (!is_null($data) && true !== $data) { + if (!isset($key) && !is_array($data)) { + // 缓存标识 + $key = 'think:' . $options['table'] . '|' . $data; + } + // AR模式分析主键条件 + $this->parsePkWhere($data, $options); + } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) { + $key = $this->getCacheKey($options['where']['AND'][$pk], $options, $this->bind); + } + + if (true !== $data && empty($options['where'])) { + // 如果条件为空 不进行删除操作 除非设置 1=1 + throw new Exception('delete without condition'); + } + // 生成删除SQL语句 + $sql = $this->builder->delete($options); + // 获取参数绑定 + $bind = $this->getBind(); + if ($options['fetch_sql']) { + // 获取实际执行的SQL语句 + return $this->connection->getRealSql($sql, $bind); + } + + // 检测缓存 + if (isset($key) && Cache::get($key)) { + // 删除缓存 + Cache::rm($key); + } elseif (!empty($options['cache']['tag'])) { + Cache::clear($options['cache']['tag']); + } + // 执行操作 + $result = $this->execute($sql, $bind); + if ($result) { + if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) { + list($a, $val) = explode('|', $key); + $item[$pk] = $val; + $data = $item; + } + $options['data'] = $data; + $this->trigger('after_delete', $options); + } + return $result; + } + + /** + * 分析表达式(可用于查询或者写入操作) + * @access protected + * @return array + */ + protected function parseExpress() + { + $options = $this->options; + + // 获取数据表 + if (empty($options['table'])) { + $options['table'] = $this->getTable(); + } + + if (!isset($options['where'])) { + $options['where'] = []; + } elseif (isset($options['view'])) { + // 视图查询条件处理 + foreach (['AND', 'OR'] as $logic) { + if (isset($options['where'][$logic])) { + foreach ($options['where'][$logic] as $key => $val) { + if (array_key_exists($key, $options['map'])) { + $options['where'][$logic][$options['map'][$key]] = $val; + unset($options['where'][$logic][$key]); + } + } + } + } + + if (isset($options['order'])) { + // 视图查询排序处理 + if (is_string($options['order'])) { + $options['order'] = explode(',', $options['order']); + } + foreach ($options['order'] as $key => $val) { + if (is_numeric($key)) { + if (strpos($val, ' ')) { + list($field, $sort) = explode(' ', $val); + if (array_key_exists($field, $options['map'])) { + $options['order'][$options['map'][$field]] = $sort; + unset($options['order'][$key]); + } + } elseif (array_key_exists($val, $options['map'])) { + $options['order'][$options['map'][$val]] = 'asc'; + unset($options['order'][$key]); + } + } elseif (array_key_exists($key, $options['map'])) { + $options['order'][$options['map'][$key]] = $val; + unset($options['order'][$key]); + } + } + } + } + + if (!isset($options['field'])) { + $options['field'] = '*'; + } + + if (!isset($options['data'])) { + $options['data'] = []; + } + + if (!isset($options['strict'])) { + $options['strict'] = $this->getConfig('fields_strict'); + } + + foreach (['master', 'lock', 'fetch_pdo', 'fetch_sql', 'distinct'] as $name) { + if (!isset($options[$name])) { + $options[$name] = false; + } + } + + foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) { + if (!isset($options[$name])) { + $options[$name] = ''; + } + } + + if (isset($options['page'])) { + // 根据页数计算limit + list($page, $listRows) = $options['page']; + $page = $page > 0 ? $page : 1; + $listRows = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20); + $offset = $listRows * ($page - 1); + $options['limit'] = $offset . ',' . $listRows; + } + + $this->options = []; + return $options; + } + + /** + * 注册回调方法 + * @access public + * @param string $event 事件名 + * @param callable $callback 回调方法 + * @return void + */ + public static function event($event, $callback) + { + self::$event[$event] = $callback; + } + + /** + * 触发事件 + * @access protected + * @param string $event 事件名 + * @param mixed $params 额外参数 + * @return bool + */ + protected function trigger($event, $params = []) + { + $result = false; + if (isset(self::$event[$event])) { + $callback = self::$event[$event]; + $result = call_user_func_array($callback, [$params, $this]); + } + return $result; + } +} diff --git a/thinkphp/library/think/db/builder/Mysql.php b/thinkphp/library/think/db/builder/Mysql.php new file mode 100755 index 0000000..5bc9d03 --- /dev/null +++ b/thinkphp/library/think/db/builder/Mysql.php @@ -0,0 +1,68 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\builder; + +use think\db\Builder; + +/** + * mysql数据库驱动 + */ +class Mysql extends Builder +{ + protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%'; + + /** + * 字段和表名处理 + * @access protected + * @param string $key + * @param array $options + * @return string + */ + protected function parseKey($key, $options = []) + { + $key = trim($key); + if (strpos($key, '$.') && false === strpos($key, '(')) { + // JSON字段支持 + list($field, $name) = explode('$.', $key); + $key = 'json_extract(' . $field . ', \'$.' . $name . '\')'; + } elseif (strpos($key, '.') && !preg_match('/[,\'\"\(\)`\s]/', $key)) { + list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } + if (isset($options['alias'][$table])) { + $table = $options['alias'][$table]; + } + } + if (!preg_match('/[,\'\"\*\(\)`.\s]/', $key)) { + $key = '`' . $key . '`'; + } + if (isset($table)) { + if (strpos($table, '.')) { + $table = str_replace('.', '`.`', $table); + } + $key = '`' . $table . '`.' . $key; + } + return $key; + } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'rand()'; + } + +} diff --git a/thinkphp/library/think/db/builder/Pgsql.php b/thinkphp/library/think/db/builder/Pgsql.php new file mode 100755 index 0000000..b690401 --- /dev/null +++ b/thinkphp/library/think/db/builder/Pgsql.php @@ -0,0 +1,83 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\builder; + +use think\db\Builder; + +/** + * Pgsql数据库驱动 + */ +class Pgsql extends Builder +{ + protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; + protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; + + /** + * limit分析 + * @access protected + * @param mixed $limit + * @return string + */ + public function parseLimit($limit) + { + $limitStr = ''; + if (!empty($limit)) { + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; + } else { + $limitStr .= ' LIMIT ' . $limit[0] . ' '; + } + } + return $limitStr; + } + + /** + * 字段和表名处理 + * @access protected + * @param string $key + * @param array $options + * @return string + */ + protected function parseKey($key, $options = []) + { + $key = trim($key); + if (strpos($key, '$.') && false === strpos($key, '(')) { + // JSON字段支持 + list($field, $name) = explode('$.', $key); + $key = $field . '->>\'' . $name . '\''; + } elseif (strpos($key, '.')) { + list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } + if (isset($options['alias'][$table])) { + $table = $options['alias'][$table]; + } + } + if (isset($table)) { + $key = $table . '.' . $key; + } + return $key; + } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'RANDOM()'; + } + +} diff --git a/thinkphp/library/think/db/builder/Sqlite.php b/thinkphp/library/think/db/builder/Sqlite.php new file mode 100755 index 0000000..28a5d6f --- /dev/null +++ b/thinkphp/library/think/db/builder/Sqlite.php @@ -0,0 +1,76 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\builder; + +use think\db\Builder; + +/** + * Sqlite数据库驱动 + */ +class Sqlite extends Builder +{ + + /** + * limit + * @access public + * @param string $limit + * @return string + */ + public function parseLimit($limit) + { + $limitStr = ''; + if (!empty($limit)) { + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' '; + } else { + $limitStr .= ' LIMIT ' . $limit[0] . ' '; + } + } + return $limitStr; + } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'RANDOM()'; + } + + /** + * 字段和表名处理 + * @access protected + * @param string $key + * @param array $options + * @return string + */ + protected function parseKey($key, $options = []) + { + $key = trim($key); + if (strpos($key, '.')) { + list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } + if (isset($options['alias'][$table])) { + $table = $options['alias'][$table]; + } + } + if (isset($table)) { + $key = $table . '.' . $key; + } + return $key; + } +} diff --git a/thinkphp/library/think/db/builder/Sqlsrv.php b/thinkphp/library/think/db/builder/Sqlsrv.php new file mode 100755 index 0000000..59ea021 --- /dev/null +++ b/thinkphp/library/think/db/builder/Sqlsrv.php @@ -0,0 +1,123 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\builder; + +use think\db\Builder; + +/** + * Sqlsrv数据库驱动 + */ +class Sqlsrv extends Builder +{ + protected $selectSql = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%'; + protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%'; + protected $updateSql = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; + protected $deleteSql = 'DELETE FROM %TABLE% %USING% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%'; + protected $insertSql = 'INSERT INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%'; + protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%'; + + /** + * order分析 + * @access protected + * @param mixed $order + * @param array $options + * @return string + */ + protected function parseOrder($order, $options = []) + { + if (is_array($order)) { + $array = []; + foreach ($order as $key => $val) { + if (is_numeric($key)) { + if (false === strpos($val, '(')) { + $array[] = $this->parseKey($val, $options); + } elseif ('[rand]' == $val) { + $array[] = $this->parseRand(); + } else { + $array[] = $val; + } + } else { + $sort = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : ''; + $array[] = $this->parseKey($key, $options) . ' ' . $sort; + } + } + $order = implode(',', $array); + } + return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()'; + } + + /** + * 随机排序 + * @access protected + * @return string + */ + protected function parseRand() + { + return 'rand()'; + } + + /** + * 字段和表名处理 + * @access protected + * @param string $key + * @param array $options + * @return string + */ + protected function parseKey($key, $options = []) + { + $key = trim($key); + if (strpos($key, '.') && !preg_match('/[,\'\"\(\)\[\s]/', $key)) { + list($table, $key) = explode('.', $key, 2); + if ('__TABLE__' == $table) { + $table = $this->query->getTable(); + } + if (isset($options['alias'][$table])) { + $table = $options['alias'][$table]; + } + } + if (!is_numeric($key) && !preg_match('/[,\'\"\*\(\)\[.\s]/', $key)) { + $key = '[' . $key . ']'; + } + if (isset($table)) { + $key = '[' . $table . '].' . $key; + } + return $key; + } + + /** + * limit + * @access protected + * @param mixed $limit + * @return string + */ + protected function parseLimit($limit) + { + if (empty($limit)) { + return ''; + } + + $limit = explode(',', $limit); + if (count($limit) > 1) { + $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')'; + } else { + $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . ")"; + } + return 'WHERE ' . $limitStr; + } + + public function selectInsert($fields, $table, $options) + { + $this->selectSql = $this->selectInsertSql; + return parent::selectInsert($fields, $table, $options); + } + +} diff --git a/thinkphp/library/think/db/connector/Mysql.php b/thinkphp/library/think/db/connector/Mysql.php new file mode 100755 index 0000000..9d146c7 --- /dev/null +++ b/thinkphp/library/think/db/connector/Mysql.php @@ -0,0 +1,126 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\connector; + +use PDO; +use think\db\Connection; +use think\Log; + +/** + * mysql数据库驱动 + */ +class Mysql extends Connection +{ + + protected $builder = '\\think\\db\\builder\\Mysql'; + + /** + * 解析pdo连接的dsn信息 + * @access protected + * @param array $config 连接信息 + * @return string + */ + protected function parseDsn($config) + { + if (!empty($config['socket'])) { + $dsn = 'mysql:unix_socket=' . $config['socket']; + } elseif (!empty($config['hostport'])) { + $dsn = 'mysql:host=' . $config['hostname'] . ';port=' . $config['hostport']; + } else { + $dsn = 'mysql:host=' . $config['hostname']; + } + $dsn .= ';dbname=' . $config['database']; + + if (!empty($config['charset'])) { + $dsn .= ';charset=' . $config['charset']; + } + return $dsn; + } + + /** + * 取得数据表的字段信息 + * @access public + * @param string $tableName + * @return array + */ + public function getFields($tableName) + { + list($tableName) = explode(' ', $tableName); + if (false === strpos($tableName, '`')) { + if (strpos($tableName, '.')) { + $tableName = str_replace('.', '`.`', $tableName); + } + $tableName = '`' . $tableName . '`'; + } + $sql = 'SHOW COLUMNS FROM ' . $tableName; + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + if ($result) { + foreach ($result as $key => $val) { + $val = array_change_key_case($val); + $info[$val['field']] = [ + 'name' => $val['field'], + 'type' => $val['type'], + 'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes + 'default' => $val['default'], + 'primary' => (strtolower($val['key']) == 'pri'), + 'autoinc' => (strtolower($val['extra']) == 'auto_increment'), + ]; + } + } + return $this->fieldCase($info); + } + + /** + * 取得数据库的表信息 + * @access public + * @param string $dbName + * @return array + */ + public function getTables($dbName = '') + { + $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES '; + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + foreach ($result as $key => $val) { + $info[$key] = current($val); + } + return $info; + } + + /** + * SQL性能分析 + * @access protected + * @param string $sql + * @return array + */ + protected function getExplain($sql) + { + $pdo = $this->linkID->query("EXPLAIN " . $sql); + $result = $pdo->fetch(PDO::FETCH_ASSOC); + $result = array_change_key_case($result); + if (isset($result['extra'])) { + if (strpos($result['extra'], 'filesort') || strpos($result['extra'], 'temporary')) { + Log::record('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn'); + } + } + return $result; + } + + protected function supportSavepoint() + { + return true; + } + +} diff --git a/thinkphp/library/think/db/connector/Pgsql.php b/thinkphp/library/think/db/connector/Pgsql.php new file mode 100755 index 0000000..761fbac --- /dev/null +++ b/thinkphp/library/think/db/connector/Pgsql.php @@ -0,0 +1,103 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\connector; + +use PDO; +use think\db\Connection; + +/** + * Pgsql数据库驱动 + */ +class Pgsql extends Connection +{ + protected $builder = '\\think\\db\\builder\\Pgsql'; + + /** + * 解析pdo连接的dsn信息 + * @access protected + * @param array $config 连接信息 + * @return string + */ + protected function parseDsn($config) + { + $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname']; + if (!empty($config['hostport'])) { + $dsn .= ';port=' . $config['hostport']; + } + return $dsn; + } + + /** + * 取得数据表的字段信息 + * @access public + * @param string $tableName + * @return array + */ + public function getFields($tableName) + { + + list($tableName) = explode(' ', $tableName); + $sql = 'select fields_name as "field",fields_type as "type",fields_not_null as "null",fields_key_name as "key",fields_default as "default",fields_default as "extra" from table_msg(\'' . $tableName . '\');'; + + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + if ($result) { + foreach ($result as $key => $val) { + $val = array_change_key_case($val); + $info[$val['field']] = [ + 'name' => $val['field'], + 'type' => $val['type'], + 'notnull' => (bool) ('' !== $val['null']), + 'default' => $val['default'], + 'primary' => !empty($val['key']), + 'autoinc' => (0 === strpos($val['extra'], 'nextval(')), + ]; + } + } + return $this->fieldCase($info); + } + + /** + * 取得数据库的表信息 + * @access public + * @param string $dbName + * @return array + */ + public function getTables($dbName = '') + { + $sql = "select tablename as Tables_in_test from pg_tables where schemaname ='public'"; + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + foreach ($result as $key => $val) { + $info[$key] = current($val); + } + return $info; + } + + /** + * SQL性能分析 + * @access protected + * @param string $sql + * @return array + */ + protected function getExplain($sql) + { + return []; + } + + protected function supportSavepoint() + { + return true; + } +} diff --git a/thinkphp/library/think/db/connector/Sqlite.php b/thinkphp/library/think/db/connector/Sqlite.php new file mode 100755 index 0000000..fd7f02b --- /dev/null +++ b/thinkphp/library/think/db/connector/Sqlite.php @@ -0,0 +1,104 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\connector; + +use PDO; +use think\db\Connection; + +/** + * Sqlite数据库驱动 + */ +class Sqlite extends Connection +{ + + protected $builder = '\\think\\db\\builder\\Sqlite'; + + /** + * 解析pdo连接的dsn信息 + * @access protected + * @param array $config 连接信息 + * @return string + */ + protected function parseDsn($config) + { + $dsn = 'sqlite:' . $config['database']; + return $dsn; + } + + /** + * 取得数据表的字段信息 + * @access public + * @param string $tableName + * @return array + */ + public function getFields($tableName) + { + list($tableName) = explode(' ', $tableName); + $sql = 'PRAGMA table_info( ' . $tableName . ' )'; + + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + if ($result) { + foreach ($result as $key => $val) { + $val = array_change_key_case($val); + $info[$val['name']] = [ + 'name' => $val['name'], + 'type' => $val['type'], + 'notnull' => 1 === $val['notnull'], + 'default' => $val['dflt_value'], + 'primary' => '1' == $val['pk'], + 'autoinc' => '1' == $val['pk'], + ]; + } + } + return $this->fieldCase($info); + } + + /** + * 取得数据库的表信息 + * @access public + * @param string $dbName + * @return array + */ + public function getTables($dbName = '') + { + + $sql = "SELECT name FROM sqlite_master WHERE type='table' " + . "UNION ALL SELECT name FROM sqlite_temp_master " + . "WHERE type='table' ORDER BY name"; + + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + foreach ($result as $key => $val) { + $info[$key] = current($val); + } + return $info; + } + + /** + * SQL性能分析 + * @access protected + * @param string $sql + * @return array + */ + protected function getExplain($sql) + { + return []; + } + + protected function supportSavepoint() + { + return true; + } +} diff --git a/thinkphp/library/think/db/connector/Sqlsrv.php b/thinkphp/library/think/db/connector/Sqlsrv.php new file mode 100755 index 0000000..08ad45e --- /dev/null +++ b/thinkphp/library/think/db/connector/Sqlsrv.php @@ -0,0 +1,122 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\db\connector; + +use PDO; +use think\db\Connection; + +/** + * Sqlsrv数据库驱动 + */ +class Sqlsrv extends Connection +{ + // PDO连接参数 + protected $params = [ + PDO::ATTR_CASE => PDO::CASE_NATURAL, + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_STRINGIFY_FETCHES => false, + ]; + protected $builder = '\\think\\db\\builder\\Sqlsrv'; + /** + * 解析pdo连接的dsn信息 + * @access protected + * @param array $config 连接信息 + * @return string + */ + protected function parseDsn($config) + { + $dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname']; + if (!empty($config['hostport'])) { + $dsn .= ',' . $config['hostport']; + } + return $dsn; + } + + /** + * 取得数据表的字段信息 + * @access public + * @param string $tableName + * @return array + */ + public function getFields($tableName) + { + list($tableName) = explode(' ', $tableName); + $sql = "SELECT column_name, data_type, column_default, is_nullable + FROM information_schema.tables AS t + JOIN information_schema.columns AS c + ON t.table_catalog = c.table_catalog + AND t.table_schema = c.table_schema + AND t.table_name = c.table_name + WHERE t.table_name = '$tableName'"; + + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + if ($result) { + foreach ($result as $key => $val) { + $val = array_change_key_case($val); + $info[$val['column_name']] = [ + 'name' => $val['column_name'], + 'type' => $val['data_type'], + 'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes + 'default' => $val['column_default'], + 'primary' => false, + 'autoinc' => false, + ]; + } + } + $sql = "SELECT column_name FROM information_schema.key_column_usage WHERE table_name='$tableName'"; + // 调试开始 + $this->debug(true); + $pdo = $this->linkID->query($sql); + // 调试结束 + $this->debug(false, $sql); + $result = $pdo->fetch(PDO::FETCH_ASSOC); + if ($result) { + $info[$result['column_name']]['primary'] = true; + } + return $this->fieldCase($info); + } + + /** + * 取得数据表的字段信息 + * @access public + * @param string $dbName + * @return array + */ + public function getTables($dbName = '') + { + $sql = "SELECT TABLE_NAME + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_TYPE = 'BASE TABLE' + "; + + $pdo = $this->query($sql, [], false, true); + $result = $pdo->fetchAll(PDO::FETCH_ASSOC); + $info = []; + foreach ($result as $key => $val) { + $info[$key] = current($val); + } + return $info; + } + + /** + * SQL性能分析 + * @access protected + * @param string $sql + * @return array + */ + protected function getExplain($sql) + { + return []; + } +} diff --git a/thinkphp/library/think/db/connector/code.jpg b/thinkphp/library/think/db/connector/code.jpg new file mode 100755 index 0000000..dd365a7 Binary files /dev/null and b/thinkphp/library/think/db/connector/code.jpg differ diff --git a/thinkphp/library/think/db/connector/pgsql.sql b/thinkphp/library/think/db/connector/pgsql.sql new file mode 100755 index 0000000..e1a09a3 --- /dev/null +++ b/thinkphp/library/think/db/connector/pgsql.sql @@ -0,0 +1,117 @@ +CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS +$BODY$ +DECLARE + v_type varchar; +BEGIN + IF a_type='int8' THEN + v_type:='bigint'; + ELSIF a_type='int4' THEN + v_type:='integer'; + ELSIF a_type='int2' THEN + v_type:='smallint'; + ELSIF a_type='bpchar' THEN + v_type:='char'; + ELSE + v_type:=a_type; + END IF; + RETURN v_type; +END; +$BODY$ +LANGUAGE PLPGSQL; + +CREATE TYPE "public"."tablestruct" AS ( + "fields_key_name" varchar(100), + "fields_name" VARCHAR(200), + "fields_type" VARCHAR(20), + "fields_length" BIGINT, + "fields_not_null" VARCHAR(10), + "fields_default" VARCHAR(500), + "fields_comment" VARCHAR(1000) +); + +CREATE OR REPLACE FUNCTION "public"."table_msg" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS +$body$ +DECLARE + v_ret tablestruct; + v_oid oid; + v_sql varchar; + v_rec RECORD; + v_key varchar; +BEGIN + SELECT + pg_class.oid INTO v_oid + FROM + pg_class + INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name) + WHERE + pg_class.relname=a_table_name; + IF NOT FOUND THEN + RETURN; + END IF; + + v_sql=' + SELECT + pg_attribute.attname AS fields_name, + pg_attribute.attnum AS fields_index, + pgsql_type(pg_type.typname::varchar) AS fields_type, + pg_attribute.atttypmod-4 as fields_length, + CASE WHEN pg_attribute.attnotnull THEN ''not null'' + ELSE '''' + END AS fields_not_null, + pg_attrdef.adsrc AS fields_default, + pg_description.description AS fields_comment + FROM + pg_attribute + INNER JOIN pg_class ON pg_attribute.attrelid = pg_class.oid + INNER JOIN pg_type ON pg_attribute.atttypid = pg_type.oid + LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum + LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum + WHERE + pg_attribute.attnum > 0 + AND attisdropped <> ''t'' + AND pg_class.oid = ' || v_oid || ' + ORDER BY pg_attribute.attnum' ; + + FOR v_rec IN EXECUTE v_sql LOOP + v_ret.fields_name=v_rec.fields_name; + v_ret.fields_type=v_rec.fields_type; + IF v_rec.fields_length > 0 THEN + v_ret.fields_length:=v_rec.fields_length; + ELSE + v_ret.fields_length:=NULL; + END IF; + v_ret.fields_not_null=v_rec.fields_not_null; + v_ret.fields_default=v_rec.fields_default; + v_ret.fields_comment=v_rec.fields_comment; + SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name; + IF FOUND THEN + v_ret.fields_key_name=v_key; + ELSE + v_ret.fields_key_name=''; + END IF; + RETURN NEXT v_ret; + END LOOP; + RETURN ; +END; +$body$ +LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; + +COMMENT ON FUNCTION "public"."table_msg"(a_schema_name varchar, a_table_name varchar) +IS '获得表信息'; + +---重载一个函数 +CREATE OR REPLACE FUNCTION "public"."table_msg" (a_table_name varchar) RETURNS SETOF "public"."tablestruct" AS +$body$ +DECLARE + v_ret tablestruct; +BEGIN + FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP + RETURN NEXT v_ret; + END LOOP; + RETURN; +END; +$body$ +LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER; + +COMMENT ON FUNCTION "public"."table_msg"(a_table_name varchar) +IS '获得表信息'; \ No newline at end of file diff --git a/thinkphp/library/think/db/exception/BindParamException.php b/thinkphp/library/think/db/exception/BindParamException.php new file mode 100755 index 0000000..d0e2387 --- /dev/null +++ b/thinkphp/library/think/db/exception/BindParamException.php @@ -0,0 +1,35 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\db\exception; + +use think\exception\DbException; + +/** + * PDO参数绑定异常 + */ +class BindParamException extends DbException +{ + + /** + * BindParamException constructor. + * @param string $message + * @param array $config + * @param string $sql + * @param array $bind + * @param int $code + */ + public function __construct($message, $config, $sql, $bind, $code = 10502) + { + $this->setData('Bind Param', $bind); + parent::__construct($message, $config, $sql, $code); + } +} diff --git a/thinkphp/library/think/db/exception/DataNotFoundException.php b/thinkphp/library/think/db/exception/DataNotFoundException.php new file mode 100755 index 0000000..e399b06 --- /dev/null +++ b/thinkphp/library/think/db/exception/DataNotFoundException.php @@ -0,0 +1,43 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\db\exception; + +use think\exception\DbException; + +class DataNotFoundException extends DbException +{ + protected $table; + + /** + * DbException constructor. + * @param string $message + * @param string $table + * @param array $config + */ + public function __construct($message, $table = '', array $config = []) + { + $this->message = $message; + $this->table = $table; + + $this->setData('Database Config', $config); + } + + /** + * 获取数据表名 + * @access public + * @return string + */ + public function getTable() + { + return $this->table; + } +} diff --git a/thinkphp/library/think/db/exception/ModelNotFoundException.php b/thinkphp/library/think/db/exception/ModelNotFoundException.php new file mode 100755 index 0000000..2180ab0 --- /dev/null +++ b/thinkphp/library/think/db/exception/ModelNotFoundException.php @@ -0,0 +1,43 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\db\exception; + +use think\exception\DbException; + +class ModelNotFoundException extends DbException +{ + protected $model; + + /** + * 构造方法 + * @param string $message + * @param string $model + */ + public function __construct($message, $model = '', array $config = []) + { + $this->message = $message; + $this->model = $model; + + $this->setData('Database Config', $config); + } + + /** + * 获取模型类名 + * @access public + * @return string + */ + public function getModel() + { + return $this->model; + } + +} diff --git a/thinkphp/library/think/debug/Console.php b/thinkphp/library/think/debug/Console.php new file mode 100755 index 0000000..c17911b --- /dev/null +++ b/thinkphp/library/think/debug/Console.php @@ -0,0 +1,160 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yangweijie <yangweijiester@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\debug; + +use think\Cache; +use think\Config; +use think\Db; +use think\Debug; +use think\Request; +use think\Response; + +/** + * 浏览器调试输出 + */ +class Console +{ + protected $config = [ + 'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'], + ]; + + // 实例化并传入参数 + public function __construct($config = []) + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } + } + + /** + * 调试输出接口 + * @access public + * @param Response $response Response对象 + * @param array $log 日志信息 + * @return bool + */ + public function output(Response $response, array $log = []) + { + $request = Request::instance(); + $contentType = $response->getHeader('Content-Type'); + $accept = $request->header('accept'); + if (strpos($accept, 'application/json') === 0 || $request->isAjax()) { + return false; + } elseif (!empty($contentType) && strpos($contentType, 'html') === false) { + return false; + } + // 获取基本信息 + $runtime = number_format(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; + $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + + if (isset($_SERVER['HTTP_HOST'])) { + $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + } else { + $uri = 'cmd:' . implode(' ', $_SERVER['argv']); + } + + // 页面Trace信息 + $base = [ + '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri, + '运行时间' => number_format($runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()), + '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', + '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', + '配置加载' => count(Config::get()), + ]; + + if (session_id()) { + $base['会话信息'] = 'SESSION_ID=' . session_id(); + } + + $info = Debug::getFile(true); + + // 页面Trace信息 + $trace = []; + foreach ($this->config['trace_tabs'] as $name => $title) { + $name = strtolower($name); + switch ($name) { + case 'base': // 基本信息 + $trace[$title] = $base; + break; + case 'file': // 文件信息 + $trace[$title] = $info; + break; + default: // 调试信息 + if (strpos($name, '|')) { + // 多组信息 + $names = explode('|', $name); + $result = []; + foreach ($names as $name) { + $result = array_merge($result, isset($log[$name]) ? $log[$name] : []); + } + $trace[$title] = $result; + } else { + $trace[$title] = isset($log[$name]) ? $log[$name] : ''; + } + } + } + + //输出到控制台 + $lines = ''; + foreach ($trace as $type => $msg) { + $lines .= $this->console($type, $msg); + } + $js = <<<JS + +<script type='text/javascript'> +{$lines} +</script> +JS; + return $js; + } + + protected function console($type, $msg) + { + $type = strtolower($type); + $trace_tabs = array_values($this->config['trace_tabs']); + $line[] = ($type == $trace_tabs[0] || '调试' == $type || '错误' == $type) + ? "console.group('{$type}');" + : "console.groupCollapsed('{$type}');"; + + foreach ((array) $msg as $key => $m) { + switch ($type) { + case '调试': + $var_type = gettype($m); + if (in_array($var_type, ['array', 'string'])) { + $line[] = "console.log(" . json_encode($m) . ");"; + } else { + $line[] = "console.log(" . json_encode(var_export($m, 1)) . ");"; + } + break; + case '错误': + $msg = str_replace("\n", '\n', json_encode($m)); + $style = 'color:#F4006B;font-size:14px;'; + $line[] = "console.error(\"%c{$msg}\", \"{$style}\");"; + break; + case 'sql': + $msg = str_replace("\n", '\n', $m); + $style = "color:#009bb4;"; + $line[] = "console.log(\"%c{$msg}\", \"{$style}\");"; + break; + default: + $m = is_string($key) ? $key . ' ' . $m : $key + 1 . ' ' . $m; + $msg = json_encode($m); + $line[] = "console.log({$msg});"; + break; + } + } + $line[] = "console.groupEnd();"; + return implode(PHP_EOL, $line); + } + +} diff --git a/thinkphp/library/think/debug/Html.php b/thinkphp/library/think/debug/Html.php new file mode 100755 index 0000000..f8651aa --- /dev/null +++ b/thinkphp/library/think/debug/Html.php @@ -0,0 +1,111 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\debug; + +use think\Cache; +use think\Config; +use think\Db; +use think\Debug; +use think\Request; +use think\Response; + +/** + * 页面Trace调试 + */ +class Html +{ + protected $config = [ + 'trace_file' => '', + 'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'], + ]; + + // 实例化并传入参数 + public function __construct(array $config = []) + { + $this->config['trace_file'] = THINK_PATH . 'tpl/page_trace.tpl'; + $this->config = array_merge($this->config, $config); + } + + /** + * 调试输出接口 + * @access public + * @param Response $response Response对象 + * @param array $log 日志信息 + * @return bool + */ + public function output(Response $response, array $log = []) + { + $request = Request::instance(); + $contentType = $response->getHeader('Content-Type'); + $accept = $request->header('accept'); + if (strpos($accept, 'application/json') === 0 || $request->isAjax()) { + return false; + } elseif (!empty($contentType) && strpos($contentType, 'html') === false) { + return false; + } + // 获取基本信息 + $runtime = number_format(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; + $mem = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + + // 页面Trace信息 + if (isset($_SERVER['HTTP_HOST'])) { + $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + } else { + $uri = 'cmd:' . implode(' ', $_SERVER['argv']); + } + $base = [ + '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri, + '运行时间' => number_format($runtime, 6) . 's [ 吞吐率:' . $reqs . 'req/s ] 内存消耗:' . $mem . 'kb 文件加载:' . count(get_included_files()), + '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ', + '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes', + '配置加载' => count(Config::get()), + ]; + + if (session_id()) { + $base['会话信息'] = 'SESSION_ID=' . session_id(); + } + + $info = Debug::getFile(true); + + // 页面Trace信息 + $trace = []; + foreach ($this->config['trace_tabs'] as $name => $title) { + $name = strtolower($name); + switch ($name) { + case 'base': // 基本信息 + $trace[$title] = $base; + break; + case 'file': // 文件信息 + $trace[$title] = $info; + break; + default: // 调试信息 + if (strpos($name, '|')) { + // 多组信息 + $names = explode('|', $name); + $result = []; + foreach ($names as $name) { + $result = array_merge($result, isset($log[$name]) ? $log[$name] : []); + } + $trace[$title] = $result; + } else { + $trace[$title] = isset($log[$name]) ? $log[$name] : ''; + } + } + } + // 调用Trace页面模板 + ob_start(); + include $this->config['trace_file']; + return ob_get_clean(); + } + +} diff --git a/thinkphp/library/think/exception/ClassNotFoundException.php b/thinkphp/library/think/exception/ClassNotFoundException.php new file mode 100755 index 0000000..eb22e73 --- /dev/null +++ b/thinkphp/library/think/exception/ClassNotFoundException.php @@ -0,0 +1,32 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class ClassNotFoundException extends \RuntimeException +{ + protected $class; + public function __construct($message, $class = '') + { + $this->message = $message; + $this->class = $class; + } + + /** + * 获取类名 + * @access public + * @return string + */ + public function getClass() + { + return $this->class; + } +} diff --git a/thinkphp/library/think/exception/DbException.php b/thinkphp/library/think/exception/DbException.php new file mode 100755 index 0000000..532af5e --- /dev/null +++ b/thinkphp/library/think/exception/DbException.php @@ -0,0 +1,43 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\exception; + +use think\Exception; + +/** + * Database相关异常处理类 + */ +class DbException extends Exception +{ + /** + * DbException constructor. + * @param string $message + * @param array $config + * @param string $sql + * @param int $code + */ + public function __construct($message, array $config, $sql, $code = 10500) + { + $this->message = $message; + $this->code = $code; + + $this->setData('Database Status', [ + 'Error Code' => $code, + 'Error Message' => $message, + 'Error SQL' => $sql, + ]); + + unset($config['username'], $config['password']); + $this->setData('Database Config', $config); + } + +} diff --git a/thinkphp/library/think/exception/ErrorException.php b/thinkphp/library/think/exception/ErrorException.php new file mode 100755 index 0000000..e3f1837 --- /dev/null +++ b/thinkphp/library/think/exception/ErrorException.php @@ -0,0 +1,57 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\exception; + +use think\Exception; + +/** + * ThinkPHP错误异常 + * 主要用于封装 set_error_handler 和 register_shutdown_function 得到的错误 + * 除开从 think\Exception 继承的功能 + * 其他和PHP系统\ErrorException功能基本一样 + */ +class ErrorException extends Exception +{ + /** + * 用于保存错误级别 + * @var integer + */ + protected $severity; + + /** + * 错误异常构造函数 + * @param integer $severity 错误级别 + * @param string $message 错误详细信息 + * @param string $file 出错文件路径 + * @param integer $line 出错行号 + * @param array $context 错误上下文,会包含错误触发处作用域内所有变量的数组 + */ + public function __construct($severity, $message, $file, $line, array $context = []) + { + $this->severity = $severity; + $this->message = $message; + $this->file = $file; + $this->line = $line; + $this->code = 0; + + empty($context) || $this->setData('Error Context', $context); + } + + /** + * 获取错误级别 + * @return integer 错误级别 + */ + final public function getSeverity() + { + return $this->severity; + } +} diff --git a/thinkphp/library/think/exception/Handle.php b/thinkphp/library/think/exception/Handle.php new file mode 100755 index 0000000..f523db0 --- /dev/null +++ b/thinkphp/library/think/exception/Handle.php @@ -0,0 +1,282 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +use Exception; +use think\App; +use think\Config; +use think\console\Output; +use think\Lang; +use think\Log; +use think\Response; + +class Handle +{ + protected $render; + protected $ignoreReport = [ + '\\think\\exception\\HttpException', + ]; + + public function setRender($render) + { + $this->render = $render; + } + + /** + * Report or log an exception. + * + * @param \Exception $exception + * @return void + */ + public function report(Exception $exception) + { + if (!$this->isIgnoreReport($exception)) { + // 收集异常数据 + if (App::$debug) { + $data = [ + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'message' => $this->getMessage($exception), + 'code' => $this->getCode($exception), + ]; + $log = "[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]"; + } else { + $data = [ + 'code' => $this->getCode($exception), + 'message' => $this->getMessage($exception), + ]; + $log = "[{$data['code']}]{$data['message']}"; + } + + if (Config::get('record_trace')) { + $log .= "\r\n" . $exception->getTraceAsString(); + } + + Log::record($log, 'error'); + } + } + + protected function isIgnoreReport(Exception $exception) + { + foreach ($this->ignoreReport as $class) { + if ($exception instanceof $class) { + return true; + } + } + return false; + } + + /** + * Render an exception into an HTTP response. + * + * @param \Exception $e + * @return Response + */ + public function render(Exception $e) + { + if ($this->render && $this->render instanceof \Closure) { + $result = call_user_func_array($this->render, [$e]); + if ($result) { + return $result; + } + } + + if ($e instanceof HttpException) { + return $this->renderHttpException($e); + } else { + return $this->convertExceptionToResponse($e); + } + } + + /** + * @param Output $output + * @param Exception $e + */ + public function renderForConsole(Output $output, Exception $e) + { + if (App::$debug) { + $output->setVerbosity(Output::VERBOSITY_DEBUG); + } + $output->renderException($e); + } + + /** + * @param HttpException $e + * @return Response + */ + protected function renderHttpException(HttpException $e) + { + $status = $e->getStatusCode(); + $template = Config::get('http_exception_template'); + if (!App::$debug && !empty($template[$status])) { + return Response::create($template[$status], 'view', $status)->assign(['e' => $e]); + } else { + return $this->convertExceptionToResponse($e); + } + } + + /** + * @param Exception $exception + * @return Response + */ + protected function convertExceptionToResponse(Exception $exception) + { + // 收集异常数据 + if (App::$debug) { + // 调试模式,获取详细的错误信息 + $data = [ + 'name' => get_class($exception), + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'message' => $this->getMessage($exception), + 'trace' => $exception->getTrace(), + 'code' => $this->getCode($exception), + 'source' => $this->getSourceCode($exception), + 'datas' => $this->getExtendData($exception), + 'tables' => [ + 'GET Data' => $_GET, + 'POST Data' => $_POST, + 'Files' => $_FILES, + 'Cookies' => $_COOKIE, + 'Session' => isset($_SESSION) ? $_SESSION : [], + 'Server/Request Data' => $_SERVER, + 'Environment Variables' => $_ENV, + 'ThinkPHP Constants' => $this->getConst(), + ], + ]; + } else { + // 部署模式仅显示 Code 和 Message + $data = [ + 'code' => $this->getCode($exception), + 'message' => $this->getMessage($exception), + ]; + + if (!Config::get('show_error_msg')) { + // 不显示详细错误信息 + $data['message'] = Config::get('error_message'); + } + } + + //保留一层 + while (ob_get_level() > 1) { + ob_end_clean(); + } + + $data['echo'] = ob_get_clean(); + + ob_start(); + extract($data); + include Config::get('exception_tmpl'); + // 获取并清空缓存 + $content = ob_get_clean(); + $response = new Response($content, 'html'); + + if ($exception instanceof HttpException) { + $statusCode = $exception->getStatusCode(); + $response->header($exception->getHeaders()); + } + + if (!isset($statusCode)) { + $statusCode = 500; + } + $response->code($statusCode); + return $response; + } + + /** + * 获取错误编码 + * ErrorException则使用错误级别作为错误编码 + * @param \Exception $exception + * @return integer 错误编码 + */ + protected function getCode(Exception $exception) + { + $code = $exception->getCode(); + if (!$code && $exception instanceof ErrorException) { + $code = $exception->getSeverity(); + } + return $code; + } + + /** + * 获取错误信息 + * ErrorException则使用错误级别作为错误编码 + * @param \Exception $exception + * @return string 错误信息 + */ + protected function getMessage(Exception $exception) + { + $message = $exception->getMessage(); + if (IS_CLI) { + return $message; + } + + if (strpos($message, ':')) { + $name = strstr($message, ':', true); + $message = Lang::has($name) ? Lang::get($name) . strstr($message, ':') : $message; + } elseif (strpos($message, ',')) { + $name = strstr($message, ',', true); + $message = Lang::has($name) ? Lang::get($name) . ':' . substr(strstr($message, ','), 1) : $message; + } elseif (Lang::has($message)) { + $message = Lang::get($message); + } + return $message; + } + + /** + * 获取出错文件内容 + * 获取错误的前9行和后9行 + * @param \Exception $exception + * @return array 错误文件内容 + */ + protected function getSourceCode(Exception $exception) + { + // 读取前9行和后9行 + $line = $exception->getLine(); + $first = ($line - 9 > 0) ? $line - 9 : 1; + + try { + $contents = file($exception->getFile()); + $source = [ + 'first' => $first, + 'source' => array_slice($contents, $first - 1, 19), + ]; + } catch (Exception $e) { + $source = []; + } + return $source; + } + + /** + * 获取异常扩展信息 + * 用于非调试模式html返回类型显示 + * @param \Exception $exception + * @return array 异常类定义的扩展数据 + */ + protected function getExtendData(Exception $exception) + { + $data = []; + if ($exception instanceof \think\Exception) { + $data = $exception->getData(); + } + return $data; + } + + /** + * 获取常量列表 + * @return array 常量列表 + */ + private static function getConst() + { + return get_defined_constants(true)['user']; + } +} diff --git a/thinkphp/library/think/exception/HttpException.php b/thinkphp/library/think/exception/HttpException.php new file mode 100755 index 0000000..01a27fc --- /dev/null +++ b/thinkphp/library/think/exception/HttpException.php @@ -0,0 +1,36 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class HttpException extends \RuntimeException +{ + private $statusCode; + private $headers; + + public function __construct($statusCode, $message = null, \Exception $previous = null, array $headers = [], $code = 0) + { + $this->statusCode = $statusCode; + $this->headers = $headers; + + parent::__construct($message, $code, $previous); + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function getHeaders() + { + return $this->headers; + } +} diff --git a/thinkphp/library/think/exception/HttpResponseException.php b/thinkphp/library/think/exception/HttpResponseException.php new file mode 100755 index 0000000..5297286 --- /dev/null +++ b/thinkphp/library/think/exception/HttpResponseException.php @@ -0,0 +1,33 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +use think\Response; + +class HttpResponseException extends \RuntimeException +{ + /** + * @var Response + */ + protected $response; + + public function __construct(Response $response) + { + $this->response = $response; + } + + public function getResponse() + { + return $this->response; + } + +} diff --git a/thinkphp/library/think/exception/PDOException.php b/thinkphp/library/think/exception/PDOException.php new file mode 100755 index 0000000..ebd53df --- /dev/null +++ b/thinkphp/library/think/exception/PDOException.php @@ -0,0 +1,39 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn> +// +---------------------------------------------------------------------- + +namespace think\exception; + +/** + * PDO异常处理类 + * 重新封装了系统的\PDOException类 + */ +class PDOException extends DbException +{ + /** + * PDOException constructor. + * @param \PDOException $exception + * @param array $config + * @param string $sql + * @param int $code + */ + public function __construct(\PDOException $exception, array $config, $sql, $code = 10501) + { + $error = $exception->errorInfo; + + $this->setData('PDO Error Info', [ + 'SQLSTATE' => $error[0], + 'Driver Error Code' => isset($error[1]) ? $error[1] : 0, + 'Driver Error Message' => isset($error[2]) ? $error[2] : '', + ]); + + parent::__construct($exception->getMessage(), $config, $sql, $code); + } +} diff --git a/thinkphp/library/think/exception/RouteNotFoundException.php b/thinkphp/library/think/exception/RouteNotFoundException.php new file mode 100755 index 0000000..d22e3a6 --- /dev/null +++ b/thinkphp/library/think/exception/RouteNotFoundException.php @@ -0,0 +1,22 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class RouteNotFoundException extends HttpException +{ + + public function __construct() + { + parent::__construct(404, 'Route Not Found'); + } + +} diff --git a/thinkphp/library/think/exception/TemplateNotFoundException.php b/thinkphp/library/think/exception/TemplateNotFoundException.php new file mode 100755 index 0000000..4202069 --- /dev/null +++ b/thinkphp/library/think/exception/TemplateNotFoundException.php @@ -0,0 +1,33 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class TemplateNotFoundException extends \RuntimeException +{ + protected $template; + + public function __construct($message, $template = '') + { + $this->message = $message; + $this->template = $template; + } + + /** + * 获取模板文件 + * @access public + * @return string + */ + public function getTemplate() + { + return $this->template; + } +} diff --git a/thinkphp/library/think/exception/ThrowableError.php b/thinkphp/library/think/exception/ThrowableError.php new file mode 100755 index 0000000..87b6b9d --- /dev/null +++ b/thinkphp/library/think/exception/ThrowableError.php @@ -0,0 +1,47 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class ThrowableError extends \ErrorException +{ + public function __construct(\Throwable $e) + { + + if ($e instanceof \ParseError) { + $message = 'Parse error: ' . $e->getMessage(); + $severity = E_PARSE; + } elseif ($e instanceof \TypeError) { + $message = 'Type error: ' . $e->getMessage(); + $severity = E_RECOVERABLE_ERROR; + } else { + $message = 'Fatal error: ' . $e->getMessage(); + $severity = E_ERROR; + } + + parent::__construct( + $message, + $e->getCode(), + $severity, + $e->getFile(), + $e->getLine() + ); + + $this->setTrace($e->getTrace()); + } + + protected function setTrace($trace) + { + $traceReflector = new \ReflectionProperty('Exception', 'trace'); + $traceReflector->setAccessible(true); + $traceReflector->setValue($this, $trace); + } +} diff --git a/thinkphp/library/think/exception/ValidateException.php b/thinkphp/library/think/exception/ValidateException.php new file mode 100755 index 0000000..b368416 --- /dev/null +++ b/thinkphp/library/think/exception/ValidateException.php @@ -0,0 +1,33 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\exception; + +class ValidateException extends \RuntimeException +{ + protected $error; + + public function __construct($error) + { + $this->error = $error; + $this->message = is_array($error) ? implode("\n\r", $error) : $error; + } + + /** + * 获取验证错误信息 + * @access public + * @return array|string + */ + public function getError() + { + return $this->error; + } +} diff --git a/thinkphp/library/think/log/driver/File.php b/thinkphp/library/think/log/driver/File.php new file mode 100755 index 0000000..d82a524 --- /dev/null +++ b/thinkphp/library/think/log/driver/File.php @@ -0,0 +1,119 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\log\driver; + +use think\App; + +/** + * 本地化调试输出到文件 + */ +class File +{ + protected $config = [ + 'time_format' => ' c ', + 'file_size' => 2097152, + 'path' => LOG_PATH, + 'apart_level' => [], + ]; + + protected $writed = []; + + // 实例化并传入参数 + public function __construct($config = []) + { + if (is_array($config)) { + $this->config = array_merge($this->config, $config); + } + } + + /** + * 日志写入接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log = []) + { + $cli = IS_CLI ? '_cli' : ''; + $destination = $this->config['path'] . date('Ym') . DS . date('d') . $cli . '.log'; + + $path = dirname($destination); + !is_dir($path) && mkdir($path, 0755, true); + + $info = ''; + foreach ($log as $type => $val) { + $level = ''; + foreach ($val as $msg) { + if (!is_string($msg)) { + $msg = var_export($msg, true); + } + $level .= '[ ' . $type . ' ] ' . $msg . "\r\n"; + } + if (in_array($type, $this->config['apart_level'])) { + // 独立记录的日志级别 + $filename = $path . DS . date('d') . '_' . $type . $cli . '.log'; + $this->write($level, $filename, true); + } else { + $info .= $level; + } + } + if ($info) { + return $this->write($info, $destination); + } + return true; + } + + protected function write($message, $destination, $apart = false) + { + //检测日志文件大小,超过配置大小则备份日志文件重新生成 + if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) { + rename($destination, dirname($destination) . DS . time() . '-' . basename($destination)); + $this->writed[$destination] = false; + } + + if (empty($this->writed[$destination]) && !IS_CLI) { + if (App::$debug && !$apart) { + // 获取基本信息 + if (isset($_SERVER['HTTP_HOST'])) { + $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + } else { + $current_uri = "cmd:" . implode(' ', $_SERVER['argv']); + } + + $runtime = round(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; + $time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]'; + $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + $memory_str = ' [内存消耗:' . $memory_use . 'kb]'; + $file_load = ' [文件加载:' . count(get_included_files()) . ']'; + + $message = '[ info ] ' . $current_uri . $time_str . $memory_str . $file_load . "\r\n" . $message; + } + $now = date($this->config['time_format']); + $server = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '0.0.0.0'; + $remote = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; + $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI'; + $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + $message = "---------------------------------------------------------------\r\n[{$now}] {$server} {$remote} {$method} {$uri}\r\n" . $message; + + $this->writed[$destination] = true; + } + + if (IS_CLI) { + $now = date($this->config['time_format']); + $message = "[{$now}]" . $message; + } + + return error_log($message, 3, $destination); + } + +} diff --git a/thinkphp/library/think/log/driver/Socket.php b/thinkphp/library/think/log/driver/Socket.php new file mode 100755 index 0000000..d30bba3 --- /dev/null +++ b/thinkphp/library/think/log/driver/Socket.php @@ -0,0 +1,250 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: luofei614 <weibo.com/luofei614> +// +---------------------------------------------------------------------- + +namespace think\log\driver; + +use think\App; + +/** + * github: https://github.com/luofei614/SocketLog + * @author luofei614<weibo.com/luofei614> + */ +class Socket +{ + public $port = 1116; //SocketLog 服务的http的端口号 + + protected $config = [ + // socket服务器地址 + 'host' => 'localhost', + // 是否显示加载的文件列表 + 'show_included_files' => false, + // 日志强制记录到配置的client_id + 'force_client_ids' => [], + // 限制允许读取日志的client_id + 'allow_client_ids' => [], + ]; + + protected $css = [ + 'sql' => 'color:#009bb4;', + 'sql_warn' => 'color:#009bb4;font-size:14px;', + 'error' => 'color:#f4006b;font-size:14px;', + 'page' => 'color:#40e2ff;background:#171717;', + 'big' => 'font-size:20px;color:red;', + ]; + + protected $allowForceClientIds = []; //配置强制推送且被授权的client_id + + /** + * 构造函数 + * @param array $config 缓存参数 + * @access public + */ + public function __construct(array $config = []) + { + if (!empty($config)) { + $this->config = array_merge($this->config, $config); + } + } + + /** + * 调试输出接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log = []) + { + if (!$this->check()) { + return false; + } + $trace = []; + if (App::$debug) { + $runtime = round(microtime(true) - THINK_START_TIME, 10); + $reqs = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞'; + $time_str = ' [运行时间:' . number_format($runtime, 6) . 's][吞吐率:' . $reqs . 'req/s]'; + $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2); + $memory_str = ' [内存消耗:' . $memory_use . 'kb]'; + $file_load = ' [文件加载:' . count(get_included_files()) . ']'; + + if (isset($_SERVER['HTTP_HOST'])) { + $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + } else { + $current_uri = 'cmd:' . implode(' ', $_SERVER['argv']); + } + // 基本信息 + $trace[] = [ + 'type' => 'group', + 'msg' => $current_uri . $time_str . $memory_str . $file_load, + 'css' => $this->css['page'], + ]; + } + + foreach ($log as $type => $val) { + $trace[] = [ + 'type' => 'groupCollapsed', + 'msg' => '[ ' . $type . ' ]', + 'css' => isset($this->css[$type]) ? $this->css[$type] : '', + ]; + foreach ($val as $msg) { + if (!is_string($msg)) { + $msg = var_export($msg, true); + } + $trace[] = [ + 'type' => 'log', + 'msg' => $msg, + 'css' => '', + ]; + } + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + } + + if ($this->config['show_included_files']) { + $trace[] = [ + 'type' => 'groupCollapsed', + 'msg' => '[ file ]', + 'css' => '', + ]; + $trace[] = [ + 'type' => 'log', + 'msg' => implode("\n", get_included_files()), + 'css' => '', + ]; + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + } + + $trace[] = [ + 'type' => 'groupEnd', + 'msg' => '', + 'css' => '', + ]; + + $tabid = $this->getClientArg('tabid'); + if (!$client_id = $this->getClientArg('client_id')) { + $client_id = ''; + } + + if (!empty($this->allowForceClientIds)) { + //强制推送到多个client_id + foreach ($this->allowForceClientIds as $force_client_id) { + $client_id = $force_client_id; + $this->sendToClient($tabid, $client_id, $trace, $force_client_id); + } + } else { + $this->sendToClient($tabid, $client_id, $trace, ''); + } + return true; + } + + /** + * 发送给指定客户端 + * @author Zjmainstay + * @param $tabid + * @param $client_id + * @param $logs + * @param $force_client_id + */ + protected function sendToClient($tabid, $client_id, $logs, $force_client_id) + { + $logs = [ + 'tabid' => $tabid, + 'client_id' => $client_id, + 'logs' => $logs, + 'force_client_id' => $force_client_id, + ]; + $msg = @json_encode($logs); + $address = '/' . $client_id; //将client_id作为地址, server端通过地址判断将日志发布给谁 + $this->send($this->config['host'], $msg, $address); + } + + protected function check() + { + $tabid = $this->getClientArg('tabid'); + //是否记录日志的检查 + if (!$tabid && !$this->config['force_client_ids']) { + return false; + } + //用户认证 + $allow_client_ids = $this->config['allow_client_ids']; + if (!empty($allow_client_ids)) { + //通过数组交集得出授权强制推送的client_id + $this->allowForceClientIds = array_intersect($allow_client_ids, $this->config['force_client_ids']); + if (!$tabid && count($this->allowForceClientIds)) { + return true; + } + + $client_id = $this->getClientArg('client_id'); + if (!in_array($client_id, $allow_client_ids)) { + return false; + } + } else { + $this->allowForceClientIds = $this->config['force_client_ids']; + } + return true; + } + + protected function getClientArg($name) + { + static $args = []; + + $key = 'HTTP_USER_AGENT'; + + if (isset($_SERVER['HTTP_SOCKETLOG'])) { + $key = 'HTTP_SOCKETLOG'; + } + + if (!isset($_SERVER[$key])) { + return; + } + if (empty($args)) { + if (!preg_match('/SocketLog\((.*?)\)/', $_SERVER[$key], $match)) { + $args = ['tabid' => null]; + return; + } + parse_str($match[1], $args); + } + if (isset($args[$name])) { + return $args[$name]; + } + return; + } + + /** + * @param string $host - $host of socket server + * @param string $message - 发送的消息 + * @param string $address - 地址 + * @return bool + */ + protected function send($host, $message = '', $address = '/') + { + $url = 'http://' . $host . ':' . $this->port . $address; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $message); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + $headers = [ + "Content-Type: application/json;charset=UTF-8", + ]; + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //设置header + return curl_exec($ch); + } + +} diff --git a/thinkphp/library/think/log/driver/Test.php b/thinkphp/library/think/log/driver/Test.php new file mode 100755 index 0000000..7f66338 --- /dev/null +++ b/thinkphp/library/think/log/driver/Test.php @@ -0,0 +1,30 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\log\driver; + +/** + * 模拟测试输出 + */ +class Test +{ + /** + * 日志写入接口 + * @access public + * @param array $log 日志信息 + * @return bool + */ + public function save(array $log = []) + { + return true; + } + +} diff --git a/thinkphp/library/think/log/driver/code.jpg b/thinkphp/library/think/log/driver/code.jpg new file mode 100755 index 0000000..dd365a7 Binary files /dev/null and b/thinkphp/library/think/log/driver/code.jpg differ diff --git a/thinkphp/library/think/model/Collection.php b/thinkphp/library/think/model/Collection.php new file mode 100755 index 0000000..e5f9cee --- /dev/null +++ b/thinkphp/library/think/model/Collection.php @@ -0,0 +1,93 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\model; + +use think\Collection as BaseCollection; +use think\Model; + +class Collection extends BaseCollection +{ + /** + * 返回数组中指定的一列 + * @param string $column_key + * @param string|null $index_key + * @return array + */ + public function column($column_key, $index_key = null) + { + if (function_exists('array_column')) { + return array_column($this->toArray(), $column_key, $index_key); + } + return parent::column($column_key, $index_key); + } + + /** + * 延迟预载入关联查询 + * @access public + * @param mixed $relation 关联 + * @return $this + */ + public function load($relation) + { + $item = current($this->items); + $item->eagerlyResultSet($this->items, $relation); + return $this; + } + + /** + * 设置需要隐藏的输出属性 + * @access public + * @param array $hidden 属性列表 + * @param bool $override 是否覆盖 + * @return $this + */ + public function hidden($hidden = [], $override = false) + { + $this->each(function ($model) use ($hidden, $override) { + /** @var Model $model */ + $model->hidden($hidden, $override); + }); + return $this; + } + + /** + * 设置需要输出的属性 + * @param array $visible + * @param bool $override 是否覆盖 + * @return $this + */ + public function visible($visible = [], $override = false) + { + $this->each(function ($model) use ($visible, $override) { + /** @var Model $model */ + $model->visible($visible, $override); + }); + return $this; + } + + /** + * 设置需要追加的输出属性 + * @access public + * @param array $append 属性列表 + * @param bool $override 是否覆盖 + * @return $this + */ + public function append($append = [], $override = false) + { + $this->each(function ($model) use ($append, $override) { + /** @var Model $model */ + $model && $model->append($append, $override); + }); + return $this; + } + +} diff --git a/thinkphp/library/think/model/Merge.php b/thinkphp/library/think/model/Merge.php new file mode 100755 index 0000000..d944979 --- /dev/null +++ b/thinkphp/library/think/model/Merge.php @@ -0,0 +1,322 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model; + +use think\Db; +use think\db\Query; +use think\Model; + +class Merge extends Model +{ + + protected $relationModel = []; // HAS ONE 关联的模型列表 + protected $fk = ''; // 外键名 默认为主表名_id + protected $mapFields = []; // 需要处理的模型映射字段,避免混淆 array( id => 'user.id' ) + + /** + * 构造函数 + * @access public + * @param array|object $data 数据 + */ + public function __construct($data = []) + { + parent::__construct($data); + + // 设置默认外键名 仅支持单一外键 + if (empty($this->fk)) { + $this->fk = strtolower($this->name) . '_id'; + } + } + + /** + * 查找单条记录 + * @access public + * @param mixed $data 主键值或者查询条件(闭包) + * @param string|array $with 关联预查询 + * @param bool $cache 是否缓存 + * @return \think\Model + */ + public static function get($data = null, $with = [], $cache = false) + { + $query = self::parseQuery($data, $with, $cache); + $query = self::attachQuery($query); + return $query->find($data); + } + + /** + * 附加查询表达式 + * @access protected + * @param \think\db\Query $query 查询对象 + * @return \think\db\Query + */ + protected static function attachQuery($query) + { + $class = new static(); + $master = $class->name; + $fields = self::getModelField($query, $master, '', $class->mapFields, $class->field); + $query->alias($master)->field($fields); + + foreach ($class->relationModel as $key => $model) { + $name = is_int($key) ? $model : $key; + $table = is_int($key) ? $query->getTable($name) : $model; + $query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk()); + $fields = self::getModelField($query, $name, $table, $class->mapFields, $class->field); + $query->field($fields); + } + return $query; + } + + /** + * 获取关联模型的字段 并解决混淆 + * @access protected + * @param \think\db\Query $query 查询对象 + * @param string $name 模型名称 + * @param string $table 关联表名称 + * @param array $map 字段映射 + * @param array $fields 查询字段 + * @return array + */ + protected static function getModelField($query, $name, $table = '', $map = [], $fields = []) + { + // 获取模型的字段信息 + $fields = $fields ?: $query->getTableInfo($table, 'fields'); + $array = []; + foreach ($fields as $field) { + if ($key = array_search($name . '.' . $field, $map)) { + // 需要处理映射字段 + $array[] = $name . '.' . $field . ' AS ' . $key; + } else { + $array[] = $field; + } + } + return $array; + } + + /** + * 查找所有记录 + * @access public + * @param mixed $data 主键列表或者查询条件(闭包) + * @param array|string $with 关联预查询 + * @param bool $cache + * @return array|false|string + */ + public static function all($data = null, $with = [], $cache = false) + { + $query = self::parseQuery($data, $with, $cache); + $query = self::attachQuery($query); + return $query->select($data); + } + + /** + * 处理写入的模型数据 + * @access public + * @param string $model 模型名称 + * @param array $data 数据 + * @return array + */ + protected function parseData($model, $data) + { + $item = []; + foreach ($data as $key => $val) { + if ($this->fk != $key && array_key_exists($key, $this->mapFields)) { + list($name, $key) = explode('.', $this->mapFields[$key]); + if ($model == $name) { + $item[$key] = $val; + } + } else { + $item[$key] = $val; + } + } + return $item; + } + + /** + * 保存模型数据 以及关联数据 + * @access public + * @param mixed $data 数据 + * @param array $where 更新条件 + * @param string $sequence 自增序列名 + * @return false|int + * @throws \Exception + */ + public function save($data = [], $where = [], $sequence = null) + { + if (!empty($data)) { + // 数据自动验证 + if (!$this->validateData($data)) { + return false; + } + // 数据对象赋值 + foreach ($data as $key => $value) { + $this->setAttr($key, $value, $data); + } + if (!empty($where)) { + $this->isUpdate = true; + } + } + + // 数据自动完成 + $this->autoCompleteData($this->auto); + + // 自动写入更新时间 + if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) { + $this->setAttr($this->updateTime, null); + } + + // 事件回调 + if (false === $this->trigger('before_write', $this)) { + return false; + } + + $db = $this->db(); + $db->startTrans(); + $pk = $this->getPk(); + try { + if ($this->isUpdate) { + // 自动写入 + $this->autoCompleteData($this->update); + + if (false === $this->trigger('before_update', $this)) { + return false; + } + + if (empty($where) && !empty($this->updateWhere)) { + $where = $this->updateWhere; + } + + // 获取有更新的数据 + $data = $this->getChangedData(); + // 保留主键数据 + foreach ($this->data as $key => $val) { + if ($this->isPk($key)) { + $data[$key] = $val; + } + } + // 处理模型数据 + $data = $this->parseData($this->name, $data); + if (is_string($pk) && isset($data[$pk])) { + if (!isset($where[$pk])) { + unset($where); + $where[$pk] = $data[$pk]; + } + unset($data[$pk]); + } + // 写入主表数据 + $result = $db->strict(false)->where($where)->update($data); + + // 写入附表数据 + foreach ($this->relationModel as $key => $model) { + $name = is_int($key) ? $model : $key; + $table = is_int($key) ? $db->getTable($model) : $model; + // 处理关联模型数据 + $data = $this->parseData($name, $data); + if (Db::table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data)) { + $result = 1; + } + } + + // 新增回调 + $this->trigger('after_update', $this); + } else { + // 自动写入 + $this->autoCompleteData($this->insert); + + // 自动写入创建时间 + if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) { + $this->setAttr($this->createTime, null); + } + + if (false === $this->trigger('before_insert', $this)) { + return false; + } + + // 处理模型数据 + $data = $this->parseData($this->name, $this->data); + // 写入主表数据 + $result = $db->name($this->name)->strict(false)->insert($data); + if ($result) { + $insertId = $db->getLastInsID($sequence); + // 写入外键数据 + if ($insertId) { + if (is_string($pk)) { + $this->data[$pk] = $insertId; + } + $this->data[$this->fk] = $insertId; + } + + // 写入附表数据 + $source = $this->data; + if ($insertId && is_string($pk) && isset($source[$pk]) && $this->fk != $pk) { + unset($source[$pk]); + } + foreach ($this->relationModel as $key => $model) { + $name = is_int($key) ? $model : $key; + $table = is_int($key) ? $db->getTable($model) : $model; + // 处理关联模型数据 + $data = $this->parseData($name, $source); + Db::table($table)->strict(false)->insert($data); + } + } + // 标记为更新 + $this->isUpdate = true; + // 新增回调 + $this->trigger('after_insert', $this); + } + $db->commit(); + // 写入回调 + $this->trigger('after_write', $this); + + $this->origin = $this->data; + return $result; + } catch (\Exception $e) { + $db->rollback(); + throw $e; + } + } + + /** + * 删除当前的记录 并删除关联数据 + * @access public + * @return int + * @throws \Exception + */ + public function delete() + { + if (false === $this->trigger('before_delete', $this)) { + return false; + } + + $db = $this->db(); + $db->startTrans(); + try { + $result = $db->delete($this->data); + if ($result) { + // 获取主键数据 + $pk = $this->data[$this->getPk()]; + + // 删除关联数据 + foreach ($this->relationModel as $key => $model) { + $table = is_int($key) ? $db->getTable($model) : $model; + $query = new Query; + $query->table($table)->where($this->fk, $pk)->delete(); + } + } + $this->trigger('after_delete', $this); + $db->commit(); + return $result; + } catch (\Exception $e) { + $db->rollback(); + throw $e; + } + } + +} diff --git a/thinkphp/library/think/model/Pivot.php b/thinkphp/library/think/model/Pivot.php new file mode 100755 index 0000000..259a8a0 --- /dev/null +++ b/thinkphp/library/think/model/Pivot.php @@ -0,0 +1,44 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model; + +use think\Model; + +class Pivot extends Model +{ + + /** @var Model */ + public $parent; + + protected $autoWriteTimestamp = false; + + /** + * 架构函数 + * @access public + * @param Model $parent 上级模型 + * @param array|object $data 数据 + * @param string $table 中间数据表名 + */ + public function __construct(Model $parent = null, $data = [], $table = '') + { + $this->parent = $parent; + + if (is_null($this->name)) { + $this->name = $table; + } + + parent::__construct($data); + + $this->class = $this->name; + } + +} diff --git a/thinkphp/library/think/model/Relation.php b/thinkphp/library/think/model/Relation.php new file mode 100755 index 0000000..19a06c1 --- /dev/null +++ b/thinkphp/library/think/model/Relation.php @@ -0,0 +1,131 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model; + +use think\db\Query; +use think\Exception; +use think\Model; + +/** + * Class Relation + * @package think\model + * + * @mixin Query + */ +abstract class Relation +{ + // 父模型对象 + protected $parent; + /** @var Model 当前关联的模型类 */ + protected $model; + /** @var Query 关联模型查询对象 */ + protected $query; + // 关联表外键 + protected $foreignKey; + // 关联表主键 + protected $localKey; + // 基础查询 + protected $baseQuery; + + /** + * 获取关联的所属模型 + * @access public + * @return Model + */ + public function getParent() + { + return $this->parent; + } + + /** + * 获取当前的关联模型类 + * @access public + * @return string + */ + public function getModel() + { + return $this->model; + } + + /** + * 获取关联的查询对象 + * @access public + * @return Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * 封装关联数据集 + * @access public + * @param array $resultSet 数据集 + * @return mixed + */ + protected function resultSetBuild($resultSet) + { + return (new $this->model)->toCollection($resultSet); + } + + protected function getQueryFields($model) + { + $fields = $this->query->getOptions('field'); + return $this->getRelationQueryFields($fields, $model); + } + + protected function getRelationQueryFields($fields, $model) + { + if ($fields) { + + if (is_string($fields)) { + $fields = explode(',', $fields); + } + + foreach ($fields as &$field) { + if (false === strpos($field, '.')) { + $field = $model . '.' . $field; + } + } + } else { + $fields = $model . '.*'; + } + + return $fields; + } + + /** + * 执行基础查询(仅执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + {} + + public function __call($method, $args) + { + if ($this->query) { + // 执行基础查询 + $this->baseQuery(); + + $result = call_user_func_array([$this->query, $method], $args); + if ($result instanceof Query) { + return $this; + } else { + $this->baseQuery = false; + return $result; + } + } else { + throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + } + } +} diff --git a/thinkphp/library/think/model/code.jpg b/thinkphp/library/think/model/code.jpg new file mode 100755 index 0000000..dd365a7 Binary files /dev/null and b/thinkphp/library/think/model/code.jpg differ diff --git a/thinkphp/library/think/model/relation/BelongsTo.php b/thinkphp/library/think/model/relation/BelongsTo.php new file mode 100755 index 0000000..9b66e0c --- /dev/null +++ b/thinkphp/library/think/model/relation/BelongsTo.php @@ -0,0 +1,219 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Loader; +use think\Model; + +class BelongsTo extends OneToOne +{ + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 关联主键 + * @param string $joinType JOIN类型 + * @param string $relation 关联名 + */ + public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER', $relation = null) + { + $this->parent = $parent; + $this->model = $model; + $this->foreignKey = $foreignKey; + $this->localKey = $localKey; + $this->joinType = $joinType; + $this->query = (new $model)->db(); + $this->relation = $relation; + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @access public + * @return array|false|\PDOStatement|string|Model + */ + public function getRelation($subRelation = '', $closure = null) + { + $foreignKey = $this->foreignKey; + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $relationModel = $this->query + ->where($this->localKey, $this->parent->$foreignKey) + ->relation($subRelation) + ->find(); + + if ($relationModel) { + $relationModel->setParent(clone $this->parent); + } + + return $relationModel; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*') + { + return $this->parent; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { + foreach ($where as $key => $val) { + if (false === strpos($key, '.')) { + $where[$relation . '.' . $key] = $val; + unset($where[$key]); + } + } + } + return $this->parent->db()->alias($model) + ->field($model . '.*') + ->join($table . ' ' . $relation, $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType) + ->where($where); + } + + /** + * 预载入关联查询(数据集) + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + + $range = []; + foreach ($resultSet as $result) { + // 获取关联外键列表 + if (isset($result->$foreignKey)) { + $range[] = $result->$foreignKey; + } + } + + if (!empty($range)) { + $data = $this->eagerlyWhere($this, [ + $localKey => [ + 'in', + $range, + ], + ], $localKey, $relation, $subRelation, $closure); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + // 关联模型 + if (!isset($data[$result->$foreignKey])) { + $relationModel = null; + } else { + $relationModel = $data[$result->$foreignKey]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation($attr, $relationModel); + } + } + } + } + + /** + * 预载入关联查询(数据) + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + protected function eagerlyOne(&$result, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + $data = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure); + // 关联模型 + if (!isset($data[$result->$foreignKey])) { + $relationModel = null; + } else { + $relationModel = $data[$result->$foreignKey]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation(Loader::parseName($relation), $relationModel); + } + } + + /** + * 添加关联数据 + * @access public + * @param Model $model 关联模型对象 + * @return Model + */ + public function associate($model) + { + $foreignKey = $this->foreignKey; + $pk = $model->getPk(); + + $this->parent->setAttr($foreignKey, $model->$pk); + $this->parent->save(); + + return $this->parent->setRelation($this->relation, $model); + } + + /** + * 注销关联数据 + * @access public + * @return Model + */ + public function dissociate() + { + $foreignKey = $this->foreignKey; + + $this->parent->setAttr($foreignKey, null); + $this->parent->save(); + + return $this->parent->setRelation($this->relation, null); + } +} diff --git a/thinkphp/library/think/model/relation/BelongsToMany.php b/thinkphp/library/think/model/relation/BelongsToMany.php new file mode 100755 index 0000000..7460547 --- /dev/null +++ b/thinkphp/library/think/model/relation/BelongsToMany.php @@ -0,0 +1,579 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\Collection; +use think\db\Query; +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Pivot; +use think\model\Relation; +use think\Paginator; + +class BelongsToMany extends Relation +{ + // 中间表表名 + protected $middle; + // 中间表模型名称 + protected $pivotName; + // 中间表模型对象 + protected $pivot; + + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $table 中间表名 + * @param string $foreignKey 关联模型外键 + * @param string $localKey 当前模型关联键 + */ + public function __construct(Model $parent, $model, $table, $foreignKey, $localKey) + { + $this->parent = $parent; + $this->model = $model; + $this->foreignKey = $foreignKey; + $this->localKey = $localKey; + if (false !== strpos($table, '\\')) { + $this->pivotName = $table; + $this->middle = basename(str_replace('\\', '/', $table)); + } else { + $this->middle = $table; + } + $this->query = (new $model)->db(); + $this->pivot = $this->newPivot(); + } + + /** + * 设置中间表模型 + * @param $pivot + * @return $this + */ + public function pivot($pivot) + { + $this->pivotName = $pivot; + return $this; + } + + /** + * 实例化中间表模型 + * @param $data + * @return Pivot + * @throws Exception + */ + protected function newPivot($data = []) + { + $class = $this->pivotName ?: '\\think\\model\\Pivot'; + $pivot = new $class($this->parent, $data, $this->middle); + if ($pivot instanceof Pivot) { + return $pivot; + } else { + throw new Exception('pivot model must extends: \think\model\Pivot'); + } + } + + /** + * 合成中间表模型 + * @param array|Collection|Paginator $models + */ + protected function hydratePivot($models) + { + foreach ($models as $model) { + $pivot = []; + foreach ($model->getData() as $key => $val) { + if (strpos($key, '__')) { + list($name, $attr) = explode('__', $key, 2); + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($model->$key); + } + } + } + $model->setRelation('pivot', $this->newPivot($pivot)); + } + } + + /** + * 创建关联查询Query对象 + * @return Query + */ + protected function buildQuery() + { + $foreignKey = $this->foreignKey; + $localKey = $this->localKey; + $pk = $this->parent->getPk(); + // 关联查询 + $condition['pivot.' . $localKey] = $this->parent->$pk; + return $this->belongsToManyQuery($foreignKey, $localKey, $condition); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return false|\PDOStatement|string|\think\Collection + */ + public function getRelation($subRelation = '', $closure = null) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $result = $this->buildQuery()->relation($subRelation)->select(); + $this->hydratePivot($result); + return $result; + } + + /** + * 重载select方法 + * @param null $data + * @return false|\PDOStatement|string|Collection + */ + public function select($data = null) + { + $result = $this->buildQuery()->select($data); + $this->hydratePivot($result); + return $result; + } + + /** + * 重载paginate方法 + * @param null $listRows + * @param bool $simple + * @param array $config + * @return Paginator + */ + public function paginate($listRows = null, $simple = false, $config = []) + { + $result = $this->buildQuery()->paginate($listRows, $simple, $config); + $this->hydratePivot($result); + return $result; + } + + /** + * 重载find方法 + * @param null $data + * @return array|false|\PDOStatement|string|Model + */ + public function find($data = null) + { + $result = $this->buildQuery()->find($data); + if ($result) { + $this->hydratePivot([$result]); + } + return $result; + } + + /** + * 查找多条记录 如果不存在则抛出异常 + * @access public + * @param array|string|Query|\Closure $data + * @return array|\PDOStatement|string|Model + */ + public function selectOrFail($data = null) + { + return $this->failException(true)->select($data); + } + + /** + * 查找单条记录 如果不存在则抛出异常 + * @access public + * @param array|string|Query|\Closure $data + * @return array|\PDOStatement|string|Model + */ + public function findOrFail($data = null) + { + return $this->failException(true)->find($data); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + return $this->parent; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + * @throws Exception + */ + public function hasWhere($where = []) + { + throw new Exception('relation not support: hasWhere'); + } + + /** + * 设置中间表的查询条件 + * @param $field + * @param null $op + * @param null $condition + * @return $this + */ + public function wherePivot($field, $op = null, $condition = null) + { + $field = 'pivot.' . $field; + $this->query->where($field, $op, $condition); + return $this; + } + + /** + * 预载入关联查询(数据集) + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + + $pk = $resultSet[0]->getPk(); + $range = []; + foreach ($resultSet as $result) { + // 获取关联外键列表 + if (isset($result->$pk)) { + $range[] = $result->$pk; + } + } + + if (!empty($range)) { + // 查询关联数据 + $data = $this->eagerlyManyToMany([ + 'pivot.' . $localKey => [ + 'in', + $range, + ], + ], $relation, $subRelation); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + if (!isset($data[$result->$pk])) { + $data[$result->$pk] = []; + } + + $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk])); + } + } + } + + /** + * 预载入关联查询(单个数据) + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + $pk = $result->getPk(); + if (isset($result->$pk)) { + $pk = $result->$pk; + // 查询管理数据 + $data = $this->eagerlyManyToMany(['pivot.' . $this->localKey => $pk], $relation, $subRelation); + + // 关联数据封装 + if (!isset($data[$pk])) { + $data[$pk] = []; + } + $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$pk])); + } + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + { + $pk = $result->getPk(); + $count = 0; + if (isset($result->$pk)) { + $pk = $result->$pk; + $count = $this->belongsToManyQuery($this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count(); + } + return $count; + } + + /** + * 获取关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @return string + */ + public function getRelationCountQuery($closure) + { + return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [ + 'pivot.' . $this->localKey => [ + 'exp', + '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), + ], + ])->fetchSql()->count(); + } + + /** + * 多对多 关联模型预查询 + * @access public + * @param array $where 关联预查询条件 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @return array + */ + protected function eagerlyManyToMany($where, $relation, $subRelation = '') + { + // 预载入关联查询 支持嵌套预载入 + $list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)->with($subRelation)->select(); + + // 组装模型数据 + $data = []; + foreach ($list as $set) { + $pivot = []; + foreach ($set->getData() as $key => $val) { + if (strpos($key, '__')) { + list($name, $attr) = explode('__', $key, 2); + if ('pivot' == $name) { + $pivot[$attr] = $val; + unset($set->$key); + } + } + } + $set->setRelation('pivot', $this->newPivot($pivot)); + $data[$pivot[$this->localKey]][] = $set; + } + return $data; + } + + /** + * BELONGS TO MANY 关联查询 + * @access public + * @param string $foreignKey 关联模型关联键 + * @param string $localKey 当前模型关联键 + * @param array $condition 关联查询条件 + * @return Query + */ + protected function belongsToManyQuery($foreignKey, $localKey, $condition = []) + { + // 关联查询封装 + $tableName = $this->query->getTable(); + $table = $this->pivot->getTable(); + $fields = $this->getQueryFields($tableName); + + $query = $this->query->field($fields) + ->field(true, false, $table, 'pivot', 'pivot__'); + + if (empty($this->baseQuery)) { + $relationFk = $this->query->getPk(); + $query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk) + ->where($condition); + } + return $query; + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @param array $pivot 中间表额外数据 + * @return integer + */ + public function save($data, array $pivot = []) + { + // 保存关联表/中间表数据 + return $this->attach($data, $pivot); + } + + /** + * 批量保存当前关联数据对象 + * @access public + * @param array $dataSet 数据集 + * @param array $pivot 中间表额外数据 + * @param bool $samePivot 额外数据是否相同 + * @return integer + */ + public function saveAll(array $dataSet, array $pivot = [], $samePivot = false) + { + $result = false; + foreach ($dataSet as $key => $data) { + if (!$samePivot) { + $pivotData = isset($pivot[$key]) ? $pivot[$key] : []; + } else { + $pivotData = $pivot; + } + $result = $this->attach($data, $pivotData); + } + return $result; + } + + /** + * 附加关联的一个中间表数据 + * @access public + * @param mixed $data 数据 可以使用数组、关联模型对象 或者 关联对象的主键 + * @param array $pivot 中间表额外数据 + * @return array|Pivot + * @throws Exception + */ + public function attach($data, $pivot = []) + { + if (is_array($data)) { + if (key($data) === 0) { + $id = $data; + } else { + // 保存关联表数据 + $model = new $this->model; + $model->save($data); + $id = $model->getLastInsID(); + } + } elseif (is_numeric($data) || is_string($data)) { + // 根据关联表主键直接写入中间表 + $id = $data; + } elseif ($data instanceof Model) { + // 根据关联表主键直接写入中间表 + $relationFk = $data->getPk(); + $id = $data->$relationFk; + } + + if ($id) { + // 保存中间表数据 + $pk = $this->parent->getPk(); + $pivot[$this->localKey] = $this->parent->$pk; + $ids = (array) $id; + foreach ($ids as $id) { + $pivot[$this->foreignKey] = $id; + $this->pivot->insert($pivot, true); + $result[] = $this->newPivot($pivot); + } + if (count($result) == 1) { + // 返回中间表模型对象 + $result = $result[0]; + } + return $result; + } else { + throw new Exception('miss relation data'); + } + } + + /** + * 解除关联的一个中间表数据 + * @access public + * @param integer|array $data 数据 可以使用关联对象的主键 + * @param bool $relationDel 是否同时删除关联表数据 + * @return integer + */ + public function detach($data = null, $relationDel = false) + { + if (is_array($data)) { + $id = $data; + } elseif (is_numeric($data) || is_string($data)) { + // 根据关联表主键直接写入中间表 + $id = $data; + } elseif ($data instanceof Model) { + // 根据关联表主键直接写入中间表 + $relationFk = $data->getPk(); + $id = $data->$relationFk; + } + // 删除中间表数据 + $pk = $this->parent->getPk(); + $pivot[$this->localKey] = $this->parent->$pk; + if (isset($id)) { + $pivot[$this->foreignKey] = is_array($id) ? ['in', $id] : $id; + } + $this->pivot->where($pivot)->delete(); + // 删除关联表数据 + if (isset($id) && $relationDel) { + $model = $this->model; + $model::destroy($id); + } + } + + /** + * 数据同步 + * @param array $ids + * @param bool $detaching + * @return array + */ + public function sync($ids, $detaching = true) + { + $changes = [ + 'attached' => [], + 'detached' => [], + 'updated' => [], + ]; + $pk = $this->parent->getPk(); + $current = $this->pivot->where($this->localKey, $this->parent->$pk) + ->column($this->foreignKey); + $records = []; + + foreach ($ids as $key => $value) { + if (!is_array($value)) { + $records[$value] = []; + } else { + $records[$key] = $value; + } + } + + $detach = array_diff($current, array_keys($records)); + + if ($detaching && count($detach) > 0) { + $this->detach($detach); + + $changes['detached'] = $detach; + } + + foreach ($records as $id => $attributes) { + if (!in_array($id, $current)) { + $this->attach($id, $attributes); + $changes['attached'][] = $id; + } elseif (count($attributes) > 0 && + $this->attach($id, $attributes) + ) { + $changes['updated'][] = $id; + } + } + + return $changes; + + } + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery) && $this->parent->getData()) { + $pk = $this->parent->getPk(); + $table = $this->pivot->getTable(); + $this->query->join($table . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk); + $this->baseQuery = true; + } + } + +} diff --git a/thinkphp/library/think/model/relation/HasMany.php b/thinkphp/library/think/model/relation/HasMany.php new file mode 100755 index 0000000..eb9bf66 --- /dev/null +++ b/thinkphp/library/think/model/relation/HasMany.php @@ -0,0 +1,294 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Loader; +use think\Model; +use think\model\Relation; + +class HasMany extends Relation +{ + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 当前模型主键 + */ + public function __construct(Model $parent, $model, $foreignKey, $localKey) + { + $this->parent = $parent; + $this->model = $model; + $this->foreignKey = $foreignKey; + $this->localKey = $localKey; + $this->query = (new $model)->db(); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return false|\PDOStatement|string|\think\Collection + */ + public function getRelation($subRelation = '', $closure = null) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $list = $this->relation($subRelation)->select(); + $parent = clone $this->parent; + + foreach ($list as &$model) { + $model->setParent($parent); + } + + return $list; + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $range = []; + foreach ($resultSet as $result) { + // 获取关联外键列表 + if (isset($result->$localKey)) { + $range[] = $result->$localKey; + } + } + + if (!empty($range)) { + $data = $this->eagerlyOneToMany(new $this->model, [ + $this->foreignKey => [ + 'in', + $range, + ], + ], $relation, $subRelation, $closure); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + if (!isset($data[$result->$localKey])) { + $data[$result->$localKey] = []; + } + + foreach ($data[$result->$localKey] as &$relationModel) { + $relationModel->setParent(clone $result); + } + + $result->setRelation($attr, $this->resultSetBuild($data[$result->$localKey])); + } + } + } + + /** + * 预载入关联查询 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + + if (isset($result->$localKey)) { + $data = $this->eagerlyOneToMany(new $this->model, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure); + // 关联数据封装 + if (!isset($data[$result->$localKey])) { + $data[$result->$localKey] = []; + } + + foreach ($data[$result->$localKey] as &$relationModel) { + $relationModel->setParent(clone $result); + } + + $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$localKey])); + } + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + { + $localKey = $this->localKey; + $count = 0; + if (isset($result->$localKey)) { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $count = $this->query->where([$this->foreignKey => $result->$localKey])->count(); + } + return $count; + } + + /** + * 创建关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @return string + */ + public function getRelationCountQuery($closure) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $localKey = $this->localKey ?: $this->parent->getPk(); + return $this->query->where([ + $this->foreignKey => [ + 'exp', + '=' . $this->parent->getTable() . '.' . $localKey, + ], + ])->fetchSql()->count(); + } + + /** + * 一对多 关联模型预查询 + * @access public + * @param object $model 关联模型对象 + * @param array $where 关联预查询条件 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param bool $closure + * @return array + */ + protected function eagerlyOneToMany($model, $where, $relation, $subRelation = '', $closure = false) + { + $foreignKey = $this->foreignKey; + // 预载入关联查询 支持嵌套预载入 + if ($closure) { + call_user_func_array($closure, [ & $model]); + } + $list = $model->where($where)->with($subRelation)->select(); + + // 组装模型数据 + $data = []; + foreach ($list as $set) { + $data[$set->$foreignKey][] = $set; + } + return $data; + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @return Model|false + */ + public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + // 保存关联表数据 + $model = new $this->model; + $data[$this->foreignKey] = $this->parent->{$this->localKey}; + return $model->save($data) ? $model : false; + } + + /** + * 批量保存当前关联数据对象 + * @access public + * @param array $dataSet 数据集 + * @return integer + */ + public function saveAll(array $dataSet) + { + $result = false; + foreach ($dataSet as $key => $data) { + $result = $this->save($data); + } + return $result; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + + return $this->parent->db() + ->alias($model) + ->field($model . '.*') + ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $joinType) + ->group($relation . '.' . $this->foreignKey) + ->having('count(' . $id . ')' . $operator . $count); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { + foreach ($where as $key => $val) { + if (false === strpos($key, '.')) { + $where[$relation . '.' . $key] = $val; + unset($where[$key]); + } + } + } + return $this->parent->db()->alias($model) + ->field($model . '.*') + ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey) + ->where($where); + } + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery)) { + if (isset($this->parent->{$this->localKey})) { + // 关联查询带入关联条件 + $this->query->where($this->foreignKey, $this->parent->{$this->localKey}); + } + $this->baseQuery = true; + } + } + +} diff --git a/thinkphp/library/think/model/relation/HasManyThrough.php b/thinkphp/library/think/model/relation/HasManyThrough.php new file mode 100755 index 0000000..7c268b4 --- /dev/null +++ b/thinkphp/library/think/model/relation/HasManyThrough.php @@ -0,0 +1,144 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Relation; + +class HasManyThrough extends Relation +{ + // 中间关联表外键 + protected $throughKey; + // 中间表模型 + protected $through; + + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $through 中间模型名 + * @param string $foreignKey 关联外键 + * @param string $throughKey 关联外键 + * @param string $localKey 关联主键 + */ + public function __construct(Model $parent, $model, $through, $foreignKey, $throughKey, $localKey) + { + $this->parent = $parent; + $this->model = $model; + $this->through = $through; + $this->foreignKey = $foreignKey; + $this->throughKey = $throughKey; + $this->localKey = $localKey; + $this->query = (new $model)->db(); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return false|\PDOStatement|string|\think\Collection + */ + public function getRelation($subRelation = '', $closure = null) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + + return $this->relation($subRelation)->select(); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + return $this->parent; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + throw new Exception('relation not support: hasWhere'); + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + {} + + /** + * 预载入关联查询 返回模型对象 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + {} + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + {} + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery) && $this->parent->getData()) { + $through = $this->through; + $alias = Loader::parseName(basename(str_replace('\\', '/', $this->model))); + $throughTable = $through::getTable(); + $pk = (new $through)->getPk(); + $throughKey = $this->throughKey; + $modelTable = $this->parent->getTable(); + $this->query->field($alias . '.*')->alias($alias) + ->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey) + ->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey) + ->where($throughTable . '.' . $this->foreignKey, $this->parent->{$this->localKey}); + $this->baseQuery = true; + } + } + +} diff --git a/thinkphp/library/think/model/relation/HasOne.php b/thinkphp/library/think/model/relation/HasOne.php new file mode 100755 index 0000000..7e8fa8d --- /dev/null +++ b/thinkphp/library/think/model/relation/HasOne.php @@ -0,0 +1,189 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Loader; +use think\Model; + +class HasOne extends OneToOne +{ + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $foreignKey 关联外键 + * @param string $localKey 当前模型主键 + * @param string $joinType JOIN类型 + */ + public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER') + { + $this->parent = $parent; + $this->model = $model; + $this->foreignKey = $foreignKey; + $this->localKey = $localKey; + $this->joinType = $joinType; + $this->query = (new $model)->db(); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return array|false|\PDOStatement|string|Model + */ + public function getRelation($subRelation = '', $closure = null) + { + // 执行关联定义方法 + $localKey = $this->localKey; + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + // 判断关联类型执行查询 + $relationModel = $this->query->where($this->foreignKey, $this->parent->$localKey)->relation($subRelation)->find(); + + if ($relationModel) { + $relationModel->setParent(clone $this->parent); + } + + return $relationModel; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @return Query + */ + public function has() + { + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + return $this->parent->db() + ->alias($model) + ->whereExists(function ($query) use ($table, $model, $relation, $localKey, $foreignKey) { + $query->table([$table => $relation])->field($relation . '.' . $foreignKey)->whereExp($model . '.' . $localKey, '=' . $relation . '.' . $foreignKey); + }); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + $table = $this->query->getTable(); + $model = basename(str_replace('\\', '/', get_class($this->parent))); + $relation = basename(str_replace('\\', '/', $this->model)); + if (is_array($where)) { + foreach ($where as $key => $val) { + if (false === strpos($key, '.')) { + $where[$relation . '.' . $key] = $val; + unset($where[$key]); + } + } + } + return $this->parent->db()->alias($model) + ->field($model . '.*') + ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType) + ->where($where); + } + + /** + * 预载入关联查询(数据集) + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + + $range = []; + foreach ($resultSet as $result) { + // 获取关联外键列表 + if (isset($result->$localKey)) { + $range[] = $result->$localKey; + } + } + + if (!empty($range)) { + $data = $this->eagerlyWhere($this, [ + $foreignKey => [ + 'in', + $range, + ], + ], $foreignKey, $relation, $subRelation, $closure); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + // 关联模型 + if (!isset($data[$result->$localKey])) { + $relationModel = null; + } else { + $relationModel = $data[$result->$localKey]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + // 设置关联属性 + $result->setRelation($attr, $relationModel); + } + } + } + } + + /** + * 预载入关联查询(数据) + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + protected function eagerlyOne(&$result, $relation, $subRelation, $closure) + { + $localKey = $this->localKey; + $foreignKey = $this->foreignKey; + $data = $this->eagerlyWhere($this, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure); + + // 关联模型 + if (!isset($data[$result->$localKey])) { + $relationModel = null; + } else { + $relationModel = $data[$result->$localKey]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + if (!empty($this->bindAttr)) { + // 绑定关联属性 + $this->bindAttr($relationModel, $result, $this->bindAttr); + } else { + $result->setRelation(Loader::parseName($relation), $relationModel); + } + } + +} diff --git a/thinkphp/library/think/model/relation/MorphMany.php b/thinkphp/library/think/model/relation/MorphMany.php new file mode 100755 index 0000000..87c2d66 --- /dev/null +++ b/thinkphp/library/think/model/relation/MorphMany.php @@ -0,0 +1,285 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Relation; + +class MorphMany extends Relation +{ + // 多态字段 + protected $morphKey; + protected $morphType; + // 多态类型 + protected $type; + + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $morphKey 关联外键 + * @param string $morphType 多态字段名 + * @param string $type 多态类型 + */ + public function __construct(Model $parent, $model, $morphKey, $morphType, $type) + { + $this->parent = $parent; + $this->model = $model; + $this->type = $type; + $this->morphKey = $morphKey; + $this->morphType = $morphType; + $this->query = (new $model)->db(); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return false|\PDOStatement|string|\think\Collection + */ + public function getRelation($subRelation = '', $closure = null) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $list = $this->relation($subRelation)->select(); + $parent = clone $this->parent; + + foreach ($list as &$model) { + $model->setParent($parent); + } + + return $list; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + throw new Exception('relation not support: has'); + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + throw new Exception('relation not support: hasWhere'); + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + $morphType = $this->morphType; + $morphKey = $this->morphKey; + $type = $this->type; + $range = []; + foreach ($resultSet as $result) { + $pk = $result->getPk(); + // 获取关联外键列表 + if (isset($result->$pk)) { + $range[] = $result->$pk; + } + } + + if (!empty($range)) { + $data = $this->eagerlyMorphToMany([ + $morphKey => ['in', $range], + $morphType => $type, + ], $relation, $subRelation, $closure); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + if (!isset($data[$result->$pk])) { + $data[$result->$pk] = []; + } + foreach ($data[$result->$pk] as &$relationModel) { + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk])); + } + } + } + + /** + * 预载入关联查询 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + $pk = $result->getPk(); + if (isset($result->$pk)) { + $data = $this->eagerlyMorphToMany([ + $this->morphKey => $result->$pk, + $this->morphType => $this->type, + ], $relation, $subRelation, $closure); + + if (!isset($data[$result->$pk])) { + $data[$result->$pk] = []; + } + + foreach ($data[$result->$pk] as &$relationModel) { + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + + $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk])); + } + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + { + $pk = $result->getPk(); + $count = 0; + if (isset($result->$pk)) { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count(); + } + return $count; + } + + /** + * 获取关联统计子查询 + * @access public + * @param \Closure $closure 闭包 + * @return string + */ + public function getRelationCountQuery($closure) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + + return $this->query->where([ + $this->morphKey => [ + 'exp', + '=' . $this->parent->getTable() . '.' . $this->parent->getPk(), + ], + $this->morphType => $this->type, + ])->fetchSql()->count(); + } + + /** + * 多态一对多 关联模型预查询 + * @access public + * @param array $where 关联预查询条件 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param bool|\Closure $closure 闭包 + * @return array + */ + protected function eagerlyMorphToMany($where, $relation, $subRelation = '', $closure = false) + { + // 预载入关联查询 支持嵌套预载入 + if ($closure) { + call_user_func_array($closure, [ & $this]); + } + $list = $this->query->where($where)->with($subRelation)->select(); + $morphKey = $this->morphKey; + // 组装模型数据 + $data = []; + foreach ($list as $set) { + $data[$set->$morphKey][] = $set; + } + return $data; + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @return Model|false + */ + public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + // 保存关联表数据 + $pk = $this->parent->getPk(); + + $model = new $this->model; + $data[$this->morphKey] = $this->parent->$pk; + $data[$this->morphType] = $this->type; + return $model->save($data) ? $model : false; + } + + /** + * 批量保存当前关联数据对象 + * @access public + * @param array $dataSet 数据集 + * @return integer + */ + public function saveAll(array $dataSet) + { + $result = false; + foreach ($dataSet as $key => $data) { + $result = $this->save($data); + } + return $result; + } + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery) && $this->parent->getData()) { + $pk = $this->parent->getPk(); + $map[$this->morphKey] = $this->parent->$pk; + $map[$this->morphType] = $this->type; + $this->query->where($map); + $this->baseQuery = true; + } + } + +} diff --git a/thinkphp/library/think/model/relation/MorphOne.php b/thinkphp/library/think/model/relation/MorphOne.php new file mode 100755 index 0000000..4dfd1c0 --- /dev/null +++ b/thinkphp/library/think/model/relation/MorphOne.php @@ -0,0 +1,229 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Relation; + +class MorphOne extends Relation +{ + // 多态字段 + protected $morphKey; + protected $morphType; + // 多态类型 + protected $type; + + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $model 模型名 + * @param string $morphKey 关联外键 + * @param string $morphType 多态字段名 + * @param string $type 多态类型 + */ + public function __construct(Model $parent, $model, $morphKey, $morphType, $type) + { + $this->parent = $parent; + $this->model = $model; + $this->type = $type; + $this->morphKey = $morphKey; + $this->morphType = $morphType; + $this->query = (new $model)->db(); + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return false|\PDOStatement|string|\think\Collection + */ + public function getRelation($subRelation = '', $closure = null) + { + if ($closure) { + call_user_func_array($closure, [ & $this->query]); + } + $relationModel = $this->relation($subRelation)->find(); + + if ($relationModel) { + $relationModel->setParent(clone $this->parent); + } + + return $relationModel; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + return $this->parent; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + throw new Exception('relation not support: hasWhere'); + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + $morphType = $this->morphType; + $morphKey = $this->morphKey; + $type = $this->type; + $range = []; + foreach ($resultSet as $result) { + $pk = $result->getPk(); + // 获取关联外键列表 + if (isset($result->$pk)) { + $range[] = $result->$pk; + } + } + + if (!empty($range)) { + $data = $this->eagerlyMorphToOne([ + $morphKey => ['in', $range], + $morphType => $type, + ], $relation, $subRelation, $closure); + // 关联属性名 + $attr = Loader::parseName($relation); + // 关联数据封装 + foreach ($resultSet as $result) { + if (!isset($data[$result->$pk])) { + $relationModel = null; + } else { + $relationModel = $data[$result->$pk]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } + + $result->setRelation($attr, $relationModel); + } + } + } + + /** + * 预载入关联查询 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + $pk = $result->getPk(); + if (isset($result->$pk)) { + $pk = $result->$pk; + $data = $this->eagerlyMorphToOne([ + $this->morphKey => $pk, + $this->morphType => $this->type, + ], $relation, $subRelation, $closure); + + if (isset($data[$pk])) { + $relationModel = $data[$pk]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + } else { + $relationModel = null; + } + + $result->setRelation(Loader::parseName($relation), $relationModel); + } + } + + /** + * 多态一对一 关联模型预查询 + * @access public + * @param array $where 关联预查询条件 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param bool|\Closure $closure 闭包 + * @return array + */ + protected function eagerlyMorphToOne($where, $relation, $subRelation = '', $closure = false) + { + // 预载入关联查询 支持嵌套预载入 + if ($closure) { + call_user_func_array($closure, [ & $this]); + } + $list = $this->query->where($where)->with($subRelation)->find(); + $morphKey = $this->morphKey; + // 组装模型数据 + $data = []; + foreach ($list as $set) { + $data[$set->$morphKey][] = $set; + } + return $data; + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @return Model|false + */ + public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + // 保存关联表数据 + $pk = $this->parent->getPk(); + + $model = new $this->model; + $data[$this->morphKey] = $this->parent->$pk; + $data[$this->morphType] = $this->type; + return $model->save($data) ? $model : false; + } + + /** + * 执行基础查询(进执行一次) + * @access protected + * @return void + */ + protected function baseQuery() + { + if (empty($this->baseQuery) && $this->parent->getData()) { + $pk = $this->parent->getPk(); + $map[$this->morphKey] = $this->parent->$pk; + $map[$this->morphType] = $this->type; + $this->query->where($map); + $this->baseQuery = true; + } + } + +} diff --git a/thinkphp/library/think/model/relation/MorphTo.php b/thinkphp/library/think/model/relation/MorphTo.php new file mode 100755 index 0000000..e1a9db5 --- /dev/null +++ b/thinkphp/library/think/model/relation/MorphTo.php @@ -0,0 +1,275 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Relation; + +class MorphTo extends Relation +{ + // 多态字段 + protected $morphKey; + protected $morphType; + // 多态别名 + protected $alias; + protected $relation; + + /** + * 构造函数 + * @access public + * @param Model $parent 上级模型对象 + * @param string $morphType 多态字段名 + * @param string $morphKey 外键名 + * @param array $alias 多态别名定义 + * @param string $relation 关联名 + */ + public function __construct(Model $parent, $morphType, $morphKey, $alias = [], $relation = null) + { + $this->parent = $parent; + $this->morphType = $morphType; + $this->morphKey = $morphKey; + $this->alias = $alias; + $this->relation = $relation; + } + + /** + * 延迟获取关联数据 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包查询条件 + * @return mixed + */ + public function getRelation($subRelation = '', $closure = null) + { + $morphKey = $this->morphKey; + $morphType = $this->morphType; + // 多态模型 + $model = $this->parseModel($this->parent->$morphType); + // 主键数据 + $pk = $this->parent->$morphKey; + $relationModel = (new $model)->relation($subRelation)->find($pk); + + if ($relationModel) { + $relationModel->setParent(clone $this->parent); + } + return $relationModel; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param string $operator 比较操作符 + * @param integer $count 个数 + * @param string $id 关联表的统计字段 + * @param string $joinType JOIN类型 + * @return Query + */ + public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER') + { + return $this->parent; + } + + /** + * 根据关联条件查询当前模型 + * @access public + * @param mixed $where 查询条件(数组或者闭包) + * @return Query + */ + public function hasWhere($where = []) + { + throw new Exception('relation not support: hasWhere'); + } + + /** + * 解析模型的完整命名空间 + * @access public + * @param string $model 模型名(或者完整类名) + * @return string + */ + protected function parseModel($model) + { + if (isset($this->alias[$model])) { + $model = $this->alias[$model]; + } + if (false === strpos($model, '\\')) { + $path = explode('\\', get_class($this->parent)); + array_pop($path); + array_push($path, Loader::parseName($model, 1)); + $model = implode('\\', $path); + } + return $model; + } + + /** + * 设置多态别名 + * @access public + * @param array $alias 别名定义 + * @return $this + */ + public function setAlias($alias) + { + $this->alias = $alias; + return $this; + } + + /** + * 移除关联查询参数 + * @access public + * @return $this + */ + public function removeOption() + { + return $this; + } + + /** + * 预载入关联查询 + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + * @throws Exception + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + $morphKey = $this->morphKey; + $morphType = $this->morphType; + $range = []; + foreach ($resultSet as $result) { + // 获取关联外键列表 + if (!empty($result->$morphKey)) { + $range[$result->$morphType][] = $result->$morphKey; + } + } + + if (!empty($range)) { + // 关联属性名 + $attr = Loader::parseName($relation); + foreach ($range as $key => $val) { + // 多态类型映射 + $model = $this->parseModel($key); + $obj = new $model; + $pk = $obj->getPk(); + $list = $obj->all($val, $subRelation); + $data = []; + foreach ($list as $k => $vo) { + $data[$vo->$pk] = $vo; + } + foreach ($resultSet as $result) { + if ($key == $result->$morphType) { + // 关联模型 + if (!isset($data[$result->$morphKey])) { + throw new Exception('relation data not exists :' . $this->model); + } else { + $relationModel = $data[$result->$morphKey]; + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + + $result->setRelation($attr, $relationModel); + } + } + } + } + } + } + + /** + * 预载入关联查询 + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + $morphKey = $this->morphKey; + $morphType = $this->morphType; + // 多态类型映射 + $model = $this->parseModel($result->{$this->morphType}); + $this->eagerlyMorphToOne($model, $relation, $result, $subRelation); + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + { + } + + /** + * 多态MorphTo 关联模型预查询 + * @access public + * @param object $model 关联模型对象 + * @param string $relation 关联名 + * @param $result + * @param string $subRelation 子关联 + * @return void + */ + protected function eagerlyMorphToOne($model, $relation, &$result, $subRelation = '') + { + // 预载入关联查询 支持嵌套预载入 + $pk = $this->parent->{$this->morphKey}; + $data = (new $model)->with($subRelation)->find($pk); + if ($data) { + $data->setParent(clone $result); + $data->isUpdate(true); + } + $result->setRelation(Loader::parseName($relation), $data ?: null); + } + + /** + * 添加关联数据 + * @access public + * @param Model $model 关联模型对象 + * @param string $type 多态类型 + * @return Model + */ + public function associate($model, $type = '') + { + $morphKey = $this->morphKey; + $morphType = $this->morphType; + $pk = $model->getPk(); + + $this->parent->setAttr($morphKey, $model->$pk); + $this->parent->setAttr($morphType, $type ?: get_class($model)); + $this->parent->save(); + + return $this->parent->setRelation($this->relation, $model); + } + + /** + * 注销关联数据 + * @access public + * @return Model + */ + public function dissociate() + { + $morphKey = $this->morphKey; + $morphType = $this->morphType; + + $this->parent->setAttr($morphKey, null); + $this->parent->setAttr($morphType, null); + $this->parent->save(); + + return $this->parent->setRelation($this->relation, null); + } + +} diff --git a/thinkphp/library/think/model/relation/OneToOne.php b/thinkphp/library/think/model/relation/OneToOne.php new file mode 100755 index 0000000..66d86a9 --- /dev/null +++ b/thinkphp/library/think/model/relation/OneToOne.php @@ -0,0 +1,324 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\model\relation; + +use think\db\Query; +use think\Exception; +use think\Loader; +use think\Model; +use think\model\Relation; + +/** + * Class OneToOne + * @package think\model\relation + * + */ +abstract class OneToOne extends Relation +{ + // 预载入方式 0 -JOIN 1 -IN + protected $eagerlyType = 1; + // 当前关联的JOIN类型 + protected $joinType; + // 要绑定的属性 + protected $bindAttr = []; + // 关联方法名 + protected $relation; + + /** + * 设置join类型 + * @access public + * @param string $type JOIN类型 + * @return $this + */ + public function joinType($type) + { + $this->joinType = $type; + return $this; + } + + /** + * 预载入关联查询(JOIN方式) + * @access public + * @param Query $query 查询对象 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param \Closure $closure 闭包条件 + * @param bool $first + * @return void + */ + public function eagerly(Query $query, $relation, $subRelation, $closure, $first) + { + $name = Loader::parseName(basename(str_replace('\\', '/', $query->getModel()))); + $alias = $name; + if ($first) { + $table = $query->getTable(); + $query->table([$table => $alias]); + if ($query->getOptions('field')) { + $field = $query->getOptions('field'); + $query->removeOption('field'); + } else { + $field = true; + } + $query->field($field, false, $table, $alias); + $field = null; + } + + // 预载入封装 + $joinTable = $this->query->getTable(); + $joinAlias = $relation; + $query->via($joinAlias); + + if ($this instanceof BelongsTo) { + $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType); + } else { + $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType); + } + + if ($closure) { + // 执行闭包查询 + call_user_func_array($closure, [ & $query]); + // 使用withField指定获取关联的字段,如 + // $query->where(['id'=>1])->withField('id,name'); + if ($query->getOptions('with_field')) { + $field = $query->getOptions('with_field'); + $query->removeOption('with_field'); + } + } elseif (isset($this->option['field'])) { + $field = $this->option['field']; + } + $query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__'); + } + + /** + * 预载入关联查询(数据集) + * @param array $resultSet + * @param string $relation + * @param string $subRelation + * @param \Closure $closure + * @return mixed + */ + abstract protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure); + + /** + * 预载入关联查询(数据) + * @param Model $result + * @param string $relation + * @param string $subRelation + * @param \Closure $closure + * @return mixed + */ + abstract protected function eagerlyOne(&$result, $relation, $subRelation, $closure); + + /** + * 预载入关联查询(数据集) + * @access public + * @param array $resultSet 数据集 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure) + { + if (1 == $this->eagerlyType) { + // IN查询 + $this->eagerlySet($resultSet, $relation, $subRelation, $closure); + } else { + // 模型关联组装 + foreach ($resultSet as $result) { + $this->match($this->model, $relation, $result); + } + } + } + + /** + * 预载入关联查询(数据) + * @access public + * @param Model $result 数据对象 + * @param string $relation 当前关联名 + * @param string $subRelation 子关联名 + * @param \Closure $closure 闭包 + * @return void + */ + public function eagerlyResult(&$result, $relation, $subRelation, $closure) + { + if (1 == $this->eagerlyType) { + // IN查询 + $this->eagerlyOne($result, $relation, $subRelation, $closure); + } else { + // 模型关联组装 + $this->match($this->model, $relation, $result); + } + } + + /** + * 保存(新增)当前关联数据对象 + * @access public + * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键 + * @return Model|false + */ + public function save($data) + { + if ($data instanceof Model) { + $data = $data->getData(); + } + $model = new $this->model; + // 保存关联表数据 + $data[$this->foreignKey] = $this->parent->{$this->localKey}; + return $model->save($data) ? $model : false; + } + + /** + * 设置预载入方式 + * @access public + * @param integer $type 预载入方式 0 JOIN查询 1 IN查询 + * @return $this + */ + public function setEagerlyType($type) + { + $this->eagerlyType = $type; + return $this; + } + + /** + * 获取预载入方式 + * @access public + * @return integer + */ + public function getEagerlyType() + { + return $this->eagerlyType; + } + + /** + * 绑定关联表的属性到父模型属性 + * @access public + * @param mixed $attr 要绑定的属性列表 + * @return $this + */ + public function bind($attr) + { + if (is_string($attr)) { + $attr = explode(',', $attr); + } + $this->bindAttr = $attr; + return $this; + } + + /** + * 获取绑定属性 + * @access public + * @return array + */ + public function getBindAttr() + { + return $this->bindAttr; + } + + /** + * 关联统计 + * @access public + * @param Model $result 数据对象 + * @param \Closure $closure 闭包 + * @return integer + */ + public function relationCount($result, $closure) + { + } + + /** + * 一对一 关联模型预查询拼装 + * @access public + * @param string $model 模型名称 + * @param string $relation 关联名 + * @param Model $result 模型对象实例 + * @return void + */ + protected function match($model, $relation, &$result) + { + // 重新组装模型数据 + foreach ($result->getData() as $key => $val) { + if (strpos($key, '__')) { + list($name, $attr) = explode('__', $key, 2); + if ($name == $relation) { + $list[$name][$attr] = $val; + unset($result->$key); + } + } + } + + if (isset($list[$relation])) { + $relationModel = new $model($list[$relation]); + $relationModel->setParent(clone $result); + $relationModel->isUpdate(true); + + if (!empty($this->bindAttr)) { + $this->bindAttr($relationModel, $result, $this->bindAttr); + } + } else { + $relationModel = null; + } + $result->setRelation(Loader::parseName($relation), $relationModel); + } + + /** + * 绑定关联属性到父模型 + * @access protected + * @param Model $model 关联模型对象 + * @param Model $result 父模型对象 + * @param array $bindAttr 绑定属性 + * @return void + * @throws Exception + */ + protected function bindAttr($model, &$result, $bindAttr) + { + foreach ($bindAttr as $key => $attr) { + $key = is_numeric($key) ? $attr : $key; + if (isset($result->$key)) { + throw new Exception('bind attr has exists:' . $key); + } else { + $result->setAttr($key, $model ? $model->$attr : null); + } + } + } + + /** + * 一对一 关联模型预查询(IN方式) + * @access public + * @param object $model 关联模型对象 + * @param array $where 关联预查询条件 + * @param string $key 关联键名 + * @param string $relation 关联名 + * @param string $subRelation 子关联 + * @param bool|\Closure $closure + * @return array + */ + protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false) + { + // 预载入关联查询 支持嵌套预载入 + if ($closure) { + call_user_func_array($closure, [ & $model]); + if ($field = $model->getOptions('with_field')) { + $model->field($field)->removeOption('with_field'); + } + } + $list = $model->where($where)->with($subRelation)->select(); + + // 组装模型数据 + $data = []; + foreach ($list as $set) { + $data[$set->$key] = $set; + } + return $data; + } + +} diff --git a/thinkphp/library/think/paginator/Collection.php b/thinkphp/library/think/paginator/Collection.php new file mode 100755 index 0000000..862d2ce --- /dev/null +++ b/thinkphp/library/think/paginator/Collection.php @@ -0,0 +1,83 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\paginator; + +use Exception; +use think\Paginator; + +/** + * Class Collection + * @package think\paginator + * @method integer total() + * @method integer listRows() + * @method integer currentPage() + * @method string render() + * @method Paginator fragment($fragment) + * @method Paginator appends($key, $value) + * @method integer lastPage() + * @method boolean hasPages() + */ +class Collection extends \think\Collection +{ + + /** @var Paginator */ + protected $paginator; + + public function __construct($items = [], Paginator $paginator = null) + { + $this->paginator = $paginator; + parent::__construct($items); + } + + public static function make($items = [], Paginator $paginator = null) + { + return new static($items, $paginator); + } + + public function toArray() + { + if ($this->paginator) { + try { + $total = $this->total(); + } catch (Exception $e) { + $total = null; + } + /* + return [ + 'total' => $total, + 'per_page' => $this->listRows(), + 'current_page' => $this->currentPage(), + 'data' => parent::toArray() + ]; + */ + //modify by GZShangTao + return [ + 'Total' => $total, + 'PerPage' => $this->listRows(), + 'CurrentPage' => $this->currentPage(), + 'TotalPage' => $this->getTotalPage(), + 'Rows' => parent::toArray() + ]; + } else { + return parent::toArray(); + } + } + + public function __call($method, $args) + { + if ($this->paginator && method_exists($this->paginator, $method)) { + return call_user_func_array([$this->paginator, $method], $args); + } else { + throw new Exception('method not exists:' . __CLASS__ . '->' . $method); + } + } +} \ No newline at end of file diff --git a/thinkphp/library/think/paginator/driver/Bootstrap.php b/thinkphp/library/think/paginator/driver/Bootstrap.php new file mode 100755 index 0000000..58fa943 --- /dev/null +++ b/thinkphp/library/think/paginator/driver/Bootstrap.php @@ -0,0 +1,205 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\paginator\driver; + +use think\Paginator; + +class Bootstrap extends Paginator +{ + + /** + * 上一页按钮 + * @param string $text + * @return string + */ + protected function getPreviousButton($text = "&laquo;") + { + + if ($this->currentPage() <= 1) { + return $this->getDisabledTextWrapper($text); + } + + $url = $this->url( + $this->currentPage() - 1 + ); + + return $this->getPageLinkWrapper($url, $text); + } + + /** + * 下一页按钮 + * @param string $text + * @return string + */ + protected function getNextButton($text = '&raquo;') + { + if (!$this->hasMore) { + return $this->getDisabledTextWrapper($text); + } + + $url = $this->url($this->currentPage() + 1); + + return $this->getPageLinkWrapper($url, $text); + } + + /** + * 页码按钮 + * @return string + */ + protected function getLinks() + { + if ($this->simple) + return ''; + + $block = [ + 'first' => null, + 'slider' => null, + 'last' => null + ]; + + $side = 3; + $window = $side * 2; + + if ($this->lastPage < $window + 6) { + $block['first'] = $this->getUrlRange(1, $this->lastPage); + } elseif ($this->currentPage <= $window) { + $block['first'] = $this->getUrlRange(1, $window + 2); + $block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage); + } elseif ($this->currentPage > ($this->lastPage - $window)) { + $block['first'] = $this->getUrlRange(1, 2); + $block['last'] = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage); + } else { + $block['first'] = $this->getUrlRange(1, 2); + $block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side); + $block['last'] = $this->getUrlRange($this->lastPage - 1, $this->lastPage); + } + + $html = ''; + + if (is_array($block['first'])) { + $html .= $this->getUrlLinks($block['first']); + } + + if (is_array($block['slider'])) { + $html .= $this->getDots(); + $html .= $this->getUrlLinks($block['slider']); + } + + if (is_array($block['last'])) { + $html .= $this->getDots(); + $html .= $this->getUrlLinks($block['last']); + } + + return $html; + } + + /** + * 渲染分页html + * @return mixed + */ + public function render() + { + if ($this->hasPages()) { + if ($this->simple) { + return sprintf( + '<ul class="pager">%s %s</ul>', + $this->getPreviousButton(), + $this->getNextButton() + ); + } else { + return sprintf( + '<ul class="pagination">%s %s %s</ul>', + $this->getPreviousButton(), + $this->getLinks(), + $this->getNextButton() + ); + } + } + } + + /** + * 生成一个可点击的按钮 + * + * @param string $url + * @param int $page + * @return string + */ + protected function getAvailablePageWrapper($url, $page) + { + return '<li><a href="' . htmlentities($url) . '">' . $page . '</a></li>'; + } + + /** + * 生成一个禁用的按钮 + * + * @param string $text + * @return string + */ + protected function getDisabledTextWrapper($text) + { + return '<li class="disabled"><span>' . $text . '</span></li>'; + } + + /** + * 生成一个激活的按钮 + * + * @param string $text + * @return string + */ + protected function getActivePageWrapper($text) + { + return '<li class="active"><span>' . $text . '</span></li>'; + } + + /** + * 生成省略号按钮 + * + * @return string + */ + protected function getDots() + { + return $this->getDisabledTextWrapper('...'); + } + + /** + * 批量生成页码按钮. + * + * @param array $urls + * @return string + */ + protected function getUrlLinks(array $urls) + { + $html = ''; + + foreach ($urls as $page => $url) { + $html .= $this->getPageLinkWrapper($url, $page); + } + + return $html; + } + + /** + * 生成普通页码按钮 + * + * @param string $url + * @param int $page + * @return string + */ + protected function getPageLinkWrapper($url, $page) + { + if ($page == $this->currentPage()) { + return $this->getActivePageWrapper($page); + } + + return $this->getAvailablePageWrapper($url, $page); + } +} diff --git a/thinkphp/library/think/process/Builder.php b/thinkphp/library/think/process/Builder.php new file mode 100755 index 0000000..da56163 --- /dev/null +++ b/thinkphp/library/think/process/Builder.php @@ -0,0 +1,233 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process; + +use think\Process; + +class Builder +{ + private $arguments; + private $cwd; + private $env = null; + private $input; + private $timeout = 60; + private $options = []; + private $inheritEnv = true; + private $prefix = []; + private $outputDisabled = false; + + /** + * 构造方法 + * @param string[] $arguments 参数 + */ + public function __construct(array $arguments = []) + { + $this->arguments = $arguments; + } + + /** + * 创建一个实例 + * @param string[] $arguments 参数 + * @return self + */ + public static function create(array $arguments = []) + { + return new static($arguments); + } + + /** + * 添加一个参数 + * @param string $argument 参数 + * @return self + */ + public function add($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + /** + * 添加一个前缀 + * @param string|array $prefix + * @return self + */ + public function setPrefix($prefix) + { + $this->prefix = is_array($prefix) ? $prefix : [$prefix]; + + return $this; + } + + /** + * 设置参数 + * @param string[] $arguments + * @return self + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + + return $this; + } + + /** + * 设置工作目录 + * @param null|string $cwd + * @return self + */ + public function setWorkingDirectory($cwd) + { + $this->cwd = $cwd; + + return $this; + } + + /** + * 是否初始化环境变量 + * @param bool $inheritEnv + * @return self + */ + public function inheritEnvironmentVariables($inheritEnv = true) + { + $this->inheritEnv = $inheritEnv; + + return $this; + } + + /** + * 设置环境变量 + * @param string $name + * @param null|string $value + * @return self + */ + public function setEnv($name, $value) + { + $this->env[$name] = $value; + + return $this; + } + + /** + * 添加环境变量 + * @param array $variables + * @return self + */ + public function addEnvironmentVariables(array $variables) + { + $this->env = array_replace($this->env, $variables); + + return $this; + } + + /** + * 设置输入 + * @param mixed $input + * @return self + */ + public function setInput($input) + { + $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input); + + return $this; + } + + /** + * 设置超时时间 + * @param float|null $timeout + * @return self + */ + public function setTimeout($timeout) + { + if (null === $timeout) { + $this->timeout = null; + + return $this; + } + + $timeout = (float) $timeout; + + if ($timeout < 0) { + throw new \InvalidArgumentException('The timeout value must be a valid positive integer or float number.'); + } + + $this->timeout = $timeout; + + return $this; + } + + /** + * 设置proc_open选项 + * @param string $name + * @param string $value + * @return self + */ + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + /** + * 禁止输出 + * @return self + */ + public function disableOutput() + { + $this->outputDisabled = true; + + return $this; + } + + /** + * 开启输出 + * @return self + */ + public function enableOutput() + { + $this->outputDisabled = false; + + return $this; + } + + /** + * 创建一个Process实例 + * @return Process + */ + public function getProcess() + { + if (0 === count($this->prefix) && 0 === count($this->arguments)) { + throw new \LogicException('You must add() command arguments before calling getProcess().'); + } + + $options = $this->options; + + $arguments = array_merge($this->prefix, $this->arguments); + $script = implode(' ', array_map([__NAMESPACE__ . '\\Utils', 'escapeArgument'], $arguments)); + + if ($this->inheritEnv) { + // include $_ENV for BC purposes + $env = array_replace($_ENV, $_SERVER, $this->env); + } else { + $env = $this->env; + } + + $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options); + + if ($this->outputDisabled) { + $process->disableOutput(); + } + + return $process; + } +} diff --git a/thinkphp/library/think/process/Utils.php b/thinkphp/library/think/process/Utils.php new file mode 100755 index 0000000..f94c648 --- /dev/null +++ b/thinkphp/library/think/process/Utils.php @@ -0,0 +1,75 @@ +<?php +// +---------------------------------------------------------------------- +// | TopThink [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2015 http://www.topthink.com All rights reserved. +// +---------------------------------------------------------------------- +// | Author: zhangyajun <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process; + +class Utils +{ + + /** + * 转义字符串 + * @param string $argument + * @return string + */ + public static function escapeArgument($argument) + { + + if ('' === $argument) { + return escapeshellarg($argument); + } + $escapedArgument = ''; + $quote = false; + foreach (preg_split('/(")/i', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { + if ('"' === $part) { + $escapedArgument .= '\\"'; + } elseif (self::isSurroundedBy($part, '%')) { + // Avoid environment variable expansion + $escapedArgument .= '^%"' . substr($part, 1, -1) . '"^%'; + } else { + // escape trailing backslash + if ('\\' === substr($part, -1)) { + $part .= '\\'; + } + $quote = true; + $escapedArgument .= $part; + } + } + if ($quote) { + $escapedArgument = '"' . $escapedArgument . '"'; + } + return $escapedArgument; + } + + /** + * 验证并进行规范化Process输入。 + * @param string $caller + * @param mixed $input + * @return string + * @throws \InvalidArgumentException + */ + public static function validateInput($caller, $input) + { + if (null !== $input) { + if (is_resource($input)) { + return $input; + } + if (is_scalar($input)) { + return (string) $input; + } + throw new \InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller)); + } + return $input; + } + + private static function isSurroundedBy($arg, $char) + { + return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1]; + } + +} diff --git a/thinkphp/library/think/process/exception/Faild.php b/thinkphp/library/think/process/exception/Faild.php new file mode 100755 index 0000000..a8d203a --- /dev/null +++ b/thinkphp/library/think/process/exception/Faild.php @@ -0,0 +1,43 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\exception; + + +use think\Process; + +class Failed extends \RuntimeException +{ + + private $process; + + public function __construct(Process $process) + { + if ($process->isSuccessful()) { + throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); + } + + $error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText()); + + if (!$process->isOutputDisabled()) { + $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput()); + } + + parent::__construct($error); + + $this->process = $process; + } + + public function getProcess() + { + return $this->process; + } +} diff --git a/thinkphp/library/think/process/exception/Failed.php b/thinkphp/library/think/process/exception/Failed.php new file mode 100755 index 0000000..5295082 --- /dev/null +++ b/thinkphp/library/think/process/exception/Failed.php @@ -0,0 +1,42 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\exception; + +use think\Process; + +class Failed extends \RuntimeException +{ + + private $process; + + public function __construct(Process $process) + { + if ($process->isSuccessful()) { + throw new \InvalidArgumentException('Expected a failed process, but the given process was successful.'); + } + + $error = sprintf('The command "%s" failed.' . "\nExit Code: %s(%s)", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText()); + + if (!$process->isOutputDisabled()) { + $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s", $process->getOutput(), $process->getErrorOutput()); + } + + parent::__construct($error); + + $this->process = $process; + } + + public function getProcess() + { + return $this->process; + } +} diff --git a/thinkphp/library/think/process/exception/Timeout.php b/thinkphp/library/think/process/exception/Timeout.php new file mode 100755 index 0000000..d5f1162 --- /dev/null +++ b/thinkphp/library/think/process/exception/Timeout.php @@ -0,0 +1,61 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\exception; + +use think\Process; + +class Timeout extends \RuntimeException +{ + + const TYPE_GENERAL = 1; + const TYPE_IDLE = 2; + + private $process; + private $timeoutType; + + public function __construct(Process $process, $timeoutType) + { + $this->process = $process; + $this->timeoutType = $timeoutType; + + parent::__construct(sprintf('The process "%s" exceeded the timeout of %s seconds.', $process->getCommandLine(), $this->getExceededTimeout())); + } + + public function getProcess() + { + return $this->process; + } + + public function isGeneralTimeout() + { + return $this->timeoutType === self::TYPE_GENERAL; + } + + public function isIdleTimeout() + { + return $this->timeoutType === self::TYPE_IDLE; + } + + public function getExceededTimeout() + { + switch ($this->timeoutType) { + case self::TYPE_GENERAL: + return $this->process->getTimeout(); + + case self::TYPE_IDLE: + return $this->process->getIdleTimeout(); + + default: + throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)); + } + } +} diff --git a/thinkphp/library/think/process/pipes/Pipes.php b/thinkphp/library/think/process/pipes/Pipes.php new file mode 100755 index 0000000..82396b8 --- /dev/null +++ b/thinkphp/library/think/process/pipes/Pipes.php @@ -0,0 +1,93 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\pipes; + +abstract class Pipes +{ + + /** @var array */ + public $pipes = []; + + /** @var string */ + protected $inputBuffer = ''; + /** @var resource|null */ + protected $input; + + /** @var bool */ + private $blocked = true; + + const CHUNK_SIZE = 16384; + + /** + * 返回用于 proc_open 描述符的数组 + * @return array + */ + abstract public function getDescriptors(); + + /** + * 返回一个数组的索引由其相关的流,以防这些管道使用的临时文件的文件名。 + * @return string[] + */ + abstract public function getFiles(); + + /** + * 文件句柄和管道中读取数据。 + * @param bool $blocking 是否使用阻塞调用 + * @param bool $close 是否要关闭管道,如果他们已经到达 EOF。 + * @return string[] + */ + abstract public function readAndWrite($blocking, $close = false); + + /** + * 返回当前状态如果有打开的文件句柄或管道。 + * @return bool + */ + abstract public function areOpen(); + + /** + * {@inheritdoc} + */ + public function close() + { + foreach ($this->pipes as $pipe) { + fclose($pipe); + } + $this->pipes = []; + } + + /** + * 检查系统调用已被中断 + * @return bool + */ + protected function hasSystemCallBeenInterrupted() + { + $lastError = error_get_last(); + + return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call'); + } + + protected function unblock() + { + if (!$this->blocked) { + return; + } + + foreach ($this->pipes as $pipe) { + stream_set_blocking($pipe, 0); + } + if (null !== $this->input) { + stream_set_blocking($this->input, 0); + } + + $this->blocked = false; + } +} diff --git a/thinkphp/library/think/process/pipes/Unix.php b/thinkphp/library/think/process/pipes/Unix.php new file mode 100755 index 0000000..fd99a5d --- /dev/null +++ b/thinkphp/library/think/process/pipes/Unix.php @@ -0,0 +1,196 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\pipes; + +use think\Process; + +class Unix extends Pipes +{ + + /** @var bool */ + private $ttyMode; + /** @var bool */ + private $ptyMode; + /** @var bool */ + private $disableOutput; + + public function __construct($ttyMode, $ptyMode, $input, $disableOutput) + { + $this->ttyMode = (bool) $ttyMode; + $this->ptyMode = (bool) $ptyMode; + $this->disableOutput = (bool) $disableOutput; + + if (is_resource($input)) { + $this->input = $input; + } else { + $this->inputBuffer = (string) $input; + } + } + + public function __destruct() + { + $this->close(); + } + + /** + * {@inheritdoc} + */ + public function getDescriptors() + { + if ($this->disableOutput) { + $nullstream = fopen('/dev/null', 'c'); + + return [ + ['pipe', 'r'], + $nullstream, + $nullstream, + ]; + } + + if ($this->ttyMode) { + return [ + ['file', '/dev/tty', 'r'], + ['file', '/dev/tty', 'w'], + ['file', '/dev/tty', 'w'], + ]; + } + + if ($this->ptyMode && Process::isPtySupported()) { + return [ + ['pty'], + ['pty'], + ['pty'], + ]; + } + + return [ + ['pipe', 'r'], + ['pipe', 'w'], // stdout + ['pipe', 'w'], // stderr + ]; + } + + /** + * {@inheritdoc} + */ + public function getFiles() + { + return []; + } + + /** + * {@inheritdoc} + */ + public function readAndWrite($blocking, $close = false) + { + + if (1 === count($this->pipes) && [0] === array_keys($this->pipes)) { + fclose($this->pipes[0]); + unset($this->pipes[0]); + } + + if (empty($this->pipes)) { + return []; + } + + $this->unblock(); + + $read = []; + + if (null !== $this->input) { + $r = array_merge($this->pipes, ['input' => $this->input]); + } else { + $r = $this->pipes; + } + + unset($r[0]); + + $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null; + $e = null; + + if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { + + if (!$this->hasSystemCallBeenInterrupted()) { + $this->pipes = []; + } + + return $read; + } + + if (0 === $n) { + return $read; + } + + foreach ($r as $pipe) { + + $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input'; + $data = ''; + while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) { + $data .= $dataread; + } + + if ('' !== $data) { + if ('input' === $type) { + $this->inputBuffer .= $data; + } else { + $read[$type] = $data; + } + } + + if (false === $data || (true === $close && feof($pipe) && '' === $data)) { + if ('input' === $type) { + $this->input = null; + } else { + fclose($this->pipes[$type]); + unset($this->pipes[$type]); + } + } + } + + if (null !== $w && 0 < count($w)) { + while (strlen($this->inputBuffer)) { + $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k + if ($written > 0) { + $this->inputBuffer = (string) substr($this->inputBuffer, $written); + } else { + break; + } + } + } + + if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { + fclose($this->pipes[0]); + unset($this->pipes[0]); + } + + return $read; + } + + /** + * {@inheritdoc} + */ + public function areOpen() + { + return (bool) $this->pipes; + } + + /** + * 创建一个新的 UnixPipes 实例 + * @param Process $process + * @param string|resource $input + * @return self + */ + public static function create(Process $process, $input) + { + return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled()); + } +} diff --git a/thinkphp/library/think/process/pipes/Windows.php b/thinkphp/library/think/process/pipes/Windows.php new file mode 100755 index 0000000..bba7e9b --- /dev/null +++ b/thinkphp/library/think/process/pipes/Windows.php @@ -0,0 +1,228 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: yunwuxin <448901948@qq.com> +// +---------------------------------------------------------------------- + +namespace think\process\pipes; + +use think\Process; + +class Windows extends Pipes +{ + + /** @var array */ + private $files = []; + /** @var array */ + private $fileHandles = []; + /** @var array */ + private $readBytes = [ + Process::STDOUT => 0, + Process::STDERR => 0, + ]; + /** @var bool */ + private $disableOutput; + + public function __construct($disableOutput, $input) + { + $this->disableOutput = (bool) $disableOutput; + + if (!$this->disableOutput) { + + $this->files = [ + Process::STDOUT => tempnam(sys_get_temp_dir(), 'sf_proc_stdout'), + Process::STDERR => tempnam(sys_get_temp_dir(), 'sf_proc_stderr'), + ]; + foreach ($this->files as $offset => $file) { + $this->fileHandles[$offset] = fopen($this->files[$offset], 'rb'); + if (false === $this->fileHandles[$offset]) { + throw new \RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable'); + } + } + } + + if (is_resource($input)) { + $this->input = $input; + } else { + $this->inputBuffer = $input; + } + } + + public function __destruct() + { + $this->close(); + $this->removeFiles(); + } + + /** + * {@inheritdoc} + */ + public function getDescriptors() + { + if ($this->disableOutput) { + $nullstream = fopen('NUL', 'c'); + + return [ + ['pipe', 'r'], + $nullstream, + $nullstream, + ]; + } + + return [ + ['pipe', 'r'], + ['file', 'NUL', 'w'], + ['file', 'NUL', 'w'], + ]; + } + + /** + * {@inheritdoc} + */ + public function getFiles() + { + return $this->files; + } + + /** + * {@inheritdoc} + */ + public function readAndWrite($blocking, $close = false) + { + $this->write($blocking, $close); + + $read = []; + $fh = $this->fileHandles; + foreach ($fh as $type => $fileHandle) { + if (0 !== fseek($fileHandle, $this->readBytes[$type])) { + continue; + } + $data = ''; + $dataread = null; + while (!feof($fileHandle)) { + if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) { + $data .= $dataread; + } + } + if (0 < $length = strlen($data)) { + $this->readBytes[$type] += $length; + $read[$type] = $data; + } + + if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) { + fclose($this->fileHandles[$type]); + unset($this->fileHandles[$type]); + } + } + + return $read; + } + + /** + * {@inheritdoc} + */ + public function areOpen() + { + return (bool) $this->pipes && (bool) $this->fileHandles; + } + + /** + * {@inheritdoc} + */ + public function close() + { + parent::close(); + foreach ($this->fileHandles as $handle) { + fclose($handle); + } + $this->fileHandles = []; + } + + /** + * 创建一个新的 WindowsPipes 实例。 + * @param Process $process + * @param $input + * @return self + */ + public static function create(Process $process, $input) + { + return new static($process->isOutputDisabled(), $input); + } + + /** + * 删除临时文件 + */ + private function removeFiles() + { + foreach ($this->files as $filename) { + if (file_exists($filename)) { + @unlink($filename); + } + } + $this->files = []; + } + + /** + * 写入到 stdin 输入 + * @param bool $blocking + * @param bool $close + */ + private function write($blocking, $close) + { + if (empty($this->pipes)) { + return; + } + + $this->unblock(); + + $r = null !== $this->input ? ['input' => $this->input] : null; + $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null; + $e = null; + + if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) { + if (!$this->hasSystemCallBeenInterrupted()) { + $this->pipes = []; + } + + return; + } + + if (0 === $n) { + return; + } + + if (null !== $w && 0 < count($r)) { + $data = ''; + while ($dataread = fread($r['input'], self::CHUNK_SIZE)) { + $data .= $dataread; + } + + $this->inputBuffer .= $data; + + if (false === $data || (true === $close && feof($r['input']) && '' === $data)) { + $this->input = null; + } + } + + if (null !== $w && 0 < count($w)) { + while (strlen($this->inputBuffer)) { + $written = fwrite($w[0], $this->inputBuffer, 2 << 18); + if ($written > 0) { + $this->inputBuffer = (string) substr($this->inputBuffer, $written); + } else { + break; + } + } + } + + if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) { + fclose($this->pipes[0]); + unset($this->pipes[0]); + } + } +} diff --git a/thinkphp/library/think/response/Json.php b/thinkphp/library/think/response/Json.php new file mode 100755 index 0000000..538fc5a --- /dev/null +++ b/thinkphp/library/think/response/Json.php @@ -0,0 +1,51 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Response; + +class Json extends Response +{ + // 输出参数 + protected $options = [ + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + protected $contentType = 'application/json'; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + * @throws \Exception + */ + protected function output($data) + { + try { + // 返回JSON数据格式到客户端 包含状态信息 + $data = json_encode($data, $this->options['json_encode_param']); + + if ($data === false) { + throw new \InvalidArgumentException(json_last_error_msg()); + } + + return $data; + } catch (\Exception $e) { + if ($e->getPrevious()) { + throw $e->getPrevious(); + } + throw $e; + } + } + +} diff --git a/thinkphp/library/think/response/Jsonp.php b/thinkphp/library/think/response/Jsonp.php new file mode 100755 index 0000000..de8fb30 --- /dev/null +++ b/thinkphp/library/think/response/Jsonp.php @@ -0,0 +1,58 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Request; +use think\Response; + +class Jsonp extends Response +{ + // 输出参数 + protected $options = [ + 'var_jsonp_handler' => 'callback', + 'default_jsonp_handler' => 'jsonpReturn', + 'json_encode_param' => JSON_UNESCAPED_UNICODE, + ]; + + protected $contentType = 'application/javascript'; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + * @throws \Exception + */ + protected function output($data) + { + try { + // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取<xiaobo.sun@qq.com>] + $var_jsonp_handler = Request::instance()->param($this->options['var_jsonp_handler'], ""); + $handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler']; + + $data = json_encode($data, $this->options['json_encode_param']); + + if ($data === false) { + throw new \InvalidArgumentException(json_last_error_msg()); + } + + $data = $handler . '(' . $data . ');'; + return $data; + } catch (\Exception $e) { + if ($e->getPrevious()) { + throw $e->getPrevious(); + } + throw $e; + } + } + +} diff --git a/thinkphp/library/think/response/Redirect.php b/thinkphp/library/think/response/Redirect.php new file mode 100755 index 0000000..0ea90a4 --- /dev/null +++ b/thinkphp/library/think/response/Redirect.php @@ -0,0 +1,105 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Request; +use think\Response; +use think\Session; +use think\Url; + +class Redirect extends Response +{ + + protected $options = []; + + // URL参数 + protected $params = []; + + public function __construct($data = '', $code = 302, array $header = [], array $options = []) + { + parent::__construct($data, $code, $header, $options); + $this->cacheControl('no-cache,must-revalidate'); + } + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + $this->header['Location'] = $this->getTargetUrl(); + return; + } + + /** + * 重定向传值(通过Session) + * @access protected + * @param string|array $name 变量名或者数组 + * @param mixed $value 值 + * @return $this + */ + public function with($name, $value = null) + { + if (is_array($name)) { + foreach ($name as $key => $val) { + Session::flash($key, $val); + } + } else { + Session::flash($name, $value); + } + return $this; + } + + /** + * 获取跳转地址 + * @return string + */ + public function getTargetUrl() + { + if (strpos($this->data, '://') || (0 === strpos($this->data, '/') && empty($this->params))) { + return $this->data; + } else { + return Url::build($this->data, $this->params); + } + } + + public function params($params = []) + { + $this->params = $params; + return $this; + } + + /** + * 记住当前url后跳转 + * @return $this + */ + public function remember() + { + Session::set('redirect_url', Request::instance()->url()); + return $this; + } + + /** + * 跳转到上次记住的url + * @return $this + */ + public function restore() + { + if (Session::has('redirect_url')) { + $this->data = Session::get('redirect_url'); + Session::delete('redirect_url'); + } + return $this; + } +} diff --git a/thinkphp/library/think/response/View.php b/thinkphp/library/think/response/View.php new file mode 100755 index 0000000..de75515 --- /dev/null +++ b/thinkphp/library/think/response/View.php @@ -0,0 +1,89 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Config; +use think\Response; +use think\View as ViewTemplate; + +class View extends Response +{ + // 输出参数 + protected $options = []; + protected $vars = []; + protected $replace = []; + protected $contentType = 'text/html'; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + // 渲染模板输出 + return ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) + ->fetch($data, $this->vars, $this->replace); + } + + /** + * 获取视图变量 + * @access public + * @param string $name 模板变量 + * @return mixed + */ + public function getVars($name = null) + { + if (is_null($name)) { + return $this->vars; + } else { + return isset($this->vars[$name]) ? $this->vars[$name] : null; + } + } + + /** + * 模板变量赋值 + * @access public + * @param mixed $name 变量名 + * @param mixed $value 变量值 + * @return $this + */ + public function assign($name, $value = '') + { + if (is_array($name)) { + $this->vars = array_merge($this->vars, $name); + return $this; + } else { + $this->vars[$name] = $value; + } + return $this; + } + + /** + * 视图内容替换 + * @access public + * @param string|array $content 被替换内容(支持批量替换) + * @param string $replace 替换内容 + * @return $this + */ + public function replace($content, $replace = '') + { + if (is_array($content)) { + $this->replace = array_merge($this->replace, $content); + } else { + $this->replace[$content] = $replace; + } + return $this; + } + +} diff --git a/thinkphp/library/think/response/Xml.php b/thinkphp/library/think/response/Xml.php new file mode 100755 index 0000000..87479be --- /dev/null +++ b/thinkphp/library/think/response/Xml.php @@ -0,0 +1,102 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\response; + +use think\Collection; +use think\Model; +use think\Response; + +class Xml extends Response +{ + // 输出参数 + protected $options = [ + // 根节点名 + 'root_node' => 'think', + // 根节点属性 + 'root_attr' => '', + //数字索引的子节点名 + 'item_node' => 'item', + // 数字索引子节点key转换的属性名 + 'item_key' => 'id', + // 数据编码 + 'encoding' => 'utf-8', + ]; + + protected $contentType = 'text/xml'; + + /** + * 处理数据 + * @access protected + * @param mixed $data 要处理的数据 + * @return mixed + */ + protected function output($data) + { + // XML数据转换 + return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']); + } + + /** + * XML编码 + * @param mixed $data 数据 + * @param string $root 根节点名 + * @param string $item 数字索引的子节点名 + * @param string $attr 根节点属性 + * @param string $id 数字索引子节点key转换的属性名 + * @param string $encoding 数据编码 + * @return string + */ + protected function xmlEncode($data, $root, $item, $attr, $id, $encoding) + { + if (is_array($attr)) { + $array = []; + foreach ($attr as $key => $value) { + $array[] = "{$key}=\"{$value}\""; + } + $attr = implode(' ', $array); + } + $attr = trim($attr); + $attr = empty($attr) ? '' : " {$attr}"; + $xml = "<?xml version=\"1.0\" encoding=\"{$encoding}\"?>"; + $xml .= "<{$root}{$attr}>"; + $xml .= $this->dataToXml($data, $item, $id); + $xml .= "</{$root}>"; + return $xml; + } + + /** + * 数据XML编码 + * @param mixed $data 数据 + * @param string $item 数字索引时的节点名称 + * @param string $id 数字索引key转换为的属性名 + * @return string + */ + protected function dataToXml($data, $item, $id) + { + $xml = $attr = ''; + + if ($data instanceof Collection || $data instanceof Model) { + $data = $data->toArray(); + } + + foreach ($data as $key => $val) { + if (is_numeric($key)) { + $id && $attr = " {$id}=\"{$key}\""; + $key = $item; + } + $xml .= "<{$key}{$attr}>"; + $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val; + $xml .= "</{$key}>"; + } + return $xml; + } +} diff --git a/thinkphp/library/think/session/driver/Memcache.php b/thinkphp/library/think/session/driver/Memcache.php new file mode 100755 index 0000000..0c02e23 --- /dev/null +++ b/thinkphp/library/think/session/driver/Memcache.php @@ -0,0 +1,118 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\session\driver; + +use SessionHandler; +use think\Exception; + +class Memcache extends SessionHandler +{ + protected $handler = null; + protected $config = [ + 'host' => '127.0.0.1', // memcache主机 + 'port' => 11211, // memcache端口 + 'expire' => 3600, // session有效期 + 'timeout' => 0, // 连接超时时间(单位:毫秒) + 'persistent' => true, // 长连接 + 'session_name' => '', // memcache key前缀 + ]; + + public function __construct($config = []) + { + $this->config = array_merge($this->config, $config); + } + + /** + * 打开Session + * @access public + * @param string $savePath + * @param mixed $sessName + */ + public function open($savePath, $sessName) + { + // 检测php环境 + if (!extension_loaded('memcache')) { + throw new Exception('not support:memcache'); + } + $this->handler = new \Memcache; + // 支持集群 + $hosts = explode(',', $this->config['host']); + $ports = explode(',', $this->config['port']); + if (empty($ports[0])) { + $ports[0] = 11211; + } + // 建立连接 + foreach ((array) $hosts as $i => $host) { + $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; + $this->config['timeout'] > 0 ? + $this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) : + $this->handler->addServer($host, $port, $this->config['persistent'], 1); + } + return true; + } + + /** + * 关闭Session + * @access public + */ + public function close() + { + $this->gc(ini_get('session.gc_maxlifetime')); + $this->handler->close(); + $this->handler = null; + return true; + } + + /** + * 读取Session + * @access public + * @param string $sessID + */ + public function read($sessID) + { + return (string) $this->handler->get($this->config['session_name'] . $sessID); + } + + /** + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData + * @return bool + */ + public function write($sessID, $sessData) + { + return $this->handler->set($this->config['session_name'] . $sessID, $sessData, 0, $this->config['expire']); + } + + /** + * 删除Session + * @access public + * @param string $sessID + * @return bool + */ + public function destroy($sessID) + { + return $this->handler->delete($this->config['session_name'] . $sessID); + } + + /** + * Session 垃圾回收 + * @access public + * @param string $sessMaxLifeTime + * @return true + */ + public function gc($sessMaxLifeTime) + { + return true; + } +} diff --git a/thinkphp/library/think/session/driver/Memcached.php b/thinkphp/library/think/session/driver/Memcached.php new file mode 100755 index 0000000..bcaf8a1 --- /dev/null +++ b/thinkphp/library/think/session/driver/Memcached.php @@ -0,0 +1,126 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\session\driver; + +use SessionHandler; +use think\Exception; + +class Memcached extends SessionHandler +{ + protected $handler = null; + protected $config = [ + 'host' => '127.0.0.1', // memcache主机 + 'port' => 11211, // memcache端口 + 'expire' => 3600, // session有效期 + 'timeout' => 0, // 连接超时时间(单位:毫秒) + 'session_name' => '', // memcache key前缀 + 'username' => '', //账号 + 'password' => '', //密码 + ]; + + public function __construct($config = []) + { + $this->config = array_merge($this->config, $config); + } + + /** + * 打开Session + * @access public + * @param string $savePath + * @param mixed $sessName + */ + public function open($savePath, $sessName) + { + // 检测php环境 + if (!extension_loaded('memcached')) { + throw new Exception('not support:memcached'); + } + $this->handler = new \Memcached; + // 设置连接超时时间(单位:毫秒) + if ($this->config['timeout'] > 0) { + $this->handler->setOption(\Memcached::OPT_CONNECT_TIMEOUT, $this->config['timeout']); + } + // 支持集群 + $hosts = explode(',', $this->config['host']); + $ports = explode(',', $this->config['port']); + if (empty($ports[0])) { + $ports[0] = 11211; + } + // 建立连接 + $servers = []; + foreach ((array) $hosts as $i => $host) { + $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1]; + } + $this->handler->addServers($servers); + if ('' != $this->config['username']) { + $this->handler->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $this->handler->setSaslAuthData($this->config['username'], $this->config['password']); + } + return true; + } + + /** + * 关闭Session + * @access public + */ + public function close() + { + $this->gc(ini_get('session.gc_maxlifetime')); + $this->handler->quit(); + $this->handler = null; + return true; + } + + /** + * 读取Session + * @access public + * @param string $sessID + */ + public function read($sessID) + { + return (string) $this->handler->get($this->config['session_name'] . $sessID); + } + + /** + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData + * @return bool + */ + public function write($sessID, $sessData) + { + return $this->handler->set($this->config['session_name'] . $sessID, $sessData, $this->config['expire']); + } + + /** + * 删除Session + * @access public + * @param string $sessID + * @return bool + */ + public function destroy($sessID) + { + return $this->handler->delete($this->config['session_name'] . $sessID); + } + + /** + * Session 垃圾回收 + * @access public + * @param string $sessMaxLifeTime + * @return true + */ + public function gc($sessMaxLifeTime) + { + return true; + } +} diff --git a/thinkphp/library/think/session/driver/Redis.php b/thinkphp/library/think/session/driver/Redis.php new file mode 100755 index 0000000..a4c2b54 --- /dev/null +++ b/thinkphp/library/think/session/driver/Redis.php @@ -0,0 +1,128 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\session\driver; + +use SessionHandler; +use think\Exception; + +class Redis extends SessionHandler +{ + /** @var \Redis */ + protected $handler = null; + protected $config = [ + 'host' => '127.0.0.1', // redis主机 + 'port' => 6379, // redis端口 + 'password' => '', // 密码 + 'select' => 0, // 操作库 + 'expire' => 3600, // 有效期(秒) + 'timeout' => 0, // 超时时间(秒) + 'persistent' => true, // 是否长连接 + 'session_name' => '', // sessionkey前缀 + ]; + + public function __construct($config = []) + { + $this->config = array_merge($this->config, $config); + } + + /** + * 打开Session + * @access public + * @param string $savePath + * @param mixed $sessName + * @return bool + * @throws Exception + */ + public function open($savePath, $sessName) + { + // 检测php环境 + if (!extension_loaded('redis')) { + throw new Exception('not support:redis'); + } + $this->handler = new \Redis; + + // 建立连接 + $func = $this->config['persistent'] ? 'pconnect' : 'connect'; + $this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']); + + if ('' != $this->config['password']) { + $this->handler->auth($this->config['password']); + } + + if (0 != $this->config['select']) { + $this->handler->select($this->config['select']); + } + + return true; + } + + /** + * 关闭Session + * @access public + */ + public function close() + { + $this->gc(ini_get('session.gc_maxlifetime')); + $this->handler->close(); + $this->handler = null; + return true; + } + + /** + * 读取Session + * @access public + * @param string $sessID + * @return string + */ + public function read($sessID) + { + return (string) $this->handler->get($this->config['session_name'] . $sessID); + } + + /** + * 写入Session + * @access public + * @param string $sessID + * @param String $sessData + * @return bool + */ + public function write($sessID, $sessData) + { + if ($this->config['expire'] > 0) { + return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData); + } else { + return $this->handler->set($this->config['session_name'] . $sessID, $sessData); + } + } + + /** + * 删除Session + * @access public + * @param string $sessID + * @return bool + */ + public function destroy($sessID) + { + return $this->handler->delete($this->config['session_name'] . $sessID) > 0; + } + + /** + * Session 垃圾回收 + * @access public + * @param string $sessMaxLifeTime + * @return bool + */ + public function gc($sessMaxLifeTime) + { + return true; + } +} diff --git a/thinkphp/library/think/template/TagLib.php b/thinkphp/library/think/template/TagLib.php new file mode 100755 index 0000000..d343bed --- /dev/null +++ b/thinkphp/library/think/template/TagLib.php @@ -0,0 +1,334 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\template; + +use think\Exception; + +/** + * ThinkPHP标签库TagLib解析基类 + * @category Think + * @package Think + * @subpackage Template + * @author liu21st <liu21st@gmail.com> + */ +class TagLib +{ + + /** + * 标签库定义XML文件 + * @var string + * @access protected + */ + protected $xml = ''; + protected $tags = []; // 标签定义 + /** + * 标签库名称 + * @var string + * @access protected + */ + protected $tagLib = ''; + + /** + * 标签库标签列表 + * @var array + * @access protected + */ + protected $tagList = []; + + /** + * 标签库分析数组 + * @var array + * @access protected + */ + protected $parse = []; + + /** + * 标签库是否有效 + * @var bool + * @access protected + */ + protected $valid = false; + + /** + * 当前模板对象 + * @var object + * @access protected + */ + protected $tpl; + + protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < ']; + + /** + * 构造函数 + * @access public + * @param \stdClass $template 模板引擎对象 + */ + public function __construct($template) + { + $this->tpl = $template; + } + + /** + * 按签标库替换页面中的标签 + * @access public + * @param string $content 模板内容 + * @param string $lib 标签库名 + * @return void + */ + public function parseTag(&$content, $lib = '') + { + $tags = []; + $lib = $lib ? strtolower($lib) . ':' : ''; + foreach ($this->tags as $name => $val) { + $close = !isset($val['close']) || $val['close'] ? 1 : 0; + $tags[$close][$lib . $name] = $name; + if (isset($val['alias'])) { + // 别名设置 + $array = (array) $val['alias']; + foreach (explode(',', $array[0]) as $v) { + $tags[$close][$lib . $v] = $name; + } + } + } + + // 闭合标签 + if (!empty($tags[1])) { + $nodes = []; + $regex = $this->getRegex(array_keys($tags[1]), 1); + if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + $right = []; + foreach ($matches as $match) { + if ('' == $match[1][0]) { + $name = strtolower($match[2][0]); + // 如果有没闭合的标签头则取出最后一个 + if (!empty($right[$name])) { + // $match[0][1]为标签结束符在模板中的位置 + $nodes[$match[0][1]] = [ + 'name' => $name, + 'begin' => array_pop($right[$name]), // 标签开始符 + 'end' => $match[0], // 标签结束符 + ]; + } + } else { + // 标签头压入栈 + $right[strtolower($match[1][0])][] = $match[0]; + } + } + unset($right, $matches); + // 按标签在模板中的位置从后向前排序 + krsort($nodes); + } + + $break = '<!--###break###--!>'; + if ($nodes) { + $beginArray = []; + // 标签替换 从后向前 + foreach ($nodes as $pos => $node) { + // 对应的标签名 + $name = $tags[1][$node['name']]; + $alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : ''; + // 解析标签属性 + $attrs = $this->parseAttr($node['begin'][0], $name, $alias); + $method = 'tag' . $name; + // 读取标签库中对应的标签内容 replace[0]用来替换标签头,replace[1]用来替换标签尾 + $replace = explode($break, $this->$method($attrs, $break)); + if (count($replace) > 1) { + while ($beginArray) { + $begin = end($beginArray); + // 判断当前标签尾的位置是否在栈中最后一个标签头的后面,是则为子标签 + if ($node['end'][1] > $begin['pos']) { + break; + } else { + // 不为子标签时,取出栈中最后一个标签头 + $begin = array_pop($beginArray); + // 替换标签头部 + $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); + } + } + // 替换标签尾部 + $content = substr_replace($content, $replace[1], $node['end'][1], strlen($node['end'][0])); + // 把标签头压入栈 + $beginArray[] = ['pos' => $node['begin'][1], 'len' => strlen($node['begin'][0]), 'str' => $replace[0]]; + } + } + while ($beginArray) { + $begin = array_pop($beginArray); + // 替换标签头部 + $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']); + } + } + } + // 自闭合标签 + if (!empty($tags[0])) { + $regex = $this->getRegex(array_keys($tags[0]), 0); + $content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) { + // 对应的标签名 + $name = $tags[0][strtolower($matches[1])]; + $alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : ''; + // 解析标签属性 + $attrs = $this->parseAttr($matches[0], $name, $alias); + $method = 'tag' . $name; + return $this->$method($attrs, ''); + }, $content); + } + return; + } + + /** + * 按标签生成正则 + * @access private + * @param array|string $tags 标签名 + * @param boolean $close 是否为闭合标签 + * @return string + */ + public function getRegex($tags, $close) + { + $begin = $this->tpl->config('taglib_begin'); + $end = $this->tpl->config('taglib_end'); + $single = strlen(ltrim($begin, '\\')) == 1 && strlen(ltrim($end, '\\')) == 1 ? true : false; + $tagName = is_array($tags) ? implode('|', $tags) : $tags; + if ($single) { + if ($close) { + // 如果是闭合标签 + $regex = $begin . '(?:(' . $tagName . ')\b(?>[^' . $end . ']*)|\/(' . $tagName . '))' . $end; + } else { + $regex = $begin . '(' . $tagName . ')\b(?>[^' . $end . ']*)' . $end; + } + } else { + if ($close) { + // 如果是闭合标签 + $regex = $begin . '(?:(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)|\/(' . $tagName . '))' . $end; + } else { + $regex = $begin . '(' . $tagName . ')\b(?>(?:(?!' . $end . ').)*)' . $end; + } + } + return '/' . $regex . '/is'; + } + + /** + * 分析标签属性 正则方式 + * @access public + * @param string $str 标签属性字符串 + * @param string $name 标签名 + * @param string $alias 别名 + * @return array + */ + public function parseAttr($str, $name, $alias = '') + { + $regex = '/\s+(?>(?P<name>[\w-]+)\s*)=(?>\s*)([\"\'])(?P<value>(?:(?!\\2).)*)\\2/is'; + $result = []; + if (preg_match_all($regex, $str, $matches)) { + foreach ($matches['name'] as $key => $val) { + $result[$val] = $matches['value'][$key]; + } + if (!isset($this->tags[$name])) { + // 检测是否存在别名定义 + foreach ($this->tags as $key => $val) { + if (isset($val['alias'])) { + $array = (array) $val['alias']; + if (in_array($name, explode(',', $array[0]))) { + $tag = $val; + $type = !empty($array[1]) ? $array[1] : 'type'; + $result[$type] = $name; + break; + } + } + } + } else { + $tag = $this->tags[$name]; + // 设置了标签别名 + if (!empty($alias) && isset($tag['alias'])) { + $type = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type'; + $result[$type] = $alias; + } + } + if (!empty($tag['must'])) { + $must = explode(',', $tag['must']); + foreach ($must as $name) { + if (!isset($result[$name])) { + throw new Exception('tag attr must:' . $name); + } + } + } + } else { + // 允许直接使用表达式的标签 + if (!empty($this->tags[$name]['expression'])) { + static $_taglibs; + if (!isset($_taglibs[$name])) { + $_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\') . $name); + $_taglibs[$name][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\')); + } + $result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]); + // 清除自闭合标签尾部/ + $result['expression'] = rtrim($result['expression'], '/'); + $result['expression'] = trim($result['expression']); + } elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) { + throw new Exception('tag error:' . $name); + } + } + return $result; + } + + /** + * 解析条件表达式 + * @access public + * @param string $condition 表达式标签内容 + * @return string + */ + public function parseCondition($condition) + { + if (strpos($condition, ':')) { + $condition = ' ' . substr(strstr($condition, ':'), 1); + } + $condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition); + $this->tpl->parseVar($condition); + // $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数,但表达式中如果有|、||这样的逻辑运算就产生了歧异 + return $condition; + } + + /** + * 自动识别构建变量 + * @access public + * @param string $name 变量描述 + * @return string + */ + public function autoBuildVar(&$name) + { + $flag = substr($name, 0, 1); + if (':' == $flag) { + // 以:开头为函数调用,解析前去掉: + $name = substr($name, 1); + } elseif ('$' != $flag && preg_match('/[a-zA-Z_]/', $flag)) { + // XXX: 这句的写法可能还需要改进 + // 常量不需要解析 + if (defined($name)) { + return $name; + } + // 不以$开头并且也不是常量,自动补上$前缀 + $name = '$' . $name; + } + $this->tpl->parseVar($name); + $this->tpl->parseVarFunction($name); + return $name; + } + + /** + * 获取标签列表 + * @access public + * @return array + */ + // 获取标签定义 + public function getTags() + { + return $this->tags; + } +} diff --git a/thinkphp/library/think/template/driver/File.php b/thinkphp/library/think/template/driver/File.php new file mode 100755 index 0000000..b27e726 --- /dev/null +++ b/thinkphp/library/think/template/driver/File.php @@ -0,0 +1,71 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\template\driver; + +use think\Exception; + +class File +{ + /** + * 写入编译缓存 + * @param string $cacheFile 缓存的文件名 + * @param string $content 缓存的内容 + * @return void|array + */ + public function write($cacheFile, $content) + { + // 检测模板目录 + $dir = dirname($cacheFile); + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + // 生成模板缓存文件 + if (false === file_put_contents($cacheFile, $content)) { + throw new Exception('cache write error:' . $cacheFile, 11602); + } + } + + /** + * 读取编译编译 + * @param string $cacheFile 缓存的文件名 + * @param array $vars 变量数组 + * @return void + */ + public function read($cacheFile, $vars = []) + { + if (!empty($vars) && is_array($vars)) { + // 模板阵列变量分解成为独立变量 + extract($vars, EXTR_OVERWRITE); + } + //载入模版缓存文件 + include $cacheFile; + } + + /** + * 检查编译缓存是否有效 + * @param string $cacheFile 缓存的文件名 + * @param int $cacheTime 缓存时间 + * @return boolean + */ + public function check($cacheFile, $cacheTime) + { + // 缓存文件不存在, 直接返回false + if (!file_exists($cacheFile)) { + return false; + } + if (0 != $cacheTime && $_SERVER['REQUEST_TIME'] > filemtime($cacheFile) + $cacheTime) { + // 缓存是否在有效期 + return false; + } + return true; + } +} diff --git a/thinkphp/library/think/template/driver/code.jpg b/thinkphp/library/think/template/driver/code.jpg new file mode 100755 index 0000000..dd365a7 Binary files /dev/null and b/thinkphp/library/think/template/driver/code.jpg differ diff --git a/thinkphp/library/think/template/taglib/Cx.php b/thinkphp/library/think/template/taglib/Cx.php new file mode 100755 index 0000000..af7a54c --- /dev/null +++ b/thinkphp/library/think/template/taglib/Cx.php @@ -0,0 +1,673 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK IT ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\template\taglib; + +use think\template\TagLib; + +/** + * CX标签库解析类 + * @category Think + * @package Think + * @subpackage Driver.Taglib + * @author liu21st <liu21st@gmail.com> + */ +class Cx extends Taglib +{ + + // 标签定义 + protected $tags = [ + // 标签定义: attr 属性列表 close 是否闭合(0 或者1 默认1) alias 标签别名 level 嵌套层次 + 'php' => ['attr' => ''], + 'volist' => ['attr' => 'name,id,offset,length,key,mod', 'alias' => 'iterate'], + 'foreach' => ['attr' => 'name,id,item,key,offset,length,mod', 'expression' => true], + 'if' => ['attr' => 'condition', 'expression' => true], + 'elseif' => ['attr' => 'condition', 'close' => 0, 'expression' => true], + 'else' => ['attr' => '', 'close' => 0], + 'switch' => ['attr' => 'name', 'expression' => true], + 'case' => ['attr' => 'value,break', 'expression' => true], + 'default' => ['attr' => '', 'close' => 0], + 'compare' => ['attr' => 'name,value,type', 'alias' => ['eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq', 'type']], + 'range' => ['attr' => 'name,value,type', 'alias' => ['in,notin,between,notbetween', 'type']], + 'empty' => ['attr' => 'name'], + 'notempty' => ['attr' => 'name'], + 'present' => ['attr' => 'name'], + 'notpresent' => ['attr' => 'name'], + 'defined' => ['attr' => 'name'], + 'notdefined' => ['attr' => 'name'], + 'load' => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['import,css,js', 'type']], + 'assign' => ['attr' => 'name,value', 'close' => 0], + 'define' => ['attr' => 'name,value', 'close' => 0], + 'for' => ['attr' => 'start,end,name,comparison,step'], + 'url' => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true], + 'function' => ['attr' => 'name,vars,use,call'], + ]; + + /** + * php标签解析 + * 格式: + * {php}echo $name{/php} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagPhp($tag, $content) + { + $parseStr = '<?php ' . $content . ' ?>'; + return $parseStr; + } + + /** + * volist标签解析 循环输出数据集 + * 格式: + * {volist name="userList" id="user" empty=""} + * {user.username} + * {user.email} + * {/volist} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string|void + */ + public function tagVolist($tag, $content) + { + $name = $tag['name']; + $id = $tag['id']; + $empty = isset($tag['empty']) ? $tag['empty'] : ''; + $key = !empty($tag['key']) ? $tag['key'] : 'i'; + $mod = isset($tag['mod']) ? $tag['mod'] : '2'; + $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0; + $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null'; + // 允许使用函数设定数据集 <volist name=":fun('arg')" id="vo">{$vo.name}</volist> + $parseStr = '<?php '; + $flag = substr($name, 0, 1); + if (':' == $flag) { + $name = $this->autoBuildVar($name); + $parseStr .= '$_result=' . $name . ';'; + $name = '$_result'; + } else { + $name = $this->autoBuildVar($name); + } + + $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): $' . $key . ' = 0;'; + // 设置了输出数组长度 + if (0 != $offset || 'null' != $length) { + $parseStr .= '$__LIST__ = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); '; + } else { + $parseStr .= ' $__LIST__ = ' . $name . ';'; + } + $parseStr .= 'if( count($__LIST__)==0 ) : echo "' . $empty . '" ;'; + $parseStr .= 'else: '; + $parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): '; + $parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );'; + $parseStr .= '++$' . $key . ';?>'; + $parseStr .= $content; + $parseStr .= '<?php endforeach; endif; else: echo "' . $empty . '" ;endif; ?>'; + + if (!empty($parseStr)) { + return $parseStr; + } + return; + } + + /** + * foreach标签解析 循环输出数据集 + * 格式: + * {foreach name="userList" id="user" key="key" index="i" mod="2" offset="3" length="5" empty=""} + * {user.username} + * {/foreach} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string|void + */ + public function tagForeach($tag, $content) + { + // 直接使用表达式 + if (!empty($tag['expression'])) { + $expression = ltrim(rtrim($tag['expression'], ')'), '('); + $expression = $this->autoBuildVar($expression); + $parseStr = '<?php foreach(' . $expression . '): ?>'; + $parseStr .= $content; + $parseStr .= '<?php endforeach; ?>'; + return $parseStr; + } + $name = $tag['name']; + $key = !empty($tag['key']) ? $tag['key'] : 'key'; + $item = !empty($tag['id']) ? $tag['id'] : $tag['item']; + $empty = isset($tag['empty']) ? $tag['empty'] : ''; + $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0; + $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null'; + + $parseStr = '<?php '; + // 支持用函数传数组 + if (':' == substr($name, 0, 1)) { + $var = '$_' . uniqid(); + $name = $this->autoBuildVar($name); + $parseStr .= $var . '=' . $name . '; '; + $name = $var; + } else { + $name = $this->autoBuildVar($name); + } + $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator): '; + // 设置了输出数组长度 + if (0 != $offset || 'null' != $length) { + if (!isset($var)) { + $var = '$_' . uniqid(); + } + $parseStr .= $var . ' = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); '; + } else { + $var = &$name; + } + + $parseStr .= 'if( count(' . $var . ')==0 ) : echo "' . $empty . '" ;'; + $parseStr .= 'else: '; + + // 设置了索引项 + if (isset($tag['index'])) { + $index = $tag['index']; + $parseStr .= '$' . $index . '=0; '; + } + $parseStr .= 'foreach(' . $var . ' as $' . $key . '=>$' . $item . '): '; + // 设置了索引项 + if (isset($tag['index'])) { + $index = $tag['index']; + if (isset($tag['mod'])) { + $mod = (int) $tag['mod']; + $parseStr .= '$mod = ($' . $index . ' % ' . $mod . '); '; + } + $parseStr .= '++$' . $index . '; '; + } + $parseStr .= '?>'; + // 循环体中的内容 + $parseStr .= $content; + $parseStr .= '<?php endforeach; endif; else: echo "' . $empty . '" ;endif; ?>'; + + if (!empty($parseStr)) { + return $parseStr; + } + return; + } + + /** + * if标签解析 + * 格式: + * {if condition=" $a eq 1"} + * {elseif condition="$a eq 2" /} + * {else /} + * {/if} + * 表达式支持 eq neq gt egt lt elt == > >= < <= or and || && + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagIf($tag, $content) + { + $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition']; + $condition = $this->parseCondition($condition); + $parseStr = '<?php if(' . $condition . '): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * elseif标签解析 + * 格式:见if标签 + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagElseif($tag, $content) + { + $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition']; + $condition = $this->parseCondition($condition); + $parseStr = '<?php elseif(' . $condition . '): ?>'; + return $parseStr; + } + + /** + * else标签解析 + * 格式:见if标签 + * @access public + * @param array $tag 标签属性 + * @return string + */ + public function tagElse($tag) + { + $parseStr = '<?php else: ?>'; + return $parseStr; + } + + /** + * switch标签解析 + * 格式: + * {switch name="a.name"} + * {case value="1" break="false"}1{/case} + * {case value="2" }2{/case} + * {default /}other + * {/switch} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagSwitch($tag, $content) + { + $name = !empty($tag['expression']) ? $tag['expression'] : $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '<?php switch(' . $name . '): ?>' . $content . '<?php endswitch; ?>'; + return $parseStr; + } + + /** + * case标签解析 需要配合switch才有效 + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagCase($tag, $content) + { + $value = !empty($tag['expression']) ? $tag['expression'] : $tag['value']; + $flag = substr($value, 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($value); + $value = 'case ' . $value . ':'; + } elseif (strpos($value, '|')) { + $values = explode('|', $value); + $value = ''; + foreach ($values as $val) { + $value .= 'case "' . addslashes($val) . '":'; + } + } else { + $value = 'case "' . $value . '":'; + } + $parseStr = '<?php ' . $value . ' ?>' . $content; + $isBreak = isset($tag['break']) ? $tag['break'] : ''; + if ('' == $isBreak || $isBreak) { + $parseStr .= '<?php break; ?>'; + } + return $parseStr; + } + + /** + * default标签解析 需要配合switch才有效 + * 使用: {default /}ddfdf + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagDefault($tag) + { + $parseStr = '<?php default: ?>'; + return $parseStr; + } + + /** + * compare标签解析 + * 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq + * 格式: {compare name="" type="eq" value="" }content{/compare} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagCompare($tag, $content) + { + $name = $tag['name']; + $value = $tag['value']; + $type = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型 + $name = $this->autoBuildVar($name); + $flag = substr($value, 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($value); + } else { + $value = '\'' . $value . '\''; + } + switch ($type) { + case 'equal': + $type = 'eq'; + break; + case 'notequal': + $type = 'neq'; + break; + } + $type = $this->parseCondition(' ' . $type . ' '); + $parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * range标签解析 + * 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外 + * 格式: {range name="var|function" value="val" type='in|notin' }content{/range} + * example: {range name="a" value="1,2,3" type='in' }content{/range} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagRange($tag, $content) + { + $name = $tag['name']; + $value = $tag['value']; + $type = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型 + + $name = $this->autoBuildVar($name); + $flag = substr($value, 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($value); + $str = 'is_array(' . $value . ')?' . $value . ':explode(\',\',' . $value . ')'; + } else { + $value = '"' . $value . '"'; + $str = 'explode(\',\',' . $value . ')'; + } + if ('between' == $type) { + $parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '>= $_RANGE_VAR_[0] && ' . $name . '<= $_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>'; + } elseif ('notbetween' == $type) { + $parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '<$_RANGE_VAR_[0] || ' . $name . '>$_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>'; + } else { + $fun = ('in' == $type) ? 'in_array' : '!in_array'; + $parseStr = '<?php if(' . $fun . '((' . $name . '), ' . $str . ')): ?>' . $content . '<?php endif; ?>'; + } + return $parseStr; + } + + /** + * present标签解析 + * 如果某个变量已经设置 则输出内容 + * 格式: {present name="" }content{/present} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagPresent($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '<?php if(isset(' . $name . ')): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * notpresent标签解析 + * 如果某个变量没有设置,则输出内容 + * 格式: {notpresent name="" }content{/notpresent} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagNotpresent($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '<?php if(!isset(' . $name . ')): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * empty标签解析 + * 如果某个变量为empty 则输出内容 + * 格式: {empty name="" }content{/empty} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagEmpty($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '<?php if(empty(' . $name . ') || ((' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator ) && ' . $name . '->isEmpty())): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * notempty标签解析 + * 如果某个变量不为empty 则输出内容 + * 格式: {notempty name="" }content{/notempty} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagNotempty($tag, $content) + { + $name = $tag['name']; + $name = $this->autoBuildVar($name); + $parseStr = '<?php if(!(empty(' . $name . ') || ((' . $name . ' instanceof \think\Collection || ' . $name . ' instanceof \think\Paginator ) && ' . $name . '->isEmpty()))): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * 判断是否已经定义了该常量 + * {defined name='TXT'}已定义{/defined} + * @param array $tag + * @param string $content + * @return string + */ + public function tagDefined($tag, $content) + { + $name = $tag['name']; + $parseStr = '<?php if(defined("' . $name . '")): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * 判断是否没有定义了该常量 + * {notdefined name='TXT'}已定义{/notdefined} + * @param array $tag + * @param string $content + * @return string + */ + public function tagNotdefined($tag, $content) + { + $name = $tag['name']; + $parseStr = '<?php if(!defined("' . $name . '")): ?>' . $content . '<?php endif; ?>'; + return $parseStr; + } + + /** + * load 标签解析 {load file="/static/js/base.js" /} + * 格式:{load file="/static/css/base.css" /} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagLoad($tag, $content) + { + $file = isset($tag['file']) ? $tag['file'] : $tag['href']; + $type = isset($tag['type']) ? strtolower($tag['type']) : ''; + $parseStr = ''; + $endStr = ''; + // 判断是否存在加载条件 允许使用函数判断(默认为isset) + if (isset($tag['value'])) { + $name = $tag['value']; + $name = $this->autoBuildVar($name); + $name = 'isset(' . $name . ')'; + $parseStr .= '<?php if(' . $name . '): ?>'; + $endStr = '<?php endif; ?>'; + } + + // 文件方式导入 + $array = explode(',', $file); + foreach ($array as $val) { + $type = strtolower(substr(strrchr($val, '.'), 1)); + switch ($type) { + case 'js': + $parseStr .= '<script type="text/javascript" src="' . $val . '"></script>'; + break; + case 'css': + $parseStr .= '<link rel="stylesheet" type="text/css" href="' . $val . '" />'; + break; + case 'php': + $parseStr .= '<?php include "' . $val . '"; ?>'; + break; + } + } + return $parseStr . $endStr; + } + + /** + * assign标签解析 + * 在模板中给某个变量赋值 支持变量赋值 + * 格式: {assign name="" value="" /} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagAssign($tag, $content) + { + $name = $this->autoBuildVar($tag['name']); + $flag = substr($tag['value'], 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($tag['value']); + } else { + $value = '\'' . $tag['value'] . '\''; + } + $parseStr = '<?php ' . $name . ' = ' . $value . '; ?>'; + return $parseStr; + } + + /** + * define标签解析 + * 在模板中定义常量 支持变量赋值 + * 格式: {define name="" value="" /} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagDefine($tag, $content) + { + $name = '\'' . $tag['name'] . '\''; + $flag = substr($tag['value'], 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($tag['value']); + } else { + $value = '\'' . $tag['value'] . '\''; + } + $parseStr = '<?php define(' . $name . ', ' . $value . '); ?>'; + return $parseStr; + } + + /** + * for标签解析 + * 格式: + * {for start="" end="" comparison="" step="" name=""} + * content + * {/for} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagFor($tag, $content) + { + //设置默认值 + $start = 0; + $end = 0; + $step = 1; + $comparison = 'lt'; + $name = 'i'; + $rand = rand(); //添加随机数,防止嵌套变量冲突 + //获取属性 + foreach ($tag as $key => $value) { + $value = trim($value); + $flag = substr($value, 0, 1); + if ('$' == $flag || ':' == $flag) { + $value = $this->autoBuildVar($value); + } + + switch ($key) { + case 'start': + $start = $value; + break; + case 'end': + $end = $value; + break; + case 'step': + $step = $value; + break; + case 'comparison': + $comparison = $value; + break; + case 'name': + $name = $value; + break; + } + } + + $parseStr = '<?php $__FOR_START_' . $rand . '__=' . $start . ';$__FOR_END_' . $rand . '__=' . $end . ';'; + $parseStr .= 'for($' . $name . '=$__FOR_START_' . $rand . '__;' . $this->parseCondition('$' . $name . ' ' . $comparison . ' $__FOR_END_' . $rand . '__') . ';$' . $name . '+=' . $step . '){ ?>'; + $parseStr .= $content; + $parseStr .= '<?php } ?>'; + return $parseStr; + } + + /** + * url函数的tag标签 + * 格式:{url link="模块/控制器/方法" vars="参数" suffix="true或者false 是否带有后缀" domain="true或者false 是否携带域名" /} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagUrl($tag, $content) + { + $url = isset($tag['link']) ? $tag['link'] : ''; + $vars = isset($tag['vars']) ? $tag['vars'] : ''; + $suffix = isset($tag['suffix']) ? $tag['suffix'] : 'true'; + $domain = isset($tag['domain']) ? $tag['domain'] : 'false'; + return '<?php echo url("' . $url . '","' . $vars . '",' . $suffix . ',' . $domain . ');?>'; + } + + /** + * function标签解析 匿名函数,可实现递归 + * 使用: + * {function name="func" vars="$data" call="$list" use="&$a,&$b"} + * {if is_array($data)} + * {foreach $data as $val} + * {~func($val) /} + * {/foreach} + * {else /} + * {$data} + * {/if} + * {/function} + * @access public + * @param array $tag 标签属性 + * @param string $content 标签内容 + * @return string + */ + public function tagFunction($tag, $content) + { + $name = !empty($tag['name']) ? $tag['name'] : 'func'; + $vars = !empty($tag['vars']) ? $tag['vars'] : ''; + $call = !empty($tag['call']) ? $tag['call'] : ''; + $use = ['&$' . $name]; + if (!empty($tag['use'])) { + foreach (explode(',', $tag['use']) as $val) { + $use[] = '&' . ltrim(trim($val), '&'); + } + } + $parseStr = '<?php $' . $name . '=function(' . $vars . ') use(' . implode(',', $use) . ') {'; + $parseStr .= ' ?>' . $content . '<?php }; '; + $parseStr .= $call ? '$' . $name . '(' . $call . '); ?>' : '?>'; + return $parseStr; + } +} diff --git a/thinkphp/library/think/view/driver/Php.php b/thinkphp/library/think/view/driver/Php.php new file mode 100755 index 0000000..468d361 --- /dev/null +++ b/thinkphp/library/think/view/driver/Php.php @@ -0,0 +1,164 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\view\driver; + +use think\App; +use think\exception\TemplateNotFoundException; +use think\Loader; +use think\Log; +use think\Request; + +class Php +{ + // 模板引擎参数 + protected $config = [ + // 视图基础目录(集中式) + 'view_base' => '', + // 模板起始路径 + 'view_path' => '', + // 模板文件后缀 + 'view_suffix' => 'php', + // 模板文件名分隔符 + 'view_depr' => DS, + ]; + + public function __construct($config = []) + { + $this->config = array_merge($this->config, $config); + } + + /** + * 检测是否存在模板文件 + * @access public + * @param string $template 模板文件或者模板规则 + * @return bool + */ + public function exists($template) + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + return is_file($template); + } + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $data 模板变量 + * @return void + */ + public function fetch($template, $data = []) + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + // 模板不存在 抛出异常 + if (!is_file($template)) { + throw new TemplateNotFoundException('template not exists:' . $template, $template); + } + // 记录视图信息 + App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); + if (isset($data['template'])) { + $__template__ = $template; + extract($data, EXTR_OVERWRITE); + include $__template__; + } else { + extract($data, EXTR_OVERWRITE); + include $template; + } + } + + /** + * 渲染模板内容 + * @access public + * @param string $content 模板内容 + * @param array $data 模板变量 + * @return void + */ + public function display($content, $data = []) + { + if (isset($data['content'])) { + $__content__ = $content; + extract($data, EXTR_OVERWRITE); + eval('?>' . $__content__); + } else { + extract($data, EXTR_OVERWRITE); + eval('?>' . $content); + } + } + + /** + * 自动定位模板文件 + * @access private + * @param string $template 模板文件规则 + * @return string + */ + private function parseTemplate($template) + { + if (empty($this->config['view_path'])) { + $this->config['view_path'] = App::$modulePath . 'view' . DS; + } + + $request = Request::instance(); + // 获取视图根目录 + if (strpos($template, '@')) { + // 跨模块调用 + list($module, $template) = explode('@', $template); + } + if ($this->config['view_base']) { + // 基础视图目录 + $module = isset($module) ? $module : $request->module(); + $path = $this->config['view_base'] . ($module ? $module . DS : ''); + } else { + $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path']; + } + + $depr = $this->config['view_depr']; + if (0 !== strpos($template, '/')) { + $template = str_replace(['/', ':'], $depr, $template); + $controller = Loader::parseName($request->controller()); + if ($controller) { + if ('' == $template) { + // 如果模板文件名为空 按照默认规则定位 + $template = str_replace('.', DS, $controller) . $depr . $request->action(); + } elseif (false === strpos($template, $depr)) { + $template = str_replace('.', DS, $controller) . $depr . $template; + } + } + } else { + $template = str_replace(['/', ':'], $depr, substr($template, 1)); + } + return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); + } + + /** + * 配置模板引擎 + * @access private + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @return void + */ + public function config($name, $value = null) + { + if (is_array($name)) { + $this->config = array_merge($this->config, $name); + } elseif (is_null($value)) { + return isset($this->config[$name]) ? $this->config[$name] : null; + } else { + $this->config[$name] = $value; + } + } + +} diff --git a/thinkphp/library/think/view/driver/Think.php b/thinkphp/library/think/view/driver/Think.php new file mode 100755 index 0000000..39a14ca --- /dev/null +++ b/thinkphp/library/think/view/driver/Think.php @@ -0,0 +1,165 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think\view\driver; + +use think\App; +use think\exception\TemplateNotFoundException; +use think\Loader; +use think\Log; +use think\Request; +use think\Template; + +class Think +{ + // 模板引擎实例 + private $template; + // 模板引擎参数 + protected $config = [ + // 视图基础目录(集中式) + 'view_base' => '', + // 模板起始路径 + 'view_path' => '', + // 模板文件后缀 + 'view_suffix' => 'html', + // 模板文件名分隔符 + 'view_depr' => DS, + // 是否开启模板编译缓存,设为false则每次都会重新编译 + 'tpl_cache' => true, + ]; + + public function __construct($config = []) + { + $this->config = array_merge($this->config, $config); + if (empty($this->config['view_path'])) { + $this->config['view_path'] = App::$modulePath . 'view' . DS; + } + + $this->template = new Template($this->config); + } + + /** + * 检测是否存在模板文件 + * @access public + * @param string $template 模板文件或者模板规则 + * @return bool + */ + public function exists($template) + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + return is_file($template); + } + + /** + * 渲染模板文件 + * @access public + * @param string $template 模板文件 + * @param array $data 模板变量 + * @param array $config 模板参数 + * @return void + */ + public function fetch($template, $data = [], $config = []) + { + if ('' == pathinfo($template, PATHINFO_EXTENSION)) { + // 获取模板文件名 + $template = $this->parseTemplate($template); + } + // 模板不存在 抛出异常 + if (!is_file($template)) { + throw new TemplateNotFoundException('template not exists:' . $template, $template); + } + // 记录视图信息 + App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info'); + $this->template->fetch($template, $data, $config); + } + + /** + * 渲染模板内容 + * @access public + * @param string $template 模板内容 + * @param array $data 模板变量 + * @param array $config 模板参数 + * @return void + */ + public function display($template, $data = [], $config = []) + { + $this->template->display($template, $data, $config); + } + + /** + * 自动定位模板文件 + * @access private + * @param string $template 模板文件规则 + * @return string + */ + private function parseTemplate($template) + { + // 分析模板文件规则 + $request = Request::instance(); + // 获取视图根目录 + if (strpos($template, '@')) { + // 跨模块调用 + list($module, $template) = explode('@', $template); + } + if ($this->config['view_base']) { + // 基础视图目录 + $module = isset($module) ? $module : $request->module(); + $path = $this->config['view_base'] . ($module ? $module . DS : ''); + } else { + $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path']; + } + + $depr = $this->config['view_depr']; + if (0 !== strpos($template, '/')) { + $template = str_replace(['/', ':'], $depr, $template); + $controller = Loader::parseName($request->controller()); + if ($controller) { + if ('' == $template) { + // 如果模板文件名为空 按照默认规则定位 + $template = str_replace('.', DS, $controller) . $depr . $request->action(); + } elseif (false === strpos($template, $depr)) { + $template = str_replace('.', DS, $controller) . $depr . $template; + } + } + } else { + $template = str_replace(['/', ':'], $depr, substr($template, 1)); + } + return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.'); + } + + /** + * 配置或者获取模板引擎参数 + * @access private + * @param string|array $name 参数名 + * @param mixed $value 参数值 + * @return mixed + */ + public function config($name, $value = null) + { + if (is_array($name)) { + $this->template->config($name); + $this->config = array_merge($this->config, $name); + } elseif (is_null($value)) { + return $this->template->config($name); + } else { + $this->template->$name = $value; + $this->config[$name] = $value; + } + } + + public function __call($method, $params) + { + return call_user_func_array([$this->template, $method], $params); + } +} diff --git a/thinkphp/library/think/view/driver/tpl.php b/thinkphp/library/think/view/driver/tpl.php new file mode 100755 index 0000000..242661f --- /dev/null +++ b/thinkphp/library/think/view/driver/tpl.php @@ -0,0 +1,3 @@ +<?php + header("Content-type: text/html; charset=utf-8"); + echo base64_decode("KiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogPGJyLz4qIFdTVE1hcnTlpJrnlKjmiLfllYbln44NCiA8YnIvPiog54mI5p2D5omA5pyJIDIwMTYtMjA2NiDlub/lt57llYbmt5jkv6Hmga/np5HmioDmnInpmZDlhazlj7jvvIzlubbkv53nlZnmiYDmnInmnYPliKnjgIINCiA8YnIvPiog5a6Y572R5Zyw5Z2AOmh0dHA6Ly93d3cud3N0bWFydC5uZXQNCiA8YnIvPiog5Lqk5rWB56S+5Yy6Omh0dHA6Ly9iYnMuc2hhbmd0YW9zb2Z0LmNvbQ0KIDxici8+KiDogZTns7tRUToxNTMyODk5NzANCiA8YnIvPiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIDxici8+KiDov5nkuI3mmK/kuIDkuKroh6rnlLHova/ku7bvvIHmnKrnu4/mnKzlhazlj7jmjojmnYPmgqjlj6rog73lnKjkuI3nlKjkuo7llYbkuJrnm67nmoTnmoTliY3mj5DkuIvlr7nnqIvluo/ku6PnoIHov5vooYzkv67mlLnlkozkvb/nlKjvvJsNCiA8YnIvPiog5LiN5YWB6K645a+556iL5bqP5Luj56CB5Lul5Lu75L2V5b2i5byP5Lu75L2V55uu55qE55qE5YaN5Y+R5biD44CCDQogPGJyLz4qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0="); \ No newline at end of file diff --git a/thinkphp/library/traits/controller/Jump.php b/thinkphp/library/traits/controller/Jump.php new file mode 100755 index 0000000..472f23d --- /dev/null +++ b/thinkphp/library/traits/controller/Jump.php @@ -0,0 +1,148 @@ +<?php + +/** + * 用法: + * load_trait('controller/Jump'); + * class index + * { + * use \traits\controller\Jump; + * public function index(){ + * $this->error(); + * $this->redirect(); + * } + * } + */ +namespace traits\controller; + +use think\Config; +use think\exception\HttpResponseException; +use think\Request; +use think\Response; +use think\response\Redirect; +use think\Url; +use think\View as ViewTemplate; + +trait Jump +{ + /** + * 操作成功跳转的快捷方法 + * @access protected + * @param mixed $msg 提示信息 + * @param string $url 跳转的URL地址 + * @param mixed $data 返回的数据 + * @param integer $wait 跳转等待时间 + * @param array $header 发送的Header信息 + * @return void + */ + protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = []) + { + if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) { + $url = Request::instance()->server('HTTP_REFERER'); + } elseif ('' !== $url) { + $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url); + } + $result = [ + 'code' => 1, + 'msg' => $msg, + 'data' => $data, + 'url' => $url, + 'wait' => $wait, + ]; + + $type = $this->getResponseType(); + if ('html' == strtolower($type)) { + $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) + ->fetch(Config::get('dispatch_success_tmpl'), $result); + } + $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); + } + + /** + * 操作错误跳转的快捷方法 + * @access protected + * @param mixed $msg 提示信息 + * @param string $url 跳转的URL地址 + * @param mixed $data 返回的数据 + * @param integer $wait 跳转等待时间 + * @param array $header 发送的Header信息 + * @return void + */ + protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = []) + { + if (is_null($url)) { + $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);'; + } elseif ('' !== $url) { + $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url); + } + $result = [ + 'code' => 0, + 'msg' => $msg, + 'data' => $data, + 'url' => $url, + 'wait' => $wait, + ]; + + $type = $this->getResponseType(); + if ('html' == strtolower($type)) { + $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str')) + ->fetch(Config::get('dispatch_error_tmpl'), $result); + } + $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); + } + + /** + * 返回封装后的API数据到客户端 + * @access protected + * @param mixed $data 要返回的数据 + * @param integer $code 返回的code + * @param mixed $msg 提示信息 + * @param string $type 返回数据格式 + * @param array $header 发送的Header信息 + * @return void + */ + protected function result($data, $code = 0, $msg = '', $type = '', array $header = []) + { + $result = [ + 'code' => $code, + 'msg' => $msg, + 'time' => Request::instance()->server('REQUEST_TIME'), + 'data' => $data, + ]; + $type = $type ?: $this->getResponseType(); + $response = Response::create($result, $type)->header($header); + throw new HttpResponseException($response); + } + + /** + * URL重定向 + * @access protected + * @param string $url 跳转的URL表达式 + * @param array|integer $params 其它URL参数 + * @param integer $code http code + * @param array $with 隐式传参 + * @return void + */ + protected function redirect($url, $params = [], $code = 302, $with = []) + { + $response = new Redirect($url); + if (is_integer($params)) { + $code = $params; + $params = []; + } + $response->code($code)->params($params)->with($with); + throw new HttpResponseException($response); + } + + /** + * 获取当前的response 输出类型 + * @access protected + * @return string + */ + protected function getResponseType() + { + $isAjax = Request::instance()->isAjax(); + return $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type'); + } +} diff --git a/thinkphp/library/traits/model/SoftDelete.php b/thinkphp/library/traits/model/SoftDelete.php new file mode 100755 index 0000000..5501bd4 --- /dev/null +++ b/thinkphp/library/traits/model/SoftDelete.php @@ -0,0 +1,175 @@ +<?php + +namespace traits\model; + +use think\db\Query; +use think\Model; + +/** + * @mixin \Think\Model + */ +trait SoftDelete +{ + + /** + * 判断当前实例是否被软删除 + * @access public + * @return boolean + */ + public function trashed() + { + $field = $this->getDeleteTimeField(); + if (!empty($this->data[$field])) { + return true; + } + return false; + } + + /** + * 查询软删除数据 + * @access public + * @return Query + */ + public static function withTrashed() + { + $model = new static(); + $field = $model->getDeleteTimeField(true); + return $model->getQuery(); + } + + /** + * 只查询软删除数据 + * @access public + * @return Query + */ + public static function onlyTrashed() + { + $model = new static(); + $field = $model->getDeleteTimeField(true); + return $model->getQuery() + ->useSoftDelete($field, ['not null', '']); + } + + /** + * 删除当前的记录 + * @access public + * @param bool $force 是否强制删除 + * @return integer + */ + public function delete($force = false) + { + if (false === $this->trigger('before_delete', $this)) { + return false; + } + $name = $this->getDeleteTimeField(); + if (!$force) { + // 软删除 + $this->data[$name] = $this->autoWriteTimestamp($name); + $result = $this->isUpdate()->save(); + } else { + // 删除条件 + $where = $this->getWhere(); + // 删除当前模型数据 + $result = $this->getQuery()->where($where)->delete(); + } + + // 关联删除 + if (!empty($this->relationWrite)) { + foreach ($this->relationWrite as $key => $name) { + $name = is_numeric($key) ? $name : $key; + $model = $this->getAttr($name); + if ($model instanceof Model) { + $model->delete($force); + } + } + } + + $this->trigger('after_delete', $this); + // 清空原始数据 + $this->origin = []; + return $result; + } + + /** + * 删除记录 + * @access public + * @param mixed $data 主键列表 支持闭包查询条件 + * @param bool $force 是否强制删除 + * @return integer 成功删除的记录数 + */ + public static function destroy($data, $force = false) + { + // 包含软删除数据 + $query = self::withTrashed(); + if (is_array($data) && key($data) !== 0) { + $query->where($data); + $data = null; + } elseif ($data instanceof \Closure) { + call_user_func_array($data, [ & $query]); + $data = null; + } elseif (is_null($data)) { + return 0; + } + + $resultSet = $query->select($data); + $count = 0; + if ($resultSet) { + foreach ($resultSet as $data) { + $result = $data->delete($force); + $count += $result; + } + } + return $count; + } + + /** + * 恢复被软删除的记录 + * @access public + * @param array $where 更新条件 + * @return integer + */ + public function restore($where = []) + { + $name = $this->getDeleteTimeField(); + if (empty($where)) { + $pk = $this->getPk(); + $where[$pk] = $this->getData($pk); + } + // 恢复删除 + return $this->getQuery() + ->useSoftDelete($name, ['not null', '']) + ->where($where) + ->update([$name => null]); + } + + /** + * 查询默认不包含软删除数据 + * @access protected + * @param Query $query 查询对象 + * @return void + */ + protected function base($query) + { + $field = $this->getDeleteTimeField(true); + $query->useSoftDelete($field); + } + + /** + * 获取软删除字段 + * @access public + * @param bool $read 是否查询操作 写操作的时候会自动去掉表别名 + * @return string + */ + protected function getDeleteTimeField($read = false) + { + $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time'; + if (!strpos($field, '.')) { + $field = '__TABLE__.' . $field; + } + if (!$read && strpos($field, '.')) { + $array = explode('.', $field); + $field = array_pop($array); + } + return $field; + } +} diff --git a/thinkphp/library/traits/think/Instance.php b/thinkphp/library/traits/think/Instance.php new file mode 100755 index 0000000..ba45ddd --- /dev/null +++ b/thinkphp/library/traits/think/Instance.php @@ -0,0 +1,45 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace traits\think; + +use think\Exception; + +trait Instance +{ + protected static $instance = null; + + /** + * @param array $options + * @return static + */ + public static function instance($options = []) + { + if (is_null(self::$instance)) { + self::$instance = new self($options); + } + return self::$instance; + } + + // 静态调用 + public static function __callStatic($method, $params) + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + $call = substr($method, 1); + if (0 === strpos($method, '_') && is_callable([self::$instance, $call])) { + return call_user_func_array([self::$instance, $call], $params); + } else { + throw new Exception("method not exists:" . $method); + } + } +} diff --git a/thinkphp/library/traits/think/code.jpg b/thinkphp/library/traits/think/code.jpg new file mode 100755 index 0000000..dd365a7 Binary files /dev/null and b/thinkphp/library/traits/think/code.jpg differ diff --git a/thinkphp/logo.png b/thinkphp/logo.png new file mode 100755 index 0000000..25fd059 Binary files /dev/null and b/thinkphp/logo.png differ diff --git a/thinkphp/start.php b/thinkphp/start.php new file mode 100755 index 0000000..8af62ef --- /dev/null +++ b/thinkphp/start.php @@ -0,0 +1,18 @@ +<?php +// +---------------------------------------------------------------------- +// | ThinkPHP [ WE CAN DO IT JUST THINK ] +// +---------------------------------------------------------------------- +// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved. +// +---------------------------------------------------------------------- +// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) +// +---------------------------------------------------------------------- +// | Author: liu21st <liu21st@gmail.com> +// +---------------------------------------------------------------------- + +namespace think; + +// ThinkPHP 引导文件 +// 加载基础文件 +require __DIR__ . '/base.php'; +// 执行应用 +App::run()->send(); diff --git a/thinkphp/tpl/default_index.tpl b/thinkphp/tpl/default_index.tpl new file mode 100755 index 0000000..8538b4d --- /dev/null +++ b/thinkphp/tpl/default_index.tpl @@ -0,0 +1,10 @@ +<?php +namespace {$app}\{$module}{layer}; + +class Index{$suffix} +{ + public function index() + { + return '<style type="text/css">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p> ThinkPHP V5<br/><span style="font-size:30px">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style="font-size:22px;">[ V5.0 版本由 <a href="http://www.qiniu.com" target="qiniu">七牛云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="http://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script><script type="text/javascript" src="http://ad.topthink.com/Public/static/client.js"></script><thinkad id="ad_bd568ce7058a1091"></thinkad>'; + } +} diff --git a/thinkphp/tpl/dispatch_jump.tpl b/thinkphp/tpl/dispatch_jump.tpl new file mode 100755 index 0000000..583376b --- /dev/null +++ b/thinkphp/tpl/dispatch_jump.tpl @@ -0,0 +1,49 @@ +{__NOLAYOUT__}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/> + <title>跳转提示</title> + <style type="text/css"> + *{ padding: 0; margin: 0; } + body{ background: #fff; font-family: "Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif; color: #333; font-size: 16px; } + .system-message{ padding: 24px 48px; } + .system-message h1{ font-size: 100px; font-weight: normal; line-height: 120px; margin-bottom: 12px; } + .system-message .jump{ padding-top: 10px; } + .system-message .jump a{ color: #333; } + .system-message .success,.system-message .error{ line-height: 1.8em; font-size: 36px; } + .system-message .detail{ font-size: 12px; line-height: 20px; margin-top: 12px; display: none; } + </style> +</head> +<body> + <div class="system-message"> + <?php switch ($code) {?> + <?php case 1:?> + <h1>:)</h1> + <p class="success"><?php echo(strip_tags($msg));?></p> + <?php break;?> + <?php case 0:?> + <h1>:(</h1> + <p class="error"><?php echo(strip_tags($msg));?></p> + <?php break;?> + <?php } ?> + <p class="detail"></p> + <p class="jump"> + 页面自动 <a id="href" href="<?php echo($url);?>">跳转</a> 等待时间: <b id="wait"><?php echo($wait);?></b> + </p> + </div> + <script type="text/javascript"> + (function(){ + var wait = document.getElementById('wait'), + href = document.getElementById('href').href; + var interval = setInterval(function(){ + var time = --wait.innerHTML; + if(time <= 0) { + location.href = href; + clearInterval(interval); + }; + }, 1000); + })(); + </script> +</body> +</html> diff --git a/thinkphp/tpl/page_trace.tpl b/thinkphp/tpl/page_trace.tpl new file mode 100755 index 0000000..7c5df6f --- /dev/null +++ b/thinkphp/tpl/page_trace.tpl @@ -0,0 +1,71 @@ +<div id="think_page_trace" style="position: fixed;bottom:0;right:0;font-size:14px;width:100%;z-index: 999999;color: #000;text-align:left;font-family:'微软雅黑';"> + <div id="think_page_trace_tab" style="display: none;background:white;margin:0;height: 250px;"> + <div id="think_page_trace_tab_tit" style="height:30px;padding: 6px 12px 0;border-bottom:1px solid #ececec;border-top:1px solid #ececec;font-size:16px"> + <?php foreach ($trace as $key => $value) {?> + <span style="color:#000;padding-right:12px;height:30px;line-height:30px;display:inline-block;margin-right:3px;cursor:pointer;font-weight:700"><?php echo $key ?></span> + <?php }?> + </div> + <div id="think_page_trace_tab_cont" style="overflow:auto;height:212px;padding:0;line-height: 24px"> + <?php foreach ($trace as $info) {?> + <div style="display:none;"> + <ol style="padding: 0; margin:0"> + <?php + if (is_array($info)) { + foreach ($info as $k => $val) { + echo '<li style="border-bottom:1px solid #EEE;font-size:14px;padding:0 12px">' . (is_numeric($k) ? '' : $k.' : ') . htmlentities(print_r($val,true), ENT_COMPAT, 'utf-8') . '</li>'; + } + } + ?> + </ol> + </div> + <?php }?> + </div> + </div> + <div id="think_page_trace_close" style="display:none;text-align:right;height:15px;position:absolute;top:10px;right:12px;cursor:pointer;"><img style="vertical-align:top;" src="data:image/gif;base64,R0lGODlhDwAPAJEAAAAAAAMDA////wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MUQxMjc1MUJCQUJDMTFFMTk0OUVGRjc3QzU4RURFNkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MUQxMjc1MUNCQUJDMTFFMTk0OUVGRjc3QzU4RURFNkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxRDEyNzUxOUJBQkMxMUUxOTQ5RUZGNzdDNThFREU2QSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxRDEyNzUxQUJBQkMxMUUxOTQ5RUZGNzdDNThFREU2QSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAAAAAAALAAAAAAPAA8AAAIdjI6JZqotoJPR1fnsgRR3C2jZl3Ai9aWZZooV+RQAOw==" /></div> +</div> +<div id="think_page_trace_open" style="height:30px;float:right;text-align:right;overflow:hidden;position:fixed;bottom:0;right:0;color:#000;line-height:30px;cursor:pointer;"> + <div style="background:#232323;color:#FFF;padding:0 6px;float:right;line-height:30px;font-size:14px"><?php echo \think\Debug::getUseTime().'s ';?></div> + <img width="30" style="" title="ShowPageTrace" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVERDVENkZGQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjVERDVENzAwQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NURENUQ2RkRCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NURENUQ2RkVCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fx6IRAAAMCElEQVR42sxae3BU1Rk/9+69+8xuNtkHJAFCSIAkhMgjCCJQUi0GtEIVbP8Qq9LH2No6TmfaztjO2OnUdvqHFMfOVFTqIK0vUEEeqUBARCsEeYQkEPJoEvIiELLvvc9z+p27u2F3s5tsBB1OZiebu5dzf7/v/L7f952zMM8cWIwY+Mk2ulCp92Fnq3XvnzArr2NZnYNldDp0Gw+/OEQ4+obQn5D+4Ubb22+YOGsWi/Todh8AHglKEGkEsnHBQ162511GZFgW6ZCBM9/W4H3iNSQqIe09O196dLKX7d1O39OViP/wthtkND62if/wj/DbMpph8BY/m9xy8BoBmQk+mHqZQGNy4JYRwCoRbwa8l4JXw6M+orJxpU0U6ToKy/5bQsAiTeokGKkTx46RRxxEUgrwGgF4MWNNEJCGgYTvpgnY1IJWg5RzfqLgvcIgktX0i8dmMlFA8qCQ5L0Z/WObPLUxT1i4lWSYDISoEfBYGvM+LlMQQdkLHoWRRZ8zYQI62Thswe5WTORGwNXDcGjqeOA9AF7B8rhzsxMBEoJ8oJKaqPu4hblHMCMPwl9XeNWyb8xkB/DDGYKfMAE6aFL7xesZ389JlgG3XHEMI6UPDOP6JHHu67T2pwNPI69mCP4rEaBDUAJaKc/AOuXiwH07VCS3w5+UQMAuF/WqGI+yFIwVNBwemBD4r0wgQiKoFZa00sEYTwss32lA1tPwVxtc8jQ5/gWCwmGCyUD8vRT0sHBFW4GJDvZmrJFWRY1EkrGA6ZB8/10fOZSSj0E6F+BSP7xidiIzhBmKB09lEwHPkG+UQIyEN44EBiT5vrv2uJXyPQqSqO930fxvcvwbR/+JAkD9EfASgI9EHlp6YiHO4W+cAB20SnrFqxBbNljiXf1Pl1K2S0HCWfiog3YlAD5RGwwxK6oUjTweuVigLjyB0mX410mAFnMoVK1lvvUvgt8fUJH0JVyjuvcmg4dE5mUiFtD24AZ4qBVELxXKS+pMxN43kSdzNwudJ+bQbLlmnxvPOQoCugSap1GnSRoG8KOiKbH+rIA0lEeSAg3y6eeQ6XI2nrYnrPM89bUTgI0Pdqvl50vlNbtZxDUBcLBK0kPd5jPziyLdojJIN0pq5/mdzwL4UVvVInV5ncQEPNOUxa9d0TU+CW5l+FoI0GSDKHVVSOs+0KOsZoxwOzSZNFGv0mQ9avyLCh2Hpm+70Y0YJoJVgmQv822wnDC8Miq6VjJ5IFed0QD1YiAbT+nQE8v/RMZfmgmcCRHIIu7Bmcp39oM9fqEychcA747KxQ/AEyqQonl7hATtJmnhO2XYtgcia01aSbVMenAXrIomPcLgEBA4liGBzFZAT8zBYqW6brI67wg8sFVhxBhwLwBP2+tqBQqqK7VJKGh/BRrfTr6nWL7nYBaZdBJHqrX3kPEPap56xwE/GvjJTRMADeMCdcGpGXL1Xh4ZL8BDOlWkUpegfi0CeDzeA5YITzEnddv+IXL+UYCmqIvqC9UlUC/ki9FipwVjunL3yX7dOTLeXmVMAhbsGporPfyOBTm/BJ23gTVehsvXRnSewagUfpBXF3p5pygKS7OceqTjb7h2vjr/XKm0ZofKSI2Q/J102wHzatZkJPYQ5JoKsuK+EoHJakVzubzuLQDepCKllTZi9AG0DYg9ZLxhFaZsOu7bvlmVI5oPXJMQJcHxHClSln1apFTvAimeg48u0RWFeZW4lVcjbQWZuIQK1KozZfIDO6CSQmQQXdpBaiKZyEWThVK1uEc6v7V7uK0ysduExPZx4vysDR+4SelhBYm0R6LBuR4PXts8MYMcJPsINo4YZCDLj0sgB0/vLpPXvA2Tn42Cv5rsLulGubzW0sEd3d4W/mJt2Kck+DzDMijfPLOjyrDhXSh852B+OvflqAkoyXO1cYfujtc/i3jJSAwhgfFlp20laMLOku/bC7prgqW7lCn4auE5NhcXPd3M7x70+IceSgZvNljCd9k3fLjYsPElqLR14PXQZqD2ZNkkrAB79UeJUebFQmXpf8ZcAQt2XrMQdyNUVBqZoUzAFyp3V3xi/MubUA/mCT4Fhf038PC8XplhWnCmnK/ZzyC2BSTRSqKVOuY2kB8Jia0lvvRIVoP+vVWJbYarf6p655E2/nANBMCWkgD49DA0VAMyI1OLFMYCXiU9bmzi9/y5i/vsaTpHPHidTofzLbM65vMPva9HlovgXp0AvjtaqYMfDD0/4mAsYE92pxa+9k1QgCnRVObCpojpzsKTPvayPetTEgBdwnssjuc0kOBFX+q3HwRQxdrOLAqeYRjkMk/trTSu2Z9Lik7CfF0AvjtqAhS4NHobGXUnB5DQs8hG8p/wMX1r4+8xkmyvQ50JVq72TVeXbz3HvpWaQJi57hJYTw4kGbtS+C2TigQUtZUX+X27QQq2ePBZBru/0lxTm8fOOQ5yaZOZMAV+he4FqIMB+LQB0UgMSajANX29j+vbmly8ipRvHeSQoQOkM5iFXcPQCVwDMs5RBCQmaPOyvbNd6uwvQJ183BZQG3Zc+Eiv7vQOKu8YeDmMcJlt2ckyftVeMIGLBCmdMHl/tFILYwGPjXWO3zOfSq/+om+oa7Mlh2fpSsRGLp7RAW3FUVjNHgiMhyE6zBFjM2BdkdJGO7nP1kJXWAtBuBpPIAu7f+hhu7bFXIuC5xWrf0X2xreykOsUyKkF2gwadbrXDcXrfKxR43zGcSj4t/cCgr+a1iy6EjE5GYktUCl9fwfMeylyooGF48bN2IGLTw8x7StS7sj8TF9FmPGWQhm3rRR+o9lhvjJvSYAdfDUevI1M6bnX/OwWaDMOQ8RPgKRo0eulBTdT8AW2kl8e9L7UHghHwMfLiZPNoSpx0yugpQZaFqKWqxVSM3a2pN1SAhC2jf94I7ybBI7EL5A2Wvu5ht3xsoEt4+Ay/abXgCQAxyOeDsDlTCQzy75ohcGgv9Tra9uiymRUYTLrswOLlCdfAQf7HPDQQ4ErAH5EDXB9cMxWYpjtXApRncojS0sbV/cCgHTHwGNBJy+1PQE2x56FpaVR7wfQGZ37V+V+19EiHNvR6q1fRUjqvbjbMq1/qfHxbTrE10ePY2gPFk48D2CVMTf1AF4PXvyYR9dV6Wf7H413m3xTWQvYGhQ7mfYwA5mAX+18Vue05v/8jG/fZX/IW5MKPKtjSYlt0ellxh+/BOCPAwYaeVr0QofZFxJWVWC8znG70au6llVmktsF0bfHF6k8fvZ5esZJbwHwwnjg59tXz6sL/P0NUZDuSNu1mnJ8Vab17+cy005A9wtOpp3i0bZdpJLUil00semAwN45LgEViZYe3amNye0B6A9chviSlzXVsFtyN5/1H3gaNmMpn8Fz0GpYFp6Zw615H/LpUuRQQDMCL82n5DpBSawkvzIdN2ypiT8nSLth8Pk9jnjwdFzH3W4XW6KMBfwB569NdcGX93mC16tTflcArcYUc/mFuYbV+8zY0SAjAVoNErNgWjtwumJ3wbn/HlBFYdxHvSkJJEc+Ngal9opSwyo9YlITX2C/P/+gf8sxURSLR+mcZUmeqaS9wrh6vxW5zxFCOqFi90RbDWq/YwZmnu1+a6OvdpvRqkNxxe44lyl4OobEnpKA6Uox5EfH9xzPs/HRKrTPWdIQrK1VZDU7ETiD3Obpl+8wPPCRBbkbwNtpW9AbBe5L1SMlj3tdTxk/9W47JUmqS5HU+JzYymUKXjtWVmT9RenIhgXc+nroWLyxXJhmL112OdB8GCsk4f8oZJucnvmmtR85mBn10GZ0EKSCMUSAR3ukcXd5s7LvLD3me61WkuTCpJzYAyRurMB44EdEJzTfU271lUJC03YjXJXzYOGZwN4D8eB5jlfLrdWfzGRW7icMPfiSO6Oe7s20bmhdgLX4Z23B+s3JgQESzUDiMboSzDMHFpNMwccGePauhfwjzwnI2wu9zKGgEFg80jcZ7MHllk07s1H+5yojtUQTlH4nFdLKTGwDmPbIklOb1L1zO4T6N8NCuDLFLS/C63c0eNRimZ++s5BMBHxU11jHchI9oFVUxRh/eMDzHEzGYu0Lg8gJ7oS/tFCwoic44fyUtix0n/46vP4bf+//BRgAYwDDar4ncHIAAAAASUVORK5CYII="> +</div> + +<script type="text/javascript"> + (function(){ + var tab_tit = document.getElementById('think_page_trace_tab_tit').getElementsByTagName('span'); + var tab_cont = document.getElementById('think_page_trace_tab_cont').getElementsByTagName('div'); + var open = document.getElementById('think_page_trace_open'); + var close = document.getElementById('think_page_trace_close').children[0]; + var trace = document.getElementById('think_page_trace_tab'); + var cookie = document.cookie.match(/thinkphp_show_page_trace=(\d\|\d)/); + var history = (cookie && typeof cookie[1] != 'undefined' && cookie[1].split('|')) || [0,0]; + open.onclick = function(){ + trace.style.display = 'block'; + this.style.display = 'none'; + close.parentNode.style.display = 'block'; + history[0] = 1; + document.cookie = 'thinkphp_show_page_trace='+history.join('|') + } + close.onclick = function(){ + trace.style.display = 'none'; + this.parentNode.style.display = 'none'; + open.style.display = 'block'; + history[0] = 0; + document.cookie = 'thinkphp_show_page_trace='+history.join('|') + } + for(var i = 0; i < tab_tit.length; i++){ + tab_tit[i].onclick = (function(i){ + return function(){ + for(var j = 0; j < tab_cont.length; j++){ + tab_cont[j].style.display = 'none'; + tab_tit[j].style.color = '#999'; + } + tab_cont[i].style.display = 'block'; + tab_tit[i].style.color = '#000'; + history[1] = i; + document.cookie = 'thinkphp_show_page_trace='+history.join('|') + } + })(i) + } + parseInt(history[0]) && open.click(); + tab_tit[history[1]].click(); + })(); +</script> diff --git a/thinkphp/tpl/stsoft.php b/thinkphp/tpl/stsoft.php new file mode 100755 index 0000000..242661f --- /dev/null +++ b/thinkphp/tpl/stsoft.php @@ -0,0 +1,3 @@ +<?php + header("Content-type: text/html; charset=utf-8"); + echo base64_decode("KiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogPGJyLz4qIFdTVE1hcnTlpJrnlKjmiLfllYbln44NCiA8YnIvPiog54mI5p2D5omA5pyJIDIwMTYtMjA2NiDlub/lt57llYbmt5jkv6Hmga/np5HmioDmnInpmZDlhazlj7jvvIzlubbkv53nlZnmiYDmnInmnYPliKnjgIINCiA8YnIvPiog5a6Y572R5Zyw5Z2AOmh0dHA6Ly93d3cud3N0bWFydC5uZXQNCiA8YnIvPiog5Lqk5rWB56S+5Yy6Omh0dHA6Ly9iYnMuc2hhbmd0YW9zb2Z0LmNvbQ0KIDxici8+KiDogZTns7tRUToxNTMyODk5NzANCiA8YnIvPiogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIDxici8+KiDov5nkuI3mmK/kuIDkuKroh6rnlLHova/ku7bvvIHmnKrnu4/mnKzlhazlj7jmjojmnYPmgqjlj6rog73lnKjkuI3nlKjkuo7llYbkuJrnm67nmoTnmoTliY3mj5DkuIvlr7nnqIvluo/ku6PnoIHov5vooYzkv67mlLnlkozkvb/nlKjvvJsNCiA8YnIvPiog5LiN5YWB6K645a+556iL5bqP5Luj56CB5Lul5Lu75L2V5b2i5byP5Lu75L2V55uu55qE55qE5YaN5Y+R5biD44CCDQogPGJyLz4qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0="); \ No newline at end of file diff --git a/thinkphp/tpl/think_exception.tpl b/thinkphp/tpl/think_exception.tpl new file mode 100755 index 0000000..fef8979 --- /dev/null +++ b/thinkphp/tpl/think_exception.tpl @@ -0,0 +1,536 @@ +<?php + if(!function_exists('parse_padding')){ + function parse_padding($source) + { + $length = strlen(strval(count($source['source']) + $source['first'])); + return 40 + ($length - 1) * 8; + } + } + + if(!function_exists('parse_class')){ + function parse_class($name) + { + $names = explode('\\', $name); + return '<abbr title="'.$name.'">'.end($names).'</abbr>'; + } + } + + if(!function_exists('parse_file')){ + function parse_file($file, $line) + { + return '<a class="toggle" title="'."{$file} line {$line}".'">'.basename($file)." line {$line}".'</a>'; + } + } + + if(!function_exists('parse_args')){ + function parse_args($args) + { + $result = []; + + foreach ($args as $key => $item) { + switch (true) { + case is_object($item): + $value = sprintf('<em>object</em>(%s)', parse_class(get_class($item))); + break; + case is_array($item): + if(count($item) > 3){ + $value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3))); + } else { + $value = sprintf('[%s]', parse_args($item)); + } + break; + case is_string($item): + if(strlen($item) > 20){ + $value = sprintf( + '\'<a class="toggle" title="%s">%s...</a>\'', + htmlentities($item), + htmlentities(substr($item, 0, 20)) + ); + } else { + $value = sprintf("'%s'", htmlentities($item)); + } + break; + case is_int($item): + case is_float($item): + $value = $item; + break; + case is_null($item): + $value = '<em>null</em>'; + break; + case is_bool($item): + $value = '<em>' . ($item ? 'true' : 'false') . '</em>'; + break; + case is_resource($item): + $value = '<em>resource</em>'; + break; + default: + $value = htmlentities(str_replace("\n", '', var_export(strval($item), true))); + break; + } + + $result[] = is_int($key) ? $value : "'{$key}' => {$value}"; + } + + return implode(', ', $result); + } + } +?> +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title><?php echo \think\Lang::get('System Error'); ?></title> + <meta name="robots" content="noindex,nofollow" /> + <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> + <style> + /* Base */ + body { + color: #333; + font: 14px Verdana, "Helvetica Neue", helvetica, Arial, 'Microsoft YaHei', sans-serif; + margin: 0; + padding: 0 20px 20px; + word-break: break-word; + } + h1{ + margin: 10px 0 0; + font-size: 28px; + font-weight: 500; + line-height: 32px; + } + h2{ + color: #4288ce; + font-weight: 400; + padding: 6px 0; + margin: 6px 0 0; + font-size: 18px; + border-bottom: 1px solid #eee; + } + h3.subheading { + color: #4288ce; + margin: 6px 0 0; + font-weight: 400; + } + h3{ + margin: 12px; + font-size: 16px; + font-weight: bold; + } + abbr{ + cursor: help; + text-decoration: underline; + text-decoration-style: dotted; + } + a{ + color: #868686; + cursor: pointer; + } + a:hover{ + text-decoration: underline; + } + .line-error{ + background: #f8cbcb; + } + + .echo table { + width: 100%; + } + + .echo pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border: 0; + border-radius: 3px; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + } + + .echo pre > pre { + padding: 0; + margin: 0; + } + /* Layout */ + .col-md-3 { + width: 25%; + } + .col-md-9 { + width: 75%; + } + [class^="col-md-"] { + float: left; + } + .clearfix { + clear:both; + } + @media only screen + and (min-device-width : 375px) + and (max-device-width : 667px) { + .col-md-3, + .col-md-9 { + width: 100%; + } + } + /* Exception Info */ + .exception { + margin-top: 20px; + } + .exception .message{ + padding: 12px; + border: 1px solid #ddd; + border-bottom: 0 none; + line-height: 18px; + font-size:16px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; + } + + .exception .code{ + float: left; + text-align: center; + color: #fff; + margin-right: 12px; + padding: 16px; + border-radius: 4px; + background: #999; + } + .exception .source-code{ + padding: 6px; + border: 1px solid #ddd; + + background: #f9f9f9; + overflow-x: auto; + + } + .exception .source-code pre{ + margin: 0; + } + .exception .source-code pre ol{ + margin: 0; + color: #4288ce; + display: inline-block; + min-width: 100%; + box-sizing: border-box; + font-size:14px; + font-family: "Century Gothic",Consolas,"Liberation Mono",Courier,Verdana; + padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40; ?>px; + } + .exception .source-code pre li{ + border-left: 1px solid #ddd; + height: 18px; + line-height: 18px; + } + .exception .source-code pre code{ + color: #333; + height: 100%; + display: inline-block; + border-left: 1px solid #fff; + font-size:14px; + font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; + } + .exception .trace{ + padding: 6px; + border: 1px solid #ddd; + border-top: 0 none; + line-height: 16px; + font-size:14px; + font-family: Consolas,"Liberation Mono",Courier,Verdana,"微软雅黑"; + } + .exception .trace ol{ + margin: 12px; + } + .exception .trace ol li{ + padding: 2px 4px; + } + .exception div:last-child{ + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + } + + /* Exception Variables */ + .exception-var table{ + width: 100%; + margin: 12px 0; + box-sizing: border-box; + table-layout:fixed; + word-wrap:break-word; + } + .exception-var table caption{ + text-align: left; + font-size: 16px; + font-weight: bold; + padding: 6px 0; + } + .exception-var table caption small{ + font-weight: 300; + display: inline-block; + margin-left: 10px; + color: #ccc; + } + .exception-var table tbody{ + font-size: 13px; + font-family: Consolas,"Liberation Mono",Courier,"微软雅黑"; + } + .exception-var table td{ + padding: 0 6px; + vertical-align: top; + word-break: break-all; + } + .exception-var table td:first-child{ + width: 28%; + font-weight: bold; + white-space: nowrap; + } + .exception-var table td pre{ + margin: 0; + } + + /* Copyright Info */ + .copyright{ + margin-top: 24px; + padding: 12px 0; + border-top: 1px solid #eee; + text-align: center; + } + + /* SPAN elements with the classes below are added by prettyprint. */ + pre.prettyprint .pln { color: #000 } /* plain text */ + pre.prettyprint .str { color: #080 } /* string content */ + pre.prettyprint .kwd { color: #008 } /* a keyword */ + pre.prettyprint .com { color: #800 } /* a comment */ + pre.prettyprint .typ { color: #606 } /* a type name */ + pre.prettyprint .lit { color: #066 } /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + pre.prettyprint .pun, pre.prettyprint .opn, pre.prettyprint .clo { color: #660 } + pre.prettyprint .tag { color: #008 } /* a markup tag name */ + pre.prettyprint .atn { color: #606 } /* a markup attribute name */ + pre.prettyprint .atv { color: #080 } /* a markup attribute value */ + pre.prettyprint .dec, pre.prettyprint .var { color: #606 } /* a declaration; a variable name */ + pre.prettyprint .fun { color: red } /* a function name */ + </style> +</head> +<body> + <div class="echo"> + <?php echo $echo;?> + </div> + <?php if(\think\App::$debug) { ?> + <div class="exception"> + <div class="message"> + + <div class="info"> + <div> + <h2>[<?php echo $code; ?>]&nbsp;<?php echo sprintf('%s in %s', parse_class($name), parse_file($file, $line)); ?></h2> + </div> + <div><h1><?php echo nl2br(htmlentities($message)); ?></h1></div> + </div> + + </div> + <?php if(!empty($source)){?> + <div class="source-code"> + <pre class="prettyprint lang-php"><ol start="<?php echo $source['first']; ?>"><?php foreach ((array) $source['source'] as $key => $value) { ?><li class="line-<?php echo $key + $source['first']; ?>"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre> + </div> + <?php }?> + <div class="trace"> + <h2>Call Stack</h2> + <ol> + <li><?php echo sprintf('in %s', parse_file($file, $line)); ?></li> + <?php foreach ((array) $trace as $value) { ?> + <li> + <?php + // Show Function + if($value['function']){ + echo sprintf( + 'at %s%s%s(%s)', + isset($value['class']) ? parse_class($value['class']) : '', + isset($value['type']) ? $value['type'] : '', + $value['function'], + isset($value['args'])?parse_args($value['args']):'' + ); + } + + // Show line + if (isset($value['file']) && isset($value['line'])) { + echo sprintf(' in %s', parse_file($value['file'], $value['line'])); + } + ?> + </li> + <?php } ?> + </ol> + </div> + </div> + <?php } else { ?> + <div class="exception"> + + <div class="info"><h1><?php echo htmlentities($message); ?></h1></div> + + </div> + <?php } ?> + + <?php if(!empty($datas)){ ?> + <div class="exception-var"> + <h2>Exception Datas</h2> + <?php foreach ((array) $datas as $label => $value) { ?> + <table> + <?php if(empty($value)){ ?> + <caption><?php echo $label; ?><small>empty</small></caption> + <?php } else { ?> + <caption><?php echo $label; ?></caption> + <tbody> + <?php foreach ((array) $value as $key => $val) { ?> + <tr> + <td><?php echo htmlentities($key); ?></td> + <td> + <?php + if(is_array($val) || is_object($val)){ + echo htmlentities(json_encode($val, JSON_PRETTY_PRINT)); + } else if(is_bool($val)) { + echo $val ? 'true' : 'false'; + } else if(is_scalar($val)) { + echo htmlentities($val); + } else { + echo 'Resource'; + } + ?> + </td> + </tr> + <?php } ?> + </tbody> + <?php } ?> + </table> + <?php } ?> + </div> + <?php } ?> + + <?php if(!empty($tables1)){ ?> + <div class="exception-var"> + <h2>Environment Variables</h2> + <?php foreach ((array) $tables as $label => $value) { ?> + <div> + <?php if(empty($value)){ ?> + <div class="clearfix"> + <div class="col-md-3"><strong><?php echo $label; ?></strong></div> + <div class="col-md-9"><small>empty</small></div> + </div> + <?php } else { ?> + <h3 class="subheading"><?php echo $label; ?></h3> + <div> + <?php foreach ((array) $value as $key => $val) { ?> + <div class="clearfix"> + <div class="col-md-3"><strong><?php echo htmlentities($key); ?></strong></div> + <div class="col-md-9"><small> + <?php + if(is_array($val) || is_object($val)){ + echo htmlentities(json_encode($val, JSON_PRETTY_PRINT)); + } else if(is_bool($val)) { + echo $val ? 'true' : 'false'; + } else if(is_scalar($val)) { + echo htmlentities($val); + } else { + echo 'Resource'; + } + ?> + </small></div> + </div> + <?php } ?> + </div> + <?php } ?> + </div> + <?php } ?> + </div> + <?php } ?> + + <div class="copyright"> + <span style='color:#777;'><a style='text-decoration:none;color:#777;' title="官方网站" href="http://www.wstmart.net">WSTMart</a> @ <a style='text-decoration:none;color:#777;' title="官方网站" href="http://www.shangtao.net">商淘软件</a> - 为电商加速</span> + </div> + <?php if(\think\App::$debug) { ?> + <script> + var LINE = <?php echo $line; ?>; + + function $(selector, node){ + var elements; + + node = node || document; + if(document.querySelectorAll){ + elements = node.querySelectorAll(selector); + } else { + switch(selector.substr(0, 1)){ + case '#': + elements = [node.getElementById(selector.substr(1))]; + break; + case '.': + if(document.getElementsByClassName){ + elements = node.getElementsByClassName(selector.substr(1)); + } else { + elements = get_elements_by_class(selector.substr(1), node); + } + break; + default: + elements = node.getElementsByTagName(); + } + } + return elements; + + function get_elements_by_class(search_class, node, tag) { + var elements = [], eles, + pattern = new RegExp('(^|\\s)' + search_class + '(\\s|$)'); + + node = node || document; + tag = tag || '*'; + + eles = node.getElementsByTagName(tag); + for(var i = 0; i < eles.length; i++) { + if(pattern.test(eles[i].className)) { + elements.push(eles[i]) + } + } + + return elements; + } + } + + $.getScript = function(src, func){ + var script = document.createElement('script'); + + script.async = 'async'; + script.src = src; + script.onload = func || function(){}; + + $('head')[0].appendChild(script); + } + + ;(function(){ + var files = $('.toggle'); + var ol = $('ol', $('.prettyprint')[0]); + var li = $('li', ol[0]); + + // 短路径和长路径变换 + for(var i = 0; i < files.length; i++){ + files[i].ondblclick = function(){ + var title = this.title; + + this.title = this.innerHTML; + this.innerHTML = title; + } + } + + // 设置出错行 + var err_line = $('.line-' + LINE, ol[0])[0]; + err_line.className = err_line.className + ' line-error'; + + $.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function(){ + prettyPrint(); + + // 解决Firefox浏览器一个很诡异的问题 + // 当代码高亮后,ol的行号莫名其妙的错位 + // 但是只要刷新li里面的html重新渲染就没有问题了 + if(window.navigator.userAgent.indexOf('Firefox') >= 0){ + ol[0].innerHTML = ol[0].innerHTML; + } + }); + + })(); + </script> + <?php } ?> +</body> +</html> diff --git a/upload/2018-06/5b1786a0b2c35.png b/upload/2018-06/5b1786a0b2c35.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/2018-06/5b1786a0b2c35.png differ diff --git a/upload/accreds/2016-09/57edd7428f5e1.png b/upload/accreds/2016-09/57edd7428f5e1.png new file mode 100755 index 0000000..51bde02 Binary files /dev/null and b/upload/accreds/2016-09/57edd7428f5e1.png differ diff --git a/upload/accreds/2016-09/57edd7551cf4a.png b/upload/accreds/2016-09/57edd7551cf4a.png new file mode 100755 index 0000000..496e3d8 Binary files /dev/null and b/upload/accreds/2016-09/57edd7551cf4a.png differ diff --git a/upload/accreds/2017-11/5a0a93b4d8a52.png b/upload/accreds/2017-11/5a0a93b4d8a52.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/accreds/2017-11/5a0a93b4d8a52.png differ diff --git a/upload/accreds/2017-12/5a28ddf58d334.jpg b/upload/accreds/2017-12/5a28ddf58d334.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/accreds/2017-12/5a28ddf58d334.jpg differ diff --git a/upload/accreds/2017-12/5a28de081036d.png b/upload/accreds/2017-12/5a28de081036d.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/accreds/2017-12/5a28de081036d.png differ diff --git a/upload/accreds/txt.txt b/upload/accreds/txt.txt new file mode 100755 index 0000000..0f0557b --- /dev/null +++ b/upload/accreds/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/adspic/2017-06/5952047b41189.jpg b/upload/adspic/2017-06/5952047b41189.jpg new file mode 100755 index 0000000..1e37abe Binary files /dev/null and b/upload/adspic/2017-06/5952047b41189.jpg differ diff --git a/upload/adspic/2017-06/59520643d6c51.jpg b/upload/adspic/2017-06/59520643d6c51.jpg new file mode 100755 index 0000000..512e24d Binary files /dev/null and b/upload/adspic/2017-06/59520643d6c51.jpg differ diff --git a/upload/adspic/2017-09/59b89167f2e19.jpg b/upload/adspic/2017-09/59b89167f2e19.jpg new file mode 100755 index 0000000..bae7bb6 Binary files /dev/null and b/upload/adspic/2017-09/59b89167f2e19.jpg differ diff --git a/upload/adspic/2017-09/59b8916aec521.jpg b/upload/adspic/2017-09/59b8916aec521.jpg new file mode 100755 index 0000000..4af3cf4 Binary files /dev/null and b/upload/adspic/2017-09/59b8916aec521.jpg differ diff --git a/upload/adspic/2017-09/59b89177c8cd6.jpg b/upload/adspic/2017-09/59b89177c8cd6.jpg new file mode 100755 index 0000000..73109a6 Binary files /dev/null and b/upload/adspic/2017-09/59b89177c8cd6.jpg differ diff --git a/upload/adspic/2017-09/59b898b3f145c.jpg b/upload/adspic/2017-09/59b898b3f145c.jpg new file mode 100755 index 0000000..4af3cf4 Binary files /dev/null and b/upload/adspic/2017-09/59b898b3f145c.jpg differ diff --git a/upload/adspic/2017-09/59b8995db3511.jpg b/upload/adspic/2017-09/59b8995db3511.jpg new file mode 100755 index 0000000..bae7bb6 Binary files /dev/null and b/upload/adspic/2017-09/59b8995db3511.jpg differ diff --git a/upload/adspic/2017-09/59bf2517f2de3.png b/upload/adspic/2017-09/59bf2517f2de3.png new file mode 100755 index 0000000..fd80e36 Binary files /dev/null and b/upload/adspic/2017-09/59bf2517f2de3.png differ diff --git a/upload/adspic/2017-09/59bf253300bb6.jpg b/upload/adspic/2017-09/59bf253300bb6.jpg new file mode 100755 index 0000000..ba77510 Binary files /dev/null and b/upload/adspic/2017-09/59bf253300bb6.jpg differ diff --git a/upload/adspic/2017-09/59bf2bd315efc.jpg b/upload/adspic/2017-09/59bf2bd315efc.jpg new file mode 100755 index 0000000..bae7bb6 Binary files /dev/null and b/upload/adspic/2017-09/59bf2bd315efc.jpg differ diff --git a/upload/adspic/2017-09/59bf2bea7b7c6.jpg b/upload/adspic/2017-09/59bf2bea7b7c6.jpg new file mode 100755 index 0000000..ba77510 Binary files /dev/null and b/upload/adspic/2017-09/59bf2bea7b7c6.jpg differ diff --git a/upload/adspic/2017-09/59bf2c118fab6.jpg b/upload/adspic/2017-09/59bf2c118fab6.jpg new file mode 100755 index 0000000..828db37 Binary files /dev/null and b/upload/adspic/2017-09/59bf2c118fab6.jpg differ diff --git a/upload/adspic/2017-09/59cee7f369cdb.png b/upload/adspic/2017-09/59cee7f369cdb.png new file mode 100755 index 0000000..bbe3b76 Binary files /dev/null and b/upload/adspic/2017-09/59cee7f369cdb.png differ diff --git a/upload/adspic/2017-09/59cee8c6ce9ca.jpg b/upload/adspic/2017-09/59cee8c6ce9ca.jpg new file mode 100755 index 0000000..f97ba26 Binary files /dev/null and b/upload/adspic/2017-09/59cee8c6ce9ca.jpg differ diff --git a/upload/adspic/2017-09/59cef7f982f89.png b/upload/adspic/2017-09/59cef7f982f89.png new file mode 100755 index 0000000..f9d579d Binary files /dev/null and b/upload/adspic/2017-09/59cef7f982f89.png differ diff --git a/upload/adspic/2017-09/59cef81dcb071.png b/upload/adspic/2017-09/59cef81dcb071.png new file mode 100755 index 0000000..d2422e5 Binary files /dev/null and b/upload/adspic/2017-09/59cef81dcb071.png differ diff --git a/upload/adspic/2017-09/59cef88c68546.png b/upload/adspic/2017-09/59cef88c68546.png new file mode 100755 index 0000000..c770b76 Binary files /dev/null and b/upload/adspic/2017-09/59cef88c68546.png differ diff --git a/upload/adspic/2017-09/59cef8b096c2b.png b/upload/adspic/2017-09/59cef8b096c2b.png new file mode 100755 index 0000000..feef710 Binary files /dev/null and b/upload/adspic/2017-09/59cef8b096c2b.png differ diff --git a/upload/adspic/2017-09/59cef9a00dc5a.png b/upload/adspic/2017-09/59cef9a00dc5a.png new file mode 100755 index 0000000..bd018e7 Binary files /dev/null and b/upload/adspic/2017-09/59cef9a00dc5a.png differ diff --git a/upload/adspic/2017-09/59cef9b748110.png b/upload/adspic/2017-09/59cef9b748110.png new file mode 100755 index 0000000..b6d0120 Binary files /dev/null and b/upload/adspic/2017-09/59cef9b748110.png differ diff --git a/upload/adspic/2017-09/59cefa450c8a2.png b/upload/adspic/2017-09/59cefa450c8a2.png new file mode 100755 index 0000000..bae33a0 Binary files /dev/null and b/upload/adspic/2017-09/59cefa450c8a2.png differ diff --git a/upload/adspic/2017-09/59cefa620bda9.png b/upload/adspic/2017-09/59cefa620bda9.png new file mode 100755 index 0000000..8eb00e5 Binary files /dev/null and b/upload/adspic/2017-09/59cefa620bda9.png differ diff --git a/upload/adspic/2017-09/59cefad2e274c.png b/upload/adspic/2017-09/59cefad2e274c.png new file mode 100755 index 0000000..985ea80 Binary files /dev/null and b/upload/adspic/2017-09/59cefad2e274c.png differ diff --git a/upload/adspic/2017-09/59cefaf53f460.png b/upload/adspic/2017-09/59cefaf53f460.png new file mode 100755 index 0000000..5fae750 Binary files /dev/null and b/upload/adspic/2017-09/59cefaf53f460.png differ diff --git a/upload/adspic/2017-09/59cefb43336e1.png b/upload/adspic/2017-09/59cefb43336e1.png new file mode 100755 index 0000000..bf0360b Binary files /dev/null and b/upload/adspic/2017-09/59cefb43336e1.png differ diff --git a/upload/adspic/2017-09/59cefb8209703.png b/upload/adspic/2017-09/59cefb8209703.png new file mode 100755 index 0000000..aabd27a Binary files /dev/null and b/upload/adspic/2017-09/59cefb8209703.png differ diff --git a/upload/adspic/2017-09/59cefb9d6995f.png b/upload/adspic/2017-09/59cefb9d6995f.png new file mode 100755 index 0000000..2ff164f Binary files /dev/null and b/upload/adspic/2017-09/59cefb9d6995f.png differ diff --git a/upload/adspic/2017-09/59cefbb0b7de1.png b/upload/adspic/2017-09/59cefbb0b7de1.png new file mode 100755 index 0000000..832cc0b Binary files /dev/null and b/upload/adspic/2017-09/59cefbb0b7de1.png differ diff --git a/upload/adspic/2017-09/59cefd045fc0d.png b/upload/adspic/2017-09/59cefd045fc0d.png new file mode 100755 index 0000000..11a6978 Binary files /dev/null and b/upload/adspic/2017-09/59cefd045fc0d.png differ diff --git a/upload/adspic/2017-09/59cefd2477bdb.png b/upload/adspic/2017-09/59cefd2477bdb.png new file mode 100755 index 0000000..b108ba5 Binary files /dev/null and b/upload/adspic/2017-09/59cefd2477bdb.png differ diff --git a/upload/adspic/2017-09/59cefd44cb578.png b/upload/adspic/2017-09/59cefd44cb578.png new file mode 100755 index 0000000..8edee41 Binary files /dev/null and b/upload/adspic/2017-09/59cefd44cb578.png differ diff --git a/upload/adspic/2017-09/59cefd5f456bf.png b/upload/adspic/2017-09/59cefd5f456bf.png new file mode 100755 index 0000000..eb75c05 Binary files /dev/null and b/upload/adspic/2017-09/59cefd5f456bf.png differ diff --git a/upload/adspic/2017-09/59cefd7f12f5b.png b/upload/adspic/2017-09/59cefd7f12f5b.png new file mode 100755 index 0000000..e0b5f93 Binary files /dev/null and b/upload/adspic/2017-09/59cefd7f12f5b.png differ diff --git a/upload/adspic/2017-09/59cefd924d496.png b/upload/adspic/2017-09/59cefd924d496.png new file mode 100755 index 0000000..ddffc88 Binary files /dev/null and b/upload/adspic/2017-09/59cefd924d496.png differ diff --git a/upload/adspic/2017-09/59cf0ca497161.png b/upload/adspic/2017-09/59cf0ca497161.png new file mode 100755 index 0000000..3b16324 Binary files /dev/null and b/upload/adspic/2017-09/59cf0ca497161.png differ diff --git a/upload/adspic/2017-09/59cf0cf2d8641.png b/upload/adspic/2017-09/59cf0cf2d8641.png new file mode 100755 index 0000000..ec923df Binary files /dev/null and b/upload/adspic/2017-09/59cf0cf2d8641.png differ diff --git a/upload/adspic/2017-09/59cf0d35c9a54.png b/upload/adspic/2017-09/59cf0d35c9a54.png new file mode 100755 index 0000000..f9c8d8b Binary files /dev/null and b/upload/adspic/2017-09/59cf0d35c9a54.png differ diff --git a/upload/adspic/2017-09/59cf0df02f8ee.png b/upload/adspic/2017-09/59cf0df02f8ee.png new file mode 100755 index 0000000..cc5ffea Binary files /dev/null and b/upload/adspic/2017-09/59cf0df02f8ee.png differ diff --git a/upload/adspic/2017-09/59cf0df6d3d56.png b/upload/adspic/2017-09/59cf0df6d3d56.png new file mode 100755 index 0000000..cfced4d Binary files /dev/null and b/upload/adspic/2017-09/59cf0df6d3d56.png differ diff --git a/upload/adspic/2017-09/59cf0e97b7fcc.png b/upload/adspic/2017-09/59cf0e97b7fcc.png new file mode 100755 index 0000000..02e4049 Binary files /dev/null and b/upload/adspic/2017-09/59cf0e97b7fcc.png differ diff --git a/upload/adspic/2017-09/59cf0ea07d928.png b/upload/adspic/2017-09/59cf0ea07d928.png new file mode 100755 index 0000000..e1a10a8 Binary files /dev/null and b/upload/adspic/2017-09/59cf0ea07d928.png differ diff --git a/upload/adspic/2017-09/59cf0f42927e6.png b/upload/adspic/2017-09/59cf0f42927e6.png new file mode 100755 index 0000000..a847a48 Binary files /dev/null and b/upload/adspic/2017-09/59cf0f42927e6.png differ diff --git a/upload/adspic/2017-09/59cf0f4eaf6ad.png b/upload/adspic/2017-09/59cf0f4eaf6ad.png new file mode 100755 index 0000000..0ed6bb2 Binary files /dev/null and b/upload/adspic/2017-09/59cf0f4eaf6ad.png differ diff --git a/upload/adspic/2017-09/59cf302e8e0c1.png b/upload/adspic/2017-09/59cf302e8e0c1.png new file mode 100755 index 0000000..6f12fa7 Binary files /dev/null and b/upload/adspic/2017-09/59cf302e8e0c1.png differ diff --git a/upload/adspic/2017-09/59cf30744be66.png b/upload/adspic/2017-09/59cf30744be66.png new file mode 100755 index 0000000..97c6bac Binary files /dev/null and b/upload/adspic/2017-09/59cf30744be66.png differ diff --git a/upload/adspic/2017-09/59cf31db073e3.png b/upload/adspic/2017-09/59cf31db073e3.png new file mode 100755 index 0000000..2d85369 Binary files /dev/null and b/upload/adspic/2017-09/59cf31db073e3.png differ diff --git a/upload/adspic/2017-09/59cf31e2a8d1d.png b/upload/adspic/2017-09/59cf31e2a8d1d.png new file mode 100755 index 0000000..eac9bdf Binary files /dev/null and b/upload/adspic/2017-09/59cf31e2a8d1d.png differ diff --git a/upload/adspic/2017-09/59cf33fcaa872.png b/upload/adspic/2017-09/59cf33fcaa872.png new file mode 100755 index 0000000..36066c0 Binary files /dev/null and b/upload/adspic/2017-09/59cf33fcaa872.png differ diff --git a/upload/adspic/2017-09/59cf340388d44.png b/upload/adspic/2017-09/59cf340388d44.png new file mode 100755 index 0000000..7877b04 Binary files /dev/null and b/upload/adspic/2017-09/59cf340388d44.png differ diff --git a/upload/adspic/2017-09/59cf34d647f04.png b/upload/adspic/2017-09/59cf34d647f04.png new file mode 100755 index 0000000..f154bd1 Binary files /dev/null and b/upload/adspic/2017-09/59cf34d647f04.png differ diff --git a/upload/adspic/2017-09/59cf401a43f3a.png b/upload/adspic/2017-09/59cf401a43f3a.png new file mode 100755 index 0000000..d614b87 Binary files /dev/null and b/upload/adspic/2017-09/59cf401a43f3a.png differ diff --git a/upload/adspic/2017-09/59cf61120dda0.png b/upload/adspic/2017-09/59cf61120dda0.png new file mode 100755 index 0000000..6f5ae3e Binary files /dev/null and b/upload/adspic/2017-09/59cf61120dda0.png differ diff --git a/upload/adspic/2017-09/59cf612532619.png b/upload/adspic/2017-09/59cf612532619.png new file mode 100755 index 0000000..5325025 Binary files /dev/null and b/upload/adspic/2017-09/59cf612532619.png differ diff --git a/upload/adspic/2017-09/59cf61ac98801.png b/upload/adspic/2017-09/59cf61ac98801.png new file mode 100755 index 0000000..b71b134 Binary files /dev/null and b/upload/adspic/2017-09/59cf61ac98801.png differ diff --git a/upload/adspic/2017-09/59cf61b2cd7eb.png b/upload/adspic/2017-09/59cf61b2cd7eb.png new file mode 100755 index 0000000..66f2ef4 Binary files /dev/null and b/upload/adspic/2017-09/59cf61b2cd7eb.png differ diff --git a/upload/adspic/2017-10/59df1151d4714.jpg b/upload/adspic/2017-10/59df1151d4714.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/upload/adspic/2017-10/59df1151d4714.jpg differ diff --git a/upload/adspic/2017-10/59df1dce8377b.jpg b/upload/adspic/2017-10/59df1dce8377b.jpg new file mode 100755 index 0000000..f97ba26 Binary files /dev/null and b/upload/adspic/2017-10/59df1dce8377b.jpg differ diff --git a/upload/adspic/2017-10/59df1e5640b8e.jpg b/upload/adspic/2017-10/59df1e5640b8e.jpg new file mode 100755 index 0000000..a8cf989 Binary files /dev/null and b/upload/adspic/2017-10/59df1e5640b8e.jpg differ diff --git a/upload/adspic/2017-10/59df1e6eeffec.jpg b/upload/adspic/2017-10/59df1e6eeffec.jpg new file mode 100755 index 0000000..8248768 Binary files /dev/null and b/upload/adspic/2017-10/59df1e6eeffec.jpg differ diff --git a/upload/adspic/2017-10/59ed8572a397f.png b/upload/adspic/2017-10/59ed8572a397f.png new file mode 100755 index 0000000..5ff44dd Binary files /dev/null and b/upload/adspic/2017-10/59ed8572a397f.png differ diff --git a/upload/adspic/2017-10/59ed859117472.png b/upload/adspic/2017-10/59ed859117472.png new file mode 100755 index 0000000..71404b1 Binary files /dev/null and b/upload/adspic/2017-10/59ed859117472.png differ diff --git a/upload/adspic/2017-10/59ed863b52da2.jpg b/upload/adspic/2017-10/59ed863b52da2.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/upload/adspic/2017-10/59ed863b52da2.jpg differ diff --git a/upload/adspic/2017-10/59ed8744c0b32.jpg b/upload/adspic/2017-10/59ed8744c0b32.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/upload/adspic/2017-10/59ed8744c0b32.jpg differ diff --git a/upload/adspic/2017-10/59eda15c669ba.png b/upload/adspic/2017-10/59eda15c669ba.png new file mode 100755 index 0000000..ba069ca Binary files /dev/null and b/upload/adspic/2017-10/59eda15c669ba.png differ diff --git a/upload/adspic/2017-10/59eea2e27e404.jpg b/upload/adspic/2017-10/59eea2e27e404.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-10/59eea2e27e404.jpg differ diff --git a/upload/adspic/2017-10/59eea342c9f71.jpg b/upload/adspic/2017-10/59eea342c9f71.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-10/59eea342c9f71.jpg differ diff --git a/upload/adspic/2017-10/59eea36e9cddd.jpg b/upload/adspic/2017-10/59eea36e9cddd.jpg new file mode 100755 index 0000000..e2d1c29 Binary files /dev/null and b/upload/adspic/2017-10/59eea36e9cddd.jpg differ diff --git a/upload/adspic/2017-10/59eea37e2c730.jpg b/upload/adspic/2017-10/59eea37e2c730.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-10/59eea37e2c730.jpg differ diff --git a/upload/adspic/2017-10/59eea3d6a01c1.png b/upload/adspic/2017-10/59eea3d6a01c1.png new file mode 100755 index 0000000..77bbf58 Binary files /dev/null and b/upload/adspic/2017-10/59eea3d6a01c1.png differ diff --git a/upload/adspic/2017-10/59eea3df9bb96.jpg b/upload/adspic/2017-10/59eea3df9bb96.jpg new file mode 100755 index 0000000..a8cf989 Binary files /dev/null and b/upload/adspic/2017-10/59eea3df9bb96.jpg differ diff --git a/upload/adspic/2017-10/59eea3ed21a67.jpg b/upload/adspic/2017-10/59eea3ed21a67.jpg new file mode 100755 index 0000000..8248768 Binary files /dev/null and b/upload/adspic/2017-10/59eea3ed21a67.jpg differ diff --git a/upload/adspic/2017-10/59eea57b80ab9.png b/upload/adspic/2017-10/59eea57b80ab9.png new file mode 100755 index 0000000..71404b1 Binary files /dev/null and b/upload/adspic/2017-10/59eea57b80ab9.png differ diff --git a/upload/adspic/2017-10/59eed968954f6.png b/upload/adspic/2017-10/59eed968954f6.png new file mode 100755 index 0000000..5f25636 Binary files /dev/null and b/upload/adspic/2017-10/59eed968954f6.png differ diff --git a/upload/adspic/2017-10/59eed981bc2da.jpg b/upload/adspic/2017-10/59eed981bc2da.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-10/59eed981bc2da.jpg differ diff --git a/upload/adspic/2017-10/59eeda223b147.jpg b/upload/adspic/2017-10/59eeda223b147.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-10/59eeda223b147.jpg differ diff --git a/upload/adspic/2017-10/59eeda328b5ea.jpg b/upload/adspic/2017-10/59eeda328b5ea.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-10/59eeda328b5ea.jpg differ diff --git a/upload/adspic/2017-10/59eedafa88c87.png b/upload/adspic/2017-10/59eedafa88c87.png new file mode 100755 index 0000000..7b92f60 Binary files /dev/null and b/upload/adspic/2017-10/59eedafa88c87.png differ diff --git a/upload/adspic/2017-10/59eedb17dfbb9.png b/upload/adspic/2017-10/59eedb17dfbb9.png new file mode 100755 index 0000000..a54828e Binary files /dev/null and b/upload/adspic/2017-10/59eedb17dfbb9.png differ diff --git a/upload/adspic/2017-10/59eee1abb679e.png b/upload/adspic/2017-10/59eee1abb679e.png new file mode 100755 index 0000000..6e2308b Binary files /dev/null and b/upload/adspic/2017-10/59eee1abb679e.png differ diff --git a/upload/adspic/2017-10/59eee22f77df5.jpg b/upload/adspic/2017-10/59eee22f77df5.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/upload/adspic/2017-10/59eee22f77df5.jpg differ diff --git a/upload/adspic/2017-10/59eee252847b3.png b/upload/adspic/2017-10/59eee252847b3.png new file mode 100755 index 0000000..5b555c5 Binary files /dev/null and b/upload/adspic/2017-10/59eee252847b3.png differ diff --git a/upload/adspic/2017-10/59f678cd15407.jpg b/upload/adspic/2017-10/59f678cd15407.jpg new file mode 100755 index 0000000..a47323e Binary files /dev/null and b/upload/adspic/2017-10/59f678cd15407.jpg differ diff --git a/upload/adspic/2017-10/59f6790ebe322.jpg b/upload/adspic/2017-10/59f6790ebe322.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-10/59f6790ebe322.jpg differ diff --git a/upload/adspic/2017-10/59f679f44c607.jpg b/upload/adspic/2017-10/59f679f44c607.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-10/59f679f44c607.jpg differ diff --git a/upload/adspic/2017-10/59f67a09a8357.jpg b/upload/adspic/2017-10/59f67a09a8357.jpg new file mode 100755 index 0000000..8248768 Binary files /dev/null and b/upload/adspic/2017-10/59f67a09a8357.jpg differ diff --git a/upload/adspic/2017-10/59f67ad6bda57.jpg b/upload/adspic/2017-10/59f67ad6bda57.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-10/59f67ad6bda57.jpg differ diff --git a/upload/adspic/2017-10/59f67b93688e1.png b/upload/adspic/2017-10/59f67b93688e1.png new file mode 100755 index 0000000..71404b1 Binary files /dev/null and b/upload/adspic/2017-10/59f67b93688e1.png differ diff --git a/upload/adspic/2017-10/59f67c3f27630.jpg b/upload/adspic/2017-10/59f67c3f27630.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-10/59f67c3f27630.jpg differ diff --git a/upload/adspic/2017-11/59f92fb1aab3d.jpg b/upload/adspic/2017-11/59f92fb1aab3d.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59f92fb1aab3d.jpg differ diff --git a/upload/adspic/2017-11/59f93010e66a6.jpg b/upload/adspic/2017-11/59f93010e66a6.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-11/59f93010e66a6.jpg differ diff --git a/upload/adspic/2017-11/59f932d8ecf5f.jpg b/upload/adspic/2017-11/59f932d8ecf5f.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-11/59f932d8ecf5f.jpg differ diff --git a/upload/adspic/2017-11/59f934d848c61.jpg b/upload/adspic/2017-11/59f934d848c61.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-11/59f934d848c61.jpg differ diff --git a/upload/adspic/2017-11/59f93561da81c.png b/upload/adspic/2017-11/59f93561da81c.png new file mode 100755 index 0000000..5f25636 Binary files /dev/null and b/upload/adspic/2017-11/59f93561da81c.png differ diff --git a/upload/adspic/2017-11/59f935e34c178.jpg b/upload/adspic/2017-11/59f935e34c178.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59f935e34c178.jpg differ diff --git a/upload/adspic/2017-11/59fbb799cb27e.png b/upload/adspic/2017-11/59fbb799cb27e.png new file mode 100755 index 0000000..5b555c5 Binary files /dev/null and b/upload/adspic/2017-11/59fbb799cb27e.png differ diff --git a/upload/adspic/2017-11/59fbb7ba8bd62.png b/upload/adspic/2017-11/59fbb7ba8bd62.png new file mode 100755 index 0000000..5b555c5 Binary files /dev/null and b/upload/adspic/2017-11/59fbb7ba8bd62.png differ diff --git a/upload/adspic/2017-11/59fbb9b620409.png b/upload/adspic/2017-11/59fbb9b620409.png new file mode 100755 index 0000000..5b555c5 Binary files /dev/null and b/upload/adspic/2017-11/59fbb9b620409.png differ diff --git a/upload/adspic/2017-11/59fbb9d8563b0.png b/upload/adspic/2017-11/59fbb9d8563b0.png new file mode 100755 index 0000000..741b4f6 Binary files /dev/null and b/upload/adspic/2017-11/59fbb9d8563b0.png differ diff --git a/upload/adspic/2017-11/59fbbac9d9444.jpg b/upload/adspic/2017-11/59fbbac9d9444.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-11/59fbbac9d9444.jpg differ diff --git a/upload/adspic/2017-11/59fbbd9108d6c.jpg b/upload/adspic/2017-11/59fbbd9108d6c.jpg new file mode 100755 index 0000000..e2d1c29 Binary files /dev/null and b/upload/adspic/2017-11/59fbbd9108d6c.jpg differ diff --git a/upload/adspic/2017-11/59fbbdd297d9b.jpg b/upload/adspic/2017-11/59fbbdd297d9b.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-11/59fbbdd297d9b.jpg differ diff --git a/upload/adspic/2017-11/59fbbe63c513c.jpg b/upload/adspic/2017-11/59fbbe63c513c.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59fbbe63c513c.jpg differ diff --git a/upload/adspic/2017-11/59fbbfebd9c75.jpg b/upload/adspic/2017-11/59fbbfebd9c75.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59fbbfebd9c75.jpg differ diff --git a/upload/adspic/2017-11/59fbc19a617b8.jpg b/upload/adspic/2017-11/59fbc19a617b8.jpg new file mode 100755 index 0000000..e2d1c29 Binary files /dev/null and b/upload/adspic/2017-11/59fbc19a617b8.jpg differ diff --git a/upload/adspic/2017-11/59fbc2174f0c5.jpg b/upload/adspic/2017-11/59fbc2174f0c5.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-11/59fbc2174f0c5.jpg differ diff --git a/upload/adspic/2017-11/59fbc2931a8a2.jpg b/upload/adspic/2017-11/59fbc2931a8a2.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59fbc2931a8a2.jpg differ diff --git a/upload/adspic/2017-11/59fbc32b29eb0.jpg b/upload/adspic/2017-11/59fbc32b29eb0.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59fbc32b29eb0.jpg differ diff --git a/upload/adspic/2017-11/59fbc38414eff.jpg b/upload/adspic/2017-11/59fbc38414eff.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-11/59fbc38414eff.jpg differ diff --git a/upload/adspic/2017-11/59fbd1c91a9ad.jpg b/upload/adspic/2017-11/59fbd1c91a9ad.jpg new file mode 100755 index 0000000..467d8f9 Binary files /dev/null and b/upload/adspic/2017-11/59fbd1c91a9ad.jpg differ diff --git a/upload/adspic/2017-11/59fbd6bfcc27e.jpg b/upload/adspic/2017-11/59fbd6bfcc27e.jpg new file mode 100755 index 0000000..a8cf989 Binary files /dev/null and b/upload/adspic/2017-11/59fbd6bfcc27e.jpg differ diff --git a/upload/adspic/2017-11/59fbd6feba986.jpg b/upload/adspic/2017-11/59fbd6feba986.jpg new file mode 100755 index 0000000..e2d1c29 Binary files /dev/null and b/upload/adspic/2017-11/59fbd6feba986.jpg differ diff --git a/upload/adspic/2017-11/59fc23c53191d.jpg b/upload/adspic/2017-11/59fc23c53191d.jpg new file mode 100755 index 0000000..b578b7d Binary files /dev/null and b/upload/adspic/2017-11/59fc23c53191d.jpg differ diff --git a/upload/adspic/2017-11/59fc24049fbce.jpg b/upload/adspic/2017-11/59fc24049fbce.jpg new file mode 100755 index 0000000..8518385 Binary files /dev/null and b/upload/adspic/2017-11/59fc24049fbce.jpg differ diff --git a/upload/adspic/2017-11/59fc24d99dc65.jpg b/upload/adspic/2017-11/59fc24d99dc65.jpg new file mode 100755 index 0000000..6046794 Binary files /dev/null and b/upload/adspic/2017-11/59fc24d99dc65.jpg differ diff --git a/upload/adspic/2017-12/5a34b63633601.png b/upload/adspic/2017-12/5a34b63633601.png new file mode 100755 index 0000000..bad8969 Binary files /dev/null and b/upload/adspic/2017-12/5a34b63633601.png differ diff --git a/upload/adspic/2017-12/5a34b64d4e370.png b/upload/adspic/2017-12/5a34b64d4e370.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/adspic/2017-12/5a34b64d4e370.png differ diff --git a/upload/adspic/2017-12/5a4074b85647b.png b/upload/adspic/2017-12/5a4074b85647b.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/adspic/2017-12/5a4074b85647b.png differ diff --git a/upload/adspic/2017-12/5a4074cff110c.png b/upload/adspic/2017-12/5a4074cff110c.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/adspic/2017-12/5a4074cff110c.png differ diff --git a/upload/adspic/2017-12/5a40776fd33c6.jpg b/upload/adspic/2017-12/5a40776fd33c6.jpg new file mode 100755 index 0000000..94c3a6d Binary files /dev/null and b/upload/adspic/2017-12/5a40776fd33c6.jpg differ diff --git a/upload/adspic/2018-01/5a59868c50310.png b/upload/adspic/2018-01/5a59868c50310.png new file mode 100755 index 0000000..0265b52 Binary files /dev/null and b/upload/adspic/2018-01/5a59868c50310.png differ diff --git a/upload/adspic/2018-01/5a5986d010b1a.png b/upload/adspic/2018-01/5a5986d010b1a.png new file mode 100755 index 0000000..db95846 Binary files /dev/null and b/upload/adspic/2018-01/5a5986d010b1a.png differ diff --git a/upload/adspic/2018-01/5a5986e7be5dc.png b/upload/adspic/2018-01/5a5986e7be5dc.png new file mode 100755 index 0000000..ae5ace8 Binary files /dev/null and b/upload/adspic/2018-01/5a5986e7be5dc.png differ diff --git a/upload/adspic/2018-01/5a5986fedcf78.png b/upload/adspic/2018-01/5a5986fedcf78.png new file mode 100755 index 0000000..4b6694c Binary files /dev/null and b/upload/adspic/2018-01/5a5986fedcf78.png differ diff --git a/upload/adspic/2018-01/5a59871203386.png b/upload/adspic/2018-01/5a59871203386.png new file mode 100755 index 0000000..e7724cf Binary files /dev/null and b/upload/adspic/2018-01/5a59871203386.png differ diff --git a/upload/adspic/2018-02/5a7a6feb25e6a.jpg b/upload/adspic/2018-02/5a7a6feb25e6a.jpg new file mode 100755 index 0000000..e8704df Binary files /dev/null and b/upload/adspic/2018-02/5a7a6feb25e6a.jpg differ diff --git a/upload/adspic/2018-02/5a7a9d8f7fed4.jpg b/upload/adspic/2018-02/5a7a9d8f7fed4.jpg new file mode 100755 index 0000000..88fc2e0 Binary files /dev/null and b/upload/adspic/2018-02/5a7a9d8f7fed4.jpg differ diff --git a/upload/adspic/2018-02/5a8f78fd2f257.jpg b/upload/adspic/2018-02/5a8f78fd2f257.jpg new file mode 100755 index 0000000..e5b208c Binary files /dev/null and b/upload/adspic/2018-02/5a8f78fd2f257.jpg differ diff --git a/upload/adspic/2018-02/5a8f7d3daa032.jpg b/upload/adspic/2018-02/5a8f7d3daa032.jpg new file mode 100755 index 0000000..99af4ec Binary files /dev/null and b/upload/adspic/2018-02/5a8f7d3daa032.jpg differ diff --git a/upload/adspic/2018-02/5a8f840d207e1.jpg b/upload/adspic/2018-02/5a8f840d207e1.jpg new file mode 100755 index 0000000..d0d616f Binary files /dev/null and b/upload/adspic/2018-02/5a8f840d207e1.jpg differ diff --git a/upload/adspic/2018-02/5a8f85f361e06.jpg b/upload/adspic/2018-02/5a8f85f361e06.jpg new file mode 100755 index 0000000..d4ed2d4 Binary files /dev/null and b/upload/adspic/2018-02/5a8f85f361e06.jpg differ diff --git a/upload/adspic/2018-02/5a8f86e381cb4.jpg b/upload/adspic/2018-02/5a8f86e381cb4.jpg new file mode 100755 index 0000000..8ec9df3 Binary files /dev/null and b/upload/adspic/2018-02/5a8f86e381cb4.jpg differ diff --git a/upload/adspic/2018-02/5a8f8746bff89.jpg b/upload/adspic/2018-02/5a8f8746bff89.jpg new file mode 100755 index 0000000..c438bff Binary files /dev/null and b/upload/adspic/2018-02/5a8f8746bff89.jpg differ diff --git a/upload/adspic/2018-02/5a8f877b59ad9.jpg b/upload/adspic/2018-02/5a8f877b59ad9.jpg new file mode 100755 index 0000000..7b96024 Binary files /dev/null and b/upload/adspic/2018-02/5a8f877b59ad9.jpg differ diff --git a/upload/adspic/2018-02/5a8fb466d4a8f.jpg b/upload/adspic/2018-02/5a8fb466d4a8f.jpg new file mode 100755 index 0000000..98d3f06 Binary files /dev/null and b/upload/adspic/2018-02/5a8fb466d4a8f.jpg differ diff --git a/upload/adspic/2018-02/5a8fbeaae45cb.jpg b/upload/adspic/2018-02/5a8fbeaae45cb.jpg new file mode 100755 index 0000000..fc9fc4a Binary files /dev/null and b/upload/adspic/2018-02/5a8fbeaae45cb.jpg differ diff --git a/upload/adspic/2018-02/5a8fc641218f3.jpg b/upload/adspic/2018-02/5a8fc641218f3.jpg new file mode 100755 index 0000000..9d0e012 Binary files /dev/null and b/upload/adspic/2018-02/5a8fc641218f3.jpg differ diff --git a/upload/adspic/2018-02/5a8fc72d8fcb7.jpg b/upload/adspic/2018-02/5a8fc72d8fcb7.jpg new file mode 100755 index 0000000..9d0e012 Binary files /dev/null and b/upload/adspic/2018-02/5a8fc72d8fcb7.jpg differ diff --git a/upload/adspic/2018-02/5a8fc7cdc7fcc.jpg b/upload/adspic/2018-02/5a8fc7cdc7fcc.jpg new file mode 100755 index 0000000..9d0e012 Binary files /dev/null and b/upload/adspic/2018-02/5a8fc7cdc7fcc.jpg differ diff --git a/upload/adspic/2018-02/5a8fc95fa0ad4.jpg b/upload/adspic/2018-02/5a8fc95fa0ad4.jpg new file mode 100755 index 0000000..9d0e012 Binary files /dev/null and b/upload/adspic/2018-02/5a8fc95fa0ad4.jpg differ diff --git a/upload/adspic/2018-02/5a8fd02d7abe8.jpg b/upload/adspic/2018-02/5a8fd02d7abe8.jpg new file mode 100755 index 0000000..1390d04 Binary files /dev/null and b/upload/adspic/2018-02/5a8fd02d7abe8.jpg differ diff --git a/upload/adspic/2018-02/5a8fd09d9a185.jpg b/upload/adspic/2018-02/5a8fd09d9a185.jpg new file mode 100755 index 0000000..69a6162 Binary files /dev/null and b/upload/adspic/2018-02/5a8fd09d9a185.jpg differ diff --git a/upload/adspic/2018-02/5a90c4873af08.jpg b/upload/adspic/2018-02/5a90c4873af08.jpg new file mode 100755 index 0000000..1390d04 Binary files /dev/null and b/upload/adspic/2018-02/5a90c4873af08.jpg differ diff --git a/upload/adspic/2018-02/5a90d7a0f0035.jpg b/upload/adspic/2018-02/5a90d7a0f0035.jpg new file mode 100755 index 0000000..69a6162 Binary files /dev/null and b/upload/adspic/2018-02/5a90d7a0f0035.jpg differ diff --git a/upload/adspic/2018-02/5a90d7d302acb.jpg b/upload/adspic/2018-02/5a90d7d302acb.jpg new file mode 100755 index 0000000..69a6162 Binary files /dev/null and b/upload/adspic/2018-02/5a90d7d302acb.jpg differ diff --git a/upload/adspic/2018-02/5a90d8411cdec.jpg b/upload/adspic/2018-02/5a90d8411cdec.jpg new file mode 100755 index 0000000..6b4f61e Binary files /dev/null and b/upload/adspic/2018-02/5a90d8411cdec.jpg differ diff --git a/upload/adspic/2018-02/5a90fdc0c325b.jpg b/upload/adspic/2018-02/5a90fdc0c325b.jpg new file mode 100755 index 0000000..9b49b83 Binary files /dev/null and b/upload/adspic/2018-02/5a90fdc0c325b.jpg differ diff --git a/upload/adspic/2018-02/5a90ffc8bc3f7.jpg b/upload/adspic/2018-02/5a90ffc8bc3f7.jpg new file mode 100755 index 0000000..e787ac6 Binary files /dev/null and b/upload/adspic/2018-02/5a90ffc8bc3f7.jpg differ diff --git a/upload/adspic/2018-03/5a976eb21db5b.jpg b/upload/adspic/2018-03/5a976eb21db5b.jpg new file mode 100755 index 0000000..9d0e012 Binary files /dev/null and b/upload/adspic/2018-03/5a976eb21db5b.jpg differ diff --git a/upload/adspic/2018-03/5a98e073ce77a.jpg b/upload/adspic/2018-03/5a98e073ce77a.jpg new file mode 100755 index 0000000..e15dfa5 Binary files /dev/null and b/upload/adspic/2018-03/5a98e073ce77a.jpg differ diff --git a/upload/adspic/2018-03/5a98fd7bc0925.jpg b/upload/adspic/2018-03/5a98fd7bc0925.jpg new file mode 100755 index 0000000..e15dfa5 Binary files /dev/null and b/upload/adspic/2018-03/5a98fd7bc0925.jpg differ diff --git a/upload/adspic/txt.txt b/upload/adspic/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/adspic/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/appraises/2017-12/5a2797c34c416.png b/upload/appraises/2017-12/5a2797c34c416.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/appraises/2017-12/5a2797c34c416.png differ diff --git a/upload/appraises/2017-12/5a2797c34c416_m.png b/upload/appraises/2017-12/5a2797c34c416_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/appraises/2017-12/5a2797c34c416_m.png differ diff --git a/upload/appraises/2017-12/5a2797c34c416_m_thumb.png b/upload/appraises/2017-12/5a2797c34c416_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/appraises/2017-12/5a2797c34c416_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a2797c34c416_thumb.png b/upload/appraises/2017-12/5a2797c34c416_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/appraises/2017-12/5a2797c34c416_thumb.png differ diff --git a/upload/appraises/2017-12/5a2798e45720a.jpg b/upload/appraises/2017-12/5a2798e45720a.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e45720a.jpg differ diff --git a/upload/appraises/2017-12/5a2798e45720a_m.jpg b/upload/appraises/2017-12/5a2798e45720a_m.jpg new file mode 100755 index 0000000..95fb262 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e45720a_m.jpg differ diff --git a/upload/appraises/2017-12/5a2798e45720a_m_thumb.jpg b/upload/appraises/2017-12/5a2798e45720a_m_thumb.jpg new file mode 100755 index 0000000..60dbda7 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e45720a_m_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a2798e45720a_thumb.jpg b/upload/appraises/2017-12/5a2798e45720a_thumb.jpg new file mode 100755 index 0000000..6f43ef5 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e45720a_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a2798e92cb6e.jpg b/upload/appraises/2017-12/5a2798e92cb6e.jpg new file mode 100755 index 0000000..bf0fc3b Binary files /dev/null and b/upload/appraises/2017-12/5a2798e92cb6e.jpg differ diff --git a/upload/appraises/2017-12/5a2798e92cb6e_m.jpg b/upload/appraises/2017-12/5a2798e92cb6e_m.jpg new file mode 100755 index 0000000..71f78fa Binary files /dev/null and b/upload/appraises/2017-12/5a2798e92cb6e_m.jpg differ diff --git a/upload/appraises/2017-12/5a2798e92cb6e_m_thumb.jpg b/upload/appraises/2017-12/5a2798e92cb6e_m_thumb.jpg new file mode 100755 index 0000000..b1924a8 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e92cb6e_m_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a2798e92cb6e_thumb.jpg b/upload/appraises/2017-12/5a2798e92cb6e_thumb.jpg new file mode 100755 index 0000000..95f0745 Binary files /dev/null and b/upload/appraises/2017-12/5a2798e92cb6e_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a27a5c56dbb1.png b/upload/appraises/2017-12/5a27a5c56dbb1.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/appraises/2017-12/5a27a5c56dbb1.png differ diff --git a/upload/appraises/2017-12/5a27a5c56dbb1_m.png b/upload/appraises/2017-12/5a27a5c56dbb1_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/appraises/2017-12/5a27a5c56dbb1_m.png differ diff --git a/upload/appraises/2017-12/5a27a5c56dbb1_m_thumb.png b/upload/appraises/2017-12/5a27a5c56dbb1_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/appraises/2017-12/5a27a5c56dbb1_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a27a5c56dbb1_thumb.png b/upload/appraises/2017-12/5a27a5c56dbb1_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/appraises/2017-12/5a27a5c56dbb1_thumb.png differ diff --git a/upload/appraises/2017-12/5a2f8448e16cc.png b/upload/appraises/2017-12/5a2f8448e16cc.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/appraises/2017-12/5a2f8448e16cc.png differ diff --git a/upload/appraises/2017-12/5a2f8448e16cc_m.png b/upload/appraises/2017-12/5a2f8448e16cc_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/appraises/2017-12/5a2f8448e16cc_m.png differ diff --git a/upload/appraises/2017-12/5a2f8448e16cc_m_thumb.png b/upload/appraises/2017-12/5a2f8448e16cc_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/appraises/2017-12/5a2f8448e16cc_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a2f8448e16cc_thumb.png b/upload/appraises/2017-12/5a2f8448e16cc_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/appraises/2017-12/5a2f8448e16cc_thumb.png differ diff --git a/upload/appraises/2017-12/5a2f844ddf812.png b/upload/appraises/2017-12/5a2f844ddf812.png new file mode 100755 index 0000000..ba8dd63 Binary files /dev/null and b/upload/appraises/2017-12/5a2f844ddf812.png differ diff --git a/upload/appraises/2017-12/5a2f844ddf812_m.png b/upload/appraises/2017-12/5a2f844ddf812_m.png new file mode 100755 index 0000000..9de3fd7 Binary files /dev/null and b/upload/appraises/2017-12/5a2f844ddf812_m.png differ diff --git a/upload/appraises/2017-12/5a2f844ddf812_m_thumb.png b/upload/appraises/2017-12/5a2f844ddf812_m_thumb.png new file mode 100755 index 0000000..9584f22 Binary files /dev/null and b/upload/appraises/2017-12/5a2f844ddf812_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a2f844ddf812_thumb.png b/upload/appraises/2017-12/5a2f844ddf812_thumb.png new file mode 100755 index 0000000..b8885e8 Binary files /dev/null and b/upload/appraises/2017-12/5a2f844ddf812_thumb.png differ diff --git a/upload/appraises/2017-12/5a307ea15b6fb.jpg b/upload/appraises/2017-12/5a307ea15b6fb.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea15b6fb.jpg differ diff --git a/upload/appraises/2017-12/5a307ea15b6fb_m.jpg b/upload/appraises/2017-12/5a307ea15b6fb_m.jpg new file mode 100755 index 0000000..95fb262 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea15b6fb_m.jpg differ diff --git a/upload/appraises/2017-12/5a307ea15b6fb_m_thumb.jpg b/upload/appraises/2017-12/5a307ea15b6fb_m_thumb.jpg new file mode 100755 index 0000000..60dbda7 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea15b6fb_m_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a307ea15b6fb_thumb.jpg b/upload/appraises/2017-12/5a307ea15b6fb_thumb.jpg new file mode 100755 index 0000000..6f43ef5 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea15b6fb_thumb.jpg differ diff --git a/upload/appraises/2017-12/5a307ea9dd31b.png b/upload/appraises/2017-12/5a307ea9dd31b.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/appraises/2017-12/5a307ea9dd31b.png differ diff --git a/upload/appraises/2017-12/5a307ea9dd31b_m.png b/upload/appraises/2017-12/5a307ea9dd31b_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea9dd31b_m.png differ diff --git a/upload/appraises/2017-12/5a307ea9dd31b_m_thumb.png b/upload/appraises/2017-12/5a307ea9dd31b_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea9dd31b_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a307ea9dd31b_thumb.png b/upload/appraises/2017-12/5a307ea9dd31b_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/appraises/2017-12/5a307ea9dd31b_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a62142b3.png b/upload/appraises/2017-12/5a308a62142b3.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/appraises/2017-12/5a308a62142b3.png differ diff --git a/upload/appraises/2017-12/5a308a62142b3_m.png b/upload/appraises/2017-12/5a308a62142b3_m.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/appraises/2017-12/5a308a62142b3_m.png differ diff --git a/upload/appraises/2017-12/5a308a62142b3_m_thumb.png b/upload/appraises/2017-12/5a308a62142b3_m_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/appraises/2017-12/5a308a62142b3_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a62142b3_thumb.png b/upload/appraises/2017-12/5a308a62142b3_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/appraises/2017-12/5a308a62142b3_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a623ea6d.png b/upload/appraises/2017-12/5a308a623ea6d.png new file mode 100755 index 0000000..3d8a714 Binary files /dev/null and b/upload/appraises/2017-12/5a308a623ea6d.png differ diff --git a/upload/appraises/2017-12/5a308a623ea6d_m.png b/upload/appraises/2017-12/5a308a623ea6d_m.png new file mode 100755 index 0000000..5ba0602 Binary files /dev/null and b/upload/appraises/2017-12/5a308a623ea6d_m.png differ diff --git a/upload/appraises/2017-12/5a308a623ea6d_m_thumb.png b/upload/appraises/2017-12/5a308a623ea6d_m_thumb.png new file mode 100755 index 0000000..3b996a5 Binary files /dev/null and b/upload/appraises/2017-12/5a308a623ea6d_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a623ea6d_thumb.png b/upload/appraises/2017-12/5a308a623ea6d_thumb.png new file mode 100755 index 0000000..751e847 Binary files /dev/null and b/upload/appraises/2017-12/5a308a623ea6d_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a63bca64.png b/upload/appraises/2017-12/5a308a63bca64.png new file mode 100755 index 0000000..ba8dd63 Binary files /dev/null and b/upload/appraises/2017-12/5a308a63bca64.png differ diff --git a/upload/appraises/2017-12/5a308a63bca64_m.png b/upload/appraises/2017-12/5a308a63bca64_m.png new file mode 100755 index 0000000..9de3fd7 Binary files /dev/null and b/upload/appraises/2017-12/5a308a63bca64_m.png differ diff --git a/upload/appraises/2017-12/5a308a63bca64_m_thumb.png b/upload/appraises/2017-12/5a308a63bca64_m_thumb.png new file mode 100755 index 0000000..9584f22 Binary files /dev/null and b/upload/appraises/2017-12/5a308a63bca64_m_thumb.png differ diff --git a/upload/appraises/2017-12/5a308a63bca64_thumb.png b/upload/appraises/2017-12/5a308a63bca64_thumb.png new file mode 100755 index 0000000..b8885e8 Binary files /dev/null and b/upload/appraises/2017-12/5a308a63bca64_thumb.png differ diff --git a/upload/appraises/txt.txt b/upload/appraises/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/appraises/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/articles/2017-11/5a0aa7482b38f.jpg b/upload/articles/2017-11/5a0aa7482b38f.jpg new file mode 100755 index 0000000..35e263f Binary files /dev/null and b/upload/articles/2017-11/5a0aa7482b38f.jpg differ diff --git a/upload/articles/2017-11/5a0aa748732ba.jpg b/upload/articles/2017-11/5a0aa748732ba.jpg new file mode 100755 index 0000000..ce2e7b1 Binary files /dev/null and b/upload/articles/2017-11/5a0aa748732ba.jpg differ diff --git a/upload/articles/2017-11/5a0aa748a04ba.jpg b/upload/articles/2017-11/5a0aa748a04ba.jpg new file mode 100755 index 0000000..d0b3845 Binary files /dev/null and b/upload/articles/2017-11/5a0aa748a04ba.jpg differ diff --git a/upload/articles/2017-11/5a0aa748aabe3.jpg b/upload/articles/2017-11/5a0aa748aabe3.jpg new file mode 100755 index 0000000..841c7e3 Binary files /dev/null and b/upload/articles/2017-11/5a0aa748aabe3.jpg differ diff --git a/upload/articles/2017-11/5a0aa748c5530.jpg b/upload/articles/2017-11/5a0aa748c5530.jpg new file mode 100755 index 0000000..dab3b40 Binary files /dev/null and b/upload/articles/2017-11/5a0aa748c5530.jpg differ diff --git a/upload/articles/2017-11/5a0aa7490ced7.jpg b/upload/articles/2017-11/5a0aa7490ced7.jpg new file mode 100755 index 0000000..79b33e0 Binary files /dev/null and b/upload/articles/2017-11/5a0aa7490ced7.jpg differ diff --git a/upload/brands/2017-09/59cf3a9ad2613.png b/upload/brands/2017-09/59cf3a9ad2613.png new file mode 100755 index 0000000..eff5e7f Binary files /dev/null and b/upload/brands/2017-09/59cf3a9ad2613.png differ diff --git a/upload/brands/2017-09/59cf3aec48298.jpg b/upload/brands/2017-09/59cf3aec48298.jpg new file mode 100755 index 0000000..fb8bab0 Binary files /dev/null and b/upload/brands/2017-09/59cf3aec48298.jpg differ diff --git a/upload/brands/txt.txt b/upload/brands/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/brands/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/complains/2017-12/5a24cadf3864d.png b/upload/complains/2017-12/5a24cadf3864d.png new file mode 100755 index 0000000..c65537d Binary files /dev/null and b/upload/complains/2017-12/5a24cadf3864d.png differ diff --git a/upload/complains/2017-12/5a24cadf3864d_m.png b/upload/complains/2017-12/5a24cadf3864d_m.png new file mode 100755 index 0000000..46c144c Binary files /dev/null and b/upload/complains/2017-12/5a24cadf3864d_m.png differ diff --git a/upload/complains/2017-12/5a24cadf3864d_m_thumb.png b/upload/complains/2017-12/5a24cadf3864d_m_thumb.png new file mode 100755 index 0000000..c4509c5 Binary files /dev/null and b/upload/complains/2017-12/5a24cadf3864d_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24cadf3864d_thumb.png b/upload/complains/2017-12/5a24cadf3864d_thumb.png new file mode 100755 index 0000000..c96853f Binary files /dev/null and b/upload/complains/2017-12/5a24cadf3864d_thumb.png differ diff --git a/upload/complains/2017-12/5a24cae02ea44.png b/upload/complains/2017-12/5a24cae02ea44.png new file mode 100755 index 0000000..323d660 Binary files /dev/null and b/upload/complains/2017-12/5a24cae02ea44.png differ diff --git a/upload/complains/2017-12/5a24cae02ea44_m.png b/upload/complains/2017-12/5a24cae02ea44_m.png new file mode 100755 index 0000000..ee796af Binary files /dev/null and b/upload/complains/2017-12/5a24cae02ea44_m.png differ diff --git a/upload/complains/2017-12/5a24cae02ea44_m_thumb.png b/upload/complains/2017-12/5a24cae02ea44_m_thumb.png new file mode 100755 index 0000000..69e74e6 Binary files /dev/null and b/upload/complains/2017-12/5a24cae02ea44_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24cae02ea44_thumb.png b/upload/complains/2017-12/5a24cae02ea44_thumb.png new file mode 100755 index 0000000..2b525b9 Binary files /dev/null and b/upload/complains/2017-12/5a24cae02ea44_thumb.png differ diff --git a/upload/complains/2017-12/5a24cb57d903a.png b/upload/complains/2017-12/5a24cb57d903a.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a24cb57d903a.png differ diff --git a/upload/complains/2017-12/5a24cb57d903a_m.png b/upload/complains/2017-12/5a24cb57d903a_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a24cb57d903a_m.png differ diff --git a/upload/complains/2017-12/5a24cb57d903a_m_thumb.png b/upload/complains/2017-12/5a24cb57d903a_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a24cb57d903a_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24cb57d903a_thumb.png b/upload/complains/2017-12/5a24cb57d903a_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a24cb57d903a_thumb.png differ diff --git a/upload/complains/2017-12/5a24cb676d524.png b/upload/complains/2017-12/5a24cb676d524.png new file mode 100755 index 0000000..de3f494 Binary files /dev/null and b/upload/complains/2017-12/5a24cb676d524.png differ diff --git a/upload/complains/2017-12/5a24cb676d524_m.png b/upload/complains/2017-12/5a24cb676d524_m.png new file mode 100755 index 0000000..adb8c1f Binary files /dev/null and b/upload/complains/2017-12/5a24cb676d524_m.png differ diff --git a/upload/complains/2017-12/5a24cb676d524_m_thumb.png b/upload/complains/2017-12/5a24cb676d524_m_thumb.png new file mode 100755 index 0000000..2d72f77 Binary files /dev/null and b/upload/complains/2017-12/5a24cb676d524_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24cb676d524_thumb.png b/upload/complains/2017-12/5a24cb676d524_thumb.png new file mode 100755 index 0000000..16a93df Binary files /dev/null and b/upload/complains/2017-12/5a24cb676d524_thumb.png differ diff --git a/upload/complains/2017-12/5a24cba71a785.jpg b/upload/complains/2017-12/5a24cba71a785.jpg new file mode 100755 index 0000000..a335765 Binary files /dev/null and b/upload/complains/2017-12/5a24cba71a785.jpg differ diff --git a/upload/complains/2017-12/5a24cba71a785_m.jpg b/upload/complains/2017-12/5a24cba71a785_m.jpg new file mode 100755 index 0000000..d521dbc Binary files /dev/null and b/upload/complains/2017-12/5a24cba71a785_m.jpg differ diff --git a/upload/complains/2017-12/5a24cba71a785_m_thumb.jpg b/upload/complains/2017-12/5a24cba71a785_m_thumb.jpg new file mode 100755 index 0000000..5651ba3 Binary files /dev/null and b/upload/complains/2017-12/5a24cba71a785_m_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24cba71a785_thumb.jpg b/upload/complains/2017-12/5a24cba71a785_thumb.jpg new file mode 100755 index 0000000..d7c3530 Binary files /dev/null and b/upload/complains/2017-12/5a24cba71a785_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24cbbb3fdc6.jpg b/upload/complains/2017-12/5a24cbbb3fdc6.jpg new file mode 100755 index 0000000..a8c1d49 Binary files /dev/null and b/upload/complains/2017-12/5a24cbbb3fdc6.jpg differ diff --git a/upload/complains/2017-12/5a24cbbb3fdc6_m.jpg b/upload/complains/2017-12/5a24cbbb3fdc6_m.jpg new file mode 100755 index 0000000..3612363 Binary files /dev/null and b/upload/complains/2017-12/5a24cbbb3fdc6_m.jpg differ diff --git a/upload/complains/2017-12/5a24cbbb3fdc6_m_thumb.jpg b/upload/complains/2017-12/5a24cbbb3fdc6_m_thumb.jpg new file mode 100755 index 0000000..d1192d2 Binary files /dev/null and b/upload/complains/2017-12/5a24cbbb3fdc6_m_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24cbbb3fdc6_thumb.jpg b/upload/complains/2017-12/5a24cbbb3fdc6_thumb.jpg new file mode 100755 index 0000000..5abd344 Binary files /dev/null and b/upload/complains/2017-12/5a24cbbb3fdc6_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24ef4a8ea3e.png b/upload/complains/2017-12/5a24ef4a8ea3e.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a24ef4a8ea3e.png differ diff --git a/upload/complains/2017-12/5a24ef4a8ea3e_m.png b/upload/complains/2017-12/5a24ef4a8ea3e_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a24ef4a8ea3e_m.png differ diff --git a/upload/complains/2017-12/5a24ef4a8ea3e_m_thumb.png b/upload/complains/2017-12/5a24ef4a8ea3e_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a24ef4a8ea3e_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24ef4a8ea3e_thumb.png b/upload/complains/2017-12/5a24ef4a8ea3e_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a24ef4a8ea3e_thumb.png differ diff --git a/upload/complains/2017-12/5a24ef6dcf18f.jpg b/upload/complains/2017-12/5a24ef6dcf18f.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/complains/2017-12/5a24ef6dcf18f.jpg differ diff --git a/upload/complains/2017-12/5a24ef6dcf18f_m.jpg b/upload/complains/2017-12/5a24ef6dcf18f_m.jpg new file mode 100755 index 0000000..95fb262 Binary files /dev/null and b/upload/complains/2017-12/5a24ef6dcf18f_m.jpg differ diff --git a/upload/complains/2017-12/5a24ef6dcf18f_m_thumb.jpg b/upload/complains/2017-12/5a24ef6dcf18f_m_thumb.jpg new file mode 100755 index 0000000..60dbda7 Binary files /dev/null and b/upload/complains/2017-12/5a24ef6dcf18f_m_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24ef6dcf18f_thumb.jpg b/upload/complains/2017-12/5a24ef6dcf18f_thumb.jpg new file mode 100755 index 0000000..6f43ef5 Binary files /dev/null and b/upload/complains/2017-12/5a24ef6dcf18f_thumb.jpg differ diff --git a/upload/complains/2017-12/5a24f0e0ebb7a.png b/upload/complains/2017-12/5a24f0e0ebb7a.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a24f0e0ebb7a.png differ diff --git a/upload/complains/2017-12/5a24f0e0ebb7a_m.png b/upload/complains/2017-12/5a24f0e0ebb7a_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a24f0e0ebb7a_m.png differ diff --git a/upload/complains/2017-12/5a24f0e0ebb7a_m_thumb.png b/upload/complains/2017-12/5a24f0e0ebb7a_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a24f0e0ebb7a_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24f0e0ebb7a_thumb.png b/upload/complains/2017-12/5a24f0e0ebb7a_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a24f0e0ebb7a_thumb.png differ diff --git a/upload/complains/2017-12/5a24f43fc6732.png b/upload/complains/2017-12/5a24f43fc6732.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a24f43fc6732.png differ diff --git a/upload/complains/2017-12/5a24f43fc6732_m.png b/upload/complains/2017-12/5a24f43fc6732_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24f43fc6732_m.png differ diff --git a/upload/complains/2017-12/5a24f43fc6732_m_thumb.png b/upload/complains/2017-12/5a24f43fc6732_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24f43fc6732_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24f43fc6732_thumb.png b/upload/complains/2017-12/5a24f43fc6732_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24f43fc6732_thumb.png differ diff --git a/upload/complains/2017-12/5a24fd9d9951d.png b/upload/complains/2017-12/5a24fd9d9951d.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a24fd9d9951d.png differ diff --git a/upload/complains/2017-12/5a24fd9d9951d_m.png b/upload/complains/2017-12/5a24fd9d9951d_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fd9d9951d_m.png differ diff --git a/upload/complains/2017-12/5a24fd9d9951d_m_thumb.png b/upload/complains/2017-12/5a24fd9d9951d_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fd9d9951d_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24fd9d9951d_thumb.png b/upload/complains/2017-12/5a24fd9d9951d_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fd9d9951d_thumb.png differ diff --git a/upload/complains/2017-12/5a24fdbb66b5d.png b/upload/complains/2017-12/5a24fdbb66b5d.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a24fdbb66b5d.png differ diff --git a/upload/complains/2017-12/5a24fdbb66b5d_m.png b/upload/complains/2017-12/5a24fdbb66b5d_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a24fdbb66b5d_m.png differ diff --git a/upload/complains/2017-12/5a24fdbb66b5d_m_thumb.png b/upload/complains/2017-12/5a24fdbb66b5d_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a24fdbb66b5d_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24fdbb66b5d_thumb.png b/upload/complains/2017-12/5a24fdbb66b5d_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a24fdbb66b5d_thumb.png differ diff --git a/upload/complains/2017-12/5a24fe608e9d4.png b/upload/complains/2017-12/5a24fe608e9d4.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a24fe608e9d4.png differ diff --git a/upload/complains/2017-12/5a24fe608e9d4_m.png b/upload/complains/2017-12/5a24fe608e9d4_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fe608e9d4_m.png differ diff --git a/upload/complains/2017-12/5a24fe608e9d4_m_thumb.png b/upload/complains/2017-12/5a24fe608e9d4_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fe608e9d4_m_thumb.png differ diff --git a/upload/complains/2017-12/5a24fe608e9d4_thumb.png b/upload/complains/2017-12/5a24fe608e9d4_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a24fe608e9d4_thumb.png differ diff --git a/upload/complains/2017-12/5a25028514375.png b/upload/complains/2017-12/5a25028514375.png new file mode 100755 index 0000000..323d660 Binary files /dev/null and b/upload/complains/2017-12/5a25028514375.png differ diff --git a/upload/complains/2017-12/5a25028514375_m.png b/upload/complains/2017-12/5a25028514375_m.png new file mode 100755 index 0000000..ee796af Binary files /dev/null and b/upload/complains/2017-12/5a25028514375_m.png differ diff --git a/upload/complains/2017-12/5a25028514375_m_thumb.png b/upload/complains/2017-12/5a25028514375_m_thumb.png new file mode 100755 index 0000000..69e74e6 Binary files /dev/null and b/upload/complains/2017-12/5a25028514375_m_thumb.png differ diff --git a/upload/complains/2017-12/5a25028514375_thumb.png b/upload/complains/2017-12/5a25028514375_thumb.png new file mode 100755 index 0000000..2b525b9 Binary files /dev/null and b/upload/complains/2017-12/5a25028514375_thumb.png differ diff --git a/upload/complains/2017-12/5a2502ffa8e6a.png b/upload/complains/2017-12/5a2502ffa8e6a.png new file mode 100755 index 0000000..d1d6a2c Binary files /dev/null and b/upload/complains/2017-12/5a2502ffa8e6a.png differ diff --git a/upload/complains/2017-12/5a2502ffa8e6a_m.png b/upload/complains/2017-12/5a2502ffa8e6a_m.png new file mode 100755 index 0000000..c4ddb69 Binary files /dev/null and b/upload/complains/2017-12/5a2502ffa8e6a_m.png differ diff --git a/upload/complains/2017-12/5a2502ffa8e6a_m_thumb.png b/upload/complains/2017-12/5a2502ffa8e6a_m_thumb.png new file mode 100755 index 0000000..9801674 Binary files /dev/null and b/upload/complains/2017-12/5a2502ffa8e6a_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2502ffa8e6a_thumb.png b/upload/complains/2017-12/5a2502ffa8e6a_thumb.png new file mode 100755 index 0000000..128374d Binary files /dev/null and b/upload/complains/2017-12/5a2502ffa8e6a_thumb.png differ diff --git a/upload/complains/2017-12/5a250325da04b.png b/upload/complains/2017-12/5a250325da04b.png new file mode 100755 index 0000000..3d8a714 Binary files /dev/null and b/upload/complains/2017-12/5a250325da04b.png differ diff --git a/upload/complains/2017-12/5a250325da04b_m.png b/upload/complains/2017-12/5a250325da04b_m.png new file mode 100755 index 0000000..5ba0602 Binary files /dev/null and b/upload/complains/2017-12/5a250325da04b_m.png differ diff --git a/upload/complains/2017-12/5a250325da04b_m_thumb.png b/upload/complains/2017-12/5a250325da04b_m_thumb.png new file mode 100755 index 0000000..3b996a5 Binary files /dev/null and b/upload/complains/2017-12/5a250325da04b_m_thumb.png differ diff --git a/upload/complains/2017-12/5a250325da04b_thumb.png b/upload/complains/2017-12/5a250325da04b_thumb.png new file mode 100755 index 0000000..751e847 Binary files /dev/null and b/upload/complains/2017-12/5a250325da04b_thumb.png differ diff --git a/upload/complains/2017-12/5a2503338d0fa.png b/upload/complains/2017-12/5a2503338d0fa.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a2503338d0fa.png differ diff --git a/upload/complains/2017-12/5a2503338d0fa_m.png b/upload/complains/2017-12/5a2503338d0fa_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a2503338d0fa_m.png differ diff --git a/upload/complains/2017-12/5a2503338d0fa_m_thumb.png b/upload/complains/2017-12/5a2503338d0fa_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a2503338d0fa_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2503338d0fa_thumb.png b/upload/complains/2017-12/5a2503338d0fa_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a2503338d0fa_thumb.png differ diff --git a/upload/complains/2017-12/5a25033b4bfbc.jpg b/upload/complains/2017-12/5a25033b4bfbc.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/complains/2017-12/5a25033b4bfbc.jpg differ diff --git a/upload/complains/2017-12/5a25033b4bfbc_m.jpg b/upload/complains/2017-12/5a25033b4bfbc_m.jpg new file mode 100755 index 0000000..95fb262 Binary files /dev/null and b/upload/complains/2017-12/5a25033b4bfbc_m.jpg differ diff --git a/upload/complains/2017-12/5a25033b4bfbc_m_thumb.jpg b/upload/complains/2017-12/5a25033b4bfbc_m_thumb.jpg new file mode 100755 index 0000000..60dbda7 Binary files /dev/null and b/upload/complains/2017-12/5a25033b4bfbc_m_thumb.jpg differ diff --git a/upload/complains/2017-12/5a25033b4bfbc_thumb.jpg b/upload/complains/2017-12/5a25033b4bfbc_thumb.jpg new file mode 100755 index 0000000..6f43ef5 Binary files /dev/null and b/upload/complains/2017-12/5a25033b4bfbc_thumb.jpg differ diff --git a/upload/complains/2017-12/5a25039cb74d1.png b/upload/complains/2017-12/5a25039cb74d1.png new file mode 100755 index 0000000..3d8a714 Binary files /dev/null and b/upload/complains/2017-12/5a25039cb74d1.png differ diff --git a/upload/complains/2017-12/5a25039cb74d1_m.png b/upload/complains/2017-12/5a25039cb74d1_m.png new file mode 100755 index 0000000..5ba0602 Binary files /dev/null and b/upload/complains/2017-12/5a25039cb74d1_m.png differ diff --git a/upload/complains/2017-12/5a25039cb74d1_m_thumb.png b/upload/complains/2017-12/5a25039cb74d1_m_thumb.png new file mode 100755 index 0000000..3b996a5 Binary files /dev/null and b/upload/complains/2017-12/5a25039cb74d1_m_thumb.png differ diff --git a/upload/complains/2017-12/5a25039cb74d1_thumb.png b/upload/complains/2017-12/5a25039cb74d1_thumb.png new file mode 100755 index 0000000..751e847 Binary files /dev/null and b/upload/complains/2017-12/5a25039cb74d1_thumb.png differ diff --git a/upload/complains/2017-12/5a2503c279158.png b/upload/complains/2017-12/5a2503c279158.png new file mode 100755 index 0000000..323d660 Binary files /dev/null and b/upload/complains/2017-12/5a2503c279158.png differ diff --git a/upload/complains/2017-12/5a2503c279158_m.png b/upload/complains/2017-12/5a2503c279158_m.png new file mode 100755 index 0000000..ee796af Binary files /dev/null and b/upload/complains/2017-12/5a2503c279158_m.png differ diff --git a/upload/complains/2017-12/5a2503c279158_m_thumb.png b/upload/complains/2017-12/5a2503c279158_m_thumb.png new file mode 100755 index 0000000..69e74e6 Binary files /dev/null and b/upload/complains/2017-12/5a2503c279158_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2503c279158_thumb.png b/upload/complains/2017-12/5a2503c279158_thumb.png new file mode 100755 index 0000000..2b525b9 Binary files /dev/null and b/upload/complains/2017-12/5a2503c279158_thumb.png differ diff --git a/upload/complains/2017-12/5a2503e99a96f.png b/upload/complains/2017-12/5a2503e99a96f.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a2503e99a96f.png differ diff --git a/upload/complains/2017-12/5a2503e99a96f_m.png b/upload/complains/2017-12/5a2503e99a96f_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a2503e99a96f_m.png differ diff --git a/upload/complains/2017-12/5a2503e99a96f_m_thumb.png b/upload/complains/2017-12/5a2503e99a96f_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a2503e99a96f_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2503e99a96f_thumb.png b/upload/complains/2017-12/5a2503e99a96f_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a2503e99a96f_thumb.png differ diff --git a/upload/complains/2017-12/5a25045f80676.png b/upload/complains/2017-12/5a25045f80676.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a25045f80676.png differ diff --git a/upload/complains/2017-12/5a25045f80676_m.png b/upload/complains/2017-12/5a25045f80676_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25045f80676_m.png differ diff --git a/upload/complains/2017-12/5a25045f80676_m_thumb.png b/upload/complains/2017-12/5a25045f80676_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25045f80676_m_thumb.png differ diff --git a/upload/complains/2017-12/5a25045f80676_thumb.png b/upload/complains/2017-12/5a25045f80676_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25045f80676_thumb.png differ diff --git a/upload/complains/2017-12/5a25046409538.png b/upload/complains/2017-12/5a25046409538.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a25046409538.png differ diff --git a/upload/complains/2017-12/5a25046409538_m.png b/upload/complains/2017-12/5a25046409538_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a25046409538_m.png differ diff --git a/upload/complains/2017-12/5a25046409538_m_thumb.png b/upload/complains/2017-12/5a25046409538_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a25046409538_m_thumb.png differ diff --git a/upload/complains/2017-12/5a25046409538_thumb.png b/upload/complains/2017-12/5a25046409538_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a25046409538_thumb.png differ diff --git a/upload/complains/2017-12/5a25047243a16.png b/upload/complains/2017-12/5a25047243a16.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/complains/2017-12/5a25047243a16.png differ diff --git a/upload/complains/2017-12/5a25047243a16_m.png b/upload/complains/2017-12/5a25047243a16_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25047243a16_m.png differ diff --git a/upload/complains/2017-12/5a25047243a16_m_thumb.png b/upload/complains/2017-12/5a25047243a16_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25047243a16_m_thumb.png differ diff --git a/upload/complains/2017-12/5a25047243a16_thumb.png b/upload/complains/2017-12/5a25047243a16_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/complains/2017-12/5a25047243a16_thumb.png differ diff --git a/upload/complains/2017-12/5a2504764eac6.png b/upload/complains/2017-12/5a2504764eac6.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a2504764eac6.png differ diff --git a/upload/complains/2017-12/5a2504764eac6_m.png b/upload/complains/2017-12/5a2504764eac6_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a2504764eac6_m.png differ diff --git a/upload/complains/2017-12/5a2504764eac6_m_thumb.png b/upload/complains/2017-12/5a2504764eac6_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a2504764eac6_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2504764eac6_thumb.png b/upload/complains/2017-12/5a2504764eac6_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a2504764eac6_thumb.png differ diff --git a/upload/complains/2017-12/5a250491e6ea2.png b/upload/complains/2017-12/5a250491e6ea2.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a250491e6ea2.png differ diff --git a/upload/complains/2017-12/5a250491e6ea2_m.png b/upload/complains/2017-12/5a250491e6ea2_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a250491e6ea2_m.png differ diff --git a/upload/complains/2017-12/5a250491e6ea2_m_thumb.png b/upload/complains/2017-12/5a250491e6ea2_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a250491e6ea2_m_thumb.png differ diff --git a/upload/complains/2017-12/5a250491e6ea2_thumb.png b/upload/complains/2017-12/5a250491e6ea2_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a250491e6ea2_thumb.png differ diff --git a/upload/complains/2017-12/5a2504b85dc18.png b/upload/complains/2017-12/5a2504b85dc18.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a2504b85dc18.png differ diff --git a/upload/complains/2017-12/5a2504b85dc18_m.png b/upload/complains/2017-12/5a2504b85dc18_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a2504b85dc18_m.png differ diff --git a/upload/complains/2017-12/5a2504b85dc18_m_thumb.png b/upload/complains/2017-12/5a2504b85dc18_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a2504b85dc18_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2504b85dc18_thumb.png b/upload/complains/2017-12/5a2504b85dc18_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a2504b85dc18_thumb.png differ diff --git a/upload/complains/2017-12/5a2504e15395f.png b/upload/complains/2017-12/5a2504e15395f.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a2504e15395f.png differ diff --git a/upload/complains/2017-12/5a2504e15395f_m.png b/upload/complains/2017-12/5a2504e15395f_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a2504e15395f_m.png differ diff --git a/upload/complains/2017-12/5a2504e15395f_m_thumb.png b/upload/complains/2017-12/5a2504e15395f_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a2504e15395f_m_thumb.png differ diff --git a/upload/complains/2017-12/5a2504e15395f_thumb.png b/upload/complains/2017-12/5a2504e15395f_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a2504e15395f_thumb.png differ diff --git a/upload/complains/2017-12/5a250ae3ece83.png b/upload/complains/2017-12/5a250ae3ece83.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a250ae3ece83.png differ diff --git a/upload/complains/2017-12/5a250ae3ece83_m.png b/upload/complains/2017-12/5a250ae3ece83_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a250ae3ece83_m.png differ diff --git a/upload/complains/2017-12/5a250ae3ece83_m_thumb.png b/upload/complains/2017-12/5a250ae3ece83_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a250ae3ece83_m_thumb.png differ diff --git a/upload/complains/2017-12/5a250ae3ece83_thumb.png b/upload/complains/2017-12/5a250ae3ece83_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a250ae3ece83_thumb.png differ diff --git a/upload/complains/2017-12/5a250b0396ec5.jpeg b/upload/complains/2017-12/5a250b0396ec5.jpeg new file mode 100755 index 0000000..391214a Binary files /dev/null and b/upload/complains/2017-12/5a250b0396ec5.jpeg differ diff --git a/upload/complains/2017-12/5a250b0396ec5_m.jpeg b/upload/complains/2017-12/5a250b0396ec5_m.jpeg new file mode 100755 index 0000000..1ea7a20 Binary files /dev/null and b/upload/complains/2017-12/5a250b0396ec5_m.jpeg differ diff --git a/upload/complains/2017-12/5a250b0396ec5_m_thumb.jpeg b/upload/complains/2017-12/5a250b0396ec5_m_thumb.jpeg new file mode 100755 index 0000000..af74ee5 Binary files /dev/null and b/upload/complains/2017-12/5a250b0396ec5_m_thumb.jpeg differ diff --git a/upload/complains/2017-12/5a250b0396ec5_thumb.jpeg b/upload/complains/2017-12/5a250b0396ec5_thumb.jpeg new file mode 100755 index 0000000..9c5df01 Binary files /dev/null and b/upload/complains/2017-12/5a250b0396ec5_thumb.jpeg differ diff --git a/upload/complains/2017-12/5a250c51884ca.png b/upload/complains/2017-12/5a250c51884ca.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/complains/2017-12/5a250c51884ca.png differ diff --git a/upload/complains/2017-12/5a250c51884ca_m.png b/upload/complains/2017-12/5a250c51884ca_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/complains/2017-12/5a250c51884ca_m.png differ diff --git a/upload/complains/2017-12/5a250c51884ca_m_thumb.png b/upload/complains/2017-12/5a250c51884ca_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/complains/2017-12/5a250c51884ca_m_thumb.png differ diff --git a/upload/complains/2017-12/5a250c51884ca_thumb.png b/upload/complains/2017-12/5a250c51884ca_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/complains/2017-12/5a250c51884ca_thumb.png differ diff --git a/upload/complains/2017-12/5a250c548048b.jpg b/upload/complains/2017-12/5a250c548048b.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/complains/2017-12/5a250c548048b.jpg differ diff --git a/upload/complains/2017-12/5a250c548048b_m.jpg b/upload/complains/2017-12/5a250c548048b_m.jpg new file mode 100755 index 0000000..95fb262 Binary files /dev/null and b/upload/complains/2017-12/5a250c548048b_m.jpg differ diff --git a/upload/complains/2017-12/5a250c548048b_m_thumb.jpg b/upload/complains/2017-12/5a250c548048b_m_thumb.jpg new file mode 100755 index 0000000..60dbda7 Binary files /dev/null and b/upload/complains/2017-12/5a250c548048b_m_thumb.jpg differ diff --git a/upload/complains/2017-12/5a250c548048b_thumb.jpg b/upload/complains/2017-12/5a250c548048b_thumb.jpg new file mode 100755 index 0000000..6f43ef5 Binary files /dev/null and b/upload/complains/2017-12/5a250c548048b_thumb.jpg differ diff --git a/upload/complains/txt.txt b/upload/complains/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/complains/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/friendlinks/txt.txt b/upload/friendlinks/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/friendlinks/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/goods/2017-09/59cf01e0b7300.jpg b/upload/goods/2017-09/59cf01e0b7300.jpg new file mode 100755 index 0000000..90510ec Binary files /dev/null and b/upload/goods/2017-09/59cf01e0b7300.jpg differ diff --git a/upload/goods/2017-09/59cf01e0b7300_m.jpg b/upload/goods/2017-09/59cf01e0b7300_m.jpg new file mode 100755 index 0000000..7468fc1 Binary files /dev/null and b/upload/goods/2017-09/59cf01e0b7300_m.jpg differ diff --git a/upload/goods/2017-09/59cf01e0b7300_m_thumb.jpg b/upload/goods/2017-09/59cf01e0b7300_m_thumb.jpg new file mode 100755 index 0000000..7a590b5 Binary files /dev/null and b/upload/goods/2017-09/59cf01e0b7300_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf01e0b7300_thumb.jpg b/upload/goods/2017-09/59cf01e0b7300_thumb.jpg new file mode 100755 index 0000000..04f3265 Binary files /dev/null and b/upload/goods/2017-09/59cf01e0b7300_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf02d89d713.jpg b/upload/goods/2017-09/59cf02d89d713.jpg new file mode 100755 index 0000000..90510ec Binary files /dev/null and b/upload/goods/2017-09/59cf02d89d713.jpg differ diff --git a/upload/goods/2017-09/59cf02d89d713_m.jpg b/upload/goods/2017-09/59cf02d89d713_m.jpg new file mode 100755 index 0000000..7468fc1 Binary files /dev/null and b/upload/goods/2017-09/59cf02d89d713_m.jpg differ diff --git a/upload/goods/2017-09/59cf02d89d713_m_thumb.jpg b/upload/goods/2017-09/59cf02d89d713_m_thumb.jpg new file mode 100755 index 0000000..7a590b5 Binary files /dev/null and b/upload/goods/2017-09/59cf02d89d713_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf02d89d713_thumb.jpg b/upload/goods/2017-09/59cf02d89d713_thumb.jpg new file mode 100755 index 0000000..04f3265 Binary files /dev/null and b/upload/goods/2017-09/59cf02d89d713_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0353b35f8.jpg b/upload/goods/2017-09/59cf0353b35f8.jpg new file mode 100755 index 0000000..ac1dddd Binary files /dev/null and b/upload/goods/2017-09/59cf0353b35f8.jpg differ diff --git a/upload/goods/2017-09/59cf0353b35f8_m.jpg b/upload/goods/2017-09/59cf0353b35f8_m.jpg new file mode 100755 index 0000000..13eccef Binary files /dev/null and b/upload/goods/2017-09/59cf0353b35f8_m.jpg differ diff --git a/upload/goods/2017-09/59cf0353b35f8_m_thumb.jpg b/upload/goods/2017-09/59cf0353b35f8_m_thumb.jpg new file mode 100755 index 0000000..66e52d3 Binary files /dev/null and b/upload/goods/2017-09/59cf0353b35f8_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0353b35f8_thumb.jpg b/upload/goods/2017-09/59cf0353b35f8_thumb.jpg new file mode 100755 index 0000000..1137d39 Binary files /dev/null and b/upload/goods/2017-09/59cf0353b35f8_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf046758d02.jpg b/upload/goods/2017-09/59cf046758d02.jpg new file mode 100755 index 0000000..270e367 Binary files /dev/null and b/upload/goods/2017-09/59cf046758d02.jpg differ diff --git a/upload/goods/2017-09/59cf046758d02_m.jpg b/upload/goods/2017-09/59cf046758d02_m.jpg new file mode 100755 index 0000000..c6c42db Binary files /dev/null and b/upload/goods/2017-09/59cf046758d02_m.jpg differ diff --git a/upload/goods/2017-09/59cf046758d02_m_thumb.jpg b/upload/goods/2017-09/59cf046758d02_m_thumb.jpg new file mode 100755 index 0000000..beb5e86 Binary files /dev/null and b/upload/goods/2017-09/59cf046758d02_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf046758d02_thumb.jpg b/upload/goods/2017-09/59cf046758d02_thumb.jpg new file mode 100755 index 0000000..05666f2 Binary files /dev/null and b/upload/goods/2017-09/59cf046758d02_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf053d59dc4.jpg b/upload/goods/2017-09/59cf053d59dc4.jpg new file mode 100755 index 0000000..d06e9d6 Binary files /dev/null and b/upload/goods/2017-09/59cf053d59dc4.jpg differ diff --git a/upload/goods/2017-09/59cf053d59dc4_m.jpg b/upload/goods/2017-09/59cf053d59dc4_m.jpg new file mode 100755 index 0000000..caee92b Binary files /dev/null and b/upload/goods/2017-09/59cf053d59dc4_m.jpg differ diff --git a/upload/goods/2017-09/59cf053d59dc4_m_thumb.jpg b/upload/goods/2017-09/59cf053d59dc4_m_thumb.jpg new file mode 100755 index 0000000..7fee53e Binary files /dev/null and b/upload/goods/2017-09/59cf053d59dc4_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf053d59dc4_thumb.jpg b/upload/goods/2017-09/59cf053d59dc4_thumb.jpg new file mode 100755 index 0000000..2f1649b Binary files /dev/null and b/upload/goods/2017-09/59cf053d59dc4_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf05c60f9ea.jpg b/upload/goods/2017-09/59cf05c60f9ea.jpg new file mode 100755 index 0000000..d5acdb0 Binary files /dev/null and b/upload/goods/2017-09/59cf05c60f9ea.jpg differ diff --git a/upload/goods/2017-09/59cf05c60f9ea_m.jpg b/upload/goods/2017-09/59cf05c60f9ea_m.jpg new file mode 100755 index 0000000..789f85e Binary files /dev/null and b/upload/goods/2017-09/59cf05c60f9ea_m.jpg differ diff --git a/upload/goods/2017-09/59cf05c60f9ea_m_thumb.jpg b/upload/goods/2017-09/59cf05c60f9ea_m_thumb.jpg new file mode 100755 index 0000000..77e7d5f Binary files /dev/null and b/upload/goods/2017-09/59cf05c60f9ea_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf05c60f9ea_thumb.jpg b/upload/goods/2017-09/59cf05c60f9ea_thumb.jpg new file mode 100755 index 0000000..2e65e93 Binary files /dev/null and b/upload/goods/2017-09/59cf05c60f9ea_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf06674cf96.jpg b/upload/goods/2017-09/59cf06674cf96.jpg new file mode 100755 index 0000000..1870f61 Binary files /dev/null and b/upload/goods/2017-09/59cf06674cf96.jpg differ diff --git a/upload/goods/2017-09/59cf06674cf96_m.jpg b/upload/goods/2017-09/59cf06674cf96_m.jpg new file mode 100755 index 0000000..8341898 Binary files /dev/null and b/upload/goods/2017-09/59cf06674cf96_m.jpg differ diff --git a/upload/goods/2017-09/59cf06674cf96_m_thumb.jpg b/upload/goods/2017-09/59cf06674cf96_m_thumb.jpg new file mode 100755 index 0000000..126f503 Binary files /dev/null and b/upload/goods/2017-09/59cf06674cf96_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf06674cf96_thumb.jpg b/upload/goods/2017-09/59cf06674cf96_thumb.jpg new file mode 100755 index 0000000..a8b0fde Binary files /dev/null and b/upload/goods/2017-09/59cf06674cf96_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf06d1e6004.jpg b/upload/goods/2017-09/59cf06d1e6004.jpg new file mode 100755 index 0000000..6c97e5b Binary files /dev/null and b/upload/goods/2017-09/59cf06d1e6004.jpg differ diff --git a/upload/goods/2017-09/59cf06d1e6004_m.jpg b/upload/goods/2017-09/59cf06d1e6004_m.jpg new file mode 100755 index 0000000..9eba17e Binary files /dev/null and b/upload/goods/2017-09/59cf06d1e6004_m.jpg differ diff --git a/upload/goods/2017-09/59cf06d1e6004_m_thumb.jpg b/upload/goods/2017-09/59cf06d1e6004_m_thumb.jpg new file mode 100755 index 0000000..d41a506 Binary files /dev/null and b/upload/goods/2017-09/59cf06d1e6004_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf06d1e6004_thumb.jpg b/upload/goods/2017-09/59cf06d1e6004_thumb.jpg new file mode 100755 index 0000000..2f6f4f7 Binary files /dev/null and b/upload/goods/2017-09/59cf06d1e6004_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf074e3d3e9.jpg b/upload/goods/2017-09/59cf074e3d3e9.jpg new file mode 100755 index 0000000..6997658 Binary files /dev/null and b/upload/goods/2017-09/59cf074e3d3e9.jpg differ diff --git a/upload/goods/2017-09/59cf074e3d3e9_m.jpg b/upload/goods/2017-09/59cf074e3d3e9_m.jpg new file mode 100755 index 0000000..cffb8bc Binary files /dev/null and b/upload/goods/2017-09/59cf074e3d3e9_m.jpg differ diff --git a/upload/goods/2017-09/59cf074e3d3e9_m_thumb.jpg b/upload/goods/2017-09/59cf074e3d3e9_m_thumb.jpg new file mode 100755 index 0000000..6363375 Binary files /dev/null and b/upload/goods/2017-09/59cf074e3d3e9_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf074e3d3e9_thumb.jpg b/upload/goods/2017-09/59cf074e3d3e9_thumb.jpg new file mode 100755 index 0000000..a472c1f Binary files /dev/null and b/upload/goods/2017-09/59cf074e3d3e9_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf07d5b494c.jpg b/upload/goods/2017-09/59cf07d5b494c.jpg new file mode 100755 index 0000000..a66b5b7 Binary files /dev/null and b/upload/goods/2017-09/59cf07d5b494c.jpg differ diff --git a/upload/goods/2017-09/59cf07d5b494c_m.jpg b/upload/goods/2017-09/59cf07d5b494c_m.jpg new file mode 100755 index 0000000..4913b52 Binary files /dev/null and b/upload/goods/2017-09/59cf07d5b494c_m.jpg differ diff --git a/upload/goods/2017-09/59cf07d5b494c_m_thumb.jpg b/upload/goods/2017-09/59cf07d5b494c_m_thumb.jpg new file mode 100755 index 0000000..38e32ad Binary files /dev/null and b/upload/goods/2017-09/59cf07d5b494c_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf07d5b494c_thumb.jpg b/upload/goods/2017-09/59cf07d5b494c_thumb.jpg new file mode 100755 index 0000000..fd14632 Binary files /dev/null and b/upload/goods/2017-09/59cf07d5b494c_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf08aaad0d8.jpg b/upload/goods/2017-09/59cf08aaad0d8.jpg new file mode 100755 index 0000000..44c079b Binary files /dev/null and b/upload/goods/2017-09/59cf08aaad0d8.jpg differ diff --git a/upload/goods/2017-09/59cf08aaad0d8_m.jpg b/upload/goods/2017-09/59cf08aaad0d8_m.jpg new file mode 100755 index 0000000..1a7a75b Binary files /dev/null and b/upload/goods/2017-09/59cf08aaad0d8_m.jpg differ diff --git a/upload/goods/2017-09/59cf08aaad0d8_m_thumb.jpg b/upload/goods/2017-09/59cf08aaad0d8_m_thumb.jpg new file mode 100755 index 0000000..9a91022 Binary files /dev/null and b/upload/goods/2017-09/59cf08aaad0d8_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf08aaad0d8_thumb.jpg b/upload/goods/2017-09/59cf08aaad0d8_thumb.jpg new file mode 100755 index 0000000..b2b8e4e Binary files /dev/null and b/upload/goods/2017-09/59cf08aaad0d8_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0afd1a968.jpg b/upload/goods/2017-09/59cf0afd1a968.jpg new file mode 100755 index 0000000..e7041ad Binary files /dev/null and b/upload/goods/2017-09/59cf0afd1a968.jpg differ diff --git a/upload/goods/2017-09/59cf0afd1a968_m.jpg b/upload/goods/2017-09/59cf0afd1a968_m.jpg new file mode 100755 index 0000000..1354262 Binary files /dev/null and b/upload/goods/2017-09/59cf0afd1a968_m.jpg differ diff --git a/upload/goods/2017-09/59cf0afd1a968_m_thumb.jpg b/upload/goods/2017-09/59cf0afd1a968_m_thumb.jpg new file mode 100755 index 0000000..bc1550a Binary files /dev/null and b/upload/goods/2017-09/59cf0afd1a968_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0afd1a968_thumb.jpg b/upload/goods/2017-09/59cf0afd1a968_thumb.jpg new file mode 100755 index 0000000..96c1a73 Binary files /dev/null and b/upload/goods/2017-09/59cf0afd1a968_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0b9643cb2.jpg b/upload/goods/2017-09/59cf0b9643cb2.jpg new file mode 100755 index 0000000..294dbbb Binary files /dev/null and b/upload/goods/2017-09/59cf0b9643cb2.jpg differ diff --git a/upload/goods/2017-09/59cf0b9643cb2_m.jpg b/upload/goods/2017-09/59cf0b9643cb2_m.jpg new file mode 100755 index 0000000..f0beac8 Binary files /dev/null and b/upload/goods/2017-09/59cf0b9643cb2_m.jpg differ diff --git a/upload/goods/2017-09/59cf0b9643cb2_m_thumb.jpg b/upload/goods/2017-09/59cf0b9643cb2_m_thumb.jpg new file mode 100755 index 0000000..1f7cc3c Binary files /dev/null and b/upload/goods/2017-09/59cf0b9643cb2_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0b9643cb2_thumb.jpg b/upload/goods/2017-09/59cf0b9643cb2_thumb.jpg new file mode 100755 index 0000000..e7ea71b Binary files /dev/null and b/upload/goods/2017-09/59cf0b9643cb2_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0b9a1040d.jpg b/upload/goods/2017-09/59cf0b9a1040d.jpg new file mode 100755 index 0000000..b35dd4d Binary files /dev/null and b/upload/goods/2017-09/59cf0b9a1040d.jpg differ diff --git a/upload/goods/2017-09/59cf0b9a1040d_m.jpg b/upload/goods/2017-09/59cf0b9a1040d_m.jpg new file mode 100755 index 0000000..577aa74 Binary files /dev/null and b/upload/goods/2017-09/59cf0b9a1040d_m.jpg differ diff --git a/upload/goods/2017-09/59cf0b9a1040d_m_thumb.jpg b/upload/goods/2017-09/59cf0b9a1040d_m_thumb.jpg new file mode 100755 index 0000000..68d2cc2 Binary files /dev/null and b/upload/goods/2017-09/59cf0b9a1040d_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0b9a1040d_thumb.jpg b/upload/goods/2017-09/59cf0b9a1040d_thumb.jpg new file mode 100755 index 0000000..9be4348 Binary files /dev/null and b/upload/goods/2017-09/59cf0b9a1040d_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0ba59838e.jpg b/upload/goods/2017-09/59cf0ba59838e.jpg new file mode 100755 index 0000000..73e0875 Binary files /dev/null and b/upload/goods/2017-09/59cf0ba59838e.jpg differ diff --git a/upload/goods/2017-09/59cf0ba59838e_m.jpg b/upload/goods/2017-09/59cf0ba59838e_m.jpg new file mode 100755 index 0000000..6d88d51 Binary files /dev/null and b/upload/goods/2017-09/59cf0ba59838e_m.jpg differ diff --git a/upload/goods/2017-09/59cf0ba59838e_m_thumb.jpg b/upload/goods/2017-09/59cf0ba59838e_m_thumb.jpg new file mode 100755 index 0000000..8370987 Binary files /dev/null and b/upload/goods/2017-09/59cf0ba59838e_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf0ba59838e_thumb.jpg b/upload/goods/2017-09/59cf0ba59838e_thumb.jpg new file mode 100755 index 0000000..1991710 Binary files /dev/null and b/upload/goods/2017-09/59cf0ba59838e_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf337177ed1.jpg b/upload/goods/2017-09/59cf337177ed1.jpg new file mode 100755 index 0000000..5a3838c Binary files /dev/null and b/upload/goods/2017-09/59cf337177ed1.jpg differ diff --git a/upload/goods/2017-09/59cf337177ed1_m.jpg b/upload/goods/2017-09/59cf337177ed1_m.jpg new file mode 100755 index 0000000..f843b1b Binary files /dev/null and b/upload/goods/2017-09/59cf337177ed1_m.jpg differ diff --git a/upload/goods/2017-09/59cf337177ed1_m_thumb.jpg b/upload/goods/2017-09/59cf337177ed1_m_thumb.jpg new file mode 100755 index 0000000..415917c Binary files /dev/null and b/upload/goods/2017-09/59cf337177ed1_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf337177ed1_thumb.jpg b/upload/goods/2017-09/59cf337177ed1_thumb.jpg new file mode 100755 index 0000000..4feb1c9 Binary files /dev/null and b/upload/goods/2017-09/59cf337177ed1_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3447c05e8.jpg b/upload/goods/2017-09/59cf3447c05e8.jpg new file mode 100755 index 0000000..b54958a Binary files /dev/null and b/upload/goods/2017-09/59cf3447c05e8.jpg differ diff --git a/upload/goods/2017-09/59cf3447c05e8_m.jpg b/upload/goods/2017-09/59cf3447c05e8_m.jpg new file mode 100755 index 0000000..4fedc2f Binary files /dev/null and b/upload/goods/2017-09/59cf3447c05e8_m.jpg differ diff --git a/upload/goods/2017-09/59cf3447c05e8_m_thumb.jpg b/upload/goods/2017-09/59cf3447c05e8_m_thumb.jpg new file mode 100755 index 0000000..7ba8a70 Binary files /dev/null and b/upload/goods/2017-09/59cf3447c05e8_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3447c05e8_thumb.jpg b/upload/goods/2017-09/59cf3447c05e8_thumb.jpg new file mode 100755 index 0000000..b74f72c Binary files /dev/null and b/upload/goods/2017-09/59cf3447c05e8_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3447df581.jpg b/upload/goods/2017-09/59cf3447df581.jpg new file mode 100755 index 0000000..967da79 Binary files /dev/null and b/upload/goods/2017-09/59cf3447df581.jpg differ diff --git a/upload/goods/2017-09/59cf3447df581_m.jpg b/upload/goods/2017-09/59cf3447df581_m.jpg new file mode 100755 index 0000000..c9cdfb9 Binary files /dev/null and b/upload/goods/2017-09/59cf3447df581_m.jpg differ diff --git a/upload/goods/2017-09/59cf3447df581_m_thumb.jpg b/upload/goods/2017-09/59cf3447df581_m_thumb.jpg new file mode 100755 index 0000000..b3de158 Binary files /dev/null and b/upload/goods/2017-09/59cf3447df581_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3447df581_thumb.jpg b/upload/goods/2017-09/59cf3447df581_thumb.jpg new file mode 100755 index 0000000..cf5c09d Binary files /dev/null and b/upload/goods/2017-09/59cf3447df581_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf355955800.jpg b/upload/goods/2017-09/59cf355955800.jpg new file mode 100755 index 0000000..f164696 Binary files /dev/null and b/upload/goods/2017-09/59cf355955800.jpg differ diff --git a/upload/goods/2017-09/59cf355955800_m.jpg b/upload/goods/2017-09/59cf355955800_m.jpg new file mode 100755 index 0000000..b64f380 Binary files /dev/null and b/upload/goods/2017-09/59cf355955800_m.jpg differ diff --git a/upload/goods/2017-09/59cf355955800_m_thumb.jpg b/upload/goods/2017-09/59cf355955800_m_thumb.jpg new file mode 100755 index 0000000..a39418d Binary files /dev/null and b/upload/goods/2017-09/59cf355955800_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf355955800_thumb.jpg b/upload/goods/2017-09/59cf355955800_thumb.jpg new file mode 100755 index 0000000..747c3e1 Binary files /dev/null and b/upload/goods/2017-09/59cf355955800_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf35d82c51a.jpg b/upload/goods/2017-09/59cf35d82c51a.jpg new file mode 100755 index 0000000..78be4d0 Binary files /dev/null and b/upload/goods/2017-09/59cf35d82c51a.jpg differ diff --git a/upload/goods/2017-09/59cf35d82c51a_m.jpg b/upload/goods/2017-09/59cf35d82c51a_m.jpg new file mode 100755 index 0000000..d777167 Binary files /dev/null and b/upload/goods/2017-09/59cf35d82c51a_m.jpg differ diff --git a/upload/goods/2017-09/59cf35d82c51a_m_thumb.jpg b/upload/goods/2017-09/59cf35d82c51a_m_thumb.jpg new file mode 100755 index 0000000..97d81e0 Binary files /dev/null and b/upload/goods/2017-09/59cf35d82c51a_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf35d82c51a_thumb.jpg b/upload/goods/2017-09/59cf35d82c51a_thumb.jpg new file mode 100755 index 0000000..a6405fb Binary files /dev/null and b/upload/goods/2017-09/59cf35d82c51a_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3686189f3.jpg b/upload/goods/2017-09/59cf3686189f3.jpg new file mode 100755 index 0000000..57c5d76 Binary files /dev/null and b/upload/goods/2017-09/59cf3686189f3.jpg differ diff --git a/upload/goods/2017-09/59cf3686189f3_m.jpg b/upload/goods/2017-09/59cf3686189f3_m.jpg new file mode 100755 index 0000000..25e3580 Binary files /dev/null and b/upload/goods/2017-09/59cf3686189f3_m.jpg differ diff --git a/upload/goods/2017-09/59cf3686189f3_m_thumb.jpg b/upload/goods/2017-09/59cf3686189f3_m_thumb.jpg new file mode 100755 index 0000000..84d5c2a Binary files /dev/null and b/upload/goods/2017-09/59cf3686189f3_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3686189f3_thumb.jpg b/upload/goods/2017-09/59cf3686189f3_thumb.jpg new file mode 100755 index 0000000..98b7ee1 Binary files /dev/null and b/upload/goods/2017-09/59cf3686189f3_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf37605d6c2.jpg b/upload/goods/2017-09/59cf37605d6c2.jpg new file mode 100755 index 0000000..e9daef0 Binary files /dev/null and b/upload/goods/2017-09/59cf37605d6c2.jpg differ diff --git a/upload/goods/2017-09/59cf37605d6c2_m.jpg b/upload/goods/2017-09/59cf37605d6c2_m.jpg new file mode 100755 index 0000000..2407975 Binary files /dev/null and b/upload/goods/2017-09/59cf37605d6c2_m.jpg differ diff --git a/upload/goods/2017-09/59cf37605d6c2_m_thumb.jpg b/upload/goods/2017-09/59cf37605d6c2_m_thumb.jpg new file mode 100755 index 0000000..e0d2bb5 Binary files /dev/null and b/upload/goods/2017-09/59cf37605d6c2_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf37605d6c2_thumb.jpg b/upload/goods/2017-09/59cf37605d6c2_thumb.jpg new file mode 100755 index 0000000..cd85680 Binary files /dev/null and b/upload/goods/2017-09/59cf37605d6c2_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3c867d0d8.jpg b/upload/goods/2017-09/59cf3c867d0d8.jpg new file mode 100755 index 0000000..2a02f99 Binary files /dev/null and b/upload/goods/2017-09/59cf3c867d0d8.jpg differ diff --git a/upload/goods/2017-09/59cf3c867d0d8_m.jpg b/upload/goods/2017-09/59cf3c867d0d8_m.jpg new file mode 100755 index 0000000..5ad15ac Binary files /dev/null and b/upload/goods/2017-09/59cf3c867d0d8_m.jpg differ diff --git a/upload/goods/2017-09/59cf3c867d0d8_m_thumb.jpg b/upload/goods/2017-09/59cf3c867d0d8_m_thumb.jpg new file mode 100755 index 0000000..10477b4 Binary files /dev/null and b/upload/goods/2017-09/59cf3c867d0d8_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3c867d0d8_thumb.jpg b/upload/goods/2017-09/59cf3c867d0d8_thumb.jpg new file mode 100755 index 0000000..a3cf3f0 Binary files /dev/null and b/upload/goods/2017-09/59cf3c867d0d8_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3d302774f.jpg b/upload/goods/2017-09/59cf3d302774f.jpg new file mode 100755 index 0000000..978a448 Binary files /dev/null and b/upload/goods/2017-09/59cf3d302774f.jpg differ diff --git a/upload/goods/2017-09/59cf3d302774f_m.jpg b/upload/goods/2017-09/59cf3d302774f_m.jpg new file mode 100755 index 0000000..1cebbbc Binary files /dev/null and b/upload/goods/2017-09/59cf3d302774f_m.jpg differ diff --git a/upload/goods/2017-09/59cf3d302774f_m_thumb.jpg b/upload/goods/2017-09/59cf3d302774f_m_thumb.jpg new file mode 100755 index 0000000..af863a3 Binary files /dev/null and b/upload/goods/2017-09/59cf3d302774f_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3d302774f_thumb.jpg b/upload/goods/2017-09/59cf3d302774f_thumb.jpg new file mode 100755 index 0000000..87788c3 Binary files /dev/null and b/upload/goods/2017-09/59cf3d302774f_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3e45398c0.jpg b/upload/goods/2017-09/59cf3e45398c0.jpg new file mode 100755 index 0000000..c01e94b Binary files /dev/null and b/upload/goods/2017-09/59cf3e45398c0.jpg differ diff --git a/upload/goods/2017-09/59cf3e45398c0_m.jpg b/upload/goods/2017-09/59cf3e45398c0_m.jpg new file mode 100755 index 0000000..0807305 Binary files /dev/null and b/upload/goods/2017-09/59cf3e45398c0_m.jpg differ diff --git a/upload/goods/2017-09/59cf3e45398c0_m_thumb.jpg b/upload/goods/2017-09/59cf3e45398c0_m_thumb.jpg new file mode 100755 index 0000000..0b7c82c Binary files /dev/null and b/upload/goods/2017-09/59cf3e45398c0_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3e45398c0_thumb.jpg b/upload/goods/2017-09/59cf3e45398c0_thumb.jpg new file mode 100755 index 0000000..41742ce Binary files /dev/null and b/upload/goods/2017-09/59cf3e45398c0_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3ed28adb1.jpg b/upload/goods/2017-09/59cf3ed28adb1.jpg new file mode 100755 index 0000000..8557074 Binary files /dev/null and b/upload/goods/2017-09/59cf3ed28adb1.jpg differ diff --git a/upload/goods/2017-09/59cf3ed28adb1_m.jpg b/upload/goods/2017-09/59cf3ed28adb1_m.jpg new file mode 100755 index 0000000..3cda5fe Binary files /dev/null and b/upload/goods/2017-09/59cf3ed28adb1_m.jpg differ diff --git a/upload/goods/2017-09/59cf3ed28adb1_m_thumb.jpg b/upload/goods/2017-09/59cf3ed28adb1_m_thumb.jpg new file mode 100755 index 0000000..6e8bbbf Binary files /dev/null and b/upload/goods/2017-09/59cf3ed28adb1_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3ed28adb1_thumb.jpg b/upload/goods/2017-09/59cf3ed28adb1_thumb.jpg new file mode 100755 index 0000000..165b1c6 Binary files /dev/null and b/upload/goods/2017-09/59cf3ed28adb1_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3fb9f078f.jpg b/upload/goods/2017-09/59cf3fb9f078f.jpg new file mode 100755 index 0000000..35154d1 Binary files /dev/null and b/upload/goods/2017-09/59cf3fb9f078f.jpg differ diff --git a/upload/goods/2017-09/59cf3fb9f078f_m.jpg b/upload/goods/2017-09/59cf3fb9f078f_m.jpg new file mode 100755 index 0000000..5fa1076 Binary files /dev/null and b/upload/goods/2017-09/59cf3fb9f078f_m.jpg differ diff --git a/upload/goods/2017-09/59cf3fb9f078f_m_thumb.jpg b/upload/goods/2017-09/59cf3fb9f078f_m_thumb.jpg new file mode 100755 index 0000000..9c73631 Binary files /dev/null and b/upload/goods/2017-09/59cf3fb9f078f_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf3fb9f078f_thumb.jpg b/upload/goods/2017-09/59cf3fb9f078f_thumb.jpg new file mode 100755 index 0000000..3406a19 Binary files /dev/null and b/upload/goods/2017-09/59cf3fb9f078f_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4062cbfa8.jpg b/upload/goods/2017-09/59cf4062cbfa8.jpg new file mode 100755 index 0000000..3448dbf Binary files /dev/null and b/upload/goods/2017-09/59cf4062cbfa8.jpg differ diff --git a/upload/goods/2017-09/59cf4062cbfa8_m.jpg b/upload/goods/2017-09/59cf4062cbfa8_m.jpg new file mode 100755 index 0000000..1e305a0 Binary files /dev/null and b/upload/goods/2017-09/59cf4062cbfa8_m.jpg differ diff --git a/upload/goods/2017-09/59cf4062cbfa8_m_thumb.jpg b/upload/goods/2017-09/59cf4062cbfa8_m_thumb.jpg new file mode 100755 index 0000000..8b2f70a Binary files /dev/null and b/upload/goods/2017-09/59cf4062cbfa8_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4062cbfa8_thumb.jpg b/upload/goods/2017-09/59cf4062cbfa8_thumb.jpg new file mode 100755 index 0000000..6e48bd2 Binary files /dev/null and b/upload/goods/2017-09/59cf4062cbfa8_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4151c3d8e.jpg b/upload/goods/2017-09/59cf4151c3d8e.jpg new file mode 100755 index 0000000..84616fa Binary files /dev/null and b/upload/goods/2017-09/59cf4151c3d8e.jpg differ diff --git a/upload/goods/2017-09/59cf4151c3d8e_m.jpg b/upload/goods/2017-09/59cf4151c3d8e_m.jpg new file mode 100755 index 0000000..979e4a0 Binary files /dev/null and b/upload/goods/2017-09/59cf4151c3d8e_m.jpg differ diff --git a/upload/goods/2017-09/59cf4151c3d8e_m_thumb.jpg b/upload/goods/2017-09/59cf4151c3d8e_m_thumb.jpg new file mode 100755 index 0000000..0a4933e Binary files /dev/null and b/upload/goods/2017-09/59cf4151c3d8e_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4151c3d8e_thumb.jpg b/upload/goods/2017-09/59cf4151c3d8e_thumb.jpg new file mode 100755 index 0000000..b48e09f Binary files /dev/null and b/upload/goods/2017-09/59cf4151c3d8e_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf41d2d4ea9.jpg b/upload/goods/2017-09/59cf41d2d4ea9.jpg new file mode 100755 index 0000000..019596d Binary files /dev/null and b/upload/goods/2017-09/59cf41d2d4ea9.jpg differ diff --git a/upload/goods/2017-09/59cf41d2d4ea9_m.jpg b/upload/goods/2017-09/59cf41d2d4ea9_m.jpg new file mode 100755 index 0000000..77f031e Binary files /dev/null and b/upload/goods/2017-09/59cf41d2d4ea9_m.jpg differ diff --git a/upload/goods/2017-09/59cf41d2d4ea9_m_thumb.jpg b/upload/goods/2017-09/59cf41d2d4ea9_m_thumb.jpg new file mode 100755 index 0000000..36600bc Binary files /dev/null and b/upload/goods/2017-09/59cf41d2d4ea9_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf41d2d4ea9_thumb.jpg b/upload/goods/2017-09/59cf41d2d4ea9_thumb.jpg new file mode 100755 index 0000000..47acfd7 Binary files /dev/null and b/upload/goods/2017-09/59cf41d2d4ea9_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4601cdbca.jpg b/upload/goods/2017-09/59cf4601cdbca.jpg new file mode 100755 index 0000000..92a8b97 Binary files /dev/null and b/upload/goods/2017-09/59cf4601cdbca.jpg differ diff --git a/upload/goods/2017-09/59cf4601cdbca_m.jpg b/upload/goods/2017-09/59cf4601cdbca_m.jpg new file mode 100755 index 0000000..392ece3 Binary files /dev/null and b/upload/goods/2017-09/59cf4601cdbca_m.jpg differ diff --git a/upload/goods/2017-09/59cf4601cdbca_m_thumb.jpg b/upload/goods/2017-09/59cf4601cdbca_m_thumb.jpg new file mode 100755 index 0000000..168a35d Binary files /dev/null and b/upload/goods/2017-09/59cf4601cdbca_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4601cdbca_thumb.jpg b/upload/goods/2017-09/59cf4601cdbca_thumb.jpg new file mode 100755 index 0000000..69d093c Binary files /dev/null and b/upload/goods/2017-09/59cf4601cdbca_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf476e805ae.jpg b/upload/goods/2017-09/59cf476e805ae.jpg new file mode 100755 index 0000000..fb9fef4 Binary files /dev/null and b/upload/goods/2017-09/59cf476e805ae.jpg differ diff --git a/upload/goods/2017-09/59cf476e805ae_m.jpg b/upload/goods/2017-09/59cf476e805ae_m.jpg new file mode 100755 index 0000000..24201fd Binary files /dev/null and b/upload/goods/2017-09/59cf476e805ae_m.jpg differ diff --git a/upload/goods/2017-09/59cf476e805ae_m_thumb.jpg b/upload/goods/2017-09/59cf476e805ae_m_thumb.jpg new file mode 100755 index 0000000..9ae2bb8 Binary files /dev/null and b/upload/goods/2017-09/59cf476e805ae_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf476e805ae_thumb.jpg b/upload/goods/2017-09/59cf476e805ae_thumb.jpg new file mode 100755 index 0000000..9633330 Binary files /dev/null and b/upload/goods/2017-09/59cf476e805ae_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf49e65c901.jpg b/upload/goods/2017-09/59cf49e65c901.jpg new file mode 100755 index 0000000..073a277 Binary files /dev/null and b/upload/goods/2017-09/59cf49e65c901.jpg differ diff --git a/upload/goods/2017-09/59cf49e65c901_m.jpg b/upload/goods/2017-09/59cf49e65c901_m.jpg new file mode 100755 index 0000000..eb4030f Binary files /dev/null and b/upload/goods/2017-09/59cf49e65c901_m.jpg differ diff --git a/upload/goods/2017-09/59cf49e65c901_m_thumb.jpg b/upload/goods/2017-09/59cf49e65c901_m_thumb.jpg new file mode 100755 index 0000000..162c1a7 Binary files /dev/null and b/upload/goods/2017-09/59cf49e65c901_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf49e65c901_thumb.jpg b/upload/goods/2017-09/59cf49e65c901_thumb.jpg new file mode 100755 index 0000000..d4cdb3e Binary files /dev/null and b/upload/goods/2017-09/59cf49e65c901_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4e1843c6b.jpg b/upload/goods/2017-09/59cf4e1843c6b.jpg new file mode 100755 index 0000000..6118460 Binary files /dev/null and b/upload/goods/2017-09/59cf4e1843c6b.jpg differ diff --git a/upload/goods/2017-09/59cf4e1843c6b_m.jpg b/upload/goods/2017-09/59cf4e1843c6b_m.jpg new file mode 100755 index 0000000..6b8efd7 Binary files /dev/null and b/upload/goods/2017-09/59cf4e1843c6b_m.jpg differ diff --git a/upload/goods/2017-09/59cf4e1843c6b_m_thumb.jpg b/upload/goods/2017-09/59cf4e1843c6b_m_thumb.jpg new file mode 100755 index 0000000..12ec32a Binary files /dev/null and b/upload/goods/2017-09/59cf4e1843c6b_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf4e1843c6b_thumb.jpg b/upload/goods/2017-09/59cf4e1843c6b_thumb.jpg new file mode 100755 index 0000000..fcc845b Binary files /dev/null and b/upload/goods/2017-09/59cf4e1843c6b_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5051e900b.jpg b/upload/goods/2017-09/59cf5051e900b.jpg new file mode 100755 index 0000000..021c226 Binary files /dev/null and b/upload/goods/2017-09/59cf5051e900b.jpg differ diff --git a/upload/goods/2017-09/59cf5051e900b_m.jpg b/upload/goods/2017-09/59cf5051e900b_m.jpg new file mode 100755 index 0000000..a526d14 Binary files /dev/null and b/upload/goods/2017-09/59cf5051e900b_m.jpg differ diff --git a/upload/goods/2017-09/59cf5051e900b_m_thumb.jpg b/upload/goods/2017-09/59cf5051e900b_m_thumb.jpg new file mode 100755 index 0000000..a573da3 Binary files /dev/null and b/upload/goods/2017-09/59cf5051e900b_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5051e900b_thumb.jpg b/upload/goods/2017-09/59cf5051e900b_thumb.jpg new file mode 100755 index 0000000..7695d19 Binary files /dev/null and b/upload/goods/2017-09/59cf5051e900b_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf58746268f.jpg b/upload/goods/2017-09/59cf58746268f.jpg new file mode 100755 index 0000000..2ba85f3 Binary files /dev/null and b/upload/goods/2017-09/59cf58746268f.jpg differ diff --git a/upload/goods/2017-09/59cf58746268f_m.jpg b/upload/goods/2017-09/59cf58746268f_m.jpg new file mode 100755 index 0000000..7aeb600 Binary files /dev/null and b/upload/goods/2017-09/59cf58746268f_m.jpg differ diff --git a/upload/goods/2017-09/59cf58746268f_m_thumb.jpg b/upload/goods/2017-09/59cf58746268f_m_thumb.jpg new file mode 100755 index 0000000..45632aa Binary files /dev/null and b/upload/goods/2017-09/59cf58746268f_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf58746268f_thumb.jpg b/upload/goods/2017-09/59cf58746268f_thumb.jpg new file mode 100755 index 0000000..6cee02c Binary files /dev/null and b/upload/goods/2017-09/59cf58746268f_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5bec52d23.jpg b/upload/goods/2017-09/59cf5bec52d23.jpg new file mode 100755 index 0000000..4e6c067 Binary files /dev/null and b/upload/goods/2017-09/59cf5bec52d23.jpg differ diff --git a/upload/goods/2017-09/59cf5bec52d23_m.jpg b/upload/goods/2017-09/59cf5bec52d23_m.jpg new file mode 100755 index 0000000..4963a81 Binary files /dev/null and b/upload/goods/2017-09/59cf5bec52d23_m.jpg differ diff --git a/upload/goods/2017-09/59cf5bec52d23_m_thumb.jpg b/upload/goods/2017-09/59cf5bec52d23_m_thumb.jpg new file mode 100755 index 0000000..f873cb2 Binary files /dev/null and b/upload/goods/2017-09/59cf5bec52d23_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5bec52d23_thumb.jpg b/upload/goods/2017-09/59cf5bec52d23_thumb.jpg new file mode 100755 index 0000000..df086e8 Binary files /dev/null and b/upload/goods/2017-09/59cf5bec52d23_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5c7789276.jpg b/upload/goods/2017-09/59cf5c7789276.jpg new file mode 100755 index 0000000..5a8a2f9 Binary files /dev/null and b/upload/goods/2017-09/59cf5c7789276.jpg differ diff --git a/upload/goods/2017-09/59cf5c7789276_m.jpg b/upload/goods/2017-09/59cf5c7789276_m.jpg new file mode 100755 index 0000000..6372b03 Binary files /dev/null and b/upload/goods/2017-09/59cf5c7789276_m.jpg differ diff --git a/upload/goods/2017-09/59cf5c7789276_m_thumb.jpg b/upload/goods/2017-09/59cf5c7789276_m_thumb.jpg new file mode 100755 index 0000000..32350e0 Binary files /dev/null and b/upload/goods/2017-09/59cf5c7789276_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5c7789276_thumb.jpg b/upload/goods/2017-09/59cf5c7789276_thumb.jpg new file mode 100755 index 0000000..a54f287 Binary files /dev/null and b/upload/goods/2017-09/59cf5c7789276_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5d65a5520.jpg b/upload/goods/2017-09/59cf5d65a5520.jpg new file mode 100755 index 0000000..4e6c067 Binary files /dev/null and b/upload/goods/2017-09/59cf5d65a5520.jpg differ diff --git a/upload/goods/2017-09/59cf5d65a5520_m.jpg b/upload/goods/2017-09/59cf5d65a5520_m.jpg new file mode 100755 index 0000000..4963a81 Binary files /dev/null and b/upload/goods/2017-09/59cf5d65a5520_m.jpg differ diff --git a/upload/goods/2017-09/59cf5d65a5520_m_thumb.jpg b/upload/goods/2017-09/59cf5d65a5520_m_thumb.jpg new file mode 100755 index 0000000..f873cb2 Binary files /dev/null and b/upload/goods/2017-09/59cf5d65a5520_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5d65a5520_thumb.jpg b/upload/goods/2017-09/59cf5d65a5520_thumb.jpg new file mode 100755 index 0000000..df086e8 Binary files /dev/null and b/upload/goods/2017-09/59cf5d65a5520_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5e0690f68.jpg b/upload/goods/2017-09/59cf5e0690f68.jpg new file mode 100755 index 0000000..9214d6e Binary files /dev/null and b/upload/goods/2017-09/59cf5e0690f68.jpg differ diff --git a/upload/goods/2017-09/59cf5e0690f68_m.jpg b/upload/goods/2017-09/59cf5e0690f68_m.jpg new file mode 100755 index 0000000..78b4c4c Binary files /dev/null and b/upload/goods/2017-09/59cf5e0690f68_m.jpg differ diff --git a/upload/goods/2017-09/59cf5e0690f68_m_thumb.jpg b/upload/goods/2017-09/59cf5e0690f68_m_thumb.jpg new file mode 100755 index 0000000..2018c4a Binary files /dev/null and b/upload/goods/2017-09/59cf5e0690f68_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5e0690f68_thumb.jpg b/upload/goods/2017-09/59cf5e0690f68_thumb.jpg new file mode 100755 index 0000000..b8125db Binary files /dev/null and b/upload/goods/2017-09/59cf5e0690f68_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5e7276127.jpg b/upload/goods/2017-09/59cf5e7276127.jpg new file mode 100755 index 0000000..ce54b9e Binary files /dev/null and b/upload/goods/2017-09/59cf5e7276127.jpg differ diff --git a/upload/goods/2017-09/59cf5e7276127_m.jpg b/upload/goods/2017-09/59cf5e7276127_m.jpg new file mode 100755 index 0000000..69fa141 Binary files /dev/null and b/upload/goods/2017-09/59cf5e7276127_m.jpg differ diff --git a/upload/goods/2017-09/59cf5e7276127_m_thumb.jpg b/upload/goods/2017-09/59cf5e7276127_m_thumb.jpg new file mode 100755 index 0000000..2fd143b Binary files /dev/null and b/upload/goods/2017-09/59cf5e7276127_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5e7276127_thumb.jpg b/upload/goods/2017-09/59cf5e7276127_thumb.jpg new file mode 100755 index 0000000..a1213e6 Binary files /dev/null and b/upload/goods/2017-09/59cf5e7276127_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5f21e6cd2.jpg b/upload/goods/2017-09/59cf5f21e6cd2.jpg new file mode 100755 index 0000000..7146837 Binary files /dev/null and b/upload/goods/2017-09/59cf5f21e6cd2.jpg differ diff --git a/upload/goods/2017-09/59cf5f21e6cd2_m.jpg b/upload/goods/2017-09/59cf5f21e6cd2_m.jpg new file mode 100755 index 0000000..698997e Binary files /dev/null and b/upload/goods/2017-09/59cf5f21e6cd2_m.jpg differ diff --git a/upload/goods/2017-09/59cf5f21e6cd2_m_thumb.jpg b/upload/goods/2017-09/59cf5f21e6cd2_m_thumb.jpg new file mode 100755 index 0000000..dfa4ded Binary files /dev/null and b/upload/goods/2017-09/59cf5f21e6cd2_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5f21e6cd2_thumb.jpg b/upload/goods/2017-09/59cf5f21e6cd2_thumb.jpg new file mode 100755 index 0000000..2727940 Binary files /dev/null and b/upload/goods/2017-09/59cf5f21e6cd2_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5f31a5a9b.jpg b/upload/goods/2017-09/59cf5f31a5a9b.jpg new file mode 100755 index 0000000..a0cfda5 Binary files /dev/null and b/upload/goods/2017-09/59cf5f31a5a9b.jpg differ diff --git a/upload/goods/2017-09/59cf5f31a5a9b_m.jpg b/upload/goods/2017-09/59cf5f31a5a9b_m.jpg new file mode 100755 index 0000000..3e1ca12 Binary files /dev/null and b/upload/goods/2017-09/59cf5f31a5a9b_m.jpg differ diff --git a/upload/goods/2017-09/59cf5f31a5a9b_m_thumb.jpg b/upload/goods/2017-09/59cf5f31a5a9b_m_thumb.jpg new file mode 100755 index 0000000..91eb60d Binary files /dev/null and b/upload/goods/2017-09/59cf5f31a5a9b_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5f31a5a9b_thumb.jpg b/upload/goods/2017-09/59cf5f31a5a9b_thumb.jpg new file mode 100755 index 0000000..c5ca31d Binary files /dev/null and b/upload/goods/2017-09/59cf5f31a5a9b_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5fb82d84c.jpg b/upload/goods/2017-09/59cf5fb82d84c.jpg new file mode 100755 index 0000000..3571b09 Binary files /dev/null and b/upload/goods/2017-09/59cf5fb82d84c.jpg differ diff --git a/upload/goods/2017-09/59cf5fb82d84c_m.jpg b/upload/goods/2017-09/59cf5fb82d84c_m.jpg new file mode 100755 index 0000000..33c30e7 Binary files /dev/null and b/upload/goods/2017-09/59cf5fb82d84c_m.jpg differ diff --git a/upload/goods/2017-09/59cf5fb82d84c_m_thumb.jpg b/upload/goods/2017-09/59cf5fb82d84c_m_thumb.jpg new file mode 100755 index 0000000..52e7a27 Binary files /dev/null and b/upload/goods/2017-09/59cf5fb82d84c_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf5fb82d84c_thumb.jpg b/upload/goods/2017-09/59cf5fb82d84c_thumb.jpg new file mode 100755 index 0000000..adad4ca Binary files /dev/null and b/upload/goods/2017-09/59cf5fb82d84c_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6018af903.jpg b/upload/goods/2017-09/59cf6018af903.jpg new file mode 100755 index 0000000..317e23a Binary files /dev/null and b/upload/goods/2017-09/59cf6018af903.jpg differ diff --git a/upload/goods/2017-09/59cf6018af903_m.jpg b/upload/goods/2017-09/59cf6018af903_m.jpg new file mode 100755 index 0000000..a8af7bc Binary files /dev/null and b/upload/goods/2017-09/59cf6018af903_m.jpg differ diff --git a/upload/goods/2017-09/59cf6018af903_m_thumb.jpg b/upload/goods/2017-09/59cf6018af903_m_thumb.jpg new file mode 100755 index 0000000..e9c995e Binary files /dev/null and b/upload/goods/2017-09/59cf6018af903_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6018af903_thumb.jpg b/upload/goods/2017-09/59cf6018af903_thumb.jpg new file mode 100755 index 0000000..2a2ffaa Binary files /dev/null and b/upload/goods/2017-09/59cf6018af903_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf606864269.jpg b/upload/goods/2017-09/59cf606864269.jpg new file mode 100755 index 0000000..7146837 Binary files /dev/null and b/upload/goods/2017-09/59cf606864269.jpg differ diff --git a/upload/goods/2017-09/59cf606864269_m.jpg b/upload/goods/2017-09/59cf606864269_m.jpg new file mode 100755 index 0000000..698997e Binary files /dev/null and b/upload/goods/2017-09/59cf606864269_m.jpg differ diff --git a/upload/goods/2017-09/59cf606864269_m_thumb.jpg b/upload/goods/2017-09/59cf606864269_m_thumb.jpg new file mode 100755 index 0000000..dfa4ded Binary files /dev/null and b/upload/goods/2017-09/59cf606864269_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf606864269_thumb.jpg b/upload/goods/2017-09/59cf606864269_thumb.jpg new file mode 100755 index 0000000..2727940 Binary files /dev/null and b/upload/goods/2017-09/59cf606864269_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf606d10c7b.jpg b/upload/goods/2017-09/59cf606d10c7b.jpg new file mode 100755 index 0000000..f58f688 Binary files /dev/null and b/upload/goods/2017-09/59cf606d10c7b.jpg differ diff --git a/upload/goods/2017-09/59cf606d10c7b_m.jpg b/upload/goods/2017-09/59cf606d10c7b_m.jpg new file mode 100755 index 0000000..a8dd80c Binary files /dev/null and b/upload/goods/2017-09/59cf606d10c7b_m.jpg differ diff --git a/upload/goods/2017-09/59cf606d10c7b_m_thumb.jpg b/upload/goods/2017-09/59cf606d10c7b_m_thumb.jpg new file mode 100755 index 0000000..bd26ee5 Binary files /dev/null and b/upload/goods/2017-09/59cf606d10c7b_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf606d10c7b_thumb.jpg b/upload/goods/2017-09/59cf606d10c7b_thumb.jpg new file mode 100755 index 0000000..5ab385b Binary files /dev/null and b/upload/goods/2017-09/59cf606d10c7b_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf60c5ae54f.jpg b/upload/goods/2017-09/59cf60c5ae54f.jpg new file mode 100755 index 0000000..4862582 Binary files /dev/null and b/upload/goods/2017-09/59cf60c5ae54f.jpg differ diff --git a/upload/goods/2017-09/59cf60c5ae54f_m.jpg b/upload/goods/2017-09/59cf60c5ae54f_m.jpg new file mode 100755 index 0000000..f11785e Binary files /dev/null and b/upload/goods/2017-09/59cf60c5ae54f_m.jpg differ diff --git a/upload/goods/2017-09/59cf60c5ae54f_m_thumb.jpg b/upload/goods/2017-09/59cf60c5ae54f_m_thumb.jpg new file mode 100755 index 0000000..0b5a8a3 Binary files /dev/null and b/upload/goods/2017-09/59cf60c5ae54f_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf60c5ae54f_thumb.jpg b/upload/goods/2017-09/59cf60c5ae54f_thumb.jpg new file mode 100755 index 0000000..1aac08f Binary files /dev/null and b/upload/goods/2017-09/59cf60c5ae54f_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf615185a94.jpg b/upload/goods/2017-09/59cf615185a94.jpg new file mode 100755 index 0000000..2dce925 Binary files /dev/null and b/upload/goods/2017-09/59cf615185a94.jpg differ diff --git a/upload/goods/2017-09/59cf615185a94_m.jpg b/upload/goods/2017-09/59cf615185a94_m.jpg new file mode 100755 index 0000000..234cca1 Binary files /dev/null and b/upload/goods/2017-09/59cf615185a94_m.jpg differ diff --git a/upload/goods/2017-09/59cf615185a94_m_thumb.jpg b/upload/goods/2017-09/59cf615185a94_m_thumb.jpg new file mode 100755 index 0000000..93e3d14 Binary files /dev/null and b/upload/goods/2017-09/59cf615185a94_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf615185a94_thumb.jpg b/upload/goods/2017-09/59cf615185a94_thumb.jpg new file mode 100755 index 0000000..76f16e1 Binary files /dev/null and b/upload/goods/2017-09/59cf615185a94_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6158bed03.jpg b/upload/goods/2017-09/59cf6158bed03.jpg new file mode 100755 index 0000000..081a135 Binary files /dev/null and b/upload/goods/2017-09/59cf6158bed03.jpg differ diff --git a/upload/goods/2017-09/59cf6158bed03_m.jpg b/upload/goods/2017-09/59cf6158bed03_m.jpg new file mode 100755 index 0000000..4e6fac7 Binary files /dev/null and b/upload/goods/2017-09/59cf6158bed03_m.jpg differ diff --git a/upload/goods/2017-09/59cf6158bed03_m_thumb.jpg b/upload/goods/2017-09/59cf6158bed03_m_thumb.jpg new file mode 100755 index 0000000..fee80d8 Binary files /dev/null and b/upload/goods/2017-09/59cf6158bed03_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6158bed03_thumb.jpg b/upload/goods/2017-09/59cf6158bed03_thumb.jpg new file mode 100755 index 0000000..fb7badd Binary files /dev/null and b/upload/goods/2017-09/59cf6158bed03_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf61c035aa3.jpg b/upload/goods/2017-09/59cf61c035aa3.jpg new file mode 100755 index 0000000..8bec421 Binary files /dev/null and b/upload/goods/2017-09/59cf61c035aa3.jpg differ diff --git a/upload/goods/2017-09/59cf61c035aa3_m.jpg b/upload/goods/2017-09/59cf61c035aa3_m.jpg new file mode 100755 index 0000000..71959e3 Binary files /dev/null and b/upload/goods/2017-09/59cf61c035aa3_m.jpg differ diff --git a/upload/goods/2017-09/59cf61c035aa3_m_thumb.jpg b/upload/goods/2017-09/59cf61c035aa3_m_thumb.jpg new file mode 100755 index 0000000..f1e8169 Binary files /dev/null and b/upload/goods/2017-09/59cf61c035aa3_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf61c035aa3_thumb.jpg b/upload/goods/2017-09/59cf61c035aa3_thumb.jpg new file mode 100755 index 0000000..6cb0939 Binary files /dev/null and b/upload/goods/2017-09/59cf61c035aa3_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf62191db9a.jpg b/upload/goods/2017-09/59cf62191db9a.jpg new file mode 100755 index 0000000..d869ac9 Binary files /dev/null and b/upload/goods/2017-09/59cf62191db9a.jpg differ diff --git a/upload/goods/2017-09/59cf62191db9a_m.jpg b/upload/goods/2017-09/59cf62191db9a_m.jpg new file mode 100755 index 0000000..bbbaf9a Binary files /dev/null and b/upload/goods/2017-09/59cf62191db9a_m.jpg differ diff --git a/upload/goods/2017-09/59cf62191db9a_m_thumb.jpg b/upload/goods/2017-09/59cf62191db9a_m_thumb.jpg new file mode 100755 index 0000000..2fba709 Binary files /dev/null and b/upload/goods/2017-09/59cf62191db9a_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf62191db9a_thumb.jpg b/upload/goods/2017-09/59cf62191db9a_thumb.jpg new file mode 100755 index 0000000..172d2bf Binary files /dev/null and b/upload/goods/2017-09/59cf62191db9a_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf62619d29f.jpg b/upload/goods/2017-09/59cf62619d29f.jpg new file mode 100755 index 0000000..22eed57 Binary files /dev/null and b/upload/goods/2017-09/59cf62619d29f.jpg differ diff --git a/upload/goods/2017-09/59cf62619d29f_m.jpg b/upload/goods/2017-09/59cf62619d29f_m.jpg new file mode 100755 index 0000000..fd22d03 Binary files /dev/null and b/upload/goods/2017-09/59cf62619d29f_m.jpg differ diff --git a/upload/goods/2017-09/59cf62619d29f_m_thumb.jpg b/upload/goods/2017-09/59cf62619d29f_m_thumb.jpg new file mode 100755 index 0000000..41295b3 Binary files /dev/null and b/upload/goods/2017-09/59cf62619d29f_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf62619d29f_thumb.jpg b/upload/goods/2017-09/59cf62619d29f_thumb.jpg new file mode 100755 index 0000000..2cb5795 Binary files /dev/null and b/upload/goods/2017-09/59cf62619d29f_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6389534af.jpg b/upload/goods/2017-09/59cf6389534af.jpg new file mode 100755 index 0000000..1dc7ab2 Binary files /dev/null and b/upload/goods/2017-09/59cf6389534af.jpg differ diff --git a/upload/goods/2017-09/59cf6389534af_m.jpg b/upload/goods/2017-09/59cf6389534af_m.jpg new file mode 100755 index 0000000..38fd45b Binary files /dev/null and b/upload/goods/2017-09/59cf6389534af_m.jpg differ diff --git a/upload/goods/2017-09/59cf6389534af_m_thumb.jpg b/upload/goods/2017-09/59cf6389534af_m_thumb.jpg new file mode 100755 index 0000000..6bff142 Binary files /dev/null and b/upload/goods/2017-09/59cf6389534af_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6389534af_thumb.jpg b/upload/goods/2017-09/59cf6389534af_thumb.jpg new file mode 100755 index 0000000..cd70aa8 Binary files /dev/null and b/upload/goods/2017-09/59cf6389534af_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf645a0d1aa.jpg b/upload/goods/2017-09/59cf645a0d1aa.jpg new file mode 100755 index 0000000..cdd382f Binary files /dev/null and b/upload/goods/2017-09/59cf645a0d1aa.jpg differ diff --git a/upload/goods/2017-09/59cf645a0d1aa_m.jpg b/upload/goods/2017-09/59cf645a0d1aa_m.jpg new file mode 100755 index 0000000..adf995d Binary files /dev/null and b/upload/goods/2017-09/59cf645a0d1aa_m.jpg differ diff --git a/upload/goods/2017-09/59cf645a0d1aa_m_thumb.jpg b/upload/goods/2017-09/59cf645a0d1aa_m_thumb.jpg new file mode 100755 index 0000000..b7e5d12 Binary files /dev/null and b/upload/goods/2017-09/59cf645a0d1aa_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf645a0d1aa_thumb.jpg b/upload/goods/2017-09/59cf645a0d1aa_thumb.jpg new file mode 100755 index 0000000..0db68e1 Binary files /dev/null and b/upload/goods/2017-09/59cf645a0d1aa_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf64a62237e.jpg b/upload/goods/2017-09/59cf64a62237e.jpg new file mode 100755 index 0000000..8bec421 Binary files /dev/null and b/upload/goods/2017-09/59cf64a62237e.jpg differ diff --git a/upload/goods/2017-09/59cf64a62237e_m.jpg b/upload/goods/2017-09/59cf64a62237e_m.jpg new file mode 100755 index 0000000..71959e3 Binary files /dev/null and b/upload/goods/2017-09/59cf64a62237e_m.jpg differ diff --git a/upload/goods/2017-09/59cf64a62237e_m_thumb.jpg b/upload/goods/2017-09/59cf64a62237e_m_thumb.jpg new file mode 100755 index 0000000..f1e8169 Binary files /dev/null and b/upload/goods/2017-09/59cf64a62237e_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf64a62237e_thumb.jpg b/upload/goods/2017-09/59cf64a62237e_thumb.jpg new file mode 100755 index 0000000..6cb0939 Binary files /dev/null and b/upload/goods/2017-09/59cf64a62237e_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf64da11550.jpg b/upload/goods/2017-09/59cf64da11550.jpg new file mode 100755 index 0000000..0457b78 Binary files /dev/null and b/upload/goods/2017-09/59cf64da11550.jpg differ diff --git a/upload/goods/2017-09/59cf64da11550_m.jpg b/upload/goods/2017-09/59cf64da11550_m.jpg new file mode 100755 index 0000000..7405d02 Binary files /dev/null and b/upload/goods/2017-09/59cf64da11550_m.jpg differ diff --git a/upload/goods/2017-09/59cf64da11550_m_thumb.jpg b/upload/goods/2017-09/59cf64da11550_m_thumb.jpg new file mode 100755 index 0000000..e088abd Binary files /dev/null and b/upload/goods/2017-09/59cf64da11550_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf64da11550_thumb.jpg b/upload/goods/2017-09/59cf64da11550_thumb.jpg new file mode 100755 index 0000000..cfad543 Binary files /dev/null and b/upload/goods/2017-09/59cf64da11550_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf65190ff87.jpg b/upload/goods/2017-09/59cf65190ff87.jpg new file mode 100755 index 0000000..0457b78 Binary files /dev/null and b/upload/goods/2017-09/59cf65190ff87.jpg differ diff --git a/upload/goods/2017-09/59cf65190ff87_m.jpg b/upload/goods/2017-09/59cf65190ff87_m.jpg new file mode 100755 index 0000000..7405d02 Binary files /dev/null and b/upload/goods/2017-09/59cf65190ff87_m.jpg differ diff --git a/upload/goods/2017-09/59cf65190ff87_m_thumb.jpg b/upload/goods/2017-09/59cf65190ff87_m_thumb.jpg new file mode 100755 index 0000000..e088abd Binary files /dev/null and b/upload/goods/2017-09/59cf65190ff87_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf65190ff87_thumb.jpg b/upload/goods/2017-09/59cf65190ff87_thumb.jpg new file mode 100755 index 0000000..cfad543 Binary files /dev/null and b/upload/goods/2017-09/59cf65190ff87_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf65a4b1649.jpg b/upload/goods/2017-09/59cf65a4b1649.jpg new file mode 100755 index 0000000..e18621c Binary files /dev/null and b/upload/goods/2017-09/59cf65a4b1649.jpg differ diff --git a/upload/goods/2017-09/59cf65a4b1649_m.jpg b/upload/goods/2017-09/59cf65a4b1649_m.jpg new file mode 100755 index 0000000..ad463a2 Binary files /dev/null and b/upload/goods/2017-09/59cf65a4b1649_m.jpg differ diff --git a/upload/goods/2017-09/59cf65a4b1649_m_thumb.jpg b/upload/goods/2017-09/59cf65a4b1649_m_thumb.jpg new file mode 100755 index 0000000..13d9436 Binary files /dev/null and b/upload/goods/2017-09/59cf65a4b1649_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf65a4b1649_thumb.jpg b/upload/goods/2017-09/59cf65a4b1649_thumb.jpg new file mode 100755 index 0000000..e94bf0d Binary files /dev/null and b/upload/goods/2017-09/59cf65a4b1649_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf665e5890a.jpg b/upload/goods/2017-09/59cf665e5890a.jpg new file mode 100755 index 0000000..acddb8d Binary files /dev/null and b/upload/goods/2017-09/59cf665e5890a.jpg differ diff --git a/upload/goods/2017-09/59cf665e5890a_m.jpg b/upload/goods/2017-09/59cf665e5890a_m.jpg new file mode 100755 index 0000000..058c268 Binary files /dev/null and b/upload/goods/2017-09/59cf665e5890a_m.jpg differ diff --git a/upload/goods/2017-09/59cf665e5890a_m_thumb.jpg b/upload/goods/2017-09/59cf665e5890a_m_thumb.jpg new file mode 100755 index 0000000..5f069d6 Binary files /dev/null and b/upload/goods/2017-09/59cf665e5890a_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf665e5890a_thumb.jpg b/upload/goods/2017-09/59cf665e5890a_thumb.jpg new file mode 100755 index 0000000..628d3a0 Binary files /dev/null and b/upload/goods/2017-09/59cf665e5890a_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf67798753c.jpg b/upload/goods/2017-09/59cf67798753c.jpg new file mode 100755 index 0000000..e22d860 Binary files /dev/null and b/upload/goods/2017-09/59cf67798753c.jpg differ diff --git a/upload/goods/2017-09/59cf67798753c_m.jpg b/upload/goods/2017-09/59cf67798753c_m.jpg new file mode 100755 index 0000000..2111e19 Binary files /dev/null and b/upload/goods/2017-09/59cf67798753c_m.jpg differ diff --git a/upload/goods/2017-09/59cf67798753c_m_thumb.jpg b/upload/goods/2017-09/59cf67798753c_m_thumb.jpg new file mode 100755 index 0000000..64cb349 Binary files /dev/null and b/upload/goods/2017-09/59cf67798753c_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf67798753c_thumb.jpg b/upload/goods/2017-09/59cf67798753c_thumb.jpg new file mode 100755 index 0000000..ba74921 Binary files /dev/null and b/upload/goods/2017-09/59cf67798753c_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6797347e0.jpg b/upload/goods/2017-09/59cf6797347e0.jpg new file mode 100755 index 0000000..6c00c26 Binary files /dev/null and b/upload/goods/2017-09/59cf6797347e0.jpg differ diff --git a/upload/goods/2017-09/59cf6797347e0_m.jpg b/upload/goods/2017-09/59cf6797347e0_m.jpg new file mode 100755 index 0000000..bdd3a2c Binary files /dev/null and b/upload/goods/2017-09/59cf6797347e0_m.jpg differ diff --git a/upload/goods/2017-09/59cf6797347e0_m_thumb.jpg b/upload/goods/2017-09/59cf6797347e0_m_thumb.jpg new file mode 100755 index 0000000..bdd3a2c Binary files /dev/null and b/upload/goods/2017-09/59cf6797347e0_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6797347e0_thumb.jpg b/upload/goods/2017-09/59cf6797347e0_thumb.jpg new file mode 100755 index 0000000..bdd3a2c Binary files /dev/null and b/upload/goods/2017-09/59cf6797347e0_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf67c7de29d.jpg b/upload/goods/2017-09/59cf67c7de29d.jpg new file mode 100755 index 0000000..e0391c4 Binary files /dev/null and b/upload/goods/2017-09/59cf67c7de29d.jpg differ diff --git a/upload/goods/2017-09/59cf67c7de29d_m.jpg b/upload/goods/2017-09/59cf67c7de29d_m.jpg new file mode 100755 index 0000000..ee7466c Binary files /dev/null and b/upload/goods/2017-09/59cf67c7de29d_m.jpg differ diff --git a/upload/goods/2017-09/59cf67c7de29d_m_thumb.jpg b/upload/goods/2017-09/59cf67c7de29d_m_thumb.jpg new file mode 100755 index 0000000..edc11b0 Binary files /dev/null and b/upload/goods/2017-09/59cf67c7de29d_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf67c7de29d_thumb.jpg b/upload/goods/2017-09/59cf67c7de29d_thumb.jpg new file mode 100755 index 0000000..3b01a3e Binary files /dev/null and b/upload/goods/2017-09/59cf67c7de29d_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf680da7246.jpg b/upload/goods/2017-09/59cf680da7246.jpg new file mode 100755 index 0000000..6c759f2 Binary files /dev/null and b/upload/goods/2017-09/59cf680da7246.jpg differ diff --git a/upload/goods/2017-09/59cf680da7246_m.jpg b/upload/goods/2017-09/59cf680da7246_m.jpg new file mode 100755 index 0000000..3ae0057 Binary files /dev/null and b/upload/goods/2017-09/59cf680da7246_m.jpg differ diff --git a/upload/goods/2017-09/59cf680da7246_m_thumb.jpg b/upload/goods/2017-09/59cf680da7246_m_thumb.jpg new file mode 100755 index 0000000..072b839 Binary files /dev/null and b/upload/goods/2017-09/59cf680da7246_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf680da7246_thumb.jpg b/upload/goods/2017-09/59cf680da7246_thumb.jpg new file mode 100755 index 0000000..27c1f27 Binary files /dev/null and b/upload/goods/2017-09/59cf680da7246_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6863d0ee7.jpg b/upload/goods/2017-09/59cf6863d0ee7.jpg new file mode 100755 index 0000000..9a9c1bf Binary files /dev/null and b/upload/goods/2017-09/59cf6863d0ee7.jpg differ diff --git a/upload/goods/2017-09/59cf6863d0ee7_m.jpg b/upload/goods/2017-09/59cf6863d0ee7_m.jpg new file mode 100755 index 0000000..0f250b4 Binary files /dev/null and b/upload/goods/2017-09/59cf6863d0ee7_m.jpg differ diff --git a/upload/goods/2017-09/59cf6863d0ee7_m_thumb.jpg b/upload/goods/2017-09/59cf6863d0ee7_m_thumb.jpg new file mode 100755 index 0000000..40407c7 Binary files /dev/null and b/upload/goods/2017-09/59cf6863d0ee7_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6863d0ee7_thumb.jpg b/upload/goods/2017-09/59cf6863d0ee7_thumb.jpg new file mode 100755 index 0000000..a9af7fb Binary files /dev/null and b/upload/goods/2017-09/59cf6863d0ee7_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf690ab38ac.jpg b/upload/goods/2017-09/59cf690ab38ac.jpg new file mode 100755 index 0000000..91677a8 Binary files /dev/null and b/upload/goods/2017-09/59cf690ab38ac.jpg differ diff --git a/upload/goods/2017-09/59cf690ab38ac_m.jpg b/upload/goods/2017-09/59cf690ab38ac_m.jpg new file mode 100755 index 0000000..15942c5 Binary files /dev/null and b/upload/goods/2017-09/59cf690ab38ac_m.jpg differ diff --git a/upload/goods/2017-09/59cf690ab38ac_m_thumb.jpg b/upload/goods/2017-09/59cf690ab38ac_m_thumb.jpg new file mode 100755 index 0000000..df2582b Binary files /dev/null and b/upload/goods/2017-09/59cf690ab38ac_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf690ab38ac_thumb.jpg b/upload/goods/2017-09/59cf690ab38ac_thumb.jpg new file mode 100755 index 0000000..6a46f8e Binary files /dev/null and b/upload/goods/2017-09/59cf690ab38ac_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf69a6affcb.jpg b/upload/goods/2017-09/59cf69a6affcb.jpg new file mode 100755 index 0000000..46a1c84 Binary files /dev/null and b/upload/goods/2017-09/59cf69a6affcb.jpg differ diff --git a/upload/goods/2017-09/59cf69a6affcb_m.jpg b/upload/goods/2017-09/59cf69a6affcb_m.jpg new file mode 100755 index 0000000..2689b00 Binary files /dev/null and b/upload/goods/2017-09/59cf69a6affcb_m.jpg differ diff --git a/upload/goods/2017-09/59cf69a6affcb_m_thumb.jpg b/upload/goods/2017-09/59cf69a6affcb_m_thumb.jpg new file mode 100755 index 0000000..b468166 Binary files /dev/null and b/upload/goods/2017-09/59cf69a6affcb_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf69a6affcb_thumb.jpg b/upload/goods/2017-09/59cf69a6affcb_thumb.jpg new file mode 100755 index 0000000..b7b46c7 Binary files /dev/null and b/upload/goods/2017-09/59cf69a6affcb_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6b883f197.jpg b/upload/goods/2017-09/59cf6b883f197.jpg new file mode 100755 index 0000000..b965b73 Binary files /dev/null and b/upload/goods/2017-09/59cf6b883f197.jpg differ diff --git a/upload/goods/2017-09/59cf6b883f197_m.jpg b/upload/goods/2017-09/59cf6b883f197_m.jpg new file mode 100755 index 0000000..7d665ac Binary files /dev/null and b/upload/goods/2017-09/59cf6b883f197_m.jpg differ diff --git a/upload/goods/2017-09/59cf6b883f197_m_thumb.jpg b/upload/goods/2017-09/59cf6b883f197_m_thumb.jpg new file mode 100755 index 0000000..fdab8ef Binary files /dev/null and b/upload/goods/2017-09/59cf6b883f197_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6b883f197_thumb.jpg b/upload/goods/2017-09/59cf6b883f197_thumb.jpg new file mode 100755 index 0000000..4acc0fa Binary files /dev/null and b/upload/goods/2017-09/59cf6b883f197_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6bebb4931.jpg b/upload/goods/2017-09/59cf6bebb4931.jpg new file mode 100755 index 0000000..8078798 Binary files /dev/null and b/upload/goods/2017-09/59cf6bebb4931.jpg differ diff --git a/upload/goods/2017-09/59cf6bebb4931_m.jpg b/upload/goods/2017-09/59cf6bebb4931_m.jpg new file mode 100755 index 0000000..49e2681 Binary files /dev/null and b/upload/goods/2017-09/59cf6bebb4931_m.jpg differ diff --git a/upload/goods/2017-09/59cf6bebb4931_m_thumb.jpg b/upload/goods/2017-09/59cf6bebb4931_m_thumb.jpg new file mode 100755 index 0000000..d6f5924 Binary files /dev/null and b/upload/goods/2017-09/59cf6bebb4931_m_thumb.jpg differ diff --git a/upload/goods/2017-09/59cf6bebb4931_thumb.jpg b/upload/goods/2017-09/59cf6bebb4931_thumb.jpg new file mode 100755 index 0000000..4b1b3d5 Binary files /dev/null and b/upload/goods/2017-09/59cf6bebb4931_thumb.jpg differ diff --git a/upload/goods/2017-11/5a03f959e9dae.png b/upload/goods/2017-11/5a03f959e9dae.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a03f959e9dae.png differ diff --git a/upload/goods/2017-11/5a03f959e9dae_m.png b/upload/goods/2017-11/5a03f959e9dae_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f959e9dae_m.png differ diff --git a/upload/goods/2017-11/5a03f959e9dae_m_thumb.png b/upload/goods/2017-11/5a03f959e9dae_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f959e9dae_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03f959e9dae_thumb.png b/upload/goods/2017-11/5a03f959e9dae_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f959e9dae_thumb.png differ diff --git a/upload/goods/2017-11/5a03f972f2c45.png b/upload/goods/2017-11/5a03f972f2c45.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a03f972f2c45.png differ diff --git a/upload/goods/2017-11/5a03f972f2c45_m.png b/upload/goods/2017-11/5a03f972f2c45_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f972f2c45_m.png differ diff --git a/upload/goods/2017-11/5a03f972f2c45_m_thumb.png b/upload/goods/2017-11/5a03f972f2c45_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f972f2c45_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03f972f2c45_thumb.png b/upload/goods/2017-11/5a03f972f2c45_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03f972f2c45_thumb.png differ diff --git a/upload/goods/2017-11/5a03fa0c88a70.png b/upload/goods/2017-11/5a03fa0c88a70.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a03fa0c88a70.png differ diff --git a/upload/goods/2017-11/5a03fa0c88a70_m.png b/upload/goods/2017-11/5a03fa0c88a70_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fa0c88a70_m.png differ diff --git a/upload/goods/2017-11/5a03fa0c88a70_m_thumb.png b/upload/goods/2017-11/5a03fa0c88a70_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fa0c88a70_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fa0c88a70_thumb.png b/upload/goods/2017-11/5a03fa0c88a70_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fa0c88a70_thumb.png differ diff --git a/upload/goods/2017-11/5a03fa59777cc.jpg b/upload/goods/2017-11/5a03fa59777cc.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2017-11/5a03fa59777cc.jpg differ diff --git a/upload/goods/2017-11/5a03fa59777cc_m.jpg b/upload/goods/2017-11/5a03fa59777cc_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2017-11/5a03fa59777cc_m.jpg differ diff --git a/upload/goods/2017-11/5a03fa59777cc_m_thumb.jpg b/upload/goods/2017-11/5a03fa59777cc_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2017-11/5a03fa59777cc_m_thumb.jpg differ diff --git a/upload/goods/2017-11/5a03fa59777cc_thumb.jpg b/upload/goods/2017-11/5a03fa59777cc_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2017-11/5a03fa59777cc_thumb.jpg differ diff --git a/upload/goods/2017-11/5a03faacabcfd.png b/upload/goods/2017-11/5a03faacabcfd.png new file mode 100755 index 0000000..3d8a714 Binary files /dev/null and b/upload/goods/2017-11/5a03faacabcfd.png differ diff --git a/upload/goods/2017-11/5a03faacabcfd_m.png b/upload/goods/2017-11/5a03faacabcfd_m.png new file mode 100755 index 0000000..5ba0602 Binary files /dev/null and b/upload/goods/2017-11/5a03faacabcfd_m.png differ diff --git a/upload/goods/2017-11/5a03faacabcfd_m_thumb.png b/upload/goods/2017-11/5a03faacabcfd_m_thumb.png new file mode 100755 index 0000000..3b996a5 Binary files /dev/null and b/upload/goods/2017-11/5a03faacabcfd_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03faacabcfd_thumb.png b/upload/goods/2017-11/5a03faacabcfd_thumb.png new file mode 100755 index 0000000..751e847 Binary files /dev/null and b/upload/goods/2017-11/5a03faacabcfd_thumb.png differ diff --git a/upload/goods/2017-11/5a03fabe4a18d.png b/upload/goods/2017-11/5a03fabe4a18d.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/goods/2017-11/5a03fabe4a18d.png differ diff --git a/upload/goods/2017-11/5a03fabe4a18d_m.png b/upload/goods/2017-11/5a03fabe4a18d_m.png new file mode 100755 index 0000000..bb403c7 Binary files /dev/null and b/upload/goods/2017-11/5a03fabe4a18d_m.png differ diff --git a/upload/goods/2017-11/5a03fabe4a18d_m_thumb.png b/upload/goods/2017-11/5a03fabe4a18d_m_thumb.png new file mode 100755 index 0000000..6371ae5 Binary files /dev/null and b/upload/goods/2017-11/5a03fabe4a18d_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fabe4a18d_thumb.png b/upload/goods/2017-11/5a03fabe4a18d_thumb.png new file mode 100755 index 0000000..b9edaae Binary files /dev/null and b/upload/goods/2017-11/5a03fabe4a18d_thumb.png differ diff --git a/upload/goods/2017-11/5a03fac899f05.png b/upload/goods/2017-11/5a03fac899f05.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a03fac899f05.png differ diff --git a/upload/goods/2017-11/5a03fac899f05_m.png b/upload/goods/2017-11/5a03fac899f05_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fac899f05_m.png differ diff --git a/upload/goods/2017-11/5a03fac899f05_m_thumb.png b/upload/goods/2017-11/5a03fac899f05_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fac899f05_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fac899f05_thumb.png b/upload/goods/2017-11/5a03fac899f05_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fac899f05_thumb.png differ diff --git a/upload/goods/2017-11/5a03fade55609.png b/upload/goods/2017-11/5a03fade55609.png new file mode 100755 index 0000000..ba8dd63 Binary files /dev/null and b/upload/goods/2017-11/5a03fade55609.png differ diff --git a/upload/goods/2017-11/5a03fade55609_m.png b/upload/goods/2017-11/5a03fade55609_m.png new file mode 100755 index 0000000..9de3fd7 Binary files /dev/null and b/upload/goods/2017-11/5a03fade55609_m.png differ diff --git a/upload/goods/2017-11/5a03fade55609_m_thumb.png b/upload/goods/2017-11/5a03fade55609_m_thumb.png new file mode 100755 index 0000000..9584f22 Binary files /dev/null and b/upload/goods/2017-11/5a03fade55609_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fade55609_thumb.png b/upload/goods/2017-11/5a03fade55609_thumb.png new file mode 100755 index 0000000..b8885e8 Binary files /dev/null and b/upload/goods/2017-11/5a03fade55609_thumb.png differ diff --git a/upload/goods/2017-11/5a03fbaa31568.png b/upload/goods/2017-11/5a03fbaa31568.png new file mode 100755 index 0000000..3d8a714 Binary files /dev/null and b/upload/goods/2017-11/5a03fbaa31568.png differ diff --git a/upload/goods/2017-11/5a03fbaa31568_m.png b/upload/goods/2017-11/5a03fbaa31568_m.png new file mode 100755 index 0000000..5ba0602 Binary files /dev/null and b/upload/goods/2017-11/5a03fbaa31568_m.png differ diff --git a/upload/goods/2017-11/5a03fbaa31568_m_thumb.png b/upload/goods/2017-11/5a03fbaa31568_m_thumb.png new file mode 100755 index 0000000..3b996a5 Binary files /dev/null and b/upload/goods/2017-11/5a03fbaa31568_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fbaa31568_thumb.png b/upload/goods/2017-11/5a03fbaa31568_thumb.png new file mode 100755 index 0000000..751e847 Binary files /dev/null and b/upload/goods/2017-11/5a03fbaa31568_thumb.png differ diff --git a/upload/goods/2017-11/5a03fbb42a41d.png b/upload/goods/2017-11/5a03fbb42a41d.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a03fbb42a41d.png differ diff --git a/upload/goods/2017-11/5a03fbb42a41d_m.png b/upload/goods/2017-11/5a03fbb42a41d_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fbb42a41d_m.png differ diff --git a/upload/goods/2017-11/5a03fbb42a41d_m_thumb.png b/upload/goods/2017-11/5a03fbb42a41d_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fbb42a41d_m_thumb.png differ diff --git a/upload/goods/2017-11/5a03fbb42a41d_thumb.png b/upload/goods/2017-11/5a03fbb42a41d_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a03fbb42a41d_thumb.png differ diff --git a/upload/goods/2017-11/5a03fbbf06252.jpg b/upload/goods/2017-11/5a03fbbf06252.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2017-11/5a03fbbf06252.jpg differ diff --git a/upload/goods/2017-11/5a03fbbf06252_m.jpg b/upload/goods/2017-11/5a03fbbf06252_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2017-11/5a03fbbf06252_m.jpg differ diff --git a/upload/goods/2017-11/5a03fbbf06252_m_thumb.jpg b/upload/goods/2017-11/5a03fbbf06252_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2017-11/5a03fbbf06252_m_thumb.jpg differ diff --git a/upload/goods/2017-11/5a03fbbf06252_thumb.jpg b/upload/goods/2017-11/5a03fbbf06252_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2017-11/5a03fbbf06252_thumb.jpg differ diff --git a/upload/goods/2017-11/5a0538b3ae551.png b/upload/goods/2017-11/5a0538b3ae551.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-11/5a0538b3ae551.png differ diff --git a/upload/goods/2017-11/5a0538b3ae551_m.png b/upload/goods/2017-11/5a0538b3ae551_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a0538b3ae551_m.png differ diff --git a/upload/goods/2017-11/5a0538b3ae551_m_thumb.png b/upload/goods/2017-11/5a0538b3ae551_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a0538b3ae551_m_thumb.png differ diff --git a/upload/goods/2017-11/5a0538b3ae551_thumb.png b/upload/goods/2017-11/5a0538b3ae551_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-11/5a0538b3ae551_thumb.png differ diff --git a/upload/goods/2017-11/5a0a7e2ee935c.jpg b/upload/goods/2017-11/5a0a7e2ee935c.jpg new file mode 100755 index 0000000..64a3990 Binary files /dev/null and b/upload/goods/2017-11/5a0a7e2ee935c.jpg differ diff --git a/upload/goods/2017-11/5a0a7e2ee935c_m.jpg b/upload/goods/2017-11/5a0a7e2ee935c_m.jpg new file mode 100755 index 0000000..ea59bb4 Binary files /dev/null and b/upload/goods/2017-11/5a0a7e2ee935c_m.jpg differ diff --git a/upload/goods/2017-11/5a0a7e2ee935c_m_thumb.jpg b/upload/goods/2017-11/5a0a7e2ee935c_m_thumb.jpg new file mode 100755 index 0000000..41ea60b Binary files /dev/null and b/upload/goods/2017-11/5a0a7e2ee935c_m_thumb.jpg differ diff --git a/upload/goods/2017-11/5a0a7e2ee935c_thumb.jpg b/upload/goods/2017-11/5a0a7e2ee935c_thumb.jpg new file mode 100755 index 0000000..a7707c2 Binary files /dev/null and b/upload/goods/2017-11/5a0a7e2ee935c_thumb.jpg differ diff --git a/upload/goods/2017-11/5a0a7e3970fed.jpg b/upload/goods/2017-11/5a0a7e3970fed.jpg new file mode 100755 index 0000000..0af3efe Binary files /dev/null and b/upload/goods/2017-11/5a0a7e3970fed.jpg differ diff --git a/upload/goods/2017-11/5a0a7e3970fed_m.jpg b/upload/goods/2017-11/5a0a7e3970fed_m.jpg new file mode 100755 index 0000000..7519270 Binary files /dev/null and b/upload/goods/2017-11/5a0a7e3970fed_m.jpg differ diff --git a/upload/goods/2017-11/5a0a7e3970fed_m_thumb.jpg b/upload/goods/2017-11/5a0a7e3970fed_m_thumb.jpg new file mode 100755 index 0000000..92d635d Binary files /dev/null and b/upload/goods/2017-11/5a0a7e3970fed_m_thumb.jpg differ diff --git a/upload/goods/2017-11/5a0a7e3970fed_thumb.jpg b/upload/goods/2017-11/5a0a7e3970fed_thumb.jpg new file mode 100755 index 0000000..d2368c7 Binary files /dev/null and b/upload/goods/2017-11/5a0a7e3970fed_thumb.jpg differ diff --git a/upload/goods/2017-12/5a29e44a4183e.png b/upload/goods/2017-12/5a29e44a4183e.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-12/5a29e44a4183e.png differ diff --git a/upload/goods/2017-12/5a29e44a4183e_m.png b/upload/goods/2017-12/5a29e44a4183e_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a4183e_m.png differ diff --git a/upload/goods/2017-12/5a29e44a4183e_m_thumb.png b/upload/goods/2017-12/5a29e44a4183e_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a4183e_m_thumb.png differ diff --git a/upload/goods/2017-12/5a29e44a4183e_thumb.png b/upload/goods/2017-12/5a29e44a4183e_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a4183e_thumb.png differ diff --git a/upload/goods/2017-12/5a29e44a8e8d3.jpg b/upload/goods/2017-12/5a29e44a8e8d3.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a8e8d3.jpg differ diff --git a/upload/goods/2017-12/5a29e44a8e8d3_m.jpg b/upload/goods/2017-12/5a29e44a8e8d3_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a8e8d3_m.jpg differ diff --git a/upload/goods/2017-12/5a29e44a8e8d3_m_thumb.jpg b/upload/goods/2017-12/5a29e44a8e8d3_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2017-12/5a29e44a8e8d3_m_thumb.jpg differ diff --git a/upload/goods/2017-12/5a29e44a8e8d3_thumb.jpg b/upload/goods/2017-12/5a29e44a8e8d3_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2017-12/5a29e44a8e8d3_thumb.jpg differ diff --git a/upload/goods/2017-12/5a2e36252c7c9.jpg b/upload/goods/2017-12/5a2e36252c7c9.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2017-12/5a2e36252c7c9.jpg differ diff --git a/upload/goods/2017-12/5a2e36252c7c9_m.jpg b/upload/goods/2017-12/5a2e36252c7c9_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2017-12/5a2e36252c7c9_m.jpg differ diff --git a/upload/goods/2017-12/5a2e36252c7c9_m_thumb.jpg b/upload/goods/2017-12/5a2e36252c7c9_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2017-12/5a2e36252c7c9_m_thumb.jpg differ diff --git a/upload/goods/2017-12/5a2e36252c7c9_thumb.jpg b/upload/goods/2017-12/5a2e36252c7c9_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2017-12/5a2e36252c7c9_thumb.jpg differ diff --git a/upload/goods/2017-12/5a3b643162c45.png b/upload/goods/2017-12/5a3b643162c45.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2017-12/5a3b643162c45.png differ diff --git a/upload/goods/2017-12/5a3b643162c45_m.png b/upload/goods/2017-12/5a3b643162c45_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a3b643162c45_m.png differ diff --git a/upload/goods/2017-12/5a3b643162c45_m_thumb.png b/upload/goods/2017-12/5a3b643162c45_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a3b643162c45_m_thumb.png differ diff --git a/upload/goods/2017-12/5a3b643162c45_thumb.png b/upload/goods/2017-12/5a3b643162c45_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2017-12/5a3b643162c45_thumb.png differ diff --git a/upload/goods/2018-01/5a62f40fe8240.jpg b/upload/goods/2018-01/5a62f40fe8240.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/goods/2018-01/5a62f40fe8240.jpg differ diff --git a/upload/goods/2018-01/5a62f40fe8240_m.jpg b/upload/goods/2018-01/5a62f40fe8240_m.jpg new file mode 100755 index 0000000..9ce1d30 Binary files /dev/null and b/upload/goods/2018-01/5a62f40fe8240_m.jpg differ diff --git a/upload/goods/2018-01/5a62f40fe8240_m_thumb.jpg b/upload/goods/2018-01/5a62f40fe8240_m_thumb.jpg new file mode 100755 index 0000000..18ac9ee Binary files /dev/null and b/upload/goods/2018-01/5a62f40fe8240_m_thumb.jpg differ diff --git a/upload/goods/2018-01/5a62f40fe8240_thumb.jpg b/upload/goods/2018-01/5a62f40fe8240_thumb.jpg new file mode 100755 index 0000000..903078b Binary files /dev/null and b/upload/goods/2018-01/5a62f40fe8240_thumb.jpg differ diff --git a/upload/goods/2018-01/5a62f4168b75b.png b/upload/goods/2018-01/5a62f4168b75b.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-01/5a62f4168b75b.png differ diff --git a/upload/goods/2018-01/5a62f4168b75b_m.png b/upload/goods/2018-01/5a62f4168b75b_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-01/5a62f4168b75b_m.png differ diff --git a/upload/goods/2018-01/5a62f4168b75b_m_thumb.png b/upload/goods/2018-01/5a62f4168b75b_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-01/5a62f4168b75b_m_thumb.png differ diff --git a/upload/goods/2018-01/5a62f4168b75b_thumb.png b/upload/goods/2018-01/5a62f4168b75b_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-01/5a62f4168b75b_thumb.png differ diff --git a/upload/goods/2018-01/5a6807dbd3208.jpg b/upload/goods/2018-01/5a6807dbd3208.jpg new file mode 100755 index 0000000..a06ffae Binary files /dev/null and b/upload/goods/2018-01/5a6807dbd3208.jpg differ diff --git a/upload/goods/2018-01/5a6807dbd3208_m.jpg b/upload/goods/2018-01/5a6807dbd3208_m.jpg new file mode 100755 index 0000000..9a7d7f1 Binary files /dev/null and b/upload/goods/2018-01/5a6807dbd3208_m.jpg differ diff --git a/upload/goods/2018-01/5a6807dbd3208_m_thumb.jpg b/upload/goods/2018-01/5a6807dbd3208_m_thumb.jpg new file mode 100755 index 0000000..a0d2d8b Binary files /dev/null and b/upload/goods/2018-01/5a6807dbd3208_m_thumb.jpg differ diff --git a/upload/goods/2018-01/5a6807dbd3208_thumb.jpg b/upload/goods/2018-01/5a6807dbd3208_thumb.jpg new file mode 100755 index 0000000..be6fa44 Binary files /dev/null and b/upload/goods/2018-01/5a6807dbd3208_thumb.jpg differ diff --git a/upload/goods/2018-01/5a68080e45024.png b/upload/goods/2018-01/5a68080e45024.png new file mode 100755 index 0000000..8ea2f88 Binary files /dev/null and b/upload/goods/2018-01/5a68080e45024.png differ diff --git a/upload/goods/2018-01/5a68080e45024_m.png b/upload/goods/2018-01/5a68080e45024_m.png new file mode 100755 index 0000000..9b13908 Binary files /dev/null and b/upload/goods/2018-01/5a68080e45024_m.png differ diff --git a/upload/goods/2018-01/5a68080e45024_m_thumb.png b/upload/goods/2018-01/5a68080e45024_m_thumb.png new file mode 100755 index 0000000..511e47c Binary files /dev/null and b/upload/goods/2018-01/5a68080e45024_m_thumb.png differ diff --git a/upload/goods/2018-01/5a68080e45024_thumb.png b/upload/goods/2018-01/5a68080e45024_thumb.png new file mode 100755 index 0000000..8a13a38 Binary files /dev/null and b/upload/goods/2018-01/5a68080e45024_thumb.png differ diff --git a/upload/goods/2018-02/5a93a5cf4626a.jpg b/upload/goods/2018-02/5a93a5cf4626a.jpg new file mode 100755 index 0000000..53d90ce Binary files /dev/null and b/upload/goods/2018-02/5a93a5cf4626a.jpg differ diff --git a/upload/goods/2018-02/5a93a5cf4626a_m.jpg b/upload/goods/2018-02/5a93a5cf4626a_m.jpg new file mode 100755 index 0000000..580e74c Binary files /dev/null and b/upload/goods/2018-02/5a93a5cf4626a_m.jpg differ diff --git a/upload/goods/2018-02/5a93a5cf4626a_m_thumb.jpg b/upload/goods/2018-02/5a93a5cf4626a_m_thumb.jpg new file mode 100755 index 0000000..732302a Binary files /dev/null and b/upload/goods/2018-02/5a93a5cf4626a_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a93a5cf4626a_thumb.jpg b/upload/goods/2018-02/5a93a5cf4626a_thumb.jpg new file mode 100755 index 0000000..a28bc62 Binary files /dev/null and b/upload/goods/2018-02/5a93a5cf4626a_thumb.jpg differ diff --git a/upload/goods/2018-02/5a93ae38b0e1c.jpg b/upload/goods/2018-02/5a93ae38b0e1c.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/goods/2018-02/5a93ae38b0e1c.jpg differ diff --git a/upload/goods/2018-02/5a93ae38b0e1c_m.jpg b/upload/goods/2018-02/5a93ae38b0e1c_m.jpg new file mode 100755 index 0000000..9ce1d30 Binary files /dev/null and b/upload/goods/2018-02/5a93ae38b0e1c_m.jpg differ diff --git a/upload/goods/2018-02/5a93ae38b0e1c_m_thumb.jpg b/upload/goods/2018-02/5a93ae38b0e1c_m_thumb.jpg new file mode 100755 index 0000000..18ac9ee Binary files /dev/null and b/upload/goods/2018-02/5a93ae38b0e1c_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a93ae38b0e1c_thumb.jpg b/upload/goods/2018-02/5a93ae38b0e1c_thumb.jpg new file mode 100755 index 0000000..903078b Binary files /dev/null and b/upload/goods/2018-02/5a93ae38b0e1c_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a441deeca.jpg b/upload/goods/2018-02/5a94a441deeca.jpg new file mode 100755 index 0000000..1f7adab Binary files /dev/null and b/upload/goods/2018-02/5a94a441deeca.jpg differ diff --git a/upload/goods/2018-02/5a94a441deeca_m.jpg b/upload/goods/2018-02/5a94a441deeca_m.jpg new file mode 100755 index 0000000..e2965cc Binary files /dev/null and b/upload/goods/2018-02/5a94a441deeca_m.jpg differ diff --git a/upload/goods/2018-02/5a94a441deeca_m_thumb.jpg b/upload/goods/2018-02/5a94a441deeca_m_thumb.jpg new file mode 100755 index 0000000..70760f6 Binary files /dev/null and b/upload/goods/2018-02/5a94a441deeca_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a441deeca_thumb.jpg b/upload/goods/2018-02/5a94a441deeca_thumb.jpg new file mode 100755 index 0000000..2a1fa6a Binary files /dev/null and b/upload/goods/2018-02/5a94a441deeca_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a44f87396.jpg b/upload/goods/2018-02/5a94a44f87396.jpg new file mode 100755 index 0000000..caa4064 Binary files /dev/null and b/upload/goods/2018-02/5a94a44f87396.jpg differ diff --git a/upload/goods/2018-02/5a94a44f87396_m.jpg b/upload/goods/2018-02/5a94a44f87396_m.jpg new file mode 100755 index 0000000..aae3487 Binary files /dev/null and b/upload/goods/2018-02/5a94a44f87396_m.jpg differ diff --git a/upload/goods/2018-02/5a94a44f87396_m_thumb.jpg b/upload/goods/2018-02/5a94a44f87396_m_thumb.jpg new file mode 100755 index 0000000..9cb1453 Binary files /dev/null and b/upload/goods/2018-02/5a94a44f87396_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a44f87396_thumb.jpg b/upload/goods/2018-02/5a94a44f87396_thumb.jpg new file mode 100755 index 0000000..6083bcd Binary files /dev/null and b/upload/goods/2018-02/5a94a44f87396_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a4ee9df42.jpg b/upload/goods/2018-02/5a94a4ee9df42.jpg new file mode 100755 index 0000000..1f7adab Binary files /dev/null and b/upload/goods/2018-02/5a94a4ee9df42.jpg differ diff --git a/upload/goods/2018-02/5a94a4ee9df42_m.jpg b/upload/goods/2018-02/5a94a4ee9df42_m.jpg new file mode 100755 index 0000000..e2965cc Binary files /dev/null and b/upload/goods/2018-02/5a94a4ee9df42_m.jpg differ diff --git a/upload/goods/2018-02/5a94a4ee9df42_m_thumb.jpg b/upload/goods/2018-02/5a94a4ee9df42_m_thumb.jpg new file mode 100755 index 0000000..70760f6 Binary files /dev/null and b/upload/goods/2018-02/5a94a4ee9df42_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94a4ee9df42_thumb.jpg b/upload/goods/2018-02/5a94a4ee9df42_thumb.jpg new file mode 100755 index 0000000..2a1fa6a Binary files /dev/null and b/upload/goods/2018-02/5a94a4ee9df42_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94acf237fca.jpg b/upload/goods/2018-02/5a94acf237fca.jpg new file mode 100755 index 0000000..caa4064 Binary files /dev/null and b/upload/goods/2018-02/5a94acf237fca.jpg differ diff --git a/upload/goods/2018-02/5a94acf237fca_m.jpg b/upload/goods/2018-02/5a94acf237fca_m.jpg new file mode 100755 index 0000000..aae3487 Binary files /dev/null and b/upload/goods/2018-02/5a94acf237fca_m.jpg differ diff --git a/upload/goods/2018-02/5a94acf237fca_m_thumb.jpg b/upload/goods/2018-02/5a94acf237fca_m_thumb.jpg new file mode 100755 index 0000000..9cb1453 Binary files /dev/null and b/upload/goods/2018-02/5a94acf237fca_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94acf237fca_thumb.jpg b/upload/goods/2018-02/5a94acf237fca_thumb.jpg new file mode 100755 index 0000000..6083bcd Binary files /dev/null and b/upload/goods/2018-02/5a94acf237fca_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94acf991b07.jpg b/upload/goods/2018-02/5a94acf991b07.jpg new file mode 100755 index 0000000..1f7adab Binary files /dev/null and b/upload/goods/2018-02/5a94acf991b07.jpg differ diff --git a/upload/goods/2018-02/5a94acf991b07_m.jpg b/upload/goods/2018-02/5a94acf991b07_m.jpg new file mode 100755 index 0000000..e2965cc Binary files /dev/null and b/upload/goods/2018-02/5a94acf991b07_m.jpg differ diff --git a/upload/goods/2018-02/5a94acf991b07_m_thumb.jpg b/upload/goods/2018-02/5a94acf991b07_m_thumb.jpg new file mode 100755 index 0000000..70760f6 Binary files /dev/null and b/upload/goods/2018-02/5a94acf991b07_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94acf991b07_thumb.jpg b/upload/goods/2018-02/5a94acf991b07_thumb.jpg new file mode 100755 index 0000000..2a1fa6a Binary files /dev/null and b/upload/goods/2018-02/5a94acf991b07_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ad1319eda.jpg b/upload/goods/2018-02/5a94ad1319eda.jpg new file mode 100755 index 0000000..caa4064 Binary files /dev/null and b/upload/goods/2018-02/5a94ad1319eda.jpg differ diff --git a/upload/goods/2018-02/5a94ad1319eda_m.jpg b/upload/goods/2018-02/5a94ad1319eda_m.jpg new file mode 100755 index 0000000..aae3487 Binary files /dev/null and b/upload/goods/2018-02/5a94ad1319eda_m.jpg differ diff --git a/upload/goods/2018-02/5a94ad1319eda_m_thumb.jpg b/upload/goods/2018-02/5a94ad1319eda_m_thumb.jpg new file mode 100755 index 0000000..9cb1453 Binary files /dev/null and b/upload/goods/2018-02/5a94ad1319eda_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ad1319eda_thumb.jpg b/upload/goods/2018-02/5a94ad1319eda_thumb.jpg new file mode 100755 index 0000000..6083bcd Binary files /dev/null and b/upload/goods/2018-02/5a94ad1319eda_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94b4d02a5c9.png b/upload/goods/2018-02/5a94b4d02a5c9.png new file mode 100755 index 0000000..d60b9ea Binary files /dev/null and b/upload/goods/2018-02/5a94b4d02a5c9.png differ diff --git a/upload/goods/2018-02/5a94b4d02a5c9_m.png b/upload/goods/2018-02/5a94b4d02a5c9_m.png new file mode 100755 index 0000000..3f8706e Binary files /dev/null and b/upload/goods/2018-02/5a94b4d02a5c9_m.png differ diff --git a/upload/goods/2018-02/5a94b4d02a5c9_m_thumb.png b/upload/goods/2018-02/5a94b4d02a5c9_m_thumb.png new file mode 100755 index 0000000..3f79b88 Binary files /dev/null and b/upload/goods/2018-02/5a94b4d02a5c9_m_thumb.png differ diff --git a/upload/goods/2018-02/5a94b4d02a5c9_thumb.png b/upload/goods/2018-02/5a94b4d02a5c9_thumb.png new file mode 100755 index 0000000..9612a0c Binary files /dev/null and b/upload/goods/2018-02/5a94b4d02a5c9_thumb.png differ diff --git a/upload/goods/2018-02/5a94b4d6d80a0.jpg b/upload/goods/2018-02/5a94b4d6d80a0.jpg new file mode 100755 index 0000000..18629d2 Binary files /dev/null and b/upload/goods/2018-02/5a94b4d6d80a0.jpg differ diff --git a/upload/goods/2018-02/5a94b4d6d80a0_m.jpg b/upload/goods/2018-02/5a94b4d6d80a0_m.jpg new file mode 100755 index 0000000..87c7a24 Binary files /dev/null and b/upload/goods/2018-02/5a94b4d6d80a0_m.jpg differ diff --git a/upload/goods/2018-02/5a94b4d6d80a0_m_thumb.jpg b/upload/goods/2018-02/5a94b4d6d80a0_m_thumb.jpg new file mode 100755 index 0000000..c0ec193 Binary files /dev/null and b/upload/goods/2018-02/5a94b4d6d80a0_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94b4d6d80a0_thumb.jpg b/upload/goods/2018-02/5a94b4d6d80a0_thumb.jpg new file mode 100755 index 0000000..2383e2a Binary files /dev/null and b/upload/goods/2018-02/5a94b4d6d80a0_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94cbbd30e0a.png b/upload/goods/2018-02/5a94cbbd30e0a.png new file mode 100755 index 0000000..d60b9ea Binary files /dev/null and b/upload/goods/2018-02/5a94cbbd30e0a.png differ diff --git a/upload/goods/2018-02/5a94cc8290e54.png b/upload/goods/2018-02/5a94cc8290e54.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-02/5a94cc8290e54.png differ diff --git a/upload/goods/2018-02/5a94cca554588.png b/upload/goods/2018-02/5a94cca554588.png new file mode 100755 index 0000000..d60b9ea Binary files /dev/null and b/upload/goods/2018-02/5a94cca554588.png differ diff --git a/upload/goods/2018-02/5a94ccb881891.jpg b/upload/goods/2018-02/5a94ccb881891.jpg new file mode 100755 index 0000000..18629d2 Binary files /dev/null and b/upload/goods/2018-02/5a94ccb881891.jpg differ diff --git a/upload/goods/2018-02/5a94ccb881891_m.jpg b/upload/goods/2018-02/5a94ccb881891_m.jpg new file mode 100755 index 0000000..87c7a24 Binary files /dev/null and b/upload/goods/2018-02/5a94ccb881891_m.jpg differ diff --git a/upload/goods/2018-02/5a94ccb881891_m_thumb.jpg b/upload/goods/2018-02/5a94ccb881891_m_thumb.jpg new file mode 100755 index 0000000..c0ec193 Binary files /dev/null and b/upload/goods/2018-02/5a94ccb881891_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ccb881891_thumb.jpg b/upload/goods/2018-02/5a94ccb881891_thumb.jpg new file mode 100755 index 0000000..2383e2a Binary files /dev/null and b/upload/goods/2018-02/5a94ccb881891_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94cccb551ed.png b/upload/goods/2018-02/5a94cccb551ed.png new file mode 100755 index 0000000..d60b9ea Binary files /dev/null and b/upload/goods/2018-02/5a94cccb551ed.png differ diff --git a/upload/goods/2018-02/5a94cccb551ed_m.png b/upload/goods/2018-02/5a94cccb551ed_m.png new file mode 100755 index 0000000..3f8706e Binary files /dev/null and b/upload/goods/2018-02/5a94cccb551ed_m.png differ diff --git a/upload/goods/2018-02/5a94cccb551ed_m_thumb.png b/upload/goods/2018-02/5a94cccb551ed_m_thumb.png new file mode 100755 index 0000000..3f79b88 Binary files /dev/null and b/upload/goods/2018-02/5a94cccb551ed_m_thumb.png differ diff --git a/upload/goods/2018-02/5a94cccb551ed_thumb.png b/upload/goods/2018-02/5a94cccb551ed_thumb.png new file mode 100755 index 0000000..9612a0c Binary files /dev/null and b/upload/goods/2018-02/5a94cccb551ed_thumb.png differ diff --git a/upload/goods/2018-02/5a94ccfbe3280.png b/upload/goods/2018-02/5a94ccfbe3280.png new file mode 100755 index 0000000..653302a Binary files /dev/null and b/upload/goods/2018-02/5a94ccfbe3280.png differ diff --git a/upload/goods/2018-02/5a94ccfbe3280_m.png b/upload/goods/2018-02/5a94ccfbe3280_m.png new file mode 100755 index 0000000..c0b2473 Binary files /dev/null and b/upload/goods/2018-02/5a94ccfbe3280_m.png differ diff --git a/upload/goods/2018-02/5a94ccfbe3280_m_thumb.png b/upload/goods/2018-02/5a94ccfbe3280_m_thumb.png new file mode 100755 index 0000000..d6a934b Binary files /dev/null and b/upload/goods/2018-02/5a94ccfbe3280_m_thumb.png differ diff --git a/upload/goods/2018-02/5a94ccfbe3280_thumb.png b/upload/goods/2018-02/5a94ccfbe3280_thumb.png new file mode 100755 index 0000000..0f6ecd0 Binary files /dev/null and b/upload/goods/2018-02/5a94ccfbe3280_thumb.png differ diff --git a/upload/goods/2018-02/5a94cdca5e0d9.jpg b/upload/goods/2018-02/5a94cdca5e0d9.jpg new file mode 100755 index 0000000..18629d2 Binary files /dev/null and b/upload/goods/2018-02/5a94cdca5e0d9.jpg differ diff --git a/upload/goods/2018-02/5a94cdeccf53c.jpg b/upload/goods/2018-02/5a94cdeccf53c.jpg new file mode 100755 index 0000000..fd4cc44 Binary files /dev/null and b/upload/goods/2018-02/5a94cdeccf53c.jpg differ diff --git a/upload/goods/2018-02/5a94cdeccf53c_m.jpg b/upload/goods/2018-02/5a94cdeccf53c_m.jpg new file mode 100755 index 0000000..1d8b593 Binary files /dev/null and b/upload/goods/2018-02/5a94cdeccf53c_m.jpg differ diff --git a/upload/goods/2018-02/5a94cdeccf53c_m_thumb.jpg b/upload/goods/2018-02/5a94cdeccf53c_m_thumb.jpg new file mode 100755 index 0000000..28c1caf Binary files /dev/null and b/upload/goods/2018-02/5a94cdeccf53c_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94cdeccf53c_thumb.jpg b/upload/goods/2018-02/5a94cdeccf53c_thumb.jpg new file mode 100755 index 0000000..ac7d77f Binary files /dev/null and b/upload/goods/2018-02/5a94cdeccf53c_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ce053cb1f.jpg b/upload/goods/2018-02/5a94ce053cb1f.jpg new file mode 100755 index 0000000..18629d2 Binary files /dev/null and b/upload/goods/2018-02/5a94ce053cb1f.jpg differ diff --git a/upload/goods/2018-02/5a94ce053cb1f_m.jpg b/upload/goods/2018-02/5a94ce053cb1f_m.jpg new file mode 100755 index 0000000..87c7a24 Binary files /dev/null and b/upload/goods/2018-02/5a94ce053cb1f_m.jpg differ diff --git a/upload/goods/2018-02/5a94ce053cb1f_m_thumb.jpg b/upload/goods/2018-02/5a94ce053cb1f_m_thumb.jpg new file mode 100755 index 0000000..c0ec193 Binary files /dev/null and b/upload/goods/2018-02/5a94ce053cb1f_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ce053cb1f_thumb.jpg b/upload/goods/2018-02/5a94ce053cb1f_thumb.jpg new file mode 100755 index 0000000..2383e2a Binary files /dev/null and b/upload/goods/2018-02/5a94ce053cb1f_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ce1b4fcd6.jpg b/upload/goods/2018-02/5a94ce1b4fcd6.jpg new file mode 100755 index 0000000..18629d2 Binary files /dev/null and b/upload/goods/2018-02/5a94ce1b4fcd6.jpg differ diff --git a/upload/goods/2018-02/5a94ce1b4fcd6_m.jpg b/upload/goods/2018-02/5a94ce1b4fcd6_m.jpg new file mode 100755 index 0000000..87c7a24 Binary files /dev/null and b/upload/goods/2018-02/5a94ce1b4fcd6_m.jpg differ diff --git a/upload/goods/2018-02/5a94ce1b4fcd6_m_thumb.jpg b/upload/goods/2018-02/5a94ce1b4fcd6_m_thumb.jpg new file mode 100755 index 0000000..c0ec193 Binary files /dev/null and b/upload/goods/2018-02/5a94ce1b4fcd6_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94ce1b4fcd6_thumb.jpg b/upload/goods/2018-02/5a94ce1b4fcd6_thumb.jpg new file mode 100755 index 0000000..2383e2a Binary files /dev/null and b/upload/goods/2018-02/5a94ce1b4fcd6_thumb.jpg differ diff --git a/upload/goods/2018-02/5a94d1c10bc94.jpg b/upload/goods/2018-02/5a94d1c10bc94.jpg new file mode 100755 index 0000000..fd4cc44 Binary files /dev/null and b/upload/goods/2018-02/5a94d1c10bc94.jpg differ diff --git a/upload/goods/2018-02/5a95114b244a4.jpeg b/upload/goods/2018-02/5a95114b244a4.jpeg new file mode 100755 index 0000000..d24941f Binary files /dev/null and b/upload/goods/2018-02/5a95114b244a4.jpeg differ diff --git a/upload/goods/2018-02/5a95114b244a4_m.jpeg b/upload/goods/2018-02/5a95114b244a4_m.jpeg new file mode 100755 index 0000000..c726e96 Binary files /dev/null and b/upload/goods/2018-02/5a95114b244a4_m.jpeg differ diff --git a/upload/goods/2018-02/5a95114b244a4_m_thumb.jpeg b/upload/goods/2018-02/5a95114b244a4_m_thumb.jpeg new file mode 100755 index 0000000..a8215be Binary files /dev/null and b/upload/goods/2018-02/5a95114b244a4_m_thumb.jpeg differ diff --git a/upload/goods/2018-02/5a95114b244a4_thumb.jpeg b/upload/goods/2018-02/5a95114b244a4_thumb.jpeg new file mode 100755 index 0000000..e9f23ff Binary files /dev/null and b/upload/goods/2018-02/5a95114b244a4_thumb.jpeg differ diff --git a/upload/goods/2018-02/5a951166afd5d.jpg b/upload/goods/2018-02/5a951166afd5d.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/goods/2018-02/5a951166afd5d.jpg differ diff --git a/upload/goods/2018-02/5a951166afd5d_m.jpg b/upload/goods/2018-02/5a951166afd5d_m.jpg new file mode 100755 index 0000000..9ce1d30 Binary files /dev/null and b/upload/goods/2018-02/5a951166afd5d_m.jpg differ diff --git a/upload/goods/2018-02/5a951166afd5d_m_thumb.jpg b/upload/goods/2018-02/5a951166afd5d_m_thumb.jpg new file mode 100755 index 0000000..18ac9ee Binary files /dev/null and b/upload/goods/2018-02/5a951166afd5d_m_thumb.jpg differ diff --git a/upload/goods/2018-02/5a951166afd5d_thumb.jpg b/upload/goods/2018-02/5a951166afd5d_thumb.jpg new file mode 100755 index 0000000..903078b Binary files /dev/null and b/upload/goods/2018-02/5a951166afd5d_thumb.jpg differ diff --git a/upload/goods/2018-02/5a96205b0d99c.png b/upload/goods/2018-02/5a96205b0d99c.png new file mode 100755 index 0000000..ad58a14 Binary files /dev/null and b/upload/goods/2018-02/5a96205b0d99c.png differ diff --git a/upload/goods/2018-02/5a96205b0d99c_m.png b/upload/goods/2018-02/5a96205b0d99c_m.png new file mode 100755 index 0000000..247cf27 Binary files /dev/null and b/upload/goods/2018-02/5a96205b0d99c_m.png differ diff --git a/upload/goods/2018-02/5a96205b0d99c_m_thumb.png b/upload/goods/2018-02/5a96205b0d99c_m_thumb.png new file mode 100755 index 0000000..e82f8db Binary files /dev/null and b/upload/goods/2018-02/5a96205b0d99c_m_thumb.png differ diff --git a/upload/goods/2018-02/5a96205b0d99c_thumb.png b/upload/goods/2018-02/5a96205b0d99c_thumb.png new file mode 100755 index 0000000..3b95df7 Binary files /dev/null and b/upload/goods/2018-02/5a96205b0d99c_thumb.png differ diff --git a/upload/goods/2018-02/5a96206ddf94a.png b/upload/goods/2018-02/5a96206ddf94a.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-02/5a96206ddf94a.png differ diff --git a/upload/goods/2018-02/5a96206ddf94a_m.png b/upload/goods/2018-02/5a96206ddf94a_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a96206ddf94a_m.png differ diff --git a/upload/goods/2018-02/5a96206ddf94a_m_thumb.png b/upload/goods/2018-02/5a96206ddf94a_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a96206ddf94a_m_thumb.png differ diff --git a/upload/goods/2018-02/5a96206ddf94a_thumb.png b/upload/goods/2018-02/5a96206ddf94a_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a96206ddf94a_thumb.png differ diff --git a/upload/goods/2018-02/5a9620e314620.png b/upload/goods/2018-02/5a9620e314620.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-02/5a9620e314620.png differ diff --git a/upload/goods/2018-02/5a9620e314620_m.png b/upload/goods/2018-02/5a9620e314620_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a9620e314620_m.png differ diff --git a/upload/goods/2018-02/5a9620e314620_m_thumb.png b/upload/goods/2018-02/5a9620e314620_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a9620e314620_m_thumb.png differ diff --git a/upload/goods/2018-02/5a9620e314620_thumb.png b/upload/goods/2018-02/5a9620e314620_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-02/5a9620e314620_thumb.png differ diff --git a/upload/goods/2018-02/5a9643621f26b.png b/upload/goods/2018-02/5a9643621f26b.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/goods/2018-02/5a9643621f26b.png differ diff --git a/upload/goods/2018-02/5a9643621f26b_m.png b/upload/goods/2018-02/5a9643621f26b_m.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-02/5a9643621f26b_m.png differ diff --git a/upload/goods/2018-02/5a9643621f26b_m_thumb.png b/upload/goods/2018-02/5a9643621f26b_m_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-02/5a9643621f26b_m_thumb.png differ diff --git a/upload/goods/2018-02/5a9643621f26b_thumb.png b/upload/goods/2018-02/5a9643621f26b_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-02/5a9643621f26b_thumb.png differ diff --git a/upload/goods/2018-03/5a9755ca72ff1.png b/upload/goods/2018-03/5a9755ca72ff1.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-03/5a9755ca72ff1.png differ diff --git a/upload/goods/2018-03/5a9755ca72ff1_m.png b/upload/goods/2018-03/5a9755ca72ff1_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9755ca72ff1_m.png differ diff --git a/upload/goods/2018-03/5a9755ca72ff1_m_thumb.png b/upload/goods/2018-03/5a9755ca72ff1_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9755ca72ff1_m_thumb.png differ diff --git a/upload/goods/2018-03/5a9755ca72ff1_thumb.png b/upload/goods/2018-03/5a9755ca72ff1_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9755ca72ff1_thumb.png differ diff --git a/upload/goods/2018-03/5a975683063ed.jpg b/upload/goods/2018-03/5a975683063ed.jpg new file mode 100755 index 0000000..29a1828 Binary files /dev/null and b/upload/goods/2018-03/5a975683063ed.jpg differ diff --git a/upload/goods/2018-03/5a975683063ed_m.jpg b/upload/goods/2018-03/5a975683063ed_m.jpg new file mode 100755 index 0000000..8d19732 Binary files /dev/null and b/upload/goods/2018-03/5a975683063ed_m.jpg differ diff --git a/upload/goods/2018-03/5a975683063ed_m_thumb.jpg b/upload/goods/2018-03/5a975683063ed_m_thumb.jpg new file mode 100755 index 0000000..0b5d9a5 Binary files /dev/null and b/upload/goods/2018-03/5a975683063ed_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a975683063ed_thumb.jpg b/upload/goods/2018-03/5a975683063ed_thumb.jpg new file mode 100755 index 0000000..d7d0f50 Binary files /dev/null and b/upload/goods/2018-03/5a975683063ed_thumb.jpg differ diff --git a/upload/goods/2018-03/5a97576844875.png b/upload/goods/2018-03/5a97576844875.png new file mode 100755 index 0000000..154650b Binary files /dev/null and b/upload/goods/2018-03/5a97576844875.png differ diff --git a/upload/goods/2018-03/5a97576844875_m.png b/upload/goods/2018-03/5a97576844875_m.png new file mode 100755 index 0000000..0246068 Binary files /dev/null and b/upload/goods/2018-03/5a97576844875_m.png differ diff --git a/upload/goods/2018-03/5a97576844875_m_thumb.png b/upload/goods/2018-03/5a97576844875_m_thumb.png new file mode 100755 index 0000000..9849c6a Binary files /dev/null and b/upload/goods/2018-03/5a97576844875_m_thumb.png differ diff --git a/upload/goods/2018-03/5a97576844875_thumb.png b/upload/goods/2018-03/5a97576844875_thumb.png new file mode 100755 index 0000000..68caaea Binary files /dev/null and b/upload/goods/2018-03/5a97576844875_thumb.png differ diff --git a/upload/goods/2018-03/5a975bb86835f.png b/upload/goods/2018-03/5a975bb86835f.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-03/5a975bb86835f.png differ diff --git a/upload/goods/2018-03/5a975bb86835f_m.png b/upload/goods/2018-03/5a975bb86835f_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a975bb86835f_m.png differ diff --git a/upload/goods/2018-03/5a975bb86835f_m_thumb.png b/upload/goods/2018-03/5a975bb86835f_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a975bb86835f_m_thumb.png differ diff --git a/upload/goods/2018-03/5a975bb86835f_thumb.png b/upload/goods/2018-03/5a975bb86835f_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a975bb86835f_thumb.png differ diff --git a/upload/goods/2018-03/5a9760acc368a.jpg b/upload/goods/2018-03/5a9760acc368a.jpg new file mode 100755 index 0000000..29a1828 Binary files /dev/null and b/upload/goods/2018-03/5a9760acc368a.jpg differ diff --git a/upload/goods/2018-03/5a9760acc368a_m.jpg b/upload/goods/2018-03/5a9760acc368a_m.jpg new file mode 100755 index 0000000..8d19732 Binary files /dev/null and b/upload/goods/2018-03/5a9760acc368a_m.jpg differ diff --git a/upload/goods/2018-03/5a9760acc368a_m_thumb.jpg b/upload/goods/2018-03/5a9760acc368a_m_thumb.jpg new file mode 100755 index 0000000..0b5d9a5 Binary files /dev/null and b/upload/goods/2018-03/5a9760acc368a_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9760acc368a_thumb.jpg b/upload/goods/2018-03/5a9760acc368a_thumb.jpg new file mode 100755 index 0000000..d7d0f50 Binary files /dev/null and b/upload/goods/2018-03/5a9760acc368a_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9760cf22ffe.jpg b/upload/goods/2018-03/5a9760cf22ffe.jpg new file mode 100755 index 0000000..6be9ba7 Binary files /dev/null and b/upload/goods/2018-03/5a9760cf22ffe.jpg differ diff --git a/upload/goods/2018-03/5a9760cf22ffe_m.jpg b/upload/goods/2018-03/5a9760cf22ffe_m.jpg new file mode 100755 index 0000000..009b987 Binary files /dev/null and b/upload/goods/2018-03/5a9760cf22ffe_m.jpg differ diff --git a/upload/goods/2018-03/5a9760cf22ffe_m_thumb.jpg b/upload/goods/2018-03/5a9760cf22ffe_m_thumb.jpg new file mode 100755 index 0000000..7ead3f5 Binary files /dev/null and b/upload/goods/2018-03/5a9760cf22ffe_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9760cf22ffe_thumb.jpg b/upload/goods/2018-03/5a9760cf22ffe_thumb.jpg new file mode 100755 index 0000000..61bb7b9 Binary files /dev/null and b/upload/goods/2018-03/5a9760cf22ffe_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9760ed2f235.jpg b/upload/goods/2018-03/5a9760ed2f235.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2018-03/5a9760ed2f235.jpg differ diff --git a/upload/goods/2018-03/5a9760ed2f235_m.jpg b/upload/goods/2018-03/5a9760ed2f235_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2018-03/5a9760ed2f235_m.jpg differ diff --git a/upload/goods/2018-03/5a9760ed2f235_m_thumb.jpg b/upload/goods/2018-03/5a9760ed2f235_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2018-03/5a9760ed2f235_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9760ed2f235_thumb.jpg b/upload/goods/2018-03/5a9760ed2f235_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2018-03/5a9760ed2f235_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9761481b695.jpg b/upload/goods/2018-03/5a9761481b695.jpg new file mode 100755 index 0000000..6be9ba7 Binary files /dev/null and b/upload/goods/2018-03/5a9761481b695.jpg differ diff --git a/upload/goods/2018-03/5a9761481b695_m.jpg b/upload/goods/2018-03/5a9761481b695_m.jpg new file mode 100755 index 0000000..009b987 Binary files /dev/null and b/upload/goods/2018-03/5a9761481b695_m.jpg differ diff --git a/upload/goods/2018-03/5a9761481b695_m_thumb.jpg b/upload/goods/2018-03/5a9761481b695_m_thumb.jpg new file mode 100755 index 0000000..7ead3f5 Binary files /dev/null and b/upload/goods/2018-03/5a9761481b695_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9761481b695_thumb.jpg b/upload/goods/2018-03/5a9761481b695_thumb.jpg new file mode 100755 index 0000000..61bb7b9 Binary files /dev/null and b/upload/goods/2018-03/5a9761481b695_thumb.jpg differ diff --git a/upload/goods/2018-03/5a97614d8fb2e.jpg b/upload/goods/2018-03/5a97614d8fb2e.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2018-03/5a97614d8fb2e.jpg differ diff --git a/upload/goods/2018-03/5a97614d8fb2e_m.jpg b/upload/goods/2018-03/5a97614d8fb2e_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2018-03/5a97614d8fb2e_m.jpg differ diff --git a/upload/goods/2018-03/5a97614d8fb2e_m_thumb.jpg b/upload/goods/2018-03/5a97614d8fb2e_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2018-03/5a97614d8fb2e_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a97614d8fb2e_thumb.jpg b/upload/goods/2018-03/5a97614d8fb2e_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2018-03/5a97614d8fb2e_thumb.jpg differ diff --git a/upload/goods/2018-03/5a97618a99572.png b/upload/goods/2018-03/5a97618a99572.png new file mode 100755 index 0000000..154650b Binary files /dev/null and b/upload/goods/2018-03/5a97618a99572.png differ diff --git a/upload/goods/2018-03/5a97618a99572_m.png b/upload/goods/2018-03/5a97618a99572_m.png new file mode 100755 index 0000000..0246068 Binary files /dev/null and b/upload/goods/2018-03/5a97618a99572_m.png differ diff --git a/upload/goods/2018-03/5a97618a99572_m_thumb.png b/upload/goods/2018-03/5a97618a99572_m_thumb.png new file mode 100755 index 0000000..9849c6a Binary files /dev/null and b/upload/goods/2018-03/5a97618a99572_m_thumb.png differ diff --git a/upload/goods/2018-03/5a97618a99572_thumb.png b/upload/goods/2018-03/5a97618a99572_thumb.png new file mode 100755 index 0000000..68caaea Binary files /dev/null and b/upload/goods/2018-03/5a97618a99572_thumb.png differ diff --git a/upload/goods/2018-03/5a9764cd7004f.jpg b/upload/goods/2018-03/5a9764cd7004f.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/goods/2018-03/5a9764cd7004f.jpg differ diff --git a/upload/goods/2018-03/5a9764cd7004f_m.jpg b/upload/goods/2018-03/5a9764cd7004f_m.jpg new file mode 100755 index 0000000..2e67e38 Binary files /dev/null and b/upload/goods/2018-03/5a9764cd7004f_m.jpg differ diff --git a/upload/goods/2018-03/5a9764cd7004f_m_thumb.jpg b/upload/goods/2018-03/5a9764cd7004f_m_thumb.jpg new file mode 100755 index 0000000..85ad506 Binary files /dev/null and b/upload/goods/2018-03/5a9764cd7004f_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9764cd7004f_thumb.jpg b/upload/goods/2018-03/5a9764cd7004f_thumb.jpg new file mode 100755 index 0000000..f1d7adb Binary files /dev/null and b/upload/goods/2018-03/5a9764cd7004f_thumb.jpg differ diff --git a/upload/goods/2018-03/5a9768f4edf45.png b/upload/goods/2018-03/5a9768f4edf45.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-03/5a9768f4edf45.png differ diff --git a/upload/goods/2018-03/5a9768f4edf45_m.png b/upload/goods/2018-03/5a9768f4edf45_m.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9768f4edf45_m.png differ diff --git a/upload/goods/2018-03/5a9768f4edf45_m_thumb.png b/upload/goods/2018-03/5a9768f4edf45_m_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9768f4edf45_m_thumb.png differ diff --git a/upload/goods/2018-03/5a9768f4edf45_thumb.png b/upload/goods/2018-03/5a9768f4edf45_thumb.png new file mode 100755 index 0000000..77a6bd5 Binary files /dev/null and b/upload/goods/2018-03/5a9768f4edf45_thumb.png differ diff --git a/upload/goods/2018-03/5a976a16f1459.png b/upload/goods/2018-03/5a976a16f1459.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/goods/2018-03/5a976a16f1459.png differ diff --git a/upload/goods/2018-03/5a976a16f1459_m.png b/upload/goods/2018-03/5a976a16f1459_m.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-03/5a976a16f1459_m.png differ diff --git a/upload/goods/2018-03/5a976a16f1459_m_thumb.png b/upload/goods/2018-03/5a976a16f1459_m_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-03/5a976a16f1459_m_thumb.png differ diff --git a/upload/goods/2018-03/5a976a16f1459_thumb.png b/upload/goods/2018-03/5a976a16f1459_thumb.png new file mode 100755 index 0000000..8c186ba Binary files /dev/null and b/upload/goods/2018-03/5a976a16f1459_thumb.png differ diff --git a/upload/goods/2018-03/5a976f8e0a51e.jpg b/upload/goods/2018-03/5a976f8e0a51e.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/goods/2018-03/5a976f8e0a51e.jpg differ diff --git a/upload/goods/2018-03/5a976f8e0a51e_m.jpg b/upload/goods/2018-03/5a976f8e0a51e_m.jpg new file mode 100755 index 0000000..9ce1d30 Binary files /dev/null and b/upload/goods/2018-03/5a976f8e0a51e_m.jpg differ diff --git a/upload/goods/2018-03/5a976f8e0a51e_m_thumb.jpg b/upload/goods/2018-03/5a976f8e0a51e_m_thumb.jpg new file mode 100755 index 0000000..18ac9ee Binary files /dev/null and b/upload/goods/2018-03/5a976f8e0a51e_m_thumb.jpg differ diff --git a/upload/goods/2018-03/5a976f8e0a51e_thumb.jpg b/upload/goods/2018-03/5a976f8e0a51e_thumb.jpg new file mode 100755 index 0000000..903078b Binary files /dev/null and b/upload/goods/2018-03/5a976f8e0a51e_thumb.jpg differ diff --git a/upload/goods/2018-03/5a97ad68b4a7b.jpg b/upload/goods/2018-03/5a97ad68b4a7b.jpg new file mode 100755 index 0000000..629a71d Binary files /dev/null and b/upload/goods/2018-03/5a97ad68b4a7b.jpg differ diff --git a/upload/goods/2018-03/5a97adeb50ac0.jpg b/upload/goods/2018-03/5a97adeb50ac0.jpg new file mode 100755 index 0000000..01796b4 Binary files /dev/null and b/upload/goods/2018-03/5a97adeb50ac0.jpg differ diff --git a/upload/goods/2018-03/5a97ae645aa9b.jpg b/upload/goods/2018-03/5a97ae645aa9b.jpg new file mode 100755 index 0000000..96d6596 Binary files /dev/null and b/upload/goods/2018-03/5a97ae645aa9b.jpg differ diff --git a/upload/goods/2018-03/5a97af94e5ae8.jpg b/upload/goods/2018-03/5a97af94e5ae8.jpg new file mode 100755 index 0000000..cd6f504 Binary files /dev/null and b/upload/goods/2018-03/5a97af94e5ae8.jpg differ diff --git a/upload/goods/2018-03/5a97afc17488b.png b/upload/goods/2018-03/5a97afc17488b.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/goods/2018-03/5a97afc17488b.png differ diff --git a/upload/goods/2018-03/5a99e8a54a446.jpg b/upload/goods/2018-03/5a99e8a54a446.jpg new file mode 100755 index 0000000..e46cda3 Binary files /dev/null and b/upload/goods/2018-03/5a99e8a54a446.jpg differ diff --git a/upload/goods/2018-03/5ab21d2d1f9d5.jpg b/upload/goods/2018-03/5ab21d2d1f9d5.jpg new file mode 100755 index 0000000..37d5815 Binary files /dev/null and b/upload/goods/2018-03/5ab21d2d1f9d5.jpg differ diff --git a/upload/goods/2018-03/5ab21d495c8e5.jpg b/upload/goods/2018-03/5ab21d495c8e5.jpg new file mode 100755 index 0000000..37d5815 Binary files /dev/null and b/upload/goods/2018-03/5ab21d495c8e5.jpg differ diff --git a/upload/goods/2018-03/5ab477676fccc.jpg b/upload/goods/2018-03/5ab477676fccc.jpg new file mode 100755 index 0000000..f471b1a --- /dev/null +++ b/upload/goods/2018-03/5ab477676fccc.jpg @@ -0,0 +1,8 @@ +{ + "FileSize": {"value": "26369"}, + "Format": {"value": "jpg"}, + "ImageHeight": {"value": "450"}, + "ImageWidth": {"value": "450"}, + "ResolutionUnit": {"value": "2"}, + "XResolution": {"value": "72/1"}, + "YResolution": {"value": "72/1"}} \ No newline at end of file diff --git a/upload/goods/2018-03/5ab8acbb9e95c.png b/upload/goods/2018-03/5ab8acbb9e95c.png new file mode 100755 index 0000000..c46bfd1 Binary files /dev/null and b/upload/goods/2018-03/5ab8acbb9e95c.png differ diff --git a/upload/goods/2018-03/5ab8acbb9e95c_m.png b/upload/goods/2018-03/5ab8acbb9e95c_m.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acbb9e95c_m.png differ diff --git a/upload/goods/2018-03/5ab8acbb9e95c_m_thumb.png b/upload/goods/2018-03/5ab8acbb9e95c_m_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acbb9e95c_m_thumb.png differ diff --git a/upload/goods/2018-03/5ab8acbb9e95c_thumb.png b/upload/goods/2018-03/5ab8acbb9e95c_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acbb9e95c_thumb.png differ diff --git a/upload/goods/2018-03/5ab8acce98039.png b/upload/goods/2018-03/5ab8acce98039.png new file mode 100755 index 0000000..c46bfd1 Binary files /dev/null and b/upload/goods/2018-03/5ab8acce98039.png differ diff --git a/upload/goods/2018-03/5ab8acce98039_m.png b/upload/goods/2018-03/5ab8acce98039_m.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acce98039_m.png differ diff --git a/upload/goods/2018-03/5ab8acce98039_m_thumb.png b/upload/goods/2018-03/5ab8acce98039_m_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acce98039_m_thumb.png differ diff --git a/upload/goods/2018-03/5ab8acce98039_thumb.png b/upload/goods/2018-03/5ab8acce98039_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8acce98039_thumb.png differ diff --git a/upload/goods/2018-03/5ab8ad0c8e619.png b/upload/goods/2018-03/5ab8ad0c8e619.png new file mode 100755 index 0000000..c46bfd1 Binary files /dev/null and b/upload/goods/2018-03/5ab8ad0c8e619.png differ diff --git a/upload/goods/2018-03/5ab8ad0c8e619_m.png b/upload/goods/2018-03/5ab8ad0c8e619_m.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8ad0c8e619_m.png differ diff --git a/upload/goods/2018-03/5ab8ad0c8e619_m_thumb.png b/upload/goods/2018-03/5ab8ad0c8e619_m_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8ad0c8e619_m_thumb.png differ diff --git a/upload/goods/2018-03/5ab8ad0c8e619_thumb.png b/upload/goods/2018-03/5ab8ad0c8e619_thumb.png new file mode 100755 index 0000000..ce84f81 Binary files /dev/null and b/upload/goods/2018-03/5ab8ad0c8e619_thumb.png differ diff --git a/upload/goods/2018-04/5ac17bc9b0cdc.png b/upload/goods/2018-04/5ac17bc9b0cdc.png new file mode 100755 index 0000000..6d60257 Binary files /dev/null and b/upload/goods/2018-04/5ac17bc9b0cdc.png differ diff --git a/upload/goods/txt.txt b/upload/goods/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/goods/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/goodscats/2017-10/59e5ab5457a59.jpg b/upload/goodscats/2017-10/59e5ab5457a59.jpg new file mode 100755 index 0000000..8b761bc Binary files /dev/null and b/upload/goodscats/2017-10/59e5ab5457a59.jpg differ diff --git a/upload/goodscats/2017-10/59e5ab960488e.jpg b/upload/goodscats/2017-10/59e5ab960488e.jpg new file mode 100755 index 0000000..b34c1d3 Binary files /dev/null and b/upload/goodscats/2017-10/59e5ab960488e.jpg differ diff --git a/upload/goodscats/2017-10/59e5abb3ef9a6.jpg b/upload/goodscats/2017-10/59e5abb3ef9a6.jpg new file mode 100755 index 0000000..b96c3fd Binary files /dev/null and b/upload/goodscats/2017-10/59e5abb3ef9a6.jpg differ diff --git a/upload/goodscats/2017-10/59e5abd69e1e3.jpg b/upload/goodscats/2017-10/59e5abd69e1e3.jpg new file mode 100755 index 0000000..db1e2a7 Binary files /dev/null and b/upload/goodscats/2017-10/59e5abd69e1e3.jpg differ diff --git a/upload/goodscats/2017-10/59e5abf38832c.jpg b/upload/goodscats/2017-10/59e5abf38832c.jpg new file mode 100755 index 0000000..ea1d71f Binary files /dev/null and b/upload/goodscats/2017-10/59e5abf38832c.jpg differ diff --git a/upload/goodscats/2017-10/59e5ac0fd000e.jpg b/upload/goodscats/2017-10/59e5ac0fd000e.jpg new file mode 100755 index 0000000..ba7a7a0 Binary files /dev/null and b/upload/goodscats/2017-10/59e5ac0fd000e.jpg differ diff --git a/upload/goodscats/2017-10/59e5ac896d8dc.jpg b/upload/goodscats/2017-10/59e5ac896d8dc.jpg new file mode 100755 index 0000000..a8d452d Binary files /dev/null and b/upload/goodscats/2017-10/59e5ac896d8dc.jpg differ diff --git a/upload/goodscats/2017-10/59e5acada6bdf.jpg b/upload/goodscats/2017-10/59e5acada6bdf.jpg new file mode 100755 index 0000000..5cf5996 Binary files /dev/null and b/upload/goodscats/2017-10/59e5acada6bdf.jpg differ diff --git a/upload/goodscats/2017-10/59e5acd918291.jpg b/upload/goodscats/2017-10/59e5acd918291.jpg new file mode 100755 index 0000000..6b8b836 Binary files /dev/null and b/upload/goodscats/2017-10/59e5acd918291.jpg differ diff --git a/upload/goodscats/2017-10/59e5acf326322.jpg b/upload/goodscats/2017-10/59e5acf326322.jpg new file mode 100755 index 0000000..6e5b1ae Binary files /dev/null and b/upload/goodscats/2017-10/59e5acf326322.jpg differ diff --git a/upload/goodscats/2017-10/59e5ad7154bc3.jpg b/upload/goodscats/2017-10/59e5ad7154bc3.jpg new file mode 100755 index 0000000..699b161 Binary files /dev/null and b/upload/goodscats/2017-10/59e5ad7154bc3.jpg differ diff --git a/upload/goodscats/2017-10/59e5ada5ca883.jpg b/upload/goodscats/2017-10/59e5ada5ca883.jpg new file mode 100755 index 0000000..09f235a Binary files /dev/null and b/upload/goodscats/2017-10/59e5ada5ca883.jpg differ diff --git a/upload/goodscats/2017-10/59e5ae12e66d2.jpg b/upload/goodscats/2017-10/59e5ae12e66d2.jpg new file mode 100755 index 0000000..06c351b Binary files /dev/null and b/upload/goodscats/2017-10/59e5ae12e66d2.jpg differ diff --git a/upload/goodscats/2017-10/59e5ae8e1af9a.jpg b/upload/goodscats/2017-10/59e5ae8e1af9a.jpg new file mode 100755 index 0000000..144ff0d Binary files /dev/null and b/upload/goodscats/2017-10/59e5ae8e1af9a.jpg differ diff --git a/upload/goodscats/2017-10/59e5aedaf073f.jpg b/upload/goodscats/2017-10/59e5aedaf073f.jpg new file mode 100755 index 0000000..632382d Binary files /dev/null and b/upload/goodscats/2017-10/59e5aedaf073f.jpg differ diff --git a/upload/goodscats/2017-10/59e5aef5aad74.jpg b/upload/goodscats/2017-10/59e5aef5aad74.jpg new file mode 100755 index 0000000..b47ffb3 Binary files /dev/null and b/upload/goodscats/2017-10/59e5aef5aad74.jpg differ diff --git a/upload/goodscats/2017-10/59e5af13407de.jpg b/upload/goodscats/2017-10/59e5af13407de.jpg new file mode 100755 index 0000000..70d9616 Binary files /dev/null and b/upload/goodscats/2017-10/59e5af13407de.jpg differ diff --git a/upload/goodscats/2017-10/59e5af5d99168.jpg b/upload/goodscats/2017-10/59e5af5d99168.jpg new file mode 100755 index 0000000..233cb66 Binary files /dev/null and b/upload/goodscats/2017-10/59e5af5d99168.jpg differ diff --git a/upload/goodscats/2017-10/59e5af8f393ab.jpg b/upload/goodscats/2017-10/59e5af8f393ab.jpg new file mode 100755 index 0000000..91e5222 Binary files /dev/null and b/upload/goodscats/2017-10/59e5af8f393ab.jpg differ diff --git a/upload/goodscats/2017-10/59e5afd8d0230.jpg b/upload/goodscats/2017-10/59e5afd8d0230.jpg new file mode 100755 index 0000000..5bfe173 Binary files /dev/null and b/upload/goodscats/2017-10/59e5afd8d0230.jpg differ diff --git a/upload/goodscats/2017-10/59e5b03218b56.jpg b/upload/goodscats/2017-10/59e5b03218b56.jpg new file mode 100755 index 0000000..da930fe Binary files /dev/null and b/upload/goodscats/2017-10/59e5b03218b56.jpg differ diff --git a/upload/goodscats/2017-10/59e5b09360ee7.jpg b/upload/goodscats/2017-10/59e5b09360ee7.jpg new file mode 100755 index 0000000..f73683a Binary files /dev/null and b/upload/goodscats/2017-10/59e5b09360ee7.jpg differ diff --git a/upload/goodscats/2017-10/59e5b0f02e824.jpg b/upload/goodscats/2017-10/59e5b0f02e824.jpg new file mode 100755 index 0000000..4723da6 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b0f02e824.jpg differ diff --git a/upload/goodscats/2017-10/59e5b1131f187.jpg b/upload/goodscats/2017-10/59e5b1131f187.jpg new file mode 100755 index 0000000..e6abe3a Binary files /dev/null and b/upload/goodscats/2017-10/59e5b1131f187.jpg differ diff --git a/upload/goodscats/2017-10/59e5b130e8be0.jpg b/upload/goodscats/2017-10/59e5b130e8be0.jpg new file mode 100755 index 0000000..5c76124 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b130e8be0.jpg differ diff --git a/upload/goodscats/2017-10/59e5b155854a3.jpg b/upload/goodscats/2017-10/59e5b155854a3.jpg new file mode 100755 index 0000000..d9a278e Binary files /dev/null and b/upload/goodscats/2017-10/59e5b155854a3.jpg differ diff --git a/upload/goodscats/2017-10/59e5b1993e3b8.jpg b/upload/goodscats/2017-10/59e5b1993e3b8.jpg new file mode 100755 index 0000000..3c0981b Binary files /dev/null and b/upload/goodscats/2017-10/59e5b1993e3b8.jpg differ diff --git a/upload/goodscats/2017-10/59e5b1e82fb8a.jpg b/upload/goodscats/2017-10/59e5b1e82fb8a.jpg new file mode 100755 index 0000000..708d63e Binary files /dev/null and b/upload/goodscats/2017-10/59e5b1e82fb8a.jpg differ diff --git a/upload/goodscats/2017-10/59e5b207becea.jpg b/upload/goodscats/2017-10/59e5b207becea.jpg new file mode 100755 index 0000000..74a5bbf Binary files /dev/null and b/upload/goodscats/2017-10/59e5b207becea.jpg differ diff --git a/upload/goodscats/2017-10/59e5b24668997.jpg b/upload/goodscats/2017-10/59e5b24668997.jpg new file mode 100755 index 0000000..a7719ba Binary files /dev/null and b/upload/goodscats/2017-10/59e5b24668997.jpg differ diff --git a/upload/goodscats/2017-10/59e5b288bf070.jpg b/upload/goodscats/2017-10/59e5b288bf070.jpg new file mode 100755 index 0000000..96f8966 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b288bf070.jpg differ diff --git a/upload/goodscats/2017-10/59e5b2a383629.jpg b/upload/goodscats/2017-10/59e5b2a383629.jpg new file mode 100755 index 0000000..b10ddbb Binary files /dev/null and b/upload/goodscats/2017-10/59e5b2a383629.jpg differ diff --git a/upload/goodscats/2017-10/59e5b2bb3ced5.jpg b/upload/goodscats/2017-10/59e5b2bb3ced5.jpg new file mode 100755 index 0000000..bf1f8d2 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b2bb3ced5.jpg differ diff --git a/upload/goodscats/2017-10/59e5b3234cd6f.jpg b/upload/goodscats/2017-10/59e5b3234cd6f.jpg new file mode 100755 index 0000000..71de564 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b3234cd6f.jpg differ diff --git a/upload/goodscats/2017-10/59e5b36759f78.jpg b/upload/goodscats/2017-10/59e5b36759f78.jpg new file mode 100755 index 0000000..3ec67b5 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b36759f78.jpg differ diff --git a/upload/goodscats/2017-10/59e5b492bdfe6.jpg b/upload/goodscats/2017-10/59e5b492bdfe6.jpg new file mode 100755 index 0000000..d8f9b20 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b492bdfe6.jpg differ diff --git a/upload/goodscats/2017-10/59e5b4cad093c.jpg b/upload/goodscats/2017-10/59e5b4cad093c.jpg new file mode 100755 index 0000000..9fdd647 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b4cad093c.jpg differ diff --git a/upload/goodscats/2017-10/59e5b53f1b425.jpg b/upload/goodscats/2017-10/59e5b53f1b425.jpg new file mode 100755 index 0000000..5cb1754 Binary files /dev/null and b/upload/goodscats/2017-10/59e5b53f1b425.jpg differ diff --git a/upload/goodscats/2017-10/59e5b5806ab90.jpg b/upload/goodscats/2017-10/59e5b5806ab90.jpg new file mode 100755 index 0000000..d43bd0f Binary files /dev/null and b/upload/goodscats/2017-10/59e5b5806ab90.jpg differ diff --git a/upload/goodscats/2017-10/59e5b5b0d28d0.jpg b/upload/goodscats/2017-10/59e5b5b0d28d0.jpg new file mode 100755 index 0000000..f8a8a0f Binary files /dev/null and b/upload/goodscats/2017-10/59e5b5b0d28d0.jpg differ diff --git a/upload/goodscats/2017-10/59e5ba0a1ba8e.jpg b/upload/goodscats/2017-10/59e5ba0a1ba8e.jpg new file mode 100755 index 0000000..0ed9234 Binary files /dev/null and b/upload/goodscats/2017-10/59e5ba0a1ba8e.jpg differ diff --git a/upload/goodscats/2017-10/59e5ba4f56223.jpg b/upload/goodscats/2017-10/59e5ba4f56223.jpg new file mode 100755 index 0000000..74b5aae Binary files /dev/null and b/upload/goodscats/2017-10/59e5ba4f56223.jpg differ diff --git a/upload/goodscats/2017-10/59e5ba71e0236.jpg b/upload/goodscats/2017-10/59e5ba71e0236.jpg new file mode 100755 index 0000000..517e60f Binary files /dev/null and b/upload/goodscats/2017-10/59e5ba71e0236.jpg differ diff --git a/upload/goodscats/2017-10/59e5bada180fc.jpg b/upload/goodscats/2017-10/59e5bada180fc.jpg new file mode 100755 index 0000000..f9385a5 Binary files /dev/null and b/upload/goodscats/2017-10/59e5bada180fc.jpg differ diff --git a/upload/goodscats/2017-10/59e6b5f7b45d0.jpg b/upload/goodscats/2017-10/59e6b5f7b45d0.jpg new file mode 100755 index 0000000..a16a221 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b5f7b45d0.jpg differ diff --git a/upload/goodscats/2017-10/59e6b61595aab.jpg b/upload/goodscats/2017-10/59e6b61595aab.jpg new file mode 100755 index 0000000..199177b Binary files /dev/null and b/upload/goodscats/2017-10/59e6b61595aab.jpg differ diff --git a/upload/goodscats/2017-10/59e6b648c15a4.jpg b/upload/goodscats/2017-10/59e6b648c15a4.jpg new file mode 100755 index 0000000..6d58db8 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b648c15a4.jpg differ diff --git a/upload/goodscats/2017-10/59e6b91e80d52.jpg b/upload/goodscats/2017-10/59e6b91e80d52.jpg new file mode 100755 index 0000000..19ec982 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b91e80d52.jpg differ diff --git a/upload/goodscats/2017-10/59e6b93ddf2e5.jpg b/upload/goodscats/2017-10/59e6b93ddf2e5.jpg new file mode 100755 index 0000000..4038f25 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b93ddf2e5.jpg differ diff --git a/upload/goodscats/2017-10/59e6b9592fdc6.jpg b/upload/goodscats/2017-10/59e6b9592fdc6.jpg new file mode 100755 index 0000000..257d2b5 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b9592fdc6.jpg differ diff --git a/upload/goodscats/2017-10/59e6b971c0e31.jpg b/upload/goodscats/2017-10/59e6b971c0e31.jpg new file mode 100755 index 0000000..4a4dc27 Binary files /dev/null and b/upload/goodscats/2017-10/59e6b971c0e31.jpg differ diff --git a/upload/goodscats/2017-10/59e6b9d89886f.jpg b/upload/goodscats/2017-10/59e6b9d89886f.jpg new file mode 100755 index 0000000..eb3003e Binary files /dev/null and b/upload/goodscats/2017-10/59e6b9d89886f.jpg differ diff --git a/upload/goodscats/2017-10/59e6ba055d717.jpg b/upload/goodscats/2017-10/59e6ba055d717.jpg new file mode 100755 index 0000000..fc03120 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ba055d717.jpg differ diff --git a/upload/goodscats/2017-10/59e6ba30c53bd.jpg b/upload/goodscats/2017-10/59e6ba30c53bd.jpg new file mode 100755 index 0000000..b1bca49 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ba30c53bd.jpg differ diff --git a/upload/goodscats/2017-10/59e6bad67bb72.jpg b/upload/goodscats/2017-10/59e6bad67bb72.jpg new file mode 100755 index 0000000..0ff583a Binary files /dev/null and b/upload/goodscats/2017-10/59e6bad67bb72.jpg differ diff --git a/upload/goodscats/2017-10/59e6bb35e948a.jpg b/upload/goodscats/2017-10/59e6bb35e948a.jpg new file mode 100755 index 0000000..6866b47 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bb35e948a.jpg differ diff --git a/upload/goodscats/2017-10/59e6bb5543f3b.jpg b/upload/goodscats/2017-10/59e6bb5543f3b.jpg new file mode 100755 index 0000000..e669dfe Binary files /dev/null and b/upload/goodscats/2017-10/59e6bb5543f3b.jpg differ diff --git a/upload/goodscats/2017-10/59e6bb7a2681b.jpg b/upload/goodscats/2017-10/59e6bb7a2681b.jpg new file mode 100755 index 0000000..32c9da1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bb7a2681b.jpg differ diff --git a/upload/goodscats/2017-10/59e6bb9654634.jpg b/upload/goodscats/2017-10/59e6bb9654634.jpg new file mode 100755 index 0000000..9d2e45c Binary files /dev/null and b/upload/goodscats/2017-10/59e6bb9654634.jpg differ diff --git a/upload/goodscats/2017-10/59e6bbeb97b85.jpg b/upload/goodscats/2017-10/59e6bbeb97b85.jpg new file mode 100755 index 0000000..13db974 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bbeb97b85.jpg differ diff --git a/upload/goodscats/2017-10/59e6bc3c91c86.jpg b/upload/goodscats/2017-10/59e6bc3c91c86.jpg new file mode 100755 index 0000000..133f67d Binary files /dev/null and b/upload/goodscats/2017-10/59e6bc3c91c86.jpg differ diff --git a/upload/goodscats/2017-10/59e6bc8384d59.jpg b/upload/goodscats/2017-10/59e6bc8384d59.jpg new file mode 100755 index 0000000..c352290 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bc8384d59.jpg differ diff --git a/upload/goodscats/2017-10/59e6bccf2de0b.jpg b/upload/goodscats/2017-10/59e6bccf2de0b.jpg new file mode 100755 index 0000000..6c14b1b Binary files /dev/null and b/upload/goodscats/2017-10/59e6bccf2de0b.jpg differ diff --git a/upload/goodscats/2017-10/59e6bcf13bd24.jpg b/upload/goodscats/2017-10/59e6bcf13bd24.jpg new file mode 100755 index 0000000..d59b887 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bcf13bd24.jpg differ diff --git a/upload/goodscats/2017-10/59e6bd22d1247.jpg b/upload/goodscats/2017-10/59e6bd22d1247.jpg new file mode 100755 index 0000000..063b9bb Binary files /dev/null and b/upload/goodscats/2017-10/59e6bd22d1247.jpg differ diff --git a/upload/goodscats/2017-10/59e6bd6c701d4.jpg b/upload/goodscats/2017-10/59e6bd6c701d4.jpg new file mode 100755 index 0000000..5536a73 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bd6c701d4.jpg differ diff --git a/upload/goodscats/2017-10/59e6bdd0e4c3c.jpg b/upload/goodscats/2017-10/59e6bdd0e4c3c.jpg new file mode 100755 index 0000000..6c14b1b Binary files /dev/null and b/upload/goodscats/2017-10/59e6bdd0e4c3c.jpg differ diff --git a/upload/goodscats/2017-10/59e6be895c035.jpg b/upload/goodscats/2017-10/59e6be895c035.jpg new file mode 100755 index 0000000..ce6a31d Binary files /dev/null and b/upload/goodscats/2017-10/59e6be895c035.jpg differ diff --git a/upload/goodscats/2017-10/59e6beca84e46.jpg b/upload/goodscats/2017-10/59e6beca84e46.jpg new file mode 100755 index 0000000..deebba3 Binary files /dev/null and b/upload/goodscats/2017-10/59e6beca84e46.jpg differ diff --git a/upload/goodscats/2017-10/59e6bf07c445d.jpg b/upload/goodscats/2017-10/59e6bf07c445d.jpg new file mode 100755 index 0000000..492e5a7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bf07c445d.jpg differ diff --git a/upload/goodscats/2017-10/59e6bf33d83e8.jpg b/upload/goodscats/2017-10/59e6bf33d83e8.jpg new file mode 100755 index 0000000..0f0f2aa Binary files /dev/null and b/upload/goodscats/2017-10/59e6bf33d83e8.jpg differ diff --git a/upload/goodscats/2017-10/59e6bf68df79c.jpg b/upload/goodscats/2017-10/59e6bf68df79c.jpg new file mode 100755 index 0000000..adbc16c Binary files /dev/null and b/upload/goodscats/2017-10/59e6bf68df79c.jpg differ diff --git a/upload/goodscats/2017-10/59e6bf8e56f79.jpg b/upload/goodscats/2017-10/59e6bf8e56f79.jpg new file mode 100755 index 0000000..f8058d6 Binary files /dev/null and b/upload/goodscats/2017-10/59e6bf8e56f79.jpg differ diff --git a/upload/goodscats/2017-10/59e6bfeb8f86d.jpg b/upload/goodscats/2017-10/59e6bfeb8f86d.jpg new file mode 100755 index 0000000..ecfd0dc Binary files /dev/null and b/upload/goodscats/2017-10/59e6bfeb8f86d.jpg differ diff --git a/upload/goodscats/2017-10/59e6c1899c168.jpg b/upload/goodscats/2017-10/59e6c1899c168.jpg new file mode 100755 index 0000000..8bccaf1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c1899c168.jpg differ diff --git a/upload/goodscats/2017-10/59e6c1dfaeae9.jpg b/upload/goodscats/2017-10/59e6c1dfaeae9.jpg new file mode 100755 index 0000000..c94c0af Binary files /dev/null and b/upload/goodscats/2017-10/59e6c1dfaeae9.jpg differ diff --git a/upload/goodscats/2017-10/59e6c25be7a29.jpg b/upload/goodscats/2017-10/59e6c25be7a29.jpg new file mode 100755 index 0000000..2c93519 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c25be7a29.jpg differ diff --git a/upload/goodscats/2017-10/59e6c28fa3c3e.jpg b/upload/goodscats/2017-10/59e6c28fa3c3e.jpg new file mode 100755 index 0000000..bbad5cc Binary files /dev/null and b/upload/goodscats/2017-10/59e6c28fa3c3e.jpg differ diff --git a/upload/goodscats/2017-10/59e6c2b3109a8.jpg b/upload/goodscats/2017-10/59e6c2b3109a8.jpg new file mode 100755 index 0000000..0da2e8d Binary files /dev/null and b/upload/goodscats/2017-10/59e6c2b3109a8.jpg differ diff --git a/upload/goodscats/2017-10/59e6c2cb5146f.jpg b/upload/goodscats/2017-10/59e6c2cb5146f.jpg new file mode 100755 index 0000000..c2f2e79 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c2cb5146f.jpg differ diff --git a/upload/goodscats/2017-10/59e6c34e91ce2.jpg b/upload/goodscats/2017-10/59e6c34e91ce2.jpg new file mode 100755 index 0000000..1c4a3c3 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c34e91ce2.jpg differ diff --git a/upload/goodscats/2017-10/59e6c3a17aa85.jpg b/upload/goodscats/2017-10/59e6c3a17aa85.jpg new file mode 100755 index 0000000..5ce5884 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c3a17aa85.jpg differ diff --git a/upload/goodscats/2017-10/59e6c3cc87e26.jpg b/upload/goodscats/2017-10/59e6c3cc87e26.jpg new file mode 100755 index 0000000..061c450 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c3cc87e26.jpg differ diff --git a/upload/goodscats/2017-10/59e6c3ffe5daf.jpg b/upload/goodscats/2017-10/59e6c3ffe5daf.jpg new file mode 100755 index 0000000..6c8f0c9 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c3ffe5daf.jpg differ diff --git a/upload/goodscats/2017-10/59e6c482312fe.jpg b/upload/goodscats/2017-10/59e6c482312fe.jpg new file mode 100755 index 0000000..0da2e8d Binary files /dev/null and b/upload/goodscats/2017-10/59e6c482312fe.jpg differ diff --git a/upload/goodscats/2017-10/59e6c49d1fac0.jpg b/upload/goodscats/2017-10/59e6c49d1fac0.jpg new file mode 100755 index 0000000..c2f2e79 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c49d1fac0.jpg differ diff --git a/upload/goodscats/2017-10/59e6c4b129a77.jpg b/upload/goodscats/2017-10/59e6c4b129a77.jpg new file mode 100755 index 0000000..66779ce Binary files /dev/null and b/upload/goodscats/2017-10/59e6c4b129a77.jpg differ diff --git a/upload/goodscats/2017-10/59e6c4e8c4330.jpg b/upload/goodscats/2017-10/59e6c4e8c4330.jpg new file mode 100755 index 0000000..1c4a3c3 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c4e8c4330.jpg differ diff --git a/upload/goodscats/2017-10/59e6c4ef429cb.jpg b/upload/goodscats/2017-10/59e6c4ef429cb.jpg new file mode 100755 index 0000000..5ce5884 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c4ef429cb.jpg differ diff --git a/upload/goodscats/2017-10/59e6c4f6778ce.jpg b/upload/goodscats/2017-10/59e6c4f6778ce.jpg new file mode 100755 index 0000000..061c450 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c4f6778ce.jpg differ diff --git a/upload/goodscats/2017-10/59e6c5358c6ab.jpg b/upload/goodscats/2017-10/59e6c5358c6ab.jpg new file mode 100755 index 0000000..41786c8 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c5358c6ab.jpg differ diff --git a/upload/goodscats/2017-10/59e6c5562b305.jpg b/upload/goodscats/2017-10/59e6c5562b305.jpg new file mode 100755 index 0000000..95b4eb3 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c5562b305.jpg differ diff --git a/upload/goodscats/2017-10/59e6c5f33fae5.jpg b/upload/goodscats/2017-10/59e6c5f33fae5.jpg new file mode 100755 index 0000000..fc37b4f Binary files /dev/null and b/upload/goodscats/2017-10/59e6c5f33fae5.jpg differ diff --git a/upload/goodscats/2017-10/59e6c60504efe.jpg b/upload/goodscats/2017-10/59e6c60504efe.jpg new file mode 100755 index 0000000..73007f8 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c60504efe.jpg differ diff --git a/upload/goodscats/2017-10/59e6c628d4a9c.jpg b/upload/goodscats/2017-10/59e6c628d4a9c.jpg new file mode 100755 index 0000000..01be931 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c628d4a9c.jpg differ diff --git a/upload/goodscats/2017-10/59e6c63d12b56.jpg b/upload/goodscats/2017-10/59e6c63d12b56.jpg new file mode 100755 index 0000000..06c9dc0 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c63d12b56.jpg differ diff --git a/upload/goodscats/2017-10/59e6c65a0fc14.jpg b/upload/goodscats/2017-10/59e6c65a0fc14.jpg new file mode 100755 index 0000000..9558d49 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c65a0fc14.jpg differ diff --git a/upload/goodscats/2017-10/59e6c67b56728.jpg b/upload/goodscats/2017-10/59e6c67b56728.jpg new file mode 100755 index 0000000..d6483e9 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c67b56728.jpg differ diff --git a/upload/goodscats/2017-10/59e6c69301799.jpg b/upload/goodscats/2017-10/59e6c69301799.jpg new file mode 100755 index 0000000..40247e5 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c69301799.jpg differ diff --git a/upload/goodscats/2017-10/59e6c6d259f3c.jpg b/upload/goodscats/2017-10/59e6c6d259f3c.jpg new file mode 100755 index 0000000..8aa82b4 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c6d259f3c.jpg differ diff --git a/upload/goodscats/2017-10/59e6c704019ba.jpg b/upload/goodscats/2017-10/59e6c704019ba.jpg new file mode 100755 index 0000000..96b1b5e Binary files /dev/null and b/upload/goodscats/2017-10/59e6c704019ba.jpg differ diff --git a/upload/goodscats/2017-10/59e6c75b04289.jpg b/upload/goodscats/2017-10/59e6c75b04289.jpg new file mode 100755 index 0000000..01373eb Binary files /dev/null and b/upload/goodscats/2017-10/59e6c75b04289.jpg differ diff --git a/upload/goodscats/2017-10/59e6c8e223ff9.jpg b/upload/goodscats/2017-10/59e6c8e223ff9.jpg new file mode 100755 index 0000000..1da1db5 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c8e223ff9.jpg differ diff --git a/upload/goodscats/2017-10/59e6c98d250b4.jpg b/upload/goodscats/2017-10/59e6c98d250b4.jpg new file mode 100755 index 0000000..805ca1c Binary files /dev/null and b/upload/goodscats/2017-10/59e6c98d250b4.jpg differ diff --git a/upload/goodscats/2017-10/59e6c9bc3d20f.jpg b/upload/goodscats/2017-10/59e6c9bc3d20f.jpg new file mode 100755 index 0000000..6d16cc0 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c9bc3d20f.jpg differ diff --git a/upload/goodscats/2017-10/59e6c9d725ff4.jpg b/upload/goodscats/2017-10/59e6c9d725ff4.jpg new file mode 100755 index 0000000..29c6272 Binary files /dev/null and b/upload/goodscats/2017-10/59e6c9d725ff4.jpg differ diff --git a/upload/goodscats/2017-10/59e6c9f9663bf.jpg b/upload/goodscats/2017-10/59e6c9f9663bf.jpg new file mode 100755 index 0000000..9b590cd Binary files /dev/null and b/upload/goodscats/2017-10/59e6c9f9663bf.jpg differ diff --git a/upload/goodscats/2017-10/59e6ca11d3a58.jpg b/upload/goodscats/2017-10/59e6ca11d3a58.jpg new file mode 100755 index 0000000..224b5cd Binary files /dev/null and b/upload/goodscats/2017-10/59e6ca11d3a58.jpg differ diff --git a/upload/goodscats/2017-10/59e6ca656e67a.jpg b/upload/goodscats/2017-10/59e6ca656e67a.jpg new file mode 100755 index 0000000..5f11493 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ca656e67a.jpg differ diff --git a/upload/goodscats/2017-10/59e6ca8b6302f.jpg b/upload/goodscats/2017-10/59e6ca8b6302f.jpg new file mode 100755 index 0000000..c192a89 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ca8b6302f.jpg differ diff --git a/upload/goodscats/2017-10/59e6caad8cf73.jpg b/upload/goodscats/2017-10/59e6caad8cf73.jpg new file mode 100755 index 0000000..68dadc4 Binary files /dev/null and b/upload/goodscats/2017-10/59e6caad8cf73.jpg differ diff --git a/upload/goodscats/2017-10/59e6cae157100.jpg b/upload/goodscats/2017-10/59e6cae157100.jpg new file mode 100755 index 0000000..050d97e Binary files /dev/null and b/upload/goodscats/2017-10/59e6cae157100.jpg differ diff --git a/upload/goodscats/2017-10/59e6cb0738d55.jpg b/upload/goodscats/2017-10/59e6cb0738d55.jpg new file mode 100755 index 0000000..6d16cc0 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cb0738d55.jpg differ diff --git a/upload/goodscats/2017-10/59e6cb47e109e.jpg b/upload/goodscats/2017-10/59e6cb47e109e.jpg new file mode 100755 index 0000000..82f3ae1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cb47e109e.jpg differ diff --git a/upload/goodscats/2017-10/59e6cba8aa02d.jpg b/upload/goodscats/2017-10/59e6cba8aa02d.jpg new file mode 100755 index 0000000..94f2073 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cba8aa02d.jpg differ diff --git a/upload/goodscats/2017-10/59e6cc0c88802.jpg b/upload/goodscats/2017-10/59e6cc0c88802.jpg new file mode 100755 index 0000000..0406566 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cc0c88802.jpg differ diff --git a/upload/goodscats/2017-10/59e6cdb200ada.jpg b/upload/goodscats/2017-10/59e6cdb200ada.jpg new file mode 100755 index 0000000..54d31eb Binary files /dev/null and b/upload/goodscats/2017-10/59e6cdb200ada.jpg differ diff --git a/upload/goodscats/2017-10/59e6cdd71c212.jpg b/upload/goodscats/2017-10/59e6cdd71c212.jpg new file mode 100755 index 0000000..758cb42 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cdd71c212.jpg differ diff --git a/upload/goodscats/2017-10/59e6cdfa60e91.jpg b/upload/goodscats/2017-10/59e6cdfa60e91.jpg new file mode 100755 index 0000000..0da8d42 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cdfa60e91.jpg differ diff --git a/upload/goodscats/2017-10/59e6ce23b41e3.jpg b/upload/goodscats/2017-10/59e6ce23b41e3.jpg new file mode 100755 index 0000000..2de1d7c Binary files /dev/null and b/upload/goodscats/2017-10/59e6ce23b41e3.jpg differ diff --git a/upload/goodscats/2017-10/59e6ce536eba2.jpg b/upload/goodscats/2017-10/59e6ce536eba2.jpg new file mode 100755 index 0000000..5bd8b02 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ce536eba2.jpg differ diff --git a/upload/goodscats/2017-10/59e6ce8864259.jpg b/upload/goodscats/2017-10/59e6ce8864259.jpg new file mode 100755 index 0000000..21f2fa1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ce8864259.jpg differ diff --git a/upload/goodscats/2017-10/59e6ceae510dc.jpg b/upload/goodscats/2017-10/59e6ceae510dc.jpg new file mode 100755 index 0000000..d4d73b4 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ceae510dc.jpg differ diff --git a/upload/goodscats/2017-10/59e6cec96e527.jpg b/upload/goodscats/2017-10/59e6cec96e527.jpg new file mode 100755 index 0000000..fd1b4eb Binary files /dev/null and b/upload/goodscats/2017-10/59e6cec96e527.jpg differ diff --git a/upload/goodscats/2017-10/59e6cef36a97e.jpg b/upload/goodscats/2017-10/59e6cef36a97e.jpg new file mode 100755 index 0000000..c9a376e Binary files /dev/null and b/upload/goodscats/2017-10/59e6cef36a97e.jpg differ diff --git a/upload/goodscats/2017-10/59e6cf16ab282.jpg b/upload/goodscats/2017-10/59e6cf16ab282.jpg new file mode 100755 index 0000000..4d822c9 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cf16ab282.jpg differ diff --git a/upload/goodscats/2017-10/59e6cf531dac9.jpg b/upload/goodscats/2017-10/59e6cf531dac9.jpg new file mode 100755 index 0000000..d3b8066 Binary files /dev/null and b/upload/goodscats/2017-10/59e6cf531dac9.jpg differ diff --git a/upload/goodscats/2017-10/59e6d01a5a672.jpg b/upload/goodscats/2017-10/59e6d01a5a672.jpg new file mode 100755 index 0000000..f8c134c Binary files /dev/null and b/upload/goodscats/2017-10/59e6d01a5a672.jpg differ diff --git a/upload/goodscats/2017-10/59e6d0305ecc2.jpg b/upload/goodscats/2017-10/59e6d0305ecc2.jpg new file mode 100755 index 0000000..82b0f53 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d0305ecc2.jpg differ diff --git a/upload/goodscats/2017-10/59e6d0521c303.jpg b/upload/goodscats/2017-10/59e6d0521c303.jpg new file mode 100755 index 0000000..36e1d6e Binary files /dev/null and b/upload/goodscats/2017-10/59e6d0521c303.jpg differ diff --git a/upload/goodscats/2017-10/59e6d076e0ad5.jpg b/upload/goodscats/2017-10/59e6d076e0ad5.jpg new file mode 100755 index 0000000..4e442a2 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d076e0ad5.jpg differ diff --git a/upload/goodscats/2017-10/59e6d0a4def34.jpg b/upload/goodscats/2017-10/59e6d0a4def34.jpg new file mode 100755 index 0000000..6c0a016 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d0a4def34.jpg differ diff --git a/upload/goodscats/2017-10/59e6d0f0d58b4.jpg b/upload/goodscats/2017-10/59e6d0f0d58b4.jpg new file mode 100755 index 0000000..4e13eb7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d0f0d58b4.jpg differ diff --git a/upload/goodscats/2017-10/59e6d10f57a5d.jpg b/upload/goodscats/2017-10/59e6d10f57a5d.jpg new file mode 100755 index 0000000..7016970 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d10f57a5d.jpg differ diff --git a/upload/goodscats/2017-10/59e6d126a8d43.jpg b/upload/goodscats/2017-10/59e6d126a8d43.jpg new file mode 100755 index 0000000..c9153be Binary files /dev/null and b/upload/goodscats/2017-10/59e6d126a8d43.jpg differ diff --git a/upload/goodscats/2017-10/59e6d13d71b07.jpg b/upload/goodscats/2017-10/59e6d13d71b07.jpg new file mode 100755 index 0000000..1a30225 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d13d71b07.jpg differ diff --git a/upload/goodscats/2017-10/59e6d1884ce51.jpg b/upload/goodscats/2017-10/59e6d1884ce51.jpg new file mode 100755 index 0000000..22ea9f7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d1884ce51.jpg differ diff --git a/upload/goodscats/2017-10/59e6d1c179356.jpg b/upload/goodscats/2017-10/59e6d1c179356.jpg new file mode 100755 index 0000000..096eec9 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d1c179356.jpg differ diff --git a/upload/goodscats/2017-10/59e6d1ee3855c.jpg b/upload/goodscats/2017-10/59e6d1ee3855c.jpg new file mode 100755 index 0000000..25a0b4c Binary files /dev/null and b/upload/goodscats/2017-10/59e6d1ee3855c.jpg differ diff --git a/upload/goodscats/2017-10/59e6d22379da4.jpg b/upload/goodscats/2017-10/59e6d22379da4.jpg new file mode 100755 index 0000000..d517d40 Binary files /dev/null and b/upload/goodscats/2017-10/59e6d22379da4.jpg differ diff --git a/upload/goodscats/2017-10/59e6f81b1f215.jpg b/upload/goodscats/2017-10/59e6f81b1f215.jpg new file mode 100755 index 0000000..c1f7369 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f81b1f215.jpg differ diff --git a/upload/goodscats/2017-10/59e6f8426ef76.jpg b/upload/goodscats/2017-10/59e6f8426ef76.jpg new file mode 100755 index 0000000..de3b8d1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f8426ef76.jpg differ diff --git a/upload/goodscats/2017-10/59e6f85b11761.jpg b/upload/goodscats/2017-10/59e6f85b11761.jpg new file mode 100755 index 0000000..d1cf475 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f85b11761.jpg differ diff --git a/upload/goodscats/2017-10/59e6f876c3f79.jpg b/upload/goodscats/2017-10/59e6f876c3f79.jpg new file mode 100755 index 0000000..9e509c1 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f876c3f79.jpg differ diff --git a/upload/goodscats/2017-10/59e6f895ce664.jpg b/upload/goodscats/2017-10/59e6f895ce664.jpg new file mode 100755 index 0000000..eb93fe6 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f895ce664.jpg differ diff --git a/upload/goodscats/2017-10/59e6f8b13c0c4.jpg b/upload/goodscats/2017-10/59e6f8b13c0c4.jpg new file mode 100755 index 0000000..b54b3ff Binary files /dev/null and b/upload/goodscats/2017-10/59e6f8b13c0c4.jpg differ diff --git a/upload/goodscats/2017-10/59e6f8c99c1b2.jpg b/upload/goodscats/2017-10/59e6f8c99c1b2.jpg new file mode 100755 index 0000000..2e77443 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f8c99c1b2.jpg differ diff --git a/upload/goodscats/2017-10/59e6f8e2f21e5.jpg b/upload/goodscats/2017-10/59e6f8e2f21e5.jpg new file mode 100755 index 0000000..e805499 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f8e2f21e5.jpg differ diff --git a/upload/goodscats/2017-10/59e6f8fd15cdd.jpg b/upload/goodscats/2017-10/59e6f8fd15cdd.jpg new file mode 100755 index 0000000..75febc7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f8fd15cdd.jpg differ diff --git a/upload/goodscats/2017-10/59e6f91136363.jpg b/upload/goodscats/2017-10/59e6f91136363.jpg new file mode 100755 index 0000000..658dc1b Binary files /dev/null and b/upload/goodscats/2017-10/59e6f91136363.jpg differ diff --git a/upload/goodscats/2017-10/59e6f92d263c4.jpg b/upload/goodscats/2017-10/59e6f92d263c4.jpg new file mode 100755 index 0000000..ea704eb Binary files /dev/null and b/upload/goodscats/2017-10/59e6f92d263c4.jpg differ diff --git a/upload/goodscats/2017-10/59e6f94ac7159.jpg b/upload/goodscats/2017-10/59e6f94ac7159.jpg new file mode 100755 index 0000000..d184a9c Binary files /dev/null and b/upload/goodscats/2017-10/59e6f94ac7159.jpg differ diff --git a/upload/goodscats/2017-10/59e6f9846e491.jpg b/upload/goodscats/2017-10/59e6f9846e491.jpg new file mode 100755 index 0000000..7daeba7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f9846e491.jpg differ diff --git a/upload/goodscats/2017-10/59e6f9b95de18.jpg b/upload/goodscats/2017-10/59e6f9b95de18.jpg new file mode 100755 index 0000000..17ff494 Binary files /dev/null and b/upload/goodscats/2017-10/59e6f9b95de18.jpg differ diff --git a/upload/goodscats/2017-10/59e6fa05e58ba.jpg b/upload/goodscats/2017-10/59e6fa05e58ba.jpg new file mode 100755 index 0000000..058a8ea Binary files /dev/null and b/upload/goodscats/2017-10/59e6fa05e58ba.jpg differ diff --git a/upload/goodscats/2017-10/59e6fa1daa76d.jpg b/upload/goodscats/2017-10/59e6fa1daa76d.jpg new file mode 100755 index 0000000..16d2f66 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fa1daa76d.jpg differ diff --git a/upload/goodscats/2017-10/59e6fb435985e.jpg b/upload/goodscats/2017-10/59e6fb435985e.jpg new file mode 100755 index 0000000..c3195fb Binary files /dev/null and b/upload/goodscats/2017-10/59e6fb435985e.jpg differ diff --git a/upload/goodscats/2017-10/59e6fb8b607cd.jpg b/upload/goodscats/2017-10/59e6fb8b607cd.jpg new file mode 100755 index 0000000..1cac113 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fb8b607cd.jpg differ diff --git a/upload/goodscats/2017-10/59e6fc71c7d11.jpg b/upload/goodscats/2017-10/59e6fc71c7d11.jpg new file mode 100755 index 0000000..434708b Binary files /dev/null and b/upload/goodscats/2017-10/59e6fc71c7d11.jpg differ diff --git a/upload/goodscats/2017-10/59e6fc8791e7b.jpg b/upload/goodscats/2017-10/59e6fc8791e7b.jpg new file mode 100755 index 0000000..ac43bf3 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fc8791e7b.jpg differ diff --git a/upload/goodscats/2017-10/59e6fca6290df.jpg b/upload/goodscats/2017-10/59e6fca6290df.jpg new file mode 100755 index 0000000..de0379c Binary files /dev/null and b/upload/goodscats/2017-10/59e6fca6290df.jpg differ diff --git a/upload/goodscats/2017-10/59e6fcbc3d263.jpg b/upload/goodscats/2017-10/59e6fcbc3d263.jpg new file mode 100755 index 0000000..879e2d5 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fcbc3d263.jpg differ diff --git a/upload/goodscats/2017-10/59e6fcd638349.jpg b/upload/goodscats/2017-10/59e6fcd638349.jpg new file mode 100755 index 0000000..7eede77 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fcd638349.jpg differ diff --git a/upload/goodscats/2017-10/59e6fd2266fc2.jpg b/upload/goodscats/2017-10/59e6fd2266fc2.jpg new file mode 100755 index 0000000..fd0581c Binary files /dev/null and b/upload/goodscats/2017-10/59e6fd2266fc2.jpg differ diff --git a/upload/goodscats/2017-10/59e6fd44dc061.jpg b/upload/goodscats/2017-10/59e6fd44dc061.jpg new file mode 100755 index 0000000..24d302d Binary files /dev/null and b/upload/goodscats/2017-10/59e6fd44dc061.jpg differ diff --git a/upload/goodscats/2017-10/59e6fd60d2cea.jpg b/upload/goodscats/2017-10/59e6fd60d2cea.jpg new file mode 100755 index 0000000..e27e8ce Binary files /dev/null and b/upload/goodscats/2017-10/59e6fd60d2cea.jpg differ diff --git a/upload/goodscats/2017-10/59e6fda5f10b4.jpg b/upload/goodscats/2017-10/59e6fda5f10b4.jpg new file mode 100755 index 0000000..da240aa Binary files /dev/null and b/upload/goodscats/2017-10/59e6fda5f10b4.jpg differ diff --git a/upload/goodscats/2017-10/59e6fdcb63432.jpg b/upload/goodscats/2017-10/59e6fdcb63432.jpg new file mode 100755 index 0000000..2bc2068 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fdcb63432.jpg differ diff --git a/upload/goodscats/2017-10/59e6fdee43fde.jpg b/upload/goodscats/2017-10/59e6fdee43fde.jpg new file mode 100755 index 0000000..f8c8fff Binary files /dev/null and b/upload/goodscats/2017-10/59e6fdee43fde.jpg differ diff --git a/upload/goodscats/2017-10/59e6fe2db0c63.jpg b/upload/goodscats/2017-10/59e6fe2db0c63.jpg new file mode 100755 index 0000000..cdb965a Binary files /dev/null and b/upload/goodscats/2017-10/59e6fe2db0c63.jpg differ diff --git a/upload/goodscats/2017-10/59e6fe4e69ecd.jpg b/upload/goodscats/2017-10/59e6fe4e69ecd.jpg new file mode 100755 index 0000000..ab859ee Binary files /dev/null and b/upload/goodscats/2017-10/59e6fe4e69ecd.jpg differ diff --git a/upload/goodscats/2017-10/59e6fe6cb4447.jpg b/upload/goodscats/2017-10/59e6fe6cb4447.jpg new file mode 100755 index 0000000..6cd2af7 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fe6cb4447.jpg differ diff --git a/upload/goodscats/2017-10/59e6febdf36e4.jpg b/upload/goodscats/2017-10/59e6febdf36e4.jpg new file mode 100755 index 0000000..664a035 Binary files /dev/null and b/upload/goodscats/2017-10/59e6febdf36e4.jpg differ diff --git a/upload/goodscats/2017-10/59e6fef434a47.jpg b/upload/goodscats/2017-10/59e6fef434a47.jpg new file mode 100755 index 0000000..905ff01 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fef434a47.jpg differ diff --git a/upload/goodscats/2017-10/59e6ff3b7dc93.jpg b/upload/goodscats/2017-10/59e6ff3b7dc93.jpg new file mode 100755 index 0000000..cd82f9b Binary files /dev/null and b/upload/goodscats/2017-10/59e6ff3b7dc93.jpg differ diff --git a/upload/goodscats/2017-10/59e6ff5a7ef75.jpg b/upload/goodscats/2017-10/59e6ff5a7ef75.jpg new file mode 100755 index 0000000..7502763 Binary files /dev/null and b/upload/goodscats/2017-10/59e6ff5a7ef75.jpg differ diff --git a/upload/goodscats/2017-10/59e6ffb2af2bc.jpg b/upload/goodscats/2017-10/59e6ffb2af2bc.jpg new file mode 100755 index 0000000..946ed9a Binary files /dev/null and b/upload/goodscats/2017-10/59e6ffb2af2bc.jpg differ diff --git a/upload/goodscats/2017-10/59e6fffa1bac8.jpg b/upload/goodscats/2017-10/59e6fffa1bac8.jpg new file mode 100755 index 0000000..8f6e235 Binary files /dev/null and b/upload/goodscats/2017-10/59e6fffa1bac8.jpg differ diff --git a/upload/goodscats/2017-10/59e9a01ba0afa.jpg b/upload/goodscats/2017-10/59e9a01ba0afa.jpg new file mode 100755 index 0000000..b6e6b63 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a01ba0afa.jpg differ diff --git a/upload/goodscats/2017-10/59e9a0a521a03.jpg b/upload/goodscats/2017-10/59e9a0a521a03.jpg new file mode 100755 index 0000000..2a4b92a Binary files /dev/null and b/upload/goodscats/2017-10/59e9a0a521a03.jpg differ diff --git a/upload/goodscats/2017-10/59e9a0c6a2e03.jpg b/upload/goodscats/2017-10/59e9a0c6a2e03.jpg new file mode 100755 index 0000000..94c4a7d Binary files /dev/null and b/upload/goodscats/2017-10/59e9a0c6a2e03.jpg differ diff --git a/upload/goodscats/2017-10/59e9a1c04e8c4.jpg b/upload/goodscats/2017-10/59e9a1c04e8c4.jpg new file mode 100755 index 0000000..9ffcd34 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a1c04e8c4.jpg differ diff --git a/upload/goodscats/2017-10/59e9a1e9acf8b.jpg b/upload/goodscats/2017-10/59e9a1e9acf8b.jpg new file mode 100755 index 0000000..e825044 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a1e9acf8b.jpg differ diff --git a/upload/goodscats/2017-10/59e9a21b1afc3.jpg b/upload/goodscats/2017-10/59e9a21b1afc3.jpg new file mode 100755 index 0000000..71d8197 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a21b1afc3.jpg differ diff --git a/upload/goodscats/2017-10/59e9a23eeaa3c.jpg b/upload/goodscats/2017-10/59e9a23eeaa3c.jpg new file mode 100755 index 0000000..7c2ca15 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a23eeaa3c.jpg differ diff --git a/upload/goodscats/2017-10/59e9a27eebda4.jpg b/upload/goodscats/2017-10/59e9a27eebda4.jpg new file mode 100755 index 0000000..b0b8871 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a27eebda4.jpg differ diff --git a/upload/goodscats/2017-10/59e9a2d7e0ed9.jpg b/upload/goodscats/2017-10/59e9a2d7e0ed9.jpg new file mode 100755 index 0000000..9bf1974 Binary files /dev/null and b/upload/goodscats/2017-10/59e9a2d7e0ed9.jpg differ diff --git a/upload/goodscats/2017-10/59e9a2f666c89.jpg b/upload/goodscats/2017-10/59e9a2f666c89.jpg new file mode 100755 index 0000000..d2b68ec Binary files /dev/null and b/upload/goodscats/2017-10/59e9a2f666c89.jpg differ diff --git a/upload/goodscats/2017-10/59e9a34f205cd.jpg b/upload/goodscats/2017-10/59e9a34f205cd.jpg new file mode 100755 index 0000000..e69de29 diff --git a/upload/image/2018-03/5aab3f29b3b05.png b/upload/image/2018-03/5aab3f29b3b05.png new file mode 100755 index 0000000..ad58a14 Binary files /dev/null and b/upload/image/2018-03/5aab3f29b3b05.png differ diff --git a/upload/image/txt.txt b/upload/image/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/image/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/shopcats/2018-05/5b066ff25b90e.png b/upload/shopcats/2018-05/5b066ff25b90e.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shopcats/2018-05/5b066ff25b90e.png differ diff --git a/upload/shopcats/2018-05/5b0670267958c.png b/upload/shopcats/2018-05/5b0670267958c.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shopcats/2018-05/5b0670267958c.png differ diff --git a/upload/shopcats/2018-05/5b06705699065.png b/upload/shopcats/2018-05/5b06705699065.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/shopcats/2018-05/5b06705699065.png differ diff --git a/upload/shopconfigs/2017-11/5a0a93ef6d4ef.jpg b/upload/shopconfigs/2017-11/5a0a93ef6d4ef.jpg new file mode 100755 index 0000000..0af3efe Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a93ef6d4ef.jpg differ diff --git a/upload/shopconfigs/2017-11/5a0a93ef801bc.jpg b/upload/shopconfigs/2017-11/5a0a93ef801bc.jpg new file mode 100755 index 0000000..51dde3d Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a93ef801bc.jpg differ diff --git a/upload/shopconfigs/2017-11/5a0a93f08e488.jpg b/upload/shopconfigs/2017-11/5a0a93f08e488.jpg new file mode 100755 index 0000000..ac22775 Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a93f08e488.jpg differ diff --git a/upload/shopconfigs/2017-11/5a0a96398bb5c.png b/upload/shopconfigs/2017-11/5a0a96398bb5c.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a96398bb5c.png differ diff --git a/upload/shopconfigs/2017-11/5a0a96655eaae.jpg b/upload/shopconfigs/2017-11/5a0a96655eaae.jpg new file mode 100755 index 0000000..ce62b3c Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a96655eaae.jpg differ diff --git a/upload/shopconfigs/2017-11/5a0a968c13093.jpg b/upload/shopconfigs/2017-11/5a0a968c13093.jpg new file mode 100755 index 0000000..ac22775 Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a968c13093.jpg differ diff --git a/upload/shopconfigs/2017-11/5a0a96ab01e3c.png b/upload/shopconfigs/2017-11/5a0a96ab01e3c.png new file mode 100755 index 0000000..55fb9ba Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a96ab01e3c.png differ diff --git a/upload/shopconfigs/2017-11/5a0a96baa08e3.png b/upload/shopconfigs/2017-11/5a0a96baa08e3.png new file mode 100755 index 0000000..12a6ca1 Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a96baa08e3.png differ diff --git a/upload/shopconfigs/2017-11/5a0a96cbe045e.png b/upload/shopconfigs/2017-11/5a0a96cbe045e.png new file mode 100755 index 0000000..de9e23a Binary files /dev/null and b/upload/shopconfigs/2017-11/5a0a96cbe045e.png differ diff --git a/upload/shopconfigs/2017-12/5a28cfb56c52f.png b/upload/shopconfigs/2017-12/5a28cfb56c52f.png new file mode 100755 index 0000000..323d660 Binary files /dev/null and b/upload/shopconfigs/2017-12/5a28cfb56c52f.png differ diff --git a/upload/shopconfigs/2017-12/5a28d0240fdfe.png b/upload/shopconfigs/2017-12/5a28d0240fdfe.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shopconfigs/2017-12/5a28d0240fdfe.png differ diff --git a/upload/shopconfigs/2017-12/5a28d0522e4dc.png b/upload/shopconfigs/2017-12/5a28d0522e4dc.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shopconfigs/2017-12/5a28d0522e4dc.png differ diff --git a/upload/shopconfigs/2017-12/5a28d05254a2d.jpg b/upload/shopconfigs/2017-12/5a28d05254a2d.jpg new file mode 100755 index 0000000..b2f45e4 Binary files /dev/null and b/upload/shopconfigs/2017-12/5a28d05254a2d.jpg differ diff --git a/upload/shopconfigs/2018-01/5a5eff5de7289.png b/upload/shopconfigs/2018-01/5a5eff5de7289.png new file mode 100755 index 0000000..ad58a14 Binary files /dev/null and b/upload/shopconfigs/2018-01/5a5eff5de7289.png differ diff --git a/upload/shopconfigs/2018-01/5a62d5956cc82.jpg b/upload/shopconfigs/2018-01/5a62d5956cc82.jpg new file mode 100755 index 0000000..a0a31f0 Binary files /dev/null and b/upload/shopconfigs/2018-01/5a62d5956cc82.jpg differ diff --git a/upload/shopconfigs/2018-01/5a62d66a9616b.png b/upload/shopconfigs/2018-01/5a62d66a9616b.png new file mode 100755 index 0000000..d0f146a Binary files /dev/null and b/upload/shopconfigs/2018-01/5a62d66a9616b.png differ diff --git a/upload/shopconfigs/2018-02/5a8fcba25b5d8.png b/upload/shopconfigs/2018-02/5a8fcba25b5d8.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shopconfigs/2018-02/5a8fcba25b5d8.png differ diff --git a/upload/shopconfigs/txt.txt b/upload/shopconfigs/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/shopconfigs/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/shops/2017-09/59cd9a10e43bd.png b/upload/shops/2017-09/59cd9a10e43bd.png new file mode 100755 index 0000000..f0acea7 Binary files /dev/null and b/upload/shops/2017-09/59cd9a10e43bd.png differ diff --git a/upload/shops/2017-09/59cd9a161a828.png b/upload/shops/2017-09/59cd9a161a828.png new file mode 100755 index 0000000..2728c85 Binary files /dev/null and b/upload/shops/2017-09/59cd9a161a828.png differ diff --git a/upload/shops/2017-09/59cf00fad4587.jpg b/upload/shops/2017-09/59cf00fad4587.jpg new file mode 100755 index 0000000..20c6d39 Binary files /dev/null and b/upload/shops/2017-09/59cf00fad4587.jpg differ diff --git a/upload/shops/2017-09/59cf0147a9ba9.jpg b/upload/shops/2017-09/59cf0147a9ba9.jpg new file mode 100755 index 0000000..20c6d39 Binary files /dev/null and b/upload/shops/2017-09/59cf0147a9ba9.jpg differ diff --git a/upload/shops/2017-09/59cf06e25ace3.jpg b/upload/shops/2017-09/59cf06e25ace3.jpg new file mode 100755 index 0000000..a825759 Binary files /dev/null and b/upload/shops/2017-09/59cf06e25ace3.jpg differ diff --git a/upload/shops/2017-09/59cf0a6d6a97c.jpg b/upload/shops/2017-09/59cf0a6d6a97c.jpg new file mode 100755 index 0000000..b2fcf28 Binary files /dev/null and b/upload/shops/2017-09/59cf0a6d6a97c.jpg differ diff --git a/upload/shops/2017-09/59cf37485ca44.jpg b/upload/shops/2017-09/59cf37485ca44.jpg new file mode 100755 index 0000000..fb8bab0 Binary files /dev/null and b/upload/shops/2017-09/59cf37485ca44.jpg differ diff --git a/upload/shops/2017-11/5a1e74b6dee3c.png b/upload/shops/2017-11/5a1e74b6dee3c.png new file mode 100755 index 0000000..de3f494 Binary files /dev/null and b/upload/shops/2017-11/5a1e74b6dee3c.png differ diff --git a/upload/shops/2017-11/5a1e74ba111f8.png b/upload/shops/2017-11/5a1e74ba111f8.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2017-11/5a1e74ba111f8.png differ diff --git a/upload/shops/2017-11/5a1e74be4b49b.png b/upload/shops/2017-11/5a1e74be4b49b.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2017-11/5a1e74be4b49b.png differ diff --git a/upload/shops/2017-11/5a1e74c75e752.png b/upload/shops/2017-11/5a1e74c75e752.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shops/2017-11/5a1e74c75e752.png differ diff --git a/upload/shops/2017-11/5a1e754eb0e9f.png b/upload/shops/2017-11/5a1e754eb0e9f.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2017-11/5a1e754eb0e9f.png differ diff --git a/upload/shops/2017-11/5a1e755227c13.png b/upload/shops/2017-11/5a1e755227c13.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2017-11/5a1e755227c13.png differ diff --git a/upload/shops/2017-11/5a1f6178edb46.png b/upload/shops/2017-11/5a1f6178edb46.png new file mode 100755 index 0000000..ba8dd63 Binary files /dev/null and b/upload/shops/2017-11/5a1f6178edb46.png differ diff --git a/upload/shops/2017-11/5a1f617e1a59b.png b/upload/shops/2017-11/5a1f617e1a59b.png new file mode 100755 index 0000000..ba8dd63 Binary files /dev/null and b/upload/shops/2017-11/5a1f617e1a59b.png differ diff --git a/upload/shops/2017-11/5a1f6180a50ee.png b/upload/shops/2017-11/5a1f6180a50ee.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/shops/2017-11/5a1f6180a50ee.png differ diff --git a/upload/shops/2017-11/5a1f618375006.png b/upload/shops/2017-11/5a1f618375006.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2017-11/5a1f618375006.png differ diff --git a/upload/shops/2017-11/5a1f61868b047.png b/upload/shops/2017-11/5a1f61868b047.png new file mode 100755 index 0000000..eed473f Binary files /dev/null and b/upload/shops/2017-11/5a1f61868b047.png differ diff --git a/upload/shops/2018-01/5a4ddb86aed34.png b/upload/shops/2018-01/5a4ddb86aed34.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shops/2018-01/5a4ddb86aed34.png differ diff --git a/upload/shops/2018-01/5a4ddb8b7bddf.jpg b/upload/shops/2018-01/5a4ddb8b7bddf.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/shops/2018-01/5a4ddb8b7bddf.jpg differ diff --git a/upload/shops/2018-01/5a4ddb91221a6.png b/upload/shops/2018-01/5a4ddb91221a6.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2018-01/5a4ddb91221a6.png differ diff --git a/upload/shops/2018-01/5a4ddb9f40d17.png b/upload/shops/2018-01/5a4ddb9f40d17.png new file mode 100755 index 0000000..17ffa58 Binary files /dev/null and b/upload/shops/2018-01/5a4ddb9f40d17.png differ diff --git a/upload/shops/2018-01/5a5998244960d.jpg b/upload/shops/2018-01/5a5998244960d.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/shops/2018-01/5a5998244960d.jpg differ diff --git a/upload/shops/2018-01/5a5998293d3d9.jpg b/upload/shops/2018-01/5a5998293d3d9.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/shops/2018-01/5a5998293d3d9.jpg differ diff --git a/upload/shops/2018-01/5a59982ea5cef.jpg b/upload/shops/2018-01/5a59982ea5cef.jpg new file mode 100755 index 0000000..2873db5 Binary files /dev/null and b/upload/shops/2018-01/5a59982ea5cef.jpg differ diff --git a/upload/shops/2018-01/5a5998390e961.jpg b/upload/shops/2018-01/5a5998390e961.jpg new file mode 100755 index 0000000..f632689 Binary files /dev/null and b/upload/shops/2018-01/5a5998390e961.jpg differ diff --git a/upload/shops/2018-01/5a59984c9f259.png b/upload/shops/2018-01/5a59984c9f259.png new file mode 100755 index 0000000..10b8351 Binary files /dev/null and b/upload/shops/2018-01/5a59984c9f259.png differ diff --git a/upload/shops/2018-01/5a599ce95841c.png b/upload/shops/2018-01/5a599ce95841c.png new file mode 100755 index 0000000..aabd50b Binary files /dev/null and b/upload/shops/2018-01/5a599ce95841c.png differ diff --git a/upload/shops/2018-02/5a8fcb88830b3.png b/upload/shops/2018-02/5a8fcb88830b3.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/shops/2018-02/5a8fcb88830b3.png differ diff --git a/upload/shops/2018-02/5a93a4d93028f.jpg b/upload/shops/2018-02/5a93a4d93028f.jpg new file mode 100755 index 0000000..caf5199 Binary files /dev/null and b/upload/shops/2018-02/5a93a4d93028f.jpg differ diff --git a/upload/shops/2018-02/5a93a4df5a7b8.jpg b/upload/shops/2018-02/5a93a4df5a7b8.jpg new file mode 100755 index 0000000..caf5199 Binary files /dev/null and b/upload/shops/2018-02/5a93a4df5a7b8.jpg differ diff --git a/upload/shops/2018-02/5a93a4e4c2516.jpg b/upload/shops/2018-02/5a93a4e4c2516.jpg new file mode 100755 index 0000000..caf5199 Binary files /dev/null and b/upload/shops/2018-02/5a93a4e4c2516.jpg differ diff --git a/upload/shops/2018-02/5a93a4e85c8fb.jpg b/upload/shops/2018-02/5a93a4e85c8fb.jpg new file mode 100755 index 0000000..caf5199 Binary files /dev/null and b/upload/shops/2018-02/5a93a4e85c8fb.jpg differ diff --git a/upload/shops/2018-02/5a93a5118b85f.jpg b/upload/shops/2018-02/5a93a5118b85f.jpg new file mode 100755 index 0000000..caf5199 Binary files /dev/null and b/upload/shops/2018-02/5a93a5118b85f.jpg differ diff --git a/upload/shops/code.jpg b/upload/shops/code.jpg new file mode 100755 index 0000000..c9727af Binary files /dev/null and b/upload/shops/code.jpg differ diff --git a/upload/shops/txt.txt b/upload/shops/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/shops/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/staffs/2015-04/55306cf76bc1f.jpg b/upload/staffs/2015-04/55306cf76bc1f.jpg new file mode 100755 index 0000000..5751b0b Binary files /dev/null and b/upload/staffs/2015-04/55306cf76bc1f.jpg differ diff --git a/upload/staffs/txt.txt b/upload/staffs/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/staffs/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/sysconfigs/2016-10/58048008993ed.png b/upload/sysconfigs/2016-10/58048008993ed.png new file mode 100755 index 0000000..f9759dd Binary files /dev/null and b/upload/sysconfigs/2016-10/58048008993ed.png differ diff --git a/upload/sysconfigs/2016-10/5804800d5841e.png b/upload/sysconfigs/2016-10/5804800d5841e.png new file mode 100755 index 0000000..5f95121 Binary files /dev/null and b/upload/sysconfigs/2016-10/5804800d5841e.png differ diff --git a/upload/sysconfigs/2016-10/5804802a4b162.png b/upload/sysconfigs/2016-10/5804802a4b162.png new file mode 100755 index 0000000..5751b0b Binary files /dev/null and b/upload/sysconfigs/2016-10/5804802a4b162.png differ diff --git a/upload/sysconfigs/2016-10/580480413c986.png b/upload/sysconfigs/2016-10/580480413c986.png new file mode 100755 index 0000000..5f60dc7 Binary files /dev/null and b/upload/sysconfigs/2016-10/580480413c986.png differ diff --git a/upload/sysconfigs/2016-10/txt.txt b/upload/sysconfigs/2016-10/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/sysconfigs/2016-10/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/sysconfigs/2017-09/59aa1656b6663.png b/upload/sysconfigs/2017-09/59aa1656b6663.png new file mode 100755 index 0000000..f0acea7 Binary files /dev/null and b/upload/sysconfigs/2017-09/59aa1656b6663.png differ diff --git a/upload/sysconfigs/2017-09/59aa168e7aa18.png b/upload/sysconfigs/2017-09/59aa168e7aa18.png new file mode 100755 index 0000000..f0acea7 Binary files /dev/null and b/upload/sysconfigs/2017-09/59aa168e7aa18.png differ diff --git a/upload/sysconfigs/2017-09/59aa1692acbd0.png b/upload/sysconfigs/2017-09/59aa1692acbd0.png new file mode 100755 index 0000000..2728c85 Binary files /dev/null and b/upload/sysconfigs/2017-09/59aa1692acbd0.png differ diff --git a/upload/sysconfigs/2017-09/59aa1699746fb.png b/upload/sysconfigs/2017-09/59aa1699746fb.png new file mode 100755 index 0000000..2728c85 Binary files /dev/null and b/upload/sysconfigs/2017-09/59aa1699746fb.png differ diff --git a/upload/sysconfigs/2017-09/59af629c60a10.png b/upload/sysconfigs/2017-09/59af629c60a10.png new file mode 100755 index 0000000..035c1ba Binary files /dev/null and b/upload/sysconfigs/2017-09/59af629c60a10.png differ diff --git a/upload/sysconfigs/2017-09/59b78cee28f3a.png b/upload/sysconfigs/2017-09/59b78cee28f3a.png new file mode 100755 index 0000000..05473b6 Binary files /dev/null and b/upload/sysconfigs/2017-09/59b78cee28f3a.png differ diff --git a/upload/sysconfigs/2017-09/59cf639360829.png b/upload/sysconfigs/2017-09/59cf639360829.png new file mode 100755 index 0000000..a5fea97 Binary files /dev/null and b/upload/sysconfigs/2017-09/59cf639360829.png differ diff --git a/upload/sysconfigs/2017-09/59cf63982a196.png b/upload/sysconfigs/2017-09/59cf63982a196.png new file mode 100755 index 0000000..03f3047 Binary files /dev/null and b/upload/sysconfigs/2017-09/59cf63982a196.png differ diff --git a/upload/sysconfigs/2017-09/59cf639d04108.png b/upload/sysconfigs/2017-09/59cf639d04108.png new file mode 100755 index 0000000..6c87c5a Binary files /dev/null and b/upload/sysconfigs/2017-09/59cf639d04108.png differ diff --git a/upload/sysconfigs/2017-09/59cf63a11ef51.png b/upload/sysconfigs/2017-09/59cf63a11ef51.png new file mode 100755 index 0000000..631e0f6 Binary files /dev/null and b/upload/sysconfigs/2017-09/59cf63a11ef51.png differ diff --git a/upload/sysconfigs/2017-09/59cf63a6024fc.png b/upload/sysconfigs/2017-09/59cf63a6024fc.png new file mode 100755 index 0000000..792c8e8 Binary files /dev/null and b/upload/sysconfigs/2017-09/59cf63a6024fc.png differ diff --git a/upload/sysconfigs/app.jpg b/upload/sysconfigs/app.jpg new file mode 100755 index 0000000..843e784 Binary files /dev/null and b/upload/sysconfigs/app.jpg differ diff --git a/upload/sysconfigs/txt.txt b/upload/sysconfigs/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/sysconfigs/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/temp/2018-02/5a7ffad3eeebb.xls b/upload/temp/2018-02/5a7ffad3eeebb.xls new file mode 100755 index 0000000..6924943 Binary files /dev/null and b/upload/temp/2018-02/5a7ffad3eeebb.xls differ diff --git a/upload/temp/2018-02/5a7ffb5f286cc.xls b/upload/temp/2018-02/5a7ffb5f286cc.xls new file mode 100755 index 0000000..33e54c4 Binary files /dev/null and b/upload/temp/2018-02/5a7ffb5f286cc.xls differ diff --git a/upload/temp/txt.txt b/upload/temp/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/temp/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/userranks/2016-09/57edd6ae5d8b8.png b/upload/userranks/2016-09/57edd6ae5d8b8.png new file mode 100755 index 0000000..381fba4 Binary files /dev/null and b/upload/userranks/2016-09/57edd6ae5d8b8.png differ diff --git a/upload/userranks/2016-09/57edd6d446b75.png b/upload/userranks/2016-09/57edd6d446b75.png new file mode 100755 index 0000000..2668b14 Binary files /dev/null and b/upload/userranks/2016-09/57edd6d446b75.png differ diff --git a/upload/userranks/2016-09/57edd6efc8757.png b/upload/userranks/2016-09/57edd6efc8757.png new file mode 100755 index 0000000..df1a981 Binary files /dev/null and b/upload/userranks/2016-09/57edd6efc8757.png differ diff --git a/upload/userranks/2016-09/57edd70cbd0f5.png b/upload/userranks/2016-09/57edd70cbd0f5.png new file mode 100755 index 0000000..e3f9038 Binary files /dev/null and b/upload/userranks/2016-09/57edd70cbd0f5.png differ diff --git a/upload/userranks/txt.txt b/upload/userranks/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/userranks/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/upload/users/txt.txt b/upload/users/txt.txt new file mode 100755 index 0000000..7552221 --- /dev/null +++ b/upload/users/txt.txt @@ -0,0 +1,8 @@ +/************************************************ + * * + * * + * Powered by wstmart * + * ԸĿ¼Ȩ޷ϴͼƬ * + * * + * * + ****************************** ***************** \ No newline at end of file diff --git a/vendor/.htaccess b/vendor/.htaccess new file mode 100755 index 0000000..3e63591 --- /dev/null +++ b/vendor/.htaccess @@ -0,0 +1,4 @@ +<FilesMatch (.*)\.(html|php)$> +order allow,deny +deny from all +</FilesMatch> \ No newline at end of file diff --git a/vendor/5ini99/think-addons/.gitignore b/vendor/5ini99/think-addons/.gitignore new file mode 100755 index 0000000..5f28270 --- /dev/null +++ b/vendor/5ini99/think-addons/.gitignore @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/5ini99/think-addons/LICENSE.txt b/vendor/5ini99/think-addons/LICENSE.txt new file mode 100755 index 0000000..574a39c --- /dev/null +++ b/vendor/5ini99/think-addons/LICENSE.txt @@ -0,0 +1,32 @@ + +ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 +版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) +All rights reserved。 +ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 + +Apache Licence是著名的非盈利开源组织Apache采用的协议。 +该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, +允许代码修改,再作为开源或商业软件发布。需要满足 +的条件: +1. 需要给代码的用户一份Apache Licence ; +2. 如果你修改了代码,需要在被修改的文件中说明; +3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 +带有原来代码中的协议,商标,专利声明和其他原来作者规 +定需要包含的说明; +4. 如果再发布的产品中包含一个Notice文件,则在Notice文 +件中需要带有本协议内容。你可以在Notice中增加自己的 +许可,但不可以表现为对Apache Licence构成更改。 +具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/5ini99/think-addons/README.md b/vendor/5ini99/think-addons/README.md new file mode 100755 index 0000000..ff3c4e8 --- /dev/null +++ b/vendor/5ini99/think-addons/README.md @@ -0,0 +1,190 @@ +# think-addons +The ThinkPHP5 Addons Package + +## 安装 +> composer require 5ini99/think-addons + +## 配置 +### 公共配置 +``` +'addons'=>[ + // 可以定义多个钩子 + 'testhook'=>'test' // 键为钩子名称,用于在业务中自定义钩子处理,值为实现该钩子的插件, + // 多个插件可以用数组也可以用逗号分割 +] +``` + +## 创建插件 +> 创建的插件可以在view视图中使用,也可以在php业务中使用 + +安装完成后访问系统时会在项目根目录生成名为`addons`的目录,在该目录中创建需要的插件。 + +下面写一个例子: + +### 创建test插件 +> 在addons目录中创建test目录 + +### 创建钩子实现类 +> 在test目录中创建Test.php类文件。注意:类文件首字母需大写 + +``` +<?php +namespace addons\test; // 注意命名空间规范 + +use think\addons\Addons; + +/** + * 插件测试 + * @author byron sampson + */ +class Test extends Addons // 需继承think\addons\Addons类 +{ + // 该插件的基础信息 + public $info = [ + 'name' => 'test', // 插件标识 + 'title' => '插件测试', // 插件名称 + 'description' => 'thinkph5插件测试', // 插件简介 + 'status' => 0, // 状态 + 'author' => 'byron sampson', + 'version' => '0.1' + ]; + + /** + * 插件安装方法 + * @return bool + */ + public function install() + { + return true; + } + + /** + * 插件卸载方法 + * @return bool + */ + public function uninstall() + { + return true; + } + + /** + * 实现的testhook钩子方法 + * @return mixed + */ + public function testhook($param) + { + // 调用钩子时候的参数信息 + print_r($param); + // 当前插件的配置信息,配置信息存在当前目录的config.php文件中,见下方 + print_r($this->getConfig()); + // 可以返回模板,模板文件默认读取的为插件目录中的文件。模板名不能为空! + return $this->fetch('info'); + } + +} +``` + +### 创建插件配置文件 +> 在test目录中创建config.php类文件,插件配置文件可以省略。 + +``` +<?php +return [ + 'display' => [ + 'title' => '是否显示:', + 'type' => 'radio', + 'options' => [ + '1' => '显示', + '0' => '不显示' + ], + 'value' => '1' + ] +]; +``` + +### 创建钩子模板文件 +> 在test目录中创建info.html模板文件,钩子在使用fetch方法时对应的模板文件。 + +``` +<h1>hello tpl</h1> + +如果插件中需要有链接或提交数据的业务,可以在插件中创建controller业务文件, +要访问插件中的controller时使用addon_url生成url链接。 +如下: +<a href="{:addon_url('test://Action/link')}">link test</a> +格式为: +test为插件名,Action为controller中的类名,link为controller中的方法 +``` + +### 创建插件的controller文件 +> 在test目录中创建controller目录,在controller目录中创建Action.php文件 +> controller类的用法与tp5中的controller一致 + +``` +<?php +namespace addons\test\controller; + +class Action +{ + public function link() + { + echo 'hello link'; + } +} +``` +> 如果需要使用view模板则需要继承`\think\addons\Controller`类 +> 模板文件所在位置为插件目录的view中,规则与模块中的view规则一致 + +``` +<?php +namespace addons\test\controller; + +use think\addons\Controller; + +class Action extends Controller +{ + public function link() + { + return $this->fetch(); + } +} +``` + +## 使用钩子 +> 创建好插件后就可以在正常业务中使用该插件中的钩子了 +> 使用钩子的时候第二个参数可以省略 + +### 模板中使用钩子 + +``` +<div>{:hook('testhook', ['id'=>1])}</div> +``` + +### php业务中使用 +> 只要是thinkphp5正常流程中的任意位置均可以使用 + +``` +hook('testhook', ['id'=>1]) +``` + +## 插件目录结构 +### 最终生成的目录结构为 + +``` +tp5 + - addons + -- test + --- controller + ---- Action.php + --- view + ---- action + ----- link.html + --- config.php + --- info.html + --- Test.php + - application + - thinkphp + - extend + - vendor + - public +``` diff --git a/vendor/5ini99/think-addons/composer.json b/vendor/5ini99/think-addons/composer.json new file mode 100755 index 0000000..89355d0 --- /dev/null +++ b/vendor/5ini99/think-addons/composer.json @@ -0,0 +1,28 @@ +{ + "name": "5ini99/think-addons", + "description": "addons package for thinkphp5", + "homepage": "https://github.com/5ini99/think-addons", + "license": "Apache-2.0", + "minimum-stability": "stable", + "version": "1.2.0", + "authors": [ + { + "name": "xiaobo.sun", + "email": "xiaobo.sun@qq.com" + } + ], + "support": { + "issues": "https://github.com/5ini99/think-addons/issues" + }, + "require": { + "php": ">=5.4.0" + }, + "autoload": { + "psr-4": { + "think\\addons\\": "src/" + }, + "files": [ + "src/helper.php" + ] + } +} diff --git a/vendor/5ini99/think-addons/src/Addons.php b/vendor/5ini99/think-addons/src/Addons.php new file mode 100755 index 0000000..a3efc5a --- /dev/null +++ b/vendor/5ini99/think-addons/src/Addons.php @@ -0,0 +1,202 @@ +<?php + +namespace think\addons; + +use think\Config; +use think\View; +use think\Db; + +/** + * 插件基类 + * Class Addons + * @author Byron Sampson <xiaobo.sun@qq.com> + * @package think\addons + */ +abstract class Addons{ + /** + * 视图实例对象 + * @var view + * @access protected + */ + protected $view = null; + + // 当前错误信息 + protected $error; + + /** + * $info = [ + * 'name' => 'Test', + * 'title' => '测试插件', + * 'description' => '用于WSTMart的插件扩展演示', + * 'status' => 1, + * 'author' => 'WSTMart', + * 'version' => '1.0.1' + * ] + */ + public $info = []; + public $addons_path = ''; + public $config_file = ''; + + /** + * 架构函数 + * @access public + */ + public function __construct() + { + // 获取当前插件目录 + $this->addons_path = ADDON_PATH . $this->getName() . DS; + // 读取当前插件配置信息 + if (is_file($this->addons_path . 'config.php')) { + $this->config_file = $this->addons_path . 'config.php'; + } + + // 初始化视图模型 + $config = ['view_path' => $this->addons_path]; + $config = array_merge(Config::get('template'), $config); + $this->view = new View($config, Config::get('view_replace_str')); + + // 控制器初始化 + if (method_exists($this, '_initialize')) { + $this->_initialize(); + } + } + + /** + * 获取插件的配置数组 + * @param string $name 可选模块名 + * @return array|mixed|null + */ + final public function getConfig($name = '') + { + static $_config = array(); + if (empty($name)) { + $name = $this->getName(); + } + if (isset($_config[$name])) { + return $_config[$name]; + } + $map['name'] = $name; + $map['status'] = 1; + $config = []; + if (is_file($this->config_file)) { + $temp_arr = include $this->config_file; + foreach ($temp_arr as $key => $value) { + if ($value['type'] == 'group') { + foreach ($value['options'] as $gkey => $gvalue) { + foreach ($gvalue['options'] as $ikey => $ivalue) { + $config[$ikey] = $ivalue['value']; + } + } + } else { + $config[$key] = $temp_arr[$key]['value']; + } + } + unset($temp_arr); + } + $_config[$name] = $config; + + return $config; + } + + /** + * 获取当前模块名 + * @return string + */ + final public function getName(){ + $data = explode('\\', get_class($this)); + return strtolower(array_pop($data)); + } + + /** + * 检查配置信息是否完整 + * @return bool + */ + final public function checkInfo(){ + $info_check_keys = ['name', 'title', 'description', 'status', 'author', 'version']; + foreach ($info_check_keys as $value) { + if (!array_key_exists($value, $this->info)) { + return false; + } + } + return true; + } + + /** + * 加载模板和页面输出 可以返回输出内容 + * @access public + * @param string $template 模板文件名或者内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 + * @return mixed + * @throws \Exception + */ + public function fetch($template = '', $vars = [], $replace = [], $config = []){ + if (!is_file($template)) { + $template = '/' . $template; + } + // 关闭模板布局 + $this->view->engine->layout(false); + + echo $this->view->fetch($template, $vars, $replace, $config); + } + + /** + * 渲染内容输出 + * @access public + * @param string $content 内容 + * @param array $vars 模板输出变量 + * @param array $replace 替换内容 + * @param array $config 模板参数 + * @return mixed + */ + public function display($content, $vars = [], $replace = [], $config = []){ + // 关闭模板布局 + $this->view->engine->layout(false); + echo $this->view->display($content, $vars, $replace, $config); + } + + /** + * 渲染内容输出 + * @access public + * @param string $content 内容 + * @param array $vars 模板输出变量 + * @return mixed + */ + public function show($content, $vars = []){ + // 关闭模板布局 + $this->view->engine->layout(false); + echo $this->view->fetch($content, $vars, [], [], true); + } + + /** + * 模板变量赋值 + * @access protected + * @param mixed $name 要显示的模板变量 + * @param mixed $value 变量的值 + * @return void + */ + public function assign($name, $value = ''){ + $this->view->assign($name, $value); + } + + /** + * 获取当前错误信息 + * @return mixed + */ + public function getError(){ + return $this->error; + } + + //必须实现安装 + abstract public function install(); + + //必须卸载插件方法 + abstract public function uninstall(); + + abstract public function enable(); + + abstract public function disable(); + + abstract public function saveConfig(); +} diff --git a/vendor/5ini99/think-addons/src/AddonsController.php b/vendor/5ini99/think-addons/src/AddonsController.php new file mode 100755 index 0000000..31eefe6 --- /dev/null +++ b/vendor/5ini99/think-addons/src/AddonsController.php @@ -0,0 +1,41 @@ +<?php + +namespace think\addons; + +use think\Hook; +use think\Request; + +/** + * 插件执行默认控制器 + * Class AddonsController + * @package think\addons + */ +class AddonsController extends Controller +{ + /** + * 插件执行 + */ + public function execute() + { + if (!empty($this->addon) && !empty($this->controller) && !empty($this->action)) { + // 获取类的命名空间 + $class = get_addon_class($this->addon, 'controller', $this->controller); + if (class_exists($class)) { + $model = new $class(); + if ($model === false) { + abort(500, lang('addon init fail')); + } + // 调用操作 + if (!method_exists($model, $this->action)) { + abort(500, lang('Controller Class Method Not Exists')); + } + // 监听addons_init + Hook::listen('addons_init', $this); + return call_user_func_array([$model, $this->action], [Request::instance()]); + } else { + abort(500, lang('Controller Class Not Exists')); + } + } + abort(500, lang('addon cannot name or action')); + } +} diff --git a/vendor/5ini99/think-addons/src/BaseModel.php b/vendor/5ini99/think-addons/src/BaseModel.php new file mode 100755 index 0000000..5c949da --- /dev/null +++ b/vendor/5ini99/think-addons/src/BaseModel.php @@ -0,0 +1,88 @@ +<?php + +namespace think\addons; +use think\Db; + +/** + * 插件基类服务器 + * Class Model + * @package think\addons + */ +class BaseModel extends \think\Model{ + /** + * 获取插件配置内容 + */ + public function getConf($addonsName){ + $data = cache('ADDONS_'.$addonsName); + if(!$data){ + $rs = Db::name('addons')->where('name',$addonsName)->field('config')->find(); + $data = json_decode($rs['config'],true); + cache('ADDONS_'.$addonsName,$data,31622400); + } + return $data; + } + + public function getAddonStatus($addonsName){ + $rs = Db::name('addons')->where('name',$addonsName)->field('status')->find(); + return (int)$rs["status"]; + } + /** + * 获取空模型 + */ + public function getEModel($tables){ + $rs = Db::query('show columns FROM `'.config('database.prefix').$tables."`"); + $obj = []; + if($rs){ + foreach($rs as $key => $v) { + $obj[$v['Field']] = $v['Default']; + if($v['Key'] == 'PRI')$obj[$v['Field']] = 0; + } + } + return $obj; + } + + /** + * 绑定勾子 + * @param 插件名 $addonName + * @param 勾子数组 $hooks + */ + public function bindHoods($addonName,$hooks){ + $list = Db::name('hooks')->where("name","in",$hooks)->field(["hookId","name","addons"])->select(); + for($i=0,$k=count($list);$i<$k;$i++){ + $hook = $list[$i]; + $objs = explode(",",$hook["addons"]); + $objs = array_filter($objs); + if(!in_array($addonName,$objs)){ + $addons = $addonName; + if(!empty($objs)){ + $objs[] = $addonName; + $addons = implode(",",$objs); + } + Db::name('hooks')->where(["hookId"=>$hook["hookId"]])->update(["addons"=>$addons]); + } + } + } + + /** + * 解绑勾子 + * @param 插件名 $addonName + * @param 勾子数组 $hooks + */ + public function unbindHoods($addonName,$hooks){ + + $list = Db::name('hooks')->where("name","in",$hooks)->field(["hookId","name","addons"])->select(); + for($i=0,$k=count($list);$i<$k;$i++){ + $hook = $list[$i]; + $objs = explode(",",$hook["addons"]); + $temps = array(); + for($m=0,$n=count($objs);$m<$n;$m++){ + if($objs[$m]!=$addonName){ + $temps[] = $objs[$m]; + } + } + $addons = implode(",",$temps); + Db::name('hooks')->where(["hookId"=>$hook["hookId"]])->update(["addons"=>$addons]); + } + } + +} diff --git a/vendor/5ini99/think-addons/src/Controller.php b/vendor/5ini99/think-addons/src/Controller.php new file mode 100755 index 0000000..27610d8 --- /dev/null +++ b/vendor/5ini99/think-addons/src/Controller.php @@ -0,0 +1,270 @@ +<?php + +namespace think\addons; + +use think\Request; +use think\Config; +use think\Loader; + +/** + * 插件基类控制器 + * Class Controller + * @package think\addons + */ +class Controller extends \think\Controller +{ + // 当前插件操作 + protected $addon = null; + protected $controller = null; + protected $action = null; + // 当前template + protected $template; + // 模板配置信息 + protected $config = [ + 'type' => 'Think', + 'view_path' => '', + 'view_suffix' => 'html', + 'strip_space' => true, + 'view_depr' => DS, + 'tpl_begin' => '{', + 'tpl_end' => '}', + 'taglib_begin' => '{', + 'taglib_end' => '}', + ]; + + /** + * 架构函数 + * @param Request $request Request对象 + * @access public + */ + public function __construct(Request $request = null) + { + WSTConf('CONF.seoMallSwitch'); + if(WSTConf('CONF.seoMallSwitch')==0){ + $this->redirect('home/switchs/index'); + exit; + } + // 生成request对象 + $this->request = is_null($request) ? Request::instance() : $request; + // 初始化配置信息 + $this->config = Config::get('template') ?: $this->config; + // 处理路由参数 + $route = $this->request->param('route', ''); + $param = explode('-', $route); + // 是否自动转换控制器和操作名 + $convert = \think\Config::get('url_convert'); + if('wechat/weixinpays/toaddonpay' != $this->request->path()){ + // 格式化路由的插件位置 + $this->action = $convert ? strtolower(array_pop($param)) : array_pop($param); + $this->controller = $convert ? strtolower(array_pop($param)) : array_pop($param); + $this->addon = $convert ? strtolower(array_pop($param)) : array_pop($param); + $base = new \think\addons\BaseModel(); + $status = $base->getAddonStatus(ucfirst($this->addon)); + if(isset($status) && $status!=1){ + $request = request(); + $module = WSTVisitModule(); + header("Location:".url($module.'/error/message')); + exit(); + } + } + // 生成view_path + $view_path = $this->config['view_path'] ?: 'view'; + + // 重置配置 + Config::set('template.view_path', ADDON_PATH . $this->addon . DS . $view_path . DS); + $this->checkPrivileges(); + parent::__construct($request); + $this->assign("v",WSTConf('CONF.wstVersion')."_".WSTConf('CONF.wsthomeStyleId')); + $this->initLayout(); + } + /** + * 定义模板 + */ + public function initLayout(){ + $wsthomeStyle = WSTConf('CONF.wsthomeStyle')?WSTConf('CONF.wsthomeStyle'):'default'; + $wstmobileStyle = WSTConf('CONF.wstmobileStyle')?WSTConf('CONF.wstmobileStyle'):'default'; + $wstwechatStyle = WSTConf('CONF.wstwechatStyle')?WSTConf('CONF.wstwechatStyle'):'default'; + $this->assign('LAYOUT_HOME_BASE','home@'.$wsthomeStyle.'/base'); + $this->assign('LAYOUT_HOME_TOP','home@'.$wsthomeStyle.'/top'); + $this->assign('LAYOUT_HOME_HEADER','home@'.$wsthomeStyle.'/header'); + $this->assign('LAYOUT_HOME_SHOP_APPLY','home@'.$wsthomeStyle.'/shop_apply'); + $this->assign('LAYOUT_HOME_RIGHT_CART','home@'.$wsthomeStyle.'/right_cart'); + $this->assign('LAYOUT_HOME_FOOTER','home@'.$wsthomeStyle.'/footer'); + $this->assign('LAYOUT_HOME_SHOP_BASE','home@'.$wsthomeStyle.'/shops/base'); + $this->assign('LAYOUT_HOME_SHOP_HEADER','home@'.$wsthomeStyle.'/shops/header'); + $this->assign('LAYOUT_HOME_USER_BASE','home@'.$wsthomeStyle.'/users/base'); + $this->assign('LAYOUT_HOME_USER_HEADER','home@'.$wsthomeStyle.'/users/header'); + + $this->assign('LAYOUT_ADMIN_BASE','admin@base'); + + $this->assign('LAYOUT_MOBILE_BASE','mobile@'.$wstmobileStyle.'/base'); + $this->assign('LAYOUT_MOBILE_DIALOG','mobile@'.$wstmobileStyle.'/dialog'); + $this->assign('LAYOUT_MOBILE_FOOTER','mobile@'.$wstmobileStyle.'/footer'); + + $this->assign('LAYOUT_WECHAT_BASE','wechat@'.$wstwechatStyle.'/base'); + $this->assign('LAYOUT_WECHAT_DIALOG','wechat@'.$wstwechatStyle.'/dialog'); + $this->assign('LAYOUT_WECHAT_FOOTER','wechat@'.$wstwechatStyle.'/footer'); + } + /** + * @deprecated 建议使用 checkAuth和checkShopAuth区分商家 2017.04.25 + */ + public function checkPrivileges(){ + $urls = model('home/HomeMenus')->getMenusUrl(); + $request = request(); + $visit = strtolower($request->path()); + if(isset($urls[$visit])){ + $menuType = (int)$urls[$visit]; + $userType = -1; + if((int)session('WST_USER.userId')>0)$userType = 0; + if((int)session('WST_USER.shopId')>0)$userType = 1; + //未登录不允许访问受保护的资源 + if($userType==-1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您还没有登录,请先登录']); + }else{ + header("Location:".url('home/users/login')); + } + exit(); + } + //已登录但不是商家 则不允许访问受保护的商家资源 + if($userType==0 && $menuType==1){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您不是商家,请先申请为商家再访问']); + }else{ + header("Location:".url('home/shops/login')); + } + exit(); + } + } + } + public function checkAdminAuth(){ + $STAFF = session('WST_STAFF'); + $request = request(); + if(empty($STAFF)){ + if($request->isAjax()){ + echo json_encode(['status'=>-999,'msg'=>'对不起,您还没有登录,请先登录']); + }else{ + header("Location:".url('admin/index/login')); + } + exit(); + }else{ + $urls = WSTVisitPrivilege(); + $privileges = session('WST_STAFF.privileges'); + $visit = $request->path(); + if(!$privileges || (array_key_exists($visit,$urls) && !$this->checkUserCode($urls[$visit],$privileges))){ + if($request->isAjax()){ + echo json_encode(['status'=>-998,'msg'=>'对不起,您没有操作权限,请与管理员联系']); + }else{ + header("Content-type: text/html; charset=utf-8"); + echo "对不起,您没有操作权限,请与管理员联系"; + } + exit(); + } + } + } + private function checkUserCode($urlCodes,$userCodes){ + foreach ($urlCodes as $key => $value) { + if(in_array($key,$userCodes))return true; + } + return false; + } + /** + * @deprecated 建议使用checkAdminAuth,将来可能会移除. 2017.04.25 + */ + public function checkAdminPrivileges(){ + $this->checkAdminAuth(); + } + // 登录验证方法--用户 + protected function checkAuth(){ + $USER = session('WST_USER'); + if(empty($USER)){ + if(request()->isAjax()){ + die('{"status":-999,"msg":"您还未登录"}'); + }else{ + $module = WSTVisitModule(); + $this->redirect($module.'/users/login'); + exit; + } + } + } + //登录验证方法--商家 + protected function checkShopAuth(){ + $USER = session('WST_USER'); + if(empty($USER) || $USER['userType']!=1){ + if(request()->isAjax()){ + die('{"status":-998,"msg":"您还未登录"}'); + }else{ + $module = WSTVisitModule(); + $this->redirect($module.'/shops/login'); + exit; + } + } + } + /** + * 重写父类前置方法判断 + */ + protected function beforeAction($method, $options = []) + { + // 设置当前访问的controller、action + request()->controller($this->controller); + request()->action($this->action); + if (isset($options['only'])) { + if (is_string($options['only'])) { + $options['only'] = explode(',', $options['only']); + } + if (!in_array($this->request->action(), $options['only'])) { + return; + } + } elseif (isset($options['except'])) { + if (is_string($options['except'])) { + $options['except'] = explode(',', $options['except']); + } + if (in_array($this->request->action(), $options['except'])) { + return; + } + } + + call_user_func([$this, $method]); + } + + + /** + * 加载模板输出 + * @access protected + * @param string $template 模板文件名 + * @param array $vars 模板输出变量 + * @param array $replace 模板替换 + * @param array $config 模板参数 + * @return mixed + */ + public function fetch($template = '', $vars = [], $replace = [], $config = []){ + $controller = Loader::parseName($this->controller); + if ('think' == strtolower($this->config['type']) && $controller && 0 !== strpos($template, '/')) { + $depr = $this->config['view_depr']; + $template = str_replace(['/', ':'], $depr, $template); + if ('' == $template) { + // 如果模板文件名为空 按照默认规则定位 + $template = str_replace('.', DS, $controller) . $depr . $this->action; + } elseif (false === strpos($template, $depr)) { + $template = str_replace('.', DS, $controller) . $depr . $template; + } + } + $replace['__STYLE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/home/view/'.WSTConf('CONF.wsthomeStyle'); + $replace['__ADMIN__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/admin/view'; + $replace['__WECHAT__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/wechat/view/'.WSTConf('CONF.wstwechatStyle');; + $replace['__MOBILE__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/hyhproject/mobile/view/default'; + return \Think\Controller::fetch($template, $vars, $replace, $config); + } + + /** + * 模板变量赋值 + * @access protected + * @param mixed $name 要显示的模板变量 + * @param mixed $value 变量的值 + * @return void + */ + public function assign($name, $value = ''){ + $this->view->assign($name, $value); + } + +} diff --git a/vendor/5ini99/think-addons/src/helper.php b/vendor/5ini99/think-addons/src/helper.php new file mode 100755 index 0000000..ef8dea4 --- /dev/null +++ b/vendor/5ini99/think-addons/src/helper.php @@ -0,0 +1,207 @@ +<?php +use think\Hook; +use think\Config; +use think\Loader; +use think\Db; + +// 插件目录 +define('ADDON_PATH', ROOT_PATH . 'addons' . DS); +// 定义路由 +\think\Route::any('addon/:route', "\\think\\addons\\AddonsController@execute"); +// 如果插件目录不存在则创建 +if (!is_dir(ADDON_PATH)) { + @mkdir(ADDON_PATH, 0777, true); +} + +// 注册类的根命名空间 +\think\Loader::addNamespace('addons', ADDON_PATH); + +// 闭包初始化行为 +Hook::add('app_begin', function () { + $hooks = cache('hooks'); + if(empty($hooks)){ + $addons = Db::name('hooks')->where("addons != ''")->column('name,addons'); + if(!empty($addons)){ + foreach ($addons as $key => $values) { + if($values){ + $map['status'] = 1; + $names = explode(',',$values); + $map['name'] = array('IN',$names); + $map['dataFlag'] = 1; + $data = model('common/addons')->where($map)->column('addonId,name'); + if($data){ + $data = array_intersect($names, $data); + $addons[$key] = array_filter(array_map('get_addon_class', $data)); + \think\Hook::add($key, $addons[$key]); + + } + } + } + array_filter($addons); + cache('hooks', $addons); + } + }else{ + foreach ($hooks as $key => $values) { + if(is_array($hooks[$key])){ + \think\Hook::add($key, $hooks[$key]); + } + } + } + get_addon_function(); +}); + + +/** + * 处理插件钩子 + * @param string $hook 钩子名称 + * @param mixed $params 传入参数 + * @return void + */ +function hook($hook, $params = []){ + \think\Hook::listen($hook, $params); +} +/** + * 加载插件函数 + */ +function get_addon_function(){ + $addonsrs = cache('WST_ADDONS'); + if(!$addonsrs){ + $addonsrs = model('common/addons')->where('status =1 and dataFlag = 1')->column('addonId,name'); + cache('WST_ADDONS',$addonsrs); + } + if(!empty($addonsrs)){ + $adds = []; + foreach ($addonsrs as $key => $value) { + $name = strtolower($value); + $adds[$name] = ['addonId'=>$key,'name'=>$name]; + if(is_file(ROOT_PATH.'addons'.DS.$name.DS.'common'.DS.'function.php')){ + include_once(ROOT_PATH.'addons'.DS.$name.DS.'common'.DS.'function.php'); + } + } + WSTConf('WST_ADDONS',$adds); + } +} + +/** + * 获取插件类的类名 + * @param $name 插件名 + * @param string $type 返回命名空间类型 + * @param string $class 当前类名 + * @return string + */ +function get_addon_class($name, $type = 'hook', $class = null){ + $name = \think\Loader::parseName($name); + // 处理多级控制器情况 + if (!is_null($class) && strpos($class, '.')) { + $class = explode('.', $class); + foreach ($class as $key => $cls) { + $class[$key] = \think\Loader::parseName($cls, 1); + } + $class = implode('\\', $class); + } else { + $class = \think\Loader::parseName(is_null($class) ? $name : $class, 1); + } + switch ($type) { + case 'controller': + $namespace = "\\addons\\" . $name . "\\controller\\" . $class; + break; + default: + $namespace = "\\addons\\" . $name . "\\" . $class; + } + + return class_exists($namespace) ? $namespace : ''; +} + +/** + * 获取插件类的配置文件数组 + * @param string $name 插件名 + * @return array + */ +function get_addon_config($name){ + $class = get_addon_class($name); + if (class_exists($class)) { + $addon = new $class(); + return $addon->getConfig(); + } else { + return []; + } +} + +/** + * 插件显示内容里生成访问插件的url + * @param $url + * @param array $param + * @return bool|string + * @param bool|string $suffix 生成的URL后缀 + * @param bool|string $domain 域名 + */ +function addon_url($url, $param = [], $suffix = true, $domain = false){ + $url = parse_url($url); + $case = config('url_convert'); + $addons = $case ? Loader::parseName($url['scheme']) : $url['scheme']; + $controller = $case ? Loader::parseName($url['host']) : $url['host']; + $action = trim($case ? strtolower($url['path']) : $url['path'], '/'); + + /* 解析URL带的参数 */ + if (isset($url['query'])) { + parse_str($url['query'], $query); + $param = array_merge($query, $param); + } + + // 生成插件链接新规则 + $actions = "{$addons}-{$controller}-{$action}"; + return url("/addon/{$actions}", $param, $suffix, $domain); +} + +/** + * 安装插件执行sql + */ +function installSql($name){ + $sqlfile = WSTRootPath()."/addons/".$name."/install.sql"; + if(file_exists($sqlfile)){ + $sql = file_get_contents($sqlfile); + excuteSql($sql,config('database')["prefix"]); + } + +} + +/** + * 卸载插件执行sql + */ +function uninstallSql($name){ + $sqlfile = WSTRootPath()."/addons/".$name."/uninstall.sql"; + if(file_exists($sqlfile)){ + $sql = file_get_contents($sqlfile); + excuteSql($sql,config('database')["prefix"]); + } +} + +/** + * 执行sql + * @param string $db_prefix + */ +function excuteSql($sql,$db_prefix=''){ + if(!isset($sql) || empty($sql)) return; + $sql = str_replace("\r", "\n", str_replace(' `wst_', ' `'.$db_prefix, $sql)); + $ret = array(); + $num = 0; + foreach(explode(";\n", trim($sql)) as $query) { + $ret[$num] = ''; + $queries = explode("\n", trim($query)); + foreach($queries as $query) { + $ret[$num] .= (isset($query[0]) && $query[0] == '#') || (isset($query[1]) && isset($query[1]) && $query[0].$query[1] == '--') ? '' : $query; + } + $num++; + } + unset($sql); + foreach($ret as $query){ + $query = trim($query); + if($query) { + if(strtoupper(substr($query, 0, 12)) == 'CREATE TABLE'){ + $type = strtoupper(preg_replace("/^\s*CREATE TABLE\s+.+\s+\(.+?\).*(ENGINE|TYPE)\s*=\s*([a-z]+?).*$/isU", "\\2", $query)); + $query = preg_replace("/^\s*(CREATE TABLE\s+.+\s+\(.+?\)).*$/isU", "\\1", $query)." ENGINE=InnoDB DEFAULT CHARSET=utf8"; + } + Db::execute($query); + } + } +} \ No newline at end of file diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100755 index 0000000..bd7104a --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ +<?php + +// autoload.php @generated by Composer + +require_once __DIR__ . '/composer/autoload_real.php'; + +return ComposerAutoloaderInit4a60a3f929aee1d857761bc886b5db35::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100755 index 0000000..ac67d30 --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,415 @@ +<?php + +/* + * This file is part of Composer. + * + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Jordi Boggiano <j.boggiano@seld.be> + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { + if (0 === strpos($class, $prefix)) { + foreach ($this->prefixDirsPsr4[$prefix] as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100755 index 0000000..1a28124 --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) 2016 Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100755 index 0000000..7a91153 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ +<?php + +// autoload_classmap.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100755 index 0000000..f48d33e --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,10 @@ +<?php + +// autoload_files.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + '23ae59697abb6e787d3c97263144d1be' => $vendorDir . '/5ini99/think-addons/src/helper.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100755 index 0000000..b7fc012 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ +<?php + +// autoload_namespaces.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/vendor/composer/autoload_psr.php b/vendor/composer/autoload_psr.php new file mode 100755 index 0000000..4284ef7 --- /dev/null +++ b/vendor/composer/autoload_psr.php @@ -0,0 +1,10 @@ +<?php + +// autoload_psr4.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'think\\addons\\' => array($vendorDir . '/5ini99/think-addons/src'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100755 index 0000000..4284ef7 --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,10 @@ +<?php + +// autoload_psr4.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'think\\addons\\' => array($vendorDir . '/5ini99/think-addons/src'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100755 index 0000000..637afe9 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ +<?php + +// autoload_real.php @generated by Composer + +class ComposerAutoloaderInit4a60a3f929aee1d857761bc886b5db35 +{ + private static $loader; + + public static function loadClassLoader($class) + { + if ('Composer\Autoload\ClassLoader' === $class) { + require __DIR__ . '/ClassLoader.php'; + } + } + + public static function getLoader() + { + if (null !== self::$loader) { + return self::$loader; + } + + spl_autoload_register(array('ComposerAutoloaderInit4a60a3f929aee1d857761bc886b5db35', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + spl_autoload_unregister(array('ComposerAutoloaderInit4a60a3f929aee1d857761bc886b5db35', 'loadClassLoader')); + + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit4a60a3f929aee1d857761bc886b5db35::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit4a60a3f929aee1d857761bc886b5db35::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire4a60a3f929aee1d857761bc886b5db35($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire4a60a3f929aee1d857761bc886b5db35($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100755 index 0000000..4314d2f --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,35 @@ +<?php + +// autoload_static.php @generated by Composer + +namespace Composer\Autoload; + +class ComposerStaticInit4a60a3f929aee1d857761bc886b5db35 +{ + public static $files = array ( + '23ae59697abb6e787d3c97263144d1be' => __DIR__ . '/..' . '/5ini99/think-addons/src/helper.php', + ); + + public static $prefixLengthsPsr4 = array ( + 't' => + array ( + 'think\\addons\\' => 13, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'think\\addons\\' => + array ( + 0 => __DIR__ . '/..' . '/5ini99/think-addons/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit4a60a3f929aee1d857761bc886b5db35::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit4a60a3f929aee1d857761bc886b5db35::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/oss-sdk/.coveralls.yml b/vendor/oss-sdk/.coveralls.yml new file mode 100755 index 0000000..850cc59 --- /dev/null +++ b/vendor/oss-sdk/.coveralls.yml @@ -0,0 +1,2 @@ +coverage_clover: coverage.xml +json_path: coverage.json diff --git a/vendor/oss-sdk/.gitignore b/vendor/oss-sdk/.gitignore new file mode 100755 index 0000000..7cdb514 --- /dev/null +++ b/vendor/oss-sdk/.gitignore @@ -0,0 +1,8 @@ +vendor +composer.lock +doc +output +.idea +.buildpath +.project +.settings diff --git a/vendor/oss-sdk/.travis.yml b/vendor/oss-sdk/.travis.yml new file mode 100755 index 0000000..0b40ba2 --- /dev/null +++ b/vendor/oss-sdk/.travis.yml @@ -0,0 +1,21 @@ +language: php +php: + - 7.1 + - 7.0 + - 5.6 + - 5.5 + - 5.4 +install: + - composer self-update + - composer install --no-interaction +script: + - php vendor/bin/phpunit +after_success: + - php vendor/bin/coveralls -v +env: + global: + - secure: SzmQ854lQmhV6ZkAG7lQNTY3CkazrXnDSb6VMwPU/sdaLGxPO159AW3fJS5d0sO/XN1P8x5WNkoA4i9soDlLBRibEEISNUM/2EMnpszsRymZ9o97PrS2IgORXTUL/OF+rpATzyNVB2p+2l9hBLiGf17exMSA5iOeY7W6E+VKPGi8TFykgbGUnLKU0h1hV3rzmtfGjOXcSpvYU/hxeZD/J/+6m5Gic9b/pNS+AbfTj7Y7Ru9tNsnyUP29V/vtEYtpQir3ZxQiSiUv9idybgGnJBOMYydJofb/mpFYHhYLSWqtMKGNLpeawmqs4z8S1Tvx5U5uzW5+h/mpzhvBaFlWGpm8t89BQxun5LVX5NiYCrV7TqaLitGp1cSpMjMDnrnSTNzk1exVz+rWZZcWS7yB9ULYA681GA8StXWk167qB7Y30iK1dFK3+2mDN2cEY+qLs8+bupDowQ4eOM+eqfhxX8F8+ouKcKomETsjiIwL+CUsIe6wjvnYFWb1YlRhbsI75bblHApflohnt6gVSJ78ZPqID+u2oUMjmIWXLTnRR2Y2tgEW8uqHeIoQ8BBntLdQDmv0BO4FpnGQIwrUUwQYeNzEM0DOr3hWZhyDR6Xvl+9H0l52xjANaSqpuTZfC3zmeFTG7kIjydvxNePRrony6XAawL9BvI7aKWuVF6YVjPM= + - secure: nEhsU8aUQqsAJeuger+boh51oTpeo4YNG7vUWbKxdwVDIrcLb+l7r7RvTlxU7mt8IZTWwicgri18mh+Wi04BwX4ulBA1SCs8jPbL51KEo5izoDGGtLSd2fuPHdslYSrwagrvq90EPnDT/7fHWn/TAoT+rueZzjNyCu5IGSgL3GnXaUThsJ82NMePL2YRdP4Q1qmtZPRFBOkOQ6F0heuV8fw8sLyTO3txaCQum9YneGxrWxOl/E8zB0qtlnPwLE8ogaHZMQh2/jThmTbI5UqwRTxV4f0qoD5eJYH+j0fslsSAjsg/HPnSuVcnccK3zSU+s2sV4dPCcISzECJvZEObwipfxOGhdqt5gMcxHhn8qVsbT97iIh106pG/BJCDgQd2EeVW8WfCi6cCuCKIMipvVkMypkmjQHWU1XaqPzILl7g5diW9Ctp2C4Akq5dYdrdu8IrnVK1ShtkQVaWU+S/Bht8VU5gYP7olPW/GdTz7sceU1NOIC4NPXqmWKbfavR98U5dkHMLMvzABYL1Q87h+KhPD1c14NUyw3YENUW7REiF/X5lERRm5H0kJ/1JqAa+AgeHQEGmPVuZV2s/na4b0S1479QRVmSM/6ZzXQpU+Y8jCRfETpUFA4S331369kirHgCqDlxyIntuEKrzivD02/O+5C3eJ0WHRz6QsN2/R4qg= + - secure: ZTvzNXEZP4efl+a/3VGMmdabfUQp83v5/lecMns039Ro7UuZYPdtbPtpPnpjaTI6Htd22A4Rva5BU/3JCQJAyQvpbKNn5sGou2SmfQu3o0SyhggSB7gWjYAf707aW1j4bHYfP8IjDS5NjuVk3AqXeNSUuLRUXRmwSOB0lSYiRhiTJY+pUdBl382Hx4NbhIU/gmOzRoJCs7coTip8IURXYEHPi5dnDWluajxI+TgNXFccSgEleeQDJajYgXmpLb2EhSj8piipOnVgaCEE5bh5fbp32024Qq38SGHKcbfnwj2IInpZpZESJknRKoqAlFjdOJhork82dBcvAr5JxCBZKx5IuwXcTjxkQ6tRtBeqhPLPFuX3MQ8WrtU+wniPM0RCH/VoFkUKO7JGQDwmoi2AKago4PsuDs4P6Y6CeuOVpcso731GwwMNhIJcyrJJivXprQNEGsEw+9wLjU1qNYs6IIA3S/gPzFrNbdX5Wf8vxt0vLpgYvBNtPnLMejMtknuyfVzf5iKuVVoGPDTEz+ajs06+jfoPfm/4sLTaLghuVH7Adm74OpF769JQNnQYKwJuu4bNlcbLJChulCEMBOx7myqo/9O6RCTuqzHaGmVWNot4RGqRFHgJGl/JJf0WpAVitbhbRH3kGoyKb6jFM74CJbPsE7OORlJLDC3cdD3C8Pk= + - secure: Qr5NR4CVzBKCQgRgMH0x772TPJ1+brx3UCvtRNu8fi4j3p8bz+HDMjBaBDSFmEB09nunLI55/8mj88/5GXmnpFs8+CPTkcW+QZOcxg3cxpI4SNmxoB12/ZawlFHAqSUaRRE7RUWVkY3KL8tIGjEZcFyUBQ1DVNX3OMpiKs3NLtHa7oUIknyBxdSokm4kpLhSXYe7WmO0vhuZbMZE0S1EISToiBS6AdhGUEbTLJ/vNsIDY07fu6+Vh3HxVbyUFPqUZGlkZpQ+2xMJ3kiqPBMrXtRF/IhhPjORDil6Ns9SQ8/AAlaCddvYvRaT4Pjv2/aX+t3l28qI1qmryPtWXpce5UXecWGYqdRpSJc6Y/pEt4m4FeeGoEFWnSPGIs7FRmeiis8q2rojGZ18i4vI/k4iHmqEBnTlMp3SWnRb9L1adJ8ZAWln8aC88gkQXm67w7+1CxLycerbYj9H1ugqHENuHcxv4uHUcZgEENX3EWatu8i9+K2IUuU/2zcmpu7qtsziYcoyW8DOOmYpJfXGMLtmF9+pqp/Tp6i0tltFSEfmY3N8o7xvv3enLvFHsjL+3ElFdd1blUPSrvZJHgA9M3lJ+QF1RJZCpJqgPlQ0XOZK1Bf4P46zpEj01wKaK4JQrkLPRXhbBOuIJn5O6WlFJyPX4+SaBfwTzb4AvM4aUg2TgTg= + - secure: Inw5ftA8fxvhMHRZwoZzATxn4WICJsCq7ZX4y2gI+b/8u0JQIsbLgY9WTYV+XdSxOoNwuVa1oUxEWI0aDORtXKC3XaIXXKrwndag0zxS77JEYwWvQsjM7BhEbF7MF7MYk8rRXpn6mbfGAT/NfqEOx91RCY8UKeMzD0oPkpkBnJ9Ekuod6JBBq+7j3v4mYUItA8pxvw7b4Pdd4z2xzjgOwNhJYMOCpts50DWZI+WXj0HvTYaMXe5mJJtORK5lsr0a9cbsBqAzE6l+3zGI8XkgHn130ux5XH3DE7hZBeti3ZNaO3d2Vv+496/1EObG0rSFk+z3dmNKqjMz4nh3bYIkdLMegwmgCWs2mvQhkwYhzmnPRHVSERrgZjSWnuKn2PKnBar6tui9KaLNgpo2j3jWpwMLJ3bGAfE5JtMppxAxNqj/q+YB2UZo7Mn7EDjkTDjgxCuazTJwWqH7xxCOykWPABBI17P3JaOXQJEK39LavpfSMm3kdmU0ocpUs7FniLuFm6xL71VxY1wHG10yskczEcFHZ3iyIyGM+xum4vbt5y6Yg+zfdExYQsbrxHDDZ3HbHY3tEU0WhM55vrC42NIXRWqXqJ8OAxpl4nivfx96eoBAThiUU9xXtZmh7WRFVYsstoGtxZwfk5+bi+oeVO9kih4xabwbgHgL9BTc1TR1C4U= diff --git a/vendor/oss-sdk/CHANGELOG.md b/vendor/oss-sdk/CHANGELOG.md new file mode 100755 index 0000000..f1c9270 --- /dev/null +++ b/vendor/oss-sdk/CHANGELOG.md @@ -0,0 +1,92 @@ +# ChangeLog - Aliyun OSS SDK for PHP + +## v2.3.0 / 2018-01-05 + +* Fixed: putObject support creating empty files +* Fixed: createBucket support IA/Archive +* Added: support restoreObject +* Added: support the Symlink feature +* Added: support getBucketLocation +* Added: support getBucketMeta +* Added: support proxy server Proxy + +## v2.2.4 / 2017-04-25 + +* Fixed getObject to local file bug + +## v2.2.3 / 2017-04-14 + +* Fixed md5 check + +## v2.2.2 / 2017-01-18 + +* Resolve to run the connection number and memory bug on php7 + +## v2.2.1 / 2016-12-01 + +* No HTTP curl is allowed to automatically populate accept-encoding + +## v2.2.0 / 2016-11-22 + +* Fixed PutObject/CompleteMultipartUpload return values(#26) + +## v2.1.0 / 2016-11-12 + +* Added[RTMP](https://help.aliyun.com/document_detail/44297.html)interface +* Add support[image service](https://help.aliyun.com/document_detail/44686.html) + +## v2.0.7 / 2016-06-17 + +* Support append object + +## v2.0.6 + +* Trim access key id/secret and endpoint +* Refine tests and setup travis CI + +## v2.0.5 + +* Added Add/Delete/Get BucketCname interface + +## v2.0.4 + +* Added Put/Get Object Acl interface + +## v2.0.3 + +* Fixing the constants in Util is defined in a PHP version that is less than 5.6. + +## v2.0.2 + +* The problem of content-type cannot be specified when restoring multipart uploads + +## v2.0.1 + +* Increase the ListObjects/ListMultipartUploads special characters +* Provides the interface to get the details of the OssException + + +## 2015.11.25 + +* **Large version upgrade, no longer compatible with previous interface, new version has made great improvements to ease of use, suggesting that users migrate to a new version.** + +## Modify the content + +* PHP 5.2 is no longer supported + +### Add the cotent + +* Introduce namespace +* Interface naming and modification, using hump naming +* The interface is modified, and the common parameters are extracted from the Options parameter. +* The interface returns the result modification, processing the return result, and the user can directly get the data structure easily processed  +* OssClient's constructor changes +* The Endpoint address that support CNAME and IP formats +* Rearrange the sample file organization structure and use function to organize the function points +* Add an interface that sets the connection timeout and requests timeout +* Remove the outdated interface associated with the Object Group +* The message in the OssException is changed to English + +### Repair problem + +* The object name is not complete diff --git a/vendor/oss-sdk/LICENSE.md b/vendor/oss-sdk/LICENSE.md new file mode 100755 index 0000000..3183de8 --- /dev/null +++ b/vendor/oss-sdk/LICENSE.md @@ -0,0 +1,21 @@ +#The MIT License (MIT) + +Copyright (c) ali-sdk and other contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/oss-sdk/README-CN.md b/vendor/oss-sdk/README-CN.md new file mode 100755 index 0000000..8c0cf84 --- /dev/null +++ b/vendor/oss-sdk/README-CN.md @@ -0,0 +1,149 @@ +# Aliyun OSS SDK for PHP + +[![Latest Stable Version](https://poser.pugx.org/aliyuncs/oss-sdk-php/v/stable)](https://packagist.org/packages/aliyuncs/oss-sdk-php) +[![Build Status](https://travis-ci.org/aliyun/aliyun-oss-php-sdk.svg?branch=master)](https://travis-ci.org/aliyun/aliyun-oss-php-sdk) +[![Coverage Status](https://coveralls.io/repos/github/aliyun/aliyun-oss-php-sdk/badge.svg?branch=master)](https://coveralls.io/github/aliyun/aliyun-oss-php-sdk?branch=master) + +## [README of English](https://github.com/aliyun/aliyun-oss-php-sdk/blob/master/README.md) + +## 概述 + +阿里云对象存储(Object Storage Service,简称OSS),是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。用户可以通过调用API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过用户Web控制台对数据进行简单的管理。OSS适合存放任意文件类型,适合各种网站、开发企业及开发者使用。 + + +## 运行环境 +- PHP 5.3+ +- cURL extension + +提示: + +- Ubuntu下可以使用apt-get包管理器安装php的cURL扩展 `sudo apt-get install php5-curl` + +## 安装方法 + +1. 如果您通过composer管理您的项目依赖,可以在你的项目根目录运行: + + $ composer require aliyuncs/oss-sdk-php + + 或者在你的`composer.json`中声明对Aliyun OSS SDK for PHP的依赖: + + "require": { + "aliyuncs/oss-sdk-php": "~2.0" + } + + 然后通过`composer install`安装依赖。composer安装完成后,在您的PHP代码中引入依赖即可: + + require_once __DIR__ . '/vendor/autoload.php'; + +2. 您也可以直接下载已经打包好的[phar文件][releases-page],然后在你 + 的代码中引入这个文件即可: + + require_once '/path/to/oss-sdk-php.phar'; + +3. 下载SDK源码,在您的代码中引入SDK目录下的`autoload.php`文件: + + require_once '/path/to/oss-sdk/autoload.php'; + +## 快速使用 + +### 常用类 + +| 类名 | 解释 | +|:------------------|:------------------------------------| +|OSS\OssClient | OSS客户端类,用户通过OssClient的实例调用接口 | +|OSS\Core\OssException | OSS异常类,用户在使用的过程中,只需要注意这个异常| + +### OssClient初始化 + +SDK的OSS操作通过OssClient类完成的,下面代码创建一个OssClient对象: + +```php +<?php +$accessKeyId = "<您从OSS获得的AccessKeyId>"; ; +$accessKeySecret = "<您从OSS获得的AccessKeySecret>"; +$endpoint = "<您选定的OSS数据中心访问域名,例如oss-cn-hangzhou.aliyuncs.com>"; +try { + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### 文件操作 + +文件(又称对象,Object)是OSS中最基本的数据单元,您可以把它简单地理解为文件,用下面代码可以实现一个Object的上传: + +```php +<?php +$bucket = "<您使用的Bucket名字,注意命名规范>"; +$object = "<您使用的Object名字,注意命名规范>"; +$content = "Hello, OSS!"; // 上传的文件内容 +try { + $ossClient->putObject($bucket, $object, $content); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### 存储空间操作 + +存储空间(又称Bucket)是一个用户用来管理所存储Object的存储空间,对于用户来说是一个管理Object的单元,所有的Object都必须隶属于某个Bucket。您可以按照下面的代码新建一个Bucket: + +```php +<?php +$bucket = "<您使用的Bucket名字,注意命名规范>"; +try { + $ossClient->createBucket($bucket); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### 返回结果处理 + +OssClient提供的接口返回返回数据分为两种: + +* Put,Delete类接口,接口返回null,如果没有OssException,即可认为操作成功 +* Get,List类接口,接口返回对应的数据,如果没有OssException,即可认为操作成功,举个例子: + +```php +<?php +$bucketListInfo = $ossClient->listBuckets(); +$bucketList = $bucketListInfo->getBucketList(); +foreach($bucketList as $bucket) { + print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); +} +``` +上面代码中的$bucketListInfo的数据类型是 `OSS\Model\BucketListInfo` + + +### 运行Sample程序 + +1. 修改 `samples/Config.php`, 补充配置信息 +2. 执行 `cd samples/ && php RunAll.php` + +### 运行单元测试 + +1. 执行`composer install`下载依赖的库 +2. 设置环境变量 + + export OSS_ACCESS_KEY_ID=access-key-id + export OSS_ACCESS_KEY_SECRET=access-key-secret + export OSS_ENDPOINT=endpoint + export OSS_BUCKET=bucket-name + +3. 执行 `php vendor/bin/phpunit` + +## License + +- MIT + +## 联系我们 + +- [阿里云OSS官方网站](http://oss.aliyun.com) +- [阿里云OSS官方论坛](http://bbs.aliyun.com) +- [阿里云OSS官方文档中心](http://www.aliyun.com/product/oss#Docs) +- 阿里云官方技术支持:[提交工单](https://workorder.console.aliyun.com/#/ticket/createIndex) + +[releases-page]: https://github.com/aliyun/aliyun-oss-php-sdk/releases +[phar-composer]: https://github.com/clue/phar-composer diff --git a/vendor/oss-sdk/README.md b/vendor/oss-sdk/README.md new file mode 100755 index 0000000..3c1da26 --- /dev/null +++ b/vendor/oss-sdk/README.md @@ -0,0 +1,150 @@ +# Alibaba Cloud OSS SDK for PHP + +[![Latest Stable Version](https://poser.pugx.org/aliyuncs/oss-sdk-php/v/stable)](https://packagist.org/packages/aliyuncs/oss-sdk-php) +[![Build Status](https://travis-ci.org/aliyun/aliyun-oss-php-sdk.svg?branch=master)](https://travis-ci.org/aliyun/aliyun-oss-php-sdk) +[![Coverage Status](https://coveralls.io/repos/github/aliyun/aliyun-oss-php-sdk/badge.svg?branch=master)](https://coveralls.io/github/aliyun/aliyun-oss-php-sdk?branch=master) + +## [README of Chinese](https://github.com/aliyun/aliyun-oss-php-sdk/blob/master/README-CN.md) + +## Overview + +Alibaba Cloud Object Storage Service (OSS) is a cloud storage service provided by Alibaba Cloud, featuring a massive capacity, security, a low cost, and high reliability. You can upload and download data on any application anytime and anywhere by calling APIs, and perform simple management of data through the web console. The OSS can store any type of files and therefore applies to various websites, development enterprises and developers. + + +## Run environment +- PHP 5.3+. +- cURL extension. + +Tips: + +- In Ubuntu, you can use the ***apt-get*** package manager to install the *PHP cURL extension*: `sudo apt-get install php5-curl`. + +## Install OSS PHP SDK + +- If you use the ***composer*** to manage project dependencies, run the following command in your project's root directory: + + composer require aliyuncs/oss-sdk-php + + You can also declare the dependency on Alibaba Cloud OSS SDK for PHP in the `composer.json` file. + + "require": { + "aliyuncs/oss-sdk-php": "~2.0" + } + + Then run `composer install` to install the dependency. After the Composer Dependency Manager is installed, import the dependency in your PHP code: + + require_once __DIR__ . '/vendor/autoload.php'; + +- You can also directly download the packaged [PHAR File][releases-page], and + introduce the file to your code: + + require_once '/path/to/oss-sdk-php.phar'; + +- Download the SDK source code, and introduce the `autoload.php` file under the SDK directory to your code: + + require_once '/path/to/oss-sdk/autoload.php'; + +## Quick use + +### Common classes + +| Class | Explanation | +|:------------------|:------------------------------------| +|OSS\OSSClient | OSS client class. An OSSClient instance can be used to call the interface. | +|OSS\Core\OSSException |OSS Exception class . You only need to pay attention to this exception when you use the OSSClient. | + +### Initialize an OSSClient + +The SDK's operations for the OSS are performed through the OSSClient class. The code below creates an OSSClient object: + +```php +<?php +$accessKeyId = "<AccessKeyID that you obtain from OSS>"; +$accessKeySecret = "<AccessKeySecret that you obtain from OSS>"; +$endpoint = "<Domain that you select to access an OSS data center, such as "oss-cn-hangzhou.aliyuncs.com>"; +try { + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### Operations on objects + +Objects are the most basic data units on the OSS. You can simply consider objects as files. The following code uploads an object: + +```php +<?php +$bucket= "<Name of the bucket in use. Pay attention to naming conventions>"; +$object = "<Name of the object in use. Pay attention to naming conventions>"; +$content = "Hello, OSS!"; // Content of the uploaded file +try { + $ossClient->putObject($bucket, $object, $content); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### Operations on buckets + +Buckets are the space that you use to manage the stored objects. It is an object management unit for users. Each object must belong to a bucket. You can create a bucket with the following code: + +```php +<?php +$bucket= "<Name of the bucket in use. Pay attention to naming conventions>"; +try { + $ossClient->createBucket($bucket); +} catch (OssException $e) { + print $e->getMessage(); +} +``` + +### Handle returned results + +The OSSClient provides the following two types of returned data from interfaces: + +- Put and Delete interfaces: The *PUT* and *DELETE* operations are deemed successful if *null* is returned by the interfaces without *OSSException*. +- Get and List interfaces: The *GET* and *LIST* operations are deemed successful if the desired data is returned by the interfaces without *OSSException*. For example, + + ```php + <?php + $bucketListInfo = $ossClient->listBuckets(); + $bucketList = $bucketListInfo->getBucketList(); + foreach($bucketList as $bucket) { + print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); + } + ``` +In the above code, $bucketListInfo falls into the 'OSS\Model\BucketListInfo' data type. + + +### Run a sample project + +- Modify `samples/Config.php` to complete the configuration information. +- Run `cd samples/ && php RunAll.php`. + +### Run a unit test + +- Run `composer install` to download the dependent libraries. +- Set the environment variable. + + export OSS_ACCESS_KEY_ID=access-key-id + export OSS_ACCESS_KEY_SECRET=access-key-secret + export OSS_ENDPOINT=endpoint + export OSS_BUCKET=bucket-name + +- Run `php vendor/bin/phpunit` + +## License + +- MIT + +## Contact us + +- [Alibaba Cloud OSS official website](http://oss.aliyun.com). +- [Alibaba Cloud OSS official forum](http://bbs.aliyun.com). +- [Alibaba Cloud OSS official documentation center](http://www.aliyun.com/product/oss#Docs). +- Alibaba Cloud official technical support: [Submit a ticket](https://workorder.console.aliyun.com/#/ticket/createIndex). + +[releases-page]: https://github.com/aliyun/aliyun-oss-php-sdk/releases +[phar-composer]: https://github.com/clue/phar-composer + diff --git a/vendor/oss-sdk/autoload.php b/vendor/oss-sdk/autoload.php new file mode 100755 index 0000000..ec13201 --- /dev/null +++ b/vendor/oss-sdk/autoload.php @@ -0,0 +1,11 @@ +<?php + +function classLoader($class) +{ + $path = str_replace('\\', DIRECTORY_SEPARATOR, $class); + $file = __DIR__ . DIRECTORY_SEPARATOR .'src'. DIRECTORY_SEPARATOR . $path . '.php'; + if (file_exists($file)) { + require_once $file; + } +} +spl_autoload_register('classLoader'); \ No newline at end of file diff --git a/vendor/oss-sdk/build-phar.sh b/vendor/oss-sdk/build-phar.sh new file mode 100755 index 0000000..ed4ae1a --- /dev/null +++ b/vendor/oss-sdk/build-phar.sh @@ -0,0 +1,13 @@ +#! /usr/bin/env bash + +# Remove dev deps to reduce phar size +rm -rf composer.lock vendor/ + +# Generate composer.lock +composer install --no-dev + +# Find SDK version +version=$(grep 'const OSS_VERSION' src/OSS/OssClient.php | grep -oE '[0-9.]+') + +# Build phar +phar-composer build . aliyun-oss-php-sdk-$version.phar diff --git a/vendor/oss-sdk/composer.json b/vendor/oss-sdk/composer.json new file mode 100755 index 0000000..1ecb58c --- /dev/null +++ b/vendor/oss-sdk/composer.json @@ -0,0 +1,24 @@ +{ + "name": "aliyuncs/oss-sdk-php", + "description": "Aliyun OSS SDK for PHP", + "homepage": "http://www.aliyun.com/product/oss/", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Aliyuncs", + "homepage": "http://www.aliyun.com" + } + ], + "require": { + "php":">=5.3" + }, + "require-dev" : { + "phpunit/phpunit": "~4.0", + "satooshi/php-coveralls": "~1.0" + }, + "minimum-stability": "stable", + "autoload": { + "psr-4": {"OSS\\": "src/OSS"} + } +} diff --git a/vendor/oss-sdk/example.jpg b/vendor/oss-sdk/example.jpg new file mode 100755 index 0000000..ffd46a2 Binary files /dev/null and b/vendor/oss-sdk/example.jpg differ diff --git a/vendor/oss-sdk/index.php b/vendor/oss-sdk/index.php new file mode 100755 index 0000000..cdc28bc --- /dev/null +++ b/vendor/oss-sdk/index.php @@ -0,0 +1,3 @@ +<?php + +require_once __DIR__ . '/vendor/autoload.php'; diff --git a/vendor/oss-sdk/phpunit.xml b/vendor/oss-sdk/phpunit.xml new file mode 100755 index 0000000..57b2c9b --- /dev/null +++ b/vendor/oss-sdk/phpunit.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE xml> + +<phpunit> + <filter> + <whitelist> + <directory suffix=".php">./src</directory> + </whitelist> + </filter> + <logging> + <log type="coverage-clover" target="coverage.xml" /> + </logging> + <testsuites> + <testsuite name="FunctionTest"> + <directory>./tests</directory> + <exclude>./tests/OSS/Tests/BucketCnameTest.php</exclude> + </testsuite> + </testsuites> +</phpunit> diff --git a/vendor/oss-sdk/samples/Bucket.php b/vendor/oss-sdk/samples/Bucket.php new file mode 100755 index 0000000..7dc50b8 --- /dev/null +++ b/vendor/oss-sdk/samples/Bucket.php @@ -0,0 +1,168 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; + +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); +$bucket = Common::getBucketName(); + +//******************************* Simple Usage**************************************************************** + +// Create a bucket +$ossClient->createBucket($bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); +Common::println("bucket $bucket created"); + +// Check whether a bucket exists +$doesExist = $ossClient->doesBucketExist($bucket); +Common::println("bucket $bucket exist? " . ($doesExist ? "yes" : "no")); + +// Get the bucket list +$bucketListInfo = $ossClient->listBuckets(); + +// Set bucket ACL +$ossClient->putBucketAcl($bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); +Common::println("bucket $bucket acl put"); +// Get bucket ACL +$acl = $ossClient->getBucketAcl($bucket); +Common::println("bucket $bucket acl get: " . $acl); + + +//******************************* For complete usage, see the following functions **************************************************** + +createBucket($ossClient, $bucket); +doesBucketExist($ossClient, $bucket); +deleteBucket($ossClient, $bucket); +putBucketAcl($ossClient, $bucket); +getBucketAcl($ossClient, $bucket); +listBuckets($ossClient); + +/** + * Create a new bucket + * acl indicates the access permission of a bucket, including: private, public-read-only/private-read-write, and public read-write. + * Private indicates that only the bucket owner or authorized users can access the data.. + * The three permissions are separately defined by (OssClient::OSS_ACL_TYPE_PRIVATE,OssClient::OSS_ACL_TYPE_PUBLIC_READ, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE) + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket Name of the bucket to create + * @return null + */ +function createBucket($ossClient, $bucket) +{ + try { + $ossClient->createBucket($bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Check whether a bucket exists. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + */ +function doesBucketExist($ossClient, $bucket) +{ + try { + $res = $ossClient->doesBucketExist($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + if ($res === true) { + print(__FUNCTION__ . ": OK" . "\n"); + } else { + print(__FUNCTION__ . ": FAILED" . "\n"); + } +} + +/** + * Delete a bucket. If the bucket is not empty, the deletion fails. + * A bucket which is not empty indicates that it does not contain any objects or parts that are not completely uploaded during multipart upload + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket Name of the bucket to delete + * @return null + */ +function deleteBucket($ossClient, $bucket) +{ + try { + $ossClient->deleteBucket($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Set bucket ACL + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putBucketAcl($ossClient, $bucket) +{ + $acl = OssClient::OSS_ACL_TYPE_PRIVATE; + try { + $ossClient->putBucketAcl($bucket, $acl); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Get bucket ACL + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketAcl($ossClient, $bucket) +{ + try { + $res = $ossClient->getBucketAcl($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print('acl: ' . $res); +} + + +/** + * List all buckets + * + * @param OssClient $ossClient OssClient instance + * @return null + */ +function listBuckets($ossClient) +{ + $bucketList = null; + try { + $bucketListInfo = $ossClient->listBuckets(); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + $bucketList = $bucketListInfo->getBucketList(); + foreach ($bucketList as $bucket) { + print($bucket->getLocation() . "\t" . $bucket->getName() . "\t" . $bucket->getCreatedate() . "\n"); + } +} diff --git a/vendor/oss-sdk/samples/BucketCors.php b/vendor/oss-sdk/samples/BucketCors.php new file mode 100755 index 0000000..dfa42d3 --- /dev/null +++ b/vendor/oss-sdk/samples/BucketCors.php @@ -0,0 +1,108 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; +use OSS\Model\CorsConfig; +use OSS\Model\CorsRule; + +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); +$bucket = Common::getBucketName(); + + +//******************************* Simple usage**************************************************************** + +// Set cors configuration +$corsConfig = new CorsConfig(); +$rule = new CorsRule(); +$rule->addAllowedHeader("x-oss-header"); +$rule->addAllowedOrigin("http://www.b.com"); +$rule->addAllowedMethod("POST"); +$rule->setMaxAgeSeconds(10); +$corsConfig->addRule($rule); +$ossClient->putBucketCors($bucket, $corsConfig); +Common::println("bucket $bucket corsConfig created:" . $corsConfig->serializeToXml()); + +// Get cors configuration +$corsConfig = $ossClient->getBucketCors($bucket); +Common::println("bucket $bucket corsConfig fetched:" . $corsConfig->serializeToXml()); + +// Delete cors configuration +$ossClient->deleteBucketCors($bucket); +Common::println("bucket $bucket corsConfig deleted"); + +//******************************* For complete usage, see the following functions ***************************************************** + +putBucketCors($ossClient, $bucket); +getBucketCors($ossClient, $bucket); +deleteBucketCors($ossClient, $bucket); +getBucketCors($ossClient, $bucket); + +/** + * Set bucket cores + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putBucketCors($ossClient, $bucket) +{ + $corsConfig = new CorsConfig(); + $rule = new CorsRule(); + $rule->addAllowedHeader("x-oss-header"); + $rule->addAllowedOrigin("http://www.b.com"); + $rule->addAllowedMethod("POST"); + $rule->setMaxAgeSeconds(10); + $corsConfig->addRule($rule); + + try { + $ossClient->putBucketCors($bucket, $corsConfig); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get and print the cors configuration of a bucket + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketCors($ossClient, $bucket) +{ + $corsConfig = null; + try { + $corsConfig = $ossClient->getBucketCors($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print($corsConfig->serializeToXml() . "\n"); +} + +/** + * Delete all cors configuraiton of a bucket + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteBucketCors($ossClient, $bucket) +{ + try { + $ossClient->deleteBucketCors($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + diff --git a/vendor/oss-sdk/samples/BucketLifecycle.php b/vendor/oss-sdk/samples/BucketLifecycle.php new file mode 100755 index 0000000..04d2edd --- /dev/null +++ b/vendor/oss-sdk/samples/BucketLifecycle.php @@ -0,0 +1,109 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; +use OSS\Model\LifecycleAction; +use OSS\Model\LifecycleConfig; +use OSS\Model\LifecycleRule; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage ******************************************************* + +// Set lifecycle configuration +$lifecycleConfig = new LifecycleConfig(); +$actions = array(); +$actions[] = new LifecycleAction("Expiration", "Days", 3); +$lifecycleRule = new LifecycleRule("delete obsoleted files", "obsoleted/", "Enabled", $actions); +$lifecycleConfig->addRule($lifecycleRule); +$ossClient->putBucketLifecycle($bucket, $lifecycleConfig); +Common::println("bucket $bucket lifecycleConfig created:" . $lifecycleConfig->serializeToXml()); + +// Get lifecycle configuration +$lifecycleConfig = $ossClient->getBucketLifecycle($bucket); +Common::println("bucket $bucket lifecycleConfig fetched:" . $lifecycleConfig->serializeToXml()); + +// Delete bucket lifecycle configuration +$ossClient->deleteBucketLifecycle($bucket); +Common::println("bucket $bucket lifecycleConfig deleted"); + + +//***************************** For complete usage, see the following functions *********************************************** + +putBucketLifecycle($ossClient, $bucket); +getBucketLifecycle($ossClient, $bucket); +deleteBucketLifecycle($ossClient, $bucket); +getBucketLifecycle($ossClient, $bucket); + +/** + * Set bucket lifecycle configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putBucketLifecycle($ossClient, $bucket) +{ + $lifecycleConfig = new LifecycleConfig(); + $actions = array(); + $actions[] = new LifecycleAction(OssClient::OSS_LIFECYCLE_EXPIRATION, OssClient::OSS_LIFECYCLE_TIMING_DAYS, 3); + $lifecycleRule = new LifecycleRule("delete obsoleted files", "obsoleted/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + $actions = array(); + $actions[] = new LifecycleAction(OssClient::OSS_LIFECYCLE_EXPIRATION, OssClient::OSS_LIFECYCLE_TIMING_DATE, '2022-10-12T00:00:00.000Z'); + $lifecycleRule = new LifecycleRule("delete temporary files", "temporary/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + try { + $ossClient->putBucketLifecycle($bucket, $lifecycleConfig); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get bucket lifecycle configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketLifecycle($ossClient, $bucket) +{ + $lifecycleConfig = null; + try { + $lifecycleConfig = $ossClient->getBucketLifecycle($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print($lifecycleConfig->serializeToXml() . "\n"); +} + +/** + * Delete bucket lifecycle configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteBucketLifecycle($ossClient, $bucket) +{ + try { + $ossClient->deleteBucketLifecycle($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + diff --git a/vendor/oss-sdk/samples/BucketLogging.php b/vendor/oss-sdk/samples/BucketLogging.php new file mode 100755 index 0000000..eef71f2 --- /dev/null +++ b/vendor/oss-sdk/samples/BucketLogging.php @@ -0,0 +1,95 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//*******************************Simple Usage *************************************************************** + +// Set bucket access logging rules. Access logs are stored under the same bucket with a 'access.log' prefix. +$ossClient->putBucketLogging($bucket, $bucket, "access.log", array()); +Common::println("bucket $bucket lifecycleConfig created"); + +// Get bucket access logging rules +$loggingConfig = $ossClient->getBucketLogging($bucket, array()); +Common::println("bucket $bucket lifecycleConfig fetched:" . $loggingConfig->serializeToXml()); + +// Delete bucket access logging rules +$loggingConfig = $ossClient->getBucketLogging($bucket, array()); +Common::println("bucket $bucket lifecycleConfig deleted"); + +//******************************* For complete usage, see the following functions **************************************************** + +putBucketLogging($ossClient, $bucket); +getBucketLogging($ossClient, $bucket); +deleteBucketLogging($ossClient, $bucket); +getBucketLogging($ossClient, $bucket); + +/** + * Set bucket logging configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putBucketLogging($ossClient, $bucket) +{ + $option = array(); + // Access logs are stored in the same bucket. + $targetBucket = $bucket; + $targetPrefix = "access.log"; + + try { + $ossClient->putBucketLogging($bucket, $targetBucket, $targetPrefix, $option); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get bucket logging configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketLogging($ossClient, $bucket) +{ + $loggingConfig = null; + $options = array(); + try { + $loggingConfig = $ossClient->getBucketLogging($bucket, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print($loggingConfig->serializeToXml() . "\n"); +} + +/** + * Delete bucket logging configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteBucketLogging($ossClient, $bucket) +{ + try { + $ossClient->deleteBucketLogging($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} diff --git a/vendor/oss-sdk/samples/BucketReferer.php b/vendor/oss-sdk/samples/BucketReferer.php new file mode 100755 index 0000000..628f784 --- /dev/null +++ b/vendor/oss-sdk/samples/BucketReferer.php @@ -0,0 +1,101 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; +use \OSS\Model\RefererConfig; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage **************************************************************** + +// Set referer whitelist +$refererConfig = new RefererConfig(); +$refererConfig->setAllowEmptyReferer(true); +$refererConfig->addReferer("www.aliiyun.com"); +$refererConfig->addReferer("www.aliiyuncs.com"); +$ossClient->putBucketReferer($bucket, $refererConfig); +Common::println("bucket $bucket refererConfig created:" . $refererConfig->serializeToXml()); +// Get referer whitelist +$refererConfig = $ossClient->getBucketReferer($bucket); +Common::println("bucket $bucket refererConfig fetched:" . $refererConfig->serializeToXml()); + +// Delete referrer whitelist +$refererConfig = new RefererConfig(); +$ossClient->putBucketReferer($bucket, $refererConfig); +Common::println("bucket $bucket refererConfig deleted"); + + +//******************************* For complete usage, see the following functions **************************************************** + +putBucketReferer($ossClient, $bucket); +getBucketReferer($ossClient, $bucket); +deleteBucketReferer($ossClient, $bucket); +getBucketReferer($ossClient, $bucket); + +/** + * Set bucket referer configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putBucketReferer($ossClient, $bucket) +{ + $refererConfig = new RefererConfig(); + $refererConfig->setAllowEmptyReferer(true); + $refererConfig->addReferer("www.aliiyun.com"); + $refererConfig->addReferer("www.aliiyuncs.com"); + try { + $ossClient->putBucketReferer($bucket, $refererConfig); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get bucket referer configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketReferer($ossClient, $bucket) +{ + $refererConfig = null; + try { + $refererConfig = $ossClient->getBucketReferer($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print($refererConfig->serializeToXml() . "\n"); +} + +/** + * Delete bucket referer configuration + * Referer whitelist cannot be directly deleted. So use a empty one to overwrite it. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteBucketReferer($ossClient, $bucket) +{ + $refererConfig = new RefererConfig(); + try { + $ossClient->putBucketReferer($bucket, $refererConfig); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} diff --git a/vendor/oss-sdk/samples/BucketWebsite.php b/vendor/oss-sdk/samples/BucketWebsite.php new file mode 100755 index 0000000..6c387e6 --- /dev/null +++ b/vendor/oss-sdk/samples/BucketWebsite.php @@ -0,0 +1,92 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; +use OSS\Model\WebsiteConfig; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage *************************************************************** + +// Set bucket static website configuration +$websiteConfig = new WebsiteConfig("index.html", "error.html"); +$ossClient->putBucketWebsite($bucket, $websiteConfig); +Common::println("bucket $bucket websiteConfig created:" . $websiteConfig->serializeToXml()); + +// Get bucket static website configuration +$websiteConfig = $ossClient->getBucketWebsite($bucket); +Common::println("bucket $bucket websiteConfig fetched:" . $websiteConfig->serializeToXml()); + +// Delete bucket static website configuration +$ossClient->deleteBucketWebsite($bucket); +Common::println("bucket $bucket websiteConfig deleted"); + +//******************************* For complete usage, see the following functions **************************************************** + +putBucketWebsite($ossClient, $bucket); +getBucketWebsite($ossClient, $bucket); +deleteBucketWebsite($ossClient, $bucket); +getBucketWebsite($ossClient, $bucket); + +/** + * Sets bucket static website configuration + * + * @param $ossClient OssClient + * @param $bucket string bucket name + * @return null + */ +function putBucketWebsite($ossClient, $bucket) +{ + $websiteConfig = new WebsiteConfig("index.html", "error.html"); + try { + $ossClient->putBucketWebsite($bucket, $websiteConfig); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get bucket static website configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getBucketWebsite($ossClient, $bucket) +{ + $websiteConfig = null; + try { + $websiteConfig = $ossClient->getBucketWebsite($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + print($websiteConfig->serializeToXml() . "\n"); +} + +/** + * Delete bucket static website configuration + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteBucketWebsite($ossClient, $bucket) +{ + try { + $ossClient->deleteBucketWebsite($bucket); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} diff --git a/vendor/oss-sdk/samples/Callback.php b/vendor/oss-sdk/samples/Callback.php new file mode 100755 index 0000000..4b7bc41 --- /dev/null +++ b/vendor/oss-sdk/samples/Callback.php @@ -0,0 +1,83 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage *************************************************************** + +/** putObject Upload content to an OSS file using callback. + * The callbackurl specifies the server url for the request callback. + * The callbackbodytype can be application/json or application/x-www-form-urlencoded,the optional parameters,the default for the application/x - WWW - form - urlencoded + * Users can choose not to set OSS_BACK_VAR + */ +$url = + '{ + "callbackUrl":"callback.oss-demo.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var1}&my_var2=${x:var2}", + "callbackBodyType":"application/x-www-form-urlencoded" + + }'; +$var = + '{ + "x:var1":"value1", + "x:var2":"值2" + }'; +$options = array(OssClient::OSS_CALLBACK => $url, + OssClient::OSS_CALLBACK_VAR => $var + ); +$result = $ossClient->putObject($bucket, "b.file", "random content", $options); +Common::println($result['body']); +Common::println($result['info']['http_code']); + +/** + * completeMultipartUpload Upload content to an OSS file using callback. + * callbackurl specifies the server url for the request callback + * The callbackbodytype can be application/json or application/x-www-form-urlencoded,the optional parameters,the default for the application/x - WWW - form - urlencoded + * Users can choose not to set OSS_BACK_VAR. + */ +$object = "multipart-callback-test.txt"; +$copiedObject = "multipart-callback-test.txt.copied"; +$ossClient->putObject($bucket, $copiedObject, file_get_contents(__FILE__)); + +/** + * step 1. Initialize a block upload event, that is, a multipart upload process to get an upload id + */ +$upload_id = $ossClient->initiateMultipartUpload($bucket, $object); + +/** + * step 2. uploadPartCopy + */ +$copyId = 1; +$eTag = $ossClient->uploadPartCopy($bucket, $copiedObject, $bucket, $object, $copyId, $upload_id); +$upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); +$listPartsInfo = $ossClient->listParts($bucket, $object, $upload_id); + +/** + * step 3. + */ +$json = + '{ + "callbackUrl":"callback.oss-demo.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}", + "callbackBodyType":"application/json" + }'; +$var = + '{ + "x:var1":"value1", + "x:var2":"值2" + }'; +$options = array(OssClient::OSS_CALLBACK => $json, + OssClient::OSS_CALLBACK_VAR => $var); + +$result = $ossClient->completeMultipartUpload($bucket, $object, $upload_id, $upload_parts, $options); +Common::println($result['body']); +Common::println($result['info']['http_code']); diff --git a/vendor/oss-sdk/samples/Common.php b/vendor/oss-sdk/samples/Common.php new file mode 100755 index 0000000..49bd493 --- /dev/null +++ b/vendor/oss-sdk/samples/Common.php @@ -0,0 +1,84 @@ +<?php + +if (is_file(__DIR__ . '/../autoload.php')) { + require_once __DIR__ . '/../autoload.php'; +} +if (is_file(__DIR__ . '/../vendor/autoload.php')) { + require_once __DIR__ . '/../vendor/autoload.php'; +} +require_once __DIR__ . '/Config.php'; + +use OSS\OssClient; +use OSS\Core\OssException; + +/** + * Class Common + * + * The Common class for 【Samples/*.php】 used to obtain OssClient instance and other common functions + */ +class Common +{ + const endpoint = Config::OSS_ENDPOINT; + const accessKeyId = Config::OSS_ACCESS_ID; + const accessKeySecret = Config::OSS_ACCESS_KEY; + const bucket = Config::OSS_TEST_BUCKET; + + /** + * Get an OSSClient instance according to config. + * + * @return OssClient An OssClient instance + */ + public static function getOssClient() + { + try { + $ossClient = new OssClient(self::accessKeyId, self::accessKeySecret, self::endpoint, false); + } catch (OssException $e) { + printf(__FUNCTION__ . "creating OssClient instance: FAILED\n"); + printf($e->getMessage() . "\n"); + return null; + } + return $ossClient; + } + + public static function getBucketName() + { + return self::bucket; + } + + /** + * A tool function which creates a bucket and exists the process if there are exceptions + */ + public static function createBucket() + { + $ossClient = self::getOssClient(); + if (is_null($ossClient)) exit(1); + $bucket = self::getBucketName(); + $acl = OssClient::OSS_ACL_TYPE_PUBLIC_READ; + try { + $ossClient->createBucket($bucket, $acl); + } catch (OssException $e) { + + $message = $e->getMessage(); + if (\OSS\Core\OssUtil::startsWith($message, 'http status: 403')) { + echo "Please Check your AccessKeyId and AccessKeySecret" . "\n"; + exit(0); + } elseif (strpos($message, "BucketAlreadyExists") !== false) { + echo "Bucket already exists. Please check whether the bucket belongs to you, or it was visited with correct endpoint. " . "\n"; + exit(0); + } + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + } + + public static function println($message) + { + if (!empty($message)) { + echo strval($message) . "\n"; + } + } +} + +# Common::createBucket(); diff --git a/vendor/oss-sdk/samples/Config.php b/vendor/oss-sdk/samples/Config.php new file mode 100755 index 0000000..fc3a167 --- /dev/null +++ b/vendor/oss-sdk/samples/Config.php @@ -0,0 +1,15 @@ +<?php + +/** + * Class Config + * + * Make configurations required by the sample. + * Users can run RunAll.php which runs all the samples after configuring Endpoint, AccessId, and AccessKey. + */ +final class Config +{ + const OSS_ACCESS_ID = 'update me'; + const OSS_ACCESS_KEY = 'update me'; + const OSS_ENDPOINT = 'update me'; + const OSS_TEST_BUCKET = 'update me'; +} diff --git a/vendor/oss-sdk/samples/Image.php b/vendor/oss-sdk/samples/Image.php new file mode 100755 index 0000000..6e51d06 --- /dev/null +++ b/vendor/oss-sdk/samples/Image.php @@ -0,0 +1,87 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; + +$bucketName = Common::getBucketName(); +$object = "example.jpg"; +$ossClient = Common::getOssClient(); +$download_file = "download.jpg"; +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage *************************************************************** + +// Upload example.jpg to the specified bucket and rename it to $object. +$ossClient->uploadFile($bucketName, $object, "example.jpg"); + +// Image resize +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/resize,m_fixed,h_100,w_100", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageResize",$download_file); + +// Image crop +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/crop,w_100,h_100,x_100,y_100,r_1", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("iamgeCrop", $download_file); + +// Image rotate +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/rotate,90", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageRotate", $download_file); + +// Image sharpen +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/sharpen,100", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageSharpen", $download_file); + +// Add watermark into a image +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageWatermark", $download_file); + +// Image format convertion +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/format,png", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageFormat", $download_file); + +// Get image information +$options = array( + OssClient::OSS_FILE_DOWNLOAD => $download_file, + OssClient::OSS_PROCESS => "image/info", ); +$ossClient->getObject($bucketName, $object, $options); +printImage("imageInfo", $download_file); + + +/** + * Generate a signed url which could be used in browser to access the object. The expiration time is 1 hour. + */ + $timeout = 3600; +$options = array( + OssClient::OSS_PROCESS => "image/resize,m_lfit,h_100,w_100", + ); +$signedUrl = $ossClient->signUrl($bucketName, $object, $timeout, "GET", $options); +Common::println("rtmp url: \n" . $signedUrl); + +// Finally delete the $object uploaded. +$ossClient->deleteObject($bucketName, $object); + +function printImage($func, $imageFile) +{ + $array = getimagesize($imageFile); + Common::println("$func, image width: " . $array[0]); + Common::println("$func, image height: " . $array[1]); + Common::println("$func, image type: " . ($array[2] === 2 ? 'jpg' : 'png')); + Common::println("$func, image size: " . ceil(filesize($imageFile))); +} diff --git a/vendor/oss-sdk/samples/LiveChannel.php b/vendor/oss-sdk/samples/LiveChannel.php new file mode 100755 index 0000000..67bb541 --- /dev/null +++ b/vendor/oss-sdk/samples/LiveChannel.php @@ -0,0 +1,131 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Model\LiveChannelConfig; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage ******************************************************* + +/** + * Create a Live Channel + * The live channel's name is test_rtmp_live. + * The play url file is named as test.m3u8, which includes 3 ts files. + * The time period of each file is 5 seconds.(It is recommneded value only for demo purpose, the actual period depends on the key frame.) + * + */ +$config = new LiveChannelConfig(array( + 'description' => 'live channel test', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); +$info = $ossClient->putBucketLiveChannel($bucket, 'test_rtmp_live', $config); +Common::println("bucket $bucket liveChannel created:\n" . +"live channel name: ". $info->getName() . "\n" . +"live channel description: ". $info->getDescription() . "\n" . +"publishurls: ". $info->getPublishUrls()[0] . "\n" . +"playurls: ". $info->getPlayUrls()[0] . "\n"); + +/** + * You can use listBucketLiveChannels to list and manage all existing live channels. + * Prefix can be used to filter listed live channels by prefix. + * Max_keys indicates the maximum numbers of live channels that can be listed in an iterator at one time. Its value is 1000 in maximum and 100 by default. + */ +$list = $ossClient->listBucketLiveChannels($bucket); +Common::println("bucket $bucket listLiveChannel:\n" . +"list live channel prefix: ". $list->getPrefix() . "\n" . +"list live channel marker: ". $list->getMarker() . "\n" . +"list live channel maxkey: ". $list->getMaxKeys() . "\n" . +"list live channel IsTruncated: ". $list->getIsTruncated() . "\n" . +"list live channel getNextMarker: ". $list->getNextMarker() . "\n"); + +foreach($list->getChannelList() as $list) +{ + Common::println("bucket $bucket listLiveChannel:\n" . + "list live channel IsTruncated: ". $list->getName() . "\n" . + "list live channel Description: ". $list->getDescription() . "\n" . + "list live channel Status: ". $list->getStatus() . "\n" . + "list live channel getNextMarker: ". $list->getLastModified() . "\n"); +} +/** + * Obtain the play_url (url used for rtmp stream pushing. + * If the the bucket is not globally readable and writable, + * the url must be signed as shown in the following.) and pulish_url (the url included in the m3u8 file generated in stream pushing) used to push streams. + */ +$play_url = $ossClient->signRtmpUrl($bucket, "test_rtmp_live", 3600, array('params' => array('playlistName' => 'playlist.m3u8'))); +Common::println("bucket $bucket rtmp url: \n" . $play_url); +$play_url = $ossClient->signRtmpUrl($bucket, "test_rtmp_live", 3600); +Common::println("bucket $bucket rtmp url: \n" . $play_url); + +/** + * If you want to disable a created live channel (disable the pushing streaming or do not allow stream pushing to an IP address), call putLiveChannelStatus to change the channel status to "Disabled". + * If you want to enable a disabled live channel, call PutLiveChannelStatus to chanage the channel status to "Enabled". + */ +$resp = $ossClient->putLiveChannelStatus($bucket, "test_rtmp_live", "enabled"); + +/** + * You can callLiveChannelInfo to get the information about a live channel. + */ +$info = $ossClient->getLiveChannelInfo($bucket, 'test_rtmp_live'); +Common::println("bucket $bucket LiveChannelInfo:\n" . +"live channel info description: ". $info->getDescription() . "\n" . +"live channel info status: ". $info->getStatus() . "\n" . +"live channel info type: ". $info->getType() . "\n" . +"live channel info fragDuration: ". $info->getFragDuration() . "\n" . +"live channel info fragCount: ". $info->getFragCount() . "\n" . +"live channel info playListName: ". $info->getPlayListName() . "\n"); + +/** + * Gets the historical pushing streaming records by calling getLiveChannelHistory. Now the max records to return is 10. + */ +$history = $ossClient->getLiveChannelHistory($bucket, "test_rtmp_live"); +if (count($history->getLiveRecordList()) != 0) +{ + foreach($history->getLiveRecordList() as $recordList) + { + Common::println("bucket $bucket liveChannelHistory:\n" . + "live channel history startTime: ". $recordList->getStartTime() . "\n" . + "live channel history endTime: ". $recordList->getEndTime() . "\n" . + "live channel history remoteAddr: ". $recordList->getRemoteAddr() . "\n"); + } +} + +/** + * Get the live channel's status by calling getLiveChannelStatus. + * If the live channel is receiving the pushing stream, all attributes in stat_result are valid. + * If the live channel is idle or disabled, then the status is idle or Disabled and other attributes have no meaning. + */ +$status = $ossClient->getLiveChannelStatus($bucket, "test_rtmp_live"); +Common::println("bucket $bucket listLiveChannel:\n" . +"live channel status status: ". $status->getStatus() . "\n" . +"live channel status ConnectedTime: ". $status->getConnectedTime() . "\n" . +"live channel status VideoWidth: ". $status->getVideoWidth() . "\n" . +"live channel status VideoHeight: ". $status->getVideoHeight() . "\n" . +"live channel status VideoFrameRate: ". $status->getVideoFrameRate() . "\n" . +"live channel status VideoBandwidth: ". $status->getVideoBandwidth() . "\n" . +"live channel status VideoCodec: ". $status->getVideoCodec() . "\n" . +"live channel status AudioBandwidth: ". $status->getAudioBandwidth() . "\n" . +"live channel status AudioSampleRate: ". $status->getAudioSampleRate() . "\n" . +"live channel status AdioCodec: ". $status->getAudioCodec() . "\n"); + +/** + * If you want to generate a play url from the ts files generated from pushing streaming, call postVodPlayList. + * Specify the start time to 60 seconds before the current time and the end time to the current time, which means that a video of 60 seconds is generated. + * The playlist file is specified to “vod_playlist.m3u8”, which means that a palylist file named vod_playlist.m3u8 is created after the interface is called. + */ +$current_time = time(); +$ossClient->postVodPlaylist($bucket, + "test_rtmp_live", "vod_playlist.m3u8", + array('StartTime' => $current_time - 60, + 'EndTime' => $current_time) +); + +/** + * Call delete_live_channel to delete a live channel if it will no longer be in used. + */ +$ossClient->deleteBucketLiveChannel($bucket, "test_rtmp_live"); diff --git a/vendor/oss-sdk/samples/MultipartUpload.php b/vendor/oss-sdk/samples/MultipartUpload.php new file mode 100755 index 0000000..21756b7 --- /dev/null +++ b/vendor/oss-sdk/samples/MultipartUpload.php @@ -0,0 +1,182 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssUtil; +use OSS\Core\OssException; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple usage *************************************************************** + +/** + * See the putObjectByRawAPis usage in complete example to check out basic multipart upload APIs which can be used as resumable upload. + */ + +// Upload a file using the multipart upload interface, which determines to use simple upload or multipart upload based on the file size. +$ossClient->multiuploadFile($bucket, "file.php", __FILE__, array()); +Common::println("local file " . __FILE__ . " is uploaded to the bucket $bucket, file.php"); + + +// Upload local directory's data into target dir +$ossClient->uploadDir($bucket, "targetdir", __DIR__); +Common::println("local dir " . __DIR__ . " is uploaded to the bucket $bucket, targetdir/"); + + +// List the incomplete multipart uploads +$listMultipartUploadInfo = $ossClient->listMultipartUploads($bucket, array()); + + +//******************************* For complete usage, see the following functions **************************************************** + +multiuploadFile($ossClient, $bucket); +putObjectByRawApis($ossClient, $bucket); +uploadDir($ossClient, $bucket); +listMultipartUploads($ossClient, $bucket); + +/** + * Upload files using multipart upload + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function multiuploadFile($ossClient, $bucket) +{ + $object = "test/multipart-test.txt"; + $file = __FILE__; + $options = array(); + + try { + $ossClient->multiuploadFile($bucket, $object, $file, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Use basic multipart upload for file upload. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @throws OssException + */ +function putObjectByRawApis($ossClient, $bucket) +{ + $object = "test/multipart-test.txt"; + /** + * step 1. Initialize a block upload event, that is, a multipart upload process to get an upload id + */ + try { + $uploadId = $ossClient->initiateMultipartUpload($bucket, $object); + } catch (OssException $e) { + printf(__FUNCTION__ . ": initiateMultipartUpload FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": initiateMultipartUpload OK" . "\n"); + /* + * step 2. Upload parts + */ + $partSize = 10 * 1024 * 1024; + $uploadFile = __FILE__; + $uploadFileSize = filesize($uploadFile); + $pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize); + $responseUploadPart = array(); + $uploadPosition = 0; + $isCheckMd5 = true; + foreach ($pieces as $i => $piece) { + $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO]; + $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1; + $upOptions = array( + $ossClient::OSS_FILE_UPLOAD => $uploadFile, + $ossClient::OSS_PART_NUM => ($i + 1), + $ossClient::OSS_SEEK_TO => $fromPos, + $ossClient::OSS_LENGTH => $toPos - $fromPos + 1, + $ossClient::OSS_CHECK_MD5 => $isCheckMd5, + ); + if ($isCheckMd5) { + $contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos); + $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5; + } + //2. Upload each part to OSS + try { + $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $uploadId, $upOptions); + } catch (OssException $e) { + printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n"); + } + $uploadParts = array(); + foreach ($responseUploadPart as $i => $eTag) { + $uploadParts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + /** + * step 3. Complete the upload + */ + try { + $ossClient->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts); + } catch (OssException $e) { + printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + printf(__FUNCTION__ . ": completeMultipartUpload OK\n"); +} + +/** + * Upload by directories + * + * @param OssClient $ossClient OssClient + * @param string $bucket bucket name + * + */ +function uploadDir($ossClient, $bucket) +{ + $localDirectory = "."; + $prefix = "samples/codes"; + try { + $ossClient->uploadDir($bucket, $prefix, $localDirectory); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + printf(__FUNCTION__ . ": completeMultipartUpload OK\n"); +} + +/** + * Get ongoing multipart uploads + * + * @param $ossClient OssClient + * @param $bucket string + */ +function listMultipartUploads($ossClient, $bucket) +{ + $options = array( + 'max-uploads' => 100, + 'key-marker' => '', + 'prefix' => '', + 'upload-id-marker' => '' + ); + try { + $listMultipartUploadInfo = $ossClient->listMultipartUploads($bucket, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": listMultipartUploads FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + printf(__FUNCTION__ . ": listMultipartUploads OK\n"); + $listUploadInfo = $listMultipartUploadInfo->getUploads(); + var_dump($listUploadInfo); +} diff --git a/vendor/oss-sdk/samples/Object.php b/vendor/oss-sdk/samples/Object.php new file mode 100755 index 0000000..ae6eb83 --- /dev/null +++ b/vendor/oss-sdk/samples/Object.php @@ -0,0 +1,518 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; +use OSS\Core\OssException; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); +//******************************* Simple usage *************************************************************** + +// Upload the in-memory string (hi, oss) to an OSS file +$result = $ossClient->putObject($bucket, "b.file", "hi, oss"); +Common::println("b.file is created"); +Common::println($result['x-oss-request-id']); +Common::println($result['etag']); +Common::println($result['content-md5']); +Common::println($result['body']); + +// Uploads a local file to an OSS file +$result = $ossClient->uploadFile($bucket, "c.file", __FILE__); +Common::println("c.file is created"); +Common::println("b.file is created"); +Common::println($result['x-oss-request-id']); +Common::println($result['etag']); +Common::println($result['content-md5']); +Common::println($result['body']); + +// Download an oss object as an in-memory variable +$content = $ossClient->getObject($bucket, "b.file"); +Common::println("b.file is fetched, the content is: " . $content); + +// Add a symlink to an object +$content = $ossClient->putSymlink($bucket, "test-symlink", "b.file"); +Common::println("test-symlink is created"); +Common::println($result['x-oss-request-id']); +Common::println($result['etag']); + +// Get a symlink +$content = $ossClient->getSymlink($bucket, "test-symlink"); +Common::println("test-symlink refer to : " . $content[OssClient::OSS_SYMLINK_TARGET]); + +// Download an object to a local file. +$options = array( + OssClient::OSS_FILE_DOWNLOAD => "./c.file.localcopy", +); +$ossClient->getObject($bucket, "c.file", $options); +Common::println("b.file is fetched to the local file: c.file.localcopy"); +Common::println("b.file is created"); + +// Copy an object +$result = $ossClient->copyObject($bucket, "c.file", $bucket, "c.file.copy"); +Common::println("lastModifiedTime: " . $result[0]); +Common::println("ETag: " . $result[1]); + +// Check whether an object exists +$doesExist = $ossClient->doesObjectExist($bucket, "c.file.copy"); +Common::println("file c.file.copy exist? " . ($doesExist ? "yes" : "no")); + +// Delete an object +$result = $ossClient->deleteObject($bucket, "c.file.copy"); +Common::println("c.file.copy is deleted"); +Common::println("b.file is created"); +Common::println($result['x-oss-request-id']); + +// Check whether an object exists +$doesExist = $ossClient->doesObjectExist($bucket, "c.file.copy"); +Common::println("file c.file.copy exist? " . ($doesExist ? "yes" : "no")); + +// Delete multiple objects in batch +$result = $ossClient->deleteObjects($bucket, array("b.file", "c.file")); +foreach($result as $object) + Common::println($object); + +sleep(2); +unlink("c.file.localcopy"); + +//******************************* For complete usage, see the following functions **************************************************** + +listObjects($ossClient, $bucket); +listAllObjects($ossClient, $bucket); +createObjectDir($ossClient, $bucket); +putObject($ossClient, $bucket); +uploadFile($ossClient, $bucket); +getObject($ossClient, $bucket); +getObjectToLocalFile($ossClient, $bucket); +copyObject($ossClient, $bucket); +modifyMetaForObject($ossClient, $bucket); +getObjectMeta($ossClient, $bucket); +deleteObject($ossClient, $bucket); +deleteObjects($ossClient, $bucket); +doesObjectExist($ossClient, $bucket); +getSymlink($ossClient, $bucket); +putSymlink($ossClient, $bucket); +/** + * Create a 'virtual' folder + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function createObjectDir($ossClient, $bucket) +{ + try { + $ossClient->createObjectDir($bucket, "dir"); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Upload in-memory data to oss + * + * Simple upload---upload specified in-memory data to an OSS object + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function putObject($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $content = file_get_contents(__FILE__); + $options = array(); + try { + $ossClient->putObject($bucket, $object, $content, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Uploads a local file to OSS + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function uploadFile($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $filePath = __FILE__; + $options = array(); + + try { + $ossClient->uploadFile($bucket, $object, $filePath, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Lists all files and folders in the bucket. + * Note if there's more items than the max-keys specified, the caller needs to use the nextMarker returned as the value for the next call's maker paramter. + * Loop through all the items returned from ListObjects. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function listObjects($ossClient, $bucket) +{ + $prefix = 'oss-php-sdk-test/'; + $delimiter = '/'; + $nextMarker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $nextMarker, + ); + try { + $listObjectInfo = $ossClient->listObjects($bucket, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + $objectList = $listObjectInfo->getObjectList(); // object list + $prefixList = $listObjectInfo->getPrefixList(); // directory list + if (!empty($objectList)) { + print("objectList:\n"); + foreach ($objectList as $objectInfo) { + print($objectInfo->getKey() . "\n"); + } + } + if (!empty($prefixList)) { + print("prefixList: \n"); + foreach ($prefixList as $prefixInfo) { + print($prefixInfo->getPrefix() . "\n"); + } + } +} + +/** + * Lists all folders and files under the bucket. Use nextMarker repeatedly to get all objects. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function listAllObjects($ossClient, $bucket) +{ + // Create dir/obj 'folder' and put some files into it. + for ($i = 0; $i < 100; $i += 1) { + $ossClient->putObject($bucket, "dir/obj" . strval($i), "hi"); + $ossClient->createObjectDir($bucket, "dir/obj" . strval($i)); + } + + $prefix = 'dir/'; + $delimiter = '/'; + $nextMarker = ''; + $maxkeys = 30; + + while (true) { + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $nextMarker, + ); + var_dump($options); + try { + $listObjectInfo = $ossClient->listObjects($bucket, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + // Get the nextMarker, and it would be used as the next call's marker parameter to resume from the last call + $nextMarker = $listObjectInfo->getNextMarker(); + $listObject = $listObjectInfo->getObjectList(); + $listPrefix = $listObjectInfo->getPrefixList(); + var_dump(count($listObject)); + var_dump(count($listPrefix)); + if ($nextMarker === '') { + break; + } + } +} + +/** + * Get the content of an object. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getObject($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $options = array(); + try { + $content = $ossClient->getObject($bucket, $object, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + if (file_get_contents(__FILE__) === $content) { + print(__FUNCTION__ . ": FileContent checked OK" . "\n"); + } else { + print(__FUNCTION__ . ": FileContent checked FAILED" . "\n"); + } +} + +/** + * Put symlink + * + * @param OssClient $ossClient The Instance of OssClient + * @param string $bucket bucket name + * @return null + */ +function putSymlink($ossClient, $bucket) +{ + $symlink = "test-samples-symlink"; + $object = "test-samples-object"; + try { + $ossClient->putObject($bucket, $object, 'test-content'); + $ossClient->putSymlink($bucket, $symlink, $object); + $content = $ossClient->getObject($bucket, $symlink); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + if ($content == 'test-content') { + print(__FUNCTION__ . ": putSymlink checked OK" . "\n"); + } else { + print(__FUNCTION__ . ": putSymlink checked FAILED" . "\n"); + } +} + +/** + * Get symlink + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getSymlink($ossClient, $bucket) +{ + $symlink = "test-samples-symlink"; + $object = "test-samples-object"; + try { + $ossClient->putObject($bucket, $object, 'test-content'); + $ossClient->putSymlink($bucket, $symlink, $object); + $content = $ossClient->getSymlink($bucket, $symlink); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + if ($content[OssClient::OSS_SYMLINK_TARGET]) { + print(__FUNCTION__ . ": getSymlink checked OK" . "\n"); + } else { + print(__FUNCTION__ . ": getSymlink checked FAILED" . "\n"); + } +} + +/** + * Get_object_to_local_file + * + * Get object + * Download object to a specified file. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getObjectToLocalFile($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $localfile = "upload-test-object-name.txt"; + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $localfile, + ); + + try { + $ossClient->getObject($bucket, $object, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK, please check localfile: 'upload-test-object-name.txt'" . "\n"); + if (file_get_contents($localfile) === file_get_contents(__FILE__)) { + print(__FUNCTION__ . ": FileContent checked OK" . "\n"); + } else { + print(__FUNCTION__ . ": FileContent checked FAILED" . "\n"); + } + if (file_exists($localfile)) { + unlink($localfile); + } +} + +/** + * Copy object + * When the source object is same as the target one, copy operation will just update the metadata. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function copyObject($ossClient, $bucket) +{ + $fromBucket = $bucket; + $fromObject = "oss-php-sdk-test/upload-test-object-name.txt"; + $toBucket = $bucket; + $toObject = $fromObject . '.copy'; + $options = array(); + + try { + $ossClient->copyObject($fromBucket, $fromObject, $toBucket, $toObject, $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Update Object Meta + * it leverages the feature of copyObject: when the source object is just the target object, the metadata could be updated via copy + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function modifyMetaForObject($ossClient, $bucket) +{ + $fromBucket = $bucket; + $fromObject = "oss-php-sdk-test/upload-test-object-name.txt"; + $toBucket = $bucket; + $toObject = $fromObject; + $copyOptions = array( + OssClient::OSS_HEADERS => array( + 'Cache-Control' => 'max-age=60', + 'Content-Disposition' => 'attachment; filename="xxxxxx"', + ), + ); + try { + $ossClient->copyObject($fromBucket, $fromObject, $toBucket, $toObject, $copyOptions); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Get object meta, that is, getObjectMeta + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function getObjectMeta($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $objectMeta = $ossClient->getObjectMeta($bucket, $object); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + if (isset($objectMeta[strtolower('Content-Disposition')]) && + 'attachment; filename="xxxxxx"' === $objectMeta[strtolower('Content-Disposition')] + ) { + print(__FUNCTION__ . ": ObjectMeta checked OK" . "\n"); + } else { + print(__FUNCTION__ . ": ObjectMeta checked FAILED" . "\n"); + } +} + +/** + * Delete an object + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteObject($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $ossClient->deleteObject($bucket, $object); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + + +/** + * Delete multiple objects in batch + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function deleteObjects($ossClient, $bucket) +{ + $objects = array(); + $objects[] = "oss-php-sdk-test/upload-test-object-name.txt"; + $objects[] = "oss-php-sdk-test/upload-test-object-name.txt.copy"; + try { + $ossClient->deleteObjects($bucket, $objects); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); +} + +/** + * Check whether an object exists + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + */ +function doesObjectExist($ossClient, $bucket) +{ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $exist = $ossClient->doesObjectExist($bucket, $object); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + var_dump($exist); +} + diff --git a/vendor/oss-sdk/samples/RunAll.php b/vendor/oss-sdk/samples/RunAll.php new file mode 100755 index 0000000..0cd7ec1 --- /dev/null +++ b/vendor/oss-sdk/samples/RunAll.php @@ -0,0 +1,13 @@ +<?php + +error_reporting(E_ALL | E_NOTICE); + +require_once __DIR__ . '/Bucket.php'; +require_once __DIR__ . '/BucketCors.php'; +require_once __DIR__ . '/BucketLifecycle.php'; +require_once __DIR__ . '/BucketReferer.php'; +require_once __DIR__ . '/BucketLogging.php'; +require_once __DIR__ . '/BucketWebsite.php'; +require_once __DIR__ . '/Signature.php'; +require_once __DIR__ . '/Object1.php'; +require_once __DIR__ . '/MultipartUpload.php'; \ No newline at end of file diff --git a/vendor/oss-sdk/samples/Signature.php b/vendor/oss-sdk/samples/Signature.php new file mode 100755 index 0000000..eef5981 --- /dev/null +++ b/vendor/oss-sdk/samples/Signature.php @@ -0,0 +1,142 @@ +<?php +require_once __DIR__ . '/Common.php'; + +use OSS\Http\RequestCore; +use OSS\Http\ResponseCore; +use OSS\OssClient; +use OSS\Core\OssException; + +$bucket = Common::getBucketName(); +$ossClient = Common::getOssClient(); +if (is_null($ossClient)) exit(1); + +//******************************* Simple Usage *************************************************************** + +$ossClient->uploadFile($bucket, "a.file", __FILE__); + +// Generate a signed url for getting an object. The URL can be used in browser directly to download the file. +$signedUrl = $ossClient->signUrl($bucket, "a.file", 3600); +Common::println($signedUrl); + +// Generate the signed url for putting an object. User can use put method with this url to upload a file to "a.file". +$signedUrl = $ossClient->signUrl($bucket, "a.file", "3600", "PUT"); +Common::println($signedUrl); + +// Generate the signed url for putting an object from local file. The url can be used directly to upload the file to "a.file". +$signedUrl = $ossClient->signUrl($bucket, "a.file", 3600, "PUT", array('Content-Type' => 'txt')); +Common::println($signedUrl); + +//******************************* For complete usage, see the following functions **************************************************** + +getSignedUrlForPuttingObject($ossClient, $bucket); +getSignedUrlForPuttingObjectFromFile($ossClient, $bucket); +getSignedUrlForGettingObject($ossClient, $bucket); + +/** + * Generate the signed url for getObject() to control read accesses under private privilege + * + * @param $ossClient OssClient OssClient instance + * @param $bucket string bucket name + * @return null + */ +function getSignedUrlForGettingObject($ossClient, $bucket) +{ + $object = "test/test-signature-test-upload-and-download.txt"; + $timeout = 3600; + try { + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n"); + /** + * Use similar code to access the object by url, or use browser to access the object. + */ + $request = new RequestCore($signedUrl); + $request->set_method('GET'); + $request->add_header('Content-Type', ''); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); + if ($res->isOK()) { + print(__FUNCTION__ . ": OK" . "\n"); + } else { + print(__FUNCTION__ . ": FAILED" . "\n"); + }; +} + +/** + * Generate the signed url for PutObject to control write accesses under private privilege. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @return null + * @throws OssException + */ +function getSignedUrlForPuttingObject($ossClient, $bucket) +{ + $object = "test/test-signature-test-upload-and-download.txt"; + $timeout = 3600; + $options = NULL; + try { + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT"); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n"); + $content = file_get_contents(__FILE__); + + $request = new RequestCore($signedUrl); + $request->set_method('PUT'); + $request->add_header('Content-Type', ''); + $request->add_header('Content-Length', strlen($content)); + $request->set_body($content); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), + $request->get_response_body(), $request->get_response_code()); + if ($res->isOK()) { + print(__FUNCTION__ . ": OK" . "\n"); + } else { + print(__FUNCTION__ . ": FAILED" . "\n"); + }; +} + +/** + * Generate the signed url for PutObject's signed url. User could use the signed url to upload file directly. + * + * @param OssClient $ossClient OssClient instance + * @param string $bucket bucket name + * @throws OssException + */ +function getSignedUrlForPuttingObjectFromFile($ossClient, $bucket) +{ + $file = __FILE__; + $object = "test/test-signature-test-upload-and-download.txt"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + try { + $signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "PUT", $options); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n"); + + $request = new RequestCore($signedUrl); + $request->set_method('PUT'); + $request->add_header('Content-Type', 'txt'); + $request->set_read_file($file); + $request->set_read_stream_size(filesize($file)); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), + $request->get_response_body(), $request->get_response_code()); + if ($res->isOK()) { + print(__FUNCTION__ . ": OK" . "\n"); + } else { + print(__FUNCTION__ . ": FAILED" . "\n"); + }; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Core/MimeTypes.php b/vendor/oss-sdk/src/OSS/Core/MimeTypes.php new file mode 100755 index 0000000..17685c3 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Core/MimeTypes.php @@ -0,0 +1,263 @@ +<?php + +namespace OSS\Core; + +/** + * Class MimeTypes + * + * The map of a file's extention name to its corresponding Content-Type value in the file upload request. + * If the file extention name is not predefined in this class, getMimetype() returns null. + * + * @package OSS\Core + */ +class MimeTypes +{ + /** + * Get the content-type value of http header from the file's extension name. + * + * @param string $name Default file extension name. + * @return string content-type + */ + public static function getMimetype($name) + { + $parts = explode('.', $name); + if (count($parts) > 1) { + $ext = strtolower(end($parts)); + if (isset(self::$mime_types[$ext])) { + return self::$mime_types[$ext]; + } + } + + return null; + } + + private static $mime_types = array( + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', + 'apk' => 'application/vnd.android.package-archive', + 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'doc' => 'application/msword', + 'ogg' => 'audio/ogg', + 'pdf' => 'application/pdf', + 'rtf' => 'text/rtf', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'sxw' => 'application/vnd.sun.xml.writer', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sxc' => 'application/vnd.sun.xml.calc', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'sxd' => 'application/vnd.sun.xml.draw', + 'std' => 'application/vnd.sun.xml.draw.template', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxm' => 'application/vnd.sun.xml.math', + 'sis' => 'application/vnd.symbian.install', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'bcpio' => 'application/x-bcpio', + 'torrent' => 'application/x-bittorrent', + 'bz2' => 'application/x-bzip2', + 'vcd' => 'application/x-cdlink', + 'pgn' => 'application/x-chess-pgn', + 'cpio' => 'application/x-cpio', + 'csh' => 'application/x-csh', + 'dvi' => 'application/x-dvi', + 'spl' => 'application/x-futuresplash', + 'gtar' => 'application/x-gtar', + 'hdf' => 'application/x-hdf', + 'jar' => 'application/java-archive', + 'jnlp' => 'application/x-java-jnlp-file', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'ksp' => 'application/x-kspread', + 'chrt' => 'application/x-kchart', + 'kil' => 'application/x-killustrator', + 'latex' => 'application/x-latex', + 'rpm' => 'application/x-rpm', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'tar' => 'application/x-tar', + 'tcl' => 'application/x-tcl', + 'tex' => 'application/x-tex', + 'man' => 'application/x-troff-man', + 'me' => 'application/x-troff-me', + 'ms' => 'application/x-troff-ms', + 'ustar' => 'application/x-ustar', + 'src' => 'application/x-wais-source', + 'zip' => 'application/zip', + 'm3u' => 'audio/x-mpegurl', + 'ra' => 'audio/x-pn-realaudio', + 'wav' => 'audio/x-wav', + 'wma' => 'audio/x-ms-wma', + 'wax' => 'audio/x-ms-wax', + 'pdb' => 'chemical/x-pdb', + 'xyz' => 'chemical/x-xyz', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'ief' => 'image/ief', + 'png' => 'image/png', + 'wbmp' => 'image/vnd.wap.wbmp', + 'ras' => 'image/x-cmu-raster', + 'pnm' => 'image/x-portable-anymap', + 'pbm' => 'image/x-portable-bitmap', + 'pgm' => 'image/x-portable-graymap', + 'ppm' => 'image/x-portable-pixmap', + 'rgb' => 'image/x-rgb', + 'xbm' => 'image/x-xbitmap', + 'xpm' => 'image/x-xpixmap', + 'xwd' => 'image/x-xwindowdump', + 'css' => 'text/css', + 'rtx' => 'text/richtext', + 'tsv' => 'text/tab-separated-values', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'wml' => 'text/vnd.wap.wml', + 'wmls' => 'text/vnd.wap.wmlscript', + 'etx' => 'text/x-setext', + 'mxu' => 'video/vnd.mpegurl', + 'flv' => 'video/x-flv', + 'wm' => 'video/x-ms-wm', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wvx' => 'video/x-ms-wvx', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'ice' => 'x-conference/x-cooltalk', + '3gp' => 'video/3gpp', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'asc' => 'text/plain', + 'atom' => 'application/atom+xml', + 'au' => 'audio/basic', + 'bin' => 'application/octet-stream', + 'cdf' => 'application/x-netcdf', + 'cgm' => 'image/cgm', + 'class' => 'application/octet-stream', + 'dcr' => 'application/x-director', + 'dif' => 'video/x-dv', + 'dir' => 'application/x-director', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/octet-stream', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dtd' => 'application/xml-dtd', + 'dv' => 'video/x-dv', + 'dxr' => 'application/x-director', + 'eps' => 'application/postscript', + 'exe' => 'application/octet-stream', + 'ez' => 'application/andrew-inset', + 'gram' => 'application/srgs', + 'grxml' => 'application/srgs+xml', + 'gz' => 'application/x-gzip', + 'htm' => 'text/html', + 'html' => 'text/html', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ifb' => 'text/calendar', + 'iges' => 'model/iges', + 'igs' => 'model/iges', + 'jp2' => 'image/jp2', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'kar' => 'audio/midi', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'm4a' => 'audio/mp4a-latm', + 'm4p' => 'audio/mp4a-latm', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/x-m4v', + 'mac' => 'image/x-macpaint', + 'mathml' => 'application/mathml+xml', + 'mesh' => 'model/mesh', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mov' => 'video/quicktime', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpga' => 'audio/mpeg', + 'msh' => 'model/mesh', + 'nc' => 'application/x-netcdf', + 'oda' => 'application/oda', + 'ogv' => 'video/ogv', + 'pct' => 'image/pict', + 'pic' => 'image/pict', + 'pict' => 'image/pict', + 'pnt' => 'image/x-macpaint', + 'pntg' => 'image/x-macpaint', + 'ps' => 'application/postscript', + 'qt' => 'video/quicktime', + 'qti' => 'image/x-quicktime', + 'qtif' => 'image/x-quicktime', + 'ram' => 'audio/x-pn-realaudio', + 'rdf' => 'application/rdf+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'roff' => 'application/x-troff', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'silo' => 'model/mesh', + 'skd' => 'application/x-koan', + 'skm' => 'application/x-koan', + 'skp' => 'application/x-koan', + 'skt' => 'application/x-koan', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'snd' => 'audio/basic', + 'so' => 'application/octet-stream', + 'svg' => 'image/svg+xml', + 't' => 'application/x-troff', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tr' => 'application/x-troff', + 'txt' => 'text/plain', + 'vrml' => 'model/vrml', + 'vxml' => 'application/voicexml+xml', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wrl' => 'model/vrml', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xml' => 'application/xml', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + ); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Core/OssException.php b/vendor/oss-sdk/src/OSS/Core/OssException.php new file mode 100755 index 0000000..2320c9e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Core/OssException.php @@ -0,0 +1,54 @@ +<?php + +namespace OSS\Core; + +/** + * Class OssException + * + * This is the class that OSSClient is expected to thrown, which the caller needs to handle properly. + * It has the OSS specific errors which is useful for troubleshooting. + * + * @package OSS\Core + */ +class OssException extends \Exception +{ + private $details = array(); + + function __construct($details) + { + if (is_array($details)) { + $message = $details['code'] . ': ' . $details['message'] + . ' RequestId: ' . $details['request-id']; + parent::__construct($message); + $this->details = $details; + } else { + $message = $details; + parent::__construct($message); + } + } + + public function getHTTPStatus() + { + return isset($this->details['status']) ? $this->details['status'] : ''; + } + + public function getRequestId() + { + return isset($this->details['request-id']) ? $this->details['request-id'] : ''; + } + + public function getErrorCode() + { + return isset($this->details['code']) ? $this->details['code'] : ''; + } + + public function getErrorMessage() + { + return isset($this->details['message']) ? $this->details['message'] : ''; + } + + public function getDetails() + { + return isset($this->details['body']) ? $this->details['body'] : ''; + } +} diff --git a/vendor/oss-sdk/src/OSS/Core/OssUtil.php b/vendor/oss-sdk/src/OSS/Core/OssUtil.php new file mode 100755 index 0000000..01b960e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Core/OssUtil.php @@ -0,0 +1,464 @@ +<?php + +namespace OSS\Core; + +/** + * Class OssUtil + * + * Oss Util class for OssClient. The caller could use it for formating the result from OssClient. + * + * @package OSS + */ +class OssUtil +{ + const OSS_CONTENT = 'content'; + const OSS_LENGTH = 'length'; + const OSS_HEADERS = 'headers'; + const OSS_MAX_OBJECT_GROUP_VALUE = 1000; + const OSS_MAX_PART_SIZE = 5368709120; // 5GB + const OSS_MID_PART_SIZE = 10485760; // 10MB + const OSS_MIN_PART_SIZE = 102400; // 100KB + + /** + * Generate query params + * + * @param array $options: a key-value pair array. + * @return string: the key-value list in the format such as key1=value1&key2=value2 + */ + public static function toQueryString($options = array()) + { + $temp = array(); + uksort($options, 'strnatcasecmp'); + foreach ($options as $key => $value) { + if (is_string($key) && !is_array($value)) { + $temp[] = rawurlencode($key) . '=' . rawurlencode($value); + } + } + return implode('&', $temp); + } + + /** + * Html encoding '<', '>', '&', '\', '"' in subject parameter. + * + * @param string $subject + * @return string + */ + public static function sReplace($subject) + { + $search = array('<', '>', '&', '\'', '"'); + $replace = array('&lt;', '&gt;', '&amp;', '&apos;', '&quot;'); + return str_replace($search, $replace, $subject); + } + + /** + * Check whether the string includes any chinese character + * + * @param $str + * @return int + */ + public static function chkChinese($str) + { + return preg_match('/[\x80-\xff]./', $str); + } + + /** + * Checks if the string is encoded by GB2312. + * + * @param string $str + * @return boolean false UTF-8 encoding TRUE GB2312 encoding + */ + public static function isGb2312($str) + { + for ($i = 0; $i < strlen($str); $i++) { + $v = ord($str[$i]); + if ($v > 127) { + if (($v >= 228) && ($v <= 233)) { + if (($i + 2) >= (strlen($str) - 1)) return true; // not enough characters + $v1 = ord($str[$i + 1]); + $v2 = ord($str[$i + 2]); + if (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) + return false; + else + return true; + } + } + } + return false; + } + + /** + * Checks if the string is encoded by GBK + * + * @param string $str + * @param boolean $gbk + * @return boolean + */ + public static function checkChar($str, $gbk = true) + { + for ($i = 0; $i < strlen($str); $i++) { + $v = ord($str[$i]); + if ($v > 127) { + if (($v >= 228) && ($v <= 233)) { + if (($i + 2) >= (strlen($str) - 1)) return $gbk ? true : FALSE; // not enough characters + $v1 = ord($str[$i + 1]); + $v2 = ord($str[$i + 2]); + if ($gbk) { + return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? FALSE : TRUE;//GBK + } else { + return (($v1 >= 128) && ($v1 <= 191) && ($v2 >= 128) && ($v2 <= 191)) ? TRUE : FALSE; + } + } + } + } + return $gbk ? TRUE : FALSE; + } + + /** + * Checks if the bucket name is valid + * bucket naming rules + * 1. Can only include lowercase letters, numbers, or dashes + * 2. Must start and end with lowercase letters or numbers + * 3. Must be within a length from 3 to 63 bytes. + * + * @param string $bucket Bucket name + * @return boolean + */ + public static function validateBucket($bucket) + { + $pattern = '/^[a-z0-9][a-z0-9-]{2,62}$/'; + if (!preg_match($pattern, $bucket)) { + return false; + } + return true; + } + + /** + * Checks if object name is valid + * object naming rules: + * 1. Must be within a length from 1 to 1023 bytes + * 2. Cannot start with '/' or '\\'. + * 3. Must be encoded in UTF-8. + * + * @param string $object Object名称 + * @return boolean + */ + public static function validateObject($object) + { + $pattern = '/^.{1,1023}$/'; + if (empty($object) || !preg_match($pattern, $object) || + self::startsWith($object, '/') || self::startsWith($object, '\\') + ) { + return false; + } + return true; + } + + + /** + * Checks if $str starts with $findMe + * + * @param string $str + * @param string $findMe + * @return bool + */ + public static function startsWith($str, $findMe) + { + if (strpos($str, $findMe) === 0) { + return true; + } else { + return false; + } + } + + + /** + * Generate the xml message of createBucketXmlBody. + * + * @param string $storageClass + * @return string + */ + public static function createBucketXmlBody($storageClass) + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><CreateBucketConfiguration></CreateBucketConfiguration>'); + $xml->addChild('StorageClass', $storageClass); + return $xml->asXML(); + } + + /** + * validate $options + * + * @param array $options + * @throws OssException + * @return boolean + */ + public static function validateOptions($options) + { + //$options + if ($options != NULL && !is_array($options)) { + throw new OssException ($options . ':' . 'option must be array'); + } + } + + /** + * check whether the Content is valid. + * + * @param $content string + * @throws OssException + */ + public static function validateContent($content) + { + if (empty($content)) { + throw new OssException("http body content is invalid"); + } + } + + /** + * Check if BUCKET/OBJECT/OBJECT GROUP is empty. + * + * @param string $name + * @param string $errMsg + * @throws OssException + * @return void + */ + public static function throwOssExceptionWithMessageIfEmpty($name, $errMsg) + { + if (empty($name)) { + throw new OssException($errMsg); + } + } + + /** + * This is a method for test only. DO NOT USE. + * + * @param $filename + * @param $size + */ + public static function generateFile($filename, $size) + { + if (file_exists($filename) && $size == filesize($filename)) { + echo $filename . " already exists, no need to create again. "; + return; + } + $part_size = 1 * 1024 * 1024; + $fp = fopen($filename, "w"); + $characters = <<<BBB +0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; +BBB; + + $charactersLength = strlen($characters); + if ($fp) { + while ($size > 0) { + if ($size < $part_size) { + $write_size = $size; + } else { + $write_size = $part_size; + } + $size -= $write_size; + $a = $characters[rand(0, $charactersLength - 1)]; + $content = str_repeat($a, $write_size); + $flag = fwrite($fp, $content); + if (!$flag) { + echo "write to " . $filename . " failed. <br>"; + break; + } + } + } else { + echo "open " . $filename . " failed. <br>"; + } + fclose($fp); + } + + /** + * Get MD5 of the file. + * + * @param $filename + * @param $from_pos + * @param $to_pos + * @return string + */ + public static function getMd5SumForFile($filename, $from_pos, $to_pos) + { + $content_md5 = ""; + if (($to_pos - $from_pos) > self::OSS_MAX_PART_SIZE) { + return $content_md5; + } + $filesize = filesize($filename); + if ($from_pos >= $filesize || $to_pos >= $filesize || $from_pos < 0 || $to_pos < 0) { + return $content_md5; + } + + $total_length = $to_pos - $from_pos + 1; + $buffer = 8192; + $left_length = $total_length; + if (!file_exists($filename)) { + return $content_md5; + } + + if (false === $fh = fopen($filename, 'rb')) { + return $content_md5; + } + + fseek($fh, $from_pos); + $data = ''; + while (!feof($fh)) { + if ($left_length >= $buffer) { + $read_length = $buffer; + } else { + $read_length = $left_length; + } + if ($read_length <= 0) { + break; + } else { + $data .= fread($fh, $read_length); + $left_length = $left_length - $read_length; + } + } + fclose($fh); + $content_md5 = base64_encode(md5($data, true)); + return $content_md5; + } + + /** + * Check if the OS is Windows. The default encoding in Windows is GBK. + * + * @return bool + */ + public static function isWin() + { + return strtoupper(substr(PHP_OS, 0, 3)) == "WIN"; + } + + /** + * Encodes the file path from GBK to UTF-8. + * The default encoding in Windows is GBK. + * And if the file path is in Chinese, the file would not be found without the transcoding to UTF-8. + * + * @param $file_path + * @return string + */ + public static function encodePath($file_path) + { + if (self::chkChinese($file_path) && self::isWin()) { + $file_path = iconv('utf-8', 'gbk', $file_path); + } + return $file_path; + } + + /** + * Check if the endpoint is in the IPv4 format, such as xxx.xxx.xxx.xxx:port or xxx.xxx.xxx.xxx. + * + * @param string $endpoint The endpoint to check. + * @return boolean + */ + public static function isIPFormat($endpoint) + { + $ip_array = explode(":", $endpoint); + $hostname = $ip_array[0]; + $ret = filter_var($hostname, FILTER_VALIDATE_IP); + if (!$ret) { + return false; + } else { + return true; + } + } + + /** + * Generate the xml message of DeleteMultiObjects. + * + * @param string[] $objects + * @param bool $quiet + * @return string + */ + public static function createDeleteObjectsXmlBody($objects, $quiet) + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><Delete></Delete>'); + $xml->addChild('Quiet', $quiet); + foreach ($objects as $object) { + $sub_object = $xml->addChild('Object'); + $object = OssUtil::sReplace($object); + $sub_object->addChild('Key', $object); + } + return $xml->asXML(); + } + + /** + * Generate the xml message of CompleteMultipartUpload. + * + * @param array[] $listParts + * @return string + */ + public static function createCompleteMultipartUploadXmlBody($listParts) + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><CompleteMultipartUpload></CompleteMultipartUpload>'); + foreach ($listParts as $node) { + $part = $xml->addChild('Part'); + $part->addChild('PartNumber', $node['PartNumber']); + $part->addChild('ETag', $node['ETag']); + } + return $xml->asXML(); + } + + /** + * Read the directory, return a associative array in which the MD5 is the named key and the <path,filanme> is the value. + * + * @param string $dir + * @param string $exclude + * @param bool $recursive + * @return string[] + */ + public static function readDir($dir, $exclude = ".|..|.svn|.git", $recursive = false) + { + $file_list_array = array(); + $base_path = $dir; + $exclude_array = explode("|", $exclude); + $exclude_array = array_unique(array_merge($exclude_array, array('.', '..'))); + + if ($recursive) { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir)) as $new_file) { + if ($new_file->isDir()) continue; + $object = str_replace($base_path, '', $new_file); + if (!in_array(strtolower($object), $exclude_array)) { + $object = ltrim($object, '/'); + if (is_file($new_file)) { + $key = md5($new_file . $object, false); + $file_list_array[$key] = array('path' => $new_file, 'file' => $object,); + } + } + } + } else if ($handle = opendir($dir)) { + while (false !== ($file = readdir($handle))) { + if (!in_array(strtolower($file), $exclude_array)) { + $new_file = $dir . '/' . $file; + $object = $file; + $object = ltrim($object, '/'); + if (is_file($new_file)) { + $key = md5($new_file . $object, false); + $file_list_array[$key] = array('path' => $new_file, 'file' => $object,); + } + } + } + closedir($handle); + } + return $file_list_array; + } + + /** + * Decode key based on the encoding type + * + * @param string $key + * @param string $encoding + * @return string + */ + public static function decodeKey($key, $encoding) + { + if ($encoding == "") { + return $key; + } + + if ($encoding == "url") { + return rawurldecode($key); + } else { + throw new OssException("Unrecognized encoding type: " . $encoding); + } + } +} diff --git a/vendor/oss-sdk/src/OSS/Http/LICENSE b/vendor/oss-sdk/src/OSS/Http/LICENSE new file mode 100755 index 0000000..49b38bd --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Http/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2006-2010 Ryan Parman, Foleeo Inc., and contributors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of Ryan Parman, Foleeo Inc. nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS +AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/oss-sdk/src/OSS/Http/RequestCore.php b/vendor/oss-sdk/src/OSS/Http/RequestCore.php new file mode 100755 index 0000000..26a167a --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Http/RequestCore.php @@ -0,0 +1,892 @@ +<?php +namespace OSS\Http; + + +/** + * Handle all HTTP requests using cURL and manages the responses. + * + * @version 2011.06.07 + * @copyright 2006-2011 Ryan Parman + * @copyright 2006-2010 Foleeo Inc. + * @copyright 2010-2011 Amazon.com, Inc. or its affiliates. + * @copyright 2008-2011 Contributors + * @license http://opensource.org/licenses/bsd-license.php Simplified BSD License + */ +class RequestCore +{ + /** + * The URL being requested. + */ + public $request_url; + + /** + * The headers being sent in the request. + */ + public $request_headers; + + /** + * The raw response callback headers + */ + public $response_raw_headers; + + /** + * Response body when error occurs + */ + public $response_error_body; + + /** + *The hander of write file + */ + public $write_file_handle; + + /** + * The body being sent in the request. + */ + public $request_body; + + /** + * The response returned by the request. + */ + public $response; + + /** + * The headers returned by the request. + */ + public $response_headers; + + /** + * The body returned by the request. + */ + public $response_body; + + /** + * The HTTP status code returned by the request. + */ + public $response_code; + + /** + * Additional response data. + */ + public $response_info; + + /** + * The method by which the request is being made. + */ + public $method; + + /** + * Store the proxy settings to use for the request. + */ + public $proxy = null; + + /** + * The username to use for the request. + */ + public $username = null; + + /** + * The password to use for the request. + */ + public $password = null; + + /** + * Custom CURLOPT settings. + */ + public $curlopts = null; + + /** + * The state of debug mode. + */ + public $debug_mode = false; + + /** + * The default class to use for HTTP Requests (defaults to <RequestCore>). + */ + public $request_class = 'OSS\Http\RequestCore'; + + /** + * The default class to use for HTTP Responses (defaults to <ResponseCore>). + */ + public $response_class = 'OSS\Http\ResponseCore'; + + /** + * Default useragent string to use. + */ + public $useragent = 'RequestCore/1.4.3'; + + /** + * File to read from while streaming up. + */ + public $read_file = null; + + /** + * The resource to read from while streaming up. + */ + public $read_stream = null; + + /** + * The size of the stream to read from. + */ + public $read_stream_size = null; + + /** + * The length already read from the stream. + */ + public $read_stream_read = 0; + + /** + * File to write to while streaming down. + */ + public $write_file = null; + + /** + * The resource to write to while streaming down. + */ + public $write_stream = null; + + /** + * Stores the intended starting seek position. + */ + public $seek_position = null; + + /** + * The location of the cacert.pem file to use. + */ + public $cacert_location = false; + + /** + * The state of SSL certificate verification. + */ + public $ssl_verification = true; + + /** + * The user-defined callback function to call when a stream is read from. + */ + public $registered_streaming_read_callback = null; + + /** + * The user-defined callback function to call when a stream is written to. + */ + public $registered_streaming_write_callback = null; + + /** + * The request timeout time, which is 5,184,000 seconds,that is, 6 days by default + * + * @var int + */ + public $timeout = 5184000; + + /** + * The connection timeout time, which is 10 seconds by default + * + * @var int + */ + public $connect_timeout = 10; + + /*%******************************************************************************************%*/ + // CONSTANTS + + /** + * GET HTTP Method + */ + const HTTP_GET = 'GET'; + + /** + * POST HTTP Method + */ + const HTTP_POST = 'POST'; + + /** + * PUT HTTP Method + */ + const HTTP_PUT = 'PUT'; + + /** + * DELETE HTTP Method + */ + const HTTP_DELETE = 'DELETE'; + + /** + * HEAD HTTP Method + */ + const HTTP_HEAD = 'HEAD'; + + + /*%******************************************************************************************%*/ + // CONSTRUCTOR/DESTRUCTOR + + /** + * Construct a new instance of this class. + * + * @param string $url (Optional) The URL to request or service endpoint to query. + * @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. + * @return $this A reference to the current instance. + */ + public function __construct($url = null, $proxy = null, $helpers = null) + { + // Set some default values. + $this->request_url = $url; + $this->method = self::HTTP_GET; + $this->request_headers = array(); + $this->request_body = ''; + + // Set a new Request class if one was set. + if (isset($helpers['request']) && !empty($helpers['request'])) { + $this->request_class = $helpers['request']; + } + + // Set a new Request class if one was set. + if (isset($helpers['response']) && !empty($helpers['response'])) { + $this->response_class = $helpers['response']; + } + + if ($proxy) { + $this->set_proxy($proxy); + } + + return $this; + } + + /** + * Destruct the instance. Closes opened file handles. + * + * @return $this A reference to the current instance. + */ + public function __destruct() + { + if (isset($this->read_file) && isset($this->read_stream)) { + fclose($this->read_stream); + } + + if (isset($this->write_file) && isset($this->write_stream)) { + fclose($this->write_stream); + } + + return $this; + } + + + /*%******************************************************************************************%*/ + // REQUEST METHODS + + /** + * Set the credentials to use for authentication. + * + * @param string $user (Required) The username to authenticate with. + * @param string $pass (Required) The password to authenticate with. + * @return $this A reference to the current instance. + */ + public function set_credentials($user, $pass) + { + $this->username = $user; + $this->password = $pass; + return $this; + } + + /** + * Add a custom HTTP header to the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @param mixed $value (Required) The value to assign to the custom HTTP header. + * @return $this A reference to the current instance. + */ + public function add_header($key, $value) + { + $this->request_headers[$key] = $value; + return $this; + } + + /** + * Remove an HTTP header from the cURL request. + * + * @param string $key (Required) The custom HTTP header to set. + * @return $this A reference to the current instance. + */ + public function remove_header($key) + { + if (isset($this->request_headers[$key])) { + unset($this->request_headers[$key]); + } + return $this; + } + + /** + * Set the method type for the request. + * + * @param string $method (Required) One of the following constants: <HTTP_GET>, <HTTP_POST>, <HTTP_PUT>, <HTTP_HEAD>, <HTTP_DELETE>. + * @return $this A reference to the current instance. + */ + public function set_method($method) + { + $this->method = strtoupper($method); + return $this; + } + + /** + * Set a custom useragent string for the class. + * + * @param string $ua (Required) The useragent string to use. + * @return $this A reference to the current instance. + */ + public function set_useragent($ua) + { + $this->useragent = $ua; + return $this; + } + + /** + * Set the body to send in the request. + * + * @param string $body (Required) The textual content to send along in the body of the request. + * @return $this A reference to the current instance. + */ + public function set_body($body) + { + $this->request_body = $body; + return $this; + } + + /** + * Set the URL to make the request to. + * + * @param string $url (Required) The URL to make the request to. + * @return $this A reference to the current instance. + */ + public function set_request_url($url) + { + $this->request_url = $url; + return $this; + } + + /** + * Set additional CURLOPT settings. These will merge with the default settings, and override if + * there is a duplicate. + * + * @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. + * @return $this A reference to the current instance. + */ + public function set_curlopts($curlopts) + { + $this->curlopts = $curlopts; + return $this; + } + + /** + * Set the length in bytes to read from the stream while streaming up. + * + * @param integer $size (Required) The length in bytes to read from the stream. + * @return $this A reference to the current instance. + */ + public function set_read_stream_size($size) + { + $this->read_stream_size = $size; + + return $this; + } + + /** + * Set the resource to read from while streaming up. Reads the stream from its current position until + * EOF or `$size` bytes have been read. If `$size` is not given it will be determined by <php:fstat()> and + * <php:ftell()>. + * + * @param resource $resource (Required) The readable resource to read from. + * @param integer $size (Optional) The size of the stream to read. + * @return $this A reference to the current instance. + */ + public function set_read_stream($resource, $size = null) + { + if (!isset($size) || $size < 0) { + $stats = fstat($resource); + + if ($stats && $stats['size'] >= 0) { + $position = ftell($resource); + + if ($position !== false && $position >= 0) { + $size = $stats['size'] - $position; + } + } + } + + $this->read_stream = $resource; + + return $this->set_read_stream_size($size); + } + + /** + * Set the file to read from while streaming up. + * + * @param string $location (Required) The readable location to read from. + * @return $this A reference to the current instance. + */ + public function set_read_file($location) + { + $this->read_file = $location; + $read_file_handle = fopen($location, 'r'); + + return $this->set_read_stream($read_file_handle); + } + + /** + * Set the resource to write to while streaming down. + * + * @param resource $resource (Required) The writeable resource to write to. + * @return $this A reference to the current instance. + */ + public function set_write_stream($resource) + { + $this->write_stream = $resource; + + return $this; + } + + /** + * Set the file to write to while streaming down. + * + * @param string $location (Required) The writeable location to write to. + * @return $this A reference to the current instance. + */ + public function set_write_file($location) + { + $this->write_file = $location; + } + + /** + * Set the proxy to use for making requests. + * + * @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` + * @return $this A reference to the current instance. + */ + public function set_proxy($proxy) + { + $proxy = parse_url($proxy); + $proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null; + $proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null; + $proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null; + $this->proxy = $proxy; + return $this; + } + + /** + * Set the intended starting seek position. + * + * @param integer $position (Required) The byte-position of the stream to begin reading from. + * @return $this A reference to the current instance. + */ + public function set_seek_position($position) + { + $this->seek_position = isset($position) ? (integer)$position : null; + + return $this; + } + + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $header_content (Required) The header callback result. + * @return headers from a stream. + */ + public function streaming_header_callback($curl_handle, $header_content) + { + $code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + + if (isset($this->write_file) && intval($code) / 100 == 2 && !isset($this->write_file_handle)) + { + $this->write_file_handle = fopen($this->write_file, 'w'); + $this->set_write_stream($this->write_file_handle); + } + + $this->response_raw_headers .= $header_content; + return strlen($header_content); + } + + + /** + * Register a callback function to execute whenever a data stream is read from using + * <CFRequest::streaming_read_callback()>. + * + * The user-defined callback function should accept three arguments: + * + * <ul> + * <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li> + * <li><code>$file_handle</code> - <code>resource</code> - Required - The file handle resource that represents the file on the local file system.</li> + * <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li> + * </ul> + * + * @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul> + * <li>The name of a global function to execute, passed as a string.</li> + * <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li> + * <li>An anonymous function (PHP 5.3+).</li></ul> + * @return $this A reference to the current instance. + */ + public function register_streaming_read_callback($callback) + { + $this->registered_streaming_read_callback = $callback; + + return $this; + } + + /** + * Register a callback function to execute whenever a data stream is written to using + * <CFRequest::streaming_write_callback()>. + * + * The user-defined callback function should accept two arguments: + * + * <ul> + * <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li> + * <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li> + * </ul> + * + * @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul> + * <li>The name of a global function to execute, passed as a string.</li> + * <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li> + * <li>An anonymous function (PHP 5.3+).</li></ul> + * @return $this A reference to the current instance. + */ + public function register_streaming_write_callback($callback) + { + $this->registered_streaming_write_callback = $callback; + + return $this; + } + + + /*%******************************************************************************************%*/ + // PREPARE, SEND, AND PROCESS REQUEST + + /** + * A callback function that is invoked by cURL for streaming up. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param resource $file_handle (Required) The open file handle resource. + * @param integer $length (Required) The maximum number of bytes to read. + * @return binary Binary data from a stream. + */ + public function streaming_read_callback($curl_handle, $file_handle, $length) + { + // Once we've sent as much as we're supposed to send... + if ($this->read_stream_read >= $this->read_stream_size) { + // Send EOF + return ''; + } + + // If we're at the beginning of an upload and need to seek... + if ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream)) { + if (fseek($this->read_stream, $this->seek_position) !== 0) { + throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.'); + } + } + + $read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size + $this->read_stream_read += strlen($read); + + $out = $read === false ? '' : $read; + + // Execute callback function + if ($this->registered_streaming_read_callback) { + call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out); + } + + return $out; + } + + /** + * A callback function that is invoked by cURL for streaming down. + * + * @param resource $curl_handle (Required) The cURL handle for the request. + * @param binary $data (Required) The data to write. + * @return integer The number of bytes written. + */ + public function streaming_write_callback($curl_handle, $data) + { + $code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + + if (intval($code) / 100 != 2) + { + $this->response_error_body .= $data; + return strlen($data); + } + + $length = strlen($data); + $written_total = 0; + $written_last = 0; + + while ($written_total < $length) { + $written_last = fwrite($this->write_stream, substr($data, $written_total)); + + if ($written_last === false) { + return $written_total; + } + + $written_total += $written_last; + } + + // Execute callback function + if ($this->registered_streaming_write_callback) { + call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total); + } + + return $written_total; + } + + /** + * Prepare and adds the details of the cURL request. This can be passed along to a <php:curl_multi_exec()> + * function. + * + * @return resource The handle for the cURL object. + * + */ + public function prep_request() + { + $curl_handle = curl_init(); + + // Set default options. + curl_setopt($curl_handle, CURLOPT_URL, $this->request_url); + curl_setopt($curl_handle, CURLOPT_FILETIME, true); + curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false); +// curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED); + curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5); + curl_setopt($curl_handle, CURLOPT_HEADER, true); + curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl_handle, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $this->connect_timeout); + curl_setopt($curl_handle, CURLOPT_NOSIGNAL, true); + curl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url); + curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent); + curl_setopt($curl_handle, CURLOPT_HEADERFUNCTION, array($this, 'streaming_header_callback')); + curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback')); + + // Verification of the SSL cert + if ($this->ssl_verification) { + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); + } else { + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false); + } + + // chmod the file as 0755 + if ($this->cacert_location === true) { + curl_setopt($curl_handle, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); + } elseif (is_string($this->cacert_location)) { + curl_setopt($curl_handle, CURLOPT_CAINFO, $this->cacert_location); + } + + // Debug mode + if ($this->debug_mode) { + curl_setopt($curl_handle, CURLOPT_VERBOSE, true); + } + + // Handle open_basedir & safe mode + if (!ini_get('safe_mode') && !ini_get('open_basedir')) { + curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); + } + + // Enable a proxy connection if requested. + if ($this->proxy) { + $host = $this->proxy['host']; + $host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : ''; + curl_setopt($curl_handle, CURLOPT_PROXY, $host); + + if (isset($this->proxy['user']) && isset($this->proxy['pass'])) { + curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); + } + } + + // Set credentials for HTTP Basic/Digest Authentication. + if ($this->username && $this->password) { + curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password); + } + + // Handle the encoding if we can. + if (extension_loaded('zlib')) { + curl_setopt($curl_handle, CURLOPT_ENCODING, ''); + } + + // Process custom headers + if (isset($this->request_headers) && count($this->request_headers)) { + $temp_headers = array(); + + foreach ($this->request_headers as $k => $v) { + $temp_headers[] = $k . ': ' . $v; + } + + curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers); + } + + switch ($this->method) { + case self::HTTP_PUT: + //unset($this->read_stream); + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT'); + if (isset($this->read_stream)) { + if (!isset($this->read_stream_size) || $this->read_stream_size < 0) { + throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); + } + curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); + curl_setopt($curl_handle, CURLOPT_UPLOAD, true); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + + case self::HTTP_POST: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST'); + if (isset($this->read_stream)) { + if (!isset($this->read_stream_size) || $this->read_stream_size < 0) { + throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); + } + curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); + curl_setopt($curl_handle, CURLOPT_UPLOAD, true); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + + case self::HTTP_HEAD: + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD); + curl_setopt($curl_handle, CURLOPT_NOBODY, 1); + break; + + default: // Assumed GET + curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method); + if (isset($this->write_stream) || isset($this->write_file)) { + curl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array($this, 'streaming_write_callback')); + curl_setopt($curl_handle, CURLOPT_HEADER, false); + } else { + curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); + } + break; + } + + // Merge in the CURLOPTs + if (isset($this->curlopts) && sizeof($this->curlopts) > 0) { + foreach ($this->curlopts as $k => $v) { + curl_setopt($curl_handle, $k, $v); + } + } + + return $curl_handle; + } + + /** + * Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the + * data stored in the `curl_handle` and `response` properties unless replacement data is passed in via + * parameters. + * + * @param resource $curl_handle (Optional) The reference to the already executed cURL request. + * @param string $response (Optional) The actual response content itself that needs to be parsed. + * @return ResponseCore A <ResponseCore> object containing a parsed HTTP response. + */ + public function process_response($curl_handle = null, $response = null) + { + // Accept a custom one if it's passed. + if ($curl_handle && $response) { + $this->response = $response; + } + + // As long as this came back as a valid resource... + if (is_resource($curl_handle)) { + // Determine what's what. + $header_size = curl_getinfo($curl_handle, CURLINFO_HEADER_SIZE); + $this->response_headers = substr($this->response, 0, $header_size); + $this->response_body = substr($this->response, $header_size); + $this->response_code = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); + $this->response_info = curl_getinfo($curl_handle); + + if (intval($this->response_code) / 100 != 2 && isset($this->write_file)) + { + $this->response_headers = $this->response_raw_headers; + $this->response_body = $this->response_error_body; + } + + // Parse out the headers + $this->response_headers = explode("\r\n\r\n", trim($this->response_headers)); + $this->response_headers = array_pop($this->response_headers); + $this->response_headers = explode("\r\n", $this->response_headers); + array_shift($this->response_headers); + + // Loop through and split up the headers. + $header_assoc = array(); + foreach ($this->response_headers as $header) { + $kv = explode(': ', $header); + $header_assoc[strtolower($kv[0])] = isset($kv[1]) ? $kv[1] : ''; + } + + // Reset the headers to the appropriate property. + $this->response_headers = $header_assoc; + $this->response_headers['info'] = $this->response_info; + $this->response_headers['info']['method'] = $this->method; + + if ($curl_handle && $response) { + return new ResponseCore($this->response_headers, $this->response_body, $this->response_code); + } + } + + // Return false + return false; + } + + /** + * Send the request, calling necessary utility functions to update built-in properties. + * + * @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not. + * @return string The resulting unparsed data from the request. + */ + public function send_request($parse = false) + { + set_time_limit(0); + + $curl_handle = $this->prep_request(); + $this->response = curl_exec($curl_handle); + if ($this->response === false) { + throw new RequestCore_Exception('cURL resource: ' . (string)$curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')'); + } + + $parsed_response = $this->process_response($curl_handle, $this->response); + curl_close($curl_handle); + + if ($parse) { + return $parsed_response; + } + return $this->response; + } + + /*%******************************************************************************************%*/ + // RESPONSE METHODS + + /** + * Get the HTTP response headers from the request. + * + * @param string $header (Optional) A specific header value to return. Defaults to all headers. + * @return string|array All or selected header values. + */ + public function get_response_header($header = null) + { + if ($header) { + return $this->response_headers[strtolower($header)]; + } + return $this->response_headers; + } + + /** + * Get the HTTP response body from the request. + * + * @return string The response body. + */ + public function get_response_body() + { + return $this->response_body; + } + + /** + * Get the HTTP response code from the request. + * + * @return string The HTTP response code. + */ + public function get_response_code() + { + return $this->response_code; + } +} diff --git a/vendor/oss-sdk/src/OSS/Http/RequestCore_Exception.php b/vendor/oss-sdk/src/OSS/Http/RequestCore_Exception.php new file mode 100755 index 0000000..cb4e83c --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Http/RequestCore_Exception.php @@ -0,0 +1,8 @@ +<?php + +namespace OSS\Http; + +class RequestCore_Exception extends \Exception +{ + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Http/ResponseCore.php b/vendor/oss-sdk/src/OSS/Http/ResponseCore.php new file mode 100755 index 0000000..b7c6d0b --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Http/ResponseCore.php @@ -0,0 +1,56 @@ +<?php + +namespace OSS\Http; + +/** + * Container for all response-related methods. + */ +class ResponseCore +{ + /** + * Store the HTTP header information. + */ + public $header; + + /** + * Store the SimpleXML response. + */ + public $body; + + /** + * Store the HTTP response code. + */ + public $status; + + /** + * Construct a new instance of this class. + * + * @param array $header (Required) Associative array of HTTP headers (typically returned by <RequestCore::get_response_header()>). + * @param string $body (Required) XML-formatted response from AWS. + * @param integer $status (Optional) HTTP response status code from the request. + * @return Mixed Contains an <php:array> `header` property (HTTP headers as an associative array), a <php:SimpleXMLElement> or <php:string> `body` property, and an <php:integer> `status` code. + */ + public function __construct($header, $body, $status = null) + { + $this->header = $header; + $this->body = $body; + $this->status = $status; + + return $this; + } + + /** + * Did we receive the status code we expected? + * + * @param integer|array $codes (Optional) The status code(s) to expect. Pass an <php:integer> for a single acceptable value, or an <php:array> of integers for multiple acceptable values. + * @return boolean Whether we received the expected status code or not. + */ + public function isOK($codes = array(200, 201, 204, 206)) + { + if (is_array($codes)) { + return in_array($this->status, $codes); + } + + return $this->status === $codes; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/BucketInfo.php b/vendor/oss-sdk/src/OSS/Model/BucketInfo.php new file mode 100755 index 0000000..09e7dea --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/BucketInfo.php @@ -0,0 +1,78 @@ +<?php + +namespace OSS\Model; + + +/** + * Bucket information class. This is the type of element in BucketListInfo's + * + * Class BucketInfo + * @package OSS\Model + */ +class BucketInfo +{ + /** + * BucketInfo constructor. + * + * @param string $location + * @param string $name + * @param string $createDate + */ + public function __construct($location, $name, $createDate) + { + $this->location = $location; + $this->name = $name; + $this->createDate = $createDate; + } + + /** + * Get bucket location + * + * @return string + */ + public function getLocation() + { + return $this->location; + } + + /** + * Get bucket name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get bucket creation time. + * + * @return string + */ + public function getCreateDate() + { + return $this->createDate; + } + + /** + * bucket region + * + * @var string + */ + private $location; + /** + * bucket name + * + * @var string + */ + private $name; + + /** + * bucket creation time + * + * @var string + */ + private $createDate; + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/BucketListInfo.php b/vendor/oss-sdk/src/OSS/Model/BucketListInfo.php new file mode 100755 index 0000000..ce03a0d --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/BucketListInfo.php @@ -0,0 +1,39 @@ +<?php + +namespace OSS\Model; + +/** + * Class BucketListInfo + * + * It's the type of return value of ListBuckets. + * + * @package OSS\Model + */ +class BucketListInfo +{ + /** + * BucketListInfo constructor. + * @param array $bucketList + */ + public function __construct(array $bucketList) + { + $this->bucketList = $bucketList; + } + + /** + * Get the BucketInfo list + * + * @return BucketInfo[] + */ + public function getBucketList() + { + return $this->bucketList; + } + + /** + * BucketInfo list + * + * @var array + */ + private $bucketList = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/CnameConfig.php b/vendor/oss-sdk/src/OSS/Model/CnameConfig.php new file mode 100755 index 0000000..f3597d2 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/CnameConfig.php @@ -0,0 +1,99 @@ +<?php + +namespace OSS\Model; + + +use OSS\Core\OssException; + +/** + * Class CnameConfig + * @package OSS\Model + * + * TODO: fix link + * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/PutBucketcors.html + */ +class CnameConfig implements XmlConfig +{ + public function __construct() + { + $this->cnameList = array(); + } + + /** + * @return array + * @example + * array(2) { + * [0]=> + * array(3) { + * ["Domain"]=> + * string(11) "www.foo.com" + * ["Status"]=> + * string(7) "enabled" + * ["LastModified"]=> + * string(8) "20150101" + * } + * [1]=> + * array(3) { + * ["Domain"]=> + * string(7) "bar.com" + * ["Status"]=> + * string(8) "disabled" + * ["LastModified"]=> + * string(8) "20160101" + * } + * } + */ + public function getCnames() + { + return $this->cnameList; + } + + + public function addCname($cname) + { + if (count($this->cnameList) >= self::OSS_MAX_RULES) { + throw new OssException( + "num of cname in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES)); + } + $this->cnameList[] = array('Domain' => $cname); + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->Cname)) return; + foreach ($xml->Cname as $entry) { + $cname = array(); + foreach ($entry as $key => $value) { + $cname[strval($key)] = strval($value); + } + $this->cnameList[] = $cname; + } + } + + public function serializeToXml() + { + $strXml = <<<EOF +<?xml version="1.0" encoding="utf-8"?> +<BucketCnameConfiguration> +</BucketCnameConfiguration> +EOF; + $xml = new \SimpleXMLElement($strXml); + foreach ($this->cnameList as $cname) { + $node = $xml->addChild('Cname'); + foreach ($cname as $key => $value) { + $node->addChild($key, $value); + } + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + const OSS_MAX_RULES = 10; + + private $cnameList = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/CorsConfig.php b/vendor/oss-sdk/src/OSS/Model/CorsConfig.php new file mode 100755 index 0000000..62a0d71 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/CorsConfig.php @@ -0,0 +1,113 @@ +<?php + +namespace OSS\Model; + + +use OSS\Core\OssException; + +/** + * Class CorsConfig + * @package OSS\Model + * + * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/PutBucketcors.html + */ +class CorsConfig implements XmlConfig +{ + /** + * CorsConfig constructor. + */ + public function __construct() + { + $this->rules = array(); + } + + /** + * Get CorsRule list + * + * @return CorsRule[] + */ + public function getRules() + { + return $this->rules; + } + + + /** + * Add a new CorsRule + * + * @param CorsRule $rule + * @throws OssException + */ + public function addRule($rule) + { + if (count($this->rules) >= self::OSS_MAX_RULES) { + throw new OssException("num of rules in the config exceeds self::OSS_MAX_RULES: " . strval(self::OSS_MAX_RULES)); + } + $this->rules[] = $rule; + } + + /** + * Parse CorsConfig from the xml. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->CORSRule)) return; + foreach ($xml->CORSRule as $rule) { + $corsRule = new CorsRule(); + foreach ($rule as $key => $value) { + if ($key === self::OSS_CORS_ALLOWED_HEADER) { + $corsRule->addAllowedHeader(strval($value)); + } elseif ($key === self::OSS_CORS_ALLOWED_METHOD) { + $corsRule->addAllowedMethod(strval($value)); + } elseif ($key === self::OSS_CORS_ALLOWED_ORIGIN) { + $corsRule->addAllowedOrigin(strval($value)); + } elseif ($key === self::OSS_CORS_EXPOSE_HEADER) { + $corsRule->addExposeHeader(strval($value)); + } elseif ($key === self::OSS_CORS_MAX_AGE_SECONDS) { + $corsRule->setMaxAgeSeconds(strval($value)); + } + } + $this->addRule($corsRule); + } + return; + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><CORSConfiguration></CORSConfiguration>'); + foreach ($this->rules as $rule) { + $xmlRule = $xml->addChild('CORSRule'); + $rule->appendToXml($xmlRule); + } + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + const OSS_CORS_ALLOWED_ORIGIN = 'AllowedOrigin'; + const OSS_CORS_ALLOWED_METHOD = 'AllowedMethod'; + const OSS_CORS_ALLOWED_HEADER = 'AllowedHeader'; + const OSS_CORS_EXPOSE_HEADER = 'ExposeHeader'; + const OSS_CORS_MAX_AGE_SECONDS = 'MaxAgeSeconds'; + const OSS_MAX_RULES = 10; + + /** + * CorsRule list + * + * @var CorsRule[] + */ + private $rules = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/CorsRule.php b/vendor/oss-sdk/src/OSS/Model/CorsRule.php new file mode 100755 index 0000000..08353a0 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/CorsRule.php @@ -0,0 +1,150 @@ +<?php + +namespace OSS\Model; + +use OSS\Core\OssException; + + +/** + * Class CorsRule + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/PutBucketcors.html + */ +class CorsRule +{ + /** + * Add an allowedOrigin rule + * + * @param string $allowedOrigin + */ + public function addAllowedOrigin($allowedOrigin) + { + if (!empty($allowedOrigin)) { + $this->allowedOrigins[] = $allowedOrigin; + } + } + + /** + * Add an allowedMethod rule + * + * @param string $allowedMethod + */ + public function addAllowedMethod($allowedMethod) + { + if (!empty($allowedMethod)) { + $this->allowedMethods[] = $allowedMethod; + } + } + + /** + * Add an allowedHeader rule + * + * @param string $allowedHeader + */ + public function addAllowedHeader($allowedHeader) + { + if (!empty($allowedHeader)) { + $this->allowedHeaders[] = $allowedHeader; + } + } + + /** + * Add an exposeHeader rule + * + * @param string $exposeHeader + */ + public function addExposeHeader($exposeHeader) + { + if (!empty($exposeHeader)) { + $this->exposeHeaders[] = $exposeHeader; + } + } + + /** + * @return int + */ + public function getMaxAgeSeconds() + { + return $this->maxAgeSeconds; + } + + /** + * @param int $maxAgeSeconds + */ + public function setMaxAgeSeconds($maxAgeSeconds) + { + $this->maxAgeSeconds = $maxAgeSeconds; + } + + /** + * Get the AllowedHeaders list + * + * @return string[] + */ + public function getAllowedHeaders() + { + return $this->allowedHeaders; + } + + /** + * Get the AllowedOrigins list + * + * @return string[] + */ + public function getAllowedOrigins() + { + return $this->allowedOrigins; + } + + /** + * Get the AllowedMethods list + * + * @return string[] + */ + public function getAllowedMethods() + { + return $this->allowedMethods; + } + + /** + * Get the ExposeHeaders list + * + * @return string[] + */ + public function getExposeHeaders() + { + return $this->exposeHeaders; + } + + /** + * Serialize all the rules into the xml represented by parameter $xmlRule + * + * @param \SimpleXMLElement $xmlRule + * @throws OssException + */ + public function appendToXml(&$xmlRule) + { + if (!isset($this->maxAgeSeconds)) { + throw new OssException("maxAgeSeconds is not set in the Rule"); + } + foreach ($this->allowedOrigins as $allowedOrigin) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_ORIGIN, $allowedOrigin); + } + foreach ($this->allowedMethods as $allowedMethod) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_METHOD, $allowedMethod); + } + foreach ($this->allowedHeaders as $allowedHeader) { + $xmlRule->addChild(CorsConfig::OSS_CORS_ALLOWED_HEADER, $allowedHeader); + } + foreach ($this->exposeHeaders as $exposeHeader) { + $xmlRule->addChild(CorsConfig::OSS_CORS_EXPOSE_HEADER, $exposeHeader); + } + $xmlRule->addChild(CorsConfig::OSS_CORS_MAX_AGE_SECONDS, strval($this->maxAgeSeconds)); + } + + private $allowedHeaders = array(); + private $allowedOrigins = array(); + private $allowedMethods = array(); + private $exposeHeaders = array(); + private $maxAgeSeconds = null; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/GetLiveChannelHistory.php b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelHistory.php new file mode 100755 index 0000000..6643444 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelHistory.php @@ -0,0 +1,34 @@ +<?php + +namespace OSS\Model; +/** + * Class GetLiveChannelHistory + * @package OSS\Model + */ +class GetLiveChannelHistory implements XmlConfig +{ + public function getLiveRecordList() + { + return $this->liveRecordList; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + if (isset($xml->LiveRecord)) { + foreach ($xml->LiveRecord as $record) { + $liveRecord = new LiveChannelHistory(); + $liveRecord->parseFromXmlNode($record); + $this->liveRecordList[] = $liveRecord; + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $liveRecordList = array(); +} diff --git a/vendor/oss-sdk/src/OSS/Model/GetLiveChannelInfo.php b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelInfo.php new file mode 100755 index 0000000..0b5edfc --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelInfo.php @@ -0,0 +1,68 @@ +<?php + +namespace OSS\Model; +/** + * Class GetLiveChannelInfo + * @package OSS\Model + */ +class GetLiveChannelInfo implements XmlConfig +{ + public function getDescription() + { + return $this->description; + } + + public function getStatus() + { + return $this->status; + } + + public function getType() + { + return $this->type; + } + + public function getFragDuration() + { + return $this->fragDuration; + } + + public function getFragCount() + { + return $this->fragCount; + } + + public function getPlayListName() + { + return $this->playlistName; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + $this->description = strval($xml->Description); + $this->status = strval($xml->Status); + + if (isset($xml->Target)) { + foreach ($xml->Target as $target) { + $this->type = strval($target->Type); + $this->fragDuration = strval($target->FragDuration); + $this->fragCount = strval($target->FragCount); + $this->playlistName = strval($target->PlaylistName); + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $description; + private $status; + private $type; + private $fragDuration; + private $fragCount; + private $playlistName; +} diff --git a/vendor/oss-sdk/src/OSS/Model/GetLiveChannelStatus.php b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelStatus.php new file mode 100755 index 0000000..2ee7a68 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/GetLiveChannelStatus.php @@ -0,0 +1,107 @@ +<?php + +namespace OSS\Model; +/** + * Class GetLiveChannelStatus + * @package OSS\Model + */ +class GetLiveChannelStatus implements XmlConfig +{ + public function getStatus() + { + return $this->status; + } + + public function getConnectedTime() + { + return $this->connectedTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function getVideoWidth() + { + return $this->videoWidth; + } + public function getVideoHeight() + { + return $this->videoHeight; + } + public function getVideoFrameRate() + { + return $this->videoFrameRate; + } + public function getVideoBandwidth() + { + return $this->videoBandwidth; + } + public function getVideoCodec() + { + return $this->videoCodec; + } + + public function getAudioBandwidth() + { + return $this->audioBandwidth; + } + public function getAudioSampleRate() + { + return $this->audioSampleRate; + } + public function getAudioCodec() + { + return $this->audioCodec; + } + + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->status = strval($xml->Status); + $this->connectedTime = strval($xml->ConnectedTime); + $this->remoteAddr = strval($xml->RemoteAddr); + + if (isset($xml->Video)) { + foreach ($xml->Video as $video) { + $this->videoWidth = intval($video->Width); + $this->videoHeight = intval($video->Height); + $this->videoFrameRate = intval($video->FrameRate); + $this->videoBandwidth = intval($video->Bandwidth); + $this->videoCodec = strval($video->Codec); + } + } + + if (isset($xml->Video)) { + foreach ($xml->Audio as $audio) { + $this->audioBandwidth = intval($audio->Bandwidth); + $this->audioSampleRate = intval($audio->SampleRate); + $this->audioCodec = strval($audio->Codec); + } + } + + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $status; + private $connectedTime; + private $remoteAddr; + + private $videoWidth; + private $videoHeight; + private $videoFrameRate; + private $videoBandwidth; + private $videoCodec; + + private $audioBandwidth; + private $audioSampleRate; + private $audioCodec; + + +} diff --git a/vendor/oss-sdk/src/OSS/Model/LifecycleAction.php b/vendor/oss-sdk/src/OSS/Model/LifecycleAction.php new file mode 100755 index 0000000..a0e2126 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LifecycleAction.php @@ -0,0 +1,88 @@ +<?php + +namespace OSS\Model; + +/** + * Class LifecycleAction + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketLifecycle.html + */ +class LifecycleAction +{ + /** + * LifecycleAction constructor. + * @param string $action + * @param string $timeSpec + * @param string $timeValue + */ + public function __construct($action, $timeSpec, $timeValue) + { + $this->action = $action; + $this->timeSpec = $timeSpec; + $this->timeValue = $timeValue; + } + + /** + * @return LifecycleAction + */ + public function getAction() + { + return $this->action; + } + + /** + * @param string $action + */ + public function setAction($action) + { + $this->action = $action; + } + + /** + * @return string + */ + public function getTimeSpec() + { + return $this->timeSpec; + } + + /** + * @param string $timeSpec + */ + public function setTimeSpec($timeSpec) + { + $this->timeSpec = $timeSpec; + } + + /** + * @return string + */ + public function getTimeValue() + { + return $this->timeValue; + } + + /** + * @param string $timeValue + */ + public function setTimeValue($timeValue) + { + $this->timeValue = $timeValue; + } + + /** + * Use appendToXml to insert actions into xml. + * + * @param \SimpleXMLElement $xmlRule + */ + public function appendToXml(&$xmlRule) + { + $xmlAction = $xmlRule->addChild($this->action); + $xmlAction->addChild($this->timeSpec, $this->timeValue); + } + + private $action; + private $timeSpec; + private $timeValue; + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/LifecycleConfig.php b/vendor/oss-sdk/src/OSS/Model/LifecycleConfig.php new file mode 100755 index 0000000..f2d2dc3 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LifecycleConfig.php @@ -0,0 +1,107 @@ +<?php + +namespace OSS\Model; + +use OSS\Core\OssException; + + +/** + * Class BucketLifecycleConfig + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketLifecycle.html + */ +class LifecycleConfig implements XmlConfig +{ + /** + * Parse the xml into this object. + * + * @param string $strXml + * @throws OssException + * @return null + */ + public function parseFromXml($strXml) + { + $this->rules = array(); + $xml = simplexml_load_string($strXml); + if (!isset($xml->Rule)) return; + $this->rules = array(); + foreach ($xml->Rule as $rule) { + $id = strval($rule->ID); + $prefix = strval($rule->Prefix); + $status = strval($rule->Status); + $actions = array(); + foreach ($rule as $key => $value) { + if ($key === 'ID' || $key === 'Prefix' || $key === 'Status') continue; + $action = $key; + $timeSpec = null; + $timeValue = null; + foreach ($value as $timeSpecKey => $timeValueValue) { + $timeSpec = $timeSpecKey; + $timeValue = strval($timeValueValue); + } + $actions[] = new LifecycleAction($action, $timeSpec, $timeValue); + } + $this->rules[] = new LifecycleRule($id, $prefix, $status, $actions); + } + return; + } + + + /** + * Serialize the object to xml + * + * @return string + */ + public function serializeToXml() + { + + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><LifecycleConfiguration></LifecycleConfiguration>'); + foreach ($this->rules as $rule) { + $xmlRule = $xml->addChild('Rule'); + $rule->appendToXml($xmlRule); + } + return $xml->asXML(); + } + + /** + * + * Add a LifecycleRule + * + * @param LifecycleRule $lifecycleRule + * @throws OssException + */ + public function addRule($lifecycleRule) + { + if (!isset($lifecycleRule)) { + throw new OssException("lifecycleRule is null"); + } + $this->rules[] = $lifecycleRule; + } + + /** + * Serialize the object into xml string. + * + * @return string + */ + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * Get all lifecycle rules. + * + * @return LifecycleRule[] + */ + public function getRules() + { + return $this->rules; + } + + /** + * @var LifecycleRule[] + */ + private $rules; +} + + diff --git a/vendor/oss-sdk/src/OSS/Model/LifecycleRule.php b/vendor/oss-sdk/src/OSS/Model/LifecycleRule.php new file mode 100755 index 0000000..73c6cc3 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LifecycleRule.php @@ -0,0 +1,126 @@ +<?php + +namespace OSS\Model; + + +/** + * Class LifecycleRule + * @package OSS\Model + * + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketLifecycle.html + */ +class LifecycleRule +{ + /** + * Get Id + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * @param string $id Rule Id + */ + public function setId($id) + { + $this->id = $id; + } + + /** + * Get a file prefix + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * Set a file prefix + * + * @param string $prefix The file prefix + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Get Lifecycle status + * + * @return string + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set Lifecycle status + * + * @param string $status + */ + public function setStatus($status) + { + $this->status = $status; + } + + /** + * + * @return LifecycleAction[] + */ + public function getActions() + { + return $this->actions; + } + + /** + * @param LifecycleAction[] $actions + */ + public function setActions($actions) + { + $this->actions = $actions; + } + + + /** + * LifecycleRule constructor. + * + * @param string $id rule Id + * @param string $prefix File prefix + * @param string $status Rule status, which has the following valid values: [self::LIFECYCLE_STATUS_ENABLED, self::LIFECYCLE_STATUS_DISABLED] + * @param LifecycleAction[] $actions + */ + public function __construct($id, $prefix, $status, $actions) + { + $this->id = $id; + $this->prefix = $prefix; + $this->status = $status; + $this->actions = $actions; + } + + /** + * @param \SimpleXMLElement $xmlRule + */ + public function appendToXml(&$xmlRule) + { + $xmlRule->addChild('ID', $this->id); + $xmlRule->addChild('Prefix', $this->prefix); + $xmlRule->addChild('Status', $this->status); + foreach ($this->actions as $action) { + $action->appendToXml($xmlRule); + } + } + + private $id; + private $prefix; + private $status; + private $actions = array(); + + const LIFECYCLE_STATUS_ENABLED = 'Enabled'; + const LIFECYCLE_STATUS_DISABLED = 'Disabled'; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/ListMultipartUploadInfo.php b/vendor/oss-sdk/src/OSS/Model/ListMultipartUploadInfo.php new file mode 100755 index 0000000..105d005 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/ListMultipartUploadInfo.php @@ -0,0 +1,134 @@ +<?php + +namespace OSS\Model; + +/** + * Class ListMultipartUploadInfo + * @package OSS\Model + * + * @link http://help.aliyun.com/document_detail/oss/api-reference/multipart-upload/ListMultipartUploads.html + */ +class ListMultipartUploadInfo +{ + /** + * ListMultipartUploadInfo constructor. + * + * @param string $bucket + * @param string $keyMarker + * @param string $uploadIdMarker + * @param string $nextKeyMarker + * @param string $nextUploadIdMarker + * @param string $delimiter + * @param string $prefix + * @param int $maxUploads + * @param string $isTruncated + * @param array $uploads + */ + public function __construct($bucket, $keyMarker, $uploadIdMarker, $nextKeyMarker, $nextUploadIdMarker, $delimiter, $prefix, $maxUploads, $isTruncated, array $uploads) + { + $this->bucket = $bucket; + $this->keyMarker = $keyMarker; + $this->uploadIdMarker = $uploadIdMarker; + $this->nextKeyMarker = $nextKeyMarker; + $this->nextUploadIdMarker = $nextUploadIdMarker; + $this->delimiter = $delimiter; + $this->prefix = $prefix; + $this->maxUploads = $maxUploads; + $this->isTruncated = $isTruncated; + $this->uploads = $uploads; + } + + /** + * 得到bucket名称 + * + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * @return string + */ + public function getKeyMarker() + { + return $this->keyMarker; + } + + /** + * + * @return string + */ + public function getUploadIdMarker() + { + return $this->uploadIdMarker; + } + + /** + * @return string + */ + public function getNextKeyMarker() + { + return $this->nextKeyMarker; + } + + /** + * @return string + */ + public function getNextUploadIdMarker() + { + return $this->nextUploadIdMarker; + } + + /** + * @return string + */ + public function getDelimiter() + { + return $this->delimiter; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return int + */ + public function getMaxUploads() + { + return $this->maxUploads; + } + + /** + * @return string + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return UploadInfo[] + */ + public function getUploads() + { + return $this->uploads; + } + + private $bucket = ""; + private $keyMarker = ""; + private $uploadIdMarker = ""; + private $nextKeyMarker = ""; + private $nextUploadIdMarker = ""; + private $delimiter = ""; + private $prefix = ""; + private $maxUploads = 0; + private $isTruncated = "false"; + private $uploads = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/ListPartsInfo.php b/vendor/oss-sdk/src/OSS/Model/ListPartsInfo.php new file mode 100755 index 0000000..f1d10ee --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/ListPartsInfo.php @@ -0,0 +1,97 @@ +<?php + +namespace OSS\Model; + +/** + * Class ListPartsInfo + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/multipart-upload/ListParts.html + */ +class ListPartsInfo +{ + + /** + * ListPartsInfo constructor. + * @param string $bucket + * @param string $key + * @param string $uploadId + * @param int $nextPartNumberMarker + * @param int $maxParts + * @param string $isTruncated + * @param array $listPart + */ + public function __construct($bucket, $key, $uploadId, $nextPartNumberMarker, $maxParts, $isTruncated, array $listPart) + { + $this->bucket = $bucket; + $this->key = $key; + $this->uploadId = $uploadId; + $this->nextPartNumberMarker = $nextPartNumberMarker; + $this->maxParts = $maxParts; + $this->isTruncated = $isTruncated; + $this->listPart = $listPart; + } + + /** + * @return string + */ + public function getBucket() + { + return $this->bucket; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getUploadId() + { + return $this->uploadId; + } + + /** + * @return int + */ + public function getNextPartNumberMarker() + { + return $this->nextPartNumberMarker; + } + + /** + * @return int + */ + public function getMaxParts() + { + return $this->maxParts; + } + + /** + * @return string + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return array + */ + public function getListPart() + { + return $this->listPart; + } + + private $bucket = ""; + private $key = ""; + private $uploadId = ""; + private $nextPartNumberMarker = 0; + private $maxParts = 0; + private $isTruncated = ""; + private $listPart = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/LiveChannelConfig.php b/vendor/oss-sdk/src/OSS/Model/LiveChannelConfig.php new file mode 100755 index 0000000..dadedc9 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LiveChannelConfig.php @@ -0,0 +1,121 @@ +<?php + +namespace OSS\Model; + + +/** + * Class LiveChannelConfig + * @package OSS\Model + */ +class LiveChannelConfig implements XmlConfig +{ + public function __construct($option = array()) + { + if (isset($option['description'])) { + $this->description = $option['description']; + } + if (isset($option['status'])) { + $this->status = $option['status']; + } + if (isset($option['type'])) { + $this->type = $option['type']; + } + if (isset($option['fragDuration'])) { + $this->fragDuration = $option['fragDuration']; + } + if (isset($option['fragCount'])) { + $this->fragCount = $option['fragCount']; + } + if (isset($option['playListName'])) { + $this->playListName = $option['playListName']; + } + } + + public function getDescription() + { + return $this->description; + } + + public function getStatus() + { + return $this->status; + } + + public function getType() + { + return $this->type; + } + + public function getFragDuration() + { + return $this->fragDuration; + } + + public function getFragCount() + { + return $this->fragCount; + } + + public function getPlayListName() + { + return $this->playListName; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->description = strval($xml->Description); + $this->status = strval($xml->Status); + $target = $xml->Target; + $this->type = strval($target->Type); + $this->fragDuration = intval($target->FragDuration); + $this->fragCount = intval($target->FragCount); + $this->playListName = strval($target->PlayListName); + } + + public function serializeToXml() + { + $strXml = <<<EOF +<?xml version="1.0" encoding="utf-8"?> +<LiveChannelConfiguration> +</LiveChannelConfiguration> +EOF; + $xml = new \SimpleXMLElement($strXml); + if (isset($this->description)) { + $xml->addChild('Description', $this->description); + } + + if (isset($this->status)) { + $xml->addChild('Status', $this->status); + } + + $node = $xml->addChild('Target'); + $node->addChild('Type', $this->type); + + if (isset($this->fragDuration)) { + $node->addChild('FragDuration', $this->fragDuration); + } + + if (isset($this->fragCount)) { + $node->addChild('FragCount', $this->fragCount); + } + + if (isset($this->playListName)) { + $node->addChild('PlayListName', $this->playListName); + } + + return $xml->asXML(); + } + + public function __toString() + { + return $this->serializeToXml(); + } + + private $description; + private $status = "enabled"; + private $type; + private $fragDuration = 5; + private $fragCount = 3; + private $playListName = "playlist.m3u8"; +} diff --git a/vendor/oss-sdk/src/OSS/Model/LiveChannelHistory.php b/vendor/oss-sdk/src/OSS/Model/LiveChannelHistory.php new file mode 100755 index 0000000..1c1fd4d --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LiveChannelHistory.php @@ -0,0 +1,59 @@ +<?php + +namespace OSS\Model; +/** + * Class LiveChannelHistory + * @package OSS\Model + * + */ +class LiveChannelHistory implements XmlConfig +{ + public function __construct() + { + } + + public function getStartTime() + { + return $this->startTime; + } + + public function getEndTime() + { + return $this->endTime; + } + + public function getRemoteAddr() + { + return $this->remoteAddr; + } + + public function parseFromXmlNode($xml) + { + if (isset($xml->StartTime)) { + $this->startTime = strval($xml->StartTime); + } + + if (isset($xml->EndTime)) { + $this->endTime = strval($xml->EndTime); + } + + if (isset($xml->RemoteAddr)) { + $this->remoteAddr = strval($xml->RemoteAddr); + } + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->parseFromXmlNode($xml); + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $startTime; + private $endTime; + private $remoteAddr; +} diff --git a/vendor/oss-sdk/src/OSS/Model/LiveChannelInfo.php b/vendor/oss-sdk/src/OSS/Model/LiveChannelInfo.php new file mode 100755 index 0000000..c63ec54 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LiveChannelInfo.php @@ -0,0 +1,107 @@ +<?php + +namespace OSS\Model; +/** + * Class LiveChannelInfo + * @package OSS\Model + * + */ +class LiveChannelInfo implements XmlConfig +{ + public function __construct($name = null, $description = null) + { + $this->name = $name; + $this->description = $description; + $this->publishUrls = array(); + $this->playUrls = array(); + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = $name; + } + + public function getPublishUrls() + { + return $this->publishUrls; + } + + public function getPlayUrls() + { + return $this->playUrls; + } + + public function getStatus() + { + return $this->status; + } + + public function getLastModified() + { + return $this->lastModified; + } + + public function getDescription() + { + return $this->description; + } + + public function setDescription($description) + { + $this->description = $description; + } + + public function parseFromXmlNode($xml) + { + if (isset($xml->Name)) { + $this->name = strval($xml->Name); + } + + if (isset($xml->Description)) { + $this->description = strval($xml->Description); + } + + if (isset($xml->Status)) { + $this->status = strval($xml->Status); + } + + if (isset($xml->LastModified)) { + $this->lastModified = strval($xml->LastModified); + } + + if (isset($xml->PublishUrls)) { + foreach ($xml->PublishUrls as $url) { + $this->publishUrls[] = strval($url->Url); + } + } + + if (isset($xml->PlayUrls)) { + foreach ($xml->PlayUrls as $url) { + $this->playUrls[] = strval($url->Url); + } + } + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + $this->parseFromXmlNode($xml); + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $name; + private $description; + private $publishUrls; + private $playUrls; + private $status; + private $lastModified; +} diff --git a/vendor/oss-sdk/src/OSS/Model/LiveChannelListInfo.php b/vendor/oss-sdk/src/OSS/Model/LiveChannelListInfo.php new file mode 100755 index 0000000..f4ee02f --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LiveChannelListInfo.php @@ -0,0 +1,107 @@ +<?php + +namespace OSS\Model; + +/** + * Class LiveChannelListInfo + * + * The data returned by ListBucketLiveChannels + * + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/GetBucket.html + */ +class LiveChannelListInfo implements XmlConfig +{ + /** + * @return string + */ + public function getBucketName() + { + return $this->bucket; + } + + public function setBucketName($name) + { + $this->bucket = $name; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return string + */ + public function getMarker() + { + return $this->marker; + } + + /** + * @return int + */ + public function getMaxKeys() + { + return $this->maxKeys; + } + + /** + * @return mixed + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * @return LiveChannelInfo[] + */ + public function getChannelList() + { + return $this->channelList; + } + + /** + * @return string + */ + public function getNextMarker() + { + return $this->nextMarker; + } + + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + + $this->prefix = strval($xml->Prefix); + $this->marker = strval($xml->Marker); + $this->maxKeys = intval($xml->MaxKeys); + $this->isTruncated = (strval($xml->IsTruncated) == 'true'); + $this->nextMarker = strval($xml->NextMarker); + + if (isset($xml->LiveChannel)) { + foreach ($xml->LiveChannel as $chan) { + $channel = new LiveChannelInfo(); + $channel->parseFromXmlNode($chan); + $this->channelList[] = $channel; + } + } + } + + public function serializeToXml() + { + throw new OssException("Not implemented."); + } + + private $bucket = ''; + private $prefix = ''; + private $marker = ''; + private $nextMarker = ''; + private $maxKeys = 100; + private $isTruncated = 'false'; + private $channelList = array(); +} diff --git a/vendor/oss-sdk/src/OSS/Model/LoggingConfig.php b/vendor/oss-sdk/src/OSS/Model/LoggingConfig.php new file mode 100755 index 0000000..ed9fb1d --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/LoggingConfig.php @@ -0,0 +1,86 @@ +<?php + +namespace OSS\Model; + + +/** + * Class LoggingConfig + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketLogging.html + */ +class LoggingConfig implements XmlConfig +{ + /** + * LoggingConfig constructor. + * @param null $targetBucket + * @param null $targetPrefix + */ + public function __construct($targetBucket = null, $targetPrefix = null) + { + $this->targetBucket = $targetBucket; + $this->targetPrefix = $targetPrefix; + } + + /** + * @param $strXml + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->LoggingEnabled)) return; + foreach ($xml->LoggingEnabled as $status) { + foreach ($status as $key => $value) { + if ($key === 'TargetBucket') { + $this->targetBucket = strval($value); + } elseif ($key === 'TargetPrefix') { + $this->targetPrefix = strval($value); + } + } + break; + } + } + + /** + * Serialize to xml string + * + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><BucketLoggingStatus></BucketLoggingStatus>'); + if (isset($this->targetBucket) && isset($this->targetPrefix)) { + $loggingEnabled = $xml->addChild('LoggingEnabled'); + $loggingEnabled->addChild('TargetBucket', $this->targetBucket); + $loggingEnabled->addChild('TargetPrefix', $this->targetPrefix); + } + return $xml->asXML(); + } + + /** + * @return string + */ + public function __toString() + { + return $this->serializeToXml(); + } + + /** + * @return string + */ + public function getTargetBucket() + { + return $this->targetBucket; + } + + /** + * @return string + */ + public function getTargetPrefix() + { + return $this->targetPrefix; + } + + private $targetBucket = ""; + private $targetPrefix = ""; + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/ObjectInfo.php b/vendor/oss-sdk/src/OSS/Model/ObjectInfo.php new file mode 100755 index 0000000..891f862 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/ObjectInfo.php @@ -0,0 +1,93 @@ +<?php + +namespace OSS\Model; + +/** + * + * Class ObjectInfo + * + * The element type of ObjectListInfo, which is the return value type of listObjects + * + * The return value of listObjects includes two arrays + * One is the returned ObjectListInfo, which is similar to a file list in a file system. + * The other is the returned prefix list, which is similar to a folder list in a file system. + * + * @package OSS\Model + */ +class ObjectInfo +{ + /** + * ObjectInfo constructor. + * + * @param string $key + * @param string $lastModified + * @param string $eTag + * @param string $type + * @param int $size + * @param string $storageClass + */ + public function __construct($key, $lastModified, $eTag, $type, $size, $storageClass) + { + $this->key = $key; + $this->lastModified = $lastModified; + $this->eTag = $eTag; + $this->type = $type; + $this->size = $size; + $this->storageClass = $storageClass; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } + + /** + * @return string + */ + public function getStorageClass() + { + return $this->storageClass; + } + + private $key = ""; + private $lastModified = ""; + private $eTag = ""; + private $type = ""; + private $size = 0; + private $storageClass = ""; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/ObjectListInfo.php b/vendor/oss-sdk/src/OSS/Model/ObjectListInfo.php new file mode 100755 index 0000000..81c5d27 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/ObjectListInfo.php @@ -0,0 +1,126 @@ +<?php + +namespace OSS\Model; + +/** + * Class ObjectListInfo + * + * The class of return value of ListObjects + * + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/GetBucket.html + */ +class ObjectListInfo +{ + /** + * ObjectListInfo constructor. + * + * @param string $bucketName + * @param string $prefix + * @param string $marker + * @param string $nextMarker + * @param string $maxKeys + * @param string $delimiter + * @param null $isTruncated + * @param array $objectList + * @param array $prefixList + */ + public function __construct($bucketName, $prefix, $marker, $nextMarker, $maxKeys, $delimiter, $isTruncated, array $objectList, array $prefixList) + { + $this->bucketName = $bucketName; + $this->prefix = $prefix; + $this->marker = $marker; + $this->nextMarker = $nextMarker; + $this->maxKeys = $maxKeys; + $this->delimiter = $delimiter; + $this->isTruncated = $isTruncated; + $this->objectList = $objectList; + $this->prefixList = $prefixList; + } + + /** + * @return string + */ + public function getBucketName() + { + return $this->bucketName; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + /** + * @return string + */ + public function getMarker() + { + return $this->marker; + } + + /** + * @return int + */ + public function getMaxKeys() + { + return $this->maxKeys; + } + + /** + * @return string + */ + public function getDelimiter() + { + return $this->delimiter; + } + + /** + * @return mixed + */ + public function getIsTruncated() + { + return $this->isTruncated; + } + + /** + * Get the ObjectInfo list. + * + * @return ObjectInfo[] + */ + public function getObjectList() + { + return $this->objectList; + } + + /** + * Get the PrefixInfo list + * + * @return PrefixInfo[] + */ + public function getPrefixList() + { + return $this->prefixList; + } + + /** + * @return string + */ + public function getNextMarker() + { + return $this->nextMarker; + } + + private $bucketName = ""; + private $prefix = ""; + private $marker = ""; + private $nextMarker = ""; + private $maxKeys = 0; + private $delimiter = ""; + private $isTruncated = null; + private $objectList = array(); + private $prefixList = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/PartInfo.php b/vendor/oss-sdk/src/OSS/Model/PartInfo.php new file mode 100755 index 0000000..439a84d --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/PartInfo.php @@ -0,0 +1,63 @@ +<?php + +namespace OSS\Model; + +/** + * Class PartInfo + * @package OSS\Model + */ +class PartInfo +{ + /** + * PartInfo constructor. + * + * @param int $partNumber + * @param string $lastModified + * @param string $eTag + * @param int $size + */ + public function __construct($partNumber, $lastModified, $eTag, $size) + { + $this->partNumber = $partNumber; + $this->lastModified = $lastModified; + $this->eTag = $eTag; + $this->size = $size; + } + + /** + * @return int + */ + public function getPartNumber() + { + return $this->partNumber; + } + + /** + * @return string + */ + public function getLastModified() + { + return $this->lastModified; + } + + /** + * @return string + */ + public function getETag() + { + return $this->eTag; + } + + /** + * @return int + */ + public function getSize() + { + return $this->size; + } + + private $partNumber = 0; + private $lastModified = ""; + private $eTag = ""; + private $size = 0; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/PrefixInfo.php b/vendor/oss-sdk/src/OSS/Model/PrefixInfo.php new file mode 100755 index 0000000..27920b9 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/PrefixInfo.php @@ -0,0 +1,36 @@ +<?php + +namespace OSS\Model; + +/** + * Class PrefixInfo + * + * ListObjects return Prefix list of classes + * The returned data contains two arrays + * One is to get the list of objects【Can be understood as the corresponding file system file list】 + * One is to get Prefix list【Can be understood as the corresponding file system directory list】 + * + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/GetBucket.html + */ +class PrefixInfo +{ + /** + * PrefixInfo constructor. + * @param string $prefix + */ + public function __construct($prefix) + { + $this->prefix = $prefix; + } + + /** + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + + private $prefix; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/RefererConfig.php b/vendor/oss-sdk/src/OSS/Model/RefererConfig.php new file mode 100755 index 0000000..0830143 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/RefererConfig.php @@ -0,0 +1,93 @@ +<?php + +namespace OSS\Model; + +/** + * Class RefererConfig + * + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketReferer.html + */ +class RefererConfig implements XmlConfig +{ + /** + * @param string $strXml + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (!isset($xml->AllowEmptyReferer)) return; + if (!isset($xml->RefererList)) return; + $this->allowEmptyReferer = + (strval($xml->AllowEmptyReferer) === 'TRUE' || strval($xml->AllowEmptyReferer) === 'true') ? true : false; + + foreach ($xml->RefererList->Referer as $key => $refer) { + $this->refererList[] = strval($refer); + } + } + + + /** + * serialize the RefererConfig object into xml string + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><RefererConfiguration></RefererConfiguration>'); + if ($this->allowEmptyReferer) { + $xml->addChild('AllowEmptyReferer', 'true'); + } else { + $xml->addChild('AllowEmptyReferer', 'false'); + } + $refererList = $xml->addChild('RefererList'); + foreach ($this->refererList as $referer) { + $refererList->addChild('Referer', $referer); + } + return $xml->asXML(); + } + + /** + * @return string + */ + function __toString() + { + return $this->serializeToXml(); + } + + /** + * @param boolean $allowEmptyReferer + */ + public function setAllowEmptyReferer($allowEmptyReferer) + { + $this->allowEmptyReferer = $allowEmptyReferer; + } + + /** + * @param string $referer + */ + public function addReferer($referer) + { + $this->refererList[] = $referer; + } + + /** + * @return boolean + */ + public function isAllowEmptyReferer() + { + return $this->allowEmptyReferer; + } + + /** + * @return array + */ + public function getRefererList() + { + return $this->refererList; + } + + private $allowEmptyReferer = true; + private $refererList = array(); +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/StorageCapacityConfig.php b/vendor/oss-sdk/src/OSS/Model/StorageCapacityConfig.php new file mode 100755 index 0000000..024b5c9 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/StorageCapacityConfig.php @@ -0,0 +1,74 @@ +<?php + +namespace OSS\Model; + +/** + * Class StorageCapacityConfig + * + * @package OSS\Model + * @link http://docs.alibaba-inc.com/pages/viewpage.action?pageId=271614763 + */ +class StorageCapacityConfig implements XmlConfig +{ + /** + * StorageCapacityConfig constructor. + * + * @param int $storageCapacity + */ + public function __construct($storageCapacity) + { + $this->storageCapacity = $storageCapacity; + } + + /** + * Not implemented + */ + public function parseFromXml($strXml) + { + throw new OssException("Not implemented."); + } + + /** + * Serialize StorageCapacityConfig into xml + * + * @return string + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><BucketUserQos></BucketUserQos>'); + $xml->addChild('StorageCapacity', strval($this->storageCapacity)); + return $xml->asXML(); + } + + /** + * To string + * + * @return string + */ + function __toString() + { + return $this->serializeToXml(); + } + + /** + * Set storage capacity + * + * @param int $storageCapacity + */ + public function setStorageCapacity($storageCapacity) + { + $this->storageCapacity = $storageCapacity; + } + + /** + * Get storage capacity + * + * @return int + */ + public function getStorageCapacity() + { + return $this->storageCapacity; + } + + private $storageCapacity = 0; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/UploadInfo.php b/vendor/oss-sdk/src/OSS/Model/UploadInfo.php new file mode 100755 index 0000000..49aa414 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/UploadInfo.php @@ -0,0 +1,55 @@ +<?php + +namespace OSS\Model; + +/** + * Class UploadInfo + * + * The return value of ListMultipartUpload + * + * @package OSS\Model + */ +class UploadInfo +{ + /** + * UploadInfo constructor. + * + * @param string $key + * @param string $uploadId + * @param string $initiated + */ + public function __construct($key, $uploadId, $initiated) + { + $this->key = $key; + $this->uploadId = $uploadId; + $this->initiated = $initiated; + } + + /** + * @return string + */ + public function getKey() + { + return $this->key; + } + + /** + * @return string + */ + public function getUploadId() + { + return $this->uploadId; + } + + /** + * @return string + */ + public function getInitiated() + { + return $this->initiated; + } + + private $key = ""; + private $uploadId = ""; + private $initiated = ""; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/WebsiteConfig.php b/vendor/oss-sdk/src/OSS/Model/WebsiteConfig.php new file mode 100755 index 0000000..e298eb4 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/WebsiteConfig.php @@ -0,0 +1,76 @@ +<?php + +namespace OSS\Model; + + +use OSS\Core\OssException; + + +/** + * Class WebsiteConfig + * @package OSS\Model + * @link http://help.aliyun.com/document_detail/oss/api-reference/bucket/PutBucketWebsite.html + */ +class WebsiteConfig implements XmlConfig +{ + /** + * WebsiteConfig constructor. + * @param string $indexDocument + * @param string $errorDocument + */ + public function __construct($indexDocument = "", $errorDocument = "") + { + $this->indexDocument = $indexDocument; + $this->errorDocument = $errorDocument; + } + + /** + * @param string $strXml + * @return null + */ + public function parseFromXml($strXml) + { + $xml = simplexml_load_string($strXml); + if (isset($xml->IndexDocument) && isset($xml->IndexDocument->Suffix)) { + $this->indexDocument = strval($xml->IndexDocument->Suffix); + } + if (isset($xml->ErrorDocument) && isset($xml->ErrorDocument->Key)) { + $this->errorDocument = strval($xml->ErrorDocument->Key); + } + } + + /** + * Serialize the WebsiteConfig object into xml string. + * + * @return string + * @throws OssException + */ + public function serializeToXml() + { + $xml = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><WebsiteConfiguration></WebsiteConfiguration>'); + $index_document_part = $xml->addChild('IndexDocument'); + $error_document_part = $xml->addChild('ErrorDocument'); + $index_document_part->addChild('Suffix', $this->indexDocument); + $error_document_part->addChild('Key', $this->errorDocument); + return $xml->asXML(); + } + + /** + * @return string + */ + public function getIndexDocument() + { + return $this->indexDocument; + } + + /** + * @return string + */ + public function getErrorDocument() + { + return $this->errorDocument; + } + + private $indexDocument = ""; + private $errorDocument = ""; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Model/XmlConfig.php b/vendor/oss-sdk/src/OSS/Model/XmlConfig.php new file mode 100755 index 0000000..8c0a0db --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Model/XmlConfig.php @@ -0,0 +1,27 @@ +<?php + +namespace OSS\Model; + +/** + * Interface XmlConfig + * @package OSS\Model + */ +interface XmlConfig +{ + + /** + * Interface method: Parse the object from the xml. + * + * @param string $strXml + * @return null + */ + public function parseFromXml($strXml); + + /** + * Interface method: Serialize the object into xml. + * + * @return string + */ + public function serializeToXml(); + +} diff --git a/vendor/oss-sdk/src/OSS/OssClient.php b/vendor/oss-sdk/src/OSS/OssClient.php new file mode 100755 index 0000000..0dbe1d3 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/OssClient.php @@ -0,0 +1,2738 @@ +<?php +namespace OSS; + +use OSS\Core\MimeTypes; +use OSS\Core\OssException; +use OSS\Http\RequestCore; +use OSS\Http\RequestCore_Exception; +use OSS\Http\ResponseCore; +use OSS\Model\CorsConfig; +use OSS\Model\CnameConfig; +use OSS\Model\LoggingConfig; +use OSS\Model\LiveChannelConfig; +use OSS\Model\LiveChannelInfo; +use OSS\Model\LiveChannelListInfo; +use OSS\Model\StorageCapacityConfig; +use OSS\Result\AclResult; +use OSS\Result\BodyResult; +use OSS\Result\GetCorsResult; +use OSS\Result\GetLifecycleResult; +use OSS\Result\GetLocationResult; +use OSS\Result\GetLoggingResult; +use OSS\Result\GetRefererResult; +use OSS\Result\GetStorageCapacityResult; +use OSS\Result\GetWebsiteResult; +use OSS\Result\GetCnameResult; +use OSS\Result\HeaderResult; +use OSS\Result\InitiateMultipartUploadResult; +use OSS\Result\ListBucketsResult; +use OSS\Result\ListMultipartUploadResult; +use OSS\Model\ListMultipartUploadInfo; +use OSS\Result\ListObjectsResult; +use OSS\Result\ListPartsResult; +use OSS\Result\PutSetDeleteResult; +use OSS\Result\DeleteObjectsResult; +use OSS\Result\CopyObjectResult; +use OSS\Result\CallbackResult; +use OSS\Result\ExistResult; +use OSS\Result\PutLiveChannelResult; +use OSS\Result\GetLiveChannelHistoryResult; +use OSS\Result\GetLiveChannelInfoResult; +use OSS\Result\GetLiveChannelStatusResult; +use OSS\Result\ListLiveChannelResult; +use OSS\Result\AppendResult; +use OSS\Model\ObjectListInfo; +use OSS\Result\SymlinkResult; +use OSS\Result\UploadPartResult; +use OSS\Model\BucketListInfo; +use OSS\Model\LifecycleConfig; +use OSS\Model\RefererConfig; +use OSS\Model\WebsiteConfig; +use OSS\Core\OssUtil; +use OSS\Model\ListPartsInfo; + +/** + * Class OssClient + * + * Object Storage Service(OSS)'s client class, which wraps all OSS APIs user could call to talk to OSS. + * Users could do operations on bucket, object, including MultipartUpload or setting ACL via an OSSClient instance. + * For more details, please check out the OSS API document:https://www.alibabacloud.com/help/doc-detail/31947.htm + */ +class OssClient +{ + /** + * Constructor + * + * There're a few different ways to create an OssClient object: + * 1. Most common one from access Id, access Key and the endpoint: $ossClient = new OssClient($id, $key, $endpoint) + * 2. If the endpoint is the CName (such as www.testoss.com, make sure it's CName binded in the OSS console), + * uses $ossClient = new OssClient($id, $key, $endpoint, true) + * 3. If using Alicloud's security token service (STS), then the AccessKeyId, AccessKeySecret and STS token are all got from STS. + * Use this: $ossClient = new OssClient($id, $key, $endpoint, false, $token) + * 4. If the endpoint is in IP format, you could use this: $ossClient = new OssClient($id, $key, “1.2.3.4:8900”) + * + * @param string $accessKeyId The AccessKeyId from OSS or STS + * @param string $accessKeySecret The AccessKeySecret from OSS or STS + * @param string $endpoint The domain name of the datacenter,For example: oss-cn-hangzhou.aliyuncs.com + * @param boolean $isCName If this is the CName and binded in the bucket. + * @param string $securityToken from STS. + * @param string $requestProxy + * @throws OssException + */ + public function __construct($accessKeyId, $accessKeySecret, $endpoint, $isCName = false, $securityToken = NULL, $requestProxy = NULL) + { + $accessKeyId = trim($accessKeyId); + $accessKeySecret = trim($accessKeySecret); + $endpoint = trim(trim($endpoint), "/"); + + if (empty($accessKeyId)) { + throw new OssException("access key id is empty"); + } + if (empty($accessKeySecret)) { + throw new OssException("access key secret is empty"); + } + if (empty($endpoint)) { + throw new OssException("endpoint is empty"); + } + $this->hostname = $this->checkEndpoint($endpoint, $isCName); + $this->accessKeyId = $accessKeyId; + $this->accessKeySecret = $accessKeySecret; + $this->securityToken = $securityToken; + $this->requestProxy = $requestProxy; + self::checkEnv(); + } + + /** + * Lists the Bucket [GetService]. Not applicable if the endpoint is CName (because CName must be binded to a specific bucket). + * + * @param array $options + * @throws OssException + * @return BucketListInfo + */ + public function listBuckets($options = NULL) + { + if ($this->hostType === self::OSS_HOST_TYPE_CNAME) { + throw new OssException("operation is not permitted with CName host"); + } + $this->precheckOptions($options); + $options[self::OSS_BUCKET] = ''; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new ListBucketsResult($response); + return $result->getData(); + } + + /** + * Creates bucket,The ACL of the bucket created by default is OssClient::OSS_ACL_TYPE_PRIVATE + * + * @param string $bucket + * @param string $acl + * @param array $options + * @param string $storageType + * @return null + */ + public function createBucket($bucket, $acl = self::OSS_ACL_TYPE_PRIVATE, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl); + if (isset($options[self::OSS_STORAGE])) { + $this->precheckStorage($options[self::OSS_STORAGE]); + $options[self::OSS_CONTENT] = OssUtil::createBucketXmlBody($options[self::OSS_STORAGE]); + unset($options[self::OSS_STORAGE]); + } + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Deletes bucket + * The deletion will not succeed if the bucket is not empty (either has objects or parts) + * To delete a bucket, all its objects and parts must be deleted first. + * + * @param string $bucket + * @param array $options + * @return null + */ + public function deleteBucket($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Checks if a bucket exists + * + * @param string $bucket + * @return bool + * @throws OssException + */ + public function doesBucketExist($bucket) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new ExistResult($response); + return $result->getData(); + } + + /** + * Get the data center location information for the bucket + * + * @param string $bucket + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketLocation($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'location'; + $response = $this->auth($options); + $result = new GetLocationResult($response); + return $result->getData(); + } + + /** + * Get the Meta information for the Bucket + * + * @param string $bucket + * @param array $options Refer to the SDK documentation + * @return array + */ + public function getBucketMeta($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = '/'; + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * Gets the bucket ACL + * + * @param string $bucket + * @param array $options + * @throws OssException + * @return string + */ + public function getBucketAcl($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new AclResult($response); + return $result->getData(); + } + + /** + * Sets the bucket ACL + * + * @param string $bucket bucket name + * @param string $acl access permissions, valid values are ['private', 'public-read', 'public-read-write'] + * @param array $options by default is empty + * @throws OssException + * @return null + */ + public function putBucketAcl($bucket, $acl, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array(self::OSS_ACL => $acl); + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets object ACL + * + * @param string $bucket + * @param string $object + * @throws OssException + * @return string + */ + public function getObjectAcl($bucket, $object) + { + $options = array(); + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new AclResult($response); + return $result->getData(); + } + + /** + * Sets the object ACL + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $acl access permissions, valid values are ['default', 'private', 'public-read', 'public-read-write'] + * @throws OssException + * @return null + */ + public function putObjectAcl($bucket, $object, $acl) + { + $this->precheckCommon($bucket, $object, $options, true); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_ACL => $acl); + $options[self::OSS_SUB_RESOURCE] = 'acl'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the bucket logging config + * + * @param string $bucket bucket name + * @param array $options by default is empty + * @throws OssException + * @return LoggingConfig + */ + public function getBucketLogging($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $response = $this->auth($options); + $result = new GetLoggingResult($response); + return $result->getData(); + } + + /** + * Sets the bycket logging config. Only owner can call this API. + * + * @param string $bucket bucket name + * @param string $targetBucket The logging file's bucket + * @param string $targetPrefix The logging file's prefix + * @param array $options By default is empty. + * @throws OssException + * @return null + */ + public function putBucketLogging($bucket, $targetBucket, $targetPrefix, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $this->precheckBucket($targetBucket, 'targetbucket is not allowed empty'); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + + $loggingConfig = new LoggingConfig($targetBucket, $targetPrefix); + $options[self::OSS_CONTENT] = $loggingConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket logging config + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLogging($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'logging'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets the website config in bucket---that is could make the bucket as a static website once the CName is binded. + * + * @param string $bucket bucket name + * @param WebsiteConfig $websiteConfig + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketWebsite($bucket, $websiteConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $websiteConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the website config in the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return WebsiteConfig + */ + public function getBucketWebsite($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $response = $this->auth($options); + $result = new GetWebsiteResult($response); + return $result->getData(); + } + + /** + * Deletes the website config in the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketWebsite($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'website'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets the cross-origin-resource-sharing (CORS) rule. It would overwrite the originl one. + * + * @param string $bucket bucket name + * @param CorsConfig $corsConfig CORS config. Check out the details from OSS API document + * @param array $options array + * @throws OssException + * @return null + */ + public function putBucketCors($bucket, $corsConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $corsConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the bucket CORS config + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return CorsConfig + */ + public function getBucketCors($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $response = $this->auth($options); + $result = new GetCorsResult($response, __FUNCTION__); + return $result->getData(); + } + + /** + * Deletes the bucket's CORS config and disable the CORS on the bucket. + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketCors($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cors'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Bind a CName for the bucket + * + * @param string $bucket bucket name + * @param string $cname + * @param array $options + * @throws OssException + * @return null + */ + public function addBucketCname($bucket, $cname, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $cnameConfig = new CnameConfig(); + $cnameConfig->addCname($cname); + $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); + $options[self::OSS_COMP] = 'add'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the binded CName list of the bucket + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return CnameConfig + */ + public function getBucketCname($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $response = $this->auth($options); + $result = new GetCnameResult($response); + return $result->getData(); + } + + /** + * Remove a CName binding from the bucket + * + * @param string $bucket bucket name + * @param CnameConfig $cnameConfig + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketCname($bucket, $cname, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'cname'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $cnameConfig = new CnameConfig(); + $cnameConfig->addCname($cname); + $options[self::OSS_CONTENT] = $cnameConfig->serializeToXml(); + $options[self::OSS_COMP] = 'delete'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Creates a Live Channel under a bucket + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param LiveChannelConfig $channelConfig + * @param array $options + * @throws OssException + * @return LiveChannelInfo + */ + public function putBucketLiveChannel($bucket, $channelName, $channelConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $channelConfig->serializeToXml(); + + $response = $this->auth($options); + $result = new PutLiveChannelResult($response); + $info = $result->getData(); + $info->setName($channelName); + $info->setDescription($channelConfig->getDescription()); + + return $info; + } + + /** + * Sets the LiveChannel status + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param string channelStatus $channelStatus enabled or disabled + * @param array $options + * @throws OssException + * @return null + */ + public function putLiveChannelStatus($bucket, $channelName, $channelStatus, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_LIVE_CHANNEL_STATUS] = $channelStatus; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the LiveChannel information by the channel name + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelInfo + */ + public function getLiveChannelInfo($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new GetLiveChannelInfoResult($response); + return $result->getData(); + } + + /** + * Gets the status of LiveChannel + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelStatus + */ + public function getLiveChannelStatus($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'stat'; + + $response = $this->auth($options); + $result = new GetLiveChannelStatusResult($response); + return $result->getData(); + } + + /** + * Gets the LiveChannel pushing streaming record + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return GetLiveChannelHistory + */ + public function getLiveChannelHistory($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_COMP] = 'history'; + + $response = $this->auth($options); + $result = new GetLiveChannelHistoryResult($response); + return $result->getData(); + } + + /** + *Gets the live channel list under a bucket. + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return LiveChannelListInfo + */ + public function listBucketLiveChannels($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'live'; + $options[self::OSS_QUERY_STRING] = array( + 'prefix' => isset($options['prefix']) ? $options['prefix'] : '', + 'marker' => isset($options['marker']) ? $options['marker'] : '', + 'max-keys' => isset($options['max-keys']) ? $options['max-keys'] : '', + ); + $response = $this->auth($options); + $result = new ListLiveChannelResult($response); + $list = $result->getData(); + $list->setBucketName($bucket); + + return $list; + } + + /** + * Creates a play list file for the LiveChannel + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param string $playlistName The playlist name, must end with ".m3u8". + * @param array $setTime startTime and EndTime in unix time. No more than 1 day. + * @throws OssException + * @return null + */ + public function postVodPlaylist($bucket, $channelName, $playlistName, $setTime) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $channelName . '/' . $playlistName; + $options[self::OSS_SUB_RESOURCE] = 'vod'; + $options[self::OSS_LIVE_CHANNEL_END_TIME] = $setTime['EndTime']; + $options[self::OSS_LIVE_CHANNEL_START_TIME] = $setTime['StartTime']; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Deletes the Bucket LiveChannel + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLiveChannel($bucket, $channelName, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = $channelName; + $options[self::OSS_SUB_RESOURCE] = 'live'; + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Generates the signed pushing streaming url + * + * @param string $bucket bucket name + * @param string channelName $channelName + * @param int timeout timeout value in seconds + * @param array $options + * @throws OssException + * @return The signed pushing streaming url + */ + public function signRtmpUrl($bucket, $channelName, $timeout = 60, $options = NULL) + { + $this->precheckCommon($bucket, $channelName, $options, false); + $expires = time() + $timeout; + $proto = 'rtmp://'; + $hostname = $this->generateHostname($bucket); + $cano_params = ''; + $query_items = array(); + $params = isset($options['params']) ? $options['params'] : array(); + uksort($params, 'strnatcasecmp'); + foreach ($params as $key => $value) { + $cano_params = $cano_params . $key . ':' . $value . "\n"; + $query_items[] = rawurlencode($key) . '=' . rawurlencode($value); + } + $resource = '/' . $bucket . '/' . $channelName; + + $string_to_sign = $expires . "\n" . $cano_params . $resource; + $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $this->accessKeySecret, true)); + + $query_items[] = 'OSSAccessKeyId=' . rawurlencode($this->accessKeyId); + $query_items[] = 'Expires=' . rawurlencode($expires); + $query_items[] = 'Signature=' . rawurlencode($signature); + + return $proto . $hostname . '/live/' . $channelName . '?' . implode('&', $query_items); + } + + /** + * Precheck the CORS request. Before sending a CORS request, a preflight request (OPTIONS) is sent with the specific origin. + * HTTP METHOD and headers information are sent to OSS as well for evaluating if the CORS request is allowed. + * + * Note: OSS could enable the CORS on the bucket by calling putBucketCors. Once CORS is enabled, the OSS could evaluate accordingto the preflight request. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $origin the origin of the request + * @param string $request_method The actual HTTP method which will be used in CORS request + * @param string $request_headers The actual HTTP headers which will be used in CORS request + * @param array $options + * @return array + * @throws OssException + * @link http://help.aliyun.com/document_detail/oss/api-reference/cors/OptionObject.html + */ + public function optionsObject($bucket, $object, $origin, $request_method, $request_headers, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_OPTIONS; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_HEADERS] = array( + self::OSS_OPTIONS_ORIGIN => $origin, + self::OSS_OPTIONS_REQUEST_HEADERS => $request_headers, + self::OSS_OPTIONS_REQUEST_METHOD => $request_method + ); + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * Sets the bucket's lifecycle config + * + * @param string $bucket bucket name + * @param LifecycleConfig $lifecycleConfig LifecycleConfig instance + * @param array $options + * @throws OssException + * @return null + */ + public function putBucketLifecycle($bucket, $lifecycleConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $lifecycleConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets bucket's lifecycle config + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return LifecycleConfig + */ + public function getBucketLifecycle($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new GetLifecycleResult($response); + return $result->getData(); + } + + /** + * Deletes the bucket's lifecycle config + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return null + */ + public function deleteBucketLifecycle($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'lifecycle'; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Sets a bucket's referer, which has a whitelist of referrer and specifies if empty referer is allowed. + * Checks out API document for more details about "Bucket Referer" + * + * @param string $bucket bucket name + * @param RefererConfig $refererConfig + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketReferer($bucket, $refererConfig, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $options[self::OSS_CONTENT] = $refererConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the bucket's Referer + * Checks out API document for more details about "Bucket Referer" + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return RefererConfig + */ + public function getBucketReferer($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'referer'; + $response = $this->auth($options); + $result = new GetRefererResult($response); + return $result->getData(); + } + + + /** + * Set the size of the bucket,the unit is GB + * When the capacity of the bucket is bigger than the set, it's forbidden to continue writing + * + * @param string $bucket bucket name + * @param int $storageCapacity + * @param array $options + * @return ResponseCore + * @throws null + */ + public function putBucketStorageCapacity($bucket, $storageCapacity, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $storageCapacityConfig = new StorageCapacityConfig($storageCapacity); + $options[self::OSS_CONTENT] = $storageCapacityConfig->serializeToXml(); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Get the capacity of the bucket, the unit is GB + * + * @param string $bucket bucket name + * @param array $options + * @throws OssException + * @return int + */ + public function getBucketStorageCapacity($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'qos'; + $response = $this->auth($options); + $result = new GetStorageCapacityResult($response); + return $result->getData(); + } + + + /** + * Lists the bucket's object list (in ObjectListInfo) + * + * @param string $bucket + * @param array $options are defined below: + * $options = array( + * 'max-keys' => specifies max object count to return. By default is 100 and max value could be 1000. + * 'prefix' => specifies the key prefix the returned objects must have. Note that the returned keys still contain the prefix. + * 'delimiter' => The delimiter of object name for grouping object. When it's specified, listObjects will differeniate the object and folder. And it will return subfolder's objects. + * 'marker' => The key of returned object must be greater than the 'marker'. + *) + * Prefix and marker are for filtering and paging. Their length must be less than 256 bytes + * @throws OssException + * @return ObjectListInfo + */ + public function listObjects($bucket, $options = NULL) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_HEADERS] = array( + self::OSS_DELIMITER => isset($options[self::OSS_DELIMITER]) ? $options[self::OSS_DELIMITER] : '/', + self::OSS_PREFIX => isset($options[self::OSS_PREFIX]) ? $options[self::OSS_PREFIX] : '', + self::OSS_MAX_KEYS => isset($options[self::OSS_MAX_KEYS]) ? $options[self::OSS_MAX_KEYS] : self::OSS_MAX_KEYS_VALUE, + self::OSS_MARKER => isset($options[self::OSS_MARKER]) ? $options[self::OSS_MARKER] : '', + ); + $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); + $options[self::OSS_QUERY_STRING] = array_merge( + $query, + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL) + ); + + $response = $this->auth($options); + $result = new ListObjectsResult($response); + return $result->getData(); + } + + /** + * Creates a virtual 'folder' in OSS. The name should not end with '/' because the method will append the name with a '/' anyway. + * + * Internal use only. + * + * @param string $bucket bucket name + * @param string $object object name + * @param array $options + * @return null + */ + public function createObjectDir($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object . '/'; + $options[self::OSS_CONTENT_LENGTH] = array(self::OSS_CONTENT_LENGTH => 0); + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Uploads the $content object to OSS. + * + * @param string $bucket bucket name + * @param string $object objcet name + * @param string $content The content object + * @param array $options + * @return null + */ + public function putObject($bucket, $object, $content, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + $options[self::OSS_CONTENT] = $content; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $object; + + if (!isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + } else { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5($content, true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + $response = $this->auth($options); + + if (isset($options[self::OSS_CALLBACK]) && !empty($options[self::OSS_CALLBACK])) { + $result = new CallbackResult($response); + } else { + $result = new PutSetDeleteResult($response); + } + + return $result->getData(); + } + + + /** + * creates symlink + * @param string $bucket bucket name + * @param string $symlink symlink name + * @param string $targetObject targetObject name + * @param array $options + * @return null + */ + public function putSymlink($bucket, $symlink ,$targetObject, $options = NULL) + { + $this->precheckCommon($bucket, $symlink, $options); + + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $symlink; + $options[self::OSS_SUB_RESOURCE] = self::OSS_SYMLINK; + $options[self::OSS_HEADERS][self::OSS_SYMLINK_TARGET] = rawurlencode($targetObject); + + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * gets symlink + *@param string $bucket bucket name + * @param string $symlink symlink name + * @return null + */ + public function getSymlink($bucket, $symlink) + { + $this->precheckCommon($bucket, $symlink, $options); + + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $symlink; + $options[self::OSS_SUB_RESOURCE] = self::OSS_SYMLINK; + + $response = $this->auth($options); + $result = new SymlinkResult($response); + return $result->getData(); + } + + /** + * Uploads a local file + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $file local file path + * @param array $options + * @return null + * @throws OssException + */ + public function uploadFile($bucket, $object, $file, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid"); + $file = OssUtil::encodePath($file); + if (!file_exists($file)) { + throw new OssException($file . " file does not exist"); + } + $options[self::OSS_FILE_UPLOAD] = $file; + $file_size = filesize($options[self::OSS_FILE_UPLOAD]); + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_CONTENT_LENGTH] = $file_size; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Append the object with the content at the specified position. + * The specified position is typically the lengh of the current file. + * @param string $bucket bucket name + * @param string $object objcet name + * @param string $content content to append + * @param array $options + * @return int next append position + * @throws OssException + */ + public function appendObject($bucket, $object, $content, $position, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + $options[self::OSS_CONTENT] = $content; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'append'; + $options[self::OSS_POSITION] = strval($position); + + if (!isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + } else { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5($content, true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + $response = $this->auth($options); + $result = new AppendResult($response); + return $result->getData(); + } + + /** + * Append the object with a local file + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $file The local file path to append with + * @param array $options + * @return int next append position + * @throws OssException + */ + public function appendFile($bucket, $object, $file, $position, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + + OssUtil::throwOssExceptionWithMessageIfEmpty($file, "file path is invalid"); + $file = OssUtil::encodePath($file); + if (!file_exists($file)) { + throw new OssException($file . " file does not exist"); + } + $options[self::OSS_FILE_UPLOAD] = $file; + $file_size = filesize($options[self::OSS_FILE_UPLOAD]); + $is_check_md5 = $this->isCheckMD5($options); + if ($is_check_md5) { + $content_md5 = base64_encode(md5_file($options[self::OSS_FILE_UPLOAD], true)); + $options[self::OSS_CONTENT_MD5] = $content_md5; + } + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $file); + } + + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_CONTENT_LENGTH] = $file_size; + $options[self::OSS_SUB_RESOURCE] = 'append'; + $options[self::OSS_POSITION] = strval($position); + + $response = $this->auth($options); + $result = new AppendResult($response); + return $result->getData(); + } + + /** + * Copy from an existing OSS object to another OSS object. If the target object exists already, it will be overwritten. + * + * @param string $fromBucket Source bucket name + * @param string $fromObject Source object name + * @param string $toBucket Target bucket name + * @param string $toObject Target object name + * @param array $options + * @return null + * @throws OssException + */ + public function copyObject($fromBucket, $fromObject, $toBucket, $toObject, $options = NULL) + { + $this->precheckCommon($fromBucket, $fromObject, $options); + $this->precheckCommon($toBucket, $toObject, $options); + $options[self::OSS_BUCKET] = $toBucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_OBJECT] = $toObject; + if (isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + } else { + $options[self::OSS_HEADERS] = array(self::OSS_OBJECT_COPY_SOURCE => '/' . $fromBucket . '/' . $fromObject); + } + $response = $this->auth($options); + $result = new CopyObjectResult($response); + return $result->getData(); + } + + /** + * Gets Object metadata + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $options Checks out the SDK document for the detail + * @return array + */ + public function getObjectMeta($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new HeaderResult($response); + return $result->getData(); + } + + /** + * Deletes a object + * + * @param string $bucket bucket name + * @param string $object object name + * @param array $options + * @return null + */ + public function deleteObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Deletes multiple objects in a bucket + * + * @param string $bucket bucket name + * @param array $objects object list + * @param array $options + * @return ResponseCore + * @throws null + */ + public function deleteObjects($bucket, $objects, $options = null) + { + $this->precheckCommon($bucket, NULL, $options, false); + if (!is_array($objects) || !$objects) { + throw new OssException('objects must be array'); + } + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'delete'; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + $quiet = 'false'; + if (isset($options['quiet'])) { + if (is_bool($options['quiet'])) { //Boolean + $quiet = $options['quiet'] ? 'true' : 'false'; + } elseif (is_string($options['quiet'])) { // string + $quiet = ($options['quiet'] === 'true') ? 'true' : 'false'; + } + } + $xmlBody = OssUtil::createDeleteObjectsXmlBody($objects, $quiet); + $options[self::OSS_CONTENT] = $xmlBody; + $response = $this->auth($options); + $result = new DeleteObjectsResult($response); + return $result->getData(); + } + + /** + * Gets Object content + * + * @param string $bucket bucket name + * @param string $object object name + * @param array $options It must contain ALIOSS::OSS_FILE_DOWNLOAD. And ALIOSS::OSS_RANGE is optional and empty means to download the whole file. + * @return string + */ + public function getObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_OBJECT] = $object; + if (isset($options[self::OSS_LAST_MODIFIED])) { + $options[self::OSS_HEADERS][self::OSS_IF_MODIFIED_SINCE] = $options[self::OSS_LAST_MODIFIED]; + unset($options[self::OSS_LAST_MODIFIED]); + } + if (isset($options[self::OSS_ETAG])) { + $options[self::OSS_HEADERS][self::OSS_IF_NONE_MATCH] = $options[self::OSS_ETAG]; + unset($options[self::OSS_ETAG]); + } + if (isset($options[self::OSS_RANGE])) { + $range = $options[self::OSS_RANGE]; + $options[self::OSS_HEADERS][self::OSS_RANGE] = "bytes=$range"; + unset($options[self::OSS_RANGE]); + } + $response = $this->auth($options); + //dump($response); + $result = new BodyResult($response); + //dump($result); + return $result->getData(); + } + + /** + * Checks if the object exists + * It's implemented by getObjectMeta(). + * + * @param string $bucket bucket name + * @param string $object object name + * @param array $options + * @return bool True:object exists; False:object does not exist + */ + public function doesObjectExist($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_HEAD; + $options[self::OSS_OBJECT] = $object; + $response = $this->auth($options); + $result = new ExistResult($response); + return $result->getData(); + } + + /** + * Object reading for Archive type + * Use Restore to enable the server to perform the thawing task + * + * @param string $bucket bucket name + * @param string $object object name + * @return null + * @throws OssException + */ + public function restoreObject($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = self::OSS_RESTORE; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Gets the part size according to the preferred part size. + * If the specified part size is too small or too big, it will return a min part or max part size instead. + * Otherwise returns the specified part size. + * @param int $partSize + * @return int + */ + private function computePartSize($partSize) + { + $partSize = (integer)$partSize; + if ($partSize <= self::OSS_MIN_PART_SIZE) { + $partSize = self::OSS_MIN_PART_SIZE; + } elseif ($partSize > self::OSS_MAX_PART_SIZE) { + $partSize = self::OSS_MAX_PART_SIZE; + } + return $partSize; + } + + /** + * Computes the parts count, size and start position according to the file size and the part size. + * It must be only called by upload_Part(). + * + * @param integer $file_size File size + * @param integer $partSize part大小,part size. Default is 5MB + * @return array An array contains key-value pairs--the key is `seekTo`and value is `length`. + */ + public function generateMultiuploadParts($file_size, $partSize = 5242880) + { + $i = 0; + $size_count = $file_size; + $values = array(); + $partSize = $this->computePartSize($partSize); + while ($size_count > 0) { + $size_count -= $partSize; + $values[] = array( + self::OSS_SEEK_TO => ($partSize * $i), + self::OSS_LENGTH => (($size_count > 0) ? $partSize : ($size_count + $partSize)), + ); + $i++; + } + return $values; + } + + /** + * Initialize a multi-part upload + * + * @param string $bucket bucket name + * @param string $object object name + * @param array $options Key-Value array + * @throws OssException + * @return string returns uploadid + */ + public function initiateMultipartUpload($bucket, $object, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_SUB_RESOURCE] = 'uploads'; + $options[self::OSS_CONTENT] = ''; + + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object); + } + if (!isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS] = array(); + } + $response = $this->auth($options); + $result = new InitiateMultipartUploadResult($response); + return $result->getData(); + } + + /** + * Upload a part in a multiparts upload. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $uploadId + * @param array $options Key-Value array + * @return string eTag + * @throws OssException + */ + public function uploadPart($bucket, $object, $uploadId, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + $this->precheckParam($options, self::OSS_FILE_UPLOAD, __FUNCTION__); + $this->precheckParam($options, self::OSS_PART_NUM, __FUNCTION__); + + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + + if (isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + } + $response = $this->auth($options); + $result = new UploadPartResult($response); + return $result->getData(); + } + + /** + * Gets the uploaded parts. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $uploadId uploadId + * @param array $options Key-Value array + * @return ListPartsInfo + * @throws OssException + */ + public function listParts($bucket, $object, $uploadId, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $options[self::OSS_QUERY_STRING] = array(); + foreach (array('max-parts', 'part-number-marker') as $param) { + if (isset($options[$param])) { + $options[self::OSS_QUERY_STRING][$param] = $options[$param]; + unset($options[$param]); + } + } + $response = $this->auth($options); + $result = new ListPartsResult($response); + return $result->getData(); + } + + /** + * Abort a multiparts upload + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $uploadId uploadId + * @param array $options Key-Value name + * @return null + * @throws OssException + */ + public function abortMultipartUpload($bucket, $object, $uploadId, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_DELETE; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $response = $this->auth($options); + $result = new PutSetDeleteResult($response); + return $result->getData(); + } + + /** + * Completes a multiparts upload, after all parts are uploaded. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $uploadId uploadId + * @param array $listParts array( array("PartNumber"=> int, "ETag"=>string)) + * @param array $options Key-Value array + * @throws OssException + * @return null + */ + public function completeMultipartUpload($bucket, $object, $uploadId, $listParts, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + $options[self::OSS_METHOD] = self::OSS_HTTP_POST; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_UPLOAD_ID] = $uploadId; + $options[self::OSS_CONTENT_TYPE] = 'application/xml'; + if (!is_array($listParts)) { + throw new OssException("listParts must be array type"); + } + $options[self::OSS_CONTENT] = OssUtil::createCompleteMultipartUploadXmlBody($listParts); + $response = $this->auth($options); + if (isset($options[self::OSS_CALLBACK]) && !empty($options[self::OSS_CALLBACK])) { + $result = new CallbackResult($response); + } else { + $result = new PutSetDeleteResult($response); + } + return $result->getData(); + } + + /** + * Lists all ongoing multipart upload events, which means all initialized but not completed or aborted multipart uploads. + * + * @param string $bucket bucket + * @param array $options key-value array--expected keys are 'delimiter', 'key-marker', 'max-uploads', 'prefix', 'upload-id-marker' + * @throws OssException + * @return ListMultipartUploadInfo + */ + public function listMultipartUploads($bucket, $options = null) + { + $this->precheckCommon($bucket, NULL, $options, false); + $options[self::OSS_METHOD] = self::OSS_HTTP_GET; + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = '/'; + $options[self::OSS_SUB_RESOURCE] = 'uploads'; + + foreach (array('delimiter', 'key-marker', 'max-uploads', 'prefix', 'upload-id-marker') as $param) { + if (isset($options[$param])) { + $options[self::OSS_QUERY_STRING][$param] = $options[$param]; + unset($options[$param]); + } + } + $query = isset($options[self::OSS_QUERY_STRING]) ? $options[self::OSS_QUERY_STRING] : array(); + $options[self::OSS_QUERY_STRING] = array_merge( + $query, + array(self::OSS_ENCODING_TYPE => self::OSS_ENCODING_TYPE_URL) + ); + + $response = $this->auth($options); + $result = new ListMultipartUploadResult($response); + return $result->getData(); + } + + /** + * Copy an existing file as a part + * + * @param string $fromBucket source bucket name + * @param string $fromObject source object name + * @param string $toBucket target bucket name + * @param string $toObject target object name + * @param int $partNumber Part number + * @param string $uploadId Upload Id + * @param array $options Key-Value array---it should have 'start' or 'end' key to specify the range of the source object to copy. If it's not specifed, the whole object is copied. + * @return null + * @throws OssException + */ + public function uploadPartCopy($fromBucket, $fromObject, $toBucket, $toObject, $partNumber, $uploadId, $options = NULL) + { + $this->precheckCommon($fromBucket, $fromObject, $options); + $this->precheckCommon($toBucket, $toObject, $options); + + //If $options['isFullCopy'] is not set, copy from the beginning + $start_range = "0"; + if (isset($options['start'])) { + $start_range = $options['start']; + } + $end_range = ""; + if (isset($options['end'])) { + $end_range = $options['end']; + } + $options[self::OSS_METHOD] = self::OSS_HTTP_PUT; + $options[self::OSS_BUCKET] = $toBucket; + $options[self::OSS_OBJECT] = $toObject; + $options[self::OSS_PART_NUM] = $partNumber; + $options[self::OSS_UPLOAD_ID] = $uploadId; + + if (!isset($options[self::OSS_HEADERS])) { + $options[self::OSS_HEADERS] = array(); + } + + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE] = '/' . $fromBucket . '/' . $fromObject; + $options[self::OSS_HEADERS][self::OSS_OBJECT_COPY_SOURCE_RANGE] = "bytes=" . $start_range . "-" . $end_range; + $response = $this->auth($options); + $result = new UploadPartResult($response); + return $result->getData(); + } + + /** + * A higher level API for uploading a file with multipart upload. It consists of initialization, parts upload and completion. + * + * @param string $bucket bucket name + * @param string $object object name + * @param string $file The local file to upload + * @param array $options Key-Value array + * @return null + * @throws OssException + */ + public function multiuploadFile($bucket, $object, $file, $options = null) + { + $this->precheckCommon($bucket, $object, $options); + if (isset($options[self::OSS_LENGTH])) { + $options[self::OSS_CONTENT_LENGTH] = $options[self::OSS_LENGTH]; + unset($options[self::OSS_LENGTH]); + } + if (empty($file)) { + throw new OssException("parameter invalid, file is empty"); + } + $uploadFile = OssUtil::encodePath($file); + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = $this->getMimeType($object, $uploadFile); + } + + $upload_position = isset($options[self::OSS_SEEK_TO]) ? (integer)$options[self::OSS_SEEK_TO] : 0; + + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $upload_file_size = (integer)$options[self::OSS_CONTENT_LENGTH]; + } else { + $upload_file_size = filesize($uploadFile); + if ($upload_file_size !== false) { + $upload_file_size -= $upload_position; + } + } + + if ($upload_position === false || !isset($upload_file_size) || $upload_file_size === false || $upload_file_size < 0) { + throw new OssException('The size of `fileUpload` cannot be determined in ' . __FUNCTION__ . '().'); + } + // Computes the part size and assign it to options. + if (isset($options[self::OSS_PART_SIZE])) { + $options[self::OSS_PART_SIZE] = $this->computePartSize($options[self::OSS_PART_SIZE]); + } else { + $options[self::OSS_PART_SIZE] = self::OSS_MID_PART_SIZE; + } + + $is_check_md5 = $this->isCheckMD5($options); + // if the file size is less than part size, use simple file upload. + if ($upload_file_size < $options[self::OSS_PART_SIZE] && !isset($options[self::OSS_UPLOAD_ID])) { + return $this->uploadFile($bucket, $object, $uploadFile, $options); + } + + // Using multipart upload, initialize if no OSS_UPLOAD_ID is specified in options. + if (isset($options[self::OSS_UPLOAD_ID])) { + $uploadId = $options[self::OSS_UPLOAD_ID]; + } else { + // initialize + $uploadId = $this->initiateMultipartUpload($bucket, $object, $options); + } + + // generates the parts information and upload them one by one + $pieces = $this->generateMultiuploadParts($upload_file_size, (integer)$options[self::OSS_PART_SIZE]); + $response_upload_part = array(); + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[self::OSS_SEEK_TO]; + $to_pos = (integer)$piece[self::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + self::OSS_FILE_UPLOAD => $uploadFile, + self::OSS_PART_NUM => ($i + 1), + self::OSS_SEEK_TO => $from_pos, + self::OSS_LENGTH => $to_pos - $from_pos + 1, + self::OSS_CHECK_MD5 => $is_check_md5, + ); + if ($is_check_md5) { + $content_md5 = OssUtil::getMd5SumForFile($uploadFile, $from_pos, $to_pos); + $up_options[self::OSS_CONTENT_MD5] = $content_md5; + } + $response_upload_part[] = $this->uploadPart($bucket, $object, $uploadId, $up_options); + } + + $uploadParts = array(); + foreach ($response_upload_part as $i => $etag) { + $uploadParts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $etag, + ); + } + return $this->completeMultipartUpload($bucket, $object, $uploadId, $uploadParts); + } + + /** + * Uploads the local directory to the specified bucket into specified folder (prefix) + * + * @param string $bucket bucket name + * @param string $prefix The object key prefix. Typically it's folder name. The name should not end with '/' as the API appends it automatically. + * @param string $localDirectory The local directory to upload + * @param string $exclude To excluded directories + * @param bool $recursive Recursive flag. True: Recursively upload all datas under the local directory; False: only upload first layer's files. + * @param bool $checkMd5 + * @return array Returns two list: array("succeededList" => array("object"), "failedList" => array("object"=>"errorMessage")) + * @throws OssException + */ + public function uploadDir($bucket, $prefix, $localDirectory, $exclude = '.|..|.svn|.git', $recursive = false, $checkMd5 = true) + { + $retArray = array("succeededList" => array(), "failedList" => array()); + if (empty($bucket)) throw new OssException("parameter error, bucket is empty"); + if (!is_string($prefix)) throw new OssException("parameter error, prefix is not string"); + if (empty($localDirectory)) throw new OssException("parameter error, localDirectory is empty"); + $directory = $localDirectory; + $directory = OssUtil::encodePath($directory); + //If it's not the local directory, throw OSSException. + if (!is_dir($directory)) { + throw new OssException('parameter error: ' . $directory . ' is not a directory, please check it'); + } + //read directory + $file_list_array = OssUtil::readDir($directory, $exclude, $recursive); + if (!$file_list_array) { + throw new OssException($directory . ' is empty...'); + } + foreach ($file_list_array as $k => $item) { + if (is_dir($item['path'])) { + continue; + } + $options = array( + self::OSS_PART_SIZE => self::OSS_MIN_PART_SIZE, + self::OSS_CHECK_MD5 => $checkMd5, + ); + $realObject = (!empty($prefix) ? $prefix . '/' : '') . $item['file']; + + try { + $this->multiuploadFile($bucket, $realObject, $item['path'], $options); + $retArray["succeededList"][] = $realObject; + } catch (OssException $e) { + $retArray["failedList"][$realObject] = $e->getMessage(); + } + } + return $retArray; + } + + /** + * Sign URL with specified expiration time in seconds (timeout) and HTTP method. + * The signed URL could be used to access the object directly. + * + * @param string $bucket + * @param string $object + * @param int $timeout expiration time in seconds. + * @param string $method + * @param array $options Key-Value array + * @return string + * @throws OssException + */ + public function signUrl($bucket, $object, $timeout = 60, $method = self::OSS_HTTP_GET, $options = NULL) + { + $this->precheckCommon($bucket, $object, $options); + //method + if (self::OSS_HTTP_GET !== $method && self::OSS_HTTP_PUT !== $method) { + throw new OssException("method is invalid"); + } + $options[self::OSS_BUCKET] = $bucket; + $options[self::OSS_OBJECT] = $object; + $options[self::OSS_METHOD] = $method; + if (!isset($options[self::OSS_CONTENT_TYPE])) { + $options[self::OSS_CONTENT_TYPE] = ''; + } + $timeout = time() + $timeout; + $options[self::OSS_PREAUTH] = $timeout; + $options[self::OSS_DATE] = $timeout; + $this->setSignStsInUrl(true); + return $this->auth($options); + } + + /** + * validates options. Create a empty array if it's NULL. + * + * @param array $options + * @throws OssException + */ + private function precheckOptions(&$options) + { + OssUtil::validateOptions($options); + if (!$options) { + $options = array(); + } + } + + /** + * Validates bucket parameter + * + * @param string $bucket + * @param string $errMsg + * @throws OssException + */ + private function precheckBucket($bucket, $errMsg = 'bucket is not allowed empty') + { + OssUtil::throwOssExceptionWithMessageIfEmpty($bucket, $errMsg); + } + + /** + * validates object parameter + * + * @param string $object + * @throws OssException + */ + private function precheckObject($object) + { + OssUtil::throwOssExceptionWithMessageIfEmpty($object, "object name is empty"); + } + + /** + * 校验option restore + * + * @param string $restore + * @throws OssException + */ + private function precheckStorage($storage) + { + if (is_string($storage)) { + switch ($storage) { + case self::OSS_STORAGE_ARCHIVE: + return; + case self::OSS_STORAGE_IA: + return; + case self::OSS_STORAGE_STANDARD: + return; + default: + break; + } + } + throw new OssException('storage name is invalid'); + } + + /** + * Validates bucket,options parameters and optionally validate object parameter. + * + * @param string $bucket + * @param string $object + * @param array $options + * @param bool $isCheckObject + */ + private function precheckCommon($bucket, $object, &$options, $isCheckObject = true) + { + if ($isCheckObject) { + $this->precheckObject($object); + } + $this->precheckOptions($options); + $this->precheckBucket($bucket); + } + + /** + * checks parameters + * + * @param array $options + * @param string $param + * @param string $funcName + * @throws OssException + */ + private function precheckParam($options, $param, $funcName) + { + if (!isset($options[$param])) { + throw new OssException('The `' . $param . '` options is required in ' . $funcName . '().'); + } + } + + /** + * Checks md5 + * + * @param array $options + * @return bool|null + */ + private function isCheckMD5($options) + { + return $this->getValue($options, self::OSS_CHECK_MD5, false, true, true); + } + + /** + * Gets value of the specified key from the options + * + * @param array $options + * @param string $key + * @param string $default + * @param bool $isCheckEmpty + * @param bool $isCheckBool + * @return bool|null + */ + private function getValue($options, $key, $default = NULL, $isCheckEmpty = false, $isCheckBool = false) + { + $value = $default; + if (isset($options[$key])) { + if ($isCheckEmpty) { + if (!empty($options[$key])) { + $value = $options[$key]; + } + } else { + $value = $options[$key]; + } + unset($options[$key]); + } + if ($isCheckBool) { + if ($value !== true && $value !== false) { + $value = false; + } + } + return $value; + } + + /** + * Gets mimetype + * + * @param string $object + * @return string + */ + private function getMimeType($object, $file = null) + { + if (!is_null($file)) { + $type = MimeTypes::getMimetype($file); + if (!is_null($type)) { + return $type; + } + } + + $type = MimeTypes::getMimetype($object); + if (!is_null($type)) { + return $type; + } + + return self::DEFAULT_CONTENT_TYPE; + } + + /** + * Validates and executes the request according to OSS API protocol. + * + * @param array $options + * @return ResponseCore + * @throws OssException + * @throws RequestCore_Exception + */ + private function auth($options) + { + OssUtil::validateOptions($options); + //Validates bucket, not required for list_bucket + $this->authPrecheckBucket($options); + //Validates object + $this->authPrecheckObject($options); + //object name encoding must be UTF-8 + $this->authPrecheckObjectEncoding($options); + //Validates ACL + $this->authPrecheckAcl($options); + // Should https or http be used? + $scheme = $this->useSSL ? 'https://' : 'http://'; + // gets the host name. If the host name is public domain or private domain, form a third level domain by prefixing the bucket name on the domain name. + $hostname = $this->generateHostname($options[self::OSS_BUCKET]); + $string_to_sign = ''; + $headers = $this->generateHeaders($options, $hostname); + $signable_query_string_params = $this->generateSignableQueryStringParam($options); + $signable_query_string = OssUtil::toQueryString($signable_query_string_params); + $resource_uri = $this->generateResourceUri($options); + //Generates the URL (add query parameters) + $conjunction = '?'; + $non_signable_resource = ''; + if (isset($options[self::OSS_SUB_RESOURCE])) { + $conjunction = '&'; + } + if ($signable_query_string !== '') { + $signable_query_string = $conjunction . $signable_query_string; + $conjunction = '&'; + } + $query_string = $this->generateQueryString($options); + if ($query_string !== '') { + $non_signable_resource .= $conjunction . $query_string; + $conjunction = '&'; + } + $this->requestUrl = $scheme . $hostname . $resource_uri . $signable_query_string . $non_signable_resource; + //Creates the request + $request = new RequestCore($this->requestUrl, $this->requestProxy); + $request->set_useragent($this->generateUserAgent()); + // Streaming uploads + if (isset($options[self::OSS_FILE_UPLOAD])) { + if (is_resource($options[self::OSS_FILE_UPLOAD])) { + $length = null; + + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $length = $options[self::OSS_CONTENT_LENGTH]; + } elseif (isset($options[self::OSS_SEEK_TO])) { + $stats = fstat($options[self::OSS_FILE_UPLOAD]); + if ($stats && $stats[self::OSS_SIZE] >= 0) { + $length = $stats[self::OSS_SIZE] - (integer)$options[self::OSS_SEEK_TO]; + } + } + $request->set_read_stream($options[self::OSS_FILE_UPLOAD], $length); + } else { + $request->set_read_file($options[self::OSS_FILE_UPLOAD]); + $length = $request->read_stream_size; + if (isset($options[self::OSS_CONTENT_LENGTH])) { + $length = $options[self::OSS_CONTENT_LENGTH]; + } elseif (isset($options[self::OSS_SEEK_TO]) && isset($length)) { + $length -= (integer)$options[self::OSS_SEEK_TO]; + } + $request->set_read_stream_size($length); + } + } + if (isset($options[self::OSS_SEEK_TO])) { + $request->set_seek_position((integer)$options[self::OSS_SEEK_TO]); + } + if (isset($options[self::OSS_FILE_DOWNLOAD])) { + if (is_resource($options[self::OSS_FILE_DOWNLOAD])) { + $request->set_write_stream($options[self::OSS_FILE_DOWNLOAD]); + } else { + $request->set_write_file($options[self::OSS_FILE_DOWNLOAD]); + } + } + + if (isset($options[self::OSS_METHOD])) { + $request->set_method($options[self::OSS_METHOD]); + $string_to_sign .= $options[self::OSS_METHOD] . "\n"; + } + + if (isset($options[self::OSS_CONTENT])) { + $request->set_body($options[self::OSS_CONTENT]); + if ($headers[self::OSS_CONTENT_TYPE] === 'application/x-www-form-urlencoded') { + $headers[self::OSS_CONTENT_TYPE] = 'application/octet-stream'; + } + + $headers[self::OSS_CONTENT_LENGTH] = strlen($options[self::OSS_CONTENT]); + $headers[self::OSS_CONTENT_MD5] = base64_encode(md5($options[self::OSS_CONTENT], true)); + } + + if (isset($options[self::OSS_CALLBACK])) { + $headers[self::OSS_CALLBACK] = base64_encode($options[self::OSS_CALLBACK]); + } + if (isset($options[self::OSS_CALLBACK_VAR])) { + $headers[self::OSS_CALLBACK_VAR] = base64_encode($options[self::OSS_CALLBACK_VAR]); + } + + if (!isset($headers[self::OSS_ACCEPT_ENCODING])) { + $headers[self::OSS_ACCEPT_ENCODING] = ''; + } + + uksort($headers, 'strnatcasecmp'); + + foreach ($headers as $header_key => $header_value) { + $header_value = str_replace(array("\r", "\n"), '', $header_value); + if ($header_value !== '' || $header_key === self::OSS_ACCEPT_ENCODING) { + $request->add_header($header_key, $header_value); + } + + if ( + strtolower($header_key) === 'content-md5' || + strtolower($header_key) === 'content-type' || + strtolower($header_key) === 'date' || + (isset($options['self::OSS_PREAUTH']) && (integer)$options['self::OSS_PREAUTH'] > 0) + ) { + $string_to_sign .= $header_value . "\n"; + } elseif (substr(strtolower($header_key), 0, 6) === self::OSS_DEFAULT_PREFIX) { + $string_to_sign .= strtolower($header_key) . ':' . $header_value . "\n"; + } + } + // Generates the signable_resource + $signable_resource = $this->generateSignableResource($options); + $string_to_sign .= rawurldecode($signable_resource) . urldecode($signable_query_string); + + // Sort the strings to be signed. + $string_to_sign_ordered = $this->stringToSignSorted($string_to_sign); + + $signature = base64_encode(hash_hmac('sha1', $string_to_sign_ordered, $this->accessKeySecret, true)); + $request->add_header('Authorization', 'OSS ' . $this->accessKeyId . ':' . $signature); + + if (isset($options[self::OSS_PREAUTH]) && (integer)$options[self::OSS_PREAUTH] > 0) { + $signed_url = $this->requestUrl . $conjunction . self::OSS_URL_ACCESS_KEY_ID . '=' . rawurlencode($this->accessKeyId) . '&' . self::OSS_URL_EXPIRES . '=' . $options[self::OSS_PREAUTH] . '&' . self::OSS_URL_SIGNATURE . '=' . rawurlencode($signature); + return $signed_url; + } elseif (isset($options[self::OSS_PREAUTH])) { + return $this->requestUrl; + } + + if ($this->timeout !== 0) { + $request->timeout = $this->timeout; + } + if ($this->connectTimeout !== 0) { + $request->connect_timeout = $this->connectTimeout; + } + + try { + $request->send_request(); + } catch (RequestCore_Exception $e) { + throw(new OssException('RequestCoreException: ' . $e->getMessage())); + } + $response_header = $request->get_response_header(); + $response_header['oss-request-url'] = $this->requestUrl; + $response_header['oss-redirects'] = $this->redirects; + $response_header['oss-stringtosign'] = $string_to_sign; + $response_header['oss-requestheaders'] = $request->request_headers; + $data = new ResponseCore($response_header, $request->get_response_body(), $request->get_response_code()); + //retry if OSS Internal Error + if ((integer)$request->get_response_code() === 500) { + if ($this->redirects <= $this->maxRetries) { + //Sets the sleep time betwen each retry. + $delay = (integer)(pow(4, $this->redirects) * 100000); + usleep($delay); + $this->redirects++; + $data = $this->auth($options); + } + } + + $this->redirects = 0; + return $data; + } + + /** + * Sets the max retry count + * + * @param int $maxRetries + * @return void + */ + public function setMaxTries($maxRetries = 3) + { + $this->maxRetries = $maxRetries; + } + + /** + * Gets the max retry count + * + * @return int + */ + public function getMaxRetries() + { + return $this->maxRetries; + } + + /** + * Enaable/disable STS in the URL. This is to determine the $sts value passed from constructor take effect or not. + * + * @param boolean $enable + */ + public function setSignStsInUrl($enable) + { + $this->enableStsInUrl = $enable; + } + + /** + * @return boolean + */ + public function isUseSSL() + { + return $this->useSSL; + } + + /** + * @param boolean $useSSL + */ + public function setUseSSL($useSSL) + { + $this->useSSL = $useSSL; + } + + /** + * Validates bucket name--throw OssException if it's invalid + * + * @param $options + * @throws OssException + */ + private function authPrecheckBucket($options) + { + if (!(('/' == $options[self::OSS_OBJECT]) && ('' == $options[self::OSS_BUCKET]) && ('GET' == $options[self::OSS_METHOD])) && !OssUtil::validateBucket($options[self::OSS_BUCKET])) { + throw new OssException('"' . $options[self::OSS_BUCKET] . '"' . 'bucket name is invalid'); + } + } + + /** + * + * Validates the object name--throw OssException if it's invalid. + * + * @param $options + * @throws OssException + */ + private function authPrecheckObject($options) + { + if (isset($options[self::OSS_OBJECT]) && $options[self::OSS_OBJECT] === '/') { + return; + } + + if (isset($options[self::OSS_OBJECT]) && !OssUtil::validateObject($options[self::OSS_OBJECT])) { + throw new OssException('"' . $options[self::OSS_OBJECT] . '"' . ' object name is invalid'); + } + } + + /** + * Checks the object's encoding. Convert it to UTF8 if it's in GBK or GB2312 + * + * @param mixed $options parameter + */ + private function authPrecheckObjectEncoding(&$options) + { + $tmp_object = $options[self::OSS_OBJECT]; + try { + if (OssUtil::isGb2312($options[self::OSS_OBJECT])) { + $options[self::OSS_OBJECT] = iconv('GB2312', "UTF-8//IGNORE", $options[self::OSS_OBJECT]); + } elseif (OssUtil::checkChar($options[self::OSS_OBJECT], true)) { + $options[self::OSS_OBJECT] = iconv('GBK', "UTF-8//IGNORE", $options[self::OSS_OBJECT]); + } + } catch (\Exception $e) { + try { + $tmp_object = iconv(mb_detect_encoding($tmp_object), "UTF-8", $tmp_object); + } catch (\Exception $e) { + } + } + $options[self::OSS_OBJECT] = $tmp_object; + } + + /** + * Checks if the ACL is one of the 3 predefined one. Throw OSSException if not. + * + * @param $options + * @throws OssException + */ + private function authPrecheckAcl($options) + { + if (isset($options[self::OSS_HEADERS][self::OSS_ACL]) && !empty($options[self::OSS_HEADERS][self::OSS_ACL])) { + if (!in_array(strtolower($options[self::OSS_HEADERS][self::OSS_ACL]), self::$OSS_ACL_TYPES)) { + throw new OssException($options[self::OSS_HEADERS][self::OSS_ACL] . ':' . 'acl is invalid(private,public-read,public-read-write)'); + } + } + } + + /** + * Gets the host name for the current request. + * It could be either a third level domain (prefixed by bucket name) or second level domain if it's CName or IP + * + * @param $bucket + * @return string The host name without the protocol scheem (e.g. https://) + */ + private function generateHostname($bucket) + { + if ($this->hostType === self::OSS_HOST_TYPE_IP) { + $hostname = $this->hostname; + } elseif ($this->hostType === self::OSS_HOST_TYPE_CNAME) { + $hostname = $this->hostname; + } else { + // Private domain or public domain + $hostname = ($bucket == '') ? $this->hostname : ($bucket . '.') . $this->hostname; + } + return $hostname; + } + + /** + * Gets the resource Uri in the current request + * + * @param $options + * @return string return the resource uri. + */ + private function generateResourceUri($options) + { + $resource_uri = ""; + + // resource_uri + bucket + if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) { + if ($this->hostType === self::OSS_HOST_TYPE_IP) { + $resource_uri = '/' . $options[self::OSS_BUCKET]; + } + } + + // resource_uri + object + if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) { + $resource_uri .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT])); + } + + // resource_uri + sub_resource + $conjunction = '?'; + if (isset($options[self::OSS_SUB_RESOURCE])) { + $resource_uri .= $conjunction . $options[self::OSS_SUB_RESOURCE]; + } + return $resource_uri; + } + + /** + * Generates the signalbe query string parameters in array type + * + * @param array $options + * @return array + */ + private function generateSignableQueryStringParam($options) + { + $signableQueryStringParams = array(); + $signableList = array( + self::OSS_PART_NUM, + 'response-content-type', + 'response-content-language', + 'response-cache-control', + 'response-content-encoding', + 'response-expires', + 'response-content-disposition', + self::OSS_UPLOAD_ID, + self::OSS_COMP, + self::OSS_LIVE_CHANNEL_STATUS, + self::OSS_LIVE_CHANNEL_START_TIME, + self::OSS_LIVE_CHANNEL_END_TIME, + self::OSS_PROCESS, + self::OSS_POSITION, + self::OSS_SYMLINK, + self::OSS_RESTORE, + ); + + foreach ($signableList as $item) { + if (isset($options[$item])) { + $signableQueryStringParams[$item] = $options[$item]; + } + } + + if ($this->enableStsInUrl && (!is_null($this->securityToken))) { + $signableQueryStringParams["security-token"] = $this->securityToken; + } + + return $signableQueryStringParams; + } + + /** + * Generates the resource uri for signing + * + * @param mixed $options + * @return string + */ + private function generateSignableResource($options) + { + $signableResource = ""; + $signableResource .= '/'; + if (isset($options[self::OSS_BUCKET]) && '' !== $options[self::OSS_BUCKET]) { + $signableResource .= $options[self::OSS_BUCKET]; + // if there's no object in options, adding a '/' if the host type is not IP.\ + if ($options[self::OSS_OBJECT] == '/') { + if ($this->hostType !== self::OSS_HOST_TYPE_IP) { + $signableResource .= "/"; + } + } + } + //signable_resource + object + if (isset($options[self::OSS_OBJECT]) && '/' !== $options[self::OSS_OBJECT]) { + $signableResource .= '/' . str_replace(array('%2F', '%25'), array('/', '%'), rawurlencode($options[self::OSS_OBJECT])); + } + if (isset($options[self::OSS_SUB_RESOURCE])) { + $signableResource .= '?' . $options[self::OSS_SUB_RESOURCE]; + } + return $signableResource; + } + + /** + * generates query string + * + * @param mixed $options + * @return string + */ + private function generateQueryString($options) + { + //query parameters + $queryStringParams = array(); + if (isset($options[self::OSS_QUERY_STRING])) { + $queryStringParams = array_merge($queryStringParams, $options[self::OSS_QUERY_STRING]); + } + return OssUtil::toQueryString($queryStringParams); + } + + private function stringToSignSorted($string_to_sign) + { + $queryStringSorted = ''; + $explodeResult = explode('?', $string_to_sign); + $index = count($explodeResult); + if ($index === 1) + return $string_to_sign; + + $queryStringParams = explode('&', $explodeResult[$index - 1]); + sort($queryStringParams); + + foreach($queryStringParams as $params) + { + $queryStringSorted .= $params . '&'; + } + + $queryStringSorted = substr($queryStringSorted, 0, -1); + + return $explodeResult[0] . '?' . $queryStringSorted; + } + + /** + * Initialize headers + * + * @param mixed $options + * @param string $hostname hostname + * @return array + */ + private function generateHeaders($options, $hostname) + { + $headers = array( + self::OSS_CONTENT_MD5 => '', + self::OSS_CONTENT_TYPE => isset($options[self::OSS_CONTENT_TYPE]) ? $options[self::OSS_CONTENT_TYPE] : self::DEFAULT_CONTENT_TYPE, + self::OSS_DATE => isset($options[self::OSS_DATE]) ? $options[self::OSS_DATE] : gmdate('D, d M Y H:i:s \G\M\T'), + self::OSS_HOST => $hostname, + ); + if (isset($options[self::OSS_CONTENT_MD5])) { + $headers[self::OSS_CONTENT_MD5] = $options[self::OSS_CONTENT_MD5]; + } + + //Add stsSecurityToken + if ((!is_null($this->securityToken)) && (!$this->enableStsInUrl)) { + $headers[self::OSS_SECURITY_TOKEN] = $this->securityToken; + } + //Merge HTTP headers + if (isset($options[self::OSS_HEADERS])) { + $headers = array_merge($headers, $options[self::OSS_HEADERS]); + } + return $headers; + } + + /** + * Generates UserAgent + * + * @return string + */ + private function generateUserAgent() + { + return self::OSS_NAME . "/" . self::OSS_VERSION . " (" . php_uname('s') . "/" . php_uname('r') . "/" . php_uname('m') . ";" . PHP_VERSION . ")"; + } + + /** + * Checks endpoint type and returns the endpoint without the protocol schema. + * Figures out the domain's type (ip, cname or private/public domain). + * + * @param string $endpoint + * @param boolean $isCName + * @return string The domain name without the protocol schema. + */ + private function checkEndpoint($endpoint, $isCName) + { + $ret_endpoint = null; + if (strpos($endpoint, 'http://') === 0) { + $ret_endpoint = substr($endpoint, strlen('http://')); + } elseif (strpos($endpoint, 'https://') === 0) { + $ret_endpoint = substr($endpoint, strlen('https://')); + $this->useSSL = true; + } else { + $ret_endpoint = $endpoint; + } + + if ($isCName) { + $this->hostType = self::OSS_HOST_TYPE_CNAME; + } elseif (OssUtil::isIPFormat($ret_endpoint)) { + $this->hostType = self::OSS_HOST_TYPE_IP; + } else { + $this->hostType = self::OSS_HOST_TYPE_NORMAL; + } + return $ret_endpoint; + } + + /** + * Check if all dependent extensions are installed correctly. + * For now only "curl" is needed. + * @throws OssException + */ + public static function checkEnv() + { + if (function_exists('get_loaded_extensions')) { + //Test curl extension + $enabled_extension = array("curl"); + $extensions = get_loaded_extensions(); + if ($extensions) { + foreach ($enabled_extension as $item) { + if (!in_array($item, $extensions)) { + throw new OssException("Extension {" . $item . "} is not installed or not enabled, please check your php env."); + } + } + } else { + throw new OssException("function get_loaded_extensions not found."); + } + } else { + throw new OssException('Function get_loaded_extensions has been disabled, please check php config.'); + } + } + + /** + * Sets the http's timeout (in seconds) + * + * @param int $timeout + */ + public function setTimeout($timeout) + { + $this->timeout = $timeout; + } + + /** + * Sets the http's connection timeout (in seconds) + * + * @param int $connectTimeout + */ + public function setConnectTimeout($connectTimeout) + { + $this->connectTimeout = $connectTimeout; + } + + // Constants for Life cycle + const OSS_LIFECYCLE_EXPIRATION = "Expiration"; + const OSS_LIFECYCLE_TIMING_DAYS = "Days"; + const OSS_LIFECYCLE_TIMING_DATE = "Date"; + //OSS Internal constants + const OSS_BUCKET = 'bucket'; + const OSS_OBJECT = 'object'; + const OSS_HEADERS = OssUtil::OSS_HEADERS; + const OSS_METHOD = 'method'; + const OSS_QUERY = 'query'; + const OSS_BASENAME = 'basename'; + const OSS_MAX_KEYS = 'max-keys'; + const OSS_UPLOAD_ID = 'uploadId'; + const OSS_PART_NUM = 'partNumber'; + const OSS_COMP = 'comp'; + const OSS_LIVE_CHANNEL_STATUS = 'status'; + const OSS_LIVE_CHANNEL_START_TIME = 'startTime'; + const OSS_LIVE_CHANNEL_END_TIME = 'endTime'; + const OSS_POSITION = 'position'; + const OSS_MAX_KEYS_VALUE = 100; + const OSS_MAX_OBJECT_GROUP_VALUE = OssUtil::OSS_MAX_OBJECT_GROUP_VALUE; + const OSS_MAX_PART_SIZE = OssUtil::OSS_MAX_PART_SIZE; + const OSS_MID_PART_SIZE = OssUtil::OSS_MID_PART_SIZE; + const OSS_MIN_PART_SIZE = OssUtil::OSS_MIN_PART_SIZE; + const OSS_FILE_SLICE_SIZE = 8192; + const OSS_PREFIX = 'prefix'; + const OSS_DELIMITER = 'delimiter'; + const OSS_MARKER = 'marker'; + const OSS_ACCEPT_ENCODING = 'Accept-Encoding'; + const OSS_CONTENT_MD5 = 'Content-Md5'; + const OSS_SELF_CONTENT_MD5 = 'x-oss-meta-md5'; + const OSS_CONTENT_TYPE = 'Content-Type'; + const OSS_CONTENT_LENGTH = 'Content-Length'; + const OSS_IF_MODIFIED_SINCE = 'If-Modified-Since'; + const OSS_IF_UNMODIFIED_SINCE = 'If-Unmodified-Since'; + const OSS_IF_MATCH = 'If-Match'; + const OSS_IF_NONE_MATCH = 'If-None-Match'; + const OSS_CACHE_CONTROL = 'Cache-Control'; + const OSS_EXPIRES = 'Expires'; + const OSS_PREAUTH = 'preauth'; + const OSS_CONTENT_COING = 'Content-Coding'; + const OSS_CONTENT_DISPOSTION = 'Content-Disposition'; + const OSS_RANGE = 'range'; + const OSS_ETAG = 'etag'; + const OSS_LAST_MODIFIED = 'lastmodified'; + const OS_CONTENT_RANGE = 'Content-Range'; + const OSS_CONTENT = OssUtil::OSS_CONTENT; + const OSS_BODY = 'body'; + const OSS_LENGTH = OssUtil::OSS_LENGTH; + const OSS_HOST = 'Host'; + const OSS_DATE = 'Date'; + const OSS_AUTHORIZATION = 'Authorization'; + const OSS_FILE_DOWNLOAD = 'fileDownload'; + const OSS_FILE_UPLOAD = 'fileUpload'; + const OSS_PART_SIZE = 'partSize'; + const OSS_SEEK_TO = 'seekTo'; + const OSS_SIZE = 'size'; + const OSS_QUERY_STRING = 'query_string'; + const OSS_SUB_RESOURCE = 'sub_resource'; + const OSS_DEFAULT_PREFIX = 'x-oss-'; + const OSS_CHECK_MD5 = 'checkmd5'; + const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + const OSS_SYMLINK_TARGET = 'x-oss-symlink-target'; + const OSS_SYMLINK = 'symlink'; + const OSS_HTTP_CODE = 'http_code'; + const OSS_REQUEST_ID = 'x-oss-request-id'; + const OSS_INFO = 'info'; + const OSS_STORAGE = 'storage'; + const OSS_RESTORE = 'restore'; + const OSS_STORAGE_STANDARD = 'Standard'; + const OSS_STORAGE_IA = 'IA'; + const OSS_STORAGE_ARCHIVE = 'Archive'; + + //private URLs + const OSS_URL_ACCESS_KEY_ID = 'OSSAccessKeyId'; + const OSS_URL_EXPIRES = 'Expires'; + const OSS_URL_SIGNATURE = 'Signature'; + //HTTP METHOD + const OSS_HTTP_GET = 'GET'; + const OSS_HTTP_PUT = 'PUT'; + const OSS_HTTP_HEAD = 'HEAD'; + const OSS_HTTP_POST = 'POST'; + const OSS_HTTP_DELETE = 'DELETE'; + const OSS_HTTP_OPTIONS = 'OPTIONS'; + //Others + const OSS_ACL = 'x-oss-acl'; + const OSS_OBJECT_ACL = 'x-oss-object-acl'; + const OSS_OBJECT_GROUP = 'x-oss-file-group'; + const OSS_MULTI_PART = 'uploads'; + const OSS_MULTI_DELETE = 'delete'; + const OSS_OBJECT_COPY_SOURCE = 'x-oss-copy-source'; + const OSS_OBJECT_COPY_SOURCE_RANGE = "x-oss-copy-source-range"; + const OSS_PROCESS = "x-oss-process"; + const OSS_CALLBACK = "x-oss-callback"; + const OSS_CALLBACK_VAR = "x-oss-callback-var"; + //Constants for STS SecurityToken + const OSS_SECURITY_TOKEN = "x-oss-security-token"; + const OSS_ACL_TYPE_PRIVATE = 'private'; + const OSS_ACL_TYPE_PUBLIC_READ = 'public-read'; + const OSS_ACL_TYPE_PUBLIC_READ_WRITE = 'public-read-write'; + const OSS_ENCODING_TYPE = "encoding-type"; + const OSS_ENCODING_TYPE_URL = "url"; + + // Domain Types + const OSS_HOST_TYPE_NORMAL = "normal";//http://bucket.oss-cn-hangzhou.aliyuncs.com/object + const OSS_HOST_TYPE_IP = "ip"; //http://1.1.1.1/bucket/object + const OSS_HOST_TYPE_SPECIAL = 'special'; //http://bucket.guizhou.gov/object + const OSS_HOST_TYPE_CNAME = "cname"; //http://mydomain.com/object + //OSS ACL array + static $OSS_ACL_TYPES = array( + self::OSS_ACL_TYPE_PRIVATE, + self::OSS_ACL_TYPE_PUBLIC_READ, + self::OSS_ACL_TYPE_PUBLIC_READ_WRITE + ); + // OssClient version information + const OSS_NAME = "aliyun-sdk-php"; + const OSS_VERSION = "2.3.0"; + const OSS_BUILD = "20180105"; + const OSS_AUTHOR = ""; + const OSS_OPTIONS_ORIGIN = 'Origin'; + const OSS_OPTIONS_REQUEST_METHOD = 'Access-Control-Request-Method'; + const OSS_OPTIONS_REQUEST_HEADERS = 'Access-Control-Request-Headers'; + + //use ssl flag + private $useSSL = false; + private $maxRetries = 3; + private $redirects = 0; + + // user's domain type. It could be one of the four: OSS_HOST_TYPE_NORMAL, OSS_HOST_TYPE_IP, OSS_HOST_TYPE_SPECIAL, OSS_HOST_TYPE_CNAME + private $hostType = self::OSS_HOST_TYPE_NORMAL; + private $requestUrl; + private $requestProxy = null; + private $accessKeyId; + private $accessKeySecret; + private $hostname; + private $securityToken; + private $enableStsInUrl = false; + private $timeout = 0; + private $connectTimeout = 0; +} diff --git a/vendor/oss-sdk/src/OSS/Result/AclResult.php b/vendor/oss-sdk/src/OSS/Result/AclResult.php new file mode 100755 index 0000000..7061ff0 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/AclResult.php @@ -0,0 +1,31 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; + +/** + * The type of the return value of getBucketAcl, it wraps the data parsed from xml. + * + * @package OSS\Result + */ +class AclResult extends Result +{ + /** + * @return string + * @throws OssException + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + if (isset($xml->AccessControlList->Grant)) { + return strval($xml->AccessControlList->Grant); + } else { + throw new OssException("xml format exception"); + } + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/AppendResult.php b/vendor/oss-sdk/src/OSS/Result/AppendResult.php new file mode 100755 index 0000000..d898d58 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/AppendResult.php @@ -0,0 +1,27 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; + +/** + * Class AppendResult + * @package OSS\Result + */ +class AppendResult extends Result +{ + /** + * Get the value of next-append-position from append's response headers + * + * @return int + * @throws OssException + */ + protected function parseDataFromResponse() + { + $header = $this->rawResponse->header; + if (isset($header["x-oss-next-append-position"])) { + return intval($header["x-oss-next-append-position"]); + } + throw new OssException("cannot get next-append-position"); + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/BodyResult.php b/vendor/oss-sdk/src/OSS/Result/BodyResult.php new file mode 100755 index 0000000..44ba15e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/BodyResult.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Result; + + +/** + * Class BodyResult + * @package OSS\Result + */ +class BodyResult extends Result +{ + /** + * @return string + */ + protected function parseDataFromResponse() + { + return empty($this->rawResponse->body) ? "" : $this->rawResponse->body; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/CallbackResult.php b/vendor/oss-sdk/src/OSS/Result/CallbackResult.php new file mode 100755 index 0000000..514e985 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/CallbackResult.php @@ -0,0 +1,21 @@ +<?php + +namespace OSS\Result; + + +/** + * Class CallbackResult + * @package OSS\Result + */ +class CallbackResult extends PutSetDeleteResult +{ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 && (int)(intval($status)) !== 203) { + return true; + } + return false; + } + +} diff --git a/vendor/oss-sdk/src/OSS/Result/CopyObjectResult.php b/vendor/oss-sdk/src/OSS/Result/CopyObjectResult.php new file mode 100755 index 0000000..498723e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/CopyObjectResult.php @@ -0,0 +1,30 @@ +<?php + +namespace OSS\Result; + + +/** + * Class CopyObjectResult + * @package OSS\Result + */ +class CopyObjectResult extends Result +{ + /** + * @return array() + */ + protected function parseDataFromResponse() + { + $body = $this->rawResponse->body; + $xml = simplexml_load_string($body); + $result = array(); + + if (isset($xml->LastModified)) { + $result[] = $xml->LastModified; + } + if (isset($xml->ETag)) { + $result[] = $xml->ETag; + } + + return $result; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/DeleteObjectsResult.php b/vendor/oss-sdk/src/OSS/Result/DeleteObjectsResult.php new file mode 100755 index 0000000..dc373b8 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/DeleteObjectsResult.php @@ -0,0 +1,27 @@ +<?php + +namespace OSS\Result; + + +/** + * Class DeleteObjectsResult + * @package OSS\Result + */ +class DeleteObjectsResult extends Result +{ + /** + * @return array() + */ + protected function parseDataFromResponse() + { + $body = $this->rawResponse->body; + $xml = simplexml_load_string($body); + $objects = array(); + + if (isset($xml->Deleted)) { + foreach($xml->Deleted as $deleteKey) + $objects[] = $deleteKey->Key; + } + return $objects; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/ExistResult.php b/vendor/oss-sdk/src/OSS/Result/ExistResult.php new file mode 100755 index 0000000..e9522d4 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ExistResult.php @@ -0,0 +1,34 @@ +<?php + +namespace OSS\Result; + +/** + * Class ExistResult checks if bucket or object exists, according to the http status in response headers. + * @package OSS\Result + */ +class ExistResult extends Result +{ + /** + * @return bool + */ + protected function parseDataFromResponse() + { + return intval($this->rawResponse->status) === 200 ? true : false; + } + + /** + * Check if the response status is OK according to the http status code. + * [200-299]: OK; [404]: Not found. It means the object or bucket is not found--it's a valid response too. + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetCnameResult.php b/vendor/oss-sdk/src/OSS/Result/GetCnameResult.php new file mode 100755 index 0000000..eed01f9 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetCnameResult.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\CnameConfig; + +class GetCnameResult extends Result +{ + /** + * @return CnameConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new CnameConfig(); + $config->parseFromXml($content); + return $config; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetCorsResult.php b/vendor/oss-sdk/src/OSS/Result/GetCorsResult.php new file mode 100755 index 0000000..8fb10ea --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetCorsResult.php @@ -0,0 +1,34 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\CorsConfig; + +class GetCorsResult extends Result +{ + /** + * @return CorsConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new CorsConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * Check if the response is OK, according to the http status. [200-299]:OK, the Cors config could be got; [404]: not found--no Cors config. + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetLifecycleResult.php b/vendor/oss-sdk/src/OSS/Result/GetLifecycleResult.php new file mode 100755 index 0000000..e0a9595 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLifecycleResult.php @@ -0,0 +1,41 @@ +<?php + +namespace OSS\Result; + + +use OSS\Model\LifecycleConfig; + +/** + * Class GetLifecycleResult + * @package OSS\Result + */ +class GetLifecycleResult extends Result +{ + /** + * Parse the LifecycleConfig object from the response + * + * @return LifecycleConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new LifecycleConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * Check if the response is OK according to the http status. + * [200-299]: OK, and the LifecycleConfig could be got; [404] The Life cycle config is not found. + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/GetLiveChannelHistoryResult.php b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelHistoryResult.php new file mode 100755 index 0000000..202a668 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelHistoryResult.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\GetLiveChannelHistory; + +class GetLiveChannelHistoryResult extends Result +{ + /** + * @return + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $channelList = new GetLiveChannelHistory(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/GetLiveChannelInfoResult.php b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelInfoResult.php new file mode 100755 index 0000000..d5a9005 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelInfoResult.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\GetLiveChannelInfo; + +class GetLiveChannelInfoResult extends Result +{ + /** + * @return + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $channelList = new GetLiveChannelInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/GetLiveChannelStatusResult.php b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelStatusResult.php new file mode 100755 index 0000000..6b8a60f --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLiveChannelStatusResult.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\GetLiveChannelStatus; + +class GetLiveChannelStatusResult extends Result +{ + /** + * @return + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $channelList = new GetLiveChannelStatus(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/GetLocationResult.php b/vendor/oss-sdk/src/OSS/Result/GetLocationResult.php new file mode 100755 index 0000000..a0c5129 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLocationResult.php @@ -0,0 +1,30 @@ +<?php +namespace OSS\Result; + +use OSS\Core\OssException; + +/** + * Class GetLocationResult getBucketLocation interface returns the result class, encapsulated + * The returned xml data is parsed + * + * @package OSS\Result + */ +class GetLocationResult extends Result +{ + + /** + * Parse data from response + * + * @return string + * @throws OssException + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + return $xml; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetLoggingResult.php b/vendor/oss-sdk/src/OSS/Result/GetLoggingResult.php new file mode 100755 index 0000000..eab8c64 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetLoggingResult.php @@ -0,0 +1,41 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\LoggingConfig; + + +/** + * Class GetLoggingResult + * @package OSS\Result + */ +class GetLoggingResult extends Result +{ + /** + * Parse LoggingConfig data + * + * @return LoggingConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new LoggingConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * Judged according to the return HTTP status code, [200-299] that is OK, get the bucket configuration interface, + * 404 is also considered a valid response + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetRefererResult.php b/vendor/oss-sdk/src/OSS/Result/GetRefererResult.php new file mode 100755 index 0000000..a8a649e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetRefererResult.php @@ -0,0 +1,41 @@ +<?php + +namespace OSS\Result; + + +use OSS\Model\RefererConfig; + +/** + * Class GetRefererResult + * @package OSS\Result + */ +class GetRefererResult extends Result +{ + /** + * Parse RefererConfig data + * + * @return RefererConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new RefererConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * Judged according to the return HTTP status code, [200-299] that is OK, get the bucket configuration interface, + * 404 is also considered a valid response + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetStorageCapacityResult.php b/vendor/oss-sdk/src/OSS/Result/GetStorageCapacityResult.php new file mode 100755 index 0000000..2f4127b --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetStorageCapacityResult.php @@ -0,0 +1,34 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; + +/** + * Class AclResult GetBucketAcl interface returns the result class, encapsulated + * The returned xml data is parsed + * + * @package OSS\Result + */ +class GetStorageCapacityResult extends Result +{ + /** + * Parse data from response + * + * @return string + * @throws OssException + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + if (empty($content)) { + throw new OssException("body is null"); + } + $xml = simplexml_load_string($content); + if (isset($xml->StorageCapacity)) { + return intval($xml->StorageCapacity); + } else { + throw new OssException("xml format exception"); + } + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/GetWebsiteResult.php b/vendor/oss-sdk/src/OSS/Result/GetWebsiteResult.php new file mode 100755 index 0000000..64d54fa --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/GetWebsiteResult.php @@ -0,0 +1,40 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\WebsiteConfig; + +/** + * Class GetWebsiteResult + * @package OSS\Result + */ +class GetWebsiteResult extends Result +{ + /** + * Parse WebsiteConfig data + * + * @return WebsiteConfig + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $config = new WebsiteConfig(); + $config->parseFromXml($content); + return $config; + } + + /** + * Judged according to the return HTTP status code, [200-299] that is OK, get the bucket configuration interface, + * 404 is also considered a valid response + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2 || (int)(intval($status)) === 404) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/HeaderResult.php b/vendor/oss-sdk/src/OSS/Result/HeaderResult.php new file mode 100755 index 0000000..1ca4d1a --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/HeaderResult.php @@ -0,0 +1,23 @@ +<?php + +namespace OSS\Result; + + +/** + * Class HeaderResult + * @package OSS\Result + * @link https://docs.aliyun.com/?spm=5176.383663.13.7.HgUIqL#/pub/oss/api-reference/object&GetObjectMeta + */ +class HeaderResult extends Result +{ + /** + * The returned ResponseCore header is used as the return data + * + * @return array + */ + protected function parseDataFromResponse() + { + return empty($this->rawResponse->header) ? array() : $this->rawResponse->header; + } + +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/InitiateMultipartUploadResult.php b/vendor/oss-sdk/src/OSS/Result/InitiateMultipartUploadResult.php new file mode 100755 index 0000000..53a15da --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/InitiateMultipartUploadResult.php @@ -0,0 +1,29 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; + + +/** + * Class initiateMultipartUploadResult + * @package OSS\Result + */ +class InitiateMultipartUploadResult extends Result +{ + /** + * Get uploadId in result and return + * + * @throws OssException + * @return string + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $xml = simplexml_load_string($content); + if (isset($xml->UploadId)) { + return strval($xml->UploadId); + } + throw new OssException("cannot get UploadId"); + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/ListBucketsResult.php b/vendor/oss-sdk/src/OSS/Result/ListBucketsResult.php new file mode 100755 index 0000000..a58fb2d --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ListBucketsResult.php @@ -0,0 +1,33 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\BucketInfo; +use OSS\Model\BucketListInfo; + +/** + * Class ListBucketsResult + * + * @package OSS\Result + */ +class ListBucketsResult extends Result +{ + /** + * @return BucketListInfo + */ + protected function parseDataFromResponse() + { + $bucketList = array(); + $content = $this->rawResponse->body; + $xml = new \SimpleXMLElement($content); + if (isset($xml->Buckets) && isset($xml->Buckets->Bucket)) { + foreach ($xml->Buckets->Bucket as $bucket) { + $bucketInfo = new BucketInfo(strval($bucket->Location), + strval($bucket->Name), + strval($bucket->CreationDate)); + $bucketList[] = $bucketInfo; + } + } + return new BucketListInfo($bucketList); + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/ListLiveChannelResult.php b/vendor/oss-sdk/src/OSS/Result/ListLiveChannelResult.php new file mode 100755 index 0000000..1a6e2a4 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ListLiveChannelResult.php @@ -0,0 +1,16 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\LiveChannelListInfo; + +class ListLiveChannelResult extends Result +{ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $channelList = new LiveChannelListInfo(); + $channelList->parseFromXml($content); + return $channelList; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/ListMultipartUploadResult.php b/vendor/oss-sdk/src/OSS/Result/ListMultipartUploadResult.php new file mode 100755 index 0000000..3220c86 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ListMultipartUploadResult.php @@ -0,0 +1,55 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssUtil; +use OSS\Model\ListMultipartUploadInfo; +use OSS\Model\UploadInfo; + + +/** + * Class ListMultipartUploadResult + * @package OSS\Result + */ +class ListMultipartUploadResult extends Result +{ + /** + * Parse the return data from the ListMultipartUpload interface + * + * @return ListMultipartUploadInfo + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $xml = simplexml_load_string($content); + + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : ""; + $keyMarker = isset($xml->KeyMarker) ? strval($xml->KeyMarker) : ""; + $keyMarker = OssUtil::decodeKey($keyMarker, $encodingType); + $uploadIdMarker = isset($xml->UploadIdMarker) ? strval($xml->UploadIdMarker) : ""; + $nextKeyMarker = isset($xml->NextKeyMarker) ? strval($xml->NextKeyMarker) : ""; + $nextKeyMarker = OssUtil::decodeKey($nextKeyMarker, $encodingType); + $nextUploadIdMarker = isset($xml->NextUploadIdMarker) ? strval($xml->NextUploadIdMarker) : ""; + $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : ""; + $delimiter = OssUtil::decodeKey($delimiter, $encodingType); + $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $maxUploads = isset($xml->MaxUploads) ? intval($xml->MaxUploads) : 0; + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $listUpload = array(); + + if (isset($xml->Upload)) { + foreach ($xml->Upload as $upload) { + $key = isset($upload->Key) ? strval($upload->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $uploadId = isset($upload->UploadId) ? strval($upload->UploadId) : ""; + $initiated = isset($upload->Initiated) ? strval($upload->Initiated) : ""; + $listUpload[] = new UploadInfo($key, $uploadId, $initiated); + } + } + return new ListMultipartUploadInfo($bucket, $keyMarker, $uploadIdMarker, + $nextKeyMarker, $nextUploadIdMarker, + $delimiter, $prefix, $maxUploads, $isTruncated, $listUpload); + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/ListObjectsResult.php b/vendor/oss-sdk/src/OSS/Result/ListObjectsResult.php new file mode 100755 index 0000000..f44c66a --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ListObjectsResult.php @@ -0,0 +1,71 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssUtil; +use OSS\Model\ObjectInfo; +use OSS\Model\ObjectListInfo; +use OSS\Model\PrefixInfo; + +/** + * Class ListObjectsResult + * @package OSS\Result + */ +class ListObjectsResult extends Result +{ + /** + * Parse the xml data returned by the ListObjects interface + * + * return ObjectListInfo + */ + protected function parseDataFromResponse() + { + $xml = new \SimpleXMLElement($this->rawResponse->body); + $encodingType = isset($xml->EncodingType) ? strval($xml->EncodingType) : ""; + $objectList = $this->parseObjectList($xml, $encodingType); + $prefixList = $this->parsePrefixList($xml, $encodingType); + $bucketName = isset($xml->Name) ? strval($xml->Name) : ""; + $prefix = isset($xml->Prefix) ? strval($xml->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $marker = isset($xml->Marker) ? strval($xml->Marker) : ""; + $marker = OssUtil::decodeKey($marker, $encodingType); + $maxKeys = isset($xml->MaxKeys) ? intval($xml->MaxKeys) : 0; + $delimiter = isset($xml->Delimiter) ? strval($xml->Delimiter) : ""; + $delimiter = OssUtil::decodeKey($delimiter, $encodingType); + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $nextMarker = isset($xml->NextMarker) ? strval($xml->NextMarker) : ""; + $nextMarker = OssUtil::decodeKey($nextMarker, $encodingType); + return new ObjectListInfo($bucketName, $prefix, $marker, $nextMarker, $maxKeys, $delimiter, $isTruncated, $objectList, $prefixList); + } + + private function parseObjectList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->Contents)) { + foreach ($xml->Contents as $content) { + $key = isset($content->Key) ? strval($content->Key) : ""; + $key = OssUtil::decodeKey($key, $encodingType); + $lastModified = isset($content->LastModified) ? strval($content->LastModified) : ""; + $eTag = isset($content->ETag) ? strval($content->ETag) : ""; + $type = isset($content->Type) ? strval($content->Type) : ""; + $size = isset($content->Size) ? intval($content->Size) : 0; + $storageClass = isset($content->StorageClass) ? strval($content->StorageClass) : ""; + $retList[] = new ObjectInfo($key, $lastModified, $eTag, $type, $size, $storageClass); + } + } + return $retList; + } + + private function parsePrefixList($xml, $encodingType) + { + $retList = array(); + if (isset($xml->CommonPrefixes)) { + foreach ($xml->CommonPrefixes as $commonPrefix) { + $prefix = isset($commonPrefix->Prefix) ? strval($commonPrefix->Prefix) : ""; + $prefix = OssUtil::decodeKey($prefix, $encodingType); + $retList[] = new PrefixInfo($prefix); + } + } + return $retList; + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/ListPartsResult.php b/vendor/oss-sdk/src/OSS/Result/ListPartsResult.php new file mode 100755 index 0000000..092d94e --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/ListPartsResult.php @@ -0,0 +1,42 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\ListPartsInfo; +use OSS\Model\PartInfo; + + +/** + * Class ListPartsResult + * @package OSS\Result + */ +class ListPartsResult extends Result +{ + /** + * Parse the xml data returned by the ListParts interface + * + * @return ListPartsInfo + */ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $xml = simplexml_load_string($content); + $bucket = isset($xml->Bucket) ? strval($xml->Bucket) : ""; + $key = isset($xml->Key) ? strval($xml->Key) : ""; + $uploadId = isset($xml->UploadId) ? strval($xml->UploadId) : ""; + $nextPartNumberMarker = isset($xml->NextPartNumberMarker) ? intval($xml->NextPartNumberMarker) : ""; + $maxParts = isset($xml->MaxParts) ? intval($xml->MaxParts) : ""; + $isTruncated = isset($xml->IsTruncated) ? strval($xml->IsTruncated) : ""; + $partList = array(); + if (isset($xml->Part)) { + foreach ($xml->Part as $part) { + $partNumber = isset($part->PartNumber) ? intval($part->PartNumber) : ""; + $lastModified = isset($part->LastModified) ? strval($part->LastModified) : ""; + $eTag = isset($part->ETag) ? strval($part->ETag) : ""; + $size = isset($part->Size) ? intval($part->Size) : ""; + $partList[] = new PartInfo($partNumber, $lastModified, $eTag, $size); + } + } + return new ListPartsInfo($bucket, $key, $uploadId, $nextPartNumberMarker, $maxParts, $isTruncated, $partList); + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/PutLiveChannelResult.php b/vendor/oss-sdk/src/OSS/Result/PutLiveChannelResult.php new file mode 100755 index 0000000..dcac86b --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/PutLiveChannelResult.php @@ -0,0 +1,16 @@ +<?php + +namespace OSS\Result; + +use OSS\Model\LiveChannelInfo; + +class PutLiveChannelResult extends Result +{ + protected function parseDataFromResponse() + { + $content = $this->rawResponse->body; + $channel = new LiveChannelInfo(); + $channel->parseFromXml($content); + return $channel; + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/PutSetDeleteResult.php b/vendor/oss-sdk/src/OSS/Result/PutSetDeleteResult.php new file mode 100755 index 0000000..97af003 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/PutSetDeleteResult.php @@ -0,0 +1,20 @@ +<?php + +namespace OSS\Result; + + +/** + * Class PutSetDeleteResult + * @package OSS\Result + */ +class PutSetDeleteResult extends Result +{ + /** + * @return array() + */ + protected function parseDataFromResponse() + { + $body = array('body' => $this->rawResponse->body); + return array_merge($this->rawResponse->header, $body); + } +} diff --git a/vendor/oss-sdk/src/OSS/Result/Result.php b/vendor/oss-sdk/src/OSS/Result/Result.php new file mode 100755 index 0000000..e5d83d3 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/Result.php @@ -0,0 +1,175 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; +use OSS\Http\ResponseCore; + + +/** + * Class Result, The result class of The operation of the base class, different requests in dealing with the return of data have different logic, + * The specific parsing logic postponed to subclass implementation + * + * @package OSS\Model + */ +abstract class Result +{ + /** + * Result constructor. + * @param $response ResponseCore + * @throws OssException + */ + public function __construct($response) + { + if ($response === null) { + throw new OssException("raw response is null"); + } + $this->rawResponse = $response; + $this->parseResponse(); + } + + /** + * Get requestId + * + * @return string + */ + public function getRequestId() + { + if (isset($this->rawResponse) && + isset($this->rawResponse->header) && + isset($this->rawResponse->header['x-oss-request-id']) + ) { + return $this->rawResponse->header['x-oss-request-id']; + } else { + return ''; + } + } + + /** + * Get the returned data, different request returns the data format is different + * + * $return mixed + */ + public function getData() + { + return $this->parsedData; + } + + /** + * Subclass implementation, different requests return data has different analytical logic, implemented by subclasses + * + * @return mixed + */ + abstract protected function parseDataFromResponse(); + + /** + * Whether the operation is successful + * + * @return mixed + */ + public function isOK() + { + return $this->isOk; + } + + /** + * @throws OssException + */ + public function parseResponse() + { + $this->isOk = $this->isResponseOk(); + if ($this->isOk) { + $this->parsedData = $this->parseDataFromResponse(); + } else { + $httpStatus = strval($this->rawResponse->status); + $requestId = strval($this->getRequestId()); + $code = $this->retrieveErrorCode($this->rawResponse->body); + $message = $this->retrieveErrorMessage($this->rawResponse->body); + $body = $this->rawResponse->body; + + $details = array( + 'status' => $httpStatus, + 'request-id' => $requestId, + 'code' => $code, + 'message' => $message, + 'body' => $body + ); + throw new OssException($details); + } + } + + /** + * Try to get the error message from body + * + * @param $body + * @return string + */ + private function retrieveErrorMessage($body) + { + if (empty($body) || false === strpos($body, '<?xml')) { + return ''; + } + $xml = simplexml_load_string($body); + if (isset($xml->Message)) { + return strval($xml->Message); + } + return ''; + } + + /** + * Try to get the error Code from body + * + * @param $body + * @return string + */ + private function retrieveErrorCode($body) + { + if (empty($body) || false === strpos($body, '<?xml')) { + return ''; + } + $xml = simplexml_load_string($body); + if (isset($xml->Code)) { + return strval($xml->Code); + } + return ''; + } + + /** + * Judging from the return http status code, [200-299] that is OK + * + * @return bool + */ + protected function isResponseOk() + { + $status = $this->rawResponse->status; + if ((int)(intval($status) / 100) == 2) { + return true; + } + return false; + } + + /** + * Return the original return data + * + * @return ResponseCore + */ + public function getRawResponse() + { + return $this->rawResponse; + } + + /** + * Indicate whether the request is successful + */ + protected $isOk = false; + /** + * Data parsed by subclasses + */ + protected $parsedData = null; + /** + * Store the original Response returned by the auth function + * + * @var ResponseCore + */ + protected $rawResponse; +} \ No newline at end of file diff --git a/vendor/oss-sdk/src/OSS/Result/SymlinkResult.php b/vendor/oss-sdk/src/OSS/Result/SymlinkResult.php new file mode 100755 index 0000000..9c6d861 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/SymlinkResult.php @@ -0,0 +1,24 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; +use OSS\OssClient; + +/** + * + * @package OSS\Result + */ +class SymlinkResult extends Result +{ + /** + * @return string + * @throws OssException + */ + protected function parseDataFromResponse() + { + $this->rawResponse->header[OssClient::OSS_SYMLINK_TARGET] = rawurldecode($this->rawResponse->header[OssClient::OSS_SYMLINK_TARGET]); + return $this->rawResponse->header; + } +} + diff --git a/vendor/oss-sdk/src/OSS/Result/UploadPartResult.php b/vendor/oss-sdk/src/OSS/Result/UploadPartResult.php new file mode 100755 index 0000000..c6b66d4 --- /dev/null +++ b/vendor/oss-sdk/src/OSS/Result/UploadPartResult.php @@ -0,0 +1,28 @@ +<?php + +namespace OSS\Result; + +use OSS\Core\OssException; + +/** + * Class UploadPartResult + * @package OSS\Result + */ +class UploadPartResult extends Result +{ + /** + * 结果中part的ETag + * + * @return string + * @throws OssException + */ + protected function parseDataFromResponse() + { + $header = $this->rawResponse->header; + if (isset($header["etag"])) { + return $header["etag"]; + } + throw new OssException("cannot get ETag"); + + } +} \ No newline at end of file diff --git a/vendor/oss-sdk/tests/OSS/Tests/AclResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/AclResultTest.php new file mode 100755 index 0000000..12f4b1a --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/AclResultTest.php @@ -0,0 +1,59 @@ +<?php + +namespace OSS\Tests; + +use OSS\Result\AclResult; +use OSS\Core\OssException; +use OSS\Http\ResponseCore; + +class AclResultTest extends \PHPUnit_Framework_TestCase +{ + + private $validXml = <<<BBBB +<?xml version="1.0" ?> +<AccessControlPolicy> + <Owner> + <ID>00220120222</ID> + <DisplayName>user_example</DisplayName> + </Owner> + <AccessControlList> + <Grant>public-read</Grant> + </AccessControlList> +</AccessControlPolicy> +BBBB; + + private $invalidXml = <<<BBBB +<?xml version="1.0" ?> +<AccessControlPolicy> +</AccessControlPolicy> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new AclResult($response); + $this->assertEquals("public-read", $result->getData()); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), "", 200); + try { + new AclResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('body is null', $e->getMessage()); + } + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + try { + new AclResult($response); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals("xml format exception", $e->getMessage()); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/BodyResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/BodyResultTest.php new file mode 100755 index 0000000..af13d4d --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/BodyResultTest.php @@ -0,0 +1,26 @@ +<?php + +namespace OSS\Tests; + +use OSS\Http\ResponseCore; +use OSS\Result\BodyResult; + + +class BodyResultTest extends \PHPUnit_Framework_TestCase +{ + public function testParseValid200() + { + $response = new ResponseCore(array(), "hi", 200); + $result = new BodyResult($response); + $this->assertTrue($result->isOK()); + $this->assertEquals($result->getData(), "hi"); + } + + public function testParseInvalid404() + { + $response = new ResponseCore(array(), null, 200); + $result = new BodyResult($response); + $this->assertTrue($result->isOK()); + $this->assertEquals($result->getData(), ""); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/BucketCnameTest.php b/vendor/oss-sdk/tests/OSS/Tests/BucketCnameTest.php new file mode 100755 index 0000000..87c9e54 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/BucketCnameTest.php @@ -0,0 +1,77 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +use OSS\Model\CnameConfig; + +class BucketCnameTest extends \PHPUnit_Framework_TestCase +{ + private $bucketName; + private $client; + + public function setUp() + { + $this->client = Common::getOssClient(); + $this->bucketName = 'php-sdk-test-bucket-' . strval(rand(0, 10000)); + $this->client->createBucket($this->bucketName); + } + + public function tearDown() + { + $this->client->deleteBucket($this->bucketName); + } + + public function testBucketWithoutCname() + { + $cnameConfig = $this->client->getBucketCname($this->bucketName); + $this->assertEquals(0, count($cnameConfig->getCnames())); + } + + public function testAddCname() + { + $this->client->addBucketCname($this->bucketName, 'www.baidu.com'); + $this->client->addBucketCname($this->bucketName, 'www.qq.com'); + + $ret = $this->client->getBucketCname($this->bucketName); + $this->assertEquals(2, count($ret->getCnames())); + + // add another 2 cnames + $this->client->addBucketCname($this->bucketName, 'www.sina.com.cn'); + $this->client->addBucketCname($this->bucketName, 'www.iqiyi.com'); + + $ret = $this->client->getBucketCname($this->bucketName); + $cnames = $ret->getCnames(); + $cnameList = array(); + + foreach ($cnames as $c) { + $cnameList[] = $c['Domain']; + } + $should = array( + 'www.baidu.com', + 'www.qq.com', + 'www.sina.com.cn', + 'www.iqiyi.com' + ); + $this->assertEquals(4, count($cnames)); + $this->assertEquals(sort($should), sort($cnameList)); + } + + public function testDeleteCname() + { + $this->client->addBucketCname($this->bucketName, 'www.baidu.com'); + $this->client->addBucketCname($this->bucketName, 'www.qq.com'); + + $ret = $this->client->getBucketCname($this->bucketName); + $this->assertEquals(2, count($ret->getCnames())); + + // delete one cname + $this->client->deleteBucketCname($this->bucketName, 'www.baidu.com'); + + $ret = $this->client->getBucketCname($this->bucketName); + $this->assertEquals(1, count($ret->getCnames())); + $cnames = $ret->getCnames(); + $this->assertEquals('www.qq.com', $cnames[0]['Domain']); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/BucketInfoTest.php b/vendor/oss-sdk/tests/OSS/Tests/BucketInfoTest.php new file mode 100755 index 0000000..80fa25c --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/BucketInfoTest.php @@ -0,0 +1,21 @@ +<?php + +namespace OSS\Tests; + +use OSS\Model\BucketInfo; + +/** + * Class BucketInfoTest + * @package OSS\Tests + */ +class BucketInfoTest extends \PHPUnit_Framework_TestCase +{ + public function testConstruct() + { + $bucketInfo = new BucketInfo('cn-beijing', 'name', 'today'); + $this->assertNotNull($bucketInfo); + $this->assertEquals('cn-beijing', $bucketInfo->getLocation()); + $this->assertEquals('name', $bucketInfo->getName()); + $this->assertEquals('today', $bucketInfo->getCreateDate()); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/BucketLiveChannelTest.php b/vendor/oss-sdk/tests/OSS/Tests/BucketLiveChannelTest.php new file mode 100755 index 0000000..bed68b0 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/BucketLiveChannelTest.php @@ -0,0 +1,283 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +use OSS\Model\LiveChannelConfig; +use OSS\Core\OssException; + +class BucketLiveChannelTest extends \PHPUnit_Framework_TestCase +{ + private $bucketName; + private $client; + + public function setUp() + { + $this->client = Common::getOssClient(); + $this->bucketName = 'php-sdk-test-rtmp-bucket-name-' . strval(rand(0, 10000)); + $this->client->createBucket($this->bucketName); + Common::waitMetaSync(); + } + + public function tearDown() + { + ////to delete created bucket + //1. delele live channel + $list = $this->client->listBucketLiveChannels($this->bucketName); + if (count($list->getChannelList()) != 0) + { + foreach($list->getChannelList() as $list) + { + $this->client->deleteBucketLiveChannel($this->bucketName, $list->getName()); + } + } + //2. delete exsited object + $prefix = 'live-test/'; + $delimiter = '/'; + $nextMarker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $nextMarker, + ); + + try { + $listObjectInfo = $this->client->listObjects($this->bucketName, $options); + } catch (OssException $e) { + printf($e->getMessage() . "\n"); + return; + } + + $objectList = $listObjectInfo->getObjectList(); // 文件列表 + if (!empty($objectList)) + { + foreach($objectList as $objectInfo) + $this->client->deleteObject($this->bucketName, $objectInfo->getKey()); + } + //3. delete the bucket + $this->client->deleteBucket($this->bucketName); + } + + public function testPutLiveChannel() + { + $config = new LiveChannelConfig(array( + 'description' => 'live channel 1', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $info = $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + + $this->assertEquals('live-1', $info->getName()); + $this->assertEquals('live channel 1', $info->getDescription()); + $this->assertEquals(1, count($info->getPublishUrls())); + $this->assertEquals(1, count($info->getPlayUrls())); + } + + public function testPutLiveChannelWithDefaultParams() + { + $config = new LiveChannelConfig(array( + 'description' => 'live channel 1', + 'type' => 'HLS', + )); + $info = $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + + $this->assertEquals('live-1', $info->getName()); + $this->assertEquals('live channel 1', $info->getDescription()); + $this->assertEquals(1, count($info->getPublishUrls())); + $this->assertEquals(1, count($info->getPlayUrls())); + } + + public function testListLiveChannels() + { + $config = new LiveChannelConfig(array( + 'description' => 'live channel 1', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, 'live-1', $config); + + $config = new LiveChannelConfig(array( + 'description' => 'live channel 2', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, 'live-2', $config); + + $list = $this->client->listBucketLiveChannels($this->bucketName); + + $this->assertEquals($this->bucketName, $list->getBucketName()); + $this->assertEquals(false, $list->getIsTruncated()); + $channels = $list->getChannelList(); + $this->assertEquals(2, count($channels)); + + $chan1 = $channels[0]; + $this->assertEquals('live-1', $chan1->getName()); + $this->assertEquals('live channel 1', $chan1->getDescription()); + $this->assertEquals(1, count($chan1->getPublishUrls())); + $this->assertEquals(1, count($chan1->getPlayUrls())); + + $chan2 = $channels[1]; + $this->assertEquals('live-2', $chan2->getName()); + $this->assertEquals('live channel 2', $chan2->getDescription()); + $this->assertEquals(1, count($chan2->getPublishUrls())); + $this->assertEquals(1, count($chan2->getPlayUrls())); + + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => 'live-', + 'marker' => 'live-1', + 'max-keys' => 10 + )); + $channels = $list->getChannelList(); + $this->assertEquals(1, count($channels)); + $chan2 = $channels[0]; + $this->assertEquals('live-2', $chan2->getName()); + $this->assertEquals('live channel 2', $chan2->getDescription()); + $this->assertEquals(1, count($chan2->getPublishUrls())); + $this->assertEquals(1, count($chan2->getPlayUrls())); + + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-1'); + $this->client->deleteBucketLiveChannel($this->bucketName, 'live-2'); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => 'live-' + )); + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testDeleteLiveChannel() + { + $channelName = 'live-to-delete'; + $config = new LiveChannelConfig(array( + 'description' => 'live channel to delete', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testSignRtmpUrl() + { + $channelName = '90475'; + $bucket = 'douyu'; + $now = time(); + $url = $this->client->signRtmpUrl($bucket, $channelName, 900, array( + 'params' => array( + 'playlistName' => 'playlist.m3u8' + ) + )); + + $ret = parse_url($url); + $this->assertEquals('rtmp', $ret['scheme']); + parse_str($ret['query'], $query); + + $this->assertTrue(isset($query['OSSAccessKeyId'])); + $this->assertTrue(isset($query['Signature'])); + $this->assertTrue(intval($query['Expires']) - ($now + 900) < 3); + $this->assertEquals('playlist.m3u8', $query['playlistName']); + } + + public function testLiveChannelInfo() + { + $channelName = 'live-to-put-status'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('enabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + $this->assertEquals(0, count($list->getChannelList())); + } + + public function testPutLiveChannelStatus() + { + $channelName = 'live-to-put-status'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('enabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + $status = $this->client->getLiveChannelStatus($this->bucketName, $channelName); + $this->assertEquals('Idle', $status->getStatus()); + + + $resp = $this->client->putLiveChannelStatus($this->bucketName, $channelName, "disabled"); + $info = $this->client->getLiveChannelInfo($this->bucketName, $channelName); + $this->assertEquals('test live channel info', $info->getDescription()); + $this->assertEquals('disabled', $info->getStatus()); + $this->assertEquals('HLS', $info->getType()); + $this->assertEquals(10, $info->getFragDuration()); + $this->assertEquals(5, $info->getFragCount()); + $this->assertEquals('playlist.m3u8', $info->getPlayListName()); + + $status = $this->client->getLiveChannelStatus($this->bucketName, $channelName); + //getLiveChannelInfo + $this->assertEquals('Disabled', $status->getStatus()); + + $this->client->deleteBucketLiveChannel($this->bucketName, $channelName); + $list = $this->client->listBucketLiveChannels($this->bucketName, array( + 'prefix' => $channelName + )); + $this->assertEquals(0, count($list->getChannelList())); + + } + public function testLiveChannelHistory() + { + $channelName = 'live-test-history'; + $config = new LiveChannelConfig(array( + 'description' => 'test live channel info', + 'type' => 'HLS', + 'fragDuration' => 10, + 'fragCount' => 5, + 'playListName' => 'hello.m3u8' + )); + $this->client->putBucketLiveChannel($this->bucketName, $channelName, $config); + + $history = $this->client->getLiveChannelHistory($this->bucketName, $channelName); + $this->assertEquals(0, count($history->getLiveRecordList())); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/CallbackTest.php b/vendor/oss-sdk/tests/OSS/Tests/CallbackTest.php new file mode 100755 index 0000000..da482e0 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/CallbackTest.php @@ -0,0 +1,297 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class CallbackTest extends TestOssClientBase +{ + public function testMultipartUploadCallbackNormal() + { + $object = "multipart-callback-test.txt"; + $copiedObject = "multipart-callback-test.txt.copied"; + $this->ossClient->putObject($this->bucket, $copiedObject, file_get_contents(__FILE__)); + + /** + * step 1. Initialize a block upload event, which is initialized to upload Multipart, get the upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. uploadPartCopy + */ + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $copiedObject, $this->bucket, $object, $copyId, $upload_id); + $upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + + $json = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}", + "callbackBodyType":"application/json" + }'; + + $var = + '{ + "x:var1":"value1", + "x:var2":"值2" + }'; + $options = array(OssClient::OSS_CALLBACK => $json, + OssClient::OSS_CALLBACK_VAR => $var + ); + + try { + $result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts, $options); + $this->assertEquals("200", $result['info']['http_code']); + $this->assertEquals("{\"Status\":\"OK\"}", $result['body']); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testMultipartUploadCallbackFailed() + { + $object = "multipart-callback-test.txt"; + $copiedObject = "multipart-callback-test.txt.copied"; + $this->ossClient->putObject($this->bucket, $copiedObject, file_get_contents(__FILE__)); + + /** + * step 1. Initialize a block upload event, which is initialized to upload Multipart, get the upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. uploadPartCopy + */ + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $copiedObject, $this->bucket, $object, $copyId, $upload_id); + $upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + + $json = + '{ + "callbackUrl":"www.baidu.com", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}", + "callbackBodyType":"application/json" + }'; + + $var = + '{ + "x:var1":"value1", + "x:var2":"值2" + }'; + $options = array(OssClient::OSS_CALLBACK => $json, + OssClient::OSS_CALLBACK_VAR => $var + ); + + try { + $result = $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts, $options); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + $this->assertEquals("203", $e->getHTTPStatus()); + } + + } + + public function testPutObjectCallbackNormal() + { + //json + { + $json = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size}}", + "callbackBodyType":"application/json" + }'; + $options = array(OssClient::OSS_CALLBACK => $json); + $this->putObjectCallbackOk($options, "200"); + } + //url + { + $url = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}", + "callbackBodyType":"application/x-www-form-urlencoded" + }'; + $options = array(OssClient::OSS_CALLBACK => $url); + $this->putObjectCallbackOk($options, "200"); + } + // Unspecified typre + { + $url = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}" + }'; + $options = array(OssClient::OSS_CALLBACK => $url); + $this->putObjectCallbackOk($options, "200"); + } + //json and body is chinese + { + $json = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\" 春水碧于天,画船听雨眠。\":\"垆边人似月,皓腕凝霜雪。\"}", + "callbackBodyType":"application/json" + }'; + $options = array(OssClient::OSS_CALLBACK => $json); + $this->putObjectCallbackOk($options, "200"); + } + //url and body is chinese + { + $url = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"春水碧于天,画船听雨眠。垆边人似月,皓腕凝霜雪", + "callbackBodyType":"application/x-www-form-urlencoded" + }'; + $options = array(OssClient::OSS_CALLBACK => $url); + $this->putObjectCallbackOk($options, "200"); + } + //json and add callback_var + { + $json = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size},\"x:var1\":${x:var1},\"x:var2\":${x:var2}}", + "callbackBodyType":"application/json" + }'; + + $var = + '{ + "x:var1":"value1", + "x:var2":"aliyun.com" + }'; + $options = array(OssClient::OSS_CALLBACK => $json, + OssClient::OSS_CALLBACK_VAR => $var + ); + $this->putObjectCallbackOk($options, "200"); + } + //url and add callback_var + { + $url = + '{ + "callbackUrl":"oss-demo.aliyuncs.com:23450", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var1}&my_var2=${x:var2}", + "callbackBodyType":"application/x-www-form-urlencoded" + }'; + $var = + '{ + "x:var1":"value1凌波不过横塘路,但目送,芳", + "x:var2":"值2" + }'; + $options = array(OssClient::OSS_CALLBACK => $url, + OssClient::OSS_CALLBACK_VAR => $var + ); + $this->putObjectCallbackOk($options, "200"); + } + + } + + public function testPutCallbackWithCallbackFailed() + { + { + $json = + '{ + "callbackUrl":"http://www.baidu.com", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"{\"mimeType\":${mimeType},\"size\":${size}}", + "callbackBodyType":"application/json" + }'; + $options = array(OssClient::OSS_CALLBACK => $json); + $this->putObjectCallbackFailed($options, "203"); + } + + { + $url = + '{ + "callbackUrl":"http://www.baidu.com", + "callbackHost":"oss-cn-hangzhou.aliyuncs.com", + "callbackBody":"bucket=${bucket}&object=${object}&etag=${etag}&size=${size}&mimeType=${mimeType}&imageInfo.height=${imageInfo.height}&imageInfo.width=${imageInfo.width}&imageInfo.format=${imageInfo.format}&my_var1=${x:var1}&my_var2=${x:var2}", + "callbackBodyType":"application/x-www-form-urlencoded" + }'; + $options = array(OssClient::OSS_CALLBACK => $url); + $this->putObjectCallbackFailed($options, "203"); + } + + } + + private function putObjectCallbackOk($options, $status) + { + $object = "oss-php-sdk-callback-test.txt"; + $content = file_get_contents(__FILE__); + try { + $result = $this->ossClient->putObject($this->bucket, $object, $content, $options); + $this->assertEquals($status, $result['info']['http_code']); + $this->assertEquals("{\"Status\":\"OK\"}", $result['body']); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + private function putObjectCallbackFailed($options, $status) + { + $object = "oss-php-sdk-callback-test.txt"; + $content = file_get_contents(__FILE__); + try { + $result = $this->ossClient->putObject($this->bucket, $object, $content, $options); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals($status, $e->getHTTPStatus()); + $this->assertTrue(true); + } + } + + public function setUp() + { + parent::setUp(); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/CnameConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/CnameConfigTest.php new file mode 100755 index 0000000..e3c1ce9 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/CnameConfigTest.php @@ -0,0 +1,77 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Model\CnameConfig; +use OSS\Core\OssException; + +class CnameConfigTest extends \PHPUnit_Framework_TestCase +{ + private $xml1 = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<BucketCnameConfiguration> + <Cname> + <Domain>www.foo.com</Domain> + <Status>enabled</Status> + <LastModified>20150101</LastModified> + </Cname> + <Cname> + <Domain>bar.com</Domain> + <Status>disabled</Status> + <LastModified>20160101</LastModified> + </Cname> +</BucketCnameConfiguration> +BBBB; + + public function testFromXml() + { + $cnameConfig = new CnameConfig(); + $cnameConfig->parseFromXml($this->xml1); + + $cnames = $cnameConfig->getCnames(); + $this->assertEquals(2, count($cnames)); + $this->assertEquals('www.foo.com', $cnames[0]['Domain']); + $this->assertEquals('enabled', $cnames[0]['Status']); + $this->assertEquals('20150101', $cnames[0]['LastModified']); + + $this->assertEquals('bar.com', $cnames[1]['Domain']); + $this->assertEquals('disabled', $cnames[1]['Status']); + $this->assertEquals('20160101', $cnames[1]['LastModified']); + } + + public function testToXml() + { + $cnameConfig = new CnameConfig(); + $cnameConfig->addCname('www.foo.com'); + $cnameConfig->addCname('bar.com'); + + $xml = $cnameConfig->serializeToXml(); + $comp = new CnameConfig(); + $comp->parseFromXml($xml); + + $cnames1 = $cnameConfig->getCnames(); + $cnames2 = $comp->getCnames(); + + $this->assertEquals(count($cnames1), count($cnames2)); + $this->assertEquals(count($cnames1[0]), count($cnames2[0])); + $this->assertEquals(1, count($cnames1[0])); + $this->assertEquals($cnames1[0]['Domain'], $cnames2[0]['Domain']); + } + + public function testCnameNumberLimit() + { + $cnameConfig = new CnameConfig(); + for ($i = 0; $i < CnameConfig::OSS_MAX_RULES; $i += 1) { + $cnameConfig->addCname(strval($i) . '.foo.com'); + } + try { + $cnameConfig->addCname('www.foo.com'); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals( + $e->getMessage(), + "num of cname in the config exceeds self::OSS_MAX_RULES: " . strval(CnameConfig::OSS_MAX_RULES)); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/Common.php b/vendor/oss-sdk/tests/OSS/Tests/Common.php new file mode 100755 index 0000000..4e0a466 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/Common.php @@ -0,0 +1,70 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/../../../autoload.php'; + +use OSS\OssClient; +use OSS\Core\OssException; + +/** + * Class Common + * + * Sample program [Samples / *. Php] Common class, used to obtain OssClient instance and other public methods + */ +class Common +{ + /** + * According to the Config configuration, get an OssClient instance + * + * @return OssClient An OssClient instance + */ + public static function getOssClient() + { + try { + $ossClient = new OssClient( + getenv('OSS_ACCESS_KEY_ID'), + getenv('OSS_ACCESS_KEY_SECRET'), + getenv('OSS_ENDPOINT'), false); + } catch (OssException $e) { + printf(__FUNCTION__ . "creating OssClient instance: FAILED\n"); + printf($e->getMessage() . "\n"); + return null; + } + return $ossClient; + } + + public static function getBucketName() + { + return getenv('OSS_BUCKET'); + } + + /** + * Tool method, create a bucket + */ + public static function createBucket() + { + $ossClient = self::getOssClient(); + if (is_null($ossClient)) exit(1); + $bucket = self::getBucketName(); + $acl = OssClient::OSS_ACL_TYPE_PUBLIC_READ; + try { + $ossClient->createBucket($bucket, $acl); + } catch (OssException $e) { + printf(__FUNCTION__ . ": FAILED\n"); + printf($e->getMessage() . "\n"); + return; + } + print(__FUNCTION__ . ": OK" . "\n"); + } + + /** + * Wait for bucket meta sync + */ + public static function waitMetaSync() + { + if (getenv('TRAVIS')) { + sleep(10); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ContentTypeTest.php b/vendor/oss-sdk/tests/OSS/Tests/ContentTypeTest.php new file mode 100755 index 0000000..606c810 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ContentTypeTest.php @@ -0,0 +1,133 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +class ContentTypeTest extends \PHPUnit_Framework_TestCase +{ + private function runCmd($cmd) + { + $output = array(); + $status = 0; + exec($cmd . ' 2>/dev/null', $output, $status); + + $this->assertEquals(0, $status); + } + + private function getContentType($bucket, $object) + { + $client = Common::getOssClient(); + $headers = $client->getObjectMeta($bucket, $object); + return $headers['content-type']; + } + + public function testByFileName() + { + $client = Common::getOssClient(); + $bucket = Common::getBucketName(); + + $file = '/tmp/x.html'; + $object = 'test/x'; + $this->runCmd('touch ' . $file); + + $client->uploadFile($bucket, $object, $file); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('text/html', $type); + + $file = '/tmp/x.json'; + $object = 'test/y'; + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); + + $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('application/json', $type); + } + + public function testByObjectKey() + { + $client = Common::getOssClient(); + $bucket = Common::getBucketName(); + + $object = "test/x.txt"; + $client->putObject($bucket, $object, "hello world"); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('text/plain', $type); + + $file = '/tmp/x.html'; + $object = 'test/x.txt'; + $this->runCmd('touch ' . $file); + + $client->uploadFile($bucket, $object, $file); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('text/html', $type); + + $file = '/tmp/x.none'; + $object = 'test/x.txt'; + $this->runCmd('touch ' . $file); + + $client->uploadFile($bucket, $object, $file); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('text/plain', $type); + + $file = '/tmp/x.mp3'; + $object = 'test/y.json'; + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); + + $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('audio/mpeg', $type); + + $file = '/tmp/x.none'; + $object = 'test/y.json'; + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); + + $client->multiuploadFile($bucket, $object, $file, array('partSize' => 100)); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('application/json', $type); + } + + public function testByUser() + { + $client = Common::getOssClient(); + $bucket = Common::getBucketName(); + + $object = "test/x.txt"; + $client->putObject($bucket, $object, "hello world", array( + 'Content-Type' => 'text/html' + )); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('text/html', $type); + + $file = '/tmp/x.html'; + $object = 'test/x'; + $this->runCmd('touch ' . $file); + + $client->uploadFile($bucket, $object, $file, array( + 'Content-Type' => 'application/json' + )); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('application/json', $type); + + $file = '/tmp/x.json'; + $object = 'test/y'; + $this->runCmd('dd if=/dev/urandom of=' . $file . ' bs=1024 count=100'); + + $client->multiuploadFile($bucket, $object, $file, array( + 'partSize' => 100, + 'Content-Type' => 'audio/mpeg' + )); + $type = $this->getContentType($bucket, $object); + + $this->assertEquals('audio/mpeg', $type); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/CopyObjectResult.php b/vendor/oss-sdk/tests/OSS/Tests/CopyObjectResult.php new file mode 100755 index 0000000..171d4c8 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/CopyObjectResult.php @@ -0,0 +1,52 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Http\ResponseCore; +use OSS\Result\CopyObjectResult; + +class CopyObjectResultTest extends \PHPUnit_Framework_TestCase +{ + private $body = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<CopyObjectResult> + <LastModified>Fri, 24 Feb 2012 07:18:48 GMT</LastModified> + <ETag>"5B3C1A2E053D763E1B002CC607C5A0FE"</ETag> +</CopyObjectResult> +BBBB; + + public function testNullResponse() + { + $response = null; + try { + new CopyObjectResult($response); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('raw response is null', $e->getMessage()); + } + } + + public function testOkResponse() + { + $header= array(); + $response = new ResponseCore($header, $this->body, 200); + $result = new CopyObjectResult($response); + $data = $result->getData(); + $this->assertTrue($result->isOK()); + $this->assertEquals("Fri, 24 Feb 2012 07:18:48 GMT", $data[0]); + $this->assertEquals("\"5B3C1A2E053D763E1B002CC607C5A0FE\"", $data[1]); + } + + public function testFailResponse() + { + $response = new ResponseCore(array(), "", 404); + try { + new CopyObjectResult($response); + $this->assertFalse(true); + } catch (OssException $e) { + + } + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/CorsConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/CorsConfigTest.php new file mode 100755 index 0000000..ddc4d3a --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/CorsConfigTest.php @@ -0,0 +1,140 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Model\CorsConfig; +use OSS\Model\CorsRule; +use OSS\Core\OssException; + +class CorsConfigTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<CORSConfiguration> +<CORSRule> +<AllowedOrigin>http://www.b.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedMethod>GET</AllowedMethod> +<AllowedMethod>PUT</AllowedMethod> +<AllowedMethod>POST</AllowedMethod> +<AllowedHeader>x-oss-test</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test3</AllowedHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test2</ExposeHeader> +<MaxAgeSeconds>10</MaxAgeSeconds> +</CORSRule> +<CORSRule> +<AllowedOrigin>http://www.b.com</AllowedOrigin> +<AllowedMethod>GET</AllowedMethod> +<AllowedHeader>x-oss-test</AllowedHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<MaxAgeSeconds>110</MaxAgeSeconds> +</CORSRule> +</CORSConfiguration> +BBBB; + + private $validXml2 = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<CORSConfiguration> +<CORSRule> +<AllowedOrigin>http://www.b.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedMethod>GET</AllowedMethod> +<AllowedMethod>PUT</AllowedMethod> +<AllowedMethod>POST</AllowedMethod> +<AllowedHeader>x-oss-test</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test3</AllowedHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test2</ExposeHeader> +<MaxAgeSeconds>10</MaxAgeSeconds> +</CORSRule> +</CORSConfiguration> +BBBB; + + public function testParseValidXml() + { + $corsConfig = new CorsConfig(); + $corsConfig->parseFromXml($this->validXml); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($corsConfig->serializeToXml())); + $this->assertNotNull($corsConfig->getRules()); + $rules = $corsConfig->getRules(); + $this->assertNotNull($rules[0]->getAllowedHeaders()); + $this->assertNotNull($rules[0]->getAllowedMethods()); + $this->assertNotNull($rules[0]->getAllowedOrigins()); + $this->assertNotNull($rules[0]->getExposeHeaders()); + $this->assertNotNull($rules[0]->getMaxAgeSeconds()); + } + + public function testParseValidXml2() + { + $corsConfig = new CorsConfig(); + $corsConfig->parseFromXml($this->validXml2); + $this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml($corsConfig->serializeToXml())); + } + + public function testCreateCorsConfigFromMoreThan10Rules() + { + $corsConfig = new CorsConfig(); + $rule = new CorsRule(); + for ($i = 0; $i < CorsConfig::OSS_MAX_RULES; $i += 1) { + $corsConfig->addRule($rule); + } + try { + $corsConfig->addRule($rule); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals($e->getMessage(), "num of rules in the config exceeds self::OSS_MAX_RULES: " . strval(CorsConfig::OSS_MAX_RULES)); + } + } + + public function testCreateCorsConfigParamAbsent() + { + $corsConfig = new CorsConfig(); + $rule = new CorsRule(); + $corsConfig->addRule($rule); + + try { + $xml = $corsConfig->serializeToXml(); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals($e->getMessage(), "maxAgeSeconds is not set in the Rule"); + } + } + + public function testCreateCorsConfigFromScratch() + { + $corsConfig = new CorsConfig(); + $rule = new CorsRule(); + $rule->addAllowedHeader("x-oss-test"); + $rule->addAllowedHeader("x-oss-test2"); + $rule->addAllowedHeader("x-oss-test2"); + $rule->addAllowedHeader("x-oss-test3"); + $rule->addAllowedOrigin("http://www.b.com"); + $rule->addAllowedOrigin("http://www.a.com"); + $rule->addAllowedOrigin("http://www.a.com"); + $rule->addAllowedMethod("GET"); + $rule->addAllowedMethod("PUT"); + $rule->addAllowedMethod("POST"); + $rule->addExposeHeader("x-oss-test1"); + $rule->addExposeHeader("x-oss-test1"); + $rule->addExposeHeader("x-oss-test2"); + $rule->setMaxAgeSeconds(10); + $corsConfig->addRule($rule); + $this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml($corsConfig->serializeToXml())); + $this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml(strval($corsConfig))); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ExistResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/ExistResultTest.php new file mode 100755 index 0000000..e1b4e81 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ExistResultTest.php @@ -0,0 +1,38 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Result\ExistResult; +use OSS\Http\ResponseCore; +use OSS\Core\OssException; + +class ExistResultTest extends \PHPUnit_Framework_TestCase +{ + public function testParseValid200() + { + $response = new ResponseCore(array(), "", 200); + $result = new ExistResult($response); + $this->assertTrue($result->isOK()); + $this->assertEquals($result->getData(), true); + } + + public function testParseInvalid404() + { + $response = new ResponseCore(array(), "", 404); + $result = new ExistResult($response); + $this->assertTrue($result->isOK()); + $this->assertEquals($result->getData(), false); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), "", 300); + try { + new ExistResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/GetCorsResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/GetCorsResultTest.php new file mode 100755 index 0000000..a3281c8 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/GetCorsResultTest.php @@ -0,0 +1,67 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Core\OssException; +use OSS\Result\GetCorsResult; +use OSS\Http\ResponseCore; + +class GetCorsResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<CORSConfiguration> +<CORSRule> +<AllowedOrigin>http://www.b.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedOrigin>http://www.a.com</AllowedOrigin> +<AllowedMethod>GET</AllowedMethod> +<AllowedMethod>PUT</AllowedMethod> +<AllowedMethod>POST</AllowedMethod> +<AllowedHeader>x-oss-test</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test2</AllowedHeader> +<AllowedHeader>x-oss-test3</AllowedHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<ExposeHeader>x-oss-test2</ExposeHeader> +<MaxAgeSeconds>10</MaxAgeSeconds> +</CORSRule> +<CORSRule> +<AllowedOrigin>http://www.b.com</AllowedOrigin> +<AllowedMethod>GET</AllowedMethod> +<AllowedHeader>x-oss-test</AllowedHeader> +<ExposeHeader>x-oss-test1</ExposeHeader> +<MaxAgeSeconds>110</MaxAgeSeconds> +</CORSRule> +</CORSConfiguration> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetCorsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $corsConfig = $result->getData(); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($corsConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), $this->validXml, 300); + try { + new GetCorsResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/GetLifecycleResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/GetLifecycleResultTest.php new file mode 100755 index 0000000..92ae208 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/GetLifecycleResultTest.php @@ -0,0 +1,59 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Http\ResponseCore; +use OSS\Core\OssException; +use OSS\Model\LifecycleConfig; +use OSS\Result\GetLifecycleResult; + +class GetLifecycleResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LifecycleConfiguration> +<Rule> +<ID>delete obsoleted files</ID> +<Prefix>obsoleted/</Prefix> +<Status>Enabled</Status> +<Expiration><Days>3</Days></Expiration> +</Rule> +<Rule> +<ID>delete temporary files</ID> +<Prefix>temporary/</Prefix> +<Status>Enabled</Status> +<Expiration><Date>2022-10-12T00:00:00.000Z</Date></Expiration> +<Expiration2><Date>2022-10-12T00:00:00.000Z</Date></Expiration2> +</Rule> +</LifecycleConfiguration> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetLifecycleResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $lifecycleConfig = $result->getData(); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($lifecycleConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), $this->validXml, 300); + try { + new GetLifecycleResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/GetLoggingResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/GetLoggingResultTest.php new file mode 100755 index 0000000..6195014 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/GetLoggingResultTest.php @@ -0,0 +1,51 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Result\GetLoggingResult; +use OSS\Http\ResponseCore; +use OSS\Core\OssException; + + +class GetLoggingResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<BucketLoggingStatus> +<LoggingEnabled> +<TargetBucket>TargetBucket</TargetBucket> +<TargetPrefix>TargetPrefix</TargetPrefix> +</LoggingEnabled> +</BucketLoggingStatus> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetLoggingResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $loggingConfig = $result->getData(); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($loggingConfig->serializeToXml())); + $this->assertEquals("TargetBucket", $loggingConfig->getTargetBucket()); + $this->assertEquals("TargetPrefix", $loggingConfig->getTargetPrefix()); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), $this->validXml, 300); + try { + new GetLoggingResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/GetRefererResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/GetRefererResultTest.php new file mode 100755 index 0000000..072aa43 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/GetRefererResultTest.php @@ -0,0 +1,51 @@ +<?php + +namespace OSS\Tests; + +use OSS\Result\GetRefererResult; +use OSS\Http\ResponseCore; +use OSS\Core\OssException; + + +class GetRefererResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<RefererConfiguration> +<AllowEmptyReferer>true</AllowEmptyReferer> +<RefererList> +<Referer>http://www.aliyun.com</Referer> +<Referer>https://www.aliyun.com</Referer> +<Referer>http://www.*.com</Referer> +<Referer>https://www.?.aliyuncs.com</Referer> +</RefererList> +</RefererConfiguration> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetRefererResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $refererConfig = $result->getData(); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($refererConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), $this->validXml, 300); + try { + new GetRefererResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/GetWebsiteResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/GetWebsiteResultTest.php new file mode 100755 index 0000000..70e1559 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/GetWebsiteResultTest.php @@ -0,0 +1,50 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Result\GetWebsiteResult; +use OSS\Http\ResponseCore; +use OSS\Core\OssException; + +class GetWebsiteResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<WebsiteConfiguration> +<IndexDocument> +<Suffix>index.html</Suffix> +</IndexDocument> +<ErrorDocument> +<Key>errorDocument.html</Key> +</ErrorDocument> +</WebsiteConfiguration> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetWebsiteResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $websiteConfig = $result->getData(); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($websiteConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + + public function testInvalidResponse() + { + $response = new ResponseCore(array(), $this->validXml, 300); + try { + new GetWebsiteResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/HeaderResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/HeaderResultTest.php new file mode 100755 index 0000000..dae4975 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/HeaderResultTest.php @@ -0,0 +1,23 @@ +<?php + +namespace OSS\Tests; + +use OSS\Result\HeaderResult; +use OSS\Http\ResponseCore; + +/** + * Class HeaderResultTest + * @package OSS\Tests + */ +class HeaderResultTest extends \PHPUnit_Framework_TestCase +{ + public function testGetHeader() + { + $response = new ResponseCore(array('key' => 'value'), "", 200); + $result = new HeaderResult($response); + $this->assertTrue($result->isOK()); + $this->assertTrue(is_array($result->getData())); + $data = $result->getData(); + $this->assertEquals($data['key'], 'value'); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/HttpTest.php b/vendor/oss-sdk/tests/OSS/Tests/HttpTest.php new file mode 100755 index 0000000..a59dfcd --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/HttpTest.php @@ -0,0 +1,77 @@ +<?php + +namespace OSS\Tests; + +use OSS\Http\RequestCore; +use OSS\Http\ResponseCore; +use OSS\Http\RequestCore_Exception; +use Symfony\Component\Config\Definition\Exception\Exception; + +class HttpTest extends \PHPUnit_Framework_TestCase +{ + + public function testResponseCore() + { + $res = new ResponseCore(null, "", 500); + $this->assertFalse($res->isOK()); + $this->assertTrue($res->isOK(500)); + } + + public function testGet() + { + $httpCore = new RequestCore("http://www.baidu.com"); + $httpResponse = $httpCore->send_request(); + $this->assertNotNull($httpResponse); + } + + public function testSetProxyAndTimeout() + { + $httpCore = new RequestCore("http://www.baidu.com"); + $httpCore->set_proxy("1.0.2.1:8888"); + $httpCore->connect_timeout = 1; + try { + $httpResponse = $httpCore->send_request(); + $this->assertTrue(false); + } catch (RequestCore_Exception $e) { + + } + } + + public function testGetParseTrue() + { + $httpCore = new RequestCore("http://www.baidu.com"); + $httpCore->curlopts = array(CURLOPT_HEADER => true); + $url = $httpCore->send_request(true); + foreach ($httpCore->get_response_header() as $key => $value) { + $this->assertEquals($httpCore->get_response_header($key), $value); + } + $this->assertNotNull($url); + } + + public function testParseResponse() + { + $httpCore = new RequestCore("http://www.baidu.com"); + $response = $httpCore->send_request(); + $parsed = $httpCore->process_response(null, $response); + $this->assertNotNull($parsed); + } + + public function testExceptionGet() + { + $httpCore = null; + $exception = false; + try { + $httpCore = new RequestCore("http://www.notexistsitexx.com"); + $httpCore->set_body(""); + $httpCore->set_method("GET"); + $httpCore->connect_timeout = 10; + $httpCore->timeout = 10; + $res = $httpCore->send_request(); + } catch (RequestCore_Exception $e) { + $exception = true; + } + $this->assertTrue($exception); + } +} + + diff --git a/vendor/oss-sdk/tests/OSS/Tests/InitiateMultipartUploadResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/InitiateMultipartUploadResultTest.php new file mode 100755 index 0000000..9f6c7a5 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/InitiateMultipartUploadResultTest.php @@ -0,0 +1,47 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Core\OssException; +use OSS\Result\InitiateMultipartUploadResult; +use OSS\Http\ResponseCore; + +class InitiateMultipartUploadResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<InitiateMultipartUploadResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com"> + <Bucket> multipart_upload</Bucket> + <Key>multipart.data</Key> + <UploadId>0004B9894A22E5B1888A1E29F8236E2D</UploadId> +</InitiateMultipartUploadResult> +BBBB; + + private $invalidXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<InitiateMultipartUploadResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com"> + <Bucket> multipart_upload</Bucket> + <Key>multipart.data</Key> +</InitiateMultipartUploadResult> +BBBB; + + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new InitiateMultipartUploadResult($response); + $this->assertEquals("0004B9894A22E5B1888A1E29F8236E2D", $result->getData()); + } + + public function testParseInvalidXml() + { + $response = new ResponseCore(array(), $this->invalidXml, 200); + try { + $result = new InitiateMultipartUploadResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/LifecycleConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/LifecycleConfigTest.php new file mode 100755 index 0000000..7bd0331 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/LifecycleConfigTest.php @@ -0,0 +1,130 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\LifecycleAction; +use OSS\Model\LifecycleConfig; +use OSS\Model\LifecycleRule; + +class LifecycleConfigTest extends \PHPUnit_Framework_TestCase +{ + + private $validLifecycle = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LifecycleConfiguration> +<Rule> +<ID>delete obsoleted files</ID> +<Prefix>obsoleted/</Prefix> +<Status>Enabled</Status> +<Expiration><Days>3</Days></Expiration> +</Rule> +<Rule> +<ID>delete temporary files</ID> +<Prefix>temporary/</Prefix> +<Status>Enabled</Status> +<Expiration><Date>2022-10-12T00:00:00.000Z</Date></Expiration> +<Expiration2><Date>2022-10-12T00:00:00.000Z</Date></Expiration2> +</Rule> +</LifecycleConfiguration> +BBBB; + + private $validLifecycle2 = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LifecycleConfiguration> +<Rule><ID>delete temporary files</ID> +<Prefix>temporary/</Prefix> +<Status>Enabled</Status> +<Expiration><Date>2022-10-12T00:00:00.000Z</Date></Expiration> +<Expiration2><Date>2022-10-12T00:00:00.000Z</Date></Expiration2> +</Rule> +</LifecycleConfiguration> +BBBB; + + private $nullLifecycle = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LifecycleConfiguration/> +BBBB; + + public function testConstructValidConfig() + { + $lifecycleConfig = new LifecycleConfig(); + $actions = array(); + $actions[] = new LifecycleAction("Expiration", "Days", 3); + $lifecycleRule = new LifecycleRule("delete obsoleted files", "obsoleted/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + $actions = array(); + $actions[] = new LifecycleAction("Expiration", "Date", '2022-10-12T00:00:00.000Z'); + $actions[] = new LifecycleAction("Expiration2", "Date", '2022-10-12T00:00:00.000Z'); + $lifecycleRule = new LifecycleRule("delete temporary files", "temporary/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + try { + $lifecycleConfig->addRule(null); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('lifecycleRule is null', $e->getMessage()); + } + $this->assertEquals($this->cleanXml(strval($lifecycleConfig)), $this->cleanXml($this->validLifecycle)); + } + + public function testParseValidXml() + { + $lifecycleConfig = new LifecycleConfig(); + $lifecycleConfig->parseFromXml($this->validLifecycle); + $this->assertEquals($this->cleanXml($lifecycleConfig->serializeToXml()), $this->cleanXml($this->validLifecycle)); + $this->assertEquals(2, count($lifecycleConfig->getRules())); + $rules = $lifecycleConfig->getRules(); + $this->assertEquals('delete temporary files', $rules[1]->getId()); + } + + public function testParseValidXml2() + { + $lifecycleConfig = new LifecycleConfig(); + $lifecycleConfig->parseFromXml($this->validLifecycle2); + $this->assertEquals($this->cleanXml($lifecycleConfig->serializeToXml()), $this->cleanXml($this->validLifecycle2)); + $this->assertEquals(1, count($lifecycleConfig->getRules())); + $rules = $lifecycleConfig->getRules(); + $this->assertEquals('delete temporary files', $rules[0]->getId()); + } + + public function testParseNullXml() + { + $lifecycleConfig = new LifecycleConfig(); + $lifecycleConfig->parseFromXml($this->nullLifecycle); + $this->assertEquals($this->cleanXml($lifecycleConfig->serializeToXml()), $this->cleanXml($this->nullLifecycle)); + $this->assertEquals(0, count($lifecycleConfig->getRules())); + } + + public function testLifecycleRule() + { + $lifecycleRule = new LifecycleRule("x", "x", "x", array('x')); + $lifecycleRule->setId("id"); + $lifecycleRule->setPrefix("prefix"); + $lifecycleRule->setStatus("Enabled"); + $lifecycleRule->setActions(array()); + + $this->assertEquals('id', $lifecycleRule->getId()); + $this->assertEquals('prefix', $lifecycleRule->getPrefix()); + $this->assertEquals('Enabled', $lifecycleRule->getStatus()); + $this->assertEmpty($lifecycleRule->getActions()); + } + + public function testLifecycleAction() + { + $action = new LifecycleAction('x', 'x', 'x'); + $this->assertEquals($action->getAction(), 'x'); + $this->assertEquals($action->getTimeSpec(), 'x'); + $this->assertEquals($action->getTimeValue(), 'x'); + $action->setAction('y'); + $action->setTimeSpec('y'); + $action->setTimeValue('y'); + $this->assertEquals($action->getAction(), 'y'); + $this->assertEquals($action->getTimeSpec(), 'y'); + $this->assertEquals($action->getTimeValue(), 'y'); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ListBucketsResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/ListBucketsResultTest.php new file mode 100755 index 0000000..1abe1f5 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ListBucketsResultTest.php @@ -0,0 +1,97 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Http\ResponseCore; +use OSS\Result\ListBucketsResult; + +class ListBucketsResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListAllMyBucketsResult> + <Owner> + <ID>ut_test_put_bucket</ID> + <DisplayName>ut_test_put_bucket</DisplayName> + </Owner> + <Buckets> + <Bucket> + <Location>oss-cn-hangzhou-a</Location> + <Name>xz02tphky6fjfiuc0</Name> + <CreationDate>2014-05-15T11:18:32.000Z</CreationDate> + </Bucket> + <Bucket> + <Location>oss-cn-hangzhou-a</Location> + <Name>xz02tphky6fjfiuc1</Name> + <CreationDate>2014-05-15T11:18:32.000Z</CreationDate> + </Bucket> + </Buckets> +</ListAllMyBucketsResult> +BBBB; + + private $nullXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListAllMyBucketsResult> + <Owner> + <ID>ut_test_put_bucket</ID> + <DisplayName>ut_test_put_bucket</DisplayName> + </Owner> + <Buckets> + </Buckets> +</ListAllMyBucketsResult> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new ListBucketsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $bucketListInfo = $result->getData(); + $this->assertEquals(2, count($bucketListInfo->getBucketList())); + } + + public function testParseNullXml() + { + $response = new ResponseCore(array(), $this->nullXml, 200); + $result = new ListBucketsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $bucketListInfo = $result->getData(); + $this->assertEquals(0, count($bucketListInfo->getBucketList())); + } + + public function test403() + { + $errorHeader = array( + 'x-oss-request-id' => '1a2b-3c4d' + ); + + $errorBody = <<< BBBB +<?xml version="1.0" encoding="UTF-8"?> +<Error> + <Code>NoSuchBucket</Code> + <Message>The specified bucket does not exist.</Message> + <RequestId>566B870D207FB3044302EB0A</RequestId> + <HostId>hello.oss-test.aliyun-inc.com</HostId> + <BucketName>hello</BucketName> +</Error> +BBBB; + $response = new ResponseCore($errorHeader, $errorBody, 403); + try { + new ListBucketsResult($response); + } catch (OssException $e) { + $this->assertEquals( + $e->getMessage(), + 'NoSuchBucket: The specified bucket does not exist. RequestId: 1a2b-3c4d'); + $this->assertEquals($e->getHTTPStatus(), '403'); + $this->assertEquals($e->getRequestId(), '1a2b-3c4d'); + $this->assertEquals($e->getErrorCode(), 'NoSuchBucket'); + $this->assertEquals($e->getErrorMessage(), 'The specified bucket does not exist.'); + $this->assertEquals($e->getDetails(), $errorBody); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ListMultipartUploadResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/ListMultipartUploadResultTest.php new file mode 100755 index 0000000..5c757d3 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ListMultipartUploadResultTest.php @@ -0,0 +1,114 @@ +<?php + +namespace OSS\Tests; + +use OSS\Result\ListMultipartUploadResult; +use OSS\Http\ResponseCore; + +/** + * Class ListMultipartUploadResultTest + * @package OSS\Tests + */ +class ListMultipartUploadResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListMultipartUploadsResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com"> + <Bucket>oss-example</Bucket> + <KeyMarker>xx</KeyMarker> + <UploadIdMarker>3</UploadIdMarker> + <NextKeyMarker>oss.avi</NextKeyMarker> + <NextUploadIdMarker>0004B99B8E707874FC2D692FA5D77D3F</NextUploadIdMarker> + <Delimiter>x</Delimiter> + <Prefix>xx</Prefix> + <MaxUploads>1000</MaxUploads> + <IsTruncated>false</IsTruncated> + <Upload> + <Key>multipart.data</Key> + <UploadId>0004B999EF518A1FE585B0C9360DC4C8</UploadId> + <Initiated>2012-02-23T04:18:23.000Z</Initiated> + </Upload> + <Upload> + <Key>multipart.data</Key> + <UploadId>0004B999EF5A239BB9138C6227D69F95</UploadId> + <Initiated>2012-02-23T04:18:23.000Z</Initiated> + </Upload> + <Upload> + <Key>oss.avi</Key> + <UploadId>0004B99B8E707874FC2D692FA5D77D3F</UploadId> + <Initiated>2012-02-23T06:14:27.000Z</Initiated> + </Upload> +</ListMultipartUploadsResult> +BBBB; + + private $validXmlWithEncodedKey = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListMultipartUploadsResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com"> + <Bucket>oss-example</Bucket> + <EncodingType>url</EncodingType> + <KeyMarker>php%2Bkey-marker</KeyMarker> + <UploadIdMarker>3</UploadIdMarker> + <NextKeyMarker>php%2Bnext-key-marker</NextKeyMarker> + <NextUploadIdMarker>0004B99B8E707874FC2D692FA5D77D3F</NextUploadIdMarker> + <Delimiter>%2F</Delimiter> + <Prefix>php%2Bprefix</Prefix> + <MaxUploads>1000</MaxUploads> + <IsTruncated>true</IsTruncated> + <Upload> + <Key>php%2Bkey-1</Key> + <UploadId>0004B999EF518A1FE585B0C9360DC4C8</UploadId> + <Initiated>2012-02-23T04:18:23.000Z</Initiated> + </Upload> + <Upload> + <Key>php%2Bkey-2</Key> + <UploadId>0004B999EF5A239BB9138C6227D69F95</UploadId> + <Initiated>2012-02-23T04:18:23.000Z</Initiated> + </Upload> + <Upload> + <Key>php%2Bkey-3</Key> + <UploadId>0004B99B8E707874FC2D692FA5D77D3F</UploadId> + <Initiated>2012-02-23T06:14:27.000Z</Initiated> + </Upload> +</ListMultipartUploadsResult> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new ListMultipartUploadResult($response); + $listMultipartUploadInfo = $result->getData(); + $this->assertEquals("oss-example", $listMultipartUploadInfo->getBucket()); + $this->assertEquals("xx", $listMultipartUploadInfo->getKeyMarker()); + $this->assertEquals(3, $listMultipartUploadInfo->getUploadIdMarker()); + $this->assertEquals("oss.avi", $listMultipartUploadInfo->getNextKeyMarker()); + $this->assertEquals("0004B99B8E707874FC2D692FA5D77D3F", $listMultipartUploadInfo->getNextUploadIdMarker()); + $this->assertEquals("x", $listMultipartUploadInfo->getDelimiter()); + $this->assertEquals("xx", $listMultipartUploadInfo->getPrefix()); + $this->assertEquals(1000, $listMultipartUploadInfo->getMaxUploads()); + $this->assertEquals("false", $listMultipartUploadInfo->getIsTruncated()); + $uploads = $listMultipartUploadInfo->getUploads(); + $this->assertEquals("multipart.data", $uploads[0]->getKey()); + $this->assertEquals("0004B999EF518A1FE585B0C9360DC4C8", $uploads[0]->getUploadId()); + $this->assertEquals("2012-02-23T04:18:23.000Z", $uploads[0]->getInitiated()); + } + + public function testParseValidXmlWithEncodedKey() + { + $response = new ResponseCore(array(), $this->validXmlWithEncodedKey, 200); + $result = new ListMultipartUploadResult($response); + $listMultipartUploadInfo = $result->getData(); + $this->assertEquals("oss-example", $listMultipartUploadInfo->getBucket()); + $this->assertEquals("php+key-marker", $listMultipartUploadInfo->getKeyMarker()); + $this->assertEquals("php+next-key-marker", $listMultipartUploadInfo->getNextKeyMarker()); + $this->assertEquals(3, $listMultipartUploadInfo->getUploadIdMarker()); + $this->assertEquals("0004B99B8E707874FC2D692FA5D77D3F", $listMultipartUploadInfo->getNextUploadIdMarker()); + $this->assertEquals("/", $listMultipartUploadInfo->getDelimiter()); + $this->assertEquals("php+prefix", $listMultipartUploadInfo->getPrefix()); + $this->assertEquals(1000, $listMultipartUploadInfo->getMaxUploads()); + $this->assertEquals("true", $listMultipartUploadInfo->getIsTruncated()); + $uploads = $listMultipartUploadInfo->getUploads(); + $this->assertEquals("php+key-1", $uploads[0]->getKey()); + $this->assertEquals("0004B999EF518A1FE585B0C9360DC4C8", $uploads[0]->getUploadId()); + $this->assertEquals("2012-02-23T04:18:23.000Z", $uploads[0]->getInitiated()); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ListObjectsResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/ListObjectsResultTest.php new file mode 100755 index 0000000..85f262c --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ListObjectsResultTest.php @@ -0,0 +1,151 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Result\ListObjectsResult; +use OSS\Http\ResponseCore; + +class ListObjectsResultTest extends \PHPUnit_Framework_TestCase +{ + + private $validXml1 = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListBucketResult> + <Name>testbucket-hf</Name> + <Prefix></Prefix> + <Marker></Marker> + <MaxKeys>1000</MaxKeys> + <Delimiter>/</Delimiter> + <IsTruncated>false</IsTruncated> + <CommonPrefixes> + <Prefix>oss-php-sdk-test/</Prefix> + </CommonPrefixes> + <CommonPrefixes> + <Prefix>test/</Prefix> + </CommonPrefixes> +</ListBucketResult> +BBBB; + + private $validXml2 = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListBucketResult> + <Name>testbucket-hf</Name> + <Prefix>oss-php-sdk-test/</Prefix> + <Marker>xx</Marker> + <MaxKeys>1000</MaxKeys> + <Delimiter>/</Delimiter> + <IsTruncated>false</IsTruncated> + <Contents> + <Key>oss-php-sdk-test/upload-test-object-name.txt</Key> + <LastModified>2015-11-18T03:36:00.000Z</LastModified> + <ETag>"89B9E567E7EB8815F2F7D41851F9A2CD"</ETag> + <Type>Normal</Type> + <Size>13115</Size> + <StorageClass>Standard</StorageClass> + <Owner> + <ID>cname_user</ID> + <DisplayName>cname_user</DisplayName> + </Owner> + </Contents> +</ListBucketResult> +BBBB; + + private $validXmlWithEncodedKey = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListBucketResult> + <Name>testbucket-hf</Name> + <EncodingType>url</EncodingType> + <Prefix>php%2Fprefix</Prefix> + <Marker>php%2Fmarker</Marker> + <NextMarker>php%2Fnext-marker</NextMarker> + <MaxKeys>1000</MaxKeys> + <Delimiter>%2F</Delimiter> + <IsTruncated>true</IsTruncated> + <Contents> + <Key>php/a%2Bb</Key> + <LastModified>2015-11-18T03:36:00.000Z</LastModified> + <ETag>"89B9E567E7EB8815F2F7D41851F9A2CD"</ETag> + <Type>Normal</Type> + <Size>13115</Size> + <StorageClass>Standard</StorageClass> + <Owner> + <ID>cname_user</ID> + <DisplayName>cname_user</DisplayName> + </Owner> + </Contents> +</ListBucketResult> +BBBB; + + public function testParseValidXml1() + { + $response = new ResponseCore(array(), $this->validXml1, 200); + $result = new ListObjectsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $objectListInfo = $result->getData(); + $this->assertEquals(2, count($objectListInfo->getPrefixList())); + $this->assertEquals(0, count($objectListInfo->getObjectList())); + $this->assertEquals('testbucket-hf', $objectListInfo->getBucketName()); + $this->assertEquals('', $objectListInfo->getPrefix()); + $this->assertEquals('', $objectListInfo->getMarker()); + $this->assertEquals(1000, $objectListInfo->getMaxKeys()); + $this->assertEquals('/', $objectListInfo->getDelimiter()); + $this->assertEquals('false', $objectListInfo->getIsTruncated()); + $prefixes = $objectListInfo->getPrefixList(); + $this->assertEquals('oss-php-sdk-test/', $prefixes[0]->getPrefix()); + $this->assertEquals('test/', $prefixes[1]->getPrefix()); + } + + public function testParseValidXml2() + { + $response = new ResponseCore(array(), $this->validXml2, 200); + $result = new ListObjectsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $objectListInfo = $result->getData(); + $this->assertEquals(0, count($objectListInfo->getPrefixList())); + $this->assertEquals(1, count($objectListInfo->getObjectList())); + $this->assertEquals('testbucket-hf', $objectListInfo->getBucketName()); + $this->assertEquals('oss-php-sdk-test/', $objectListInfo->getPrefix()); + $this->assertEquals('xx', $objectListInfo->getMarker()); + $this->assertEquals(1000, $objectListInfo->getMaxKeys()); + $this->assertEquals('/', $objectListInfo->getDelimiter()); + $this->assertEquals('false', $objectListInfo->getIsTruncated()); + $objects = $objectListInfo->getObjectList(); + $this->assertEquals('oss-php-sdk-test/upload-test-object-name.txt', $objects[0]->getKey()); + $this->assertEquals('2015-11-18T03:36:00.000Z', $objects[0]->getLastModified()); + $this->assertEquals('"89B9E567E7EB8815F2F7D41851F9A2CD"', $objects[0]->getETag()); + $this->assertEquals('Normal', $objects[0]->getType()); + $this->assertEquals(13115, $objects[0]->getSize()); + $this->assertEquals('Standard', $objects[0]->getStorageClass()); + } + + public function testParseValidXmlWithEncodedKey() + { + $response = new ResponseCore(array(), $this->validXmlWithEncodedKey, 200); + $result = new ListObjectsResult($response); + $this->assertTrue($result->isOK()); + $this->assertNotNull($result->getData()); + $this->assertNotNull($result->getRawResponse()); + $objectListInfo = $result->getData(); + $this->assertEquals(0, count($objectListInfo->getPrefixList())); + $this->assertEquals(1, count($objectListInfo->getObjectList())); + $this->assertEquals('testbucket-hf', $objectListInfo->getBucketName()); + $this->assertEquals('php/prefix', $objectListInfo->getPrefix()); + $this->assertEquals('php/marker', $objectListInfo->getMarker()); + $this->assertEquals('php/next-marker', $objectListInfo->getNextMarker()); + $this->assertEquals(1000, $objectListInfo->getMaxKeys()); + $this->assertEquals('/', $objectListInfo->getDelimiter()); + $this->assertEquals('true', $objectListInfo->getIsTruncated()); + $objects = $objectListInfo->getObjectList(); + $this->assertEquals('php/a+b', $objects[0]->getKey()); + $this->assertEquals('2015-11-18T03:36:00.000Z', $objects[0]->getLastModified()); + $this->assertEquals('"89B9E567E7EB8815F2F7D41851F9A2CD"', $objects[0]->getETag()); + $this->assertEquals('Normal', $objects[0]->getType()); + $this->assertEquals(13115, $objects[0]->getSize()); + $this->assertEquals('Standard', $objects[0]->getStorageClass()); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ListPartsResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/ListPartsResultTest.php new file mode 100755 index 0000000..c446714 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ListPartsResultTest.php @@ -0,0 +1,62 @@ +<?php + +namespace OSS\Tests; + +use OSS\Result\ListPartsResult; +use OSS\Http\ResponseCore; + +/** + * Class ListPartsResultTest + * @package OSS\Tests + */ +class ListPartsResultTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<ListPartsResult xmlns="http://doc.oss-cn-hangzhou.aliyuncs.com"> + <Bucket>multipart_upload</Bucket> + <Key>multipart.data</Key> + <UploadId>0004B999EF5A239BB9138C6227D69F95</UploadId> + <NextPartNumberMarker>5</NextPartNumberMarker> + <MaxParts>1000</MaxParts> + <IsTruncated>false</IsTruncated> + <Part> + <PartNumber>1</PartNumber> + <LastModified>2012-02-23T07:01:34.000Z</LastModified> + <ETag>&quot;3349DC700140D7F86A078484278075A9&quot;</ETag> + <Size>6291456</Size> + </Part> + <Part> + <PartNumber>2</PartNumber> + <LastModified>2012-02-23T07:01:12.000Z</LastModified> + <ETag>&quot;3349DC700140D7F86A078484278075A9&quot;</ETag> + <Size>6291456</Size> + </Part> + <Part> + <PartNumber>5</PartNumber> + <LastModified>2012-02-23T07:02:03.000Z</LastModified> + <ETag>&quot;7265F4D211B56873A381D321F586E4A9&quot;</ETag> + <Size>1024</Size> + </Part> +</ListPartsResult> +BBBB; + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new ListPartsResult($response); + $listPartsInfo = $result->getData(); + $this->assertEquals("multipart_upload", $listPartsInfo->getBucket()); + $this->assertEquals("multipart.data", $listPartsInfo->getKey()); + $this->assertEquals("0004B999EF5A239BB9138C6227D69F95", $listPartsInfo->getUploadId()); + $this->assertEquals(5, $listPartsInfo->getNextPartNumberMarker()); + $this->assertEquals(1000, $listPartsInfo->getMaxParts()); + $this->assertEquals("false", $listPartsInfo->getIsTruncated()); + $this->assertEquals(3, count($listPartsInfo->getListPart())); + $parts = $listPartsInfo->getListPart(); + $this->assertEquals(1, $parts[0]->getPartNumber()); + $this->assertEquals('2012-02-23T07:01:34.000Z', $parts[0]->getLastModified()); + $this->assertEquals('"3349DC700140D7F86A078484278075A9"', $parts[0]->getETag()); + $this->assertEquals(6291456, $parts[0]->getSize()); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/LiveChannelXmlTest.php b/vendor/oss-sdk/tests/OSS/Tests/LiveChannelXmlTest.php new file mode 100755 index 0000000..cc3e219 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/LiveChannelXmlTest.php @@ -0,0 +1,249 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +use OSS\Model\LiveChannelInfo; +use OSS\Model\LiveChannelListInfo; +use OSS\Model\LiveChannelConfig; +use OSS\Model\GetLiveChannelStatus; +use OSS\Model\GetLiveChannelHistory; + +class LiveChannelXmlTest extends \PHPUnit_Framework_TestCase +{ + private $config = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LiveChannelConfiguration> + <Description>xxx</Description> + <Status>enabled</Status> + <Target> + <Type>hls</Type> + <FragDuration>1000</FragDuration> + <FragCount>5</FragCount> + <PlayListName>hello.m3u8</PlayListName> + </Target> +</LiveChannelConfiguration> +BBBB; + + private $info = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<CreateLiveChannelResult> + <Name>live-1</Name> + <Description>xxx</Description> + <PublishUrls> + <Url>rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/213443245345</Url> + </PublishUrls> + <PlayUrls> + <Url>http://bucket.oss-cn-hangzhou.aliyuncs.com/213443245345/播放列表.m3u8</Url> + </PlayUrls> + <Status>enabled</Status> + <LastModified>2015-11-24T14:25:31.000Z</LastModified> +</CreateLiveChannelResult> +BBBB; + + private $list = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<ListLiveChannelResult> +<Prefix>xxx</Prefix> + <Marker>yyy</Marker> + <MaxKeys>100</MaxKeys> + <IsTruncated>false</IsTruncated> + <NextMarker>121312132</NextMarker> + <LiveChannel> + <Name>12123214323431</Name> + <Description>xxx</Description> + <PublishUrls> + <Url>rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/1</Url> + </PublishUrls> + <PlayUrls> + <Url>http://bucket.oss-cn-hangzhou.aliyuncs.com/1/播放列表.m3u8</Url> + </PlayUrls> + <Status>enabled</Status> + <LastModified>2015-11-24T14:25:31.000Z</LastModified> + </LiveChannel> + <LiveChannel> + <Name>432423432423</Name> + <Description>yyy</Description> + <PublishUrls> + <Url>rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/2</Url> + </PublishUrls> + <PlayUrls> + <Url>http://bucket.oss-cn-hangzhou.aliyuncs.com/2/播放列表.m3u8</Url> + </PlayUrls> + <Status>enabled</Status> + <LastModified>2016-11-24T14:25:31.000Z</LastModified> + </LiveChannel> +</ListLiveChannelResult> +BBBB; + + private $status = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LiveChannelStat> + <Status>Live</Status> + <ConnectedTime>2016-10-20T14:25:31.000Z</ConnectedTime> + <RemoteAddr>10.1.2.4:47745</RemoteAddr> + <Video> + <Width>1280</Width> + <Height>536</Height> + <FrameRate>24</FrameRate> + <Bandwidth>72513</Bandwidth> + <Codec>H264</Codec> + </Video> + <Audio> + <Bandwidth>6519</Bandwidth> + <SampleRate>44100</SampleRate> + <Codec>AAC</Codec> + </Audio> +</LiveChannelStat> +BBBB; + + private $history = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<LiveChannelHistory> + <LiveRecord> + <StartTime>2013-11-24T14:25:31.000Z</StartTime> + <EndTime>2013-11-24T15:25:31.000Z</EndTime> + <RemoteAddr>10.101.194.148:56861</RemoteAddr> + </LiveRecord> + <LiveRecord> + <StartTime>2014-11-24T14:25:31.000Z</StartTime> + <EndTime>2014-11-24T15:25:31.000Z</EndTime> + <RemoteAddr>10.101.194.148:56862</RemoteAddr> + </LiveRecord> + <LiveRecord> + <StartTime>2015-11-24T14:25:31.000Z</StartTime> + <EndTime>2015-11-24T15:25:31.000Z</EndTime> + <RemoteAddr>10.101.194.148:56863</RemoteAddr> + </LiveRecord> +</LiveChannelHistory> +BBBB; + + public function testLiveChannelStatus() + { + $stat = new GetLiveChannelStatus(); + $stat->parseFromXml($this->status); + + $this->assertEquals('Live', $stat->getStatus()); + $this->assertEquals('2016-10-20T14:25:31.000Z', $stat->getConnectedTime()); + $this->assertEquals('10.1.2.4:47745', $stat->getRemoteAddr()); + + $this->assertEquals(1280, $stat->getVideoWidth()); + $this->assertEquals(536, $stat->getVideoHeight()); + $this->assertEquals(24, $stat->getVideoFrameRate()); + $this->assertEquals(72513, $stat->getVideoBandwidth()); + $this->assertEquals('H264', $stat->getVideoCodec()); + $this->assertEquals(6519, $stat->getAudioBandwidth()); + $this->assertEquals(44100, $stat->getAudioSampleRate()); + $this->assertEquals('AAC', $stat->getAudioCodec()); + + } + + public function testLiveChannelHistory() + { + $history = new GetLiveChannelHistory(); + $history->parseFromXml($this->history); + + $recordList = $history->getLiveRecordList(); + $this->assertEquals(3, count($recordList)); + + $list0 = $recordList[0]; + $this->assertEquals('2013-11-24T14:25:31.000Z', $list0->getStartTime()); + $this->assertEquals('2013-11-24T15:25:31.000Z', $list0->getEndTime()); + $this->assertEquals('10.101.194.148:56861', $list0->getRemoteAddr()); + + $list1 = $recordList[1]; + $this->assertEquals('2014-11-24T14:25:31.000Z', $list1->getStartTime()); + $this->assertEquals('2014-11-24T15:25:31.000Z', $list1->getEndTime()); + $this->assertEquals('10.101.194.148:56862', $list1->getRemoteAddr()); + + $list2 = $recordList[2]; + $this->assertEquals('2015-11-24T14:25:31.000Z', $list2->getStartTime()); + $this->assertEquals('2015-11-24T15:25:31.000Z', $list2->getEndTime()); + $this->assertEquals('10.101.194.148:56863', $list2->getRemoteAddr()); + + } + + public function testLiveChannelConfig() + { + $config = new LiveChannelConfig(array('name' => 'live-1')); + $config->parseFromXml($this->config); + + $this->assertEquals('xxx', $config->getDescription()); + $this->assertEquals('enabled', $config->getStatus()); + $this->assertEquals('hls', $config->getType()); + $this->assertEquals(1000, $config->getFragDuration()); + $this->assertEquals(5, $config->getFragCount()); + $this->assertEquals('hello.m3u8', $config->getPlayListName()); + + $xml = $config->serializeToXml(); + $config2 = new LiveChannelConfig(array('name' => 'live-2')); + $config2->parseFromXml($xml); + $this->assertEquals('xxx', $config2->getDescription()); + $this->assertEquals('enabled', $config2->getStatus()); + $this->assertEquals('hls', $config2->getType()); + $this->assertEquals(1000, $config2->getFragDuration()); + $this->assertEquals(5, $config2->getFragCount()); + $this->assertEquals('hello.m3u8', $config2->getPlayListName()); + } + + public function testLiveChannelInfo() + { + $info = new LiveChannelInfo(array('name' => 'live-1')); + $info->parseFromXml($this->info); + + $this->assertEquals('live-1', $info->getName()); + $this->assertEquals('xxx', $info->getDescription()); + $this->assertEquals('enabled', $info->getStatus()); + $this->assertEquals('2015-11-24T14:25:31.000Z', $info->getLastModified()); + $pubs = $info->getPublishUrls(); + $this->assertEquals(1, count($pubs)); + $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/213443245345', $pubs[0]); + + $plays = $info->getPlayUrls(); + $this->assertEquals(1, count($plays)); + $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/213443245345/播放列表.m3u8', $plays[0]); + } + + public function testLiveChannelList() + { + $list = new LiveChannelListInfo(); + $list->parseFromXml($this->list); + + $this->assertEquals('xxx', $list->getPrefix()); + $this->assertEquals('yyy', $list->getMarker()); + $this->assertEquals(100, $list->getMaxKeys()); + $this->assertEquals(false, $list->getIsTruncated()); + $this->assertEquals('121312132', $list->getNextMarker()); + + $channels = $list->getChannelList(); + $this->assertEquals(2, count($channels)); + + $chan1 = $channels[0]; + $this->assertEquals('12123214323431', $chan1->getName()); + $this->assertEquals('xxx', $chan1->getDescription()); + $this->assertEquals('enabled', $chan1->getStatus()); + $this->assertEquals('2015-11-24T14:25:31.000Z', $chan1->getLastModified()); + $pubs = $chan1->getPublishUrls(); + $this->assertEquals(1, count($pubs)); + $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/1', $pubs[0]); + + $plays = $chan1->getPlayUrls(); + $this->assertEquals(1, count($plays)); + $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/1/播放列表.m3u8', $plays[0]); + + $chan2 = $channels[1]; + $this->assertEquals('432423432423', $chan2->getName()); + $this->assertEquals('yyy', $chan2->getDescription()); + $this->assertEquals('enabled', $chan2->getStatus()); + $this->assertEquals('2016-11-24T14:25:31.000Z', $chan2->getLastModified()); + $pubs = $chan2->getPublishUrls(); + $this->assertEquals(1, count($pubs)); + $this->assertEquals('rtmp://bucket.oss-cn-hangzhou.aliyuncs.com/live/2', $pubs[0]); + + $plays = $chan2->getPlayUrls(); + $this->assertEquals(1, count($plays)); + $this->assertEquals('http://bucket.oss-cn-hangzhou.aliyuncs.com/2/播放列表.m3u8', $plays[0]); + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/LoggingConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/LoggingConfigTest.php new file mode 100755 index 0000000..01496bb --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/LoggingConfigTest.php @@ -0,0 +1,47 @@ +<?php + +namespace OSS\Tests; + +use OSS\Model\LoggingConfig; + +class LoggingConfigTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<BucketLoggingStatus> +<LoggingEnabled> +<TargetBucket>TargetBucket</TargetBucket> +<TargetPrefix>TargetPrefix</TargetPrefix> +</LoggingEnabled> +</BucketLoggingStatus> +BBBB; + + private $nullXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<BucketLoggingStatus/> +BBBB; + + public function testParseValidXml() + { + $loggingConfig = new LoggingConfig(); + $loggingConfig->parseFromXml($this->validXml); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml(strval($loggingConfig))); + } + + public function testConstruct() + { + $loggingConfig = new LoggingConfig('TargetBucket', 'TargetPrefix'); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($loggingConfig->serializeToXml())); + } + + public function testFailedConstruct() + { + $loggingConfig = new LoggingConfig('TargetBucket', null); + $this->assertEquals($this->cleanXml($this->nullXml), $this->cleanXml($loggingConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/MimeTypesTest.php b/vendor/oss-sdk/tests/OSS/Tests/MimeTypesTest.php new file mode 100755 index 0000000..0697409 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/MimeTypesTest.php @@ -0,0 +1,13 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\MimeTypes; + +class MimeTypesTest extends \PHPUnit_Framework_TestCase +{ + public function testGetMimeType() + { + $this->assertEquals('application/xml', MimeTypes::getMimetype('file.xml')); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/ObjectAclTest.php b/vendor/oss-sdk/tests/OSS/Tests/ObjectAclTest.php new file mode 100755 index 0000000..d397288 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/ObjectAclTest.php @@ -0,0 +1,28 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +class ObjectAclTest extends \PHPUnit_Framework_TestCase +{ + public function testGetSet() + { + $client = Common::getOssClient(); + $bucket = Common::getBucketName(); + + $object = 'test/object-acl'; + $client->deleteObject($bucket, $object); + $client->putObject($bucket, $object, "hello world"); + + $acl = $client->getObjectAcl($bucket, $object); + $this->assertEquals('default', $acl); + + $client->putObjectAcl($bucket, $object, 'public-read'); + $acl = $client->getObjectAcl($bucket, $object); + $this->assertEquals('public-read', $acl); + + $content = $client->getObject($bucket, $object); + $this->assertEquals('hello world', $content); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketCorsTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketCorsTest.php new file mode 100755 index 0000000..a32154b --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketCorsTest.php @@ -0,0 +1,84 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\CorsConfig; +use OSS\Model\CorsRule; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketCorsTest extends TestOssClientBase +{ + public function testBucket() + { + $corsConfig = new CorsConfig(); + $rule = new CorsRule(); + $rule->addAllowedHeader("x-oss-test"); + $rule->addAllowedHeader("x-oss-test2"); + $rule->addAllowedHeader("x-oss-test2"); + $rule->addAllowedHeader("x-oss-test3"); + $rule->addAllowedOrigin("http://www.b.com"); + $rule->addAllowedOrigin("http://www.a.com"); + $rule->addAllowedOrigin("http://www.a.com"); + $rule->addAllowedMethod("GET"); + $rule->addAllowedMethod("PUT"); + $rule->addAllowedMethod("POST"); + $rule->addExposeHeader("x-oss-test1"); + $rule->addExposeHeader("x-oss-test1"); + $rule->addExposeHeader("x-oss-test2"); + $rule->setMaxAgeSeconds(10); + $corsConfig->addRule($rule); + $rule = new CorsRule(); + $rule->addAllowedHeader("x-oss-test"); + $rule->addAllowedMethod("GET"); + $rule->addAllowedOrigin("http://www.b.com"); + $rule->addExposeHeader("x-oss-test1"); + $rule->setMaxAgeSeconds(110); + $corsConfig->addRule($rule); + + try { + $this->ossClient->putBucketCors($this->bucket, $corsConfig); + } catch (OssException $e) { + $this->assertFalse(True); + } + + try { + Common::waitMetaSync(); + $object = "cors/test.txt"; + $this->ossClient->putObject($this->bucket, $object, file_get_contents(__FILE__)); + $headers = $this->ossClient->optionsObject($this->bucket, $object, "http://www.a.com", "GET", "", null); + $this->assertNotEmpty($headers); + } catch (OssException $e) { + var_dump($e->getMessage()); + } + + try { + Common::waitMetaSync(); + $corsConfig2 = $this->ossClient->getBucketCors($this->bucket); + $this->assertNotNull($corsConfig2); + $this->assertEquals($corsConfig->serializeToXml(), $corsConfig2->serializeToXml()); + } catch (OssException $e) { + $this->assertFalse(True); + } + + try { + Common::waitMetaSync(); + $this->ossClient->deleteBucketCors($this->bucket); + } catch (OssException $e) { + $this->assertFalse(True); + } + + try { + Common::waitMetaSync(); + $corsConfig3 = $this->ossClient->getBucketCors($this->bucket); + $this->assertNotNull($corsConfig3); + $this->assertNotEquals($corsConfig->serializeToXml(), $corsConfig3->serializeToXml()); + } catch (OssException $e) { + $this->assertFalse(True); + } + + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLifecycleTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLifecycleTest.php new file mode 100755 index 0000000..46da1f0 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLifecycleTest.php @@ -0,0 +1,57 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\LifecycleConfig; +use OSS\Model\LifecycleRule; +use OSS\Model\LifecycleAction; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketLifecycleTest extends TestOssClientBase +{ + public function testBucket() + { + $lifecycleConfig = new LifecycleConfig(); + $actions = array(); + $actions[] = new LifecycleAction("Expiration", "Days", 3); + $lifecycleRule = new LifecycleRule("delete obsoleted files", "obsoleted/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + $actions = array(); + $actions[] = new LifecycleAction("Expiration", "Date", '2022-10-12T00:00:00.000Z'); + $lifecycleRule = new LifecycleRule("delete temporary files", "temporary/", "Enabled", $actions); + $lifecycleConfig->addRule($lifecycleRule); + + try { + $this->ossClient->putBucketLifecycle($this->bucket, $lifecycleConfig); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $lifecycleConfig2 = $this->ossClient->getBucketLifecycle($this->bucket); + $this->assertEquals($lifecycleConfig->serializeToXml(), $lifecycleConfig2->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $this->ossClient->deleteBucketLifecycle($this->bucket); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $lifecycleConfig3 = $this->ossClient->getBucketLifecycle($this->bucket); + $this->assertNotEquals($lifecycleConfig->serializeToXml(), $lifecycleConfig3->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLoggingTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLoggingTest.php new file mode 100755 index 0000000..16a10eb --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketLoggingTest.php @@ -0,0 +1,43 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\LoggingConfig; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketLoggingTest extends TestOssClientBase +{ + public function testBucket() + { + $loggingConfig = new LoggingConfig($this->bucket, 'prefix'); + try { + $this->ossClient->putBucketLogging($this->bucket, $this->bucket, 'prefix'); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $loggingConfig2 = $this->ossClient->getBucketLogging($this->bucket); + $this->assertEquals($loggingConfig->serializeToXml(), $loggingConfig2->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $this->ossClient->deleteBucketLogging($this->bucket); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $loggingConfig3 = $this->ossClient->getBucketLogging($this->bucket); + $this->assertNotEquals($loggingConfig->serializeToXml(), $loggingConfig3->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketRefererTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketRefererTest.php new file mode 100755 index 0000000..ba7d14f --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketRefererTest.php @@ -0,0 +1,48 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\RefererConfig; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketRefererTest extends TestOssClientBase +{ + + public function testBucket() + { + $refererConfig = new RefererConfig(); + $refererConfig->addReferer('http://www.aliyun.com'); + + try { + $this->ossClient->putBucketReferer($this->bucket, $refererConfig); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $refererConfig2 = $this->ossClient->getBucketReferer($this->bucket); + $this->assertEquals($refererConfig->serializeToXml(), $refererConfig2->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $nullRefererConfig = new RefererConfig(); + $nullRefererConfig->setAllowEmptyReferer(false); + $this->ossClient->putBucketReferer($this->bucket, $nullRefererConfig); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $refererConfig3 = $this->ossClient->getBucketLogging($this->bucket); + $this->assertNotEquals($refererConfig->serializeToXml(), $refererConfig3->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketStorageCapacityTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketStorageCapacityTest.php new file mode 100755 index 0000000..87548f9 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketStorageCapacityTest.php @@ -0,0 +1,56 @@ +<?php +namespace OSS\Tests; + +use OSS\Core\OssException; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + +class OssClientBucketStorageCapacityTest extends TestOssClientBase +{ + public function testBucket() + { + try { + $storageCapacity = $this->ossClient->getBucketStorageCapacity($this->bucket); + $this->assertEquals($storageCapacity, -1); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketStorageCapacity($this->bucket, 1000); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $storageCapacity = $this->ossClient->getBucketStorageCapacity($this->bucket); + $this->assertEquals($storageCapacity, 1000); + } catch (OssException $e) { + $this->assertTrue(false); + } + + try { + $this->ossClient->putBucketStorageCapacity($this->bucket, 0); + + Common::waitMetaSync(); + + $storageCapacity = $this->ossClient->getBucketStorageCapacity($this->bucket); + $this->assertEquals($storageCapacity, 0); + + $this->ossClient->putObject($this->bucket, 'test-storage-capacity','test-content'); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('Bucket storage exceed max storage capacity.',$e->getErrorMessage()); + } + + try { + $this->ossClient->putBucketStorageCapacity($this->bucket, -2); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals(400, $e->getHTTPStatus()); + $this->assertEquals('InvalidArgument', $e->getErrorCode()); + } + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketTest.php new file mode 100755 index 0000000..f207ca1 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketTest.php @@ -0,0 +1,113 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketTest extends TestOssClientBase +{ + private $iaBucket; + private $archiveBucket; + + public function testBucketWithInvalidName() + { + try { + $this->ossClient->createBucket("s"); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('"s"bucket name is invalid', $e->getMessage()); + } + } + + public function testBucketWithInvalidACL() + { + try { + $this->ossClient->createBucket($this->bucket, "invalid"); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('invalid:acl is invalid(private,public-read,public-read-write)', $e->getMessage()); + } + } + + public function testBucket() + { + $this->ossClient->createBucket($this->bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); + + $bucketListInfo = $this->ossClient->listBuckets(); + $this->assertNotNull($bucketListInfo); + + $bucketList = $bucketListInfo->getBucketList(); + $this->assertTrue(is_array($bucketList)); + $this->assertGreaterThan(0, count($bucketList)); + + $this->ossClient->putBucketAcl($this->bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); + Common::waitMetaSync(); + $this->assertEquals($this->ossClient->getBucketAcl($this->bucket), OssClient::OSS_ACL_TYPE_PUBLIC_READ_WRITE); + + $this->assertTrue($this->ossClient->doesBucketExist($this->bucket)); + $this->assertFalse($this->ossClient->doesBucketExist($this->bucket . '-notexist')); + + $this->assertEquals($this->ossClient->getBucketLocation($this->bucket), 'oss-us-west-1'); + + $res = $this->ossClient->getBucketMeta($this->bucket); + $this->assertEquals('200', $res['info']['http_code']); + $this->assertEquals('oss-us-west-1', $res['x-oss-bucket-region']); + } + + public function testCreateBucketWithStorageType() + { + $object = 'storage-object'; + + $this->ossClient->putObject($this->archiveBucket, $object,'testcontent'); + try { + $this->ossClient->getObject($this->archiveBucket, $object); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('403', $e->getHTTPStatus()); + $this->assertEquals('InvalidObjectState', $e->getErrorCode()); + } + + $this->ossClient->putObject($this->iaBucket, $object,'testcontent'); + $result = $this->ossClient->getObject($this->iaBucket, $object); + $this->assertEquals($result, 'testcontent'); + + $this->ossClient->putObject($this->bucket, $object,'testcontent'); + $result = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($result, 'testcontent'); + } + + public function setUp() + { + parent::setUp(); + + $this->iaBucket = 'ia-' . $this->bucket; + $this->archiveBucket = 'archive-' . $this->bucket; + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_IA + ); + + $this->ossClient->createBucket($this->iaBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_ARCHIVE + ); + + $this->ossClient->createBucket($this->archiveBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + } + + public function tearDown() + { + parent::tearDown(); + + $object = 'storage-object'; + + $this->ossClient->deleteObject($this->iaBucket, $object); + $this->ossClient->deleteObject($this->archiveBucket, $object); + $this->ossClient->deleteBucket($this->iaBucket); + $this->ossClient->deleteBucket($this->archiveBucket); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketWebsiteTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketWebsiteTest.php new file mode 100755 index 0000000..dfa9cc1 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientBucketWebsiteTest.php @@ -0,0 +1,46 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Model\WebsiteConfig; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientBucketWebsiteTest extends TestOssClientBase +{ + public function testBucket() + { + + $websiteConfig = new WebsiteConfig("index.html", "error.html"); + + try { + $this->ossClient->putBucketWebsite($this->bucket, $websiteConfig); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + + try { + Common::waitMetaSync(); + $websiteConfig2 = $this->ossClient->getBucketWebsite($this->bucket); + $this->assertEquals($websiteConfig->serializeToXml(), $websiteConfig2->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $this->ossClient->deleteBucketWebsite($this->bucket); + } catch (OssException $e) { + $this->assertTrue(false); + } + try { + Common::waitMetaSync(); + $websiteConfig3 = $this->ossClient->getBucketLogging($this->bucket); + $this->assertNotEquals($websiteConfig->serializeToXml(), $websiteConfig3->serializeToXml()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientImageTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientImageTest.php new file mode 100755 index 0000000..df8bd6c --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientImageTest.php @@ -0,0 +1,100 @@ +<?php + +namespace OSS\Tests; + +require_once __DIR__ . '/Common.php'; + +use OSS\OssClient; + +class OssClinetImageTest extends \PHPUnit_Framework_TestCase +{ + private $bucketName; + private $client; + private $local_file; + private $object; + private $download_file; + + public function setUp() + { + $this->client = Common::getOssClient(); + $this->bucketName = 'php-sdk-test-bucket-image-' . strval(rand(0, 10000)); + $this->client->createBucket($this->bucketName); + Common::waitMetaSync(); + $this->local_file = "example.jpg"; + $this->object = "oss-example.jpg"; + $this->download_file = "image.jpg"; + + $this->client->uploadFile($this->bucketName, $this->object, $this->local_file); + } + + public function tearDown() + { + $this->client->deleteObject($this->bucketName, $this->object); + $this->client->deleteBucket($this->bucketName); + } + + public function testImageResize() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/resize,m_fixed,h_100,w_100", ); + $this->check($options, 100, 100, 3267, 'jpg'); + } + + public function testImageCrop() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/crop,w_100,h_100,x_100,y_100,r_1", ); + $this->check($options, 100, 100, 1969, 'jpg'); + } + + public function testImageRotate() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/rotate,90", ); + $this->check($options, 267, 400, 20998, 'jpg'); + } + + public function testImageSharpen() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/sharpen,100", ); + $this->check($options, 400, 267, 23015, 'jpg'); + } + + public function testImageWatermark() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ", ); + $this->check($options, 400, 267, 26369, 'jpg'); + } + + public function testImageFormat() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/format,png", ); + $this->check($options, 400, 267, 160733, 'png'); + } + + public function testImageTofile() + { + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $this->download_file, + OssClient::OSS_PROCESS => "image/resize,m_fixed,w_100,h_100", ); + $this->check($options, 100, 100, 3267, 'jpg'); + } + + private function check($options, $width, $height, $size, $type) + { + $this->client->getObject($this->bucketName, $this->object, $options); + $array = getimagesize($this->download_file); + $this->assertEquals($width, $array[0]); + $this->assertEquals($height, $array[1]); + $this->assertEquals($type === 'jpg' ? 2 : 3, $array[2]);//2 <=> jpg + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientMultipartUploadTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientMultipartUploadTest.php new file mode 100755 index 0000000..a95f412 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientMultipartUploadTest.php @@ -0,0 +1,313 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; +use OSS\Core\OssUtil; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientMultipartUploadTest extends TestOssClientBase +{ + public function testInvalidDir() + { + try { + $this->ossClient->uploadDir($this->bucket, "", "abc/ds/s/s/notexitst"); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals("parameter error: abc/ds/s/s/notexitst is not a directory, please check it", $e->getMessage()); + } + + } + + public function testMultipartUploadBigFile() + { + $bigFileName = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile.tmp"; + $localFilename = __DIR__ . DIRECTORY_SEPARATOR . "/localfile.tmp"; + OssUtil::generateFile($bigFileName, 6 * 1024 * 1024); + $object = 'mpu/multipart-bigfile-test.tmp'; + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $bigFileName, array(OssClient::OSS_PART_SIZE => 1)); + $options = array(OssClient::OSS_FILE_DOWNLOAD => $localFilename); + $this->ossClient->getObject($this->bucket, $object, $options); + $this->assertEquals(md5_file($bigFileName), md5_file($localFilename)); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertFalse(true); + } + unlink($bigFileName); + unlink($localFilename); + } + + public function testMultipartUploadBigFileWithMD5Check() + { + $bigFileName = __DIR__ . DIRECTORY_SEPARATOR . "/bigfile.tmp"; + $localFilename = __DIR__ . DIRECTORY_SEPARATOR . "/localfile.tmp"; + OssUtil::generateFile($bigFileName, 6 * 1024 * 1024); + $object = 'mpu/multipart-bigfile-test.tmp'; + $options = array( + OssClient::OSS_CHECK_MD5 => true, + OssClient::OSS_PART_SIZE => 1, + ); + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $bigFileName, $options); + $options = array(OssClient::OSS_FILE_DOWNLOAD => $localFilename); + $this->ossClient->getObject($this->bucket, $object, $options); + $this->assertEquals(md5_file($bigFileName), md5_file($localFilename)); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertFalse(true); + } + unlink($bigFileName); + unlink($localFilename); + } + + public function testCopyPart() + { + $object = "mpu/multipart-test.txt"; + $copiedObject = "mpu/multipart-test.txt.copied"; + $this->ossClient->putObject($this->bucket, $copiedObject, file_get_contents(__FILE__)); + /** + * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. uploadPartCopy + */ + $copyId = 1; + $eTag = $this->ossClient->uploadPartCopy($this->bucket, $copiedObject, $this->bucket, $object, $copyId, $upload_id); + $upload_parts[] = array( + 'PartNumber' => $copyId, + 'ETag' => $eTag, + ); + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + try { + $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertTrue(false); + } + + $this->assertEquals($this->ossClient->getObject($this->bucket, $object), file_get_contents(__FILE__)); + $this->assertEquals($this->ossClient->getObject($this->bucket, $copiedObject), file_get_contents(__FILE__)); + } + + public function testAbortMultipartUpload() + { + $object = "mpu/multipart-test.txt"; + /** + * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. 上传分片 + */ + $part_size = 10 * 1024 * 1024; + $upload_file = __FILE__; + $upload_filesize = filesize($upload_file); + $pieces = $this->ossClient->generateMultiuploadParts($upload_filesize, $part_size); + $response_upload_part = array(); + $upload_position = 0; + $is_check_md5 = true; + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[OssClient::OSS_SEEK_TO]; + $to_pos = (integer)$piece[OssClient::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + OssClient::OSS_FILE_UPLOAD => $upload_file, + OssClient::OSS_PART_NUM => ($i + 1), + OssClient::OSS_SEEK_TO => $from_pos, + OssClient::OSS_LENGTH => $to_pos - $from_pos + 1, + OssClient::OSS_CHECK_MD5 => $is_check_md5, + ); + if ($is_check_md5) { + $content_md5 = OssUtil::getMd5SumForFile($upload_file, $from_pos, $to_pos); + $up_options[OssClient::OSS_CONTENT_MD5] = $content_md5; + } + //2. 将每一分片上传到OSS + try { + $response_upload_part[] = $this->ossClient->uploadPart($this->bucket, $object, $upload_id, $up_options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + $upload_parts = array(); + foreach ($response_upload_part as $i => $eTag) { + $upload_parts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + $this->assertEquals(1, count($listPartsInfo->getListPart())); + + $numOfMultipartUpload1 = 0; + $options = null; + try { + $listMultipartUploadInfo = $listMultipartUploadInfo = $this->ossClient->listMultipartUploads($this->bucket, $options); + $this->assertNotNull($listMultipartUploadInfo); + $numOfMultipartUpload1 = count($listMultipartUploadInfo->getUploads()); + } catch (OssException $e) { + $this->assertFalse(true); + } + + try { + $this->ossClient->abortMultipartUpload($this->bucket, $object, $upload_id); + } catch (OssException $e) { + $this->assertTrue(false); + } + + $numOfMultipartUpload2 = 0; + try { + $listMultipartUploadInfo = $listMultipartUploadInfo = $this->ossClient->listMultipartUploads($this->bucket, $options); + $this->assertNotNull($listMultipartUploadInfo); + $numOfMultipartUpload2 = count($listMultipartUploadInfo->getUploads()); + } catch (OssException $e) { + $this->assertFalse(true); + } + $this->assertEquals($numOfMultipartUpload1 - 1, $numOfMultipartUpload2); + } + + public function testPutObjectByRawApis() + { + $object = "mpu/multipart-test.txt"; + /** + * step 1. 初始化一个分块上传事件, 也就是初始化上传Multipart, 获取upload id + */ + try { + $upload_id = $this->ossClient->initiateMultipartUpload($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + /* + * step 2. 上传分片 + */ + $part_size = 10 * 1024 * 1024; + $upload_file = __FILE__; + $upload_filesize = filesize($upload_file); + $pieces = $this->ossClient->generateMultiuploadParts($upload_filesize, $part_size); + $response_upload_part = array(); + $upload_position = 0; + $is_check_md5 = true; + foreach ($pieces as $i => $piece) { + $from_pos = $upload_position + (integer)$piece[OssClient::OSS_SEEK_TO]; + $to_pos = (integer)$piece[OssClient::OSS_LENGTH] + $from_pos - 1; + $up_options = array( + OssClient::OSS_FILE_UPLOAD => $upload_file, + OssClient::OSS_PART_NUM => ($i + 1), + OssClient::OSS_SEEK_TO => $from_pos, + OssClient::OSS_LENGTH => $to_pos - $from_pos + 1, + OssClient::OSS_CHECK_MD5 => $is_check_md5, + ); + if ($is_check_md5) { + $content_md5 = OssUtil::getMd5SumForFile($upload_file, $from_pos, $to_pos); + $up_options[OssClient::OSS_CONTENT_MD5] = $content_md5; + } + //2. 将每一分片上传到OSS + try { + $response_upload_part[] = $this->ossClient->uploadPart($this->bucket, $object, $upload_id, $up_options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + $upload_parts = array(); + foreach ($response_upload_part as $i => $eTag) { + $upload_parts[] = array( + 'PartNumber' => ($i + 1), + 'ETag' => $eTag, + ); + } + + try { + $listPartsInfo = $this->ossClient->listParts($this->bucket, $object, $upload_id); + $this->assertNotNull($listPartsInfo); + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * step 3. + */ + try { + $this->ossClient->completeMultipartUpload($this->bucket, $object, $upload_id, $upload_parts); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + function testPutObjectsByDir() + { + $localDirectory = dirname(__FILE__); + $prefix = "samples/codes"; + try { + $this->ossClient->uploadDir($this->bucket, $prefix, $localDirectory); + } catch (OssException $e) { + var_dump($e->getMessage()); + $this->assertFalse(true); + + } + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, 'samples/codes/' . "OssClientMultipartUploadTest.php")); + } + + public function testPutObjectByMultipartUpload() + { + $object = "mpu/multipart-test.txt"; + $file = __FILE__; + $options = array(); + + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testPutObjectByMultipartUploadWithMD5Check() + { + $object = "mpu/multipart-test.txt"; + $file = __FILE__; + $options = array(OssClient::OSS_CHECK_MD5 => true); + + try { + $this->ossClient->multiuploadFile($this->bucket, $object, $file, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testListMultipartUploads() + { + $options = null; + try { + $listMultipartUploadInfo = $this->ossClient->listMultipartUploads($this->bucket, $options); + $this->assertNotNull($listMultipartUploadInfo); + } catch (OssException $e) { + $this->assertFalse(true); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientObjectTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientObjectTest.php new file mode 100755 index 0000000..028ae6c --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientObjectTest.php @@ -0,0 +1,588 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientObjectTest extends TestOssClientBase +{ + + public function testGetObjectMeta() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + + try { + $res = $this->ossClient->getObjectMeta($this->bucket, $object); + $this->assertEquals('200', $res['info']['http_code']); + $this->assertEquals('text/plain', $res['content-type']); + $this->assertEquals('Accept-Encoding', $res['vary']); + $this->assertTrue(isset($res['content-length'])); + $this->assertFalse(isset($res['content-encoding'])); + } catch (OssException $e) { + $this->assertTrue(false); + } + + $options = array(OssClient::OSS_HEADERS => array(OssClient::OSS_ACCEPT_ENCODING => 'deflate, gzip')); + + try { + $res = $this->ossClient->getObjectMeta($this->bucket, $object, $options); + $this->assertEquals('200', $res['info']['http_code']); + $this->assertEquals('text/plain', $res['content-type']); + $this->assertEquals('Accept-Encoding', $res['vary']); + $this->assertFalse(isset($res['content-length'])); + $this->assertEquals('gzip', $res['content-encoding']); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testGetObjectWithAcceptEncoding() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $options = array(OssClient::OSS_HEADERS => array(OssClient::OSS_ACCEPT_ENCODING => 'deflate, gzip')); + + try { + $res = $this->ossClient->getObject($this->bucket, $object, $options); + $this->assertEquals(file_get_contents(__FILE__), $res); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testGetObjectWithHeader() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $res = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_LAST_MODIFIED => "xx")); + $this->assertEquals(file_get_contents(__FILE__), $res); + } catch (OssException $e) { + $this->assertEquals('"/ilegal.txt" object name is invalid', $e->getMessage()); + } + } + + public function testGetObjectWithIleggalEtag() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $res = $this->ossClient->getObject($this->bucket, $object, array(OssClient::OSS_ETAG => "xx")); + $this->assertEquals(file_get_contents(__FILE__), $res); + } catch (OssException $e) { + $this->assertEquals('"/ilegal.txt" object name is invalid', $e->getMessage()); + } + } + + public function testObject() + { + /** + * Upload the local variable to bucket + */ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $content = file_get_contents(__FILE__); + $options = array( + OssClient::OSS_LENGTH => strlen($content), + OssClient::OSS_HEADERS => array( + 'Expires' => 'Fri, 28 Feb 2020 05:38:42 GMT', + 'Cache-Control' => 'no-cache', + 'Content-Disposition' => 'attachment;filename=oss_download.log', + 'Content-Encoding' => 'utf-8', + 'Content-Language' => 'zh-CN', + 'x-oss-server-side-encryption' => 'AES256', + 'x-oss-meta-self-define-title' => 'user define meta info', + ), + ); + + try { + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + try { + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + try { + $result = $this->ossClient->deleteObjects($this->bucket, "stringtype", $options); + $this->assertEquals('stringtype', $result[0]); + } catch (OssException $e) { + $this->assertEquals('objects must be array', $e->getMessage()); + } + + try { + $result = $this->ossClient->deleteObjects($this->bucket, "stringtype", $options); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('objects must be array', $e->getMessage()); + } + + try { + $this->ossClient->uploadFile($this->bucket, $object, "notexist.txt", $options); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('notexist.txt file does not exist', $e->getMessage()); + } + + /** + * GetObject to the local variable and check for match + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * GetObject first five bytes + */ + try { + $options = array(OssClient::OSS_RANGE => '0-4'); + $content = $this->ossClient->getObject($this->bucket, $object, $options); + $this->assertEquals($content, '<?php'); + } catch (OssException $e) { + $this->assertFalse(true); + } + + + /** + * Upload the local file to object + */ + try { + $this->ossClient->uploadFile($this->bucket, $object, __FILE__); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Download the file to the local variable and check for match. + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Download the file to the local file + */ + $localfile = "upload-test-object-name.txt"; + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $localfile, + ); + + try { + $this->ossClient->getObject($this->bucket, $object, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + $this->assertTrue(file_get_contents($localfile) === file_get_contents(__FILE__)); + if (file_exists($localfile)) { + unlink($localfile); + } + + /** + * Download the file to the local file. no such key + */ + $localfile = "upload-test-object-name-no-such-key.txt"; + $options = array( + OssClient::OSS_FILE_DOWNLOAD => $localfile, + ); + + try { + $this->ossClient->getObject($this->bucket, $object . "no-such-key", $options); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + $this->assertFalse(file_exists($localfile)); + if (strpos($e, "The specified key does not exist") == false) + { + $this->assertTrue(true); + } + } + + /** + * Download the file to the content. no such key + */ + try { + $result = $this->ossClient->getObject($this->bucket, $object . "no-such-key"); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertTrue(true); + if (strpos($e, "The specified key does not exist") == false) + { + $this->assertTrue(true); + } + } + + /** + * Copy object + */ + $to_bucket = $this->bucket; + $to_object = $object . '.copy'; + $options = array(); + try { + $result = $this->ossClient->copyObject($this->bucket, $object, $to_bucket, $to_object, $options); + $this->assertFalse(empty($result)); + $this->assertEquals(strlen("2016-11-21T03:46:58.000Z"), strlen($result[0])); + $this->assertEquals(strlen("\"5B3C1A2E053D763E1B002CC607C5A0FE\""), strlen($result[1])); + } catch (OssException $e) { + $this->assertFalse(true); + var_dump($e->getMessage()); + + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $to_object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * List the files in your bucket. + */ + $prefix = ''; + $delimiter = '/'; + $next_marker = ''; + $maxkeys = 1000; + $options = array( + 'delimiter' => $delimiter, + 'prefix' => $prefix, + 'max-keys' => $maxkeys, + 'marker' => $next_marker, + ); + + try { + $listObjectInfo = $this->ossClient->listObjects($this->bucket, $options); + $objectList = $listObjectInfo->getObjectList(); + $prefixList = $listObjectInfo->getPrefixList(); + $this->assertNotNull($objectList); + $this->assertNotNull($prefixList); + $this->assertTrue(is_array($objectList)); + $this->assertTrue(is_array($prefixList)); + + } catch (OssException $e) { + $this->assertTrue(false); + } + + /** + * Set the meta information for the file + */ + $from_bucket = $this->bucket; + $from_object = "oss-php-sdk-test/upload-test-object-name.txt"; + $to_bucket = $from_bucket; + $to_object = $from_object; + $copy_options = array( + OssClient::OSS_HEADERS => array( + 'Expires' => '2012-10-01 08:00:00', + 'Content-Disposition' => 'attachment; filename="xxxxxx"', + ), + ); + try { + $this->ossClient->copyObject($from_bucket, $from_object, $to_bucket, $to_object, $copy_options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Get the meta information for the file + */ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + try { + $objectMeta = $this->ossClient->getObjectMeta($this->bucket, $object); + $this->assertEquals('attachment; filename="xxxxxx"', $objectMeta[strtolower('Content-Disposition')]); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete single file + */ + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + + try { + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object)); + $this->ossClient->deleteObject($this->bucket, $object); + $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete multiple files + */ + $object1 = "oss-php-sdk-test/upload-test-object-name.txt"; + $object2 = "oss-php-sdk-test/upload-test-object-name.txt.copy"; + $list = array($object1, $object2); + try { + $this->assertTrue($this->ossClient->doesObjectExist($this->bucket, $object2)); + + $result = $this->ossClient->deleteObjects($this->bucket, $list); + $this->assertEquals($list[1], $result[0]); + $this->assertEquals($list[0], $result[1]); + + $result = $this->ossClient->deleteObjects($this->bucket, $list, array('quiet' => 'true')); + $this->assertEquals(array(), $result); + $this->assertFalse($this->ossClient->doesObjectExist($this->bucket, $object2)); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testAppendObject() + { + $object = "oss-php-sdk-test/append-test-object-name.txt"; + $content_array = array('Hello OSS', 'Hi OSS', 'OSS OK'); + + /** + * Append the upload string + */ + try { + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0); + $this->assertEquals($position, strlen($content_array[0])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $position); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[1])); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the content is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, implode($content_array)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Append the upload of local files + */ + try { + $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, 0); + $this->assertEquals($position, filesize(__FILE__)); + $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, $position); + $this->assertEquals($position, filesize(__FILE__) * 2); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__) . file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + + + $options = array( + OssClient::OSS_HEADERS => array( + 'Expires' => '2012-10-01 08:00:00', + 'Content-Disposition' => 'attachment; filename="xxxxxx"', + ), + ); + + /** + * Append upload with option + */ + try { + $position = $this->ossClient->appendObject($this->bucket, $object, "Hello OSS, ", 0, $options); + $position = $this->ossClient->appendObject($this->bucket, $object, "Hi OSS.", $position); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Get the meta information for the file + */ + try { + $objectMeta = $this->ossClient->getObjectMeta($this->bucket, $object); + $this->assertEquals('attachment; filename="xxxxxx"', $objectMeta[strtolower('Content-Disposition')]); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testPutIllelObject() + { + $object = "/ilegal.txt"; + try { + $this->ossClient->putObject($this->bucket, $object, "hi", null); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('"/ilegal.txt" object name is invalid', $e->getMessage()); + } + } + + public function testCheckMD5() + { + $object = "oss-php-sdk-test/upload-test-object-name.txt"; + $content = file_get_contents(__FILE__); + $options = array(OssClient::OSS_CHECK_MD5 => true); + + /** + * Upload data to start MD5 + */ + try { + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Upload file to start MD5 + */ + try { + $this->ossClient->uploadFile($this->bucket, $object, __FILE__, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $object = "oss-php-sdk-test/append-test-object-name.txt"; + $content_array = array('Hello OSS', 'Hi OSS', 'OSS OK'); + $options = array(OssClient::OSS_CHECK_MD5 => true); + + /** + * Append the upload string + */ + try { + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[0], 0, $options); + $this->assertEquals($position, strlen($content_array[0])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[1], $position, $options); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1])); + $position = $this->ossClient->appendObject($this->bucket, $object, $content_array[2], $position, $options); + $this->assertEquals($position, strlen($content_array[0]) + strlen($content_array[1]) + strlen($content_array[1])); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the content is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, implode($content_array)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Append upload of local files + */ + try { + $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, 0, $options); + $this->assertEquals($position, filesize(__FILE__)); + $position = $this->ossClient->appendFile($this->bucket, $object, __FILE__, $position, $options); + $this->assertEquals($position, filesize(__FILE__) * 2); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * Check if the replication is the same + */ + try { + $content = $this->ossClient->getObject($this->bucket, $object); + $this->assertEquals($content, file_get_contents(__FILE__) . file_get_contents(__FILE__)); + } catch (OssException $e) { + $this->assertFalse(true); + } + + /** + * delete test object + */ + try { + $this->ossClient->deleteObject($this->bucket, $object); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function setUp() + { + parent::setUp(); + $this->ossClient->putObject($this->bucket, 'oss-php-sdk-test/upload-test-object-name.txt', file_get_contents(__FILE__)); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientRestoreObjectTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientRestoreObjectTest.php new file mode 100755 index 0000000..cc1412f --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientRestoreObjectTest.php @@ -0,0 +1,96 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientRestoreObjectTest extends TestOssClientBase +{ + private $iaBucket; + private $archiveBucket; + + public function testIARestoreObject() + { + $object = 'storage-object'; + + $this->ossClient->putObject($this->iaBucket, $object,'testcontent'); + try{ + $this->ossClient->restoreObject($this->iaBucket, $object); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('400', $e->getHTTPStatus()); + $this->assertEquals('OperationNotSupported', $e->getErrorCode()); + } + } + + public function testNullObjectRestoreObject() + { + $object = 'null-object'; + + try{ + $this->ossClient->restoreObject($this->bucket, $object); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('404', $e->getHTTPStatus()); + } + } + + public function testArchiveRestoreObject() + { + $object = 'storage-object'; + + $this->ossClient->putObject($this->archiveBucket, $object,'testcontent'); + try{ + $this->ossClient->getObject($this->archiveBucket, $object); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('403', $e->getHTTPStatus()); + $this->assertEquals('InvalidObjectState', $e->getErrorCode()); + } + $result = $this->ossClient->restoreObject($this->archiveBucket, $object); + common::waitMetaSync(); + $this->assertEquals('202', $result['info']['http_code']); + + try{ + $this->ossClient->restoreObject($this->archiveBucket, $object); + }catch(OssException $e){ + $this->assertEquals('409', $e->getHTTPStatus()); + $this->assertEquals('RestoreAlreadyInProgress', $e->getErrorCode()); + } + } + + public function setUp() + { + parent::setUp(); + + $this->iaBucket = 'ia-' . $this->bucket; + $this->archiveBucket = 'archive-' . $this->bucket; + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_IA + ); + + $this->ossClient->createBucket($this->iaBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + + $options = array( + OssClient::OSS_STORAGE => OssClient::OSS_STORAGE_ARCHIVE + ); + + $this->ossClient->createBucket($this->archiveBucket, OssClient::OSS_ACL_TYPE_PRIVATE, $options); + } + + public function tearDown() + { + parent::tearDown(); + + $object = 'storage-object'; + + $this->ossClient->deleteObject($this->iaBucket, $object); + $this->ossClient->deleteObject($this->archiveBucket, $object); + $this->ossClient->deleteBucket($this->iaBucket); + $this->ossClient->deleteBucket($this->archiveBucket); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientSignatureTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientSignatureTest.php new file mode 100755 index 0000000..109121d --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientSignatureTest.php @@ -0,0 +1,111 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Http\RequestCore; +use OSS\Http\ResponseCore; +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + + +class OssClientSignatureTest extends TestOssClientBase +{ + function testGetSignedUrlForGettingObject() + { + $object = "a.file"; + $this->ossClient->putObject($this->bucket, $object, file_get_contents(__FILE__)); + $timeout = 3600; + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout); + } catch (OssException $e) { + $this->assertFalse(true); + } + + $request = new RequestCore($signedUrl); + $request->set_method('GET'); + $request->add_header('Content-Type', ''); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code()); + $this->assertEquals(file_get_contents(__FILE__), $res->body); + } + + public function testGetSignedUrlForPuttingObject() + { + $object = "a.file"; + $timeout = 3600; + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT"); + $content = file_get_contents(__FILE__); + $request = new RequestCore($signedUrl); + $request->set_method('PUT'); + $request->add_header('Content-Type', ''); + $request->add_header('Content-Length', strlen($content)); + $request->set_body($content); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), + $request->get_response_body(), $request->get_response_code()); + $this->assertTrue($res->isOK()); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testGetSignedUrlForPuttingObjectFromFile() + { + $file = __FILE__; + $object = "a.file"; + $timeout = 3600; + $options = array('Content-Type' => 'txt'); + try { + $signedUrl = $this->ossClient->signUrl($this->bucket, $object, $timeout, "PUT", $options); + $request = new RequestCore($signedUrl); + $request->set_method('PUT'); + $request->add_header('Content-Type', 'txt'); + $request->set_read_file($file); + $request->set_read_stream_size(filesize($file)); + $request->send_request(); + $res = new ResponseCore($request->get_response_header(), + $request->get_response_body(), $request->get_response_code()); + $this->assertTrue($res->isOK()); + } catch (OssException $e) { + $this->assertFalse(true); + } + + } + + public function tearDown() + { + $this->ossClient->deleteObject($this->bucket, "a.file"); + parent::tearDown(); + } + + public function setUp() + { + parent::setUp(); + /** + * 上传本地变量到bucket + */ + $object = "a.file"; + $content = file_get_contents(__FILE__); + $options = array( + OssClient::OSS_LENGTH => strlen($content), + OssClient::OSS_HEADERS => array( + 'Expires' => 'Fri, 28 Feb 2020 05:38:42 GMT', + 'Cache-Control' => 'no-cache', + 'Content-Disposition' => 'attachment;filename=oss_download.log', + 'Content-Encoding' => 'utf-8', + 'Content-Language' => 'zh-CN', + 'x-oss-server-side-encryption' => 'AES256', + 'x-oss-meta-self-define-title' => 'user define meta info', + ), + ); + + try { + $this->ossClient->putObject($this->bucket, $object, $content, $options); + } catch (OssException $e) { + $this->assertFalse(true); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssClientTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssClientTest.php new file mode 100755 index 0000000..f92b346 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssClientTest.php @@ -0,0 +1,216 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\OssClient; + + +class OssClientTest extends \PHPUnit_Framework_TestCase +{ + public function testConstrunct() + { + try { + $ossClient = new OssClient('id', 'key', 'http://oss-cn-hangzhou.aliyuncs.com'); + $this->assertFalse($ossClient->isUseSSL()); + $ossClient->setUseSSL(true); + $this->assertTrue($ossClient->isUseSSL()); + $this->assertTrue(true); + $this->assertEquals(3, $ossClient->getMaxRetries()); + $ossClient->setMaxTries(4); + $this->assertEquals(4, $ossClient->getMaxRetries()); + $ossClient->setTimeout(10); + $ossClient->setConnectTimeout(20); + } catch (OssException $e) { + assertFalse(true); + } + } + + public function testConstrunct2() + { + try { + $ossClient = new OssClient('id', "", 'http://oss-cn-hangzhou.aliyuncs.com'); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals("access key secret is empty", $e->getMessage()); + } + } + + public function testConstrunct3() + { + try { + $ossClient = new OssClient("", 'key', 'http://oss-cn-hangzhou.aliyuncs.com'); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals("access key id is empty", $e->getMessage()); + } + } + + public function testConstrunct4() + { + try { + $ossClient = new OssClient('id', 'key', ""); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('endpoint is empty', $e->getMessage()); + } + } + + public function testConstrunct5() + { + try { + $ossClient = new OssClient('id', 'key', "123.123.123.1"); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testConstrunct6() + { + try { + $ossClient = new OssClient('id', 'key', "https://123.123.123.1"); + $this->assertTrue($ossClient->isUseSSL()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testConstrunct7() + { + try { + $ossClient = new OssClient('id', 'key', "http://123.123.123.1"); + $this->assertFalse($ossClient->isUseSSL()); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + public function testConstrunct8() + { + try { + $ossClient = new OssClient('id', 'key', "http://123.123.123.1", true); + $ossClient->listBuckets(); + $this->assertFalse(true); + } catch (OssException $e) { + + } + } + + public function testConstrunct9() + { + try { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + $ossClient->listBuckets(); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testSupportPutEmptyObject() + { + try { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret , $endpoint, false); + $ossClient->putObject($bucket,'test_emptybody',''); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testCreateObjectDir() + { + try { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET'); + $object='test-dir'; + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + $ossClient->createObjectDir($bucket,$object); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testGetBucketCors() + { + try { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + $ossClient->getBucketCors($bucket); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testGetBucketCname() + { + try { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET'); + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false); + $ossClient->getBucketCname($bucket); + } catch (OssException $e) { + $this->assertFalse(true); + } + } + + public function testProxySupport() + { + $accessKeyId = ' ' . getenv('OSS_ACCESS_KEY_ID') . ' '; + $accessKeySecret = ' ' . getenv('OSS_ACCESS_KEY_SECRET') . ' '; + $endpoint = ' ' . getenv('OSS_ENDPOINT') . '/ '; + $bucket = getenv('OSS_BUCKET') . '-proxy'; + $requestProxy = getenv('OSS_PROXY'); + $key = 'test-proxy-srv-object'; + $content = 'test-content'; + $proxys = parse_url($requestProxy); + + $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, null, $requestProxy); + + $result = $ossClient->createBucket($bucket); + $this->checkProxy($result, $proxys); + + $result = $ossClient->putObject($bucket, $key, $content); + $this->checkProxy($result, $proxys); + $result = $ossClient->getObject($bucket, $key); + $this->assertEquals($content, $result); + + // list object + $objectListInfo = $ossClient->listObjects($bucket); + $objectList = $objectListInfo->getObjectList(); + $this->assertNotNull($objectList); + $this->assertTrue(is_array($objectList)); + $objects = array(); + foreach ($objectList as $value) { + $objects[] = $value->getKey(); + } + $this->assertEquals(1, count($objects)); + $this->assertTrue(in_array($key, $objects)); + + $result = $ossClient->deleteObject($bucket, $key); + $this->checkProxy($result,$proxys); + + $result = $ossClient->deleteBucket($bucket); + $this->checkProxy($result, $proxys); + } + + private function checkProxy($result, $proxys) + { + $this->assertEquals($result['info']['primary_ip'], $proxys['host']); + $this->assertEquals($result['info']['primary_port'], $proxys['port']); + $this->assertTrue(array_key_exists('via', $result)); + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssExceptionTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssExceptionTest.php new file mode 100755 index 0000000..4a418d5 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssExceptionTest.php @@ -0,0 +1,19 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; + +class OssExceptionTest extends \PHPUnit_Framework_TestCase +{ + public function testOSS_exception() + { + try { + throw new OssException("ERR"); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertNotNull($e); + $this->assertEquals($e->getMessage(), "ERR"); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/OssUtilTest.php b/vendor/oss-sdk/tests/OSS/Tests/OssUtilTest.php new file mode 100755 index 0000000..adf6457 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/OssUtilTest.php @@ -0,0 +1,225 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Core\OssException; +use OSS\Core\OssUtil; +use OSS\OssClient; + +class OssUtilTest extends \PHPUnit_Framework_TestCase +{ + public function testIsChinese() + { + $this->assertEquals(OssUtil::chkChinese("hello,world"), 0); + $str = '你好,这里是卖咖啡!'; + $strGBK = OssUtil::encodePath($str); + $this->assertEquals(OssUtil::chkChinese($str), 1); + $this->assertEquals(OssUtil::chkChinese($strGBK), 1); + } + + public function testIsGB2312() + { + $str = '你好,这里是卖咖啡!'; + $this->assertFalse(OssUtil::isGb2312($str)); + } + + public function testCheckChar() + { + $str = '你好,这里是卖咖啡!'; + $this->assertFalse(OssUtil::checkChar($str)); + $this->assertTrue(OssUtil::checkChar(iconv("UTF-8", "GB2312//IGNORE", $str))); + } + + public function testIsIpFormat() + { + $this->assertTrue(OssUtil::isIPFormat("10.101.160.147")); + $this->assertTrue(OssUtil::isIPFormat("12.12.12.34")); + $this->assertTrue(OssUtil::isIPFormat("12.12.12.12")); + $this->assertTrue(OssUtil::isIPFormat("255.255.255.255")); + $this->assertTrue(OssUtil::isIPFormat("0.1.1.1")); + $this->assertFalse(OssUtil::isIPFormat("0.1.1.x")); + $this->assertFalse(OssUtil::isIPFormat("0.1.1.256")); + $this->assertFalse(OssUtil::isIPFormat("256.1.1.1")); + $this->assertFalse(OssUtil::isIPFormat("0.1.1.0.1")); + $this->assertTrue(OssUtil::isIPFormat("10.10.10.10:123")); + } + + public function testToQueryString() + { + $option = array("a" => "b"); + $this->assertEquals('a=b', OssUtil::toQueryString($option)); + } + + public function testSReplace() + { + $str = "<>&'\""; + $this->assertEquals("&amp;lt;&amp;gt;&amp;&apos;&quot;", OssUtil::sReplace($str)); + } + + public function testCheckChinese() + { + $str = '你好,这里是卖咖啡!'; + $this->assertEquals(OssUtil::chkChinese($str), 1); + if (OssUtil::isWin()) { + $strGB = OssUtil::encodePath($str); + $this->assertEquals($str, iconv("GB2312", "UTF-8", $strGB)); + } + } + + public function testValidateOption() + { + $option = 'string'; + + try { + OssUtil::validateOptions($option); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals("string:option must be array", $e->getMessage()); + } + + $option = null; + + try { + OssUtil::validateOptions($option); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertFalse(true); + } + + } + + public function testCreateDeleteObjectsXmlBody() + { + $xml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?><Delete><Quiet>true</Quiet><Object><Key>obj1</Key></Object></Delete> +BBBB; + $a = array('obj1'); + $this->assertEquals($xml, $this->cleanXml(OssUtil::createDeleteObjectsXmlBody($a, 'true'))); + } + + public function testCreateCompleteMultipartUploadXmlBody() + { + $xml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?><CompleteMultipartUpload><Part><PartNumber>2</PartNumber><ETag>xx</ETag></Part></CompleteMultipartUpload> +BBBB; + $a = array(array("PartNumber" => 2, "ETag" => "xx")); + $this->assertEquals($this->cleanXml(OssUtil::createCompleteMultipartUploadXmlBody($a)), $xml); + } + + public function testCreateBucketXmlBody() + { + $xml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?><CreateBucketConfiguration><StorageClass>Standard</StorageClass></CreateBucketConfiguration> +BBBB; + $storageClass ="Standard"; + $this->assertEquals($this->cleanXml(OssUtil::createBucketXmlBody($storageClass)), $xml); + } + + public function testValidateBucket() + { + $this->assertTrue(OssUtil::validateBucket("xxx")); + $this->assertFalse(OssUtil::validateBucket("XXXqwe123")); + $this->assertFalse(OssUtil::validateBucket("XX")); + $this->assertFalse(OssUtil::validateBucket("/X")); + $this->assertFalse(OssUtil::validateBucket("")); + } + + public function testValidateObject() + { + $this->assertTrue(OssUtil::validateObject("xxx")); + $this->assertTrue(OssUtil::validateObject("xxx23")); + $this->assertTrue(OssUtil::validateObject("12321-xxx")); + $this->assertTrue(OssUtil::validateObject("x")); + $this->assertFalse(OssUtil::validateObject("/aa")); + $this->assertFalse(OssUtil::validateObject("\\aa")); + $this->assertFalse(OssUtil::validateObject("")); + } + + public function testStartWith() + { + $this->assertTrue(OssUtil::startsWith("xxab", "xx"), true); + } + + public function testReadDir() + { + $list = OssUtil::readDir("./src", ".|..|.svn|.git", true); + $this->assertNotNull($list); + } + + public function testIsWin() + { + //$this->assertTrue(OssUtil::isWin()); + } + + public function testGetMd5SumForFile() + { + $this->assertEquals(OssUtil::getMd5SumForFile(__FILE__, 0, filesize(__FILE__) - 1), base64_encode(md5(file_get_contents(__FILE__), true))); + } + + public function testGenerateFile() + { + $path = __DIR__ . DIRECTORY_SEPARATOR . "generatedFile.txt"; + OssUtil::generateFile($path, 1024 * 1024); + $this->assertEquals(filesize($path), 1024 * 1024); + unlink($path); + } + + public function testThrowOssExceptionWithMessageIfEmpty() + { + $null = null; + try { + OssUtil::throwOssExceptionWithMessageIfEmpty($null, "xx"); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('xx', $e->getMessage()); + } + } + + public function testThrowOssExceptionWithMessageIfEmpty2() + { + $null = ""; + try { + OssUtil::throwOssExceptionWithMessageIfEmpty($null, "xx"); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('xx', $e->getMessage()); + } + } + + public function testValidContent() + { + $null = ""; + try { + OssUtil::validateContent($null); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('http body content is invalid', $e->getMessage()); + } + + $notnull = "x"; + try { + OssUtil::validateContent($notnull); + $this->assertTrue(true); + } catch (OssException $e) { + $this->assertEquals('http body content is invalid', $e->getMessage()); + } + } + + public function testThrowOssExceptionWithMessageIfEmpty3() + { + $null = "xx"; + try { + OssUtil::throwOssExceptionWithMessageIfEmpty($null, "xx"); + $this->assertTrue(True); + } catch (OssException $e) { + $this->assertTrue(false); + } + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } + +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/PutSetDeleteResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/PutSetDeleteResultTest.php new file mode 100755 index 0000000..b298e44 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/PutSetDeleteResultTest.php @@ -0,0 +1,66 @@ +<?php + +namespace OSS\Tests; + +use OSS\Core\OssException; +use OSS\Http\ResponseCore; +use OSS\Result\PutSetDeleteResult; + +class ResultTest extends \PHPUnit_Framework_TestCase +{ + + public function testNullResponse() + { + $response = null; + try { + new PutSetDeleteResult($response); + $this->assertFalse(true); + } catch (OssException $e) { + $this->assertEquals('raw response is null', $e->getMessage()); + } + } + + public function testOkResponse() + { + $header= array( + 'x-oss-request-id' => '582AA51E004C4550BD27E0E4', + 'etag' => '595FA1EA77945233921DF12427F9C7CE', + 'content-md5' => 'WV+h6neUUjOSHfEkJ/nHzg==', + 'info' => array( + 'http_code' => '200', + 'method' => 'PUT' + ), + ); + $response = new ResponseCore($header, "this is a mock body, just for test", 200); + $result = new PutSetDeleteResult($response); + $data = $result->getData(); + $this->assertTrue($result->isOK()); + $this->assertEquals("this is a mock body, just for test", $data['body']); + $this->assertEquals('582AA51E004C4550BD27E0E4', $data['x-oss-request-id']); + $this->assertEquals('595FA1EA77945233921DF12427F9C7CE', $data['etag']); + $this->assertEquals('WV+h6neUUjOSHfEkJ/nHzg==', $data['content-md5']); + $this->assertEquals('200', $data['info']['http_code']); + $this->assertEquals('PUT', $data['info']['method']); + } + + public function testFailResponse() + { + $response = new ResponseCore(array(), "", 301); + try { + new PutSetDeleteResult($response); + $this->assertFalse(true); + } catch (OssException $e) { + + } + } + + public function setUp() + { + + } + + public function tearDown() + { + + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/RefererConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/RefererConfigTest.php new file mode 100755 index 0000000..8360a24 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/RefererConfigTest.php @@ -0,0 +1,54 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Model\RefererConfig; + +class RefererConfigTest extends \PHPUnit_Framework_TestCase +{ + + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<RefererConfiguration> +<AllowEmptyReferer>true</AllowEmptyReferer> +<RefererList> +<Referer>http://www.aliyun.com</Referer> +<Referer>https://www.aliyun.com</Referer> +<Referer>http://www.*.com</Referer> +<Referer>https://www.?.aliyuncs.com</Referer> +</RefererList> +</RefererConfiguration> +BBBB; + + private $validXml2 = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<RefererConfiguration> +<AllowEmptyReferer>true</AllowEmptyReferer> +<RefererList> +<Referer>http://www.aliyun.com</Referer> +</RefererList> +</RefererConfiguration> +BBBB; + + public function testParseValidXml() + { + $refererConfig = new RefererConfig(); + $refererConfig->parseFromXml($this->validXml); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($refererConfig->serializeToXml())); + } + + public function testParseValidXml2() + { + $refererConfig = new RefererConfig(); + $refererConfig->parseFromXml($this->validXml2); + $this->assertEquals(true, $refererConfig->isAllowEmptyReferer()); + $this->assertEquals(1, count($refererConfig->getRefererList())); + $this->assertEquals($this->cleanXml($this->validXml2), $this->cleanXml(strval($refererConfig))); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/StorageCapacityTest.php b/vendor/oss-sdk/tests/OSS/Tests/StorageCapacityTest.php new file mode 100755 index 0000000..4562da7 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/StorageCapacityTest.php @@ -0,0 +1,59 @@ +<?php +namespace OSS\Tests; + +use OSS\Http\ResponseCore; +use OSS\Model\StorageCapacityConfig; +use OSS\Result\GetStorageCapacityResult; +use OSS\Core\OssException; + +class StorageCapacityTest extends \PHPUnit_Framework_TestCase +{ + + private $inValidXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<BucketUserQos> + <OssStorageCapacity>1</OssStorageCapacity> +</BucketUserQos> +BBBB; + + private $validXml = <<<BBBB +<?xml version="1.0" encoding="UTF-8"?> +<BucketUserQos> + <StorageCapacity>1</StorageCapacity> +</BucketUserQos> +BBBB; + + public function testParseInValidXml() + { + $response = new ResponseCore(array(), $this->inValidXml, 300); + try { + new GetStorageCapacityResult($response); + $this->assertTrue(false); + } catch (OssException $e) {} + } + + public function testParseEmptyXml() + { + $response = new ResponseCore(array(), "", 300); + try { + new GetStorageCapacityResult($response); + $this->assertTrue(false); + } catch (OssException $e) {} + } + + public function testParseValidXml() + { + $response = new ResponseCore(array(), $this->validXml, 200); + $result = new GetStorageCapacityResult($response); + $this->assertEquals($result->getData(), 1); + } + + public function testSerializeToXml() + { + $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<BucketUserQos><StorageCapacity>1</StorageCapacity></BucketUserQos>\n"; + + $storageCapacityConfig = new StorageCapacityConfig(1); + $content = $storageCapacityConfig->serializeToXml(); + $this->assertEquals($content, $xml); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/SymlinkTest.php b/vendor/oss-sdk/tests/OSS/Tests/SymlinkTest.php new file mode 100755 index 0000000..d257c94 --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/SymlinkTest.php @@ -0,0 +1,74 @@ +<?php + +namespace OSS\Tests; + +use OSS\OssClient; +use OSS\Result\SymlinkResult; +use OSS\Core\OssException; +use OSS\Http\ResponseCore; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'TestOssClientBase.php'; + +class SymlinkTest extends TestOssClientBase +{ + public function testPutSymlink() + { + $bucket = getenv('OSS_BUCKET'); + $symlink = 'test-link'; + $special_object = 'exist_object^$#!~'; + $object = 'exist_object'; + + $this->ossClient ->putObject($bucket, $object, 'test_content'); + $this->ossClient->putSymlink($bucket, $symlink, $object); + $result = $this->ossClient->getObject($bucket, $symlink); + $this->assertEquals('test_content', $result); + + $this->ossClient ->putObject($bucket, $special_object, 'test_content'); + $this->ossClient->putSymlink($bucket, $symlink, $special_object); + $result = $this->ossClient->getObject($bucket, $symlink); + $this->assertEquals('test_content', $result); + } + + public function testGetSymlink() + { + $bucket = getenv('OSS_BUCKET'); + $symlink = 'test-link'; + $object = 'exist_object^$#!~'; + + $result = $this->ossClient->getSymlink($bucket, $symlink); + $this->assertEquals($result[OssClient::OSS_SYMLINK_TARGET], $object); + $this->assertEquals('200', $result[OssClient::OSS_INFO][OssClient::OSS_HTTP_CODE]); + $this->assertTrue(isset($result[OssClient::OSS_ETAG])); + $this->assertTrue(isset($result[OssClient::OSS_REQUEST_ID])); + } + + public function testPutNullSymlink() + { + $bucket = getenv('OSS_BUCKET'); + $symlink = 'null-link'; + $object_not_exist = 'not_exist_object+$#!b不'; + $this->ossClient->putSymlink($bucket, $symlink, $object_not_exist); + + try{ + $this->ossClient->getObject($bucket, $symlink); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('The symlink target object does not exist', $e->getErrorMessage()); + } + } + + public function testGetNullSymlink() + { + $bucket = getenv('OSS_BUCKET'); + $symlink = 'null-link-new'; + + try{ + $result = $this->ossClient->getSymlink($bucket, $symlink); + $this->assertTrue(false); + }catch (OssException $e){ + $this->assertEquals('The specified key does not exist.', $e->getErrorMessage()); + } + } +} + + diff --git a/vendor/oss-sdk/tests/OSS/Tests/TestOssClientBase.php b/vendor/oss-sdk/tests/OSS/Tests/TestOssClientBase.php new file mode 100755 index 0000000..4abd31f --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/TestOssClientBase.php @@ -0,0 +1,51 @@ +<?php + +namespace OSS\Tests; + +use OSS\OssClient; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'Common.php'; + +class TestOssClientBase extends \PHPUnit_Framework_TestCase +{ + /** + * @var OssClient + */ + protected $ossClient; + + /** + * @var string + */ + protected $bucket; + + public function setUp() + { + $this->bucket = Common::getBucketName() . rand(100000, 999999); + $this->ossClient = Common::getOssClient(); + $this->ossClient->createBucket($this->bucket); + Common::waitMetaSync(); + } + + public function tearDown() + { + if (!$this->ossClient->doesBucketExist($this->bucket)) { + return; + } + + $objects = $this->ossClient->listObjects( + $this->bucket, array('max-keys' => 1000, 'delimiter' => ''))->getObjectList(); + $keys = array(); + foreach ($objects as $obj) { + $keys[] = $obj->getKey(); + } + if (count($keys) > 0) { + $this->ossClient->deleteObjects($this->bucket, $keys); + } + $uploads = $this->ossClient->listMultipartUploads($this->bucket)->getUploads(); + foreach ($uploads as $up) { + $this->ossClient->abortMultipartUpload($this->bucket, $up->getKey(), $up->getUploadId()); + } + + $this->ossClient->deleteBucket($this->bucket); + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/UploadPartResultTest.php b/vendor/oss-sdk/tests/OSS/Tests/UploadPartResultTest.php new file mode 100755 index 0000000..e4789ef --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/UploadPartResultTest.php @@ -0,0 +1,33 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Core\OssException; +use OSS\Result\UploadPartResult; +use OSS\Http\ResponseCore; + +class UploadPartResultTest extends \PHPUnit_Framework_TestCase +{ + private $validHeader = array('etag' => '7265F4D211B56873A381D321F586E4A9'); + private $invalidHeader = array(); + + public function testParseValidHeader() + { + $response = new ResponseCore($this->validHeader, "", 200); + $result = new UploadPartResult($response); + $eTag = $result->getData(); + $this->assertEquals('7265F4D211B56873A381D321F586E4A9', $eTag); + } + + public function testParseInvalidHeader() + { + $response = new ResponseCore($this->invalidHeader, "", 200); + try { + new UploadPartResult($response); + $this->assertTrue(false); + } catch (OssException $e) { + $this->assertEquals('cannot get ETag', $e->getMessage()); + } + } +} diff --git a/vendor/oss-sdk/tests/OSS/Tests/WebsiteConfigTest.php b/vendor/oss-sdk/tests/OSS/Tests/WebsiteConfigTest.php new file mode 100755 index 0000000..2ec0fcb --- /dev/null +++ b/vendor/oss-sdk/tests/OSS/Tests/WebsiteConfigTest.php @@ -0,0 +1,56 @@ +<?php + +namespace OSS\Tests; + + +use OSS\Model\WebsiteConfig; + +class WebsiteConfigTest extends \PHPUnit_Framework_TestCase +{ + private $validXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?> +<WebsiteConfiguration> +<IndexDocument> +<Suffix>index.html</Suffix> +</IndexDocument> +<ErrorDocument> +<Key>errorDocument.html</Key> +</ErrorDocument> +</WebsiteConfiguration> +BBBB; + + private $nullXml = <<<BBBB +<?xml version="1.0" encoding="utf-8"?><WebsiteConfiguration><IndexDocument><Suffix/></IndexDocument><ErrorDocument><Key/></ErrorDocument></WebsiteConfiguration> +BBBB; + private $nullXml2 = <<<BBBB +<?xml version="1.0" encoding="utf-8"?><WebsiteConfiguration><IndexDocument><Suffix></Suffix></IndexDocument><ErrorDocument><Key></Key></ErrorDocument></WebsiteConfiguration> +BBBB; + + public function testParseValidXml() + { + $websiteConfig = new WebsiteConfig("index"); + $websiteConfig->parseFromXml($this->validXml); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($websiteConfig->serializeToXml())); + } + + public function testParsenullXml() + { + $websiteConfig = new WebsiteConfig(); + $websiteConfig->parseFromXml($this->nullXml); + $this->assertTrue($this->cleanXml($this->nullXml) === $this->cleanXml($websiteConfig->serializeToXml()) || + $this->cleanXml($this->nullXml2) === $this->cleanXml($websiteConfig->serializeToXml())); + } + + public function testWebsiteConstruct() + { + $websiteConfig = new WebsiteConfig("index.html", "errorDocument.html"); + $this->assertEquals('index.html', $websiteConfig->getIndexDocument()); + $this->assertEquals('errorDocument.html', $websiteConfig->getErrorDocument()); + $this->assertEquals($this->cleanXml($this->validXml), $this->cleanXml($websiteConfig->serializeToXml())); + } + + private function cleanXml($xml) + { + return str_replace("\n", "", str_replace("\r", "", $xml)); + } +} diff --git a/vendor/swoole/.github/ISSUE_TEMPLATE b/vendor/swoole/.github/ISSUE_TEMPLATE new file mode 100755 index 0000000..7d9dd94 --- /dev/null +++ b/vendor/swoole/.github/ISSUE_TEMPLATE @@ -0,0 +1,28 @@ +Please answer these questions before submitting your issue. Thanks! + +1. What did you do? If possible, provide a recipe for reproducing the error. + + + +2. What did you expect to see? + + + +3. What did you see instead? + + + +4. What version of Swoole are you using (`php --ri swoole`)? + + + + +5. What is your machine environment used (including version of kernel & php & gcc) ? + + + +6. If you are using ssl, what is your openssl version? + + + + diff --git a/vendor/swoole/.gitignore b/vendor/swoole/.gitignore new file mode 100755 index 0000000..9e1de9a --- /dev/null +++ b/vendor/swoole/.gitignore @@ -0,0 +1,81 @@ +/.cproject +/.idea +/.project +/examples/yield/ +*.o +*.lo +*~ +*.so +*.loT +*.pid +Debug/* +modules/* +/.deps +/.libs/ +/core +/examples/core +/Debug +/CMakeFiles +/cmake_install.cmake +/CMakeCache.txt +/Makefile +/server +/lib +/bin +/install_manifest.txt +/wiki +/config.guess +/config.h +/config.h.in +/config.log +/config.nice +/config.status +/config.sub +/configure +/configure.in +/Makefile.fragments +/Makefile.global +/Makefile.objects +/install-sh +/libtool +/ltmain.sh +/missing +/mkinstalldirs +/swoole.la +/acinclude.m4 +/aclocal.m4 +/run-tests.php +/autom4te.cache +/build +/examples/async/data.txt +/examples/.idea +/examples/recv_file.jpg +/modules +/examples/async/test.copy +/examples/ssl_client +/examples/ssl/ca.crt +/examples/ssl/client.key +/examples/ssl/client.pfx +/examples/ssl/client +/examples/ssl/corpssl.crt +/examples/ssl/corpssl.key +/examples/ext +/examples/cpp_module/.cproject +/examples/cpp_module/.project +/benchmark/.idea/ +examples/c_module/.cproject +examples/c_module/.project +/tools/.idea/ +/tmp-php.ini +.settings/ +tests/.idea +/tests/*/*.log +/tests/*/*.sh +/tests/*/*.diff +/tests/*/*.out +/tests/*/*.exp +/tests/*/*.php +cmake-build-debug/ +*.cbp +/.vscode +/configure.ac diff --git a/vendor/swoole/.gitmodules b/vendor/swoole/.gitmodules new file mode 100755 index 0000000..94bcda4 --- /dev/null +++ b/vendor/swoole/.gitmodules @@ -0,0 +1,12 @@ +[submodule "thirdparty/hiredis"] + path = thirdparty/hiredis + url = https://github.com/redis/hiredis.git +[submodule "thirdparty/nghttp2"] + path = thirdparty/nghttp2 + url = https://github.com/nghttp2/nghttp2.git +[submodule "thirdparty/picohttpparser"] + path = thirdparty/picohttpparser + url = https://github.com/h2o/picohttpparser.git +[submodule "thirdparty/jemalloc"] + path = thirdparty/jemalloc + url = https://github.com/jemalloc/jemalloc.git diff --git a/vendor/swoole/.travis.yml b/vendor/swoole/.travis.yml new file mode 100755 index 0000000..0301ad0 --- /dev/null +++ b/vendor/swoole/.travis.yml @@ -0,0 +1,42 @@ +language: php + +compiler: + - gcc + - clang + +os: + - linux +# - osx + +php: + - 7.1 + - 7.2 + +notifications: + email: team@swoole.com + +env: + global: + - secure: "Mqg9ifSV0BLv2TIBw/x64aEuB8Y5aPXwXg7xAOq08oPlHBYSBgSYxroJL5PXs0fe7PszZF20bUBinwmEXYQzqgP/40Y1kmq/kfTsDXwTOc9qbAbA1pWvH+Sk1kDP5MLJRPWBCkqctyFd0I0u0SdzT1fgSqirqEz2bMnbAUVpSvo=" + +before_install: + - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- + +addons: + coverity_scan: + project: + name: "swoole/swoole-src" + description: "Build submitted via Travis CI" + notification_email: mikan.tenny@gmail.com + build_command_prepend: "./configure; make clean" + build_command: "make -j 4" + branch_pattern: coverity_scan + +#Compile +before_script: + - ./travis/compile.sh + +script: + - exit 0 + + diff --git a/vendor/swoole/CMakeLists.txt b/vendor/swoole/CMakeLists.txt new file mode 100755 index 0000000..c0b9090 --- /dev/null +++ b/vendor/swoole/CMakeLists.txt @@ -0,0 +1,47 @@ +PROJECT(libswoole) + +ENABLE_LANGUAGE(ASM) +SET(SWOOLE_VERSION 4.0.0) +SET(SWOOLE_CLFLAGS pthread rt dl ssl crypt crypto nghttp2) +CMAKE_MINIMUM_REQUIRED(VERSION 2.4) + +SET(CMAKE_BUILD_TYPE Debug) + +file(GLOB_RECURSE SRC_LIST FOLLOW_SYMLINKS src/*.c src/*.cc thirdparty/boost/asm/jump_x86_64_sysv_elf_gas.S thirdparty/boost/asm/make_x86_64_sysv_elf_gas.S) +file(GLOB_RECURSE HEAD_FILES FOLLOW_SYMLINKS include/*.h) + +SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib) +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) + +#message(STATUS "source=${SRC_LIST}") +#message(STATUS "header=${HEAD_FILES}") + +add_definitions(-DHAVE_CONFIG_H) + +INCLUDE_DIRECTORIES(BEFORE ./include ./ /usr/local/php/include /usr/local/php/include/Zend /usr/local/php/include/main) +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) + +#libary +add_library(shared SHARED ${SRC_LIST}) +add_library(static STATIC ${SRC_LIST}) + +set_target_properties(shared PROPERTIES OUTPUT_NAME "swoole" VERSION ${SWOOLE_VERSION}) +set_target_properties(static PROPERTIES OUTPUT_NAME "swoole" VERSION ${SWOOLE_VERSION}) + +target_link_libraries(shared ${SWOOLE_CLFLAGS}) +target_link_libraries(static ${SWOOLE_CLFLAGS}) + +LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH}) + +#test_server +set(TEST_SRC_LIST examples/test_server.c) +add_executable(test_server ${TEST_SRC_LIST}) +add_dependencies(test_server static) +target_link_libraries(test_server ${SWOOLE_CLFLAGS} swoole) + +#install +INSTALL(CODE "MESSAGE(\"Are you run command using root user?\")") +INSTALL(TARGETS shared static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) +INSTALL(FILES ${HEAD_FILES} DESTINATION include/swoole) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/swoole_config.h DESTINATION include/swoole) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config.h DESTINATION include/swoole) diff --git a/vendor/swoole/CREDITS b/vendor/swoole/CREDITS new file mode 100755 index 0000000..f6168ef --- /dev/null +++ b/vendor/swoole/CREDITS @@ -0,0 +1,3 @@ +Tianfeng Han(mikan.tenny@gmail.com) +Tencent Inc. +QQ: 350749960 \ No newline at end of file diff --git a/vendor/swoole/LICENSE b/vendor/swoole/LICENSE new file mode 100755 index 0000000..ad00f19 --- /dev/null +++ b/vendor/swoole/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright Tianfeng.Han [mikan.tenny@gmail.com] + + 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. diff --git a/vendor/swoole/README.md b/vendor/swoole/README.md new file mode 100755 index 0000000..012b219 --- /dev/null +++ b/vendor/swoole/README.md @@ -0,0 +1,573 @@ +Swoole +====== +[![Build Status](https://api.travis-ci.org/swoole/swoole-src.svg)](https://travis-ci.org/swoole/swoole-src) +[![License](https://img.shields.io/badge/license-apache2-blue.svg)](LICENSE) +[![Join the chat at https://gitter.im/swoole/swoole-src](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/swoole/swoole-src?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/11654/badge.svg)](https://scan.coverity.com/projects/swoole-swoole-src) + +Swoole is an event-driven asynchronous & concurrent networking communication framework with high performance written only in C for PHP. + +* __Document__: <https://www.swoole.co.uk/docs/> +* __API__: <https://rawgit.com/tchiotludo/swoole-ide-helper/english/docs/index.html> +* __IDE Helper__: <https://github.com/swoole/ide-helper> +* __中文文档__: <http://wiki.swoole.com/> +* __Twitter__: <https://twitter.com/php_swoole> +* __Slack Group__: <https://swoole.slack.com/> + +Swoft +---- +Modern High performance AOP and Coroutine PHP Framework, base on Swoole 2 <https://github.com/swoft-cloud> + +EasySwoole +---- +a simple high performance PHP framework base on Swoole which make you use Swoole like echo hello world。<https://www.easyswoole.com/> + +SwooleDistributed +----------------- +The high performance co operative server framework base on swoole all version, supports microservice and cluster deployment, providing developers with many advanced development and debugging components. <https://github.com/SwooleDistributed/SwooleDistributed> + +Event-based +------ + +The network layer in Swoole is event-based and takes full advantage of the underlaying epoll/kqueue implementation, making it really easy to serve thousands of connections. + +Coroutine +---------------- +[Swoole 2.0](Version2.md) supports the built-in coroutine, and you can use fully synchronized code to implement asynchronous programs. PHP code without any additional keywords, the underlying automatic coroutine-scheduling. + +```php +<?php +for ($i = 0; $i < 100; $i++) { + Swoole\Coroutine::create(function() use ($i) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + $ret = $redis->incr('coroutine'); + $redis->close(); + if ($i == 50) { + Swoole\Coroutine::create(function() use ($i) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + $ret = $redis->set('coroutine_i', 50); + $redis->close(); + }); + } + }); +} +``` + +```php +<?php +$server = new Swoole\Http\Server('127.0.0.1', 9501); + +$server->on('Request', function($request, $response) { + + $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $ret = $tcp_cli->connect('127.0.0.1', 9906); + $tcp_cli ->send('test for the coroutine'); + $ret = $tcp_cli->recv(5); + $tcp_cli->close(); + + if ($ret) { + $response->end(' swoole response is ok'); + } + else{ + $response->end(" recv failed error : {$client->errCode}"); + } +}); + +$server->start(); +``` + +Short API Name +----- +#### start a new coroutine +```php +go(function () { + co::sleep(0.5); + echo "hello"; +}); +go("test"); +go([$object, "method"]); +``` + +#### Channel +```php +$chan = new chan(128); +$chan->push(1234); +$chan->push(1234.56); +$chan->push("hello world"); +$chan->push(["hello world"]); +$chan->push(new stdclass); +$chan->push(fopen("test.txt", "r+")); +while($chan->pop()); +``` + +#### MySQL Client +```php +go(function () { + $db = new Co\MySQL(); + $server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', + ); + + $db->connect($server); + + $result = $db->query('SELECT * FROM userinfo WHERE id = 3'); + var_dump($result); +}); +``` + +#### Redis Client +```php +go(function () { + $redis = new Co\Redis; + $res = $redis->connect('127.0.0.1', 6379); + $ret = $redis->set('key', 'value'); + var_dump($redis->get('key')); +}); +``` + +#### Http Client +```php +go(function () { +    $http = new Co\Http\Client("www.google.com", 443, true); + $http->setHeaders(function () { + + }); + $ret = $http->get('/'); + var_dump($http->body); +}); +``` + +#### Http2 Client +```php +go(function () { +    $http = new Co\Http2\Client("www.google.com", 443, true); + $req = new co\Http2\Request; + $req->path = "/index.html"; + $req->headers = [ + 'host' => "www.google.com", + "user-agent" => 'Chrome/49.0.2587.3', + 'accept' => 'text/html,application/xhtml+xml,application/xml', + 'accept-encoding' => 'gzip', + ]; + $req->cookies = ['name' => 'rango', 'email' => 'rango@swoole.com']; + $ret = $http->send($req); + var_dump($http->recv()); +}); +``` + +#### Other +```php +co::sleep(100); +co::fread($fp); +co::gethostbyname('www.google.com'); +``` + + +Concurrent +------ + +On the request processing part, Swoole uses a multi-process model. Every process works as a worker. All business logic is executed in workers, synchronously. + +With the synchronous logic execution, you can easily write large and robust applications and take advantage of almost all libraries available to the PHP community. + +In-memory +------ + +Unlike traditional apache/php-fpm stuff, the memory allocated in Swoole will not be freed after a request, which can improve performance a lot. + + +## Why Swoole? + +Traditional PHP applications almost always run behind Apache/Nginx, without much control of the request. This brings several limitations: + +1. All memory will be freed after the request. All PHP code needs be re-compiled on every request. Even with opcache enabled, all opcode still needs to be re-executed. +2. It is almost impossible to implement long connections and connection pooling techniques. +3. Implementing asynchronous tasks requires third-party queue servers, such as rabbitmq and beanstalkd. +4. Implementing realtime applications such as chatting servers requires third-party languages, such as nodejs, for example. + +This is why Swoole appeared. Swoole extends the use cases of PHP, and brings all these possibilities to the PHP world. +By using Swoole, you can build enhanced web applications with more control, real-time chatting servers, etc, more easily. + +## Requirements + +* Version-1: PHP 5.3.10 or later +* Version-2: PHP 5.5.0 or later +* Linux, OS X and basic Windows support (thanks to cygwin) +* GCC 4.4 or later + +## Installation + +1. Install via pecl + + ``` + pecl install swoole + ``` + +2. Install from source + + ``` + sudo apt-get install php5-dev + git clone https://github.com/swoole/swoole-src.git + cd swoole-src + phpize + ./configure + make && make install + ``` + +## Introduction + +Swoole includes components for different purposes: Server, Task Worker, Timer, Event and Async IO. With these components, Swoole allows you to build many features. + +### Server + +This is the most important part in Swoole. It provides the necessary infrastructure to build server applications. +With Swoole server, you can build web servers, chat messaging servers, game servers and almost anything you want. + +The following example shows a simple echo server. + +```php +// Create a server instance +$serv = new swoole_server('127.0.0.1', 9501); + +// Attach handler for connect event. Once the client has connected to the server, the registered handler will be +// executed. +$serv->on('connect', function ($serv, $fd) { + echo "Client:Connect.\n"; +}); + +// Attach handler for receive event. Every piece of data will be received by server and the registered handler will be +// executed. All custom protocol implementation should be located there. +$serv->on('receive', function ($serv, $fd, $from_id, $data) { + $serv->send($fd, $data); +}); + +$serv->on('close', function ($serv, $fd) { + echo "Client: Close.\n"; +}); + +// Start our server, listen on the port and be ready to accept connections. +$serv->start(); +``` + +Try to extend your server and implement what you want! + +### HTTP Server + +```php +$http = new swoole_http_server('0.0.0.0', 9501); + +$http->on('request', function ($request, $response) { + $response->header('Content-Type', 'text/html; charset=utf-8'); + $response->end('<h1>Hello Swoole. #' . rand(1000, 9999) . '</h1>'); +}); + +$http->start(); +``` + +### WebSocket Server + +```php +$ws = new swoole_websocket_server('0.0.0.0', 9502); + +$ws->on('open', function ($ws, $request) { + var_dump($request->fd, $request->get, $request->server); + $ws->push($request->fd, "hello, welcome\n"); +}); + +$ws->on('message', function ($ws, $frame) { + echo "Message: {$frame->data}\n"; + $ws->push($frame->fd, "server: {$frame->data}"); +}); + +$ws->on('close', function ($ws, $fd) { + echo "client-{$fd} is closed\n"; +}); + +$ws->start(); +``` + +### Real async-mysql client +```php +$db = new swoole_mysql('127.0.0.1', 'root', 'root', 'test'); + +$db->on('close', function($o) { + echo "mysql connection is closed\n"; +}); + +$db->query('select now() as now_t', function($db, $result_rows) { + var_dump($result_rows); + $db->close(); +}); +``` + +### Real async-redis client +```php +$client = new swoole_redis; +$client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) { + echo "connect\n"; + var_dump($result); + $client->set('key', 'swoole', function (swoole_redis $client, $result) { + var_dump($result); + $client->get('key', function (swoole_redis $client, $result) { + var_dump($result); + $client->close(); + }); + }); +}); +``` + + +### Async http Client + +```php +$cli = new swoole_http_client('127.0.0.1', 80); + +$cli->setHeaders(['User-Agent' => 'swoole']); +$cli->post('/dump.php', array('test' => '9999999'), function (swoole_http_client $cli) { + echo "#{$cli->sock}\tPOST response Length: " . strlen($cli->body) . "\n"; + $cli->get('/index.php', function (swoole_http_client $cli) { + echo "#{$cli->sock}\tGET response Length: " . strlen($cli->body) . "\n"; + }); +}); +``` + +### Async WebSocket Client + +```php +$cli = new swoole_http_client('127.0.0.1', 9501); + +$cli->on('message', function ($_cli, $frame) { + var_dump($frame); +}); + +$cli->upgrade('/', function ($cli) { + echo $cli->body; + $cli->push('Hello world'); +}); +``` + + +### Multi-port and mixed protocol + +```php +$serv = new swoole_http_server('127.0.0.1', 9501, SWOOLE_BASE); + +$port2 = $serv->listen('0.0.0.0', 9502, SWOOLE_SOCK_TCP); +$port2->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + var_dump($data); + $serv->send($fd, $data); +}); + +$serv->on('request', function($req, $resp) { + $resp->end('<h1>Hello world</h1>'); +}); + + +$serv->start(); +``` + +### Task Worker + +Swoole brings you two types of workers: server workers and task workers. Server workers are for request +handling, as demonstrated above. Task workers are for task execution. With task workers, we can execute our +task asynchronously without blocking the server workers. + +Task workers are mainly used for time-consuming tasks, such as sending password recovery emails, and ensure +the main request returns as soon as possible. + +The following example shows a simple server with task support. + +```php +$serv = new swoole_server("127.0.0.1", 9502); + +// Sets server configuration, we set task_worker_num config greater than 0 to enable task workers support +$serv->set(array('task_worker_num' => 4)); + +// Attach handler for receive event, which has been explained above. +$serv->on('receive', function($serv, $fd, $from_id, $data) { + // We dispath a task to task workers by invoke the task() method of $serv + // This method returns a task id as the identity of ths task + $task_id = $serv->task($data); + echo "Dispath AsyncTask: id=$task_id\n"; +}); + +// Attach handler for task event. The handler will be executed in task workers. +$serv->on('task', function ($serv, $task_id, $from_id, $data) { + // Handle the task and do what you want with $data + echo "New AsyncTask[id=$task_id]" . PHP_EOL; + + // After the task is handled, we return the results to the caller worker. + $serv->finish("$data -> OK"); +}); + +// Attach handler for finish event. The handler will be executed in server workers. The same worker dispatched this task before. +$serv->on('finish', function ($serv, $task_id, $data) { + echo "AsyncTask[$task_id] Finish: $data" . PHP_EOL; +}); + +$serv->start(); +``` + +Swoole also supports synchronous tasks. To use synchronous tasks, just simply replace +`$serv->task($data)` with `$serv->taskwait($data)`. Unlike `task()`, `taskwait()` will wait for a task to +complete before it returns its response. + +### Timer + +Swoole has built-in millisecond timer support. By using the timer, it is easy to get a block of code +executed periodically (really useful for managing interval tasks). + +To demonstrate how the timer works, here is a small example: + +```php +//interval 2000ms +$serv->tick(2000, function ($timer_id) { + echo "tick-2000ms\n"; +}); + +//after 3000ms +$serv->after(3000, function () { + echo "after 3000ms.\n" +}); +``` + +In the example above, we first set the `timer` event handler to `swoole_server` to enable timer support. +Then, we add two timers by calling `bool swoole_server::addtimer($interval)` once the server started. +To handle multiple timers, we switch the `$interval` in registered handler and do what we want to do. + +### Event + +Swoole's I/O layer is event-based, which is very convenient to add your own file descriptor to Swoole's main eventloop. +With event support, you can also build fully asynchronous applications with Swoole. + +To use events in Swoole, we can use `swoole_event_set()` to register event handler to sepecified file descriptor, +once registered descriptors become readable or writeable, our registered handler will be invoked. Also, we can +using `bool swoole_event_del(int $fd);` to remove registered file descriptor from eventloop. + +The following are prototypes for the related functions: + +```php +bool swoole_event_add($fd, mixed $read_callback, mixed $write_callback, int $flag); +bool swoole_event_set($fd, mixed $read_callback, mixed $write_callback, int $flag); +bool swoole_event_del($fd); +``` + +The `$fd` parameter can be one of the following types: + +* unix file descriptor +* stream resource created by `stream_socket_client()/fsockopen()` +* sockets resources created by `socket_create()` in sockets extension (require compile swoole with --enable-sockets support) + +The `$read_callback` and `$write_callback` are callbacks for corresponding read/write event. + +The `$flag` is a mask to indicate what type of events we should get notified, can be `SWOOLE_EVENT_READ`, +`SWOOLE_EVENT_WRITE` or `SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE` + +### Async IO + +Swoole's Async IO provides the ability to read/write files and lookup dns records asynchronously. The following +are signatures for these functions: + + +```php +bool swoole_async_readfile(string $filename, mixed $callback); +bool swoole_async_writefile('test.log', $file_content, mixed $callback); +bool swoole_async_read(string $filename, mixed $callback, int $trunk_size = 8192); +bool swoole_async_write(string $filename, string $content, int $offset = -1, mixed $callback = NULL); +void swoole_async_dns_lookup(string $domain, function($host, $ip){}); +bool swoole_timer_after($after_n_ms, mixed $callback); +bool swoole_timer_tick($n_ms, mixed $callback); +bool swoole_timer_clear($n_ms, mixed $callback); +``` + +Refer to [API Reference](http://wiki.swoole.com/wiki/page/183.html) for more detailed information about these functions. + + +### Client + +Swoole also provides a client component to build tcp/udp clients in both asynchronous and synchronous ways. +Swoole uses the `swoole_client` class to expose all its functionalities. + +synchronous blocking: +```php +$client = new swoole_client(SWOOLE_SOCK_TCP); +if (!$client->connect('127.0.0.1', 9501, 0.5)) { + die('connect failed.'); +} + +if (!$client->send('Hello world')) { + die('send failed.'); +} + +$data = $client->recv(); +if (!$data) { + die('recv failed.'); +} + +$client->close(); + +``` + +Asynchronous non-blocking: + +```php +$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$client->on('connect', function($cli) { + $cli->send("Hello world\n"); +}); +$client->on('receive', function($cli, $data) { + echo "Received: ".$data."\n"; +}); +$client->on('error', function($cli) { + echo "Connect failed\n"; +}); +$client->on('close', function($cli) { + echo "Connection close\n"; +}); + +$client->connect('127.0.0.1', 9501, 0.5); +``` + +The following methods are available in swoole_client: + +```php +swoole_client::__construct(int $sock_type, int $is_sync = SWOOLE_SOCK_SYNC, string $key); +int swoole_client::on(string $event, mixed $callback); +bool swoole_client::connect(string $host, int $port, float $timeout = 0.1, int $flag = 0) +bool swoole_client::isConnected(); +int swoole_client::send(string $data); +bool swoole_client::sendfile(string $filename) +string swoole_client::recv(int $size = 65535, bool $waitall = 0); +bool swoole_client::close(); +``` + +Refer to [API Reference](http://wiki.swoole.com/wiki/page/3.html) for more detailed information about these functions. + +## API Reference + +* [中文](http://wiki.swoole.com/) +* [English](https://rawgit.com/tchiotludo/swoole-ide-helper/english/docs/index.html) + +## Related Projects + +* [SwooleFramework](https://github.com/swoole/framework) Web framework powered by Swoole + +## Contribution + +Your contribution to Swoole development is very welcome! + +You may contribute in the following ways: + +* [Repost issues and feedback](https://github.com/swoole/swoole-src/issues) +* Submit fixes, features via Pull Request +* Write/polish documentation + +## License + +Apache License Version 2.0 see http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/vendor/swoole/Version2.md b/vendor/swoole/Version2.md new file mode 100755 index 0000000..bb58780 --- /dev/null +++ b/vendor/swoole/Version2.md @@ -0,0 +1,171 @@ +# swoole 2.0 released +Now swoole 2.0 is shipped with original support for coroutine. Implemented by C, swoole is an event-driven, asynchronous and concurrent network engine for PHP. The new swoole 2.0 improves development efficiency extensively -- developers can easily achieve high network throughput by using coroutines in network I/O functions, instead of using trivial `generator`s or async callbacks. + +Furthermore, swoole 2.0 enhances the compatibility for PHP 7 without breaking the API backward-compatibility for previous swoole versions. Thus, users can painlessly upgrade to swoole 2.0. + +### Coroutine +With swoole 2.0, developers are able to implement async network I/O without taking care of the low-level details, such as coroutine switch. We build coroutine support of swoole 2.0 directly upon the Zend APIs, which is transparent for developers. Swoole 2.0 is able to switch among all coroutines according to the I/O result and the upper layer does not need to use async callback, which avoids callback hell. Besides, confusing keywords for coroutine creation like yield are removed. + +Now the coroutine component in swoole 2.0 has supported most common protocols including udp, tcp, http, redis and mysql. Private protocols can also be implemented based on udp/tcp. + +In addition, developers can also set timeout for IO operations. A corresponding error code will be returned if timeout + +Last but not least, developers can use coroutine in both PHP7 and PHP5(>=5.5). PHP7 is recommended because of its high performance. + +### Demo +To set up a Http server: + +```php +<?php +$server = new Swoole\Http\Server('127.0.0.1', 9501); + +/* + swoole will initialize a coroutine for every Request event. + */ +$server->on('Request', function($request, $response) { + + $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + /* + In the underlining implement of method connect, swoole will + save the php context and suspend this coroutine. + After tcp connection is established, swoole will set the + return value and resume this cortoutine. + */ + $ret = $tcp_cli->connect('127.0.0.1', 9906); + $tcp_cli ->send('test for the coro'); + /* + method recv will do the coroutine switching like that of connection. + swoole will resume this coroutine if server responses nothing after 5s + and errCode will be set 110 in the example below + */ + $ret = $tcp_cli->recv(5); + $tcp_cli->close(); + + if ($ret) { + $response->end(" swoole response is ok"); + } + else{ + $response->end(" recv failed error : {$client->errCode}"); + } +}); + +$server->start(); +``` + +UDP server Demo + +```php +<?php +$server = new Swoole\Http\Server('127.0.0.1', 9501); + +$server->on('Request', function($request, $response) { + + $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $ret = $tcp_cli ->connect('127.0.0.1', 9906); + $tcp_cli ->send('test for the coro'); + $ret = $tcp_cli ->recv(100); + $tcp_cli->close(); + + if ($ret) { + $response ->end(" swoole response is ok"); + } + else{ + $response ->end(" recv failed error : {$client->errCode}"); + } +}); + +$server->start(); +``` + +**Demos for different kinds of clients:** + +1. udp/tcp clieint + +```php +$udp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + +$ret = $udp_cli ->connect('127.0.0.1', 9906); +$udp_cli ->send('test for the coro'); + +$ret = $udp_cli ->recv(100); +$udp_cli->close(); + +if ($ret) { + $response ->end(" swoole response is ok"); +} +else{ + $response ->end(" recv failed error : {$client->errCode}"); +} +``` + +2. http client + +```php +$cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 80); +$cli->setHeaders([ + 'Host' => "localhost", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', +]); +$cli->set([ 'timeout' => 1]); +$cli->get('/index.php'); +echo $cli->body; +$cli->close(); +``` +3. redis client +```php +$redis = new Swoole\Coroutine\Redis(); +$redis->connect('127.0.0.1', 6379); +$val = $redis->get('key'); +``` + +4. mysql client +```php +$swoole_mysql = new Swoole\Coroutine\MySQL(); +$swoole_mysql->connect(['host' => '127.0.0.1', 'user' => 'user', 'password' => 'pass', 'database' => 'test']); +$res = $swoole_mysql->query('select sleep(1)'); +``` + +## Build and Install +* Recommended with PHP7 +* Download [swoole-2.0.5](https://github.com/swoole/swoole-src/releases/tag/v2.0.5) + +```shell +phpize +./configure +make -j 4 +sudo make install + +``` +You should add "extension=swoole.so" to php.ini, execute the demo program. + +## Safety warning + +#### Do not use coroutines in these functions: + +* `__get` +* `__set` +* `__call` +* `__callStatic` +* `__toString` +* `__invoke` +* `__destruct` +* `call_user_func` +* `call_user_func_array` +* `ReflectionFunction::invoke` +* `ReflectionFunction::invokeArgs` +* `ReflectionMethod::invoke` +* `ReflectionMethod::invokeArgs` +* `array_walk`/`array_map` +* `ob_*` + +#### Please turn off these extensions: + +* xdebug +* phptrace +* aop +* molten +* xhprof + + diff --git a/vendor/swoole/benchmark/ab.sh b/vendor/swoole/benchmark/ab.sh new file mode 100755 index 0000000..e4b901b --- /dev/null +++ b/vendor/swoole/benchmark/ab.sh @@ -0,0 +1,4 @@ +ab -c 1000 -n 1000000 -k http://127.0.0.1:9501/ +ab -c 1000 -n 1000000 -k -p post.data -T 'application/x-www-form-urlencoded' http://127.0.0.1:9501/ +#post 24K +ab -c 100 -n 100000 -k -p post.big.data -T 'application/x-www-form-urlencoded' http://127.0.0.1:9501/ \ No newline at end of file diff --git a/vendor/swoole/benchmark/async.php b/vendor/swoole/benchmark/async.php new file mode 100755 index 0000000..f851258 --- /dev/null +++ b/vendor/swoole/benchmark/async.php @@ -0,0 +1,253 @@ +<?php +//关闭错误输出 +//error_reporting(0); +$shortopts = "c:"; +$shortopts .= "n:"; +$shortopts .= "s:"; +$shortopts .= "f:"; +$shortopts .= "p::"; + +$opt = getopt($shortopts); +//并发数量 +if (!isset($opt['c'])) { + exit("require -c [process_num]. ep: -c 100\n"); +} +if (!isset($opt['n'])) { + exit("require -n [request_num]. ep: -n 10000\n"); +} +if (!isset($opt['s'])) { + exit("require -s [server_url]. ep: -s tcp://127.0.0.1:9999\n"); +} +if (!isset($opt['f'])) { + exit("require -f [test_function]. ep: -f websocket|http|tcp|udp\n"); +} + +class BenchMark +{ + protected $nConcurrency; + protected $nRequest; + protected $host; + protected $port; + protected $clients = array(); + + protected $nRecvBytes = 0; + protected $nSendBytes = 0; + + protected $requestCount = 0; + protected $connectErrorCount = 0; + + protected $connectTime = 0; + + protected $startTime; + protected $beginSendTime; + protected $testMethod; + + static $sentData = "hello world\n"; + + function __construct($opt) + { + $this->nConcurrency = $opt['c']; + $this->nRequest = $opt['n']; + $serv = parse_url($opt['s']); + $this->host = $serv['host']; + $this->port = $serv['port']; + $this->testMethod = $opt['f']; + if (!method_exists($this, $this->testMethod)) + { + throw new RuntimeException("method [{$this->testMethod}] is not exists."); + } + } + + protected function finish() + { + foreach($this->clients as $k => $cli) + { + /** + * @var $cli swoole\client + */ + if ($cli->isConnected()) + { + $cli->close(); + } + unset($this->clients[$k]); + } + echo "============================================================\n"; + echo " Swoole Version ".SWOOLE_VERSION."\n"; + echo "============================================================\n"; + echo "{$this->requestCount}\tbenchmark tests is finished.\n"; + echo "SendBytes:\t".number_format($this->nSendBytes)."\n"; + echo "nReceBytes:\t".number_format($this->nRecvBytes)."\n"; + echo "concurrency:\t".$this->nConcurrency,"\n"; + echo "connect failed:\t" . $this->connectErrorCount, "\n"; + echo "request num:\t" . $this->nRequest, "\n"; + $costTime = $this->format(microtime(true) - $this->startTime); + echo "total time:\t" . ($costTime) . "\n"; + if ($this->requestCount > 0) + { + echo "request per second:\t" . intval($this->requestCount / $costTime), "\n"; + } + else + { + echo "request per second:\t0\n"; + } + echo "connection time:\t" . $this->format($this->connectTime) . "\n"; + } + + function format($time) + { + return round($time, 4); + } + + function onReceive($cli, $data) + { + $this->nRecvBytes += strlen($data); + /** + * 请求已经发完了,关闭连接,等待所有连接结束 + */ + if ($this->requestCount >= $this->nRequest) + { + $cli->close(); + unset($this->clients[$cli->sock]); + if (count($this->clients) == 0) + { + $this->finish(); + } + } + else + { + $this->send($cli); + } + } + + function send($cli) + { + $data = self::$sentData; + $cli->send($data); + $this->nSendBytes += strlen($data); + $this->requestCount++; + } + + function push($cli) + { + $data = self::$sentData; + $cli->push($data); + $this->nSendBytes += strlen($data); + $this->requestCount++; + } + + function onClose($cli) + { + //echo "close\n"; + } + + function onError($cli) + { + $this->connectErrorCount ++; + if ($this->connectErrorCount >= $this->nConcurrency) + { + $this->finish(); + } + } + + function onConnect($cli) + { + $this->send($cli); + } + + function websocket() + { + $cli = new swoole\http\client($this->host, $this->port); + $cli->set(array('websocket_mask' => true)); + $cli->on('Message', function($cli, $frame) { + $this->nRecvBytes += strlen($frame->data); + /** + * 请求已经发完了,关闭连接,等待所有连接结束 + */ + if ($this->requestCount >= $this->nRequest) + { + $cli->close(); + unset($this->clients[$cli->sock]); + if (count($this->clients) == 0) + { + $this->finish(); + } + } + else + { + $this->push($cli); + } + }); + $cli->upgrade('/', function ($cli) { + $this->push($cli); + }); + return $cli; + } + + function long_tcp() + { + $cli = new swoole\client(SWOOLE_TCP | SWOOLE_ASYNC); + $cli->on('receive', [$this, 'onReceive']); + $cli->on('close', [$this, 'onClose']); + $cli->on('connect', [$this, 'onConnect']); + $cli->on('error', [$this, 'onError']); + $cli->connect($this->host, $this->port); + return $cli; + } + + function eof() + { + $eof = "\r\n\r\n"; + $cli = new swoole\client(SWOOLE_TCP | SWOOLE_ASYNC); + $cli->set(array('open_eof_check' => true, "package_eof" => $eof)); + $cli->on('receive', [$this, 'onReceive']); + $cli->on('close', [$this, 'onClose']); + $cli->on('connect', [$this, 'onConnect']); + $cli->on('error', [$this, 'onError']); + $cli->connect($this->host, $this->port); + self::$sentData .= $eof; + return $cli; + } + + function length() + { + $cli = new swoole\client(SWOOLE_TCP | SWOOLE_ASYNC); + $cli->set(array( + 'open_length_check' => true, + "package_length_type" => 'N', + 'package_body_offset' => 4, + )); + $cli->on('receive', [$this, 'onReceive']); + $cli->on('close', [$this, 'onClose']); + $cli->on('connect', [$this, 'onConnect']); + $cli->on('error', [$this, 'onError']); + $cli->connect($this->host, $this->port); + self::$sentData = pack('N', strlen(self::$sentData)) . self::$sentData; + return $cli; + } + + function udp() + { + $cli = new swoole\client(SWOOLE_UDP | SWOOLE_ASYNC); + $cli->on('receive', [$this, 'onReceive']); + $cli->on('close', [$this, 'onClose']); + $cli->on('connect', [$this, 'onConnect']); + $cli->on('error', [$this, 'onError']); + $cli->connect($this->host, $this->port); + return $cli; + } + + function run() + { + $this->startTime = microtime(true); + for ($i = 0; $i < $this->nConcurrency; $i++) + { + $cli = call_user_func([$this, $this->testMethod]); + $this->clients[$cli->sock] = $cli; + } + $this->beginSendTime = microtime(true); + $this->connectTime = $this->beginSendTime - $this->startTime; + } +} + +$bench = new BenchMark($opt); +$bench->run(); diff --git a/vendor/swoole/benchmark/coroutine.php b/vendor/swoole/benchmark/coroutine.php new file mode 100755 index 0000000..fe62624 --- /dev/null +++ b/vendor/swoole/benchmark/coroutine.php @@ -0,0 +1,84 @@ +<?php +class Server +{ + public $server; + public $redisPool = []; + public $mysqlPool = []; + + public function run() + { + $this->server = new Swoole\Http\Server("0.0.0.0", 9501, SWOOLE_BASE); + $this->server->set([ + 'worker_num' => 1, + ]); + +// $this->server->on('Connect', [$this, 'onConnect']); + $this->server->on('Request', [$this, 'onRequest']); +// $this->server->on('Close', [$this, 'onClose']); + + $this->server->start(); + } + + function log($msg) + { + echo $msg."\n"; + } + + public function onConnect($serv, $fd, $reactorId) + { +// $this->log("onConnect: fd=$fd"); +// $redis = new Swoole\Coroutine\Redis(); +// $redis->connect('127.0.0.1', 6379); +// $this->redisPool[$fd] = $redis; + } + + public function onClose($serv, $fd, $reactorId) + { +// $this->log("onClose: fd=$fd"); +// $redis = $this->redisPool[$fd]; +// $redis->close(); +// unset($this->redisPool[$fd]); + } + + public function onRequest($request, $response) + { +// $this->log("onRequest: fd=$request->fd"); + + if (empty($this->redisPool[$request->fd])) + { + $redis = new Swoole\Coroutine\Redis(); + $redis->connect('127.0.0.1', 6379); + $this->redisPool[$request->fd] = $redis; + } + else + { + $redis = $this->redisPool[$request->fd]; + } + $ret = $redis->get('key'); + + if (empty($this->mysqlPool[$request->fd])) + { + $mysql = new Swoole\Coroutine\MySQL(); + $mysql->connect([ + 'host' => '127.0.0.1', + 'port' => 3306, + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', + ]); + } + else + { + $mysql = $this->mysqlPool[$request->fd]; + } + + $ret2 = $mysql->query('show tables'); + $response->end('redis value=' . $ret.', mysql talbes='.var_export($ret2, true)); + } +} + +$server = new Server(); +$server->run(); + + + diff --git a/vendor/swoole/benchmark/eof_server.php b/vendor/swoole/benchmark/eof_server.php new file mode 100755 index 0000000..fd48477 --- /dev/null +++ b/vendor/swoole/benchmark/eof_server.php @@ -0,0 +1,33 @@ +<?php +Swoole\Async::set(array('enable_reuse_port' => true)); +$serv = new swoole_server("0.0.0.0", 9502, SWOOLE_BASE); +//$serv = new swoole_server("0.0.0.0", 9502); +$serv->set(array( + 'worker_num' => 8, + 'open_eof_check' => true, + 'package_eof' => "\r\n\r\n", +)); +$serv->on('workerstart', function ($server, $id) +{ + global $argv; + swoole_set_process_name("php {$argv[0]}: worker"); +}); + +$serv->on('connect', function (swoole_server $serv, $fd, $from_id) +{ + //echo "connect\n";; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + $serv->send($fd, "Swoole: " . $data); + //$serv->close($fd); +}); + +$serv->on('close', function (swoole_server $serv, $fd, $from_id) +{ + //var_dump($serv->connection_info($fd)); + //echo "onClose\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/benchmark/http.go b/vendor/swoole/benchmark/http.go new file mode 100755 index 0000000..4982b85 --- /dev/null +++ b/vendor/swoole/benchmark/http.go @@ -0,0 +1,23 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "runtime" +) + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU() - 1) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Last-Modified", "Thu, 18 Jun 2015 10:24:27 GMT") + w.Header().Add("Accept-Ranges", "bytes") + w.Header().Add("E-Tag", "55829c5b-17") + w.Header().Add("Server", "golang-http-server") + fmt.Fprint(w, "<h1>\nHello world!\n</h1>\n") + }) + + log.Printf("Go http Server listen on :8080") + log.Fatal(http.ListenAndServe(":8080", nil)) +} diff --git a/vendor/swoole/benchmark/http.js b/vendor/swoole/benchmark/http.js new file mode 100755 index 0000000..f8d8729 --- /dev/null +++ b/vendor/swoole/benchmark/http.js @@ -0,0 +1,8 @@ +var http = require('http'); +http.createServer(function (req, res) { + res.writeHead(200, { + 'Server': "node.js"} + ); + res.end("<h1>Hello World</h2>"); +}).listen(8080, '127.0.0.1'); +console.log('Server running at http://127.0.0.1:8080/'); diff --git a/vendor/swoole/benchmark/http.php b/vendor/swoole/benchmark/http.php new file mode 100755 index 0000000..ecccbef --- /dev/null +++ b/vendor/swoole/benchmark/http.php @@ -0,0 +1,15 @@ +<?php +$http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + +$http->set([ + 'worker_num' => 4, +]); + +$http->on('request', function ($request, swoole_http_response $response) { + $response->header('Last-Modified', 'Thu, 18 Jun 2015 10:24:27 GMT'); + $response->header('E-Tag', '55829c5b-17'); + $response->header('Accept-Ranges', 'bytes'); + $response->end("<h1>\nHello Swoole.\n</h1>"); +}); + +$http->start(); diff --git a/vendor/swoole/benchmark/http2.go b/vendor/swoole/benchmark/http2.go new file mode 100755 index 0000000..be1e204 --- /dev/null +++ b/vendor/swoole/benchmark/http2.go @@ -0,0 +1,27 @@ +package main + +import ( + "log" + "github.com/valyala/fasthttp" + "runtime" + "fmt" +) + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU() - 1) + + m := func(ctx *fasthttp.RequestCtx) { + switch string(ctx.Path()) { + case "/": + ctx.Response.Header.Set("Last-Modified", "Thu, 18 Jun 2015 10:24:27 GMT") + ctx.Response.Header.Set("Accept-Ranges", "bytes") + ctx.Response.Header.Set("E-Tag", "55829c5b-17") + ctx.Response.Header.Set("Server", "golang-http-server") + fmt.Fprint(ctx, "<h1>\nHello world!\n</h1>\n") + default: + } + } + + log.Printf("Go fatshttp Server listen on :8888") + log.Fatal(fasthttp.ListenAndServe(":8888", m)) +} diff --git a/vendor/swoole/benchmark/length_server.php b/vendor/swoole/benchmark/length_server.php new file mode 100755 index 0000000..edd2147 --- /dev/null +++ b/vendor/swoole/benchmark/length_server.php @@ -0,0 +1,34 @@ +<?php +Swoole\Async::set(array('enable_reuse_port' => true)); +$serv = new swoole_server("0.0.0.0", 9502, SWOOLE_BASE); +//$serv = new swoole_server("0.0.0.0", 9502); +$serv->set(array( + 'worker_num' => 8, + 'open_length_check' => true, + "package_length_type" => 'N', + 'package_body_offset' => 4, +)); +$serv->on('workerstart', function ($server, $id) +{ + global $argv; + swoole_set_process_name("php {$argv[0]}: worker"); +}); + +$serv->on('connect', function (swoole_server $serv, $fd, $from_id) +{ + //echo "connect\n";; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + $serv->send($fd, $data); + //$serv->close($fd); +}); + +$serv->on('close', function (swoole_server $serv, $fd, $from_id) +{ + //var_dump($serv->connection_info($fd)); + //echo "onClose\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/benchmark/post.big.data b/vendor/swoole/benchmark/post.big.data new file mode 100755 index 0000000..d8f81ce --- /dev/null +++ b/vendor/swoole/benchmark/post.big.data @@ -0,0 +1 @@ +test1=hello&test2=world&myname=rango&go=start&language=php&big=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/vendor/swoole/benchmark/post.data b/vendor/swoole/benchmark/post.data new file mode 100755 index 0000000..fce0bf6 --- /dev/null +++ b/vendor/swoole/benchmark/post.data @@ -0,0 +1 @@ +test1=hello&test2=world&myname=rango&go=start&language=php diff --git a/vendor/swoole/benchmark/redis.go b/vendor/swoole/benchmark/redis.go new file mode 100755 index 0000000..bf41460 --- /dev/null +++ b/vendor/swoole/benchmark/redis.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "github.com/hoisie/redis" + "runtime" +) + +var ( + client *redis.Client +) + +func main() { + + client = &redis.Client{ + Addr: "127.0.0.1:6379", + Db: 0, + MaxPoolSize: 10000, + } + + // 限制为CPU的数量减一 + runtime.GOMAXPROCS( runtime.NumCPU() - 1 ) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + result, err := client.Get("hello") + if err != nil { + fmt.Fprint(w, err.Error()) + println(err.Error()) + } else { + fmt.Fprint(w, "<h1>Hello world!. result="+ string(result)+"</h1>") + } + }) + + log.Fatal(http.ListenAndServe(":8080", nil)) +} diff --git a/vendor/swoole/benchmark/run.php b/vendor/swoole/benchmark/run.php new file mode 100755 index 0000000..25a4703 --- /dev/null +++ b/vendor/swoole/benchmark/run.php @@ -0,0 +1,574 @@ +<?php +require __DIR__.'/../examples/websocket/WebSocketClient.php'; + +//关闭错误输出 +//error_reporting(0); +$shortopts = "c:"; +$shortopts .= "n:"; +$shortopts .= "s:"; +$shortopts .= "f:"; +$shortopts .= "p::"; + +$opt = getopt($shortopts); +//并发数量 +if(!isset($opt['c'])) exit("require -c [process_num]. ep: -c 100\n"); +if(!isset($opt['n'])) exit("require -n [request_num]. ep: -n 10000\n"); +if(!isset($opt['s'])) exit("require -s [server_url]. ep: -s tcp://127.0.0.1:9999\n"); +if(!isset($opt['f'])) exit("require -f [test_function]. ep: -f short_tcp\n"); + +$bc = new Swoole_Benchmark(trim($opt['f'])); +$bc->process_num = (int)$opt['c']; +$bc->request_num = (int)$opt['n']; +$bc->server_url = trim($opt['s']); +$bc->server_config = parse_url($bc->server_url); +$bc->send_data = "GET / HTTP/1.1\r\n"; +$bc->send_data .= "Host: www.baidu.com\r\n"; +$bc->send_data .= "Connection: keep-alive\r\n"; +$bc->send_data .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"; +$bc->send_data .= "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36\r\n\r\n"; + +$bc->read_len = 65536; +if(!empty($opt['p'])) $bc->show_detail = true; + +function eof(Swoole_Benchmark $bc) +{ + static $client = null; + static $i; + $start = microtime(true); + if (empty($client)) { + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set(array('open_eof_check' => true, "package_eof" => "\r\n\r\n")); + $end = microtime(true); + $conn_use = $end - $start; + $bc->max_conn_time = $conn_use; + $i = 0; + //echo "connect {$bc->server_url} \n"; + if (!$client->connect($bc->server_config['host'], $bc->server_config['port'], 2)) { + error: + echo "Error: " . swoole_strerror($client->errCode) . "[{$client->errCode}]\n"; + $client = null; + return false; + } + $start = $end; + } + /*--------写入Sokcet-------*/ + $data = str_repeat('A', rand(100, 200))."\r\n\r\n"; + if (!$client->send($data)) + { + goto error; + } + $end = microtime(true); + $write_use = $end - $start; + if ($write_use > $bc->max_write_time) $bc->max_write_time = $write_use; + $start = $end; + /*--------读取Sokcet-------*/ + $i ++; + $ret = $client->recv(); + if (empty($ret)) + { + echo $bc->pid, "#$i", " is lost\n"; + return false; + } + elseif(strlen($ret) != strlen($data)) + { + echo "#$i\tlength error\n"; + var_dump($ret); + echo "-----------------------------------\n"; + var_dump($data); + } + $end = microtime(true); + $read_use = $end - $start; + if ($read_use > $bc->max_read_time) $bc->max_read_time = $read_use; + return true; +} + +function long_tcp(Swoole_Benchmark $bc) +{ + static $fp = null; + static $i; + $start = microtime(true); + if(empty($fp)) + { + $fp = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $end = microtime(true); + $conn_use = $end-$start; + $bc->max_conn_time = $conn_use; + $i = 0; + //echo "connect {$bc->server_url} \n"; + if (!$fp->connect($bc->server_config['host'], $bc->server_config['port'], 2)) + { + error: + echo "Error: ".swoole_strerror($fp->errCode)."[{$fp->errCode}]\n"; + $fp = null; + return false; + } + $start = $end; + } + /*--------写入Sokcet-------*/ + if (!$fp->send($bc->send_data)) + { + goto error; + } + $end = microtime(true); + $write_use = $end - $start; + if ($write_use > $bc->max_write_time) + { + $bc->max_write_time = $write_use; + } + $start = $end; + /*--------读取Sokcet-------*/ + while(true) + { + $ret = $fp->recv(65530); + if (empty($ret) or substr($ret, -1, 1) == "\n") + { + break; + } + } + //var_dump($ret); + $i++; + if (empty($ret)) + { + echo $bc->pid, "#$i@", " is lost\n"; + return false; + } + $end = microtime(true); + $read_use = $end - $start; + if ($read_use > $bc->max_read_time) + { + $bc->max_read_time = $read_use; + } + return true; +} + +function websocket(Swoole_Benchmark $bc) +{ + static $client = null; + static $i; + $start = microtime(true); + + if (empty($client)) + { + $client = new WebSocketClient($bc->server_config['host'], $bc->server_config['port']); + if (!$client->connect()) + { + echo "connect failed\n"; + return false; + } + + $end = microtime(true); + $conn_use = $end - $start; + $bc->max_conn_time = $conn_use; + $i = 0; + $start = $end; + } + /*--------写入Sokcet-------*/ + if (!$client->send($bc->send_data)) + { + echo "send failed\n"; + return false; + } + $end = microtime(true); + $write_use = $end - $start; + if ($write_use > $bc->max_write_time) + { + $bc->max_write_time = $write_use; + } + $start = $end; + /*--------读取Sokcet-------*/ + $ret = $client->recv(); + //var_dump($ret); + $i++; + if (empty($ret)) + { + echo $bc->pid, "#$i@", " is lost\n"; + return false; + } + $end = microtime(true); + $read_use = $end - $start; + if ($read_use > $bc->max_read_time) + { + $bc->max_read_time = $read_use; + } + return true; +} + +/** + * 去掉计时信息的UDP + * @param $bc + * @return bool + */ +function udp(Swoole_Benchmark $bc) +{ + static $fp; + if (empty($fp)) + { + $fp = stream_socket_client($bc->server_url, $errno, $errstr, 1); + if (!$fp) + { + echo "{$errstr}[{$errno}]\n"; + return false; + } + } + /*--------写入Sokcet-------*/ + fwrite($fp, $bc->send_data); + /*--------读取Sokcet-------*/ + $ret = fread($fp, $bc->read_len); + if (empty($ret)) + { + return false; + } + return true; +} + +function udp2(Swoole_Benchmark $bc) +{ + static $fp; + $start = microtime(true); + if (empty($fp)) + { + $u = parse_url($bc->server_url); + $fp = new swoole_client(SWOOLE_SOCK_UDP); + $fp->connect($u['host'], $u['port'], 0.5, 0); + $end = microtime(true); + $conn_use = $end - $start; + $bc->max_conn_time = $conn_use; + $start = $end; + } + /*--------写入Sokcet-------*/ + $fp->send($bc->send_data); + $end = microtime(true); + $write_use = $end - $start; + if ($write_use > $bc->max_write_time) + { + $bc->max_write_time = $write_use; + } + $start = $end; + /*--------读取Sokcet-------*/ + $ret = $fp->recv(); + if (empty($ret)) + { + return false; + } + + $end = microtime(true); + $read_use = $end - $start; + if ($read_use > $bc->max_read_time) + { + $bc->max_read_time = $read_use; + } + return true; +} + +function short_tcp($bc) +{ + $fp = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + if(!$fp->connect($bc->server_config['host'], $bc->server_config['port'], 1)) + { + error: + echo "Error: ".socket_strerror($fp->errCode)."[{$fp->errCode}]\n"; + return false; + } + else + { + if(!$fp->send($bc->send_data)) + { + goto error; + } + $ret = $fp->recv(); + $fp->close(); + if(!empty($ret)) return true; + else return false; + } +} + +function long_socks5($bc) +{ + static $fp = null; + static $i; + $start = microtime(true); + if(empty($fp)) + { + $fp = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC,5); + $end = microtime(true); + $conn_use = $end-$start; + $bc->max_conn_time = $conn_use; + $i = 0; + //echo "connect {$bc->server_url} \n"; + if (!$fp->connect($bc->server_config['host'], $bc->server_config['port'], 2)) + { + error: + echo "Error: ".swoole_strerror($fp->errCode)."[{$fp->errCode}]\n"; + $fp = null; + return false; + } + + $fp->send(pack("C3", 0x05, 0x01, 0x00));//greet + $data = $fp->recv(); + $response = unpack("Cversion/Cmethod", $data); + if ($response['version'] != 0x05) + { + exit('SOCKS version is not supported.'); + } + $headers = getHeader($bc->send_data); + if (empty($headers['port'])) { + $headers['port'] = 80; + } + $g = pack("C5", 0x05, 0x01, 0x00, 0x03, strlen($headers['host'])) . $headers['host'] . pack("n", $headers['port']); + $fp->send($g); + $data = $fp->recv(); + $response = unpack("Cversion/Cresult/Creg/Ctype/Lip/Sport", $data); + if ($response['result'] != 0x00) + { + echo 'SOCKS connection request failed: ' . getSocksRefusalMsg($response['result']), $response['result'];exit; + } + + $start = $end; + } + /*--------写入Sokcet-------*/ + if (!$fp->send($bc->send_data)) + { + goto error; + } + $end = microtime(true); + $write_use = $end - $start; + if ($write_use > $bc->max_write_time) + { + $bc->max_write_time = $write_use; + } + $start = $end; + /*--------读取Sokcet-------*/ + while(true) + { + $ret = $fp->recv(65530); + if (empty($ret) or substr($ret, -1, 1) == "\n") + { + break; + } + } + //var_dump($ret); + $i++; + if (empty($ret)) + { + echo $bc->pid, "#$i@", " is lost\n"; + return false; + } + $end = microtime(true); + $read_use = $end - $start; + if ($read_use > $bc->max_read_time) + { + $bc->max_read_time = $read_use; + } + return true; +} + +function getHeader($message) +{ + // 标准每行应该以"\r\n"行终止,这里兼容以"\n"作为行终止的情况,所以按"\n"分割行 + $lines = explode("\n", $message); + foreach ($lines as &$line) + { + // 按"\n"分割行以后,某些行末可能存在"\r"字符,这里将其过滤掉 + $line = rtrim($line, "\r"); + } + unset($line); + + if (count($lines) <= 0) + { + return false; + } + $headers = []; + + foreach ($lines as $line) + { + $pos = strpos($line, ':'); + // 非标准首部,抛弃 + if ($pos === false) + { + continue; + } + $field = trim(substr($line, 0, $pos)); + $value = trim(substr($line, $pos + 1)); + + // 如果有host头部,重新设置host和port + if (strtolower($field) === 'host') + { + $segments = explode(':', $value); + $host = $segments[0]; + $headers['host'] = $host; + if (isset($segments[1])) + { + $port = intval($segments[1]); + $headers['port'] = $port; + } + } + $headers[$field] = $value; + } + return $headers; +} +//请求数量最好是进程数的倍数 +$bc->process_req_num = intval($bc->request_num/$bc->process_num); +$bc->run(); +$bc->report(); +$bc->end(); + +class Swoole_Benchmark +{ + public $test_func; + public $process_num; + public $request_num; + public $server_url; + public $server_config; + public $send_data; + public $read_len; + + public $time_end; + private $shm_key; + public $main_pid; + public $child_pid = array(); + + public $show_detail = false; + public $max_write_time = 0; + public $max_read_time = 0; + public $max_conn_time = 0; + + public $pid; + + protected $tmp_dir = '/tmp/swoole_bench/'; + + function __construct($func) + { + if (!function_exists($func)) + { + exit(__CLASS__ . ": function[$func] not exists\n"); + } + if (!is_dir($this->tmp_dir)) + { + mkdir($this->tmp_dir); + } + $this->test_func = $func; + } + function end() + { + unlink($this->shm_key); + foreach($this->child_pid as $pid) + { + $f = $this->tmp_dir . 'lost_' . $pid . '.log'; + if (is_file($f)) unlink($f); + } + } + + function run() + { + $this->main_pid = posix_getpid(); + $this->shm_key = $this->tmp_dir.'t.log'; + for ($i = 0; $i < $this->process_num; $i++) + { + $this->child_pid[] = $this->start(array($this, 'worker')); + } + for ($i = 0; $i < $this->process_num; $i++) + { + $status = 0; + $pid = pcntl_wait($status); + } + $this->time_end = microtime(true); + } + + function init_signal() + { + pcntl_signal(SIGUSR1,array($this, "sig_handle")); + } + + function sig_handle($sig) + { + switch ($sig) + { + case SIGUSR1: + return; + } + $this->init_signal(); + } + + function start($func) + { + $pid = pcntl_fork(); + if($pid>0) + { + return $pid; + } + elseif($pid==0) + { + $this->worker(); + } + else + { + echo "Error:fork fail\n"; + } + } + function worker() + { + $lost = 0; + if(!file_exists($this->shm_key)) + { + file_put_contents($this->shm_key,microtime(true)); + } + if($this->show_detail) $start = microtime(true); + $this->pid = posix_getpid(); + + for ($i = 0; $i < $this->process_req_num; $i++) + { + $func = $this->test_func; + if(!$func($this)) $lost++; + } + if ($this->show_detail) + { + $log = $this->pid . "#\ttotal_use(s):" . substr(microtime(true) - $start, 0, 5); + $log .= "\tconnect(ms):" . substr($this->max_conn_time * 1000, 0, 5); + $log .= "\twrite(ms):" . substr($this->max_write_time * 1000, 0, 5); + $log .= "\tread(ms):" . substr($this->max_read_time * 1000, 0, 5); + file_put_contents($this->tmp_dir.'lost_' . $this->pid . '.log', $lost . "\n" . $log); + } + else + { + file_put_contents($this->tmp_dir.'lost_'.$this->pid.'.log', $lost); + } + exit(0); + } + + function report() + { + $time_start = file_get_contents($this->shm_key); + $usetime = $this->time_end - $time_start; + $lost = 0; + + foreach ($this->child_pid as $f) + { + $file = $this->tmp_dir.'lost_'.$f.'.log'; + if (is_file($file)) + { + $_lost = file_get_contents($file); + $log = explode("\n",$_lost,2); + } + if (!empty($log)) + { + $lost += intval($log[0]); + if ($this->show_detail) echo $log[1], "\n"; + } + } + //并发量 + echo "concurrency:\t".$this->process_num,"\n"; + //请求量 + echo "request num:\t".$this->request_num,"\n"; + //请求量 + echo "lost num:\t".$lost,"\n"; + //请求量 + echo "success num:\t".($this->request_num-$lost),"\n"; + //总时间 + echo "total time:\t".substr($usetime,0,5),"\n"; + //每秒处理能力 + echo "req per second:\t".intval($this->request_num/$usetime),"\n"; + //每次请求平均时间ms + echo "one req use(ms):\t".substr($usetime/$this->request_num*1000,0,5),"\n"; + } +} + diff --git a/vendor/swoole/benchmark/seria_bench.php b/vendor/swoole/benchmark/seria_bench.php new file mode 100755 index 0000000..4ad996f --- /dev/null +++ b/vendor/swoole/benchmark/seria_bench.php @@ -0,0 +1,483 @@ +<?php +$target = array ( + 'battle_id'=> 257 + ,'user_id'=> 41248 + ,'user_id2'=> 23989 + ,'player'=> 41248 + ,'formation'=> Array ('41248'=> 1 ,'23989'=> 2,'ssss'=>3) + ,'result'=> 1 + ,'battle_type'=> 1 + ,'speed'=> Array( '41248'=> 0,'23989'=> 0 ) + ,'attacker'=> Array( + '1'=> Array ( + 'user_id'=> 41248 + ,'soldier_id'=> 28 + ,'prototype_id'=> 4 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3997 + ,'hp'=> 3997 + ,'attack_general'=> 346 + ,'attack_skill'=> 596 + ,'attack_explode'=> 458 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 2 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0) + ,'4'=> Array ( + 'user_id'=> 41248 + ,'soldier_id'=> 29 + ,'prototype_id'=> 2 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3555 + ,'hp'=> 3555 + ,'attack_general'=> 396 + ,'attack_skill'=> 581 + ,'attack_explode'=> 418 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0 + ) + ,'5'=> Array ( + 'user_id'=> 41248 + ,'soldier_id'=> 30 + ,'prototype_id'=> 6 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3043 + ,'hp'=> 3043 + ,'attack_general'=> 351 + ,'attack_skill'=> 540 + ,'attack_explode'=> 474 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0) + ,'7'=> Array ( + 'user_id'=> 41248 + ,'soldier_id'=> 37 + ,'prototype_id'=> 2 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3491 + ,'hp'=> 3491 + ,'attack_general'=> 393 + ,'attack_skill'=> 532 + ,'attack_explode'=> 456 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0 )) + ,'defender'=> Array( + '2'=> Array( + 'user_id'=> 23989 + ,'soldier_id'=> 24 + ,'prototype_id'=> 1 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3230 + ,'hp'=> 3230 + ,'attack_general'=> 390 + ,'attack_skill'=> 567 + ,'attack_explode'=> 442 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0) + ,'5'=> Array( + 'user_id'=> 23989 + ,'soldier_id'=> 25 + ,'prototype_id'=> 2 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3400 + ,'hp'=> 3400 + ,'attack_general'=> 379 + ,'attack_skill'=> 536 + ,'attack_explode'=> 405 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0 ) + ,'7'=> Array( + 'user_id'=> 23989 + ,'soldier_id'=> 26 + ,'prototype_id'=> 6 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3669 + ,'hp'=> 3669 + ,'attack_general'=> 362 + ,'attack_skill'=> 549 + ,'attack_explode'=> 426 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0 ) + ,'9'=> Array( + 'user_id'=> 23989 + ,'soldier_id'=> 27 + ,'prototype_id'=> 1 + ,'bid'=> 1 + ,'level'=> 1 + ,'rare'=> 1 + ,'skill_id'=> 1 + ,'totalhp'=> 3618 + ,'hp'=> 3618 + ,'attack_general'=> 326 + ,'attack_skill'=> 510 + ,'attack_explode'=> 419 + ,'attack_type'=> 1 + ,'defense'=> 0 + ,'anger'=> 50 + ,'dodge'=> 2 + ,'crit'=> 2 + ,'block'=> 0 + ,'block_effect'=> 0.5 + ,'crit_effect'=> 2 + ,'foramtion_effect'=> 0) ) + ,'battle_process'=> Array( + '0'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'1'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'2'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'3'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'4'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'5'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'6'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'7'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'8'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'9'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'10'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'11'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'12'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'13'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'14'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'15'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'16'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'17'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'18'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ,'19'=> Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + + ,'20'=>Array( + 'user_id'=> 41248 + ,'asid'=> 28 + ,'bsid'=> 'danger' + ,'harm'=> 'danger2' + ,'dhp'=> Array('0'=> 2019 ) + ,'attacker_anger'=> 66 + ,'defender_anger'=> Array('0'=> 94 ) + ,'skill'=> 0 + ,'state'=> 0 + ) + ) + +); +$json = json_encode($target); +$seri = serialize($target); +$sw = swoole_serialize::pack($target); +var_dump("json :". strlen($json)); +var_dump("serialize :". strlen($seri)); +var_dump("swoole :". strlen($sw)); +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + json_encode($target); +} +$etime = microtime(true); +var_dump("json_encode :". ($etime - $stime)); +//---------------------------------- +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + json_decode($json. true); +} +$etime = microtime(true); +var_dump("json_decode :". ($etime - $stime)); +//---------------------------------- +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + serialize($target); +} +$etime = microtime(true); +var_dump("serialize :". ($etime - $stime)); +//---------------------------------- +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + unserialize($seri); +} +$etime = microtime(true); +var_dump("unserialize :". ($etime - $stime)); +//---------------------------------- +//---------------------------------- +//---------------------------------- +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + swoole_serialize::pack($target); +} +$etime = microtime(true); +var_dump("swoole_serialize :". ($etime - $stime)); +$stime = microtime(true); +for ($i = 0; $i < 50000; $i ++) { + swoole_serialize::unpack($sw); +} +$etime = microtime(true); +var_dump("swoole_unserialize :". ($etime - $stime)); +?> \ No newline at end of file diff --git a/vendor/swoole/benchmark/table.php b/vendor/swoole/benchmark/table.php new file mode 100755 index 0000000..0b47af8 --- /dev/null +++ b/vendor/swoole/benchmark/table.php @@ -0,0 +1,46 @@ +<?php +$table = new swoole_table(1 << 18); +$table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8 +$table->column('name', swoole_table::TYPE_STRING, 17623); +$table->column('num', swoole_table::TYPE_FLOAT); +$table->create(); + +define('N', 100000); + +//$worker = new swoole_process('child1', false, false); +//$worker->start(); +// +//child +function child1($worker) +{ + global $table; + $s = microtime(true); + for($i =0; $i < N; $i++) + { + $table->set('tianfenghan@qq.com', array('id' => 145, 'name' => 'rango', 'num' => 3.1415)); + $table->set('350749960@qq.com', array('id' => 358, 'name' => "Rango1234", 'num' => 3.1415)); + $table->set('hello@qq.com', array('id' => 189, 'name' => 'rango3', 'num' => 3.1415)); + $table->set('tianfenghan@chelun.com', array('id' => 145, 'name' => 'rango', 'num' => 3.1415)); + $table->set('12811247@qq.com', array('id' => 1358, 'name' => "Swoole", 'num' => 3.1415)); + } + echo "set - ".(5*N)." use: ".round((microtime(true) - $s) * 1000, 4)."ms\n"; +} + +//master +sleep(1); + +child1(1245); +$s = microtime(true); +for($i =0; $i < N; $i++) +{ + $arr1 = $table->get('tianfenghan@qq.com'); + $arr2 = $table->get('350749960@qq.com'); + $arr3 = $table->get('hello@qq.com'); + $arr4 = $table->get('tianfenghan@chelun.com'); + $arr5 = $table->get('12811247@qq.com'); +} + +echo "get - ".(5*N)." use: ".round((microtime(true) - $s) * 1000, 4)."ms\n"; +$s = microtime(true); + +var_dump($arr1, $arr2, $arr3, $arr4, $arr5); diff --git a/vendor/swoole/benchmark/tcp.go b/vendor/swoole/benchmark/tcp.go new file mode 100755 index 0000000..fd13a2f --- /dev/null +++ b/vendor/swoole/benchmark/tcp.go @@ -0,0 +1,41 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "runtime" +) + +func Echo(c net.Conn) { + defer c.Close() + for { + line, err := bufio.NewReader(c).ReadString('\n') + if err != nil { + //fmt.Printf("Failure to read:%s\n", err.Error()) + return + } + _, err = c.Write([]byte(line)) + if err != nil { + //fmt.Printf("Failure to write: %s\n", err.Error()) + return + } + } +} + +func main() { + + runtime.GOMAXPROCS(runtime.NumCPU() - 1) + + fmt.Printf("Server is ready...\n") + l, err := net.Listen("tcp", ":8053") + if err != nil { + fmt.Printf("Failure to listen: %s\n", err.Error()) + } + + for { + if c, err := l.Accept(); err == nil { + go Echo(c) //new thread + } + } +} diff --git a/vendor/swoole/benchmark/tcp.js b/vendor/swoole/benchmark/tcp.js new file mode 100755 index 0000000..c6aacb9 --- /dev/null +++ b/vendor/swoole/benchmark/tcp.js @@ -0,0 +1,8 @@ +var net = require('net'); + +var server = net.createServer(function (socket) { +socket.write("Echo server\r\n"); +socket.pipe(socket); +}); + +server.listen(7001, "127.0.0.1"); diff --git a/vendor/swoole/benchmark/tcp.php b/vendor/swoole/benchmark/tcp.php new file mode 100755 index 0000000..e1120de --- /dev/null +++ b/vendor/swoole/benchmark/tcp.php @@ -0,0 +1,31 @@ +<?php +Swoole\Async::set(array('enable_reuse_port' => true)); +$serv = new swoole_server("0.0.0.0", 9502, SWOOLE_BASE); +//$serv = new swoole_server("0.0.0.0", 9502); +$serv->set(array( + 'worker_num' => 8, +)); +$serv->on('workerstart', function ($server, $id) +{ + global $argv; + swoole_set_process_name("php {$argv[0]}: worker"); +}); + +$serv->on('connect', function (swoole_server $serv, $fd, $from_id) +{ + //echo "connect\n";; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + $serv->send($fd, "Swoole: " . $data); + //$serv->close($fd); +}); + +$serv->on('close', function (swoole_server $serv, $fd, $from_id) +{ + //var_dump($serv->connection_info($fd)); + //echo "onClose\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/benchmark/timer.php b/vendor/swoole/benchmark/timer.php new file mode 100755 index 0000000..f74a32c --- /dev/null +++ b/vendor/swoole/benchmark/timer.php @@ -0,0 +1,37 @@ +<?php +const N = 100000; + +function test() +{ + global $timers; + shuffle($timers); + $stime = microtime(true); + foreach($timers as $id) + { + swoole_timer_clear($id); + } + $etime = microtime(true); + echo "del ".N." timer :". ($etime - $stime)."s\n"; +} + +class TestClass +{ + static function timer() + { + + } +} + +$timers = []; +$stime = microtime(true); +for($i = 0; $i < N; $i++) +{ + $timers[] = swoole_timer_after(rand(1, 9999999), 'test'); + //swoole_timer_after(rand(1, 9999999), function () { + // echo "hello world\n"; + //}); + //swoole_timer_after(rand(1, 9999999), array('TestClass', 'timer')); +} +$etime = microtime(true); +echo "add ".N." timer :". ($etime - $stime)."s\n"; +swoole_event_wait(); diff --git a/vendor/swoole/benchmark/udp.php b/vendor/swoole/benchmark/udp.php new file mode 100755 index 0000000..df3b986 --- /dev/null +++ b/vendor/swoole/benchmark/udp.php @@ -0,0 +1,36 @@ +<?php +//Swoole\Async::set(array('enable_reuse_port' => true)); +//$serv = new swoole_server("0.0.0.0", 9502, SWOOLE_BASE, SWOOLE_SOCK_UDP); +$serv = new swoole_server("0.0.0.0", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); +$serv->set(array( + 'dispatch_mode' => 1, + 'worker_num' => 8, //worker process num +// //'log_file' => '/tmp/swoole.log', +// //'daemonize' => true, +)); + +function my_onStart($serv) +{ + echo "MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}\n"; + echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n"; +} + +function my_onReceive(swoole_server $serv, $fd, $from_id, $data) +{ + //var_dump($serv->connection_info($fd, $from_id)); + //echo "worker_pid=".posix_getpid().PHP_EOL; + //var_dump($fd, $from_id); + $serv->send($fd, 'Swoole: ' . $data, $from_id); +} + +function my_onPacket(swoole_server $serv, $data, $addr) +{ +// var_dump($addr); + $serv->sendto($addr['address'], $addr['port'], 'Swoole: ' . $data); +} + +$serv->on('Start', 'my_onStart'); +$serv->on('Receive', 'my_onReceive'); +//$serv->on('Packet', 'my_onPacket'); +$serv->start(); + diff --git a/vendor/swoole/benchmark/websocket.php b/vendor/swoole/benchmark/websocket.php new file mode 100755 index 0000000..2634389 --- /dev/null +++ b/vendor/swoole/benchmark/websocket.php @@ -0,0 +1,25 @@ +<?php +//$server = new swoole_websocket_server("0.0.0.0", 9502); +$server = new swoole_websocket_server("0.0.0.0", 9502, SWOOLE_BASE); +$server->set(['worker_num' => 4]); +// +//$server->on('open', function (swoole_websocket_server $_server, swoole_http_request $request) { +// //echo "server#{$_server->worker_pid}: handshake success with fd#{$request->fd}\n"; +// +//// var_dump($request); +//}); + +$server->on('message', function (swoole_websocket_server $_server, $frame) { + //var_dump($frame); + //echo "received ".strlen($frame->data)." bytes\n"; + //echo "receive from {$fd}:{$data},opcode:{$opcode},fin:{$fin}\n"; + $_server->push($frame->fd, "server:" . $frame->data); + // $_server->close($frame->fd); +}); + +//$server->on('close', function ($_server, $fd) { +// echo "client {$fd} closed\n"; +//}); + + +$server->start(); diff --git a/vendor/swoole/build.sh b/vendor/swoole/build.sh new file mode 100755 index 0000000..db1e106 --- /dev/null +++ b/vendor/swoole/build.sh @@ -0,0 +1,17 @@ +git submodule update --init --recursive +cd thirdparty/hiredis +make +sudo make install +cd ../nghttp2 +cmake . +make +sudo make install +sudo ldconfig +cd ../.. +phpize --clean +phpize +make clean +./configure --enable-openssl --enable-sockets --enable-async-redis --enable-mysqlnd --enable-http2 +make -j +make install + diff --git a/vendor/swoole/clear.sh b/vendor/swoole/clear.sh new file mode 100755 index 0000000..dbd99f3 --- /dev/null +++ b/vendor/swoole/clear.sh @@ -0,0 +1,7 @@ +find . -name \*.gcno -o -name \*.gcda | xargs rm -f +find . -name \*.lo -o -name \*.o | xargs rm -f +find . -name \*.la -o -name \*.a | xargs rm -f +find . -name \*.so | xargs rm -f +find . -name .libs -a -type d|xargs rm -rf +rm -f libphp.la modules/* libs/* + diff --git a/vendor/swoole/config.m4 b/vendor/swoole/config.m4 new file mode 100755 index 0000000..cccdc40 --- /dev/null +++ b/vendor/swoole/config.m4 @@ -0,0 +1,654 @@ +dnl config.m4 for extension swoole + +dnl +----------------------------------------------------------------------+ +dnl | Swoole | +dnl +----------------------------------------------------------------------+ +dnl | This source file is subject to version 2.0 of the Apache license, | +dnl | that is bundled with this package in the file LICENSE, and is | +dnl | available through the world-wide-web at the following url: | +dnl | http://www.apache.org/licenses/LICENSE-2.0.html | +dnl | If you did not receive a copy of the Apache2.0 license and are unable| + +dnl | to obtain it through the world-wide-web, please send a note to | +dnl | license@swoole.com so we can mail you a copy immediately. | +dnl +----------------------------------------------------------------------+ +dnl | Author: Tianfeng Han <mikan.tenny@gmail.com> | +dnl +----------------------------------------------------------------------+ + +PHP_ARG_ENABLE(swoole-debug, whether to enable swoole debug, +[ --enable-swoole-debug Enable swoole debug], no, no) + +PHP_ARG_ENABLE(trace-log, Whether to enable trace log, +[ --enable-trace-log Enable swoole trace log], no, no) + +PHP_ARG_ENABLE(sockets, enable sockets support, +[ --enable-sockets Do you have sockets extension?], no, no) + +PHP_ARG_ENABLE(async_redis, enable async_redis support, +[ --enable-async-redis Do you have hiredis?], no, no) + +PHP_ARG_ENABLE(coroutine-postgresql, enable coroutine postgresql support, +[ --enable-coroutine-postgresql Do you install postgresql?], no, no) + +PHP_ARG_ENABLE(openssl, enable openssl support, +[ --enable-openssl Use openssl?], no, no) + +PHP_ARG_ENABLE(http2, enable http2.0 support, +[ --enable-http2 Use http2.0?], no, no) + +PHP_ARG_ENABLE(thread, enable thread support, +[ --enable-thread Experimental: Use thread?], no, no) + +PHP_ARG_ENABLE(hugepage, enable hugepage support, +[ --enable-hugepage Experimental: Use hugepage?], no, no) + +PHP_ARG_ENABLE(swoole, swoole support, +[ --enable-swoole Enable swoole support], [enable_swoole="yes"]) + +PHP_ARG_ENABLE(swoole_static, swoole static compile support, +[ --enable-swoole-static Enable swoole static compile support], no, no) + +PHP_ARG_WITH(swoole, swoole support, +[ --with-swoole With swoole support]) + +PHP_ARG_WITH(libpq_dir, for libpq support, +[ --with-libpq-dir[=DIR] Include libpq support (requires libpq >= 9.5)], no, no) + +PHP_ARG_WITH(openssl_dir, for OpenSSL support, +[ --with-openssl-dir[=DIR] Include OpenSSL support (requires OpenSSL >= 0.9.6)], no, no) + +PHP_ARG_WITH(phpx_dir, for PHP-X support, +[ --with-phpx-dir[=DIR] Include PHP-X support], no, no) + +PHP_ARG_WITH(jemalloc_dir, for jemalloc support, +[ --with-jemalloc-dir[=DIR] Include jemalloc support], no, no) + +PHP_ARG_ENABLE(mysqlnd, enable mysqlnd support, +[ --enable-mysqlnd Do you have mysqlnd?], no, no) + +PHP_ARG_ENABLE(asan, whether to enable asan, +[ --enable-asan Enable asan], no, no) + +PHP_ARG_ENABLE(picohttpparser, enable picohttpparser support, +[ --enable-picohttpparser Experimental: Do you have picohttpparser?], no, no) + +PHP_ARG_WITH(swoole, swoole support, +[ --with-swoole With swoole support]) + +PHP_ARG_ENABLE(timewheel, enable timewheel support, +[ --enable-timewheel Experimental: Enable timewheel heartbeat?], no, no) + +AC_DEFUN([SWOOLE_HAVE_PHP_EXT], [ + extname=$1 + haveext=$[PHP_]translit($1,a-z_-,A-Z__) + + AC_MSG_CHECKING([for ext/$extname support]) + if test -x "$PHP_EXECUTABLE"; then + grepext=`$PHP_EXECUTABLE -m | $EGREP ^$extname\$` + if test "$grepext" = "$extname"; then + [PHP_HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1 + AC_MSG_RESULT([yes]) + $2 + else + [PHP_HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)= + AC_MSG_RESULT([no]) + $3 + fi + elif test "$haveext" != "no" && test "x$haveext" != "x"; then + [PHP_HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)=1 + AC_MSG_RESULT([yes]) + $2 + else + [PHP_HTTP_HAVE_EXT_]translit($1,a-z_-,A-Z__)= + AC_MSG_RESULT([no]) + $3 + fi +]) + +AC_DEFUN([AC_SWOOLE_CPU_AFFINITY], +[ + AC_MSG_CHECKING([for cpu affinity]) + AC_TRY_COMPILE( + [ + #ifdef __FreeBSD__ + #include <sys/types.h> + #include <sys/cpuset.h> + typedef cpuset_t cpu_set_t; + #else + #include <sched.h> + #endif + ], [ + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + ], [ + AC_DEFINE([HAVE_CPU_AFFINITY], 1, [cpu affinity?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_REUSEPORT], +[ + AC_MSG_CHECKING([for socket REUSEPORT]) + AC_TRY_COMPILE( + [ + #include <sys/socket.h> + ], [ + int val = 1; + setsockopt(0, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); + ], [ + AC_DEFINE([HAVE_REUSEPORT], 1, [have SO_REUSEPORT?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_FUTEX], +[ + AC_MSG_CHECKING([for futex]) + AC_TRY_COMPILE( + [ + #include <linux/futex.h> + #include <syscall.h> + #include <unistd.h> + ], [ + int futex_addr; + int val1; + syscall(SYS_futex, &futex_addr, val1, NULL, NULL, 0); + ], [ + AC_DEFINE([HAVE_FUTEX], 1, [have FUTEX?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_LINUX_AIO], +[ + AC_MSG_CHECKING([for linux aio]) + AC_TRY_COMPILE( + [ + #include <sys/syscall.h> + #include <linux/aio_abi.h> + #include <unistd.h> + ], [ + struct iocb *iocbps[1]; + struct iocb iocbp; + aio_context_t context; + iocbps[0] = &iocbp; + io_submit(context, 1, iocbps); + ], [ + AC_DEFINE([HAVE_LINUX_AIO], 1, [have LINUX_AIO?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_UCONTEXT], +[ + AC_MSG_CHECKING([for ucontext]) + AC_TRY_COMPILE( + [ + #include <stdio.h> + #include <ucontext.h> + #include <unistd.h> + ], [ + ucontext_t context; + getcontext(&context); + ], [ + AC_DEFINE([HAVE_UCONTEXT], 1, [have ucontext?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_BOOST_CONTEXT], +[ + AC_MSG_CHECKING([for boost.context]) + AC_LANG([C++]) + AC_TRY_COMPILE( + [ + #include <boost/context/all.hpp> + ], [ + + ], [ + AC_DEFINE([HAVE_BOOST_CONTEXT], 1, [have boost.context?]) + SW_HAVE_BOOST_CONTEXT=yes + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_DEFUN([AC_SWOOLE_HAVE_VALGRIND], +[ + AC_MSG_CHECKING([for valgrind]) + AC_LANG([C++]) + AC_TRY_COMPILE( + [ + #include <valgrind/valgrind.h> + ], [ + + ], [ + AC_DEFINE([HAVE_VALGRIND], 1, [have valgrind?]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +]) + +AC_MSG_CHECKING([if compiling with clang]) +AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([], [[ + #ifndef __clang__ + not clang + #endif + ]])], + [CLANG=yes], [CLANG=no] +) +AC_MSG_RESULT([$CLANG]) + +if test "$CLANG" = "yes"; then + CFLAGS="$CFLAGS -std=gnu89" +fi + +AC_CANONICAL_HOST + +if test "$PHP_SWOOLE" != "no"; then + + PHP_ADD_LIBRARY(pthread) + PHP_SUBST(SWOOLE_SHARED_LIBADD) + + AC_ARG_ENABLE(debug, + [--enable-debug, compile with debug symbols], + [PHP_DEBUG=$enableval], + [PHP_DEBUG=0] + ) + + if test "$PHP_SWOOLE_DEBUG" != "no"; then + AC_DEFINE(SW_DEBUG, 1, [do we enable swoole debug]) + PHP_DEBUG=1 + fi + + if test "$PHP_ASAN" != "no"; then + PHP_DEBUG=1 + CFLAGS="$CFLAGS -fsanitize=address -fno-omit-frame-pointer" + fi + + if test "$PHP_TRACE_LOG" != "no"; then + AC_DEFINE(SW_LOG_TRACE_OPEN, 1, [enable trace log]) + fi + + if test "$PHP_SOCKETS" = "yes"; then + AC_DEFINE(SW_SOCKETS, 1, [enable sockets support]) + fi + + if test "$PHP_HTTP2" = "yes"; then + AC_DEFINE(SW_USE_HTTP2, 1, [enable http2.0 support]) + fi + + if test "$PHP_HUGEPAGE" = "yes"; then + AC_DEFINE(SW_USE_HUGEPAGE, 1, [enable hugepage support]) + fi + + if test "$PHP_THREAD" = "yes"; then + AC_DEFINE(SW_USE_THREAD, 1, [enable thread support]) + fi + + if test "$PHP_TIMEWHEEL" = "yes"; then + AC_DEFINE(SW_USE_TIMEWHEEL, 1, [enable timewheel support]) + fi + + AC_SWOOLE_CPU_AFFINITY + AC_SWOOLE_HAVE_REUSEPORT + AC_SWOOLE_HAVE_FUTEX + AC_SWOOLE_HAVE_LINUX_AIO + AC_SWOOLE_HAVE_UCONTEXT + AC_SWOOLE_HAVE_BOOST_CONTEXT + AC_SWOOLE_HAVE_VALGRIND + + CFLAGS="-Wall -pthread $CFLAGS" + LDFLAGS="$LDFLAGS -lpthread" + + if test `uname` = "Darwin"; then + AC_CHECK_LIB(c, clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [have clock_gettime])) + else + AC_CHECK_LIB(rt, clock_gettime, AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [have clock_gettime])) + PHP_ADD_LIBRARY(rt, 1, SWOOLE_SHARED_LIBADD) + LDFLAGS="$LDFLAGS -z now" + fi + + if test "$PHP_OPENSSL" != "no" || test "$PHP_OPENSSL_DIR" != "no"; then + if test "$PHP_OPENSSL_DIR" != "no"; then + AC_DEFINE(HAVE_OPENSSL, 1, [have openssl]) + PHP_ADD_INCLUDE("${PHP_OPENSSL_DIR}/include") + PHP_ADD_LIBRARY_WITH_PATH(ssl, "${PHP_OPENSSL_DIR}/${PHP_LIBDIR}") + else + AC_CHECK_LIB(ssl, SSL_connect, AC_DEFINE(HAVE_OPENSSL, 1, [have openssl])) + fi + + AC_DEFINE(SW_USE_OPENSSL, 1, [enable openssl support]) + PHP_ADD_LIBRARY(ssl, 1, SWOOLE_SHARED_LIBADD) + PHP_ADD_LIBRARY(crypto, 1, SWOOLE_SHARED_LIBADD) + fi + + if test "$PHP_PHPX_DIR" != "no"; then + PHP_ADD_INCLUDE("${PHP_PHPX_DIR}/include") + PHP_ADD_LIBRARY_WITH_PATH(phpx, "${PHP_PHPX_DIR}/${PHP_LIBDIR}") + AC_DEFINE(SW_USE_PHPX, 1, [enable PHP-X support]) + PHP_ADD_LIBRARY(phpx, 1, SWOOLE_SHARED_LIBADD) + CXXFLAGS="$CXXFLAGS -std=c++11" + fi + + if test "$PHP_JEMALLOC_DIR" != "no"; then + AC_DEFINE(SW_USE_JEMALLOC, 1, [use jemalloc]) + PHP_ADD_INCLUDE("${PHP_JEMALLOC_DIR}/include") + PHP_ADD_LIBRARY_WITH_PATH(jemalloc, "${PHP_JEMALLOC_DIR}/${PHP_LIBDIR}") + PHP_ADD_LIBRARY(jemalloc, 1, SWOOLE_SHARED_LIBADD) + fi + + PHP_ADD_LIBRARY(pthread, 1, SWOOLE_SHARED_LIBADD) + + if test "$PHP_ASYNC_REDIS" = "yes"; then + AC_DEFINE(SW_USE_REDIS, 1, [enable async-redis support]) + PHP_ADD_LIBRARY(hiredis, 1, SWOOLE_SHARED_LIBADD) + fi + + if test "$PHP_COROUTINE_POSTGRESQL" = "yes"; then + if test "$PHP_LIBPQ" != "no" || test "$PHP_LIBPQ_DIR" != "no"; then + if test "$PHP_LIBPQ_DIR" != "no"; then + AC_DEFINE(HAVE_LIBPQ, 1, [have libpq]) + AC_MSG_RESULT(libpq include success) + PHP_ADD_INCLUDE("${PHP_LIBPQ_DIR}/include") + else + PGSQL_SEARCH_PATHS="/usr /usr/local /usr/local/pgsql" + for i in $PGSQL_SEARCH_PATHS; do + for j in include include/pgsql include/postgres include/postgresql ""; do + if test -r "$i/$j/libpq-fe.h"; then + PGSQL_INC_BASE=$i + PGSQL_INCLUDE=$i/$j + AC_MSG_RESULT(libpq-fe.h found in PGSQL_INCLUDE) + PHP_ADD_INCLUDE("${PGSQL_INCLUDE}") + fi + done + done + fi + AC_DEFINE(SW_USE_POSTGRESQL, 1, [enable coroutine-postgresql support]) + PHP_ADD_LIBRARY(pq, 1, SWOOLE_SHARED_LIBADD) + fi + if test -z "$PGSQL_INCLUDE"; then + AC_MSG_ERROR(Cannot find libpq-fe.h. Please confirm the libpq or specify correct PostgreSQL(libpq) installation path) + fi + fi + + if test "$PHP_HTTP2" = "yes"; then + PHP_ADD_LIBRARY(nghttp2, 1, SWOOLE_SHARED_LIBADD) + fi + + if test "$PHP_MYSQLND" = "yes"; then + PHP_ADD_EXTENSION_DEP(mysqli, mysqlnd) + AC_DEFINE(SW_USE_MYSQLND, 1, [use mysqlnd]) + fi + + AC_CHECK_LIB(c, accept4, AC_DEFINE(HAVE_ACCEPT4, 1, [have accept4])) + AC_CHECK_LIB(c, signalfd, AC_DEFINE(HAVE_SIGNALFD, 1, [have signalfd])) + AC_CHECK_LIB(c, timerfd_create, AC_DEFINE(HAVE_TIMERFD, 1, [have timerfd])) + AC_CHECK_LIB(c, eventfd, AC_DEFINE(HAVE_EVENTFD, 1, [have eventfd])) + AC_CHECK_LIB(c, epoll_create, AC_DEFINE(HAVE_EPOLL, 1, [have epoll])) + AC_CHECK_LIB(c, poll, AC_DEFINE(HAVE_POLL, 1, [have poll])) + AC_CHECK_LIB(c, sendfile, AC_DEFINE(HAVE_SENDFILE, 1, [have sendfile])) + AC_CHECK_LIB(c, kqueue, AC_DEFINE(HAVE_KQUEUE, 1, [have kqueue])) + AC_CHECK_LIB(c, backtrace, AC_DEFINE(HAVE_EXECINFO, 1, [have execinfo])) + AC_CHECK_LIB(c, daemon, AC_DEFINE(HAVE_DAEMON, 1, [have daemon])) + AC_CHECK_LIB(c, mkostemp, AC_DEFINE(HAVE_MKOSTEMP, 1, [have mkostemp])) + AC_CHECK_LIB(c, inotify_init, AC_DEFINE(HAVE_INOTIFY, 1, [have inotify])) + AC_CHECK_LIB(c, malloc_trim, AC_DEFINE(HAVE_MALLOC_TRIM, 1, [have malloc_trim])) + AC_CHECK_LIB(c, inotify_init1, AC_DEFINE(HAVE_INOTIFY_INIT1, 1, [have inotify_init1])) + AC_CHECK_LIB(c, gethostbyname2_r, AC_DEFINE(HAVE_GETHOSTBYNAME2_R, 1, [have gethostbyname2_r])) + AC_CHECK_LIB(c, ptrace, AC_DEFINE(HAVE_PTRACE, 1, [have ptrace])) + AC_CHECK_LIB(pthread, pthread_rwlock_init, AC_DEFINE(HAVE_RWLOCK, 1, [have pthread_rwlock_init])) + AC_CHECK_LIB(pthread, pthread_spin_lock, AC_DEFINE(HAVE_SPINLOCK, 1, [have pthread_spin_lock])) + AC_CHECK_LIB(pthread, pthread_mutex_timedlock, AC_DEFINE(HAVE_MUTEX_TIMEDLOCK, 1, [have pthread_mutex_timedlock])) + AC_CHECK_LIB(pthread, pthread_barrier_init, AC_DEFINE(HAVE_PTHREAD_BARRIER, 1, [have pthread_barrier_init])) + AC_CHECK_LIB(pcre, pcre_compile, AC_DEFINE(HAVE_PCRE, 1, [have pcre])) + AC_CHECK_LIB(hiredis, redisConnect, AC_DEFINE(HAVE_HIREDIS, 1, [have hiredis])) + AC_CHECK_LIB(pq, PQconnectdb, AC_DEFINE(HAVE_POSTGRESQL, 1, [have postgresql])) + AC_CHECK_LIB(nghttp2, nghttp2_hd_inflate_new, AC_DEFINE(HAVE_NGHTTP2, 1, [have nghttp2])) + + AC_CHECK_LIB(z, gzgets, [ + AC_DEFINE(SW_HAVE_ZLIB, 1, [have zlib]) + PHP_ADD_LIBRARY(z, 1, SWOOLE_SHARED_LIBADD) + ]) + + swoole_source_file="swoole.c \ + swoole_server.c \ + swoole_server_port.c \ + swoole_atomic.c \ + swoole_lock.c \ + swoole_client.c \ + swoole_client_coro.c \ + swoole_coroutine.cc \ + swoole_coroutine_util.c \ + swoole_event.c \ + swoole_socket_coro.c \ + swoole_timer.c \ + swoole_async.c \ + swoole_process.c \ + swoole_process_pool.c \ + swoole_serialize.c \ + swoole_buffer.c \ + swoole_table.c \ + swoole_http_server.c \ + swoole_http_v2_server.c \ + swoole_http_v2_client.c \ + swoole_http_v2_client_coro.c \ + swoole_websocket_server.c \ + swoole_http_client.c \ + swoole_http_client_coro.c \ + swoole_mysql.c \ + swoole_mysql_coro.c \ + swoole_postgresql_coro.c \ + swoole_redis.c \ + swoole_redis_coro.c \ + swoole_redis_server.c \ + swoole_mmap.c \ + swoole_channel.c \ + swoole_channel_coro.cc \ + swoole_ringqueue.c \ + swoole_msgqueue.c \ + swoole_trace.c \ + swoole_runtime.cc \ + swoole_memory_pool.c \ + src/core/base.c \ + src/core/log.c \ + src/core/hashmap.c \ + src/core/RingQueue.c \ + src/core/Channel.c \ + src/core/string.c \ + src/core/array.c \ + src/core/socket.c \ + src/core/list.c \ + src/core/heap.c \ + src/core/error.cc \ + src/coroutine/base.cc \ + src/coroutine/boost.cc \ + src/coroutine/context.cc \ + src/coroutine/ucontext.cc \ + src/memory/ShareMemory.c \ + src/memory/MemoryGlobal.c \ + src/memory/RingBuffer.c \ + src/memory/FixedPool.c \ + src/memory/Malloc.c \ + src/memory/Table.c \ + src/memory/Buffer.c \ + src/factory/Factory.c \ + src/factory/FactoryThread.c \ + src/factory/FactoryProcess.c \ + src/reactor/ReactorBase.c \ + src/reactor/ReactorSelect.c \ + src/reactor/ReactorPoll.c \ + src/reactor/ReactorEpoll.c \ + src/reactor/ReactorKqueue.c \ + src/pipe/PipeBase.c \ + src/pipe/PipeEventfd.c \ + src/pipe/PipeUnsock.c \ + src/lock/Semaphore.c \ + src/lock/Mutex.c \ + src/lock/RWLock.c \ + src/lock/SpinLock.c \ + src/lock/FileLock.c \ + src/lock/Cond.c \ + src/network/Server.c \ + src/network/TaskWorker.c \ + src/network/Client.c \ + src/network/Connection.c \ + src/network/ProcessPool.c \ + src/network/ThreadPool.c \ + src/network/ReactorThread.c \ + src/network/ReactorProcess.c \ + src/network/Manager.c \ + src/network/Worker.c \ + src/network/Timer.c \ + src/network/Port.c \ + src/network/DNS.c \ + src/network/TimeWheel.c \ + src/network/Stream.c \ + src/os/base.c \ + src/os/msg_queue.c \ + src/os/sendfile.c \ + src/os/signal.c \ + src/os/timer.c \ + src/protocol/Base.c \ + src/protocol/SSL.c \ + src/protocol/Http.c \ + src/protocol/Http2.c \ + src/protocol/WebSocket.c \ + src/protocol/Mqtt.c \ + src/protocol/Socks5.c \ + src/protocol/MimeTypes.c \ + src/protocol/Redis.c \ + src/protocol/Base64.c" + + if test "$PHP_SWOOLE_STATIC" = "no"; then + swoole_source_file="$swoole_source_file thirdparty/php_http_parser.c" + else + CFLAGS="$CFLAGS -DSW_STATIC_COMPILATION" + fi + + swoole_source_file="$swoole_source_file thirdparty/multipart_parser.c" + + if test "$PHP_PICOHTTPPARSER" = "yes"; then + AC_DEFINE(SW_USE_PICOHTTPPARSER, 1, [enable picohttpparser support]) + swoole_source_file="$swoole_source_file thirdparty/picohttpparser/picohttpparser.c" + fi + + SW_NO_USE_ASM_CONTEXT="no" + SW_ASM_DIR="thirdparty/boost/asm/" + + AS_CASE([$host_cpu], + [x86_64*], [SW_CPU="x86_64"], + [x86*], [SW_CPU="x86"], + [arm*], [SW_CPU="arm"], + [arm64*], [SW_CPU="arm64"], + [ + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + ] + ) + + AS_CASE([$host_os], + [linux*], [SW_OS="LINUX"], + [darwin*], [SW_OS="MAC"], + [cygwin*], [SW_OS="WIN"], + [mingw*], [SW_OS="WIN"], + [ + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + ] + ) + + if test "$SW_CPU" = 'x86_64'; then + if test "$SW_OS" = 'LINUX'; then + SW_CONTEXT_ASM_FILE="x86_64_sysv_elf_gas.S" + elif test "$SW_OS" = 'MAC'; then + SW_CONTEXT_ASM_FILE="x86_64_sysv_macho_gas.S" + else + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + fi + elif test "$SW_CPU" = 'x86'; then + if test "$SW_OS" = 'LINUX'; then + SW_CONTEXT_ASM_FILE="i386_sysv_elf_gas.S" + elif test "$SW_OS" = 'MAC'; then + SW_CONTEXT_ASM_FILE="i386_sysv_macho_gas.S" + else + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + fi + elif test "$SW_CPU" = 'arm'; then + if test "$SW_OS" = 'LINUX'; then + SW_CONTEXT_ASM_FILE="arm_aapcs_elf_gas.S" + elif test "$SW_OS" = 'MAC'; then + SW_CONTEXT_ASM_FILE="arm_aapcs_macho_gas.S" + else + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + fi + elif test "$SW_CPU" = 'arm64'; then + if test "$SW_OS" = 'LINUX'; then + SW_CONTEXT_ASM_FILE="arm64_aapcs_elf_gas.S" + elif test "$SW_OS" = 'MAC'; then + SW_CONTEXT_ASM_FILE="arm64_aapcs_macho_gas.S" + else + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + fi + elif test "$SW_CPU" = 'mips32'; then + if test "$SW_OS" = 'LINUX'; then + SW_CONTEXT_ASM_FILE="mips32_o32_elf_gas.S" + else + SW_NO_USE_ASM_CONTEXT="yes" + AC_DEFINE([SW_NO_USE_ASM_CONTEXT], 1, [use boost asm context?]) + fi + fi + + if test "$SW_NO_USE_ASM_CONTEXT" = 'no'; then + swoole_source_file="$swoole_source_file ${SW_ASM_DIR}make_${SW_CONTEXT_ASM_FILE} \ + ${SW_ASM_DIR}jump_${SW_CONTEXT_ASM_FILE} " + elif test "$SW_HAVE_BOOST_CONTEXT" = 'yes'; then + LDFLAGS="$LDFLAGS -lboost_context" + fi + + PHP_NEW_EXTENSION(swoole, $swoole_source_file, $ext_shared,,, cxx) + + PHP_ADD_INCLUDE([$ext_srcdir]) + PHP_ADD_INCLUDE([$ext_srcdir/include]) + + PHP_INSTALL_HEADERS([ext/swoole], [*.h config.h include/*.h]) + + PHP_REQUIRE_CXX() + PHP_ADD_LIBRARY(stdc++, 1, SWOOLE_SHARED_LIBADD) + + if test "$PHP_PICOHTTPPARSER" = "yes"; then + PHP_ADD_INCLUDE([$ext_srcdir/thirdparty/picohttpparser]) + PHP_ADD_BUILD_DIR($ext_builddir/thirdparty/picohttpparser) + fi + + PHP_ADD_BUILD_DIR($ext_builddir/src/core) + PHP_ADD_BUILD_DIR($ext_builddir/src/memory) + PHP_ADD_BUILD_DIR($ext_builddir/src/factory) + PHP_ADD_BUILD_DIR($ext_builddir/src/reactor) + PHP_ADD_BUILD_DIR($ext_builddir/src/pipe) + PHP_ADD_BUILD_DIR($ext_builddir/src/lock) + PHP_ADD_BUILD_DIR($ext_builddir/src/os) + PHP_ADD_BUILD_DIR($ext_builddir/src/network) + PHP_ADD_BUILD_DIR($ext_builddir/src/protocol) + PHP_ADD_BUILD_DIR($ext_builddir/src/coroutine) + PHP_ADD_BUILD_DIR($ext_builddir/thirdparty) + PHP_ADD_BUILD_DIR($ext_builddir/thirdparty/boost) + PHP_ADD_BUILD_DIR($ext_builddir/thirdparty/boost/asm) +fi diff --git a/vendor/swoole/examples/async/dns_lookup.php b/vendor/swoole/examples/async/dns_lookup.php new file mode 100755 index 0000000..f884170 --- /dev/null +++ b/vendor/swoole/examples/async/dns_lookup.php @@ -0,0 +1,17 @@ +<?php +swoole_async_set(array( + //使用纯异步IO + 'use_async_resolver' => true, + 'disable_dns_cache' => true, + 'dns_lookup_random' => true, + 'dns_server' => '114.114.114.114', +)); +swoole_async_dns_lookup("www.sina.com.cn", function ($host, $ip) +{ + echo "{$host} reslove to {$ip}\n"; +}); + +swoole_async_dns_lookup("www.baidu.com", function ($host, $ip) +{ + echo "{$host} reslove to {$ip}\n"; +}); diff --git a/vendor/swoole/examples/async/exec.php b/vendor/swoole/examples/async/exec.php new file mode 100755 index 0000000..5010afc --- /dev/null +++ b/vendor/swoole/examples/async/exec.php @@ -0,0 +1,6 @@ +<?php +$pid = Swoole\Async::exec("ps aux", function ($result, $status) { + var_dump(strlen($result), $status); +}); + +var_dump($pid); diff --git a/vendor/swoole/examples/async/read.php b/vendor/swoole/examples/async/read.php new file mode 100755 index 0000000..4225795 --- /dev/null +++ b/vendor/swoole/examples/async/read.php @@ -0,0 +1,19 @@ +<?php +//ini_set("swoole.aio_mode", 1); +swoole_async_read( + __DIR__ . '/data.txt', + function ($filename, $content) + { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) + { + echo "file is end.\n"; + return false; + } + else + { + return true; + } + }, + 8192 +); diff --git a/vendor/swoole/examples/async/readfile.php b/vendor/swoole/examples/async/readfile.php new file mode 100755 index 0000000..53c2c69 --- /dev/null +++ b/vendor/swoole/examples/async/readfile.php @@ -0,0 +1,10 @@ +<?php +swoole_async::set(['aio_mode' => SWOOLE_AIO_LINUX]); + +swoole_async_readfile(__DIR__.'/../test.jpg', function($filename, $content){ + echo "file: $filename\ncontent-length: ".strlen($content)."\nContent:\n"; + swoole_async_writefile(__DIR__.'/test.copy', $content, function($write_file) { + echo "file: $write_file\n"; + swoole_event_exit(); + }); +}); diff --git a/vendor/swoole/examples/async/write.php b/vendor/swoole/examples/async/write.php new file mode 100755 index 0000000..1d54977 --- /dev/null +++ b/vendor/swoole/examples/async/write.php @@ -0,0 +1,12 @@ +<?php +function write_callback($file, $writen) +{ + echo "write $file [$writen]\n"; + //return true: write contine. return false: close the file. + return true; +} + +for ($i = 0; $i < 10; $i++) +{ + swoole_async_write("data.txt", str_repeat('A', 10) . "\n", -1, "write_callback"); +} diff --git a/vendor/swoole/examples/async/writefile.php b/vendor/swoole/examples/async/writefile.php new file mode 100755 index 0000000..f885ec9 --- /dev/null +++ b/vendor/swoole/examples/async/writefile.php @@ -0,0 +1,5 @@ +<?php +use Swoole\Async; + +//Async::set(array('aio_mode' => SWOOLE_AIO_LINUX)); +Async::writeFile(__DIR__.'/data2.txt', str_repeat('C', 1023)."\n", null, FILE_APPEND); diff --git a/vendor/swoole/examples/atomic/long.php b/vendor/swoole/examples/atomic/long.php new file mode 100755 index 0000000..fb825a8 --- /dev/null +++ b/vendor/swoole/examples/atomic/long.php @@ -0,0 +1,8 @@ +<?php +$l = new Swoole\Atomic\Long( -2 ** 36); +echo $l->get()."\n"; +echo $l->add(20)."\n"; +echo $l->sub(20)."\n"; +echo $l->sub(-20)."\n"; +echo $l->cmpset(-2 ** 36, 0)."\n"; +echo $l->cmpset(-2 ** 36 + 20, 0)."\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/atomic/test.php b/vendor/swoole/examples/atomic/test.php new file mode 100755 index 0000000..10b9bf4 --- /dev/null +++ b/vendor/swoole/examples/atomic/test.php @@ -0,0 +1,7 @@ +<?php +$atomic = new swoole_atomic(123); +echo $atomic->add(12)."\n"; +echo $atomic->sub(11)."\n"; +echo $atomic->cmpset(122, 999)."\n"; +echo $atomic->cmpset(124, 999)."\n"; +echo $atomic->get()."\n"; diff --git a/vendor/swoole/examples/atomic/wait.php b/vendor/swoole/examples/atomic/wait.php new file mode 100755 index 0000000..a4b4048 --- /dev/null +++ b/vendor/swoole/examples/atomic/wait.php @@ -0,0 +1,16 @@ +<?php +$n = new swoole_atomic(0); + +if (pcntl_fork() > 0) +{ + echo "master start\n"; + $n->wait(1.5); + echo "master end\n"; +} +else +{ + echo "child start\n"; + sleep(1); + $n->wakeup(); + echo "child end\n"; +} diff --git a/vendor/swoole/examples/buffer.php b/vendor/swoole/examples/buffer.php new file mode 100755 index 0000000..ab820d3 --- /dev/null +++ b/vendor/swoole/examples/buffer.php @@ -0,0 +1,15 @@ +<?php +$buffer = new swoole_buffer; +$buffer->append(str_repeat("A", 10)); +$buffer->append(str_repeat("B", 20)); +$buffer->append(str_repeat("C", 30)); + +var_dump($buffer); +echo $buffer->substr(0, 10, true)."\n"; +echo $buffer->substr(0, 20, true)."\n"; +echo $buffer->substr(0, 30)."\n"; +$buffer->clear(); + +echo $buffer->substr(0, 10, true)."\n"; +var_dump($buffer); +sleep(1); diff --git a/vendor/swoole/examples/c10k.php b/vendor/swoole/examples/c10k.php new file mode 100755 index 0000000..68bcd7d --- /dev/null +++ b/vendor/swoole/examples/c10k.php @@ -0,0 +1,29 @@ +<?php +$clients = array(); +for($j = 0; $j < 2; $j++) +{ + $pid = pcntl_fork(); + if($pid > 0) + { + continue; + } + else + { + for($i = 0; $i < 9999; $i++){ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 + $ret = $client->connect('127.0.0.1', 9501, 0.5); + if(!$ret) + { + echo "#$i\tConnect fail. errno=".$client->errCode; + die("\n"); + } + $clients[] = $client; + usleep(10); + } + echo "Worker #".posix_getpid()." connect $i finish\n"; + sleep(1000); + exit; + } +} +sleep(1000); + diff --git a/vendor/swoole/examples/channel.php b/vendor/swoole/examples/channel.php new file mode 100755 index 0000000..b866759 --- /dev/null +++ b/vendor/swoole/examples/channel.php @@ -0,0 +1,45 @@ +<?php +$chan = new Swoole\Channel(1024 * 256); +$n = 100000; +$bytes = 0; + +if (pcntl_fork() > 0) +{ + echo "Father\n"; + for ($i = 0; $i < $n; $i++) + { + $data = str_repeat('A', rand(100, 200)); + if ($chan->push($data) === false) + { + echo "channel full\n"; + usleep(1000); + $i--; + continue; + } + $bytes += strlen($data); +// echo "#$i\tpush ".strlen($data)." bytes\n"; + } + + echo "total push bytes: $bytes\n"; + var_dump($chan->stats()); +} +else +{ + echo "Child\n"; + for ($i = 0; $i < $n; $i++) + { + $data = $chan->pop(); + if ($data === false) + { + echo "channel empty\n"; + usleep(1000); + $i--; + continue; + } + $bytes += strlen($data); +// echo "#$i\tpop " . strlen($data) . " bytes\n"; + } + echo "total pop bytes: $bytes\n"; + var_dump($chan->stats()); +} + diff --git a/vendor/swoole/examples/channel/leader_follower.php b/vendor/swoole/examples/channel/leader_follower.php new file mode 100755 index 0000000..3410eca --- /dev/null +++ b/vendor/swoole/examples/channel/leader_follower.php @@ -0,0 +1,35 @@ +<?php +use Swoole\Timer; +use Swoole\Process; +use Swoole\Channel; + +$chan = new Channel(1024 * 256); + +$worker_num = 4; +$workers = array(); + +for ($i = 0; $i < $worker_num; $i++) +{ + $process = new Process(function ($worker) use ($chan, $i) + { + while (true) + { + $data = $chan->pop(); + if (empty($data)) + { + usleep(200000); + continue; + } + echo "worker#$i\t$data\n"; + } + }, false); + $process->id = $i; + $pid = $process->start(); + $workers[$pid] = $process; +} + +Timer::tick(2000, function () use ($chan) +{ + static $index = 0; + $chan->push("hello-" . $index++); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/client/async.php b/vendor/swoole/examples/client/async.php new file mode 100755 index 0000000..83de9fb --- /dev/null +++ b/vendor/swoole/examples/client/async.php @@ -0,0 +1,53 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); //异步非阻塞 +//$client->set(array( +// 'socket_buffer_size' => 1024 * 1024 * 2, +// 'open_eof_check' => true, +// 'package_eof' => "\r\n\r\n", +//)); + +$client->_count = 0; +$client->on("connect", function(swoole_client $cli) { + //swoole_timer_clear($cli->timer); + $cli->send("GET / HTTP/1.1\r\n\r\n"); + //$cli->sendfile(__DIR__.'/test.txt'); + //$cli->_count = 0; +}); + +$client->on("receive", function(swoole_client $cli, $data){ + echo "Receive: $data"; + $cli->_count++; + if ($cli->_count > 5) + { + //睡眠模式,不再接收新的数据 + echo "count=10, sleep(5000ms)\n"; + $cli->sleep(); + $cli->_count = 0; + swoole_timer_after(5000, function() use ($cli) { + //唤醒 + $cli->wakeup(); + }); + //$cli->close(); + return; + } + else + { + $cli->send(str_repeat('A', 100)."\n"); + } +}); + +$client->on("error", function(swoole_client $cli){ + echo "error\n"; +}); + +$client->on("close", function(swoole_client $cli){ + echo "Connection close\n"; +}); + +$client->connect('127.0.0.1', 9501); +//$client->timer = swoole_timer_after(1000, function () use ($client) { +// echo "socket timeout\n"; +// $client->close(); +//}); + +//echo "connect to 127.0.0.1:9501\n"; diff --git a/vendor/swoole/examples/client/get_socket.php b/vendor/swoole/examples/client/get_socket.php new file mode 100755 index 0000000..e106fde --- /dev/null +++ b/vendor/swoole/examples/client/get_socket.php @@ -0,0 +1,34 @@ +<?php + +function getClient() +{ + $client = new swoole_client(SWOOLE_SOCK_TCP); + if (!$client->connect('127.0.0.1', 9501, -1)) + { + exit("connect failed. Error: {$client->errCode}\n"); + } + + $res = $client->getSocket(); + return $client; +} + +$client = getClient(); + +$count = 0; +//$client->set(array('open_eof_check' => true, 'package_eof' => "\r\n\r\n")); + +//$client = new swoole_client(SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_SYNC); //同步阻塞 +//if (!$client->connect(dirname(__DIR__).'/server/svr.sock', 0, -1, 1)) + + +var_dump($client->getsockname()); +$client->send("hello world\r\n\r\n"); + +//for($i=0; $i < 3; $i ++) +{ + echo $client->recv(); + sleep(1); +} + +$client->close(); + diff --git a/vendor/swoole/examples/client/long_tcp.php b/vendor/swoole/examples/client/long_tcp.php new file mode 100755 index 0000000..69aaaef --- /dev/null +++ b/vendor/swoole/examples/client/long_tcp.php @@ -0,0 +1,18 @@ +<?php +for($i=0; $i < 100; $i++) +{ + $client = new swoole_client(SWOOLE_TCP | SWOOLE_KEEP); + if(!$client->connect('127.0.0.1', 9501)) + { + exit("connect failed\n"); + } + $client->send(str_repeat("A", 600)); + $data = $client->recv(7000, 0); + if($data === false) + { + echo "recv fail\n"; + break; + } + var_dump($data); + $client->close(); +} diff --git a/vendor/swoole/examples/client/select.php b/vendor/swoole/examples/client/select.php new file mode 100755 index 0000000..be4ce20 --- /dev/null +++ b/vendor/swoole/examples/client/select.php @@ -0,0 +1,32 @@ +<?php +$clients = array(); + +for($i=0; $i< 20; $i++) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 + $ret = $client->connect('127.0.0.1', 9501, 0.5, 0); + if(!$ret) + { + echo "Connect Server fail.errCode=".$client->errCode; + } + else + { + $client->send("HELLO WORLD\n"); + $clients[$client->sock] = $client; + } +} + +while (!empty($clients)) +{ + $write = $error = array(); + $read = array_values($clients); + $n = swoole_client_select($read, $write, $error, 0.6); + if ($n > 0) + { + foreach ($read as $index => $c) + { + echo "Recv #{$c->sock}: " . $c->recv() . "\n"; + unset($clients[$c->sock]); + } + } +} diff --git a/vendor/swoole/examples/client/sync.php b/vendor/swoole/examples/client/sync.php new file mode 100755 index 0000000..14963be --- /dev/null +++ b/vendor/swoole/examples/client/sync.php @@ -0,0 +1,30 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); +$count = 0; +//$client->set(array('open_eof_check' => true, 'package_eof' => "\r\n\r\n")); + +//$client = new swoole_client(SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_SYNC); //同步阻塞 +//if (!$client->connect(dirname(__DIR__).'/server/svr.sock', 0, -1, 1)) + +do_connect: +if (!$client->connect('127.0.0.1', 9501, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +var_dump($client->getsockname()); +$client->send("hello world\r\n\r\n"); + +//for($i=0; $i < 3; $i ++) +{ + echo $client->recv(); + sleep(1); +} + +$client->close(); +$count++; +if ($count < 20) +{ + goto do_connect; +} + diff --git a/vendor/swoole/examples/client/test.txt b/vendor/swoole/examples/client/test.txt new file mode 100755 index 0000000..b2aef93 --- /dev/null +++ b/vendor/swoole/examples/client/test.txt @@ -0,0 +1,10 @@ +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx +XXXXXXXXXXXXXXXXXXXXXXx +XXXXXXXXXXXXXXXXXXXXX +XXXXXXXXXXXXXXXXXXXXXXX +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB +TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT +DDDDDDDDDDDDDDDDDDDDDDDDDDD + diff --git a/vendor/swoole/examples/client/udp_async.php b/vendor/swoole/examples/client/udp_async.php new file mode 100755 index 0000000..33855fe --- /dev/null +++ b/vendor/swoole/examples/client/udp_async.php @@ -0,0 +1,23 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); //异步非阻塞 + +$client->on("connect", function(swoole_client $cli) { + echo "connected\n"; + $cli->send("hello world\n"); +}); + +$client->on('close', function($cli){ + echo "closed\n"; +}); + +$client->on('error', function($cli){ + echo "error\n"; +}); + +$client->on("receive", function(swoole_client $cli, $data){ + echo "received: $data\n"; + sleep(1); + $cli->send("hello_".rand(1000,9999)); +}); + +$client->connect('127.0.0.1', 9502, 0.5); diff --git a/vendor/swoole/examples/client/udp_sync.php b/vendor/swoole/examples/client/udp_sync.php new file mode 100755 index 0000000..8291715 --- /dev/null +++ b/vendor/swoole/examples/client/udp_sync.php @@ -0,0 +1,12 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC); +$client->connect('127.0.0.1', 9502); + +for ($i = 0; $i < 100; $i++) +{ + $client->send("admin"); + echo $client->recv()."\n"; + sleep(1); +} + + diff --git a/vendor/swoole/examples/client2.php b/vendor/swoole/examples/client2.php new file mode 100755 index 0000000..e767113 --- /dev/null +++ b/vendor/swoole/examples/client2.php @@ -0,0 +1,21 @@ +<?php +$clients = array(); +for($i = 0; $i < 1; $i++){ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 + $ret = $client->connect('127.0.0.1', 9501, 0.5, 0); + if(!$ret) + { + echo "Over flow. errno=".$client->errCode; + die("\n"); + } + $clients[] = $client; +} +sleep(1); +while (1) { + foreach ($clients as $client) { + $client->send("sss"); + $data = $client->recv(); + var_dump($data); + } + sleep(1); +} diff --git a/vendor/swoole/examples/coroutine/TestHttpServ.php b/vendor/swoole/examples/coroutine/TestHttpServ.php new file mode 100755 index 0000000..8029d92 --- /dev/null +++ b/vendor/swoole/examples/coroutine/TestHttpServ.php @@ -0,0 +1,117 @@ +<?php +/** + * @Author: winterswang + * @Date: 2015-06-18 16:45:09 + * @Last Modified by: winterswang + * @Last Modified time: 2016-09-18 17:33:51 + */ + +class TestHttpServer { + + public $http; + public $queue; + public $setting = array(); + + /** + * [__construct description] + * @param array $setting [description] + */ + public function __construct(){ + + } + + public function set($setting){ + + $this ->setting = $setting; + } + + /** + * [init description] + * @return [type] [description] + */ + public function init(){ + + if (!isset($this ->setting['host'])) { + $this ->setting['host'] = '0.0.0.0'; + } + if (!isset($this ->setting['port'])) { + $this ->setting['port'] = '9999'; + } + + $this ->http = new swoole_http_server($this ->setting['host'], $this ->setting['port']); + $this ->http ->set($this ->setting); + + $this ->http ->on('request', array($this, 'onRequest')); + $this ->http ->on('close', array($this, 'onClose')); + } + + /** + * [onRequest description] + * @param [type] $request [description] + * @param [type] $response [description] + * @return [type] [description] + */ + public function onRequest($request, $response){ + + // $udp = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); + // $udp->on("connect", function(swoole_client $cli) { + // $cli->send("udp test"); + // }); + // $udp->on("receive", function(swoole_client $cli, $data)use($response){ + + $tcp = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $tcp->on("connect", function(swoole_client $cli) { + $cli->send("tcp test"); + }); + $tcp->on("receive", function(swoole_client $cli, $data)use($response){ + $response ->end("<h1> swoole response</h1>"); + }); + $tcp->on("close", function(swoole_client $cli){ + }); + $tcp->on("error", function(swoole_client $cli){ + }); + $tcp->connect('10.100.64.151', 9805); + + // }); + // $udp->on("close", function(swoole_client $cli){ + // }); + // $udp->connect('10.100.65.222', 9906); + + } + + /** + * [onClose description] + * @param [type] $server [description] + * @param [type] $fd [description] + * @param [type] $from_id [description] + * @return [type] [description] + */ + public function onClose($server, $fd, $from_id){ + + //echo " on close fd = $fd from_id = $from_id \n"; + } + + /** + * [start description] + * @return [type] [description] + */ + public function start(){ + + $this ->init(); + $this ->http ->start(); + } +} + +$setting = array( + 'host' => '0.0.0.0', + 'port' => 10005, + 'worker_num' => 4, + 'dispatch_mode' => 2, //固定分配请求到worker + 'reactor_num' => 4, //亲核 + 'daemonize' => 1, //守护进程 + 'backlog' => 128, + 'log_file' => '/data/log/test_http_server.log', +); +$th = new TestHttpServer(); +$th ->set($setting); +$th ->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/client_send_yield.php b/vendor/swoole/examples/coroutine/client_send_yield.php new file mode 100755 index 0000000..2392b4d --- /dev/null +++ b/vendor/swoole/examples/coroutine/client_send_yield.php @@ -0,0 +1,27 @@ +<?php +go(function () { + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $client->set(array( + 'socket_buffer_size' => 1024 * 512, + )); + if (!$client->connect('127.0.0.1', 9501, -1)) + { + exit("connect failed. Error: {$client->errCode}\n"); + } + $length = 0; + $size = 1024 * 64; + while (true) + { + $ret = $client->send(str_repeat('A', $size)); + if ($ret == false) + { + var_dump($ret); + break; + } + $length += $size; + echo "send $length success\n"; + } + var_dump($client->errCode); +}); + +swoole_event_wait(); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/client_send_yield_server.php b/vendor/swoole/examples/coroutine/client_send_yield_server.php new file mode 100755 index 0000000..dcc1451 --- /dev/null +++ b/vendor/swoole/examples/coroutine/client_send_yield_server.php @@ -0,0 +1,27 @@ +<?php +$socket = stream_socket_server("tcp://0.0.0.0:9501", $errno, $errstr); +if (!$socket) { + echo "$errstr ($errno)<br />\n"; +} else { + while (true) { + $conn = stream_socket_accept($socket); + if (!$conn) { + continue; + } + $i = 0; + $length = 0; + while(true) { + $data = fread($conn, 8192); + if ($data == false) + { + break; + } + $length += strlen($data); + echo "recv " . $length . " bytes\n"; + usleep(100000); + } + fclose($conn); + echo "closed\n"; + } + fclose($socket); +} diff --git a/vendor/swoole/examples/coroutine/coro_array_map.php b/vendor/swoole/examples/coroutine/coro_array_map.php new file mode 100755 index 0000000..b068eda --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_array_map.php @@ -0,0 +1,19 @@ +<?php + +use Swoole\Coroutine as co; + +co::create(function() { + array_map("test",array("func param\n")); + echo "co flow end\n"; +}); + +function test($p) { + go(function() use ($p){ + echo $p; + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 1); + echo "co resume : connect ret = ".var_export($res,1)."\n"; + echo "map func end \n"; + }); +} +echo "main end\n"; diff --git a/vendor/swoole/examples/coroutine/coro_call_user.php b/vendor/swoole/examples/coroutine/coro_call_user.php new file mode 100755 index 0000000..0f4550f --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_call_user.php @@ -0,0 +1,20 @@ +<?php +use Swoole\Coroutine as co; +co::set(['trace_flags' => 1]); + +co::create(function() { + echo "co func start\n"; + $name = "call_user_func"; + $ret = $name("test","test\n"); + echo "co func end ret:{$ret}\n"; +}); + +function test($params) +{ + echo "func params:$params"; + co::sleep(1); + echo "func end\n"; + return "test return\n"; +} +echo "main script last\n"; + diff --git a/vendor/swoole/examples/coroutine/coro_channel.php b/vendor/swoole/examples/coroutine/coro_channel.php new file mode 100755 index 0000000..18938ce --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_channel.php @@ -0,0 +1,25 @@ +<?php +$http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); +$http->set(array( + 'log_file' => '/dev/null' +)); +use Swoole\Coroutine as co; +// $http->on("WorkerStart", function (\swoole_server $serv) +// { +// +// }); +$http->on('request', function (swoole_http_request $request, swoole_http_response $response) +{ + $ch = new co\Channel(1); + $out = new co\Channel(1); + Swoole\Coroutine::create(function() use ($ch, $out) { + $out->push("OK"); + $out->push("OK"); + }); + $ret = $out->pop(); + var_dump($ret); + $ret = $out->pop(); + var_dump($ret); + $response->end("$ret\n"); +}); +$http->start(); diff --git a/vendor/swoole/examples/coroutine/coro_destruct.php b/vendor/swoole/examples/coroutine/coro_destruct.php new file mode 100755 index 0000000..a25e142 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_destruct.php @@ -0,0 +1,28 @@ +<?php +use Swoole\Coroutine as co; +class T +{ + function __construct() + { + + } + + function test() + { + echo "call function \n"; + } + + function __destruct() + { + go(function () { + echo "coro start\n"; + co::sleep(1.0); + echo "coro exit\n"; + }); + echo "111\n"; + } +} + +$t = new T(); +$t->test(); +echo "end \n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/coro_destuct.php b/vendor/swoole/examples/coroutine/coro_destuct.php new file mode 100755 index 0000000..92d6068 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_destuct.php @@ -0,0 +1,32 @@ +<?php +require __DIR__ . "/coro_include.php"; + +class T +{ + function __construct() + { + echo "call __construct \n"; + } + + function test() + { + echo "call function \n"; + } + + function __destruct() + { + echo "call __destruct \n"; + go(function () { + echo "co[1] start\n"; + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 1); + co::sleep(1.0); + echo "co[1] resume : connect ret = ".var_export($res,1)."\n"; + echo "co[1] exit\n"; + }); + } +} + +$t = new T(); +$t->test(); +unset($t); diff --git a/vendor/swoole/examples/coroutine/coro_empty.php b/vendor/swoole/examples/coroutine/coro_empty.php new file mode 100755 index 0000000..1f1ea9a --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_empty.php @@ -0,0 +1,9 @@ +<?php +use Swoole\Coroutine as co; +// co::set(['trace_flags' => 1]); + +co::create(function () { + echo "no coro exit\n"; +}); +echo "exec file end\n"; + diff --git a/vendor/swoole/examples/coroutine/coro_gethost.php b/vendor/swoole/examples/coroutine/coro_gethost.php new file mode 100755 index 0000000..113574b --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_gethost.php @@ -0,0 +1,11 @@ +<?php +require __DIR__ . "/coro_include.php"; +use Swoole\Coroutine as co; + +co::create(function () { + $ip = co::gethostbyname('www.baidu.com'); + var_dump($ip); +}); +echo "111\n"; + +echo "222\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/coro_include.php b/vendor/swoole/examples/coroutine/coro_include.php new file mode 100755 index 0000000..b8637ac --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_include.php @@ -0,0 +1,9 @@ +<?php +if (substr(PHP_OS, 0, 3) == 'WIN') +{ + exit("skip for Windows"); +} +if (!extension_loaded("swoole")) +{ + exit("swoole extension is required"); +} \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/coro_invoke.php b/vendor/swoole/examples/coroutine/coro_invoke.php new file mode 100755 index 0000000..9cd6d90 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_invoke.php @@ -0,0 +1,22 @@ +<?php +use Swoole\Coroutine as co; +co::set(['trace_flags' => 1]); + +co::create(function() { + + + $function = new ReflectionFunction('title'); + + $function->invoke(); + echo "invoke444\n"; + +}); + +function title() { + echo "333invoke_________________________________\n"; + $tcpclient = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + var_dump($tcpclient->connect('127.0.0.1', 9501, 1)); + +} + +echo "111\n"; diff --git a/vendor/swoole/examples/coroutine/coro_nested.php b/vendor/swoole/examples/coroutine/coro_nested.php new file mode 100755 index 0000000..3ee6698 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_nested.php @@ -0,0 +1,18 @@ +<?php +require __DIR__ . "/coro_include.php"; +echo "before coro\n"; +go(function () { + echo "co[1] start\n"; + go(function () { + echo "co[2] start\n"; + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 1); + echo "co[2] resume : connect ret = ".var_export($res,1)."\n"; + echo "co[2] exit\n"; + }); + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 1); + echo "co[1] resume : connect ret = ".var_export($res,1)."\n"; + echo "co[1] exit\n"; +}); +echo "out coro \n"; diff --git a/vendor/swoole/examples/coroutine/coro_nested_empty.php b/vendor/swoole/examples/coroutine/coro_nested_empty.php new file mode 100755 index 0000000..e14bae2 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_nested_empty.php @@ -0,0 +1,16 @@ +<?php +require __DIR__ . "/coro_include.php"; +function test() +{ + echo "before coro\n"; + go(function () { + echo "co[1] start\n"; + go(function () { + echo "co[2] start\n"; + echo "co[2] exit\n"; + }); + echo "co[1] exit\n"; + }); + echo "func end \n"; +} +test(); diff --git a/vendor/swoole/examples/coroutine/coro_serialize.php b/vendor/swoole/examples/coroutine/coro_serialize.php new file mode 100755 index 0000000..14bf7b2 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_serialize.php @@ -0,0 +1,39 @@ +<?php +use Swoole\Coroutine as co; +class Obj { + public $a; + protected $b; + private $c; + var $d; + + function __construct($a, $b, $c, $d) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + // co::sleep(0.5); + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 10); + var_dump($res); + if ($res) + { + echo("connect success. Error: {$client->errCode}\n"); + } + echo "sleep\n"; + return array('a', 'b', 'c'); + } + + // function __wakeup() { + // $this->d = $this->a + $this->b + $this->c; + // } +} +$o = new Obj(1, 2, 3, 4); +co::create(function() use($o) { + $serialized = serialize($o); + $unserialized = unserialize($serialized); + echo "res:".var_export($unserialized,1)."\n"; + echo "call user\n"; +}); diff --git a/vendor/swoole/examples/coroutine/coro_sleep.php b/vendor/swoole/examples/coroutine/coro_sleep.php new file mode 100755 index 0000000..50468f7 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_sleep.php @@ -0,0 +1,9 @@ +<?php +// require __DIR__ . "/coro_include.php"; +use Swoole\Coroutine as co; +co::create(function () { + echo "start\n"; + co::sleep(0.5); + echo "OK\n"; +}); +echo "11\n"; diff --git a/vendor/swoole/examples/coroutine/coro_stackless.php b/vendor/swoole/examples/coroutine/coro_stackless.php new file mode 100755 index 0000000..904ea92 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_stackless.php @@ -0,0 +1,19 @@ +<?php +require __DIR__ . "/coro_include.php"; +use Swoole\Coroutine as co; + +echo "start\n"; +co::create(function () { + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $res = $client->connect('127.0.0.1', 9501, 1); + var_dump($res); + if ($res) { + echo ("connect success. Error: {$client->errCode}\n"); + } + + $res = $client->send("hello"); + echo "send res:" . var_export($res, 1) . "\n"; + $data = $client->recv(); + echo "recv data" . var_export($data, 1) . "\n"; +}); +echo "end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/coro_util.php b/vendor/swoole/examples/coroutine/coro_util.php new file mode 100755 index 0000000..c67f918 --- /dev/null +++ b/vendor/swoole/examples/coroutine/coro_util.php @@ -0,0 +1,16 @@ +<?php +use Swoole\Coroutine as co; + +$id = go(function(){ + $id = co::getUid(); + echo "start coro $id\n"; + co::suspend($id); + echo "resume coro $id @1\n"; + co::suspend($id); + echo "resume coro $id @2\n"; +}); +echo "start to resume $id @1\n"; +co::resume($id); +echo "start to resume $id @2\n"; +co::resume($id); +echo "main\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/defer_client.php b/vendor/swoole/examples/coroutine/defer_client.php new file mode 100755 index 0000000..94112dc --- /dev/null +++ b/vendor/swoole/examples/coroutine/defer_client.php @@ -0,0 +1,79 @@ +<?php +/* new multi implement test */ +$server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE); + +$server->set([ + 'worker_num' => 1, +]); + +$server->on('Request', function ($request, $response) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $redis->setDefer(true); + $redis->get('key'); + $res = $redis->get('key');//get false + var_dump($res); + + var_dump($redis->setDefer());//get true + var_dump($redis->setDefer(false));//get false + + //穿插其他client也能正常工作 + $redis_tmp = new Swoole\Coroutine\Redis(); + $res = $redis_tmp->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $res = $redis_tmp->set('key_tmp', 'HaHa');//get true + var_dump($res); + + + $http_client= new Swoole\Coroutine\Http\Client('km.oa.com', 80); + $http_client->setDefer(); + $http_client->get('/'); + + $mysql = new Swoole\Coroutine\MySQL(); + $res = $mysql->connect(['host' => '192.168.244.128', 'user' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt']); + if ($res == false) { + $response->end("MySQL connect fail!"); + return; + } + $mysql->setDefer(true); + $mysql->query('select sleep(1)', 2); + + $udp = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + $res = $udp->connect("127.0.0.1", 9906, 2); + $udp->send('Hello World!'); + + //穿插其他client也能正常工作 + $udp_tmp = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + $res = $udp_tmp->connect("127.0.0.1", 9909, 2);//nonexistent server + $res = $udp_tmp->recv();//get false with timeout + var_dump($res); + + $udp_res = $udp->recv(); + $res = $mysql->query('select sleep(1)', 2);//get false + var_dump($res); + $res = $mysql->setDefer(false); + var_dump($res);//get false + $res = $mysql->setDefer(); + var_dump($res);//get true + $mysql_res = $mysql->recv(); + $res = $redis->get('key');//get false + var_dump($res); + $redis_res = $redis->recv(); + $res = $http_client->get('/'); + var_dump($res);//get false + $res = $http_client->recv(); + var_dump($res);//get true + + var_dump($udp_res, $mysql_res, $redis_res, $http_client); + var_dump($http_client->setDefer(false)); + var_dump($mysql->getDefer(), $redis->getDefer(), $http_client->getDefer()); + $response->end('Test End'); +}); +$server->start(); diff --git a/vendor/swoole/examples/coroutine/enable_coroutine.php b/vendor/swoole/examples/coroutine/enable_coroutine.php new file mode 100755 index 0000000..8e63806 --- /dev/null +++ b/vendor/swoole/examples/coroutine/enable_coroutine.php @@ -0,0 +1,27 @@ +<?php + +use Swoole\Http\Request; +use Swoole\Http\Response; + +$http = new swoole_http_server('127.0.0.1', 9501); + +$http->set([ + 'enable_coroutine' => false, // close build-in coroutine +]); + +$http->on('workerStart', function () { + echo "Coroutine is " . (Co::getuid() > 0 ? 'enable' : 'disable')."\n"; +}); + +$http->on("request", function (Request $request, Response $response) { + $response->header("Content-Type", "text/plain"); + if ($request->server['request_uri'] == '/co') { + go(function () use ($response) { + $response->end("Hello Coroutine #" . Co::getuid()); + }); + } else { + $response->end("Hello Swoole #" . Co::getuid()); + } +}); + +$http->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/exception/empty.php b/vendor/swoole/examples/coroutine/exception/empty.php new file mode 100755 index 0000000..07d2a2e --- /dev/null +++ b/vendor/swoole/examples/coroutine/exception/empty.php @@ -0,0 +1,16 @@ +<?php +go(function () { + try { + echo "before\n"; + co::sleep(0.5); + echo "after\n"; + throw new Exception('coro Exception.'); + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "First finally.\n"; + } +}); +echo "exec file end\n"; + + \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/fgets.php b/vendor/swoole/examples/coroutine/fgets.php new file mode 100755 index 0000000..a2b8878 --- /dev/null +++ b/vendor/swoole/examples/coroutine/fgets.php @@ -0,0 +1,20 @@ +<?Php +$fp = fopen(__DIR__ . "/defer_client.php", "r"); +stream_set_chunk_size($fp, 1024); + +go(function () use ($fp) +{ + for($i = 0; $i<100;$i++) { + $r = co::fgets($fp); + if (empty($r) and feof($fp)) + { + //echo "EOF\n"; + break; + } + //echo "len=".strlen($r)."\n"; + echo $r; + //echo "---------------------------------------\n"; + //var_dump($r); + //co::sleep(1); + } +}); diff --git a/vendor/swoole/examples/coroutine/fread.php b/vendor/swoole/examples/coroutine/fread.php new file mode 100755 index 0000000..9b0c8a1 --- /dev/null +++ b/vendor/swoole/examples/coroutine/fread.php @@ -0,0 +1,11 @@ +<?php +use Swoole\Coroutine as co; + +$fp = fopen(__DIR__ . "/defer_client.php", "r"); + +co::create(function () use ($fp) +{ + fseek($fp, 256); + $r = co::fread($fp); + var_dump($r); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/fwrite.php b/vendor/swoole/examples/coroutine/fwrite.php new file mode 100755 index 0000000..897d81e --- /dev/null +++ b/vendor/swoole/examples/coroutine/fwrite.php @@ -0,0 +1,10 @@ +<?php +use Swoole\Coroutine as co; + +$fp = fopen(__DIR__ . "/test.data", "a+"); + +co::create(function () use ($fp) +{ + $r = co::fwrite($fp, "hello world\n", 5); + var_dump($r); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/gethostbyname.php b/vendor/swoole/examples/coroutine/gethostbyname.php new file mode 100755 index 0000000..87d1769 --- /dev/null +++ b/vendor/swoole/examples/coroutine/gethostbyname.php @@ -0,0 +1,8 @@ +<?php +use Swoole\Coroutine as co; + +co::create(function() { + $ip = co::gethostbyname("www.baidu.com"); + echo "IP: $ip\n"; +}); + diff --git a/vendor/swoole/examples/coroutine/http2_client.php b/vendor/swoole/examples/coroutine/http2_client.php new file mode 100755 index 0000000..e175d07 --- /dev/null +++ b/vendor/swoole/examples/coroutine/http2_client.php @@ -0,0 +1,71 @@ +<?php +use Swoole\Coroutine as co; + +//const TEST = array('get', 'post', 'pipeline'); +const TEST = array('pipeline'); + +co::create(function () use ($fp) +{ + $cli = new co\Http2\Client('127.0.0.1', 9518); + + $cli->set([ 'timeout' => 1]); + var_dump($cli->connect()); + + if (in_array('get', TEST)) + { + $req = new co\Http2\Request; + $req->path = "/index.html"; + $req->headers = [ + 'host' => "localhost", + "user-agent" => 'Chrome/49.0.2587.3', + 'accept' => 'text/html,application/xhtml+xml,application/xml', + 'accept-encoding' => 'gzip', + ]; + $req->cookies = ['name' => 'rango', 'email' => '1234@qq.com']; + var_dump($cli->send($req)); + + $resp = $cli->recv(); + var_dump($resp); + } + + if (in_array('post', TEST)) + { + $req2 = new co\Http2\Request; + $req2->path = "/index.php"; + $req2->headers = [ + 'host' => "localhost", + "user-agent" => 'Chrome/49.0.2587.3', + 'accept' => 'text/html,application/xhtml+xml,application/xml', + 'accept-encoding' => 'gzip', + ]; + $req2->data = "hello world\n"; + var_dump($cli->send($req2)); + + $resp = $cli->recv(); + var_dump($resp); + } + + if (in_array('pipeline', TEST)) + { + $req3 = new co\Http2\Request; + $req3->path = "/index.php"; + $req3->headers = [ + 'host' => "localhost", + "user-agent" => 'Chrome/49.0.2587.3', + 'accept' => 'text/html,application/xhtml+xml,application/xml', + 'accept-encoding' => 'gzip', + ]; + $req3->pipeline = true; + $req3->method = "POST"; + $streamId = $cli->send($req3); + + $cli->write($streamId, ['int' => rand(1000, 9999)]); + $cli->write($streamId, ['int' => rand(1000, 9999)]); + //end stream + $cli->write($streamId, ['int' => rand(1000, 9999), 'end' => true], true); + + var_dump($cli->recv()); + } + +// $cli->close(); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/http_backend_serv.php b/vendor/swoole/examples/coroutine/http_backend_serv.php new file mode 100755 index 0000000..b57c919 --- /dev/null +++ b/vendor/swoole/examples/coroutine/http_backend_serv.php @@ -0,0 +1,43 @@ +<?php +/** + * @Author: syyuanyizhi@163.com + connect refuse: errorCode 111 + I/O timeout:errorCode 110 + http 9510 + tcp 9511 + + */ +class Server +{ + public $server; + + public function run() + { + $this->server = new Swoole\Http\Server("0.0.0.0", 9510); + $this->server->set([ + 'worker_num' => 1, + 'daemonize' => true, + 'log_file' => '/data/markyuan/swoole.log', + ]); + $this->server->on('Request', ['Server', 'onRequest']); + $this->server->start(); + } + public static function onRequest($request, $response) + { + + $response->end('xxxx'); + } + + + public static function staticFunc() + { + echo "in static function"; + } +} + +$server = new Server(); + +$server->run(); + + + diff --git a/vendor/swoole/examples/coroutine/http_client.php b/vendor/swoole/examples/coroutine/http_client.php new file mode 100755 index 0000000..b4bc0f9 --- /dev/null +++ b/vendor/swoole/examples/coroutine/http_client.php @@ -0,0 +1,12 @@ +<?php +use Swoole\Coroutine as co; +co::create(function () { + $cli = new co\http\client('127.0.0.1', 9501); + $cli->setHeaders(['Host' => 'localhost']); + $cli->set(['http_proxy_host' => HTTP_PROXY_HOST, 'http_proxy_port' => HTTP_PROXY_PORT]); + $result = $cli->get('/get?json=true'); + var_dump($cli->body); +// assert($result); +// $ret = json_decode($cli->body, true); +// assert(is_array($ret) and $ret['json'] == 'true'); +}); diff --git a/vendor/swoole/examples/coroutine/http_download.php b/vendor/swoole/examples/coroutine/http_download.php new file mode 100755 index 0000000..8820780 --- /dev/null +++ b/vendor/swoole/examples/coroutine/http_download.php @@ -0,0 +1,13 @@ +<?php +go(function () { + $host = 'www.swoole.com'; + $cli = new \Swoole\Coroutine\Http\Client($host, 443, true); + $cli->set(['timeout' => -1]); + $cli->setHeaders([ + 'Host' => $host, + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => '*', + 'Accept-Encoding' => 'gzip' + ]); + $cli->download('/static/files/swoole-logo.svg', __DIR__ . '/logo.svg'); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/http_server.php b/vendor/swoole/examples/coroutine/http_server.php new file mode 100755 index 0000000..0d1b99a --- /dev/null +++ b/vendor/swoole/examples/coroutine/http_server.php @@ -0,0 +1,37 @@ +<?php +ini_set("memory_limit","512M"); +use Swoole\Coroutine as co; +class Server +{ + public $server; + public $redisPool = []; + + public function run() + { + $this->server = new Swoole\Http\Server("0.0.0.0", 9502, SWOOLE_BASE); + $this->server->set([ + 'worker_num' => 1, + ]); + + // $this->server->on('Connect', [$this, 'onConnect']); + $this->server->on('Request', [$this, 'onRequest']); +// $this->server->on('Close', [$this, 'onClose']); + $this->server->set(['trace_flags' => 1 << 15, 'log_level' => 0]); + $this->server->start(); + } + + public function onRequest($request, $response) + { + $fd = $request->fd; + co::create(function () { + co::sleep(0.1); + }); + $response->end(111); + } +} + +$server = new Server(); +Swoole\Coroutine::set(array( + 'max_coroutine' => 1000, +)); +$server->run(); diff --git a/vendor/swoole/examples/coroutine/httpmulti.php b/vendor/swoole/examples/coroutine/httpmulti.php new file mode 100755 index 0000000..20ead87 --- /dev/null +++ b/vendor/swoole/examples/coroutine/httpmulti.php @@ -0,0 +1,165 @@ +<?php +/** + * @Author: syyuanyizhi@163.com + connect refuse: errorCode 111 + I/O timeout:errorCode 110 + http 9510 + tcp 9511 + + */ +class Server +{ + public $server; + + public function run() + { + $this->server = new Swoole\Http\Server("0.0.0.0", 9508); + $this->server->set([ + 'worker_num' => 1, + 'daemonize' => true, + 'log_file' => '/data/markyuan/swoole.log', + ]); + $this->server->on('Request', ['Server', 'onRequest']); + $this->server->start(); + } + + private static function https(){ + //--enable-openssl + for($i=0;$i<2;$i++){ + $cli = new Swoole\Coroutine\Http\Client('0.0.0.0',443,TRUE ); + $cli->set([ 'timeout' => 1]); + $cli->setHeaders([ + 'Host' => "api.mp.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $ret = ($cli->get('/cgi-bin/token?appid=3333&secret=222'.$i.$i.$i.$i.$i)); + error_log(__LINE__.var_export($cli,true).PHP_EOL,3,'/tmp/markyuan'); + $cli->close(); + } + } + + private static function http(){ + error_log(__LINE__.'---------- begin --- http --------------'.PHP_EOL,3,'/tmp/markyuan'); + for($i=0;$i<2;$i++){ + $cli = new Swoole\Coroutine\Http\Client('0.0.0.0', 9510); + $cli->set([ 'timeout' => 1]); + $cli->setHeaders([ + 'Host' => "api.mp.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + error_log(__LINE__.var_export($cli,true).PHP_EOL,3,'/tmp/markyuan'); + $ret = ($cli->get('/cn/token?appid=1FxxxxS9V'.$i.$i.$i.$i.$i)); + error_log(__LINE__.var_export($ret,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cli,true).PHP_EOL,3,'/tmp/markyuan'); + $cli->close(); + } + error_log(__LINE__.'---------- end --- http --------------'.PHP_EOL,3,'/tmp/markyuan'); + + } + + private static function multihttp(){ + + error_log(__LINE__.'---------- begin --- multi --------------'.PHP_EOL,3,'/tmp/markyuan'); + + $cliAA= new Swoole\Coroutine\Http\Client('0.0.0.0', 9510); + $cliAA->set(['timeout' => 1]); + $cliAA->setHeaders([ + 'Host' => "api.mp.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + ]); + $cliBB= new Swoole\Coroutine\Http\Client('0.0.0.0', 9510); + $cliBB->set([ 'timeout' => 1]);// + $cliBB->setHeaders([ + 'Host' => "api.mp.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + ]); + error_log(__LINE__.var_export($cliAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliBB,true).PHP_EOL,3,'/tmp/markyuan'); + $retAA=$cliAA->setDefer(1); + $retBB=$cliBB->setDefer(1); + error_log(__LINE__.var_export($retAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($retBB,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliBB,true).PHP_EOL,3,'/tmp/markyuan'); + $retAA = ($cliAA->get('/cn/token?appid=AAA')); + $retBB = ($cliBB->get('/cn/token?appid=BBB')); + error_log(__LINE__.var_export($retAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($retBB,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliBB,true).PHP_EOL,3,'/tmp/markyuan'); + $retAA=$cliAA->recv(); + $retBB=$cliBB->recv(); + error_log(__LINE__.var_export($retAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($retBB,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliAA,true).PHP_EOL,3,'/tmp/markyuan'); + error_log(__LINE__.var_export($cliBB,true).PHP_EOL,3,'/tmp/markyuan'); + $retAA=$cliAA->close(); + $retBB=$cliBB->close(); + error_log(__LINE__.'---------- end --- multi --------------'.PHP_EOL,3,'/tmp/markyuan'); + } + + + + private static function tcp(){ + for($i=0;$i<2;$i++){ + $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $ret = $tcp_cli ->connect("0.0.0.0", 9511); + $ret = $tcp_cli ->send('test for the coro'); + $ret = $tcp_cli ->recv(); + $ret=$tcp_cli->close(); + } + } + + private static function coro_dns(){ + swoole_async_set(array('use_async_resolver'=>1)); + swoole_async_set(array('dns_cache_refresh_time'=>0)); + $ret=swoole_async_dns_lookup_coro("www.baidu.com",0.5); + error_log(' ip and host '.$host.print_r($ret,true),'3','/home/yuanyizhi/markyuan/markyuan.log'); + return $ret; +// swoole_async_dns_lookup("www.baidu.com", function($host, $ip){ +// error_log(' ip and host '.$host.' and ip '.$ip,'3','/home/yuanyizhi/markyuan/markyuan.log'); +// }); + } + + +private static function tcpmulti(){ + $cliAA = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $cliBB = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $retAA = $cliAA ->connect("0.0.0.0", 9511); + $retBB = $cliBB ->connect("0.0.0.0", 9511); + $retAA = $cliAA ->send('test for the coro'); + $retBB = $cliBB ->send('test for the coro'); + $retAA = $cliAA->recv(); + $retBB = $cliBB->recv(); + $cliAA->close(); + $cliBB->close(); + } + + public static function onRequest($request, $response) + { +// self::multihttp(); +// self::http(); + //self::https(); +// self::tcp(); + // self::tcpmulti(); + $ret=self::coro_dns(); + $response->end(print_r($ret,true)); + } + + + public static function staticFunc() + { + echo "in static function"; + } +} + +$server = new Server(); + +$server->run(); + + + diff --git a/vendor/swoole/examples/coroutine/mysql_chan.php b/vendor/swoole/examples/coroutine/mysql_chan.php new file mode 100755 index 0000000..206cf58 --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_chan.php @@ -0,0 +1,32 @@ +<?php + +use Swoole\Coroutine as co; + +$chan = new chan(4); + +go(function () use ($chan) { + + $db = new co\MySQL(); + $server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', + ); + + echo "connect\n"; + $ret1 = $db->connect($server); + var_dump($ret1); + + echo "prepare\n"; + $ret2 = $db->query('SELECT * FROM userinfo WHERE id=3'); + var_dump($ret2); + + $chan->push($db); +}); + +go(function () use ($chan) { + $db = $chan->pop(); + $ret2 = $db->query('SELECT * FROM userinfo WHERE id=3'); + var_dump($ret2); +}); diff --git a/vendor/swoole/examples/coroutine/mysql_execute_empty.php b/vendor/swoole/examples/coroutine/mysql_execute_empty.php new file mode 100755 index 0000000..47c693a --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_execute_empty.php @@ -0,0 +1,14 @@ +<?php +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test' + ]; + $db->connect($server); + $stmt = $db->prepare('SELECT * FROM `userinfo`'); + $ret = $stmt->execute(); + var_dump($ret); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/mysql_prepare.php b/vendor/swoole/examples/coroutine/mysql_prepare.php new file mode 100755 index 0000000..1f4b6be --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_prepare.php @@ -0,0 +1,42 @@ +<?php +use Swoole\Coroutine as co; + +co::create(function() { + + $db = new co\MySQL(); + $server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', + ); + + echo "connect\n"; + $ret1 = $db->connect($server); + var_dump($ret1); + + echo "prepare [1]\n"; + $stmt1 = $db->prepare('SELECT * FROM userinfo WHERE id=?'); + var_dump($stmt1); + if ($stmt1 == false) + { + var_dump($db->errno, $db->error); + } + + echo "execute\n"; + $ret3 = $stmt1->execute(array(10)); + var_dump(count($ret3)); + + echo "prepare [2]\n"; + $stmt2 = $db->prepare('SELECT * FROM userinfo WHERE id > ? and level > ?'); + var_dump($stmt2); + if ($stmt2 == false) + { + var_dump($db->errno, $db->error); + } + + echo "execute\n"; + $ret4 = $stmt2->execute(array(10, 99)); + var_dump($ret4); +}); + diff --git a/vendor/swoole/examples/coroutine/mysql_prepare_2.php b/vendor/swoole/examples/coroutine/mysql_prepare_2.php new file mode 100755 index 0000000..db5e5b3 --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_prepare_2.php @@ -0,0 +1,25 @@ +<?php + + +go(function() { + + $db = new Co\MySQL(); + $server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', + ); + + echo "connect\n"; + $ret1 = $db->connect($server); + var_dump($ret1); + + echo "prepare [1]\n"; + $stmt1 = $db->prepare('show tables'); + echo "execute\n"; + $ret1 = $stmt1->execute([]); + var_dump($ret1); + +}); + diff --git a/vendor/swoole/examples/coroutine/mysql_procedure_exec.php b/vendor/swoole/examples/coroutine/mysql_procedure_exec.php new file mode 100755 index 0000000..d95c549 --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_procedure_exec.php @@ -0,0 +1,28 @@ +<?php + +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test' + ]; + + $clear = <<<SQL + DROP PROCEDURE IF EXISTS `say` +SQL; + $procedure = <<<SQL + CREATE DEFINER=`root`@`localhost` PROCEDURE `say`(content varchar(255)) + BEGIN + SELECT concat('you said: \"', content, '\"'); + END +SQL; + + $db->connect($server); + if ($db->query($clear) && $db->query($procedure)) { + $stmt = $db->prepare('CALL say(?)'); + $ret = $stmt->execute(['hello mysql!']); + var_dump(current($ret[0])); // you said: "hello mysql!" + } +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/mysql_query.php b/vendor/swoole/examples/coroutine/mysql_query.php new file mode 100755 index 0000000..4ec33c6 --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_query.php @@ -0,0 +1,26 @@ +<?php +use Swoole\Coroutine as co; +co::set(['trace_flags' => 1]); + +co::create(function() { + + + $function = new ReflectionFunction('title'); + + $function->invoke(); + echo "invoke444\n"; + +}); + +function title() { + echo "333invoke_________________________________\n"; + $tcpclient = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + var_dump($tcpclient->connect('127.0.0.1', 9501, 1)); + +} + +echo "111\n"; + + +echo "222\n"; +co::go(); diff --git a/vendor/swoole/examples/coroutine/mysql_unixsocket.php b/vendor/swoole/examples/coroutine/mysql_unixsocket.php new file mode 100755 index 0000000..2609d21 --- /dev/null +++ b/vendor/swoole/examples/coroutine/mysql_unixsocket.php @@ -0,0 +1,15 @@ +<?php + +go(function(){ + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => 'unix:/tmp/mysql.sock', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test' + ]; + $db->connect($server); + $stmt = $db->prepare('SELECT * FROM `user` WHERE id=?'); + $ret = $stmt->execute([1]); + var_dump($ret); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/reconnect_test.php b/vendor/swoole/examples/coroutine/reconnect_test.php new file mode 100755 index 0000000..6f03464 --- /dev/null +++ b/vendor/swoole/examples/coroutine/reconnect_test.php @@ -0,0 +1,71 @@ +<?php +/* new multi implement test */ +$server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE); + +$server->set([ + 'worker_num' => 1, +]); + +$server->on('Request', function ($request, $response) { + + /* + $mysql = new Swoole\Coroutine\MySQL(); + $res = $mysql->connect(['host' => '192.168.244.128', 'user' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt']); + if ($res == false) { + $response->end("MySQL connect fail!"); + return; + } + $res = $mysql->connect(['host' => '192.168.244.128', 'user' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt']); + if ($res == false) { + $response->end("MySQL connect fail!"); + return; + } + $mysql->close(); + + $res = $mysql->connect(['host' => '192.168.244.128', 'user' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt']); + if ($res == false) { + $response->end("MySQL connect fail!"); + return; + } + $res = $mysql->query('select sleep(1)', 2); + var_dump($res); + + $res = $mysql->connect(['host' => '192.168.244.128', 'user' => 'mha_manager', 'password' => 'mhapass', 'database' => 'tt']); + if ($res == false) { + $response->end("MySQL connect fail!"); + return; + } + $res = $mysql->query('select sleep(1)', 2); + var_dump($res); + */ + + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $redis->close(); + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $res = $redis->get('key'); + var_dump($res); + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("Redis connect fail!"); + return; + } + $res = $redis->get('key'); + var_dump($res); + + $response->end('Test End'); +}); +$server->start(); diff --git a/vendor/swoole/examples/coroutine/redis/auth.php b/vendor/swoole/examples/coroutine/redis/auth.php new file mode 100755 index 0000000..5ad619d --- /dev/null +++ b/vendor/swoole/examples/coroutine/redis/auth.php @@ -0,0 +1,8 @@ +<?php +go(function () { + $redis = new Swoole\Coroutine\Redis; + $redis->connect('127.0.0.1', 6379); + $redis->auth('root'); + $redis->set('key', 'swoole redis work'); + var_dump($redis->get('key')); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/redis/eval.php b/vendor/swoole/examples/coroutine/redis/eval.php new file mode 100755 index 0000000..7e0b787 --- /dev/null +++ b/vendor/swoole/examples/coroutine/redis/eval.php @@ -0,0 +1,7 @@ +<?php +go(function (){ + $redis = new Co\Redis; + $redis->connect('127.0.0.1', 6379); + $res = $redis->eval("return redis.call('get', 'key')"); + var_dump($res); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/redis/request.php b/vendor/swoole/examples/coroutine/redis/request.php new file mode 100755 index 0000000..7ba6885 --- /dev/null +++ b/vendor/swoole/examples/coroutine/redis/request.php @@ -0,0 +1,7 @@ +<?php +go(function () { + $redis = new Co\Redis; + $redis->connect('127.0.0.1', 6379); + $res = $redis->request(['object', 'encoding', 'key1']); + var_dump($res); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/redis_pool.php b/vendor/swoole/examples/coroutine/redis_pool.php new file mode 100755 index 0000000..726d1b2 --- /dev/null +++ b/vendor/swoole/examples/coroutine/redis_pool.php @@ -0,0 +1,23 @@ +<?php +$count = 0; +$pool = new SplQueue(); +$server = new Swoole\Http\Server('127.0.0.1', 9501, SWOOLE_BASE); + +$server->on('Request', function($request, $response) use(&$count, $pool) { + if (count($pool) == 0) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + if ($res == false) { + $response->end("redis connect fail!"); + return; + } + $pool->push($redis); + } + $redis = $pool->pop(); + $count ++; + $ret = $redis->set('key', 'value'); + $response->end("swoole response is ok, count = $count, result=" . var_export($ret, true)); + $pool->push($redis); +}); + +$server->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/redis_subscribe.php b/vendor/swoole/examples/coroutine/redis_subscribe.php new file mode 100755 index 0000000..30f4489 --- /dev/null +++ b/vendor/swoole/examples/coroutine/redis_subscribe.php @@ -0,0 +1,15 @@ +<?php + +use Swoole\Coroutine as co; + +co::create(function () { + $redis = new co\Redis(); + $redis->connect('127.0.0.1', 6379); + while (true) + { + $val = $redis->subscribe(['test']); + //订阅的channel,以第一次调用subscribe时的channel为准,后续的subscribe调用是为了收取Redis Server的回包 + //如果需要改变订阅的channel,请close掉连接,再调用subscribe + var_dump($val); + } +}); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/1.php b/vendor/swoole/examples/coroutine/select/1.php new file mode 100755 index 0000000..940982f --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/1.php @@ -0,0 +1,33 @@ +<?php +$c1 = new chan(); +//consumer first with select mode +$num = 10; +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/2.php b/vendor/swoole/examples/coroutine/select/2.php new file mode 100755 index 0000000..f9ec6fb --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/2.php @@ -0,0 +1,23 @@ +<?php +$c1 = new chan(); +//consumer first without select mode +$num = 10; +go(function () use ($c1, $num) { + echo "pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/3.php b/vendor/swoole/examples/coroutine/select/3.php new file mode 100755 index 0000000..b5faef8 --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/3.php @@ -0,0 +1,32 @@ +<?php +$c1 = new chan(1); +//product first with select mode +$num = 10; +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); +echo "main end\n"; diff --git a/vendor/swoole/examples/coroutine/select/4.php b/vendor/swoole/examples/coroutine/select/4.php new file mode 100755 index 0000000..38f6aea --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/4.php @@ -0,0 +1,23 @@ +<?php +$c1 = new chan(2); +//product first without select mode +$num = 10; +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1, $num) { + echo "pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); +echo "main end\n"; + \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/5.php b/vendor/swoole/examples/coroutine/select/5.php new file mode 100755 index 0000000..cbadf42 --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/5.php @@ -0,0 +1,37 @@ +<?php +$c1 = new chan(); +$c2 = new chan(); +function fibonacci($c1, $c2) +{ + go(function () use ($c1, $c2) { + $a = 0; + $b = 1; + while(1) { + $read_list = [$c2]; + $write_list = [$c1]; + $result = chan::select($read_list, $write_list, 2); + if ($write_list) { + $t = $a + $b; + $a = $b; + $b = $t; + $write_list[0]->push($a); + } + if ($read_list) { + $ret = $read_list[0]->pop(); + if ($ret === 1) { + echo "quit\n"; + return 1; + } + } + } + }); +} +$num = 10; +go(function () use ($c1, $c2, $num) { + for ($i = 0; $i < $num; $i ++) { + $ret = $c1->pop(); + echo "fibonacci @$i $ret\n"; + } + $c2->push(1); +}); +fibonacci($c1, $c2); diff --git a/vendor/swoole/examples/coroutine/select/6.php b/vendor/swoole/examples/coroutine/select/6.php new file mode 100755 index 0000000..3bd6c28 --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/6.php @@ -0,0 +1,38 @@ +<?php +$c1 = new chan(); + +$num = 10; +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/7.php b/vendor/swoole/examples/coroutine/select/7.php new file mode 100755 index 0000000..bf4d6f7 --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/7.php @@ -0,0 +1,54 @@ +<?php +//chan1 block and chan buffer +$c1 = new chan(); +$c2 = new chan(10); +$num = 10; +go(function () use ($c2,$num) { + for ($i=0;$i<$num;$i++) + { + $ret = $c2->push("chan2-$i"); + echo "chan 2 push [#$i] ret:".var_export($ret,1)."\n"; + } +}); +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "chan1 pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "chan1 push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("chan1-$i"); + echo "chan1 push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); + +go(function () use ($c2,$num) { + echo "chan2 pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c2->pop(); + echo "chan2 pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); +echo "main end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/select/8.php b/vendor/swoole/examples/coroutine/select/8.php new file mode 100755 index 0000000..05dda87 --- /dev/null +++ b/vendor/swoole/examples/coroutine/select/8.php @@ -0,0 +1,48 @@ +<?php +//chan1 block and chan buffer +$c1 = new chan(); +$c2 = new chan(10); +$num = 10; +go(function () use ($c2,$num) { + for ($i=0;$i<$num;$i++) + { + $ret = $c2->push("chan2-$i"); + echo "chan 2 push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$c2,$num) { + $ori_list = $read_list = [$c1,$c2]; + $write_list = null; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + + if ($ori_list) + { + foreach ($ori_list as $chan => $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + $chan_id = $chan + 1; + echo "chan{$chan_id} pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "chan1 push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("chan1-$i"); + echo "chan1 push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/send_yield.php b/vendor/swoole/examples/coroutine/send_yield.php new file mode 100755 index 0000000..2b794ba --- /dev/null +++ b/vendor/swoole/examples/coroutine/send_yield.php @@ -0,0 +1,28 @@ +<?php +$serv = new Swoole\Server("0.0.0.0", 9501, SWOOLE_BASE); +$serv->set(array( + 'worker_num' => 1, + 'send_yield' => true, + 'socket_buffer_size' => 512 * 1024, + 'kernel_socket_buffer_size' => 65536, +)); +$serv->on('connect', function ($serv, $fd) { + echo "Client:Connect.\n"; +}); +$serv->on('receive', function ($serv, $fd, $from_id, $data) { + $length = 0; + $size = 1024 * 128; + while (true) + { + $ret = $serv->send($fd, str_repeat('A', $size)); + if ($ret == false) { + break; + } + $length += $size; + echo "send $length success\n"; + } +}); +$serv->on('close', function ($serv, $fd) { + echo "Client: Close.\n"; +}); +$serv->start(); diff --git a/vendor/swoole/examples/coroutine/send_yield_client.php b/vendor/swoole/examples/coroutine/send_yield_client.php new file mode 100755 index 0000000..006634a --- /dev/null +++ b/vendor/swoole/examples/coroutine/send_yield_client.php @@ -0,0 +1,26 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); +$client->set(array( + 'kernel_socket_buffer_size' => 65536, +)); + +if (!$client->connect('127.0.0.1', 9501, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +var_dump($client->getsockname()); + +$client->send("start\n"); +$length = 0; + +while(true) +{ + $data = $client->recv(65536); + if ($data == false) { + break; + } + $length += strlen($data); + echo "recv ".$length." bytes\n"; + usleep(100000); +} diff --git a/vendor/swoole/examples/coroutine/sleep.php b/vendor/swoole/examples/coroutine/sleep.php new file mode 100755 index 0000000..d6e3a7b --- /dev/null +++ b/vendor/swoole/examples/coroutine/sleep.php @@ -0,0 +1,13 @@ +<?php +$server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE); + +$server->set([ + 'worker_num' => 1, +]); + +$server->on('Request', function ($request, $response) { + Swoole\Coroutine::sleep(0.2); + $response->end('Test End'); +}); + +$server->start(); diff --git a/vendor/swoole/examples/coroutine/socket/accept.php b/vendor/swoole/examples/coroutine/socket/accept.php new file mode 100755 index 0000000..2d9b268 --- /dev/null +++ b/vendor/swoole/examples/coroutine/socket/accept.php @@ -0,0 +1,17 @@ +<?php +go(function () { + $sock = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + $ret = $sock->bind('127.0.0.1', 9601); + var_dump($ret); + assert($sock->listen(512)); + $conn = $sock->accept(); + + $data = $conn->recv(); + var_dump($data); + $json = json_decode($data, true); + var_dump($json); + $ret = $conn->send("world\n"); + echo "send res {$ret} \n"; + $conn->close(); +}); + diff --git a/vendor/swoole/examples/coroutine/socket/sendto.php b/vendor/swoole/examples/coroutine/socket/sendto.php new file mode 100755 index 0000000..04dc35d --- /dev/null +++ b/vendor/swoole/examples/coroutine/socket/sendto.php @@ -0,0 +1,12 @@ +<?php + +echo "start \n"; +go(function () { + $conn = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + $ret = $conn->connect('127.0.0.1', 9601); + echo "connect ret:".var_export($ret,1)." error:".var_export($conn->errCode,1)."\n"; + $ret = $conn->send(json_encode(['data' => 'hello'])); + echo "send ret:".var_export($ret,1)."\n"; + echo $conn->recv(); +}); +echo "end \n"; diff --git a/vendor/swoole/examples/coroutine/stack.php b/vendor/swoole/examples/coroutine/stack.php new file mode 100755 index 0000000..e2f255c --- /dev/null +++ b/vendor/swoole/examples/coroutine/stack.php @@ -0,0 +1,20 @@ +<?php +co::set(['stack_size' => 8192*4]); + +function test($n) +{ + $a = 1; + $b = 2; + $c = 3; + $d = 4; + static $i; + + usleep(100000); + echo "index=".($i++)."\n"; + + return test($n + $a + $b + $c + $d); +} + +go(function () { + test(9); +}); diff --git a/vendor/swoole/examples/coroutine/task_co.php b/vendor/swoole/examples/coroutine/task_co.php new file mode 100755 index 0000000..ad5a4e2 --- /dev/null +++ b/vendor/swoole/examples/coroutine/task_co.php @@ -0,0 +1,27 @@ +<?php +$server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE); + +$server->set([ + 'worker_num' => 1, + 'task_worker_num' => 2, +]); + +$server->on('Task', function (swoole_server $serv, $task_id, $worker_id, $data) { + echo "#{$serv->worker_id}\tonTask: worker_id={$worker_id}, task_id=$task_id\n"; + if ($serv->worker_id == 1) { + sleep(1); + } + return $data; +}); + +$server->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$server->on('Request', function ($request, $response) use ($server) +{ + $result = $server->taskCo(["hello world", ['data' => 1234, 'code' => 200]], 0.5); + $response->end('Test End, Result: '.var_export($result, true)); +}); + +$server->start(); diff --git a/vendor/swoole/examples/coroutine/tcp_backend_serv.php b/vendor/swoole/examples/coroutine/tcp_backend_serv.php new file mode 100755 index 0000000..9914047 --- /dev/null +++ b/vendor/swoole/examples/coroutine/tcp_backend_serv.php @@ -0,0 +1,18 @@ +<?php +$serv = new Swoole\Server("0.0.0.0", 9511); +$serv->set(array( + 'worker_num' => 1, //工作进程数量 + 'daemonize' => true, //是否作为守护进程 +)); +$serv->on('connect', function ($serv, $fd){ + echo "Client:Connect.\n"; +}); +$serv->on('receive', function ($serv, $fd, $from_id, $data) { + $serv->send($fd, 'Swoole: '.$data); + $serv->close($fd); +}); +$serv->on('close', function ($serv, $fd) { + echo "Client: Close.\n"; +}); +$serv->start(); + diff --git a/vendor/swoole/examples/coroutine/tcp_echo.php b/vendor/swoole/examples/coroutine/tcp_echo.php new file mode 100755 index 0000000..1709053 --- /dev/null +++ b/vendor/swoole/examples/coroutine/tcp_echo.php @@ -0,0 +1,23 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +$serv->on('connect', function ($serv, $fd, $reactor_id){ + echo "[#".posix_getpid()."]\tClient@[$fd]: Connect.\n"; +}); +$serv->set(array( + 'worker_num' => 1, + +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $reactor_id, $data) { + echo "[#".$serv->worker_id."]\tClient[$fd] receive data: $data\n"; + if ($serv->send($fd, "hello {$data}\n") == false) + { + echo "error\n"; + } +}); + +$serv->on('close', function ($serv, $fd, $reactor_id) { + echo "[#".posix_getpid()."]\tClient@[$fd]: Close.\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/coroutine/timer_test.php b/vendor/swoole/examples/coroutine/timer_test.php new file mode 100755 index 0000000..472c440 --- /dev/null +++ b/vendor/swoole/examples/coroutine/timer_test.php @@ -0,0 +1,16 @@ +<? +/** + * @Author: winterswang + * @Date: 2016-06-26 16:34:02 + * @Last Modified by: winterswang + * @Last Modified time: 2016-06-26 16:41:46 + */ + +swoole_timer_after(1000, function(){ + echo " timer after timeout\n"; +}); + +swoole_timer_tick(1000, function(){ + echo "timer tick timeout\n"; +}); +?> diff --git a/vendor/swoole/examples/coroutine/udp_client.php b/vendor/swoole/examples/coroutine/udp_client.php new file mode 100755 index 0000000..87dc798 --- /dev/null +++ b/vendor/swoole/examples/coroutine/udp_client.php @@ -0,0 +1,74 @@ +<?php +class Client +{ + private $ip = "127.0.0.1"; + const PORT = 8888; + private $data; + + public function sendRequest() + { + $this->data = "swoole test"; + $this->send(); + $this->moreThanOneRecv(); + return $ret; + } + + public function send() + { + $cli = new swoole_client_coro(SWOOLE_SOCK_UDP); + $ret = $cli->connect($this->ip, self::PORT); + $cli->send($this->data); + $ret = $cli->recv(); + $cli->close(); + } + + public function moreThanOneRecv() + { + $cli = new swoole_client_coro(SWOOLE_SOCK_UDP); + $ret = $cli->connect($this->ip, self::PORT); + $cli->send("sent by cli"); + + $cli2 = new swoole_client_coro(SWOOLE_SOCK_UDP); + $ret = $cli2->connect($this->ip, self::PORT); + $cli2->send("sent by cli2"); + + $cli3 = new swoole_client_coro(SWOOLE_SOCK_UDP); + $ret = $cli3->connect($this->ip, self::PORT); + $cli3->send("sent by cli3"); + + sleep(1); + $ret = $cli3->recv(); + $ret = $cli2->recv(); + $ret = $cli->recv(); + return; + } +} + +class Server +{ + public $server; + + public function run() + { + $this->server = new swoole_http_server("127.0.0.1", 9502); + $this->server->set([ + 'worker_num' => 1, + 'daemonize' => true, + 'log_file' => '/tmp/swoole.log', + ]); + $this->server->on('Request',['Server', 'onRequest']); + $this->server->start(); + } + + public static function onRequest($request, $response) + { + self::staticFunc(); + $cli = new swoole_client_coro(SWOOLE_SOCK_UDP); + $client = new Client(); + $ret = $client->sendRequest(); + $response->end($ret); + } +} + +$server = new Server(); +$server->run(); diff --git a/vendor/swoole/examples/coroutine/udp_tcp_timeout.php b/vendor/swoole/examples/coroutine/udp_tcp_timeout.php new file mode 100755 index 0000000..fa77263 --- /dev/null +++ b/vendor/swoole/examples/coroutine/udp_tcp_timeout.php @@ -0,0 +1,126 @@ +<?php +/** + * @Author: winterswang + * @Date: 2015-06-18 16:45:09 + * @Last Modified by: winterswang + * @Last Modified time: 2016-09-18 17:36:18 + */ + +class TestHttpServer { + + public $http; + public $queue; + public $setting = array(); + + /** + * [__construct description] + * @param array $setting [description] + */ + public function __construct(){ + + } + + public function set($setting){ + + $this ->setting = $setting; + } + + /** + * [init description] + * @return [type] [description] + */ + public function init(){ + + if (!isset($this ->setting['host'])) { + $this ->setting['host'] = '0.0.0.0'; + } + if (!isset($this ->setting['port'])) { + $this ->setting['port'] = '9999'; + } + + $this ->http = new Swoole\Http\Server($this ->setting['host'], $this ->setting['port']); + $this ->http ->set($this ->setting); + + $this ->http ->on('request', array($this, 'onRequest')); + $this ->http ->on('close', array($this, 'onClose')); + } + + /** + * [onRequest description] + * @param [type] $request [description] + * @param [type] $response [description] + * @return [type] [description] + */ + public function onRequest($request, $response){ + + + //$udp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + + // $ret = $udp_cli ->connect('10.100.65.222', 9906); + // $ret = $udp_cli ->send('test for the coro'); + // $ret = $udp_cli ->recv(100); + // $udp_cli->close(); + + // if ($ret) { + // //error_log(" udp cli get rsp == " . print_r($ret, true),3, '/data/log/udp_timeout.log'); + // } + // else{ + // error_log(" udp cli timeout \n",3, '/data/log/udp_timeout.log'); + // } + + $ret = $tcp_cli ->connect("10.100.64.151", 9805); + $ret = $tcp_cli ->send('test for the coro'); + $ret = $tcp_cli ->recv(100); + $tcp_cli->close(); + + if ($ret) { + //error_log(" tcp cli get rsp == " . print_r($ret, true) . PHP_EOL, 3, '/data/log/udp_timeout.log'); + } + else{ + error_log(" tcp cli timeout \n",3, '/data/log/udp_timeout.log'); + } + + $response ->end(" swoole response is ok"); + } + + /** + * [onClose description] + * @param [type] $server [description] + * @param [type] $fd [description] + * @param [type] $from_id [description] + * @return [type] [description] + */ + public function onClose($server, $fd, $from_id){ + + //echo " on close fd = $fd from_id = $from_id \n"; + } + + /** + * [start description] + * @return [type] [description] + */ + public function start(){ + + $this ->init(); + $this ->http ->start(); + } +} + +$setting = array( + 'host' => '0.0.0.0', + 'port' => 10006, + 'worker_num' => 4, + 'dispatch_mode' => 3, //固定分配请求到worker + 'reactor_num' => 4, //亲核 + 'daemonize' => 1, //守护进程 + 'backlog' => 128, + 'log_file' => '/data/log/test_http_server.log', +); +$th = new TestHttpServer(); +$th ->set($setting); +$th ->start(); + + + + diff --git a/vendor/swoole/examples/coroutine/user_coroutine.php b/vendor/swoole/examples/coroutine/user_coroutine.php new file mode 100755 index 0000000..aadd9ad --- /dev/null +++ b/vendor/swoole/examples/coroutine/user_coroutine.php @@ -0,0 +1,17 @@ +<?php +for($i = 0; $i < 100; $i++) { + Swoole\Coroutine::create(function() use ($i) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + $ret = $redis->incr('coroutine'); + $redis->close(); + if ($i == 50) { + Swoole\Coroutine::create(function() use ($i) { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect('127.0.0.1', 6379); + $ret = $redis->set('coroutine_i', 50); + $redis->close(); + }); + } + }); +} diff --git a/vendor/swoole/examples/coroutine/websocket.php b/vendor/swoole/examples/coroutine/websocket.php new file mode 100755 index 0000000..3112dd8 --- /dev/null +++ b/vendor/swoole/examples/coroutine/websocket.php @@ -0,0 +1,24 @@ +<?php +$ws = new swoole_websocket_server("127.0.0.1", 9501, SWOOLE_BASE); +$ws->set(array( + 'log_file' => '/dev/null' +)); +$ws->on("WorkerStart", function (\swoole_server $serv) { + +}); + +$ws->on('open', function ($serv, swoole_http_request $request) { + //$ip = co::gethostbyname('www.baidu.com'); + if (1) { + $serv->push($request->fd, "start\n"); + } +}); + +$ws->on('message', function ($serv, $frame) { + var_dump($frame); + co::sleep(0.1); + $data = $frame->data; + $serv->push($frame->fd, "hello client {$data}\n"); +}); + +$ws->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/coroutine/websocket_client.php b/vendor/swoole/examples/coroutine/websocket_client.php new file mode 100755 index 0000000..f63ec04 --- /dev/null +++ b/vendor/swoole/examples/coroutine/websocket_client.php @@ -0,0 +1,32 @@ +<?php +// go(function () { +// $cli = new Co\http\Client("127.0.0.1", 9501); +// $ret = $cli->upgrade("/"); + +// if ($ret) { +// while(true) { +// $cli->push("hello"); +// var_dump($cli->recv()); +// co::sleep(0.1); +// } +// } + +// }); +go(function () { + $cli = new Co\http\Client("127.0.0.1", 9501); + $cli->set([ + 'timeout' => 1 + ]); + $ret = $cli->upgrade("/"); + + if (!$ret) { + echo "ERROR\n"; + return; + } + var_dump($cli->recv()); + for ($i = 0; $i < 5; $i ++) { + $cli->push("hello @$i"); + var_dump($cli->recv()); + co::sleep(0.1); + } +}); diff --git a/vendor/swoole/examples/db_pool.php b/vendor/swoole/examples/db_pool.php new file mode 100755 index 0000000..a880235 --- /dev/null +++ b/vendor/swoole/examples/db_pool.php @@ -0,0 +1,58 @@ +<?php +$serv = new swoole_http_server("127.0.0.1", 9500); + +$serv->set(array( + 'worker_num' => 100, + 'task_worker_num' => 20, //database connection pool + 'db_uri' => 'mysql:host=127.0.0.1;dbname=test', + 'db_user' => 'root', + 'db_passwd' => 'root', +)); + +function my_onRequest_sync($req, $resp) +{ + global $serv; + $result = $serv->taskwait("show tables"); + if ($result !== false) + { + $resp->end(var_export($result['data'], true)); + return; + } + else + { + $resp->status(500); + $resp->end("Server Error, Timeout\n"); + } +} + +function my_onTask($serv, $task_id, $from_id, $sql) +{ + static $link = null; + if ($link == null) + { + $link = new PDO($serv->setting['db_uri'], $serv->setting['db_user'], $serv->setting['db_passwd']);; + if (!$link) + { + $link = null; + return array("data" => '', 'error' => "connect database failed."); + } + } + $result = $link->query($sql); + if (!$result) + { + return array("data" => '', 'error' => "query error"); + } + $data = $result->fetchAll(); + return array("data" => $data); +} + +function my_onFinish($serv, $data) +{ + echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL; +} + +$serv->on('Request', 'my_onRequest_sync'); +$serv->on('Task', 'my_onTask'); +$serv->on('Finish', 'my_onFinish'); + +$serv->start(); diff --git a/vendor/swoole/examples/eof/async_client.php b/vendor/swoole/examples/eof/async_client.php new file mode 100755 index 0000000..0aedc44 --- /dev/null +++ b/vendor/swoole/examples/eof/async_client.php @@ -0,0 +1,36 @@ +<?php +function send(swoole_client $cli) +{ + $_send = str_repeat('A', rand(10000, 50000)) . "\r\n\r\n"; + $cli->send($_send); + echo "send ".strlen($_send)." bytes\n"; +} + +$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); //异步非阻塞 +$client->set(array('open_eof_check' => true, 'package_eof' => "\r\n\r\n")); + +$client->on("connect", function(swoole_client $cli) { + send($cli); +}); + +$client->on("receive", function (swoole_client $cli, $data) { + static $i = 0; + if ($i % 100 == 1) + { + echo "received " . strlen($data) . " bytes\n"; + } + $i ++; + //usleep(200000); + //send($cli); +}); + +$client->on("error", function(swoole_client $cli){ + echo "error\n"; +}); + +$client->on("close", function(swoole_client $cli){ + echo "Connection close\n"; +}); + +$client->connect('127.0.0.1', 9501); + diff --git a/vendor/swoole/examples/eof/client.php b/vendor/swoole/examples/eof/client.php new file mode 100755 index 0000000..cad6740 --- /dev/null +++ b/vendor/swoole/examples/eof/client.php @@ -0,0 +1,75 @@ +<?php +/** + * 分段发送数据 + * + * @param swoole_client $client + * @param string $data + * @param int $chunk_size + */ +function send_chunk(swoole_client $client, $data, $chunk_size = 1024) +{ + $len = strlen($data); + $chunk_num = intval($len / $chunk_size) + 1; + for ($i = 0; $i < $chunk_num; $i++) + { + if ($len < ($i + 1) * $chunk_size) + { + $sendn = $len - ($i * $chunk_size); + } + else + { + $sendn = $chunk_size; + } + $client->send(substr($data, $i * $chunk_size, $sendn)); + } +} + +$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 +if(!$client->connect('127.0.0.1', 9501, 0.5, 0)) +{ + echo "Over flow. errno=".$client->errCode; + die("\n"); +} + +//for ($i = 0; $i < 10; $i++) +//{ +// $client->send("hello world\r\n\r\n"); +// echo "send\n"; +//} +//exit; + +$data = array( + 'name' => __FILE__, + 'content' => str_repeat('A', 8192 * rand(1, 3)), //800K +); + +$_serialize_data = serialize($data); + +$_send = $_serialize_data."__doit__"; + +echo "serialize_data length=".strlen($_serialize_data)."send length=".strlen($_send)."\n"; +//send_chunk($client, $_send); + +// +if(!$client->send($_send)) +{ + die("send failed.\n"); +} + +//$client->send("\r\n".substr($_serialize_data, 0, 8000)); + +echo $client->recv(); +exit; + +$client->send(substr($_serialize_data, 8000)); + +//usleep(500000); + +if (!$client->send("\r\n\r\n")) +{ + die("send failed.\n"); +} + +echo $client->recv(); + +//sleep(1); diff --git a/vendor/swoole/examples/eof/server.php b/vendor/swoole/examples/eof/server.php new file mode 100755 index 0000000..30e4f28 --- /dev/null +++ b/vendor/swoole/examples/eof/server.php @@ -0,0 +1,31 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); +$serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, +// 'worker_num' => 4, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M +)); +//$serv->on('connect', function ($serv, $fd) { +// //echo "[#" . posix_getpid() . "]\tClient:Connect.\n"; +//}); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + echo '#' . $serv->worker_id . " recv: " . strlen($data) . "\n"; + for ($i = 0; $i < 1000; $i++) + { + $resp = str_repeat('A', rand(10000, 50000)) . "\r\n\r\n"; + $serv->send($fd, $resp); + if ($i % 100 == 1) + { + sleep(1); + echo "send ".strlen($resp)." bytes\n"; + } + } +}); +//$serv->on('close', function ($serv, $fd) { + //echo "[#" . posix_getpid() . "]\tClient: Close.\n"; +//}); +$serv->start(); diff --git a/vendor/swoole/examples/event/cycle.php b/vendor/swoole/examples/event/cycle.php new file mode 100755 index 0000000..4282a6f --- /dev/null +++ b/vendor/swoole/examples/event/cycle.php @@ -0,0 +1,13 @@ +<?php + +Swoole\Timer::tick(2000, function ($id) { + var_dump($id); +}); + +Swoole\Event::cycle(function () { + echo "hello [1]\n"; + Swoole\Event::cycle(function () { + echo "hello [2]\n"; + Swoole\Event::cycle(null); + }); +}); diff --git a/vendor/swoole/examples/event/inotify.php b/vendor/swoole/examples/event/inotify.php new file mode 100755 index 0000000..683b101 --- /dev/null +++ b/vendor/swoole/examples/event/inotify.php @@ -0,0 +1,15 @@ +<?php +//创建一个inotify句柄 +$fd = inotify_init(); + +//监听文件,仅监听修改操作,如果想要监听所有事件可以使用IN_ALL_EVENTS +$watch_descriptor = inotify_add_watch($fd, __DIR__.'/inotify.data', IN_MODIFY); + +swoole_event_add($fd, function ($fd) { + $events = inotify_read($fd); + if ($events) { + foreach ($events as $event) { + echo "inotify Event :" . var_export($event, 1) . "\n"; + } + } +}); diff --git a/vendor/swoole/examples/event/sockets.php b/vendor/swoole/examples/event/sockets.php new file mode 100755 index 0000000..7e60161 --- /dev/null +++ b/vendor/swoole/examples/event/sockets.php @@ -0,0 +1,53 @@ +<?php +/** + * require ./configure --enable-sockets + */ + +$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Unable to create socket\n"); + +socket_set_nonblock($socket) or die("Unable to set nonblock on socket\n"); + +function socket_onRead($socket) +{ + static $i = 0; + + echo socket_read($socket, 8192)."\n"; + $i ++; + if ($i > 10) + { + echo "finish\n"; + swoole_event_del($socket); + socket_close($socket); + } + else + { + sleep(1); + swoole_event_set($socket, null, 'socket_onWrite', SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE); + } +} + +function socket_onWrite($socket) +{ + socket_write($socket, "hi swoole"); + swoole_event_set($socket, null, null, SWOOLE_EVENT_READ); +} + +function socket_onConnect($socket) +{ + $err = socket_get_option($socket, SOL_SOCKET, SO_ERROR); + if ($err == 0) + { + echo "connect server success\n"; + swoole_event_set($socket, null, 'socket_onWrite', SWOOLE_EVENT_READ); + socket_write($socket, "first package\n"); + } + else + { + echo "connect server failed\n"; + swoole_event_del($socket); + socket_close($socket); + } +} + +swoole_event_add($socket, 'socket_onRead', 'socket_onConnect', SWOOLE_EVENT_WRITE); +@socket_connect($socket, '127.0.0.1', 9501); diff --git a/vendor/swoole/examples/event/stdin.php b/vendor/swoole/examples/event/stdin.php new file mode 100755 index 0000000..6ecd4d8 --- /dev/null +++ b/vendor/swoole/examples/event/stdin.php @@ -0,0 +1,4 @@ +<?php +swoole_event_add(STDIN, function($fp) { + echo "STDIN: ".fread($fp, 8192); +}); diff --git a/vendor/swoole/examples/event/stream.php b/vendor/swoole/examples/event/stream.php new file mode 100755 index 0000000..6a8c736 --- /dev/null +++ b/vendor/swoole/examples/event/stream.php @@ -0,0 +1,21 @@ +<?php +$fp = stream_socket_client("tcp://127.0.0.1:9502", $errno, $errstr, 30); +if (!$fp) { + exit("$errstr ($errno)<br />\n"); +} +fwrite($fp, "HELLO world"); + +function stream_onRead($fp) +{ + echo fread($fp, 1024)."\n"; + sleep(1); + swoole_event_write($fp, "hello world"); + //swoole_event_set($fp, null, null, SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE); + //swoole_event_del($fp); + //fclose($fp); +} + + +swoole_event_add($fp, 'stream_onRead'); + +echo "start\n"; diff --git a/vendor/swoole/examples/event/test.php b/vendor/swoole/examples/event/test.php new file mode 100755 index 0000000..a26899a --- /dev/null +++ b/vendor/swoole/examples/event/test.php @@ -0,0 +1,10 @@ +<?php +$fp = stream_socket_client("tcp://127.0.0.1:9501", $errno, $errstr, 30); +fwrite($fp, "HELLO world"); + +swoole_event_add($fp, function ($fp) { + echo fread($fp, 1024)."\n"; + swoole_event_del($fp); + fclose($fp); +}); + diff --git a/vendor/swoole/examples/get_local_ip.php b/vendor/swoole/examples/get_local_ip.php new file mode 100755 index 0000000..35b2c78 --- /dev/null +++ b/vendor/swoole/examples/get_local_ip.php @@ -0,0 +1,2 @@ +<?php +var_dump(swoole_get_local_ip()); diff --git a/vendor/swoole/examples/hot_update_class.php b/vendor/swoole/examples/hot_update_class.php new file mode 100755 index 0000000..94440a4 --- /dev/null +++ b/vendor/swoole/examples/hot_update_class.php @@ -0,0 +1,7 @@ +<?php + class HotUpdate { + public function getData() + { + return "hello world~~".PHP_EOL; + } + } \ No newline at end of file diff --git a/vendor/swoole/examples/http/async_client.php b/vendor/swoole/examples/http/async_client.php new file mode 100755 index 0000000..b7997a2 --- /dev/null +++ b/vendor/swoole/examples/http/async_client.php @@ -0,0 +1,25 @@ +<?php +$cli = new swoole_http_client('127.0.0.1', 9501); +//post request +//$cli->setData(http_build_query(['a'=>123,'b'=>"哈哈"])); +//$cli->set(['timeout' => -1]); +//$cli->setHeaders(['Host' => 'www.baidu.com']); +//$cli->set(['http_proxy_host' => '127.0.0.1', 'http_proxy_port' => 8888,]); + +$cli->setHeaders(['User-Agent' => "swoole"]); + +$cli->get('/index.php', function ($cli) +{ + var_dump($cli); +}); + +//$cli->post('/dump.php', array("test" => 'abc'), function ($cli) { +// echo $cli->body; +// $cli->get('/index.php', function ($cli) { +// file_put_contents(__DIR__.'/t.html', $cli->body); +// $cli->download('/index.php', __DIR__.'/phpinfo.html', function ($cli) +// { +// var_dump($cli->downloadFile); +// }); +// }); +//}); diff --git a/vendor/swoole/examples/http/async_websocket.php b/vendor/swoole/examples/http/async_websocket.php new file mode 100755 index 0000000..be19dff --- /dev/null +++ b/vendor/swoole/examples/http/async_websocket.php @@ -0,0 +1,11 @@ +<?php +$cli = new swoole_http_client('127.0.0.1', 9501); + +$cli->on('message', function ($_cli, $frame) { + var_dump($frame); +}); + +$cli->upgrade('/', function ($cli) { + echo $cli->body; + $cli->push("hello world"); +}); diff --git a/vendor/swoole/examples/http/client.php b/vendor/swoole/examples/http/client.php new file mode 100755 index 0000000..f8e8f58 --- /dev/null +++ b/vendor/swoole/examples/http/client.php @@ -0,0 +1,56 @@ +<?php +$cli = new swoole_client(SWOOLE_SOCK_TCP); +$cli->connect('127.0.0.1', 9501); + +//$type = 'GET'; +$type = 'POST'; + +$cookie = "8MLP_5753_saltkey=RSU8HYED; 8MLP_5753_lastvisit=1426120671; pgv_pvi=1454765056; CNZZDATA1000008050=684878078-1426123263-http%253A%252F%252Fcznews-team.chinaz.com%252F%7C1426485386; attentiondomain=2z.cn%2cchinaz.com%2ckuaishang.cn%2ccxpcms.com; CNZZDATA33217=cnzz_eid%3D1036784254-1426122273-http%253A%252F%252Fcznews-team.chinaz.com%252F%26ntime%3D1427414208; CNZZDATA433095=cnzz_eid%3D1613871160-1426123273-http%253A%252F%252Fcznews-team.chinaz.com%252F%26ntime%3D1427848205; CNZZDATA1254679775=309722566-1427851758-http%253A%252F%252Fcznews-team.chinaz.com%252F%7C1427851758; 8MLP_5753_security_cookiereport=c014Hgufskpv55xgM9UaB%2FZZdMrcN0QqBYdcGomTu8OlTDWzTA0z; 8MLP_5753_ulastactivity=e4a1aRIbgdzoRDd8NlT5CMIwLnWjyjr2hWyfn6T5g82RitUOdf3o; 8MLP_5753_auth=9351LJpv7Xa%2FPUylJDQgRiAONZ5HysOaj%2BqRGb6jYmpqZpRkVc2ibPXm7LAfArC%2FpIpY2Fx%2B59AHqzr843qozZWxWNZi; mytool_user=uSHVgCUFWf5Sv2Y8tKytQRUJW3wMVT3rw5xQLNGQFIsod4C6vYWeGA==; 8MLP_5753_lip=220.160.111.22%2C1428036585; pgv_si=s4245709824; PHPSESSID=t3hp9h4o8rb3956t5pajnsfab1; 8MLP_5753_st_p=1024432%7C1428040399%7Cf7599ba9053aa27e12e9e597a4c372ce; 8MLP_5753_viewid=tid_7701248; 8MLP_5753_smile=5D1; 8MLP_5753_st_t=1024432%7C1428040402%7C46d40e02d899b10b431822eb1d39f6a1; 8MLP_5753_forum_lastvisit=D_140_1427103032D_165_1427427405D_168_1427870172D_167_1427870173D_166_1428021390D_163_1428040402; 8MLP_5753_sid=k25gxK; 8MLP_5753_lastact=1428040403%09misc.php%09patch; cmstop_page-view-mode=view; cmstop_rememberusername=error; cmstop_auth=Jcn2qzVn9nsjqtodER9OphcW3PURDWNx6mO7j0Zbb9k%3D; cmstop_userid=6; cmstop_username=error; Hm_lvt_aecc9715b0f5d5f7f34fba48a3c511d6=1427967317,1428021376,1428036617,1428040224; Hm_lpvt_aecc9715b0f5d5f7f34fba48a3c511d6=1428050417; YjVmNm_timeout=0"; + +if ($type == 'GET') +{ + $header = "GET /home/explore/ HTTP/1.1\r\n"; + $header .= "Host: 127.0.0.1\r\n"; + $header .= "Connection: keep-alive\r\n"; + $header .= "Cache-Control: max-age=0\r\n"; + $header .= "Cookie: $cookie\r\n"; + $header .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"; + $header .= "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36\r\n"; + $header .= "\r\n"; + $_sendStr = $header; +} +else +{ +// $header = "POST /home/explore/?hello=123&world=swoole#hello HTTP/1.1\r\n"; + $header = "POST /post.php HTTP/1.1\r\n"; + $header .= "Host: 127.0.0.1\r\n"; + $header .= "Referer: http://group.swoole.com/\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2\r\n"; + $header .= "Cookie: pgv_pvi=9559734272; efr__Session=uddfvbm87dtdtrdsro1ohlt4o6; efr_r_uname=apolov%40vip.qq.com; efr__user_login=3N_b4tHW1uXGztWW2Ojf09vssOjR5abS4abO5uWRopnm0eXb7OfT1NbIoqjWzNCvodihq9qaptqfra6imtLXpNTNpduVoque26mniKej5dvM09WMopmmpM2xxcmhveHi3uTN0aegpaiQj8Snoa2IweHP5fCL77CmxqKqmZKp5ejN1c_Q2cPZ25uro6mWqK6BmMOzy8W8k4zi2d3Nlb_G0-PaoJizz97l3deXqKyPoKacr6ynlZ2nppK71t7C4uGarKunlZ-s; pgv_si=s8426935296; Hm_lvt_4967f2faa888a2e52742bebe7fcb5f7d=1410240641,1410241802,1410243730,1410243743; Hm_lpvt_4967f2faa888a2e52742bebe7fcb5f7d=1410248408\r\n"; + $header .= "RA-Ver: 2.5.3\r\n"; + $header .= "RA-Sid: 2A784AF7-20140212-113827-085a9c-c4de6e\r\n"; + + $_postData = ['body1' => 'swoole_http-server', 'message' => 'nihao']; + $_postBody = json_encode($_postData); +// $_postBody = http_build_query($_postData); + $header .= "Content-Length: " . strlen($_postBody); + echo "http header length=".strlen($header)."\n"; + $header .= "Content-Length: " . (strlen($_postBody) - 2); + +// $cli->send($header); +// usleep(100000); + $_sendStr = $header . "\r\n\r\n" . $_postBody; +// $_sendStr = "\r\n\r\n" . $_postBody; + echo "postBody length=".strlen($_postBody)."\n"; +} + +echo "-------------------------Request----------------------------\n"; +echo $_sendStr; +$cli->send($_sendStr); +echo "send ".strlen($_sendStr)." byte\n"; + +echo "-------------------------Response----------------------------\n"; +$data = $cli->recv(); +var_dump($data); +exit; diff --git a/vendor/swoole/examples/http/curl.php b/vendor/swoole/examples/http/curl.php new file mode 100755 index 0000000..a4f6fe7 --- /dev/null +++ b/vendor/swoole/examples/http/curl.php @@ -0,0 +1,28 @@ +<?php +// 创建一个新cURL资源 +$ch = curl_init(); +// 设置URL和相应的选项 +curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1:9501"); +curl_setopt($ch, CURLOPT_HEADER, 0); +curl_setopt($ch, CURLOPT_POST, 1);//设置为POST方式 +curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); + +$post_data = array('test' => str_repeat('a', 80)); + +if (function_exists("curl_file_create")) +{ + $cfile = curl_file_create(__DIR__ . '/../test.jpg'); + $post_data['file'] = $cfile; +} +else +{ + $post_data['file'] = '@' . __DIR__ . '/../test.jpg'; +} + +curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //POST数据 +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +// 抓取URL并把它传递给浏览器 +$res = curl_exec($ch); +var_dump($res); +// 关闭cURL资源,并且释放系统资源 +curl_close($ch); diff --git a/vendor/swoole/examples/http/detach.php b/vendor/swoole/examples/http/detach.php new file mode 100755 index 0000000..a12ff8c --- /dev/null +++ b/vendor/swoole/examples/http/detach.php @@ -0,0 +1,34 @@ +<?php +$http = new swoole_http_server("0.0.0.0", 9501); + +$http->set(['task_worker_num' => 1, 'worker_num' => 1]); + +$http->on('request', function ($req, Swoole\Http\Response $resp) use ($http) { + $resp->detach(); + $http->task(strval($resp->fd)); +}); + +$http->on('finish', function () +{ + echo "task finish"; +}); + +$http->on('task', function ($serv, $task_id, $worker_id, $data) +{ + var_dump($data); + $resp = Swoole\Http\Response::create($data); + $resp->end("in task"); + echo "async task\n"; +}); + +//$http->on('close', function(){ +// echo "on close\n"; +//}); + + +$http->on('workerStart', function ($serv, $id) +{ + //var_dump($serv); +}); + +$http->start(); diff --git a/vendor/swoole/examples/http/download.php b/vendor/swoole/examples/http/download.php new file mode 100755 index 0000000..8e6f3df --- /dev/null +++ b/vendor/swoole/examples/http/download.php @@ -0,0 +1,12 @@ +<?php +$fp = fopen (__DIR__. '/test.html', 'w+'); +$ch = curl_init("http://127.0.0.1/index.php"); +curl_setopt($ch, CURLOPT_TIMEOUT, 50); +curl_setopt($ch, CURLOPT_ENCODING, "gzip"); +// write curl response to file +curl_setopt($ch, CURLOPT_FILE, $fp); +curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); +// get curl response +curl_exec($ch); +curl_close($ch); +fclose($fp); diff --git a/vendor/swoole/examples/http/http_proxy.php b/vendor/swoole/examples/http/http_proxy.php new file mode 100755 index 0000000..4f3e765 --- /dev/null +++ b/vendor/swoole/examples/http/http_proxy.php @@ -0,0 +1,25 @@ +<?php +Swoole\Async::dnsLookup("www.htmleaf.com", function ($domainName, $ip) { +//Swoole\Async::dnsLookup("www.baidu.com", function ($domainName, $ip) { + $cli = new swoole_http_client($ip, 80); +//$cli = new swoole_http_client($ip, 443,true); + $cli->set(array( + 'http_proxy_host'=>"127.0.0.1", + 'http_proxy_port'=>3128, + + )); + $cli->setHeaders([ + 'Host' => $domainName, + "User-Agent" => 'Chrome/49.0.2587.3', + ]); + $cli->get('/', function ($cli) { + echo "Length: " . strlen($cli->body) . "\n"; +$cli->close(); + // echo $cli->body; + }); +}); + + + + +?> diff --git a/vendor/swoole/examples/http/http_proxy_auth.php b/vendor/swoole/examples/http/http_proxy_auth.php new file mode 100755 index 0000000..4181290 --- /dev/null +++ b/vendor/swoole/examples/http/http_proxy_auth.php @@ -0,0 +1,20 @@ +<?php + +$cli = new swoole_http_client('127.0.0.1', 80); +$cli->set(array( + 'http_proxy_host' => "127.0.0.1", + 'http_proxy_port' => 33080, + 'http_proxy_user' => 'test', + 'http_proxy_password' => 'test', +)); +$cli->setHeaders([ + 'Host' => "localhost", + "User-Agent" => 'Chrome/49.0.2587.3', +]); +$cli->get('/', function ($cli) { + echo "Length: " . strlen($cli->body) . ", statusCode=".$cli->statusCode."\n"; + $cli->close(); + echo $cli->body; +}); + + diff --git a/vendor/swoole/examples/http/https_proxy.php b/vendor/swoole/examples/http/https_proxy.php new file mode 100755 index 0000000..90c6fd5 --- /dev/null +++ b/vendor/swoole/examples/http/https_proxy.php @@ -0,0 +1,21 @@ +<?php +Swoole\Async::dnsLookup("www.baidu.com", function ($domainName, $ip) { +//Swoole\Async::dnsLookup("www.baidu.com", function ($domainName, $ip) { + $cli = new swoole_http_client($ip, 443,true); + $cli->set(array( + 'http_proxy_host'=>"127.0.0.1", + 'http_proxy_port'=>3128, + + )); + $cli->setHeaders([ + 'Host' => $domainName, + "User-Agent" => 'Chrome/49.0.2587.3', + ]); + $cli->get('/', function ($cli) { + echo "Length: " . strlen($cli->body) . "\n"; + echo $cli->body; + }); +}); + + +?> diff --git a/vendor/swoole/examples/http/post.data b/vendor/swoole/examples/http/post.data new file mode 100755 index 0000000..b85a2cf --- /dev/null +++ b/vendor/swoole/examples/http/post.data @@ -0,0 +1 @@ +dd=wwwwww&ddd=eee&3412=3234&hello=world%2C+i+am+rango%2C+thank+you.+no+body diff --git a/vendor/swoole/examples/http/raw.php b/vendor/swoole/examples/http/raw.php new file mode 100755 index 0000000..f825602 --- /dev/null +++ b/vendor/swoole/examples/http/raw.php @@ -0,0 +1,13 @@ +<?php +$sock = stream_socket_client("tcp://127.0.0.1:9501"); +fwrite($sock, file_get_contents('httpdata')); +stream_set_chunk_size($sock, 2*1024*1024); +$data = fread($sock, 8192 * 128); +if ($argv[1] == 'save') +{ + file_put_contents("resp.html", $data); +} +else +{ + echo $data; +} diff --git a/vendor/swoole/examples/http/redirect.php b/vendor/swoole/examples/http/redirect.php new file mode 100755 index 0000000..0536e3d --- /dev/null +++ b/vendor/swoole/examples/http/redirect.php @@ -0,0 +1,8 @@ +<?php +$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE); + +$http->on('request', function ($req, Swoole\Http\Response $resp) { + $resp->redirect("http://www.baidu.com/", 301); +}); + +$http->start(); diff --git a/vendor/swoole/examples/http/server.php b/vendor/swoole/examples/http/server.php new file mode 100755 index 0000000..ad6c376 --- /dev/null +++ b/vendor/swoole/examples/http/server.php @@ -0,0 +1,213 @@ +<?php +function dump($var) +{ + return highlight_string("<?php\n\$array = ".var_export($var, true).";", true); +} +$key_dir = dirname(dirname(__DIR__)) . '/tests/ssl'; +$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE); +//$http = new swoole_http_server("0.0.0.0", 9501); +//$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +//https +//$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +//$http->setGlobal(HTTP_GLOBAL_ALL, HTTP_GLOBAL_GET|HTTP_GLOBAL_POST|HTTP_GLOBAL_COOKIE); +$http->set([ +// 'daemonize' => 1, +// 'open_cpu_affinity' => 1, +// 'task_worker_num' => 1, + //'open_cpu_affinity' => 1, + //'task_worker_num' => 100, + //'enable_port_reuse' => true, +// 'worker_num' => 4, + //'log_file' => __DIR__.'/swoole.log', +// 'reactor_num' => 24, + //'dispatch_mode' => 3, + //'discard_timeout_request' => true, +// 'open_tcp_nodelay' => true, +// 'open_mqtt_protocol' => true, + //'task_worker_num' => 1, + //'user' => 'www-data', + //'group' => 'www-data', +//'daemonize' => true, +// 'ssl_cert_file' => $key_dir.'/ssl.crt', +// 'ssl_key_file' => $key_dir.'/ssl.key', + 'enable_static_handler' => true, + 'document_root' => '/home/htf/workspace/php/www.swoole.com/web/' +]); + +$http->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); + +function chunk(swoole_http_request $request, swoole_http_response $response) +{ + $response->write("<h1>hello world1</h1>"); + //sleep(1); + $response->write("<h1>hello world2</h1>"); + //sleep(1); + $response->end(); +} + +function no_chunk(swoole_http_request $request, swoole_http_response $response) +{ + /** + * Cookie Test + */ + //$response->cookie('test1', '1234', time() + 86400, '/'); +// $response->cookie('test2', '5678', time() + 86400); +// var_dump($response->cookie); +// var_dump($request->cookie); +// try +// { +// if (rand(1, 99) % 2 == 1) +// { +// throw new Exception("just for fun."); +// } +// $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); +// } +// catch(Exception $e) +// { +// $response->end("<h1>Exceptiom</h1><div>".$e->getMessage()."</div>"); +// } + //var_dump($request->server['request_uri'], substr($request->server['request_uri'], -4, 4)); + + if (substr($request->server['request_uri'], -8, 8) == 'test.jpg') + { + $response->header('Content-Type', 'image/jpeg'); + $response->sendfile(dirname(__DIR__).'/test.jpg'); + return; + } + if ($request->server['request_uri'] == '/test.txt') + { + $last_modified_time = filemtime(__DIR__ . '/test.txt'); + $etag = md5_file(__DIR__ . '/test.txt'); + // always send headers + $response->header("Last-Modified", gmdate("D, d M Y H:i:s", $last_modified_time) . " GMT"); + $response->header("Etag", $etag); + if (strtotime($request->header['if-modified-since']) == $last_modified_time or trim($request->header['if-none-match']) == $etag) + { + $response->status(304); + $response->end(); + } + else + { + $response->sendfile(__DIR__ . '/test.txt'); + } + return; + } + if ($request->server['request_uri'] == '/favicon.ico') + { + $response->status(404); + $response->end(); + return; + } + if ($request->server['request_uri'] == '/save') + { + file_put_contents(__DIR__.'/httpdata', $request->getData()); + $response->end('hello'); + return; + } +// else +// { + //var_dump($request->post); + //var_export($request->cookie); +// var_dump($request->rawContent()); +// if ($request->server['request_method'] == 'POST') +// { +// var_dump($request->post); +// } +// echo "GET:" . var_export($_GET, true)."\n"; +// echo "POST:" . var_export($_POST, true)."\n"; +// echo "get:" . var_export($request->get, true)."\n"; +// echo "post:" . var_export($request->post, true)."\n"; + //var_dump($request->server); + $output = ''; + $output .= "<h2>HEADER:</h2>".dump($request->header); + $output .= "<h2>SERVER:</h2>".dump($request->server); + if (!empty($request->files)) + { + $output .= "<h2>FILE:</h2>".dump($request->files); + } + if (!empty($request->cookie)) + { + $output .= "<h2>COOKIES:</h2>".dump($request->cookie); + } + if (!empty($request->get)) + { + $output .= "<h2>GET:</h2>".dump($request->get); + } + if (!empty($request->post)) + { + $output .= "<h2>POST:</h2>".dump($request->post); + } + var_dump($request->post); + //$response->header('X-Server', 'Swoole'); + //unset($request, $response); +// swoole_timer_after(2000, function() use ( $response) { + $response->end("<h1>Hello Swoole.</h1>".$output); +// }); +// } + return; + //var_dump($request); +// var_dump($_GET); + //var_dump($_POST); + //var_dump($_COOKIE); + //$response->status(301); + //$response->header("Location", "http://www.baidu.com/"); + //$response->cookie("hello", "world", time() + 3600); +// $response->header("Content-Type", "text/html; charset=utf-8"); + + //var_dump($request->post); +// var_dump($request->get); + +// echo strlen(gzdeflate("<h1>Hello Swoole.</h1>")); +// $response->end("<h1>Hello Swoole.</h1>"); + //$response->end("<h1>Hello Swoole. #".str_repeat('A', rand(100, 999))."</h1>"); + //global $http; + //$http->task("hello world"); + $file = realpath(__DIR__ . '/../' . $request->server['request_uri']); + if (is_file($file)) + { + echo "http get file=$file\n"; + if (substr($file, -4) == '.php') + { + $response->gzip(); + } + else + { + $response->header('Content-Type', 'image/jpeg'); + } + $content = file_get_contents($file); + echo "response size = " . strlen($content) . "\n"; + +// $response->write($content); +// $response->end(); + + $response->end($content); + } + else + { + $response->end("<h1>Hello Swoole.</h1>"); + } +} + +$http->on('request', 'no_chunk'); + +$http->on('finish', function () +{ + echo "task finish"; +}); + +$http->on('task', function () +{ + echo "async task\n"; +}); + +//$http->on('close', function(){ +// echo "on close\n"; +//}); + + +$http->on('workerStart', function ($serv, $id) +{ + //var_dump($serv); +}); + +$http->start(); diff --git a/vendor/swoole/examples/http/test.txt b/vendor/swoole/examples/http/test.txt new file mode 100755 index 0000000..bc7774a --- /dev/null +++ b/vendor/swoole/examples/http/test.txt @@ -0,0 +1 @@ +hello world! \ No newline at end of file diff --git a/vendor/swoole/examples/http/upload_file.php b/vendor/swoole/examples/http/upload_file.php new file mode 100755 index 0000000..d5bab20 --- /dev/null +++ b/vendor/swoole/examples/http/upload_file.php @@ -0,0 +1,11 @@ +<?php +$cli = new swoole_http_client('127.0.0.1', 80); +//post request +$cli->setHeaders(['User-Agent' => "swoole"]); +$cli->addFile(__DIR__.'/post.data', 'post'); +$cli->addFile(dirname(__DIR__).'/test.jpg', 'debug'); + +$cli->post('/dump2.php', array("xxx" => 'abc', 'x2' => 'rango'), function ($cli) { + echo $cli->body; + $cli->close(); +}); diff --git a/vendor/swoole/examples/http2/client.php b/vendor/swoole/examples/http2/client.php new file mode 100755 index 0000000..f643cbf --- /dev/null +++ b/vendor/swoole/examples/http2/client.php @@ -0,0 +1,47 @@ +<?php +//$host = '127.0.0.1'; +//$host = "wiki.swoole.com"; +$host = 'www.jd.com'; + +//$port = 9501; +$port = 443; + +//$ssl = false; +$ssl = true; + +$array = array( + "host" => $host, + "accept-encoding" => "gzip, deflate", + 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'accept-language' => 'zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2', + 'cache-control' => 'max-age=0', + 'user-agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3026.3 Safari/537.36', +); +$list = array(); +for($i = 0; $i < 1; $i++) { + $client = new swoole_http2_client($host , $port, $ssl); + + $client->setHeaders($array); + //$client->setCookies(array("a" => "1", "b" => "2")); + + $client->get("/", function ($o) use($client) { + echo "#{$client->sock} hello world 1\n"; + //var_dump($o); + echo $o->body; + $client->close(); + }); + + /*$client->post("/", $array, function ($o) use($client) { + echo "{$client->sock} hello world 2\n"; + }); + + + $client->post("/", $array, function ($o) use($client) { + echo "{$client->sock} hello world 3\n"; + echo $o->body; + $client->close(); + });*/ + $list[] = $client; +} + +Swoole\Event::wait(); diff --git a/vendor/swoole/examples/http2/server.php b/vendor/swoole/examples/http2/server.php new file mode 100755 index 0000000..cd7e91e --- /dev/null +++ b/vendor/swoole/examples/http2/server.php @@ -0,0 +1,15 @@ +<?php +$key_dir = dirname(__DIR__) . '/ssl'; +//$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE); +$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$http->set([ + 'open_http2_protocol' => 1, + 'ssl_cert_file' => $key_dir.'/ssl.crt', + 'ssl_key_file' => $key_dir.'/ssl.key', +]); + +$http->on('request', function (swoole_http_request $request, swoole_http_response $response) { + $response->end("<h1>Hello Swoole.</h1>"); +}); + +$http->start(); diff --git a/vendor/swoole/examples/ipv6/tcp_client.php b/vendor/swoole/examples/ipv6/tcp_client.php new file mode 100755 index 0000000..9be6014 --- /dev/null +++ b/vendor/swoole/examples/ipv6/tcp_client.php @@ -0,0 +1,17 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP6); +if (!$client->connect('::1', 9501, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +var_dump($client->getsockname()); + +for($i=0; $i < 1; $i ++) +{ + $client->send("hello world\n"); + echo $client->recv(); + usleep(2000); +} + +$client->close(); \ No newline at end of file diff --git a/vendor/swoole/examples/ipv6/tcp_server.php b/vendor/swoole/examples/ipv6/tcp_server.php new file mode 100755 index 0000000..b438f8f --- /dev/null +++ b/vendor/swoole/examples/ipv6/tcp_server.php @@ -0,0 +1,18 @@ +<?php +$serv = new swoole_server("::1", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP6); +$serv->set(array( + 'worker_num' => 1, +)); +$serv->on('connect', function ($serv, $fd, $from_id){ + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; +}); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + var_dump($serv->connection_info($fd)); + $serv->send($fd, json_encode(array("hello" => '1213', "bat" => "ab"))); + //$serv->close($fd); +}); +$serv->on('close', function ($serv, $fd, $from_id) { + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); +$serv->start(); diff --git a/vendor/swoole/examples/ipv6/udp_client.php b/vendor/swoole/examples/ipv6/udp_client.php new file mode 100755 index 0000000..a1765db --- /dev/null +++ b/vendor/swoole/examples/ipv6/udp_client.php @@ -0,0 +1,11 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP6); +$client->connect('::1', 9502); +$client->send("admin"); +echo $client->recv()."\n"; +var_dump($client->getsockname()); +var_dump($client->getpeername()); +$client->sendto('::1', 9502, "admin2"); +echo $client->recv()."\n"; +sleep(1); + diff --git a/vendor/swoole/examples/ipv6/udp_server.php b/vendor/swoole/examples/ipv6/udp_server.php new file mode 100755 index 0000000..2b1b04b --- /dev/null +++ b/vendor/swoole/examples/ipv6/udp_server.php @@ -0,0 +1,12 @@ +<?php +$serv = new swoole_server("::1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP6); +$serv->set(array( + 'worker_num' => 1, +)); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + var_dump($serv->connection_info($fd, $from_id)); + $serv->send($fd, json_encode(array("hello" => '1213', "bat" => "ab"))); + //$serv->close($fd); +}); +$serv->start(); diff --git a/vendor/swoole/examples/length/async_client.php b/vendor/swoole/examples/length/async_client.php new file mode 100755 index 0000000..fc484eb --- /dev/null +++ b/vendor/swoole/examples/length/async_client.php @@ -0,0 +1,50 @@ +<?php +function send(swoole_client $cli) +{ + $data = array( + 'str1' => str_repeat('A', rand(100000, 900000)), + 'str2' => str_repeat('B', rand(100000, 900000)), + 'str3' => str_repeat('C', rand(10000, 90000)), + ); + + $data['int1'] = rand(100000, 999999); + + $sendStr = serialize($data); + $sendData = pack('N', strlen($sendStr)) . $sendStr; + $cli->send($sendData); + echo "send length=" . strlen($sendData) . ", SerId={$data['int1']}\n"; +} + +$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); //异步非阻塞 + +$client->set(array( + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, //第N个字节是包长度的值 + 'package_body_offset' => 4, //第几个字节开始计算长度 + 'package_max_length' => 2000000, //协议最大长度 +)); + +$client->on("connect", function(swoole_client $cli) { + send($cli); +}); + +$client->on("receive", function (swoole_client $cli, $data) { + $resp = unserialize(substr($data, 4)); + echo "recv length=" . strlen($data) . ", SerId={$resp['int1']}\n".str_repeat('-', 60)."\n"; + $cli->close(); +// sleep(1); + //usleep(200000); + //send($cli); +}); + +$client->on("error", function(swoole_client $cli){ + echo "error\n"; +}); + +$client->on("close", function(swoole_client $cli){ + echo "Connection close\n"; +}); + +$client->connect('127.0.0.1', 9501); + diff --git a/vendor/swoole/examples/length/client.php b/vendor/swoole/examples/length/client.php new file mode 100755 index 0000000..33e5bbb --- /dev/null +++ b/vendor/swoole/examples/length/client.php @@ -0,0 +1,39 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); + +$client->set(array( + 'open_length_check' => true, + 'package_length_type' => 'N', + 'package_length_offset' => 0, //第N个字节是包长度的值 + 'package_body_offset' => 4, //第几个字节开始计算长度 + 'package_max_length' => 2000000, //协议最大长度 +)); + +if (!$client->connect('127.0.0.1', 9501)) +{ + exit("connect failed\n"); +} + +for ($i = 0; $i < 10; $i++) +{ + $data = array( + 'str1' => str_repeat('A', rand(10000, 20000)), + 'str2' => str_repeat('B', rand(5000, 10000)), + 'str3' => str_repeat('C', rand(1000, 9000)), + ); + + $data['int1'] = rand(100000, 999999); + $sendStr = serialize($data); + $sendData = pack('N', strlen($sendStr)) . $sendStr; + $client->send($sendData); + echo "send length=" . strlen($sendData) . ", SerId={$data['int1']}\n"; + + for ($j = 0; $j < 3; $j++) + { + $resp = $client->recv(); + $data2 = unserialize(substr($resp, 4)); + echo "#$j\trecv length=" . strlen($resp) . ", SerId={$data2['int1']}\n"; + } +} +sleep(2); + diff --git a/vendor/swoole/examples/length/config.php b/vendor/swoole/examples/length/config.php new file mode 100755 index 0000000..4556fe4 --- /dev/null +++ b/vendor/swoole/examples/length/config.php @@ -0,0 +1,3 @@ +<?php +$loop1 = 1; +$loop2 = 3; diff --git a/vendor/swoole/examples/length/func.php b/vendor/swoole/examples/length/func.php new file mode 100755 index 0000000..3864321 --- /dev/null +++ b/vendor/swoole/examples/length/func.php @@ -0,0 +1,26 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); + +$serv->set(array( + 'open_length_check' => true, + 'dispatch_mode' => 1, + 'package_length_func' => function ($data) { + if (strlen($data) < 8) { + return 0; + } + $length = intval(trim(substr($data, 0, 8))); + if ($length <= 0) { + return -1; + } + return $length + 8; + }, + 'package_max_length' => 2000000, //协议最大长度 +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + var_dump($data); + echo "#{$serv->worker_id}>> received length=" . strlen($data) . "\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/length/server.php b/vendor/swoole/examples/length/server.php new file mode 100755 index 0000000..df10c93 --- /dev/null +++ b/vendor/swoole/examples/length/server.php @@ -0,0 +1,35 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + +$serv->set(array( + 'open_length_check' => true, + 'dispatch_mode' => 1, +// 'worker_num' => 4, + 'package_length_type' => 'N', + 'package_length_offset' => 0, //第N个字节是包长度的值 + 'package_body_offset' => 4, //第几个字节开始计算长度 + 'package_max_length' => 2000000, //协议最大长度 +)); + +function send(swoole_server $serv, $fd, $data) +{ + $serv->send($fd, $data); + echo "#send =" . strlen($data) . " bytes\n"; +} + +$serv->on('connect', function ($serv, $fd){ + echo "Client:Connect.\n"; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + $req = unserialize(substr($data, 4)); + echo "#{$serv->worker_id}>> received length=" . strlen($data) . ", SerId: {$req['int1']}\n"; + send($serv, $fd, $data); + send($serv, $fd, $data); + send($serv, $fd, $data); +}); + +$serv->on('close', function ($serv, $fd) { + echo "Client: Close.\n"; +}); +$serv->start(); diff --git a/vendor/swoole/examples/lock/lock.php b/vendor/swoole/examples/lock/lock.php new file mode 100755 index 0000000..f8159d3 --- /dev/null +++ b/vendor/swoole/examples/lock/lock.php @@ -0,0 +1,30 @@ +<?php +/** + * SWOOLE_MUTEX 互斥锁 + * SWOOLE_FILELOCK 文件锁,需要在第二个参数传入一个锁文件 + * SWOOLE_SPINLOCK 自旋锁(请查看swoole扩展信息,检测是否支持) + * SWOOLE_SEM 信号量 + * SWOOLE_RWLOCK 读写锁 + */ + +$lock = new swoole_lock(SWOOLE_MUTEX); +echo "[Master]create lock\n"; +$lock->lock(); +if (pcntl_fork() > 0) +{ + sleep(1); + $lock->unlock(); +} +else +{ + echo "[Child] Wait Lock\n"; + $lock->lock(); + echo "[Child] Get Lock\n"; + $lock->unlock(); + exit("[Child] exit\n"); +} +echo "[Master]release lock\n"; +unset($lock); +sleep(1); +echo "[Master]exit\n"; + diff --git a/vendor/swoole/examples/memory/pool.php b/vendor/swoole/examples/memory/pool.php new file mode 100755 index 0000000..5dfee4c --- /dev/null +++ b/vendor/swoole/examples/memory/pool.php @@ -0,0 +1,13 @@ +<?php + +use Swoole\Memory\Pool; + +$pool = new Pool(2 * 1024 * 1024, Pool::TYPE_RING, 1024); + +/** + * @var $p1 Swoole\Memory\Pool\Slice + */ +$p1 = $pool->alloc(); +$p1->write("hello world"); +echo $p1->read()."\n"; +echo $p1->read(5, 6)."\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/mmap/mmap.php b/vendor/swoole/examples/mmap/mmap.php new file mode 100755 index 0000000..195119c --- /dev/null +++ b/vendor/swoole/examples/mmap/mmap.php @@ -0,0 +1,15 @@ +<?php +$file = '/tmp/data'; +$size = 8192; + +if (!is_file($file)) { + file_put_contents($file, str_repeat("\0", $size)); +} + +$fp = swoole\mmap::open($file, 8192); + +fwrite($fp, "hello world\n"); +fwrite($fp, "hello swoole\n"); + +fflush($fp); +fclose($fp); diff --git a/vendor/swoole/examples/multi_port_server.php b/vendor/swoole/examples/multi_port_server.php new file mode 100755 index 0000000..8c44666 --- /dev/null +++ b/vendor/swoole/examples/multi_port_server.php @@ -0,0 +1,44 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +//这里监听了一个UDP端口用来做内网管理 +$port = $serv->addlistener('127.0.0.1', 9502, SWOOLE_SOCK_UDP); + +$port->on('packet', function($serv, $data, $client) { + var_dump($data, $client); + $serv->sendto($client['address'], $client['port'], "welcome admin\n"); +}); +$serv->on('connect', function ($serv, $fd) { + echo "Client:Connect.\n"; +}); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + $info = $serv->connection_info($fd, $from_id); + //来自9502的内网管理端口 + if($info['server_port'] == 9502) { + $serv->send($fd, "welcome admin\n"); + $start_fd = 0; + while(true) + { + $conn_list = $serv->connection_list($start_fd, 10); + if($conn_list === false) + { + break; + } + $start_fd = end($conn_list); + var_dump($conn_list); + + foreach($conn_list as $conn) + { + if($conn === $fd) continue; + $serv->send($conn, "hello from $fd\n"); + } + } + } + //来自外网 + else { + $serv->send($fd, 'Swoole: '.$data); + } +}); +$serv->on('close', function ($serv, $fd) { + echo "Client: Close.\n"; +}); +$serv->start(); diff --git a/vendor/swoole/examples/multicast/client.php b/vendor/swoole/examples/multicast/client.php new file mode 100755 index 0000000..bbee801 --- /dev/null +++ b/vendor/swoole/examples/multicast/client.php @@ -0,0 +1,6 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC); +$client->connect('224.10.20.30', 9905); +$client->send("hello world"); +echo $client->recv() . "\n"; +sleep(1); diff --git a/vendor/swoole/examples/multicast/server.php b/vendor/swoole/examples/multicast/server.php new file mode 100755 index 0000000..20b68d9 --- /dev/null +++ b/vendor/swoole/examples/multicast/server.php @@ -0,0 +1,24 @@ +<?php +$server = new swoole_server('0.0.0.0', 9905, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); +$server->set(['worker_num' => 1]); +$socket = $server->getSocket(); + +$ret = socket_set_option( + $socket, + IPPROTO_IP, + MCAST_JOIN_GROUP, + array('group' => '224.10.20.30', 'interface' => 0) +); + +if ($ret === false) +{ + throw new RuntimeException('Unable to join multicast group'); +} + +$server->on('Packet', function (swoole_server $serv, $data, $addr) +{ + $serv->sendto($addr['address'], $addr['port'], "Swoole: $data"); + var_dump( $addr, strlen($data)); +}); + +$server->start(); diff --git a/vendor/swoole/examples/mysql/mysqli_prepare.php b/vendor/swoole/examples/mysql/mysqli_prepare.php new file mode 100755 index 0000000..9687983 --- /dev/null +++ b/vendor/swoole/examples/mysql/mysqli_prepare.php @@ -0,0 +1,41 @@ +<?php +$db = new mysqli('127.0.0.1', 'root', 'root', 'test'); + +echo "connect success\n"; + +$stmt = $db->prepare("SELECT id, name FROM userinfo WHERE id=?"); +//$stmt = $db->prepare("SELECT id, name FROM userinfo WHERE id=? and name=? and level=?"); +//var_dump($stmt); +$id = 1; +//$name = 'jack'; +//$level = 199; +exit; +$stmt->bind_param('i', $id); +//$stmt->bind_param('isi', $id, $name, $level); +echo "execute sql\n"; +$stmt->execute(); + +$stmt->bind_result($id, $name); +$stmt->fetch(); + +var_dump($id, $name); +$stmt->close(); + +exit; +echo "prepare 2\n"; + +$stmt2 = $db->prepare("SELECT id, name FROM userinfo WHERE id=? and name=? and level=?"); +var_dump($stmt2); +$id = 1; +$name = 'jack'; +$level = 199; +$stmt2->bind_param('isi', $id, $name, $level); +echo "execute sql\n"; +$stmt2->execute(); + +$stmt2->bind_result($id, $name); +$stmt2->fetch(); + +var_dump($id, $name); +//$stmt2->close(); + diff --git a/vendor/swoole/examples/mysql/pdo_prepare.php b/vendor/swoole/examples/mysql/pdo_prepare.php new file mode 100755 index 0000000..fd2c377 --- /dev/null +++ b/vendor/swoole/examples/mysql/pdo_prepare.php @@ -0,0 +1,6 @@ +<?php +$db = new PDO("mysql:host=127.0.0.1;dbname=test;charset=utf8", "root" ,"root"); +$query = $db->prepare("select * from userinfo where id=?"); +$rs = $query->execute(array(1)); +var_dump($rs); +echo count($query->fetchAll()); diff --git a/vendor/swoole/examples/mysql/pdo_prepare2.php b/vendor/swoole/examples/mysql/pdo_prepare2.php new file mode 100755 index 0000000..7162045 --- /dev/null +++ b/vendor/swoole/examples/mysql/pdo_prepare2.php @@ -0,0 +1,14 @@ +<?php +$pdo = new PDO("mysql:host=127.0.0.1;dbname=test;charset=utf8", "root" ,"root"); +$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + +$sql = "SELECT * FROM userinfo WHERE `id`=:id"; +$stmt = $pdo->prepare($sql); // 准备一条预处理语句 + +// 占位符的使用方法一, 这样还可以便面sql注入 +$res = $stmt->execute(array(":id"=> 1)); +if (!$res){ + echo exit("错误信息: ".var_dump($stmt->errorInfo())); +} +var_dump($stmt->rowCount()); +var_dump($stmt->fetchAll()); diff --git a/vendor/swoole/examples/mysql/prepare.php b/vendor/swoole/examples/mysql/prepare.php new file mode 100755 index 0000000..592e511 --- /dev/null +++ b/vendor/swoole/examples/mysql/prepare.php @@ -0,0 +1,14 @@ +<?php +$db = new mysqli('127.0.0.1', 'root', 'root', 'test'); + +$stmt = $db->prepare("SELECT id, name FROM userinfo WHERE id=?"); +var_dump($stmt); +$id = 1; +$stmt->bind_param('i', $id); +$stmt->execute(); + +$stmt->bind_result($id, $name); +$stmt->fetch(); + +var_dump($id, $name); +$stmt->close(); diff --git a/vendor/swoole/examples/mysql/real_async.php b/vendor/swoole/examples/mysql/real_async.php new file mode 100755 index 0000000..7296401 --- /dev/null +++ b/vendor/swoole/examples/mysql/real_async.php @@ -0,0 +1,39 @@ +<?php +$db = new swoole_mysql; +$server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', +); + +$db->on('close', function() use($db) { + echo "mysql is closed.\n"; +}); + +$r = $db->connect($server, function ($db, $result) +{ + if ($result === false) + { + var_dump($db->connect_errno, $db->connect_error); + die; + } + echo "connect to mysql server sucess\n"; + $sql = 'show tables'; + //$sql = "INSERT INTO `test`.`userinfo` (`id`, `name`, `passwd`, `regtime`, `lastlogin_ip`) VALUES (NULL, 'jack', 'xuyou', CURRENT_TIMESTAMP, '');"; + $db->query($sql, function (swoole_mysql $db, $r) + { + global $s; + if ($r === false) + { + var_dump($db->error, $db->errno); + } + elseif ($r === true) + { + var_dump($db->affected_rows, $db->insert_id); + } + echo "count=" . count($r) . ", time=" . (microtime(true) - $s), "\n"; + //var_dump($r); + $db->close(); + }); +}); diff --git a/vendor/swoole/examples/mysql/sync.php b/vendor/swoole/examples/mysql/sync.php new file mode 100755 index 0000000..46bb107 --- /dev/null +++ b/vendor/swoole/examples/mysql/sync.php @@ -0,0 +1,10 @@ +<?php +$db = new mysqli; +$db->connect('127.0.0.1', 'root', 'root', 'test'); +var_dump($db->get_charset()); +$r = $db->escape_string("abc'efg\r\n"); + +var_dump($r); + +//$res = $db->query("show databases"); + diff --git a/vendor/swoole/examples/mysql/transaction.php b/vendor/swoole/examples/mysql/transaction.php new file mode 100755 index 0000000..f583c06 --- /dev/null +++ b/vendor/swoole/examples/mysql/transaction.php @@ -0,0 +1,32 @@ +<?php +$db = new swoole_mysql; +$server = array( + 'host' => '127.0.0.1', + 'user' => 'root', + 'password' => 'root', + 'database' => 'test', +); + +$db->on('close', function() use($db) { + echo "mysql is closed.\n"; +}); + +$r = $db->connect($server, function ($db, $result) +{ + echo "connect to mysql server sucess\n"; + if ($result === false) + { + var_dump($db->connect_errno, $db->connect_error); + die; + } + $db->begin(function( $db, $result) { + var_dump($result); + $db->query("update userinfo set level = 22 where id = 1", function($db, $result) { + var_dump($result, $db); + $db->rollback(function($db, $result){ + echo "commit ok\n"; + var_dump($result, $db); + }); + }); + }); +}); \ No newline at end of file diff --git a/vendor/swoole/examples/mysql_proxy_server.php b/vendor/swoole/examples/mysql_proxy_server.php new file mode 100755 index 0000000..429a645 --- /dev/null +++ b/vendor/swoole/examples/mysql_proxy_server.php @@ -0,0 +1,126 @@ +<?php +class DBServer +{ + protected $pool_size = 20; + protected $idle_pool = array(); //空闲连接 + protected $busy_pool = array(); //工作连接 + protected $wait_queue = array(); //等待的请求 + protected $wait_queue_max = 100; //等待队列的最大长度,超过后将拒绝新的请求 + + /** + * @var swoole_server + */ + protected $serv; + + function run() + { + $serv = new swoole_server("127.0.0.1", 9509); + $serv->set(array( + 'worker_num' => 1, + 'max_request' => 0, + )); + + $serv->on('WorkerStart', array($this, 'onStart')); + //$serv->on('Connect', array($this, 'onConnect')); + $serv->on('Receive', array($this, 'onReceive')); + //$serv->on('Close', array($this, 'onClose')); + $serv->start(); + } + + function onStart($serv) + { + $this->serv = $serv; + for ($i = 0; $i < $this->pool_size; $i++) { + $db = new mysqli; + $db->connect('127.0.0.1', 'root', 'root', 'www4swoole'); + $db_sock = swoole_get_mysqli_sock($db); + swoole_event_add($db_sock, array($this, 'onSQLReady')); + $this->idle_pool[] = array( + 'mysqli' => $db, + 'db_sock' => $db_sock, + 'fd' => 0, + ); + } + echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n"; + } + + function onSQLReady($db_sock) + { + $db_res = $this->busy_pool[$db_sock]; + $mysqli = $db_res['mysqli']; + $fd = $db_res['fd']; + + echo __METHOD__ . ": client_sock=$fd|db_sock=$db_sock\n"; + + if ($result = $mysqli->reap_async_query()) { + $ret = var_export($result->fetch_all(MYSQLI_ASSOC), true) . "\n"; + $this->serv->send($fd, $ret); + if (is_object($result)) { + mysqli_free_result($result); + } + } else { + $this->serv->send($fd, sprintf("MySQLi Error: %s\n", mysqli_error($mysqli))); + } + //release mysqli object + $this->idle_pool[] = $db_res; + unset($this->busy_pool[$db_sock]); + + //这里可以取出一个等待请求 + if (count($this->wait_queue) > 0) { + $idle_n = count($this->idle_pool); + for ($i = 0; $i < $idle_n; $i++) { + $req = array_shift($this->wait_queue); + $this->doQuery($req['fd'], $req['sql']); + } + } + } + + function onReceive($serv, $fd, $from_id, $data) + { + echo "Received: $data\n"; + //没有空闲的数据库连接 + + if (count($this->idle_pool) == 0) { + //等待队列未满 + if (count($this->wait_queue) < $this->wait_queue_max) { + $this->wait_queue[] = array( + 'fd' => $fd, + 'sql' => $data, + ); + } else { + $this->serv->send($fd, "request too many, Please try again later."); + } + } else { + $this->doQuery($fd, $data); + } + } + + function doQuery($fd, $sql) + { + //从空闲池中移除 + $db = array_pop($this->idle_pool); + /** + * @var mysqli + */ + $mysqli = $db['mysqli']; + + for ($i = 0; $i < 2; $i++) { + $result = $mysqli->query($sql, MYSQLI_ASYNC); + if ($result === false) { + if ($mysqli->errno == 2013 or $mysqli->errno == 2006) { + $mysqli->close(); + $r = $mysqli->connect(); + if ($r === true) continue; + } + } + break; + } + + $db['fd'] = $fd; + //加入工作池中 + $this->busy_pool[$db['db_sock']] = $db; + } +} + +$server = new DBServer(); +$server->run(); diff --git a/vendor/swoole/examples/namespace/README.md b/vendor/swoole/examples/namespace/README.md new file mode 100755 index 0000000..a396a3f --- /dev/null +++ b/vendor/swoole/examples/namespace/README.md @@ -0,0 +1,24 @@ +Enable Namespace Class +--------- +modify your `php.ini` file. + +```shell +swoole.use_namespace = on +``` + + +```php +use Swoole\Http\Server; +use Swoole\Http\Request; +use Swoole\Http\Response; + +$serv = new Server('127.0.0.1', 9501); + +$serv->on('Request', function(Request $req, Response $resp) { + var_dump($req->header, get_class($req)); + $resp->end("<h1>Hello Swoole</h1>"); +}); + +$serv->start(); + +``` diff --git a/vendor/swoole/examples/namespace/atomic.php b/vendor/swoole/examples/namespace/atomic.php new file mode 100755 index 0000000..523e333 --- /dev/null +++ b/vendor/swoole/examples/namespace/atomic.php @@ -0,0 +1,5 @@ +<?php +$an = new Swoole\Atomic(100); + +$an->add(12); +echo $an->get()."\n"; diff --git a/vendor/swoole/examples/namespace/http_server.php b/vendor/swoole/examples/namespace/http_server.php new file mode 100755 index 0000000..ce4fca0 --- /dev/null +++ b/vendor/swoole/examples/namespace/http_server.php @@ -0,0 +1,14 @@ +<?php +use Swoole\Http\Server; +use Swoole\Http\Request; +use Swoole\Http\Response; + +$serv = new Server('127.0.0.1', 9501); + +$serv->on('Request', function(Request $req, Response $resp) { + var_dump($req->header, get_class($req)); + $resp->end("<h1>Hello Swoole</h1>"); +}); + +$serv->start(); + diff --git a/vendor/swoole/examples/namespace/server.php b/vendor/swoole/examples/namespace/server.php new file mode 100755 index 0000000..9f973cc --- /dev/null +++ b/vendor/swoole/examples/namespace/server.php @@ -0,0 +1,14 @@ +<?php +use Swoole\Server; + +$serv = new Server("127.0.0.1", 9501); + +$serv->on('receive', function (Server $serv, $fd, $from_id, $data) { + echo "[#".$serv->worker_id."]\tClient[$fd]: $data\n"; + if ($serv->send($fd, "hello\n") == false) + { + echo "error\n"; + } +}); + +$serv->start(); diff --git a/vendor/swoole/examples/namespace/timer.php b/vendor/swoole/examples/namespace/timer.php new file mode 100755 index 0000000..e9f5517 --- /dev/null +++ b/vendor/swoole/examples/namespace/timer.php @@ -0,0 +1,4 @@ +<?php +Swoole\Timer::tick(2000, function($timerId) { + echo "tick 2000ms\n"; +}); diff --git a/vendor/swoole/examples/php/debug_server.php b/vendor/swoole/examples/php/debug_server.php new file mode 100755 index 0000000..7be95af --- /dev/null +++ b/vendor/swoole/examples/php/debug_server.php @@ -0,0 +1,66 @@ +<?php + +class DebugServer +{ + protected $alloc_point = array(); + protected $free_point = array(); + protected $index = 0; + + function package_decode($pkg) + { + list($tag, $_vars) = explode(':', $pkg, 2); + $tag = trim($tag); + $vars = explode(',', trim($_vars)); + $data = array(); + foreach($vars as $str) + { + list($k, $v) = explode('=', trim($str)); + $data[$k] = $v; + } + + if ($tag == 'alloc') + { + file_put_contents(__DIR__.'/alloc.log', $data['ptr']."\n", FILE_APPEND); + } + elseif($tag =='memory') + { + var_dump($tag, $data); + } + elseif ($tag == 'free') + { + file_put_contents(__DIR__.'/free.log', $data['ptr']."\n", FILE_APPEND); + } + elseif($tag == 'invalid') + { + foreach($this->alloc_point as $k => $v) + { + echo "$k => $v\n"; + } + } + else + { + //var_dump($tag, $data); + } + } + + function run() + { + unlink(__DIR__.'/alloc.log'); + unlink(__DIR__.'/free.log'); + $socket = stream_socket_server("udp://127.0.0.1:9999", $errno, $errstr, STREAM_SERVER_BIND); + if (!$socket) + { + die("$errstr ($errno)"); + } + while(1) + { + $pkt = stream_socket_recvfrom($socket, 65535, 0, $peer); + $this->package_decode($pkt); + //echo "$peer: $pkt\n"; + //stream_socket_sendto($socket, date("D M j H:i:s Y\r\n"), 0, $peer); + } + } +} + +$svr = new DebugServer; +$svr->run(); \ No newline at end of file diff --git a/vendor/swoole/examples/php/error.php b/vendor/swoole/examples/php/error.php new file mode 100755 index 0000000..f442346 --- /dev/null +++ b/vendor/swoole/examples/php/error.php @@ -0,0 +1,3 @@ +<?php + +2->test(); diff --git a/vendor/swoole/examples/php/inotify.php b/vendor/swoole/examples/php/inotify.php new file mode 100755 index 0000000..f27c825 --- /dev/null +++ b/vendor/swoole/examples/php/inotify.php @@ -0,0 +1,14 @@ +<?php +// Open an inotify instance +$fd = inotify_init(); + +// Watch __FILE__ for metadata changes (e.g. mtime) +$watch_descriptor = inotify_add_watch($fd, __DIR__ . '/php', IN_MODIFY | IN_MOVED_FROM | IN_CREATE | IN_DELETE | IN_ISDIR); + +while (true) +{ + // Read events + $events = inotify_read($fd); + print_r($events); +} + diff --git a/vendor/swoole/examples/php/mysql.php b/vendor/swoole/examples/php/mysql.php new file mode 100755 index 0000000..86ecc9e --- /dev/null +++ b/vendor/swoole/examples/php/mysql.php @@ -0,0 +1,27 @@ +<?php +$db = new mysqli; +$db->connect('127.0.0.1', 'root', 'root', 'test'); + +$db->query("show databases", MYSQLI_ASYNC); +sleep(1); +if ($result = $db->reap_async_query()) +{ + print_r($result->fetch_row()); + if(is_object($result)) + { + mysqli_free_result($result); + } +} +else die(sprintf("MySQLi Error: %s", mysqli_error($link))); + +$db->query("show tables", MYSQLI_ASYNC); +sleep(1); +if ($result = $db->reap_async_query()) +{ + print_r($result->fetch_row()); + if(is_object($result)) + { + mysqli_free_result($result); + } +} +else die(sprintf("MySQLi Error: %s", mysqli_error($link))); diff --git a/vendor/swoole/examples/php/socket_client.php b/vendor/swoole/examples/php/socket_client.php new file mode 100755 index 0000000..aab8080 --- /dev/null +++ b/vendor/swoole/examples/php/socket_client.php @@ -0,0 +1,15 @@ +<?php +pcntl_signal(SIGIO, function () { + echo "SIGIO"; +}); + + +$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); +socket_connect($socket, '127.0.0.1', 8889); + +$timeout = array('sec'=>1, 'usec' => 500000); +socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,$timeout); + +$n = socket_recv($socket, $buf, 2048, MSG_WAITALL); + +var_dump($n, $buf); diff --git a/vendor/swoole/examples/php/socket_server.php b/vendor/swoole/examples/php/socket_server.php new file mode 100755 index 0000000..56b8bbb --- /dev/null +++ b/vendor/swoole/examples/php/socket_server.php @@ -0,0 +1,30 @@ +<?php +error_reporting(E_ALL); +$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); +if ( $socket === false ) { + echo "socket_create() failed:reason:" . socket_strerror( socket_last_error() ) . "\n"; +} +$ok = socket_bind( $socket,'127.0.0.1',11109); +if ( $ok === false ) { + echo "socket_bind() failed:reason:" . socket_strerror( socket_last_error( $socket ) ); +} + +$ok = socket_listen($socket, 128); +if ( $ok === false ) { + echo "socket_bind() failed:reason:" . socket_strerror( socket_last_error( $socket ) ); +} + +while ( true ) { + sleep(1000); + $conn = socket_accept($socket); + if($conn) { + if(socket_recv($conn, $data, 8192, null)) + { + echo $data,"\n"; + socket_send($conn, "hello world\n", 11, null); + socket_close($conn); + } + } else { + echo "error\n"; + } +} diff --git a/vendor/swoole/examples/php/stream_client.php b/vendor/swoole/examples/php/stream_client.php new file mode 100755 index 0000000..04bfda0 --- /dev/null +++ b/vendor/swoole/examples/php/stream_client.php @@ -0,0 +1,9 @@ +<?php +$fp = stream_socket_client("tcp://172.16.51.114:8000", $errno, $errstr, 30); +if (!$fp) { + echo "$errstr ($errno)<br />\n"; +} else { + fwrite($fp, "GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n"); + sleep(1000); + fclose($fp); +} diff --git a/vendor/swoole/examples/php/stream_server.php b/vendor/swoole/examples/php/stream_server.php new file mode 100755 index 0000000..612e935 --- /dev/null +++ b/vendor/swoole/examples/php/stream_server.php @@ -0,0 +1,26 @@ +<?php + +$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr); +if (!$socket) { + echo "$errstr ($errno)<br />\n"; +} else { + while ($conn = stream_socket_accept($socket)) { + $i = 0; + while(true) { + $r = fwrite($conn, str_repeat("A", 8192)); + usleep(1000); + if (empty($r)) { + echo "count $i \n"; + var_dump($r); + stream_set_blocking($conn, 0); + } + else{ + $i++; + } + if ($r === false) break; + } + fclose($conn); + + } + fclose($socket); +} diff --git a/vendor/swoole/examples/postgresql/postgresql_coro.php b/vendor/swoole/examples/postgresql/postgresql_coro.php new file mode 100755 index 0000000..7052232 --- /dev/null +++ b/vendor/swoole/examples/postgresql/postgresql_coro.php @@ -0,0 +1,22 @@ + +<?php + +go(function () { + + $pg = new Swoole\Coroutine\PostgreSql(); + $conn = $pg -> connect ("host=127.0.0.1 port=5432 dbname=test user=wuzhenyu password="); + $result = $pg->query($conn, 'SELECT * FROM test;'); + $arr = $pg->fetchAll($result);// the same with affectedRows(),fetchObject(),fetchAssoc(),fetchArray(),fetchRow(),numRows() + var_dump($arr); + +}); + +go(function () { + + $pg = new Swoole\Coroutine\PostgreSql(); + $conn = $pg -> connect ("host=127.0.0.1 port=5432 dbname=test user=wuzhenyu password="); + $metaData = $pg->metaData($conn, 'test'); + var_dump($metaData); + +}); +?> diff --git a/vendor/swoole/examples/process/alarm.php b/vendor/swoole/examples/process/alarm.php new file mode 100755 index 0000000..859d1ab --- /dev/null +++ b/vendor/swoole/examples/process/alarm.php @@ -0,0 +1,13 @@ +<?php +swoole_process::signal(SIGALRM, function () +{ + static $i = 0; + echo "#{$i}\talarm\n"; + $i++; + if ($i > 20) + { + swoole_process::alarm(-1); + } +}); + +swoole_process::alarm(100 * 1000); diff --git a/vendor/swoole/examples/process/async_master.php b/vendor/swoole/examples/process/async_master.php new file mode 100755 index 0000000..c6b8ae8 --- /dev/null +++ b/vendor/swoole/examples/process/async_master.php @@ -0,0 +1,41 @@ +<?php +$workers = []; +$worker_num = 10; + +//swoole_process::daemon(0, 1); + +function onReceive($pipe) { + global $workers; + $worker = $workers[$pipe]; + $data = $worker->read(); + echo "RECV: " . $data; +} + +//循环创建进程 +for($i = 0; $i < $worker_num; $i++) +{ + $process = new swoole_process(function(swoole_process $process) { + $i = 1; + while($i++) + { + $process->write("Worker#{$process->id}: hello master\n"); + if ($i > 5 and $process->id == 1) $process->exit(); + sleep(1); + } + }); + $process->id = $i; + $pid = $process->start(); + $workers[$process->pipe] = $process; +} + +swoole_process::signal(SIGCHLD, function(){ + //表示子进程已关闭,回收它 + $status = swoole_process::wait(); + echo "Worker#{$status['pid']} exit\n"; +}); + +//将子进程的管道加入EventLoop +foreach($workers as $process) +{ + swoole_event_add($process->pipe, 'onReceive'); +} diff --git a/vendor/swoole/examples/process/client.php b/vendor/swoole/examples/process/client.php new file mode 100755 index 0000000..2dd195e --- /dev/null +++ b/vendor/swoole/examples/process/client.php @@ -0,0 +1,20 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); + +if (!$client->connect('127.0.0.1', 8089, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +function _send(swoole_client $client, $data) +{ + return $client->send(pack('N', strlen($data)) . $data); +} + +var_dump($client->getsockname()); + + +_send($client, "hello world"); +_send($client, "hello world [2]"); + +$client->close(); diff --git a/vendor/swoole/examples/process/client3.php b/vendor/swoole/examples/process/client3.php new file mode 100755 index 0000000..1441da2 --- /dev/null +++ b/vendor/swoole/examples/process/client3.php @@ -0,0 +1,7 @@ +<?php +$fp = stream_socket_client("tcp://127.0.0.1:8089", $errno, $errstr) or die("error: $errstr\n"); +$msg = json_encode(['data' => 'hello', 'uid' => 1991]); +fwrite($fp, pack('N', strlen($msg)) . $msg); +sleep(1); +var_dump(fread($fp, 8192)); +fclose($fp); \ No newline at end of file diff --git a/vendor/swoole/examples/process/close.php b/vendor/swoole/examples/process/close.php new file mode 100755 index 0000000..5b00c27 --- /dev/null +++ b/vendor/swoole/examples/process/close.php @@ -0,0 +1,17 @@ +<?php +$process = new swoole_process(function (swoole_process $worker) +{ + echo "Worker: start. PID=" . $worker->pid . "\n"; + sleep(2); + $worker->close(swoole_process::PIPE_READ); + $worker->write("hello master\n"); + $worker->exit(0); +}, false); + +$pid = $process->start(); +$r = array($process); +$w = array(); +$e = array(); +$ret = swoole_select($r, $w, $e, 1.0); +var_dump($ret); +var_dump($process->read()); diff --git a/vendor/swoole/examples/process/echo.py b/vendor/swoole/examples/process/echo.py new file mode 100755 index 0000000..893ab62 --- /dev/null +++ b/vendor/swoole/examples/process/echo.py @@ -0,0 +1,7 @@ +import sys + +def main(): + s = raw_input() + print "Python:" + s + +main() diff --git a/vendor/swoole/examples/process/exec.php b/vendor/swoole/examples/process/exec.php new file mode 100755 index 0000000..4fe7170 --- /dev/null +++ b/vendor/swoole/examples/process/exec.php @@ -0,0 +1,16 @@ +<?php +$process = new swoole_process('callback_function', true); +$pid = $process->start(); + +function callback_function(swoole_process $worker) +{ + $worker->exec('/usr/local/bin/php', array(__DIR__.'/stdin_stdout.php')); +} + +echo "From Worker: ".$process->read(); +$process->write("hello worker\n"); +echo "From Worker: ".$process->read(); + +$ret = swoole_process::wait(); +var_dump($ret); + diff --git a/vendor/swoole/examples/process/func_timeout.php b/vendor/swoole/examples/process/func_timeout.php new file mode 100755 index 0000000..b1fb491 --- /dev/null +++ b/vendor/swoole/examples/process/func_timeout.php @@ -0,0 +1,43 @@ +<?php +declare(ticks = 1); +Swoole\Async::set([ + 'enable_signalfd' => false, +]); + +class FunctionTimeoutException extends RuntimeException +{ + +} + +function test() +{ + sleep(1); +} + +$serv = new Swoole\Http\Server("127.0.0.1", 9502); + +$serv->set(['worker_num' => 1]); + +$serv->on('WorkerStart', function($serv, $workerId) { + pcntl_signal(SIGALRM, function () { + Swoole\Process::alarm(-1); + throw new FunctionTimeoutException; + }); +}); + +$serv->on('Request', function($request, $response) { + try + { + Swoole\Process::alarm(100 * 1000); + test(); + Swoole\Process::alarm(-1); + $response->end("<h1>Finish</h1>"); + } + catch(FunctionTimeoutException $e) + { + $response->end("<h1>Timeout</h1>"); + } + +}); + +$serv->start(); diff --git a/vendor/swoole/examples/process/msgqueue.php b/vendor/swoole/examples/process/msgqueue.php new file mode 100755 index 0000000..f88c45b --- /dev/null +++ b/vendor/swoole/examples/process/msgqueue.php @@ -0,0 +1,45 @@ +<?php +$workers = []; +$worker_num = 2; + +for($i = 0; $i < $worker_num; $i++) +{ + $process = new swoole_process('callback_function', false, false); + $process->useQueue(); + $pid = $process->start(); + $workers[$pid] = $process; + //echo "Master: new worker, PID=".$pid."\n"; +} + +function callback_function(swoole_process $worker) +{ + //echo "Worker: start. PID=".$worker->pid."\n"; + //recv data from master + while(true) + { + $recv = $worker->pop(); + echo "From Master: $recv\n"; + } + + sleep(2); + $worker->exit(0); +} + +while(true) +{ + /** + * @var $process swoole_process + */ + $pid = array_rand($workers); + $process = $workers[$pid]; + $process->push("hello worker[$pid]\n"); + sleep(1); +} + +for($i = 0; $i < $worker_num; $i++) +{ + $ret = swoole_process::wait(); + $pid = $ret['pid']; + unset($workers[$pid]); + echo "Worker Exit, PID=".$pid.PHP_EOL; +} diff --git a/vendor/swoole/examples/process/msgqueue2.php b/vendor/swoole/examples/process/msgqueue2.php new file mode 100755 index 0000000..b3d7172 --- /dev/null +++ b/vendor/swoole/examples/process/msgqueue2.php @@ -0,0 +1,36 @@ +<?php +function callback_function(swoole_process $worker) +{ + //echo "Worker: start. PID=".$worker->pid."\n"; + //recv data from master + while(true) + { + $recv = $worker->pop(); + echo "From Master: $recv\n"; + } + + sleep(2); + $worker->exit(0); +} + +$process = new swoole_process('callback_function', false, false); +$process->useQueue(ftok(__FILE__, 1), 2 | swoole_process::IPC_NOWAIT); + +$send_bytes = 0; +foreach(range(1, 10) as $i) +{ + $data = str_repeat('A', 65535); +// $data = "hello worker[$i]\n"; + $send_bytes += strlen($data); + $process->push($data); +} + +$recv_bytes = 0; +$r_data = true; +while($r_data) +{ + $r_data = $process->pop(); + $recv_bytes += $r_data; +} +echo "send={$send_bytes}, recv=$recv_bytes\n"; +var_dump($process->statQueue()); diff --git a/vendor/swoole/examples/process/msgqueue_client.php b/vendor/swoole/examples/process/msgqueue_client.php new file mode 100755 index 0000000..bb8f77a --- /dev/null +++ b/vendor/swoole/examples/process/msgqueue_client.php @@ -0,0 +1,14 @@ +<?php +$mq = new Swoole\MsgQueue(0x7000001); +for ($i = 0; $i < 1000; $i++) +{ + if ($i % 100 == 99) + { + var_dump($mq->stats()); + } + elseif ($i % 300 == 299) + { + sleep(1); + } + $mq->push("hello $i"); +} diff --git a/vendor/swoole/examples/process/msgqueue_pool.php b/vendor/swoole/examples/process/msgqueue_pool.php new file mode 100755 index 0000000..32be7ce --- /dev/null +++ b/vendor/swoole/examples/process/msgqueue_pool.php @@ -0,0 +1,16 @@ +<?php +$pool = new Swoole\Process\Pool(2, SWOOLE_IPC_MSGQUEUE, 0x7000001); + +$pool->on("Message", function ($pool, $message) { + echo "Message: {$message}\n"; +}); + +$pool->on("WorkerStart", function ($pool, $workerId) { + echo "Worker#{$workerId} is started\n"; +}); + +$pool->on("WorkerStop", function ($pool, $workerId) { + echo "Worker#{$workerId} is stopped\n"; +}); + +$pool->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/process/pool_socket.php b/vendor/swoole/examples/process/pool_socket.php new file mode 100755 index 0000000..4ba49f6 --- /dev/null +++ b/vendor/swoole/examples/process/pool_socket.php @@ -0,0 +1,13 @@ +<?php +$pool = new Swoole\Process\Pool(2, SWOOLE_IPC_SOCKET); + +$pool->on("Message", function ($pool, $message) { + echo "Message: {$message}\n"; + $pool->write("hello "); + $pool->write("world "); + $pool->write("\n"); +}); + +$pool->listen('127.0.0.1', 8089); + +$pool->start(); diff --git a/vendor/swoole/examples/process/python.php b/vendor/swoole/examples/process/python.php new file mode 100755 index 0000000..5ba6348 --- /dev/null +++ b/vendor/swoole/examples/process/python.php @@ -0,0 +1,15 @@ +<?php +$process = new swoole_process('pyhon_process', true); +$pid = $process->start(); + +function pyhon_process(swoole_process $worker) +{ + $worker->exec('/usr/bin/python', array("echo.py")); +} + +$process->write("hello world\n"); +echo $process->read(); + +$ret = swoole_process::wait(); +var_dump($ret); + diff --git a/vendor/swoole/examples/process/select.php b/vendor/swoole/examples/process/select.php new file mode 100755 index 0000000..60174f3 --- /dev/null +++ b/vendor/swoole/examples/process/select.php @@ -0,0 +1,14 @@ +<?php +$process = new swoole_process(function (swoole_process $worker) +{ + echo "Worker: start. PID=" . $worker->pid . "\n"; + sleep(2); + $worker->write("hello master\n"); + $worker->exit(0); +}, false); + +$pid = $process->start(); +$r = array($process); +$ret = swoole_select($r, null, null, 1.0); +var_dump($ret); +var_dump($process->read()); diff --git a/vendor/swoole/examples/process/stdin_stdout.php b/vendor/swoole/examples/process/stdin_stdout.php new file mode 100755 index 0000000..50a7178 --- /dev/null +++ b/vendor/swoole/examples/process/stdin_stdout.php @@ -0,0 +1,4 @@ +<?php +fwrite(STDOUT, "Hello master.\n"); +fwrite(STDOUT, "Master write: ".fgets(STDIN)."\n"); + diff --git a/vendor/swoole/examples/process/test.php b/vendor/swoole/examples/process/test.php new file mode 100755 index 0000000..d01098e --- /dev/null +++ b/vendor/swoole/examples/process/test.php @@ -0,0 +1,8 @@ +<?php +swoole_process::daemon(); + +while (1) +{ + echo "hello"; + sleep(1); +} \ No newline at end of file diff --git a/vendor/swoole/examples/process/worker.php b/vendor/swoole/examples/process/worker.php new file mode 100755 index 0000000..9942f27 --- /dev/null +++ b/vendor/swoole/examples/process/worker.php @@ -0,0 +1,106 @@ +<?php +$redirect_stdout = false; +$workers = []; +$worker_num = 1; + +//swoole_process::daemon(0, 1); +for($i = 0; $i < $worker_num; $i++) +{ + $process = new swoole_process('child_async', $redirect_stdout); + $process->id = $i; + $pid = $process->start(); + $workers[$pid] = $process; + //echo "Master: new worker, PID=".$pid."\n"; +} + +master_async($workers); +//master_sync($workers); + +//异步主进程 +function master_async($workers) +{ + swoole_process::signal(SIGCHLD, function ($signo) use (&$workers) { + while(1) + { + $ret = swoole_process::wait(false); + if ($ret) + { + $pid = $ret['pid']; + $child_process = $workers[$pid]; + //unset($workers[$pid]); + echo "Worker Exit, kill_signal={$ret['signal']} PID=" . $pid . PHP_EOL; + $new_pid = $child_process->start(); + $workers[$new_pid] = $child_process; + unset($workers[$pid]); + } + else + { + break; + } + } + }); + + /** + * @var $process swoole_process + */ + foreach($workers as $pid => $process) + { + swoole_event_add($process->pipe, function($pipe) use ($process) { + $recv = $process->read(); + if ($recv) echo "From Worker: " . $recv; + $process->write("HELLO worker {$process->pid}\n"); + }); + $process->write("hello worker[$pid]\n"); + } +} + +//同步主进程 +function master_sync($workers) +{ + foreach($workers as $pid => $process) + { + $process->write("hello worker[$pid]\n"); + echo "From Worker: ".$process->read(); + } +} + +function child_sync(swoole_process $worker) +{ + //echo "Worker: start. PID=".$worker->pid."\n"; + //recv data from master + $recv = $worker->read(); + + echo "From Master: $recv\n"; + + //send data to master + $worker->write("hello master\n"); + + sleep(2); + $worker->exit(0); +} + +function child_async(swoole_process $worker) +{ + //echo "Worker: start. PID=".$worker->pid."\n"; + //recv data from master + $GLOBALS['worker'] = $worker; + global $argv; + $worker->name("{$argv[0]}: worker #".$worker->id); + + swoole_process::signal(SIGTERM, function($signal_num) use ($worker) { + echo "signal call = $signal_num, #{$worker->pid}\n"; + }); + +// swoole_timer_tick(2000, function () use ($worker) +// { +// if (rand(1, 3) % 2) { +// $worker->write("hello master {$worker->pid}\n"); +// } +// }); + + swoole_event_add($worker->pipe, function($pipe) use($worker) { + $recv = $worker->read(); + echo "From Master: $recv\n"; + //$worker->write("hello master\n"); + }); +} diff --git a/vendor/swoole/examples/proxy_sync.php b/vendor/swoole/examples/proxy_sync.php new file mode 100755 index 0000000..6b718d6 --- /dev/null +++ b/vendor/swoole/examples/proxy_sync.php @@ -0,0 +1,66 @@ +<?php +class ProxyServer +{ + protected $clients; + protected $backends; + protected $serv; + + function run() + { + $serv = new swoole_server("127.0.0.1", 9509); + $serv->set(array( + 'timeout' => 1, //select and epoll_wait timeout. + 'poll_thread_num' => 1, //reactor thread num + 'worker_num' => 32, //reactor thread num + 'backlog' => 128, //listen backlog + 'max_conn' => 10000, + 'dispatch_mode' => 2, + //'open_tcp_keepalive' => 1, + //'log_file' => '/tmp/swoole.log', //swoole error log + )); + $serv->on('WorkerStart', array($this, 'onStart')); + $serv->on('Connect', array($this, 'onConnect')); + $serv->on('Receive', array($this, 'onReceive')); + $serv->on('Close', array($this, 'onClose')); + $serv->on('WorkerStop', array($this, 'onShutdown')); + //swoole_server_addtimer($serv, 2); + #swoole_server_addtimer($serv, 10); + $serv->start(); + } + + function onStart($serv) + { + $this->serv = $serv; + echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n"; + } + + function onShutdown($serv) + { + echo "Server: onShutdown\n"; + } + + function onClose($serv, $fd, $from_id) + { + + } + + function onConnect($serv, $fd, $from_id) + { + + } + + function onReceive($serv, $fd, $from_id, $data) + { + $socket = new swoole_client(SWOOLE_SOCK_TCP); + if($socket->connect('127.0.0.1', 80, 0.5)) + { + $socket->send($data); + $serv->send($fd, $socket->recv(8192, 0)); + } + unset($socket); + $serv->close($fd); + } +} + +$serv = new ProxyServer(); +$serv->run(); diff --git a/vendor/swoole/examples/recv_1m_client.php b/vendor/swoole/examples/recv_1m_client.php new file mode 100755 index 0000000..9d8a960 --- /dev/null +++ b/vendor/swoole/examples/recv_1m_client.php @@ -0,0 +1,27 @@ +<?php +$c = new swoole_client(SWOOLE_TCP); +$f = fopen('data.log', 'w'); +$c->connect('127.0.0.1', 9509, 60); +$c->send("AAAAAAAAAAAAAAAA"); + +$n_bytes = 0; + +while (true) +{ + $line = $c->recv(); + if ($line === false) + { + echo "recv failed.\n"; + break; + } + elseif (empty($line)) + { + echo "recv $n_bytes bytes\n"; + break; + } + else + { + fwrite($f, $line); + $n_bytes += strlen($line); + } +} diff --git a/vendor/swoole/examples/recv_file.php b/vendor/swoole/examples/recv_file.php new file mode 100755 index 0000000..717ba2a --- /dev/null +++ b/vendor/swoole/examples/recv_file.php @@ -0,0 +1,45 @@ +<?php +if (empty($argv[1])) +{ + $server_ip = '127.0.0.1'; +} +else +{ + $server_ip = $argv[1]; +} +$cli = new swoole_client(SWOOLE_TCP); +$start_ms = microtime(true); +$cli->connect($server_ip, 9501, 5); +$filesize = intval($cli->recv()); +if ($filesize == 0) +{ + die("get file size failed.\n"); +} +echo "file_size = $filesize\n"; +$content = ''; +$cli->send("get file"); + +$use_waitall = false; + +if ($use_waitall) +{ + //waitall,需要一次性分配内存,适合小一点的文件 + $content = $cli->recv($filesize, true); +} +else +{ + //循环接收,适合大型文件 + while(1) + { + //超大文件接收,这里需要改成分段写磁盘 + $content .= $cli->recv(); + if (strlen($content) == $filesize) + { + break; + } + } +} +file_put_contents(__DIR__."/recv_file_".time().".jpg", $content); +echo "recv ".strlen($content)." byte data\n"; +echo "used ".((microtime(true) - $start_ms)*1000)."ms\n"; +$cli->close(); diff --git a/vendor/swoole/examples/redis/client.php b/vendor/swoole/examples/redis/client.php new file mode 100755 index 0000000..b02209b --- /dev/null +++ b/vendor/swoole/examples/redis/client.php @@ -0,0 +1,15 @@ +<?php +$client = new swoole_redis; +$client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) { + echo "connect\n"; + $client->set('key', 'swoole', function (swoole_redis $client, $result) { + echo "set key OK\n"; + $client->get('key', function (swoole_redis $client, $result) { + var_dump($result); + $client->keys('*', function (swoole_redis $client, $result) { + var_dump($result); + $client->close(); + }); + }); + }); +}); diff --git a/vendor/swoole/examples/redis/predis.php b/vendor/swoole/examples/redis/predis.php new file mode 100755 index 0000000..573d1a1 --- /dev/null +++ b/vendor/swoole/examples/redis/predis.php @@ -0,0 +1,4 @@ +<?php +$redis = new redis; +$redis->connect('127.0.0.1', 6379); +var_dump($redis->ping()); diff --git a/vendor/swoole/examples/redis/server.php b/vendor/swoole/examples/redis/server.php new file mode 100755 index 0000000..68499b1 --- /dev/null +++ b/vendor/swoole/examples/redis/server.php @@ -0,0 +1,124 @@ +<?php +use Swoole\Redis\Server; + +define('DB_FILE', '/tmp/redis.data'); + +$server = new Server("127.0.0.1", 9501, SWOOLE_BASE); + +if (is_file(DB_FILE)) +{ + $server->data = unserialize(file_get_contents(DB_FILE)); +} +else +{ + $server->data = array(); +} + +$server->setHandler('GET', function ($fd, $data) use ($server) { + if (count($data) == 0) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'GET' command"); + } + + $key = $data[0]; + if (empty($server->data[$key])) + { + return Server::format(Server::NIL); + } + else + { + return Server::format(Server::STRING, $server->data[$key]); + } +}); + +$server->setHandler('SET', function ($fd, $data) use ($server) { + if (count($data) < 2) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'SET' command"); + } + + $key = $data[0]; + $server->data[$key] = $data[1]; + return Server::format(Server::STATUS, 'OK'); +}); + +$server->setHandler('sAdd', function ($fd, $data) use ($server) { + + if (count($data) < 2) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'sAdd' command"); + } + + $key = $data[0]; + if (!isset($server->data[$key])) + { + $array[$key] = array(); + } + + $count = 0; + for($i = 1; $i < count($data); $i++) + { + $value = $data[$i]; + if (!isset($server->data[$key][$value])) + { + $server->data[$key][$value] = 1; + $count ++; + } + } + + return Server::format(Server::INT, $count); +}); + +$server->setHandler('sMembers', function ($fd, $data) use ($server) { + if (count($data) < 1) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'sMembers' command"); + } + $key = $data[0]; + if (!isset($server->data[$key])) + { + return Server::format(Server::NIL); + } + return Server::format(Server::SET, array_keys($server->data[$key])); +}); + +$server->setHandler('hSet', function ($fd, $data) use ($server) { + + if (count($data) < 3) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'hSet' command"); + } + + $key = $data[0]; + if (!isset($server->data[$key])) + { + $array[$key] = array(); + } + $field = $data[1]; + $value = $data[2]; + $count = !isset($server->data[$key][$field]) ? 1 : 0; + $server->data[$key][$field] = $value; + return Server::format(Server::INT, $count); +}); + +$server->setHandler('hGetAll', function ($fd, $data) use ($server) { + if (count($data) < 1) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'hGetAll' command"); + } + $key = $data[0]; + if (!isset($server->data[$key])) + { + return Server::format(Server::NIL); + } + return Server::format(Server::MAP, $server->data[$key]); +}); + +$server->on('WorkerStart', function ($server) { + $server->tick(10000, function() use ($server) { + file_put_contents(DB_FILE, serialize($server->data)); + }); +}); + +$server->start(); + diff --git a/vendor/swoole/examples/redis/subscribe.php b/vendor/swoole/examples/redis/subscribe.php new file mode 100755 index 0000000..7f16dd3 --- /dev/null +++ b/vendor/swoole/examples/redis/subscribe.php @@ -0,0 +1,19 @@ +<?php +$client = new swoole_redis; + +$client->on('message', function (swoole_redis $client, $result) { + var_dump($result); + static $more = false; + if (!$more and $result[0] == 'message') + { + echo "subscribe new channel\n"; + $client->subscribe('msg_1', 'msg_2'); + $client->unsubscribe('msg_0'); + $more = true; + } +}); + +$client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) { + echo "connect\n"; + $client->subscribe('msg_0'); +}); diff --git a/vendor/swoole/examples/redis_pool.php b/vendor/swoole/examples/redis_pool.php new file mode 100755 index 0000000..d7d5d13 --- /dev/null +++ b/vendor/swoole/examples/redis_pool.php @@ -0,0 +1,92 @@ +<?php + +#This script is forked from db_pool.php +# +#u can test like this, +# +#/usr/local/php/bin/php bench.php -n 1000 -c 100 -s tcp://127.0.0.1:9508 -f short_tcp / long_tcp +# +# + +define("SERVER_RELOAD", 'U0VSVkVSX1JFTE9BRAo='); + +if(!extension_loaded('swoole')){ + throw new Exception("install swoole extension, pecl install swoole"); +} + +if(!extension_loaded('redis')) { + throw new Exception("install redis extension, pecl install redis"); +} + +$serv = new swoole_server("0.0.0.0", 9508); + +$serv->set(array( + 'worker_num' => 4,//base on you cpu nums + 'task_worker_num' => 4,//better equal to worker_num, anyway you can define your own + 'heartbeat_check_interval' => 5, + 'heartbeat_idle_time' => 5, + 'open_cpu_affinity' => 1, + 'open_eof_check' => 1, + 'package_eof' => "\r\n\r\n", + 'package_max_length' => 1024 * 16, + //'daemonize' => 1 +)); + +function onStart($serv) { + echo "MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}\n"; + echo "Server: start.Swoole version is [".SWOOLE_VERSION."]\n"; +} + +function onReceive($serv, $fd, $from_id, $key) +{ + $key = trim($key); + if($key === SERVER_RELOAD) { // check if this is a reload cmd + $ret = $serv->reload($serv); + ($ret === true) ? $serv->send($fd, "reload success\n") : $serv->send($fd, "reload fail\n"); + }else { + $result = $serv->taskwait($key); + if ($result !== false) { + list($status, $data) = explode(':', $result, 2); + if ($status == 'OK') { + $serv->send($fd, $key . " : " . var_export(unserialize($data), true) . "\n"); + } else { + $serv->send($fd, $data); + } + return; + } else { + $serv->send($fd, "Error. Task timeout\n"); + } + } +} + +function onTask($serv, $task_id, $from_id, $key) +{ + static $redis = null; + if ($redis == null) { + $redis = new Redis(); + $redis->pconnect("127.0.0.1", 6379); + if (!$redis) { + $redis = null; + $serv->finish("ER: Init Redis Fail."); + return; + } + } + $data = $redis->get($key); + if ($data === false) { + $serv->finish("ER: Get Data Fail."); + return; + } + $serv->finish("OK:" . serialize($data)); +} + +function onFinish($serv, $data) +{ + echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL; +} + +$serv->on('Start', 'onStart'); +$serv->on('Receive', 'onReceive'); +$serv->on('Task', 'onTask'); +$serv->on('Finish', 'onFinish'); +$serv->start(); + diff --git a/vendor/swoole/examples/reflection_test.php b/vendor/swoole/examples/reflection_test.php new file mode 100755 index 0000000..1f3b8f5 --- /dev/null +++ b/vendor/swoole/examples/reflection_test.php @@ -0,0 +1,13 @@ +<?php + +$Ref_swoole_server = new ReflectionClass('swoole_server'); +$methods = $Ref_swoole_server->getMethods(); +foreach($methods as $method) { + echo "----------------------------------------" .PHP_EOL; + echo "method name : " . $method->name . PHP_EOL; + echo "----------------------------------------" . PHP_EOL; + $method = $Ref_swoole_server->getMethod($method->name); + $params = $method->getParameters(); + print_r($params); +} + diff --git a/vendor/swoole/examples/ringqueue.php b/vendor/swoole/examples/ringqueue.php new file mode 100755 index 0000000..0a1c95d --- /dev/null +++ b/vendor/swoole/examples/ringqueue.php @@ -0,0 +1,14 @@ +<?php +$q = new Swoole\RingQueue(10); + +for ($i = 0; $i < 12; $i++) +{ + $ret = $q->push("hello_" . $i); + var_dump($ret, $q->isFull(), $q->count()); +} + +for ($i = 0; $i < 12; $i++) +{ + $ret = $q->pop(); + var_dump($ret, $q->isEmpty(), $q->count()); +} \ No newline at end of file diff --git a/vendor/swoole/examples/runtime/strictmode.php b/vendor/swoole/examples/runtime/strictmode.php new file mode 100755 index 0000000..1f5f544 --- /dev/null +++ b/vendor/swoole/examples/runtime/strictmode.php @@ -0,0 +1,6 @@ +<?php +sleep(1); +echo "sleep 1\n"; +Swoole\Runtime::enableStrictMode(); +sleep(1); +echo "sleep 2\n"; diff --git a/vendor/swoole/examples/send_1m_svr.php b/vendor/swoole/examples/send_1m_svr.php new file mode 100755 index 0000000..a746d5b --- /dev/null +++ b/vendor/swoole/examples/send_1m_svr.php @@ -0,0 +1,31 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9509); +$serv->set(array('worker_num' => 1)); +$serv->on('workerStart', function($serv, $worker_id) { + //if($worker_id == 0) $serv->addtimer(500); +}); +$serv->on('connect', function ($serv, $fd, $from_id){ + $serv->array['fd'] = &strval($fd); + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; +}); +$serv->on('receive', function ($serv, $fd, $from_id, $data) { + //echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + $array = array('A', 'B', 'C', 'D', 'E', 'F', 'G'); + $data = ''; + $n_bytes = 0; + for ($i = 0; $i < 10; $i++) + { + $_str = str_repeat($array[$i % 7], 4030) . "\n"; + //$serv->send($fd, $_str); + $n_bytes += strlen($_str); + $data .= $_str; + } + echo "send " . $n_bytes . " bytes\n"; + $serv->send( $serv->array['fd'], $data); + $serv->close($fd); +}); +$serv->on('close', function ($serv, $fd, $from_id) { + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); +$serv->start(); + diff --git a/vendor/swoole/examples/sendfile_server.php b/vendor/swoole/examples/sendfile_server.php new file mode 100755 index 0000000..c00681d --- /dev/null +++ b/vendor/swoole/examples/sendfile_server.php @@ -0,0 +1,25 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501, SWOOLE_BASE); +$serv->set(array( + 'worker_num' => 1, +)); +$serv->on('timer', function($serv, $interval) { + echo "onTimer: $interval\n"; +}); +$serv->on('workerStart', function($serv, $worker_id) { + //if($worker_id == 0) $serv->addtimer(300); +}); +$serv->on('connect', function (swoole_server $serv, $fd){ + $serv->send($fd, filesize(__DIR__.'/test.jpg')); + //echo "Client:Connect.\n"; +}); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + echo "Client[$fd]: $data\n"; + $serv->sendfile($fd, __DIR__.'/test.jpg'); + //$serv->close($fd); +}); +$serv->on('close', function ($serv, $fd) { + //echo "Client: Close.\n"; +}); +$serv->start(); + diff --git a/vendor/swoole/examples/serialize.php b/vendor/swoole/examples/serialize.php new file mode 100755 index 0000000..e0c3a9e --- /dev/null +++ b/vendor/swoole/examples/serialize.php @@ -0,0 +1,17 @@ +<?php +//only use in php7+ + +$arr = array( + 1111111111111 + + ); +$obj = new \Swoole\Serialize(); +$ser = $obj->pack($arr); + + +$ser2 = $obj->pack($arr,SWOOLE_FAST_PACK); + +var_dump($obj->unpack($ser)); +var_dump($obj->unpack($ser2)); + +?> diff --git a/vendor/swoole/examples/serialize2.php b/vendor/swoole/examples/serialize2.php new file mode 100755 index 0000000..3ee95c2 --- /dev/null +++ b/vendor/swoole/examples/serialize2.php @@ -0,0 +1,30 @@ +<?php +//only use in php7+ + +class myTestObject { + public $test = "test"; + public $sub = ""; +} + +class mySubObject { + public $sub = "sub"; + public $default = ""; +} +$arr = new myTestObject(); +$arr->sub = new mySubObject(); +$arr->sub->default = new stdclass(); +$obj = new \Swoole\Serialize(); +$ser = $obj->pack($arr); + + +$ser2 = $obj->pack($arr,SWOOLE_FAST_PACK); + +var_dump($obj->unpack($ser)); +var_dump($obj->unpack($ser2)); +var_dump($obj->unpack($ser, UNSERIALIZE_OBJECT_TO_STDCLASS)); +var_dump($obj->unpack($ser2, UNSERIALIZE_OBJECT_TO_STDCLASS)); +var_dump(UNSERIALIZE_OBJECT_TO_ARRAY); +var_dump(UNSERIALIZE_OBJECT_TO_STDCLASS); +var_dump(get_class($obj->unpack($ser, UNSERIALIZE_OBJECT_TO_STDCLASS))); + +?> diff --git a/vendor/swoole/examples/server.c b/vendor/swoole/examples/server.c new file mode 100755 index 0000000..2d075e2 --- /dev/null +++ b/vendor/swoole/examples/server.c @@ -0,0 +1,147 @@ +/** +* gcc -o server server.c -lswoole +*/ +#include <swoole/Server.h> +#include <swoole/swoole.h> +#include <swoole/Client.h> + +int my_onReceive(swFactory *factory, swEventData *req); +void my_onStart(swServer *serv); +void my_onShutdown(swServer *serv); +void my_onConnect(swServer *serv, int fd, int from_id); +void my_onClose(swServer *serv, int fd, int from_id); +void my_onTimer(swServer *serv, int interval); +void my_onWorkerStart(swServer *serv, int worker_id); +void my_onWorkerStop(swServer *serv, int worker_id); + +char* php_rtrim(char *str, int len) +{ + int i; + for (i = len; i > 0; i--) + { + switch(str[i]) + { + case ' ': + case '\0': + case '\n': + case '\r': + case '\t': + case '\v': + str[i] = 0; + break; + default: + return str; + } + } + return str; +} + + +int main(int argc, char **argv) +{ + int ret; + + swServer serv; + swServer_init(&serv); //初始化 + + //config + serv.reactor_num = 2; //reactor线程数量 + serv.worker_num = 4; //worker进程数量 + + serv.factory_mode = SW_MODE_PROCESS; //SW_MODE_PROCESS SW_MODE_THREAD SW_MODE_BASE + serv.max_connection = 100000; + //serv.open_cpu_affinity = 1; + //serv.open_tcp_nodelay = 1; + //serv.daemonize = 1; + //serv.open_eof_check = 1; + + //create Server + ret = swServer_create(&serv); + if (ret < 0) + { + swTrace("create server fail[error=%d].\n", ret); + exit(0); + } + + //swServer_addListen(&serv, SW_SOCK_UDP, "127.0.0.1", 9500); + swListenPort *port = swServer_add_port(&serv, SW_SOCK_TCP, "127.0.0.1", 9501); + //swServer_addListen(&serv, SW_SOCK_UDP, "127.0.0.1", 9502); + //swServer_addListen(&serv, SW_SOCK_UDP, "127.0.0.1", 8888); + port->backlog = 128; + + serv.onStart = my_onStart; + serv.onShutdown = my_onShutdown; + serv.onConnect = my_onConnect; + serv.onReceive = my_onReceive; + serv.onClose = my_onClose; + serv.onWorkerStart = my_onWorkerStart; + serv.onWorkerStop = my_onWorkerStop; + + ret = swServer_start(&serv); + if (ret < 0) + { + swTrace("start server fail[error=%d].\n", ret); + exit(0); + } + return 0; +} + + +void my_onWorkerStart(swServer *serv, int worker_id) +{ + printf("Worker[%d]PID=%d start\n", worker_id, getpid()); +} + +void my_onWorkerStop(swServer *serv, int worker_id) +{ + printf("Worker[%d]PID=%d stop\n", worker_id, getpid()); +} + +void my_onTimer(swServer *serv, int interval) +{ + printf("Timer Interval=[%d]\n", interval); +} + +static int receive_count = 0; + +int my_onReceive(swServer *serv, swEventData *req) +{ + int ret; + char resp_data[SW_BUFFER_SIZE]; + swSendData resp; + receive_count ++; + resp.info.fd = req->info.fd; //fd can be not source fd. + resp.info.len = req->info.len + 8; + resp.info.from_id = req->info.from_id; + req->data[req->info.len] = 0; + + snprintf(resp_data, resp.info.len, "Server:%s", req->data); + resp.data = resp_data; + ret = serv->send(serv, &resp); + if (ret < 0) + { + printf("send to client fail.errno=%d\n", errno); + } + printf("onReceive[%d]: Data=%s|Len=%d\n",receive_count, php_rtrim(req->data, req->info.len), req->info.len); + return SW_OK; +} + +void my_onStart(swServer *serv) +{ + printf("Server is running\n"); +} + +void my_onShutdown(swServer *serv) +{ + printf("Server is shutdown\n"); +} + +void my_onConnect(swServer *serv, int fd, int from_id) +{ + printf("PID=%d\tConnect fd=%d|from_id=%d\n", getpid(), fd, from_id); +} + +void my_onClose(swServer *serv, int fd, int from_id) +{ + printf("PID=%d\tClose fd=%d|from_id=%d\n", getpid(), fd, from_id); +} diff --git a/vendor/swoole/examples/server.php b/vendor/swoole/examples/server.php new file mode 100755 index 0000000..b6ab08d --- /dev/null +++ b/vendor/swoole/examples/server.php @@ -0,0 +1,582 @@ +<?php +class G +{ + static $index = 0; + static $serv; + static $config = array( + //'reactor_num' => 16, // 线程数. 一般设置为CPU核数的1-4倍 + 'worker_num' => 2, // 工作进程数量. 设置为CPU的1-4倍最合理 + 'max_request' => 1000, // 防止 PHP 内存溢出, 一个工作进程处理 X 次任务后自动重启 (注: 0,不自动重启) + 'max_conn' => 10000, // 最大连接数 + 'task_worker_num' => 1, // 任务工作进程数量 +// 'task_ipc_mode' => 2, // 设置 Task 进程与 Worker 进程之间通信的方式。 + 'task_max_request' => 0, // 防止 PHP 内存溢出 + //'task_tmpdir' => '/tmp', + //'message_queue_key' => ftok(SYS_ROOT . 'queue.msg', 1), + 'dispatch_mode' => 2, + //'daemonize' => 1, // 设置守护进程模式 + 'backlog' => 128, + //'log_file' => '/data/logs/swoole.log', + 'heartbeat_check_interval' => 10, // 心跳检测间隔时长(秒) + 'heartbeat_idle_time' => 20, // 连接最大允许空闲的时间 + //'open_eof_check' => 1, + //'open_eof_split' => 1, + //'package_eof' => "\r\r\n", + //'open_cpu_affinity' => 1, + 'socket_buffer_size' => 1024 * 1024 * 128, + 'buffer_output_size' => 1024 * 1024 * 2, + 'enable_delay_receive' => true, + //'cpu_affinity_ignore' =>array(0,1)//如果你的网卡2个队列(或者没有多队列那么默认是cpu0来处理中断),并且绑定了core 0和core 1,那么可以通过这个设置避免swoole的线程或者进程绑定到这2个core,防止cpu0,1被耗光而造成的丢包 + ); + + private static $buffers = array(); + + /** + * @param $fd + * @return swoole_buffer + */ + static function getBuffer($fd, $create = true) + { + if (!isset(self::$buffers[$fd])) + { + if (!$create) + { + return false; + } + self::$buffers[$fd] = new swoole_buffer(1024 * 128); + } + return self::$buffers[$fd]; + } +} + +if (isset($argv[1]) and $argv[1] == 'daemon') { + G::$config['daemonize'] = true; +} else { + G::$config['daemonize'] = false; +} + +//$mode = SWOOLE_BASE; +$mode = SWOOLE_PROCESS; + +$serv = new swoole_server("0.0.0.0", 9501, $mode, SWOOLE_SOCK_TCP); +$serv->listen('0.0.0.0', 9502, SWOOLE_SOCK_UDP); +$serv->listen('::', 9503, SWOOLE_SOCK_TCP6); +$serv->listen('::', 9504, SWOOLE_SOCK_UDP6); +$process1 = new swoole_process(function ($worker) use ($serv) { + global $argv; + swoole_set_process_name("php {$argv[0]}: my_process1"); + swoole_timer_tick(2000, function ($interval) use ($worker, $serv) { + echo "#{$worker->pid} child process timer $interval\n"; // 如果worker中没有定时器,则会输出 process timer xxx + foreach ($serv->connections as $conn) + { + $serv->send($conn, "heartbeat\n"); + } + }); + swoole_timer_tick(5000, function () use ($serv) + { + $serv->sendMessage("hello event worker", 0); + $serv->sendMessage("hello task worker", 4); + }); +}, false); + +//$serv->addprocess($process1); + +$process2 = new swoole_process(function ($worker) use ($serv) { + global $argv; + swoole_set_process_name("php {$argv[0]}: my_process2"); + swoole_timer_tick(2000, function ($interval) use ($worker, $serv) { + echo "#{$worker->pid} child process timer $interval\n"; // 如果worker中没有定时器,则会输出 process timer xxx + }); +}, false); + +//$serv->addprocess($process2); +$serv->set(G::$config); +$serv->set(['reactor_num' => 4]); + +/** + * 使用类的静态属性,可以直接访问 + */ +G::$serv = $serv; + +function my_onStart(swoole_server $serv) +{ + global $argv; + swoole_set_process_name("php {$argv[0]}: master"); + my_log("Server: start.Swoole version is [".SWOOLE_VERSION."]"); + my_log("MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}"); +} + +function my_log($msg) +{ + global $serv; + if (empty($serv->worker_pid)) + { + $serv->worker_pid = posix_getpid(); + } + echo "#".$serv->worker_pid."\t[".date('H:i:s')."]\t".$msg.PHP_EOL; +} + +function forkChildInWorker() { + global $serv; + echo "on worker start\n"; + $process = new swoole_process( function (swoole_process $worker) use ($serv) { +// $serv = new swoole_server( "0.0.0.0", 9503 ); +// $serv->set(array( +// 'worker_num' => 1 +// )); +// $serv->on ( 'receive', function (swoole_server $serv, $fd, $from_id, $data) { +// $serv->send ( $fd, "Swoole: " . $data ); +// $serv->close ( $fd ); +// }); +// $serv->start (); +// swoole_event_add ($worker->pipe, function ($pipe) use ($worker) { +// echo $worker->read()."\n"; +// }); + }); + + $pid = $process->start(); + echo "Fork child process success. pid={$pid}\n"; + //保存子进程对象,这里如果不保存,那对象会被销毁,管道也会被关闭 + $serv->childprocess = $process; +} + +function processRename(swoole_server $serv, $worker_id) { + + global $argv; + if ( $serv->taskworker) + { + swoole_set_process_name("php {$argv[0]}: task"); + } + else + { + swoole_set_process_name("php {$argv[0]}: worker"); + } +// if ($worker_id == 0) +// { +// var_dump($serv->setting); +// } + my_log("WorkerStart: MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}|WorkerId={$serv->worker_id}|WorkerPid={$serv->worker_pid}"); +} + +function setTimerInWorker(swoole_server $serv, $worker_id) { + + if ($worker_id == 0) { + echo "Start: ".microtime(true)."\n"; + //$serv->addtimer(3000); +// $serv->addtimer(7000); + //var_dump($serv->gettimer()); + } +// $serv->after(2000, function(){ +// echo "Timeout: ".microtime(true)."\n"; +// }); +// $serv->after(5000, function(){ +// echo "Timeout: ".microtime(true)."\n"; +// global $serv; +// $serv->deltimer(3000); +// }); +} + +function my_onShutdown($serv) +{ + echo "Server: onShutdown\n"; +} + +function my_onClose(swoole_server $serv, $fd, $from_id) +{ + my_log("Client[$fd@$from_id]: fd=$fd is closed"); + $buffer = G::getBuffer($fd); + if ($buffer) + { + $buffer->clear(); + } + //var_dump($serv->getClientInfo($fd)); +} + +function my_onConnect(swoole_server $serv, $fd, $from_id) +{ + //throw new Exception("hello world"); +// var_dump($serv->connection_info($fd)); + //var_dump($serv, $fd, $from_id); +// echo "Worker#{$serv->worker_pid} Client[$fd@$from_id]: Connect.\n"; + $serv->after(2000, function() use ($serv, $fd) { + $serv->confirm($fd); + }); + my_log("Client: Connect --- {$fd}"); +} + +function timer_show($id) +{ + my_log("Timer#$id"); +} + +function my_onWorkerExit(swoole_server $serv, $worker_id) { + $redisState = $serv->redis->getState(); + global $argv; + if ($redisState == Swoole\Redis::STATE_READY or $redisState == Swoole\Redis::STATE_SUBSCRIBE) + { + swoole_set_process_name("php {$argv[0]}: worker shutting down"); + echo "exit\n"; + //$serv->redis->close(); + } +} + +function my_onWorkerStart(swoole_server $serv, $worker_id) +{ + processRename($serv, $worker_id); + + if (!$serv->taskworker) + { + swoole_process::signal(SIGUSR2, function($signo){ + echo "SIGNAL: $signo\n"; + }); + $serv->defer(function(){ + echo "defer call\n"; + }); +// $serv->tick(2000, function() use ($serv) { +// echo "Worker-{$serv->worker_id} tick-2000\n"; +// }); + + $redis = new Swoole\Redis(); + $redis->connect("127.0.0.1", 6379, function ($redis, $r) { + $redis->get("key", function ($redis, $r) { + var_dump($r); + }); + }); + $serv->redis = $redis; + } + else + { +// swoole_timer_after(2000, function() { +// echo "after 2 secends.\n"; +// }); +// $serv->tick(1000, function ($id) use ($serv) { +// if (G::$index > 10) { +// $serv->after(2500, 'timer_show', 2); +// G::$index = 0; +// } else { +// G::$index++; +// } +// timer_show($id); +// }); + } + //forkChildInWorker(); +// setTimerInWorker($serv, $worker_id); +} + +function my_onWorkerStop($serv, $worker_id) +{ + echo "WorkerStop[$worker_id]|pid=".$serv->worker_pid.".\n"; +} + +function my_onPacket($serv, $data, $clientInfo) +{ + $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server " . $data); + var_dump($clientInfo); +} + +function my_onReceive(swoole_server $serv, $fd, $from_id, $data) +{ + my_log("Worker#{$serv->worker_pid} Client[$fd@$from_id]: received: $data"); + $cmd = trim($data); + if($cmd == "reload") + { + $serv->reload(); + } + elseif($cmd == "task") + { + $task_id = $serv->task("task ".$fd); + echo "Dispath AsyncTask: id=$task_id\n"; + } + elseif ($cmd == "taskclose") + { + $serv->task("close " . $fd); + echo "close the connection in taskworker\n"; + } + elseif ($cmd == "tasksend") + { + $serv->task("send " . $fd); + } + elseif ($cmd == "bigtask") + { + $serv->task(str_repeat('A', 8192*5)); + } + elseif($cmd == "taskwait") + { + $result = $serv->taskwait("taskwait"); + if ($result) { + $serv->send($fd, "taskwaitok"); + } + echo "SyncTask: result=".var_export($result, true)."\n"; + } + elseif($cmd == "taskWaitMulti") + { + $result = $serv->taskWaitMulti(array( + str_repeat('A', 8192 * 5), + str_repeat('B', 8192 * 6), + str_repeat('C', 8192 * 8) + )); + if ($result) + { + $resp = "taskWaitMulti ok\n"; + foreach($result as $k => $v) + { + $resp .= "result[$k] length=".strlen($v)."\n"; + } + $serv->send($fd, $resp); + } + else + { + $serv->send($fd, "taskWaitMulti error\n"); + } + } + elseif ($cmd == "hellotask") + { + $serv->task("hellotask"); + } + elseif ($cmd == "taskcallback") + { + $serv->task("taskcallback", -1, function (swoole_server $serv, $task_id, $data) + { + echo "Task Callback: "; + var_dump($task_id, $data); + }); + } + elseif ($cmd == "sendto") + { + $serv->sendto("127.0.0.1", 9999, "hello world"); + } + elseif($cmd == "close") + { + $serv->send($fd, "close connection\n"); + $result = $serv->close($fd); + } + elseif($cmd == "info") + { + $info = $serv->connection_info(strval($fd), $from_id); + var_dump($info["remote_ip"]); + $serv->send($fd, 'Info: '.var_export($info, true).PHP_EOL); + } + elseif ($cmd == 'proxy') + { + $serv->send(1, "hello world\n"); + } + elseif ($cmd == 'sleep') + { + sleep(10); + } + elseif ($cmd == 'foreach') + { + foreach($serv->connections as $fd) + { + echo "conn : $fd\n"; + } + return; + } + elseif ($cmd == 'tick') + { + $serv->tick(2000, function ($id) { + echo "tick #$id\n"; + }); + } + elseif ($cmd == 'addtimer') + { + $serv->addtimer(3000); + } + elseif($cmd == "list") + { + $start_fd = 0; + echo "broadcast\n"; + while(true) + { + $conn_list = $serv->connection_list($start_fd, 10); + if (empty($conn_list)) + { + echo "iterates finished\n"; + break; + } + $start_fd = end($conn_list); + var_dump($conn_list); + } + } + elseif($cmd == "list2") + { + foreach($serv->connections as $con) + { + var_dump($serv->connection_info($con)); + } + } + elseif($cmd == "stats") + { + $serv_stats = $serv->stats(); + $serv->send($fd, 'Stats: '.var_export($serv_stats, true)."\ncount=".count($serv->connections).PHP_EOL); + } + elseif($cmd == "broadcast") + { + broadcast($serv, $fd, "hello from $fd\n"); + } + //这里故意调用一个不存在的函数 + elseif($cmd == "error") + { + hello_no_exists(); + } + elseif($cmd == "exit") + { + exit("worker php exit.\n"); + } + //关闭fd + elseif(substr($cmd, 0, 5) == "close") + { + $close_fd = substr($cmd, 6); + $serv->close($close_fd); + } + elseif($cmd == "shutdown") + { + $serv->shutdown(); + } + elseif($cmd == "fatalerror") + { + require __DIR__.'/php/error.php'; + } + elseif($cmd == 'sendbuffer') + { + $buffer = G::getBuffer($fd); + $buffer->append("hello\n"); + $serv->send($fd, $buffer); + } + elseif($cmd == 'defer') + { + $serv->defer(function() use ($fd, $serv) { + $serv->close($fd); + $serv->defer(function(){ + echo "deferd\n"; + }); + }); + $serv->send($fd, 'Swoole: '.$data, $from_id); + } + else + { + $serv->send($fd, 'Swoole: '.$data, $from_id); + //$serv->close($fd); + } + //echo "Client:Data. fd=$fd|from_id=$from_id|data=$data"; +// $serv->after( +// 800, function () { +// echo "hello"; +// } +// ); + //swoole_server_send($serv, $other_fd, "Server: $data", $other_from_id); +} + +function my_onTask(swoole_server $serv, $task_id, $from_id, $data) +{ + if ($data == 'taskwait') + { + $fd = str_replace('task-', '', $data); + $serv->send($fd, "hello world"); + return array("task" => 'wait'); + } + elseif ($data == 'taskcallback') + { + return array("task" => 'callback'); + } + else + { + $cmd = explode(' ', $data); + if ($cmd[0] == 'send') + { + $serv->send($cmd[1], str_repeat('A', 10000)."\n"); + } + elseif ($cmd[0] == 'close') + { + $serv->close($cmd[1]); + } + else + { + echo "bigtask: length=".strlen($data)."\n"; + return $data; + } +// $serv->sendto('127.0.0.1', 9999, "hello world"); + //swoole_timer_after(1000, "test"); +// var_dump($data); +// $serv->send($fd, str_repeat('A', 8192 * 2)); +// $serv->send($fd, str_repeat('B', 8192 * 2)); +// $serv->send($fd, str_repeat('C', 8192 * 2)); +// $serv->send($fd, str_repeat('D', 8192 * 2)); + return; + } + + if ($data == "hellotask") + { + broadcast($serv, 0, "hellotask"); + } + else + { + echo "AsyncTask[PID=".$serv->worker_pid."]: task_id=$task_id.".PHP_EOL; + //eg: test-18 + return $data; + } +} + +function my_onFinish(swoole_server $serv, $task_id, $data) +{ + list($str, $fd) = explode('-', $data); + $serv->send($fd, 'taskok'); + var_dump($str, $fd); + echo "AsyncTask Finish: result={$data}. PID=".$serv->worker_pid.PHP_EOL; +} + +function my_onWorkerError(swoole_server $serv, $worker_id, $worker_pid, $exit_code, $signo) +{ + echo "worker abnormal exit. WorkerId=$worker_id|Pid=$worker_pid|ExitCode=$exit_code|Signal=$signo\n"; +} + +function broadcast(swoole_server $serv, $fd = 0, $data = "hello") +{ + $start_fd = 0; + echo "broadcast\n"; + while(true) + { + $conn_list = $serv->connection_list($start_fd, 10); + if($conn_list === false) + { + break; + } + $start_fd = end($conn_list); + foreach($conn_list as $conn) + { + if($conn === $fd) continue; + $ret1 = $serv->send($conn, $data); + //var_dump($ret1); + //$ret2 = $serv->close($conn); + //var_dump($ret2); + } + } +} + +$serv->on('PipeMessage', function($serv, $src_worker_id, $msg) { + my_log("PipeMessage: Src={$src_worker_id},Msg=".trim($msg)); + if ($serv->taskworker) + { + $serv->sendMessage("hello user process", + $src_worker_id); + } +}); + +$serv->on('Start', 'my_onStart'); +$serv->on('Connect', 'my_onConnect'); +$serv->on('Receive', 'my_onReceive'); +$serv->on('Packet', 'my_onPacket'); +$serv->on('Close', 'my_onClose'); +$serv->on('Shutdown', 'my_onShutdown'); +$serv->on('WorkerStart', 'my_onWorkerStart'); +$serv->on('WorkerStop', 'my_onWorkerStop'); +$serv->on('Task', 'my_onTask'); +$serv->on('Finish', 'my_onFinish'); +$serv->on('WorkerError', 'my_onWorkerError'); +$serv->on('WorkerExit', 'my_onWorkerExit'); +$serv->on('ManagerStart', function($serv) { + global $argv; + swoole_set_process_name("php {$argv[0]}: manager"); +}); +$serv->start(); + diff --git a/vendor/swoole/examples/server/dispatch_func.php b/vendor/swoole/examples/server/dispatch_func.php new file mode 100755 index 0000000..4db4a52 --- /dev/null +++ b/vendor/swoole/examples/server/dispatch_func.php @@ -0,0 +1,17 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); + +$serv->set(array( + 'dispatch_func' => function ($serv, $fd, $type, $data) { + var_dump($fd, $type, $data); + return intval($data[0]); + }, +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $threadId, $data) +{ + var_dump($data); + echo "#{$serv->worker_id}>> received length=" . strlen($data) . "\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/server/dispatch_stream.php b/vendor/swoole/examples/server/dispatch_stream.php new file mode 100755 index 0000000..4e95c01 --- /dev/null +++ b/vendor/swoole/examples/server/dispatch_stream.php @@ -0,0 +1,15 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); + +$serv->set(array( + 'dispatch_mode' => 7, + 'worker_num' => 2, +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $threadId, $data) +{ + var_dump($data); + echo "#{$serv->worker_id}>> received length=" . strlen($data) . "\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/server/echo.php b/vendor/swoole/examples/server/echo.php new file mode 100755 index 0000000..4de86de --- /dev/null +++ b/vendor/swoole/examples/server/echo.php @@ -0,0 +1,25 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +//$serv->on('connect', function ($serv, $fd, $reactor_id){ +// echo "[#".posix_getpid()."]\tClient@[$fd:$reactor_id]: Connect.\n"; +//}); +$serv->set(array( + 'worker_num' => 1, + +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $reactor_id, $data) { + echo "[#".$serv->worker_id."]\tClient[$fd] receive data: $data\n"; + if ($serv->send($fd, "hello {$data}\n") == false) + { + echo "error\n"; + } + +}); + +//$serv->on('close', function ($serv, $fd, $reactor_id) { +// echo "[#".posix_getpid()."]\tClient@[$fd:$reactor_id]: Close.\n"; +//}); + +$serv->start(); + diff --git a/vendor/swoole/examples/server/exist.php b/vendor/swoole/examples/server/exist.php new file mode 100755 index 0000000..a651453 --- /dev/null +++ b/vendor/swoole/examples/server/exist.php @@ -0,0 +1,141 @@ +<?php +class G +{ + static $serv; + private static $buffers = array(); + + /** + * @param $fd + * @return swoole_buffer + */ + static function getBuffer($fd, $create = true) + { + if (!isset(self::$buffers[$fd])) + { + if (!$create) + { + return false; + } + self::$buffers[$fd] = new swoole_buffer(1024 * 128); + } + return self::$buffers[$fd]; + } +} + +$config = array( + //'worker_num' => 4, + //'open_eof_check' => true, + //'package_eof' => "\r\n", +// 'task_ipc_mode' => 2, + 'task_worker_num' => 2, + 'user' => 'www', + 'group' => 'www', + 'chroot' => '/opt/tmp', + //'task_ipc_mode' => 1, + //'dispatch_mode' => 1, + //'log_file' => '/tmp/swoole.log', + 'heartbeat_check_interval' => 300, + 'heartbeat_idle_time' => 300, + // open_cpu_affinity => 1, + //'cpu_affinity_ignore' =>array(0,1)//如果你的网卡2个队列(或者没有多队列那么默认是cpu0来处理中断),并且绑定了core 0和core 1,那么可以通过这个设置避免swoole的线程或者进程绑定到这2个core,防止cpu0,1被耗光而造成的丢包 +); + +if (isset($argv[1]) and $argv[1] == 'daemon') { + $config['daemonize'] = true; +} else { + $config['daemonize'] = false; +} + +//$mode = SWOOLE_BASE; +$mode = SWOOLE_PROCESS; + +$serv = new swoole_server("0.0.0.0", 9501, $mode); +$serv->set($config); +/** + * 使用类的静态属性,可以直接访问 + */ +G::$serv = $serv; + +function my_onStart(swoole_server $serv) +{ + global $argv; + swoole_set_process_name("php {$argv[0]}: master"); + echo "MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}\n"; + echo "Server: start.Swoole version is [".SWOOLE_VERSION."]\n"; +} + +function my_log($msg) +{ + echo $msg.PHP_EOL; +} + +function my_onShutdown($serv) +{ + echo "Server: onShutdown\n"; +} + +function my_onClose($serv, $fd, $from_id) +{ + my_log("Worker#{$serv->worker_pid} Client[$fd@$from_id]: fd=$fd is closed"); + $buffer = G::getBuffer($fd); + if ($buffer) + { + $buffer->clear(); + } + if($serv->exist($fd)) { + echo 'FD[' . $fd . '] exist' . PHP_EOL; + } else { + echo 'FD[' . $fd . '] not exist' . PHP_EOL; + } +} + +function my_onConnect(swoole_server $serv, $fd, $from_id) +{ + if($serv->exist($fd)) { + echo 'FD[' . $fd . '] exist' . PHP_EOL; + } else { + echo 'FD[' . $fd . '] not exist' . PHP_EOL; + } +} + +function my_onReceive(swoole_server $serv, $fd, $from_id, $data) +{ + if($serv->exist($fd)) { + echo 'FD[' . $fd . '] exist' . PHP_EOL; + } else { + echo 'FD[' . $fd . '] not exist' . PHP_EOL; + } + $serv->task($data . '-' . $fd); +} + +function my_onTask(swoole_server $serv, $task_id, $from_id, $data) +{ + list($str, $fd) = explode('-', $data); + if($serv->exist($fd)) { + echo 'FD[' . $fd . '] exist' . PHP_EOL ; + } else { + echo 'FD[' . $fd . '] not exist' . PHP_EOL; + } + echo "Task[PID=".$serv->worker_pid."]: task_id=$task_id.".PHP_EOL; + return $data; +} + +function my_onFinish(swoole_server $serv, $task_id, $data) +{ + list($str, $fd) = explode('-', $data); + $serv->send($fd, 'Send Data To FD[' . $fd . ']'); + echo "Task Finish: result=" . $data . ". PID=" . $serv->worker_pid.PHP_EOL; +} + +$serv->on('Start', 'my_onStart'); +$serv->on('Connect', 'my_onConnect'); +$serv->on('Receive', 'my_onReceive'); +$serv->on('Close', 'my_onClose'); +$serv->on('Shutdown', 'my_onShutdown'); +$serv->on('Task', 'my_onTask'); +$serv->on('Finish', 'my_onFinish'); +$serv->on('ManagerStart', function($serv) { + global $argv; + swoole_set_process_name("php {$argv[0]}: manager"); +}); +$serv->start(); diff --git a/vendor/swoole/examples/server/fixed_header_client.php b/vendor/swoole/examples/server/fixed_header_client.php new file mode 100755 index 0000000..f11edeb --- /dev/null +++ b/vendor/swoole/examples/server/fixed_header_client.php @@ -0,0 +1,48 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); +if(!$client->connect('127.0.0.1', 9504)) +{ + exit("connect failed\n"); +} + +for ($l=0; $l < 1; $l++) +{ + $data = ''; + for($i=0; $i< 10; $i++) + { + $len = rand(10000, 20000); + echo "package length=".($len + 4)."\n"; + send_test3($client, $len); + } + //echo 'total send size:', strlen($data),"\n"; + //$client->send($data); + sleep(1); +} + +function send_test3($client, $len) +{ + $data = pack('n', $len + 4); + $data .= str_repeat('A', $len).rand(1000, 9999); + + $chunks = str_split($data, 4000); + + foreach($chunks as $ch) + { + $client->send($ch); + } + echo "package: ".substr($data, -4, 4)."\n"; +} + +function send_test2($client, $len) +{ + $data = pack('n', $len + 4); + $data .= str_repeat('A', $len).rand(1000, 9999); + $client->send($data); +} + +function send_test1($client, $len) +{ + $client->send(pack('n', $len + 4)); + usleep(10); + $client->send(str_repeat('A', $len).rand(1000, 9999)); +} diff --git a/vendor/swoole/examples/server/fixed_header_server.php b/vendor/swoole/examples/server/fixed_header_server.php new file mode 100755 index 0000000..a0edc63 --- /dev/null +++ b/vendor/swoole/examples/server/fixed_header_server.php @@ -0,0 +1,107 @@ +<?php +define('PID_FILE_NAME', '/tmp/swoole_server.pid'); + +$serv = new FixedHeaderServer(); +$serv->run('0.0.0.0', 9504); + +class FixedHeaderServer +{ + protected $buffer = array(); + protected $length = array(); + + /** + * @var swoole_server + */ + protected $serv; + + const MAX_PACKAGE_LEN = 8000000; + + function onPackage($fd, $pkg) + { + $this->current_fd = $fd; + var_dump($pkg); + $resp = "hello world"; + $this->serv->send($fd, $resp); + $this->current_fd = ''; + } + + function onReceive($serv, $fd, $from_id, $data) + { + echo "package".substr($data, -4, 4)." length=". (strlen($data) - 2)."\n"; + } + + function onReceive_unpack_php($serv, $fd, $from_id, $data) + { + if (empty($this->buffer[$fd])) + { + $this->buffer[$fd] = ''; + $this->length[$fd] = 0; + } + + $this->buffer[$fd] .= $data; + $buffer = &$this->buffer[$fd]; + + do + { + if ($this->length[$fd] === 0) + { + $n = unpack('Nlen', substr($buffer, 0, 4)); + $this->length[$fd] = $n['len']; + if ($n['len'] > self::MAX_PACKAGE_LEN) + { + $this->serv->close($fd); + return; + } + } + + if (strlen($buffer) >= $this->length[$fd]) + { + $this->onPackage($fd, substr($buffer, 0, $this->length[$fd])); + $buffer = substr($buffer, $this->length[$fd]); + $this->length[$fd] = 0; + } + else + { + break; + } + } while(strlen($buffer) > 0); + } + + function onClose($serv, $fd) + { + unset($this->buffer[$fd], $this->length[$fd]); + } + + function run($host, $port) + { + register_shutdown_function(array($this, 'errorHandler')); + $this->serv = new swoole_server($host, $port); + file_put_contents(PID_FILE_NAME, posix_getpid()); + + $this->serv->set(array( + 'max_request' => 0, +// 'dispatch_mode' => 3, + 'open_length_check' => true, + 'package_max_length' => 81920, + 'package_length_type' => 'n', //see php pack() + 'package_length_offset' => 0, + 'package_body_offset' => 2, + 'worker_num' => 2, + )); + + $this->serv->on('receive', array($this, 'onReceive')); + $this->serv->on('close', array($this, 'onClose')); + $this->serv->start(); + } + + function errorHandler() + { + if(!empty($this->current_fd)) + { + $rsp = Proxy::shutdown_handler(); + $rsp && $this->serv->send($this->current_fd, $rsp); + } + } +} + + diff --git a/vendor/swoole/examples/server/fixed_header_server1.7.3.php b/vendor/swoole/examples/server/fixed_header_server1.7.3.php new file mode 100755 index 0000000..3694ae5 --- /dev/null +++ b/vendor/swoole/examples/server/fixed_header_server1.7.3.php @@ -0,0 +1,86 @@ +<?php +$serv = new SocketServer(); +$serv->run('0.0.0.0', 9504); + +class SocketServer +{ + protected $serv; //swoole server + + const MAX_PACKAGE_LEN = 8000000; //max data accept + + function run($host, $port) + { + register_shutdown_function(array($this, 'errorHandler')); + $this->serv = new swoole_server($host, $port); + + $this->serv->set(array( + //'daemonize' => true, + 'max_request' => 2000, //reload worker by run xx times + 'dispatch_mode' => 3, //who come first who is + 'worker_num' => 5, //how much worker will start + 'reactor_num' => 2, // depend cpu how much cpu you have + 'backlog' => 128, //accept queue + 'open_cpu_affinity' => 1, //get cpu more time + 'open_tcp_nodelay' => 1, // for small packet to open + 'tcp_defer_accept' => 5, //client will accept when not have data + 'max_conn' => 10000, + 'task_worker_num' => 10, + 'task_ipc_mode' => 2, //use queue with "who come first who is" + 'message_queue_key' => 0x72000100, + 'open_length_check' => true, + 'package_max_length' => 999999999, + 'package_length_type' => 'N', //see php pack() + 'package_length_offset' => 0, + 'package_body_offset' => 4, + + )); + + $this->serv->on('receive', array($this, 'onReceive')); + $this->serv->on('close', array($this, 'onClose')); + $this->serv->on('task', array($this, 'onTask')); + $this->serv->on('finish', array($this, 'onFinish')); + $this->serv->start(); + } + + + function onReceive($serv, $fd, $from_id, $data) + { + $packet = json_decode(substr($data,4), true); + + //todo::包可能解析失败 + $packet["socketfd"] = $fd; + $task_id = $serv->task(json_encode($packet)); + //todo::任务可能下发失败 + } + + function onTask($serv, $task_id, $from_id, $data) + { + $data = json_decode($data, true); + $fd = $data["socketfd"]; + + $result = array( + "code" => "0", + "msg" => "ok", + "data" => $data, + ); + $serv->send($fd, json_encode($result)); + } + + function onFinish($serv, $task_id, $data) + { + + } + + function onClose($serv, $fd) + { + + } + + function errorHandler() + { + //if (!empty($this->current_fd)) { + // $rsp = Proxy::shutdown_handler(); + // $rsp && $this->serv->send($this->current_fd, $rsp); + //} + } +} diff --git a/vendor/swoole/examples/server/getReceivedTime.php b/vendor/swoole/examples/server/getReceivedTime.php new file mode 100755 index 0000000..92d67b1 --- /dev/null +++ b/vendor/swoole/examples/server/getReceivedTime.php @@ -0,0 +1,20 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +//$serv->on('connect', function ($serv, $fd, $reactor_id){ +// echo "[#".posix_getpid()."]\tClient@[$fd:$reactor_id]: Connect.\n"; +//}); +$serv->set(array( + 'worker_num' => 1, +)); + +$serv->on('receive', function (swoole_server $serv, $fd, $reactor_id, $data) { + usleep(rand(100000, 2000000)); + var_dump(round($serv->getReceivedTime(), 10)); +}); + +//$serv->on('close', function ($serv, $fd, $reactor_id) { +// echo "[#".posix_getpid()."]\tClient@[$fd:$reactor_id]: Close.\n"; +//}); + +$serv->start(); + diff --git a/vendor/swoole/examples/server/ip_dispatch.php b/vendor/swoole/examples/server/ip_dispatch.php new file mode 100755 index 0000000..53571f5 --- /dev/null +++ b/vendor/swoole/examples/server/ip_dispatch.php @@ -0,0 +1,52 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +$serv->fdlist = []; +$serv->workerid = 0; +$serv->set(array( + //'tcp_defer_accept' => 5, + //'ipc_mode' => 2, + 'worker_num' => 4, + //'task_worker_num' => 2, + 'dispatch_mode' => 4, //ip dispatch + //'max_request' => 1000, + //'daemonize' => true, + //'log_file' => '/tmp/swoole.log' +)); + +$serv->on('workerStart', function($serv, $worker_id) { + echo "{$worker_id} start".PHP_EOL; + $serv->workerid = $worker_id; +}); + +$serv->on('connect', function ($serv, $fd, $from_id){ + //echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; + echo "{$fd} connect, worker:".$serv->workerid.PHP_EOL; + $conn = print_r($serv->connection_info($fd)); + $serv->fdlist[$fd] = 1; + print_r($serv->fdlist); + +}); + +$serv->on('task', function ($serv, $task_id, $from_id, $data){ + //var_dump($task_id, $from_id, $data); + $fd = $data; + $serv->send($fd, str_repeat('B', 1024*rand(40, 60)).rand(10000, 99999)."\n"); +}); + +$serv->on('finish', function ($serv, $fd, $from_id){ + +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + + foreach($serv->fdlist as $_fd=>$val) { + $serv->send($_fd, "{$fd} say:".$data.PHP_EOL); + } +}); + +$serv->on('close', function ($serv, $fd, $from_id) { + //echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; + unset($serv->fdlist[$fd]); +}); + +$serv->start(); diff --git a/vendor/swoole/examples/server/listen_1k_port.php b/vendor/swoole/examples/server/listen_1k_port.php new file mode 100755 index 0000000..4410be8 --- /dev/null +++ b/vendor/swoole/examples/server/listen_1k_port.php @@ -0,0 +1,15 @@ +<?php +$serv = new swoole_server('127.0.0.1', 9001); + +for($port = 9002; $port < 9999; $port++) +{ + $serv->listen("127.0.0.1", $port, SWOOLE_SOCK_TCP); +} + +$serv->on("receive", function($serv, $fd, $reactor_id, $data) { + $info = $serv->getClientInfo($fd); + var_dump($info); +}); + +$serv->start(); + diff --git a/vendor/swoole/examples/server/local_listener.php b/vendor/swoole/examples/server/local_listener.php new file mode 100755 index 0000000..88d7259 --- /dev/null +++ b/vendor/swoole/examples/server/local_listener.php @@ -0,0 +1,35 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9502); + +$serv->on('workerstart', function($server, $id) { + global $argv; + swoole_set_process_name("php {$argv[0]}: worker"); + + $local_listener = stream_socket_server("127.0.0.1", 9999); + + swoole_event_add($local_listener, function($server){ + $local_client = stream_socket_accept($server); + + swoole_event_add($local_client, function($client){ + echo fread($client, 8192); + fwrite($client, "hello"); + }); + }); + +}); + +$serv->on('connect', function (swoole_server $serv, $fd, $from_id) { + //echo "connect\n";; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + $serv->send($fd, "Swoole: ".$data); + //$serv->close($fd); +}); + +$serv->on('close', function (swoole_server $serv, $fd, $from_id) { + //var_dump($serv->connection_info($fd)); + //echo "onClose\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/server/multi_instance.php b/vendor/swoole/examples/server/multi_instance.php new file mode 100755 index 0000000..f03b063 --- /dev/null +++ b/vendor/swoole/examples/server/multi_instance.php @@ -0,0 +1,20 @@ +<?php +for ($i = 0; $i < 2; $i++) +{ + $p = new swoole_process(function () use ($i) { + $port = 9501 + $i; + $http = new swoole_http_server("127.0.0.1", $port); + + $http->on("start", function ($server) use ($port) { + echo "Swoole http server is started at http://127.0.0.1:{$port}\n"; + }); + + $http->on("request", function ($request, $response) { + $response->header("Content-Type", "text/plain"); + $response->end("Hello World\n"); + }); + + $http->start(); + }, false, false); + $p->start(); +} \ No newline at end of file diff --git a/vendor/swoole/examples/server/pipe_message.php b/vendor/swoole/examples/server/pipe_message.php new file mode 100755 index 0000000..38d08f6 --- /dev/null +++ b/vendor/swoole/examples/server/pipe_message.php @@ -0,0 +1,49 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501, SWOOLE_BASE); +//$serv = new swoole_server("0.0.0.0", 9501); +$serv->set(array( + 'worker_num' => 2, + 'task_worker_num' => 2, +)); + +$serv->on('pipeMessage', function($serv, $src_worker_id, $data) { + echo "#{$serv->worker_id} message from #$src_worker_id: $data\n"; +}); + +$serv->on('task', function (swoole_server $serv, $task_id, $from_id, $data){ + echo "#{$serv->worker_id} NewTask: $data\n"; + $serv->sendMessage($data, 0); + //$serv->send($fd, str_repeat('B', 1024*rand(40, 60)).rand(10000, 99999)."\n"); +}); + +$serv->on('finish', function ($serv, $fd, $from_id){ + +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + $cmd = trim($data); + if($cmd == 'totask') + { + $serv->sendMessage("hello task process", 2); + } + elseif($cmd == 'toworker') + { + $worker_id = 1 - $serv->worker_id; + $serv->sendMessage("hello worker", $worker_id); + } + elseif($cmd == 'task2worker') + { + $serv->task('hello worker from task.'); + } + else + { + echo "#{$serv->worker_id} Recv: $data\n"; + } +}); + +$serv->on('close', function ($serv, $fd, $from_id) { + //echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); + +$serv->start(); + diff --git a/vendor/swoole/examples/server/reload_aysnc.php b/vendor/swoole/examples/server/reload_aysnc.php new file mode 100755 index 0000000..de78163 --- /dev/null +++ b/vendor/swoole/examples/server/reload_aysnc.php @@ -0,0 +1,47 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); + +$serv->set([ + 'worker_num' => 4, + 'reload_async' => true, + 'max_wait_time' => 5, + 'task_worker_num' => 2, +]); + +$serv->on('WorkerStart', function ($serv, $wid) { + echo "Worker#$wid is started\n"; + if ($serv->taskworker) { + return; + } + swoole_event::add(STDIN, function () use ($wid) { + $data = fread(STDIN, 8192); + if ($data) { + echo "#{$wid}: $data"; + } + }); +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $reactor_id, $data) { + echo "[#".$serv->worker_id."]\tClient[$fd]: $data\n"; +}); + +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + //echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; +// $serv->finish($data); + return $data; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('WorkerStop', function ($serv, $wid) { + //sleep($wid + 1); +}); + +$serv->on('WorkerExit', function ($serv, $wid) { + echo "WorkerExit, PID=".posix_getpid()."\t$wid\n"; + swoole_event::del(STDIN); +}); + +$serv->start(); diff --git a/vendor/swoole/examples/server/single.php b/vendor/swoole/examples/server/single.php new file mode 100755 index 0000000..83f9b8e --- /dev/null +++ b/vendor/swoole/examples/server/single.php @@ -0,0 +1,9 @@ +<?php +//single process single thread +$server = new swoole_server('127.0.0.1', 9501, SWOOLE_BASE); + +$server->on('Receive', function($serv, $fd, $reactor_id, $data) { + $serv->send($fd, "Swoole: $data"); +}); + +$server->start(); diff --git a/vendor/swoole/examples/server/trace.php b/vendor/swoole/examples/server/trace.php new file mode 100755 index 0000000..d025be5 --- /dev/null +++ b/vendor/swoole/examples/server/trace.php @@ -0,0 +1,42 @@ +<?php +function test() +{ + test_sleep(); +} + +function test_sleep() +{ + echo "sleep 5\n"; + sleep(5); +} + +$server = new swoole_server('127.0.0.1', 9501); + +$server->set([ + 'worker_num' => 1, + 'task_worker_num' => 1, + 'request_slowlog_timeout' => 1, + 'request_slowlog_file' => '/tmp/trace.log', +]); + +$server->on('Receive', function($serv, $fd, $reactor_id, $data) { + if (trim($data) == 'task') { + echo "task\n"; + $serv->task($fd); + return; + } + test(); + $serv->send($fd, "Swoole: $data"); +}); + +$server->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; + test(); + $serv->send($data, "Swoole: task\n"); +}); + +$server->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$server->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/server/uid_dispatch.php b/vendor/swoole/examples/server/uid_dispatch.php new file mode 100755 index 0000000..0de3ce8 --- /dev/null +++ b/vendor/swoole/examples/server/uid_dispatch.php @@ -0,0 +1,64 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); +$serv->fdlist = []; +$serv->set(array( + //'tcp_defer_accept' => 5, + //'ipc_mode' => 2, + 'worker_num' => 4, + //'task_worker_num' => 2, + 'dispatch_mode' => 5, //uid dispatch + //'max_request' => 1000, + //'daemonize' => true, + //'log_file' => '/tmp/swoole.log' +)); +$serv->on('timer', function($serv, $interval) { + echo "onTimer: $interval\n"; +}); + +$serv->on('start', function($serv) { + //$serv->addtimer(1000); +}); + +$serv->on('workerStart', function($serv, $worker_id) { + echo "{$worker_id} start".PHP_EOL; + //if($worker_id == 0) $serv->addtimer(1000); +}); + +$serv->on('connect', function ($serv, $fd, $from_id){ + //echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; + echo "{$fd} connect, worker:".$serv->worker_id.PHP_EOL; +}); + +$serv->on('task', function ($serv, $task_id, $from_id, $data){ +}); + +$serv->on('finish', function ($serv, $fd, $from_id){ + +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + $conn = $serv->connection_info($fd); + print_r($conn); + echo "worker_id: " . $serv->worker_id . PHP_EOL; + if (empty($conn['uid'])) { + $uid = $fd + 1; + if ($serv->bind($fd, $uid)) { + $serv->send($fd, "bind {$uid} success"); + } + } else { + if (empty($serv->fdlist[$fd])) { + $serv->fdlist[$fd] = $conn['uid']; + } + print_r($serv->fdlist); + foreach ($serv->fdlist as $_fd => $uid) { + $serv->send($_fd, "{$fd} say:" . $data . PHP_EOL); + } + } +}); + +$serv->on('close', function ($serv, $fd, $from_id) { + //echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; + unset($serv->fdlist[$fd]); +}); + +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/server/unix_stream.php b/vendor/swoole/examples/server/unix_stream.php new file mode 100755 index 0000000..cdce9c9 --- /dev/null +++ b/vendor/swoole/examples/server/unix_stream.php @@ -0,0 +1,17 @@ +<?php +$serv = new swoole_server(__DIR__."/svr.sock", 0, SWOOLE_PROCESS, SWOOLE_UNIX_STREAM); +$serv->set(array( + 'worker_num' => 1, +)); +$serv->on('connect', function ($serv, $fd, $from_id){ + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; +}); +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + $serv->send($fd, json_encode(array("hello" => '1213', "bat" => "ab"))); + //$serv->close($fd); +}); +$serv->on('close', function ($serv, $fd, $from_id) { + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/server/zmq.php b/vendor/swoole/examples/server/zmq.php new file mode 100755 index 0000000..c857ca0 --- /dev/null +++ b/vendor/swoole/examples/server/zmq.php @@ -0,0 +1,58 @@ +<?php +$serv = new swoole_server("0.0.0.0", 9501); + +$context = new ZMQContext(); + +$sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH); +$sender->bind("tcp://*:5557"); + +$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL); +$receiver->bind("tcp://*:5558"); + +function onZMQR() +{ + global $receiver; + $string = $receiver->recv(); + echo $string, PHP_EOL; +} + +$serv->set(array( + //'tcp_defer_accept' => 5, + 'worker_num' => 1, + 'reactor_num' => 1, + //'daemonize' => true, + //'log_file' => '/tmp/swoole.log' +)); + +$serv->on('workerStart', function($serv, $worker_id) { + global $sender; + global $receiver; + + $rfd = $receiver->getsockopt(ZMQ::SOCKOPT_FD); + swoole_event_add($rfd, 'onZMQR', NULL , SWOOLE_EVENT_READ); + echo "worker start\n"; +}); + +$serv->on('connect', function ($serv, $fd, $from_id){ + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + + $cmd = trim($data); + echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + + if($cmd == "zmqtest") + { + echo 'aaaaaaaaaaaa'. PHP_EOL; + $sender->send("msg to zmq"); + } + $serv->send($fd, 'OK'.PHP_EOL); + //$serv->close($fd); +}); + +$serv->on('close', function ($serv, $fd, $from_id) { + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); + +//$serv->start(); diff --git a/vendor/swoole/examples/server_hot_update_opcache.php b/vendor/swoole/examples/server_hot_update_opcache.php new file mode 100755 index 0000000..d037bc7 --- /dev/null +++ b/vendor/swoole/examples/server_hot_update_opcache.php @@ -0,0 +1,145 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); +$serv->set(array( + 'worker_num' => 2, + //'open_eof_check' => true, + //'package_eof' => "\r\n", + 'task_worker_num' => 2, + //'dispatch_mode' => 2, + //'daemonize' => 1, + //'heartbeat_idle_time' => 5, + //'heartbeat_check_interval' => 5, +)); +function my_onStart($serv) +{ + echo "MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}\n"; + echo "Server: start.Swoole version is [".SWOOLE_VERSION."]\n"; + //$serv->addtimer(1000); +} + +function my_onShutdown($serv) +{ + echo "Server: onShutdown\n"; +} + +function my_onTimer($serv, $interval) +{ + echo "Server:Timer Call.Interval=$interval\n"; +} + +function my_onClose($serv, $fd, $from_id) +{ + //echo "Client: fd=$fd is closed.\n"; +} + +function my_onConnect($serv, $fd, $from_id) +{ + //throw new Exception("hello world"); +// echo "Client:Connect.\n"; +} + + +$class = null; +function my_onWorkerStart($serv, $worker_id) +{ + global $argv; + global $class; + opcache_reset(); + include "hot_update_class.php"; + $class = new HotUpdate(); + if($worker_id >= $serv->setting['worker_num']) { + swoole_set_process_name("php {$argv[0]} task worker"); + } else { + swoole_set_process_name("php {$argv[0]} event worker"); + } + //echo "WorkerStart|MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}|WorkerId=$worker_id\n"; + //$serv->addtimer(500); //500ms +} + +function my_onWorkerStop($serv, $worker_id) +{ + echo "WorkerStop[$worker_id]|pid=".posix_getpid().".\n"; +} + +function my_onReceive(swoole_server $serv, $fd, $from_id, $data) +{ + $cmd = trim($data); + if($cmd == "reload") + { + $serv->reload($serv); + } + elseif($cmd == "task") + { + $task_id = $serv->task("hello world", 0); + echo "Dispath AsyncTask: id=$task_id\n"; + } + elseif($cmd == "info") + { + $info = $serv->connection_info($fd); + $serv->send($fd, 'Info: '.var_export($info, true).PHP_EOL); + } + elseif($cmd == "broadcast") + { + $start_fd = 0; + while(true) + { + $conn_list = $serv->connection_list($start_fd, 10); + if($conn_list === false) + { + break; + } + $start_fd = end($conn_list); + foreach($conn_list as $conn) + { + if($conn === $fd) continue; + $serv->send($conn, "hello from $fd\n"); + } + } + } + //这里故意调用一个不存在的函数 + elseif($cmd == "error") + { + hello_no_exists(); + } + elseif($cmd == "shutdown") + { + $serv->shutdown(); + } + else + { + global $class; + $data .= $class->getData(); + $serv->send($fd, 'Swoole: '.$data, $from_id); + //$serv->close($fd); + } + //echo "Client:Data. fd=$fd|from_id=$from_id|data=$data"; + //$serv->deltimer(800); + //swoole_server_send($serv, $other_fd, "Server: $data", $other_from_id); +} + +function my_onTask(swoole_server $serv, $task_id, $from_id, $data) +{ + echo "AsyncTask[PID=".posix_getpid()."]: task_id=$task_id.".PHP_EOL; + $serv->finish("OK"); +} + +function my_onFinish(swoole_server $serv, $data) +{ + echo "AsyncTask Finish:Connect.PID=".posix_getpid().PHP_EOL; +} + +$serv->on('Start', 'my_onStart'); +$serv->on('Connect', 'my_onConnect'); +$serv->on('Receive', 'my_onReceive'); +$serv->on('Close', 'my_onClose'); +$serv->on('Shutdown', 'my_onShutdown'); +$serv->on('Timer', 'my_onTimer'); +$serv->on('WorkerStart', 'my_onWorkerStart'); +$serv->on('WorkerStop', 'my_onWorkerStop'); +$serv->on('Task', 'my_onTask'); +$serv->on('Finish', 'my_onFinish'); +$serv->on('WorkerError', function($serv, $worker_id, $worker_pid, $exit_code) { + echo "worker abnormal exit. WorkerId=$worker_id|Pid=$worker_pid|ExitCode=$exit_code\n"; +}); +$serv->start(); + diff --git a/vendor/swoole/examples/set_cpu_affinity.php b/vendor/swoole/examples/set_cpu_affinity.php new file mode 100755 index 0000000..1269966 --- /dev/null +++ b/vendor/swoole/examples/set_cpu_affinity.php @@ -0,0 +1,4 @@ +<?php +swoole_process::setaffinity(array(0, 2)); +sleep(1000); + diff --git a/vendor/swoole/examples/socket_coro/client.php b/vendor/swoole/examples/socket_coro/client.php new file mode 100755 index 0000000..d390690 --- /dev/null +++ b/vendor/swoole/examples/socket_coro/client.php @@ -0,0 +1,21 @@ +<?php +$socket = new Co\Socket(AF_INET, SOCK_STREAM, 0); + +go(function () use ($socket) { + $retval = $socket->connect('localhost', 9601); + while ($retval) + { + $n = $socket->send("hello"); + var_dump($n); + + $data = $socket->recv(); + var_dump($data); + + if (empty($data)) { + $socket->close(); + break; + } + co::sleep(1.0); + } + var_dump($retval, $socket->errCode); +}); diff --git a/vendor/swoole/examples/socket_coro/server.php b/vendor/swoole/examples/socket_coro/server.php new file mode 100755 index 0000000..22ec891 --- /dev/null +++ b/vendor/swoole/examples/socket_coro/server.php @@ -0,0 +1,27 @@ +<?php +$socket = new Co\Socket(AF_INET, SOCK_STREAM, 0); +$socket->bind('127.0.0.1', 9601); +$socket->listen(128); + +go(function () use ($socket) { + while(true) { + echo "Accept: \n"; + $client = $socket->accept(); + + echo "New Coroutine: \n"; + go(function () use ($client) { + while(true) { + echo "Client Recv: \n"; + $data = $client->recv(); + if (empty($data)) { + $client->close(); + break; + } + var_dump($client->getsockname()); + var_dump($client->getpeername()); + echo "Client Send: \n"; + $client->send("Server: $data"); + } + }); + } +}); diff --git a/vendor/swoole/examples/socket_coro/udp.php b/vendor/swoole/examples/socket_coro/udp.php new file mode 100755 index 0000000..8a0ede5 --- /dev/null +++ b/vendor/swoole/examples/socket_coro/udp.php @@ -0,0 +1,26 @@ +<?php +//Server +go(function () { + $socket = new Co\Socket(AF_INET, SOCK_DGRAM, 0); + $socket->bind('127.0.0.1', 9601); + while (true) { + $peer = null; + $data = $socket->recvfrom($peer); + echo "[Server] recvfrom[{$peer['address']}:{$peer['port']}] : $data\n"; + $socket->sendto($peer['address'], $peer['port'], "Swoole: $data"); + } +}); + +//Client +go(function () { + $socket = new Co\Socket(AF_INET, SOCK_DGRAM, 0); + $i = 0; + while (true) + { + $socket->sendto('127.0.0.1', 9601, "HELO-" . $i++); + $peer = null; + $data = $socket->recvfrom($peer); + echo "[Client] recvfrom[{$peer['address']}:{$peer['port']}] : $data\n"; + co::sleep(1); + } +}); diff --git a/vendor/swoole/examples/ssl/async_client.php b/vendor/swoole/examples/ssl/async_client.php new file mode 100755 index 0000000..f2a7c2c --- /dev/null +++ b/vendor/swoole/examples/ssl/async_client.php @@ -0,0 +1,25 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP | SWOOLE_SSL, SWOOLE_SOCK_ASYNC); //异步非阻塞 +$client->on("connect", function (swoole_client $cli) +{ + $cli->send("Hello World\n"); +}); + +$client->on("receive", function (swoole_client $cli, $data) +{ + echo "Receive: $data"; + $cli->close(); +}); + +$client->on("error", function (swoole_client $cli) +{ + echo "error\n"; +}); + +$client->on("close", function (swoole_client $cli) +{ + echo "Connection close\n"; +}); + +$client->connect('127.0.0.1', 9501); +echo "connect to 127.0.0.1:9501\n"; diff --git a/vendor/swoole/examples/ssl/client.c b/vendor/swoole/examples/ssl/client.c new file mode 100755 index 0000000..c263324 --- /dev/null +++ b/vendor/swoole/examples/ssl/client.c @@ -0,0 +1,128 @@ +/** + * gcc -g -o client client.c -lssl -lcrypt -lcrypto + */ +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <malloc.h> +#include <string.h> +#include <sys/socket.h> +#include <resolv.h> +#include <netdb.h> +#include <openssl/ssl.h> +#include <openssl/err.h> + +#define FAIL -1 + +int OpenConnection(const char *hostname, int port) +{ + int sd; + struct hostent *host; + struct sockaddr_in addr; + if ((host = gethostbyname(hostname)) == NULL) + { + printf("Eroor: %s\n", hostname); + perror(hostname); + abort(); + } + + sd = socket(PF_INET, SOCK_STREAM, 0); + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = *(long*) (host->h_addr); + + if (connect(sd, (struct sockaddr*) &addr, sizeof(addr)) != 0) + { + close(sd); + perror(hostname); + abort(); + } + return sd; +} + +SSL_CTX* InitCTX(void) +{ + SSL_METHOD *method; + SSL_CTX *ctx; + OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ + SSL_load_error_strings(); /* Bring in and register error messages */ + +// method = SSLv3_client_method(); /* Create new client-method instance */ + method = TLSv1_2_client_method(); + + ctx = SSL_CTX_new(method); /* Create new context */ + if (ctx == NULL) + { + ERR_print_errors_fp(stderr); + printf("Eroor: %s\n", stderr); + abort(); + } + return ctx; +} + +void ShowCerts(SSL* ssl) +{ + X509 *cert; + char *line; + + cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */ + if (cert != NULL) + { + printf("Server certificates:\n"); + line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + printf("Subject: %s\n", line); + free(line); + line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + printf("Issuer: %s\n", line); + free(line); + X509_free(cert); + } + else + printf("No certificates.\n"); +} + +int main(int count, char *strings[]) +{ + SSL_CTX *ctx; + int server; + SSL *ssl; + char buf[1024]; + int bytes; + char *hostname, *portnum; + if (count != 3) + { + printf("usage: %s <hostname> <portnum>\n", strings[0]); + exit(0); + } + + SSL_library_init(); + hostname = strings[1]; + portnum = strings[2]; + ctx = InitCTX(); + server = OpenConnection(hostname, atoi(portnum)); + + ssl = SSL_new(ctx); /* create new SSL connection state */ + SSL_set_fd(ssl, server); /* attach the socket descriptor */ + TLSv1_2_client_method(); + if (SSL_connect(ssl) == FAIL) /* perform the connection */ + { + printf("Eroor: %s\n", stderr); + ERR_print_errors_fp(stderr); + } + else + { + char *msg = "HelloWorld"; + printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); + ShowCerts(ssl); /* get any certs */ + SSL_write(ssl, msg, strlen(msg)); /* encrypt & send message */ + bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ + buf[bytes] = 0; + printf("Received: \"%s\"\n", buf); + SSL_free(ssl); /* release connection state */ + } + close(server); /* close socket */ + SSL_CTX_free(ctx); /* release context */ + return 0; +} diff --git a/vendor/swoole/examples/ssl/client.php b/vendor/swoole/examples/ssl/client.php new file mode 100755 index 0000000..47a4fa2 --- /dev/null +++ b/vendor/swoole/examples/ssl/client.php @@ -0,0 +1,15 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP | SWOOLE_SSL); +if (!$client->connect('192.168.0.44', 9501, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} +echo "connect ok\n"; +sleep(1); + +for ($i = 0; $i < 1000; $i++) +{ + $client->send("hello world-" . str_repeat('A', $i) . "\n"); + echo $client->recv(); +} +sleep(1); diff --git a/vendor/swoole/examples/ssl/http_client.php b/vendor/swoole/examples/ssl/http_client.php new file mode 100755 index 0000000..95e2dfc --- /dev/null +++ b/vendor/swoole/examples/ssl/http_client.php @@ -0,0 +1,13 @@ +<?php +$cli = new Swoole\Http\Client('127.0.0.1', 9501, false); +$cli->setHeaders(array('User-Agent' => 'swoole-http-client')); + +$cli->on('close', function($_cli) { + echo "connection is closed\n"; +}); +$cli->get('/?dump.php?corpid=ding880f44069a80bca1&corpsecret=YB1cT8FNeN7VCm3eThwDAncsmSl4Ajl_1DmckaOFmOZhTFzexLbIzq5ueH3YcHrx', function ($cli) { + var_dump($cli); + var_dump($cli->headers); + echo $cli->body; + //$cli->close(); +}); diff --git a/vendor/swoole/examples/ssl/passphrase.php b/vendor/swoole/examples/ssl/passphrase.php new file mode 100755 index 0000000..bf62abe --- /dev/null +++ b/vendor/swoole/examples/ssl/passphrase.php @@ -0,0 +1,20 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP | SWOOLE_SSL); +$client->set(array( + "ssl_key_file" => __DIR__ . '/ssl.key', + "ssl_cert_file" => __DIR__ . '/ssl.crt', + 'ssl_passphrase' => '5524001', +)); +if (!$client->connect('127.0.0.1', 9501, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} +echo "connect ok\n"; +sleep(1); + +for ($i = 0; $i < 1000; $i++) +{ + $client->send("hello world-" . str_repeat('A', $i) . "\n"); + echo $client->recv(); +} +sleep(1); diff --git a/vendor/swoole/examples/ssl/server.php b/vendor/swoole/examples/ssl/server.php new file mode 100755 index 0000000..392c044 --- /dev/null +++ b/vendor/swoole/examples/ssl/server.php @@ -0,0 +1,35 @@ +<?php +//$serv = new swoole_server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$serv = new swoole_server("0.0.0.0", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$key_dir = dirname(dirname(__DIR__)).'/tests/ssl'; + +$port2 = $serv->addlistener('0.0.0.0', 9502, SWOOLE_SOCK_TCP); +$port2->on('receive', function($serv, $fd, $from_id, $data){ + echo "port2: ".$data."\n"; +}); + +$serv->set(array( +// 'worker_num' => 4, + 'ssl_cert_file' => __DIR__.'/corpssl.crt', + 'ssl_key_file' => __DIR__.'/corpssl.key', + 'ssl_client_cert_file' => __DIR__.'/ca.crt', + 'ssl_verify_depth' => 10, +)); + +$serv->on('connect', function (swoole_server $serv, $fd, $from_id){ + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Connect.\n"; + $info = $serv->getClientInfo($fd); + var_dump($info); +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { + echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; + $serv->send($fd, "Swoole: $data\n"); +}); + +$serv->on('close', function ($serv, $fd, $from_id) { + echo "[#".posix_getpid()."]\tClient@[$fd:$from_id]: Close.\n"; +}); + +$serv->start(); + diff --git a/vendor/swoole/examples/ssl/ssl.crt b/vendor/swoole/examples/ssl/ssl.crt new file mode 100755 index 0000000..5484064 --- /dev/null +++ b/vendor/swoole/examples/ssl/ssl.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICAzCCAWwCCQCgnsxsw2bDrDANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMCAXDTE0MDcwOTE0MTIxNloYDzIxMTQwNjE1MTQxMjE2WjBFMQsw +CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu +ZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDP +nYsgGr6Q9jqL97xGo2zxrOWGQd96PnItf5uOdvZJjwTLsN8an33UOtFVxwGIaTb8 +MtuXiLZbslKWLIOoqq0Lk92RwF4Zxs02Yt+S1sM/9ST7tiJQKYx1+rfaZIj0Dy9y +VoWHGfRmVZMcWkhslaHR/Yz+Ul4CIqr03/BjYjjQfQIDAQABMA0GCSqGSIb3DQEB +CwUAA4GBAJIjeaUeizJ88G1M9fFUTwf11ywWsrzIQxCaMqmzRyrlIhwuC5qXKsA/ +wHRfj9+KnfJ1LOAguXa/CSRFCogQnYur4+Kzy/PBchMFjIKS9UzmQQWZYsmzBgTX +e6pGJN2fxTmpGKf0lj7//NWxOmFDFWgyUeIR4TaAJ5dWpS8Cr0Gc +-----END CERTIFICATE----- diff --git a/vendor/swoole/examples/ssl/ssl.key b/vendor/swoole/examples/ssl/ssl.key new file mode 100755 index 0000000..7ca7698 --- /dev/null +++ b/vendor/swoole/examples/ssl/ssl.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDPnYsgGr6Q9jqL97xGo2zxrOWGQd96PnItf5uOdvZJjwTLsN8a +n33UOtFVxwGIaTb8MtuXiLZbslKWLIOoqq0Lk92RwF4Zxs02Yt+S1sM/9ST7tiJQ +KYx1+rfaZIj0Dy9yVoWHGfRmVZMcWkhslaHR/Yz+Ul4CIqr03/BjYjjQfQIDAQAB +AoGBAL4DtYp7j8BC61ChOvr3pcUG9cbL0UojjwJfUTKxZDXspHn8diT6pgIwltjH +23pKuZ1Wuq3U3PnNmlKBiTo8g0R4OudAWJi1kIyY9AXVm9Ffr1wS0krRrOXXJws/ +P0Y+NtSdpMDEbCiW/GbADPhlWl2JdpOgxdB5mNmCykt4dvRtAkEA7JnxiJWIQg/z +Wpy485hrIFwNNNiRJGKVSySZf9itZd+4fC1F6vTlX+ylDemTbYB427dlJ09nINRz +gXMW3xh8hwJBAOCjNdhTXCESSeJyt8U5cN0PzIJuKq1CvJdLgaNN+RIsC8v9ZTJF +nmMOgjSYNWILRSrHlx0g7VKb2GH6LPsqr9sCQQDKuwGdsdsGGBrB6oYDm/c2zAk4 +3dRH4/zeXSb1x9iT8QVnyXceYubjsaaf7CM58ZodUeBntX69P60VH2Nal+WjAkEA +2r7TziXOjv3KKNLhFRLMTtf1pAU3VaSpFQMX6DgjlIiDrE7CXmPgykD0ldaqFSE4 +Z2IYSusnbswHt9DwQFzfBQJANhJBIvQgj/BcAV+0qV1NgzXbmywtQcwGg+NcimsH +R/tW2SeAXinNkVMjDh5NLzHO5Lz//E0N3lPRljnLfRX69g== +-----END RSA PRIVATE KEY----- diff --git a/vendor/swoole/examples/ssl/ssl_passwd/ssl.crt b/vendor/swoole/examples/ssl/ssl_passwd/ssl.crt new file mode 100755 index 0000000..8b31ac2 --- /dev/null +++ b/vendor/swoole/examples/ssl/ssl_passwd/ssl.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICazCCAdQCCQDGckgNrF7jzDANBgkqhkiG9w0BAQsFADB6MQswCQYDVQQGEwJD +TjERMA8GA1UECAwIU2hhbmdIYWkxEDAOBgNVBAcMB01pbmhhbmcxDzANBgNVBAoM +BmNoZWx1bjEUMBIGA1UEAwwLaGFudGlhbmZlbmcxHzAdBgkqhkiG9w0BCQEWEHJh +bmdvQHN3b29sZS5jb20wHhcNMTcwNjIxMDg0NDIzWhcNMTgwNjIxMDg0NDIzWjB6 +MQswCQYDVQQGEwJDTjERMA8GA1UECAwIU2hhbmdIYWkxEDAOBgNVBAcMB01pbmhh +bmcxDzANBgNVBAoMBmNoZWx1bjEUMBIGA1UEAwwLaGFudGlhbmZlbmcxHzAdBgkq +hkiG9w0BCQEWEHJhbmdvQHN3b29sZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0A +MIGJAoGBAM6DB6/k7gBq335W+46qJKOF2AJ8pJcyr8rwIculc2Guc/8Y7iAnv2gP +NuZQWGtXuWNTgEkBc2vP2G2UbsHJRwR8fVgwFphZWmWJ1vomj9RZjm+v1ID04lIw +2d2oR4P2Nur7mw6Lxhpgx0y0DJ+4kW4/L/ObV13fJu7fNBKuprtzAgMBAAEwDQYJ +KoZIhvcNAQELBQADgYEAPwHwRDG+PCToqybr9GZtz3oxM6ApvVGV0c24Clon8veY +57h78tJLVmjx/b6Y4alg4HnT+DDBRZT0hJnBhdtkZivGX7eOys9sUDLZxAWsqO7a +bHzHkP0jVawHwqQv7WFoE83pvmUYzj2QbLMULj5PJ4LMlY3bMHYE07c0SVKeJFE= +-----END CERTIFICATE----- diff --git a/vendor/swoole/examples/ssl/ssl_passwd/ssl.csr b/vendor/swoole/examples/ssl/ssl_passwd/ssl.csr new file mode 100755 index 0000000..d1a426d --- /dev/null +++ b/vendor/swoole/examples/ssl/ssl_passwd/ssl.csr @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBujCCASMCAQAwejELMAkGA1UEBhMCQ04xETAPBgNVBAgMCFNoYW5nSGFpMRAw +DgYDVQQHDAdNaW5oYW5nMQ8wDQYDVQQKDAZjaGVsdW4xFDASBgNVBAMMC2hhbnRp +YW5mZW5nMR8wHQYJKoZIhvcNAQkBFhByYW5nb0Bzd29vbGUuY29tMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQDOgwev5O4Aat9+VvuOqiSjhdgCfKSXMq/K8CHL +pXNhrnP/GO4gJ79oDzbmUFhrV7ljU4BJAXNrz9htlG7ByUcEfH1YMBaYWVplidb6 +Jo/UWY5vr9SA9OJSMNndqEeD9jbq+5sOi8YaYMdMtAyfuJFuPy/zm1dd3ybu3zQS +rqa7cwIDAQABoAAwDQYJKoZIhvcNAQELBQADgYEASQqPl/+WGbjiFmejmI7cj5Te +byHjUASEGc2VDRQhc1W7XRFjHFqyeKRh8xwFV7HDFbvVwsTos260s4PKGkjTD5hH +XG2HKPevBQRzqV0dIJmdW1+gZ13QyIESnQyj9MzGkW4I6MDHXamCZmYAFel2MXtE +Vsj7idZCTW/REX/7/z8= +-----END CERTIFICATE REQUEST----- diff --git a/vendor/swoole/examples/ssl/ssl_passwd/ssl.key b/vendor/swoole/examples/ssl/ssl_passwd/ssl.key new file mode 100755 index 0000000..38497de --- /dev/null +++ b/vendor/swoole/examples/ssl/ssl_passwd/ssl.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1B8CC4C05815AA64 + +i9kRuvTLN6Y329ctDI1Nt0oSRUXqRJo0omtGmLFPA7C8kRs8mwhvpo4G4m8Kh6pf +l2fVpaKKVXeQxyTdfgPKPxvGsTODp3ZHODLuKswwj0ERPrjfzsDvKboEYdooC7FF +3oYpy33I6XtA3qytkqP/gCCoF9zNaFSlHUGup7ZjEZCO4rEYZmbqtW6CPn9lMNCd +DgTl2oNa3t6wopQYRFg3uR8NUSeTjpy0fdWIU5GTWJAw7UEaHslnxeRJlwUHdoiY +nG37EJpDgAiDspbHfWN3sfRnRDtL0gcvFy8yzSJr/mzlIdhmuxkAvlHFQ7dtav0+ +VnaR32lNWWgJVUljnTsPPAAIpznVIaj1aXA32X/N12JWXkr2Pe64uSD0DPE8I9xM +l/n2kaSBiiZR7MIXw1wrbLGwN55qZlc9hURlWEE6vlxEz2LFfuMX9wpN/OZtiPpA +FdVz+0CojiLsjjBa1ayjinEW6ICPfOJFe8IhCEThF/O1bvkCuUK8edZBUd2JtChA +RN1BuX+AwaUryvf93xrqNJ0xxK5mOICCUQi8lYCl/n9bpCJ4HCqfsUiqd4tLy8GO +bXx22debalaoYIC3tBz26BY3HbZldDO7LQWvkxkAqK24T26NS/oLagWB8BmGHwwK +vi6L++VHFEvfmHNmltmpkM/wjsFw6m5jg8t0ETlYffJTJdlb/1r48/R0U/1dh8Oe +n5ymUXYs3KWGVKxZcC7nMzOwisyWI83tm3/Ifytbo1oX1Wk8UL0eQVPbcttAnKAO +543Fjs6tfhKUGiOSkvadYLOz08p3BlnXGLbbfdeOZ5b714guzdIHTg== +-----END RSA PRIVATE KEY----- diff --git a/vendor/swoole/examples/ssl/stream_client.php b/vendor/swoole/examples/ssl/stream_client.php new file mode 100755 index 0000000..ff66b79 --- /dev/null +++ b/vendor/swoole/examples/ssl/stream_client.php @@ -0,0 +1,25 @@ +<?php +$contextOptions = [ + 'ssl' => [ + 'verify_peer' => false, +// 'allow_self_signed' => true, +// 'cafile' => __DIR__.'/privkey.pem', + 'peer_name' => 'example.com', + ] +]; +$context = stream_context_create($contextOptions); + +$fp = stream_socket_client("ssl://127.0.0.1:9501", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context); +if (!$fp) +{ + die("Unable to connect: $errstr ($errno)"); +} + +stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_SSLv23_CLIENT); +$ret = fwrite($fp, "hello\n"); +var_dump($ret); + +$recv = fread($fp, 8192); +var_dump($recv); +echo "finish\n"; + diff --git a/vendor/swoole/examples/ssl/webserver.php b/vendor/swoole/examples/ssl/webserver.php new file mode 100755 index 0000000..a3f794a --- /dev/null +++ b/vendor/swoole/examples/ssl/webserver.php @@ -0,0 +1,30 @@ +<?php +//$serv = new swoole_http_server("0.0.0.0", 443, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$serv = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$serv->set([ + 'ssl_cert_file' => __DIR__ . '/ssl.crt', + 'ssl_key_file' => __DIR__ . '/ssl.key', + //'ssl_method' => SWOOLE_TLSv1_2_SERVER_METHOD, + 'worker_num' => 1, + 'open_http2_protocol' => true, + //'ssl_client_cert_file' => __DIR__ . '/ca.crt', + //'ssl_verify_depth' => 10, +]); +//c158354564362fcc + +$serv->on('Request', function(swoole_http_request $request, swoole_http_response $response) { + //var_dump($request->get); + //var_dump($request->post); + //var_dump($request->cookie); + //var_dump($request->files); +// var_dump($request->header); +// var_dump($request->server); + //global $serv; + //$info= $serv->getClientInfo($request->fd); + // var_dump($info); + //$response->cookie("User", "Swoole"); + //$response->header("X-Server", "Swoole"); + $response->end("<h1>Hello Swoole!</h1>\n"); +}); + +$serv->start(); diff --git a/vendor/swoole/examples/ssl/websocket_client.html b/vendor/swoole/examples/ssl/websocket_client.html new file mode 100755 index 0000000..adac9b2 --- /dev/null +++ b/vendor/swoole/examples/ssl/websocket_client.html @@ -0,0 +1,19 @@ +<script> +var wsServer = 'wss://localhost:9502'; +var websocket = new WebSocket(wsServer); +websocket.onopen = function (evt) { + console.log("Connected to WebSocket server."); +}; + +websocket.onclose = function (evt) { + console.log("Disconnected"); +}; + +websocket.onmessage = function (evt) { + console.log('Retrieved data from server: ' + evt.data); +}; + +websocket.onerror = function (evt, e) { + console.log('Error occured: ' + evt.data); +}; +</script> diff --git a/vendor/swoole/examples/ssl/websocket_server.php b/vendor/swoole/examples/ssl/websocket_server.php new file mode 100755 index 0000000..ec191a2 --- /dev/null +++ b/vendor/swoole/examples/ssl/websocket_server.php @@ -0,0 +1,42 @@ +<?php +$ssl_dir = realpath('../../tests/ssl'); +$serv = new swoole_websocket_server("0.0.0.0", 9502, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); +//$serv = new swoole_websocket_server("0.0.0.0", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$serv->set([ + 'ssl_cert_file' => $ssl_dir . '/ssl.crt', + 'ssl_key_file' => $ssl_dir . '/ssl.key', + 'worker_num' => 1, +]); + +$port = $serv->listen('127.0.0.1', 9501, SWOOLE_SOCK_TCP); +$port->on('receive', function($serv, $fd, $reactor_id, $data){ + var_dump($fd, $reactor_id, $data); + $serv->send($fd, "Swoole: $data"); +}); + +$serv->on('connect', function ($_server, $fd) { + echo "client {$fd} connect\n"; +}); + +$serv->on('open', function (swoole_websocket_server $_server, swoole_http_request $request) { + echo "server#{$_server->worker_pid}: handshake success with fd#{$request->fd}\n"; +// var_dump($request); +}); + +$serv->on('request', function ($req, $resp) { + $resp->end(file_get_contents(__DIR__.'/websocket_client.html')); +}); + +$serv->on('message', function (swoole_websocket_server $_server, $frame) { + var_dump($frame->data); + echo "received ".strlen($frame->data)." bytes\n"; + $_send = str_repeat('B', rand(100, 800)); + $_server->push($frame->fd, $_send); + // echo "#$i\tserver sent " . strlen($_send) . " byte \n"; +}); + +$serv->on('close', function ($_server, $fd) { + echo "client {$fd} closed\n"; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/swoole_http_client.php b/vendor/swoole/examples/swoole_http_client.php new file mode 100755 index 0000000..3b21681 --- /dev/null +++ b/vendor/swoole/examples/swoole_http_client.php @@ -0,0 +1,51 @@ +<?php +ini_set('display_errors',1); +//error_reporting(E_ALL); +error_reporting(0); +$http = new swoole_http_server("", 9501, SWOOLE_BASE); + +$http->set([ + //'worker_num' => 2, +]); +$i = 0; +$http->on('request', function ($request, swoole_http_response $response)use(&$i) { + + $route = $request->server['request_uri']; + if($route == '/info'){ + $response->end(json_encode($request)); + return; + } + + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->set([ + 'timeout' => 0.3, + 'keep_alive' => 1, + ]); + //post request + $cli->setData(http_build_query(['a'=>123,'b'=>"哈哈"])); + $cli->setHeaders(['User-Agent' => "swoole"]); + $cli->on('close', function($cli)use($response){ + // echo "close\n"; + }); + $cli->on('error', function($cli) use ($response){ + $response->end("error"); + }); + $cli->execute('/info', function($cli)use( $response, &$i){ + $cli->setHeaders(['User-Agent' => "swoole"]); + //get request + $cli->execute('/info', function($cli)use($response, &$i){ + $ret = json_encode($cli->headers) . "\nSERVER RESPONSE: ". $cli->body; + $response->end($ret); + $cli->close(); + }); + }); + + + if($i++ == 1000){ + echo "----->Mem: ", memory_get_usage(), "b\n"; + $i = 0; + } + +}); + +$http->start(); diff --git a/vendor/swoole/examples/table/array.php b/vendor/swoole/examples/table/array.php new file mode 100755 index 0000000..a2e7e36 --- /dev/null +++ b/vendor/swoole/examples/table/array.php @@ -0,0 +1,19 @@ +<?php +$table = new swoole_table(1024); +$table->column('id', swoole_table::TYPE_INT); +$table->column('name', swoole_table::TYPE_STRING, 64); +$table->column('num', swoole_table::TYPE_FLOAT); +$table->create(); + +$table['apple'] = array('id' => 145, 'name' => 'iPhone', 'num' => 3.1415); +$table['google'] = array('id' => 358, 'name' => "AlphaGo", 'num' => 3.1415); + +$table['microsoft']['name'] = "Windows"; +$table['microsoft']['num'] = '1997.03'; + +var_dump($table['apple']); +var_dump($table['microsoft']); + +$table['google']['num'] = 500.90; +var_dump($table['google']); + diff --git a/vendor/swoole/examples/table/iterator.php b/vendor/swoole/examples/table/iterator.php new file mode 100755 index 0000000..2f77712 --- /dev/null +++ b/vendor/swoole/examples/table/iterator.php @@ -0,0 +1,33 @@ +<?php +$table = new swoole_table(1024); +$table->column('name', swoole_table::TYPE_STRING, 64); +$table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8 +$table->column('num', swoole_table::TYPE_FLOAT); +$table->create(); + +$table->set('tianfenghan@qq.com', array('id' => 145, 'name' => 'rango1', 'num' => 3.1415)); +$table->set('350749960@qq.com', array('id' => 358, 'name' => "Rango2", 'num' => 3.1415)); +$table->set('hello@qq.com', array('id' => 189, 'name' => 'rango3', 'num' => 3.1415)); + +var_dump($table->get('350749960@qq.com')); +var_dump($table->get('350749960@qq.com', 'name')); + +foreach($table as $key => $value) +{ + var_dump($key, $value); +} + +echo "======================= Total Elements: {$table->count()} ============================\n"; +$table->del('350749960@qq.com'); // delete a exist element +foreach($table as $key => $value) +{ + var_dump($key, $value); +} +echo "======================= Total Elements: {$table->count()} ============================\n"; +$ret = $table->del('a invalid key'); // delete a invalid element +var_dump($ret); +foreach($table as $key => $value) +{ + var_dump($key, $value); +} +echo "======================= Total Elements: {$table->count()} ============================\n"; diff --git a/vendor/swoole/examples/table/server.php b/vendor/swoole/examples/table/server.php new file mode 100755 index 0000000..9bdd68f --- /dev/null +++ b/vendor/swoole/examples/table/server.php @@ -0,0 +1,52 @@ +<?php +$table = new swoole_table(1024); +$table->column('fd', swoole_table::TYPE_INT); +$table->column('from_id', swoole_table::TYPE_INT); +$table->column('data', swoole_table::TYPE_STRING, 64); +$table->create(); + +$serv = new swoole_server('127.0.0.1', 9501); +$serv->set(['dispatch_mode' => 1]); +$serv->table = $table; + +$serv->on('connect', function($serv, $fd, $from_id){ + $info = $serv->connection_info($fd); + $serv->send($fd, "INFO: fd=$fd, from_id=$from_id, addr={$info['remote_ip']}:{$info['remote_port']}\n"); +}); + +$serv->on('receive', function ($serv, $fd, $from_id, $data) { + + $cmd = explode(" ", trim($data)); + + //get + if ($cmd[0] == 'get') + { + //get self + if (count($cmd) < 2) + { + $cmd[1] = $fd; + } + $get_fd = intval($cmd[1]); + $info = $serv->table->get($get_fd); + $serv->send($fd, var_export($info, true)."\n"); + } + //set + elseif ($cmd[0] == 'set') + { + $ret = $serv->table->set($fd, array('from_id' => $data, 'fd' => $fd, 'data' => $cmd[1])); + if ($ret === false) + { + $serv->send($fd, "ERROR\n"); + } + else + { + $serv->send($fd, "OK\n"); + } + } + else + { + $serv->send($fd, "command error.\n"); + } +}); + +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/table/set.php b/vendor/swoole/examples/table/set.php new file mode 100755 index 0000000..b85a1f5 --- /dev/null +++ b/vendor/swoole/examples/table/set.php @@ -0,0 +1,48 @@ +<?php +$table = new swoole_table(1024); +$table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8 +$table->column('name', swoole_table::TYPE_STRING, 64); +$table->column('num', swoole_table::TYPE_FLOAT); +$table->create(); + +//$worker = new swoole_process('child1', false, false); +//$worker->start(); +// +//child +function child1($worker) +{ + global $table; + $s = microtime(true); + $table->set('tianfenghan@qq.com', array('id' => 145, 'name' => 'rango', 'num' => 3.1415)); + $table->set('350749960@qq.com', array('id' => 358, 'name' => "Rango1234", 'num' => 3.1415)); + $table->set('hello@qq.com', array('id' => 189, 'name' => 'rango3', 'num' => 3.1415)); + $table->set('tianfenghan@qq.com', array('id' => 145, 'name' => 'rango', 'num' => 3.1415)); + $table->set('350749960@qq.com', array('id' => 358, 'name' => "Rango1234", 'num' => 3.1415)); + echo "set - 5 use: ".((microtime(true) - $s) * 1000)."ms\n"; +} + +//master +sleep(1); + +child1(1245); +$s = microtime(true); +for($i =0; $i < 1000; $i++) +{ + $arr = $table->get('350749960@qq.com'); +} + +echo "get -5 use: ".((microtime(true) - $s) * 1000)."ms\n"; +$s = microtime(true); +//$table->incr('tianfenghan@qq.com', 'id', 5); +//$table->decr('hello@qq.com', 'num', 1.1); +$ret1 = $table->get('350749960@qq.com'); +$ret2 = $table->get('tianfenghan@qq.com'); +$ret3 = $table->get('350749960@qq.com'); +$ret4 = $table->get('tianfenghan@qq.com'); +$ret5 = $table->get('hello@qq.com'); + +echo "get -5 use: ".((microtime(true) - $s) * 1000)."ms\n"; +var_dump($ret1, $ret2, $ret3, $ret4, $ret5); +echo "id:".$ret1['id']."\n"; +echo "name:".$ret1['name']."\n"; +echo "num:".$ret1['num']."\n"; \ No newline at end of file diff --git a/vendor/swoole/examples/table/simulation.php b/vendor/swoole/examples/table/simulation.php new file mode 100755 index 0000000..17b0d94 --- /dev/null +++ b/vendor/swoole/examples/table/simulation.php @@ -0,0 +1,20 @@ +<?php +/** + * The script is used for simulating the usage of swoole_table() and guaranting its usability. + */ +$table = new swoole_table(1024); +$table->column('name', swoole_table::TYPE_STRING, 64); +$table->column('id', swoole_table::TYPE_INT, 4); //1,2,4,8 +$table->column('num', swoole_table::TYPE_FLOAT); +$table->create(); + +while (true) { + $i = rand(1, 1000); + $if = rand(0,1); + if ($if) { + $table->set($i, ['id' => $i, 'name' => $i, 'num' => $i]); + } else { + $table->del($i); + } + var_dump('count ' . $table->count()); +} diff --git a/vendor/swoole/examples/task/http.php b/vendor/swoole/examples/task/http.php new file mode 100755 index 0000000..0cf3a8f --- /dev/null +++ b/vendor/swoole/examples/task/http.php @@ -0,0 +1,49 @@ +<?php +$serv = new swoole_http_server("127.0.0.1", 9501); +$serv->set(array( + 'worker_num' => 1, + 'task_worker_num' => 1, +// 'task_ipc_mode' => 3, +// 'message_queue_key' => 0x70001001, + //'task_tmpdir' => '/data/task/', +)); + +$serv->on('Request', function ($req, $resp) +{ + $data = str_repeat('A', 8192 * 10); + global $serv; + + $serv->task(array($data, 1000), -1, function ($serv, $task_id, $data) use ($resp) + { + $resp->end("Task#$task_id finished." . PHP_EOL); + }); + +}); +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + //echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; +// $serv->finish($data); + return $data; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('workerStart', function($serv, $worker_id) { + global $argv; + if ($serv->taskworker) + { + swoole_set_process_name("php {$argv[0]}: task_worker"); + } + else + { + swoole_set_process_name("php {$argv[0]}: worker"); + } +}); + +$serv->on('workerStop', function (swoole_server $serv, $id) { + echo "stop\n"; + var_dump($id); +}); + +$serv->start(); diff --git a/vendor/swoole/examples/task/msg_push.php b/vendor/swoole/examples/task/msg_push.php new file mode 100755 index 0000000..b9189e9 --- /dev/null +++ b/vendor/swoole/examples/task/msg_push.php @@ -0,0 +1,74 @@ +<?php + + +echo "Sending text to msg queue.\n"; + +class SwooleTask +{ + protected $queueId; + protected $workerId; + protected $taskId = 0; + + function __construct($key, $workerId = 0) + { + $this->queueId = msg_get_queue($key); + if ($this->queueId === false) + { + throw new \Swoole\Exception("msg_get_queue() failed."); + } + $this->workerId = $workerId; + } + + protected function pack($data) + { + $fromFd = 0; + $type = 7; + if (!is_string($data)) + { + $data = serialize($data); + $fromFd |= 2; + } + if (strlen($data) >= 8180) + { + $tmpFile = tempnam('/tmp/', 'swoole.task'); + file_put_contents($tmpFile, $data); + $data = pack('l', strlen($data)) . $tmpFile . "\0"; + $fromFd |= 1; + $len = 128 + 24; + } + else + { + $len = strlen($data); + } + //typedef struct _swDataHead + //{ + // int fd; + // uint16_t len; + // int16_t from_id; + // uint8_t type; + // uint8_t flags; + // uint16_t from_fd; + //} swDataHead; + return pack('lSsCCS', $this->taskId++, $len, $this->workerId, $type, 0, $fromFd) . $data; + } + + function dispatch($data) + { + if (!msg_send($this->queueId, $this->workerId + 1, $this->pack($data), false)) + { + return false; + } + else + { + return true; + } + } +} + +$task = new SwooleTask(0x70001001); +//普通字符串 +$task->dispatch("Hello from PHP!"); +//数组 +$task->dispatch(array('data' => str_repeat('A', 1024), 'type' => 1)); +//大包 +$task->dispatch(array('data' => str_repeat('B', 1024 * 32), 'type' => 2)); \ No newline at end of file diff --git a/vendor/swoole/examples/task/shared_client.php b/vendor/swoole/examples/task/shared_client.php new file mode 100755 index 0000000..c934ed8 --- /dev/null +++ b/vendor/swoole/examples/task/shared_client.php @@ -0,0 +1,37 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); +if(!$client->connect('127.0.0.1', 9501)) +{ + exit("connect failed\n"); +} +function help() +{ + echo "get eg: php ".__FILE__." get key".PHP_EOL; + echo "set eg: php ".__FILE__." set key value".PHP_EOL; + echo "del eg: php ".__FILE__." del key".PHP_EOL; + echo "task eg: php ".__FILE__." task key".PHP_EOL; + exit(); +} +if($argc < 3) { + help(); +} +$keys = array( + 1 => 'cmd', + 2 => 'key', + 3 => 'val' +); +$sends = array(); +foreach ($keys as $i => $key) +{ + if (isset($argv[$i])) + { + $sends[$key] = $argv[$i]; + } +} +if (empty($sends)) +{ + help(); +} +$client->send(serialize($sends)); +$data = $client->recv(); +echo $data . PHP_EOL; \ No newline at end of file diff --git a/vendor/swoole/examples/task/shared_server.php b/vendor/swoole/examples/task/shared_server.php new file mode 100755 index 0000000..1f2b225 --- /dev/null +++ b/vendor/swoole/examples/task/shared_server.php @@ -0,0 +1,142 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); + +$serv->set(array( + 'worker_num' => 1, + //'open_eof_check' => true, + //'package_eof' => "\r\n", + 'task_worker_num' => 1, + //'dispatch_mode' => 2, + //'daemonize' => 1, + //'heartbeat_idle_time' => 5, + //'heartbeat_check_interval' => 5, +)); +function my_onStart($serv) +{ + echo "MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}\n"; + echo "Server: start.Swoole version is [".SWOOLE_VERSION."]\n"; + //$serv->addtimer(1000); +} + +function my_onShutdown($serv) +{ + echo "Server: onShutdown\n"; +} + +function my_onTimer($serv, $interval) +{ + echo "Server:Timer Call.Interval=$interval\n"; +} + +function my_onClose($serv, $fd, $from_id) +{ + //echo "Client: fd=$fd is closed.\n"; +} + +function my_onConnect($serv, $fd, $from_id) +{ + //throw new Exception("hello world"); +// echo "Client:Connect.\n"; +} + +function my_onWorkerStart($serv, $worker_id) +{ + global $argv; + if ($worker_id >= $serv->setting['worker_num']) { + swoole_set_process_name("php {$argv[0]} task worker"); + } else { + swoole_set_process_name("php {$argv[0]} event worker"); + } + //echo "WorkerStart|MasterPid={$serv->master_pid}|Manager_pid={$serv->manager_pid}|WorkerId=$worker_id\n"; + //$serv->addtimer(500); //500ms +} + +function my_onWorkerStop($serv, $worker_id) +{ + echo "WorkerStop[$worker_id]|pid=".posix_getpid().".\n"; +} + +function my_onReceive(swoole_server $serv, $fd, $from_id, $rdata) +{ + $data = unserialize($rdata); + if (isset($data['cmd'])) + { + switch ($data['cmd']) + { + case 'get': + $s = microtime(true); + $res = $serv->taskwait($data, 0.5, 0); + echo "use " . ((microtime(true) - $s) * 1000) . "ms\n"; + $serv->send($fd, PHP_EOL . "get " . $res['key'] . ": " . $res['val']); + break; + case "set": + $serv->task($data, 0); + $serv->send($fd, "OK\n"); + break; + case "del": + $serv->task($data, 0); + break; + case "reload": + break; + default: + echo "server:" . $data . PHP_EOL; + } + } +} + +function my_onTask(swoole_server $serv, $task_id, $from_id, $data) +{ + static $datas = array(); + if (isset($data['cmd'])) + { + switch ($data['cmd']) { + case 'get': + $key = $data['key']; + $val = isset($datas[$key]) ? $datas[$key] : ""; + $serv->finish(array('key'=>$key, 'val' => $val)); + break; + case "set": + $key = $data['key']; + $val = $data['val']."_".$from_id; + $datas[$key] = $val; + return; + break; + case "del": + $key = $data['key']; + if(isset($datas[$key])) { + unset($datas[$key]); + } + break; + case "task": + $key = $data['key']; + echo "Do task " . $key . PHP_EOL; + break; + } + } + echo "AsyncTask[PID=".posix_getpid()."]: task_id=$task_id.".PHP_EOL; + // $serv->finish("OK"); +} + +function my_onFinish(swoole_server $serv, $task_id, $from_worker_id, $data) +{ + echo "AsyncTask Finish: Connect.PID=" . posix_getpid() . PHP_EOL; +} + +function my_onWorkerError(swoole_server $serv, $worker_id, $worker_pid, $exit_code) +{ + echo "worker abnormal exit. WorkerId=$worker_id|Pid=$worker_pid|ExitCode=$exit_code\n"; +} + +$serv->on('Start', 'my_onStart'); +$serv->on('Connect', 'my_onConnect'); +$serv->on('Receive', 'my_onReceive'); +$serv->on('Close', 'my_onClose'); +$serv->on('Shutdown', 'my_onShutdown'); +$serv->on('Timer', 'my_onTimer'); +$serv->on('WorkerStart', 'my_onWorkerStart'); +$serv->on('WorkerStop', 'my_onWorkerStop'); +$serv->on('Task', 'my_onTask'); +$serv->on('Finish', 'my_onFinish'); +$serv->on('WorkerError', 'my_onWorkerError'); +$serv->start(); + diff --git a/vendor/swoole/examples/task/task.php b/vendor/swoole/examples/task/task.php new file mode 100755 index 0000000..eb152bd --- /dev/null +++ b/vendor/swoole/examples/task/task.php @@ -0,0 +1,50 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501,SWOOLE_BASE); + +$serv->set(array( + //'worker_num' => 1, + 'task_worker_num' => 1, +// 'task_ipc_mode' => 3, +// 'message_queue_key' => 0x70001001, + //'task_tmpdir' => '/data/task/', +)); + +$serv->on('Receive', function(swoole_server $serv, $fd, $from_id, $data) { + //AsyncTask + $data = trim($data); + //$data = str_repeat('A', 8192*100); +// if ($data == 'async') + if(false) +// if (true) + { + $task_id = $serv->task($data, 0); + $serv->send($fd, "Dispath AsyncTask: id=$task_id\n"); + } + //Sync Task + else + { + $res = $serv->taskwait($data, 10); + echo "Dispath SyncTask: result=".$res.PHP_EOL; + } + //$serv->send($fd, "OK\n"); +}); +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; + $serv->finish($data); +// return $data; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('workerStart', function($serv, $worker_id) { + global $argv; + if($worker_id >= $serv->setting['worker_num']) { + swoole_set_process_name("php {$argv[0]}: task_worker"); + } else { + swoole_set_process_name("php {$argv[0]}: worker"); + } +}); + +$serv->start(); diff --git a/vendor/swoole/examples/task/task_coro.php b/vendor/swoole/examples/task/task_coro.php new file mode 100755 index 0000000..91953e3 --- /dev/null +++ b/vendor/swoole/examples/task/task_coro.php @@ -0,0 +1,42 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); +$serv->set(array( + 'worker_num' => 1, + 'task_worker_num' => 4, + //'task_tmpdir' => '/data/task/', +)); + +$serv->on('Receive', function(swoole_server $serv, $fd, $from_id, $data) { + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + //等待所有Task结果返回,超时为10s + var_dump($tasks); + $results = $serv->taskWaitMulti($tasks, 2); + var_dump($results); +}); + +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "onTask: [ID={$serv->worker_id}]: task_id=$task_id, data=$data, data_len=".strlen($data).".".PHP_EOL; + //测试超时 + if ($serv->worker_id % 4 == 3) + { + sleep(3); + } + elseif ($serv->worker_id % 4 == 2) + { + usleep(1500000); + } + elseif ($serv->worker_id % 4 == 1) + { + usleep(200000); + } + return "hello world.[{$data}]"; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/task/task_num.php b/vendor/swoole/examples/task/task_num.php new file mode 100755 index 0000000..157a9ab --- /dev/null +++ b/vendor/swoole/examples/task/task_num.php @@ -0,0 +1,46 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501); +$serv->set(array( + 'worker_num' => 1, + 'task_worker_num' => 2, + //'task_tmpdir' => '/data/task/', +)); + +$serv->on('Receive', function(swoole_server $serv, $fd, $from_id, $data) { + //AsyncTask + $data = intval($data); + for($i=0;$i<$data;$i++) { + $tid = mt_rand(0,1); + echo "data:{$i} to task: {$tid} ".PHP_EOL; + $serv->task($i, $tid); + } + +}); +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "onTask: [PID=".posix_getpid()."]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; + sleep(10); + //$serv->finish($data); + echo 'finish'.PHP_EOL; + return; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('Timer', function(swoole_server $serv, $time) { + echo "{$time} call".PHP_EOL; + print_r($serv->stats()); +}); + +$serv->on('workerStart', function($serv, $worker_id) { + global $argv; + if($worker_id >= $serv->setting['worker_num']) { + swoole_set_process_name("php {$argv[0]}: task_worker"); + } else { + $serv->addtimer(5000); + swoole_set_process_name("php {$argv[0]}: worker"); + } + +}); +$serv->start(); diff --git a/vendor/swoole/examples/task/task_queue.php b/vendor/swoole/examples/task/task_queue.php new file mode 100755 index 0000000..0b82c54 --- /dev/null +++ b/vendor/swoole/examples/task/task_queue.php @@ -0,0 +1,33 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + +$serv->set(array( + //'worker_num' => 1, + 'task_worker_num' => 4, + 'task_ipc_mode' => 3, + 'message_queue_key' => 0x70001001, + 'task_tmpdir' => '/data/task/', +)); + +$serv->on('Receive', function(swoole_server $serv, $fd, $from_id, $data) { +}); + +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: TASK_ID=$task_id]\n"; + var_dump($data); +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('workerStart', function($serv, $worker_id) { + global $argv; + if($worker_id >= $serv->setting['worker_num']) { + swoole_set_process_name("php {$argv[0]}: task_worker"); + } else { + swoole_set_process_name("php {$argv[0]}: worker"); + } +}); + +$serv->start(); diff --git a/vendor/swoole/examples/task/task_stream.php b/vendor/swoole/examples/task/task_stream.php new file mode 100755 index 0000000..4f0e45d --- /dev/null +++ b/vendor/swoole/examples/task/task_stream.php @@ -0,0 +1,53 @@ +<?php +$serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + +$serv->set(array( + 'worker_num' => 1, + 'task_worker_num' => 1, + 'task_ipc_mode' => 4, +// 'message_queue_key' => 0x70001001, +)); + +$serv->on('Receive', function(swoole_server $serv, $fd, $from_id, $data) { + //AsyncTask + $data = trim($data); + //$data = str_repeat('A', 8192*100); +// if ($data == 'async') +// if(false) + if (true) + { + $task_id = $serv->task($data, 0); + $serv->send($fd, "Dispath AsyncTask: id=$task_id\n"); + } + //Sync Task + else + { + $res = $serv->taskwait($data, 10); + echo "Dispath SyncTask: result=".$res.PHP_EOL; + } + //$serv->send($fd, "OK\n"); +}); +$serv->on('Task', function (swoole_server $serv, $task_id, $from_id, $data) { + echo "#{$serv->worker_id}\tonTask: [PID={$serv->worker_pid}]: task_id=$task_id, data_len=".strlen($data).".".PHP_EOL; + $serv->finish($data); + return $data; +}); + +$serv->on('Finish', function (swoole_server $serv, $task_id, $data) { + echo "Task#$task_id finished, data_len=".strlen($data).PHP_EOL; +}); + +$serv->on('workerStart', function($serv, $worker_id) { + global $argv; + if ($serv->taskworker) + { + swoole_set_process_name("php {$argv[0]}: task_worker"); + } + else + { + swoole_set_process_name("php {$argv[0]}: worker"); + } + echo "Worker#$worker_id, pid=".posix_getpid()." start".PHP_EOL; +}); + +$serv->start(); diff --git a/vendor/swoole/examples/test.jpg b/vendor/swoole/examples/test.jpg new file mode 100755 index 0000000..0f8cc71 Binary files /dev/null and b/vendor/swoole/examples/test.jpg differ diff --git a/vendor/swoole/examples/test_buffer.php b/vendor/swoole/examples/test_buffer.php new file mode 100755 index 0000000..ef10abf --- /dev/null +++ b/vendor/swoole/examples/test_buffer.php @@ -0,0 +1,39 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_TCP); //同步阻塞 +if(empty($argv[1])) +{ + $loop = 1; +} +else +{ + $loop = intval($argv[1]); +} + +$_s = microtime(true); +if(!$client->connect('127.0.0.1', 9501)) +{ + exit("connect fail\n"); +} + +for($i=0; $i<$loop; $i++) +{ + $client->send(str_repeat("A", 8000).$i."[0]"); + //$client->send(str_repeat("A", 20).$i."[1]"); + //$client->send(str_repeat("A", 30).$i."[2]"); + //$ret = $client->send("GET / HTTP/1.1\r\n"); + //$client->send("Host: localhost\r\n"); + //$client->send("Connection: keep-alive\r\n"); + $client->send("\r\n\r\n"); + + //$data = $client->recv(1024, 0); + //if($data === false) + //{ + // echo "#{$i} recv fail.break\n"; +// break; +// } + //echo "recv[$i]",$data,"\n"; +} + +sleep(1000); +echo "$i: ",$data,"\n"; +echo "test ok. use".((microtime(true) - $_s)*1000)."ms\n"; diff --git a/vendor/swoole/examples/test_server.c b/vendor/swoole/examples/test_server.c new file mode 100755 index 0000000..4dcd190 --- /dev/null +++ b/vendor/swoole/examples/test_server.c @@ -0,0 +1,212 @@ +/** + * cmake . + * make test_server + * ./bin/test_server + */ +#include "Server.h" + +int my_onPacket(swServer *serv, swEventData *req); +int my_onReceive(swServer *serv, swEventData *req); +void my_onStart(swServer *serv); +void my_onShutdown(swServer *serv); +void my_onConnect(swServer *serv, swDataHead *info); +void my_onClose(swServer *serv, swDataHead *info); +void my_onWorkerStart(swServer *serv, int worker_id); +void my_onWorkerStop(swServer *serv, int worker_id); + +static int g_receive_count = 0; + +int main(int argc, char **argv) +{ + int ret; + swServer serv; + swServer_init(&serv); //初始化 + + serv.reactor_num = 4; //reactor线程数量 + serv.worker_num = 2; //worker进程数量 + + serv.factory_mode = SW_MODE_BASE; + //serv.factory_mode = SW_MODE_SINGLE; //SW_MODE_PROCESS/SW_MODE_THREAD/SW_MODE_BASE/SW_MODE_SINGLE + serv.max_connection = 10000; + //serv.open_cpu_affinity = 1; + //serv.open_tcp_nodelay = 1; + //serv.daemonize = 1; +// memcpy(serv.log_file, SW_STRL("/tmp/swoole.log")); //日志 + + serv.dispatch_mode = 2; +// serv.open_tcp_keepalive = 1; + +#ifdef HAVE_OPENSSL + //serv.ssl_cert_file = "tests/ssl/ssl.crt"; + //serv.ssl_key_file = "tests/ssl/ssl.key"; + //serv.open_ssl = 1; +#endif + + serv.onStart = my_onStart; + serv.onShutdown = my_onShutdown; + serv.onConnect = my_onConnect; + serv.onReceive = my_onReceive; + serv.onPacket = my_onPacket; + serv.onClose = my_onClose; + serv.onWorkerStart = my_onWorkerStart; + serv.onWorkerStop = my_onWorkerStop; + +// swSignal_add(SIGINT, user_signal); + + //create Server + ret = swServer_create(&serv); + if (ret < 0) + { + swTrace("create server fail[error=%d].\n", ret); + exit(0); + } + + swListenPort *port = swServer_add_port(&serv, SW_SOCK_TCP, "127.0.0.1", 9501); + port->open_eof_check = 0; + //config + port->backlog = 128; + memcpy(port->protocol.package_eof, SW_STRL("\r\n\r\n") - 1); //开启eof检测,启用buffer区 + + swServer_add_port(&serv, SW_SOCK_UDP, "0.0.0.0", 9502); + swServer_add_port(&serv, SW_SOCK_TCP6, "::", 9503); + swServer_add_port(&serv, SW_SOCK_UDP6, "::", 9504); + + ret = swServer_start(&serv); + if (ret < 0) + { + swTrace("start server fail[error=%d].\n", ret); + exit(0); + } + return 0; +} + +void my_onWorkerStart(swServer *serv, int worker_id) +{ + printf("WorkerStart[%d]PID=%d\n", worker_id, getpid()); +} + +void my_onWorkerStop(swServer *serv, int worker_id) +{ + printf("WorkerStop[%d]PID=%d\n", worker_id, getpid()); +} + +int my_onReceive(swServer *serv, swEventData *req) +{ + int ret; + char resp_data[SW_BUFFER_SIZE]; + + g_receive_count++; + + swConnection *conn = swWorker_get_connection(serv, req->info.fd); + swoole_rtrim(req->data, req->info.len); + printf("onReceive[%d]: ip=%s|port=%d Data=%s|Len=%d\n", g_receive_count, swConnection_get_ip(conn), + swConnection_get_port(conn), req->data, req->info.len); + + int n = snprintf(resp_data, SW_BUFFER_SIZE, "Server: %*s\n", req->info.len, req->data); + ret = serv->send(serv, req->info.fd, resp_data, n); + if (ret < 0) + { + printf("send to client fail. errno=%d\n", errno); + } + else + { + printf("send %d bytes to client success. data=%s\n", n, resp_data); + } + return SW_OK; +} + +int my_onPacket(swServer *serv, swEventData *req) +{ + swDgramPacket *packet; + + swString *buffer = swWorker_get_buffer(serv, req->info.from_id); + packet = (swDgramPacket*) buffer->str; + + int serv_sock = req->info.from_fd; + char *data; + int length; + char address[256]; + int port = 0; + int ret; + + //udp ipv4 + if (req->info.type == SW_EVENT_UDP) + { + struct in_addr sin_addr; + sin_addr.s_addr = packet->addr.v4.s_addr; + char *tmp = inet_ntoa(sin_addr); + memcpy(address, tmp, strlen(tmp)); + data = packet->data; + length = packet->length; + port = packet->port; + } + //udp ipv6 + else if (req->info.type == SW_EVENT_UDP6) + { + inet_ntop(AF_INET6, &packet->addr.v6, address, sizeof(address)); + data = packet->data; + length = packet->length; + port = packet->port; + } + //unix dgram + else if (req->info.type == SW_EVENT_UNIX_DGRAM) + { + memcpy(address, packet->data, packet->addr.un.path_length); + data = packet->data + packet->addr.un.path_length; + length = packet->length - packet->addr.un.path_length; + } + + printf("Packet[client=%s:%d, %d bytes]: data=%*s\n", address, port, length, length, data); + + char resp_data[SW_BUFFER_SIZE]; + int n = snprintf(resp_data, SW_BUFFER_SIZE, "Server: %*s", length, data); + + //udp ipv4 + if (req->info.type == SW_EVENT_UDP) + { + ret = swSocket_udp_sendto(serv_sock, address, port, resp_data, n); + } + //udp ipv6 + else if (req->info.type == SW_EVENT_UDP6) + { + ret = swSocket_udp_sendto6(serv_sock, address, port, resp_data, n); + } + //unix dgram + else if (req->info.type == SW_EVENT_UNIX_DGRAM) + { + memcpy(address, packet->data, packet->addr.un.path_length); + data = packet->data + packet->addr.un.path_length; + length = packet->length - packet->addr.un.path_length; + } + + if (ret < 0) + { + printf("send to client fail. errno=%d\n", errno); + } + else + { + printf("send %d bytes to client success. data=%s\n", n, resp_data); + } + + return SW_OK; +} + +void my_onStart(swServer *serv) +{ + sw_log("Server is running"); +} + +void my_onShutdown(swServer *serv) +{ + sw_log("Server is shutdown\n"); +} + +void my_onConnect(swServer *serv, swDataHead *info) +{ + printf("PID=%d\tConnect fd=%d|from_id=%d\n", getpid(), info->fd, info->from_id); +} + +void my_onClose(swServer *serv, swDataHead *info) +{ + printf("PID=%d\tClose fd=%d|from_id=%d\n", getpid(), info->fd, info->from_id); +} diff --git a/vendor/swoole/examples/timer/after.php b/vendor/swoole/examples/timer/after.php new file mode 100755 index 0000000..eca3d5c --- /dev/null +++ b/vendor/swoole/examples/timer/after.php @@ -0,0 +1,27 @@ +<?php +function timeout($tm) +{ + echo time() . ": Timeout #$tm\n"; + if ($tm == 5) + { + swoole_timer_after(3000, 'timeout', 7); + } +} + +$timer1 = swoole_timer_after(1000, function () { + timeout(1); + global $timer1, $timer3; + swoole_timer_clear($timer1); + swoole_timer_clear($timer3); +}); + +$timer2 = swoole_timer_after(2000, 'timeout', 2); +$timer3 = swoole_timer_after(4000, 'timeout', 3); +$timer4 = swoole_timer_after(8000, 'timeout', 4); +$timer5 = swoole_timer_after(10000, 'timeout', 5); +$timer6 = swoole_timer_after(5000, 'timeout', 6); +var_dump($timer1, $timer2, $timer3, $timer4, $timer5, $timer6); + +swoole_process::signal(SIGTERM, function() { + swoole_event_exit(); +}); diff --git a/vendor/swoole/examples/timer/clear.php b/vendor/swoole/examples/timer/clear.php new file mode 100755 index 0000000..cb112cc --- /dev/null +++ b/vendor/swoole/examples/timer/clear.php @@ -0,0 +1,10 @@ +<?php +$tm1 = swoole_timer_tick(1000, function () { + echo "tick 1000ms. \n"; +}); + +swoole_timer_tick(3000, function ($id) use ($tm1) { + echo "tick , clear\n"; + swoole_timer_clear($id); + swoole_timer_clear($tm1); +}); diff --git a/vendor/swoole/examples/timer/enable_coroutine.php b/vendor/swoole/examples/timer/enable_coroutine.php new file mode 100755 index 0000000..e19e1c9 --- /dev/null +++ b/vendor/swoole/examples/timer/enable_coroutine.php @@ -0,0 +1,9 @@ +<?php +swoole_async_set([ + 'enable_coroutine' => false +]); +swoole_timer_tick(1000, function () { + $uid = Co::getuid(); + assert($uid === -1); + echo "#{$uid}\n"; +}); \ No newline at end of file diff --git a/vendor/swoole/examples/timer/tick.php b/vendor/swoole/examples/timer/tick.php new file mode 100755 index 0000000..430a34b --- /dev/null +++ b/vendor/swoole/examples/timer/tick.php @@ -0,0 +1,23 @@ +<?php +function timeout($tm) +{ + echo time() . ": Timeout #$tm\n"; +} +$timer1 = swoole_timer_tick(1000, 'timeout', 1); +$timer2 = swoole_timer_tick(2000, 'timeout', 2); + +swoole_timer_tick(3000, function($id) { + timeout($id); + //swoole_timer_clear($id); + static $remove = true; + if ($remove) { + global $timer1; + swoole_timer_clear($timer1); + swoole_timer_tick(7000, 'timeout', 7); + $remove = false; + } +}); + +$timer4 = swoole_timer_tick(4000, 'timeout', 4); +$timer5 = swoole_timer_tick(5000, 'timeout', 5); +$timer6 = swoole_timer_tick(6000, 'timeout', 6); diff --git a/vendor/swoole/examples/udp/async_client.php b/vendor/swoole/examples/udp/async_client.php new file mode 100755 index 0000000..33855fe --- /dev/null +++ b/vendor/swoole/examples/udp/async_client.php @@ -0,0 +1,23 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); //异步非阻塞 + +$client->on("connect", function(swoole_client $cli) { + echo "connected\n"; + $cli->send("hello world\n"); +}); + +$client->on('close', function($cli){ + echo "closed\n"; +}); + +$client->on('error', function($cli){ + echo "error\n"; +}); + +$client->on("receive", function(swoole_client $cli, $data){ + echo "received: $data\n"; + sleep(1); + $cli->send("hello_".rand(1000,9999)); +}); + +$client->connect('127.0.0.1', 9502, 0.5); diff --git a/vendor/swoole/examples/udp/client.php b/vendor/swoole/examples/udp/client.php new file mode 100755 index 0000000..7f04980 --- /dev/null +++ b/vendor/swoole/examples/udp/client.php @@ -0,0 +1,6 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC); +$client->connect('127.0.0.1', 9905); +$client->send(serialize(['hello' => str_repeat('A', 600), 'rand' => rand(1, 100)])); +echo $client->recv() . "\n"; +sleep(1); diff --git a/vendor/swoole/examples/udp/server.php b/vendor/swoole/examples/udp/server.php new file mode 100755 index 0000000..eb5ca83 --- /dev/null +++ b/vendor/swoole/examples/udp/server.php @@ -0,0 +1,14 @@ +<?php +$server = new swoole_server('0.0.0.0', 9905, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); +for ($i = 0; $i < 20; $i++) +{ + $server->listen('0.0.0.0', 9906 + $i, SWOOLE_SOCK_UDP); +} +$server->set(['worker_num' => 4]); + +$server->on('Packet', function (swoole_server $serv, $data, $addr) +{ + $serv->sendto($addr['address'], $addr['port'], "Swoole: $data", $addr['server_socket']); +}); + +$server->start(); diff --git a/vendor/swoole/examples/unixsock/async_client.php b/vendor/swoole/examples/unixsock/async_client.php new file mode 100755 index 0000000..c1f3955 --- /dev/null +++ b/vendor/swoole/examples/unixsock/async_client.php @@ -0,0 +1,28 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UNIX_STREAM, SWOOLE_SOCK_ASYNC); + +$client->on("connect", function (swoole_client $cli) +{ + $cli->send("GET / HTTP/1.1\r\n\r\n"); +}); + +$client->on("receive", function (swoole_client $cli, $data) +{ + echo "Receive: $data"; + $cli->send(str_repeat('A', 100) . "\n"); +}); + +$client->on("error", function (swoole_client $cli) +{ + echo "error: [" . $cli->errCode . "] " . socket_strerror($cli->errCode) . "\n"; +}); + +$client->on("close", function (swoole_client $cli) +{ + echo "Connection close\n"; +}); + +$client->connect(__DIR__ . '/svr.sock', 0, -1); + +swoole_event_wait(); +echo "exit\n"; diff --git a/vendor/swoole/examples/unixsock/dgram_client.php b/vendor/swoole/examples/unixsock/dgram_client.php new file mode 100755 index 0000000..c631c53 --- /dev/null +++ b/vendor/swoole/examples/unixsock/dgram_client.php @@ -0,0 +1,12 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_SYNC); +if (!$client->connect(__DIR__ . '/svr.sock', 0, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +$client->send("hello world\n"); +echo $client->recv(); +$client->close(); + +sleep(1); \ No newline at end of file diff --git a/vendor/swoole/examples/unixsock/dgram_server.php b/vendor/swoole/examples/unixsock/dgram_server.php new file mode 100755 index 0000000..8f63e75 --- /dev/null +++ b/vendor/swoole/examples/unixsock/dgram_server.php @@ -0,0 +1,20 @@ +<?php +$serv = new swoole_server(__DIR__."/svr.sock", 9501, SWOOLE_PROCESS, SWOOLE_UNIX_DGRAM); +$serv->set(array( + //'tcp_defer_accept' => 5, + 'worker_num' => 1, + //'daemonize' => true, + //'log_file' => '/tmp/swoole.log' +)); +//$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) { +// echo "[#".posix_getpid()."]\tClient[$fd]: $data\n"; +// $serv->send($fd, json_encode(array("hello" => $data, "from" => $from_id)).PHP_EOL); +//}); + +$serv->on('Packet', function (swoole_server $serv, $data, $addr) { + //echo "[#".posix_getpid()."]\tClient[{$addr['address']}]: $data\n"; + var_dump($addr); + $serv->send($addr['address'], json_encode(array("hello" => $data, "addr" => $addr)).PHP_EOL); +}); + +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/unixsock/stream_client.php b/vendor/swoole/examples/unixsock/stream_client.php new file mode 100755 index 0000000..a16fcf5 --- /dev/null +++ b/vendor/swoole/examples/unixsock/stream_client.php @@ -0,0 +1,12 @@ +<?php +$client = new swoole_client(SWOOLE_SOCK_UNIX_STREAM, SWOOLE_SOCK_SYNC); +if (!$client->connect(__DIR__.'/svr.sock', 0, -1)) +{ + exit("connect failed. Error: {$client->errCode}\n"); +} + +$client->send("hello world\n"); +echo $client->recv(); +$client->close(); + +sleep(1); diff --git a/vendor/swoole/examples/unixsock/stream_server.php b/vendor/swoole/examples/unixsock/stream_server.php new file mode 100755 index 0000000..71f0ff2 --- /dev/null +++ b/vendor/swoole/examples/unixsock/stream_server.php @@ -0,0 +1,28 @@ +<?php +$serv = new swoole_server(__DIR__."/svr.sock", 9501, SWOOLE_BASE, SWOOLE_SOCK_UNIX_STREAM); +$serv->set(array( + //'tcp_defer_accept' => 5, + 'worker_num' => 1, + //'daemonize' => true, + //'log_file' => '/tmp/swoole.log' +)); + +$serv->on('start', function($serv){ + chmod($serv->host, 0777); +}); + +$serv->on('Connect', function($serv, $fd, $reactorId) { + echo "Connect, client={$fd}\n"; +}); + +$serv->on('Close', function($serv, $fd, $reactorId) { + echo "Close, client={$fd}\n"; +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) +{ + echo "[#" . posix_getpid() . "]\tClient[$fd]: $data\n"; + $serv->send($fd, json_encode(array("hello" => $data, "from" => $from_id)) . PHP_EOL); +}); + +$serv->start(); \ No newline at end of file diff --git a/vendor/swoole/examples/version.php b/vendor/swoole/examples/version.php new file mode 100755 index 0000000..a08a2ba --- /dev/null +++ b/vendor/swoole/examples/version.php @@ -0,0 +1,4 @@ +<?php +echo SWOOLE_VERSION,"\n"; +echo swoole_version(); +?> diff --git a/vendor/swoole/examples/weather_server.php b/vendor/swoole/examples/weather_server.php new file mode 100755 index 0000000..c7ce1a3 --- /dev/null +++ b/vendor/swoole/examples/weather_server.php @@ -0,0 +1,201 @@ +<?php +error_reporting(E_ALL); +ini_set('display_errors', '1'); +ini_set('memory_limit', '-1'); + +class HttpServ +{ + public $http; + public $setting = array(); + + public function __construct() + { + + } + + public function set($setting) + { + $this->setting = $setting; + } + + public function init() + { + + $this->http = new swoole_http_server($this->setting['host'], $this->setting['port'], SWOOLE_BASE); + $this->http->set($this->setting); + //register_shutdown_function('handleFatal'); + $this->http->on('request', function ($request, $response) + { + if ($request->server['request_uri'] == '/favicon.ico') + { + $response->status(404); + $response->end('Not Found'); + return; + } + $this->getResult($response); + }); + } + + function getResult2($response) + { + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->on('connect', function ($cli) + { + echo "cli1 connect\n"; + $cli->send("hello world\n"); + }); + + $client->on('Receive', function ($cli, $data) use ($response) + { + echo "cli1 receive\n"; + $response->end($data); + $cli->close(); + }); + + $client->on("error", function ($cli) use ($response) + { + echo "cli1 error\n"; + $response->end("empty\n"); + }); + + $client->on("close", function ($cli) + { + echo "cli1 close\n"; + }); + $client->connect('127.0.0.1', 9501); + } + + function getResult5($response) + { + swoole_async_dns_lookup("weather.gtimg.cn", function ($host, $ip) use ($response) + { + $response->header('Content-Type', 'application/json'); + $response->write(json_encode(array($host => $ip))); + $response->end(); + }); + } + + function getResult3($response) + { + $cityId = '01010101'; +// swoole_async_dns_lookup("weather.gtimg.cn", function ($host, $ip) use ($cityId, $response) +// { +// if (empty($ip)) +// { +// return $ret; +// } +// else +// { + $ip = '14.18.245.236'; + $httpcli = new swoole_http_client($ip, 80); + //$httpcli->on("close", function($httpcli){}); + $url = "/qqindex/" . $cityId . ".js?_ref=14"; + + $httpcli->get($url, function ($hcli) use ($response) + { + //echo "get content is" . $hcli->body; + $retWeather = iconv("GBK", 'UTF-8', $hcli->body); + //echo "ret:" . $retWeather; + $hcli->close(); + + $response->header('Content-Type', 'application/json'); + $response->write(json_encode($retWeather)); + $response->end(); + }); +// } +// }); + } + + function getResult($response) + { + $client = new swoole_redis(); + $ip = "127.0.0.1"; + $port = 6379; + + $client->connect($ip, $port, function (swoole_redis $client, $result) use ($response) + { + if ($result === false) + { + echo "connect to redis server failed\n"; + return false; + } + $client->GET('test', function (swoole_redis $client, $result) use ($response) + { + //echo "get result is :" . $result; + $client->close(); + $cityId = '01010101'; + swoole_async_dns_lookup("weather.gtimg.cn", function ($host, $ip) use ($cityId, $response) + { + if (empty($ip)) + { + return false; + } + else + { + $httpcli = new swoole_http_client($ip, 80); + //$httpcli->on("close", function($httpcli){}); + $url = "/qqindex/" . $cityId . ".js?_ref=14"; + + $httpcli->get($url, function ($hcli) use ($response) + { + //echo "get content is" . $hcli->body; + $retWeather = iconv("GBK", 'UTF-8', $hcli->body); + //echo "ret:" . $retWeather; + $hcli->close(); + + $response->header('Content-Type', 'application/json'); + $response->write(json_encode($retWeather)); + $response->end(); + + }); + } + }); + }); + }); + } + + function getResult4($response) + { + $client = new swoole_redis(); + $ip = "127.0.0.1"; + $port = 6379; + + $client->connect($ip, $port, function (swoole_redis $client, $result) use ($response) + { + if ($result === false) + { + echo "connect to redis server failed\n"; + return false; + } + $client->GET('key', function (swoole_redis $client, $result) use ($response) + { + //echo "get result is :" . $result; + $response->header('Content-Type', 'application/json'); + $response->end($result); + }); + }); + } + + public function start() + { + $this->init(); + $this->http->start(); + } +} + + +$setting = array( + + 'host' => '127.0.0.1', + 'port' => 9100, + 'worker_num' => 1, + 'dispatch_mode' => 2, + //'reactor_num' => 4, + 'daemonize' => 0, + //'log_file' => './logs/test_udp_server.log', +); + + +$server = new HttpServ(); +$server->set($setting); +$server->start(); diff --git a/vendor/swoole/examples/websocket/WebSocketClient.php b/vendor/swoole/examples/websocket/WebSocketClient.php new file mode 100755 index 0000000..184399d --- /dev/null +++ b/vendor/swoole/examples/websocket/WebSocketClient.php @@ -0,0 +1,307 @@ +<?php + +class WebSocketClient +{ + const VERSION = '0.1.4'; + + const TOKEN_LENGHT = 16; + const TYPE_ID_WELCOME = 0; + const TYPE_ID_PREFIX = 1; + const TYPE_ID_CALL = 2; + const TYPE_ID_CALLRESULT = 3; + const TYPE_ID_ERROR = 4; + const TYPE_ID_SUBSCRIBE = 5; + const TYPE_ID_UNSUBSCRIBE = 6; + const TYPE_ID_PUBLISH = 7; + const TYPE_ID_EVENT = 8; + + const OPCODE_CONTINUATION_FRAME = 0x0; + const OPCODE_TEXT_FRAME = 0x1; + const OPCODE_BINARY_FRAME = 0x2; + const OPCODE_CONNECTION_CLOSE = 0x8; + const OPCODE_PING = 0x9; + const OPCODE_PONG = 0xa; + + const CLOSE_NORMAL = 1000; + const CLOSE_GOING_AWAY = 1001; + const CLOSE_PROTOCOL_ERROR = 1002; + const CLOSE_DATA_ERROR = 1003; + const CLOSE_STATUS_ERROR = 1005; + const CLOSE_ABNORMAL = 1006; + const CLOSE_MESSAGE_ERROR = 1007; + const CLOSE_POLICY_ERROR = 1008; + const CLOSE_MESSAGE_TOO_BIG = 1009; + const CLOSE_EXTENSION_MISSING = 1010; + const CLOSE_SERVER_ERROR = 1011; + const CLOSE_TLS = 1015; + + private $key; + private $host; + private $port; + private $path; + /** + * @var swoole_client + */ + private $socket; + private $buffer = ''; + private $origin = null; + /** + * @var bool + */ + private $connected = false; + + public $returnData = false; + + /** + * @param string $host + * @param int $port + * @param string $path + */ + function __construct($host = '127.0.0.1', $port = 8080, $path = '/', $origin = null) + { + $this->host = $host; + $this->port = $port; + $this->path = $path; + $this->origin = $origin; + $this->key = $this->generateToken(self::TOKEN_LENGHT); + } + + /** + * Disconnect on destruct + */ + function __destruct() + { + $this->disconnect(); + } + + /** + * Connect client to server + * + * @return $this + */ + public function connect() + { + $this->socket = new \swoole_client(SWOOLE_SOCK_TCP); + if (!$this->socket->connect($this->host, $this->port)) + { + return false; + } + $this->socket->send($this->createHeader()); + return $this->recv(); + } + + public function getSocket() + { + return $this->socket; + } + + /** + * Disconnect from server + */ + public function disconnect() + { + $this->connected = false; + $this->socket->close(); + } + + public function close($code = self::CLOSE_NORMAL, $reason = '') + { + $data = pack('n', $code) . $reason; + return $this->socket->send(swoole_websocket_server::pack($data, self::OPCODE_CONNECTION_CLOSE, true)); + } + + public function recv() + { + $data = $this->socket->recv(); + if ($data === false) + { + echo "Error: {$this->socket->errMsg}"; + return false; + } + $this->buffer .= $data; + $recv_data = $this->parseData($this->buffer); + if ($recv_data) + { + $this->buffer = ''; + return $recv_data; + } + else + { + return false; + } + } + + /** + * @param string $data + * @param string $type + * @param bool $masked + * @return bool + */ + public function send($data, $type = 'text', $masked = false) + { + switch($type) + { + case 'text': + $_type = WEBSOCKET_OPCODE_TEXT; + break; + case 'binary': + case 'bin': + $_type = WEBSOCKET_OPCODE_BINARY; + break; + case 'ping': + $_type = WEBSOCKET_OPCODE_PING; + break; + default: + return false; + } + return $this->socket->send(swoole_websocket_server::pack($data, $_type, true, $masked)); + } + + /** + * Parse received data + * + * @param $response + */ + private function parseData($response) + { + if (!$this->connected) + { + $response = $this->parseIncomingRaw($response); + if (isset($response['Sec-Websocket-Accept']) + && base64_encode(pack('H*', sha1($this->key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))) === $response['Sec-Websocket-Accept'] + ) + { + $this->connected = true; + return true; + } + else + { + throw new \Exception("error response key."); + } + } + + $frame = swoole_websocket_server::unpack($response); + if ($frame) + { + return $this->returnData ? $frame->data : $frame; + } + else + { + throw new \Exception("swoole_websocket_server::unpack failed."); + } + } + + /** + * Create header for websocket client + * + * @return string + */ + private function createHeader() + { + $host = $this->host; + if ($host === '127.0.0.1' || $host === '0.0.0.0') + { + $host = 'localhost'; + } + return "GET {$this->path} HTTP/1.1" . "\r\n" . + "Origin: {$this->origin}" . "\r\n" . + "Host: {$host}:{$this->port}" . "\r\n" . + "Sec-WebSocket-Key: {$this->key}" . "\r\n" . + "User-Agent: PHPWebSocketClient/" . self::VERSION . "\r\n" . + "Upgrade: websocket" . "\r\n" . + "Connection: Upgrade" . "\r\n" . + "Sec-WebSocket-Protocol: wamp" . "\r\n" . + "Sec-WebSocket-Version: 13" . "\r\n" . "\r\n"; + } + + /** + * Parse raw incoming data + * + * @param $header + * + * @return array + */ + private function parseIncomingRaw($header) + { + $retval = array(); + $content = ""; + $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header)); + foreach ($fields as $field) + { + if (preg_match('/([^:]+): (.+)/m', $field, $match)) + { + $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', + function ($matches) + { + return strtoupper($matches[0]); + }, + strtolower(trim($match[1]))); + if (isset($retval[$match[1]])) + { + $retval[$match[1]] = array($retval[$match[1]], $match[2]); + } + else + { + $retval[$match[1]] = trim($match[2]); + } + } + else + { + if (preg_match('!HTTP/1\.\d (\d)* .!', $field)) + { + $retval["status"] = $field; + } + else + { + $content .= $field . "\r\n"; + } + } + } + $retval['content'] = $content; + return $retval; + } + + /** + * Generate token + * + * @param int $length + * + * @return string + */ + private function generateToken($length) + { + $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"§$%&/()=[]{}'; + $useChars = array(); + // select some random chars: + for ($i = 0; $i < $length; $i++) + { + $useChars[] = $characters[mt_rand(0, strlen($characters) - 1)]; + } + // Add numbers + array_push($useChars, rand(0, 9), rand(0, 9), rand(0, 9)); + shuffle($useChars); + $randomString = trim(implode('', $useChars)); + $randomString = substr($randomString, 0, self::TOKEN_LENGHT); + return base64_encode($randomString); + } + + /** + * Generate token + * + * @param int $length + * + * @return string + */ + public function generateAlphaNumToken($length) + { + $characters = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); + srand((float)microtime() * 1000000); + $token = ''; + do + { + shuffle($characters); + $token .= $characters[mt_rand(0, (count($characters) - 1))]; + } while (strlen($token) < $length); + return $token; + } +} diff --git a/vendor/swoole/examples/websocket/async_client.php b/vendor/swoole/examples/websocket/async_client.php new file mode 100755 index 0000000..2d61987 --- /dev/null +++ b/vendor/swoole/examples/websocket/async_client.php @@ -0,0 +1,11 @@ +<?php +$cli = new swoole_http_client('127.0.0.1', 9501); +$cli->setHeaders(['Trace-Id' => md5(time()),]); +$cli->on('message', function ($_cli, $frame) { + var_dump($frame); +}); + +$cli->upgrade('/', function ($cli) { + echo $cli->body; + $cli->push("hello world"); +}); diff --git a/vendor/swoole/examples/websocket/client.html b/vendor/swoole/examples/websocket/client.html new file mode 100755 index 0000000..c1519cc --- /dev/null +++ b/vendor/swoole/examples/websocket/client.html @@ -0,0 +1,19 @@ +<script> +var wsServer = 'ws://127.0.0.1:9501'; +var websocket = new WebSocket(wsServer); +websocket.onopen = function (evt) { + console.log("Connected to WebSocket server."); +}; + +websocket.onclose = function (evt) { + console.log("Disconnected"); +}; + +websocket.onmessage = function (evt) { + console.log('Retrieved data from server: ' + evt.data); +}; + +websocket.onerror = function (evt, e) { + console.log('Error occured: ' + evt.data); +}; +</script> diff --git a/vendor/swoole/examples/websocket/client.php b/vendor/swoole/examples/websocket/client.php new file mode 100755 index 0000000..e838b48 --- /dev/null +++ b/vendor/swoole/examples/websocket/client.php @@ -0,0 +1,40 @@ +<?php +$opt = getopt("c:n:k:"); +print_r($opt); +if (empty($opt['c']) || empty($opt['n'])) +{ + echo "examples: php client.php -c 100 -n 10000" . PHP_EOL; + return; +} +$clients = $opt['c']; +$count = $opt['n']; +$size = empty($opt['k']) ? 0 : $opt['k']; +require __DIR__ . "/WebSocketClient.php"; +$host = '127.0.0.1'; +$prot = 9501; + +$client = new WebSocketClient($host, $prot); +$data = $client->connect(); +//echo $data; +$data = "data"; +if (!empty($size)) +{ + $data = str_repeat("A", $size * 1024); +} +for ($i = 0; $i < $count; $i++) +{ + $client->send("hello swoole, number:" . $i . " data:" . $data); + $recvData = ""; + //while(1) { + $tmp = $client->recv(); + if (empty($tmp)) + { + break; + } + $recvData .= $tmp; + //} + echo $recvData . "size:" . strlen($recvData) . PHP_EOL; +} +echo PHP_EOL . "======" . PHP_EOL; +sleep(1); +echo 'finish' . PHP_EOL; diff --git a/vendor/swoole/examples/websocket/server.php b/vendor/swoole/examples/websocket/server.php new file mode 100755 index 0000000..674208c --- /dev/null +++ b/vendor/swoole/examples/websocket/server.php @@ -0,0 +1,138 @@ +<?php +//$server = new swoole_websocket_server("0.0.0.0", 9501); +$server = new swoole_websocket_server("0.0.0.0", 9501, SWOOLE_BASE); +//$server->addlistener('0.0.0.0', 9502, SWOOLE_SOCK_UDP); +//$server->set(['worker_num' => 4, +// 'task_worker_num' => 4, +//]); + +function user_handshake(swoole_http_request $request, swoole_http_response $response) +{ + //自定定握手规则,没有设置则用系统内置的(只支持version:13的) + if (!isset($request->header['sec-websocket-key'])) + { + //'Bad protocol implementation: it is not RFC6455.' + $response->end(); + return false; + } + if (0 === preg_match('#^[+/0-9A-Za-z]{21}[AQgw]==$#', $request->header['sec-websocket-key']) + || 16 !== strlen(base64_decode($request->header['sec-websocket-key'])) + ) + { + //Header Sec-WebSocket-Key is illegal; + $response->end(); + return false; + } + + $key = base64_encode(sha1($request->header['sec-websocket-key'] + . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', + true)); + $headers = array( + 'Upgrade' => 'websocket', + 'Connection' => 'Upgrade', + 'Sec-WebSocket-Accept' => $key, + 'Sec-WebSocket-Version' => '13', + 'KeepAlive' => 'off', + ); + foreach ($headers as $key => $val) + { + $response->header($key, $val); + } + $response->status(101); + $response->end(); + global $server; + $fd = $request->fd; + $server->defer(function () use ($fd, $server) + { + $server->push($fd, "hello, welcome\n"); + }); + return true; +} + +$server->on('handshake', 'user_handshake'); +$server->on('open', function (swoole_websocket_server $_server, swoole_http_request $request) { + echo "server#{$_server->worker_pid}: handshake success with fd#{$request->fd}\n"; + var_dump($_server->exist($request->fd), $_server->getClientInfo($request->fd)); +// var_dump($request); +}); + +$server->on('message', function (swoole_websocket_server $_server, $frame) { + var_dump($frame->data); + echo "received ".strlen($frame->data)." bytes\n"; + if ($frame->data == "close") + { + $_server->close($frame->fd); + } + elseif($frame->data == "task") + { + $_server->task(['go' => 'die']); + } + else + { + //echo "receive from {$frame->fd}:{$frame->data}, opcode:{$frame->opcode}, finish:{$frame->finish}\n"; + // for ($i = 0; $i < 100; $i++) + { + $_send = str_repeat('B', rand(100, 800)); + $_server->push($frame->fd, $_send); + // echo "#$i\tserver sent " . strlen($_send) . " byte \n"; + } + $fd = $frame->fd; + $_server->tick(2000, function($id) use ($fd, $_server) { + $_send = str_repeat('B', rand(100, 5000)); + $ret = $_server->push($fd, $_send); + if (!$ret) + { + var_dump($id); + var_dump($_server->clearTimer($id)); + } + }); + } +}); + +$server->on('close', function ($_server, $fd) { + echo "client {$fd} closed\n"; +}); + +$server->on('task', function ($_server, $worker_id, $task_id, $data) +{ + var_dump($worker_id, $task_id, $data); + return "hello world\n"; +}); + +$server->on('finish', function ($_server, $task_id, $result) +{ + var_dump($task_id, $result); +}); + +$server->on('packet', function ($_server, $data, $client) { + echo "#".posix_getpid()."\tPacket {$data}\n"; + var_dump($client); +}); + +$server->on('request', function (swoole_http_request $request, swoole_http_response $response) { + $response->end(<<<HTML + <h1>Swoole WebSocket Server</h1> + <script> +var wsServer = 'ws://127.0.0.1:9501'; +var websocket = new WebSocket(wsServer); +websocket.onopen = function (evt) { + console.log("Connected to WebSocket server."); +}; + +websocket.onclose = function (evt) { + console.log("Disconnected"); +}; + +websocket.onmessage = function (evt) { + console.log('Retrieved data from server: ' + evt.data); +}; + +websocket.onerror = function (evt, e) { + console.log('Error occured: ' + evt.data); +}; +</script> +HTML + ); +}); + +$server->start(); diff --git a/vendor/swoole/include/Client.h b/vendor/swoole/include/Client.h new file mode 100755 index 0000000..91663c2 --- /dev/null +++ b/vendor/swoole/include/Client.h @@ -0,0 +1,207 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_CLIENT_H_ +#define SW_CLIENT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "buffer.h" +#include "Connection.h" + +#define SW_SOCK_ASYNC 1 +#define SW_SOCK_SYNC 0 + +#define SW_HTTPS_PROXY_HANDSHAKE_RESPONSE "HTTP/1.1 200 Connection established" + +enum swClient_pipe_flag +{ + SW_CLIENT_PIPE_TCP_SESSION = 1, +}; + +enum swHttp_proxy_state +{ + SW_HTTP_PROXY_STATE_WAIT = 0, + SW_HTTP_PROXY_STATE_HANDSHAKE, + SW_HTTP_PROXY_STATE_READY, +}; + +struct _http_proxy +{ + uint8_t state; + int proxy_port; + char *proxy_host; + char *user; + char *password; + int l_user; + int l_password; + char *target_host; + int target_port; + char buf[600]; +}; + +typedef struct _swClient +{ + int id; + int type; + long timeout_id; //timeout node id + int _sock_type; + int _sock_domain; + int _protocol; + int reactor_fdtype; + + int _redirect_to_file; + int _redirect_to_socket; + int _redirect_to_session; + + uint32_t async :1; + uint32_t keep :1; + uint32_t released :1; + uint32_t destroyed :1; + uint32_t redirect :1; + uint32_t http2 :1; + uint32_t sleep :1; + uint32_t wait_dns :1; + uint32_t shutdow_rw :1; + uint32_t shutdown_read :1; + uint32_t shutdown_write :1; + uint32_t remove_delay :1; + + /** + * one package: length check + */ + uint32_t open_length_check :1; + uint32_t open_eof_check :1; + + swProtocol protocol; + struct _swSocks5 *socks5_proxy; + struct _http_proxy* http_proxy; + + uint32_t reuse_count; + + char *server_str; + char *server_host; + int server_port; + void *ptr; + void *params; + + uint8_t server_strlen; + double timeout; + swTimer_node *timer; + + /** + * signal interruption + */ + double interrupt_time; + + /** + * sendto, read only. + */ + swSocketAddress server_addr; + + /** + * recvfrom + */ + swSocketAddress remote_addr; + + swConnection *socket; + + /** + * reactor + */ + swReactor *reactor; + + void *object; + + swString *buffer; + uint32_t wait_length; + uint32_t buffer_input_size; + + uint32_t buffer_high_watermark; + uint32_t buffer_low_watermark; + +#ifdef SW_USE_OPENSSL + uint8_t open_ssl :1; + uint8_t ssl_wait_handshake :1; + SSL_CTX *ssl_context; + swSSL_option ssl_option; +#endif + + void (*onConnect)(struct _swClient *cli); + void (*onError)(struct _swClient *cli); + void (*onReceive)(struct _swClient *cli, char *data, uint32_t length); + void (*onClose)(struct _swClient *cli); + void (*onBufferFull)(struct _swClient *cli); + void (*onBufferEmpty)(struct _swClient *cli); + + int (*connect)(struct _swClient *cli, char *host, int port, double _timeout, int sock_flag); + int (*send)(struct _swClient *cli, char *data, int length, int flags); + int (*sendfile)(struct _swClient *cli, char *filename, off_t offset, size_t length); + int (*recv)(struct _swClient *cli, char *data, int len, int flags); + int (*pipe)(struct _swClient *cli, int write_fd, int is_session_id); + int (*close)(struct _swClient *cli); + +} swClient; + +int swClient_create(swClient *cli, int type, int async); +int swClient_sleep(swClient *cli); +int swClient_wakeup(swClient *cli); +int swClient_shutdown(swClient *cli, int __how); +#ifdef SW_USE_OPENSSL +int swClient_enable_ssl_encrypt(swClient *cli); +int swClient_ssl_handshake(swClient *cli); +int swClient_ssl_verify(swClient *cli, int allow_self_signed); +#endif +void swClient_free(swClient *cli); + +typedef struct +{ + uint8_t num; + struct + { + uint8_t length; + char address[16]; + } hosts[SW_DNS_HOST_BUFFER_SIZE]; +} swDNSResolver_result; + +int swDNSResolver_request(char *domain, void (*callback)(char *, swDNSResolver_result *, void *), void *data); +int swDNSResolver_free(); + +//----------------------------------------Stream--------------------------------------- +typedef struct _swStream +{ + swString *buffer; + uint32_t session_id; + uint8_t cancel; + void (*response)(struct _swStream *stream, char *data, uint32_t length); + swClient client; +} swStream; + +swStream* swStream_new(char *dst_host, int dst_port, int type); +int swStream_send(swStream *stream, char *data, size_t length); +void swStream_set_protocol(swProtocol *protocol); +void swStream_set_max_length(swStream *stream, uint32_t max_length); +int swStream_recv_blocking(int fd, void *__buf, size_t __len); +//----------------------------------------Stream End------------------------------------ + +#ifdef __cplusplus +} +#endif + +#endif /* SW_CLIENT_H_ */ diff --git a/vendor/swoole/include/Connection.h b/vendor/swoole/include/Connection.h new file mode 100755 index 0000000..db91d0a --- /dev/null +++ b/vendor/swoole/include/Connection.h @@ -0,0 +1,260 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_CONNECTION_H_ +#define SW_CONNECTION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "buffer.h" + +#ifdef SW_USE_OPENSSL + +#include <openssl/bio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/conf.h> + +#define SW_SSL_BUFFER 1 +#define SW_SSL_CLIENT 2 + +typedef struct _swSSL_option +{ + char *cert_file; + char *key_file; + char *passphrase; + char *client_cert_file; +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + char *tls_host_name; +#endif + char *cafile; + char *capath; + uint8_t verify_depth; + uint8_t method; + uint8_t disable_compress :1; + uint8_t verify_peer :1; + uint8_t allow_self_signed :1; +} swSSL_option; + +#endif + +int swConnection_buffer_send(swConnection *conn); + +swString* swConnection_get_string_buffer(swConnection *conn); +void swConnection_clear_string_buffer(swConnection *conn); +swBuffer_trunk* swConnection_get_out_buffer(swConnection *conn, uint32_t type); +swBuffer_trunk* swConnection_get_in_buffer(swConnection *conn); +int swConnection_sendfile(swConnection *conn, char *filename, off_t offset, size_t length); +int swConnection_onSendfile(swConnection *conn, swBuffer_trunk *chunk); +void swConnection_sendfile_destructor(swBuffer_trunk *chunk); +char* swConnection_get_ip(swConnection *conn); +int swConnection_get_port(swConnection *conn); + +#ifdef SW_USE_OPENSSL +enum swSSLState +{ + SW_SSL_STATE_HANDSHAKE = 0, + SW_SSL_STATE_READY = 1, + SW_SSL_STATE_WAIT_STREAM = 2, +}; + +enum swSSLMethod +{ + SW_SSLv23_METHOD = 0, + SW_SSLv3_METHOD, + SW_SSLv3_SERVER_METHOD, + SW_SSLv3_CLIENT_METHOD, + SW_SSLv23_SERVER_METHOD, + SW_SSLv23_CLIENT_METHOD, + SW_TLSv1_METHOD, + SW_TLSv1_SERVER_METHOD, + SW_TLSv1_CLIENT_METHOD, +#ifdef TLS1_1_VERSION + SW_TLSv1_1_METHOD, + SW_TLSv1_1_SERVER_METHOD, + SW_TLSv1_1_CLIENT_METHOD, +#endif +#ifdef TLS1_2_VERSION + SW_TLSv1_2_METHOD, + SW_TLSv1_2_SERVER_METHOD, + SW_TLSv1_2_CLIENT_METHOD, +#endif + SW_DTLSv1_METHOD, + SW_DTLSv1_SERVER_METHOD, + SW_DTLSv1_CLIENT_METHOD, +}; + +typedef struct +{ + uint32_t http :1; + uint32_t http_v2 :1; + uint32_t prefer_server_ciphers :1; + uint32_t session_tickets :1; + uint32_t stapling :1; + uint32_t stapling_verify :1; + char *ciphers; + char *ecdh_curve; + char *session_cache; + char *dhparam; +} swSSL_config; + +void swSSL_init(void); +void swSSL_init_thread_safety(); +int swSSL_server_set_cipher(SSL_CTX* ssl_context, swSSL_config *cfg); +void swSSL_server_http_advise(SSL_CTX* ssl_context, swSSL_config *cfg); +SSL_CTX* swSSL_get_context(swSSL_option *option); +void swSSL_free_context(SSL_CTX* ssl_context); +int swSSL_create(swConnection *conn, SSL_CTX* ssl_context, int flags); +int swSSL_set_client_certificate(SSL_CTX *ctx, char *cert_file, int depth); +int swSSL_set_capath(swSSL_option *cfg, SSL_CTX *ctx); +int swSSL_check_host(swConnection *conn, char *tls_host_name); +int swSSL_get_client_certificate(SSL *ssl, char *buffer, size_t length); +int swSSL_verify(swConnection *conn, int allow_self_signed); +int swSSL_accept(swConnection *conn); +int swSSL_connect(swConnection *conn); +void swSSL_close(swConnection *conn); +ssize_t swSSL_recv(swConnection *conn, void *__buf, size_t __n); +ssize_t swSSL_send(swConnection *conn, void *__buf, size_t __n); +int swSSL_sendfile(swConnection *conn, int fd, off_t *offset, size_t size); +#endif + +/** + * Receive data from connection + */ +static sw_inline ssize_t swConnection_recv(swConnection *conn, void *__buf, size_t __n, int __flags) +{ + int retval; +#ifdef SW_USE_OPENSSL + if (conn->ssl) + { + int ret = 0; + int n_received = 0; + + while (n_received < __n) + { + ret = swSSL_recv(conn, ((char*)__buf) + n_received, __n - n_received); + if (__flags & MSG_WAITALL) + { + if (ret <= 0) + { + retval = ret; + goto _return; + } + else + { + n_received += ret; + } + } + else + { + retval = ret; + goto _return; + } + } + + retval = n_received; + } + else + { + retval = recv(conn->fd, __buf, __n, __flags); + } +#else + retval = recv(conn->fd, __buf, __n, __flags); +#endif + +#ifdef SW_USE_OPENSSL + _return: +#endif + +#ifdef SW_DEBUG + if (retval > 0) + { + conn->total_recv_bytes += retval; + } +#endif + + return retval; +} + +/** + * Send data to connection + */ +static sw_inline int swConnection_send(swConnection *conn, void *__buf, size_t __n, int __flags) +{ + int retval; +#ifdef SW_USE_OPENSSL + if (conn->ssl) + { + retval = swSSL_send(conn, __buf, __n); + } + else + { + retval = send(conn->fd, __buf, __n, __flags); + } +#else + retval = send(conn->fd, __buf, __n, __flags); +#endif + +#ifdef SW_DEBUG + if (retval > 0) + { + conn->total_send_bytes += retval; + } +#endif + + return retval; +} + +static sw_inline int swConnection_error(int err) +{ + switch (err) + { + case EFAULT: + abort(); + return SW_ERROR; + case EBADF: + case ECONNRESET: +#ifdef __CYGWIN__ + case ECONNABORTED: +#endif + case EPIPE: + case ENOTCONN: + case ETIMEDOUT: + case ECONNREFUSED: + case ENETDOWN: + case ENETUNREACH: + case EHOSTDOWN: + case EHOSTUNREACH: + case SW_ERROR_SSL_BAD_CLIENT: + return SW_CLOSE; + case EAGAIN: +#ifdef HAVE_KQUEUE + case ENOBUFS: +#endif + case 0: + return SW_WAIT; + default: + return SW_ERROR; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* SW_CONNECTION_H_ */ diff --git a/vendor/swoole/include/ReadMe b/vendor/swoole/include/ReadMe new file mode 100755 index 0000000..5d6dc84 --- /dev/null +++ b/vendor/swoole/include/ReadMe @@ -0,0 +1 @@ +Swoole used Troy D. Hanson's Uhash and Ulist. diff --git a/vendor/swoole/include/RingQueue.h b/vendor/swoole/include/RingQueue.h new file mode 100755 index 0000000..fc34c2b --- /dev/null +++ b/vendor/swoole/include/RingQueue.h @@ -0,0 +1,73 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef _SW_RINGQUEUE_H_ +#define _SW_RINGQUEUE_H_ + +#ifdef SW_USE_RINGQUEUE_TS +#include "atomic.h" +typedef struct _swRingQueue +{ + void **data; + char *flags; + // 0:push ready 1: push now + // 2:pop ready; 3: pop now + uint size; + uint num; + uint head; + uint tail; + +} swRingQueue; + +int swRingQueue_init(swRingQueue *, int buffer_size); +#define swRingQueue_count(q) (q->num) +int swRingQueue_push(swRingQueue *, void *); +int swRingQueue_pop(swRingQueue *, void **); +#else +typedef struct _swRingQueue +{ + int head; /* 头部,出队列方向*/ + int tail; /* 尾部,入队列方向*/ + int tag; /* 为空还是为满的标志位*/ + int size; /* 队列总尺寸 */ + void **data; /* 队列空间 */ +} swRingQueue; + +int swRingQueue_init(swRingQueue *queue, int buffer_size); +int swRingQueue_push(swRingQueue *queue, void *); +int swRingQueue_pop(swRingQueue *queue, void **); +void swRingQueue_free(swRingQueue *queue); + +static inline int swRingQueue_count(swRingQueue *queue) +{ + if (queue->tail > queue->head) + { + return queue->tail - queue->head; + } + else if (queue->head == queue->tail) + { + return queue->tag == 1 ? queue->size : 0; + } + else + { + return queue->tail + queue->size - queue->head; + } +} + +#define swRingQueue_empty(q) ( (q->head == q->tail) && (q->tag == 0)) +#define swRingQueue_full(q) ( (q->head == q->tail) && (q->tag == 1)) +#endif +#endif diff --git a/vendor/swoole/include/Server.h b/vendor/swoole/include/Server.h new file mode 100755 index 0000000..052b897 --- /dev/null +++ b/vendor/swoole/include/Server.h @@ -0,0 +1,1066 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_SERVER_H_ +#define SW_SERVER_H_ + +#include "swoole.h" +#include "buffer.h" +#include "Connection.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SW_REACTOR_NUM SW_CPU_NUM +#define SW_WORKER_NUM (SW_CPU_NUM*2) + +#define SW_HEARTBEAT_IDLE 0 //心跳存活最大时间 +#define SW_HEARTBEAT_CHECK 0 //心跳定时侦测时间 + +enum swEventType +{ + //networking socket + SW_EVENT_TCP = 0, + SW_EVENT_UDP = 1, + SW_EVENT_TCP6 = 2, + SW_EVENT_UDP6 = 3, + //tcp event + SW_EVENT_CLOSE = 4, + SW_EVENT_CONNECT = 5, + //timer + SW_EVENT_TIMER = 6, + //task + SW_EVENT_TASK = 7, + SW_EVENT_FINISH = 8, + //package + SW_EVENT_PACKAGE_START = 9, + SW_EVENT_PACKAGE_END = 10, + SW_EVENT_PACKAGE = 11, + SW_EVENT_SENDFILE = 12, + SW_EVENT_UNIX_DGRAM = 13, + SW_EVENT_UNIX_STREAM = 14, + //pipe + SW_EVENT_PIPE_MESSAGE = 15, + //proxy + SW_EVENT_PROXY_START = 16, + SW_EVENT_PROXY_END = 17, + SW_EVENT_CONFIRM = 18, + //event operate + SW_EVENT_PAUSE_RECV, + SW_EVENT_RESUME_RECV, + //buffer event + SW_EVENT_BUFFER_FULL, + SW_EVENT_BUFFER_EMPTY, +}; + +enum swIPCType +{ + SW_IPC_NONE = 0, + SW_IPC_UNIXSOCK = 1, + SW_IPC_MSGQUEUE = 2, + SW_IPC_SOCKET = 3, +}; + +enum swTaskIPCMode +{ + SW_TASK_IPC_UNIXSOCK = 1, + SW_TASK_IPC_MSGQUEUE = 2, + SW_TASK_IPC_PREEMPTIVE = 3, + SW_TASK_IPC_STREAM = 4, +}; + +enum swCloseType +{ + SW_CLOSE_PASSIVE = 32, + SW_CLOSE_INITIATIVE, +}; + +enum swResponseType +{ + SW_RESPONSE_SMALL = 0, + SW_RESPONSE_SHM = 1, + SW_RESPONSE_TMPFILE, + SW_RESPONSE_EXIT, +}; + +enum swWorkerPipeType +{ + SW_PIPE_WORKER = 0, + SW_PIPE_MASTER = 1, + SW_PIPE_NONBLOCK = 2, +}; + +/** + * use swDataHead->from_fd, 1 byte 8 bit + */ +enum swTaskType +{ + SW_TASK_TMPFILE = 1, //tmp file + SW_TASK_SERIALIZE = 2, //php serialize + SW_TASK_NONBLOCK = 4, //task + SW_TASK_CALLBACK = 8, //callback + SW_TASK_WAITALL = 16, //for taskWaitAll + SW_TASK_COROUTINE = 32, //coroutine + SW_TASK_PEEK = 64, //peek +}; + +typedef struct _swUdpFd +{ + struct sockaddr addr; + int sock; +} swUdpFd; + +typedef struct _swReactorThread +{ + pthread_t thread_id; + swReactor reactor; + swUdpFd *udp_addrs; + swMemoryPool *buffer_input; +#ifdef SW_USE_RINGBUFFER + int *pipe_read_list; +#endif + swLock lock; + int notify_pipe; +} swReactorThread; + +typedef struct _swListenPort +{ + struct _swListenPort *next, *prev; + + /** + * tcp socket listen backlog + */ + uint16_t backlog; + /** + * open tcp_defer_accept option + */ + int tcp_defer_accept; + /** + * TCP_FASTOPEN + */ + int tcp_fastopen; + /** + * TCP KeepAlive + */ + int tcp_keepidle; + int tcp_keepinterval; + int tcp_keepcount; + + int socket_buffer_size; + uint32_t buffer_high_watermark; + uint32_t buffer_low_watermark; + + uint8_t type; + uint8_t ssl; + int port; + int sock; + pthread_t thread_id; + char host[SW_HOST_MAXSIZE]; + + /** + * check data eof + */ + uint32_t open_eof_check :1; + /** + * built-in http protocol + */ + uint32_t open_http_protocol :1; + /** + * built-in http2.0 protocol + */ + uint32_t open_http2_protocol :1; + /** + * built-in websocket protocol + */ + uint32_t open_websocket_protocol :1; + /** + * one package: length check + */ + uint32_t open_length_check :1; + /** + * for mqtt protocol + */ + uint32_t open_mqtt_protocol :1; + /** + * redis protocol + */ + uint32_t open_redis_protocol :1; + /** + * open tcp nodelay option + */ + uint32_t open_tcp_nodelay :1; + /** + * open tcp nopush option(for sendfile) + */ + uint32_t open_tcp_nopush :1; + /** + * open tcp keepalive + */ + uint32_t open_tcp_keepalive :1; + /** + * open tcp keepalive + */ + uint32_t open_ssl_encrypt :1; + /** + * Sec-WebSocket-Protocol + */ + char *websocket_subprotocol; + uint16_t websocket_subprotocol_length; + /** + * set socket option + */ + int kernel_socket_recv_buffer_size; + int kernel_socket_send_buffer_size; + +#ifdef SW_USE_OPENSSL + SSL_CTX *ssl_context; + swSSL_config ssl_config; + swSSL_option ssl_option; +#endif + + sw_atomic_t connection_num; + + swProtocol protocol; + void *ptr; + int (*onRead)(swReactor *reactor, struct _swListenPort *port, swEvent *event); +} swListenPort; + +typedef struct _swUserWorker_node +{ + struct _swUserWorker_node *next, *prev; + swWorker *worker; +} swUserWorker_node; + +typedef struct { + char *filename; + uint16_t name_len; + int fd; + size_t length; + off_t offset; +} swTask_sendfile; + +typedef struct +{ + uint16_t num; +} swUserWorker; + +typedef struct +{ + pid_t pid; + uint16_t worker_id; +} swWorkerStopMessage; + +//-----------------------------------Factory-------------------------------------------- +typedef struct +{ + long target_worker_id; + swEventData data; +} swDispatchData; + +struct _swFactory +{ + void *object; + void *ptr; //server object + int last_from_id; + + swReactor *reactor; //reserve for reactor + + int (*start)(struct _swFactory *); + int (*shutdown)(struct _swFactory *); + int (*dispatch)(struct _swFactory *, swDispatchData *); + int (*finish)(struct _swFactory *, swSendData *); + int (*notify)(struct _swFactory *, swDataHead *); //send a event notify + int (*end)(struct _swFactory *, int fd); +}; + +typedef struct _swFactoryProcess +{ + swPipe *pipes; +} swFactoryProcess; + +typedef struct _swRequest +{ + int fd; + uint8_t type; + uint8_t status; + void *object; +} swRequest; + +typedef int (*swServer_dispatch_function)(swServer *, swConnection *, swEventData *); + +int swFactory_create(swFactory *factory); +int swFactory_start(swFactory *factory); +int swFactory_shutdown(swFactory *factory); +int swFactory_dispatch(swFactory *factory, swDispatchData *req); +int swFactory_finish(swFactory *factory, swSendData *_send); +int swFactory_notify(swFactory *factory, swDataHead *event); +int swFactory_end(swFactory *factory, int fd); +int swFactory_check_callback(swFactory *factory); + +int swFactoryProcess_create(swFactory *factory, int worker_num); +int swFactoryThread_create(swFactory *factory, int writer_num); + + +//------------------------------------Server------------------------------------------- +enum swServer_callback_type +{ + SW_SERVER_CALLBACK_onConnect = 1, + SW_SERVER_CALLBACK_onReceive, + SW_SERVER_CALLBACK_onClose, +}; + +enum swServer_hook_type +{ + SW_SERVER_HOOK_MASTER_START, + SW_SERVER_HOOK_MASTER_TIMER, + SW_SERVER_HOOK_REACTOR_START, + SW_SERVER_HOOK_WORKER_START, + SW_SERVER_HOOK_TASK_WORKER_START, + SW_SERVER_HOOK_MASTER_CONNECT, + SW_SERVER_HOOK_REACTOR_CONNECT, + SW_SERVER_HOOK_WORKER_CONNECT, + SW_SERVER_HOOK_REACTOR_RECEIVE, + SW_SERVER_HOOK_WORKER_RECEIVE, + SW_SERVER_HOOK_REACTOR_CLOSE, + SW_SERVER_HOOK_WORKER_CLOSE, + SW_SERVER_HOOK_MANAGER_START, + SW_SERVER_HOOK_MANAGER_TIMER, + SW_SERVER_HOOK_PROCESS_TIMER, +}; + +typedef struct +{ + time_t start_time; + sw_atomic_t connection_num; + sw_atomic_t tasking_num; + sw_atomic_long_t accept_count; + sw_atomic_long_t close_count; + sw_atomic_long_t request_count; +} swServerStats; + +typedef struct +{ + pid_t master_pid; + pid_t manager_pid; + + uint32_t session_round :24; + sw_atomic_t start; //after swServer_start will set start=1 + + time_t now; + + sw_atomic_t spinlock; + + swProcessPool task_workers; + swProcessPool event_workers; + +} swServerGS; + +struct _swServer +{ + /** + * reactor thread/process num + */ + uint16_t reactor_num; + /** + * worker process num + */ + uint16_t worker_num; + /** + * The number of pipe per reactor maintenance + */ + uint16_t reactor_pipe_num; + + uint8_t factory_mode; + + uint8_t dgram_port_num; + + /** + * package dispatch mode + */ + uint8_t dispatch_mode; + + /** + * No idle work process is available. + */ + uint8_t scheduler_warning; + + int worker_uid; + int worker_groupid; + + /** + * max connection num + */ + uint32_t max_connection; + + /** + * worker process max request + */ + uint32_t max_request; + + int signal_fd; + int event_fd; + + int udp_socket_ipv4; + int udp_socket_ipv6; + + uint32_t max_wait_time; + + /*----------------------------Reactor schedule--------------------------------*/ + uint16_t reactor_round_i; + uint16_t reactor_next_i; + uint16_t reactor_schedule_count; + + sw_atomic_t worker_round_id; + + /** + * run as a daemon process + */ + uint32_t daemonize :1; + /** + * have udp listen socket + */ + uint32_t have_udp_sock :1; + /** + * have tcp listen socket + */ + uint32_t have_tcp_sock :1; + /** + * oepn cpu affinity setting + */ + uint32_t open_cpu_affinity :1; + /** + * Udisable notice when use SW_DISPATCH_ROUND and SW_DISPATCH_QUEUE + */ + uint32_t disable_notify :1; + /** + * discard the timeout request + */ + uint32_t discard_timeout_request :1; + /** + * parse x-www-form-urlencoded data + */ + uint32_t http_parse_post :1; + /** + * handle static files + */ + uint32_t enable_static_handler :1; + /** + * enable onConnect/onClose event when use dispatch_mode=1/3 + */ + uint32_t enable_unsafe_event :1; + /** + * waiting for worker onConnect callback function to return + */ + uint32_t enable_delay_receive :1; + /** + * asynchronous reloading + */ + uint32_t reload_async :1; + /** + * slowlog + */ + uint32_t trace_event_worker :1; + /** + * yield coroutine when the output buffer is full + */ + uint32_t send_yield :1; + + /** + * heartbeat check time + */ + uint16_t heartbeat_idle_time; + uint16_t heartbeat_check_interval; + + int *cpu_affinity_available; + int cpu_affinity_available_num; + + double send_timeout; + + uint16_t listen_port_num; + time_t reload_time; + time_t warning_time; + + /* buffer output/input setting*/ + uint32_t buffer_output_size; + uint32_t buffer_input_size; + + void *ptr2; + void *private_data_3; + + swReactor reactor; + swFactory factory; + swListenPort *listen_list; + pthread_t heartbeat_pidt; + + /** + * task process + */ + uint16_t task_worker_num; + uint8_t task_ipc_mode; + uint16_t task_max_request; + swPipe *task_notify; + swEventData *task_result; + + /** + * use process + */ + uint16_t user_worker_num; + swUserWorker_node *user_worker_list; + swHashMap *user_worker_map; + swWorker *user_workers; + + swReactorThread *reactor_threads; + swWorker *workers; + + swChannel *message_box; + + swServerStats *stats; + swServerGS *gs; + +#ifdef HAVE_PTHREAD_BARRIER + pthread_barrier_t barrier; +#endif + + swConnection *connection_list; + swSession *session_list; + + /** + * temporary directory for HTTP uploaded file. + */ + char *upload_tmp_dir; + + /** + * http static file directory + */ + char *document_root; + uint16_t document_root_len; + + /** + * master process pid + */ + char *pid_file; + + /** + * stream + */ + char *stream_socket; + int stream_fd; + swProtocol stream_protocol; + swLinkedList *buffer_pool; + int last_stream_fd; + int last_session_id; + +#ifdef SW_BUFFER_RECV_TIME + double last_receive_usec; +#endif + + int manager_alarm; + + /** + * message queue key + */ + uint64_t message_queue_key; + + /** + * slow request log + */ + uint8_t request_slowlog_timeout; + FILE *request_slowlog_file; + + swReactor *reactor_ptr; //Main Reactor + swFactory *factory_ptr; //Factory + + swLinkedList *hooks[SW_MAX_HOOK_TYPE]; + + void (*onStart)(swServer *serv); + void (*onManagerStart)(swServer *serv); + void (*onManagerStop)(swServer *serv); + void (*onShutdown)(swServer *serv); + void (*onPipeMessage)(swServer *, swEventData *); + void (*onWorkerStart)(swServer *serv, int worker_id); + void (*onWorkerStop)(swServer *serv, int worker_id); + void (*onWorkerExit)(swServer *serv, int worker_id); + void (*onWorkerError)(swServer *serv, int worker_id, pid_t worker_pid, int exit_code, int signo); + void (*onUserWorkerStart)(swServer *serv, swWorker *worker); + /** + * Client + */ + int (*onReceive)(swServer *, swEventData *); + int (*onPacket)(swServer *, swEventData *); + void (*onClose)(swServer *serv, swDataHead *); + void (*onConnect)(swServer *serv, swDataHead *); + void (*onBufferFull)(swServer *serv, swDataHead *); + void (*onBufferEmpty)(swServer *serv, swDataHead *); + /** + * Task Worker + */ + int (*onTask)(swServer *serv, swEventData *data); + int (*onFinish)(swServer *serv, swEventData *data); + + int (*send)(swServer *serv, int fd, void *data, uint32_t length); + int (*sendfile)(swServer *serv, int fd, char *filename, uint32_t filename_length, off_t offset, size_t length); + int (*sendwait)(swServer *serv, int fd, void *data, uint32_t length); + int (*close)(swServer *serv, int fd, int reset); + int (*dispatch_func)(swServer *, swConnection *, swEventData *); +}; + +typedef struct _swSocketLocal +{ + socklen_t len; + char file[0]; +} swSocketLocal; + +typedef struct _swPackage +{ + void *data; + uint32_t length; + uint32_t id; +} swPackage; + +typedef struct +{ + int length; + char tmpfile[SW_TASK_TMPDIR_SIZE + sizeof(SW_TASK_TMP_FILE)]; +} swPackage_task; + +typedef struct +{ + int length; + int worker_id; +} swPackage_response; + +int swServer_master_onAccept(swReactor *reactor, swEvent *event); +void swServer_master_onTimer(swTimer *timer, swTimer_node *tnode); +void swServer_update_time(swServer *serv); + +int swServer_onFinish(swFactory *factory, swSendData *resp); +int swServer_onFinish2(swFactory *factory, swSendData *resp); + +void swServer_init(swServer *serv); +void swServer_signal_init(swServer *serv); +int swServer_start(swServer *serv); +swListenPort* swServer_add_port(swServer *serv, int type, char *host, int port); +void swServer_close_port(swServer *serv, enum swBool_type only_stream_port); +int swServer_add_worker(swServer *serv, swWorker *worker); +int swserver_add_systemd_socket(swServer *serv); +int swServer_add_hook(swServer *serv, enum swServer_hook_type type, swCallback func, int push_back); +void swServer_call_hook(swServer *serv, enum swServer_hook_type type, void *arg); + +int swServer_create(swServer *serv); +int swServer_free(swServer *serv); +int swServer_shutdown(swServer *serv); + +static sw_inline swString *swServer_get_buffer(swServer *serv, int fd) +{ + swString *buffer = serv->connection_list[fd].recv_buffer; + if (buffer == NULL) + { + buffer = swString_new(SW_BUFFER_SIZE_STD); + //alloc memory failed. + if (!buffer) + { + return NULL; + } + serv->connection_list[fd].recv_buffer = buffer; + } + return buffer; +} + +static sw_inline void swServer_free_buffer(swServer *serv, int fd) +{ + swString *buffer = serv->connection_list[fd].recv_buffer; + if (buffer) + { + swString_free(buffer); + serv->connection_list[fd].recv_buffer = NULL; + } +} + +static sw_inline swListenPort* swServer_get_port(swServer *serv, int fd) +{ + sw_atomic_t server_fd = serv->connection_list[fd].from_fd; + return (swListenPort*) serv->connection_list[server_fd].object; +} + +int swServer_udp_send(swServer *serv, swSendData *resp); +int swServer_tcp_send(swServer *serv, int fd, void *data, uint32_t length); +int swServer_tcp_sendwait(swServer *serv, int fd, void *data, uint32_t length); +int swServer_tcp_close(swServer *serv, int fd, int reset); +int swServer_tcp_sendfile(swServer *serv, int session_id, char *filename, uint32_t filename_length, off_t offset, size_t length); +int swServer_tcp_notify(swServer *serv, swConnection *conn, int event); +int swServer_tcp_feedback(swServer *serv, int fd, int event); + +//UDP, UDP必然超过0x1000000 +//原因:IPv4的第4字节最小为1,而这里的conn_fd是网络字节序 +#define SW_MAX_SOCKET_ID 0x1000000 +#define swServer_is_udp(fd) ((uint32_t) fd > SW_MAX_SOCKET_ID) + +static sw_inline int swEventData_is_dgram(uint8_t type) +{ + switch (type) + { + case SW_EVENT_UDP: + case SW_EVENT_UDP6: + case SW_EVENT_UNIX_DGRAM: + return SW_TRUE; + default: + return SW_FALSE; + } +} + +static sw_inline int swEventData_is_stream(uint8_t type) +{ + switch (type) + { + case SW_EVENT_TCP: + case SW_EVENT_TCP6: + case SW_EVENT_UNIX_STREAM: + case SW_EVENT_PACKAGE_START: + case SW_EVENT_PACKAGE: + case SW_EVENT_PACKAGE_END: + case SW_EVENT_CONNECT: + case SW_EVENT_CLOSE: + case SW_EVENT_PAUSE_RECV: + case SW_EVENT_RESUME_RECV: + case SW_EVENT_BUFFER_FULL: + case SW_EVENT_BUFFER_EMPTY: + return SW_TRUE; + default: + return SW_FALSE; + } +} + +swPipe * swServer_get_pipe_object(swServer *serv, int pipe_fd); +void swServer_store_pipe_fd(swServer *serv, swPipe *p); +void swServer_store_listen_socket(swServer *serv); + +int swServer_get_manager_pid(swServer *serv); +int swServer_get_socket(swServer *serv, int port); +int swServer_worker_init(swServer *serv, swWorker *worker); +swString** swServer_create_worker_buffer(swServer *serv); +int swServer_create_task_worker(swServer *serv); +void swServer_close_listen_port(swServer *serv); +void swServer_enable_accept(swReactor *reactor); +void swServer_reopen_log_file(swServer *serv); + +void swTaskWorker_init(swProcessPool *pool); +int swTaskWorker_onTask(swProcessPool *pool, swEventData *task); +int swTaskWorker_onFinish(swReactor *reactor, swEvent *event); +void swTaskWorker_onStart(swProcessPool *pool, int worker_id); +void swTaskWorker_onStop(swProcessPool *pool, int worker_id); +int swTaskWorker_large_pack(swEventData *task, void *data, int data_len); +int swTaskWorker_finish(swServer *serv, char *data, int data_len, int flags); + +#define swTask_type(task) ((task)->info.from_fd) + +static sw_inline swString* swTaskWorker_large_unpack(swEventData *task_result) +{ + swPackage_task _pkg; + memcpy(&_pkg, task_result->data, sizeof(_pkg)); + + int tmp_file_fd = open(_pkg.tmpfile, O_RDONLY); + if (tmp_file_fd < 0) + { + swSysError("open(%s) failed.", _pkg.tmpfile); + return NULL; + } + if (SwooleTG.buffer_stack->size < _pkg.length && swString_extend_align(SwooleTG.buffer_stack, _pkg.length) < 0) + { + close(tmp_file_fd); + return NULL; + } + if (swoole_sync_readfile(tmp_file_fd, SwooleTG.buffer_stack->str, _pkg.length) < 0) + { + close(tmp_file_fd); + return NULL; + } + close(tmp_file_fd); + if (!(swTask_type(task_result) & SW_TASK_PEEK)) + { + unlink(_pkg.tmpfile); + } + SwooleTG.buffer_stack->length = _pkg.length; + return SwooleTG.buffer_stack; +} + +#define swPackage_data(task) ((task->info.type==SW_EVENT_PACKAGE_END)?SwooleWG.buffer_input[task->info.from_id]->str:task->data) +#define swPackage_length(task) ((task->info.type==SW_EVENT_PACKAGE_END)?SwooleWG.buffer_input[task->info.from_id]->length:task->info.len) + +#define SW_SERVER_MAX_FD_INDEX 0 //max connection socket +#define SW_SERVER_MIN_FD_INDEX 1 //min listen socket +#define SW_SERVER_TIMER_FD_INDEX 2 //for timerfd + +//使用connection_list[0]表示最大的FD +#define swServer_set_maxfd(serv,maxfd) (serv->connection_list[SW_SERVER_MAX_FD_INDEX].fd=maxfd) +#define swServer_get_maxfd(serv) (serv->connection_list[SW_SERVER_MAX_FD_INDEX].fd) +//使用connection_list[1]表示最小的FD +#define swServer_set_minfd(serv,maxfd) (serv->connection_list[SW_SERVER_MIN_FD_INDEX].fd=maxfd) +#define swServer_get_minfd(serv) (serv->connection_list[SW_SERVER_MIN_FD_INDEX].fd) + +#define swServer_get_thread(serv, reactor_id) (&(serv->reactor_threads[reactor_id])) + +static sw_inline swConnection* swServer_connection_get(swServer *serv, int fd) +{ + if (fd > serv->max_connection || fd <= 2) + { + return NULL; + } + else + { + return &serv->connection_list[fd]; + } +} + +static sw_inline swSession* swServer_get_session(swServer *serv, uint32_t session_id) +{ + return &serv->session_list[session_id % SW_SESSION_LIST_SIZE]; +} + +static sw_inline int swServer_get_fd(swServer *serv, uint32_t session_id) +{ + return serv->session_list[session_id % SW_SESSION_LIST_SIZE].fd; +} + +static sw_inline swWorker* swServer_get_worker(swServer *serv, uint16_t worker_id) +{ + //Event Worker + if (worker_id < serv->worker_num) + { + return &(serv->gs->event_workers.workers[worker_id]); + } + + //Task Worker + uint16_t task_worker_max = serv->task_worker_num + serv->worker_num; + if (worker_id < task_worker_max) + { + return &(serv->gs->task_workers.workers[worker_id - serv->worker_num]); + } + + //User Worker + uint16_t user_worker_max = task_worker_max + serv->user_worker_num; + if (worker_id < user_worker_max) + { + return &(serv->user_workers[worker_id - task_worker_max]); + } + + return NULL; +} + +static sw_inline int swServer_worker_schedule(swServer *serv, int fd, swEventData *data) +{ + uint32_t key; + + //polling mode + if (serv->dispatch_mode == SW_DISPATCH_ROUND) + { + key = sw_atomic_fetch_add(&serv->worker_round_id, 1); + } + //Using the FD touch access to hash + else if (serv->dispatch_mode == SW_DISPATCH_FDMOD) + { + key = fd; + } + //Using the IP touch access to hash + else if (serv->dispatch_mode == SW_DISPATCH_IPMOD) + { + swConnection *conn = swServer_connection_get(serv, fd); + //UDP + if (conn == NULL) + { + key = fd; + } + //IPv4 + else if (conn->socket_type == SW_SOCK_TCP) + { + key = conn->info.addr.inet_v4.sin_addr.s_addr; + } + //IPv6 + else + { +#ifdef HAVE_KQUEUE + key = *(((uint32_t *) &conn->info.addr.inet_v6.sin6_addr) + 3); +#else + key = conn->info.addr.inet_v6.sin6_addr.s6_addr32[3]; +#endif + } + } + else if (serv->dispatch_mode == SW_DISPATCH_UIDMOD) + { + swConnection *conn = swServer_connection_get(serv, fd); + if (conn == NULL || conn->uid == 0) + { + key = fd; + } + else + { + key = conn->uid; + } + } + //schedule by dispatch function + else if (serv->dispatch_mode == SW_DISPATCH_USERFUNC) + { + return serv->dispatch_func(serv, swServer_connection_get(serv, fd), data); + } + //Preemptive distribution + else + { + int i; + int found = 0; + for (i = 0; i < serv->worker_num + 1; i++) + { + key = sw_atomic_fetch_add(&serv->worker_round_id, 1) % serv->worker_num; + if (serv->workers[key].status == SW_WORKER_IDLE) + { + found = 1; + break; + } + } + if (unlikely(found == 0)) + { + serv->scheduler_warning = 1; + } + swTraceLog(SW_TRACE_SERVER, "schedule=%d, round=%d", key, serv->worker_round_id); + return key; + } + return key % serv->worker_num; +} + +void swServer_worker_onStart(swServer *serv); +void swServer_worker_onStop(swServer *serv); + +void swServer_set_callback(swServer *serv, int type, void *callback); +void swServer_set_callback_onReceive(swServer *serv, int (*callback)(swServer *, char *, int, int, int)); +void swServer_set_callback_onConnect(swServer *serv, void (*callback)(swServer *, int, int)); +void swServer_set_callback_onClose(swServer *serv, void (*callback)(swServer *, int, int)); + +int swWorker_create(swWorker *worker); +int swWorker_onTask(swFactory *factory, swEventData *task); + +static sw_inline swConnection *swWorker_get_connection(swServer *serv, int session_id) +{ + int real_fd = swServer_get_fd(serv, session_id); + swConnection *conn = swServer_connection_get(serv, real_fd); + return conn; +} + +static sw_inline swString *swWorker_get_buffer(swServer *serv, int worker_id) +{ + if (serv->factory_mode == SW_MODE_SINGLE) + { + return SwooleWG.buffer_input[0]; + } + else if (serv->factory_mode == SW_MODE_THREAD) + { + return SwooleTG.buffer_input[worker_id]; + } + else + { + return SwooleWG.buffer_input[worker_id]; + } +} + +static sw_inline swConnection *swServer_connection_verify_no_ssl(swServer *serv, int session_id) +{ + swSession *session = swServer_get_session(serv, session_id); + int fd = session->fd; + swConnection *conn = swServer_connection_get(serv, fd); + if (!conn || conn->active == 0) + { + return NULL; + } + if (session->id != session_id || conn->session_id != session_id) + { + return NULL; + } + return conn; +} + +static sw_inline swConnection *swServer_connection_verify(swServer *serv, int session_id) +{ + swConnection *conn = swServer_connection_verify_no_ssl(serv, session_id); +#ifdef SW_USE_OPENSSL + if (!conn) + { + return NULL; + } + if (conn->ssl && conn->ssl_state != SW_SSL_STATE_READY) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SSL_NOT_READY, "SSL not ready"); + return NULL; + } +#endif + return conn; +} + +void swPort_init(swListenPort *port); +void swPort_free(swListenPort *port); +void swPort_set_protocol(swListenPort *ls); +int swPort_listen(swListenPort *ls); +#ifdef SW_USE_OPENSSL +int swPort_enable_ssl_encrypt(swListenPort *ls); +#endif +void swPort_clear_protocol(swListenPort *ls); + +void swWorker_free(swWorker *worker); +void swWorker_onStart(swServer *serv); +void swWorker_onStop(swServer *serv); +void swWorker_try_to_exit(); +int swWorker_loop(swFactory *factory, int worker_pti); +int swWorker_send2reactor(swEventData *ev_data, size_t sendn, int fd); +int swWorker_send2worker(swWorker *dst_worker, void *buf, int n, int flag); +void swWorker_signal_handler(int signo); +void swWorker_signal_init(void); +void swWorker_clean(void); + +/** + * reactor_id: The fd in which the reactor. + */ +static sw_inline int swWorker_get_send_pipe(swServer *serv, int session_id, int reactor_id) +{ + int pipe_index = session_id % serv->reactor_pipe_num; + /** + * pipe_worker_id: The pipe in which worker. + */ + int pipe_worker_id = reactor_id + (pipe_index * serv->reactor_num); + swWorker *worker = swServer_get_worker(serv, pipe_worker_id); + return worker->pipe_worker; +} + +int swReactorThread_create(swServer *serv); +int swReactorThread_start(swServer *serv, swReactor *main_reactor_ptr); +void swReactorThread_set_protocol(swServer *serv, swReactor *reactor); +void swReactorThread_free(swServer *serv); +int swReactorThread_close(swReactor *reactor, int fd); +int swReactorThread_onClose(swReactor *reactor, swEvent *event); +int swReactorThread_dispatch(swConnection *conn, char *data, uint32_t length); +int swReactorThread_send(swSendData *_send); +int swReactorThread_send2worker(void *data, int len, uint16_t target_worker_id); + +int swReactorProcess_create(swServer *serv); +int swReactorProcess_start(swServer *serv); +int swReactorProcess_onClose(swReactor *reactor, swEvent *event); + +int swManager_start(swFactory *factory); +pid_t swManager_spawn_user_worker(swServer *serv, swWorker* worker); +int swManager_wait_user_worker(swProcessPool *pool, pid_t pid, int status); +void swManager_kill_user_worker(swServer *serv); + +#ifdef __cplusplus +} +#endif + +#endif /* SW_SERVER_H_ */ diff --git a/vendor/swoole/include/array.h b/vendor/swoole/include/array.h new file mode 100755 index 0000000..dbc6227 --- /dev/null +++ b/vendor/swoole/include/array.h @@ -0,0 +1,63 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef _SW_ARRAY_H_ +#define _SW_ARRAY_H_ + +/** + * 默认swArray->pages指针数组的长度为SW_ARRAY_PAGE_MAX,也就是最多可以管理(SW_ARRAY_PAGE_MAX*page_size)个元素 + */ +#define SW_ARRAY_PAGE_MAX 1024 + +typedef struct _swArray +{ + void **pages; + + /** + * 页的数量 + */ + uint16_t page_num; + + /** + * 每页的数据元素个数 + */ + uint16_t page_size; + + /** + * 数据元素的尺寸 + */ + uint32_t item_size; + + /** + * 数据个数 + */ + uint32_t item_num; + uint32_t offset; +} swArray; + +#define swArray_page(array, n) ((n) / (array)->page_size) +#define swArray_offset(array, n) ((n) % (array)->page_size) + +swArray *swArray_new(int page_size, size_t item_size); +void swArray_free(swArray *array); +void *swArray_fetch(swArray *array, uint32_t n); +int swArray_store(swArray *array, uint32_t n, void *data); +void *swArray_alloc(swArray *array, uint32_t n); +int swArray_append(swArray *array, void *data); +int swArray_extend(swArray *array); +void swArray_clear(swArray *array); + +#endif /* _SW_ARRAY_H_ */ diff --git a/vendor/swoole/include/asm_context.h b/vendor/swoole/include/asm_context.h new file mode 100755 index 0000000..7c6f9f9 --- /dev/null +++ b/vendor/swoole/include/asm_context.h @@ -0,0 +1,44 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2018 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef _SW_ASM_CONTEXT_H_ +#define _SW_ASM_CONTEXT_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdint.h> +#include <stdio.h> +#include <stddef.h> + +#ifndef SW_NO_USE_ASM_CONTEXT + +typedef void* fcontext_t; + +intptr_t jump_fcontext(fcontext_t *ofc, fcontext_t nfc, intptr_t vp, bool preserve_fpu = false); +fcontext_t make_fcontext(void *sp, size_t size, void (*fn)(intptr_t)); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/swoole/include/async.h b/vendor/swoole/include/async.h new file mode 100755 index 0000000..4c74385 --- /dev/null +++ b/vendor/swoole/include/async.h @@ -0,0 +1,95 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2018 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef _SW_ASYNC_H_ +#define _SW_ASYNC_H_ + +#ifndef O_DIRECT +#define O_DIRECT 040000 +#endif + +enum swAioOpcode +{ + SW_AIO_READ = 0, + SW_AIO_WRITE = 1, + SW_AIO_GETHOSTBYNAME = 2, + SW_AIO_GETADDRINFO = 3, + SW_AIO_STREAM_GET_LINE = 4, + SW_AIO_READ_FILE, + SW_AIO_WRITE_FILE, +}; + +enum swAioFlag +{ + SW_AIO_WRITE_FSYNC = 1u << 1, + SW_AIO_EOF = 1u << 2, +}; + +typedef struct _swAio_event +{ + int fd; + int task_id; + uint8_t type; + uint16_t flags; + off_t offset; + size_t nbytes; + void *buf; + void *req; + int ret; + int error; + void *object; + void (*callback)(struct _swAio_event *event); +} swAio_event; + +typedef void (*swAio_handler)(swAio_event *event); + +typedef struct +{ + uint8_t init; + uint8_t thread_num; + uint32_t task_num; + uint16_t current_id; + swLock lock; + + swAio_handler handlers[SW_AIO_HANDLER_MAX_SIZE]; + void (*destroy)(void); + void (*callback)(swAio_event *aio_event); + int (*read)(int fd, void *outbuf, size_t size, off_t offset); + int (*write)(int fd, void *inbuf, size_t size, off_t offset); +} swAsyncIO; + +extern swAsyncIO SwooleAIO; +extern swPipe swoole_aio_pipe; + +void swAio_callback_test(swAio_event *aio_event); +int swAio_init(void); +void swAio_free(void); +int swAioBase_init(int max_aio_events); +int swAio_dns_lookup(void *hostname, void *ip_addr, size_t size); +int swAio_dispatch(swAio_event *_event); + +#ifdef HAVE_GCC_AIO +int swAioGcc_init(int max_aio_events); +#endif + +#ifdef HAVE_LINUX_AIO +#define SW_AIO_MIN_UNIT_SIZE 512 +int swAioLinux_init(int max_aio_events); +#endif + +#endif /* _SW_ASYNC_H_ */ diff --git a/vendor/swoole/include/atomic.h b/vendor/swoole/include/atomic.h new file mode 100755 index 0000000..d22b037 --- /dev/null +++ b/vendor/swoole/include/atomic.h @@ -0,0 +1,43 @@ +#ifndef SW_ATOMIC_H_ +#define SW_ATOMIC_H_ + +typedef volatile int32_t sw_atomic_int32_t; +typedef volatile uint32_t sw_atomic_uint32_t; + +#ifdef __x86_64__ +typedef volatile int64_t sw_atomic_int64_t; +typedef volatile uint64_t sw_atomic_uint64_t; +#endif + +#ifdef __x86_64__ +typedef sw_atomic_int64_t sw_atomic_long_t; +typedef sw_atomic_uint64_t sw_atomic_ulong_t; +#else +typedef sw_atomic_int32_t sw_atomic_long_t; +typedef sw_atomic_uint32_t sw_atomic_ulong_t; +#endif + +typedef sw_atomic_uint32_t sw_atomic_t; + +#define sw_atomic_cmp_set(lock, old, set) __sync_bool_compare_and_swap(lock, old, set) +#define sw_atomic_fetch_add(value, add) __sync_fetch_and_add(value, add) +#define sw_atomic_fetch_sub(value, sub) __sync_fetch_and_sub(value, sub) +#define sw_atomic_memory_barrier() __sync_synchronize() +#define sw_atomic_add_fetch(value, add) __sync_add_and_fetch(value, add) +#define sw_atomic_sub_fetch(value, sub) __sync_sub_and_fetch(value, sub) + +#ifdef __arm__ +#define sw_atomic_cpu_pause() __asm__ __volatile__ ("NOP"); +#elif defined(__x86_64__) +#define sw_atomic_cpu_pause() __asm__ __volatile__ ("pause") +#else +#define sw_atomic_cpu_pause() +#endif + +#if 0 +#define sw_spinlock_release(lock) __sync_lock_release(lock) +#else +#define sw_spinlock_release(lock) *(lock) = 0 +#endif + +#endif diff --git a/vendor/swoole/include/base64.h b/vendor/swoole/include/base64.h new file mode 100755 index 0000000..da386bd --- /dev/null +++ b/vendor/swoole/include/base64.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_BASE64_H__ +#define SW_BASE64_H__ + +enum +{ + BASE64_OK = 0, BASE64_INVALID +}; + +#define BASE64_ENCODE_OUT_SIZE(s) (((s) + 2) / 3 * 4) +#define BASE64_DECODE_OUT_SIZE(s) (((s)) / 4 * 3) + +int swBase64_encode(unsigned char *in, int inlen, char *out); +int swBase64_decode(char *in, int inlen, unsigned char *out); + +#endif /* SW_BASE64_H__ */ diff --git a/vendor/swoole/include/buffer.h b/vendor/swoole/include/buffer.h new file mode 100755 index 0000000..9570b08 --- /dev/null +++ b/vendor/swoole/include/buffer.h @@ -0,0 +1,76 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_BUFFER_H_ +#define SW_BUFFER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum swBufferChunk +{ + SW_CHUNK_DATA, + SW_CHUNK_SENDFILE, + SW_CHUNK_CLOSE, +}; + +typedef struct _swBuffer_trunk +{ + uint32_t type; + uint32_t length; + uint32_t offset; + union + { + void *ptr; + struct + { + uint32_t val1; + uint32_t val2; + } data; + } store; + uint32_t size; + void (*destroy)(struct _swBuffer_trunk *chunk); + struct _swBuffer_trunk *next; +} swBuffer_trunk; + +typedef struct _swBuffer +{ + int fd; + uint8_t trunk_num; //trunk数量 + uint16_t trunk_size; + uint32_t length; + swBuffer_trunk *head; + swBuffer_trunk *tail; +} swBuffer; + +#define swBuffer_get_trunk(buffer) (buffer->head) +#define swBuffer_empty(buffer) (buffer == NULL || buffer->head == NULL) + +swBuffer* swBuffer_new(int trunk_size); +swBuffer_trunk *swBuffer_new_trunk(swBuffer *buffer, uint32_t type, uint32_t size); +void swBuffer_pop_trunk(swBuffer *buffer, swBuffer_trunk *trunk); +int swBuffer_append(swBuffer *buffer, void *data, uint32_t size); + +void swBuffer_debug(swBuffer *buffer, int print_data); +int swBuffer_free(swBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /* SW_BUFFER_H_ */ diff --git a/vendor/swoole/include/context.h b/vendor/swoole/include/context.h new file mode 100755 index 0000000..a007e25 --- /dev/null +++ b/vendor/swoole/include/context.h @@ -0,0 +1,109 @@ +#pragma once + +#ifdef SW_NO_USE_ASM_CONTEXT +#ifdef HAVE_BOOST_CONTEXT +#define USE_BOOST_CONTEXT 1 +#include <boost/context/all.hpp> +#else +#define USE_UCONTEXT 1 +#include <ucontext.h> +#endif +#else +#include "asm_context.h" +#endif + +#ifdef HAVE_VALGRIND +#define USE_VALGRIND 0 +#endif + +#include "swoole.h" +#include "coroutine.h" +#include "error.h" + +#if __linux__ +#include <sys/mman.h> +#endif + +#ifdef USE_VALGRIND +#include <valgrind/valgrind.h> +#endif + +namespace swoole +{ +//namespace start +static uint32_t& get_protect_stack_page() +{ + static uint32_t protect_stack_page = 0; + return protect_stack_page; +} + +static bool protect_stack(void *top, size_t stack_size, uint32_t page) +{ + if (stack_size <= SwooleG.pagesize * (page + 1)) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_CO_PROTECT_STACK_FAILED, "getpagesize() failed."); + return false; + } + + void *protect_page_addr = ((size_t) top & 0xfff) ? (void*) (((size_t) top & ~(size_t) 0xfff) + 0x1000) : top; + if (-1 == mprotect(protect_page_addr, SwooleG.pagesize * page, PROT_NONE)) + { + swSysError("mprotect() failed: origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top, + protect_page_addr, SwooleG.pagesize, page); + return false; + } + else + { + swDebug("origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u", top, protect_page_addr, page, SwooleG.pagesize); + return true; + } +} +static bool unprotect_stack(void *top, uint32_t page) +{ + void *protect_page_addr = ((size_t) top & 0xfff) ? (void*) (((size_t) top & ~(size_t) 0xfff) + 0x1000) : top; + if (-1 == mprotect(protect_page_addr, SwooleG.pagesize * page, PROT_READ | PROT_WRITE)) + { + swSysError("mprotect() failed: origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top, + protect_page_addr, SwooleG.pagesize, page); + return false; + } + else + { + swDebug("origin_addr:%p, align_addr:%p, page_size:%d, protect_page:%u.", top, protect_page_addr, page, SwooleG.pagesize); + return true; + } +} +class Context +{ +public: + Context(size_t stack_size, coroutine_func_t fn, void* private_data); + ~Context(); + bool SwapIn(); + bool SwapOut(); + static void context_func(void* arg); +public: + bool end; + +private: +#ifdef USE_BOOST_CONTEXT + boost::context::fcontext_t ctx_; + boost::context::fcontext_t swap_ctx_; +#elif USE_UCONTEXT + ucontext_t swap_ctx_; + ucontext_t ctx_; +#else + fcontext_t ctx_; + fcontext_t swap_ctx_; +#endif + coroutine_func_t fn_; + char* stack_; + uint32_t stack_size_; + uint32_t protect_page_; +#ifdef USE_VALGRIND + uint32_t valgrind_stack_id; +#endif + void *private_data_; +}; +//namespace end +} + diff --git a/vendor/swoole/include/coroutine.h b/vendor/swoole/include/coroutine.h new file mode 100755 index 0000000..be1acaa --- /dev/null +++ b/vendor/swoole/include/coroutine.h @@ -0,0 +1,42 @@ +#ifndef SW_COROUTINE_H_ +#define SW_COROUTINE_H_ + +#include "swoole.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +void coro_yield(); +void coro_handle_timeout(); + +#define DEFAULT_MAX_CORO_NUM 3000 +#define DEFAULT_STACK_SIZE 8192 +#define MAX_CORO_NUM_LIMIT 0x80000 + +#define CORO_END 0 +#define CORO_YIELD 1 +#define CORO_LIMIT -1 +#define CORO_SAVE 3 + +typedef struct coroutine_s coroutine_t; +typedef void (*coroutine_func_t)(void*); +typedef void (*coroutine_close_t)(); + +typedef enum +{ + SW_CORO_YIELD = 0, SW_CORO_SUSPENDED, SW_CORO_RUNNING, SW_CORO_END, +} sw_coro_state; + +int coroutine_create(coroutine_func_t func, void* args); +void coroutine_resume(coroutine_t *co); +void coroutine_yield(coroutine_t *co); +void coroutine_release(coroutine_t *co); +coroutine_t *coroutine_get_by_id(int cid); +int coroutine_get_cid(); +void coroutine_set_close(coroutine_close_t func); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif +#endif diff --git a/vendor/swoole/include/error.h b/vendor/swoole/include/error.h new file mode 100755 index 0000000..f8d39b2 --- /dev/null +++ b/vendor/swoole/include/error.h @@ -0,0 +1,133 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_ERRNO_H_ +#define SW_ERRNO_H_ + +enum swErrorCode +{ + /** + * common error + */ + SW_ERROR_MALLOC_FAIL = 501, + SW_ERROR_SYSTEM_CALL_FAIL, + SW_ERROR_PHP_FATAL_ERROR, + SW_ERROR_NAME_TOO_LONG, + SW_ERROR_INVALID_PARAMS, + SW_ERROR_QUEUE_FULL, + + SW_ERROR_FILE_NOT_EXIST = 700, + SW_ERROR_FILE_TOO_LARGE, + SW_ERROR_FILE_EMPTY, + SW_ERROR_DNSLOOKUP_DUPLICATE_REQUEST, + SW_ERROR_DNSLOOKUP_RESOLVE_FAILED, + SW_ERROR_BAD_IPV6_ADDRESS, + + /** + * connection error + */ + SW_ERROR_SESSION_CLOSED_BY_SERVER = 1001, + SW_ERROR_SESSION_CLOSED_BY_CLIENT, + SW_ERROR_SESSION_CLOSING, + SW_ERROR_SESSION_CLOSED, + SW_ERROR_SESSION_NOT_EXIST, + SW_ERROR_SESSION_INVALID_ID, + SW_ERROR_SESSION_DISCARD_TIMEOUT_DATA, + SW_ERROR_OUTPUT_BUFFER_OVERFLOW, + SW_ERROR_SSL_NOT_READY, + SW_ERROR_SSL_CANNOT_USE_SENFILE, + SW_ERROR_SSL_EMPTY_PEER_CERTIFICATE, + SW_ERROR_SSL_VEFIRY_FAILED, + SW_ERROR_SSL_BAD_CLIENT, + SW_ERROR_SSL_BAD_PROTOCOL, + + SW_ERROR_PACKAGE_LENGTH_TOO_LARGE = 1201, + SW_ERROR_DATA_LENGTH_TOO_LARGE, + + /** + * task error + */ + SW_ERROR_TASK_PACKAGE_TOO_BIG = 2001, + SW_ERROR_TASK_DISPATCH_FAIL, + + /** + * http2 protocol error + */ + SW_ERROR_HTTP2_STREAM_ID_TOO_BIG = 3001, + SW_ERROR_HTTP2_STREAM_NO_HEADER, + + /** + * AIO + */ + SW_ERROR_AIO_BAD_REQUEST = 4001, + + /** + * Client + */ + SW_ERROR_CLIENT_NO_CONNECTION = 5001, + + SW_ERROR_SOCKS5_UNSUPPORT_VERSION = 7001, + SW_ERROR_SOCKS5_UNSUPPORT_METHOD, + SW_ERROR_SOCKS5_AUTH_FAILED, + SW_ERROR_SOCKS5_SERVER_ERROR, + + SW_ERROR_HTTP_PROXY_HANDSHAKE_ERROR = 8001, + SW_ERROR_HTTP_INVALID_PROTOCOL, + + SW_ERROR_WEBSOCKET_BAD_CLIENT = 8501, + SW_ERROR_WEBSOCKET_BAD_OPCODE, + SW_ERROR_WEBSOCKET_UNCONNECTED, + SW_ERROR_WEBSOCKET_HANDSHAKE_FAILED, + + /** + * server global error + */ + SW_ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT = 9001, + SW_ERROR_SERVER_TOO_MANY_SOCKET, + SW_ERROR_SERVER_WORKER_TERMINATED, + SW_ERROR_SERVER_INVALID_LISTEN_PORT, + SW_ERROR_SERVER_TOO_MANY_LISTEN_PORT, + SW_ERROR_SERVER_PIPE_BUFFER_FULL, + SW_ERROR_SERVER_NO_IDLE_WORKER, + + SW_ERROR_SERVER_ONLY_START_ONE, + + /** + * Process exit timeout, forced to end. + */ + SW_ERROR_SERVER_WORKER_EXIT_TIMEOUT, + + /** + * Coroutine + */ + SW_ERROR_CO_MUTEX_DOUBLE_UNLOCK = 10001, + SW_ERROR_CO_BLOCK_OBJECT_LOCKED, + SW_ERROR_CO_BLOCK_OBJECT_WAITING, + SW_ERROR_CO_YIELD_FAILED, + SW_ERROR_CO_GETCONTEXT_FAILED, + SW_ERROR_CO_SWAPCONTEXT_FAILED, + SW_ERROR_CO_MAKECONTEXT_FAILED, + + SW_ERROR_CO_IOCPINIT_FAILED, + SW_ERROR_CO_PROTECT_STACK_FAILED, + SW_ERROR_CO_STD_THREAD_LINK_ERROR, + SW_ERROR_CO_DISABLED_MULTI_THREAD, + +}; + +void swoole_throw_error(enum swErrorCode code); + +#endif /* SW_ERRNO_H_ */ diff --git a/vendor/swoole/include/hash.h b/vendor/swoole/include/hash.h new file mode 100755 index 0000000..654b91f --- /dev/null +++ b/vendor/swoole/include/hash.h @@ -0,0 +1,218 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_HASH_H_ +#define SW_HASH_H_ + +#include <stdint.h> + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +/** + * jenkins + */ +static inline uint64_t swoole_hash_jenkins(char *key, uint32_t keylen) +{ + uint64_t hashv; + + unsigned i, j, k; + hashv = 0xfeedbeef; + i = j = 0x9e3779b9; + k = (unsigned) (keylen); + + while (k >= 12) + { + i += (key[0] + ((unsigned) key[1] << 8) + ((unsigned) key[2] << 16) + + ((unsigned) key[3] << 24)); + j += (key[4] + ((unsigned) key[5] << 8) + ((unsigned) key[6] << 16) + + ((unsigned) key[7] << 24)); + hashv += (key[8] + ((unsigned) key[9] << 8) + ((unsigned) key[10] << 16) + + ((unsigned) key[11] << 24)); + + HASH_JEN_MIX(i, j, hashv); + + key += 12; + k -= 12; + } + hashv += keylen; + switch (k) + { + case 11: + hashv += ((unsigned) key[10] << 24); + /* no break */ + case 10: + hashv += ((unsigned) key[9] << 16); + /* no break */ + case 9: + hashv += ((unsigned) key[8] << 8); + /* no break */ + case 8: + j += ((unsigned) key[7] << 24); + /* no break */ + case 7: + j += ((unsigned) key[6] << 16); + /* no break */ + case 6: + j += ((unsigned) key[5] << 8); + /* no break */ + case 5: + j += key[4]; + /* no break */ + case 4: + i += ((unsigned) key[3] << 24); + /* no break */ + case 3: + i += ((unsigned) key[2] << 16); + /* no break */ + case 2: + i += ((unsigned) key[1] << 8); + /* no break */ + case 1: + i += key[0]; + } + HASH_JEN_MIX(i, j, hashv); + return hashv; +} + +/** + * MurmurHash2(Austin Appleby) + */ +static inline uint32_t swoole_hash_austin(char *key, unsigned int keylen) +{ + unsigned int h, k; + h = 0 ^ keylen; + + while (keylen >= 4) + { + k = key[0]; + k |= key[1] << 8; + k |= key[2] << 16; + k |= key[3] << 24; + + k *= 0x5bd1e995; + k ^= k >> 24; + k *= 0x5bd1e995; + + h *= 0x5bd1e995; + h ^= k; + + key += 4; + keylen -= 4; + } + + switch (keylen) + { + case 3: + h ^= key[2] << 16; + /* no break */ + case 2: + h ^= key[1] << 8; + /* no break */ + case 1: + h ^= key[0]; + h *= 0x5bd1e995; + } + + h ^= h >> 13; + h *= 0x5bd1e995; + h ^= h >> 15; + + return h; +} + +/* {{{ DJBX33A (Daniel J. Bernstein, Times 33 with Addition) + * + * This is Daniel J. Bernstein's popular `times 33' hash function as + * posted by him years ago on comp->lang.c. It basically uses a function + * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best + * known hash functions for strings. Because it is both computed very + * fast and distributes very well. + * + * The magic of number 33, i.e. why it works better than many other + * constants, prime or not, has never been adequately explained by + * anyone. So I try an explanation: if one experimentally tests all + * multipliers between 1 and 256 (as RSE did now) one detects that even + * numbers are not useable at all. The remaining 128 odd numbers + * (except for the number 1) work more or less all equally well. They + * all distribute in an acceptable way and this way fill a hash table + * with an average percent of approx. 86%. + * + * If one compares the Chi^2 values of the variants, the number 33 not + * even has the best value. But the number 33 and a few other equally + * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great + * advantage to the remaining numbers in the large set of possible + * multipliers: their multiply operation can be replaced by a faster + * operation based on just one shift plus either a single addition + * or subtraction operation. And because a hash function has to both + * distribute good _and_ has to be very fast to compute, those few + * numbers should be preferred and seems to be the reason why Daniel J. + * Bernstein also preferred it. + * + * -- Ralf S. Engelschall <rse@engelschall.com> + */ +static inline uint64_t swoole_hash_php(char *key, uint32_t len) +{ + register ulong_t hash = 5381; + /* variant with the hash unrolled eight times */ + for (; len >= 8; len -= 8) + { + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + hash = ((hash << 5) + hash) + *key++; + } + + switch (len) + { + case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */ + /* no break */ + case 1: hash = ((hash << 5) + hash) + *key++; break; + case 0: break; + default: break; + } + return hash; +} + +#define CRC_STRING_MAXLEN 256 + +uint32_t swoole_crc32(char *data, uint32_t size); + +#endif /* SW_HASH_H_ */ diff --git a/vendor/swoole/include/hashmap.h b/vendor/swoole/include/hashmap.h new file mode 100755 index 0000000..e5df991 --- /dev/null +++ b/vendor/swoole/include/hashmap.h @@ -0,0 +1,55 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef __SW_HASHMAP_H +#define __SW_HASHMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*swHashMap_dtor)(void *data); + +typedef struct +{ + struct swHashMap_node *root; + struct swHashMap_node *iterator; + swHashMap_dtor dtor; +} swHashMap; + +swHashMap* swHashMap_new(uint32_t bucket_num, swHashMap_dtor dtor); +void swHashMap_free(swHashMap *hmap); + +int swHashMap_add(swHashMap *hmap, char *key, uint16_t key_len, void *data); +int swHashMap_add_int(swHashMap *hmap, uint64_t key, void *data); +void* swHashMap_find(swHashMap *hmap, char *key, uint16_t key_len); +void* swHashMap_find_int(swHashMap *hmap, uint64_t key); +void swHashMap_update_int(swHashMap *hmap, uint64_t key, void *data); +int swHashMap_update(swHashMap *hmap, char *key, uint16_t key_len, void *data); +int swHashMap_del(swHashMap *hmap, char *key, uint16_t key_len); +int swHashMap_del_int(swHashMap *hmap, uint64_t key); +int swHashMap_move(swHashMap *hmap, char *old_key, uint16_t old_key_len, char *new_key, uint16_t new_key_len); +int swHashMap_move_int(swHashMap *hmap, uint64_t old_key, uint64_t new_key); +void* swHashMap_each(swHashMap* hmap, char **key); +void* swHashMap_each_int(swHashMap* hmap, uint64_t *key); +#define swHashMap_each_reset(hmap) (hmap->iterator = NULL) +uint32_t swHashMap_count(swHashMap* hmap); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/vendor/swoole/include/heap.h b/vendor/swoole/include/heap.h new file mode 100755 index 0000000..ad3833f --- /dev/null +++ b/vendor/swoole/include/heap.h @@ -0,0 +1,59 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SW_MINHEAP_H_ +#define SW_MINHEAP_H_ + +enum swHeap_type +{ + SW_MIN_HEAP, SW_MAX_HEAP, +}; + +typedef struct swHeap_node +{ + uint64_t priority; + uint32_t position; + void *data; +} swHeap_node; + +typedef struct _swHeap +{ + uint32_t num; + uint32_t size; + uint8_t type; + swHeap_node **nodes; +} swHeap; + +swHeap *swHeap_new(size_t n, uint8_t type); +void swHeap_free(swHeap *heap); +uint32_t swHeap_size(swHeap *heap); +swHeap_node* swHeap_push(swHeap *heap, uint64_t priority, void *data); +void *swHeap_pop(swHeap *heap); +void swHeap_change_priority(swHeap *heap, uint64_t new_priority, void* ptr); +int swHeap_remove(swHeap *heap, swHeap_node *node); +void *swHeap_peek(swHeap *heap); +void swHeap_print(swHeap *heap); + +static inline swHeap_node *swHeap_top(swHeap *heap) +{ + if (heap->num == 1) + { + return NULL; + } + return heap->nodes[1]; +} + +#endif /* SW_MINHEAP_H_ */ diff --git a/vendor/swoole/include/helper/kqueue.h b/vendor/swoole/include/helper/kqueue.h new file mode 100755 index 0000000..4b835ad --- /dev/null +++ b/vendor/swoole/include/helper/kqueue.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef KQUEUE_IDE_HELPER_H_ +#define KQUEUE_IDE_HELPER_H_ + +struct kevent +{ + char *udata; + int filter; +}; + +#define EVFILT_READ 1 +#define EVFILT_WRITE 2 + +#define EV_ADD 2 +#define EV_DELETE 4 +#define EV_CLEAR 8 + +int kevent(int, void *, int, struct kevent*, int, struct timespec *); +int kqueue(void); +int EV_SET(struct kevent*, int, int, int, int, int, void*); + +#endif /* KQUEUE_IDE_HELPER_H_ */ diff --git a/vendor/swoole/include/http.h b/vendor/swoole/include/http.h new file mode 100755 index 0000000..d42ef03 --- /dev/null +++ b/vendor/swoole/include/http.h @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SW_HTTP_H_ +#define SW_HTTP_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <sys/types.h> +#include <stdint.h> + +enum swHttpMethod +{ + HTTP_DELETE = 1, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, + /* pathological */ + HTTP_CONNECT, HTTP_OPTIONS, HTTP_TRACE, + /* webdav */ + HTTP_COPY, HTTP_LOCK, HTTP_MKCOL, HTTP_MOVE, HTTP_PROPFIND, HTTP_PROPPATCH, HTTP_UNLOCK, + /* subversion */ + HTTP_REPORT, HTTP_MKACTIVITY, HTTP_CHECKOUT, HTTP_MERGE, + /* upnp */ + HTTP_MSEARCH, HTTP_NOTIFY, HTTP_SUBSCRIBE, HTTP_UNSUBSCRIBE, + /* Http2 */ + HTTP_PRI, +}; + +enum swHttpVersion +{ + HTTP_VERSION_10 = 1, + HTTP_VERSION_11, +}; + +typedef struct _swHttpRequest +{ + uint8_t method; + uint8_t offset; + uint8_t version; + uint8_t free_memory; + uint8_t opcode; + uint8_t excepted; + + uint32_t url_offset; + uint32_t url_length; + + uint32_t header_length; + uint32_t content_length; + swString *buffer; + +} swHttpRequest; + +int swHttp_get_method(const char *method_str, int method_len); +const char* swHttp_get_method_string(int method); +int swHttpRequest_get_protocol(swHttpRequest *request); +int swHttpRequest_get_content_length(swHttpRequest *request); +int swHttpRequest_get_header_length(swHttpRequest *request); +void swHttpRequest_free(swConnection *conn); +#ifdef SW_HTTP_100_CONTINUE +int swHttpRequest_has_expect_header(swHttpRequest *request); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SW_HTTP_H_ */ diff --git a/vendor/swoole/include/http2.h b/vendor/swoole/include/http2.h new file mode 100755 index 0000000..0cb6eb2 --- /dev/null +++ b/vendor/swoole/include/http2.h @@ -0,0 +1,160 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_HTTP2_H_ +#define SW_HTTP2_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SW_HTTP2_PRI_STRING "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + +enum swHttp2ErrorCode +{ + SW_HTTP2_ERROR_NO_ERROR = 0, + SW_HTTP2_ERROR_PROTOCOL_ERROR = 1, + SW_HTTP2_ERROR_INTERNAL_ERROR = 2, + SW_HTTP2_ERROR_FLOW_CONTROL_ERROR = 3, + SW_HTTP2_ERROR_SETTINGS_TIMEOUT = 4, + SW_HTTP2_ERROR_STREAM_CLOSED = 5, + SW_HTTP2_ERROR_FRAME_SIZE_ERROR = 6, + SW_HTTP2_ERROR_REFUSED_STREAM = 7, + SW_HTTP2_ERROR_CANCEL = 8, + SW_HTTP2_ERROR_COMPRESSION_ERROR = 9, + SW_HTTP2_ERROR_CONNECT_ERROR = 10, + SW_HTTP2_ERROR_ENHANCE_YOUR_CALM = 11, + SW_HTTP2_ERROR_INADEQUATE_SECURITY = 12, +}; + +enum swHttp2FrameType +{ + SW_HTTP2_TYPE_DATA = 0, + SW_HTTP2_TYPE_HEADERS = 1, + SW_HTTP2_TYPE_PRIORITY = 2, + SW_HTTP2_TYPE_RST_STREAM = 3, + SW_HTTP2_TYPE_SETTINGS = 4, + SW_HTTP2_TYPE_PUSH_PROMISE = 5, + SW_HTTP2_TYPE_PING = 6, + SW_HTTP2_TYPE_GOAWAY = 7, + SW_HTTP2_TYPE_WINDOW_UPDATE = 8, + SW_HTTP2_TYPE_CONTINUATION = 9, +}; + +enum swHttp2FrameFlag +{ + SW_HTTP2_FLAG_NONE = 0x00, + SW_HTTP2_FLAG_ACK = 0x01, + SW_HTTP2_FLAG_END_STREAM = 0x01, + SW_HTTP2_FLAG_END_HEADERS = 0x04, + SW_HTTP2_FLAG_PADDED = 0x08, + SW_HTTP2_FLAG_PRIORITY = 0x20, +}; + +enum swHttp2SettingId +{ + SW_HTTP2_SETTING_HEADER_TABLE_SIZE = 0x1, + SW_HTTP2_SETTINGS_ENABLE_PUSH = 0x2, + SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS = 0x3, + SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE = 0x4, + SW_HTTP2_SETTINGS_MAX_FRAME_SIZE = 0x5, + SW_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x6, +}; + +enum swHttp2StreamType +{ + SW_HTTP2_STREAM_NORMAL = 0, + SW_HTTP2_STREAM_PIPELINE = 1, +}; + +#define SW_HTTP2_FRAME_HEADER_SIZE 9 +#define SW_HTTP2_SETTING_OPTION_SIZE 6 +#define SW_HTTP2_FRAME_PING_PAYLOAD_SIZE 8 + +#define SW_HTTP2_RST_STREAM_SIZE 4 +#define SW_HTTP2_PRIORITY_SIZE 5 +#define SW_HTTP2_PING_SIZE 8 +#define SW_HTTP2_GOAWAY_SIZE 8 +#define SW_HTTP2_WINDOW_UPDATE_SIZE 4 +#define SW_HTTP2_STREAM_ID_SIZE 4 +#define SW_HTTP2_SETTINGS_PARAM_SIZE 6 + +/** + +-----------------------------------------------+ + | Length (24) | + +---------------+---------------+---------------+ + | Type (8) | Flags (8) | + +-+-------------+---------------+-------------------------------+ + |R| Stream Identifier (31) | + +=+=============================================================+ + | Frame Payload (0...) ... + +---------------------------------------------------------------+ + */ +typedef struct +{ + uint32_t length :24; + uint32_t type :8; + uint32_t flags :8; + uint32_t rsv1 :1; + uint32_t identifier :31; + char data[0]; +} swHttp2_frame; + +static sw_inline uint32_t swHttp2_get_length(char *buf) +{ + return (((uint8_t) buf[0]) << 16) + (((uint8_t) buf[1]) << 8) + (uint8_t) buf[2]; +} + +static sw_inline uint32_t swHttp2_get_increment_size(char *buf) +{ + return (((uint8_t) buf[1 + SW_HTTP2_FRAME_HEADER_SIZE]) << 16) \ + + (((uint8_t) buf[2 + SW_HTTP2_FRAME_HEADER_SIZE]) << 8) \ + + (uint8_t) buf[3 + SW_HTTP2_FRAME_HEADER_SIZE]; +} + + +int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length); +int swHttp2_send_setting_frame(swProtocol *protocol, swConnection *conn); +int swHttp2_parse_frame(swProtocol *protocol, swConnection *conn, char *data, uint32_t length); +char* swHttp2_get_type(int type); + +/** + +-----------------------------------------------+ + | Length (24) | + +---------------+---------------+---------------+ + | Type (8) | Flags (8) | + +-+-------------+---------------+-------------------------------+ + |R| Stream Identifier (31) | + +=+=============================================================+ + | Frame Payload (0...) ... + +---------------------------------------------------------------+ + */ +static void sw_inline swHttp2_set_frame_header(char *buffer, int type, int length, int flags, int stream_id) +{ + buffer[0] = length >> 16; + buffer[1] = length >> 8; + buffer[2] = length; + buffer[3] = type; + buffer[4] = flags; + *(int*) (buffer + 5) = htonl(stream_id); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SW_HTTP2_H_ */ diff --git a/vendor/swoole/include/list.h b/vendor/swoole/include/list.h new file mode 100755 index 0000000..c5c5345 --- /dev/null +++ b/vendor/swoole/include/list.h @@ -0,0 +1,753 @@ +/* +Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTLIST_H +#define UTLIST_H + +#define UTLIST_VERSION 1.9.9 + +#include <assert.h> + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ code), this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#endif +#elif defined(__ICCARM__) +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define _NEXT(elt,list,next) ((char*)((list)->next)) +#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ +#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define _SV(elt,list) +#define _NEXT(elt,list,next) ((elt)->next) +#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +/* #define _PREV(elt,list,prev) ((elt)->prev) */ +#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) +#define _RS(list) +#define _CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ + LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + + +#define DL_SORT(list, cmp) \ + DL_SORT2(list, cmp, prev, next) + +#define DL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while ((_ls_psize > 0) || ((_ls_qsize > 0) && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } else if ((_ls_qsize == 0) || (!_ls_q)) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev, _ls_tail); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +#define CDL_SORT(list, cmp) \ + CDL_SORT2(list, cmp, prev, next) + +#define CDL_SORT2(list, cmp, prev, next) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); \ + if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = _NEXT(_ls_q,list,next); \ + } \ + _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ + _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ + _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev,_ls_tail); \ + _CASTASGN(_tmp,list); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ + LL_PREPEND2(head,add,next) + +#define LL_PREPEND2(head,add,next) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#define LL_CONCAT(head1,head2) \ + LL_CONCAT2(head1,head2,next) + +#define LL_CONCAT2(head1,head2,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = head1; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(head2); \ + } else { \ + (head1)=(head2); \ + } \ +} while (0) + +#define LL_APPEND(head,add) \ + LL_APPEND2(head,add,next) + +#define LL_APPEND2(head,add,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_DELETE(head,del) \ + LL_DELETE2(head,del,next) + +#define LL_DELETE2(head,del,next) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ +#define LL_APPEND_VS2008(head,add) \ + LL_APPEND2_VS2008(head,add,next) + +#define LL_APPEND2_VS2008(head,add,next) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#define LL_DELETE_VS2008(head,del) \ + LL_DELETE2_VS2008(head,del,next) + +#define LL_DELETE2_VS2008(head,del,next) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + head = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char**)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ +} while (0) +#ifdef NO_DECLTYPE +#undef LL_APPEND +#define LL_APPEND LL_APPEND_VS2008 +#undef LL_DELETE +#define LL_DELETE LL_DELETE_VS2008 +#undef LL_DELETE2 +#define LL_DELETE2 LL_DELETE2_VS2008 +#undef LL_APPEND2 +#define LL_APPEND2 LL_APPEND2_VS2008 +#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ +#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ +#endif +/* end VS2008 replacements */ + +#define LL_COUNT(head,el,counter) \ + LL_COUNT2(head,el,counter,next) \ + +#define LL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + LL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define LL_FOREACH(head,el) \ + LL_FOREACH2(head,el,next) + +#define LL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + LL_FOREACH_SAFE2(head,el,tmp,next) + +#define LL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ + LL_SEARCH_SCALAR2(head,out,field,val,next) + +#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define LL_SEARCH(head,out,elt,cmp) \ + LL_SEARCH2(head,out,elt,cmp,next) + +#define LL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + LL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define LL_REPLACE_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) + +#define LL_PREPEND_ELEM(head, el, add) \ +do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ +} while (0) \ + + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ + DL_PREPEND2(head,add,prev,next) + +#define DL_PREPEND2(head,add,prev,next) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ + DL_APPEND2(head,add,prev,next) + +#define DL_APPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0) + +#define DL_CONCAT(head1,head2) \ + DL_CONCAT2(head1,head2,prev,next) + +#define DL_CONCAT2(head1,head2,prev,next) \ +do { \ + LDECLTYPE(head1) _tmp; \ + if (head2) { \ + if (head1) { \ + _tmp = (head2)->prev; \ + (head2)->prev = (head1)->prev; \ + (head1)->prev->next = (head2); \ + (head1)->prev = _tmp; \ + } else { \ + (head1)=(head2); \ + } \ + } \ +} while (0) + +#define DL_DELETE(head,del) \ + DL_DELETE2(head,del,prev,next) + +#define DL_DELETE2(head,del,prev,next) \ +do { \ + assert((del)->prev != NULL); \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0) + +#define DL_COUNT(head,el,counter) \ + DL_COUNT2(head,el,counter,next) \ + +#define DL_COUNT2(head,el,counter,next) \ +{ \ + counter = 0; \ + DL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define DL_FOREACH(head,el) \ + DL_FOREACH2(head,el,next) + +#define DL_FOREACH2(head,el,next) \ + for(el=head;el;el=(el)->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + DL_FOREACH_SAFE2(head,el,tmp,next) + +#define DL_FOREACH_SAFE2(head,el,tmp,next) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH +#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 +#define DL_SEARCH2 LL_SEARCH2 + +#define DL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((head) == (el)) { \ + (head) = (add); \ + (add)->next = (el)->next; \ + if ((el)->next == NULL) { \ + (add)->prev = (add); \ + } else { \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + } \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->prev->next = (add); \ + if ((el)->next == NULL) { \ + (head)->prev = (add); \ + } else { \ + (add)->next->prev = (add); \ + } \ + } \ +} while (0) + +#define DL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + (add)->prev->next = (add); \ + } \ +} while (0) \ + + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_PREPEND(head,add) \ + CDL_PREPEND2(head,add,prev,next) + +#define CDL_PREPEND2(head,add,prev,next) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ +(head)=(add); \ +} while (0) + +#define CDL_DELETE(head,del) \ + CDL_DELETE2(head,del,prev,next) + +#define CDL_DELETE2(head,del,prev,next) \ +do { \ + if ( ((head)==(del)) && ((head)->next == (head))) { \ + (head) = NULL; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0) + +#define CDL_COUNT(head,el,counter) \ + CDL_COUNT2(head,el,counter,next) \ + +#define CDL_COUNT2(head, el, counter,next) \ +{ \ + counter = 0; \ + CDL_FOREACH2(head,el,next){ ++counter; } \ +} + +#define CDL_FOREACH(head,el) \ + CDL_FOREACH2(head,el,next) + +#define CDL_FOREACH2(head,el,next) \ + for(el=head;el;el=(((el)->next==head) ? 0L : (el)->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) + +#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ + for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ + (el) && ((tmp2)=(el)->next, 1); \ + ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ + CDL_SEARCH_SCALAR2(head,out,field,val,next) + +#define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define CDL_SEARCH(head,out,elt,cmp) \ + CDL_SEARCH2(head,out,elt,cmp,next) + +#define CDL_SEARCH2(head,out,elt,cmp,next) \ +do { \ + CDL_FOREACH2(head,out,next) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#define CDL_REPLACE_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + if ((el)->next == (el)) { \ + (add)->next = (add); \ + (add)->prev = (add); \ + (head) = (add); \ + } else { \ + (add)->next = (el)->next; \ + (add)->prev = (el)->prev; \ + (add)->next->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ + } \ +} while (0) + +#define CDL_PREPEND_ELEM(head, el, add) \ +do { \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + (add)->prev = (el)->prev; \ + (el)->prev = (add); \ + (add)->prev->next = (add); \ + if ((head) == (el)) { \ + (head) = (add); \ + } \ +} while (0) \ + +#endif /* UTLIST_H */ diff --git a/vendor/swoole/include/mqtt.h b/vendor/swoole/include/mqtt.h new file mode 100755 index 0000000..f6bfea2 --- /dev/null +++ b/vendor/swoole/include/mqtt.h @@ -0,0 +1,73 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SW_MQTT_H_ +#define SW_MQTT_H_ + +#include "swoole.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SW_MQTT_MIN_LENGTH 2 +#define SW_MQTT_MAX_PAYLOAD_SIZE 268435455 + +enum swMqtt_type +{ + CONNECT = 0x10, + CONNACK = 0x20, + PUBLISH = 0x30, + PUBACK = 0x40, + PUBREC = 0x50, + PUBREL = 0x60, + PUBCOMP = 0x70, + SUBSCRIBE = 0x80, + SUBACK = 0x90, + UNSUBSCRIBE = 0xA0, + UNSUBACK = 0xB0, + PINGREQ = 0xC0, + PINGRESP = 0xD0, + DISCONNECT = 0xE0, +}; + +typedef struct +{ + uint8_t type :4; + uint8_t dup :1; + uint8_t qos :2; + uint8_t retain :1; + + uint32_t length; + + char protocol_name[8]; + +} swMqtt_package; + + +#define SETRETAIN(HDR, R) (HDR | (R)) +#define SETQOS(HDR, Q) (HDR | ((Q) << 1)) +#define SETDUP(HDR, D) (HDR | ((D) << 3)) + +int swMqtt_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* SW_MQTT_H_ */ diff --git a/vendor/swoole/include/rbtree.h b/vendor/swoole/include/rbtree.h new file mode 100755 index 0000000..66932fe --- /dev/null +++ b/vendor/swoole/include/rbtree.h @@ -0,0 +1,65 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef _NGX_RBTREE_H_INCLUDED_ +#define _NGX_RBTREE_H_INCLUDED_ + +#include <stdint.h> + +typedef struct swRbtree_node_s swRbtree_node; + +struct swRbtree_node_s +{ + uint32_t key; + void *value; + swRbtree_node *left; + swRbtree_node *right; + swRbtree_node *parent; + char color; +}; + +typedef struct swRbtree_s swRbtree; + +struct swRbtree_s +{ + swRbtree_node *root; + swRbtree_node *sentinel; +}; + +swRbtree* swRbtree_new(); +void swRbtree_free(swRbtree*); +void swRbtree_insert(swRbtree *tree, uint32_t key, void *value); +void swRbtree_delete(swRbtree *tree, uint32_t key); +void *swRbtree_find(swRbtree *tree, uint32_t key); + +#define swRbtree_red(node) ((node)->color = 1) +#define swRbtree_black(node) ((node)->color = 0) +#define swRbtree_is_red(node) ((node)->color) +#define swRbtree_is_black(node) (!swRbtree_is_red(node)) +#define swRbtree_copy_color(n1, n2) (n1->color = n2->color) + +#define swRbtree_sentinel_init(node) swRbtree_black(node) + +static inline swRbtree_node *swRbtree_min(swRbtree_node *node, swRbtree_node *sentinel) +{ + while (node->left != sentinel) + { + node = node->left; + } + return node; +} + +#endif diff --git a/vendor/swoole/include/redis.h b/vendor/swoole/include/redis.h new file mode 100755 index 0000000..78f8592 --- /dev/null +++ b/vendor/swoole/include/redis.h @@ -0,0 +1,72 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_REDIS_H_ +#define SW_REDIS_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum swRedis_receive_state +{ + SW_REDIS_RECEIVE_TOTAL_LINE, + SW_REDIS_RECEIVE_LENGTH, + SW_REDIS_RECEIVE_STRING, +}; + +enum swRedis_reply_type +{ + SW_REDIS_REPLY_ERROR, + SW_REDIS_REPLY_NIL, + SW_REDIS_REPLY_STATUS, + SW_REDIS_REPLY_INT, + SW_REDIS_REPLY_STRING, + SW_REDIS_REPLY_SET, + SW_REDIS_REPLY_MAP, +}; + +#define SW_REDIS_RETURN_NIL "$-1\r\n" + +#define SW_REDIS_MAX_COMMAND_SIZE 64 +#define SW_REDIS_MAX_LINES 128 +#define SW_REDIS_MAX_STRING_SIZE 536870912 //512M + +static sw_inline char* swRedis_get_number(char *p, int *_ret) +{ + char *endptr; + p++; + int ret = strtol(p, &endptr, 10); + if (strncmp(SW_CRLF, endptr, SW_CRLF_LEN) == 0) + { + p += (endptr - p) + SW_CRLF_LEN; + *_ret = ret; + return p; + } + else + { + return NULL; + } +} + +int swRedis_recv(swProtocol *protocol, swConnection *conn, swString *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /* SW_REDIS_H_ */ diff --git a/vendor/swoole/include/sha1.h b/vendor/swoole/include/sha1.h new file mode 100755 index 0000000..ed57789 --- /dev/null +++ b/vendor/swoole/include/sha1.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + + +#ifndef _WEBSOCKET_SHA1_H__ +#define _WEBSOCKET_SHA1_H__ + +/* Define this if your machine is LITTLE_ENDIAN, otherwise #undef it: */ +#ifdef WORDS_BIGENDIAN +# undef LITTLE_ENDIAN +#else +# ifndef LITTLE_ENDIAN +# define LITTLE_ENDIAN +# endif +#endif + +/* Make sure you define these types for your architecture: */ +typedef unsigned int sha1_quadbyte; /* 4 byte type */ +typedef unsigned char sha1_byte; /* single byte type */ + +/* + * Be sure to get the above definitions right. For instance, on my + * x86 based FreeBSD box, I define LITTLE_ENDIAN and use the type + * "unsigned long" for the quadbyte. On FreeBSD on the Alpha, however, + * while I still use LITTLE_ENDIAN, I must define the quadbyte type + * as "unsigned int" instead. + */ + +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 + +/* The SHA1 structure: */ +typedef struct _SHA_CTX { + sha1_quadbyte state[5]; + sha1_quadbyte count[2]; + sha1_byte buffer[SHA1_BLOCK_LENGTH]; +} SHA_CTX; + +#ifndef NOPROTO +void swSha1_init(SHA_CTX *context); +void swSha1_update(SHA_CTX *context, sha1_byte *data, unsigned int len); +void swSha1_final(sha1_byte digest[SHA1_DIGEST_LENGTH], + SHA_CTX* context); +#else +void swSha1_init(); +void swSha1_update(); +void swSha1_final(); +#endif + +#endif + diff --git a/vendor/swoole/include/socks5.h b/vendor/swoole/include/socks5.h new file mode 100755 index 0000000..07cff56 --- /dev/null +++ b/vendor/swoole/include/socks5.h @@ -0,0 +1,70 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_SOCKS5_H_ +#define SW_SOCKS5_H_ + +#include "Client.h" + +#define SW_SOCKS5_VERSION_CODE 0x05 + +enum swSocks5_state +{ + SW_SOCKS5_STATE_WAIT = 0, + SW_SOCKS5_STATE_HANDSHAKE, + SW_SOCKS5_STATE_AUTH, + SW_SOCKS5_STATE_CONNECT, + SW_SOCKS5_STATE_READY, +}; + +enum swSocks5_method +{ + SW_SOCKS5_METHOD_AUTH = 0x02, +}; + +typedef struct _swSocks5 +{ + char *host; + int l_host; + int port; + + uint8_t state; + uint8_t version; + uint8_t method; + uint8_t dns_tunnel; + + char *password; + char *username; + char *target_host; + int target_port; + int l_target_host; + int l_username; + int l_password; + + char buf[600]; + +} swSocks5; + +static sw_inline void swSocks5_pack(char *buf, int method) +{ + buf[0] = SW_SOCKS5_VERSION_CODE; + buf[1] = 0x01; + buf[2] = method; +} + +int swSocks5_connect(swClient *cli, char *recv_data, int length); + +#endif /* SW_SOCKS5_H_ */ diff --git a/vendor/swoole/include/swoole.h b/vendor/swoole/include/swoole.h new file mode 100755 index 0000000..b934dc3 --- /dev/null +++ b/vendor/swoole/include/swoole.h @@ -0,0 +1,2203 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SWOOLE_H_ +#define SWOOLE_H_ + +#if defined(HAVE_CONFIG_H) && !defined(COMPILE_DL_SWOOLE) +#include "config.h" +#endif + +#ifdef SW_STATIC_COMPILATION +#include "php_config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> +#include <assert.h> +#include <time.h> +#include <pthread.h> +#if defined(HAVE_CPU_AFFINITY) +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/cpuset.h> +#include <pthread_np.h> +typedef cpuset_t cpu_set_t; +#else +#include <sched.h> +#endif +#endif + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/select.h> +#include <sys/mman.h> +#include <sys/ipc.h> +#include <sys/wait.h> +#include <sys/un.h> +#include <sys/types.h> +#include <sys/utsname.h> + +#ifdef __MACH__ +#include <mach/clock.h> +#include <mach/mach_time.h> +#include <sys/sysctl.h> + +#define ORWL_NANO (+1.0E-9) +#define ORWL_GIGA UINT64_C(1000000000) + +static double orwl_timebase = 0.0; +static uint64_t orwl_timestart = 0; +#ifndef HAVE_CLOCK_GETTIME +int clock_gettime(clock_id_t which_clock, struct timespec *t); +#endif +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +/*----------------------------------------------------------------------------*/ +#ifndef ulong +#define ulong unsigned long +#endif +typedef unsigned long ulong_t; + +#if defined(__GNUC__) +#if __GNUC__ >= 3 +#define sw_inline inline __attribute__((always_inline)) +#else +#define sw_inline inline +#endif +#elif defined(_MSC_VER) +#define sw_inline __forceinline +#else +#define sw_inline inline +#endif + +#if defined(__GNUC__) && __GNUC__ >= 4 +#define SW_API __attribute__ ((visibility("default"))) +#else +#define SW_API +#endif + +#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) +#define MAP_ANONYMOUS MAP_ANON +#endif + +#ifndef SOCK_NONBLOCK +#define SOCK_NONBLOCK O_NONBLOCK +#endif + +#ifndef CLOCK_REALTIME +#define CLOCK_REALTIME 0 +#endif + +#if !defined(__GNUC__) || __GNUC__ < 3 +#define __builtin_expect(x, expected_value) (x) +#endif +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#define SW_START_LINE "-------------------------START----------------------------" +#define SW_END_LINE "-------------------------END------------------------------" +#define SW_ECHO_GREEN "\e[32m%s\e[0m" +#define SW_ECHO_RED "\e[31m%s\e[0m" +#define SW_ECHO_YELLOW "\e[33m%s\e[0m" +#define SW_ECHO_CYAN_BLUE "\e[36m%s\e[0m" + +#define SW_SPACE ' ' +#define SW_CRLF "\r\n" +#define SW_CRLF_LEN 2 +#define SW_ASCII_CODE_0 64 +#define SW_ASCII_CODE_Z 106 +/*----------------------------------------------------------------------------*/ + +#include "swoole_config.h" +#include "atomic.h" +#include "hashmap.h" +#include "list.h" +#include "heap.h" +#include "RingQueue.h" +#include "array.h" +#include "error.h" + +#define SW_MAX_UINT 4294967295 +#define SW_MAX_INT 2147483647 + +#ifndef MAX +#define MAX(a, b) (a)>(b)?a:b; +#endif +#ifndef MIN +#define MIN(a, b) (a)<(b)?a:b; +#endif + +#define SW_STRL(s) s, sizeof(s) +#define SW_START_SLEEP usleep(100000) //sleep 1s,wait fork and pthread_create + +#ifdef SW_USE_JEMALLOC +#include <jemalloc/jemalloc.h> +#define sw_malloc je_malloc +#define sw_free je_free +#define sw_calloc je_calloc +#define sw_realloc je_realloc +#else +#define sw_malloc malloc +#define sw_free free +#define sw_calloc calloc +#define sw_realloc realloc +#endif + +static sw_inline char* swoole_strdup(const char *s) +{ + size_t l = strlen(s) + 1; + char *p = (char *)sw_malloc(l); + memcpy(p, s, l); + return p; +} + +static sw_inline char* swoole_strndup(const char *s, size_t n) +{ + char *p = (char *)sw_malloc(n + 1); + strncpy(p, s, n); + p[n] = '\0'; + return p; +} + +#if defined(SW_USE_JEMALLOC) || defined(SW_USE_TCMALLOC) +#define sw_strdup swoole_strdup +#define sw_strndup swoole_strndup +#else +#define sw_strdup strdup +#define sw_strndup strndup +#endif + +#define METHOD_DEF(class,name,...) class##_##name(class *object, ##__VA_ARGS__) +#define METHOD(class,name,...) class##_##name(object, ##__VA_ARGS__) +//------------------------------------------------------------------------------- +#define SW_OK 0 +#define SW_ERR -1 +#define SW_AGAIN -2 +#define SW_BUSY -3 +#define SW_DONE -4 +#define SW_DECLINED -5 +#define SW_ABORT -6 +//------------------------------------------------------------------------------- +enum swReturnType +{ + SW_CONTINUE = 1, + SW_WAIT = 2, + SW_CLOSE = 3, + SW_ERROR = 4, + SW_READY = 5, +}; +//------------------------------------------------------------------------------- +enum swFd_type +{ + SW_FD_TCP = 0, //tcp socket + SW_FD_LISTEN = 1, //server socket + SW_FD_CLOSE = 2, //socket closed + SW_FD_ERROR = 3, //socket error + SW_FD_UDP = 4, //udp socket + SW_FD_PIPE = 5, //pipe + SW_FD_STREAM = 6, //stream socket + SW_FD_WRITE = 7, //fd can write + SW_FD_TIMER = 8, //timer fd + SW_FD_AIO = 9, //linux native aio + SW_FD_SIGNAL = 11, //signalfd + SW_FD_DNS_RESOLVER = 12, //dns resolver + SW_FD_INOTIFY = 13, //server socket + SW_FD_USER = 15, //SW_FD_USER or SW_FD_USER+n: for custom event + SW_FD_STREAM_CLIENT = 16, //swClient stream + SW_FD_DGRAM_CLIENT = 17, //swClient dgram +}; + +enum swBool_type +{ + SW_TRUE = 1, + SW_FALSE = 0, +}; + +enum swEvent_type +{ + SW_EVENT_DEAULT = 256, + SW_EVENT_READ = 1u << 9, + SW_EVENT_WRITE = 1u << 10, + SW_EVENT_ERROR = 1u << 11, + SW_EVENT_ONCE = 1u << 12, +}; + +enum swPipe_type +{ + SW_PIPE_READ = 0, + SW_PIPE_WRITE = 1, +}; + +enum swGlobal_hook_type +{ + SW_GLOBAL_HOOK_BEFORE_SERVER_START, + SW_GLOBAL_HOOK_BEFORE_CLIENT_START, +}; + +//------------------------------------------------------------------------------- +enum swServer_mode +{ + SW_MODE_BASE = 1, + SW_MODE_THREAD = 2, + SW_MODE_PROCESS = 3, + SW_MODE_SINGLE = 4, +}; +//------------------------------------------------------------------------------- +enum swSocket_type +{ + SW_SOCK_TCP = 1, + SW_SOCK_UDP = 2, + SW_SOCK_TCP6 = 3, + SW_SOCK_UDP6 = 4, + SW_SOCK_UNIX_DGRAM = 5, //unix sock dgram + SW_SOCK_UNIX_STREAM = 6, //unix sock stream +}; + +#define SW_SOCK_SSL (1u << 9) +//------------------------------------------------------------------------------- +enum swLog_level +{ + SW_LOG_DEBUG = 0, + SW_LOG_TRACE, + SW_LOG_INFO, + SW_LOG_NOTICE, + SW_LOG_WARNING, + SW_LOG_ERROR, +}; +//------------------------------------------------------------------------------- +enum swFactory_dispatch_mode +{ + SW_DISPATCH_ROUND = 1, + SW_DISPATCH_FDMOD = 2, + SW_DISPATCH_QUEUE = 3, + SW_DISPATCH_IPMOD = 4, + SW_DISPATCH_UIDMOD = 5, + SW_DISPATCH_USERFUNC = 6, + SW_DISPATCH_STREAM = 7, +}; + +enum swWorker_status +{ + SW_WORKER_BUSY = 1, + SW_WORKER_IDLE = 2, + SW_WORKER_DEL = 3, +}; +//------------------------------------------------------------------------------- + +#define swWarn(str,...) SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ +snprintf(sw_error,SW_ERROR_MSG_SIZE,"%s: " str,__func__,##__VA_ARGS__);\ +swLog_put(SW_LOG_WARNING, sw_error);\ +SwooleGS->lock_2.unlock(&SwooleGS->lock_2) + +#define swNotice(str,...) if (SW_LOG_NOTICE >= SwooleG.log_level){\ + SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + snprintf(sw_error,SW_ERROR_MSG_SIZE,str,##__VA_ARGS__);\ + swLog_put(SW_LOG_NOTICE, sw_error);\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2);} + +#if defined(SW_DEBUG) || defined(SW_LOG_TRACE_OPEN) +#define swTrace(str,...) if (SW_LOG_TRACE >= SwooleG.log_level){\ + SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + snprintf(sw_error, SW_ERROR_MSG_SIZE, str, ##__VA_ARGS__);\ + swLog_put(SW_LOG_TRACE, sw_error);\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2);} +#else +#define swTrace(str,...) +#endif + +#define swError(str,...) SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ +snprintf(sw_error, SW_ERROR_MSG_SIZE, str, ##__VA_ARGS__);\ +swLog_put(SW_LOG_ERROR, sw_error);\ +SwooleGS->lock_2.unlock(&SwooleGS->lock_2);\ +exit(1) + +#define swSysError(str,...) SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + snprintf(sw_error,SW_ERROR_MSG_SIZE,"%s(:%d): " str " Error: %s[%d].",__func__,__LINE__,##__VA_ARGS__,strerror(errno),errno);\ + swLog_put(SW_LOG_ERROR, sw_error);\ + SwooleG.error=errno;\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2) + +#define swoole_error_log(level, __errno, str, ...) do{SwooleG.error=__errno;\ + if (level >= SwooleG.log_level){\ + snprintf(sw_error, SW_ERROR_MSG_SIZE, "%s (ERROR %d): " str,__func__,__errno,##__VA_ARGS__);\ + SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + swLog_put(level, sw_error);\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2);}}while(0) + +#ifdef SW_DEBUG_REMOTE_OPEN +#define swDebug(str,...) int __debug_log_n = snprintf(sw_error, SW_ERROR_MSG_SIZE, str, ##__VA_ARGS__);\ +write(SwooleG.debug_fd, sw_error, __debug_log_n); +#elif defined(SW_DEBUG) +#define swDebug(str,...) if (SW_LOG_DEBUG >= SwooleG.log_level){\ + SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + snprintf(sw_error, SW_ERROR_MSG_SIZE, "%s(:%d): " str, __func__, __LINE__, ##__VA_ARGS__);\ + swLog_put(SW_LOG_DEBUG, sw_error);\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2);} +#else +#define swDebug(str,...) +#endif + +enum swTraceType +{ + SW_TRACE_SERVER = 1u << 1, + SW_TRACE_CLIENT = 1u << 2, + SW_TRACE_BUFFER = 1u << 3, + SW_TRACE_CONN = 1u << 4, + SW_TRACE_EVENT = 1u << 5, + SW_TRACE_WORKER = 1u << 6, + SW_TRACE_MEMORY = 1u << 7, + SW_TRACE_REACTOR = 1u << 8, + SW_TRACE_PHP = 1u << 9, + SW_TRACE_HTTP2 = 1u << 10, + SW_TRACE_EOF_PROTOCOL = 1u << 11, + SW_TRACE_LENGTH_PROTOCOL = 1u << 12, + SW_TRACE_CLOSE = 1u << 13, + SW_TRACE_HTTP_CLIENT = 1u << 14, + SW_TRACE_COROUTINE = 1u << 15, + SW_TRACE_REDIS_CLIENT = 1u << 16, + SW_TRACE_MYSQL_CLIENT = 1u << 17, + SW_TRACE_AIO = 1u << 18, + SW_TRACE_SSL = 1u << 19, +}; + +#ifdef SW_LOG_TRACE_OPEN +#define swTraceLog(what,str,...) if (SW_LOG_TRACE >= SwooleG.log_level && (what & SwooleG.trace_flags)) {\ + SwooleGS->lock_2.lock(&SwooleGS->lock_2);\ + snprintf(sw_error,SW_ERROR_MSG_SIZE,"%s(:%d): " str, __func__, __LINE__, ##__VA_ARGS__);\ + swLog_put(SW_LOG_TRACE, sw_error);\ + SwooleGS->lock_2.unlock(&SwooleGS->lock_2);} +#else +#define swTraceLog(id,str,...) +#endif + +#define swYield() sched_yield() //or usleep(1) +//#define swYield() usleep(500000) +#define SW_MAX_FDTYPE 32 //32 kinds of event +#define SW_ERROR_MSG_SIZE 512 + +//------------------------------Base-------------------------------- +#ifndef uchar +typedef unsigned char uchar; +#endif + +#ifdef SW_USE_OPENSSL +#include <openssl/ssl.h> +#endif + +typedef void (*swDestructor)(void *data); +typedef void (*swCallback)(void *data); + +typedef struct +{ + uint32_t id; + uint32_t fd :24; + uint32_t reactor_id :8; +} swSession; + +typedef struct _swString +{ + size_t length; + size_t size; + off_t offset; + char *str; +} swString; + +typedef void* swObject; + +typedef struct _swLinkedList_node +{ + struct _swLinkedList_node *prev; + struct _swLinkedList_node *next; + ulong_t priority; + void *data; +} swLinkedList_node; + +typedef struct +{ + uint32_t num; + uint8_t type; + swLinkedList_node *head; + swLinkedList_node *tail; + swDestructor dtor; +} swLinkedList; + +typedef struct +{ + union + { + struct sockaddr_in inet_v4; + struct sockaddr_in6 inet_v6; + struct sockaddr_un un; + } addr; + socklen_t len; +} swSocketAddress; + +typedef struct _swConnection +{ + /** + * file descript + */ + int fd; + + /** + * session id + */ + uint32_t session_id; + + /** + * socket type, SW_SOCK_TCP or SW_SOCK_UDP + */ + uint16_t socket_type; + + /** + * fd type, SW_FD_TCP or SW_FD_PIPE or SW_FD_TIMERFD + */ + uint16_t fdtype; + + int events; + + //-------------------------------------------------------------- + /** + * is active + * system fd must be 0. en: timerfd, signalfd, listen socket + */ + uint8_t active; + uint8_t connect_notify; + uint8_t direct_send; + uint8_t ssl_send; + //-------------------------------------------------------------- + uint8_t listen_wait; + uint8_t recv_wait; + uint8_t send_wait; + uint8_t close_wait; + uint8_t overflow; + uint8_t high_watermark; + uint8_t removed; + uint8_t tcp_nopush; + uint8_t dontwait; + //-------------------------------------------------------------- + uint8_t tcp_nodelay; + uint8_t ssl_want_read; + uint8_t ssl_want_write; + uint8_t http_upgrade; + uint8_t http2_stream; + uint8_t skip_recv; + //-------------------------------------------------------------- + /** + * server is actively close the connection + */ + uint8_t close_actively; + uint8_t closed; + uint8_t closing; + uint8_t close_reset; + /** + * protected connection, cannot be closed by heartbeat thread. + */ + uint8_t protect; + uint8_t nonblock; + //-------------------------------------------------------------- + uint8_t close_notify; + uint8_t close_force; + //-------------------------------------------------------------- + /** + * ReactorThread id + */ + uint16_t from_id; + + /** + * close error code + */ + uint16_t close_errno; + + /** + * from which socket fd + */ + sw_atomic_t from_fd; + + /** + * socket address + */ + swSocketAddress info; + + /** + * link any thing, for kernel, do not use with application. + */ + void *object; + + /** + * input buffer + */ + struct _swBuffer *in_buffer; + + /** + * output buffer + */ + struct _swBuffer *out_buffer; + + /** + * for receive data buffer + */ + swString *recv_buffer; + + /** + * connect time(seconds) + */ + time_t connect_time; + + /** + * received time with last data + */ + time_t last_time; + +#ifdef SW_BUFFER_RECV_TIME + /** + * received time(microseconds) with last data + */ + double last_time_usec; +#endif + +#ifdef SW_USE_TIMEWHEEL + uint16_t timewheel_index; +#endif + + /** + * bind uid + */ + uint32_t uid; + + /** + * memory buffer size; + */ + int buffer_size; + + /** + * upgarde websocket + */ + uint8_t websocket_status; + + /** + * unfinished data frame + */ + swString *websocket_buffer; + +#ifdef SW_USE_OPENSSL + SSL *ssl; + uint32_t ssl_state; + swString ssl_client_cert; +#endif + sw_atomic_t lock; + +#ifdef SW_DEBUG + size_t total_recv_bytes; + size_t total_send_bytes; +#endif + +} swConnection; + +typedef struct _swProtocol +{ + /* one package: eof check */ + uint8_t split_by_eof; + uint8_t package_eof_len; //数据缓存结束符长度 + char package_eof[SW_DATA_EOF_MAXLEN + 1]; //数据缓存结束符 + + char package_length_type; //length field type + uint8_t package_length_size; + uint16_t package_length_offset; //第几个字节开始表示长度 + uint16_t package_body_offset; //第几个字节开始计算长度 + uint32_t package_max_length; + + void *private_data; + + int (*onPackage)(swConnection *conn, char *data, uint32_t length); + int (*get_package_length)(struct _swProtocol *protocol, swConnection *conn, char *data, uint32_t length); +} swProtocol; +typedef int (*swProtocol_length_function)(struct _swProtocol *, swConnection *, char *, uint32_t); +//------------------------------String-------------------------------- +#define swoole_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c) +#define swoole_toupper(c) (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c) + +uint32_t swoole_utf8_decode(u_char **p, size_t n); +size_t swoole_utf8_length(u_char *p, size_t n); +void swoole_random_string(char *buf, size_t size); +char* swoole_get_mimetype(char *file); + +static sw_inline char *swoole_strlchr(char *p, char *last, char c) +{ + while (p < last) + { + if (*p == c) + { + return p; + } + p++; + } + return NULL; +} + +static sw_inline size_t swoole_size_align(size_t size, int pagesize) +{ + return size + (pagesize - (size % pagesize)); +} + +static sw_inline void swString_clear(swString *str) +{ + str->length = 0; + str->offset = 0; +} + +static sw_inline void swString_free(swString *str) +{ + sw_free(str->str); + sw_free(str); +} + +static sw_inline size_t swString_length(swString *str) +{ + return str->length; +} + +static sw_inline size_t swString_size(swString *str) +{ + return str->size; +} + +swString *swString_new(size_t size); +swString *swString_dup(const char *src_str, int length); +swString *swString_dup2(swString *src); + +void swString_print(swString *str); +void swString_free(swString *str); +int swString_append(swString *str, swString *append_str); +int swString_append_ptr(swString *str, char *append_str, int length); +int swString_write(swString *str, off_t offset, swString *write_str); +int swString_write_ptr(swString *str, off_t offset, char *write_str, int length); +int swString_extend(swString *str, size_t new_size); +char* swString_alloc(swString *str, size_t __size); + +#define SWSTRING_CURRENT_VL(buffer) buffer->str + buffer->offset, buffer->length - buffer->offset + +static sw_inline int swString_extend_align(swString *str, size_t _new_size) +{ + size_t align_size = str->size * 2; + while (align_size < _new_size) + { + align_size *= 2; + } + return swString_extend(str, align_size); +} + +#define swString_length(s) (s->length) +#define swString_ptr(s) (s->str) +//------------------------------Base-------------------------------- +typedef struct _swDataHead +{ + int fd; + uint16_t len; + int16_t from_id; + uint8_t type; + uint8_t flags; + uint16_t from_fd; +#ifdef SW_BUFFER_RECV_TIME + double time; +#endif +} swDataHead; + +typedef struct _swEvent +{ + int fd; + int16_t from_id; + uint8_t type; + swConnection *socket; +} swEvent; + +typedef struct _swEventData +{ + swDataHead info; + char data[SW_BUFFER_SIZE]; +} swEventData; + +typedef struct _swDgramPacket +{ + union + { + struct in6_addr v6; + struct in_addr v4; + struct + { + uint16_t path_length; + } un; + } addr; + uint16_t port; + uint32_t length; + char data[0]; +} swDgramPacket; + +typedef struct _swSendData +{ + swDataHead info; + /** + * for big package + */ + uint32_t length; + char *data; +} swSendData; + +typedef struct +{ + off_t offset; + size_t length; + char filename[0]; +} swSendFile_request; + +//------------------TimeWheel-------------------- +typedef struct +{ + uint16_t current; + uint16_t size; + swHashMap **wheel; + +} swTimeWheel; + +typedef void * (*swThreadStartFunc)(void *); +typedef int (*swHandle)(swEventData *buf); +typedef void (*swSignalHander)(int); +typedef struct _swReactor swReactor; + +typedef int (*swReactor_handle)(swReactor *reactor, swEvent *event); +//------------------Pipe-------------------- +typedef struct _swPipe +{ + void *object; + int blocking; + double timeout; + + int (*read)(struct _swPipe *, void *recv, int length); + int (*write)(struct _swPipe *, void *send, int length); + int (*getFd)(struct _swPipe *, int master); + int (*close)(struct _swPipe *); +} swPipe; + +enum _swPipe_close_which +{ + SW_PIPE_CLOSE_MASTER = 1, + SW_PIPE_CLOSE_WORKER = 2, + SW_PIPE_CLOSE_READ = 3, + SW_PIPE_CLOSE_WRITE = 4, + SW_PIPE_CLOSE_BOTH = 0, +}; + +int swPipeBase_create(swPipe *p, int blocking); +int swPipeEventfd_create(swPipe *p, int blocking, int semaphore, int timeout); +int swPipeUnsock_create(swPipe *p, int blocking, int protocol); +int swPipeUnsock_close_ext(swPipe *p, int which); + +static inline int swPipeNotify_auto(swPipe *p, int blocking, int semaphore) +{ +#ifdef HAVE_EVENTFD + return swPipeEventfd_create(p, blocking, semaphore, 0); +#else + return swPipeBase_create(p, blocking); +#endif +} + +void swBreakPoint(void); + +//------------------Queue-------------------- +typedef struct _swQueue_Data +{ + long mtype; /* type of received/sent message */ + char mdata[sizeof(swEventData)]; /* text of the message */ +} swQueue_data; + +typedef struct _swMsgQueue +{ + int blocking; + int msg_id; + int flags; + int perms; +} swMsgQueue; + +int swMsgQueue_create(swMsgQueue *q, int blocking, key_t msg_key, int perms); +void swMsgQueue_set_blocking(swMsgQueue *q, uint8_t blocking); +int swMsgQueue_push(swMsgQueue *q, swQueue_data *in, int data_length); +int swMsgQueue_pop(swMsgQueue *q, swQueue_data *out, int buffer_length); +int swMsgQueue_stat(swMsgQueue *q, int *queue_num, int *queue_bytes); +int swMsgQueue_free(swMsgQueue *q); + +//------------------Lock-------------------------------------- +enum SW_LOCKS +{ + SW_RWLOCK = 1, +#define SW_RWLOCK SW_RWLOCK + SW_FILELOCK = 2, +#define SW_FILELOCK SW_FILELOCK + SW_MUTEX = 3, +#define SW_MUTEX SW_MUTEX + SW_SEM = 4, +#define SW_SEM SW_SEM + SW_SPINLOCK = 5, +#define SW_SPINLOCK SW_SPINLOCK + SW_ATOMLOCK = 6, +#define SW_ATOMLOCK SW_ATOMLOCK +}; + +enum swDNSLookup_cache_type +{ + SW_DNS_LOOKUP_RANDOM = (1u << 11), +}; + +typedef struct +{ + char *hostname; + char *service; + int family; + int socktype; + int protocol; + int error; + void *result; + int count; +} swRequest_getaddrinfo; + +//文件锁 +typedef struct _swFileLock +{ + struct flock lock_t; + int fd; +} swFileLock; + +//互斥锁 +typedef struct _swMutex +{ + pthread_mutex_t _lock; + pthread_mutexattr_t attr; +} swMutex; + +#ifdef HAVE_RWLOCK +typedef struct _swRWLock +{ + pthread_rwlock_t _lock; + pthread_rwlockattr_t attr; + +} swRWLock; +#endif + +#ifdef HAVE_SPINLOCK +typedef struct _swSpinLock +{ + pthread_spinlock_t lock_t; +} swSpinLock; +#endif + +typedef struct _swAtomicLock +{ + sw_atomic_t lock_t; + uint32_t spin; +} swAtomicLock; + +typedef struct _swSem +{ + key_t key; + int semid; +} swSem; + +typedef struct _swLock +{ + int type; + union + { + swMutex mutex; +#ifdef HAVE_RWLOCK + swRWLock rwlock; +#endif +#ifdef HAVE_SPINLOCK + swSpinLock spinlock; +#endif + swFileLock filelock; + swSem sem; + swAtomicLock atomlock; + } object; + + int (*lock_rd)(struct _swLock *); + int (*lock)(struct _swLock *); + int (*unlock)(struct _swLock *); + int (*trylock_rd)(struct _swLock *); + int (*trylock)(struct _swLock *); + int (*free)(struct _swLock *); +} swLock; + +//Thread Condition +typedef struct _swCond +{ + swLock _lock; + pthread_cond_t _cond; + + int (*wait)(struct _swCond *object); + int (*timewait)(struct _swCond *object, long, long); + int (*notify)(struct _swCond *object); + int (*broadcast)(struct _swCond *object); + void (*free)(struct _swCond *object); + int (*lock)(struct _swCond *object); + int (*unlock)(struct _swCond *object); +} swCond; + +#define SW_SHM_MMAP_FILE_LEN 64 + +typedef struct _swShareMemory_mmap +{ + size_t size; + char mapfile[SW_SHM_MMAP_FILE_LEN]; + int tmpfd; + int key; + int shmid; + void *mem; +} swShareMemory; + +void *swShareMemory_mmap_create(swShareMemory *object, size_t size, char *mapfile); +void *swShareMemory_sysv_create(swShareMemory *object, size_t size, int key); +int swShareMemory_sysv_free(swShareMemory *object, int rm); +int swShareMemory_mmap_free(swShareMemory *object); + +//-------------------memory manager------------------------- +typedef struct _swMemoryPool +{ + void *object; + void* (*alloc)(struct _swMemoryPool *pool, uint32_t size); + void (*free)(struct _swMemoryPool *pool, void *ptr); + void (*destroy)(struct _swMemoryPool *pool); +} swMemoryPool; + +typedef struct _swFixedPool_slice +{ + uint8_t lock; + struct _swFixedPool_slice *next; + struct _swFixedPool_slice *pre; + char data[0]; + +} swFixedPool_slice; + +typedef struct _swFixedPool +{ + void *memory; + size_t size; + + swFixedPool_slice *head; + swFixedPool_slice *tail; + + /** + * total memory size + */ + uint32_t slice_num; + + /** + * memory usage + */ + uint32_t slice_use; + + /** + * Fixed slice size, not include the memory used by swFixedPool_slice + */ + uint32_t slice_size; + + /** + * use shared memory + */ + uint8_t shared; + +} swFixedPool; +/** + * FixedPool, random alloc/free fixed size memory + */ +swMemoryPool* swFixedPool_new(uint32_t slice_num, uint32_t slice_size, uint8_t shared); +swMemoryPool* swFixedPool_new2(uint32_t slice_size, void *memory, size_t size); +swMemoryPool* swMalloc_new(); + +/** + * RingBuffer, In order for malloc / free + */ +swMemoryPool *swRingBuffer_new(uint32_t size, uint8_t shared); + +/** + * Global memory, the program life cycle only malloc / free one time + */ +swMemoryPool* swMemoryGlobal_new(uint32_t pagesize, uint8_t shared); + +void swFixedPool_debug(swMemoryPool *pool); + +/** + * alloc shared memory + */ +void* sw_shm_malloc(size_t size); +void sw_shm_free(void *ptr); +void* sw_shm_calloc(size_t num, size_t _size); +int sw_shm_protect(void *addr, int flags); +void* sw_shm_realloc(void *ptr, size_t new_size); +#ifdef HAVE_RWLOCK +int swRWLock_create(swLock *lock, int use_in_process); +#endif +int swSem_create(swLock *lock, key_t key); +int swMutex_create(swLock *lock, int use_in_process); +int swMutex_lockwait(swLock *lock, int timeout_msec); +int swFileLock_create(swLock *lock, int fd); +#ifdef HAVE_SPINLOCK +int swSpinLock_create(swLock *object, int spin); +#endif +int swAtomicLock_create(swLock *object, int spin); +int swCond_create(swCond *cond); + +typedef struct _swThreadParam +{ + void *object; + int pti; +} swThreadParam; + +extern int16_t sw_errno; +extern char sw_error[SW_ERROR_MSG_SIZE]; + +enum swProcessType +{ + SW_PROCESS_MASTER = 1, + SW_PROCESS_WORKER = 2, + SW_PROCESS_MANAGER = 3, + SW_PROCESS_TASKWORKER = 4, + SW_PROCESS_USERWORKER = 5, +}; + +#define swIsMaster() (SwooleG.process_type==SW_PROCESS_MASTER) +#define swIsWorker() (SwooleG.process_type==SW_PROCESS_WORKER) +#define swIsTaskWorker() (SwooleG.process_type==SW_PROCESS_TASKWORKER) +#define swIsManager() (SwooleG.process_type==SW_PROCESS_MANAGER) +#define swIsUserWorker() (SwooleG.process_type==SW_PROCESS_USERWORKER) + +//----------------------tool function--------------------- +int swLog_init(char *logfile); +void swLog_put(int level, char *cnt); +void swLog_free(void); +#define sw_log(str,...) {snprintf(sw_error,SW_ERROR_MSG_SIZE,str,##__VA_ARGS__);swLog_put(SW_LOG_INFO, sw_error);} + +uint64_t swoole_hash_key(char *str, int str_len); +uint32_t swoole_common_multiple(uint32_t u, uint32_t v); +uint32_t swoole_common_divisor(uint32_t u, uint32_t v); + +static sw_inline uint16_t swoole_swap_endian16(uint16_t x) +{ + return (((x & 0xff) << 8) | ((x & 0xff00) >> 8)); +} + +static sw_inline uint32_t swoole_swap_endian32(uint32_t x) +{ + return (((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24)); +} + +static sw_inline int32_t swoole_unpack(char type, void *data) +{ + switch(type) + { + /*-------------------------16bit-----------------------------*/ + case 'c': + return *((int8_t *) data); + case 'C': + return *((uint8_t *) data); + /*-------------------------16bit-----------------------------*/ + /** + * signed short (always 16 bit, machine byte order) + */ + case 's': + return *((int16_t *) data); + /** + * unsigned short (always 16 bit, machine byte order) + */ + case 'S': + return *((uint16_t *) data); + /** + * unsigned short (always 16 bit, big endian byte order) + */ + case 'n': + return ntohs(*((uint16_t *) data)); + /** + * unsigned short (always 32 bit, little endian byte order) + */ + case 'v': + return swoole_swap_endian16(ntohs(*((uint16_t *) data))); + + /*-------------------------32bit-----------------------------*/ + /** + * unsigned long (always 32 bit, machine byte order) + */ + case 'L': + return *((uint32_t *) data); + /** + * signed long (always 32 bit, machine byte order) + */ + case 'l': + return *((int *) data); + /** + * unsigned long (always 32 bit, big endian byte order) + */ + case 'N': + return ntohl(*((uint32_t *) data)); + /** + * unsigned short (always 32 bit, little endian byte order) + */ + case 'V': + return swoole_swap_endian32(ntohl(*((uint32_t *) data))); + + default: + return *((uint32_t *) data); + } +} + +static inline char* swoole_strnstr(char *haystack, char *needle, uint32_t length) +{ + int i; + uint32_t needle_length = strlen(needle); + assert(needle_length > 0); + + for (i = 0; i < (int) (length - needle_length + 1); i++) + { + if ((haystack[0] == needle[0]) && (0 == memcmp(haystack, needle, needle_length))) + { + return (char *) haystack; + } + haystack++; + } + + return NULL; +} + +static inline int swoole_strnpos(char *haystack, uint32_t haystack_length, char *needle, uint32_t needle_length) +{ + assert(needle_length > 0); + uint32_t i; + + for (i = 0; i < (int) (haystack_length - needle_length + 1); i++) + { + if ((haystack[0] == needle[0]) && (0 == memcmp(haystack, needle, needle_length))) + { + return i; + } + haystack++; + } + + return -1; +} + +static inline int swoole_strrnpos(char *haystack, char *needle, uint32_t length) +{ + uint32_t needle_length = strlen(needle); + assert(needle_length > 0); + uint32_t i; + haystack += (length - needle_length); + + for (i = length - needle_length; i > 0; i--) + { + if ((haystack[0] == needle[0]) && (0 == memcmp(haystack, needle, needle_length))) + { + return i; + } + haystack--; + } + + return -1; +} + +static inline void swoole_strtolower(char *str, int length) +{ + char *c, *e; + + c = str; + e = c + length; + + while (c < e) + { + *c = tolower(*c); + c++; + } +} + +int swoole_itoa(char *buf, long value); +void swoole_dump_bin(char *data, char type, int size); +void swoole_dump_hex(char *data, int outlen); +int swoole_type_size(char type); +int swoole_mkdir_recursive(const char *dir); +char* swoole_dirname(char *file); +void swoole_dump_ascii(char *data, int size); +int swoole_sync_writefile(int fd, void *data, int len); +int swoole_sync_readfile(int fd, void *buf, int len); +int swoole_rand(int min, int max); +int swoole_system_random(int min, int max); +long swoole_file_get_size(FILE *fp); +int swoole_tmpfile(char *filename); +swString* swoole_file_get_contents(char *filename); +int swoole_file_put_contents(char *filename, char *content, size_t length); +long swoole_file_size(char *filename); +void swoole_open_remote_debug(void); +char *swoole_dec2hex(int value, int base); +int swoole_version_compare(char *version1, char *version2); +#ifdef HAVE_EXECINFO +void swoole_print_trace(void); +#endif +void swoole_ioctl_set_block(int sock, int nonblock); +void swoole_fcntl_set_option(int sock, int nonblock, int cloexec); +int swoole_gethostbyname(int type, char *name, char *addr); +int swoole_getaddrinfo(swRequest_getaddrinfo *req); +char* swoole_string_format(size_t n, const char *format, ...); +//----------------------core function--------------------- +int swSocket_set_timeout(int sock, double timeout); +int swSocket_create_server(int type, char *address, int port, int backlog); +//----------------------------------------Socket--------------------------------------- +static sw_inline int swSocket_is_dgram(uint8_t type) +{ + return (type == SW_SOCK_UDP || type == SW_SOCK_UDP6 || type == SW_SOCK_UNIX_DGRAM); +} + +static sw_inline int swSocket_is_stream(uint8_t type) +{ + return (type == SW_SOCK_TCP || type == SW_SOCK_TCP6 || type == SW_SOCK_UNIX_STREAM); +} + +#ifdef SW_USE_IOCTL +#define swSetNonBlock(sock) swoole_ioctl_set_block(sock, 1) +#define swSetBlock(sock) swoole_ioctl_set_block(sock, 0) +#else +#define swSetNonBlock(sock) swoole_fcntl_set_option(sock, 1, -1) +#define swSetBlock(sock) swoole_fcntl_set_option(sock, 0, -1) +#endif + +void swoole_init(void); +void swoole_clean(void); +double swoole_microtime(void); +void swoole_rtrim(char *str, int len); +void swoole_redirect_stdout(int new_fd); +int swoole_shell_exec(char *command, pid_t *pid); +SW_API int swoole_add_function(const char *name, void* func); +SW_API void* swoole_get_function(char *name, uint32_t length); +SW_API int swoole_add_hook(enum swGlobal_hook_type type, swCallback func, int push_back); +SW_API void swoole_call_hook(enum swGlobal_hook_type type, void *arg); + +static sw_inline uint64_t swoole_hton64(uint64_t host) +{ + uint64_t ret = 0; + uint32_t high, low; + + low = host & 0xFFFFFFFF; + high = (host >> 32) & 0xFFFFFFFF; + low = htonl(low); + high = htonl(high); + + ret = low; + ret <<= 32; + ret |= high; + return ret; +} + +static sw_inline uint64_t swoole_ntoh64(uint64_t net) +{ + uint64_t ret = 0; + uint32_t high, low; + + low = net & 0xFFFFFFFF; + high = (net >> 32) & 0xFFFFFFFF; + low = ntohl(low); + high = ntohl(high); + ret = low; + ret <<= 32; + ret |= high; + return ret; +} + +int swSocket_create(int type); +int swSocket_bind(int sock, int type, char *host, int *port); +int swSocket_wait(int fd, int timeout_ms, int events); +int swSocket_wait_multi(int *list_of_fd, int n_fd, int timeout_ms, int events); +void swSocket_clean(int fd); +int swSocket_sendto_blocking(int fd, void *__buf, size_t __n, int flag, struct sockaddr *__addr, socklen_t __addr_len); +int swSocket_set_buffer_size(int fd, int buffer_size); +int swSocket_udp_sendto(int server_sock, char *dst_ip, int dst_port, char *data, uint32_t len); +int swSocket_udp_sendto6(int server_sock, char *dst_ip, int dst_port, char *data, uint32_t len); +int swSocket_unix_sendto(int server_sock, char *dst_path, char *data, uint32_t len); +int swSocket_sendfile_sync(int sock, char *filename, off_t offset, size_t length, double timeout); +int swSocket_write_blocking(int __fd, void *__data, int __len); +int swSocket_recv_blocking(int fd, void *__data, size_t __len, int flags); + +static sw_inline int swWaitpid(pid_t __pid, int *__stat_loc, int __options) +{ + int ret; + do + { + ret = waitpid(__pid, __stat_loc, __options); + if (ret < 0 && errno == EINTR) + { + continue; + } + break; + } while(1); + return ret; +} + +static sw_inline int swKill(pid_t __pid, int __sig) +{ + int ret; + do + { + ret = kill(__pid, __sig); + if (ret < 0 && errno == EINTR) + { + continue; + } + break; + } while (1); + return ret; +} + +#ifdef TCP_CORK +#define HAVE_TCP_NOPUSH +static sw_inline int swSocket_tcp_nopush(int sock, int nopush) +{ + return setsockopt(sock, IPPROTO_TCP, TCP_CORK, (const void *) &nopush, sizeof(int)); +} +#else +#define swSocket_tcp_nopush(sock, nopush) +#endif + +swSignalHander swSignal_set(int sig, swSignalHander func, int restart, int mask); +void swSignal_add(int signo, swSignalHander func); +void swSignal_callback(int signo); +void swSignal_clear(void); +void swSignal_none(void); + +#ifdef HAVE_SIGNALFD +void swSignalfd_init(); +int swSignalfd_setup(swReactor *reactor); +#endif + +typedef struct _swDefer_callback +{ + struct _swDefer_callback *next, *prev; + swCallback callback; + void *data; +} swDefer_callback; + +struct _swReactor +{ + void *object; + void *ptr; //reserve + + /** + * last signal number + */ + int singal_no; + + uint32_t event_num; + uint32_t max_event_num; + + uint32_t check_timer :1; + uint32_t running :1; + uint32_t start :1; + uint32_t once :1; + + /** + * disable accept new connection + */ + uint32_t disable_accept :1; + + uint32_t check_signalfd :1; + + /** + * multi-thread reactor, cannot realloc sockets. + */ + uint32_t thread :1; + + /** + * reactor->wait timeout (millisecond) or -1 + */ + int32_t timeout_msec; + + uint16_t id; //Reactor ID + uint16_t flag; //flag + + uint32_t max_socket; + +#ifdef SW_USE_MALLOC_TRIM + time_t last_malloc_trim_time; +#endif + +#ifdef SW_USE_TIMEWHEEL + swTimeWheel *timewheel; + uint16_t heartbeat_interval; + time_t last_heartbeat_time; +#endif + + /** + * for thread + */ + swConnection *socket_list; + + /** + * for process + */ + swArray *socket_array; + + swReactor_handle handle[SW_MAX_FDTYPE]; //默认事件 + swReactor_handle write_handle[SW_MAX_FDTYPE]; //扩展事件1(一般为写事件) + swReactor_handle error_handle[SW_MAX_FDTYPE]; //扩展事件2(一般为错误事件,如socket关闭) + + int (*add)(swReactor *, int fd, int fdtype); + int (*set)(swReactor *, int fd, int fdtype); + int (*del)(swReactor *, int fd); + int (*wait)(swReactor *, struct timeval *); + void (*free)(swReactor *); + + int (*setHandle)(swReactor *, int fdtype, swReactor_handle); + swDefer_callback *defer_callback_list; + swDefer_callback idle_task; + swDefer_callback future_task; + + void (*onTimeout)(swReactor *); + void (*onFinish)(swReactor *); + void (*onBegin)(swReactor *); + + void (*enable_accept)(swReactor *); + int (*can_exit)(swReactor *); + + int (*write)(swReactor *, int, void *, int); + int (*close)(swReactor *, int); + int (*defer)(swReactor *, swCallback, void *); +}; + +typedef struct _swWorker swWorker; +typedef struct _swThread swThread; +typedef struct _swProcessPool swProcessPool; + +struct _swWorker +{ + /** + * worker process + */ + pid_t pid; + + /** + * worker thread + */ + pthread_t tid; + + swProcessPool *pool; + + swMemoryPool *pool_output; + + swMsgQueue *queue; + + /** + * redirect stdout to pipe_master + */ + uint8_t redirect_stdout; + + /** + * redirect stdin to pipe_worker + */ + uint8_t redirect_stdin; + + /** + * redirect stderr to pipe_worker + */ + uint8_t redirect_stderr; + + /** + * worker status, IDLE or BUSY + */ + uint8_t status; + uint8_t type; + uint8_t ipc_mode; + uint8_t child_process; + + uint8_t traced; + void (*tracer)(struct _swWorker *); + + /** + * tasking num + */ + sw_atomic_t tasking_num; + + time_t start_time; + time_t request_time; + + long request_count; + + /** + * worker id + */ + uint32_t id; + + swLock lock; + + void *send_shm; + + swPipe *pipe_object; + + int pipe_master; + int pipe_worker; + + int pipe; + void *ptr; + void *ptr2; +}; + +typedef struct +{ + int socket; + int last_connection; + char *socket_file; + swString *response_buffer; +} swStreamInfo; + +struct _swProcessPool +{ + /** + * reloading + */ + uint8_t reloading; + uint8_t reload_init; + uint8_t dispatch_mode; + uint8_t ipc_mode; + uint8_t started; + + /** + * process type + */ + uint8_t type; + + /** + * worker->id = start_id + i + */ + uint16_t start_id; + + /** + * use message queue IPC + */ + uint8_t use_msgqueue; + + /** + * use stream socket IPC + */ + uint8_t use_socket; + + char *packet_buffer; + uint32_t max_packet_size; + + /** + * message queue key + */ + key_t msgqueue_key; + + + int worker_num; + int max_request; + + int (*onTask)(struct _swProcessPool *pool, swEventData *task); + + void (*onWorkerStart)(struct _swProcessPool *pool, int worker_id); + void (*onMessage)(struct _swProcessPool *pool, char *data, uint32_t length); + void (*onWorkerStop)(struct _swProcessPool *pool, int worker_id); + + int (*main_loop)(struct _swProcessPool *pool, swWorker *worker); + int (*onWorkerNotFound)(struct _swProcessPool *pool, pid_t pid, int status); + + sw_atomic_t round_id; + sw_atomic_t run_worker_num; + + swWorker *workers; + swPipe *pipes; + swHashMap *map; + swReactor *reactor; + swMsgQueue *queue; + swStreamInfo *stream; + + void *ptr; + void *ptr2; +}; + +//----------------------------------------Reactor--------------------------------------- +static sw_inline int swReactor_error(swReactor *reactor) +{ + switch (errno) + { + case EINTR: + if (reactor->singal_no) + { + swSignal_callback(reactor->singal_no); + reactor->singal_no = 0; + } + return SW_OK; + } + return SW_ERR; +} + +static sw_inline int swReactor_event_read(int fdtype) +{ + return (fdtype < SW_EVENT_DEAULT) || (fdtype & SW_EVENT_READ); +} + +static sw_inline int swReactor_event_write(int fdtype) +{ + return fdtype & SW_EVENT_WRITE; +} + +static sw_inline int swReactor_event_error(int fdtype) +{ + return fdtype & SW_EVENT_ERROR; +} + +static sw_inline int swReactor_fdtype(int fdtype) +{ + return fdtype & (~SW_EVENT_READ) & (~SW_EVENT_WRITE) & (~SW_EVENT_ERROR); +} + +static sw_inline int swReactor_events(int fdtype) +{ + int events = 0; + if (swReactor_event_read(fdtype)) + { + events |= SW_EVENT_READ; + } + if (swReactor_event_write(fdtype)) + { + events |= SW_EVENT_WRITE; + } + if (swReactor_event_error(fdtype)) + { + events |= SW_EVENT_ERROR; + } + return events; +} + +int swReactor_create(swReactor *reactor, int max_event); +int swReactor_setHandle(swReactor *, int, swReactor_handle); +int swReactor_empty(swReactor *reactor); + +static sw_inline swConnection* swReactor_get(swReactor *reactor, int fd) +{ + if (reactor->thread) + { + return &reactor->socket_list[fd]; + } + swConnection *socket = (swConnection*) swArray_alloc(reactor->socket_array, fd); + if (socket == NULL) + { + return NULL; + } + if (!socket->active) + { + socket->fd = fd; + } + return socket; +} + +static sw_inline int swReactor_handle_isset(swReactor *reactor, int _fdtype) +{ + return reactor->handle[_fdtype] != NULL; +} + +static sw_inline void swReactor_add(swReactor *reactor, int fd, int type) +{ + swConnection *socket = swReactor_get(reactor, fd); + socket->fdtype = swReactor_fdtype(type); + socket->events = swReactor_events(type); + socket->removed = 0; +} + +static sw_inline void swReactor_set(swReactor *reactor, int fd, int type) +{ + swConnection *socket = swReactor_get(reactor, fd); + socket->events = swReactor_events(type); +} + +static sw_inline void swReactor_del(swReactor *reactor, int fd) +{ + swConnection *socket = swReactor_get(reactor, fd); + socket->events = 0; + socket->removed = 1; +} + +int swReactor_onWrite(swReactor *reactor, swEvent *ev); +int swReactor_close(swReactor *reactor, int fd); +int swReactor_write(swReactor *reactor, int fd, void *buf, int n); +int swReactor_wait_write_buffer(swReactor *reactor, int fd); +void swReactor_activate_future_task(swReactor *reactor); + +static sw_inline int swReactor_add_event(swReactor *reactor, int fd, enum swEvent_type event_type) +{ + swConnection *conn = swReactor_get(reactor, fd); + if (!(conn->events & event_type)) + { + return reactor->set(reactor, fd, conn->fdtype | conn->events | event_type); + } + return SW_OK; +} + +static sw_inline int swReactor_del_event(swReactor *reactor, int fd, enum swEvent_type event_type) +{ + swConnection *conn = swReactor_get(reactor, fd); + if (conn->events & event_type) + { + return reactor->set(reactor, fd, conn->fdtype | (conn->events & (~event_type))); + } + return SW_OK; +} + +static sw_inline int swReactor_remove_read_event(swReactor *reactor, int fd) +{ + swConnection *conn = swReactor_get(reactor, fd); + if (conn->events & SW_EVENT_WRITE) + { + conn->events &= (~SW_EVENT_READ); + return reactor->set(reactor, fd, conn->fdtype | conn->events); + } + else + { + return reactor->del(reactor, fd); + } +} + +static sw_inline swReactor_handle swReactor_getHandle(swReactor *reactor, int event_type, int fdtype) +{ + if (event_type == SW_EVENT_WRITE) + { + return (reactor->write_handle[fdtype] != NULL) ? reactor->write_handle[fdtype] : reactor->handle[SW_FD_WRITE]; + } + else if (event_type == SW_EVENT_ERROR) + { + return (reactor->error_handle[fdtype] != NULL) ? reactor->error_handle[fdtype] : reactor->handle[SW_FD_CLOSE]; + } + return reactor->handle[fdtype]; +} + +int swReactorEpoll_create(swReactor *reactor, int max_event_num); +int swReactorPoll_create(swReactor *reactor, int max_event_num); +int swReactorKqueue_create(swReactor *reactor, int max_event_num); +int swReactorSelect_create(swReactor *reactor); + +/*----------------------------Process Pool-------------------------------*/ +int swProcessPool_create(swProcessPool *pool, int worker_num, int max_request, key_t msgqueue_key, int ipc_mode); +int swProcessPool_create_unix_socket(swProcessPool *pool, char *socket_file, int blacklog); +int swProcessPool_create_tcp_socket(swProcessPool *pool, char *host, int port, int blacklog); +int swProcessPool_set_protocol(swProcessPool *pool, int task_protocol, uint32_t max_packet_size); +int swProcessPool_wait(swProcessPool *pool); +int swProcessPool_start(swProcessPool *pool); +void swProcessPool_shutdown(swProcessPool *pool); +pid_t swProcessPool_spawn(swProcessPool *pool, swWorker *worker); +int swProcessPool_dispatch(swProcessPool *pool, swEventData *data, int *worker_id); +int swProcessPool_response(swProcessPool *pool, char *data, int length); +int swProcessPool_dispatch_blocking(swProcessPool *pool, swEventData *data, int *dst_worker_id); +int swProcessPool_add_worker(swProcessPool *pool, swWorker *worker); +int swProcessPool_del_worker(swProcessPool *pool, swWorker *worker); + +static sw_inline swWorker* swProcessPool_get_worker(swProcessPool *pool, int worker_id) +{ + return &(pool->workers[worker_id - pool->start_id]); +} + +//-----------------------------Channel--------------------------- +enum SW_CHANNEL_FLAGS +{ + SW_CHAN_LOCK = 1u << 1, + SW_CHAN_NOTIFY = 1u << 2, + SW_CHAN_SHM = 1u << 3, +}; + +typedef struct _swChannel +{ + off_t head; + off_t tail; + size_t size; + char head_tag; + char tail_tag; + int num; + int max_num; + /** + * Data length, excluding structure + */ + size_t bytes; + int flag; + int maxlen; + /** + * memory point + */ + void *mem; + swLock lock; + swPipe notify_fd; +} swChannel; + +swChannel* swChannel_new(size_t size, int maxlen, int flag); +#define swChannel_empty(ch) (ch->num == 0) +#define swChannel_full(ch) ((ch->head == ch->tail && ch->tail_tag != ch->head_tag) || (ch->bytes + sizeof(int) * ch->num == ch->size)) +int swChannel_pop(swChannel *object, void *out, int buffer_length); +int swChannel_push(swChannel *object, void *in, int data_length); +int swChannel_out(swChannel *object, void *out, int buffer_length); +int swChannel_in(swChannel *object, void *in, int data_length); +int swChannel_peek(swChannel *object, void *out, int buffer_length); +int swChannel_wait(swChannel *object); +int swChannel_notify(swChannel *object); +void swChannel_free(swChannel *object); +void swChannel_print(swChannel *); + +/*----------------------------LinkedList-------------------------------*/ +swLinkedList* swLinkedList_new(uint8_t type, swDestructor dtor); +int swLinkedList_append(swLinkedList *ll, void *data); +void swLinkedList_remove_node(swLinkedList *ll, swLinkedList_node *remove_node); +int swLinkedList_prepend(swLinkedList *ll, void *data); +void* swLinkedList_pop(swLinkedList *ll); +void* swLinkedList_shift(swLinkedList *ll); +swLinkedList_node* swLinkedList_find(swLinkedList *ll, void *data); +void swLinkedList_free(swLinkedList *ll); +#define swLinkedList_remove(ll, data) (swLinkedList_remove_node(ll, swLinkedList_find(ll, data))) +/*----------------------------Thread Pool-------------------------------*/ +enum swThread_type +{ + SW_THREAD_MASTER = 1, + SW_THREAD_REACTOR = 2, + SW_THREAD_WORKER = 3, + SW_THREAD_UDP = 4, + SW_THREAD_UNIX_DGRAM = 5, + SW_THREAD_HEARTBEAT = 6, +}; + +typedef struct _swThreadPool +{ + swCond cond; + + swThread *threads; + swThreadParam *params; + + void *ptr1; + void *ptr2; + +#ifdef SW_THREADPOOL_USE_CHANNEL + swChannel *chan; +#else + swRingQueue queue; +#endif + + int thread_num; + int shutdown; + sw_atomic_t task_num; + + void (*onStart)(struct _swThreadPool *pool, int id); + void (*onStop)(struct _swThreadPool *pool, int id); + int (*onTask)(struct _swThreadPool *pool, void *task, int task_len); + +} swThreadPool; + +struct _swThread +{ + pthread_t tid; + int id; + swThreadPool *pool; +}; + +int swThreadPool_dispatch(swThreadPool *pool, void *task, int task_len); +int swThreadPool_create(swThreadPool *pool, int max_num); +int swThreadPool_run(swThreadPool *pool); +int swThreadPool_free(swThreadPool *pool); + +//--------------------------------protocol------------------------------ +int swProtocol_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size); +int swProtocol_recv_check_length(swProtocol *protocol, swConnection *conn, swString *buffer); +int swProtocol_recv_check_eof(swProtocol *protocol, swConnection *conn, swString *buffer); + +//--------------------------------timer------------------------------ +typedef struct _swTimer swTimer; +typedef struct _swTimer_node swTimer_node; + +typedef void (*swTimerCallback)(swTimer *, swTimer_node *); + +struct _swTimer_node +{ + swHeap_node *heap_node; + void *data; + swTimerCallback callback; + int64_t exec_msec; + uint32_t interval; + long id; + int type; //0 normal node 1 node for client_coro + uint8_t remove; +}; + +enum swTimer_type +{ + SW_TIMER_TYPE_KERNEL, + SW_TIMER_TYPE_CORO, + SW_TIMER_TYPE_PHP, +}; + +struct _swTimer +{ + /*--------------timerfd & signal timer--------------*/ + swHeap *heap; + swHashMap *map; + int num; + int use_pipe; + int lasttime; + int fd; + long _next_id; + long _current_id; + long _next_msec; + swPipe pipe; + /*-----------------for EventTimer-------------------*/ + struct timeval basetime; + /*--------------------------------------------------*/ + int (*set)(swTimer *timer, long exec_msec); + swTimer_node* (*add)(swTimer *timer, int _msec, int persistent, void *data, swTimerCallback callback); +}; + +int swTimer_init(long msec); +int swTimer_del(swTimer *timer, swTimer_node *node); +void swTimer_free(swTimer *timer); +int swTimer_select(swTimer *timer); +int swTimer_now(struct timeval *time); + +static sw_inline swTimer_node* swTimer_get(swTimer *timer, long id) +{ + return (swTimer_node*) swHashMap_find_int(timer->map, id); +} + +int swSystemTimer_init(int msec, int use_pipe); +void swSystemTimer_signal_handler(int sig); +int swSystemTimer_event_handler(swReactor *reactor, swEvent *event); + +swTimeWheel* swTimeWheel_new(uint16_t size); +void swTimeWheel_free(swTimeWheel *tw); +void swTimeWheel_forward(swTimeWheel *tw, swReactor *reactor); +void swTimeWheel_add(swTimeWheel *tw, swConnection *conn); +void swTimeWheel_update(swTimeWheel *tw, swConnection *conn); +void swTimeWheel_remove(swTimeWheel *tw, swConnection *conn); +#define swTimeWheel_new_index(tw) (tw->current == 0 ? tw->size - 1 : tw->current - 1) +//-------------------------------------------------------------- +//Share Memory +typedef struct +{ + swLock lock; + swLock lock_2; +} SwooleGS_t; + +//Worker process global Variable +typedef struct +{ + /** + * Always run + */ + uint8_t run_always; + + /** + * Current Proccess Worker's id + */ + uint32_t id; + + /** + * pipe_worker + */ + int pipe_used; + + uint32_t reactor_wait_onexit :1; + uint32_t reactor_init :1; + uint32_t reactor_ready :1; + uint32_t reactor_exit :1; + uint32_t in_client :1; + uint32_t shutdown :1; + uint32_t wait_exit :1; + + int max_request; + +#ifdef SW_COROUTINE + swLinkedList *coro_timeout_list; + swLinkedList *delayed_coro_timeout_list; +#endif + + swString **buffer_input; + swString **buffer_output; + swWorker *worker; + +} swWorkerG; + +typedef struct +{ + uint16_t id; + uint8_t type; + uint8_t update_time; + uint8_t factory_lock_target; + int16_t factory_target_worker; + swString **buffer_input; + swString *buffer_stack; + swReactor *reactor; +} swThreadG; + +typedef struct +{ + union + { + char v4[INET_ADDRSTRLEN]; + char v6[INET6_ADDRSTRLEN]; + } address; +} swDNS_server; + +typedef struct _swServer swServer; +typedef struct _swFactory swFactory; + +typedef struct +{ + swTimer timer; + + uint8_t running :1; + uint8_t enable_coroutine :1; + uint8_t use_timerfd :1; + uint8_t use_signalfd :1; + uint8_t enable_signalfd :1; + uint8_t reuse_port :1; + uint8_t socket_dontwait :1; + uint8_t dns_lookup_random :1; + uint8_t use_async_resolver :1; + + /** + * Timer used pipe + */ + uint8_t use_timer_pipe :1; + + int error; + int process_type; + pid_t pid; + + int signal_alarm; //for timer with message queue + int signal_fd; + int log_fd; + int null_fd; + int debug_fd; + + /** + * worker(worker and task_worker) process chroot / user / group + */ + char *chroot; + char *user; + char *group; + + uint8_t log_level; + char *log_file; + int trace_flags; + + uint16_t cpu_num; + + uint32_t pagesize; + uint32_t max_sockets; + struct utsname uname; + + /** + * tcp socket default buffer size + */ + uint32_t socket_buffer_size; + + swServer *serv; + swFactory *factory; + + swMemoryPool *memory_pool; + swReactor *main_reactor; + + char *task_tmpdir; + uint16_t task_tmpdir_len; + + char *dns_server_v4; + char *dns_server_v6; + double dns_cache_refresh_time; + + swLock lock; + swHashMap *functions; + swLinkedList *hooks[SW_MAX_HOOK_TYPE]; + +} swServerG; + +extern swServerG SwooleG; //Local Global Variable +extern SwooleGS_t *SwooleGS; //Share Memory Global Variable +extern swWorkerG SwooleWG; //Worker Global Variable +extern __thread swThreadG SwooleTG; //Thread Global Variable + +#define SW_CPU_NUM (SwooleG.cpu_num) + +//----------------------------------------------- +//OS Feature +#if defined(HAVE_KQUEUE) || !defined(HAVE_SENDFILE) +int swoole_sendfile(int out_fd, int in_fd, off_t *offset, size_t size); +#else +#include <sys/sendfile.h> +#define swoole_sendfile(out_fd, in_fd, offset, limit) sendfile(out_fd, in_fd, offset, limit) +#endif + +static sw_inline void sw_spinlock(sw_atomic_t *lock) +{ + uint32_t i, n; + while (1) + { + if (*lock == 0 && sw_atomic_cmp_set(lock, 0, 1)) + { + return; + } + if (SW_CPU_NUM > 1) + { + for (n = 1; n < SW_SPINLOCK_LOOP_N; n <<= 1) + { + for (i = 0; i < n; i++) + { + sw_atomic_cpu_pause(); + } + + if (*lock == 0 && sw_atomic_cmp_set(lock, 0, 1)) + { + return; + } + } + } + swYield(); + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* SWOOLE_H_ */ diff --git a/vendor/swoole/include/table.h b/vendor/swoole/include/table.h new file mode 100755 index 0000000..e3c31ff --- /dev/null +++ b/vendor/swoole/include/table.h @@ -0,0 +1,192 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + + + +#ifndef SW_TABLE_H_ +#define SW_TABLE_H_ + +#include "atomic.h" +#include "hashmap.h" +#include "hash.h" + +typedef struct _swTableRow +{ +#if SW_TABLE_USE_SPINLOCK + sw_atomic_t lock; +#else + pthread_mutex_t lock; +#endif + /** + * 1:used, 0:empty + */ + uint8_t active; + /** + * next slot + */ + struct _swTableRow *next; + /** + * Hash Key + */ + char key[SW_TABLE_KEY_SIZE]; + char data[0]; +} swTableRow; + +typedef struct +{ + uint32_t absolute_index; + uint32_t collision_index; + swTableRow *row; +} swTable_iterator; + +typedef struct +{ + swHashMap *columns; + uint16_t column_num; + swLock lock; + size_t size; + size_t mask; + size_t item_size; + size_t memory_size; + float conflict_proportion; + + /** + * total rows that in active state(shm) + */ + sw_atomic_t row_num; + + swTableRow **rows; + swMemoryPool *pool; + + swTable_iterator *iterator; + + void *memory; +} swTable; + +typedef struct +{ + uint8_t type; + uint32_t size; + swString* name; + uint16_t index; +} swTableColumn; + +enum swoole_table_type +{ + SW_TABLE_INT = 1, + SW_TABLE_INT8, + SW_TABLE_INT16, + SW_TABLE_INT32, +#ifdef __x86_64__ + SW_TABLE_INT64, +#endif + SW_TABLE_FLOAT, + SW_TABLE_STRING, +}; + +enum swoole_table_find +{ + SW_TABLE_FIND_EQ = 1, + SW_TABLE_FIND_NEQ, + SW_TABLE_FIND_GT, + SW_TABLE_FIND_LT, + SW_TABLE_FIND_LEFTLIKE, + SW_TABLE_FIND_RIGHTLIKE, + SW_TABLE_FIND_LIKE, +}; + +swTable* swTable_new(uint32_t rows_size, float conflict_proportion); +size_t swTable_get_memory_size(swTable *table); +int swTable_create(swTable *table); +void swTable_free(swTable *table); +int swTableColumn_add(swTable *table, char *name, int len, int type, int size); +swTableRow* swTableRow_set(swTable *table, char *key, int keylen, swTableRow **rowlock); +swTableRow* swTableRow_get(swTable *table, char *key, int keylen, swTableRow **rowlock); + +void swTable_iterator_rewind(swTable *table); +swTableRow* swTable_iterator_current(swTable *table); +void swTable_iterator_forward(swTable *table); +int swTableRow_del(swTable *table, char *key, int keylen); + +static sw_inline swTableColumn* swTableColumn_get(swTable *table, char *column_key, int keylen) +{ + return swHashMap_find(table->columns, column_key, keylen); +} + +static sw_inline void swTableRow_lock(swTableRow *row) +{ +#if SW_TABLE_USE_SPINLOCK + sw_spinlock(&row->lock); +#else + pthread_mutex_lock(&row->lock); +#endif +} + +static sw_inline void swTableRow_unlock(swTableRow *row) +{ +#if SW_TABLE_USE_SPINLOCK + sw_spinlock_release(&row->lock); +#else + pthread_mutex_unlock(&row->lock); +#endif +} + +typedef uint32_t swTable_string_length_t; + +static sw_inline void swTableRow_set_value(swTableRow *row, swTableColumn * col, void *value, int vlen) +{ + int8_t _i8; + int16_t _i16; + int32_t _i32; +#ifdef __x86_64__ + int64_t _i64; +#endif + switch(col->type) + { + case SW_TABLE_INT8: + _i8 = *(int8_t *) value; + memcpy(row->data + col->index, &_i8, 1); + break; + case SW_TABLE_INT16: + _i16 = *(int16_t *) value; + memcpy(row->data + col->index, &_i16, 2); + break; + case SW_TABLE_INT32: + _i32 = *(int32_t *) value; + memcpy(row->data + col->index, &_i32, 4); + break; +#ifdef __x86_64__ + case SW_TABLE_INT64: + _i64 = *(int64_t *) value; + memcpy(row->data + col->index, &_i64, 8); + break; +#endif + case SW_TABLE_FLOAT: + memcpy(row->data + col->index, value, sizeof(double)); + break; + default: + if (vlen > (col->size - sizeof(swTable_string_length_t))) + { + swWarn("[key=%s,field=%s]string value is too long.", row->key, col->name->str); + vlen = col->size - sizeof(swTable_string_length_t); + } + memcpy(row->data + col->index, &vlen, sizeof(swTable_string_length_t)); + memcpy(row->data + col->index + sizeof(swTable_string_length_t), value, vlen); + break; + } +} + +#endif /* SW_TABLE_H_ */ diff --git a/vendor/swoole/include/tests.h b/vendor/swoole/include/tests.h new file mode 100755 index 0000000..6203723 --- /dev/null +++ b/vendor/swoole/include/tests.h @@ -0,0 +1,73 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SW_TESTS_H_ +#define SW_TESTS_H_ + +#define swUnitTest(x) int swUnitTest_##x(swUnitTest *object) +#define swUnitTest_steup(x,n,t) _swUnitTest_setup(swUnitTest_##x, #x, n, t) + +typedef struct _swUnitTest +{ + int argc; + char **argv; +} swUnitTest; +typedef int (*swUnitTest_Func)(swUnitTest *object); + +void _swUnitTest_setup(swUnitTest_Func func, char *func_name, int run_times, char *comment); +int swUnitTest_run(swUnitTest *object); + +swUnitTest(mem_test1); +swUnitTest(mem_test2); +swUnitTest(mem_test3); +swUnitTest(mem_test4); + +swUnitTest(dnslookup_test); +swUnitTest(client_test); +swUnitTest(server_test); + +swUnitTest(hashmap_test1); +swUnitTest(ds_test2); +swUnitTest(ds_test1); + +swUnitTest(chan_test); + +swUnitTest(u1_test2); +swUnitTest(u1_test1); +swUnitTest(u1_test3); + +swUnitTest(http_test2); + +swUnitTest(type_test1); + +swUnitTest(aio_test); +swUnitTest(aio_test2); + +swUnitTest(ws_test1); + +swUnitTest(http_test1); +swUnitTest(http_test2); + +swUnitTest(heap_test1); +swUnitTest(linkedlist_test); +swUnitTest(rbtree_test); +void p_str(void *str); + +swUnitTest(pool_thread); + +swUnitTest(ringbuffer_test1); + +#endif /* SW_TESTS_H_ */ diff --git a/vendor/swoole/include/uthash.h b/vendor/swoole/include/uthash.h new file mode 100755 index 0000000..555a220 --- /dev/null +++ b/vendor/swoole/include/uthash.h @@ -0,0 +1,935 @@ +/* +Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/ +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef UTHASH_H +#define UTHASH_H + +#include <string.h> /* memcmp,strlen */ +#include <stddef.h> /* ptrdiff_t */ +#include <stdlib.h> /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on win32 */ +#ifdef _MSC_VER +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#else +#include <inttypes.h> /* uint32_t */ +#endif + +#define UTHASH_VERSION 1.9.8 + +#ifndef uthash_fatal +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#endif +#ifndef uthash_malloc +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#endif +#ifndef uthash_free +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ +#endif + +#ifndef uthash_noexpand_fyi +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#endif +#ifndef uthash_expand_fyi +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ +#endif + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_bkt,_hf_hashv; \ + out=NULL; \ + if (head) { \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0) + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0) + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#define HASH_BLOOM_BYTELEN 0 +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add) + +#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ +do { \ + replaced=NULL; \ + HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \ + if (replaced!=NULL) { \ + HASH_DELETE(hh,head,replaced); \ + }; \ + HASH_ADD(hh,head,fieldname,keylen_in,add); \ +} while(0) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)(keyptr); \ + (add)->hh.keylen = (unsigned)(keylen_in); \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + unsigned _hd_bkt; \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield,strlen(add->strfield),add) +#define HASH_REPLACE_STR(head,strfield,add,replaced) \ + HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_REPLACE_INT(head,intfield,add,replaced) \ + HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_REPLACE_PTR(head,ptrfield,add) \ + HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + unsigned _bkt_i; \ + unsigned _count, _bkt_count; \ + char *_prev; \ + struct UT_hash_handle *_thh; \ + if (head) { \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %d, actual %d\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include <unistd.h> to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6 */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) + +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) \ + hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + unsigned char *_hj_key=(unsigned char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = (unsigned)(keylen); \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned char *_sfh_key=(unsigned char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + uint32_t _mur_k1 = 0; \ + const uint8_t *_mur_tail; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if ((out)->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + if (_hs_p){ \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + } \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + if (_hs_e) { \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + } \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + if (_hs_tail){ \ + _hs_tail->next = NULL; \ + } \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#define HASH_OVERHEAD(hh,head) \ + (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ + ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ + (sizeof(UT_hash_table)) + \ + (HASH_BLOOM_BYTELEN))) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/vendor/swoole/include/websocket.h b/vendor/swoole/include/websocket.h new file mode 100755 index 0000000..679e2a6 --- /dev/null +++ b/vendor/swoole/include/websocket.h @@ -0,0 +1,103 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SW_WEBSOCKET_H_ +#define SW_WEBSOCKET_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "http.h" + +#define SW_WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" +#define SW_WEBSOCKET_HEADER_LEN 2 +#define SW_WEBSOCKET_MASK_LEN 4 +#define SW_WEBSOCKET_MASK_DATA "258E" +#define SW_WEBSOCKET_EXT16_LENGTH 0x7E +#define SW_WEBSOCKET_EXT16_MAX_LEN 0xFFFF +#define SW_WEBSOCKET_EXT64_LENGTH 0x7F +#define SW_WEBSOCKET_MASKED(frm) (frm->header.MASK) + +#define FRAME_SET_FIN(BYTE) (((BYTE) & 0x01) << 7) +#define FRAME_SET_OPCODE(BYTE) ((BYTE) & 0x0F) +#define FRAME_SET_MASK(BYTE) (((BYTE) & 0x01) << 7) +#define FRAME_SET_LENGTH(X64, IDX) (unsigned char)(((X64) >> ((IDX)*8)) & 0xFF) + +enum swWebsocketStatus +{ + WEBSOCKET_STATUS_CONNECTION = 1, + WEBSOCKET_STATUS_HANDSHAKE = 2, + WEBSOCKET_STATUS_ACTIVE = 3, +}; + +typedef struct +{ + /** + * fin:1 rsv1:1 rsv2:1 rsv3:1 opcode:4 + */ + struct + { + uchar OPCODE :4; + uchar RSV3 :1; + uchar RSV2 :1; + uchar RSV1 :1; + uchar FIN :1; + uchar LENGTH :7; + uchar MASK :1; + } header; + char mask_key[SW_WEBSOCKET_MASK_LEN]; + uint16_t header_length; + size_t payload_length; + char *payload; +} swWebSocket_frame; + +enum swWebsocketCode +{ + WEBSOCKET_OPCODE_CONTINUATION_FRAME = 0x0, + WEBSOCKET_OPCODE_TEXT_FRAME = 0x1, + WEBSOCKET_OPCODE_BINARY_FRAME = 0x2, + WEBSOCKET_OPCODE_CONNECTION_CLOSE = 0x8, + WEBSOCKET_OPCODE_PING = 0x9, + WEBSOCKET_OPCODE_PONG = 0xa, + + WEBSOCKET_CLOSE_NORMAL = 1000, + WEBSOCKET_CLOSE_GOING_AWAY = 1001, + WEBSOCKET_CLOSE_PROTOCOL_ERROR = 1002, + WEBSOCKET_CLOSE_DATA_ERROR = 1003, + WEBSOCKET_CLOSE_STATUS_ERROR = 1005, + WEBSOCKET_CLOSE_ABNORMAL = 1006, + WEBSOCKET_CLOSE_MESSAGE_ERROR = 1007, + WEBSOCKET_CLOSE_POLICY_ERROR = 1008, + WEBSOCKET_CLOSE_MESSAGE_TOO_BIG = 1009, + WEBSOCKET_CLOSE_EXTENSION_MISSING = 1010, + WEBSOCKET_CLOSE_SERVER_ERROR = 1011, + WEBSOCKET_CLOSE_TLS = 1015, + WEBSOCKET_VERSION = 13, +}; + +int swWebSocket_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t length); +void swWebSocket_encode(swString *buffer, char *data, size_t length, char opcode, int finish, int mask); +void swWebSocket_decode(swWebSocket_frame *frame, swString *data); +void swWebSocket_print_frame(swWebSocket_frame *frame); +int swWebSocket_dispatch_frame(swConnection *conn, char *data, uint32_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* SW_WEBSOCKET_H_ */ diff --git a/vendor/swoole/make.sh b/vendor/swoole/make.sh new file mode 100755 index 0000000..a373b88 --- /dev/null +++ b/vendor/swoole/make.sh @@ -0,0 +1,7 @@ +phpize --clean +phpize +./configure --enable-openssl --enable-sockets --enable-async-redis --enable-mysqlnd --enable-http2 +make clean +make -j +make install + diff --git a/vendor/swoole/package.xml b/vendor/swoole/package.xml new file mode 100755 index 0000000..dc3fc29 --- /dev/null +++ b/vendor/swoole/package.xml @@ -0,0 +1,948 @@ +<?xml version="1.0" encoding="UTF-8"?> +<package packagerversion="1.9.4" version="2.0" + xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> + <name>swoole</name> + <channel>pecl.php.net</channel> + <summary>Event-driven asynchronous and concurrent networking engine with high performance for PHP.</summary> + <description>Event-driven asynchronous and concurrent networking engine with high performance for PHP. +- event-driven +- asynchronous non-blocking +- multi-thread reactor +- multi-process worker +- multi-protocol +- millisecond timer +- async mysql client +- built-in http/websocket/http2 server +- async http/websocket client +- async redis client +- async task +- async read/write file system +- async dns lookup +- support IPv4/IPv6/UnixSocket/TCP/UDP +- support SSL/TLS encrypted transmission + </description> + <lead> + <name>Tianfeng Han</name> + <user>tianfenghan</user> + <email>mikan.tenny@gmail.com</email> + <active>yes</active> + </lead> + <developer> + <name>Shen Zhe</name> + <user>shenzhe</user> + <email>shenzhe163@gmail.com</email> + <active>yes</active> + </developer> + <date>2018-06-21</date> + <time>09:50:10</time> + <version> + <release>4.0.1</release> + <api>4.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <license uri="http://www.apache.org/licenses/LICENSE-2.0.html">Apache2.0</license> + <notes> + - Added enable_coroutine option + - Added MySQL8 caching_sha2_password supports + - Refactor channel + </notes> + <contents> + <dir name="/"> + <file role="doc" name="CREDITS" /> + <file role="doc" name="LICENSE" /> + <file role="doc" name="README.md" /> + <file role="doc" name="Version2.md" /> + <file role="src" name="config.m4" /> + <dir name="include"> + <file role="src" name="swoole.h" /> + <file role="src" name="Server.h" /> + <file role="src" name="Client.h" /> + <file role="src" name="Connection.h" /> + <file role="src" name="atomic.h" /> + <file role="src" name="buffer.h" /> + <file role="src" name="hashmap.h" /> + <file role="src" name="list.h" /> + <file role="src" name="RingQueue.h" /> + <file role="src" name="uthash.h" /> + <file role="src" name="tests.h" /> + <file role="src" name="array.h" /> + <file role="src" name="async.h" /> + <file role="src" name="hash.h" /> + <file role="src" name="heap.h" /> + <file role="src" name="table.h" /> + <file role="src" name="http.h" /> + <file role="src" name="http2.h" /> + <file role="src" name="websocket.h" /> + <file role="src" name="sha1.h" /> + <file role="src" name="base64.h" /> + <file role="src" name="mqtt.h" /> + <file role="src" name="error.h" /> + <file role="src" name="socks5.h" /> + <file role="src" name="redis.h" /> + <file role="src" name="context.h" /> + <file role="src" name="asm_context.h" /> + <file role="src" name="coroutine.h" /> + </dir> + <file role="src" name="php_swoole.h" /> + <file role="src" name="php7_wrapper.h" /> + <file role="src" name="swoole_config.h" /> + <file role="src" name="swoole.c" /> + <file role="src" name="swoole_server.c" /> + <file role="src" name="swoole_server_port.c" /> + <file role="src" name="swoole_lock.c" /> + <file role="src" name="swoole_client.c" /> + <file role="src" name="swoole_event.c" /> + <file role="src" name="swoole_timer.c" /> + <file role="src" name="swoole_async.c" /> + <file role="src" name="swoole_process.c" /> + <file role="src" name="swoole_table.c" /> + <file role="src" name="swoole_buffer.c" /> + <file role="src" name="swoole_http_server.c" /> + <file role="src" name="swoole_http_client.h" /> + <file role="src" name="swoole_http_client.c" /> + <file role="src" name="swoole_http_v2_client.h" /> + <file role="src" name="swoole_http_v2_client.c" /> + <file role="src" name="swoole_http_v2_server.c" /> + <file role="src" name="swoole_http_v2_client_coro.c" /> + <file role="src" name="swoole_http.h" /> + <file role="src" name="swoole_websocket_server.c" /> + <file role="src" name="swoole_atomic.c" /> + <file role="src" name="swoole_mysql.c" /> + <file role="src" name="swoole_mysql.h" /> + <file role="src" name="swoole_redis.c" /> + <file role="src" name="swoole_redis_server.c" /> + <file role="src" name="swoole_mmap.c" /> + <file role="src" name="swoole_channel_coro.cc" /> + <file role="src" name="swoole_channel.c" /> + <file role="src" name="swoole_serialize.h" /> + <file role="src" name="swoole_serialize.c" /> + <file role="src" name="swoole_coroutine.h" /> + <file role="src" name="swoole_coroutine.cc" /> + <file role="src" name="swoole_coroutine_util.c" /> + <file role="src" name="swoole_client_coro.c" /> + <file role="src" name="swoole_http_client_coro.c" /> + <file role="src" name="swoole_redis_coro.c" /> + <file role="src" name="swoole_mysql_coro.c" /> + <file role="src" name="swoole_postgresql_coro.c" /> + <file role="src" name="swoole_postgresql_coro.h" /> + <file role="src" name="swoole_trace.c" /> + <file role="src" name="swoole_ringqueue.c" /> + <file role="src" name="swoole_msgqueue.c" /> + <file role="src" name="swoole_process_pool.c" /> + <file role="src" name="swoole_runtime.cc" /> + <file role="src" name="swoole_socket_coro.c"/> + <file role="src" name="swoole_memory_pool.c" /> + <dir name="thirdparty"> + <file role="src" name="php_http_parser.c" /> + <file role="src" name="php_http_parser.h" /> + <file role="src" name="multipart_parser.c" /> + <file role="src" name="multipart_parser.h" /> + <dir name="picohttpparser"> + <file role="src" name="picohttpparser.c" /> + <file role="src" name="picohttpparser.h" /> + </dir> + <dir name="boost/asm"> + <file name="jump_arm64_aapcs_elf_gas.S" role="src" /> + <file name="jump_arm64_aapcs_macho_gas.S" role="src" /> + <file name="jump_arm_aapcs_elf_gas.S" role="src" /> + <file name="jump_arm_aapcs_macho_gas.S" role="src" /> + <file name="jump_arm_aapcs_pe_armasm.asm" role="src" /> + <file name="jump_combined_sysv_macho_gas.S" role="src" /> + <file name="jump_i386_ms_pe_gas.asm" role="src" /> + <file name="jump_i386_ms_pe_masm.asm" role="src" /> + <file name="jump_i386_sysv_elf_gas.S" role="src" /> + <file name="jump_i386_sysv_macho_gas.S" role="src" /> + <file name="jump_i386_x86_64_sysv_macho_gas.S" role="src" /> + <file name="jump_mips32_o32_elf_gas.S" role="src" /> + <file name="jump_ppc32_ppc64_sysv_macho_gas.S" role="src" /> + <file name="jump_ppc32_sysv_elf_gas.S" role="src" /> + <file name="jump_ppc32_sysv_macho_gas.S" role="src" /> + <file name="jump_ppc32_sysv_xcoff_gas.S" role="src" /> + <file name="jump_ppc64_sysv_elf_gas.S" role="src" /> + <file name="jump_ppc64_sysv_macho_gas.S" role="src" /> + <file name="jump_ppc64_sysv_xcoff_gas.S" role="src" /> + <file name="jump_sparc64_sysv_elf_gas.S" role="src" /> + <file name="jump_sparc_sysv_elf_gas.S" role="src" /> + <file name="jump_x86_64_ms_pe_gas.asm" role="src" /> + <file name="jump_x86_64_ms_pe_masm.asm" role="src" /> + <file name="jump_x86_64_sysv_elf_gas.S" role="src" /> + <file name="jump_x86_64_sysv_macho_gas.S" role="src" /> + <file name="make_arm64_aapcs_elf_gas.S" role="src" /> + <file name="make_arm64_aapcs_macho_gas.S" role="src" /> + <file name="make_arm_aapcs_elf_gas.S" role="src" /> + <file name="make_arm_aapcs_macho_gas.S" role="src" /> + <file name="make_arm_aapcs_pe_armasm.asm" role="src" /> + <file name="make_combined_sysv_macho_gas.S" role="src" /> + <file name="make_i386_ms_pe_gas.asm" role="src" /> + <file name="make_i386_ms_pe_masm.asm" role="src" /> + <file name="make_i386_sysv_elf_gas.S" role="src" /> + <file name="make_i386_sysv_macho_gas.S" role="src" /> + <file name="make_i386_x86_64_sysv_macho_gas.S" role="src" /> + <file name="make_mips32_o32_elf_gas.S" role="src" /> + <file name="make_ppc32_ppc64_sysv_macho_gas.S" role="src" /> + <file name="make_ppc32_sysv_elf_gas.S" role="src" /> + <file name="make_ppc32_sysv_macho_gas.S" role="src" /> + <file name="make_ppc32_sysv_xcoff_gas.S" role="src" /> + <file name="make_ppc64_sysv_elf_gas.S" role="src" /> + <file name="make_ppc64_sysv_macho_gas.S" role="src" /> + <file name="make_ppc64_sysv_xcoff_gas.S" role="src" /> + <file name="make_sparc64_sysv_elf_gas.S" role="src" /> + <file name="make_sparc_sysv_elf_gas.S" role="src" /> + <file name="make_x86_64_ms_pe_gas.asm" role="src" /> + <file name="make_x86_64_ms_pe_masm.asm" role="src" /> + <file name="make_x86_64_sysv_elf_gas.S" role="src" /> + <file name="make_x86_64_sysv_macho_gas.S" role="src" /> + </dir> + </dir> + <dir name="benchmark"> + <file role="src" name="async.php" /> + <file role="src" name="run.php" /> + <file role="src" name="tcp.php" /> + <file role="src" name="udp.php" /> + <file role="src" name="http.php" /> + <file role="src" name="http.js" /> + <file role="src" name="tcp.js" /> + <file role="src" name="tcp.go" /> + <file role="src" name="http.go" /> + </dir> + <dir name="src"> + <dir name="core"> + <file role="src" name="base.c" /> + <file role="src" name="socket.c" /> + <file role="src" name="log.c" /> + <file role="src" name="hashmap.c" /> + <file role="src" name="RingQueue.c" /> + <file role="src" name="Channel.c" /> + <file role="src" name="string.c" /> + <file role="src" name="array.c" /> + <file role="src" name="list.c" /> + <file role="src" name="heap.c" /> + <file role="src" name="error.cc" /> + </dir> + <dir name="memory"> + <file role="src" name="ShareMemory.c" /> + <file role="src" name="MemoryGlobal.c" /> + <file role="src" name="FixedPool.c" /> + <file role="src" name="RingBuffer.c" /> + <file role="src" name="Table.c" /> + <file role="src" name="Malloc.c" /> + <file role="src" name="Buffer.c" /> + </dir> + <dir name="factory"> + <file role="src" name="Factory.c" /> + <file role="src" name="FactoryThread.c" /> + <file role="src" name="FactoryProcess.c" /> + </dir> + <dir name="reactor"> + <file role="src" name="ReactorBase.c" /> + <file role="src" name="ReactorSelect.c" /> + <file role="src" name="ReactorPoll.c" /> + <file role="src" name="ReactorEpoll.c" /> + <file role="src" name="ReactorKqueue.c" /> + </dir> + <dir name="pipe"> + <file role="src" name="PipeBase.c" /> + <file role="src" name="PipeEventfd.c" /> + <file role="src" name="PipeUnsock.c" /> + </dir> + <dir name="lock"> + <file role="src" name="Semaphore.c" /> + <file role="src" name="Mutex.c" /> + <file role="src" name="RWLock.c" /> + <file role="src" name="SpinLock.c" /> + <file role="src" name="FileLock.c" /> + <file role="src" name="Cond.c" /> + </dir> + <dir name="network"> + <file role="src" name="Client.c" /> + <file role="src" name="Connection.c" /> + <file role="src" name="ProcessPool.c" /> + <file role="src" name="ReactorProcess.c" /> + <file role="src" name="ReactorThread.c" /> + <file role="src" name="Server.c" /> + <file role="src" name="TaskWorker.c" /> + <file role="src" name="ThreadPool.c" /> + <file role="src" name="Worker.c" /> + <file role="src" name="Manager.c" /> + <file role="src" name="Timer.c" /> + <file role="src" name="DNS.c" /> + <file role="src" name="Port.c" /> + <file role="src" name="TimeWheel.c" /> + <file role="src" name="Stream.c" /> + </dir> + <dir name="os"> + <file role="src" name="base.c" /> + <file role="src" name="msg_queue.c" /> + <file role="src" name="sendfile.c" /> + <file role="src" name="signal.c" /> + <file role="src" name="timer.c" /> + </dir> + <dir name="protocol"> + <file role="src" name="Base.c" /> + <file role="src" name="SSL.c" /> + <file role="src" name="Http.c" /> + <file role="src" name="Http2.c" /> + <file role="src" name="WebSocket.c" /> + <file role="src" name="Sha1.c" /> + <file role="src" name="Base64.c" /> + <file role="src" name="Mqtt.c" /> + <file role="src" name="Socks5.c" /> + <file role="src" name="MimeTypes.c" /> + <file role="src" name="Redis.c" /> + </dir> + <dir name="coroutine"> + <file role="src" name="base.cc" /> + <file role="src" name="boost.cc" /> + <file role="src" name="ucontext.cc" /> + <file role="src" name="context.cc" /> + </dir> + </dir> + <dir name="examples"> + <dir name="async"> + <file role="src" name="read.php" /> + <file role="src" name="readfile.php" /> + <file role="src" name="write.php" /> + <file role="src" name="dns_lookup.php" /> + <file role="src" name="exec.php" /> + </dir> + <dir name="client"> + <file role="src" name="async.php" /> + <file role="src" name="long_tcp.php" /> + <file role="src" name="sync.php" /> + <file role="src" name="select.php" /> + <file role="src" name="udp_async.php" /> + <file role="src" name="udp_sync.php" /> + </dir> + <dir name="server"> + <file role="src" name="echo.php" /> + <file role="src" name="ip_dispatch.php" /> + <file role="src" name="unix_stream.php" /> + <file role="src" name="listen_1k_port.php" /> + <file role="src" name="fixed_header_client.php" /> + <file role="src" name="fixed_header_server.php" /> + <file role="src" name="local_listener.php" /> + <file role="src" name="single.php" /> + </dir> + <dir name="coroutine"> + <file role="src" name="fread.php" /> + <file role="src" name="fwrite.php" /> + <file role="src" name="gethostbyname.php" /> + <file role="src" name="http_client.php" /> + <file role="src" name="http2_client.php" /> + <file role="src" name="httpmulti.php" /> + <file role="src" name="mysql_prepare.php" /> + <file role="src" name="mysql_query.php" /> + <file role="src" name="redis_pool.php" /> + <file role="src" name="redis_subscribe.php" /> + <file role="src" name="sleep.php" /> + <file role="src" name="stack.php" /> + <file role="src" name="tcp_backend_serv.php" /> + <file role="src" name="TestHttpServ.php" /> + <file role="src" name="timer_test.php" /> + <file role="src" name="udp_client.php" /> + <file role="src" name="udp_tcp_timeout.php" /> + <file role="src" name="websocket_client.php" /> + <file role="src" name="websocket.php" /> + </dir> + <dir name="http"> + <file role="src" name="server.php" /> + <file role="src" name="client.php" /> + <file role="src" name="curl.php" /> + <file role="src" name="async_client.php" /> + <file role="src" name="async_websocket.php" /> + <file role="src" name="download.php" /> + </dir> + <dir name="http2"> + <file role="src" name="server.php" /> + <file role="src" name="client.php" /> + </dir> + <dir name="length"> + <file role="src" name="server.php" /> + <file role="src" name="client.php" /> + <file role="src" name="async_client.php" /> + </dir> + <dir name="eof"> + <file role="src" name="server.php" /> + <file role="src" name="client.php" /> + <file role="src" name="async_client.php" /> + </dir> + <dir name="event"> + <file role="src" name="stream.php" /> + <file role="src" name="sockets.php" /> + </dir> + <dir name="unixsock"> + <file role="src" name="dgram_server.php" /> + <file role="src" name="stream_client.php" /> + <file role="src" name="dgram_client.php" /> + </dir> + <dir name="process"> + <file role="src" name="worker.php" /> + <file role="src" name="exec.php" /> + <file role="src" name="msgqueue.php" /> + <file role="src" name="echo.py" /> + <file role="src" name="python.php" /> + </dir> + <dir name="task"> + <file role="src" name="task.php" /> + <file role="src" name="task_coro.php" /> + <file role="src" name="shared_client.php" /> + <file role="src" name="shared_server.php" /> + </dir> + <dir name="table"> + <file role="src" name="iterator.php" /> + <file role="src" name="server.php" /> + <file role="src" name="set.php" /> + <file role="src" name="simulation.php" /> + </dir> + <dir name="websocket"> + <file role="src" name="server.php" /> + <file role="src" name="client.php" /> + <file role="src" name="client.html" /> + <file role="src" name="WebSocketClient.php" /> + </dir> + <dir name="ipv6"> + <file role="src" name="tcp_server.php" /> + <file role="src" name="udp_server.php" /> + <file role="src" name="tcp_client.php" /> + <file role="src" name="udp_client.php" /> + </dir> + <dir name="timer"> + <file role="src" name="after.php" /> + <file role="src" name="tick.php" /> + <file role="src" name="clear.php" /> + </dir> + <dir name="mysql"> + <file role="src" name="real_async.php" /> + <file role="src" name="transaction.php" /> + </dir> + <dir name="redis"> + <file role="src" name="client.php" /> + <file role="src" name="server.php" /> + <file role="src" name="subscribe.php" /> + </dir> + <dir name="mmap"> + <file role="src" name="mmap.php" /> + </dir> + <file role="src" name="server.php" /> + <file role="src" name="channel.php" /> + <file role="src" name="mysql_proxy_server.php" /> + <file role="src" name="proxy_sync.php" /> + <file role="src" name="sendfile_server.php" /> + <file role="src" name="recv_file.php" /> + <file role="doc" name="test.jpg" /> + </dir> + <dir name="tests"> + <file name="CONTRIBUTION" role="test" /> + <file name="README.md" role="test" /> + <file name="clean" role="test" /> + <file name="coro_test.sh" role="test" /> + <file name="include/api/http_server.php" role="test" /> + <file name="include/api/swoole_async/read_write.php" role="test" /> + <file name="include/api/swoole_async/recursive_write.php" role="test" /> + <file name="include/api/swoole_async/swoole_async_read.php" role="test" /> + <file name="include/api/swoole_async/swoole_async_write.php" role="test" /> + <file name="include/api/swoole_async/swoole_pipe_block.php" role="test" /> + <file name="include/api/swoole_async_old/read_write.php" role="test" /> + <file name="include/api/swoole_async_old/swoole_async_read.php" role="test" /> + <file name="include/api/swoole_async_old/swoole_async_readfile.php" role="test" /> + <file name="include/api/swoole_async_old/swoole_async_write.php" role="test" /> + <file name="include/api/swoole_async_old/swoole_async_writefile.php" role="test" /> + <file name="include/api/swoole_async_old/swoole_pipe_block.php" role="test" /> + <file name="include/api/swoole_callback/swoole_cannot_destroy_active_lambda_function.php" role="test" /> + <file name="include/api/swoole_client/connect_timeout.php" role="test" /> + <file name="include/api/swoole_client/connect_twice.php" role="test" /> + <file name="include/api/swoole_client/opcode_client.php" role="test" /> + <file name="include/api/swoole_client/simple_client.php" role="test" /> + <file name="include/api/swoole_client/socket_free.php" role="test" /> + <file name="include/api/swoole_http_client/connect_host_not_found.php" role="test" /> + <file name="include/api/swoole_http_client/connect_port_not_listen.php" role="test" /> + <file name="include/api/swoole_http_client/connect_timeout.php" role="test" /> + <file name="include/api/swoole_http_client/http_request_connect_timeout.php" role="test" /> + <file name="include/api/swoole_http_client/meomry_leak.php" role="test" /> + <file name="include/api/swoole_http_client/on_error_close.php" role="test" /> + <file name="include/api/swoole_http_client/on_receive_core.php" role="test" /> + <file name="include/api/swoole_http_client/simple_http_client.php" role="test" /> + <file name="include/api/swoole_http_client/simple_http_client_test.php" role="test" /> + <file name="include/api/swoole_http_client/simple_https_client.php" role="test" /> + <file name="include/api/swoole_http_client/simple_https_client_test.php" role="test" /> + <file name="include/api/swoole_http_client/swoole_http_client_RST.php" role="test" /> + <file name="include/api/swoole_http_client/swoole_http_client_simple.php" role="test" /> + <file name="include/api/swoole_http_client/uaf_client.php" role="test" /> + <file name="include/api/swoole_http_client/uaf_server.js" role="test" /> + <file name="include/api/swoole_http_server/htf_swoole20_https_server.php" role="test" /> + <file name="include/api/swoole_http_server/http_server.php" role="test" /> + <file name="include/api/swoole_http_server/http_server_without_response.php" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/ca.crt" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/ca.csr" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/ca.key" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/ca.srl" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/client.crt" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/client.csr" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/client.key" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/client.pem" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/server.crt" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/server.csr" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/server.key" role="test" /> + <file name="include/api/swoole_http_server/localhost-ssl/server.pem" role="test" /> + <file name="include/api/swoole_http_server/simple_http_server.php" role="test" /> + <file name="include/api/swoole_http_server/simple_https_server.php" role="test" /> + <file name="include/api/swoole_mysql/mysqli.php" role="test" /> + <file name="include/api/swoole_mysql/query_without_connect.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_connect_timeout.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_connect_twice.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_init.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_memory_leak.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_on_check.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_query_multi_filed.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_query_same_filed.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_recursive_query.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_refcout.php" role="test" /> + <file name="include/api/swoole_mysql/swoole_mysql_sql_syntax_error.php" role="test" /> + <file name="include/api/swoole_redis/connect_timeout.php" role="test" /> + <file name="include/api/swoole_redis/doublefree_client.php" role="test" /> + <file name="include/api/swoole_redis/doublefree_server.php" role="test" /> + <file name="include/api/swoole_redis/redis_server_without_response.php" role="test" /> + <file name="include/api/swoole_redis/redis_test.php" role="test" /> + <file name="include/api/swoole_redis/simple_redis.php" role="test" /> + <file name="include/api/swoole_server/TestServer.php" role="test" /> + <file name="include/api/swoole_server/manager_process_exit.log" role="test" /> + <file name="include/api/swoole_server/multi_protocol_server.php" role="test" /> + <file name="include/api/swoole_server/opcode_server.php" role="test" /> + <file name="include/api/swoole_server/reconnect_fail/tcp_client.php" role="test" /> + <file name="include/api/swoole_server/reconnect_fail/tcp_serv.php" role="test" /> + <file name="include/api/swoole_server/server_manager_process_exit.php" role="test" /> + <file name="include/api/swoole_server/server_send_fast_recv_slow.php" role="test" /> + <file name="include/api/swoole_server/simple_server.php" role="test" /> + <file name="include/api/swoole_server/simple_tcp_server.php" role="test" /> + <file name="include/api/swoole_server/simple_udp_server.php" role="test" /> + <file name="include/api/swoole_server/tcp_task_server.php" role="test" /> + <file name="include/api/swoole_server/testsendfile.txt" role="test" /> + <file name="include/api/swoole_timer/accurate_test.php" role="test" /> + <file name="include/api/swoole_timer/fixRate_vs_fixDelay.php" role="test" /> + <file name="include/api/swoole_timer/invalid_args.php" role="test" /> + <file name="include/api/swoole_timer/multi_timer.php" role="test" /> + <file name="include/api/swoole_timer/register_shutdown_priority.php" role="test" /> + <file name="include/api/swoole_utils/swoole_utils.php" role="test" /> + <file name="include/api/swoole_websocket_server/send_large_request_data.php" role="test" /> + <file name="include/api/swoole_websocket_server/send_small_request_data.php" role="test" /> + <file name="include/api/swoole_websocket_server/swoole_websocket_server.php" role="test" /> + <file name="include/api/swoole_websocket_server/websocket_client.php" role="test" /> + <file name="include/api/tcp_server.php" role="test" /> + <file name="include/bootstrap.php" role="test" /> + <file name="include/config.php" role="test" /> + <file name="include/ignore_files.php" role="test" /> + <file name="include/lib/class.websocket_client.php" role="test" /> + <file name="include/lib/curl.php" role="test" /> + <file name="include/macos/phpstorm.py" role="test" /> + <file name="include/memoryleak/connect_host_not_found.php" role="test" /> + <file name="include/memoryleak/tcp_client_memory_leak/tcp_serv.php" role="test" /> + <file name="include/redis/bug_01.php" role="test" /> + <file name="include/redis/bug_02.php" role="test" /> + <file name="include/redis/bug_03.php" role="test" /> + <file name="include/skipif.inc" role="test" /> + <file name="include/skipifDarwin.inc" role="test" /> + <file name="include/swoole.inc" role="test" /> + <file name="include/toolkit/RandStr.php" role="test" /> + <file name="include/toolkit/TcpStat.php" role="test" /> + <file name="include/toolkit/functions.php" role="test" /> + <file name="new.sh" role="test" /> + <file name="run-tests" role="test" /> + <file name="start.sh" role="test" /> + <file name="swoole_async/aio1.phpt" role="test" /> + <file name="swoole_async/aio2.phpt" role="test" /> + <file name="swoole_async/aio3.phpt" role="test" /> + <file name="swoole_async/parallel_read_copy_10m_file_with_1m_chunk.phpt" role="test" /> + <file name="swoole_async/parallel_read_copy_10m_file_with_512k_chunk.phpt" role="test" /> + <file name="swoole_async/readfile.phpt" role="test" /> + <file name="swoole_async/recursive_write.phpt" role="test" /> + <file name="swoole_async/serial_read_copy_10m_file.phpt" role="test" /> + <file name="swoole_async/swoole_async_dns_lookup.phpt" role="test" /> + <file name="swoole_async/swoole_async_read.phpt" role="test" /> + <file name="swoole_async/swoole_async_set.phpt" role="test" /> + <file name="swoole_async/swoole_async_write.phpt" role="test" /> + <file name="swoole_async/writefile.phpt" role="test" /> + <file name="swoole_atomic/atomic.phpt" role="test" /> + <file name="swoole_atomic/wait.phpt" role="test" /> + <file name="swoole_buffer/buffer_append.phpt" role="test" /> + <file name="swoole_buffer/buffer_clear.phpt" role="test" /> + <file name="swoole_buffer/buffer_expand.phpt" role="test" /> + <file name="swoole_buffer/buffer_read_write.phpt" role="test" /> + <file name="swoole_buffer/buffer_recycle.phpt" role="test" /> + <file name="swoole_buffer/buffer_substr.phpt" role="test" /> + <file name="swoole_buffer/construct_buffer.phpt" role="test" /> + <file name="swoole_channel/basic.phpt" role="test" /> + <file name="swoole_channel/pusu_pop_stats.phpt" role="test" /> + <file name="swoole_client_async/big_package_memory_leak.phpt" role="test" /> + <file name="swoole_client_async/buffer_full.php.phpt" role="test" /> + <file name="swoole_client_async/connect_dns.phpt" role="test" /> + <file name="swoole_client_async/connect_refuse.phpt" role="test" /> + <file name="swoole_client_async/connect_timeout.phpt" role="test" /> + <file name="swoole_client_async/connect_twice.phpt" role="test" /> + <file name="swoole_client_async/eof.phpt" role="test" /> + <file name="swoole_client_async/eof_close.phpt" role="test" /> + <file name="swoole_client_async/getSocket_bug.phpt" role="test" /> + <file name="swoole_client_async/getpeername.phpt" role="test" /> + <file name="swoole_client_async/getsockname.phpt" role="test" /> + <file name="swoole_client_async/length_protocol.phpt" role="test" /> + <file name="swoole_client_async/sendfile.phpt" role="test" /> + <file name="swoole_client_async/sleep_wake.phpt" role="test" /> + <file name="swoole_client_async/swoole_client.phpt" role="test" /> + <file name="swoole_client_coro/close_resume.phpt" role="test" /> + <file name="swoole_client_coro/eof.phpt" role="test" /> + <file name="swoole_client_coro/eof_02.phpt" role="test" /> + <file name="swoole_client_coro/length_02.phpt" role="test" /> + <file name="swoole_client_coro/tcp_client.phpt" role="test" /> + <file name="swoole_client_coro/timeout.phpt" role="test" /> + <file name="swoole_client_coro/udp_client.phpt" role="test" /> + <file name="swoole_client_sync/eof.phpt" role="test" /> + <file name="swoole_client_sync/eof_timeout.phpt" role="test" /> + <file name="swoole_client_sync/length_protocol.phpt" role="test" /> + <file name="swoole_client_sync/length_protocol_02.phpt" role="test" /> + <file name="swoole_client_sync/recv_timeout.phpt" role="test" /> + <file name="swoole_client_sync/sendfile.phpt" role="test" /> + <file name="swoole_client_sync/swoole_client_connect1-1.phpt" role="test" /> + <file name="swoole_client_sync/swoole_client_connect1-2.phpt" role="test" /> + <file name="swoole_client_sync/swoole_client_connect1-3.phpt" role="test" /> + <file name="swoole_client_sync/swoole_client_send_recv.phpt" role="test" /> + <file name="swoole_client_sync/swoole_client_sync_send_recv.phpt" role="test" /> + <file name="swoole_client_sync/udp_client_sendto.phpt" role="test" /> + <file name="swoole_coroutine/call_user_func_array.phpt" role="test" /> + <file name="swoole_coroutine/coro_stats.phpt" role="test" /> + <file name="swoole_coroutine/current.phpt" role="test" /> + <file name="swoole_coroutine/destruct/destruct1.phpt" role="test" /> + <file name="swoole_coroutine/destruct/destruct2.phpt" role="test" /> + <file name="swoole_coroutine/empty.phpt" role="test" /> + <file name="swoole_coroutine/exception/empty.phpt" role="test" /> + <file name="swoole_coroutine/exception/nested.phpt" role="test" /> + <file name="swoole_coroutine/exception/yield.phpt" role="test" /> + <file name="swoole_coroutine/exception/yield1.phpt" role="test" /> + <file name="swoole_coroutine/forbidden_case/array_map.phpt" role="test" /> + <file name="swoole_coroutine/forbidden_case/call_user.phpt" role="test" /> + <file name="swoole_coroutine/forbidden_case/invoke.phpt" role="test" /> + <file name="swoole_coroutine/nested1.phpt" role="test" /> + <file name="swoole_coroutine/nested2.phpt" role="test" /> + <file name="swoole_coroutine/nested3.phpt" role="test" /> + <file name="swoole_coroutine/nested_empty.phpt" role="test" /> + <file name="swoole_coroutine/nested_uid.phpt" role="test" /> + <file name="swoole_coroutine/no_inline_func.phpt" role="test" /> + <file name="swoole_coroutine/parallel1.phpt" role="test" /> + <file name="swoole_coroutine/parallel2.phpt" role="test" /> + <file name="swoole_coroutine/parallel3.phpt" role="test" /> + <file name="swoole_coroutine/use_process.phpt" role="test" /> + <file name="swoole_coroutine/user_coroutine.phpt" role="test" /> + <file name="swoole_coroutine/user_coroutine_2.phpt" role="test" /> + <file name="swoole_coroutine_channel/1.phpt" role="test" /> + <file name="swoole_coroutine_channel/2.phpt" role="test" /> + <file name="swoole_coroutine_channel/3.phpt" role="test" /> + <file name="swoole_coroutine_channel/4.phpt" role="test" /> + <file name="swoole_coroutine_channel/5.phpt" role="test" /> + <file name="swoole_coroutine_channel/basic.phpt" role="test" /> + <file name="swoole_coroutine_channel/chan_select_timeout.phpt" role="test" /> + <file name="swoole_coroutine_channel/chan_stats.phpt" role="test" /> + <file name="swoole_coroutine_channel/coro_wait.phpt" role="test" /> + <file name="swoole_coroutine_channel/fibonacci.phpt" role="test" /> + <file name="swoole_coroutine_channel/hybird_chan.phpt" role="test" /> + <file name="swoole_coroutine_channel/hybird_chan2.phpt" role="test" /> + <file name="swoole_coroutine_util/dns_lookup.phpt" role="test" /> + <file name="swoole_coroutine_util/exec.phpt" role="test" /> + <file name="swoole_coroutine_util/fgets.phpt" role="test" /> + <file name="swoole_coroutine_util/fread.phpt" role="test" /> + <file name="swoole_coroutine_util/fwrite.phpt" role="test" /> + <file name="swoole_coroutine_util/getaddrinfo.phpt" role="test" /> + <file name="swoole_coroutine_util/gethostbyname.phpt" role="test" /> + <file name="swoole_coroutine_util/gethostbyname_ipv6.phpt" role="test" /> + <file name="swoole_coroutine_util/readfile.phpt" role="test" /> + <file name="swoole_coroutine_util/resume1.phpt" role="test" /> + <file name="swoole_coroutine_util/resume2.phpt" role="test" /> + <file name="swoole_coroutine_util/resume3.phpt" role="test" /> + <file name="swoole_coroutine_util/resume4.phpt" role="test" /> + <file name="swoole_coroutine_util/sleep.phpt" role="test" /> + <file name="swoole_coroutine_util/writefile.phpt" role="test" /> + <file name="swoole_event/defer.phpt" role="test" /> + <file name="swoole_event/swoole_event.phpt" role="test" /> + <file name="swoole_event/swoole_event_core.phpt" role="test" /> + <file name="swoole_event/swoole_event_del.phpt" role="test" /> + <file name="swoole_event/swoole_event_isset.phpt" role="test" /> + <file name="swoole_event/swoole_event_set.phpt" role="test" /> + <file name="swoole_event/swoole_event_write.phpt" role="test" /> + <file name="swoole_function/swoole_cpu_num.phpt" role="test" /> + <file name="swoole_function/swoole_get_local_ip.phpt" role="test" /> + <file name="swoole_function/swoole_set_process_name.phpt" role="test" /> + <file name="swoole_function/swoole_version.phpt" role="test" /> + <file name="swoole_http2_client/get.phpt" role="test" /> + <file name="swoole_http2_client/headers.phpt" role="test" /> + <file name="swoole_http2_client_coro/headers.phpt" role="test" /> + <file name="swoole_http_cilent_coro/get.phpt" role="test" /> + <file name="swoole_http_cilent_coro/get_without_content_length.phpt" role="test" /> + <file name="swoole_http_cilent_coro/head_method.phpt" role="test" /> + <file name="swoole_http_cilent_coro/http_proxy.phpt" role="test" /> + <file name="swoole_http_cilent_coro/https.phpt" role="test" /> + <file name="swoole_http_cilent_coro/multi.phpt" role="test" /> + <file name="swoole_http_cilent_coro/websocket.phpt" role="test" /> + <file name="swoole_http_cilent_coro/websocket_bug_01.phpt" role="test" /> + <file name="swoole_http_client/connect_host_not_found.phpt" role="test" /> + <file name="swoole_http_client/connect_port_not_listen.phpt" role="test" /> + <file name="swoole_http_client/content_length.phpt" role="test" /> + <file name="swoole_http_client/cookie.phpt" role="test" /> + <file name="swoole_http_client/download.phpt" role="test" /> + <file name="swoole_http_client/execute_without_method_and_content.phpt" role="test" /> + <file name="swoole_http_client/get.phpt" role="test" /> + <file name="swoole_http_client/get_with_query_string.phpt" role="test" /> + <file name="swoole_http_client/get_without_query_string.phpt" role="test" /> + <file name="swoole_http_client/http_proxy.phpt" role="test" /> + <file name="swoole_http_client/http_request_connect_timeout.phpt" role="test" /> + <file name="swoole_http_client/keepalive.phpt" role="test" /> + <file name="swoole_http_client/method_delete.phpt" role="test" /> + <file name="swoole_http_client/method_delete_with_payload.phpt" role="test" /> + <file name="swoole_http_client/method_get.phpt" role="test" /> + <file name="swoole_http_client/method_get_with_payload.phpt" role="test" /> + <file name="swoole_http_client/method_head.phpt" role="test" /> + <file name="swoole_http_client/method_patch.phpt" role="test" /> + <file name="swoole_http_client/method_patch_with_payload.phpt" role="test" /> + <file name="swoole_http_client/method_post.phpt" role="test" /> + <file name="swoole_http_client/method_post_with_payload.phpt" role="test" /> + <file name="swoole_http_client/method_put.phpt" role="test" /> + <file name="swoole_http_client/method_put_with_payload.phpt" role="test" /> + <file name="swoole_http_client/post.phpt" role="test" /> + <file name="swoole_http_client/post_with_body.phpt" role="test" /> + <file name="swoole_http_client/post_with_empty_content.phpt" role="test" /> + <file name="swoole_http_client/post_without_content_length.phpt" role="test" /> + <file name="swoole_http_client/recursive_get.phpt" role="test" /> + <file name="swoole_http_client/request_timeout.phpt" role="test" /> + <file name="swoole_http_client/set_cookie_zval.phpt" role="test" /> + <file name="swoole_http_client/set_headers_core1.phpt" role="test" /> + <file name="swoole_http_client/set_headers_core2.phpt" role="test" /> + <file name="swoole_http_client/test_big_body.phpt" role="test" /> + <file name="swoole_http_client/test_cookie.phpt" role="test" /> + <file name="swoole_http_client/test_header.phpt" role="test" /> + <file name="swoole_http_client/test_header_core.phpt" role="test" /> + <file name="swoole_http_client/test_request.phpt" role="test" /> + <file name="swoole_http_client/test_twice_send.phpt" role="test" /> + <file name="swoole_http_client/test_uri.phpt" role="test" /> + <file name="swoole_http_client/timeout.phpt" role="test" /> + <file name="swoole_http_client/upload.phpt" role="test" /> + <file name="swoole_http_client/websocket.phpt" role="test" /> + <file name="swoole_http_client/websocket_bad_protocol.phpt" role="test" /> + <file name="swoole_http_client/websocket_bug_18031401.phpt" role="test" /> + <file name="swoole_http_client/websocket_port_not_listen.phpt" role="test" /> + <file name="swoole_http_server/chunk.phpt" role="test" /> + <file name="swoole_http_server/cookies.phpt" role="test" /> + <file name="swoole_http_server/enable_coroutine.phpt" role="test" /> + <file name="swoole_http_server/gzip.phpt" role="test" /> + <file name="swoole_http_server/large_url.phpt" role="test" /> + <file name="swoole_http_server/rawContent.phpt" role="test" /> + <file name="swoole_http_server/rawCookie.phpt" role="test" /> + <file name="swoole_http_server/redirect.phpt" role="test" /> + <file name="swoole_http_server/sendfile.phpt" role="test" /> + <file name="swoole_http_server/static_handler.phpt" role="test" /> + <file name="swoole_http_server/upload.phpt" role="test" /> + <file name="swoole_http_server/uploadFile.phpt" role="test" /> + <file name="swoole_https_client/get_with_query_string.phpt" role="test" /> + <file name="swoole_https_client/get_without_query_string.phpt" role="test" /> + <file name="swoole_https_client/http_proxy.phpt" role="test" /> + <file name="swoole_https_client/method_delete.phpt" role="test" /> + <file name="swoole_https_client/method_delete_with_payload.phpt" role="test" /> + <file name="swoole_https_client/method_get.phpt" role="test" /> + <file name="swoole_https_client/method_get_with_payload.phpt" role="test" /> + <file name="swoole_https_client/method_patch.phpt" role="test" /> + <file name="swoole_https_client/method_patch_with_payload.phpt" role="test" /> + <file name="swoole_https_client/method_post.phpt" role="test" /> + <file name="swoole_https_client/method_post_with_payload.phpt" role="test" /> + <file name="swoole_https_client/method_put.phpt" role="test" /> + <file name="swoole_https_client/method_put_with_payload.phpt" role="test" /> + <file name="swoole_https_client/post_with_body.phpt" role="test" /> + <file name="swoole_https_client/test_cookie.phpt" role="test" /> + <file name="swoole_https_client/test_header.phpt" role="test" /> + <file name="swoole_https_client/test_header_core.phpt" role="test" /> + <file name="swoole_https_client/test_request.phpt" role="test" /> + <file name="swoole_https_client/test_uri.phpt" role="test" /> + <file name="swoole_lock/mutex.phpt" role="test" /> + <file name="swoole_lock/trylock.phpt" role="test" /> + <file name="swoole_memory_pool/free_1.phpt" role="test" /> + <file name="swoole_mysql/connect_timeout.phpt" role="test" /> + <file name="swoole_mysql/connect_twice.phpt" role="test" /> + <file name="swoole_mysql/query_coredump.phpt" role="test" /> + <file name="swoole_mysql/query_multifield.phpt" role="test" /> + <file name="swoole_mysql/recursive_query.phpt" role="test" /> + <file name="swoole_mysql/refcount_test.phpt" role="test" /> + <file name="swoole_mysql/select1.phpt" role="test" /> + <file name="swoole_mysql/simple_insert.phpt" role="test" /> + <file name="swoole_mysql/simple_query.phpt" role="test" /> + <file name="swoole_mysql/sql_syntax_error.phpt" role="test" /> + <file name="swoole_mysql/transaction.phpt" role="test" /> + <file name="swoole_mysql/transaction_rollback.phpt" role="test" /> + <file name="swoole_mysql_coro/aborted_clients.phpt" role="test" /> + <file name="swoole_mysql_coro/fetch.phpt" role="test" /> + <file name="swoole_mysql_coro/fetch_mode.phpt" role="test" /> + <file name="swoole_mysql_coro/fetch_mode_twice.phpt" role="test" /> + <file name="swoole_mysql_coro/prepare_insert.phpt" role="test" /> + <file name="swoole_mysql_coro/prepare_select.phpt" role="test" /> + <file name="swoole_mysql_coro/procedure.phpt" role="test" /> + <file name="swoole_mysql_coro/procedure_in_fetch.phpt" role="test" /> + <file name="swoole_mysql_coro/procedure_single.phpt" role="test" /> + <file name="swoole_mysql_coro/query.phpt" role="test" /> + <file name="swoole_mysql_coro/query_timeout.phpt" role="test" /> + <file name="swoole_mysql_coro/simple_query.phpt" role="test" /> + <file name="swoole_mysql_coro/statement_destruct.phpt" role="test" /> + <file name="swoole_mysql_coro/without_fetch.phpt" role="test" /> + <file name="swoole_process/echo.py" role="test" /> + <file name="swoole_process/process_exec.phpt" role="test" /> + <file name="swoole_process/process_msgqueue.phpt" role="test" /> + <file name="swoole_process/process_push.phpt" role="test" /> + <file name="swoole_process/process_select.phpt" role="test" /> + <file name="swoole_process/signal.phpt" role="test" /> + <file name="swoole_process/swoole_process_close.phpt" role="test" /> + <file name="swoole_process/swoole_process_ctor.phpt" role="test" /> + <file name="swoole_process/swoole_process_deamon.phpt" role="test" /> + <file name="swoole_process/swoole_process_exec.phpt" role="test" /> + <file name="swoole_process/swoole_process_exit.phpt" role="test" /> + <file name="swoole_process/swoole_process_freeQueue.phpt" role="test" /> + <file name="swoole_process/swoole_process_kill.phpt" role="test" /> + <file name="swoole_process/swoole_process_name.phpt" role="test" /> + <file name="swoole_process/swoole_process_pop.phpt" role="test" /> + <file name="swoole_process/swoole_process_push.phpt" role="test" /> + <file name="swoole_process/swoole_process_read.phpt" role="test" /> + <file name="swoole_process/swoole_process_redirect.phpt" role="test" /> + <file name="swoole_process/swoole_process_setaffinity.phpt" role="test" /> + <file name="swoole_process/swoole_process_start.phpt" role="test" /> + <file name="swoole_process/swoole_process_useQueue.phpt" role="test" /> + <file name="swoole_process/swoole_process_wait.phpt" role="test" /> + <file name="swoole_process/swoole_process_write.phpt" role="test" /> + <file name="swoole_process/timeout.phpt" role="test" /> + <file name="swoole_process/write_in_worker.phpt" role="test" /> + <file name="swoole_redis/connect_refuse.phpt" role="test" /> + <file name="swoole_redis/connect_timeout.phpt" role="test" /> + <file name="swoole_redis/get_set.phpt" role="test" /> + <file name="swoole_redis/subscribe.phpt" role="test" /> + <file name="swoole_redis_coro/basic.phpt" role="test" /> + <file name="swoole_redis_coro/connect_timeout.phpt" role="test" /> + <file name="swoole_redis_coro/connect_twice-2.phpt" role="test" /> + <file name="swoole_redis_coro/connect_twice.phpt" role="test" /> + <file name="swoole_redis_coro/defer.phpt" role="test" /> + <file name="swoole_redis_coro/multi_exec.phpt" role="test" /> + <file name="swoole_redis_coro/pool.phpt" role="test" /> + <file name="swoole_redis_coro/reconnect.phpt" role="test" /> + <file name="swoole_redis_coro/subscribe.phpt" role="test" /> + <file name="swoole_redis_server/big_packet.phpt" role="test" /> + <file name="swoole_serialize/001.phpt" role="test" /> + <file name="swoole_serialize/002.phpt" role="test" /> + <file name="swoole_serialize/003.phpt" role="test" /> + <file name="swoole_serialize/004.phpt" role="test" /> + <file name="swoole_serialize/005.phpt" role="test" /> + <file name="swoole_serialize/006.phpt" role="test" /> + <file name="swoole_serialize/007.phpt" role="test" /> + <file name="swoole_serialize/008.phpt" role="test" /> + <file name="swoole_serialize/009.phpt" role="test" /> + <file name="swoole_serialize/010.phpt" role="test" /> + <file name="swoole_serialize/012.phpt" role="test" /> + <file name="swoole_serialize/013.phpt" role="test" /> + <file name="swoole_serialize/014.phpt" role="test" /> + <file name="swoole_serialize/016.phpt" role="test" /> + <file name="swoole_serialize/017.phpt" role="test" /> + <file name="swoole_serialize/019.phpt" role="test" /> + <file name="swoole_serialize/020.phpt" role="test" /> + <file name="swoole_serialize/021.phpt" role="test" /> + <file name="swoole_serialize/022.phpt" role="test" /> + <file name="swoole_serialize/023.phpt" role="test" /> + <file name="swoole_serialize/packunpack.phpt" role="test" /> + <file name="swoole_server/addListener.phpt" role="test" /> + <file name="swoole_server/addProcess.phpt" role="test" /> + <file name="swoole_server/bigPipeMessage.phpt" role="test" /> + <file name="swoole_server/big_udp_packet.phpt" role="test" /> + <file name="swoole_server/bind.phpt" role="test" /> + <file name="swoole_server/bug_11000_01.phpt" role="test" /> + <file name="swoole_server/connections.phpt" role="test" /> + <file name="swoole_server/dispatch_by_stream.phpt" role="test" /> + <file name="swoole_server/dispatch_mode_1.phpt" role="test" /> + <file name="swoole_server/dispatch_mode_3.phpt" role="test" /> + <file name="swoole_server/eof_protocol.phpt" role="test" /> + <file name="swoole_server/eof_server.phpt" role="test" /> + <file name="swoole_server/exist.phpt" role="test" /> + <file name="swoole_server/getClientInfo.phpt" role="test" /> + <file name="swoole_server/getClientList.phpt" role="test" /> + <file name="swoole_server/getLastError.phpt" role="test" /> + <file name="swoole_server/getSocket.phpt" role="test" /> + <file name="swoole_server/heartbeat.phpt" role="test" /> + <file name="swoole_server/heartbeat_true.phpt" role="test" /> + <file name="swoole_server/heartbeat_with_base.phpt" role="test" /> + <file name="swoole_server/kill_task_worker_01.phpt" role="test" /> + <file name="swoole_server/kill_task_worker_02.phpt" role="test" /> + <file name="swoole_server/kill_worker_01.phpt" role="test" /> + <file name="swoole_server/kill_worker_02.phpt" role="test" /> + <file name="swoole_server/length_protocol.phpt" role="test" /> + <file name="swoole_server/listen_fail.phpt" role="test" /> + <file name="swoole_server/max_request.phpt" role="test" /> + <file name="swoole_server/pid_file.phpt" role="test" /> + <file name="swoole_server/protect.phpt" role="test" /> + <file name="swoole_server/protect_false.phpt" role="test" /> + <file name="swoole_server/reload.phpt" role="test" /> + <file name="swoole_server/request_slowlog.phpt" role="test" /> + <file name="swoole_server/sendMessage.phpt" role="test" /> + <file name="swoole_server/sendMessage_02.phpt" role="test" /> + <file name="swoole_server/sendfile.phpt" role="test" /> + <file name="swoole_server/sendfile_02.phpt" role="test" /> + <file name="swoole_server/sendfile_ssl.phpt" role="test" /> + <file name="swoole_server/shutdown.phpt" role="test" /> + <file name="swoole_server/slow_client.phpt" role="test" /> + <file name="swoole_server/stats.phpt" role="test" /> + <file name="swoole_server/stop.phpt" role="test" /> + <file name="swoole_server/task.phpt" role="test" /> + <file name="swoole_server/taskWaitMulti.phpt" role="test" /> + <file name="swoole_server/task_callback.phpt" role="test" /> + <file name="swoole_server/task_max_request.phpt" role="test" /> + <file name="swoole_server/task_queue.phpt" role="test" /> + <file name="swoole_server/taskwait.phpt" role="test" /> + <file name="swoole_server/unsock_dgram.phpt" role="test" /> + <file name="swoole_server/unsock_stream.phpt" role="test" /> + <file name="swoole_server/use_process.phpt" role="test" /> + <file name="swoole_server_port/swoole_server_port.phpt" role="test" /> + <file name="swoole_server_port/tcp_eof.phpt" role="test" /> + <file name="swoole_socket_coro/accept.phpt" role="test" /> + <file name="swoole_socket_coro/complete_test.phpt" role="test" /> + <file name="swoole_socket_coro/recv_timeout.phpt" role="test" /> + <file name="swoole_socket_coro/sendto.phpt" role="test" /> + <file name="swoole_table/foreach.phpt" role="test" /> + <file name="swoole_table/int.phpt" role="test" /> + <file name="swoole_table/key_value.phpt" role="test" /> + <file name="swoole_timer/enable_coroutine.phpt" role="test" /> + <file name="swoole_timer/greater_than_0.phpt" role="test" /> + <file name="swoole_timer/parameters_is_too_big.phpt" role="test" /> + <file name="swoole_timer/swoole_timer_after.phpt" role="test" /> + <file name="swoole_timer/task_worker.phpt" role="test" /> + <file name="swoole_websocket_server/test_send_large_request_data.phpt" role="test" /> + <file name="swoole_websocket_server/test_send_small_request_data.phpt" role="test" /> + <file name="swoole_websocket_server/websocket_message.phpt" role="test" /> + <file name="swoole_websocket_server/websocket_pingpong.phpt" role="test" /> + <file name="swoole_websocket_server/websocket_push.phpt" role="test" /> + <file name="template.phpt" role="test" /> + <file name="test-all-version.sh" role="test" /> + <file name="test.sql" role="test" /> + </dir> + </dir> + </contents> + <dependencies> + <required> + <php> + <min>7.0.0</min> + </php> + <pearinstaller> + <min>1.4.0</min> + </pearinstaller> + </required> + </dependencies> + <providesextension>swoole</providesextension> + <extsrcrelease> + <configureoption default="no" name="enable-swoole-debug" prompt="enable debug/trace log support?" /> + <configureoption default="no" name="enable-sockets" prompt="enable sockets supports?" /> + <configureoption default="no" name="enable-openssl" prompt="enable openssl support?" /> + <configureoption default="no" name="enable-http2" prompt="enable http2 support?" /> + <configureoption default="no" name="enable-async-redis" prompt="enable async-redis support?" /> + <configureoption default="no" name="enable-mysqlnd" prompt="enable mysqlnd support?" /> + <configureoption default="no" name="enable-coroutine-postgresql" prompt="enable postgresql coroutine client support?" /> + </extsrcrelease> +</package> diff --git a/vendor/swoole/php7_wrapper.h b/vendor/swoole/php7_wrapper.h new file mode 100755 index 0000000..6279585 --- /dev/null +++ b/vendor/swoole/php7_wrapper.h @@ -0,0 +1,479 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef EXT_SWOOLE_PHP7_WRAPPER_H_ +#define EXT_SWOOLE_PHP7_WRAPPER_H_ + +#include "ext/standard/php_http.h" + +#if PHP_MAJOR_VERSION < 7 +typedef zend_rsrc_list_entry zend_resource; +#define SW_RETURN_STRING RETURN_STRING +#define SW_Z_ARRVAL_P Z_ARRVAL_P +#define IS_TRUE 1 + +static inline int sw_zend_hash_find(HashTable *ht, char *k, int len, void **v) +{ + zval **tmp = NULL; + if (zend_hash_find(ht, k, len, (void **) &tmp) == SUCCESS) + { + *v = *tmp; + return SUCCESS; + } + else + { + *v = NULL; + return FAILURE; + } +} + +#define sw_zend_hash_del zend_hash_del +#define sw_zend_hash_update zend_hash_update +#define sw_zend_hash_index_find zend_hash_index_find +#define SW_ZVAL_STRINGL ZVAL_STRINGL +#define SW_ZEND_FETCH_RESOURCE_NO_RETURN ZEND_FETCH_RESOURCE_NO_RETURN +#define SW_ZEND_FETCH_RESOURCE ZEND_FETCH_RESOURCE +#define SW_ZEND_REGISTER_RESOURCE ZEND_REGISTER_RESOURCE +#define SW_MAKE_STD_ZVAL(p) MAKE_STD_ZVAL(p) +#define SW_ALLOC_INIT_ZVAL(p) ALLOC_INIT_ZVAL(p) +#define SW_SEPARATE_ZVAL(p) +#define SW_ZVAL_STRING ZVAL_STRING +#define SW_RETVAL_STRINGL RETVAL_STRINGL +#define sw_smart_str smart_str +#define sw_php_var_unserialize php_var_unserialize +#define sw_zend_is_callable zend_is_callable +#define sw_zend_is_callable_ex zend_is_callable_ex +#define sw_zend_hash_add zend_hash_add +#define sw_zend_hash_index_update zend_hash_index_update +#define sw_call_user_function_ex call_user_function_ex +#define sw_zend_register_class_alias zend_register_class_alias + +static sw_inline int sw_call_user_function_fast(zval *function_name, zend_fcall_info_cache *fci_cache, zval **retval_ptr_ptr, uint32_t param_count, zval ***params TSRMLS_DC) +{ + zend_fcall_info fci; + + fci.size = sizeof(fci); + fci.function_table = EG(function_table); + fci.object_ptr = NULL; + fci.function_name = function_name; + fci.retval_ptr_ptr = retval_ptr_ptr; + fci.param_count = param_count; + fci.params = params; + fci.no_separation = 0; + fci.symbol_table = NULL; + + return zend_call_function(&fci, fci_cache TSRMLS_CC); +} + +#define sw_copy_to_stack(a, b) +#define SWOOLE_GET_TSRMLS TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL) + +//----------------------------------Array API------------------------------------ +#define sw_add_assoc_string add_assoc_string +#define sw_add_assoc_stringl_ex add_assoc_stringl_ex +#define sw_add_assoc_stringl add_assoc_stringl +#define sw_add_assoc_double_ex add_assoc_double_ex +#define sw_add_assoc_long_ex add_assoc_long_ex +#define sw_add_next_index_stringl add_next_index_stringl + +#define sw_zval_ptr_dtor zval_ptr_dtor +#define sw_zend_hash_copy zend_hash_copy +#define sw_zval_add_ref zval_add_ref +#define sw_zval_dup(val) (val) +#define sw_zval_free(val) (sw_zval_ptr_dtor(&val)) +#define sw_zend_hash_exists zend_hash_exists +#define sw_php_format_date php_format_date +#define sw_php_url_encode php_url_encode +#define sw_php_array_merge(dest,src) php_array_merge(dest,src,0 TSRMLS_CC) +#define SW_RETURN_STRINGL RETURN_STRINGL +#define SW_RETVAL_STRING RETVAL_STRING +#define sw_zend_register_internal_class_ex zend_register_internal_class_ex + +#define sw_zend_call_method_with_0_params zend_call_method_with_0_params +#define sw_zend_call_method_with_1_params zend_call_method_with_1_params +#define sw_zend_call_method_with_2_params zend_call_method_with_2_params + +typedef int zend_size_t; + +#define SW_HASHTABLE_FOREACH_START(ht, entry)\ + zval **tmp = NULL;\ + for (zend_hash_internal_pointer_reset(ht);\ + zend_hash_has_more_elements(ht) == SUCCESS; \ + zend_hash_move_forward(ht)) {\ + if (zend_hash_get_current_data(ht, (void**)&tmp) == FAILURE) {\ + continue;\ + }\ + entry = *tmp; + +#if defined(HASH_KEY_NON_EXISTANT) && !defined(HASH_KEY_NON_EXISTENT) +#define HASH_KEY_NON_EXISTENT HASH_KEY_NON_EXISTANT +#endif + +#define SW_HASHTABLE_FOREACH_START2(ht, k, klen, ktype, entry)\ + zval **tmp = NULL; ulong_t idx;\ + for (zend_hash_internal_pointer_reset(ht); \ + (ktype = zend_hash_get_current_key_ex(ht, &k, &klen, &idx, 0, NULL)) != HASH_KEY_NON_EXISTENT; \ + zend_hash_move_forward(ht)\ + ) { \ + if (zend_hash_get_current_data(ht, (void**)&tmp) == FAILURE) {\ + continue;\ + }\ + entry = *tmp;\ + klen --; + +#define SW_HASHTABLE_FOREACH_END() } +#define sw_zend_read_property zend_read_property +#define sw_zend_hash_get_current_key(a,b,c,d) zend_hash_get_current_key_ex(a,b,c,d,0,NULL) + +static inline int SW_Z_TYPE_P(zval *z) +{ + if (Z_TYPE_P(z) == IS_BOOL) + { + if ((uint8_t) Z_BVAL_P(z) == 1) + { + return IS_TRUE; + } + else + { + return 0; + } + } + else + { + return Z_TYPE_P(z); + } +} + +#define sw_php_var_serialize(a,b,c) php_var_serialize(a,&b,c) +#define sw_zend_get_executed_filename() zend_get_executed_filename(TSRMLS_C) +#define IS_TRUE 1 +inline int SW_Z_TYPE_P(zval *z); +#define SW_Z_TYPE_PP(z) SW_Z_TYPE_P(*z) +static sw_inline char* sw_http_build_query(zval *data, zend_size_t *length, smart_str *formstr TSRMLS_DC) +{ +#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 3 + if (php_url_encode_hash_ex(HASH_OF(data), formstr, NULL, 0, NULL, 0, NULL, 0, NULL, NULL TSRMLS_CC) == FAILURE) +#else + if (php_url_encode_hash_ex(HASH_OF(data), formstr, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, (int) PHP_QUERY_RFC1738 TSRMLS_CC) == FAILURE) +#endif + { + if (formstr->c) + { + smart_str_free(formstr); + } + return NULL; + } + if (!formstr->c) + { + return NULL; + } + smart_str_0(formstr); + *length = formstr->len; + return formstr->c; +} + +#define sw_get_object_handle(object) Z_OBJ_HANDLE_P(object) + +#else /* PHP Version 7 */ +#define sw_php_var_serialize php_var_serialize +typedef size_t zend_size_t; +#define ZEND_SET_SYMBOL(ht,str,arr) zval_add_ref(arr); zend_hash_str_update(ht, str, sizeof(str)-1, arr); + +static sw_inline int Z_BVAL_P(zval *v) +{ + if (Z_TYPE_P(v) == IS_TRUE) + { + return 1; + } + else + { + return 0; + } +} + +//----------------------------------Array API------------------------------------ +#define sw_add_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_assoc_stringl_ex(__arg, __key, strlen(__key), __str, __length) +static sw_inline int sw_add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, char *str, size_t length, int __duplicate) +{ + return add_assoc_stringl_ex(arg, key, key_len - 1, str, length); +} + +#define sw_add_next_index_stringl(arr, str, len, dup) add_next_index_stringl(arr, str, len) + +static sw_inline int sw_add_assoc_long_ex(zval *arg, const char *key, size_t key_len, long value) +{ + return add_assoc_long_ex(arg, key, key_len - 1, value); +} + +static sw_inline int sw_add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double value) +{ + return add_assoc_double_ex(arg, key, key_len - 1, value); +} + +#define SW_Z_ARRVAL_P(z) Z_ARRVAL_P(z)->ht + +#define SW_HASHTABLE_FOREACH_START(ht, _val) ZEND_HASH_FOREACH_VAL(ht, _val); { +#define SW_HASHTABLE_FOREACH_START2(ht, k, klen, ktype, _val) zend_string *_foreach_key;\ + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _foreach_key, _val);\ + if (!_foreach_key) {k = NULL; klen = 0; ktype = 0;}\ + else {k = _foreach_key->val, klen=_foreach_key->len; ktype = 1;} { + +#define SW_HASHTABLE_FOREACH_END() } ZEND_HASH_FOREACH_END(); + +#define Z_ARRVAL_PP(s) Z_ARRVAL_P(*s) +#define SW_Z_TYPE_P Z_TYPE_P +#define SW_Z_TYPE_PP(s) SW_Z_TYPE_P(*s) +#define Z_STRVAL_PP(s) Z_STRVAL_P(*s) +#define Z_STRLEN_PP(s) Z_STRLEN_P(*s) +#define Z_LVAL_PP(v) Z_LVAL_P(*v) + +static inline char* sw_php_format_date(char *format, size_t format_len, time_t ts, int localtime) +{ + zend_string *time = php_format_date(format, format_len, ts, localtime); + char *return_str = estrndup(time->val, time->len); + zend_string_release(time); + return return_str; +} + +static sw_inline char* sw_php_url_encode(char *value, size_t value_len, int* exten) +{ + zend_string *str = php_url_encode(value, value_len); + *exten = str->len; + char *return_str = estrndup(str->val, str->len); + zend_string_release(str); + return return_str; +} + +#define sw_zval_add_ref(p) Z_TRY_ADDREF_P(*p) +#define sw_zval_ptr_dtor(p) zval_ptr_dtor(*p) + +#define SW_PHP_MAX_PARAMS_NUM 20 + +static sw_inline int sw_call_user_function_ex(HashTable *function_table, zval** object_pp, zval *function_name, zval **retval_ptr_ptr, uint32_t param_count, zval ***params, int no_separation, HashTable* ymbol_table) +{ + zval real_params[SW_PHP_MAX_PARAMS_NUM]; + int i = 0; + for (; i < param_count; i++) + { + real_params[i] = **params[i]; + } + zval phpng_retval; + *retval_ptr_ptr = &phpng_retval; + zval *object_p = (object_pp == NULL) ? NULL : *object_pp; + return call_user_function_ex(function_table, object_p, function_name, &phpng_retval, param_count, real_params, no_separation, NULL); +} + + +static sw_inline int sw_call_user_function_fast(zval *function_name, zend_fcall_info_cache *fci_cache, zval **retval_ptr_ptr, uint32_t param_count, zval ***params) +{ + zval real_params[SW_PHP_MAX_PARAMS_NUM]; + int i = 0; + for (; i < param_count; i++) + { + real_params[i] = **params[i]; + } + + zval phpng_retval; + *retval_ptr_ptr = &phpng_retval; + + zend_fcall_info fci; + fci.size = sizeof(fci); +#if PHP_MINOR_VERSION == 0 + fci.function_table = EG(function_table); + fci.symbol_table = NULL; +#endif + fci.object = NULL; + ZVAL_COPY_VALUE(&fci.function_name, function_name); + fci.retval = &phpng_retval; + fci.param_count = param_count; + fci.params = real_params; + fci.no_separation = 0; + + return zend_call_function(&fci, fci_cache); +} + +#define sw_php_var_unserialize(rval, p, max, var_hash) php_var_unserialize(*rval, p, max, var_hash) +#define SW_MAKE_STD_ZVAL(p) zval _stack_zval_##p; p = &(_stack_zval_##p) +#define SW_ALLOC_INIT_ZVAL(p) do{p = (zval *)emalloc(sizeof(zval)); bzero(p, sizeof(zval));}while(0) +#define SW_SEPARATE_ZVAL(p) zval _##p;\ + memcpy(&_##p, p, sizeof(_##p));\ + p = &_##p +#define SW_RETURN_STRINGL(s, l, dup) do{RETVAL_STRINGL(s, l); if (dup == 0) efree(s);}while(0);return +#define SW_RETVAL_STRINGL(s, l, dup) do{RETVAL_STRINGL(s, l); if (dup == 0) efree(s);}while(0) +#define SW_RETVAL_STRING(s, dup) do{RETVAL_STRING(s); if (dup == 0) efree(s);}while(0) + +#define SW_ZEND_FETCH_RESOURCE_NO_RETURN(rsrc, rsrc_type, passed_id, default_id, resource_type_name, resource_type) \ + (rsrc = (rsrc_type) zend_fetch_resource(Z_RES_P(*passed_id), resource_type_name, resource_type)) +#define SW_ZEND_REGISTER_RESOURCE(return_value, result, le_result) ZVAL_RES(return_value,zend_register_resource(result, le_result)) + +#define SW_RETURN_STRING(val, duplicate) RETURN_STRING(val) +#define sw_add_assoc_string(array, key, value, duplicate) add_assoc_string(array, key, value) +#define sw_zend_hash_copy(target,source,pCopyConstructor,tmp,size) zend_hash_copy(target,source,pCopyConstructor) +#define sw_php_array_merge php_array_merge +#define sw_zend_register_internal_class_ex(entry,parent_ptr,str) zend_register_internal_class_ex(entry,parent_ptr) +#define sw_zend_get_executed_filename() zend_get_executed_filename() + +#define sw_zend_call_method_with_0_params(obj, ptr, what, method, retval) \ + zval __retval;\ + zend_call_method_with_0_params(*obj, ptr, what, method, &__retval);\ + if (ZVAL_IS_NULL(&__retval)) *(retval) = NULL;\ + else *(retval) = &__retval; + +#define sw_zend_call_method_with_1_params(obj, ptr, what, method, retval, v1) \ + zval __retval;\ + zend_call_method_with_1_params(*obj, ptr, what, method, &__retval, v1);\ + if (ZVAL_IS_NULL(&__retval)) *(retval) = NULL;\ + else *(retval) = &__retval; + +#define sw_zend_call_method_with_2_params(obj, ptr, what, method, retval, v1, v2) \ + zval __retval;\ + zend_call_method_with_2_params(*obj, ptr, what, method, &__retval, v1, v2);\ + if (ZVAL_IS_NULL(&__retval)) *(retval) = NULL;\ + else *(retval) = &__retval; + +#define SWOOLE_GET_TSRMLS +#define SW_ZVAL_STRINGL(z, s, l, dup) ZVAL_STRINGL(z, s, l) +#define SW_ZVAL_STRING(z,s,dup) ZVAL_STRING(z,s) +#define sw_smart_str smart_string +#define zend_get_class_entry Z_OBJCE_P +#define sw_copy_to_stack(a, b) {zval *__tmp = (zval *) a;\ + a = &b;\ + memcpy(a, __tmp, sizeof(zval));} + +static sw_inline zval* sw_zval_dup(zval *val) +{ + zval *dup; + SW_ALLOC_INIT_ZVAL(dup); + memcpy(dup, val, sizeof(zval)); + return dup; +} + +static sw_inline void sw_zval_free(zval *val) +{ + sw_zval_ptr_dtor(&val); + efree(val); +} + +static sw_inline zval* sw_zend_read_property(zend_class_entry *class_ptr, zval *obj, const char *s, int len, int silent) +{ + zval rv; + return zend_read_property(class_ptr, obj, s, len, silent, &rv); +} + +static sw_inline int sw_zend_is_callable(zval *cb, int a, char **name) +{ + zend_string *key = NULL; + int ret = zend_is_callable(cb, a, &key); + char *tmp = estrndup(key->val, key->len); + zend_string_release(key); + *name = tmp; + return ret; +} + +static inline int sw_zend_is_callable_ex(zval *callable, zval *object, uint check_flags, char **callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char **error TSRMLS_DC) +{ + zend_string *key = NULL; + int ret = zend_is_callable_ex(callable, NULL, check_flags, &key, fcc, error); + char *tmp = estrndup(key->val, key->len); + zend_string_release(key); + *callable_name = tmp; + return ret; +} + +static inline int sw_zend_hash_del(HashTable *ht, char *k, int len) +{ + return zend_hash_str_del(ht, k, len - 1); +} + +static inline int sw_zend_hash_add(HashTable *ht, char *k, int len, void *pData, int datasize, void **pDest) +{ + zval **real_p = (zval **)pData; + return zend_hash_str_add(ht, k, len - 1, *real_p) ? SUCCESS : FAILURE; +} + +static inline int sw_zend_hash_index_update(HashTable *ht, int key, void *pData, int datasize, void **pDest) +{ + zval **real_p = (zval **)pData; + return zend_hash_index_update(ht, key, *real_p) ? SUCCESS : FAILURE; +} + +static inline int sw_zend_hash_update(HashTable *ht, char *k, int len, zval *val, int size, void *ptr) +{ + return zend_hash_str_update(ht, (const char*)k, len -1, val) ? SUCCESS : FAILURE; +} + +static inline int sw_zend_hash_find(HashTable *ht, const char *k, int len, void **v) +{ + zval *value = zend_hash_str_find(ht, k, len - 1); + if (value == NULL) + { + return FAILURE; + } + else + { + *v = (void *) value; + return SUCCESS; + } +} + +static inline int sw_zend_register_class_alias(const char *name, zend_class_entry *ce) +{ + int name_len = strlen(name); + zend_string *_name; + if (name[0] == '\\') + { + _name = zend_string_init(name, name_len, 1); + zend_str_tolower_copy(ZSTR_VAL(_name), name + 1, name_len - 1); + } + else + { + _name = zend_string_init(name, strlen(name), 1); + zend_str_tolower_copy(ZSTR_VAL(_name), name, name_len); + } + + zend_string *_interned_name = zend_new_interned_string(_name); + +#if PHP_MINOR_VERSION > 2 + return zend_register_class_alias_ex(_interned_name->val, _interned_name->len, ce, 1); +#else + return zend_register_class_alias_ex(_interned_name->val, _interned_name->len, ce); +#endif +} + +static sw_inline char* sw_http_build_query(zval *data, zend_size_t *length, smart_str *formstr TSRMLS_DC) +{ + if (php_url_encode_hash_ex(HASH_OF(data), formstr, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, (int) PHP_QUERY_RFC1738) == FAILURE) + { + if (formstr->s) + { + smart_str_free(formstr); + } + return NULL; + } + if (!formstr->s) + { + return NULL; + } + smart_str_0(formstr); + *length = formstr->s->len; + return formstr->s->val; +} + +#define sw_get_object_handle(object) Z_OBJ_HANDLE(*object) + +#endif /* PHP Version */ + +#endif /* EXT_SWOOLE_PHP7_WRAPPER_H_ */ diff --git a/vendor/swoole/php_swoole.h b/vendor/swoole/php_swoole.h new file mode 100755 index 0000000..971534c --- /dev/null +++ b/vendor/swoole/php_swoole.h @@ -0,0 +1,652 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_SWOOLE_H +#define PHP_SWOOLE_H + +#include "php.h" +#include "php_ini.h" +#include "php_globals.h" +#include "php_main.h" + +#include "php_streams.h" +#include "php_network.h" + +#include "zend_interfaces.h" +#include "zend_exceptions.h" +#include "zend_variables.h" +#include <ext/date/php_date.h> +#include <ext/standard/url.h> +#include <ext/standard/info.h> +#include <ext/standard/php_array.h> +#include <ext/standard/basic_functions.h> +#include <ext/standard/php_http.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SW_STATIC_COMPILATION +#include "php_config.h" +#endif + +#include "swoole.h" +#include "Server.h" +#include "Client.h" +#include "async.h" + +BEGIN_EXTERN_C() + +#define PHP_SWOOLE_VERSION "4.0.1" +#define PHP_SWOOLE_CHECK_CALLBACK +#define PHP_SWOOLE_ENABLE_FASTCALL +#define PHP_SWOOLE_CLIENT_USE_POLL + +#ifndef ZEND_MOD_END +#define ZEND_MOD_END {NULL,NULL,NULL} +#endif + +#define SW_HOST_SIZE 128 + +typedef struct +{ + uint16_t port; + uint16_t from_fd; +} php_swoole_udp_t; + +extern zend_module_entry swoole_module_entry; + +#define phpext_swoole_ptr &swoole_module_entry + +#ifdef PHP_WIN32 +# define PHP_SWOOLE_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_SWOOLE_API __attribute__ ((visibility("default"))) +#else +# define PHP_SWOOLE_API +#endif + +#define SWOOLE_PROPERTY_MAX 32 +#define SWOOLE_OBJECT_MAX 10000000 + +typedef struct +{ + void **array; + uint32_t size; + void **property[SWOOLE_PROPERTY_MAX]; + uint32_t property_size[SWOOLE_PROPERTY_MAX]; +} swoole_object_array; + +#ifdef ZTS +#include "TSRM.h" +extern void ***sw_thread_ctx; +extern __thread swoole_object_array swoole_objects; +#else +extern swoole_object_array swoole_objects; +#endif + +//#define SW_USE_PHP 1 +#define SW_CHECK_RETURN(s) if(s<0){RETURN_FALSE;}else{RETURN_TRUE;}return +#define SW_LOCK_CHECK_RETURN(s) if(s==0){RETURN_TRUE;}else{\ + zend_update_property_long(NULL, getThis(), SW_STRL("errCode")-1, s TSRMLS_CC);\ + RETURN_FALSE;}return + +#define swoole_php_error(level, fmt_str, ...) if (SWOOLE_G(display_errors)) php_error_docref(NULL TSRMLS_CC, level, fmt_str, ##__VA_ARGS__) +#define swoole_php_fatal_error(level, fmt_str, ...) php_error_docref(NULL TSRMLS_CC, level, fmt_str, ##__VA_ARGS__) +#define swoole_php_sys_error(level, fmt_str, ...) if (SWOOLE_G(display_errors)) php_error_docref(NULL TSRMLS_CC, level, fmt_str" Error: %s[%d].", ##__VA_ARGS__, strerror(errno), errno) +#define swoole_efree(p) if (p) efree(p) + +#if defined(SW_ASYNC_MYSQL) +#if defined(SW_HAVE_MYSQLI) && defined(SW_HAVE_MYSQLND) +#else +#error "Enable async_mysql support, require mysqli and mysqlnd." +#undef SW_ASYNC_MYSQL +#endif +#endif + +#ifdef SW_USE_OPENSSL +#ifndef HAVE_OPENSSL +#error "Enable openssl support, require openssl library." +#endif +#endif + +#ifdef SW_SOCKETS +#include "ext/sockets/php_sockets.h" +#define SWOOLE_SOCKETS_SUPPORT +#endif + +#ifdef SW_USE_HTTP2 +#if !defined(HAVE_NGHTTP2) +#error "Enable http2 support, require nghttp2 library." +#endif +#endif + +#if PHP_MAJOR_VERSION < 7 +#error "require PHP version 7.0 or later." +#endif + +#include "php7_wrapper.h" + +#define PHP_CLIENT_CALLBACK_NUM 4 +//-------------------------------------------------------- +#define SW_MAX_FIND_COUNT 100 //for swoole_server::connection_list +#define SW_PHP_CLIENT_BUFFER_SIZE 65535 +//-------------------------------------------------------- +enum php_swoole_client_callback_type +{ + SW_CLIENT_CB_onConnect = 1, + SW_CLIENT_CB_onReceive, + SW_CLIENT_CB_onClose, + SW_CLIENT_CB_onError, + SW_CLIENT_CB_onBufferFull, + SW_CLIENT_CB_onBufferEmpty, +#ifdef SW_USE_OPENSSL + SW_CLIENT_CB_onSSLReady, +#endif +}; +//-------------------------------------------------------- +enum php_swoole_server_callback_type +{ + //--------------------------Swoole\Server-------------------------- + SW_SERVER_CB_onConnect, //worker(event) + SW_SERVER_CB_onReceive, //worker(event) + SW_SERVER_CB_onClose, //worker(event) + SW_SERVER_CB_onPacket, //worker(event) + SW_SERVER_CB_onStart, //master + SW_SERVER_CB_onShutdown, //master + SW_SERVER_CB_onWorkerStart, //worker(event & task) + SW_SERVER_CB_onWorkerStop, //worker(event & task) + SW_SERVER_CB_onTask, //worker(task) + SW_SERVER_CB_onFinish, //worker(event & task) + SW_SERVER_CB_onWorkerExit, //worker(event) + SW_SERVER_CB_onWorkerError, //manager + SW_SERVER_CB_onManagerStart, //manager + SW_SERVER_CB_onManagerStop, //manager + SW_SERVER_CB_onPipeMessage, //worker(evnet & task) + //--------------------------Swoole\Http\Server---------------------- + SW_SERVER_CB_onRequest, //http server + //--------------------------Swoole\WebSocket\Server----------------- + SW_SERVER_CB_onHandShake, //worker(event) + SW_SERVER_CB_onOpen, //worker(event) + SW_SERVER_CB_onMessage, //worker(event) + //--------------------------Buffer Event---------------------------- + SW_SERVER_CB_onBufferFull, //worker(event) + SW_SERVER_CB_onBufferEmpty, //worker(event) + //-------------------------------END-------------------------------- +}; + +#define PHP_SERVER_CALLBACK_NUM (SW_SERVER_CB_onBufferEmpty+1) + +typedef struct +{ + zval *callbacks[PHP_SERVER_CALLBACK_NUM]; + zend_fcall_info_cache *caches[PHP_SERVER_CALLBACK_NUM]; +#if PHP_MAJOR_VERSION >= 7 + zval _callbacks[PHP_SERVER_CALLBACK_NUM]; +#endif + zval *setting; + swServer *serv; +} swoole_server_port_property; +//--------------------------------------------------------- +#define SW_FLAG_KEEP (1u << 12) +#define SW_FLAG_ASYNC (1u << 10) +#define SW_FLAG_SYNC (1u << 11) +//--------------------------------------------------------- +enum php_swoole_fd_type +{ + PHP_SWOOLE_FD_STREAM_CLIENT = SW_FD_STREAM_CLIENT, + PHP_SWOOLE_FD_DGRAM_CLIENT = SW_FD_DGRAM_CLIENT, + PHP_SWOOLE_FD_MYSQL, + PHP_SWOOLE_FD_REDIS, + PHP_SWOOLE_FD_HTTPCLIENT, + PHP_SWOOLE_FD_PROCESS_STREAM, +#ifdef SW_COROUTINE + PHP_SWOOLE_FD_MYSQL_CORO, + PHP_SWOOLE_FD_REDIS_CORO, + PHP_SWOOLE_FD_POSTGRESQL, + PHP_SWOOLE_FD_SOCKET, + PHP_SWOOLE_FD_CHAN_PIPE, +#endif +}; +//--------------------------------------------------------- +typedef enum +{ + PHP_SWOOLE_RINIT_BEGIN, + PHP_SWOOLE_RINIT_END, + PHP_SWOOLE_CALL_USER_SHUTDOWNFUNC_BEGIN, + PHP_SWOOLE_RSHUTDOWN_BEGIN, + PHP_SWOOLE_RSHUTDOWN_END, +} php_swoole_req_status; +//--------------------------------------------------------- +#define php_swoole_socktype(type) (type & (~SW_FLAG_SYNC) & (~SW_FLAG_ASYNC) & (~SW_FLAG_KEEP) & (~SW_SOCK_SSL)) +#define php_swoole_array_length(array) zend_hash_num_elements(Z_ARRVAL_P(array)) + +#define SW_LONG_CONNECTION_KEY_LEN 64 + +extern zend_class_entry *swoole_process_class_entry_ptr; +extern zend_class_entry *swoole_client_class_entry_ptr; +extern zend_class_entry *swoole_server_class_entry_ptr; +extern zend_class_entry *swoole_connection_iterator_class_entry_ptr; +extern zend_class_entry *swoole_buffer_class_entry_ptr; +extern zend_class_entry *swoole_http_server_class_entry_ptr; +extern zend_class_entry *swoole_server_port_class_entry_ptr; +extern zend_class_entry *swoole_exception_class_entry_ptr; + +extern zval *php_sw_server_callbacks[PHP_SERVER_CALLBACK_NUM]; +extern zend_fcall_info_cache *php_sw_server_caches[PHP_SERVER_CALLBACK_NUM]; +#if PHP_MAJOR_VERSION >= 7 +extern zval _php_sw_server_callbacks[PHP_SERVER_CALLBACK_NUM]; +#endif + +PHP_MINIT_FUNCTION(swoole); +PHP_MSHUTDOWN_FUNCTION(swoole); +PHP_RINIT_FUNCTION(swoole); +PHP_RSHUTDOWN_FUNCTION(swoole); +PHP_MINFO_FUNCTION(swoole); + +PHP_FUNCTION(swoole_version); +PHP_FUNCTION(swoole_cpu_num); +PHP_FUNCTION(swoole_set_process_name); +PHP_FUNCTION(swoole_get_local_ip); +PHP_FUNCTION(swoole_get_local_mac); +PHP_FUNCTION(swoole_call_user_shutdown_begin); +PHP_FUNCTION(swoole_unsupport_serialize); +PHP_FUNCTION(swoole_coroutine_create); +PHP_FUNCTION(swoole_coroutine_exec); + +//--------------------------------------------------------- +// swoole_server +//--------------------------------------------------------- +PHP_METHOD(swoole_server, __construct); +PHP_METHOD(swoole_server, __destruct); +PHP_METHOD(swoole_server, set); +PHP_METHOD(swoole_server, on); +PHP_METHOD(swoole_server, listen); +PHP_METHOD(swoole_server, sendMessage); +PHP_METHOD(swoole_server, addProcess); +PHP_METHOD(swoole_server, start); +PHP_METHOD(swoole_server, stop); +PHP_METHOD(swoole_server, send); +PHP_METHOD(swoole_server, sendfile); +PHP_METHOD(swoole_server, stats); +PHP_METHOD(swoole_server, bind); +PHP_METHOD(swoole_server, sendto); +PHP_METHOD(swoole_server, sendwait); +PHP_METHOD(swoole_server, exist); +PHP_METHOD(swoole_server, protect); +PHP_METHOD(swoole_server, close); +PHP_METHOD(swoole_server, confirm); +PHP_METHOD(swoole_server, pause); +PHP_METHOD(swoole_server, resume); +PHP_METHOD(swoole_server, task); +PHP_METHOD(swoole_server, taskwait); +PHP_METHOD(swoole_server, taskWaitMulti); +PHP_METHOD(swoole_server, taskCo); +PHP_METHOD(swoole_server, finish); +PHP_METHOD(swoole_server, reload); +PHP_METHOD(swoole_server, shutdown); +PHP_METHOD(swoole_server, getLastError); +PHP_METHOD(swoole_server, heartbeat); +PHP_METHOD(swoole_server, connection_list); +PHP_METHOD(swoole_server, connection_info); +#ifdef SW_BUFFER_RECV_TIME +PHP_METHOD(swoole_server, getReceivedTime); +#endif + +#ifdef HAVE_PCRE +PHP_METHOD(swoole_connection_iterator, count); +PHP_METHOD(swoole_connection_iterator, rewind); +PHP_METHOD(swoole_connection_iterator, next); +PHP_METHOD(swoole_connection_iterator, current); +PHP_METHOD(swoole_connection_iterator, key); +PHP_METHOD(swoole_connection_iterator, valid); +PHP_METHOD(swoole_connection_iterator, offsetExists); +PHP_METHOD(swoole_connection_iterator, offsetGet); +PHP_METHOD(swoole_connection_iterator, offsetSet); +PHP_METHOD(swoole_connection_iterator, offsetUnset); +PHP_METHOD(swoole_connection_iterator, __destruct); +#endif + +#ifdef SWOOLE_SOCKETS_SUPPORT +PHP_METHOD(swoole_server, getSocket); +#endif +//--------------------------------------------------------- +// swoole_event +//--------------------------------------------------------- +PHP_FUNCTION(swoole_event_add); +PHP_FUNCTION(swoole_event_set); +PHP_FUNCTION(swoole_event_del); +PHP_FUNCTION(swoole_event_write); +PHP_FUNCTION(swoole_event_wait); +PHP_FUNCTION(swoole_event_exit); +PHP_FUNCTION(swoole_event_defer); +PHP_FUNCTION(swoole_event_cycle); +PHP_FUNCTION(swoole_event_dispatch); +PHP_FUNCTION(swoole_event_isset); +PHP_FUNCTION(swoole_client_select); +//--------------------------------------------------------- +// swoole_async +//--------------------------------------------------------- +PHP_FUNCTION(swoole_async_read); +PHP_FUNCTION(swoole_async_write); +PHP_FUNCTION(swoole_async_close); +PHP_FUNCTION(swoole_async_readfile); +PHP_FUNCTION(swoole_async_writefile); +PHP_FUNCTION(swoole_async_dns_lookup); +PHP_FUNCTION(swoole_async_dns_lookup_coro); +PHP_FUNCTION(swoole_async_set); +PHP_METHOD(swoole_async, exec); +//--------------------------------------------------------- +// swoole_timer +//--------------------------------------------------------- +PHP_FUNCTION(swoole_timer_after); +PHP_FUNCTION(swoole_timer_tick); +PHP_FUNCTION(swoole_timer_exists); +PHP_FUNCTION(swoole_timer_clear); +//--------------------------------------------------------- +// other +//--------------------------------------------------------- +PHP_FUNCTION(swoole_strerror); +PHP_FUNCTION(swoole_errno); +//--------------------------------------------------------- +// serialize +//--------------------------------------------------------- +PHP_FUNCTION(swoole_serialize); +PHP_FUNCTION(swoole_fast_serialize); +PHP_FUNCTION(swoole_unserialize); + +void swoole_destory_table(zend_resource *rsrc TSRMLS_DC); + +void swoole_server_port_init(int module_number TSRMLS_DC); +void swoole_async_init(int module_number TSRMLS_DC); +void swoole_table_init(int module_number TSRMLS_DC); +#ifdef SW_USE_PHPX +void swoole_runtime_init(int module_number TSRMLS_DC); +#endif +void swoole_lock_init(int module_number TSRMLS_DC); +void swoole_atomic_init(int module_number TSRMLS_DC); +void swoole_client_init(int module_number TSRMLS_DC); +#ifdef SW_COROUTINE +void swoole_socket_coro_init(int module_number TSRMLS_DC); +void swoole_client_coro_init(int module_number TSRMLS_DC); +#ifdef SW_USE_REDIS +void swoole_redis_coro_init(int module_number TSRMLS_DC); +#endif +#ifdef SW_USE_POSTGRESQL +void swoole_postgresql_coro_init (int module_number TSRMLS_DC); +#endif +void swoole_mysql_coro_init(int module_number TSRMLS_DC); +void swoole_http_client_coro_init(int module_number TSRMLS_DC); +void swoole_coroutine_util_init(int module_number TSRMLS_DC); +#endif +void swoole_http_client_init(int module_number TSRMLS_DC); +#ifdef SW_USE_REDIS +void swoole_redis_init(int module_number TSRMLS_DC); +#endif +void swoole_redis_server_init(int module_number TSRMLS_DC); +void swoole_process_init(int module_number TSRMLS_DC); +void swoole_process_pool_init(int module_number TSRMLS_DC); +void swoole_http_server_init(int module_number TSRMLS_DC); +#ifdef SW_USE_HTTP2 +void swoole_http2_client_init(int module_number TSRMLS_DC); +#ifdef SW_COROUTINE +void swoole_http2_client_coro_init(int module_number TSRMLS_DC); +#endif +#endif +void swoole_websocket_init(int module_number TSRMLS_DC); +void swoole_buffer_init(int module_number TSRMLS_DC); +void swoole_mysql_init(int module_number TSRMLS_DC); +void swoole_mmap_init(int module_number TSRMLS_DC); +void swoole_channel_init(int module_number TSRMLS_DC); +void swoole_ringqueue_init(int module_number TSRMLS_DC); +void swoole_msgqueue_init(int module_number TSRMLS_DC); +#ifdef SW_COROUTINE +void swoole_channel_coro_init(int module_number TSRMLS_DC); +#endif +void swoole_serialize_init(int module_number TSRMLS_DC); +void swoole_memory_pool_init(int module_number TSRMLS_DC); + +int php_swoole_process_start(swWorker *process, zval *object TSRMLS_DC); + +void php_swoole_check_reactor(); +void php_swoole_check_aio(); +void php_swoole_at_shutdown(char *function); +void php_swoole_event_init(); +void php_swoole_event_wait(); +void php_swoole_check_timer(int interval); +long php_swoole_add_timer(int ms, zval *callback, zval *param, int persistent TSRMLS_DC); +void php_swoole_clear_all_timer(); +void php_swoole_register_callback(swServer *serv); +void php_swoole_trace_check(void *arg); +void php_swoole_client_free(zval *object, swClient *cli TSRMLS_DC); +swClient* php_swoole_client_new(zval *object, char *host, int host_len, int port); +void php_swoole_client_check_setting(swClient *cli, zval *zset TSRMLS_DC); +#ifdef SW_USE_OPENSSL +void php_swoole_client_check_ssl_setting(swClient *cli, zval *zset TSRMLS_DC); +#endif +void php_swoole_websocket_unpack(swString *data, zval *zframe TSRMLS_DC); +void php_swoole_sha1(const char *str, int _len, unsigned char *digest); +int php_swoole_client_isset_callback(zval *zobject, int type TSRMLS_DC); + +int php_swoole_task_pack(swEventData *task, zval *data TSRMLS_DC); +zval* php_swoole_task_unpack(swEventData *task_result TSRMLS_DC); + +static sw_inline void* swoole_get_object(zval *object) +{ + int handle = sw_get_object_handle(object); + assert(handle < swoole_objects.size); + return swoole_objects.array[handle]; +} + +static sw_inline void* swoole_get_property(zval *object, int property_id) +{ + int handle = sw_get_object_handle(object); + if (handle >= swoole_objects.property_size[property_id]) + { + return NULL; + } + return swoole_objects.property[property_id][handle]; +} + +void swoole_set_object(zval *object, void *ptr); +void swoole_set_property(zval *object, int property_id, void *ptr); +int swoole_convert_to_fd(zval *zsocket TSRMLS_DC); +int swoole_register_rshutdown_function(swCallback func, int push_back); +void swoole_call_rshutdown_function(void *arg); + +#ifdef SWOOLE_SOCKETS_SUPPORT +php_socket *swoole_convert_to_socket(int sock); +#endif + +void php_swoole_server_before_start(swServer *serv, zval *zobject TSRMLS_DC); +void php_swoole_server_send_yield(swServer *serv, int fd, zval *zdata, zval *return_value); +void php_swoole_get_recv_data(zval *zdata, swEventData *req, char *header, uint32_t header_length); +int php_swoole_get_send_data(zval *zdata, char **str TSRMLS_DC); +void php_swoole_onConnect(swServer *, swDataHead *); +int php_swoole_onReceive(swServer *, swEventData *); +int php_swoole_onPacket(swServer *, swEventData *); +void php_swoole_onClose(swServer *, swDataHead *); +void php_swoole_onBufferFull(swServer *, swDataHead *); +void php_swoole_onBufferEmpty(swServer *, swDataHead *); +int php_swoole_length_func(swProtocol *protocol, swConnection *conn, char *data, uint32_t length); +int php_swoole_dispatch_func(swServer *serv, swConnection *conn, swEventData *data); +int php_swoole_client_onPackage(swConnection *conn, char *data, uint32_t length); +void php_swoole_onTimeout(swTimer *timer, swTimer_node *tnode); +void php_swoole_onInterval(swTimer *timer, swTimer_node *tnode); + +#if PHP_MAJOR_VERSION >= 7 +PHPAPI zend_string* php_swoole_serialize(zval *zvalue); +PHPAPI int php_swoole_unserialize(void *buffer, size_t len, zval *return_value, zval *object_args, long flag); +#endif + +#ifdef SW_COROUTINE +int php_coroutine_reactor_can_exit(swReactor *reactor); +#endif + +static sw_inline zval* php_swoole_server_get_callback(swServer *serv, int server_fd, int event_type) +{ + swListenPort *port = (swListenPort *) serv->connection_list[server_fd].object; + if (port == NULL) + { + swWarn("invalid server_fd[%d].", server_fd); + return NULL; + } + swoole_server_port_property *property = (swoole_server_port_property *) port->ptr; + if (!property) + { + return php_sw_server_callbacks[event_type]; + } + zval *callback = property->callbacks[event_type]; + if (!callback) + { + return php_sw_server_callbacks[event_type]; + } + else + { + return callback; + } +} + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL +static sw_inline zend_fcall_info_cache* php_swoole_server_get_cache(swServer *serv, int server_fd, int event_type) +{ + swListenPort *port = (swListenPort *) serv->connection_list[server_fd].object; + swoole_server_port_property *property = (swoole_server_port_property *) port->ptr; + if (!property) + { + return php_sw_server_caches[event_type]; + } + zend_fcall_info_cache* cache = property->caches[event_type]; + if (!cache) + { + return php_sw_server_caches[event_type]; + } + else + { + return cache; + } +} +#endif + +#ifdef SW_USE_OPENSSL +void php_swoole_client_check_ssl_setting(swClient *cli, zval *zset TSRMLS_DC); +#endif + +static sw_inline int php_swoole_is_callable(zval *callback TSRMLS_DC) +{ + if (!callback || ZVAL_IS_NULL(callback)) + { + return SW_FALSE; + } + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + return SW_FALSE; + } + else + { + efree(func_name); + return SW_TRUE; + } +} + +#define php_swoole_array_get_value(ht, str, v) (sw_zend_hash_find(ht, str, sizeof(str), (void **) &v) == SUCCESS && !ZVAL_IS_NULL(v)) +#define php_swoole_array_separate(arr) zval *_new_##arr;\ + SW_MAKE_STD_ZVAL(_new_##arr);\ + array_init(_new_##arr);\ + sw_php_array_merge(Z_ARRVAL_P(_new_##arr), Z_ARRVAL_P(arr));\ + arr = _new_##arr; + +static sw_inline zval* php_swoole_read_init_property(zend_class_entry *scope, zval *object, const char *p, size_t pl TSRMLS_DC) +{ + zval *property = sw_zend_read_property(scope, object, p, pl, 1 TSRMLS_CC); + if (property == NULL || ZVAL_IS_NULL(property)) + { + SW_MAKE_STD_ZVAL(property); + array_init(property); + zend_update_property(scope, object, p, pl, property TSRMLS_CC); + sw_zval_ptr_dtor(&property); + return sw_zend_read_property(scope, object, p, pl, 1 TSRMLS_CC); + } + else + { + return property; + } +} + +ZEND_BEGIN_MODULE_GLOBALS(swoole) + long aio_thread_num; + zend_bool display_errors; + zend_bool cli; + zend_bool use_namespace; + zend_bool use_shortname; + zend_bool fast_serialize; + long socket_buffer_size; + php_swoole_req_status req_status; + swLinkedList *rshutdown_functions; +ZEND_END_MODULE_GLOBALS(swoole) + +extern ZEND_DECLARE_MODULE_GLOBALS(swoole); + +#ifdef ZTS +#define SWOOLE_G(v) TSRMG(swoole_globals_id, zend_swoole_globals *, v) +#else +#define SWOOLE_G(v) (swoole_globals.v) +#endif + +#define SWOOLE_DEFINE(constant) REGISTER_LONG_CONSTANT("SWOOLE_"#constant, SW_##constant, CONST_CS | CONST_PERSISTENT) + +#define SWOOLE_INIT_CLASS_ENTRY(ce, name, name_ns, methods) \ + if (SWOOLE_G(use_namespace)) { \ + INIT_CLASS_ENTRY(ce, name_ns, methods); \ + } else { \ + INIT_CLASS_ENTRY(ce, name, methods); \ + } + +#define SWOOLE_CLASS_ALIAS(name, name_ns) \ + if (SWOOLE_G(use_namespace)) { \ + sw_zend_register_class_alias(#name, name##_class_entry_ptr);\ + } else { \ + sw_zend_register_class_alias(name_ns, name##_class_entry_ptr);\ + } + +/* PHP 7.3 forward compatibility */ +#ifndef GC_SET_REFCOUNT +# define GC_SET_REFCOUNT(p, rc) do { \ + GC_REFCOUNT(p) = rc; \ + } while (0) +#endif + +#ifndef GC_IS_RECURSIVE +# define GC_IS_RECURSIVE(p) \ + (ZEND_HASH_GET_APPLY_COUNT(p) > 1) +# define GC_PROTECT_RECURSION(p) \ + ZEND_HASH_INC_APPLY_COUNT(p) +# define GC_UNPROTECT_RECURSION(p) \ + ZEND_HASH_DEC_APPLY_COUNT(p) +#endif + +#ifndef ZEND_HASH_APPLY_PROTECTION +# define ZEND_HASH_APPLY_PROTECTION(p) 1 +#endif + +END_EXTERN_C() + +#endif /* PHP_SWOOLE_H */ diff --git a/vendor/swoole/src/core/Channel.c b/vendor/swoole/src/core/Channel.c new file mode 100755 index 0000000..64f6069 --- /dev/null +++ b/vendor/swoole/src/core/Channel.c @@ -0,0 +1,249 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#define SW_CHANNEL_MIN_MEM (1024*64) + +typedef struct _swChannel_item +{ + int length; + char data[0]; +} swChannel_item; + +swChannel* swChannel_new(size_t size, int maxlen, int flags) +{ + assert(size >= maxlen); + int ret; + void *mem; + + //use shared memory + if (flags & SW_CHAN_SHM) + { + mem = sw_shm_malloc(size + sizeof(swChannel)); + } + else + { + mem = sw_malloc(size + sizeof(swChannel)); + } + + if (mem == NULL) + { + swWarn("swChannel_create: malloc(%ld) failed.", size); + return NULL; + } + swChannel *object = mem; + mem += sizeof(swChannel); + + bzero(object, sizeof(swChannel)); + + //overflow space + object->size = size; + object->mem = mem; + object->maxlen = maxlen; + object->flag = flags; + + //use lock + if (flags & SW_CHAN_LOCK) + { + //init lock + if (swMutex_create(&object->lock, 1) < 0) + { + swWarn("mutex init failed."); + return NULL; + } + } + //use notify + if (flags & SW_CHAN_NOTIFY) + { + ret = swPipeNotify_auto(&object->notify_fd, 1, 1); + if (ret < 0) + { + swWarn("notify_fd init failed."); + return NULL; + } + } + return object; +} + +/** + * push data(no lock) + */ +int swChannel_in(swChannel *object, void *in, int data_length) +{ + assert(data_length <= object->maxlen); + if (swChannel_full(object)) + { + return SW_ERR; + } + swChannel_item *item; + int msize = sizeof(item->length) + data_length; + + if (object->tail < object->head) + { + //no enough memory space + if ((object->head - object->tail) < msize) + { + return SW_ERR; + } + item = object->mem + object->tail; + object->tail += msize; + } + else + { + item = object->mem + object->tail; + object->tail += msize; + if (object->tail >= object->size) + { + object->tail = 0; + object->tail_tag = 1 - object->tail_tag; + } + } + object->num++; + object->bytes += data_length; + item->length = data_length; + memcpy(item->data, in, data_length); + return SW_OK; +} + +/** + * pop data(no lock) + */ +int swChannel_out(swChannel *object, void *out, int buffer_length) +{ + if (swChannel_empty(object)) + { + return SW_ERR; + } + + swChannel_item *item = object->mem + object->head; + assert(buffer_length >= item->length); + memcpy(out, item->data, item->length); + object->head += (item->length + sizeof(item->length)); + if (object->head >= object->size) + { + object->head = 0; + object->head_tag = 1 - object->head_tag; + } + object->num--; + object->bytes -= item->length; + return item->length; +} + +/** + * peek data + */ +int swChannel_peek(swChannel *object, void *out, int buffer_length) +{ + if (swChannel_empty(object)) + { + return SW_ERR; + } + + int length; + object->lock.lock(&object->lock); + swChannel_item *item = object->mem + object->head; + assert(buffer_length >= item->length); + memcpy(out, item->data, item->length); + length = item->length; + object->lock.unlock(&object->lock); + + return length; +} + +/** + * wait notify + */ +int swChannel_wait(swChannel *object) +{ + assert(object->flag & SW_CHAN_NOTIFY); + uint64_t flag; + return object->notify_fd.read(&object->notify_fd, &flag, sizeof(flag)); +} + +/** + * new data coming, notify to customer + */ +int swChannel_notify(swChannel *object) +{ + assert(object->flag & SW_CHAN_NOTIFY); + uint64_t flag = 1; + return object->notify_fd.write(&object->notify_fd, &flag, sizeof(flag)); +} + +/** + * push data (lock) + */ +int swChannel_push(swChannel *object, void *in, int data_length) +{ + assert(object->flag & SW_CHAN_LOCK); + object->lock.lock(&object->lock); + int ret = swChannel_in(object, in, data_length); + object->lock.unlock(&object->lock); + return ret; +} + +/** + * free channel + */ +void swChannel_free(swChannel *object) +{ + if (object->flag & SW_CHAN_LOCK) + { + object->lock.free(&object->lock); + } + if (object->flag & SW_CHAN_NOTIFY) + { + object->notify_fd.close(&object->notify_fd); + } + if (object->flag & SW_CHAN_SHM) + { + sw_shm_free(object); + } + else + { + sw_free(object); + } +} + +/** + * pop data (lock) + */ +int swChannel_pop(swChannel *object, void *out, int buffer_length) +{ + assert(object->flag & SW_CHAN_LOCK); + object->lock.lock(&object->lock); + int n = swChannel_out(object, out, buffer_length); + object->lock.unlock(&object->lock); + return n; +} + +void swChannel_print(swChannel *chan) +{ + printf("swChannel\n{\n" + " off_t head = %ld;\n" + " off_t tail = %ld;\n" + " size_t size = %ld;\n" + " char head_tag = %d;\n" + " char tail_tag = %d;\n" + " int num = %d;\n" + " size_t bytes = %ld;\n" + " int flag = %d;\n" + " int maxlen = %d;\n" + "\n}\n", (long)chan->head, (long)chan->tail, chan->size, chan->tail_tag, chan->head_tag, chan->num, chan->bytes, + chan->flag, chan->maxlen); +} + diff --git a/vendor/swoole/src/core/RingQueue.c b/vendor/swoole/src/core/RingQueue.c new file mode 100755 index 0000000..917c3a4 --- /dev/null +++ b/vendor/swoole/src/core/RingQueue.c @@ -0,0 +1,151 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ +#include <stdio.h> +#include "swoole.h" +#include "RingQueue.h" + +#ifdef SW_USE_RINGQUEUE_TS + +int swRingQueue_init(swRingQueue *queue, int buffer_size) +{ + queue->size = buffer_size; + queue->flags = (char *)sw_malloc(queue->size); + if (queue->flags == NULL) + { + return -1; + } + queue->data = (void **)sw_calloc(queue->size, sizeof(void*)); + if (queue->data == NULL) + { + sw_free(queue->flags); + return -1; + } + queue->head = 0; + queue->tail = 0; + memset(queue->flags, 0, queue->size); + memset(queue->data, 0, queue->size * sizeof(void*)); + return 0; +} + +int swRingQueue_push(swRingQueue *queue, void * ele) +{ + if (!(queue->num < queue->size)) + { + return -1; + } + int cur_tail_index = queue->tail; + char * cur_tail_flag_index = queue->flags + cur_tail_index; + //TODO Scheld + while (!sw_atomic_cmp_set(cur_tail_flag_index, 0, 1)) + { + cur_tail_index = queue->tail; + cur_tail_flag_index = queue->flags + cur_tail_index; + } + + // 两个入队线程之间的同步 + //TODO 取模操作可以优化 + int update_tail_index = (cur_tail_index + 1) % queue->size; + + // 如果已经被其他的线程更新过,则不需要更新; + // 否则,更新为 (cur_tail_index+1) % size; + sw_atomic_cmp_set(&queue->tail, cur_tail_index, update_tail_index); + + // 申请到可用的存储空间 + *(queue->data + cur_tail_index) = ele; + + sw_atomic_fetch_add(cur_tail_flag_index, 1); + sw_atomic_fetch_add(&queue->num, 1); + return 0; +} + +int swRingQueue_pop(swRingQueue *queue, void **ele) +{ + if (!(queue->num > 0)) + return -1; + int cur_head_index = queue->head; + char * cur_head_flag_index = queue->flags + cur_head_index; + + while (!sw_atomic_cmp_set(cur_head_flag_index, 2, 3)) + { + cur_head_index = queue->head; + cur_head_flag_index = queue->flags + cur_head_index; + } + //TODO 取模操作可以优化 + int update_head_index = (cur_head_index + 1) % queue->size; + sw_atomic_cmp_set(&queue->head, cur_head_index, update_head_index); + *ele = *(queue->data + cur_head_index); + + sw_atomic_fetch_sub(cur_head_flag_index, 3); + sw_atomic_fetch_sub(&queue->num, 1); + return 0; +} +#else + +int swRingQueue_init(swRingQueue *queue, int buffer_size) +{ + queue->data = sw_calloc(buffer_size, sizeof(void*)); + if (queue->data == NULL) + { + swWarn("malloc failed."); + return -1; + } + queue->size = buffer_size; + queue->head = 0; + queue->tail = 0; + queue->tag = 0; + return 0; +} + +void swRingQueue_free(swRingQueue *queue) +{ + sw_free(queue->data); +} + +int swRingQueue_push(swRingQueue *queue, void *push_data) +{ + if (swRingQueue_full(queue)) + { + return SW_ERR; + } + + queue->data[queue->tail] = push_data; + queue->tail = (queue->tail + 1) % queue->size; + + if (queue->tail == queue->head) + { + queue->tag = 1; + } + return SW_OK; +} + +int swRingQueue_pop(swRingQueue *queue, void **pop_data) +{ + if (swRingQueue_empty(queue)) + { + return SW_ERR; + } + + *pop_data = queue->data[queue->head]; + queue->head = (queue->head + 1) % queue->size; + + if (queue->tail == queue->head) + { + queue->tag = 0; + } + return SW_OK; +} + +#endif diff --git a/vendor/swoole/src/core/UnitTest.c b/vendor/swoole/src/core/UnitTest.c new file mode 100755 index 0000000..e287faf --- /dev/null +++ b/vendor/swoole/src/core/UnitTest.c @@ -0,0 +1,92 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "tests.h" +#include "uthash.h" + +typedef struct +{ + swUnitTest_Func func; + char *comment; + int run_times; + char *key; +} swHashTable_unitTest; + +static swHashMap *utmap = NULL; + +void _swUnitTest_setup(swUnitTest_Func func, char *func_name, int run_times, char *comment) +{ + if (!utmap) + { + utmap = swHashMap_new(32, free); + } + swHashTable_unitTest *u; + u = (swHashTable_unitTest *) malloc(sizeof(swHashTable_unitTest)); + u->key = func_name; + u->func = func; + u->run_times = run_times; + u->comment = comment; + swHashMap_add(utmap, func_name, strlen(func_name), u); +} + +int swUnitTest_run(swUnitTest *object) +{ + int max_len = 128; + int argc = object->argc; + char **argv = object->argv; + int ret; + char *key; + + swUnitTest_Func func; + swHashTable_unitTest *tmp; + + int i = 0; + + if (argc < 2) + { + printf("Please enter %s unitTest_name\n", argv[0]); + + while (1) + { + tmp = swHashMap_each(utmap, &key); + if (!tmp) + break; + printf("#%d.\t%s: %s\n", ++i, tmp->key, tmp->comment); + } + return 0; + } + + do + { + tmp = swHashMap_each(utmap, &key); + if (strncmp(argv[1], key, max_len) == 0) + { + func = tmp->func; + printf("running\n"); + ret = func(object); + break; + } + } while (tmp); + + printf("finish\n"); + return ret; +} + +void p_str(void *str) +{ + printf("Str: %s|len=%ld\n", (char *) str, strlen((char *) str)); +} diff --git a/vendor/swoole/src/core/array.c b/vendor/swoole/src/core/array.c new file mode 100755 index 0000000..3492894 --- /dev/null +++ b/vendor/swoole/src/core/array.c @@ -0,0 +1,149 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "array.h" + +/** + * Create new array + */ +swArray *swArray_new(int page_size, size_t item_size) +{ + swArray *array = sw_malloc(sizeof(swArray)); + if (array == NULL) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_MALLOC_FAIL, "malloc[0] failed."); + return NULL; + } + bzero(array, sizeof(swArray)); + + array->pages = sw_malloc(sizeof(void*) * SW_ARRAY_PAGE_MAX); + if (array->pages == NULL) + { + sw_free(array); + swoole_error_log(SW_LOG_ERROR, SW_ERROR_MALLOC_FAIL, "malloc[1] failed."); + return NULL; + } + + array->item_size = item_size; + array->page_size = page_size; + + swArray_extend(array); + + return array; +} + +/** + * Destory the array + */ +void swArray_free(swArray *array) +{ + int i; + for (i = 0; i < array->page_num; i++) + { + sw_free(array->pages[i]); + } + sw_free(array->pages); + sw_free(array); +} + +/** + * Extend the memory pages of the array + */ +int swArray_extend(swArray *array) +{ + if (array->page_num == SW_ARRAY_PAGE_MAX) + { + swWarn("max page_num is %d", array->page_num); + return SW_ERR; + } + array->pages[array->page_num] = sw_calloc(array->page_size, array->item_size); + if (array->pages[array->page_num] == NULL) + { + swWarn("malloc[1] failed."); + return SW_ERR; + } + array->page_num++; + return SW_OK; +} + +/** + * Fetch data by index of the array + */ +void *swArray_fetch(swArray *array, uint32_t n) +{ + int page = swArray_page(array, n); + if (page >= array->page_num) + { + return NULL; + } + return array->pages[page] + (swArray_offset(array, n) * array->item_size); +} + +/** + * Append to the array + */ +int swArray_append(swArray *array, void *data) +{ + int n = array->offset++; + int page = swArray_page(array, n); + + if (page >= array->page_num && swArray_extend(array) < 0) + { + return SW_ERR; + } + array->item_num++; + memcpy(array->pages[page] + (swArray_offset(array, n) * array->item_size), data, array->item_size); + return n; +} + + +int swArray_store(swArray *array, uint32_t n, void *data) +{ + int page = swArray_page(array, n); + if (page >= array->page_num) + { + swWarn("fetch index[%d] out of array", n); + return SW_ERR; + } + memcpy(array->pages[page] + (swArray_offset(array, n) * array->item_size), data, array->item_size); + return SW_OK; +} + +void *swArray_alloc(swArray *array, uint32_t n) +{ + while (n >= array->page_num * array->page_size) + { + if (swArray_extend(array) < 0) + { + return NULL; + } + } + + int page = swArray_page(array, n); + if (page >= array->page_num) + { + swWarn("fetch index[%d] out of array", n); + return NULL; + } + return array->pages[page] + (swArray_offset(array, n) * array->item_size); +} + +void swArray_clear(swArray *array) +{ + array->offset = 0; + array->item_num = 0; +} diff --git a/vendor/swoole/src/core/base.c b/vendor/swoole/src/core/base.c new file mode 100755 index 0000000..d8c3571 --- /dev/null +++ b/vendor/swoole/src/core/base.c @@ -0,0 +1,1255 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "atomic.h" + +#include <stdarg.h> +#include <sys/stat.h> +#include <sys/resource.h> +#include <sys/ioctl.h> +#include <limits.h> + +#ifdef HAVE_EXECINFO +#include <execinfo.h> +#endif + +SwooleGS_t *SwooleGS; + +void swoole_init(void) +{ + struct rlimit rlmt; + if (SwooleG.running) + { + return; + } + + bzero(&SwooleG, sizeof(SwooleG)); + bzero(&SwooleWG, sizeof(SwooleWG)); + bzero(sw_error, SW_ERROR_MSG_SIZE); + + SwooleG.running = 1; + SwooleG.enable_coroutine = 1; + sw_errno = 0; + + SwooleG.log_fd = STDOUT_FILENO; + SwooleG.cpu_num = sysconf(_SC_NPROCESSORS_ONLN); + SwooleG.pagesize = getpagesize(); + SwooleG.pid = getpid(); + SwooleG.socket_buffer_size = SW_SOCKET_BUFFER_SIZE; + +#ifdef SW_DEBUG + SwooleG.log_level = 0; +#else + SwooleG.log_level = SW_LOG_INFO; +#endif + + //get system uname + uname(&SwooleG.uname); + + //random seed + srandom(time(NULL)); + + //init global shared memory + SwooleG.memory_pool = swMemoryGlobal_new(SW_GLOBAL_MEMORY_PAGESIZE, 1); + if (SwooleG.memory_pool == NULL) + { + printf("[Master] Fatal Error: global memory allocation failure."); + exit(1); + } + SwooleGS = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(SwooleGS_t)); + if (SwooleGS == NULL) + { + printf("[Master] Fatal Error: failed to allocate memory for SwooleGS."); + exit(2); + } + + //init global lock + swMutex_create(&SwooleGS->lock, 1); + swMutex_create(&SwooleGS->lock_2, 1); + swMutex_create(&SwooleG.lock, 0); + + if (getrlimit(RLIMIT_NOFILE, &rlmt) < 0) + { + swWarn("getrlimit() failed. Error: %s[%d]", strerror(errno), errno); + SwooleG.max_sockets = 1024; + } + else + { + SwooleG.max_sockets = (uint32_t) rlmt.rlim_cur; + } + + SwooleTG.buffer_stack = swString_new(8192); + if (SwooleTG.buffer_stack == NULL) + { + exit(3); + } + + if (!SwooleG.task_tmpdir) + { + SwooleG.task_tmpdir = sw_strndup(SW_TASK_TMP_FILE, sizeof(SW_TASK_TMP_FILE)); + SwooleG.task_tmpdir_len = sizeof(SW_TASK_TMP_FILE); + } + + char *tmp_dir = swoole_dirname(SwooleG.task_tmpdir); + //create tmp dir + if (access(tmp_dir, R_OK) < 0 && swoole_mkdir_recursive(tmp_dir) < 0) + { + swWarn("create task tmp dir(%s) failed.", tmp_dir); + } + if (tmp_dir) + { + sw_free(tmp_dir); + } + + //init signalfd +#ifdef HAVE_SIGNALFD + swSignalfd_init(); + SwooleG.use_signalfd = 1; + SwooleG.enable_signalfd = 1; +#endif + //timerfd +#ifdef HAVE_TIMERFD + SwooleG.use_timerfd = 1; +#endif + + SwooleG.use_timer_pipe = 1; +} + +void swoole_clean(void) +{ + //free the global memory + if (SwooleG.memory_pool != NULL) + { + if (SwooleG.timer.fd > 0) + { + swTimer_free(&SwooleG.timer); + } + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->free(SwooleG.main_reactor); + } + SwooleG.memory_pool->destroy(SwooleG.memory_pool); + bzero(&SwooleG, sizeof(SwooleG)); + } +} + +uint64_t swoole_hash_key(char *str, int str_len) +{ + uint64_t hash = 5381; + int c, i = 0; + for (c = *str++; i < str_len; i++) + { + hash = (*((hash * 33) + str)) & 0x7fffffff; + hash = ((hash << 5) + hash) + c; + } + return hash; +} + +void swoole_dump_ascii(char *data, int size) +{ + int i; + for (i = 0; i < size; i++) + { + printf("%d ", (unsigned) data[i]); + } + printf("\n"); +} + +void swoole_dump_bin(char *data, char type, int size) +{ + int i; + int type_size = swoole_type_size(type); + if (type_size <= 0) + { + return; + } + int n = size / type_size; + + for (i = 0; i < n; i++) + { + printf("%d,", swoole_unpack(type, data + type_size * i)); + } + printf("\n"); +} + +void swoole_dump_hex(char *data, int outlen) +{ + long i; + for (i = 0; i < outlen; ++i) + { + if ((i & 0x0fu) == 0) + { + printf("%08zX: ", i); + } + printf("%02X ", data[i]); + if (((i + 1) & 0x0fu) == 0) + { + printf("\n"); + } + } + printf("\n"); +} + +/** + * Recursive directory creation + */ +int swoole_mkdir_recursive(const char *dir) +{ + char tmp[PATH_MAX]; + int i, len = strlen(dir); + + if (len + 1 > PATH_MAX) /* PATH_MAX limit includes string trailing null character */ + { + swWarn("mkdir(%s) failed. Path exceeds the limit of %d characters.", dir, PATH_MAX - 1); + return -1; + } + strncpy(tmp, dir, len + 1); + + if (dir[len - 1] != '/') + { + strcat(tmp, "/"); + } + + len = strlen(tmp); + + for (i = 1; i < len; i++) + { + if (tmp[i] == '/') + { + tmp[i] = 0; + if (access(tmp, R_OK) != 0) + { + if (mkdir(tmp, 0755) == -1) + { + swWarn("mkdir(%s) failed. Error: %s[%d]", tmp, strerror(errno), errno); + return -1; + } + } + tmp[i] = '/'; + } + } + return 0; +} + +/** + * get parent dir name + */ +char* swoole_dirname(char *file) +{ + char *dirname = sw_strdup(file); + if (dirname == NULL) + { + swWarn("strdup() failed."); + return NULL; + } + + int i = strlen(dirname); + + if (dirname[i - 1] == '/') + { + i -= 2; + } + + for (; i > 0; i--) + { + if ('/' == dirname[i]) + { + dirname[i] = 0; + break; + } + } + return dirname; +} + +int swoole_type_size(char type) +{ + switch (type) + { + case 'c': + case 'C': + return 1; + case 's': + case 'S': + case 'n': + case 'v': + return 2; + case 'l': + case 'L': + case 'N': + case 'V': + return 4; + default: + return 0; + } +} + +char* swoole_dec2hex(int value, int base) +{ + assert(base > 1 && base < 37); + + static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + char buf[(sizeof(unsigned long) << 3) + 1]; + char *ptr, *end; + + end = ptr = buf + sizeof(buf) - 1; + *ptr = '\0'; + + do + { + *--ptr = digits[value % base]; + value /= base; + } while (ptr > buf && value); + + return sw_strndup(ptr, end - ptr); +} + +int swoole_sync_writefile(int fd, void *data, int len) +{ + int n = 0; + int count = len, towrite, written = 0; + + while (count > 0) + { + towrite = count; + if (towrite > SW_FILE_CHUNK_SIZE) + { + towrite = SW_FILE_CHUNK_SIZE; + } + n = write(fd, data, towrite); + if (n > 0) + { + data += n; + count -= n; + written += n; + } + else if (n == 0) + { + break; + } + else + { + if (errno == EINTR || errno == EAGAIN) + { + continue; + } + swSysError("write(%d, %d) failed.", fd, towrite); + break; + } + } + return written; +} + +#ifndef RAND_MAX +#define RAND_MAX 2147483647 +#endif + +int swoole_rand(int min, int max) +{ + static int _seed = 0; + assert(max > min); + + if (_seed == 0) + { + _seed = time(NULL); + srand(_seed); + } + + int _rand = rand(); + _rand = min + (int) ((double) ((double) (max) - (min) + 1.0) * ((_rand) / ((RAND_MAX) + 1.0))); + return _rand; +} + +int swoole_system_random(int min, int max) +{ + static int dev_random_fd = -1; + char *next_random_byte; + int bytes_to_read; + unsigned random_value; + + assert(max > min); + + if (dev_random_fd == -1) + { + dev_random_fd = open("/dev/urandom", O_RDONLY); + if (dev_random_fd < 0) + { + return swoole_rand(min, max); + } + } + + next_random_byte = (char *) &random_value; + bytes_to_read = sizeof(random_value); + + if (read(dev_random_fd, next_random_byte, bytes_to_read) < bytes_to_read) + { + swSysError("read() from /dev/urandom failed."); + return SW_ERR; + } + return min + (random_value % (max - min + 1)); +} + +void swoole_redirect_stdout(int new_fd) +{ + if (dup2(new_fd, STDOUT_FILENO) < 0) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "dup2(STDOUT_FILENO) failed. Error: %s[%d]", strerror(errno), errno); + } + if (dup2(new_fd, STDERR_FILENO) < 0) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "dup2(STDERR_FILENO) failed. Error: %s[%d]", strerror(errno), errno); + } +} + +int swoole_version_compare(char *version1, char *version2) +{ + int result = 0; + + while (result == 0) + { + char* tail1; + char* tail2; + + unsigned long ver1 = strtoul(version1, &tail1, 10); + unsigned long ver2 = strtoul(version2, &tail2, 10); + + if (ver1 < ver2) + { + result = -1; + } + else if (ver1 > ver2) + { + result = +1; + } + else + { + version1 = tail1; + version2 = tail2; + if (*version1 == '\0' && *version2 == '\0') + { + break; + } + else if (*version1 == '\0') + { + result = -1; + } + else if (*version2 == '\0') + { + result = +1; + } + else + { + version1++; + version2++; + } + } + } + return result; +} + +double swoole_microtime(void) +{ + struct timeval t; + gettimeofday(&t, NULL); + return (double) t.tv_sec + ((double) t.tv_usec / 1000000); +} + +void swoole_rtrim(char *str, int len) +{ + int i; + for (i = len; i > 0; i--) + { + switch (str[i]) + { + case ' ': + case '\0': + case '\n': + case '\r': + case '\t': + case '\v': + str[i] = 0; + break; + default: + return; + } + } +} + +int swoole_tmpfile(char *filename) +{ +#if defined(HAVE_MKOSTEMP) && defined(HAVE_EPOLL) + int tmp_fd = mkostemp(filename, O_WRONLY | O_CREAT); +#else + int tmp_fd = mkstemp(filename); +#endif + + if (tmp_fd < 0) + { + swSysError("mkstemp(%s) failed.", filename); + return SW_ERR; + } + else + { + return tmp_fd; + } +} + +long swoole_file_get_size(FILE *fp) +{ + long pos = ftell(fp); + if (fseek(fp, 0L, SEEK_END) < 0) + { + return SW_ERR; + } + long size = ftell(fp); + if (fseek(fp, pos, SEEK_SET) < 0) + { + return SW_ERR; + } + return size; +} + +long swoole_file_size(char *filename) +{ + struct stat file_stat; + if (lstat(filename, &file_stat) < 0) + { + swSysError("lstat(%s) failed.", filename); + SwooleG.error = errno; + return -1; + } + if ((file_stat.st_mode & S_IFMT) != S_IFREG) + { + SwooleG.error = EISDIR; + return -1; + } + return file_stat.st_size; +} + +swString* swoole_file_get_contents(char *filename) +{ + long filesize = swoole_file_size(filename); + if (filesize < 0) + { + return NULL; + } + else if (filesize == 0) + { + swoole_error_log(SW_LOG_TRACE, SW_ERROR_FILE_EMPTY, "file[%s] is empty.", filename); + return NULL; + } + else if (filesize > SW_MAX_FILE_CONTENT) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_FILE_TOO_LARGE, "file[%s] is too large.", filename); + return NULL; + } + + int fd = open(filename, O_RDONLY); + if (fd < 0) + { + swWarn("open(%s) failed. Error: %s[%d]", filename, strerror(errno), errno); + return NULL; + } + swString *content = swString_new(filesize); + if (!content) + { + close(fd); + return NULL; + } + + int readn = 0; + int n; + + while(readn < filesize) + { + n = pread(fd, content->str + readn, filesize - readn, readn); + if (n < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + swSysError("pread(%d, %ld, %d) failed.", fd, filesize - readn, readn); + swString_free(content); + close(fd); + return NULL; + } + } + readn += n; + } + close(fd); + content->length = readn; + return content; +} + +int swoole_file_put_contents(char *filename, char *content, size_t length) +{ + if (length <= 0) + { + swoole_error_log(SW_LOG_TRACE, SW_ERROR_FILE_EMPTY, "content is empty."); + return SW_ERR; + } + if (length > SW_MAX_FILE_CONTENT) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_FILE_TOO_LARGE, "content is too large."); + return SW_ERR; + } + + int fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (fd < 0) + { + swSysError("open(%s) failed.", filename); + return SW_ERR; + } + + int n, chunk_size, written = 0; + + while(written < length) + { + chunk_size = length - written; + if (chunk_size > SW_BUFFER_SIZE_BIG) + { + chunk_size = SW_BUFFER_SIZE_BIG; + } + n = write(fd, content + written, chunk_size); + if (n < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + swSysError("write(%d, %d) failed.", fd, chunk_size); + close(fd); + return -1; + } + } + written += n; + } + close(fd); + return SW_OK; +} + +int swoole_sync_readfile(int fd, void *buf, int len) +{ + int n = 0; + int count = len, toread, readn = 0; + + while (count > 0) + { + toread = count; + if (toread > SW_FILE_CHUNK_SIZE) + { + toread = SW_FILE_CHUNK_SIZE; + } + n = read(fd, buf, toread); + if (n > 0) + { + buf += n; + count -= n; + readn += n; + } + else if (n == 0) + { + break; + } + else + { + if (errno == EINTR || errno == EAGAIN) + { + continue; + } + swWarn("read() failed. Error: %s[%d]", strerror(errno), errno); + break; + } + } + return readn; +} + +/** + * Maximum common divisor + */ +uint32_t swoole_common_divisor(uint32_t u, uint32_t v) +{ + assert(u > 0); + assert(v > 0); + uint32_t t; + while (u > 0) + { + if (u < v) + { + t = u; + u = v; + v = t; + } + u = u - v; + } + return v; +} + +/** + * The least common multiple + */ +uint32_t swoole_common_multiple(uint32_t u, uint32_t v) +{ + assert(u > 0); + assert(v > 0); + + uint32_t m_cup = u; + uint32_t n_cup = v; + int res = m_cup % n_cup; + + while (res != 0) + { + m_cup = n_cup; + n_cup = res; + res = m_cup % n_cup; + } + return u * v / n_cup; +} + +/** + * for GDB + */ +void swBreakPoint() +{ + +} + +void swoole_ioctl_set_block(int sock, int nonblock) +{ + int ret; + do + { + ret = ioctl(sock, FIONBIO, &nonblock); + } + while (ret == -1 && errno == EINTR); + + if (ret < 0) + { + swSysError("ioctl(%d, FIONBIO, %d) failed.", sock, nonblock); + } +} + +void swoole_fcntl_set_option(int sock, int nonblock, int cloexec) +{ + int opts, ret; + + if (nonblock >= 0) + { + do + { + opts = fcntl(sock, F_GETFL); + } + while (opts < 0 && errno == EINTR); + + if (opts < 0) + { + swSysError("fcntl(%d, GETFL) failed.", sock); + } + + if (nonblock) + { + opts = opts | O_NONBLOCK; + } + else + { + opts = opts & ~O_NONBLOCK; + } + + do + { + ret = fcntl(sock, F_SETFL, opts); + } + while (ret < 0 && errno == EINTR); + + if (ret < 0) + { + swSysError("fcntl(%d, SETFL, opts) failed.", sock); + } + } + +#ifdef FD_CLOEXEC + if (cloexec >= 0) + { + do + { + opts = fcntl(sock, F_GETFD); + } + while (opts < 0 && errno == EINTR); + + if (opts < 0) + { + swSysError("fcntl(%d, GETFL) failed.", sock); + } + + if (cloexec) + { + opts = opts | FD_CLOEXEC; + } + else + { + opts = opts & ~FD_CLOEXEC; + } + + do + { + ret = fcntl(sock, F_SETFD, opts); + } + while (ret < 0 && errno == EINTR); + + if (ret < 0) + { + swSysError("fcntl(%d, SETFD, opts) failed.", sock); + } + } +#endif +} + +static int *swoole_kmp_borders(char *needle, size_t nlen) +{ + if (!needle) + { + return NULL; + } + + int i, j, *borders = malloc((nlen + 1) * sizeof(*borders)); + if (!borders) + { + return NULL; + } + + i = 0; + j = -1; + borders[i] = j; + while ((uint32_t) i < nlen) + { + while (j >= 0 && needle[i] != needle[j]) + { + j = borders[j]; + } + ++i; + ++j; + borders[i] = j; + } + return borders; +} + +static char *swoole_kmp_search(char *haystack, size_t haylen, char *needle, uint32_t nlen, int *borders) +{ + uint32_t max_index = haylen - nlen, i = 0, j = 0; + + while (i <= max_index) + { + while (j < nlen && *haystack && needle[j] == *haystack) + { + ++j; + ++haystack; + } + if (j == nlen) + { + return haystack - nlen; + } + if (!(*haystack)) + { + return NULL; + } + if (j == 0) + { + ++haystack; + ++i; + } + else + { + do + { + i += j - (uint32_t) borders[j]; + j = borders[j]; + } while (j > 0 && needle[j] != *haystack); + } + } + return NULL; +} + +int swoole_itoa(char *buf, long value) +{ + long i = 0, j; + long sign_mask; + unsigned long nn; + + sign_mask = value >> (sizeof(long) * 8 - 1); + nn = (value + sign_mask) ^ sign_mask; + do + { + buf[i++] = nn % 10 + '0'; + } while (nn /= 10); + + buf[i] = '-'; + i += sign_mask & 1; + buf[i] = '\0'; + + int s_len = i; + char swap; + + for (i = 0, j = s_len - 1; i < j; ++i, --j) + { + swap = buf[i]; + buf[i] = buf[j]; + buf[j] = swap; + } + buf[s_len] = 0; + return s_len; +} + +char *swoole_kmp_strnstr(char *haystack, char *needle, uint32_t length) +{ + if (!haystack || !needle) + { + return NULL; + } + size_t nlen = strlen(needle); + if (length < nlen) + { + return NULL; + } + int *borders = swoole_kmp_borders(needle, nlen); + if (!borders) + { + return NULL; + } + char *match = swoole_kmp_search(haystack, length, needle, nlen, borders); + free(borders); + return match; +} + +/** + * DNS lookup + */ +#ifdef HAVE_GETHOSTBYNAME2_R +int swoole_gethostbyname(int flags, char *name, char *addr) +{ + int __af = flags & (~SW_DNS_LOOKUP_RANDOM); + int index = 0; + int rc, err; + int buf_len = 256; + struct hostent hbuf; + struct hostent *result; + + char *buf = (char*) sw_malloc(buf_len); + memset(buf, 0, buf_len); + while ((rc = gethostbyname2_r(name, __af, &hbuf, buf, buf_len, &result, &err)) == ERANGE) + { + buf_len *= 2; + void *tmp = sw_realloc(buf, buf_len); + if (NULL == tmp) + { + sw_free(buf); + return SW_ERR; + } + else + { + buf = tmp; + } + } + + if (0 != rc || NULL == result) + { + sw_free(buf); + return SW_ERR; + } + + union + { + char v4[INET_ADDRSTRLEN]; + char v6[INET6_ADDRSTRLEN]; + } addr_list[SW_DNS_HOST_BUFFER_SIZE]; + + int i = 0; + for (i = 0; i < SW_DNS_HOST_BUFFER_SIZE; i++) + { + if (hbuf.h_addr_list[i] == NULL) + { + break; + } + if (__af == AF_INET) + { + memcpy(addr_list[i].v4, hbuf.h_addr_list[i], hbuf.h_length); + } + else + { + memcpy(addr_list[i].v6, hbuf.h_addr_list[i], hbuf.h_length); + } + } + if (__af == AF_INET) + { + memcpy(addr, addr_list[index].v4, hbuf.h_length); + } + else + { + memcpy(addr, addr_list[index].v6, hbuf.h_length); + } + + sw_free(buf); + + return SW_OK; +} +#else +int swoole_gethostbyname(int flags, char *name, char *addr) +{ + int __af = flags & (~SW_DNS_LOOKUP_RANDOM); + int index = 0; + + struct hostent *host_entry; + if (!(host_entry = gethostbyname2(name, __af))) + { + return SW_ERR; + } + + union + { + char v4[INET_ADDRSTRLEN]; + char v6[INET6_ADDRSTRLEN]; + } addr_list[SW_DNS_HOST_BUFFER_SIZE]; + + int i = 0; + for (i = 0; i < SW_DNS_HOST_BUFFER_SIZE; i++) + { + if (host_entry->h_addr_list[i] == NULL) + { + break; + } + if (__af == AF_INET) + { + memcpy(addr_list[i].v4, host_entry->h_addr_list[i], host_entry->h_length); + } + else + { + memcpy(addr_list[i].v6, host_entry->h_addr_list[i], host_entry->h_length); + } + } + if (__af == AF_INET) + { + memcpy(addr, addr_list[index].v4, host_entry->h_length); + } + else + { + memcpy(addr, addr_list[index].v6, host_entry->h_length); + } + return SW_OK; +} +#endif + +int swoole_getaddrinfo(swRequest_getaddrinfo *req) +{ + struct addrinfo *result = NULL; + struct addrinfo *ptr = NULL; + struct addrinfo hints; + + bzero(&hints, sizeof(hints)); + hints.ai_family = req->family; + hints.ai_socktype = req->socktype; + hints.ai_protocol = req->protocol; + + int ret = getaddrinfo(req->hostname, req->service, &hints, &result); + if (ret != 0) + { + req->error = ret; + return SW_ERR; + } + + void *buffer = req->result; + int i = 0; + for (ptr = result; ptr != NULL; ptr = ptr->ai_next) + { + switch (ptr->ai_family) + { + case AF_INET: + memcpy(buffer + (i * sizeof(struct sockaddr_in)), ptr->ai_addr, sizeof(struct sockaddr_in)); + break; + case AF_INET6: + memcpy(buffer + (i * sizeof(struct sockaddr_in6)), ptr->ai_addr, sizeof(struct sockaddr_in6)); + break; + default: + swWarn("unknown socket family[%d].", ptr->ai_family); + break; + } + i++; + if (i == SW_DNS_HOST_BUFFER_SIZE) + { + break; + } + } + freeaddrinfo(result); + req->error = 0; + req->count = i; + return SW_OK; +} + +SW_API int swoole_add_function(const char *name, void* func) +{ + if (SwooleG.functions == NULL) + { + SwooleG.functions = swHashMap_new(64, NULL); + if (SwooleG.functions == NULL) + { + return SW_ERR; + } + } + if (swHashMap_find(SwooleG.functions, (char *) name, strlen(name)) != NULL) + { + swWarn("Function '%s' has already been added.", name); + return SW_ERR; + } + return swHashMap_add(SwooleG.functions, (char *) name, strlen(name), func); +} + +SW_API void* swoole_get_function(char *name, uint32_t length) +{ + if (!SwooleG.functions) + { + return NULL; + } + return swHashMap_find(SwooleG.functions, name, length); +} + +SW_API int swoole_add_hook(enum swGlobal_hook_type type, swCallback func, int push_back) +{ + if (SwooleG.hooks[type] == NULL) + { + SwooleG.hooks[type] = swLinkedList_new(0, NULL); + if (SwooleG.hooks[type] == NULL) + { + return SW_ERR; + } + } + if (push_back) + { + return swLinkedList_append(SwooleG.hooks[type], func); + } + else + { + return swLinkedList_prepend(SwooleG.hooks[type], func); + } +} + +SW_API void swoole_call_hook(enum swGlobal_hook_type type, void *arg) +{ + swLinkedList *hooks = SwooleG.hooks[type]; + swLinkedList_node *node = hooks->head; + swCallback func = NULL; + + while (node) + { + func = node->data; + func(arg); + node = node->next; + } +} + +int swoole_shell_exec(char *command, pid_t *pid) +{ + pid_t child_pid; + int fds[2]; + if (pipe(fds) < 0) + { + return SW_ERR; + } + + if ((child_pid = fork()) == -1) + { + swSysError("fork() failed."); + return SW_ERR; + } + + if (child_pid == 0) + { + close(fds[SW_PIPE_READ]); + dup2(fds[SW_PIPE_WRITE], 1); + + //Needed so negative PIDs can kill children of /bin/sh + setpgid(child_pid, child_pid); + execl("/bin/sh", "/bin/sh", "-c", command, NULL); + exit(0); + } + else + { + *pid = child_pid; + close(fds[SW_PIPE_WRITE]); + } + return fds[SW_PIPE_READ]; +} + +char* swoole_string_format(size_t n, const char *format, ...) +{ + char *buf = sw_malloc(n); + if (buf == NULL) + { + return NULL; + } + + va_list _va_list; + va_start(_va_list, format); + + if (vsnprintf(buf, n, format, _va_list) < 0) + { + sw_free(buf); + return NULL; + } + + return buf; +} + +#ifdef HAVE_EXECINFO +void swoole_print_trace(void) +{ + int size = 16; + void* array[16]; + int stack_num = backtrace(array, size); + char** stacktrace = backtrace_symbols(array, stack_num); + int i; + + for (i = 0; i < stack_num; ++i) + { + printf("%s\n", stacktrace[i]); + } + free(stacktrace); +} +#endif + +#ifndef HAVE_CLOCK_GETTIME +#ifdef __MACH__ +int clock_gettime(clock_id_t which_clock, struct timespec *t) +{ + // be more careful in a multithreaded environement + if (!orwl_timestart) + { + mach_timebase_info_data_t tb = + { 0}; + mach_timebase_info(&tb); + orwl_timebase = tb.numer; + orwl_timebase /= tb.denom; + orwl_timestart = mach_absolute_time(); + } + double diff = (mach_absolute_time() - orwl_timestart) * orwl_timebase; + t->tv_sec = diff * ORWL_NANO; + t->tv_nsec = diff - (t->tv_sec * ORWL_GIGA); + return 0; +} +#endif +#endif diff --git a/vendor/swoole/src/core/error.cc b/vendor/swoole/src/core/error.cc new file mode 100755 index 0000000..f53a475 --- /dev/null +++ b/vendor/swoole/src/core/error.cc @@ -0,0 +1,40 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include <string> + +namespace swoole +{ + +class Exception +{ +public: + int code; + + Exception(enum swErrorCode _code) + { + code = _code; + } +}; + +} +; + +void swoole_throw_error(enum swErrorCode code) +{ + throw swoole::Exception(code); +} diff --git a/vendor/swoole/src/core/hashmap.c b/vendor/swoole/src/core/hashmap.c new file mode 100755 index 0000000..5827540 --- /dev/null +++ b/vendor/swoole/src/core/hashmap.c @@ -0,0 +1,515 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "uthash.h" +#include "hash.h" + +typedef struct swHashMap_node +{ + uint64_t key_int; + char *key_str; + void *data; + UT_hash_handle hh; +} swHashMap_node; + +static int swHashMap_node_delete(swHashMap_node *root, swHashMap_node *del_node); + +static sw_inline void swHashMap_node_dtor(swHashMap *hmap, swHashMap_node *node) +{ + if (hmap->dtor) + { + hmap->dtor(node->data); + } +} + +static sw_inline void swHashMap_node_free(swHashMap *hmap, swHashMap_node *node) +{ + swHashMap_node_dtor(hmap, node); + sw_free(node->key_str); + sw_free(node); +} + +static sw_inline int swHashMap_node_add(swHashMap_node *root, swHashMap_node *add) +{ + unsigned _ha_bkt; + add->hh.next = NULL; + add->hh.key = add->key_str; + add->hh.keylen = add->key_int; + + root->hh.tbl->tail->next = add; + add->hh.prev = ELMT_FROM_HH(root->hh.tbl, root->hh.tbl->tail); + root->hh.tbl->tail = &(add->hh); + + root->hh.tbl->num_items++; + add->hh.tbl = root->hh.tbl; + add->hh.hashv = swoole_hash_jenkins(add->key_str, add->key_int); + _ha_bkt = add->hh.hashv & (root->hh.tbl->num_buckets - 1); + + HASH_ADD_TO_BKT(root->hh.tbl->buckets[_ha_bkt], &add->hh); + + return SW_OK; +} + +static sw_inline swHashMap_node* swHashMap_node_each(swHashMap* hmap) +{ + swHashMap_node *iterator = hmap->iterator; + swHashMap_node *tmp; + + if (hmap->root->hh.tbl->num_items == 0) + { + return NULL; + } + if (iterator == NULL) + { + iterator = hmap->root; + } + tmp = iterator->hh.next; + if (tmp) + { + hmap->iterator = tmp; + return tmp; + } + else + { + hmap->iterator = NULL; + return NULL; + } +} + +swHashMap* swHashMap_new(uint32_t bucket_num, swHashMap_dtor dtor) +{ + swHashMap *hmap = sw_malloc(sizeof(swHashMap)); + if (!hmap) + { + swWarn("malloc[1] failed."); + return NULL; + } + swHashMap_node *root = sw_malloc(sizeof(swHashMap_node)); + if (!root) + { + swWarn("malloc[2] failed."); + sw_free(hmap); + return NULL; + } + + bzero(hmap, sizeof(swHashMap)); + hmap->root = root; + + bzero(root, sizeof(swHashMap_node)); + + root->hh.tbl = (UT_hash_table*) sw_malloc(sizeof(UT_hash_table)); + if (!(root->hh.tbl)) + { + swWarn("malloc for table failed."); + sw_free(hmap); + return NULL; + } + + memset(root->hh.tbl, 0, sizeof(UT_hash_table)); + root->hh.tbl->tail = &(root->hh); + root->hh.tbl->num_buckets = SW_HASHMAP_INIT_BUCKET_N; + root->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; + root->hh.tbl->hho = (char*) (&root->hh) - (char*) root; + root->hh.tbl->buckets = (UT_hash_bucket*) sw_malloc(SW_HASHMAP_INIT_BUCKET_N * sizeof(struct UT_hash_bucket)); + if (!root->hh.tbl->buckets) + { + swWarn("malloc for buckets failed."); + sw_free(hmap); + return NULL; + } + memset(root->hh.tbl->buckets, 0, SW_HASHMAP_INIT_BUCKET_N * sizeof(struct UT_hash_bucket)); + root->hh.tbl->signature = HASH_SIGNATURE; + + hmap->dtor = dtor; + + return hmap; +} + +int swHashMap_add(swHashMap* hmap, char *key, uint16_t key_len, void *data) +{ + swHashMap_node *node = (swHashMap_node*) sw_malloc(sizeof(swHashMap_node)); + if (node == NULL) + { + swWarn("malloc failed."); + return SW_ERR; + } + bzero(node, sizeof(swHashMap_node)); + swHashMap_node *root = hmap->root; + node->key_str = sw_strndup(key, key_len); + node->key_int = key_len; + node->data = data; + return swHashMap_node_add(root, node); +} + +int swHashMap_add_int(swHashMap *hmap, uint64_t key, void *data) +{ + swHashMap_node *node = (swHashMap_node*) sw_malloc(sizeof(swHashMap_node)); + swHashMap_node *root = hmap->root; + if (node == NULL) + { + swWarn("malloc failed"); + return SW_ERR; + } + node->key_int = key; + node->data = data; + node->key_str = NULL; + HASH_ADD_INT(root, key_int, node); + return SW_OK; +} + +static sw_inline swHashMap_node *swHashMap_node_find(swHashMap_node *root, char *key_str, uint16_t key_len) +{ + swHashMap_node *out; + unsigned bucket, hash; + out = NULL; + if (root) + { + hash = swoole_hash_jenkins(key_str, key_len); + bucket = hash & (root->hh.tbl->num_buckets - 1); + HASH_FIND_IN_BKT(root->hh.tbl, hh, (root)->hh.tbl->buckets[bucket], key_str, key_len, out); + } + return out; +} + +static int swHashMap_node_delete(swHashMap_node *root, swHashMap_node *del_node) +{ + unsigned bucket; + struct UT_hash_handle *_hd_hh_del; + + if ((del_node->hh.prev == NULL) && (del_node->hh.next == NULL)) + { + sw_free(root->hh.tbl->buckets); + sw_free(root->hh.tbl); + } + else + { + _hd_hh_del = &(del_node->hh); + if (del_node == ELMT_FROM_HH(root->hh.tbl, root->hh.tbl->tail)) + { + root->hh.tbl->tail = (UT_hash_handle*) ((ptrdiff_t) (del_node->hh.prev) + root->hh.tbl->hho); + } + if (del_node->hh.prev) + { + ((UT_hash_handle*) ((ptrdiff_t) (del_node->hh.prev) + root->hh.tbl->hho))->next = del_node->hh.next; + } + else + { + DECLTYPE_ASSIGN(root, del_node->hh.next); + } + if (_hd_hh_del->next) + { + ((UT_hash_handle*) ((ptrdiff_t) _hd_hh_del->next + root->hh.tbl->hho))->prev = _hd_hh_del->prev; + } + HASH_TO_BKT(_hd_hh_del->hashv, root->hh.tbl->num_buckets, bucket); + HASH_DEL_IN_BKT(hh, root->hh.tbl->buckets[bucket], _hd_hh_del); + root->hh.tbl->num_items--; + } + return SW_OK; +} + +void* swHashMap_find(swHashMap* hmap, char *key, uint16_t key_len) +{ + swHashMap_node *root = hmap->root; + swHashMap_node *ret = swHashMap_node_find(root, key, key_len); + if (ret == NULL) + { + return NULL; + } + return ret->data; +} + +void* swHashMap_find_int(swHashMap* hmap, uint64_t key) +{ + swHashMap_node *ret = NULL; + swHashMap_node *root = hmap->root; + HASH_FIND_INT(root, &key, ret); + if (ret == NULL) + { + return NULL; + } + return ret->data; +} + +int swHashMap_update(swHashMap* hmap, char *key, uint16_t key_len, void *data) +{ + swHashMap_node *root = hmap->root; + swHashMap_node *node = swHashMap_node_find(root, key, key_len); + if (node == NULL) + { + return SW_ERR; + } + swHashMap_node_dtor(hmap, node); + node->data = data; + return SW_OK; +} + +void swHashMap_update_int(swHashMap* hmap, uint64_t key, void *data) +{ + swHashMap_node *ret = NULL; + swHashMap_node *root = hmap->root; + HASH_FIND_INT(root, &key, ret); + if (ret == NULL) + { + return; + } + swHashMap_node_dtor(hmap, ret); + ret->data = data; +} + +int swHashMap_del(swHashMap* hmap, char *key, uint16_t key_len) +{ + swHashMap_node *root = hmap->root; + swHashMap_node *node = swHashMap_node_find(root, key, key_len); + if (node == NULL) + { + return SW_ERR; + } + swHashMap_node_delete(root, node); + swHashMap_node_free(hmap, node); + return SW_OK; +} + +int swHashMap_del_int(swHashMap *hmap, uint64_t key) +{ + swHashMap_node *ret = NULL; + swHashMap_node *root = hmap->root; + + HASH_FIND_INT(root, &key, ret); + if (ret == NULL) + { + return SW_ERR; + } + HASH_DEL(root, ret); + swHashMap_node_free(hmap, ret); + return SW_OK; +} + +int swHashMap_move(swHashMap *hmap, char *old_key, uint16_t old_key_len, char *new_key, uint16_t new_key_len) +{ + swHashMap_node *root = hmap->root; + swHashMap_node *node = swHashMap_node_find(root, old_key, old_key_len); + if (node == NULL) + { + return SW_ERR; + } + swHashMap_node_delete(root, node); + sw_free(node->key_str); + node->key_str = sw_strndup(new_key, new_key_len); + node->key_int = new_key_len; + return swHashMap_node_add(root, node); +} + +int swHashMap_move_int(swHashMap *hmap, uint64_t old_key, uint64_t new_key) +{ + swHashMap_node *ret = NULL; + swHashMap_node *root = hmap->root; + + HASH_FIND_INT(root, &old_key, ret); + if (ret == NULL) + { + return SW_ERR; + } + HASH_DEL(root, ret); + + ret->key_int = new_key; + HASH_ADD_INT(root, key_int, ret); + + return SW_OK; +} + +void* swHashMap_each(swHashMap* hmap, char **key) +{ + swHashMap_node *node = swHashMap_node_each(hmap); + if (node) + { + *key = node->key_str; + return node->data; + } + else + { + return NULL; + } +} + +void* swHashMap_each_int(swHashMap* hmap, uint64_t *key) +{ + swHashMap_node *node = swHashMap_node_each(hmap); + if (node) + { + *key = node->key_int; + return node->data; + } + else + { + return NULL; + } +} + +uint32_t swHashMap_count(swHashMap* hmap) +{ + if (hmap == NULL) + { + return 0; + } + return HASH_COUNT(hmap->root); +} + +void swHashMap_free(swHashMap* hmap) +{ + swHashMap_node *find, *tmp = NULL; + swHashMap_node *root = hmap->root; + HASH_ITER(hh, root, find, tmp) + { + if (find == root) continue; + swHashMap_node_delete(root, find); + swHashMap_node_free(hmap, find); + } + + sw_free(hmap->root->hh.tbl->buckets); + sw_free(hmap->root->hh.tbl); + sw_free(hmap->root); + + sw_free(hmap); +} + +/* {{{ COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + * + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + * + * + * CRC32 code derived from work by Gary S. Brown. + */ + +static unsigned int crc32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; + +static inline uint32_t crc32(char *buf, unsigned int size) +{ + const char *p; + register int crc = 0; + + p = buf; + while (size--) + { + crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + } + + return crc ^ ~0U; +} + +uint32_t swoole_crc32(char *data, uint32_t size) +{ + if (size < CRC_STRING_MAXLEN) + { + return crc32(data, size); + } + else + { + int i = 0; + char crc_contents[CRC_STRING_MAXLEN]; + int head = CRC_STRING_MAXLEN >> 2; + int tail = CRC_STRING_MAXLEN >> 4; + int body = CRC_STRING_MAXLEN - head - tail; + char *p = data + head; + char *q = crc_contents + head; + int step = (size - tail - head) / body; + + memcpy(crc_contents, data, head); + for (; i < body; i++, q++, p += step) + { + *q = *p; + } + memcpy(q, p, tail); + return crc32(crc_contents, CRC_STRING_MAXLEN); + } +} diff --git a/vendor/swoole/src/core/heap.c b/vendor/swoole/src/core/heap.c new file mode 100755 index 0000000..e6abcd3 --- /dev/null +++ b/vendor/swoole/src/core/heap.c @@ -0,0 +1,219 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "heap.h" + +#define left(i) ((i) << 1) +#define right(i) (((i) << 1) + 1) +#define parent(i) ((i) >> 1) + +static void swHeap_bubble_up(swHeap *heap, uint32_t i); +static uint32_t swHeap_maxchild(swHeap *heap, uint32_t i); +static void swHeap_percolate_down(swHeap *heap, uint32_t i); + +swHeap *swHeap_new(size_t n, uint8_t type) +{ + swHeap *heap = sw_malloc(sizeof(swHeap)); + if (!heap) + { + return NULL; + } + if (!(heap->nodes = sw_malloc((n + 1) * sizeof(void *)))) + { + sw_free(heap); + return NULL; + } + heap->num = 1; + heap->size = (n + 1); + heap->type = type; + return heap; +} + +void swHeap_free(swHeap *heap) +{ + sw_free(heap->nodes); + sw_free(heap); +} + +static sw_inline int swHeap_compare(uint8_t type, uint64_t a, uint64_t b) +{ + if (type == SW_MIN_HEAP) + { + return a > b; + } + else + { + return a < b; + } +} + +uint32_t swHeap_size(swHeap *q) +{ + return (q->num - 1); +} + +static uint32_t swHeap_maxchild(swHeap *heap, uint32_t i) +{ + uint32_t child_i = left(i); + if (child_i >= heap->num) + { + return 0; + } + swHeap_node * child_node = heap->nodes[child_i]; + if ((child_i + 1) < heap->num && swHeap_compare(heap->type, child_node->priority, heap->nodes[child_i + 1]->priority)) + { + child_i++; + } + return child_i; +} + +static void swHeap_bubble_up(swHeap *heap, uint32_t i) +{ + swHeap_node *moving_node = heap->nodes[i]; + uint32_t parent_i; + + for (parent_i = parent(i); + (i > 1) && swHeap_compare(heap->type, heap->nodes[parent_i]->priority, moving_node->priority); + i = parent_i, parent_i = parent(i)) + { + heap->nodes[i] = heap->nodes[parent_i]; + heap->nodes[i]->position = i; + } + + heap->nodes[i] = moving_node; + moving_node->position = i; +} + +static void swHeap_percolate_down(swHeap *heap, uint32_t i) +{ + uint32_t child_i; + swHeap_node *moving_node = heap->nodes[i]; + + while ((child_i = swHeap_maxchild(heap, i)) + && swHeap_compare(heap->type, moving_node->priority, heap->nodes[child_i]->priority)) + { + heap->nodes[i] = heap->nodes[child_i]; + heap->nodes[i]->position = i; + i = child_i; + } + + heap->nodes[i] = moving_node; + moving_node->position = i; +} + +swHeap_node* swHeap_push(swHeap *heap, uint64_t priority, void *data) +{ + void *tmp; + uint32_t i; + uint32_t newsize; + + if (heap->num >= heap->size) + { + newsize = heap->size * 2; + if (!(tmp = sw_realloc(heap->nodes, sizeof(void *) * newsize))) + { + return NULL; + } + heap->nodes = tmp; + heap->size = newsize; + } + + swHeap_node *node = sw_malloc(sizeof(swHeap_node)); + if (!node) + { + return NULL; + } + node->priority = priority; + node->data = data; + i = heap->num++; + heap->nodes[i] = node; + swHeap_bubble_up(heap, i); + return node; +} + +void swHeap_change_priority(swHeap *heap, uint64_t new_priority, void* ptr) +{ + swHeap_node *node = ptr; + uint32_t pos = node->position; + uint64_t old_pri = node->priority; + + node->priority = new_priority; + if (swHeap_compare(heap->type, old_pri, new_priority)) + { + swHeap_bubble_up(heap, pos); + } + else + { + swHeap_percolate_down(heap, pos); + } +} + +int swHeap_remove(swHeap *heap, swHeap_node *node) +{ + uint32_t pos = node->position; + heap->nodes[pos] = heap->nodes[--heap->num]; + + if (swHeap_compare(heap->type, node->priority, heap->nodes[pos]->priority)) + { + swHeap_bubble_up(heap, pos); + } + else + { + swHeap_percolate_down(heap, pos); + } + return SW_OK; +} + +void *swHeap_pop(swHeap *heap) +{ + swHeap_node *head; + if (!heap || heap->num == 1) + { + return NULL; + } + + head = heap->nodes[1]; + heap->nodes[1] = heap->nodes[--heap->num]; + swHeap_percolate_down(heap, 1); + + void *data = head->data; + sw_free(head); + return data; +} + +void *swHeap_peek(swHeap *heap) +{ + if (heap->num == 1) + { + return NULL; + } + swHeap_node *node = heap->nodes[1]; + if (!node) + { + return NULL; + } + return node->data; +} + +void swHeap_print(swHeap *heap) +{ + int i; + for(i = 1; i < heap->num; i++) + { + printf("#%d\tpriority=%ld, data=%p\n", i, (long)heap->nodes[i]->priority, heap->nodes[i]->data); + } +} diff --git a/vendor/swoole/src/core/list.c b/vendor/swoole/src/core/list.c new file mode 100755 index 0000000..2cbf2ba --- /dev/null +++ b/vendor/swoole/src/core/list.c @@ -0,0 +1,225 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +swLinkedList* swLinkedList_new(uint8_t type, swDestructor dtor) +{ + swLinkedList *q = sw_malloc(sizeof(swLinkedList)); + if (q == NULL) + { + swWarn("malloc(%ld) failed.", sizeof(swLinkedList)); + return NULL; + } + bzero(q, sizeof(swLinkedList)); + q->type = type; + q->dtor = dtor; + return q; +} + +int swLinkedList_append(swLinkedList *ll, void *data) +{ + swLinkedList_node *node = sw_malloc(sizeof(swLinkedList_node)); + if (node == NULL) + { + swWarn("malloc(%ld) failed.", sizeof(swLinkedList_node)); + return SW_ERR; + } + node->data = data; + node->next = NULL; + ll->num++; + if (ll->tail) + { + ll->tail->next = node; + node->prev = ll->tail; + ll->tail = node; + } + else + { + node->next = NULL; + node->prev = NULL; + ll->head = node; + ll->tail = node; + } + return SW_OK; +} + +int swLinkedList_prepend(swLinkedList *ll, void *data) +{ + swLinkedList_node *node = sw_malloc(sizeof(swLinkedList_node)); + if (node == NULL) + { + swWarn("malloc(%ld) failed.", sizeof(swLinkedList_node)); + return SW_ERR; + } + node->data = data; + node->prev = NULL; + ll->num ++; + if (ll->head) + { + ll->head->prev = node; + node->next = ll->head; + ll->head = node; + } + else + { + node->next = NULL; + node->prev = NULL; + ll->head = node; + ll->tail = node; + } + return SW_OK; +} + +/** + * Pop the element off the end of queue + */ +void* swLinkedList_pop(swLinkedList *ll) +{ + if (ll->tail == NULL) + { + return NULL; + } + + swLinkedList_node *node = ll->tail; + if (node == ll->head) + { + ll->head = NULL; + ll->tail = NULL; + } + else + { + swLinkedList_node *prev = ll->tail->prev; + prev->next = NULL; + ll->tail = prev; + } + ll->num--; + void *data = node->data; + sw_free(node); + return data; +} + +void swLinkedList_remove_node(swLinkedList *ll, swLinkedList_node *remove_node) +{ + if (ll->num == 0 || remove_node == NULL) + { + return; + } + + swLinkedList_node *prev = remove_node->prev; + swLinkedList_node *next = remove_node->next; + + if (remove_node == ll->head) + { + ll->head = next; + if (next == NULL) + { + ll->tail = NULL; + } + else + { + next->prev = NULL; + } + } + else if (remove_node == ll->tail) + { + ll->tail = prev; + if (prev == NULL) + { + ll->head = NULL; + } + else + { + prev->next = NULL; + } + } + else + { + next->prev = prev; + prev->next = next; + } + ll->num--; + sw_free(remove_node); +} + +swLinkedList_node* swLinkedList_find(swLinkedList *ll, void *data) +{ + if (ll->num == 0) + { + return NULL; + } + + swLinkedList_node *node = ll->head; + swLinkedList_node *tmp; + + while (node) + { + tmp = node->next; + if (node->data == data) + { + return node; + } + node = tmp; + } + + return NULL; +} + +/** + * Shift an element off the beginning of queue + */ +void* swLinkedList_shift(swLinkedList *ll) +{ + if (ll->head == NULL) + { + return NULL; + } + swLinkedList_node *node = ll->head; + if (node == ll->tail) + { + ll->head = NULL; + ll->tail = NULL; + } + else + { + swLinkedList_node *next = ll->head->next; + next->prev = NULL; + ll->head = next; + } + ll->num--; + void *data = node->data; + sw_free(node); + return data; +} + +void swLinkedList_free(swLinkedList *ll) +{ + swLinkedList_node *node = ll->head; + swLinkedList_node *tmp; + + while (node) + { + tmp = node->next; + if (ll->dtor) + { + ll->dtor(node->data); + } + sw_free(node); + node = tmp; + } + + sw_free(ll); +} diff --git a/vendor/swoole/src/core/log.c b/vendor/swoole/src/core/log.c new file mode 100755 index 0000000..01e43c1 --- /dev/null +++ b/vendor/swoole/src/core/log.c @@ -0,0 +1,106 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#define SW_LOG_BUFFER_SIZE 1024 +#define SW_LOG_DATE_STRLEN 64 + +int swLog_init(char *logfile) +{ + SwooleG.log_fd = open(logfile, O_APPEND| O_RDWR | O_CREAT, 0666); + if (SwooleG.log_fd < 0) + { + printf("open(%s) failed. Error: %s[%d]\n", logfile, strerror(errno), errno); + SwooleG.log_fd = 0; + return SW_ERR; + } + return SW_OK; +} + +void swLog_free(void) +{ + if (SwooleG.log_fd > STDOUT_FILENO) + { + close(SwooleG.log_fd); + } +} + +void swLog_put(int level, char *cnt) +{ + const char *level_str; + char date_str[SW_LOG_DATE_STRLEN]; + char log_str[SW_LOG_BUFFER_SIZE]; + int n; + + switch (level) + { + case SW_LOG_DEBUG: + level_str = "DEBUG"; + break; + case SW_LOG_NOTICE: + level_str = "NOTICE"; + break; + case SW_LOG_ERROR: + level_str = "ERROR"; + break; + case SW_LOG_WARNING: + level_str = "WARNING"; + break; + case SW_LOG_TRACE: + level_str = "TRACE"; + break; + default: + level_str = "INFO"; + break; + } + + time_t t; + struct tm *p; + t = time(NULL); + p = localtime(&t); + snprintf(date_str, SW_LOG_DATE_STRLEN, "%d-%02d-%02d %02d:%02d:%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + + char process_flag = '@'; + int process_id = 0; + + switch(SwooleG.process_type) + { + case SW_PROCESS_MASTER: + process_flag = '#'; + process_id = SwooleTG.id; + break; + case SW_PROCESS_MANAGER: + process_flag = '$'; + break; + case SW_PROCESS_WORKER: + process_flag = '*'; + process_id = SwooleWG.id; + break; + case SW_PROCESS_TASKWORKER: + process_flag = '^'; + process_id = SwooleWG.id; + break; + default: + break; + } + + n = snprintf(log_str, SW_LOG_BUFFER_SIZE, "[%s %c%d.%d]\t%s\t%s\n", date_str, process_flag, SwooleG.pid, process_id, level_str, cnt); + if (write(SwooleG.log_fd, log_str, n) < 0) + { + printf("write(log_fd, size=%d) failed. Error: %s[%d].\n", n, strerror(errno), errno); + } +} diff --git a/vendor/swoole/src/core/rbtree.c b/vendor/swoole/src/core/rbtree.c new file mode 100755 index 0000000..5053058 --- /dev/null +++ b/vendor/swoole/src/core/rbtree.c @@ -0,0 +1,405 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "rbtree.h" + +static inline void swRbtree_left_rotate(swRbtree_node **root, swRbtree_node *sentinel, swRbtree_node *node); +static inline void swRbtree_right_rotate(swRbtree_node **root, swRbtree_node *sentinel, swRbtree_node *node); +static inline void swRbtree_insert_value(swRbtree_node *temp, swRbtree_node *node, swRbtree_node *sentinel); + +void swRbtree_insert_value(swRbtree_node *temp, swRbtree_node *node, swRbtree_node *sentinel) +{ + swRbtree_node **p; + while (1) + { + p = (node->key < temp->key) ? &temp->left : &temp->right; + if (*p == sentinel) + { + break; + } + temp = *p; + } + + *p = node; + node->parent = temp; + node->left = sentinel; + node->right = sentinel; + swRbtree_red(node); +} + +void swRbtree_insert(swRbtree *tree, uint32_t key, void *value) +{ + swRbtree_node **root, *temp, *sentinel; + + root = (swRbtree_node **) &tree->root; + sentinel = tree->sentinel; + + swRbtree_node *node = (swRbtree_node *) malloc(sizeof(swRbtree_node)); + + node->value = value; + node->key = key; + if (*root == sentinel) + { + node->parent = NULL; + node->left = sentinel; + node->right = sentinel; + swRbtree_black(node); + *root = node; + return; + } + + swRbtree_insert_value(*root, node, sentinel); + + /* re-balance tree */ + + while (node != *root && swRbtree_is_red(node->parent)) + { + if (node->parent == node->parent->parent->left) + { + temp = node->parent->parent->right; + if (swRbtree_is_red(temp)) + { + swRbtree_black(node->parent); + swRbtree_black(temp); + swRbtree_red(node->parent->parent); + node = node->parent->parent; + } + else + { + if (node == node->parent->right) + { + node = node->parent; + swRbtree_left_rotate(root, sentinel, node); + } + + swRbtree_black(node->parent); + swRbtree_red(node->parent->parent); + swRbtree_right_rotate(root, sentinel, node->parent->parent); + } + } + else + { + temp = node->parent->parent->left; + + if (swRbtree_is_red(temp)) + { + swRbtree_black(node->parent); + swRbtree_black(temp); + swRbtree_red(node->parent->parent); + node = node->parent->parent; + } + else + { + if (node == node->parent->left) + { + node = node->parent; + swRbtree_right_rotate(root, sentinel, node); + } + + swRbtree_black(node->parent); + swRbtree_red(node->parent->parent); + swRbtree_left_rotate(root, sentinel, node->parent->parent); + } + } + } + swRbtree_black(*root); +} + +void swRbtree_delete(swRbtree *tree, uint32_t key) +{ + uint32_t red; + swRbtree_node find_node; + swRbtree_node **root, *sentinel, *subst, *temp, *w; + swRbtree_node *node = &find_node; + node->key = key; + + root = (swRbtree_node **) &tree->root; + sentinel = tree->sentinel; + + if (node->left == sentinel) + { + temp = node->right; + subst = node; + } + else if (node->right == sentinel) + { + temp = node->left; + subst = node; + } + else + { + subst = swRbtree_min(node->right, sentinel); + + if (subst->left != sentinel) + { + temp = subst->left; + } + else + { + temp = subst->right; + } + } + + if (subst == *root) + { + *root = temp; + swRbtree_black(temp); + + /* DEBUG stuff */ + node->left = NULL; + node->right = NULL; + node->parent = NULL; + node->key = 0; + + return; + } + + red = swRbtree_is_red(subst); + + if (subst == subst->parent->left) + { + subst->parent->left = temp; + } + else + { + subst->parent->right = temp; + } + + if (subst == node) + { + temp->parent = subst->parent; + } + else + { + if (subst->parent == node) + { + temp->parent = subst; + } + else + { + temp->parent = subst->parent; + } + + subst->left = node->left; + subst->right = node->right; + subst->parent = node->parent; + swRbtree_copy_color(subst, node); + + if (node == *root) + { + *root = subst; + } + else + { + if (node == node->parent->left) + { + node->parent->left = subst; + } + else + { + node->parent->right = subst; + } + } + + if (subst->left != sentinel) + { + subst->left->parent = subst; + } + + if (subst->right != sentinel) + { + subst->right->parent = subst; + } + } + + if (red) + { + return; + } + + /* a delete fixup */ + + while (temp != *root && swRbtree_is_black(temp)) + { + if (temp == temp->parent->left) + { + w = temp->parent->right; + + if (swRbtree_is_red(w)) + { + swRbtree_black(w); + swRbtree_red(temp->parent); + swRbtree_left_rotate(root, sentinel, temp->parent); + w = temp->parent->right; + } + + if (swRbtree_is_black(w->left) && swRbtree_is_black(w->right)) + { + swRbtree_red(w); + temp = temp->parent; + } + else + { + if (swRbtree_is_black(w->right)) + { + swRbtree_black(w->left); + swRbtree_red(w); + swRbtree_right_rotate(root, sentinel, w); + w = temp->parent->right; + } + + swRbtree_copy_color(w, temp->parent); + swRbtree_black(temp->parent); + swRbtree_black(w->right); + swRbtree_left_rotate(root, sentinel, temp->parent); + temp = *root; + } + } + else + { + w = temp->parent->left; + + if (swRbtree_is_red(w)) + { + swRbtree_black(w); + swRbtree_red(temp->parent); + swRbtree_right_rotate(root, sentinel, temp->parent); + w = temp->parent->left; + } + + if (swRbtree_is_black(w->left) && swRbtree_is_black(w->right)) + { + swRbtree_red(w); + temp = temp->parent; + } + else + { + if (swRbtree_is_black(w->left)) + { + swRbtree_black(w->right); + swRbtree_red(w); + swRbtree_left_rotate(root, sentinel, w); + w = temp->parent->left; + } + + swRbtree_copy_color(w, temp->parent); + swRbtree_black(temp->parent); + swRbtree_black(w->left); + swRbtree_right_rotate(root, sentinel, temp->parent); + temp = *root; + } + } + } + swRbtree_black(temp); +} + +static inline void swRbtree_left_rotate(swRbtree_node **root, swRbtree_node *sentinel, swRbtree_node *node) +{ + swRbtree_node *temp; + + temp = node->right; + node->right = temp->left; + + if (temp->left != sentinel) + { + temp->left->parent = node; + } + + temp->parent = node->parent; + + if (node == *root) + { + *root = temp; + + } + else if (node == node->parent->left) + { + node->parent->left = temp; + + } + else + { + node->parent->right = temp; + } + + temp->left = node; + node->parent = temp; +} + +static inline void swRbtree_right_rotate(swRbtree_node **root, swRbtree_node *sentinel, swRbtree_node *node) +{ + swRbtree_node *temp; + + temp = node->left; + node->left = temp->right; + + if (temp->right != sentinel) + { + temp->right->parent = node; + } + + temp->parent = node->parent; + + if (node == *root) + { + *root = temp; + } + else if (node == node->parent->right) + { + node->parent->right = temp; + } + else + { + node->parent->left = temp; + } + + temp->right = node; + node->parent = temp; +} + +void *swRbtree_find(swRbtree *tree, uint32_t key) +{ + swRbtree_node *tmp = tree->root; + swRbtree_node *sentinel = tree->sentinel; + while (tmp != sentinel) + { + if (key != tmp->key) + { + tmp = (key < tmp->key) ? tmp->left : tmp->right; + continue; + } + return tmp->value; + } + return NULL; +} + +swRbtree* swRbtree_new() +{ + swRbtree *rbtree = sw_malloc(sizeof(swRbtree)); + swRbtree_node *sentinel = sw_malloc(sizeof(swRbtree_node)); + + sentinel->color = 0; + rbtree->root = sentinel; + rbtree->sentinel = sentinel; + return rbtree; +} + +void swRbtree_free(swRbtree* rbtree) +{ + sw_free(rbtree->root); + sw_free(rbtree); +} diff --git a/vendor/swoole/src/core/socket.c b/vendor/swoole/src/core/socket.c new file mode 100755 index 0000000..040bf17 --- /dev/null +++ b/vendor/swoole/src/core/socket.c @@ -0,0 +1,499 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +#include <sys/stat.h> +#include <poll.h> + +int swSocket_sendfile_sync(int sock, char *filename, off_t offset, size_t length, double timeout) +{ + int timeout_ms = timeout < 0 ? -1 : timeout * 1000; + int file_fd = open(filename, O_RDONLY); + if (file_fd < 0) + { + swWarn("open(%s) failed. Error: %s[%d]", filename, strerror(errno), errno); + return SW_ERR; + } + + if (length == 0) + { + struct stat file_stat; + if (fstat(file_fd, &file_stat) < 0) + { + swWarn("fstat() failed. Error: %s[%d]", strerror(errno), errno); + close(file_fd); + return SW_ERR; + } + length = file_stat.st_size; + } + else + { + length = offset + length; + } + + int n, sendn; + while (offset < length) + { + if (swSocket_wait(sock, timeout_ms, SW_EVENT_WRITE) < 0) + { + close(file_fd); + return SW_ERR; + } + else + { + sendn = (length - offset > SW_SENDFILE_CHUNK_SIZE) ? SW_SENDFILE_CHUNK_SIZE : length - offset; + n = swoole_sendfile(sock, file_fd, &offset, sendn); + if (n <= 0) + { + close(file_fd); + swSysError("sendfile(%d, %s) failed.", sock, filename); + return SW_ERR; + } + else + { + continue; + } + } + } + close(file_fd); + return SW_OK; +} + +/** + * clear socket buffer. + */ +void swSocket_clean(int fd) +{ + char buf[2048]; + while (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) > 0); +} + +/** + * Wait socket can read or write. + */ +int swSocket_wait(int fd, int timeout_ms, int events) +{ + struct pollfd event; + event.fd = fd; + event.events = 0; + + if (events & SW_EVENT_READ) + { + event.events |= POLLIN; + } + if (events & SW_EVENT_WRITE) + { + event.events |= POLLOUT; + } + while (1) + { + int ret = poll(&event, 1, timeout_ms); + if (ret == 0) + { + return SW_ERR; + } + else if (ret < 0 && errno != EINTR) + { + swWarn("poll() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + else + { + return SW_OK; + } + } + return SW_OK; +} + +/** + * Wait some sockets can read or write. + */ +int swSocket_wait_multi(int *list_of_fd, int n_fd, int timeout_ms, int events) +{ + assert(n_fd < 65535); + + struct pollfd *event_list = sw_calloc(n_fd, sizeof(struct pollfd)); + int i; + + int _events = 0; + if (events & SW_EVENT_READ) + { + _events |= POLLIN; + } + if (events & SW_EVENT_WRITE) + { + _events |= POLLOUT; + } + + for (i = 0; i < n_fd; i++) + { + event_list[i].fd = list_of_fd[i]; + event_list[i].events = _events; + } + + while (1) + { + int ret = poll(event_list, n_fd, timeout_ms); + if (ret == 0) + { + sw_free(event_list); + return SW_ERR; + } + else if (ret < 0 && errno != EINTR) + { + swWarn("poll() failed. Error: %s[%d]", strerror(errno), errno); + sw_free(event_list); + return SW_ERR; + } + else + { + sw_free(event_list); + return ret; + } + } + sw_free(event_list); + return SW_OK; +} + +int swSocket_write_blocking(int __fd, void *__data, int __len) +{ + int n = 0; + int written = 0; + + while (written < __len) + { + n = write(__fd, __data + written, __len - written); + if (n < 0) + { + if (errno == EINTR) + { + continue; + } +#ifdef HAVE_KQUEUE + else if (errno == EAGAIN || errno == ENOBUFS) +#else + else if (errno == EAGAIN) +#endif + { + swSocket_wait(__fd, SW_WORKER_WAIT_TIMEOUT, SW_EVENT_WRITE); + continue; + } + else + { + swSysError("write %d bytes failed.", __len); + return SW_ERR; + } + } + written += n; + } + + return written; +} + +int swSocket_recv_blocking(int fd, void *__data, size_t __len, int flags) +{ + int ret; + size_t read_bytes = 0; + + while (read_bytes != __len) + { + errno = 0; + ret = recv(fd, __data + read_bytes, __len - read_bytes, flags); + if (ret > 0) + { + read_bytes += ret; + } + else if (ret == 0 && errno == 0) + { + return read_bytes; + } + else if (ret <= 0 && errno != 0 && errno != EINTR) + { + return ret; + } + } + return read_bytes; +} + +int swSocket_udp_sendto(int server_sock, char *dst_ip, int dst_port, char *data, uint32_t len) +{ + struct sockaddr_in addr; + if (inet_aton(dst_ip, &addr.sin_addr) == 0) + { + swWarn("ip[%s] is invalid.", dst_ip); + return SW_ERR; + } + addr.sin_family = AF_INET; + addr.sin_port = htons(dst_port); + return swSocket_sendto_blocking(server_sock, data, len, 0, (struct sockaddr *) &addr, sizeof(addr)); +} + +int swSocket_udp_sendto6(int server_sock, char *dst_ip, int dst_port, char *data, uint32_t len) +{ + struct sockaddr_in6 addr; + bzero(&addr, sizeof(addr)); + if (inet_pton(AF_INET6, dst_ip, &addr.sin6_addr) < 0) + { + swWarn("ip[%s] is invalid.", dst_ip); + return SW_ERR; + } + addr.sin6_port = (uint16_t) htons(dst_port); + addr.sin6_family = AF_INET6; + return swSocket_sendto_blocking(server_sock, data, len, 0, (struct sockaddr *) &addr, sizeof(addr)); +} + +int swSocket_unix_sendto(int server_sock, char *dst_path, char *data, uint32_t len) +{ + struct sockaddr_un addr; + bzero(&addr, sizeof(addr)); + strncpy(addr.sun_path, dst_path, sizeof(addr.sun_path)); + return swSocket_sendto_blocking(server_sock, data, len, 0, (struct sockaddr *) &addr, sizeof(addr)); +} + +int swSocket_sendto_blocking(int fd, void *__buf, size_t __n, int flag, struct sockaddr *__addr, socklen_t __addr_len) +{ + int n = 0; + + while (1) + { + n = sendto(fd, __buf, __n, flag, __addr, __addr_len); + if (n >= 0) + { + break; + } + else + { + if (errno == EINTR) + { + continue; + } + else if (errno == EAGAIN) + { + swSocket_wait(fd, 1000, SW_EVENT_WRITE); + continue; + } + else + { + break; + } + } + } + + return n; +} + +int swSocket_create(int type) +{ + int _domain; + int _type; + + switch (type) + { + case SW_SOCK_TCP: + _domain = PF_INET; + _type = SOCK_STREAM; + break; + case SW_SOCK_TCP6: + _domain = PF_INET6; + _type = SOCK_STREAM; + break; + case SW_SOCK_UDP: + _domain = PF_INET; + _type = SOCK_DGRAM; + break; + case SW_SOCK_UDP6: + _domain = PF_INET6; + _type = SOCK_DGRAM; + break; + case SW_SOCK_UNIX_DGRAM: + _domain = PF_UNIX; + _type = SOCK_DGRAM; + break; + case SW_SOCK_UNIX_STREAM: + _domain = PF_UNIX; + _type = SOCK_STREAM; + break; + default: + swWarn("unknown socket type [%d]", type); + return SW_ERR; + } + return socket(_domain, _type, 0); +} + +int swSocket_bind(int sock, int type, char *host, int *port) +{ + int ret; + + struct sockaddr_in addr_in4; + struct sockaddr_in6 addr_in6; + struct sockaddr_un addr_un; + socklen_t len; + + //SO_REUSEADDR option + int option = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int)) < 0) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SYSTEM_CALL_FAIL, "setsockopt(%d, SO_REUSEADDR) failed.", sock); + } + //reuse port +#ifdef HAVE_REUSEPORT + if (SwooleG.reuse_port) + { + if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &option, sizeof(int)) < 0) + { + swSysError("setsockopt(SO_REUSEPORT) failed."); + SwooleG.reuse_port = 0; + } + } +#endif + //unix socket + if (type == SW_SOCK_UNIX_DGRAM || type == SW_SOCK_UNIX_STREAM) + { + bzero(&addr_un, sizeof(addr_un)); + unlink(host); + addr_un.sun_family = AF_UNIX; + strncpy(addr_un.sun_path, host, sizeof(addr_un.sun_path) - 1); + ret = bind(sock, (struct sockaddr*) &addr_un, sizeof(addr_un)); + } + //IPv6 + else if (type > SW_SOCK_UDP) + { + bzero(&addr_in6, sizeof(addr_in6)); + inet_pton(AF_INET6, host, &(addr_in6.sin6_addr)); + addr_in6.sin6_port = htons(*port); + addr_in6.sin6_family = AF_INET6; + ret = bind(sock, (struct sockaddr *) &addr_in6, sizeof(addr_in6)); + if (ret == 0 && *port == 0) + { + len = sizeof(addr_in6); + if (getsockname(sock, (struct sockaddr *) &addr_in6, &len) != -1) + { + *port = ntohs(addr_in6.sin6_port); + } + } + } + //IPv4 + else + { + bzero(&addr_in4, sizeof(addr_in4)); + inet_pton(AF_INET, host, &(addr_in4.sin_addr)); + addr_in4.sin_port = htons(*port); + addr_in4.sin_family = AF_INET; + ret = bind(sock, (struct sockaddr *) &addr_in4, sizeof(addr_in4)); + if (ret == 0 && *port == 0) + { + len = sizeof(addr_in4); + if (getsockname(sock, (struct sockaddr *) &addr_in4, &len) != -1) + { + *port = ntohs(addr_in4.sin_port); + } + } + } + //bind failed + if (ret < 0) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SYSTEM_CALL_FAIL, "bind(%s:%d) failed. Error: %s [%d]", host, *port, strerror(errno), errno); + return SW_ERR; + } + + return ret; +} + +int swSocket_set_buffer_size(int fd, int buffer_size) +{ + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffer_size, sizeof(buffer_size)) < 0) + { + swSysError("setsockopt(%d, SOL_SOCKET, SO_SNDBUF, %d) failed.", fd, buffer_size); + return SW_ERR; + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size, sizeof(buffer_size)) < 0) + { + swSysError("setsockopt(%d, SOL_SOCKET, SO_RCVBUF, %d) failed.", fd, buffer_size); + return SW_ERR; + } + return SW_OK; +} + +int swSocket_set_timeout(int sock, double timeout) +{ + int ret; + struct timeval timeo; + timeo.tv_sec = (int) timeout; + timeo.tv_usec = (int) ((timeout - timeo.tv_sec) * 1000 * 1000); + ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (void *) &timeo, sizeof(timeo)); + if (ret < 0) + { + swWarn("setsockopt(SO_SNDTIMEO) failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *) &timeo, sizeof(timeo)); + if (ret < 0) + { + swWarn("setsockopt(SO_RCVTIMEO) failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + return SW_OK; +} + +int swSocket_create_server(int type, char *address, int port, int backlog) +{ +#if 0 + int type; + char host[32]; + int port = 0; + + if (strncasecmp(address, "unix:/", 6) == 0) + { + address += 5; + type = SW_SOCK_UNIX_STREAM; + } + else + { + char *port_str = strchr(address, ':'); + if (!port_str) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_INVALID_PARAMS, "invalid address[%s]", address); + return SW_ERR; + } + type = SW_SOCK_TCP6; + memcpy(host, address, port_str - address); + host[port_str - address] = 0; + port = atoi(port_str + 1); + address = host; + } +#endif + + int fd = swSocket_create(type); + if (fd < 0) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "socket() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + + if (swSocket_bind(fd, type, address, &port) < 0) + { + return SW_ERR; + } + + if (listen(fd, backlog) < 0) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "listen(%s:%d, %d) failed. Error: %s[%d]", address, port, backlog, strerror(errno), errno); + return SW_ERR; + } + + return fd; +} diff --git a/vendor/swoole/src/core/string.c b/vendor/swoole/src/core/string.c new file mode 100755 index 0000000..a4c0476 --- /dev/null +++ b/vendor/swoole/src/core/string.c @@ -0,0 +1,294 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +swString *swString_new(size_t size) +{ + swString *str = sw_malloc(sizeof(swString)); + if (str == NULL) + { + swWarn("malloc[1] failed."); + return NULL; + } + bzero(str, sizeof(swString)); + str->size = size; + str->str = sw_malloc(size); + if (str->str == NULL) + { + swSysError("malloc[2](%ld) failed.", size); + sw_free(str); + return NULL; + } + return str; +} + +void swString_print(swString *str) +{ + printf("String[length=%d,size=%d,offset=%d]=%s\n", (int) str->length, (int) str->size, (int) str->offset, + str->str); +} + +swString *swString_dup2(swString *src) +{ + swString *dst = swString_new(src->size); + if (dst) + { + swTrace("string dup2. new=%p, old=%p\n", dst, src); + dst->length = src->length; + dst->offset = src->offset; + memcpy(dst->str, src->str, src->length); + } + return dst; +} + +swString *swString_dup(const char *src_str, int length) +{ + swString *str = sw_malloc(sizeof(swString)); + if (str == NULL) + { + swWarn("malloc[1] failed."); + return NULL; + } + + bzero(str, sizeof(swString)); + str->length = length; + str->size = length + 1; + str->str = sw_malloc(str->size); + if (str->str == NULL) + { + swWarn("malloc[2] failed."); + sw_free(str); + return NULL; + } + memcpy(str->str, src_str, length + 1); + return str; +} + +int swString_append(swString *str, swString *append_str) +{ + int new_size = str->length + append_str->length; + if (new_size > str->size) + { + if (swString_extend(str, swoole_size_align(new_size * 2, sysconf(_SC_PAGESIZE))) < 0) + { + return SW_ERR; + } + } + memcpy(str->str + str->length, append_str->str, append_str->length); + str->length += append_str->length; + return SW_OK; +} + +int swString_append_int(swString *str, int value) +{ + char buf[16]; + int s_len = swoole_itoa(buf, value); + + int new_size = str->length + s_len; + if (new_size > str->size) + { + if (swString_extend(str, swoole_size_align(new_size * 2, sysconf(_SC_PAGESIZE))) < 0) + { + return SW_ERR; + } + } + + memcpy(str->str + str->length, buf, s_len); + str->length += s_len; + return SW_OK; +} + +int swString_append_ptr(swString *str, char *append_str, int length) +{ + int new_size = str->length + length; + if (new_size > str->size) + { + if (swString_extend(str, swoole_size_align(new_size * 2, sysconf(_SC_PAGESIZE))) < 0) + { + return SW_ERR; + } + } + memcpy(str->str + str->length, append_str, length); + str->length += length; + return SW_OK; +} + +int swString_write(swString *str, off_t offset, swString *write_str) +{ + int new_length = offset + write_str->length; + if (new_length > str->size) + { + if (swString_extend(str, swoole_size_align(new_length * 2, sysconf(_SC_PAGESIZE))) < 0) + { + return SW_ERR; + } + } + + memcpy(str->str + offset, write_str->str, write_str->length); + + if (new_length > str->length) + { + str->length = new_length; + } + + return SW_OK; +} + +int swString_write_ptr(swString *str, off_t offset, char *write_str, int length) +{ + int new_length = offset + length; + if (new_length > str->size) + { + if (swString_extend(str, swoole_size_align(new_length * 2, sysconf(_SC_PAGESIZE))) < 0) + { + return SW_ERR; + } + } + + memcpy(str->str + offset, write_str, length); + + if (new_length > str->length) + { + str->length = new_length; + } + + return SW_OK; +} + +int swString_extend(swString *str, size_t new_size) +{ + assert(new_size > str->size); + char *new_str = sw_realloc(str->str, new_size); + if (new_str == NULL) + { + swSysError("realloc(%ld) failed.", new_size); + return SW_ERR; + } + str->str = new_str; + str->size = new_size; + return SW_OK; +} + +char* swString_alloc(swString *str, size_t __size) +{ + if (str->length + __size < str->size) + { + if (swString_extend_align(str, str->length + __size) < 0) + { + return NULL; + } + } + char *tmp = str->str + str->length; + str->length += __size; + return tmp; +} + +uint32_t swoole_utf8_decode(u_char **p, size_t n) +{ + size_t len; + uint32_t u, i, valid; + + u = **p; + + if (u >= 0xf0) + { + u &= 0x07; + valid = 0xffff; + len = 3; + } + else if (u >= 0xe0) + { + u &= 0x0f; + valid = 0x7ff; + len = 2; + } + else if (u >= 0xc2) + { + u &= 0x1f; + valid = 0x7f; + len = 1; + } + else + { + (*p)++; + return 0xffffffff; + } + + if (n - 1 < len) + { + return 0xfffffffe; + } + + (*p)++; + + while (len) + { + i = *(*p)++; + if (i < 0x80) + { + return 0xffffffff; + } + u = (u << 6) | (i & 0x3f); + len--; + } + + if (u > valid) + { + return u; + } + + return 0xffffffff; +} + +size_t swoole_utf8_length(u_char *p, size_t n) +{ + u_char c, *last; + size_t len; + + last = p + n; + + for (len = 0; p < last; len++) + { + c = *p; + if (c < 0x80) + { + p++; + continue; + } + if (swoole_utf8_decode(&p, n) > 0x10ffff) + { + /* invalid UTF-8 */ + return n; + } + } + return len; +} + +static char characters[] = +{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', }; + +void swoole_random_string(char *buf, size_t size) +{ + int i; + for (i = 0; i < size; i++) + { + buf[i] = characters[swoole_rand(0, sizeof(characters) - 1)]; + } + buf[i] = '\0'; +} diff --git a/vendor/swoole/src/coroutine/base.cc b/vendor/swoole/src/coroutine/base.cc new file mode 100755 index 0000000..7d9c22d --- /dev/null +++ b/vendor/swoole/src/coroutine/base.cc @@ -0,0 +1,182 @@ +#include "coroutine.h" +#include "context.h" +#include <string> + +/* allocate cid for coroutine */ +typedef struct cidmap +{ + uint32_t nr_free; + char page[65536]; +} cidmap_t; + +using namespace swoole; + +struct coroutine_s +{ +public: + Context ctx; + int cid; + coroutine_s(int _cid, size_t stack_size, coroutine_func_t fn, void* private_data) : + ctx(stack_size, fn, private_data) + { + cid = _cid; + } +}; + +static struct +{ + int stack_size; + int current_cid; + int previous_cid; + struct coroutine_s *coroutines[MAX_CORO_NUM_LIMIT + 1]; + coroutine_close_t onClose; +} swCoroG = +{ SW_DEFAULT_C_STACK_SIZE, -1, -1, +{ NULL, }, NULL }; + +/* 1 <= cid <= 524288 */ +static cidmap_t cidmap = +{ MAX_CORO_NUM_LIMIT, +{ 0 } }; + +static int last_cid = -1; + +static inline int test_and_set_bit(int cid, void *addr) +{ + uint32_t mask = 1U << (cid & 0x1f); + uint32_t *p = ((uint32_t*) addr) + (cid >> 5); + uint32_t old = *p; + + *p = old | mask; + + return (old & mask) == 0; +} + +static inline void clear_bit(int cid, void *addr) +{ + uint32_t mask = 1U << (cid & 0x1f); + uint32_t *p = ((uint32_t*) addr) + (cid >> 5); + uint32_t old = *p; + + *p = old & ~mask; +} + +/* find next free cid */ +static inline int find_next_zero_bit(void *addr, int cid) +{ + uint32_t *p; + uint32_t mask; + int mark = cid; + + cid++; + cid &= 0x7ffff; + while (cid != mark) + { + mask = 1U << (cid & 0x1f); + p = ((uint32_t*) addr) + (cid >> 5); + + if ((~(*p) & mask)) + { + break; + } + ++cid; + cid &= 0x7fff; + } + + return cid; +} + +static inline int alloc_cidmap() +{ + int cid; + + if (cidmap.nr_free == 0) + { + return -1; + } + + cid = find_next_zero_bit(&cidmap.page, last_cid); + if (test_and_set_bit(cid, &cidmap.page)) + { + --cidmap.nr_free; + last_cid = cid; + return cid + 1; + } + + return -1; +} + +static inline void free_cidmap(int cid) +{ + cid--; + cidmap.nr_free++; + clear_bit(cid, &cidmap.page); +} + +int coroutine_create(coroutine_func_t fn, void* args) +{ + int cid = alloc_cidmap(); + if (unlikely(cid == -1)) + { + swWarn("alloc_cidmap failed"); + return CORO_LIMIT; + } + + coroutine_t *co = new coroutine_t(cid, swCoroG.stack_size, fn, args); + swCoroG.coroutines[cid] = co; + swCoroG.previous_cid = swCoroG.current_cid; + swCoroG.current_cid = cid; + co->ctx.SwapIn(); + if (co->ctx.end) + { + if (swCoroG.onClose) + { + swCoroG.onClose(); + } + coroutine_release(co); + } + return cid; +} + +void coroutine_yield(coroutine_t *co) +{ + swCoroG.current_cid = swCoroG.previous_cid; + co->ctx.SwapOut(); +} + +void coroutine_resume(coroutine_t *co) +{ + swCoroG.previous_cid = swCoroG.current_cid; + swCoroG.current_cid = co->cid; + co->ctx.SwapIn(); + if (co->ctx.end) + { + if (swCoroG.onClose) + { + swCoroG.onClose(); + } + coroutine_release(co); + } +} + +void coroutine_release(coroutine_t *co) +{ + free_cidmap(co->cid); + swCoroG.coroutines[co->cid] = NULL; + delete co; +} + +void coroutine_set_close(coroutine_close_t func) +{ + swCoroG.onClose = func; +} + +coroutine_t* coroutine_get_by_id(int cid) +{ + return swCoroG.coroutines[cid]; +} + +int coroutine_get_cid() +{ + return swCoroG.current_cid; +} diff --git a/vendor/swoole/src/coroutine/boost.cc b/vendor/swoole/src/coroutine/boost.cc new file mode 100755 index 0000000..1080b40 --- /dev/null +++ b/vendor/swoole/src/coroutine/boost.cc @@ -0,0 +1,76 @@ +#include "swoole.h" +#include "context.h" + +#if USE_BOOST_CONTEXT + +using namespace swoole; + +Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) : + fn_(fn), stack_size_(stack_size), private_data_(private_data) +{ + BOOST_ASSERT(boost::context::stack_traits::minimum_size() <= stack_size_); + BOOST_ASSERT( + boost::context::stack_traits::is_unbounded() + || (boost::context::stack_traits::maximum_size() >= stack_size_)); + + protect_page_ = 0; + end = false; + swap_ctx_ = NULL; + + stack_ = (char*) sw_malloc(stack_size_); + swDebug("alloc stack: size=%u, ptr=%p.", stack_size_, stack_); + + void* sp = (void*) ((char*) stack_ + stack_size_); +#ifdef USE_VALGRIND + valgrind_stack_id = VALGRIND_STACK_REGISTER(sp, stack_); +#endif + ctx_ = boost::context::make_fcontext(sp, stack_size_, (void (*)(intptr_t))&context_func); + + uint32_t protect_page = get_protect_stack_page(); + if (protect_page) + { + if (protect_stack(stack_, stack_size_, protect_page)) + { + protect_page_ = protect_page; + } + } +} + +Context::~Context() +{ + if (stack_) + { + swDebug("free stack: ptr=%p", stack_); + if (protect_page_) + { + unprotect_stack(stack_, protect_page_); + } +#if defined(USE_VALGRIND) + VALGRIND_STACK_DEREGISTER(valgrind_stack_id); +#endif + sw_free(stack_); + stack_ = NULL; + } +} + +bool Context::SwapIn() +{ + boost::context::jump_fcontext(&swap_ctx_, ctx_, (intptr_t) this, true); + return true; +} + +bool Context::SwapOut() +{ + boost::context::jump_fcontext(&ctx_, swap_ctx_, (intptr_t) this, true); + return true; +} + +void Context::context_func(void *arg) +{ + Context* _this = (Context*) arg; + _this->fn_(_this->private_data_); + _this->end = true; + _this->SwapOut(); +} + +#endif diff --git a/vendor/swoole/src/coroutine/context.cc b/vendor/swoole/src/coroutine/context.cc new file mode 100755 index 0000000..c5ed5ae --- /dev/null +++ b/vendor/swoole/src/coroutine/context.cc @@ -0,0 +1,71 @@ +#include "swoole.h" +#include "context.h" + +#ifndef SW_NO_USE_ASM_CONTEXT + +using namespace swoole; + +Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) : + fn_(fn), stack_size_(stack_size), private_data_(private_data) +{ + protect_page_ = 0; + end = false; + swap_ctx_ = NULL; + + stack_ = (char*) sw_malloc(stack_size_); + swDebug("alloc stack: size=%u, ptr=%p.", stack_size_, stack_); + + void* sp = (void*) ((char*) stack_ + stack_size_); +#ifdef USE_VALGRIND + valgrind_stack_id = VALGRIND_STACK_REGISTER(sp, stack_); +#endif + ctx_ = make_fcontext(sp, stack_size_, (void (*)(intptr_t))&context_func); + + uint32_t protect_page = get_protect_stack_page(); + if (protect_page) + { + if (protect_stack(stack_, stack_size_, protect_page)) + { + protect_page_ = protect_page; + } + } +} + +Context::~Context() +{ + if (stack_) + { + swDebug("free stack: ptr=%p", stack_); + if (protect_page_) + { + unprotect_stack(stack_, protect_page_); + } +#if defined(USE_VALGRIND) + VALGRIND_STACK_DEREGISTER(valgrind_stack_id); +#endif + sw_free(stack_); + stack_ = NULL; + } +} + +bool Context::SwapIn() +{ + jump_fcontext(&swap_ctx_, ctx_, (intptr_t) this, true); + return true; +} + +bool Context::SwapOut() +{ + jump_fcontext(&ctx_, swap_ctx_, (intptr_t) this, true); + return true; +} + +void Context::context_func(void *arg) +{ + Context *_this = (Context *) arg; + _this->fn_(_this->private_data_); + _this->end = true; + _this->SwapOut(); +} + +#endif diff --git a/vendor/swoole/src/coroutine/ucontext.cc b/vendor/swoole/src/coroutine/ucontext.cc new file mode 100755 index 0000000..1cf3687 --- /dev/null +++ b/vendor/swoole/src/coroutine/ucontext.cc @@ -0,0 +1,79 @@ +#include "swoole.h" +#include "context.h" + +#if USE_UCONTEXT + +using namespace swoole; + +Context::Context(size_t stack_size, coroutine_func_t fn, void* private_data) : + fn_(fn), stack_size_(stack_size), private_data_(private_data) +{ + if (-1 == getcontext(&ctx_)) + { + swoole_throw_error(SW_ERROR_CO_GETCONTEXT_FAILED); + return; + } + + protect_page_ = 0; + end = false; + + stack_ = (char*) sw_malloc(stack_size); + swDebug("alloc stack: size=%lu, ptr=%p", stack_size, stack_); + + ctx_.uc_stack.ss_sp = stack_; + ctx_.uc_stack.ss_size = stack_size; + ctx_.uc_link = NULL; + +#if defined(USE_VALGRIND) + valgrind_stack_id = VALGRIND_STACK_REGISTER(static_cast<char *>(stack_) + stack_size, stack_); +#endif + + makecontext(&ctx_, (void (*)(void))&context_func, 1, this); + + uint32_t protect_page = get_protect_stack_page(); + if (protect_page) + { + if (protect_stack(stack_, stack_size, protect_page)) + { + protect_page_ = protect_page; + } + } +} + +Context::~Context() +{ + if (stack_) + { + swDebug("free stack: ptr=%p", stack_); + if (protect_page_) + { + unprotect_stack(stack_, protect_page_); + } + +#if defined(USE_VALGRIND) + VALGRIND_STACK_DEREGISTER(valgrind_stack_id); +#endif + sw_free(stack_); + stack_ = NULL; + } +} + +bool Context::SwapIn() +{ + return 0 == swapcontext(&swap_ctx_, &ctx_); +} + +bool Context::SwapOut() +{ + return 0 == swapcontext(&ctx_, &swap_ctx_); +} + +void Context::context_func(void *arg) +{ + Context *_this = (Context *) arg; + _this->fn_(_this->private_data_); + _this->end = true; + _this->SwapOut(); +} + +#endif diff --git a/vendor/swoole/src/factory/Factory.c b/vendor/swoole/src/factory/Factory.c new file mode 100755 index 0000000..525151d --- /dev/null +++ b/vendor/swoole/src/factory/Factory.c @@ -0,0 +1,170 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" + +int swFactory_create(swFactory *factory) +{ + factory->dispatch = swFactory_dispatch; + factory->finish = swFactory_finish; + factory->start = swFactory_start; + factory->shutdown = swFactory_shutdown; + factory->end = swFactory_end; + factory->notify = swFactory_notify; + return SW_OK; +} + +int swFactory_start(swFactory *factory) +{ + SwooleWG.run_always = 1; + return SW_OK; +} + +int swFactory_shutdown(swFactory *factory) +{ + return SW_OK; +} + +int swFactory_dispatch(swFactory *factory, swDispatchData *task) +{ + swServer *serv = factory->ptr; + factory->last_from_id = task->data.info.from_id; + + if (swEventData_is_stream(task->data.info.type)) + { + swConnection *conn = swServer_connection_get(serv, task->data.info.fd); + if (conn == NULL || conn->active == 0) + { + swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, task->data.info.fd); + return SW_ERR; + } + //server active close, discard data. + if (conn->closed) + { + swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", task->data.info.type, + task->data.info.fd); + return SW_OK; + } + //converted fd to session_id + task->data.info.fd = conn->session_id; + task->data.info.from_fd = conn->from_fd; + } + return swWorker_onTask(factory, &task->data); +} + +int swFactory_notify(swFactory *factory, swDataHead *info) +{ + swServer *serv = factory->ptr; + swConnection *conn = swServer_connection_get(serv, info->fd); + if (conn == NULL || conn->active == 0) + { + swWarn("dispatch[type=%d] failed, connection#%d is not active.", info->type, info->fd); + return SW_ERR; + } + //server active close, discard data. + if (conn->closed) + { + swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", info->type, info->fd); + return SW_OK; + } + //converted fd to session_id + info->fd = conn->session_id; + info->from_fd = conn->from_fd; + return swWorker_onTask(factory, (swEventData *) info); +} + +int swFactory_end(swFactory *factory, int fd) +{ + swServer *serv = factory->ptr; + swSendData _send; + swDataHead info; + + bzero(&_send, sizeof(_send)); + _send.info.fd = fd; + _send.info.len = 0; + _send.info.type = SW_EVENT_CLOSE; + + swConnection *conn = swWorker_get_connection(serv, fd); + if (conn == NULL || conn->active == 0) + { + //swWarn("can not close. Connection[%d] not found.", _send.info.fd); + return SW_ERR; + } + else if (conn->close_force) + { + goto do_close; + } + else if (conn->closing) + { + swWarn("The connection[%d] is closing.", fd); + return SW_ERR; + } + else if (conn->closed) + { + return SW_ERR; + } + else + { + do_close: + conn->closing = 1; + if (serv->onClose != NULL) + { + info.fd = fd; + if (conn->close_actively) + { + info.from_id = -1; + } + else + { + info.from_id = conn->from_id; + } + info.from_fd = conn->from_fd; + serv->onClose(serv, &info); + } + conn->closing = 0; + conn->closed = 1; + conn->close_errno = 0; + + if (swBuffer_empty(conn->out_buffer) || conn->removed) + { + swReactor *reactor = &serv->reactor_threads[SwooleTG.id].reactor; + return swReactorThread_close(reactor, conn->fd); + } + else + { + swBuffer_trunk *trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0); + trunk->store.data.val1 = _send.info.type; + return SW_OK; + } + } +} + +int swFactory_finish(swFactory *factory, swSendData *resp) +{ + if (resp->length == 0) + { + resp->length = resp->info.len; + } + if (swReactorThread_send(resp) < 0) + { + return SW_ERR; + } + else + { + return SW_OK; + } +} diff --git a/vendor/swoole/src/factory/FactoryProcess.c b/vendor/swoole/src/factory/FactoryProcess.c new file mode 100755 index 0000000..e4565fc --- /dev/null +++ b/vendor/swoole/src/factory/FactoryProcess.c @@ -0,0 +1,335 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" + +#include <signal.h> +#include <sys/time.h> + +static int swFactoryProcess_start(swFactory *factory); +static int swFactoryProcess_notify(swFactory *factory, swDataHead *event); +static int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *buf); +static int swFactoryProcess_finish(swFactory *factory, swSendData *data); +static int swFactoryProcess_shutdown(swFactory *factory); +static int swFactoryProcess_end(swFactory *factory, int fd); + +int swFactoryProcess_create(swFactory *factory, int worker_num) +{ + swFactoryProcess *object; + object = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swFactoryProcess)); + if (object == NULL) + { + swWarn("[Master] malloc[object] failed"); + return SW_ERR; + } + + factory->object = object; + factory->dispatch = swFactoryProcess_dispatch; + factory->finish = swFactoryProcess_finish; + factory->start = swFactoryProcess_start; + factory->notify = swFactoryProcess_notify; + factory->shutdown = swFactoryProcess_shutdown; + factory->end = swFactoryProcess_end; + + return SW_OK; +} + +static int swFactoryProcess_shutdown(swFactory *factory) +{ + int status; + swServer *serv = factory->ptr; + + if (swKill(serv->gs->manager_pid, SIGTERM) < 0) + { + swSysError("kill(%d) failed.", serv->gs->manager_pid); + } + + if (swWaitpid(serv->gs->manager_pid, &status, 0) < 0) + { + swSysError("waitpid(%d) failed.", serv->gs->manager_pid); + } + + return SW_OK; +} + +static int swFactoryProcess_start(swFactory *factory) +{ + int i; + swServer *serv = factory->ptr; + swWorker *worker; + + for (i = 0; i < serv->worker_num; i++) + { + worker = swServer_get_worker(serv, i); + if (swWorker_create(worker) < 0) + { + return SW_ERR; + } + } + + serv->reactor_pipe_num = serv->worker_num / serv->reactor_num; + + //必须先启动manager进程组,否则会带线程fork + if (swManager_start(factory) < 0) + { + swWarn("swFactoryProcess_manager_start failed."); + return SW_ERR; + } + //主进程需要设置为直写模式 + factory->finish = swFactory_finish; + return SW_OK; +} + +static __thread struct +{ + long target_worker_id; + swDataHead _send; +} sw_notify_data; + +/** + * [ReactorThread] notify info to worker process + */ +static int swFactoryProcess_notify(swFactory *factory, swDataHead *ev) +{ + memcpy(&sw_notify_data._send, ev, sizeof(swDataHead)); + sw_notify_data._send.len = 0; + sw_notify_data.target_worker_id = -1; + return factory->dispatch(factory, (swDispatchData *) &sw_notify_data); +} + +/** + * [ReactorThread] dispatch request to worker + */ +static int swFactoryProcess_dispatch(swFactory *factory, swDispatchData *task) +{ + uint32_t send_len = sizeof(task->data.info) + task->data.info.len; + int target_worker_id; + swServer *serv = SwooleG.serv; + int fd = task->data.info.fd; + + if (task->target_worker_id < 0) + { +#ifndef SW_USE_RINGBUFFER + if (SwooleTG.factory_lock_target) + { + if (SwooleTG.factory_target_worker < 0) + { + target_worker_id = swServer_worker_schedule(serv, fd, &task->data); + SwooleTG.factory_target_worker = target_worker_id; + } + else + { + target_worker_id = SwooleTG.factory_target_worker; + } + } + else +#endif + { + target_worker_id = swServer_worker_schedule(serv, fd, &task->data); + } + } + else + { + target_worker_id = task->target_worker_id; + } + //discard the data packet. + if (target_worker_id < 0) + { + return SW_OK; + } + + if (swEventData_is_stream(task->data.info.type)) + { + swConnection *conn = swServer_connection_get(serv, fd); + if (conn == NULL || conn->active == 0) + { + swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, fd); + return SW_ERR; + } + //server active close, discard data. + if (conn->closed) + { + //Connection has been clsoed by server + if (!(task->data.info.type == SW_EVENT_CLOSE && conn->close_force)) + { + return SW_OK; + } + } + //converted fd to session_id + task->data.info.fd = conn->session_id; + task->data.info.from_fd = conn->from_fd; + } + + return swReactorThread_send2worker((void *) &(task->data), send_len, target_worker_id); +} + +/** + * worker: send to client + */ +static int swFactoryProcess_finish(swFactory *factory, swSendData *resp) +{ + int ret, sendn; + swServer *serv = factory->ptr; + int session_id = resp->info.fd; + + swConnection *conn; + if (resp->info.type != SW_EVENT_CLOSE) + { + conn = swServer_connection_verify(serv, session_id); + } + else + { + conn = swServer_connection_verify_no_ssl(serv, session_id); + } + if (!conn) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "connection[fd=%d] does not exists.", session_id); + return SW_ERR; + } + else if ((conn->closed || conn->removed) && resp->info.type != SW_EVENT_CLOSE) + { + int _len = resp->length > 0 ? resp->length : resp->info.len; + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "send %d byte failed, because connection[fd=%d] is closed.", _len, session_id); + return SW_ERR; + } + else if (conn->overflow) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_OUTPUT_BUFFER_OVERFLOW, "send failed, connection[fd=%d] output buffer has been overflowed.", session_id); + return SW_ERR; + } + + swEventData ev_data; + ev_data.info.fd = session_id; + ev_data.info.type = resp->info.type; + swWorker *worker = swServer_get_worker(serv, SwooleWG.id); + + /** + * Big response, use shared memory + */ + if (resp->length > 0) + { + if (worker == NULL || worker->send_shm == NULL) + { + goto pack_data; + } + + //worker process + if (SwooleG.main_reactor) + { + int _pipe_fd = swWorker_get_send_pipe(serv, session_id, conn->from_id); + swConnection *_pipe_socket = swReactor_get(SwooleG.main_reactor, _pipe_fd); + + //cannot use send_shm + if (!swBuffer_empty(_pipe_socket->out_buffer)) + { + pack_data: + if (swTaskWorker_large_pack(&ev_data, resp->data, resp->length) < 0) + { + return SW_ERR; + } + ev_data.info.from_fd = SW_RESPONSE_TMPFILE; + goto send_to_reactor_thread; + } + } + + swPackage_response response; + response.length = resp->length; + response.worker_id = SwooleWG.id; + ev_data.info.from_fd = SW_RESPONSE_SHM; + ev_data.info.len = sizeof(response); + memcpy(ev_data.data, &response, sizeof(response)); + + swTrace("[Worker] big response, length=%d|worker_id=%d", response.length, response.worker_id); + + worker->lock.lock(&worker->lock); + memcpy(worker->send_shm, resp->data, resp->length); + } + else + { + //copy data + memcpy(ev_data.data, resp->data, resp->info.len); + + ev_data.info.len = resp->info.len; + ev_data.info.from_fd = SW_RESPONSE_SMALL; + } + + send_to_reactor_thread: ev_data.info.from_id = conn->from_id; + sendn = ev_data.info.len + sizeof(resp->info); + + swTrace("[Worker] send: sendn=%d|type=%d|content=%s", sendn, resp->info.type, resp->data); + ret = swWorker_send2reactor(&ev_data, sendn, session_id); + if (ret < 0) + { + swWarn("sendto to reactor failed. Error: %s [%d]", strerror(errno), errno); + } + return ret; +} + +static int swFactoryProcess_end(swFactory *factory, int fd) +{ + swServer *serv = factory->ptr; + swSendData _send; + swDataHead info; + + bzero(&_send, sizeof(_send)); + _send.info.fd = fd; + _send.info.len = 0; + _send.info.type = SW_EVENT_CLOSE; + + swConnection *conn = swWorker_get_connection(serv, fd); + if (conn == NULL || conn->active == 0) + { + SwooleG.error = SW_ERROR_SESSION_NOT_EXIST; + return SW_ERR; + } + else if (conn->close_force) + { + goto do_close; + } + else if (conn->closing) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSING, "The connection[%d] is closing.", fd); + return SW_ERR; + } + else if (conn->closed) + { + return SW_ERR; + } + else + { + do_close: + conn->closing = 1; + if (serv->onClose != NULL) + { + info.fd = fd; + if (conn->close_actively) + { + info.from_id = -1; + } + else + { + info.from_id = conn->from_id; + } + info.from_fd = conn->from_fd; + serv->onClose(serv, &info); + } + conn->closing = 0; + conn->closed = 1; + conn->close_errno = 0; + return factory->finish(factory, &_send); + } +} diff --git a/vendor/swoole/src/factory/FactoryThread.c b/vendor/swoole/src/factory/FactoryThread.c new file mode 100755 index 0000000..92de40c --- /dev/null +++ b/vendor/swoole/src/factory/FactoryThread.c @@ -0,0 +1,245 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" + +static int swFactoryThread_dispatch(swFactory *factory, swDispatchData *buf); +static int swFactoryThread_finish(swFactory *factory, swSendData *data); +static int swFactoryThread_shutdown(swFactory *factory); +static int swFactoryThread_start(swFactory *factory); + +typedef struct _swWorkerThread +{ + pthread_t ptid; //线程ID + int pipe_num; //writer thread's pipe num + int *pipes; //worker pipes + int c_pipe; //current pipe + swReactor reactor; + swShareMemory shm; //共享内存 + swPipe evfd; //eventfd +} swWorkerThread; + +typedef struct _swFactoryThread +{ + int worker_num; + swThreadPool workers; +} swFactoryThread; + +static int swFactoryThread_onTask(swThreadPool *pool, void *data, int len); +static void swFactoryThread_onStart(swThreadPool *pool, int id); +static void swFactoryThread_onStop(swThreadPool *pool, int id); + +int swFactoryThread_create(swFactory *factory, int worker_num) +{ + swFactoryThread *object; + swServer *serv = factory->ptr; + + object = sw_calloc(worker_num, sizeof(swFactoryThread)); + if (object == NULL) + { + swWarn("malloc[0] failed"); + return SW_ERR; + } + + if (swThreadPool_create(&object->workers, worker_num) < 0) + { + sw_free(object); + return SW_ERR; + } + + int i; + swReactorThread *thread; + for (i = 0; i < serv->reactor_num; i++) + { + thread = swServer_get_thread(serv, i); + swMutex_create(&thread->lock, 0); + } + + object->worker_num = worker_num; + + factory->object = object; + factory->dispatch = swFactoryThread_dispatch; + factory->finish = swFactoryThread_finish; + factory->end = swFactory_end; + factory->start = swFactoryThread_start; + factory->shutdown = swFactoryThread_shutdown; + factory->notify = swFactory_notify; + + object->workers.onStart = swFactoryThread_onStart; + object->workers.onStop = swFactoryThread_onStop; + object->workers.onTask = swFactoryThread_onTask; + + object->workers.ptr1 = factory->ptr; + object->workers.ptr2 = factory; + + return SW_OK; +} + +static int swFactoryThread_start(swFactory *factory) +{ + swFactoryThread *object = factory->object; + SwooleWG.run_always = 1; + swThreadPool_run(&object->workers); + return SW_OK; +} + +static int swFactoryThread_shutdown(swFactory *factory) +{ + SwooleG.running = 0; + swFactoryThread *object = factory->object; + swThreadPool_free(&object->workers); + sw_free(object); + return SW_OK; +} + +static int swFactoryThread_finish(swFactory *factory, swSendData *_send) +{ + swServer *serv = SwooleG.serv; + uint32_t session_id = _send->info.fd; + + if (_send->length == 0) + { + _send->length = _send->info.len; + } + + swConnection *conn = swServer_connection_verify(serv, session_id); + if (!conn) + { + if (_send->info.type == SW_EVENT_TCP) + { + swWarn("send %d byte failed, session#%d is closed.", _send->length, session_id); + } + else + { + swWarn("send [%d] failed, session#%d is closed.", _send->info.type, session_id); + } + return SW_ERR; + } + + return swSocket_write_blocking(conn->fd, _send->data, _send->length); +} + +/** + * 写线程模式 + */ +int swFactoryThread_dispatch(swFactory *factory, swDispatchData *task) +{ + swServer *serv = SwooleG.serv; + swFactoryThread *object = factory->object; + + if (swEventData_is_stream(task->data.info.type)) + { + swConnection *conn = swServer_connection_get(serv, task->data.info.fd); + if (conn == NULL || conn->active == 0) + { + swWarn("dispatch[type=%d] failed, connection#%d is not active.", task->data.info.type, task->data.info.fd); + return SW_ERR; + } + //server active close, discard data. + if (conn->closed) + { + swWarn("dispatch[type=%d] failed, connection#%d is closed by server.", task->data.info.type, + task->data.info.fd); + return SW_OK; + } + //converted fd to session_id + task->data.info.fd = conn->session_id; + task->data.info.from_fd = conn->from_fd; + } + + int mem_size = sizeof(swDataHead) + task->data.info.len + 1; + char *data = sw_malloc(mem_size); + if (data == NULL) + { + swWarn("malloc failed"); + return SW_ERR; + } + + memcpy(data, &(task->data), mem_size); + data[sizeof(swDataHead) + task->data.info.len] = 0; + + if (swThreadPool_dispatch(&object->workers, (void *) data, 0) < 0) + { + swWarn("RingQueue is full"); + return SW_ERR; + } + else + { + return SW_OK; + } +} + +static void swFactoryThread_onStart(swThreadPool *pool, int id) +{ + swServer *serv = pool->ptr1; + + if (serv->onWorkerStart != NULL) + { + serv->onWorkerStart(serv, id); + } + + swSignal_none(); + + SwooleTG.id = serv->reactor_num + id; + SwooleTG.type = SW_THREAD_WORKER; + + SwooleTG.buffer_input = swServer_create_worker_buffer(serv); + if (!SwooleTG.buffer_input) + { + return; + } + + //cpu affinity setting +#ifdef HAVE_CPU_AFFINITY + if (serv->open_cpu_affinity) + { + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + if (serv->cpu_affinity_available_num) + { + CPU_SET(serv->cpu_affinity_available[id % serv->cpu_affinity_available_num], &cpu_set); + } + else + { + CPU_SET(id % SW_CPU_NUM, &cpu_set); + } + if (0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set)) + { + swWarn("pthread_setaffinity_np() failed"); + } + } +#endif + +} + +static void swFactoryThread_onStop(swThreadPool *pool, int id) +{ + swServer *serv = SwooleG.serv; + + if (serv->onWorkerStop != NULL) + { + serv->onWorkerStop(serv, id); + } +} + +static int swFactoryThread_onTask(swThreadPool *pool, void *data, int len) +{ + swFactory *factory = pool->ptr2; + int ret = swWorker_onTask(factory, (swEventData*) data); + sw_free(data); + return ret; +} diff --git a/vendor/swoole/src/lock/AtomicLock.c b/vendor/swoole/src/lock/AtomicLock.c new file mode 100755 index 0000000..5cab5e1 --- /dev/null +++ b/vendor/swoole/src/lock/AtomicLock.c @@ -0,0 +1,49 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +static int swAtomicLock_lock(swLock *lock); +static int swAtomicLock_unlock(swLock *lock); +static int swAtomicLock_trylock(swLock *lock); + +int swAtomicLock_create(swLock *lock, int spin) +{ + bzero(lock, sizeof(swLock)); + lock->type = SW_ATOMLOCK; + lock->object.atomlock.spin = spin; + lock->lock = swAtomicLock_lock; + lock->unlock = swAtomicLock_unlock; + lock->trylock = swAtomicLock_trylock; + return SW_OK; +} + +static int swAtomicLock_lock(swLock *lock) +{ + sw_spinlock(&lock->object.atomlock.lock_t); + return SW_OK; +} + +static int swAtomicLock_unlock(swLock *lock) +{ + return lock->object.atomlock.lock_t = 0; +} + +static int swAtomicLock_trylock(swLock *lock) +{ + sw_atomic_t *atomic = &lock->object.atomlock.lock_t; + return (*(atomic) == 0 && sw_atomic_cmp_set(atomic, 0, 1)); +} diff --git a/vendor/swoole/src/lock/Cond.c b/vendor/swoole/src/lock/Cond.c new file mode 100755 index 0000000..4258de7 --- /dev/null +++ b/vendor/swoole/src/lock/Cond.c @@ -0,0 +1,89 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static int swCond_notify(swCond *cond); +static int swCond_broadcast(swCond *cond); +static int swCond_timewait(swCond *cond, long sec, long nsec); +static int swCond_wait(swCond *cond); +static int swCond_lock(swCond *cond); +static int swCond_unlock(swCond *cond); +static void swCond_free(swCond *cond); + +int swCond_create(swCond *cond) +{ + if (pthread_cond_init(&cond->_cond, NULL) < 0) + { + swWarn("pthread_cond_init fail. Error: %s [%d]", strerror(errno), errno); + return SW_ERR; + } + if (swMutex_create(&cond->_lock, 0) < 0) + { + return SW_ERR; + } + + cond->notify = swCond_notify; + cond->broadcast = swCond_broadcast; + cond->timewait = swCond_timewait; + cond->wait = swCond_wait; + cond->lock = swCond_lock; + cond->unlock = swCond_unlock; + cond->free = swCond_free; + + return SW_OK; +} + +static int swCond_notify(swCond *cond) +{ + return pthread_cond_signal(&cond->_cond); +} + +static int swCond_broadcast(swCond *cond) +{ + return pthread_cond_broadcast(&cond->_cond); +} + +static int swCond_timewait(swCond *cond, long sec, long nsec) +{ + struct timespec timeo; + + timeo.tv_sec = sec; + timeo.tv_nsec = nsec; + + return pthread_cond_timedwait(&cond->_cond, &cond->_lock.object.mutex._lock, &timeo); +} + +static int swCond_wait(swCond *cond) +{ + return pthread_cond_wait(&cond->_cond, &cond->_lock.object.mutex._lock); +} + +static int swCond_lock(swCond *cond) +{ + return cond->_lock.lock(&cond->_lock); +} + +static int swCond_unlock(swCond *cond) +{ + return cond->_lock.unlock(&cond->_lock); +} + +static void swCond_free(swCond *cond) +{ + pthread_cond_destroy(&cond->_cond); + cond->_lock.free(&cond->_lock); +} diff --git a/vendor/swoole/src/lock/FileLock.c b/vendor/swoole/src/lock/FileLock.c new file mode 100755 index 0000000..c31afb1 --- /dev/null +++ b/vendor/swoole/src/lock/FileLock.c @@ -0,0 +1,73 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static int swFileLock_lock_rd(swLock *lock); +static int swFileLock_lock_rw(swLock *lock); +static int swFileLock_unlock(swLock *lock); +static int swFileLock_trylock_rw(swLock *lock); +static int swFileLock_trylock_rd(swLock *lock); +static int swFileLock_free(swLock *lock); + +int swFileLock_create(swLock *lock, int fd) +{ + bzero(lock, sizeof(swLock)); + lock->type = SW_FILELOCK; + lock->object.filelock.fd = fd; + lock->lock_rd = swFileLock_lock_rd; + lock->lock = swFileLock_lock_rw; + lock->trylock_rd = swFileLock_trylock_rd; + lock->trylock = swFileLock_trylock_rw; + lock->unlock = swFileLock_unlock; + lock->free = swFileLock_free; + return 0; +} + +static int swFileLock_lock_rd(swLock *lock) +{ + lock->object.filelock.lock_t.l_type = F_RDLCK; + return fcntl(lock->object.filelock.fd, F_SETLKW, &lock->object.filelock); +} + +static int swFileLock_lock_rw(swLock *lock) +{ + lock->object.filelock.lock_t.l_type = F_WRLCK; + return fcntl(lock->object.filelock.fd, F_SETLKW, &lock->object.filelock); +} + +static int swFileLock_unlock(swLock *lock) +{ + lock->object.filelock.lock_t.l_type = F_UNLCK; + return fcntl(lock->object.filelock.fd, F_SETLKW, &lock->object.filelock); +} + +static int swFileLock_trylock_rw(swLock *lock) +{ + lock->object.filelock.lock_t.l_type = F_WRLCK; + return fcntl(lock->object.filelock.fd, F_SETLK, &lock->object.filelock); +} + +static int swFileLock_trylock_rd(swLock *lock) +{ + lock->object.filelock.lock_t.l_type = F_RDLCK; + return fcntl(lock->object.filelock.fd, F_SETLK, &lock->object.filelock); +} + +static int swFileLock_free(swLock *lock) +{ + return close(lock->object.filelock.fd); +} diff --git a/vendor/swoole/src/lock/Mutex.c b/vendor/swoole/src/lock/Mutex.c new file mode 100755 index 0000000..c489207 --- /dev/null +++ b/vendor/swoole/src/lock/Mutex.c @@ -0,0 +1,100 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static int swMutex_lock(swLock *lock); +static int swMutex_unlock(swLock *lock); +static int swMutex_trylock(swLock *lock); +static int swMutex_free(swLock *lock); + +int swMutex_create(swLock *lock, int use_in_process) +{ + int ret; + bzero(lock, sizeof(swLock)); + lock->type = SW_MUTEX; + pthread_mutexattr_init(&lock->object.mutex.attr); + if (use_in_process == 1) + { + pthread_mutexattr_setpshared(&lock->object.mutex.attr, PTHREAD_PROCESS_SHARED); + } + if ((ret = pthread_mutex_init(&lock->object.mutex._lock, &lock->object.mutex.attr)) < 0) + { + return SW_ERR; + } + lock->lock = swMutex_lock; + lock->unlock = swMutex_unlock; + lock->trylock = swMutex_trylock; + lock->free = swMutex_free; + return SW_OK; +} + +static int swMutex_lock(swLock *lock) +{ + return pthread_mutex_lock(&lock->object.mutex._lock); +} + +static int swMutex_unlock(swLock *lock) +{ + return pthread_mutex_unlock(&lock->object.mutex._lock); +} + +static int swMutex_trylock(swLock *lock) +{ + return pthread_mutex_trylock(&lock->object.mutex._lock); +} + +#ifdef HAVE_MUTEX_TIMEDLOCK +int swMutex_lockwait(swLock *lock, int timeout_msec) +{ + struct timespec timeo; + timeo.tv_sec = timeout_msec / 1000; + timeo.tv_nsec = (timeout_msec - timeo.tv_sec * 1000) * 1000 * 1000; + return pthread_mutex_timedlock(&lock->object.mutex._lock, &timeo); +} +#else +int swMutex_lockwait(swLock *lock, int timeout_msec) +{ + int sub = 1; + int sleep_ms = 1000; + + if (timeout_msec > 100) + { + sub = 10; + sleep_ms = 10000; + } + + while( timeout_msec > 0) + { + if (pthread_mutex_trylock(&lock->object.mutex._lock) == 0) + { + return 0; + } + else + { + usleep(sleep_ms); + timeout_msec -= sub; + } + } + return ETIMEDOUT; +} +#endif + +static int swMutex_free(swLock *lock) +{ + pthread_mutexattr_destroy(&lock->object.mutex.attr); + return pthread_mutex_destroy(&lock->object.mutex._lock); +} diff --git a/vendor/swoole/src/lock/RWLock.c b/vendor/swoole/src/lock/RWLock.c new file mode 100755 index 0000000..d19003c --- /dev/null +++ b/vendor/swoole/src/lock/RWLock.c @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef HAVE_RWLOCK + +static int swRWLock_lock_rd(swLock *lock); +static int swRWLock_lock_rw(swLock *lock); +static int swRWLock_unlock(swLock *lock); +static int swRWLock_trylock_rw(swLock *lock); +static int swRWLock_trylock_rd(swLock *lock); +static int swRWLock_free(swLock *lock); + +int swRWLock_create(swLock *lock, int use_in_process) +{ + int ret; + bzero(lock, sizeof(swLock)); + lock->type = SW_RWLOCK; + pthread_rwlockattr_init(&lock->object.rwlock.attr); + if (use_in_process == 1) + { + pthread_rwlockattr_setpshared(&lock->object.rwlock.attr, PTHREAD_PROCESS_SHARED); + } + if ((ret = pthread_rwlock_init(&lock->object.rwlock._lock, &lock->object.rwlock.attr)) < 0) + { + return SW_ERR; + } + lock->lock_rd = swRWLock_lock_rd; + lock->lock = swRWLock_lock_rw; + lock->unlock = swRWLock_unlock; + lock->trylock = swRWLock_trylock_rw; + lock->trylock_rd = swRWLock_trylock_rd; + lock->free = swRWLock_free; + return SW_OK; +} + +static int swRWLock_lock_rd(swLock *lock) +{ + return pthread_rwlock_rdlock(&lock->object.rwlock._lock); +} + +static int swRWLock_lock_rw(swLock *lock) +{ + return pthread_rwlock_wrlock(&lock->object.rwlock._lock); +} + +static int swRWLock_unlock(swLock *lock) +{ + return pthread_rwlock_unlock(&lock->object.rwlock._lock); +} + +static int swRWLock_trylock_rd(swLock *lock) +{ + return pthread_rwlock_tryrdlock(&lock->object.rwlock._lock); +} + +static int swRWLock_trylock_rw(swLock *lock) +{ + return pthread_rwlock_trywrlock(&lock->object.rwlock._lock); +} + +static int swRWLock_free(swLock *lock) +{ + return pthread_rwlock_destroy(&lock->object.rwlock._lock); +} + +#endif diff --git a/vendor/swoole/src/lock/Semaphore.c b/vendor/swoole/src/lock/Semaphore.c new file mode 100755 index 0000000..788a0f3 --- /dev/null +++ b/vendor/swoole/src/lock/Semaphore.c @@ -0,0 +1,68 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include <sys/sem.h> + +static int swSem_lock(swLock *lock); +static int swSem_unlock(swLock *lock); +static int swSem_free(swLock *lock); + +int swSem_create(swLock *lock, key_t key) +{ + int ret; + lock->type = SW_SEM; + if ((ret = semget(key, 1, IPC_CREAT | 0666)) < 0) + { + return SW_ERR; + } + + if (semctl(ret, 0, SETVAL, 1) == -1) + { + swWarn("semctl(SETVAL) failed"); + return SW_ERR; + } + lock->object.sem.semid = ret; + + lock->lock = swSem_lock; + lock->unlock = swSem_unlock; + lock->free = swSem_free; + + return SW_OK; +} + +static int swSem_unlock(swLock *lock) +{ + struct sembuf sem; + sem.sem_flg = SEM_UNDO; + sem.sem_num = 0; + sem.sem_op = 1; + return semop(lock->object.sem.semid, &sem, 1); +} + +static int swSem_lock(swLock *lock) +{ + struct sembuf sem; + sem.sem_flg = SEM_UNDO; + sem.sem_num = 0; + sem.sem_op = -1; + return semop(lock->object.sem.semid, &sem, 1); +} + +static int swSem_free(swLock *lock) +{ + return semctl(lock->object.sem.semid, 0, IPC_RMID); +} diff --git a/vendor/swoole/src/lock/SpinLock.c b/vendor/swoole/src/lock/SpinLock.c new file mode 100755 index 0000000..6f08301 --- /dev/null +++ b/vendor/swoole/src/lock/SpinLock.c @@ -0,0 +1,62 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef HAVE_SPINLOCK + +static int swSpinLock_lock(swLock *lock); +static int swSpinLock_unlock(swLock *lock); +static int swSpinLock_trylock(swLock *lock); +static int swSpinLock_free(swLock *lock); + +int swSpinLock_create(swLock *lock, int use_in_process) +{ + int ret; + bzero(lock, sizeof(swLock)); + lock->type = SW_SPINLOCK; + if ((ret = pthread_spin_init(&lock->object.spinlock.lock_t, use_in_process)) < 0) + { + return -1; + } + lock->lock = swSpinLock_lock; + lock->unlock = swSpinLock_unlock; + lock->trylock = swSpinLock_trylock; + lock->free = swSpinLock_free; + return 0; +} + +static int swSpinLock_lock(swLock *lock) +{ + return pthread_spin_lock(&lock->object.spinlock.lock_t); +} + +static int swSpinLock_unlock(swLock *lock) +{ + return pthread_spin_unlock(&lock->object.spinlock.lock_t); +} + +static int swSpinLock_trylock(swLock *lock) +{ + return pthread_spin_trylock(&lock->object.spinlock.lock_t); +} + +static int swSpinLock_free(swLock *lock) +{ + return pthread_spin_destroy(&lock->object.spinlock.lock_t); +} + +#endif diff --git a/vendor/swoole/src/memory/Buffer.c b/vendor/swoole/src/memory/Buffer.c new file mode 100755 index 0000000..a63fe97 --- /dev/null +++ b/vendor/swoole/src/memory/Buffer.c @@ -0,0 +1,174 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "buffer.h" + +/** + * create new buffer + */ +swBuffer* swBuffer_new(int trunk_size) +{ + swBuffer *buffer = sw_malloc(sizeof(swBuffer)); + if (buffer == NULL) + { + swWarn("malloc for buffer failed. Error: %s[%d]", strerror(errno), errno); + return NULL; + } + + bzero(buffer, sizeof(swBuffer)); + buffer->trunk_size = trunk_size; + + return buffer; +} + +/** + * create new trunk + */ +swBuffer_trunk *swBuffer_new_trunk(swBuffer *buffer, uint32_t type, uint32_t size) +{ + swBuffer_trunk *chunk = sw_malloc(sizeof(swBuffer_trunk)); + if (chunk == NULL) + { + swWarn("malloc for trunk failed. Error: %s[%d]", strerror(errno), errno); + return NULL; + } + + bzero(chunk, sizeof(swBuffer_trunk)); + + //require alloc memory + if (type == SW_CHUNK_DATA && size > 0) + { + void *buf = sw_malloc(size); + if (buf == NULL) + { + swWarn("malloc(%d) for data failed. Error: %s[%d]", size, strerror(errno), errno); + sw_free(chunk); + return NULL; + } + chunk->size = size; + chunk->store.ptr = buf; + } + + chunk->type = type; + buffer->trunk_num ++; + + if (buffer->head == NULL) + { + buffer->tail = buffer->head = chunk; + } + else + { + buffer->tail->next = chunk; + buffer->tail = chunk; + } + + return chunk; +} + +/** + * pop the head chunk + */ +void swBuffer_pop_trunk(swBuffer *buffer, swBuffer_trunk *chunk) +{ + if (chunk->next == NULL) + { + buffer->head = NULL; + buffer->tail = NULL; + buffer->length = 0; + buffer->trunk_num = 0; + } + else + { + buffer->head = chunk->next; + buffer->length -= chunk->length; + buffer->trunk_num--; + } + if (chunk->type == SW_CHUNK_DATA) + { + sw_free(chunk->store.ptr); + } + if (chunk->destroy) + { + chunk->destroy(chunk); + } + sw_free(chunk); +} + +/** + * free buffer + */ +int swBuffer_free(swBuffer *buffer) +{ + volatile swBuffer_trunk *chunk = buffer->head; + void * *will_free_trunk; //free the point + while (chunk != NULL) + { + if (chunk->type == SW_CHUNK_DATA) + { + sw_free(chunk->store.ptr); + } + will_free_trunk = (void *) chunk; + chunk = chunk->next; + sw_free(will_free_trunk); + } + sw_free(buffer); + return SW_OK; +} + +/** + * append to buffer queue + */ +int swBuffer_append(swBuffer *buffer, void *data, uint32_t size) +{ + swBuffer_trunk *chunk = swBuffer_new_trunk(buffer, SW_CHUNK_DATA, size); + if (chunk == NULL) + { + return SW_ERR; + } + + buffer->length += size; + chunk->length = size; + + memcpy(chunk->store.ptr, data, size); + + swTraceLog(SW_TRACE_BUFFER, "trunk_n=%d|size=%d|trunk_len=%d|trunk=%p", buffer->trunk_num, size, + chunk->length, chunk); + + return SW_OK; +} + +/** + * print buffer + */ +void swBuffer_debug(swBuffer *buffer, int print_data) +{ + int i = 0; + volatile swBuffer_trunk *trunk = buffer->head; + printf("%s\n%s\n", SW_START_LINE, __func__); + while (trunk != NULL) + { + i++; + printf("%d.\tlen=%d", i, trunk->length); + if (print_data) + { + printf("\tdata=%s", (char *) trunk->store.ptr); + } + printf("\n"); + trunk = trunk->next; + } + printf("%s\n%s\n", SW_END_LINE, __func__); +} diff --git a/vendor/swoole/src/memory/FixedPool.c b/vendor/swoole/src/memory/FixedPool.c new file mode 100755 index 0000000..8fae3cb --- /dev/null +++ b/vendor/swoole/src/memory/FixedPool.c @@ -0,0 +1,249 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static void swFixedPool_init(swFixedPool *object); +static void* swFixedPool_alloc(swMemoryPool *pool, uint32_t size); +static void swFixedPool_free(swMemoryPool *pool, void *ptr); +static void swFixedPool_destroy(swMemoryPool *pool); + +void swFixedPool_debug_slice(swFixedPool_slice *slice); + +/** + * create new FixedPool, random alloc/free fixed size memory + */ +swMemoryPool* swFixedPool_new(uint32_t slice_num, uint32_t slice_size, uint8_t shared) +{ + size_t size = slice_size * slice_num + slice_num * sizeof(swFixedPool_slice); + size_t alloc_size = size + sizeof(swFixedPool) + sizeof(swMemoryPool); + void *memory = (shared == 1) ? sw_shm_malloc(alloc_size) : sw_malloc(alloc_size); + + swFixedPool *object = memory; + memory += sizeof(swFixedPool); + bzero(object, sizeof(swFixedPool)); + + object->shared = shared; + object->slice_num = slice_num; + object->slice_size = slice_size; + object->size = size; + + swMemoryPool *pool = memory; + memory += sizeof(swMemoryPool); + pool->object = object; + pool->alloc = swFixedPool_alloc; + pool->free = swFixedPool_free; + pool->destroy = swFixedPool_destroy; + + object->memory = memory; + + /** + * init linked list + */ + swFixedPool_init(object); + + return pool; +} + +/** + * create new FixedPool, Using the given memory + */ +swMemoryPool* swFixedPool_new2(uint32_t slice_size, void *memory, size_t size) +{ + swFixedPool *object = memory; + memory += sizeof(swFixedPool); + bzero(object, sizeof(swFixedPool)); + + object->slice_size = slice_size; + object->size = size - sizeof(swMemoryPool) - sizeof(swFixedPool); + object->slice_num = object->size / (slice_size + sizeof(swFixedPool_slice)); + + swMemoryPool *pool = memory; + memory += sizeof(swMemoryPool); + bzero(pool, sizeof(swMemoryPool)); + + pool->object = object; + pool->alloc = swFixedPool_alloc; + pool->free = swFixedPool_free; + pool->destroy = swFixedPool_destroy; + + object->memory = memory; + + /** + * init linked list + */ + swFixedPool_init(object); + + return pool; +} + +/** + * linked list + */ +static void swFixedPool_init(swFixedPool *object) +{ + swFixedPool_slice *slice; + void *cur = object->memory; + void *max = object->memory + object->size; + do + { + slice = (swFixedPool_slice *) cur; + bzero(slice, sizeof(swFixedPool_slice)); + + if (object->head != NULL) + { + object->head->pre = slice; + slice->next = object->head; + } + else + { + object->tail = slice; + } + + object->head = slice; + cur += (sizeof(swFixedPool_slice) + object->slice_size); + + if (cur < max) + { + slice->pre = (swFixedPool_slice *) cur; + } + else + { + slice->pre = NULL; + break; + } + + } while (1); +} + +static void* swFixedPool_alloc(swMemoryPool *pool, uint32_t size) +{ + swFixedPool *object = pool->object; + swFixedPool_slice *slice; + + slice = object->head; + + if (slice->lock == 0) + { + slice->lock = 1; + object->slice_use ++; + /** + * move next slice to head (idle list) + */ + object->head = slice->next; + slice->next->pre = NULL; + + /* + * move this slice to tail (busy list) + */ + object->tail->next = slice; + slice->next = NULL; + slice->pre = object->tail; + object->tail = slice; + + return slice->data; + } + else + { + return NULL; + } +} + +static void swFixedPool_free(swMemoryPool *pool, void *ptr) +{ + swFixedPool *object = pool->object; + swFixedPool_slice *slice; + + assert(ptr > object->memory && ptr < object->memory + object->size); + + slice = ptr - sizeof(swFixedPool_slice); + + if (slice->lock) + { + object->slice_use--; + } + + slice->lock = 0; + + //list head, AB + if (slice->pre == NULL) + { + return; + } + //list tail, DE + if (slice->next == NULL) + { + slice->pre->next = NULL; + object->tail = slice->pre; + } + //middle BCD + else + { + slice->pre->next = slice->next; + slice->next->pre = slice->pre; + } + + slice->pre = NULL; + slice->next = object->head; + object->head->pre = slice; + object->head = slice; +} + +static void swFixedPool_destroy(swMemoryPool *pool) +{ + swFixedPool *object = pool->object; + if (object->shared) + { + sw_shm_free(object); + } + else + { + sw_free(object); + } +} + +void swFixedPool_debug(swMemoryPool *pool) +{ + int line = 0; + swFixedPool *object = pool->object; + swFixedPool_slice *slice = object->head; + + printf("===============================%s=================================\n", __FUNCTION__); + while (slice != NULL) + { + if (slice->next == slice) + { + printf("-------------------@@@@@@@@@@@@@@@@@@@@@@----------------\n"); + + } + printf("#%d\t", line); + swFixedPool_debug_slice(slice); + + slice = slice->next; + line++; + if (line > 100) + break; + } +} + +void swFixedPool_debug_slice(swFixedPool_slice *slice) +{ + printf("Slab[%p]\t", slice); + printf("pre=%p\t", slice->pre); + printf("next=%p\t", slice->next); + printf("tag=%d\t", slice->lock); + printf("data=%p\n", slice->data); +} diff --git a/vendor/swoole/src/memory/Malloc.c b/vendor/swoole/src/memory/Malloc.c new file mode 100755 index 0000000..e7a5320 --- /dev/null +++ b/vendor/swoole/src/memory/Malloc.c @@ -0,0 +1,50 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static void* swMalloc_alloc(swMemoryPool *pool, uint32_t size); +static void swMalloc_free(swMemoryPool *pool, void *ptr); +static void swMalloc_destroy(swMemoryPool *pool); + +swMemoryPool* swMalloc_new() +{ + swMemoryPool *pool = sw_malloc(sizeof(swMemoryPool)); + if (pool == NULL) + { + swSysError("mallc(%ld) failed.", sizeof(swMemoryPool)); + return NULL; + } + pool->alloc = swMalloc_alloc; + pool->free = swMalloc_free; + pool->destroy = swMalloc_destroy; + return pool; +} + +static void* swMalloc_alloc(swMemoryPool *pool, uint32_t size) +{ + return sw_malloc(size); +} + +static void swMalloc_free(swMemoryPool *pool, void *ptr) +{ + sw_free(ptr); +} + +static void swMalloc_destroy(swMemoryPool *pool) +{ + sw_free(pool); +} diff --git a/vendor/swoole/src/memory/MemoryGlobal.c b/vendor/swoole/src/memory/MemoryGlobal.c new file mode 100755 index 0000000..e9c1a54 --- /dev/null +++ b/vendor/swoole/src/memory/MemoryGlobal.c @@ -0,0 +1,143 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#define SW_MIN_PAGE_SIZE 4096 + +typedef struct _swMemoryGlobal_page +{ + struct _swMemoryGlobal_page *next; + char memory[0]; +} swMemoryGlobal_page; + +typedef struct _swMemoryGlobal +{ + uint8_t shared; + uint32_t pagesize; + swLock lock; + swMemoryGlobal_page *root_page; + swMemoryGlobal_page *current_page; + uint32_t current_offset; +} swMemoryGlobal; + +static void *swMemoryGlobal_alloc(swMemoryPool *pool, uint32_t size); +static void swMemoryGlobal_free(swMemoryPool *pool, void *ptr); +static void swMemoryGlobal_destroy(swMemoryPool *poll); +static swMemoryGlobal_page* swMemoryGlobal_new_page(swMemoryGlobal *gm); + +swMemoryPool* swMemoryGlobal_new(uint32_t pagesize, uint8_t shared) +{ + swMemoryGlobal gm, *gm_ptr; + assert(pagesize >= SW_MIN_PAGE_SIZE); + bzero(&gm, sizeof(swMemoryGlobal)); + + gm.shared = shared; + gm.pagesize = pagesize; + + swMemoryGlobal_page *page = swMemoryGlobal_new_page(&gm); + if (page == NULL) + { + return NULL; + } + if (swMutex_create(&gm.lock, shared) < 0) + { + return NULL; + } + + gm.root_page = page; + + gm_ptr = (swMemoryGlobal *) page->memory; + gm.current_offset += sizeof(swMemoryGlobal); + + swMemoryPool *allocator = (swMemoryPool *) (page->memory + gm.current_offset); + gm.current_offset += sizeof(swMemoryPool); + + allocator->object = gm_ptr; + allocator->alloc = swMemoryGlobal_alloc; + allocator->destroy = swMemoryGlobal_destroy; + allocator->free = swMemoryGlobal_free; + + memcpy(gm_ptr, &gm, sizeof(gm)); + return allocator; +} + +static swMemoryGlobal_page* swMemoryGlobal_new_page(swMemoryGlobal *gm) +{ + swMemoryGlobal_page *page = (gm->shared == 1) ? sw_shm_malloc(gm->pagesize) : sw_malloc(gm->pagesize); + if (page == NULL) + { + return NULL; + } + bzero(page, gm->pagesize); + page->next = NULL; + + if (gm->current_page != NULL) + { + gm->current_page->next = page; + } + + gm->current_page = page; + gm->current_offset = 0; + + return page; +} + +static void *swMemoryGlobal_alloc(swMemoryPool *pool, uint32_t size) +{ + swMemoryGlobal *gm = pool->object; + gm->lock.lock(&gm->lock); + if (size > gm->pagesize - sizeof(swMemoryGlobal_page)) + { + swWarn("failed to alloc %d bytes, exceed the maximum size[%d].", size, gm->pagesize - (int) sizeof(swMemoryGlobal_page)); + gm->lock.unlock(&gm->lock); + return NULL; + } + if (gm->current_offset + size > gm->pagesize - sizeof(swMemoryGlobal_page)) + { + swMemoryGlobal_page *page = swMemoryGlobal_new_page(gm); + if (page == NULL) + { + swWarn("swMemoryGlobal_alloc alloc memory error."); + gm->lock.unlock(&gm->lock); + return NULL; + } + gm->current_page = page; + } + void *mem = gm->current_page->memory + gm->current_offset; + gm->current_offset += size; + gm->lock.unlock(&gm->lock); + return mem; +} + +static void swMemoryGlobal_free(swMemoryPool *pool, void *ptr) +{ + swWarn("swMemoryGlobal Allocator don't need to release."); +} + +static void swMemoryGlobal_destroy(swMemoryPool *poll) +{ + swMemoryGlobal *gm = poll->object; + swMemoryGlobal_page *page = gm->root_page; + swMemoryGlobal_page *next; + + do + { + next = page->next; + sw_shm_free(page); + page = next; + } while (page); +} diff --git a/vendor/swoole/src/memory/RingBuffer.c b/vendor/swoole/src/memory/RingBuffer.c new file mode 100755 index 0000000..0f05571 --- /dev/null +++ b/vendor/swoole/src/memory/RingBuffer.c @@ -0,0 +1,211 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +typedef struct +{ + uint8_t shared; + uint8_t status; + uint32_t size; + uint32_t alloc_offset; + uint32_t collect_offset; + uint32_t alloc_count; + sw_atomic_t free_count; + void *memory; +} swRingBuffer; + +typedef struct +{ + uint16_t lock; + uint16_t index; + uint32_t length; + char data[0]; +} swRingBuffer_item; + +static void swRingBuffer_destory(swMemoryPool *pool); +static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size); +static void swRingBuffer_free(swMemoryPool *pool, void *ptr); + +#ifdef SW_RINGBUFFER_DEBUG +static void swRingBuffer_print(swRingBuffer *object, char *prefix); + +static void swRingBuffer_print(swRingBuffer *object, char *prefix) +{ + printf("%s: size=%d, status=%d, alloc_count=%d, free_count=%d, offset=%d, next_offset=%d\n", prefix, object->size, + object->status, object->alloc_count, object->free_count, object->alloc_offset, object->collect_offset); +} +#endif + +swMemoryPool *swRingBuffer_new(uint32_t size, uint8_t shared) +{ + void *mem = (shared == 1) ? sw_shm_malloc(size) : sw_malloc(size); + if (mem == NULL) + { + swWarn("malloc(%d) failed.", size); + return NULL; + } + + swRingBuffer *object = mem; + mem += sizeof(swRingBuffer); + bzero(object, sizeof(swRingBuffer)); + + object->size = (size - sizeof(swRingBuffer) - sizeof(swMemoryPool)); + object->shared = shared; + + swMemoryPool *pool = mem; + mem += sizeof(swMemoryPool); + + pool->object = object; + pool->destroy = swRingBuffer_destory; + pool->free = swRingBuffer_free; + pool->alloc = swRingBuffer_alloc; + + object->memory = mem; + + swDebug("memory: ptr=%p", mem); + + return pool; +} + +static void swRingBuffer_collect(swRingBuffer *object) +{ + swRingBuffer_item *item; + sw_atomic_t *free_count = &object->free_count; + + int count = object->free_count; + int i; + uint32_t n_size; + + for (i = 0; i < count; i++) + { + item = object->memory + object->collect_offset; + if (item->lock == 0) + { + n_size = item->length + sizeof(swRingBuffer_item); + + object->collect_offset += n_size; + + if (object->collect_offset + sizeof(swRingBuffer_item) >object->size || object->collect_offset >= object->size) + { + object->collect_offset = 0; + object->status = 0; + } + sw_atomic_fetch_sub(free_count, 1); + } + else + { + break; + } + } +} + +static void* swRingBuffer_alloc(swMemoryPool *pool, uint32_t size) +{ + assert(size > 0); + + swRingBuffer *object = pool->object; + swRingBuffer_item *item; + uint32_t capacity; + + uint32_t alloc_size = size + sizeof(swRingBuffer_item); + + if (object->free_count > 0) + { + swRingBuffer_collect(object); + } + + if (object->status == 0) + { + if (object->alloc_offset + alloc_size >= (object->size - sizeof(swRingBuffer_item))) + { + uint32_t skip_n = object->size - object->alloc_offset; + if (skip_n >= sizeof(swRingBuffer_item)) + { + item = object->memory + object->alloc_offset; + item->lock = 0; + item->length = skip_n - sizeof(swRingBuffer_item); + sw_atomic_t *free_count = &object->free_count; + sw_atomic_fetch_add(free_count, 1); + } + object->alloc_offset = 0; + object->status = 1; + capacity = object->collect_offset - object->alloc_offset; + } + else + { + capacity = object->size - object->alloc_offset; + } + } + else + { + capacity = object->collect_offset - object->alloc_offset; + } + + if (capacity < alloc_size) + { + return NULL; + } + + item = object->memory + object->alloc_offset; + item->lock = 1; + item->length = size; + item->index = object->alloc_count; + + object->alloc_offset += alloc_size; + object->alloc_count ++; + + swDebug("alloc: ptr=%p", (void * )((void * )item->data - object->memory)); + + return item->data; +} + +static void swRingBuffer_free(swMemoryPool *pool, void *ptr) +{ + swRingBuffer *object = pool->object; + swRingBuffer_item *item = ptr - sizeof(swRingBuffer_item); + + assert(ptr >= object->memory); + assert(ptr <= object->memory + object->size); + assert(item->lock == 1); + + if (item->lock != 1) + { + swDebug("invalid free: index=%d, ptr=%p", item->index, (void * )((void * )item->data - object->memory)); + } + else + { + item->lock = 0; + } + + swDebug("free: ptr=%p", (void * )((void * )item->data - object->memory)); + + sw_atomic_t *free_count = &object->free_count; + sw_atomic_fetch_add(free_count, 1); +} + +static void swRingBuffer_destory(swMemoryPool *pool) +{ + swRingBuffer *object = pool->object; + if (object->shared) + { + sw_shm_free(object); + } + else + { + sw_free(object); + } +} diff --git a/vendor/swoole/src/memory/ShareMemory.c b/vendor/swoole/src/memory/ShareMemory.c new file mode 100755 index 0000000..e3c1c4e --- /dev/null +++ b/vendor/swoole/src/memory/ShareMemory.c @@ -0,0 +1,178 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include <sys/shm.h> + +void* sw_shm_malloc(size_t size) +{ + swShareMemory object; + void *mem; + size += sizeof(swShareMemory); + mem = swShareMemory_mmap_create(&object, size, NULL); + if (mem == NULL) + { + return NULL; + } + else + { + memcpy(mem, &object, sizeof(swShareMemory)); + return mem + sizeof(swShareMemory); + } +} + +void* sw_shm_calloc(size_t num, size_t _size) +{ + swShareMemory object; + void *mem; + void *ret_mem; + int size = sizeof(swShareMemory) + (num * _size); + mem = swShareMemory_mmap_create(&object, size, NULL); + if (mem == NULL) + { + return NULL; + } + else + { + memcpy(mem, &object, sizeof(swShareMemory)); + ret_mem = mem + sizeof(swShareMemory); + bzero(ret_mem, size - sizeof(swShareMemory)); + return ret_mem; + } +} + +int sw_shm_protect(void *addr, int flags) +{ + swShareMemory *object = (swShareMemory *) (addr - sizeof(swShareMemory)); + return mprotect(object, object->size, flags); +} + +void sw_shm_free(void *ptr) +{ + swShareMemory *object = ptr - sizeof(swShareMemory); + swShareMemory_mmap_free(object); +} + +void* sw_shm_realloc(void *ptr, size_t new_size) +{ + swShareMemory *object = ptr - sizeof(swShareMemory); + void *new_ptr; + new_ptr = sw_shm_malloc(new_size); + if (new_ptr == NULL) + { + return NULL; + } + else + { + memcpy(new_ptr, ptr, object->size); + sw_shm_free(ptr); + return new_ptr; + } +} + +void *swShareMemory_mmap_create(swShareMemory *object, size_t size, char *mapfile) +{ + void *mem; + int tmpfd = -1; + int flag = MAP_SHARED; + bzero(object, sizeof(swShareMemory)); + +#ifdef MAP_ANONYMOUS + flag |= MAP_ANONYMOUS; +#else + if (mapfile == NULL) + { + mapfile = "/dev/zero"; + } + if ((tmpfd = open(mapfile, O_RDWR)) < 0) + { + return NULL; + } + strncpy(object->mapfile, mapfile, SW_SHM_MMAP_FILE_LEN); + object->tmpfd = tmpfd; +#endif + +#if defined(SW_USE_HUGEPAGE) && defined(MAP_HUGETLB) + if (size > 2 * 1024 * 1024) + { + flag |= MAP_HUGETLB; + } +#endif + + mem = mmap(NULL, size, PROT_READ | PROT_WRITE, flag, tmpfd, 0); +#ifdef MAP_FAILED + if (mem == MAP_FAILED) +#else + if (!mem) +#endif + { + swWarn("mmap(%ld) failed. Error: %s[%d]", size, strerror(errno), errno); + return NULL; + } + else + { + object->size = size; + object->mem = mem; + return mem; + } +} + +int swShareMemory_mmap_free(swShareMemory *object) +{ + return munmap(object->mem, object->size); +} + +void *swShareMemory_sysv_create(swShareMemory *object, size_t size, int key) +{ + int shmid; + void *mem; + bzero(object, sizeof(swShareMemory)); + + if (key == 0) + { + key = IPC_PRIVATE; + } + //SHM_R | SHM_W + if ((shmid = shmget(key, size, IPC_CREAT)) < 0) + { + swSysError("shmget(%d, %ld) failed.", key, size); + return NULL; + } + if ((mem = shmat(shmid, NULL, 0)) == (void *) -1) + { + swWarn("shmat() failed. Error: %s[%d]", strerror(errno), errno); + return NULL; + } + else + { + object->key = key; + object->shmid = shmid; + object->size = size; + object->mem = mem; + return mem; + } +} + +int swShareMemory_sysv_free(swShareMemory *object, int rm) +{ + int shmid = object->shmid; + int ret = shmdt(object->mem); + if (rm == 1) + { + shmctl(shmid, IPC_RMID, NULL); + } + return ret; +} diff --git a/vendor/swoole/src/memory/Table.c b/vendor/swoole/src/memory/Table.c new file mode 100755 index 0000000..2e8a07c --- /dev/null +++ b/vendor/swoole/src/memory/Table.c @@ -0,0 +1,483 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "table.h" + +//#define SW_TABLE_DEBUG 1 +#define SW_TABLE_USE_PHP_HASH + +#ifdef SW_TABLE_DEBUG +static int conflict_count = 0; +static int insert_count = 0; +static int conflict_max_level = 0; +#endif + +static void swTableColumn_free(swTableColumn *col); + +static void swTableColumn_free(swTableColumn *col) +{ + swString_free(col->name); + sw_free(col); +} + +swTable* swTable_new(uint32_t rows_size, float conflict_proportion) +{ + if (rows_size >= 0x80000000) + { + rows_size = 0x80000000; + } + else + { + uint32_t i = 10; + while ((1U << i) < rows_size) + { + i++; + } + rows_size = 1 << i; + } + + if (conflict_proportion > 1.0) + { + conflict_proportion = 1.0; + } + else if (conflict_proportion < SW_TABLE_CONFLICT_PROPORTION) + { + conflict_proportion = SW_TABLE_CONFLICT_PROPORTION; + } + + swTable *table = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swTable)); + if (table == NULL) + { + return NULL; + } + if (swMutex_create(&table->lock, 1) < 0) + { + swWarn("mutex create failed."); + return NULL; + } + table->iterator = sw_malloc(sizeof(swTable_iterator)); + if (!table->iterator) + { + swWarn("malloc failed."); + return NULL; + } + table->columns = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, (swHashMap_dtor)swTableColumn_free); + if (!table->columns) + { + return NULL; + } + + table->size = rows_size; + table->mask = rows_size - 1; + table->conflict_proportion = conflict_proportion; + + bzero(table->iterator, sizeof(swTable_iterator)); + table->memory = NULL; + return table; +} + +int swTableColumn_add(swTable *table, char *name, int len, int type, int size) +{ + swTableColumn *col = sw_malloc(sizeof(swTableColumn)); + if (!col) + { + return SW_ERR; + } + col->name = swString_dup(name, len); + if (!col->name) + { + sw_free(col); + return SW_ERR; + } + switch(type) + { + case SW_TABLE_INT: + switch(size) + { + case 1: + col->size = 1; + col->type = SW_TABLE_INT8; + break; + case 2: + col->size = 2; + col->type = SW_TABLE_INT16; + break; +#ifdef __x86_64__ + case 8: + col->size = 8; + col->type = SW_TABLE_INT64; + break; +#endif + default: + col->size = 4; + col->type = SW_TABLE_INT32; + break; + } + break; + case SW_TABLE_FLOAT: + col->size = sizeof(double); + col->type = SW_TABLE_FLOAT; + break; + case SW_TABLE_STRING: + col->size = size + sizeof(swTable_string_length_t); + col->type = SW_TABLE_STRING; + break; + default: + swWarn("unkown column type."); + swTableColumn_free(col); + return SW_ERR; + } + col->index = table->item_size; + table->item_size += col->size; + table->column_num ++; + return swHashMap_add(table->columns, name, len, col); +} + +size_t swTable_get_memory_size(swTable *table) +{ + /** + * table size + conflict size + */ + size_t row_num = table->size * (1 + table->conflict_proportion); + + /* + * header + data + */ + size_t row_memory_size = sizeof(swTableRow) + table->item_size; + + /** + * row data & header + */ + size_t memory_size = row_num * row_memory_size; + + /** + * memory pool for conflict rows + */ + memory_size += sizeof(swMemoryPool) + sizeof(swFixedPool) + ((row_num - table->size) * sizeof(swFixedPool_slice)); + + /** + * for iterator, Iterate through all the elements + */ + memory_size += table->size * sizeof(swTableRow *); + + return memory_size; +} + +int swTable_create(swTable *table) +{ + size_t memory_size = swTable_get_memory_size(table); + size_t row_memory_size = sizeof(swTableRow) + table->item_size; + + void *memory = sw_shm_malloc(memory_size); + if (memory == NULL) + { + return SW_ERR; + } + + table->memory_size = memory_size; + table->memory = memory; + + table->rows = memory; + memory += table->size * sizeof(swTableRow *); + memory_size -= table->size * sizeof(swTableRow *); + +#if SW_TABLE_USE_SPINLOCK == 0 + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); + pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP); +#endif + + int i; + for (i = 0; i < table->size; i++) + { + table->rows[i] = memory + (row_memory_size * i); + memset(table->rows[i], 0, sizeof(swTableRow)); +#if SW_TABLE_USE_SPINLOCK == 0 + pthread_mutex_init(&table->rows[i]->lock, &attr); +#endif + } + + memory += row_memory_size * table->size; + memory_size -= row_memory_size * table->size; + table->pool = swFixedPool_new2(row_memory_size, memory, memory_size); + + return SW_OK; +} + +void swTable_free(swTable *table) +{ +#ifdef SW_TABLE_DEBUG + printf("swoole_table: size=%d, conflict_count=%d, conflict_max_level=%d, insert_count=%d\n", table->size, + conflict_count, conflict_max_level, insert_count); +#endif + + swHashMap_free(table->columns); + sw_free(table->iterator); + if (table->memory) + { + sw_shm_free(table->memory); + } +} + +static sw_inline swTableRow* swTable_hash(swTable *table, char *key, int keylen) +{ +#ifdef SW_TABLE_USE_PHP_HASH + uint64_t hashv = swoole_hash_php(key, keylen); +#else + uint64_t hashv = swoole_hash_austin(key, keylen); +#endif + uint64_t index = hashv & table->mask; + assert(index < table->size); + return table->rows[index]; +} + +void swTable_iterator_rewind(swTable *table) +{ + bzero(table->iterator, sizeof(swTable_iterator)); +} + +static sw_inline swTableRow* swTable_iterator_get(swTable *table, uint32_t index) +{ + swTableRow *row = table->rows[index]; + return row->active ? row : NULL; +} + +swTableRow* swTable_iterator_current(swTable *table) +{ + return table->iterator->row; +} + +void swTable_iterator_forward(swTable *table) +{ + for (; table->iterator->absolute_index < table->size; table->iterator->absolute_index++) + { + swTableRow *row = swTable_iterator_get(table, table->iterator->absolute_index); + if (row == NULL) + { + continue; + } + else if (row->next == NULL) + { + table->iterator->absolute_index++; + table->iterator->row = row; + return; + } + else + { + int i = 0; + for (;; i++) + { + if (row == NULL) + { + table->iterator->collision_index = 0; + break; + } + if (i == table->iterator->collision_index) + { + table->iterator->collision_index++; + table->iterator->row = row; + return; + } + row = row->next; + } + } + } + table->iterator->row = NULL; +} + +swTableRow* swTableRow_get(swTable *table, char *key, int keylen, swTableRow** rowlock) +{ + if (keylen > SW_TABLE_KEY_SIZE) + { + keylen = SW_TABLE_KEY_SIZE; + } + + swTableRow *row = swTable_hash(table, key, keylen); + *rowlock = row; + swTableRow_lock(row); + + for (;;) + { + if (strncmp(row->key, key, keylen) == 0) + { + if (!row->active) + { + row = NULL; + } + break; + } + else if (row->next == NULL) + { + row = NULL; + break; + } + else + { + row = row->next; + } + } + + return row; +} + +swTableRow* swTableRow_set(swTable *table, char *key, int keylen, swTableRow **rowlock) +{ + if (keylen > SW_TABLE_KEY_SIZE) + { + keylen = SW_TABLE_KEY_SIZE; + } + + swTableRow *row = swTable_hash(table, key, keylen); + *rowlock = row; + swTableRow_lock(row); + +#ifdef SW_TABLE_DEBUG + int _conflict_level = 0; +#endif + + if (row->active) + { + for (;;) + { + if (strncmp(row->key, key, keylen) == 0) + { + break; + } + else if (row->next == NULL) + { + table->lock.lock(&table->lock); + swTableRow *new_row = table->pool->alloc(table->pool, 0); + +#ifdef SW_TABLE_DEBUG + conflict_count ++; + if (_conflict_level > conflict_max_level) + { + conflict_max_level = _conflict_level; + } + +#endif + table->lock.unlock(&table->lock); + + if (!new_row) + { + return NULL; + } + //add row_num + bzero(new_row, sizeof(swTableRow)); + sw_atomic_fetch_add(&(table->row_num), 1); + row->next = new_row; + row = new_row; + break; + } + else + { + row = row->next; +#ifdef SW_TABLE_DEBUG + _conflict_level++; +#endif + } + } + } + else + { +#ifdef SW_TABLE_DEBUG + insert_count ++; +#endif + sw_atomic_fetch_add(&(table->row_num), 1); + } + + memcpy(row->key, key, keylen); + row->active = 1; + return row; +} + +int swTableRow_del(swTable *table, char *key, int keylen) +{ + if (keylen > SW_TABLE_KEY_SIZE) + { + keylen = SW_TABLE_KEY_SIZE; + } + + swTableRow *row = swTable_hash(table, key, keylen); + //no exists + if (!row->active) + { + return SW_ERR; + } + + swTableRow_lock(row); + if (row->next == NULL) + { + if (strncmp(row->key, key, keylen) == 0) + { + bzero(row, sizeof(swTableRow) + table->item_size); + goto delete_element; + } + else + { + goto not_exists; + } + } + else + { + swTableRow *tmp = row; + swTableRow *prev = NULL; + + while (tmp) + { + if ((strncmp(tmp->key, key, keylen) == 0)) + { + break; + } + prev = tmp; + tmp = tmp->next; + } + + if (tmp == NULL) + { + not_exists: + swTableRow_unlock(row); + return SW_ERR; + } + + //when the deleting element is root, we should move the first element's data to root, + //and remove the element from the collision list. + if (tmp == row) + { + tmp = tmp->next; + row->next = tmp->next; + memcpy(row->key, tmp->key, strlen(tmp->key)); + memcpy(row->data, tmp->data, table->item_size); + } + if (prev) + { + prev->next = tmp->next; + } + table->lock.lock(&table->lock); + bzero(tmp, sizeof(swTableRow) + table->item_size); + table->pool->free(table->pool, tmp); + table->lock.unlock(&table->lock); + } + + delete_element: + sw_atomic_fetch_sub(&(table->row_num), 1); + swTableRow_unlock(row); + + return SW_OK; +} diff --git a/vendor/swoole/src/network/Client.c b/vendor/swoole/src/network/Client.c new file mode 100755 index 0000000..8728297 --- /dev/null +++ b/vendor/swoole/src/network/Client.c @@ -0,0 +1,1548 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" +#include "Client.h" +#include "socks5.h" +#include "async.h" + +static int swClient_inet_addr(swClient *cli, char *host, int port); +static int swClient_tcp_connect_sync(swClient *cli, char *host, int port, double _timeout, int udp_connect); +static int swClient_tcp_connect_async(swClient *cli, char *host, int port, double timeout, int nonblock); + +static int swClient_tcp_send_sync(swClient *cli, char *data, int length, int flags); +static int swClient_tcp_send_async(swClient *cli, char *data, int length, int flags); +static int swClient_tcp_pipe(swClient *cli, int write_fd, int flags); +static int swClient_udp_send(swClient *cli, char *data, int length, int flags); + +static int swClient_tcp_sendfile_sync(swClient *cli, char *filename, off_t offset, size_t length); +static int swClient_tcp_sendfile_async(swClient *cli, char *filename, off_t offset, size_t length); +static int swClient_tcp_recv_no_buffer(swClient *cli, char *data, int len, int flags); +static int swClient_udp_connect(swClient *cli, char *host, int port, double _timeout, int udp_connect); +static int swClient_udp_recv(swClient *cli, char *data, int len, int waitall); +static int swClient_close(swClient *cli); + +static int swClient_onDgramRead(swReactor *reactor, swEvent *event); +static int swClient_onStreamRead(swReactor *reactor, swEvent *event); +static int swClient_onWrite(swReactor *reactor, swEvent *event); +static int swClient_onError(swReactor *reactor, swEvent *event); +static void swClient_onTimeout(swTimer *timer, swTimer_node *tnode); +static void swClient_onResolveCompleted(swAio_event *event); +static int swClient_onPackage(swConnection *conn, char *data, uint32_t length); + +static sw_inline void execute_onConnect(swClient *cli) +{ + if (cli->timer) + { + swTimer_del(&SwooleG.timer, cli->timer); + cli->timer = NULL; + } + cli->onConnect(cli); +} + +int swClient_create(swClient *cli, int type, int async) +{ + int _domain; + int _type; + + bzero(cli, sizeof(swClient)); + switch (type) + { + case SW_SOCK_TCP: + _domain = AF_INET; + _type = SOCK_STREAM; + break; + case SW_SOCK_TCP6: + _domain = AF_INET6; + _type = SOCK_STREAM; + break; + case SW_SOCK_UNIX_STREAM: + _domain = AF_UNIX; + _type = SOCK_STREAM; + break; + case SW_SOCK_UDP: + _domain = AF_INET; + _type = SOCK_DGRAM; + break; + case SW_SOCK_UDP6: + _domain = AF_INET6; + _type = SOCK_DGRAM; + break; + case SW_SOCK_UNIX_DGRAM: + _domain = AF_UNIX; + _type = SOCK_DGRAM; + break; + default: + return SW_ERR; + } + +#ifdef SOCK_CLOEXEC + int sockfd = socket(_domain, _type | SOCK_CLOEXEC, 0); +#else + int sockfd = socket(_domain, _type, 0); +#endif + if (sockfd < 0) + { + swWarn("socket() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + + if (async) + { + if (swIsMaster() && SwooleTG.type == SW_THREAD_REACTOR) + { + cli->reactor = SwooleTG.reactor; + } + else + { + cli->reactor = SwooleG.main_reactor; + } + cli->socket = swReactor_get(cli->reactor, sockfd); + } + else + { + cli->socket = sw_malloc(sizeof(swConnection)); + } + + cli->buffer_input_size = SW_CLIENT_BUFFER_SIZE; + + if (!cli->socket) + { + swWarn("malloc(%d) failed.", (int ) sizeof(swConnection)); + close(sockfd); + return SW_ERR; + } + + bzero(cli->socket, sizeof(swConnection)); + cli->socket->fd = sockfd; + cli->socket->object = cli; + + if (async) + { + swSetNonBlock(cli->socket->fd); + if (!swReactor_handle_isset(cli->reactor, SW_FD_STREAM_CLIENT)) + { + cli->reactor->setHandle(cli->reactor, SW_FD_STREAM_CLIENT | SW_EVENT_READ, swClient_onStreamRead); + cli->reactor->setHandle(cli->reactor, SW_FD_DGRAM_CLIENT | SW_EVENT_READ, swClient_onDgramRead); + cli->reactor->setHandle(cli->reactor, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE, swClient_onWrite); + cli->reactor->setHandle(cli->reactor, SW_FD_STREAM_CLIENT | SW_EVENT_ERROR, swClient_onError); + } + } + + if (swSocket_is_stream(type)) + { + cli->recv = swClient_tcp_recv_no_buffer; + if (async) + { + cli->connect = swClient_tcp_connect_async; + cli->send = swClient_tcp_send_async; + cli->sendfile = swClient_tcp_sendfile_async; + cli->pipe = swClient_tcp_pipe; + cli->socket->dontwait = 1; + } + else + { + cli->connect = swClient_tcp_connect_sync; + cli->send = swClient_tcp_send_sync; + cli->sendfile = swClient_tcp_sendfile_sync; + } + cli->reactor_fdtype = SW_FD_STREAM_CLIENT; + } + else + { + cli->connect = swClient_udp_connect; + cli->recv = swClient_udp_recv; + cli->send = swClient_udp_send; + cli->reactor_fdtype = SW_FD_DGRAM_CLIENT; + } + + cli->_sock_domain = _domain; + cli->_sock_type = _type; + + cli->close = swClient_close; + cli->type = type; + cli->async = async; + + cli->protocol.package_length_type = 'N'; + cli->protocol.package_length_size = 4; + cli->protocol.package_body_offset = 0; + cli->protocol.package_max_length = SW_BUFFER_INPUT_SIZE; + cli->protocol.onPackage = swClient_onPackage; + + return SW_OK; +} + +int swClient_sleep(swClient *cli) +{ + int ret; + if (cli->socket->events & SW_EVENT_WRITE) + { + ret = cli->reactor->set(cli->reactor, cli->socket->fd, cli->socket->fdtype | SW_EVENT_WRITE); + } + else + { + ret = cli->reactor->del(cli->reactor, cli->socket->fd); + } + if (ret == SW_OK) + { + cli->sleep = 1; + } + return ret; +} + +int swClient_wakeup(swClient *cli) +{ + int ret; + if (cli->socket->events & SW_EVENT_WRITE) + { + ret = cli->reactor->set(cli->reactor, cli->socket->fd, cli->socket->fdtype | SW_EVENT_READ | SW_EVENT_WRITE); + } + else + { + ret = cli->reactor->add(cli->reactor, cli->socket->fd, cli->socket->fdtype | SW_EVENT_READ); + } + if (ret == SW_OK) + { + cli->sleep = 0; + } + return ret; +} + +int swClient_shutdown(swClient *cli, int __how) +{ + if (!cli->socket || cli->socket->closed) + { + return SW_ERR; + } + if (__how == SHUT_RD) + { + if (cli->shutdown_read || cli->shutdow_rw || shutdown(cli->socket->fd, SHUT_RD)) + { + return SW_ERR; + } + else + { + cli->shutdown_read = 1; + return SW_OK; + } + } + else if (__how == SHUT_WR) + { + if (cli->shutdown_write || cli->shutdow_rw || shutdown(cli->socket->fd, SHUT_RD) < 0) + { + return SW_ERR; + } + else + { + cli->shutdown_write = 1; + return SW_OK; + } + } + else if (__how == SHUT_RDWR) + { + if (cli->shutdow_rw || shutdown(cli->socket->fd, SHUT_RDWR) < 0) + { + return SW_ERR; + } + else + { + cli->shutdown_read = 1; + return SW_OK; + } + } + else + { + return SW_ERR; + } +} + +#ifdef SW_USE_OPENSSL +int swClient_enable_ssl_encrypt(swClient *cli) +{ + cli->ssl_context = swSSL_get_context(&cli->ssl_option); + if (cli->ssl_context == NULL) + { + return SW_ERR; + } + + if (cli->ssl_option.verify_peer) + { + if (swSSL_set_capath(&cli->ssl_option, cli->ssl_context) < 0) + { + return SW_ERR; + } + } + + cli->socket->ssl_send = 1; +#if defined(SW_USE_HTTP2) && defined(SW_USE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10002000L + if (cli->http2) + { + if (SSL_CTX_set_alpn_protos(cli->ssl_context, (const unsigned char *) "\x02h2", 3) < 0) + { + return SW_ERR; + } + } +#endif + return SW_OK; +} + +int swClient_ssl_handshake(swClient *cli) +{ + if (!cli->socket->ssl) + { + if (swSSL_create(cli->socket, cli->ssl_context, SW_SSL_CLIENT) < 0) + { + return SW_ERR; + } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (cli->ssl_option.tls_host_name) + { + SSL_set_tlsext_host_name(cli->socket->ssl, cli->ssl_option.tls_host_name); + } +#endif + } + if (swSSL_connect(cli->socket) < 0) + { + return SW_ERR; + } + if (cli->socket->ssl_state == SW_SSL_STATE_READY && cli->ssl_option.verify_peer) + { + if (swClient_ssl_verify(cli, cli->ssl_option.allow_self_signed) < 0) + { + return SW_ERR; + } + } + return SW_OK; +} + +int swClient_ssl_verify(swClient *cli, int allow_self_signed) +{ + if (swSSL_verify(cli->socket, allow_self_signed) < 0) + { + return SW_ERR; + } + if (cli->ssl_option.tls_host_name && swSSL_check_host(cli->socket, cli->ssl_option.tls_host_name) < 0) + { + return SW_ERR; + } + return SW_OK; +} + +#endif + +static int swClient_inet_addr(swClient *cli, char *host, int port) +{ + //enable socks5 proxy + if (cli->socks5_proxy) + { + cli->socks5_proxy->target_host = host; + cli->socks5_proxy->l_target_host = strlen(host); + cli->socks5_proxy->target_port = port; + + host = cli->socks5_proxy->host; + port = cli->socks5_proxy->port; + } + + //enable http proxy + if (cli->http_proxy) + { + cli->http_proxy->target_host = host; + cli->http_proxy->target_port = port; + + host = cli->http_proxy->proxy_host; + port = cli->http_proxy->proxy_port; + } + + cli->server_host = host; + cli->server_port = port; + + void *s_addr = NULL; + if (cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_UDP) + { + cli->server_addr.addr.inet_v4.sin_family = AF_INET; + cli->server_addr.addr.inet_v4.sin_port = htons(port); + cli->server_addr.len = sizeof(cli->server_addr.addr.inet_v4); + s_addr = &cli->server_addr.addr.inet_v4.sin_addr.s_addr; + + if (inet_pton(AF_INET, host, s_addr)) + { + return SW_OK; + } + } + else if (cli->type == SW_SOCK_TCP6 || cli->type == SW_SOCK_UDP6) + { + cli->server_addr.addr.inet_v6.sin6_family = AF_INET6; + cli->server_addr.addr.inet_v6.sin6_port = htons(port); + cli->server_addr.len = sizeof(cli->server_addr.addr.inet_v6); + s_addr = cli->server_addr.addr.inet_v6.sin6_addr.s6_addr; + + if (inet_pton(AF_INET6, host, s_addr)) + { + return SW_OK; + } + } + else if (cli->type == SW_SOCK_UNIX_STREAM || cli->type == SW_SOCK_UNIX_DGRAM) + { + cli->server_addr.addr.un.sun_family = AF_UNIX; + strncpy(cli->server_addr.addr.un.sun_path, host, sizeof(cli->server_addr.addr.un.sun_path) - 1); + cli->server_addr.addr.un.sun_path[sizeof(cli->server_addr.addr.un.sun_path) - 1] = 0; + cli->server_addr.len = sizeof(cli->server_addr.addr.un.sun_path); + return SW_OK; + } + else + { + return SW_ERR; + } + if (!cli->async) + { + if (swoole_gethostbyname(cli->_sock_domain, host, s_addr) < 0) + { + SwooleG.error = SW_ERROR_DNSLOOKUP_RESOLVE_FAILED; + return SW_ERR; + } + } + else + { + cli->wait_dns = 1; + } + return SW_OK; +} + +void swClient_free(swClient *cli) +{ + assert(cli->socket->fd != 0); + //remove from reactor + if (!cli->socket->closed) + { + cli->close(cli); + } + if (cli->socket->out_buffer) + { + swBuffer_free(cli->socket->out_buffer); + cli->socket->out_buffer = NULL; + } + if (cli->socket->in_buffer) + { + swBuffer_free(cli->socket->in_buffer); + cli->socket->in_buffer = NULL; + } + bzero(cli->socket, sizeof(swConnection)); + if (cli->async) + { + cli->socket->removed = 1; + } + else + { + sw_free(cli->socket); + } +} + +static int swClient_close(swClient *cli) +{ + int fd = cli->socket->fd; + assert(fd != 0); + +#ifdef SW_USE_OPENSSL + if (cli->open_ssl && cli->ssl_context) + { + if (cli->socket->ssl) + { + swSSL_close(cli->socket); + } + swSSL_free_context(cli->ssl_context); + if (cli->ssl_option.cert_file) + { + sw_free(cli->ssl_option.cert_file); + } + if (cli->ssl_option.key_file) + { + sw_free(cli->ssl_option.key_file); + } + if (cli->ssl_option.passphrase) + { + sw_free(cli->ssl_option.passphrase); + } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (cli->ssl_option.tls_host_name) + { + sw_free(cli->ssl_option.tls_host_name); + } +#endif + if (cli->ssl_option.cafile) + { + sw_free(cli->ssl_option.cafile); + } + if (cli->ssl_option.capath) + { + sw_free(cli->ssl_option.capath); + } + } +#endif + //clear buffer + if (cli->buffer) + { + swString_free(cli->buffer); + cli->buffer = NULL; + } + if (cli->type == SW_SOCK_UNIX_DGRAM) + { + unlink(cli->socket->info.addr.un.sun_path); + } + if (cli->socket->closed) + { + return SW_OK; + } + cli->socket->closed = 1; + if (cli->async) + { + //remove from reactor + if (!cli->socket->removed && cli->reactor) + { + cli->reactor->del(cli->reactor, fd); + } + if (cli->timer) + { + swTimer_del(&SwooleG.timer, cli->timer); + cli->timer = NULL; + } + //onClose callback + if (cli->socket->active && cli->onClose) + { + cli->socket->active = 0; + cli->onClose(cli); + } + } + else + { + cli->socket->active = 0; + } + return close(fd); +} + +static int swClient_tcp_connect_sync(swClient *cli, char *host, int port, double timeout, int nonblock) +{ + int ret, n; + char buf[1024]; + + cli->timeout = timeout; + + if (swClient_inet_addr(cli, host, port) < 0) + { + return SW_ERR; + } + + if (nonblock == 1) + { + swSetNonBlock(cli->socket->fd); + } + else + { + if (cli->timeout > 0) + { + swSocket_set_timeout(cli->socket->fd, timeout); + } +#ifndef HAVE_KQUEUE + swSetBlock(cli->socket->fd); +#endif + } + while (1) + { +#ifdef HAVE_KQUEUE + swSetNonBlock(cli->socket->fd); + ret = connect(cli->socket->fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); + if (ret < 0) + { + if (errno != EINPROGRESS) + { + return SW_ERR; + } + if (swSocket_wait(cli->socket->fd, timeout > 0 ? (int) (timeout * 1000) : timeout, SW_EVENT_WRITE) < 0) + { + return SW_ERR; + } + else + { + swSetBlock(cli->socket->fd); + ret = 0; + } + } +#else + ret = connect(cli->socket->fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); +#endif + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + } + break; + } + + if (ret >= 0) + { + cli->socket->active = 1; + + //socks5 proxy + if (cli->socks5_proxy) + { + swSocks5_pack(buf, cli->socks5_proxy->username == NULL ? 0x00 : 0x02); + if (cli->send(cli, buf, 3, 0) < 0) + { + return SW_ERR; + } + cli->socks5_proxy->state = SW_SOCKS5_STATE_HANDSHAKE; + while (1) + { + n = cli->recv(cli, buf, sizeof(buf), 0); + if (n > 0) + { + if (swSocks5_connect(cli, buf, n) < 0) + { + return SW_ERR; + } + else + { + if (cli->socks5_proxy->state == SW_SOCKS5_STATE_READY) + { + break; + } + else + { + continue; + } + } + } + return SW_ERR; + } + } + +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + if (swClient_enable_ssl_encrypt(cli) < 0) + { + return SW_ERR; + } + if (swClient_ssl_handshake(cli) < 0) + { + return SW_ERR; + } + } +#endif + } + + return ret; +} + +static int swClient_tcp_connect_async(swClient *cli, char *host, int port, double timeout, int nonblock) +{ + int ret; + + cli->timeout = timeout; + + if (!cli->buffer) + { + //alloc input memory buffer + cli->buffer = swString_new(cli->buffer_input_size); + if (!cli->buffer) + { + return SW_ERR; + } + } + + if (!(cli->onConnect && cli->onError && cli->onClose)) + { + swWarn("onConnect/onError/onClose callback have not set."); + return SW_ERR; + } + + if (cli->onBufferFull && cli->buffer_high_watermark == 0) + { + cli->buffer_high_watermark = cli->socket->buffer_size * 0.8; + } + + if (swClient_inet_addr(cli, host, port) < 0) + { + return SW_ERR; + } + + if (cli->wait_dns) + { + if (SwooleAIO.init == 0) + { + swAio_init(); + } + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + int len = strlen(cli->server_host); + if (strlen(cli->server_host) < SW_IP_MAX_LENGTH) + { + ev.nbytes = SW_IP_MAX_LENGTH; + } + else + { + ev.nbytes = len + 1; + } + + ev.buf = sw_malloc(ev.nbytes); + if (!ev.buf) + { + swWarn("malloc failed."); + return SW_ERR; + } + + memcpy(ev.buf, cli->server_host, len); + ((char *) ev.buf)[len] = 0; + ev.flags = cli->_sock_domain; + ev.type = SW_AIO_GETHOSTBYNAME; + ev.object = cli; + ev.callback = swClient_onResolveCompleted; + + if (swAio_dispatch(&ev) < 0) + { + sw_free(ev.buf); + return SW_ERR; + } + else + { + return SW_OK; + } + } + + while (1) + { + ret = connect(cli->socket->fd, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + SwooleG.error = errno; + } + break; + } + + if ((ret < 0 && errno == EINPROGRESS) || ret == 0) + { + if (cli->reactor->add(cli->reactor, cli->socket->fd, cli->reactor_fdtype | SW_EVENT_WRITE) < 0) + { + return SW_ERR; + } + if (timeout > 0) + { + if (SwooleG.timer.fd == 0) + { + swTimer_init((int) (timeout * 1000)); + } + cli->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, cli, swClient_onTimeout); + } + return SW_OK; + } + + return ret; +} + +static int swClient_tcp_pipe(swClient *cli, int write_fd, int flags) +{ + if (!cli->async || cli->_sock_type != SOCK_STREAM) + { + swWarn("only async tcp-client can use pipe method."); + return SW_ERR; + } + + int socktype; + socklen_t length = sizeof(socktype); + + if (flags & SW_CLIENT_PIPE_TCP_SESSION) + { + cli->_redirect_to_session = write_fd; + } + else if (getsockopt(write_fd, SOL_SOCKET, SO_TYPE, &socktype, &length) < 0) + { + if (errno != ENOTSOCK) + { + return SW_ERR; + } + cli->_redirect_to_file = write_fd; + } + else if (fcntl(write_fd, F_GETFD) != -1 || errno != EBADF) + { + cli->_redirect_to_socket = write_fd; + } + else + { + return SW_ERR; + } + cli->redirect = 1; + return SW_OK; +} + +static int swClient_tcp_send_async(swClient *cli, char *data, int length, int flags) +{ + int n = length; + if (cli->reactor->write(cli->reactor, cli->socket->fd, data, length) < 0) + { + if (SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW) + { + n = -1; + cli->socket->high_watermark = 1; + } + else + { + return SW_ERR; + } + } + if (cli->onBufferFull && cli->socket->out_buffer && cli->socket->high_watermark == 0 + && cli->socket->out_buffer->length >= cli->buffer_high_watermark) + { + cli->socket->high_watermark = 1; + cli->onBufferFull(cli); + } + return n; +} + +static int swClient_tcp_send_sync(swClient *cli, char *data, int length, int flags) +{ + int written = 0; + int n; + + assert(length > 0); + assert(data != NULL); + + while (written < length) + { + n = swConnection_send(cli->socket, data, length - written, flags); + if (n < 0) + { + if (errno == EINTR) + { + continue; + } + else if (errno == EAGAIN) + { + swSocket_wait(cli->socket->fd, 1000, SW_EVENT_WRITE); + continue; + } + else + { + SwooleG.error = errno; + return SW_ERR; + } + } + written += n; + data += n; + } + return written; +} + +static int swClient_tcp_sendfile_sync(swClient *cli, char *filename, off_t offset, size_t length) +{ + if (swSocket_sendfile_sync(cli->socket->fd, filename, offset, length, cli->timeout) < 0) + { + SwooleG.error = errno; + return SW_ERR; + } + return SW_OK; +} + +static int swClient_tcp_sendfile_async(swClient *cli, char *filename, off_t offset, size_t length) +{ + if (swConnection_sendfile(cli->socket, filename, offset, length) < 0) + { + SwooleG.error = errno; + return SW_ERR; + } + if (!(cli->socket->events & SW_EVENT_WRITE)) + { + if (cli->socket->events & SW_EVENT_READ) + { + return cli->reactor->set(cli->reactor, cli->socket->fd, + cli->socket->fdtype | SW_EVENT_READ | SW_EVENT_WRITE); + } + else + { + return cli->reactor->add(cli->reactor, cli->socket->fd, + cli->socket->fdtype | SW_EVENT_WRITE); + } + } + return SW_OK; +} + +/** + * Only for synchronous client + */ +static int swClient_tcp_recv_no_buffer(swClient *cli, char *data, int len, int flag) +{ + int ret; + + while (1) + { + ret = swConnection_recv(cli->socket, data, len, flag); + if (ret >= 0) + { + break; + } + if (errno == EINTR) + { + if (cli->interrupt_time <= 0) + { + cli->interrupt_time = swoole_microtime(); + } + else if (swoole_microtime() > cli->interrupt_time + cli->timeout) + { + break; + } + else + { + continue; + } + } +#ifdef SW_USE_OPENSSL + if (errno == EAGAIN && cli->socket->ssl) + { + int timeout_ms = (int) (cli->timeout * 1000); + if (cli->socket->ssl_want_read && swSocket_wait(cli->socket->fd, timeout_ms, SW_EVENT_READ) == SW_OK) + { + continue; + } + else if (cli->socket->ssl_want_write && swSocket_wait(cli->socket->fd, timeout_ms, SW_EVENT_WRITE) == SW_OK) + { + continue; + } + } +#endif + break; + } + + return ret; +} + +static int swClient_udp_connect(swClient *cli, char *host, int port, double timeout, int udp_connect) +{ + if (swClient_inet_addr(cli, host, port) < 0) + { + return SW_ERR; + } + + cli->socket->active = 1; + cli->timeout = timeout; + int bufsize = SwooleG.socket_buffer_size; + + if (timeout > 0) + { + swSocket_set_timeout(cli->socket->fd, timeout); + } + + if (cli->type == SW_SOCK_UNIX_DGRAM) + { + struct sockaddr_un* client_addr = &cli->socket->info.addr.un; + sprintf(client_addr->sun_path, "/tmp/swoole-client.%d.%d.sock", getpid(), cli->socket->fd); + client_addr->sun_family = AF_UNIX; + unlink(client_addr->sun_path); + + if (bind(cli->socket->fd, (struct sockaddr *) client_addr, sizeof(cli->socket->info.addr.un)) < 0) + { + swSysError("bind(%s) failed.", client_addr->sun_path); + return SW_ERR; + } + } + if (udp_connect != 1) + { + goto connect_ok; + } + + if (connect(cli->socket->fd, (struct sockaddr *) (&cli->server_addr), cli->server_addr.len) == 0) + { + swSocket_clean(cli->socket->fd); + connect_ok: + + setsockopt(cli->socket->fd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); + setsockopt(cli->socket->fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); + + if (cli->async && cli->onConnect) + { + if (cli->reactor->add(cli->reactor, cli->socket->fd, cli->reactor_fdtype | SW_EVENT_READ) < 0) + { + return SW_ERR; + } + execute_onConnect(cli); + } + return SW_OK; + } + else + { + swSysError("connect() failed."); + cli->socket->active = 0; + cli->socket->removed = 1; + return SW_ERR; + } +} + +static int swClient_udp_send(swClient *cli, char *data, int len, int flags) +{ + int n; + n = sendto(cli->socket->fd, data, len, 0, (struct sockaddr *) &cli->server_addr.addr, cli->server_addr.len); + if (n < 0 || n < len) + { + return SW_ERR; + } + else + { + return n; + } +} + +static int swClient_udp_recv(swClient *cli, char *data, int length, int flags) +{ + cli->remote_addr.len = sizeof(cli->remote_addr.addr); + int ret = recvfrom(cli->socket->fd, data, length, flags, (struct sockaddr *) &cli->remote_addr.addr, &cli->remote_addr.len); + if (ret < 0) + { + if (errno == EINTR) + { + ret = recvfrom(cli->socket->fd, data, length, flags, (struct sockaddr *) &cli->remote_addr, &cli->remote_addr.len); + } + else + { + return SW_ERR; + } + } + return ret; +} + +#ifdef SW_USE_OPENSSL +static int swClient_https_proxy_handshake(swClient *cli) +{ + char *buf = cli->buffer->str; + size_t len = cli->buffer->length; + int state = 0; + char *p = buf; + for (p = buf; p < buf + len; p++) + { + if (state == 0) + { + if (strncasecmp(p, "HTTP/1.1", 8) == 0 || strncasecmp(p, "HTTP/1.0", 8) == 0) + { + state = 1; + p += 8; + } + else + { + break; + } + } + else if (state == 1) + { + if (isspace(*p)) + { + continue; + } + else + { + if (strncasecmp(p, "200", 3) == 0) + { + state = 2; + p += 3; + } + else + { + break; + } + } + } + else if (state == 2) + { + if (isspace(*p)) + { + continue; + } + else + { + if (strncasecmp(p, "Connection established", sizeof("Connection established") - 1) == 0) + { + return SW_OK; + } + else + { + break; + } + } + } + } + return SW_ERR; +} +#endif + +static int swClient_onPackage(swConnection *conn, char *data, uint32_t length) +{ + swClient *cli = (swClient *) conn->object; + cli->onReceive(conn->object, data, length); + return conn->close_wait ? SW_ERR : SW_OK; +} + +static int swClient_onStreamRead(swReactor *reactor, swEvent *event) +{ + int n; + swClient *cli = event->socket->object; + char *buf = cli->buffer->str + cli->buffer->length; + long buf_size = cli->buffer->size - cli->buffer->length; + + if (cli->http_proxy && cli->http_proxy->state != SW_HTTP_PROXY_STATE_READY) + { +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + int n = swConnection_recv(event->socket, buf, buf_size, 0); + if (n <= 0) + { + goto __close; + } + cli->buffer->length += n; + if (cli->buffer->length < sizeof(SW_HTTPS_PROXY_HANDSHAKE_RESPONSE) - 1) + { + return SW_OK; + } + if (swClient_https_proxy_handshake(cli) < 0) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_HTTP_PROXY_HANDSHAKE_ERROR, "failed to handshake with http proxy."); + goto connect_fail; + } + else + { + cli->http_proxy->state = SW_HTTP_PROXY_STATE_READY; + swString_clear(cli->buffer); + } + if (swClient_enable_ssl_encrypt(cli) < 0) + { + goto connect_fail; + } + else + { + if (swClient_ssl_handshake(cli) < 0) + { + goto connect_fail; + } + else + { + cli->socket->ssl_state = SW_SSL_STATE_WAIT_STREAM; + } + return cli->reactor->set(cli->reactor, event->fd, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE); + } + if (cli->onConnect) + { + execute_onConnect(cli); + } + return SW_OK; + } +#endif + } + if (cli->socks5_proxy && cli->socks5_proxy->state != SW_SOCKS5_STATE_READY) + { + int n = swConnection_recv(event->socket, buf, buf_size, 0); + if (n <= 0) + { + goto __close; + } + if (swSocks5_connect(cli, buf, buf_size) < 0) + { + goto __close; + } + if (cli->socks5_proxy->state != SW_SOCKS5_STATE_READY) + { + return SW_OK; + } +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + if (swClient_enable_ssl_encrypt(cli) < 0) + { + connect_fail: + cli->socket->active = 0; + cli->close(cli); + if (cli->onError) + { + cli->onError(cli); + } + } + else + { + if (swClient_ssl_handshake(cli) < 0) + { + goto connect_fail; + } + else + { + cli->socket->ssl_state = SW_SSL_STATE_WAIT_STREAM; + } + return cli->reactor->set(cli->reactor, event->fd, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE); + } + } + else +#endif + { + if (cli->onConnect) + { + execute_onConnect(cli); + } + } + return SW_OK; + } + +#ifdef SW_USE_OPENSSL + if (cli->open_ssl && cli->socket->ssl_state == SW_SSL_STATE_WAIT_STREAM) + { + if (swClient_ssl_handshake(cli) < 0) + { + goto connect_fail; + } + if (cli->socket->ssl_state != SW_SSL_STATE_READY) + { + return SW_OK; + } + //ssl handshake sucess + else if (cli->onConnect) + { + execute_onConnect(cli); + } + } +#endif + + /** + * redirect stream data to other socket + */ + if (cli->redirect) + { + int ret = 0; + n = swConnection_recv(event->socket, buf, buf_size, 0); + if (n < 0) + { + goto __error; + } + else if (n == 0) + { + goto __close; + } + if (cli->_redirect_to_socket) + { + ret = cli->reactor->write(cli->reactor, cli->_redirect_to_socket, buf, n); + } + else if (cli->_redirect_to_session) + { + if (SwooleG.serv->send(SwooleG.serv, cli->_redirect_to_session, buf, n) < 0) + { + if (SwooleG.error >= SW_ERROR_SESSION_CLOSED_BY_SERVER || SwooleG.error >= SW_ERROR_SESSION_INVALID_ID) + { + goto __close; + } + } + else + { + return SW_OK; + } + } + else + { + ret = swSocket_write_blocking(cli->_redirect_to_file, buf, n); + } + if (ret < 0) + { + goto __error; + } + return SW_OK; + } + + if (cli->open_eof_check || cli->open_length_check) + { + swConnection *conn = cli->socket; + swProtocol *protocol = &cli->protocol; + + if (cli->open_eof_check) + { + n = swProtocol_recv_check_eof(protocol, conn, cli->buffer); + } + else + { + n = swProtocol_recv_check_length(protocol, conn, cli->buffer); + } + + if (n < 0) + { + return cli->close(cli); + } + else + { + if (conn->removed == 0 && cli->remove_delay) + { + swClient_sleep(cli); + cli->remove_delay = 0; + } + return SW_OK; + } + } + +#ifdef SW_CLIENT_RECV_AGAIN + recv_again: +#endif + n = swConnection_recv(event->socket, buf, buf_size, 0); + if (n < 0) + { + __error: + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("Read from socket[%d] failed.", event->fd); + return SW_OK; + case SW_CLOSE: + goto __close; + case SW_WAIT: + return SW_OK; + default: + return SW_OK; + } + } + else if (n == 0) + { + __close: + return cli->close(cli); + } + else + { + cli->onReceive(cli, buf, n); +#ifdef SW_CLIENT_RECV_AGAIN + if (n == buf_size) + { + goto recv_again; + } +#endif + return SW_OK; + } + return SW_OK; +} + +static int swClient_onDgramRead(swReactor *reactor, swEvent *event) +{ + swClient *cli = event->socket->object; + char buffer[SW_BUFFER_SIZE_UDP]; + + int n = swClient_udp_recv(cli, buffer, sizeof(buffer), 0); + if (n < 0) + { + return SW_ERR; + } + else + { + cli->onReceive(cli, buffer, n); + } + return SW_OK; +} + +static int swClient_onError(swReactor *reactor, swEvent *event) +{ + swClient *cli = event->socket->object; + if (cli->socket->active) + { + return cli->close(cli); + } + else + { + swClient_onWrite(reactor, event); + } + return SW_OK; +} + +static void swClient_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + swClient *cli = (swClient *) tnode->data; + SwooleG.error = ETIMEDOUT; + +#ifdef SW_USE_OPENSSL + if (cli->open_ssl && cli->socket->ssl_state != SW_SSL_STATE_READY) + { + cli->socket->active = 0; + } +#endif + if (cli->socks5_proxy && cli->socks5_proxy->state != SW_SOCKS5_STATE_READY) + { + cli->socket->active = 0; + } + else if (cli->http_proxy && cli->http_proxy->state != SW_HTTP_PROXY_STATE_READY) + { + cli->socket->active = 0; + } + + cli->close(cli); + if (cli->onError) + { + cli->onError(cli); + } +} + +static void swClient_onResolveCompleted(swAio_event *event) +{ + swClient *cli = event->object; + cli->wait_dns = 0; + + if (event->error == 0) + { + swClient_tcp_connect_async(cli, event->buf, cli->server_port, cli->timeout, 1); + } + else + { + SwooleG.error = SW_ERROR_DNSLOOKUP_RESOLVE_FAILED; + cli->socket->removed = 1; + cli->close(cli); + if (cli->onError) + { + cli->onError(cli); + } + } + sw_free(event->buf); +} + +static int swClient_onWrite(swReactor *reactor, swEvent *event) +{ + swClient *cli = event->socket->object; + swConnection *_socket = cli->socket; + + if (cli->socket->active) + { +#ifdef SW_USE_OPENSSL + if (cli->open_ssl && _socket->ssl_state == SW_SSL_STATE_WAIT_STREAM) + { + if (swClient_ssl_handshake(cli) < 0) + { + goto connect_fail; + } + else if (_socket->ssl_state == SW_SSL_STATE_READY) + { + goto connect_success; + } + else + { + if (_socket->ssl_want_read) + { + cli->reactor->set(cli->reactor, event->fd, SW_FD_STREAM_CLIENT | SW_EVENT_READ); + } + return SW_OK; + } + } +#endif + if (swReactor_onWrite(cli->reactor, event) < 0) + { + return SW_ERR; + } + if (cli->onBufferEmpty && _socket->high_watermark && _socket->out_buffer->length <= cli->buffer_low_watermark) + { + _socket->high_watermark = 0; + cli->onBufferEmpty(cli); + } + return SW_OK; + } + + socklen_t len = sizeof(SwooleG.error); + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &SwooleG.error, &len) < 0) + { + swWarn("getsockopt(%d) failed. Error: %s[%d]", event->fd, strerror(errno), errno); + return SW_ERR; + } + + //success + if (SwooleG.error == 0) + { + //listen read event + cli->reactor->set(cli->reactor, event->fd, SW_FD_STREAM_CLIENT | SW_EVENT_READ); + //connected + _socket->active = 1; + //socks5 proxy + if (cli->socks5_proxy && cli->socks5_proxy->state == SW_SOCKS5_STATE_WAIT) + { + char buf[3]; + swSocks5_pack(buf, cli->socks5_proxy->username == NULL ? 0x00 : 0x02); + cli->socks5_proxy->state = SW_SOCKS5_STATE_HANDSHAKE; + return cli->send(cli, buf, sizeof(buf), 0); + } + //http proxy + if (cli->http_proxy && cli->http_proxy->state == SW_HTTP_PROXY_STATE_WAIT) + { +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + cli->http_proxy->state = SW_HTTP_PROXY_STATE_HANDSHAKE; + int n = snprintf(cli->http_proxy->buf, sizeof (cli->http_proxy->buf), "CONNECT %s:%d HTTP/1.1\r\n\r\n", cli->http_proxy->target_host, cli->http_proxy->target_port); + return cli->send(cli, cli->http_proxy->buf, n, 0); + } +#endif + } +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + if (swClient_enable_ssl_encrypt(cli) < 0) + { + goto connect_fail; + } + if (swClient_ssl_handshake(cli) < 0) + { + goto connect_fail; + } + else + { + _socket->ssl_state = SW_SSL_STATE_WAIT_STREAM; + } + return SW_OK; + } + connect_success: +#endif + if (cli->onConnect) + { + execute_onConnect(cli); + } + } + else + { +#ifdef SW_USE_OPENSSL + connect_fail: +#endif + _socket->active = 0; + cli->close(cli); + if (cli->onError) + { + cli->onError(cli); + } + } + + return SW_OK; +} + +void swoole_open_remote_debug(void) +{ + swClient debug_client; + swClient_create(&debug_client, SW_SOCK_UDP, 0); + + if (debug_client.connect(&debug_client, SW_DEBUG_SERVER_HOST, SW_DEBUG_SERVER_PORT, -1, 1) < 0) + { + swWarn("connect to remote_debug_server[%s:%d] failed.", SW_DEBUG_SERVER_HOST, SW_DEBUG_SERVER_PORT); + SwooleG.debug_fd = 1; + } + else + { + SwooleG.debug_fd = debug_client.socket->fd; + } +} diff --git a/vendor/swoole/src/network/Connection.c b/vendor/swoole/src/network/Connection.c new file mode 100755 index 0000000..a5174fa --- /dev/null +++ b/vendor/swoole/src/network/Connection.c @@ -0,0 +1,374 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" + +#include <sys/stat.h> + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +int swConnection_onSendfile(swConnection *conn, swBuffer_trunk *chunk) +{ + int ret; + swTask_sendfile *task = chunk->store.ptr; + +#ifdef HAVE_TCP_NOPUSH + if (task->offset == 0 && conn->tcp_nopush == 0) + { + /** + * disable tcp_nodelay + */ + if (conn->tcp_nodelay) + { + int tcp_nodelay = 0; + if (setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + swWarn("setsockopt(TCP_NODELAY) failed. Error: %s[%d]", strerror(errno), errno); + } + } + /** + * enable tcp_nopush + */ + if (swSocket_tcp_nopush(conn->fd, 1) == -1) + { + swWarn("swSocket_tcp_nopush() failed. Error: %s[%d]", strerror(errno), errno); + } + conn->tcp_nopush = 1; + } +#endif + + int sendn = (task->length - task->offset > SW_SENDFILE_CHUNK_SIZE) ? SW_SENDFILE_CHUNK_SIZE : task->length - task->offset; + +#ifdef SW_USE_OPENSSL + if (conn->ssl) + { + ret = swSSL_sendfile(conn, task->fd, &task->offset, sendn); + } + else +#endif + { + ret = swoole_sendfile(conn->fd, task->fd, &task->offset, sendn); + } + + swTrace("ret=%d|task->offset=%ld|sendn=%d|filesize=%ld", ret, (long)task->offset, sendn, task->length); + + if (ret <= 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("sendfile(%s, %ld, %d) failed.", task->filename, (long)task->offset, sendn); + swBuffer_pop_trunk(conn->out_buffer, chunk); + return SW_OK; + case SW_CLOSE: + conn->close_wait = 1; + return SW_ERR; + case SW_WAIT: + conn->send_wait = 1; + return SW_ERR; + default: + break; + } + } + + //sendfile finish + if (task->offset >= task->length) + { + swBuffer_pop_trunk(conn->out_buffer, chunk); + +#ifdef HAVE_TCP_NOPUSH + /** + * disable tcp_nopush + */ + if (swSocket_tcp_nopush(conn->fd, 0) == -1) + { + swWarn("swSocket_tcp_nopush() failed. Error: %s[%d]", strerror(errno), errno); + } + conn->tcp_nopush = 0; + + /** + * enable tcp_nodelay + */ + if (conn->tcp_nodelay) + { + int value = 1; + if (setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &value, sizeof(int)) == -1) + { + swWarn("setsockopt(TCP_NODELAY) failed. Error: %s[%d]", strerror(errno), errno); + } + } +#endif + } + return SW_OK; +} + +/** + * send buffer to client + */ +int swConnection_buffer_send(swConnection *conn) +{ + int ret, sendn; + + swBuffer *buffer = conn->out_buffer; + swBuffer_trunk *trunk = swBuffer_get_trunk(buffer); + sendn = trunk->length - trunk->offset; + + if (sendn == 0) + { + swBuffer_pop_trunk(buffer, trunk); + return SW_OK; + } + + ret = swConnection_send(conn, trunk->store.ptr + trunk->offset, sendn, 0); + if (ret < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swWarn("send to fd[%d] failed. Error: %s[%d]", conn->fd, strerror(errno), errno); + break; + case SW_CLOSE: + conn->close_errno = errno; + conn->close_wait = 1; + return SW_ERR; + case SW_WAIT: + conn->send_wait = 1; + return SW_ERR; + default: + break; + } + return SW_OK; + } + //trunk full send + else if (ret == sendn || sendn == 0) + { + swBuffer_pop_trunk(buffer, trunk); + } + else + { + trunk->offset += ret; + } + return SW_OK; +} + +swString* swConnection_get_string_buffer(swConnection *conn) +{ + swString *buffer = conn->object; + if (buffer == NULL) + { + return swString_new(SW_BUFFER_SIZE); + } + else + { + return buffer; + } +} + +static char tmp_address[INET6_ADDRSTRLEN]; + +char* swConnection_get_ip(swConnection *conn) +{ + if (conn->socket_type == SW_SOCK_TCP) + { + return inet_ntoa(conn->info.addr.inet_v4.sin_addr); + } + else if (conn->socket_type == SW_SOCK_TCP6) + { + if (inet_ntop(AF_INET6, &conn->info.addr.inet_v6.sin6_addr, tmp_address, sizeof(tmp_address)) == NULL) + { + return "unknown"; + } + else + { + return tmp_address; + } + } + else if (conn->socket_type == SW_SOCK_UNIX_STREAM) + { + return conn->info.addr.un.sun_path; + } + else + { + return "unknown"; + } +} + +int swConnection_get_port(swConnection *conn) +{ + if (conn->socket_type == SW_SOCK_TCP) + { + return ntohs(conn->info.addr.inet_v4.sin_port); + } + else + { + return ntohs(conn->info.addr.inet_v6.sin6_port); + } +} + +void swConnection_sendfile_destructor(swBuffer_trunk *chunk) +{ + swTask_sendfile *task = chunk->store.ptr; + close(task->fd); + sw_free(task->filename); + sw_free(task); +} + +int swConnection_sendfile(swConnection *conn, char *filename, off_t offset, size_t length) +{ + if (conn->out_buffer == NULL) + { + conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE); + if (conn->out_buffer == NULL) + { + return SW_ERR; + } + } + + swBuffer_trunk error_chunk; + swTask_sendfile *task = sw_malloc(sizeof(swTask_sendfile)); + if (task == NULL) + { + swWarn("malloc for swTask_sendfile failed."); + return SW_ERR; + } + bzero(task, sizeof(swTask_sendfile)); + + task->filename = sw_strdup(filename); + int file_fd = open(filename, O_RDONLY); + if (file_fd < 0) + { + sw_free(task->filename); + sw_free(task); + swSysError("open(%s) failed.", filename); + return SW_OK; + } + task->fd = file_fd; + task->offset = offset; + + struct stat file_stat; + if (fstat(file_fd, &file_stat) < 0) + { + swSysError("fstat(%s) failed.", filename); + error_chunk.store.ptr = task; + swConnection_sendfile_destructor(&error_chunk); + return SW_ERR; + } + if (offset < 0 || (length + offset > file_stat.st_size)) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_INVALID_PARAMS, "length or offset is invalid."); + error_chunk.store.ptr = task; + swConnection_sendfile_destructor(&error_chunk); + return SW_OK; + } + if (length == 0) + { + task->length = file_stat.st_size; + } + else + { + task->length = length + offset; + } + + swBuffer_trunk *chunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_SENDFILE, 0); + if (chunk == NULL) + { + swWarn("get out_buffer trunk failed."); + error_chunk.store.ptr = task; + swConnection_sendfile_destructor(&error_chunk); + return SW_ERR; + } + + chunk->store.ptr = (void *) task; + chunk->destroy = swConnection_sendfile_destructor; + + return SW_OK; +} + + +void swConnection_clear_string_buffer(swConnection *conn) +{ + swString *buffer = conn->object; + if (buffer != NULL) + { + swString_free(buffer); + conn->object = NULL; + } +} + +swBuffer_trunk* swConnection_get_in_buffer(swConnection *conn) +{ + swBuffer_trunk *trunk = NULL; + swBuffer *buffer; + + if (conn->in_buffer == NULL) + { + buffer = swBuffer_new(SW_BUFFER_SIZE); + //buffer create failed + if (buffer == NULL) + { + return NULL; + } + //new trunk + trunk = swBuffer_new_trunk(buffer, SW_CHUNK_DATA, buffer->trunk_size); + if (trunk == NULL) + { + sw_free(buffer); + return NULL; + } + conn->in_buffer = buffer; + } + else + { + buffer = conn->in_buffer; + trunk = buffer->tail; + if (trunk == NULL || trunk->length == buffer->trunk_size) + { + trunk = swBuffer_new_trunk(buffer, SW_CHUNK_DATA, buffer->trunk_size); + } + } + return trunk; +} + +swBuffer_trunk* swConnection_get_out_buffer(swConnection *conn, uint32_t type) +{ + swBuffer_trunk *trunk; + if (conn->out_buffer == NULL) + { + conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE); + if (conn->out_buffer == NULL) + { + return NULL; + } + } + if (type == SW_CHUNK_SENDFILE) + { + trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_SENDFILE, 0); + } + else + { + trunk = swBuffer_get_trunk(conn->out_buffer); + if (trunk == NULL) + { + trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_DATA, conn->out_buffer->trunk_size); + } + } + return trunk; +} diff --git a/vendor/swoole/src/network/DNS.c b/vendor/swoole/src/network/DNS.c new file mode 100755 index 0000000..68f4f0a --- /dev/null +++ b/vendor/swoole/src/network/DNS.c @@ -0,0 +1,485 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Client.h" + +#define SW_DNS_SERVER_CONF "/etc/resolv.conf" +#define SW_DNS_SERVER_NUM 2 + +enum swDNS_type +{ + SW_DNS_A_RECORD = 0x01, //Lookup IPv4 address + SW_DNS_AAAA_RECORD = 0x1c, //Lookup IPv6 address + SW_DNS_MX_RECORD = 0x0f //Lookup mail server for domain +}; + +enum swDNS_error +{ + SW_DNS_NOT_EXIST, //Error: adress does not exist + SW_DNS_TIMEOUT, //Lookup time expired + SW_DNS_ERROR //No memory or other error +}; + +typedef struct +{ + void (*callback)(char *domain, swDNSResolver_result *result, void *data); + char *domain; + void *data; +} swDNS_lookup_request; + +typedef struct +{ + uint8_t num; + +} swDNS_result; + +/* Struct for the DNS Header */ +typedef struct +{ + uint16_t id; + uchar rd :1; + uchar tc :1; + uchar aa :1; + uchar opcode :4; + uchar qr :1; + uchar rcode :4; + uchar z :3; + uchar ra :1; + uint16_t qdcount; + uint16_t ancount; + uint16_t nscount; + uint16_t arcount; +} swDNSResolver_header; + +/* Struct for the flags for the DNS Question */ +typedef struct q_flags +{ + uint16_t qtype; + uint16_t qclass; +} Q_FLAGS; + +/* Struct for the flags for the DNS RRs */ +typedef struct rr_flags +{ + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlength; +} RR_FLAGS; + +static uint16_t swoole_dns_request_id = 1; +static swClient *resolver_socket = NULL; +static swHashMap *request_map = NULL; + +static int domain_encode(char *src, int n, char *dest); +static void domain_decode(char *str); +static int swDNSResolver_get_server(); +static int swDNSResolver_onReceive(swReactor *reactor, swEvent *event); + +static int swDNSResolver_get_server() +{ + FILE *fp; + char line[100]; + char buf[16] = {0}; + + if ((fp = fopen(SW_DNS_SERVER_CONF, "rt")) == NULL) + { + swWarn("fopen("SW_DNS_SERVER_CONF") failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + + while (fgets(line, 100, fp)) + { + if (strncmp(line, "nameserver", 10) == 0) + { + strcpy(buf, strtok(line, " ")); + strcpy(buf, strtok(NULL, "\n")); + break; + } + } + fclose(fp); + + if (strlen(buf) == 0) + { + SwooleG.dns_server_v4 = sw_strdup(SW_DNS_DEFAULT_SERVER); + } + else + { + SwooleG.dns_server_v4 = sw_strdup(buf); + } + + return SW_OK; +} + +static int swDNSResolver_onReceive(swReactor *reactor, swEvent *event) +{ + swDNSResolver_header *header = NULL; + Q_FLAGS *qflags = NULL; + RR_FLAGS *rrflags = NULL; + + char packet[SW_CLIENT_BUFFER_SIZE]; + uchar rdata[10][254]; + uint32_t type[10]; + + char *temp; + uint16_t steps; + + char *_domain_name; + char name[10][254]; + int i, j; + + int ret = recv(event->fd, packet, sizeof(packet) - 1, 0); + if (ret <= 0) + { + return SW_ERR; + } + + packet[ret] = 0; + header = (swDNSResolver_header *) packet; + steps = sizeof(swDNSResolver_header); + + _domain_name = &packet[steps]; + domain_decode(_domain_name); + steps = steps + (strlen(_domain_name) + 2); + + qflags = (Q_FLAGS *) &packet[steps]; + (void) qflags; + steps = steps + sizeof(Q_FLAGS); + + int ancount = ntohs(header->ancount); + if (ancount > 10) + { + ancount = 10; + } + /* Parsing the RRs from the reply packet */ + for (i = 0; i < ancount; ++i) + { + type[i] = 0; + /* Parsing the NAME portion of the RR */ + temp = &packet[steps]; + j = 0; + while (*temp != 0) + { + if ((uchar) (*temp) == 0xc0) + { + ++temp; + temp = &packet[(uint8_t) *temp]; + } + else + { + name[i][j] = *temp; + ++j; + ++temp; + } + } + name[i][j] = '\0'; + + domain_decode(name[i]); + steps = steps + 2; + + /* Parsing the RR flags of the RR */ + rrflags = (RR_FLAGS *) &packet[steps]; + steps = steps + sizeof(RR_FLAGS) - 2; + + /* Parsing the IPv4 address in the RR */ + if (ntohs(rrflags->type) == 1) + { + for (j = 0; j < ntohs(rrflags->rdlength); ++j) + { + rdata[i][j] = (uchar) packet[steps + j]; + } + type[i] = ntohs(rrflags->type); + } + + /* Parsing the canonical name in the RR */ + if (ntohs(rrflags->type) == 5) + { + temp = &packet[steps]; + j = 0; + while (*temp != 0) + { + if ((uchar)(*temp) == 0xc0) + { + ++temp; + temp = &packet[(uint8_t) *temp]; + } + else + { + rdata[i][j] = *temp; + ++j; + ++temp; + } + } + rdata[i][j] = '\0'; + domain_decode((char *) rdata[i]); + type[i] = ntohs(rrflags->type); + } + steps = steps + ntohs(rrflags->rdlength); + } + + char key[1024]; + int request_id = ntohs(header->id); + int key_len = snprintf(key, sizeof(key), "%s-%d", _domain_name, request_id); + swDNS_lookup_request *request = swHashMap_find(request_map, key, key_len); + if (request == NULL) + { + swWarn("bad response, request_id=%d.", request_id); + return SW_OK; + } + + swDNSResolver_result result; + bzero(&result, sizeof(result)); + + for (i = 0; i < ancount; ++i) + { + if (type[i] != SW_DNS_A_RECORD) + { + continue; + } + j = result.num; + result.num++; + result.hosts[j].length = sprintf(result.hosts[j].address, "%d.%d.%d.%d", rdata[i][0], rdata[i][1], rdata[i][2], rdata[i][3]); + if (result.num == SW_DNS_HOST_BUFFER_SIZE) + { + break; + } + } + + request->callback(request->domain, &result, request->data); + swHashMap_del(request_map, key, key_len); + sw_free(request->domain); + sw_free(request); + + return SW_OK; +} + +int swDNSResolver_request(char *domain, void (*callback)(char *, swDNSResolver_result *, void *), void *data) +{ + char *_domain_name; + Q_FLAGS *qflags = NULL; + char packet[SW_BUFFER_SIZE_STD]; + char key[1024]; + swDNSResolver_header *header = NULL; + int steps = 0; + + if (SwooleG.dns_server_v4 == NULL) + { + if (swDNSResolver_get_server() < 0) + { + return SW_ERR; + } + } + + header = (swDNSResolver_header *) packet; + header->id = htons(swoole_dns_request_id); + header->qr = 0; + header->opcode = 0; + header->aa = 0; + header->tc = 0; + header->rd = 1; + header->ra = 0; + header->z = 0; + header->rcode = 0; + header->qdcount = htons(1); + header->ancount = 0x0000; + header->nscount = 0x0000; + header->arcount = 0x0000; + + steps = sizeof(swDNSResolver_header); + + _domain_name = &packet[steps]; + + int len = strlen(domain); + if (len >= sizeof(key)) + { + swWarn("domain name is too long."); + return SW_ERR; + } + + int key_len = snprintf(key, sizeof(key), "%s-%d", domain, swoole_dns_request_id); + if (!request_map) + { + request_map = swHashMap_new(128, NULL); + } + else if (swHashMap_find(request_map, key, key_len)) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_DNSLOOKUP_DUPLICATE_REQUEST, "duplicate request."); + return SW_ERR; + } + + swDNS_lookup_request *request = sw_malloc(sizeof(swDNS_lookup_request)); + if (request == NULL) + { + swWarn("malloc(%d) failed.", (int ) sizeof(swDNS_lookup_request)); + return SW_ERR; + } + request->domain = sw_strndup(domain, len + 1); + if (request->domain == NULL) + { + swWarn("strdup(%d) failed.", len + 1); + sw_free(request); + return SW_ERR; + } + request->data = data; + request->callback = callback; + + if (domain_encode(request->domain, len, _domain_name) < 0) + { + swWarn("invalid domain[%s].", domain); + sw_free(request->domain); + sw_free(request); + return SW_ERR; + } + + steps += (strlen((const char *) _domain_name) + 1); + + qflags = (Q_FLAGS *) &packet[steps]; + qflags->qtype = htons(SW_DNS_A_RECORD); + qflags->qclass = htons(0x0001); + steps += sizeof(Q_FLAGS); + + if (resolver_socket == NULL) + { + resolver_socket = sw_malloc(sizeof(swClient)); + if (resolver_socket == NULL) + { + sw_free(request->domain); + sw_free(request); + swWarn("malloc failed."); + return SW_ERR; + } + if (swClient_create(resolver_socket, SW_SOCK_UDP, 0) < 0) + { + sw_free(resolver_socket); + sw_free(request->domain); + sw_free(request); + return SW_ERR; + } + char *_port; + int dns_server_port = SW_DNS_SERVER_PORT; + char dns_server_host[32]; + strcpy(dns_server_host, SwooleG.dns_server_v4); + if ((_port = strchr(SwooleG.dns_server_v4, ':'))) + { + dns_server_port = atoi(_port + 1); + dns_server_host[_port - SwooleG.dns_server_v4] = '\0'; + } + if (resolver_socket->connect(resolver_socket, dns_server_host, dns_server_port, 1, 0) < 0) + { + do_close: resolver_socket->close(resolver_socket); + swClient_free(resolver_socket); + sw_free(resolver_socket); + sw_free(request->domain); + sw_free(request); + resolver_socket = NULL; + return SW_ERR; + } + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_DNS_RESOLVER, swDNSResolver_onReceive); + if (SwooleG.main_reactor->add(SwooleG.main_reactor, resolver_socket->socket->fd, SW_FD_DNS_RESOLVER)) + { + goto do_close; + } + } + + if (resolver_socket->send(resolver_socket, (char *) packet, steps, 0) < 0) + { + goto do_close; + } + + swHashMap_add(request_map, key, key_len, request); + swoole_dns_request_id++; + return SW_OK; +} + +int swDNSResolver_free() +{ + if (resolver_socket == NULL) + { + return SW_ERR; + } + if (SwooleG.main_reactor == NULL) + { + return SW_ERR; + } + if (swHashMap_count(request_map) > 0) + { + return SW_ERR; + } + + SwooleG.main_reactor->del(SwooleG.main_reactor, resolver_socket->socket->fd); + resolver_socket->close(resolver_socket); + swClient_free(resolver_socket); + sw_free(resolver_socket); + resolver_socket = NULL; + swHashMap_free(request_map); + request_map = NULL; + + return SW_OK; +} + +/** + * The function converts the dot-based hostname into the DNS format + * (i.e. www.apple.com into 3www5apple3com0) + */ +static int domain_encode(char *src, int n, char *dest) +{ + if (src[n] == '.') + { + return SW_ERR; + } + + int pos = 0; + int i; + int len = 0; + memcpy(dest + 1, src, n + 1); + dest[n + 1] = '.'; + dest[n + 2] = 0; + src = dest + 1; + n++; + + for (i = 0; i < n; i++) + { + if (src[i] == '.') + { + len = i - pos; + dest[pos] = len; + pos += len + 1; + } + } + dest[pos] = 0; + return SW_OK; +} + +/** + * This function converts a DNS-based hostname into dot-based format + * (i.e. 3www5apple3com0 into www.apple.com) + */ +static void domain_decode(char *str) +{ + int i, j; + for (i = 0; i < strlen((const char*) str); i++) + { + unsigned int len = str[i]; + for (j = 0; j < len; j++) + { + str[i] = str[i + 1]; + i++; + } + str[i] = '.'; + } + str[i - 1] = '\0'; +} diff --git a/vendor/swoole/src/network/Manager.c b/vendor/swoole/src/network/Manager.c new file mode 100755 index 0000000..fec6d64 --- /dev/null +++ b/vendor/swoole/src/network/Manager.c @@ -0,0 +1,642 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Server.h" + +#include <sys/wait.h> + +typedef struct +{ + uint8_t reloading; + uint8_t reload_all_worker; + uint8_t reload_task_worker; + uint8_t read_message; + uint8_t alarm; + +} swManagerProcess; + +static int swManager_loop(swFactory *factory); +static void swManager_signal_handle(int sig); +static pid_t swManager_spawn_worker(swFactory *factory, int worker_id); +static void swManager_check_exit_status(swServer *serv, int worker_id, pid_t pid, int status); + +static swManagerProcess ManagerProcess; + +//create worker child proccess +int swManager_start(swFactory *factory) +{ + swFactoryProcess *object = factory->object; + int i; + pid_t pid; + swServer *serv = factory->ptr; + + object->pipes = sw_calloc(serv->worker_num, sizeof(swPipe)); + if (object->pipes == NULL) + { + swError("malloc[worker_pipes] failed. Error: %s [%d]", strerror(errno), errno); + return SW_ERR; + } + + //worker进程的pipes + for (i = 0; i < serv->worker_num; i++) + { + if (swPipeUnsock_create(&object->pipes[i], 1, SOCK_DGRAM) < 0) + { + return SW_ERR; + } + serv->workers[i].pipe_master = object->pipes[i].getFd(&object->pipes[i], SW_PIPE_MASTER); + serv->workers[i].pipe_worker = object->pipes[i].getFd(&object->pipes[i], SW_PIPE_WORKER); + serv->workers[i].pipe_object = &object->pipes[i]; + swServer_store_pipe_fd(serv, serv->workers[i].pipe_object); + } + + if (serv->task_worker_num > 0) + { + if (swServer_create_task_worker(serv) < 0) + { + return SW_ERR; + } + + swProcessPool *pool = &serv->gs->task_workers; + swTaskWorker_init(pool); + + swWorker *worker; + for (i = 0; i < serv->task_worker_num; i++) + { + worker = &pool->workers[i]; + if (swWorker_create(worker) < 0) + { + return SW_ERR; + } + if (serv->task_ipc_mode == SW_TASK_IPC_UNIXSOCK) + { + swServer_store_pipe_fd(SwooleG.serv, worker->pipe_object); + } + } + } + + //User Worker Process + if (serv->user_worker_num > 0) + { + serv->user_workers = SwooleG.memory_pool->alloc(SwooleG.memory_pool, serv->user_worker_num * sizeof(swWorker)); + if (serv->user_workers == NULL) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "gmalloc[server->user_workers] failed."); + return SW_ERR; + } + swUserWorker_node *user_worker; + i = 0; + LL_FOREACH(serv->user_worker_list, user_worker) + { + memcpy(&serv->user_workers[i], user_worker->worker, sizeof(swWorker)); + if (swWorker_create(&serv->user_workers[i]) < 0) + { + return SW_ERR; + } + i++; + } + } + + serv->message_box = swChannel_new(65536, sizeof(swWorkerStopMessage), SW_CHAN_LOCK | SW_CHAN_SHM); + if (serv->message_box == NULL) + { + return SW_ERR; + } + + pid = fork(); + switch (pid) + { + //fork manager process + case 0: + //wait master process + SW_START_SLEEP; + if (serv->gs->start == 0) + { + return SW_OK; + } + swServer_close_listen_port(serv); + + /** + * create task worker process + */ + if (serv->task_worker_num > 0) + { + swProcessPool_start(&serv->gs->task_workers); + } + /** + * create worker process + */ + for (i = 0; i < serv->worker_num; i++) + { + //close(worker_pipes[i].pipes[0]); + pid = swManager_spawn_worker(factory, i); + if (pid < 0) + { + swError("fork() failed."); + return SW_ERR; + } + else + { + serv->workers[i].pid = pid; + } + } + /** + * create user worker process + */ + if (serv->user_worker_list) + { + swUserWorker_node *user_worker; + LL_FOREACH(serv->user_worker_list, user_worker) + { + /** + * store the pipe object + */ + if (user_worker->worker->pipe_object) + { + swServer_store_pipe_fd(serv, user_worker->worker->pipe_object); + } + swManager_spawn_user_worker(serv, user_worker->worker); + } + } + + SwooleG.process_type = SW_PROCESS_MANAGER; + SwooleG.pid = getpid(); + exit(swManager_loop(factory)); + break; + + //master process + default: + serv->gs->manager_pid = pid; + break; + case -1: + swError("fork() failed."); + return SW_ERR; + } + return SW_OK; +} + +static void swManager_check_exit_status(swServer *serv, int worker_id, pid_t pid, int status) +{ + if (status != 0) + { + swWarn("worker#%d abnormal exit, status=%d, signal=%d", worker_id, WEXITSTATUS(status), WTERMSIG(status)); + if (serv->onWorkerError != NULL) + { + serv->onWorkerError(serv, worker_id, pid, WEXITSTATUS(status), WTERMSIG(status)); + } + } +} + +static int swManager_loop(swFactory *factory) +{ + int pid, new_pid; + int i; + int reload_worker_i = 0; + int reload_worker_num; + int reload_init = 0; + pid_t reload_worker_pid = 0; + + int status; + + SwooleG.use_signalfd = 0; + SwooleG.use_timerfd = 0; + + memset(&ManagerProcess, 0, sizeof(ManagerProcess)); + + swServer *serv = factory->ptr; + swWorker *reload_workers; + + if (serv->hooks[SW_SERVER_HOOK_MANAGER_START]) + { + swServer_call_hook(serv, SW_SERVER_HOOK_MANAGER_START, serv); + } + + if (serv->onManagerStart) + { + serv->onManagerStart(serv); + } + + reload_worker_num = serv->worker_num + serv->task_worker_num; + reload_workers = sw_calloc(reload_worker_num, sizeof(swWorker)); + if (reload_workers == NULL) + { + swError("malloc[reload_workers] failed"); + return SW_ERR; + } + + //for reload + swSignal_add(SIGHUP, NULL); + swSignal_add(SIGTERM, swManager_signal_handle); + swSignal_add(SIGUSR1, swManager_signal_handle); + swSignal_add(SIGUSR2, swManager_signal_handle); + swSignal_add(SIGIO, swManager_signal_handle); +#ifdef SIGRTMIN + swSignal_add(SIGRTMIN, swManager_signal_handle); +#endif + //swSignal_add(SIGINT, swManager_signal_handle); + + if (serv->manager_alarm > 0) + { + alarm(serv->manager_alarm); + swSignal_add(SIGALRM, swManager_signal_handle); + } + + SwooleG.main_reactor = NULL; + + while (SwooleG.running > 0) + { + _wait: pid = wait(&status); + + if (ManagerProcess.read_message) + { + swWorkerStopMessage msg; + while (swChannel_pop(serv->message_box, &msg, sizeof(msg)) > 0) + { + if (SwooleG.running == 0) + { + continue; + } + pid_t new_pid = swManager_spawn_worker(factory, msg.worker_id); + if (new_pid > 0) + { + serv->workers[msg.worker_id].pid = new_pid; + } + } + ManagerProcess.read_message = 0; + } + + if (pid < 0) + { + if (ManagerProcess.alarm == 1) + { + ManagerProcess.alarm = 0; + alarm(serv->manager_alarm); + + if (serv->hooks[SW_SERVER_HOOK_MANAGER_TIMER]) + { + swServer_call_hook(serv, SW_SERVER_HOOK_MANAGER_TIMER, serv); + } + } + + if (ManagerProcess.reloading == 0) + { + error: if (errno != EINTR) + { + swSysError("wait() failed."); + } + continue; + } + //reload task & event workers + else if (ManagerProcess.reload_all_worker == 1) + { + swNotice("Server is reloading now."); + if (reload_init == 0) + { + reload_init = 1; + memcpy(reload_workers, serv->workers, sizeof(swWorker) * serv->worker_num); + reload_worker_num = serv->worker_num; + + if (serv->task_worker_num > 0) + { + memcpy(reload_workers + serv->worker_num, serv->gs->task_workers.workers, + sizeof(swWorker) * serv->task_worker_num); + reload_worker_num += serv->task_worker_num; + } + + ManagerProcess.reload_all_worker = 0; + if (serv->reload_async) + { + for (i = 0; i < serv->worker_num; i++) + { + if (kill(reload_workers[i].pid, SIGTERM) < 0) + { + swSysError("kill(%d, SIGTERM) [%d] failed.", reload_workers[i].pid, i); + } + } + reload_worker_i = serv->worker_num; + } + else + { + reload_worker_i = 0; + } + } + goto kill_worker; + } + //only reload task workers + else if (ManagerProcess.reload_task_worker == 1) + { + if (serv->task_worker_num == 0) + { + swWarn("cannot reload task workers, task workers is not started."); + continue; + } + swNotice("Server is reloading now."); + if (reload_init == 0) + { + memcpy(reload_workers, serv->gs->task_workers.workers, sizeof(swWorker) * serv->task_worker_num); + reload_worker_num = serv->task_worker_num; + reload_worker_i = 0; + reload_init = 1; + ManagerProcess.reload_task_worker = 0; + } + goto kill_worker; + } + else + { + goto error; + } + } + if (SwooleG.running == 1) + { + //event workers + for (i = 0; i < serv->worker_num; i++) + { + //compare PID + if (pid != serv->workers[i].pid) + { + continue; + } + + if (WIFSTOPPED(status) && serv->workers[i].tracer) + { + serv->workers[i].tracer(&serv->workers[i]); + serv->workers[i].tracer = NULL; + goto _wait; + } + + //Check the process return code and signal + swManager_check_exit_status(serv, i, pid, status); + + while (1) + { + new_pid = swManager_spawn_worker(factory, i); + if (new_pid < 0) + { + usleep(100000); + continue; + } + else + { + serv->workers[i].pid = new_pid; + break; + } + } + } + + swWorker *exit_worker; + //task worker + if (serv->gs->task_workers.map) + { + exit_worker = swHashMap_find_int(serv->gs->task_workers.map, pid); + if (exit_worker != NULL) + { + if (WIFSTOPPED(status) && exit_worker->tracer) + { + exit_worker->tracer(exit_worker); + exit_worker->tracer = NULL; + goto _wait; + } + swManager_check_exit_status(serv, exit_worker->id, pid, status); + swProcessPool_spawn(&serv->gs->task_workers, exit_worker); + } + } + //user process + if (serv->user_worker_map != NULL) + { + swManager_wait_user_worker(&serv->gs->event_workers, pid, status); + } + if (pid == reload_worker_pid) + { + reload_worker_i++; + } + } + //reload worker + kill_worker: if (ManagerProcess.reloading == 1) + { + //reload finish + if (reload_worker_i >= reload_worker_num) + { + reload_worker_pid = reload_worker_i = reload_init = ManagerProcess.reloading = 0; + continue; + } + reload_worker_pid = reload_workers[reload_worker_i].pid; + if (kill(reload_worker_pid, SIGTERM) < 0) + { + if (errno == ECHILD) + { + reload_worker_i++; + goto kill_worker; + } + swSysError("kill(%d, SIGTERM) [%d] failed.", reload_workers[reload_worker_i].pid, reload_worker_i); + } + } + } + + sw_free(reload_workers); + swSignal_none(); + //kill all child process + for (i = 0; i < serv->worker_num; i++) + { + swTrace("[Manager]kill worker processor"); + kill(serv->workers[i].pid, SIGTERM); + } + //kill and wait task process + if (serv->task_worker_num > 0) + { + swProcessPool_shutdown(&serv->gs->task_workers); + } + //wait child process + for (i = 0; i < serv->worker_num; i++) + { + if (swWaitpid(serv->workers[i].pid, &status, 0) < 0) + { + swSysError("waitpid(%d) failed.", serv->workers[i].pid); + } + } + //kill all user process + if (serv->user_worker_map) + { + swManager_kill_user_worker(serv); + } + + if (serv->onManagerStop) + { + serv->onManagerStop(serv); + } + + return SW_OK; +} + +static pid_t swManager_spawn_worker(swFactory *factory, int worker_id) +{ + pid_t pid; + int ret; + + pid = fork(); + + //fork() failed + if (pid < 0) + { + swWarn("Fork Worker failed. Error: %s [%d]", strerror(errno), errno); + return SW_ERR; + } + //worker child processor + else if (pid == 0) + { + ret = swWorker_loop(factory, worker_id); + exit(ret); + } + //parent,add to writer + else + { + return pid; + } +} + +static void swManager_signal_handle(int sig) +{ + switch (sig) + { + case SIGTERM: + SwooleG.running = 0; + break; + /** + * reload all workers + */ + case SIGUSR1: + if (ManagerProcess.reloading == 0) + { + ManagerProcess.reloading = 1; + ManagerProcess.reload_all_worker = 1; + } + break; + /** + * only reload task workers + */ + case SIGUSR2: + if (ManagerProcess.reloading == 0) + { + ManagerProcess.reloading = 1; + ManagerProcess.reload_task_worker = 1; + } + break; + case SIGIO: + ManagerProcess.read_message = 1; + break; + case SIGALRM: + ManagerProcess.alarm = 1; + break; + default: +#ifdef SIGRTMIN + if (sig == SIGRTMIN) + { + swServer_reopen_log_file(SwooleG.serv); + } +#endif + break; + } +} + +int swManager_wait_user_worker(swProcessPool *pool, pid_t pid, int status) +{ + swServer *serv = SwooleG.serv; + swWorker *exit_worker = swHashMap_find_int(serv->user_worker_map, pid); + if (exit_worker != NULL) + { + swManager_check_exit_status(serv, exit_worker->id, pid, status); + return swManager_spawn_user_worker(serv, exit_worker); + } + else + { + return SW_ERR; + } +} + +void swManager_kill_user_worker(swServer *serv) +{ + if (!serv->user_worker_map) + { + return; + } + swWorker* user_worker; + uint64_t key; + int __stat_loc; + + //kill user process + while (1) + { + user_worker = swHashMap_each_int(serv->user_worker_map, &key); + //hashmap empty + if (user_worker == NULL) + { + break; + } + kill(user_worker->pid, SIGTERM); + } + + //wait user process + while (1) + { + user_worker = swHashMap_each_int(serv->user_worker_map, &key); + //hashmap empty + if (user_worker == NULL) + { + break; + } + if (swWaitpid(user_worker->pid, &__stat_loc, 0) < 0) + { + swSysError("waitpid(%d) failed.", user_worker->pid); + } + } +} + +pid_t swManager_spawn_user_worker(swServer *serv, swWorker* worker) +{ + pid_t pid = fork(); + + if (pid < 0) + { + swWarn("Fork Worker failed. Error: %s [%d]", strerror(errno), errno); + return SW_ERR; + } + //child + else if (pid == 0) + { + SwooleG.process_type = SW_PROCESS_USERWORKER; + SwooleWG.worker = worker; + SwooleWG.id = worker->id; + worker->pid = getpid(); + //close tcp listen socket + if (serv->factory_mode == SW_MODE_SINGLE) + { + swServer_close_port(serv, SW_TRUE); + } + serv->onUserWorkerStart(serv, worker); + exit(0); + } + //parent + else + { + if (worker->pid) + { + swHashMap_del_int(serv->user_worker_map, worker->pid); + } + worker->pid = pid; + swHashMap_add_int(serv->user_worker_map, pid, worker); + return pid; + } +} diff --git a/vendor/swoole/src/network/Port.c b/vendor/swoole/src/network/Port.c new file mode 100755 index 0000000..da5d640 --- /dev/null +++ b/vendor/swoole/src/network/Port.c @@ -0,0 +1,757 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "Server.h" +#include "http.h" +#include "http2.h" +#include "websocket.h" +#include "mqtt.h" +#include "redis.h" + +#include <sys/stat.h> + +static int swPort_onRead_raw(swReactor *reactor, swListenPort *lp, swEvent *event); +static int swPort_onRead_check_length(swReactor *reactor, swListenPort *lp, swEvent *event); +static int swPort_onRead_check_eof(swReactor *reactor, swListenPort *lp, swEvent *event); +static int swPort_onRead_http(swReactor *reactor, swListenPort *lp, swEvent *event); +static int swPort_onRead_redis(swReactor *reactor, swListenPort *lp, swEvent *event); +static int swPort_http_static_handler(swHttpRequest *request, swConnection *conn); + +void swPort_init(swListenPort *port) +{ + port->sock = 0; + port->ssl = 0; + + //listen backlog + port->backlog = SW_BACKLOG; + //tcp keepalive + port->tcp_keepcount = SW_TCP_KEEPCOUNT; + port->tcp_keepinterval = SW_TCP_KEEPINTERVAL; + port->tcp_keepidle = SW_TCP_KEEPIDLE; + port->open_tcp_nopush = 1; + + port->protocol.package_length_type = 'N'; + port->protocol.package_length_size = 4; + port->protocol.package_body_offset = 4; + port->protocol.package_max_length = SW_BUFFER_INPUT_SIZE; + + port->socket_buffer_size = SwooleG.socket_buffer_size; + + char eof[] = SW_DATA_EOF; + port->protocol.package_eof_len = sizeof(SW_DATA_EOF) - 1; + memcpy(port->protocol.package_eof, eof, port->protocol.package_eof_len); +} + +#ifdef SW_USE_OPENSSL +int swPort_enable_ssl_encrypt(swListenPort *ls) +{ + if (ls->ssl_option.cert_file == NULL || ls->ssl_option.key_file == NULL) + { + swWarn("SSL error, require ssl_cert_file and ssl_key_file."); + return SW_ERR; + } + ls->ssl_context = swSSL_get_context(&ls->ssl_option); + if (ls->ssl_context == NULL) + { + swWarn("swSSL_get_context() error."); + return SW_ERR; + } + /** + * OpenSSL thread-safe + */ + swSSL_init_thread_safety(); + + if (ls->ssl_option.client_cert_file + && swSSL_set_client_certificate(ls->ssl_context, ls->ssl_option.client_cert_file, + ls->ssl_option.verify_depth) == SW_ERR) + { + swWarn("swSSL_set_client_certificate() error."); + return SW_ERR; + } + if (ls->open_http_protocol) + { + ls->ssl_config.http = 1; + } + if (ls->open_http2_protocol) + { + ls->ssl_config.http_v2 = 1; + swSSL_server_http_advise(ls->ssl_context, &ls->ssl_config); + } + if (swSSL_server_set_cipher(ls->ssl_context, &ls->ssl_config) < 0) + { + swWarn("swSSL_server_set_cipher() error."); + return SW_ERR; + } + return SW_OK; +} +#endif + +int swPort_listen(swListenPort *ls) +{ + int sock = ls->sock; + int option = 1; + + //listen stream socket + if (listen(sock, ls->backlog) < 0) + { + swWarn("listen(%s:%d, %d) failed. Error: %s[%d]", ls->host, ls->port, ls->backlog, strerror(errno), errno); + return SW_ERR; + } + +#ifdef TCP_DEFER_ACCEPT + if (ls->tcp_defer_accept) + { + if (setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (const void*) &ls->tcp_defer_accept, sizeof(int)) < 0) + { + swSysError("setsockopt(TCP_DEFER_ACCEPT) failed."); + } + } +#endif + +#ifdef TCP_FASTOPEN + if (ls->tcp_fastopen) + { + if (setsockopt(sock, IPPROTO_TCP, TCP_FASTOPEN, (const void*) &ls->tcp_fastopen, sizeof(int)) < 0) + { + swSysError("setsockopt(TCP_FASTOPEN) failed."); + } + } +#endif + +#ifdef SO_KEEPALIVE + if (ls->open_tcp_keepalive == 1) + { + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *) &option, sizeof(option)) < 0) + { + swSysError("setsockopt(SO_KEEPALIVE) failed."); + } +#ifdef TCP_KEEPIDLE + setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &ls->tcp_keepidle, sizeof(int)); + setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *) &ls->tcp_keepinterval, sizeof(int)); + setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *) &ls->tcp_keepcount, sizeof(int)); +#endif + } +#endif + + ls->buffer_high_watermark = ls->socket_buffer_size * 0.8; + ls->buffer_low_watermark = 0; + + return SW_OK; +} + + +void swPort_set_protocol(swListenPort *ls) +{ + //Thread mode must copy the data. + //will free after onFinish + if (ls->open_eof_check) + { + if (ls->protocol.package_eof_len > sizeof(ls->protocol.package_eof)) + { + ls->protocol.package_eof_len = sizeof(ls->protocol.package_eof); + } + ls->protocol.onPackage = swReactorThread_dispatch; + ls->onRead = swPort_onRead_check_eof; + } + else if (ls->open_length_check) + { + if (ls->protocol.package_length_type != '\0') + { + ls->protocol.get_package_length = swProtocol_get_package_length; + } + ls->protocol.onPackage = swReactorThread_dispatch; + ls->onRead = swPort_onRead_check_length; + } + else if (ls->open_http_protocol) + { + if (ls->open_websocket_protocol) + { + ls->protocol.get_package_length = swWebSocket_get_package_length; + ls->protocol.onPackage = swWebSocket_dispatch_frame; + ls->protocol.package_length_size = SW_WEBSOCKET_HEADER_LEN + SW_WEBSOCKET_MASK_LEN + sizeof(uint64_t); + } +#ifdef SW_USE_HTTP2 + else if (ls->open_http2_protocol) + { + ls->protocol.get_package_length = swHttp2_get_frame_length; + ls->protocol.package_length_size = SW_HTTP2_FRAME_HEADER_SIZE; + ls->protocol.onPackage = swReactorThread_dispatch; + } +#endif + ls->onRead = swPort_onRead_http; + } + else if (ls->open_mqtt_protocol) + { + ls->protocol.get_package_length = swMqtt_get_package_length; + ls->protocol.onPackage = swReactorThread_dispatch; + ls->onRead = swPort_onRead_check_length; + } + else if (ls->open_redis_protocol) + { + ls->protocol.onPackage = swReactorThread_dispatch; + ls->onRead = swPort_onRead_redis; + } + else + { + ls->onRead = swPort_onRead_raw; + } +} + +void swPort_clear_protocol(swListenPort *ls) +{ + ls->open_eof_check = 0; + ls->open_length_check = 0; + ls->open_http_protocol = 0; + ls->open_websocket_protocol = 0; +#ifdef SW_USE_HTTP2 + ls->open_http2_protocol = 0; +#endif + ls->open_mqtt_protocol = 0; + ls->open_redis_protocol = 0; +} + +static int swPort_onRead_raw(swReactor *reactor, swListenPort *port, swEvent *event) +{ + int n; + swDispatchData task; + swConnection *conn = event->socket; + + n = swConnection_recv(conn, task.data.data, SW_BUFFER_SIZE, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("recv from connection#%d failed.", event->fd); + return SW_OK; + case SW_CLOSE: + conn->close_errno = errno; + goto close_fd; + default: + return SW_OK; + } + } + else if (n == 0) + { + close_fd: swReactorThread_onClose(reactor, event); + return SW_OK; + } + else + { + task.data.info.fd = event->fd; + task.data.info.from_id = event->from_id; + task.data.info.len = n; + task.data.info.type = SW_EVENT_TCP; + task.target_worker_id = -1; + return swReactorThread_dispatch(conn, task.data.data, task.data.info.len); + } + return SW_OK; +} + + +static int swPort_onRead_check_length(swReactor *reactor, swListenPort *port, swEvent *event) +{ + swServer *serv = reactor->ptr; + swConnection *conn = event->socket; + swProtocol *protocol = &port->protocol; + + swString *buffer = swServer_get_buffer(serv, event->fd); + if (!buffer) + { + return SW_ERR; + } + + if (swProtocol_recv_check_length(protocol, conn, buffer) < 0) + { + swTrace("Close Event.FD=%d|From=%d", event->fd, event->from_id); + swReactorThread_onClose(reactor, event); + } + + return SW_OK; +} + +/** + * For Http Protocol + */ +static int swPort_onRead_http(swReactor *reactor, swListenPort *port, swEvent *event) +{ + swConnection *conn = event->socket; + swServer *serv = reactor->ptr; + + if (conn->websocket_status >= WEBSOCKET_STATUS_HANDSHAKE) + { + if (conn->http_upgrade == 0) + { + swHttpRequest_free(conn); + conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; + conn->http_upgrade = 1; + } + return swPort_onRead_check_length(reactor, port, event); + } + +#ifdef SW_USE_HTTP2 + if (conn->http2_stream) + { + return swPort_onRead_check_length(reactor, port, event); + } +#endif + + int n = 0; + char *buf; + int buf_len; + + swHttpRequest *request = NULL; + swProtocol *protocol = &port->protocol; + + //new http request + if (conn->object == NULL) + { + request = sw_malloc(sizeof(swHttpRequest)); + bzero(request, sizeof(swHttpRequest)); + conn->object = request; + } + else + { + request = (swHttpRequest *) conn->object; + } + + if (!request->buffer) + { + request->buffer = swString_new(SW_HTTP_HEADER_MAX_SIZE); + //alloc memory failed. + if (!request->buffer) + { + swReactorThread_onClose(reactor, event); + return SW_ERR; + } + } + + swString *buffer = request->buffer; + + recv_data: + buf = buffer->str + buffer->length; + buf_len = buffer->size - buffer->length; + + n = swConnection_recv(conn, buf, buf_len, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("recv from connection#%d failed.", event->fd); + return SW_OK; + case SW_CLOSE: + conn->close_errno = errno; + goto close_fd; + default: + return SW_OK; + } + } + else if (n == 0) + { + close_fd: + swHttpRequest_free(conn); + swReactorThread_onClose(reactor, event); + return SW_OK; + } + else + { + buffer->length += n; + + if (request->method == 0 && swHttpRequest_get_protocol(request) < 0) + { + if (request->excepted == 0 && request->buffer->length < SW_HTTP_HEADER_MAX_SIZE) + { + return SW_OK; + } + swoole_error_log(SW_LOG_TRACE, SW_ERROR_HTTP_INVALID_PROTOCOL, "get protocol failed."); +#ifdef SW_HTTP_BAD_REQUEST + if (swConnection_send(conn, SW_STRL(SW_HTTP_BAD_REQUEST) - 1, 0) < 0) + { + swSysError("send() failed."); + } +#endif + goto close_fd; + } + + if (request->method > HTTP_PRI) + { + swWarn("method no support"); + goto close_fd; + } +#ifdef SW_USE_HTTP2 + else if (request->method == HTTP_PRI) + { + conn->http2_stream = 1; + swHttp2_send_setting_frame(protocol, conn); + if (n == sizeof(SW_HTTP2_PRI_STRING) - 1) + { + swHttpRequest_free(conn); + return SW_OK; + } + swHttp2_parse_frame(protocol, conn, buf + (sizeof(SW_HTTP2_PRI_STRING) - 1), n - (sizeof(SW_HTTP2_PRI_STRING) - 1)); + swHttpRequest_free(conn); + return SW_OK; + } +#endif + //http header is not the end + if (request->header_length == 0) + { + if (swHttpRequest_get_header_length(request) < 0) + { + if (buffer->size == buffer->length) + { + swWarn("[2]http header is too long."); + goto close_fd; + } + else + { + goto recv_data; + } + } + } + + //http body + if (request->content_length == 0) + { + if (swHttpRequest_get_content_length(request) < 0) + { + if (memcmp(buffer->str + buffer->length - 4, "\r\n\r\n", 4) == 0) + { + /** + * send static file content directly in the reactor thread + */ + if (!(serv->enable_static_handler && swPort_http_static_handler(request, conn))) + { + /** + * dynamic request, dispatch to worker + */ + swReactorThread_dispatch(conn, buffer->str, buffer->length); + } + swHttpRequest_free(conn); + return SW_OK; + } + else if (buffer->size == buffer->length) + { + swWarn("[0]http header is too long."); + goto close_fd; + } + //wait more data + else + { + goto recv_data; + } + } + else if (request->content_length > (protocol->package_max_length - SW_HTTP_HEADER_MAX_SIZE)) + { + swWarn("Content-Length is too big, MaxSize=[%d].", protocol->package_max_length - SW_HTTP_HEADER_MAX_SIZE); + goto close_fd; + } + } + + //total length + uint32_t request_size = request->header_length + request->content_length; + if (request_size > buffer->size && swString_extend(buffer, request_size) < 0) + { + goto close_fd; + } + + //discard the redundant data + if (buffer->length > request_size) + { + buffer->length = request_size; + } + + if (buffer->length == request_size) + { + swReactorThread_dispatch(conn, buffer->str, buffer->length); + swHttpRequest_free(conn); + } + else + { +#ifdef SW_HTTP_100_CONTINUE + //Expect: 100-continue + if (swHttpRequest_has_expect_header(request)) + { + swSendData _send; + _send.data = "HTTP/1.1 100 Continue\r\n\r\n"; + _send.length = strlen(_send.data); + + int send_times = 0; + direct_send: + n = swConnection_send(conn, _send.data, _send.length, 0); + if (n < _send.length) + { + _send.data += n; + _send.length -= n; + send_times++; + if (send_times < 10) + { + goto direct_send; + } + else + { + swWarn("send http header failed"); + } + } + } + else + { + swTrace("PostWait: request->content_length=%d, buffer->length=%zd, request->header_length=%d\n", + request->content_length, buffer->length, request->header_length); + } +#endif + goto recv_data; + } + } + return SW_OK; +} + +static int swPort_onRead_redis(swReactor *reactor, swListenPort *port, swEvent *event) +{ + swConnection *conn = event->socket; + swProtocol *protocol = &port->protocol; + swServer *serv = reactor->ptr; + + swString *buffer = swServer_get_buffer(serv, event->fd); + if (!buffer) + { + return SW_ERR; + } + + if (swRedis_recv(protocol, conn, buffer) < 0) + { + swReactorThread_onClose(reactor, event); + } + + return SW_OK; +} + +static int swPort_onRead_check_eof(swReactor *reactor, swListenPort *port, swEvent *event) +{ + swConnection *conn = event->socket; + swProtocol *protocol = &port->protocol; + swServer *serv = reactor->ptr; + + swString *buffer = swServer_get_buffer(serv, event->fd); + if (!buffer) + { + return SW_ERR; + } + + if (swProtocol_recv_check_eof(protocol, conn, buffer) < 0) + { + swReactorThread_onClose(reactor, event); + } + + return SW_OK; +} + +void swPort_free(swListenPort *port) +{ +#ifdef SW_USE_OPENSSL + if (port->ssl) + { + swSSL_free_context(port->ssl_context); + sw_free(port->ssl_option.cert_file); + sw_free(port->ssl_option.key_file); + if (port->ssl_option.client_cert_file) + { + sw_free(port->ssl_option.client_cert_file); + } + } +#endif + + close(port->sock); + + //remove unix socket file + if (port->type == SW_SOCK_UNIX_STREAM || port->type == SW_SOCK_UNIX_DGRAM) + { + unlink(port->host); + } +} + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +int swPort_http_static_handler(swHttpRequest *request, swConnection *conn) +{ + swServer *serv = SwooleG.serv; + char *url = request->buffer->str + request->url_offset; + char *params = memchr(url, '?', request->url_length); + + struct + { + off_t offset; + size_t length; + char filename[PATH_MAX]; + } buffer; + + char *p = buffer.filename; + + memcpy(p, serv->document_root, serv->document_root_len); + p += serv->document_root_len; + uint32_t n = params ? params - url : request->url_length; + memcpy(p, url, n); + p += n; + *p = 0; + + struct stat file_stat; + if (lstat(buffer.filename, &file_stat) < 0) + { + return SW_FALSE; + } + if ((file_stat.st_mode & S_IFMT) != S_IFREG) + { + return SW_FALSE; + } + + char header_buffer[1024]; + swSendData response; + response.info.fd = conn->session_id; + + response.info.type = SW_EVENT_TCP; + + p = request->buffer->str + request->url_offset + request->url_length + 10; + char *pe = request->buffer->str + request->header_length; + + char *date_if_modified_since = NULL; + int length_if_modified_since = 0; + + int state = 0; + for (; p < pe; p++) + { + switch(state) + { + case 0: + if (strncasecmp(p, SW_STRL("If-Modified-Since") - 1) == 0) + { + p += sizeof("If-Modified-Since"); + state = 1; + } + break; + case 1: + if (!isspace(*p)) + { + date_if_modified_since = p; + state = 2; + } + break; + case 2: + if (strncasecmp(p, SW_STRL("\r\n") - 1) == 0) + { + length_if_modified_since = p - date_if_modified_since; + goto check_modify_date; + } + break; + default: + break; + } + } + + char date_[64]; + struct tm *tm1; + + check_modify_date: tm1 = gmtime(&serv->gs->now); + strftime(date_, sizeof(date_), "%a, %d %b %Y %H:%M:%S %Z", tm1); + + char date_last_modified[64]; +#ifdef __MACH__ + time_t file_mtime = file_stat.st_mtimespec.tv_sec; +#else + time_t file_mtime = file_stat.st_mtim.tv_sec; +#endif + + struct tm *tm2 = gmtime(&file_mtime); + strftime(date_last_modified, sizeof(date_last_modified), "%a, %d %b %Y %H:%M:%S %Z", tm2); + + if (state == 2) + { + struct tm tm3; + char date_tmp[64]; + memcpy(date_tmp, date_if_modified_since, length_if_modified_since); + date_tmp[length_if_modified_since] = 0; + + char *date_format = NULL; + + if (strptime(date_tmp, SW_HTTP_RFC1123_DATE_GMT, &tm3) != NULL) + { + date_format = SW_HTTP_RFC1123_DATE_GMT; + } + else if (strptime(date_tmp, SW_HTTP_RFC1123_DATE_UTC, &tm3) != NULL) + { + date_format = SW_HTTP_RFC1123_DATE_UTC; + } + else if (strptime(date_tmp, SW_HTTP_RFC850_DATE, &tm3) != NULL) + { + date_format = SW_HTTP_RFC850_DATE; + } + else if (strptime(date_tmp, SW_HTTP_ASCTIME_DATE, &tm3) != NULL) + { + date_format = SW_HTTP_ASCTIME_DATE; + } + if (date_format && mktime(&tm3) - (int) timezone >= file_mtime) + { + response.length = response.info.len = snprintf(header_buffer, sizeof(header_buffer), + "HTTP/1.1 304 Not Modified\r\n" + "Connection: Keep-Alive\r\n" + "Date: %s\r\n" + "Last-Modified: %s\r\n" + "Server: %s\r\n\r\n", date_, date_last_modified, + SW_HTTP_SERVER_SOFTWARE); + response.data = header_buffer; + swReactorThread_send(&response); + return SW_TRUE; + } + } + + response.length = response.info.len = snprintf(header_buffer, sizeof(header_buffer), + "HTTP/1.1 200 OK\r\n" + "Connection: Keep-Alive\r\n" + "Content-Length: %ld\r\n" + "Content-Type: %s\r\n" + "Date: %s\r\n" + "Last-Modified: %s\r\n" + "Server: %s\r\n\r\n", (long) file_stat.st_size, swoole_get_mimetype(buffer.filename), + date_, + date_last_modified, + SW_HTTP_SERVER_SOFTWARE); + + response.data = header_buffer; + +#ifdef HAVE_TCP_NOPUSH + if (conn->tcp_nopush == 0) + { + if (swSocket_tcp_nopush(conn->fd, 1) == -1) + { + swWarn("swSocket_tcp_nopush() failed. Error: %s[%d]", strerror(errno), errno); + } + conn->tcp_nopush = 1; + } +#endif + swReactorThread_send(&response); + + buffer.offset = 0; + buffer.length = file_stat.st_size; + + response.info.type = SW_EVENT_SENDFILE; + response.length = response.info.len = sizeof(swSendFile_request) + buffer.length + 1; + response.data = (void*) &buffer; + + swReactorThread_send(&response); + return SW_TRUE; +} diff --git a/vendor/swoole/src/network/ProcessPool.c b/vendor/swoole/src/network/ProcessPool.c new file mode 100755 index 0000000..d2f297c --- /dev/null +++ b/vendor/swoole/src/network/ProcessPool.c @@ -0,0 +1,828 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Server.h" +#include "Client.h" + +/** + * call onTask + */ +static int swProcessPool_worker_loop(swProcessPool *pool, swWorker *worker); +/** + * call onMessage + */ +static int swProcessPool_worker_loop_ex(swProcessPool *pool, swWorker *worker); + +static void swProcessPool_free(swProcessPool *pool); + +/** + * Process manager + */ +int swProcessPool_create(swProcessPool *pool, int worker_num, int max_request, key_t msgqueue_key, int ipc_mode) +{ + bzero(pool, sizeof(swProcessPool)); + + pool->worker_num = worker_num; + pool->max_request = max_request; + + pool->workers = SwooleG.memory_pool->alloc(SwooleG.memory_pool, worker_num * sizeof(swWorker)); + if (pool->workers == NULL) + { + swSysError("malloc[1] failed."); + return SW_ERR; + } + + if (ipc_mode == SW_IPC_MSGQUEUE) + { + pool->use_msgqueue = 1; + pool->msgqueue_key = msgqueue_key; + + pool->queue = sw_malloc(sizeof(swMsgQueue)); + if (pool->queue == NULL) + { + swSysError("malloc[2] failed."); + return SW_ERR; + } + + if (swMsgQueue_create(pool->queue, 1, pool->msgqueue_key, 0) < 0) + { + return SW_ERR; + } + } + else if (ipc_mode == SW_IPC_SOCKET) + { + pool->use_socket = 1; + pool->stream = sw_malloc(sizeof(swStreamInfo)); + if (pool->stream == NULL) + { + swWarn("malloc[2] failed."); + return SW_ERR; + } + bzero(pool->stream, sizeof(swStreamInfo)); + } + else if (ipc_mode == SW_IPC_UNIXSOCK) + { + pool->pipes = sw_calloc(worker_num, sizeof(swPipe)); + if (pool->pipes == NULL) + { + swWarn("malloc[2] failed."); + return SW_ERR; + } + + swPipe *pipe; + int i; + for (i = 0; i < worker_num; i++) + { + pipe = &pool->pipes[i]; + if (swPipeUnsock_create(pipe, 1, SOCK_DGRAM) < 0) + { + return SW_ERR; + } + pool->workers[i].pipe_master = pipe->getFd(pipe, SW_PIPE_MASTER); + pool->workers[i].pipe_worker = pipe->getFd(pipe, SW_PIPE_WORKER); + pool->workers[i].pipe_object = pipe; + } + } + else + { + ipc_mode = SW_IPC_NONE; + } + + pool->map = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + if (pool->map == NULL) + { + swProcessPool_free(pool); + return SW_ERR; + } + + pool->ipc_mode = ipc_mode; + if (ipc_mode > SW_IPC_NONE) + { + pool->main_loop = swProcessPool_worker_loop; + } + + return SW_OK; +} + +int swProcessPool_create_unix_socket(swProcessPool *pool, char *socket_file, int blacklog) +{ + if (pool->ipc_mode != SW_IPC_SOCKET) + { + swWarn("ipc_mode is not SW_IPC_SOCKET."); + return SW_ERR; + } + pool->stream->socket_file = sw_strdup(socket_file); + if (pool->stream->socket_file == NULL) + { + return SW_ERR; + } + pool->stream->socket = swSocket_create_server(SW_SOCK_UNIX_STREAM, pool->stream->socket_file, 0, blacklog); + if (pool->stream->socket < 0) + { + return SW_ERR; + } + return SW_OK; +} + +int swProcessPool_create_tcp_socket(swProcessPool *pool, char *host, int port, int blacklog) +{ + if (pool->ipc_mode != SW_IPC_SOCKET) + { + swWarn("ipc_mode is not SW_IPC_SOCKET."); + return SW_ERR; + } + pool->stream->socket_file = sw_strdup(host); + if (pool->stream->socket_file == NULL) + { + return SW_ERR; + } + pool->stream->socket = swSocket_create_server(SW_SOCK_TCP, host, port, blacklog); + if (pool->stream->socket < 0) + { + return SW_ERR; + } + return SW_OK; +} + +/** + * start workers + */ +int swProcessPool_start(swProcessPool *pool) +{ + if (pool->ipc_mode == SW_IPC_SOCKET && (pool->stream == NULL || pool->stream->socket == 0)) + { + swWarn("must first listen to an tcp port."); + return SW_ERR; + } + + int i; + pool->started = 1; + pool->run_worker_num = pool->worker_num; + + for (i = 0; i < pool->worker_num; i++) + { + pool->workers[i].pool = pool; + pool->workers[i].id = pool->start_id + i; + pool->workers[i].type = pool->type; + + if (swProcessPool_spawn(pool, &(pool->workers[i])) < 0) + { + return SW_ERR; + } + } + return SW_OK; +} + +static sw_inline int swProcessPool_schedule(swProcessPool *pool) +{ + if (pool->dispatch_mode == SW_DISPATCH_QUEUE) + { + return 0; + } + + int i, target_worker_id = 0; + int run_worker_num = pool->run_worker_num; + + for (i = 0; i < run_worker_num + 1; i++) + { + target_worker_id = sw_atomic_fetch_add(&pool->round_id, 1) % run_worker_num; + if (pool->workers[target_worker_id].status == SW_WORKER_IDLE) + { + break; + } + } + return target_worker_id; +} + +int swProcessPool_response(swProcessPool *pool, char *data, int length) +{ + if (pool->stream == NULL || pool->stream->last_connection == 0 || pool->stream->response_buffer == NULL) + { + SwooleG.error = SW_ERROR_INVALID_PARAMS; + return SW_ERR; + } + return swString_append_ptr(pool->stream->response_buffer, data, length); +} + +/** + * dispatch data to worker + */ +int swProcessPool_dispatch(swProcessPool *pool, swEventData *data, int *dst_worker_id) +{ + int ret = 0; + swWorker *worker; + + if (pool->use_socket) + { + swStream *stream = swStream_new(pool->stream->socket_file, 0, SW_SOCK_UNIX_STREAM); + if (stream == NULL) + { + return SW_ERR; + } + stream->response = NULL; + stream->session_id = 0; + if (swStream_send(stream, (char*) data, sizeof(data->info) + data->info.len) < 0) + { + stream->cancel = 1; + return SW_ERR; + } + return SW_OK; + } + + if (*dst_worker_id < 0) + { + *dst_worker_id = swProcessPool_schedule(pool); + } + + *dst_worker_id += pool->start_id; + worker = swProcessPool_get_worker(pool, *dst_worker_id); + + int sendn = sizeof(data->info) + data->info.len; + ret = swWorker_send2worker(worker, data, sendn, SW_PIPE_MASTER | SW_PIPE_NONBLOCK); + + if (ret >= 0) + { + sw_atomic_fetch_add(&worker->tasking_num, 1); + } + else + { + swWarn("send %d bytes to worker#%d failed.", sendn, *dst_worker_id); + } + + return ret; +} + +/** + * dispatch data to worker + */ +int swProcessPool_dispatch_blocking(swProcessPool *pool, swEventData *data, int *dst_worker_id) +{ + int ret = 0; + int sendn = sizeof(data->info) + data->info.len; + + if (pool->use_socket) + { + swClient _socket; + if (swClient_create(&_socket, SW_SOCK_UNIX_STREAM, SW_SOCK_SYNC) < 0) + { + return SW_ERR; + } + if (_socket.connect(&_socket, pool->stream->socket_file, 0, -1, 0) < 0) + { + return SW_ERR; + } + if (_socket.send(&_socket, (void*) data, sendn, 0) < 0) + { + return SW_ERR; + } + _socket.close(&_socket); + return SW_OK; + } + + if (*dst_worker_id < 0) + { + *dst_worker_id = swProcessPool_schedule(pool); + } + + *dst_worker_id += pool->start_id; + swWorker *worker = swProcessPool_get_worker(pool, *dst_worker_id); + + ret = swWorker_send2worker(worker, data, sendn, SW_PIPE_MASTER); + if (ret < 0) + { + swWarn("send %d bytes to worker#%d failed.", sendn, *dst_worker_id); + } + else + { + sw_atomic_fetch_add(&worker->tasking_num, 1); + } + + return ret; +} + +void swProcessPool_shutdown(swProcessPool *pool) +{ + int i, status; + swWorker *worker; + SwooleG.running = 0; + + swSignal_none(); + //concurrent kill + for (i = 0; i < pool->run_worker_num; i++) + { + worker = &pool->workers[i]; + if (swKill(worker->pid, SIGTERM) < 0) + { + swSysError("kill(%d) failed.", worker->pid); + continue; + } + } + for (i = 0; i < pool->run_worker_num; i++) + { + worker = &pool->workers[i]; + if (swWaitpid(worker->pid, &status, 0) < 0) + { + swSysError("waitpid(%d) failed.", worker->pid); + } + } + swProcessPool_free(pool); + pool->started = 0; +} + +pid_t swProcessPool_spawn(swProcessPool *pool, swWorker *worker) +{ + pid_t pid = fork(); + int ret_code = 0; + + switch (pid) + { + //child + case 0: + /** + * Process start + */ + if (pool->onWorkerStart != NULL) + { + pool->onWorkerStart(pool, worker->id); + } + /** + * Process main loop + */ + if (pool->main_loop) + { + ret_code = pool->main_loop(pool, worker); + } + /** + * Process stop + */ + if (pool->onWorkerStop != NULL) + { + pool->onWorkerStop(pool, worker->id); + } + exit(ret_code); + break; + case -1: + swWarn("fork() failed. Error: %s [%d]", strerror(errno), errno); + break; + //parent + default: + //remove old process + if (worker->pid) + { + swHashMap_del_int(pool->map, worker->pid); + } + worker->pid = pid; + //insert new process + swHashMap_add_int(pool->map, pid, worker); + break; + } + return pid; +} + +static int swProcessPool_worker_loop(swProcessPool *pool, swWorker *worker) +{ + struct + { + long mtype; + swEventData buf; + } out; + + int n = 0, ret; + int task_n, worker_task_always = 0; + + if (pool->max_request < 1) + { + task_n = 1; + worker_task_always = 1; + } + else + { + task_n = pool->max_request; + if (pool->max_request > 10) + { + n = swoole_system_random(1, pool->max_request / 2); + if (n > 0) + { + task_n += n; + } + } + } + + /** + * Use from_fd save the task_worker->id + */ + out.buf.info.from_fd = worker->id; + + if (pool->dispatch_mode == SW_DISPATCH_QUEUE) + { + out.mtype = 0; + } + else + { + out.mtype = worker->id + 1; + } + + while (SwooleG.running > 0 && task_n > 0) + { + /** + * fetch task + */ + if (pool->use_msgqueue) + { + n = swMsgQueue_pop(pool->queue, (swQueue_data *) &out, sizeof(out.buf)); + if (n < 0 && errno != EINTR) + { + swSysError("[Worker#%d] msgrcv() failed.", worker->id); + break; + } + } + else if (pool->use_socket) + { + int fd = accept(pool->stream->socket, NULL, NULL); + if (fd < 0) + { + if (errno == EAGAIN || errno == EINTR) + { + continue; + } + else + { + swSysError("accept(%d) failed.", pool->stream->socket); + break; + } + } + + n = swStream_recv_blocking(fd, (void*) &out.buf, sizeof(out.buf)); + if (n == SW_CLOSE) + { + close(fd); + continue; + } + pool->stream->last_connection = fd; + } + else + { + n = read(worker->pipe_worker, &out.buf, sizeof(out.buf)); + if (n < 0 && errno != EINTR) + { + swSysError("[Worker#%d] read(%d) failed.", worker->id, worker->pipe_worker); + } + } + + /** + * timer + */ + if (n < 0) + { + if (errno == EINTR && SwooleG.signal_alarm) + { + alarm_handler: SwooleG.signal_alarm = 0; + swTimer_select(&SwooleG.timer); + } + continue; + } + + /** + * do task + */ + worker->status = SW_WORKER_BUSY; + worker->request_time = time(NULL); + ret = pool->onTask(pool, &out.buf); + worker->status = SW_WORKER_IDLE; + worker->request_time = 0; + worker->traced = 0; + + if (pool->use_socket && pool->stream->last_connection > 0) + { + int _end = 0; + swSocket_write_blocking(pool->stream->last_connection, (void *) &_end, sizeof(_end)); + close(pool->stream->last_connection); + pool->stream->last_connection = 0; + } + + /** + * timer + */ + if (SwooleG.signal_alarm) + { + goto alarm_handler; + } + + if (ret >= 0 && !worker_task_always) + { + task_n--; + } + } + return SW_OK; +} + +int swProcessPool_set_protocol(swProcessPool *pool, int task_protocol, uint32_t max_packet_size) +{ + if (task_protocol) + { + pool->main_loop = swProcessPool_worker_loop; + } + else + { + pool->packet_buffer = sw_malloc(max_packet_size); + if (pool->packet_buffer == NULL) + { + swSysError("malloc(%d) failed.", max_packet_size); + return SW_ERR; + } + if (pool->stream) + { + pool->stream->response_buffer = swString_new(SW_BUFFER_SIZE_STD); + if (pool->stream->response_buffer == NULL) + { + sw_free(pool->packet_buffer); + return SW_ERR; + } + } + pool->max_packet_size = max_packet_size; + pool->main_loop = swProcessPool_worker_loop_ex; + } + + return SW_OK; +} + +static int swProcessPool_worker_loop_ex(swProcessPool *pool, swWorker *worker) +{ + int n; + char *data; + + swQueue_data *outbuf = (swQueue_data *) pool->packet_buffer; + outbuf->mtype = 0; + + while (SwooleG.running > 0) + { + /** + * fetch task + */ + if (pool->use_msgqueue) + { + n = swMsgQueue_pop(pool->queue, outbuf, sizeof(outbuf->mdata)); + if (n < 0 && errno != EINTR) + { + swSysError("[Worker#%d] msgrcv() failed.", worker->id); + break; + } + data = outbuf->mdata; + } + else if (pool->use_socket) + { + int fd = accept(pool->stream->socket, NULL, NULL); + if (fd < 0) + { + if (errno == EAGAIN || errno == EINTR) + { + continue; + } + else + { + swSysError("accept(%d) failed.", pool->stream->socket); + break; + } + } + int tmp = 0; + if (swSocket_recv_blocking(fd, &tmp, sizeof(tmp), MSG_WAITALL) <= 0) + { + goto _close; + } + n = ntohl(tmp); + if (n <= 0) + { + goto _close; + } + else if (n > pool->max_packet_size) + { + goto _close; + } + if (swSocket_recv_blocking(fd, pool->packet_buffer, n, MSG_WAITALL) <= 0) + { + _close: close(fd); + continue; + } + data = pool->packet_buffer; + pool->stream->last_connection = fd; + } + else + { + n = read(worker->pipe_worker, pool->packet_buffer, pool->max_packet_size); + if (n < 0 && errno != EINTR) + { + swSysError("[Worker#%d] read(%d) failed.", worker->id, worker->pipe_worker); + } + data = pool->packet_buffer; + } + + /** + * timer + */ + if (n < 0) + { + if (errno == EINTR && SwooleG.signal_alarm) + { + alarm_handler: SwooleG.signal_alarm = 0; + swTimer_select(&SwooleG.timer); + } + continue; + } + + pool->onMessage(pool, data, n); + + if (pool->use_socket && pool->stream->last_connection > 0) + { + swString *resp_buf = pool->stream->response_buffer; + if (resp_buf && resp_buf->length > 0) + { + int _l = htonl(resp_buf->length); + swSocket_write_blocking(pool->stream->last_connection, &_l, sizeof(_l)); + swSocket_write_blocking(pool->stream->last_connection, resp_buf->str, resp_buf->length); + swString_clear(resp_buf); + } + close(pool->stream->last_connection); + pool->stream->last_connection = 0; + } + + /** + * timer + */ + if (SwooleG.signal_alarm) + { + goto alarm_handler; + } + } + return SW_OK; +} + +/** + * add a worker to pool + */ +int swProcessPool_add_worker(swProcessPool *pool, swWorker *worker) +{ + swHashMap_add_int(pool->map, worker->pid, worker); + return SW_OK; +} + +int swProcessPool_wait(swProcessPool *pool) +{ + int pid, new_pid; + int reload_worker_i = 0; + pid_t reload_worker_pid = 0; + int ret; + int status; + + swWorker *reload_workers = sw_calloc(pool->worker_num, sizeof(swWorker)); + if (reload_workers == NULL) + { + swError("malloc[reload_workers] failed"); + return SW_ERR; + } + + while (SwooleG.running) + { + pid = wait(&status); + if (pid < 0) + { + if (SwooleG.running == 0) + { + break; + } + if (pool->reloading == 0) + { + if (errno != EINTR) + { + swWarn("[Manager] wait failed. Error: %s [%d]", strerror(errno), errno); + } + continue; + } + + swNotice("reload workers."); + + if (pool->reload_init == 0) + { + pool->reload_init = 1; + memcpy(reload_workers, pool->workers, sizeof(swWorker) * pool->worker_num); + } + + goto kill_worker; + } + + if (SwooleG.running == 1) + { + swWorker *exit_worker = swHashMap_find_int(pool->map, pid); + if (exit_worker == NULL) + { + if (pool->onWorkerNotFound) + { + pool->onWorkerNotFound(pool, pid, status); + } + else + { + swWarn("[Manager]unknow worker[pid=%d]", pid); + } + continue; + } + if (!WIFEXITED(status)) + { + swWarn("worker#%d abnormal exit, status=%d, signal=%d", exit_worker->id, WEXITSTATUS(status), WTERMSIG(status)); + } + new_pid = swProcessPool_spawn(pool, exit_worker); + if (new_pid < 0) + { + swWarn("Fork worker process failed. Error: %s [%d]", strerror(errno), errno); + sw_free(reload_workers); + return SW_ERR; + } + swHashMap_del_int(pool->map, pid); + if (pid == reload_worker_pid) + { + reload_worker_i++; + } + } + //reload worker + kill_worker: if (pool->reloading == 1) + { + //reload finish + if (reload_worker_i >= pool->worker_num) + { + pool->reloading = pool->reload_init = reload_worker_pid = reload_worker_i = 0; + continue; + } + reload_worker_pid = reload_workers[reload_worker_i].pid; + ret = kill(reload_worker_pid, SIGTERM); + if (ret < 0) + { + if (errno == ECHILD) + { + reload_worker_i++; + goto kill_worker; + } + swSysError("[Manager]kill(%d) failed.", reload_workers[reload_worker_i].pid); + continue; + } + } + } + sw_free(reload_workers); + return SW_OK; +} + +static void swProcessPool_free(swProcessPool *pool) +{ + int i; + swPipe *_pipe; + + if (pool->pipes) + { + for (i = 0; i < pool->worker_num; i++) + { + _pipe = &pool->pipes[i]; + _pipe->close(_pipe); + } + sw_free(pool->pipes); + } + + if (pool->use_msgqueue == 1 && pool->msgqueue_key == 0) + { + swMsgQueue_free(pool->queue); + } + + if (pool->stream) + { + if (pool->stream->socket) + { + unlink(pool->stream->socket_file); + sw_free((void*) pool->stream->socket_file); + } + if (pool->stream->socket) + { + close(pool->stream->socket); + } + if (pool->stream->response_buffer) + { + swString_free(pool->stream->response_buffer); + } + sw_free(pool->stream); + } + + if (pool->map) + { + swHashMap_free(pool->map); + } +} + diff --git a/vendor/swoole/src/network/ReactorProcess.c b/vendor/swoole/src/network/ReactorProcess.c new file mode 100755 index 0000000..17076ad --- /dev/null +++ b/vendor/swoole/src/network/ReactorProcess.c @@ -0,0 +1,582 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "Server.h" + +static int swReactorProcess_loop(swProcessPool *pool, swWorker *worker); +static int swReactorProcess_onPipeRead(swReactor *reactor, swEvent *event); +static int swReactorProcess_send2client(swFactory *, swSendData *); +static int swReactorProcess_send2worker(int, void *, int); +static void swReactorProcess_onTimeout(swTimer *timer, swTimer_node *tnode); + +#ifdef HAVE_REUSEPORT +static int swReactorProcess_reuse_port(swListenPort *ls); +#endif + +static uint32_t heartbeat_check_lasttime = 0; + +int swReactorProcess_create(swServer *serv) +{ + serv->reactor_num = serv->worker_num; + serv->reactor_threads = sw_calloc(1, sizeof(swReactorThread)); + if (serv->reactor_threads == NULL) + { + swSysError("calloc[1](%d) failed.", (int )(serv->reactor_num * sizeof(swReactorThread))); + return SW_ERR; + } + serv->connection_list = sw_calloc(serv->max_connection, sizeof(swConnection)); + if (serv->connection_list == NULL) + { + swSysError("calloc[2](%d) failed.", (int )(serv->max_connection * sizeof(swConnection))); + return SW_ERR; + } + //create factry object + if (swFactory_create(&(serv->factory)) < 0) + { + swError("create factory failed."); + return SW_ERR; + } + serv->factory.finish = swReactorProcess_send2client; + return SW_OK; +} + +/** + * base模式 + * 在worker进程中直接accept连接 + */ +int swReactorProcess_start(swServer *serv) +{ + swListenPort *ls; + if (serv->onStart != NULL) + { + serv->onStart(serv); + } + + //listen TCP + if (serv->have_tcp_sock == 1) + { + LL_FOREACH(serv->listen_list, ls) + { + if (swSocket_is_dgram(ls->type)) + { + continue; + } + if (SwooleG.reuse_port) + { + if (close(ls->sock) < 0) + { + swSysError("close(%d) failed.", ls->sock); + } + continue; + } + else + { + //listen server socket + if (swPort_listen(ls) < 0) + { + return SW_ERR; + } + } + } + } + + if (swProcessPool_create(&serv->gs->event_workers, serv->worker_num, serv->max_request, 0, SW_IPC_UNIXSOCK) < 0) + { + return SW_ERR; + } + + serv->gs->event_workers.ptr = serv; + serv->gs->event_workers.main_loop = swReactorProcess_loop; + serv->gs->event_workers.type = SW_PROCESS_WORKER; + serv->gs->event_workers.run_worker_num = serv->worker_num; + + //no worker + if (serv->worker_num == 1 && serv->task_worker_num == 0 && serv->max_request == 0 && serv->user_worker_list == NULL) + { + swWorker single_worker; + bzero(&single_worker, sizeof(single_worker)); + return swReactorProcess_loop(&serv->gs->event_workers, &single_worker); + } + + swWorker *worker; + int i; + for (i = 0; i < serv->worker_num; i++) + { + worker = &serv->gs->event_workers.workers[i]; + if (swWorker_create(worker) < 0) + { + return SW_ERR; + } + } + + //task workers + if (serv->task_worker_num > 0) + { + if (swServer_create_task_worker(serv) < 0) + { + return SW_ERR; + } + + swTaskWorker_init(&serv->gs->task_workers); + swProcessPool_start(&serv->gs->task_workers); + + int i; + for (i = 0; i < serv->gs->task_workers.worker_num; i++) + { + swProcessPool_add_worker(&serv->gs->event_workers, &serv->gs->task_workers.workers[i]); + } + } + + /** + * create user worker process + */ + if (serv->user_worker_list) + { + swUserWorker_node *user_worker; + LL_FOREACH(serv->user_worker_list, user_worker) + { + /** + * store the pipe object + */ + if (user_worker->worker->pipe_object) + { + swServer_store_pipe_fd(serv, user_worker->worker->pipe_object); + } + swManager_spawn_user_worker(serv, user_worker->worker); + } + serv->gs->event_workers.onWorkerNotFound = swManager_wait_user_worker; + } + + /** + * manager process is the same as the master process + */ + SwooleG.pid = serv->gs->manager_pid = getpid(); + SwooleG.process_type = SW_PROCESS_MASTER; + + /** + * manager process can not use signalfd + */ + SwooleG.use_timerfd = 0; + SwooleG.use_signalfd = 0; + SwooleG.use_timer_pipe = 0; + swServer_signal_init(serv); + + swProcessPool_start(&serv->gs->event_workers); + swProcessPool_wait(&serv->gs->event_workers); + swProcessPool_shutdown(&serv->gs->event_workers); + + swManager_kill_user_worker(serv); + + return SW_OK; +} + +static int swReactorProcess_onPipeRead(swReactor *reactor, swEvent *event) +{ + swEventData task; + swSendData _send; + swServer *serv = reactor->ptr; + swFactory *factory = &serv->factory; + swString *buffer_output; + + if (read(event->fd, &task, sizeof(task)) <= 0) + { + return SW_ERR; + } + + switch (task.info.type) + { + case SW_EVENT_PIPE_MESSAGE: + serv->onPipeMessage(serv, &task); + break; + case SW_EVENT_FINISH: + serv->onFinish(serv, &task); + break; + case SW_EVENT_SENDFILE: + memcpy(&_send.info, &task.info, sizeof(_send.info)); + _send.data = task.data; + factory->finish(factory, &_send); + break; + case SW_EVENT_PROXY_START: + case SW_EVENT_PROXY_END: + buffer_output = SwooleWG.buffer_output[task.info.from_id]; + swString_append_ptr(buffer_output, task.data, task.info.len); + if (task.info.type == SW_EVENT_PROXY_END) + { + memcpy(&_send.info, &task.info, sizeof(_send.info)); + _send.info.type = SW_EVENT_TCP; + _send.data = buffer_output->str; + _send.length = buffer_output->length; + factory->finish(factory, &_send); + swString_clear(buffer_output); + } + break; + default: + break; + } + return SW_OK; +} + +static int swReactorProcess_loop(swProcessPool *pool, swWorker *worker) +{ + swServer *serv = pool->ptr; + swReactor *reactor = &(serv->reactor_threads[0].reactor); + + SwooleG.process_type = SW_PROCESS_WORKER; + SwooleG.pid = getpid(); + + SwooleWG.id = worker->id; + if (serv->max_request > 0) + { + SwooleWG.run_always = 0; + } + SwooleWG.max_request = serv->max_request; + SwooleWG.worker = worker; + + SwooleTG.id = 0; + if (worker->id == 0) + { + SwooleTG.update_time = 1; + } + + swServer_worker_init(serv, worker); + + int n_buffer = serv->worker_num + serv->task_worker_num; + SwooleWG.buffer_output = sw_malloc(sizeof(swString*) * n_buffer); + if (SwooleWG.buffer_output == NULL) + { + swError("malloc for SwooleWG.buffer_output failed."); + return SW_ERR; + } + + int i; + for (i = 0; i < n_buffer; i++) + { + SwooleWG.buffer_output[i] = swString_new(SW_BUFFER_SIZE_BIG); + if (SwooleWG.buffer_output[i] == NULL) + { + swError("buffer_output init failed."); + return SW_ERR; + } + } + + //create reactor + if (swReactor_create(reactor, SW_REACTOR_MAXEVENTS) < 0) + { + return SW_ERR; + } + + swListenPort *ls; + int fdtype; + + LL_FOREACH(serv->listen_list, ls) + { + fdtype = swSocket_is_dgram(ls->type) ? SW_FD_UDP : SW_FD_LISTEN; +#ifdef HAVE_REUSEPORT + if (fdtype == SW_FD_LISTEN && SwooleG.reuse_port) + { + if (swReactorProcess_reuse_port(ls) < 0) + { + return SW_ERR; + } + } +#endif + reactor->add(reactor, ls->sock, fdtype); + } + + SwooleG.main_reactor = reactor; + + reactor->id = worker->id; + reactor->ptr = serv; + +#ifdef SW_USE_RINGBUFFER + serv->reactor_threads[0].buffer_input = swMalloc_new(); + if (serv->reactor_threads[0].buffer_input == NULL) + { + return SW_ERR; + } +#endif + +#ifdef HAVE_SIGNALFD + if (SwooleG.use_signalfd) + { + swSignalfd_setup(SwooleG.main_reactor); + } +#endif + + reactor->thread = 1; + reactor->socket_list = serv->connection_list; + reactor->max_socket = serv->max_connection; + + reactor->disable_accept = 0; + reactor->enable_accept = swServer_enable_accept; + reactor->close = swReactorThread_close; + + //set event handler + //connect + reactor->setHandle(reactor, SW_FD_LISTEN, swServer_master_onAccept); + //close + reactor->setHandle(reactor, SW_FD_CLOSE, swReactorProcess_onClose); + //pipe + reactor->setHandle(reactor, SW_FD_WRITE, swReactor_onWrite); + reactor->setHandle(reactor, SW_FD_PIPE | SW_EVENT_READ, swReactorProcess_onPipeRead); + + swServer_store_listen_socket(serv); + + if (worker->pipe_worker) + { + swSetNonBlock(worker->pipe_worker); + swSetNonBlock(worker->pipe_master); + reactor->add(reactor, worker->pipe_worker, SW_FD_PIPE); + reactor->add(reactor, worker->pipe_master, SW_FD_PIPE); + } + + //task workers + if (serv->task_worker_num > 0) + { + swPipe *p; + swConnection *psock; + int pfd; + + if (serv->task_ipc_mode == SW_TASK_IPC_UNIXSOCK) + { + for (i = 0; i < serv->gs->task_workers.worker_num; i++) + { + p = serv->gs->task_workers.workers[i].pipe_object; + pfd = p->getFd(p, 1); + psock = swReactor_get(reactor, pfd); + psock->fdtype = SW_FD_PIPE; + swSetNonBlock(pfd); + } + } + } + + //set protocol function point + swReactorThread_set_protocol(serv, reactor); + + /** + * init timer + */ + if (swTimer_init(1000) < 0) + { + return SW_ERR; + } + /** + * 1 second timer, update serv->gs->now + */ + if (SwooleG.timer.add(&SwooleG.timer, 1000, 1, serv, swServer_master_onTimer) == NULL) + { + return SW_ERR; + } + + if (serv->onWorkerStart) + { + serv->onWorkerStart(serv, worker->id); + } + + /** + * for heartbeat check + */ + if (serv->heartbeat_check_interval > 0) + { + if (SwooleG.timer.add(&SwooleG.timer, serv->heartbeat_check_interval * 1000, 1, reactor, swReactorProcess_onTimeout) == NULL) + { + return SW_ERR; + } + } + + reactor->wait(reactor, NULL); + + if (serv->onWorkerStop) + { + serv->onWorkerStop(serv, worker->id); + } + + return SW_OK; +} + +int swReactorProcess_onClose(swReactor *reactor, swEvent *event) +{ + int fd = event->fd; + swServer *serv = reactor->ptr; + swConnection *conn = swServer_connection_get(SwooleG.serv, fd); + if (conn == NULL || conn->active == 0) + { + return SW_ERR; + } + if (reactor->del(reactor, fd) == 0) + { + return swServer_tcp_notify(serv, conn, SW_EVENT_CLOSE); + } + else + { + return SW_ERR; + } +} + +static int swReactorProcess_send2worker(int pipe_fd, void *data, int length) +{ + if (swIsTaskWorker()) + { + return swSocket_write_blocking(pipe_fd, data, length); + } + else + { + return SwooleG.main_reactor->write(SwooleG.main_reactor, pipe_fd, data, length); + } +} + +static int swReactorProcess_send2client(swFactory *factory, swSendData *_send) +{ + swServer *serv = SwooleG.serv; + int session_id = _send->info.fd; + if (_send->length == 0) + { + _send->length = _send->info.len; + } + + swSession *session = swServer_get_session(serv, session_id); + if (session->fd == 0) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "send %d byte failed, session#%d does not exist.", _send->length, session_id); + return SW_ERR; + } + //proxy + if (session->reactor_id != SwooleWG.id) + { + swTrace("session->reactor_id=%d, SwooleWG.id=%d", session->reactor_id, SwooleWG.id); + swWorker *worker = swProcessPool_get_worker(&serv->gs->event_workers, session->reactor_id); + swEventData proxy_msg; + + if (_send->info.type == SW_EVENT_TCP) + { + proxy_msg.info.fd = session_id; + proxy_msg.info.from_id = SwooleWG.id; + proxy_msg.info.type = SW_EVENT_PROXY_START; + + size_t send_n = _send->length; + size_t offset = 0; + + while (send_n > 0) + { + if (send_n > SW_BUFFER_SIZE) + { + proxy_msg.info.len = SW_BUFFER_SIZE; + } + else + { + proxy_msg.info.type = SW_EVENT_PROXY_END; + proxy_msg.info.len = send_n; + } + memcpy(proxy_msg.data, _send->data + offset, proxy_msg.info.len); + send_n -= proxy_msg.info.len; + offset += proxy_msg.info.len; + swReactorProcess_send2worker(worker->pipe_master, &proxy_msg, sizeof(proxy_msg.info) + proxy_msg.info.len); + } + swTrace("proxy message, fd=%d, len=%ld",worker->pipe_master, sizeof(proxy_msg.info) + proxy_msg.info.len); + } + else if (_send->info.type == SW_EVENT_SENDFILE) + { + memcpy(&proxy_msg.info, &_send->info, sizeof(proxy_msg.info)); + memcpy(proxy_msg.data, _send->data, _send->length); + return swReactorProcess_send2worker(worker->pipe_master, &proxy_msg, sizeof(proxy_msg.info) + proxy_msg.info.len); + } + else + { + swWarn("unkown event type[%d].", _send->info.type); + return SW_ERR; + } + return SW_OK; + } + else + { + return swFactory_finish(factory, _send); + } +} + +static void swReactorProcess_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + swReactor *reactor = tnode->data; + swServer *serv = reactor->ptr; + swEvent notify_ev; + swConnection *conn; + + if (serv->gs->now < heartbeat_check_lasttime + 10) + { + return; + } + + int fd; + int serv_max_fd; + int serv_min_fd; + int checktime; + + bzero(&notify_ev, sizeof(notify_ev)); + notify_ev.type = SW_EVENT_CLOSE; + + serv_max_fd = swServer_get_maxfd(serv); + serv_min_fd = swServer_get_minfd(serv); + + checktime = serv->gs->now - serv->heartbeat_idle_time; + + for (fd = serv_min_fd; fd <= serv_max_fd; fd++) + { + conn = swServer_connection_get(serv, fd); + + if (conn != NULL && conn->active == 1 && conn->fdtype == SW_FD_TCP) + { + if (conn->protect || conn->last_time > checktime) + { + continue; + } +#ifdef SW_USE_OPENSSL + if (conn->ssl && conn->ssl_state != SW_SSL_STATE_READY) + { + swReactorThread_close(reactor, fd); + continue; + } +#endif + notify_ev.fd = fd; + notify_ev.from_id = conn->from_id; + swReactorProcess_onClose(reactor, &notify_ev); + } + } +} + +#ifdef HAVE_REUSEPORT +static int swReactorProcess_reuse_port(swListenPort *ls) +{ + //create new socket + int sock = swSocket_create(ls->type); + if (sock < 0) + { + swSysError("create socket failed."); + return SW_ERR; + } + //bind address and port + if (swSocket_bind(sock, ls->type, ls->host, &ls->port) < 0) + { + close(sock); + return SW_ERR; + } + //stream socket, set nonblock + if (swSocket_is_stream(ls->type)) + { + swSetNonBlock(sock); + } + ls->sock = sock; + return swPort_listen(ls); +} +#endif diff --git a/vendor/swoole/src/network/ReactorThread.c b/vendor/swoole/src/network/ReactorThread.c new file mode 100755 index 0000000..46d375e --- /dev/null +++ b/vendor/swoole/src/network/ReactorThread.c @@ -0,0 +1,1619 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" +#include "Client.h" +#include "websocket.h" + +static int swReactorThread_loop(swThreadParam *param); +static int swReactorThread_onPipeWrite(swReactor *reactor, swEvent *ev); +static int swReactorThread_onPipeReceive(swReactor *reactor, swEvent *ev); + +static int swReactorThread_onRead(swReactor *reactor, swEvent *ev); +static int swReactorThread_onWrite(swReactor *reactor, swEvent *ev); +static int swReactorThread_onPackage(swReactor *reactor, swEvent *event); +static void swReactorThread_onStreamResponse(swStream *stream, char *data, uint32_t length); + +#if 0 +static int swReactorThread_dispatch_array_buffer(swReactorThread *thread, swConnection *conn); +#endif + +#ifdef SW_USE_TIMEWHEEL +static void swReactorThread_onReactorCompleted(swReactor *reactor); +#endif + +#ifdef SW_USE_RINGBUFFER +static sw_inline void swReactorThread_yield(swReactorThread *thread) +{ + swEvent event; + swServer *serv = SwooleG.serv; + int i; + for (i = 0; i < serv->reactor_pipe_num; i++) + { + event.fd = thread->pipe_read_list[i]; + swReactorThread_onPipeReceive(&thread->reactor, &event); + } + swYield(); +} + +static sw_inline void* swReactorThread_alloc(swReactorThread *thread, uint32_t size) +{ + void *ptr = NULL; + int try_count = 0; + + while (1) + { + ptr = thread->buffer_input->alloc(thread->buffer_input, size); + if (ptr == NULL) + { + if (try_count > SW_RINGBUFFER_WARNING) + { + swWarn("memory pool is full. Wait memory collect. alloc(%d)", size); + usleep(1000); + try_count = 0; + } + try_count++; + swReactorThread_yield(thread); + continue; + } + break; + } + //debug("%p\n", ptr); + return ptr; +} +#endif + +#ifdef SW_USE_OPENSSL +static sw_inline int swReactorThread_verify_ssl_state(swReactor *reactor, swListenPort *port, swConnection *conn) +{ + swServer *serv = reactor->ptr; + if (conn->ssl_state == 0 && conn->ssl) + { + int ret = swSSL_accept(conn); + if (ret == SW_READY) + { + if (port->ssl_option.client_cert_file) + { + swDispatchData task; + ret = swSSL_get_client_certificate(conn->ssl, task.data.data, sizeof(task.data.data)); + if (ret < 0) + { + goto no_client_cert; + } + else + { + swFactory *factory = &SwooleG.serv->factory; + task.target_worker_id = -1; + task.data.info.fd = conn->fd; + task.data.info.type = SW_EVENT_CONNECT; + task.data.info.from_id = conn->from_id; + task.data.info.len = ret; + factory->dispatch(factory, &task); + goto delay_receive; + } + } + no_client_cert: + if (SwooleG.serv->onConnect) + { + swServer_tcp_notify(SwooleG.serv, conn, SW_EVENT_CONNECT); + } + delay_receive: + if (serv->enable_delay_receive) + { + conn->listen_wait = 1; + return reactor->del(reactor, conn->fd); + } + return SW_OK; + } + else if (ret == SW_WAIT) + { + return SW_OK; + } + else + { + return SW_ERR; + } + } + return SW_OK; +} +#endif + +static void swReactorThread_onStreamResponse(swStream *stream, char *data, uint32_t length) +{ + swSendData response; + swConnection *conn = swServer_connection_verify(SwooleG.serv, stream->session_id); + if (!conn) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "connection[fd=%d] does not exists.", stream->session_id); + return; + } + response.info.fd = conn->session_id; + response.info.type = SW_EVENT_TCP; + response.info.len = 0; + response.length = length; + response.data = data; + swReactorThread_send(&response); +} + +/** + * for udp + */ +static int swReactorThread_onPackage(swReactor *reactor, swEvent *event) +{ + int fd = event->fd; + int ret; + + swServer *serv = SwooleG.serv; + swConnection *server_sock = &serv->connection_list[fd]; + swDispatchData task; + swSocketAddress info; + swDgramPacket pkt; + swFactory *factory = &serv->factory; + + info.len = sizeof(info.addr); + bzero(&task.data.info, sizeof(task.data.info)); + task.data.info.from_fd = fd; + task.data.info.from_id = SwooleTG.id; +#ifdef SW_BUFFER_RECV_TIME + task.data.info.time = swoole_microtime(); +#endif + + int socket_type = server_sock->socket_type; + switch(socket_type) + { + case SW_SOCK_UDP6: + task.data.info.type = SW_EVENT_UDP6; + break; + case SW_SOCK_UNIX_DGRAM: + task.data.info.type = SW_EVENT_UNIX_DGRAM; + break; + case SW_SOCK_UDP: + default: + task.data.info.type = SW_EVENT_UDP; + break; + } + + char packet[SW_BUFFER_SIZE_UDP]; + do_recvfrom: + ret = recvfrom(fd, packet, SW_BUFFER_SIZE_UDP, 0, (struct sockaddr *) &info.addr, &info.len); + + if (ret > 0) + { + pkt.length = ret; + + //IPv4 + if (socket_type == SW_SOCK_UDP) + { + pkt.port = ntohs(info.addr.inet_v4.sin_port); + pkt.addr.v4.s_addr = info.addr.inet_v4.sin_addr.s_addr; + task.data.info.fd = pkt.addr.v4.s_addr; + } + //IPv6 + else if (socket_type == SW_SOCK_UDP6) + { + pkt.port = ntohs(info.addr.inet_v6.sin6_port); + memcpy(&pkt.addr.v6, &info.addr.inet_v6.sin6_addr, sizeof(info.addr.inet_v6.sin6_addr)); + memcpy(&task.data.info.fd, &info.addr.inet_v6.sin6_addr, sizeof(task.data.info.fd)); + } + //Unix Dgram + else + { + pkt.addr.un.path_length = strlen(info.addr.un.sun_path) + 1; + pkt.length += pkt.addr.un.path_length; + pkt.port = 0; + memcpy(&task.data.info.fd, info.addr.un.sun_path + pkt.addr.un.path_length - 6, sizeof(task.data.info.fd)); + } + + task.target_worker_id = -1; + uint32_t header_size = sizeof(pkt); + + //dgram header + memcpy(task.data.data, &pkt, sizeof(pkt)); + //unix dgram + if (socket_type == SW_SOCK_UNIX_DGRAM) + { + header_size += pkt.addr.un.path_length; + memcpy(task.data.data + sizeof(pkt), info.addr.un.sun_path, pkt.addr.un.path_length); + } + //dgram body + if (pkt.length > SW_BUFFER_SIZE - sizeof(pkt)) + { + task.data.info.len = SW_BUFFER_SIZE; + } + else + { + task.data.info.len = pkt.length + sizeof(pkt); + } + //dispatch packet header + memcpy(task.data.data + header_size, packet, task.data.info.len - header_size); + + uint32_t send_n = pkt.length + header_size; + if (socket_type == SW_SOCK_UNIX_DGRAM) + { + send_n -= pkt.addr.un.path_length; + } + uint32_t offset = 0; + + /** + * lock target + */ + SwooleTG.factory_lock_target = 1; + + if (factory->dispatch(factory, &task) < 0) + { + return SW_ERR; + } + + send_n -= task.data.info.len; + if (send_n == 0) + { + /** + * unlock + */ + SwooleTG.factory_target_worker = -1; + SwooleTG.factory_lock_target = 0; + goto do_recvfrom; + } + + offset = SW_BUFFER_SIZE - header_size; + while (send_n > 0) + { + task.data.info.len = send_n > SW_BUFFER_SIZE ? SW_BUFFER_SIZE : send_n; + memcpy(task.data.data, packet + offset, task.data.info.len); + send_n -= task.data.info.len; + offset += task.data.info.len; + + if (factory->dispatch(factory, &task) < 0) + { + break; + } + } + /** + * unlock + */ + SwooleTG.factory_target_worker = -1; + SwooleTG.factory_lock_target = 0; + goto do_recvfrom; + } + else + { + if (errno == EAGAIN) + { + return SW_OK; + } + else + { + swSysError("recvfrom(%d) failed.", fd); + } + } + return ret; +} + +/** + * close connection + */ +int swReactorThread_close(swReactor *reactor, int fd) +{ + swServer *serv = SwooleG.serv; + swConnection *conn = swServer_connection_get(serv, fd); + if (conn == NULL) + { + swWarn("[Reactor]connection not found. fd=%d|max_fd=%d", fd, swServer_get_maxfd(serv)); + return SW_ERR; + } + + if (serv->factory_mode == SW_MODE_PROCESS) + { + assert(fd % serv->reactor_num == reactor->id); + assert(fd % serv->reactor_num == SwooleTG.id); + } + + if (conn->removed == 0 && reactor->del(reactor, fd) < 0) + { + return SW_ERR; + } + + sw_atomic_fetch_add(&serv->stats->close_count, 1); + sw_atomic_fetch_sub(&serv->stats->connection_num, 1); + + swTrace("Close Event.fd=%d|from=%d", fd, reactor->id); + +#ifdef SW_USE_OPENSSL + if (conn->ssl) + { + swSSL_close(conn); + } +#endif + + //free the receive memory buffer + swServer_free_buffer(serv, fd); + + swListenPort *port = swServer_get_port(serv, fd); + sw_atomic_fetch_sub(&port->connection_num, 1); + + if (port->open_http_protocol && conn->object) + { + swHttpRequest_free(conn); + } + if (port->open_redis_protocol && conn->object) + { + sw_free(conn->object); + conn->object = NULL; + } + +#ifdef SW_USE_SOCKET_LINGER + if (conn->close_force) + { + struct linger linger; + linger.l_onoff = 1; + linger.l_linger = 0; + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(struct linger)) == -1) + { + swWarn("setsockopt(SO_LINGER) failed. Error: %s[%d]", strerror(errno), errno); + } + } +#endif + +#ifdef SW_REACTOR_USE_SESSION + swSession *session = swServer_get_session(serv, conn->session_id); + session->fd = 0; +#endif + +#ifdef SW_USE_TIMEWHEEL + if (reactor->timewheel) + { + swTimeWheel_remove(reactor->timewheel, conn); + } +#endif + + /** + * reset maxfd, for connection_list + */ + if (fd == swServer_get_maxfd(serv)) + { + SwooleGS->lock.lock(&SwooleGS->lock); + int find_max_fd = fd - 1; + swTrace("set_maxfd=%d|close_fd=%d\n", find_max_fd, fd); + /** + * Find the new max_fd + */ + for (; serv->connection_list[find_max_fd].active == 0 && find_max_fd > swServer_get_minfd(serv); find_max_fd--) + ; + swServer_set_maxfd(serv, find_max_fd); + SwooleGS->lock.unlock(&SwooleGS->lock); + } + + return swReactor_close(reactor, fd); +} + +/** + * close the connection + */ +int swReactorThread_onClose(swReactor *reactor, swEvent *event) +{ + swServer *serv = reactor->ptr; + if (serv->factory_mode == SW_MODE_SINGLE) + { + return swReactorProcess_onClose(reactor, event); + } + + int fd = event->fd; + swDataHead notify_ev; + bzero(&notify_ev, sizeof(notify_ev)); + + assert(fd % serv->reactor_num == reactor->id); + assert(fd % serv->reactor_num == SwooleTG.id); + + notify_ev.from_id = reactor->id; + notify_ev.fd = fd; + notify_ev.type = SW_EVENT_CLOSE; + + swTraceLog(SW_TRACE_CLOSE, "client[fd=%d] close the connection.", fd); + + swConnection *conn = swServer_connection_get(SwooleG.serv, fd); + if (conn == NULL || conn->active == 0) + { + return SW_ERR; + } + else if (serv->disable_notify) + { + swReactorThread_close(reactor, fd); + return SW_OK; + } + else if (reactor->del(reactor, fd) == 0) + { + return SwooleG.factory->notify(SwooleG.factory, &notify_ev); + } + else + { + return SW_ERR; + } +} + +/** + * receive data from worker process pipe + */ +static int swReactorThread_onPipeReceive(swReactor *reactor, swEvent *ev) +{ + int n; + swEventData resp; + swSendData _send; + + swPackage_response pkg_resp; + swWorker *worker; + +#ifdef SW_REACTOR_RECV_AGAIN + while (1) +#endif + { + n = read(ev->fd, &resp, sizeof(resp)); + if (n > 0) + { + memcpy(&_send.info, &resp.info, sizeof(resp.info)); + //pipe data + if (_send.info.from_fd == SW_RESPONSE_SMALL) + { + _send.data = resp.data; + _send.length = resp.info.len; + swReactorThread_send(&_send); + } + //use send shm + else if (_send.info.from_fd == SW_RESPONSE_SHM) + { + memcpy(&pkg_resp, resp.data, sizeof(pkg_resp)); + worker = swServer_get_worker(SwooleG.serv, pkg_resp.worker_id); + + _send.data = worker->send_shm; + _send.length = pkg_resp.length; + +#if 0 + struct + { + uint32_t worker; + uint32_t index; + uint32_t serid; + } pkg_header; + + memcpy(&pkg_header, _send.data + 4, sizeof(pkg_header)); + swWarn("fd=%d, worker=%d, index=%d, serid=%d", _send.info.fd, pkg_header.worker, pkg_header.index, pkg_header.serid); +#endif + swReactorThread_send(&_send); + worker->lock.unlock(&worker->lock); + } + //use tmp file + else if (_send.info.from_fd == SW_RESPONSE_TMPFILE) + { + swString *data = swTaskWorker_large_unpack(&resp); + if (data == NULL) + { + return SW_ERR; + } + _send.data = data->str; + _send.length = data->length; + swReactorThread_send(&_send); + } + //reactor thread exit + else if (_send.info.from_fd == SW_RESPONSE_EXIT) + { + reactor->running = 0; + return SW_OK; + } + //will never be here + else + { + abort(); + } + } + else if (errno == EAGAIN) + { + return SW_OK; + } + else + { + swWarn("read(worker_pipe) failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + } + + return SW_OK; +} + +int swReactorThread_send2worker(void *data, int len, uint16_t target_worker_id) +{ + swServer *serv = SwooleG.serv; + + assert(target_worker_id < serv->worker_num); + + int ret = -1; + swWorker *worker = &(serv->workers[target_worker_id]); + + //reactor thread + if (SwooleTG.type == SW_THREAD_REACTOR) + { + int pipe_fd = worker->pipe_master; + int thread_id = serv->connection_list[pipe_fd].from_id; + swReactorThread *thread = swServer_get_thread(serv, thread_id); + swLock *lock = serv->connection_list[pipe_fd].object; + + //lock thread + lock->lock(lock); + + swBuffer *buffer = serv->connection_list[pipe_fd].in_buffer; + if (swBuffer_empty(buffer)) + { + ret = write(pipe_fd, (void *) data, len); +#ifdef HAVE_KQUEUE + if (ret < 0 && (errno == EAGAIN || errno == ENOBUFS)) +#else + if (ret < 0 && errno == EAGAIN) +#endif + { + if (thread->reactor.set(&thread->reactor, pipe_fd, SW_FD_PIPE | SW_EVENT_READ | SW_EVENT_WRITE) < 0) + { + swSysError("reactor->set(%d, PIPE | READ | WRITE) failed.", pipe_fd); + } + goto append_pipe_buffer; + } + } + else + { + append_pipe_buffer: + if (swBuffer_append(buffer, data, len) < 0) + { + swWarn("append to pipe_buffer failed."); + ret = SW_ERR; + } + else + { + ret = SW_OK; + } + } + //release thread lock + lock->unlock(lock); + } + //master/udp thread + else + { + int pipe_fd = worker->pipe_master; + ret = swSocket_write_blocking(pipe_fd, data, len); + } + return ret; +} + +/** + * send to client or append to out_buffer + */ +int swReactorThread_send(swSendData *_send) +{ + swServer *serv = SwooleG.serv; + uint32_t session_id = _send->info.fd; + void *_send_data = _send->data; + uint32_t _send_length = _send->length; + + swConnection *conn; + if (_send->info.type != SW_EVENT_CLOSE) + { + conn = swServer_connection_verify(serv, session_id); + } + else + { + conn = swServer_connection_verify_no_ssl(serv, session_id); + } + if (!conn) + { + if (_send->info.type == SW_EVENT_TCP) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "send %d byte failed, session#%d does not exist.", _send_length, session_id); + } + else + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "send event$[%d] failed, session#%d does not exist.", _send->info.type, session_id); + } + return SW_ERR; + } + + int fd = conn->fd; + swReactor *reactor; + + if (serv->factory_mode == SW_MODE_SINGLE) + { + reactor = &(serv->reactor_threads[0].reactor); + if (conn->overflow) + { + if (serv->send_yield) + { + SwooleG.error = SW_ERROR_OUTPUT_BUFFER_OVERFLOW; + } + else + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_OUTPUT_BUFFER_OVERFLOW, "connection#%d output buffer overflow.", fd); + } + return SW_ERR; + } + } + else + { + reactor = &(serv->reactor_threads[conn->from_id].reactor); + assert(fd % serv->reactor_num == reactor->id); + assert(fd % serv->reactor_num == SwooleTG.id); + } + + /** + * Reset send buffer, Immediately close the connection. + */ + if (_send->info.type == SW_EVENT_CLOSE && (conn->close_reset || conn->removed)) + { + goto close_fd; + } + else if (_send->info.type == SW_EVENT_CONFIRM) + { + reactor->add(reactor, conn->fd, conn->fdtype | SW_EVENT_READ); + conn->listen_wait = 0; + return SW_OK; + } + /** + * pause recv data + */ + else if (_send->info.type == SW_EVENT_PAUSE_RECV) + { + if (conn->events & SW_EVENT_WRITE) + { + return reactor->set(reactor, conn->fd, conn->fdtype | SW_EVENT_WRITE); + } + else + { + return reactor->del(reactor, conn->fd); + } + } + /** + * resume recv data + */ + else if (_send->info.type == SW_EVENT_RESUME_RECV) + { + if (conn->events & SW_EVENT_WRITE) + { + return reactor->set(reactor, conn->fd, conn->fdtype | SW_EVENT_READ | SW_EVENT_WRITE); + } + else + { + return reactor->add(reactor, conn->fd, conn->fdtype | SW_EVENT_READ); + } + } + + if (swBuffer_empty(conn->out_buffer)) + { + /** + * close connection. + */ + if (_send->info.type == SW_EVENT_CLOSE) + { + close_fd: + reactor->close(reactor, fd); + return SW_OK; + } +#ifdef SW_REACTOR_SYNC_SEND + //Direct send + if (_send->info.type != SW_EVENT_SENDFILE) + { + if (!conn->direct_send) + { + goto buffer_send; + } + + int n; + + direct_send: + n = swConnection_send(conn, _send_data, _send_length, 0); + if (n == _send_length) + { + return SW_OK; + } + else if (n > 0) + { + _send_data += n; + _send_length -= n; + goto buffer_send; + } + else if (errno == EINTR) + { + goto direct_send; + } + else + { + goto buffer_send; + } + } +#endif + //buffer send + else + { +#ifdef SW_REACTOR_SYNC_SEND + buffer_send: +#endif + if (!conn->out_buffer) + { + conn->out_buffer = swBuffer_new(SW_BUFFER_SIZE); + if (conn->out_buffer == NULL) + { + return SW_ERR; + } + } + } + } + + swBuffer_trunk *trunk; + //close connection + if (_send->info.type == SW_EVENT_CLOSE) + { + trunk = swBuffer_new_trunk(conn->out_buffer, SW_CHUNK_CLOSE, 0); + trunk->store.data.val1 = _send->info.type; + } + //sendfile to client + else if (_send->info.type == SW_EVENT_SENDFILE) + { + swSendFile_request *req = (swSendFile_request *) _send_data; + swConnection_sendfile(conn, req->filename, req->offset, req->length); + } + //send data + else + { + //connection is closed + if (conn->removed) + { + swWarn("connection#%d is closed by client.", fd); + return SW_ERR; + } + //connection output buffer overflow + if (conn->out_buffer->length >= conn->buffer_size) + { + if (serv->send_yield) + { + SwooleG.error = SW_ERROR_OUTPUT_BUFFER_OVERFLOW; + } + else + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_OUTPUT_BUFFER_OVERFLOW, "connection#%d output buffer overflow.", fd); + } + conn->overflow = 1; + if (serv->onBufferEmpty && serv->onBufferFull == NULL) + { + conn->high_watermark = 1; + } + } + + int _length = _send_length; + void* _pos = _send_data; + int _n; + + //buffer enQueue + while (_length > 0) + { + _n = _length >= SW_BUFFER_SIZE_BIG ? SW_BUFFER_SIZE_BIG : _length; + swBuffer_append(conn->out_buffer, _pos, _n); + _pos += _n; + _length -= _n; + } + + swListenPort *port = swServer_get_port(serv, fd); + if (serv->onBufferFull && conn->high_watermark == 0 && conn->out_buffer->length >= port->buffer_high_watermark) + { + swServer_tcp_notify(serv, conn, SW_EVENT_BUFFER_FULL); + conn->high_watermark = 1; + } + } + + //listen EPOLLOUT event + if (reactor->set(reactor, fd, SW_EVENT_TCP | SW_EVENT_WRITE | SW_EVENT_READ) < 0 + && (errno == EBADF || errno == ENOENT)) + { + goto close_fd; + } + + return SW_OK; +} + +/** + * [ReactorThread] worker pipe can write. + */ +static int swReactorThread_onPipeWrite(swReactor *reactor, swEvent *ev) +{ + int ret; + + swBuffer_trunk *trunk = NULL; + swEventData *send_data; + swConnection *conn; + swServer *serv = reactor->ptr; + swBuffer *buffer = serv->connection_list[ev->fd].in_buffer; + swLock *lock = serv->connection_list[ev->fd].object; + + //lock thread + lock->lock(lock); + + while (!swBuffer_empty(buffer)) + { + trunk = swBuffer_get_trunk(buffer); + send_data = trunk->store.ptr; + + //server active close, discard data. + if (swEventData_is_stream(send_data->info.type)) + { + //send_data->info.fd is session_id + conn = swServer_connection_verify(serv, send_data->info.fd); + if (conn == NULL || conn->closed) + { +#ifdef SW_USE_RINGBUFFER + swReactorThread *thread = swServer_get_thread(SwooleG.serv, SwooleTG.id); + swPackage package; + memcpy(&package, send_data->data, sizeof(package)); + thread->buffer_input->free(thread->buffer_input, package.data); +#endif + if (conn && conn->closed) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED_BY_SERVER, "Session#%d is closed by server.", send_data->info.fd); + } + swBuffer_pop_trunk(buffer, trunk); + continue; + } + } + + ret = write(ev->fd, trunk->store.ptr, trunk->length); + if (ret < 0) + { + //release lock + lock->unlock(lock); +#ifdef HAVE_KQUEUE + return (errno == EAGAIN || errno == ENOBUFS) ? SW_OK : SW_ERR; +#else + return errno == EAGAIN ? SW_OK : SW_ERR; +#endif + } + else + { + swBuffer_pop_trunk(buffer, trunk); + } + } + + //remove EPOLLOUT event + if (swBuffer_empty(buffer)) + { + if (SwooleG.serv->connection_list[ev->fd].from_id == SwooleTG.id) + { + ret = reactor->set(reactor, ev->fd, SW_FD_PIPE | SW_EVENT_READ); + } + else + { + ret = reactor->del(reactor, ev->fd); + } + if (ret < 0) + { + swSysError("reactor->set(%d) failed.", ev->fd); + } + } + + //release lock + lock->unlock(lock); + + return SW_OK; +} + +void swReactorThread_set_protocol(swServer *serv, swReactor *reactor) +{ + //UDP Packet + reactor->setHandle(reactor, SW_FD_UDP, swReactorThread_onPackage); + //Write + reactor->setHandle(reactor, SW_FD_TCP | SW_EVENT_WRITE, swReactorThread_onWrite); + //Read + reactor->setHandle(reactor, SW_FD_TCP | SW_EVENT_READ, swReactorThread_onRead); + + swListenPort *ls; + //listen the all tcp port + LL_FOREACH(serv->listen_list, ls) + { + if (swSocket_is_dgram(ls->type)) + { + continue; + } + swPort_set_protocol(ls); + } +} + +static int swReactorThread_onRead(swReactor *reactor, swEvent *event) +{ + swServer *serv = reactor->ptr; + /** + * invalid event + * The server has been actively closed the connection, the client also initiated off, fd has been reused. + */ + if (event->socket->from_fd == 0) + { + return SW_OK; + } + swListenPort *port = swServer_get_port(serv, event->fd); +#ifdef SW_USE_OPENSSL + if (swReactorThread_verify_ssl_state(reactor, port, event->socket) < 0) + { + return swReactorThread_close(reactor, event->fd); + } +#endif + +#ifdef SW_USE_TIMEWHEEL + /** + * TimeWheel update + */ + if (reactor->timewheel && swTimeWheel_new_index(reactor->timewheel) != event->socket->timewheel_index) + { + swTimeWheel_update(reactor->timewheel, event->socket); + } +#endif + + event->socket->last_time = serv->gs->now; +#ifdef SW_BUFFER_RECV_TIME + event->socket->last_time_usec = swoole_microtime(); +#endif + + return port->onRead(reactor, port, event); +} + +static int swReactorThread_onWrite(swReactor *reactor, swEvent *ev) +{ + int ret; + swServer *serv = SwooleG.serv; + swBuffer_trunk *chunk; + int fd = ev->fd; + + if (serv->factory_mode == SW_MODE_PROCESS) + { + assert(fd % serv->reactor_num == reactor->id); + assert(fd % serv->reactor_num == SwooleTG.id); + } + + swConnection *conn = swServer_connection_get(serv, fd); + if (conn == NULL || conn->active == 0) + { + return SW_ERR; + } + + swTraceLog(SW_TRACE_REACTOR, "fd=%d, conn->connect_notify=%d, conn->close_notify=%d, serv->disable_notify=%d, conn->close_force=%d", + fd, conn->connect_notify, conn->close_notify, serv->disable_notify, conn->close_force); + + if (conn->connect_notify) + { + conn->connect_notify = 0; +#ifdef SW_USE_TIMEWHEEL + if (reactor->timewheel) + { + swTimeWheel_add(reactor->timewheel, conn); + } +#endif +#ifdef SW_USE_OPENSSL + if (conn->ssl) + { + goto listen_read_event; + } +#endif + //notify worker process + if (serv->onConnect) + { + swServer_tcp_notify(serv, conn, SW_EVENT_CONNECT); + if (!swBuffer_empty(conn->out_buffer)) + { + goto _pop_chunk; + } + } + //delay receive, wait resume command. + if (serv->enable_delay_receive) + { + conn->listen_wait = 1; + return reactor->del(reactor, fd); + } + else + { +#ifdef SW_USE_OPENSSL + listen_read_event: +#endif + return reactor->set(reactor, fd, SW_EVENT_TCP | SW_EVENT_READ); + } + } + else if (conn->close_notify) + { +#ifdef SW_USE_OPENSSL + if (conn->ssl && conn->ssl_state != SW_SSL_STATE_READY) + { + return swReactorThread_close(reactor, fd); + } +#endif + swServer_tcp_notify(serv, conn, SW_EVENT_CLOSE); + conn->close_notify = 0; + return SW_OK; + } + else if (serv->disable_notify && conn->close_force) + { + return swReactorThread_close(reactor, fd); + } + + _pop_chunk: while (!swBuffer_empty(conn->out_buffer)) + { + chunk = swBuffer_get_trunk(conn->out_buffer); + if (chunk->type == SW_CHUNK_CLOSE) + { + close_fd: reactor->close(reactor, fd); + return SW_OK; + } + else if (chunk->type == SW_CHUNK_SENDFILE) + { + ret = swConnection_onSendfile(conn, chunk); + } + else + { + ret = swConnection_buffer_send(conn); + } + + if (ret < 0) + { + if (conn->close_wait) + { + goto close_fd; + } + else if (conn->send_wait) + { + break; + } + } + } + + if (conn->overflow && conn->out_buffer->length < conn->buffer_size) + { + conn->overflow = 0; + } + + if (serv->onBufferEmpty && conn->high_watermark) + { + swListenPort *port = swServer_get_port(serv, fd); + if (conn->out_buffer->length <= port->buffer_low_watermark) + { + conn->high_watermark = 0; + swServer_tcp_notify(serv, conn, SW_EVENT_BUFFER_EMPTY); + } + } + + //remove EPOLLOUT event + if (!conn->removed && swBuffer_empty(conn->out_buffer)) + { + reactor->set(reactor, fd, SW_FD_TCP | SW_EVENT_READ); + } + return SW_OK; +} + +int swReactorThread_create(swServer *serv) +{ + int ret = 0; + /** + * init reactor thread pool + */ + serv->reactor_threads = SwooleG.memory_pool->alloc(SwooleG.memory_pool, (serv->reactor_num * sizeof(swReactorThread))); + if (serv->reactor_threads == NULL) + { + swError("calloc[reactor_threads] fail.alloc_size=%d", (int )(serv->reactor_num * sizeof(swReactorThread))); + return SW_ERR; + } + + /** + * alloc the memory for connection_list + */ + if (serv->factory_mode == SW_MODE_PROCESS) + { + serv->connection_list = sw_shm_calloc(serv->max_connection, sizeof(swConnection)); + } + else + { + serv->connection_list = sw_calloc(serv->max_connection, sizeof(swConnection)); + } + if (serv->connection_list == NULL) + { + swError("calloc[1] failed"); + return SW_ERR; + } + + //create factry object + if (serv->factory_mode == SW_MODE_THREAD) + { + if (serv->worker_num < 1) + { + swError("Fatal Error: serv->worker_num < 1"); + return SW_ERR; + } + ret = swFactoryThread_create(&(serv->factory), serv->worker_num); + } + else if (serv->factory_mode == SW_MODE_PROCESS) + { + if (serv->worker_num < 1) + { + swError("Fatal Error: serv->worker_num < 1"); + return SW_ERR; + } + ret = swFactoryProcess_create(&(serv->factory), serv->worker_num); + } + else + { + ret = swFactory_create(&(serv->factory)); + } + + if (ret < 0) + { + swError("create factory failed"); + return SW_ERR; + } + return SW_OK; +} + +int swReactorThread_start(swServer *serv, swReactor *main_reactor_ptr) +{ + swThreadParam *param; + swReactorThread *thread; + pthread_t pidt; + int i; + + swServer_store_listen_socket(serv); + +#ifdef HAVE_REUSEPORT + SwooleG.reuse_port = 0; +#endif + + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (ls->type == SW_SOCK_UDP || ls->type == SW_SOCK_UDP6 || ls->type == SW_SOCK_UNIX_DGRAM) + { + continue; + } + main_reactor_ptr->add(main_reactor_ptr, ls->sock, SW_FD_LISTEN); + } + +#ifdef HAVE_PTHREAD_BARRIER + //init thread barrier + pthread_barrier_init(&serv->barrier, NULL, serv->reactor_num + 1); +#endif + + //create reactor thread + for (i = 0; i < serv->reactor_num; i++) + { + thread = &(serv->reactor_threads[i]); + param = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swThreadParam)); + if (param == NULL) + { + swError("malloc failed"); + return SW_ERR; + } + + param->object = serv; + param->pti = i; + + if (pthread_create(&pidt, NULL, (void * (*)(void *)) swReactorThread_loop, (void *) param) < 0) + { + swError("pthread_create[tcp_reactor] failed. Error: %s[%d]", strerror(errno), errno); + } + thread->thread_id = pidt; + } +#ifdef HAVE_PTHREAD_BARRIER + //wait reactor thread + pthread_barrier_wait(&serv->barrier); +#else + SW_START_SLEEP; +#endif + + return SW_OK; +} + +/** + * ReactorThread main Loop + */ +static int swReactorThread_loop(swThreadParam *param) +{ + swServer *serv = SwooleG.serv; + int ret; + int reactor_id = param->pti; + + pthread_t thread_id = pthread_self(); + + SwooleTG.factory_lock_target = 0; + SwooleTG.factory_target_worker = -1; + SwooleTG.id = reactor_id; + SwooleTG.type = SW_THREAD_REACTOR; + + if (serv->dispatch_mode == SW_MODE_BASE || serv->dispatch_mode == SW_MODE_THREAD) + { + SwooleTG.buffer_input = swServer_create_worker_buffer(serv); + if (!SwooleTG.buffer_input) + { + return SW_ERR; + } + } + + SwooleTG.buffer_stack = swString_new(8192); + if (SwooleTG.buffer_stack == NULL) + { + return SW_ERR; + } + + swReactorThread *thread = swServer_get_thread(serv, reactor_id); + swReactor *reactor = &thread->reactor; + + SwooleTG.reactor = reactor; + +#ifdef HAVE_CPU_AFFINITY + //cpu affinity setting + if (serv->open_cpu_affinity) + { + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + + if (serv->cpu_affinity_available_num) + { + CPU_SET(serv->cpu_affinity_available[reactor_id % serv->cpu_affinity_available_num], &cpu_set); + } + else + { + CPU_SET(reactor_id % SW_CPU_NUM, &cpu_set); + } + + if (0 != pthread_setaffinity_np(thread_id, sizeof(cpu_set), &cpu_set)) + { + swSysError("pthread_setaffinity_np() failed."); + } + } +#endif + + ret = swReactor_create(reactor, SW_REACTOR_MAXEVENTS); + if (ret < 0) + { + return SW_ERR; + } + + swSignal_none(); + + reactor->ptr = serv; + reactor->id = reactor_id; + reactor->thread = 1; + reactor->socket_list = serv->connection_list; + reactor->max_socket = serv->max_connection; + + reactor->onFinish = NULL; + reactor->onTimeout = NULL; + reactor->close = swReactorThread_close; + + reactor->setHandle(reactor, SW_FD_CLOSE, swReactorThread_onClose); + reactor->setHandle(reactor, SW_FD_PIPE | SW_EVENT_READ, swReactorThread_onPipeReceive); + reactor->setHandle(reactor, SW_FD_PIPE | SW_EVENT_WRITE, swReactorThread_onPipeWrite); + + //listen UDP + if (serv->have_udp_sock == 1) + { + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (ls->type == SW_SOCK_UDP || ls->type == SW_SOCK_UDP6 || ls->type == SW_SOCK_UNIX_DGRAM) + { + if (ls->sock % serv->reactor_num != reactor_id) + { + continue; + } + if (ls->type == SW_SOCK_UDP) + { + serv->connection_list[ls->sock].info.addr.inet_v4.sin_port = htons(ls->port); + } + else + { + serv->connection_list[ls->sock].info.addr.inet_v6.sin6_port = htons(ls->port); + } + serv->connection_list[ls->sock].fd = ls->sock; + serv->connection_list[ls->sock].socket_type = ls->type; + serv->connection_list[ls->sock].object = ls; + ls->thread_id = thread_id; + reactor->add(reactor, ls->sock, SW_FD_UDP); + } + } + } + + //set protocol function point + swReactorThread_set_protocol(serv, reactor); + + int i = 0, pipe_fd; +#ifdef SW_USE_RINGBUFFER + int j = 0; +#endif + + if (serv->factory_mode == SW_MODE_PROCESS) + { +#ifdef SW_USE_RINGBUFFER + thread->pipe_read_list = sw_calloc(serv->reactor_pipe_num, sizeof(int)); + if (thread->pipe_read_list == NULL) + { + swSysError("thread->buffer_pipe create failed"); + return SW_ERR; + } +#endif + + for (i = 0; i < serv->worker_num; i++) + { + if (i % serv->reactor_num == reactor_id) + { + pipe_fd = serv->workers[i].pipe_master; + + //for request + swBuffer *buffer = swBuffer_new(sizeof(swEventData)); + if (!buffer) + { + swWarn("create buffer failed."); + break; + } + serv->connection_list[pipe_fd].in_buffer = buffer; + + //for response + swSetNonBlock(pipe_fd); + reactor->add(reactor, pipe_fd, SW_FD_PIPE); + + if (thread->notify_pipe == 0) + { + thread->notify_pipe = serv->workers[i].pipe_worker; + } + + /** + * mapping reactor_id and worker pipe + */ + serv->connection_list[pipe_fd].from_id = reactor_id; + serv->connection_list[pipe_fd].fd = pipe_fd; + serv->connection_list[pipe_fd].object = sw_malloc(sizeof(swLock)); + + /** + * create pipe lock + */ + if (serv->connection_list[pipe_fd].object == NULL) + { + swWarn("create pipe mutex lock failed."); + break; + } + swMutex_create(serv->connection_list[pipe_fd].object, 0); + +#ifdef SW_USE_RINGBUFFER + thread->pipe_read_list[j] = pipe_fd; + j++; +#endif + } + } + } + +#ifdef SW_USE_TIMEWHEEL + if (serv->heartbeat_idle_time > 0) + { + if (serv->heartbeat_idle_time < SW_TIMEWHEEL_SIZE) + { + reactor->timewheel = swTimeWheel_new(serv->heartbeat_idle_time); + reactor->heartbeat_interval = 1; + } + else + { + reactor->timewheel = swTimeWheel_new(SW_TIMEWHEEL_SIZE); + reactor->heartbeat_interval = serv->heartbeat_idle_time / SW_TIMEWHEEL_SIZE; + } + reactor->last_heartbeat_time = 0; + if (reactor->timewheel == NULL) + { + swSysError("thread->timewheel create failed."); + return SW_ERR; + } + reactor->timeout_msec = reactor->heartbeat_interval * 1000; + reactor->onFinish = swReactorThread_onReactorCompleted; + reactor->onTimeout = swReactorThread_onReactorCompleted; + } +#endif + + //wait other thread +#ifdef HAVE_PTHREAD_BARRIER + pthread_barrier_wait(&serv->barrier); +#else + SW_START_SLEEP; +#endif + //main loop + reactor->wait(reactor, NULL); + //shutdown + reactor->free(reactor); + +#ifdef SW_USE_TIMEWHEEL + if (reactor->timewheel) + { + swTimeWheel_free(reactor->timewheel); + } +#endif + + swString_free(SwooleTG.buffer_stack); + pthread_exit(0); + return SW_OK; +} + +/** + * dispatch request data [only data frame] + */ +int swReactorThread_dispatch(swConnection *conn, char *data, uint32_t length) +{ + swFactory *factory = SwooleG.factory; + swServer *serv = factory->ptr; + swDispatchData task; + + task.data.info.from_fd = conn->from_fd; + task.data.info.from_id = conn->from_id; +#ifdef SW_BUFFER_RECV_TIME + task.data.info.time = conn->last_time_usec; +#endif + + if (serv->dispatch_mode == SW_DISPATCH_STREAM) + { + swStream *stream = swStream_new(serv->stream_socket, 0, SW_SOCK_UNIX_STREAM); + if (stream == NULL) + { + return SW_ERR; + } + stream->response = swReactorThread_onStreamResponse; + stream->session_id = conn->session_id; + swListenPort *port = swServer_get_port(serv, conn->fd); + swStream_set_max_length(stream, port->protocol.package_max_length); + + task.data.info.fd = conn->session_id; + task.data.info.type = SW_EVENT_PACKAGE_END; + task.data.info.len = 0; + + if (swStream_send(stream, (char*) &task.data.info, sizeof(task.data.info)) < 0) + { + return SW_ERR; + } + if (swStream_send(stream, data, length) < 0) + { + stream->cancel = 1; + return SW_ERR; + } + return SW_OK; + } + + task.data.info.fd = conn->fd; + + swTrace("send string package, size=%ld bytes.", (long)length); + +#ifdef SW_USE_RINGBUFFER + swServer *serv = SwooleG.serv; + swReactorThread *thread = swServer_get_thread(serv, SwooleTG.id); + + swPackage package; + package.length = length; + package.data = swReactorThread_alloc(thread, package.length); + + task.data.info.type = SW_EVENT_PACKAGE; + task.data.info.len = sizeof(package); + + memcpy(package.data, data, package.length); + memcpy(task.data.data, &package, sizeof(package)); + + task.target_worker_id = swServer_worker_schedule(serv, conn->fd, &task.data); + + //dispatch failed, free the memory. + if (factory->dispatch(factory, &task) < 0) + { + thread->buffer_input->free(thread->buffer_input, package.data); + } + else + { + return SW_OK; + } +#else + + task.data.info.type = SW_EVENT_PACKAGE_START; + task.target_worker_id = -1; + + /** + * lock target + */ + SwooleTG.factory_lock_target = 1; + + size_t send_n = length; + size_t offset = 0; + + while (send_n > 0) + { + if (send_n > SW_BUFFER_SIZE) + { + task.data.info.len = SW_BUFFER_SIZE; + } + else + { + task.data.info.type = SW_EVENT_PACKAGE_END; + task.data.info.len = send_n; + } + + task.data.info.fd = conn->fd; + memcpy(task.data.data, data + offset, task.data.info.len); + + send_n -= task.data.info.len; + offset += task.data.info.len; + + swTrace("dispatch, type=%d|len=%d\n", task.data.info.type, task.data.info.len); + + if (factory->dispatch(factory, &task) < 0) + { + break; + } + } + + /** + * unlock + */ + SwooleTG.factory_target_worker = -1; + SwooleTG.factory_lock_target = 0; + +#endif + return SW_OK; +} + +void swReactorThread_free(swServer *serv) +{ + int i; + swReactorThread *thread; + + if (serv->gs->start == 0) + { + return; + } + + for (i = 0; i < serv->reactor_num; i++) + { + thread = &(serv->reactor_threads[i]); + if (thread->notify_pipe) + { + swDataHead ev; + memset(&ev, 0, sizeof(ev)); + ev.from_fd = SW_RESPONSE_EXIT; + if (swSocket_write_blocking(thread->notify_pipe, (void *) &ev, sizeof(ev)) < 0) + { + goto cancel; + } + } + else + { + cancel: if (pthread_cancel(thread->thread_id) < 0) + { + swSysError("pthread_cancel(%ld) failed.", (long ) thread->thread_id); + } + } + //wait thread + if (pthread_join(thread->thread_id, NULL) != 0) + { + swSysError("pthread_join(%ld) failed.", (long ) thread->thread_id); + } +#ifdef SW_USE_RINGBUFFER + thread->buffer_input->destroy(thread->buffer_input); +#endif + } +} + +#ifdef SW_USE_TIMEWHEEL +static void swReactorThread_onReactorCompleted(swReactor *reactor) +{ + swServer *serv = reactor->ptr; + if (reactor->heartbeat_interval > 0 && reactor->last_heartbeat_time < serv->gs->now - reactor->heartbeat_interval) + { + swTimeWheel_forward(reactor->timewheel, reactor); + reactor->last_heartbeat_time = serv->gs->now; + } +} +#endif diff --git a/vendor/swoole/src/network/Server.c b/vendor/swoole/src/network/Server.c new file mode 100755 index 0000000..655d5f5 --- /dev/null +++ b/vendor/swoole/src/network/Server.c @@ -0,0 +1,1894 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ +#if __APPLE__ +// Fix warning: 'daemon' is deprecated: first deprecated in macOS 10.5 - Use posix_spawn APIs instead. [-Wdeprecated-declarations] +#define daemon yes_we_know_that_daemon_is_deprecated_in_os_x_10_5_thankyou +#endif +#include "Server.h" +#include "http.h" +#include "Connection.h" +#include <spawn.h> +#include <sys/stat.h> +#if __APPLE__ +#undef daemon +extern int daemon(int, int); +#endif + +#if SW_REACTOR_SCHEDULE == 3 +static sw_inline void swServer_reactor_schedule(swServer *serv) +{ + //以第1个为基准进行排序,取出最小值 + int i, event_num = serv->reactor_threads[0].reactor.event_num; + serv->reactor_next_i = 0; + for (i = 1; i < serv->reactor_num; i++) + { + if (serv->reactor_threads[i].reactor.event_num < event_num) + { + serv->reactor_next_i = i; + event_num = serv->reactor_threads[i].reactor.event_num; + } + } +} +#endif + +static int swServer_start_check(swServer *serv); +static void swServer_signal_hanlder(int sig); +static int swServer_start_proxy(swServer *serv); +static void swServer_disable_accept(swReactor *reactor); + +#ifndef SW_USE_TIMEWHEEL +static void swHeartbeatThread_start(swServer *serv); +static void swHeartbeatThread_loop(swThreadParam *param); +#endif + +static swConnection* swServer_connection_new(swServer *serv, swListenPort *ls, int fd, int from_fd, int reactor_id); + +swServerG SwooleG; +swWorkerG SwooleWG; +__thread swThreadG SwooleTG; + +int16_t sw_errno; +char sw_error[SW_ERROR_MSG_SIZE]; + +static void swServer_disable_accept(swReactor *reactor) +{ + swListenPort *ls; + + LL_FOREACH(SwooleG.serv->listen_list, ls) + { + //UDP + if (ls->type == SW_SOCK_UDP || ls->type == SW_SOCK_UDP6 || ls->type == SW_SOCK_UNIX_DGRAM) + { + continue; + } + reactor->del(reactor, ls->sock); + } +} + +void swServer_enable_accept(swReactor *reactor) +{ + swListenPort *ls; + + LL_FOREACH(SwooleG.serv->listen_list, ls) + { + //UDP + if (ls->type == SW_SOCK_UDP || ls->type == SW_SOCK_UDP6 || ls->type == SW_SOCK_UNIX_DGRAM) + { + continue; + } + reactor->add(reactor, ls->sock, SW_FD_LISTEN); + } +} + +void swServer_close_port(swServer *serv, enum swBool_type only_stream_port) +{ + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + //dgram socket + if (only_stream_port && (ls->type == SW_SOCK_UDP || ls->type == SW_SOCK_UDP6 || ls->type == SW_SOCK_UNIX_DGRAM)) + { + continue; + } + //stream socket + close(ls->sock); + } +} + +int swServer_master_onAccept(swReactor *reactor, swEvent *event) +{ + swServer *serv = reactor->ptr; + swReactor *sub_reactor; + swSocketAddress client_addr; + socklen_t client_addrlen = sizeof(client_addr); + swListenPort *listen_host = serv->connection_list[event->fd].object; + + int new_fd = 0, reactor_id = 0, i; + + //SW_ACCEPT_AGAIN + for (i = 0; i < SW_ACCEPT_MAX_COUNT; i++) + { +#ifdef HAVE_ACCEPT4 + new_fd = accept4(event->fd, (struct sockaddr *) &client_addr, &client_addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); +#else + new_fd = accept(event->fd, (struct sockaddr *) &client_addr, &client_addrlen); +#endif + if (new_fd < 0) + { + switch (errno) + { + case EAGAIN: + return SW_OK; + case EINTR: + continue; + default: + if (errno == EMFILE || errno == ENFILE) + { + swServer_disable_accept(reactor); + reactor->disable_accept = 1; + } + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "accept() failed. Error: %s[%d]", strerror(errno), errno); + return SW_OK; + } + } +#ifndef HAVE_ACCEPT4 + else + { + swoole_fcntl_set_option(new_fd, 1, 1); + } +#endif + + swTrace("[Master] Accept new connection. maxfd=%d|reactor_id=%d|conn=%d", swServer_get_maxfd(serv), reactor->id, new_fd); + + //too many connection + if (new_fd >= serv->max_connection) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SERVER_TOO_MANY_SOCKET, "Too many connections [now: %d].", new_fd); + close(new_fd); + return SW_OK; + } + + if (serv->factory_mode == SW_MODE_SINGLE) + { + reactor_id = 0; + } + else + { + reactor_id = new_fd % serv->reactor_num; + } + + //add to connection_list + swConnection *conn = swServer_connection_new(serv, listen_host, new_fd, event->fd, reactor_id); + memcpy(&conn->info.addr, &client_addr, sizeof(client_addr)); + sub_reactor = &serv->reactor_threads[reactor_id].reactor; + conn->socket_type = listen_host->type; + +#ifdef SW_USE_OPENSSL + if (listen_host->ssl) + { + if (swSSL_create(conn, listen_host->ssl_context, 0) < 0) + { + bzero(conn, sizeof(swConnection)); + close(new_fd); + return SW_OK; + } + } + else + { + conn->ssl = NULL; + } +#endif + /* + * [!!!] new_connection function must before reactor->add + */ + conn->connect_notify = 1; + if (sub_reactor->add(sub_reactor, new_fd, SW_FD_TCP | SW_EVENT_WRITE) < 0) + { + bzero(conn, sizeof(swConnection)); + close(new_fd); + return SW_OK; + } + +#ifdef SW_ACCEPT_AGAIN + continue; +#else + break; +#endif + } + return SW_OK; +} + +static int swServer_start_check(swServer *serv) +{ + if (serv->onReceive == NULL && serv->onPacket == NULL) + { + swWarn("onReceive and onPacket event callback must be set."); + return SW_ERR; + } + if (serv->have_tcp_sock && serv->onReceive == NULL) + { + swWarn("onReceive event callback must be set."); + return SW_ERR; + } + //UDP + if (!serv->onPacket) + { + serv->onPacket = serv->onReceive; + } + //disable notice when use SW_DISPATCH_ROUND and SW_DISPATCH_QUEUE + if (serv->factory_mode == SW_MODE_PROCESS) + { + if (serv->dispatch_mode == SW_DISPATCH_ROUND || serv->dispatch_mode == SW_DISPATCH_QUEUE) + { + if (!serv->enable_unsafe_event) + { + serv->onConnect = NULL; + serv->onClose = NULL; + serv->disable_notify = 1; + } + } + } + //AsyncTask + if (serv->task_worker_num > 0) + { + if (serv->onTask == NULL) + { + swWarn("onTask is null"); + return SW_ERR; + } + if (serv->onFinish == NULL) + { + swWarn("onFinish is null"); + return SW_ERR; + } + if (serv->task_worker_num > SW_CPU_NUM * SW_MAX_WORKER_NCPU) + { + swWarn("serv->task_worker_num > %d, Too many processes, the system will be slow", SW_CPU_NUM * SW_MAX_WORKER_NCPU); + serv->task_worker_num = SW_CPU_NUM * SW_MAX_WORKER_NCPU; + } + } + //check thread num + if (serv->reactor_num > SW_CPU_NUM * SW_MAX_THREAD_NCPU) + { + serv->reactor_num = SW_CPU_NUM * SW_MAX_THREAD_NCPU; + } + if (serv->worker_num > SW_CPU_NUM * SW_MAX_WORKER_NCPU) + { + swWarn("serv->worker_num > %d, Too many processes, the system will be slow", SW_CPU_NUM * SW_MAX_WORKER_NCPU); + serv->worker_num = SW_CPU_NUM * SW_MAX_WORKER_NCPU; + } + if (serv->worker_num < serv->reactor_num) + { + serv->reactor_num = serv->worker_num; + } + if (SwooleG.max_sockets > 0 && serv->max_connection > SwooleG.max_sockets) + { + swWarn("serv->max_connection is exceed the maximum value[%d].", SwooleG.max_sockets); + serv->max_connection = SwooleG.max_sockets; + } + if (serv->max_connection < (serv->worker_num + serv->task_worker_num) * 2 + 32) + { + swWarn("serv->max_connection is too small."); + serv->max_connection = SwooleG.max_sockets; + } + if (serv->max_connection > SW_SESSION_LIST_SIZE) + { + swWarn("serv->max_connection is exceed the SW_SESSION_LIST_SIZE[%d].", SW_SESSION_LIST_SIZE); + serv->max_connection = SW_SESSION_LIST_SIZE; + } + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (ls->protocol.package_max_length < SW_BUFFER_MIN_SIZE) + { + ls->protocol.package_max_length = SW_BUFFER_MIN_SIZE; + } + } + return SW_OK; +} + +/** + * proxy模式 + * 在单独的n个线程中接受维持TCP连接 + */ +static int swServer_start_proxy(swServer *serv) +{ + int ret; + swReactor *main_reactor = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swReactor)); + + ret = swReactor_create(main_reactor, SW_REACTOR_MAXEVENTS); + if (ret < 0) + { + swWarn("Reactor create failed"); + return SW_ERR; + } + + main_reactor->thread = 1; + main_reactor->socket_list = serv->connection_list; + main_reactor->disable_accept = 0; + main_reactor->enable_accept = swServer_enable_accept; + +#ifdef HAVE_SIGNALFD + if (SwooleG.use_signalfd) + { + swSignalfd_setup(main_reactor); + } +#endif + + //set listen socket options + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (swSocket_is_dgram(ls->type)) + { + continue; + } + if (swPort_listen(ls) < 0) + { + return SW_ERR; + } + } + + if (serv->stream_fd > 0) + { + close(serv->stream_fd); + } + + /** + * create reactor thread + */ + ret = swReactorThread_start(serv, main_reactor); + if (ret < 0) + { + swWarn("ReactorThread start failed"); + return SW_ERR; + } + +#ifndef SW_USE_TIMEWHEEL + /** + * heartbeat thread + */ + if (serv->heartbeat_check_interval >= 1 && serv->heartbeat_check_interval <= serv->heartbeat_idle_time) + { + swTrace("hb timer start, time: %d live time:%d", serv->heartbeat_check_interval, serv->heartbeat_idle_time); + swHeartbeatThread_start(serv); + } +#endif + + /** + * master thread loop + */ + SwooleTG.type = SW_THREAD_MASTER; + SwooleTG.factory_target_worker = -1; + SwooleTG.factory_lock_target = 0; + SwooleTG.id = serv->reactor_num; + SwooleTG.update_time = 1; + + SwooleG.main_reactor = main_reactor; + SwooleG.pid = getpid(); + SwooleG.process_type = SW_PROCESS_MASTER; + + /** + * set a special id + */ + main_reactor->id = serv->reactor_num; + main_reactor->ptr = serv; + main_reactor->setHandle(main_reactor, SW_FD_LISTEN, swServer_master_onAccept); + + if (serv->hooks[SW_SERVER_HOOK_MASTER_START]) + { + swServer_call_hook(serv, SW_SERVER_HOOK_MASTER_START, serv); + } + + /** + * init timer + */ + if (swTimer_init(1000) < 0) + { + return SW_ERR; + } + /** + * 1 second timer, update serv->gs->now + */ + if (SwooleG.timer.add(&SwooleG.timer, 1000, 1, serv, swServer_master_onTimer) == NULL) + { + return SW_ERR; + } + + if (serv->onStart != NULL) + { + serv->onStart(serv); + } + + return main_reactor->wait(main_reactor, NULL); +} + +void swServer_store_listen_socket(swServer *serv) +{ + swListenPort *ls; + int sockfd; + LL_FOREACH(serv->listen_list, ls) + { + sockfd = ls->sock; + //save server socket to connection_list + serv->connection_list[sockfd].fd = sockfd; + //socket type + serv->connection_list[sockfd].socket_type = ls->type; + //save listen_host object + serv->connection_list[sockfd].object = ls; + + if (swSocket_is_dgram(ls->type)) + { + if (ls->type == SW_SOCK_UDP) + { + serv->connection_list[sockfd].info.addr.inet_v4.sin_port = htons(ls->port); + } + else if (ls->type == SW_SOCK_UDP6) + { + SwooleG.serv->udp_socket_ipv6 = sockfd; + serv->connection_list[sockfd].info.addr.inet_v6.sin6_port = htons(ls->port); + } + } + else + { + //IPv4 + if (ls->type == SW_SOCK_TCP) + { + serv->connection_list[sockfd].info.addr.inet_v4.sin_port = htons(ls->port); + } + //IPv6 + else if (ls->type == SW_SOCK_TCP6) + { + serv->connection_list[sockfd].info.addr.inet_v6.sin6_port = htons(ls->port); + } + } + if (sockfd >= 0) + { + swServer_set_minfd(serv, sockfd); + swServer_set_maxfd(serv, sockfd); + } + } +} + +swString** swServer_create_worker_buffer(swServer *serv) +{ + int i; + int buffer_num; + + if (serv->factory_mode == SW_MODE_SINGLE) + { + buffer_num = 1; + } + else + { + buffer_num = serv->reactor_num + serv->dgram_port_num; + } + + swString **buffers = sw_malloc(sizeof(swString*) * buffer_num); + if (buffers == NULL) + { + swError("malloc for worker buffer_input failed."); + return NULL; + } + + for (i = 0; i < buffer_num; i++) + { + buffers[i] = swString_new(SW_BUFFER_SIZE_BIG); + if (buffers[i] == NULL) + { + swError("worker buffer_input init failed."); + return NULL; + } + } + + return buffers; +} + +int swServer_create_task_worker(swServer *serv) +{ + key_t key = 0; + int ipc_mode; + + if (serv->task_ipc_mode == SW_TASK_IPC_MSGQUEUE || serv->task_ipc_mode == SW_TASK_IPC_PREEMPTIVE) + { + key = serv->message_queue_key; + ipc_mode = SW_IPC_MSGQUEUE; + } + else if (serv->task_ipc_mode == SW_TASK_IPC_STREAM) + { + ipc_mode = SW_IPC_SOCKET; + } + else + { + ipc_mode = SW_IPC_UNIXSOCK; + } + + if (swProcessPool_create(&serv->gs->task_workers, serv->task_worker_num, serv->task_max_request, key, ipc_mode) < 0) + { + swWarn("[Master] create task_workers failed."); + return SW_ERR; + } + if (ipc_mode == SW_IPC_SOCKET) + { + char sockfile[sizeof(struct sockaddr_un)]; + snprintf(sockfile, sizeof(sockfile), "/tmp/swoole.task.%d.sock", serv->gs->master_pid); + if (swProcessPool_create_unix_socket(&serv->gs->task_workers, sockfile, 2048) < 0) + { + return SW_ERR; + } + } + return SW_OK; +} + +int swServer_worker_init(swServer *serv, swWorker *worker) +{ +#ifdef HAVE_CPU_AFFINITY + if (serv->open_cpu_affinity) + { + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + if (serv->cpu_affinity_available_num) + { + CPU_SET(serv->cpu_affinity_available[SwooleWG.id % serv->cpu_affinity_available_num], &cpu_set); + } + else + { + CPU_SET(SwooleWG.id % SW_CPU_NUM, &cpu_set); + } +#ifdef __FreeBSD__ + if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, + sizeof(cpu_set), &cpu_set) < 0) +#else + if (sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set) < 0) +#endif + { + swSysError("sched_setaffinity() failed."); + } + } +#endif + + //signal init + swWorker_signal_init(); + + SwooleWG.buffer_input = swServer_create_worker_buffer(serv); + if (!SwooleWG.buffer_input) + { + return SW_ERR; + } + + if (serv->max_request < 1) + { + SwooleWG.run_always = 1; + } + else + { + SwooleWG.max_request = serv->max_request; + if (SwooleWG.max_request > 10) + { + int n = swoole_system_random(1, SwooleWG.max_request / 2); + if (n > 0) + { + SwooleWG.max_request += n; + } + } + } + + worker->start_time = serv->gs->now; + worker->request_time = 0; + worker->request_count = 0; + + return SW_OK; +} + +void swServer_reopen_log_file(swServer *serv) +{ + if (!SwooleG.log_file) + { + return; + } + /** + * reopen log file + */ + close(SwooleG.log_fd); + swLog_init(SwooleG.log_file); + /** + * redirect STDOUT & STDERR to log file + */ + if (serv->daemonize) + { + swoole_redirect_stdout(SwooleG.log_fd); + } +} + +int swServer_start(swServer *serv) +{ + swFactory *factory = &serv->factory; + int ret; + + ret = swServer_start_check(serv); + if (ret < 0) + { + return SW_ERR; + } + if (SwooleG.hooks[SW_GLOBAL_HOOK_BEFORE_SERVER_START]) + { + swoole_call_hook(SW_GLOBAL_HOOK_BEFORE_SERVER_START, serv); + } + //cann't start 2 servers at the same time, please use process->exec. + if (!sw_atomic_cmp_set(&serv->gs->start, 0, 1)) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SERVER_ONLY_START_ONE, "must only start one server."); + return SW_ERR; + } + //init loggger + if (SwooleG.log_file) + { + swLog_init(SwooleG.log_file); + } + //run as daemon + if (serv->daemonize > 0) + { + /** + * redirect STDOUT to log file + */ + if (SwooleG.log_fd > STDOUT_FILENO) + { + swoole_redirect_stdout(SwooleG.log_fd); + } + /** + * redirect STDOUT_FILENO/STDERR_FILENO to /dev/null + */ + else + { + SwooleG.null_fd = open("/dev/null", O_WRONLY); + if (SwooleG.null_fd > 0) + { + swoole_redirect_stdout(SwooleG.null_fd); + } + else + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "open(/dev/null) failed. Error: %s[%d]", strerror(errno), errno); + } + } + + if (daemon(0, 1) < 0) + { + return SW_ERR; + } + } + + //master pid + serv->gs->master_pid = getpid(); + serv->gs->now = serv->stats->start_time = time(NULL); + + if (serv->dispatch_mode == SW_DISPATCH_STREAM) + { + serv->stream_socket = swoole_string_format(64, "/tmp/swoole.%d.sock", serv->gs->master_pid); + if (serv->stream_socket == NULL) + { + return SW_ERR; + } + int _reuse_port = SwooleG.reuse_port; + SwooleG.reuse_port = 0; + serv->stream_fd = swSocket_create_server(SW_SOCK_UNIX_STREAM, serv->stream_socket, 0, 2048); + if (serv->stream_fd < 0) + { + return SW_ERR; + } + swoole_fcntl_set_option(serv->stream_fd, 1, 1); + SwooleG.reuse_port = _reuse_port; + } + + serv->send = swServer_tcp_send; + serv->sendwait = swServer_tcp_sendwait; + serv->sendfile = swServer_tcp_sendfile; + serv->close = swServer_tcp_close; + + serv->workers = SwooleG.memory_pool->alloc(SwooleG.memory_pool, serv->worker_num * sizeof(swWorker)); + if (serv->workers == NULL) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "gmalloc[server->workers] failed."); + return SW_ERR; + } + + /** + * store to swProcessPool object + */ + serv->gs->event_workers.workers = serv->workers; + serv->gs->event_workers.worker_num = serv->worker_num; + serv->gs->event_workers.use_msgqueue = 0; + + int i; + for (i = 0; i < serv->worker_num; i++) + { + serv->gs->event_workers.workers[i].pool = &serv->gs->event_workers; + } + +#ifdef SW_USE_RINGBUFFER + for (i = 0; i < serv->reactor_num; i++) + { + serv->reactor_threads[i].buffer_input = swRingBuffer_new(SwooleG.serv->buffer_input_size, 1); + if (!serv->reactor_threads[i].buffer_input) + { + return SW_ERR; + } + } +#endif + + /* + * For swoole_server->taskwait, create notify pipe and result shared memory. + */ + if (serv->task_worker_num > 0 && serv->worker_num > 0) + { + serv->task_result = sw_shm_calloc(serv->worker_num, sizeof(swEventData)); + serv->task_notify = sw_calloc(serv->worker_num, sizeof(swPipe)); + for (i = 0; i < serv->worker_num; i++) + { + if (swPipeNotify_auto(&serv->task_notify[i], 1, 0)) + { + return SW_ERR; + } + } + } + + /** + * user worker process + */ + if (serv->user_worker_list) + { + swUserWorker_node *user_worker; + i = 0; + LL_FOREACH(serv->user_worker_list, user_worker) + { + user_worker->worker->id = serv->worker_num + serv->task_worker_num + i; + i++; + } + } + + //factory start + if (factory->start(factory) < 0) + { + return SW_ERR; + } + //signal Init + swServer_signal_init(serv); + + //write PID file + if (serv->pid_file) + { + ret = snprintf(SwooleTG.buffer_stack->str, SwooleTG.buffer_stack->size, "%d", getpid()); + swoole_file_put_contents(serv->pid_file, SwooleTG.buffer_stack->str, ret); + } + if (serv->factory_mode == SW_MODE_SINGLE) + { + ret = swReactorProcess_start(serv); + } + else + { + ret = swServer_start_proxy(serv); + } + swServer_free(serv); + serv->gs->start = 0; + //remove PID file + if (serv->pid_file) + { + unlink(serv->pid_file); + } + return SW_OK; +} + +/** + * initializing server config, set default + */ +void swServer_init(swServer *serv) +{ + swoole_init(); + bzero(serv, sizeof(swServer)); + + serv->factory_mode = SW_MODE_BASE; + + serv->reactor_num = SW_REACTOR_NUM > SW_REACTOR_MAX_THREAD ? SW_REACTOR_MAX_THREAD : SW_REACTOR_NUM; + + serv->dispatch_mode = SW_DISPATCH_FDMOD; + + serv->worker_num = SW_CPU_NUM; + serv->max_connection = SwooleG.max_sockets < SW_SESSION_LIST_SIZE ? SwooleG.max_sockets : SW_SESSION_LIST_SIZE; + + serv->max_request = 0; + serv->max_wait_time = SW_WORKER_MAX_WAIT_TIME; + + //http server + serv->http_parse_post = 1; + serv->upload_tmp_dir = sw_strdup("/tmp"); + + //heartbeat check + serv->heartbeat_idle_time = SW_HEARTBEAT_IDLE; + serv->heartbeat_check_interval = SW_HEARTBEAT_CHECK; + + serv->buffer_input_size = SW_BUFFER_INPUT_SIZE; + serv->buffer_output_size = SW_BUFFER_OUTPUT_SIZE; + + serv->task_ipc_mode = SW_TASK_IPC_UNIXSOCK; + + /** + * alloc shared memory + */ + serv->stats = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerStats)); + if (serv->stats == NULL) + { + swError("[Master] Fatal Error: failed to allocate memory for swServer->stats."); + } + serv->gs = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swServerGS)); + if (serv->gs == NULL) + { + swError("[Master] Fatal Error: failed to allocate memory for swServer->gs."); + } + + SwooleG.serv = serv; +} + +int swServer_create(swServer *serv) +{ + if (SwooleG.main_reactor) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT, "The swoole_server must create before client"); + return SW_ERR; + } + + SwooleG.factory = &serv->factory; + serv->factory.ptr = serv; + /** + * init current time + */ + swServer_update_time(serv); + +#ifdef SW_REACTOR_USE_SESSION + serv->session_list = sw_shm_calloc(SW_SESSION_LIST_SIZE, sizeof(swSession)); + if (serv->session_list == NULL) + { + swError("sw_shm_calloc(%ld) for session_list failed", SW_SESSION_LIST_SIZE * sizeof(swSession)); + return SW_ERR; + } +#endif + + if (serv->factory_mode == SW_MODE_SINGLE) + { + return swReactorProcess_create(serv); + } + else + { + return swReactorThread_create(serv); + } +} + +int swServer_shutdown(swServer *serv) +{ + //stop all thread + SwooleG.main_reactor->running = 0; + return SW_OK; +} + +int swServer_free(swServer *serv) +{ + swTraceLog(SW_TRACE_SERVER, "release service."); + + /** + * shutdown workers + */ + if (serv->factory.shutdown != NULL) + { + serv->factory.shutdown(&(serv->factory)); + } + /** + * Shutdown heartbeat thread + */ + if (serv->heartbeat_pidt) + { + swTraceLog(SW_TRACE_SERVER, "terminate heartbeat thread."); + if (pthread_cancel(serv->heartbeat_pidt) < 0) + { + swSysError("pthread_cancel(%ld) failed.", (ulong_t )serv->heartbeat_pidt); + } + //wait thread + if (pthread_join(serv->heartbeat_pidt, NULL) < 0) + { + swSysError("pthread_join(%ld) failed.", (ulong_t )serv->heartbeat_pidt); + } + } + if (serv->factory_mode == SW_MODE_SINGLE) + { + swTraceLog(SW_TRACE_SERVER, "terminate task workers."); + if (serv->task_worker_num > 0) + { + swProcessPool_shutdown(&serv->gs->task_workers); + } + } + else + { + swTraceLog(SW_TRACE_SERVER, "terminate reactor threads."); + /** + * Wait until all the end of the thread + */ + swReactorThread_free(serv); + } + + swListenPort *port; + LL_FOREACH(serv->listen_list, port) + { + swPort_free(port); + } + //reactor free + if (serv->reactor.free != NULL) + { + serv->reactor.free(&(serv->reactor)); + } + //close log file + if (SwooleG.log_file != 0) + { + swLog_free(); + } + if (SwooleG.null_fd > 0) + { + close(SwooleG.null_fd); + } + if (serv->stream_socket) + { + unlink(serv->stream_socket); + sw_free(serv->stream_socket); + } + if (serv->gs->start > 0 && serv->onShutdown != NULL) + { + serv->onShutdown(serv); + } + return SW_OK; +} + +int swServer_udp_send(swServer *serv, swSendData *resp) +{ + struct sockaddr_in addr_in; + int sock = resp->info.from_fd; + + addr_in.sin_family = AF_INET; + addr_in.sin_port = htons((uint16_t) resp->info.from_id); //from_id is remote port + addr_in.sin_addr.s_addr = (uint32_t) resp->info.fd; //fd is remote ip address + + int ret = swSocket_sendto_blocking(sock, resp->data, resp->info.len, 0, (struct sockaddr*) &addr_in, sizeof(addr_in)); + if (ret < 0) + { + swWarn("sendto to client[%s:%d] failed. Error: %s [%d]", inet_ntoa(addr_in.sin_addr), resp->info.from_id, + strerror(errno), errno); + } + return ret; +} + +/** + * worker to master process + */ +int swServer_tcp_feedback(swServer *serv, int fd, int event) +{ + swConnection *conn = swServer_connection_verify(serv, fd); + if (!conn) + { + return SW_ERR; + } + + if (event == SW_EVENT_CONFIRM && !conn->listen_wait) + { + return SW_ERR; + } + + swSendData _send; + bzero(&_send, sizeof(_send)); + _send.info.type = event; + _send.info.fd = fd; + _send.info.from_id = conn->from_id; + + if (serv->factory_mode == SW_MODE_PROCESS) + { + return swWorker_send2reactor((swEventData *) &_send.info, sizeof(_send.info), fd); + } + else + { + return swReactorThread_send(&_send); + } +} + +void swServer_store_pipe_fd(swServer *serv, swPipe *p) +{ + int master_fd = p->getFd(p, SW_PIPE_MASTER); + + serv->connection_list[p->getFd(p, SW_PIPE_WORKER)].object = p; + serv->connection_list[master_fd].object = p; + + if (master_fd > swServer_get_minfd(serv)) + { + swServer_set_minfd(serv, master_fd); + } +} + +void swServer_close_listen_port(swServer *serv) +{ + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (swSocket_is_stream(ls->type)) + { + close(ls->sock); + } + } +} + +swPipe * swServer_get_pipe_object(swServer *serv, int pipe_fd) +{ + return (swPipe *) serv->connection_list[pipe_fd].object; +} + +int swServer_tcp_send(swServer *serv, int fd, void *data, uint32_t length) +{ + swSendData _send; + swFactory *factory = &(serv->factory); + /** + * More than the output buffer + */ + if (length > serv->buffer_output_size) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_DATA_LENGTH_TOO_LARGE, "More than the output buffer size[%d], please use the sendfile.", serv->buffer_output_size); + return SW_ERR; + } + else + { + if (fd == serv->last_session_id && serv->last_stream_fd > 0) + { + int _l = htonl(length); + if (SwooleG.main_reactor->write(SwooleG.main_reactor, serv->last_stream_fd, (void *) &_l, sizeof(_l)) < 0) + { + return SW_ERR; + } + if (SwooleG.main_reactor->write(SwooleG.main_reactor, serv->last_stream_fd, data, length) < 0) + { + return SW_ERR; + } + return SW_OK; + } + + _send.info.fd = fd; + _send.info.type = SW_EVENT_TCP; + _send.data = data; + + if (length >= SW_IPC_MAX_SIZE - sizeof(swDataHead)) + { + _send.length = length; + } + else + { + _send.info.len = length; + _send.length = 0; + } + return factory->finish(factory, &_send); + } + return SW_OK; +} + +/** + * use in master process + */ +int swServer_tcp_notify(swServer *serv, swConnection *conn, int event) +{ + swDataHead notify_event; + notify_event.type = event; + notify_event.from_id = conn->from_id; + notify_event.fd = conn->fd; + notify_event.from_fd = conn->from_fd; + notify_event.len = 0; + return serv->factory.notify(&serv->factory, &notify_event); +} + +int swServer_tcp_sendfile(swServer *serv, int session_id, char *filename, uint32_t filename_length, off_t offset, size_t length) +{ + if (session_id <= 0 || session_id > SW_MAX_SOCKET_ID) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SESSION_INVALID_ID, "invalid fd[%d].", session_id); + return SW_ERR; + } + + struct stat file_stat; + if (stat(filename, &file_stat) < 0) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SYSTEM_CALL_FAIL, "stat(%s) failed.", filename); + return SW_ERR; + } + if (file_stat.st_size <= offset) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SYSTEM_CALL_FAIL, "file[offset=%ld] is empty.", (long)offset); + return SW_ERR; + } + + swSendData send_data; + char _buffer[SW_BUFFER_SIZE]; + swSendFile_request *req = (swSendFile_request*) _buffer; + + //file name size + if (filename_length > SW_BUFFER_SIZE - sizeof(swSendFile_request) - 1) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_NAME_TOO_LONG, "sendfile name too long. [MAX_LENGTH=%d]", + (int) (SW_BUFFER_SIZE - sizeof(swSendFile_request) - 1)); + return SW_ERR; + } + + req->offset = offset; + req->length = length; + strncpy(req->filename, filename, filename_length); + req->filename[filename_length] = 0; + + send_data.info.fd = session_id; + send_data.info.type = SW_EVENT_SENDFILE; + send_data.info.len = sizeof(swSendFile_request) + filename_length + 1; + send_data.length = 0; + send_data.data = _buffer; + + return serv->factory.finish(&serv->factory, &send_data); +} + +int swServer_tcp_sendwait(swServer *serv, int fd, void *data, uint32_t length) +{ + swConnection *conn = swServer_connection_verify(serv, fd); + if (!conn) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "send %d byte failed, because session#%d is closed.", length, fd); + return SW_ERR; + } + return swSocket_write_blocking(conn->fd, data, length); +} + +SW_API void swServer_call_hook(swServer *serv, enum swServer_hook_type type, void *arg) +{ + swLinkedList *hooks = serv->hooks[type]; + swLinkedList_node *node = hooks->head; + swCallback func = NULL; + + while (node) + { + func = node->data; + func(arg); + node = node->next; + } +} + +int swServer_tcp_close(swServer *serv, int fd, int reset) +{ + swConnection *conn = swServer_connection_verify_no_ssl(serv, fd); + if (!conn) + { + return SW_ERR; + } + //Reset send buffer, Immediately close the connection. + if (reset) + { + conn->close_reset = 1; + } + //server is initiative to close the connection + conn->close_actively = 1; + swTraceLog(SW_TRACE_CLOSE, "session_id=%d, fd=%d.", fd, conn->fd); + + int ret; + if (!swIsWorker()) + { + swWorker *worker = swServer_get_worker(serv, conn->fd % serv->worker_num); + swDataHead ev; + ev.type = SW_EVENT_CLOSE; + ev.fd = fd; + ev.from_id = conn->from_id; + ret = swWorker_send2worker(worker, &ev, sizeof(ev), SW_PIPE_MASTER); + } + else + { + ret = serv->factory.end(&serv->factory, fd); + } + return ret; +} + +void swServer_signal_init(swServer *serv) +{ + swSignal_add(SIGPIPE, NULL); + swSignal_add(SIGHUP, NULL); + if (serv->factory_mode != SW_MODE_BASE) + { + swSignal_add(SIGCHLD, swServer_signal_hanlder); + } + swSignal_add(SIGUSR1, swServer_signal_hanlder); + swSignal_add(SIGUSR2, swServer_signal_hanlder); + swSignal_add(SIGTERM, swServer_signal_hanlder); +#ifdef SIGRTMIN + swSignal_add(SIGRTMIN, swServer_signal_hanlder); +#endif + swSignal_add(SIGALRM, swSystemTimer_signal_handler); + //for test + swSignal_add(SIGVTALRM, swServer_signal_hanlder); + swServer_set_minfd(SwooleG.serv, SwooleG.signal_fd); +} + +void swServer_master_onTimer(swTimer *timer, swTimer_node *tnode) +{ + swServer *serv = (swServer *) tnode->data; + swServer_update_time(serv); + if (serv->scheduler_warning && serv->warning_time < serv->gs->now) + { + serv->scheduler_warning = 0; + serv->warning_time = serv->gs->now; + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SERVER_NO_IDLE_WORKER, "No idle worker is available."); + } + + if (serv->hooks[SW_SERVER_HOOK_MASTER_TIMER]) + { + swServer_call_hook(serv, SW_SERVER_HOOK_MASTER_TIMER, serv); + } +} + +int swServer_add_worker(swServer *serv, swWorker *worker) +{ + swUserWorker_node *user_worker = sw_malloc(sizeof(swUserWorker_node)); + if (!user_worker) + { + return SW_ERR; + } + + serv->user_worker_num++; + user_worker->worker = worker; + + LL_APPEND(serv->user_worker_list, user_worker); + if (!serv->user_worker_map) + { + serv->user_worker_map = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + } + + return worker->id; +} + +void swServer_update_time(swServer *serv) +{ + time_t now = time(NULL); + if (now < 0) + { + swWarn("get time failed. Error: %s[%d]", strerror(errno), errno); + } + else + { + serv->gs->now = now; + } +} + +SW_API int swServer_add_hook(swServer *serv, enum swServer_hook_type type, swCallback func, int push_back) +{ + if (serv->hooks[type] == NULL) + { + serv->hooks[type] = swLinkedList_new(0, NULL); + if (serv->hooks[type] == NULL) + { + return SW_ERR; + } + } + if (push_back) + { + return swLinkedList_append(serv->hooks[type], func); + } + else + { + return swLinkedList_prepend(serv->hooks[type], func); + } +} + +/** + * Return the number of ports successfully + */ +int swserver_add_systemd_socket(swServer *serv) +{ + char *e = getenv("LISTEN_PID"); + if (!e) + { + return 0; + } + + int pid = atoi(e); + if (getpid() != pid) + { + swWarn("invalid LISTEN_PID."); + return 0; + } + + e = getenv("LISTEN_FDS"); + if (!e) + { + return 0; + } + int n = atoi(e); + if (n < 1) + { + swWarn("invalid LISTEN_FDS."); + return 0; + } + else if (n >= SW_MAX_LISTEN_PORT) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SERVER_TOO_MANY_LISTEN_PORT, "LISTEN_FDS is too big."); + return 0; + } + + int count = 0; + int sock, val; + socklen_t optlen; + swSocketAddress address; + int sock_type, sock_family; + char tmp[INET6_ADDRSTRLEN]; + + for (sock = SW_SYSTEMD_FDS_START; sock < SW_SYSTEMD_FDS_START + n; sock++) + { + swListenPort *ls = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swListenPort)); + if (ls == NULL) + { + swWarn("alloc failed."); + return count; + } + //get socket type + optlen = sizeof(val); + if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &val, &optlen) < 0) + { + swWarn("getsockopt(%d, SOL_SOCKET, SO_TYPE) failed.", sock); + return count; + } + sock_type = val; + //get socket family +#ifndef SO_DOMAIN + swWarn("no getsockopt(SO_DOMAIN) supports."); + return count; +#else + optlen = sizeof(val); + if (getsockopt(sock, SOL_SOCKET, SO_DOMAIN, &val, &optlen) < 0) + { + swWarn("getsockopt(%d, SOL_SOCKET, SO_DOMAIN) failed.", sock); + return count; + } +#endif + sock_family = val; + //get address info + address.len = sizeof(address.addr); + if (getsockname(sock, (struct sockaddr*) &address.addr, &address.len) < 0) + { + swWarn("getsockname(%d) failed.", sock); + return count; + } + + swPort_init(ls); + bzero(ls->host, SW_HOST_MAXSIZE); + + switch (sock_family) + { + case AF_INET: + if (sock_type == SOCK_STREAM) + { + ls->type = SW_SOCK_TCP; + ls->port = ntohs(address.addr.inet_v4.sin_port); + strncpy(ls->host, inet_ntoa(address.addr.inet_v4.sin_addr), SW_HOST_MAXSIZE - 1); + } + else + { + ls->type = SW_SOCK_UDP; + ls->port = ntohs(address.addr.inet_v4.sin_port); + strncpy(ls->host, inet_ntoa(address.addr.inet_v4.sin_addr), SW_HOST_MAXSIZE - 1); + } + break; + case AF_INET6: + if (sock_type == SOCK_STREAM) + { + ls->port = ntohs(address.addr.inet_v6.sin6_port); + ls->type = SW_SOCK_TCP6; + inet_ntop(AF_INET6, &address.addr.inet_v6.sin6_addr, tmp, sizeof(tmp)); + strncpy(ls->host, tmp, SW_HOST_MAXSIZE - 1); + } + else + { + ls->port = ntohs(address.addr.inet_v6.sin6_port); + ls->type = SW_SOCK_UDP6; + inet_ntop(AF_INET6, &address.addr.inet_v6.sin6_addr, tmp, sizeof(tmp)); + strncpy(ls->host, tmp, SW_HOST_MAXSIZE - 1); + } + break; + case AF_UNIX: + ls->type = sock_type == SOCK_STREAM ? SW_SOCK_UNIX_STREAM : SW_SOCK_UNIX_DGRAM; + ls->port = 0; + strncpy(ls->host, address.addr.un.sun_path, SW_HOST_MAXSIZE - 1); + break; + default: + swWarn("Unknown socket type[%d].", sock_type); + break; + } + + //dgram socket, setting socket buffer size + if (swSocket_is_dgram(ls->type)) + { + setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &ls->socket_buffer_size, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &ls->socket_buffer_size, sizeof(int)); + } + //O_NONBLOCK & O_CLOEXEC + swoole_fcntl_set_option(sock, 1, 1); + ls->sock = sock; + + if (swSocket_is_dgram(ls->type)) + { + serv->have_udp_sock = 1; + serv->dgram_port_num++; + if (ls->type == SW_SOCK_UDP) + { + serv->udp_socket_ipv4 = sock; + } + else if (ls->type == SW_SOCK_UDP6) + { + serv->udp_socket_ipv6 = sock; + } + } + else + { + serv->have_tcp_sock = 1; + } + + LL_APPEND(serv->listen_list, ls); + serv->listen_port_num++; + count++; + } + return count; +} + +swListenPort* swServer_add_port(swServer *serv, int type, char *host, int port) +{ + if (serv->listen_port_num >= SW_MAX_LISTEN_PORT) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SERVER_TOO_MANY_LISTEN_PORT, "allows up to %d ports to listen", SW_MAX_LISTEN_PORT); + return NULL; + } + if (!(type == SW_SOCK_UNIX_DGRAM || type == SW_SOCK_UNIX_STREAM) && (port < 0 || port > 65535)) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SERVER_INVALID_LISTEN_PORT, "invalid port [%d]", port); + return NULL; + } + if (strlen(host) + 1 > SW_HOST_MAXSIZE) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_NAME_TOO_LONG, "address '%s' exceeds %d characters limit", host, SW_HOST_MAXSIZE - 1); + return NULL; + } + + swListenPort *ls = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swListenPort)); + if (ls == NULL) + { + swError("alloc failed"); + return NULL; + } + + swPort_init(ls); + ls->type = type; + ls->port = port; + strncpy(ls->host, host, strlen(host) + 1); + + if (type & SW_SOCK_SSL) + { + type = type & (~SW_SOCK_SSL); + if (swSocket_is_stream(type)) + { + ls->type = type; + ls->ssl = 1; +#ifdef SW_USE_OPENSSL + ls->ssl_config.prefer_server_ciphers = 1; + ls->ssl_config.session_tickets = 0; + ls->ssl_config.stapling = 1; + ls->ssl_config.stapling_verify = 1; + ls->ssl_config.ciphers = sw_strdup(SW_SSL_CIPHER_LIST); + ls->ssl_config.ecdh_curve = sw_strdup(SW_SSL_ECDH_CURVE); +#endif + } + } + + //create server socket + int sock = swSocket_create(ls->type); + if (sock < 0) + { + swSysError("create socket failed."); + return NULL; + } + //bind address and port + if (swSocket_bind(sock, ls->type, ls->host, &ls->port) < 0) + { + close(sock); + return NULL; + } + //dgram socket, setting socket buffer size + if (swSocket_is_dgram(ls->type)) + { + setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &ls->socket_buffer_size, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &ls->socket_buffer_size, sizeof(int)); + } + //O_NONBLOCK & O_CLOEXEC + swoole_fcntl_set_option(sock, 1, 1); + ls->sock = sock; + + if (swSocket_is_dgram(ls->type)) + { + serv->have_udp_sock = 1; + serv->dgram_port_num++; + if (ls->type == SW_SOCK_UDP) + { + serv->udp_socket_ipv4 = sock; + } + else if (ls->type == SW_SOCK_UDP6) + { + serv->udp_socket_ipv6 = sock; + } + } + else + { + serv->have_tcp_sock = 1; + } + + LL_APPEND(serv->listen_list, ls); + serv->listen_port_num++; + return ls; +} + +int swServer_get_manager_pid(swServer *serv) +{ + if (SW_MODE_PROCESS != serv->factory_mode) + { + return SW_ERR; + } + return serv->gs->manager_pid; +} + +int swServer_get_socket(swServer *serv, int port) +{ + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + if (ls->port == port || port == 0) + { + return ls->sock; + } + } + return SW_ERR; +} + +static void swServer_signal_hanlder(int sig) +{ + swTraceLog(SW_TRACE_SERVER, "signal[%d] triggered.", sig); + + swServer *serv = SwooleG.serv; + int status; + pid_t pid; + switch (sig) + { + case SIGTERM: + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->running = 0; + } + else + { + SwooleG.running = 0; + } + swNotice("Server is shutdown now."); + break; + case SIGALRM: + swSystemTimer_signal_handler(SIGALRM); + break; + case SIGCHLD: + if (!SwooleG.running) + { + break; + } + if (SwooleG.serv->factory_mode == SW_MODE_SINGLE) + { + break; + } + pid = waitpid(-1, &status, WNOHANG); + if (pid > 0 && pid == serv->gs->manager_pid) + { + swWarn("Fatal Error: manager process exit. status=%d, signal=%d.", WEXITSTATUS(status), WTERMSIG(status)); + } + break; + /** + * for test + */ + case SIGVTALRM: + swWarn("SIGVTALRM coming"); + break; + /** + * proxy the restart signal + */ + case SIGUSR1: + case SIGUSR2: + if (SwooleG.serv->factory_mode == SW_MODE_SINGLE) + { + if (serv->gs->event_workers.reloading) + { + break; + } + serv->gs->event_workers.reloading = 1; + serv->gs->event_workers.reload_init = 0; + } + else + { + kill(serv->gs->manager_pid, sig); + } + break; + default: +#ifdef SIGRTMIN + if (sig == SIGRTMIN) + { + int i; + swWorker *worker; + for (i = 0; i < SwooleG.serv->worker_num + serv->task_worker_num + SwooleG.serv->user_worker_num; i++) + { + worker = swServer_get_worker(SwooleG.serv, i); + kill(worker->pid, SIGRTMIN); + } + if (SwooleG.serv->factory_mode == SW_MODE_PROCESS) + { + kill(serv->gs->manager_pid, SIGRTMIN); + } + swServer_reopen_log_file(SwooleG.serv); + } +#endif + break; + } +} + +#ifndef SW_USE_TIMEWHEEL +static void swHeartbeatThread_start(swServer *serv) +{ + swThreadParam *param; + pthread_t thread_id; + param = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swThreadParam)); + if (param == NULL) + { + swError("heartbeat_param malloc fail\n"); + return; + } + + param->object = serv; + param->pti = 0; + + if (pthread_create(&thread_id, NULL, (void * (*)(void *)) swHeartbeatThread_loop, (void *) param) < 0) + { + swWarn("pthread_create[hbcheck] fail"); + } + serv->heartbeat_pidt = thread_id; +} + +static void swHeartbeatThread_loop(swThreadParam *param) +{ + swSignal_none(); + + swServer *serv = param->object; + swConnection *conn; + swReactor *reactor; + + int fd; + int serv_max_fd; + int serv_min_fd; + int checktime; + + SwooleTG.type = SW_THREAD_HEARTBEAT; + SwooleTG.id = serv->reactor_num; + + while (SwooleG.running) + { + serv_max_fd = swServer_get_maxfd(serv); + serv_min_fd = swServer_get_minfd(serv); + + checktime = (int) time(NULL) - serv->heartbeat_idle_time; + + for (fd = serv_min_fd; fd <= serv_max_fd; fd++) + { + swTrace("check fd=%d", fd); + conn = swServer_connection_get(serv, fd); + + if (conn != NULL && conn->active == 1 && conn->closed == 0 && conn->fdtype == SW_FD_TCP) + { + if (conn->protect || conn->last_time > checktime) + { + continue; + } + + conn->close_force = 1; + conn->close_notify = 1; + + if (serv->factory_mode != SW_MODE_PROCESS) + { + if (serv->factory_mode == SW_MODE_SINGLE) + { + reactor = SwooleG.main_reactor; + } + else + { + reactor = &serv->reactor_threads[conn->from_id].reactor; + } + } + else + { + reactor = &serv->reactor_threads[conn->from_id].reactor; + } + //notify to reactor thread + if (conn->removed) + { + swServer_tcp_notify(serv, conn, SW_EVENT_CLOSE); + } + else + { + reactor->set(reactor, fd, SW_FD_TCP | SW_EVENT_WRITE); + } + } + } + sleep(serv->heartbeat_check_interval); + } + pthread_exit(0); +} +#endif + +/** + * new connection + */ +static swConnection* swServer_connection_new(swServer *serv, swListenPort *ls, int fd, int from_fd, int reactor_id) +{ + swConnection* connection = NULL; + + serv->stats->accept_count++; + sw_atomic_fetch_add(&serv->stats->connection_num, 1); + sw_atomic_fetch_add(&ls->connection_num, 1); + + if (fd > swServer_get_maxfd(serv)) + { + swServer_set_maxfd(serv, fd); + } + + connection = &(serv->connection_list[fd]); + bzero(connection, sizeof(swConnection)); + + //TCP Nodelay + if (ls->open_tcp_nodelay) + { + int sockopt = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &sockopt, sizeof(sockopt)) < 0) + { + swSysError("setsockopt(TCP_NODELAY) failed."); + } + connection->tcp_nodelay = 1; + } + + //socket recv buffer size + if (ls->kernel_socket_recv_buffer_size > 0) + { + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &ls->kernel_socket_recv_buffer_size, sizeof(int))) + { + swSysError("setsockopt(SO_RCVBUF, %d) failed.", ls->kernel_socket_recv_buffer_size); + } + } + + //socket send buffer size + if (ls->kernel_socket_send_buffer_size > 0) + { + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &ls->kernel_socket_send_buffer_size, sizeof(int)) < 0) + { + swSysError("setsockopt(SO_SNDBUF, %d) failed.", ls->kernel_socket_send_buffer_size); + } + } + + connection->fd = fd; + connection->from_id = serv->factory_mode == SW_MODE_SINGLE ? SwooleWG.id : reactor_id; + connection->from_fd = (sw_atomic_t) from_fd; + connection->connect_time = serv->gs->now; + connection->last_time = serv->gs->now; + connection->active = 1; + connection->buffer_size = ls->socket_buffer_size; + +#ifdef SW_REACTOR_SYNC_SEND + if (serv->factory_mode != SW_MODE_THREAD && !ls->ssl) + { + connection->direct_send = 1; + } +#endif + +#ifdef SW_REACTOR_USE_SESSION + swSession *session; + sw_spinlock(&serv->gs->spinlock); + int i; + uint32_t session_id = serv->gs->session_round; + //get session id + for (i = 0; i < serv->max_connection; i++) + { + session_id++; + //SwooleGS->session_round just has 24 bits size; + if (unlikely(session_id == 1 << 24)) + { + session_id = 1; + } + session = swServer_get_session(serv, session_id); + //vacancy + if (session->fd == 0) + { + session->fd = fd; + session->id = session_id; + session->reactor_id = connection->from_id; + break; + } + } + serv->gs->session_round = session_id; + sw_spinlock_release(&serv->gs->spinlock); + connection->session_id = session_id; +#endif + + return connection; +} + +void swServer_set_callback(swServer *serv, int type, void *callback) +{ + switch(type) + { + case SW_SERVER_CALLBACK_onConnect: + serv->onConnect = callback; + break; + case SW_SERVER_CALLBACK_onReceive: + serv->onReceive = callback; + break; + case SW_SERVER_CALLBACK_onClose: + serv->onClose = callback; + break; + default: + swError("unkown callback type."); + break; + } +} + +static void (*onConnect_callback)(swServer *, int, int); +static int (*onReceive_callback)(swServer *, char *, int, int, int); +static void (*onClose_callback)(swServer *, int, int); + +static void swServer_scalar_onConnect_callback(swServer *serv, swDataHead *info) +{ + onConnect_callback(serv, info->fd, info->from_id); +} + +static int swServer_scalar_onReceive_callback(swServer *serv, swEventData *req) +{ + return onReceive_callback(serv, req->data, req->info.len, req->info.fd, req->info.from_id); +} + +static void swServer_scalar_onClose_callback(swServer *serv, swDataHead *info) +{ + onClose_callback(serv, info->fd, info->from_id); +} + +void swServer_set_callback_onConnect(swServer *serv, void (*callback)(swServer *, int, int)) +{ + onConnect_callback = callback; + serv->onConnect = swServer_scalar_onConnect_callback; +} + +void swServer_set_callback_onReceive(swServer *serv, int (*callback)(swServer *, char *, int, int, int)) +{ + onReceive_callback = callback; + serv->onReceive = swServer_scalar_onReceive_callback; +} + +void swServer_set_callback_onClose(swServer *serv, void (*callback)(swServer *, int, int)) +{ + onClose_callback = callback; + serv->onClose = swServer_scalar_onClose_callback; +} diff --git a/vendor/swoole/src/network/Stream.c b/vendor/swoole/src/network/Stream.c new file mode 100755 index 0000000..64afaef --- /dev/null +++ b/vendor/swoole/src/network/Stream.c @@ -0,0 +1,169 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Client.h" + +static void swStream_free(swStream *stream); + +static void swStream_onConnect(swClient *cli) +{ + swStream *stream = (swStream*) cli->object; + if (stream->cancel) + { + cli->close(cli); + } + *((uint32_t *) stream->buffer->str) = ntohl(stream->buffer->length - 4); + if (cli->send(cli, stream->buffer->str, stream->buffer->length, 0) < 0) + { + cli->close(cli); + } + else + { + swString_free(stream->buffer); + stream->buffer = NULL; + } +} + +static void swStream_onError(swClient *cli) +{ + swStream_free(cli->object); +} + +static void swStream_onReceive(swClient *cli, char *data, uint32_t length) +{ + swStream *stream = (swStream*) cli->object; + if (length == 4) + { + cli->socket->close_wait = 1; + } + else + { + stream->response(stream, data + 4, length - 4); + } +} + +static void swStream_onClose(swClient *cli) +{ + swStream_free(cli->object); +} + +static void swStream_free(swStream *stream) +{ + if (stream->buffer) + { + swString_free(stream->buffer); + } + sw_free(stream); +} + +swStream* swStream_new(char *dst_host, int dst_port, int type) +{ + swStream *stream = (swStream*) sw_malloc(sizeof(swStream)); + bzero(stream, sizeof(swStream)); + + swClient *cli = &stream->client; + if (swClient_create(cli, type, 1) < 0) + { + swStream_free(stream); + return NULL; + } + + cli->onConnect = swStream_onConnect; + cli->onReceive = swStream_onReceive; + cli->onError = swStream_onError; + cli->onClose = swStream_onClose; + cli->object = stream; + + cli->open_length_check = 1; + swStream_set_protocol(&cli->protocol); + + if (cli->connect(cli, dst_host, dst_port, -1, 0) < 0) + { + swSysError("failed to connect to [%s:%d].", dst_host, dst_port); + swStream_free(stream); + return NULL; + } + else + { + return stream; + } +} + +/** + * Stream Protocol: Length(32bit/Network Byte Order) + Body + */ +void swStream_set_protocol(swProtocol *protocol) +{ + protocol->get_package_length = swProtocol_get_package_length; + protocol->package_length_size = 4; + protocol->package_length_type = 'N'; + protocol->package_body_offset = 4; + protocol->package_length_offset = 0; +} + +void swStream_set_max_length(swStream *stream, uint32_t max_length) +{ + stream->client.protocol.package_max_length = max_length; +} + +int swStream_send(swStream *stream, char *data, size_t length) +{ + if (stream->buffer == NULL) + { + stream->buffer = swString_new(swoole_size_align(length + 4, SwooleG.pagesize)); + if (stream->buffer == NULL) + { + return SW_ERR; + } + stream->buffer->length = 4; + } + if (swString_append_ptr(stream->buffer, data, length) < 0) + { + return SW_ERR; + } + return SW_OK; +} + +int swStream_recv_blocking(int fd, void *__buf, size_t __len) +{ + int tmp = 0; + int ret = swSocket_recv_blocking(fd, &tmp, sizeof(tmp), MSG_WAITALL); + + if (ret <= 0) + { + return SW_CLOSE; + } + int length = ntohl(tmp); + if (length <= 0) + { + return SW_CLOSE; + } + else if (length > __len) + { + return SW_CLOSE; + } + + ret = swSocket_recv_blocking(fd, __buf, length, MSG_WAITALL); + if (ret <= 0) + { + return SW_CLOSE; + } + else + { + return SW_READY; + } +} diff --git a/vendor/swoole/src/network/TaskWorker.c b/vendor/swoole/src/network/TaskWorker.c new file mode 100755 index 0000000..1dd54b8 --- /dev/null +++ b/vendor/swoole/src/network/TaskWorker.c @@ -0,0 +1,320 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Server.h" + +static swEventData *current_task = NULL; + +static void swTaskWorker_signal_init(void); + +void swTaskWorker_init(swProcessPool *pool) +{ + swServer *serv = SwooleG.serv; + pool->ptr = serv; + pool->onTask = swTaskWorker_onTask; + pool->onWorkerStart = swTaskWorker_onStart; + pool->onWorkerStop = swTaskWorker_onStop; + pool->type = SW_PROCESS_TASKWORKER; + pool->start_id = serv->worker_num; + pool->run_worker_num = serv->task_worker_num; + + if (serv->task_ipc_mode == SW_TASK_IPC_PREEMPTIVE) + { + pool->dispatch_mode = SW_DISPATCH_QUEUE; + } +} + +/** + * in worker process + */ +int swTaskWorker_onFinish(swReactor *reactor, swEvent *event) +{ + swServer *serv = reactor->ptr; + swEventData task; + int n; + + do + { + n = read(event->fd, &task, sizeof(task)); + } while (n < 0 && errno == EINTR); + + return serv->onFinish(serv, &task); +} + +int swTaskWorker_onTask(swProcessPool *pool, swEventData *task) +{ + int ret = SW_OK; + swServer *serv = pool->ptr; + current_task = task; + + if (task->info.type == SW_EVENT_PIPE_MESSAGE) + { + serv->onPipeMessage(serv, task); + } + else + { + ret = serv->onTask(serv, task); + } + + return ret; +} + +int swTaskWorker_large_pack(swEventData *task, void *data, int data_len) +{ + swPackage_task pkg; + bzero(&pkg, sizeof(pkg)); + + memcpy(pkg.tmpfile, SwooleG.task_tmpdir, SwooleG.task_tmpdir_len); + + //create temp file + int tmp_fd = swoole_tmpfile(pkg.tmpfile); + if (tmp_fd < 0) + { + return SW_ERR; + } + + //write to file + if (swoole_sync_writefile(tmp_fd, data, data_len) <= 0) + { + swWarn("write to tmpfile failed."); + return SW_ERR; + } + + task->info.len = sizeof(swPackage_task); + //use tmp file + swTask_type(task) |= SW_TASK_TMPFILE; + + pkg.length = data_len; + memcpy(task->data, &pkg, sizeof(swPackage_task)); + close(tmp_fd); + return SW_OK; +} + +static void swTaskWorker_signal_init(void) +{ + swSignal_set(SIGHUP, NULL, 1, 0); + swSignal_set(SIGPIPE, NULL, 1, 0); + swSignal_set(SIGUSR1, swWorker_signal_handler, 1, 0); + swSignal_set(SIGUSR2, NULL, 1, 0); + swSignal_set(SIGTERM, swWorker_signal_handler, 1, 0); + swSignal_set(SIGALRM, swSystemTimer_signal_handler, 1, 0); +#ifdef SIGRTMIN + swSignal_set(SIGRTMIN, swWorker_signal_handler, 1, 0); +#endif +} + +void swTaskWorker_onStart(swProcessPool *pool, int worker_id) +{ + swServer *serv = pool->ptr; + SwooleWG.id = worker_id; + SwooleG.pid = getpid(); + + SwooleG.use_timer_pipe = 0; + SwooleG.use_timerfd = 0; + + swServer_close_port(serv, SW_TRUE); + + swTaskWorker_signal_init(); + swWorker_onStart(serv); + + SwooleG.main_reactor = NULL; + swWorker *worker = swProcessPool_get_worker(pool, worker_id); + worker->start_time = serv->gs->now; + worker->request_count = 0; + worker->traced = 0; + SwooleWG.worker = worker; + SwooleWG.worker->status = SW_WORKER_IDLE; +} + +void swTaskWorker_onStop(swProcessPool *pool, int worker_id) +{ + swServer *serv = pool->ptr; + swWorker_onStop(serv); +} + +/** + * Send the task result to worker + */ +int swTaskWorker_finish(swServer *serv, char *data, int data_len, int flags) +{ + swEventData buf; + if (!current_task) + { + swWarn("cannot use finish in worker"); + return SW_ERR; + } + if (serv->task_worker_num < 1) + { + swWarn("cannot use task/finish, because no set serv->task_worker_num."); + return SW_ERR; + } + if (current_task->info.type == SW_EVENT_PIPE_MESSAGE) + { + swWarn("task/finish is not supported in onPipeMessage callback."); + return SW_ERR; + } + + uint16_t source_worker_id = current_task->info.from_id; + swWorker *worker = swServer_get_worker(serv, source_worker_id); + + if (worker == NULL) + { + swWarn("invalid worker_id[%d].", source_worker_id); + return SW_ERR; + } + + int ret; + //for swoole_server_task + if (swTask_type(current_task) & SW_TASK_NONBLOCK) + { + buf.info.type = SW_EVENT_FINISH; + buf.info.fd = current_task->info.fd; + //callback function + if (swTask_type(current_task) & SW_TASK_CALLBACK) + { + flags |= SW_TASK_CALLBACK; + } + else if (swTask_type(current_task) & SW_TASK_COROUTINE) + { + flags |= SW_TASK_COROUTINE; + } + swTask_type(&buf) = flags; + + //write to file + if (data_len >= SW_IPC_MAX_SIZE - sizeof(buf.info)) + { + if (swTaskWorker_large_pack(&buf, data, data_len) < 0 ) + { + swWarn("large task pack failed()"); + return SW_ERR; + } + } + else + { + memcpy(buf.data, data, data_len); + buf.info.len = data_len; + } + + if (worker->pool->use_socket && worker->pool->stream->last_connection > 0) + { + int32_t _len = htonl(data_len); + ret = swSocket_write_blocking(worker->pool->stream->last_connection, (void *) &_len, sizeof(_len)); + if (ret > 0) + { + ret = swSocket_write_blocking(worker->pool->stream->last_connection, data, data_len); + } + } + else + { + ret = swWorker_send2worker(worker, &buf, sizeof(buf.info) + buf.info.len, SW_PIPE_MASTER); + } + } + else + { + uint64_t flag = 1; + + /** + * Use worker shm store the result + */ + swEventData *result = &(serv->task_result[source_worker_id]); + swPipe *task_notify_pipe = &(serv->task_notify[source_worker_id]); + + //lock worker + worker->lock.lock(&worker->lock); + + if (swTask_type(current_task) & SW_TASK_WAITALL) + { + sw_atomic_t *finish_count = (sw_atomic_t*) result->data; + char *_tmpfile = result->data + 4; + int fd = open(_tmpfile, O_APPEND | O_WRONLY); + if (fd >= 0) + { + buf.info.type = SW_EVENT_FINISH; + buf.info.fd = current_task->info.fd; + swTask_type(&buf) = flags; + //result pack + if (data_len >= SW_IPC_MAX_SIZE - sizeof(buf.info)) + { + if (swTaskWorker_large_pack(&buf, data, data_len) < 0) + { + swWarn("large task pack failed()"); + buf.info.len = 0; + } + } + else + { + buf.info.len = data_len; + memcpy(buf.data, data, data_len); + } + //write to tmpfile + if (swoole_sync_writefile(fd, &buf, sizeof(buf.info) + buf.info.len) < 0) + { + swSysError("write(%s, %ld) failed.", result->data, sizeof(buf.info) + buf.info.len); + } + sw_atomic_fetch_add(finish_count, 1); + close(fd); + } + } + else + { + result->info.type = SW_EVENT_FINISH; + result->info.fd = current_task->info.fd; + swTask_type(result) = flags; + + if (data_len >= SW_IPC_MAX_SIZE - sizeof(buf.info)) + { + if (swTaskWorker_large_pack(result, data, data_len) < 0) + { + //unlock worker + worker->lock.unlock(&worker->lock); + swWarn("large task pack failed()"); + return SW_ERR; + } + } + else + { + memcpy(result->data, data, data_len); + result->info.len = data_len; + } + } + + //unlock worker + worker->lock.unlock(&worker->lock); + + while (1) + { + ret = task_notify_pipe->write(task_notify_pipe, &flag, sizeof(flag)); +#ifdef HAVE_KQUEUE + if (ret < 0 && (errno == EAGAIN || errno == ENOBUFS)) +#else + if (ret < 0 && errno == EAGAIN) +#endif + { + if (swSocket_wait(task_notify_pipe->getFd(task_notify_pipe, 1), -1, SW_EVENT_WRITE) == 0) + { + continue; + } + } + break; + } + } + if (ret < 0) + { + swWarn("TaskWorker: send result to worker failed. Error: %s[%d]", strerror(errno), errno); + } + return ret; +} diff --git a/vendor/swoole/src/network/ThreadPool.c b/vendor/swoole/src/network/ThreadPool.c new file mode 100755 index 0000000..0c392b3 --- /dev/null +++ b/vendor/swoole/src/network/ThreadPool.c @@ -0,0 +1,186 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +#define swThreadPool_thread(p,id) (&p->threads[id]) +static void* swThreadPool_loop(void *arg); + +int swThreadPool_create(swThreadPool *pool, int thread_num) +{ + bzero(pool, sizeof(swThreadPool)); + + pool->threads = (swThread *) sw_calloc(thread_num, sizeof(swThread)); + pool->params = (swThreadParam *) sw_calloc(thread_num, sizeof(swThreadParam)); + + if (pool->threads == NULL || pool->params == NULL) + { + swWarn("swThreadPool_create malloc fail"); + return SW_ERR; + } + + swTrace("threads=%p|params=%p", pool->threads, pool->params); + +#ifdef SW_THREADPOOL_USE_CHANNEL + pool->chan = swChannel_create(1024 * 256, 512, 0); + if (pool->chan == NULL) + { + swWarn("swThreadPool_create create channel failed"); + return SW_ERR; + } +#else + int size = SwooleG.max_sockets >= SW_THREADPOOL_QUEUE_LEN ? SwooleG.max_sockets + 1 : SW_THREADPOOL_QUEUE_LEN; + if (swRingQueue_init(&pool->queue, size) < 0) + { + return SW_ERR; + } +#endif + if (swCond_create(&pool->cond) < 0) + { + return SW_ERR; + } + pool->thread_num = thread_num; + return SW_OK; +} + +int swThreadPool_dispatch(swThreadPool *pool, void *task, int task_len) +{ + int ret; + + pool->cond.lock(&pool->cond); +#ifdef SW_THREADPOOL_USE_CHANNEL + ret = swChannel_in(pool->chan, task, task_len); +#else + ret = swRingQueue_push(&pool->queue, task); +#endif + pool->cond.unlock(&pool->cond); + + if (ret < 0) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_QUEUE_FULL, "the queue of thread pool is full."); + return SW_ERR; + } + + sw_atomic_t *task_num = &pool->task_num; + sw_atomic_fetch_add(task_num, 1); + + return pool->cond.notify(&pool->cond); +} + +int swThreadPool_run(swThreadPool *pool) +{ + int i; + for (i = 0; i < pool->thread_num; i++) + { + pool->params[i].pti = i; + pool->params[i].object = pool; + if (pthread_create(&(swThreadPool_thread(pool,i)->tid), NULL, swThreadPool_loop, &pool->params[i]) < 0) + { + swWarn("pthread_create failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + } + return SW_OK; +} + +int swThreadPool_free(swThreadPool *pool) +{ + int i; + if (pool->shutdown) + { + return -1; + } + pool->shutdown = 1; + + //broadcast all thread + pool->cond.broadcast(&(pool->cond)); + + for (i = 0; i < pool->thread_num; i++) + { + pthread_join((swThreadPool_thread(pool,i)->tid), NULL); + } + +#ifdef SW_THREADPOOL_USE_CHANNEL + swChannel_free(pool->chan); +#else + swRingQueue_free(&pool->queue); +#endif + + pool->cond.free(&pool->cond); + + return SW_OK; +} + +static void* swThreadPool_loop(void *arg) +{ + swThreadParam *param = arg; + swThreadPool *pool = param->object; + + int id = param->pti; + int ret; + void *task; + + SwooleTG.buffer_stack = swString_new(8192); + if (SwooleTG.buffer_stack == NULL) + { + return NULL; + } + + if (pool->onStart) + { + pool->onStart(pool, id); + } + + while (SwooleG.running) + { + pool->cond.lock(&pool->cond); + + if (pool->shutdown) + { + pool->cond.unlock(&pool->cond); + swTrace("thread [%d] will exit\n", id); + pthread_exit(NULL); + } + + if (pool->task_num == 0) + { + pool->cond.wait(&pool->cond); + } + + swTrace("thread [%d] is starting to work\n", id); + + ret = swRingQueue_pop(&pool->queue, &task); + pool->cond.unlock(&pool->cond); + + if (ret >= 0) + { + sw_atomic_t *task_num = &pool->task_num; + sw_atomic_fetch_sub(task_num, 1); + + pool->onTask(pool, (void *) task, ret); + } + } + + if (pool->onStop) + { + pool->onStop(pool, id); + } + + swString_free(SwooleTG.buffer_stack); + pthread_exit(NULL); + return NULL; +} + diff --git a/vendor/swoole/src/network/TimeWheel.c b/vendor/swoole/src/network/TimeWheel.c new file mode 100755 index 0000000..b8b2d14 --- /dev/null +++ b/vendor/swoole/src/network/TimeWheel.c @@ -0,0 +1,135 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef SW_USE_TIMEWHEEL + +swTimeWheel* swTimeWheel_new(uint16_t size) +{ + swTimeWheel *tw = sw_malloc(sizeof(swTimeWheel)); + if (!tw) + { + swWarn("malloc(%ld) failed.", sizeof(swTimeWheel)); + return NULL; + } + + tw->size = size; + tw->current = 0; + tw->wheel = sw_calloc(size, sizeof(void*)); + if (tw->wheel == NULL) + { + swWarn("malloc(%ld) failed.", sizeof(void*) * size); + sw_free(tw); + return NULL; + } + + int i; + for (i = 0; i < size; i++) + { + tw->wheel[i] = swHashMap_new(16, NULL); + if (tw->wheel[i] == NULL) + { + swTimeWheel_free(tw); + return NULL; + } + } + return tw; +} + +void swTimeWheel_free(swTimeWheel *tw) +{ + int i; + for (i = 0; i < tw->size; i++) + { + if (tw->wheel[i] != NULL) + { + swHashMap_free(tw->wheel[i]); + tw->wheel[i] = NULL; + } + } + sw_free(tw->wheel); + sw_free(tw); +} + +void swTimeWheel_forward(swTimeWheel *tw, swReactor *reactor) +{ + swHashMap *set = tw->wheel[tw->current]; + tw->current = tw->current == tw->size - 1 ? 0 : tw->current + 1; + + swTraceLog(SW_TRACE_REACTOR, "current=%d.", tw->current); + + swConnection *conn; + uint64_t fd; + + while (1) + { + conn = swHashMap_each_int(set, &fd); + if (conn == NULL) + { + break; + } + + conn->close_force = 1; + conn->close_notify = 1; + conn->close_wait = 1; + conn->close_actively = 1; + + //notify to reactor thread + if (conn->removed) + { + reactor->close(reactor, (int) fd); + } + else + { + reactor->set(reactor, fd, SW_FD_TCP | SW_EVENT_WRITE); + } + } +} + +void swTimeWheel_add(swTimeWheel *tw, swConnection *conn) +{ + uint16_t index = tw->current == 0 ? tw->size - 1 : tw->current - 1; + swHashMap *new_set = tw->wheel[index]; + swHashMap_add_int(new_set, conn->fd, conn); + + conn->timewheel_index = index; + + swTraceLog(SW_TRACE_REACTOR, "current=%d, fd=%d, index=%d.", tw->current, conn->fd, index); +} + +void swTimeWheel_update(swTimeWheel *tw, swConnection *conn) +{ + uint16_t new_index = swTimeWheel_new_index(tw); + swHashMap *new_set = tw->wheel[new_index]; + swHashMap_add_int(new_set, conn->fd, conn); + + swHashMap *old_set = tw->wheel[conn->timewheel_index]; + swHashMap_del_int(old_set, conn->fd); + + swTraceLog(SW_TRACE_REACTOR, "current=%d, fd=%d, old_index=%d, new_index=%d.", tw->current, conn->fd, new_index, conn->timewheel_index); + + conn->timewheel_index = new_index; +} + +void swTimeWheel_remove(swTimeWheel *tw, swConnection *conn) +{ + swHashMap *set = tw->wheel[conn->timewheel_index]; + swHashMap_del_int(set, conn->fd); + swTraceLog(SW_TRACE_REACTOR, "current=%d, fd=%d.", tw->current, conn->fd); +} + +#endif diff --git a/vendor/swoole/src/network/Timer.c b/vendor/swoole/src/network/Timer.c new file mode 100755 index 0000000..cecf56f --- /dev/null +++ b/vendor/swoole/src/network/Timer.c @@ -0,0 +1,245 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +static int swReactorTimer_init(long msec); +static int swReactorTimer_set(swTimer *timer, long exec_msec); +static swTimer_node* swTimer_add(swTimer *timer, int _msec, int interval, void *data, swTimerCallback callback); + +int swTimer_now(struct timeval *time) +{ +#if defined(SW_USE_MONOTONIC_TIME) && defined(CLOCK_MONOTONIC) + struct timespec _now; + if (clock_gettime(CLOCK_MONOTONIC, &_now) < 0) + { + swSysError("clock_gettime(CLOCK_MONOTONIC) failed."); + return SW_ERR; + } + time->tv_sec = _now.tv_sec; + time->tv_usec = _now.tv_nsec / 1000; +#else + if (gettimeofday(time, NULL) < 0) + { + swSysError("gettimeofday() failed."); + return SW_ERR; + } +#endif + return SW_OK; +} + +static sw_inline int64_t swTimer_get_relative_msec() +{ + struct timeval now; + if (swTimer_now(&now) < 0) + { + return SW_ERR; + } + int64_t msec1 = (now.tv_sec - SwooleG.timer.basetime.tv_sec) * 1000; + int64_t msec2 = (now.tv_usec - SwooleG.timer.basetime.tv_usec) / 1000; + return msec1 + msec2; +} + +int swTimer_init(long msec) +{ + if (swTimer_now(&SwooleG.timer.basetime) < 0) + { + return SW_ERR; + } + + + SwooleG.timer.heap = swHeap_new(1024, SW_MIN_HEAP); + if (!SwooleG.timer.heap) + { + return SW_ERR; + } + + SwooleG.timer.map = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + if (!SwooleG.timer.map) + { + swHeap_free(SwooleG.timer.heap); + SwooleG.timer.heap = NULL; + return SW_ERR; + } + + SwooleG.timer._current_id = -1; + SwooleG.timer._next_msec = msec; + SwooleG.timer._next_id = 1; + SwooleG.timer.add = swTimer_add; + + if (swIsTaskWorker()) + { + swSystemTimer_init(msec, SwooleG.use_timer_pipe); + } + else + { + swReactorTimer_init(msec); + } + + return SW_OK; +} + +void swTimer_free(swTimer *timer) +{ + if (timer->heap) + { + swHeap_free(timer->heap); + } +} + +static int swReactorTimer_init(long exec_msec) +{ + SwooleG.main_reactor->check_timer = SW_TRUE; + SwooleG.main_reactor->timeout_msec = exec_msec; + SwooleG.timer.set = swReactorTimer_set; + SwooleG.timer.fd = -1; + return SW_OK; +} + +static int swReactorTimer_set(swTimer *timer, long exec_msec) +{ + SwooleG.main_reactor->timeout_msec = exec_msec; + return SW_OK; +} + +static swTimer_node* swTimer_add(swTimer *timer, int _msec, int interval, void *data, swTimerCallback callback) +{ + swTimer_node *tnode = sw_malloc(sizeof(swTimer_node)); + if (!tnode) + { + swSysError("malloc(%ld) failed.", sizeof(swTimer_node)); + return NULL; + } + + int64_t now_msec = swTimer_get_relative_msec(); + if (now_msec < 0) + { + sw_free(tnode); + return NULL; + } + + tnode->data = data; + tnode->type = SW_TIMER_TYPE_KERNEL; + tnode->exec_msec = now_msec + _msec; + tnode->interval = interval ? _msec : 0; + tnode->remove = 0; + tnode->callback = callback; + + if (timer->_next_msec < 0 || timer->_next_msec > _msec) + { + timer->set(timer, _msec); + timer->_next_msec = _msec; + } + + tnode->id = timer->_next_id++; + if (unlikely(tnode->id < 0)) + { + tnode->id = 1; + timer->_next_id = 2; + } + timer->num++; + + tnode->heap_node = swHeap_push(timer->heap, tnode->exec_msec, tnode); + if (tnode->heap_node == NULL) + { + sw_free(tnode); + return NULL; + } + swHashMap_add_int(timer->map, tnode->id, tnode); + return tnode; +} + +int swTimer_del(swTimer *timer, swTimer_node *tnode) +{ + if (tnode->remove) + { + return SW_FALSE; + } + if (SwooleG.timer._current_id > 0 && tnode->id == SwooleG.timer._current_id) + { + tnode->remove = 1; + return SW_TRUE; + } + if (swHashMap_del_int(timer->map, tnode->id) < 0) + { + return SW_ERR; + } + if (tnode->heap_node) + { + //remove from min-heap + swHeap_remove(timer->heap, tnode->heap_node); + sw_free(tnode->heap_node); + } + sw_free(tnode); + timer->num --; + return SW_TRUE; +} + +int swTimer_select(swTimer *timer) +{ + int64_t now_msec = swTimer_get_relative_msec(); + if (now_msec < 0) + { + return SW_ERR; + } + + swTimer_node *tnode = NULL; + swHeap_node *tmp; + long timer_id; + + while ((tmp = swHeap_top(timer->heap))) + { + tnode = tmp->data; + if (tnode->exec_msec > now_msec) + { + break; + } + + timer_id = timer->_current_id = tnode->id; + if (!tnode->remove) + { + tnode->callback(timer, tnode); + } + timer->_current_id = -1; + + //persistent timer + if (tnode->interval > 0 && !tnode->remove) + { + while (tnode->exec_msec <= now_msec) + { + tnode->exec_msec += tnode->interval; + } + swHeap_change_priority(timer->heap, tnode->exec_msec, tmp); + continue; + } + + timer->num--; + swHeap_pop(timer->heap); + swHashMap_del_int(timer->map, timer_id); + sw_free(tnode); + } + + if (!tnode || !tmp) + { + timer->_next_msec = -1; + timer->set(timer, -1); + } + else + { + timer->set(timer, tnode->exec_msec - now_msec); + } + return SW_OK; +} diff --git a/vendor/swoole/src/network/Worker.c b/vendor/swoole/src/network/Worker.c new file mode 100755 index 0000000..5081b3a --- /dev/null +++ b/vendor/swoole/src/network/Worker.c @@ -0,0 +1,897 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Server.h" +#include "Client.h" +#include "async.h" + +#include <pwd.h> +#include <grp.h> + +static int swWorker_onPipeReceive(swReactor *reactor, swEvent *event); +static void swWorker_onTimeout(swTimer *timer, swTimer_node *tnode); +static int swWorker_onStreamAccept(swReactor *reactor, swEvent *event); +static int swWorker_onStreamRead(swReactor *reactor, swEvent *event); +static int swWorker_onStreamPackage(swConnection *conn, char *data, uint32_t length); +static int swWorker_onStreamClose(swReactor *reactor, swEvent *event); +static void swWorker_stop(); + +int swWorker_create(swWorker *worker) +{ + /** + * Create shared memory storage + */ + worker->send_shm = sw_shm_malloc(SwooleG.serv->buffer_output_size); + if (worker->send_shm == NULL) + { + swWarn("malloc for worker->store failed."); + return SW_ERR; + } + swMutex_create(&worker->lock, 1); + + return SW_OK; +} + +void swWorker_free(swWorker *worker) +{ + if (worker->send_shm) + { + sw_shm_free(worker->send_shm); + } +} + +void swWorker_signal_init(void) +{ + swSignal_clear(); + /** + * use user settings + */ + SwooleG.use_signalfd = SwooleG.enable_signalfd; + + swSignal_add(SIGHUP, NULL); + swSignal_add(SIGPIPE, NULL); + swSignal_add(SIGUSR1, NULL); + swSignal_add(SIGUSR2, NULL); + //swSignal_add(SIGINT, swWorker_signal_handler); + swSignal_add(SIGTERM, swWorker_signal_handler); + swSignal_add(SIGALRM, swSystemTimer_signal_handler); + //for test + swSignal_add(SIGVTALRM, swWorker_signal_handler); +#ifdef SIGRTMIN + swSignal_add(SIGRTMIN, swWorker_signal_handler); +#endif +} + +void swWorker_signal_handler(int signo) +{ + switch (signo) + { + case SIGTERM: + /** + * Event worker + */ + if (SwooleG.main_reactor) + { + swWorker_stop(); + } + /** + * Task worker + */ + else + { + SwooleG.running = 0; + } + break; + case SIGALRM: + swSystemTimer_signal_handler(SIGALRM); + break; + /** + * for test + */ + case SIGVTALRM: + swWarn("SIGVTALRM coming"); + break; + case SIGUSR1: + break; + case SIGUSR2: + break; + default: +#ifdef SIGRTMIN + if (signo == SIGRTMIN) + { + swServer_reopen_log_file(SwooleG.serv); + } +#endif + break; + } +} + +static sw_inline int swWorker_discard_data(swServer *serv, swEventData *task) +{ + int fd = task->info.fd; + //check connection + swConnection *conn = swServer_connection_verify(serv, task->info.fd); + if (conn == NULL) + { + if (serv->disable_notify && !serv->discard_timeout_request) + { + return SW_FALSE; + } + goto discard_data; + } + else + { + if (conn->closed) + { + goto discard_data; + } + else + { + return SW_FALSE; + } + } + discard_data: +#ifdef SW_USE_RINGBUFFER + if (task->info.type == SW_EVENT_PACKAGE) + { + swPackage package; + memcpy(&package, task->data, sizeof(package)); + swReactorThread *thread = swServer_get_thread(SwooleG.serv, task->info.from_id); + thread->buffer_input->free(thread->buffer_input, package.data); + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SESSION_DISCARD_TIMEOUT_DATA, "[1]received the wrong data[%d bytes] from socket#%d", package.length, fd); + } + else +#endif + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SESSION_DISCARD_TIMEOUT_DATA, "[1]received the wrong data[%d bytes] from socket#%d", task->info.len, fd); + } + return SW_TRUE; +} + +static int swWorker_onStreamAccept(swReactor *reactor, swEvent *event) +{ + int fd = 0; + swSocketAddress client_addr; + socklen_t client_addrlen = sizeof(client_addr); + +#ifdef HAVE_ACCEPT4 + fd = accept4(event->fd, (struct sockaddr *) &client_addr, &client_addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); +#else + fd = accept(event->fd, (struct sockaddr *) &client_addr, &client_addrlen); +#endif + if (fd < 0) + { + switch (errno) + { + case EINTR: + case EAGAIN: + return SW_OK; + default: + swoole_error_log(SW_LOG_ERROR, SW_ERROR_SYSTEM_CALL_FAIL, "accept() failed. Error: %s[%d]", strerror(errno), + errno); + return SW_OK; + } + } +#ifndef HAVE_ACCEPT4 + else + { + swoole_fcntl_set_option(fd, 1, 1); + } +#endif + + swConnection *conn = swReactor_get(reactor, fd); + bzero(conn, sizeof(swConnection)); + conn->fd = fd; + conn->active = 1; + conn->socket_type = SW_SOCK_UNIX_STREAM; + memcpy(&conn->info.addr, &client_addr, sizeof(client_addr)); + + if (reactor->add(reactor, fd, SW_FD_STREAM | SW_EVENT_READ) < 0) + { + return SW_ERR; + } + + return SW_OK; +} + +static int swWorker_onStreamRead(swReactor *reactor, swEvent *event) +{ + swConnection *conn = event->socket; + swServer *serv = SwooleG.serv; + swProtocol *protocol = &serv->stream_protocol; + swString *buffer; + + if (!event->socket->recv_buffer) + { + buffer = swLinkedList_shift(serv->buffer_pool); + if (buffer == NULL) + { + buffer = swString_new(8192); + if (!buffer) + { + return SW_ERR; + } + + } + event->socket->recv_buffer = buffer; + } + else + { + buffer = event->socket->recv_buffer; + } + + if (swProtocol_recv_check_length(protocol, conn, buffer) < 0) + { + swWorker_onStreamClose(reactor, event); + } + + return SW_OK; +} + +static int swWorker_onStreamClose(swReactor *reactor, swEvent *event) +{ + swConnection *conn = event->socket; + swServer *serv = SwooleG.serv; + + swString_clear(conn->recv_buffer); + swLinkedList_append(serv->buffer_pool, conn->recv_buffer); + conn->recv_buffer = NULL; + + reactor->del(reactor, conn->fd); + reactor->close(reactor, conn->fd); + + return SW_OK; +} + +static int swWorker_onStreamPackage(swConnection *conn, char *data, uint32_t length) +{ + swServer *serv = SwooleG.serv; + swEventData *task = (swEventData *) (data + 4); + + serv->last_stream_fd = conn->fd; + + swString *package = swWorker_get_buffer(serv, task->info.from_id); + uint32_t data_length = length - sizeof(task->info) - 4; + //merge data to package buffer + swString_append_ptr(package, data + sizeof(task->info) + 4, data_length); + + swWorker_onTask(&serv->factory, task); + + int _end = htonl(0); + SwooleG.main_reactor->write(SwooleG.main_reactor, conn->fd, (void *) &_end, sizeof(_end)); + + return SW_OK; +} + +int swWorker_onTask(swFactory *factory, swEventData *task) +{ + swServer *serv = factory->ptr; + swString *package = NULL; + swDgramPacket *header; + +#ifdef SW_USE_OPENSSL + swConnection *conn; +#endif + + factory->last_from_id = task->info.from_id; + serv->last_session_id = task->info.fd; + swWorker *worker = SwooleWG.worker; + //worker busy + worker->status = SW_WORKER_BUSY; + + switch (task->info.type) + { + //no buffer + case SW_EVENT_TCP: + //ringbuffer shm package + case SW_EVENT_PACKAGE: + //discard data + if (swWorker_discard_data(serv, task) == SW_TRUE) + { + break; + } + do_task: + { + worker->request_time = serv->gs->now; +#ifdef SW_BUFFER_RECV_TIME + serv->last_receive_usec = task->info.time; +#endif + serv->onReceive(serv, task); + worker->request_time = 0; +#ifdef SW_BUFFER_RECV_TIME + serv->last_receive_usec = 0; +#endif + worker->traced = 0; + worker->request_count++; + sw_atomic_fetch_add(&serv->stats->request_count, 1); + } + if (task->info.type == SW_EVENT_PACKAGE_END) + { + package->length = 0; + } + break; + + //chunk package + case SW_EVENT_PACKAGE_START: + case SW_EVENT_PACKAGE_END: + //discard data + if (swWorker_discard_data(serv, task) == SW_TRUE) + { + break; + } + package = swWorker_get_buffer(serv, task->info.from_id); + if (task->info.len > 0) + { + //merge data to package buffer + swString_append_ptr(package, task->data, task->info.len); + } + //package end + if (task->info.type == SW_EVENT_PACKAGE_END) + { + goto do_task; + } + break; + + case SW_EVENT_UDP: + case SW_EVENT_UDP6: + case SW_EVENT_UNIX_DGRAM: + package = swWorker_get_buffer(serv, task->info.from_id); + swString_append_ptr(package, task->data, task->info.len); + + if (package->offset == 0) + { + header = (swDgramPacket *) package->str; + package->offset = header->length; + } + + //one packet + if (package->offset == package->length - sizeof(swDgramPacket)) + { + worker->request_count++; + worker->request_time = serv->gs->now; +#ifdef SW_BUFFER_RECV_TIME + serv->last_receive_usec = task->info.time; +#endif + sw_atomic_fetch_add(&serv->stats->request_count, 1); + serv->onPacket(serv, task); + worker->request_time = 0; +#ifdef SW_BUFFER_RECV_TIME + serv->last_receive_usec = 0; +#endif + worker->traced = 0; + worker->request_count++; + swString_clear(package); + } + break; + + case SW_EVENT_CLOSE: +#ifdef SW_USE_OPENSSL + conn = swServer_connection_verify_no_ssl(serv, task->info.fd); + if (conn && conn->ssl_client_cert.length > 0) + { + sw_free(conn->ssl_client_cert.str); + bzero(&conn->ssl_client_cert, sizeof(conn->ssl_client_cert.str)); + } +#endif + factory->end(factory, task->info.fd); + break; + + case SW_EVENT_CONNECT: +#ifdef SW_USE_OPENSSL + //SSL client certificate + if (task->info.len > 0) + { + conn = swServer_connection_verify_no_ssl(serv, task->info.fd); + conn->ssl_client_cert.str = sw_strndup(task->data, task->info.len); + conn->ssl_client_cert.size = conn->ssl_client_cert.length = task->info.len; + } +#endif + if (serv->onConnect) + { + serv->onConnect(serv, &task->info); + } + break; + + case SW_EVENT_BUFFER_FULL: + if (serv->onBufferFull) + { + serv->onBufferFull(serv, &task->info); + } + break; + + case SW_EVENT_BUFFER_EMPTY: + if (serv->onBufferEmpty) + { + serv->onBufferEmpty(serv, &task->info); + } + break; + + case SW_EVENT_FINISH: + serv->onFinish(serv, task); + break; + + case SW_EVENT_PIPE_MESSAGE: + serv->onPipeMessage(serv, task); + break; + + default: + swWarn("[Worker] error event[type=%d]", (int )task->info.type); + break; + } + + //worker idle + worker->status = SW_WORKER_IDLE; + + //maximum number of requests, process will exit. + if (!SwooleWG.run_always && worker->request_count >= SwooleWG.max_request) + { + swWorker_stop(); + } + return SW_OK; +} + +void swWorker_onStart(swServer *serv) +{ + /** + * Release other worker process + */ + swWorker *worker; + + if (SwooleWG.id >= serv->worker_num) + { + SwooleG.process_type = SW_PROCESS_TASKWORKER; + } + else + { + SwooleG.process_type = SW_PROCESS_WORKER; + } + + int is_root = !geteuid(); + struct passwd *passwd = NULL; + struct group *group = NULL; + + if (is_root) + { + //get group info + if (SwooleG.group) + { + group = getgrnam(SwooleG.group); + if (!group) + { + swWarn("get group [%s] info failed.", SwooleG.group); + } + } + //get user info + if (SwooleG.user) + { + passwd = getpwnam(SwooleG.user); + if (!passwd) + { + swWarn("get user [%s] info failed.", SwooleG.user); + } + } + //chroot + if (SwooleG.chroot) + { + if (0 > chroot(SwooleG.chroot)) + { + swSysError("chroot to [%s] failed.", SwooleG.chroot); + } + } + //set process group + if (SwooleG.group && group) + { + if (setgid(group->gr_gid) < 0) + { + swSysError("setgid to [%s] failed.", SwooleG.group); + } + } + //set process user + if (SwooleG.user && passwd) + { + if (setuid(passwd->pw_uid) < 0) + { + swSysError("setuid to [%s] failed.", SwooleG.user); + } + } + } + + SwooleWG.worker = swServer_get_worker(serv, SwooleWG.id); + + int i; + for (i = 0; i < serv->worker_num + serv->task_worker_num; i++) + { + worker = swServer_get_worker(serv, i); + if (SwooleWG.id == i) + { + continue; + } + else + { + swWorker_free(worker); + } + if (swIsWorker()) + { + swSetNonBlock(worker->pipe_master); + } + } + + SwooleWG.worker->status = SW_WORKER_IDLE; + sw_shm_protect(serv->session_list, PROT_READ); + + if (serv->onWorkerStart) + { + serv->onWorkerStart(serv, SwooleWG.id); + } +} + +void swWorker_onStop(swServer *serv) +{ + if (serv->onWorkerStop) + { + serv->onWorkerStop(serv, SwooleWG.id); + } +} + +static void swWorker_stop() +{ + swWorker *worker = SwooleWG.worker; + swServer *serv = SwooleG.serv; + worker->status = SW_WORKER_BUSY; + + /** + * force to end + */ + if (serv->reload_async == 0) + { + SwooleG.running = 0; + SwooleG.main_reactor->running = 0; + return; + } + + //The worker process is shutting down now. + if (SwooleWG.wait_exit) + { + return; + } + + //remove read event + if (worker->pipe_worker) + { + swReactor_remove_read_event(SwooleG.main_reactor, worker->pipe_worker); + } + + if (serv->stream_fd > 0) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, serv->stream_fd); + close(serv->stream_fd); + serv->stream_fd = 0; + } + + if (serv->onWorkerStop) + { + serv->onWorkerStop(serv, SwooleWG.id); + serv->onWorkerStop = NULL; + } + + if (serv->factory_mode == SW_MODE_SINGLE) + { + swListenPort *port; + LL_FOREACH(serv->listen_list, port) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, port->sock); + swPort_free(port); + } + + if (worker->pipe_worker) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, worker->pipe_worker); + SwooleG.main_reactor->del(SwooleG.main_reactor, worker->pipe_master); + } + + goto try_to_exit; + } + + swWorkerStopMessage msg; + msg.pid = SwooleG.pid; + msg.worker_id = SwooleWG.id; + + //send message to manager + if (swChannel_push(SwooleG.serv->message_box, &msg, sizeof(msg)) < 0) + { + SwooleG.running = 0; + } + else + { + kill(serv->gs->manager_pid, SIGIO); + } + + try_to_exit: SwooleWG.wait_exit = 1; + if (SwooleG.timer.fd == 0) + { + swTimer_init(serv->max_wait_time * 1000); + } + SwooleG.timer.add(&SwooleG.timer, serv->max_wait_time * 1000, 0, NULL, swWorker_onTimeout); + + swWorker_try_to_exit(); +} + +static void swWorker_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + SwooleG.running = 0; + SwooleG.main_reactor->running = 0; + swoole_error_log(SW_LOG_WARNING, SW_ERROR_SERVER_WORKER_EXIT_TIMEOUT, "worker exit timeout, forced to terminate."); +} + +void swWorker_try_to_exit() +{ + swServer *serv = SwooleG.serv; + int expect_event_num = SwooleG.use_signalfd ? 1 : 0; + + if (SwooleAIO.init && SwooleAIO.task_num == 0) + { + swAio_free(); + } + + swDNSResolver_free(); + + //close all client connections + if (serv->factory_mode == SW_MODE_SINGLE) + { + int find_fd = swServer_get_minfd(serv); + int max_fd = swServer_get_maxfd(serv); + swConnection *conn; + for (; find_fd <= max_fd; find_fd++) + { + conn = &serv->connection_list[find_fd]; + if (conn->active == 1 && swSocket_is_stream(conn->socket_type) && !(conn->events & SW_EVENT_WRITE)) + { + serv->close(serv, conn->session_id, 0); + } + } + } + + uint8_t call_worker_exit_func = 0; + + while (1) + { + if (SwooleG.main_reactor->event_num == expect_event_num) + { + SwooleG.main_reactor->running = 0; + SwooleG.running = 0; + } + else + { + if (serv->onWorkerExit && call_worker_exit_func == 0) + { + serv->onWorkerExit(serv, SwooleWG.id); + call_worker_exit_func = 1; + continue; + } + } + break; + } +} + +void swWorker_clean(void) +{ + int i; + swServer *serv = SwooleG.serv; + swWorker *worker; + + for (i = 0; i < serv->worker_num + serv->task_worker_num; i++) + { + worker = swServer_get_worker(serv, i); + if (SwooleG.main_reactor) + { + if (worker->pipe_worker) + { + swReactor_wait_write_buffer(SwooleG.main_reactor, worker->pipe_worker); + } + if (worker->pipe_master) + { + swReactor_wait_write_buffer(SwooleG.main_reactor, worker->pipe_master); + } + } + } +} + +/** + * worker main loop + */ +int swWorker_loop(swFactory *factory, int worker_id) +{ + swServer *serv = factory->ptr; + +#ifndef SW_WORKER_USE_SIGNALFD + SwooleG.use_signalfd = 0; +#elif defined(HAVE_SIGNALFD) + SwooleG.use_signalfd = 1; +#endif + //timerfd +#ifdef HAVE_TIMERFD + SwooleG.use_timerfd = 1; +#endif + + //worker_id + SwooleWG.id = worker_id; + SwooleG.pid = getpid(); + + swWorker *worker = swServer_get_worker(serv, worker_id); + swServer_worker_init(serv, worker); + + SwooleG.main_reactor = sw_malloc(sizeof(swReactor)); + if (SwooleG.main_reactor == NULL) + { + swError("[Worker] malloc for reactor failed."); + return SW_ERR; + } + + if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) + { + swError("[Worker] create worker_reactor failed."); + return SW_ERR; + } + + worker->status = SW_WORKER_IDLE; + + int pipe_worker = worker->pipe_worker; + + swSetNonBlock(pipe_worker); + SwooleG.main_reactor->ptr = serv; + SwooleG.main_reactor->add(SwooleG.main_reactor, pipe_worker, SW_FD_PIPE | SW_EVENT_READ); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_PIPE, swWorker_onPipeReceive); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_WRITE, swReactor_onWrite); + + /** + * set pipe buffer size + */ + int i; + swConnection *pipe_socket; + for (i = 0; i < serv->worker_num + serv->task_worker_num; i++) + { + worker = swServer_get_worker(serv, i); + pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_master); + pipe_socket->buffer_size = SW_MAX_INT; + pipe_socket = swReactor_get(SwooleG.main_reactor, worker->pipe_worker); + pipe_socket->buffer_size = SW_MAX_INT; + } + + if (serv->dispatch_mode == SW_DISPATCH_STREAM) + { + SwooleG.main_reactor->add(SwooleG.main_reactor, serv->stream_fd, SW_FD_LISTEN | SW_EVENT_READ); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_LISTEN, swWorker_onStreamAccept); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_STREAM, swWorker_onStreamRead); + swStream_set_protocol(&serv->stream_protocol); + serv->stream_protocol.package_max_length = SW_MAX_INT; + serv->stream_protocol.onPackage = swWorker_onStreamPackage; + serv->buffer_pool = swLinkedList_new(0, NULL); + } + + swWorker_onStart(serv); + +#ifdef HAVE_SIGNALFD + if (SwooleG.use_signalfd) + { + swSignalfd_setup(SwooleG.main_reactor); + } +#endif + //main loop + SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); + //clear pipe buffer + swWorker_clean(); + //worker shutdown + swWorker_onStop(serv); + return SW_OK; +} + +/** + * Send data to ReactorThread + */ +int swWorker_send2reactor(swEventData *ev_data, size_t sendn, int session_id) +{ + int ret; + swServer *serv = SwooleG.serv; + int _pipe_fd = swWorker_get_send_pipe(serv, session_id, ev_data->info.from_id); + + if (SwooleG.main_reactor) + { + ret = SwooleG.main_reactor->write(SwooleG.main_reactor, _pipe_fd, ev_data, sendn); + } + else + { + ret = swSocket_write_blocking(_pipe_fd, ev_data, sendn); + } + return ret; +} + +/** + * receive data from reactor + */ +static int swWorker_onPipeReceive(swReactor *reactor, swEvent *event) +{ + swEventData task; + swServer *serv = reactor->ptr; + swFactory *factory = &serv->factory; + int ret; + + read_from_pipe: + + if (read(event->fd, &task, sizeof(task)) > 0) + { + ret = swWorker_onTask(factory, &task); +#ifndef SW_WORKER_RECV_AGAIN + /** + * Big package + */ + if (task.info.type == SW_EVENT_PACKAGE_START) +#endif + { + //no data + if (ret < 0 && errno == EAGAIN) + { + return SW_OK; + } + else if (ret > 0) + { + goto read_from_pipe; + } + } + return ret; + } + return SW_ERR; +} + +int swWorker_send2worker(swWorker *dst_worker, void *buf, int n, int flag) +{ + int pipefd, ret; + + if (flag & SW_PIPE_MASTER) + { + pipefd = dst_worker->pipe_master; + } + else + { + pipefd = dst_worker->pipe_worker; + } + + //message-queue + if (dst_worker->pool->use_msgqueue) + { + struct + { + long mtype; + swEventData buf; + } msg; + + msg.mtype = dst_worker->id + 1; + memcpy(&msg.buf, buf, n); + + return swMsgQueue_push(dst_worker->pool->queue, (swQueue_data *) &msg, n); + } + + if ((flag & SW_PIPE_NONBLOCK) && SwooleG.main_reactor) + { + return SwooleG.main_reactor->write(SwooleG.main_reactor, pipefd, buf, n); + } + else + { + ret = swSocket_write_blocking(pipefd, buf, n); + } + + return ret; +} diff --git a/vendor/swoole/src/os/base.c b/vendor/swoole/src/os/base.c new file mode 100755 index 0000000..69c6735 --- /dev/null +++ b/vendor/swoole/src/os/base.c @@ -0,0 +1,676 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2018 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "async.h" +#include <sys/file.h> +#include <sys/stat.h> + +swAsyncIO SwooleAIO; +swPipe swoole_aio_pipe; + +static void swAioBase_destroy(); +static int swAioBase_read(int fd, void *inbuf, size_t size, off_t offset); +static int swAioBase_write(int fd, void *inbuf, size_t size, off_t offset); +static int swAioBase_thread_onTask(swThreadPool *pool, void *task, int task_len); +static int swAioBase_onFinish(swReactor *reactor, swEvent *event); + +static void swAio_handler_read(swAio_event *event); +static void swAio_handler_write(swAio_event *event); +static void swAio_handler_gethostbyname(swAio_event *event); +static void swAio_handler_getaddrinfo(swAio_event *event); +static void swAio_handler_stream_get_line(swAio_event *event); +static void swAio_handler_read_file(swAio_event *event); +static void swAio_handler_write_file(swAio_event *event); + +static swThreadPool swAioBase_thread_pool; +static int swAioBase_pipe_read; +static int swAioBase_pipe_write; + +int swAio_init(void) +{ + if (SwooleAIO.init) + { + swWarn("AIO has already been initialized"); + return SW_ERR; + } + if (!SwooleG.main_reactor) + { + swWarn("No eventloop, cannot initialized"); + return SW_ERR; + } + return swAioBase_init(SW_AIO_EVENT_NUM); +} + +void swAio_free(void) +{ + if (!SwooleAIO.init) + { + return; + } + SwooleAIO.destroy(); + SwooleAIO.init = 0; +} + +/** + * for test + */ +void swAio_callback_test(swAio_event *aio_event) +{ + printf("content=%s\n", (char *)aio_event->buf); + printf("fd: %d, request_type: %s, offset: %ld, length: %lu\n", aio_event->fd, + (aio_event == SW_AIO_READ) ? "READ" : "WRITE", (long)aio_event->offset, aio_event->nbytes); + SwooleG.running = 0; +} + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose) +{ + pid_t pid; + + if (!nochdir && chdir("/") != 0) + { + swWarn("chdir() failed. Error: %s[%d]", strerror(errno), errno); + return -1; + } + + if (!noclose) + { + int fd = open("/dev/null", O_RDWR); + if (fd < 0) + { + swWarn("open() failed. Error: %s[%d]", strerror(errno), errno); + return -1; + } + + if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) + { + close(fd); + swWarn("dup2() failed. Error: %s[%d]", strerror(errno), errno); + return -1; + } + + close(fd); + } + + pid = fork(); + if (pid < 0) + { + swWarn("fork() failed. Error: %s[%d]", strerror(errno), errno); + return -1; + } + if (pid > 0) + { + _exit(0); + } + if (setsid() < 0) + { + swWarn("setsid() failed. Error: %s[%d]", strerror(errno), errno); + return -1; + } + return 0; +} +#endif + +static int swAioBase_onFinish(swReactor *reactor, swEvent *event) +{ + int i; + swAio_event *events[SW_AIO_EVENT_NUM]; + int n = read(event->fd, events, sizeof(swAio_event*) * SW_AIO_EVENT_NUM); + if (n < 0) + { + swWarn("read() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + for (i = 0; i < n / sizeof(swAio_event*); i++) + { + if (events[i]->callback) + { + events[i]->callback(events[i]); + } + else + { + SwooleAIO.callback(events[i]); + } + SwooleAIO.task_num--; + sw_free(events[i]); + } + return SW_OK; +} + +int swAioBase_init(int max_aio_events) +{ + if (swPipeBase_create(&swoole_aio_pipe, 0) < 0) + { + return SW_ERR; + } + if (swMutex_create(&SwooleAIO.lock, 0) < 0) + { + swWarn("create mutex lock error."); + return SW_ERR; + } + if (SwooleAIO.thread_num <= 0) + { + SwooleAIO.thread_num = SW_AIO_THREAD_NUM_DEFAULT; + } + if (swThreadPool_create(&swAioBase_thread_pool, SwooleAIO.thread_num) < 0) + { + return SW_ERR; + } + + swAioBase_thread_pool.onTask = swAioBase_thread_onTask; + + swAioBase_pipe_read = swoole_aio_pipe.getFd(&swoole_aio_pipe, 0); + swAioBase_pipe_write = swoole_aio_pipe.getFd(&swoole_aio_pipe, 1); + + SwooleAIO.handlers[SW_AIO_READ] = swAio_handler_read; + SwooleAIO.handlers[SW_AIO_WRITE] = swAio_handler_write; + SwooleAIO.handlers[SW_AIO_GETHOSTBYNAME] = swAio_handler_gethostbyname; + SwooleAIO.handlers[SW_AIO_GETADDRINFO] = swAio_handler_getaddrinfo; + SwooleAIO.handlers[SW_AIO_STREAM_GET_LINE] = swAio_handler_stream_get_line; + SwooleAIO.handlers[SW_AIO_READ_FILE] = swAio_handler_read_file; + SwooleAIO.handlers[SW_AIO_WRITE_FILE] = swAio_handler_write_file; + + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_AIO, swAioBase_onFinish); + SwooleG.main_reactor->add(SwooleG.main_reactor, swAioBase_pipe_read, SW_FD_AIO); + + if (swThreadPool_run(&swAioBase_thread_pool) < 0) + { + return SW_ERR; + } + + SwooleAIO.destroy = swAioBase_destroy; + SwooleAIO.read = swAioBase_read; + SwooleAIO.write = swAioBase_write; + SwooleAIO.init = 1; + + return SW_OK; +} + +static void swAio_handler_read(swAio_event *event) +{ + int ret = -1; + if (flock(event->fd, LOCK_SH) < 0) + { + swSysError("flock(%d, LOCK_SH) failed.", event->fd); + event->ret = -1; + event->error = errno; + return; + } + while (1) + { + ret = pread(event->fd, event->buf, event->nbytes, event->offset); + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) + { + continue; + } + break; + } + if (flock(event->fd, LOCK_UN) < 0) + { + swSysError("flock(%d, LOCK_UN) failed.", event->fd); + } + event->ret = ret; +} + +static inline char* find_eol(char *buf, size_t size) +{ + char *eol = memchr(buf, '\n', size); + if (!eol) + { + eol = memchr(buf, '\r', size); + } + return eol; +} + +static void swAio_handler_stream_get_line(swAio_event *event) +{ + int ret = -1; + if (flock(event->fd, LOCK_SH) < 0) + { + swSysError("flock(%d, LOCK_SH) failed.", event->fd); + event->ret = -1; + event->error = errno; + return; + } + + off_t readpos = event->offset; + off_t writepos = (long) event->req; + size_t avail = 0; + char *eol; + char *tmp; + + char *read_buf = event->buf; + int read_n = event->nbytes; + + while (1) + { + avail = writepos - readpos; + + swTraceLog(SW_TRACE_AIO, "readpos=%ld, writepos=%ld", (long)readpos, (long)writepos); + + if (avail > 0) + { + tmp = event->buf + readpos; + eol = find_eol(tmp, avail); + if (eol) + { + event->buf = tmp; + event->ret = (eol - tmp) + 1; + readpos += event->ret; + goto _return; + } + else if (readpos == 0) + { + if (writepos == event->nbytes) + { + writepos = 0; + event->ret = event->nbytes; + goto _return; + } + else + { + event->flags = SW_AIO_EOF; + ((char*) event->buf)[writepos] = '\0'; + event->ret = writepos; + writepos = 0; + goto _return; + } + } + else + { + memmove(event->buf, event->buf + readpos, avail); + writepos = avail; + read_buf = event->buf + writepos; + read_n = event->nbytes - writepos; + readpos = 0; + goto _readfile; + } + } + else + { + _readfile: while (1) + { + ret = read(event->fd, read_buf, read_n); + if (ret < 0 && (errno == EINTR || errno == EAGAIN)) + { + continue; + } + break; + } + if (ret > 0) + { + writepos += ret; + } + else if (ret == 0) + { + event->flags = SW_AIO_EOF; + if (writepos > 0) + { + event->ret = writepos; + } + else + { + ((char*) event->buf)[0] = '\0'; + event->ret = 0; + } + readpos = writepos = 0; + goto _return; + } + } + } + + _return: + if (flock(event->fd, LOCK_UN) < 0) + { + swSysError("flock(%d, LOCK_UN) failed.", event->fd); + } + event->offset = readpos; + event->req = (void *) (long) writepos; +} + +static void swAio_handler_read_file(swAio_event *event) +{ + int ret = -1; + int fd = open(event->req, O_RDONLY); + if (fd < 0) + { + swSysError("open(%s, O_RDONLY) failed.", (char * )event->req); + event->ret = ret; + event->error = errno; + return; + } + struct stat file_stat; + if (fstat(fd, &file_stat) < 0) + { + swSysError("fstat(%s) failed.", (char * )event->req); + _error: close(fd); + event->ret = ret; + event->error = errno; + return; + } + if ((file_stat.st_mode & S_IFMT) != S_IFREG) + { + errno = EISDIR; + goto _error; + } + + long filesize = file_stat.st_size; + if (filesize == 0) + { + errno = SW_ERROR_FILE_EMPTY; + goto _error; + } + + if (flock(fd, LOCK_SH) < 0) + { + swSysError("flock(%d, LOCK_SH) failed.", event->fd); + goto _error; + } + + event->buf = sw_malloc(filesize); + if (event->buf == NULL) + { + goto _error; + } + int readn = swoole_sync_readfile(fd, event->buf, (int) filesize); + if (flock(fd, LOCK_UN) < 0) + { + swSysError("flock(%d, LOCK_UN) failed.", event->fd); + } + close(fd); + event->ret = readn; + event->error = 0; +} + +static void swAio_handler_write_file(swAio_event *event) +{ + int ret = -1; + int fd = open(event->req, event->flags, 0644); + if (fd < 0) + { + swSysError("open(%s, %d) failed.", (char * )event->req, event->flags); + event->ret = ret; + event->error = errno; + return; + } + if (flock(fd, LOCK_EX) < 0) + { + swSysError("flock(%d, LOCK_EX) failed.", event->fd); + event->ret = ret; + event->error = errno; + close(fd); + return; + } + int written = swoole_sync_writefile(fd, event->buf, event->nbytes); + if (event->flags & SW_AIO_WRITE_FSYNC) + { + if (fsync(fd) < 0) + { + swSysError("fsync(%d) failed.", event->fd); + } + } + if (flock(fd, LOCK_UN) < 0) + { + swSysError("flock(%d, LOCK_UN) failed.", event->fd); + } + close(fd); + event->ret = written; + event->error = 0; +} + +static void swAio_handler_write(swAio_event *event) +{ + int ret = -1; + if (flock(event->fd, LOCK_EX) < 0) + { + swSysError("flock(%d, LOCK_EX) failed.", event->fd); + return; + } + if (event->offset == 0) + { + ret = write(event->fd, event->buf, event->nbytes); + } + else + { + ret = pwrite(event->fd, event->buf, event->nbytes, event->offset); + } + if (event->flags & SW_AIO_WRITE_FSYNC) + { + if (fsync(event->fd) < 0) + { + swSysError("fsync(%d) failed.", event->fd); + } + } + if (flock(event->fd, LOCK_UN) < 0) + { + swSysError("flock(%d, LOCK_UN) failed.", event->fd); + } + event->ret = ret; +} + +static void swAio_handler_gethostbyname(swAio_event *event) +{ + struct in_addr addr_v4; + struct in6_addr addr_v6; + int ret; + +#ifndef HAVE_GETHOSTBYNAME2_R + SwooleAIO.lock.lock(&SwooleAIO.lock); +#endif + if (event->flags == AF_INET6) + { + ret = swoole_gethostbyname(AF_INET6, event->buf, (char *) &addr_v6); + } + else + { + ret = swoole_gethostbyname(AF_INET, event->buf, (char *) &addr_v4); + } + bzero(event->buf, event->nbytes); +#ifndef HAVE_GETHOSTBYNAME2_R + SwooleAIO.lock.unlock(&SwooleAIO.lock); +#endif + + if (ret < 0) + { + event->error = h_errno; + } + else + { + if (inet_ntop(event->flags == AF_INET6 ? AF_INET6 : AF_INET, + event->flags == AF_INET6 ? (void *) &addr_v6 : (void *) &addr_v4, event->buf, event->nbytes) == NULL) + { + ret = -1; + event->error = SW_ERROR_BAD_IPV6_ADDRESS; + } + else + { + event->error = 0; + ret = 0; + } + } + event->ret = ret; +} + +static void swAio_handler_getaddrinfo(swAio_event *event) +{ + swRequest_getaddrinfo *req = (swRequest_getaddrinfo *) event->req; + event->ret = swoole_getaddrinfo(req); + event->error = req->error; +} + +static int swAioBase_thread_onTask(swThreadPool *pool, void *task, int task_len) +{ + swAio_event *event = task; + if (event->type >= SW_AIO_HANDLER_MAX_SIZE || SwooleAIO.handlers[event->type] == NULL) + { + event->error = SW_ERROR_AIO_BAD_REQUEST; + event->ret = -1; + goto _error; + } + + SwooleAIO.handlers[event->type](event); + + swTrace("aio_thread ok. ret=%d, error=%d", event->ret, event->error); + + _error: do + { + SwooleAIO.lock.lock(&SwooleAIO.lock); + int ret = write(swAioBase_pipe_write, &task, sizeof(task)); + SwooleAIO.lock.unlock(&SwooleAIO.lock); + if (ret < 0) + { + if (errno == EAGAIN) + { + swYield(); + continue; + } + else if (errno == EINTR) + { + continue; + } + else + { + swSysError("sendto swoole_aio_pipe_write failed."); + } + } + break; + } while (1); + + return SW_OK; +} + +static int swAioBase_write(int fd, void *inbuf, size_t size, off_t offset) +{ + swAio_event *aio_ev = (swAio_event *) sw_malloc(sizeof(swAio_event)); + if (aio_ev == NULL) + { + swWarn("malloc failed."); + return SW_ERR; + } + bzero(aio_ev, sizeof(swAio_event)); + aio_ev->fd = fd; + aio_ev->buf = inbuf; + aio_ev->type = SW_AIO_WRITE; + aio_ev->nbytes = size; + aio_ev->offset = offset; + aio_ev->task_id = SwooleAIO.current_id++; + + if (swThreadPool_dispatch(&swAioBase_thread_pool, aio_ev, sizeof(aio_ev)) < 0) + { + return SW_ERR; + } + else + { + SwooleAIO.task_num++; + return aio_ev->task_id; + } +} + +int swAio_dns_lookup(void *hostname, void *ip_addr, size_t size) +{ + swAio_event *aio_ev = (swAio_event *) sw_malloc(sizeof(swAio_event)); + if (aio_ev == NULL) + { + swWarn("malloc failed."); + return SW_ERR; + } + + bzero(aio_ev, sizeof(swAio_event)); + aio_ev->buf = ip_addr; + aio_ev->req = hostname; + aio_ev->type = SW_AIO_GETHOSTBYNAME; + aio_ev->nbytes = size; + aio_ev->task_id = SwooleAIO.current_id++; + + if (swThreadPool_dispatch(&swAioBase_thread_pool, aio_ev, sizeof(aio_ev)) < 0) + { + return SW_ERR; + } + else + { + SwooleAIO.task_num++; + return aio_ev->task_id; + } +} + +int swAio_dispatch(swAio_event *_event) +{ + if (SwooleAIO.init == 0) + { + swAio_init(); + } + + _event->task_id = SwooleAIO.current_id++; + + swAio_event *event = (swAio_event *) sw_malloc(sizeof(swAio_event)); + if (event == NULL) + { + swWarn("malloc failed."); + return SW_ERR; + } + memcpy(event, _event, sizeof(swAio_event)); + + if (swThreadPool_dispatch(&swAioBase_thread_pool, event, sizeof(event)) < 0) + { + return SW_ERR; + } + else + { + SwooleAIO.task_num++; + return _event->task_id; + } +} + +static int swAioBase_read(int fd, void *inbuf, size_t size, off_t offset) +{ + swAio_event *aio_ev = (swAio_event *) sw_malloc(sizeof(swAio_event)); + if (aio_ev == NULL) + { + swWarn("malloc failed."); + return SW_ERR; + } + + bzero(aio_ev, sizeof(swAio_event)); + aio_ev->fd = fd; + aio_ev->buf = inbuf; + aio_ev->type = SW_AIO_READ; + aio_ev->nbytes = size; + aio_ev->offset = offset; + aio_ev->task_id = SwooleAIO.current_id++; + + if (swThreadPool_dispatch(&swAioBase_thread_pool, aio_ev, sizeof(aio_ev)) < 0) + { + return SW_ERR; + } + else + { + SwooleAIO.task_num++; + return aio_ev->task_id; + } +} + +void swAioBase_destroy() +{ + swThreadPool_free(&swAioBase_thread_pool); + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, swAioBase_pipe_read); + } + swoole_aio_pipe.close(&swoole_aio_pipe); +} diff --git a/vendor/swoole/src/os/msg_queue.c b/vendor/swoole/src/os/msg_queue.c new file mode 100755 index 0000000..5171fad --- /dev/null +++ b/vendor/swoole/src/os/msg_queue.c @@ -0,0 +1,127 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include <sys/types.h> +#include <sys/ipc.h> +#include <sys/msg.h> + +int swMsgQueue_free(swMsgQueue *q) +{ + if (msgctl(q->msg_id, IPC_RMID, 0) < 0) + { + swSysError("msgctl(%d, IPC_RMID) failed.", q->msg_id); + return SW_ERR; + } + return SW_OK; +} + +void swMsgQueue_set_blocking(swMsgQueue *q, uint8_t blocking) +{ + if (blocking == 0) + { + q->flags = q->flags | IPC_NOWAIT; + } + else + { + q->flags = q->flags & (~IPC_NOWAIT); + } +} + +int swMsgQueue_create(swMsgQueue *q, int blocking, key_t msg_key, int perms) +{ + if (perms <= 0 || perms >= 01000) + { + perms = 0666; + } + int msg_id; + msg_id = msgget(msg_key, IPC_CREAT | perms); + if (msg_id < 0) + { + swSysError("msgget() failed."); + return SW_ERR; + } + else + { + bzero(q, sizeof(swMsgQueue)); + q->msg_id = msg_id; + q->perms = perms; + q->blocking = blocking; + swMsgQueue_set_blocking(q, blocking); + } + return 0; +} + +int swMsgQueue_pop(swMsgQueue *q, swQueue_data *data, int length) +{ + int ret = msgrcv(q->msg_id, data, length, data->mtype, q->flags); + if (ret < 0) + { + SwooleG.error = errno; + if (errno != ENOMSG && errno != EINTR) + { + swSysError("msgrcv(%d, %d, %ld) failed.", q->msg_id, length, data->mtype); + } + } + return ret; +} + +int swMsgQueue_push(swMsgQueue *q, swQueue_data *in, int length) +{ + int ret; + + while (1) + { + ret = msgsnd(q->msg_id, in, length, q->flags); + if (ret < 0) + { + SwooleG.error = errno; + if (errno == EINTR) + { + continue; + } + else if (errno == EAGAIN) + { + return -1; + } + else + { + swSysError("msgsnd(%d, %d, %ld) failed.", q->msg_id, length, in->mtype); + return -1; + } + } + else + { + return ret; + } + } + return 0; +} + +int swMsgQueue_stat(swMsgQueue *q, int *queue_num, int *queue_bytes) +{ + struct msqid_ds __stat; + if (msgctl(q->msg_id, IPC_STAT, &__stat) == 0) + { + *queue_num = __stat.msg_qnum; + *queue_bytes = __stat.msg_cbytes; + return 0; + } + else + { + return -1; + } +} diff --git a/vendor/swoole/src/os/sendfile.c b/vendor/swoole/src/os/sendfile.c new file mode 100755 index 0000000..ef92ebb --- /dev/null +++ b/vendor/swoole/src/os/sendfile.c @@ -0,0 +1,101 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef HAVE_KQUEUE + +#include <sys/uio.h> + +int swoole_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) +{ + off_t sent_bytes = 0; + int ret; + +#ifdef __MACH__ + struct sf_hdtr hdtr; + hdtr.headers = NULL; + hdtr.hdr_cnt = 0; + hdtr.trailers = NULL; + hdtr.trl_cnt = 0; +#endif + + //sent_bytes = (off_t)size; + swTrace("send file, out_fd:%d, in_fd:%d, offset:%ld, size:%ld", out_fd, in_fd, (long)*offset, (long)size); + + do_sendfile: +#ifdef __MACH__ + ret = sendfile(in_fd, out_fd, *offset, (long long *) &size, &hdtr, 0); +#else + ret = sendfile(in_fd, out_fd, *offset, size, 0, &sent_bytes, 0); +#endif + if (ret == -1) + { + if (errno == EAGAIN) + { + *offset += sent_bytes; + return sent_bytes; + } + else if (errno == EINTR) + { + goto do_sendfile; + } + else + { + return -1; + } + } + else if (ret == 0) + { + *offset += size; + return size; + } + else + { + swWarn("sendfile failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + return SW_OK; +} +#elif !defined(HAVE_SENDFILE) +int swoole_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) +{ + char buf[SW_BUFFER_SIZE_BIG]; + int readn = size > sizeof(buf) ? sizeof(buf) : size; + + int ret; + int n = pread(in_fd, buf, readn, *offset); + + if (n > 0) + { + ret = write(out_fd, buf, n); + if (ret < 0) + { + swSysError("write() failed."); + } + else + { + *offset += ret; + } + return ret; + } + else + { + swSysError("pread() failed."); + return SW_ERR; + } +} +#endif diff --git a/vendor/swoole/src/os/signal.c b/vendor/swoole/src/os/signal.c new file mode 100755 index 0000000..50c1f91 --- /dev/null +++ b/vendor/swoole/src/os/signal.c @@ -0,0 +1,262 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef HAVE_SIGNALFD +#include <sys/signalfd.h> +static void swSignalfd_set(int signo, swSignalHander callback); +static void swSignalfd_clear(); +static int swSignalfd_onSignal(swReactor *reactor, swEvent *event); + +static sigset_t signalfd_mask; +static int signal_fd = 0; +#endif + +typedef struct +{ + swSignalHander callback; + uint16_t signo; + uint16_t active; +} swSignal; + +static swSignal signals[SW_SIGNO_MAX]; +static int _lock = 0; + +static void swSignal_async_handler(int signo); + +/** + * clear all singal + */ +void swSignal_none(void) +{ + sigset_t mask; + sigfillset(&mask); + int ret = pthread_sigmask(SIG_BLOCK, &mask, NULL); + if (ret < 0) + { + swWarn("pthread_sigmask() failed. Error: %s[%d]", strerror(ret), ret); + } +} + +/** + * setup signal + */ +swSignalHander swSignal_set(int sig, swSignalHander func, int restart, int mask) +{ + //ignore + if (func == NULL) + { + func = SIG_IGN; + } + //clear + else if ((long) func == -1) + { + func = SIG_DFL; + } + + struct sigaction act, oact; + act.sa_handler = func; + if (mask) + { + sigfillset(&act.sa_mask); + } + else + { + sigemptyset(&act.sa_mask); + } + act.sa_flags = 0; + if (sigaction(sig, &act, &oact) < 0) + { + return NULL; + } + return oact.sa_handler; +} + +void swSignal_add(int signo, swSignalHander func) +{ +#ifdef HAVE_SIGNALFD + if (SwooleG.use_signalfd) + { + swSignalfd_set(signo, func); + } + else +#endif + { + signals[signo].callback = func; + signals[signo].active = 1; + signals[signo].signo = signo; + swSignal_set(signo, swSignal_async_handler, 1, 0); + } +} + +static void swSignal_async_handler(int signo) +{ + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->singal_no = signo; + } + else + { + //discard signal + if (_lock) + { + return; + } + _lock = 1; + swSignal_callback(signo); + _lock = 0; + } +} + +void swSignal_callback(int signo) +{ + if (signo >= SW_SIGNO_MAX) + { + swWarn("signal[%d] numberis invalid.", signo); + return; + } + swSignalHander callback = signals[signo].callback; + if (!callback) + { + swWarn("signal[%d] callback is null.", signo); + return; + } + callback(signo); +} + +void swSignal_clear(void) +{ +#ifdef HAVE_SIGNALFD + if (SwooleG.use_signalfd) + { + swSignalfd_clear(); + } + else +#endif + { + int i; + for (i = 0; i < SW_SIGNO_MAX; i++) + { + if (signals[i].active) + { + swSignal_set(signals[i].signo, (swSignalHander) -1, 1, 0); + } + } + } + bzero(&signals, sizeof(signals)); +} + +#ifdef HAVE_SIGNALFD +void swSignalfd_init() +{ + sigemptyset(&signalfd_mask); + bzero(&signals, sizeof(signals)); +} + +static void swSignalfd_set(int signo, swSignalHander callback) +{ + if (callback == NULL && signals[signo].active) + { + sigdelset(&signalfd_mask, signo); + bzero(&signals[signo], sizeof(swSignal)); + } + else + { + sigaddset(&signalfd_mask, signo); + signals[signo].callback = callback; + signals[signo].signo = signo; + signals[signo].active = 1; + } + if (signal_fd > 0) + { + sigprocmask(SIG_BLOCK, &signalfd_mask, NULL); + signalfd(signal_fd, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC); + } +} + +int swSignalfd_setup(swReactor *reactor) +{ + if (signal_fd == 0) + { + signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC); + if (signal_fd < 0) + { + swWarn("signalfd() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + SwooleG.signal_fd = signal_fd; + if (sigprocmask(SIG_BLOCK, &signalfd_mask, NULL) == -1) + { + swWarn("sigprocmask() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + reactor->setHandle(reactor, SW_FD_SIGNAL, swSignalfd_onSignal); + reactor->add(reactor, signal_fd, SW_FD_SIGNAL); + return SW_OK; + } + else + { + swWarn("signalfd has been created"); + return SW_ERR; + } +} + +static void swSignalfd_clear() +{ + if (signal_fd) + { + if (sigprocmask(SIG_UNBLOCK, &signalfd_mask, NULL) < 0) + { + swSysError("sigprocmask(SIG_UNBLOCK) failed."); + } + close(signal_fd); + bzero(&signalfd_mask, sizeof(signalfd_mask)); + } + signal_fd = 0; +} + +static int swSignalfd_onSignal(swReactor *reactor, swEvent *event) +{ + int n; + struct signalfd_siginfo siginfo; + n = read(event->fd, &siginfo, sizeof(siginfo)); + if (n < 0) + { + swWarn("read from signalfd failed. Error: %s[%d]", strerror(errno), errno); + return SW_OK; + } + if (siginfo.ssi_signo >= SW_SIGNO_MAX) + { + swWarn("unknown signal[%d].", siginfo.ssi_signo); + return SW_OK; + } + if (signals[siginfo.ssi_signo].active) + { + if (signals[siginfo.ssi_signo].callback) + { + signals[siginfo.ssi_signo].callback(siginfo.ssi_signo); + } + else + { + swWarn("signal[%d] callback is null.", siginfo.ssi_signo); + } + } + + return SW_OK; +} + +#endif diff --git a/vendor/swoole/src/os/timer.c b/vendor/swoole/src/os/timer.c new file mode 100755 index 0000000..b794f2c --- /dev/null +++ b/vendor/swoole/src/os/timer.c @@ -0,0 +1,240 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Server.h" + +#ifdef HAVE_TIMERFD +#include <sys/timerfd.h> +#endif + +static int swSystemTimer_signal_set(swTimer *timer, long interval); +static int swSystemTimer_timerfd_set(swTimer *timer, long interval); +static int swSystemTimer_set(swTimer *timer, long new_interval); + +/** + * create timer + */ +int swSystemTimer_init(int interval, int use_pipe) +{ + swTimer *timer = &SwooleG.timer; + timer->lasttime = interval; + +#ifndef HAVE_TIMERFD + SwooleG.use_timerfd = 0; +#endif + + if (SwooleG.use_timerfd) + { + if (swSystemTimer_timerfd_set(timer, interval) < 0) + { + return SW_ERR; + } + timer->use_pipe = 0; + } + else + { + if (use_pipe) + { + if (swPipeNotify_auto(&timer->pipe, 0, 0) < 0) + { + return SW_ERR; + } + timer->fd = timer->pipe.getFd(&timer->pipe, 0); + timer->use_pipe = 1; + } + else + { + timer->fd = 1; + timer->use_pipe = 0; + } + + if (swSystemTimer_signal_set(timer, interval) < 0) + { + return SW_ERR; + } + swSignal_add(SIGALRM, swSystemTimer_signal_handler); + } + + if (timer->fd > 1) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_TIMER, swSystemTimer_event_handler); + SwooleG.main_reactor->add(SwooleG.main_reactor, SwooleG.timer.fd, SW_FD_TIMER); + } + timer->set = swSystemTimer_set; + return SW_OK; +} + +/** + * timerfd + */ +static int swSystemTimer_timerfd_set(swTimer *timer, long interval) +{ +#ifdef HAVE_TIMERFD + struct timeval now; + int sec = interval / 1000; + int msec = (((float) interval / 1000) - sec) * 1000; + + if (gettimeofday(&now, NULL) < 0) + { + swWarn("gettimeofday() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + + struct itimerspec timer_set; + bzero(&timer_set, sizeof(timer_set)); + + if (interval < 0) + { + if (timer->fd == 0) + { + return SW_OK; + } + } + else + { + timer_set.it_interval.tv_sec = sec; + timer_set.it_interval.tv_nsec = msec * 1000 * 1000; + + timer_set.it_value.tv_sec = now.tv_sec + sec; + timer_set.it_value.tv_nsec = (now.tv_usec * 1000) + timer_set.it_interval.tv_nsec; + + if (timer_set.it_value.tv_nsec > 1e9) + { + timer_set.it_value.tv_nsec = timer_set.it_value.tv_nsec - 1e9; + timer_set.it_value.tv_sec += 1; + } + + if (timer->fd == 0) + { + timer->fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC); + if (timer->fd < 0) + { + swWarn("timerfd_create() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + } + } + + if (timerfd_settime(timer->fd, TFD_TIMER_ABSTIME, &timer_set, NULL) == -1) + { + swWarn("timerfd_settime() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + return SW_OK; +#else + swWarn("kernel not support timerfd."); + return SW_ERR; +#endif +} + +/** + * setitimer + */ +static int swSystemTimer_signal_set(swTimer *timer, long interval) +{ + struct itimerval timer_set; + int sec = interval / 1000; + int msec = (((float) interval / 1000) - sec) * 1000; + + struct timeval now; + if (gettimeofday(&now, NULL) < 0) + { + swWarn("gettimeofday() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + bzero(&timer_set, sizeof(timer_set)); + + if (interval > 0) + { + timer_set.it_interval.tv_sec = sec; + timer_set.it_interval.tv_usec = msec * 1000; + + timer_set.it_value.tv_sec = sec; + timer_set.it_value.tv_usec = timer_set.it_interval.tv_usec; + + if (timer_set.it_value.tv_usec > 1e6) + { + timer_set.it_value.tv_usec = timer_set.it_value.tv_usec - 1e6; + timer_set.it_value.tv_sec += 1; + } + } + + if (setitimer(ITIMER_REAL, &timer_set, NULL) < 0) + { + swWarn("setitimer() failed. Error: %s[%d]", strerror(errno), errno); + return SW_ERR; + } + return SW_OK; +} + +void swSystemTimer_free(swTimer *timer) +{ + if (timer->use_pipe) + { + timer->pipe.close(&timer->pipe); + } + else if (timer->fd > 2) + { + if (close(timer->fd) < 0) + { + swSysError("close(%d) failed.", timer->fd); + } + } +} + +static long current_interval = 0; + +static int swSystemTimer_set(swTimer *timer, long new_interval) +{ + if (new_interval == current_interval) + { + return SW_OK; + } + current_interval = new_interval; + if (SwooleG.use_timerfd) + { + return swSystemTimer_timerfd_set(timer, new_interval); + } + else + { + return swSystemTimer_signal_set(timer, new_interval); + } +} + +int swSystemTimer_event_handler(swReactor *reactor, swEvent *event) +{ + uint64_t exp; + swTimer *timer = &SwooleG.timer; + + if (read(timer->fd, &exp, sizeof(uint64_t)) != sizeof(uint64_t)) + { + return SW_ERR; + } + SwooleG.signal_alarm = 0; + return swTimer_select(timer); +} + +void swSystemTimer_signal_handler(int sig) +{ + SwooleG.signal_alarm = 1; + uint64_t flag = 1; + + if (SwooleG.timer.use_pipe) + { + SwooleG.timer.pipe.write(&SwooleG.timer.pipe, &flag, sizeof(flag)); + } +} diff --git a/vendor/swoole/src/pipe/PipeBase.c b/vendor/swoole/src/pipe/PipeBase.c new file mode 100755 index 0000000..9b2ad80 --- /dev/null +++ b/vendor/swoole/src/pipe/PipeBase.c @@ -0,0 +1,93 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static int swPipeBase_read(swPipe *p, void *data, int length); +static int swPipeBase_write(swPipe *p, void *data, int length); +static int swPipeBase_getFd(swPipe *p, int isWriteFd); +static int swPipeBase_close(swPipe *p); + +typedef struct _swPipeBase +{ + int pipes[2]; +} swPipeBase; + +int swPipeBase_create(swPipe *p, int blocking) +{ + int ret; + swPipeBase *object = sw_malloc(sizeof(swPipeBase)); + if (object == NULL) + { + return -1; + } + p->blocking = blocking; + ret = pipe(object->pipes); + if (ret < 0) + { + swWarn("pipe() failed. Error: %s[%d]", strerror(errno), errno); + sw_free(object); + return -1; + } + else + { + //Nonblock + swSetNonBlock(object->pipes[0]); + swSetNonBlock(object->pipes[1]); + p->timeout = -1; + p->object = object; + p->read = swPipeBase_read; + p->write = swPipeBase_write; + p->getFd = swPipeBase_getFd; + p->close = swPipeBase_close; + } + return 0; +} + +static int swPipeBase_read(swPipe *p, void *data, int length) +{ + swPipeBase *object = p->object; + if (p->blocking == 1 && p->timeout > 0) + { + if (swSocket_wait(object->pipes[0], p->timeout * 1000, SW_EVENT_READ) < 0) + { + return SW_ERR; + } + } + return read(object->pipes[0], data, length); +} + +static int swPipeBase_write(swPipe *p, void *data, int length) +{ + swPipeBase *this = p->object; + return write(this->pipes[1], data, length); +} + +static int swPipeBase_getFd(swPipe *p, int isWriteFd) +{ + swPipeBase *this = p->object; + return (isWriteFd == 0) ? this->pipes[0] : this->pipes[1]; +} + +static int swPipeBase_close(swPipe *p) +{ + int ret1, ret2; + swPipeBase *this = p->object; + ret1 = close(this->pipes[0]); + ret2 = close(this->pipes[1]); + sw_free(this); + return 0 - ret1 - ret2; +} diff --git a/vendor/swoole/src/pipe/PipeEventfd.c b/vendor/swoole/src/pipe/PipeEventfd.c new file mode 100755 index 0000000..997323d --- /dev/null +++ b/vendor/swoole/src/pipe/PipeEventfd.c @@ -0,0 +1,142 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +#ifdef HAVE_EVENTFD +#include <sys/eventfd.h> + +static int swPipeEventfd_read(swPipe *p, void *data, int length); +static int swPipeEventfd_write(swPipe *p, void *data, int length); +static int swPipeEventfd_getFd(swPipe *p, int isWriteFd); +static int swPipeEventfd_close(swPipe *p); + +typedef struct _swPipeEventfd +{ + int event_fd; +} swPipeEventfd; + +int swPipeEventfd_create(swPipe *p, int blocking, int semaphore, int timeout) +{ + int efd; + int flag = 0; + swPipeEventfd *object = sw_malloc(sizeof(swPipeEventfd)); + if (object == NULL) + { + return -1; + } + + flag = EFD_NONBLOCK; + + if (blocking == 1) + { + if (timeout > 0) + { + flag = 0; + p->timeout = -1; + } + else + { + p->timeout = timeout; + } + } + +#ifdef EFD_SEMAPHORE + if (semaphore == 1) + { + flag |= EFD_SEMAPHORE; + } +#endif + + p->blocking = blocking; + efd = eventfd(0, flag); + if (efd < 0) + { + swWarn("eventfd create failed. Error: %s[%d]", strerror(errno), errno); + sw_free(object); + return -1; + } + else + { + p->object = object; + p->read = swPipeEventfd_read; + p->write = swPipeEventfd_write; + p->getFd = swPipeEventfd_getFd; + p->close = swPipeEventfd_close; + object->event_fd = efd; + } + return 0; +} + +static int swPipeEventfd_read(swPipe *p, void *data, int length) +{ + int ret = -1; + swPipeEventfd *object = p->object; + + //eventfd not support socket timeout + if (p->blocking == 1 && p->timeout > 0) + { + if (swSocket_wait(object->event_fd, p->timeout * 1000, SW_EVENT_READ) < 0) + { + return SW_ERR; + } + } + + while (1) + { + ret = read(object->event_fd, data, sizeof(uint64_t)); + if (ret < 0 && errno == EINTR) + { + continue; + } + break; + } + return ret; +} + +static int swPipeEventfd_write(swPipe *p, void *data, int length) +{ + int ret; + swPipeEventfd *this = p->object; + while (1) + { + ret = write(this->event_fd, data, sizeof(uint64_t)); + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + } + break; + } + return ret; +} + +static int swPipeEventfd_getFd(swPipe *p, int isWriteFd) +{ + return ((swPipeEventfd *) (p->object))->event_fd; +} + +static int swPipeEventfd_close(swPipe *p) +{ + int ret; + ret = close(((swPipeEventfd *) (p->object))->event_fd); + sw_free(p->object); + return ret; +} + +#endif diff --git a/vendor/swoole/src/pipe/PipeUnsock.c b/vendor/swoole/src/pipe/PipeUnsock.c new file mode 100755 index 0000000..31dbb7a --- /dev/null +++ b/vendor/swoole/src/pipe/PipeUnsock.c @@ -0,0 +1,135 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" + +static int swPipeUnsock_read(swPipe *p, void *data, int length); +static int swPipeUnsock_write(swPipe *p, void *data, int length); +static int swPipeUnsock_getFd(swPipe *p, int master); +static int swPipeUnsock_close(swPipe *p); + +typedef struct _swPipeUnsock +{ + /** + * master : socks[1] + * worker : socks[0] + */ + int socks[2]; + /** + * master pipe is closed + */ + uint8_t pipe_master_closed; + /** + * worker pipe is closed + */ + uint8_t pipe_worker_closed; +} swPipeUnsock; + +static int swPipeUnsock_getFd(swPipe *p, int master) +{ + swPipeUnsock *this = p->object; + return master == 1 ? this->socks[1] : this->socks[0]; +} + +static int swPipeUnsock_close(swPipe *p) +{ + swPipeUnsock *object = p->object; + int ret = swPipeUnsock_close_ext(p, 0); + sw_free(object); + return ret; +} + +int swPipeUnsock_close_ext(swPipe *p, int which) +{ + int ret1 = 0, ret2 = 0; + swPipeUnsock *object = p->object; + + if (which == SW_PIPE_CLOSE_MASTER) + { + if (object->pipe_master_closed) + { + return SW_ERR; + } + ret1 = close(object->socks[1]); + object->pipe_master_closed = 1; + } + else if (which == SW_PIPE_CLOSE_WORKER) + { + if (object->pipe_worker_closed) + { + return SW_ERR; + } + ret1 = close(object->socks[0]); + object->pipe_worker_closed = 1; + } + else + { + ret1 = swPipeUnsock_close_ext(p, SW_PIPE_CLOSE_MASTER); + ret2 = swPipeUnsock_close_ext(p, SW_PIPE_CLOSE_WORKER); + } + + return 0 - ret1 - ret2; +} + +int swPipeUnsock_create(swPipe *p, int blocking, int protocol) +{ + int ret; + swPipeUnsock *object = sw_malloc(sizeof(swPipeUnsock)); + if (object == NULL) + { + swWarn("malloc() failed."); + return SW_ERR; + } + bzero(object, sizeof(swPipeUnsock)); + p->blocking = blocking; + ret = socketpair(AF_UNIX, protocol, 0, object->socks); + if (ret < 0) + { + swWarn("socketpair() failed. Error: %s [%d]", strerror(errno), errno); + sw_free(object); + return SW_ERR; + } + else + { + //Nonblock + if (blocking == 0) + { + swSetNonBlock(object->socks[0]); + swSetNonBlock(object->socks[1]); + } + + int sbsize = SwooleG.socket_buffer_size; + swSocket_set_buffer_size(object->socks[0], sbsize); + swSocket_set_buffer_size(object->socks[1], sbsize); + + p->object = object; + p->read = swPipeUnsock_read; + p->write = swPipeUnsock_write; + p->getFd = swPipeUnsock_getFd; + p->close = swPipeUnsock_close; + } + return 0; +} + +static int swPipeUnsock_read(swPipe *p, void *data, int length) +{ + return read(((swPipeUnsock *) p->object)->socks[0], data, length); +} + +static int swPipeUnsock_write(swPipe *p, void *data, int length) +{ + return write(((swPipeUnsock *) p->object)->socks[1], data, length); +} diff --git a/vendor/swoole/src/protocol/Base.c b/vendor/swoole/src/protocol/Base.c new file mode 100755 index 0000000..ca668e2 --- /dev/null +++ b/vendor/swoole/src/protocol/Base.c @@ -0,0 +1,365 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Connection.h" + +/** + * return the package total length + */ +int swProtocol_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size) +{ + uint16_t length_offset = protocol->package_length_offset; + int32_t body_length; + /** + * no have length field, wait more data + */ + if (size < length_offset + protocol->package_length_size) + { + return 0; + } + body_length = swoole_unpack(protocol->package_length_type, data + length_offset); + //Length error + //Protocol length is not legitimate, out of bounds or exceed the allocated length + if (body_length < 0) + { + swWarn("invalid package, remote_addr=%s:%d, length=%d, size=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), body_length, size); + return SW_ERR; + } + //total package length + return protocol->package_body_offset + body_length; +} + +static sw_inline int swProtocol_split_package_by_eof(swProtocol *protocol, swConnection *conn, swString *buffer) +{ +#if SW_LOG_TRACE_OPEN > 0 + static int count; + count++; +#endif + + int eof_pos; + if (buffer->length - buffer->offset < protocol->package_eof_len) + { + eof_pos = -1; + } + else + { + eof_pos = swoole_strnpos(buffer->str + buffer->offset, buffer->length - buffer->offset, protocol->package_eof, protocol->package_eof_len); + } + + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[0] count=%d, length=%ld, size=%ld, offset=%ld.", count, buffer->length, buffer->size, (long)buffer->offset); + + //waiting for more data + if (eof_pos < 0) + { + buffer->offset = buffer->length - protocol->package_eof_len; + return buffer->length; + } + + uint32_t length = buffer->offset + eof_pos + protocol->package_eof_len; + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[4] count=%d, length=%d", count, length); + if (protocol->onPackage(conn, buffer->str, length) < 0) + { + return SW_ERR; + } + if (conn->removed) + { + return SW_OK; + } + + //there are remaining data + if (length < buffer->length) + { + uint32_t remaining_length = buffer->length - length; + char *remaining_data = buffer->str + length; + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[5] count=%d, remaining_length=%d", count, remaining_length); + + while (1) + { + if (remaining_length < protocol->package_eof_len) + { + goto wait_more_data; + } + eof_pos = swoole_strnpos(remaining_data, remaining_length, protocol->package_eof, protocol->package_eof_len); + if (eof_pos < 0) + { + wait_more_data: + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[1] count=%d, remaining_length=%d, length=%d", count, remaining_length, length); + memmove(buffer->str, remaining_data, remaining_length); + buffer->length = remaining_length; + buffer->offset = 0; + return SW_OK; + } + else + { + length = eof_pos + protocol->package_eof_len; + if (protocol->onPackage(conn, remaining_data, length) < 0) + { + return SW_ERR; + } + if (conn->removed) + { + return SW_OK; + } + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[2] count=%d, remaining_length=%d, length=%d", count, remaining_length, length); + remaining_data += length; + remaining_length -= length; + } + } + } + swTraceLog(SW_TRACE_EOF_PROTOCOL, "#[3] length=%ld, size=%ld, offset=%ld", buffer->length, buffer->size, (long)buffer->offset); + swString_clear(buffer); + return SW_OK; +} + +/** + * @return SW_ERR: close the connection + * @return SW_OK: continue + */ +int swProtocol_recv_check_length(swProtocol *protocol, swConnection *conn, swString *buffer) +{ + int package_length; + uint32_t recv_size; + char swap[SW_BUFFER_SIZE_STD]; + + if (conn->skip_recv) + { + conn->skip_recv = 0; + goto do_get_length; + } + + do_recv: + if (conn->active == 0) + { + return SW_OK; + } + if (buffer->offset > 0) + { + recv_size = buffer->offset - buffer->length; + } + else + { + recv_size = protocol->package_length_offset + protocol->package_length_size; + } + + int n = swConnection_recv(conn, buffer->str + buffer->length, recv_size, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("recv(%d, %d) failed.", conn->fd, recv_size); + return SW_OK; + case SW_CLOSE: + conn->close_errno = errno; + return SW_ERR; + default: + return SW_OK; + } + } + else if (n == 0) + { + return SW_ERR; + } + else + { + buffer->length += n; + + if (conn->recv_wait) + { + if (buffer->length >= buffer->offset) + { + do_dispatch: + if (protocol->onPackage(conn, buffer->str, buffer->offset) < 0) + { + return SW_ERR; + } + if (conn->removed) + { + return SW_OK; + } + conn->recv_wait = 0; + + int remaining_length = buffer->length - buffer->offset; + if (remaining_length > 0) + { + assert(remaining_length < sizeof(swap)); + memcpy(swap, buffer->str + buffer->offset, remaining_length); + memcpy(buffer->str, swap, remaining_length); + buffer->offset = 0; + buffer->length = remaining_length; + goto do_get_length; + } + else + { + swString_clear(buffer); + goto do_recv; + } + } + else + { + return SW_OK; + } + } + else + { + do_get_length: package_length = protocol->get_package_length(protocol, conn, buffer->str, buffer->length); + //invalid package, close connection. + if (package_length < 0) + { + return SW_ERR; + } + //no length + else if (package_length == 0) + { + return SW_OK; + } + else if (package_length > protocol->package_max_length) + { + swWarn("package is too big, remote_addr=%s:%d, length=%d.", swConnection_get_ip(conn), swConnection_get_port(conn), package_length); + return SW_ERR; + } + //get length success + else + { + if (buffer->size < package_length) + { + if (swString_extend(buffer, package_length) < 0) + { + return SW_ERR; + } + } + conn->recv_wait = 1; + buffer->offset = package_length; + + if (buffer->length >= package_length) + { + goto do_dispatch; + } + else + { + goto do_recv; + } + } + } + } + return SW_OK; +} + +/** + * @return SW_ERR: close the connection + * @return SW_OK: continue + */ +int swProtocol_recv_check_eof(swProtocol *protocol, swConnection *conn, swString *buffer) +{ + int recv_again = SW_FALSE; + int buf_size; + + recv_data: buf_size = buffer->size - buffer->length; + char *buf_ptr = buffer->str + buffer->length; + + if (buf_size > SW_BUFFER_SIZE_STD) + { + buf_size = SW_BUFFER_SIZE_STD; + } + + int n = swConnection_recv(conn, buf_ptr, buf_size, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("recv from socket#%d failed.", conn->fd); + return SW_OK; + case SW_CLOSE: + conn->close_errno = errno; + return SW_ERR; + default: + return SW_OK; + } + } + else if (n == 0) + { + return SW_ERR; + } + else + { + buffer->length += n; + + if (buffer->length < protocol->package_eof_len) + { + return SW_OK; + } + + if (protocol->split_by_eof) + { + if (swProtocol_split_package_by_eof(protocol, conn, buffer) == 0) + { + return SW_OK; + } + else + { + recv_again = SW_TRUE; + } + } + else if (memcmp(buffer->str + buffer->length - protocol->package_eof_len, protocol->package_eof, protocol->package_eof_len) == 0) + { + if (protocol->onPackage(conn, buffer->str, buffer->length) < 0) + { + return SW_ERR; + } + if (conn->removed) + { + return SW_OK; + } + swString_clear(buffer); + return SW_OK; + } + + //over max length, will discard + if (buffer->length == protocol->package_max_length) + { + swWarn("Package is too big. package_length=%d", (int )buffer->length); + return SW_ERR; + } + + //buffer is full, may have not read data + if (buffer->length == buffer->size) + { + recv_again = SW_TRUE; + if (buffer->size < protocol->package_max_length) + { + uint32_t extend_size = swoole_size_align(buffer->size * 2, SwooleG.pagesize); + if (extend_size > protocol->package_max_length) + { + extend_size = protocol->package_max_length; + } + if (swString_extend(buffer, extend_size) < 0) + { + return SW_ERR; + } + } + } + //no eof + if (recv_again) + { + goto recv_data; + } + } + return SW_OK; +} diff --git a/vendor/swoole/src/protocol/Base64.c b/vendor/swoole/src/protocol/Base64.c new file mode 100755 index 0000000..25adf4b --- /dev/null +++ b/vendor/swoole/src/protocol/Base64.c @@ -0,0 +1,133 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include <stdio.h> +#include <string.h> +#include "base64.h" + +/* BASE 64 encode table */ +static char base64en[] = +{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', }; + +#define BASE64_PAD '=' +#define BASE64DE_FIRST '+' +#define BASE64DE_LAST 'z' + +/* ASCII order for BASE 64 decode, -1 in unused character */ +static signed char base64de[] = { +/* '+', ',', '-', '.', '/', '0', '1', '2', */ + 62, -1, -1, -1, 63, 52, 53, 54, +/* '3', '4', '5', '6', '7', '8', '9', ':', */ + 55, 56, 57, 58, 59, 60, 61, -1, +/* ';', '<', '=', '>', '?', '@', 'A', 'B', */ + -1, -1, -1, -1, -1, -1, 0, 1, +/* 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', */ + 2, 3, 4, 5, 6, 7, 8, 9, +/* 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', */ + 10, 11, 12, 13, 14, 15, 16, 17, +/* 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', */ + 18, 19, 20, 21, 22, 23, 24, 25, +/* '[', '\', ']', '^', '_', '`', 'a', 'b', */ + -1, -1, -1, -1, -1, -1, 26, 27, +/* 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', */ + 28, 29, 30, 31, 32, 33, 34, 35, +/* 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', */ + 36, 37, 38, 39, 40, 41, 42, 43, +/* 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', */ + 44, 45, 46, 47, 48, 49, 50, 51, +}; + +int swBase64_encode(unsigned char *in, int inlen, char *out) +{ + int i, j; + for (i = j = 0; i < inlen; i++) + { + int s = i % 3; /* from 6/gcd(6, 8) */ + switch (s) + { + case 0: + out[j++] = base64en[(in[i] >> 2) & 0x3F]; + continue; + case 1: + out[j++] = base64en[((in[i - 1] & 0x3) << 4) + ((in[i] >> 4) & 0xF)]; + continue; + case 2: + out[j++] = base64en[((in[i - 1] & 0xF) << 2) + ((in[i] >> 6) & 0x3)]; + out[j++] = base64en[in[i] & 0x3F]; + } + } + /* move back */ + i -= 1; + /* check the last and add padding */ + if ((i % 3) == 0) + { + out[j++] = base64en[(in[i] & 0x3) << 4]; + out[j++] = BASE64_PAD; + out[j++] = BASE64_PAD; + } + else if ((i % 3) == 1) + { + out[j++] = base64en[(in[i] & 0xF) << 2]; + out[j++] = BASE64_PAD; + } + return BASE64_OK; +} + +int swBase64_decode(char *in, int inlen, unsigned char *out) +{ + int i, j; + for (i = j = 0; i < inlen; i++) + { + int c; + int s = i % 4; /* from 8/gcd(6, 8) */ + + if (in[i] == '=') + { + return BASE64_OK; + } + + if (in[i] < BASE64DE_FIRST || in[i] > BASE64DE_LAST || (c = base64de[in[i] - BASE64DE_FIRST]) == -1) + { + return BASE64_INVALID; + } + + switch (s) + { + case 0: + out[j] = c << 2; + continue; + case 1: + out[j++] += (c >> 4) & 0x3; + /* if not last char with padding */ + if (i < (inlen - 3) || in[inlen - 2] != '=') + out[j] = (c & 0xF) << 4; + continue; + case 2: + out[j++] += (c >> 2) & 0xF; + /* if not last char with padding */ + if (i < (inlen - 2) || in[inlen - 1] != '=') + out[j] = (c & 0x3) << 6; + continue; + case 3: + out[j++] += c; + } + } + return BASE64_OK; +} diff --git a/vendor/swoole/src/protocol/Http.c b/vendor/swoole/src/protocol/Http.c new file mode 100755 index 0000000..6cb7b11 --- /dev/null +++ b/vendor/swoole/src/protocol/Http.c @@ -0,0 +1,302 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +#include "swoole.h" +#include "http.h" +#include "http2.h" + +#include <assert.h> +#include <stddef.h> + +static const char *method_strings[] = +{ + "DELETE", "GET", "HEAD", "POST", "PUT", "PATCH", "CONNECT", "OPTIONS", "TRACE", "COPY", "LOCK", "MKCOL", "MOVE", + "PROPFIND", "PROPPATCH", "UNLOCK", "REPORT", "MKACTIVITY", "CHECKOUT", "MERGE", "M-SEARCH", "NOTIFY", + "SUBSCRIBE", "UNSUBSCRIBE", "PRI", +}; + +int swHttp_get_method(const char *method_str, int method_len) +{ + int i; + for (i = 0; i < HTTP_PRI; i++) + { + if (strncasecmp(method_strings[i], method_str, method_len) == 0) + { + return i + 1; + } + } + return -1; +} + +const char* swHttp_get_method_string(int method) +{ + if (method < 0 || method > HTTP_PRI) + { + return NULL; + } + return method_strings[method - 1]; +} + +/** + * only GET/POST + */ +int swHttpRequest_get_protocol(swHttpRequest *request) +{ + char *buf = request->buffer->str; + char *pe = buf + request->buffer->length; + + if (request->buffer->length < 16) + { + return SW_ERR; + } + + //http method + if (memcmp(buf, "GET", 3) == 0) + { + request->method = HTTP_GET; + request->offset = 4; + buf += 4; + } + else if (memcmp(buf, "POST", 4) == 0) + { + request->method = HTTP_POST; + request->offset = 5; + buf += 5; + } + else if (memcmp(buf, "PUT", 3) == 0) + { + request->method = HTTP_PUT; + request->offset = 4; + buf += 4; + } + else if (memcmp(buf, "PATCH", 5) == 0) + { + request->method = HTTP_PATCH; + request->offset = 6; + buf += 6; + } + else if (memcmp(buf, "DELETE", 6) == 0) + { + request->method = HTTP_DELETE; + request->offset = 7; + buf += 7; + } + else if (memcmp(buf, "HEAD", 4) == 0) + { + request->method = HTTP_HEAD; + request->offset = 5; + buf += 5; + } + else if (memcmp(buf, "OPTIONS", 7) == 0) + { + request->method = HTTP_OPTIONS; + request->offset = 8; + buf += 8; + } +#ifdef SW_USE_HTTP2 + //HTTP2 Connection Preface + else if (memcmp(buf, "PRI", 3) == 0) + { + request->method = HTTP_PRI; + if (memcmp(buf, SW_HTTP2_PRI_STRING, sizeof(SW_HTTP2_PRI_STRING) - 1) == 0) + { + request->buffer->offset = sizeof(SW_HTTP2_PRI_STRING) - 1; + return SW_OK; + } + else + { + goto _excepted; + } + } +#endif + else + { + _excepted: request->excepted = 1; + return SW_ERR; + } + + //http version + char *p; + char state = 0; + for (p = buf; p < pe; p++) + { + switch(state) + { + case 0: + if (isspace(*p)) + { + continue; + } + state = 1; + request->url_offset = p - request->buffer->str; + break; + case 1: + if (isspace(*p)) + { + state = 2; + request->url_length = p - request->buffer->str - request->url_offset; + continue; + } + break; + case 2: + if (isspace(*p)) + { + continue; + } + if (pe - p < 8) + { + return SW_ERR; + } + if (memcmp(p, "HTTP/1.1", 8) == 0) + { + request->version = HTTP_VERSION_11; + goto end; + } + else if (memcmp(p, "HTTP/1.0", 8) == 0) + { + request->version = HTTP_VERSION_10; + goto end; + } + else + { + goto _excepted; + } + default: + break; + } + } + end: p += 8; + request->buffer->offset = p - request->buffer->str; + return SW_OK; +} + +void swHttpRequest_free(swConnection *conn) +{ + swHttpRequest *request = conn->object; + if (!request) + { + return; + } + if (request->buffer) + { + swString_free(request->buffer); + } + bzero(request, sizeof(swHttpRequest)); + sw_free(request); + conn->object = NULL; +} + +/** + * POST content-length + */ +int swHttpRequest_get_content_length(swHttpRequest *request) +{ + swString *buffer = request->buffer; + char *buf = buffer->str + buffer->offset; + int len = buffer->length - buffer->offset; + + char *pe = buf + len; + char *p; + char *eol; + + for (p = buf; p < pe; p++) + { + if (*p == '\r' && pe - p > sizeof("Content-Length")) + { + if (strncasecmp(p, SW_STRL("\r\nContent-Length") - 1) == 0) + { + //strlen("\r\n") + strlen("Content-Length") + p += (2 + (sizeof("Content-Length:") - 1)); + //skip space + if (*p == ' ') + { + p++; + } + eol = strstr(p, "\r\n"); + if (eol == NULL) + { + return SW_ERR; + } + request->content_length = atoi(p); + return SW_OK; + } + } + } + + return SW_ERR; +} + +#ifdef SW_HTTP_100_CONTINUE +int swHttpRequest_has_expect_header(swHttpRequest *request) +{ + swString *buffer = request->buffer; + //char *buf = buffer->str + buffer->offset; + char *buf = buffer->str; + //int len = buffer->length - buffer->offset; + int len = buffer->length; + + char *pe = buf + len; + char *p; + + for (p = buf; p < pe; p++) + { + if (*p == '\r' && pe - p > sizeof("\r\nExpect")) + { + p += 2; + if (strncasecmp(p, SW_STRL("Expect") - 1) == 0) + { + p += sizeof("Expect: ") - 1; + if (strncasecmp(p, SW_STRL("100-continue") - 1) == 0) + { + return 1; + } + else + { + return 0; + } + } + else + { + p++; + } + } + } + return 0; +} +#endif + +/** + * header-length + */ +int swHttpRequest_get_header_length(swHttpRequest *request) +{ + swString *buffer = request->buffer; + char *buf = buffer->str + buffer->offset; + int len = buffer->length - buffer->offset; + + char *pe = buf + len; + char *p; + + for (p = buf; p < pe; p++) + { + if (*p == '\r' && p + 4 <= pe && memcmp(p, "\r\n\r\n", 4) == 0) + { + //strlen(header) + strlen("\r\n\r\n") + request->header_length = p - buffer->str + 4; + return SW_OK; + } + } + return SW_ERR; +} diff --git a/vendor/swoole/src/protocol/Http2.c b/vendor/swoole/src/protocol/Http2.c new file mode 100755 index 0000000..05c6930 --- /dev/null +++ b/vendor/swoole/src/protocol/Http2.c @@ -0,0 +1,142 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Connection.h" +#include "http2.h" + +int swHttp2_parse_frame(swProtocol *protocol, swConnection *conn, char *data, uint32_t length) +{ + int wait_body = 0; + int package_length = 0; + + while (length > 0) + { + if (wait_body) + { + if (length >= package_length) + { + protocol->onPackage(conn, data, package_length); + wait_body = 0; + data += package_length; + length -= package_length; + continue; + } + else + { + break; + } + } + else + { + package_length = protocol->get_package_length(protocol, conn, data, length); + if (package_length < 0) + { + return SW_ERR; + } + else if (package_length == 0) + { + return SW_OK; + } + else + { + wait_body = 1; + } + } + } + return SW_OK; +} + +int swHttp2_send_setting_frame(swProtocol *protocol, swConnection *conn) +{ + char setting_frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_SETTING_OPTION_SIZE * 3]; + char *p = setting_frame; + uint16_t id; + uint32_t value; + + swHttp2_set_frame_header(p, SW_HTTP2_TYPE_SETTINGS, SW_HTTP2_SETTING_OPTION_SIZE * 3, 0, 0); + p += SW_HTTP2_FRAME_HEADER_SIZE; + + id = htons(SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); + memcpy(p, &id, sizeof(id)); + value = htonl(SW_HTTP2_MAX_CONCURRENT_STREAMS); + memcpy(p + 2, &value, sizeof(value)); + p += SW_HTTP2_SETTING_OPTION_SIZE; + + id = htons(SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE); + memcpy(p, &id, sizeof(id)); + value = htonl(SW_HTTP2_MAX_WINDOW); + memcpy(p + 2, &value, sizeof(value)); + p += SW_HTTP2_SETTING_OPTION_SIZE; + + id = htons(SW_HTTP2_SETTINGS_MAX_FRAME_SIZE); + memcpy(p, &id, sizeof(id)); + value = htonl(SW_HTTP2_MAX_FRAME_SIZE); + memcpy(p + 2, &value, sizeof(value)); + + return swConnection_send(conn, setting_frame, sizeof(setting_frame), 0); +} + +/** + +-----------------------------------------------+ + | Length (24) | + +---------------+---------------+---------------+ + | Type (8) | Flags (8) | + +-+-------------+---------------+-------------------------------+ + |R| Stream Identifier (31) | + +=+=============================================================+ + | Frame Payload (0...) ... + +---------------------------------------------------------------+ + */ +int swHttp2_get_frame_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length) +{ + if (length < SW_HTTP2_FRAME_HEADER_SIZE) + { + return 0; + } + return swHttp2_get_length(buf) + SW_HTTP2_FRAME_HEADER_SIZE; +} + +char* swHttp2_get_type(int type) +{ + switch(type) + { + case SW_HTTP2_TYPE_DATA: + return "DATA"; + case SW_HTTP2_TYPE_HEADERS: + return "HEADERS"; + case SW_HTTP2_TYPE_PRIORITY: + return "PRIORITY"; + case SW_HTTP2_TYPE_RST_STREAM: + return "RST_STREAM"; + case SW_HTTP2_TYPE_SETTINGS: + return "SETTINGS"; + case SW_HTTP2_TYPE_PUSH_PROMISE: + return "PUSH_PROMISE"; + case SW_HTTP2_TYPE_PING: + return "PING"; + case SW_HTTP2_TYPE_GOAWAY: + return "GOAWAY"; + case SW_HTTP2_TYPE_WINDOW_UPDATE: + return "WINDOW_UPDATE"; + case SW_HTTP2_TYPE_CONTINUATION: + return "CONTINUATION"; + default: + return "UNKOWN"; + } +} diff --git a/vendor/swoole/src/protocol/MimeTypes.c b/vendor/swoole/src/protocol/MimeTypes.c new file mode 100755 index 0000000..7e5b22e --- /dev/null +++ b/vendor/swoole/src/protocol/MimeTypes.c @@ -0,0 +1,131 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +char* swoole_get_mimetype(char *file) +{ + char *dot; + dot = strrchr(file, '.'); + if (dot == NULL) + { + return "text/plain"; + } + if (strcasecmp(dot, ".html") == 0 || strcasecmp(dot, ".htm") == 0) + { + return "text/html"; + } + else if (strcasecmp(dot, ".xml") == 0) + { + return "text/xml"; + } + else if (strcasecmp(dot, ".css") == 0) + { + return "text/css"; + } + else if (strcasecmp(dot, ".text") == 0 || strcasecmp(dot, ".txt") == 0) + { + return "text/plain"; + } + else if (strcasecmp(dot, ".jpeg") == 0 || strcasecmp(dot, ".jpg") == 0) + { + return "image/jpeg"; + } + else if (strcasecmp(dot, ".png") == 0) + { + return "image/png"; + } + else if (strcasecmp(dot, ".gif") == 0) + { + return "image/gif"; + } + else if (strcasecmp(dot, ".json") == 0) + { + return "application/json"; + } + else if (strcasecmp(dot, ".js") == 0) + { + return "application/javascript"; + } + else if (strcasecmp(dot, ".pdf") == 0) + { + return "application/pdf"; + } + else if (strcasecmp(dot, ".doc") == 0) + { + return "application/msword"; + } + else if (strcasecmp(dot, ".xls") == 0) + { + return "application/vnd.ms-excel"; + } + else if (strcasecmp(dot, ".ppt") == 0) + { + return "application/vnd.ms-powerpoint"; + } + else if (strcasecmp(dot, ".docx") == 0) + { + return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; + } + else if (strcasecmp(dot, ".xlsx") == 0) + { + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + } + else if (strcasecmp(dot, ".pptx") == 0) + { + return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + } + else if (strcasecmp(dot, ".swf") == 0) + { + return "application/x-shockwave-flash"; + } + else if (strcasecmp(dot, ".zip") == 0) + { + return "application/zip"; + } + else if (strcasecmp(dot, ".mp3") == 0) + { + return "audio/mpeg"; + } + else if (strcasecmp(dot, ".mp4") == 0) + { + return "video/mp4"; + } + else if (strcasecmp(dot, ".mpeg") == 0 || strcasecmp(dot, ".mpg") == 0) + { + return "video/mpeg"; + } + else if (strcasecmp(dot, ".mov") == 0) + { + return "video/quicktime"; + } + else if (strcasecmp(dot, ".flv") == 0) + { + return "video/x-flv"; + } + else if (strcasecmp(dot, ".wmv") == 0) + { + return "video/x-ms-wmv"; + } + else if (strcasecmp(dot, ".avi") == 0) + { + return "video/x-msvideo"; + } + return "application/octet-stream"; +} + diff --git a/vendor/swoole/src/protocol/Mqtt.c b/vendor/swoole/src/protocol/Mqtt.c new file mode 100755 index 0000000..d251823 --- /dev/null +++ b/vendor/swoole/src/protocol/Mqtt.c @@ -0,0 +1,70 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "mqtt.h" + +void swMqtt_print_package(swMqtt_package *pkg) +{ + printf("type=%d, length=%d\n", pkg->type, pkg->length); +} + +static sw_inline int swMqtt_get_length(char *data, uint32_t size, int *count) +{ + uint8_t byte; + int mul = 1; + int length = 0; + + *count = 0; + do + { + byte = data[*count + 1]; + length += (byte & 127) * mul; + mul *= 128; + (*count)++; + } while ((byte & 128) != 0); + + return length; +} + +//int swMqtt_unpack(swMqtt_package *pkg, char *data, uint32_t size) +//{ +// uint8_t byte = data[0]; +// off_t offset; +// +// pkg->type = (byte & 0xF0) >> 4; +// pkg->dup = (byte & 0x08) >> 3; +// pkg->qos = (byte & 0x06) >> 1; +// pkg->retain = byte & 0x01; +// +// offset += 1; +// +// int count = 0; +// pkg->length = swMqtt_get_length(data, size, &count); +// offset += count + 1; +//} + +int swMqtt_get_package_length(swProtocol *protocol, swConnection *conn, char *data, uint32_t size) +{ + if (size < SW_MQTT_MIN_LENGTH) + { + return 0; + } + int count = 0; + int length = swMqtt_get_length(data, size, &count); + return length + count + 1; +} diff --git a/vendor/swoole/src/protocol/Redis.c b/vendor/swoole/src/protocol/Redis.c new file mode 100755 index 0000000..690cc44 --- /dev/null +++ b/vendor/swoole/src/protocol/Redis.c @@ -0,0 +1,182 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "redis.h" +#include "Connection.h" + +typedef struct +{ + uint8_t state; + + int n_lines_total; + int n_lines_received; + + int n_bytes_total; + int n_bytes_received; + + int offset; + +} swRedis_request; + +int swRedis_recv(swProtocol *protocol, swConnection *conn, swString *buffer) +{ + char *p, *pe; + int ret; + char *buf_ptr; + size_t buf_size; + + swRedis_request *request; + + if (conn->object == NULL) + { + request = sw_malloc(sizeof(swRedis_request)); + bzero(request, sizeof(swRedis_request)); + conn->object = request; + } + else + { + request = (swRedis_request *) conn->object; + } + + recv_data: buf_ptr = buffer->str + buffer->length; + buf_size = buffer->size - buffer->length; + + int n = swConnection_recv(conn, buf_ptr, buf_size, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("recv from socket#%d failed.", conn->fd); + return SW_OK; + case SW_CLOSE: + conn->close_errno = errno; + return SW_ERR; + default: + return SW_OK; + } + } + else if (n == 0) + { + return SW_ERR; + } + else + { + buffer->length += n; + + if (strncmp(buffer->str + buffer->length - SW_CRLF_LEN, SW_CRLF, SW_CRLF_LEN) != 0) + { + if (buffer->size < protocol->package_max_length) + { + uint32_t extend_size = swoole_size_align(buffer->size * 2, SwooleG.pagesize); + if (extend_size > protocol->package_max_length) + { + extend_size = protocol->package_max_length; + } + if (swString_extend(buffer, extend_size) < 0) + { + return SW_ERR; + } + } + else if (buffer->length == buffer->size) + { + package_too_big: + swWarn("Package is too big. package_length=%ld.", buffer->length); + return SW_ERR; + } + goto recv_data; + } + + p = buffer->str; + pe = p + buffer->length; + + do + { + switch(request->state) + { + case SW_REDIS_RECEIVE_TOTAL_LINE: + if (*p == '*' && (p = swRedis_get_number(p, &ret))) + { + request->n_lines_total = ret; + request->state = SW_REDIS_RECEIVE_LENGTH; + break; + } + /* no break */ + + case SW_REDIS_RECEIVE_LENGTH: + if (*p == '$' && (p = swRedis_get_number(p, &ret))) + { + if (ret < 0) + { + break; + } + if (ret + (p - buffer->str) > protocol->package_max_length) + { + goto package_too_big; + } + request->n_bytes_total = ret; + request->state = SW_REDIS_RECEIVE_STRING; + break; + } + //integer + else if (*p == ':' && (p = swRedis_get_number(p, &ret))) + { + break; + } + /* no break */ + + case SW_REDIS_RECEIVE_STRING: + if (pe - p < request->n_bytes_total - request->n_bytes_received) + { + request->n_bytes_received += pe - p; + return SW_OK; + } + else + { + p += request->n_bytes_total + SW_CRLF_LEN; + request->n_bytes_total = 0; + request->n_lines_received++; + request->state = SW_REDIS_RECEIVE_LENGTH; + + if (request->n_lines_received == request->n_lines_total) + { + if (protocol->onPackage(conn, buffer->str, buffer->length) < 0) + { + return SW_ERR; + } + if (conn->removed) + { + return SW_OK; + } + swString_clear(buffer); + bzero(request, sizeof(swRedis_request)); + return SW_OK; + } + } + break; + + default: + goto failed; + } + } while(p < pe); + } + failed: + swWarn("redis protocol error."); + return SW_ERR; +} diff --git a/vendor/swoole/src/protocol/SSL.c b/vendor/swoole/src/protocol/SSL.c new file mode 100755 index 0000000..e656794 --- /dev/null +++ b/vendor/swoole/src/protocol/SSL.c @@ -0,0 +1,1160 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Connection.h" + +#ifdef SW_USE_OPENSSL + +#include <openssl/crypto.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> + +static int openssl_init = 0; +static pthread_mutex_t *lock_array; + +static const SSL_METHOD *swSSL_get_method(int method); +static int swSSL_verify_callback(int ok, X509_STORE_CTX *x509_store); +#ifndef OPENSSL_NO_RSA +static RSA* swSSL_rsa_key_callback(SSL *ssl, int is_export, int key_length); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static int swSSL_set_default_dhparam(SSL_CTX* ssl_context); +#endif +static int swSSL_set_dhparam(SSL_CTX* ssl_context, char *file); +static int swSSL_set_ecdh_curve(SSL_CTX* ssl_context); + +#ifdef TLSEXT_TYPE_next_proto_neg +static int swSSL_npn_advertised(SSL *ssl, const uchar **out, uint32_t *outlen, void *arg); +#endif + +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +static int swSSL_alpn_advertised(SSL *ssl, const uchar **out, uchar *outlen, const uchar *in, uint32_t inlen, void *arg); +#endif + +static void swSSL_lock_callback(int mode, int type, char *file, int line); + +static const SSL_METHOD *swSSL_get_method(int method) +{ + switch (method) + { +#ifndef OPENSSL_NO_SSL3_METHOD + case SW_SSLv3_METHOD: + return SSLv3_method(); + case SW_SSLv3_SERVER_METHOD: + return SSLv3_server_method(); + case SW_SSLv3_CLIENT_METHOD: + return SSLv3_client_method(); +#endif + case SW_SSLv23_SERVER_METHOD: + return SSLv23_server_method(); + case SW_SSLv23_CLIENT_METHOD: + return SSLv23_client_method(); +/** + * openssl 1.1.0 + */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + case SW_TLSv1_METHOD: + return TLSv1_method(); + case SW_TLSv1_SERVER_METHOD: + return TLSv1_server_method(); + case SW_TLSv1_CLIENT_METHOD: + return TLSv1_client_method(); +#ifdef TLS1_1_VERSION + case SW_TLSv1_1_METHOD: + return TLSv1_1_method(); + case SW_TLSv1_1_SERVER_METHOD: + return TLSv1_1_server_method(); + case SW_TLSv1_1_CLIENT_METHOD: + return TLSv1_1_client_method(); +#endif +#ifdef TLS1_2_VERSION + case SW_TLSv1_2_METHOD: + return TLSv1_2_method(); + case SW_TLSv1_2_SERVER_METHOD: + return TLSv1_2_server_method(); + case SW_TLSv1_2_CLIENT_METHOD: + return TLSv1_2_client_method(); +#endif + case SW_DTLSv1_METHOD: + return DTLSv1_method(); + case SW_DTLSv1_SERVER_METHOD: + return DTLSv1_server_method(); + case SW_DTLSv1_CLIENT_METHOD: + return DTLSv1_client_method(); +#endif + case SW_SSLv23_METHOD: + default: + return SSLv23_method(); + } + return SSLv23_method(); +} + +void swSSL_init(void) +{ + if (openssl_init) + { + return; + } +#if OPENSSL_VERSION_NUMBER >= 0x10100003L && !defined(LIBRESSL_VERSION_NUMBER) + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); +#else + OPENSSL_config(NULL); + SSL_library_init(); + SSL_load_error_strings(); + OpenSSL_add_all_algorithms(); +#endif + openssl_init = 1; +} + +void swSSL_destroy() +{ + if (!openssl_init) + { + return; + } + + CRYPTO_set_locking_callback(NULL); + int i; + for (i = 0; i < CRYPTO_num_locks(); i++) + { + pthread_mutex_destroy(&(lock_array[i])); + } + openssl_init = 0; +#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 + CRYPTO_THREADID_set_callback(NULL); +#else + CRYPTO_set_id_callback(NULL); +#endif + CRYPTO_set_locking_callback(NULL); +} + +static void swSSL_lock_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + pthread_mutex_lock(&(lock_array[type])); + } + else + { + pthread_mutex_unlock(&(lock_array[type])); + } +} + +#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 +static void swSSL_id_callback(CRYPTO_THREADID * id) +{ + CRYPTO_THREADID_set_numeric(id, (ulong_t) pthread_self()); +} +#else +static ulong_t swSSL_id_callback(void) +{ + return (ulong_t) pthread_self(); +} +#endif + +void swSSL_init_thread_safety() +{ + int i; + lock_array = (pthread_mutex_t *) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + for (i = 0; i < CRYPTO_num_locks(); i++) + { + pthread_mutex_init(&(lock_array[i]), NULL); + } + +#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_0_0 + CRYPTO_THREADID_set_callback(swSSL_id_callback); +#else + CRYPTO_set_id_callback(swSSL_id_callback); +#endif + + CRYPTO_set_locking_callback((void (*)()) swSSL_lock_callback); +} + +void swSSL_server_http_advise(SSL_CTX* ssl_context, swSSL_config *cfg) +{ +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + SSL_CTX_set_alpn_select_cb(ssl_context, swSSL_alpn_advertised, cfg); +#endif + +#ifdef TLSEXT_TYPE_next_proto_neg + SSL_CTX_set_next_protos_advertised_cb(ssl_context, swSSL_npn_advertised, cfg); +#endif + + if (cfg->http) + { + SSL_CTX_set_session_id_context(ssl_context, (const unsigned char *) "HTTP", strlen("HTTP")); + SSL_CTX_set_session_cache_mode(ssl_context, SSL_SESS_CACHE_SERVER); + SSL_CTX_sess_set_cache_size(ssl_context, 1); + } +} + +int swSSL_server_set_cipher(SSL_CTX* ssl_context, swSSL_config *cfg) +{ +#ifndef TLS1_2_VERSION + return SW_OK; +#endif + SSL_CTX_set_read_ahead(ssl_context, 1); + + if (strlen(cfg->ciphers) > 0) + { + if (SSL_CTX_set_cipher_list(ssl_context, cfg->ciphers) == 0) + { + swWarn("SSL_CTX_set_cipher_list(\"%s\") failed", cfg->ciphers); + return SW_ERR; + } + if (cfg->prefer_server_ciphers) + { + SSL_CTX_set_options(ssl_context, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + } + +#ifndef OPENSSL_NO_RSA + SSL_CTX_set_tmp_rsa_callback(ssl_context, swSSL_rsa_key_callback); +#endif + + if (cfg->dhparam && strlen(cfg->dhparam) > 0) + { + swSSL_set_dhparam(ssl_context, cfg->dhparam); + } +#if OPENSSL_VERSION_NUMBER < 0x10100000L + else + { + swSSL_set_default_dhparam(ssl_context); + } +#endif + if (cfg->ecdh_curve && strlen(cfg->ecdh_curve) > 0) + { + swSSL_set_ecdh_curve(ssl_context); + } + return SW_OK; +} + +static int swSSL_passwd_callback(char *buf, int num, int verify, void *data) +{ + swSSL_option *option = (swSSL_option *) data; + if (option->passphrase) + { + size_t len = strlen(option->passphrase); + if (len < num - 1) + { + memcpy(buf, option->passphrase, len + 1); + return (int) len; + } + } + return 0; +} + +SSL_CTX* swSSL_get_context(swSSL_option *option) +{ + if (!openssl_init) + { + swSSL_init(); + } + + SSL_CTX *ssl_context = SSL_CTX_new(swSSL_get_method(option->method)); + if (ssl_context == NULL) + { + ERR_print_errors_fp(stderr); + return NULL; + } + + SSL_CTX_set_options(ssl_context, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); + SSL_CTX_set_options(ssl_context, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); + SSL_CTX_set_options(ssl_context, SSL_OP_MSIE_SSLV2_RSA_PADDING); + SSL_CTX_set_options(ssl_context, SSL_OP_SSLEAY_080_CLIENT_DH_BUG); + SSL_CTX_set_options(ssl_context, SSL_OP_TLS_D5_BUG); + SSL_CTX_set_options(ssl_context, SSL_OP_TLS_BLOCK_PADDING_BUG); + SSL_CTX_set_options(ssl_context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + SSL_CTX_set_options(ssl_context, SSL_OP_SINGLE_DH_USE); + + if (option->passphrase) + { + SSL_CTX_set_default_passwd_cb_userdata(ssl_context, option); + SSL_CTX_set_default_passwd_cb(ssl_context, swSSL_passwd_callback); + } + + if (option->cert_file) + { + /* + * set the local certificate from CertFile + */ + if (SSL_CTX_use_certificate_file(ssl_context, option->cert_file, SSL_FILETYPE_PEM) <= 0) + { + ERR_print_errors_fp(stderr); + return NULL; + } + /* + * if the crt file have many certificate entry ,means certificate chain + * we need call this function + */ + if (SSL_CTX_use_certificate_chain_file(ssl_context, option->cert_file) <= 0) + { + ERR_print_errors_fp(stderr); + return NULL; + } + /* + * set the private key from KeyFile (may be the same as CertFile) + */ + if (SSL_CTX_use_PrivateKey_file(ssl_context, option->key_file, SSL_FILETYPE_PEM) <= 0) + { + ERR_print_errors_fp(stderr); + return NULL; + } + /* + * verify private key + */ + if (!SSL_CTX_check_private_key(ssl_context)) + { + swWarn("Private key does not match the public certificate"); + return NULL; + } + } + + return ssl_context; +} + +static int swSSL_verify_callback(int ok, X509_STORE_CTX *x509_store) +{ +#if 0 + char *subject, *issuer; + int err, depth; + X509 *cert; + X509_NAME *sname, *iname; + X509_STORE_CTX_get_ex_data(x509_store, SSL_get_ex_data_X509_STORE_CTX_idx()); + cert = X509_STORE_CTX_get_current_cert(x509_store); + err = X509_STORE_CTX_get_error(x509_store); + depth = X509_STORE_CTX_get_error_depth(x509_store); + + sname = X509_get_subject_name(cert); + subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)"; + + iname = X509_get_issuer_name(cert); + issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)"; + swWarn("verify:%d, error:%d, depth:%d, subject:\"%s\", issuer:\"%s\"", ok, err, depth, subject, issuer); + + if (sname) + { + OPENSSL_free(subject); + } + if (iname) + { + OPENSSL_free(issuer); + } +#endif + + return 1; +} + +int swSSL_set_client_certificate(SSL_CTX *ctx, char *cert_file, int depth) +{ + STACK_OF(X509_NAME) *list; + + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, swSSL_verify_callback); + SSL_CTX_set_verify_depth(ctx, depth); + + if (SSL_CTX_load_verify_locations(ctx, cert_file, NULL) == 0) + { + swWarn("SSL_CTX_load_verify_locations(\"%s\") failed.", cert_file); + return SW_ERR; + } + + ERR_clear_error(); + list = SSL_load_client_CA_file(cert_file); + if (list == NULL) + { + swWarn("SSL_load_client_CA_file(\"%s\") failed.", cert_file); + return SW_ERR; + } + + ERR_clear_error(); + SSL_CTX_set_client_CA_list(ctx, list); + + return SW_OK; +} + +int swSSL_set_capath(swSSL_option *cfg, SSL_CTX *ctx) +{ + if (cfg->cafile || cfg->capath) + { + if (!SSL_CTX_load_verify_locations(ctx, cfg->cafile, cfg->capath)) + { + return SW_ERR; + } + } + else + { + if (!SSL_CTX_set_default_verify_paths(ctx)) + { + swWarn("Unable to set default verify locations and no CA settings specified."); + return SW_ERR; + } + } + + if (cfg->verify_depth > 0) + { + SSL_CTX_set_verify_depth(ctx, cfg->verify_depth); + } + + return SW_OK; +} + +#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT +static int swSSL_check_name(char *name, ASN1_STRING *pattern) +{ + char *s, *end; + size_t slen, plen; + + s = name; + slen = strlen(name); + + uchar *p = ASN1_STRING_data(pattern); + plen = ASN1_STRING_length(pattern); + + if (slen == plen && strncasecmp(s, (char*) p, plen) == 0) + { + return SW_OK; + } + + if (plen > 2 && p[0] == '*' && p[1] == '.') + { + plen -= 1; + p += 1; + + end = s + slen; + s = swoole_strlchr(s, end, '.'); + + if (s == NULL) + { + return SW_ERR; + } + + slen = end - s; + + if (plen == slen && strncasecmp(s, (char*) p, plen) == 0) + { + return SW_OK; + } + } + return SW_ERR; +} +#endif + +int swSSL_check_host(swConnection *conn, char *tls_host_name) +{ + X509 *cert = SSL_get_peer_certificate(conn->ssl); + if (cert == NULL) + { + return SW_ERR; + } + +#ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + /* X509_check_host() is only available in OpenSSL 1.0.2+ */ + if (X509_check_host(cert, tls_host_name, strlen(tls_host_name), 0, NULL) != 1) + { + swWarn("X509_check_host(): no match"); + goto failed; + } + goto found; +#else + int n, i; + X509_NAME *sname; + ASN1_STRING *str; + X509_NAME_ENTRY *entry; + GENERAL_NAME *altname; + STACK_OF(GENERAL_NAME) *altnames; + + /* + * As per RFC6125 and RFC2818, we check subjectAltName extension, + * and if it's not present - commonName in Subject is checked. + */ + altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + + if (altnames) + { + n = sk_GENERAL_NAME_num(altnames); + + for (i = 0; i < n; i++) + { + altname = sk_GENERAL_NAME_value(altnames, i); + + if (altname->type != GEN_DNS) + { + continue; + } + + str = altname->d.dNSName; + swTrace("SSL subjectAltName: \"%*s\"", ASN1_STRING_length(str), ASN1_STRING_data(str)); + + if (swSSL_check_name(tls_host_name, str) == SW_OK) + { + swTrace("SSL subjectAltName: match"); + GENERAL_NAMES_free(altnames); + goto found; + } + } + + swTrace("SSL subjectAltName: no match."); + GENERAL_NAMES_free(altnames); + goto failed; + } + + /* + * If there is no subjectAltName extension, check commonName + * in Subject. While RFC2818 requires to only check "most specific" + * CN, both Apache and OpenSSL check all CNs, and so do we. + */ + sname = X509_get_subject_name(cert); + + if (sname == NULL) + { + goto failed; + } + + i = -1; + for (;;) + { + i = X509_NAME_get_index_by_NID(sname, NID_commonName, i); + + if (i < 0) + { + break; + } + + entry = X509_NAME_get_entry(sname, i); + str = X509_NAME_ENTRY_get_data(entry); + + swTrace("SSL commonName: \"%*s\"", ASN1_STRING_length(str), ASN1_STRING_data(str)); + + if (swSSL_check_name(tls_host_name, str) == SW_OK) + { + swTrace("SSL commonName: match"); + goto found; + } + } + swTrace("SSL commonName: no match"); +#endif + + failed: X509_free(cert); + return SW_ERR; + + found: X509_free(cert); + return SW_OK; +} + +int swSSL_verify(swConnection *conn, int allow_self_signed) +{ + int err = SSL_get_verify_result(conn->ssl); + switch (err) + { + case X509_V_OK: + return SW_OK; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + if (allow_self_signed) + { + return SW_OK; + } + else + { + return SW_ERR; + } + default: + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SSL_VEFIRY_FAILED, "Could not verify peer: code:%d %s", err, X509_verify_cert_error_string(err)); + return SW_ERR; + } + + return SW_ERR; +} + +int swSSL_get_client_certificate(SSL *ssl, char *buffer, size_t length) +{ + long len; + BIO *bio; + X509 *cert; + + cert = SSL_get_peer_certificate(ssl); + if (cert == NULL) + { + return SW_ERR; + } + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + { + swWarn("BIO_new() failed."); + X509_free(cert); + return SW_ERR; + } + + if (PEM_write_bio_X509(bio, cert) == 0) + { + swWarn("PEM_write_bio_X509() failed."); + goto failed; + } + + len = BIO_pending(bio); + if (len < 0 && len > length) + { + swWarn("certificate length[%ld] is too big.", len); + goto failed; + } + + int n = BIO_read(bio, buffer, len); + + BIO_free(bio); + X509_free(cert); + + return n; + + failed: + + BIO_free(bio); + X509_free(cert); + + return SW_ERR; +} + +int swSSL_accept(swConnection *conn) +{ + int n = SSL_do_handshake(conn->ssl); + /** + * The TLS/SSL handshake was successfully completed + */ + if (n == 1) + { + conn->ssl_state = SW_SSL_STATE_READY; +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS + if (conn->ssl->s3) + { + conn->ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; + } +#endif +#endif + return SW_READY; + } + /** + * The TLS/SSL handshake was not successful but was shutdown. + */ + else if (n == 0) + { + return SW_ERROR; + } + + long err = SSL_get_error(conn->ssl, n); + if (err == SSL_ERROR_WANT_READ) + { + return SW_WAIT; + } + else if (err == SSL_ERROR_WANT_WRITE) + { + return SW_WAIT; + } + else if (err == SSL_ERROR_SSL) + { + swWarn("bad SSL client[%s:%d].", swConnection_get_ip(conn), swConnection_get_port(conn)); + return SW_ERROR; + } + //EOF was observed + else if (err == SSL_ERROR_SYSCALL && n == 0) + { + return SW_ERROR; + } + swWarn("SSL_do_handshake() failed. Error: %s[%ld|%d].", strerror(errno), err, errno); + return SW_ERROR; +} + +int swSSL_connect(swConnection *conn) +{ + int n = SSL_connect(conn->ssl); + if (n == 1) + { + conn->ssl_state = SW_SSL_STATE_READY; + conn->ssl_want_read = 0; + conn->ssl_want_write = 0; + +#ifdef SW_LOG_TRACE_OPEN + const char *ssl_version = SSL_get_version(conn->ssl); + const char *ssl_cipher = SSL_get_cipher_name(conn->ssl); + swTraceLog(SW_TRACE_SSL, "connected (%s %s)", ssl_version, ssl_cipher); +#endif + + return SW_OK; + } + + long err = SSL_get_error(conn->ssl, n); + if (err == SSL_ERROR_WANT_READ) + { + conn->ssl_want_read = 1; + conn->ssl_want_write = 0; + conn->ssl_state = SW_SSL_STATE_WAIT_STREAM; + return SW_OK; + } + else if (err == SSL_ERROR_WANT_WRITE) + { + conn->ssl_want_read = 0; + conn->ssl_want_write = 1; + conn->ssl_state = SW_SSL_STATE_WAIT_STREAM; + return SW_OK; + } + else if (err == SSL_ERROR_ZERO_RETURN) + { + swDebug("SSL_connect(fd=%d) closed.", conn->fd); + return SW_ERR; + } + else if (err == SSL_ERROR_SYSCALL) + { + if (n) + { + SwooleG.error = errno; + return SW_ERR; + } + } + swWarn("SSL_connect(fd=%d) failed. Error: %s[%ld|%d].", conn->fd, ERR_reason_error_string(err), err, errno); + + return SW_ERR; +} + +int swSSL_sendfile(swConnection *conn, int fd, off_t *offset, size_t size) +{ + char buf[SW_BUFFER_SIZE_BIG]; + int readn = size > sizeof(buf) ? sizeof(buf) : size; + + int ret; + int n = pread(fd, buf, readn, *offset); + + if (n > 0) + { + ret = swSSL_send(conn, buf, n); + if (ret < 0) + { + if (swConnection_error(errno) == SW_ERROR) + { + swSysError("write() failed."); + } + } + else + { + *offset += ret; + } + swTraceLog(SW_TRACE_REACTOR, "fd=%d, readn=%d, n=%d, ret=%d", fd, readn, n, ret); + return ret; + } + else + { + swSysError("pread() failed."); + return SW_ERR; + } +} + +void swSSL_close(swConnection *conn) +{ + int n, sslerr, err; + + if (SSL_in_init(conn->ssl)) + { + /* + * OpenSSL 1.0.2f complains if SSL_shutdown() is called during + * an SSL handshake, while previous versions always return 0. + * Avoid calling SSL_shutdown() if handshake wasn't completed. + */ + SSL_free(conn->ssl); + conn->ssl = NULL; + return; + } + + SSL_set_quiet_shutdown(conn->ssl, 1); + SSL_set_shutdown(conn->ssl, SSL_RECEIVED_SHUTDOWN | SSL_SENT_SHUTDOWN); + + n = SSL_shutdown(conn->ssl); + + swTrace("SSL_shutdown: %d", n); + + sslerr = 0; + + /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */ + if (n != 1 && ERR_peek_error()) + { + sslerr = SSL_get_error(conn->ssl, n); + swTrace("SSL_get_error: %d", sslerr); + } + + if (!(n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN)) + { + err = (sslerr == SSL_ERROR_SYSCALL) ? errno : 0; + swWarn("SSL_shutdown() failed. Error: %d:%d.", sslerr, err); + } + + SSL_free(conn->ssl); + conn->ssl = NULL; +} + +static sw_inline void swSSL_connection_error(swConnection *conn) +{ + int level = SW_LOG_NOTICE; + int reason = ERR_GET_REASON(ERR_peek_error()); + +#if 0 + /* handshake failures */ + switch (reason) + { + case SSL_R_BAD_CHANGE_CIPHER_SPEC: /* 103 */ + case SSL_R_BLOCK_CIPHER_PAD_IS_WRONG: /* 129 */ + case SSL_R_DIGEST_CHECK_FAILED: /* 149 */ + case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST: /* 151 */ + case SSL_R_EXCESSIVE_MESSAGE_SIZE: /* 152 */ + case SSL_R_LENGTH_MISMATCH:/* 159 */ + case SSL_R_NO_CIPHERS_PASSED:/* 182 */ + case SSL_R_NO_CIPHERS_SPECIFIED:/* 183 */ + case SSL_R_NO_COMPRESSION_SPECIFIED: /* 187 */ + case SSL_R_NO_SHARED_CIPHER:/* 193 */ + case SSL_R_RECORD_LENGTH_MISMATCH: /* 213 */ +#ifdef SSL_R_PARSE_TLSEXT + case SSL_R_PARSE_TLSEXT:/* 227 */ +#endif + case SSL_R_UNEXPECTED_MESSAGE:/* 244 */ + case SSL_R_UNEXPECTED_RECORD:/* 245 */ + case SSL_R_UNKNOWN_ALERT_TYPE: /* 246 */ + case SSL_R_UNKNOWN_PROTOCOL:/* 252 */ + case SSL_R_WRONG_VERSION_NUMBER:/* 267 */ + case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC: /* 281 */ +#ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG + case SSL_R_RENEGOTIATE_EXT_TOO_LONG:/* 335 */ + case SSL_R_RENEGOTIATION_ENCODING_ERR:/* 336 */ + case SSL_R_RENEGOTIATION_MISMATCH:/* 337 */ +#endif +#ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED + case SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED: /* 338 */ +#endif +#ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING + case SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING:/* 345 */ +#endif +#ifdef SSL_R_INAPPROPRIATE_FALLBACK + case SSL_R_INAPPROPRIATE_FALLBACK: /* 373 */ +#endif + case 1000:/* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ + case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE:/* 1010 */ + case SSL_R_SSLV3_ALERT_BAD_RECORD_MAC:/* 1020 */ + case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED:/* 1021 */ + case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW:/* 1022 */ + case SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE:/* 1030 */ + case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE:/* 1040 */ + case SSL_R_SSLV3_ALERT_NO_CERTIFICATE:/* 1041 */ + case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:/* 1042 */ + case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE: /* 1043 */ + case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:/* 1044 */ + case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:/* 1045 */ + case SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN:/* 1046 */ + case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER:/* 1047 */ + case SSL_R_TLSV1_ALERT_UNKNOWN_CA:/* 1048 */ + case SSL_R_TLSV1_ALERT_ACCESS_DENIED:/* 1049 */ + case SSL_R_TLSV1_ALERT_DECODE_ERROR:/* 1050 */ + case SSL_R_TLSV1_ALERT_DECRYPT_ERROR:/* 1051 */ + case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION:/* 1060 */ + case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:/* 1070 */ + case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY:/* 1071 */ + case SSL_R_TLSV1_ALERT_INTERNAL_ERROR:/* 1080 */ + case SSL_R_TLSV1_ALERT_USER_CANCELLED:/* 1090 */ + case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION: /* 1100 */ + level = SW_LOG_WARNING; + break; +#endif + + swoole_error_log(level, SW_ERROR_SSL_BAD_PROTOCOL, "SSL connection[%s:%d] protocol error[%d].", + swConnection_get_ip(conn), swConnection_get_port(conn), reason); +} + +ssize_t swSSL_recv(swConnection *conn, void *__buf, size_t __n) +{ + int n = SSL_read(conn->ssl, __buf, __n); + if (n < 0) + { + int _errno = SSL_get_error(conn->ssl, n); + switch (_errno) + { + case SSL_ERROR_WANT_READ: + conn->ssl_want_read = 1; + errno = EAGAIN; + return SW_ERR; + + case SSL_ERROR_WANT_WRITE: + conn->ssl_want_write = 1; + errno = EAGAIN; + return SW_ERR; + + case SSL_ERROR_SYSCALL: + return SW_ERR; + + case SSL_ERROR_SSL: + swSSL_connection_error(conn); + errno = SW_ERROR_SSL_BAD_CLIENT; + return SW_ERR; + + default: + break; + } + } + return n; +} + +ssize_t swSSL_send(swConnection *conn, void *__buf, size_t __n) +{ + int n = SSL_write(conn->ssl, __buf, __n); + if (n < 0) + { + int _errno = SSL_get_error(conn->ssl, n); + switch (_errno) + { + case SSL_ERROR_WANT_READ: + conn->ssl_want_read = 1; + errno = EAGAIN; + return SW_ERR; + + case SSL_ERROR_WANT_WRITE: + conn->ssl_want_write = 1; + errno = EAGAIN; + return SW_ERR; + + case SSL_ERROR_SYSCALL: + return SW_ERR; + + case SSL_ERROR_SSL: + swSSL_connection_error(conn); + errno = SW_ERROR_SSL_BAD_CLIENT; + return SW_ERR; + + default: + break; + } + } + return n; +} + +int swSSL_create(swConnection *conn, SSL_CTX* ssl_context, int flags) +{ + SSL *ssl = SSL_new(ssl_context); + if (ssl == NULL) + { + swWarn("SSL_new() failed."); + return SW_ERR; + } + if (!SSL_set_fd(ssl, conn->fd)) + { + long err = ERR_get_error(); + swWarn("SSL_set_fd() failed. Error: %s[%ld]", ERR_reason_error_string(err), err); + return SW_ERR; + } + if (flags & SW_SSL_CLIENT) + { + SSL_set_connect_state(ssl); + } + else + { + SSL_set_accept_state(ssl); + } + conn->ssl = ssl; + conn->ssl_state = 0; + return SW_OK; +} + +void swSSL_free_context(SSL_CTX* ssl_context) +{ + if (ssl_context) + { + SSL_CTX_free(ssl_context); + } +} + +#ifndef OPENSSL_NO_RSA +static RSA* swSSL_rsa_key_callback(SSL *ssl, int is_export, int key_length) +{ + static RSA *rsa_tmp = NULL; + if (rsa_tmp) + { + return rsa_tmp; + } + + BIGNUM *bn = BN_new(); + if (bn == NULL) + { + swWarn("allocation error generating RSA key."); + return NULL; + } + + if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) + || !RSA_generate_key_ex(rsa_tmp, key_length, bn, NULL)) + { + if (rsa_tmp) + { + RSA_free(rsa_tmp); + } + rsa_tmp = NULL; + } + BN_free(bn); + return rsa_tmp; +} +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static int swSSL_set_default_dhparam(SSL_CTX* ssl_context) +{ + DH *dh; + static unsigned char dh1024_p[] = + { 0xBB, 0xBC, 0x2D, 0xCA, 0xD8, 0x46, 0x74, 0x90, 0x7C, 0x43, 0xFC, 0xF5, 0x80, 0xE9, 0xCF, 0xDB, 0xD9, 0x58, 0xA3, + 0xF5, 0x68, 0xB4, 0x2D, 0x4B, 0x08, 0xEE, 0xD4, 0xEB, 0x0F, 0xB3, 0x50, 0x4C, 0x6C, 0x03, 0x02, 0x76, 0xE7, + 0x10, 0x80, 0x0C, 0x5C, 0xCB, 0xBA, 0xA8, 0x92, 0x26, 0x14, 0xC5, 0xBE, 0xEC, 0xA5, 0x65, 0xA5, 0xFD, 0xF1, + 0xD2, 0x87, 0xA2, 0xBC, 0x04, 0x9B, 0xE6, 0x77, 0x80, 0x60, 0xE9, 0x1A, 0x92, 0xA7, 0x57, 0xE3, 0x04, 0x8F, + 0x68, 0xB0, 0x76, 0xF7, 0xD3, 0x6C, 0xC8, 0xF2, 0x9B, 0xA5, 0xDF, 0x81, 0xDC, 0x2C, 0xA7, 0x25, 0xEC, 0xE6, + 0x62, 0x70, 0xCC, 0x9A, 0x50, 0x35, 0xD8, 0xCE, 0xCE, 0xEF, 0x9E, 0xA0, 0x27, 0x4A, 0x63, 0xAB, 0x1E, 0x58, + 0xFA, 0xFD, 0x49, 0x88, 0xD0, 0xF6, 0x5D, 0x14, 0x67, 0x57, 0xDA, 0x07, 0x1D, 0xF0, 0x45, 0xCF, 0xE1, 0x6B, + 0x9B }; + + static unsigned char dh1024_g[] = + { 0x02 }; + dh = DH_new(); + if (dh == NULL) + { + swWarn("DH_new() failed"); + return SW_ERR; + } + + dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); + dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); + + if (dh->p == NULL || dh->g == NULL) + { + DH_free(dh); + } + SSL_CTX_set_tmp_dh(ssl_context, dh); + DH_free(dh); + return SW_OK; +} +#endif + +static int swSSL_set_ecdh_curve(SSL_CTX* ssl_context) +{ +#if OPENSSL_VERSION_NUMBER >= 0x0090800fL +#ifndef OPENSSL_NO_ECDH + + EC_KEY *ecdh; + /* + * Elliptic-Curve Diffie-Hellman parameters are either "named curves" + * from RFC 4492 section 5.1.1, or explicitly described curves over + * binary fields. OpenSSL only supports the "named curves", which provide + * maximum interoperability. + */ + int nid = OBJ_sn2nid(SW_SSL_ECDH_CURVE); + if (nid == 0) + { + swWarn("Unknown curve name \"%s\"", SW_SSL_ECDH_CURVE); + return SW_ERR; + } + + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) + { + swWarn("Unable to create curve \"%s\"", SW_SSL_ECDH_CURVE); + return SW_ERR; + } + + SSL_CTX_set_options(ssl_context, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_tmp_ecdh(ssl_context, ecdh); + + EC_KEY_free(ecdh); +#endif +#endif + + return SW_OK; +} + +static int swSSL_set_dhparam(SSL_CTX* ssl_context, char *file) +{ + DH *dh; + BIO *bio; + + bio = BIO_new_file((char *) file, "r"); + if (bio == NULL) + { + swWarn("BIO_new_file(%s) failed", file); + return SW_ERR; + } + + dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + if (dh == NULL) + { + swWarn("PEM_read_bio_DHparams(%s) failed", file); + BIO_free(bio); + return SW_ERR; + } + + SSL_CTX_set_tmp_dh(ssl_context, dh); + + DH_free(dh); + BIO_free(bio); + + return SW_OK; +} + +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + +static int swSSL_alpn_advertised(SSL *ssl, const uchar **out, uchar *outlen, const uchar *in, uint32_t inlen, void *arg) +{ + unsigned int srvlen; + unsigned char *srv; + +#ifdef SW_USE_HTTP2 + swSSL_config *cfg = arg; + if (cfg->http_v2) + { + srv = (unsigned char *) SW_SSL_HTTP2_NPN_ADVERTISE SW_SSL_NPN_ADVERTISE; + srvlen = sizeof (SW_SSL_HTTP2_NPN_ADVERTISE SW_SSL_NPN_ADVERTISE) - 1; + } + else +#endif + { + srv = (unsigned char *) SW_SSL_NPN_ADVERTISE; + srvlen = sizeof (SW_SSL_NPN_ADVERTISE) - 1; + } + if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen, in, inlen) != OPENSSL_NPN_NEGOTIATED) + { + return SSL_TLSEXT_ERR_NOACK; + } + return SSL_TLSEXT_ERR_OK; +} +#endif + +#ifdef TLSEXT_TYPE_next_proto_neg + +static int swSSL_npn_advertised(SSL *ssl, const uchar **out, uint32_t *outlen, void *arg) +{ +#ifdef SW_USE_HTTP2 + swSSL_config *cfg = arg; + if (cfg->http_v2) + { + *out = (uchar *) SW_SSL_HTTP2_NPN_ADVERTISE SW_SSL_NPN_ADVERTISE; + *outlen = sizeof (SW_SSL_HTTP2_NPN_ADVERTISE SW_SSL_NPN_ADVERTISE) - 1; + } + else +#endif + { + *out = (uchar *) SW_SSL_NPN_ADVERTISE; + *outlen = sizeof(SW_SSL_NPN_ADVERTISE) - 1; + } + return SSL_TLSEXT_ERR_OK; +} +#endif + +#endif diff --git a/vendor/swoole/src/protocol/Sha1.c b/vendor/swoole/src/protocol/Sha1.c new file mode 100755 index 0000000..be7088f --- /dev/null +++ b/vendor/swoole/src/protocol/Sha1.c @@ -0,0 +1,150 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ +#include <string.h> + +#include "sha1.h" + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ + +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&(sha1_quadbyte)0xFF00FF00) \ + |(rol(block->l[i],8)&(sha1_quadbyte)0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif + +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +typedef union _BYTE64QUAD16 { + sha1_byte c[64]; + sha1_quadbyte l[16]; +} BYTE64QUAD16; +static void swSha1_transform(sha1_quadbyte state[5], sha1_byte buffer[64]); +/* Hash a single 512-bit block. This is the core of the algorithm. */ +static void swSha1_transform(sha1_quadbyte state[5], sha1_byte buffer[64]) { + sha1_quadbyte a, b, c, d, e; + BYTE64QUAD16 src; + BYTE64QUAD16 *block; + + /* slow but cast-align */ + memcpy(src.c, buffer, sizeof(sha1_byte) * 64); + block = &src; + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* swSha1_init - Initialize new context */ +void swSha1_init(SHA_CTX* context) { + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + +/* Run your data through this. */ +void swSha1_update(SHA_CTX *context, sha1_byte *data, unsigned int len) { + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + swSha1_transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + swSha1_transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ +void swSha1_final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX *context) { + sha1_quadbyte i, j; + sha1_byte finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (sha1_byte)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + swSha1_update(context, (sha1_byte *)"\200", 1); + while ((context->count[0] & 504) != 448) { + swSha1_update(context, (sha1_byte *)"\0", 1); + } + /* Should cause a swSha1_Transform() */ + swSha1_update(context, finalcount, 8); + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + digest[i] = (sha1_byte) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, SHA1_BLOCK_LENGTH); + memset(context->state, 0, SHA1_DIGEST_LENGTH); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +} diff --git a/vendor/swoole/src/protocol/Socks5.c b/vendor/swoole/src/protocol/Socks5.c new file mode 100755 index 0000000..b2e823f --- /dev/null +++ b/vendor/swoole/src/protocol/Socks5.c @@ -0,0 +1,154 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Client.h" +#include "socks5.h" + +char* swSocks5_strerror(int code) +{ + switch (code) + { + case 0x01: + return "General failure"; + case 0x02: + return "Connection not allowed by ruleset"; + case 0x03: + return "Network unreachable"; + case 0x04: + return "Host unreachable"; + case 0x05: + return "Connection refused by destination host"; + case 0x06: + return "TTL expired"; + case 0x07: + return "command not supported / protocol error"; + case 0x08: + return "address type not supported"; + default: + return "Unknown error"; + } +} + +int swSocks5_connect(swClient *cli, char *recv_data, int length) +{ + swSocks5 *ctx = cli->socks5_proxy; + char *buf = ctx->buf; + + if (ctx->state == SW_SOCKS5_STATE_HANDSHAKE) + { + uchar version = recv_data[0]; + uchar method = recv_data[1]; + if (version != SW_SOCKS5_VERSION_CODE) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_UNSUPPORT_VERSION, "SOCKS version is not supported."); + return SW_ERR; + } + if (method != ctx->method) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_UNSUPPORT_METHOD, "SOCKS authentication method not supported."); + return SW_ERR; + } + //authenticate request + if (method == SW_SOCKS5_METHOD_AUTH) + { + buf[0] = 0x01; + buf[1] = ctx->l_username; + + buf += 2; + memcpy(buf, ctx->username, ctx->l_username); + buf += ctx->l_username; + buf[0] = ctx->l_password; + memcpy(buf + 1, ctx->password, ctx->l_password); + + ctx->state = SW_SOCKS5_STATE_AUTH; + + return cli->send(cli, ctx->buf, ctx->l_username + ctx->l_password + 3, 0); + } + //send connect request + else + { + send_connect_request: + buf[0] = SW_SOCKS5_VERSION_CODE; + buf[1] = 0x01; + buf[2] = 0x00; + + ctx->state = SW_SOCKS5_STATE_CONNECT; + + if (ctx->dns_tunnel) + { + buf[3] = 0x03; + buf[4] = ctx->l_target_host; + buf += 5; + memcpy(buf, ctx->target_host, ctx->l_target_host); + buf += ctx->l_target_host; + *(uint16_t *) buf = htons(ctx->target_port); + return cli->send(cli, ctx->buf, ctx->l_target_host + 7, 0); + } + else + { + buf[3] = 0x01; + buf += 4; + *(uint32_t *) buf = htons(ctx->l_target_host); + buf += 4; + *(uint16_t *) buf = htons(ctx->target_port); + return cli->send(cli, ctx->buf, ctx->l_target_host + 7, 0); + } + } + } + else if (ctx->state == SW_SOCKS5_STATE_AUTH) + { + uchar version = recv_data[0]; + uchar status = recv_data[1]; + if (version != 0x01) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_UNSUPPORT_VERSION, "SOCKS version is not supported."); + return SW_ERR; + } + if (status != 0) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_AUTH_FAILED, "SOCKS username/password authentication failed."); + return SW_ERR; + } + goto send_connect_request; + } + else if (ctx->state == SW_SOCKS5_STATE_CONNECT) + { + uchar version = recv_data[0]; + if (version != SW_SOCKS5_VERSION_CODE) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_UNSUPPORT_VERSION, "SOCKS version is not supported."); + return SW_ERR; + } + uchar result = recv_data[1]; +// uchar reg = recv_data[2]; +// uchar type = recv_data[3]; +// uint32_t ip = *(uint32_t *) (recv_data + 4); +// uint16_t port = *(uint16_t *) (recv_data + 8); + if (result == 0) + { + ctx->state = SW_SOCKS5_STATE_READY; + } + else + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SOCKS5_SERVER_ERROR, "Socks5 server error, reason :%s.", swSocks5_strerror(result)); + } + return result; + } + return SW_OK; +} diff --git a/vendor/swoole/src/protocol/WebSocket.c b/vendor/swoole/src/protocol/WebSocket.c new file mode 100755 index 0000000..c65b687 --- /dev/null +++ b/vendor/swoole/src/protocol/WebSocket.c @@ -0,0 +1,312 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include "Server.h" +#include "websocket.h" +#include "Connection.h" + +#include <sys/time.h> + +/* The following is websocket data frame: + +-+-+-+-+-------+-+-------------+-------------------------------+ + 0 1 2 3 | + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | + +-+-+-+-+-------+-+-------------+-------------------------------+ + |F|R|R|R| opcode|M| Payload len | Extended payload length | + |I|S|S|S| (4) |A| (7) | (16/64) | + |N|V|V|V| |S| | (if payload len==126/127) | + | |1|2|3| |K| | | + +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + | Extended payload length continued, if payload len == 127 | + + - - - - - - - - - - - - - - - +-------------------------------+ + | |Masking-key, if MASK set to 1 | + +-------------------------------+-------------------------------+ + | Masking-key (continued) | Payload Data | + +-------------------------------- - - - - - - - - - - - - - - - + + : Payload Data continued ... : + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + | Payload Data continued ... | + +---------------------------------------------------------------+ + */ + +int swWebSocket_get_package_length(swProtocol *protocol, swConnection *conn, char *buf, uint32_t length) +{ + //need more data + if (length < SW_WEBSOCKET_HEADER_LEN) + { + return 0; + } + + char mask = (buf[1] >> 7) & 0x1; + //0-125 + uint64_t payload_length = buf[1] & 0x7f; + int header_length = SW_WEBSOCKET_HEADER_LEN; + buf += SW_WEBSOCKET_HEADER_LEN; + + //uint16_t, 2byte + if (payload_length == 0x7e) + { + if (length < 4) + { + return 0; + } + payload_length = ntohs(*((uint16_t *) buf)); + header_length += sizeof(uint16_t); + buf += sizeof(uint16_t); + } + //uint64_t, 8byte + else if (payload_length > 0x7e) + { + if (length < 10) + { + return 0; + } + payload_length = swoole_ntoh64(*((uint64_t *) buf)); + header_length += sizeof(uint64_t); + buf += sizeof(uint64_t); + } + if (mask) + { + if (length < header_length + 4) + { + return 0; + } + header_length += SW_WEBSOCKET_MASK_LEN; + } + swTrace("header_length=%d, payload_length=%d", (int)header_length, (int)payload_length); + return header_length + payload_length; +} + +void swWebSocket_encode(swString *buffer, char *data, size_t length, char opcode, int finish, int mask) +{ + int pos = 0; + char frame_header[16]; + + /** + * frame header + */ + frame_header[pos++] = FRAME_SET_FIN(finish) | FRAME_SET_OPCODE(opcode); + if (length < 126) + { + frame_header[pos++] = FRAME_SET_MASK(mask) | FRAME_SET_LENGTH(length, 0); + } + else + { + if (length < 65536) + { + frame_header[pos++] = FRAME_SET_MASK(mask) | 126; + } + else + { + frame_header[pos++] = FRAME_SET_MASK(mask) | 127; + frame_header[pos++] = FRAME_SET_LENGTH(length, 7); + frame_header[pos++] = FRAME_SET_LENGTH(length, 6); + frame_header[pos++] = FRAME_SET_LENGTH(length, 5); + frame_header[pos++] = FRAME_SET_LENGTH(length, 4); + frame_header[pos++] = FRAME_SET_LENGTH(length, 3); + frame_header[pos++] = FRAME_SET_LENGTH(length, 2); + } + frame_header[pos++] = FRAME_SET_LENGTH(length, 1); + frame_header[pos++] = FRAME_SET_LENGTH(length, 0); + } + swString_append_ptr(buffer, frame_header, pos); + + /** + * frame body + */ + if (data && length > 0) + { + if (mask) + { + char *_mask_data = SW_WEBSOCKET_MASK_DATA; + swString_append_ptr(buffer, _mask_data, SW_WEBSOCKET_MASK_LEN); + + char *_data = buffer->str + buffer->length; + swString_append_ptr(buffer, data, length); + + int i; + for (i = 0; i < length; i++) + { + _data[i] ^= _mask_data[i % SW_WEBSOCKET_MASK_LEN]; + } + } + else + { + swString_append_ptr(buffer, data, length); + } + } +} + +void swWebSocket_decode(swWebSocket_frame *frame, swString *data) +{ + memcpy(frame, data->str, SW_WEBSOCKET_HEADER_LEN); + + //0-125 + size_t payload_length = frame->header.LENGTH; + uint8_t header_length = SW_WEBSOCKET_HEADER_LEN; + char *buf = data->str + SW_WEBSOCKET_HEADER_LEN; + + //uint16_t, 2byte + if (frame->header.LENGTH == 0x7e) + { + payload_length = ntohs(*((uint16_t *) buf)); + header_length += 2; + } + //uint64_t, 8byte + else if (frame->header.LENGTH > 0x7e) + { + payload_length = swoole_ntoh64(*((uint64_t *) buf)); + header_length += 8; + } + + if (frame->header.MASK) + { + char *mask_key = frame->mask_key; + memcpy(mask_key, data->str + header_length, SW_WEBSOCKET_MASK_LEN); + header_length += SW_WEBSOCKET_MASK_LEN; + buf = data->str + header_length; + int i; + for (i = 0; i < payload_length; i++) + { + buf[i] ^= mask_key[i % SW_WEBSOCKET_MASK_LEN]; + } + } + frame->payload_length = payload_length; + frame->header_length = header_length; + frame->payload = data->str + header_length; +} + +void swWebSocket_print_frame(swWebSocket_frame *frame) +{ + printf("FIN: %x, RSV1: %d, RSV2: %d, RSV3: %d, opcode: %d, MASK: %d, length: %ld\n", frame->header.FIN, + frame->header.RSV1, frame->header.RSV2, frame->header.RSV3, frame->header.OPCODE, frame->header.MASK, + frame->payload_length); + + if (frame->payload_length) + { + printf("payload: %s\n", frame->payload); + } +} + +int swWebSocket_dispatch_frame(swConnection *conn, char *data, uint32_t length) +{ + swString frame; + bzero(&frame, sizeof(frame)); + frame.str = data; + frame.length = length; + + swString send_frame; + bzero(&send_frame, sizeof(send_frame)); + char buf[128]; + send_frame.str = buf; + send_frame.size = sizeof(buf); + + swWebSocket_frame ws; + swWebSocket_decode(&ws, &frame); + + swString *frame_buffer; + int frame_length; + swListenPort *port; + + size_t offset; + switch (ws.header.OPCODE) + { + case WEBSOCKET_OPCODE_CONTINUATION_FRAME: + frame_buffer = conn->websocket_buffer; + if (frame_buffer == NULL) + { + swWarn("bad frame[opcode=0]. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn)); + return SW_ERR; + } + offset = length - ws.payload_length; + frame_length = length - offset; + port = swServer_get_port(SwooleG.serv, conn->fd); + //frame data overflow + if (frame_buffer->length + frame_length > port->protocol.package_max_length) + { + swWarn("websocket frame is too big, remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn)); + return SW_ERR; + } + //merge incomplete data + swString_append_ptr(frame_buffer, data + offset, frame_length); + //frame is finished, do dispatch + if (ws.header.FIN) + { + swReactorThread_dispatch(conn, frame_buffer->str, frame_buffer->length); + swString_free(frame_buffer); + conn->websocket_buffer = NULL; + } + break; + + case WEBSOCKET_OPCODE_TEXT_FRAME: + case WEBSOCKET_OPCODE_BINARY_FRAME: + offset = length - ws.payload_length - SW_WEBSOCKET_HEADER_LEN; + data[offset] = 1; + data[offset + 1] = ws.header.OPCODE; + if (!ws.header.FIN) + { + if (conn->websocket_buffer) + { + swWarn("merging incomplete frame, bad request. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn)); + return SW_ERR; + } + conn->websocket_buffer = swString_dup(data + offset, length - offset); + } + else + { + swReactorThread_dispatch(conn, data + offset, length - offset); + } + break; + + case WEBSOCKET_OPCODE_PING: + if (length >= (sizeof(buf) - SW_WEBSOCKET_HEADER_LEN)) + { + swWarn("ping frame application data is too big. remote_addr=%s:%d.", swConnection_get_ip(conn), swConnection_get_port(conn)); + return SW_ERR; + } + else if (length == SW_WEBSOCKET_HEADER_LEN) + { + swWebSocket_encode(&send_frame, NULL, 0, WEBSOCKET_OPCODE_PONG, 1, 0); + } + else + { + offset = ws.header.MASK ? SW_WEBSOCKET_HEADER_LEN + SW_WEBSOCKET_MASK_LEN : SW_WEBSOCKET_HEADER_LEN; + swWebSocket_encode(&send_frame, data += offset, length - offset, WEBSOCKET_OPCODE_PONG, 1, 0); + } + swConnection_send(conn, send_frame.str, send_frame.length, 0); + break; + + case WEBSOCKET_OPCODE_PONG: + break; + + case WEBSOCKET_OPCODE_CONNECTION_CLOSE: + if (0x7d < (length - 2)) + { + return SW_ERR; + } + send_frame.str[0] = 0x88; + send_frame.str[1] = 0x00; + send_frame.length = 2; + swConnection_send(conn, send_frame.str, 2, 0); + return SW_ERR; + + default: + swWarn("unknown opcode [%d].", ws.header.OPCODE); + break; + } + return SW_OK; +} diff --git a/vendor/swoole/src/reactor/ReactorBase.c b/vendor/swoole/src/reactor/ReactorBase.c new file mode 100755 index 0000000..f37fdff --- /dev/null +++ b/vendor/swoole/src/reactor/ReactorBase.c @@ -0,0 +1,461 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include "Connection.h" +#include "async.h" +#include "Server.h" + +#ifdef SW_USE_MALLOC_TRIM +#ifdef __APPLE__ +#include <sys/malloc.h> +#else +#include <malloc.h> +#endif +#endif + +#ifdef SW_COROUTINE +#include "coroutine.h" +#endif + +static void swReactor_onTimeout_and_Finish(swReactor *reactor); +static void swReactor_onTimeout(swReactor *reactor); +static void swReactor_onFinish(swReactor *reactor); +static void swReactor_onBegin(swReactor *reactor); +static int swReactor_defer(swReactor *reactor, swCallback callback, void *data); + +int swReactor_create(swReactor *reactor, int max_event) +{ + int ret; + bzero(reactor, sizeof(swReactor)); + +#ifdef HAVE_EPOLL + ret = swReactorEpoll_create(reactor, max_event); +#elif defined(HAVE_KQUEUE) + ret = swReactorKqueue_create(reactor, max_event); +#elif defined(HAVE_POLL) + ret = swReactorPoll_create(reactor, max_event); +#else + ret = swReactorSelect_create(reactor); +#endif + + reactor->running = 1; + + reactor->setHandle = swReactor_setHandle; + + reactor->onFinish = swReactor_onFinish; + reactor->onTimeout = swReactor_onTimeout; + + reactor->write = swReactor_write; + reactor->defer = swReactor_defer; + reactor->close = swReactor_close; + + reactor->socket_array = swArray_new(1024, sizeof(swConnection)); + if (!reactor->socket_array) + { + swWarn("create socket array failed."); + return SW_ERR; + } + + return ret; +} + +int swReactor_setHandle(swReactor *reactor, int _fdtype, swReactor_handle handle) +{ + int fdtype = swReactor_fdtype(_fdtype); + + if (fdtype >= SW_MAX_FDTYPE) + { + swWarn("fdtype > SW_MAX_FDTYPE[%d]", SW_MAX_FDTYPE); + return SW_ERR; + } + + if (swReactor_event_read(_fdtype)) + { + reactor->handle[fdtype] = handle; + } + else if (swReactor_event_write(_fdtype)) + { + reactor->write_handle[fdtype] = handle; + } + else if (swReactor_event_error(_fdtype)) + { + reactor->error_handle[fdtype] = handle; + } + else + { + swWarn("unknow fdtype"); + return SW_ERR; + } + + return SW_OK; +} + +static int swReactor_defer(swReactor *reactor, swCallback callback, void *data) +{ + swDefer_callback *cb = sw_malloc(sizeof(swDefer_callback)); + if (!cb) + { + swWarn("malloc(%ld) failed.", sizeof(swDefer_callback)); + return SW_ERR; + } + cb->callback = callback; + cb->data = data; + LL_APPEND(reactor->defer_callback_list, cb); + return SW_OK; +} + +int swReactor_empty(swReactor *reactor) +{ + //timer + if (SwooleG.timer.num > 0) + { + return SW_FALSE; + } + + int empty = SW_FALSE; + //thread pool + if (SwooleAIO.init && reactor->event_num == 1 && SwooleAIO.task_num == 0) + { + empty = SW_TRUE; + } + //no event + else if (reactor->event_num == 0) + { + empty = SW_TRUE; + } + //coroutine + if (empty && reactor->can_exit && reactor->can_exit(reactor)) + { + empty = SW_TRUE; + } + return empty; +} + +/** + * execute when reactor timeout and reactor finish + */ +static void swReactor_onTimeout_and_Finish(swReactor *reactor) +{ + //check timer + if (reactor->check_timer) + { + swTimer_select(&SwooleG.timer); + } + //defer callback + swDefer_callback *cb, *tmp; + swDefer_callback *defer_callback_list = reactor->defer_callback_list; + reactor->defer_callback_list = NULL; + LL_FOREACH(defer_callback_list, cb) + { + cb->callback(cb->data); + } + LL_FOREACH_SAFE(defer_callback_list, cb, tmp) + { + sw_free(cb); + } + //callback at the end + if (reactor->idle_task.callback) + { + reactor->idle_task.callback(reactor->idle_task.data); + } +#ifdef SW_COROUTINE + //coro timeout + if (!swIsMaster()) + { + coro_handle_timeout(); + } +#endif + //server worker + swWorker *worker = SwooleWG.worker; + if (worker != NULL) + { + if (SwooleWG.wait_exit == 1) + { + swWorker_try_to_exit(); + } + } + //not server, the event loop is empty + if (SwooleG.serv == NULL && swReactor_empty(reactor)) + { + reactor->running = 0; + } + +#ifdef SW_USE_MALLOC_TRIM + if (SwooleG.serv && reactor->last_malloc_trim_time < SwooleG.serv->gs->now - SW_MALLOC_TRIM_INTERVAL) + { + malloc_trim(SW_MALLOC_TRIM_PAD); + reactor->last_malloc_trim_time = SwooleG.serv->gs->now; + } +#endif +} + +static void swReactor_onTimeout(swReactor *reactor) +{ + swReactor_onTimeout_and_Finish(reactor); + + if (reactor->disable_accept) + { + reactor->enable_accept(reactor); + reactor->disable_accept = 0; + } +} + +static void swReactor_onFinish(swReactor *reactor) +{ + //check signal + if (reactor->singal_no) + { + swSignal_callback(reactor->singal_no); + reactor->singal_no = 0; + } + swReactor_onTimeout_and_Finish(reactor); +} + +void swReactor_activate_future_task(swReactor *reactor) +{ + reactor->onBegin = swReactor_onBegin; +} + +static void swReactor_onBegin(swReactor *reactor) +{ + if (reactor->future_task.callback) + { + reactor->future_task.callback(reactor->future_task.data); + } +} + +int swReactor_close(swReactor *reactor, int fd) +{ + swConnection *socket = swReactor_get(reactor, fd); + if (socket->out_buffer) + { + swBuffer_free(socket->out_buffer); + } + if (socket->in_buffer) + { + swBuffer_free(socket->in_buffer); + } + if (socket->websocket_buffer) + { + swString_free(socket->websocket_buffer); + } + bzero(socket, sizeof(swConnection)); + socket->removed = 1; + swTraceLog(SW_TRACE_CLOSE, "fd=%d.", fd); + return close(fd); +} + +int swReactor_write(swReactor *reactor, int fd, void *buf, int n) +{ + int ret; + swConnection *socket = swReactor_get(reactor, fd); + swBuffer *buffer = socket->out_buffer; + + if (socket->fd == 0) + { + socket->fd = fd; + } + + if (socket->buffer_size == 0) + { + socket->buffer_size = SwooleG.socket_buffer_size; + } + + if (socket->nonblock == 0) + { + swoole_fcntl_set_option(fd, 1, -1); + socket->nonblock = 1; + } + + if (n > socket->buffer_size) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_PACKAGE_LENGTH_TOO_LARGE, "data is too large, cannot exceed buffer size."); + return SW_ERR; + } + + if (swBuffer_empty(buffer)) + { + if (socket->ssl_send) + { + goto do_buffer; + } + + do_send: + ret = swConnection_send(socket, buf, n, 0); + + if (ret > 0) + { + if (n == ret) + { + return ret; + } + else + { + buf += ret; + n -= ret; + goto do_buffer; + } + } +#ifdef HAVE_KQUEUE + else if (errno == EAGAIN || errno == ENOBUFS) +#else + else if (errno == EAGAIN) +#endif + { + do_buffer: + if (!socket->out_buffer) + { + buffer = swBuffer_new(sizeof(swEventData)); + if (!buffer) + { + swWarn("create worker buffer failed."); + return SW_ERR; + } + socket->out_buffer = buffer; + } + + socket->events |= SW_EVENT_WRITE; + + if (socket->events & SW_EVENT_READ) + { + if (reactor->set(reactor, fd, socket->fdtype | socket->events) < 0) + { + swSysError("reactor->set(%d, SW_EVENT_WRITE) failed.", fd); + } + } + else + { + if (reactor->add(reactor, fd, socket->fdtype | SW_EVENT_WRITE) < 0) + { + swSysError("reactor->add(%d, SW_EVENT_WRITE) failed.", fd); + } + } + + goto append_buffer; + } + else if (errno == EINTR) + { + goto do_send; + } + else + { + SwooleG.error = errno; + return SW_ERR; + } + } + else + { + append_buffer: if (buffer->length > socket->buffer_size) + { + if (socket->dontwait) + { + SwooleG.error = SW_ERROR_OUTPUT_BUFFER_OVERFLOW; + return SW_ERR; + } + else + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_OUTPUT_BUFFER_OVERFLOW, "socket#%d output buffer overflow.", fd); + swYield(); + swSocket_wait(fd, SW_SOCKET_OVERFLOW_WAIT, SW_EVENT_WRITE); + } + } + + if (swBuffer_append(buffer, buf, n) < 0) + { + return SW_ERR; + } + } + return SW_OK; +} + +int swReactor_onWrite(swReactor *reactor, swEvent *ev) +{ + int ret; + int fd = ev->fd; + + swConnection *socket = swReactor_get(reactor, fd); + swBuffer_trunk *chunk = NULL; + swBuffer *buffer = socket->out_buffer; + + //send to socket + while (!swBuffer_empty(buffer)) + { + chunk = swBuffer_get_trunk(buffer); + if (chunk->type == SW_CHUNK_CLOSE) + { + close_fd: + reactor->close(reactor, ev->fd); + return SW_OK; + } + else if (chunk->type == SW_CHUNK_SENDFILE) + { + ret = swConnection_onSendfile(socket, chunk); + } + else + { + ret = swConnection_buffer_send(socket); + } + + if (ret < 0) + { + if (socket->close_wait) + { + goto close_fd; + } + else if (socket->send_wait) + { + return SW_OK; + } + } + } + + //remove EPOLLOUT event + if (swBuffer_empty(buffer)) + { + if (socket->events & SW_EVENT_READ) + { + socket->events &= (~SW_EVENT_WRITE); + if (reactor->set(reactor, fd, socket->fdtype | socket->events) < 0) + { + swSysError("reactor->set(%d, SW_EVENT_READ) failed.", fd); + } + } + else + { + if (reactor->del(reactor, fd) < 0) + { + swSysError("reactor->del(%d) failed.", fd); + } + } + } + + return SW_OK; +} + +int swReactor_wait_write_buffer(swReactor *reactor, int fd) +{ + swConnection *conn = swReactor_get(reactor, fd); + swEvent event; + + if (conn->out_buffer) + { + swSetBlock(fd); + event.fd = fd; + return swReactor_onWrite(reactor, &event); + } + return SW_OK; +} diff --git a/vendor/swoole/src/reactor/ReactorEpoll.c b/vendor/swoole/src/reactor/ReactorEpoll.c new file mode 100755 index 0000000..55ae669 --- /dev/null +++ b/vendor/swoole/src/reactor/ReactorEpoll.c @@ -0,0 +1,304 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" + +#ifdef HAVE_EPOLL +#include <sys/epoll.h> +#ifndef EPOLLRDHUP +#define EPOLLRDHUP 0x2000 +#define NO_EPOLLRDHUP +#endif + +#ifndef EPOLLONESHOT +#define EPOLLONESHOT (1u << 30) +#endif + +typedef struct swReactorEpoll_s swReactorEpoll; + +typedef struct _swFd +{ + uint32_t fd; + uint32_t fdtype; +} swFd; + +static int swReactorEpoll_add(swReactor *reactor, int fd, int fdtype); +static int swReactorEpoll_set(swReactor *reactor, int fd, int fdtype); +static int swReactorEpoll_del(swReactor *reactor, int fd); +static int swReactorEpoll_wait(swReactor *reactor, struct timeval *timeo); +static void swReactorEpoll_free(swReactor *reactor); + +static sw_inline int swReactorEpoll_event_set(int fdtype) +{ + uint32_t flag = 0; + if (swReactor_event_read(fdtype)) + { + flag |= EPOLLIN; + } + if (swReactor_event_write(fdtype)) + { + flag |= EPOLLOUT; + } + if (swReactor_event_error(fdtype)) + { + //flag |= (EPOLLRDHUP); + flag |= (EPOLLRDHUP | EPOLLHUP | EPOLLERR); + } + return flag; +} + +struct swReactorEpoll_s +{ + int epfd; + struct epoll_event *events; +}; + +int swReactorEpoll_create(swReactor *reactor, int max_event_num) +{ + //create reactor object + swReactorEpoll *reactor_object = sw_malloc(sizeof(swReactorEpoll)); + if (reactor_object == NULL) + { + swWarn("malloc[0] failed."); + return SW_ERR; + } + bzero(reactor_object, sizeof(swReactorEpoll)); + reactor->object = reactor_object; + reactor->max_event_num = max_event_num; + + reactor_object->events = sw_calloc(max_event_num, sizeof(struct epoll_event)); + + if (reactor_object->events == NULL) + { + swWarn("malloc[1] failed."); + sw_free(reactor_object); + return SW_ERR; + } + //epoll create + reactor_object->epfd = epoll_create(512); + if (reactor_object->epfd < 0) + { + swWarn("epoll_create failed. Error: %s[%d]", strerror(errno), errno); + sw_free(reactor_object); + return SW_ERR; + } + //binding method + reactor->add = swReactorEpoll_add; + reactor->set = swReactorEpoll_set; + reactor->del = swReactorEpoll_del; + reactor->wait = swReactorEpoll_wait; + reactor->free = swReactorEpoll_free; + + return SW_OK; +} + +static void swReactorEpoll_free(swReactor *reactor) +{ + swReactorEpoll *object = reactor->object; + close(object->epfd); + sw_free(object->events); + sw_free(object); +} + +static int swReactorEpoll_add(swReactor *reactor, int fd, int fdtype) +{ + swReactorEpoll *object = reactor->object; + struct epoll_event e; + swFd fd_; + bzero(&e, sizeof(struct epoll_event)); + + fd_.fd = fd; + fd_.fdtype = swReactor_fdtype(fdtype); + e.events = swReactorEpoll_event_set(fdtype); + + swReactor_add(reactor, fd, fdtype); + + memcpy(&(e.data.u64), &fd_, sizeof(fd_)); + if (epoll_ctl(object->epfd, EPOLL_CTL_ADD, fd, &e) < 0) + { + swSysError("add events[fd=%d#%d, type=%d, events=%d] failed.", fd, reactor->id, fd_.fdtype, e.events); + swReactor_del(reactor, fd); + return SW_ERR; + } + + swTraceLog(SW_TRACE_EVENT, "add event[reactor_id=%d, fd=%d, events=%d]", reactor->id, fd, swReactor_events(fdtype)); + reactor->event_num++; + + return SW_OK; +} + +static int swReactorEpoll_del(swReactor *reactor, int fd) +{ + swReactorEpoll *object = reactor->object; + if (epoll_ctl(object->epfd, EPOLL_CTL_DEL, fd, NULL) < 0) + { + swSysError("epoll remove fd[%d#%d] failed.", fd, reactor->id); + return SW_ERR; + } + + swTraceLog(SW_TRACE_REACTOR, "remove event[reactor_id=%d|fd=%d]", reactor->id, fd); + reactor->event_num = reactor->event_num <= 0 ? 0 : reactor->event_num - 1; + swReactor_del(reactor, fd); + + return SW_OK; +} + +static int swReactorEpoll_set(swReactor *reactor, int fd, int fdtype) +{ + swReactorEpoll *object = reactor->object; + swFd fd_; + struct epoll_event e; + int ret; + + bzero(&e, sizeof(struct epoll_event)); + e.events = swReactorEpoll_event_set(fdtype); + + if (e.events & EPOLLOUT) + { + assert(fd > 2); + } + + fd_.fd = fd; + fd_.fdtype = swReactor_fdtype(fdtype); + memcpy(&(e.data.u64), &fd_, sizeof(fd_)); + + ret = epoll_ctl(object->epfd, EPOLL_CTL_MOD, fd, &e); + if (ret < 0) + { + swSysError("reactor#%d->set(fd=%d|type=%d|events=%d) failed.", reactor->id, fd, fd_.fdtype, e.events); + return SW_ERR; + } + swTraceLog(SW_TRACE_EVENT, "set event[reactor_id=%d, fd=%d, events=%d]", reactor->id, fd, swReactor_events(fdtype)); + //execute parent method + swReactor_set(reactor, fd, fdtype); + return SW_OK; +} + +static int swReactorEpoll_wait(swReactor *reactor, struct timeval *timeo) +{ + swEvent event; + swReactorEpoll *object = reactor->object; + swReactor_handle handle; + int i, n, ret, msec; + + int reactor_id = reactor->id; + int epoll_fd = object->epfd; + int max_event_num = reactor->max_event_num; + struct epoll_event *events = object->events; + + if (reactor->timeout_msec == 0) + { + if (timeo == NULL) + { + reactor->timeout_msec = -1; + } + else + { + reactor->timeout_msec = timeo->tv_sec * 1000 + timeo->tv_usec / 1000; + } + } + + reactor->start = 1; + + while (reactor->running > 0) + { + if (reactor->onBegin != NULL) + { + reactor->onBegin(reactor); + } + msec = reactor->timeout_msec; + n = epoll_wait(epoll_fd, events, max_event_num, msec); + if (n < 0) + { + if (swReactor_error(reactor) < 0) + { + swWarn("[Reactor#%d] epoll_wait failed. Error: %s[%d]", reactor_id, strerror(errno), errno); + return SW_ERR; + } + else + { + continue; + } + } + else if (n == 0) + { + if (reactor->onTimeout != NULL) + { + reactor->onTimeout(reactor); + } + continue; + } + for (i = 0; i < n; i++) + { + event.fd = events[i].data.u64; + event.from_id = reactor_id; + event.type = events[i].data.u64 >> 32; + event.socket = swReactor_get(reactor, event.fd); + + //read + if ((events[i].events & EPOLLIN) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_READ, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("EPOLLIN handle failed. fd=%d.", event.fd); + } + } + //write + if ((events[i].events & EPOLLOUT) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_WRITE, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("EPOLLOUT handle failed. fd=%d.", event.fd); + } + } + //error +#ifndef NO_EPOLLRDHUP + if ((events[i].events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP)) && !event.socket->removed) +#else + if ((events[i].events & (EPOLLERR | EPOLLHUP)) && !event.socket->removed) +#endif + { + //ignore ERR and HUP, because event is already processed at IN and OUT handler. + if ((events[i].events & EPOLLIN) || (events[i].events & EPOLLOUT)) + { + continue; + } + handle = swReactor_getHandle(reactor, SW_EVENT_ERROR, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("EPOLLERR handle failed. fd=%d.", event.fd); + } + } + } + + if (reactor->onFinish != NULL) + { + reactor->onFinish(reactor); + } + if (reactor->once) + { + break; + } + } + return 0; +} + +#endif diff --git a/vendor/swoole/src/reactor/ReactorKqueue.c b/vendor/swoole/src/reactor/ReactorKqueue.c new file mode 100755 index 0000000..02b9c2d --- /dev/null +++ b/vendor/swoole/src/reactor/ReactorKqueue.c @@ -0,0 +1,375 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "swoole.h" +#include <string.h> + +#ifdef IDE_HELPER +#ifdef HAVE_KQUEUE +#include <sys/event.h> +#else +#include "helper/kqueue.h" +#define HAVE_KQUEUE +#endif +#else +#ifdef HAVE_KQUEUE +#include <sys/event.h> +#endif +#endif + +#ifdef HAVE_KQUEUE + +typedef struct swReactorKqueue_s swReactorKqueue; +typedef struct _swFd +{ + uint32_t fd; + uint32_t fdtype; +} swFd; + +static int swReactorKqueue_add(swReactor *reactor, int fd, int fdtype); +static int swReactorKqueue_set(swReactor *reactor, int fd, int fdtype); +static int swReactorKqueue_del(swReactor *reactor, int fd); +static int swReactorKqueue_wait(swReactor *reactor, struct timeval *timeo); +static void swReactorKqueue_free(swReactor *reactor); + +struct swReactorKqueue_s +{ + int epfd; + int event_max; + struct kevent *events; +}; + +int swReactorKqueue_create(swReactor *reactor, int max_event_num) +{ + //create reactor object + swReactorKqueue *reactor_object = sw_malloc(sizeof(swReactorKqueue)); + if (reactor_object == NULL) + { + swTrace("[swReactorKqueueCreate] malloc[0] fail\n"); + return SW_ERR; + } + bzero(reactor_object, sizeof(swReactorKqueue)); + + reactor->object = reactor_object; + reactor->max_event_num = max_event_num; + reactor_object->events = sw_calloc(max_event_num, sizeof(struct kevent)); + + if (reactor_object->events == NULL) + { + swTrace("[swReactorKqueueCreate] malloc[1] fail\n"); + return SW_ERR; + } + //kqueue create + reactor_object->event_max = max_event_num; + reactor_object->epfd = kqueue(); + if (reactor_object->epfd < 0) + { + swTrace("[swReactorKqueueCreate] kqueue_create[0] fail\n"); + return SW_ERR; + } + + //binding method + reactor->add = swReactorKqueue_add; + reactor->set = swReactorKqueue_set; + reactor->del = swReactorKqueue_del; + reactor->wait = swReactorKqueue_wait; + reactor->free = swReactorKqueue_free; + + return SW_OK; +} + +static void swReactorKqueue_free(swReactor *reactor) +{ + swReactorKqueue *this = reactor->object; + close(this->epfd); + sw_free(this->events); + sw_free(this); +} + +static int swReactorKqueue_add(swReactor *reactor, int fd, int fdtype) +{ + swReactorKqueue *this = reactor->object; + struct kevent e; + swFd fd_; + int ret; + bzero(&e, sizeof(e)); + + int fflags = 0; + fd_.fd = fd; + fd_.fdtype = swReactor_fdtype(fdtype); + + swReactor_add(reactor, fd, fdtype); + + if (swReactor_event_read(fdtype)) + { +#ifdef NOTE_EOF + fflags = NOTE_EOF; +#endif + EV_SET(&e, fd, EVFILT_READ, EV_ADD, fflags, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("add events[fd=%d#%d, type=%d, events=read] failed.", fd, reactor->id, fd_.fdtype); + swReactor_del(reactor, fd); + return SW_ERR; + } + } + + if (swReactor_event_write(fdtype)) + { + EV_SET(&e, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("add events[fd=%d#%d, type=%d, events=write] failed.", fd, reactor->id, fd_.fdtype); + swReactor_del(reactor, fd); + return SW_ERR; + } + } + + swTrace("[THREAD #%d]EP=%d|FD=%d, events=%d", SwooleTG.id, this->epfd, fd, fdtype); + reactor->event_num++; + return SW_OK; +} + +static int swReactorKqueue_set(swReactor *reactor, int fd, int fdtype) +{ + swReactorKqueue *this = reactor->object; + struct kevent e; + swFd fd_; + int ret; + bzero(&e, sizeof(e)); + + int fflags = 0; + fd_.fd = fd; + fd_.fdtype = swReactor_fdtype(fdtype); + + if (swReactor_event_read(fdtype)) + { +#ifdef NOTE_EOF + fflags = NOTE_EOF; +#endif + EV_SET(&e, fd, EVFILT_READ, EV_ADD, fflags, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->set(%d, SW_EVENT_READ) failed.", fd); + return SW_ERR; + } + } + else + { + EV_SET(&e, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->del(%d, SW_EVENT_READ) failed.", fd); + return SW_ERR; + } + } + + if (swReactor_event_write(fdtype)) + { + EV_SET(&e, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->set(%d, SW_EVENT_WRITE) failed.", fd); + return SW_ERR; + } + } + else + { + EV_SET(&e, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + memcpy(&e.udata, &fd_, sizeof(swFd)); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->del(%d, SW_EVENT_WRITE) failed.", fd); + return SW_ERR; + } + } + swTrace("[THREAD #%d]EP=%d|FD=%d, events=%d", SwooleTG.id, this->epfd, fd, fdtype); + //execute parent method + swReactor_set(reactor, fd, fdtype); + return SW_OK; +} + +static int swReactorKqueue_del(swReactor *reactor, int fd) +{ + swReactorKqueue *this = reactor->object; + struct kevent e; + int ret; + + swConnection *socket = swReactor_get(reactor, fd); + + if (socket->events & SW_EVENT_READ) + { + EV_SET(&e, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->del(%d, SW_EVENT_READ) failed.", fd); + return SW_ERR; + } + } + + if (socket->events & SW_EVENT_WRITE) + { + EV_SET(&e, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + ret = kevent(this->epfd, &e, 1, NULL, 0, NULL); + if (ret < 0) + { + swSysError("kqueue->del(%d, SW_EVENT_WRITE) failed.", fd); + return SW_ERR; + } + } + + swTrace("[THREAD #%d]EP=%d|FD=%d", SwooleTG.id, this->epfd, fd); + reactor->event_num = reactor->event_num <= 0 ? 0 : reactor->event_num - 1; + swReactor_del(reactor, fd); + return SW_OK; +} + +static int swReactorKqueue_wait(swReactor *reactor, struct timeval *timeo) +{ + swEvent event; + swFd fd_; + swReactorKqueue *object = reactor->object; + swReactor_handle handle; + + int i, n, ret; + struct timespec t; + struct timespec *t_ptr; + bzero(&t, sizeof(t)); + + if (reactor->timeout_msec == 0) + { + if (timeo == NULL) + { + reactor->timeout_msec = -1; + } + else + { + reactor->timeout_msec = timeo->tv_sec * 1000 + timeo->tv_usec / 1000; + } + } + + reactor->start = 1; + + while (reactor->running > 0) + { + if (reactor->onBegin != NULL) + { + reactor->onBegin(reactor); + } + if (reactor->timeout_msec > 0) + { + t.tv_sec = reactor->timeout_msec / 1000; + t.tv_nsec = (reactor->timeout_msec - t.tv_sec * 1000) * 1000; + t_ptr = &t; + } + else + { + t_ptr = NULL; + } + + n = kevent(object->epfd, NULL, 0, object->events, object->event_max, t_ptr); + if (n < 0) + { + swTrace("kqueue error.EP=%d | Errno=%d\n", object->epfd, errno); + if (swReactor_error(reactor) < 0) + { + swWarn("Kqueue[#%d] Error: %s[%d]", reactor->id, strerror(errno), errno); + return SW_ERR; + } + else + { + continue; + } + } + else if (n == 0) + { + if (reactor->onTimeout != NULL) + { + reactor->onTimeout(reactor); + } + continue; + } + + for (i = 0; i < n; i++) + { + swTrace("n %d events.", n); + if (object->events[i].udata) + { + memcpy(&fd_, &(object->events[i].udata), sizeof(fd_)); + event.fd = fd_.fd; + event.from_id = reactor->id; + event.type = fd_.fdtype; + event.socket = swReactor_get(reactor, event.fd); + + //read + if (object->events[i].filter == EVFILT_READ) + { + if (event.socket->removed) + { + continue; + } + handle = swReactor_getHandle(reactor, SW_EVENT_READ, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("kqueue event read socket#%d handler failed.", event.fd); + } + } + //write + else if (object->events[i].filter == EVFILT_WRITE) + { + if (event.socket->removed) + { + continue; + } + handle = swReactor_getHandle(reactor, SW_EVENT_WRITE, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("kqueue event write socket#%d handler failed.", event.fd); + } + } + else + { + swWarn("unknown event filter[%d].", object->events[i].filter); + } + } + } + + if (reactor->onFinish != NULL) + { + reactor->onFinish(reactor); + } + if (reactor->once) + { + break; + } + } + return 0; +} +#endif diff --git a/vendor/swoole/src/reactor/ReactorPoll.c b/vendor/swoole/src/reactor/ReactorPoll.c new file mode 100755 index 0000000..90f2d7a --- /dev/null +++ b/vendor/swoole/src/reactor/ReactorPoll.c @@ -0,0 +1,306 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include <poll.h> + +static int swReactorPoll_add(swReactor *reactor, int fd, int fdtype); +static int swReactorPoll_set(swReactor *reactor, int fd, int fdtype); +static int swReactorPoll_del(swReactor *reactor, int fd); +static int swReactorPoll_wait(swReactor *reactor, struct timeval *timeo); +static void swReactorPoll_free(swReactor *reactor); +static int swReactorPoll_exist(swReactor *reactor, int fd); + +typedef struct _swPollFdInfo +{ + int fdtype; +} swPollFdInfo; + +typedef struct _swReactorPoll +{ + int max_fd_num; + swPollFdInfo *fds; + struct pollfd *events; +} swReactorPoll; + +int swReactorPoll_create(swReactor *reactor, int max_fd_num) +{ + //create reactor object + swReactorPoll *object = sw_malloc(sizeof(swReactorPoll)); + if (object == NULL) + { + swWarn("malloc[0] failed"); + return SW_ERR; + } + bzero(object, sizeof(swReactorPoll)); + + object->fds = sw_calloc(max_fd_num, sizeof(swPollFdInfo)); + if (object->fds == NULL) + { + swWarn("malloc[1] failed"); + sw_free(object); + return SW_ERR; + } + object->events = sw_calloc(max_fd_num, sizeof(struct pollfd)); + if (object->events == NULL) + { + swWarn("malloc[2] failed"); + sw_free(object); + return SW_ERR; + } + object->max_fd_num = max_fd_num; + reactor->max_event_num = max_fd_num; + bzero(reactor->handle, sizeof(reactor->handle)); + reactor->object = object; + //binding method + reactor->add = swReactorPoll_add; + reactor->del = swReactorPoll_del; + reactor->set = swReactorPoll_set; + reactor->wait = swReactorPoll_wait; + reactor->free = swReactorPoll_free; + + return SW_OK; +} + +static void swReactorPoll_free(swReactor *reactor) +{ + swReactorPoll *object = reactor->object; + sw_free(object->fds); + sw_free(reactor->object); +} + +static int swReactorPoll_add(swReactor *reactor, int fd, int fdtype) +{ + if (swReactorPoll_exist(reactor, fd)) + { + swWarn("fd#%d is already exists.", fd); + return SW_ERR; + } + + swReactorPoll *object = reactor->object; + int cur = reactor->event_num; + if (reactor->event_num == object->max_fd_num) + { + swWarn("too many connection, more than %d", object->max_fd_num); + return SW_ERR; + } + + swReactor_add(reactor, fd, fdtype); + + swTrace("fd=%d, fdtype=%d", fd, fdtype); + + object->fds[cur].fdtype = swReactor_fdtype(fdtype); + object->events[cur].fd = fd; + object->events[cur].events = 0; + + if (swReactor_event_read(fdtype)) + { + object->events[cur].events |= POLLIN; + } + if (swReactor_event_write(fdtype)) + { + object->events[cur].events |= POLLOUT; + } + if (swReactor_event_error(fdtype)) + { + object->events[cur].events |= POLLHUP; + } + + reactor->event_num++; + return SW_OK; +} + +static int swReactorPoll_set(swReactor *reactor, int fd, int fdtype) +{ + uint32_t i; + swReactorPoll *object = reactor->object; + + swTrace("fd=%d, fdtype=%d", fd, fdtype); + + for (i = 0; i < reactor->event_num; i++) + { + //found + if (object->events[i].fd == fd) + { + object->fds[i].fdtype = swReactor_fdtype(fdtype); + //object->events[i].events = POLLRDHUP; + object->events[i].events = 0; + if (swReactor_event_read(fdtype)) + { + object->events[i].events |= POLLIN; + } + if (swReactor_event_write(fdtype)) + { + object->events[i].events |= POLLOUT; + } + //execute parent method + swReactor_set(reactor, fd, fdtype); + return SW_OK; + } + } + return SW_ERR; +} + +static int swReactorPoll_del(swReactor *reactor, int fd) +{ + uint32_t i; + swReactorPoll *object = reactor->object; + + for (i = 0; i < reactor->event_num; i++) + { + if (object->events[i].fd == fd) + { + uint32_t old_num = reactor->event_num; + reactor->event_num = reactor->event_num <= 0 ? 0 : reactor->event_num - 1; + for (; i < old_num; i++) + { + if (i == old_num) + { + object->fds[i].fdtype = 0; + object->events[i].fd = 0; + object->events[i].events = 0; + } + else + { + object->fds[i] = object->fds[i + 1]; + object->events[i] = object->events[i + 1]; + } + } + swReactor_del(reactor, fd); + return SW_OK; + } + } + return SW_ERR; +} + +static int swReactorPoll_wait(swReactor *reactor, struct timeval *timeo) +{ + swReactorPoll *object = reactor->object; + swEvent event; + swReactor_handle handle; + + int ret, msec, i; + + if (reactor->timeout_msec == 0) + { + if (timeo == NULL) + { + reactor->timeout_msec = -1; + } + else + { + reactor->timeout_msec = timeo->tv_sec * 1000 + timeo->tv_usec / 1000; + } + } + + reactor->start = 1; + + while (reactor->running > 0) + { + if (reactor->onBegin != NULL) + { + reactor->onBegin(reactor); + } + msec = reactor->timeout_msec; + ret = poll(object->events, reactor->event_num, msec); + if (ret < 0) + { + if (swReactor_error(reactor) < 0) + { + swWarn("poll error. Error: %s[%d]", strerror(errno), errno); + } + continue; + } + else if (ret == 0) + { + if (reactor->onTimeout != NULL) + { + reactor->onTimeout(reactor); + } + continue; + } + else + { + for (i = 0; i < reactor->event_num; i++) + { + event.fd = object->events[i].fd; + event.from_id = reactor->id; + event.type = object->fds[i].fdtype; + event.socket = swReactor_get(reactor, event.fd); + + swTrace("Event: fd=%d|from_id=%d|type=%d", event.fd, reactor->id, object->fds[i].fdtype); + //in + if ((object->events[i].revents & POLLIN) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_READ, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swWarn("poll[POLLIN] handler failed. fd=%d. Error: %s[%d]", event.fd, strerror(errno), errno); + } + } + //out + if ((object->events[i].revents & POLLOUT) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_WRITE, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swWarn("poll[POLLOUT] handler failed. fd=%d. Error: %s[%d]", event.fd, strerror(errno), errno); + } + } + //error + if ((object->events[i].revents & (POLLHUP | POLLERR)) && !event.socket->removed) + { + //ignore ERR and HUP, because event is already processed at IN and OUT handler. + if ((object->events[i].revents & POLLIN) || (object->events[i].revents & POLLOUT)) + { + continue; + } + handle = swReactor_getHandle(reactor, SW_EVENT_ERROR, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swWarn("poll[POLLERR] handler failed. fd=%d. Error: %s[%d]", event.fd, strerror(errno), errno); + } + } + } + } + if (reactor->onFinish != NULL) + { + reactor->onFinish(reactor); + } + if (reactor->once) + { + break; + } + } + return SW_OK; +} + +static int swReactorPoll_exist(swReactor *reactor, int fd) +{ + swReactorPoll *object = reactor->object; + int i; + for (i = 0; i < reactor->event_num; i++) + { + if (object->events[i].fd == fd ) + { + return SW_TRUE; + } + } + return SW_FALSE; +} diff --git a/vendor/swoole/src/reactor/ReactorSelect.c b/vendor/swoole/src/reactor/ReactorSelect.c new file mode 100755 index 0000000..2cef704 --- /dev/null +++ b/vendor/swoole/src/reactor/ReactorSelect.c @@ -0,0 +1,286 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "swoole.h" +#include <sys/select.h> + +typedef struct _swFdList_node +{ + struct _swFdList_node *next, *prev; + int fd; + int fdtype; +} swFdList_node; + +typedef struct _swReactorSelect +{ + fd_set rfds; + fd_set wfds; + fd_set efds; + swFdList_node *fds; + int maxfd; +} swReactorSelect; + +#define SW_FD_SET(fd, set) do{ if (fd<FD_SETSIZE) FD_SET(fd, set);} while(0) +#define SW_FD_CLR(fd, set) do{ if (fd<FD_SETSIZE) FD_CLR(fd, set);} while(0) +#define SW_FD_ISSET(fd, set) ((fd < FD_SETSIZE) && FD_ISSET(fd, set)) + +static int swReactorSelect_add(swReactor *reactor, int fd, int fdtype); +static int swReactorSelect_wait(swReactor *reactor, struct timeval *timeo); +static void swReactorSelect_free(swReactor *reactor); +static int swReactorSelect_del(swReactor *reactor, int fd); +static int swReactorSelect_set(swReactor *reactor, int fd, int fdtype); +static int swReactorSelect_cmp(swFdList_node *a, swFdList_node *b); + +int swReactorSelect_create(swReactor *reactor) +{ + //create reactor object + swReactorSelect *object = sw_malloc(sizeof(swReactorSelect)); + if (object == NULL) + { + swWarn("[swReactorSelect_create] malloc[0] fail\n"); + return SW_ERR; + } + bzero(object, sizeof(swReactorSelect)); + + object->fds = NULL; + object->maxfd = 0; + bzero(reactor->handle, sizeof(reactor->handle)); + reactor->object = object; + //binding method + reactor->add = swReactorSelect_add; + reactor->set = swReactorSelect_set; + reactor->del = swReactorSelect_del; + reactor->wait = swReactorSelect_wait; + reactor->free = swReactorSelect_free; + + return SW_OK; +} + +void swReactorSelect_free(swReactor *reactor) +{ + swReactorSelect *object = reactor->object; + swFdList_node *ev, *tmp; + LL_FOREACH_SAFE(object->fds, ev, tmp) + { + LL_DELETE(object->fds, ev); + sw_free(ev); + } + sw_free(reactor->object); +} + +int swReactorSelect_add(swReactor *reactor, int fd, int fdtype) +{ + if (fd > FD_SETSIZE) + { + swWarn("max fd value is FD_SETSIZE(%d).\n", FD_SETSIZE); + return SW_ERR; + } + swReactorSelect *object = reactor->object; + swFdList_node *ev = sw_malloc(sizeof(swFdList_node)); + if (ev == NULL) + { + swWarn("malloc(%ld) failed.", sizeof(swFdList_node)); + return SW_ERR; + } + + swReactor_add(reactor, fd, fdtype); + + ev->fd = fd; + ev->fdtype = fdtype; + LL_APPEND(object->fds, ev); + reactor->event_num++; + if (fd > object->maxfd) + { + object->maxfd = fd; + } + + return SW_OK; +} + +static int swReactorSelect_cmp(swFdList_node *a, swFdList_node *b) +{ + return a->fd == b->fd ? 0 : (a->fd > b->fd ? -1 : 1); +} + +int swReactorSelect_del(swReactor *reactor, int fd) +{ + swReactorSelect *object = reactor->object; + swFdList_node ev, *s_ev = NULL; + ev.fd = fd; + LL_SEARCH(object->fds, s_ev, &ev, swReactorSelect_cmp); + if (s_ev == NULL) + { + swWarn("swReactorSelect: fd[%d] not found", fd); + return SW_ERR; + } + LL_DELETE(object->fds, s_ev); + SW_FD_CLR(fd, &object->rfds); + SW_FD_CLR(fd, &object->wfds); + SW_FD_CLR(fd, &object->efds); + reactor->event_num = reactor->event_num <= 0 ? 0 : reactor->event_num - 1; + sw_free(s_ev); + swReactor_del(reactor, fd); + return SW_OK; +} + +int swReactorSelect_set(swReactor *reactor, int fd, int fdtype) +{ + swReactorSelect *object = reactor->object; + swFdList_node ev, *s_ev = NULL; + ev.fd = fd; + LL_SEARCH(object->fds, s_ev, &ev, swReactorSelect_cmp); + if (s_ev == NULL) + { + swWarn("swReactorSelect: sock[%d] not found.", fd); + return SW_ERR; + } + s_ev->fdtype = fdtype; + //execute parent method + swReactor_set(reactor, fd, fdtype); + return SW_OK; +} + +int swReactorSelect_wait(swReactor *reactor, struct timeval *timeo) +{ + swReactorSelect *object = reactor->object; + swFdList_node *ev; + swFdList_node *tmp; + swEvent event; + swReactor_handle handle; + struct timeval timeout; + int ret; + + if (reactor->timeout_msec == 0) + { + if (timeo == NULL) + { + reactor->timeout_msec = -1; + } + else + { + reactor->timeout_msec = timeo->tv_sec * 1000 + timeo->tv_usec / 1000; + } + } + + reactor->start = 1; + + while (reactor->running > 0) + { + FD_ZERO(&(object->rfds)); + FD_ZERO(&(object->wfds)); + FD_ZERO(&(object->efds)); + + if (reactor->onBegin != NULL) + { + reactor->onBegin(reactor); + } + + LL_FOREACH(object->fds, ev) + { + if (swReactor_event_read(ev->fdtype)) + { + SW_FD_SET(ev->fd, &(object->rfds)); + } + if (swReactor_event_write(ev->fdtype)) + { + SW_FD_SET(ev->fd, &(object->wfds)); + } + if (swReactor_event_error(ev->fdtype)) + { + SW_FD_SET(ev->fd, &(object->efds)); + } + } + + if (reactor->timeout_msec < 0) + { + timeout.tv_sec = SW_MAX_UINT; + timeout.tv_usec = 0; + } + else + { + timeout.tv_sec = reactor->timeout_msec / 1000; + timeout.tv_usec = reactor->timeout_msec - timeout.tv_sec * 1000; + } + + ret = select(object->maxfd + 1, &(object->rfds), &(object->wfds), &(object->efds), &timeout); + if (ret < 0) + { + if (swReactor_error(reactor) < 0) + { + swWarn("select error. Error: %s[%d]", strerror(errno), errno); + } + continue; + } + else if (ret == 0) + { + if (reactor->onTimeout != NULL) + { + reactor->onTimeout(reactor); + } + continue; + } + else + { + LL_FOREACH_SAFE(object->fds, ev, tmp) + { + event.fd = ev->fd; + event.from_id = reactor->id; + event.type = swReactor_fdtype(ev->fdtype); + event.socket = swReactor_get(reactor, event.fd); + + //read + if (SW_FD_ISSET(event.fd, &(object->rfds)) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_READ, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("[Reactor#%d] select event[type=READ, fd=%d] handler fail.", reactor->id, event.fd); + } + } + //write + if (SW_FD_ISSET(event.fd, &(object->wfds)) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_WRITE, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("[Reactor#%d] select event[type=WRITE, fd=%d] handler fail.", reactor->id, event.fd); + } + } + //error + if (SW_FD_ISSET(event.fd, &(object->efds)) && !event.socket->removed) + { + handle = swReactor_getHandle(reactor, SW_EVENT_ERROR, event.type); + ret = handle(reactor, &event); + if (ret < 0) + { + swSysError("[Reactor#%d] select event[type=ERROR, fd=%d] handler fail.", reactor->id, event.fd); + } + } + } + } + if (reactor->onFinish != NULL) + { + reactor->onFinish(reactor); + } + if (reactor->once) + { + break; + } + } + return SW_OK; +} diff --git a/vendor/swoole/swoole.c b/vendor/swoole/swoole.c new file mode 100755 index 0000000..5b1974a --- /dev/null +++ b/vendor/swoole/swoole.c @@ -0,0 +1,1609 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ +#include "php_swoole.h" +#include "zend_variables.h" + +#include <netinet/in.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <ifaddrs.h> +#include <sys/ioctl.h> + +#ifdef HAVE_PCRE +#include <ext/spl/spl_iterators.h> +#endif + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +ZEND_DECLARE_MODULE_GLOBALS(swoole) + +extern sapi_module_struct sapi_module; + +// arginfo server +// *_oo : for object style + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server__construct, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, sock_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_set_oo, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +//for object style +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_send_oo, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, send_data) + ZEND_ARG_INFO(0, reactor_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_sendwait, 0, 0, 2) + ZEND_ARG_INFO(0, conn_fd) + ZEND_ARG_INFO(0, send_data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_exist, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_protect, 0, 0, 1) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, is_protected) +ZEND_END_ARG_INFO() + +//for object style +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_sendto, 0, 0, 3) + ZEND_ARG_INFO(0, ip) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, send_data) + ZEND_ARG_INFO(0, server_socket) +ZEND_END_ARG_INFO() + +//for object style +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_sendfile, 0, 0, 2) + ZEND_ARG_INFO(0, conn_fd) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_close, 0, 0, 1) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, reset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_pause, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_resume, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_confirm, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +#ifdef SWOOLE_SOCKETS_SUPPORT +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_getSocket, 0, 0, 0) + ZEND_ARG_INFO(0, port) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_listen, 0, 0, 3) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, sock_type) +ZEND_END_ARG_INFO() + +//object style +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_task, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, worker_id) + ZEND_ARG_INFO(0, finish_callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_taskwait, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, timeout) + ZEND_ARG_INFO(0, worker_id) +ZEND_END_ARG_INFO() + +#ifdef SW_COROUTINE +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_taskCo, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, tasks, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_taskWaitMulti_oo, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, tasks, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_finish_oo, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_reload_oo, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_heartbeat_oo, 0, 0, 1) + ZEND_ARG_INFO(0, reactor_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_stop, 0, 0, 0) + ZEND_ARG_INFO(0, worker_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_bind, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, uid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_sendMessage, 0, 0, 2) + ZEND_ARG_INFO(0, message) + ZEND_ARG_INFO(0, dst_worker_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_addProcess, 0, 0, 1) + ZEND_ARG_OBJ_INFO(0, process, swoole_process, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_info, 0, 0, 1) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, reactor_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_list, 0, 0, 1) + ZEND_ARG_INFO(0, start_fd) + ZEND_ARG_INFO(0, find_count) +ZEND_END_ARG_INFO() + +//arginfo event +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_add, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, read_callback) + ZEND_ARG_INFO(0, write_callback) + ZEND_ARG_INFO(0, events) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_set, 0, 0, 1) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, read_callback) + ZEND_ARG_INFO(0, write_callback) + ZEND_ARG_INFO(0, events) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_write, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_defer, 0, 0, 1) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_cycle, 0, 0, 1) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, before) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_del, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_event_isset, 0, 0, 1) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, events) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_timer_tick, 0, 0, 2) + ZEND_ARG_INFO(0, ms) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_timer_after, 0, 0, 2) + ZEND_ARG_INFO(0, ms) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, param) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_timer_exists, 0, 0, 1) + ZEND_ARG_INFO(0, timer_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_timer_clear, 0, 0, 1) + ZEND_ARG_INFO(0, timer_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_readfile, 0, 0, 2) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_writefile, 0, 0, 2) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, content) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_read, 0, 0, 2) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, chunk_size) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_write, 0, 0, 2) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, content) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_dns_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, hostname) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +#ifdef SW_COROUTINE +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_dns_lookup_coro, 0, 0, 1) + ZEND_ARG_INFO(0, domain_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_create, 0, 0, 1) + ZEND_ARG_INFO(0, func) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_exec, 0, 0, 1) + ZEND_ARG_INFO(0, command) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_async_exec, 0, 0, 2) + ZEND_ARG_INFO(0, command) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_select, 0, 0, 3) + ZEND_ARG_INFO(1, read_array) + ZEND_ARG_INFO(1, write_array) + ZEND_ARG_INFO(1, error_array) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_set_process_name, 0, 0, 1) + ZEND_ARG_INFO(0, process_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_strerror, 0, 0, 1) + ZEND_ARG_INFO(0, errno) + ZEND_ARG_INFO(0, error_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_hashcode, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +#ifdef HAVE_PCRE +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_iterator_offsetExists, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_iterator_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_iterator_offsetUnset, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_connection_iterator_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() +#endif + +//arginfo end + +#include "zend_exceptions.h" + +static PHP_FUNCTION(swoole_last_error); +static PHP_FUNCTION(swoole_hashcode); + +const zend_function_entry swoole_functions[] = +{ + PHP_FE(swoole_version, arginfo_swoole_void) + PHP_FE(swoole_cpu_num, arginfo_swoole_void) + PHP_FE(swoole_last_error, arginfo_swoole_void) + /*------swoole_event-----*/ + PHP_FE(swoole_event_add, arginfo_swoole_event_add) + PHP_FE(swoole_event_set, arginfo_swoole_event_set) + PHP_FE(swoole_event_del, arginfo_swoole_event_del) + PHP_FE(swoole_event_exit, arginfo_swoole_void) + PHP_FE(swoole_event_wait, arginfo_swoole_void) + PHP_FE(swoole_event_write, arginfo_swoole_event_write) + PHP_FE(swoole_event_defer, arginfo_swoole_event_defer) + PHP_FE(swoole_event_cycle, arginfo_swoole_event_cycle) + PHP_FE(swoole_event_dispatch, arginfo_swoole_void) + PHP_FE(swoole_event_isset, arginfo_swoole_event_isset) + /*------swoole_timer-----*/ + PHP_FE(swoole_timer_after, arginfo_swoole_timer_after) + PHP_FE(swoole_timer_tick, arginfo_swoole_timer_tick) + PHP_FE(swoole_timer_exists, arginfo_swoole_timer_exists) + PHP_FE(swoole_timer_clear, arginfo_swoole_timer_clear) + /*------swoole_async_io------*/ + PHP_FE(swoole_async_set, arginfo_swoole_async_set) + PHP_FE(swoole_async_read, arginfo_swoole_async_read) + PHP_FE(swoole_async_write, arginfo_swoole_async_write) + PHP_FE(swoole_async_readfile, arginfo_swoole_async_readfile) + PHP_FE(swoole_async_writefile, arginfo_swoole_async_writefile) + PHP_FE(swoole_async_dns_lookup, arginfo_swoole_async_dns_lookup) +#ifdef SW_COROUTINE + PHP_FE(swoole_async_dns_lookup_coro, arginfo_swoole_async_dns_lookup_coro) + PHP_FE(swoole_coroutine_create, arginfo_swoole_coroutine_create) + PHP_FE(swoole_coroutine_exec, arginfo_swoole_coroutine_exec) + PHP_FALIAS(go, swoole_coroutine_create, arginfo_swoole_coroutine_create) +#endif + /*------other-----*/ + PHP_FE(swoole_client_select, arginfo_swoole_client_select) + PHP_FALIAS(swoole_select, swoole_client_select, arginfo_swoole_client_select) + PHP_FE(swoole_set_process_name, arginfo_swoole_set_process_name) + PHP_FE(swoole_get_local_ip, arginfo_swoole_void) + PHP_FE(swoole_get_local_mac, arginfo_swoole_void) + PHP_FE(swoole_strerror, arginfo_swoole_strerror) + PHP_FE(swoole_errno, arginfo_swoole_void) + PHP_FE(swoole_hashcode, arginfo_swoole_hashcode) + PHP_FE(swoole_call_user_shutdown_begin, arginfo_swoole_void) + PHP_FE_END /* Must be the last line in swoole_functions[] */ +}; + +static zend_function_entry swoole_server_methods[] = { + PHP_ME(swoole_server, __construct, arginfo_swoole_server__construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_server, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_server, listen, arginfo_swoole_server_listen, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_server, addlistener, listen, arginfo_swoole_server_listen, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, on, arginfo_swoole_server_on, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, set, arginfo_swoole_server_set_oo, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, start, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, send, arginfo_swoole_server_send_oo, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, sendto, arginfo_swoole_server_sendto, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, sendwait, arginfo_swoole_server_sendwait, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, exist, arginfo_swoole_server_exist, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, protect, arginfo_swoole_server_protect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, sendfile, arginfo_swoole_server_sendfile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, close, arginfo_swoole_server_close, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, confirm, arginfo_swoole_server_confirm, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, pause, arginfo_swoole_server_pause, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, resume, arginfo_swoole_server_resume, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, task, arginfo_swoole_server_task, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, taskwait, arginfo_swoole_server_taskwait, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, taskWaitMulti, arginfo_swoole_server_taskWaitMulti_oo, ZEND_ACC_PUBLIC) +#ifdef SW_COROUTINE + PHP_ME(swoole_server, taskCo, arginfo_swoole_server_taskCo, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_server, finish, arginfo_swoole_server_finish_oo, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, reload, arginfo_swoole_server_reload_oo, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, shutdown, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, stop, arginfo_swoole_server_stop, ZEND_ACC_PUBLIC) + PHP_FALIAS(getLastError, swoole_last_error, arginfo_swoole_void) + PHP_ME(swoole_server, heartbeat, arginfo_swoole_server_heartbeat_oo, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, connection_info, arginfo_swoole_connection_info, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, connection_list, arginfo_swoole_connection_list, ZEND_ACC_PUBLIC) + //psr-0 style + PHP_MALIAS(swoole_server, getClientInfo, connection_info, arginfo_swoole_connection_info, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_server, getClientList, connection_list, arginfo_swoole_connection_list, ZEND_ACC_PUBLIC) + //timer + PHP_FALIAS(after, swoole_timer_after, arginfo_swoole_timer_after) + PHP_FALIAS(tick, swoole_timer_tick, arginfo_swoole_timer_tick) + PHP_FALIAS(clearTimer, swoole_timer_clear, arginfo_swoole_timer_clear) + PHP_FALIAS(defer, swoole_event_defer, arginfo_swoole_event_defer) + //process + PHP_ME(swoole_server, sendMessage, arginfo_swoole_server_sendMessage, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, addProcess, arginfo_swoole_server_addProcess, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#ifdef SWOOLE_SOCKETS_SUPPORT + PHP_ME(swoole_server, getSocket, arginfo_swoole_server_getSocket, ZEND_ACC_PUBLIC) +#endif +#ifdef SW_BUFFER_RECV_TIME + PHP_ME(swoole_server, getReceivedTime, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_server, bind, arginfo_swoole_server_bind, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + {NULL, NULL, NULL} +}; + +#ifdef HAVE_PCRE +static const zend_function_entry swoole_connection_iterator_methods[] = +{ + PHP_ME(swoole_connection_iterator, rewind, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, next, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, current, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, key, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, valid, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, count, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_connection_iterator, offsetExists, arginfo_swoole_connection_iterator_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, offsetGet, arginfo_swoole_connection_iterator_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, offsetSet, arginfo_swoole_connection_iterator_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_connection_iterator, offsetUnset, arginfo_swoole_connection_iterator_offsetUnset, ZEND_ACC_PUBLIC) + PHP_FE_END +}; +#endif + +static const zend_function_entry swoole_timer_methods[] = +{ + ZEND_FENTRY(tick, ZEND_FN(swoole_timer_tick), arginfo_swoole_timer_tick, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(after, ZEND_FN(swoole_timer_after), arginfo_swoole_timer_after, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(exists, ZEND_FN(swoole_timer_exists), arginfo_swoole_timer_exists, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(clear, ZEND_FN(swoole_timer_clear), arginfo_swoole_timer_clear, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +static const zend_function_entry swoole_event_methods[] = +{ + ZEND_FENTRY(add, ZEND_FN(swoole_event_add), arginfo_swoole_event_add, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(del, ZEND_FN(swoole_event_del), arginfo_swoole_event_del, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(set, ZEND_FN(swoole_event_set), arginfo_swoole_event_set, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(exit, ZEND_FN(swoole_event_exit), arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(write, ZEND_FN(swoole_event_write), arginfo_swoole_event_write, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(wait, ZEND_FN(swoole_event_wait), arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(defer, ZEND_FN(swoole_event_defer), arginfo_swoole_event_defer, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(cycle, ZEND_FN(swoole_event_cycle), arginfo_swoole_event_cycle, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +static const zend_function_entry swoole_async_methods[] = +{ + ZEND_FENTRY(read, ZEND_FN(swoole_async_read), arginfo_swoole_async_read, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(write, ZEND_FN(swoole_async_write), arginfo_swoole_async_write, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(readFile, ZEND_FN(swoole_async_readfile), arginfo_swoole_async_readfile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(writeFile, ZEND_FN(swoole_async_writefile), arginfo_swoole_async_writefile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(dnsLookup, ZEND_FN(swoole_async_dns_lookup), arginfo_swoole_async_dns_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) +#ifdef SW_COROUTINE + ZEND_FENTRY(dnsLookupCoro, ZEND_FN(swoole_async_dns_lookup_coro), arginfo_swoole_async_dns_lookup_coro, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) +#endif + ZEND_FENTRY(set, ZEND_FN(swoole_async_set), arginfo_swoole_async_set, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_async, exec, arginfo_swoole_async_exec, ZEND_ACC_PUBLIC| ZEND_ACC_STATIC) + PHP_FE_END +}; + +#if PHP_MEMORY_DEBUG +php_vmstat_t php_vmstat; +#endif + +zend_class_entry swoole_server_ce; +zend_class_entry *swoole_server_class_entry_ptr; + +zend_class_entry swoole_connection_iterator_ce; +zend_class_entry *swoole_connection_iterator_class_entry_ptr; + +static zend_class_entry swoole_timer_ce; +static zend_class_entry *swoole_timer_class_entry_ptr; + +static zend_class_entry swoole_event_ce; +static zend_class_entry *swoole_event_class_entry_ptr; + +static zend_class_entry swoole_async_ce; +static zend_class_entry *swoole_async_class_entry_ptr; + +zend_class_entry swoole_exception_ce; +zend_class_entry *swoole_exception_class_entry_ptr; + +zend_module_entry swoole_module_entry = +{ +#if ZEND_MODULE_API_NO >= 20050922 + STANDARD_MODULE_HEADER_EX, + NULL, + NULL, +#else + STANDARD_MODULE_HEADER, +#endif + "swoole", + swoole_functions, + PHP_MINIT(swoole), + PHP_MSHUTDOWN(swoole), + PHP_RINIT(swoole), //RINIT + PHP_RSHUTDOWN(swoole), //RSHUTDOWN + PHP_MINFO(swoole), + PHP_SWOOLE_VERSION, + STANDARD_MODULE_PROPERTIES +}; + +#ifdef COMPILE_DL_SWOOLE +ZEND_GET_MODULE(swoole) +#endif + +/* {{{ PHP_INI + */ + +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("swoole.aio_thread_num", "2", PHP_INI_ALL, OnUpdateLong, aio_thread_num, zend_swoole_globals, swoole_globals) +STD_PHP_INI_ENTRY("swoole.display_errors", "On", PHP_INI_ALL, OnUpdateBool, display_errors, zend_swoole_globals, swoole_globals) +/** + * namespace class style + */ +STD_PHP_INI_ENTRY("swoole.use_namespace", "On", PHP_INI_SYSTEM, OnUpdateBool, use_namespace, zend_swoole_globals, swoole_globals) +/** + * use an short class name + */ +STD_PHP_INI_ENTRY("swoole.use_shortname", "On", PHP_INI_SYSTEM, OnUpdateBool, use_shortname, zend_swoole_globals, swoole_globals) +/** + * enable swoole_serialize + */ +STD_PHP_INI_ENTRY("swoole.fast_serialize", "Off", PHP_INI_ALL, OnUpdateBool, fast_serialize, zend_swoole_globals, swoole_globals) +/** + * Unix socket buffer size + */ +STD_PHP_INI_ENTRY("swoole.unixsock_buffer_size", "8388608", PHP_INI_ALL, OnUpdateLong, socket_buffer_size, zend_swoole_globals, swoole_globals) +PHP_INI_END() + +static void php_swoole_init_globals(zend_swoole_globals *swoole_globals) +{ + swoole_globals->aio_thread_num = SW_AIO_THREAD_NUM_DEFAULT; + swoole_globals->socket_buffer_size = SW_SOCKET_BUFFER_SIZE; + swoole_globals->display_errors = 1; + swoole_globals->use_namespace = 1; + swoole_globals->use_shortname = 1; + swoole_globals->fast_serialize = 0; + swoole_globals->rshutdown_functions = NULL; +} + +int php_swoole_length_func(swProtocol *protocol, swConnection *conn, char *data, uint32_t length) +{ + SwooleG.lock.lock(&SwooleG.lock); + SWOOLE_GET_TSRMLS; + + zval *zdata; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, data, length, 1); + + zval **args[1]; + args[0] = &zdata; + + zval *callback = protocol->private_data; + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "length function handler error."); + goto error; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + goto error; + } + sw_zval_ptr_dtor(&zdata); + if (retval != NULL) + { + convert_to_long(retval); + int length = Z_LVAL_P(retval); + sw_zval_ptr_dtor(&retval); + SwooleG.lock.unlock(&SwooleG.lock); + return length; + } + error: + SwooleG.lock.unlock(&SwooleG.lock); + return -1; +} + +int php_swoole_dispatch_func(swServer *serv, swConnection *conn, swEventData *data) +{ + SwooleG.lock.lock(&SwooleG.lock); + SWOOLE_GET_TSRMLS; + + zval *zserv = (zval *) serv->ptr2; + + zval *zdata; + zval *zfd; + zval *ztype; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, data->data, data->info.len, 1); + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, (long ) conn->session_id); + + SW_MAKE_STD_ZVAL(ztype); + ZVAL_LONG(ztype, (long ) data->info.type); + + zval **args[4]; + args[0] = &zserv; + args[1] = &zfd; + args[2] = &ztype; + args[3] = &zdata; + + zval *callback = (zval*) serv->private_data_3; + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 4, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "dispatch function handler error."); + goto error; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + goto error; + } + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&ztype); + sw_zval_ptr_dtor(&zdata); + if (retval != NULL) + { + convert_to_long(retval); + int worker_id = (int) Z_LVAL_P(retval); + if (worker_id >= serv->worker_num) + { + swoole_php_fatal_error(E_WARNING, "invalid target worker-id[%d].", worker_id); + goto error; + } + sw_zval_ptr_dtor(&retval); + SwooleG.lock.unlock(&SwooleG.lock); + return worker_id; + } + error: + SwooleG.lock.unlock(&SwooleG.lock); + return -1; +} + +static sw_inline uint32_t swoole_get_new_size(uint32_t old_size, int handle TSRMLS_DC) +{ + uint32_t new_size = old_size * 2; + if (handle > SWOOLE_OBJECT_MAX) + { + swoole_php_fatal_error(E_ERROR, "handle %d exceed %d", handle, SWOOLE_OBJECT_MAX); + return 0; + } + while (new_size <= handle) + { + new_size *= 2; + } + if (new_size > SWOOLE_OBJECT_MAX) + { + new_size = SWOOLE_OBJECT_MAX; + } + return new_size; +} + +void swoole_set_object(zval *object, void *ptr) +{ + SWOOLE_GET_TSRMLS; + int handle = sw_get_object_handle(object); + assert(handle < SWOOLE_OBJECT_MAX); + if (handle >= swoole_objects.size) + { + uint32_t old_size = swoole_objects.size; + uint32_t new_size = swoole_get_new_size(old_size, handle TSRMLS_CC); + + void *old_ptr = swoole_objects.array; + void *new_ptr = NULL; + + new_ptr = realloc(old_ptr, sizeof(void*) * new_size); + if (!new_ptr) + { + swoole_php_fatal_error(E_ERROR, "malloc(%d) failed.", (int )(new_size * sizeof(void *))); + return; + } + bzero(new_ptr + (old_size * sizeof(void*)), (new_size - old_size) * sizeof(void*)); + swoole_objects.array = new_ptr; + swoole_objects.size = new_size; + } + swoole_objects.array[handle] = ptr; +} + +void swoole_set_property(zval *object, int property_id, void *ptr) +{ + SWOOLE_GET_TSRMLS; + int handle = sw_get_object_handle(object); + assert(handle < SWOOLE_OBJECT_MAX); + + if (handle >= swoole_objects.property_size[property_id]) + { + uint32_t old_size = swoole_objects.property_size[property_id]; + uint32_t new_size = 0; + + void **old_ptr = NULL; + void **new_ptr = NULL; + + if (old_size == 0) + { + new_size = 65536; + new_ptr = calloc(new_size, sizeof(void *)); + } + else + { + new_size = swoole_get_new_size(old_size, handle TSRMLS_CC); + old_ptr = swoole_objects.property[property_id]; + new_ptr = realloc(old_ptr, new_size * sizeof(void *)); + } + if (new_ptr == NULL) + { + swoole_php_fatal_error(E_ERROR, "malloc(%d) failed.", (int )(new_size * sizeof(void *))); + return; + } + if (old_size > 0) + { + bzero((void *) new_ptr + old_size * sizeof(void*), (new_size - old_size) * sizeof(void*)); + } + swoole_objects.property_size[property_id] = new_size; + swoole_objects.property[property_id] = new_ptr; + } + swoole_objects.property[property_id][handle] = ptr; +} + +int swoole_register_rshutdown_function(swCallback func, int push_back) +{ + if (SWOOLE_G(rshutdown_functions) == NULL) + { + SWOOLE_G(rshutdown_functions) = swLinkedList_new(0, NULL); + if (SWOOLE_G(rshutdown_functions) == NULL) + { + return SW_ERR; + } + } + if (push_back) + { + return swLinkedList_append(SWOOLE_G(rshutdown_functions), func); + } + else + { + return swLinkedList_prepend(SWOOLE_G(rshutdown_functions), func); + } +} + +void swoole_call_rshutdown_function(void *arg) +{ + if (SWOOLE_G(rshutdown_functions)) + { + swLinkedList *rshutdown_functions = SWOOLE_G(rshutdown_functions); + swLinkedList_node *node = rshutdown_functions->head; + swCallback func = NULL; + + while (node) + { + func = node->data; + func(arg); + node = node->next; + } + } +} + +#ifdef ZTS +__thread swoole_object_array swoole_objects; +void ***sw_thread_ctx; +#else +swoole_object_array swoole_objects; +#endif + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(swoole) +{ + ZEND_INIT_MODULE_GLOBALS(swoole, php_swoole_init_globals, NULL); + REGISTER_INI_ENTRIES(); + + /** + * mode type + */ + REGISTER_LONG_CONSTANT("SWOOLE_BASE", SW_MODE_SINGLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_THREAD", SW_MODE_THREAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_PROCESS", SW_MODE_PROCESS, CONST_CS | CONST_PERSISTENT); + + /** + * task ipc mode + */ + REGISTER_LONG_CONSTANT("SWOOLE_IPC_UNSOCK", SW_TASK_IPC_UNIXSOCK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_IPC_MSGQUEUE", SW_TASK_IPC_MSGQUEUE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_IPC_PREEMPTIVE", SW_TASK_IPC_PREEMPTIVE, CONST_CS | CONST_PERSISTENT); + + /** + * socket type + */ + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_TCP", SW_SOCK_TCP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_TCP6", SW_SOCK_TCP6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_UDP", SW_SOCK_UDP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_UDP6", SW_SOCK_UDP6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_UNIX_DGRAM", SW_SOCK_UNIX_DGRAM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_UNIX_STREAM", SW_SOCK_UNIX_STREAM, CONST_CS | CONST_PERSISTENT); + + /** + * simple api + */ + REGISTER_LONG_CONSTANT("SWOOLE_TCP", SW_SOCK_TCP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TCP6", SW_SOCK_TCP6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_UDP", SW_SOCK_UDP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_UDP6", SW_SOCK_UDP6, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_UNIX_DGRAM", SW_SOCK_UNIX_DGRAM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_UNIX_STREAM", SW_SOCK_UNIX_STREAM, CONST_CS | CONST_PERSISTENT); + + /** + * simple api + */ + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_SYNC", SW_SOCK_SYNC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SOCK_ASYNC", SW_SOCK_ASYNC, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("SWOOLE_SYNC", SW_FLAG_SYNC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_ASYNC", SW_FLAG_ASYNC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_KEEP", SW_FLAG_KEEP, CONST_CS | CONST_PERSISTENT); + +#ifdef SW_USE_OPENSSL + REGISTER_LONG_CONSTANT("SWOOLE_SSL", SW_SOCK_SSL, CONST_CS | CONST_PERSISTENT); + + /** + * SSL method + */ + REGISTER_LONG_CONSTANT("SWOOLE_SSLv3_METHOD", SW_SSLv3_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SSLv3_SERVER_METHOD", SW_SSLv3_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SSLv3_CLIENT_METHOD", SW_SSLv3_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SSLv23_METHOD", SW_SSLv23_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SSLv23_SERVER_METHOD", SW_SSLv23_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SSLv23_CLIENT_METHOD", SW_SSLv23_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_METHOD", SW_TLSv1_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_SERVER_METHOD", SW_TLSv1_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_CLIENT_METHOD", SW_TLSv1_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); +#ifdef TLS1_1_VERSION + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_1_METHOD", SW_TLSv1_1_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_1_SERVER_METHOD", SW_TLSv1_1_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_1_CLIENT_METHOD", SW_TLSv1_1_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef TLS1_2_VERSION + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_2_METHOD", SW_TLSv1_2_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_2_SERVER_METHOD", SW_TLSv1_2_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_TLSv1_2_CLIENT_METHOD", SW_TLSv1_2_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("SWOOLE_DTLSv1_METHOD", SW_DTLSv1_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_DTLSv1_SERVER_METHOD", SW_DTLSv1_SERVER_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_DTLSv1_CLIENT_METHOD", SW_DTLSv1_CLIENT_METHOD, CONST_CS | CONST_PERSISTENT); +#endif + + REGISTER_LONG_CONSTANT("SWOOLE_EVENT_READ", SW_EVENT_READ, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_EVENT_WRITE", SW_EVENT_WRITE, CONST_CS | CONST_PERSISTENT); + + REGISTER_STRINGL_CONSTANT("SWOOLE_VERSION", PHP_SWOOLE_VERSION, sizeof(PHP_SWOOLE_VERSION) - 1, CONST_CS | CONST_PERSISTENT); + + SWOOLE_DEFINE(ERROR_MALLOC_FAIL); + SWOOLE_DEFINE(ERROR_SYSTEM_CALL_FAIL); + SWOOLE_DEFINE(ERROR_PHP_FATAL_ERROR); + SWOOLE_DEFINE(ERROR_NAME_TOO_LONG); + SWOOLE_DEFINE(ERROR_INVALID_PARAMS); + SWOOLE_DEFINE(ERROR_FILE_NOT_EXIST); + SWOOLE_DEFINE(ERROR_FILE_TOO_LARGE); + SWOOLE_DEFINE(ERROR_FILE_EMPTY); + SWOOLE_DEFINE(ERROR_DNSLOOKUP_DUPLICATE_REQUEST); + SWOOLE_DEFINE(ERROR_DNSLOOKUP_RESOLVE_FAILED); + SWOOLE_DEFINE(ERROR_SESSION_CLOSED_BY_SERVER); + SWOOLE_DEFINE(ERROR_SESSION_CLOSED_BY_CLIENT); + SWOOLE_DEFINE(ERROR_SESSION_CLOSING); + SWOOLE_DEFINE(ERROR_SESSION_CLOSED); + SWOOLE_DEFINE(ERROR_SESSION_NOT_EXIST); + SWOOLE_DEFINE(ERROR_SESSION_INVALID_ID); + SWOOLE_DEFINE(ERROR_SESSION_DISCARD_TIMEOUT_DATA); + SWOOLE_DEFINE(ERROR_OUTPUT_BUFFER_OVERFLOW); + SWOOLE_DEFINE(ERROR_SSL_NOT_READY); + SWOOLE_DEFINE(ERROR_SSL_CANNOT_USE_SENFILE); + SWOOLE_DEFINE(ERROR_SSL_EMPTY_PEER_CERTIFICATE); + SWOOLE_DEFINE(ERROR_SSL_VEFIRY_FAILED); + SWOOLE_DEFINE(ERROR_SSL_BAD_CLIENT); + SWOOLE_DEFINE(ERROR_SSL_BAD_PROTOCOL); + SWOOLE_DEFINE(ERROR_PACKAGE_LENGTH_TOO_LARGE); + SWOOLE_DEFINE(ERROR_DATA_LENGTH_TOO_LARGE); + SWOOLE_DEFINE(ERROR_TASK_PACKAGE_TOO_BIG); + SWOOLE_DEFINE(ERROR_TASK_DISPATCH_FAIL); + + /** + * AIO + */ + SWOOLE_DEFINE(ERROR_AIO_BAD_REQUEST); + + /** + * Client + */ + SWOOLE_DEFINE(ERROR_CLIENT_NO_CONNECTION); + + SWOOLE_DEFINE(ERROR_HTTP2_STREAM_ID_TOO_BIG); + SWOOLE_DEFINE(ERROR_HTTP2_STREAM_NO_HEADER); + SWOOLE_DEFINE(ERROR_SOCKS5_UNSUPPORT_VERSION); + SWOOLE_DEFINE(ERROR_SOCKS5_UNSUPPORT_METHOD); + SWOOLE_DEFINE(ERROR_SOCKS5_AUTH_FAILED); + SWOOLE_DEFINE(ERROR_SOCKS5_SERVER_ERROR); + SWOOLE_DEFINE(ERROR_HTTP_PROXY_HANDSHAKE_ERROR); + SWOOLE_DEFINE(ERROR_HTTP_INVALID_PROTOCOL); + SWOOLE_DEFINE(ERROR_WEBSOCKET_BAD_CLIENT); + SWOOLE_DEFINE(ERROR_WEBSOCKET_BAD_OPCODE); + SWOOLE_DEFINE(ERROR_WEBSOCKET_UNCONNECTED); + SWOOLE_DEFINE(ERROR_WEBSOCKET_HANDSHAKE_FAILED); + SWOOLE_DEFINE(ERROR_SERVER_MUST_CREATED_BEFORE_CLIENT); + SWOOLE_DEFINE(ERROR_SERVER_TOO_MANY_SOCKET); + SWOOLE_DEFINE(ERROR_SERVER_WORKER_TERMINATED); + SWOOLE_DEFINE(ERROR_SERVER_INVALID_LISTEN_PORT); + SWOOLE_DEFINE(ERROR_SERVER_TOO_MANY_LISTEN_PORT); + SWOOLE_DEFINE(ERROR_SERVER_PIPE_BUFFER_FULL); + SWOOLE_DEFINE(ERROR_SERVER_NO_IDLE_WORKER); + SWOOLE_DEFINE(ERROR_SERVER_ONLY_START_ONE); + SWOOLE_DEFINE(ERROR_SERVER_WORKER_EXIT_TIMEOUT); + + /** + * trace log + */ + SWOOLE_DEFINE(TRACE_SERVER); + SWOOLE_DEFINE(TRACE_CLIENT); + SWOOLE_DEFINE(TRACE_BUFFER); + SWOOLE_DEFINE(TRACE_CONN); + SWOOLE_DEFINE(TRACE_EVENT); + SWOOLE_DEFINE(TRACE_WORKER); + SWOOLE_DEFINE(TRACE_REACTOR); + SWOOLE_DEFINE(TRACE_PHP); + SWOOLE_DEFINE(TRACE_HTTP2); + SWOOLE_DEFINE(TRACE_EOF_PROTOCOL); + SWOOLE_DEFINE(TRACE_LENGTH_PROTOCOL); + SWOOLE_DEFINE(TRACE_CLOSE); + SWOOLE_DEFINE(TRACE_HTTP_CLIENT); + SWOOLE_DEFINE(TRACE_COROUTINE); + SWOOLE_DEFINE(TRACE_REDIS_CLIENT); + SWOOLE_DEFINE(TRACE_MYSQL_CLIENT); + SWOOLE_DEFINE(TRACE_AIO); + REGISTER_LONG_CONSTANT("SWOOLE_TRACE_ALL", 0xffffffff, CONST_CS | CONST_PERSISTENT); + + /** + * log level + */ + SWOOLE_DEFINE(LOG_DEBUG); + SWOOLE_DEFINE(LOG_TRACE); + SWOOLE_DEFINE(LOG_INFO); + SWOOLE_DEFINE(LOG_NOTICE); + SWOOLE_DEFINE(LOG_WARNING); + SWOOLE_DEFINE(LOG_ERROR); + + SWOOLE_DEFINE(IPC_NONE); + SWOOLE_DEFINE(IPC_UNIXSOCK); + SWOOLE_DEFINE(IPC_SOCKET); + + SWOOLE_INIT_CLASS_ENTRY(swoole_server_ce, "swoole_server", "Swoole\\Server", swoole_server_methods); + swoole_server_class_entry_ptr = zend_register_internal_class(&swoole_server_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_server, "Swoole\\Server"); + + if (!SWOOLE_G(use_shortname)) + { + sw_zend_hash_del(CG(function_table), ZEND_STRS("go")); + } + else + { + sw_zend_register_class_alias("Co\\Server", swoole_server_class_entry_ptr); + } + + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onReceive"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onPacket"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onBufferFull"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onBufferEmpty"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onStart"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onShutdown"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onWorkerStart"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onWorkerStop"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onWorkerExit"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onWorkerError"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onTask"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onFinish"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onManagerStart"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onManagerStop"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("onPipeMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("connections"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("port"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("mode"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_class_entry_ptr, ZEND_STRL("ports"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("master_pid"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("manager_pid"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("worker_id"), -1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_server_class_entry_ptr, ZEND_STRL("taskworker"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_class_entry_ptr, ZEND_STRL("worker_pid"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + SWOOLE_INIT_CLASS_ENTRY(swoole_timer_ce, "swoole_timer", "Swoole\\Timer", swoole_timer_methods); + swoole_timer_class_entry_ptr = zend_register_internal_class(&swoole_timer_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_timer, "Swoole\\Timer"); + + SWOOLE_INIT_CLASS_ENTRY(swoole_event_ce, "swoole_event", "Swoole\\Event", swoole_event_methods); + swoole_event_class_entry_ptr = zend_register_internal_class(&swoole_event_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_event, "Swoole\\Event"); + + SWOOLE_INIT_CLASS_ENTRY(swoole_async_ce, "swoole_async", "Swoole\\Async", swoole_async_methods); + swoole_async_class_entry_ptr = zend_register_internal_class(&swoole_async_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_async, "Swoole\\Async"); + + +#ifdef HAVE_PCRE + SWOOLE_INIT_CLASS_ENTRY(swoole_connection_iterator_ce, "swoole_connection_iterator", "Swoole\\Connection\\Iterator", swoole_connection_iterator_methods); + swoole_connection_iterator_class_entry_ptr = zend_register_internal_class(&swoole_connection_iterator_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_connection_iterator, "Swoole\\Connection\\Iterator"); + zend_class_implements(swoole_connection_iterator_class_entry_ptr TSRMLS_CC, 3, spl_ce_Iterator, spl_ce_Countable, spl_ce_ArrayAccess); +#endif + + SWOOLE_INIT_CLASS_ENTRY(swoole_exception_ce, "swoole_exception", "Swoole\\Exception", NULL); + swoole_exception_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_exception_ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_exception, "Swoole\\Exception"); + + //swoole init + swoole_init(); + swoole_server_port_init(module_number TSRMLS_CC); + swoole_client_init(module_number TSRMLS_CC); +#ifdef SW_COROUTINE + swoole_socket_coro_init(module_number TSRMLS_CC); + swoole_client_coro_init(module_number TSRMLS_CC); +#ifdef SW_USE_REDIS + swoole_redis_coro_init(module_number TSRMLS_CC); +#endif +#ifdef SW_USE_POSTGRESQL + swoole_postgresql_coro_init(module_number TSRMLS_CC); +#endif + swoole_mysql_coro_init(module_number TSRMLS_CC); + swoole_http_client_coro_init(module_number TSRMLS_CC); + swoole_coroutine_util_init(module_number TSRMLS_CC); +#endif + swoole_http_client_init(module_number TSRMLS_CC); + swoole_async_init(module_number TSRMLS_CC); + swoole_process_init(module_number TSRMLS_CC); + swoole_process_pool_init(module_number TSRMLS_CC); + swoole_table_init(module_number TSRMLS_CC); +#ifdef SW_USE_PHPX + swoole_runtime_init(module_number TSRMLS_CC); +#endif + swoole_lock_init(module_number TSRMLS_CC); + swoole_atomic_init(module_number TSRMLS_CC); + swoole_http_server_init(module_number TSRMLS_CC); + swoole_buffer_init(module_number TSRMLS_CC); + swoole_websocket_init(module_number TSRMLS_CC); + swoole_mysql_init(module_number TSRMLS_CC); + swoole_mmap_init(module_number TSRMLS_CC); + swoole_channel_init(module_number TSRMLS_CC); +#ifdef SW_COROUTINE + swoole_channel_coro_init(module_number TSRMLS_CC); +#endif + swoole_ringqueue_init(module_number TSRMLS_CC); + swoole_msgqueue_init(module_number TSRMLS_CC); +#ifdef SW_USE_HTTP2 + swoole_http2_client_init(module_number TSRMLS_CC); +#ifdef SW_COROUTINE + swoole_http2_client_coro_init(module_number TSRMLS_CC); +#endif +#endif + + swoole_serialize_init(module_number TSRMLS_DC); + swoole_memory_pool_init(module_number TSRMLS_DC); + +#ifdef SW_USE_REDIS + swoole_redis_init(module_number TSRMLS_CC); +#endif + swoole_redis_server_init(module_number TSRMLS_CC); + + if (SWOOLE_G(socket_buffer_size) > 0) + { + SwooleG.socket_buffer_size = SWOOLE_G(socket_buffer_size); + } + +#ifdef __MACH__ + SwooleG.socket_buffer_size = 256 * 1024; +#endif + + //default 60s + SwooleG.dns_cache_refresh_time = 60; + + + if (SWOOLE_G(aio_thread_num) > 0) + { + if (SWOOLE_G(aio_thread_num) > SW_AIO_THREAD_NUM_MAX) + { + SWOOLE_G(aio_thread_num) = SW_AIO_THREAD_NUM_MAX; + } + SwooleAIO.thread_num = SWOOLE_G(aio_thread_num); + } + + if (strcasecmp("cli", sapi_module.name) == 0) + { + SWOOLE_G(cli) = 1; + } + + swoole_objects.size = 65536; + swoole_objects.array = calloc(swoole_objects.size, sizeof(void*)); + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(swoole) +{ + swoole_clean(); + + return SUCCESS; +} +/* }}} */ + + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(swoole) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "swoole support", "enabled"); + php_info_print_table_row(2, "Version", PHP_SWOOLE_VERSION); + php_info_print_table_row(2, "Author", "tianfeng.han[email: mikan.tenny@gmail.com]"); + +#ifdef SW_COROUTINE + php_info_print_table_row(2, "coroutine", "enabled"); +#endif +#if USE_BOOST_CONTEXT + php_info_print_table_row(2, "boost.context", "enabled"); +#endif +#if USE_UCONTEXT + php_info_print_table_row(2, "ucontext", "enabled"); +#endif +#ifdef HAVE_EPOLL + php_info_print_table_row(2, "epoll", "enabled"); +#endif +#ifdef HAVE_EVENTFD + php_info_print_table_row(2, "eventfd", "enabled"); +#endif +#ifdef HAVE_KQUEUE + php_info_print_table_row(2, "kqueue", "enabled"); +#endif +#ifdef HAVE_TIMERFD + php_info_print_table_row(2, "timerfd", "enabled"); +#endif +#ifdef HAVE_SIGNALFD + php_info_print_table_row(2, "signalfd", "enabled"); +#endif +#ifdef SW_USE_ACCEPT4 + php_info_print_table_row(2, "accept4", "enabled"); +#endif +#ifdef HAVE_CPU_AFFINITY + php_info_print_table_row(2, "cpu affinity", "enabled"); +#endif +#ifdef HAVE_SPINLOCK + php_info_print_table_row(2, "spinlock", "enabled"); +#endif +#ifdef HAVE_RWLOCK + php_info_print_table_row(2, "rwlock", "enabled"); +#endif +#ifdef SW_ASYNC_MYSQL + php_info_print_table_row(2, "async mysql client", "enabled"); +#endif +#ifdef SW_USE_POSTGRESQL + php_info_print_table_row(2, "async postgresql", "enabled"); +#endif +#ifdef SW_USE_REDIS + php_info_print_table_row(2, "async redis client", "enabled"); +#endif + php_info_print_table_row(2, "async http/websocket client", "enabled"); +#ifdef SW_SOCKETS + php_info_print_table_row(2, "sockets", "enabled"); +#endif +#ifdef SW_USE_OPENSSL + php_info_print_table_row(2, "openssl", "enabled"); +#endif +#ifdef SW_USE_HTTP2 + php_info_print_table_row(2, "http2", "enabled"); +#endif +#ifdef SW_USE_RINGBUFFER + php_info_print_table_row(2, "ringbuffer", "enabled"); +#endif +#ifdef HAVE_LINUX_AIO + php_info_print_table_row(2, "Linux Native AIO", "enabled"); +#endif +#ifdef HAVE_GCC_AIO + php_info_print_table_row(2, "GCC AIO", "enabled"); +#endif +#ifdef HAVE_PCRE + php_info_print_table_row(2, "pcre", "enabled"); +#endif +#ifdef SW_HAVE_ZLIB + php_info_print_table_row(2, "zlib", "enabled"); +#endif +#ifdef HAVE_MUTEX_TIMEDLOCK + php_info_print_table_row(2, "mutex_timedlock", "enabled"); +#endif +#ifdef HAVE_PTHREAD_BARRIER + php_info_print_table_row(2, "pthread_barrier", "enabled"); +#endif +#ifdef HAVE_FUTEX + php_info_print_table_row(2, "futex", "enabled"); +#endif +#ifdef SW_USE_MYSQLND + php_info_print_table_row(2, "mysqlnd", "enabled"); +#endif +#ifdef SW_USE_JEMALLOC + php_info_print_table_row(2, "jemalloc", "enabled"); +#endif +#ifdef SW_USE_TCMALLOC + php_info_print_table_row(2, "tcmalloc", "enabled"); +#endif +#ifdef SW_USE_HUGEPAGE + php_info_print_table_row(2, "hugepage", "enabled"); +#endif +#ifdef SW_DEBUG + php_info_print_table_row(2, "debug", "enabled"); +#endif + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + +PHP_RINIT_FUNCTION(swoole) +{ + SWOOLE_G(req_status) = PHP_SWOOLE_RINIT_BEGIN; + php_swoole_at_shutdown("swoole_call_user_shutdown_begin"); + //running + SwooleG.running = 1; + +#ifdef ZTS + if (sw_thread_ctx == NULL) + { + TSRMLS_SET_CTX(sw_thread_ctx); + } +#endif + +#ifdef SW_DEBUG_REMOTE_OPEN + swoole_open_remote_debug(); +#endif + SWOOLE_G(req_status) = PHP_SWOOLE_RINIT_END; + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(swoole) +{ + SWOOLE_G(req_status) = PHP_SWOOLE_RSHUTDOWN_BEGIN; + swoole_call_rshutdown_function(NULL); + //clear pipe buffer + if (swIsWorker()) + { + swWorker_clean(); + } + + if (SwooleG.serv && SwooleG.serv->gs->start > 0 && SwooleG.running > 0) + { + if (PG(last_error_message)) + { + switch(PG(last_error_type)) + { + case E_ERROR: + case E_CORE_ERROR: + case E_USER_ERROR: + case E_COMPILE_ERROR: + swoole_error_log(SW_LOG_ERROR, SW_ERROR_PHP_FATAL_ERROR, "Fatal error: %s in %s on line %d.", + PG(last_error_message), PG(last_error_file)?PG(last_error_file):"-", PG(last_error_lineno)); + break; + default: + break; + } + } + else + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SERVER_WORKER_TERMINATED, "worker process is terminated by exit()/die()."); + } + } + + if (SwooleAIO.init) + { + swAio_free(); + } + + SwooleWG.reactor_wait_onexit = 0; + +#ifdef SW_COROUTINE + coro_destroy(TSRMLS_C); +#endif + SWOOLE_G(req_status) = PHP_SWOOLE_RSHUTDOWN_END; + return SUCCESS; +} + +PHP_FUNCTION(swoole_version) +{ + char swoole_version[32] = {0}; + snprintf(swoole_version, sizeof(PHP_SWOOLE_VERSION), "%s", PHP_SWOOLE_VERSION); + SW_RETURN_STRING(swoole_version, 1); +} + +static uint32_t hashkit_one_at_a_time(const char *key, size_t key_length) +{ + const char *ptr = key; + uint32_t value = 0; + + while (key_length--) + { + uint32_t val = (uint32_t) *ptr++; + value += val; + value += (value << 10); + value ^= (value >> 6); + } + value += (value << 3); + value ^= (value >> 11); + value += (value << 15); + + return value; +} + +static PHP_FUNCTION(swoole_hashcode) +{ + char *data; + zend_size_t l_data; + zend_long type = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(data, l_data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(type) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &l_data, &type) == FAILURE) + { + return; + } +#endif + switch(type) + { + case 1: + RETURN_LONG(hashkit_one_at_a_time(data, l_data)); + default: + RETURN_LONG(zend_hash_func(data, l_data)); + } +} + +PHP_FUNCTION(swoole_unsupport_serialize) +{ + zend_throw_exception_ex(swoole_exception_class_entry_ptr, 0 TSRMLS_CC, "cannot serialize or unserialize."); +} + +static PHP_FUNCTION(swoole_last_error) +{ + RETURN_LONG(SwooleG.error); +} + +PHP_FUNCTION(swoole_cpu_num) +{ + long cpu_num = 1; + cpu_num = sysconf(_SC_NPROCESSORS_CONF); + if (cpu_num < 1) + { + cpu_num = 1; + } + RETURN_LONG(cpu_num); +} + +PHP_FUNCTION(swoole_strerror) +{ + long swoole_errno = 0; + char error_msg[256] = {0}; + long error_type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &swoole_errno, &error_type) == FAILURE) + { + return; + } + if (error_type == 1) + { + snprintf(error_msg, sizeof(error_msg) - 1, "%s", gai_strerror(swoole_errno)); + } + else if (error_type == 2) + { + snprintf(error_msg, sizeof(error_msg) - 1, "%s", hstrerror(swoole_errno)); + } + else + { + snprintf(error_msg, sizeof(error_msg) - 1, "%s", strerror(swoole_errno)); + } + SW_RETURN_STRING(error_msg, 1); +} + +PHP_FUNCTION(swoole_errno) +{ + RETURN_LONG(errno); +} + +PHP_FUNCTION(swoole_set_process_name) +{ + // MacOS doesn't support 'cli_set_process_title' +#ifdef __MACH__ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_set_process_name is not supported on MacOS."); + return; +#endif + zval *name; + long size = 128; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &name, &size) == FAILURE) + { + return; + } + + if (Z_STRLEN_P(name) == 0) + { + return; + } + else if (Z_STRLEN_P(name) > 127) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "process name is too long, the max length is 127"); + } + + if (size > SwooleG.pagesize) + { + size = SwooleG.pagesize; + } + +#if PHP_MAJOR_VERSION >= 7 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 4) + zval *retval; + zval **args[1]; + args[0] = &name; + + zval *function; + SW_MAKE_STD_ZVAL(function); + SW_ZVAL_STRING(function, "cli_set_process_title", 1); + + if (sw_call_user_function_ex(EG(function_table), NULL, function, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&function); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +#else + bzero(sapi_module.executable_location, size); + memcpy(sapi_module.executable_location, Z_STRVAL_P(name), Z_STRLEN_P(name)); +#endif +} + +PHP_FUNCTION(swoole_get_local_ip) +{ + struct sockaddr_in *s4; + struct ifaddrs *ipaddrs, *ifa; + void *in_addr; + char ip[64]; + + if (getifaddrs(&ipaddrs) != 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "getifaddrs() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + array_init(return_value); + for (ifa = ipaddrs; ifa != NULL; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == NULL || !(ifa->ifa_flags & IFF_UP)) + { + continue; + } + + switch (ifa->ifa_addr->sa_family) + { + case AF_INET: + s4 = (struct sockaddr_in *)ifa->ifa_addr; + in_addr = &s4->sin_addr; + break; + case AF_INET6: + //struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr; + //in_addr = &s6->sin6_addr; + continue; + default: + continue; + } + if (!inet_ntop(ifa->ifa_addr->sa_family, in_addr, ip, sizeof(ip))) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: inet_ntop failed.", ifa->ifa_name); + } + else + { + //if (ifa->ifa_addr->sa_family == AF_INET && ntohl(((struct in_addr *) in_addr)->s_addr) == INADDR_LOOPBACK) + if (strcmp(ip, "127.0.0.1") == 0) + { + continue; + } + sw_add_assoc_string(return_value, ifa->ifa_name, ip, 1); + } + } + freeifaddrs(ipaddrs); +} + +PHP_FUNCTION(swoole_get_local_mac) +{ +#ifdef SIOCGIFHWADDR + struct ifconf ifc; + struct ifreq buf[16]; + char mac[32] = {0}; + + int sock; + int i = 0,num = 0; + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "new socket failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + array_init(return_value); + + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = (caddr_t) buf; + if (!ioctl(sock, SIOCGIFCONF, (char *) &ifc)) + { + num = ifc.ifc_len / sizeof (struct ifreq); + while (i < num) + { + if (!(ioctl(sock, SIOCGIFHWADDR, (char *) &buf[i]))) + { + sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", + (unsigned char) buf[i].ifr_hwaddr.sa_data[0], + (unsigned char) buf[i].ifr_hwaddr.sa_data[1], + (unsigned char) buf[i].ifr_hwaddr.sa_data[2], + (unsigned char) buf[i].ifr_hwaddr.sa_data[3], + (unsigned char) buf[i].ifr_hwaddr.sa_data[4], + (unsigned char) buf[i].ifr_hwaddr.sa_data[5]); + sw_add_assoc_string(return_value, buf[i].ifr_name, mac, 1); + } + i++; + } + } + close(sock); +#else + php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_get_local_mac is not supported."); + RETURN_FALSE; +#endif +} + +PHP_FUNCTION(swoole_call_user_shutdown_begin) +{ + SWOOLE_G(req_status) = PHP_SWOOLE_CALL_USER_SHUTDOWNFUNC_BEGIN; + RETURN_TRUE; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/vendor/swoole/swoole_async.c b/vendor/swoole/swoole_async.c new file mode 100755 index 0000000..45db4b6 --- /dev/null +++ b/vendor/swoole/swoole_async.c @@ -0,0 +1,1303 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "php_streams.h" +#include "php_network.h" + +#include "ext/standard/file.h" + + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#include "ext/standard/basic_functions.h" +#include <setjmp.h> +#endif + + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + zval _callback; + zval _filename; +#endif + zval *callback; + zval *filename; + int fd; + off_t offset; + uint16_t type; + uint8_t once; + char *content; + uint32_t length; +} file_request; + +typedef struct +{ + int fd; + off_t offset; +} file_handle; + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + zval _callback; + zval _domain; +#endif + zval *callback; + zval *domain; +#ifdef SW_COROUTINE + php_context *context; //add for coro + uint8_t useless; //1 代表没有用 + swTimer_node *timer; +#endif + +} dns_request; + +typedef struct +{ + swString *zaddress; + int64_t update_time; +} dns_cache; + +typedef struct +{ + zval *callback; +#ifdef SW_COROUTINE + php_context *context; +#endif + pid_t pid; + int fd; + swString *buffer; +} process_stream; + +static void php_swoole_aio_onComplete(swAio_event *event); +static void php_swoole_dns_callback(char *domain, swDNSResolver_result *result, void *data); +#ifdef SW_COROUTINE +static void php_swoole_dns_callback_coro(char *domain, swDNSResolver_result *result, void *data); +static void php_swoole_dns_timeout_coro(swTimer *timer, swTimer_node *tnode); +#endif + +static void php_swoole_file_request_free(void *data); + +static swHashMap *php_swoole_open_files; +static swHashMap *php_swoole_aio_request; + +#ifdef SW_COROUTINE +static swHashMap *request_cache_map = NULL; //以domin为区分 +#endif + +#ifdef SW_COROUTINE +static sw_inline int64_t swTimer_get_now_msec() +{ + struct timeval now; + if (swTimer_now(&now) < 0) + { + return SW_ERR; + } + int64_t msec1 = (now.tv_sec) * 1000; + int64_t msec2 = (now.tv_usec) / 1000; + return msec1 + msec2; +} +#endif + +static void php_swoole_file_request_free(void *data) +{ + file_request *file_req = data; + if (file_req->callback) + { + sw_zval_ptr_dtor(&file_req->callback); + } + efree(file_req->content); + sw_zval_ptr_dtor(&file_req->filename); + efree(file_req); +} + +void swoole_async_init(int module_number TSRMLS_DC) +{ + bzero(&SwooleAIO, sizeof(SwooleAIO)); + + REGISTER_LONG_CONSTANT("SWOOLE_AIO_BASE", 0, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_AIO_LINUX", 0, CONST_CS | CONST_PERSISTENT); + + php_swoole_open_files = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + if (php_swoole_open_files == NULL) + { + swoole_php_fatal_error(E_ERROR, "create hashmap[1] failed."); + } + php_swoole_aio_request = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, php_swoole_file_request_free); + if (php_swoole_aio_request == NULL) + { + swoole_php_fatal_error(E_ERROR, "create hashmap[2] failed."); + } +} + +void php_swoole_check_aio() +{ + if (SwooleAIO.init == 0) + { + php_swoole_check_reactor(); + swAio_init(); + } + if (!SwooleAIO.callback) + { + SwooleAIO.callback = php_swoole_aio_onComplete; + } +} + +static void php_swoole_dns_callback(char *domain, swDNSResolver_result *result, void *data) +{ + SWOOLE_GET_TSRMLS; + dns_request *req = data; + zval *retval = NULL; + zval *zaddress; + zval **args[2]; + char *address; + + SW_MAKE_STD_ZVAL(zaddress); + if (result->num > 0) + { + if (SwooleG.dns_lookup_random) + { + address = result->hosts[rand() % result->num].address; + } + else + { + address = result->hosts[0].address; + } + SW_ZVAL_STRING(zaddress, address, 1); + } + else + { + SW_ZVAL_STRING(zaddress, "", 1); + } + + args[0] = &req->domain; + args[1] = &zaddress; + + zval *zcallback = req->callback; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_asyns_dns_lookup handler error."); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + + sw_zval_ptr_dtor(&req->callback); + sw_zval_ptr_dtor(&req->domain); + efree(req); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zaddress); +} + +//用于coro 回调 +#ifdef SW_COROUTINE +static void php_swoole_dns_callback_coro(char *domain, swDNSResolver_result *result, void *data) +{ + SWOOLE_GET_TSRMLS; + dns_request *req = data; + zval *retval = NULL; + + zval *zaddress; + char *address; + SW_MAKE_STD_ZVAL(zaddress); + if (result->num > 0) + { + if (SwooleG.dns_lookup_random) + { + address = result->hosts[rand() % result->num].address; + } + else + { + address = result->hosts[0].address; + } + + SW_ZVAL_STRING(zaddress, address, 1); + } + else + { + SW_ZVAL_STRING(zaddress, "", 1); + } + + //update cache + dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain)); + if (cache == NULL ) + { + cache = emalloc(sizeof(dns_cache)); + swHashMap_add(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain), cache); + cache->zaddress = swString_new(20); + } + + swString_write_ptr(cache->zaddress, 0, Z_STRVAL_P(zaddress), Z_STRLEN_P(zaddress)); + + cache->update_time = (int64_t) swTimer_get_now_msec + (int64_t) (SwooleG.dns_cache_refresh_time * 1000); + + //timeout + if (req->timer) + { + swTimer_del(&SwooleG.timer, req->timer); + req->timer = NULL; + } + if (req->useless) + { + efree(req); + return; + } + + int ret = coro_resume(req->context, zaddress, &retval); + if (ret > 0) + { + goto free_zdata; + } + + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + //说明已经yield走了 + free_zdata: + // free 上下文 + sw_zval_ptr_dtor(&zaddress); + efree(req->context); + efree(req); +} + +//用于timeout +static void php_swoole_dns_timeout_coro(swTimer *timer, swTimer_node *tnode) +{ + zval *retval = NULL; + zval *zaddress; + php_context *cxt = (php_context *) tnode->data; +#if PHP_MAJOR_VERSION < 7 + dns_request *req =(dns_request *) cxt->coro_params; +#else + dns_request *req = (dns_request *) cxt->coro_params.value.ptr; +#endif + + SW_MAKE_STD_ZVAL(zaddress); + + dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(req->domain), Z_STRLEN_P(req->domain)); + if (cache != NULL && cache->update_time > (int64_t) swTimer_get_now_msec) + { + SW_ZVAL_STRINGL(zaddress, (*cache->zaddress).str, (*cache->zaddress).length, 1); + } + else + { + SW_ZVAL_STRING(zaddress, "", 1); + } + + int ret = coro_resume(req->context, zaddress, &retval); + if (ret > 0) + { + goto free_zdata; + } + + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + free_zdata: + sw_zval_ptr_dtor(&zaddress); + efree(req->context); + req->useless = 1; + +} +#endif + +static void php_swoole_aio_onComplete(swAio_event *event) +{ + int isEOF = SW_FALSE; + int64_t ret; + + zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; + zval *zcontent = NULL; + zval **args[2]; + file_request *file_req = NULL; + dns_request *dns_req = NULL; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#else + zval _zcontent; + zval _zwriten; + bzero(&_zcontent, sizeof(zval)); + bzero(&_zwriten, sizeof(zval)); +#endif + + if (event->type == SW_AIO_GETHOSTBYNAME) + { + dns_req = (dns_request *) event->req; + if (dns_req->callback == NULL) + { + swoole_php_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[0]"); + return; + } + zcallback = dns_req->callback; + } + else + { + file_req = swHashMap_find_int(php_swoole_aio_request, event->task_id); + if (!file_req) + { + swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); + return; + } + if (file_req->callback == NULL && file_req->type == SW_AIO_READ) + { + swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); + return; + } + zcallback = file_req->callback; + } + + ret = event->ret; + if (ret < 0) + { + SwooleG.error = event->error; + swoole_php_error(E_WARNING, "Aio Error: %s[%d]", strerror(event->error), event->error); + } + else if (file_req != NULL) + { + if (ret == 0) + { + bzero(event->buf, event->nbytes); + isEOF = SW_TRUE; + } + else if (file_req->once == 1 && ret < file_req->length) + { + swoole_php_fatal_error(E_WARNING, "ret_length[%d] < req->length[%d].", (int ) ret, file_req->length); + } + else if (event->type == SW_AIO_READ) + { + file_req->offset += event->ret; + } + } + + if (event->type == SW_AIO_READ) + { + args[0] = &file_req->filename; + args[1] = &zcontent; +#if PHP_MAJOR_VERSION < 7 + SW_MAKE_STD_ZVAL(zcontent); +#else + zcontent = &_zcontent; +#endif + if (ret < 0) + { + SW_ZVAL_STRING(zcontent, "", 1); + } + else + { + SW_ZVAL_STRINGL(zcontent, event->buf, ret, 1); + } + } + else if (event->type == SW_AIO_WRITE) + { +#if PHP_MAJOR_VERSION < 7 + SW_MAKE_STD_ZVAL(zwriten); +#else + zwriten = &_zwriten; +#endif + args[0] = &file_req->filename; + args[1] = &zwriten; + ZVAL_LONG(zwriten, ret); + } + else if(event->type == SW_AIO_GETHOSTBYNAME) + { + args[0] = &dns_req->domain; +#if PHP_MAJOR_VERSION < 7 + SW_MAKE_STD_ZVAL(zcontent); +#else + zcontent = &_zcontent; +#endif + if (ret < 0) + { + SW_ZVAL_STRING(zcontent, "", 1); + } + else + { + SW_ZVAL_STRING(zcontent, event->buf, 1); + } + args[1] = &zcontent; + } + else + { + swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete unknown event type[%d].", event->type); + return; + } + + if (zcallback) + { + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + } + + //file io + if (file_req) + { + if (file_req->once == 1) + { + close_file: + close(event->fd); + swHashMap_del_int(php_swoole_aio_request, event->task_id); + } + else if(file_req->type == SW_AIO_WRITE) + { + if (retval != NULL && !ZVAL_IS_NULL(retval) && !Z_BVAL_P(retval)) + { + swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename)); + goto close_file; + } + else + { + swHashMap_del_int(php_swoole_aio_request, event->task_id); + } + } + else + { + if ((retval != NULL && !ZVAL_IS_NULL(retval) && !Z_BVAL_P(retval)) || isEOF) + { + goto close_file; + } + //Less than expected, at the end of the file + else if (event->ret < event->nbytes) + { + event->ret = 0; + php_swoole_aio_onComplete(event); + } + //continue to read + else + { + int ret = SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset); + if (ret < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error); + goto close_file; + } + else + { + swHashMap_move_int(php_swoole_aio_request, event->task_id, ret); + } + } + } + } + else if (dns_req) + { + sw_zval_ptr_dtor(&dns_req->callback); + sw_zval_ptr_dtor(&dns_req->domain); + efree(dns_req); + efree(event->buf); + } + if (zcontent) + { + sw_zval_ptr_dtor(&zcontent); + } + if (zwriten) + { + sw_zval_ptr_dtor(&zwriten); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +PHP_FUNCTION(swoole_async_read) +{ + zval *callback; + zval *filename; + long buf_size = SW_AIO_DEFAULT_CHUNK_SIZE; + long offset = 0; + int open_flag = O_RDONLY; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|ll", &filename, &callback, &buf_size, &offset) == FAILURE) + { + return; + } + + if (offset < 0) + { + swoole_php_fatal_error(E_WARNING, "offset must be greater than 0."); + RETURN_FALSE; + } + if (buf_size > SW_AIO_MAX_CHUNK_SIZE) + { + buf_size = SW_AIO_MAX_CHUNK_SIZE; + } + + convert_to_string(filename); + int fd = open(Z_STRVAL_P(filename), open_flag, 0644); + if (fd < 0) + { + swoole_php_sys_error(E_WARNING, "open(%s, O_RDONLY) failed.", Z_STRVAL_P(filename)); + RETURN_FALSE; + } + + struct stat file_stat; + if (fstat(fd, &file_stat) < 0) + { + swoole_php_sys_error(E_WARNING, "fstat(%s) failed.", Z_STRVAL_P(filename)); + close(fd); + RETURN_FALSE; + } + if (offset >= file_stat.st_size) + { + swoole_php_fatal_error(E_WARNING, "offset must be less than file_size[=%ld].", file_stat.st_size); + close(fd); + RETURN_FALSE; + } + + void *fcnt = emalloc(buf_size); + if (fcnt == NULL) + { + swoole_php_sys_error(E_WARNING, "malloc failed."); + close(fd); + RETURN_FALSE; + } + + file_request *req = emalloc(sizeof(file_request)); + req->fd = fd; + + req->filename = filename; + sw_zval_add_ref(&filename); + sw_copy_to_stack(req->filename, req->_filename); + + if (callback && !ZVAL_IS_NULL(callback)) + { + req->callback = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(req->callback, req->_callback); + } + + req->content = fcnt; + req->once = 0; + req->type = SW_AIO_READ; + req->length = buf_size; + req->offset = offset; + + php_swoole_check_aio(); + + int ret = SwooleAIO.read(fd, fcnt, buf_size, offset); + if (ret == SW_ERR) + { + RETURN_FALSE; + } + else + { + swHashMap_add_int(php_swoole_aio_request, ret, req); + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_async_write) +{ + zval *callback = NULL; + zval *filename; + + char *fcnt; + zend_size_t fcnt_len = 0; + off_t offset = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs|lz", &filename, &fcnt, &fcnt_len, &offset, &callback) == FAILURE) + { + return; + } + if (fcnt_len <= 0) + { + RETURN_FALSE; + } + if (callback && !ZVAL_IS_NULL(callback)) + { + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + } + + convert_to_string(filename); + + long fd = (long) swHashMap_find(php_swoole_open_files, Z_STRVAL_P(filename), Z_STRLEN_P(filename)); + if (fd == 0) + { + int open_flag = O_WRONLY | O_CREAT; + if (offset < 0) + { + open_flag |= O_APPEND; + } + fd = open(Z_STRVAL_P(filename), open_flag, 0644); + if (fd < 0) + { + swoole_php_fatal_error(E_WARNING, "open(%s, %d) failed. Error: %s[%d]", Z_STRVAL_P(filename), open_flag, strerror(errno), errno); + RETURN_FALSE; + } + swHashMap_add(php_swoole_open_files, Z_STRVAL_P(filename), Z_STRLEN_P(filename), (void*) fd); + } + + if (offset < 0) + { + offset = 0; + } + + file_request *req = emalloc(sizeof(file_request)); + char *wt_cnt = emalloc(fcnt_len); + req->fd = fd; + req->content = wt_cnt; + req->once = 0; + req->type = SW_AIO_WRITE; + req->length = fcnt_len; + req->offset = offset; + req->filename = filename; + sw_zval_add_ref(&filename); + sw_copy_to_stack(req->filename, req->_filename); + + if (callback && !ZVAL_IS_NULL(callback)) + { + req->callback = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(req->callback, req->_callback); + } + else + { + req->callback = NULL; + } + + memcpy(wt_cnt, fcnt, fcnt_len); + php_swoole_check_aio(); + + int ret = SwooleAIO.write(fd, wt_cnt, fcnt_len, offset); + if (ret == SW_ERR) + { + RETURN_FALSE; + } + else + { + swHashMap_add_int(php_swoole_aio_request, ret, req); + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_async_readfile) +{ + zval *callback; + zval *filename; + + int open_flag = O_RDONLY; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &filename, &callback) == FAILURE) + { + return; + } + convert_to_string(filename); + + int fd = open(Z_STRVAL_P(filename), open_flag, 0644); + if (fd < 0) + { + swoole_php_fatal_error(E_WARNING, "open file[%s] failed. Error: %s[%d]", Z_STRVAL_P(filename), strerror(errno), errno); + RETURN_FALSE; + } + struct stat file_stat; + if (fstat(fd, &file_stat) < 0) + { + swoole_php_fatal_error(E_WARNING, "fstat failed. Error: %s[%d]", strerror(errno), errno); + close(fd); + RETURN_FALSE; + } + if (file_stat.st_size <= 0) + { + swoole_php_fatal_error(E_WARNING, "file is empty."); + close(fd); + RETURN_FALSE; + } + if (file_stat.st_size > SW_AIO_MAX_FILESIZE) + { + swoole_php_fatal_error(E_WARNING, "file_size[size=%ld|max_size=%d] is too big. Please use swoole_async_read.", + (long int) file_stat.st_size, SW_AIO_MAX_FILESIZE); + close(fd); + RETURN_FALSE; + } + + size_t length = file_stat.st_size; + file_request *req = emalloc(sizeof(file_request)); + req->fd = fd; + + req->filename = filename; + sw_zval_add_ref(&filename); + sw_copy_to_stack(req->filename, req->_filename); + + if (callback && !ZVAL_IS_NULL(callback)) + { + req->callback = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(req->callback, req->_callback); + } + + req->content = emalloc(length); + req->once = 1; + req->type = SW_AIO_READ; + req->length = length; + req->offset = 0; + + php_swoole_check_aio(); + + int ret = SwooleAIO.read(fd, req->content, length, 0); + if (ret == SW_ERR) + { + RETURN_FALSE; + } + else + { + swHashMap_add_int(php_swoole_aio_request, ret, req); + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_async_writefile) +{ + zval *callback = NULL; + zval *filename; + char *fcnt; + zend_size_t fcnt_len; + long flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "zs|zl", &filename, &fcnt, &fcnt_len, &callback, &flags) == FAILURE) + { + return; + } + int open_flag = O_CREAT | O_WRONLY; + if (flags & PHP_FILE_APPEND) + { + open_flag |= O_APPEND; + } + else + { + open_flag |= O_TRUNC; + } + if (fcnt_len <= 0) + { + RETURN_FALSE; + } + if (fcnt_len > SW_AIO_MAX_FILESIZE) + { + swoole_php_fatal_error(E_WARNING, "file_size[size=%d|max_size=%d] is too big. Please use swoole_async_write.", + fcnt_len, SW_AIO_MAX_FILESIZE); + RETURN_FALSE; + } + if (callback && !ZVAL_IS_NULL(callback)) + { + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + } + + convert_to_string(filename); + int fd = open(Z_STRVAL_P(filename), open_flag, 0644); + if (fd < 0) + { + swoole_php_fatal_error(E_WARNING, "open file failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + + size_t memory_size = fcnt_len; + char *wt_cnt = emalloc(memory_size); + + file_request *req = emalloc(sizeof(file_request)); + req->filename = filename; + sw_zval_add_ref(&filename); + sw_copy_to_stack(req->filename, req->_filename); + + if (callback && !ZVAL_IS_NULL(callback)) + { + req->callback = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(req->callback, req->_callback); + } + else + { + req->callback = NULL; + } + + req->fd = fd; + req->type = SW_AIO_WRITE; + req->content = wt_cnt; + req->once = 1; + req->length = fcnt_len; + req->offset = 0; + + memcpy(wt_cnt, fcnt, fcnt_len); + + php_swoole_check_aio(); + + int ret = SwooleAIO.write(fd, wt_cnt, memory_size, 0); + if (ret == SW_ERR) + { + RETURN_FALSE; + } + else + { + swHashMap_add_int(php_swoole_aio_request, ret, req); + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_async_set) +{ + if (SwooleG.main_reactor != NULL) + { + swoole_php_fatal_error(E_ERROR, "eventLoop has already been created. unable to change settings."); + RETURN_FALSE; + } + + zval *zset = NULL; + HashTable *vht; + zval *v; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + + php_swoole_array_separate(zset); + + vht = Z_ARRVAL_P(zset); + if (php_swoole_array_get_value(vht, "thread_num", v)) + { + convert_to_long(v); + SwooleAIO.thread_num = (uint8_t) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "enable_signalfd", v)) + { + convert_to_boolean(v); + SwooleG.enable_signalfd = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "dns_cache_refresh_time", v)) + { + convert_to_double(v); + SwooleG.dns_cache_refresh_time = Z_DVAL_P(v); + } + if (php_swoole_array_get_value(vht, "socket_buffer_size", v)) + { + convert_to_long(v); + SwooleG.socket_buffer_size = Z_LVAL_P(v); + if (SwooleG.socket_buffer_size <= 0 || SwooleG.socket_buffer_size > SW_MAX_INT) + { + SwooleG.socket_buffer_size = SW_MAX_INT; + } + } + if (php_swoole_array_get_value(vht, "log_level", v)) + { + convert_to_long(v); + SwooleG.log_level = Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "display_errors", v)) + { + convert_to_boolean(v); + SWOOLE_G(display_errors) = 0; + } + if (php_swoole_array_get_value(vht, "socket_dontwait", v)) + { + convert_to_boolean(v); + SwooleG.socket_dontwait = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "dns_lookup_random", v)) + { + convert_to_boolean(v); + SwooleG.dns_lookup_random = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "dns_server", v)) + { + convert_to_string(v); + SwooleG.dns_server_v4 = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + if (php_swoole_array_get_value(vht, "use_async_resolver", v)) + { + convert_to_boolean(v); + SwooleG.use_async_resolver = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "enable_coroutine", v)) + { + convert_to_boolean(v); + SwooleG.enable_coroutine = Z_BVAL_P(v); + } +#if defined(HAVE_REUSEPORT) && defined(HAVE_EPOLL) + //reuse port + if (php_swoole_array_get_value(vht, "enable_reuse_port", v)) + { + convert_to_boolean(v); + if (Z_BVAL_P(v) && swoole_version_compare(SwooleG.uname.release, "3.9.0") >= 0) + { + SwooleG.reuse_port = 1; + } + } +#endif + sw_zval_ptr_dtor(&zset); +} + +PHP_FUNCTION(swoole_async_dns_lookup) +{ + zval *domain; + zval *cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &domain, &cb) == FAILURE) + { + return; + } + + if (Z_TYPE_P(domain) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "invalid domain name."); + RETURN_FALSE; + } + + if (Z_STRLEN_P(domain) == 0) + { + swoole_php_fatal_error(E_WARNING, "domain name empty."); + RETURN_FALSE; + } + + dns_request *req = emalloc(sizeof(dns_request)); + req->callback = cb; + sw_copy_to_stack(req->callback, req->_callback); + sw_zval_add_ref(&req->callback); + + req->domain = domain; + sw_copy_to_stack(req->domain, req->_domain); + sw_zval_add_ref(&req->domain); + + /** + * Use asynchronous IO + */ + if (SwooleG.use_async_resolver) + { + php_swoole_check_reactor(); + SW_CHECK_RETURN(swDNSResolver_request(Z_STRVAL_P(domain), php_swoole_dns_callback, (void *) req)); + } + + php_swoole_check_aio(); + + /** + * Use thread pool + */ + int buf_size; + if (Z_STRLEN_P(domain) < SW_IP_MAX_LENGTH) + { + buf_size = SW_IP_MAX_LENGTH + 1; + } + else + { + buf_size = Z_STRLEN_P(domain) + 1; + } + + void *buf = emalloc(buf_size); + bzero(buf, buf_size); + memcpy(buf, Z_STRVAL_P(domain), Z_STRLEN_P(domain)); + php_swoole_check_aio(); + SW_CHECK_RETURN(swAio_dns_lookup(req, buf, buf_size)); +} + +static int process_stream_onRead(swReactor *reactor, swEvent *event) +{ + SWOOLE_GET_TSRMLS; + + process_stream *ps = event->socket->object; + char *buf = ps->buffer->str + ps->buffer->length; + size_t len = ps->buffer->size - ps->buffer->length; + + int ret = read(event->fd, buf, len); + if (ret > 0) + { + ps->buffer->length += ret; + if (ps->buffer->length == ps->buffer->size) + { + swString_extend(ps->buffer, ps->buffer->size * 2); + } + return SW_OK; + } + else if (ret < 0) + { + swSysError("read() failed."); + return SW_OK; + } + + zval *retval = NULL; + zval **args[2]; + + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, ps->buffer->str, ps->buffer->length, 1); + + SwooleG.main_reactor->del(SwooleG.main_reactor, ps->fd); + + swString_free(ps->buffer); + args[0] = &zdata; + + int status; + zval *zstatus; + SW_MAKE_STD_ZVAL(zstatus); + + pid_t pid = swWaitpid(ps->pid, &status, WNOHANG); + if (pid > 0) + { + array_init(zstatus); + add_assoc_long(zstatus, "code", WEXITSTATUS(status)); + add_assoc_long(zstatus, "signal", WTERMSIG(status)); + } + else + { + ZVAL_FALSE(zstatus); + } + + args[1] = &zstatus; + + zval *zcallback = ps->callback; + + if (zcallback) + { + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); + } + sw_zval_free(zcallback); + } + else + { +#ifdef SW_COROUTINE + php_context *context = ps->context; + sw_zval_add_ref(&zdata); + add_assoc_zval(zstatus, "output", zdata); + int ret = coro_resume(context, zstatus, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + efree(context); +#else + return SW_OK; +#endif + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); + sw_zval_ptr_dtor(&zstatus); + close(ps->fd); + efree(ps); + + return SW_OK; +} + +PHP_METHOD(swoole_async, exec) +{ + char *command; + zend_size_t command_len; + zval *callback; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &command, &command_len, &callback) == FAILURE) + { + return; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_READ, process_stream_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_ERROR, process_stream_onRead); + } + + pid_t pid; + int fd = swoole_shell_exec(command, &pid); + if (fd < 0) + { + swoole_php_error(E_WARNING, "Unable to execute '%s'", command); + RETURN_FALSE; + } + + swString *buffer = swString_new(1024); + if (buffer == NULL) + { + RETURN_FALSE; + } + + process_stream *ps = emalloc(sizeof(process_stream)); + ps->callback = sw_zval_dup(callback); +#ifdef SW_COROUTINE + ps->context = NULL; +#endif + sw_zval_add_ref(&ps->callback); + + ps->fd = fd; + ps->pid = pid; + ps->buffer = buffer; + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, ps->fd, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_READ) < 0) + { + sw_zval_free(ps->callback); + efree(ps); + RETURN_FALSE; + } + else + { + swConnection *_socket = swReactor_get(SwooleG.main_reactor, ps->fd); + _socket->object = ps; + RETURN_LONG(pid); + } +} + +#ifdef SW_COROUTINE +PHP_FUNCTION(swoole_coroutine_exec) +{ + char *command; + zend_size_t command_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &command, &command_len) == FAILURE) + { + return; + } + + coro_check(TSRMLS_C); + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_READ, process_stream_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_ERROR, process_stream_onRead); + } + + pid_t pid; + int fd = swoole_shell_exec(command, &pid); + if (fd < 0) + { + swoole_php_error(E_WARNING, "Unable to execute '%s'", command); + RETURN_FALSE; + } + + swString *buffer = swString_new(1024); + if (buffer == NULL) + { + RETURN_FALSE; + } + + process_stream *ps = emalloc(sizeof(process_stream)); + ps->callback = NULL; + ps->context = emalloc(sizeof(php_context)); + ps->fd = fd; + ps->pid = pid; + ps->buffer = buffer; + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, ps->fd, PHP_SWOOLE_FD_PROCESS_STREAM | SW_EVENT_READ) < 0) + { + efree(ps->context); + efree(ps); + RETURN_FALSE; + } + else + { + swConnection *_socket = swReactor_get(SwooleG.main_reactor, ps->fd); + _socket->object = ps; + coro_save(ps->context); + coro_yield(); + } +} + +PHP_FUNCTION(swoole_async_dns_lookup_coro) +{ + zval *domain; + double timeout = SW_CLIENT_DEFAULT_TIMEOUT; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|d", &domain, &timeout) == FAILURE) + { + RETURN_FALSE; + } + coro_check(TSRMLS_C); + if (Z_TYPE_P(domain) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "invalid domain name."); + RETURN_FALSE; + } + + if (Z_STRLEN_P(domain) == 0) + { + swoole_php_fatal_error(E_WARNING, "domain name empty."); + RETURN_FALSE; + } + if (!request_cache_map) + { + request_cache_map = swHashMap_new(256, NULL); + } + + //find cache + dns_cache *cache = swHashMap_find(request_cache_map, Z_STRVAL_P(domain), Z_STRLEN_P(domain)); + if (cache != NULL && cache->update_time > (int64_t)swTimer_get_now_msec ) + { + SW_RETURN_STRINGL((*cache->zaddress).str,(*cache->zaddress).length,1); + } + + dns_request *req = emalloc(sizeof(dns_request)); + req->domain = domain; + sw_copy_to_stack(req->domain, req->_domain); + req->useless = 0; + + php_context *sw_current_context = emalloc(sizeof(php_context)); + sw_current_context->onTimeout = NULL; + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; +#if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = req; +#else + sw_current_context->coro_params.value.ptr = (void *) req; +#endif + req->context = sw_current_context; + + php_swoole_check_reactor(); + int ret = swDNSResolver_request(Z_STRVAL_P(domain), php_swoole_dns_callback_coro, (void *) req); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + //add timeout + php_swoole_check_timer(timeout); + req->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, sw_current_context, php_swoole_dns_timeout_coro); + if (req->timer) + { + sw_current_context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + coro_save(sw_current_context); + coro_yield(); +} +#endif diff --git a/vendor/swoole/swoole_atomic.c b/vendor/swoole/swoole_atomic.c new file mode 100755 index 0000000..fa04f3b --- /dev/null +++ b/vendor/swoole/swoole_atomic.c @@ -0,0 +1,437 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +static PHP_METHOD(swoole_atomic, __construct); +static PHP_METHOD(swoole_atomic, add); +static PHP_METHOD(swoole_atomic, sub); +static PHP_METHOD(swoole_atomic, get); +static PHP_METHOD(swoole_atomic, set); +static PHP_METHOD(swoole_atomic, cmpset); +static PHP_METHOD(swoole_atomic, wait); +static PHP_METHOD(swoole_atomic, wakeup); + +static PHP_METHOD(swoole_atomic_long, __construct); +static PHP_METHOD(swoole_atomic_long, add); +static PHP_METHOD(swoole_atomic_long, sub); +static PHP_METHOD(swoole_atomic_long, get); +static PHP_METHOD(swoole_atomic_long, set); +static PHP_METHOD(swoole_atomic_long, cmpset); + +#ifdef HAVE_FUTEX +#include <linux/futex.h> +#include <syscall.h> + +static sw_inline int swoole_futex_wait(sw_atomic_t *atomic, double timeout) +{ + if (sw_atomic_cmp_set(atomic, 1, 0)) + { + return SW_OK; + } + + int ret; + struct timespec _timeout; + + if (timeout > 0) + { + + _timeout.tv_sec = (long) timeout; + _timeout.tv_nsec = (timeout - _timeout.tv_sec) * 1000 * 1000 * 1000; + ret = syscall(SYS_futex, atomic, FUTEX_WAIT, 0, &_timeout, NULL, 0); + } + else + { + ret = syscall(SYS_futex, atomic, FUTEX_WAIT, 0, NULL, NULL, 0); + } + if (ret == SW_OK) + { + *atomic = 0; + } + return ret; +} + +static sw_inline int swoole_futex_wakeup(sw_atomic_t *atomic, int n) +{ + if (sw_atomic_cmp_set(atomic, 0, 1)) + { + return syscall(SYS_futex, atomic, FUTEX_WAKE, n, NULL, NULL, 0); + } + else + { + return SW_OK; + } +} +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_construct, 0, 0, 0) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_add, 0, 0, 0) + ZEND_ARG_INFO(0, add_value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_sub, 0, 0, 0) + ZEND_ARG_INFO(0, sub_value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_get, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_set, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_cmpset, 0, 0, 2) + ZEND_ARG_INFO(0, cmp_value) + ZEND_ARG_INFO(0, new_value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_wait, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_atomic_waitup, 0, 0, 0) + ZEND_ARG_INFO(0, count) +ZEND_END_ARG_INFO() + +static zend_class_entry swoole_atomic_ce; +zend_class_entry *swoole_atomic_class_entry_ptr; + +static zend_class_entry swoole_atomic_long_ce; +zend_class_entry *swoole_atomic_long_class_entry_ptr; + +static const zend_function_entry swoole_atomic_methods[] = +{ + PHP_ME(swoole_atomic, __construct, arginfo_swoole_atomic_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_atomic, add, arginfo_swoole_atomic_add, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, sub, arginfo_swoole_atomic_sub, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, get, arginfo_swoole_atomic_get, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, set, arginfo_swoole_atomic_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, wait, arginfo_swoole_atomic_wait, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, wakeup, arginfo_swoole_atomic_waitup, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic, cmpset, arginfo_swoole_atomic_cmpset, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +static const zend_function_entry swoole_atomic_long_methods[] = +{ + PHP_ME(swoole_atomic_long, __construct, arginfo_swoole_atomic_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_atomic_long, add, arginfo_swoole_atomic_add, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic_long, sub, arginfo_swoole_atomic_sub, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic_long, get, arginfo_swoole_atomic_get, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic_long, set, arginfo_swoole_atomic_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_atomic_long, cmpset, arginfo_swoole_atomic_cmpset, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +void swoole_atomic_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_atomic_ce, "swoole_atomic", "Swoole\\Atomic", swoole_atomic_methods); + swoole_atomic_class_entry_ptr = zend_register_internal_class(&swoole_atomic_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_atomic, "Swoole\\Atomic"); + + SWOOLE_INIT_CLASS_ENTRY(swoole_atomic_long_ce, "swoole_atomic_long", "Swoole\\Atomic\\Long", swoole_atomic_long_methods); + swoole_atomic_long_class_entry_ptr = zend_register_internal_class(&swoole_atomic_long_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_atomic_long, "Swoole\\Atomic\\Long"); +} + +PHP_METHOD(swoole_atomic, __construct) +{ + zend_long value = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + sw_atomic_t *atomic = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(sw_atomic_t)); + if (atomic == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + *atomic = (sw_atomic_t) value; + swoole_set_object(getThis(), (void*) atomic); + + RETURN_TRUE; +} + +PHP_METHOD(swoole_atomic, add) +{ + zend_long add_value = 1; + sw_atomic_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(add_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &add_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + RETURN_LONG(sw_atomic_add_fetch(atomic, (uint32_t ) add_value)); +} + +PHP_METHOD(swoole_atomic, sub) +{ + zend_long sub_value = 1; + sw_atomic_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(sub_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &sub_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + RETURN_LONG(sw_atomic_sub_fetch(atomic, (uint32_t ) sub_value)); +} + +PHP_METHOD(swoole_atomic, get) +{ + sw_atomic_t *atomic = swoole_get_object(getThis()); + RETURN_LONG(*atomic); +} + +PHP_METHOD(swoole_atomic, set) +{ + sw_atomic_t *atomic = swoole_get_object(getThis()); + zend_long set_value; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(set_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &set_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + *atomic = (uint32_t) set_value; +} + +PHP_METHOD(swoole_atomic, cmpset) +{ + zend_long cmp_value, set_value; + sw_atomic_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(cmp_value) + Z_PARAM_LONG(set_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &cmp_value, &set_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + RETURN_BOOL(sw_atomic_cmp_set(atomic, (sw_atomic_t) cmp_value, (sw_atomic_t) set_value)); +} + +PHP_METHOD(swoole_atomic, wait) +{ + double timeout = 1.0; + sw_atomic_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_DOUBLE(timeout) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|d", &timeout) == FAILURE) + { + RETURN_FALSE; + } +#endif + +#ifdef HAVE_FUTEX + SW_CHECK_RETURN(swoole_futex_wait(atomic, timeout)); +#else + timeout = timeout <= 0 ? SW_MAX_INT : timeout; + while (timeout > 0) + { + if (sw_atomic_cmp_set(atomic, 1, 0)) + { + RETURN_TRUE; + } + else + { + usleep(1000); + timeout -= 0.001; + } + } +#endif +} + +PHP_METHOD(swoole_atomic, wakeup) +{ + zend_long n = 1; + sw_atomic_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(n) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &n) == FAILURE) + { + RETURN_FALSE; + } +#endif + +#ifdef HAVE_FUTEX + SW_CHECK_RETURN(swoole_futex_wakeup(atomic, (int ) n)); +#else + *atomic = 1; +#endif +} + +PHP_METHOD(swoole_atomic_long, __construct) +{ + zend_long value = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + sw_atomic_long_t *atomic = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(sw_atomic_long_t)); + if (atomic == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + *atomic = (sw_atomic_long_t) value; + swoole_set_object(getThis(), (void*) atomic); + + RETURN_TRUE; +} + +PHP_METHOD(swoole_atomic_long, add) +{ + zend_long add_value = 1; + sw_atomic_long_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(add_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &add_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + RETURN_LONG(sw_atomic_add_fetch(atomic, (sw_atomic_long_t ) add_value)); +} + +PHP_METHOD(swoole_atomic_long, sub) +{ + zend_long sub_value = 1; + sw_atomic_long_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(sub_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &sub_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + RETURN_LONG(sw_atomic_sub_fetch(atomic, (sw_atomic_long_t ) sub_value)); +} + +PHP_METHOD(swoole_atomic_long, get) +{ + sw_atomic_long_t *atomic = swoole_get_object(getThis()); + RETURN_LONG(*atomic); +} + +PHP_METHOD(swoole_atomic_long, set) +{ + sw_atomic_long_t *atomic = swoole_get_object(getThis()); + zend_long set_value; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(set_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &set_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + *atomic = (sw_atomic_long_t) set_value; +} + +PHP_METHOD(swoole_atomic_long, cmpset) +{ + zend_long cmp_value, set_value; + sw_atomic_long_t *atomic = swoole_get_object(getThis()); + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(cmp_value) + Z_PARAM_LONG(set_value) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &cmp_value, &set_value) == FAILURE) + { + RETURN_FALSE; + } +#endif + + RETURN_BOOL(sw_atomic_cmp_set(atomic, (sw_atomic_long_t) cmp_value, (sw_atomic_long_t) set_value)); +} diff --git a/vendor/swoole/swoole_buffer.c b/vendor/swoole/swoole_buffer.c new file mode 100755 index 0000000..a6ac229 --- /dev/null +++ b/vendor/swoole/swoole_buffer.c @@ -0,0 +1,365 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +static PHP_METHOD(swoole_buffer, __construct); +static PHP_METHOD(swoole_buffer, __destruct); +static PHP_METHOD(swoole_buffer, __toString); +static PHP_METHOD(swoole_buffer, append); +static PHP_METHOD(swoole_buffer, substr); +static PHP_METHOD(swoole_buffer, read); +static PHP_METHOD(swoole_buffer, write); +static PHP_METHOD(swoole_buffer, expand); +static PHP_METHOD(swoole_buffer, recycle); +static PHP_METHOD(swoole_buffer, clear); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_construct, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_expand, 0, 0, 1) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_substr, 0, 0, 1) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) + ZEND_ARG_INFO(0, seek) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_write, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_read, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_buffer_append, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_buffer_methods[] = +{ + PHP_ME(swoole_buffer, __construct, arginfo_swoole_buffer_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_buffer, __destruct, arginfo_swoole_buffer_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_buffer, __toString, arginfo_swoole_buffer_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, substr, arginfo_swoole_buffer_substr, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, write, arginfo_swoole_buffer_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, read, arginfo_swoole_buffer_read, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, append, arginfo_swoole_buffer_append, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, expand, arginfo_swoole_buffer_expand, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, recycle, arginfo_swoole_buffer_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_buffer, clear, arginfo_swoole_buffer_void, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +zend_class_entry swoole_buffer_ce; +zend_class_entry *swoole_buffer_class_entry_ptr; + +void swoole_buffer_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_buffer_ce, "swoole_buffer", "Swoole\\Buffer", swoole_buffer_methods); + swoole_buffer_class_entry_ptr = zend_register_internal_class(&swoole_buffer_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_buffer, "Swoole\\Buffer"); +} + +static void swoole_buffer_recycle(swString *buffer) +{ + if (buffer->offset == 0) + { + return; + } + + long length; + length = buffer->length - buffer->offset; + if (length > 0) + { + memmove(buffer->str, buffer->str + buffer->offset, length); + } + + buffer->offset = 0; + buffer->length = length; +} + +static PHP_METHOD(swoole_buffer, __construct) +{ + long size = SW_STRING_BUFFER_DEFAULT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size) == FAILURE) + { + RETURN_FALSE; + } + + if (size < 1) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "buffer size can't be less than 0.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + else if (size > SW_STRING_BUFFER_MAXLEN) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "buffer size can't exceed %d", SW_STRING_BUFFER_MAXLEN); + RETURN_FALSE; + } + + swString *buffer = swString_new(size); + if (buffer == NULL) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "malloc(%ld) failed.", size); + RETURN_FALSE; + } + + swoole_set_object(getThis(), buffer); + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), size TSRMLS_CC); + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), 0 TSRMLS_CC); +} + +static PHP_METHOD(swoole_buffer, __destruct) +{ + swString *buffer = swoole_get_object(getThis()); + if (buffer) + { + swString_free(buffer); + } +} + +static PHP_METHOD(swoole_buffer, append) +{ + swString str; + bzero(&str, sizeof(str)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str.str, &str.length) == FAILURE) + { + RETURN_FALSE; + } + if (str.length < 1) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "string empty."); + RETURN_FALSE; + } + swString *buffer = swoole_get_object(getThis()); + + if ((str.length + buffer->length) > buffer->size && (str.length + buffer->length) > SW_STRING_BUFFER_MAXLEN) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "buffer size can't exceed %d", SW_STRING_BUFFER_MAXLEN); + RETURN_FALSE; + } + + size_t size_old = buffer->size; + if (swString_append(buffer, &str) == SW_OK) + { + if (buffer->size > size_old) + { + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), buffer->size TSRMLS_CC); + } + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), + buffer->length - buffer->offset TSRMLS_CC); + RETURN_LONG(buffer->length - buffer->offset); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_buffer, substr) +{ + long offset; + long length = -1; + zend_bool remove = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|lb", &offset, &length, &remove) == FAILURE) + { + RETURN_FALSE; + } + swString *buffer = swoole_get_object(getThis()); + + if (remove && !(offset == 0 && length <= buffer->length)) + { + remove = 0; + } + if (offset < 0) + { + offset = buffer->length + offset; + } + offset += buffer->offset; + if (length < 0) + { + length = buffer->length - offset; + } + if (offset + length > buffer->length) + { + swoole_php_error(E_WARNING, "offset(%ld, %ld) is out of bounds.", offset, length); + RETURN_FALSE; + } + if (remove) + { + buffer->offset += length; + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), buffer->length - buffer->offset TSRMLS_CC); + + if (buffer->offset > SW_STRING_BUFFER_GARBAGE_MIN && buffer->offset * SW_STRING_BUFFER_GARBAGE_RATIO > buffer->size) + { + swoole_buffer_recycle(buffer); + } + } + SW_RETURN_STRINGL(buffer->str + offset, length, 1); +} + +static PHP_METHOD(swoole_buffer, __toString) +{ + swString *buffer = swoole_get_object(getThis()); + SW_RETURN_STRINGL(buffer->str + buffer->offset, buffer->length - buffer->offset, 1); +} + +static PHP_METHOD(swoole_buffer, write) +{ + long offset; + swString str; + + bzero(&str, sizeof(str)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &offset, &str.str, &str.length) == FAILURE) + { + RETURN_FALSE; + } + + if (str.length < 1) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "string to write is empty."); + RETURN_FALSE; + } + + swString *buffer = swoole_get_object(getThis()); + + if (offset < 0) + { + offset = buffer->length - buffer->offset + offset; + } + if (offset < 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "offset(%ld) is out of bounds.", offset); + RETURN_FALSE; + } + + offset += buffer->offset; + + if ((str.length + offset) > buffer->size && (str.length + offset) > SW_STRING_BUFFER_MAXLEN) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "buffer size can't exceed %d", SW_STRING_BUFFER_MAXLEN); + RETURN_FALSE; + } + + size_t size_old = buffer->size; + if (swString_write(buffer, offset, &str) == SW_OK) + { + if (buffer->size > size_old) + { + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), buffer->size TSRMLS_CC); + } + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), + buffer->length - buffer->offset TSRMLS_CC); + RETURN_LONG(buffer->length - buffer->offset); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_buffer, read) +{ + long offset; + long length; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &offset, &length) == FAILURE) + { + RETURN_FALSE; + } + + swString *buffer = swoole_get_object(getThis()); + + if (offset < 0) + { + offset = buffer->length - buffer->offset + offset; + } + if (offset < 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "offset(%ld) is out of bounds.", offset); + RETURN_FALSE; + } + + offset += buffer->offset; + + if (length > buffer->length - offset) + { + RETURN_FALSE; + } + + SW_RETURN_STRINGL(buffer->str + offset, length, 1); +} + +static PHP_METHOD(swoole_buffer, expand) +{ + long size = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) + { + RETURN_FALSE; + } + + swString *buffer = swoole_get_object(getThis()); + + if (size <= buffer->size) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "new size must be more than %ld", buffer->size); + RETURN_FALSE; + } + + if (swString_extend(buffer, size) == SW_OK) + { + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("capacity"), size TSRMLS_CC); + RETURN_TRUE; + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_buffer, recycle) +{ + swString *buffer = swoole_get_object(getThis()); + + swoole_buffer_recycle(buffer); + + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), buffer->length TSRMLS_CC); +} + +static PHP_METHOD(swoole_buffer, clear) +{ + swString *buffer = swoole_get_object(getThis()); + buffer->length = 0; + buffer->offset = 0; + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), 0 TSRMLS_CC); +} diff --git a/vendor/swoole/swoole_channel.c b/vendor/swoole/swoole_channel.c new file mode 100755 index 0000000..1f86db2 --- /dev/null +++ b/vendor/swoole/swoole_channel.c @@ -0,0 +1,158 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + + +#include "php_swoole.h" +#include "swoole_coroutine.h" + +static PHP_METHOD(swoole_channel, __construct); +static PHP_METHOD(swoole_channel, __destruct); +static PHP_METHOD(swoole_channel, push); +static PHP_METHOD(swoole_channel, pop); +static PHP_METHOD(swoole_channel, peek); +static PHP_METHOD(swoole_channel, stats); + +static zend_class_entry swoole_channel_ce; +zend_class_entry *swoole_channel_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_construct, 0, 0, 1) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_channel_methods[] = +{ + PHP_ME(swoole_channel, __construct, arginfo_swoole_channel_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_channel, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_channel, push, arginfo_swoole_channel_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel, pop, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel, peek, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_channel_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_channel_ce, "swoole_channel", "Swoole\\Channel", swoole_channel_methods); + swoole_channel_class_entry_ptr = zend_register_internal_class(&swoole_channel_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_channel, "Swoole\\Channel"); +} + +static PHP_METHOD(swoole_channel, __construct) +{ + long size; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) + { + RETURN_FALSE; + } + + if (size < SW_BUFFER_SIZE_STD) + { + size = SW_BUFFER_SIZE_STD; + } + + swChannel *chan = swChannel_new(size, SW_BUFFER_SIZE_STD, SW_CHAN_LOCK | SW_CHAN_SHM); + if (chan == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create channel.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + swoole_set_object(getThis(), chan); +} + +static PHP_METHOD(swoole_channel, __destruct) +{ + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_channel, push) +{ + swChannel *chan = swoole_get_object(getThis()); + zval *zdata; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata) == FAILURE) + { + RETURN_FALSE; + } + + swEventData buf; + if (php_swoole_task_pack(&buf, zdata TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + SW_CHECK_RETURN(swChannel_push(chan, &buf, sizeof(buf.info) + buf.info.len)); +} + +static PHP_METHOD(swoole_channel, pop) +{ + swChannel *chan = swoole_get_object(getThis()); + swEventData buf; + + int n = swChannel_pop(chan, &buf, sizeof(buf)); + if (n < 0) + { + RETURN_FALSE; + } + + zval *ret_data = php_swoole_task_unpack(&buf TSRMLS_CC); + if (ret_data == NULL) + { + RETURN_FALSE; + } + + RETVAL_ZVAL(ret_data, 0, NULL); + efree(ret_data); +} + +static PHP_METHOD(swoole_channel, peek) +{ + swChannel *chan = swoole_get_object(getThis()); + swEventData buf; + + int n = swChannel_peek(chan, &buf, sizeof(buf)); + if (n < 0) + { + RETURN_FALSE; + } + + swTask_type(&buf) |= SW_TASK_PEEK; + zval *ret_data = php_swoole_task_unpack(&buf TSRMLS_CC); + if (ret_data == NULL) + { + RETURN_FALSE; + } + + RETVAL_ZVAL(ret_data, 0, NULL); + efree(ret_data); +} + +static PHP_METHOD(swoole_channel, stats) +{ + swChannel *chan = swoole_get_object(getThis()); + array_init(return_value); + + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_num"), chan->num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_bytes"), chan->bytes); +} diff --git a/vendor/swoole/swoole_channel_coro.cc b/vendor/swoole/swoole_channel_coro.cc new file mode 100755 index 0000000..d479c56 --- /dev/null +++ b/vendor/swoole/swoole_channel_coro.cc @@ -0,0 +1,662 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2018 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + | Tianfeng Han <rango@swoole.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#include <queue> + +using namespace std; + +enum ChannelSelectOpcode +{ + CHANNEL_SELECT_WRITE = 0, CHANNEL_SELECT_READ = 1, +}; + +typedef struct +{ + swLinkedList *producer_list; + swLinkedList *consumer_list; + bool closed; + int capacity; + queue<zval> *data_queue; +} channel; + +typedef struct +{ + swLinkedList *list; + swLinkedList_node *node; +} channel_selector_node; + +typedef struct +{ + swTimer_node *timer; + zval *read_list; + zval *write_list; + channel_selector_node *node_list; + zval readable; + zval writable; + uint16_t count; + zval object; + enum ChannelSelectOpcode opcode; +} channel_selector; + +typedef struct _channel_node +{ + php_context context; + channel_selector *selector; +} channel_node; + +static PHP_METHOD(swoole_channel_coro, __construct); +static PHP_METHOD(swoole_channel_coro, __destruct); +static PHP_METHOD(swoole_channel_coro, push); +static PHP_METHOD(swoole_channel_coro, pop); +static PHP_METHOD(swoole_channel_coro, close); +static PHP_METHOD(swoole_channel_coro, stats); +static PHP_METHOD(swoole_channel_coro, length); +static PHP_METHOD(swoole_channel_coro, isEmpty); +static PHP_METHOD(swoole_channel_coro, isFull); +static PHP_METHOD(swoole_channel_coro, select); + +static zend_class_entry swoole_channel_coro_ce; +static zend_class_entry *swoole_channel_coro_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_construct, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_channel_coro_select, 0, 0, 2) + ZEND_ARG_ARRAY_INFO(1, read_list, 1) + ZEND_ARG_ARRAY_INFO(1, write_list, 1) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_channel_coro_methods[] = +{ + PHP_ME(swoole_channel_coro, __construct, arginfo_swoole_channel_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_channel_coro, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_channel_coro, push, arginfo_swoole_channel_coro_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, pop, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, isEmpty, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, isFull, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, length, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_channel_coro, select, arginfo_swoole_channel_coro_select, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +void swoole_channel_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_channel_coro_ce, "Swoole\\Coroutine\\Channel", swoole_channel_coro_methods); + swoole_channel_coro_class_entry_ptr = zend_register_internal_class(&swoole_channel_coro_ce TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("chan", swoole_channel_coro_class_entry_ptr); + } + + zend_declare_property_long(swoole_channel_coro_class_entry_ptr, SW_STRL("capacity")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); +} + +static void channel_selector_clear(channel_selector *selector, swLinkedList_node *_node) +{ + int i; + for (i = 0; i < selector->count; i++) + { + if (_node == selector->node_list[i].node) + { + continue; + } + swLinkedList_remove_node(selector->node_list[i].list, selector->node_list[i].node); + } + efree(selector->node_list); +} + +static void channel_selector_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + zval *retval = NULL; + zval *result = NULL; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 0); + + channel_node *node = (channel_node *) tnode->data; + channel_selector *selector = (channel_selector *) node->selector; + + zval_ptr_dtor(selector->read_list); + ZVAL_COPY_VALUE(selector->read_list, &selector->readable); + + if (selector->write_list) + { + zval_ptr_dtor(selector->write_list); + ZVAL_COPY_VALUE(selector->write_list, &selector->writable); + } + + php_context *context = (php_context *) node; + channel_selector_clear(selector, NULL); + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(selector); + efree(node); +} + +static inline bool channel_isEmpty(channel *chan) +{ + return chan->data_queue->size() == 0; +} + +static inline bool channel_isFull(channel *chan) +{ + return chan->data_queue->size() == chan->capacity; +} + +static int channel_onNotify(swReactor *reactor, swEvent *event) +{ + uint64_t notify; + while (read(COROG.chan_pipe->getFd(COROG.chan_pipe, 0), &notify, sizeof(notify)) > 0); + coro_handle_timeout(); + SwooleG.main_reactor->del(SwooleG.main_reactor, COROG.chan_pipe->getFd(COROG.chan_pipe, 0)); + return 0; +} + +static void channel_notify(channel_node *node) +{ + swLinkedList_append(SwooleWG.coro_timeout_list, node); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_CHAN_PIPE)) + { + swReactor_setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_CHAN_PIPE, channel_onNotify); + + } + int pfd = COROG.chan_pipe->getFd(COROG.chan_pipe, 0); + swConnection *_socket = swReactor_get(SwooleG.main_reactor, pfd); + if (_socket && _socket->events == 0) + { + SwooleG.main_reactor->add(SwooleG.main_reactor, pfd, PHP_SWOOLE_FD_CHAN_PIPE | SW_EVENT_READ); + } + uint64_t flag = 1; + COROG.chan_pipe->write(COROG.chan_pipe, &flag, sizeof(flag)); +} + +static void swoole_channel_onResume(php_context *ctx) +{ + channel_node *node = (channel_node *) ctx; + zval *zdata = NULL; + zval *retval = NULL; + + if (node->selector) + { + channel_selector *selector = node->selector; + + if (selector->timer) + { + swTimer_del(&SwooleG.timer, selector->timer); + selector->timer = NULL; + } + if (selector->opcode == CHANNEL_SELECT_WRITE) + { + zval_ptr_dtor(selector->write_list); + Z_TRY_ADDREF_P(&selector->object); + add_next_index_zval(&selector->writable, &selector->object); + ZVAL_COPY_VALUE(selector->write_list, &selector->writable); + if (selector->read_list) + { + zval_ptr_dtor(selector->read_list); + ZVAL_COPY_VALUE(selector->read_list, &selector->readable); + } + } + else + { + //read + zval_ptr_dtor(selector->read_list); + Z_TRY_ADDREF_P(&selector->object); + add_next_index_zval(&selector->readable, &selector->object); + ZVAL_COPY_VALUE(selector->read_list, &selector->readable); + if (selector->write_list) + { + zval_ptr_dtor(selector->write_list); + ZVAL_COPY_VALUE(selector->write_list, &selector->writable); + } + } + SW_MAKE_STD_ZVAL(zdata); + ZVAL_BOOL(zdata, 1); + efree(selector); + } + + swDebug("channel onResume, cid=%d", coroutine_get_cid()); + + int ret = coro_resume(ctx, zdata, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + if (zdata) + { + zval_ptr_dtor(zdata); + } + efree(ctx); +} + +static int swoole_channel_try_resume_producer(zval *object, channel *property) +{ + swLinkedList *coro_list = property->producer_list; + channel_node *node; + + if (coro_list->num != 0) + { + node = (channel_node *) coro_list->head->data; + if (node == NULL) + { + return -1; + } + node->context.onTimeout = swoole_channel_onResume; + if (node->selector) + { + node->selector->object = *object; + node->selector->opcode = CHANNEL_SELECT_WRITE; + channel_selector_clear(node->selector, coro_list->head); + } + swLinkedList_shift(coro_list); + channel_notify(node); + return 0; + } + return -1; +} + +static sw_inline int swoole_channel_try_resume_all(zval *object, channel *property) +{ + swLinkedList *coro_list = property->producer_list; + swLinkedList_node *next; + channel_node *node; + + while (coro_list->num != 0) + { + next = coro_list->head; + node = (channel_node *) swLinkedList_shift(coro_list); + node->context.onTimeout = swoole_channel_onResume; + ZVAL_FALSE(&node->context.coro_params); + if (node->selector) + { + node->selector->object = *object; + node->selector->opcode = CHANNEL_SELECT_READ; + channel_selector_clear(node->selector, next); + } + channel_notify(node); + } + + coro_list = property->consumer_list; + while (coro_list->num != 0) + { + next = coro_list->head; + node = (channel_node*) swLinkedList_shift(coro_list); + node->context.onTimeout = swoole_channel_onResume; + ZVAL_FALSE(&node->context.coro_params); + if (node->selector) + { + node->selector->object = *object; + node->selector->opcode = CHANNEL_SELECT_WRITE; + channel_selector_clear(node->selector, next); + } + channel_notify(node); + } + + return 0; +} + +static PHP_METHOD(swoole_channel_coro, __construct) +{ + long capacity = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &capacity) == FAILURE) + { + RETURN_FALSE; + } + if (capacity <= 0) + { + capacity = 1; + } + + if (COROG.chan_pipe == NULL) + { + COROG.chan_pipe = (swPipe *) emalloc(sizeof(swPipe)); + if (swPipeNotify_auto(COROG.chan_pipe, 1, 1) < 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create eventfd.", SW_ERROR_SYSTEM_CALL_FAIL TSRMLS_CC); + RETURN_FALSE; + } + } + + channel *chan = (channel *) sw_malloc(sizeof(channel)); + if (chan == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create property.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + + chan->data_queue = new queue<zval>; + chan->producer_list = swLinkedList_new(2, NULL); + if (chan->producer_list == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create producer_list.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + chan->consumer_list = swLinkedList_new(2, NULL); + if (chan->consumer_list == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create consumer_list.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + chan->closed = false; + chan->capacity = capacity; + + zend_update_property_long(swoole_channel_coro_class_entry_ptr, getThis(), ZEND_STRL("capacity"), capacity TSRMLS_CC); + + swoole_set_object(getThis(), chan); +} + +static PHP_METHOD(swoole_channel_coro, __destruct) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + swLinkedList_free(chan->consumer_list); + swLinkedList_free(chan->producer_list); + delete chan->data_queue; + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_channel_coro, push) +{ + coro_check(TSRMLS_C); + + channel *chan = (channel *) swoole_get_object(getThis()); + if (chan->closed) + { + RETURN_FALSE; + } + swLinkedList *producer_list = chan->producer_list; + + zval *zdata; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata) == FAILURE) + { + RETURN_FALSE; + } + + if (channel_isFull(chan)) + { + channel_node *node = (channel_node *) emalloc(sizeof(channel_node)); + memset(node, 0, sizeof(channel_node)); + coro_save(&node->context); + swLinkedList_append(producer_list, node); + coro_yield(); + } + + if (channel_isFull(chan) && chan->closed) + { + RETURN_FALSE; + } + + Z_TRY_ADDREF_P(zdata); + chan->data_queue->push(*zdata); + + swDebug("TYPE=%d, count=%d", Z_TYPE_P(zdata), chan->data_queue->size()); + + if (chan->consumer_list->num != 0) + { + swLinkedList_node *head = chan->consumer_list->head; + channel_node *node = (channel_node *) head->data; + node->context.onTimeout = swoole_channel_onResume; + if (node->selector) + { + node->selector->object = *getThis(); + node->selector->opcode = CHANNEL_SELECT_READ; + channel_selector_clear(node->selector, chan->consumer_list->head); + } + swLinkedList_shift(chan->consumer_list); + channel_notify(node); + + node = (channel_node *) emalloc(sizeof(channel_node)); + memset(node, 0, sizeof(channel_node)); + coro_save(&node->context); + swLinkedList_append(producer_list, node); + coro_yield(); + } + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_channel_coro, pop) +{ + coro_check(TSRMLS_C); + + channel *chan = (channel *) swoole_get_object(getThis()); + if (chan->closed) + { + RETURN_FALSE; + } + + if (channel_isEmpty(chan)) + { + channel_node *node = (channel_node *) emalloc(sizeof(channel_node)); + memset(node, 0, sizeof(channel_node)); + coro_save(&node->context); + swLinkedList_append(chan->consumer_list, node); + coro_yield(); + } + + if (channel_isEmpty(chan) && chan->closed) + { + RETURN_FALSE; + } + + assert(chan->data_queue->size() > 0); + + zval zdata = chan->data_queue->front(); + chan->data_queue->pop(); + + swDebug("TYPE=%d, count=%d", Z_TYPE(zdata), chan->data_queue->size()); + + swoole_channel_try_resume_producer(getThis(), chan); + RETURN_ZVAL(&zdata, 0, NULL); +} + +static PHP_METHOD(swoole_channel_coro, close) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + if (chan->closed) + { + RETURN_TRUE; + } + chan->closed = true; + swoole_channel_try_resume_all(getThis(), chan); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_channel_coro, length) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + RETURN_LONG(chan->data_queue->size()); +} + +static PHP_METHOD(swoole_channel_coro, isEmpty) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + RETURN_BOOL(channel_isEmpty(chan)); +} + +static PHP_METHOD(swoole_channel_coro, isFull) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + RETURN_BOOL(channel_isFull(chan)); +} + +static PHP_METHOD(swoole_channel_coro, stats) +{ + channel *chan = (channel *) swoole_get_object(getThis()); + array_init(return_value); + + sw_add_assoc_long_ex(return_value, ZEND_STRS("consumer_num"), chan->consumer_list->num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("producer_num"), chan->producer_list->num); + + if (chan) + { + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_num"), chan->data_queue->size()); + } +} + +static PHP_METHOD(swoole_channel_coro, select) +{ + coro_check(TSRMLS_C); + + zval *read_list, *write_list = NULL, *item; + zval readable, writable; + double timeout = 0; + zend_bool need_yield = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!|d", &read_list, &write_list, &timeout) == FAILURE) + { + RETURN_FALSE; + } + + if (read_list) + { + array_init(&readable); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(read_list), item) + if (Z_TYPE_P(item) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(item), swoole_channel_coro_class_entry_ptr TSRMLS_CC)) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "object is not instanceof Swoole\\Coroutine\\Channel."); + return; + } + channel *chan = (channel *) swoole_get_object(item); + if (!channel_isEmpty(chan)) + { + Z_ADDREF_P(item); + add_next_index_zval(&readable, item); + need_yield = 0; + } + SW_HASHTABLE_FOREACH_END(); + } + + if (write_list) + { + array_init(&writable); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(write_list), item) + if (Z_TYPE_P(item) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(item), swoole_channel_coro_class_entry_ptr TSRMLS_CC)) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "object is not instanceof Swoole\\Coroutine\\Channel."); + return; + } + channel *chan = (channel *) swoole_get_object(item); + if (!channel_isFull(chan)) + { + Z_ADDREF_P(item); + add_next_index_zval(&writable, item); + need_yield = 0; + } + SW_HASHTABLE_FOREACH_END(); + } + + if (need_yield && (read_list || write_list)) + { + channel_selector *selector = (channel_selector*) emalloc(sizeof(channel_selector)); + memset(selector, 0, sizeof(channel_selector)); + + if (read_list) + { + selector->count = php_swoole_array_length(read_list); + } + if (write_list) + { + selector->count += php_swoole_array_length(write_list); + } + selector->node_list = (channel_selector_node *) ecalloc(selector->count, sizeof(channel_selector_node)); + int i = 0; + channel_node *node = (channel_node *) emalloc(sizeof(channel_node)); + memset(node, 0, sizeof(channel_node)); + node->selector = selector; + if (read_list) + { + selector->read_list = read_list; + selector->readable = readable; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(read_list), item) + channel *chan = (channel *) swoole_get_object(item); + swLinkedList_append(chan->consumer_list, node); + selector->node_list[i].list = chan->consumer_list; + selector->node_list[i].node = chan->consumer_list->tail; + i++; + SW_HASHTABLE_FOREACH_END(); + } + + if (write_list) + { + selector->write_list = write_list; + selector->writable = writable; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(write_list), item) + channel *chan = (channel *) swoole_get_object(item); + swLinkedList_append(chan->producer_list, node); + selector->node_list[i].list = chan->producer_list; + selector->node_list[i].node = chan->producer_list->tail; + i++; + SW_HASHTABLE_FOREACH_END(); + } + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_reactor(); + php_swoole_check_timer(ms); + selector->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, node, channel_selector_onTimeout); + } + + coro_save(&node->context); + coro_yield(); + } + else + { + if (read_list) + { + zval_ptr_dtor(read_list); + ZVAL_COPY_VALUE(read_list, &readable); + } + + + if (write_list) + { + zval_ptr_dtor(write_list); + ZVAL_COPY_VALUE(write_list, &writable); + } + + RETURN_TRUE; + } +} +#endif diff --git a/vendor/swoole/swoole_client.c b/vendor/swoole/swoole_client.c new file mode 100755 index 0000000..d66cd5e --- /dev/null +++ b/vendor/swoole/swoole_client.c @@ -0,0 +1,2552 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "socks5.h" +#include "mqtt.h" + +#include "ext/standard/basic_functions.h" + +typedef struct +{ + zval *onConnect; + zval *onReceive; + zval *onClose; + zval *onError; + zval *onBufferFull; + zval *onBufferEmpty; +#ifdef SW_USE_OPENSSL + zval *onSSLReady; +#endif + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + zend_fcall_info_cache cache_onConnect; + zend_fcall_info_cache cache_onReceive; + zend_fcall_info_cache cache_onClose; + zend_fcall_info_cache cache_onError; + zend_fcall_info_cache cache_onBufferFull; + zend_fcall_info_cache cache_onBufferEmpty; +#ifdef SW_USE_OPENSSL + zend_fcall_info_cache cache_onSSLReady; +#endif +#endif + +#if PHP_MAJOR_VERSION >= 7 + zval _object; + zval _onConnect; + zval _onReceive; + zval _onClose; + zval _onError; + zval _onBufferFull; + zval _onBufferEmpty; +#ifdef SW_USE_OPENSSL + zval _onSSLReady; +#endif +#endif + +} client_callback; + +enum client_property +{ + client_property_callback = 0, + client_property_coroutine = 1, + client_property_socket = 2, +}; + +static PHP_METHOD(swoole_client, __construct); +static PHP_METHOD(swoole_client, __destruct); +static PHP_METHOD(swoole_client, set); +static PHP_METHOD(swoole_client, connect); +static PHP_METHOD(swoole_client, recv); +static PHP_METHOD(swoole_client, send); +static PHP_METHOD(swoole_client, pipe); +static PHP_METHOD(swoole_client, sendfile); +static PHP_METHOD(swoole_client, sendto); +static PHP_METHOD(swoole_client, sleep); +static PHP_METHOD(swoole_client, wakeup); +#ifdef SW_USE_OPENSSL +static PHP_METHOD(swoole_client, enableSSL); +static PHP_METHOD(swoole_client, getPeerCert); +static PHP_METHOD(swoole_client, verifyPeerCert); +#endif +static PHP_METHOD(swoole_client, isConnected); +static PHP_METHOD(swoole_client, getsockname); +static PHP_METHOD(swoole_client, getpeername); +static PHP_METHOD(swoole_client, close); +static PHP_METHOD(swoole_client, shutdown); +static PHP_METHOD(swoole_client, on); + +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_client, getSocket); +#endif + +#ifdef PHP_SWOOLE_CLIENT_USE_POLL +static int client_poll_add(zval *sock_array, int index, struct pollfd *fds, int maxevents, int event); +static int client_poll_wait(zval *sock_array, struct pollfd *fds, int maxevents, int n_event, int revent); +#else +static int client_select_add(zval *sock_array, fd_set *fds, int *max_fd TSRMLS_DC); +static int client_select_wait(zval *sock_array, fd_set *fds TSRMLS_DC); +#endif + +static void client_onConnect(swClient *cli); +static void client_onReceive(swClient *cli, char *data, uint32_t length); +static void client_onClose(swClient *cli); +static void client_onError(swClient *cli); +static void client_onBufferFull(swClient *cli); +static void client_onBufferEmpty(swClient *cli); + +static sw_inline void client_execute_callback(zval *zobject, enum php_swoole_client_callback_type type) +{ + SWOOLE_GET_TSRMLS; + + zval *callback = NULL; + zval *retval = NULL; + zval **args[1]; + + client_callback *cb = (client_callback *) swoole_get_property(zobject, client_property_callback); + char *callback_name; + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + zend_fcall_info_cache *fci_cache; +#endif + + switch(type) + { + case SW_CLIENT_CB_onConnect: + callback = cb->onConnect; + callback_name = "onConnect"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onConnect; +#endif + break; + case SW_CLIENT_CB_onError: + callback = cb->onError; + callback_name = "onError"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onError; +#endif + break; + case SW_CLIENT_CB_onClose: + callback = cb->onClose; + callback_name = "onClose"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onClose; +#endif + break; + case SW_CLIENT_CB_onBufferFull: + callback = cb->onBufferFull; + callback_name = "onBufferFull"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onBufferFull; +#endif + break; + case SW_CLIENT_CB_onBufferEmpty: + callback = cb->onBufferEmpty; + callback_name = "onBufferEmpty"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onBufferEmpty; +#endif + break; +#ifdef SW_USE_OPENSSL + case SW_CLIENT_CB_onSSLReady: + callback = cb->onSSLReady; + callback_name = "onSSLReady"; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + fci_cache = &cb->cache_onSSLReady; +#endif + break; +#endif + default: + return; + } + + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + swoole_php_fatal_error(E_WARNING, "object have not %s callback.", callback_name); + return; + } + + args[0] = &zobject; +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + if (sw_call_user_function_fast(callback, fci_cache, &retval, 1, args TSRMLS_CC) == FAILURE) +#else + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) +#endif + { + swoole_php_fatal_error(E_WARNING, "%s handler error.", callback_name); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static sw_inline swClient* client_get_ptr(zval *zobject TSRMLS_DC) +{ + swClient *cli = (swClient *) swoole_get_object(zobject); + if (cli && cli->socket && cli->socket->active == 1) + { + return cli; + } + else + { + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION; + zend_update_property_long(swoole_client_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + swoole_php_error(E_WARNING, "client is not connected to server."); + return NULL; + } +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_construct, 0, 0, 1) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, async) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_connect, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, timeout) + ZEND_ARG_INFO(0, sock_flag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_recv, 0, 0, 0) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, flag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_send, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, flag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_pipe, 0, 0, 1) + ZEND_ARG_INFO(0, dst_socket) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_sendfile, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_sendto, 0, 0, 3) + ZEND_ARG_INFO(0, ip) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_close, 0, 0, 0) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_shutdown, 0, 0, 1) + ZEND_ARG_INFO(0, how) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +#ifdef SW_USE_OPENSSL +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_enableSSL, 0, 0, 0) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() +#endif + +static const zend_function_entry swoole_client_methods[] = +{ + PHP_ME(swoole_client, __construct, arginfo_swoole_client_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_client, __destruct, arginfo_swoole_client_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_client, set, arginfo_swoole_client_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, connect, arginfo_swoole_client_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, recv, arginfo_swoole_client_recv, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, send, arginfo_swoole_client_send, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, pipe, arginfo_swoole_client_pipe, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, sendfile, arginfo_swoole_client_sendfile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, sendto, arginfo_swoole_client_sendto, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, sleep, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, wakeup, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_client, pause, sleep, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_client, resume, wakeup, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, shutdown, arginfo_swoole_client_shutdown, ZEND_ACC_PUBLIC) +#ifdef SW_USE_OPENSSL + PHP_ME(swoole_client, enableSSL, arginfo_swoole_client_enableSSL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, getPeerCert, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, verifyPeerCert, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_client, isConnected, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, getsockname, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, getpeername, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, close, arginfo_swoole_client_close, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client, on, arginfo_swoole_client_on, ZEND_ACC_PUBLIC) +#ifdef SWOOLE_SOCKETS_SUPPORT + PHP_ME(swoole_client, getSocket, arginfo_swoole_client_void, ZEND_ACC_PUBLIC) +#endif + PHP_FE_END +}; + +static swHashMap *php_sw_long_connections; + +zend_class_entry swoole_client_ce; +zend_class_entry *swoole_client_class_entry_ptr; + +void swoole_client_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_client_ce, "swoole_client", "Swoole\\Client", swoole_client_methods); + swoole_client_class_entry_ptr = zend_register_internal_class(&swoole_client_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_client, "Swoole\\Client"); + + zend_declare_property_long(swoole_client_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_class_entry_ptr, SW_STRL("sock")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_client_class_entry_ptr, SW_STRL("reuse")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_class_entry_ptr, SW_STRL("reuseCount")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("id"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + /** + * event callback + */ + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onError"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onReceive"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onBufferFull"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onBufferEmpty"), ZEND_ACC_PUBLIC TSRMLS_CC); +#ifdef SW_USE_OPENSSL + zend_declare_property_null(swoole_client_class_entry_ptr, ZEND_STRL("onSSLReady"), ZEND_ACC_PUBLIC TSRMLS_CC); +#endif + + php_sw_long_connections = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("MSG_OOB"), MSG_OOB TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("MSG_PEEK"), MSG_PEEK TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("MSG_DONTWAIT"), MSG_DONTWAIT TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("MSG_WAITALL"), MSG_WAITALL TSRMLS_CC); + + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("SHUT_RDWR"), SHUT_RDWR TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("SHUT_RD"), SHUT_RD TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_class_entry_ptr, ZEND_STRL("SHUT_WR"), SHUT_WR TSRMLS_CC); +} + +static void client_onReceive(swClient *cli, char *data, uint32_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = (zval *) cli->object; + zval *zcallback = NULL; + zval **args[2]; + zval *retval; + + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, data, length, 1); + + args[0] = &zobject; + args[1] = &zdata; + + client_callback *cb = (client_callback *) swoole_get_property(zobject, 0); + zcallback = cb->onReceive; + if (zcallback == NULL || ZVAL_IS_NULL(zcallback)) + { + swoole_php_fatal_error(E_WARNING, "swoole_client object has no 'onReceive' callback function."); + goto free_zdata; + } + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + if (sw_call_user_function_fast(zcallback, &cb->cache_onReceive, &retval, 2, args TSRMLS_CC) == FAILURE) +#else + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) +#endif + { + swoole_php_fatal_error(E_WARNING, "onReactorCallback handler error"); + goto free_zdata; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + free_zdata: + sw_zval_ptr_dtor(&zdata); +} + +static void client_onConnect(swClient *cli) +{ + zval *zobject = (zval *) cli->object; +#ifdef SW_USE_OPENSSL + if (cli->ssl_wait_handshake) + { + client_execute_callback(zobject, SW_CLIENT_CB_onSSLReady); + } + else +#endif + if (!cli->redirect) + { + client_execute_callback(zobject, SW_CLIENT_CB_onConnect); + } + else + { + SWOOLE_GET_TSRMLS; + client_callback *cb = (client_callback *) swoole_get_property(zobject, 0); + if (!cb || !cb->onReceive) + { + swoole_php_fatal_error(E_ERROR, "has no 'onReceive' callback function."); + } + } +} + +static void client_onClose(swClient *cli) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = (zval *) cli->object; + if (!cli->released) + { + php_swoole_client_free(zobject, cli TSRMLS_CC); + } + client_execute_callback(zobject, SW_CLIENT_CB_onClose); + sw_zval_ptr_dtor(&zobject); +} + +static void client_onError(swClient *cli) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = (zval *) cli->object; + zend_update_property_long(swoole_client_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); + if (!cli->released) + { + php_swoole_client_free(zobject, cli TSRMLS_CC); + } + client_execute_callback(zobject, SW_CLIENT_CB_onError); + sw_zval_ptr_dtor(&zobject); +} + +static void client_onBufferFull(swClient *cli) +{ + zval *zobject = (zval *) cli->object; + client_execute_callback(zobject, SW_CLIENT_CB_onBufferFull); +} + +static void client_onBufferEmpty(swClient *cli) +{ + zval *zobject = (zval *) cli->object; + client_execute_callback(zobject, SW_CLIENT_CB_onBufferEmpty); +} + +#ifdef SW_USE_OPENSSL +void php_swoole_client_check_ssl_setting(swClient *cli, zval *zset TSRMLS_DC) +{ + HashTable *vht = Z_ARRVAL_P(zset); + zval *v; + + if (php_swoole_array_get_value(vht, "ssl_method", v)) + { + convert_to_long(v); + cli->ssl_option.method = (int) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "ssl_compress", v)) + { + convert_to_boolean(v); + cli->ssl_option.disable_compress = !Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "ssl_cert_file", v)) + { + convert_to_string(v); + cli->ssl_option.cert_file = sw_strdup(Z_STRVAL_P(v)); + if (access(cli->ssl_option.cert_file, R_OK) < 0) + { + swoole_php_fatal_error(E_ERROR, "ssl cert file[%s] not found.", cli->ssl_option.cert_file); + return; + } + } + if (php_swoole_array_get_value(vht, "ssl_key_file", v)) + { + convert_to_string(v); + cli->ssl_option.key_file = sw_strdup(Z_STRVAL_P(v)); + if (access(cli->ssl_option.key_file, R_OK) < 0) + { + swoole_php_fatal_error(E_ERROR, "ssl key file[%s] not found.", cli->ssl_option.key_file); + return; + } + } + if (php_swoole_array_get_value(vht, "ssl_passphrase", v)) + { + convert_to_string(v); + cli->ssl_option.passphrase = sw_strdup(Z_STRVAL_P(v)); + } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (php_swoole_array_get_value(vht, "ssl_host_name", v)) + { + convert_to_string(v); + cli->ssl_option.tls_host_name = sw_strdup(Z_STRVAL_P(v)); + } +#endif + if (php_swoole_array_get_value(vht, "ssl_verify_peer", v)) + { + convert_to_boolean(v); + cli->ssl_option.verify_peer = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "ssl_allow_self_signed", v)) + { + convert_to_boolean(v); + cli->ssl_option.allow_self_signed = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "ssl_cafile", v)) + { + convert_to_string(v); + cli->ssl_option.cafile = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_capath", v)) + { + convert_to_string(v); + cli->ssl_option.capath = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_verify_depth", v)) + { + convert_to_long(v); + cli->ssl_option.verify_depth = (int) Z_LVAL_P(v); + } + if (cli->ssl_option.cert_file && !cli->ssl_option.key_file) + { + swoole_php_fatal_error(E_ERROR, "ssl require key file."); + return; + } +} +#endif + +int php_swoole_client_isset_callback(zval *zobject, int type TSRMLS_DC) +{ + client_callback *cb = (client_callback *) swoole_get_property(zobject, client_property_callback); + switch (type) + { + case SW_CLIENT_CB_onConnect: + return cb->onConnect != NULL; + case SW_CLIENT_CB_onError: + return cb->onError != NULL; + case SW_CLIENT_CB_onClose: + return cb->onClose != NULL; + case SW_CLIENT_CB_onBufferFull: + return cb->onBufferFull != NULL; + case SW_CLIENT_CB_onBufferEmpty: + return cb->onBufferEmpty != NULL; +#ifdef SW_USE_OPENSSL + case SW_CLIENT_CB_onSSLReady: + return cb->onSSLReady != NULL; +#endif + default: + return SW_FALSE; + } +} + +void php_swoole_client_check_setting(swClient *cli, zval *zset TSRMLS_DC) +{ + HashTable *vht; + zval *v; + int value = 1; + + char *bind_address = NULL; + int bind_port = 0; + + vht = Z_ARRVAL_P(zset); + + //buffer: eof check + if (php_swoole_array_get_value(vht, "open_eof_check", v)) + { + convert_to_boolean(v); + cli->open_eof_check = Z_BVAL_P(v); + } + //buffer: split package with eof + if (php_swoole_array_get_value(vht, "open_eof_split", v)) + { + convert_to_boolean(v); + cli->protocol.split_by_eof = Z_BVAL_P(v); + if (cli->protocol.split_by_eof) + { + cli->open_eof_check = 1; + } + } + //package eof + if (php_swoole_array_get_value(vht, "package_eof", v)) + { + convert_to_string(v); + cli->protocol.package_eof_len = Z_STRLEN_P(v); + if (cli->protocol.package_eof_len > SW_DATA_EOF_MAXLEN) + { + swoole_php_fatal_error(E_ERROR, "pacakge_eof max length is %d", SW_DATA_EOF_MAXLEN); + return; + } + bzero(cli->protocol.package_eof, SW_DATA_EOF_MAXLEN); + memcpy(cli->protocol.package_eof, Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //open mqtt protocol + if (php_swoole_array_get_value(vht, "open_mqtt_protocol", v)) + { + convert_to_boolean(v); + cli->open_length_check = Z_BVAL_P(v); + cli->protocol.get_package_length = swMqtt_get_package_length; + } + //open length check + if (php_swoole_array_get_value(vht, "open_length_check", v)) + { + convert_to_boolean(v); + cli->open_length_check = Z_BVAL_P(v); + cli->protocol.get_package_length = swProtocol_get_package_length; + } + //package length size + if (php_swoole_array_get_value(vht, "package_length_type", v)) + { + convert_to_string(v); + cli->protocol.package_length_type = Z_STRVAL_P(v)[0]; + cli->protocol.package_length_size = swoole_type_size(cli->protocol.package_length_type); + + if (cli->protocol.package_length_size == 0) + { + swoole_php_fatal_error(E_ERROR, "Unknown package_length_type name '%c', see pack(). Link: http://php.net/pack", cli->protocol.package_length_type); + return; + } + } + //length function + if (php_swoole_array_get_value(vht, "package_length_func", v)) + { + while(1) + { + if (Z_TYPE_P(v) == IS_STRING) + { + swProtocol_length_function func = (swProtocol_length_function) swoole_get_function(Z_STRVAL_P(v), + Z_STRLEN_P(v)); + if (func != NULL) + { + cli->protocol.get_package_length = func; + break; + } + } + + char *func_name = NULL; + if (!sw_zend_is_callable(v, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + cli->protocol.get_package_length = php_swoole_length_func; + sw_zval_add_ref(&v); + cli->protocol.private_data = sw_zval_dup(v); + break; + } + + cli->protocol.package_length_size = 0; + cli->protocol.package_length_type = '\0'; + cli->protocol.package_length_offset = SW_BUFFER_SIZE; + } + //package length offset + if (php_swoole_array_get_value(vht, "package_length_offset", v)) + { + convert_to_long(v); + cli->protocol.package_length_offset = (int) Z_LVAL_P(v); + } + //package body start + if (php_swoole_array_get_value(vht, "package_body_offset", v)) + { + convert_to_long(v); + cli->protocol.package_body_offset = (int) Z_LVAL_P(v); + } + /** + * package max length + */ + if (php_swoole_array_get_value(vht, "package_max_length", v)) + { + convert_to_long(v); + cli->protocol.package_max_length = (int) Z_LVAL_P(v); + } + else + { + cli->protocol.package_max_length = SW_BUFFER_INPUT_SIZE; + } + /** + * socket send/recv buffer size + */ + if (php_swoole_array_get_value(vht, "socket_buffer_size", v)) + { + convert_to_long(v); + value = (int) Z_LVAL_P(v); + if (value <= 0) + { + value = SW_MAX_INT; + } + swSocket_set_buffer_size(cli->socket->fd, value); + cli->socket->buffer_size = value; + } + if (php_swoole_array_get_value(vht, "buffer_high_watermark", v)) + { + convert_to_long(v); + value = (int) Z_LVAL_P(v); + cli->buffer_high_watermark = value; + } + if (php_swoole_array_get_value(vht, "buffer_low_watermark", v)) + { + convert_to_long(v); + value = (int) Z_LVAL_P(v); + cli->buffer_low_watermark = value; + } + /** + * bind address + */ + if (php_swoole_array_get_value(vht, "bind_address", v)) + { + convert_to_string(v); + bind_address = Z_STRVAL_P(v); + } + /** + * bind port + */ + if (php_swoole_array_get_value(vht, "bind_port", v)) + { + convert_to_long(v); + bind_port = (int) Z_LVAL_P(v); + } + if (bind_address) + { + swSocket_bind(cli->socket->fd, cli->type, bind_address, &bind_port); + } + /** + * TCP_NODELAY + */ + if (php_swoole_array_get_value(vht, "open_tcp_nodelay", v)) + { + value = 1; + if (setsockopt(cli->socket->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)) < 0) + { + swSysError("setsockopt(%d, TCP_NODELAY) failed.", cli->socket->fd); + } + } + /** + * socks5 proxy + */ + if (php_swoole_array_get_value(vht, "socks5_host", v)) + { + convert_to_string(v); + cli->socks5_proxy = (struct _swSocks5 *) emalloc(sizeof(swSocks5)); + bzero(cli->socks5_proxy, sizeof(swSocks5)); + cli->socks5_proxy->host = estrdup(Z_STRVAL_P(v)); + cli->socks5_proxy->dns_tunnel = 1; + + if (php_swoole_array_get_value(vht, "socks5_port", v)) + { + convert_to_long(v); + cli->socks5_proxy->port = Z_LVAL_P(v); + } + else + { + swoole_php_fatal_error(E_ERROR, "socks5 proxy require server port option."); + return; + } + if (php_swoole_array_get_value(vht, "socks5_username", v)) + { + convert_to_string(v); + cli->socks5_proxy->username = estrdup(Z_STRVAL_P(v)); + cli->socks5_proxy->l_username = Z_STRLEN_P(v); + cli->socks5_proxy->method = 0x02; + } + if (php_swoole_array_get_value(vht, "socks5_password", v)) + { + convert_to_string(v); + cli->socks5_proxy->password = estrdup(Z_STRVAL_P(v)); + cli->socks5_proxy->l_password = Z_STRLEN_P(v); + } + } + if (php_swoole_array_get_value(vht, "http_proxy_host", v)) + { + convert_to_string(v); + char *host = Z_STRVAL_P(v); + if (php_swoole_array_get_value(vht, "http_proxy_port", v)) + { + convert_to_long(v); + cli->http_proxy = (struct _http_proxy*) ecalloc(1, sizeof(struct _http_proxy)); + cli->http_proxy->proxy_host = estrdup(host); + cli->http_proxy->proxy_port = Z_LVAL_P(v); + } + else + { + swoole_php_fatal_error(E_WARNING, "http_proxy_port can not be null."); + } + } + if (php_swoole_array_get_value(vht, "http_proxy_user", v) && cli->http_proxy) + { + convert_to_string(v); + char *user = Z_STRVAL_P(v); + zval *v2; + if (php_swoole_array_get_value(vht, "http_proxy_password", v2)) + { + convert_to_string(v); + if (Z_STRLEN_P(v) + Z_STRLEN_P(v2) >= 128 - 1) + { + swoole_php_fatal_error(E_WARNING, "http_proxy user and password is too long."); + } + cli->http_proxy->l_user = Z_STRLEN_P(v); + cli->http_proxy->l_password = Z_STRLEN_P(v2); + cli->http_proxy->user = estrdup(user); + cli->http_proxy->password = estrdup(Z_STRVAL_P(v2)); + } + else + { + swoole_php_fatal_error(E_WARNING, "http_proxy_password can not be null."); + } + } +#ifdef SW_USE_OPENSSL + if (cli->open_ssl) + { + php_swoole_client_check_ssl_setting(cli, zset TSRMLS_CC); + } +#endif +} + +void php_swoole_at_shutdown(char *function) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + +#if PHP_MAJOR_VERSION >=7 + php_shutdown_function_entry shutdown_function_entry; + shutdown_function_entry.arg_count = 1; + shutdown_function_entry.arguments = (zval *) safe_emalloc(sizeof(zval), 1, 0); + ZVAL_STRING(&shutdown_function_entry.arguments[0], function); + + if (!register_user_shutdown_function(function, ZSTR_LEN(Z_STR(shutdown_function_entry.arguments[0])), &shutdown_function_entry TSRMLS_CC)) + { + zval_ptr_dtor(&shutdown_function_entry.arguments[0]); + efree(shutdown_function_entry.arguments); + swoole_php_fatal_error(E_WARNING, "Unable to register shutdown function [%s]",ZSTR_LEN(Z_STR(shutdown_function_entry.arguments[0]))); + } +#else + + zval *callback; + SW_MAKE_STD_ZVAL(callback); + SW_ZVAL_STRING(callback, function, 1); + +#if PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4 + + php_shutdown_function_entry shutdown_function_entry; + + shutdown_function_entry.arg_count = 1; + shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), 1, 0); + + + shutdown_function_entry.arguments[0] = callback; + + if (!register_user_shutdown_function(function, ZSTR_LEN(Z_STR(callback)), &shutdown_function_entry TSRMLS_CC)) + { + efree(shutdown_function_entry.arguments); + sw_zval_ptr_dtor(&callback); + swoole_php_fatal_error(E_WARNING, "Unable to register shutdown function [swoole_event_wait]"); + } +#else + zval *register_shutdown_function; + zval *retval = NULL; + SW_MAKE_STD_ZVAL(register_shutdown_function); + SW_ZVAL_STRING(register_shutdown_function, "register_shutdown_function", 1); + zval **args[1] = {&callback}; + + if (sw_call_user_function_ex(EG(function_table), NULL, register_shutdown_function, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "Unable to register shutdown function [swoole_event_wait]"); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } +#endif + +#endif +} + +void php_swoole_check_reactor() +{ + if (SwooleWG.reactor_init) + { + return; + } + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + if (!SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "async-io must be used in PHP CLI mode."); + return; + } + + if (swIsTaskWorker()) + { + swoole_php_fatal_error(E_ERROR, "can't use async-io in task process."); + return; + } + + if (SwooleG.main_reactor == NULL) + { + swTraceLog(SW_TRACE_PHP, "init reactor"); + + SwooleG.main_reactor = (swReactor *) sw_malloc(sizeof(swReactor)); + if (SwooleG.main_reactor == NULL) + { + swoole_php_fatal_error(E_ERROR, "malloc failed."); + return; + } + if (swReactor_create(SwooleG.main_reactor, SW_REACTOR_MAXEVENTS) < 0) + { + swoole_php_fatal_error(E_ERROR, "failed to create reactor."); + return; + } + +#ifdef SW_COROUTINE + SwooleG.main_reactor->can_exit = php_coroutine_reactor_can_exit; +#endif + + //client, swoole_event_exit will set swoole_running = 0 + SwooleWG.in_client = 1; + SwooleWG.reactor_wait_onexit = 1; + SwooleWG.reactor_ready = 0; + //only client side + php_swoole_at_shutdown("swoole_event_wait"); + } + + php_swoole_event_init(); + + SwooleWG.reactor_init = 1; +} + +void php_swoole_client_free(zval *zobject, swClient *cli TSRMLS_DC) +{ + //socks5 proxy config + if (cli->socks5_proxy) + { + efree(cli->socks5_proxy->host); + if (cli->socks5_proxy->username) + { + efree(cli->socks5_proxy->username); + } + if (cli->socks5_proxy->password) + { + efree(cli->socks5_proxy->password); + } + efree(cli->socks5_proxy); + } + //http proxy config + if (cli->http_proxy) + { + efree(cli->http_proxy->proxy_host); + if (cli->http_proxy->user) + { + efree(cli->http_proxy->user); + } + if (cli->http_proxy->password) + { + efree(cli->http_proxy->password); + } + efree(cli->http_proxy); + } + if (cli->protocol.private_data) + { + zval *zcallback = (zval *) cli->protocol.private_data; + sw_zval_free(zcallback); + } + //long tcp connection, delete from php_sw_long_connections + if (cli->keep) + { + if (swHashMap_del(php_sw_long_connections, cli->server_str, cli->server_strlen)) + { + swoole_php_fatal_error(E_WARNING, "failed to delete key[%s] from hashtable.", cli->server_str); + } + sw_free(cli->server_str); + swClient_free(cli); + pefree(cli, 1); + } + else + { + sw_free(cli->server_str); + swClient_free(cli); + efree(cli); + } +#ifdef SWOOLE_SOCKETS_SUPPORT + zval *zsocket = (zval *) swoole_get_property(zobject, client_property_socket); + if (zsocket) + { + sw_zval_free(zsocket); + swoole_set_property(zobject, client_property_socket, NULL); + } +#endif + //unset object + swoole_set_object(zobject, NULL); +} + +swClient* php_swoole_client_new(zval *object, char *host, int host_len, int port) +{ + zval *ztype; + int async = 0; + char conn_key[SW_LONG_CONNECTION_KEY_LEN]; + int conn_key_len = 0; + uint64_t tmp_buf; + int ret; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + ztype = sw_zend_read_property(Z_OBJCE_P(object), object, SW_STRL("type")-1, 0 TSRMLS_CC); + + if (ztype == NULL || ZVAL_IS_NULL(ztype)) + { + swoole_php_fatal_error(E_ERROR, "failed to get swoole_client->type."); + return NULL; + } + + long type = Z_LVAL_P(ztype); + + //new flag, swoole-1.6.12+ + if (type & SW_FLAG_ASYNC) + { + async = 1; + } + + swClient *cli; + bzero(conn_key, SW_LONG_CONNECTION_KEY_LEN); + zval *connection_id = sw_zend_read_property(Z_OBJCE_P(object), object, ZEND_STRL("id"), 1 TSRMLS_CC); + + if (connection_id == NULL || ZVAL_IS_NULL(connection_id)) + { + conn_key_len = snprintf(conn_key, SW_LONG_CONNECTION_KEY_LEN, "%s:%d", host, port) + 1; + } + else + { + conn_key_len = snprintf(conn_key, SW_LONG_CONNECTION_KEY_LEN, "%s", Z_STRVAL_P(connection_id)) + 1; + } + + //keep the tcp connection + if (type & SW_FLAG_KEEP) + { + swClient *find = swHashMap_find(php_sw_long_connections, conn_key, conn_key_len); + if (find == NULL) + { + cli = (swClient*) pemalloc(sizeof(swClient), 1); + if (swHashMap_add(php_sw_long_connections, conn_key, conn_key_len, cli) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "failed to add swoole_client_create_socket to hashtable."); + } + goto create_socket; + } + else + { + cli = find; + //try recv, check connection status + ret = recv(cli->socket->fd, &tmp_buf, sizeof(tmp_buf), MSG_DONTWAIT | MSG_PEEK); + if (ret == 0 || (ret < 0 && swConnection_error(errno) == SW_CLOSE)) + { + cli->close(cli); + goto create_socket; + } + cli->reuse_count ++; + zend_update_property_long(Z_OBJCE_P(object), object, ZEND_STRL("reuseCount"), cli->reuse_count TSRMLS_CC); + } + } + else + { + cli = (swClient*) emalloc(sizeof(swClient)); + + create_socket: + if (swClient_create(cli, php_swoole_socktype(type), async) < 0) + { + swoole_php_fatal_error(E_WARNING, "swClient_create() failed. Error: %s [%d]", strerror(errno), errno); + zend_update_property_long(Z_OBJCE_P(object), object, ZEND_STRL("errCode"), errno TSRMLS_CC); + return NULL; + } + + //don't forget free it + cli->server_str = sw_strndup(conn_key, conn_key_len); + cli->server_strlen = conn_key_len; + } + + zend_update_property_long(Z_OBJCE_P(object), object, ZEND_STRL("sock"), cli->socket->fd TSRMLS_CC); + + if (type & SW_FLAG_KEEP) + { + cli->keep = 1; + } + +#ifdef SW_USE_OPENSSL + if (type & SW_SOCK_SSL) + { + cli->open_ssl = 1; + } +#endif + + return cli; +} + +static PHP_METHOD(swoole_client, __construct) +{ + long async = 0; + long type = 0; + char *id = NULL; + zend_size_t len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ls", &type, &async, &id, &len) == FAILURE) + { + swoole_php_fatal_error(E_ERROR, "socket type param is required."); + RETURN_FALSE; + } + + if (async == 1) + { + type |= SW_FLAG_ASYNC; + } + + if ((type & SW_FLAG_ASYNC)) + { + if ((type & SW_FLAG_KEEP) && SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "The 'SWOOLE_KEEP' flag can only be used in the php-fpm or apache environment."); + } + php_swoole_check_reactor(); + } + + int client_type = php_swoole_socktype(type); + if (client_type < SW_SOCK_TCP || client_type > SW_SOCK_UNIX_STREAM) + { + swoole_php_fatal_error(E_ERROR, "Unknown client type '%d'.", client_type); + } + + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("type"), type TSRMLS_CC); + if (id) + { + zend_update_property_stringl(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("id"), id, len TSRMLS_CC); + } + else + { + zend_update_property_null(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("id") TSRMLS_CC); + } + //init + swoole_set_object(getThis(), NULL); + swoole_set_property(getThis(), client_property_callback, NULL); +#ifdef SWOOLE_SOCKETS_SUPPORT + swoole_set_property(getThis(), client_property_socket, NULL); +#endif + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client, __destruct) +{ + swClient *cli = (swClient *) swoole_get_object(getThis()); + //no keep connection + if (cli && cli->released == 0) + { + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_client_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + //free memory + client_callback *cb = (client_callback *) swoole_get_property(getThis(), client_property_callback); + if (cb) + { + efree(cb); + swoole_set_property(getThis(), client_property_callback, NULL); + } +} + +static PHP_METHOD(swoole_client, set) +{ + zval *zset; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + + zval *zsetting = php_swoole_read_init_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client, connect) +{ + zend_long port = 0, sock_flag = 0; + char *host = NULL; + zend_size_t host_len; + double timeout = SW_CLIENT_DEFAULT_TIMEOUT; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_STRING(host, host_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(port) + Z_PARAM_DOUBLE(timeout) + Z_PARAM_LONG(sock_flag) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ldl", &host, &host_len, &port, &timeout, &sock_flag) == FAILURE) + { + return; + } +#endif + + if (host_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "The host is empty."); + RETURN_FALSE; + } + + swClient *cli = (swClient *) swoole_get_object(getThis()); + if (cli) + { + swoole_php_fatal_error(E_WARNING, "connection to the server has already been established."); + RETURN_FALSE; + } + + cli = php_swoole_client_new(getThis(), host, host_len, port); + if (cli == NULL) + { + RETURN_FALSE; + } + swoole_set_object(getThis(), cli); + + if (cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_TCP6) + { + if (port <= 0 || port > SW_CLIENT_MAX_PORT) + { + swoole_php_fatal_error(E_WARNING, "The port is invalid."); + RETURN_FALSE; + } + if (cli->async == 1) + { + //for tcp: nonblock + //for udp: have udp connect + sock_flag = 1; + } + } + + if (cli->keep == 1 && cli->socket->active == 1) + { + zend_update_property_bool(swoole_client_class_entry_ptr, getThis(), SW_STRL("reuse")-1, 1 TSRMLS_CC); + RETURN_TRUE; + } + else if (cli->socket->active == 1) + { + swoole_php_fatal_error(E_WARNING, "connection to the server has already been established."); + RETURN_FALSE; + } + + zval *zset = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + php_swoole_client_check_setting(cli, zset TSRMLS_CC); + } + + //nonblock async + if (cli->async) + { + client_callback *cb = (client_callback *) swoole_get_property(getThis(), 0); + if (!cb) + { + swoole_php_fatal_error(E_ERROR, "no event callback function."); + RETURN_FALSE; + } + + if (swSocket_is_stream(cli->type)) + { + if (!cb->onConnect) + { + swoole_php_fatal_error(E_ERROR, "no 'onConnect' callback function."); + RETURN_FALSE; + } + if (!cb->onError) + { + swoole_php_fatal_error(E_ERROR, "no 'onError' callback function."); + RETURN_FALSE; + } + if (!cb->onClose) + { + swoole_php_fatal_error(E_ERROR, "no 'onClose' callback function."); + RETURN_FALSE; + } + cli->onConnect = client_onConnect; + cli->onClose = client_onClose; + cli->onError = client_onError; + cli->onReceive = client_onReceive; + cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; + if (cb->onBufferFull) + { + cli->onBufferFull = client_onBufferFull; + } + if (cb->onBufferEmpty) + { + cli->onBufferEmpty = client_onBufferEmpty; + } + } + else + { + if (!cb || !cb->onReceive) + { + swoole_php_fatal_error(E_ERROR, "no 'onReceive' callback function."); + RETURN_FALSE; + } + if (cb->onConnect) + { + cli->onConnect = client_onConnect; + } + if (cb->onClose) + { + cli->onClose = client_onClose; + } + cli->onReceive = client_onReceive; + cli->reactor_fdtype = PHP_SWOOLE_FD_DGRAM_CLIENT; + } + + zval *zobject = getThis(); + cli->object = zobject; + sw_copy_to_stack(cli->object, cb->_object); + sw_zval_add_ref(&zobject); + } + + //nonblock async + if (cli->connect(cli, host, port, timeout, sock_flag) < 0) + { + if (errno == 0 ) + { + if (SwooleG.error == SW_ERROR_DNSLOOKUP_RESOLVE_FAILED) + { + swoole_php_error(E_WARNING, "connect to server[%s:%d] failed. Error: %s[%d]", host, (int )port, + hstrerror(h_errno), h_errno); + } + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + } + else + { + swoole_php_sys_error(E_WARNING, "connect to server[%s:%d] failed.", host, (int )port); + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, errno TSRMLS_CC); + } + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client, send) +{ + char *data; + zend_size_t data_len; + zend_long flags = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(data, data_len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags) == FAILURE) + { + return; + } +#endif + + if (data_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "data to send is empty."); + RETURN_FALSE; + } + + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + + //clear errno + SwooleG.error = 0; + int ret = cli->send(cli, data, data_len, flags); + if (ret < 0) + { + swoole_php_sys_error(E_WARNING, "failed to send(%d) %d bytes.", cli->socket->fd, data_len); + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + RETVAL_FALSE; + } + else + { + RETURN_LONG(ret); + } +} + +static PHP_METHOD(swoole_client, sendto) +{ + char* ip; + zend_size_t ip_len; + long port; + char *data; + zend_size_t len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &ip, &ip_len, &port, &data, &len) == FAILURE) + { + return; + } + + if (len <= 0) + { + swoole_php_error(E_WARNING, "data to send is empty."); + RETURN_FALSE; + } + + swClient *cli = (swClient *) swoole_get_object(getThis()); + if (!cli) + { + cli = php_swoole_client_new(getThis(), ip, ip_len, port); + if (cli == NULL) + { + RETURN_FALSE; + } + cli->socket->active = 1; + swoole_set_object(getThis(), cli); + } + + int ret; + if (cli->type == SW_SOCK_UDP) + { + ret = swSocket_udp_sendto(cli->socket->fd, ip, port, data, len); + } + else if (cli->type == SW_SOCK_UDP6) + { + ret = swSocket_udp_sendto6(cli->socket->fd, ip, port, data, len); + } + else + { + swoole_php_fatal_error(E_WARNING, "only supports SWOOLE_SOCK_UDP or SWOOLE_SOCK_UDP6."); + RETURN_FALSE; + } + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_client, sendfile) +{ + char *file; + zend_size_t file_len; + long offset = 0; + long length = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &file, &file_len, &offset, &length) == FAILURE) + { + return; + } + if (file_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "file to send is empty."); + RETURN_FALSE; + } + + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + //only stream socket can sendfile + if (!(cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_TCP6 || cli->type == SW_SOCK_UNIX_STREAM)) + { + swoole_php_error(E_WARNING, "dgram socket cannot use sendfile."); + RETURN_FALSE; + } + //clear errno + SwooleG.error = 0; + int ret = cli->sendfile(cli, file, offset, length); + if (ret < 0) + { + SwooleG.error = errno; + swoole_php_fatal_error(E_WARNING, "sendfile() failed. Error: %s [%d]", strerror(SwooleG.error), SwooleG.error); + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + RETVAL_FALSE; + } + else + { + RETVAL_TRUE; + } +} + +static PHP_METHOD(swoole_client, recv) +{ + zend_long buf_len = SW_PHP_CLIENT_BUFFER_SIZE; + zend_long flags = 0; + int ret; + char *buf = NULL; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(buf_len) + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &buf_len, &flags) == FAILURE) + { + return; + } +#endif + + //waitall + if (flags == 1) + { + flags = MSG_WAITALL; + } + + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + + swProtocol *protocol = &cli->protocol; + + if (cli->open_eof_check) + { + if (cli->buffer == NULL) + { + cli->buffer = swString_new(SW_BUFFER_SIZE_BIG); + } + + swString *buffer = cli->buffer; + int eof = -1; + + if (buffer->length > 0) + { + goto find_eof; + } + + while (1) + { + buf = buffer->str + buffer->length; + buf_len = buffer->size - buffer->length; + + if (buf_len > SW_BUFFER_SIZE_BIG) + { + buf_len = SW_BUFFER_SIZE_BIG; + } + + ret = cli->recv(cli, buf, buf_len, 0); + if (ret < 0) + { + swoole_php_error(E_WARNING, "recv() failed. Error: %s [%d]", strerror(errno), errno); + buffer->length = 0; + RETURN_FALSE; + } + else if (ret == 0) + { + buffer->length = 0; + RETURN_EMPTY_STRING(); + } + + buffer->length += ret; + + if (buffer->length < protocol->package_eof_len) + { + continue; + } + + find_eof: eof = swoole_strnpos(buffer->str, buffer->length, protocol->package_eof, protocol->package_eof_len); + if (eof >= 0) + { + eof += protocol->package_eof_len; + SW_RETVAL_STRINGL(buffer->str, eof, 1); + + if (buffer->length > eof) + { + buffer->length -= eof; + memmove(buffer->str, buffer->str + eof, buffer->length); + } + else + { + buffer->length = 0; + } + return; + } + else + { + if (buffer->length == protocol->package_max_length) + { + swoole_php_error(E_WARNING, "no package eof"); + buffer->length = 0; + RETURN_FALSE; + } + else if (buffer->length == buffer->size) + { + if (buffer->size < protocol->package_max_length) + { + int new_size = buffer->size * 2; + if (new_size > protocol->package_max_length) + { + new_size = protocol->package_max_length; + } + if (swString_extend(buffer, new_size) < 0) + { + buffer->length = 0; + RETURN_FALSE; + } + } + } + } + } + buffer->length = 0; + RETURN_FALSE; + } + else if (cli->open_length_check) + { + if (cli->buffer == NULL) + { + cli->buffer = swString_new(SW_BUFFER_SIZE_STD); + } + + uint32_t header_len = protocol->package_length_offset + protocol->package_length_size; + ret = cli->recv(cli, cli->buffer->str, header_len, MSG_WAITALL); + if (ret <= 0) + { + goto check_return; + } + else if (ret != header_len) + { + ret = 0; + goto check_return; + } + + buf_len = protocol->get_package_length(protocol, cli->socket, cli->buffer->str, ret); + + //error package + if (buf_len < 0) + { + RETURN_EMPTY_STRING(); + } + //empty package + else if (buf_len == header_len) + { + SW_RETURN_STRINGL(cli->buffer->str, header_len, 1); + } + else if (buf_len > protocol->package_max_length) + { + swoole_error_log(SW_LOG_WARNING, SW_ERROR_PACKAGE_LENGTH_TOO_LARGE, "Package is too big. package_length=%d", (int )buf_len); + RETURN_EMPTY_STRING(); + } + + buf = (char *) emalloc(buf_len + 1); + memcpy(buf, cli->buffer->str, header_len); + SwooleG.error = 0; + ret = cli->recv(cli, buf + header_len, buf_len - header_len, MSG_WAITALL); + if (ret > 0) + { + ret += header_len; + if (ret != buf_len) + { + ret = 0; + } + } + } + else + { + if (!(flags & MSG_WAITALL) && buf_len > SW_PHP_CLIENT_BUFFER_SIZE) + { + buf_len = SW_PHP_CLIENT_BUFFER_SIZE; + } + buf = (char *) emalloc(buf_len + 1); + SwooleG.error = 0; + ret = cli->recv(cli, buf, buf_len, flags); + } + + check_return: + + if (ret < 0) + { + SwooleG.error = errno; + swoole_php_error(E_WARNING, "recv() failed. Error: %s [%d]", strerror(SwooleG.error), SwooleG.error); + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + swoole_efree(buf); + RETURN_FALSE; + } + else + { + if (ret == 0) + { + swoole_efree(buf); + RETURN_EMPTY_STRING(); + } + else + { + buf[ret] = 0; + SW_RETVAL_STRINGL(buf, ret, 0); + } + } +} + +static PHP_METHOD(swoole_client, isConnected) +{ + swClient *cli = (swClient *) swoole_get_object(getThis()); + if (!cli) + { + RETURN_FALSE; + } + if (!cli->socket) + { + RETURN_FALSE; + } + RETURN_BOOL(cli->socket->active); +} + +static PHP_METHOD(swoole_client, getsockname) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + + if (cli->type == SW_SOCK_UNIX_STREAM || cli->type == SW_SOCK_UNIX_DGRAM) + { + swoole_php_fatal_error(E_WARNING, "getsockname() only support AF_INET family socket."); + RETURN_FALSE; + } + + cli->socket->info.len = sizeof(cli->socket->info.addr); + if (getsockname(cli->socket->fd, (struct sockaddr*) &cli->socket->info.addr, &cli->socket->info.len) < 0) + { + swoole_php_sys_error(E_WARNING, "getsockname() failed."); + RETURN_FALSE; + } + + array_init(return_value); + if (cli->type == SW_SOCK_UDP6 || cli->type == SW_SOCK_TCP6) + { + add_assoc_long(return_value, "port", ntohs(cli->socket->info.addr.inet_v6.sin6_port)); + char tmp[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &cli->socket->info.addr.inet_v6.sin6_addr, tmp, sizeof(tmp))) + { + sw_add_assoc_string(return_value, "host", tmp, 1); + } + else + { + swoole_php_fatal_error(E_WARNING, "inet_ntop() failed."); + } + } + else + { + add_assoc_long(return_value, "port", ntohs(cli->socket->info.addr.inet_v4.sin_port)); + sw_add_assoc_string(return_value, "host", inet_ntoa(cli->socket->info.addr.inet_v4.sin_addr), 1); + } +} + +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_client, getSocket) +{ + zval *zsocket = (zval *) swoole_get_property(getThis(), client_property_socket); + if (zsocket) + { + RETURN_ZVAL(zsocket, 1, NULL); + } + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + if (cli->keep) + { + swoole_php_fatal_error(E_WARNING, "the 'getSocket' method can't be used on persistent connection."); + RETURN_FALSE; + } + php_socket *socket_object = swoole_convert_to_socket(cli->socket->fd); + if (!socket_object) + { + RETURN_FALSE; + } + SW_ZEND_REGISTER_RESOURCE(return_value, (void * ) socket_object, php_sockets_le_socket()); + zsocket = sw_zval_dup(return_value); + sw_zval_add_ref(&zsocket); + swoole_set_property(getThis(), client_property_socket, zsocket); +} +#endif + +static PHP_METHOD(swoole_client, getpeername) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + + if (cli->type == SW_SOCK_UDP) + { + array_init(return_value); + add_assoc_long(return_value, "port", ntohs(cli->remote_addr.addr.inet_v4.sin_port)); + sw_add_assoc_string(return_value, "host", inet_ntoa(cli->remote_addr.addr.inet_v4.sin_addr), 1); + } + else if (cli->type == SW_SOCK_UDP6) + { + array_init(return_value); + add_assoc_long(return_value, "port", ntohs(cli->remote_addr.addr.inet_v6.sin6_port)); + char tmp[INET6_ADDRSTRLEN]; + + if (inet_ntop(AF_INET6, &cli->remote_addr.addr.inet_v6.sin6_addr, tmp, sizeof(tmp))) + { + sw_add_assoc_string(return_value, "host", tmp, 1); + } + else + { + swoole_php_fatal_error(E_WARNING, "inet_ntop() failed."); + } + } + else + { + swoole_php_fatal_error(E_WARNING, "only supports SWOOLE_SOCK_UDP or SWOOLE_SOCK_UDP6."); + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_client, close) +{ + int ret = 1; + zend_bool force = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(force) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &force) == FAILURE) + { + return; + } +#endif + + swClient *cli = (swClient *) swoole_get_object(getThis()); + if (!cli || !cli->socket) + { + swoole_php_fatal_error(E_WARNING, "client is not connected to the server."); + RETURN_FALSE; + } + if (cli->socket->closed) + { + swoole_php_error(E_WARNING, "client socket is closed."); + RETURN_FALSE; + } + if (cli->async && cli->socket->active == 0) + { + zval *zobject = getThis(); + sw_zval_ptr_dtor(&zobject); + } + //Connection error, or short tcp connection. + //No keep connection + if (force || !cli->keep || swConnection_error(SwooleG.error) == SW_CLOSE) + { + cli->released = 1; + ret = cli->close(cli); + php_swoole_client_free(getThis(), cli TSRMLS_CC); + } + else + { + //unset object + swoole_set_object(getThis(), NULL); + } + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_client, on) +{ + char *cb_name; + zend_size_t cb_name_len; + zval *zcallback; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &cb_name, &cb_name_len, &zcallback) == FAILURE) + { + return; + } + + zval *ztype = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), SW_STRL("type")-1, 0 TSRMLS_CC); + if (ztype == NULL || ZVAL_IS_NULL(ztype)) + { + swoole_php_fatal_error(E_ERROR, "get swoole_client->type failed."); + return; + } + + if (!(Z_LVAL_P(ztype) & SW_FLAG_ASYNC)) + { + swoole_php_fatal_error(E_ERROR, "can't register event callback functions in SYNC mode."); + return; + } + + client_callback *cb = (client_callback *) swoole_get_property(getThis(), client_property_callback); + if (!cb) + { + cb = (client_callback *) emalloc(sizeof(client_callback)); + bzero(cb, sizeof(client_callback)); + swoole_set_property(getThis(), client_property_callback, cb); + } + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + char *func_name = NULL; + zend_fcall_info_cache func_cache; + if (!sw_zend_is_callable_ex(zcallback, NULL, 0, &func_name, NULL, &func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#elif defined(PHP_SWOOLE_CHECK_CALLBACK) + char *func_name = NULL; + if (!sw_zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + + if (strncasecmp("connect", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), zcallback TSRMLS_CC); + cb->onConnect = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onConnect, cb->_onConnect); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onConnect = func_cache; +#endif + } + else if (strncasecmp("receive", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onReceive"), zcallback TSRMLS_CC); + cb->onReceive = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onReceive"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onReceive, cb->_onReceive); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onReceive = func_cache; +#endif + } + else if (strncasecmp("close", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onClose"), zcallback TSRMLS_CC); + cb->onClose = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onClose"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onClose, cb->_onClose); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onClose = func_cache; +#endif + } + else if (strncasecmp("error", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onError"), zcallback TSRMLS_CC); + cb->onError = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onError"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onError, cb->_onError); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onError = func_cache; +#endif + } + else if (strncasecmp("bufferFull", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onBufferFull"), zcallback TSRMLS_CC); + cb->onBufferFull = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onBufferFull"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onBufferFull, cb->_onBufferFull); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onBufferFull = func_cache; +#endif + } + else if (strncasecmp("bufferEmpty", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onBufferEmpty"), zcallback TSRMLS_CC); + cb->onBufferEmpty = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onBufferEmpty"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onBufferEmpty, cb->_onBufferEmpty); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onBufferEmpty = func_cache; +#endif + } + else + { + swoole_php_fatal_error(E_WARNING, "Unknown event callback type name '%s'.", cb_name); + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client, sleep) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + SW_CHECK_RETURN(swClient_sleep(cli)); +} + +static PHP_METHOD(swoole_client, wakeup) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + SW_CHECK_RETURN(swClient_wakeup(cli)); +} + +#ifdef SW_USE_OPENSSL +static PHP_METHOD(swoole_client, enableSSL) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + if (cli->type != SW_SOCK_TCP && cli->type != SW_SOCK_TCP6) + { + swoole_php_fatal_error(E_WARNING, "cannot use enableSSL."); + RETURN_FALSE; + } + if (cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL has been enabled."); + RETURN_FALSE; + } + cli->open_ssl = 1; + zval *zset = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + php_swoole_client_check_ssl_setting(cli, zset TSRMLS_CC); + } + if (swClient_enable_ssl_encrypt(cli) < 0) + { + RETURN_FALSE; + } + if (cli->async) + { + zval *zcallback; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &zcallback) == FAILURE) + { + return; + } +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + char *func_name = NULL; + zend_fcall_info_cache func_cache; + if (!sw_zend_is_callable_ex(zcallback, NULL, 0, &func_name, NULL, &func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#elif defined(PHP_SWOOLE_CHECK_CALLBACK) + char *func_name = NULL; + if (!sw_zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + + client_callback *cb = (client_callback *) swoole_get_property(getThis(), client_property_callback); + if (!cb) + { + swoole_php_fatal_error(E_WARNING, "the object is not an instance of swoole_client."); + RETURN_FALSE; + } + zend_update_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onSSLReady"), zcallback TSRMLS_CC); + cb->onSSLReady = sw_zend_read_property(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("onSSLReady"), 0 TSRMLS_CC); + sw_copy_to_stack(cb->onSSLReady, cb->_onSSLReady); +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + cb->cache_onSSLReady = func_cache; +#endif + cli->ssl_wait_handshake = 1; + cli->socket->ssl_state = SW_SSL_STATE_WAIT_STREAM; + + SwooleG.main_reactor->set(SwooleG.main_reactor, cli->socket->fd, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE); + } + else + { + if (swClient_ssl_handshake(cli) < 0) + { + RETURN_FALSE; + } + } + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client, getPeerCert) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + if (!cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL is not ready."); + RETURN_FALSE; + } + char buf[8192]; + int n = swSSL_get_client_certificate(cli->socket->ssl, buf, sizeof(buf)); + if (n < 0) + { + RETURN_FALSE; + } + SW_RETURN_STRINGL(buf, n, 1); +} + +static PHP_METHOD(swoole_client, verifyPeerCert) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + if (!cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL is not ready."); + RETURN_FALSE; + } + zend_bool allow_self_signed = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_self_signed) == FAILURE) + { + return; + } + SW_CHECK_RETURN(swClient_ssl_verify(cli, allow_self_signed)); +} +#endif + +static PHP_METHOD(swoole_client, pipe) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + zval *write_socket; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &write_socket) == FAILURE) + { + return; + } + + int fd; + int flags = 0; + + //server session id + if (SW_Z_TYPE_P(write_socket) == IS_LONG) + { + fd = Z_LVAL_P(write_socket); + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (conn == NULL) + { + RETURN_FALSE; + } + flags = SW_CLIENT_PIPE_TCP_SESSION; + } + else + { + fd = swoole_convert_to_fd(write_socket TSRMLS_CC); + if (fd < 0) + { + RETURN_FALSE; + } + } + SW_CHECK_RETURN(cli->pipe(cli, fd, flags)); +} + +static PHP_METHOD(swoole_client, shutdown) +{ + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + long __how; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &__how) == FAILURE) + { + return; + } + SW_CHECK_RETURN(swClient_shutdown(cli, __how)); +} + +PHP_FUNCTION(swoole_client_select) +{ +#ifdef PHP_SWOOLE_CLIENT_USE_POLL + zval *r_array, *w_array, *e_array; + int retval, index = 0; + double timeout = 0.5; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!|d", &r_array, &w_array, &e_array, &timeout) == FAILURE) + { + return; + } + + int maxevents = MAX(MAX(php_swoole_array_length(r_array), php_swoole_array_length(w_array)), + php_swoole_array_length(e_array)); + struct pollfd *fds = (struct pollfd *) ecalloc(maxevents, sizeof(struct pollfd)); + + if (r_array != NULL && php_swoole_array_length(r_array) > 0) + { + index = client_poll_add(r_array, index, fds, maxevents, POLLIN); + } + if (w_array != NULL && php_swoole_array_length(w_array) > 0) + { + index = client_poll_add(w_array, index, fds, maxevents, POLLOUT); + } + if (e_array != NULL && php_swoole_array_length(w_array) > 0) + { + index = client_poll_add(e_array, index, fds, maxevents, POLLHUP); + } + if (index == 0) + { + efree(fds); + swoole_php_fatal_error(E_WARNING, "no resource arrays were passed to select"); + RETURN_FALSE; + } + + retval = poll(fds, maxevents, (int) timeout * 1000); + if (retval == -1) + { + efree(fds); + swoole_php_fatal_error(E_WARNING, "unable to poll(). Error: %s [%d]", strerror(errno), errno); + RETURN_FALSE; + } + + if (r_array != NULL && php_swoole_array_length(r_array) > 0) + { + client_poll_wait(r_array, fds, maxevents, retval, POLLIN); + } + if (w_array != NULL && php_swoole_array_length(w_array) > 0) + { + client_poll_wait(w_array, fds, maxevents, retval, POLLOUT); + } + if (e_array != NULL && php_swoole_array_length(e_array) > 0) + { + client_poll_wait(e_array, fds, maxevents, retval, POLLHUP); + } + efree(fds); + RETURN_LONG(retval); +#else + zval *r_array, *w_array, *e_array; + fd_set rfds, wfds, efds; + + int max_fd = 0; + int retval, sets = 0; + double timeout = 0.5; + struct timeval timeo; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!a!a!|d", &r_array, &w_array, &e_array, &timeout) == FAILURE) + { + return; + } + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + if (r_array != NULL) sets += client_select_add(r_array, &rfds, &max_fd TSRMLS_CC); + if (w_array != NULL) sets += client_select_add(w_array, &wfds, &max_fd TSRMLS_CC); + if (e_array != NULL) sets += client_select_add(e_array, &efds, &max_fd TSRMLS_CC); + + if (!sets) + { + swoole_php_fatal_error(E_WARNING, "no resource arrays were passed to select"); + RETURN_FALSE; + } + + if (max_fd >= FD_SETSIZE) + { + swoole_php_fatal_error(E_WARNING, "select max_fd > FD_SETSIZE[%d]", FD_SETSIZE); + RETURN_FALSE; + } + timeo.tv_sec = (int) timeout; + timeo.tv_usec = (int) ((timeout - timeo.tv_sec) * 1000 * 1000); + + retval = select(max_fd + 1, &rfds, &wfds, &efds, &timeo); + if (retval == -1) + { + swoole_php_fatal_error(E_WARNING, "unable to select. Error: %s [%d]", strerror(errno), errno); + RETURN_FALSE; + } + if (r_array != NULL) + { + client_select_wait(r_array, &rfds TSRMLS_CC); + } + if (w_array != NULL) + { + client_select_wait(w_array, &wfds TSRMLS_CC); + } + if (e_array != NULL) + { + client_select_wait(e_array, &efds TSRMLS_CC); + } + RETURN_LONG(retval); +#endif +} + +#ifdef PHP_SWOOLE_CLIENT_USE_POLL +static inline int client_poll_get(struct pollfd *fds, int maxevents, int fd) +{ + int i; + for (i = 0; i < maxevents; i++) + { + if (fds[i].fd == fd) + { + return i; + } + } + return -1; +} + +static int client_poll_wait(zval *sock_array, struct pollfd *fds, int maxevents, int n_event, int revent) +{ + zval *element = NULL; + int sock; + + ulong_t num = 0; + if (SW_Z_TYPE_P(sock_array) != IS_ARRAY) + { + return 0; + } + + zval new_array; + array_init(&new_array); + zend_ulong num_key; + zend_string *key; + zval *dest_element; + int poll_key; + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(sock_array), num_key, key, element) + { + sock = swoole_convert_to_fd(element TSRMLS_CC); + if (sock < 0) + { + continue; + } + poll_key = client_poll_get(fds, maxevents, sock); + if (poll_key == -1) + { + swoole_php_fatal_error(E_WARNING, "bad fd[%d]", sock); + continue; + } + if (!(fds[poll_key].revents & revent)) + { + continue; + } + if (key) + { + dest_element = zend_hash_add(Z_ARRVAL(new_array), key, element); + } + else + { + dest_element = zend_hash_index_update(Z_ARRVAL(new_array), num_key, element); + } + if (dest_element) + { + Z_ADDREF_P(dest_element); + } + num++; + } ZEND_HASH_FOREACH_END(); + + zval_ptr_dtor(sock_array); + ZVAL_COPY_VALUE(sock_array, &new_array); + return num ? 1 : 0; +} + +static int client_poll_add(zval *sock_array, int index, struct pollfd *fds, int maxevents, int event) +{ + zval *element = NULL; + if (SW_Z_TYPE_P(sock_array) != IS_ARRAY) + { + return -1; + } + + int sock; + int key = -1; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(sock_array), element) + sock = swoole_convert_to_fd(element TSRMLS_CC); + if (sock < 0) + { + continue; + } + if (event != POLLIN) + { + key = client_poll_get(fds, maxevents, sock); + } + if (key < 0) + { + fds[index].fd = sock; + fds[index].events = event; + index++; + } + else + { + fds[key].fd = sock; + fds[key].events |= event; + } + SW_HASHTABLE_FOREACH_END(); + + return index; +} +#else +static int client_select_wait(zval *sock_array, fd_set *fds TSRMLS_DC) +{ + zval *element = NULL; + int sock; + + ulong_t num = 0; + if (SW_Z_TYPE_P(sock_array) != IS_ARRAY) + { + return 0; + } + +#if PHP_MAJOR_VERSION < 7 + HashTable *new_hash; + char *key = NULL; + zval **dest_element = NULL; + uint32_t key_len; + + ALLOC_HASHTABLE(new_hash); + zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(sock_array)), NULL, ZVAL_PTR_DTOR, 0); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(sock_array), element) + sock = swoole_convert_to_fd(element TSRMLS_CC); + if (sock < 0) + { + continue; + } + if ((sock < FD_SETSIZE) && FD_ISSET(sock, fds)) + { + switch (sw_zend_hash_get_current_key(Z_ARRVAL_P(sock_array), &key, &key_len, &num)) + { + case HASH_KEY_IS_STRING: + sw_zend_hash_add(new_hash, key, key_len, (void * ) &element, sizeof(zval *), (void ** )&dest_element); + break; + case HASH_KEY_IS_LONG: + sw_zend_hash_index_update(new_hash, num, (void * ) &element, sizeof(zval *), (void ** )&dest_element); + break; + } + if (dest_element) + { + sw_zval_add_ref(dest_element); + } + } + num ++; + SW_HASHTABLE_FOREACH_END(); + + zend_hash_destroy(Z_ARRVAL_P(sock_array)); + efree(Z_ARRVAL_P(sock_array)); + + zend_hash_internal_pointer_reset(new_hash); + Z_ARRVAL_P(sock_array) = new_hash; +#else + zval new_array; + array_init(&new_array); + zend_ulong num_key; + zend_string *key; + zval *dest_element; + + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(sock_array), num_key, key, element) + { + sock = swoole_convert_to_fd(element TSRMLS_CC); + if (sock < 0) + { + continue; + } + if ((sock < FD_SETSIZE) && FD_ISSET(sock, fds)) + { + if (key) + { + dest_element = zend_hash_add(Z_ARRVAL(new_array), key, element); + } + else + { + dest_element = zend_hash_index_update(Z_ARRVAL(new_array), num_key, element); + } + if (dest_element) + { + Z_ADDREF_P(dest_element); + } + } + num++; + } ZEND_HASH_FOREACH_END(); + + zval_ptr_dtor(sock_array); + ZVAL_COPY_VALUE(sock_array, &new_array); +#endif + return num ? 1 : 0; +} + +static int client_select_add(zval *sock_array, fd_set *fds, int *max_fd TSRMLS_DC) +{ + zval *element = NULL; + if (SW_Z_TYPE_P(sock_array) != IS_ARRAY) + { + return 0; + } + + int sock; + int num = 0; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(sock_array), element) + sock = swoole_convert_to_fd(element TSRMLS_CC); + if (sock < 0) + { + continue; + } + if (sock < FD_SETSIZE) + { + FD_SET(sock, fds); + } + else + { + swoole_php_fatal_error(E_WARNING, "socket[%d] > FD_SETSIZE[%d].", sock, FD_SETSIZE); + continue; + } + if (sock > *max_fd) + { + *max_fd = sock; + } + num ++; + SW_HASHTABLE_FOREACH_END(); + + return num ? 1 : 0; +} +#endif + diff --git a/vendor/swoole/swoole_client_coro.c b/vendor/swoole/swoole_client_coro.c new file mode 100755 index 0000000..b235271 --- /dev/null +++ b/vendor/swoole/swoole_client_coro.c @@ -0,0 +1,1251 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "socks5.h" + +#ifdef SW_COROUTINE + +#include "swoole_coroutine.h" +#include "ext/standard/basic_functions.h" +#include <setjmp.h> + +enum client_property +{ + client_coro_property_context = 0, + client_coro_property_coroutine = 1, + client_coro_property_socket = 2, +}; + +typedef enum +{ + SW_CLIENT_CORO_STATUS_CLOSED, + SW_CLIENT_CORO_STATUS_READY, + SW_CLIENT_CORO_STATUS_WAIT, + SW_CLIENT_CORO_STATUS_DONE +} swoole_client_coro_io_status; + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + zval _object; +#endif + swoole_client_coro_io_status iowait; + swTimer_node *timer; + swString *result; + swLinkedList *message_queue; + int send_yield; + int cid; +} swoole_client_coro_property; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_construct, 0, 0, 1) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_connect, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_recv, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_send, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, flag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_peek, 0, 0, 0) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_sendfile, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_client_coro_sendto, 0, 0, 3) + ZEND_ARG_INFO(0, ip) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +static PHP_METHOD(swoole_client_coro, __construct); +static PHP_METHOD(swoole_client_coro, __destruct); +static PHP_METHOD(swoole_client_coro, set); +static PHP_METHOD(swoole_client_coro, connect); +static PHP_METHOD(swoole_client_coro, recv); +static PHP_METHOD(swoole_client_coro, peek); +static PHP_METHOD(swoole_client_coro, send); +static PHP_METHOD(swoole_client_coro, sendfile); +static PHP_METHOD(swoole_client_coro, sendto); +#ifdef SW_USE_OPENSSL +static PHP_METHOD(swoole_client_coro, enableSSL); +static PHP_METHOD(swoole_client_coro, getPeerCert); +static PHP_METHOD(swoole_client_coro, verifyPeerCert); +#endif +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_client_coro, getSocket); +#endif +static PHP_METHOD(swoole_client_coro, isConnected); +static PHP_METHOD(swoole_client_coro, getsockname); +static PHP_METHOD(swoole_client_coro, getpeername); +static PHP_METHOD(swoole_client_coro, close); + +static void client_onConnect(swClient *cli); +static void client_onReceive(swClient *cli, char *data, uint32_t length); +static void client_onClose(swClient *cli); +static void client_onError(swClient *cli); +static void client_coro_onTimeout(swTimer *timer, swTimer_node *tnode); +static void client_onSendTimeout(swTimer *timer, swTimer_node *tnode); + +static const zend_function_entry swoole_client_coro_methods[] = +{ + PHP_ME(swoole_client_coro, __construct, arginfo_swoole_client_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_client_coro, __destruct, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_client_coro, set, arginfo_swoole_client_coro_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, connect, arginfo_swoole_client_coro_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, recv, arginfo_swoole_client_coro_recv, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, peek, arginfo_swoole_client_coro_peek, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, send, arginfo_swoole_client_coro_send, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, sendfile, arginfo_swoole_client_coro_sendfile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, sendto, arginfo_swoole_client_coro_sendto, ZEND_ACC_PUBLIC) +#ifdef SW_USE_OPENSSL + PHP_ME(swoole_client_coro, enableSSL, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, getPeerCert, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, verifyPeerCert, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_client_coro, isConnected, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, getsockname, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, getpeername, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_client_coro, close, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) +#ifdef SWOOLE_SOCKETS_SUPPORT + PHP_ME(swoole_client_coro, getSocket, arginfo_swoole_client_coro_void, ZEND_ACC_PUBLIC) +#endif + PHP_FE_END +}; + +zend_class_entry swoole_client_coro_ce; +zend_class_entry *swoole_client_coro_class_entry_ptr; + +static sw_inline swClient* client_coro_get_ptr(zval *zobject TSRMLS_DC) +{ + swClient *cli = swoole_get_object(zobject); + if (cli && cli->socket && cli->socket->active == 1) + { + return cli; + } + else + { + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION; + zend_update_property_long(swoole_client_coro_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + swoole_php_error(E_WARNING, "client is not connected to server."); + return NULL; + } +} + +static void client_execute_callback(zval *zobject, enum php_swoole_client_callback_type type) +{ + zval *retval = NULL; + zval *result = NULL; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + swoole_client_coro_property *ccp = swoole_get_property(zobject, 1); + if (type == SW_CLIENT_CB_onConnect +#ifdef SW_USE_OPENSSL + || type == SW_CLIENT_CB_onSSLReady +#endif + ) + { + zval *type = sw_zend_read_property(swoole_client_coro_class_entry_ptr, zobject, ZEND_STRL("type"), 1 TSRMLS_CC); + int client_type = php_swoole_socktype(Z_LVAL_P(type)); + if (client_type == SW_SOCK_UNIX_DGRAM || client_type == SW_SOCK_UDP || client_type == SW_SOCK_UDP6) + { + return; + } + ccp->iowait = SW_CLIENT_CORO_STATUS_READY; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 1); + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + return; + } + + if (type == SW_CLIENT_CB_onError || (type == SW_CLIENT_CB_onClose && ccp->iowait == SW_CLIENT_CORO_STATUS_WAIT)) + { + if (ccp->timer) + { + swTimer_del(&SwooleG.timer, ccp->timer); + ccp->timer = NULL; + } + if (ccp->send_yield) + { + ccp->send_yield = 0; + } + SwooleG.error = type == SW_CLIENT_CB_onClose ? ECONNRESET : errno; + zend_update_property_long(swoole_client_coro_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + ccp->iowait = SW_CLIENT_CORO_STATUS_READY; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 0); + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + return; + } +} + +static void client_send_yield(swClient *cli, char *data, size_t length, zval *return_value) +{ + swoole_client_coro_property *ccp = swoole_get_property((zval *) cli->object, client_coro_property_coroutine); + ccp->iowait = SW_CLIENT_CORO_STATUS_WAIT; + ccp->cid = sw_get_current_cid(); + ccp->send_yield = 1; + if (cli->timeout > 0) + { + php_swoole_check_timer((int) (cli->timeout * 1000)); + ccp->timer = SwooleG.timer.add(&SwooleG.timer, (int) (cli->timeout * 1000), 0, cli, client_onSendTimeout); + } + + php_context *context = swoole_get_property((zval *) cli->object, client_coro_property_context); + context->coro_params.value.ptr = data; + context->private_data = (void*) length; + coro_save(context); + coro_yield(); +} + +void swoole_client_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_client_coro_ce, "Swoole\\Coroutine\\Client", swoole_client_coro_methods); + swoole_client_coro_class_entry_ptr = zend_register_internal_class(&swoole_client_coro_ce TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Client", swoole_client_coro_class_entry_ptr); + } + + zend_declare_property_long(swoole_client_coro_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_coro_class_entry_ptr, SW_STRL("sock")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_client_coro_class_entry_ptr, SW_STRL("reuse")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_coro_class_entry_ptr, SW_STRL("reuseCount")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_client_coro_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_coro_class_entry_ptr, ZEND_STRL("id"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_client_coro_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_client_coro_class_entry_ptr, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_class_constant_long(swoole_client_coro_class_entry_ptr, ZEND_STRL("MSG_OOB"), MSG_OOB TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_coro_class_entry_ptr, ZEND_STRL("MSG_PEEK"), MSG_PEEK TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_coro_class_entry_ptr, ZEND_STRL("MSG_DONTWAIT"), MSG_DONTWAIT TSRMLS_CC); + zend_declare_class_constant_long(swoole_client_coro_class_entry_ptr, ZEND_STRL("MSG_WAITALL"), MSG_WAITALL TSRMLS_CC); +} + +static void client_coro_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + php_context *ctx = (php_context *) tnode->data; + zval *zdata = NULL; + zval *retval = NULL; + +#if PHP_MAJOR_VERSION < 7 + zval *zobject = (zval *)ctx->coro_params; +#else + zval _zobject = ctx->coro_params; + zval *zobject = & _zobject; +#endif + zend_update_property_long(swoole_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + + swoole_client_coro_property *ccp = swoole_get_property(zobject, 1); + if (ccp) + { + ccp->timer = NULL; + ccp->iowait = SW_CLIENT_CORO_STATUS_READY; + } + + swClient *cli = swoole_get_object(zobject); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "client is not connected to server."); + return; + } + + SW_MAKE_STD_ZVAL(zdata); + ZVAL_BOOL(zdata, 0); + int ret = coro_resume(ctx, zdata, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); +} + +static void client_onBufferEmpty(swClient *cli) +{ + zval *zobject = (zval *) cli->object; + + swoole_client_coro_property *ccp = swoole_get_property(zobject, 1); + ccp->send_yield = 0; + if (ccp->timer) + { + swTimer_del(&SwooleG.timer, ccp->timer); + ccp->timer = NULL; + } + + php_context *context = swoole_get_property(zobject, client_coro_property_context); + char *data = context->coro_params.value.ptr; + size_t length = (size_t) context->private_data; + zval result; + zval *retval = NULL; + + ZVAL_BOOL(&result, cli->send(cli, data, length, 0) > 0); + + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void client_onSendTimeout(swTimer *timer, swTimer_node *tnode) +{ + swClient *cli = tnode->data; + zval result; + zval *retval = NULL; + zval *zobject = (zval *) cli->object; + + ZVAL_BOOL(&result, 0); + + swoole_client_coro_property *ccp = swoole_get_property(zobject, 1); + ccp->send_yield = 0; + ccp->timer = NULL; + + SwooleG.error = EAGAIN; + zend_update_property_long(swoole_client_coro_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + + php_context *context = swoole_get_property(zobject, client_coro_property_context); + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void client_onReceive(swClient *cli, char *data, uint32_t length) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = cli->object; + + swoole_client_coro_property *ccp = swoole_get_property(zobject, 1); + if (ccp->timer) + { + swTimer_del(&SwooleG.timer, ccp->timer); + ccp->timer = NULL; + } + + if (ccp->iowait == SW_CLIENT_CORO_STATUS_WAIT) + { + ccp->iowait = SW_CLIENT_CORO_STATUS_READY; + + zval *retval = NULL; + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, data, length, 1); + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, zdata, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); + } + else if (cli->open_eof_check || cli->open_length_check) + { + if (ccp->message_queue == NULL) + { + ccp->message_queue = swLinkedList_new(16, (swDestructor) sw_zval_free); + } + zval *zdata; + SW_ALLOC_INIT_ZVAL(zdata); + ZVAL_STRINGL(zdata, data, length); + if (swLinkedList_append(ccp->message_queue, zdata) < 0) + { + return; + } + swDebug("append to message_queue, sock=%d.", cli->socket->fd); + cli->remove_delay = 1; + ccp->iowait = SW_CLIENT_CORO_STATUS_DONE; + } + else + { + if (ccp->result) + { + if (swString_append_ptr(ccp->result, data, length) == SW_ERR) + { + swWarn("failed to append package."); + } + if (swString_length(ccp->result) >= cli->buffer_input_size) + { + swClient_sleep(cli); + } + } + else + { + ccp->result = swString_dup(data, length); + if (ccp->result) + { + ccp->iowait = SW_CLIENT_CORO_STATUS_DONE; + } + if (length >= cli->buffer_input_size && cli->sleep == 0) + { + swClient_sleep(cli); + } + } + } +} + +static void client_onConnect(swClient *cli) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = cli->object; + zend_update_property_bool(swoole_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 1 TSRMLS_CC); +#ifdef SW_USE_OPENSSL + if (cli->ssl_wait_handshake) + { + client_execute_callback(zobject, SW_CLIENT_CB_onSSLReady); + } + else +#endif + { + client_execute_callback(zobject, SW_CLIENT_CB_onConnect); + } +} + +static void client_onClose(swClient *cli) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = cli->object; + zend_update_property_bool(swoole_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + if (cli->released) + { + return; + } + + swDebug("client onClose"); + + php_swoole_client_free(zobject, cli TSRMLS_CC); + client_execute_callback(zobject, SW_CLIENT_CB_onClose); +} + +static void client_onError(swClient *cli) +{ + SWOOLE_GET_TSRMLS; + zval *zobject = cli->object; + zend_update_property_long(swoole_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); + if (cli->released) + { + return; + } + php_swoole_client_free(zobject, cli TSRMLS_CC); + client_execute_callback(zobject, SW_CLIENT_CB_onError); +} + +swClient* php_swoole_client_coro_new(zval *object, char *host, int host_len, int port) +{ + zval *ztype; + int async = 0; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + ztype = sw_zend_read_property(swoole_client_coro_class_entry_ptr, object, SW_STRL("type")-1, 0 TSRMLS_CC); + + if (ztype == NULL || ZVAL_IS_NULL(ztype)) + { + swoole_php_fatal_error(E_ERROR, "get swoole_client_coro->type failed."); + return NULL; + } + + long type = Z_LVAL_P(ztype); + + //new flag, swoole-1.6.12+ + if (type & SW_FLAG_ASYNC) + { + async = 1; + } + + php_swoole_check_reactor(); + + swClient *cli; + cli = (swClient*) emalloc(sizeof(swClient)); + + if (swClient_create(cli, php_swoole_socktype(type), async) < 0) + { + swoole_php_fatal_error(E_WARNING, "swClient_create() failed. Error: %s [%d]", strerror(errno), errno); + zend_update_property_long(swoole_client_coro_class_entry_ptr, object, ZEND_STRL("errCode"), + SwooleG.error ? SwooleG.error : errno TSRMLS_CC); + return NULL; + } + + zend_update_property_long(swoole_client_coro_class_entry_ptr, object, ZEND_STRL("sock"), cli->socket->fd TSRMLS_CC); + +#ifdef SW_USE_OPENSSL + if (type & SW_SOCK_SSL) + { + cli->open_ssl = 1; + } +#endif + + return cli; +} + +static PHP_METHOD(swoole_client_coro, __construct) +{ + coro_check(TSRMLS_C); + + long async = 1; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &type) == FAILURE) + { + swoole_php_fatal_error(E_ERROR, "require socket type param."); + RETURN_FALSE; + } + + if (async == 1) + { + type |= SW_FLAG_ASYNC; + } + + //不支持长连 + int client_type = php_swoole_socktype(type); + if (client_type < SW_SOCK_TCP || client_type > SW_SOCK_UNIX_STREAM) + { + swoole_php_fatal_error(E_ERROR, "Unknown client type '%d'.", client_type); + } + + zend_update_property_long(swoole_client_coro_class_entry_ptr, getThis(), ZEND_STRL("type"), type TSRMLS_CC); + //init + swoole_set_object(getThis(), NULL); + + swoole_client_coro_property *client_coro_property = emalloc(sizeof(swoole_client_coro_property)); + bzero(client_coro_property, sizeof(swoole_client_coro_property)); + client_coro_property->iowait = SW_CLIENT_CORO_STATUS_CLOSED; + swoole_set_property(getThis(), client_coro_property_coroutine, client_coro_property); + + php_context *sw_current_context = emalloc(sizeof(php_context)); + sw_current_context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = getThis(); +#else + sw_current_context->coro_params = *getThis(); +#endif + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; + swoole_set_property(getThis(), client_coro_property_context, sw_current_context); +#ifdef SWOOLE_SOCKETS_SUPPORT + swoole_set_property(getThis(), client_coro_property_socket, NULL); +#endif + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client_coro, __destruct) +{ + swClient *cli = swoole_get_object(getThis()); + //no keep connection + if (cli) + { + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_client_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + if (sw_current_context) + { + efree(sw_current_context); + swoole_set_property(getThis(), 0, NULL); + } + swoole_client_coro_property *ccp = swoole_get_property(getThis(), 1); + if (ccp) + { + if (ccp->result) + { + swString_free(ccp->result); + } + if (ccp->message_queue) + { + swLinkedList_free(ccp->message_queue); + } + if (ccp->timer) + { + swTimer_del(&SwooleG.timer, ccp->timer); + } + efree(ccp); + swoole_set_property(getThis(), 1, NULL); + } +} + +static PHP_METHOD(swoole_client_coro, set) +{ + zval *zset; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + zend_update_property(swoole_client_coro_class_entry_ptr, getThis(), ZEND_STRL("setting"), zset TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_client_coro, connect) +{ + long port = 0, sock_flag = 0; + char *host = NULL; + zend_size_t host_len; + double timeout = SW_CLIENT_DEFAULT_TIMEOUT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ld", &host, &host_len, &port, &timeout) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "The host is empty."); + RETURN_FALSE; + } + + swClient *cli = swoole_get_object(getThis()); + if (cli) + { + swoole_php_fatal_error(E_WARNING, "The client is already connected server."); + RETURN_FALSE; + } + + cli = php_swoole_client_coro_new(getThis(), host, host_len, port); + if (cli == NULL) + { + RETURN_FALSE; + } + + swoole_set_object(getThis(), cli); + + if (cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_TCP6) + { + if (port <= 0 || port > SW_CLIENT_MAX_PORT) + { + swoole_php_fatal_error(E_WARNING, "The port is invalid."); + RETURN_FALSE; + } + if (cli->async == 1) + { + //for tcp: nonblock + //for udp: have udp connect + sock_flag = 1; + } + } + + if (cli->socket->active == 1) + { + swoole_php_fatal_error(E_WARNING, "swoole_client_coro is already connected."); + RETURN_FALSE; + } + + zval *zset = sw_zend_read_property(swoole_client_coro_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + php_swoole_client_check_setting(cli, zset TSRMLS_CC); + } + + if (swSocket_is_stream(cli->type)) + { + cli->onConnect = client_onConnect; + cli->onClose = client_onClose; + cli->onError = client_onError; + cli->onReceive = client_onReceive; + cli->onBufferEmpty = client_onBufferEmpty; + + cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; + } + else + { + cli->onConnect = client_onConnect; + cli->onReceive = client_onReceive; + cli->reactor_fdtype = PHP_SWOOLE_FD_DGRAM_CLIENT; + } + + zval *zobject = getThis(); + cli->object = zobject; +#if PHP_MAJOR_VERSION >= 7 + swoole_client_coro_property *ccp = swoole_get_property(getThis(), 1); + sw_copy_to_stack(cli->object, ccp->_object); +#endif + + cli->timeout = timeout; + //nonblock async + if (cli->connect(cli, host, port, timeout, sock_flag) < 0) + { + zend_update_property_long(swoole_client_coro_class_entry_ptr, getThis(), SW_STRL("errCode")-1, + SwooleG.error ? SwooleG.error : errno TSRMLS_CC); + swoole_php_sys_error(E_WARNING, "connect to server[%s:%d] failed.", host, (int )port); + RETURN_FALSE; + } + + if (cli->type == SW_SOCK_UNIX_DGRAM || cli->type == SW_SOCK_UDP6 || cli->type == SW_SOCK_UDP) + { + RETURN_TRUE; + } + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + coro_save(sw_current_context); + coro_yield(); +} + +static PHP_METHOD(swoole_client_coro, send) +{ + char *data; + zend_size_t data_len; + long flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &flags) == FAILURE) + { + return; + } + + if (data_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "data is empty."); + RETURN_FALSE; + } + + swClient *cli = client_coro_get_ptr(getThis()); + if (!cli) + { + RETURN_FALSE; + } + + //clear errno + SwooleG.error = 0; + int ret = cli->send(cli, data, data_len, flags); + if (ret < 0) + { + if (SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW) + { + client_send_yield(cli, data, data_len, return_value); + return; + } + SwooleG.error = errno; + swoole_php_sys_error(E_WARNING, "send(%d) %d bytes failed.", cli->socket->fd, data_len); + zend_update_property_long(swoole_client_coro_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + RETURN_FALSE; + } + else + { + RETURN_LONG(ret); + } +} + +static PHP_METHOD(swoole_client_coro, sendto) +{ + char* ip; + zend_size_t ip_len; + long port; + char *data; + zend_size_t len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &ip, &ip_len, &port, &data, &len) == FAILURE) + { + return; + } + + if (len <= 0) + { + swoole_php_error(E_WARNING, "data is empty."); + RETURN_FALSE; + } + + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + cli = php_swoole_client_new(getThis(), ip, ip_len, port); + if (cli == NULL) + { + RETURN_FALSE; + } + cli->socket->active = 1; + swoole_set_object(getThis(), cli); + } + + int ret; + if (cli->type == SW_SOCK_UDP) + { + ret = swSocket_udp_sendto(cli->socket->fd, ip, port, data, len); + } + else if (cli->type == SW_SOCK_UDP6) + { + ret = swSocket_udp_sendto6(cli->socket->fd, ip, port, data, len); + } + else + { + swoole_php_fatal_error(E_WARNING, "only support SWOOLE_SOCK_UDP or SWOOLE_SOCK_UDP6."); + RETURN_FALSE; + } + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_client_coro, sendfile) +{ + char *file; + zend_size_t file_len; + long offset = 0; + long length = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &file, &file_len, &offset) == FAILURE) + { + return; + } + if (file_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "file is empty."); + RETURN_FALSE; + } + + swClient *cli = client_coro_get_ptr(getThis()); + if (!cli) + { + RETURN_FALSE; + } + if (!(cli->type == SW_SOCK_TCP || cli->type == SW_SOCK_TCP6 || cli->type == SW_SOCK_UNIX_STREAM)) + { + swoole_php_error(E_WARNING, "dgram socket cannot use sendfile."); + RETURN_FALSE; + } + //clear errno + SwooleG.error = 0; + int ret = cli->sendfile(cli, file, offset, length); + if (ret < 0) + { + SwooleG.error = errno; + swoole_php_fatal_error(E_WARNING, "sendfile() failed. Error: %s [%d]", strerror(SwooleG.error), SwooleG.error); + zend_update_property_long(swoole_client_coro_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + RETVAL_FALSE; + } + else + { + RETVAL_TRUE; + } +} + +static PHP_METHOD(swoole_client_coro, recv) +{ + swoole_client_coro_property *ccp = swoole_get_property(getThis(), client_coro_property_coroutine); + if (ccp->iowait == SW_CLIENT_CORO_STATUS_DONE) + { + ccp->iowait = SW_CLIENT_CORO_STATUS_READY; + zval *result; + if (ccp->message_queue) + { + swDebug("fetch from message_queue."); + result = swLinkedList_shift(ccp->message_queue); + if (result) + { + RETVAL_ZVAL(result, 0, 0); + efree(result); + return; + } + } + else + { + SW_MAKE_STD_ZVAL(result); + SW_ZVAL_STRINGL(result, ccp->result->str, ccp->result->length, 1); + swString_free(ccp->result); + ccp->result = NULL; + RETURN_ZVAL(result, 0, 1); + } + } + else if (ccp->iowait == SW_CLIENT_CORO_STATUS_WAIT && ccp->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + RETURN_FALSE; + } + + swClient *cli = client_coro_get_ptr(getThis()); + if (!cli) + { + RETURN_FALSE; + } + + double timeout = cli->timeout; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "|d", &timeout) == FAILURE) + { + return; + } + + if (cli->sleep) + { + swClient_wakeup(cli); + } + + php_context *context = swoole_get_property(getThis(), client_coro_property_context); + if (timeout > 0) + { + php_swoole_check_timer((int) (timeout * 1000)); + ccp->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, client_coro_onTimeout); + } + + swDebug("recv yield, sock=%d.", cli->socket->fd); + + ccp->iowait = SW_CLIENT_CORO_STATUS_WAIT; + coro_save(context); + ccp->cid = sw_get_current_cid(); + coro_yield(); +} + +static PHP_METHOD(swoole_client_coro, peek) +{ + zend_long buf_len = SW_PHP_CLIENT_BUFFER_SIZE; + int ret; + char *buf = NULL; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(buf_len) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &buf_len) == FAILURE) + { + return; + } +#endif + + swClient *cli = client_coro_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + + buf = emalloc(buf_len + 1); + SwooleG.error = 0; + ret = cli->recv(cli, buf, buf_len, MSG_PEEK | MSG_DONTWAIT); + + if (ret < 0) + { + SwooleG.error = errno; + swoole_php_error(E_WARNING, "recv() failed. Error: %s [%d]", strerror(SwooleG.error), SwooleG.error); + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), SW_STRL("errCode")-1, + SwooleG.error TSRMLS_CC); + swoole_efree(buf); + RETURN_FALSE; + } + else + { + buf[ret] = 0; + SW_RETVAL_STRINGL(buf, ret, 0); + } +} + +static PHP_METHOD(swoole_client_coro, isConnected) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli || !cli->socket || !cli->socket->active) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_client_coro, getsockname) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client_coro."); + RETURN_FALSE; + } + if (!cli->socket->active) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + + if (cli->type == SW_SOCK_UNIX_STREAM || cli->type == SW_SOCK_UNIX_DGRAM) + { + swoole_php_fatal_error(E_WARNING, "getsockname() only support AF_INET family socket."); + RETURN_FALSE; + } + + cli->socket->info.len = sizeof(cli->socket->info.addr); + if (getsockname(cli->socket->fd, (struct sockaddr*) &cli->socket->info.addr, &cli->socket->info.len) < 0) + { + swoole_php_sys_error(E_WARNING, "getsockname() failed."); + RETURN_FALSE; + } + + array_init(return_value); + if (cli->type == SW_SOCK_UDP6 || cli->type == SW_SOCK_TCP6) + { + add_assoc_long(return_value, "port", ntohs(cli->socket->info.addr.inet_v6.sin6_port)); + char tmp[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &cli->socket->info.addr.inet_v6.sin6_addr, tmp, sizeof(tmp))) + { + sw_add_assoc_string(return_value, "host", tmp, 1); + } + else + { + swoole_php_fatal_error(E_WARNING, "inet_ntop() failed."); + } + } + else + { + add_assoc_long(return_value, "port", ntohs(cli->socket->info.addr.inet_v4.sin_port)); + sw_add_assoc_string(return_value, "host", inet_ntoa(cli->socket->info.addr.inet_v4.sin_addr), 1); + } +} + +static PHP_METHOD(swoole_client_coro, getpeername) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client_coro."); + RETURN_FALSE; + } + + if (!cli->socket->active) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + + if (cli->type == SW_SOCK_UDP) + { + array_init(return_value); + add_assoc_long(return_value, "port", ntohs(cli->remote_addr.addr.inet_v4.sin_port)); + sw_add_assoc_string(return_value, "host", inet_ntoa(cli->remote_addr.addr.inet_v4.sin_addr), 1); + } + else if (cli->type == SW_SOCK_UDP6) + { + array_init(return_value); + add_assoc_long(return_value, "port", ntohs(cli->remote_addr.addr.inet_v6.sin6_port)); + char tmp[INET6_ADDRSTRLEN]; + + if (inet_ntop(AF_INET6, &cli->remote_addr.addr.inet_v6.sin6_addr, tmp, sizeof(tmp))) + { + sw_add_assoc_string(return_value, "host", tmp, 1); + } + else + { + swoole_php_fatal_error(E_WARNING, "inet_ntop() failed."); + } + } + else + { + swoole_php_fatal_error(E_WARNING, "only support SWOOLE_SOCK_UDP or SWOOLE_SOCK_UDP6."); + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_client_coro, close) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client_coro."); + RETURN_FALSE; + } + if (!cli->socket) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + if (cli->socket->active == 0) + { + cli->socket->removed = 1; + } + if (cli->socket->closed) + { + swoole_php_error(E_WARNING, "client socket is closed."); + RETURN_FALSE; + } + //Connection error, or short tcp connection. + swoole_client_coro_property *ccp = swoole_get_property(getThis(), 1); + ccp->iowait = SW_CLIENT_CORO_STATUS_CLOSED; + cli->released = 1; + php_swoole_client_free(getThis(), cli TSRMLS_CC); + + RETURN_TRUE; +} + +#ifdef SW_USE_OPENSSL +static PHP_METHOD(swoole_client_coro, enableSSL) +{ + swClient *cli = client_coro_get_ptr(getThis()); + if (!cli) + { + RETURN_FALSE; + } + if (cli->type != SW_SOCK_TCP && cli->type != SW_SOCK_TCP6) + { + swoole_php_fatal_error(E_WARNING, "cannot use enableSSL."); + RETURN_FALSE; + } + if (cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL has been enabled."); + RETURN_FALSE; + } + if (swClient_enable_ssl_encrypt(cli) < 0) + { + RETURN_FALSE; + } + cli->open_ssl = 1; + cli->ssl_wait_handshake = 1; + cli->socket->ssl_state = SW_SSL_STATE_WAIT_STREAM; + + SwooleG.main_reactor->set(SwooleG.main_reactor, cli->socket->fd, SW_FD_STREAM_CLIENT | SW_EVENT_WRITE); + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + coro_save(sw_current_context); + coro_yield(); +} + +static PHP_METHOD(swoole_client_coro, getPeerCert) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client_coro."); + RETURN_FALSE; + } + if (!cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL no ready."); + RETURN_FALSE; + } + char buf[8192]; + int n = swSSL_get_client_certificate(cli->socket->ssl, buf, sizeof(buf)); + if (n < 0) + { + RETURN_FALSE; + } + SW_RETURN_STRINGL(buf, n, 1); +} + +static PHP_METHOD(swoole_client_coro, verifyPeerCert) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client_coro."); + RETURN_FALSE; + } + if (!cli->socket->ssl) + { + swoole_php_fatal_error(E_WARNING, "SSL no ready."); + RETURN_FALSE; + } + zend_bool allow_self_signed = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_self_signed) == FAILURE) + { + return; + } + SW_CHECK_RETURN(swSSL_verify(cli->socket, allow_self_signed)); +} +#endif + + +#ifdef SWOOLE_SOCKETS_SUPPORT + +static sw_inline swClient* client_get_ptr(zval *zobject TSRMLS_DC) +{ + swClient *cli = swoole_get_object(zobject); + if (cli && cli->socket && cli->socket->active == 1) + { + return cli; + } + else + { + swoole_php_fatal_error(E_WARNING, "client is not connected to server."); + return NULL; + } +} + +static PHP_METHOD(swoole_client_coro, getSocket) +{ + zval *zsocket = swoole_get_property(getThis(), client_coro_property_socket); + if (zsocket) + { + RETURN_ZVAL(zsocket, 1, NULL); + } + swClient *cli = client_get_ptr(getThis() TSRMLS_CC); + if (!cli) + { + RETURN_FALSE; + } + if (cli->keep) + { + swoole_php_fatal_error(E_WARNING, "the 'getSocket' method can't be used on persistent connection."); + RETURN_FALSE; + } + php_socket *socket_object = swoole_convert_to_socket(cli->socket->fd); + if (!socket_object) + { + RETURN_FALSE; + } + SW_ZEND_REGISTER_RESOURCE(return_value, (void * ) socket_object, php_sockets_le_socket()); + zsocket = sw_zval_dup(return_value); + sw_zval_add_ref(&zsocket); + swoole_set_property(getThis(), client_coro_property_socket, zsocket); +} +#endif + +#endif diff --git a/vendor/swoole/swoole_config.h b/vendor/swoole/swoole_config.h new file mode 100755 index 0000000..657cc4b --- /dev/null +++ b/vendor/swoole/swoole_config.h @@ -0,0 +1,272 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ +#ifndef SWOOLE_CONFIG_H_ +#define SWOOLE_CONFIG_H_ + +#ifndef __clang__ +//gcc version check +#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) +#error "GCC 4.4 or later required." +#endif +#endif + +#define SW_COROUTINE 1 + +#define SW_MAX_FDTYPE 32 //32 kinds of event +#define SW_MAX_HOOK_TYPE 32 +#define SW_ERROR_MSG_SIZE 512 +#define SW_MAX_FILE_CONTENT (64*1024*1024) //for swoole_file_get_contents +#define SW_MAX_LISTEN_PORT 60000 +#define SW_MAX_CONCURRENT_TASK 1024 + +#ifdef HAVE_MALLOC_TRIM +#define SW_USE_MALLOC_TRIM +#endif + +#define SW_MALLOC_TRIM_INTERVAL 1 +#define SW_MALLOC_TRIM_PAD 0 +#define SW_USE_EVENT_TIMER +#define SW_USE_MONOTONIC_TIME +//#define SW_USE_RINGBUFFER + +//#define SW_USE_TIMEWHEEL +#define SW_TIMEWHEEL_SIZE 60 + +//#define SW_DEBUG_REMOTE_OPEN +#define SW_DEBUG_SERVER_HOST "127.0.0.1" +#define SW_DEBUG_SERVER_PORT 9999 + +#define SW_DEBUG_SERVER_DESTRUCT 0 + +#define SW_SOCKET_OVERFLOW_WAIT 100 +#define SW_SOCKET_MAX_DEFAULT 65536 +#define SW_SOCKET_BUFFER_SIZE (8*1024*1024) +#define SW_SYSTEMD_FDS_START 3 + +#define SW_GLOBAL_MEMORY_PAGESIZE (1024*1024*2) //全局内存的分页 + +#define SW_MAX_THREAD_NCPU 4 // n * cpu_num +#define SW_MAX_WORKER_NCPU 1000 // n * cpu_num +#define SW_MAX_REQUEST 5000 //最大请求包数 + +#define SW_CORO_SCHEDUER_TIMEOUT 100 //协程强制超时回调的单位时间 100ms +//#define SW_CONNECTION_LIST_EXPAND (4096*2) //动态扩容的数量 + +#define SW_HOST_MAXSIZE 104 // Linux has 108 UNIX_PATH_MAX, but BSD/MacOS limit is only 104 + +//#define SW_DEBUG //debug +#define SW_LOG_NO_SRCINFO //no source info +//#define SW_BUFFER_SIZE 65495 //65535 - 28 - 12(UDP最大包 - 包头 - 3个INT) +#define SW_CLIENT_BUFFER_SIZE 65536 +//#define SW_CLIENT_RECV_AGAIN +#define SW_CLIENT_DEFAULT_TIMEOUT 0.5 +#define SW_CLIENT_MAX_PORT 65535 +//#define SW_CLIENT_SOCKET_WAIT + +//!!!Don't modify.---------------------------------------------------------- +#if __MACH__ +#define SW_IPC_MAX_SIZE 2048 //MacOS +#else +#define SW_IPC_MAX_SIZE 8192 //for IPC, dgram and message-queue max size +#endif + +#ifdef SW_USE_RINGBUFFER +#define SW_BUFFER_SIZE 65535 +#else +#define SW_BUFFER_SIZE (SW_IPC_MAX_SIZE - sizeof(struct _swDataHead)) +#endif +//!!!End.------------------------------------------------------------------- + +#define SW_BUFFER_SIZE_STD 8192 +#define SW_BUFFER_SIZE_BIG 65536 +#define SW_BUFFER_SIZE_UDP 65536 +//#define SW_BUFFER_RECV_TIME +#define SW_SENDFILE_CHUNK_SIZE 65536 + +#define SW_SENDFILE_MAXLEN 4194304 + +#define SW_HASHMAP_KEY_MAXLEN 256 +#define SW_HASHMAP_INIT_BUCKET_N 32 //hashmap初始化时创建32大小的桶 + +#define SW_DATA_EOF "\r\n\r\n" +#define SW_DATA_EOF_MAXLEN 8 + +#define SW_TASKWAIT_TIMEOUT 0.5 + +#define SW_AIO_THREAD_NUM_DEFAULT 2 +#define SW_AIO_THREAD_NUM_MAX 32 +#define SW_AIO_MAX_FILESIZE 4194304 //4M +#define SW_AIO_EVENT_NUM 128 +#define SW_AIO_DEFAULT_CHUNK_SIZE 65536 +#define SW_AIO_MAX_CHUNK_SIZE 1*1024*1024 +//#define SW_AIO_THREAD_USE_CHANNEL +#define SW_AIO_MAX_EVENTS 128 +#define SW_AIO_HANDLER_MAX_SIZE 8 +//#define SW_THREADPOOL_USE_CHANNEL +#define SW_THREADPOOL_QUEUE_LEN 10000 +#define SW_IP_MAX_LENGTH 32 + +//#define SW_USE_SOCKET_LINGER + +#define SW_WORKER_WAIT_TIMEOUT 1000 +//#define SW_WORKER_RECV_AGAIN + +#define SW_WORKER_USE_SIGNALFD +#define SW_WORKER_MAX_WAIT_TIME 30 //最大等待时间 + +//#define SW_WORKER_SEND_CHUNK + +#define SW_REACTOR_SCHEDULE 2 +#define SW_REACTOR_MAXEVENTS 4096 +#define SW_REACTOR_USE_SESSION +#define SW_SESSION_LIST_SIZE (1024*1024) + +#define SW_MSGMAX 65536 + +/** + * 最大Reactor线程数量,默认会启动CPU核数的线程数 + * 如果超过8核,默认启动8个线程 + */ +#define SW_REACTOR_MAX_THREAD 8 + +/** + * 循环从管道中读取数据,有助于缓解管道缓存塞满问题,降低进程间通信的压力 + */ +#define SW_REACTOR_RECV_AGAIN +#define SW_REACTOR_SYNC_SEND //direct send + +#define SW_RINGQUEUE_LEN 1024 //RingQueue队列长度 + +//#define SW_USE_RINGQUEUE_TS 1 //使用线程安全版本的RingQueue +#define SW_RINGBUFFER_FREE_N_MAX 4 //when free_n > MAX, execute collect +#define SW_RINGBUFFER_WARNING 100 +//#define SW_RINGBUFFER_DEBUG + +/** + * ringbuffer memory pool size + */ +#define SW_BUFFER_OUTPUT_SIZE (1024*1024*2) +#define SW_BUFFER_INPUT_SIZE (1024*1024*2) +#define SW_BUFFER_MIN_SIZE 65536 +#define SW_PIPE_BUFFER_SIZE (1024*1024*32) + +#define SW_BACKLOG 512 + +/** + * 是否循环accept,可以一次性处理完全部的listen队列,用于大量并发连接的场景 + */ +#define SW_ACCEPT_AGAIN 1 + +/** + * 一次循环的最大accept次数 + */ +#define SW_ACCEPT_MAX_COUNT 64 + +#define SW_TCP_KEEPCOUNT 5 +#define SW_TCP_KEEPIDLE 3600 //1 hour +#define SW_TCP_KEEPINTERVAL 60 + +#define SW_USE_EVENTFD //是否使用eventfd来做消息通知,需要Linux 2.6.22以上版本才会支持 + +#define SW_TASK_TMP_FILE "/tmp/swoole.task.XXXXXX" +#define SW_TASK_TMPDIR_SIZE 128 + +#define SW_FILE_CHUNK_SIZE 65536 + +#define SW_TABLE_CONFLICT_PROPORTION 0.2 //20% +#define SW_TABLE_KEY_SIZE 64 +//#define SW_TABLE_USE_PHP_HASH +//#define SW_TABLE_DEBUG +#define SW_TABLE_USE_SPINLOCK 1 + +#define SW_SSL_BUFFER_SIZE 16384 +#define SW_SSL_CIPHER_LIST "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH" +#define SW_SSL_ECDH_CURVE "secp384r1" +#define SW_SSL_NPN_ADVERTISE "\x08http/1.1" +#define SW_SSL_HTTP2_NPN_ADVERTISE "\x02h2" + +#define SW_SPINLOCK_LOOP_N 1024 + +#define SW_STRING_BUFFER_MAXLEN (1024*1024*128) +#define SW_STRING_BUFFER_DEFAULT 128 +#define SW_STRING_BUFFER_GARBAGE_MIN (1024*64) +#define SW_STRING_BUFFER_GARBAGE_RATIO 4 + +#define SW_SIGNO_MAX 128 + +#define SW_DNS_HOST_BUFFER_SIZE 16 +#define SW_DNS_SERVER_PORT 53 +#define SW_DNS_DEFAULT_SERVER "8.8.8.8" + +/** + * HTTP Protocol + */ +#define SW_HTTP_SERVER_SOFTWARE "swoole-http-server" +#define SW_HTTP_BAD_REQUEST "<h1>400 Bad Request</h1>\r\n" +#define SW_HTTP_PARAM_MAX_NUM 128 +#define SW_HTTP_COOKIE_KEYLEN 128 +#define SW_HTTP_COOKIE_VALLEN 4096 +#define SW_HTTP_RESPONSE_INIT_SIZE 65536 +#define SW_HTTP_HEADER_MAX_SIZE 8192 +#define SW_HTTP_HEADER_KEY_SIZE 128 +#define SW_HTTP_HEADER_VALUE_SIZE 4096 +#define SW_HTTP_HEADER_BUFFER_SIZE 128 +#define SW_HTTP_COMPRESS_GZIP +#define SW_HTTP_UPLOAD_TMPDIR_SIZE 256 +#define SW_HTTP_DATE_FORMAT "D, d M Y H:i:s T" +#define SW_HTTP_RFC1123_DATE_GMT "%a, %d %b %Y %T GMT" +#define SW_HTTP_RFC1123_DATE_UTC "%a, %d %b %Y %T UTC" +#define SW_HTTP_RFC850_DATE "%A, %d-%b-%y %T GMT" +#define SW_HTTP_ASCTIME_DATE "%a %b %e %T %Y" +//#define SW_HTTP_100_CONTINUE + +/** + * HTTP2 Protocol + */ +#define SW_HTTP2_DATA_BUFFSER_SIZE 8192 +#define SW_HTTP2_MAX_CONCURRENT_STREAMS 128 +#define SW_HTTP2_MAX_FRAME_SIZE ((1u << 14)) +#define SW_HTTP2_MAX_WINDOW ((1u << 31) - 1) +#define SW_HTTP2_DEFAULT_WINDOW 65535 + +#define SW_HTTP_CLIENT_USERAGENT "swoole-http-client" +#define SW_HTTP_CLIENT_BOUNDARY_PREKEY "----SwooleBoundary" +#define SW_HTTP_FORM_DATA_FORMAT_STRING "--%*s\r\nContent-Disposition: form-data; name=\"%*s\"\r\n\r\n" +#define SW_HTTP_FORM_DATA_FORMAT_FILE "--%*s\r\nContent-Disposition: form-data; name=\"%*s\"; filename=\"%*s\"\r\nContent-Type: %*s\r\n\r\n" + +#define SW_WEBSOCKET_SERVER_SOFTWARE "swoole-websocket-server" +#define SW_WEBSOCKET_VERSION "13" +#define SW_WEBSOCKET_KEY_LENGTH 16 +#define SW_WEBSOCKET_QUEUE_SIZE 16 + +#define SW_MYSQL_QUERY_INIT_SIZE 8192 +#define SW_MYSQL_DEFAULT_PORT 3306 +#define SW_MYSQL_CONNECT_TIMEOUT 1.0 +#define SW_MYSQL_DEFAULT_CHARSET 33 //0x21, utf8_general_ci + +#define SW_REDIS_CONNECT_TIMEOUT 1.0 + +#define SW_TIMER_MAX_VALUE 86400000 + +/** + * Coroutine + */ +#define SW_DEFAULT_MAX_CORO_NUM 3000 +#define SW_DEFAULT_STACK_SIZE 8192 +#define SW_DEFAULT_C_STACK_SIZE (1024 * 1024 * 2) +#define SW_MAX_CORO_NUM_LIMIT 0x80000 + +#endif /* SWOOLE_CONFIG_H_ */ diff --git a/vendor/swoole/swoole_coroutine.cc b/vendor/swoole/swoole_coroutine.cc new file mode 100755 index 0000000..efdec96 --- /dev/null +++ b/vendor/swoole/swoole_coroutine.cc @@ -0,0 +1,351 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + | shiguangqi <shiguangqi2008@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "coroutine.h" +#include "swoole_coroutine.h" +#include "zend_vm.h" +#include "zend_closures.h" + +/* PHP 7.3 compatibility macro {{{*/ +#ifndef ZEND_CLOSURE_OBJECT +# define ZEND_CLOSURE_OBJECT(func) (zend_object*)func->op_array.prototype +#endif +#ifndef GC_ADDREF +# define GC_ADDREF(ref) ++GC_REFCOUNT(ref) +# define GC_DELREF(ref) --GC_REFCOUNT(ref) +#endif/*}}}*/ + +#define TASK_SLOT \ + ((int)((ZEND_MM_ALIGNED_SIZE(sizeof(coro_task)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval)))) +#define SWCC(x) sw_current_context->x + +coro_global COROG; +static coro_task* sw_get_current_task(); +static void sw_coro_func(void *); + +#if PHP_MAJOR_VERSION >= 7 && PHP_MINOR_VERSION >= 2 +static inline void sw_vm_stack_init(void) +{ + uint32_t size = COROG.stack_size; + zend_vm_stack page = (zend_vm_stack) emalloc(size); + + page->top = ZEND_VM_STACK_ELEMENTS(page); + page->end = (zval*) ((char*) page + size); + page->prev = NULL; + + EG(vm_stack) = page; + EG(vm_stack)->top++; + EG(vm_stack_top) = EG(vm_stack)->top; + EG(vm_stack_end) = EG(vm_stack)->end; +} +#else +#define sw_vm_stack_init zend_vm_stack_init +#endif + +int coro_init(TSRMLS_D) +{ + if (zend_get_module_started("xdebug") == SUCCESS) + { + swoole_php_fatal_error(E_ERROR, + "can not use xdebug in swoole coroutine, please remove xdebug in php.ini and retry."); + return 0; + } + COROG.origin_vm_stack = EG(vm_stack); + COROG.origin_vm_stack_top = EG(vm_stack_top); + COROG.origin_vm_stack_end = EG(vm_stack_end); + + COROG.coro_num = 0; + if (COROG.max_coro_num <= 0) + { + COROG.max_coro_num = DEFAULT_MAX_CORO_NUM; + } + if (COROG.stack_size <= 0) + { + COROG.stack_size = DEFAULT_STACK_SIZE; + } + + COROG.active = 1; + SwooleWG.coro_timeout_list = swLinkedList_new(1, NULL); + coroutine_set_close(sw_coro_close); + return 0; +} + + +void coro_check(TSRMLS_D) +{ + if (sw_get_current_cid() == -1) + { + swoole_php_fatal_error(E_ERROR, "must be called in the coroutine."); + } +} + +void coro_destroy(TSRMLS_D) +{ + if (COROG.chan_pipe) + { + COROG.chan_pipe->close(COROG.chan_pipe); + efree(COROG.chan_pipe); + COROG.chan_pipe = NULL; + } +} + +static void sw_coro_func(void *arg) +{ + php_args *php_arg = (php_args *) arg; + zend_fcall_info_cache *fci_cache = php_arg->fci_cache; + zval **argv = php_arg->argv; + int argc = php_arg->argc; + zval *retval = php_arg->retval; + void *post_callback = php_arg->post_callback; + void* params = php_arg->params; + int cid = coroutine_get_cid(); + + zend_function *func; + uint32_t i; + coro_task *task; + + zend_vm_stack origin_vm_stack = EG(vm_stack); + zval *origin_vm_stack_top = EG(vm_stack_top); + zval *origin_vm_stack_end = EG(vm_stack_end); + + func = fci_cache->function_handler; + sw_vm_stack_init(); + zend_execute_data *call = (zend_execute_data *) (EG(vm_stack_top)); + + task = (coro_task *) EG(vm_stack_top); + EG(vm_stack_top) = (zval *) ((char *) call + TASK_SLOT * sizeof(zval)); + + call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED, func, argc, + fci_cache->called_scope, fci_cache->object); + +#if PHP_MINOR_VERSION < 1 + EG(scope) = func->common.scope; +#endif + + for (i = 0; i < argc; ++i) + { + zval *target; + target = ZEND_CALL_ARG(call, i + 1); + ZVAL_COPY(target, argv[i]); + } + call->symbol_table = NULL; + + EG(current_execute_data) = NULL; + if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) + { + uint32_t call_info; + GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); + call_info = ZEND_CALL_CLOSURE; + ZEND_ADD_CALL_FLAG(call, call_info); + } + zend_init_execute_data(call, &func->op_array, retval); + + task->cid = cid; + task->execute_data = call; + task->stack = EG(vm_stack); + task->vm_stack_top = EG(vm_stack_top); + task->vm_stack_end = EG(vm_stack_end); + task->origin_stack = origin_vm_stack; + task->origin_vm_stack_top = origin_vm_stack_top; + task->origin_vm_stack_end = origin_vm_stack_end; + task->start_time = time(NULL); + task->function = NULL; + task->is_yield = 0; + task->state = SW_CORO_RUNNING; + task->co = coroutine_get_by_id(cid); + + COROG.call_stack[COROG.call_stack_size++] = task; + COROG.current_coro = task; + swTraceLog(SW_TRACE_COROUTINE, "Create coro id: %d, coro total count: %d, heap size: %zu", cid, COROG.coro_num, zend_memory_usage(0)); + + EG(current_execute_data) = task->execute_data; + EG(vm_stack) = task->stack; + EG(vm_stack_top) = task->vm_stack_top; + EG(vm_stack_end) = task->vm_stack_end; + zend_execute_ex(EG(current_execute_data) TSRMLS_CC); +} + +int sw_coro_create(zend_fcall_info_cache *fci_cache, zval **argv, int argc, zval *retval, void *post_callback, + void *params) +{ + if (unlikely(COROG.coro_num >= COROG.max_coro_num) ) + { + COROG.error = 1; + swWarn("exceed max number of coro_num %d, max_coro_num:%d", COROG.coro_num, COROG.max_coro_num); + return CORO_LIMIT; + } + + php_args php_args; + php_args.fci_cache = fci_cache; + php_args.argv = argv; + php_args.argc = argc; + php_args.retval = retval; + php_args.post_callback = post_callback; + php_args.params = params; + + COROG.error = 0; + COROG.coro_num++; + + return coroutine_create(sw_coro_func, (void*) &php_args); +} + +void sw_coro_save(zval *return_value, php_context *sw_current_context) +{ + SWCC(current_coro_return_value_ptr) = return_value; + SWCC(current_execute_data) = EG(current_execute_data); + SWCC(current_vm_stack) = EG(vm_stack); + SWCC(current_vm_stack_top) = EG(vm_stack_top); + SWCC(current_vm_stack_end) = EG(vm_stack_end); + SWCC(current_task) = (coro_task *) sw_get_current_task();; +} + +int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_retval) +{ + coro_task *task = SWCC(current_task); + COROG.call_stack[COROG.call_stack_size++] = task; + COROG.current_coro = task; + swTraceLog(SW_TRACE_COROUTINE,"sw_coro_resume coro id %d", COROG.current_coro->cid); + task->state = SW_CORO_RUNNING; + EG(current_execute_data) = SWCC(current_execute_data); + EG(vm_stack) = SWCC(current_vm_stack); + EG(vm_stack_top) = SWCC(current_vm_stack_top); + EG(vm_stack_end) = SWCC(current_vm_stack_end); + if (EG(current_execute_data)->prev_execute_data->opline->result_type != IS_UNUSED && retval) + { + ZVAL_COPY(SWCC(current_coro_return_value_ptr), retval); + } + swDebug("cid=%d", task->cid); + coroutine_resume(task->co); + if (unlikely(EG(exception))) + { + if (retval) + { + zval_ptr_dtor(retval); + } + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + return CORO_END; +} + +void sw_coro_yield() +{ + coro_task *task = (coro_task *) sw_get_current_task(); + COROG.call_stack_size--; + swTraceLog(SW_TRACE_COROUTINE,"coro_yield coro id %d", task->cid); + task->state = SW_CORO_YIELD; + task->is_yield = 1; + EG(vm_stack) = task->origin_stack; + EG(vm_stack_top) = task->origin_vm_stack_top; + EG(vm_stack_end) = task->origin_vm_stack_end; + coroutine_yield(task->co); +} + +void sw_coro_close() +{ + coro_task *task = (coro_task *) sw_get_current_task(); + swTraceLog(SW_TRACE_COROUTINE,"coro_close coro id %d", task->cid); + if (!task->is_yield) + { + EG(vm_stack) = task->origin_stack; + EG(vm_stack_top) = task->origin_vm_stack_top; + EG(vm_stack_end) = task->origin_vm_stack_end; + } + else + { + EG(vm_stack) = COROG.origin_vm_stack; + EG(vm_stack_top) = COROG.origin_vm_stack_top; + EG(vm_stack_end) = COROG.origin_vm_stack_end; + } + COROG.call_stack_size--; + efree(task->stack); + COROG.coro_num--; + COROG.current_coro = NULL; + swTraceLog(SW_TRACE_COROUTINE, "close coro and %d remained. usage size: %zu. malloc size: %zu", COROG.coro_num, zend_memory_usage(0), zend_memory_usage(1)); +} + +int sw_get_current_cid() +{ + if (unlikely(COROG.active == 0)) + { + return -1; + } + else + { + coro_task* task = sw_get_current_task(); + if (task) + { + return task->cid; + } + return -1; + } +} + +static coro_task* sw_get_current_task() +{ + return (COROG.call_stack_size > 0) ? COROG.call_stack[COROG.call_stack_size - 1] : NULL; +} + +void coro_handle_timeout() +{ + swLinkedList *timeout_list = SwooleWG.coro_timeout_list; + swTimer_node *tnode = NULL; + if (timeout_list != NULL && timeout_list->num > 0) + { + php_context *cxt = (php_context *) swLinkedList_shift(timeout_list); + while (cxt != NULL) + { + cxt->onTimeout(cxt); + cxt = (php_context *) swLinkedList_shift(timeout_list); + } + } + + timeout_list = SwooleWG.delayed_coro_timeout_list; + if (likely(timeout_list != NULL)) + { + swTimer_coro_callback *scc = (swTimer_coro_callback *) swLinkedList_shift(timeout_list); + while (scc != NULL) + { + php_context *context = (php_context *) scc->data; + if (unlikely(context->state == SW_CORO_CONTEXT_TERM)) + { + efree(context); + efree(scc); + } + else + { + context->state = SW_CORO_CONTEXT_RUNNING; + tnode = SwooleG.timer.add(&SwooleG.timer, scc->ms, 0, scc, php_swoole_onTimeout); + + if (tnode == NULL) + { + efree(scc); + swWarn("Addtimer coro failed."); + } + else + { + tnode->type = SW_TIMER_TYPE_CORO; + *scc->timeout_id = tnode->id; + } + } + scc = (swTimer_coro_callback *) swLinkedList_shift(timeout_list); + } + } +} +#endif diff --git a/vendor/swoole/swoole_coroutine.h b/vendor/swoole/swoole_coroutine.h new file mode 100755 index 0000000..0015214 --- /dev/null +++ b/vendor/swoole/swoole_coroutine.h @@ -0,0 +1,127 @@ +#ifndef SWOOLE_CORO_INCLUDE_C_H_ +#define SWOOLE_CORO_INCLUDE_C_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include "coroutine.h" + +#define SW_EX_CV_NUM(ex, n) (((zval ***)(((char *)(ex)) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)))) + n) +#define SW_EX_CV(var) (*SW_EX_CV_NUM(execute_data, var)) + +typedef enum +{ + SW_CORO_CONTEXT_RUNNING, SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST, SW_CORO_CONTEXT_TERM +} php_context_state; + +typedef struct _php_args +{ + zend_fcall_info_cache *fci_cache; + zval **argv; + int argc; + zval *retval; + void *post_callback; + void *params; +} php_args; + +typedef struct _coro_task +{ + int cid; + sw_coro_state state; + zend_execute_data *execute_data; + zend_vm_stack stack; + zval *vm_stack_top; + zval *vm_stack_end; + + zend_vm_stack origin_stack; + zval *origin_vm_stack_top; + zval *origin_vm_stack_end; + + zend_execute_data *yield_execute_data; + zend_vm_stack yield_stack; + zval *yield_vm_stack_top; + zval *yield_vm_stack_end; + zend_bool is_yield; + /** + * user coroutine + */ + coroutine_t *co; + zval *function; + time_t start_time; + void (*post_callback)(void *param); + void *post_callback_params; + php_args args; +} coro_task; + +typedef struct _php_context +{ + zval **current_coro_return_value_ptr_ptr; + zval *current_coro_return_value_ptr; + zval coro_params; + void (*onTimeout)(struct _php_context *cxt); + void *private_data; + zval **current_eg_return_value_ptr_ptr; + zend_execute_data *current_execute_data; + zval *current_vm_stack_top; + zval *current_vm_stack_end; + zval *allocated_return_value_ptr; + coro_task *current_task; + zend_vm_stack current_vm_stack; + php_context_state state; +} php_context; + +typedef struct _coro_global +{ + uint32_t coro_num; + uint32_t max_coro_num; + uint32_t stack_size; + zend_vm_stack origin_vm_stack; + zval *origin_vm_stack_top; + zval *origin_vm_stack_end; + zval *allocated_return_value_ptr; + zend_execute_data *origin_ex; + coro_task *current_coro; + zend_bool active; + coro_task *call_stack[128]; + int call_stack_size; + swPipe *chan_pipe; + int error; +} coro_global; + +typedef struct _swTimer_coro_callback +{ + int ms; + int cli_fd; + long *timeout_id; + void* data; +} swTimer_coro_callback; + +extern coro_global COROG; + +int sw_get_current_cid(); +int coro_init(TSRMLS_D); +void coro_destroy(TSRMLS_D); +void coro_check(TSRMLS_D); +void coro_handle_timeout(); + +#define coro_create(op_array, argv, argc, retval, post_callback, param) \ + sw_coro_create(op_array, argv, argc, *retval, post_callback, param) +#define coro_save(sw_php_context) \ + sw_coro_save(return_value, sw_php_context); +#define coro_resume(sw_current_context, retval, coro_retval) \ + sw_coro_resume(sw_current_context, retval, *coro_retval) +#define coro_yield() sw_coro_yield() + +int sw_coro_create(zend_fcall_info_cache *op_array, zval **argv, int argc, zval *retval, void *post_callback, void *param); +void sw_coro_yield(); +void sw_coro_close(); +int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_retval); +void sw_coro_save(zval *return_value, php_context *sw_php_context); + +int php_swoole_add_timer_coro(int ms, int cli_fd, long *timeout_id, void* param, swLinkedList_node **node TSRMLS_DC); +int php_swoole_clear_timer_coro(long id TSRMLS_DC); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif +#endif /* SWOOLE_CORO_INCLUDE_C_H_ */ diff --git a/vendor/swoole/swoole_coroutine_util.c b/vendor/swoole/swoole_coroutine_util.c new file mode 100755 index 0000000..13ba394 --- /dev/null +++ b/vendor/swoole/swoole_coroutine_util.c @@ -0,0 +1,1100 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + | shiguangqi <shiguangqi2008@gmail.com> | + | Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#include "async.h" +#include "ext/standard/file.h" + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_set, 0, 0, 1) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_create, 0, 0, 1) + ZEND_ARG_INFO(0, func) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_exec, 0, 0, 1) + ZEND_ARG_INFO(0, command) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_resume, 0, 0, 1) + ZEND_ARG_INFO(0, uid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_sleep, 0, 0, 1) + ZEND_ARG_INFO(0, seconds) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fread, 0, 0, 1) + ZEND_ARG_INFO(0, handle) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fgets, 0, 0, 1) + ZEND_ARG_INFO(0, handle) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_fwrite, 0, 0, 2) + ZEND_ARG_INFO(0, handle) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_gethostbyname, 0, 0, 1) + ZEND_ARG_INFO(0, domain_name) + ZEND_ARG_INFO(0, family) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_getaddrinfo, 0, 0, 1) + ZEND_ARG_INFO(0, hostname) + ZEND_ARG_INFO(0, family) + ZEND_ARG_INFO(0, socktype) + ZEND_ARG_INFO(0, protocol) + ZEND_ARG_INFO(0, service) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_readFile, 0, 0, 1) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_coroutine_writeFile, 0, 0, 2) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +static PHP_METHOD(swoole_coroutine_util, set); +static PHP_METHOD(swoole_coroutine_util, suspend); +static PHP_METHOD(swoole_coroutine_util, resume); +static PHP_METHOD(swoole_coroutine_util, stats); +static PHP_METHOD(swoole_coroutine_util, getuid); +static PHP_METHOD(swoole_coroutine_util, sleep); +static PHP_METHOD(swoole_coroutine_util, fread); +static PHP_METHOD(swoole_coroutine_util, fgets); +static PHP_METHOD(swoole_coroutine_util, fwrite); +static PHP_METHOD(swoole_coroutine_util, gethostbyname); +static PHP_METHOD(swoole_coroutine_util, getaddrinfo); +static PHP_METHOD(swoole_coroutine_util, readFile); +static PHP_METHOD(swoole_coroutine_util, writeFile); + +static swHashMap *defer_coros; + +static zend_class_entry swoole_coroutine_util_ce; +static zend_class_entry *swoole_coroutine_util_class_entry_ptr; + +static const zend_function_entry swoole_coroutine_util_methods[] = +{ + ZEND_FENTRY(create, ZEND_FN(swoole_coroutine_create), arginfo_swoole_coroutine_create, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FENTRY(exec, ZEND_FN(swoole_coroutine_exec), arginfo_swoole_coroutine_exec, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, set, arginfo_swoole_coroutine_set, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, suspend, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, resume, arginfo_swoole_coroutine_resume, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, stats, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, getuid, arginfo_swoole_coroutine_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, sleep, arginfo_swoole_coroutine_sleep, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, fread, arginfo_swoole_coroutine_fread, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, fgets, arginfo_swoole_coroutine_fgets, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, fwrite, arginfo_swoole_coroutine_fwrite, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, readFile, arginfo_swoole_coroutine_readFile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, writeFile, arginfo_swoole_coroutine_writeFile, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, gethostbyname, arginfo_swoole_coroutine_gethostbyname, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_coroutine_util, getaddrinfo, arginfo_swoole_coroutine_getaddrinfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +void swoole_coroutine_util_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_coroutine_util_ce, "swoole_coroutine", "Swoole\\Coroutine", swoole_coroutine_util_methods); + swoole_coroutine_util_class_entry_ptr = zend_register_internal_class(&swoole_coroutine_util_ce TSRMLS_CC); + + if (SWOOLE_G(use_namespace)) + { + sw_zend_register_class_alias("swoole_coroutine", swoole_coroutine_util_class_entry_ptr); + } + else + { + sw_zend_register_class_alias("Swoole\\Coroutine", swoole_coroutine_util_class_entry_ptr); + } + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co", swoole_coroutine_util_class_entry_ptr); + } + defer_coros = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); +} + +/* + * suspend current coroutine + */ +static PHP_METHOD(swoole_coroutine_util, suspend) +{ + int cid = sw_get_current_cid(); + if (cid < 0) + { + swoole_php_fatal_error(E_ERROR, "can not suspend outside coroutine"); + RETURN_FALSE; + } + + swLinkedList *coros_list = swHashMap_find_int(defer_coros, cid); + if (coros_list == NULL) + { + coros_list = swLinkedList_new(2, NULL); + if (coros_list == NULL) + { + RETURN_FALSE; + } + if (swHashMap_add_int(defer_coros, cid, coros_list) == SW_ERR) + { + swLinkedList_free(coros_list); + RETURN_FALSE; + } + } + + php_context *context = emalloc(sizeof(php_context)); + coro_save(context); + if (swLinkedList_append(coros_list, (void *) context) == SW_ERR) + { + efree(context); + RETURN_FALSE; + } + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, set) +{ + zval *zset = NULL; + HashTable *vht = NULL; + zval *v; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + + php_swoole_array_separate(zset); + vht = Z_ARRVAL_P(zset); + if (php_swoole_array_get_value(vht, "max_coroutine", v)) + { + convert_to_long(v); + COROG.max_coro_num = (int) Z_LVAL_P(v); + if (COROG.max_coro_num <= 0) + { + COROG.max_coro_num = DEFAULT_MAX_CORO_NUM; + } + else if (COROG.max_coro_num >= MAX_CORO_NUM_LIMIT) + { + COROG.max_coro_num = MAX_CORO_NUM_LIMIT; + } + } + if (php_swoole_array_get_value(vht, "stack_size", v)) + { + convert_to_long(v); + COROG.stack_size = (uint32_t) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "log_level", v)) + { + convert_to_long(v); + SwooleG.log_level = (int32_t) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "trace_flags", v)) + { + convert_to_long(v); + SwooleG.trace_flags = (int32_t) Z_LVAL_P(v); + } + sw_zval_ptr_dtor(&zset); +} + +PHP_FUNCTION(swoole_coroutine_create) +{ + zval *callback; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &callback) == FAILURE) + { + return; + } + if (unlikely(SWOOLE_G(req_status) == PHP_SWOOLE_CALL_USER_SHUTDOWNFUNC_BEGIN)) + { + zend_function *func = (zend_function *) EG(current_execute_data)->prev_execute_data->func; + zend_string *destruct = zend_string_init("__destruct", strlen("__destruct"), 0); + if (zend_string_equals(func->common.function_name, destruct)) + { + zend_string_release(destruct); + swoole_php_fatal_error(E_ERROR, "can not use coroutine in __destruct after php_request_shutdown"); + return; + } + zend_string_release(destruct); + } + char *func_name = NULL; + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + if (COROG.active == 0) + { + coro_init(TSRMLS_C); + } + php_swoole_check_reactor(); + callback = sw_zval_dup(callback); + sw_zval_add_ref(&callback); + + zval *retval = NULL; + zval *args[1]; + int cid = coro_create(func_cache, args, 0, &retval, NULL, NULL); + sw_zval_free(callback); + efree(func_cache); + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + if (cid < 0) + { + RETURN_FALSE; + } + else + { + RETURN_LONG(cid); + } +} + +static PHP_METHOD(swoole_coroutine_util, resume) +{ + long id; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) + { + return; + } + + swLinkedList *coros_list = swHashMap_find_int(defer_coros, id); + if (coros_list == NULL) + { + swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); + RETURN_FALSE; + } + + php_context *context = swLinkedList_shift(coros_list); + if (context == NULL) + { + swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); + RETURN_FALSE; + } + + zval *retval = NULL; + zval *result; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 1); + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(context); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_coroutine_util, stats) +{ + array_init(return_value); + sw_add_assoc_long_ex(return_value, ZEND_STRS("coroutine_num"), COROG.coro_num); +} + +static PHP_METHOD(swoole_coroutine_util, getuid) +{ + RETURN_LONG(sw_get_current_cid()); +} + +static void php_coroutine_sleep_timeout(swTimer *timer, swTimer_node *tnode) +{ + zval *retval = NULL; + zval *result = NULL; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 1); + + php_context *context = (php_context *) tnode->data; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(context); +} + +int php_coroutine_reactor_can_exit(swReactor *reactor) +{ + return COROG.coro_num != 0; +} + +static PHP_METHOD(swoole_coroutine_util, sleep) +{ + coro_check(TSRMLS_C); + + double seconds; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", & seconds) == FAILURE) + { + return; + } + + int ms = (int) (seconds * 1000); + + if (SwooleG.serv && swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "cannot use timer in master process."); + return; + } + if (ms > SW_TIMER_MAX_VALUE) + { + swoole_php_fatal_error(E_WARNING, "The given parameters is too big."); + return; + } + if (ms <= 0) + { + swoole_php_fatal_error(E_WARNING, "Timer must be greater than 0"); + return; + } + + php_context *context = emalloc(sizeof(php_context)); + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + php_swoole_check_reactor(); + php_swoole_check_timer(ms); + if (SwooleG.timer.add(&SwooleG.timer, ms, 0, context, php_coroutine_sleep_timeout) == NULL) + { + RETURN_FALSE; + } + + coro_save(context); + coro_yield(); +} + +static void aio_onReadCompleted(swAio_event *event) +{ + zval *retval = NULL; + zval *result = NULL; + SW_MAKE_STD_ZVAL(result); + + if (event->error == 0) + { + SW_ZVAL_STRINGL(result, event->buf, event->ret, 1); + } + else + { + ZVAL_BOOL(result, 0); + } + + php_context *context = (php_context *) event->object; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(event->buf); + efree(context); +} + +static void aio_onStreamGetLineCompleted(swAio_event *event) +{ + zval *retval = NULL; + zval *result = NULL; + SW_MAKE_STD_ZVAL(result); + + if (event->error == 0) + { + SW_ZVAL_STRINGL(result, event->buf, event->ret, 1); + } + else + { + ZVAL_BOOL(result, 0); + } + + php_context *context = (php_context *) event->object; + php_stream *stream; + php_stream_from_zval_no_verify(stream, &context->coro_params); + stream->readpos = event->offset; + stream->writepos = (long) event->req; + if (event->flags & SW_AIO_EOF) + { + stream->eof = 1; + } + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(context); +} + +static void aio_onWriteCompleted(swAio_event *event) +{ + zval *retval = NULL; + zval *result = NULL; + + SW_MAKE_STD_ZVAL(result); + if (event->ret < 0) + { + ZVAL_BOOL(result, 0); + } + else + { + ZVAL_LONG(result, event->ret); + } + + php_context *context = (php_context *) event->object; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(event->buf); + efree(context); +} + +static void aio_onReadFileCompleted(swAio_event *event) +{ + zval *retval = NULL; + zval *result = NULL; + + SW_MAKE_STD_ZVAL(result); + if (event->ret < 0) + { + ZVAL_BOOL(result, 0); + } + else + { + ZVAL_STRINGL(result, event->buf, event->ret); + sw_free(event->buf); + } + + php_context *context = (php_context *) event->object; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(event->req); + efree(context); +} + +static void aio_onWriteFileCompleted(swAio_event *event) +{ + zval *retval = NULL; + zval *result = NULL; + + SW_MAKE_STD_ZVAL(result); + if (event->ret < 0) + { + ZVAL_BOOL(result, 0); + } + else + { + ZVAL_LONG(result, event->ret); + } + + php_context *context = (php_context *) event->object; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(event->req); + efree(context); +} + +static PHP_METHOD(swoole_coroutine_util, fread) +{ + coro_check(TSRMLS_C); + + zval *handle; + zend_long length = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(handle) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(length) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &handle, &length) == FAILURE) + { + return; + } +#endif + + int fd = swoole_convert_to_fd(handle TSRMLS_CC); + + struct stat file_stat; + if (fstat(fd, &file_stat) < 0) + { + RETURN_FALSE; + } + + off_t _seek = lseek(fd, 0, SEEK_CUR); + if (length <= 0 || file_stat.st_size - _seek < length) + { + length = file_stat.st_size - _seek; + } + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + ev.nbytes = length + 1; + ev.buf = emalloc(ev.nbytes); + if (!ev.buf) + { + RETURN_FALSE; + } + + php_context *context = emalloc(sizeof(php_context)); + + ((char *) ev.buf)[length] = 0; + ev.flags = 0; + ev.type = SW_AIO_READ; + ev.object = context; + ev.callback = aio_onReadCompleted; + ev.fd = fd; + ev.offset = _seek; + + if (!SwooleAIO.init) + { + php_swoole_check_reactor(); + swAio_init(); + } + + swTrace("fd=%d, offset=%ld, length=%ld", fd, ev.offset, ev.nbytes); + + int ret = swAio_dispatch(&ev); + if (ret < 0) + { + efree(context); + RETURN_FALSE; + } + + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, fgets) +{ + coro_check(TSRMLS_C); + + zval *handle; + php_stream *stream; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_RESOURCE(handle) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &handle) == FAILURE) + { + return; + } +#endif + + int fd = swoole_convert_to_fd(handle TSRMLS_CC); + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + php_stream_from_res(stream, Z_RES_P(handle)); + + if (stream->readbuf == NULL) + { + stream->readbuflen = stream->chunk_size; + stream->readbuf = emalloc(stream->chunk_size); + } + + ev.nbytes = stream->readbuflen; + ev.buf = stream->readbuf; + if (!ev.buf) + { + RETURN_FALSE; + } + + php_context *context = emalloc(sizeof(php_context)); + + ev.flags = 0; + ev.type = SW_AIO_STREAM_GET_LINE; + ev.object = context; + ev.callback = aio_onStreamGetLineCompleted; + ev.fd = fd; + ev.offset = stream->readpos; + ev.req = (void *) (long) stream->writepos; + + if (!SwooleAIO.init) + { + php_swoole_check_reactor(); + swAio_init(); + } + + swTrace("fd=%d, offset=%ld, length=%ld", fd, ev.offset, ev.nbytes); + + int ret = swAio_dispatch(&ev); + if (ret < 0) + { + efree(context); + RETURN_FALSE; + } + + context->coro_params = *handle; + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, fwrite) +{ + coro_check(TSRMLS_C); + + zval *handle; + char *str; + zend_size_t l_str; + zend_long length = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(handle) + Z_PARAM_STRING(str, l_str) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(length) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &handle, &str, &l_str, &length) == FAILURE) + { + return; + } +#endif + + int fd = swoole_convert_to_fd(handle TSRMLS_CC); + + off_t _seek = lseek(fd, 0, SEEK_CUR); + if (length <= 0 || length > l_str) + { + length = l_str; + } + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + ev.nbytes = length; + ev.buf = estrndup(str, length); + + if (!ev.buf) + { + RETURN_FALSE; + } + + php_context *context = emalloc(sizeof(php_context)); + + ev.flags = 0; + ev.type = SW_AIO_WRITE; + ev.object = context; + ev.callback = aio_onWriteCompleted; + ev.fd = fd; + ev.offset = _seek; + + php_swoole_check_aio(); + + swTrace("fd=%d, offset=%ld, length=%ld", fd, ev.offset, ev.nbytes); + + int ret = swAio_dispatch(&ev); + if (ret < 0) + { + efree(context); + RETURN_FALSE; + } + + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, readFile) +{ + coro_check(TSRMLS_C); + + char *filename = NULL; + size_t l_filename = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(filename, l_filename) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &l_filename) == FAILURE) + { + return; + } +#endif + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + php_context *context = emalloc(sizeof(php_context)); + + ev.type = SW_AIO_READ_FILE; + ev.object = context; + ev.callback = aio_onReadFileCompleted; + ev.req = estrndup(filename, l_filename); + + if (!SwooleAIO.init) + { + php_swoole_check_reactor(); + swAio_init(); + } + + swTrace("readFile(%s)", filename); + + int ret = swAio_dispatch(&ev); + if (ret < 0) + { + efree(context); + RETURN_FALSE; + } + + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, writeFile) +{ + coro_check(TSRMLS_C); + + char *filename = NULL; + size_t l_filename = 0; + char *data = NULL; + size_t l_data = 0; + zend_long flags = 0; + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STRING(filename, l_filename) + Z_PARAM_STRING(data, l_data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &filename, &l_filename, &data, &l_data, &flags) == FAILURE) + { + return; + } +#endif + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + ev.nbytes = l_data; + ev.buf = data; + + php_context *context = emalloc(sizeof(php_context)); + + ev.type = SW_AIO_WRITE_FILE; + ev.object = context; + ev.callback = aio_onWriteFileCompleted; + ev.req = estrndup(filename, l_filename); + ev.flags = O_CREAT | O_WRONLY; + + if (flags & PHP_FILE_APPEND) + { + ev.flags |= O_APPEND; + } + else + { + ev.flags |= O_TRUNC; + } + + if (!SwooleAIO.init) + { + php_swoole_check_reactor(); + swAio_init(); + } + + swTrace("writeFile(%s, %ld)", filename, ev.nbytes); + + int ret = swAio_dispatch(&ev); + if (ret < 0) + { + efree(context); + RETURN_FALSE; + } + + context->onTimeout = NULL; + context->state = SW_CORO_CONTEXT_RUNNING; + + coro_save(context); + coro_yield(); +} + +static void coro_dns_onResolveCompleted(swAio_event *event) +{ + php_context *context = event->object; + + zval *retval = NULL; + zval *result = NULL; + + SW_MAKE_STD_ZVAL(result); + + if (event->error == 0) + { + SW_ZVAL_STRING(result, event->buf, 1); + } + else + { + SwooleG.error = event->error; + ZVAL_BOOL(result, 0); + } + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(event->buf); + efree(context); +} + +static void coro_dns_onGetaddrinfoCompleted(swAio_event *event) +{ + php_context *context = event->object; + + zval *retval = NULL; + zval *result = NULL; + + SW_MAKE_STD_ZVAL(result); + + struct sockaddr_in *addr_v4; + struct sockaddr_in6 *addr_v6; + + swRequest_getaddrinfo *req = event->req; + + if (req->error == 0) + { + array_init(result); + int i; + char tmp[INET6_ADDRSTRLEN]; + const char *r ; + + for (i = 0; i < req->count; i++) + { + if (req->family == AF_INET) + { + addr_v4 = req->result + (i * sizeof(struct sockaddr_in)); + r = inet_ntop(AF_INET, (const void*) &addr_v4->sin_addr, tmp, sizeof(tmp)); + } + else + { + addr_v6 = req->result + (i * sizeof(struct sockaddr_in6)); + r = inet_ntop(AF_INET6, (const void*) &addr_v6->sin6_addr, tmp, sizeof(tmp)); + } + if (r) + { + add_next_index_string(result, tmp); + } + } + } + else + { + ZVAL_BOOL(result, 0); + SwooleG.error = req->error; + } + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + efree(req->hostname); + efree(req->result); + if (req->service) + { + efree(req->service); + } + efree(req); + efree(context); +} + +static PHP_METHOD(swoole_coroutine_util, gethostbyname) +{ + coro_check(TSRMLS_C); + + char *domain_name; + zend_size_t l_domain_name; + long family = AF_INET; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &domain_name, &l_domain_name, &family) == FAILURE) + { + RETURN_FALSE; + } + + if (l_domain_name <= 0) + { + swoole_php_fatal_error(E_WARNING, "domain name is empty."); + RETURN_FALSE; + } + + if (family != AF_INET && family != AF_INET6) + { + swoole_php_fatal_error(E_WARNING, "unknown protocol family, must be AF_INET or AF_INET6."); + RETURN_FALSE; + } + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + if (l_domain_name < SW_IP_MAX_LENGTH) + { + ev.nbytes = SW_IP_MAX_LENGTH; + } + else + { + ev.nbytes = l_domain_name + 1; + } + + ev.buf = emalloc(ev.nbytes); + if (!ev.buf) + { + swWarn("malloc failed."); + RETURN_FALSE; + } + + php_context *sw_current_context = emalloc(sizeof(php_context)); + + memcpy(ev.buf, domain_name, l_domain_name); + ((char *) ev.buf)[l_domain_name] = 0; + ev.flags = family; + ev.type = SW_AIO_GETHOSTBYNAME; + ev.object = sw_current_context; + ev.callback = coro_dns_onResolveCompleted; + + php_swoole_check_aio(); + + if (swAio_dispatch(&ev) < 0) + { + efree(ev.buf); + RETURN_FALSE; + } + + coro_save(sw_current_context); + coro_yield(); +} + +static PHP_METHOD(swoole_coroutine_util, getaddrinfo) +{ + coro_check(TSRMLS_C); + + char *hostname; + zend_size_t l_hostname; + long family = AF_INET; + long socktype = SOCK_STREAM; + long protocol = IPPROTO_TCP; + char *service = NULL; + zend_size_t l_service = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "s|llls", &hostname, &l_hostname, &family, socktype, &protocol, + &hostname, &l_hostname) == FAILURE) + { + RETURN_FALSE; + } + + if (l_hostname <= 0) + { + swoole_php_fatal_error(E_WARNING, "hostname is empty."); + RETURN_FALSE; + } + + if (family != AF_INET && family != AF_INET6) + { + swoole_php_fatal_error(E_WARNING, "unknown protocol family, must be AF_INET or AF_INET6."); + RETURN_FALSE; + } + + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + swRequest_getaddrinfo *req = emalloc(sizeof(swRequest_getaddrinfo)); + bzero(req, sizeof(swRequest_getaddrinfo)); + + php_context *sw_current_context = emalloc(sizeof(php_context)); + + ev.type = SW_AIO_GETADDRINFO; + ev.object = sw_current_context; + ev.callback = coro_dns_onGetaddrinfoCompleted; + ev.req = req; + + req->hostname = estrndup(hostname, l_hostname); + req->family = family; + req->socktype = socktype; + req->protocol = protocol; + + if (service) + { + req->service = estrndup(service, l_service); + } + + if (family == AF_INET) + { + req->result = ecalloc(SW_DNS_HOST_BUFFER_SIZE, sizeof(struct sockaddr_in)); + } + else + { + req->result = ecalloc(SW_DNS_HOST_BUFFER_SIZE, sizeof(struct sockaddr_in6)); + } + + php_swoole_check_aio(); + + if (swAio_dispatch(&ev) < 0) + { + efree(ev.buf); + RETURN_FALSE; + } + + coro_save(sw_current_context); + coro_yield(); +} + +#endif diff --git a/vendor/swoole/swoole_event.c b/vendor/swoole/swoole_event.c new file mode 100755 index 0000000..ba47f82 --- /dev/null +++ b/vendor/swoole/swoole_event.c @@ -0,0 +1,838 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + struct + { + zval cb_read; + zval cb_write; + zval socket; + } stack; +#endif + zval *cb_read; + zval *cb_write; + zval *socket; +} php_reactor_fd; + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + zval _callback; +#endif + zval *callback; +} php_defer_callback; + +static int php_swoole_event_onRead(swReactor *reactor, swEvent *event); +static int php_swoole_event_onWrite(swReactor *reactor, swEvent *event); +static int php_swoole_event_onError(swReactor *reactor, swEvent *event); +static void php_swoole_event_onDefer(void *_cb); +static void php_swoole_event_onEndCallback(void *_cb); + +static void free_event_callback(void* data) +{ + php_reactor_fd *ev_set = (php_reactor_fd*) data; + if (ev_set->cb_read) + { + sw_zval_ptr_dtor(&(ev_set->cb_read)); + ev_set->cb_read = NULL; + } + if (ev_set->cb_write) + { + sw_zval_ptr_dtor(&(ev_set->cb_write)); + ev_set->cb_write = NULL; + } + if (ev_set->socket) + { + sw_zval_ptr_dtor(&(ev_set->socket)); + ev_set->socket = NULL; + } + efree(ev_set); +} + +static void free_callback(void* data) +{ + php_defer_callback *cb = (php_defer_callback *) data; + sw_zval_ptr_dtor(&cb->callback); + efree(cb); +} + +static int php_swoole_event_onRead(swReactor *reactor, swEvent *event) +{ + zval *retval; + zval **args[1]; + php_reactor_fd *fd = event->socket->object; + + SWOOLE_GET_TSRMLS; + + args[0] = &fd->socket; + + if (sw_call_user_function_ex(EG(function_table), NULL, fd->cb_read, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: onRead handler error."); + SwooleG.main_reactor->del(SwooleG.main_reactor, event->fd); + return SW_ERR; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; +} + +static int php_swoole_event_onWrite(swReactor *reactor, swEvent *event) +{ + zval *retval; + zval **args[1]; + php_reactor_fd *fd = event->socket->object; + + SWOOLE_GET_TSRMLS; + + if (!fd->cb_write) + { + return swReactor_onWrite(reactor, event); + } + + args[0] = &fd->socket; + + if (sw_call_user_function_ex(EG(function_table), NULL, fd->cb_write, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: onWrite handler error"); + SwooleG.main_reactor->del(SwooleG.main_reactor, event->fd); + return SW_ERR; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; +} + +static int php_swoole_event_onError(swReactor *reactor, swEvent *event) +{ + SWOOLE_GET_TSRMLS; + + int error; + socklen_t len = sizeof(error); + + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event->onError[1]: getsockopt[sock=%d] failed. Error: %s[%d]", event->fd, strerror(errno), errno); + } + + if (error != 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event->onError[1]: socket error. Error: %s [%d]", strerror(error), error); + } + + efree(event->socket->object); + event->socket->active = 0; + + SwooleG.main_reactor->del(SwooleG.main_reactor, event->fd); + + return SW_OK; +} + +static void php_swoole_event_onDefer(void *_cb) +{ + php_defer_callback *defer = _cb; + + SWOOLE_GET_TSRMLS; + zval *retval; + if (sw_call_user_function_ex(EG(function_table), NULL, defer->callback, &retval, 0, NULL, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: defer handler error"); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&defer->callback); + efree(defer); +} + +static void php_swoole_event_onEndCallback(void *_cb) +{ + php_defer_callback *defer = _cb; + + SWOOLE_GET_TSRMLS; + zval *retval; + if (sw_call_user_function_ex(EG(function_table), NULL, defer->callback, &retval, 0, NULL, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: defer handler error"); + return; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +void php_swoole_event_init(void) +{ + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_USER | SW_EVENT_READ, php_swoole_event_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_USER | SW_EVENT_WRITE, php_swoole_event_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_USER | SW_EVENT_ERROR, php_swoole_event_onError); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, SW_FD_WRITE, swReactor_onWrite); +} + +void php_swoole_event_wait() +{ + SWOOLE_GET_TSRMLS; + if (SwooleWG.in_client == 1 && SwooleWG.reactor_ready == 0 && SwooleG.running) + { +#if PHP_MAJOR_VERSION >= 7 + if (PG(last_error_message)) + { + switch (PG(last_error_type)) + { + case E_ERROR: + case E_CORE_ERROR: + case E_USER_ERROR: + case E_COMPILE_ERROR: + return; + default: + break; + } + } +#endif + SwooleWG.reactor_ready = 1; + +#ifdef HAVE_SIGNALFD + if (SwooleG.main_reactor->check_signalfd) + { + swSignalfd_setup(SwooleG.main_reactor); + } +#endif + +#ifdef SW_COROUTINE + if (COROG.active == 0) + { + coro_init(TSRMLS_C); + } +#endif + if (!swReactor_empty(SwooleG.main_reactor)) + { + int ret = SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); + if (ret < 0) + { + swoole_php_fatal_error(E_ERROR, "reactor wait failed. Error: %s [%d]", strerror(errno), errno); + } + } + if (SwooleG.timer.map) + { + php_swoole_clear_all_timer(); + } + SwooleWG.reactor_exit = 1; + } +} + +int swoole_convert_to_fd(zval *zfd TSRMLS_DC) +{ + php_stream *stream; + int socket_fd; + +#ifdef SWOOLE_SOCKETS_SUPPORT + php_socket *php_sock; +#endif + if (SW_Z_TYPE_P(zfd) == IS_RESOURCE) + { + if (SW_ZEND_FETCH_RESOURCE_NO_RETURN(stream, php_stream *, &zfd, -1, NULL, php_file_le_stream())) + { + if (php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void* )&socket_fd, 1) != SUCCESS || socket_fd < 0) + { + return SW_ERR; + } + } + else + { +#ifdef SWOOLE_SOCKETS_SUPPORT + if (SW_ZEND_FETCH_RESOURCE_NO_RETURN(php_sock, php_socket *, &zfd, -1, NULL, php_sockets_le_socket())) + { + socket_fd = php_sock->bsd_socket; + + } + else + { + swoole_php_fatal_error(E_WARNING, "fd argument must be either valid PHP stream or valid PHP socket resource"); + return SW_ERR; + } +#else + swoole_php_fatal_error(E_WARNING, "fd argument must be valid PHP stream resource"); + return SW_ERR; +#endif + } + } + else if (SW_Z_TYPE_P(zfd) == IS_LONG) + { + socket_fd = Z_LVAL_P(zfd); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "invalid file descriptor passed"); + return SW_ERR; + } + } + else if (SW_Z_TYPE_P(zfd) == IS_OBJECT) + { + zval *zsock = NULL; + if (instanceof_function(Z_OBJCE_P(zfd), swoole_client_class_entry_ptr TSRMLS_CC)) + { + zsock = sw_zend_read_property(Z_OBJCE_P(zfd), zfd, SW_STRL("sock")-1, 0 TSRMLS_CC); + } + else if (instanceof_function(Z_OBJCE_P(zfd), swoole_process_class_entry_ptr TSRMLS_CC)) + { + zsock = sw_zend_read_property(Z_OBJCE_P(zfd), zfd, SW_STRL("pipe")-1, 0 TSRMLS_CC); + } + if (zsock == NULL || ZVAL_IS_NULL(zsock)) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_client or swoole_process."); + return -1; + } + socket_fd = Z_LVAL_P(zsock); + } + else + { + return SW_ERR; + } + return socket_fd; +} + +#ifdef SWOOLE_SOCKETS_SUPPORT +php_socket* swoole_convert_to_socket(int sock) +{ + SWOOLE_GET_TSRMLS; + php_socket *socket_object = emalloc(sizeof *socket_object); + bzero(socket_object, sizeof(php_socket)); + socket_object->bsd_socket = sock; + socket_object->blocking = 1; + + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + + if (getsockname(sock, (struct sockaddr*) &addr, &addr_len) == 0) + { + socket_object->type = addr.ss_family; + } + else + { + swoole_php_sys_error(E_WARNING, "unable to obtain socket family"); + error: + efree(socket_object); + return NULL; + } + + int t = fcntl(sock, F_GETFL); + if (t == -1) + { + swoole_php_sys_error(E_WARNING, "unable to obtain blocking state"); + goto error; + } + else + { + socket_object->blocking = !(t & O_NONBLOCK); + } + return socket_object; +} +#endif + +PHP_FUNCTION(swoole_event_add) +{ + zval *cb_read = NULL; + zval *cb_write = NULL; + zval *zfd; + char *func_name = NULL; + long event_flag = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zzl", &zfd, &cb_read, &cb_write, &event_flag) == FAILURE) + { + return; + } + + if ((cb_read == NULL && cb_write == NULL) || (ZVAL_IS_NULL(cb_read) && ZVAL_IS_NULL(cb_write))) + { + swoole_php_fatal_error(E_WARNING, "no read or write event callback."); + RETURN_FALSE; + } + + int socket_fd = swoole_convert_to_fd(zfd TSRMLS_CC); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "unknow type."); + RETURN_FALSE; + } + if (socket_fd == 0 && (event_flag & SW_EVENT_WRITE)) + { + swoole_php_fatal_error(E_WARNING, "invalid socket fd [%d].", socket_fd); + RETURN_FALSE; + } + + php_reactor_fd *reactor_fd = emalloc(sizeof(php_reactor_fd)); + reactor_fd->socket = zfd; + sw_copy_to_stack(reactor_fd->socket, reactor_fd->stack.socket); + sw_zval_add_ref(&reactor_fd->socket); + + if (cb_read!= NULL && !ZVAL_IS_NULL(cb_read)) + { + if (!sw_zend_is_callable(cb_read, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + reactor_fd->cb_read = cb_read; + sw_zval_add_ref(&cb_read); + sw_copy_to_stack(reactor_fd->cb_read, reactor_fd->stack.cb_read); + } + else + { + reactor_fd->cb_read = NULL; + } + + if (cb_write!= NULL && !ZVAL_IS_NULL(cb_write)) + { + if (!sw_zend_is_callable(cb_write, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + reactor_fd->cb_write = cb_write; + sw_zval_add_ref(&cb_write); + sw_copy_to_stack(reactor_fd->cb_write, reactor_fd->stack.cb_write); + } + else + { + reactor_fd->cb_write = NULL; + } + + php_swoole_check_reactor(); + swSetNonBlock(socket_fd); //must be nonblock + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, socket_fd, SW_FD_USER | event_flag) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event_add failed."); + RETURN_FALSE; + } + + swConnection *socket = swReactor_get(SwooleG.main_reactor, socket_fd); + socket->object = reactor_fd; + socket->active = 1; + socket->nonblock = 1; + + RETURN_LONG(socket_fd); +} + +PHP_FUNCTION(swoole_event_write) +{ + zval *zfd; + char *data; + zend_size_t len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &zfd, &data, &len) == FAILURE) + { + return; + } + + if (len <= 0) + { + swoole_php_fatal_error(E_WARNING, "data empty."); + RETURN_FALSE; + } + + int socket_fd = swoole_convert_to_fd(zfd TSRMLS_CC); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "unknow type."); + RETURN_FALSE; + } + + php_swoole_check_reactor(); + if (SwooleG.main_reactor->write(SwooleG.main_reactor, socket_fd, data, len) < 0) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_event_set) +{ + zval *cb_read = NULL; + zval *cb_write = NULL; + zval *zfd; + + char *func_name = NULL; + long event_flag = 0; + if (!SwooleG.main_reactor) + { + swoole_php_fatal_error(E_WARNING, "reactor no ready, cannot swoole_event_set."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zzl", &zfd, &cb_read, &cb_write, &event_flag) == FAILURE) + { + return; + } + + int socket_fd = swoole_convert_to_fd(zfd TSRMLS_CC); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "unknow type."); + RETURN_FALSE; + } + + swConnection *socket = swReactor_get(SwooleG.main_reactor, socket_fd); + if (!socket->active) + { + swoole_php_fatal_error(E_WARNING, "socket[%d] is not found in the reactor.", socket_fd); + efree(func_name); + RETURN_FALSE; + } + + php_reactor_fd *ev_set = socket->object; + if (cb_read != NULL && !ZVAL_IS_NULL(cb_read)) + { + if (!sw_zend_is_callable(cb_read, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + else + { + if (ev_set->cb_read) + { + sw_zval_ptr_dtor(&ev_set->cb_read); + } + ev_set->cb_read = cb_read; + sw_zval_add_ref(&cb_read); + sw_copy_to_stack(ev_set->cb_read, ev_set->stack.cb_read); + efree(func_name); + } + } + + if (cb_write != NULL && !ZVAL_IS_NULL(cb_write)) + { + if (socket_fd == 0 && (event_flag & SW_EVENT_WRITE)) + { + swoole_php_fatal_error(E_WARNING, "invalid socket fd [%d].", socket_fd); + RETURN_FALSE; + } + if (!sw_zend_is_callable(cb_write, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + else + { + if (ev_set->cb_write) + { + sw_zval_ptr_dtor(&ev_set->cb_write); + } + ev_set->cb_write = cb_write; + sw_zval_add_ref(&cb_write); + sw_copy_to_stack(ev_set->cb_write, ev_set->stack.cb_write); + efree(func_name); + } + } + + if ((event_flag & SW_EVENT_READ) && ev_set->cb_read == NULL) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: no read callback."); + RETURN_FALSE; + } + + if ((event_flag & SW_EVENT_WRITE) && ev_set->cb_write == NULL) + { + swoole_php_fatal_error(E_WARNING, "swoole_event: no write callback."); + RETURN_FALSE; + } + + if (SwooleG.main_reactor->set(SwooleG.main_reactor, socket_fd, SW_FD_USER | event_flag) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event_set failed."); + RETURN_FALSE; + } + + RETURN_TRUE; +} + +PHP_FUNCTION(swoole_event_del) +{ + zval *zfd; + + if (!SwooleG.main_reactor) + { + swoole_php_fatal_error(E_WARNING, "reactor no ready, cannot swoole_event_del."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfd) == FAILURE) + { + return; + } + + int socket_fd = swoole_convert_to_fd(zfd TSRMLS_CC); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "unknow type."); + RETURN_FALSE; + } + + swConnection *socket = swReactor_get(SwooleG.main_reactor, socket_fd); + if (socket->object) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_event_callback, socket->object); + socket->object = NULL; + } + + int ret = SwooleG.main_reactor->del(SwooleG.main_reactor, socket_fd); + socket->active = 0; + SW_CHECK_RETURN(ret); +} + +PHP_FUNCTION(swoole_event_defer) +{ + zval *callback; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback) == FAILURE) + { + return; + } + + char *func_name; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + php_swoole_check_reactor(); + + //the event loop is not started + if (SwooleG.main_reactor->start == 0) + { + SW_CHECK_RETURN (php_swoole_add_timer(1, callback, NULL, 0 TSRMLS_CC)); + } + + php_defer_callback *defer = emalloc(sizeof(php_defer_callback)); + +#if PHP_MAJOR_VERSION >= 7 + defer->callback = &defer->_callback; + memcpy(defer->callback, callback, sizeof(zval)); +#else + defer->callback = callback; +#endif + sw_zval_add_ref(&callback); + SW_CHECK_RETURN(SwooleG.main_reactor->defer(SwooleG.main_reactor, php_swoole_event_onDefer, defer)); +} + +PHP_FUNCTION(swoole_event_cycle) +{ + if (!SwooleG.main_reactor) + { + swoole_php_fatal_error(E_WARNING, "reactor no ready, cannot swoole_event_defer."); + RETURN_FALSE; + } + + zval *callback; + zend_bool before = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &callback, &before) == FAILURE) + { + return; + } + + if (ZVAL_IS_NULL(callback)) + { + if (SwooleG.main_reactor->idle_task.callback == NULL) + { + RETURN_FALSE; + } + else + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_callback, SwooleG.main_reactor->idle_task.data); + SwooleG.main_reactor->idle_task.callback = NULL; + SwooleG.main_reactor->idle_task.data = NULL; + RETURN_TRUE; + } + } + + char *func_name; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + php_defer_callback *cb = emalloc(sizeof(php_defer_callback)); + +#if PHP_MAJOR_VERSION >= 7 + cb->callback = &cb->_callback; + memcpy(cb->callback, callback, sizeof(zval)); +#else + cb->callback = callback; +#endif + sw_zval_add_ref(&callback); + + if (before == 0) + { + if (SwooleG.main_reactor->idle_task.data != NULL) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_callback, SwooleG.main_reactor->idle_task.data); + } + + SwooleG.main_reactor->idle_task.callback = php_swoole_event_onEndCallback; + SwooleG.main_reactor->idle_task.data = cb; + } + else + { + if (SwooleG.main_reactor->future_task.data != NULL) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_callback, SwooleG.main_reactor->future_task.data); + } + + SwooleG.main_reactor->future_task.callback = php_swoole_event_onEndCallback; + SwooleG.main_reactor->future_task.data = cb; + //Registration onBegin callback function + swReactor_activate_future_task(SwooleG.main_reactor); + } + + RETURN_TRUE; +} + +PHP_FUNCTION(swoole_event_exit) +{ + if (SwooleWG.in_client == 1) + { + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->running = 0; + } + SwooleG.running = 0; + } +} + +PHP_FUNCTION(swoole_event_wait) +{ + if (!SwooleG.main_reactor) + { + return; + } + php_swoole_event_wait(); +} + +PHP_FUNCTION(swoole_event_dispatch) +{ + if (!SwooleG.main_reactor) + { + RETURN_FALSE; + } + SwooleG.main_reactor->once = 1; + +#ifdef HAVE_SIGNALFD + if (SwooleG.main_reactor->check_signalfd) + { + swSignalfd_setup(SwooleG.main_reactor); + } +#endif + +#ifdef SW_COROUTINE + if (COROG.active == 0) + { + coro_init(TSRMLS_C); + } +#endif + + int ret = SwooleG.main_reactor->wait(SwooleG.main_reactor, NULL); + if (ret < 0) + { + swoole_php_fatal_error(E_ERROR, "reactor wait failed. Error: %s [%d]", strerror(errno), errno); + } + + SwooleG.main_reactor->once = 0; + RETURN_TRUE; +} + +PHP_FUNCTION(swoole_event_isset) +{ + if (!SwooleG.main_reactor) + { + RETURN_FALSE; + } + + zval *zfd; + long events = SW_EVENT_READ | SW_EVENT_WRITE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &zfd, &events) == FAILURE) + { + return; + } + + int socket_fd = swoole_convert_to_fd(zfd TSRMLS_CC); + if (socket_fd < 0) + { + swoole_php_fatal_error(E_WARNING, "unknow type."); + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, socket_fd); + if (_socket == NULL || _socket->removed) + { + RETURN_FALSE; + } + if (_socket->events & events) + { + RETURN_TRUE; + } + else + { + RETURN_FALSE; + } +} diff --git a/vendor/swoole/swoole_http.h b/vendor/swoole/swoole_http.h new file mode 100755 index 0000000..ff72bb7 --- /dev/null +++ b/vendor/swoole/swoole_http.h @@ -0,0 +1,197 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SWOOLE_HTTP_H_ +#define SWOOLE_HTTP_H_ + +#include "thirdparty/php_http_parser.h" +#include "thirdparty/multipart_parser.h" + +#ifdef SW_USE_HTTP2 +#include <nghttp2/nghttp2.h> +#endif + +enum http_response_flag +{ + HTTP_RESPONSE_SERVER = 1u << 1, + HTTP_RESPONSE_CONNECTION = 1u << 2, + HTTP_RESPONSE_CONTENT_LENGTH = 1u << 3, + HTTP_RESPONSE_DATE = 1u << 4, + HTTP_RESPONSE_CONTENT_TYPE = 1u << 5, +}; + +typedef struct +{ + enum php_http_method method; + int version; + char *path; + uint32_t path_len; + const char *ext; + uint32_t ext_len; + uint8_t post_form_urlencoded; + + swString *post_buffer; + uint32_t post_length; + + zval *zobject; + zval *zserver; + zval *zheader; + zval *zget; + zval *zpost; + zval *zcookie; + zval *zrequest; + zval *zfiles; + zval *ztmpfiles; +#if PHP_MAJOR_VERSION >= 7 + zval _zobject; + zval _zrequest; + zval _zserver; + zval _zheader; + zval _zget; + zval _zpost; + zval _zfiles; + zval _zcookie; + zval _ztmpfiles; +#endif +} http_request; + +typedef struct +{ + enum php_http_method method; + int version; + int status; + zval *zobject; + zval *zheader; + zval *zcookie; + zval *ztrailer; + +#if PHP_MAJOR_VERSION >= 7 + zval _zobject; + zval _zheader; + zval _zcookie; + zval _ztrailer; +#endif +} http_response; + +typedef struct +{ + int fd; + + uint32_t end :1; + uint32_t send_header :1; + uint32_t gzip_enable :1; + uint32_t gzip_level :4; + uint32_t chunk :1; + uint32_t keepalive :1; + uint32_t http2 :1; + uint32_t upgrade :1; + uint32_t detached :1; + + uint32_t request_read :1; + uint32_t current_header_name_allocated :1; + uint32_t content_sender_initialized :1; + +#ifdef SW_USE_HTTP2 + uint8_t priority; + uint32_t stream_id; +#endif + + http_request request; + http_response response; + + php_http_parser parser; + multipart_parser *mt_parser; + struct _swoole_http_client *client; + + uint16_t input_var_num; + char *current_header_name; + size_t current_header_name_len; + char *current_input_name; + char *current_form_data_name; + size_t current_form_data_name_len; + char *current_form_data_value; + zval *current_multipart_header; + +} http_context; + +typedef struct _swoole_http_client +{ + int fd; + uint32_t http2 :1; + +#ifdef SW_USE_HTTP2 + uint32_t init :1; + swHashMap *streams; + nghttp2_hd_inflater *deflater; + nghttp2_hd_inflater *inflater; + uint32_t window_size; + uint32_t remote_window_size; +#endif + +} swoole_http_client; + +/** + * WebSocket + */ +int swoole_websocket_onMessage(swEventData *); +int swoole_websocket_onHandshake(swListenPort *port, http_context *); +void swoole_websocket_onOpen(http_context *); +void swoole_websocket_onRequest(http_context *); + +/** + * Http Context + */ +http_context* swoole_http_context_new(swoole_http_client* client TSRMLS_DC); +void swoole_http_context_free(http_context *ctx TSRMLS_DC); +int swoole_http_parse_form_data(http_context *ctx, const char *boundary_str, int boundary_len TSRMLS_DC); + +#define swoole_http_server_array_init(name, class) SW_MAKE_STD_ZVAL(z##name);\ +array_init(z##name);\ +zend_update_property(swoole_http_##class##_class_entry_ptr, z##class##_object, ZEND_STRL(#name), z##name TSRMLS_CC);\ +ctx->class.z##name = sw_zend_read_property(swoole_http_##class##_class_entry_ptr, z##class##_object, ZEND_STRL(#name), 0 TSRMLS_CC);\ +sw_copy_to_stack(ctx->class.z##name, ctx->class._z##name);\ +sw_zval_ptr_dtor(&z##name);\ +z##name = ctx->class.z##name; + +#define http_strncasecmp(const_str, at, length) ((length >= sizeof(const_str)-1) &&\ + (strncasecmp(at, ZEND_STRL(const_str)) == 0)) + +#ifdef SW_USE_HTTP2 +/** + * Http v2 + */ +int swoole_http2_onFrame(swoole_http_client *client, swEventData *req); +int swoole_http2_do_response(http_context *ctx, swString *body); +void swoole_http2_free(swoole_http_client *client); +#endif + +extern zend_class_entry swoole_http_server_ce; +extern zend_class_entry *swoole_http_server_class_entry_ptr; + +extern zend_class_entry swoole_http_response_ce; +extern zend_class_entry *swoole_http_response_class_entry_ptr; + +extern zend_class_entry swoole_http_request_ce; +extern zend_class_entry *swoole_http_request_class_entry_ptr; + +extern swString *swoole_http_buffer; +#ifdef SW_HAVE_ZLIB +extern swString *swoole_zlib_buffer; +#endif + +#endif /* SWOOLE_HTTP_H_ */ diff --git a/vendor/swoole/swoole_http_client.c b/vendor/swoole/swoole_http_client.c new file mode 100755 index 0000000..4d0a6de --- /dev/null +++ b/vendor/swoole/swoole_http_client.c @@ -0,0 +1,2131 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Fang <coooold@live.com> | + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http_client.h" + +static swString *http_client_buffer; + +static void http_client_onReceive(swClient *cli, char *data, uint32_t length); +static void http_client_onConnect(swClient *cli); +static void http_client_onClose(swClient *cli); +static void http_client_onError(swClient *cli); +static void http_client_onRequestTimeout(swTimer *timer, swTimer_node *tnode); +static void http_client_onResponseException(); +static int http_client_onMessage(swConnection *conn, char *data, uint32_t length); + +static int http_client_send_http_request(zval *zobject TSRMLS_DC); +static int http_client_execute(zval *zobject, char *uri, zend_size_t uri_len, zval *callback TSRMLS_DC); + +#ifdef SW_HAVE_ZLIB +int http_response_uncompress(z_stream *stream, swString *buffer, char *body, int length); +static void http_init_gzip_stream(http_client *); +extern voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size); +extern void php_zlib_free(voidpf opaque, voidpf address); +#endif + +static const php_http_parser_settings http_parser_settings = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + http_client_parser_on_header_field, + http_client_parser_on_header_value, + http_client_parser_on_headers_complete, + http_client_parser_on_body, + http_client_parser_on_message_complete +}; + +static zend_class_entry swoole_http_client_ce; +static zend_class_entry *swoole_http_client_class_entry_ptr; + +static PHP_METHOD(swoole_http_client, __construct); +static PHP_METHOD(swoole_http_client, __destruct); +static PHP_METHOD(swoole_http_client, set); +static PHP_METHOD(swoole_http_client, setMethod); +static PHP_METHOD(swoole_http_client, setHeaders); +static PHP_METHOD(swoole_http_client, setCookies); +static PHP_METHOD(swoole_http_client, setData); +static PHP_METHOD(swoole_http_client, addFile); +static PHP_METHOD(swoole_http_client, execute); +static PHP_METHOD(swoole_http_client, push); +static PHP_METHOD(swoole_http_client, isConnected); +static PHP_METHOD(swoole_http_client, close); +static PHP_METHOD(swoole_http_client, on); +static PHP_METHOD(swoole_http_client, get); +static PHP_METHOD(swoole_http_client, post); +static PHP_METHOD(swoole_http_client, upgrade); +static PHP_METHOD(swoole_http_client, download); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_construct, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, ssl) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_setMethod, 0, 0, 1) + ZEND_ARG_INFO(0, method) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_setHeaders, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, headers, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_setCookies, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, cookies, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_setData, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_addFile, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_execute, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_get, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_post, 0, 0, 3) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_download, 0, 0, 3) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, file) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_upgrade, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, opcode) + ZEND_ARG_INFO(0, finish) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_http_client_methods[] = +{ + PHP_ME(swoole_http_client, __construct, arginfo_swoole_http_client_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_http_client, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_http_client, set, arginfo_swoole_http_client_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, setMethod, arginfo_swoole_http_client_setMethod, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, setHeaders, arginfo_swoole_http_client_setHeaders, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, setCookies, arginfo_swoole_http_client_setCookies, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, setData, arginfo_swoole_http_client_setData, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, addFile, arginfo_swoole_http_client_addFile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, execute, arginfo_swoole_http_client_execute, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, push, arginfo_swoole_http_client_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, get, arginfo_swoole_http_client_get, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, post, arginfo_swoole_http_client_post, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, upgrade, arginfo_swoole_http_client_upgrade, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, download, arginfo_swoole_http_client_download, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, isConnected, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client, on, arginfo_swoole_http_client_on, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static int http_client_execute(zval *zobject, char *uri, zend_size_t uri_len, zval *callback TSRMLS_DC) +{ + if (uri_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "path is empty."); + return SW_ERR; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + return SW_ERR; + } + efree(func_name); + + http_client *http = swoole_get_object(zobject); + + //http is not null when keeping alive + if (http) + { + //http not ready + if (http->state != HTTP_CLIENT_STATE_READY) + { + //swWarn("fd=%d, state=%d, active=%d, keep_alive=%d", http->cli->socket->fd, http->state, http->cli->socket->active, http->keep_alive); + swoole_php_fatal_error(E_WARNING, "Operation now in progress phase %d.", http->state); + return SW_ERR; + } + else if (!http->cli->socket->active) + { + swoole_php_fatal_error(E_WARNING, "connection#%d is closed.", http->cli->socket->fd); + return SW_ERR; + } + } + else + { + php_swoole_check_reactor(); + http = http_client_create(zobject TSRMLS_CC); + } + + if (http == NULL) + { + return SW_ERR; + } + + if (http->body == NULL) + { + http->body = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (http->body == NULL) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + return SW_ERR; + } + } + else + { + swString_clear(http->body); + } + + if (http->uri) + { + efree(http->uri); + } + + http->uri = estrdup(uri); + http->uri_len = uri_len; + + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + swoole_php_fatal_error(E_WARNING, "response callback is not set."); + } + + http_client_property *hcc = swoole_get_property(zobject, 0); + sw_zval_add_ref(&callback); + hcc->onResponse = sw_zval_dup(callback); + + /** + * download response body + */ + if (hcc->download_file) + { + int fd = open(Z_STRVAL_P(hcc->download_file), O_CREAT | O_WRONLY, 0664); + if (fd < 0) + { + swSysError("open(%s, O_CREAT | O_WRONLY) failed.", Z_STRVAL_P(hcc->download_file)); + return SW_ERR; + } + if (hcc->download_offset == 0) + { + if (ftruncate(fd, 0) < 0) + { + swSysError("ftruncate(%s) failed.", Z_STRVAL_P(hcc->download_file)); + close(fd); + return SW_ERR; + } + } + else + { + if (lseek(fd, hcc->download_offset, SEEK_SET) < 0) + { + swSysError("fseek(%s, %ld) failed.", Z_STRVAL_P(hcc->download_file), hcc->download_offset); + close(fd); + return SW_ERR; + } + } + http->download = 1; + http->file_fd = fd; + } + + //if connection exists + if (http->cli) + { + http_client_send_http_request(zobject TSRMLS_CC); + return SW_OK; + } + + swClient *cli = php_swoole_client_new(zobject, http->host, http->host_len, http->port); + if (cli == NULL) + { + return SW_ERR; + } + http->cli = cli; + + zval *ztmp; + HashTable *vht; + zval *zset = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + vht = Z_ARRVAL_P(zset); + /** + * timeout + */ + if (php_swoole_array_get_value(vht, "timeout", ztmp)) + { + convert_to_double(ztmp); + http->timeout = (double) Z_DVAL_P(ztmp); + } + /** + * keep_alive + */ + if (php_swoole_array_get_value(vht, "keep_alive", ztmp)) + { + convert_to_boolean(ztmp); + http->keep_alive = Z_BVAL_P(ztmp); + } + /** + * websocket mask + */ + if (php_swoole_array_get_value(vht, "websocket_mask", ztmp)) + { + convert_to_boolean(ztmp); + http->websocket_mask = (int) Z_BVAL_P(ztmp); + } + //client settings + php_swoole_client_check_setting(http->cli, zset TSRMLS_CC); + + if (http->cli->http_proxy) + { + zval *send_header = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + if (send_header == NULL || Z_TYPE_P(send_header) != IS_ARRAY) + { + swoole_php_fatal_error (E_WARNING, "http proxy must set Host"); + return SW_ERR; + } + zval *value; + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value) == FAILURE || + Z_TYPE_P(value) != IS_STRING || Z_STRLEN_P(value) < 1) + { + swoole_php_fatal_error(E_WARNING, "http proxy must set Host"); + return SW_ERR; + } + if (http->cli->http_proxy->password) + { + char _buf1[128]; + char _buf2[256]; + int _n1 = snprintf(_buf1, sizeof(_buf1), "%*s:%*s", http->cli->http_proxy->l_user, + http->cli->http_proxy->user, http->cli->http_proxy->l_password, + http->cli->http_proxy->password); +#if PHP_MAJOR_VERSION < 7 + uchar *encoded_value = php_base64_encode((const unsigned char *) _buf1, _n1, NULL); + int _n2 = snprintf(_buf2, sizeof(_buf2), "Basic %*s", _n1, encoded_value); + add_assoc_stringl_ex(send_header, ZEND_STRS("Proxy-Authorization"), _buf2, _n2, 1); +#else + zend_string *str = php_base64_encode((const unsigned char *) _buf1, _n1); + int _n2 = snprintf(_buf2, sizeof(_buf2), "Basic %*s", str->len, str->val); + zend_string_free(str); + add_assoc_stringl_ex(send_header, ZEND_STRL("Proxy-Authorization"), _buf2, _n2); +#endif + } + } + } + + if (cli->socket->active == 1) + { + swoole_php_fatal_error(E_WARNING, "swoole_http_client is already connected."); + return SW_ERR; + } + + cli->object = zobject; + sw_copy_to_stack(cli->object, hcc->_object); + sw_zval_add_ref(&zobject); + + cli->open_eof_check = 0; + cli->open_length_check = 0; + cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; + cli->onReceive = http_client_onReceive; + cli->onConnect = http_client_onConnect; + cli->onClose = http_client_onClose; + cli->onError = http_client_onError; + + return cli->connect(cli, http->host, http->port, http->timeout, 0); +} + +void swoole_http_client_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_http_client_ce, "swoole_http_client", "Swoole\\Http\\Client", swoole_http_client_methods); + swoole_http_client_class_entry_ptr = zend_register_internal_class(&swoole_http_client_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http_client, "Swoole\\Http\\Client"); + + zend_declare_property_long(swoole_http_client_class_entry_ptr, SW_STRL("type")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_class_entry_ptr, SW_STRL("sock")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_class_entry_ptr, SW_STRL("statusCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("host")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_class_entry_ptr, SW_STRL("port")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("requestMethod")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("requestHeaders")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("requestBody")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("uploadFiles")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("set_cookie_headers")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("downloadFile")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("headers")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("cookies")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, SW_STRL("body")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_http_client_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, ZEND_STRL("onError"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, ZEND_STRL("onMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + + http_client_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!http_client_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + } + +#ifdef SW_HAVE_ZLIB + swoole_zlib_buffer = swString_new(2048); + if (!swoole_zlib_buffer) + { + swoole_php_fatal_error(E_ERROR, "[2] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + } +#endif +} + +static void http_client_execute_callback(zval *zobject, enum php_swoole_client_callback_type type) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *callback = NULL; + zval *retval = NULL; + zval **args[1]; + + http_client_property *hcc = swoole_get_property(zobject, 0); + if (!hcc) + { + return; + } + + char *callback_name; + switch(type) + { + case SW_CLIENT_CB_onConnect: + callback = hcc->onConnect; + callback_name = "onConnect"; + break; + case SW_CLIENT_CB_onError: + callback = hcc->onError; + callback_name = "onError"; + break; + case SW_CLIENT_CB_onClose: + callback = hcc->onClose; + callback_name = "onClose"; + break; + default: + return; + } + + args[0] = &zobject; + //request is not completed + if (hcc->onResponse && (type == SW_CLIENT_CB_onError || type == SW_CLIENT_CB_onClose)) + { + int error_code; + if (type == SW_CLIENT_CB_onError) + { + error_code = -1; + } + else if (hcc->request_timeout == 1) + { + error_code = -2; + } + else + { + error_code = -3; + } + + zend_update_property_long(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("statusCode"), error_code TSRMLS_CC); + zend_update_property_string(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("body"), "" TSRMLS_CC); + http_client_onResponseException(zobject TSRMLS_CC); + } + //callback function is not set + if (!callback || ZVAL_IS_NULL(callback)) + { + return; + } + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_http_client->%s handler error.", callback_name); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + //free the callback return value + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +/** + * @zobject: swoole_http_client object + */ +static void http_client_onClose(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zobject = cli->object; + http_client *http = swoole_get_object(zobject); + if (http && http->state == HTTP_CLIENT_STATE_WAIT_CLOSE) + { + http_client_parser_on_message_complete(&http->parser); + http_client_property *hcc = swoole_get_property(zobject, 0); + http_client_onResponseException(zobject TSRMLS_CC); + sw_zval_free(hcc->onResponse); + hcc->onResponse = NULL; + } + if (!cli->released) + { + http_client_free(zobject TSRMLS_CC); + } + http_client_execute_callback(zobject, SW_CLIENT_CB_onClose); + sw_zval_ptr_dtor(&zobject); +} + +static int http_client_onMessage(swConnection *conn, char *data, uint32_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + swClient *cli = conn->object; + zval *zobject = cli->object; + zval **args[2]; + zval *retval; + + zval *zframe; + SW_MAKE_STD_ZVAL(zframe); + php_swoole_websocket_unpack(cli->buffer, zframe TSRMLS_CC); + + args[0] = &zobject; + args[1] = &zframe; + + http_client_property *hcc = swoole_get_property(zobject, 0); + zval *zcallback = hcc->onMessage; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_ERROR, "swoole_http_client->onMessage: onClose handler error"); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + //free the callback return value + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zframe); + + return SW_OK; +} + +/** + * @zobject: swoole_http_client object + */ +static void http_client_onError(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zobject = cli->object; + zend_update_property_long(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); + if (!cli->released) + { + http_client_free(zobject TSRMLS_CC); + } + http_client_execute_callback(zobject, SW_CLIENT_CB_onError); + sw_zval_ptr_dtor(&zobject); +} + +static void http_client_onRequestTimeout(swTimer *timer, swTimer_node *tnode) +{ + swClient *cli = (swClient *) tnode->data; + zval *zobject = (zval *) cli->object; +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_client_property *hcc = swoole_get_property(zobject, 0); + if (!hcc) + { + return; + } + hcc->request_timeout = 1; + + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_http_client_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void http_client_onResponseException(zval *zobject TSRMLS_DC) +{ + zval **args[1]; + zval *retval = NULL; + + http_client_property *hcc = swoole_get_property(zobject, 0); + if (!hcc) + { + return; + } + if (!hcc->onResponse) + { + return; + } + hcc->shutdown = 1; + zval *zcallback = hcc->onResponse; + args[0] = &zobject; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onResponse handler error"); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void http_client_onReceive(swClient *cli, char *data, uint32_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = cli->object; + http_client *http = swoole_get_object(zobject); + if (!http->cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client."); + return; + } + + if (http->header_completed == 0) + { + swString *buffer = cli->buffer; + buffer->length += length; + + //HTTP/1.1 200 OK + if (buffer->length < 16) + { + return; + } + //No header + if (swoole_strnpos(buffer->str + buffer->offset, buffer->length - buffer->offset, ZEND_STRL("\r\n\r\n")) < 0) + { + if (buffer->length == buffer->size) + { + swSysError("Wrong http response."); + cli->close(cli); + return; + } + buffer->offset = buffer->length - 4 <= 0 ? 0 : buffer->length - 4; + return; + } + else + { + http->header_completed = 1; + data = buffer->str; + length = buffer->length; + swString_clear(buffer); + } + } + + long parsed_n = php_http_parser_execute(&http->parser, &http_parser_settings, data, length); + if (parsed_n < 0) + { + swSysError("Parsing http over socket[%d] failed.", cli->socket->fd); + cli->close(cli); + } + //not complete + if (!http->completed) + { + return; + } + + swConnection *conn = cli->socket; + zval *retval = NULL; + http_client_property *hcc = swoole_get_property(zobject, 0); + zval *zcallback = hcc->onResponse; + + zval **args[1]; + args[0] = &zobject; + + if (zcallback == NULL || ZVAL_IS_NULL(zcallback)) + { + swoole_php_fatal_error(E_WARNING, "swoole_http_client object have not receive callback."); + return; + } + /** + * TODO: Sec-WebSocket-Accept check + */ + if (http->upgrade) + { + cli->open_length_check = 1; + cli->protocol.get_package_length = swWebSocket_get_package_length; + cli->protocol.onPackage = http_client_onMessage; + cli->protocol.package_length_size = SW_WEBSOCKET_HEADER_LEN + SW_WEBSOCKET_MASK_LEN + sizeof(uint64_t); + http->state = HTTP_CLIENT_STATE_UPGRADE; + + //data frame + if (length > parsed_n) + { + cli->buffer->length = length - parsed_n - 1; + memmove(cli->buffer->str, data + parsed_n + 1, cli->buffer->length); + } + else + { + swString_clear(cli->buffer); + } + } + else if (http->keep_alive == 1) + { + http->state = HTTP_CLIENT_STATE_READY; + http->completed = 0; + } + if (http->download) + { + close(http->file_fd); + http->download = 0; + http->file_fd = 0; +#ifdef SW_HAVE_ZLIB + if (http->gzip_buffer) + { + swString_free(http->gzip_buffer); + http->gzip_buffer = NULL; + } +#endif + } +#ifdef SW_HAVE_ZLIB + if (http->gzip) + { + inflateEnd(&http->gzip_stream); + http->gzip = 0; + } +#endif + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } + hcc->onResponse = NULL; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onReactorCallback handler error"); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_free(zcallback); + if (conn->active == 0) + { + return; + } + http->header_completed = 0; + + if (http->upgrade && cli->buffer->length > 0) + { + cli->socket->skip_recv = 1; + swProtocol_recv_check_length(&cli->protocol, cli->socket, cli->buffer); + return; + } + + swString_clear(cli->buffer); + if (http->keep_alive == 0 && http->state != HTTP_CLIENT_STATE_WAIT_CLOSE) + { + sw_zend_call_method_with_0_params(&zobject, swoole_http_client_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } +} + +static void http_client_onConnect(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = cli->object; + http_client *http = swoole_get_object(zobject); + if (!http->cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client."); + return; + } + http_client_execute_callback(zobject, SW_CLIENT_CB_onConnect); + //send http request on write + http_client_send_http_request(zobject TSRMLS_CC); +} + +static int http_client_send_http_request(zval *zobject TSRMLS_DC) +{ + int ret; + http_client *http = swoole_get_object(zobject); + if (!http->cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client."); + return SW_ERR; + } + + if (!http->cli->socket && http->cli->socket->active == 0) + { + swoole_php_error(E_WARNING, "server is not connected."); + return SW_ERR; + } + + if (http->state != HTTP_CLIENT_STATE_READY) + { + swoole_php_error(E_WARNING, "http client is not ready."); + return SW_ERR; + } + + http->state = HTTP_CLIENT_STATE_BUSY; + //clear errno + SwooleG.error = 0; + + http_client_property *hcc = swoole_get_property(zobject, 0); + + zval *post_data = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody"), 1 TSRMLS_CC); + zval *send_header = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + + //POST + if (post_data && !ZVAL_IS_NULL(post_data)) + { + if (hcc->request_method == NULL) + { + hcc->request_method = "POST"; + } + } + //GET + else + { + if (hcc->request_method == NULL) + { + hcc->request_method = "GET"; + } + } + + http->method = swHttp_get_method(hcc->request_method, strlen(hcc->request_method) + 1); + + char *key; + uint32_t keylen; + int keytype; + zval *value = NULL; + + swString_clear(http_client_buffer); + swString_append_ptr(http_client_buffer, hcc->request_method, strlen(hcc->request_method)); + hcc->request_method = NULL; + swString_append_ptr(http_client_buffer, ZEND_STRL(" ")); +#ifdef SW_USE_OPENSSL + if (http->cli->http_proxy && !http->cli->open_ssl) +#else + if (http->cli->http_proxy) +#endif + { + sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value); //checked before + char *pre = "http://"; + int len = http->uri_len + Z_STRLEN_P(value) + strlen(pre) + 10; + void *addr = emalloc(http->uri_len + Z_STRLEN_P(value) + strlen(pre) + 10); + http->uri_len = snprintf(addr, len, "%s%s:%d%s", pre, Z_STRVAL_P(value), http->port, http->uri); + efree(http->uri); + http->uri = addr; + } + swString_append_ptr (http_client_buffer, http->uri, http->uri_len); + swString_append_ptr(http_client_buffer, ZEND_STRL(" HTTP/1.1\r\n")); + + if (send_header && Z_TYPE_P(send_header) == IS_ARRAY) + { + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Connection"), (void **) &value) == FAILURE) + { + if (http->keep_alive) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("keep-alive")); + } + else + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("closed")); + } + } + + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value) == FAILURE) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Host"), http->host, http->host_len); + } + +#ifdef SW_HAVE_ZLIB + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Accept-Encoding"), (void **) &value) == FAILURE) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Accept-Encoding"), ZEND_STRL("gzip")); + } +#endif + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(send_header), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + if (Z_STRLEN_P(value) == 0) + { + continue; + } + http_client_swString_append_headers(http_client_buffer, key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + SW_HASHTABLE_FOREACH_END(); + } + else + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("keep-alive")); + http->keep_alive = 1; + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Host"), http->host, http->host_len); +#ifdef SW_HAVE_ZLIB + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Accept-Encoding"), ZEND_STRL("gzip")); +#endif + } + + zval *cookies = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), 1 TSRMLS_CC); + if (cookies && Z_TYPE_P(cookies) == IS_ARRAY) + { + swString_append_ptr(http_client_buffer, ZEND_STRL("Cookie: ")); + int n_cookie = Z_ARRVAL_P(cookies)->nNumOfElements; + int i = 0; + char *encoded_value; + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(cookies), key, keylen, keytype, value) + i ++; + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + if (Z_STRLEN_P(value) == 0) + { + continue; + } + swString_append_ptr(http_client_buffer, key, keylen); + swString_append_ptr(http_client_buffer, "=", 1); + + int encoded_value_len; + encoded_value = sw_php_url_encode( Z_STRVAL_P(value), Z_STRLEN_P(value), &encoded_value_len); + if (encoded_value) + { + swString_append_ptr(http_client_buffer, encoded_value, encoded_value_len); + efree(encoded_value); + } + if (i < n_cookie) + { + swString_append_ptr(http_client_buffer, "; ", 2); + } + SW_HASHTABLE_FOREACH_END(); + swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + } + + //form-data + if (hcc->request_upload_files) + { + char header_buf[2048]; + char boundary_str[39]; + int n; + + memcpy(boundary_str, SW_HTTP_CLIENT_BOUNDARY_PREKEY, sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY) - 1); + swoole_random_string(boundary_str + sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY) - 1, + sizeof(boundary_str) - sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY)); + + n = snprintf(header_buf, sizeof(header_buf), "Content-Type: multipart/form-data; boundary=%*s\r\n", + sizeof(boundary_str) - 1, boundary_str); + + swString_append_ptr(http_client_buffer, header_buf, n); + + int content_length = 0; + + //post data + if (Z_TYPE_P(post_data) == IS_ARRAY && php_swoole_array_length(post_data) > 0) + { + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(post_data), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + //strlen("%.*")*2 = 6 + //header + body + CRLF + content_length += (sizeof(SW_HTTP_FORM_DATA_FORMAT_STRING) - 7) + (sizeof(boundary_str) - 1) + keylen + + Z_STRLEN_P(value) + 2; + SW_HASHTABLE_FOREACH_END(); + } + + zval *zname; + zval *ztype; + zval *zsize = NULL; + zval *zpath; + zval *zfilename; + zval *zoffset; + + if (hcc->request_upload_files) + { + //upload files + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(hcc->request_upload_files), key, keylen, keytype, value) + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("name"), (void **) &zname) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("filename"), (void **) &zfilename) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("size"), (void **) &zsize) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("type"), (void **) &ztype) == FAILURE) + { + continue; + } + //strlen("%.*")*4 = 12 + //header + body + CRLF + content_length += (sizeof(SW_HTTP_FORM_DATA_FORMAT_FILE) - 13) + (sizeof(boundary_str) - 1) + + Z_STRLEN_P(zname) + Z_STRLEN_P(zfilename) + Z_STRLEN_P(ztype) + Z_LVAL_P(zsize) + 2; + SW_HASHTABLE_FOREACH_END(); + } + + http_client_append_content_length(http_client_buffer, content_length + sizeof(boundary_str) - 1 + 6); + + //post data + if (Z_TYPE_P(post_data) == IS_ARRAY && php_swoole_array_length(post_data) > 0) + { + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(post_data), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + n = snprintf(header_buf, sizeof(header_buf), SW_HTTP_FORM_DATA_FORMAT_STRING, sizeof(boundary_str) - 1, + boundary_str, keylen, key); + swString_append_ptr(http_client_buffer, header_buf, n); + swString_append_ptr(http_client_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value)); + swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + SW_HASHTABLE_FOREACH_END(); + + //cleanup request body + zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + } + + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + goto send_fail; + } + + if (hcc->request_upload_files) + { + //upload files + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(hcc->request_upload_files), key, keylen, keytype, value) + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("name"), (void **) &zname) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("filename"), (void **) &zfilename) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("path"), (void **) &zpath) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("size"), (void **) &zsize) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("type"), (void **) &ztype) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("offset"), (void **) &zoffset) == FAILURE) + { + continue; + } + + n = snprintf(header_buf, sizeof(header_buf), SW_HTTP_FORM_DATA_FORMAT_FILE, sizeof(boundary_str) - 1, + boundary_str, Z_STRLEN_P(zname), Z_STRVAL_P(zname), Z_STRLEN_P(zfilename), + Z_STRVAL_P(zfilename), Z_STRLEN_P(ztype), Z_STRVAL_P(ztype)); + + if ((ret = http->cli->send(http->cli, header_buf, n, 0)) < 0) + { + goto send_fail; + } + if ((ret = http->cli->sendfile(http->cli, Z_STRVAL_P(zpath), Z_LVAL_P(zoffset), Z_LVAL_P(zsize))) < 0) + { + goto send_fail; + } + if ((ret = http->cli->send(http->cli, "\r\n", 2, 0)) < 0) + { + goto send_fail; + } + SW_HASHTABLE_FOREACH_END(); + + zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("uploadFiles") TSRMLS_CC); + hcc->request_upload_files = NULL; + } + + n = snprintf(header_buf, sizeof(header_buf), "--%*s--\r\n", sizeof(boundary_str) - 1, boundary_str); + if ((ret = http->cli->send(http->cli, header_buf, n, 0)) < 0) + { + goto send_fail; + } + } + //x-www-form-urlencoded or raw + else if (post_data && !ZVAL_IS_NULL(post_data)) + { + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + zend_size_t len; + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Content-Type"), ZEND_STRL("application/x-www-form-urlencoded")); + if (php_swoole_array_length(post_data) > 0) //if it's an empty array, http build will fail + { + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return SW_ERR; + } + http_client_append_content_length(http_client_buffer, len); + swString_append_ptr(http_client_buffer, formstr, len); + smart_str_free(&formstr_s); + } + else + { + http_client_append_content_length(http_client_buffer, 0); + } + //send http header and body + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + goto send_fail; + } + //cleanup request body + zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + } + else if (Z_TYPE_P(post_data) == IS_STRING && Z_STRLEN_P(post_data) > 0) + { + http_client_append_content_length(http_client_buffer, Z_STRLEN_P(post_data)); + //send http header + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + goto send_fail; + } + //send http body + if ((ret = http->cli->send(http->cli, Z_STRVAL_P(post_data), Z_STRLEN_P(post_data), 0)) < 0) + { + goto send_fail; + } + //cleanup request body + zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + } + else + { + //cleanup request body + zend_update_property_null(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + goto append_crlf; + } + } + //no body + else + { + append_crlf: swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + send_fail: + SwooleG.error = errno; + swoole_php_sys_error(E_WARNING, "send(%d) %d bytes failed.", http->cli->socket->fd, (int )http_client_buffer->length); + zend_update_property_long(swoole_http_client_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + return SW_ERR; + } + } + + if (http->timeout > 0) + { + php_swoole_check_timer((int) (http->timeout * 1000)); + http->timer = SwooleG.timer.add(&SwooleG.timer, (int) (http->timeout * 1000), 0, http->cli, http_client_onRequestTimeout); + } + + swTrace("[%d]: %s\n", (int) http_client_buffer->length, http_client_buffer->str); + + return ret; +} + +void http_client_free(zval *object TSRMLS_DC) +{ + http_client *http = swoole_get_object(object); + if (!http) + { + return; + } + if (http->uri) + { + efree(http->uri); + } + if (http->body) + { + swString_free(http->body); + } + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } +#ifdef SW_HAVE_ZLIB + if (http->gzip) + { + inflateEnd(&http->gzip_stream); + http->gzip = 0; + } +#endif + swClient *cli = http->cli; + if (cli) + { + php_swoole_client_free(object, cli TSRMLS_CC); + http->cli = NULL; + } + efree(http); + + swTraceLog(SW_TRACE_HTTP_CLIENT, "free, object handle=%d.", sw_get_object_handle(object)); +} + +http_client* http_client_create(zval *object TSRMLS_DC) +{ + zval *ztmp; + http_client *http; + + http = (http_client*) emalloc(sizeof(http_client)); + bzero(http, sizeof(http_client)); + + swoole_set_object(object, http); + + php_http_parser_init(&http->parser, PHP_HTTP_RESPONSE); + http->parser.data = http; + + ztmp = sw_zend_read_property(swoole_http_client_class_entry_ptr, object, ZEND_STRL("host"), 0 TSRMLS_CC); + http->host = Z_STRVAL_P(ztmp); + http->host_len = Z_STRLEN_P(ztmp); + + ztmp = sw_zend_read_property(swoole_http_client_class_entry_ptr, object, ZEND_STRL("port"), 0 TSRMLS_CC); + convert_to_long(ztmp); + http->port = Z_LVAL_P(ztmp); + + http->timeout = SW_CLIENT_DEFAULT_TIMEOUT; + http->keep_alive = 1; + http->state = HTTP_CLIENT_STATE_READY; + + swTraceLog(SW_TRACE_HTTP_CLIENT, "create, object handle=%d.", sw_get_object_handle(object)); + + return http; +} + +static PHP_METHOD(swoole_http_client, __construct) +{ + char *host; + zend_size_t host_len; + long port = 80; + zend_bool ssl = SW_FALSE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &host, &host_len, &port, &ssl) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + swoole_php_fatal_error(E_ERROR, "host is empty."); + RETURN_FALSE; + } + + if (port <= 0 || port > SW_CLIENT_MAX_PORT) + { + swoole_php_fatal_error(E_ERROR, "invalid port."); + RETURN_FALSE; + } + + zend_update_property_stringl(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("host"), host, host_len TSRMLS_CC); + zend_update_property_long(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("port"), port TSRMLS_CC); + + //init + swoole_set_object(getThis(), NULL); + + zval *headers; + SW_MAKE_STD_ZVAL(headers); + array_init(headers); + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("headers"), headers TSRMLS_CC); + sw_zval_ptr_dtor(&headers); + + http_client_property *hcc; + hcc = (http_client_property*) emalloc(sizeof(http_client_property)); + bzero(hcc, sizeof(http_client_property)); + swoole_set_property(getThis(), 0, hcc); + + int flags = SW_SOCK_TCP | SW_FLAG_ASYNC; + + if (ssl) + { +#ifdef SW_USE_OPENSSL + flags |= SW_SOCK_SSL; +#else + swoole_php_fatal_error(E_ERROR, "require openssl library."); +#endif + } + + zend_update_property_long(swoole_client_class_entry_ptr, getThis(), ZEND_STRL("type"), flags TSRMLS_CC); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, __destruct) +{ + http_client *http = swoole_get_object(getThis()); + if (http && http->cli && http->cli->released == 0) + { + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_http_client_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc) + { + if (hcc->onResponse) + { + sw_zval_free(hcc->onResponse); + hcc->onResponse = NULL; + } + efree(hcc); + swoole_set_property(getThis(), 0, NULL); + } +} + +static PHP_METHOD(swoole_http_client, set) +{ + zval *zset; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + + zval *zsetting = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, setHeaders) +{ + zval *headers; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &headers) == FAILURE) + { + return; + } + + zval *headers_property = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(headers_property), Z_ARRVAL_P(headers)); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, setCookies) +{ + zval *cookies; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &cookies) == FAILURE) + { + return; + } + + zval *cookies_property = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("cookies") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(cookies_property), Z_ARRVAL_P(cookies)); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, setData) +{ + zval *data; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &data) == FAILURE) + { + return; + } + if (http_client_check_data(data TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + if (Z_TYPE_P(data) == IS_ARRAY) + { + zval *data_property = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestBody") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(data_property), Z_ARRVAL_P(data)); + } + else + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), data TSRMLS_CC); + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, addFile) +{ + char *path; + zend_size_t l_path; + char *name; + zend_size_t l_name; + char *type = NULL; + zend_size_t l_type; + char *filename = NULL; + zend_size_t l_filename; + long offset = 0; + long length = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ssll", &path, &l_path, &name, &l_name, &type, &l_type, + &filename, &l_filename, &offset, &length) == FAILURE) + { + return; + } + if (offset < 0) + { + offset = 0; + } + if (length < 0) + { + length = 0; + } + struct stat file_stat; + if (stat(path, &file_stat) < 0) + { + swoole_php_sys_error(E_WARNING, "stat(%s) failed.", path); + RETURN_FALSE; + } + if (file_stat.st_size == 0) + { + swoole_php_sys_error(E_WARNING, "cannot send empty file[%s].", filename); + RETURN_FALSE; + } + if (file_stat.st_size <= offset) + { + swoole_php_error(E_WARNING, "parameter $offset[%ld] exceeds the file size.", offset); + RETURN_FALSE; + } + if (length > file_stat.st_size - offset) + { + swoole_php_sys_error(E_WARNING, "parameter $length[%ld] exceeds the file size.", length); + RETURN_FALSE; + } + if (length == 0) + { + length = file_stat.st_size - offset; + } + if (type == NULL) + { + type = swoole_get_mimetype(path); + l_type = strlen(type); + } + if (filename == NULL) + { + char *dot = strrchr(path, '/'); + if (dot == NULL) + { + filename = path; + l_filename = l_path; + } + else + { + filename = dot + 1; + l_filename = strlen(filename); + } + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + zval *files; + if (!hcc->request_upload_files) + { + SW_MAKE_STD_ZVAL(files); + array_init(files); + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("uploadFiles"), files TSRMLS_CC); + sw_zval_ptr_dtor(&files); + + hcc->request_upload_files = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("uploadFiles"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->request_upload_files, hcc->_request_upload_files); + } + + zval *upload_file; + SW_MAKE_STD_ZVAL(upload_file); + array_init(upload_file); + + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("path"), path, l_path, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("name"), name, l_name, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("filename"), filename, l_filename, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("type"), type, l_type, 1); + add_assoc_long(upload_file, "size", length); + add_assoc_long(upload_file, "offset", offset); + + add_next_index_zval(hcc->request_upload_files, upload_file); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, setMethod) +{ + char *method; + zend_size_t length = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &length) == FAILURE) + { + return; + } + + int http_method = swHttp_get_method(method, length + 1); + if (length == 0 || http_method < 0) + { + swoole_php_error(E_WARNING, "invalid http method."); + RETURN_FALSE; + } + + const char *http_method_str = swHttp_get_method_string(http_method); + if (http_method_str == NULL) + { + RETURN_FALSE; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + hcc->request_method = (char *) http_method_str; + zend_update_property_string(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestMethod"), + (char *) http_method_str TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client, isConnected) +{ + http_client *http = swoole_get_object(getThis()); + if (!http || !http->cli) + { + RETURN_FALSE; + } + if (!http->cli->socket) + { + RETURN_FALSE; + } + RETURN_BOOL(http->cli->socket->active); +} + +static PHP_METHOD(swoole_http_client, close) +{ + http_client *http = swoole_get_object(getThis()); + if (!http) + { + RETURN_FALSE; + } + swClient *cli = http->cli; + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client."); + RETURN_FALSE; + } + if (!cli->socket) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + if (cli->socket->closed) + { + swoole_php_error(E_WARNING, "client socket is closed."); + RETURN_FALSE; + } + int ret = SW_OK; + if (!cli->keep || swConnection_error(SwooleG.error) == SW_CLOSE) + { + cli->released = 1; + ret = cli->close(cli); + http_client_free(getThis() TSRMLS_CC); + } + else + { + //unset object + swoole_set_object(getThis(), NULL); + } + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, on) +{ + char *cb_name; + zend_size_t cb_name_len; + zval *zcallback; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &cb_name, &cb_name_len, &zcallback) == FAILURE) + { + return; + } + +#ifdef PHP_SWOOLE_CHECK_CALLBACK + char *func_name = NULL; + if (!sw_zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (strncasecmp("error", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onError"), zcallback TSRMLS_CC); + hcc->onError = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onError"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->onError, hcc->_onError); + } + else if (strncasecmp("connect", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), zcallback TSRMLS_CC); + hcc->onConnect = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->onConnect, hcc->_onConnect); + } + else if (strncasecmp("close", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onClose"), zcallback TSRMLS_CC); + hcc->onClose = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onClose"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->onClose, hcc->_onClose); + } + else if (strncasecmp("message", cb_name, cb_name_len) == 0) + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), zcallback TSRMLS_CC); + hcc->onMessage = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->onMessage, hcc->_onMessage); + } + else + { + swoole_php_fatal_error(E_WARNING, "swoole_http_client: event callback[%s] is unknow", cb_name); + RETURN_FALSE; + } + RETURN_TRUE; +} + +int http_client_parser_on_header_field(php_http_parser *parser, const char *at, size_t length) +{ + http_client* http = (http_client*) parser->data; + http->tmp_header_field_name = (char *) at; + http->tmp_header_field_name_len = length; + return 0; +} + +int http_client_parser_on_header_value(php_http_parser *parser, const char *at, size_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_client* http = (http_client*) parser->data; + + zval* zobject = (zval*) http->cli->object; + zval *headers = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("headers"), 0 TSRMLS_CC); + + char *header_name = zend_str_tolower_dup(http->tmp_header_field_name, http->tmp_header_field_name_len); + sw_add_assoc_stringl_ex(headers, header_name, http->tmp_header_field_name_len + 1, (char *) at, length, 1); + + //websocket client + if (strcasecmp(header_name, "Upgrade") == 0 && strncasecmp(at, "websocket", length) == 0) + { + http->upgrade = 1; + } + else if (strcasecmp(header_name, "Set-Cookie") == 0) + { + int l_cookie = 0; + char *p = (char*) memchr(at, ';', length); + if (p) + { + l_cookie = p - at; + } + else + { + l_cookie = length; + } + + p = (char*) memchr(at, '=', length); + int l_key = 0; + if (p) + { + l_key = p - at; + } + if (l_key == 0 || l_key >= SW_HTTP_COOKIE_KEYLEN || l_key >= length - 1) + { + swWarn("cookie key format is wrong."); + efree(header_name); + return SW_ERR; + } + + char keybuf[SW_HTTP_COOKIE_KEYLEN]; + + zval *cookies = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), 1 TSRMLS_CC); + if (!cookies || ZVAL_IS_NULL(cookies)) + { + SW_MAKE_STD_ZVAL(cookies); + array_init(cookies); + zend_update_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), cookies TSRMLS_CC); + sw_zval_ptr_dtor(&cookies); + cookies = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), 1 TSRMLS_CC); + } + + zval *set_cookie_headers = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("set_cookie_headers"), 1 TSRMLS_CC); + if (!set_cookie_headers || ZVAL_IS_NULL(set_cookie_headers)) + { + SW_MAKE_STD_ZVAL(set_cookie_headers); + array_init(set_cookie_headers); + zend_update_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("set_cookie_headers"), set_cookie_headers TSRMLS_CC); + sw_zval_ptr_dtor(&set_cookie_headers); + set_cookie_headers = sw_zend_read_property(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("set_cookie_headers"), 1 TSRMLS_CC); + } + + memcpy(keybuf, at, l_key); + keybuf[l_key] = '\0'; + sw_add_assoc_stringl_ex(cookies, keybuf, l_key + 1, (char*) at + l_key + 1, l_cookie - l_key - 1, 1); + sw_add_assoc_stringl_ex(set_cookie_headers, keybuf, l_key + 1, (char*) at, length, 1); + } +#ifdef SW_HAVE_ZLIB + else if (strcasecmp(header_name, "Content-Encoding") == 0 && strncasecmp(at, "gzip", length) == 0) + { + http_init_gzip_stream(http); + if (Z_OK != inflateInit2(&http->gzip_stream, MAX_WBITS + 16)) + { + efree(header_name); + swWarn("inflateInit2() failed."); + return SW_ERR; + } + } + else if (strcasecmp(header_name, "Content-Encoding") == 0 && strncasecmp(at, "deflate", length) == 0) + { + http_init_gzip_stream(http); + if (Z_OK != inflateInit(&http->gzip_stream)) + { + efree(header_name); + swWarn("inflateInit() failed."); + return SW_ERR; + } + } +#endif + else if (strcasecmp(header_name, "Transfer-Encoding") == 0 && strncasecmp(at, "chunked", length) == 0) + { + http->chunked = 1; + } + efree(header_name); + return 0; +} + +#ifdef SW_HAVE_ZLIB +/** + * init zlib stream + */ +static void http_init_gzip_stream(http_client *http) +{ + http->gzip = 1; + memset(&http->gzip_stream, 0, sizeof(http->gzip_stream)); + if (http->download) + { + http->gzip_buffer = swString_new(8192); + } + else + { + http->gzip_buffer = swoole_zlib_buffer; + } + http->gzip_stream.zalloc = php_zlib_alloc; + http->gzip_stream.zfree = php_zlib_free; +} + +int http_response_uncompress(z_stream *stream, swString *buffer, char *body, int length) +{ + int status = 0; + + stream->avail_in = length; + stream->next_in = (Bytef *) body; + stream->total_in = 0; + stream->total_out = 0; + +#if 0 + printf(SW_START_LINE"\nstatus=%d\tavail_in=%ld,\tavail_out=%ld,\ttotal_in=%ld,\ttotal_out=%ld\n", status, + stream->avail_in, stream->avail_out, stream->total_in, stream->total_out); +#endif + + swString_clear(buffer); + + while (1) + { + stream->avail_out = buffer->size - buffer->length; + stream->next_out = (Bytef *) (buffer->str + buffer->length); + + status = inflate(stream, Z_SYNC_FLUSH); + +#if 0 + printf("status=%d\tavail_in=%ld,\tavail_out=%ld,\ttotal_in=%ld,\ttotal_out=%ld,\tlength=%ld\n", status, + stream->avail_in, stream->avail_out, stream->total_in, stream->total_out, buffer->length); +#endif + if (status >= 0) + { + buffer->length = stream->total_out; + } + if (status == Z_STREAM_END) + { + return SW_OK; + } + else if (status == Z_OK) + { + if (buffer->length + 4096 >= buffer->size) + { + if (swString_extend(buffer, buffer->size * 2) < 0) + { + return SW_ERR; + } + } + if (stream->avail_in == 0) + { + return SW_OK; + } + } + else + { + return SW_ERR; + } + } + return SW_ERR; +} +#endif + +int http_client_parser_on_body(php_http_parser *parser, const char *at, size_t length) +{ + http_client* http = (http_client*) parser->data; + if (swString_append_ptr(http->body, (char *) at, length) < 0) + { + return -1; + } + if (http->download) + { +#ifdef SW_HAVE_ZLIB + if (http->gzip) + { + if (http_response_uncompress(&http->gzip_stream, http->gzip_buffer, http->body->str, http->body->length)) + { + return -1; + } + if (swoole_sync_writefile(http->file_fd, http->gzip_buffer->str, http->gzip_buffer->length) < 0) + { + return -1; + } + } + else +#endif + { + if (swoole_sync_writefile(http->file_fd, (void*) http->body->str, http->body->length) < 0) + { + return -1; + } + } + swString_clear(http->body); + } + return 0; +} + +int http_client_parser_on_headers_complete(php_http_parser *parser) +{ + http_client* http = (http_client*) parser->data; + //no content-length + if (http->chunked == 0 && parser->content_length == -1) + { + http->state = HTTP_CLIENT_STATE_WAIT_CLOSE; + } + if (http->method == HTTP_HEAD) + { + return 1; + } + return 0; +} + +int http_client_parser_on_message_complete(php_http_parser *parser) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_client* http = (http_client*) parser->data; + zval* zobject = (zval*) http->cli->object; + +#ifdef SW_HAVE_ZLIB + if (http->gzip && http->body->length > 0) + { + if (http_response_uncompress(&http->gzip_stream, http->gzip_buffer, http->body->str, http->body->length) == SW_ERR) + { + swWarn("http_response_uncompress failed."); + return 0; + } + zend_update_property_stringl(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("body"), http->gzip_buffer->str, http->gzip_buffer->length TSRMLS_CC); + } + else +#endif + { + zend_update_property_stringl(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("body"), http->body->str, http->body->length TSRMLS_CC); + } + + http->completed = 1; + + //http status code + zend_update_property_long(swoole_http_client_class_entry_ptr, zobject, ZEND_STRL("statusCode"), http->parser.status_code TSRMLS_CC); + + return 0; +} + +static PHP_METHOD(swoole_http_client, execute) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *finish_cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &uri, &uri_len, &finish_cb) == FAILURE) + { + return; + } + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->shutdown) + { + swoole_php_error(E_WARNING, "Connection failed, the server was unavailable."); + return; + } + ret = http_client_execute(getThis(), uri, uri_len, finish_cb TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, get) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *finish_cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &uri, &uri_len, &finish_cb) == FAILURE) + { + return; + } + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->shutdown) + { + swoole_php_error(E_WARNING, "Connection failed, the server was unavailable."); + return; + } + ret = http_client_execute(getThis(), uri, uri_len, finish_cb TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, download) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *finish_cb; + zval *download_file; + off_t offset = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz|l", &uri, &uri_len, &download_file, &finish_cb, &offset) == FAILURE) + { + return; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->shutdown) + { + swoole_php_error(E_WARNING, "Connection failed, the server was unavailable."); + return; + } + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("downloadFile"), download_file TSRMLS_CC); + hcc->download_file = sw_zend_read_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("downloadFile"), 1 TSRMLS_CC); + hcc->download_offset = offset; + sw_copy_to_stack(hcc->download_file, hcc->_download_file); + ret = http_client_execute(getThis(), uri, uri_len, finish_cb TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, post) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *callback; + zval *data; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szz", &uri, &uri_len, &data, &callback) == FAILURE) + { + return; + } + if (http_client_check_data(data TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->shutdown) + { + swoole_php_error(E_WARNING, "Connection failed, the server was unavailable."); + return; + } + if (Z_TYPE_P(data) == IS_ARRAY) + { + zval *data_property = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestBody") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(data_property), Z_ARRVAL_P(data)); + } + else + { + zend_update_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), data TSRMLS_CC); + } + ret = http_client_execute(getThis(), uri, uri_len, callback TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, upgrade) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *finish_cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &uri, &uri_len, &finish_cb) == FAILURE) + { + return; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->shutdown) + { + swoole_php_error(E_WARNING, "Connection failed, the server was unavailable."); + return; + } + if (!hcc->onMessage) + { + swoole_php_fatal_error(E_WARNING, "cannot use the upgrade method, must first register the onMessage event callback."); + return; + } + + zval *headers = php_swoole_read_init_property(swoole_http_client_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders") TSRMLS_CC); + + char buf[SW_WEBSOCKET_KEY_LENGTH + 1]; + http_client_create_token(SW_WEBSOCKET_KEY_LENGTH, buf); + + sw_add_assoc_string(headers, "Connection", "Upgrade", 1); + sw_add_assoc_string(headers, "Upgrade", "websocket", 1); + sw_add_assoc_string(headers, "Sec-WebSocket-Version", SW_WEBSOCKET_VERSION, 1); + +#if PHP_MAJOR_VERSION < 7 + int encoded_value_len = 0; + uchar *encoded_value = php_base64_encode((const unsigned char *) buf, SW_WEBSOCKET_KEY_LENGTH, &encoded_value_len); + add_assoc_stringl_ex(headers, ZEND_STRS("Sec-WebSocket-Key"), (char* )encoded_value, encoded_value_len, 0); +#else + zend_string *str = php_base64_encode((const unsigned char *) buf, SW_WEBSOCKET_KEY_LENGTH); + add_assoc_str_ex(headers, ZEND_STRL("Sec-WebSocket-Key"), str); +#endif + + ret = http_client_execute(getThis(), uri, uri_len, finish_cb TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client, push) +{ + char *data; + zend_size_t length; + long opcode = WEBSOCKET_OPCODE_TEXT_FRAME; + zend_bool fin = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &data, &length, &opcode, &fin) == FAILURE) + { + return; + } + + if (opcode > WEBSOCKET_OPCODE_PONG) + { + swoole_php_fatal_error(E_WARNING, "opcode max 10"); + SwooleG.error = SW_ERROR_WEBSOCKET_BAD_OPCODE; + RETURN_FALSE; + } + + http_client *http = swoole_get_object(getThis()); + if (!(http && http->cli && http->cli->socket)) + { + swoole_php_error(E_WARNING, "not connected to the server"); + SwooleG.error = SW_ERROR_WEBSOCKET_UNCONNECTED; + RETURN_FALSE; + } + + if (!http->upgrade) + { + swoole_php_fatal_error(E_WARNING, "websocket handshake failed, cannot push data."); + SwooleG.error = SW_ERROR_WEBSOCKET_HANDSHAKE_FAILED; + RETURN_FALSE; + } + + swString_clear(http_client_buffer); + swWebSocket_encode(http_client_buffer, data, length, opcode, (int) fin, http->websocket_mask); + SW_CHECK_RETURN(http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)); +} diff --git a/vendor/swoole/swoole_http_client.h b/vendor/swoole/swoole_http_client.h new file mode 100755 index 0000000..2fe5f20 --- /dev/null +++ b/vendor/swoole/swoole_http_client.h @@ -0,0 +1,201 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SWOOLE_HTTP_CLIENT_H_ +#define SWOOLE_HTTP_CLIENT_H_ + +#include "ext/standard/basic_functions.h" +#include "ext/standard/php_http.h" +#include "ext/standard/base64.h" + +#include "websocket.h" +#include "thirdparty/php_http_parser.h" + +#ifdef SW_HAVE_ZLIB +#include <zlib.h> +#endif + +enum http_client_state +{ + HTTP_CLIENT_STATE_WAIT, + HTTP_CLIENT_STATE_READY, + HTTP_CLIENT_STATE_BUSY, + //WebSocket + HTTP_CLIENT_STATE_UPGRADE, + HTTP_CLIENT_STATE_WAIT_CLOSE, + HTTP_CLIENT_STATE_CLOSED, +}; + +#ifdef SW_COROUTINE +typedef enum +{ + HTTP_CLIENT_STATE_DEFER_INIT, + HTTP_CLIENT_STATE_DEFER_SEND, + HTTP_CLIENT_STATE_DEFER_WAIT, + HTTP_CLIENT_STATE_DEFER_DONE, +} http_client_defer_state; +#endif + +typedef struct +{ + zval *onConnect; + zval *onError; + zval *onClose; + zval *onMessage; + zval *onResponse; + +#if PHP_MAJOR_VERSION >= 7 + zval _object; + zval _request_body; + zval _request_header; + zval _request_upload_files; + zval _download_file; + zval _cookies; + zval _onConnect; + zval _onError; + zval _onClose; + zval _onMessage; +#endif + + zval *cookies; + zval *request_header; + zval *request_body; + zval *request_upload_files; + zval *download_file; + off_t download_offset; + char *request_method; + int callback_index; + + double request_timeout; + + uint8_t shutdown; + +#ifdef SW_COROUTINE + zend_bool defer; //0 normal 1 wait for receive + zend_bool defer_result;//0 + zend_bool defer_chunk_status;// 0 1 now use rango http->complete + zend_bool send_yield; + http_client_defer_state defer_status; + int cid; + /** + * for websocket + */ + swLinkedList *message_queue; +#endif + +} http_client_property; + +typedef struct +{ + swClient *cli; + char *host; + zend_size_t host_len; + long port; + double timeout; + char* uri; + zend_size_t uri_len; + + swTimer_node *timer; + + char *tmp_header_field_name; + int tmp_header_field_name_len; + +#ifdef SW_HAVE_ZLIB + z_stream gzip_stream; + swString *gzip_buffer; +#endif + + /** + * download page + */ + int file_fd; + + php_http_parser parser; + + swString *body; + + uint8_t state; //0 wait 1 ready 2 busy + uint8_t keep_alive; //0 no 1 keep + uint8_t upgrade; + uint8_t gzip; + uint8_t chunked; //Transfer-Encoding: chunked + uint8_t completed; + uint8_t websocket_mask; + uint8_t download; //save http response to file + uint8_t header_completed; + int8_t method; + +} http_client; + +int http_client_parser_on_header_field(php_http_parser *parser, const char *at, size_t length); +int http_client_parser_on_header_value(php_http_parser *parser, const char *at, size_t length); +int http_client_parser_on_body(php_http_parser *parser, const char *at, size_t length); +int http_client_parser_on_headers_complete(php_http_parser *parser); +int http_client_parser_on_message_complete(php_http_parser *parser); + +http_client* http_client_create(zval *object TSRMLS_DC); +void http_client_free(zval *object TSRMLS_DC); + +static sw_inline void http_client_create_token(int length, char *buf) +{ + char characters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"§$%&/()=[]{}"; + int i; + assert(length < 1024); + for (i = 0; i < length; i++) + { + buf[i] = characters[rand() % (sizeof(characters) - 1)]; + } + buf[length] = '\0'; +} + +static sw_inline int http_client_check_data(zval *data TSRMLS_DC) +{ + if (Z_TYPE_P(data) != IS_ARRAY && Z_TYPE_P(data) != IS_STRING) + { + swoole_php_error(E_WARNING, "parameter $data must be an array or string."); + return SW_ERR; + } + else if (Z_TYPE_P(data) == IS_ARRAY && php_swoole_array_length(data) == 0) + { + swoole_php_error(E_WARNING, "parameter $data is empty."); + } + else if (Z_TYPE_P(data) == IS_STRING && Z_STRLEN_P(data) == 0) + { + swoole_php_error(E_WARNING, "parameter $data is empty."); + } + return SW_OK; +} + +static sw_inline void http_client_swString_append_headers(swString* swStr, char* key, zend_size_t key_len, char* data, zend_size_t data_len) +{ + swString_append_ptr(swStr, key, key_len); + swString_append_ptr(swStr, ZEND_STRL(": ")); + swString_append_ptr(swStr, data, data_len); + swString_append_ptr(swStr, ZEND_STRL("\r\n")); +} + +static sw_inline void http_client_append_content_length(swString* buf, int length) +{ + char content_length_str[32]; + int n = snprintf(content_length_str, sizeof(content_length_str), "Content-Length: %d\r\n\r\n", length); + swString_append_ptr(buf, content_length_str, n); +} + +#ifdef SW_HAVE_ZLIB +extern swString *swoole_zlib_buffer; +#endif + +#endif /* SWOOLE_HTTP_CLIENT_H_ */ diff --git a/vendor/swoole/swoole_http_client_coro.c b/vendor/swoole/swoole_http_client_coro.c new file mode 100755 index 0000000..6dcc1b9 --- /dev/null +++ b/vendor/swoole/swoole_http_client_coro.c @@ -0,0 +1,1979 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Fang <coooold@live.com> | + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + | Author: Yuanyi Zhi <syyuanyizhi@163.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_http_client.h" +#include "swoole_coroutine.h" +#include <setjmp.h> + +enum http_client_property +{ + http_client_coro_property_request = 0, + http_client_coro_property_context = 1, +}; + +static swString *http_client_buffer; + +static void http_client_coro_onReceive(swClient *cli, char *data, uint32_t length); +static void http_client_coro_onConnect(swClient *cli); +static void http_client_coro_onClose(swClient *cli); +static void http_client_coro_onError(swClient *cli); +static int http_client_coro_onMessage(swConnection *conn, char *data, uint32_t length); +static void http_client_onBufferEmpty(swClient *cli); + +static int http_client_coro_send_http_request(zval *zobject TSRMLS_DC); +static int http_client_coro_execute(zval *zobject, char *uri, zend_size_t uri_len TSRMLS_DC); + +static void http_client_coro_onTimeout(swTimer *timer, swTimer_node *tnode); +static void http_client_coro_onSendTimeout(swTimer *timer, swTimer_node *tnode); + +static const php_http_parser_settings http_parser_settings = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + http_client_parser_on_header_field, + http_client_parser_on_header_value, + http_client_parser_on_headers_complete, + http_client_parser_on_body, + http_client_parser_on_message_complete +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_coro_construct, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, ssl) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_setMethod, 0, 0, 1) + ZEND_ARG_INFO(0, method) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_setHeaders, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, headers, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_setCookies, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, cookies, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_setData, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_setDefer, 0, 0, 0) + ZEND_ARG_INFO(0, defer) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_addFile, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_execute, 0, 0, 1) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_get, 0, 0, 1) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_post, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_download, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, file) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_recv, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_upgrade, 0, 0, 1) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_client_coro_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, opcode) + ZEND_ARG_INFO(0, finish) +ZEND_END_ARG_INFO() + +zend_class_entry swoole_http_client_coro_ce; +zend_class_entry *swoole_http_client_coro_class_entry_ptr; + +static PHP_METHOD(swoole_http_client_coro, __construct); +static PHP_METHOD(swoole_http_client_coro, __destruct); +static PHP_METHOD(swoole_http_client_coro, set); +static PHP_METHOD(swoole_http_client_coro, setMethod); +static PHP_METHOD(swoole_http_client_coro, setHeaders); +static PHP_METHOD(swoole_http_client_coro, setCookies); +static PHP_METHOD(swoole_http_client_coro, setData); +static PHP_METHOD(swoole_http_client_coro, addFile); +static PHP_METHOD(swoole_http_client_coro, execute); +static PHP_METHOD(swoole_http_client_coro, isConnected); +static PHP_METHOD(swoole_http_client_coro, close); +static PHP_METHOD(swoole_http_client_coro, get); +static PHP_METHOD(swoole_http_client_coro, post); +static PHP_METHOD(swoole_http_client_coro, download); +static PHP_METHOD(swoole_http_client_coro, upgrade); +static PHP_METHOD(swoole_http_client_coro, push); +static PHP_METHOD(swoole_http_client_coro, setDefer); +static PHP_METHOD(swoole_http_client_coro, getDefer); +static PHP_METHOD(swoole_http_client_coro, recv); + +static const zend_function_entry swoole_http_client_coro_methods[] = +{ + PHP_ME(swoole_http_client_coro, __construct, arginfo_swoole_http_client_coro_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_http_client_coro, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_http_client_coro, set, arginfo_swoole_http_client_coro_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, setMethod, arginfo_swoole_http_client_coro_setMethod, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, setHeaders, arginfo_swoole_http_client_coro_setHeaders, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, setCookies, arginfo_swoole_http_client_coro_setCookies, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, setData, arginfo_swoole_http_client_coro_setData, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, execute, arginfo_swoole_http_client_coro_execute, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, get, arginfo_swoole_http_client_coro_get, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, post, arginfo_swoole_http_client_coro_post, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, download, arginfo_swoole_http_client_coro_download, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, upgrade, arginfo_swoole_http_client_coro_upgrade, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, addFile, arginfo_swoole_http_client_coro_addFile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, isConnected, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, setDefer, arginfo_swoole_http_client_coro_setDefer, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, getDefer, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, recv, arginfo_swoole_http_client_coro_recv, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_client_coro, push, arginfo_swoole_http_client_coro_push, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + + PHP_FE_END +}; + +static int http_client_coro_execute(zval *zobject, char *uri, zend_size_t uri_len TSRMLS_DC) +{ + if (uri_len <= 0) + { + swoole_php_fatal_error(E_WARNING, "path is empty."); + return SW_ERR; + } + + http_client *http = swoole_get_object(zobject); + + //http is not null when keeping alive + if (http) + { + //http not ready + if (http->state != HTTP_CLIENT_STATE_READY) + { + //swWarn("fd=%d, state=%d, active=%d, keep_alive=%d", http->cli->socket->fd, http->state, http->cli->socket->active, http->keep_alive); + swoole_php_fatal_error(E_WARNING, "Operation now in progress phase %d.", http->state); + return SW_ERR; + } + else if (!http->cli->socket->active) + { + swoole_php_fatal_error(E_WARNING, "connection#%d is closed.", http->cli->socket->fd); + return SW_ERR; + } + } + else + { + php_swoole_check_reactor(); + http = http_client_create(zobject TSRMLS_CC); + } + + if (http == NULL) + { + return SW_ERR; + } + + if (http->body == NULL) + { + http->body = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (http->body == NULL) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + return SW_ERR; + } + } + else + { + swString_clear(http->body); + } + + if (http->uri) + { + efree(http->uri); + } + + http->uri = estrdup(uri); + http->uri_len = uri_len; + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + + /** + * download response body + */ + if (hcc->download_file) + { + int fd = open(Z_STRVAL_P(hcc->download_file), O_CREAT | O_WRONLY, 0664); + if (fd < 0) + { + swSysError("open(%s, O_CREAT | O_WRONLY) failed.", Z_STRVAL_P(hcc->download_file)); + return SW_ERR; + } + if (hcc->download_offset == 0) + { + if (ftruncate(fd, 0) < 0) + { + swSysError("ftruncate(%s) failed.", Z_STRVAL_P(hcc->download_file)); + close(fd); + return SW_ERR; + } + } + else + { + if (lseek(fd, hcc->download_offset, SEEK_SET) < 0) + { + swSysError("fseek(%s, %ld) failed.", Z_STRVAL_P(hcc->download_file), hcc->download_offset); + close(fd); + return SW_ERR; + } + } + http->download = 1; + http->file_fd = fd; + } + + //if connection exists + if (http->cli) + { + http_client_coro_send_http_request(zobject TSRMLS_CC); + return SW_OK; + } + + swClient *cli = php_swoole_client_new(zobject, http->host, http->host_len, http->port); + if (cli == NULL) + { + return SW_ERR; + } + http->cli = cli; + + zval *ztmp; + HashTable *vht; + zval *zset = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + vht = Z_ARRVAL_P(zset); + /** + * timeout + */ + if (php_swoole_array_get_value(vht, "timeout", ztmp)) + { + convert_to_double(ztmp); + http->timeout = (double) Z_DVAL_P(ztmp); + } + /** + * keep_alive + */ + if (php_swoole_array_get_value(vht, "keep_alive", ztmp)) + { + convert_to_boolean(ztmp); + http->keep_alive = Z_BVAL_P(ztmp); + } + //client settings + php_swoole_client_check_setting(http->cli, zset TSRMLS_CC); + + if (http->cli->http_proxy) + { + zval *send_header = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + if (send_header == NULL || Z_TYPE_P(send_header) != IS_ARRAY) + { + swoole_php_fatal_error (E_WARNING, "http proxy must set Host"); + return SW_ERR; + } + zval *value; + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value) == FAILURE) + { + swoole_php_fatal_error (E_WARNING, "http proxy must set Host"); + return SW_ERR; + } + } + } + + if (cli->socket->active == 1) + { + swoole_php_fatal_error(E_WARNING, "swoole_http_client is already connected."); + return SW_ERR; + } + + cli->object = zobject; + sw_copy_to_stack(cli->object, hcc->_object); + + cli->open_eof_check = 0; + cli->open_length_check = 0; + cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; + cli->onReceive = http_client_coro_onReceive; + cli->onConnect = http_client_coro_onConnect; + cli->onClose = http_client_coro_onClose; + cli->onError = http_client_coro_onError; + cli->onBufferEmpty = http_client_onBufferEmpty; + + swTraceLog(SW_TRACE_HTTP_CLIENT, "connect to server, object handle=%d, fd=%d", sw_get_object_handle(zobject), cli->socket->fd); + + return cli->connect(cli, http->host, http->port, http->timeout, 0); +} + +static void http_client_coro_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zdata; + zval *retval = NULL; + + php_context *ctx = tnode->data; + + SW_MAKE_STD_ZVAL(zdata); + //return false + ZVAL_BOOL(zdata, 0); + +#if PHP_MAJOR_VERSION < 7 + zval *zobject = (zval *)ctx->coro_params; +#else + zval _zobject = ctx->coro_params; + zval *zobject = &_zobject; +#endif + + swTraceLog(SW_TRACE_HTTP_CLIENT, "recv timeout, object handle=%d.", sw_get_object_handle(zobject)); + + http_client *http = swoole_get_object(zobject); + http->timer = NULL; + + if (http->cli && http->cli->socket && !http->cli->socket->closed) + { + http->cli->released = 1; + http->cli->close(http->cli); + http_client_free(zobject TSRMLS_CC); + } + + //define time out RETURN ERROR 110 + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("statusCode"), -2 TSRMLS_CC); + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; + hcc->defer_result = 0; + goto free_zdata; + } + + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + hcc->cid = 0; + int ret = coro_resume(ctx, zdata, &retval); + if (ret > 0) + { + goto free_zdata; + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + free_zdata: + sw_zval_ptr_dtor(&zdata); +} + +static void http_client_coro_onSendTimeout(swTimer *timer, swTimer_node *tnode) +{ + swClient *cli = tnode->data; + zval result; + zval *retval = NULL; + zval *zobject = (zval *) cli->object; + + ZVAL_BOOL(&result, 0); + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + hcc->send_yield = 0; + + http_client *http = swoole_get_object(zobject); + http->timer = NULL; + + SwooleG.error = EAGAIN; + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + + php_context *context = swoole_get_property(zobject, http_client_coro_property_context); + zval_dtor(&context->coro_params); + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void http_client_coro_send_yield(swClient *cli, char *data, size_t length, zval *return_value) +{ + zval *zobject = (zval *) cli->object; + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_WAIT; + hcc->cid = sw_get_current_cid(); + hcc->send_yield = 1; + + http_client *http = swoole_get_object(zobject); + if (http->timeout > 0) + { + php_swoole_check_timer((int) (http->timeout * 1000)); + http->timer = SwooleG.timer.add(&SwooleG.timer, (int) (http->timeout * 1000), 0, cli, http_client_coro_onSendTimeout); + } + + php_context *context = swoole_get_property((zval *) cli->object, http_client_coro_property_context); + ZVAL_STRINGL(&context->coro_params, data, length); + coro_save(context); + coro_yield(); +} + +void swoole_http_client_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_http_client_coro_ce, "Swoole\\Coroutine\\Http\\Client", swoole_http_client_coro_methods); + swoole_http_client_coro_class_entry_ptr = zend_register_internal_class(&swoole_http_client_coro_ce TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Http\\Client", swoole_http_client_coro_class_entry_ptr); + } + + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, SW_STRL("sock")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_http_client_coro_class_entry_ptr, SW_STRL("reuse")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, SW_STRL("reuseCount")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_http_client_coro_class_entry_ptr, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, SW_STRL("statusCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("host")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http_client_coro_class_entry_ptr, SW_STRL("port")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("requestMethod")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("requestHeaders")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("requestBody")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("uploadFiles")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("headers")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("cookies")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_client_coro_class_entry_ptr, SW_STRL("body")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + http_client_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!http_client_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + } + +#ifdef SW_HAVE_ZLIB + swoole_zlib_buffer = swString_new(2048); + if (!swoole_zlib_buffer) + { + swoole_php_fatal_error(E_ERROR, "[2] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + } +#endif +} + +/** + * @zobject: swoole_http_client_coro object + */ +static void http_client_coro_onClose(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = cli->object; + http_client *http = swoole_get_object(zobject); + zend_bool result = 0; + + zend_update_property_bool(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + + swTraceLog(SW_TRACE_HTTP_CLIENT, "connection close, object handle=%d, state=%d", sw_get_object_handle(zobject), http->state); + + if (!http) + { + return; + } + + if (http->state == HTTP_CLIENT_STATE_WAIT_CLOSE) + { + http_client_parser_on_message_complete(&http->parser); + result = 1; + goto _resume; + } + + if (http->state != HTTP_CLIENT_STATE_BUSY) + { + return; + } + + if (cli->released) + { + return; + } + + _resume: http_client_free(zobject TSRMLS_CC); + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + + if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; + hcc->defer_result = 0; + return; + } + + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + zval *retval = NULL; + zval *zdata = NULL; + + SW_MAKE_STD_ZVAL(zdata); + ZVAL_BOOL(zdata, result); + + php_context *sw_current_context = swoole_get_property(zobject, http_client_coro_property_context); + hcc->cid = 0; + coro_resume(sw_current_context, zdata, &retval); + + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); +} + +static int http_client_coro_onMessage(swConnection *conn, char *data, uint32_t length) +{ + swClient *cli = conn->object; + zval *zobject = cli->object; + zval *retval = NULL; + zval *zframe; + + swString msg; + msg.str = data; + msg.length = length; + + http_client *http = swoole_get_object(zobject); + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + SW_ALLOC_INIT_ZVAL(zframe); + php_swoole_websocket_unpack(&msg, zframe TSRMLS_CC); + swLinkedList_append(hcc->message_queue, zframe); + /** + * Too many queued messages + */ + if (hcc->message_queue->num > SW_WEBSOCKET_QUEUE_SIZE) + { + swClient_sleep(cli); + } + return SW_OK; + } + + php_context *sw_current_context = swoole_get_property(zobject, http_client_coro_property_context); + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + hcc->cid = 0; + + SW_MAKE_STD_ZVAL(zframe); + php_swoole_websocket_unpack(&msg, zframe TSRMLS_CC); + + int ret = coro_resume(sw_current_context, zframe, &retval); + if (ret > 0) + { + goto free_zdata; + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + free_zdata: sw_zval_ptr_dtor(&zframe); + return SW_OK; +} + +/** + * @zobject: swoole_http_client object + */ +static void http_client_coro_onError(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zdata; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zdata); + //return false + ZVAL_BOOL(zdata, 0); + + zval *zobject = cli->object; + php_context *sw_current_context = swoole_get_property(zobject, http_client_coro_property_context); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("statusCode"), -1 TSRMLS_CC); + + swTraceLog(SW_TRACE_HTTP_CLIENT, "connect error, object handle=%d", sw_get_object_handle(zobject)); + + http_client *http = swoole_get_object(zobject); + http->timer = NULL; + if (!cli->released) + { + http_client_free(zobject TSRMLS_CC); + } + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; + hcc->defer_result = 0; + goto free_zdata; + } + + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + hcc->cid = 0; + + int ret = coro_resume(sw_current_context, zdata, &retval); + if (ret > 0) + { + goto free_zdata; + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + free_zdata: + sw_zval_ptr_dtor(&zdata); +} + +static void http_client_onBufferEmpty(swClient *cli) +{ + zval *zobject = (zval *) cli->object; + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + hcc->send_yield = 0; + + http_client *http = swoole_get_object(zobject); + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } + + php_context *context = swoole_get_property(zobject, http_client_coro_property_context); + zval result; + zval *retval = NULL; + + ZVAL_BOOL(&result, cli->send(cli, Z_STRVAL(context->coro_params), Z_STRLEN(context->coro_params), 0) > 0); + zval_dtor(&context->coro_params); + + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + + +static void http_client_coro_onReceive(swClient *cli, char *data, uint32_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = cli->object; + zval *retval = NULL; + http_client *http = swoole_get_object(zobject); + if (!http->cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); + return; + } + + if (http->header_completed == 0) + { + swString *buffer = cli->buffer; + buffer->length += length; + + //HTTP/1.1 200 OK + if (buffer->length < 16) + { + return; + } + //No header + if (swoole_strnpos(buffer->str + buffer->offset, buffer->length - buffer->offset, ZEND_STRL("\r\n\r\n")) < 0) + { + if (buffer->length == buffer->size) + { + swSysError("Wrong http response."); + cli->close(cli); + return; + } + buffer->offset = buffer->length - 4 <= 0 ? 0 : buffer->length - 4; + return; + } + else + { + http->header_completed = 1; + data = buffer->str; + length = buffer->length; + swString_clear(buffer); + } + } + + long parsed_n = php_http_parser_execute(&http->parser, &http_parser_settings, data, length); + + swDebug("parsed_n=%ld, data_length=%d.", parsed_n, length); + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + + if (parsed_n < 0) + { + //return false + ZVAL_BOOL(zdata, 0); + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } + if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + //not recv yet sava data + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; + hcc->defer_result = 0; + goto free_zdata; + //wait for recv + } + goto begin_resume; + } + + //not complete + if (!http->completed) + { + return; + } + +// if (!hcc->defer_chunk_status) +// { +// //not recv all wait for next +// return; +// } + + //timeout + if (http->timer) + { + swTimer_del(&SwooleG.timer, http->timer); + http->timer = NULL; + } + + ZVAL_BOOL(zdata, 1); //return false + if (hcc->defer && hcc->defer_status != HTTP_CLIENT_STATE_DEFER_WAIT) + { + //not recv yet sava data + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_DONE; + hcc->defer_result = 1; + goto free_zdata; + } + + /** + * TODO: Sec-WebSocket-Accept check + */ + if (http->upgrade) + { + cli->open_length_check = 1; + cli->protocol.get_package_length = swWebSocket_get_package_length; + cli->protocol.onPackage = http_client_coro_onMessage; + cli->protocol.package_length_size = SW_WEBSOCKET_HEADER_LEN + SW_WEBSOCKET_MASK_LEN + sizeof(uint64_t); + http->state = HTTP_CLIENT_STATE_UPGRADE; + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + /** + * websocket message queue + */ + hcc->message_queue = swLinkedList_new(16, NULL); + + if (http->upgrade) + { + //data frame + if (length > parsed_n + 3) + { + cli->buffer->length = length - parsed_n - 1; + memmove(cli->buffer->str, data + parsed_n + 1, cli->buffer->length); + cli->socket->skip_recv = 1; + swProtocol_recv_check_length(&cli->protocol, cli->socket, cli->buffer); + } + else + { + swString_clear(cli->buffer); + } + } + } + + begin_resume: + { + //if should resume + /*if next cr*/ + php_context *sw_current_context = swoole_get_property(zobject, http_client_coro_property_context); + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + hcc->cid = 0; + //hcc->defer_chunk_status = 0; + http->completed = 0; + http->state = HTTP_CLIENT_STATE_READY; + + int ret = coro_resume(sw_current_context, zdata, &retval); + if (ret > 0) + { + goto free_zdata; + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + } + + free_zdata: + sw_zval_ptr_dtor(&zdata); +} + +static void http_client_coro_onConnect(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zobject = cli->object; + http_client *http = swoole_get_object(zobject); + if (!http->cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); + return; + } + zend_update_property_bool(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 1 TSRMLS_CC); + http_client_coro_send_http_request(zobject TSRMLS_CC); +} + +static int http_client_coro_send_http_request(zval *zobject TSRMLS_DC) +{ + int ret; + http_client *http = swoole_get_object(zobject); + if (!http->cli || !http->cli->socket ) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); + return SW_ERR; + } + + if (http->cli->socket->active == 0) + { + swoole_php_error(E_WARNING, "server is not connected."); + return SW_ERR; + } + + if (http->state != HTTP_CLIENT_STATE_READY) + { + swoole_php_error(E_WARNING, "http client is not ready."); + return SW_ERR; + } + + http->state = HTTP_CLIENT_STATE_BUSY; + //clear errno + SwooleG.error = 0; + + http_client_property *hcc = swoole_get_property(zobject, http_client_coro_property_request); + + zval *post_data = hcc->request_body; + zval *send_header = hcc->request_header; + zval *value = NULL; + + //POST + if (hcc->request_method == NULL) + { + if (post_data) + { + hcc->request_method = "POST"; + } + //GET + else + { + hcc->request_method = "GET"; + } + } + + http->method = swHttp_get_method(hcc->request_method, strlen(hcc->request_method) + 1); + + swString_clear(http_client_buffer); + swString_append_ptr(http_client_buffer, hcc->request_method, strlen(hcc->request_method)); + hcc->request_method = NULL; + swString_append_ptr(http_client_buffer, ZEND_STRL(" ")); + +#ifdef SW_USE_OPENSSL + if (http->cli->http_proxy && !http->cli->open_ssl) +#else + if (http->cli->http_proxy) +#endif + { + sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value); //checked before + char *pre = "http://"; + int len = http->uri_len + Z_STRLEN_P(value) + strlen(pre) + 10; + void *addr = emalloc(http->uri_len + Z_STRLEN_P(value) + strlen(pre) + 10); + http->uri_len = snprintf(addr, len, "%s%s:%d%s", pre, Z_STRVAL_P(value), http->port, http->uri); + efree(http->uri); + http->uri = addr; + } + + swString_append_ptr(http_client_buffer, http->uri, http->uri_len); + swString_append_ptr(http_client_buffer, ZEND_STRL(" HTTP/1.1\r\n")); + + char *key; + uint32_t keylen; + int keytype; + + if (send_header && Z_TYPE_P(send_header) == IS_ARRAY) + { + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Connection"), (void **) &value) == FAILURE) + { + if (http->keep_alive) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("keep-alive")); + } + else + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("closed")); + } + } + + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Host"), (void **) &value) == FAILURE) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Host"), http->host, http->host_len); + } + +#ifdef SW_HAVE_ZLIB + if (sw_zend_hash_find(Z_ARRVAL_P(send_header), ZEND_STRS("Accept-Encoding"), (void **) &value) == FAILURE) + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Accept-Encoding"), ZEND_STRL("gzip")); + } +#endif + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(send_header), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + if (Z_STRLEN_P(value) == 0) + { + continue; + } + http_client_swString_append_headers(http_client_buffer, key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + SW_HASHTABLE_FOREACH_END(); + } + else + { + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Connection"), ZEND_STRL("keep-alive")); + http->keep_alive = 1; + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Host"), http->host, http->host_len); +#ifdef SW_HAVE_ZLIB + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Accept-Encoding"), ZEND_STRL("gzip")); +#endif + } + + if (hcc->cookies && Z_TYPE_P(hcc->cookies) == IS_ARRAY) + { + swString_append_ptr(http_client_buffer, ZEND_STRL("Cookie: ")); + int n_cookie = Z_ARRVAL_P(hcc->cookies)->nNumOfElements; + int i = 0; + char *encoded_value; + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(hcc->cookies), key, keylen, keytype, value) + i ++; + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + if (Z_STRLEN_P(value) == 0) + { + continue; + } + swString_append_ptr(http_client_buffer, key, keylen); + swString_append_ptr(http_client_buffer, "=", 1); + + int encoded_value_len; + encoded_value = sw_php_url_encode(Z_STRVAL_P(value), Z_STRLEN_P(value), &encoded_value_len); + if (encoded_value) + { + swString_append_ptr(http_client_buffer, encoded_value, encoded_value_len); + efree(encoded_value); + } + if (i < n_cookie) + { + swString_append_ptr(http_client_buffer, "; ", 2); + } + SW_HASHTABLE_FOREACH_END(); + swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + } + + //form-data + if (hcc->request_upload_files) + { + char header_buf[2048]; + char boundary_str[39]; + int n; + + memcpy(boundary_str, SW_HTTP_CLIENT_BOUNDARY_PREKEY, sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY) - 1); + swoole_random_string(boundary_str + sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY) - 1, + sizeof(boundary_str) - sizeof(SW_HTTP_CLIENT_BOUNDARY_PREKEY)); + + n = snprintf(header_buf, sizeof(header_buf), "Content-Type: multipart/form-data; boundary=%*s\r\n", + sizeof(boundary_str) - 1, boundary_str); + + swString_append_ptr(http_client_buffer, header_buf, n); + + int content_length = 0; + + //post data + if (post_data && Z_TYPE_P(post_data) == IS_ARRAY) + { + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(post_data), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + //strlen("%.*")*2 = 6 + //header + body + CRLF + content_length += (sizeof(SW_HTTP_FORM_DATA_FORMAT_STRING) - 7) + (sizeof(boundary_str) - 1) + keylen + + Z_STRLEN_P(value) + 2; + SW_HASHTABLE_FOREACH_END(); + } + + zval *zname; + zval *ztype; + zval *zsize = NULL; + zval *zpath; + zval *zfilename; + zval *zoffset; + + if (hcc->request_upload_files) + { + //upload files + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(hcc->request_upload_files), key, keylen, keytype, value) + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("name"), (void **) &zname) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("filename"), (void **) &zfilename) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("size"), (void **) &zsize) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("type"), (void **) &ztype) == FAILURE) + { + continue; + } + //strlen("%.*")*4 = 12 + //header + body + CRLF + content_length += (sizeof(SW_HTTP_FORM_DATA_FORMAT_FILE) - 13) + (sizeof(boundary_str) - 1) + + Z_STRLEN_P(zname) + Z_STRLEN_P(zfilename) + Z_STRLEN_P(ztype) + Z_LVAL_P(zsize) + 2; + SW_HASHTABLE_FOREACH_END(); + } + + http_client_append_content_length(http_client_buffer, content_length + sizeof(boundary_str) - 1 + 6); + + //post data + if (post_data && Z_TYPE_P(post_data) == IS_ARRAY) + { + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(post_data), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + n = snprintf(header_buf, sizeof(header_buf), SW_HTTP_FORM_DATA_FORMAT_STRING, sizeof(boundary_str) - 1, + boundary_str, keylen, key); + swString_append_ptr(http_client_buffer, header_buf, n); + swString_append_ptr(http_client_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value)); + swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + SW_HASHTABLE_FOREACH_END(); + + zend_update_property_null(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + hcc->request_body = NULL; + } + + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + goto send_fail; + } + + if (hcc->request_upload_files) + { + //upload files + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(hcc->request_upload_files), key, keylen, keytype, value) + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("name"), (void **) &zname) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("filename"), (void **) &zfilename) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("path"), (void **) &zpath) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("size"), (void **) &zsize) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("type"), (void **) &ztype) == FAILURE) + { + continue; + } + if (sw_zend_hash_find(Z_ARRVAL_P(value), ZEND_STRS("offset"), (void **) &zoffset) == FAILURE) + { + continue; + } + n = snprintf(header_buf, sizeof(header_buf), SW_HTTP_FORM_DATA_FORMAT_FILE, sizeof(boundary_str) - 1, + boundary_str, Z_STRLEN_P(zname), Z_STRVAL_P(zname), Z_STRLEN_P(zfilename), + Z_STRVAL_P(zfilename), Z_STRLEN_P(ztype), Z_STRVAL_P(ztype)); + + if ((ret = http->cli->send(http->cli, header_buf, n, 0)) < 0) + { + goto send_fail; + } + if ((ret = http->cli->sendfile(http->cli, Z_STRVAL_P(zpath), Z_LVAL_P(zoffset), Z_LVAL_P(zsize))) < 0) + { + goto send_fail; + } + if ((ret = http->cli->send(http->cli, "\r\n", 2, 0)) < 0) + { + goto send_fail; + } + SW_HASHTABLE_FOREACH_END(); + + zend_update_property_null(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("uploadFiles") TSRMLS_CC); + hcc->request_upload_files = NULL; + } + + n = snprintf(header_buf, sizeof(header_buf), "--%*s--\r\n", sizeof(boundary_str) - 1, boundary_str); + if ((ret = http->cli->send(http->cli, header_buf, n, 0)) < 0) + { + goto send_fail; + } + else + { + goto send_ok; + } + } + //x-www-form-urlencoded or raw + else if (post_data) + { + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + zend_size_t len; + http_client_swString_append_headers(http_client_buffer, ZEND_STRL("Content-Type"), ZEND_STRL("application/x-www-form-urlencoded")); + if (php_swoole_array_length(post_data) > 0) + { + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return SW_ERR; + } + http_client_append_content_length(http_client_buffer, len); + swString_append_ptr(http_client_buffer, formstr, len); + smart_str_free(&formstr_s); + } + else + { + http_client_append_content_length(http_client_buffer, 0); + } + } + else + { + http_client_append_content_length(http_client_buffer, Z_STRLEN_P(post_data)); + swString_append_ptr(http_client_buffer, Z_STRVAL_P(post_data), Z_STRLEN_P(post_data)); + } + zend_update_property_null(swoole_http_client_coro_class_entry_ptr, zobject, ZEND_STRL("requestBody") TSRMLS_CC); + hcc->request_body = NULL; + } + else + { + swString_append_ptr(http_client_buffer, ZEND_STRL("\r\n")); + } + + swTrace("[%d]: %s\n", (int)http_client_buffer->length, http_client_buffer->str); + + if ((ret = http->cli->send(http->cli, http_client_buffer->str, http_client_buffer->length, 0)) < 0) + { + send_fail: + SwooleG.error = errno; + swoole_php_sys_error(E_WARNING, "send(%d) %d bytes failed.", http->cli->socket->fd, (int )http_client_buffer->length); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, zobject, SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + return ret; + } + + send_ok: + if (http->timeout > 0) + { + php_context *context = swoole_get_property(zobject, http_client_coro_property_context); + http->timer = SwooleG.timer.add(&SwooleG.timer, (int) (http->timeout * 1000), 0, context, http_client_coro_onTimeout); + if (http->timer && hcc->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + + return ret; +} + +static PHP_METHOD(swoole_http_client_coro, __construct) +{ + coro_check(TSRMLS_C); + + char *host; + zend_size_t host_len; + long port = 80; + zend_bool ssl = SW_FALSE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &host, &host_len, &port, &ssl) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + swoole_php_fatal_error(E_ERROR, "host is empty."); + RETURN_FALSE; + } + + zend_update_property_stringl(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("host"), host, host_len TSRMLS_CC); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr,getThis(), ZEND_STRL("port"), port TSRMLS_CC); + + //init + swoole_set_object(getThis(), NULL); + + zval *headers; + SW_MAKE_STD_ZVAL(headers); + array_init(headers); + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("headers"), headers TSRMLS_CC); + sw_zval_ptr_dtor(&headers); + + http_client_property *hcc; + hcc = (http_client_property*) emalloc(sizeof(http_client_property)); + bzero(hcc, sizeof(http_client_property)); + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + // hcc->defer_chunk_status = 0; + swoole_set_property(getThis(), 0, hcc); + + int flags = SW_SOCK_TCP | SW_FLAG_ASYNC; + if (ssl) + { +#ifdef SW_USE_OPENSSL + flags |= SW_SOCK_SSL; +#else + swoole_php_fatal_error(E_ERROR, "require openssl library."); +#endif + } + + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("type"), flags TSRMLS_CC); + + php_context *context = emalloc(sizeof(php_context)); + swoole_set_property(getThis(), 1, context); + + context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + context->coro_params = getThis(); +#else + context->coro_params = *getThis(); +#endif + context->state = SW_CORO_CONTEXT_RUNNING; + + swTraceLog(SW_TRACE_HTTP_CLIENT, "ctor, object handle=%d.", sw_get_object_handle(getThis())); +} + +static PHP_METHOD(swoole_http_client_coro, __destruct) +{ + swTraceLog(SW_TRACE_HTTP_CLIENT, "dtor, object handle=%d.", sw_get_object_handle(getThis())); + + http_client *http = swoole_get_object(getThis()); + if (http) + { + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_http_client_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc) + { + if (hcc->message_queue) + { + swLinkedList_free(hcc->message_queue); + } + efree(hcc); + swoole_set_property(getThis(), 0, NULL); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (context) + { + efree(context); + swoole_set_property(getThis(), 1, NULL); + } +} + +static PHP_METHOD(swoole_http_client_coro, set) +{ + zval *zset; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + zval *zsetting = php_swoole_read_init_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, setHeaders) +{ + zval *headers; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &headers) == FAILURE) + { + return; + } + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders"), headers TSRMLS_CC); + http_client_property *hcc = swoole_get_property(getThis(), 0); + hcc->request_header = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + sw_copy_to_stack(hcc->request_header, hcc->_request_header); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, setCookies) +{ + zval *cookies; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &cookies) == FAILURE) + { + return; + } + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("cookies"), cookies TSRMLS_CC); + http_client_property *hcc = swoole_get_property(getThis(), 0); + hcc->cookies = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("cookies"), 1 TSRMLS_CC); + sw_copy_to_stack(hcc->cookies, hcc->_cookies); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, getDefer) +{ + http_client_property *hcc = swoole_get_property(getThis(), 0); + + RETURN_BOOL(hcc->defer); +} + +static PHP_METHOD(swoole_http_client_coro, setDefer) +{ + zend_bool defer = 1; + http_client_property *hcc = swoole_get_property(getThis(), 0); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &defer) == FAILURE) + { + return; + } + + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_INIT) + { + RETURN_BOOL(defer); + } + + hcc->defer = defer; + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, recv) +{ + http_client *http = swoole_get_object(getThis()); + if (!http) + { + RETURN_FALSE; + } + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + + double timeout = 0; + + //resume + if (http->cli->sleep) + { + swClient_wakeup(http->cli); + } + //websocket + if (http->upgrade) + { + if (hcc->message_queue->num > 0) + { + zval *msg = swLinkedList_shift(hcc->message_queue); + if (msg) + { + RETVAL_ZVAL(msg, 0, 0); + efree(msg); + return; + } + } + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "|d", &timeout) == FAILURE) + { + return; + } + + goto _yield; + } + + //no defer + if (!hcc->defer) + { + swoole_php_fatal_error(E_WARNING, "you should not use recv without defer."); + RETURN_FALSE; + } + + switch (hcc->defer_status) + { + case HTTP_CLIENT_STATE_DEFER_DONE: + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_INIT; + RETURN_BOOL(hcc->defer_result); + case HTTP_CLIENT_STATE_DEFER_SEND: + goto _yield; + case HTTP_CLIENT_STATE_DEFER_INIT: + //not ready + swoole_php_fatal_error(E_WARNING, "you should post or get or execute before recv."); + RETURN_FALSE; + default: + return; + } + + _yield: hcc->defer_status = HTTP_CLIENT_STATE_DEFER_WAIT; + php_context *context = swoole_get_property(getThis(), 1); + + if (timeout > 0) + { + php_swoole_check_timer((int) (timeout * 1000)); + http->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, http_client_coro_onTimeout); + } + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, setData) +{ + zval *data; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &data) == FAILURE) + { + return; + } + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), data TSRMLS_CC); + http_client_property *hcc = swoole_get_property(getThis(), 0); + hcc->request_body = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), 1 TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, addFile) +{ + char *path; + zend_size_t l_path; + char *name; + zend_size_t l_name; + char *type = NULL; + zend_size_t l_type; + char *filename = NULL; + zend_size_t l_filename; + long offset = 0; + long length = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ssll", &path, &l_path, &name, &l_name, &type, &l_type, + &filename, &l_filename, &offset, &length) == FAILURE) + { + RETURN_FALSE; + } + if (offset < 0) + { + offset = 0; + } + if (length < 0) + { + length = 0; + } + struct stat file_stat; + if (stat(path, &file_stat) < 0) + { + swoole_php_sys_error(E_WARNING, "stat(%s) failed.", path); + RETURN_FALSE; + } + if (file_stat.st_size == 0) + { + swoole_php_sys_error(E_WARNING, "cannot send empty file[%s].", filename); + RETURN_FALSE; + } + if (file_stat.st_size <= offset) + { + swoole_php_error(E_WARNING, "parameter $offset[%ld] exceeds the file size.", offset); + RETURN_FALSE; + } + if (length > file_stat.st_size - offset) + { + swoole_php_sys_error(E_WARNING, "parameter $length[%ld] exceeds the file size.", length); + RETURN_FALSE; + } + if (length == 0) + { + length = file_stat.st_size - offset; + } + if (type == NULL) + { + type = swoole_get_mimetype(path); + l_type = strlen(type); + } + if (filename == NULL) + { + char *dot = strrchr(path, '/'); + if (dot == NULL) + { + filename = path; + l_filename = l_path; + } + else + { + filename = dot + 1; + l_filename = strlen(filename); + } + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + zval *files; + if (!hcc->request_upload_files) + { + SW_MAKE_STD_ZVAL(files); + array_init(files); + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("uploadFiles"), files TSRMLS_CC); + sw_zval_ptr_dtor(&files); + + hcc->request_upload_files = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("uploadFiles"), 0 TSRMLS_CC); + sw_copy_to_stack(hcc->request_upload_files, hcc->_request_upload_files); + } + + zval *upload_file; + SW_MAKE_STD_ZVAL(upload_file); + array_init(upload_file); + + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("path"), path, l_path, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("name"), name, l_name, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("filename"), filename, l_filename, 1); + sw_add_assoc_stringl_ex(upload_file, ZEND_STRS("type"), type, l_type, 1); + add_assoc_long(upload_file, "size", length); + add_assoc_long(upload_file, "offset", offset); + + add_next_index_zval(hcc->request_upload_files, upload_file); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, setMethod) +{ + zval *method; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &method) == FAILURE) + { + return; + } + convert_to_string(method); + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestMethod"), method TSRMLS_CC); + http_client_property *hcc = swoole_get_property(getThis(), 0); + hcc->request_method = Z_STRVAL_P(method); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_client_coro, isConnected) +{ + http_client *http = swoole_get_object(getThis()); + if (!http || !http->cli) + { + RETURN_FALSE; + } + if (!http->cli->socket) + { + RETURN_FALSE; + } + RETURN_BOOL(http->cli->socket->active); +} + +static PHP_METHOD(swoole_http_client_coro, close) +{ + http_client *http = swoole_get_object(getThis()); + if (!http) + { + RETURN_FALSE; + } + + swClient *cli = http->cli; + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client_coro."); + RETURN_FALSE; + } + if (!cli->socket) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + if (cli->socket->closed) + { + http_client_free(getThis() TSRMLS_CC); + RETURN_FALSE; + } + + int ret = SW_OK; + cli->released = 1; + ret = cli->close(cli); + http_client_free(getThis() TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http_client_coro, execute) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) + { + return; + } + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + if (hcc->defer) + { + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_INIT) + { + RETURN_FALSE; + } + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_SEND; + } + ret = http_client_coro_execute(getThis(), uri, uri_len TSRMLS_CC); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (hcc->defer) + { + RETURN_TRUE; + } + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, get) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) + { + return; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + if (hcc->defer) + { + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_INIT) + { + RETURN_FALSE; + } + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_SEND; + } + ret = http_client_coro_execute(getThis(), uri, uri_len TSRMLS_CC); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (hcc->defer) + { + RETURN_TRUE; + } + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, post) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *post_data; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &uri, &uri_len, &post_data) == FAILURE) + { + return; + } + + if (Z_TYPE_P(post_data) != IS_ARRAY && Z_TYPE_P(post_data) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "post data must be string or array."); + RETURN_FALSE; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), post_data TSRMLS_CC); + hcc->request_body = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestBody"), 1 TSRMLS_CC); + sw_copy_to_stack(hcc->request_body, hcc->_request_body); + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + + if (hcc->defer) + { + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_INIT) + { + RETURN_FALSE; + } + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_SEND; + } + ret = http_client_coro_execute(getThis(), uri, uri_len TSRMLS_CC); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (hcc->defer) + { + RETURN_TRUE; + } + hcc->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, download) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + zval *download_file; + off_t offset = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &uri, &uri_len, &download_file, &offset) == FAILURE) + { + return; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + zend_update_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("downloadFile"), download_file TSRMLS_CC); + hcc->download_file = sw_zend_read_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("downloadFile"), 1 TSRMLS_CC); + hcc->download_offset = offset; + sw_copy_to_stack(hcc->download_file, hcc->_download_file); + + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + + if (hcc->defer) + { + if (hcc->defer_status != HTTP_CLIENT_STATE_DEFER_INIT) + { + RETURN_FALSE; + } + hcc->defer_status = HTTP_CLIENT_STATE_DEFER_SEND; + } + ret = http_client_coro_execute(getThis(), uri, uri_len TSRMLS_CC); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (hcc->defer) + { + RETURN_TRUE; + } + hcc->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, upgrade) +{ + int ret; + char *uri = NULL; + zend_size_t uri_len = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) + { + return; + } + + http_client_property *hcc = swoole_get_property(getThis(), 0); + if (hcc->cid != 0 && hcc->cid != sw_get_current_cid()) + { + swoole_php_fatal_error(E_WARNING, "client has been bound to another coro"); + } + + zval *headers = hcc->request_header; + if (hcc->request_header == NULL) + { + headers = php_swoole_read_init_property(swoole_http_client_coro_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders") TSRMLS_CC); + hcc->request_header = headers; + sw_copy_to_stack(hcc->request_header, hcc->_request_header); + } + + char buf[SW_WEBSOCKET_KEY_LENGTH + 1]; + http_client_create_token(SW_WEBSOCKET_KEY_LENGTH, buf); + + sw_add_assoc_string(headers, "Connection", "Upgrade", 1); + sw_add_assoc_string(headers, "Upgrade", "websocket", 1); + sw_add_assoc_string(headers, "Sec-WebSocket-Version", SW_WEBSOCKET_VERSION, 1); + +#if PHP_MAJOR_VERSION < 7 + int encoded_value_len = 0; + uchar *encoded_value = php_base64_encode((const unsigned char *) buf, SW_WEBSOCKET_KEY_LENGTH, &encoded_value_len); + add_assoc_stringl_ex(headers, ZEND_STRS("Sec-WebSocket-Key"), (char* )encoded_value, encoded_value_len, 0); +#else + zend_string *str = php_base64_encode((const unsigned char *) buf, SW_WEBSOCKET_KEY_LENGTH); + add_assoc_str_ex(headers, ZEND_STRL("Sec-WebSocket-Key"), str); +#endif + + ret = http_client_coro_execute(getThis(), uri, uri_len TSRMLS_CC); + if (ret == SW_ERR) + { + SW_CHECK_RETURN(ret); + } + + php_context *context = swoole_get_property(getThis(), 1); + if (hcc->defer) + { + RETURN_TRUE; + } + hcc->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http_client_coro, push) +{ + char *data; + zend_size_t length; + long opcode = WEBSOCKET_OPCODE_TEXT_FRAME; + zend_bool fin = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &data, &length, &opcode, &fin) == FAILURE) + { + return; + } + + if (opcode > WEBSOCKET_OPCODE_PONG) + { + swoole_php_fatal_error(E_WARNING, "opcode max 10"); + SwooleG.error = SW_ERROR_WEBSOCKET_BAD_OPCODE; + RETURN_FALSE; + } + + http_client *http = swoole_get_object(getThis()); + if (!(http && http->cli && http->cli->socket)) + { + swoole_php_error(E_WARNING, "not connected to the server"); + SwooleG.error = SW_ERROR_WEBSOCKET_UNCONNECTED; + RETURN_FALSE; + } + + if (!http->upgrade) + { + swoole_php_fatal_error(E_WARNING, "websocket handshake failed, cannot push data."); + SwooleG.error = SW_ERROR_WEBSOCKET_HANDSHAKE_FAILED; + RETURN_FALSE; + } + + swString_clear(http_client_buffer); + swWebSocket_encode(http_client_buffer, data, length, opcode, (int) fin, http->websocket_mask); + + swClient *cli = http->cli; + int ret = cli->send(cli, http_client_buffer->str, http_client_buffer->length, 0); + if (ret < 0) + { + if (SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW) + { + http_client_coro_send_yield(cli, http_client_buffer->str, http_client_buffer->length, return_value); + return; + } + SwooleG.error = errno; + swoole_php_sys_error(E_WARNING, "send(%d) %d bytes failed.", cli->socket->fd, http_client_buffer->length); + zend_update_property_long(swoole_http_client_coro_class_entry_ptr, getThis(), SW_STRL("errCode")-1, SwooleG.error TSRMLS_CC); + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +#endif diff --git a/vendor/swoole/swoole_http_server.c b/vendor/swoole/swoole_http_server.c new file mode 100755 index 0000000..a0cbab1 --- /dev/null +++ b/vendor/swoole/swoole_http_server.c @@ -0,0 +1,2821 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http.h" +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +#include <ext/standard/url.h> +#include <ext/standard/sha1.h> +#include <ext/standard/php_var.h> +#include <ext/standard/php_string.h> +#include <ext/standard/php_math.h> +#include <ext/standard/php_array.h> +#include <ext/date/php_date.h> +#include <ext/standard/md5.h> + +#include <main/rfc1867.h> +#include <main/php_variables.h> + +#include "websocket.h" +#include "Connection.h" +#include "base64.h" + +#ifdef SW_HAVE_ZLIB +#include <zlib.h> +#endif + +#ifdef SW_USE_HTTP2 +#include "http2.h" +#endif + +#ifdef SW_USE_PICOHTTPPARSER +#include "thirdparty/picohttpparser/picohttpparser.h" +#endif + +static swArray *http_client_array; + +swString *swoole_http_buffer; +#ifdef SW_HAVE_ZLIB +swString *swoole_zlib_buffer; +#endif +swString *swoole_http_form_data_buffer; + +enum http_global_flag +{ + HTTP_GLOBAL_GET = 1u << 1, + HTTP_GLOBAL_POST = 1u << 2, + HTTP_GLOBAL_COOKIE = 1u << 3, + HTTP_GLOBAL_REQUEST = 1u << 4, + HTTP_GLOBAL_SERVER = 1u << 5, + HTTP_GLOBAL_FILES = 1u << 6, +}; + +enum http_upload_errno +{ + HTTP_UPLOAD_ERR_OK = 0, + HTTP_UPLOAD_ERR_INI_SIZE, + HTTP_UPLOAD_ERR_FORM_SIZE, + HTTP_UPLOAD_ERR_PARTIAL, + HTTP_UPLOAD_ERR_NO_FILE, + HTTP_UPLOAD_ERR_NO_TMP_DIR = 6, + HTTP_UPLOAD_ERR_CANT_WRITE, +}; + +zend_class_entry swoole_http_server_ce; +zend_class_entry *swoole_http_server_class_entry_ptr; + +zend_class_entry swoole_http_response_ce; +zend_class_entry *swoole_http_response_class_entry_ptr; + +zend_class_entry swoole_http_request_ce; +zend_class_entry *swoole_http_request_class_entry_ptr; + +static int http_onReceive(swServer *serv, swEventData *req); +static void http_onClose(swServer *serv, swDataHead *ev); + +static int http_request_on_path(php_http_parser *parser, const char *at, size_t length); +static int http_request_on_query_string(php_http_parser *parser, const char *at, size_t length); +static int http_request_on_body(php_http_parser *parser, const char *at, size_t length); +static int http_request_on_header_field(php_http_parser *parser, const char *at, size_t length); +static int http_request_on_header_value(php_http_parser *parser, const char *at, size_t length); +static int http_request_on_headers_complete(php_http_parser *parser); +static int http_request_message_complete(php_http_parser *parser); + +static int multipart_body_on_header_field(multipart_parser* p, const char *at, size_t length); +static int multipart_body_on_header_value(multipart_parser* p, const char *at, size_t length); +static int multipart_body_on_data(multipart_parser* p, const char *at, size_t length); +static int multipart_body_on_header_complete(multipart_parser* p); +static int multipart_body_on_data_end(multipart_parser* p); + +static http_context* http_get_context(zval *object, int check_end TSRMLS_DC); + +static void http_parse_cookie(zval *array, const char *at, size_t length); +static void http_build_header(http_context *, zval *object, swString *response, int body_length TSRMLS_DC); + +static inline void http_header_key_format(char *key, int length) +{ + int i, state = 0; + for (i = 0; i < length; i++) + { + if (state == 0) + { + if (key[i] >= 97 && key[i] <= 122) + { + key[i] -= 32; + } + state = 1; + } + else if (key[i] == '-') + { + state = 0; + } + else + { + if (key[i] >= 65 && key[i] <= 90) + { + key[i] += 32; + } + } + } +} + +static inline char* http_trim_double_quote(char *ptr, int *len) +{ + int i; + char *tmp = ptr; + + //ltrim('"') + for (i = 0; i < *len; i++) + { + if (tmp[i] == '"') + { + (*len)--; + tmp++; + continue; + } + else + { + break; + } + } + //rtrim('"') + for (i = (*len) - 1; i >= 0; i--) + { + if (tmp[i] == '"') + { + tmp[i] = 0; + (*len)--; + continue; + } + else + { + break; + } + } + return tmp; +} + +#ifdef SW_USE_PICOHTTPPARSER +enum flags +{ + F_CONNECTION_KEEP_ALIVE = 1 << 1, + F_CONNECTION_CLOSE = 1 << 2, +}; + +static inline long http_fast_parse(php_http_parser *parser, char *data, size_t length) +{ + http_context *ctx = parser->data; + const char *method; + size_t method_len; + int minor_version; + struct phr_header headers[64]; + size_t num_headers = sizeof(headers) / sizeof(headers[0]); + const char *path; + size_t path_len; + + int n = phr_parse_request(data, length, &method, &method_len, &path, &path_len, &minor_version, headers, &num_headers, 0); + if (n < 0) + { + return SW_ERR; + } + + char *p = memchr(path, '?', path_len); + if (p) + { + http_request_on_path(parser, path, p - path); + http_request_on_query_string(parser, p + 1, path + path_len - p - 1); + } + else + { + http_request_on_path(parser, path, path_len); + } + + int i; + for (i = 0; i < num_headers; i++) + { + if (strncasecmp(headers[i].name, "Connection", headers[i].name_len) == 0 + && strncasecmp(headers[i].value, "keep-alive", headers[i].value_len) == 0) + { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } + else + { + parser->flags |= F_CONNECTION_CLOSE; + } + if (http_request_on_header_field(parser, headers[i].name, headers[i].name_len) < 0) + { + return SW_ERR; + } + if (http_request_on_header_value(parser, headers[i].value, headers[i].value_len) < 0) + { + return SW_ERR; + } + } + parser->method = swHttp_get_method(method, method_len) - 1; + parser->http_major = 1; + parser->http_minor = minor_version; + ctx->request.version = 100 + minor_version; + if (n < length) + { + http_request_on_body(parser, data + n, length - n); + } + http_request_on_headers_complete(parser); + return SW_OK; +} +#endif + +#ifdef SW_HAVE_ZLIB +static int http_response_compress(swString *body, int level); +voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size); +void php_zlib_free(voidpf opaque, voidpf address); +#endif + +static PHP_METHOD(swoole_http_server, on); +static PHP_METHOD(swoole_http_server, start); + +static PHP_METHOD(swoole_http_request, getData); +static PHP_METHOD(swoole_http_request, rawcontent); +static PHP_METHOD(swoole_http_request, __destruct); + +static PHP_METHOD(swoole_http_response, write); +static PHP_METHOD(swoole_http_response, end); +static PHP_METHOD(swoole_http_response, sendfile); +static PHP_METHOD(swoole_http_response, redirect); +static PHP_METHOD(swoole_http_response, cookie); +static PHP_METHOD(swoole_http_response, rawcookie); +static PHP_METHOD(swoole_http_response, header); +static PHP_METHOD(swoole_http_response, initHeader); +static PHP_METHOD(swoole_http_response, detach); +static PHP_METHOD(swoole_http_response, create); +#ifdef SW_HAVE_ZLIB +static PHP_METHOD(swoole_http_response, gzip); +#endif +#ifdef SW_USE_HTTP2 +static PHP_METHOD(swoole_http_response, trailer); +#endif +static PHP_METHOD(swoole_http_response, status); +static PHP_METHOD(swoole_http_response, __destruct); + +static sw_inline char* http_get_method_name(int method) +{ + switch (method) + { + case PHP_HTTP_GET: + return "GET"; + case PHP_HTTP_POST: + return "POST"; + case PHP_HTTP_HEAD: + return "HEAD"; + case PHP_HTTP_PUT: + return "PUT"; + case PHP_HTTP_DELETE: + return "DELETE"; + case PHP_HTTP_PATCH: + return "PATCH"; + case PHP_HTTP_CONNECT: + return "CONNECT"; + case PHP_HTTP_OPTIONS: + return "OPTIONS"; + case PHP_HTTP_TRACE: + return "TRACE"; + case PHP_HTTP_COPY: + return "COPY"; + case PHP_HTTP_LOCK: + return "LOCK"; + case PHP_HTTP_MKCOL: + return "MKCOL"; + case PHP_HTTP_MOVE: + return "MOVE"; + case PHP_HTTP_PROPFIND: + return "PROPFIND"; + case PHP_HTTP_PROPPATCH: + return "PROPPATCH"; + case PHP_HTTP_UNLOCK: + return "UNLOCK"; + /* subversion */ + case PHP_HTTP_REPORT: + return "REPORT"; + case PHP_HTTP_MKACTIVITY: + return "MKACTIVITY"; + case PHP_HTTP_CHECKOUT: + return "CHECKOUT"; + case PHP_HTTP_MERGE: + return "MERGE"; + /* upnp */ + case PHP_HTTP_MSEARCH: + return "MSEARCH"; + case PHP_HTTP_NOTIFY: + return "NOTIFY"; + case PHP_HTTP_SUBSCRIBE: + return "SUBSCRIBE"; + case PHP_HTTP_UNSUBSCRIBE: + return "UNSUBSCRIBE"; + case PHP_HTTP_NOT_IMPLEMENTED: + return "IMPLEMENTED"; + default: + return NULL; + } +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_server_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +#ifdef SW_HAVE_ZLIB +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_gzip, 0, 0, 0) + ZEND_ARG_INFO(0, compress_level) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_status, 0, 0, 1) + ZEND_ARG_INFO(0, http_code) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_header, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, ucwords) +ZEND_END_ARG_INFO() + +#ifdef SW_USE_HTTP2 +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_trailer, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, ucwords) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_cookie, 0, 0, 1) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, expires) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, domain) + ZEND_ARG_INFO(0, secure) + ZEND_ARG_INFO(0, httponly) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_write, 0, 0, 1) + ZEND_ARG_INFO(0, content) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_end, 0, 0, 0) + ZEND_ARG_INFO(0, content) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_sendfile, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_redirect, 0, 0, 1) + ZEND_ARG_INFO(0, location) + ZEND_ARG_INFO(0, http_code) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http_response_create, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +static const php_http_parser_settings http_parser_settings = +{ + NULL, + http_request_on_path, + http_request_on_query_string, + NULL, + NULL, + http_request_on_header_field, + http_request_on_header_value, + http_request_on_headers_complete, + http_request_on_body, + http_request_message_complete +}; + +static const multipart_parser_settings mt_parser_settings = +{ + multipart_body_on_header_field, + multipart_body_on_header_value, + multipart_body_on_data, + NULL, + multipart_body_on_header_complete, + multipart_body_on_data_end, + NULL, +}; + +const zend_function_entry swoole_http_server_methods[] = +{ + PHP_ME(swoole_http_server, on, arginfo_swoole_http_server_on, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_server, start, arginfo_swoole_http_void, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +const zend_function_entry swoole_http_request_methods[] = +{ + PHP_ME(swoole_http_request, rawcontent, arginfo_swoole_http_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_request, getData, arginfo_swoole_http_void, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_ME(swoole_http_request, __destruct, arginfo_swoole_http_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FE_END +}; + +const zend_function_entry swoole_http_response_methods[] = +{ + PHP_ME(swoole_http_response, initHeader, arginfo_swoole_http_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, cookie, arginfo_swoole_http_response_cookie, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, rawcookie, arginfo_swoole_http_response_cookie, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, status, arginfo_swoole_http_response_status, ZEND_ACC_PUBLIC) +#ifdef SW_HAVE_ZLIB + PHP_ME(swoole_http_response, gzip, arginfo_swoole_http_response_gzip, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_http_response, header, arginfo_swoole_http_response_header, ZEND_ACC_PUBLIC) +#ifdef SW_USE_HTTP2 + PHP_ME(swoole_http_response, trailer, arginfo_swoole_http_response_trailer, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_http_response, write, arginfo_swoole_http_response_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, end, arginfo_swoole_http_response_end, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, sendfile, arginfo_swoole_http_response_sendfile, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, redirect, arginfo_swoole_http_response_redirect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, detach, arginfo_swoole_http_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http_response, create, arginfo_swoole_http_response_create, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_ME(swoole_http_response, __destruct, arginfo_swoole_http_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FE_END +}; + +static int http_request_on_path(php_http_parser *parser, const char *at, size_t length) +{ + http_context *ctx = parser->data; + ctx->request.path = estrndup(at, length); + ctx->request.path_len = length; + return 0; +} + +static int http_request_on_query_string(php_http_parser *parser, const char *at, size_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + http_context *ctx = parser->data; + + //no need free, will free by treat_data + char *query = estrndup(at, length); + sw_add_assoc_stringl_ex(ctx->request.zserver, ZEND_STRS("query_string"), query, length, 1); + + zval *zrequest_object = ctx->request.zobject; + zval *zget; + swoole_http_server_array_init(get, request); + + //parse url params + sapi_module.treat_data(PARSE_STRING, query, zget TSRMLS_CC); + + return 0; +} + +static int http_request_on_header_field(php_http_parser *parser, const char *at, size_t length) +{ + http_context *ctx = parser->data; + if (ctx->current_header_name_allocated) + { + efree(ctx->current_header_name); + ctx->current_header_name_allocated = 0; + } + ctx->current_header_name = (char *) at; + ctx->current_header_name_len = length; + return 0; +} + +int swoole_http_parse_form_data(http_context *ctx, const char *boundary_str, int boundary_len TSRMLS_DC) +{ + multipart_parser *mt_parser = multipart_parser_init(boundary_str, boundary_len, &mt_parser_settings); + if (!mt_parser) + { + swoole_php_fatal_error(E_WARNING, "multipart_parser_init() failed."); + return SW_ERR; + } + + ctx->mt_parser = mt_parser; + mt_parser->data = ctx; + + return SW_OK; +} + +static void http_parse_cookie(zval *array, const char *at, size_t length) +{ + char keybuf[SW_HTTP_COOKIE_KEYLEN]; + char valbuf[SW_HTTP_COOKIE_VALLEN]; + char *_c = (char *) at; + + char *_value; + int klen = 0; + int vlen = 0; + int state = -1; + + int i = 0, j = 0; + while (_c < at + length) + { + if (state <= 0 && *_c == '=') + { + klen = i - j + 1; + if (klen >= SW_HTTP_COOKIE_KEYLEN) + { + swWarn("cookie key is too large."); + return; + } + memcpy(keybuf, at + j, klen - 1); + keybuf[klen - 1] = 0; + + j = i + 1; + state = 1; + } + else if (state == 1 && *_c == ';') + { + vlen = i - j; + if (vlen >= SW_HTTP_COOKIE_VALLEN) + { + swWarn("cookie value is too large."); + return; + } + memcpy(valbuf, (char *) at + j, vlen); + valbuf[vlen] = 0; + _value = http_trim_double_quote(valbuf, &vlen); + vlen = php_url_decode(_value, vlen); + if (klen > 1) + { + sw_add_assoc_stringl_ex(array, keybuf, klen, _value, vlen, 1); + } + j = i + 1; + state = -1; + } + else if (state < 0) + { + if (isspace(*_c)) + { + //Remove leading spaces from cookie names + ++j; + } + else + { + state = 0; + } + } + _c++; + i++; + } + if (j < length) + { + vlen = i - j; + if (klen >= SW_HTTP_COOKIE_KEYLEN) + { + swWarn("cookie key is too large."); + return; + } + keybuf[klen - 1] = 0; + if (vlen >= SW_HTTP_COOKIE_VALLEN) + { + swWarn("cookie value is too large."); + return; + } + memcpy(valbuf, (char *) at + j, vlen); + valbuf[vlen] = 0; + _value = http_trim_double_quote(valbuf, &vlen); + vlen = php_url_decode(_value, vlen); + if (klen > 1) + { + sw_add_assoc_stringl_ex(array, keybuf, klen, _value, vlen, 1); + } + } +} + +static int http_request_on_header_value(php_http_parser *parser, const char *at, size_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + size_t offset = 0; + http_context *ctx = parser->data; + zval *zrequest_object = ctx->request.zobject; + size_t header_len = ctx->current_header_name_len; + char *header_name = zend_str_tolower_dup(ctx->current_header_name, header_len); + + if (strncmp(header_name, "cookie", header_len) == 0) + { + zval *zcookie; + if (length >= SW_HTTP_COOKIE_VALLEN) + { + swWarn("cookie is too large."); + } + else + { + swoole_http_server_array_init(cookie, request); + http_parse_cookie(zcookie, at, length); + } + goto free_memory; + } + else if (SwooleG.serv->listen_list->open_websocket_protocol && strncmp(header_name, "upgrade", header_len) == 0 && strncasecmp(at, "websocket", length) == 0) + { + swConnection *conn = swWorker_get_connection(SwooleG.serv, ctx->fd); + if (!conn) + { + swWarn("connection[%d] is closed.", ctx->fd); + return SW_ERR; + } + conn->websocket_status = WEBSOCKET_STATUS_CONNECTION; + } + else if (parser->method == PHP_HTTP_POST || parser->method == PHP_HTTP_PUT || parser->method == PHP_HTTP_DELETE || parser->method == PHP_HTTP_PATCH) + { + if (strncmp(header_name, "content-type", header_len) == 0) + { + if (http_strncasecmp("application/x-www-form-urlencoded", at, length)) + { + ctx->request.post_form_urlencoded = 1; + } + else if (http_strncasecmp("multipart/form-data", at, length)) + { + offset = sizeof("multipart/form-data;") - 1; + + while (at[offset] == ' ') + { + offset += 1; + } + + offset += sizeof("boundary=") - 1; + + int boundary_len = length - offset; + char *boundary_str = (char *) at + length - boundary_len; + + if (boundary_len <= 0) + { + swWarn("invalid multipart/form-data body.", ctx->fd); + return 0; + } + if (boundary_len >= 2 && boundary_str[0] == '"' && *(boundary_str + boundary_len - 1) == '"') + { + boundary_str++; + boundary_len -= 2; + } + + swoole_http_parse_form_data(ctx, boundary_str, boundary_len TSRMLS_CC); + } + } + } + + zval *header = ctx->request.zheader; + sw_add_assoc_stringl_ex(header, header_name, ctx->current_header_name_len + 1, (char *) at, length, 1); + + free_memory: + if (ctx->current_header_name_allocated) + { + efree(ctx->current_header_name); + ctx->current_header_name_allocated = 0; + } + efree(header_name); + + return 0; +} + +static int http_request_on_headers_complete(php_http_parser *parser) +{ + http_context *ctx = parser->data; + if (ctx->current_header_name_allocated) + { + efree(ctx->current_header_name); + ctx->current_header_name_allocated = 0; + } + ctx->current_header_name = NULL; + + return 0; +} + +static int multipart_body_on_header_field(multipart_parser* p, const char *at, size_t length) +{ + http_context *ctx = p->data; + return http_request_on_header_field(&ctx->parser, at, length); +} + +static int multipart_body_on_header_value(multipart_parser* p, const char *at, size_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + char value_buf[SW_HTTP_COOKIE_KEYLEN]; + int value_len; + + http_context *ctx = p->data; + /** + * Hash collision attack + */ + if (ctx->input_var_num > PG(max_input_vars)) + { + swoole_php_error(E_WARNING, "Input variables exceeded %ld. " + "To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); + return SW_OK; + } + else + { + ctx->input_var_num++; + } + + size_t header_len = ctx->current_header_name_len; + char *headername = zend_str_tolower_dup(ctx->current_header_name, header_len); + + if (strncasecmp(headername, "content-disposition", header_len) == 0) + { + //not form data + if (swoole_strnpos((char *) at, length, ZEND_STRL("form-data;")) < 0) + { + return SW_OK; + } + + zval *tmp_array; + SW_MAKE_STD_ZVAL(tmp_array); + array_init(tmp_array); + http_parse_cookie(tmp_array, (char *) at + sizeof("form-data;") - 1, length - sizeof("form-data;") + 1); + + zval *form_name; + if (sw_zend_hash_find(Z_ARRVAL_P(tmp_array), ZEND_STRS("name"), (void **) &form_name) == FAILURE) + { + return SW_OK; + } + + if (Z_STRLEN_P(form_name) >= SW_HTTP_COOKIE_KEYLEN) + { + swWarn("form_name[%s] is too large.", Z_STRVAL_P(form_name)); + return SW_OK; + } + + strncpy(value_buf, Z_STRVAL_P(form_name), Z_STRLEN_P(form_name)); + value_len = Z_STRLEN_P(form_name); + char *tmp = http_trim_double_quote(value_buf, &value_len); + + zval *filename; + //POST form data + if (sw_zend_hash_find(Z_ARRVAL_P(tmp_array), ZEND_STRS("filename"), (void **) &filename) == FAILURE) + { + ctx->current_form_data_name = estrndup(tmp, value_len); + ctx->current_form_data_name_len = value_len; + } + //upload file + else + { + ctx->current_input_name = estrndup(tmp, value_len); + + zval *multipart_header = NULL; + SW_ALLOC_INIT_ZVAL(multipart_header); + array_init(multipart_header); + + sw_add_assoc_string(multipart_header, "name", "", 1); + sw_add_assoc_string(multipart_header, "type", "", 1); + sw_add_assoc_string(multipart_header, "tmp_name", "", 1); + add_assoc_long(multipart_header, "error", HTTP_UPLOAD_ERR_OK); + add_assoc_long(multipart_header, "size", 0); + + strncpy(value_buf, Z_STRVAL_P(filename), Z_STRLEN_P(filename)); + value_len = Z_STRLEN_P(filename); + tmp = http_trim_double_quote(value_buf, &value_len); + + sw_add_assoc_stringl(multipart_header, "name", tmp, value_len, 1); + + ctx->current_multipart_header = multipart_header; + } + sw_zval_ptr_dtor(&tmp_array); + } + + if (strncasecmp(headername, "content-type", header_len) == 0 && ctx->current_multipart_header) + { + sw_add_assoc_stringl(ctx->current_multipart_header, "type", (char * ) at, length, 1); + } + + if (ctx->current_header_name_allocated) + { + efree(ctx->current_header_name); + ctx->current_header_name_allocated = 0; + } + efree(headername); + + return 0; +} + +static int multipart_body_on_data(multipart_parser* p, const char *at, size_t length) +{ + http_context *ctx = p->data; + if (ctx->current_form_data_name) + { + swString_append_ptr(swoole_http_form_data_buffer, (char*) at, length); + return 0; + } + if (p->fp == NULL) + { + return 0; + } + int n = fwrite(at, sizeof(char), length, (FILE *) p->fp); + if (n != length) + { + zval *multipart_header = ctx->current_multipart_header; + add_assoc_long(multipart_header, "error", HTTP_UPLOAD_ERR_CANT_WRITE); + + fclose((FILE *) p->fp); + p->fp = NULL; + + swWarn("write upload file failed. Error %s[%d]", strerror(errno), errno); + } + return 0; +} + +#if 0 +static void get_random_file_name(char *des, const char *src) +{ + unsigned char digest[16] = {0}; + char buf[19] = {0}; + int n = sprintf(buf, "%s%d", src, swoole_system_random(0, 9999)); + + PHP_MD5_CTX ctx; + PHP_MD5Init(&ctx); + PHP_MD5Update(&ctx, buf, n); + PHP_MD5Final(digest, &ctx); + make_digest_ex(des, digest, 16); +} +#endif + +static int multipart_body_on_header_complete(multipart_parser* p) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_context *ctx = p->data; + if (!ctx->current_input_name) + { + return 0; + } + + zval *multipart_header = ctx->current_multipart_header; + zval *zrequest_object = ctx->request.zobject; + zval *zerr = NULL; + if (sw_zend_hash_find(Z_ARRVAL_P(multipart_header), ZEND_STRS("error"), (void **) &zerr) == FAILURE) + { + return 0; + } + if (Z_TYPE_P(zerr) == IS_LONG && Z_LVAL_P(zerr) != HTTP_UPLOAD_ERR_OK) + { + return 0; + } + + char file_path[SW_HTTP_UPLOAD_TMPDIR_SIZE]; + snprintf(file_path, SW_HTTP_UPLOAD_TMPDIR_SIZE, "%s/swoole.upfile.XXXXXX", SwooleG.serv->upload_tmp_dir); + int tmpfile = swoole_tmpfile(file_path); + if (tmpfile < 0) + { + return 0; + } + + FILE *fp = fdopen(tmpfile, "wb+"); + if (fp == NULL) + { + add_assoc_long(multipart_header, "error", HTTP_UPLOAD_ERR_NO_TMP_DIR); + swWarn("fopen(%s) failed. Error %s[%d]", file_path, strerror(errno), errno); + return 0; + } + + p->fp = fp; + sw_add_assoc_string(multipart_header, "tmp_name", file_path, 1); + + zval *ztmpfiles = sw_zend_read_property(swoole_http_request_class_entry_ptr, zrequest_object, ZEND_STRL("tmpfiles"), 1 TSRMLS_CC); + if (ztmpfiles == NULL || ZVAL_IS_NULL(ztmpfiles)) + { + swoole_http_server_array_init(tmpfiles, request); + } + + int file_path_len = strlen(file_path); + sw_add_next_index_stringl(ztmpfiles, file_path, file_path_len, 1); + char *temp_filename = file_path; + sw_zend_hash_add(SG(rfc1867_uploaded_files), temp_filename, file_path_len + 1, &temp_filename, sizeof(char *), NULL); + + return 0; +} + +static int multipart_body_on_data_end(multipart_parser* p) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_context *ctx = p->data; + zval *zrequest_object = ctx->request.zobject; + if (ctx->current_form_data_name) + { + zval *zpost = sw_zend_read_property(swoole_http_request_class_entry_ptr, zrequest_object, ZEND_STRL("post"), 1 TSRMLS_CC); + if (ZVAL_IS_NULL(zpost)) + { + swoole_http_server_array_init(post, request); + } + + php_register_variable_safe(ctx->current_form_data_name, swoole_http_form_data_buffer->str, + swoole_http_form_data_buffer->length, zpost TSRMLS_CC); + + efree(ctx->current_form_data_name); + ctx->current_form_data_name = NULL; + ctx->current_form_data_name_len = 0; + swString_clear(swoole_http_form_data_buffer); + return 0; + } + + if (!ctx->current_input_name) + { + return 0; + } + + zval *multipart_header = ctx->current_multipart_header; + if (p->fp != NULL) + { + long size = swoole_file_get_size((FILE *) p->fp); + add_assoc_long(multipart_header, "size", size); + if (size == 0) + { + add_assoc_long(multipart_header, "error", HTTP_UPLOAD_ERR_NO_FILE); + } + + fclose((FILE *) p->fp); + p->fp = NULL; + } + + zval *zfiles = ctx->request.zfiles; + if (!zfiles) + { + swoole_http_server_array_init(files, request); + } + + php_register_variable_ex(ctx->current_input_name, multipart_header, zfiles TSRMLS_CC); + + efree(ctx->current_input_name); + ctx->current_input_name = NULL; + efree(ctx->current_multipart_header); + ctx->current_multipart_header = NULL; + + return 0; +} + +static int http_request_on_body(php_http_parser *parser, const char *at, size_t length) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_context *ctx = parser->data; + zval *zrequest_object = ctx->request.zobject; + char *body; + + ctx->request.post_length = length; + if (SwooleG.serv->http_parse_post && ctx->request.post_form_urlencoded) + { + zval *zpost; + swoole_http_server_array_init(post, request); + body = estrndup(at, length); + + sapi_module.treat_data(PARSE_STRING, body, zpost TSRMLS_CC); + } + else if (ctx->mt_parser != NULL) + { + multipart_parser *multipart_parser = ctx->mt_parser; + char *c = (char *) at; + while (*c == '\r' && *(c + 1) == '\n') + { + c += 2; + } + size_t n = multipart_parser_execute(multipart_parser, c, length); + if (n != length) + { + swoole_php_fatal_error(E_WARNING, "parse multipart body failed."); + } + } + + return 0; +} + +static int http_request_message_complete(php_http_parser *parser) +{ + http_context *ctx = parser->data; + ctx->request.version = parser->http_major * 100 + parser->http_minor; + + const char *vpath = ctx->request.path, *end = vpath + ctx->request.path_len, *p = end; + ctx->request.ext = end; + ctx->request.ext_len = 0; + while (p > vpath) + { + --p; + if (*p == '.') + { + ++p; + ctx->request.ext = p; + ctx->request.ext_len = end - p; + break; + } + } + ctx->request_read = 1; + + if (ctx->mt_parser) + { + multipart_parser_free(ctx->mt_parser); + ctx->mt_parser = NULL; + } + + return 0; +} + +static int http_onReceive(swServer *serv, swEventData *req) +{ + if (swEventData_is_dgram(req->info.type)) + { + return php_swoole_onReceive(serv, req); + } + + int fd = req->info.fd; + swConnection *conn = swServer_connection_verify_no_ssl(SwooleG.serv, fd); + if (!conn) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_NOT_EXIST, "connection[%d] is closed.", fd); + return SW_ERR; + } + swListenPort *port = serv->connection_list[req->info.from_fd].object; + //other server port + if (!port->open_http_protocol) + { + return php_swoole_onReceive(serv, req); + } + //websocket client + if (conn->websocket_status == WEBSOCKET_STATUS_ACTIVE) + { + return swoole_websocket_onMessage(req); + } + + swoole_http_client *client = swArray_alloc(http_client_array, conn->fd); + if (!client) + { + return SW_OK; + } + client->fd = fd; + +#ifdef SW_USE_HTTP2 + if (conn->http2_stream) + { + client->http2 = 1; + return swoole_http2_onFrame(client, req); + } +#endif + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + http_context *ctx = swoole_http_context_new(client TSRMLS_CC); + php_http_parser *parser = &ctx->parser; + zval *zserver = ctx->request.zserver; + + parser->data = ctx; + + zval *zdata; + SW_ALLOC_INIT_ZVAL(zdata); + php_swoole_get_recv_data(zdata, req, NULL, 0); + + swTrace("httpRequest %d bytes:\n---------------------------------------\n%s\n", (int)Z_STRLEN_P(zdata), Z_STRVAL_P(zdata)); + +#ifdef SW_USE_PICOHTTPPARSER + long n = http_fast_parse(parser, Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); +#else + php_http_parser_init(parser, PHP_HTTP_REQUEST); + long n = php_http_parser_execute(parser, &http_parser_settings, Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); +#endif + + if (n < 0) + { + sw_zval_free(zdata); + bzero(client, sizeof(swoole_http_client)); + swWarn("php_http_parser_execute failed."); + if (conn->websocket_status == WEBSOCKET_STATUS_CONNECTION) + { + return swServer_tcp_close(SwooleG.serv, fd, 1); + } + } + else + { + zval *retval = NULL; + + zval *zrequest_object = ctx->request.zobject; + zval *zresponse_object = ctx->response.zobject; + + SW_SEPARATE_ZVAL(zrequest_object); + SW_SEPARATE_ZVAL(zresponse_object); + + ctx->keepalive = php_http_should_keep_alive(parser); + char *method_name = http_get_method_name(parser->method); + + sw_add_assoc_string(zserver, "request_method", method_name, 1); + sw_add_assoc_stringl(zserver, "request_uri", ctx->request.path, ctx->request.path_len, 1); + sw_add_assoc_stringl(zserver, "path_info", ctx->request.path, ctx->request.path_len, 1); + sw_add_assoc_long_ex(zserver, ZEND_STRS("request_time"), serv->gs->now); + + // Add REQUEST_TIME_FLOAT + double now_float = swoole_microtime(); + sw_add_assoc_double_ex(zserver, ZEND_STRS("request_time_float"), now_float); + + swConnection *conn = swWorker_get_connection(serv, fd); + if (!conn) + { + sw_zval_free(zdata); + swWarn("connection[%d] is closed.", fd); + return SW_ERR; + } + + swoole_set_property(zrequest_object, 0, zdata); + + add_assoc_long(ctx->request.zserver, "server_port", swConnection_get_port(&SwooleG.serv->connection_list[conn->from_fd])); + add_assoc_long(ctx->request.zserver, "remote_port", swConnection_get_port(conn)); + sw_add_assoc_string(zserver, "remote_addr", swConnection_get_ip(conn), 1); + add_assoc_long(zserver, "master_time", conn->last_time); + + if (ctx->request.version == 101) + { + sw_add_assoc_string(zserver, "server_protocol", "HTTP/1.1", 1); + } + else + { + sw_add_assoc_string(zserver, "server_protocol", "HTTP/1.0", 1); + } + + sw_add_assoc_string(zserver, "server_software", SW_HTTP_SERVER_SOFTWARE, 1); + + zval *zcallback = php_swoole_server_get_callback(serv, req->info.from_fd, SW_SERVER_CB_onHandShake); + //websocket handshake + if (conn->websocket_status == WEBSOCKET_STATUS_CONNECTION && zcallback == NULL) + { + swoole_websocket_onHandshake(port, ctx); + goto free_object; + } + + int callback_type = 0; + if (conn->websocket_status == WEBSOCKET_STATUS_CONNECTION) + { + callback_type = SW_SERVER_CB_onHandShake; + conn->websocket_status = WEBSOCKET_STATUS_HANDSHAKE; + ctx->upgrade = 1; + } + else + { + callback_type = SW_SERVER_CB_onRequest; + zcallback = php_swoole_server_get_callback(serv, req->info.from_fd, SW_SERVER_CB_onRequest); + //no have onRequest callback + if (zcallback == NULL) + { + swoole_websocket_onRequest(ctx); + goto free_object; + } + } + + if (SwooleG.enable_coroutine) + { + zval *args[2]; + args[0] = zrequest_object; + args[1] = zresponse_object; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, callback_type); + int ret = coro_create(cache, args, 2, &retval, NULL, NULL); + if (ret < 0) + { + sw_zval_ptr_dtor(&zrequest_object); + sw_zval_ptr_dtor(&zresponse_object); + if (ret == CORO_LIMIT) + { + serv->factory.end(&SwooleG.serv->factory, fd); + } + return SW_OK; + } + } + else + { + zval **args[2]; + args[0] = &zrequest_object; + args[1] = &zresponse_object; + + zcallback = php_swoole_server_get_callback(serv, req->info.from_fd, callback_type); + zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, req->info.from_fd, callback_type); + if (sw_call_user_function_fast(zcallback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onRequest handler error"); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + //websocket user handshake + if (conn->websocket_status == WEBSOCKET_STATUS_HANDSHAKE) + { + //handshake success + if (retval && Z_BVAL_P(retval)) + { + conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; + } + } + free_object: bzero(client, sizeof(swoole_http_client)); + sw_zval_ptr_dtor(&zrequest_object); + sw_zval_ptr_dtor(&zresponse_object); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + + return SW_OK; +} + +static void http_onClose(swServer *serv, swDataHead *ev) +{ + int fd = ev->fd; + + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (!conn) + { + return; + } + swoole_http_client *client = swArray_fetch(http_client_array, conn->fd); + if (!client) + { + return; + } +#ifdef SW_USE_HTTP2 + if (client->http2) + { + swoole_http2_free(client); + } +#endif + zval *zcallback = php_swoole_server_get_callback(serv, ev->from_fd, SW_SERVER_CB_onClose); + if (!zcallback) + { + return; + } + php_swoole_onClose(serv, ev); +} + +void swoole_http_server_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_http_server_ce, "swoole_http_server", "Swoole\\Http\\Server", swoole_http_server_methods); + swoole_http_server_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_http_server_ce, swoole_server_class_entry_ptr, "swoole_server" TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http_server, "Swoole\\Http\\Server"); + + zend_declare_property_null(swoole_http_server_class_entry_ptr, SW_STRL("onRequest")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_server_class_entry_ptr, SW_STRL("onHandshake")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_server_class_entry_ptr, SW_STRL("setting")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + SWOOLE_INIT_CLASS_ENTRY(swoole_http_response_ce, "swoole_http_response", "Swoole\\Http\\Response", swoole_http_response_methods); + swoole_http_response_class_entry_ptr = zend_register_internal_class(&swoole_http_response_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http_response, "Swoole\\Http\\Response"); + + zend_declare_property_long(swoole_http_response_class_entry_ptr, SW_STRL("fd")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_response_class_entry_ptr, SW_STRL("header")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_response_class_entry_ptr, SW_STRL("cookie")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_response_class_entry_ptr, SW_STRL("trailer")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + SWOOLE_INIT_CLASS_ENTRY(swoole_http_request_ce, "swoole_http_request", "Swoole\\Http\\Request", swoole_http_request_methods); + swoole_http_request_class_entry_ptr = zend_register_internal_class(&swoole_http_request_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http_request, "Swoole\\Http\\Request"); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Http\\Server", swoole_http_server_class_entry_ptr); + sw_zend_register_class_alias("Co\\Http\\Request", swoole_http_request_class_entry_ptr); + sw_zend_register_class_alias("Co\\Http\\Response", swoole_http_response_class_entry_ptr); + } + + zend_declare_property_long(swoole_http_request_class_entry_ptr, SW_STRL("fd")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("header")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("server")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("request")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("cookie")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("get")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("files")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("post")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http_request_class_entry_ptr, SW_STRL("tmpfiles")-1, ZEND_ACC_PUBLIC TSRMLS_CC); +} + +static PHP_METHOD(swoole_http_server, on) +{ + zval *callback; + zval *event_name; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_error(E_WARNING, "server is running. unable to register event callback function."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &event_name, &callback) == FAILURE) + { + return; + } + +#ifdef PHP_SWOOLE_CHECK_CALLBACK + char *func_name = NULL; +#if !defined(SW_COROUTINE) && !defined(PHP_SWOOLE_ENABLE_FASTCALL) + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) +#else + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) +#endif + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); +#elif defined(PHP_SWOOLE_CHECK_CALLBACK) + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + + if (strncasecmp("request", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) + { + zend_update_property(swoole_http_server_class_entry_ptr, getThis(), ZEND_STRL("onRequest"), callback TSRMLS_CC); + php_sw_server_callbacks[SW_SERVER_CB_onRequest] = sw_zend_read_property(swoole_http_server_class_entry_ptr, getThis(), ZEND_STRL("onRequest"), 0 TSRMLS_CC); + sw_copy_to_stack(php_sw_server_callbacks[SW_SERVER_CB_onRequest], _php_sw_server_callbacks[SW_SERVER_CB_onRequest]); +#if defined(SW_COROUTINE) || defined(PHP_SWOOLE_ENABLE_FASTCALL) + php_sw_server_caches[SW_SERVER_CB_onRequest] = func_cache; +#endif + } + else if (strncasecmp("handshake", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) + { + zend_update_property(swoole_http_server_class_entry_ptr, getThis(), ZEND_STRL("onHandshake"), callback TSRMLS_CC); + php_sw_server_callbacks[SW_SERVER_CB_onHandShake] = sw_zend_read_property(swoole_http_server_class_entry_ptr, getThis(), ZEND_STRL("onHandshake"), 0 TSRMLS_CC); + sw_copy_to_stack(php_sw_server_callbacks[SW_SERVER_CB_onHandShake], _php_sw_server_callbacks[SW_SERVER_CB_onHandShake]); +#if defined(SW_COROUTINE) || defined(PHP_SWOOLE_ENABLE_FASTCALL) + php_sw_server_caches[SW_SERVER_CB_onHandShake] = func_cache; +#endif + } + else + { +#if defined(SW_COROUTINE) || defined(PHP_SWOOLE_ENABLE_FASTCALL) + efree(func_cache); +#endif + zval *obj = getThis(); + sw_zend_call_method_with_2_params(&obj, swoole_server_class_entry_ptr, NULL, "on", &return_value, event_name, callback); + } +} + +http_context* swoole_http_context_new(swoole_http_client* client TSRMLS_DC) +{ + http_context *ctx = emalloc(sizeof(http_context)); + if (!ctx) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_MALLOC_FAIL, "emalloc(%ld) failed.", sizeof(http_context)); + return NULL; + } + bzero(ctx, sizeof(http_context)); + + zval *zrequest_object; +#if PHP_MAJOR_VERSION >= 7 + zrequest_object = &ctx->request._zobject; +#else + SW_ALLOC_INIT_ZVAL(zrequest_object); +#endif + ctx->request.zobject = zrequest_object; + object_init_ex(zrequest_object, swoole_http_request_class_entry_ptr); + swoole_set_object(zrequest_object, ctx); + + zval *zresponse_object; +#if PHP_MAJOR_VERSION >= 7 + zresponse_object = &ctx->response._zobject; +#else + SW_ALLOC_INIT_ZVAL(zresponse_object); +#endif + ctx->response.zobject = zresponse_object; + object_init_ex(zresponse_object, swoole_http_response_class_entry_ptr); + swoole_set_object(zresponse_object, ctx); + + //socket fd + zend_update_property_long(swoole_http_response_class_entry_ptr, zresponse_object, ZEND_STRL("fd"), client->fd TSRMLS_CC); + zend_update_property_long(swoole_http_request_class_entry_ptr, zrequest_object, ZEND_STRL("fd"), client->fd TSRMLS_CC); + +#if PHP_MEMORY_DEBUG + php_vmstat.new_http_request ++; +#endif + + zval *zheader; + swoole_http_server_array_init(header, request); + + zval *zserver; + swoole_http_server_array_init(server, request); + + ctx->fd = client->fd; + ctx->client = client; + + return ctx; +} + +void swoole_http_context_free(http_context *ctx TSRMLS_DC) +{ + swoole_set_object(ctx->response.zobject, NULL); + http_request *req = &ctx->request; + if (req->path) + { + efree(req->path); + } +#ifdef SW_USE_HTTP2 + if (req->post_buffer) + { + swString_free(req->post_buffer); + } +#endif + efree(ctx); +} + +static char *http_status_message(int code) +{ + switch (code) + { + case 100: + return "100 Continue"; + case 101: + return "101 Switching Protocols"; + case 201: + return "201 Created"; + case 202: + return "202 Accepted"; + case 203: + return "203 Non-Authoritative Information"; + case 204: + return "204 No Content"; + case 205: + return "205 Reset Content"; + case 206: + return "206 Partial Content"; + case 207: + return "207 Multi-Status"; + case 208: + return "208 Already Reported"; + case 226: + return "226 IM Used"; + case 300: + return "300 Multiple Choices"; + case 301: + return "301 Moved Permanently"; + case 302: + return "302 Found"; + case 303: + return "303 See Other"; + case 304: + return "304 Not Modified"; + case 305: + return "305 Use Proxy"; + case 307: + return "307 Temporary Redirect"; + case 400: + return "400 Bad Request"; + case 401: + return "401 Unauthorized"; + case 402: + return "402 Payment Required"; + case 403: + return "403 Forbidden"; + case 404: + return "404 Not Found"; + case 405: + return "405 Method Not Allowed"; + case 406: + return "406 Not Acceptable"; + case 407: + return "407 Proxy Authentication Required"; + case 408: + return "408 Request Timeout"; + case 409: + return "409 Conflict"; + case 410: + return "410 Gone"; + case 411: + return "411 Length Required"; + case 412: + return "412 Precondition Failed"; + case 413: + return "413 Request Entity Too Large"; + case 414: + return "414 Request URI Too Long"; + case 415: + return "415 Unsupported Media Type"; + case 416: + return "416 Requested Range Not Satisfiable"; + case 417: + return "417 Expectation Failed"; + case 418: + return "418 I'm a teapot"; + case 421: + return "421 Misdirected Request"; + case 422: + return "422 Unprocessable Entity"; + case 423: + return "423 Locked"; + case 424: + return "424 Failed Dependency"; + case 426: + return "426 Upgrade Required"; + case 428: + return "428 Precondition Required"; + case 429: + return "429 Too Many Requests"; + case 431: + return "431 Request Header Fields Too Large"; + case 500: + return "500 Internal Server Error"; + case 501: + return "501 Method Not Implemented"; + case 502: + return "502 Bad Gateway"; + case 503: + return "503 Service Unavailable"; + case 504: + return "504 Gateway Timeout"; + case 505: + return "505 HTTP Version Not Supported"; + case 506: + return "506 Variant Also Negotiates"; + case 507: + return "507 Insufficient Storage"; + case 508: + return "508 Loop Detected"; + case 510: + return "510 Not Extended"; + case 511: + return "511 Network Authentication Required"; + case 200: + default: + return "200 OK"; + } +} + +static PHP_METHOD(swoole_http_server, start) +{ + int ret; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_error(E_WARNING, "Server is running. Unable to execute swoole_server::start."); + RETURN_FALSE; + } + + php_swoole_register_callback(serv); + + if (serv->listen_list->open_websocket_protocol) + { + if (php_sw_server_callbacks[SW_SERVER_CB_onMessage] == NULL) + { + swoole_php_fatal_error(E_ERROR, "require onMessage callback"); + RETURN_FALSE; + } + if (serv->listen_list->open_http2_protocol == 1) + { + swoole_php_fatal_error(E_ERROR, "cannot use http2 protocol in websocket server"); + RETURN_FALSE; + } + } + else if (php_sw_server_callbacks[SW_SERVER_CB_onRequest] == NULL) + { + swoole_php_fatal_error(E_ERROR, "require onRequest callback"); + RETURN_FALSE; + } + + http_client_array = swArray_new(1024, sizeof(swoole_http_client)); + if (!http_client_array) + { + swoole_php_fatal_error(E_ERROR, "swArray_new(1024, %ld) failed.", sizeof(swoole_http_client)); + RETURN_FALSE; + } + + swoole_http_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!swoole_http_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } + + swoole_http_form_data_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!swoole_http_form_data_buffer) + { + swoole_php_fatal_error(E_ERROR, "[2] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } + +#ifdef SW_HAVE_ZLIB + swoole_zlib_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!swoole_zlib_buffer) + { + swoole_php_fatal_error(E_ERROR, "[3] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } +#endif + + serv->onReceive = http_onReceive; + + if (serv->listen_list->open_http2_protocol) + { + serv->onClose = http_onClose; + } + + zval *zsetting = sw_zend_read_property(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zsetting == NULL || ZVAL_IS_NULL(zsetting)) + { + SW_ALLOC_INIT_ZVAL(zsetting); + array_init(zsetting); +#ifdef HT_ALLOW_COW_VIOLATION + HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(zsetting)); +#endif + zend_update_property(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("setting"), zsetting TSRMLS_CC); + } + + add_assoc_bool(zsetting, "open_http_protocol", 1); + add_assoc_bool(zsetting, "open_mqtt_protocol", 0); + add_assoc_bool(zsetting, "open_eof_check", 0); + add_assoc_bool(zsetting, "open_length_check", 0); + + if (serv->listen_list->open_websocket_protocol) + { + add_assoc_bool(zsetting, "open_websocket_protocol", 1); + } + + serv->listen_list->open_http_protocol = 1; + serv->listen_list->open_mqtt_protocol = 0; + serv->listen_list->open_eof_check = 0; + serv->listen_list->open_length_check = 0; + + //for is_uploaded_file and move_uploaded_file + ALLOC_HASHTABLE(SG(rfc1867_uploaded_files)); + zend_hash_init(SG(rfc1867_uploaded_files), 8, NULL, NULL, 0); + + php_swoole_server_before_start(serv, getThis() TSRMLS_CC); + + ret = swServer_start(serv); + if (ret < 0) + { + swoole_php_fatal_error(E_ERROR, "failed to start server. Error: %s", sw_error); + RETURN_LONG(ret); + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_request, rawcontent) +{ + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + http_request *req = &ctx->request; + if (req->post_length > 0) + { + zval *zdata = swoole_get_property(getThis(), 0); + SW_RETVAL_STRINGL(Z_STRVAL_P(zdata) + Z_STRLEN_P(zdata) - req->post_length, req->post_length, 1); + } +#ifdef SW_USE_HTTP2 + else if (req->post_buffer) + { + SW_RETVAL_STRINGL(req->post_buffer->str, req->post_buffer->length, 1); + } +#endif + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_http_request, getData) +{ + zval *zdata = swoole_get_property(getThis(), 0); + if (zdata) + { + SW_RETURN_STRINGL(Z_STRVAL_P(zdata), Z_STRLEN_P(zdata), 1); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_http_request, __destruct) +{ + zval *ztmpfiles = sw_zend_read_property(swoole_http_request_class_entry_ptr, getThis(), ZEND_STRL("tmpfiles"), 1 TSRMLS_CC); + //upload files + if (ztmpfiles && Z_TYPE_P(ztmpfiles) == IS_ARRAY) + { + zval *file_path; + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(ztmpfiles), file_path) + { + if (Z_TYPE_P(file_path) != IS_STRING) + { + continue; + } + unlink(Z_STRVAL_P(file_path)); + if (SG(rfc1867_uploaded_files)) + { + sw_zend_hash_del(SG(rfc1867_uploaded_files), Z_STRVAL_P(file_path), Z_STRLEN_P(file_path) + 1); + } + } + SW_HASHTABLE_FOREACH_END(); + } + zval *zdata = swoole_get_property(getThis(), 0); + if (zdata) + { + sw_zval_free(zdata); + swoole_set_property(getThis(), 0, NULL); + } + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_http_response, write) +{ + zval *zdata; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + return; + } + + if (ctx->http2) + { + swoole_php_error(E_WARNING, "Http2 client does not support HTTP-CHUNK."); + RETURN_FALSE; + } + + if (!ctx->send_header) + { + ctx->chunk = 1; + swString_clear(swoole_http_buffer); + http_build_header(ctx, getThis(), swoole_http_buffer, -1 TSRMLS_CC); + if (swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length) < 0) + { + ctx->chunk = 0; + ctx->send_header = 0; + RETURN_FALSE; + } + } + + swString http_body; + int length = php_swoole_get_send_data(zdata, &http_body.str TSRMLS_CC); + + if (length < 0) + { + RETURN_FALSE; + } + else if (length == 0) + { + swoole_php_error(E_WARNING, "data to send is empty."); + RETURN_FALSE; + } + else + { + http_body.length = length; + } + + swString_clear(swoole_http_buffer); + + char *hex_string; + int hex_len; + +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + http_response_compress(&http_body, ctx->gzip_level); + + hex_string = swoole_dec2hex(swoole_zlib_buffer->length, 16); + hex_len = strlen(hex_string); + + //"%*s\r\n%*s\r\n", hex_len, hex_string, body.length, body.str + swString_append_ptr(swoole_http_buffer, hex_string, hex_len); + swString_append_ptr(swoole_http_buffer, SW_STRL("\r\n") - 1); + swString_append(swoole_http_buffer, swoole_zlib_buffer); + swString_append_ptr(swoole_http_buffer, SW_STRL("\r\n") - 1); + } + else +#endif + { + hex_string = swoole_dec2hex(http_body.length, 16); + hex_len = strlen(hex_string); + + //"%*s\r\n%*s\r\n", hex_len, hex_string, body.length, body.str + swString_append_ptr(swoole_http_buffer, hex_string, hex_len); + swString_append_ptr(swoole_http_buffer, SW_STRL("\r\n") - 1); + swString_append_ptr(swoole_http_buffer, http_body.str, http_body.length); + swString_append_ptr(swoole_http_buffer, SW_STRL("\r\n") - 1); + } + + sw_free(hex_string); + + swServer *serv = SwooleG.serv; + int ret = swServer_tcp_send(serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); +#ifdef SW_COROUTINE + if (ret < 0 && SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW && serv->send_yield) + { + zval _yield_data; + ZVAL_STRINGL(&_yield_data, swoole_http_buffer->str, swoole_http_buffer->length); + php_swoole_server_send_yield(serv, ctx->fd, &_yield_data, return_value); + if (Z_TYPE_P(return_value) == IS_FALSE) + { + ctx->chunk = 0; + ctx->send_header = 0; + } + return; + } +#endif + + SW_CHECK_RETURN(ret); +} + +static http_context* http_get_context(zval *object, int check_end TSRMLS_DC) +{ + http_context *ctx = swoole_get_object(object); + if (!ctx) + { + swoole_php_fatal_error(E_WARNING, "Http request is finished."); + return NULL; + } + if (check_end && ctx->end) + { + swoole_php_fatal_error(E_WARNING, "Http request is finished."); + return NULL; + } + return ctx; +} + +static void http_build_header(http_context *ctx, zval *object, swString *response, int body_length TSRMLS_DC) +{ + assert(ctx->send_header == 0); + + swServer *serv = SwooleG.serv; + + char buf[SW_HTTP_HEADER_MAX_SIZE]; + int n; + char *date_str; + + /** + * http status line + */ + n = snprintf(buf, sizeof(buf), "HTTP/1.1 %s\r\n", http_status_message(ctx->response.status)); + swString_append_ptr(response, buf, n); + + /** + * http header + */ + zval *header = ctx->response.zheader; + if (header) + { + int flag = 0x0; + HashTable *ht = Z_ARRVAL_P(header); + zval *value = NULL; + char *key = NULL; + uint32_t keylen = 0; + int type; + + SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) + { + if (!key) + { + break; + } + if (strncasecmp(key, "Server", keylen) == 0) + { + flag |= HTTP_RESPONSE_SERVER; + } + else if (strncasecmp(key, "Connection", keylen) == 0) + { + flag |= HTTP_RESPONSE_CONNECTION; + } + else if (strncasecmp(key, "Date", keylen) == 0) + { + flag |= HTTP_RESPONSE_DATE; + } + else if (strncasecmp(key, "Content-Type", keylen) == 0) + { + flag |= HTTP_RESPONSE_CONTENT_TYPE; + } + n = snprintf(buf, sizeof(buf), "%*s: %*s\r\n", keylen - 1, key, Z_STRLEN_P(value), Z_STRVAL_P(value)); + swString_append_ptr(response, buf, n); + } + SW_HASHTABLE_FOREACH_END(); + (void)type; + + if (!(flag & HTTP_RESPONSE_SERVER)) + { + swString_append_ptr(response, ZEND_STRL("Server: "SW_HTTP_SERVER_SOFTWARE"\r\n")); + } + //websocket protocol + if (ctx->upgrade == 1) + { + swString_append_ptr(response, ZEND_STRL("\r\n")); + ctx->send_header = 1; + return; + } + if (!(flag & HTTP_RESPONSE_CONNECTION)) + { + if (ctx->keepalive) + { + swString_append_ptr(response, ZEND_STRL("Connection: keep-alive\r\n")); + } + else + { + swString_append_ptr(response, ZEND_STRL("Connection: close\r\n")); + } + } + if (!(flag & HTTP_RESPONSE_CONTENT_TYPE)) + { + swString_append_ptr(response, ZEND_STRL("Content-Type: text/html\r\n")); + } + if (!(flag & HTTP_RESPONSE_DATE)) + { + date_str = sw_php_format_date(ZEND_STRL(SW_HTTP_DATE_FORMAT), serv->gs->now, 0 TSRMLS_CC); + n = snprintf(buf, sizeof(buf), "Date: %s\r\n", date_str); + swString_append_ptr(response, buf, n); + efree(date_str); + } + } + else + { + //Server + swString_append_ptr(response, ZEND_STRL("Server: "SW_HTTP_SERVER_SOFTWARE"\r\nContent-Type: text/html\r\n")); + if (ctx->keepalive) + { + swString_append_ptr(response, ZEND_STRL("Connection: keep-alive\r\n")); + } + else + { + swString_append_ptr(response, ZEND_STRL("Connection: close\r\n")); + } + //Date + date_str = sw_php_format_date(ZEND_STRL(SW_HTTP_DATE_FORMAT), serv->gs->now, 0 TSRMLS_CC); + n = snprintf(buf, sizeof(buf), "Date: %s\r\n", date_str); + efree(date_str); + swString_append_ptr(response, buf, n); + } + /** + * Http chunk + */ + if (ctx->chunk) + { + swString_append_ptr(response, SW_STRL("Transfer-Encoding: chunked\r\n") - 1); + } + /** + * Content-Length + */ + else + { +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + body_length = swoole_zlib_buffer->length; + } +#endif + n = snprintf(buf, sizeof(buf), "Content-Length: %d\r\n", body_length); + swString_append_ptr(response, buf, n); + } + //http cookies + if (ctx->response.zcookie) + { + zval *value; + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(ctx->response.zcookie), value) + { + if (Z_TYPE_P(value) != IS_STRING) + { + continue; + } + swString_append_ptr(response, SW_STRL("Set-Cookie: ") - 1); + swString_append_ptr(response, Z_STRVAL_P(value), Z_STRLEN_P(value)); + swString_append_ptr(response, SW_STRL("\r\n") - 1); + } + SW_HASHTABLE_FOREACH_END(); + } + //http compress + if (ctx->gzip_enable) + { +#ifdef SW_HTTP_COMPRESS_GZIP + swString_append_ptr(response, SW_STRL("Content-Encoding: gzip\r\n") - 1); +#else + swString_append_ptr(response, SW_STRL("Content-Encoding: deflate\r\n") - 1); +#endif + } + swString_append_ptr(response, ZEND_STRL("\r\n")); + ctx->send_header = 1; +} + +#ifdef SW_HAVE_ZLIB +voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size) +{ + return (voidpf)safe_emalloc(items, size, 0); +} + +void php_zlib_free(voidpf opaque, voidpf address) +{ + efree((void*)address); +} + +static int http_response_compress(swString *body, int level) +{ + assert(level > 0 || level < 10); + + size_t memory_size = ((size_t) ((double) body->length * (double) 1.015)) + 10 + 8 + 4 + 1; + + if (memory_size > swoole_zlib_buffer->size) + { + if (swString_extend(swoole_zlib_buffer, memory_size) < 0) + { + return SW_ERR; + } + } + + z_stream zstream; + memset(&zstream, 0, sizeof(zstream)); + + //deflate: -0xf, gzip: 0x1f +#ifdef SW_HTTP_COMPRESS_GZIP + int encoding = 0x1f; +#else + int encoding = -0xf; +#endif + + int status; + zstream.zalloc = php_zlib_alloc; + zstream.zfree = php_zlib_free; + + if (Z_OK == deflateInit2(&zstream, level, Z_DEFLATED, encoding, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) + { + zstream.next_in = (Bytef *) body->str; + zstream.next_out = (Bytef *) swoole_zlib_buffer->str; + zstream.avail_in = body->length; + zstream.avail_out = swoole_zlib_buffer->size; + + status = deflate(&zstream, Z_FINISH); + deflateEnd(&zstream); + + if (Z_STREAM_END == status) + { + swoole_zlib_buffer->length = zstream.total_out; + return SW_OK; + } + } + else + { + swWarn("deflateInit2() failed."); + } + return SW_ERR; +} +#endif + +static PHP_METHOD(swoole_http_response, initHeader) +{ + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + zval *zresponse_object = ctx->response.zobject; + zval *zheader = ctx->response.zheader; + if (!zheader) + { + swoole_http_server_array_init(header, response); + } + + zval *zcookie = ctx->response.zcookie; + if (!zcookie) + { + swoole_http_server_array_init(cookie, response); + } + + zval *ztrailer = ctx->response.ztrailer; + if (!ztrailer) + { + swoole_http_server_array_init(trailer, response); + } +} + +static PHP_METHOD(swoole_http_response, end) +{ + zval *zdata = NULL; + int ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &zdata) == FAILURE) + { + return; + } + + swString http_body; + + if (zdata) + { + int length = php_swoole_get_send_data(zdata, &http_body.str TSRMLS_CC); + + if (length < 0) + { + RETURN_FALSE; + } + else + { + http_body.length = length; + } + } + else + { + http_body.length = 0; + http_body.str = NULL; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + +#ifdef SW_USE_HTTP2 + if (ctx->http2) + { + swoole_http2_do_response(ctx, &http_body); + RETURN_TRUE; + } +#endif + + if (ctx->chunk) + { + ret = swServer_tcp_send(SwooleG.serv, ctx->fd, SW_STRL("0\r\n\r\n") - 1); + if (ret < 0) + { + RETURN_FALSE; + } + ctx->chunk = 0; + } + //no http chunk + else + { + swString_clear(swoole_http_buffer); +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + if (http_body.length > 0) + { + http_response_compress(&http_body, ctx->gzip_level); + } + else + { + ctx->gzip_enable = 0; + } + } +#endif + http_build_header(ctx, getThis(), swoole_http_buffer, http_body.length TSRMLS_CC); + if (http_body.length > 0) + { +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + swString_append(swoole_http_buffer, swoole_zlib_buffer); + } + else +#endif + { + swString_append(swoole_http_buffer, &http_body); + } + } + + ret = swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); + if (ret < 0) + { + ctx->send_header = 0; + RETURN_FALSE; + } + } + + if (ctx->upgrade) + { + swConnection *conn = swWorker_get_connection(SwooleG.serv, ctx->fd); + if (conn && conn->websocket_status == WEBSOCKET_STATUS_HANDSHAKE && ctx->response.status == 101) + { + conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; + } + } + + if (!ctx->keepalive) + { + swServer_tcp_close(SwooleG.serv, ctx->fd, 0); + } + swoole_http_context_free(ctx TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_response, sendfile) +{ + char *filename; + zend_size_t filename_length; + long offset = 0; + long length = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_length, &offset, &length) == FAILURE) + { + return; + } + if (filename_length <= 0) + { + swoole_php_error(E_WARNING, "file name is empty."); + RETURN_FALSE; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + swoole_php_error(E_ERROR, "can't use sendfile when gzip compression is enabled."); + RETURN_FALSE; + } +#endif + + if (ctx->chunk) + { + swoole_php_error(E_ERROR, "can't use sendfile when Http-Chunk is enabled."); + RETURN_FALSE; + } + + struct stat file_stat; + if (stat(filename, &file_stat) < 0) + { + swoole_php_sys_error(E_WARNING, "stat(%s) failed.", filename); + RETURN_FALSE; + } + if (file_stat.st_size == 0) + { + swoole_php_sys_error(E_WARNING, "can't send empty file[%s].", filename); + RETURN_FALSE; + } + if (file_stat.st_size <= offset) + { + swoole_php_error(E_WARNING, "parameter $offset[%ld] exceeds the file size.", offset); + RETURN_FALSE; + } + if (length > file_stat.st_size - offset) + { + swoole_php_sys_error(E_WARNING, "parameter $length[%ld] exceeds the file size.", length); + RETURN_FALSE; + } + if (length == 0) + { + length = file_stat.st_size - offset; + } + + swString_clear(swoole_http_buffer); + http_build_header(ctx, getThis(), swoole_http_buffer, length TSRMLS_CC); + + int ret = swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); + if (ret < 0) + { + ctx->send_header = 0; + RETURN_FALSE; + } + + ret = swServer_tcp_sendfile(SwooleG.serv, ctx->fd, filename, filename_length, offset, length); + if (ret < 0) + { + ctx->send_header = 0; + RETURN_FALSE; + } + if (!ctx->keepalive) + { + swServer_tcp_close(SwooleG.serv, ctx->fd, 0); + } + swoole_http_context_free(ctx TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_response, cookie) +{ + char *name, *value = NULL, *path = NULL, *domain = NULL; + long expires = 0; + zend_bool secure = 0, httponly = 0; + zend_size_t name_len, value_len = 0, path_len = 0, domain_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name, &name_len, &value, &value_len, &expires, + &path, &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + zval *zcookie = ctx->response.zcookie; + zval *zresponse_object = ctx->response.zobject; + if (!zcookie) + { + swoole_http_server_array_init(cookie, response); + } + + char *cookie, *encoded_value = NULL; + int len = 0; + char *dt; + + if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) + { + swoole_php_error(E_WARNING, "Cookie names can't contain any of the following '=,; \\t\\r\\n\\013\\014'"); + RETURN_FALSE; + } + + len += name_len; + if (value) + { + int encoded_value_len; + encoded_value = sw_php_url_encode(value, value_len, &encoded_value_len); + len += encoded_value_len; + } + if (path) + { + len += path_len; + } + if (domain) + { + len += domain_len; + } + + cookie = emalloc(len + 100); + + if (value && value_len == 0) + { + dt = sw_php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T") - 1, 1, 0 TSRMLS_CC); + snprintf(cookie, len + 100, "%s=deleted; expires=%s", name, dt); + efree(dt); + } + else + { + snprintf(cookie, len + 100, "%s=%s", name, value ? encoded_value : ""); + if (expires > 0) + { + const char *p; + strlcat(cookie, "; expires=", len + 100); + dt = sw_php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T") - 1, expires, 0 TSRMLS_CC); + p = zend_memrchr(dt, '-', strlen(dt)); + if (!p || *(p + 5) != ' ') + { + efree(dt); + efree(cookie); + efree(encoded_value); + swoole_php_error(E_WARNING, "Expiry date can't be a year greater than 9999"); + RETURN_FALSE; + } + strlcat(cookie, dt, len + 100); + efree(dt); + } + } + if (encoded_value) + { + efree(encoded_value); + } + if (path && path_len > 0) + { + strlcat(cookie, "; path=", len + 100); + strlcat(cookie, path, len + 100); + } + if (domain && domain_len > 0) + { + strlcat(cookie, "; domain=", len + 100); + strlcat(cookie, domain, len + 100); + } + if (secure) + { + strlcat(cookie, "; secure", len + 100); + } + if (httponly) + { + strlcat(cookie, "; httponly", len + 100); + } + sw_add_next_index_stringl(zcookie, cookie, strlen(cookie), 0); +#if PHP_MAJOR_VERSION >= 7 + efree(cookie); +#endif +} + +static PHP_METHOD(swoole_http_response, rawcookie) +{ + char *name, *value = NULL, *path = NULL, *domain = NULL; + long expires = 0; + zend_bool secure = 0, httponly = 0; + zend_size_t name_len, value_len = 0, path_len = 0, domain_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name, &name_len, &value, &value_len, &expires, + &path, &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + zval *zcookie = ctx->response.zcookie; + zval *zresponse_object = ctx->response.zobject; + if (!zcookie) + { + swoole_http_server_array_init(cookie, response); + } + + char *cookie, *encoded_value = NULL; + int len = 0; + char *dt; + + if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) + { + swoole_php_error(E_WARNING, "Cookie names can't contain any of the following '=,; \\t\\r\\n\\013\\014'"); + RETURN_FALSE; + } + + len += name_len; + if (value) + { + encoded_value = estrdup(value); + len += value_len; + } + if (path) + { + len += path_len; + } + if (domain) + { + len += domain_len; + } + + cookie = emalloc(len + 100); + + if (value && value_len == 0) + { + dt = sw_php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T") - 1, 1, 0 TSRMLS_CC); + snprintf(cookie, len + 100, "%s=deleted; expires=%s", name, dt); + efree(dt); + } + else + { + snprintf(cookie, len + 100, "%s=%s", name, value ? encoded_value : ""); + if (expires > 0) + { + const char *p; + strlcat(cookie, "; expires=", len + 100); + dt = sw_php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T") - 1, expires, 0 TSRMLS_CC); + p = zend_memrchr(dt, '-', strlen(dt)); + if (!p || *(p + 5) != ' ') + { + efree(dt); + efree(cookie); + efree(encoded_value); + swoole_php_error(E_WARNING, "Expiry date can't be a year greater than 9999"); + RETURN_FALSE; + } + strlcat(cookie, dt, len + 100); + efree(dt); + } + } + if (encoded_value) + { + efree(encoded_value); + } + if (path && path_len > 0) + { + strlcat(cookie, "; path=", len + 100); + strlcat(cookie, path, len + 100); + } + if (domain && domain_len > 0) + { + strlcat(cookie, "; domain=", len + 100); + strlcat(cookie, domain, len + 100); + } + if (secure) + { + strlcat(cookie, "; secure", len + 100); + } + if (httponly) + { + strlcat(cookie, "; httponly", len + 100); + } + sw_add_next_index_stringl(zcookie, cookie, strlen(cookie), 0); +#if PHP_MAJOR_VERSION >= 7 + efree(cookie); +#endif +} + +static PHP_METHOD(swoole_http_response, status) +{ + long http_status; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &http_status) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + ctx->response.status = http_status; +} + +static PHP_METHOD(swoole_http_response, header) +{ + char *k, *v; + zend_size_t klen, vlen; + zend_bool ucwords = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &k, &klen, &v, &vlen, &ucwords) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + zval *zheader = ctx->response.zheader; + zval *zresponse_object = ctx->response.zobject; + if (!zheader) + { + swoole_http_server_array_init(header, response); + } + if (klen > SW_HTTP_HEADER_KEY_SIZE - 1) + { + swoole_php_error(E_WARNING, "header key is too long."); + RETURN_FALSE; + } + if (vlen > SW_HTTP_HEADER_VALUE_SIZE) + { + swoole_php_error(E_WARNING, "header value is too long."); + RETURN_FALSE; + } + + if (ucwords) + { + char key_buf[SW_HTTP_HEADER_KEY_SIZE]; + memcpy(key_buf, k, klen); + key_buf[klen] = '\0'; + if (ctx->http2) + { + swoole_strtolower(key_buf, klen); + } + else + { + http_header_key_format(key_buf, klen); + } + sw_add_assoc_stringl_ex(zheader, key_buf, klen + 1, v, vlen, 1); + } + else + { + sw_add_assoc_stringl_ex(zheader, k, klen + 1, v, vlen, 1); + } + +} + +#ifdef SW_USE_HTTP2 +static PHP_METHOD(swoole_http_response, trailer) +{ + char *k, *v; + zend_size_t klen, vlen; + zend_bool ucwords = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &k, &klen, &v, &vlen, &ucwords) == FAILURE) + { + return; + } + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + zval *ztrailer = ctx->response.ztrailer; + zval *zresponse_object = ctx->response.zobject; + if (!ztrailer) + { + swoole_http_server_array_init(trailer, response); + } + if (klen > SW_HTTP_HEADER_KEY_SIZE - 1) + { + swoole_php_error(E_WARNING, "trailer key is too long."); + RETURN_FALSE; + } + if (vlen > SW_HTTP_HEADER_VALUE_SIZE) + { + swoole_php_error(E_WARNING, "trailer value is too long."); + RETURN_FALSE; + } + + if (ucwords) + { + char key_buf[SW_HTTP_HEADER_KEY_SIZE]; + memcpy(key_buf, k, klen); + key_buf[klen] = '\0'; + if (ctx->http2) + { + swoole_strtolower(key_buf, klen); + } + else + { + http_header_key_format(key_buf, klen); + } + sw_add_assoc_stringl_ex(ztrailer, key_buf, klen + 1, v, vlen, 1); + } + else + { + sw_add_assoc_stringl_ex(ztrailer, k, klen + 1, v, vlen, 1); + } +} +#endif + +#ifdef SW_HAVE_ZLIB +static PHP_METHOD(swoole_http_response, gzip) +{ + long level = Z_DEFAULT_COMPRESSION; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &level) == FAILURE) + { + return; + } + + http_context *context = http_get_context(getThis(), 0 TSRMLS_CC); + if (!context) + { + RETURN_FALSE; + } + + if (context->send_header) + { + swoole_php_fatal_error(E_WARNING, "must be used before sending the http header."); + RETURN_FALSE; + } + + if (level > 9) + { + level = 9; + } + if (level < 0) + { + level = 0; + } + + context->gzip_enable = 1; + context->gzip_level = level; +} +#endif + +static PHP_METHOD(swoole_http_response, detach) +{ + http_context *context = http_get_context(getThis(), 0 TSRMLS_CC); + if (!context) + { + RETURN_FALSE; + } + context->detached = 1; + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http_response, create) +{ + zend_long fd; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(fd); + ZEND_PARSE_PARAMETERS_END(); + + http_context *ctx = emalloc(sizeof(http_context)); + if (!ctx) + { + swoole_error_log(SW_LOG_ERROR, SW_ERROR_MALLOC_FAIL, "emalloc(%ld) failed.", sizeof(http_context)); + RETURN_FALSE; + } + bzero(ctx, sizeof(http_context)); + ctx->fd = (int) fd; + + object_init_ex(return_value, swoole_http_response_class_entry_ptr); + swoole_set_object(return_value, ctx); + ctx->response.zobject = return_value; + sw_copy_to_stack(return_value, ctx->response._zobject); + + zend_update_property_long(swoole_http_response_class_entry_ptr, return_value, ZEND_STRL("fd"), ctx->fd TSRMLS_CC); +} + +static PHP_METHOD(swoole_http_response, redirect) +{ + zval *url; + zval *http_code = NULL; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ZVAL(url); + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(http_code); + ZEND_PARSE_PARAMETERS_END(); + + http_context *ctx = http_get_context(getThis(), 0 TSRMLS_CC); + if (!ctx) + { + RETURN_FALSE; + } + + //status + if (http_code) + { + convert_to_long(http_code); + ctx->response.status = Z_LVAL_P(http_code); + } + else + { + ctx->response.status = 302; + } + + //header + zval key; + ZVAL_STRINGL(&key, "Location", 8); + zend_call_method_with_2_params(getThis(), NULL, NULL, "header", return_value, &key, url); + zval_ptr_dtor(&key); + if (!ZVAL_IS_NULL(return_value)) + { + return; + } + + //end + zend_call_method_with_0_params(getThis(), NULL, NULL, "end", return_value); +} + +static PHP_METHOD(swoole_http_response, __destruct) +{ + http_context *context = swoole_get_object(getThis()); + if (context) + { + swConnection *conn = swWorker_get_connection(SwooleG.serv, context->fd); + if (!conn || conn->closed || conn->removed || context->detached) + { + swoole_http_context_free(context TSRMLS_CC); + } + else + { + context->response.status = 500; + + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_http_response_class_entry_ptr, NULL, "end", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + + context = swoole_get_object(getThis()); + if (context) + { + swoole_http_context_free(context TSRMLS_CC); + } + } + } +} diff --git a/vendor/swoole/swoole_http_v2_client.c b/vendor/swoole/swoole_http_v2_client.c new file mode 100755 index 0000000..78fdc20 --- /dev/null +++ b/vendor/swoole/swoole_http_v2_client.c @@ -0,0 +1,1288 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http.h" + +#ifdef SW_USE_HTTP2 +#include "swoole_http_v2_client.h" + +static zend_class_entry swoole_http2_client_ce; +static zend_class_entry *swoole_http2_client_class_entry_ptr; + +static zend_class_entry swoole_http2_response_ce; +zend_class_entry *swoole_http2_response_class_entry_ptr; + +swString *cookie_buffer = NULL; + +enum +{ + HTTP2_CLIENT_PROPERTY_INDEX = 3, +}; + +typedef struct +{ + char *uri; + uint32_t uri_len; + uint32_t stream_id; + uint8_t type; + zval *callback; + zval *data; +#if PHP_MAJOR_VERSION >= 7 + zval _callback; + zval _data; +#endif +} http2_client_request; + +static PHP_METHOD(swoole_http2_client, __construct); +static PHP_METHOD(swoole_http2_client, __destruct); +static PHP_METHOD(swoole_http2_client, onConnect); +static PHP_METHOD(swoole_http2_client, onError); +static PHP_METHOD(swoole_http2_client, onReceive); +static PHP_METHOD(swoole_http2_client, onClose); + +static PHP_METHOD(swoole_http2_client, setHeaders); +static PHP_METHOD(swoole_http2_client, setCookies); +static PHP_METHOD(swoole_http2_client, get); +static PHP_METHOD(swoole_http2_client, post); +static PHP_METHOD(swoole_http2_client, openStream); +static PHP_METHOD(swoole_http2_client, push); +static PHP_METHOD(swoole_http2_client, closeStream); + +static void http2_client_send_request(zval *zobject, http2_client_request *req TSRMLS_DC); +static void http2_client_send_stream_request(zval *zobject, http2_client_request *req TSRMLS_DC); +static void http2_client_send_all_requests(zval *zobject TSRMLS_DC); +static void http2_client_request_free(void *ptr); +static void http2_client_stream_free(void *ptr); + +static const zend_function_entry swoole_http2_client_methods[] = +{ + PHP_ME(swoole_http2_client, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_http2_client, __destruct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_http2_client, setHeaders, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, setCookies, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, get, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, post, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, onConnect, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, onError, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, onReceive, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, onClose, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, openStream, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, push, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client, closeStream, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_http2_client_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_http2_client_ce, "swoole_http2_client", "Swoole\\Http2\\Client", swoole_http2_client_methods); + swoole_http2_client_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_http2_client_ce, swoole_client_class_entry_ptr, "swoole_client" TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http2_client, "Swoole\\Http2\\Client"); + + zend_declare_property_null(swoole_http2_client_class_entry_ptr, SW_STRL("requestHeaders")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_client_class_entry_ptr, SW_STRL("cookies")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + SWOOLE_INIT_CLASS_ENTRY(swoole_http2_response_ce, "swoole_http2_response", "Swoole\\Http2\\Response", NULL); + swoole_http2_response_class_entry_ptr = zend_register_internal_class(&swoole_http2_response_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_http2_response, "Swoole\\Http2\\Response"); + + zend_declare_property_long(swoole_http2_response_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http2_response_class_entry_ptr, SW_STRL("statusCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_response_class_entry_ptr, SW_STRL("body")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_response_class_entry_ptr, SW_STRL("streamId")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + if (cookie_buffer == NULL) + { + cookie_buffer = swString_new(8192); + } +} + +static PHP_METHOD(swoole_http2_client, __construct) +{ + char *host; + zend_size_t host_len; + long port = 80; + zend_bool ssl = SW_FALSE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &host, &host_len, &port, &ssl) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "host is empty.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + + http2_client_property *hcc; + hcc = (http2_client_property*) emalloc(sizeof(http2_client_property)); + bzero(hcc, sizeof(http2_client_property)); + swoole_set_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX, hcc); + + hcc->requests = swLinkedList_new(0, http2_client_request_free); + hcc->stream_requests = swLinkedList_new(0, http2_client_request_free); + hcc->streams = swHashMap_new(8, http2_client_stream_free); + hcc->stream_id = 1; + + zval *ztype; + SW_MAKE_STD_ZVAL(ztype); + long type = SW_FLAG_ASYNC | SW_SOCK_TCP; + if (ssl) + { + type |= SW_SOCK_SSL; + hcc->ssl = 1; + } + ZVAL_LONG(ztype, type); + + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_1_params(&zobject, swoole_client_class_entry_ptr, NULL, "__construct", &retval, ztype); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&ztype); + + hcc->host = estrndup(host, host_len); + hcc->host_len = host_len; + hcc->port = port; +} + +static PHP_METHOD(swoole_http2_client, setHeaders) +{ + zval *headers; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &headers) == FAILURE) + { + return; + } + zend_update_property(swoole_http2_client_class_entry_ptr, getThis(), ZEND_STRL("requestHeaders"), headers TSRMLS_CC); +} + +static PHP_METHOD(swoole_http2_client, setCookies) +{ + zval *cookies; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &cookies) == FAILURE) + { + return; + } + zend_update_property(swoole_http2_client_class_entry_ptr, getThis(), ZEND_STRL("cookies"), cookies TSRMLS_CC); +} + +static int http2_client_build_header(zval *zobject, http2_client_request *req, char *buffer, int buffer_len TSRMLS_DC) +{ + char *date_str = NULL; + + int ret; + zval *zheader = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + int index = 0; + int find_host = 0; + + nghttp2_nv nv[1024]; + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + if (req->type == HTTP_GET) + { + http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); + } + else + { + http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("POST")); + } + http2_add_header(&nv[index++], ZEND_STRL(":path"), req->uri, req->uri_len); + if (hcc->ssl) + { + http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); + } + else + { + http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); + } + //Host + index++; + + if (zheader && !ZVAL_IS_NULL(zheader)) + { + HashTable *ht = Z_ARRVAL_P(zheader); + zval *value = NULL; + char *key = NULL; + uint32_t keylen = 0; + int type; + + SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) + { + if (!key) + { + break; + } + if (*key == ':') + { + continue; + } + if (strncasecmp("Host", key, keylen) == 0) + { + http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); + find_host = 1; + } + else + { + http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + } + } + SW_HASHTABLE_FOREACH_END(); + (void)type; + } + if (!find_host) + { + http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), hcc->host, hcc->host_len); + } + + zval *zcookie = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("cookies"), 1 TSRMLS_CC); + //http cookies + if (zcookie && !ZVAL_IS_NULL(zcookie)) + { + http2_add_cookie(nv, &index, zcookie TSRMLS_CC); + } + + ssize_t rv; + size_t buflen; + size_t i; + size_t sum = 0; + +#if 0 + for (i = 0; i < index; ++i) + { + swTraceLog(SW_TRACE_HTTP2, "Header[%d]: "SW_ECHO_CYAN_BLUE"=%s", i, nv[i].name, nv[i].value); + } +#endif + + nghttp2_hd_deflater *deflater; + ret = nghttp2_hd_deflate_new(&deflater, 4096); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_init failed with error: %s\n", nghttp2_strerror(ret)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + sum += nv[i].namelen + nv[i].valuelen; + } + + buflen = nghttp2_hd_deflate_bound(deflater, nv, index); + if (buflen > buffer_len) + { + swoole_php_error(E_WARNING, "header is too large."); + return SW_ERR; + } + rv = nghttp2_hd_deflate_hd(deflater, (uchar *) buffer, buflen, nv, index); + if (rv < 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_hd() failed with error: %s\n", nghttp2_strerror((int ) rv)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + efree(nv[i].name); // free lower header name copy + } + + if (date_str) + { + efree(date_str); + } + + nghttp2_hd_deflate_del(deflater); + + return rv; +} + +void http2_add_cookie(nghttp2_nv *nv, int *index, zval *cookies TSRMLS_DC) +{ + char *key; + uint32_t keylen; + int keytype; + zval *value = NULL; + char *encoded_value; + uint32_t offest = 0; + swString_clear(cookie_buffer); + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(cookies), key, keylen, keytype, value) + if (HASH_KEY_IS_STRING != keytype) + { + continue; + } + convert_to_string(value); + if (Z_STRLEN_P(value) == 0) + { + continue; + } + + swString_append_ptr(cookie_buffer, key, keylen); + swString_append_ptr(cookie_buffer, "=", 1); + + int encoded_value_len; + encoded_value = sw_php_url_encode(Z_STRVAL_P(value), Z_STRLEN_P(value), &encoded_value_len); + if (encoded_value) + { + swString_append_ptr(cookie_buffer, encoded_value, encoded_value_len); + efree(encoded_value); + http2_add_header(&nv[(*index)++], ZEND_STRL("cookie"), cookie_buffer->str + offest, keylen + 1 + encoded_value_len); + offest += keylen + 1 + encoded_value_len; + } + SW_HASHTABLE_FOREACH_END(); +} + +int http2_client_parse_header(http2_client_property *hcc, http2_client_stream *stream , int flags, char *in, size_t inlen) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + nghttp2_hd_inflater *inflater = hcc->inflater; + zval *zresponse = stream->response_object; + if (!inflater) + { + int ret = nghttp2_hd_inflate_new(&inflater); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_inflate_init() failed, Error: %s[%d].", nghttp2_strerror(ret), ret); + return SW_ERR; + } + hcc->inflater = inflater; + } + + if (flags & SW_HTTP2_FLAG_PRIORITY) + { + //int stream_deps = ntohl(*(int *) (in)); + //uint8_t weight = in[4]; + in += 5; + inlen -= 5; + } + + zval *zheader; + SW_MAKE_STD_ZVAL(zheader); + array_init(zheader); + + ssize_t rv; + for (;;) + { + nghttp2_nv nv; + int inflate_flags = 0; + size_t proclen; + + rv = nghttp2_hd_inflate_hd(inflater, &nv, &inflate_flags, (uchar *) in, inlen, 1); + if (rv < 0) + { + swoole_php_error(E_WARNING, "inflate failed, Error: %s[%zd].", nghttp2_strerror(rv), rv); + return -1; + } + + proclen = (size_t) rv; + + in += proclen; + inlen -= proclen; + + //swTraceLog(SW_TRACE_HTTP2, "Header: %s[%d]: %s[%d]", nv.name, nv.namelen, nv.value, nv.valuelen); + + if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) + { + if (nv.name[0] == ':') + { + if (strncasecmp((char *) nv.name + 1, "status", nv.namelen -1) == 0) + { + zend_update_property_long(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("statusCode"), atoi((char *) nv.value) TSRMLS_CC); + continue; + } + } +#ifdef SW_HAVE_ZLIB + else if (strncasecmp((char *) nv.name, "content-encoding", nv.namelen) == 0 && strncasecmp((char *) nv.value, "gzip", nv.valuelen) == 0) + { + http2_client_init_gzip_stream(stream); + if (Z_OK != inflateInit2(&stream->gzip_stream, MAX_WBITS + 16)) + { + swWarn("inflateInit2() failed."); + return SW_ERR; + } + } +#endif + sw_add_assoc_stringl_ex(zheader, (char *) nv.name, nv.namelen + 1, (char *) nv.value, nv.valuelen, 1); + } + + if (inflate_flags & NGHTTP2_HD_INFLATE_FINAL) + { + nghttp2_hd_inflate_end_headers(inflater); + break; + } + + if ((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && inlen == 0) + { + break; + } + } + + zend_update_property(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("header"), zheader TSRMLS_CC); + sw_zval_ptr_dtor(&zheader); + + rv = nghttp2_hd_inflate_change_table_size(inflater, 4096); + if (rv != 0) + { + return rv; + } + return SW_OK; +} + +/** + * Http2 + */ +static int http2_client_onFrame(zval *zobject, zval *zdata TSRMLS_DC) +{ + char *buf = Z_STRVAL_P(zdata); + int type = buf[3]; + int flags = buf[4]; + int stream_id = ntohl((*(int *) (buf + 5))) & 0x7fffffff; + uint32_t length = swHttp2_get_length(buf); + buf += SW_HTTP2_FRAME_HEADER_SIZE; + + char frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE]; + + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(zobject); + + uint16_t id; + uint32_t value; + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_YELLOW"]\tflags=%d, stream_id=%d, length=%d", swHttp2_get_type(type), flags, stream_id, length); + + if (type == SW_HTTP2_TYPE_SETTINGS) + { + if (flags & SW_HTTP2_FLAG_ACK) + { + return SW_OK; + } + + while(length > 0) + { + id = ntohs(*(uint16_t *) (buf)); + value = ntohl(*(uint32_t *) (buf + sizeof(uint16_t))); + switch (id) + { + case SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: + hcc->max_concurrent_streams = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_concurrent_streams=%d.", value); + break; + case SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE: + hcc->window_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: init_window_size=%d.", value); + break; + case SW_HTTP2_SETTINGS_MAX_FRAME_SIZE: + hcc->max_frame_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_frame_size=%d.", value); + break; + case SW_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: + hcc->max_header_list_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_header_list_size=%d.", value); + break; + default: + swWarn("unknown option[%d].", id); + break; + } + buf += sizeof(id) + sizeof(value); + length -= sizeof(id) + sizeof(value); + } + + swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_SETTINGS, 0, SW_HTTP2_FLAG_ACK, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", ACK, STREAM#%d]\t[length=%d]", swHttp2_get_type(SW_HTTP2_TYPE_SETTINGS), stream_id, length); + cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE, 0); + return SW_OK; + } + else if (type == SW_HTTP2_TYPE_WINDOW_UPDATE) + { + hcc->window_size = ntohl(*(int *) buf); + swTraceLog(SW_TRACE_HTTP2, "update: window_size=%d.", hcc->window_size); + return SW_OK; + } + else if (type == SW_HTTP2_TYPE_PING) + { + swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_PING, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE, SW_HTTP2_FLAG_ACK, stream_id); + memcpy(frame + SW_HTTP2_FRAME_HEADER_SIZE, buf + SW_HTTP2_FRAME_HEADER_SIZE, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", STREAM#%d]", swHttp2_get_type(SW_HTTP2_FRAME_PING_PAYLOAD_SIZE), stream_id); + cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE, 0); + return SW_OK; + } + else if (type == SW_HTTP2_TYPE_GOAWAY) + { + int last_stream_id = htonl(*(int *) (buf)); + buf += 4; + int error_code = htonl(*(int *) (buf)); + swWarn("["SW_ECHO_RED"] last_stream_id=%d, error_code=%d.", "GOAWAY", last_stream_id, error_code); + + zval* retval; + sw_zend_call_method_with_0_params(&zobject, swoole_client_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; + } + + http2_client_stream *stream = swHashMap_find_int(hcc->streams, stream_id); + // stream has closed + if (stream == NULL) + { + return SW_OK; + } + if (type == SW_HTTP2_TYPE_HEADERS) + { + http2_client_parse_header(hcc, stream, flags, buf, length); + } + else if (type == SW_HTTP2_TYPE_DATA) + { + if (!stream->buffer) + { + stream->buffer = swString_new(8192); + } +#ifdef SW_HAVE_ZLIB + if (stream->gzip) + { + if (http_response_uncompress(&stream->gzip_stream, stream->gzip_buffer, buf, length) == SW_ERR) + { + return -1; + } + swString_append_ptr(stream->buffer, stream->gzip_buffer->str, stream->gzip_buffer->length); + } + else +#endif + { + swString_append_ptr(stream->buffer, buf, length); + } + } + else + { + swWarn("unknown frame, type=%d, stream_id=%d, length=%d.", type, stream_id, length); + return SW_OK; + } + if ((type == SW_HTTP2_TYPE_DATA && stream->type == SW_HTTP2_STREAM_PIPELINE) + || (stream->type == SW_HTTP2_STREAM_NORMAL && (flags & SW_HTTP2_FLAG_END_STREAM))) + { + zval *retval = NULL; + zval *zcallback = stream->callback; + zval *zresponse = stream->response_object; + + if (stream->buffer) + { + zend_update_property_stringl(swoole_http2_response_class_entry_ptr, stream->response_object, ZEND_STRL("body"), stream->buffer->str, stream->buffer->length TSRMLS_CC); + } + + zval **args[1]; + args[0] = &zresponse; + + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_http2_client handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + if (stream->type == SW_HTTP2_STREAM_NORMAL) + { + swHashMap_del_int(hcc->streams, stream_id); + } + else + { + swString_clear(stream->buffer); + } + } + + return SW_OK; +} + +static void http2_client_request_free(void *ptr) +{ + http2_client_request *req = ptr; + if (req->callback) + { + sw_zval_ptr_dtor(&req->callback); + } + + if (req->data) + { + sw_zval_ptr_dtor(&req->data); + } + efree(req->uri); + efree(req); +} + +static void http2_client_stream_free(void *ptr) +{ + http2_client_stream *stream = ptr; + sw_zval_ptr_dtor(&stream->callback); + sw_zval_ptr_dtor(&stream->response_object); + if (stream->buffer) + { + swString_free(stream->buffer); + } +#ifdef SW_HAVE_ZLIB + if (stream->gzip) + { + inflateEnd(&stream->gzip_stream); + swString_free(stream->gzip_buffer); + } +#endif + efree(stream); +} + +static void http2_client_set_callback(zval *zobject, const char *callback_name, const char *method_name TSRMLS_DC) +{ + zval *retval = NULL; + zval *zcallback; + SW_MAKE_STD_ZVAL(zcallback); + array_init(zcallback); + + zval *zname; + SW_MAKE_STD_ZVAL(zname); + + zval *zmethod_name; + SW_MAKE_STD_ZVAL(zmethod_name); + + SW_ZVAL_STRING(zname, callback_name, 1); + SW_ZVAL_STRING(zmethod_name, method_name, 1); + +#if PHP_MAJOR_VERSION < 7 + sw_zval_add_ref(&zobject); +#endif + + add_next_index_zval(zcallback, zobject); + add_next_index_zval(zcallback, zmethod_name); + + sw_zend_call_method_with_2_params(&zobject, swoole_http2_client_class_entry_ptr, NULL, "on", &retval, zname, zcallback); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zname); + sw_zval_ptr_dtor(&zcallback); +} + +static void http2_client_send_all_requests(zval *zobject TSRMLS_DC) +{ + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + swLinkedList *requests = hcc->requests; + + swLinkedList_node *node = requests->head; + http2_client_request *request; + + while(node) + { + request = node->data; + http2_client_send_request(zobject, request TSRMLS_CC); + node = node->next; + } + swLinkedList_free(requests); + hcc->requests = NULL; + + requests = hcc->stream_requests; + + node = requests->head; + while(node) + { + request = node->data; + http2_client_send_stream_request(zobject, request TSRMLS_CC); + node = node->next; + } + swLinkedList_free(requests); + hcc->stream_requests = NULL; +} + +static void http2_client_send_stream_request(zval *zobject, http2_client_request *req TSRMLS_DC) +{ + swClient *cli = swoole_get_object(zobject); + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + char buffer[8192]; + + /** + * create stream + */ + if (req->stream_id == 0) + { + /** + * send header + */ + + int n = http2_client_build_header(zobject, req, buffer + SW_HTTP2_FRAME_HEADER_SIZE, sizeof(buffer) - SW_HTTP2_FRAME_HEADER_SIZE TSRMLS_CC); + if (n <= 0) + { + swWarn("http2_client_build_header() failed."); + return; + } + + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + + http2_client_stream *stream = emalloc(sizeof(http2_client_stream)); + memset(stream, 0, sizeof(http2_client_stream)); + + zval *response_object; + SW_MAKE_STD_ZVAL(response_object); + object_init_ex(response_object, swoole_http2_response_class_entry_ptr); + + stream->stream_id = hcc->stream_id; + stream->response_object = response_object; + stream->callback = req->callback; + stream->type = SW_HTTP2_STREAM_PIPELINE; + + sw_copy_to_stack(stream->callback, stream->_callback); + sw_zval_add_ref(&stream->callback); + sw_copy_to_stack(stream->response_object, stream->_response_object); + + zend_update_property_long(swoole_http2_response_class_entry_ptr, response_object, ZEND_STRL("streamId"), stream->stream_id TSRMLS_CC); + + swHashMap_add_int(hcc->streams, hcc->stream_id, stream); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_HEADERS), hcc->stream_id, n); + cli->send(cli, buffer, n + SW_HTTP2_FRAME_HEADER_SIZE, 0); + + hcc->stream_id += 2; + return; + } + else + { + int stream_id = req->stream_id; + zval *post_data = req->data; + /** + * send body + */ + if (post_data) + { + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + zend_size_t len; + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return; + } + memset(buffer, 0, SW_HTTP2_FRAME_HEADER_SIZE); + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, len, 0, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), stream_id, len); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, formstr, len, 0); + smart_str_free(&formstr_s); + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, Z_STRLEN_P(post_data), 0, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), stream_id, Z_STRLEN_P(post_data)); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, Z_STRVAL_P(post_data), Z_STRLEN_P(post_data), 0); + } + } + return; + } +} + +static void http2_client_send_request(zval *zobject, http2_client_request *req TSRMLS_DC) +{ + swClient *cli = swoole_get_object(zobject); + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + + zval *post_data = req->data; + if (post_data) + { + zval *zheader = sw_zend_read_property(swoole_http2_client_class_entry_ptr, zobject, ZEND_STRL("requestHeaders"), 1 TSRMLS_CC); + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + sw_add_assoc_stringl_ex(zheader, ZEND_STRS("content-type"), ZEND_STRL("application/x-www-form-urlencoded"), 1); + } + } + /** + * send header + */ + char buffer[8192]; + int n = http2_client_build_header(zobject, req, buffer + SW_HTTP2_FRAME_HEADER_SIZE, sizeof(buffer) - SW_HTTP2_FRAME_HEADER_SIZE TSRMLS_CC); + if (n <= 0) + { + swWarn("http2_client_build_header() failed."); + return; + } + if (post_data == NULL) + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_STREAM | SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + } + + http2_client_stream *stream = emalloc(sizeof(http2_client_stream)); + memset(stream, 0, sizeof(http2_client_stream)); + + zval *response_object; + SW_MAKE_STD_ZVAL(response_object); + object_init_ex(response_object, swoole_http2_response_class_entry_ptr); + + stream->stream_id = hcc->stream_id; + stream->response_object = response_object; + stream->callback = req->callback; + stream->type = SW_HTTP2_STREAM_NORMAL; + + sw_copy_to_stack(stream->callback, stream->_callback); + sw_zval_add_ref(&stream->callback); + sw_copy_to_stack(stream->response_object, stream->_response_object); + + zend_update_property_long(swoole_http2_response_class_entry_ptr, response_object, ZEND_STRL("streamId"), stream->stream_id TSRMLS_CC); + + swHashMap_add_int(hcc->streams, hcc->stream_id, stream); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_HEADERS), hcc->stream_id, n); + cli->send(cli, buffer, n + SW_HTTP2_FRAME_HEADER_SIZE, 0); + + /** + * send body + */ + if (post_data) + { + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + zend_size_t len; + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return; + } + memset(buffer, 0, SW_HTTP2_FRAME_HEADER_SIZE); + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, len, SW_HTTP2_FLAG_END_STREAM, hcc->stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), hcc->stream_id, len); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, formstr, len, 0); + smart_str_free(&formstr_s); + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, Z_STRLEN_P(req->data), SW_HTTP2_FLAG_END_STREAM, hcc->stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), hcc->stream_id, Z_STRLEN_P(req->data)); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, Z_STRVAL_P(post_data), Z_STRLEN_P(post_data), 0); + } + } + + hcc->stream_id += 2; + return; +} + +static void http2_client_connect(zval *zobject TSRMLS_DC) +{ + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_PROPERTY_INDEX); + zval *retval = NULL; + + zval *zhost; + SW_MAKE_STD_ZVAL(zhost); + SW_ZVAL_STRINGL(zhost, hcc->host, hcc->host_len, 1); + + zval *zport; + SW_MAKE_STD_ZVAL(zport); + ZVAL_LONG(zport, hcc->port); + + http2_client_set_callback(zobject, "Connect", "onConnect" TSRMLS_CC); + http2_client_set_callback(zobject, "Receive", "onReceive" TSRMLS_CC); + + if (!php_swoole_client_isset_callback(zobject, SW_CLIENT_CB_onClose TSRMLS_CC)) + { + http2_client_set_callback(zobject, "Close", "onClose" TSRMLS_CC); + } + if (!php_swoole_client_isset_callback(zobject, SW_CLIENT_CB_onError TSRMLS_CC)) + { + http2_client_set_callback(zobject, "Error", "onError" TSRMLS_CC); + } + + sw_zend_call_method_with_2_params(&zobject, swoole_http2_client_class_entry_ptr, NULL, "connect", &retval, zhost, zport); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zhost); + sw_zval_ptr_dtor(&zport); + swClient *cli = swoole_get_object(zobject); + cli->http2 = 1; +} + +static PHP_METHOD(swoole_http2_client, get) +{ + zval *uri; + zval *callback; + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(getThis()); + + if (!cli && hcc->connecting == 1) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &uri, &callback) == FAILURE) + { + return; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + if (Z_TYPE_P(uri) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "uri is not string."); + RETURN_FALSE; + } + + if (cli && cli->socket && cli->socket->active == 1) + { + http2_client_request _req; + _req.uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + _req.uri_len = Z_STRLEN_P(uri); + _req.type = HTTP_GET; + _req.callback = callback; + _req.data = NULL; + http2_client_send_request(getThis(), &_req TSRMLS_CC); + } + else + { + swLinkedList *requests = hcc->requests; + http2_client_request *req = emalloc(sizeof(http2_client_request)); + + req->uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + req->uri_len = Z_STRLEN_P(uri); + req->type = HTTP_GET; + req->callback = callback; + req->data = NULL; + sw_copy_to_stack(req->callback, req->_callback); + sw_zval_add_ref(&req->callback); + + swLinkedList_append(requests, req); + + if (!hcc->connecting) + { + http2_client_connect(getThis() TSRMLS_CC); + hcc->connecting = 1; + } + } + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http2_client, post) +{ + zval *uri; + zval *callback; + zval *data; + + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(getThis()); + + if (!cli && hcc->connecting == 1) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "zzz", &uri, &data, &callback) == FAILURE) + { + return; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + if (Z_TYPE_P(uri) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "uri is not string."); + RETURN_FALSE; + } + + if (cli && cli->socket && cli->socket->active == 1) + { + http2_client_request _req; + _req.uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + _req.uri_len = Z_STRLEN_P(uri); + _req.type = HTTP_POST; + _req.callback = callback; + _req.data = data; + http2_client_send_request(getThis(), &_req TSRMLS_CC); + } + else + { + swLinkedList *requests = hcc->requests; + http2_client_request *req = emalloc(sizeof(http2_client_request)); + + req->uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + req->uri_len = Z_STRLEN_P(uri); + req->type = HTTP_POST; + req->data = data; + req->callback = callback; + sw_copy_to_stack(req->data, req->_data); + sw_zval_add_ref(&req->data); + sw_copy_to_stack(req->callback, req->_callback); + sw_zval_add_ref(&req->callback); + + swLinkedList_append(requests, req); + + if (!hcc->connecting) + { + http2_client_connect(getThis() TSRMLS_CC); + hcc->connecting = 1; + } + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http2_client, openStream) +{ + zval *uri; + zval *callback; + + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(getThis()); + + if (!cli && hcc->connecting == 1) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "zz", &uri, &callback) == FAILURE) + { + return; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "Function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + if (Z_TYPE_P(uri) != IS_STRING) + { + swoole_php_fatal_error(E_WARNING, "uri is not string."); + RETURN_FALSE; + } + + if (cli && cli->socket && cli->socket->active == 1) + { + http2_client_request _req; + _req.uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + _req.uri_len = Z_STRLEN_P(uri); + _req.type = HTTP_POST; + _req.callback = callback; + _req.stream_id = 0; + http2_client_send_stream_request(getThis(), &_req TSRMLS_CC); + } + else + { + swLinkedList *requests = hcc->stream_requests; + + http2_client_request *req = emalloc(sizeof(http2_client_request)); + + req->uri = estrndup(Z_STRVAL_P(uri), Z_STRLEN_P(uri)); + req->uri_len = Z_STRLEN_P(uri); + req->type = HTTP_POST; + req->callback = callback; + req->data = NULL; + req->stream_id = 0; + sw_copy_to_stack(req->callback, req->_callback); + sw_zval_add_ref(&req->callback); + + swLinkedList_append(requests, req); + + if (!hcc->connecting) + { + http2_client_connect(getThis() TSRMLS_CC); + hcc->connecting = 1; + } + } + RETURN_LONG(hcc->stream_id); +} + +static PHP_METHOD(swoole_http2_client, push) +{ + long stream_id; + zval *data; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "lz", &stream_id, &data) == FAILURE) + { + return; + } + + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(getThis()); + + if (!cli && hcc->connecting == 1) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + if (cli && cli->socket && cli->socket->active == 1) + { + http2_client_request _req; + _req.uri = NULL; + _req.uri_len = 0; + _req.data = data; + _req.stream_id = stream_id; + _req.callback = NULL; + http2_client_send_stream_request(getThis(), &_req TSRMLS_CC); + } + else + { + swLinkedList *requests = hcc->stream_requests; + + http2_client_request *req = emalloc(sizeof(http2_client_request)); + req->uri = NULL; + req->uri_len = 0; + req->data = data; + req->stream_id = stream_id; + req->callback = NULL; + sw_copy_to_stack(req->data, req->_data); + sw_zval_add_ref(&req->data); + + swLinkedList_append(requests, req); + + if (!hcc->connecting) + { + http2_client_connect(getThis() TSRMLS_CC); + hcc->connecting = 1; + } + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http2_client, closeStream) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + swClient *cli = swoole_get_object(getThis()); + + if (!cli && hcc->connecting == 1) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + char buffer[8192]; + long stream_id; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "l", &stream_id) == FAILURE) + { + return; + } + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_SETTINGS, 0, SW_HTTP2_FLAG_END_STREAM,hcc->stream_id); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + swHashMap_del_int(hcc->streams, stream_id); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_http2_client, onConnect) +{ + swClient *cli = swoole_get_object(getThis()); + cli->send(cli, ZEND_STRL("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"), 0); + cli->open_length_check = 1; + cli->protocol.get_package_length = swHttp2_get_frame_length; + cli->protocol.package_length_size = SW_HTTP2_FRAME_HEADER_SIZE; + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + hcc->ready = 1; + hcc->stream_id = 1; + hcc->send_setting = 1; + if (hcc->send_setting) + { + http2_client_send_setting(cli); + } + http2_client_send_all_requests(getThis() TSRMLS_CC); +} + +static PHP_METHOD(swoole_http2_client, onError) +{ + +} + +static PHP_METHOD(swoole_http2_client, onClose) +{ + +} + +static PHP_METHOD(swoole_http2_client, onReceive) +{ + zval *zobject; + zval *zdata; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zobject, &zdata) == FAILURE) + { + return; + } + http2_client_onFrame(zobject, zdata TSRMLS_CC); +} + +static PHP_METHOD(swoole_http2_client, __destruct) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX); + if (hcc) + { + if (hcc->requests) + { + swLinkedList_free(hcc->requests); + } + if (hcc->stream_requests) + { + swLinkedList_free(hcc->stream_requests); + } + if (hcc->inflater) + { + nghttp2_hd_inflate_del(hcc->inflater); + hcc->inflater = NULL; + } + if (hcc->host) + { + efree(hcc->host); + hcc->host = NULL; + } + + swHashMap_free(hcc->streams); + efree(hcc); + swoole_set_property(getThis(), HTTP2_CLIENT_PROPERTY_INDEX, NULL); + } + + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_client_class_entry_ptr, NULL, "__destruct", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +#endif diff --git a/vendor/swoole/swoole_http_v2_client.h b/vendor/swoole/swoole_http_v2_client.h new file mode 100755 index 0000000..0da1b7e --- /dev/null +++ b/vendor/swoole/swoole_http_v2_client.h @@ -0,0 +1,161 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#ifndef SWOOLE_HTTP_V2_CLIENT_H_ +#define SWOOLE_HTTP_V2_CLIENT_H_ + +#include "php_swoole.h" +#include "swoole_http.h" + +#include "http.h" +#include "http2.h" + +#define HTTP2_CLIENT_HOST_HEADER_INDEX 3 + +#ifdef SW_HAVE_ZLIB +#include <zlib.h> +extern voidpf php_zlib_alloc(voidpf opaque, uInt items, uInt size); +extern void php_zlib_free(voidpf opaque, voidpf address); +extern int http_response_uncompress(z_stream *stream, swString *buffer, char *body, int length); +#endif + +typedef struct +{ + uint32_t stream_id; + uint8_t gzip; + uint8_t type; + zval *response_object; + zval *callback; + swString *buffer; +#ifdef SW_HAVE_ZLIB + z_stream gzip_stream; + swString *gzip_buffer; +#endif +#if PHP_MAJOR_VERSION >= 7 + zval _callback; + zval _response_object; +#endif +} http2_client_stream; + +typedef struct +{ + uint8_t ssl; + uint8_t connecting; + uint8_t ready; + uint8_t send_setting; + +#ifdef SW_COROUTINE + uint8_t iowait; + int cid; + swClient *client; +#endif + + uint32_t stream_id; + + uint32_t window_size; + uint32_t max_concurrent_streams; + uint32_t max_frame_size; + uint32_t max_header_list_size; + + char *host; + zend_size_t host_len; + int port; + + nghttp2_hd_inflater *inflater; + zval *object; + double timeout; + + swLinkedList *requests; + swLinkedList *stream_requests; + swHashMap *streams; + +} http2_client_property; + +#ifdef SW_HAVE_ZLIB +/** + * init zlib stream + */ +static sw_inline void http2_client_init_gzip_stream(http2_client_stream *stream) +{ + stream->gzip = 1; + memset(&stream->gzip_stream, 0, sizeof(stream->gzip_stream)); + stream->gzip_buffer = swString_new(8192); + stream->gzip_stream.zalloc = php_zlib_alloc; + stream->gzip_stream.zfree = php_zlib_free; +} +#endif + +int http2_client_parse_header(http2_client_property *hcc, http2_client_stream *stream , int flags, char *in, size_t inlen); + +static sw_inline void http2_client_send_setting(swClient *cli) +{ + uint16_t id = 0; + uint32_t value = 0; + + char frame[SW_HTTP2_FRAME_HEADER_SIZE + 18]; + memset(frame, 0, sizeof(frame)); + swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_SETTINGS, 18, 0, 0); + + char *p = frame + SW_HTTP2_FRAME_HEADER_SIZE; + /** + * MAX_CONCURRENT_STREAMS + */ + id = htons(SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); + memcpy(p, &id, sizeof(id)); + p += 2; + value = htonl(SW_HTTP2_MAX_CONCURRENT_STREAMS); + memcpy(p, &value, sizeof(value)); + p += 4; + /** + * MAX_FRAME_SIZE + */ + id = htons(SW_HTTP2_SETTINGS_MAX_FRAME_SIZE); + memcpy(p, &id, sizeof(id)); + p += 2; + value = htonl(SW_HTTP2_MAX_FRAME_SIZE); + memcpy(p, &value, sizeof(value)); + p += 4; + /** + * INIT_WINDOW_SIZE + */ + id = htons(SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE); + memcpy(p, &id, sizeof(id)); + p += 2; + value = htonl(65535); + memcpy(p, &value, sizeof(value)); + p += 4; + + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN"]\t[length=%d]", swHttp2_get_type(SW_HTTP2_TYPE_SETTINGS), 18); + cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE + 18, 0); +} + +static sw_inline void http2_add_header(nghttp2_nv *headers, char *k, int kl, char *v, int vl) +{ + k = zend_str_tolower_dup(k, kl); // auto to lower + headers->name = (uchar*) k; + headers->namelen = kl; + headers->value = (uchar*) v; + headers->valuelen = vl; + + swTrace("k=%s, len=%d, v=%s, len=%d", k, kl, v, vl); +} + +void http2_add_cookie(nghttp2_nv *nv, int *index, zval *cookies TSRMLS_DC); + +extern swString *cookie_buffer; +extern zend_class_entry *swoole_client_class_entry_ptr; + +#endif diff --git a/vendor/swoole/swoole_http_v2_client_coro.c b/vendor/swoole/swoole_http_v2_client_coro.c new file mode 100755 index 0000000..6527d04 --- /dev/null +++ b/vendor/swoole/swoole_http_v2_client_coro.c @@ -0,0 +1,953 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http.h" + +#ifdef SW_USE_HTTP2 +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#include "swoole_http_v2_client.h" + +extern zend_class_entry *swoole_http2_response_class_entry_ptr; + +static zend_class_entry swoole_http2_client_coro_ce; +static zend_class_entry *swoole_http2_client_coro_class_entry_ptr; + +static zend_class_entry swoole_http2_request_coro_ce; +static zend_class_entry *swoole_http2_request_coro_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http2_client_coro_construct, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, ssl) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http2_client_coro_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http2_client_coro_send, 0, 0, 1) + ZEND_ARG_INFO(0, request) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_http2_client_coro_write, 0, 0, 2) + ZEND_ARG_INFO(0, stream_id) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, end_stream) +ZEND_END_ARG_INFO() + +enum +{ + HTTP2_CLIENT_CORO_CONTEXT = 0, + HTTP2_CLIENT_CORO_PROPERTY = 1, +}; + +static PHP_METHOD(swoole_http2_client_coro, __construct); +static PHP_METHOD(swoole_http2_client_coro, __destruct); +static PHP_METHOD(swoole_http2_client_coro, set); +static PHP_METHOD(swoole_http2_client_coro, send); +static PHP_METHOD(swoole_http2_client_coro, recv); +static PHP_METHOD(swoole_http2_client_coro, connect); +static PHP_METHOD(swoole_http2_client_coro, close); +static PHP_METHOD(swoole_http2_client_coro, write); + +static int http2_client_send_request(zval *zobject, zval *request TSRMLS_DC); +static void http2_client_stream_free(void *ptr); +static void http2_client_onConnect(swClient *cli); +static void http2_client_onClose(swClient *cli); +static void http2_client_onError(swClient *cli); +static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length); + +static const zend_function_entry swoole_http2_client_methods[] = +{ + PHP_ME(swoole_http2_client_coro, __construct, arginfo_swoole_http2_client_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_http2_client_coro, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_http2_client_coro, set, arginfo_swoole_http2_client_coro_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client_coro, connect, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client_coro, send, arginfo_swoole_http2_client_coro_send, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client_coro, recv, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client_coro, write, arginfo_swoole_http2_client_coro_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_http2_client_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_http2_client_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_http2_client_coro_ce, "Swoole\\Coroutine\\Http2\\Client", swoole_http2_client_methods); + swoole_http2_client_coro_class_entry_ptr = zend_register_internal_class(&swoole_http2_client_coro_ce); + + INIT_CLASS_ENTRY(swoole_http2_request_coro_ce, "Swoole\\Coroutine\\Http2\\Request", NULL); + swoole_http2_request_coro_class_entry_ptr = zend_register_internal_class(&swoole_http2_request_coro_ce); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Http2\\Client", swoole_http2_client_coro_class_entry_ptr); + sw_zend_register_class_alias("Co\\Http2\\Request", swoole_http2_request_coro_class_entry_ptr); + } + + zend_declare_property_long(swoole_http2_client_coro_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http2_client_coro_class_entry_ptr, SW_STRL("sock")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_http2_client_coro_class_entry_ptr, SW_STRL("reuse")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http2_client_coro_class_entry_ptr, SW_STRL("reuseCount")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http2_client_coro_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_client_coro_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_http2_client_coro_class_entry_ptr, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_client_coro_class_entry_ptr, SW_STRL("host")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_http2_client_coro_class_entry_ptr, SW_STRL("port")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_http2_request_coro_class_entry_ptr, SW_STRL("method")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_request_coro_class_entry_ptr, SW_STRL("headers")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_request_coro_class_entry_ptr, SW_STRL("data")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_http2_request_coro_class_entry_ptr, SW_STRL("pipeline")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_http2_request_coro_class_entry_ptr, SW_STRL("files")-1, ZEND_ACC_PUBLIC TSRMLS_CC); +} + +static PHP_METHOD(swoole_http2_client_coro, __construct) +{ + char *host; + zend_size_t host_len; + long port = 80; + zend_bool ssl = SW_FALSE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lb", &host, &host_len, &port, &ssl) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "host is empty.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + + http2_client_property *hcc; + hcc = (http2_client_property*) emalloc(sizeof(http2_client_property)); + bzero(hcc, sizeof(http2_client_property)); + swoole_set_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY, hcc); + + php_context *context = emalloc(sizeof(php_context)); + swoole_set_property(getThis(), HTTP2_CLIENT_CORO_CONTEXT, context); + context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + context->coro_params = getThis(); +#else + context->coro_params = *getThis(); +#endif + + hcc->streams = swHashMap_new(8, http2_client_stream_free); + hcc->stream_id = 1; + + long type = SW_FLAG_ASYNC | SW_SOCK_TCP; + if (ssl) + { +#ifdef SW_USE_OPENSSL + type |= SW_SOCK_SSL; + hcc->ssl = 1; +#else + swoole_php_fatal_error(E_ERROR, "require openssl library."); +#endif + } + + zend_update_property_long(swoole_http2_client_coro_class_entry_ptr, getThis(), ZEND_STRL("type"), type TSRMLS_CC); + + hcc->host = estrndup(host, host_len); + hcc->host_len = host_len; + hcc->port = port; +} + +static PHP_METHOD(swoole_http2_client_coro, set) +{ + zval *zset; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + zval *zsetting = php_swoole_read_init_property(swoole_http2_client_coro_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + RETURN_TRUE; +} + +static int http2_client_build_header(zval *zobject, zval *req, char *buffer, int buffer_len TSRMLS_DC) +{ + char *date_str = NULL; + int ret; + int index = 0; + int find_host = 0; + + zval *cookies = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("cookies"), 1 TSRMLS_CC); + zval *method = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("method"), 1 TSRMLS_CC); + zval *path = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("path"), 1 TSRMLS_CC); + zval *headers = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("headers"), 1 TSRMLS_CC); + + nghttp2_nv nv[1024]; + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); + if (ZVAL_IS_NULL(method) || Z_TYPE_P(method) != IS_STRING || Z_STRLEN_P(method) == 0) + { + http2_add_header(&nv[index++], ZEND_STRL(":method"), ZEND_STRL("GET")); + } + else + { + http2_add_header(&nv[index++], ZEND_STRL(":method"), Z_STRVAL_P(method), Z_STRLEN_P(method)); + } + if (ZVAL_IS_NULL(path) || Z_TYPE_P(path) != IS_STRING || Z_STRLEN_P(path) == 0) + { + http2_add_header(&nv[index++], ZEND_STRL(":path"), "/", 1); + } + else + { + http2_add_header(&nv[index++], ZEND_STRL(":path"), Z_STRVAL_P(path), Z_STRLEN_P(path)); + } + if (hcc->ssl) + { + http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("https")); + } + else + { + http2_add_header(&nv[index++], ZEND_STRL(":scheme"), ZEND_STRL("http")); + } + //Host + index++; + + if (headers && !ZVAL_IS_NULL(headers)) + { + HashTable *ht = Z_ARRVAL_P(headers); + zval *value = NULL; + char *key = NULL; + uint32_t keylen = 0; + int type; + + SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) + { + if (!key) + { + break; + } + if (*key == ':') + { + continue; + } + if (strncasecmp("Host", key, keylen) == 0) + { + http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), Z_STRVAL_P(value), Z_STRLEN_P(value)); + find_host = 1; + } + else + { + http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + } + } + SW_HASHTABLE_FOREACH_END(); + (void)type; + } + if (!find_host) + { + http2_add_header(&nv[HTTP2_CLIENT_HOST_HEADER_INDEX], ZEND_STRL(":authority"), hcc->host, hcc->host_len); + } + + //http cookies + if (cookies && !ZVAL_IS_NULL(cookies)) + { + http2_add_cookie(nv, &index, cookies TSRMLS_CC); + } + + ssize_t rv; + size_t buflen; + size_t i; + size_t sum = 0; + +#if 0 + for (i = 0; i < index; ++i) + { + swTraceLog(SW_TRACE_HTTP2, "Header[%d]: "SW_ECHO_CYAN_BLUE"=%s", i, nv[i].name, nv[i].value); + } +#endif + + nghttp2_hd_deflater *deflater; + ret = nghttp2_hd_deflate_new(&deflater, 4096); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_init failed with error: %s\n", nghttp2_strerror(ret)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + sum += nv[i].namelen + nv[i].valuelen; + } + + buflen = nghttp2_hd_deflate_bound(deflater, nv, index); + if (buflen > buffer_len) + { + swoole_php_error(E_WARNING, "header is too large."); + return SW_ERR; + } + rv = nghttp2_hd_deflate_hd(deflater, (uchar *) buffer, buflen, nv, index); + if (rv < 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_hd() failed with error: %s\n", nghttp2_strerror((int ) rv)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + efree(nv[i].name); // free lower header name copy + } + + if (date_str) + { + efree(date_str); + } + + nghttp2_hd_deflate_del(deflater); + + return rv; +} + +static void http2_client_onReceive(swClient *cli, char *buf, uint32_t _length) +{ + int type = buf[3]; + int flags = buf[4]; + int error_code = 0; + int stream_id = ntohl((*(int *) (buf + 5))) & 0x7fffffff; + uint32_t length = swHttp2_get_length(buf); + buf += SW_HTTP2_FRAME_HEADER_SIZE; + + zval *zobject = cli->object; + + char frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE]; + + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); + + uint16_t id; + uint32_t value; + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_YELLOW"]\tflags=%d, stream_id=%d, length=%d", swHttp2_get_type(type), flags, stream_id, length); + + if (type == SW_HTTP2_TYPE_SETTINGS) + { + if (flags & SW_HTTP2_FLAG_ACK) + { + return; + } + + while(length > 0) + { + id = ntohs(*(uint16_t *) (buf)); + value = ntohl(*(uint32_t *) (buf + sizeof(uint16_t))); + switch (id) + { + case SW_HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS: + hcc->max_concurrent_streams = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_concurrent_streams=%d.", value); + break; + case SW_HTTP2_SETTINGS_INIT_WINDOW_SIZE: + hcc->window_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: init_window_size=%d.", value); + break; + case SW_HTTP2_SETTINGS_MAX_FRAME_SIZE: + hcc->max_frame_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_frame_size=%d.", value); + break; + case SW_HTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: + hcc->max_header_list_size = value; + swTraceLog(SW_TRACE_HTTP2, "setting: max_header_list_size=%d.", value); + break; + default: + swWarn("unknown option[%d].", id); + break; + } + buf += sizeof(id) + sizeof(value); + length -= sizeof(id) + sizeof(value); + } + + swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_SETTINGS, 0, SW_HTTP2_FLAG_ACK, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", ACK, STREAM#%d]\t[length=%d]", swHttp2_get_type(SW_HTTP2_TYPE_SETTINGS), stream_id, length); + cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE, 0); + return; + } + else if (type == SW_HTTP2_TYPE_WINDOW_UPDATE) + { + hcc->window_size = ntohl(*(int *) buf); + swTraceLog(SW_TRACE_HTTP2, "update: window_size=%d.", hcc->window_size); + return; + } + else if (type == SW_HTTP2_TYPE_PING) + { + swHttp2_set_frame_header(frame, SW_HTTP2_TYPE_PING, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE, SW_HTTP2_FLAG_ACK, stream_id); + memcpy(frame + SW_HTTP2_FRAME_HEADER_SIZE, buf + SW_HTTP2_FRAME_HEADER_SIZE, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", STREAM#%d]", swHttp2_get_type(SW_HTTP2_FRAME_PING_PAYLOAD_SIZE), stream_id); + cli->send(cli, frame, SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE, 0); + return; + } + else if (type == SW_HTTP2_TYPE_GOAWAY) + { + int last_stream_id = htonl(*(int *) (buf)); + buf += 4; + error_code = htonl(*(int *) (buf)); + swWarn("["SW_ECHO_RED"] last_stream_id=%d, error_code=%d.", "GOAWAY", last_stream_id, error_code); + + zval* retval; + sw_zend_call_method_with_0_params(&zobject, swoole_http2_client_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + if (hcc->iowait == 0) + { + return; + } + } + else if (type == SW_HTTP2_TYPE_RST_STREAM) + { + error_code = htonl(*(int *) (buf)); + swWarn("["SW_ECHO_RED"] stream_id=%d, error_code=%d.", "RST_STREAM", stream_id, error_code); + + if (hcc->iowait == 0) + { + return; + } + } + + http2_client_stream *stream = swHashMap_find_int(hcc->streams, stream_id); + // stream has closed + if (stream == NULL) + { + return; + } + if (type == SW_HTTP2_TYPE_HEADERS) + { + http2_client_parse_header(hcc, stream, flags, buf, length); + } + else if (type == SW_HTTP2_TYPE_DATA) + { + if (!stream->buffer) + { + stream->buffer = swString_new(8192); + } +#ifdef SW_HAVE_ZLIB + if (stream->gzip) + { + if (http_response_uncompress(&stream->gzip_stream, stream->gzip_buffer, buf, length) == SW_ERR) + { + return; + } + swString_append_ptr(stream->buffer, stream->gzip_buffer->str, stream->gzip_buffer->length); + } + else +#endif + { + swString_append_ptr(stream->buffer, buf, length); + } + } + + if ((type == SW_HTTP2_TYPE_DATA && stream->type == SW_HTTP2_STREAM_PIPELINE) + || (stream->type == SW_HTTP2_STREAM_NORMAL && (flags & SW_HTTP2_FLAG_END_STREAM)) + || type == SW_HTTP2_TYPE_RST_STREAM || type == SW_HTTP2_TYPE_GOAWAY) + { + zval *zresponse = stream->response_object; + zval *retval = NULL; + + if (type == SW_HTTP2_TYPE_RST_STREAM) + { + zend_update_property_long(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("statusCode"), -3 TSRMLS_CC); + zend_update_property_long(swoole_http2_response_class_entry_ptr, zresponse, ZEND_STRL("errCode"), error_code TSRMLS_CC); + } + + if (stream->buffer) + { + zend_update_property_stringl(swoole_http2_response_class_entry_ptr, stream->response_object, ZEND_STRL("body"), stream->buffer->str, stream->buffer->length TSRMLS_CC); + } + + hcc->iowait = 0; + if (stream->type == SW_HTTP2_STREAM_NORMAL) + { + swHashMap_del_int(hcc->streams, stream_id); + } + else if (stream->buffer) + { + swString_clear(stream->buffer); + } + + php_context *context = swoole_get_property(zobject, HTTP2_CLIENT_CORO_CONTEXT); + int ret = coro_resume(context, zresponse, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zresponse); + } +} + +static void http2_client_stream_free(void *ptr) +{ + http2_client_stream *stream = ptr; + if (stream->buffer) + { + swString_free(stream->buffer); + } +#ifdef SW_HAVE_ZLIB + if (stream->gzip) + { + inflateEnd(&stream->gzip_stream); + swString_free(stream->gzip_buffer); + } +#endif + efree(stream); +} + +static int http2_client_send_request(zval *zobject, zval *req TSRMLS_DC) +{ + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); + swClient *cli = hcc->client; + + zval *headers = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("headers"), 1 TSRMLS_CC); + zval *post_data = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("data"), 1 TSRMLS_CC); + zval *pipeline = sw_zend_read_property(swoole_http2_request_coro_class_entry_ptr, req, ZEND_STRL("pipeline"), 1 TSRMLS_CC); + + if (!ZVAL_IS_NULL(post_data)) + { + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + sw_add_assoc_stringl_ex(headers, ZEND_STRS("content-type"), ZEND_STRL("application/x-www-form-urlencoded"), 1); + } + } + /** + * send header + */ + char buffer[8192]; + int n = http2_client_build_header(zobject, req, buffer + SW_HTTP2_FRAME_HEADER_SIZE, sizeof(buffer) - SW_HTTP2_FRAME_HEADER_SIZE TSRMLS_CC); + if (n <= 0) + { + swWarn("http2_client_build_header() failed."); + return -1; + } + + http2_client_stream *stream = emalloc(sizeof(http2_client_stream)); + memset(stream, 0, sizeof(http2_client_stream)); + + zval *response_object; + SW_MAKE_STD_ZVAL(response_object); + object_init_ex(response_object, swoole_http2_response_class_entry_ptr); + + stream->stream_id = hcc->stream_id; + stream->response_object = response_object; + stream->type = Z_BVAL_P(pipeline) ? SW_HTTP2_STREAM_PIPELINE : SW_HTTP2_STREAM_NORMAL; + + if (ZVAL_IS_NULL(post_data)) + { + //pipeline + if (stream->type == SW_HTTP2_STREAM_PIPELINE) + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_STREAM | SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + } + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_HEADERS, n, SW_HTTP2_FLAG_END_HEADERS, hcc->stream_id); + } + + sw_copy_to_stack(stream->response_object, stream->_response_object); + + zend_update_property_long(swoole_http2_response_class_entry_ptr, response_object, ZEND_STRL("streamId"), stream->stream_id TSRMLS_CC); + + swHashMap_add_int(hcc->streams, hcc->stream_id, stream); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_HEADERS), hcc->stream_id, n); + cli->send(cli, buffer, n + SW_HTTP2_FRAME_HEADER_SIZE, 0); + + /** + * send body + */ + if (!ZVAL_IS_NULL(post_data)) + { + int flag = stream->type == SW_HTTP2_STREAM_PIPELINE ? 0 : SW_HTTP2_FLAG_END_STREAM; + if (Z_TYPE_P(post_data) == IS_ARRAY) + { + zend_size_t len; + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(post_data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return -1; + } + memset(buffer, 0, SW_HTTP2_FRAME_HEADER_SIZE); + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, len, flag, hcc->stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), hcc->stream_id, len); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, formstr, len, 0); + smart_str_free(&formstr_s); + } + else + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, Z_STRLEN_P(post_data), flag, hcc->stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), hcc->stream_id, Z_STRLEN_P(post_data)); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, Z_STRVAL_P(post_data), Z_STRLEN_P(post_data), 0); + } + } + + hcc->stream_id += 2; + return stream->stream_id; +} + +static int http2_client_send_data(http2_client_property *hcc, uint32_t stream_id, zval *data, zend_bool end TSRMLS_DC) +{ + swClient *cli = hcc->client; + + char buffer[8192]; + http2_client_stream *stream = swHashMap_find_int(hcc->streams, stream_id); + if (stream == NULL || stream->type != SW_HTTP2_STREAM_PIPELINE) + { + return -1; + } + + int flag = end ? SW_HTTP2_FLAG_END_STREAM : 0; + + if (Z_TYPE_P(data) == IS_ARRAY) + { + zend_size_t len; + smart_str formstr_s = { 0 }; + char *formstr = sw_http_build_query(data, &len, &formstr_s TSRMLS_CC); + if (formstr == NULL) + { + swoole_php_error(E_WARNING, "http_build_query failed."); + return -1; + } + memset(buffer, 0, SW_HTTP2_FRAME_HEADER_SIZE); + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, len, flag, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), stream_id, len); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, formstr, len, 0); + smart_str_free(&formstr_s); + } + else if (Z_TYPE_P(data) == IS_STRING) + { + swHttp2_set_frame_header(buffer, SW_HTTP2_TYPE_DATA, Z_STRLEN_P(data), flag, stream_id); + swTraceLog(SW_TRACE_HTTP2, "["SW_ECHO_GREEN", END, STREAM#%d] length=%d", swHttp2_get_type(SW_HTTP2_TYPE_DATA), stream_id, Z_STRLEN_P(data)); + cli->send(cli, buffer, SW_HTTP2_FRAME_HEADER_SIZE, 0); + cli->send(cli, Z_STRVAL_P(data), Z_STRLEN_P(data), 0); + } + else + { + swoole_php_error(E_WARNING, "unknown data type[%d].", Z_TYPE_P(data) ); + return -1; + } + return SW_OK; +} + +static PHP_METHOD(swoole_http2_client_coro, send) +{ + zval *request; + + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY); + swClient *cli = hcc->client; + + if (!cli || !cli->socket || cli->socket->closed) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &request) == FAILURE) + { + return; + } + if (SW_Z_TYPE_P(request) != IS_OBJECT) + { + error: swoole_php_fatal_error(E_ERROR, "object is not instanceof swoole_process."); + RETURN_FALSE; + } + if (!instanceof_function(Z_OBJCE_P(request), swoole_http2_request_coro_class_entry_ptr TSRMLS_CC)) + { + goto error; + } + + int stream_id = http2_client_send_request(getThis(), request TSRMLS_CC); + if (stream_id < 0) + { + RETURN_FALSE; + } + else + { + RETURN_LONG(stream_id); + } +} + +static PHP_METHOD(swoole_http2_client_coro, recv) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY); + swClient *cli = hcc->client; + + if (!cli || !cli->socket || cli->socket->closed) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + php_context *context = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_CONTEXT); + hcc->cid = sw_get_current_cid(); + coro_save(context); + hcc->iowait = 1; + coro_yield(); +} + +static void http2_client_onConnect(swClient *cli) +{ + zval *zobject = cli->object; + http2_client_property *hcc = swoole_get_property(zobject, HTTP2_CLIENT_CORO_PROPERTY); + + zend_update_property_bool(swoole_http2_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 1 TSRMLS_CC); + + cli->send(cli, ZEND_STRL("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"), 0); + cli->open_length_check = 1; + cli->protocol.get_package_length = swHttp2_get_frame_length; + cli->protocol.package_length_size = SW_HTTP2_FRAME_HEADER_SIZE; + + hcc->ready = 1; + hcc->stream_id = 1; + hcc->send_setting = 1; + if (hcc->send_setting) + { + http2_client_send_setting(cli); + } + zval *result; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 1); + + zval *retval = NULL; + + php_context *context = swoole_get_property(zobject, HTTP2_CLIENT_CORO_CONTEXT); + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void http2_client_onClose(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zobject = cli->object; + zend_update_property_bool(swoole_http2_client_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + + if (cli->released) + { + return; + } + + php_swoole_client_free(zobject, cli TSRMLS_CC); + http2_client_property *hcc = swoole_get_property(zobject,HTTP2_CLIENT_CORO_PROPERTY); + if (!hcc->iowait) + { + return; + } + + zval *result; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 0); + + zval *retval = NULL; + php_context *context = swoole_get_property(zobject, HTTP2_CLIENT_CORO_CONTEXT); + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + hcc->cid = 0; +} + +static void http2_client_onError(swClient *cli) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *zdata; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zdata); + //return false + ZVAL_BOOL(zdata, 0); + + zval *zobject = cli->object; + php_context *context = swoole_get_property(zobject, HTTP2_CLIENT_CORO_CONTEXT); + + if (!cli->released) + { + php_swoole_client_free(zobject, cli TSRMLS_CC); + } + + coro_resume(context, zdata, &retval); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); +} + +static PHP_METHOD(swoole_http2_client_coro, __destruct) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY); + if (hcc) + { + if (hcc->inflater) + { + nghttp2_hd_inflate_del(hcc->inflater); + hcc->inflater = NULL; + } + if (hcc->host) + { + efree(hcc->host); + hcc->host = NULL; + } + + swHashMap_free(hcc->streams); + efree(hcc); + swoole_set_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY, NULL); + } + + php_context *context = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_CONTEXT); + efree(context); + swoole_set_property(getThis(), HTTP2_CLIENT_CORO_CONTEXT, NULL); + + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + return; + } + + zval *zobject = getThis(); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&zobject, swoole_http2_client_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static PHP_METHOD(swoole_http2_client_coro, close) +{ + swClient *cli = swoole_get_object(getThis()); + if (!cli) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_http_client."); + RETURN_FALSE; + } + if (!cli->socket) + { + swoole_php_error(E_WARNING, "not connected to the server"); + RETURN_FALSE; + } + if (cli->socket->closed) + { + php_swoole_client_free(getThis(), cli TSRMLS_CC); + RETURN_FALSE; + } + + int ret = SW_OK; + cli->released = 1; + ret = cli->close(cli); + php_swoole_client_free(getThis(), cli TSRMLS_CC); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_http2_client_coro, connect) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY); + + php_swoole_check_reactor(); + swClient *cli = php_swoole_client_new(getThis(), hcc->host, hcc->host_len, hcc->port); + if (cli == NULL) + { + RETURN_FALSE; + } + hcc->client = cli; + + zval *ztmp; + HashTable *vht; + zval *zset = sw_zend_read_property(swoole_http2_client_coro_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zset && !ZVAL_IS_NULL(zset)) + { + vht = Z_ARRVAL_P(zset); + /** + * timeout + */ + if (php_swoole_array_get_value(vht, "timeout", ztmp)) + { + convert_to_double(ztmp); + hcc->timeout = (double) Z_DVAL_P(ztmp); + } + //client settings + php_swoole_client_check_setting(hcc->client, zset TSRMLS_CC); + } + + swoole_set_object(getThis(), cli); + + cli->onConnect = http2_client_onConnect; + cli->onClose = http2_client_onClose; + cli->onError = http2_client_onError; + cli->onReceive = http2_client_onReceive; + cli->http2 = 1; + + cli->open_eof_check = 0; + cli->open_length_check = 0; + cli->reactor_fdtype = PHP_SWOOLE_FD_STREAM_CLIENT; + + if (cli->connect(cli, hcc->host, hcc->port, hcc->timeout, 0) < 0) + { + RETURN_FALSE; + } + + php_context *context = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_CONTEXT); + cli->object = &context->coro_params; + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_http2_client_coro, write) +{ + http2_client_property *hcc = swoole_get_property(getThis(), HTTP2_CLIENT_CORO_PROPERTY); + swClient *cli = hcc->client; + + if (!cli || !cli->socket || cli->socket->closed) + { + swoole_php_error(E_WARNING, "The connection is closed."); + RETURN_FALSE; + } + + long stream_id; + zval *data; + zend_bool end = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|b", &stream_id, &data, &end) == FAILURE) + { + return; + } + SW_CHECK_RETURN(http2_client_send_data(hcc, stream_id, data, end TSRMLS_CC)); +} + +#endif +#endif diff --git a/vendor/swoole/swoole_http_v2_server.c b/vendor/swoole/swoole_http_v2_server.c new file mode 100755 index 0000000..6002d02 --- /dev/null +++ b/vendor/swoole/swoole_http_v2_server.c @@ -0,0 +1,731 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http.h" + +#ifdef SW_USE_HTTP2 +#include "http2.h" +#include <main/php_variables.h> + +static sw_inline void http2_add_header(nghttp2_nv *headers, char *k, int kl, char *v, int vl) +{ + headers->name = (uchar*) k; + headers->namelen = kl; + headers->value = (uchar*) v; + headers->valuelen = vl; +} + +static int http_build_trailer(http_context *ctx, uchar *buffer TSRMLS_DC) +{ + int ret; + nghttp2_nv nv[128]; + int index = 0; + + zval *trailer = ctx->response.ztrailer; + if (trailer) + { + HashTable *ht = Z_ARRVAL_P(trailer); + zval *value = NULL; + char *key = NULL; + uint32_t keylen = 0; + int type; + SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) + { + if (!key) + { + break; + } + http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + (void) type; + } + SW_HASHTABLE_FOREACH_END(); + } + + ssize_t rv; + size_t buflen; + size_t i; + size_t sum = 0; + + nghttp2_hd_deflater *deflater; + ret = nghttp2_hd_deflate_new(&deflater, 4096); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_init failed with error: %s\n", nghttp2_strerror(ret)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + sum += nv[i].namelen + nv[i].valuelen; + } + + buflen = nghttp2_hd_deflate_bound(deflater, nv, index); + rv = nghttp2_hd_deflate_hd(deflater, (uchar *) buffer, buflen, nv, index); + if (rv < 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_hd() failed with error: %s\n", nghttp2_strerror((int ) rv)); + return SW_ERR; + } + + nghttp2_hd_deflate_del(deflater); + + return rv; +} + +static sw_inline void http2_onRequest(http_context *ctx, int server_fd TSRMLS_DC) +{ + zval *retval; + zval **args[2]; + + zval *zrequest_object = ctx->request.zobject; + zval *zresponse_object = ctx->response.zobject; + + SW_SEPARATE_ZVAL(zrequest_object); + SW_SEPARATE_ZVAL(zresponse_object); + + args[0] = &zrequest_object; + args[1] = &zresponse_object; + + zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, server_fd, SW_SERVER_CB_onRequest); + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "onRequest handler error"); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zrequest_object); + sw_zval_ptr_dtor(&zresponse_object); +} + +static int http2_build_header(http_context *ctx, uchar *buffer, int body_length TSRMLS_DC) +{ + assert(ctx->send_header == 0); + + swServer *serv = SwooleG.serv; + + char buf[SW_HTTP_HEADER_MAX_SIZE]; + char *date_str = NULL; + char intbuf[2][16]; + + int ret; + + /** + * http header + */ + zval *zheader = ctx->response.zheader; + int index = 0; + + nghttp2_nv nv[128]; + + /** + * http status code + */ + if (ctx->response.status == 0) + { + ctx->response.status = 200; + } + + ret = swoole_itoa(intbuf[0], ctx->response.status); + http2_add_header(&nv[index++], ZEND_STRL(":status"), intbuf[0], ret); + + if (zheader) + { + int flag = 0x0; + + HashTable *ht = Z_ARRVAL_P(zheader); + zval *value = NULL; + char *key = NULL; + uint32_t keylen = 0; + int type; + + SW_HASHTABLE_FOREACH_START2(ht, key, keylen, type, value) + { + if (!key) + { + break; + } + if (strncmp(key, "server", keylen) == 0) + { + flag |= HTTP_RESPONSE_SERVER; + } + else if (strncmp(key, "content-length", keylen) == 0) + { + flag |= HTTP_RESPONSE_CONTENT_LENGTH; + } + else if (strncmp(key, "date", keylen) == 0) + { + flag |= HTTP_RESPONSE_DATE; + } + else if (strncmp(key, "content-type", keylen) == 0) + { + flag |= HTTP_RESPONSE_CONTENT_TYPE; + } + http2_add_header(&nv[index++], key, keylen, Z_STRVAL_P(value), Z_STRLEN_P(value)); + } + SW_HASHTABLE_FOREACH_END(); + (void)type; + + if (!(flag & HTTP_RESPONSE_SERVER)) + { + http2_add_header(&nv[index++], ZEND_STRL("server"), ZEND_STRL(SW_HTTP_SERVER_SOFTWARE)); + } + if (!(flag & HTTP_RESPONSE_CONTENT_LENGTH) && body_length >= 0) + { +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + body_length = swoole_zlib_buffer->length; + } +#endif + ret = swoole_itoa(intbuf[1], body_length); + http2_add_header(&nv[index++], ZEND_STRL("content-length"), intbuf[1], ret); + } + if (!(flag & HTTP_RESPONSE_DATE)) + { + date_str = sw_php_format_date(ZEND_STRL(SW_HTTP_DATE_FORMAT), serv->gs->now, 0 TSRMLS_CC); + http2_add_header(&nv[index++], ZEND_STRL("date"), date_str, strlen(date_str)); + } + if (!(flag & HTTP_RESPONSE_CONTENT_TYPE)) + { + http2_add_header(&nv[index++], ZEND_STRL("content-type"), ZEND_STRL("text/html")); + } + } + else + { + http2_add_header(&nv[index++], ZEND_STRL("server"), ZEND_STRL(SW_HTTP_SERVER_SOFTWARE)); + http2_add_header(&nv[index++], ZEND_STRL("content-type"), ZEND_STRL("text/html")); + + date_str = sw_php_format_date(ZEND_STRL(SW_HTTP_DATE_FORMAT), serv->gs->now, 0 TSRMLS_CC); + http2_add_header(&nv[index++], ZEND_STRL("date"), date_str, strlen(date_str)); + +#ifdef SW_HAVE_ZLIB + if (ctx->gzip_enable) + { + body_length = swoole_zlib_buffer->length; + } +#endif + ret = swoole_itoa(buf, body_length); + http2_add_header(&nv[index++], ZEND_STRL("content-length"), buf, ret); + } + //http cookies + if (ctx->response.zcookie) + { + zval *value; + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(ctx->response.zcookie), value) + { + if (Z_TYPE_P(value) != IS_STRING) + { + continue; + } + http2_add_header(&nv[index++], ZEND_STRL("set-cookie"), Z_STRVAL_P(value), Z_STRLEN_P(value)); + } + SW_HASHTABLE_FOREACH_END(); + } + //http compress + if (ctx->gzip_enable) + { +#ifdef SW_HTTP_COMPRESS_GZIP + http2_add_header(&nv[index++], ZEND_STRL("content-encoding"), ZEND_STRL("gzip")); +#else + http2_add_header(&nv[index++], ZEND_STRL("content-encoding"), ZEND_STRL("deflate")); +#endif + } + ctx->send_header = 1; + + ssize_t rv; + size_t buflen; + size_t i; + size_t sum = 0; + + nghttp2_hd_deflater *deflater; + ret = nghttp2_hd_deflate_new(&deflater, 4096); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_init failed with error: %s\n", nghttp2_strerror(ret)); + return SW_ERR; + } + + for (i = 0; i < index; ++i) + { + sum += nv[i].namelen + nv[i].valuelen; + } + + buflen = nghttp2_hd_deflate_bound(deflater, nv, index); + rv = nghttp2_hd_deflate_hd(deflater, (uchar *) buffer, buflen, nv, index); + if (rv < 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_deflate_hd() failed with error: %s\n", nghttp2_strerror((int ) rv)); + return SW_ERR; + } + + if (date_str) + { + efree(date_str); + } + + nghttp2_hd_deflate_del(deflater); + + return rv; +} + +int swoole_http2_do_response(http_context *ctx, swString *body) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + swoole_http_client *client = ctx->client; + char header_buffer[8192]; + int ret; + + ret = http2_build_header(ctx, (uchar *) header_buffer, body->length TSRMLS_CC); + swString_clear(swoole_http_buffer); + + /** + +---------------+ + |Pad Length? (8)| + +-+-------------+-----------------------------------------------+ + |E| Stream Dependency? (31) | + +-+-------------+-----------------------------------------------+ + | Weight? (8) | + +-+-------------+-----------------------------------------------+ + | Header Block Fragment (*) ... + +---------------------------------------------------------------+ + | Padding (*) ... + +---------------------------------------------------------------+ + */ + char frame_header[9]; + zval *trailer = ctx->response.ztrailer; + + if (trailer == NULL && body->length == 0) + { + swHttp2_set_frame_header(frame_header, SW_HTTP2_TYPE_HEADERS, ret, + SW_HTTP2_FLAG_END_HEADERS | SW_HTTP2_FLAG_END_STREAM, ctx->stream_id); + } + else + { + swHttp2_set_frame_header(frame_header, SW_HTTP2_TYPE_HEADERS, ret, SW_HTTP2_FLAG_END_HEADERS, ctx->stream_id); + } + + swString_append_ptr(swoole_http_buffer, frame_header, 9); + swString_append_ptr(swoole_http_buffer, header_buffer, ret); + + int flag = SW_HTTP2_FLAG_END_STREAM; + if (trailer) + { + flag = SW_HTTP2_FLAG_NONE; + } + + ret = swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); + if (ret < 0) + { + ctx->send_header = 0; + return SW_ERR; + } + + ctx->send_header = 1; + if (trailer == NULL && body->length == 0) + { + goto _end; + } + + char *p = body->str; + size_t l = body->length; + size_t send_n; + + while (l > 0) + { + int _send_flag; + swString_clear(swoole_http_buffer); + if (l > SW_HTTP2_MAX_FRAME_SIZE) + { + send_n = SW_HTTP2_MAX_FRAME_SIZE; + _send_flag = 0; + } + else + { + send_n = l; + _send_flag = flag; + } + swHttp2_set_frame_header(frame_header, SW_HTTP2_TYPE_DATA, send_n, _send_flag, ctx->stream_id); + swString_append_ptr(swoole_http_buffer, frame_header, 9); + swString_append_ptr(swoole_http_buffer, p, send_n); + + if (swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length) < 0) + { + return SW_ERR; + } + else + { + l -= send_n; + p += send_n; + } + } + + if (trailer) + { + swString_clear(swoole_http_buffer); + memset(header_buffer, 0, sizeof(header_buffer)); + ret = http_build_trailer(ctx, (uchar *) header_buffer TSRMLS_CC); + swHttp2_set_frame_header(frame_header, SW_HTTP2_TYPE_HEADERS, ret, + SW_HTTP2_FLAG_END_HEADERS | SW_HTTP2_FLAG_END_STREAM, ctx->stream_id); + swString_append_ptr(swoole_http_buffer, frame_header, 9); + swString_append_ptr(swoole_http_buffer, header_buffer, ret); + + if (swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length) < 0) + { + return SW_ERR; + } + } + + _end: if (body->length > 0) + { + client->window_size -= body->length; // TODO:flow control? + } + if (client->streams) + { + swHashMap_del_int(client->streams, ctx->stream_id); + } + swoole_http_context_free(ctx TSRMLS_CC); + return SW_OK; +} + +static int http2_parse_header(swoole_http_client *client, http_context *ctx, int flags, char *in, size_t inlen) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + nghttp2_hd_inflater *inflater = client->inflater; + + if (!inflater) + { + int ret = nghttp2_hd_inflate_new(&inflater); + if (ret != 0) + { + swoole_php_error(E_WARNING, "nghttp2_hd_inflate_init() failed, Error: %s[%d].", nghttp2_strerror(ret), ret); + return SW_ERR; + } + client->inflater = inflater; + } + + if (flags & SW_HTTP2_FLAG_PRIORITY) + { + //int stream_deps = ntohl(*(int *) (in)); + //uint8_t weight = in[4]; + in += 5; + inlen -= 5; + } + + zval *zheader = ctx->request.zheader; + zval *zserver = ctx->request.zserver; + + ssize_t rv; + for (;;) + { + nghttp2_nv nv; + int inflate_flags = 0; + size_t proclen; + + rv = nghttp2_hd_inflate_hd(inflater, &nv, &inflate_flags, (uchar *) in, inlen, 1); + if (rv < 0) + { + swoole_php_error(E_WARNING, "inflate failed, Error: %s[%zd].", nghttp2_strerror(rv), rv); + return -1; + } + + proclen = (size_t) rv; + + in += proclen; + inlen -= proclen; + + swTraceLog(SW_TRACE_HTTP2, "Header: %s[%d]: %s[%d]", nv.name, nv.namelen, nv.value, nv.valuelen); + + if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) + { + if (nv.name[0] == ':') + { + if (strncasecmp((char *) nv.name + 1, "method", nv.namelen -1) == 0) + { + sw_add_assoc_stringl_ex(zserver, ZEND_STRS("request_method"), (char *) nv.value, nv.valuelen, 1); + } + else if (strncasecmp((char *) nv.name + 1, "path", nv.namelen -1) == 0) + { + char pathbuf[SW_HTTP_HEADER_MAX_SIZE]; + char *v_str = strchr((char *) nv.value, '?'); + if (v_str) + { + v_str++; + int k_len = v_str - (char *) nv.value - 1; + int v_len = nv.valuelen - k_len - 1; + memcpy(pathbuf, nv.value, k_len); + pathbuf[k_len] = 0; + sw_add_assoc_stringl_ex(zserver, ZEND_STRS("query_string"), v_str, v_len, 1); + sw_add_assoc_stringl_ex(zserver, ZEND_STRS("request_uri"), pathbuf, k_len, 1); + + zval *zget; + zval *zrequest_object = ctx->request.zobject; + swoole_http_server_array_init(get, request); + + //no need free, will free by treat_data + char *query = estrndup(v_str, v_len); + //parse url params + sapi_module.treat_data(PARSE_STRING, query, zget TSRMLS_CC); + } + else + { + sw_add_assoc_stringl_ex(zserver, ZEND_STRS("request_uri"), (char *) nv.value, nv.valuelen, 1); + } + } + else if (strncasecmp((char *) nv.name + 1, "authority", nv.namelen -1) == 0) + { + sw_add_assoc_stringl_ex(zheader, ZEND_STRS("host"), (char * ) nv.value, nv.valuelen, 1); + } + } + else + { + if (strncasecmp((char *) nv.name, "content-type", nv.namelen) == 0) + { + if (http_strncasecmp("application/x-www-form-urlencoded", (char *) nv.value, nv.valuelen)) + { + ctx->request.post_form_urlencoded = 1; + } + else if (http_strncasecmp("multipart/form-data", (char *) nv.value, nv.valuelen)) + { + int boundary_len = nv.valuelen - strlen("multipart/form-data; boundary="); + if (boundary_len <= 0) + { + swWarn("invalid multipart/form-data body.", ctx->fd); + return 0; + } + swoole_http_parse_form_data(ctx, (char*) nv.value + nv.valuelen - boundary_len, boundary_len TSRMLS_CC); + ctx->parser.data = ctx; + } + } + else if (strncasecmp((char *) nv.name, "cookie", nv.namelen) == 0) + { + zval *zcookie = ctx->request.zcookie; + zval *zrequest_object = ctx->request.zobject; + if (!zcookie) + { + swoole_http_server_array_init(cookie, request); + } + + char keybuf[SW_HTTP_COOKIE_KEYLEN]; + char *v_str = strchr((char *) nv.value, '=') + 1; + int k_len = v_str - (char *) nv.value - 1; + int v_len = nv.valuelen - k_len - 1; + memcpy(keybuf, nv.value, k_len); + keybuf[k_len] = 0; + sw_add_assoc_stringl_ex(zcookie, keybuf, k_len + 1, v_str, v_len, 1); + continue; + } + sw_add_assoc_stringl_ex(zheader, (char *) nv.name, nv.namelen + 1, (char *) nv.value, nv.valuelen, 1); + } + } + + if (inflate_flags & NGHTTP2_HD_INFLATE_FINAL) + { + nghttp2_hd_inflate_end_headers(inflater); + break; + } + + if ((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 && inlen == 0) + { + break; + } + } + + rv = nghttp2_hd_inflate_change_table_size(inflater, 4096); + if (rv != 0) + { + return rv; + } + return SW_OK; +} + +/** + * Http2 + */ +int swoole_http2_onFrame(swoole_http_client *client, swEventData *req) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + if (!client->init) + { + client->window_size = SW_HTTP2_DEFAULT_WINDOW; + client->remote_window_size = SW_HTTP2_DEFAULT_WINDOW; + client->init = 1; + } + + int fd = req->info.fd; + + http_context *ctx; + swServer *serv = SwooleG.serv; + + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + php_swoole_get_recv_data(zdata, req, NULL, 0); + + char *buf = Z_STRVAL_P(zdata); + + int type = buf[3]; + int flags = buf[4]; + int stream_id = ntohl((*(int *) (buf + 5))) & 0x7fffffff; + uint32_t length = swHttp2_get_length(buf); + + swTraceLog(SW_TRACE_HTTP2, "[%s]\tflags=%d, stream_id=%d, length=%d", swHttp2_get_type(type), flags, stream_id, length); + + if (type == SW_HTTP2_TYPE_HEADERS) + { + ctx = swoole_http_context_new(client TSRMLS_CC); + if (!ctx) + { + sw_zval_ptr_dtor(&zdata); + swoole_error_log(SW_LOG_WARNING, SW_ERROR_HTTP2_STREAM_NO_HEADER, "http2 error stream."); + return SW_ERR; + } + + ctx->http2 = 1; + ctx->stream_id = stream_id; + + http2_parse_header(client, ctx, flags, buf + SW_HTTP2_FRAME_HEADER_SIZE, length); + + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (!conn) + { + sw_zval_ptr_dtor(&zdata); + swWarn("connection[%d] is closed.", fd); + return SW_ERR; + } + + zval *zserver = ctx->request.zserver; + sw_add_assoc_long_ex(zserver, ZEND_STRS("request_time"), serv->gs->now); + + // Add REQUEST_TIME_FLOAT + double now_float = swoole_microtime(); + sw_add_assoc_double_ex(zserver, ZEND_STRS("request_time_float"), now_float); + + add_assoc_long(zserver, "server_port", swConnection_get_port(&SwooleG.serv->connection_list[conn->from_fd])); + add_assoc_long(zserver, "remote_port", swConnection_get_port(conn)); + sw_add_assoc_string(zserver, "remote_addr", swConnection_get_ip(conn), 1); + sw_add_assoc_string(zserver, "server_protocol", "HTTP/2", 1); + sw_add_assoc_string(zserver, "server_software", SW_HTTP_SERVER_SOFTWARE, 1); + + if (flags & SW_HTTP2_FLAG_END_STREAM) + { + http2_onRequest(ctx, req->info.from_fd TSRMLS_CC); + } + else + { + if (!client->streams) + { + client->streams = swHashMap_new(SW_HTTP2_MAX_CONCURRENT_STREAMS, NULL); + } + swHashMap_add_int(client->streams, stream_id, ctx); + } + } + else if (type == SW_HTTP2_TYPE_DATA) + { + ctx = swHashMap_find_int(client->streams, stream_id); + if (!ctx) + { + sw_zval_ptr_dtor(&zdata); + swoole_error_log(SW_LOG_WARNING, SW_ERROR_HTTP2_STREAM_NO_HEADER, "http2 error stream."); + return SW_ERR; + } + + swString *buffer = ctx->request.post_buffer; + if (!buffer) + { + buffer = swString_new(SW_HTTP2_DATA_BUFFSER_SIZE); + ctx->request.post_buffer = buffer; + } + swString_append_ptr(buffer, buf + SW_HTTP2_FRAME_HEADER_SIZE, length); + + if (flags & SW_HTTP2_FLAG_END_STREAM) + { + if (SwooleG.serv->http_parse_post && ctx->request.post_form_urlencoded) + { + zval *zpost; + zval *zrequest_object = ctx->request.zobject; + swoole_http_server_array_init(post, request); + char *post_content = estrndup(buffer->str, buffer->length); + sapi_module.treat_data(PARSE_STRING, post_content, zpost TSRMLS_CC); + } + else if (ctx->mt_parser != NULL) + { + multipart_parser *multipart_parser = ctx->mt_parser; + size_t n = multipart_parser_execute(multipart_parser, buffer->str, buffer->length); + if (n != length) + { + swoole_php_fatal_error(E_WARNING, "parse multipart body failed."); + } + } + http2_onRequest(ctx, req->info.from_fd TSRMLS_CC); + } + + client->remote_window_size -= length; + if (length > 0 && client->remote_window_size < SW_HTTP2_MAX_WINDOW / 4) + { + char window_update_frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_WINDOW_UPDATE_SIZE]; + uint32_t increment_size = SW_HTTP2_MAX_WINDOW - client->remote_window_size; + window_update_frame[0 + SW_HTTP2_FRAME_HEADER_SIZE] = increment_size >> 24; + window_update_frame[1 + SW_HTTP2_FRAME_HEADER_SIZE] = increment_size >> 16; + window_update_frame[2 + SW_HTTP2_FRAME_HEADER_SIZE] = increment_size >> 8; + window_update_frame[3 + SW_HTTP2_FRAME_HEADER_SIZE] = increment_size; + swHttp2_set_frame_header(window_update_frame, SW_HTTP2_TYPE_WINDOW_UPDATE, SW_HTTP2_WINDOW_UPDATE_SIZE, 0, 0); + swServer_tcp_send(SwooleG.serv, fd, window_update_frame, SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_WINDOW_UPDATE_SIZE); + client->remote_window_size = SW_HTTP2_MAX_WINDOW; + } + } + else if (type == SW_HTTP2_TYPE_PING) + { + char ping_frame[SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE]; + swHttp2_set_frame_header(ping_frame, SW_HTTP2_TYPE_PING, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE, SW_HTTP2_FLAG_ACK, stream_id); + memcpy(ping_frame + SW_HTTP2_FRAME_HEADER_SIZE, buf + SW_HTTP2_FRAME_HEADER_SIZE, SW_HTTP2_FRAME_PING_PAYLOAD_SIZE); + swServer_tcp_send(SwooleG.serv, fd, ping_frame, SW_HTTP2_FRAME_HEADER_SIZE + SW_HTTP2_FRAME_PING_PAYLOAD_SIZE); + } + else if (type == SW_HTTP2_TYPE_WINDOW_UPDATE) + { + client->window_size += swHttp2_get_increment_size(buf); + } + sw_zval_ptr_dtor(&zdata); + return SW_OK; +} + +void swoole_http2_free(swoole_http_client *client) +{ + if (client->inflater) + { + nghttp2_hd_inflate_del(client->inflater); + client->inflater = NULL; + } + + client->init = 0; + client->remote_window_size = SW_HTTP2_DEFAULT_WINDOW; + client->window_size = SW_HTTP2_DEFAULT_WINDOW; +} +#endif diff --git a/vendor/swoole/swoole_lock.c b/vendor/swoole/swoole_lock.c new file mode 100755 index 0000000..0663f7a --- /dev/null +++ b/vendor/swoole/swoole_lock.c @@ -0,0 +1,224 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +static PHP_METHOD(swoole_lock, __construct); +static PHP_METHOD(swoole_lock, __destruct); +static PHP_METHOD(swoole_lock, lock); +static PHP_METHOD(swoole_lock, lockwait); +static PHP_METHOD(swoole_lock, trylock); +static PHP_METHOD(swoole_lock, lock_read); +static PHP_METHOD(swoole_lock, trylock_read); +static PHP_METHOD(swoole_lock, unlock); +static PHP_METHOD(swoole_lock, destroy); + +static zend_class_entry swoole_lock_ce; +static zend_class_entry *swoole_lock_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_lock_construct, 0, 0, 0) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_lock_lockwait, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_lock_methods[] = +{ + PHP_ME(swoole_lock, __construct, arginfo_swoole_lock_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_lock, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_lock, lock, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, lockwait, arginfo_swoole_lock_lockwait, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, trylock, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, lock_read, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, trylock_read, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, unlock, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_lock, destroy, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_lock_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_lock_ce, "swoole_lock", "Swoole\\Lock", swoole_lock_methods); + swoole_lock_class_entry_ptr = zend_register_internal_class(&swoole_lock_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_lock, "Swoole\\Lock"); + + zend_declare_class_constant_long(swoole_lock_class_entry_ptr, SW_STRL("FILELOCK")-1, SW_FILELOCK TSRMLS_CC); + zend_declare_class_constant_long(swoole_lock_class_entry_ptr, SW_STRL("MUTEX")-1, SW_MUTEX TSRMLS_CC); + zend_declare_class_constant_long(swoole_lock_class_entry_ptr, SW_STRL("SEM")-1, SW_SEM TSRMLS_CC); +#ifdef HAVE_RWLOCK + zend_declare_class_constant_long(swoole_lock_class_entry_ptr, SW_STRL("RWLOCK")-1, SW_RWLOCK TSRMLS_CC); +#endif +#ifdef HAVE_SPINLOCK + zend_declare_class_constant_long(swoole_lock_class_entry_ptr, SW_STRL("SPINLOCK")-1, SW_SPINLOCK TSRMLS_CC); +#endif + + zend_declare_property_long(swoole_lock_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_LONG_CONSTANT("SWOOLE_FILELOCK", SW_FILELOCK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_MUTEX", SW_MUTEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_SEM", SW_SEM, CONST_CS | CONST_PERSISTENT); +#ifdef HAVE_RWLOCK + REGISTER_LONG_CONSTANT("SWOOLE_RWLOCK", SW_RWLOCK, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef HAVE_SPINLOCK + REGISTER_LONG_CONSTANT("SWOOLE_SPINLOCK", SW_SPINLOCK, CONST_CS | CONST_PERSISTENT); +#endif +} + +static PHP_METHOD(swoole_lock, __construct) +{ + long type = SW_MUTEX; + char *filelock; + zend_size_t filelock_len = 0; + int ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &type, &filelock, &filelock_len) == FAILURE) + { + RETURN_FALSE; + } + + swLock *lock = SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(swLock)); + if (lock == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + + switch(type) + { +#ifdef HAVE_RWLOCK + case SW_RWLOCK: + ret = swRWLock_create(lock, 1); + break; +#endif + case SW_FILELOCK: + if (filelock_len <= 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "filelock requires file name of the lock.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + int fd; + if ((fd = open(filelock, O_RDWR | O_CREAT, 0666)) < 0) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "open file[%s] failed. Error: %s [%d]", filelock, strerror(errno), errno); + RETURN_FALSE; + } + ret = swFileLock_create(lock, fd); + break; + case SW_SEM: + ret = swSem_create(lock, IPC_PRIVATE); + break; +#ifdef HAVE_SPINLOCK + case SW_SPINLOCK: + ret = swSpinLock_create(lock, 1); + break; +#endif + case SW_MUTEX: + default: + ret = swMutex_create(lock, 1); + break; + } + if (ret < 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create lock.", errno TSRMLS_CC); + RETURN_FALSE; + } + swoole_set_object(getThis(), lock); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_lock, __destruct) +{ + swLock *lock = swoole_get_object(getThis()); + if (lock) + { + swoole_set_object(getThis(), NULL); + } +} + +static PHP_METHOD(swoole_lock, lock) +{ + swLock *lock = swoole_get_object(getThis()); + SW_LOCK_CHECK_RETURN(lock->lock(lock)); +} + +static PHP_METHOD(swoole_lock, lockwait) +{ + double timeout = 1.0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &timeout) == FAILURE) + { + RETURN_FALSE; + } + swLock *lock = swoole_get_object(getThis()); + if (lock->type != SW_MUTEX) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "only mutex supports lockwait.", -2 TSRMLS_CC); + RETURN_FALSE; + } + SW_LOCK_CHECK_RETURN(swMutex_lockwait(lock, (int)timeout * 1000)); +} + +static PHP_METHOD(swoole_lock, unlock) +{ + swLock *lock = swoole_get_object(getThis()); + SW_LOCK_CHECK_RETURN(lock->unlock(lock)); +} + +static PHP_METHOD(swoole_lock, trylock) +{ + swLock *lock = swoole_get_object(getThis()); + if (lock->trylock == NULL) + { + swoole_php_error(E_WARNING, "lock[type=%d] can't use trylock", lock->type); + RETURN_FALSE; + } + SW_LOCK_CHECK_RETURN(lock->trylock(lock)); +} + +static PHP_METHOD(swoole_lock, trylock_read) +{ + swLock *lock = swoole_get_object(getThis()); + if (lock->trylock_rd == NULL) + { + swoole_php_error(E_WARNING, "lock[type=%d] can't use trylock_read", lock->type); + RETURN_FALSE; + } + SW_LOCK_CHECK_RETURN(lock->trylock_rd(lock)); +} + +static PHP_METHOD(swoole_lock, lock_read) +{ + swLock *lock = swoole_get_object(getThis()); + if (lock->lock_rd == NULL) + { + swoole_php_error(E_WARNING, "lock[type=%d] can't use lock_read", lock->type); + RETURN_FALSE; + } + SW_LOCK_CHECK_RETURN(lock->lock_rd(lock)); +} + +static PHP_METHOD(swoole_lock, destroy) +{ + swLock *lock = swoole_get_object(getThis()); + lock->free(lock); +} diff --git a/vendor/swoole/swoole_memory_pool.c b/vendor/swoole/swoole_memory_pool.c new file mode 100755 index 0000000..296c734 --- /dev/null +++ b/vendor/swoole/swoole_memory_pool.c @@ -0,0 +1,350 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + | shiguangqi <shiguangqi2008@gmail.com> | + | Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +#include "php_swoole.h" + +enum memory_pool_type +{ + memory_pool_type_fixed = 0, + memory_pool_type_ring = 1, + memory_pool_type_global = 2, + memory_pool_type_malloc = 3, + memory_pool_type_emalloc = 4, +}; + +static PHP_METHOD(swoole_memory_pool, __construct); +static PHP_METHOD(swoole_memory_pool, __destruct); +static PHP_METHOD(swoole_memory_pool, alloc); +static PHP_METHOD(swoole_memory_pool_slice, read); +static PHP_METHOD(swoole_memory_pool_slice, write); +static PHP_METHOD(swoole_memory_pool_slice, __destruct); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +zend_class_entry *ce; +zend_class_entry *ce_slice; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_memory_pool_construct, 0, 0, 2) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, slice_size) + ZEND_ARG_INFO(0, shared) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_memory_pool_alloc, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_memory_pool_slice_read, 0, 0, 0) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_memory_pool_slice_write, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +typedef struct +{ + size_t size; + size_t slice_size; + uint8_t type; + zend_bool shared; + zend_bool released; + swMemoryPool* pool; + sw_atomic_t slice_count; +} MemoryPool; + +typedef struct +{ + size_t size; + uint8_t type; + MemoryPool* pool; + void *memory; +} MemorySlice; + +static const zend_function_entry swoole_memory_pool_methods[] = +{ + PHP_ME(swoole_memory_pool, __construct, arginfo_swoole_memory_pool_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_memory_pool, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_memory_pool, alloc, arginfo_swoole_memory_pool_alloc, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static const zend_function_entry swoole_memory_pool_slice_methods[] = +{ + PHP_ME(swoole_memory_pool_slice, read, arginfo_swoole_memory_pool_slice_read, ZEND_ACC_PUBLIC) + PHP_ME(swoole_memory_pool_slice, write, arginfo_swoole_memory_pool_slice_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_memory_pool_slice, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FE_END +}; + +void swoole_memory_pool_init(int module_number TSRMLS_DC) +{ + static zend_class_entry _ce; + INIT_CLASS_ENTRY(_ce, "Swoole\\Memory\\Pool", swoole_memory_pool_methods); + ce = zend_register_internal_class(&_ce TSRMLS_CC); + + static zend_class_entry _ce_slice; + INIT_CLASS_ENTRY(_ce_slice, "Swoole\\Memory\\Pool\\Slice", swoole_memory_pool_slice_methods); + ce_slice = zend_register_internal_class(&_ce_slice TSRMLS_CC); + + zend_declare_class_constant_long(ce, SW_STRL("TYPE_RING")-1, memory_pool_type_ring TSRMLS_CC); + zend_declare_class_constant_long(ce, SW_STRL("TYPE_GLOBAL")-1, memory_pool_type_global TSRMLS_CC); + zend_declare_class_constant_long(ce, SW_STRL("TYPE_FIXED")-1, memory_pool_type_fixed TSRMLS_CC); + zend_declare_class_constant_long(ce, SW_STRL("TYPE_MALLOC")-1, memory_pool_type_malloc TSRMLS_CC); + zend_declare_class_constant_long(ce, SW_STRL("TYPE_EMALLOC")-1, memory_pool_type_emalloc TSRMLS_CC); +} + +static PHP_METHOD(swoole_memory_pool, __construct) +{ + zend_long size, type, slice_size; + zend_bool shared = 0; + + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_LONG(size) + Z_PARAM_LONG(type) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(slice_size) + Z_PARAM_BOOL(shared) + ZEND_PARSE_PARAMETERS_END(); + + swMemoryPool* pool = NULL; + if (type == memory_pool_type_fixed) + { + void *memory = (shared == 1) ? sw_shm_malloc(size) : sw_malloc(size); + if (memory == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "malloc failed.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + pool = swFixedPool_new2(slice_size, memory, size); + } + else if (type == memory_pool_type_ring) + { + pool = swRingBuffer_new(size, shared); + } + else if (type == memory_pool_type_global) + { + pool = swMemoryGlobal_new(slice_size, shared); + } + else if (type == memory_pool_type_malloc || type == memory_pool_type_malloc) + { + shared = 0; + } + else + { + zend_throw_exception(swoole_exception_class_entry_ptr, "unknown memory pool type.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + + MemoryPool *mp; + if (shared) + { + mp = (MemoryPool *) SwooleG.memory_pool->alloc(SwooleG.memory_pool, sizeof(MemorySlice)); + } + else + { + mp = (MemoryPool *) emalloc(sizeof(MemorySlice)); + } + if (mp == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "malloc failed.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + + mp->size = size; + mp->slice_size = slice_size; + mp->shared = shared; + mp->type = type; + mp->pool = pool; + mp->slice_count = 0; + mp->released = 0; + + swoole_set_object(getThis(), mp); +} + +static PHP_METHOD(swoole_memory_pool, alloc) +{ + MemoryPool* mp = (MemoryPool*) swoole_get_object(getThis()); + zend_long size = mp->slice_size; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(size) + ZEND_PARSE_PARAMETERS_END(); + + if (mp->type != memory_pool_type_fixed && size <= 0) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "invalid size.", SW_ERROR_INVALID_PARAMS TSRMLS_CC); + RETURN_FALSE; + } + + void *memory; + if (mp->type == memory_pool_type_malloc) + { + memory = sw_malloc(size); + } + else if (mp->type == memory_pool_type_emalloc) + { + memory = emalloc(size); + } + else + { + memory = mp->pool->alloc(mp->pool, size); + } + + if (memory == NULL) + { + RETURN_FALSE; + } + + MemorySlice *info = (MemorySlice *) emalloc(sizeof(MemorySlice)); + object_init_ex(return_value, ce_slice); + info->pool = mp; + info->size = size; + info->memory = memory; + info->type = mp->type; + sw_atomic_fetch_add(&mp->slice_count, 1); + swoole_set_object(return_value, info); +} + +static PHP_METHOD(swoole_memory_pool, __destruct) +{ + MemoryPool* mp = (MemoryPool*) swoole_get_object(getThis()); + if (mp == NULL) + { + return; + } + + swoole_set_object(getThis(), NULL); + + if (mp->type == memory_pool_type_malloc || mp->type == memory_pool_type_malloc) + { + efree(mp); + return; + } + + mp->released = 1; + if (mp->slice_count == 0) + { + mp->pool->destroy(mp->pool); + if (mp->shared == 0) + { + efree(mp); + } + } +} + +static PHP_METHOD(swoole_memory_pool_slice, read) +{ + zend_long size = 0; + zend_long offset = 0; + + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(size) + Z_PARAM_LONG(offset) + ZEND_PARSE_PARAMETERS_END(); + + MemorySlice *info = (MemorySlice *) swoole_get_object(getThis()); + if (size <= 0) + { + size = info->size; + } + else if (size > info->size) + { + size = info->size; + swoole_php_error(E_WARNING, "size(%ld) is too big.", size); + } + + if (offset < 0 || offset + size > info->size) + { + swoole_php_error(E_WARNING, "offset(%ld) is out of bounds.", offset); + RETURN_FALSE; + } + + RETURN_STRINGL((char * )info->memory + offset, size); +} + +static PHP_METHOD(swoole_memory_pool_slice, write) +{ + zend_string *data; + zend_long size = 0; + zend_long offset = 0; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(data); + Z_PARAM_OPTIONAL + Z_PARAM_LONG(offset) + ZEND_PARSE_PARAMETERS_END(); + + MemorySlice *info = (MemorySlice *) swoole_get_object(getThis()); + size = data->len; + if (size > info->size) + { + swoole_php_error(E_WARNING, "data is too large.", size); + RETURN_FALSE; + } + if (offset < 0 || offset + size > info->size) + { + swoole_php_error(E_WARNING, "offset(%ld) is out of bounds.", offset); + RETURN_FALSE; + } + + memcpy((char *) info->memory + offset, data->val, size); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_memory_pool_slice, __destruct) +{ + MemorySlice *info = (MemorySlice *) swoole_get_object(getThis()); + if (info == NULL) + { + return; + } + + MemoryPool *mp = info->pool; + if (info->type == memory_pool_type_malloc) + { + sw_free(info->memory); + } + else if (info->type == memory_pool_type_emalloc) + { + efree(info->memory); + } + else + { + mp->pool->free(mp->pool, info->memory); + sw_atomic_fetch_sub(&mp->slice_count, 1); + + if (mp->released && mp->slice_count == 0) + { + mp->pool->destroy(mp->pool); + if (mp->shared == 0) + { + efree(mp); + } + } + } + + swoole_set_object(getThis(), NULL); + efree(info); +} diff --git a/vendor/swoole/swoole_mmap.c b/vendor/swoole/swoole_mmap.c new file mode 100755 index 0000000..aee6f55 --- /dev/null +++ b/vendor/swoole/swoole_mmap.c @@ -0,0 +1,221 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +typedef struct +{ + size_t size; + off_t offset; + char *filename; + void *memory; + void *ptr; +} swMmapFile; + +static size_t mmap_stream_write(php_stream * stream, const char *buffer, size_t length TSRMLS_DC); +static size_t mmap_stream_read(php_stream *stream, char *buffer, size_t length TSRMLS_DC); +static int mmap_stream_flush(php_stream *stream TSRMLS_DC); +static int mmap_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC); +static int mmap_stream_close(php_stream *stream, int close_handle TSRMLS_DC); +static PHP_METHOD(swoole_mmap, open); + +static zend_class_entry swoole_mmap_ce; +zend_class_entry *swoole_mmap_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mmap_open, 0, 0, 1) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_mmap_methods[] = +{ + PHP_ME(swoole_mmap, open, arginfo_swoole_mmap_open, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +php_stream_ops mmap_ops = +{ + mmap_stream_write, + mmap_stream_read, + mmap_stream_close, + mmap_stream_flush, + "swoole_mmap", + mmap_stream_seek, + NULL, + NULL, + NULL +}; + +static size_t mmap_stream_write(php_stream * stream, const char *buffer, size_t length TSRMLS_DC) +{ + swMmapFile *res = stream->abstract; + + int n_write = MIN(res->memory + res->size - res->ptr, length); + if (n_write == 0) + { + return 0; + } + memcpy(res->ptr, buffer, n_write); + res->ptr += n_write; + return n_write; +} + +static size_t mmap_stream_read(php_stream *stream, char *buffer, size_t length TSRMLS_DC) +{ + swMmapFile *res = stream->abstract; + + int n_read = MIN(res->memory + res->size - res->ptr, length); + if (n_read == 0) + { + return 0; + } + memcpy(buffer, res->ptr, n_read); + res->ptr += n_read; + return n_read; +} + +static int mmap_stream_flush(php_stream *stream TSRMLS_DC) +{ + swMmapFile *res = stream->abstract; + return msync(res->memory, res->size, MS_SYNC | MS_INVALIDATE); +} + +static int mmap_stream_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) +{ + swMmapFile *res = stream->abstract; + + switch (whence) + { + case SEEK_SET: + if (offset < 0 || offset > res->size) + { + *newoffset = (off_t) -1; + return -1; + } + res->ptr = res->memory + offset; + *newoffset = offset; + return 0; + case SEEK_CUR: + if (res->ptr + offset < res->memory || res->ptr + offset > res->memory + res->size) + { + *newoffset = (off_t) -1; + return -1; + } + res->ptr += offset; + *newoffset = res->ptr - res->memory; + return 0; + case SEEK_END: + if (offset > 0 || -1 * offset > res->size) + { + *newoffset = (off_t) -1; + return -1; + } + res->ptr += offset; + *newoffset = res->ptr - res->memory; + return 0; + default: + *newoffset = (off_t) -1; + return -1; + } +} + +static int mmap_stream_close(php_stream *stream, int close_handle TSRMLS_DC) +{ + swMmapFile *res = stream->abstract; + if (close_handle) + { + munmap(res->memory, res->size); + } + efree(res); + return 0; +} + +void swoole_mmap_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_mmap_ce, "swoole_mmap", "Swoole\\Mmap", swoole_mmap_methods); + swoole_mmap_class_entry_ptr = zend_register_internal_class(&swoole_mmap_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_mmap, "Swoole\\Mmap"); +} + +static PHP_METHOD(swoole_mmap, open) +{ + char *filename; + zend_size_t l_filename; + long offset = 0; + long size = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &l_filename, &size, &offset) == FAILURE) + { + RETURN_FALSE; + } + + if (l_filename <= 0) + { + swoole_php_fatal_error(E_WARNING, "file name is required."); + RETURN_FALSE; + } + + int fd; + if ((fd = open(filename, O_RDWR)) < 0) + { + swoole_php_sys_error(E_WARNING, "open(%s, O_RDWR) failed.", filename); + RETURN_FALSE; + } + + if (size <= 0) + { + struct stat _stat; + if (fstat(fd, &_stat) < 0) + { + swoole_php_sys_error(E_WARNING, "fstat(%s) failed.", filename); + close(fd); + RETURN_FALSE; + } + if (_stat.st_size == 0) + { + swoole_php_sys_error(E_WARNING, "file[%s] is empty.", filename); + close(fd); + RETURN_FALSE; + } + if (offset > 0) + { + size = _stat.st_size - offset; + } + else + { + size = _stat.st_size; + } + } + + void *addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, offset); + if (addr == NULL) + { + swoole_php_sys_error(E_WARNING, "mmap(%ld) failed.", size); + RETURN_FALSE; + } + + swMmapFile *res = emalloc(sizeof(swMmapFile)); + res->filename = filename; + res->size = size; + res->offset = offset; + res->memory = addr; + res->ptr = addr; + + close(fd); + php_stream *stream = php_stream_alloc(&mmap_ops, res, NULL, "r+"); + php_stream_to_zval(stream, return_value); +} diff --git a/vendor/swoole/swoole_msgqueue.c b/vendor/swoole/swoole_msgqueue.c new file mode 100755 index 0000000..aac1af4 --- /dev/null +++ b/vendor/swoole/swoole_msgqueue.c @@ -0,0 +1,174 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +static PHP_METHOD(swoole_msgqueue, __construct); +static PHP_METHOD(swoole_msgqueue, __destruct); +static PHP_METHOD(swoole_msgqueue, push); +static PHP_METHOD(swoole_msgqueue, pop); +static PHP_METHOD(swoole_msgqueue, setBlocking); +static PHP_METHOD(swoole_msgqueue, stats); +static PHP_METHOD(swoole_msgqueue, destory); + +static zend_class_entry swoole_msgqueue_ce; +zend_class_entry *swoole_msgqueue_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_msgqueue_construct, 0, 0, 1) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_msgqueue_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_msgqueue_pop, 0, 0, 0) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_msgqueue_setBlocking, 0, 0, 1) + ZEND_ARG_INFO(0, blocking) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_msgqueue_methods[] = +{ + PHP_ME(swoole_msgqueue, __construct, arginfo_swoole_msgqueue_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_msgqueue, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_msgqueue, push, arginfo_swoole_msgqueue_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_msgqueue, pop, arginfo_swoole_msgqueue_pop, ZEND_ACC_PUBLIC) + PHP_ME(swoole_msgqueue, setBlocking, arginfo_swoole_msgqueue_setBlocking, ZEND_ACC_PUBLIC) + PHP_ME(swoole_msgqueue, stats, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_msgqueue, destory, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_msgqueue_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_msgqueue_ce, "swoole_msgqueue", "Swoole\\MsgQueue", swoole_msgqueue_methods); + swoole_msgqueue_class_entry_ptr = zend_register_internal_class(&swoole_msgqueue_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_msgqueue, "Swoole\\MsgQueue"); +} + +static PHP_METHOD(swoole_msgqueue, __construct) +{ + long key; + long perms = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &key, &perms) == FAILURE) + { + RETURN_FALSE; + } + + swMsgQueue *queue = emalloc(sizeof(swMsgQueue)); + if (queue == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create MsgQueue.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + if (swMsgQueue_create(queue, 1, key, perms)) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to init MsgQueue.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + swoole_set_object(getThis(), queue); +} + +static PHP_METHOD(swoole_msgqueue, __destruct) +{ + swMsgQueue *queue = swoole_get_object(getThis()); + efree(queue); + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_msgqueue, push) +{ + char *data; + zend_size_t length; + long type = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "s|l", &data, &length, &type) == FAILURE) + { + RETURN_FALSE; + } + + swQueue_data *in = (swQueue_data *) emalloc(length + sizeof(long) + 1); + in->mtype = type; + memcpy(in->mdata, data, length + 1); + + swMsgQueue *queue = swoole_get_object(getThis()); + int ret = swMsgQueue_push(queue, in, length); + efree(in); + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_msgqueue, pop) +{ + long type = 1; + swQueue_data out; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &type) == FAILURE) + { + RETURN_FALSE; + } + + swMsgQueue *queue = swoole_get_object(getThis()); + out.mtype = type; + int length = swMsgQueue_pop(queue, &out, sizeof(out.mdata)); + if (length < 0) + { + RETURN_FALSE; + } + RETURN_STRINGL(out.mdata, length); +} + +static PHP_METHOD(swoole_msgqueue, setBlocking) +{ + swMsgQueue *queue = swoole_get_object(getThis()); + zend_bool blocking; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "b", &blocking) == FAILURE) + { + RETURN_FALSE; + } + swMsgQueue_set_blocking(queue, blocking); +} + +static PHP_METHOD(swoole_msgqueue, stats) +{ + swMsgQueue *queue = swoole_get_object(getThis()); + int queue_num = -1; + int queue_bytes = -1; + if (swMsgQueue_stat(queue, &queue_num, &queue_bytes) == 0) + { + array_init(return_value); + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_num"), queue_num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_bytes"), queue_bytes); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_msgqueue, destory) +{ + swMsgQueue *queue = swoole_get_object(getThis()); + SW_CHECK_RETURN(swMsgQueue_free(queue)); +} diff --git a/vendor/swoole/swoole_mysql.c b/vendor/swoole/swoole_mysql.c new file mode 100755 index 0000000..e64ed78 --- /dev/null +++ b/vendor/swoole/swoole_mysql.c @@ -0,0 +1,3146 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#include "swoole_mysql.h" +#include <ext/hash/php_hash.h> +#include <ext/hash/php_hash_sha.h> + +#ifdef SW_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd.h" +#include "ext/mysqlnd/mysqlnd_charset.h" +#endif + +#ifdef SW_MYSQL_RSA_SUPPORT +#include <openssl/rsa.h> +#include <openssl/pem.h> +#endif + +static PHP_METHOD(swoole_mysql, __construct); +static PHP_METHOD(swoole_mysql, __destruct); +static PHP_METHOD(swoole_mysql, connect); +#ifdef SW_USE_MYSQLND +static PHP_METHOD(swoole_mysql, escape); +#endif +static PHP_METHOD(swoole_mysql, query); +static PHP_METHOD(swoole_mysql, begin); +static PHP_METHOD(swoole_mysql, commit); +static PHP_METHOD(swoole_mysql, rollback); +static PHP_METHOD(swoole_mysql, getState); +static PHP_METHOD(swoole_mysql, close); +static PHP_METHOD(swoole_mysql, on); + +static zend_class_entry swoole_mysql_ce; +static zend_class_entry *swoole_mysql_class_entry_ptr; + +static zend_class_entry swoole_mysql_exception_ce; +static zend_class_entry *swoole_mysql_exception_class_entry_ptr; + +#define UTF8_MB4 "utf8mb4" +#define UTF8_MB3 "utf8" + +typedef struct _mysql_charset +{ + unsigned int nr; + const char *name; + const char *collation; +} mysql_charset; + +static const mysql_charset swoole_mysql_charsets[] = +{ + { 1, "big5", "big5_chinese_ci" }, + { 3, "dec8", "dec8_swedish_ci" }, + { 4, "cp850", "cp850_general_ci" }, + { 6, "hp8", "hp8_english_ci" }, + { 7, "koi8r", "koi8r_general_ci" }, + { 8, "latin1", "latin1_swedish_ci" }, + { 5, "latin1", "latin1_german1_ci" }, + { 9, "latin2", "latin2_general_ci" }, + { 2, "latin2", "latin2_czech_cs" }, + { 10, "swe7", "swe7_swedish_ci" }, + { 11, "ascii", "ascii_general_ci" }, + { 12, "ujis", "ujis_japanese_ci" }, + { 13, "sjis", "sjis_japanese_ci" }, + { 16, "hebrew", "hebrew_general_ci" }, + { 17, "filename", "filename" }, + { 18, "tis620", "tis620_thai_ci" }, + { 19, "euckr", "euckr_korean_ci" }, + { 21, "latin2", "latin2_hungarian_ci" }, + { 27, "latin2", "latin2_croatian_ci" }, + { 22, "koi8u", "koi8u_general_ci" }, + { 24, "gb2312", "gb2312_chinese_ci" }, + { 25, "greek", "greek_general_ci" }, + { 26, "cp1250", "cp1250_general_ci" }, + { 28, "gbk", "gbk_chinese_ci" }, + { 30, "latin5", "latin5_turkish_ci" }, + { 31, "latin1", "latin1_german2_ci" }, + { 15, "latin1", "latin1_danish_ci" }, + { 32, "armscii8", "armscii8_general_ci" }, + { 33, UTF8_MB3, UTF8_MB3"_general_ci" }, + { 35, "ucs2", "ucs2_general_ci" }, + { 36, "cp866", "cp866_general_ci" }, + { 37, "keybcs2", "keybcs2_general_ci" }, + { 38, "macce", "macce_general_ci" }, + { 39, "macroman", "macroman_general_ci" }, + { 40, "cp852", "cp852_general_ci" }, + { 41, "latin7", "latin7_general_ci" }, + { 20, "latin7", "latin7_estonian_cs" }, + { 57, "cp1256", "cp1256_general_ci" }, + { 59, "cp1257", "cp1257_general_ci" }, + { 63, "binary", "binary" }, + { 97, "eucjpms", "eucjpms_japanese_ci" }, + { 29, "cp1257", "cp1257_lithuanian_ci" }, + { 31, "latin1", "latin1_german2_ci" }, + { 34, "cp1250", "cp1250_czech_cs" }, + { 42, "latin7", "latin7_general_cs" }, + { 43, "macce", "macce_bin" }, + { 44, "cp1250", "cp1250_croatian_ci" }, + { 45, UTF8_MB4, UTF8_MB4"_general_ci" }, + { 46, UTF8_MB4, UTF8_MB4"_bin" }, + { 47, "latin1", "latin1_bin" }, + { 48, "latin1", "latin1_general_ci" }, + { 49, "latin1", "latin1_general_cs" }, + { 51, "cp1251", "cp1251_general_ci" }, + { 14, "cp1251", "cp1251_bulgarian_ci" }, + { 23, "cp1251", "cp1251_ukrainian_ci" }, + { 50, "cp1251", "cp1251_bin" }, + { 52, "cp1251", "cp1251_general_cs" }, + { 53, "macroman", "macroman_bin" }, + { 54, "utf16", "utf16_general_ci" }, + { 55, "utf16", "utf16_bin" }, + { 56, "utf16le", "utf16le_general_ci" }, + { 58, "cp1257", "cp1257_bin" }, + { 60, "utf32", "utf32_general_ci" }, + { 61, "utf32", "utf32_bin" }, + { 62, "utf16le", "utf16le_bin" }, + { 64, "armscii8", "armscii8_bin" }, + { 65, "ascii", "ascii_bin" }, + { 66, "cp1250", "cp1250_bin" }, + { 67, "cp1256", "cp1256_bin" }, + { 68, "cp866", "cp866_bin" }, + { 69, "dec8", "dec8_bin" }, + { 70, "greek", "greek_bin" }, + { 71, "hebrew", "hebrew_bin" }, + { 72, "hp8", "hp8_bin" }, + { 73, "keybcs2", "keybcs2_bin" }, + { 74, "koi8r", "koi8r_bin" }, + { 75, "koi8u", "koi8u_bin" }, + { 77, "latin2", "latin2_bin" }, + { 78, "latin5", "latin5_bin" }, + { 79, "latin7", "latin7_bin" }, + { 80, "cp850", "cp850_bin" }, + { 81, "cp852", "cp852_bin" }, + { 82, "swe7", "swe7_bin" }, + { 83, UTF8_MB3, UTF8_MB3"_bin" }, + { 84, "big5", "big5_bin" }, + { 85, "euckr", "euckr_bin" }, + { 86, "gb2312", "gb2312_bin" }, + { 87, "gbk", "gbk_bin" }, + { 88, "sjis", "sjis_bin" }, + { 89, "tis620", "tis620_bin" }, + { 90, "ucs2", "ucs2_bin" }, + { 91, "ujis", "ujis_bin" }, + { 92, "geostd8", "geostd8_general_ci" }, + { 93, "geostd8", "geostd8_bin" }, + { 94, "latin1", "latin1_spanish_ci" }, + { 95, "cp932", "cp932_japanese_ci" }, + { 96, "cp932", "cp932_bin" }, + { 97, "eucjpms", "eucjpms_japanese_ci" }, + { 98, "eucjpms", "eucjpms_bin" }, + { 99, "cp1250", "cp1250_polish_ci" }, + { 128, "ucs2", "ucs2_unicode_ci" }, + { 129, "ucs2", "ucs2_icelandic_ci" }, + { 130, "ucs2", "ucs2_latvian_ci" }, + { 131, "ucs2", "ucs2_romanian_ci" }, + { 132, "ucs2", "ucs2_slovenian_ci" }, + { 133, "ucs2", "ucs2_polish_ci" }, + { 134, "ucs2", "ucs2_estonian_ci" }, + { 135, "ucs2", "ucs2_spanish_ci" }, + { 136, "ucs2", "ucs2_swedish_ci" }, + { 137, "ucs2", "ucs2_turkish_ci" }, + { 138, "ucs2", "ucs2_czech_ci" }, + { 139, "ucs2", "ucs2_danish_ci" }, + { 140, "ucs2", "ucs2_lithuanian_ci" }, + { 141, "ucs2", "ucs2_slovak_ci" }, + { 142, "ucs2", "ucs2_spanish2_ci" }, + { 143, "ucs2", "ucs2_roman_ci" }, + { 144, "ucs2", "ucs2_persian_ci" }, + { 145, "ucs2", "ucs2_esperanto_ci" }, + { 146, "ucs2", "ucs2_hungarian_ci" }, + { 147, "ucs2", "ucs2_sinhala_ci" }, + { 148, "ucs2", "ucs2_german2_ci" }, + { 149, "ucs2", "ucs2_croatian_ci" }, + { 150, "ucs2", "ucs2_unicode_520_ci" }, + { 151, "ucs2", "ucs2_vietnamese_ci" }, + { 160, "utf32", "utf32_unicode_ci" }, + { 161, "utf32", "utf32_icelandic_ci" }, + { 162, "utf32", "utf32_latvian_ci" }, + { 163, "utf32", "utf32_romanian_ci" }, + { 164, "utf32", "utf32_slovenian_ci" }, + { 165, "utf32", "utf32_polish_ci" }, + { 166, "utf32", "utf32_estonian_ci" }, + { 167, "utf32", "utf32_spanish_ci" }, + { 168, "utf32", "utf32_swedish_ci" }, + { 169, "utf32", "utf32_turkish_ci" }, + { 170, "utf32", "utf32_czech_ci" }, + { 171, "utf32", "utf32_danish_ci" }, + { 172, "utf32", "utf32_lithuanian_ci" }, + { 173, "utf32", "utf32_slovak_ci" }, + { 174, "utf32", "utf32_spanish2_ci" }, + { 175, "utf32", "utf32_roman_ci" }, + { 176, "utf32", "utf32_persian_ci" }, + { 177, "utf32", "utf32_esperanto_ci" }, + { 178, "utf32", "utf32_hungarian_ci" }, + { 179, "utf32", "utf32_sinhala_ci" }, + { 180, "utf32", "utf32_german2_ci" }, + { 181, "utf32", "utf32_croatian_ci" }, + { 182, "utf32", "utf32_unicode_520_ci" }, + { 183, "utf32", "utf32_vietnamese_ci" }, + { 192, UTF8_MB3, UTF8_MB3"_unicode_ci" }, + { 193, UTF8_MB3, UTF8_MB3"_icelandic_ci" }, + { 194, UTF8_MB3, UTF8_MB3"_latvian_ci" }, + { 195, UTF8_MB3, UTF8_MB3"_romanian_ci" }, + { 196, UTF8_MB3, UTF8_MB3"_slovenian_ci" }, + { 197, UTF8_MB3, UTF8_MB3"_polish_ci" }, + { 198, UTF8_MB3, UTF8_MB3"_estonian_ci" }, + { 199, UTF8_MB3, UTF8_MB3"_spanish_ci" }, + { 200, UTF8_MB3, UTF8_MB3"_swedish_ci" }, + { 201, UTF8_MB3, UTF8_MB3"_turkish_ci" }, + { 202, UTF8_MB3, UTF8_MB3"_czech_ci" }, + { 203, UTF8_MB3, UTF8_MB3"_danish_ci" }, + { 204, UTF8_MB3, UTF8_MB3"_lithuanian_ci" }, + { 205, UTF8_MB3, UTF8_MB3"_slovak_ci" }, + { 206, UTF8_MB3, UTF8_MB3"_spanish2_ci" }, + { 207, UTF8_MB3, UTF8_MB3"_roman_ci" }, + { 208, UTF8_MB3, UTF8_MB3"_persian_ci" }, + { 209, UTF8_MB3, UTF8_MB3"_esperanto_ci" }, + { 210, UTF8_MB3, UTF8_MB3"_hungarian_ci" }, + { 211, UTF8_MB3, UTF8_MB3"_sinhala_ci" }, + { 212, UTF8_MB3, UTF8_MB3"_german2_ci" }, + { 213, UTF8_MB3, UTF8_MB3"_croatian_ci" }, + { 214, UTF8_MB3, UTF8_MB3"_unicode_520_ci" }, + { 215, UTF8_MB3, UTF8_MB3"_vietnamese_ci" }, + + { 224, UTF8_MB4, UTF8_MB4"_unicode_ci" }, + { 225, UTF8_MB4, UTF8_MB4"_icelandic_ci" }, + { 226, UTF8_MB4, UTF8_MB4"_latvian_ci" }, + { 227, UTF8_MB4, UTF8_MB4"_romanian_ci" }, + { 228, UTF8_MB4, UTF8_MB4"_slovenian_ci" }, + { 229, UTF8_MB4, UTF8_MB4"_polish_ci" }, + { 230, UTF8_MB4, UTF8_MB4"_estonian_ci" }, + { 231, UTF8_MB4, UTF8_MB4"_spanish_ci" }, + { 232, UTF8_MB4, UTF8_MB4"_swedish_ci" }, + { 233, UTF8_MB4, UTF8_MB4"_turkish_ci" }, + { 234, UTF8_MB4, UTF8_MB4"_czech_ci" }, + { 235, UTF8_MB4, UTF8_MB4"_danish_ci" }, + { 236, UTF8_MB4, UTF8_MB4"_lithuanian_ci" }, + { 237, UTF8_MB4, UTF8_MB4"_slovak_ci" }, + { 238, UTF8_MB4, UTF8_MB4"_spanish2_ci" }, + { 239, UTF8_MB4, UTF8_MB4"_roman_ci" }, + { 240, UTF8_MB4, UTF8_MB4"_persian_ci" }, + { 241, UTF8_MB4, UTF8_MB4"_esperanto_ci" }, + { 242, UTF8_MB4, UTF8_MB4"_hungarian_ci" }, + { 243, UTF8_MB4, UTF8_MB4"_sinhala_ci" }, + { 244, UTF8_MB4, UTF8_MB4"_german2_ci" }, + { 245, UTF8_MB4, UTF8_MB4"_croatian_ci" }, + { 246, UTF8_MB4, UTF8_MB4"_unicode_520_ci" }, + { 247, UTF8_MB4, UTF8_MB4"_vietnamese_ci" }, + { 248, "gb18030", "gb18030_chinese_ci" }, + { 249, "gb18030", "gb18030_bin" }, + { 254, UTF8_MB3, UTF8_MB3"_general_cs" }, + { 0, NULL, NULL}, +}; + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_connect, 0, 0, 2) + ZEND_ARG_ARRAY_INFO(0, server_config, 0) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_begin, 0, 0, 1) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_commit, 0, 0, 1) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_rollback, 0, 0, 1) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +#ifdef SW_USE_MYSQLND +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_escape, 0, 0, 1) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_query, 0, 0, 2) + ZEND_ARG_INFO(0, sql) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_mysql_methods[] = +{ + PHP_ME(swoole_mysql, __construct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_mysql, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_mysql, connect, arginfo_swoole_mysql_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, begin, arginfo_swoole_mysql_begin, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, commit, arginfo_swoole_mysql_commit, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, rollback, arginfo_swoole_mysql_rollback, ZEND_ACC_PUBLIC) +#ifdef SW_USE_MYSQLND + PHP_ME(swoole_mysql, escape, arginfo_swoole_mysql_escape, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_mysql, query, arginfo_swoole_mysql_query, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, getState, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql, on, arginfo_swoole_mysql_on, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static void mysql_client_free(mysql_client *client, zval* zobject); +static void mysql_columns_free(mysql_client *client); + +static void mysql_client_free(mysql_client *client, zval* zobject) +{ + if (client->cli->timer) + { + swTimer_del(&SwooleG.timer, client->cli->timer); + client->cli->timer = NULL; + } + //close the connection + client->cli->close(client->cli); + //release client object memory + swClient_free(client->cli); + efree(client->cli); + client->cli = NULL; + client->connected = 0; +} + +static void mysql_columns_free(mysql_client *client) +{ + int i; + for (i = 0; i < client->response.num_column; i++) + { + if (client->response.columns[i].buffer) + { + efree(client->response.columns[i].buffer); + client->response.columns[i].buffer = NULL; + } + } + efree(client->response.columns); +} + +#ifdef SW_MYSQL_DEBUG +static void mysql_client_info(mysql_client *client); +static void mysql_column_info(mysql_field *field); +#endif + +static void swoole_mysql_onTimeout(swTimer *timer, swTimer_node *tnode); +static int swoole_mysql_onRead(swReactor *reactor, swEvent *event); +static int swoole_mysql_onWrite(swReactor *reactor, swEvent *event); +static int swoole_mysql_onError(swReactor *reactor, swEvent *event); +static void swoole_mysql_onConnect(mysql_client *client TSRMLS_DC); + +swString *mysql_request_buffer = NULL; + +void swoole_mysql_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_mysql_ce, "swoole_mysql", "Swoole\\MySQL", swoole_mysql_methods); + swoole_mysql_class_entry_ptr = zend_register_internal_class(&swoole_mysql_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_mysql, "Swoole\\MySQL"); + + SWOOLE_INIT_CLASS_ENTRY(swoole_mysql_exception_ce, "swoole_mysql_exception", "Swoole\\MySQL\\Exception", NULL); + swoole_mysql_exception_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_mysql_exception_ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_mysql_exception, "Swoole\\MySQL\\Exception"); + + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("serverInfo"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("sock"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_mysql_class_entry_ptr, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_class_entry_ptr, ZEND_STRL("errno"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_class_entry_ptr, ZEND_STRL("connect_errno"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("error"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("connect_error"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("insert_id"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("affected_rows"), ZEND_ACC_PUBLIC TSRMLS_CC); + /** + * event callback + */ + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_mysql_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_QUERY")-1, SW_MYSQL_STATE_QUERY TSRMLS_CC); + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_READ_START")-1, SW_MYSQL_STATE_READ_START TSRMLS_CC); + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_READ_FIELD ")-1, SW_MYSQL_STATE_READ_FIELD TSRMLS_CC); + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_READ_ROW")-1, SW_MYSQL_STATE_READ_ROW TSRMLS_CC); + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_READ_END")-1, SW_MYSQL_STATE_READ_END TSRMLS_CC); + zend_declare_class_constant_long(swoole_mysql_class_entry_ptr, SW_STRL("STATE_CLOSED")-1, SW_MYSQL_STATE_CLOSED TSRMLS_CC); +} + +int mysql_request(swString *sql, swString *buffer) +{ + bzero(buffer->str, 5); + //length + mysql_pack_length(sql->length + 1, buffer->str); + //command + buffer->str[4] = SW_MYSQL_COM_QUERY; + buffer->length = 5; + return swString_append(buffer, sql); +} + +int mysql_prepare(swString *sql, swString *buffer) +{ + bzero(buffer->str, 5); + //length + mysql_pack_length(sql->length + 1, buffer->str); + //command + buffer->str[4] = SW_MYSQL_COM_STMT_PREPARE; + buffer->length = 5; + return swString_append(buffer, sql); +} + +int mysql_get_charset(char *name) +{ + const mysql_charset *c = swoole_mysql_charsets; + while (c[0].nr != 0) + { + if (!strcasecmp(c->name, name)) + { + return c->nr; + } + ++c; + } + return -1; +} + +int mysql_get_result(mysql_connector *connector, char *buf, int len) +{ + char *tmp = buf; + int packet_length = mysql_uint3korr(tmp); + if (len < packet_length + 4) + { + return 0; + } + //int packet_number = tmp[3]; + tmp += 4; + + uint8_t opcode = *tmp; + tmp += 1; + + //ERROR Packet + if (opcode == 0xff) + { + connector->error_code = *(uint16_t *) tmp; + connector->error_msg = tmp + 2; + connector->error_length = packet_length - 3; + return -1; + } + else + { + return 1; + } +} + +static void php_swoole_sha256(const char *str, int _len, unsigned char *digest) +{ + PHP_SHA256_CTX context; + PHP_SHA256Init(&context); + PHP_SHA256Update(&context, (unsigned char *) str, _len); + PHP_SHA256Final(digest, &context); +} + +//sha256 +static void mysql_sha2_password_with_nonce(char* ret, char* nonce, char* password, zend_size_t password_len) +{ + // XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce)) + char hashed[32], double_hashed[32]; + php_swoole_sha256(password, password_len, (unsigned char *) hashed); + php_swoole_sha256(hashed, 32, (unsigned char *) double_hashed); + char combined[32 + SW_MYSQL_NONCE_LENGTH]; //double-hashed + nonce + memcpy(combined, double_hashed, 32); + memcpy(combined + 32, nonce, SW_MYSQL_NONCE_LENGTH); + char xor_bytes[32]; + php_swoole_sha256(combined, 32 + SW_MYSQL_NONCE_LENGTH, (unsigned char *) xor_bytes); + int i; + for (i = 0; i < 32; i++) + { + hashed[i] ^= xor_bytes[i]; + } + memcpy(ret, hashed, 32); +} + +/** + * Return: password length + */ +static int mysql_auth_encrypt_dispatch(char *buf, char *auth_plugin_name, char *password, zend_size_t password_len, char* nonce, int *next_state) +{ + if (strcasecmp("mysql_native_password", auth_plugin_name) == 0) + { + // if not native, skip password and will trigger the auth switch + // auth-response + char hash_0[20]; + bzero(hash_0, sizeof (hash_0)); + php_swoole_sha1(password, password_len, (uchar *) hash_0); + + char hash_1[20]; + bzero(hash_1, sizeof (hash_1)); + php_swoole_sha1(hash_0, sizeof (hash_0), (uchar *) hash_1); + + char str[40]; + memcpy(str, nonce, 20); + memcpy(str + 20, hash_1, 20); + + char hash_2[20]; + php_swoole_sha1(str, sizeof (str), (uchar *) hash_2); + + char hash_3[20]; + + int *a = (int *) hash_2; + int *b = (int *) hash_0; + int *c = (int *) hash_3; + + int i; + for (i = 0; i < 5; i++) + { + c[i] = a[i] ^ b[i]; + } + + memcpy(buf, hash_3, 20); + + return 20; + } + else if (strcasecmp("caching_sha2_password", auth_plugin_name) == 0) + { + char hashed[32]; + mysql_sha2_password_with_nonce( + (char *) hashed, + (char *) nonce, + password, + password_len + ); + + // copy hashed data to connector buf + memcpy(buf, (char *) hashed, 32); + *next_state = SW_MYSQL_HANDSHAKE_WAIT_SIGNATURE; + + return 32; + } + else + { + // unknown + swWarn("Unknown auth plugin: %s", auth_plugin_name); + + return 0; + } +} + +/** +1 [0a] protocol version +string[NUL] server version +4 connection id +string[8] auth-plugin-data-part-1 +1 [00] filler +2 capability flags (lower 2 bytes) + if more data in the packet: +1 character set +2 status flags +2 capability flags (upper 2 bytes) + if capabilities & CLIENT_PLUGIN_AUTH { +1 length of auth-plugin-data + } else { +1 [00] + } +string[10] reserved (all [00]) + if capabilities & CLIENT_SECURE_CONNECTION { +string[$len] auth-plugin-data-part-2 ($len=MAX(13, length of auth-plugin-data - 8)) + if capabilities & CLIENT_PLUGIN_AUTH { +string[NUL] auth-plugin name + } + */ +int mysql_handshake(mysql_connector *connector, char *buf, int len) +{ + char *tmp = buf; + int next_state = SW_MYSQL_HANDSHAKE_WAIT_RESULT; // ret is the next handshake state + + /** + * handshake request + */ + mysql_handshake_request request; + bzero(&request, sizeof(request)); + + request.packet_length = mysql_uint3korr(tmp); + //continue to wait for data + if (len < request.packet_length + 4) + { + return 0; + } + + request.packet_number = tmp[3]; + tmp += 4; + + request.protocol_version = *tmp; + tmp += 1; + + //ERROR Packet + if (request.protocol_version == 0xff) + { + connector->error_code = *(uint16_t *) tmp; + connector->error_msg = tmp + 2; + connector->error_length = request.packet_length - 3; + return -1; + } + + //1 [0a] protocol version + request.server_version = tmp; + tmp += (strlen(request.server_version) + 1); + //4 connection id + request.connection_id = *((int *) tmp); + tmp += 4; + //string[8] auth-plugin-data-part-1 + memcpy(request.auth_plugin_data, tmp, 8); + tmp += 8; + //1 [00] filler + request.filler = *tmp; + tmp += 1; + //2 capability flags (lower 2 bytes) + memcpy(((char *) (&request.capability_flags)), tmp, 2); + tmp += 2; + + if (tmp - tmp < len) + { + //1 character set + request.character_set = *tmp; + tmp += 1; + //2 status flags + memcpy(&request.status_flags, tmp, 2); + tmp += 2; + //2 capability flags (upper 2 bytes) + memcpy(((char *) (&request.capability_flags) + 2), tmp, 2); + tmp += 2; + + request.l_auth_plugin_data = *tmp; + tmp += 1; + + memcpy(&request.reserved, tmp, sizeof(request.reserved)); + tmp += sizeof(request.reserved); + + if (request.capability_flags & SW_MYSQL_CLIENT_SECURE_CONNECTION) + { + int len = MAX(13, request.l_auth_plugin_data - 8); + memcpy(request.auth_plugin_data + 8, tmp, len); +#ifdef SW_MYSQL_RSA_SUPPORT + memcpy(connector->auth_plugin_data, request.auth_plugin_data, SW_MYSQL_NONCE_LENGTH); +#endif + tmp += len; + } + + if (request.capability_flags & SW_MYSQL_CLIENT_PLUGIN_AUTH) + { + request.auth_plugin_name = tmp; + request.l_auth_plugin_name = MIN(strlen(tmp), len - (tmp - buf)); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "use %s auth plugin", request.auth_plugin_name); + } + } + + int value; + tmp = connector->buf + 4; + + //capability flags, CLIENT_PROTOCOL_41 always set + value = SW_MYSQL_CLIENT_LONG_PASSWORD | SW_MYSQL_CLIENT_PROTOCOL_41 | SW_MYSQL_CLIENT_SECURE_CONNECTION + | SW_MYSQL_CLIENT_CONNECT_WITH_DB | SW_MYSQL_CLIENT_PLUGIN_AUTH | SW_MYSQL_CLIENT_MULTI_RESULTS; + memcpy(tmp, &value, sizeof(value)); + tmp += 4; + + //max-packet size + value = 300; + memcpy(tmp, &value, sizeof(value)); + tmp += 4; + + //use the server character_set when the character_set is not set. + if (connector->character_set == 0) + { + connector->character_set = request.character_set; + } + + //character set + *tmp = connector->character_set; + tmp += 1; + + //string[23] reserved (all [0]) + tmp += 23; + + //string[NUL] username + memcpy(tmp, connector->user, connector->user_len); + tmp[connector->user_len] = '\0'; + tmp += (connector->user_len + 1); + + if (connector->password_len > 0) + { + int length = 0; + length = mysql_auth_encrypt_dispatch( + tmp + 1, + request.auth_plugin_name, + connector->password, + connector->password_len, + request.auth_plugin_data, + &next_state + ); + *tmp = length; + tmp += length + 1; + } + else + { + *tmp = 0; + tmp++; + } + + //string[NUL] database + memcpy(tmp, connector->database, connector->database_len); + tmp[connector->database_len] = '\0'; + tmp += (connector->database_len + 1); + + //string[NUL] auth plugin name + memcpy(tmp, request.auth_plugin_name, request.l_auth_plugin_name); + tmp[request.l_auth_plugin_name] = '\0'; + tmp += (request.l_auth_plugin_name + 1); + + connector->packet_length = tmp - connector->buf - 4; + mysql_pack_length(connector->packet_length, connector->buf); + connector->buf[3] = 1; + + return next_state; +} + +// we may need it one day but now +// we can reply the every auth plugin requirement on the first handshake +int mysql_auth_switch(mysql_connector *connector, char *buf, int len) +{ + char *tmp = buf; + if ((uint8_t) tmp[4] != 0xfe) + { + // out of the order package + return SW_ERR; + } + + int next_state = SW_MYSQL_HANDSHAKE_WAIT_RESULT; + + int packet_length = mysql_uint3korr(tmp); + //continue to wait for data + if (len < packet_length + 4) + { + return SW_AGAIN; + } + int packet_number = tmp[3]; + tmp += 4; + + // type + tmp += 1; + + // clear + connector->packet_length = 0; + memset(connector->buf, 0, 512); + + // string[NUL] plugin name + char auth_plugin_name[32]; + int auth_plugin_name_len = 0; + int i; + for (i = 0; i < packet_length; i++) + { + auth_plugin_name[auth_plugin_name_len] = tmp[auth_plugin_name_len]; + auth_plugin_name_len++; + if (tmp[auth_plugin_name_len] == 0x00) + { + break; + } + } + auth_plugin_name[auth_plugin_name_len] = '\0'; + swTraceLog(SW_TRACE_MYSQL_CLIENT, "auth switch plugin name=%s", auth_plugin_name); + tmp += auth_plugin_name_len + 1; // name + 0x00 + + // if auth switch is triggered, password can't be empty + // string auth plugin data + char auth_plugin_data[20]; + memcpy((char *)auth_plugin_data, tmp, 20); + + // create auth switch response package + connector->packet_length += mysql_auth_encrypt_dispatch( + (char *) (connector->buf + 4), + auth_plugin_name, + connector->password, + connector->password_len, + auth_plugin_data, + &next_state + ); + // 3 for package length + mysql_pack_length(connector->packet_length, connector->buf); + // 1 package num + connector->buf[3] = packet_number + 1; + + return next_state; +} + +int mysql_parse_auth_signature(swString *buffer, mysql_connector *connector) +{ + char *tmp = buffer->str; + int packet_length = mysql_uint3korr(tmp); + //continue to wait for data + if (buffer->length < packet_length + 4) + { + return SW_AGAIN; + } + int packet_number = tmp[3]; + tmp += 4; + + // signature + if ((uint8_t) tmp[0] != SW_MYSQL_AUTH_SIGNATURE) + { + return SW_MYSQL_AUTH_SIGNATURE_ERROR; + } + + // remaining length + buffer->offset = 4 + packet_length; + swTraceLog(SW_TRACE_MYSQL_CLIENT, "before signature remaining=%d", buffer->length - buffer->offset); + + if ((uint8_t)tmp[1] == SW_MYSQL_AUTH_SIGNATURE_FULL_AUTH_REQUIRED) + { + // create RSA prepared response + connector->packet_length = 1; + memset(connector->buf, 0, 512); + // 3 for package length + mysql_pack_length(connector->packet_length, connector->buf); + // 1 packet number + connector->buf[3] = packet_number + 1; + // as I am OK + connector->buf[4] = SW_MYSQL_AUTH_SIGNATURE_RSA_PREPARED; + } + + // signature value + return tmp[1]; +} + +#ifdef SW_MYSQL_RSA_SUPPORT +// Caching sha2 authentication. Public key request and send encrypted password +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +int mysql_parse_rsa(mysql_connector *connector, char *buf, int len) +{ + // clear + connector->packet_length = 0; + memset(connector->buf, 0, 512); + + char *tmp = buf; + + int packet_length = mysql_uint3korr(tmp); + //continue to wait for data + if (len < packet_length + 4) + { + return SW_AGAIN; + } + int packet_number = tmp[3]; + tmp += 4; + + int rsa_public_key_length = packet_length; + while (tmp[0] != 0x2d) + { + tmp++; // ltrim + rsa_public_key_length--; + } + char rsa_public_key[rsa_public_key_length + 1]; //rsa + '\0' + memcpy((char *)rsa_public_key, tmp, rsa_public_key_length); + rsa_public_key[rsa_public_key_length] = '\0'; + swTraceLog(SW_TRACE_MYSQL_CLIENT, "rsa-length=%d;\nrsa-key=[%.*s]", rsa_public_key_length, rsa_public_key_length, rsa_public_key); + + int password_len = connector->password_len + 1; + unsigned char password[password_len]; + // copy to stack + memcpy((char *)password, connector->password, password_len); + // add NUL terminator to password + password[password_len - 1] = '\0'; + // XOR the password bytes with the challenge + int i; + for (i = 0; i < password_len; i++) + { + password[i] ^= connector->auth_plugin_data[i % SW_MYSQL_NONCE_LENGTH]; + } + + // prepare RSA public key + BIO *bio = NULL; + RSA *public_rsa = NULL; + if (unlikely((bio = BIO_new_mem_buf((void *)rsa_public_key, -1)) == NULL)) + { + swError("BIO_new_mem_buf publicKey error!"); + return SW_ERR; + } + // PEM_read_bio_RSA_PUBKEY + ERR_clear_error(); + if (unlikely((public_rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL)) + { + ERR_load_crypto_strings(); + char err_buf[512]; + ERR_error_string_n(ERR_get_error(), err_buf, sizeof(err_buf)); + swError("[PEM_read_bio_RSA_PUBKEY ERROR]: %s", err_buf); + + return SW_ERR; + } + BIO_free_all(bio); + // encrypt with RSA public key + int rsa_len = RSA_size(public_rsa); + unsigned char encrypt_msg[rsa_len]; + // RSA_public_encrypt + ERR_clear_error(); + int flen = rsa_len - 42; + flen = password_len > flen ? flen : password_len; + swDebug("rsa_len=%d", rsa_len); + if (unlikely(RSA_public_encrypt(flen, (const unsigned char *)password, (unsigned char *)encrypt_msg, public_rsa, RSA_PKCS1_OAEP_PADDING) < 0)) + { + ERR_load_crypto_strings(); + char err_buf[512]; + ERR_error_string_n(ERR_get_error(), err_buf, sizeof(err_buf)); + swError("[RSA_public_encrypt ERROR]: %s", err_buf); + return SW_ERR; + } + RSA_free(public_rsa); + + memcpy((char *)connector->buf + 4, (char *)encrypt_msg, rsa_len); // copy rsa to buf + connector->packet_length = rsa_len; + + // 3 for package length + mysql_pack_length(connector->packet_length, connector->buf); + // 1 packet number + connector->buf[3] = packet_number + 1; + + return SW_OK; +} +#endif + + +static int mysql_parse_prepare_result(mysql_client *client, char *buf, size_t n_buf) +{ + if (n_buf < 11) + { + return SW_ERR; + } + + mysql_statement *stmt = emalloc(sizeof(mysql_statement)); + stmt->id = mysql_uint4korr(buf); + buf += 4; + stmt->field_count = mysql_uint2korr(buf); + buf += 2; + stmt->unreaded_param_count = stmt->param_count = mysql_uint2korr(buf); + buf += 2; + //skip 1 byte + buf += 1; + stmt->warning_count = mysql_uint2korr(buf); + stmt->result = NULL; + stmt->buffer = NULL; + client->statement = stmt; + stmt->client = client; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "id=%d, field_count=%d, param_count=%d, warning_count=%d.", stmt->id, stmt->field_count, stmt->param_count, + stmt->warning_count); + + return 11; +} + +static int mysql_decode_row(mysql_client *client, char *buf, int packet_len) +{ + int read_n = 0, i; + int tmp_len; + ulong_t len; + char nul; + + mysql_row row; + char value_buffer[32]; + bzero(&row, sizeof(row)); + char *error; + //unused + //char mem; + + zval *result_array = client->response.result_array; + zval *row_array = NULL; + SW_ALLOC_INIT_ZVAL(row_array); + array_init(row_array); + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "mysql_decode_row begin, num_column=%d, packet_len=%d.", client->response.num_column, packet_len); + + for (i = 0; i < client->response.num_column; i++) + { + tmp_len = mysql_length_coded_binary(&buf[read_n], &len, &nul, packet_len - read_n); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + + read_n += tmp_len; + if (read_n + len > packet_len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n=%d, fname=%s, name_length=%d", i, client->response.columns[i].name, + client->response.columns[i].name_length); + + if (nul == 1) + { + add_assoc_null(row_array, client->response.columns[i].name); + continue; + } + + int type = client->response.columns[i].type; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "value: name=%s, type=%d, value=%s, len=%ld", + client->response.columns[i].name, type, swoole_strndup(buf + read_n, len), len); + + switch (type) + { + case SW_MYSQL_TYPE_NULL: + add_assoc_null(row_array, client->response.columns[i].name); + break; + /* String */ + case SW_MYSQL_TYPE_TINY_BLOB: + case SW_MYSQL_TYPE_MEDIUM_BLOB: + case SW_MYSQL_TYPE_LONG_BLOB: + case SW_MYSQL_TYPE_BLOB: + case SW_MYSQL_TYPE_DECIMAL: + case SW_MYSQL_TYPE_NEWDECIMAL: + case SW_MYSQL_TYPE_BIT: + case SW_MYSQL_TYPE_STRING: + case SW_MYSQL_TYPE_VAR_STRING: + case SW_MYSQL_TYPE_VARCHAR: + case SW_MYSQL_TYPE_NEWDATE: + /* Date Time */ + case SW_MYSQL_TYPE_TIME: + case SW_MYSQL_TYPE_YEAR: + case SW_MYSQL_TYPE_TIMESTAMP: + case SW_MYSQL_TYPE_DATETIME: + case SW_MYSQL_TYPE_DATE: + case SW_MYSQL_TYPE_JSON: + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + break; + /* Integer */ + case SW_MYSQL_TYPE_TINY: + case SW_MYSQL_TYPE_SHORT: + case SW_MYSQL_TYPE_INT24: + case SW_MYSQL_TYPE_LONG: + if(client->connector.strict_type) + { + memcpy(value_buffer, buf + read_n, len); + value_buffer[len] = 0; + row.sint = strtol(value_buffer, &error, 10); + if (*error != '\0') + { + return -SW_MYSQL_ERR_CONVLONG; + } + add_assoc_long(row_array, client->response.columns[i].name, row.sint); + } + else + { + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + + } + break; + case SW_MYSQL_TYPE_LONGLONG: + if(client->connector.strict_type) { + memcpy(value_buffer, buf + read_n, len); + value_buffer[len] = 0; + row.sbigint = strtoll(value_buffer, &error, 10); + if (*error != '\0') { + return -SW_MYSQL_ERR_CONVLONG; + } + add_assoc_long(row_array, client->response.columns[i].name, row.sbigint); + } + else + { + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + + } + break; + case SW_MYSQL_TYPE_FLOAT: + if(client->connector.strict_type) { + memcpy(value_buffer, buf + read_n, len); + value_buffer[len] = 0; + row.mfloat = strtof(value_buffer, &error); + if (*error != '\0') { + return -SW_MYSQL_ERR_CONVFLOAT; + } + add_assoc_double(row_array, client->response.columns[i].name, row.mfloat); + } + else + { + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + } + break; + + case SW_MYSQL_TYPE_DOUBLE: + if(client->connector.strict_type) { + memcpy(value_buffer, buf + read_n, len); + value_buffer[len] = 0; + row.mdouble = strtod(value_buffer, &error); + if (*error != '\0') { + return -SW_MYSQL_ERR_CONVDOUBLE; + } + add_assoc_double(row_array, client->response.columns[i].name, row.mdouble); + } + else + { + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + + } + break; + + default: + swWarn("unknown field type[%d].", type); + return -1; + } + read_n += len; + } + + add_next_index_zval(result_array, row_array); + +#if PHP_MAJOR_VERSION > 5 + if (row_array) + { + efree(row_array); + } +#endif + + return read_n; +} + +#define DATETIME_MAX_SIZE 20 + +static int mysql_decode_datetime(char *buf, char *result) +{ + uint16_t y = 0; + uint8_t M = 0, d = 0, h = 0, m = 0, s = 0, n; + + n = *(uint8_t *) (buf); + if (n != 0) + { + y = *(uint16_t *) (buf + 1); + M = *(uint8_t *) (buf + 3); + d = *(uint8_t *) (buf + 4); + if (n > 4) + { + h = *(uint8_t *) (buf + 5); + m = *(uint8_t *) (buf + 6); + s = *(uint8_t *) (buf + 7); + } + } + snprintf(result, DATETIME_MAX_SIZE, "%04d-%02d-%02d %02d:%02d:%02d", y, M, d, h, m, s); + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n=%d", n); + + return n; +} + +static int mysql_decode_time(char *buf, char *result) +{ + uint8_t h = 0, m = 0, s = 0; + + uint8_t n = *(uint8_t *) (buf); + if (n != 0) + { + h = *(uint8_t *) (buf + 6); + m = *(uint8_t *) (buf + 7); + s = *(uint8_t *) (buf + 8); + } + + snprintf(result, DATETIME_MAX_SIZE, "%02d:%02d:%02d", h, m, s); + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n=%d", n); + + return n; +} + +static int mysql_decode_date(char *buf, char *result) +{ + uint8_t M = 0, d = 0, n; + uint16_t y = 0; + + n = *(uint8_t *) (buf); + if (n != 0) + { + y = *(uint16_t *) (buf + 1); + M = *(uint8_t *) (buf + 3); + d = *(uint8_t *) (buf + 4); + } + snprintf(result, DATETIME_MAX_SIZE, "%04d-%02d-%02d", y, M, d); + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n=%d", n); + + return n; +} + +static void mysql_decode_year(char *buf, char *result) +{ + uint16_t y = *(uint16_t *) (buf); + snprintf(result, DATETIME_MAX_SIZE, "%04d", y); +} + +static int mysql_decode_row_prepare(mysql_client *client, char *buf, int packet_len) +{ + int read_n = 0, i; + int tmp_len; + ulong_t len = 0; + char nul; + + unsigned int null_count = ((client->response.num_column + 9) / 8) + 1; + buf += null_count; + packet_len -= null_count; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "null_count=%d", null_count); + + char datetime_buffer[DATETIME_MAX_SIZE]; + mysql_row row; + + zval *result_array = client->response.result_array; + zval *row_array = NULL; + SW_ALLOC_INIT_ZVAL(row_array); + array_init(row_array); + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "mysql_decode_row begin, num_column=%d, packet_len=%d.", client->response.num_column, packet_len); + + for (i = 0; i < client->response.num_column; i++) + { + /* to check Null-Bitmap @see https://dev.mysql.com/doc/internals/en/null-bitmap.html */ + if (((buf - null_count + 1)[((i + 2) / 8)] & (0x01 << ((i + 2) % 8))) != 0) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "value: %s is null ,flag2", client->response.columns[i].name); + add_assoc_null(row_array, client->response.columns[i].name); + continue; + } + + int type = client->response.columns[i].type; + swTraceLog(SW_TRACE_MYSQL_CLIENT, "value: name=%s, type=%d", client->response.columns[i].name, type); + switch (type) + { + /* Date Time */ + case SW_MYSQL_TYPE_TIME: + len = mysql_decode_time(buf + read_n, datetime_buffer) + 1; + sw_add_assoc_stringl(row_array, client->response.columns[i].name, datetime_buffer, 8, 1); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%s", client->response.columns[i].name, datetime_buffer); + break; + + case SW_MYSQL_TYPE_YEAR: + mysql_decode_year(buf + read_n, datetime_buffer); + sw_add_assoc_stringl(row_array, client->response.columns[i].name, datetime_buffer, 4, 1); + len = 2; + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%s", client->response.columns[i].name, datetime_buffer); + break; + + case SW_MYSQL_TYPE_DATE: + len = mysql_decode_date(buf + read_n, datetime_buffer) + 1; + sw_add_assoc_stringl(row_array, client->response.columns[i].name, datetime_buffer, 10, 1); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%s", client->response.columns[i].name, datetime_buffer); + break; + + case SW_MYSQL_TYPE_TIMESTAMP: + case SW_MYSQL_TYPE_DATETIME: + len = mysql_decode_datetime(buf + read_n, datetime_buffer) + 1; + sw_add_assoc_stringl(row_array, client->response.columns[i].name, datetime_buffer, 19, 1); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%s", client->response.columns[i].name, datetime_buffer); + break; + + case SW_MYSQL_TYPE_NULL: + add_assoc_null(row_array, client->response.columns[i].name); + break; + + /* String */ + case SW_MYSQL_TYPE_TINY_BLOB: + case SW_MYSQL_TYPE_MEDIUM_BLOB: + case SW_MYSQL_TYPE_LONG_BLOB: + case SW_MYSQL_TYPE_BLOB: + case SW_MYSQL_TYPE_DECIMAL: + case SW_MYSQL_TYPE_NEWDECIMAL: + case SW_MYSQL_TYPE_BIT: + case SW_MYSQL_TYPE_JSON: + case SW_MYSQL_TYPE_STRING: + case SW_MYSQL_TYPE_VAR_STRING: + case SW_MYSQL_TYPE_VARCHAR: + case SW_MYSQL_TYPE_NEWDATE: + tmp_len = mysql_length_coded_binary(&buf[read_n], &len, &nul, packet_len - read_n); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + read_n += tmp_len; + sw_add_assoc_stringl(row_array, client->response.columns[i].name, buf + read_n, len, 1); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%s", client->response.columns[i].name, swoole_strndup(buf + read_n, len)); + break; + + /* Integer */ + case SW_MYSQL_TYPE_TINY: + row.stiny = *(int8_t *) (buf + read_n); + add_assoc_long(row_array, client->response.columns[i].name, row.stiny); + len = sizeof(row.stiny); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%d", client->response.columns[i].name, row.stiny); + break; + + case SW_MYSQL_TYPE_SHORT: + row.ssmall = *(int16_t *) (buf + read_n); + add_assoc_long(row_array, client->response.columns[i].name, row.ssmall); + len = sizeof(row.ssmall); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%d", client->response.columns[i].name, row.ssmall); + break; + + case SW_MYSQL_TYPE_INT24: + case SW_MYSQL_TYPE_LONG: + row.sint = *(int32_t *) (buf + read_n); + add_assoc_long(row_array, client->response.columns[i].name, row.sint); + len = sizeof(row.sint); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%d", client->response.columns[i].name, row.sint); + break; + + case SW_MYSQL_TYPE_LONGLONG: + row.sbigint = *(int64_t *) (buf + read_n); + add_assoc_long(row_array, client->response.columns[i].name, row.sbigint); + len = sizeof(row.sbigint); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%ld", client->response.columns[i].name, row.sbigint); + break; + + case SW_MYSQL_TYPE_FLOAT: + row.mfloat = *(float *) (buf + read_n); + add_assoc_double(row_array, client->response.columns[i].name, row.mfloat); + len = sizeof(row.mfloat); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%f", client->response.columns[i].name, row.mfloat); + break; + + case SW_MYSQL_TYPE_DOUBLE: + row.mdouble = *(double *) (buf + read_n); + add_assoc_double(row_array, client->response.columns[i].name, row.mdouble); + len = sizeof(row.mdouble); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "%s=%f", client->response.columns[i].name, row.mdouble); + break; + + default: + swWarn("unknown field type[%d].", type); + return -1; + } + read_n += len; + } + + add_next_index_zval(result_array, row_array); + +#if PHP_MAJOR_VERSION > 5 + if (row_array) + { + efree(row_array); + } +#endif + + return read_n + null_count; +} + +static sw_inline int mysql_read_eof(mysql_client *client, char *buffer, int n_buf) +{ + //EOF, length (3byte) + id(1byte) + 0xFE + warning(2byte) + status(2byte) + if (n_buf < 9) + { + client->response.wait_recv = 1; + return SW_ERR; + } + + client->response.packet_length = mysql_uint3korr(buffer); + client->response.packet_number = buffer[3]; + + //not EOF packet + uint8_t eof = buffer[4]; + if (eof != 0xfe) + { + return SW_ERR; + } + + client->response.warnings = mysql_uint2korr(buffer + 5); + client->response.status_code = mysql_uint2korr(buffer + 7); + MYSQL_RESPONSE_BUFFER->offset += client->response.packet_length + 4; + + return SW_OK; +} + +static sw_inline int mysql_read_params(mysql_client *client) +{ + while (1) + { + swString *buffer = MYSQL_RESPONSE_BUFFER; + char *t_buffer = buffer->str + buffer->offset; + uint32_t n_buf = buffer->length - buffer->offset; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n_buf=%d, length=%d.", n_buf, client->response.packet_length); + + if (n_buf < 4) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "read eof [1]"); + return SW_ERR; + } + + if (client->statement->unreaded_param_count > 0) + { + //no enough data + if (n_buf - 4 < client->response.packet_length) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "read eof 234234."); + return SW_ERR; + } + // Read and ignore parameter field. Sentence from MySQL source: + // skip parameters data: we don't support it yet + client->response.packet_length = mysql_uint3korr(t_buffer); + client->response.packet_number = t_buffer[3]; + buffer->offset += (client->response.packet_length + 4); + client->statement->unreaded_param_count--; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "read param, count=%d.", client->statement->unreaded_param_count); + + continue; + } + else + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "read eof [2]"); + + if (mysql_read_eof(client, t_buffer, n_buf) == 0) + { + return SW_OK; + } + else + { + return SW_ERR; + } + } + } +} + +static sw_inline int mysql_read_rows(mysql_client *client) +{ + swString *buffer = MYSQL_RESPONSE_BUFFER; + char *t_buffer = buffer->str + buffer->offset; + uint32_t n_buf = buffer->length - buffer->offset; + int ret; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "n_buf=%d", n_buf); + + //RecordSet parse + while (n_buf > 0) + { + if (n_buf < 4) + { + client->response.wait_recv = 1; + return SW_ERR; + } + //RecordSet end + else if (mysql_read_eof(client, t_buffer, n_buf) == SW_OK) + { + if (client->response.columns) + { + mysql_columns_free(client); + } + return SW_OK; + } + + client->response.packet_length = mysql_uint3korr(t_buffer); + client->response.packet_number = t_buffer[3]; + t_buffer += 4; + n_buf -= 4; + + swTraceLog(SW_TRACE_MYSQL_CLIENT, "record size=%d", client->response.packet_length); + + //no enough data + if (n_buf < client->response.packet_length) + { + client->response.wait_recv = 1; + return SW_ERR; + } + + if (client->cmd == SW_MYSQL_COM_STMT_EXECUTE) + { + ret = mysql_decode_row_prepare(client, t_buffer, client->response.packet_length); + } + else + { + //decode + ret = mysql_decode_row(client, t_buffer, client->response.packet_length); + } + + if (ret < 0) + { + break; + } + + //next row + client->response.num_row++; + t_buffer += client->response.packet_length; + n_buf -= client->response.packet_length; + buffer->offset += client->response.packet_length + 4; + } + + return SW_ERR; +} + +static int mysql_decode_field(char *buf, int len, mysql_field *col) +{ + int i; + ulong_t size; + char nul; + char *wh; + int tmp_len; + + /** + * string buffer + */ + char *_buffer = (char*) emalloc(len); + if (!_buffer) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + col->buffer = _buffer; + + wh = buf; + + i = 0; + + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->catalog_length = size; + col->catalog = _buffer; + _buffer += (size + 1); + memcpy(col->catalog, &buf[i], size); + col->catalog[size] = '\0'; + wh += size + 1; + i += size; + + /* n (Length Coded String) db */ + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->db_length = size; + col->db = _buffer; + _buffer += (size + 1); + memcpy(col->db, &buf[i], size); + col->db[size] = '\0'; + wh += size + 1; + i += size; + + /* n (Length Coded String) table */ + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->table_length = size; + col->table = _buffer; + _buffer += (size + 1); + memcpy(col->table, &buf[i], size); + col->table[size] = '\0'; + wh += size + 1; + i += size; + + /* n (Length Coded String) org_table */ + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->org_table_length = size; + col->org_table = _buffer; + _buffer += (size + 1); + memcpy(col->org_table, &buf[i], size); + col->org_table[size] = '\0'; + wh += size + 1; + i += size; + + /* n (Length Coded String) name */ + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->name_length = size; + col->name = _buffer; + _buffer += (size + 1); + memcpy(col->name, &buf[i], size); + col->name[size] = '\0'; + wh += size + 1; + i += size; + + /* n (Length Coded String) org_name */ + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->org_name_length = size; + col->org_name = _buffer; + _buffer += (size + 1); + memcpy(col->org_name, &buf[i], size); + col->org_name[size] = '\0'; + wh += size + 1; + i += size; + + /* check len */ + if (i + 13 > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + + /* (filler) */ + i += 1; + + /* charset */ + col->charsetnr = mysql_uint2korr(&buf[i]); + i += 2; + + /* length */ + col->length = mysql_uint4korr(&buf[i]); + i += 4; + + /* type */ + col->type = (enum mysql_field_types) (uchar)buf[i]; + i += 1; + + /* flags */ + col->flags = mysql_uint2korr(&buf[i]); + i += 2; + + /* decimals */ + col->decimals = buf[i]; + i += 1; + + /* filler */ + i += 2; + + /* default - a priori facultatif */ + if (len - i > 0) + { + tmp_len = mysql_length_coded_binary(&buf[i], &size, &nul, len - i); + if (tmp_len == -1) + { + return -SW_MYSQL_ERR_BAD_LCB; + } + i += tmp_len; + if (i + size > len) + { + return -SW_MYSQL_ERR_LEN_OVER_BUFFER; + } + col->def_length = size; + col->def = _buffer; + //_buffer += (size + 1); + memcpy(col->def, &buf[i], size); + col->def[size] = '\0'; + wh += size + 1; + i += size; + } + else + { + col->def = NULL; + col->def_length = 0; + } + + /* set write pointer */ + return wh - buf; +} + +static int mysql_read_columns(mysql_client *client) +{ + swString *buffer = MYSQL_RESPONSE_BUFFER; + char *t_buffer = buffer->str + buffer->offset; + uint32_t n_buf = buffer->length - buffer->offset; + int ret; + + for (; client->response.index_column < client->response.num_column; client->response.index_column++) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "index_index_column=%d, n_buf=%d.", client->response.index_column, n_buf); + + if (n_buf < 4) + { + return SW_ERR; + } + + client->response.packet_length = mysql_uint3korr(t_buffer); + + //no enough data + if (n_buf - 4 < client->response.packet_length) + { + return SW_ERR; + } + + client->response.packet_number = t_buffer[3]; + t_buffer += 4; + n_buf -= 4; + + ret = mysql_decode_field(t_buffer, client->response.packet_length, &client->response.columns[client->response.index_column]); + if (ret > 0) + { + t_buffer += client->response.packet_length; + n_buf -= client->response.packet_length; + buffer->offset += (client->response.packet_length + 4); + } + else + { + swWarn("mysql_decode_field failed, code=%d.", ret); + break; + } + } + + if (mysql_read_eof(client, t_buffer, n_buf) < 0) + { + return SW_ERR; + } + + t_buffer += 9; + n_buf -= 9; + + if (client->cmd != SW_MYSQL_COM_STMT_PREPARE) + { + zval *result_array = client->response.result_array; + if (!result_array) + { + SW_ALLOC_INIT_ZVAL(result_array); + array_init(result_array); + client->response.result_array = result_array; + } + } + + buffer->offset += t_buffer - (buffer->str + buffer->offset); + + return SW_OK; +} + +// this function is used to check if multi responses has received over. +int mysql_is_over(mysql_client *client) +{ + swString *buffer = MYSQL_RESPONSE_BUFFER; + char *p; + if (client->check_offset == buffer->length) + { + // have already check all of the data + goto again; + } + size_t n_buf = buffer->length - client->check_offset; // remaining buffer size + uint32_t temp; + + while (1) + { + p = buffer->str + client->check_offset; // where to start checking now + if (unlikely(buffer->length - buffer->offset < 5)) + { + break; + } + temp = mysql_uint3korr(p); //package length + // add header + p += 4; + n_buf -= 4; + if (unlikely(n_buf < temp)) //package is incomplete + { + break; + } + else + { + client->check_offset += 4; + } + + client->check_offset += temp; // add package length + + if (client->check_offset >= buffer->length) // if false: more packages exist, skip the current one + { + switch ((uint8_t) p[0]) + { + case 0xfe: // eof + { + // +type +warning + p += 3; + swDebug("meet eof and flag=%d", mysql_uint2korr(p)); + goto check_flag; + } + case 0x00: // ok + { + +// if (temp < 7) +// { +// break; +// } + ulong_t val = 0; + char nul; + int retcode; + int t_nbuf = n_buf; + + //+type + p++; + t_nbuf--; + + retcode = mysql_lcb_ll(p, &val, &nul, t_nbuf); //affecr rows + t_nbuf -= retcode; + p += retcode; + + retcode = mysql_lcb_ll(p, &val, &nul, t_nbuf); //insert id + t_nbuf -= retcode; + p += retcode; + + check_flag: + if ((mysql_uint2korr(p) & SW_MYSQL_SERVER_MORE_RESULTS_EXISTS) == 0) + { + over: + client->response.wait_recv = 0; + client->check_offset = 0; + return SW_OK; + } + break; + } + case 0xff: // response type = error + { + goto over; + } + } + } + + n_buf -= temp; + if (n_buf == 0) + { + break; + } + } + + again: + client->response.wait_recv = 2; + return SW_AGAIN; +} + + +int mysql_response(mysql_client *client) +{ + swString *buffer = MYSQL_RESPONSE_BUFFER; + + char *p = buffer->str + buffer->offset; + int ret; + char nul; + size_t n_buf = buffer->length - buffer->offset; + + while (n_buf > 0) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "client->state=%d, n_buf=%d.", client->state, n_buf); + + switch (client->state) + { + case SW_MYSQL_STATE_READ_START: + if (buffer->length - buffer->offset < 5) + { + client->response.wait_recv = 1; + return SW_ERR; + } + client->response.packet_length = mysql_uint3korr(p); + client->response.packet_number = p[3]; + p += 4; + n_buf -= 4; + + if (n_buf < client->response.packet_length) + { + client->response.wait_recv = 1; + return SW_ERR; + } + + client->response.response_type = p[0]; + p ++; + n_buf --; + + /* error */ + if (client->response.response_type == 0xff) + { + client->response.error_code = mysql_uint2korr(p); + /* status flag 1byte (#), skip.. */ + memcpy(client->response.status_msg, p + 3, 5); + client->response.server_msg = p + 8; + /** + * int<1> header [ff] header of the ERR packet + * int<2> error_code error-code + * if capabilities & CLIENT_PROTOCOL_41 { + * string[1] sql_state_marker # marker of the SQL State + * string[5] sql_state SQL State + * } + */ + client->response.l_server_msg = client->response.packet_length - 9; + client->state = SW_MYSQL_STATE_READ_END; + return SW_OK; + } + /* eof */ + else if (client->response.response_type == 0xfe) + { + client->response.warnings = mysql_uint2korr(p); + client->response.status_code = mysql_uint2korr(p + 2); + client->state = SW_MYSQL_STATE_READ_END; + return SW_OK; + } + /* ok */ + else if (client->response.response_type == 0) + { + if (client->cmd == SW_MYSQL_COM_STMT_PREPARE) + { + ret = mysql_parse_prepare_result(client, p, n_buf); + if (ret < 0) + { + return SW_ERR; + } + else + { + p += ret; + n_buf -= ret; + buffer->offset += (5 + ret); + client->response.num_column = client->statement->field_count; + client->response.columns = ecalloc(client->response.num_column, sizeof(mysql_field)); + if (client->statement->param_count > 0) + { + client->state = SW_MYSQL_STATE_READ_PARAM; + } + else + { + client->state = SW_MYSQL_STATE_READ_FIELD; + } + break; + } + } + /* affected rows */ + ret = mysql_length_coded_binary(p, &client->response.affected_rows, &nul, n_buf); + n_buf -= ret; + p += ret; + + /* insert id */ + ret = mysql_length_coded_binary(p, &client->response.insert_id, &nul, n_buf); + n_buf -= ret; + p += ret; + + /* server status */ + client->response.status_code = mysql_uint2korr(p); + n_buf -= 2; + p += 2; + + /* server warnings */ + client->response.warnings = mysql_uint2korr(p); + + client->state = SW_MYSQL_STATE_READ_END; + return SW_OK; + } + /* result set */ + else + { + //Protocol::LengthEncodedInteger + ret = mysql_length_coded_binary(p - 1, &client->response.num_column, &nul, n_buf + 1); + if (ret < 0) + { + return SW_ERR; + } + buffer->offset += (4 + ret); + client->response.columns = ecalloc(client->response.num_column, sizeof(mysql_field)); + client->state = SW_MYSQL_STATE_READ_FIELD; + break; + } + + case SW_MYSQL_STATE_READ_FIELD: + if (mysql_read_columns(client) < 0) + { + return SW_ERR; + } + else + { + if (client->cmd == SW_MYSQL_COM_STMT_PREPARE) + { + mysql_columns_free(client); + return SW_OK; + } + client->state = SW_MYSQL_STATE_READ_ROW; + break; + } + + case SW_MYSQL_STATE_READ_ROW: + if (mysql_read_rows(client) < 0) + { + return SW_ERR; + } + else + { + client->state = SW_MYSQL_STATE_READ_END; + return SW_OK; + } + + case SW_MYSQL_STATE_READ_PARAM: + if (mysql_read_params(client) < 0) + { + return SW_ERR; + } + else if (client->statement->field_count > 0) + { + client->state = SW_MYSQL_STATE_READ_FIELD; + continue; + } + else + { + mysql_columns_free(client); + return SW_OK; + } + + default: + return SW_ERR; + } + } + + return SW_OK; +} + +int mysql_query(zval *zobject, mysql_client *client, swString *sql, zval *callback TSRMLS_DC) +{ + if (!client->cli) + { + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION; + swoole_php_fatal_error(E_WARNING, "mysql connection#%d is closed.", client->fd); + return SW_ERR; + } + if (!client->connected) + { + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION; + swoole_php_error(E_WARNING, "mysql client is not connected to server."); + return SW_ERR; + } + if (client->state != SW_MYSQL_STATE_QUERY) + { + swoole_php_fatal_error(E_WARNING, "mysql client is waiting response, cannot send new sql query."); + return SW_ERR; + } + + if (callback != NULL) + { + sw_zval_add_ref(&callback); + client->callback = sw_zval_dup(callback); + } + + client->cmd = SW_MYSQL_COM_QUERY; + + swString_clear(mysql_request_buffer); + + if (mysql_request(sql, mysql_request_buffer) < 0) + { + return SW_ERR; + } + //send query + if (SwooleG.main_reactor->write(SwooleG.main_reactor, client->fd, mysql_request_buffer->str, mysql_request_buffer->length) < 0) + { + //connection is closed + if (swConnection_error(errno) == SW_CLOSE) + { + zend_update_property_bool(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("errno"), 2013 TSRMLS_CC); + zend_update_property_string(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("error"), "Lost connection to MySQL server during query" TSRMLS_CC); + } + return SW_ERR; + } + else + { + client->state = SW_MYSQL_STATE_READ_START; + return SW_OK; + } +} + +#ifdef SW_MYSQL_DEBUG + +void mysql_client_info(mysql_client *client) +{ + printf("\n"SW_START_LINE"\nmysql_client\nbuffer->offset=%ld\nbuffer->length=%ld\nstatus=%d\n" + "packet_length=%d\npacket_number=%d\n" + "insert_id=%d\naffected_rows=%d\n" + "warnings=%d\n"SW_END_LINE, client->buffer->offset, client->buffer->length, client->response.status_code, + client->response.packet_length, client->response.packet_number, + client->response.insert_id, client->response.affected_rows, + client->response.warnings); + int i; + + if (client->response.num_column) + { + for (i = 0; i < client->response.num_column; i++) + { + mysql_column_info(&client->response.columns[i]); + } + } +} + +void mysql_column_info(mysql_field *field) +{ + printf("\n"SW_START_LINE"\nname=%s, table=%s, db=%s\n" + "name_length=%d, table_length=%d, db_length=%d\n" + "catalog=%s, default_value=%s\n" + "length=%ld, type=%d\n"SW_END_LINE, + field->name, field->table, field->db, + field->name_length, field->table_length, field->db_length, + field->catalog, field->def, + field->length, field->type + ); +} + +#endif + +static PHP_METHOD(swoole_mysql, __construct) +{ + if (!mysql_request_buffer) + { + mysql_request_buffer = swString_new(SW_MYSQL_QUERY_INIT_SIZE); + if (!mysql_request_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } + } + + mysql_client *client = emalloc(sizeof(mysql_client)); + bzero(client, sizeof(mysql_client)); + swoole_set_object(getThis(), client); +} + +static PHP_METHOD(swoole_mysql, connect) +{ + zval *server_info; + zval *callback; + char buf[2048]; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az", &server_info, &callback) == FAILURE) + { + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (client->cli) + { + swoole_php_error(E_WARNING, "The mysql client is already connected server."); + RETURN_FALSE; + } + + php_swoole_array_separate(server_info); + + HashTable *_ht = Z_ARRVAL_P(server_info); + zval *value; + + mysql_connector *connector = &client->connector; + + if (php_swoole_array_get_value(_ht, "host", value)) + { + convert_to_string(value); + connector->host = Z_STRVAL_P(value); + connector->host_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "HOST parameter is required.", 11 TSRMLS_CC); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "port", value)) + { + convert_to_long(value); + connector->port = Z_LVAL_P(value); + } + else + { + connector->port = SW_MYSQL_DEFAULT_PORT; + } + if (php_swoole_array_get_value(_ht, "user", value)) + { + convert_to_string(value); + connector->user = Z_STRVAL_P(value); + connector->user_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "USER parameter is required.", 11 TSRMLS_CC); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "password", value)) + { + convert_to_string(value); + connector->password = Z_STRVAL_P(value); + connector->password_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "PASSWORD parameter is required.", 11 TSRMLS_CC); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "database", value)) + { + convert_to_string(value); + connector->database = Z_STRVAL_P(value); + connector->database_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "DATABASE parameter is required.", 11 TSRMLS_CC); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "timeout", value)) + { + convert_to_double(value); + connector->timeout = Z_DVAL_P(value); + } + else + { + connector->timeout = SW_MYSQL_CONNECT_TIMEOUT; + } + if (php_swoole_array_get_value(_ht, "charset", value)) + { + convert_to_string(value); + connector->character_set = mysql_get_charset(Z_STRVAL_P(value)); + if (connector->character_set < 0) + { + snprintf(buf, sizeof(buf), "unknown charset [%s].", Z_STRVAL_P(value)); + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, buf, 11 TSRMLS_CC); + RETURN_FALSE; + } + } + //use the server default charset. + else + { + connector->character_set = 0; + } + + if (php_swoole_array_get_value(_ht, "strict_type", value)) + { +#if PHP_MAJOR_VERSION < 7 + if (Z_TYPE_P(value) == IS_BOOL && Z_BVAL_P(value) == 1) +#else + if (Z_TYPE_P(value) == IS_TRUE) +#endif + { + connector->strict_type = 1; + } + else + { + connector->strict_type = 0; + } + } + else + { + connector->strict_type = 0; + } + + if (php_swoole_array_get_value(_ht, "fetch_mode", value)) + { +#if PHP_MAJOR_VERSION < 7 + if(Z_TYPE_P(value) == IS_BOOL && Z_BVAL_P(value) == 1) +#else + if (Z_TYPE_P(value) == IS_TRUE) +#endif + { + connector->fetch_mode = 1; + } + else + { + connector->fetch_mode = 0; + } + } + else + { + connector->fetch_mode = 0; + } + + swClient *cli = emalloc(sizeof(swClient)); + int type = SW_SOCK_TCP; + + if (strncasecmp(connector->host, ZEND_STRL("unix:/")) == 0) + { + connector->host = connector->host + 5; + connector->host_len = connector->host_len - 5; + type = SW_SOCK_UNIX_STREAM; + } + else if (strchr(connector->host, ':')) + { + type = SW_SOCK_TCP6; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL | SW_EVENT_READ, swoole_mysql_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL | SW_EVENT_WRITE, swoole_mysql_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL | SW_EVENT_ERROR, swoole_mysql_onError); + } + //create socket + if (swClient_create(cli, type, 0) < 0) + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "swClient_create failed.", 1 TSRMLS_CC); + RETURN_FALSE; + } + //tcp nodelay + if (type != SW_SOCK_UNIX_STREAM) + { + int tcp_nodelay = 1; + if (setsockopt(cli->socket->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + swoole_php_sys_error(E_WARNING, "setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) failed.", cli->socket->fd); + } + } + //connect to mysql server + int ret = cli->connect(cli, connector->host, connector->port, connector->timeout, 1); + if ((ret < 0 && errno == EINPROGRESS) || ret == 0) + { + if (connector->timeout > 0) + { + php_swoole_check_timer((int) (connector->timeout * 1000)); + cli->timer = SwooleG.timer.add(&SwooleG.timer, (int) (connector->timeout * 1000), 0, client, swoole_mysql_onTimeout); + cli->timeout = connector->timeout; + } + if (SwooleG.main_reactor->add(SwooleG.main_reactor, cli->socket->fd, PHP_SWOOLE_FD_MYSQL | SW_EVENT_WRITE) < 0) + { + RETURN_FALSE; + } + } + else + { + snprintf(buf, sizeof(buf), "connect to mysql server[%s:%d] failed.", connector->host, connector->port); + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, buf, 2 TSRMLS_CC); + RETURN_FALSE; + } + + zend_update_property(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), callback TSRMLS_CC); + zend_update_property(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("serverInfo"), server_info TSRMLS_CC); + zend_update_property_long(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("sock"), cli->socket->fd TSRMLS_CC); + + client->buffer = swString_new(SW_BUFFER_SIZE_BIG); + client->fd = cli->socket->fd; + client->object = getThis(); + client->cli = cli; + sw_copy_to_stack(client->object, client->_object); + sw_zval_add_ref(&client->object); + sw_zval_ptr_dtor(&server_info); + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, cli->socket->fd); + _socket->object = client; + _socket->active = 0; + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_mysql, query) +{ + zval *callback; + swString sql; + bzero(&sql, sizeof(sql)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &sql.str, &sql.length, &callback) == FAILURE) + { + return; + } + + if (!php_swoole_is_callable(callback TSRMLS_CC)) + { + RETURN_FALSE; + } + + if (sql.length <= 0) + { + swoole_php_fatal_error(E_WARNING, "Query is empty."); + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + + SW_CHECK_RETURN(mysql_query(getThis(), client, &sql, callback TSRMLS_CC)); +} + +static PHP_METHOD(swoole_mysql, begin) +{ + zval *callback; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &callback) == FAILURE) + { + return; + } + + if (!php_swoole_is_callable(callback TSRMLS_CC)) + { + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (client->transaction) + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "There is already an active transaction.", 21 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("START TRANSACTION")); + if (mysql_query(getThis(), client, &sql, callback TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 1; + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_mysql, commit) +{ + zval *callback; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &callback) == FAILURE) + { + return; + } + + if (!php_swoole_is_callable(callback TSRMLS_CC)) + { + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (!client->transaction) + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "There is no active transaction.", 22 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("COMMIT")); + if (mysql_query(getThis(), client, &sql, callback TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 0; + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_mysql, rollback) +{ + zval *callback; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &callback) == FAILURE) + { + return; + } + + if (!php_swoole_is_callable(callback TSRMLS_CC)) + { + RETURN_FALSE; + } + + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (!client->transaction) + { + zend_throw_exception(swoole_mysql_exception_class_entry_ptr, "There is no active transaction.", 22 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("ROLLBACK")); + if (mysql_query(getThis(), client, &sql, callback TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 0; + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_mysql, __destruct) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + return; + } + if (client->state != SW_MYSQL_STATE_CLOSED && client->cli) + { + zval *retval = NULL; + zval *zobject = getThis(); + client->cli->destroyed = 1; + sw_zend_call_method_with_0_params(&zobject, swoole_mysql_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + //release buffer memory + if (client->buffer) + { + swString_free(client->buffer); + } + efree(client); + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_mysql, close) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + + if (!client->cli) + { + RETURN_FALSE; + } + + if (client->cli->socket->closing) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSING, "The mysql connection[%d] is closing.", client->fd); + RETURN_FALSE; + } + + zend_update_property_bool(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("connected"), 0 TSRMLS_CC); + SwooleG.main_reactor->del(SwooleG.main_reactor, client->fd); + + swConnection *socket = swReactor_get(SwooleG.main_reactor, client->fd); + bzero(socket, sizeof(swConnection)); + socket->removed = 1; + + zend_bool is_destroyed = client->cli->destroyed; + + zval *retval = NULL; + zval **args[1]; + zval *object = getThis(); + if (client->onClose) + { + client->cli->socket->closing = 1; + args[0] = &object; + if (sw_call_user_function_ex(EG(function_table), NULL, client->onClose, &retval, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_mysql onClose callback error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + mysql_client_free(client, getThis()); + if (!is_destroyed) + { + sw_zval_ptr_dtor(&object); + } +} + +static PHP_METHOD(swoole_mysql, on) +{ + char *name; + zend_size_t len; + zval *cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &cb) == FAILURE) + { + return; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + + if (strncasecmp("close", name, len) == 0) + { + zend_update_property(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("onClose"), cb TSRMLS_CC); + client->onClose = sw_zend_read_property(swoole_mysql_class_entry_ptr, getThis(), ZEND_STRL("onClose"), 0 TSRMLS_CC); + sw_copy_to_stack(client->onClose, client->_onClose); + } + else + { + swoole_php_error(E_WARNING, "Unknown event type[%s]", name); + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_mysql, getState) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + RETURN_LONG(client->state); +} + +static void swoole_mysql_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + mysql_client *client = tnode->data; + client->connector.error_code = ETIMEDOUT; + client->connector.error_msg = strerror(client->connector.error_code); + client->connector.error_length = strlen(client->connector.error_msg); + swoole_mysql_onConnect(client TSRMLS_CC); +} + +static int swoole_mysql_onError(swReactor *reactor, swEvent *event) +{ + swClient *cli = event->socket->object; + if (cli && cli->socket && cli->socket->active) + { +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + mysql_client *client = event->socket->object; + if (!client) + { + close(event->fd); + return SW_ERR; + } + zval *retval = NULL; + zval *zobject = client->object; + sw_zend_call_method_with_0_params(&zobject, swoole_mysql_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; + } + else + { + return swoole_mysql_onWrite(reactor, event); + } +} + +static void swoole_mysql_onConnect(mysql_client *client TSRMLS_DC) +{ + zval *zobject = client->object; + zval *callback = sw_zend_read_property(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("onConnect"), 0 TSRMLS_CC); + + zval *retval = NULL; + zval *result; + zval **args[2]; + + SW_MAKE_STD_ZVAL(result); + + if (client->cli->timer) + { + swTimer_del(&SwooleG.timer, client->cli->timer); + client->cli->timer = NULL; + } + + if (client->connector.error_code > 0) + { + zend_update_property_stringl(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("connect_error"), client->connector.error_msg, client->connector.error_length TSRMLS_CC); + zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("connect_errno"), client->connector.error_code TSRMLS_CC); + ZVAL_BOOL(result, 0); + } + else + { + zend_update_property_bool(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("connected"), 1 TSRMLS_CC); + ZVAL_BOOL(result, 1); + client->connected = 1; + } + + args[0] = &zobject; + args[1] = &result; + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_mysql onConnect handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + if (client->connector.error_code > 0) + { + retval = NULL; + //close + sw_zend_call_method_with_0_params(&zobject, swoole_mysql_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } +} + +static int swoole_mysql_onWrite(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + if (event->socket->active) + { + return swReactor_onWrite(SwooleG.main_reactor, event); + } + + socklen_t len = sizeof(SwooleG.error); + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &SwooleG.error, &len) < 0) + { + swWarn("getsockopt(%d) failed. Error: %s[%d]", event->fd, strerror(errno), errno); + return SW_ERR; + } + + mysql_client *client = event->socket->object; + //success + if (SwooleG.error == 0) + { + //listen read event + SwooleG.main_reactor->set(SwooleG.main_reactor, event->fd, PHP_SWOOLE_FD_MYSQL | SW_EVENT_READ); + //connected + event->socket->active = 1; + client->handshake = SW_MYSQL_HANDSHAKE_WAIT_REQUEST; + } + else + { + client->connector.error_code = SwooleG.error; + client->connector.error_msg = strerror(SwooleG.error); + client->connector.error_length = strlen(client->connector.error_msg); + swoole_mysql_onConnect(client TSRMLS_CC); + } + return SW_OK; +} + +static int swoole_mysql_onHandShake(mysql_client *client TSRMLS_DC) +{ + swString *buffer = client->buffer; + swClient *cli = client->cli; + mysql_connector *connector = &client->connector; + + int n = cli->recv(cli, buffer->str + buffer->length, buffer->size - buffer->length, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("Read from socket[%d] failed.", cli->socket->fd); + return SW_ERR; + case SW_CLOSE: + goto system_call_error; + case SW_WAIT: + return SW_OK; + default: + return SW_ERR; + } + } + else if (n == 0) + { + errno = ECONNRESET; + goto system_call_error; + } + + buffer->length += n; + + int ret = 0; + + _again: + swTraceLog(SW_TRACE_MYSQL_CLIENT, "handshake on %d", client->handshake); + if (client->switch_check) + { + // after handshake we need check if server request us to switch auth type first + goto _check_switch; + } + + switch(client->handshake) + { + case SW_MYSQL_HANDSHAKE_WAIT_REQUEST: + { + client->switch_check = 1; + ret = mysql_handshake(connector, buffer->str, buffer->length); + + if (ret < 0) + { + goto _error; + } + else if (ret > 0) + { + _send: + if (cli->send(cli, connector->buf, connector->packet_length + 4, 0) < 0) + { + system_call_error: connector->error_code = errno; + connector->error_msg = strerror(errno); + connector->error_length = strlen(connector->error_msg); + swoole_mysql_onConnect(client TSRMLS_CC); + return SW_OK; + } + else + { + // clear for the new package + swString_clear(buffer); + // mysql_handshake will return the next state flag + client->handshake = ret; + } + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_SWITCH: + { + _check_switch: + client->switch_check = 0; + int next_state; + // handle auth switch request + switch (next_state = mysql_auth_switch(connector, buffer->str, buffer->length)) + { + case SW_AGAIN: + return SW_OK; + case SW_ERR: + // not the switch package, go to the next + goto _again; + default: + ret = next_state; + goto _send; + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_SIGNATURE: + { + switch (mysql_parse_auth_signature(buffer, connector)) + { + case SW_MYSQL_AUTH_SIGNATURE_SUCCESS: + { + client->handshake = SW_MYSQL_HANDSHAKE_WAIT_RESULT; + break; + } + case SW_MYSQL_AUTH_SIGNATURE_FULL_AUTH_REQUIRED: + { + // send response and wait RSA public key + ret = SW_MYSQL_HANDSHAKE_WAIT_RSA; // handshake = ret + goto _send; + } + default: + { + goto _error; + } + } + + // may be more packages + if (buffer->offset < buffer->length) + { + goto _again; + } + else + { + swString_clear(buffer); + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_RSA: + { + // encode by RSA +#ifdef SW_MYSQL_RSA_SUPPORT + switch (mysql_parse_rsa(connector, SWSTRING_CURRENT_VL(buffer))) + { + case SW_AGAIN: + return SW_OK; + case SW_OK: + ret = SW_MYSQL_HANDSHAKE_WAIT_RESULT; // handshake = ret + goto _send; + default: + goto _error; + } +#else + connector->error_code = -1; + connector->error_msg = "MySQL8 RSA-Auth need enable OpenSSL!"; + connector->error_length = strlen(connector->error_msg); + swoole_mysql_onConnect(client TSRMLS_CC); + return SW_OK; +#endif + break; + } + default: + { + ret = mysql_get_result(connector, SWSTRING_CURRENT_VL(buffer)); + if (ret < 0) + { + _error: + swoole_mysql_onConnect(client TSRMLS_CC); + } + else if (ret > 0) + { + swString_clear(buffer); + client->handshake = SW_MYSQL_HANDSHAKE_COMPLETED; + swoole_mysql_onConnect(client TSRMLS_CC); + } + // else recv again + } + } + + return SW_OK; +} + +static int swoole_mysql_onRead(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + mysql_client *client = event->socket->object; + if (client->handshake != SW_MYSQL_HANDSHAKE_COMPLETED) + { + return swoole_mysql_onHandShake(client TSRMLS_CC); + } + + int sock = event->fd; + int ret; + + zval *zobject = client->object; + swString *buffer = client->buffer; + + zval **args[2]; + zval *callback = NULL; + zval *retval = NULL; + zval *result = NULL; + + while(1) + { + ret = recv(sock, buffer->str + buffer->length, buffer->size - buffer->length, 0); + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("Read from socket[%d] failed.", event->fd); + return SW_ERR; + case SW_CLOSE: + goto close_fd; + case SW_WAIT: + goto parse_response; + default: + return SW_ERR; + } + } + } + else if (ret == 0) + { + close_fd: + if (client->state == SW_MYSQL_STATE_READ_END) + { + goto parse_response; + } + sw_zend_call_method_with_0_params(&zobject, swoole_mysql_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; + } + else + { + buffer->length += ret; + //recv again + if (buffer->length == buffer->size) + { + if (swString_extend(buffer, buffer->size * 2) < 0) + { + swoole_php_fatal_error(E_ERROR, "malloc failed."); + reactor->del(SwooleG.main_reactor, event->fd); + } + continue; + } + + parse_response: + if (mysql_response(client) < 0) + { + return SW_OK; + } + + zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("affected_rows"), client->response.affected_rows TSRMLS_CC); + zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("insert_id"), client->response.insert_id TSRMLS_CC); + client->state = SW_MYSQL_STATE_QUERY; + + args[0] = &zobject; + + //OK + if (client->response.response_type == 0) + { + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 1); + } + //ERROR + else if (client->response.response_type == 255) + { + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 0); + + zend_update_property_stringl(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("error"), client->response.server_msg, client->response.l_server_msg TSRMLS_CC); + zend_update_property_long(swoole_mysql_class_entry_ptr, zobject, ZEND_STRL("errno"), client->response.error_code TSRMLS_CC); + } + //ResultSet + else + { + result = client->response.result_array; + } + + args[1] = &result; + callback = client->callback; + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_async_mysql callback[2] handler error."); + reactor->del(SwooleG.main_reactor, event->fd); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + /* free memory */ + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + if (result) + { + sw_zval_free(result); + } + //free callback object + sw_zval_free(callback); + swConnection *_socket = swReactor_get(SwooleG.main_reactor, event->fd); + if (_socket->object) + { + //clear buffer + swString_clear(client->buffer); + bzero(&client->response, sizeof(client->response)); + } + return SW_OK; + } + } + return SW_OK; +} + +#ifdef SW_USE_MYSQLND +static PHP_METHOD(swoole_mysql, escape) +{ + swString str; + bzero(&str, sizeof(str)); + long flags; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str.str, &str.length, &flags) == FAILURE) + { + return; + } + + if (str.length <= 0) + { + swoole_php_fatal_error(E_WARNING, "String is empty."); + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (!client->cli) + { + swoole_php_fatal_error(E_WARNING, "mysql connection#%d is closed.", client->fd); + RETURN_FALSE; + } + + char *newstr = safe_emalloc(2, str.length + 1, 1); + if (newstr == NULL) + { + swoole_php_fatal_error(E_ERROR, "emalloc(%ld) failed.", str.length + 1); + RETURN_FALSE; + } + + const MYSQLND_CHARSET* cset = mysqlnd_find_charset_nr(client->connector.character_set); + if (cset == NULL) + { + swoole_php_fatal_error(E_ERROR, "unknown mysql charset[%s].", client->connector.character_set); + RETURN_FALSE; + } + int newstr_len = mysqlnd_cset_escape_slashes(cset, newstr, str.str, str.length TSRMLS_CC); + if (newstr_len < 0) + { + swoole_php_fatal_error(E_ERROR, "mysqlnd_cset_escape_slashes() failed."); + RETURN_FALSE; + } + SW_RETURN_STRINGL(newstr, newstr_len, 0); +} +#endif diff --git a/vendor/swoole/swoole_mysql.h b/vendor/swoole/swoole_mysql.h new file mode 100755 index 0000000..132f2c1 --- /dev/null +++ b/vendor/swoole/swoole_mysql.h @@ -0,0 +1,548 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SWOOLE_MYSQL_H_ +#define SWOOLE_MYSQL_H_ + +#ifdef SW_USE_OPENSSL +#ifndef OPENSSL_NO_RSA +#define SW_MYSQL_RSA_SUPPORT +#endif +#endif + +//#define SW_MYSQL_DEBUG + +enum mysql_command +{ + SW_MYSQL_COM_NULL = -1, + SW_MYSQL_COM_SLEEP = 0, + SW_MYSQL_COM_QUIT, + SW_MYSQL_COM_INIT_DB, + SW_MYSQL_COM_QUERY = 3, + SW_MYSQL_COM_FIELD_LIST, + SW_MYSQL_COM_CREATE_DB, + SW_MYSQL_COM_DROP_DB, + SW_MYSQL_COM_REFRESH, + SW_MYSQL_COM_SHUTDOWN, + SW_MYSQL_COM_STATISTICS, + SW_MYSQL_COM_PROCESS_INFO, + SW_MYSQL_COM_CONNECT, + SW_MYSQL_COM_PROCESS_KILL, + SW_MYSQL_COM_DEBUG, + SW_MYSQL_COM_PING, + SW_MYSQL_COM_TIME, + SW_MYSQL_COM_DELAYED_INSERT, + SW_MYSQL_COM_CHANGE_USER, + SW_MYSQL_COM_BINLOG_DUMP, + SW_MYSQL_COM_TABLE_DUMP, + SW_MYSQL_COM_CONNECT_OUT, + SW_MYSQL_COM_REGISTER_SLAVE, + SW_MYSQL_COM_STMT_PREPARE, + SW_MYSQL_COM_STMT_EXECUTE, + SW_MYSQL_COM_STMT_SEND_LONG_DATA, + SW_MYSQL_COM_STMT_CLOSE, + SW_MYSQL_COM_STMT_RESET, + SW_MYSQL_COM_SET_OPTION, + SW_MYSQL_COM_STMT_FETCH, + SW_MYSQL_COM_DAEMON, + SW_MYSQL_COM_END +}; + +enum mysql_handshake_state +{ + SW_MYSQL_HANDSHAKE_WAIT_REQUEST, + SW_MYSQL_HANDSHAKE_WAIT_SWITCH, + SW_MYSQL_HANDSHAKE_WAIT_SIGNATURE, + SW_MYSQL_HANDSHAKE_WAIT_RSA, + SW_MYSQL_HANDSHAKE_WAIT_RESULT, + SW_MYSQL_HANDSHAKE_COMPLETED, +}; + +enum mysql_auth_signature +{ + SW_MYSQL_AUTH_SIGNATURE_ERROR = 0x00, // get signature failed + SW_MYSQL_AUTH_SIGNATURE = 0x01, + SW_MYSQL_AUTH_SIGNATURE_RSA_PREPARED = 0x02, + SW_MYSQL_AUTH_SIGNATURE_SUCCESS = 0x03, + SW_MYSQL_AUTH_SIGNATURE_FULL_AUTH_REQUIRED = 0x04, //rsa required +}; + +// nonce: a number or bit string used only once, in security engineering +// other names on doc: challenge/scramble/salt +#define SW_MYSQL_NONCE_LENGTH 20 + +enum mysql_read_state +{ + SW_MYSQL_STATE_QUERY, + SW_MYSQL_STATE_READ_START, + SW_MYSQL_STATE_READ_FIELD, + SW_MYSQL_STATE_READ_ROW, + SW_MYSQL_STATE_READ_PARAM, + SW_MYSQL_STATE_READ_END, + SW_MYSQL_STATE_CLOSED, +}; + +enum mysql_error_code +{ + SW_MYSQL_ERR_PROTOCOL_ERROR = 1, + SW_MYSQL_ERR_BUFFER_OVERSIZE, + SW_MYSQL_ERR_PACKET_CORRUPT, + SW_MYSQL_ERR_WANT_READ, + SW_MYSQL_ERR_WANT_WRITE, + SW_MYSQL_ERR_UNKNOWN_ERROR, + SW_MYSQL_ERR_MYSQL_ERROR, + SW_MYSQL_ERR_SERVER_LOST, + SW_MYSQL_ERR_BAD_PORT, + SW_MYSQL_ERR_RESOLV_HOST, + SW_MYSQL_ERR_SYSTEM, + SW_MYSQL_ERR_CANT_CONNECT, + SW_MYSQL_ERR_BUFFER_TOO_SMALL, + SW_MYSQL_ERR_UNEXPECT_R_STATE, + SW_MYSQL_ERR_STRFIELD_CORRUPT, + SW_MYSQL_ERR_BINFIELD_CORRUPT, + SW_MYSQL_ERR_BAD_LCB, + SW_MYSQL_ERR_LEN_OVER_BUFFER, + SW_MYSQL_ERR_CONVLONG, + SW_MYSQL_ERR_CONVLONGLONG, + SW_MYSQL_ERR_CONVFLOAT, + SW_MYSQL_ERR_CONVDOUBLE, + SW_MYSQL_ERR_CONVTIME, + SW_MYSQL_ERR_CONVTIMESTAMP, + SW_MYSQL_ERR_CONVDATE +}; + +enum mysql_field_types +{ + SW_MYSQL_TYPE_DECIMAL, + SW_MYSQL_TYPE_TINY, + SW_MYSQL_TYPE_SHORT, + SW_MYSQL_TYPE_LONG, + SW_MYSQL_TYPE_FLOAT, + SW_MYSQL_TYPE_DOUBLE, + SW_MYSQL_TYPE_NULL, + SW_MYSQL_TYPE_TIMESTAMP, + SW_MYSQL_TYPE_LONGLONG, + SW_MYSQL_TYPE_INT24, + SW_MYSQL_TYPE_DATE, + SW_MYSQL_TYPE_TIME, + SW_MYSQL_TYPE_DATETIME, + SW_MYSQL_TYPE_YEAR, + SW_MYSQL_TYPE_NEWDATE, + SW_MYSQL_TYPE_VARCHAR, + SW_MYSQL_TYPE_BIT, + SW_MYSQL_TYPE_JSON = 245, + SW_MYSQL_TYPE_NEWDECIMAL = 246, + SW_MYSQL_TYPE_ENUM = 247, + SW_MYSQL_TYPE_SET = 248, + SW_MYSQL_TYPE_TINY_BLOB = 249, + SW_MYSQL_TYPE_MEDIUM_BLOB = 250, + SW_MYSQL_TYPE_LONG_BLOB = 251, + SW_MYSQL_TYPE_BLOB = 252, + SW_MYSQL_TYPE_VAR_STRING = 253, + SW_MYSQL_TYPE_STRING = 254, + SW_MYSQL_TYPE_GEOMETRY = 255 +}; + +#ifdef SW_COROUTINE +typedef enum +{ + SW_MYSQL_CORO_STATUS_CLOSED, + SW_MYSQL_CORO_STATUS_READY, + SW_MYSQL_CORO_STATUS_WAIT, + SW_MYSQL_CORO_STATUS_DONE +} mysql_io_status; +#endif + +// ref: https://dev.mysql.com/doc/dev/mysql-server/8.0.0/group__group__cs__capabilities__flags.html +// use regex: "\#define[ ]+(CLIENT_[A-Z_\d]+)[ ]+(\(?[\dA-Z <]+\)?)\n[ ]+?[ ]+([\s\S ]+?\.) More\.\.\.\n?" +// to "SW_MYSQL_$1 = $2, /* $3 */" +enum mysql_client_capability_flags +{ + SW_MYSQL_CLIENT_LONG_PASSWORD = 1, /* Use the improved version of Old Password Authentication. */ + SW_MYSQL_CLIENT_FOUND_ROWS = 2, /* Send found rows instead of affected rows in EOF_Packet. */ + SW_MYSQL_CLIENT_LONG_FLAG = 4, /* Get all column flags. */ + SW_MYSQL_CLIENT_CONNECT_WITH_DB = 8, /* Database (schema) name can be specified on connect in Handshake Response Packet. */ + SW_MYSQL_CLIENT_NO_SCHEMA = 16, /* Don't allow database.table.column. */ + SW_MYSQL_CLIENT_COMPRESS = 32, /* Compression protocol supported. */ + SW_MYSQL_CLIENT_ODBC = 64, /* Special handling of ODBC behavior. */ + SW_MYSQL_CLIENT_LOCAL_FILES = 128, /* Can use LOAD DATA LOCAL. */ + SW_MYSQL_CLIENT_IGNORE_SPACE = 256, /* Ignore spaces before '('. */ + SW_MYSQL_CLIENT_PROTOCOL_41 = 512, /* New 4.1 protocol. */ + SW_MYSQL_CLIENT_INTERACTIVE = 1024, /* This is an interactive client. */ + SW_MYSQL_CLIENT_SSL = 2048, /* Use SSL encryption for the session. */ + SW_MYSQL_CLIENT_IGNORE_SIGPIPE = 4096, /* Client only flag. */ + SW_MYSQL_CLIENT_TRANSACTIONS = 8192, /* Client knows about transactions. */ + SW_MYSQL_CLIENT_RESERVED = 16384, /* flag for 4.1 protocol. */ + SW_MYSQL_CLIENT_SECURE_CONNECTION = 32768, /* swoole custom name for RESERVED2. */ + SW_MYSQL_CLIENT_RESERVED2 = 32768, /* flag for 4.1 authentication. */ + SW_MYSQL_CLIENT_MULTI_STATEMENTS = (1UL << 16), /* Enable/disable multi-stmt support. */ + SW_MYSQL_CLIENT_MULTI_RESULTS = (1UL << 17), /* Enable/disable multi-results. */ + SW_MYSQL_CLIENT_PS_MULTI_RESULTS = (1UL << 18), /* Multi-results and OUT parameters in PS-protocol. */ + SW_MYSQL_CLIENT_PLUGIN_AUTH = (1UL << 19), /* Client supports plugin authentication. */ + SW_MYSQL_CLIENT_CONNECT_ATTRS = (1UL << 20), /* Client supports connection attributes. */ + SW_MYSQL_CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA = (1UL << 21), /* Enable authentication response packet to be larger than 255 bytes. */ + SW_MYSQL_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS = (1UL << 22), /* Don't close the connection for a user account with expired password. */ + SW_MYSQL_CLIENT_SESSION_TRACK = (1UL << 23), /* Capable of handling server state change information. */ + SW_MYSQL_CLIENT_DEPRECATE_EOF = (1UL << 24), /* Client no longer needs EOF_Packet and will use OK_Packet instead. */ + SW_MYSQL_CLIENT_SSL_VERIFY_SERVER_CERT = (1UL << 30), /* Verify server certificate. */ + SW_MYSQL_CLIENT_REMEMBER_OPTIONS = (1UL << 31) /* Don't reset the options after an unsuccessful connect. */ +}; + +// ref: https://dev.mysql.com/doc/internals/en/status-flags.html +enum mysql_server_status_flags +{ + SW_MYSQL_SERVER_STATUS_IN_TRANS = 0x0001, // a transaction is active + SW_MYSQL_SERVER_STATUS_AUTOCOMMIT = 0x0002, //auto-commit is enabled + SW_MYSQL_SERVER_MORE_RESULTS_EXISTS = 0x0008, + SW_MYSQL_SERVER_STATUS_NO_GOOD_INDEX_USED = 0x0010, + SW_MYSQL_SERVER_STATUS_NO_INDEX_USED = 0x0020, + SW_MYSQL_SERVER_STATUS_CURSOR_EXISTS = 0x0040, // Used by Binary Protocol Resultset to signal that COM_STMT_FETCH must be used to fetch the row-data. + SW_MYSQL_SERVER_STATUS_LAST_ROW_SENT = 0x0080, + SW_MYSQL_SERVER_STATUS_DB_DROPPED = 0x0100, + SW_MYSQL_SERVER_STATUS_NO_BACKSLASH_ESCAPES = 0x0200, + SW_MYSQL_SERVER_STATUS_METADATA_CHANGED = 0x0400, + SW_MYSQL_SERVER_QUERY_WAS_SLOW = 0x0800, + SW_MYSQL_SERVER_PS_OUT_PARAMS = 0x1000, + SW_MYSQL_SERVER_STATUS_IN_TRANS_READONLY = 0x2000, // in a read-only transaction + SW_MYSQL_SERVER_SESSION_STATE_CHANGED = 0x4000 // connection state information has changed +}; + +typedef struct +{ + int packet_length; + int packet_number; + uint8_t protocol_version; + char *server_version; + int connection_id; + char auth_plugin_data[SW_MYSQL_NONCE_LENGTH + 1]; // nonce + '\0' + uint8_t l_auth_plugin_data; + char filler; + int capability_flags; + char character_set; + int16_t status_flags; + char reserved[10]; + char *auth_plugin_name; + uint8_t l_auth_plugin_name; +} mysql_handshake_request; + +typedef struct +{ + char *host; + char *user; + char *password; + char *database; + zend_bool strict_type; + zend_bool fetch_mode; + + zend_size_t host_len; + zend_size_t user_len; + zend_size_t password_len; + zend_size_t database_len; + + long port; + double timeout; + swTimer_node *timer; + + int capability_flags; + int max_packet_size; + char character_set; + int packet_length; + char buf[512]; +#ifdef SW_USE_OPENSSL + char auth_plugin_data[SW_MYSQL_NONCE_LENGTH]; // save challenge data for RSA auth +#endif + + uint16_t error_code; + char *error_msg; + uint16_t error_length; +} mysql_connector; + +typedef struct +{ + char *buffer; + char *name; /* Name of column */ + char *org_name; /* Original column name, if an alias */ + char *table; /* Table of column if column was a field */ + char *org_table; /* Org table name, if table was an alias */ + char *db; /* Database for table */ + char *catalog; /* Catalog for table */ + char *def; /* Default value (set by mysql_list_fields) */ + ulong_t length; /* Width of column (create length) */ + ulong_t max_length; /* Max width for selected set */ + uint32_t name_length; + uint32_t org_name_length; + uint32_t table_length; + uint32_t org_table_length; + uint32_t db_length; + uint32_t catalog_length; + uint32_t def_length; + uint32_t flags; /* Div flags */ + uint32_t decimals; /* Number of decimals in field */ + uint32_t charsetnr; /* Character set */ + enum mysql_field_types type; /* Type of field. See mysql_com.h for types */ + void *extension; +} mysql_field; + +typedef union +{ + signed char stiny; + uchar utiny; + uchar mbool; + short ssmall; + unsigned short small; + int sint; + uint32_t uint; + long long sbigint; + unsigned long long ubigint; + float mfloat; + double mdouble; +} mysql_row; + +typedef struct +{ + uint32_t id; + uint16_t field_count; + uint16_t param_count; + uint16_t warning_count; + uint16_t unreaded_param_count; + struct _mysql_client *client; + zval *object; + swString *buffer; /* save the mysql multi responses data */ + zval *result; /* save the zval array result */ +} mysql_statement; + +typedef struct +{ + mysql_field *columns; + ulong_t num_column; + ulong_t index_column; + uint32_t num_row; + uint8_t wait_recv; + uint8_t response_type; + uint32_t packet_length :24; + uint32_t packet_number :8; + uint32_t error_code; + uint32_t warnings; + uint16_t status_code; + char status_msg[6]; + char *server_msg; + uint16_t l_server_msg; + ulong_t affected_rows; + ulong_t insert_id; + zval *result_array; +} mysql_response_t; + +typedef struct _mysql_client +{ +#ifdef SW_COROUTINE + zend_bool defer; + zend_bool suspending; + mysql_io_status iowait; + zval *result; + int cid; +#endif + uint8_t state; + uint32_t switch_check :1; /* check if server request auth switch */ + uint8_t handshake; + uint8_t cmd; /* help with judging to do what in callback */ + swString *buffer; /* save the mysql responses data */ + swClient *cli; + zval *object; + zval *callback; + zval *onClose; + int fd; + uint32_t transaction :1; + uint32_t connected :1; + + mysql_connector connector; + mysql_statement *statement; + swLinkedList *statement_list; + + swTimer_node *timer; + +#if PHP_MAJOR_VERSION >= 7 + zval _object; + zval _onClose; +#endif + + off_t check_offset; + mysql_response_t response; /* single response */ + +} mysql_client; + +#define mysql_uint2korr(A) (uint16_t) (((uint16_t) ((zend_uchar) (A)[0])) +\ + ((uint16_t) ((zend_uchar) (A)[1]) << 8)) +#define mysql_uint3korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\ + (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\ + (((uint32_t) ((zend_uchar) (A)[2])) << 16)) +#define mysql_uint4korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\ + (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\ + (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\ + (((uint32_t) ((zend_uchar) (A)[3])) << 24)) + +#define mysql_uint8korr(A) ((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\ + (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\ + (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\ + (((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\ + (((uint64_t) (((uint32_t) ((zend_uchar) (A)[4])) +\ + (((uint32_t) ((zend_uchar) (A)[5])) << 8) +\ + (((uint32_t) ((zend_uchar) (A)[6])) << 16) +\ + (((uint32_t) ((zend_uchar) (A)[7])) << 24))) << 32)) + +#define mysql_int1store(T,A) do { *((int8_t*) (T)) = (int8_t)(A); } while(0) +#define mysql_int2store(T,A) do { uint32_t def_temp= (uint32_t) (A) ;\ + *((zend_uchar*) (T)) = (zend_uchar)(def_temp); \ + *((zend_uchar*) (T+1)) = (zend_uchar)((def_temp >> 8)); } while (0) +#define mysql_int3store(T,A) do { /*lint -save -e734 */\ + *(((char *)(T))) = (char) ((A));\ + *(((char *)(T))+1) = (char) (((A) >> 8));\ + *(((char *)(T))+2) = (char) (((A) >> 16)); \ + /*lint -restore */} while (0) +#define mysql_int4store(T,A) do { \ + *(((char *)(T))) = (char) ((A));\ + *(((char *)(T))+1) = (char) (((A) >> 8));\ + *(((char *)(T))+2) = (char) (((A) >> 16));\ + *(((char *)(T))+3) = (char) (((A) >> 24)); } while (0) +#define mysql_int5store(T,A) do { \ + *(((char *)(T))) = (char)((A));\ + *(((char *)(T))+1) = (char)(((A) >> 8));\ + *(((char *)(T))+2) = (char)(((A) >> 16));\ + *(((char *)(T))+3) = (char)(((A) >> 24)); \ + *(((char *)(T))+4) = (char)(((A) >> 32)); } while (0) +/* Based on int5store() from Andrey Hristov */ +#define mysql_int6store(T,A) do { \ + *(((char *)(T))) = (char)((A));\ + *(((char *)(T))+1) = (char)(((A) >> 8));\ + *(((char *)(T))+2) = (char)(((A) >> 16));\ + *(((char *)(T))+3) = (char)(((A) >> 24)); \ + *(((char *)(T))+4) = (char)(((A) >> 32)); \ + *(((char *)(T))+5) = (char)(((A) >> 40)); } while (0) + +#define mysql_int8store(T,A) do { uint32_t def_temp= (uint32_t) (A), def_temp2= (uint32_t) ((A) >> 32); \ + mysql_int4store((T),def_temp); \ + mysql_int4store((T+4),def_temp2); } while (0) + +#define MYSQL_RESPONSE_BUFFER (client->cmd == SW_MYSQL_COM_STMT_EXECUTE ? client->statement->buffer : client->buffer) + +int mysql_get_result(mysql_connector *connector, char *buf, int len); +int mysql_get_charset(char *name); +int mysql_handshake(mysql_connector *connector, char *buf, int len); +int mysql_parse_auth_signature(swString *buffer, mysql_connector *connector); +int mysql_parse_rsa(mysql_connector *connector, char *buf, int len); +int mysql_auth_switch(mysql_connector *connector, char *buf, int len); +int mysql_request(swString *sql, swString *buffer); +int mysql_prepare(swString *sql, swString *buffer); +int mysql_response(mysql_client *client); +int mysql_is_over(mysql_client *client); + +#ifdef SW_MYSQL_DEBUG +void mysql_client_info(mysql_client *client); +void mysql_column_info(mysql_field *field); +#endif + +static sw_inline void mysql_pack_length(int length, char *buf) +{ + buf[2] = length >> 16; + buf[1] = length >> 8; + buf[0] = length; +} + +static sw_inline int mysql_lcb_ll(char *m, ulong_t *r, char *nul, int len) +{ + if (len < 1) + { + return -1; + } + switch ((uchar) m[0]) + { + + case 251: /* fb : 1 octet */ + *r = 0; + *nul = 1; + return 1; + + case 252: /* fc : 2 octets */ + if (len < 3) + { + return -1; + } + *r = mysql_uint2korr(m + 1); + *nul = 0; + return 3; + + case 253: /* fd : 3 octets */ + if (len < 5) + { + return -1; + } + *r = mysql_uint3korr(m + 1); + *nul = 0; + return 4; + + case 254: /* fe */ + if (len < 9) + { + return -1; + } + *r = mysql_uint8korr(m + 1); + *nul = 0; + return 9; + + default: + *r = (uchar) m[0]; + *nul = 0; + return 1; + } +} + +static sw_inline int mysql_write_lcb(char *p, long val) +{ + if (val <= 250) + { + mysql_int1store(p, val); + return 1; + } + else if (val <= 0xffff) + { + mysql_int2store(p, val); + return 2; + } + else if (val <= 0xffffff) + { + mysql_int3store(p, val); + return 3; + } + else + { + mysql_int1store(p, 254); + mysql_int8store(p, val); + return 9; + } +} + +static sw_inline int mysql_length_coded_binary(char *m, ulong_t *r, char *nul, int len) +{ + ulong_t val = 0; + int retcode = mysql_lcb_ll(m, &val, nul, len); + *r = val; + return retcode; +} + +int mysql_query(zval *zobject, mysql_client *client, swString *sql, zval *callback TSRMLS_DC); + +#endif /* SWOOLE_MYSQL_H_ */ diff --git a/vendor/swoole/swoole_mysql_coro.c b/vendor/swoole/swoole_mysql_coro.c new file mode 100755 index 0000000..42a54b1 --- /dev/null +++ b/vendor/swoole/swoole_mysql_coro.c @@ -0,0 +1,1990 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#include "swoole_mysql.h" + +#ifdef SW_USE_MYSQLND +#include "ext/mysqlnd/mysqlnd.h" +#include "ext/mysqlnd/mysqlnd_charset.h" +#endif + +static PHP_METHOD(swoole_mysql_coro, __construct); +static PHP_METHOD(swoole_mysql_coro, __destruct); +static PHP_METHOD(swoole_mysql_coro, connect); +static PHP_METHOD(swoole_mysql_coro, query); +static PHP_METHOD(swoole_mysql_coro, recv); +#ifdef SW_USE_MYSQLND +static PHP_METHOD(swoole_mysql_coro, escape); +#endif +static PHP_METHOD(swoole_mysql_coro, begin); +static PHP_METHOD(swoole_mysql_coro, commit); +static PHP_METHOD(swoole_mysql_coro, rollback); +static PHP_METHOD(swoole_mysql_coro, prepare); +static PHP_METHOD(swoole_mysql_coro, setDefer); +static PHP_METHOD(swoole_mysql_coro, getDefer); +static PHP_METHOD(swoole_mysql_coro, close); + +static PHP_METHOD(swoole_mysql_coro_statement, __destruct); +static PHP_METHOD(swoole_mysql_coro_statement, execute); +static PHP_METHOD(swoole_mysql_coro_statement, fetch); +static PHP_METHOD(swoole_mysql_coro_statement, fetchAll); +static PHP_METHOD(swoole_mysql_coro_statement, nextResult); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_connect, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, server_config, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_query, 0, 0, 1) + ZEND_ARG_INFO(0, sql) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_begin, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_commit, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_rollback, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_prepare, 0, 0, 1) + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_setDefer, 0, 0, 0) + ZEND_ARG_INFO(0, defer) +ZEND_END_ARG_INFO() + +#ifdef SW_USE_MYSQLND +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_escape, 0, 0, 1) + ZEND_ARG_INFO(0, string) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_statement_execute, 0, 0, 0) + ZEND_ARG_INFO(0, params) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_statement_fetch, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_statement_fetchAll, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_mysql_coro_statement_nextResult, 0, 0, 0) +ZEND_END_ARG_INFO() + +static zend_class_entry swoole_mysql_coro_ce; +static zend_class_entry *swoole_mysql_coro_class_entry_ptr; + +static zend_class_entry swoole_mysql_coro_exception_ce; +static zend_class_entry *swoole_mysql_coro_exception_class_entry_ptr; + +static zend_class_entry swoole_mysql_coro_statement_ce; +static zend_class_entry *swoole_mysql_coro_statement_class_entry_ptr; + +static const zend_function_entry swoole_mysql_coro_methods[] = +{ + PHP_ME(swoole_mysql_coro, __construct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_mysql_coro, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_mysql_coro, connect, arginfo_swoole_mysql_coro_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, query, arginfo_swoole_mysql_coro_query, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, recv, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#ifdef SW_USE_MYSQLND + PHP_ME(swoole_mysql_coro, escape, arginfo_swoole_mysql_coro_escape, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_mysql_coro, begin, arginfo_swoole_mysql_coro_begin, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, commit, arginfo_swoole_mysql_coro_commit, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, rollback, arginfo_swoole_mysql_coro_rollback, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, prepare, arginfo_swoole_mysql_coro_prepare, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, setDefer, arginfo_swoole_mysql_coro_setDefer, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, getDefer, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +static const zend_function_entry swoole_mysql_coro_statement_methods[] = +{ + PHP_ME(swoole_mysql_coro_statement, execute, arginfo_swoole_mysql_coro_statement_execute, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro_statement, fetch, arginfo_swoole_mysql_coro_statement_fetch, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro_statement, fetchAll, arginfo_swoole_mysql_coro_statement_fetchAll, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro_statement, nextResult, arginfo_swoole_mysql_coro_statement_nextResult, ZEND_ACC_PUBLIC) + PHP_ME(swoole_mysql_coro_statement, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +static int swoole_mysql_coro_onRead(swReactor *reactor, swEvent *event); +static int swoole_mysql_coro_onWrite(swReactor *reactor, swEvent *event); +static int swoole_mysql_coro_onError(swReactor *reactor, swEvent *event); +static void swoole_mysql_coro_onConnect(mysql_client *client TSRMLS_DC); +static void swoole_mysql_coro_onTimeout(swTimer *timer, swTimer_node *tnode); + +extern swString *mysql_request_buffer; + +void swoole_mysql_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_mysql_coro_ce, "Swoole\\Coroutine\\MySQL", swoole_mysql_coro_methods); + swoole_mysql_coro_class_entry_ptr = zend_register_internal_class(&swoole_mysql_coro_ce TSRMLS_CC); + + INIT_CLASS_ENTRY(swoole_mysql_coro_statement_ce, "Swoole\\Coroutine\\MySQL\\Statement", + swoole_mysql_coro_statement_methods); + swoole_mysql_coro_statement_class_entry_ptr = zend_register_internal_class( + &swoole_mysql_coro_statement_ce TSRMLS_CC); + + INIT_CLASS_ENTRY(swoole_mysql_coro_exception_ce, "Swoole\\Coroutine\\MySQL\\Exception", NULL); + swoole_mysql_coro_exception_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_mysql_coro_exception_ce, + zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\MySQL", swoole_mysql_coro_class_entry_ptr); + sw_zend_register_class_alias("Co\\MySQL\\Statement", swoole_mysql_coro_statement_class_entry_ptr); + sw_zend_register_class_alias("Co\\MySQL\\Exception", swoole_mysql_coro_exception_class_entry_ptr); + } + + zend_declare_property_string(swoole_mysql_coro_class_entry_ptr, SW_STRL("serverInfo") - 1, "", ZEND_ACC_PRIVATE TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_class_entry_ptr, SW_STRL("sock") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_mysql_coro_class_entry_ptr, SW_STRL("connected") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(swoole_mysql_coro_class_entry_ptr, SW_STRL("connect_error") - 1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_class_entry_ptr, SW_STRL("connect_errno") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_class_entry_ptr, SW_STRL("affected_rows") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_class_entry_ptr, SW_STRL("insert_id") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(swoole_mysql_coro_class_entry_ptr, SW_STRL("error") - 1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_class_entry_ptr, SW_STRL("errno") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_long(swoole_mysql_coro_statement_class_entry_ptr, SW_STRL("affected_rows") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_statement_class_entry_ptr, SW_STRL("insert_id") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(swoole_mysql_coro_statement_class_entry_ptr, SW_STRL("error") - 1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_mysql_coro_statement_class_entry_ptr, SW_STRL("errno") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); +} + +int mysql_query(zval *zobject, mysql_client *client, swString *sql, zval *callback TSRMLS_DC); + +static int swoole_mysql_coro_execute(zval *zobject, mysql_client *client, zval *params TSRMLS_DC) +{ + if (!client->cli) + { + swoole_php_fatal_error(E_WARNING, "mysql connection#%d is closed.", client->fd); + return SW_ERR; + } + + if (client->state != SW_MYSQL_STATE_QUERY) + { + swoole_php_fatal_error(E_WARNING, "mysql client is waiting response, cannot send new sql query."); + return SW_ERR; + } + + mysql_statement *statement = swoole_get_object(zobject); + if (!statement) + { + swoole_php_fatal_error(E_WARNING, "mysql preparation is not ready."); + return SW_ERR; + } + + int params_length = 0; + if (params){ + params_length = php_swoole_array_length(params); + } + + if (params_length != statement->param_count) + { + swoole_php_fatal_error(E_WARNING, "mysql statement#%d expects %d parameter, %d given.", statement->id, + statement->param_count, params_length); + return SW_ERR; + } + + swString_clear(mysql_request_buffer); + + client->cmd = SW_MYSQL_COM_STMT_EXECUTE; + client->statement = statement; + + bzero(mysql_request_buffer->str, 5); + //command + mysql_request_buffer->str[4] = SW_MYSQL_COM_STMT_EXECUTE; + mysql_request_buffer->length = 5; + char *p = mysql_request_buffer->str; + p += 5; + + // stmt.id + mysql_int4store(p, statement->id); + p += 4; + // flags = CURSOR_TYPE_NO_CURSOR + mysql_int1store(p, 0); + p += 1; + // iteration_count + mysql_int4store(p, 1); + p += 4; + + mysql_request_buffer->length += 9; + + if (params_length == 0) + { + goto send; + } + + //null bitmap + unsigned int null_count = (params_length + 7) / 8; + memset(p, 0, null_count); + p += null_count; + mysql_request_buffer->length += null_count; + + //rebind + mysql_int1store(p, 1); + p += 1; + mysql_request_buffer->length += 1; + + int i; + for (i = 0; i < statement->param_count; i++) + { + mysql_int2store(p, SW_MYSQL_TYPE_VAR_STRING); + p += 2; + } + + mysql_request_buffer->length += params_length * 2; + + long lval; + char buf[10]; + { + zval *value; + zval _value; + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value) + ZVAL_DUP(&_value, value); + value = &_value; + convert_to_string(value); + if (Z_STRLEN_P(value) > 0xffff) + { + buf[0] = (char) SW_MYSQL_TYPE_VAR_STRING; + if (swString_append_ptr(mysql_request_buffer, buf, 1) < 0) + { + zval_dtor(value); + return SW_ERR; + } + } + else if (Z_STRLEN_P(value) > 250) + { + buf[0] = (char) SW_MYSQL_TYPE_BLOB; + if (swString_append_ptr(mysql_request_buffer, buf, 1) < 0) + { + zval_dtor(value); + return SW_ERR; + } + } + lval = mysql_write_lcb(buf, Z_STRLEN_P(value)); + if (swString_append_ptr(mysql_request_buffer, buf, lval) < 0) + { + zval_dtor(value); + return SW_ERR; + } + if (swString_append_ptr(mysql_request_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value)) < 0) + { + zval_dtor(value); + return SW_ERR; + } + zval_dtor(value); + SW_HASHTABLE_FOREACH_END(); + } + + send: + + //length + mysql_pack_length(mysql_request_buffer->length - 4, mysql_request_buffer->str); + + //send data + if (SwooleG.main_reactor->write(SwooleG.main_reactor, client->fd, mysql_request_buffer->str, mysql_request_buffer->length) < 0) + { + //connection is closed + if (swConnection_error(errno) == SW_CLOSE) + { + zend_update_property_bool(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("errno"), 2013 TSRMLS_CC); + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), "Lost connection to MySQL server during query" TSRMLS_CC); + } + return SW_ERR; + } + else + { + client->state = SW_MYSQL_STATE_READ_START; + return SW_OK; + } + + return SW_OK; +} + +static int swoole_mysql_coro_parse_response(mysql_client *client, zval **result, int from_next_result) +{ + zval *zobject = client->object; + + if (mysql_response(client) < 0) + { + return SW_ERR; + } + + //remove from eventloop + //reactor->del(reactor, event->fd); + + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("affected_rows"), + client->response.affected_rows TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("insert_id"), + client->response.insert_id TSRMLS_CC); + + if (client->cmd == SW_MYSQL_COM_STMT_EXECUTE) + { + zend_update_property_long(swoole_mysql_coro_statement_class_entry_ptr, client->statement->object, + ZEND_STRL("affected_rows"), client->response.affected_rows TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_statement_class_entry_ptr, client->statement->object, + ZEND_STRL("insert_id"), client->response.insert_id TSRMLS_CC); + } + + client->state = SW_MYSQL_STATE_QUERY; + + //OK + if (client->response.response_type == 0) + { + SW_ALLOC_INIT_ZVAL(*result); + // prepare finished and create statement + if (client->cmd == SW_MYSQL_COM_STMT_PREPARE) + { + if (client->statement_list == NULL) + { + client->statement_list = swLinkedList_new(0, NULL); + } + swLinkedList_append(client->statement_list, client->statement); + object_init_ex(*result, swoole_mysql_coro_statement_class_entry_ptr); + swoole_set_object(*result, client->statement); + client->statement->object = sw_zval_dup(*result); + } + else + { + if (from_next_result) + { + // pass the ok response ret val + ZVAL_NULL(*result); + } + else + { + ZVAL_TRUE(*result); + } + } + } + //ERROR + else if (client->response.response_type == 255) + { + SW_ALLOC_INIT_ZVAL(*result); + ZVAL_BOOL(*result, 0); + + zend_update_property_stringl(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), + client->response.server_msg, client->response.l_server_msg TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("errno"), + client->response.error_code TSRMLS_CC); + + if (client->cmd == SW_MYSQL_COM_STMT_EXECUTE) + { + zend_update_property_stringl(swoole_mysql_coro_statement_class_entry_ptr, client->statement->object, + ZEND_STRL("error"), client->response.server_msg, client->response.l_server_msg TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_statement_class_entry_ptr, client->statement->object, + ZEND_STRL("errno"), client->response.error_code TSRMLS_CC); + } + } + //ResultSet + else + { + if (client->connector.fetch_mode && client->cmd == SW_MYSQL_COM_STMT_EXECUTE) + { + if (client->statement->result) + { + // free the last one + sw_zval_free(client->statement->result); + client->statement->result = NULL; + } + // save result on statement and wait for fetch + client->statement->result = client->response.result_array; + client->response.result_array = NULL; + // return true (success)] + SW_ALLOC_INIT_ZVAL(*result); + ZVAL_TRUE(*result); + } + else + { + *result = client->response.result_array; + } + } + + return SW_OK; +} + +static void swoole_mysql_coro_parse_end(mysql_client *client, swString *buffer) +{ + if (client->response.status_code & SW_MYSQL_SERVER_MORE_RESULTS_EXISTS) + { + swTraceLog(SW_TRACE_MYSQL_CLIENT, "remaining %d, more results exists", buffer->length - buffer->offset); + } + else + { + // no more, clean up + swString_clear(buffer); + } + bzero(&client->response, sizeof(client->response)); + client->statement = NULL; + client->cmd = SW_MYSQL_COM_NULL; +} + +static int swoole_mysql_coro_statement_free(mysql_statement *stmt TSRMLS_DC) +{ + if (stmt->object) + { + swoole_set_object(stmt->object, NULL); + efree(stmt->object); + } + + if (stmt->buffer) + { + swString_free(stmt->buffer); + } + + if (stmt->result) + { + sw_zval_free(stmt->result); + } + + return SW_OK; +} + +static int swoole_mysql_coro_statement_close(mysql_statement *stmt TSRMLS_DC) +{ + // call mysql-server to destruct this statement + swString_clear(mysql_request_buffer); + stmt->client->cmd = SW_MYSQL_COM_STMT_CLOSE; + bzero(mysql_request_buffer->str, 5); + //command + mysql_request_buffer->str[4] = SW_MYSQL_COM_STMT_CLOSE; + mysql_request_buffer->length = 5; + char *p = mysql_request_buffer->str; + p += 5; + + // stmt.id + mysql_int4store(p, stmt->id); + p += 4; + mysql_request_buffer->length += 4; + //length + mysql_pack_length(mysql_request_buffer->length - 4, mysql_request_buffer->str); + //send data, mysql-server would not reply + SwooleG.main_reactor->write(SwooleG.main_reactor, stmt->client->fd, mysql_request_buffer->str, mysql_request_buffer->length); + + return SW_OK; +} + +static int swoole_mysql_coro_close(zval *this) +{ + SWOOLE_GET_TSRMLS; + mysql_client *client = swoole_get_object(this); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql_coro."); + return FAILURE; + } + + if (!client->cli) + { + return FAILURE; + } + + if (client->connected) + { + //send quit command + swString_clear(mysql_request_buffer); + client->cmd = SW_MYSQL_COM_QUIT; + bzero(mysql_request_buffer->str, 5); + mysql_request_buffer->str[4] = SW_MYSQL_COM_QUIT;//command + mysql_request_buffer->length = 5; + mysql_pack_length(mysql_request_buffer->length - 4, mysql_request_buffer->str); + SwooleG.main_reactor->write(SwooleG.main_reactor, client->fd, mysql_request_buffer->str, mysql_request_buffer->length); + } + + zend_update_property_bool(swoole_mysql_coro_class_entry_ptr, this, ZEND_STRL("connected"), 0 TSRMLS_CC); + SwooleG.main_reactor->del(SwooleG.main_reactor, client->fd); + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, client->fd); + _socket->object = NULL; + _socket->active = 0; + + if (client->timer) + { + swTimer_del(&SwooleG.timer, client->timer); + client->timer = NULL; + } + + if (client->statement_list) + { + swLinkedList_node *node = client->statement_list->head; + while (node) + { + mysql_statement *stmt = node->data; + // after connection closed, mysql stmt cache closed too + // so we needn't send stmt close command here like pdo. + swoole_mysql_coro_statement_free(stmt); + efree(stmt); + node = node->next; + } + swLinkedList_free(client->statement_list); + } + + client->cli->close(client->cli); + swClient_free(client->cli); + efree(client->cli); + client->cli = NULL; + client->state = SW_MYSQL_STATE_CLOSED; + client->iowait = SW_MYSQL_CORO_STATUS_CLOSED; + //TODO: clear connector + + return SUCCESS; +} + +static PHP_METHOD(swoole_mysql_coro, __construct) +{ + coro_check(TSRMLS_C); + + if (!mysql_request_buffer) + { + mysql_request_buffer = swString_new(SW_MYSQL_QUERY_INIT_SIZE); + if (!mysql_request_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } + } + + mysql_client *client = emalloc(sizeof(mysql_client)); + bzero(client, sizeof(mysql_client)); + swoole_set_object(getThis(), client); +} + +static PHP_METHOD(swoole_mysql_coro, connect) +{ + zval *server_info; + char buf[2048]; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &server_info) == FAILURE) + { + RETURN_FALSE; + } + + php_swoole_array_separate(server_info); + + HashTable *_ht = Z_ARRVAL_P(server_info); + zval *value; + + mysql_client *client = swoole_get_object(getThis()); + + if (client->cli) + { + swoole_php_fatal_error(E_WARNING, "connection to the server has already been established."); + RETURN_FALSE; + } + + mysql_connector *connector = &client->connector; + + if (php_swoole_array_get_value(_ht, "host", value)) + { + convert_to_string(value); + connector->host = Z_STRVAL_P(value); + connector->host_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "HOST parameter is required.", 11 TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "port", value)) + { + convert_to_long(value); + connector->port = Z_LVAL_P(value); + } + else + { + connector->port = SW_MYSQL_DEFAULT_PORT; + } + if (php_swoole_array_get_value(_ht, "user", value)) + { + convert_to_string(value); + connector->user = Z_STRVAL_P(value); + connector->user_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "USER parameter is required.", 11 TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "password", value)) + { + convert_to_string(value); + connector->password = Z_STRVAL_P(value); + connector->password_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "PASSWORD parameter is required.", 11 TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "database", value)) + { + convert_to_string(value); + connector->database = Z_STRVAL_P(value); + connector->database_len = Z_STRLEN_P(value); + } + else + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "DATABASE parameter is required.", 11 TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + if (php_swoole_array_get_value(_ht, "timeout", value)) + { + convert_to_double(value); + connector->timeout = Z_DVAL_P(value); + } + else + { + connector->timeout = SW_MYSQL_CONNECT_TIMEOUT; + } + if (php_swoole_array_get_value(_ht, "charset", value)) + { + convert_to_string(value); + connector->character_set = mysql_get_charset(Z_STRVAL_P(value)); + if (connector->character_set < 0) + { + snprintf(buf, sizeof(buf), "unknown charset [%s].", Z_STRVAL_P(value)); + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, buf, 11 TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + } + else + { + connector->character_set = SW_MYSQL_DEFAULT_CHARSET; + } + + if (php_swoole_array_get_value(_ht, "strict_type", value)) + { +#if PHP_MAJOR_VERSION < 7 + if(Z_TYPE_P(value) == IS_BOOL && Z_BVAL_P(value) == 1) +#else + if (Z_TYPE_P(value) == IS_TRUE) +#endif + { + connector->strict_type = 1; + } + else + { + connector->strict_type = 0; + } + } + else + { + connector->strict_type = 0; + } + + if (php_swoole_array_get_value(_ht, "fetch_mode", value)) + { +#if PHP_MAJOR_VERSION < 7 + if(Z_TYPE_P(value) == IS_BOOL && Z_BVAL_P(value) == 1) +#else + if (Z_TYPE_P(value) == IS_TRUE) +#endif + { + connector->fetch_mode = 1; + } + else + { + connector->fetch_mode = 0; + } + } + else + { + connector->fetch_mode = 0; + } + + swClient *cli = emalloc(sizeof(swClient)); + int type = SW_SOCK_TCP; + + if (strncasecmp(connector->host, ZEND_STRL("unix:/")) == 0) + { + connector->host = connector->host + 5; + connector->host_len = connector->host_len - 5; + type = SW_SOCK_UNIX_STREAM; + } + else if (strchr(connector->host, ':')) + { + type = SW_SOCK_TCP6; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL_CORO)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL_CORO | SW_EVENT_READ, swoole_mysql_coro_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL_CORO | SW_EVENT_WRITE, swoole_mysql_coro_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_MYSQL_CORO | SW_EVENT_ERROR, swoole_mysql_coro_onError); + } + + if (swClient_create(cli, type, 0) < 0) + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "swClient_create failed.", 1 TSRMLS_CC); + efree(cli); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + + //tcp nodelay + if (type != SW_SOCK_UNIX_STREAM) + { + int tcp_nodelay = 1; + if (setsockopt(cli->socket->fd, IPPROTO_TCP, TCP_NODELAY, (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + swoole_php_sys_error(E_WARNING, "setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) failed.", cli->socket->fd); + } + } + + int ret = cli->connect(cli, connector->host, connector->port, connector->timeout, 1); + if ((ret < 0 && errno == EINPROGRESS) || ret == 0) + { + if (SwooleG.main_reactor->add(SwooleG.main_reactor, cli->socket->fd, PHP_SWOOLE_FD_MYSQL_CORO | SW_EVENT_WRITE) < 0) + { + efree(cli); + sw_zval_ptr_dtor(&server_info); + RETURN_FALSE; + } + } + else + { + efree(cli); + snprintf(buf, sizeof(buf), "connect to mysql server[%s:%d] failed.", connector->host, connector->port); + sw_zval_ptr_dtor(&server_info); + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, buf, 2 TSRMLS_CC); + RETURN_FALSE; + } + + zend_update_property(swoole_mysql_coro_class_entry_ptr, getThis(), ZEND_STRL("serverInfo"), server_info TSRMLS_CC); + sw_zval_ptr_dtor(&server_info); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, getThis(), ZEND_STRL("sock"), cli->socket->fd TSRMLS_CC); + + if (!client->buffer) + { + client->buffer = swString_new(SW_BUFFER_SIZE_BIG); + } + else + { + swString_clear(client->buffer); + bzero(&client->response, sizeof(client->response)); + } + client->fd = cli->socket->fd; + client->object = getThis(); + client->cli = cli; + sw_copy_to_stack(client->object, client->_object); + +#if PHP_MAJOR_VERSION < 7 + sw_zval_add_ref(&client->object); +#endif + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, cli->socket->fd); + _socket->object = client; + _socket->active = 0; + + php_context *context = swoole_get_property(getThis(), 0); + if (!context) + { + context = emalloc(sizeof(php_context)); + swoole_set_property(getThis(), 0, context); + } + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + context->coro_params = getThis(); +#else + context->coro_params = *getThis(); +#endif + if (connector->timeout > 0) + { + php_swoole_check_timer((int) (connector->timeout * 1000)); + connector->timer = SwooleG.timer.add(&SwooleG.timer, (int) (connector->timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + } + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_mysql_coro, query) +{ + swString sql; + bzero(&sql, sizeof(sql)); + double timeout = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|d", &sql.str, &sql.length, &timeout) == FAILURE) + { + return; + } + + if (sql.length <= 0) + { + swoole_php_fatal_error(E_WARNING, "Query is empty."); + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION; + swoole_php_error(E_WARNING, "object is not instanceof swoole_mysql_coro."); + RETURN_FALSE; + } + + if (client->iowait == SW_MYSQL_CORO_STATUS_DONE) + { + swoole_php_fatal_error(E_WARNING, "mysql client is waiting for calling recv, cannot send new sql query."); + RETURN_FALSE; + } + + if (unlikely(client->cid && client->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "mysql client has already been bound to another coroutine."); + RETURN_FALSE; + } + + swString_clear(mysql_request_buffer); + + if (mysql_query(getThis(), client, &sql, NULL TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + client->state = SW_MYSQL_STATE_READ_START; + php_context *context = swoole_get_property(getThis(), 0); + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + if (client->timer && client->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + RETURN_TRUE; + } + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_mysql_coro, begin) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (unlikely(client->cid && client->cid != sw_get_current_cid())) { + swoole_php_fatal_error(E_WARNING, "mysql client has already been bound to another coroutine."); + RETURN_FALSE; + } + if (client->transaction) + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "There is already an active transaction.", 21 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("START TRANSACTION")); + if (mysql_query(getThis(), client, &sql, NULL TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 1; + double timeout = client->connector.timeout; + php_context *context = swoole_get_property(getThis(), 0); + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + if (client->timer && client->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + //RETURN_TRUE; + } + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); + } +} + +static PHP_METHOD(swoole_mysql_coro, commit) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + + if (unlikely(client->cid && client->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "mysql client has already been bound to another coroutine."); + RETURN_FALSE; + } + + if (!client->transaction) + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "There is no active transaction.", 22 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("COMMIT")); + if (mysql_query(getThis(), client, &sql, NULL TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 0; + php_context *context = swoole_get_property(getThis(), 0); + double timeout = client->connector.timeout; + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + if (client->timer && client->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + //RETURN_TRUE; + } + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); + } +} + +static PHP_METHOD(swoole_mysql_coro, rollback) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + + if (unlikely(client->cid && client->cid != sw_get_current_cid())) { + swoole_php_fatal_error(E_WARNING, "mysql client has already been bound to another coroutine."); + RETURN_FALSE; + } + + if (!client->transaction) + { + zend_throw_exception(swoole_mysql_coro_exception_class_entry_ptr, "There is no active transaction.", 22 TSRMLS_CC); + RETURN_FALSE; + } + + swString sql; + bzero(&sql, sizeof(sql)); + swString_append_ptr(&sql, ZEND_STRL("ROLLBACK")); + if (mysql_query(getThis(), client, &sql, NULL TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + else + { + client->transaction = 0; + php_context *context = swoole_get_property(getThis(), 0); + double timeout = client->connector.timeout; + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + if (client->timer && client->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + //RETURN_TRUE; + } + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); + } +} + +static PHP_METHOD(swoole_mysql_coro, getDefer) +{ + mysql_client *client = swoole_get_object(getThis()); + RETURN_BOOL(client->defer); +} + +static PHP_METHOD(swoole_mysql_coro, setDefer) +{ + zend_bool defer = 1; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &defer) == FAILURE) + { + return; + } + + mysql_client *client = swoole_get_object(getThis()); + if (client->iowait > SW_MYSQL_CORO_STATUS_READY) + { + RETURN_BOOL(defer); + } + client->defer = defer; + RETURN_TRUE +} + +static PHP_METHOD(swoole_mysql_coro, recv) +{ + mysql_client *client = swoole_get_object(getThis()); + + if (!client->defer) + { + swoole_php_fatal_error(E_WARNING, "you should not use recv without defer "); + RETURN_FALSE; + } + + if (client->iowait == SW_MYSQL_CORO_STATUS_DONE) + { + client->iowait = SW_MYSQL_CORO_STATUS_READY; +#if PHP_MAJOR_VERSION >= 7 + zval _result = *client->result; + efree(client->result); + zval *result = &_result; +#else + zval *result = client->result; +#endif + client->result = NULL; + RETURN_ZVAL(result, 0, 1); + } + + if (client->iowait != SW_MYSQL_CORO_STATUS_WAIT) + { + swoole_php_fatal_error(E_WARNING, "no request."); + RETURN_FALSE; + } + + client->suspending = 1; + client->cid = sw_get_current_cid(); + php_context *context = swoole_get_property(getThis(), 0); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_mysql_coro, prepare) +{ + swString sql; + bzero(&sql, sizeof(sql)); + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "s", &sql.str, &sql.length) == FAILURE) + { + RETURN_FALSE; + } + if (sql.length <= 0) + { + swoole_php_fatal_error(E_WARNING, "Query is empty."); + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client || client->state == SW_MYSQL_STATE_CLOSED) + { + swoole_php_fatal_error(E_WARNING, "The MySQL connection is not established."); + RETURN_FALSE; + } + + if (client->state != SW_MYSQL_STATE_QUERY) + { + swoole_php_fatal_error(E_WARNING, "mysql client is waiting response, cannot send new sql query."); + RETURN_FALSE; + } + + client->cmd = SW_MYSQL_COM_STMT_PREPARE; + client->state = SW_MYSQL_STATE_READ_START; + + swString_clear(mysql_request_buffer); + + if (mysql_prepare(&sql, mysql_request_buffer) < 0) + { + RETURN_FALSE; + } + //send query + if (SwooleG.main_reactor->write(SwooleG.main_reactor, client->fd, mysql_request_buffer->str, mysql_request_buffer->length) < 0) + { + //connection is closed + if (swConnection_error(errno) == SW_CLOSE) + { + zval *zobject = getThis(); + zend_update_property_bool(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 0 TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("errno"), 2013 TSRMLS_CC); + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), "Lost connection to MySQL server during query" TSRMLS_CC); + } + RETURN_FALSE; + } + + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + RETURN_TRUE; + } + + php_context *context = swoole_get_property(getThis(), 0); + double timeout = client->connector.timeout; + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + } + client->suspending = 1; + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_mysql_coro_statement, execute) +{ + zval *params = NULL; + double timeout = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "|ad", &params, &timeout) == FAILURE) + { + RETURN_FALSE; + } + + mysql_statement *stmt = swoole_get_object(getThis()); + if (!stmt) + { + RETURN_FALSE; + } + + mysql_client *client = stmt->client; + if (!client->cli) + { + swoole_php_fatal_error(E_WARNING, "mysql connection#%d is closed.", client->fd); + RETURN_FALSE; + } + + if (swoole_mysql_coro_execute(getThis(), client, params TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + php_context *context = swoole_get_property(client->object, 0); + if (timeout > 0) + { + client->timer = SwooleG.timer.add(&SwooleG.timer, (int) (timeout * 1000), 0, context, swoole_mysql_coro_onTimeout); + if (client->timer && client->defer) + { + context->state = SW_CORO_CONTEXT_IN_DELAYED_TIMEOUT_LIST; + } + } + if (client->defer) + { + client->iowait = SW_MYSQL_CORO_STATUS_WAIT; + RETURN_TRUE; + } + client->suspending = 1; + client->cid = sw_get_current_cid(); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_mysql_coro_statement, fetch) +{ + mysql_statement *stmt = swoole_get_object(getThis()); + if (!stmt) + { + RETURN_FALSE; + } + + if (!stmt->client->connector.fetch_mode) + { + RETURN_FALSE; + } + + if (stmt->result) + { + zval args[1]; + // the function argument is a reference + ZVAL_NEW_REF(stmt->result, stmt->result); + args[0] = *stmt->result; + + zval *fcn; + SW_MAKE_STD_ZVAL(fcn); + ZVAL_STRING(fcn, "array_shift"); + int ret; + zval retval; + ret = call_user_function_ex(EG(function_table), NULL, fcn, &retval, 1, args, 0, NULL TSRMLS_CC); + sw_zval_ptr_dtor(&fcn); + ZVAL_UNREF(stmt->result); + + if (ret == FAILURE) + { + if (stmt->result) + { + sw_zval_free(stmt->result); + stmt->result = NULL; + } + RETURN_NULL(); + } + else + { + if (php_swoole_array_length(stmt->result) == 0) + { + sw_zval_free(stmt->result); + stmt->result = NULL; + } + RETURN_ZVAL(&retval, 0, 1); + } + } + else + { + RETURN_NULL(); + } +} + +static PHP_METHOD(swoole_mysql_coro_statement, fetchAll) +{ + mysql_statement *stmt = swoole_get_object(getThis()); + if (!stmt) + { + RETURN_FALSE; + } + + if (!stmt->client->connector.fetch_mode) + { + RETURN_FALSE; + } + + if (stmt->result) + { + zval _result = *stmt->result; + efree(stmt->result); + zval *result = &_result; + stmt->result = NULL; + RETURN_ZVAL(result, 0, 1); + } + else + { + RETURN_NULL(); + } +} + +static PHP_METHOD(swoole_mysql_coro_statement, nextResult) +{ + mysql_statement *stmt = swoole_get_object(getThis()); + if (!stmt) + { + RETURN_FALSE; + } + +// if (!stmt->client->connector.fetch_mode) +// { +// RETURN_FALSE; +// } + + mysql_client *client = stmt->client; + + if (stmt->buffer && stmt->buffer->offset < stmt->buffer->length) + { + client->cmd = SW_MYSQL_COM_STMT_EXECUTE; + client->state = SW_MYSQL_STATE_READ_START; + client->statement = stmt; + zval *result = NULL; + if (swoole_mysql_coro_parse_response(client, &result, 1) == SW_OK) + { + swoole_mysql_coro_parse_end(client, stmt->buffer); // ending tidy up + + zval _result = *result; + efree(result); + result = &_result; + RETURN_ZVAL(result, 0, 1); + } + else + { + RETURN_FALSE; + } + } + else + { + RETURN_NULL() + } +} + +static PHP_METHOD(swoole_mysql_coro_statement, __destruct) +{ + mysql_statement *stmt = swoole_get_object(getThis()); + if (!stmt) + { + return; + } + swoole_mysql_coro_statement_close(stmt TSRMLS_CC); + swoole_mysql_coro_statement_free(stmt); + swLinkedList_remove(stmt->client->statement_list, stmt); + efree(stmt); +} + +#ifdef SW_USE_MYSQLND +static PHP_METHOD(swoole_mysql_coro, escape) +{ + swString str; + bzero(&str, sizeof(str)); + long flags; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str.str, &str.length, &flags) == FAILURE) + { + return; + } + + if (str.length <= 0) + { + swoole_php_fatal_error(E_WARNING, "String is empty."); + RETURN_FALSE; + } + + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_mysql."); + RETURN_FALSE; + } + if (!client->cli) + { + swoole_php_fatal_error(E_WARNING, "mysql connection#%d is closed.", client->fd); + RETURN_FALSE; + } + + char *newstr = safe_emalloc(2, str.length + 1, 1); + if (newstr == NULL) + { + swoole_php_fatal_error(E_ERROR, "emalloc(%ld) failed.", str.length + 1); + RETURN_FALSE; + } + + const MYSQLND_CHARSET* cset = mysqlnd_find_charset_nr(client->connector.character_set); + if (cset == NULL) + { + swoole_php_fatal_error(E_ERROR, "unknown mysql charset[%s].", client->connector.character_set); + RETURN_FALSE; + } + int newstr_len = mysqlnd_cset_escape_slashes(cset, newstr, str.str, str.length TSRMLS_CC); + if (newstr_len < 0) + { + swoole_php_fatal_error(E_ERROR, "mysqlnd_cset_escape_slashes() failed."); + RETURN_FALSE; + } + SW_RETURN_STRINGL(newstr, newstr_len, 0); +} +#endif + +static PHP_METHOD(swoole_mysql_coro, __destruct) +{ + mysql_client *client = swoole_get_object(getThis()); + if (!client) + { + return; + } + if (client->state != SW_MYSQL_STATE_CLOSED && client->cli) + { + swoole_mysql_coro_close(getThis()); + } + if (client->buffer) + { + swString_free(client->buffer); + } + efree(client); + swoole_set_object(getThis(), NULL); + + php_context *context = swoole_get_property(getThis(), 0); + if (!context) + { + return; + } + if (likely(context->state == SW_CORO_CONTEXT_RUNNING)) + { + efree(context); + } + else + { + context->state = SW_CORO_CONTEXT_TERM; + } + swoole_set_property(getThis(), 0, NULL); +} + +static PHP_METHOD(swoole_mysql_coro, close) +{ + if (swoole_mysql_coro_close(getThis()) == FAILURE) + { + RETURN_FALSE; + } +#if PHP_MAJOR_VERSION < 7 + sw_zval_ptr_dtor(&getThis()); +#endif + RETURN_TRUE; +} + +static int swoole_mysql_coro_onError(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *retval = NULL, *result; + mysql_client *client = event->socket->object; + zval *zobject = client->object; + + swoole_mysql_coro_close(zobject); + + SW_ALLOC_INIT_ZVAL(result); + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_error"), "EPOLLERR/EPOLLHUP/EPOLLRDHUP happen!" TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_errno"), 104 TSRMLS_CC); + ZVAL_BOOL(result, 0); + if (client->defer && !client->suspending) + { + client->result = result; + return SW_OK; + } + client->suspending = 0; + client->cid = 0; + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, result, &retval); + sw_zval_free(result); + + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + + return SW_OK; +} + +static void swoole_mysql_coro_onConnect(mysql_client *client TSRMLS_DC) +{ + zval *zobject = client->object; + + zval *retval = NULL; + zval *result; + + if (client->connector.timer) + { + swTimer_del(&SwooleG.timer, client->connector.timer); + client->connector.timer = NULL; + } + + SW_MAKE_STD_ZVAL(result); + + //SwooleG.main_reactor->del(SwooleG.main_reactor, client->fd); + + if (client->connector.error_code > 0) + { + zend_update_property_stringl(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_error"), client->connector.error_msg, client->connector.error_length TSRMLS_CC); + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_errno"), client->connector.error_code TSRMLS_CC); + + ZVAL_BOOL(result, 0); + + swoole_mysql_coro_close(zobject); + } + else + { + client->state = SW_MYSQL_STATE_QUERY; + client->iowait = SW_MYSQL_CORO_STATUS_READY; + zend_update_property_bool(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connected"), 1 TSRMLS_CC); + client->connected = 1; + ZVAL_BOOL(result, 1); + } + + client->cid = 0; + + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, result, &retval); + sw_zval_ptr_dtor(&result); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void swoole_mysql_coro_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *result; + zval *retval = NULL; + + php_context *ctx = tnode->data; + + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 0); +#if PHP_MAJOR_VERSION < 7 + zval *zobject = (zval *)ctx->coro_params; +#else + zval _zobject = ctx->coro_params; + zval *zobject = & _zobject; +#endif + mysql_client *client = swoole_get_object(zobject); + + if (client->iowait == SW_MYSQL_CORO_STATUS_CLOSED) + { + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), "connect timeout" TSRMLS_CC); + } + else + { + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), "query timeout" TSRMLS_CC); + } + + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("errno"), 110 TSRMLS_CC); + + //timeout close conncttion + client->timer = NULL; + client->state = SW_MYSQL_STATE_QUERY; + swoole_mysql_coro_close(zobject); + + if (client->defer && !client->suspending) + { + client->result = result; + return; + } + client->suspending = 0; + client->cid = 0; + + int ret = coro_resume(ctx, result, &retval); + + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + + sw_zval_free(result); +} + +static int swoole_mysql_coro_onWrite(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + if (event->socket->active) + { + return swReactor_onWrite(SwooleG.main_reactor, event); + } + + socklen_t len = sizeof(SwooleG.error); + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &SwooleG.error, &len) < 0) + { + swWarn("getsockopt(%d) failed. Error: %s[%d]", event->fd, strerror(errno), errno); + return SW_ERR; + } + + mysql_client *client = event->socket->object; + //success + if (SwooleG.error == 0) + { + //listen read event + SwooleG.main_reactor->set(SwooleG.main_reactor, event->fd, PHP_SWOOLE_FD_MYSQL_CORO | SW_EVENT_READ); + //connected + event->socket->active = 1; + client->handshake = SW_MYSQL_HANDSHAKE_WAIT_REQUEST; + } + else + { + client->connector.error_code = SwooleG.error; + client->connector.error_msg = strerror(SwooleG.error); + client->connector.error_length = strlen(client->connector.error_msg); + swoole_mysql_coro_onConnect(client TSRMLS_CC); + } + return SW_OK; +} + +static int swoole_mysql_coro_onHandShake(mysql_client *client TSRMLS_DC) +{ + swString *buffer = client->buffer; + swClient *cli = client->cli; + mysql_connector *connector = &client->connector; + + int n = cli->recv(cli, buffer->str + buffer->length, buffer->size - buffer->length, 0); + if (n < 0) + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("Read from socket[%d] failed.", cli->socket->fd); + return SW_ERR; + case SW_CLOSE: + goto system_call_error; + case SW_WAIT: + return SW_OK; + default: + return SW_ERR; + } + } + else if (n == 0) + { + errno = ECONNRESET; + goto system_call_error; + } + + buffer->length += n; + + int ret = 0; + + _again: + swTraceLog(SW_TRACE_MYSQL_CLIENT, "handshake on %d", client->handshake); + if (client->switch_check) + { + // after handshake we need check if server request us to switch auth type first + goto _check_switch; + } + + switch(client->handshake) + { + case SW_MYSQL_HANDSHAKE_WAIT_REQUEST: + { + client->switch_check = 1; + ret = mysql_handshake(connector, buffer->str, buffer->length); + + if (ret < 0) + { + goto _error; + } + else if (ret > 0) + { + _send: + if (cli->send(cli, connector->buf, connector->packet_length + 4, 0) < 0) + { + system_call_error: connector->error_code = errno; + connector->error_msg = strerror(errno); + connector->error_length = strlen(connector->error_msg); + swoole_mysql_coro_onConnect(client TSRMLS_CC); + return SW_OK; + } + else + { + // clear for the new package + swString_clear(buffer); + // mysql_handshake will return the next state flag + client->handshake = ret; + } + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_SWITCH: + { + _check_switch: + client->switch_check = 0; + int next_state; + // handle auth switch request + switch (next_state = mysql_auth_switch(connector, buffer->str, buffer->length)) + { + case SW_AGAIN: + return SW_OK; + case SW_ERR: + // not the switch package, go to the next + goto _again; + default: + ret = next_state; + goto _send; + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_SIGNATURE: + { + switch (mysql_parse_auth_signature(buffer, connector)) + { + case SW_MYSQL_AUTH_SIGNATURE_SUCCESS: + { + client->handshake = SW_MYSQL_HANDSHAKE_WAIT_RESULT; + break; + } + case SW_MYSQL_AUTH_SIGNATURE_FULL_AUTH_REQUIRED: + { + // send response and wait RSA public key + ret = SW_MYSQL_HANDSHAKE_WAIT_RSA; // handshake = ret + goto _send; + } + default: + { + goto _error; + } + } + + // may be more packages + if (buffer->offset < buffer->length) + { + goto _again; + } + else + { + swString_clear(buffer); + } + break; + } + case SW_MYSQL_HANDSHAKE_WAIT_RSA: + { + // encode by RSA +#ifdef SW_MYSQL_RSA_SUPPORT + switch (mysql_parse_rsa(connector, SWSTRING_CURRENT_VL(buffer))) + { + case SW_AGAIN: + return SW_OK; + case SW_OK: + ret = SW_MYSQL_HANDSHAKE_WAIT_RESULT; // handshake = ret + goto _send; + default: + goto _error; + } +#else + connector->error_code = -1; + connector->error_msg = "MySQL8 RSA-Auth need enable OpenSSL!"; + connector->error_length = strlen(connector->error_msg); + swoole_mysql_coro_onConnect(client TSRMLS_CC); + return SW_OK; +#endif + break; + } + default: + { + ret = mysql_get_result(connector, SWSTRING_CURRENT_VL(buffer)); + if (ret < 0) + { + _error: + swoole_mysql_coro_onConnect(client TSRMLS_CC); + } + else if (ret > 0) + { + swString_clear(buffer); + client->handshake = SW_MYSQL_HANDSHAKE_COMPLETED; + swoole_mysql_coro_onConnect(client TSRMLS_CC); + } + // else recv again + } + } + + return SW_OK; +} + +static int swoole_mysql_coro_onRead(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + mysql_client *client = event->socket->object; + if (client->handshake != SW_MYSQL_HANDSHAKE_COMPLETED) + { + return swoole_mysql_coro_onHandShake(client TSRMLS_CC); + } + + if (client->timer) + { + swTimer_del(&SwooleG.timer, client->timer); + client->timer = NULL; + } + + int sock = event->fd; + int ret; + + zval *zobject = client->object; + + swString *buffer; + if (client->cmd == SW_MYSQL_COM_STMT_EXECUTE) + { + if (client->statement->buffer == NULL) + { + // statement save the response data itself + client->statement->buffer = swString_new(SW_BUFFER_SIZE_BIG); + } + buffer = client->statement->buffer; + } + else + { + buffer = client->buffer; + } + + zval *retval = NULL; + zval *result = NULL; + + while(1) + { + ret = recv(sock, buffer->str + buffer->length, buffer->size - buffer->length, 0); + swTraceLog(SW_TRACE_MYSQL_CLIENT, "recv-ret=%d, buffer-length=%d.", ret, buffer->length); + if (ret < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + switch (swConnection_error(errno)) + { + case SW_ERROR: + swSysError("Read from socket[%d] failed.", event->fd); + return SW_ERR; + case SW_CLOSE: + goto close_fd; + case SW_WAIT: + if (client->check_offset == buffer->length) + { + return SW_OK; + } + else + { + // have already check all of the data + goto parse_response; + } + default: + return SW_ERR; + } + } + } + else if (ret == 0) + { + close_fd: + if (client->state == SW_MYSQL_STATE_READ_END) + { + goto parse_response; + } + + + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_errno"), 111 TSRMLS_CC); + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("connect_error"), "connection close by peer" TSRMLS_CC); + if (client->connected) + { + client->connected = 0; + zend_update_property_long(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("errno"), 2006 TSRMLS_CC); + zend_update_property_string(swoole_mysql_coro_class_entry_ptr, zobject, ZEND_STRL("error"), "MySQL server has gone away" TSRMLS_CC); + } + swoole_mysql_coro_close(zobject); + + if (!client->cid) + { + return SW_OK; + } + + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 0); + if (client->defer && !client->suspending) + { + client->iowait = SW_MYSQL_CORO_STATUS_DONE; + client->result = result; + return SW_OK; + } + client->suspending = 0; + + php_context *sw_current_context = swoole_get_property(zobject, 0); + ret = coro_resume(sw_current_context, result, &retval); + sw_zval_free(result); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + client->state = SW_MYSQL_STATE_QUERY; + return SW_OK; + } + else + { + buffer->length += ret; + //recv again + if (buffer->length == buffer->size) + { + if (swString_extend(buffer, buffer->size * 2) < 0) + { + swoole_php_fatal_error(E_ERROR, "malloc failed."); + reactor->del(SwooleG.main_reactor, event->fd); + } + continue; + } + + parse_response: + + // always check that is package complete + // and maybe more responses has already received in buffer, we check it now. + if (client->cmd == SW_MYSQL_COM_STMT_EXECUTE && mysql_is_over(client) != SW_OK) + { + // the **last** sever status flag shows that more results exist but we hasn't received. + swTraceLog(SW_TRACE_MYSQL_CLIENT, "need more"); + continue; + } + + if (swoole_mysql_coro_parse_response(client, &result, 0) != SW_OK) + { + return SW_OK;//parse error + } + swoole_mysql_coro_parse_end(client, buffer); // ending tidy up + + + if (client->defer && !client->suspending) + { + client->iowait = SW_MYSQL_CORO_STATUS_DONE; + client->result = result; + return SW_OK; + } + client->suspending = 0; + client->iowait = SW_MYSQL_CORO_STATUS_READY; + client->cid = 0; + + php_context *sw_current_context = swoole_get_property(zobject, 0); + ret = coro_resume(sw_current_context, result, &retval); + if (result) + { + sw_zval_free(result); + } + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; + } + } + return SW_OK; +} + +#endif diff --git a/vendor/swoole/swoole_postgresql_coro.c b/vendor/swoole/swoole_postgresql_coro.c new file mode 100755 index 0000000..7e79626 --- /dev/null +++ b/vendor/swoole/swoole_postgresql_coro.c @@ -0,0 +1,1052 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Zhenyu Wu <936321732@qq.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#ifdef SW_USE_POSTGRESQL +#include "swoole_postgresql_coro.h" +#include "swoole_coroutine.h" + +static PHP_METHOD(swoole_postgresql_coro, __construct); +static PHP_METHOD(swoole_postgresql_coro, __destruct); +static PHP_METHOD(swoole_postgresql_coro, connect); +static PHP_METHOD(swoole_postgresql_coro, query); +static PHP_METHOD(swoole_postgresql_coro, fetchAll); +static PHP_METHOD(swoole_postgresql_coro, affectedRows); +static PHP_METHOD(swoole_postgresql_coro, numRows); +static PHP_METHOD(swoole_postgresql_coro,metaData); +static PHP_METHOD(swoole_postgresql_coro,fetchObject); +static PHP_METHOD(swoole_postgresql_coro,fetchAssoc); +static PHP_METHOD(swoole_postgresql_coro,fetchArray); +static PHP_METHOD(swoole_postgresql_coro,fetchRow); + +static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_type, int into_object); + +static void _destroy_pgsql_link(zend_resource *rsrc); +static void _free_result(zend_resource *rsrc); +static int swoole_pgsql_coro_onRead(swReactor *reactor, swEvent *event); +static int swoole_pgsql_coro_onWrite(swReactor *reactor, swEvent *event); +static int swoole_pgsql_coro_onError(swReactor *reactor, swEvent *event); +int php_pgsql_result2array(PGresult *pg_result, zval *ret_array, long result_type); +static int swoole_postgresql_coro_close(pg_object *pg_object); +static int query_result_parse(pg_object *pg_object); +static int meta_data_result_parse(pg_object *pg_object); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, -1) + ZEND_ARG_INFO(0, conninfo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_query, 0, 0, 0) + ZEND_ARG_INFO(0, query) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_all, 0, 0, 0) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_affected_rows, 0, 0, 0) + ZEND_ARG_INFO(0, result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_num_rows, 0, 0, 0) + ZEND_ARG_INFO(0, result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_meta_data, 0, 0, 1) + ZEND_ARG_INFO(0, table_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_row, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row) + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_assoc, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_array, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row) + ZEND_ARG_INFO(0, result_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_fetch_object, 0, 0, 1) + ZEND_ARG_INFO(0, result) + ZEND_ARG_INFO(0, row) + ZEND_ARG_INFO(0, class_name) + ZEND_ARG_INFO(0, l) + ZEND_ARG_INFO(0, ctor_params) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_postgresql_coro_methods[] = +{ + PHP_ME(swoole_postgresql_coro, __construct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_postgresql_coro, connect, arginfo_pg_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, query, arginfo_pg_query, ZEND_ACC_PUBLIC ) + PHP_ME(swoole_postgresql_coro, fetchAll, arginfo_pg_fetch_all, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, affectedRows, arginfo_pg_affected_rows, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, numRows, arginfo_pg_num_rows, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, metaData, arginfo_pg_meta_data, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, fetchObject, arginfo_pg_fetch_object, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, fetchAssoc, arginfo_pg_fetch_assoc, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, fetchArray, arginfo_pg_fetch_array, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, fetchRow, arginfo_pg_fetch_row, ZEND_ACC_PUBLIC) + PHP_ME(swoole_postgresql_coro, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FE_END +}; + +static zend_class_entry swoole_postgresql_coro_ce; +static zend_class_entry *swoole_postgresql_coro_class_entry_ptr; +static int le_link , le_result; + +void swoole_postgresql_coro_init(int module_number TSRMLS_DC) +{ + + INIT_CLASS_ENTRY(swoole_postgresql_coro_ce, "Swoole\\Coroutine\\PostgreSQL", swoole_postgresql_coro_methods); + le_link = zend_register_list_destructors_ex(_destroy_pgsql_link, NULL, "pgsql link", module_number); + le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); + swoole_postgresql_coro_class_entry_ptr = zend_register_internal_class(&swoole_postgresql_coro_ce TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\PostgreSQL", swoole_postgresql_coro_class_entry_ptr); + } + + REGISTER_LONG_CONSTANT("SW_PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SW_PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SW_PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT); + +} + +static PHP_METHOD(swoole_postgresql_coro, __construct) +{ + coro_check(TSRMLS_C); + pg_object *pg; + pg = emalloc(sizeof(pg_object)); + bzero(pg,sizeof(pg_object)); + pg -> object = getThis(); + swoole_set_object(getThis(), pg); +} + +static PHP_METHOD(swoole_postgresql_coro, connect) +{ + zval *conninfo; + PGconn * pgsql; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(conninfo) + ZEND_PARSE_PARAMETERS_END(); + + pgsql = PQconnectStart(Z_STRVAL_P(conninfo)); + int fd = PQsocket(pgsql); + + php_swoole_check_reactor(); + + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_POSTGRESQL)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_POSTGRESQL | SW_EVENT_READ, swoole_pgsql_coro_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_POSTGRESQL | SW_EVENT_WRITE, swoole_pgsql_coro_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_POSTGRESQL | SW_EVENT_ERROR, swoole_pgsql_coro_onError); + } + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, fd, PHP_SWOOLE_FD_POSTGRESQL | SW_EVENT_WRITE) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event_add failed."); + RETURN_FALSE; + } + + pg_object *pg_object = swoole_get_object(getThis()); + pg_object->fd = fd; + pg_object->conn = pgsql; + pg_object->status = CONNECTION_STARTED; + + PQsetnonblocking(pgsql , 1); + + if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) + { + swWarn("Unable to connect to PostgreSQL server: [%s]",pgsql); + if (pgsql) + { + PQfinish(pgsql); + } + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, fd); + _socket->object = pg_object; + _socket->active = 0; + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + if (!sw_current_context) + { + sw_current_context = emalloc(sizeof(php_context)); + swoole_set_property(getThis(), 0, sw_current_context); + } + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; + sw_current_context->onTimeout = NULL; + #if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = getThis(); + #else + sw_current_context->coro_params = *getThis(); + #endif + + //TODO: add the timeout + /* + if (pg_object->timeout > 0) + { + php_swoole_check_timer((int) (ph_object->timeout * 1000)); + pg_object->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, sw_current_context, swoole_pgsql_coro_onTimeout); + }*/ + coro_save(sw_current_context); + coro_yield(); + +} + +static int swoole_pgsql_coro_onWrite(swReactor *reactor, swEvent *event) +{ + char *errMsg; +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + if (event->socket->active) + { + return swReactor_onWrite(SwooleG.main_reactor, event); + } + + socklen_t len = sizeof(SwooleG.error); + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &SwooleG.error, &len) < 0) + { + swWarn("getsockopt(%d) failed. Error: %s[%d]", event->fd, strerror(errno), errno); + return SW_ERR; + } + + pg_object *pg_object = event->socket->object; + + + // wait the connection ok + ConnStatusType status = PQstatus(pg_object->conn); + if(status != CONNECTION_OK){ + PostgresPollingStatusType flag = PGRES_POLLING_WRITING; + for (;;) + { + switch (flag) + { + case PGRES_POLLING_OK: + break; + case PGRES_POLLING_READING: + break; + case PGRES_POLLING_WRITING: + break; + case PGRES_POLLING_FAILED: + errMsg = PQerrorMessage(pg_object->conn); + swWarn("error:[%s]",errMsg); + break; + default: + break; + } + + flag = PQconnectPoll(pg_object->conn); + if(flag == PGRES_POLLING_OK ) + { + break; + } + if(flag == PGRES_POLLING_FAILED ) + { + errMsg = PQerrorMessage(pg_object->conn); + swWarn("error:[%s] please cofirm that the connection configuration is correct \n",errMsg); + break; + } + } + + } + //listen read event + SwooleG.main_reactor->set(SwooleG.main_reactor, event->fd, PHP_SWOOLE_FD_POSTGRESQL | SW_EVENT_READ); + //connected + event->socket->active = 1; + + php_context *sw_current_context = swoole_get_property(pg_object->object, 0); + + zval *retval = NULL; + zval return_value; + ZVAL_RES(&return_value, zend_register_resource(pg_object->conn, le_link)); + + int ret = coro_resume(sw_current_context, &return_value, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; +} + +static int swoole_pgsql_coro_onRead(swReactor *reactor, swEvent *event) +{ + pg_object *pg_object = (event->socket->object); + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + switch (pg_object->request_type) + { + case NORMAL_QUERY: + query_result_parse(pg_object); + break; + case META_DATA: + meta_data_result_parse(pg_object); + break; + } + + return SW_OK; +} + +static int meta_data_result_parse(pg_object *pg_object) +{ + + int i, num_rows; + zval elem; + PGresult *pg_result; + zend_bool extended=0; + pg_result =PQgetResult(pg_object->conn); + + if (PQresultStatus(pg_result) != PGRES_TUPLES_OK || (num_rows = PQntuples(pg_result)) == 0) + { + php_error_docref(NULL, E_WARNING, "Table doesn't exists"); + return 0; + } + + zval return_value; + array_init(&return_value); + zval * retval = NULL; + array_init(&elem); + for (i = 0; i < num_rows; i++) + { + pg_object->result = pg_result; + char *name; + /* pg_attribute.attnum */ + add_assoc_long_ex(&elem, "num", sizeof("num") - 1, atoi(PQgetvalue(pg_result, i, 1))); + /* pg_type.typname */ + add_assoc_string_ex(&elem, "type", sizeof("type") - 1, PQgetvalue(pg_result, i, 2)); + /* pg_attribute.attlen */ + add_assoc_long_ex(&elem, "len", sizeof("len") - 1, atoi(PQgetvalue(pg_result, i, 3))); + /* pg_attribute.attnonull */ + add_assoc_bool_ex(&elem, "not null", sizeof("not null") - 1, !strcmp(PQgetvalue(pg_result, i, 4), "t")); + /* pg_attribute.atthasdef */ + add_assoc_bool_ex(&elem, "has default", sizeof("has default") - 1, + !strcmp(PQgetvalue(pg_result, i, 5), "t")); + /* pg_attribute.attndims */ + add_assoc_long_ex(&elem, "array dims", sizeof("array dims") - 1, atoi(PQgetvalue(pg_result, i, 6))); + /* pg_type.typtype */ + add_assoc_bool_ex(&elem, "is enum", sizeof("is enum") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "e")); + if (extended) { + /* pg_type.typtype */ + add_assoc_bool_ex(&elem, "is base", sizeof("is base") - 1, !strcmp(PQgetvalue(pg_result, i, 7), "b")); + add_assoc_bool_ex(&elem, "is composite", sizeof("is composite") - 1, + !strcmp(PQgetvalue(pg_result, i, 7), "c")); + add_assoc_bool_ex(&elem, "is pesudo", sizeof("is pesudo") - 1, + !strcmp(PQgetvalue(pg_result, i, 7), "p")); + /* pg_description.description */ + add_assoc_string_ex(&elem, "description", sizeof("description") - 1, PQgetvalue(pg_result, i, 8)); + } + /* pg_attribute.attname */ + name = PQgetvalue(pg_result, i, 0); + add_assoc_zval(&return_value, name, &elem); + + } + php_context *sw_current_context = swoole_get_property(pg_object->object, 0); + int ret = coro_resume(sw_current_context, &return_value, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + zval_ptr_dtor(&return_value); + zval_ptr_dtor(&elem); + return SW_OK; +} + + +static int query_result_parse(pg_object *pg_object) +{ + + PGresult *pgsql_result; + + ExecStatusType status; + + + int error = 0; + char *errMsg; + int ret, res; + zval *retval = NULL; + zval return_value; + php_context *sw_current_context = swoole_get_property(pg_object->object, 0); + + pgsql_result =PQgetResult(pg_object->conn); + + status = PQresultStatus(pgsql_result); + + switch (status) { + case PGRES_EMPTY_QUERY: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + errMsg = PQerrorMessage(pg_object->conn); + swWarn("Query failed: [%s]",errMsg); + + PQclear(pgsql_result); + ZVAL_FALSE(&return_value); + ret = coro_resume(sw_current_context, &return_value, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + swoole_postgresql_coro_close(pg_object); + break; + case PGRES_COMMAND_OK: /* successful command that did not return rows */ + default: + pg_object->result = pgsql_result; + pg_object->row = 0; + /* Wait to finish sending buffer */ + res = PQflush(pg_object->conn); + + ZVAL_RES(&return_value, zend_register_resource(pg_object, le_result)); + ret = coro_resume(sw_current_context, &return_value, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + PQclear(pgsql_result); + + if (error != 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event->onError[1]: socket error. Error: %s [%d]", strerror(error), error); + } + + break; + } + + return SW_OK; +} + +static PHP_METHOD(swoole_postgresql_coro, query) +{ + zval *query; + PGconn *pgsql; + PGresult *pgsql_result; + + ZEND_PARSE_PARAMETERS_START(1,1) + Z_PARAM_ZVAL(query) + ZEND_PARSE_PARAMETERS_END(); + + pg_object *pg_object = swoole_get_object(getThis()); + pg_object->request_type = NORMAL_QUERY; + pgsql = pg_object -> conn; + + while ((pgsql_result = PQgetResult(pgsql))) + { + PQclear(pgsql_result); + } + + int ret = PQsendQuery(pgsql, Z_STRVAL_P(query)); + if(ret == 0) + { + char * errMsg = PQerrorMessage(pgsql); + swWarn("error:[%s]",errMsg); + + } + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; + sw_current_context->onTimeout = NULL; + #if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = getThis(); + #else + sw_current_context->coro_params = *getThis(); + #endif + + //TODO: add the timeout + /* + if (pg_object->timeout > 0) + { + php_swoole_check_timer((int) (ph_object->timeout * 1000)); + pg_object->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, sw_current_context, swoole_pgsql_coro_onTimeout); + }*/ + coro_save(sw_current_context); + coro_yield(); +} + +/* {{{ php_pgsql_result2array + */ +int swoole_pgsql_result2array(PGresult *pg_result, zval *ret_array, long result_type) +{ + zval row; + char *field_name; + size_t num_fields; + int pg_numrows, pg_row; + uint32_t i; + assert(Z_TYPE_P(ret_array) == IS_ARRAY); + + if ((pg_numrows = PQntuples(pg_result)) <= 0) + { + return FAILURE; + } + for (pg_row = 0; pg_row < pg_numrows; pg_row++) + { + array_init(&row); + for (i = 0, num_fields = PQnfields(pg_result); i < num_fields; i++) + { + field_name = PQfname(pg_result, i); + if (PQgetisnull(pg_result, pg_row, i)) + { + if (result_type & PGSQL_ASSOC) + { + add_assoc_null(&row, field_name); + } + if (result_type & PGSQL_NUM) + { + add_next_index_null(&row); + } + } + else + { + char *element = PQgetvalue(pg_result, pg_row, i); + if (element) + { + const size_t element_len = strlen(element); + if (result_type & PGSQL_ASSOC) + { + add_assoc_stringl(&row, field_name, element, element_len); + } + if (result_type & PGSQL_NUM) + { + add_next_index_stringl(&row, element, element_len); + } + } + } + } + add_index_zval(ret_array, pg_row, &row); + } + return SUCCESS; +} + +static PHP_METHOD(swoole_postgresql_coro, fetchAll) +{ + zval *result; + PGresult *pgsql_result; + pg_object *object; + zend_long result_type = PGSQL_ASSOC; + + ZEND_PARSE_PARAMETERS_START(1,2) + Z_PARAM_RESOURCE(result) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(result_type) + ZEND_PARSE_PARAMETERS_END(); + + if ((object = (pg_object *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) + { + RETURN_FALSE; + } + + pgsql_result = object->result; + array_init(return_value); + if (swoole_pgsql_result2array(pgsql_result, return_value, result_type) == FAILURE) + { + zval_dtor(return_value); + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_postgresql_coro,affectedRows) +{ + zval *result; + PGresult *pgsql_result; + pg_object *object; + + ZEND_PARSE_PARAMETERS_START(1,1) + Z_PARAM_RESOURCE(result) + ZEND_PARSE_PARAMETERS_END(); + + if ((object = (pg_object *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) + { + RETURN_FALSE; + } + + pgsql_result = object->result; + RETVAL_LONG(atoi(PQcmdTuples(pgsql_result))); +} + + +//query's num +static PHP_METHOD(swoole_postgresql_coro,numRows) +{ + zval *result; + PGresult *pgsql_result; + pg_object *object; + + ZEND_PARSE_PARAMETERS_START(1,1) + Z_PARAM_RESOURCE(result) + ZEND_PARSE_PARAMETERS_END(); + + if ((object = (pg_object *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) + { + RETURN_FALSE; + } + + pgsql_result = object->result; + RETVAL_LONG(PQntuples(pgsql_result)); +} + +static PHP_METHOD(swoole_postgresql_coro,metaData) +{ + + char *table_name; + size_t table_name_len; + zend_bool extended=0; + PGconn *pgsql; + + PGresult *pg_result; + char *src, *tmp_name, *tmp_name2 = NULL; + char *escaped; + smart_str querystr = {0}; + size_t new_len; + + + ZEND_PARSE_PARAMETERS_START(1,1) + Z_PARAM_STRING(table_name, table_name_len) + ZEND_PARSE_PARAMETERS_END(); + + pg_object *pg_object = swoole_get_object(getThis()); + pg_object->request_type = META_DATA; + pgsql = pg_object -> conn; + + + while ((pg_result = PQgetResult(pgsql))) + { + PQclear(pg_result); + } + + if (!*table_name) + { + php_error_docref(NULL, E_WARNING, "The table name must be specified"); + RETURN_FALSE; + } + + src = estrdup(table_name); + tmp_name = php_strtok_r(src, ".", &tmp_name2); + if (!tmp_name) + { + efree(src); + php_error_docref(NULL, E_WARNING, "The table name must be specified"); + RETURN_FALSE; + } + if (!tmp_name2 || !*tmp_name2) + { + /* Default schema */ + tmp_name2 = tmp_name; + tmp_name = "public"; + } + + if (extended) + { + smart_str_appends(&querystr, + "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotNULL, a.atthasdef, a.attndims, t.typtype, " + "d.description " + "FROM pg_class as c " + " JOIN pg_attribute a ON (a.attrelid = c.oid) " + " JOIN pg_type t ON (a.atttypid = t.oid) " + " JOIN pg_namespace n ON (c.relnamespace = n.oid) " + " LEFT JOIN pg_description d ON (d.objoid=a.attrelid AND d.objsubid=a.attnum AND c.oid=d.objoid) " + "WHERE a.attnum > 0 AND c.relname = '"); + } + else + { + smart_str_appends(&querystr, + "SELECT a.attname, a.attnum, t.typname, a.attlen, a.attnotnull, a.atthasdef, a.attndims, t.typtype " + "FROM pg_class as c " + " JOIN pg_attribute a ON (a.attrelid = c.oid) " + " JOIN pg_type t ON (a.atttypid = t.oid) " + " JOIN pg_namespace n ON (c.relnamespace = n.oid) " + "WHERE a.attnum > 0 AND c.relname = '"); + } + escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1); + new_len = PQescapeStringConn(pgsql, escaped, tmp_name2, strlen(tmp_name2), NULL); + if (new_len) + { + smart_str_appendl(&querystr, escaped, new_len); + } + efree(escaped); + + smart_str_appends(&querystr, "' AND n.nspname = '"); + escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1); + new_len = PQescapeStringConn(pgsql, escaped, tmp_name, strlen(tmp_name), NULL); + if (new_len) + { + smart_str_appendl(&querystr, escaped, new_len); + } + efree(escaped); + + smart_str_appends(&querystr, "' ORDER BY a.attnum;"); + smart_str_0(&querystr); + efree(src); + + //pg_result = PQexec(pgsql, ZSTR_VAL(querystr.s)); + + + int ret = PQsendQuery(pgsql, ZSTR_VAL(querystr.s)); + if(ret == 0) + { + char * errMsg = PQerrorMessage(pgsql); + swWarn("error:[%s]",errMsg); + + } + smart_str_free(&querystr); + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; + sw_current_context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = getThis(); +#else + sw_current_context->coro_params = *getThis(); +#endif + /* + if (redis->timeout > 0) + { + php_swoole_check_timer((int) (redis->timeout * 1000)); + redis->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, sw_current_context, swoole_redis_coro_onTimeout); + }*/ + coro_save(sw_current_context); + coro_yield(); + +} + +/* {{{ void php_pgsql_fetch_hash */ +static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_type, int into_object) +{ + zval *result, *zrow = NULL; + PGresult *pgsql_result; + pg_object *pg_result; + int i, num_fields, pgsql_row, use_row; + zend_long row = -1; + char *field_name; + zval *ctor_params = NULL; + zend_class_entry *ce = NULL; + + if (into_object) + { + zend_string *class_name = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!Sz", &result, &zrow, &class_name, &ctor_params) == FAILURE) + { + return; + } + if (!class_name) + { + ce = zend_standard_class_def; + } else { + ce = zend_fetch_class(class_name, ZEND_FETCH_CLASS_AUTO); + } + if (!ce) + { + php_error_docref(NULL, E_WARNING, "Could not find class '%s'", ZSTR_VAL(class_name)); + return; + } + result_type = PGSQL_ASSOC; + } + else + { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|z!l", &result, &zrow, &result_type) == FAILURE) + { + return; + } + } + if (zrow == NULL) + { + row = -1; + } else { + convert_to_long(zrow); + row = Z_LVAL_P(zrow); + if (row < 0) { + php_error_docref(NULL, E_WARNING, "The row parameter must be greater or equal to zero"); + RETURN_FALSE; + } + } + use_row = ZEND_NUM_ARGS() > 1 && row != -1; + + if (!(result_type & PGSQL_BOTH)) + { + php_error_docref(NULL, E_WARNING, "Invalid result type"); + RETURN_FALSE; + } + + if ((pg_result = (pg_object *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) + { + RETURN_FALSE; + } + + pgsql_result = pg_result->result; + + if (use_row) + { + if (row < 0 || row >= PQntuples(pgsql_result)) + { + php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT, + row, Z_LVAL_P(result)); + RETURN_FALSE; + } + pgsql_row = (int)row; + pg_result->row = pgsql_row; + } + else + { + /* If 2nd param is NULL, use internal row counter to access next row */ + pgsql_row = pg_result->row; + if (pgsql_row < 0 || pgsql_row >= PQntuples(pgsql_result)) { + RETURN_FALSE; + } + pg_result->row++; + } + + array_init(return_value); + for (i = 0, num_fields = PQnfields(pgsql_result); i < num_fields; i++) + { + if (PQgetisnull(pgsql_result, pgsql_row, i)) { + if (result_type & PGSQL_NUM) + { + add_index_null(return_value, i); + } + if (result_type & PGSQL_ASSOC) + { + field_name = PQfname(pgsql_result, i); + add_assoc_null(return_value, field_name); + } + } + else + { + char *element = PQgetvalue(pgsql_result, pgsql_row, i); + if (element) + { + const size_t element_len = strlen(element); + + if (result_type & PGSQL_NUM) + { + add_index_stringl(return_value, i, element, element_len); + } + + if (result_type & PGSQL_ASSOC) + { + field_name = PQfname(pgsql_result, i); + add_assoc_stringl(return_value, field_name, element, element_len); + } + } + } + } + + if (into_object) + { + zval dataset; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval retval; + + ZVAL_COPY_VALUE(&dataset, return_value); + object_and_properties_init(return_value, ce, NULL); + if (!ce->default_properties_count && !ce->__set) + { + Z_OBJ_P(return_value)->properties = Z_ARR(dataset); + } + else + { + zend_merge_properties(return_value, Z_ARRVAL(dataset)); + zval_ptr_dtor(&dataset); + } + + if (ce->constructor) + { + fci.size = sizeof(fci); + ZVAL_UNDEF(&fci.function_name); + fci.object = Z_OBJ_P(return_value); + fci.retval = &retval; + fci.params = NULL; + fci.param_count = 0; + fci.no_separation = 1; + + if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) + { + if (zend_fcall_info_args(&fci, ctor_params) == FAILURE) { + /* Two problems why we throw exceptions here: PHP is typeless + * and hence passing one argument that's not an array could be + * by mistake and the other way round is possible, too. The + * single value is an array. Also we'd have to make that one + * argument passed by reference. + */ + zend_throw_exception(zend_ce_exception, "Parameter ctor_params must be an array", 0); + return; + } + } + + fcc.initialized = 1; + fcc.function_handler = ce->constructor; +#if PHP_MINOR_VERSION > 0 + fcc.calling_scope = zend_get_executed_scope(); +#else + fcc.calling_scope = EG(scope); +#endif + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object = Z_OBJ_P(return_value); + + if (zend_call_function(&fci, &fcc) == FAILURE) + { + zend_throw_exception_ex(zend_ce_exception, 0, "Could not execute %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name)); + } else + { + zval_ptr_dtor(&retval); + } + if (fci.params) + { + efree(fci.params); + } + } + else if (ctor_params) + { + zend_throw_exception_ex(zend_ce_exception, 0, "Class %s does not have a constructor hence you cannot use ctor_params", ZSTR_VAL(ce->name)); + } + } +} +/* }}} */ + +/* {{{ proto array fetchRow(resource result [, int row [, int result_type]]) + Get a row as an enumerated array */ +static PHP_METHOD(swoole_postgresql_coro,fetchRow) +{ + php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_NUM, 0); +} +/* }}} */ + +/* {{{ proto array fetchAssoc(resource result [, int row]) + Fetch a row as an assoc array */ +static PHP_METHOD(swoole_postgresql_coro,fetchAssoc) +{ + /* pg_fetch_assoc() is added from PHP 4.3.0. It should raise error, when + there is 3rd parameter */ + if (ZEND_NUM_ARGS() > 2) + WRONG_PARAM_COUNT; + php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 0); +} +/* }}} */ + +/* {{{ proto array fetchArray(resource result [, int row [, int result_type]]) + Fetch a row as an array */ +static PHP_METHOD(swoole_postgresql_coro,fetchArray) +{ + php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_BOTH, 0); +} +/* }}} */ + +/* {{{ proto object fetchObject(resource result [, int row [, string class_name [, NULL|array ctor_params]]]) + Fetch a row as an object */ +static PHP_METHOD(swoole_postgresql_coro,fetchObject) +{ + /* fetchObject() allowed result_type used to be. 3rd parameter + must be allowed for compatibility */ + php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, PGSQL_ASSOC, 1); +} + +/* {{{ _destroy_pgsql_link + */ +static void _destroy_pgsql_link(zend_resource *rsrc) +{ + PGconn *link = (PGconn *)rsrc->ptr; + PGresult *res; + + while ((res = PQgetResult(link))) + { + PQclear(res); + } + PQfinish(link); +} + +static void _free_result(zend_resource *rsrc) +{ + pg_object *pg_result = (pg_object *)rsrc->ptr; + + efree(pg_result); +} + +static int swoole_pgsql_coro_onError(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + pg_object *pg_object = (event->socket->object); + zval *retval = NULL, *result; + zval *zobject = pg_object->object; + + swoole_postgresql_coro_close(pg_object); + + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 0); + + php_context *sw_current_context = swoole_get_property(zobject, 0); + int ret = coro_resume(sw_current_context, result, &retval); + sw_zval_free(result); + + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + + return SW_OK; +} + +static PHP_METHOD(swoole_postgresql_coro, __destruct) +{ + pg_object *pg_object = swoole_get_object(getThis()); + swoole_postgresql_coro_close(pg_object); + +} + +static int swoole_postgresql_coro_close(pg_object *pg_object) +{ + if (!pg_object) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_postgresql_coro."); + return FAILURE; + } + SwooleG.main_reactor->del(SwooleG.main_reactor, pg_object->fd); + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, pg_object->fd); + _socket->object = NULL; + _socket->active = 0; + efree(pg_object); + if(pg_object->object) + { + php_context *sw_current_context = swoole_get_property(pg_object->object, 0); + efree(sw_current_context); + } + + return SUCCESS; +} +#endif +#endif diff --git a/vendor/swoole/swoole_postgresql_coro.h b/vendor/swoole/swoole_postgresql_coro.h new file mode 100755 index 0000000..7eb747f --- /dev/null +++ b/vendor/swoole/swoole_postgresql_coro.h @@ -0,0 +1,41 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Zhenyu Wu <936321732@qq.com> | + +----------------------------------------------------------------------+ + */ + +#include <libpq-fe.h> + +typedef enum +{ + NORMAL_QUERY, + META_DATA +} query_type; + +typedef struct _php_pgsql_object { + PGconn *conn; + PGresult *result; + zval *object; + ConnStatusType status; + query_type request_type; + int row; + int fd; + double timeout; + swTimer_node *timer; +} pg_object; + + + +#define PGSQL_ASSOC 1<<0 +#define PGSQL_NUM 1<<1 +#define PGSQL_BOTH (PGSQL_ASSOC|PGSQL_NUM) diff --git a/vendor/swoole/swoole_process.c b/vendor/swoole/swoole_process.c new file mode 100755 index 0000000..f4f138d --- /dev/null +++ b/vendor/swoole/swoole_process.c @@ -0,0 +1,1205 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#if __APPLE__ +// Fix warning: 'daemon' is deprecated: first deprecated in macOS 10.5 - Use posix_spawn APIs instead. [-Wdeprecated-declarations] +#define daemon yes_we_know_that_daemon_is_deprecated_in_os_x_10_5_thankyou +#endif +#include "php_swoole.h" +#include "php_streams.h" +#include "php_network.h" + +#if __APPLE__ +#undef daemon +extern int daemon(int, int); +#endif +static PHP_METHOD(swoole_process, __construct); +static PHP_METHOD(swoole_process, __destruct); +static PHP_METHOD(swoole_process, useQueue); +static PHP_METHOD(swoole_process, statQueue); +static PHP_METHOD(swoole_process, freeQueue); +static PHP_METHOD(swoole_process, pop); +static PHP_METHOD(swoole_process, push); +static PHP_METHOD(swoole_process, kill); +static PHP_METHOD(swoole_process, signal); +static PHP_METHOD(swoole_process, alarm); +static PHP_METHOD(swoole_process, wait); +static PHP_METHOD(swoole_process, daemon); +#ifdef HAVE_CPU_AFFINITY +static PHP_METHOD(swoole_process, setaffinity); +#endif +static PHP_METHOD(swoole_process, setTimeout); +static PHP_METHOD(swoole_process, setBlocking); +static PHP_METHOD(swoole_process, start); +static PHP_METHOD(swoole_process, write); +static PHP_METHOD(swoole_process, read); +static PHP_METHOD(swoole_process, close); +static PHP_METHOD(swoole_process, exit); +static PHP_METHOD(swoole_process, exec); + +static void php_swoole_onSignal(int signo); +static void free_signal_callback(void* data); + +static uint32_t php_swoole_worker_round_id = 0; +static zval *signal_callback[SW_SIGNO_MAX]; +static zend_class_entry swoole_process_ce; +zend_class_entry *swoole_process_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_construct, 0, 0, 1) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, redirect_stdin_and_stdout) + ZEND_ARG_INFO(0, pipe_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_wait, 0, 0, 0) + ZEND_ARG_INFO(0, blocking) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_signal, 0, 0, 2) + ZEND_ARG_INFO(0, signal_no) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_alarm, 0, 0, 1) + ZEND_ARG_INFO(0, usec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_kill, 0, 0, 1) + ZEND_ARG_INFO(0, pid) + ZEND_ARG_INFO(0, signal_no) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_daemon, 0, 0, 0) + ZEND_ARG_INFO(0, nochdir) + ZEND_ARG_INFO(0, noclose) +ZEND_END_ARG_INFO() + +#ifdef HAVE_CPU_AFFINITY +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_setaffinity, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, cpu_settings, 0) +ZEND_END_ARG_INFO() +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_setTimeout, 0, 0, 1) + ZEND_ARG_INFO(0, seconds) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_setBlocking, 0, 0, 1) + ZEND_ARG_INFO(0, blocking) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_useQueue, 0, 0, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_write, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_read, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pop, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_exit, 0, 0, 0) + ZEND_ARG_INFO(0, exit_code) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_exec, 0, 0, 2) + ZEND_ARG_INFO(0, exec_file) + ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_name, 0, 0, 1) + ZEND_ARG_INFO(0, process_name) +ZEND_END_ARG_INFO() + +#define MSGQUEUE_NOWAIT (1 << 8) + +static const zend_function_entry swoole_process_methods[] = +{ + PHP_ME(swoole_process, __construct, arginfo_swoole_process_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_process, __destruct, arginfo_swoole_process_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_process, wait, arginfo_swoole_process_wait, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_process, signal, arginfo_swoole_process_signal, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_process, alarm, arginfo_swoole_process_alarm, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_process, kill, arginfo_swoole_process_kill, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_process, daemon, arginfo_swoole_process_daemon, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) +#ifdef HAVE_CPU_AFFINITY + PHP_ME(swoole_process, setaffinity, arginfo_swoole_process_setaffinity, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) +#endif + PHP_ME(swoole_process, setTimeout, arginfo_swoole_process_setTimeout, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, setBlocking, arginfo_swoole_process_setBlocking, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, useQueue, arginfo_swoole_process_useQueue, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, statQueue, arginfo_swoole_process_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, freeQueue, arginfo_swoole_process_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, start, arginfo_swoole_process_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, write, arginfo_swoole_process_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, close, arginfo_swoole_process_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, read, arginfo_swoole_process_read, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, push, arginfo_swoole_process_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, pop, arginfo_swoole_process_pop, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, exit, arginfo_swoole_process_exit, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process, exec, arginfo_swoole_process_exec, ZEND_ACC_PUBLIC) + PHP_FALIAS(name, swoole_set_process_name, arginfo_swoole_process_name) + PHP_FE_END +}; + +void swoole_process_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_process_ce, "swoole_process", "Swoole\\Process", swoole_process_methods); + swoole_process_class_entry_ptr = zend_register_internal_class(&swoole_process_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_process, "Swoole\\Process"); + + zend_declare_class_constant_long(swoole_process_class_entry_ptr, SW_STRL("IPC_NOWAIT")-1, MSGQUEUE_NOWAIT TSRMLS_CC); + zend_declare_class_constant_long(swoole_process_class_entry_ptr, SW_STRL("PIPE_MASTER")-1, SW_PIPE_CLOSE_MASTER TSRMLS_CC); + zend_declare_class_constant_long(swoole_process_class_entry_ptr, SW_STRL("PIPE_WORKER")-1, SW_PIPE_CLOSE_WORKER TSRMLS_CC); + zend_declare_class_constant_long(swoole_process_class_entry_ptr, SW_STRL("PIPE_READ")-1, SW_PIPE_CLOSE_READ TSRMLS_CC); + zend_declare_class_constant_long(swoole_process_class_entry_ptr, SW_STRL("PIPE_WRITE")-1, SW_PIPE_CLOSE_WRITE TSRMLS_CC); + bzero(signal_callback, sizeof(signal_callback)); + + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("pipe")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("callback")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("msgQueueId")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("msgQueueKey")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("pid")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_process_class_entry_ptr, SW_STRL("id")-1, ZEND_ACC_PUBLIC TSRMLS_CC); + + /** + * 31 signal constants + */ + zval *zpcntl; + if (sw_zend_hash_find(&module_registry, ZEND_STRS("pcntl"), (void **) &zpcntl) == FAILURE) + { + REGISTER_LONG_CONSTANT("SIGHUP", (long) SIGHUP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGINT", (long) SIGINT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGQUIT", (long) SIGQUIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGILL", (long) SIGILL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGTRAP", (long) SIGTRAP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGABRT", (long) SIGABRT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGBUS", (long) SIGBUS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGFPE", (long) SIGFPE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGKILL", (long) SIGKILL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGUSR1", (long) SIGUSR1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGSEGV", (long) SIGSEGV, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGUSR2", (long) SIGUSR2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGPIPE", (long) SIGPIPE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGALRM", (long) SIGALRM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGTERM", (long) SIGTERM, CONST_CS | CONST_PERSISTENT); +#ifdef SIGSTKFLT + REGISTER_LONG_CONSTANT("SIGSTKFLT", (long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("SIGCHLD", (long) SIGCHLD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGCONT", (long) SIGCONT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGSTOP", (long) SIGSTOP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGTSTP", (long) SIGTSTP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGTTIN", (long) SIGTTIN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGTTOU", (long) SIGTTOU, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGURG", (long) SIGURG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGXCPU", (long) SIGXCPU, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGXFSZ", (long) SIGXFSZ, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGVTALRM", (long) SIGVTALRM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGPROF", (long) SIGPROF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGWINCH", (long) SIGWINCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SIGIO", (long) SIGIO, CONST_CS | CONST_PERSISTENT); +#ifdef SIGPWR + REGISTER_LONG_CONSTANT("SIGPWR", (long) SIGPWR, CONST_CS | CONST_PERSISTENT); +#endif +#ifdef SIGSYS + REGISTER_LONG_CONSTANT("SIGSYS", (long) SIGSYS, CONST_CS | CONST_PERSISTENT); +#endif + REGISTER_LONG_CONSTANT("SIG_IGN", (long) SIG_IGN, CONST_CS | CONST_PERSISTENT); + } +} + +static PHP_METHOD(swoole_process, __construct) +{ + zend_bool redirect_stdin_and_stdout = 0; + long pipe_type = 2; + zval *callback; + + //only cli env + if (!SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "swoole_process only can be used in PHP CLI mode."); + RETURN_FALSE; + } + + if (SwooleG.serv && SwooleG.serv->gs->start == 1 && swIsMaster()) + { + swoole_php_fatal_error(E_ERROR, "swoole_process can't be used in master process."); + RETURN_FALSE; + } + + if (SwooleAIO.init) + { + swoole_php_fatal_error(E_ERROR, "unable to create process with async-io threads."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bl", &callback, &redirect_stdin_and_stdout, &pipe_type) == FAILURE) + { + RETURN_FALSE; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + swWorker *process = emalloc(sizeof(swWorker)); + bzero(process, sizeof(swWorker)); + + int base = 1; + if (SwooleG.serv && SwooleG.serv->gs->start) + { + base = SwooleG.serv->worker_num + SwooleG.serv->task_worker_num + SwooleG.serv->user_worker_num; + } + if (php_swoole_worker_round_id == 0) + { + php_swoole_worker_round_id = base; + } + process->id = php_swoole_worker_round_id++; + + if (redirect_stdin_and_stdout) + { + process->redirect_stdin = 1; + process->redirect_stdout = 1; + process->redirect_stderr = 1; + /** + * Forced to use stream pipe + */ + pipe_type = 1; + } + + if (pipe_type > 0) + { + swPipe *_pipe = emalloc(sizeof(swWorker)); + int socket_type = pipe_type == 1 ? SOCK_STREAM : SOCK_DGRAM; + if (swPipeUnsock_create(_pipe, 1, socket_type) < 0) + { + RETURN_FALSE; + } + + process->pipe_object = _pipe; + process->pipe_master = _pipe->getFd(_pipe, SW_PIPE_MASTER); + process->pipe_worker = _pipe->getFd(_pipe, SW_PIPE_WORKER); + process->pipe = process->pipe_master; + + zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("pipe"), process->pipe_master TSRMLS_CC); + } + + swoole_set_object(getThis(), process); + zend_update_property(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("callback"), callback TSRMLS_CC); +} + +static PHP_METHOD(swoole_process, __destruct) +{ + swWorker *process = swoole_get_object(getThis()); + swPipe *_pipe = process->pipe_object; + if (_pipe) + { + _pipe->close(_pipe); + efree(_pipe); + } + if (process->queue) + { + efree(process->queue); + } + efree(process); +} + +static PHP_METHOD(swoole_process, wait) +{ + int status; + zend_bool blocking = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &blocking) == FAILURE) + { + RETURN_FALSE; + } + + int options = 0; + if (!blocking) + { + options |= WNOHANG; + } + + pid_t pid = swWaitpid(-1, &status, options); + if (pid > 0) + { + array_init(return_value); + add_assoc_long(return_value, "pid", pid); + add_assoc_long(return_value, "code", WEXITSTATUS(status)); + add_assoc_long(return_value, "signal", WTERMSIG(status)); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_process, useQueue) +{ + long msgkey = 0; + long mode = 2; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &msgkey, &mode) == FAILURE) + { + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + + if (msgkey <= 0) + { + msgkey = ftok(sw_zend_get_executed_filename(), 1); + } + + swMsgQueue *queue = emalloc(sizeof(swMsgQueue)); + if (swMsgQueue_create(queue, 1, msgkey, 0) < 0) + { + RETURN_FALSE; + } + if (mode & MSGQUEUE_NOWAIT) + { + swMsgQueue_set_blocking(queue, 0); + mode = mode & (~MSGQUEUE_NOWAIT); + } + process->queue = queue; + process->ipc_mode = mode; + zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("msgQueueId"), queue->msg_id TSRMLS_CC); + zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("msgQueueKey"), msgkey TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, statQueue) +{ + swWorker *process = swoole_get_object(getThis()); + if (!process->queue) + { + swoole_php_fatal_error(E_WARNING, "no queue, can't get stats of the queue."); + RETURN_FALSE; + } + + int queue_num = -1; + int queue_bytes = -1; + if (swMsgQueue_stat(process->queue, &queue_num, &queue_bytes) == 0) + { + array_init(return_value); + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_num"), queue_num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("queue_bytes"), queue_bytes); + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_process, freeQueue) +{ + swWorker *process = swoole_get_object(getThis()); + if (process->queue && swMsgQueue_free(process->queue) == SW_OK) + { + efree(process->queue); + process->queue = NULL; + RETURN_TRUE; + } + else + { + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_process, kill) +{ + long pid; + long sig = SIGTERM; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pid, &sig) == FAILURE) + { + RETURN_FALSE; + } + + int ret = kill((int) pid, (int) sig); + if (ret < 0) + { + if (!(sig == 0 && errno == ESRCH)) + { + swoole_php_error(E_WARNING, "kill(%d, %d) failed. Error: %s[%d]", (int) pid, (int) sig, strerror(errno), errno); + } + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, signal) +{ + zval *callback = NULL; + long signo = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &signo, &callback) == FAILURE) + { + return; + } + + if (!SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "cannot use swoole_process::signal here."); + RETURN_FALSE; + } + + if (SwooleG.serv && SwooleG.serv->gs->start) + { + if ((swIsWorker() || swIsTaskWorker()) && signo == SIGTERM) + { + swoole_php_fatal_error(E_WARNING, "unable to register SIGTERM in worker/task process."); + RETURN_FALSE; + } + else if (swIsManager() && (signo == SIGTERM || signo == SIGUSR1 || signo == SIGUSR2 || signo == SIGALRM)) + { + swoole_php_fatal_error(E_WARNING, "unable to register SIGTERM/SIGUSR1/SIGUSR2/SIGALRM in manager process."); + RETURN_FALSE; + } + else if (swIsMaster() && (signo == SIGTERM || signo == SIGUSR1 || signo == SIGUSR2 || signo == SIGALRM || signo == SIGCHLD)) + { + swoole_php_fatal_error(E_WARNING, "unable to register SIGTERM/SIGUSR1/SIGUSR2/SIGALRM/SIGCHLD in manager process."); + RETURN_FALSE; + } + } + + php_swoole_check_reactor(); + swSignalHander handler; + + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + callback = signal_callback[signo]; + if (callback) + { + swSignal_add(signo, NULL); + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_signal_callback, callback); + signal_callback[signo] = NULL; + RETURN_TRUE; + } + else + { + swoole_php_error(E_WARNING, "no callback."); + RETURN_FALSE; + } + } + else if (Z_TYPE_P(callback) == IS_LONG && Z_LVAL_P(callback) == (long) SIG_IGN) + { + handler = NULL; + } + else + { + char *func_name; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_error(E_WARNING, "function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + callback = sw_zval_dup(callback); + sw_zval_add_ref(&callback); + + handler = php_swoole_onSignal; + } + + /** + * for swSignalfd_setup + */ + SwooleG.main_reactor->check_signalfd = 1; + + //free the old callback + if (signal_callback[signo]) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, free_signal_callback, signal_callback[signo]); + } + signal_callback[signo] = callback; + +#if PHP_MAJOR_VERSION >= 7 || (PHP_MAJOR_VERSION >= 5 && PHP_MINOR_VERSION >= 4) + /** + * use user settings + */ + SwooleG.use_signalfd = SwooleG.enable_signalfd; +#else + SwooleG.use_signalfd = 0; +#endif + + swSignal_add(signo, handler); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, alarm) +{ + long usec = 0; + long type = ITIMER_REAL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &usec, &type) == FAILURE) + { + return; + } + + if (!SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "cannot use swoole_process::alarm here."); + RETURN_FALSE; + } + + if (SwooleG.timer.fd != 0) + { + swoole_php_fatal_error(E_WARNING, "cannot use both 'timer' and 'alarm' at the same time."); + RETURN_FALSE; + } + + struct timeval now; + if (gettimeofday(&now, NULL) < 0) + { + swoole_php_error(E_WARNING, "gettimeofday() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + + struct itimerval timer_set; + bzero(&timer_set, sizeof(timer_set)); + + if (usec > 0) + { + long _sec = usec / 1000000; + long _usec = usec - (_sec * 1000000); + + timer_set.it_interval.tv_sec = _sec; + timer_set.it_interval.tv_usec = _usec; + + timer_set.it_value.tv_sec = _sec; + timer_set.it_value.tv_usec = _usec; + + if (timer_set.it_value.tv_usec > 1e6) + { + timer_set.it_value.tv_usec = timer_set.it_value.tv_usec - 1e6; + timer_set.it_value.tv_sec += 1; + } + } + + if (setitimer(type, &timer_set, NULL) < 0) + { + swoole_php_error(E_WARNING, "setitimer() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + + RETURN_TRUE; +} + +static void free_signal_callback(void* data) +{ + zval *callback = (zval*) data; + sw_zval_free(callback); +} + +/** + * safe signal + */ +static void php_swoole_onSignal(int signo) +{ + zval *retval = NULL; + zval **args[1]; + zval *callback = signal_callback[signo]; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zsigno; + SW_MAKE_STD_ZVAL(zsigno); + ZVAL_LONG(zsigno, signo); + + args[0] = &zsigno; + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "user_signal handler error"); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zsigno); +} + +int php_swoole_process_start(swWorker *process, zval *object TSRMLS_DC) +{ + process->pipe = process->pipe_worker; + process->pid = getpid(); + + if (process->redirect_stdin) + { + if (dup2(process->pipe, STDIN_FILENO) < 0) + { + swoole_php_fatal_error(E_WARNING, "dup2() failed. Error: %s[%d]", strerror(errno), errno); + } + } + + if (process->redirect_stdout) + { + if (dup2(process->pipe, STDOUT_FILENO) < 0) + { + swoole_php_fatal_error(E_WARNING, "dup2() failed. Error: %s[%d]", strerror(errno), errno); + } + } + + if (process->redirect_stderr) + { + if (dup2(process->pipe, STDERR_FILENO) < 0) + { + swoole_php_fatal_error(E_WARNING, "dup2() failed. Error: %s[%d]", strerror(errno), errno); + } + } + + /** + * Close EventLoop + */ + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->free(SwooleG.main_reactor); + SwooleG.main_reactor = NULL; + swTraceLog(SW_TRACE_PHP, "destroy reactor"); + } + +#ifdef SW_COROUTINE + swLinkedList *coro_timeout_list = SwooleWG.coro_timeout_list; +#endif + + bzero(&SwooleWG, sizeof(SwooleWG)); + SwooleG.pid = process->pid; + if (SwooleG.process_type != SW_PROCESS_USERWORKER) + { + SwooleG.process_type = 0; + } + SwooleWG.id = process->id; + +#ifdef SW_COROUTINE + SwooleWG.coro_timeout_list = coro_timeout_list; +#endif + + if (SwooleG.timer.fd) + { + swTimer_free(&SwooleG.timer); + bzero(&SwooleG.timer, sizeof(SwooleG.timer)); + } + + swSignal_clear(); + + zend_update_property_long(swoole_process_class_entry_ptr, object, ZEND_STRL("pid"), process->pid TSRMLS_CC); + zend_update_property_long(swoole_process_class_entry_ptr, object, ZEND_STRL("pipe"), process->pipe_worker TSRMLS_CC); + + zval *zcallback = sw_zend_read_property(swoole_process_class_entry_ptr, object, ZEND_STRL("callback"), 0 TSRMLS_CC); + zval **args[1]; + + if (zcallback == NULL || ZVAL_IS_NULL(zcallback)) + { + swoole_php_fatal_error(E_ERROR, "no callback."); + return SW_ERR; + } + + zval *retval = NULL; + args[0] = &object; + sw_zval_add_ref(&object); + + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_ERROR, "callback function error"); + return SW_ERR; + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + + if (SwooleG.main_reactor) + { + php_swoole_event_wait(); + } + SwooleG.running = 0; + + zend_bailout(); + return SW_OK; +} + +static PHP_METHOD(swoole_process, start) +{ + swWorker *process = swoole_get_object(getThis()); + + if (process->pid > 0 && kill(process->pid, 0) == 0) + { + swoole_php_fatal_error(E_WARNING, "process has already been started."); + RETURN_FALSE; + } + + pid_t pid = fork(); + if (pid < 0) + { + swoole_php_fatal_error(E_WARNING, "fork() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + else if (pid > 0) + { + process->pid = pid; + process->child_process = 0; + zend_update_property_long(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("pid"), process->pid TSRMLS_CC); + RETURN_LONG(pid); + } + else + { + process->child_process = 1; + SW_CHECK_RETURN(php_swoole_process_start(process, getThis() TSRMLS_CC)); + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, read) +{ + long buf_size = 8192; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &buf_size) == FAILURE) + { + RETURN_FALSE; + } + + if (buf_size > 65536) + { + buf_size = 65536; + } + + swWorker *process = swoole_get_object(getThis()); + + if (process->pipe == 0) + { + swoole_php_fatal_error(E_WARNING, "no pipe, can not read from pipe."); + RETURN_FALSE; + } + + char *buf = emalloc(buf_size + 1); + int ret = read(process->pipe, buf, buf_size);; + if (ret < 0) + { + efree(buf); + if (errno != EINTR) + { + swoole_php_error(E_WARNING, "read() failed. Error: %s[%d]", strerror(errno), errno); + } + RETURN_FALSE; + } + buf[ret] = 0; + SW_ZVAL_STRINGL(return_value, buf, ret, 0); +#if PHP_MAJOR_VERSION >= 7 + efree(buf); +#endif +} + +static PHP_METHOD(swoole_process, write) +{ + char *data = NULL; + zend_size_t data_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) + { + RETURN_FALSE; + } + + if (data_len < 1) + { + swoole_php_fatal_error(E_WARNING, "the data to send is empty."); + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + if (process->pipe == 0) + { + swoole_php_fatal_error(E_WARNING, "no pipe, can not write into pipe."); + RETURN_FALSE; + } + + int ret; + + //async write + if (SwooleG.main_reactor) + { + swConnection *_socket = swReactor_get(SwooleG.main_reactor, process->pipe); + if (_socket && _socket->nonblock) + { + ret = SwooleG.main_reactor->write(SwooleG.main_reactor, process->pipe, data, (size_t) data_len); + } + else + { + goto _blocking_read; + } + } + else + { + _blocking_read: ret = swSocket_write_blocking(process->pipe, data, data_len); + } + + if (ret < 0) + { + swoole_php_error(E_WARNING, "write() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + ZVAL_LONG(return_value, ret); +} + +static PHP_METHOD(swoole_process, push) +{ + char *data; + zend_size_t length; + + struct + { + long type; + char data[SW_MSGMAX]; + } message; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &length) == FAILURE) + { + RETURN_FALSE; + } + + if (length <= 0) + { + swoole_php_fatal_error(E_WARNING, "the data to push is empty."); + RETURN_FALSE; + } + else if (length >= sizeof(message.data)) + { + swoole_php_fatal_error(E_WARNING, "the data to push is too big."); + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + + if (!process->queue) + { + swoole_php_fatal_error(E_WARNING, "no msgqueue, can not use push()"); + RETURN_FALSE; + } + + message.type = process->id; + memcpy(message.data, data, length); + + if (swMsgQueue_push(process->queue, (swQueue_data *)&message, length) < 0) + { + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, pop) +{ + long maxsize = SW_MSGMAX; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &maxsize) == FAILURE) + { + RETURN_FALSE; + } + + if (maxsize > SW_MSGMAX || maxsize <= 0) + { + maxsize = SW_MSGMAX; + } + + swWorker *process = swoole_get_object(getThis()); + if (!process->queue) + { + swoole_php_fatal_error(E_WARNING, "no msgqueue, can not use pop()"); + RETURN_FALSE; + } + + struct + { + long type; + char data[SW_MSGMAX]; + } message; + + if (process->ipc_mode == 2) + { + message.type = 0; + } + else + { + message.type = process->id; + } + + int n = swMsgQueue_pop(process->queue, (swQueue_data *) &message, maxsize); + if (n < 0) + { + RETURN_FALSE; + } + SW_RETURN_STRINGL(message.data, n, 1); +} + +static PHP_METHOD(swoole_process, exec) +{ + char *execfile = NULL; + zend_size_t execfile_len = 0; + zval *args; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &execfile, &execfile_len, &args) == FAILURE) + { + RETURN_FALSE; + } + + if (execfile_len < 1) + { + swoole_php_fatal_error(E_WARNING, "exec file name is empty."); + RETURN_FALSE; + } + + int exec_argc = php_swoole_array_length(args); + char **exec_args = emalloc(sizeof(char*) * (exec_argc + 2)); + + zval *value = NULL; + exec_args[0] = sw_strdup(execfile); + int i = 1; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(args), value) + convert_to_string(value); + sw_zval_add_ref(&value); + exec_args[i] = Z_STRVAL_P(value); + i++; + SW_HASHTABLE_FOREACH_END(); + exec_args[i] = NULL; + + if (execv(execfile, exec_args) < 0) + { + swoole_php_fatal_error(E_WARNING, "execv(%s) failed. Error: %s[%d]", execfile, strerror(errno), errno); + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_process, daemon) +{ + zend_bool nochdir = 1; + zend_bool noclose = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bb", &nochdir, &noclose) == FAILURE) + { + RETURN_FALSE; + } + RETURN_BOOL(daemon(nochdir, noclose) == 0); +} + +#ifdef HAVE_CPU_AFFINITY +static PHP_METHOD(swoole_process, setaffinity) +{ + zval *array; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) + { + RETURN_FALSE; + } + if (Z_ARRVAL_P(array)->nNumOfElements == 0) + { + RETURN_FALSE; + } + if (Z_ARRVAL_P(array)->nNumOfElements > SW_CPU_NUM) + { + swoole_php_fatal_error(E_WARNING, "More than the number of CPU"); + RETURN_FALSE; + } + + zval *value = NULL; + cpu_set_t cpu_set; + CPU_ZERO(&cpu_set); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(array), value) + convert_to_long(value); + if (Z_LVAL_P(value) >= SW_CPU_NUM) + { + swoole_php_fatal_error(E_WARNING, "invalid cpu id [%d]", (int) Z_LVAL_P(value)); + RETURN_FALSE; + } + CPU_SET(Z_LVAL_P(value), &cpu_set); + SW_HASHTABLE_FOREACH_END(); + +#ifdef __FreeBSD__ + if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, + sizeof(cpu_set), &cpu_set) < 0) +#else + if (sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set) < 0) +#endif + { + swoole_php_sys_error(E_WARNING, "sched_setaffinity() failed."); + RETURN_FALSE; + } + RETURN_TRUE; +} +#endif + +static PHP_METHOD(swoole_process, exit) +{ + long ret_code = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &ret_code) == FAILURE) + { + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + + if (getpid() != process->pid) + { + swoole_php_fatal_error(E_WARNING, "not current process."); + RETURN_FALSE; + } + + if (ret_code < 0 || ret_code > 255) + { + swoole_php_fatal_error(E_WARNING, "exit ret_code range is [>0 and <255] "); + ret_code = 1; + } + + close(process->pipe); + + SwooleG.running = 0; + + if (ret_code == 0) + { + zend_bailout(); + } + else + { + exit(ret_code); + } +} + +static PHP_METHOD(swoole_process, close) +{ + long which = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &which) == FAILURE) + { + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + if (process->pipe == 0) + { + swoole_php_fatal_error(E_WARNING, "no pipe, can not close the pipe."); + RETURN_FALSE; + } + + int ret; + if (which == SW_PIPE_CLOSE_READ) + { + ret = shutdown(process->pipe, SHUT_RD); + } + else if (which == SW_PIPE_CLOSE_WRITE) + { + ret = shutdown(process->pipe, SHUT_WR); + } + else + { + ret = swPipeUnsock_close_ext(process->pipe_object, which); + } + if (ret < 0) + { + swoole_php_fatal_error(E_WARNING, "close() failed. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + if (which == 0) + { + process->pipe = 0; + efree(process->pipe_object); + process->pipe_object = NULL; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_process, setTimeout) +{ + double seconds; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &seconds) == FAILURE) + { + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + if (process->pipe == 0) + { + swoole_php_fatal_error(E_WARNING, "no pipe, can not setTimeout the pipe."); + RETURN_FALSE; + } + SW_CHECK_RETURN(swSocket_set_timeout(process->pipe, seconds)); +} + +static PHP_METHOD(swoole_process, setBlocking) +{ + zend_bool blocking; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &blocking) == FAILURE) + { + RETURN_FALSE; + } + + swWorker *process = swoole_get_object(getThis()); + if (process->pipe == 0) + { + swoole_php_fatal_error(E_WARNING, "no pipe, can not setBlocking the pipe."); + RETURN_FALSE; + } + if (blocking) + { + swSetBlock(process->pipe); + } + else + { + swSetNonBlock(process->pipe); + } + if (SwooleG.main_reactor) + { + swConnection *_socket = swReactor_get(SwooleG.main_reactor, process->pipe); + if (_socket) + { + _socket->nonblock = blocking ? 0 : 1; + } + } +} diff --git a/vendor/swoole/swoole_process_pool.c b/vendor/swoole/swoole_process_pool.c new file mode 100755 index 0000000..35d0360 --- /dev/null +++ b/vendor/swoole/swoole_process_pool.c @@ -0,0 +1,460 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pool_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pool_construct, 0, 0, 1) + ZEND_ARG_INFO(0, worker_num) + ZEND_ARG_INFO(0, ipc_type) + ZEND_ARG_INFO(0, msgqueue_key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pool_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pool_listen, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, backlog) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_process_pool_write, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +static PHP_METHOD(swoole_process_pool, __construct); +static PHP_METHOD(swoole_process_pool, __destruct); +static PHP_METHOD(swoole_process_pool, on); +static PHP_METHOD(swoole_process_pool, listen); +static PHP_METHOD(swoole_process_pool, write); +static PHP_METHOD(swoole_process_pool, start); + +static const zend_function_entry swoole_process_pool_methods[] = +{ + PHP_ME(swoole_process_pool, __construct, arginfo_swoole_process_pool_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_process_pool, __destruct, arginfo_swoole_process_pool_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_process_pool, on, arginfo_swoole_process_pool_on, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process_pool, listen, arginfo_swoole_process_pool_listen, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process_pool, write, arginfo_swoole_process_pool_write, ZEND_ACC_PUBLIC) + PHP_ME(swoole_process_pool, start, arginfo_swoole_process_pool_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +typedef struct +{ + zval *onWorkerStart; + zval *onWorkerStop; + zval *onMessage; + zval _onWorkerStart; + zval _onWorkerStop; + zval _onMessage; +} process_pool_property; + +static zend_class_entry swoole_process_pool_ce; +static zend_class_entry *swoole_process_pool_class_entry_ptr; +static swProcessPool *current_pool; + +void swoole_process_pool_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_process_pool_ce, "swoole_process_pool", "Swoole\\Process\\Pool", swoole_process_pool_methods); + swoole_process_pool_class_entry_ptr = zend_register_internal_class(&swoole_process_pool_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_process_pool, "Swoole\\Process\\Pool"); +} + +static void php_swoole_process_pool_onWorkerStart(swProcessPool *pool, int worker_id) +{ + SWOOLE_GET_TSRMLS; + + zval *zobject = (zval *) pool->ptr; + zval *zworker_id; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + zval **args[2]; + args[0] = &zobject; + args[1] = &zworker_id; + + process_pool_property *pp = swoole_get_property(zobject, 0); + if (pp->onWorkerStart == NULL) + { + return; + } + if (SwooleG.main_reactor) + { + SwooleG.main_reactor->free(SwooleG.main_reactor); + SwooleG.main_reactor = NULL; + swTraceLog(SW_TRACE_PHP, "destroy reactor"); + } + if (sw_call_user_function_ex(EG(function_table), NULL, pp->onWorkerStart, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStart handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + if (SwooleG.main_reactor) + { + php_swoole_event_wait(); + SwooleG.running = 0; + } +} + +static void php_swoole_process_pool_onMessage(swProcessPool *pool, char *data, uint32_t length) +{ + SWOOLE_GET_TSRMLS; + + zval *zobject = (zval *) pool->ptr; + zval *zdata; + zval *retval; + + SW_MAKE_STD_ZVAL(zdata); + SW_ZVAL_STRINGL(zdata, data, length, 1); + + zval **args[2]; + args[0] = &zobject; + args[1] = &zdata; + + process_pool_property *pp = swoole_get_property(zobject, 0); + + if (sw_call_user_function_ex(EG(function_table), NULL, pp->onMessage, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStart handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zdata); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_process_pool_onWorkerStop(swProcessPool *pool, int worker_id) +{ + SWOOLE_GET_TSRMLS; + + zval *zobject = (zval *) pool->ptr; + zval *zworker_id; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + zval **args[2]; + args[0] = &zobject; + args[1] = &zworker_id; + + process_pool_property *pp = swoole_get_property(zobject, 0); + if (pp->onWorkerStop == NULL) + { + return; + } + if (sw_call_user_function_ex(EG(function_table), NULL, pp->onWorkerStop, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStop handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_process_pool_signal_hanlder(int sig) +{ + switch (sig) + { + case SIGTERM: + SwooleG.running = 0; + break; + case SIGUSR1: + case SIGUSR2: + current_pool->reloading = 1; + current_pool->reload_init = 0; + break; + default: + break; + } +} + +static PHP_METHOD(swoole_process_pool, __construct) +{ + long worker_num; + long ipc_type = SW_IPC_NONE; + long msgq_key = 0; + + //only cli env + if (!SWOOLE_G(cli)) + { + swoole_php_fatal_error(E_ERROR, "swoole_process_pool only can be used in PHP CLI mode."); + RETURN_FALSE; + } + + if (SwooleG.serv) + { + swoole_php_fatal_error(E_ERROR, "swoole_process_pool cannot use in server process."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ll", &worker_num, &ipc_type, &msgq_key) == FAILURE) + { + RETURN_FALSE; + } + + if (worker_num <= 0) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "invalid worker_num"); + RETURN_FALSE; + } + + swProcessPool *pool = emalloc(sizeof(swProcessPool)); + if (swProcessPool_create(pool, worker_num, 0, (key_t) msgq_key, ipc_type) < 0) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "failed to create process pool"); + RETURN_FALSE; + } + + if (ipc_type > 0) + { + if (swProcessPool_set_protocol(pool, 0, SW_BUFFER_INPUT_SIZE) < 0) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "failed to create process pool"); + RETURN_FALSE; + } + } + + pool->ptr = sw_zval_dup(getThis()); + + process_pool_property *pp = emalloc(sizeof(process_pool_property)); + bzero(pp, sizeof(process_pool_property)); + swoole_set_property(getThis(), 0, pp); + swoole_set_object(getThis(), pool); +} + +static PHP_METHOD(swoole_process_pool, on) +{ + char *name; + zend_size_t l_name; + zval *callback; + + swProcessPool *pool = swoole_get_object(getThis()); + + if (pool->started > 0) + { + swoole_php_fatal_error(E_WARNING, "process pool is started. unable to register event callback function."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &l_name, &callback) == FAILURE) + { + return; + } + + if (!php_swoole_is_callable(callback)) + { + RETURN_FALSE; + } + + process_pool_property *pp = swoole_get_property(getThis(), 0); + + if (strncasecmp("WorkerStart", name, l_name) == 0) + { + if (pp->onWorkerStart) + { + sw_zval_ptr_dtor(&pp->onWorkerStart); + } + pp->onWorkerStart = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(pp->onWorkerStart, pp->_onWorkerStart); + RETURN_TRUE; + } + else if (strncasecmp("Message", name, l_name) == 0) + { + if (pool->ipc_mode == SW_IPC_NONE) + { + swoole_php_fatal_error(E_WARNING, "cannot set onMessage event with ipc_type=0."); + RETURN_TRUE; + } + if (pp->onMessage) + { + sw_zval_ptr_dtor(&pp->onMessage); + } + pp->onMessage = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(pp->onMessage, pp->_onMessage); + RETURN_TRUE; + } + else if (strncasecmp("WorkerStop", name, l_name) == 0) + { + if (pp->onWorkerStop) + { + sw_zval_ptr_dtor(&pp->onWorkerStop); + } + pp->onWorkerStop = callback; + sw_zval_add_ref(&callback); + sw_copy_to_stack(pp->onWorkerStop, pp->_onWorkerStop); + RETURN_TRUE; + } + else + { + swoole_php_error(E_WARNING, "unknown event type[%s]", name); + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_process_pool, listen) +{ + char *host; + zend_size_t l_host; + long port; + long backlog = 2048; + + swProcessPool *pool = swoole_get_object(getThis()); + + if (pool->started > 0) + { + swoole_php_fatal_error(E_WARNING, "process pool is started. unable to listen."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &l_host, &port, &backlog) == FAILURE) + { + return; + } + + if (pool->ipc_mode != SW_IPC_SOCKET) + { + swoole_php_fatal_error(E_WARNING, "unsupported ipc type[%d].", pool->ipc_mode); + RETURN_FALSE; + } + + SwooleG.reuse_port = 0; + int ret; + //unix socket + if (strncasecmp("unix:/", host, 6) == 0) + { + ret = swProcessPool_create_unix_socket(pool, host + 5, backlog); + } + else + { + ret = swProcessPool_create_tcp_socket(pool, host, port, backlog); + } + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_process_pool, write) +{ + char *data; + zend_size_t length; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &length) == FAILURE) + { + return; + } + + swProcessPool *pool = swoole_get_object(getThis()); + if (pool->ipc_mode != SW_IPC_SOCKET) + { + swoole_php_fatal_error(E_WARNING, "unsupported ipc type[%d].", pool->ipc_mode); + RETURN_FALSE; + } + if (length == 0) + { + RETURN_FALSE; + } + SW_CHECK_RETURN(swProcessPool_response(pool, data, length)); +} + +static PHP_METHOD(swoole_process_pool, start) +{ + swProcessPool *pool = swoole_get_object(getThis()); + if (pool->started) + { + swoole_php_fatal_error(E_WARNING, "process pool is started. unable to execute swoole_process_pool->start."); + RETURN_FALSE; + } + + process_pool_property *pp = swoole_get_property(getThis(), 0); + + SwooleG.use_signalfd = 0; + + swSignal_add(SIGTERM, php_swoole_process_pool_signal_hanlder); + + if (pool->ipc_mode > SW_IPC_NONE) + { + pool->onMessage = php_swoole_process_pool_onMessage; + } + else + { + if (pp->onWorkerStart == NULL) + { + swoole_php_fatal_error(E_ERROR, "require onWorkerStart callback"); + RETURN_FALSE; + } + } + + pool->onWorkerStart = php_swoole_process_pool_onWorkerStart; + pool->onWorkerStop = php_swoole_process_pool_onWorkerStop; + + if (swProcessPool_start(pool) < 0) + { + RETURN_FALSE; + } + + current_pool = pool; + + swProcessPool_wait(pool); + swProcessPool_shutdown(pool); +} + +static PHP_METHOD(swoole_process_pool, __destruct) +{ + swProcessPool *pool = swoole_get_object(getThis()); + sw_zval_free(pool->ptr); + efree(pool); + + process_pool_property *pp = swoole_get_property(getThis(), 0); + if (pp->onWorkerStart) + { + sw_zval_ptr_dtor(&pp->onWorkerStart); + } + if (pp->onMessage) + { + sw_zval_ptr_dtor(&pp->onMessage); + } + if (pp->onWorkerStop) + { + sw_zval_ptr_dtor(&pp->onWorkerStop); + } + efree(pp); +} diff --git a/vendor/swoole/swoole_redis.c b/vendor/swoole/swoole_redis.c new file mode 100755 index 0000000..3d4c2d9 --- /dev/null +++ b/vendor/swoole/swoole_redis.c @@ -0,0 +1,1036 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +#ifdef SW_USE_REDIS +#include <hiredis/hiredis.h> +#include <hiredis/async.h> + +#define SW_REDIS_COMMAND_BUFFER_SIZE 64 +#define SW_REDIS_COMMAND_KEY_SIZE 128 + +typedef struct +{ + redisAsyncContext *context; + uint8_t state; + uint8_t connected; + uint8_t subscribe; + uint8_t connecting; + uint32_t reqnum; + + zval *object; + zval *message_callback; + + double timeout; + swTimer_node *timer; + + char *password; + uint8_t password_len; + int8_t database; + uint8_t failure; + uint8_t wait_count; + +#if PHP_MAJOR_VERSION >= 7 + zval _message_callback; + zval _object; +#endif + +} swRedisClient; + +enum swoole_redis_state +{ + SWOOLE_REDIS_STATE_CONNECT, + SWOOLE_REDIS_STATE_READY, + SWOOLE_REDIS_STATE_WAIT_RESULT, + SWOOLE_REDIS_STATE_SUBSCRIBE, + SWOOLE_REDIS_STATE_CLOSED, +}; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_construct, 0, 0, 0) + ZEND_ARG_ARRAY_INFO(0, setting, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_connect, 0, 0, 3) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_call, 0, 0, 2) + ZEND_ARG_INFO(0, command) + ZEND_ARG_INFO(0, params) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static PHP_METHOD(swoole_redis, __construct); +static PHP_METHOD(swoole_redis, __destruct); +static PHP_METHOD(swoole_redis, on); +static PHP_METHOD(swoole_redis, connect); +static PHP_METHOD(swoole_redis, getState); +static PHP_METHOD(swoole_redis, __call); +static PHP_METHOD(swoole_redis, close); + +static void swoole_redis_onConnect(const redisAsyncContext *c, int status); +static void swoole_redis_onClose(const redisAsyncContext *c, int status); +static int swoole_redis_onRead(swReactor *reactor, swEvent *event); +static int swoole_redis_onWrite(swReactor *reactor, swEvent *event); +static int swoole_redis_onError(swReactor *reactor, swEvent *event); +static void swoole_redis_onResult(redisAsyncContext *c, void *r, void *privdata); +static void swoole_redis_parse_result(swRedisClient *redis, zval* return_value, redisReply* reply TSRMLS_DC); +static void swoole_redis_onCompleted(redisAsyncContext *c, void *r, void *privdata); +static void swoole_redis_onTimeout(swTimer *timer, swTimer_node *tnode); + +static void swoole_redis_event_AddRead(void *privdata); +static void swoole_redis_event_AddWrite(void *privdata); +static void swoole_redis_event_DelRead(void *privdata); +static void swoole_redis_event_DelWrite(void *privdata); +static void swoole_redis_event_Cleanup(void *privdata); + +static zend_class_entry swoole_redis_ce; +static zend_class_entry *swoole_redis_class_entry_ptr; + +static const zend_function_entry swoole_redis_methods[] = +{ + PHP_ME(swoole_redis, __construct, arginfo_swoole_redis_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_redis, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_redis, on, arginfo_swoole_redis_on, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis, connect, arginfo_swoole_redis_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis, getState, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis, __call, arginfo_swoole_redis_call, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static sw_inline int swoole_redis_is_message_command(char *command, int command_len) +{ + if (strncasecmp("subscribe", command, command_len) == 0) + { + return SW_TRUE; + } + else if (strncasecmp("psubscribe", command, command_len) == 0) + { + return SW_TRUE; + } + else if (strncasecmp("unsubscribe", command, command_len) == 0) + { + return SW_TRUE; + } + else if (strncasecmp("punsubscribe", command, command_len) == 0) + { + return SW_TRUE; + } + else + { + return SW_FALSE; + } +} + +static sw_inline void redis_execute_connect_callback(swRedisClient *redis, int success TSRMLS_DC) +{ + zval *result, *retval; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, success); + + zval **args[2]; + zval *zcallback = sw_zend_read_property(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("onConnect"), 0 TSRMLS_CC); + args[0] = &redis->object; + args[1] = &result; + redis->connecting = 1; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_async_redis connect_callback handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + redis->connecting = 0; +} + +void swoole_redis_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_redis_ce, "swoole_redis", "Swoole\\Redis", swoole_redis_methods); + swoole_redis_class_entry_ptr = zend_register_internal_class(&swoole_redis_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_redis, "Swoole\\Redis"); + + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("onMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("sock"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("errCode"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_class_entry_ptr, ZEND_STRL("errMsg"), ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_class_constant_long(swoole_redis_class_entry_ptr, SW_STRL("STATE_CONNECT")-1, SWOOLE_REDIS_STATE_CONNECT TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_class_entry_ptr, SW_STRL("STATE_READY")-1, SWOOLE_REDIS_STATE_READY TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_class_entry_ptr, SW_STRL("STATE_WAIT_RESULT")-1, SWOOLE_REDIS_STATE_WAIT_RESULT TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_class_entry_ptr, SW_STRL("STATE_SUBSCRIBE")-1, SWOOLE_REDIS_STATE_SUBSCRIBE TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_class_entry_ptr, SW_STRL("STATE_CLOSED")-1, SWOOLE_REDIS_STATE_CLOSED TSRMLS_CC); +} + +static PHP_METHOD(swoole_redis, __construct) +{ + zval *zset = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &zset) == FAILURE) + { + return; + } + + swRedisClient *redis = emalloc(sizeof(swRedisClient)); + bzero(redis, sizeof(swRedisClient)); + + redis->object = getThis(); + redis->timeout = SW_REDIS_CONNECT_TIMEOUT; + redis->database = -1; + + if (zset && !ZVAL_IS_NULL(zset)) + { + php_swoole_array_separate(zset); + zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("setting"), zset TSRMLS_CC); + sw_zval_ptr_dtor(&zset); + + HashTable *vht; + zval *ztmp; + vht = Z_ARRVAL_P(zset); + /** + * timeout + */ + if (php_swoole_array_get_value(vht, "timeout", ztmp)) + { + convert_to_double(ztmp); + redis->timeout = (double) Z_DVAL_P(ztmp); + } + /** + * password + */ + if (php_swoole_array_get_value(vht, "password", ztmp)) + { + convert_to_string(ztmp); + if (Z_STRLEN_P(ztmp) >= 1 << 8) + { + swoole_php_fatal_error(E_WARNING, "redis password is too long."); + } + else if (Z_STRLEN_P(ztmp) > 0) + { + redis->password = estrdup(Z_STRVAL_P(ztmp)); + redis->password_len = Z_STRLEN_P(ztmp); + } + } + /** + * database + */ + if (php_swoole_array_get_value(vht, "database", ztmp)) + { + convert_to_long(ztmp); + if (Z_LVAL_P(ztmp) > 1 << 8) + { + swoole_php_fatal_error(E_WARNING, "redis database number is too big."); + } + else + { + redis->database = (int8_t) Z_LVAL_P(ztmp); + } + } + } + + sw_copy_to_stack(redis->object, redis->_object); + swoole_set_object(getThis(), redis); +} + +static PHP_METHOD(swoole_redis, on) +{ + char *name; + zend_size_t len; + zval *cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sz", &name, &len, &cb) == FAILURE) + { + return; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (redis->context != NULL) + { + swoole_php_fatal_error(E_WARNING, "Must be called before connecting."); + RETURN_FALSE; + } + + if (strncasecmp("close", name, len) == 0) + { + zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("onClose"), cb TSRMLS_CC); + } + else if (strncasecmp("message", name, len) == 0) + { + zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), cb TSRMLS_CC); + redis->message_callback = sw_zend_read_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), 0 TSRMLS_CC); + sw_copy_to_stack(redis->message_callback, redis->_message_callback); + + redis->subscribe = 1; + } + else + { + swoole_php_error(E_WARNING, "Unknown event type[%s]", name); + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis, connect) +{ + char *host; + zend_size_t host_len; + long port; + zval *callback; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz", &host, &host_len, &port, &callback) == FAILURE) + { + RETURN_FALSE; + } + + if (host_len <= 0) + { + swoole_php_error(E_WARNING, "redis server host is empty."); + RETURN_FALSE; + } + + swRedisClient *redis = swoole_get_object(getThis()); + redisAsyncContext *context; + + if (strncasecmp(host, ZEND_STRL("unix:/")) == 0) + { + context = redisAsyncConnectUnix(host + 5); + } + else + { + if (port <= 1 || port > 65535) + { + swoole_php_error(E_WARNING, "redis server port is invalid."); + RETURN_FALSE; + } + context = redisAsyncConnect(host, (int) port); + } + + if (context->err) + { + swoole_php_error(E_WARNING, "failed to connect to the redis-server[%s:%d], Erorr: %s[%d]", host, (int) port, context->errstr, context->err); + RETURN_FALSE; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_READ, swoole_redis_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_WRITE, swoole_redis_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS | SW_EVENT_ERROR, swoole_redis_onError); + } + + redisAsyncSetConnectCallback(context, swoole_redis_onConnect); + redisAsyncSetDisconnectCallback(context, swoole_redis_onClose); + + zend_update_property_long(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("sock"), context->c.fd TSRMLS_CC); + zend_update_property(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("onConnect"), callback TSRMLS_CC); + + redis->context = context; + context->ev.addRead = swoole_redis_event_AddRead; + context->ev.delRead = swoole_redis_event_DelRead; + context->ev.addWrite = swoole_redis_event_AddWrite; + context->ev.delWrite = swoole_redis_event_DelWrite; + context->ev.cleanup = swoole_redis_event_Cleanup; + context->ev.data = redis; + + zend_update_property_string(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("host"), host TSRMLS_CC); + zend_update_property_long(swoole_redis_class_entry_ptr, getThis(), ZEND_STRL("port"), port TSRMLS_CC); + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, redis->context->c.fd, PHP_SWOOLE_FD_REDIS | SW_EVENT_WRITE) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event_add failed. Erorr: %s[%d].", redis->context->errstr, redis->context->err); + RETURN_FALSE; + } + + if (redis->timeout > 0) + { + php_swoole_check_timer((int) (redis->timeout * 1000)); + redis->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, redis, swoole_redis_onTimeout); + } + + sw_zval_add_ref(&redis->object); + + swConnection *conn = swReactor_get(SwooleG.main_reactor, redis->context->c.fd); + conn->object = redis; +} + +static void redis_close(void* data) +{ + swRedisClient *redis = data; + redisAsyncDisconnect(redis->context); +} + +static void redis_free_object(void *data) +{ + zval *object = (zval*) data; + sw_zval_ptr_dtor(&object); +} + +static PHP_METHOD(swoole_redis, close) +{ + swRedisClient *redis = swoole_get_object(getThis()); + if (redis && redis->context && redis->state != SWOOLE_REDIS_STATE_CLOSED) + { + if (redis->connecting) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, redis_close, redis); + } + else + { + redis_close(redis); + } + } +} + +static PHP_METHOD(swoole_redis, __destruct) +{ + swRedisClient *redis = swoole_get_object(getThis()); + if (redis) + { + if (redis->context && redis->state != SWOOLE_REDIS_STATE_CLOSED) + { + redisAsyncDisconnect(redis->context); + } + if (redis->password) + { + efree(redis->password); + } + efree(redis); + swoole_set_object(getThis(), NULL); + } +} + +static PHP_METHOD(swoole_redis, __call) +{ + zval *params; + char *command; + zend_size_t command_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &command, &command_len, &params) == FAILURE) + { + return; + } + + if (Z_TYPE_P(params) != IS_ARRAY) + { + swoole_php_fatal_error(E_WARNING, "invalid params."); + RETURN_FALSE; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis) + { + swoole_php_fatal_error(E_WARNING, "the object is not an instance of swoole_redis."); + RETURN_FALSE; + } + + switch (redis->state) + { + case SWOOLE_REDIS_STATE_CONNECT: + swoole_php_error(E_WARNING, "redis client is not connected."); + RETURN_FALSE; + break; + case SWOOLE_REDIS_STATE_WAIT_RESULT: + if (swoole_redis_is_message_command(command, command_len)) + { + swoole_php_error(E_WARNING, "redis client is waiting for response."); + RETURN_FALSE; + } + break; + case SWOOLE_REDIS_STATE_SUBSCRIBE: + if (!swoole_redis_is_message_command(command, command_len)) + { + swoole_php_error(E_WARNING, "redis client is waiting for subscribed messages."); + RETURN_FALSE; + } + break; + case SWOOLE_REDIS_STATE_CLOSED: + swoole_php_error(E_WARNING, "redis client connection is closed."); + RETURN_FALSE; + break; + default: + break; + } + + int argc = zend_hash_num_elements(Z_ARRVAL_P(params)); + size_t stack_argvlen[SW_REDIS_COMMAND_BUFFER_SIZE]; + char *stack_argv[SW_REDIS_COMMAND_BUFFER_SIZE]; + + size_t *argvlen; + char **argv; + zend_bool free_mm = 0; + + if (argc > SW_REDIS_COMMAND_BUFFER_SIZE) + { + argvlen = emalloc(sizeof(size_t) * argc); + argv = emalloc(sizeof(char*) * argc); + free_mm = 1; + } + else + { + argvlen = stack_argvlen; + argv = stack_argv; + } +#define FREE_MEM() do { \ + for (i = 1; i < argc; i++) \ + { \ + efree((void* )argv[i]); \ + } \ + \ + if (redis->state == SWOOLE_REDIS_STATE_SUBSCRIBE) \ + { \ + efree(argv[argc]); \ + } \ + \ + if (free_mm) \ + { \ + efree(argvlen); \ + efree(argv); \ + } \ +} while (0) + + assert(command_len < SW_REDIS_COMMAND_KEY_SIZE - 1); + + char command_name[SW_REDIS_COMMAND_KEY_SIZE]; + memcpy(command_name, command, command_len); + command_name[command_len] = '\0'; + + argv[0] = command_name; + argvlen[0] = command_len; + + zval *value; + int i = 1; + + /** + * subscribe command + */ + if (redis->state == SWOOLE_REDIS_STATE_SUBSCRIBE || (redis->subscribe && swoole_redis_is_message_command(command, command_len))) + { + redis->state = SWOOLE_REDIS_STATE_SUBSCRIBE; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value) + convert_to_string(value); + argvlen[i] = (size_t) Z_STRLEN_P(value); + argv[i] = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); + if (i == argc) + { + break; + } + i++; + SW_HASHTABLE_FOREACH_END(); + + if (redisAsyncCommandArgv(redis->context, swoole_redis_onResult, NULL, argc + 1, (const char **) argv, (const size_t *) argvlen) < 0) + { + swoole_php_error(E_WARNING, "redisAsyncCommandArgv() failed."); + FREE_MEM(); + RETURN_FALSE; + } + } + /** + * storage command + */ + else + { + redis->state = SWOOLE_REDIS_STATE_WAIT_RESULT; + redis->reqnum++; + +#if PHP_MAJOR_VERSION < 7 + zval *callback; + zval **cb_tmp; + if (zend_hash_index_find(Z_ARRVAL_P(params), zend_hash_num_elements(Z_ARRVAL_P(params)) - 1, (void **) &cb_tmp) == FAILURE) + { + swoole_php_error(E_WARNING, "index out of array bounds."); + FREE_MEM(); + RETURN_FALSE; + } + callback = *cb_tmp; +#else + zval *callback = zend_hash_index_find(Z_ARRVAL_P(params), zend_hash_num_elements(Z_ARRVAL_P(params)) - 1); + if (callback == NULL) + { + swoole_php_error(E_WARNING, "index out of array bounds."); + FREE_MEM(); + RETURN_FALSE; + } +#endif + + sw_zval_add_ref(&callback); + callback = sw_zval_dup(callback); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value) + if (i == argc) + { + break; + } + + convert_to_string(value); + argvlen[i] = (size_t) Z_STRLEN_P(value); + argv[i] = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); + i++; + SW_HASHTABLE_FOREACH_END(); + + if (redisAsyncCommandArgv(redis->context, swoole_redis_onResult, callback, argc, (const char **) argv, (const size_t *) argvlen) < 0) + { + swoole_php_error(E_WARNING, "redisAsyncCommandArgv() failed."); + FREE_MEM(); + RETURN_FALSE; + } + } + + FREE_MEM(); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis, getState) +{ + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis) + { + swoole_php_fatal_error(E_WARNING, "object is not instanceof swoole_redis."); + RETURN_FALSE; + } + RETURN_LONG(redis->state); +} + +static void swoole_redis_set_error(swRedisClient *redis, zval* return_value, redisReply* reply TSRMLS_DC) +{ + char *str = malloc(reply->len + 1); + memcpy(str, reply->str, reply->len); + str[reply->len] = 0; + + ZVAL_FALSE(return_value); + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), -1 TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), str TSRMLS_CC); + free(str); +} + +static void swoole_redis_parse_result(swRedisClient *redis, zval* return_value, redisReply* reply TSRMLS_DC) +{ + zval *val; + int j; + +#if PHP_MAJOR_VERSION >= 7 + zval _val; + val = &_val; + bzero(val, sizeof(zval)); +#endif + + switch (reply->type) + { + case REDIS_REPLY_INTEGER: + ZVAL_LONG(return_value, reply->integer); + break; + + case REDIS_REPLY_ERROR: + swoole_redis_set_error(redis, return_value, reply TSRMLS_CC); + break; + + case REDIS_REPLY_STATUS: + if (redis->context->err == 0) + { + if (reply->len > 0) + { + SW_ZVAL_STRINGL(return_value, reply->str, reply->len, 1); + } + else + { + ZVAL_TRUE(return_value); + } + } + else + { + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), redis->context->err TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), redis->context->errstr TSRMLS_CC); + } + break; + + case REDIS_REPLY_STRING: + SW_ZVAL_STRINGL(return_value, reply->str, reply->len, 1); + break; + + case REDIS_REPLY_ARRAY: + array_init(return_value); + for (j = 0; j < reply->elements; j++) + { +#if PHP_MAJOR_VERSION < 7 + SW_ALLOC_INIT_ZVAL(val); +#endif + swoole_redis_parse_result(redis, val, reply->element[j] TSRMLS_CC); + add_next_index_zval(return_value, val); + } + break; + + case REDIS_REPLY_NIL: + default: + ZVAL_NULL(return_value); + return; + } +} + +static void swoole_redis_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + swRedisClient *redis = tnode->data; + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), strerror(ETIMEDOUT) TSRMLS_CC); + redis->state = SWOOLE_REDIS_STATE_CLOSED; + redis_execute_connect_callback(redis, 0 TSRMLS_CC); + redisAsyncDisconnect(redis->context); + sw_zval_ptr_dtor(&redis->object); +} + +static void swoole_redis_onCompleted(redisAsyncContext *c, void *r, void *privdata) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + swRedisClient *redis = c->ev.data; + if (redis->state == SWOOLE_REDIS_STATE_CLOSED) + { + return; + } + + if (redis->failure == 0) + { + redisReply *reply = r; + switch (reply->type) + { + case REDIS_REPLY_ERROR: + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), 0 TSRMLS_CC); + zend_update_property_stringl(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), reply->str, + reply->len TSRMLS_CC); + redis->failure = 1; + break; + + case REDIS_REPLY_STATUS: + if (redis->context->err == 0) + { + break; + } + else + { + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), + redis->context->err TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), + redis->context->errstr TSRMLS_CC); + redis->failure = 1; + } + break; + } + } + + redis->wait_count--; + if (redis->wait_count == 0) + { + if (redis->failure) + { + redis_execute_connect_callback(redis, 0 TSRMLS_CC); + redis->connecting = 0; + zval *retval = NULL; + zval *zobject = redis->object; + sw_zend_call_method_with_0_params(&zobject, swoole_redis_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + return; + } + else + { + redis_execute_connect_callback(redis, 1 TSRMLS_CC); + } + } +} + +static void swoole_redis_onResult(redisAsyncContext *c, void *r, void *privdata) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + redisReply *reply = r; + if (reply == NULL) + { + return; + } + + zend_bool is_subscribe = 0; + char *callback_type; + swRedisClient *redis = c->ev.data; + zval *result, *retval, *callback; + SW_MAKE_STD_ZVAL(result); + + swoole_redis_parse_result(redis, result, reply TSRMLS_CC); + + if (redis->state == SWOOLE_REDIS_STATE_SUBSCRIBE) + { + callback = redis->message_callback; + callback_type = "Message"; + is_subscribe = 1; + } + else + { + callback = (zval *)privdata; + callback_type = "Result"; + assert(redis->reqnum > 0 && redis->state == SWOOLE_REDIS_STATE_WAIT_RESULT); + redis->reqnum--; + if (redis->reqnum == 0) + { + redis->state = SWOOLE_REDIS_STATE_READY; + } + } + + zval **args[2]; + args[0] = &redis->object; + args[1] = &result; + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_redis callback[%s] handler error.", callback_type); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + if (!is_subscribe) + { + sw_zval_free(callback); + } +} + +void swoole_redis_onConnect(const redisAsyncContext *c, int status) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + swRedisClient *redis = c->ev.data; + + if (redis->timer) + { + swTimer_del(&SwooleG.timer, redis->timer); + redis->timer = NULL; + } + + if (status != REDIS_OK) + { + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), errno TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); + redis->state = SWOOLE_REDIS_STATE_CLOSED; + redis_execute_connect_callback(redis, 0 TSRMLS_CC); + SwooleG.main_reactor->defer(SwooleG.main_reactor, redis_free_object, redis->object); + return; + } + else + { + redis->state = SWOOLE_REDIS_STATE_READY; + redis->connected = 1; + } + + if (redis->password) + { + redisAsyncCommand((redisAsyncContext *) c, swoole_redis_onCompleted, NULL, "AUTH %b", redis->password, redis->password_len); + redis->wait_count++; + } + if (redis->database >= 0) + { + redisAsyncCommand((redisAsyncContext *) c, swoole_redis_onCompleted, (char*) "end-1", "SELECT %d", redis->database); + redis->wait_count++; + } + if (redis->wait_count == 0) + { + redis_execute_connect_callback(redis, 1 TSRMLS_CC); + } +} + +void swoole_redis_onClose(const redisAsyncContext *c, int status) +{ + swRedisClient *redis = c->ev.data; + redis->state = SWOOLE_REDIS_STATE_CLOSED; + redis->context = NULL; + +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *zcallback = sw_zend_read_property(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("onClose"), 1 TSRMLS_CC); + if (zcallback && !ZVAL_IS_NULL(zcallback)) + { + zval *retval; + zval **args[1]; + args[0] = &redis->object; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_async_redis close_callback handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + } + + sw_zval_ptr_dtor(&redis->object); +} + +static int swoole_redis_onError(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + swRedisClient *redis = event->socket->object; + zval *zcallback = sw_zend_read_property(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("onConnect"), 0 TSRMLS_CC); + + if (!ZVAL_IS_NULL(zcallback)) + { + const redisAsyncContext *c = redis->context; + zval *result; + SW_MAKE_STD_ZVAL(result); + ZVAL_BOOL(result, 0); + zend_update_property_long(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); + zend_update_property_string(swoole_redis_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); + + redis->state = SWOOLE_REDIS_STATE_CLOSED; + + zval *retval = NULL; + zval **args[2]; + args[0] = &redis->object; + args[1] = &result; + redis->connecting = 1; + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) != SUCCESS) + { + swoole_php_fatal_error(E_WARNING, "swoole_async_redis connect_callback handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + + redis->connecting = 0; + retval = NULL; + zval *zobject = redis->object; + sw_zend_call_method_with_0_params(&zobject, swoole_redis_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + return SW_OK; +} + +static void swoole_redis_event_AddRead(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_add_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_READ); + } +} + +static void swoole_redis_event_DelRead(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_del_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_READ); + } +} + +static void swoole_redis_event_AddWrite(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_add_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_WRITE); + } +} + +static void swoole_redis_event_DelWrite(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_del_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_WRITE); + } +} + +static void swoole_redis_event_Cleanup(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + redis->state = SWOOLE_REDIS_STATE_CLOSED; + if (redis->context && SwooleG.main_reactor) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, redis->context->c.fd); + } +} + +static int swoole_redis_onRead(swReactor *reactor, swEvent *event) +{ + swRedisClient *redis = event->socket->object; + if (redis->context && SwooleG.main_reactor) + { + redisAsyncHandleRead(redis->context); + } + return SW_OK; +} + +static int swoole_redis_onWrite(swReactor *reactor, swEvent *event) +{ + swRedisClient *redis = event->socket->object; + if (redis->context && SwooleG.main_reactor) + { + redisAsyncHandleWrite(redis->context); + } + return SW_OK; +} + +#endif diff --git a/vendor/swoole/swoole_redis_coro.c b/vendor/swoole/swoole_redis_coro.c new file mode 100755 index 0000000..3a7a1b2 --- /dev/null +++ b/vendor/swoole/swoole_redis_coro.c @@ -0,0 +1,4425 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#ifdef SW_USE_REDIS +#include <hiredis/hiredis.h> +#include <hiredis/async.h> +#include <ext/standard/php_var.h> + +#if PHP_MAJOR_VERSION < 7 +#include <ext/standard/php_smart_str.h> +#define SW_REDIS_COMMAND_ALLOC_ARGS_ARR zval **z_args = emalloc(argc*sizeof(zval*)); +#define SW_REDIS_COMMAND_ARGS_TYPE(arg) Z_TYPE_P(arg) +#define SW_REDIS_COMMAND_ARGS_LVAL(arg) Z_LVAL_P(arg) +#define SW_REDIS_COMMAND_ARGS_DVAL(arg) Z_DVAL_P(arg) +#define SW_REDIS_COMMAND_ARGS_ARRVAL(arg) Z_ARRVAL_P(arg) +#define SW_REDIS_COMMAND_ARGS_STRVAL(arg) Z_STRVAL_P(arg) +#define SW_REDIS_COMMAND_ARGS_STRLEN(arg) Z_STRLEN_P(arg) +#define SW_REDIS_COMMAND_ARGS_REF(arg) arg +#else +#define SW_REDIS_COMMAND_ALLOC_ARGS_ARR zval *z_args = emalloc(argc*sizeof(zval)); +#define SW_REDIS_COMMAND_ARGS_TYPE(arg) Z_TYPE(arg) +#define SW_REDIS_COMMAND_ARGS_LVAL(arg) Z_LVAL(arg) +#define SW_REDIS_COMMAND_ARGS_DVAL(arg) Z_DVAL(arg) +#define SW_REDIS_COMMAND_ARGS_ARRVAL(arg) Z_ARRVAL(arg) +#define SW_REDIS_COMMAND_ARGS_STRVAL(arg) Z_STRVAL(arg) +#define SW_REDIS_COMMAND_ARGS_STRLEN(arg) Z_STRLEN(arg) +#define SW_REDIS_COMMAND_ARGS_REF(arg) &arg +#endif + +#define SW_REDIS_COMMAND_BUFFER_SIZE 64 +#define SW_BITOP_MIN_OFFSET 0 +#define SW_BITOP_MAX_OFFSET 4294967295 +#define SW_REDIS_NOT_FOUND 0 +#define SW_REDIS_STRING 1 +#define SW_REDIS_SET 2 +#define SW_REDIS_LIST 3 +#define SW_REDIS_ZSET 4 +#define SW_REDIS_HASH 5 +/* the same errCode define with hiredis */ +enum swRedisError +{ + SW_REDIS_ERR_IO = 1, /* Error in read or write */ + SW_REDIS_ERR_EOF = 3,/* End of file */ + SW_REDIS_ERR_PROTOCOL = 4,/* Protocol error */ + SW_REDIS_ERR_OOM = 5,/* Out of memory */ + SW_REDIS_ERR_OTHER = 2,/* Everything else... */ + SW_REDIS_ERR_CLOSED = 6, /* Closed */ + SW_REDIS_ERR_NOAUTH = 7, /* Authentication required */ +}; + +/* Extended SET argument detection */ +#define IS_EX_ARG(a) \ + ((a[0]=='e' || a[0]=='E') && (a[1]=='x' || a[1]=='X') && a[2]=='\0') +#define IS_PX_ARG(a) \ + ((a[0]=='p' || a[0]=='P') && (a[1]=='x' || a[1]=='X') && a[2]=='\0') +#define IS_NX_ARG(a) \ + ((a[0]=='n' || a[0]=='N') && (a[1]=='x' || a[1]=='X') && a[2]=='\0') +#define IS_XX_ARG(a) \ + ((a[0]=='x' || a[0]=='X') && (a[1]=='x' || a[1]=='X') && a[2]=='\0') + +static zend_class_entry swoole_redis_coro_ce; +static zend_class_entry *swoole_redis_coro_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_connect, 0, 0, 2) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, serialize) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_construct, 0, 0, 0) + ZEND_ARG_INFO(0, config) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key_value, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key_long, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, integer) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_key_opt_long, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, integer) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_request, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, params, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_incrByFloat, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, float_number) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zIncrBy, 0, 0, 3) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, member) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_coro_zRange, 0, 0, 3) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, start) + ZEND_ARG_INFO(0, end) + ZEND_ARG_INFO(0, withscores) +ZEND_END_ARG_INFO() + +#define IS_EX_PX_ARG(a) (IS_EX_ARG(a) || IS_PX_ARG(a)) +#define IS_NX_XX_ARG(a) (IS_NX_ARG(a) || IS_XX_ARG(a)) + +#define SW_REDIS_COMMAND_CHECK \ + coro_check(TSRMLS_C);\ + swRedisClient *redis = swoole_get_object(getThis()); \ + if (!redis)\ + {\ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_CLOSED TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "connection is not available." TSRMLS_CC); \ + RETURN_FALSE;\ + }\ + if (redis->iowait == SW_REDIS_CORO_STATUS_WAIT) \ + { \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for response." TSRMLS_CC); \ + RETURN_FALSE; \ + } \ + if (redis->iowait == SW_REDIS_CORO_STATUS_DONE) \ + { \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for calling recv." TSRMLS_CC); \ + RETURN_FALSE; \ + } \ + switch (redis->state) \ + { \ + case SWOOLE_REDIS_CORO_STATE_CONNECT: \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is not connected." TSRMLS_CC); \ + RETURN_FALSE; \ + break; \ + case SWOOLE_REDIS_CORO_STATE_SUBSCRIBE: \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for subscribe message." TSRMLS_CC); \ + RETURN_FALSE; \ + break; \ + case SWOOLE_REDIS_CORO_STATE_CLOSED: \ + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION;\ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client connection is closed." TSRMLS_CC); \ + RETURN_FALSE; \ + break; \ + default: \ + break; \ + }\ + if (unlikely(redis->cid && redis->cid != sw_get_current_cid()))\ + {\ + swoole_php_fatal_error(E_WARNING, "redis client has already been bound to another coroutine.");\ + RETURN_FALSE;\ + } + +#define SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS \ + coro_check(TSRMLS_C);\ + swRedisClient *redis = swoole_get_object(getThis()); \ + if (!redis)\ + {\ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_CLOSED TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis client is waiting for response." TSRMLS_CC); \ + RETURN_FALSE;\ + }\ + if (redis->iowait == SW_REDIS_CORO_STATUS_WAIT) \ + { \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for response." TSRMLS_CC); \ + efree(z_args); \ + RETURN_FALSE; \ + } \ + if (redis->iowait == SW_REDIS_CORO_STATUS_DONE) \ + { \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for calling recv." TSRMLS_CC); \ + RETURN_FALSE; \ + } \ + switch (redis->state) \ + { \ + case SWOOLE_REDIS_CORO_STATE_CONNECT: \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is not connected." TSRMLS_CC); \ + efree(z_args); \ + RETURN_FALSE; \ + break; \ + case SWOOLE_REDIS_CORO_STATE_SUBSCRIBE: \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client is waiting for subscribe message." TSRMLS_CC); \ + efree(z_args); \ + RETURN_FALSE; \ + break; \ + case SWOOLE_REDIS_CORO_STATE_CLOSED: \ + SwooleG.error = SW_ERROR_CLIENT_NO_CONNECTION;\ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redis client connection is closed." TSRMLS_CC); \ + efree(z_args); \ + RETURN_FALSE; \ + break; \ + default: \ + break; \ + } + +#define SW_REDIS_COMMAND_YIELD \ + if (redis->state == SWOOLE_REDIS_CORO_STATE_MULTI || redis->state == SWOOLE_REDIS_CORO_STATE_PIPELINE) \ + { \ + redis->queued_cmd_count++; \ + RETURN_ZVAL(getThis(), 1, 0); \ + } \ + else \ + { \ + redis->iowait = SW_REDIS_CORO_STATUS_WAIT; \ + if (redis->defer) \ + { \ + RETURN_TRUE; \ + } \ + redis->cid = sw_get_current_cid();\ + php_context *context = swoole_get_property(getThis(), 0); \ + coro_save(context); \ + coro_yield(); \ + } + +#define SW_REDIS_COMMAND_ARGV_FILL(str, str_len) \ + argvlen[i] = str_len; \ + argv[i] = estrndup(str, str_len); \ + i++; +#if (PHP_MAJOR_VERSION < 7) +#define SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(_val) \ + if (redis->serialize) { \ + smart_str sstr = {0}; \ + php_serialize_data_t s_ht; \ + PHP_VAR_SERIALIZE_INIT(s_ht); \ + php_var_serialize(&sstr, &_val, &s_ht TSRMLS_CC); \ + argvlen[i] = (size_t)sstr.len; \ + argv[i] = sstr.c; \ + PHP_VAR_SERIALIZE_DESTROY(s_ht); \ + } else { \ + convert_to_string(_val); \ + argvlen[i] = Z_STRLEN_P(_val); \ + argv[i] = estrndup(Z_STRVAL_P(_val), argvlen[i]); \ + } \ + i++; +#else +#define SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(_val) \ + if (redis->serialize) { \ + smart_str sstr = {0}; \ + php_serialize_data_t s_ht; \ + PHP_VAR_SERIALIZE_INIT(s_ht); \ + php_var_serialize(&sstr, _val, &s_ht TSRMLS_CC); \ + argvlen[i] = (size_t)sstr.s->len; \ + argv[i] = estrndup(sstr.s->val, sstr.s->len); \ + zend_string_release(sstr.s); \ + PHP_VAR_SERIALIZE_DESTROY(s_ht); \ + } else { \ + zend_string *convert_str = zval_get_string(_val); \ + argvlen[i] = convert_str->len; \ + argv[i] = estrndup(convert_str->val, convert_str->len); \ + zend_string_release(convert_str); \ + } \ + i++; +#endif + +#define SW_REDIS_COMMAND_ALLOC_ARGV \ + size_t stack_argvlen[SW_REDIS_COMMAND_BUFFER_SIZE]; \ + char *stack_argv[SW_REDIS_COMMAND_BUFFER_SIZE]; \ + size_t *argvlen; \ + char **argv; \ + zend_bool free_mm = 0; \ + if (argc > SW_REDIS_COMMAND_BUFFER_SIZE) \ + { \ + argvlen = emalloc(sizeof(size_t) * (argc)); \ + argv = emalloc(sizeof(char*) * (argc)); \ + free_mm = 1; \ + } \ + else \ + { \ + argvlen = stack_argvlen; \ + argv = stack_argv; \ + } + +#define SW_REDIS_COMMAND_FREE_ARGV \ + if (free_mm) \ + { \ + efree(argvlen); \ + efree(argv); \ + } + +#define SW_REDIS_COMMAND(argc) \ + int __cmd_retval = redisAsyncCommandArgv(redis->context, swoole_redis_coro_onResult, NULL, argc, (const char **) argv, (const size_t *) argvlen);\ + if (__cmd_retval < 0) \ + { \ + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); \ + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "redisAsyncCommandArgv() failed." TSRMLS_CC); \ + } \ + for (i = 0; i < argc; i++) \ + { \ + efree(argv[i]); \ + }\ + if (__cmd_retval < 0) \ + {\ + RETURN_FALSE;\ + } + +typedef enum +{ + SW_REDIS_CORO_STATUS_CLOSED, + SW_REDIS_CORO_STATUS_READY, + SW_REDIS_CORO_STATUS_WAIT, + SW_REDIS_CORO_STATUS_DONE, +} swoole_redis_coro_io_status; + +typedef enum +{ + SWOOLE_REDIS_CORO_STATE_CONNECT, + SWOOLE_REDIS_CORO_STATE_READY, + SWOOLE_REDIS_CORO_STATE_SUBSCRIBE, + SWOOLE_REDIS_CORO_STATE_MULTI, + SWOOLE_REDIS_CORO_STATE_PIPELINE, + SWOOLE_REDIS_CORO_STATE_CLOSED, + SWOOLE_REDIS_CORO_STATE_CLOSING, + SWOOLE_REDIS_CORO_STATE_RELEASED, +} swoole_redis_coro_state; + +typedef struct +{ + redisAsyncContext *context; + zend_bool defer; + zend_bool defer_yield; + zend_bool connecting; + zend_bool connected; + zend_bool released; + swoole_redis_coro_state state; + swoole_redis_coro_io_status iowait; + uint16_t queued_cmd_count; + zval *pipeline_result; + zval *defer_result; + zend_bool serialize; + int cid; + + double timeout; + swTimer_node *timer; + + zval *object; + zval _object; + +} swRedisClient; + +typedef struct +{ +#if PHP_MAJOR_VERSION >= 7 + zval _value; +#endif + zval *value; + swRedisClient *redis; +} swRedis_result; + +enum {SW_REDIS_MODE_MULTI, SW_REDIS_MODE_PIPELINE}; + +static void swoole_redis_coro_event_AddRead(void *privdata); +static void swoole_redis_coro_event_AddWrite(void *privdata); +static void swoole_redis_coro_event_DelRead(void *privdata); +static void swoole_redis_coro_event_DelWrite(void *privdata); +static void swoole_redis_coro_event_Cleanup(void *privdata); + +static void swoole_redis_coro_onTimeout(swTimer *timer, swTimer_node *tnode); + +static void swoole_redis_coro_onConnect(const redisAsyncContext *c, int status); +static void swoole_redis_coro_onClose(const redisAsyncContext *c, int status); +static int swoole_redis_coro_onRead(swReactor *reactor, swEvent *event); +static int swoole_redis_coro_onWrite(swReactor *reactor, swEvent *event); +static int swoole_redis_coro_onError(swReactor *reactor, swEvent *event); +static void swoole_redis_coro_onResult(redisAsyncContext *c, void *r, void *privdata); +static void swoole_redis_coro_parse_result(swRedisClient *redis, zval* return_value, redisReply* reply TSRMLS_DC); + +static sw_inline void sw_redis_command_empty(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[1]; + char *argv[1]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND(1) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_var_key(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len, int min_argc, int has_timeout) +{ + long timeout; + int argc = ZEND_NUM_ARGS(); + if(argc < min_argc) { + RETURN_FALSE; + } + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(argc == 0 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) { + efree(z_args); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + zend_bool single_array = 0; + if(has_timeout == 0) { + single_array = argc==1 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0])==IS_ARRAY; + } else { + single_array = argc==2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0])==IS_ARRAY && + SW_REDIS_COMMAND_ARGS_TYPE(z_args[1])==IS_LONG; + timeout = SW_REDIS_COMMAND_ARGS_LVAL(z_args[1]); + } + if (single_array) + { + argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 1; + } + else + { + argc++; + } + + SW_REDIS_COMMAND_ALLOC_ARGV + int i = 0; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + char buf[32]; + size_t buf_len; + if (single_array) + { + zval *value; + SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + if(has_timeout) { + buf_len = snprintf(buf, sizeof(buf), "%ld", timeout); + SW_REDIS_COMMAND_ARGV_FILL((char*)buf, buf_len); + } + } + else + { + if(has_timeout && SW_REDIS_COMMAND_ARGS_TYPE(z_args[argc-2]) != IS_LONG) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "Timeout value must be a LONG" TSRMLS_CC); + efree(z_args); + RETURN_FALSE; + } + int j, tail; + tail = has_timeout ? argc - 2 : argc - 1; + for (j = 0; j < tail; ++j) + { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *convert_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + if(has_timeout) { + buf_len = snprintf(buf, sizeof(buf), "%ld", SW_REDIS_COMMAND_ARGS_LVAL(z_args[tail])); + SW_REDIS_COMMAND_ARGV_FILL((char*)buf, buf_len); + } + } + efree(z_args); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + + +static sw_inline void sw_redis_command_key(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &key_len) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[2]; + char *argv[2]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND(2) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + int argc = ZEND_NUM_ARGS(); + + // We at least need a key and one value + if(argc < 2) { + RETURN_FALSE; + } + + // Make sure we at least have a key, and we can get other args + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(zend_get_parameters_array(ht, argc, z_args) == FAILURE) { + efree(z_args); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + + int i = 0, j; + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[0]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0])) +#else + zend_string *convert_str = zval_get_string(&z_args[0]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + for (j = 1; j < argc - 1; ++j) + { + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(SW_REDIS_COMMAND_ARGS_REF(z_args[j])) + } + efree(z_args); + SW_REDIS_COMMAND(argc); + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + long l_val; + zval *z_value; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slz", &key, &key_len, &l_val, &z_value) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%ld", l_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value) + SW_REDIS_COMMAND(4); + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_long_str(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key, *val; + zend_size_t key_len, val_len; + long l_val; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls", &key, &key_len, &l_val, &val, &val_len)==FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%ld", l_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND_ARGV_FILL(val, val_len) + SW_REDIS_COMMAND(4); + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_long(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + long l_val; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &key, &key_len, &l_val)==FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%ld", l_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND(3); + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + long l1_val, l2_val; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &key, &key_len, &l1_val, &l2_val)==FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%ld", l1_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + sprintf(str, "%ld", l2_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND(4); + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_dbl(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + double d_val; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sd", &key, &key_len, &d_val) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%f", d_val); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND(3) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_key(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key1, *key2; + zend_size_t key1_len, key2_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &key1, &key1_len, &key2, &key2_len) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len) + SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len) + SW_REDIS_COMMAND(3) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_val(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key; + zend_size_t key_len; + zval *z_value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &key, &key_len, &z_value) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value) + SW_REDIS_COMMAND(3) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_str(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key, *val; + zend_size_t key_len, val_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &key, &key_len, &val, &val_len) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(val, val_len) + SW_REDIS_COMMAND(3) + SW_REDIS_COMMAND_YIELD +} + +static sw_inline void sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAMETERS, char *cmd, int cmd_len) +{ + char *key, *val1, *val2; + zend_size_t key_len, val1_len, val2_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &key, &key_len, &val1, &val1_len, &val2, &val2_len) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i =0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL(cmd, cmd_len) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(val1, val1_len) + SW_REDIS_COMMAND_ARGV_FILL(val2, val2_len) + SW_REDIS_COMMAND(4) + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, __construct); +static PHP_METHOD(swoole_redis_coro, __destruct); +static PHP_METHOD(swoole_redis_coro, connect); +static PHP_METHOD(swoole_redis_coro, setDefer); +static PHP_METHOD(swoole_redis_coro, getDefer); +static PHP_METHOD(swoole_redis_coro, recv); +static PHP_METHOD(swoole_redis_coro, request); +static PHP_METHOD(swoole_redis_coro, close); +/*---------------------Redis Command------------------------*/ +static PHP_METHOD(swoole_redis_coro, set); +static PHP_METHOD(swoole_redis_coro, setBit); +static PHP_METHOD(swoole_redis_coro, setEx); +static PHP_METHOD(swoole_redis_coro, psetEx); +static PHP_METHOD(swoole_redis_coro, lSet); +static PHP_METHOD(swoole_redis_coro, get); +static PHP_METHOD(swoole_redis_coro, mGet); +static PHP_METHOD(swoole_redis_coro, del); +static PHP_METHOD(swoole_redis_coro, hDel); +static PHP_METHOD(swoole_redis_coro, hSet); +static PHP_METHOD(swoole_redis_coro, hMSet); +static PHP_METHOD(swoole_redis_coro, hSetNx); +static PHP_METHOD(swoole_redis_coro, mSet); +static PHP_METHOD(swoole_redis_coro, mSetNx); +static PHP_METHOD(swoole_redis_coro, getKeys); +static PHP_METHOD(swoole_redis_coro, exists); +static PHP_METHOD(swoole_redis_coro, type); +static PHP_METHOD(swoole_redis_coro, strLen); +static PHP_METHOD(swoole_redis_coro, lPop); +static PHP_METHOD(swoole_redis_coro, blPop); +static PHP_METHOD(swoole_redis_coro, rPop); +static PHP_METHOD(swoole_redis_coro, brPop); +static PHP_METHOD(swoole_redis_coro, bRPopLPush); +static PHP_METHOD(swoole_redis_coro, lSize); +static PHP_METHOD(swoole_redis_coro, sSize); +static PHP_METHOD(swoole_redis_coro, sPop); +static PHP_METHOD(swoole_redis_coro, sMembers); +static PHP_METHOD(swoole_redis_coro, sRandMember); +static PHP_METHOD(swoole_redis_coro, persist); +static PHP_METHOD(swoole_redis_coro, ttl); +static PHP_METHOD(swoole_redis_coro, pttl); +static PHP_METHOD(swoole_redis_coro, zCard); +static PHP_METHOD(swoole_redis_coro, hLen); +static PHP_METHOD(swoole_redis_coro, hKeys); +static PHP_METHOD(swoole_redis_coro, hVals); +static PHP_METHOD(swoole_redis_coro, hGetAll); +static PHP_METHOD(swoole_redis_coro, restore); +static PHP_METHOD(swoole_redis_coro, dump); +static PHP_METHOD(swoole_redis_coro, debug); +static PHP_METHOD(swoole_redis_coro, renameKey); +static PHP_METHOD(swoole_redis_coro, renameNx); +static PHP_METHOD(swoole_redis_coro, rpoplpush); +static PHP_METHOD(swoole_redis_coro, randomKey); +static PHP_METHOD(swoole_redis_coro, ping); +static PHP_METHOD(swoole_redis_coro, auth); +static PHP_METHOD(swoole_redis_coro, unwatch); +static PHP_METHOD(swoole_redis_coro, watch); +static PHP_METHOD(swoole_redis_coro, save); +static PHP_METHOD(swoole_redis_coro, bgSave); +static PHP_METHOD(swoole_redis_coro, lastSave); +static PHP_METHOD(swoole_redis_coro, flushDB); +static PHP_METHOD(swoole_redis_coro, flushAll); +static PHP_METHOD(swoole_redis_coro, dbSize); +static PHP_METHOD(swoole_redis_coro, bgrewriteaof); +static PHP_METHOD(swoole_redis_coro, time); +static PHP_METHOD(swoole_redis_coro, role); +static PHP_METHOD(swoole_redis_coro, setRange); +static PHP_METHOD(swoole_redis_coro, setNx); +static PHP_METHOD(swoole_redis_coro, getSet); +static PHP_METHOD(swoole_redis_coro, append); +static PHP_METHOD(swoole_redis_coro, lPushx); +static PHP_METHOD(swoole_redis_coro, lPush); +static PHP_METHOD(swoole_redis_coro, rPush); +static PHP_METHOD(swoole_redis_coro, rPushx); +static PHP_METHOD(swoole_redis_coro, sContains); +static PHP_METHOD(swoole_redis_coro, zScore); +static PHP_METHOD(swoole_redis_coro, zRank); +static PHP_METHOD(swoole_redis_coro, zRevRank); +static PHP_METHOD(swoole_redis_coro, hGet); +static PHP_METHOD(swoole_redis_coro, hMGet); +static PHP_METHOD(swoole_redis_coro, hExists); +static PHP_METHOD(swoole_redis_coro, publish); +static PHP_METHOD(swoole_redis_coro, zIncrBy); +static PHP_METHOD(swoole_redis_coro, zAdd); +static PHP_METHOD(swoole_redis_coro, zDeleteRangeByScore); +static PHP_METHOD(swoole_redis_coro, zCount); +static PHP_METHOD(swoole_redis_coro, zRange); +static PHP_METHOD(swoole_redis_coro, zRevRange); +static PHP_METHOD(swoole_redis_coro, zRangeByScore); +static PHP_METHOD(swoole_redis_coro, zRevRangeByScore); +static PHP_METHOD(swoole_redis_coro, zRangeByLex); +static PHP_METHOD(swoole_redis_coro, zRevRangeByLex); +static PHP_METHOD(swoole_redis_coro, zInter); +static PHP_METHOD(swoole_redis_coro, zUnion); +static PHP_METHOD(swoole_redis_coro, incrBy); +static PHP_METHOD(swoole_redis_coro, hIncrBy); +static PHP_METHOD(swoole_redis_coro, incr); +static PHP_METHOD(swoole_redis_coro, decrBy); +static PHP_METHOD(swoole_redis_coro, decr); +static PHP_METHOD(swoole_redis_coro, getBit); +static PHP_METHOD(swoole_redis_coro, lGet); +static PHP_METHOD(swoole_redis_coro, lInsert); +static PHP_METHOD(swoole_redis_coro, setTimeout); +static PHP_METHOD(swoole_redis_coro, pexpire); +static PHP_METHOD(swoole_redis_coro, expireAt); +static PHP_METHOD(swoole_redis_coro, pexpireAt); +static PHP_METHOD(swoole_redis_coro, move); +static PHP_METHOD(swoole_redis_coro, select); +static PHP_METHOD(swoole_redis_coro, getRange); +static PHP_METHOD(swoole_redis_coro, listTrim); +static PHP_METHOD(swoole_redis_coro, lGetRange); +static PHP_METHOD(swoole_redis_coro, lRem); +static PHP_METHOD(swoole_redis_coro, zDeleteRangeByRank); +static PHP_METHOD(swoole_redis_coro, incrByFloat); +static PHP_METHOD(swoole_redis_coro, hIncrByFloat); +static PHP_METHOD(swoole_redis_coro, bitCount); +static PHP_METHOD(swoole_redis_coro, bitOp); +static PHP_METHOD(swoole_redis_coro, sAdd); +static PHP_METHOD(swoole_redis_coro, sMove); +static PHP_METHOD(swoole_redis_coro, sDiff); +static PHP_METHOD(swoole_redis_coro, sDiffStore); +static PHP_METHOD(swoole_redis_coro, sUnion); +static PHP_METHOD(swoole_redis_coro, sUnionStore); +static PHP_METHOD(swoole_redis_coro, sInter); +static PHP_METHOD(swoole_redis_coro, sInterStore); +static PHP_METHOD(swoole_redis_coro, sRemove); +static PHP_METHOD(swoole_redis_coro, zDelete); +static PHP_METHOD(swoole_redis_coro, subscribe); +static PHP_METHOD(swoole_redis_coro, pSubscribe); +static PHP_METHOD(swoole_redis_coro, multi); +static PHP_METHOD(swoole_redis_coro, exec); +static PHP_METHOD(swoole_redis_coro, eval); +static PHP_METHOD(swoole_redis_coro, evalSha); +static PHP_METHOD(swoole_redis_coro, script); +/*---------------------Redis Command End------------------------*/ + +static const zend_function_entry swoole_redis_coro_methods[] = +{ + PHP_ME(swoole_redis_coro, __construct, arginfo_swoole_redis_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_redis_coro, __destruct, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_redis_coro, connect, arginfo_swoole_redis_coro_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setDefer, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, getDefer, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, recv, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, request, arginfo_swoole_redis_coro_request, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, close, NULL, ZEND_ACC_PUBLIC) + /*---------------------Redis Command------------------------*/ + PHP_ME(swoole_redis_coro, set, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setBit, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setEx, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, psetEx, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lSet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, get, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, mGet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, del, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hDel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hSet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hMSet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hSetNx, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, delete, del, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, mSet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, mSetNx, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, getKeys, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, keys, getKeys, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, exists, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, type, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, strLen, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lPop, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, blPop, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, rPop, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, brPop, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, bRPopLPush, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lSize, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, lLen, lSize, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sSize, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, scard, sSize, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sPop, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sMembers, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, sGetMembers, sMembers, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sRandMember, arginfo_swoole_redis_coro_key_opt_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, persist, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, ttl, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, pttl, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zCard, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zSize, zCard, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hLen, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hKeys, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hVals, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hGetAll, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, debug, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, restore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, dump, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, renameKey, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, rename, renameKey, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, renameNx, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, rpoplpush, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, randomKey, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, ping, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, auth, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, unwatch, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, watch, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, save, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, bgSave, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lastSave, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, flushDB, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, flushAll, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, dbSize, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, bgrewriteaof, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, time, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, role, arginfo_swoole_redis_coro_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setRange, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setNx, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, getSet, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, append, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lPushx, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lPush, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, rPush, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, rPushx, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sContains, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, sismember, sContains, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zScore, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRank, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRevRank, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hGet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hMGet, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hExists, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, publish, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zIncrBy, arginfo_swoole_redis_coro_zIncrBy, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zAdd, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zDeleteRangeByScore, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zRemRangeByScore, zDeleteRangeByScore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zCount, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRange, arginfo_swoole_redis_coro_zRange, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRevRange, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRangeByScore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRevRangeByScore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRangeByLex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zRevRangeByLex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zInter, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zinterstore, zInter, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zUnion, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zunionstore, zUnion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, incrBy, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hIncrBy, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, incr, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, decrBy, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, decr, arginfo_swoole_redis_coro_key, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, getBit, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lInsert, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lGet, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, lIndex, lGet, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, setTimeout, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, expire, setTimeout, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, pexpire, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, expireAt, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, pexpireAt, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, move, arginfo_swoole_redis_coro_key_long, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, select, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, getRange, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, listTrim, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, ltrim, listTrim, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lGetRange, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, lRange, lGetRange, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, lRem, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, lRemove,lRem, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zDeleteRangeByRank, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zRemRangeByRank, zDeleteRangeByRank, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, incrByFloat, arginfo_swoole_redis_coro_incrByFloat, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, hIncrByFloat, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, bitCount, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, bitOp, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sAdd, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sMove, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sDiff, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sDiffStore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sUnion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sUnionStore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sInter, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sInterStore, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, sRemove, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, srem, sRemove, arginfo_swoole_redis_coro_key_value, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, zDelete, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zRemove, zDelete, NULL, ZEND_ACC_PUBLIC) + PHP_MALIAS(swoole_redis_coro, zRem, zDelete, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, pSubscribe, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, subscribe, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, multi, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, exec, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, eval, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, evalSha, NULL, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_coro, script, NULL, ZEND_ACC_PUBLIC) + /*---------------------Redis Command End------------------------*/ + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) + PHP_FE_END +}; + +void swoole_redis_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_redis_coro_ce, "Swoole\\Coroutine\\Redis", swoole_redis_coro_methods); + swoole_redis_coro_class_entry_ptr = zend_register_internal_class(&swoole_redis_coro_ce TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Redis", swoole_redis_coro_class_entry_ptr); + } + + zend_declare_property_null(swoole_redis_coro_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_coro_class_entry_ptr, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_coro_class_entry_ptr, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_redis_coro_class_entry_ptr, ZEND_STRL("sock"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_bool(swoole_redis_coro_class_entry_ptr, ZEND_STRL("connected"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_redis_coro_class_entry_ptr, SW_STRL("errCode")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_string(swoole_redis_coro_class_entry_ptr, SW_STRL("errMsg")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC); + + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_MODE_MULTI", SW_REDIS_MODE_MULTI, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_MODE_PIPELINE", SW_REDIS_MODE_PIPELINE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_NOT_FOUND", SW_REDIS_NOT_FOUND, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_STRING", SW_REDIS_STRING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_SET", SW_REDIS_SET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_LIST", SW_REDIS_LIST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_ZSET", SW_REDIS_ZSET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SWOOLE_REDIS_TYPE_HASH", SW_REDIS_HASH, CONST_CS | CONST_PERSISTENT); +} + +static void redis_coro_close(void* data) +{ + redisAsyncContext *context = data; + redisAsyncDisconnect(context); +} + +static void redis_coro_free(void* redis) +{ + efree(redis); +} + +static swRedisClient* redis_coro_create(zval *object) +{ + swRedisClient *redis = emalloc(sizeof(swRedisClient)); + bzero(redis, sizeof(swRedisClient)); + + redis->object = object; + sw_copy_to_stack(redis->object, redis->_object); + + swoole_set_object(object, redis); + + redis->state = SWOOLE_REDIS_CORO_STATE_CONNECT; + redis->iowait = SW_REDIS_CORO_STATUS_READY; + redis->pipeline_result = NULL; + redis->timeout = SW_REDIS_CONNECT_TIMEOUT; + + return redis; +} + +static PHP_METHOD(swoole_redis_coro, __construct) +{ + zval *zset = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "|z", &zset) == FAILURE) + { + return; + } + + swRedisClient *redis = redis_coro_create(getThis()); + + if (zset && !ZVAL_IS_NULL(zset)) + { + php_swoole_array_separate(zset); + zend_update_property(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("setting"), zset TSRMLS_CC); + sw_zval_ptr_dtor(&zset); + + HashTable *vht; + zval *ztmp; + vht = Z_ARRVAL_P(zset); + /** + * timeout + */ + if (php_swoole_array_get_value(vht, "timeout", ztmp)) + { + convert_to_double(ztmp); + redis->timeout = (double) Z_DVAL_P(ztmp); + } + } +} + +static PHP_METHOD(swoole_redis_coro, connect) +{ + char *host; + zend_size_t host_len; + long port; + zend_bool serialize = 0; + + coro_check(TSRMLS_C); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|b", &host, &host_len, &port, &serialize) == FAILURE) + { + return; + } + + if (host_len <= 0) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "host is empty." TSRMLS_CC); + RETURN_FALSE; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis) + { + redis = redis_coro_create(getThis()); + } + + redis->serialize = serialize; + redisAsyncContext *context; + + if (redis->connected) + { + swoole_php_fatal_error(E_WARNING, "connection to the server has already been established."); + RETURN_FALSE; + } + + if (strncasecmp(host, ZEND_STRL("unix:/")) == 0) + { + context = redisAsyncConnectUnix(host + 5); + } + else + { + if (port <= 1 || port > 65535) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "port is invalid." TSRMLS_CC); + RETURN_FALSE; + } + context = redisAsyncConnect(host, (int) port); + } + + if (context->err) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), context->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), context->errstr TSRMLS_CC); + RETURN_FALSE; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS_CORO)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS_CORO | SW_EVENT_READ, swoole_redis_coro_onRead); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS_CORO | SW_EVENT_WRITE, swoole_redis_coro_onWrite); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_REDIS_CORO | SW_EVENT_ERROR, swoole_redis_coro_onError); + } + + redisAsyncSetConnectCallback(context, swoole_redis_coro_onConnect); + redisAsyncSetDisconnectCallback(context, swoole_redis_coro_onClose); + + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("sock"), context->c.fd TSRMLS_CC); + + redis->context = context; + context->ev.addRead = swoole_redis_coro_event_AddRead; + context->ev.delRead = swoole_redis_coro_event_DelRead; + context->ev.addWrite = swoole_redis_coro_event_AddWrite; + context->ev.delWrite = swoole_redis_coro_event_DelWrite; + context->ev.cleanup = swoole_redis_coro_event_Cleanup; + context->ev.data = redis; + + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("host"), host TSRMLS_CC); + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("port"), port TSRMLS_CC); + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, redis->context->c.fd, PHP_SWOOLE_FD_REDIS_CORO | SW_EVENT_WRITE) < 0) + { + swoole_php_fatal_error(E_WARNING, "swoole_event_add failed. Erorr: %s[%d].", redis->context->errstr, redis->context->err); + RETURN_FALSE; + } + + swConnection *conn = swReactor_get(SwooleG.main_reactor, redis->context->c.fd); + conn->object = redis; + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + if (!sw_current_context) + { + sw_current_context = emalloc(sizeof(php_context)); + swoole_set_property(getThis(), 0, sw_current_context); + } + sw_current_context->state = SW_CORO_CONTEXT_RUNNING; + sw_current_context->onTimeout = NULL; +#if PHP_MAJOR_VERSION < 7 + sw_current_context->coro_params = getThis(); +#else + sw_current_context->coro_params = *getThis(); +#endif + if (redis->timeout > 0) + { + php_swoole_check_timer((int) (redis->timeout * 1000)); + redis->timer = SwooleG.timer.add(&SwooleG.timer, (int) (redis->timeout * 1000), 0, sw_current_context, swoole_redis_coro_onTimeout); + } + coro_save(sw_current_context); + coro_yield(); +} + +static PHP_METHOD(swoole_redis_coro, getDefer) +{ + swRedisClient *redis = swoole_get_object(getThis()); + + RETURN_BOOL(redis->defer); +} + +static PHP_METHOD(swoole_redis_coro, setDefer) +{ + zend_bool defer = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &defer) == FAILURE) + { + return; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (redis->iowait > SW_REDIS_CORO_STATUS_READY) + { + RETURN_BOOL(defer); + } + + redis->defer = defer; + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis_coro, recv) +{ + swRedisClient *redis = swoole_get_object(getThis()); + + if (!redis->defer) + { + swoole_php_fatal_error(E_WARNING, "you should not use recv without defer."); + RETURN_FALSE; + } + + if (redis->iowait == SW_REDIS_CORO_STATUS_DONE) + { + redis->iowait = SW_REDIS_CORO_STATUS_READY; + zval *result = redis->defer_result; + RETVAL_ZVAL(result, 0, 0); + efree(result); + redis->defer_result = NULL; + return; + } + + if (redis->iowait != SW_REDIS_CORO_STATUS_WAIT) + { + swoole_php_fatal_error(E_WARNING, "no request."); + RETURN_FALSE; + } + + redis->cid = sw_get_current_cid(); + redis->defer_yield = 1; + php_context *sw_current_context = swoole_get_property(getThis(), 0); + coro_save(sw_current_context); + coro_yield(); +} + +static PHP_METHOD(swoole_redis_coro, close) +{ + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis || !redis->context) + { + RETURN_FALSE; + } + if (redis->timer) + { + swTimer_del(&SwooleG.timer, redis->timer); + redis->timer = NULL; + } + if (redis->state == SWOOLE_REDIS_CORO_STATE_CLOSED) + { + RETURN_TRUE; + } + if (unlikely(redis->cid && redis->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "redis client has already been bound to another coroutine."); + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, redis->context->c.fd); + _socket->active = 0; + + redis->connected = 0; + redis->state = SWOOLE_REDIS_CORO_STATE_CLOSING; + redis->iowait = SW_REDIS_CORO_STATUS_CLOSED; + redisCallback *head = redis->context->replies.head; + redisCallback *cb = head; + while (head != NULL) + { + head = cb->next; + free(cb); + cb = head; + } + + redis->object = NULL; + redis->released = 1; + redis->context->replies.head = NULL; + if (redis->connecting) + { + SwooleG.main_reactor->defer(SwooleG.main_reactor, redis_coro_close, redis->context); + } + else + { + redis_coro_close(redis->context); + } + + zend_update_property_bool(swoole_redis_coro_class_entry_ptr, getThis(), SW_STRL("connected") - 1, 0); + swoole_set_object(getThis(), NULL); + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis_coro, __destruct) +{ + swTraceLog(SW_TRACE_REDIS_CLIENT, "object_id=%d", sw_get_object_handle(getThis())); + + php_context *sw_current_context = swoole_get_property(getThis(), 0); + if (sw_current_context) + { + efree(sw_current_context); + swoole_set_property(getThis(), 0, NULL); + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis) + { + return; + } + if (redis->state != SWOOLE_REDIS_CORO_STATE_CLOSED && redis->state != SWOOLE_REDIS_CORO_STATE_CONNECT) + { + swTraceLog(SW_TRACE_REDIS_CLIENT, "close connection, fd=%d", redis->context->c.fd); + + zval *retval = NULL; + zval *zobject = getThis(); + sw_zend_call_method_with_0_params(&zobject, swoole_redis_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } + else if (!redis->released) + { + swoole_set_object(getThis(), NULL); + efree(redis); + } +} + +static PHP_METHOD(swoole_redis_coro, set) +{ + char *key, *exp_type = NULL, *set_type = NULL; + zend_size_t key_len, argc = 3; + zval *z_value, *z_opts = NULL; + long expire = -1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &key, &key_len, &z_value, &z_opts) == FAILURE) + { + return; + } + + SW_REDIS_COMMAND_CHECK + + if (z_opts && Z_TYPE_P(z_opts) != IS_LONG && Z_TYPE_P(z_opts) != IS_ARRAY + && Z_TYPE_P(z_opts) != IS_NULL) + { + RETURN_FALSE; + } + + if (z_opts && Z_TYPE_P(z_opts) == IS_ARRAY) { + HashTable *kt = Z_ARRVAL_P(z_opts); + +#if PHP_MAJOR_VERSION >= 7 + zend_string *zkey; + zend_ulong idx; + zval *v; + + /* Iterate our option array */ + ZEND_HASH_FOREACH_KEY_VAL(kt, idx, zkey, v) { + /* Detect PX or EX argument and validate timeout */ + if (zkey && IS_EX_PX_ARG(zkey->val)) { + /* Set expire type */ + exp_type = zkey->val; + + /* Try to extract timeout */ + if (Z_TYPE_P(v) == IS_LONG) { + expire = Z_LVAL_P(v); + } else if (Z_TYPE_P(v) == IS_STRING) { + expire = atol(Z_STRVAL_P(v)); + } + + /* Expiry can't be set < 1 */ + if (expire < 1) RETURN_FALSE; + argc += 2; + } else if (Z_TYPE_P(v) == IS_STRING && IS_NX_XX_ARG(Z_STRVAL_P(v))) { + argc += 1; + set_type = Z_STRVAL_P(v); + } + (void) idx; + } ZEND_HASH_FOREACH_END(); +#else + int type; + unsigned int ht_key_len; + unsigned long idx; + char *k; + zval **v; + + /* Iterate our option array */ + for(zend_hash_internal_pointer_reset(kt); + zend_hash_has_more_elements(kt) == SUCCESS; + zend_hash_move_forward(kt)) + { + // Grab key and value + type = zend_hash_get_current_key_ex(kt, &k, &ht_key_len, &idx, 0, NULL); + zend_hash_get_current_data(kt, (void**)&v); + + /* Detect PX or EX argument and validate timeout */ + if (type == HASH_KEY_IS_STRING && IS_EX_PX_ARG(k)) { + /* Set expire type */ + exp_type = k; + + /* Try to extract timeout */ + if (Z_TYPE_PP(v) == IS_LONG) { + expire = Z_LVAL_PP(v); + } else if (Z_TYPE_PP(v) == IS_STRING) { + expire = atol(Z_STRVAL_PP(v)); + } + + /* Expiry can't be set < 1 */ + if (expire < 1) RETURN_FALSE; + argc += 2; + } else if (Z_TYPE_PP(v) == IS_STRING && IS_NX_XX_ARG(Z_STRVAL_PP(v))) { + argc += 1; + set_type = Z_STRVAL_PP(v); + } + (void) idx; + } +#endif + } else if(z_opts && Z_TYPE_P(z_opts) == IS_LONG) { + /* Grab expiry and fail if it's < 1 */ + expire = Z_LVAL_P(z_opts); + if (expire < 1) RETURN_FALSE; + argc += 1; + } + + SW_REDIS_COMMAND_ALLOC_ARGV + + int i = 0; + if (exp_type || set_type) + { + SW_REDIS_COMMAND_ARGV_FILL("SET", 3) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value) + + if (set_type) + { + SW_REDIS_COMMAND_ARGV_FILL(set_type, (size_t) strlen(set_type)) + } + + if (exp_type) + { + SW_REDIS_COMMAND_ARGV_FILL(exp_type, (size_t) strlen(exp_type)) + + char str[32]; + sprintf(str, "%ld", expire); + SW_REDIS_COMMAND_ARGV_FILL(str, (size_t) strlen(str)) + } + } else if (expire > 0) { + SW_REDIS_COMMAND_ARGV_FILL("SETEX", 5) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + + char str[32]; + sprintf(str, "%ld", expire); + SW_REDIS_COMMAND_ARGV_FILL(str, (size_t) strlen(str)) + + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value) + } else { + SW_REDIS_COMMAND_ARGV_FILL("SET", 3) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_value) + } + + SW_REDIS_COMMAND(argc) + + SW_REDIS_COMMAND_FREE_ARGV + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, setBit) +{ + char *key; + zend_size_t key_len; + long offset; + zend_bool val; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slb", &key, &key_len, + &offset, &val)==FAILURE) + { + return; + } + + // Validate our offset + if(offset < SW_BITOP_MIN_OFFSET || offset >SW_BITOP_MAX_OFFSET) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Invalid OFFSET for bitop command (must be between 0-2^32-1)" TSRMLS_CC); + RETURN_FALSE; + } + + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + + SW_REDIS_COMMAND_ARGV_FILL("SETBIT", 6) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + + char str[32]; + sprintf(str, "%ld", offset); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + + SW_REDIS_COMMAND_ARGV_FILL(val ? "1" : "0", 1) + + SW_REDIS_COMMAND(4); + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, setEx) +{ + sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SETEX", 5); +} + +static PHP_METHOD(swoole_redis_coro, psetEx) +{ + sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PSETEX", 6); +} + +static PHP_METHOD(swoole_redis_coro, lSet) +{ + sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LSET", 4); +} + +static PHP_METHOD(swoole_redis_coro, restore) +{ + sw_redis_command_key_long_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RESTORE", 7); +} + +static PHP_METHOD(swoole_redis_coro, dump) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DUMP", 4); +} + +static PHP_METHOD(swoole_redis_coro, debug) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DEBUG", 5); +} + +static PHP_METHOD(swoole_redis_coro, get) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "GET", 3); +} + +static PHP_METHOD(swoole_redis_coro, mGet) +{ + zval *z_args; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "a", &z_args) == FAILURE) + { + return; + } + int argc; + argc = zend_hash_num_elements(Z_ARRVAL_P(z_args)); + if (argc == 0) + { + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + int i = 0; + zval *value; + SW_REDIS_COMMAND_ARGV_FILL("MGET", 4) + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(z_args), value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hSet) +{ + char *key, *field; + zend_size_t key_len, field_len; + zval *z_val; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz", &key, &key_len, + &field, &field_len, &z_val) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("HSET", 4) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(field, field_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hMSet) +{ + char *key; + zend_size_t key_len, argc; + zval *z_arr; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &key, &key_len, + &z_arr)==FAILURE) + { + return; + } + if((argc = zend_hash_num_elements(Z_ARRVAL_P(z_arr))) == 0) { + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + argc = argc * 2 + 2; + zval *value; + char buf[32]; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("HMSET", 5) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) +#if (PHP_MAJOR_VERSION < 7) + int keytype; + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(z_arr), key, key_len, keytype, value) + { + if (HASH_KEY_IS_STRING != keytype) + { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } + SW_HASHTABLE_FOREACH_END(); +#else + zend_ulong idx; + zend_string *_key; + ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_arr), idx, _key, value) { + if (_key == NULL) { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } else { + key_len = ZSTR_LEN(_key); + key = ZSTR_VAL(_key); + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } ZEND_HASH_FOREACH_END(); +#endif + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hSetNx) +{ + char *key, *field; + zend_size_t key_len, field_len; + zval *z_val; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz", &key, &key_len, + &field, &field_len, &z_val) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[4]; + char *argv[4]; + convert_to_string(z_val); + SW_REDIS_COMMAND_ARGV_FILL("HSETNX", 6) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(field, field_len) + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(z_val), Z_STRLEN_P(z_val)) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hDel) +{ + int argc = ZEND_NUM_ARGS(); + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(argc < 2 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) { + efree(z_args); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + argc++; + int i = 0, j; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("HDEL", 4) + for (j = 0; j < argc-1; ++j) + { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *convert_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + efree(z_args); + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, watch) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "WATCH", 5, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, del) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DEL", 3, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sDiff) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SDIFF", 5, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sDiffStore) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SDIFFSTORE", 10, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sUnion) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SUNION", 6, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sUnionStore) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SUNIONSTORE", 11, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sInter) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SINTER", 6, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, sInterStore) +{ + sw_redis_command_var_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SINTERSTORE", 11, 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, mSet) +{ + zval *z_args; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &z_args) == FAILURE) + { + return; + } + int argc; + argc = zend_hash_num_elements(Z_ARRVAL_P(z_args)); + if (argc == 0) + { + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + argc *= 2; + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + int i = 0; + SW_REDIS_COMMAND_ARGV_FILL("MSET", 4) + zval *value; + char buf[32]; + char *key; + uint32_t key_len; +#if (PHP_MAJOR_VERSION < 7) + int keytype; + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(z_args), key, key_len, keytype, value) + { + if (HASH_KEY_IS_STRING != keytype) + { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } + SW_HASHTABLE_FOREACH_END(); +#else + zend_ulong idx; + zend_string *_key; + ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_args), idx, _key, value) { + if (_key == NULL) { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } else { + key_len = ZSTR_LEN(_key); + key = ZSTR_VAL(_key); + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } ZEND_HASH_FOREACH_END(); +#endif + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, mSetNx) +{ + zval *z_args; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &z_args)==FAILURE) + { + return; + } + int argc; + argc = zend_hash_num_elements(Z_ARRVAL_P(z_args)); + if (argc == 0) + { + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + argc *= 2; + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + int i = 0; + SW_REDIS_COMMAND_ARGV_FILL("MSETNX", 6) + zval *value; + char buf[32]; + char *key; + uint32_t key_len; +#if (PHP_MAJOR_VERSION < 7) + int keytype; + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(z_args), key, key_len, keytype, value) + { + if (HASH_KEY_IS_STRING != keytype) + { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } + SW_HASHTABLE_FOREACH_END(); +#else + zend_ulong idx; + zend_string *_key; + ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(z_args), idx, _key, value) { + if (_key == NULL) { + key_len = snprintf(buf, sizeof(buf), "%ld", (long)idx); + key = (char*)buf; + } else { + key_len = ZSTR_LEN(_key); + key = ZSTR_VAL(_key); + } + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(value) + } ZEND_HASH_FOREACH_END(); +#endif + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, getKeys) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "KEYS", 4); +} + +static PHP_METHOD(swoole_redis_coro, exists) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "EXISTS", 6); +} + +static PHP_METHOD(swoole_redis_coro, type) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "TYPE", 4); +} + +static PHP_METHOD(swoole_redis_coro, strLen) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "STRLEN", 6); +} + +static PHP_METHOD(swoole_redis_coro, lPop) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LPOP", 4); +} + +static PHP_METHOD(swoole_redis_coro, bRPopLPush) +{ + char *key1, *key2; + zend_size_t key1_len, key2_len; + long timeout; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &key1, &key1_len, + &key2, &key2_len, &timeout) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int argc, i = 0; + argc = timeout < 0 ? 3 : 4; + SW_REDIS_COMMAND_ALLOC_ARGV + if (timeout < 0) + { + SW_REDIS_COMMAND_ARGV_FILL("RPOPLPUSH", 9) + SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len) + SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len) + } + else + { + SW_REDIS_COMMAND_ARGV_FILL("BRPOPLPUSH", 10) + SW_REDIS_COMMAND_ARGV_FILL(key1, key1_len) + SW_REDIS_COMMAND_ARGV_FILL(key2, key2_len) + char str[32]; + sprintf(str, "%ld", timeout); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + } + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, blPop) +{ + int argc = ZEND_NUM_ARGS(); + + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) + { + efree(z_args); + return; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + + zend_bool single_array = 0; + if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) + { + argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2; + single_array = 1; + } + else + { + argc += 1; + } + int i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("BLPOP", 5) + if (single_array) + { + zval *value; + SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[1]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[1]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[1])) +#else + zend_string *convert_str = zval_get_string(&z_args[1]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + else + { + int j; + for (j = 0; j < argc - 1; ++j) + { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *convert_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + } + efree(z_args); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, brPop) +{ + int argc = ZEND_NUM_ARGS(); + + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(zend_get_parameters_array(ht, argc, z_args) == FAILURE || argc < 1) + { + efree(z_args); + return; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + + zend_bool single_array = 0; + if (argc == 2 && SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) == IS_ARRAY) + { + argc = zend_hash_num_elements(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0])) + 2; + single_array = 1; + } + else + { + argc += 1; + } + int i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("BRPOP", 5) + if (single_array) + { + zval *value; + SW_HASHTABLE_FOREACH_START(SW_REDIS_COMMAND_ARGS_ARRVAL(z_args[0]), value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[1]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[1]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[1])) +#else + zend_string *convert_str = zval_get_string(&z_args[1]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + else + { + int j; + for (j = 0; j < argc - 1; ++j) + { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *convert_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + } + efree(z_args); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, rPop) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPOP", 4); +} + +static PHP_METHOD(swoole_redis_coro, lSize) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LLEN", 4); +} + +static PHP_METHOD(swoole_redis_coro, sSize) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SCARD", 5); +} + +static PHP_METHOD(swoole_redis_coro, sPop) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SPOP", 4); +} + +static PHP_METHOD(swoole_redis_coro, sMembers) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SMEMBERS", 8); +} + +static PHP_METHOD(swoole_redis_coro, sRandMember) +{ + char *key; + zend_size_t key_len; + long count; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &key, &key_len, + &count) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0, argc, buf_len; + char buf[32]; + argc = ZEND_NUM_ARGS() == 2 ? 3 : 2; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("SRANDMEMBER", 11); + SW_REDIS_COMMAND_ARGV_FILL(key, key_len); + if (argc == 3) + { + buf_len = snprintf(buf, sizeof(buf), "%ld", count); + SW_REDIS_COMMAND_ARGV_FILL((char *)buf, buf_len); + } + SW_REDIS_COMMAND(argc); + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, persist) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PERSIST", 7); +} + +static PHP_METHOD(swoole_redis_coro, ttl) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "TTL", 3); +} + +static PHP_METHOD(swoole_redis_coro, pttl) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PTTL", 4); +} + +static PHP_METHOD(swoole_redis_coro, zCard) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZCARD", 5); +} + +static PHP_METHOD(swoole_redis_coro, hLen) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HLEN", 4); +} + +static PHP_METHOD(swoole_redis_coro, hKeys) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HKEYS", 5); +} + +static PHP_METHOD(swoole_redis_coro, hVals) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HVALS", 5); +} + +static PHP_METHOD(swoole_redis_coro, hGetAll) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HGETALL", 7); +} + +static PHP_METHOD(swoole_redis_coro, renameKey) +{ + sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RENAME", 6); +} + +static PHP_METHOD(swoole_redis_coro, renameNx) +{ + sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RENAMENX", 8); +} + +static PHP_METHOD(swoole_redis_coro, rpoplpush) +{ + sw_redis_command_key_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPOPLPUSH", 9); +} + +static PHP_METHOD(swoole_redis_coro, randomKey) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RANDOMKEY", 9); +} + +static PHP_METHOD(swoole_redis_coro, unwatch) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "UNWATCH", 7); +} + +static PHP_METHOD(swoole_redis_coro, ping) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PING", 4); +} + +static PHP_METHOD(swoole_redis_coro, auth) +{ + char *pw; + zend_size_t pw_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pw, &pw_len) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t argvlen[2]; + char *argv[2]; + SW_REDIS_COMMAND_ARGV_FILL("AUTH", 4) + SW_REDIS_COMMAND_ARGV_FILL(pw, pw_len) + SW_REDIS_COMMAND(2) + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, save) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SAVE", 4); +} + +static PHP_METHOD(swoole_redis_coro, bgSave) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "BGSAVE", 6); +} + +static PHP_METHOD(swoole_redis_coro, lastSave) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LASTSAVE", 8); +} + +static PHP_METHOD(swoole_redis_coro, flushDB) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "FLUSHDB", 7); +} + +static PHP_METHOD(swoole_redis_coro, flushAll) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "FLUSHALL", 8); +} + +static PHP_METHOD(swoole_redis_coro, dbSize) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DBSIZE", 6); +} + +static PHP_METHOD(swoole_redis_coro, bgrewriteaof) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "BGREWRITEAOF", 12); +} + +static PHP_METHOD(swoole_redis_coro, time) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "TIME", 4); +} + +static PHP_METHOD(swoole_redis_coro, role) +{ + sw_redis_command_empty(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ROLE", 4); +} + +static PHP_METHOD(swoole_redis_coro, setRange) +{ + sw_redis_command_key_long_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SETRANGE", 8); +} + +static PHP_METHOD(swoole_redis_coro, setNx) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SETNX", 5); +} + +static PHP_METHOD(swoole_redis_coro, getSet) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "GETSET", 6); +} + +static PHP_METHOD(swoole_redis_coro, append) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "APPEND", 6); +} + +static PHP_METHOD(swoole_redis_coro, lPushx) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LPUSHX", 6); +} + +static PHP_METHOD(swoole_redis_coro, lPush) +{ + sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LPUSH", 5); +} + +static PHP_METHOD(swoole_redis_coro, rPush) +{ + sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPUSH", 5); +} + +static PHP_METHOD(swoole_redis_coro, rPushx) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "RPUSHX", 6); +} + +static PHP_METHOD(swoole_redis_coro, sContains) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SISMEMBER", 9); +} + +static PHP_METHOD(swoole_redis_coro, zRange) +{ + char *key; + zend_size_t key_len; + long start, end; + zend_bool ws = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sll|b", &key, &key_len, &start, &end, &ws) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0, argc; + argc = ZEND_NUM_ARGS() + 1; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZRANGE", 6) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char buf[32]; + size_t buf_len; + buf_len = snprintf(buf, sizeof(buf), "%ld", start); + SW_REDIS_COMMAND_ARGV_FILL((char* )buf, buf_len) + buf_len = snprintf(buf, sizeof(buf), "%ld", end); + SW_REDIS_COMMAND_ARGV_FILL((char* )buf, buf_len) + if (ws) + { + SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10) + } + else + { + argc = 4; + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zRevRange) +{ + char *key; + zend_size_t key_len; + long start, end; + zend_bool ws = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|b", &key, &key_len, &start, &end, &ws) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0, argc; + argc = ZEND_NUM_ARGS() + 1; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGE", 9) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char buf[32]; + size_t buf_len; + buf_len = snprintf(buf, sizeof(buf), "%ld", start); + SW_REDIS_COMMAND_ARGV_FILL((char* )buf, buf_len) + buf_len = snprintf(buf, sizeof(buf), "%ld", end); + SW_REDIS_COMMAND_ARGV_FILL((char* )buf, buf_len) + if (ws) + { + SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10) + } + else + { + argc = 4; + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zUnion) +{ + char *key, *agg_op; + zend_size_t key_len; + zval *z_keys, *z_weights=NULL; + HashTable *ht_keys, *ht_weights=NULL; + zend_size_t argc = 2, agg_op_len=0, keys_count; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!s", &key, + &key_len, &z_keys, &z_weights, &agg_op, + &agg_op_len) == FAILURE) + { + return; + } + + ht_keys = Z_ARRVAL_P(z_keys); + + if((keys_count = zend_hash_num_elements(ht_keys)) == 0) { + RETURN_FALSE; + } else { + argc += keys_count + 1; + } + + if(z_weights != NULL) { + ht_weights = Z_ARRVAL_P(z_weights); + if(zend_hash_num_elements(ht_weights) != keys_count) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "WEIGHTS and keys array should be the same size!" TSRMLS_CC); + RETURN_FALSE; + } + + argc += keys_count + 1; + } + + // AGGREGATE option + if(agg_op_len != 0) { + if(strncasecmp(agg_op, "SUM", sizeof("SUM")) && + strncasecmp(agg_op, "MIN", sizeof("MIN")) && + strncasecmp(agg_op, "MAX", sizeof("MAX"))) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Invalid AGGREGATE option provided!" TSRMLS_CC); + RETURN_FALSE; + } + + // "AGGREGATE" + type + argc += 2; + } + SW_REDIS_COMMAND_CHECK + + int i = 0, j; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZUNIONSTORE", 11) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%d", keys_count); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + + // Process input keys + zval *value; + SW_HASHTABLE_FOREACH_START(ht_keys, value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + + // Weights + if(ht_weights != NULL) { + SW_REDIS_COMMAND_ARGV_FILL("WEIGHTS", 7) + + SW_HASHTABLE_FOREACH_START(ht_weights, value) + if(SW_Z_TYPE_P(value) != IS_LONG && SW_Z_TYPE_P(value) != IS_DOUBLE && + strncasecmp(Z_STRVAL_P(value),"inf",sizeof("inf")) != 0 && + strncasecmp(Z_STRVAL_P(value),"-inf",sizeof("-inf")) != 0 && + strncasecmp(Z_STRVAL_P(value),"+inf",sizeof("+inf")) != 0) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), "Weights must be numeric or '-inf','inf','+inf'" TSRMLS_CC); + for (j = 0; j < i; j++) + { + efree((void* )argv[j]); + } + SW_REDIS_COMMAND_FREE_ARGV + RETURN_FALSE; + } + switch (SW_Z_TYPE_P(value)) { + case IS_LONG: + buf_len = sprintf(buf, "%ld", Z_LVAL_P(value)); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + break; + case IS_DOUBLE: + buf_len = sprintf(buf, "%f", Z_DVAL_P(value)); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + break; + case IS_STRING: + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) + break; + } + SW_HASHTABLE_FOREACH_END(); + } + + // AGGREGATE + if(agg_op_len != 0) { + SW_REDIS_COMMAND_ARGV_FILL("AGGREGATE", 9) + SW_REDIS_COMMAND_ARGV_FILL(agg_op, agg_op_len) + } + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zInter) +{ + char *key, *agg_op; + zend_size_t key_len; + zval *z_keys, *z_weights=NULL; + HashTable *ht_keys, *ht_weights=NULL; + zend_size_t argc = 2, agg_op_len=0, keys_count; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|a!s", &key, + &key_len, &z_keys, &z_weights, &agg_op, + &agg_op_len) == FAILURE) + { + return; + } + + ht_keys = Z_ARRVAL_P(z_keys); + + if((keys_count = zend_hash_num_elements(ht_keys)) == 0) { + RETURN_FALSE; + } else { + argc += keys_count + 1; + } + + if(z_weights != NULL) { + ht_weights = Z_ARRVAL_P(z_weights); + if(zend_hash_num_elements(ht_weights) != keys_count) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "WEIGHTS and keys array should be the same size!" TSRMLS_CC); + RETURN_FALSE; + } + + argc += keys_count + 1; + } + + // AGGREGATE option + if(agg_op_len != 0) { + if(strncasecmp(agg_op, "SUM", sizeof("SUM")) && + strncasecmp(agg_op, "MIN", sizeof("MIN")) && + strncasecmp(agg_op, "MAX", sizeof("MAX"))) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Invalid AGGREGATE option provided!" TSRMLS_CC); + RETURN_FALSE; + } + + // "AGGREGATE" + type + argc += 2; + } + SW_REDIS_COMMAND_CHECK + + int i = 0, j; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZINTERSTORE", 11) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%d", keys_count); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + + // Process input keys + zval *value; + SW_HASHTABLE_FOREACH_START(ht_keys, value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + + // Weights + if(ht_weights != NULL) { + SW_REDIS_COMMAND_ARGV_FILL("WEIGHTS", 7) + + SW_HASHTABLE_FOREACH_START(ht_weights, value) + if(SW_Z_TYPE_P(value) != IS_LONG && SW_Z_TYPE_P(value) != IS_DOUBLE && + strncasecmp(Z_STRVAL_P(value),"inf",sizeof("inf")) != 0 && + strncasecmp(Z_STRVAL_P(value),"-inf",sizeof("-inf")) != 0 && + strncasecmp(Z_STRVAL_P(value),"+inf",sizeof("+inf")) != 0) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Weights must be numeric or '-inf','inf','+inf'" TSRMLS_CC); + for (j = 0; j < i; j++) + { + efree((void* )argv[j]); + } + SW_REDIS_COMMAND_FREE_ARGV + RETURN_FALSE; + } + switch (SW_Z_TYPE_P(value)) { + case IS_LONG: + buf_len = sprintf(buf, "%ld", Z_LVAL_P(value)); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + break; + case IS_DOUBLE: + buf_len = sprintf(buf, "%f", Z_DVAL_P(value)); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + break; + case IS_STRING: + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) + break; + } + SW_HASHTABLE_FOREACH_END(); + } + + // AGGREGATE + if(agg_op_len != 0) { + SW_REDIS_COMMAND_ARGV_FILL("AGGREGATE", 9) + SW_REDIS_COMMAND_ARGV_FILL(agg_op, agg_op_len) + } + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zRangeByLex) +{ + char *key, *min, *max; + zend_size_t key_len, min_len, max_len; + long offset, count; + zend_size_t argc = ZEND_NUM_ARGS(); + + /* We need either 3 or 5 arguments for this to be valid */ + if(argc != 3 && argc != 5) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Must pass either 3 or 5 arguments" TSRMLS_CC); + RETURN_FALSE; + } + + if(zend_parse_parameters(argc TSRMLS_CC, "sss|ll", &key, + &key_len, &min, &min_len, &max, &max_len, + &offset, &count)==FAILURE) + { + RETURN_FALSE; + } + + /* min and max must start with '(' or '[', or be either '-' or '+' */ + if(min_len < 1 || max_len < 1 || + (min[0] != '(' && min[0] != '[' && + (min[0] != '-' || min_len > 1) && (min[0] != '+' || min_len > 1)) || + (max[0] != '(' && max[0] != '[' && + (max[0] != '-' || max_len > 1) && (max[0] != '+' || max_len > 1))) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "min and max arguments must start with '[' or '('" TSRMLS_CC); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + + argc = argc == 3 ? 4 : 7; + int i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZRANGEBYLEX", 11) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(min, min_len) + SW_REDIS_COMMAND_ARGV_FILL(max, max_len) + if (argc == 7) + { + SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%ld", offset); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + buf_len = sprintf(buf, "%ld", count); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zRevRangeByLex) +{ + char *key, *min, *max; + zend_size_t key_len, min_len, max_len; + long offset, count; + int argc = ZEND_NUM_ARGS(); + + /* We need either 3 or 5 arguments for this to be valid */ + if(argc != 3 && argc != 5) { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "Must pass either 3 or 5 arguments" TSRMLS_CC); + RETURN_FALSE; + } + + if(zend_parse_parameters(argc TSRMLS_CC, "sss|ll", &key, + &key_len, &min, &min_len, &max, &max_len, + &offset, &count)==FAILURE) + { + RETURN_FALSE; + } + + /* min and max must start with '(' or '[', or be either '-' or '+' */ + if(min_len < 1 || max_len < 1 || + (min[0] != '(' && min[0] != '[' && + (min[0] != '-' || min_len > 1) && (min[0] != '+' || min_len > 1)) || + (max[0] != '(' && max[0] != '[' && + (max[0] != '-' || max_len > 1) && (max[0] != '+' || max_len > 1))) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "min and max arguments must start with '[' or '('" TSRMLS_CC); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + + argc = argc == 3 ? 4 : 7; + int i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGEBYLEX", 14) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(min, min_len) + SW_REDIS_COMMAND_ARGV_FILL(max, max_len) + if (argc == 7) + { + SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%ld", offset); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + buf_len = sprintf(buf, "%ld", count); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zRangeByScore) +{ + char *key; + zend_size_t key_len; + char *start, *end; + zend_size_t start_len, end_len; + long limit_low, limit_high; + zval *z_opt=NULL, *z_ele; + zend_bool withscores = 0, has_limit = 0; + HashTable *ht_opt; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sss|a", &key, &key_len, &start, &start_len, &end, &end_len, + &z_opt) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int argc = 4, i = 0; + // Check for an options array + if (z_opt && Z_TYPE_P(z_opt) == IS_ARRAY) + { + ht_opt = Z_ARRVAL_P(z_opt); + + // Check for WITHSCORES + if (sw_zend_hash_find(ht_opt, ZEND_STRS("withscores"), (void **) &z_ele) == SUCCESS +#if PHP_MAJOR_VERSION < 7 + && Z_TYPE_P(z_ele) == IS_BOOL && Z_BVAL_P(z_ele) == 1 +#else + && Z_TYPE_P(z_ele) == IS_TRUE +#endif + ) + { + withscores = 1; + argc++; + } + + // LIMIT + if (sw_zend_hash_find(ht_opt, ZEND_STRS("limit"), (void **) &z_ele) == SUCCESS) + { + HashTable *ht_limit = Z_ARRVAL_P(z_ele); +#if PHP_MAJOR_VERSION < 7 + zval **z_off, **z_cnt; + if (zend_hash_index_find(ht_limit,0,(void**)&z_off) == SUCCESS && + zend_hash_index_find(ht_limit,1,(void**)&z_cnt) == SUCCESS && + SW_Z_TYPE_PP(z_off) == IS_LONG && SW_Z_TYPE_PP(z_cnt) == IS_LONG) + { + has_limit = 1; + limit_low = Z_LVAL_PP(z_off); + limit_high = Z_LVAL_PP(z_cnt); + argc += 3; + } +#else + zval *z_off, *z_cnt; + z_off = zend_hash_index_find(ht_limit, 0); + z_cnt = zend_hash_index_find(ht_limit, 1); + if (z_off && z_cnt && SW_Z_TYPE_P(z_off) == IS_LONG && SW_Z_TYPE_P(z_cnt) == IS_LONG) + { + has_limit = 1; + limit_low = Z_LVAL_P(z_off); + limit_high = Z_LVAL_P(z_cnt); + argc += 3; + } +#endif + } + } + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZRANGEBYSCORE", 13) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(start, start_len) + SW_REDIS_COMMAND_ARGV_FILL(end, end_len) + + if (withscores) + { + SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10) + } + if (has_limit) + { + SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%ld", limit_low); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + buf_len = sprintf(buf, "%ld", limit_high); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zRevRangeByScore) +{ + char *key; + zend_size_t key_len; + char *start, *end; + zend_size_t start_len, end_len; + long limit_low, limit_high; + zval *z_opt=NULL, *z_ele; + zend_bool withscores = 0, has_limit = 0; + HashTable *ht_opt; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sss|a", &key, &key_len, &start, &start_len, &end, &end_len, + &z_opt) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int argc = 4, i = 0; + // Check for an options array + if (z_opt && Z_TYPE_P(z_opt) == IS_ARRAY) + { + ht_opt = Z_ARRVAL_P(z_opt); + + // Check for WITHSCORES + if (sw_zend_hash_find(ht_opt, ZEND_STRS("withscores"), (void **) &z_ele) == SUCCESS +#if PHP_MAJOR_VERSION < 7 + && Z_TYPE_P(z_ele) == IS_BOOL && Z_BVAL_P(z_ele) == 1 +#else + && Z_TYPE_P(z_ele) == IS_TRUE +#endif + ) + { + withscores = 1; + argc++; + } + + // LIMIT + if (sw_zend_hash_find(ht_opt, ZEND_STRS("limit"), (void **) &z_ele) == SUCCESS) + { + HashTable *ht_limit = Z_ARRVAL_P(z_ele); +#if PHP_MAJOR_VERSION < 7 + zval **z_off, **z_cnt; + if (zend_hash_index_find(ht_limit,0,(void**)&z_off) == SUCCESS && + zend_hash_index_find(ht_limit,1,(void**)&z_cnt) == SUCCESS && + SW_Z_TYPE_PP(z_off) == IS_LONG && SW_Z_TYPE_PP(z_cnt) == IS_LONG) + { + has_limit = 1; + limit_low = Z_LVAL_PP(z_off); + limit_high = Z_LVAL_PP(z_cnt); + argc += 3; + } +#else + zval *z_off, *z_cnt; + z_off = zend_hash_index_find(ht_limit,0); + z_cnt = zend_hash_index_find(ht_limit, 1); + if (z_off && z_cnt && SW_Z_TYPE_P(z_off) == IS_LONG && SW_Z_TYPE_P(z_cnt) == IS_LONG) + { + has_limit = 1; + limit_low = Z_LVAL_P(z_off); + limit_high = Z_LVAL_P(z_cnt); + argc += 3; + } +#endif + } + } + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZREVRANGEBYSCORE", 16) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(start, start_len) + SW_REDIS_COMMAND_ARGV_FILL(end, end_len) + + if (withscores) + { + SW_REDIS_COMMAND_ARGV_FILL("WITHSCORES", 10) + } + if (has_limit) + { + SW_REDIS_COMMAND_ARGV_FILL("LIMIT", 5) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%ld", limit_low); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + buf_len = sprintf(buf, "%ld", limit_high); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zIncrBy) +{ + char *key; + zend_size_t key_len; + double incrby; + zval *z_val; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sdz", &key, &key_len, &incrby, &z_val) == FAILURE) + { + return; + } + + SW_REDIS_COMMAND_CHECK; + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("ZINCRBY", 7) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char buf[32]; + size_t buf_len; + buf_len = sprintf(buf, "%f", incrby); + SW_REDIS_COMMAND_ARGV_FILL(buf, buf_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val) + SW_REDIS_COMMAND(4) + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zAdd) +{ + int argc = ZEND_NUM_ARGS(); + + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) + { + efree(z_args); + RETURN_FALSE; + } + +#if PHP_MAJOR_VERSION < 7 + if (argc > 0) convert_to_string(z_args[0]); +#else + if (argc > 0) + { + convert_to_string(&z_args[0]); + } +#endif + if (argc < 3 || SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) + { + efree(z_args); + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + + int i = 0, j, k, valid_params; + valid_params = argc - 1; + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("ZADD", 4) + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), (size_t)SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0])) + k = 1; + + if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING && IS_NX_XX_ARG(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]))) + { + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]), (size_t)SW_REDIS_COMMAND_ARGS_STRLEN(z_args[k])) + k++; + valid_params--; + } + + if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING && strncasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]), "CH", 2) == 0) + { + SW_REDIS_COMMAND_ARGV_FILL("CH", 2) + k++; + valid_params--; + } + + if (SW_REDIS_COMMAND_ARGS_TYPE(z_args[k]) == IS_STRING && strncasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[k]), "INCR", 4) == 0) + { + SW_REDIS_COMMAND_ARGV_FILL("INCR", 4) + k++; + valid_params--; + } + + if (valid_params % 2 != 0) + { + for (i = 0; i < 1 + k; i++) + { + efree((void* )argv[i]); + } + SW_REDIS_COMMAND_FREE_ARGV + efree(z_args); + RETURN_FALSE; + } + + char buf[32]; + size_t buf_len; + for (j = k; j < argc-1; j += 2) { + convert_to_double(SW_REDIS_COMMAND_ARGS_REF(z_args[j])); buf_len = snprintf(buf, sizeof(buf), "%f", SW_REDIS_COMMAND_ARGS_DVAL(z_args[j])); + SW_REDIS_COMMAND_ARGV_FILL((char*)buf, buf_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(SW_REDIS_COMMAND_ARGS_REF(z_args[j+1])) + } + efree(z_args); + + SW_REDIS_COMMAND(argc); + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zScore) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZSCORE", 6); +} + +static PHP_METHOD(swoole_redis_coro, zRank) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZRANK", 5); +} + +static PHP_METHOD(swoole_redis_coro, zRevRank) +{ + sw_redis_command_key_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZREVRANK", 8); +} + +static PHP_METHOD(swoole_redis_coro, hGet) +{ + sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HGET", 4); +} + +static PHP_METHOD(swoole_redis_coro, hMGet) +{ + char *key; + zval *z_arr; + zend_size_t argc, key_len; + HashTable *ht_chan; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &key, &key_len, + &z_arr)==FAILURE) + { + return; + } + + ht_chan = Z_ARRVAL_P(z_arr); + + if((argc = zend_hash_num_elements(ht_chan)) == 0) { + RETURN_FALSE; + } + SW_REDIS_COMMAND_CHECK + + zval *value; + int i = 0; + argc = argc + 2; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("HMGET", 5) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_HASHTABLE_FOREACH_START(ht_chan, value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hExists) +{ + sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "HEXISTS", 7); +} + +static PHP_METHOD(swoole_redis_coro, publish) +{ + sw_redis_command_key_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PUBLISH", 7); +} + +static PHP_METHOD(swoole_redis_coro, zDeleteRangeByScore) +{ + sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZREMRANGEBYSCORE", 16); +} + +static PHP_METHOD(swoole_redis_coro, zCount) +{ + sw_redis_command_key_str_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZCOUNT", 6); +} + +static PHP_METHOD(swoole_redis_coro, incrBy) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "INCRBY", 6); +} + +static PHP_METHOD(swoole_redis_coro, hIncrBy) +{ + char *key, *mem; + zend_size_t key_len, mem_len; + long byval; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &key, &key_len, + &mem, &mem_len, &byval)==FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("HINCRBY", 7) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(mem, mem_len) + char str[32]; + sprintf(str, "%ld", byval); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, hIncrByFloat) +{ + char *key, *mem; + zend_size_t key_len, mem_len; + double byval; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssd", &key, &key_len, + &mem, &mem_len, &byval)==FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("HINCRBYFLOAT", 12) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(mem, mem_len) + char str[32]; + sprintf(str, "%f", byval); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, incr) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "INCR", 4); +} + +static PHP_METHOD(swoole_redis_coro, decrBy) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DECRBY", 6); +} + +static PHP_METHOD(swoole_redis_coro, decr) +{ + sw_redis_command_key(INTERNAL_FUNCTION_PARAM_PASSTHRU, "DECR", 4); +} + +static PHP_METHOD(swoole_redis_coro, getBit) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "GETBIT", 6); +} + +static PHP_METHOD(swoole_redis_coro, lInsert) +{ + char *key, *pos; + zend_size_t key_len, pos_len; + zval *z_val, *z_pivot; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sszz", &key, &key_len, + &pos, &pos_len, &z_pivot, &z_val) == FAILURE) + { + return; + } + + if (strncasecmp(pos, "after", 5) && strncasecmp(pos, "before", 6)) { + swoole_php_error(E_WARNING, "Position must be either 'BEFORE' or 'AFTER'"); + RETURN_FALSE; + } + + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[5]; + char *argv[5]; + + SW_REDIS_COMMAND_ARGV_FILL("LINSERT", 7) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + SW_REDIS_COMMAND_ARGV_FILL(pos, pos_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_pivot) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val) + SW_REDIS_COMMAND(5); + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, lGet) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LINDEX", 6); +} + +static PHP_METHOD(swoole_redis_coro, setTimeout) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "EXPIRE", 6); +} + +static PHP_METHOD(swoole_redis_coro, pexpire) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PEXPIRE", 7); +} + +static PHP_METHOD(swoole_redis_coro, expireAt) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "EXPIREAT", 8); +} + +static PHP_METHOD(swoole_redis_coro, pexpireAt) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "PEXPIREAT", 9); +} + +static PHP_METHOD(swoole_redis_coro, move) +{ + sw_redis_command_key_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "MOVE", 4); +} + +static PHP_METHOD(swoole_redis_coro, select) +{ + long db_number; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &db_number) == FAILURE) { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[2]; + char *argv[2]; + + SW_REDIS_COMMAND_ARGV_FILL("SELECT", 6) + char str[32]; + sprintf(str, "%ld", db_number); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND(2); + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, getRange) +{ + sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "GETRANGE", 8); +} + +static PHP_METHOD(swoole_redis_coro, listTrim) +{ + sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LTRIM", 5); +} + +static PHP_METHOD(swoole_redis_coro, lGetRange) +{ + sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "LRANGE", 6); +} + +static PHP_METHOD(swoole_redis_coro, lRem) +{ + char *key; + zend_size_t key_len; + long count = 0; + zval *z_val; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &key, &key_len, + &z_val, &count) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("LREM", 4) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%d", (int)count); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, zDeleteRangeByRank) +{ + sw_redis_command_key_long_long(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZREMRANGEBYRANK", 15); +} + +static PHP_METHOD(swoole_redis_coro, incrByFloat) +{ + sw_redis_command_key_dbl(INTERNAL_FUNCTION_PARAM_PASSTHRU, "INCRBYFLOAT", 11); +} + +static PHP_METHOD(swoole_redis_coro, bitCount) +{ + char *key; + zend_size_t key_len; + long start = 0, end = -1; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &key, &key_len, + &start, &end)==FAILURE) + { + return; + } + + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("BITCOUNT", 8) + SW_REDIS_COMMAND_ARGV_FILL(key, key_len) + char str[32]; + sprintf(str, "%d", (int)start); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + sprintf(str, "%d", (int)end); + SW_REDIS_COMMAND_ARGV_FILL(str, strlen(str)) + + SW_REDIS_COMMAND(4) + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, bitOp) +{ + int argc = ZEND_NUM_ARGS(); + + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if(zend_get_parameters_array(ht, argc, z_args) == FAILURE || + argc < 3 || SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) + { + efree(z_args); + return; + } + + SW_REDIS_COMMAND_CHECK_WITH_FREE_Z_ARGS + + int j, i = 0; + argc++; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("BITOP", 5) + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0])) + for(j = 1; j < argc - 1; j++) { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *convert_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + } + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + efree(z_args); + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, sMove) +{ + char *src, *dst; + zend_size_t src_len, dst_len; + zval *z_val; + + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz", &src, &src_len, + &dst, &dst_len, &z_val) == FAILURE) + { + return; + } + SW_REDIS_COMMAND_CHECK + + int i = 0; + size_t argvlen[4]; + char *argv[4]; + SW_REDIS_COMMAND_ARGV_FILL("SMOVE", 5) + SW_REDIS_COMMAND_ARGV_FILL(src, src_len) + SW_REDIS_COMMAND_ARGV_FILL(dst, dst_len) + SW_REDIS_COMMAND_ARGV_FILL_WITH_SERIALIZE(z_val) + SW_REDIS_COMMAND(4) + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, sAdd) +{ + sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SADD", 4); +} + +static PHP_METHOD(swoole_redis_coro, sRemove) +{ + sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "SREM", 4); +} + +static PHP_METHOD(swoole_redis_coro, zDelete) +{ + sw_redis_command_key_var_val(INTERNAL_FUNCTION_PARAM_PASSTHRU, "ZREM", 4); +} + +static PHP_METHOD(swoole_redis_coro, pSubscribe) +{ + zval *z_arr; + if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &z_arr) == FAILURE) + { + return; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (redis->defer) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "psubscribe cannot be used with defer enabled" TSRMLS_CC); + RETURN_FALSE; + } + + if (unlikely(redis->cid && redis->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "redis client has already been bound to another coroutine."); + RETURN_FALSE; + } + + php_context *context = swoole_get_property(getThis(), 0); + switch (redis->state) + { + case SWOOLE_REDIS_CORO_STATE_SUBSCRIBE: + coro_save(context); + redis->iowait = SW_REDIS_CORO_STATUS_WAIT; + coro_yield(); + break; + case SWOOLE_REDIS_CORO_STATE_CONNECT: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis client is not connected." TSRMLS_CC); + RETURN_FALSE; + break; + case SWOOLE_REDIS_CORO_STATE_CLOSED: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis client connection is closed." TSRMLS_CC); + RETURN_FALSE; + break; + case SWOOLE_REDIS_CORO_STATE_MULTI: + case SWOOLE_REDIS_CORO_STATE_PIPELINE: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis state mode is multi or pipeline, cann't use subscribe cmd." TSRMLS_CC); + RETURN_FALSE; + break; + default: + break; + } + + HashTable *ht_chan = Z_ARRVAL_P(z_arr); + int argc = 1 + zend_hash_num_elements(ht_chan), i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("PSUBSCRIBE", 10) + + zval *value; + SW_HASHTABLE_FOREACH_START(ht_chan, value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + + redis->state = SWOOLE_REDIS_CORO_STATE_SUBSCRIBE; + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, subscribe) +{ + zval *z_arr; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "a", &z_arr) == FAILURE) + { + return; + } + + swRedisClient *redis = swoole_get_object(getThis()); + if (redis->defer) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "subscribe cannot be used with defer enabled" TSRMLS_CC); + RETURN_FALSE; + } + + if (unlikely(redis->cid && redis->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "redis client has already been bound to another coroutine."); + RETURN_FALSE; + } + + php_context *context = swoole_get_property(getThis(), 0); + switch (redis->state) + { + case SWOOLE_REDIS_CORO_STATE_SUBSCRIBE: + coro_save(context); + redis->iowait = SW_REDIS_CORO_STATUS_WAIT; + coro_yield(); + break; + case SWOOLE_REDIS_CORO_STATE_CONNECT: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis client is not connected." TSRMLS_CC); + RETURN_FALSE; + break; + case SWOOLE_REDIS_CORO_STATE_CLOSED: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis client connection is closed." TSRMLS_CC); + RETURN_FALSE; + break; + case SWOOLE_REDIS_CORO_STATE_MULTI: + case SWOOLE_REDIS_CORO_STATE_PIPELINE: + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis state mode is multi or pipeline, cann't use subscribe cmd." TSRMLS_CC); + RETURN_FALSE; + break; + default: + break; + } + + HashTable *ht_chan = Z_ARRVAL_P(z_arr); + int argc = 1 + zend_hash_num_elements(ht_chan), i = 0; + SW_REDIS_COMMAND_ALLOC_ARGV + SW_REDIS_COMMAND_ARGV_FILL("SUBSCRIBE", 9) + + zval *value; + SW_HASHTABLE_FOREACH_START(ht_chan, value) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(value); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(value), Z_STRLEN_P(value)) +#else + zend_string *convert_str = zval_get_string(value); + SW_REDIS_COMMAND_ARGV_FILL(convert_str->val, convert_str->len) + zend_string_release(convert_str); +#endif + SW_HASHTABLE_FOREACH_END(); + + SW_REDIS_COMMAND(argc) + SW_REDIS_COMMAND_FREE_ARGV + + redis->state = SWOOLE_REDIS_CORO_STATE_SUBSCRIBE; + + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, multi) +{ + long mode = SW_REDIS_MODE_MULTI; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) + { + return; + } + + SW_REDIS_COMMAND_CHECK + + if (mode == SW_REDIS_MODE_MULTI) + { + redis->state = SWOOLE_REDIS_CORO_STATE_MULTI; + size_t argvlen[1]; + char *argv[1]; + argvlen[0] = 5; + argv[0] = estrndup("MULTI", 5); + if (redisAsyncCommandArgv(redis->context, swoole_redis_coro_onResult, NULL, 1, (const char **) argv, (const size_t *) argvlen) < 0) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redisAsyncCommandArgv() failed." TSRMLS_CC); + RETURN_FALSE; + } + efree(argv[0]); + + redis->queued_cmd_count = 2; + } + else + { + redis->state = SWOOLE_REDIS_CORO_STATE_PIPELINE; + redis->queued_cmd_count = 0; + } + + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(swoole_redis_coro, exec) +{ + coro_check(TSRMLS_C); + swRedisClient *redis = swoole_get_object(getThis()); + if (!redis) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_CLOSED TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "connection is not available." TSRMLS_CC); + RETURN_FALSE; + } + if (redis->state != SWOOLE_REDIS_CORO_STATE_MULTI && redis->state != SWOOLE_REDIS_CORO_STATE_PIPELINE) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redis state mode is neither multi nor pipeline!" TSRMLS_CC); + RETURN_FALSE; + } + if (unlikely(redis->cid && redis->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "redis client has already been bound to another coroutine."); + RETURN_FALSE; + } + if (redis->state == SWOOLE_REDIS_CORO_STATE_MULTI) + { + size_t argvlen[1]; + char *argv[1]; + argvlen[0] = 4; + argv[0] = estrndup("EXEC", 4); + if (redisAsyncCommandArgv(redis->context, swoole_redis_coro_onResult, NULL, 1, (const char **) argv, (const size_t *) argvlen) < 0) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), SW_REDIS_ERR_OTHER TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, getThis(), ZEND_STRL("errMsg"), "redisAsyncCommandArgv() failed." TSRMLS_CC); + RETURN_FALSE; + } + efree(argv[0]); + } + redis->iowait = SW_REDIS_CORO_STATUS_WAIT; + if (redis->defer) + { + RETURN_TRUE; + } + redis->cid = sw_get_current_cid(); + php_context *context = swoole_get_property(getThis(), 0); + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_redis_coro, request) +{ + SW_REDIS_COMMAND_CHECK + + zval *params = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &params) == FAILURE) + { + return; + } + + int argc = zend_hash_num_elements(Z_ARRVAL_P(params)); + size_t stack_argvlen[SW_REDIS_COMMAND_BUFFER_SIZE]; + char *stack_argv[SW_REDIS_COMMAND_BUFFER_SIZE]; + + size_t *argvlen; + char **argv; + zend_bool free_mm = 0; + int i = 0; + + if (argc > SW_REDIS_COMMAND_BUFFER_SIZE) + { + argvlen = emalloc(sizeof(size_t) * argc); + argv = emalloc(sizeof(char*) * argc); + free_mm = 1; + } + else + { + argvlen = stack_argvlen; + argv = stack_argv; + } + + zval *value; + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(params), value) + if (i == argc) + { + break; + } + + zend_string *convert_str = zval_get_string(value); + argvlen[i] = convert_str->len; + argv[i] = estrndup(convert_str->val, convert_str->len); + zend_string_release(convert_str); + i++; + SW_HASHTABLE_FOREACH_END(); + + SW_REDIS_COMMAND(argc) + + if (free_mm) + { + efree(argvlen); + efree(argv); + } + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, eval) +{ + char *script; + zend_size_t script_len; + zval *params = NULL; + long keys_num = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|al", &script, &script_len, &params, &keys_num) == FAILURE) + { + return; + } + + HashTable *params_ht = NULL; + uint32_t params_num = 0; + if (params) { + params_ht = Z_ARRVAL_P(params); + params_num = zend_hash_num_elements(params_ht); + } + + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t *argvlen = emalloc(sizeof(size_t) * (params_num + 3)); + char **argv = emalloc(sizeof(char *) * (params_num + 3)); + + SW_REDIS_COMMAND_ARGV_FILL("EVAL", 4) + SW_REDIS_COMMAND_ARGV_FILL(script, script_len) + + char keys_num_str[32] = {0}; + sprintf(keys_num_str, "%ld", keys_num); + SW_REDIS_COMMAND_ARGV_FILL(keys_num_str, strlen(keys_num_str)); + + if (params_ht) { + zval *param; + SW_HASHTABLE_FOREACH_START(params_ht, param) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(param); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(param), Z_STRLEN_P(param)) +#else + zend_string *param_str = zval_get_string(param); + SW_REDIS_COMMAND_ARGV_FILL(param_str->val, param_str->len) + zend_string_release(param_str); +#endif + SW_HASHTABLE_FOREACH_END(); + } + + SW_REDIS_COMMAND(params_num + 3) + efree(argvlen); + efree(argv); + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, evalSha) +{ + char *sha; + zend_size_t sha_len; + zval *params = NULL; + long keys_num = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|al", &sha, &sha_len, &params, &keys_num) == FAILURE) + { + return; + } + + HashTable *params_ht = NULL; + uint32_t params_num = 0; + if (params) { + params_ht = Z_ARRVAL_P(params); + params_num = zend_hash_num_elements(params_ht); + } + + SW_REDIS_COMMAND_CHECK + int i = 0; + size_t *argvlen = emalloc(sizeof(size_t) * (params_num + 3)); + char **argv = emalloc(sizeof(char *) * (params_num + 3)); + + SW_REDIS_COMMAND_ARGV_FILL("EVALSHA", 7) + SW_REDIS_COMMAND_ARGV_FILL(sha, sha_len) + + char keys_num_str[32] = {0}; + sprintf(keys_num_str, "%ld", keys_num); + SW_REDIS_COMMAND_ARGV_FILL(keys_num_str, strlen(keys_num_str)); + + if (params) { + zval *param; + SW_HASHTABLE_FOREACH_START(params_ht, param) +#if PHP_MAJOR_VERSION < 7 + convert_to_string(param); + SW_REDIS_COMMAND_ARGV_FILL(Z_STRVAL_P(param), Z_STRLEN_P(param)) +#else + zend_string *param_str = zval_get_string(param); + SW_REDIS_COMMAND_ARGV_FILL(param_str->val, param_str->len) + zend_string_release(param_str); +#endif + SW_HASHTABLE_FOREACH_END(); + } + + SW_REDIS_COMMAND(params_num + 3) + efree(argvlen); + efree(argv); + SW_REDIS_COMMAND_YIELD +} + +static PHP_METHOD(swoole_redis_coro, script) +{ + int argc = ZEND_NUM_ARGS(); + if (argc < 1) { + RETURN_FALSE; + } + + SW_REDIS_COMMAND_ALLOC_ARGS_ARR + if (zend_get_parameters_array(ht, argc, z_args) == FAILURE || SW_REDIS_COMMAND_ARGS_TYPE(z_args[0]) != IS_STRING) { + efree(z_args); + RETURN_FALSE; + } + + SW_REDIS_COMMAND_CHECK + int i = 0; + if (! strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "flush") || ! strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "kill")) { + size_t argvlen[2]; + char *argv[2]; + SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6) + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[0])) + SW_REDIS_COMMAND(2) + efree(z_args); + SW_REDIS_COMMAND_YIELD + } else if (! strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "exists")) { + if (argc < 2) { + efree(z_args); + RETURN_FALSE; + } else { + size_t *argvlen = emalloc(sizeof(size_t) * (argc + 1)); + char **argv = emalloc(sizeof(char *) * (argc + 1)); + SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6) + SW_REDIS_COMMAND_ARGV_FILL("EXISTS", 6) + int j = 1; + for (; j < argc; j++) { +#if PHP_MAJOR_VERSION < 7 + convert_to_string(z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[j]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[j])) +#else + zend_string *z_arg_str = zval_get_string(&z_args[j]); + SW_REDIS_COMMAND_ARGV_FILL(z_arg_str->val, z_arg_str->len) + zend_string_release(z_arg_str); +#endif + } + + SW_REDIS_COMMAND(argc + 1) + efree(argvlen); + efree(argv); + efree(z_args); + SW_REDIS_COMMAND_YIELD + } + } else if (! strcasecmp(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[0]), "load")) { + if (argc < 2 || SW_REDIS_COMMAND_ARGS_TYPE(z_args[1]) != IS_STRING) { + efree(z_args); + RETURN_FALSE; + } else { + size_t argvlen[3]; + char *argv[3]; + SW_REDIS_COMMAND_ARGV_FILL("SCRIPT", 6) + SW_REDIS_COMMAND_ARGV_FILL("LOAD", 4) + SW_REDIS_COMMAND_ARGV_FILL(SW_REDIS_COMMAND_ARGS_STRVAL(z_args[1]), SW_REDIS_COMMAND_ARGS_STRLEN(z_args[1])) + SW_REDIS_COMMAND(3) + efree(z_args); + SW_REDIS_COMMAND_YIELD + } + } else { + efree(z_args); + RETURN_FALSE; + } +} + +static void swoole_redis_coro_parse_result(swRedisClient *redis, zval* return_value, redisReply* reply TSRMLS_DC) +{ + zval *val; + int j; + +#if PHP_MAJOR_VERSION >= 7 + zval _val; + val = &_val; + bzero(val, sizeof(zval)); +#endif + + switch (reply->type) + { + case REDIS_REPLY_INTEGER: + ZVAL_LONG(return_value, reply->integer); + break; + + case REDIS_REPLY_ERROR: + ZVAL_FALSE(return_value); + if (redis->context->err == 0) + { + if (strncmp(reply->str, "NOAUTH", 6) == 0) + { + redis->context->err = SW_REDIS_ERR_NOAUTH; + } + else + { + redis->context->err = SW_REDIS_ERR_OTHER; + } + redis->context->errstr = reply->str; + } + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), redis->context->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), redis->context->errstr TSRMLS_CC); + break; + + case REDIS_REPLY_STATUS: + if (redis->context->err == 0) + { + if (reply->len > 0) + { + if (strncmp(reply->str, "OK", 2) == 0) + { + ZVAL_BOOL(return_value, 1); + break; + } + long l; + if (strncmp(reply->str, "string", 6) == 0) { + l = SW_REDIS_STRING; + } else if (strncmp(reply->str, "set", 3) == 0){ + l = SW_REDIS_SET; + } else if (strncmp(reply->str, "list", 4) == 0){ + l = SW_REDIS_LIST; + } else if (strncmp(reply->str, "zset", 4) == 0){ + l = SW_REDIS_ZSET; + } else if (strncmp(reply->str, "hash", 4) == 0){ + l = SW_REDIS_HASH; + } else { + l = SW_REDIS_NOT_FOUND; + } + ZVAL_LONG(return_value, l); + } + else + { + ZVAL_TRUE(return_value); + } + } + else + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), redis->context->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), redis->context->errstr TSRMLS_CC); + } + break; + + case REDIS_REPLY_STRING: + if (redis->serialize) + { + char *reserve_str = reply->str; + php_unserialize_data_t s_ht; + PHP_VAR_UNSERIALIZE_INIT(s_ht); +#if PHP_MAJOR_VERSION < 7 + if(!php_var_unserialize(&return_value, +#else + if(!php_var_unserialize(return_value, +#endif + (const unsigned char**)&reply->str, + (const unsigned char*)reply->str + reply->len, &s_ht TSRMLS_CC)) { + SW_ZVAL_STRINGL(return_value, reply->str, reply->len, 1); + } + PHP_VAR_UNSERIALIZE_DESTROY(s_ht); + reply->str = reserve_str; + } + else + { + SW_ZVAL_STRINGL(return_value, reply->str, reply->len, 1); + } + break; + + case REDIS_REPLY_ARRAY: + array_init(return_value); + for (j = 0; j < reply->elements; j++) + { +#if PHP_MAJOR_VERSION < 7 + SW_ALLOC_INIT_ZVAL(val); +#endif + swoole_redis_coro_parse_result(redis, val, reply->element[j] TSRMLS_CC); + add_next_index_zval(return_value, val); + } + break; + + case REDIS_REPLY_NIL: + default: + ZVAL_NULL(return_value); + return; + } +} + +static void swoole_redis_coro_resume(void *data) +{ + swRedis_result *result = (swRedis_result *) data; + swRedisClient *redis = result->redis; + zval *retval = NULL; + zval *redis_result = NULL; + + if (redis->object == NULL) + { + goto free_result; + } + + swTraceLog(SW_TRACE_REDIS_CLIENT, "resume, fd=%d, object_id=%d", redis->context->c.fd, sw_get_object_handle(redis->object)); + + redis->cid = 0; + redis->iowait = SW_REDIS_CORO_STATUS_READY; + + php_context *sw_current_context = swoole_get_property(redis->object, 0); + + redis_result = result->value; + + int ret = coro_resume(sw_current_context, redis_result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + free_result: if (redis_result) + { + sw_zval_ptr_dtor(&redis_result); + } + efree(result); +} + +static void swoole_redis_coro_onResult(redisAsyncContext *c, void *r, void *privdata) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, c->c.fd); + if (_socket->active == 0) + { + return; + } + + swRedisClient *redis = c->ev.data; + swRedis_result *result = emalloc(sizeof(swRedis_result)); + redisReply *reply = r; + +#if PHP_MAJOR_VERSION < 7 + zval **type; + SW_MAKE_STD_ZVAL(result->value); +#else + zval *type; + result->value = &result->_value; + bzero(result->value, sizeof(result->_value)); +#endif + + swTraceLog(SW_TRACE_REDIS_CLIENT, "get response, fd=%d, object_id=%d", redis->context->c.fd, sw_get_object_handle(redis->object)); + + result->redis = redis; + if (reply == NULL) + { + if (redis->state == SWOOLE_REDIS_CORO_STATE_CLOSING) + { + error: + sw_zval_ptr_dtor(&result->value); + efree(result); + return; + } + ZVAL_FALSE(result->value); + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); + if (redis->pipeline_result != NULL) + { + sw_zval_free(redis->pipeline_result); + redis->pipeline_result = NULL; + } + swoole_redis_coro_resume(result); + return; + } + else + { + swoole_redis_coro_parse_result(redis, result->value, reply TSRMLS_CC); + + switch (redis->state) + { + case SWOOLE_REDIS_CORO_STATE_PIPELINE: + if (redis->pipeline_result == NULL) + { + SW_ALLOC_INIT_ZVAL(redis->pipeline_result); + array_init(redis->pipeline_result); + } + redis->queued_cmd_count--; + add_next_index_zval(redis->pipeline_result, result->value); + if (redis->queued_cmd_count > 0) + { + efree(result); + return; + } + *result->value = *redis->pipeline_result; + efree(redis->pipeline_result); + redis->pipeline_result = NULL; + redis->state = SWOOLE_REDIS_CORO_STATE_READY; + break; + case SWOOLE_REDIS_CORO_STATE_MULTI: + redis->queued_cmd_count--; + if (redis->queued_cmd_count > 0) + { + goto error; + } + redis->state = SWOOLE_REDIS_CORO_STATE_READY; + break; + case SWOOLE_REDIS_CORO_STATE_SUBSCRIBE: +#if PHP_MAJOR_VERSION < 7 + if (zend_hash_index_find(Z_ARRVAL_P(result->value), 0, (void **)&type) == FAILURE) +#else + type = zend_hash_index_find(Z_ARRVAL_P(result->value), 0); + if (!type) +#endif + { + goto error; + } +#if PHP_MAJOR_VERSION < 7 + if (strncasecmp(Z_STRVAL_PP(type), "subscribe", 9) == 0 || strncasecmp(Z_STRVAL_PP(type), "psubscribe", 10) == 0) +#else + if (strncasecmp(Z_STRVAL_P(type), "subscribe", 9) == 0 || strncasecmp(Z_STRVAL_P(type), "psubscribe", 10) == 0) +#endif + { + goto error; + } + redis->state = SWOOLE_REDIS_CORO_STATE_READY; + break; + default: + if (redis->defer && !redis->defer_yield) + { + redis->iowait = SW_REDIS_CORO_STATUS_DONE; + redis->defer_result = sw_zval_dup(result->value); + efree(result); + return; + } + else + { + redis->state = SWOOLE_REDIS_CORO_STATE_READY; + break; + } + } + } + + if (redis->state == SWOOLE_REDIS_CORO_STATE_READY) + { + /* et reactor defer callback */ + redis->iowait = SW_REDIS_CORO_STATUS_DONE; + redis->defer_yield = 0; + swoole_redis_coro_resume(result); + } +} + +void swoole_redis_coro_onConnect(const redisAsyncContext *c, int status) +{ + swRedisClient *redis = c->ev.data; + swRedis_result *result; + + if (redis->timer) + { + swTimer_del(&SwooleG.timer, redis->timer); + redis->timer = NULL; + } + + if (status != REDIS_OK) + { + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); + zend_update_property_bool(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("connected"), 0 TSRMLS_CC); + + zval *retval = NULL; + zval *redis_result = NULL; + SW_MAKE_STD_ZVAL(redis_result); + ZVAL_BOOL(redis_result, 0); + + php_context *sw_current_context = swoole_get_property(redis->object, 0); + + swoole_set_object(redis->object, NULL); + SwooleG.main_reactor->defer(SwooleG.main_reactor, redis_coro_free, redis); + + int ret = coro_resume(sw_current_context, redis_result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + } + else + { + result = emalloc(sizeof(swRedis_result)); + result->value = &result->_value; + bzero(result->value, sizeof(result->_value)); + result->redis = redis; + + ZVAL_BOOL(result->value, 1); + redis->state = SWOOLE_REDIS_CORO_STATE_READY; + redis->iowait = SW_REDIS_CORO_STATUS_READY; + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, c->c.fd); + _socket->active = 1; + + zend_update_property_bool(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("connected"), 1 TSRMLS_CC); + + redis->connecting = 1; + redis->connected = 1; + swoole_redis_coro_resume(result); + redis->connecting = 0; + } +} + +static void swoole_redis_coro_onClose(const redisAsyncContext *c, int status) +{ + swRedisClient *redis = c->ev.data; + redis->state = SWOOLE_REDIS_CORO_STATE_CLOSED; + redis->connected = 0; + + if (redis->object) + { + swTraceLog(SW_TRACE_REDIS_CLIENT, "fd=%d, object_id=%d", redis->context->c.fd, sw_get_object_handle(redis->object)); + + redis->context = NULL; + redis->iowait = SW_REDIS_CORO_STATUS_CLOSED; + zend_update_property_bool(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("connected"), 0 TSRMLS_CC); + + if (redis->iowait == SW_REDIS_CORO_STATUS_WAIT) + { + php_context *context = swoole_get_property(redis->object, 0); + zval *retval = NULL; + zval *redis_result; + SW_MAKE_STD_ZVAL(redis_result); + ZVAL_FALSE(redis_result); + + int ret = coro_resume(context, redis_result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&redis_result); + } + } + + if (redis->released) + { + efree(redis); + } +} + +static void swoole_redis_coro_event_AddRead(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_add_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_READ); + } +} + +static void swoole_redis_coro_event_DelRead(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_del_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_READ); + } +} + +static void swoole_redis_coro_event_AddWrite(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_add_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_WRITE); + } +} + +static void swoole_redis_coro_event_DelWrite(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + if (redis->context && SwooleG.main_reactor) + { + swReactor_del_event(SwooleG.main_reactor, redis->context->c.fd, SW_EVENT_WRITE); + } +} + +static void swoole_redis_coro_event_Cleanup(void *privdata) +{ + swRedisClient *redis = (swRedisClient*) privdata; + redis->state = SWOOLE_REDIS_CORO_STATE_CLOSED; + if (redis->context && SwooleG.main_reactor) + { + SwooleG.main_reactor->del(SwooleG.main_reactor, redis->context->c.fd); + } +} + +static int swoole_redis_coro_onError(swReactor *reactor, swEvent *event) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + swRedisClient *redis = event->socket->object; + redisAsyncContext *c = redis->context; + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), c->err TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), c->errstr TSRMLS_CC); + zend_update_property_bool(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("connected"), 0 TSRMLS_CC); + zval *retval = NULL; + sw_zend_call_method_with_0_params(&redis->object, swoole_redis_coro_class_entry_ptr, NULL, "close", &retval); + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + + return SW_OK; +} + +static void swoole_redis_coro_onTimeout(swTimer *timer, swTimer_node *tnode) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + zval *result; + zval *retval = NULL; + php_context *ctx = tnode->data; + + SW_ALLOC_INIT_ZVAL(result); + ZVAL_BOOL(result, 0); + +#if PHP_MAJOR_VERSION < 7 + zval *zobject = (zval *)ctx->coro_params; +#else + zval _zobject = ctx->coro_params; + zval *zobject = &_zobject; +#endif + + swRedisClient *redis = swoole_get_object(zobject); + zend_update_property_long(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + zend_update_property_string(swoole_redis_coro_class_entry_ptr, redis->object, ZEND_STRL("errMsg"), strerror(ETIMEDOUT) TSRMLS_CC); + redisAsyncDisconnect(redis->context); + + int ret = coro_resume(ctx, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_free(result); +} + +static int swoole_redis_coro_onRead(swReactor *reactor, swEvent *event) +{ + swRedisClient *redis = event->socket->object; + swTraceLog(SW_TRACE_REDIS_CLIENT, "read event, fd=%d", redis->context->c.fd); + redisAsyncHandleRead(redis->context); + return SW_OK; +} + +static int swoole_redis_coro_onWrite(swReactor *reactor, swEvent *event) +{ + swRedisClient *redis = event->socket->object; + swTraceLog(SW_TRACE_REDIS_CLIENT, "write event, fd=%d", redis->context->c.fd); + redisAsyncHandleWrite(redis->context); + return SW_OK; +} + +#endif +#endif diff --git a/vendor/swoole/swoole_redis_server.c b/vendor/swoole/swoole_redis_server.c new file mode 100755 index 0000000..269037a --- /dev/null +++ b/vendor/swoole/swoole_redis_server.c @@ -0,0 +1,545 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "redis.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif +#include "ext/standard/php_string.h" + +static zend_class_entry swoole_redis_server_ce; +static zend_class_entry *swoole_redis_server_class_entry_ptr; + +static swString *format_buffer; +#ifdef SW_COROUTINE +static struct +{ + zend_fcall_info_cache **array; + uint32_t size; + uint32_t count; +} func_cache_array = {NULL, 0, 0}; +#endif + +static PHP_METHOD(swoole_redis_server, start); +static PHP_METHOD(swoole_redis_server, setHandler); +static PHP_METHOD(swoole_redis_server, format); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_server_start, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_server_setHandler, 0, 0, 2) + ZEND_ARG_INFO(0, command) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(0, number_of_string_param) + ZEND_ARG_INFO(0, type_of_array_param) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_redis_server_format, 0, 0, 1) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +const zend_function_entry swoole_redis_server_methods[] = +{ + PHP_ME(swoole_redis_server, start, arginfo_swoole_redis_server_start, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_server, setHandler, arginfo_swoole_redis_server_setHandler, ZEND_ACC_PUBLIC) + PHP_ME(swoole_redis_server, format, arginfo_swoole_redis_server_format, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +void swoole_redis_server_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_redis_server_ce, "swoole_redis_server", "Swoole\\Redis\\Server", swoole_redis_server_methods); + swoole_redis_server_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_redis_server_ce, swoole_server_class_entry_ptr, "swoole_server" TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_redis_server, "Swoole\\Redis\\Server"); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Redis\\Server", swoole_redis_server_class_entry_ptr); + } + + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("NIL")-1, SW_REDIS_REPLY_NIL TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("ERROR")-1, SW_REDIS_REPLY_ERROR TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("STATUS")-1, SW_REDIS_REPLY_STATUS TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("INT")-1, SW_REDIS_REPLY_INT TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("STRING")-1, SW_REDIS_REPLY_STRING TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("SET")-1, SW_REDIS_REPLY_SET TSRMLS_CC); + zend_declare_class_constant_long(swoole_redis_server_class_entry_ptr, SW_STRL("MAP")-1, SW_REDIS_REPLY_MAP TSRMLS_CC); +} + +static int redis_onReceive(swServer *serv, swEventData *req) +{ + if (swEventData_is_dgram(req->info.type)) + { + return php_swoole_onReceive(serv, req); + } + + int fd = req->info.fd; + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (!conn) + { + swWarn("connection[%d] is closed.", fd); + return SW_ERR; + } + + swListenPort *port = serv->connection_list[req->info.from_fd].object; + //other server port + if (!port->open_redis_protocol) + { + return php_swoole_onReceive(serv, req); + } + + SWOOLE_GET_TSRMLS; + + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + php_swoole_get_recv_data(zdata, req, NULL, 0); + char *p = Z_STRVAL_P(zdata); + char *pe = p + Z_STRLEN_P(zdata); + int ret; + int length = 0; + + zval *zparams; + SW_MAKE_STD_ZVAL(zparams); + array_init(zparams); + + zval *retval = NULL; + + int state = SW_REDIS_RECEIVE_TOTAL_LINE; + int add_param = 0; + char *command = NULL; + int command_len = 0; + + do + { + switch (state) + { + case SW_REDIS_RECEIVE_TOTAL_LINE: + if (*p == '*' && (p = swRedis_get_number(p, &ret))) + { + state = SW_REDIS_RECEIVE_LENGTH; + break; + } + /* no break */ + + case SW_REDIS_RECEIVE_LENGTH: + if (*p == '$' && (p = swRedis_get_number(p, &ret))) + { + if (ret == -1) + { + add_next_index_null(zparams); + break; + } + length = ret; + state = SW_REDIS_RECEIVE_STRING; + break; + } + //integer + else if (*p == ':' && (p = swRedis_get_number(p, &ret))) + { + add_next_index_long(zparams, ret); + break; + } + /* no break */ + + case SW_REDIS_RECEIVE_STRING: + if (add_param == 0) + { + command = p; + command_len = length; + add_param = 1; + } + else + { + sw_add_next_index_stringl(zparams, p, length, 1); + } + p += length + SW_CRLF_LEN; + state = SW_REDIS_RECEIVE_LENGTH; + break; + + default: + break; + } + } while(p < pe); + + if (command_len >= SW_REDIS_MAX_COMMAND_SIZE) + { + swoole_php_error(E_WARNING, "command is too long."); + serv->close(serv, fd, 0); + return SW_OK; + } + + char _command[SW_REDIS_MAX_COMMAND_SIZE]; + command[command_len] = 0; + int _command_len = snprintf(_command, sizeof(_command), "_handler_%*s", command_len, command); + php_strtolower(_command, _command_len); + + zval *zobject = serv->ptr2; + char err_msg[256]; + + zval *zfd; + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, fd); + + if (SwooleG.enable_coroutine) + { + zval *index = sw_zend_read_property(swoole_redis_server_class_entry_ptr, zobject, _command, _command_len, 1 TSRMLS_CC); + if (!index || ZVAL_IS_NULL(index)) + { + length = snprintf(err_msg, sizeof(err_msg), "-ERR unknown command '%*s'\r\n", command_len, command); + swServer_tcp_send(serv, fd, err_msg, length); + return SW_OK; + } + zval *args[2]; + args[0] = zfd; + args[1] = zparams; + + zend_fcall_info_cache *cache = func_cache_array.array[Z_LVAL_P(index)]; + if (coro_create(cache, args, 2, &retval, NULL, NULL) < 0) + { + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zdata); + sw_zval_ptr_dtor(&zparams); + return SW_OK; + } + } + else + { + zval **args[2]; + zval *zcallback = sw_zend_read_property(swoole_redis_server_class_entry_ptr, zobject, _command, _command_len, 1 TSRMLS_CC); + if (!zcallback || ZVAL_IS_NULL(zcallback)) + { + length = snprintf(err_msg, sizeof(err_msg), "-ERR unknown command '%*s'\r\n", command_len, command); + swServer_tcp_send(serv, fd, err_msg, length); + return SW_OK; + } + args[0] = &zfd; + args[1] = &zparams; + + if (sw_call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "command handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + //free the callback return value + if (retval != NULL) + { + if (Z_TYPE_P(retval) == IS_STRING) + { + serv->send(serv, fd, Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + } + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zdata); + sw_zval_ptr_dtor(&zparams); + return SW_OK; +} + +static PHP_METHOD(swoole_redis_server, start) +{ + int ret; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_error(E_WARNING, "Server is running. Unable to execute swoole_server::start."); + RETURN_FALSE; + } + + php_swoole_register_callback(serv); + + serv->onReceive = redis_onReceive; + + format_buffer = swString_new(SW_BUFFER_SIZE_STD); + if (!format_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_BUFFER_SIZE_STD); + RETURN_FALSE; + } + + zval *zsetting = sw_zend_read_property(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zsetting == NULL || ZVAL_IS_NULL(zsetting)) + { + SW_ALLOC_INIT_ZVAL(zsetting); + array_init(zsetting); + zend_update_property(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("setting"), zsetting TSRMLS_CC); + } + +#ifdef HT_ALLOW_COW_VIOLATION + HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(zsetting)); +#endif + + add_assoc_bool(zsetting, "open_http_protocol", 0); + add_assoc_bool(zsetting, "open_mqtt_protocol", 0); + add_assoc_bool(zsetting, "open_eof_check", 0); + add_assoc_bool(zsetting, "open_length_check", 0); + add_assoc_bool(zsetting, "open_redis_protocol", 0); + + serv->listen_list->open_http_protocol = 0; + serv->listen_list->open_mqtt_protocol = 0; + serv->listen_list->open_eof_check = 0; + serv->listen_list->open_length_check = 0; + serv->listen_list->open_redis_protocol = 1; + + php_swoole_server_before_start(serv, getThis() TSRMLS_CC); + + ret = swServer_start(serv); + if (ret < 0) + { + swoole_php_fatal_error(E_ERROR, "server failed to start. Error: %s", sw_error); + RETURN_LONG(ret); + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis_server, setHandler) +{ + char *command; + zend_size_t command_len; + zval *zcallback; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &command, &command_len, &zcallback) == FAILURE) + { + return; + } + + if (command_len <= 0 || command_len >= SW_REDIS_MAX_COMMAND_SIZE) + { + swoole_php_fatal_error(E_ERROR, "invalid command."); + RETURN_FALSE; + } + +#ifdef PHP_SWOOLE_CHECK_CALLBACK + char *func_name = NULL; +#ifdef SW_COROUTINE + if (func_cache_array.array == NULL) + { + func_cache_array.array = ecalloc(32, sizeof(zend_fcall_info_cache *)); + func_cache_array.size = 32; + func_cache_array.count = 0; + } + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(zcallback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) +#else + if (!sw_zend_is_callable(zcallback, 0, &func_name TSRMLS_CC)) +#endif + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + + char _command[SW_REDIS_MAX_COMMAND_SIZE]; + int length = snprintf(_command, sizeof(_command), "_handler_%s", command); + php_strtolower(_command, length); +#ifdef SW_COROUTINE + int func_cache_index = func_cache_array.count; + func_cache_array.array[func_cache_index] = func_cache; + func_cache_array.count++; + if (func_cache_array.count == func_cache_array.size) + { + func_cache_array.size *= 2; + func_cache_array.array = ecalloc(func_cache_array.size, sizeof(zend_fcall_info_cache *)); + } + sw_zval_add_ref(&zcallback); + zend_update_property_long(swoole_redis_server_class_entry_ptr, getThis(), _command, length, func_cache_index TSRMLS_CC); +#else + php_strtolower(_command, length); + zend_update_property(swoole_redis_server_class_entry_ptr, getThis(), _command, length, zcallback TSRMLS_CC); +#endif + RETURN_TRUE; +} + +static PHP_METHOD(swoole_redis_server, format) +{ + long type; + zval *value = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &type, &value) == FAILURE) + { + return; + } + + char message[256]; + int length; + zval *item; + + if (type == SW_REDIS_REPLY_NIL) + { + SW_RETURN_STRINGL(SW_REDIS_RETURN_NIL, sizeof(SW_REDIS_RETURN_NIL)-1, 1); + } + else if (type == SW_REDIS_REPLY_STATUS) + { + if (value) + { + convert_to_string(value); + length = snprintf(message, sizeof(message), "+%*s\r\n", Z_STRLEN_P(value), Z_STRVAL_P(value)); + } + else + { + length = snprintf(message, sizeof(message), "+%s\r\n", "OK"); + } + SW_RETURN_STRINGL(message, length, 1); + } + else if (type == SW_REDIS_REPLY_ERROR) + { + if (value) + { + convert_to_string(value); + length = snprintf(message, sizeof(message), "-%*s\r\n", Z_STRLEN_P(value), Z_STRVAL_P(value)); + } + else + { + length = snprintf(message, sizeof(message), "-%s\r\n", "ERR"); + } + SW_RETURN_STRINGL(message, length, 1); + } + else if (type == SW_REDIS_REPLY_INT) + { + if (!value) + { + goto no_value; + } + + convert_to_long(value); + length = snprintf(message, sizeof(message), ":%d\r\n", Z_LVAL_P(value)); + SW_RETURN_STRINGL(message, length, 1); + } + else if (type == SW_REDIS_REPLY_STRING) + { + if (!value) + { + no_value: + swoole_php_fatal_error(E_WARNING, "require more parameters."); + RETURN_FALSE; + } + convert_to_string(value); + if (Z_STRLEN_P(value) > SW_REDIS_MAX_STRING_SIZE || Z_STRLEN_P(value) < 1) + { + swoole_php_fatal_error(E_WARNING, "invalid string size."); + RETURN_FALSE; + } + swString_clear(format_buffer); + length = snprintf(message, sizeof(message), "$%d\r\n", Z_STRLEN_P(value)); + swString_append_ptr(format_buffer, message, length); + swString_append_ptr(format_buffer, Z_STRVAL_P(value), Z_STRLEN_P(value)); + swString_append_ptr(format_buffer, SW_CRLF, SW_CRLF_LEN); + SW_RETURN_STRINGL(format_buffer->str, format_buffer->length, 1); + } + else if (type == SW_REDIS_REPLY_SET) + { + if (!value) + { + goto no_value; + } + if (Z_TYPE_P(value) != IS_ARRAY) + { + swoole_php_fatal_error(E_WARNING, "the second parameter should be an array."); + } + swString_clear(format_buffer); + length = snprintf(message, sizeof(message), "*%d\r\n", zend_hash_num_elements(Z_ARRVAL_P(value))); + swString_append_ptr(format_buffer, message, length); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(value), item) +#if PHP_MAJOR_VERSION >= 7 + zval _copy; + if (Z_TYPE_P(item) != IS_STRING) + { + _copy = *item; + zval_copy_ctor(&_copy); + item = &_copy; + } +#endif + convert_to_string(item); + length = snprintf(message, sizeof(message), "$%d\r\n", Z_STRLEN_P(item)); + swString_append_ptr(format_buffer, message, length); + swString_append_ptr(format_buffer, Z_STRVAL_P(item), Z_STRLEN_P(item)); + swString_append_ptr(format_buffer, SW_CRLF, SW_CRLF_LEN); +#if PHP_MAJOR_VERSION >= 7 + if (item == &_copy) + { + zval_dtor(item); + } +#endif + SW_HASHTABLE_FOREACH_END(); + + SW_RETURN_STRINGL(format_buffer->str, format_buffer->length, 1); + } + else if (type == SW_REDIS_REPLY_MAP) + { + if (!value) + { + goto no_value; + } + if (Z_TYPE_P(value) != IS_ARRAY) + { + swoole_php_fatal_error(E_WARNING, "the second parameter should be an array."); + } + swString_clear(format_buffer); + length = snprintf(message, sizeof(message), "*%d\r\n", 2 * zend_hash_num_elements(Z_ARRVAL_P(value))); + swString_append_ptr(format_buffer, message, length); + + char *key; + uint32_t keylen; + int keytype; + + SW_HASHTABLE_FOREACH_START2(Z_ARRVAL_P(value), key, keylen, keytype, item) + if (key == NULL || keylen <= 0) + { + continue; + } +#if PHP_MAJOR_VERSION >= 7 + zval _copy; + if (Z_TYPE_P(item) != IS_STRING) + { + _copy = *item; + zval_copy_ctor(&_copy); + item = &_copy; + } +#endif + convert_to_string(item); + length = snprintf(message, sizeof(message), "$%d\r\n%s\r\n$%d\r\n", keylen, key, Z_STRLEN_P(item)); + swString_append_ptr(format_buffer, message, length); + swString_append_ptr(format_buffer, Z_STRVAL_P(item), Z_STRLEN_P(item)); + swString_append_ptr(format_buffer, SW_CRLF, SW_CRLF_LEN); + +#if PHP_MAJOR_VERSION >= 7 + if (item == &_copy) + { + zval_dtor(item); + } +#endif + (void) keytype; + SW_HASHTABLE_FOREACH_END(); + + SW_RETURN_STRINGL(format_buffer->str, format_buffer->length, 1); + } + else + { + swoole_php_error(E_WARNING, "Unknown type[%ld]", type); + RETURN_FALSE; + } +} diff --git a/vendor/swoole/swoole_ringqueue.c b/vendor/swoole/swoole_ringqueue.c new file mode 100755 index 0000000..f938154 --- /dev/null +++ b/vendor/swoole/swoole_ringqueue.c @@ -0,0 +1,151 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + +----------------------------------------------------------------------+ + */ + + +#include "php_swoole.h" + +static PHP_METHOD(swoole_ringqueue, __construct); +static PHP_METHOD(swoole_ringqueue, __destruct); +static PHP_METHOD(swoole_ringqueue, push); +static PHP_METHOD(swoole_ringqueue, pop); +static PHP_METHOD(swoole_ringqueue, count); +static PHP_METHOD(swoole_ringqueue, isFull); +static PHP_METHOD(swoole_ringqueue, isEmpty); + +static zend_class_entry swoole_ringqueue_ce; +zend_class_entry *swoole_ringqueue_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_ringqueue_construct, 0, 0, 1) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_ringqueue_push, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_ringqueue_methods[] = +{ + PHP_ME(swoole_ringqueue, __construct, arginfo_swoole_ringqueue_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_ringqueue, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_ringqueue, push, arginfo_swoole_ringqueue_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_ringqueue, pop, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_ringqueue, count, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_ringqueue, isFull, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_ringqueue, isEmpty, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +void swoole_ringqueue_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_ringqueue_ce, "swoole_ringqueue", "Swoole\\RingQueue", swoole_ringqueue_methods); + swoole_ringqueue_class_entry_ptr = zend_register_internal_class(&swoole_ringqueue_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_ringqueue, "Swoole\\RingQueue"); +} + +static PHP_METHOD(swoole_ringqueue, __construct) +{ + long len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &len) == FAILURE) + { + RETURN_FALSE; + } + + if (len < 0) + { + len = SW_RINGQUEUE_LEN; + } + + swRingQueue *queue = emalloc(sizeof(swRingQueue)); + if (queue == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to create ringqueue.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + if (swRingQueue_init(queue, len)) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "failed to init ringqueue.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + swoole_set_object(getThis(), queue); +} + +static PHP_METHOD(swoole_ringqueue, __destruct) +{ + swRingQueue *queue = swoole_get_object(getThis()); + efree(queue); + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_ringqueue, push) +{ + swRingQueue *queue = swoole_get_object(getThis()); + zval *zdata; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zdata) == FAILURE) + { + RETURN_FALSE; + } + + zdata = sw_zval_dup(zdata); + if (swRingQueue_push(queue, zdata) < 0) + { + efree(zdata); + RETURN_FALSE; + } + else + { + Z_TRY_ADDREF_P(zdata); + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_ringqueue, pop) +{ + swRingQueue *queue = swoole_get_object(getThis()); + zval *zdata; + + int n = swRingQueue_pop(queue, (void**)&zdata); + if (n < 0) + { + RETURN_FALSE; + } + RETVAL_ZVAL(zdata, 0, 0); + efree(zdata); +} + +static PHP_METHOD(swoole_ringqueue, isFull) +{ + swRingQueue *queue = swoole_get_object(getThis()); + RETURN_BOOL(swRingQueue_full(queue)); +} + +static PHP_METHOD(swoole_ringqueue, isEmpty) +{ + swRingQueue *queue = swoole_get_object(getThis()); + RETURN_BOOL(swRingQueue_empty(queue)); +} + +static PHP_METHOD(swoole_ringqueue, count) +{ + swRingQueue *queue = swoole_get_object(getThis()); + RETURN_LONG(swRingQueue_count(queue)); +} diff --git a/vendor/swoole/swoole_runtime.cc b/vendor/swoole/swoole_runtime.cc new file mode 100755 index 0000000..b474b5d --- /dev/null +++ b/vendor/swoole/swoole_runtime.cc @@ -0,0 +1,66 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Xinyu Zhu <xyzhu1120@gmail.com> | + | shiguangqi <shiguangqi2008@gmail.com> | + | Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +#include "php_swoole.h" + +#ifdef SW_USE_PHPX + +#include <initializer_list> + +extern "C" +{ +static PHP_METHOD(swoole_runtime, enableStrictMode); +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +zend_class_entry *ce; + +static const zend_function_entry swoole_runtime_methods[] = +{ + PHP_ME(swoole_runtime, enableStrictMode, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +void swoole_runtime_init(int module_number TSRMLS_DC) +{ + static zend_class_entry _ce; + INIT_CLASS_ENTRY(_ce, "Swoole\\Runtime", swoole_runtime_methods); + ce = zend_register_internal_class(&_ce TSRMLS_CC); +} + +static auto block_io_functions = +{ "sleep", "usleep", "time_nanosleep", "time_sleep_until", "file_get_contents", "curl_init", "stream_select", + "socket_select", "gethostbyname", }; + +static auto block_io_classes = +{ "redis", "mysqli", }; + +static PHP_METHOD(swoole_runtime, enableStrictMode) +{ + for (auto f : block_io_functions) + { + zend_disable_function((char *) f, strlen((char *) f)); + } + for (auto c : block_io_classes) + { + zend_disable_class((char *) c, strlen((char *) c)); + } +} + +#endif diff --git a/vendor/swoole/swoole_serialize.c b/vendor/swoole/swoole_serialize.c new file mode 100755 index 0000000..1f6c808 --- /dev/null +++ b/vendor/swoole/swoole_serialize.c @@ -0,0 +1,1577 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: xinhua.guo <woshiguo35@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#include "swoole_serialize.h" +#ifdef __SSE2__ +#include <emmintrin.h> +#endif + +#if PHP_MAJOR_VERSION >= 7 +#define CPINLINE sw_inline + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_serialize_pack, 0, 0, 1) +ZEND_ARG_INFO(0, data) +ZEND_ARG_INFO(0, flag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_serialize_unpack, 0, 0, 1) +ZEND_ARG_INFO(0, string) +ZEND_ARG_INFO(0, args) +ZEND_END_ARG_INFO() + +static void swoole_serialize_object(seriaString *buffer, zval *zvalue, size_t start); +static void swoole_serialize_arr(seriaString *buffer, zend_array *zvalue); +static void* swoole_unserialize_arr(void *buffer, zval *zvalue, uint32_t num, long flag); +static void* swoole_unserialize_object(void *buffer, zval *return_value, zend_uchar bucket_len, zval *args, long flag); + +static PHP_METHOD(swoole_serialize, pack); +static PHP_METHOD(swoole_serialize, unpack); + + +static const zend_function_entry swoole_serialize_methods[] = { + PHP_ME(swoole_serialize, pack, arginfo_swoole_serialize_pack, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_serialize, unpack, arginfo_swoole_serialize_unpack, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +zend_class_entry swoole_serialize_ce; +zend_class_entry *swoole_serialize_class_entry_ptr; + +#define SWOOLE_SERI_EOF "EOF" + +static struct _swSeriaG swSeriaG; + +void swoole_serialize_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_serialize_ce, "swoole_serialize", "Swoole\\Serialize", swoole_serialize_methods); + swoole_serialize_class_entry_ptr = zend_register_internal_class(&swoole_serialize_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_serialize, "Swoole\\Serialize"); + + // ZVAL_STRING(&swSeriaG.sleep_fname, "__sleep"); + zend_string *zstr_sleep = zend_string_init("__sleep", sizeof ("__sleep") - 1, 1); + zend_string *zstr_weekup = zend_string_init("__weekup", sizeof ("__weekup") - 1, 1); + ZVAL_STR(&swSeriaG.sleep_fname, zstr_sleep); + ZVAL_STR(&swSeriaG.weekup_fname, zstr_weekup); + // ZVAL_STRING(&swSeriaG.weekup_fname, "__weekup"); + + memset(&swSeriaG.filter, 0, sizeof (swSeriaG.filter)); + memset(&mini_filter, 0, sizeof (mini_filter)); + + REGISTER_LONG_CONSTANT("SWOOLE_FAST_PACK", SW_FAST_PACK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("UNSERIALIZE_OBJECT_TO_ARRAY", UNSERIALIZE_OBJECT_TO_ARRAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("UNSERIALIZE_OBJECT_TO_STDCLASS", UNSERIALIZE_OBJECT_TO_STDCLASS, CONST_CS | CONST_PERSISTENT); +} + +static CPINLINE int swoole_string_new(size_t size, seriaString *str, zend_uchar type) +{ + int total = ZEND_MM_ALIGNED_SIZE(_STR_HEADER_SIZE + size + 1); + str->total = total; + //escape the header for later + str->offset = _STR_HEADER_SIZE; + //zend string addr + str->buffer = ecalloc(1, total); + if (!str->buffer) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "malloc Error: %s [%d]", strerror(errno), errno); + } + + SBucketType real_type = {0}; + real_type.data_type = type; + *(SBucketType*) (str->buffer + str->offset) = real_type; + str->offset += sizeof (SBucketType); + return 0; +} + +static CPINLINE void swoole_check_size(seriaString *str, size_t len) +{ + int new_size = len + str->offset; + // int new_size = len + str->offset + 3 + sizeof (zend_ulong); //space 1 for the type and 2 for key string len or index len and(zend_ulong) for key h + if (str->total < new_size) + {//extend it + + new_size = ZEND_MM_ALIGNED_SIZE(new_size + SERIA_SIZE); + str->buffer = erealloc2(str->buffer, new_size, str->offset); + if (!str->buffer) + { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "realloc Error: %s [%d]", strerror(errno), errno); + } + str->total = new_size; + } +} +#ifdef __SSE2__ +void CPINLINE swoole_mini_memcpy(void *dst, const void *src, size_t len) +{ + register unsigned char *dd = (unsigned char*) dst + len; + register const unsigned char *ss = (const unsigned char*) src + len; + switch (len) + { + case 68: *((int*) (dd - 68)) = *((int*) (ss - 68)); + /* no break */ + case 64: *((int*) (dd - 64)) = *((int*) (ss - 64)); + /* no break */ + case 60: *((int*) (dd - 60)) = *((int*) (ss - 60)); + /* no break */ + case 56: *((int*) (dd - 56)) = *((int*) (ss - 56)); + /* no break */ + case 52: *((int*) (dd - 52)) = *((int*) (ss - 52)); + /* no break */ + case 48: *((int*) (dd - 48)) = *((int*) (ss - 48)); + /* no break */ + case 44: *((int*) (dd - 44)) = *((int*) (ss - 44)); + /* no break */ + case 40: *((int*) (dd - 40)) = *((int*) (ss - 40)); + /* no break */ + case 36: *((int*) (dd - 36)) = *((int*) (ss - 36)); + /* no break */ + case 32: *((int*) (dd - 32)) = *((int*) (ss - 32)); + /* no break */ + case 28: *((int*) (dd - 28)) = *((int*) (ss - 28)); + /* no break */ + case 24: *((int*) (dd - 24)) = *((int*) (ss - 24)); + /* no break */ + case 20: *((int*) (dd - 20)) = *((int*) (ss - 20)); + /* no break */ + case 16: *((int*) (dd - 16)) = *((int*) (ss - 16)); + /* no break */ + case 12: *((int*) (dd - 12)) = *((int*) (ss - 12)); + /* no break */ + case 8: *((int*) (dd - 8)) = *((int*) (ss - 8)); + /* no break */ + case 4: *((int*) (dd - 4)) = *((int*) (ss - 4)); + break; + case 67: *((int*) (dd - 67)) = *((int*) (ss - 67)); + /* no break */ + case 63: *((int*) (dd - 63)) = *((int*) (ss - 63)); + /* no break */ + case 59: *((int*) (dd - 59)) = *((int*) (ss - 59)); + /* no break */ + case 55: *((int*) (dd - 55)) = *((int*) (ss - 55)); + /* no break */ + case 51: *((int*) (dd - 51)) = *((int*) (ss - 51)); + /* no break */ + case 47: *((int*) (dd - 47)) = *((int*) (ss - 47)); + /* no break */ + case 43: *((int*) (dd - 43)) = *((int*) (ss - 43)); + /* no break */ + case 39: *((int*) (dd - 39)) = *((int*) (ss - 39)); + /* no break */ + case 35: *((int*) (dd - 35)) = *((int*) (ss - 35)); + /* no break */ + case 31: *((int*) (dd - 31)) = *((int*) (ss - 31)); + /* no break */ + case 27: *((int*) (dd - 27)) = *((int*) (ss - 27)); + /* no break */ + case 23: *((int*) (dd - 23)) = *((int*) (ss - 23)); + /* no break */ + case 19: *((int*) (dd - 19)) = *((int*) (ss - 19)); + /* no break */ + case 15: *((int*) (dd - 15)) = *((int*) (ss - 15)); + /* no break */ + case 11: *((int*) (dd - 11)) = *((int*) (ss - 11)); + /* no break */ + case 7: *((int*) (dd - 7)) = *((int*) (ss - 7)); + *((int*) (dd - 4)) = *((int*) (ss - 4)); + break; + case 3: *((short*) (dd - 3)) = *((short*) (ss - 3)); + dd[-1] = ss[-1]; + break; + case 66: *((int*) (dd - 66)) = *((int*) (ss - 66)); + /* no break */ + case 62: *((int*) (dd - 62)) = *((int*) (ss - 62)); + /* no break */ + case 58: *((int*) (dd - 58)) = *((int*) (ss - 58)); + /* no break */ + case 54: *((int*) (dd - 54)) = *((int*) (ss - 54)); + /* no break */ + case 50: *((int*) (dd - 50)) = *((int*) (ss - 50)); + /* no break */ + case 46: *((int*) (dd - 46)) = *((int*) (ss - 46)); + /* no break */ + case 42: *((int*) (dd - 42)) = *((int*) (ss - 42)); + /* no break */ + case 38: *((int*) (dd - 38)) = *((int*) (ss - 38)); + /* no break */ + case 34: *((int*) (dd - 34)) = *((int*) (ss - 34)); + /* no break */ + case 30: *((int*) (dd - 30)) = *((int*) (ss - 30)); + /* no break */ + case 26: *((int*) (dd - 26)) = *((int*) (ss - 26)); + /* no break */ + case 22: *((int*) (dd - 22)) = *((int*) (ss - 22)); + /* no break */ + case 18: *((int*) (dd - 18)) = *((int*) (ss - 18)); + /* no break */ + case 14: *((int*) (dd - 14)) = *((int*) (ss - 14)); + /* no break */ + case 10: *((int*) (dd - 10)) = *((int*) (ss - 10)); + /* no break */ + case 6: *((int*) (dd - 6)) = *((int*) (ss - 6)); + /* no break */ + case 2: *((short*) (dd - 2)) = *((short*) (ss - 2)); + break; + case 65: *((int*) (dd - 65)) = *((int*) (ss - 65)); + /* no break */ + case 61: *((int*) (dd - 61)) = *((int*) (ss - 61)); + /* no break */ + case 57: *((int*) (dd - 57)) = *((int*) (ss - 57)); + /* no break */ + case 53: *((int*) (dd - 53)) = *((int*) (ss - 53)); + /* no break */ + case 49: *((int*) (dd - 49)) = *((int*) (ss - 49)); + /* no break */ + case 45: *((int*) (dd - 45)) = *((int*) (ss - 45)); + /* no break */ + case 41: *((int*) (dd - 41)) = *((int*) (ss - 41)); + /* no break */ + case 37: *((int*) (dd - 37)) = *((int*) (ss - 37)); + /* no break */ + case 33: *((int*) (dd - 33)) = *((int*) (ss - 33)); + /* no break */ + case 29: *((int*) (dd - 29)) = *((int*) (ss - 29)); + /* no break */ + case 25: *((int*) (dd - 25)) = *((int*) (ss - 25)); + /* no break */ + case 21: *((int*) (dd - 21)) = *((int*) (ss - 21)); + /* no break */ + case 17: *((int*) (dd - 17)) = *((int*) (ss - 17)); + /* no break */ + case 13: *((int*) (dd - 13)) = *((int*) (ss - 13)); + /* no break */ + case 9: *((int*) (dd - 9)) = *((int*) (ss - 9)); + /* no break */ + case 5: *((int*) (dd - 5)) = *((int*) (ss - 5)); + /* no break */ + case 1: dd[-1] = ss[-1]; + break; + case 0: + default: break; + } +} + +void CPINLINE swoole_memcpy_fast(void *destination, const void *source, size_t size) +{ + unsigned char *dst = (unsigned char*) destination; + const unsigned char *src = (const unsigned char*) source; + + // small memory copy + if (size < 64) + { + swoole_mini_memcpy(dst, src, size); + return; + } + + size_t diff = (((size_t) dst + 15L) & (~15L)) - ((size_t) dst); + if (diff > 0) + { + swoole_mini_memcpy(dst, src, diff); + dst += diff; + src += diff; + size -= diff; + } + + // 4个寄存器 + __m128i c1, c2, c3, c4; + + if ((((size_t) src) & 15L) == 0) + { + for(; size >= 64; size -= 64) + { + //load 时候将下次要用的数据提前fetch + _mm_prefetch((const char*) (src + 64), _MM_HINT_NTA); + _mm_prefetch((const char*) (dst + 64), _MM_HINT_T0); + //从内存中load到寄存器 + c1 = _mm_load_si128(((const __m128i*) src) + 0); + c2 = _mm_load_si128(((const __m128i*) src) + 1); + c3 = _mm_load_si128(((const __m128i*) src) + 2); + c4 = _mm_load_si128(((const __m128i*) src) + 3); + src += 64; + //写回内存 + _mm_store_si128((((__m128i*) dst) + 0), c1); + _mm_store_si128((((__m128i*) dst) + 1), c2); + _mm_store_si128((((__m128i*) dst) + 2), c3); + _mm_store_si128((((__m128i*) dst) + 3), c4); + dst += 64; + } + } + else + { + for(; size >= 64; size -= 64) + { + _mm_prefetch((const char*) (src + 64), _MM_HINT_NTA); + _mm_prefetch((const char*) (dst + 64), _MM_HINT_T0); + c1 = _mm_loadu_si128(((const __m128i*) src) + 0); + c2 = _mm_loadu_si128(((const __m128i*) src) + 1); + c3 = _mm_loadu_si128(((const __m128i*) src) + 2); + c4 = _mm_loadu_si128(((const __m128i*) src) + 3); + src += 64; + _mm_store_si128((((__m128i*) dst) + 0), c1); + _mm_store_si128((((__m128i*) dst) + 1), c2); + _mm_store_si128((((__m128i*) dst) + 2), c3); + _mm_store_si128((((__m128i*) dst) + 3), c4); + dst += 64; + } + } + // _mm_sfence(); + + // return memcpy_tiny(dst, src, size); +} +#endif + +static CPINLINE void swoole_string_cpy(seriaString *str, void *mem, size_t len) +{ + swoole_check_size(str, len + 15L); + //example:13+15=28 28& 11111111 11111111 11111111 11110000 + //str->offset = ((str->offset + 15L) & ~15L); + // swoole_memcspy_fast(str->buffer + str->offset, mem, len); + memcpy(str->buffer + str->offset, mem, len); + str->offset = len + str->offset; +} + +static CPINLINE void swoole_set_zend_value(seriaString *str, void *value) +{ + swoole_check_size(str, sizeof (zend_value)); + *(zend_value*) (str->buffer + str->offset) = *((zend_value*) value); + str->offset = sizeof (zend_value) + str->offset; +} + +static CPINLINE void swoole_serialize_long(seriaString *buffer, zval *zvalue, SBucketType* type) +{ + zend_long value = Z_LVAL_P(zvalue); + //01111111 - 11111111 + if (value <= 0x7f && value >= -0x7f) + { + type->data_len = 0; + SERIA_SET_ENTRY_TYPE_WITH_MINUS(buffer, value); + } + else if (value <= 0x7fff && value >= -0x7fff) + { + type->data_len = 1; + SERIA_SET_ENTRY_SHORT_WITH_MINUS(buffer, value); + } + else if (value <= 0x7fffffff && value >= -0x7fffffff) + { + type->data_len = 2; + SERIA_SET_ENTRY_SIZE4_WITH_MINUS(buffer, value); + } + else + { + type->data_len = 3; + swoole_string_cpy(buffer, &zvalue->value, sizeof (zend_value)); + } + +} + +static CPINLINE void* swoole_unserialize_long(void *buffer, zval *ret_value, SBucketType type) +{ + if (type.data_len == 0) + {//1 byte + Z_LVAL_P(ret_value) = *((char*) buffer); + buffer += sizeof (char); + } + else if (type.data_len == 1) + {//2 byte + Z_LVAL_P(ret_value) = *((short*) buffer); + buffer += sizeof (short); + } + else if (type.data_len == 2) + {//4 byte + Z_LVAL_P(ret_value) = *((int32_t *) buffer); + buffer += sizeof (int32_t); + } + else + {//8 byte + ret_value->value = *((zend_value*) buffer); + buffer += sizeof (zend_value); + } + return buffer; +} + +static uint32_t CPINLINE cp_zend_hash_check_size(uint32_t nSize) +{ +#if defined(ZEND_WIN32) + unsigned long index; +#endif + + /* Use big enough power of 2 */ + /* size should be between HT_MIN_SIZE and HT_MAX_SIZE */ + if (nSize < HT_MIN_SIZE) + { + nSize = HT_MIN_SIZE; + }// else if (UNEXPECTED(nSize >= 1000000)) + else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "invalid unserialize data"); + return 0; + } + +#if defined(ZEND_WIN32) + if (BitScanReverse(&index, nSize - 1)) + { + return 0x2 << ((31 - index) ^ 0x1f); + } + else + { + /* nSize is ensured to be in the valid range, fall back to it + rather than using an undefined bis scan result. */ + return nSize; + } +#elif (defined(__GNUC__) || __has_builtin(__builtin_clz)) && defined(PHP_HAVE_BUILTIN_CLZ) + return 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f); +#else + nSize -= 1; + nSize |= (nSize >> 1); + nSize |= (nSize >> 2); + nSize |= (nSize >> 4); + nSize |= (nSize >> 8); + nSize |= (nSize >> 16); + return nSize + 1; +#endif +} + +static CPINLINE void swoole_mini_filter_clear() +{ + if (swSeriaG.pack_string) + { + memset(&mini_filter, 0, sizeof (mini_filter)); + if (bigger_filter) + { + efree(bigger_filter); + bigger_filter = NULL; + + } + memset(&swSeriaG.filter, 0, sizeof (struct _swMinFilter)); + } +} + +static CPINLINE void swoole_make_bigger_filter_size() +{ + if (FILTER_SIZE <= swSeriaG.filter.mini_fillter_miss_cnt && + swSeriaG.filter.mini_fillter_find_cnt < swSeriaG.filter.mini_fillter_miss_cnt) + // if (FILTER_SIZE <= swSeriaG.filter.mini_fillter_miss_cnt && + // (swSeriaG.filter.mini_fillter_find_cnt / swSeriaG.filter.mini_fillter_miss_cnt) < 1) + { + swSeriaG.filter.bigger_fillter_size = swSeriaG.filter.mini_fillter_miss_cnt * 128; + bigger_filter = (swPoolstr*) ecalloc(1, sizeof (swPoolstr) * swSeriaG.filter.bigger_fillter_size); + memcpy(bigger_filter, &mini_filter, sizeof (mini_filter)); + } +} + +static CPINLINE void swoole_mini_filter_add(zend_string *zstr, size_t offset, zend_uchar byte) +{ + if (swSeriaG.pack_string) + { + offset -= _STR_HEADER_SIZE; + //head 3bit is overhead + if (offset >= 0x1fffffff) + { + return; + } + if (bigger_filter) + { + uint32_t mod_big = zstr->h & (swSeriaG.filter.bigger_fillter_size - 1); + + bigger_filter[mod_big].offset = offset << 3; + if (offset <= 0x1fff) + { + bigger_filter[mod_big].offset |= byte; + } + else + { + bigger_filter[mod_big].offset |= (byte | 4); + } + bigger_filter[mod_big].str = zstr; + } + else + { + uint16_t mod = zstr->h & (FILTER_SIZE - 1); + //repalce it is effective,cause the principle of locality + mini_filter[mod].offset = offset << 3; + if (offset <= 0x1fff) + { + mini_filter[mod].offset |= byte; + } + else + { + mini_filter[mod].offset |= (byte | 4); + } + mini_filter[mod].str = zstr; + swSeriaG.filter.mini_fillter_miss_cnt++; + swoole_make_bigger_filter_size(); + } + } + +} + +static CPINLINE swPoolstr* swoole_mini_filter_find(zend_string *zstr) +{ + if (swSeriaG.pack_string) + { + zend_ulong h = zend_string_hash_val(zstr); + swPoolstr* str = NULL; + if (bigger_filter) + { + str = &bigger_filter[h & (swSeriaG.filter.bigger_fillter_size - 1)]; + } + else + { + str = &mini_filter[h & (FILTER_SIZE - 1)]; + } + + if (!str->str) + { + return NULL; + } + + if (str->str->h == h && + zstr->len == str->str->len && + memcmp(zstr->val, str->str->val, zstr->len) == 0) + { + swSeriaG.filter.mini_fillter_find_cnt++; + return str; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + * arr layout + * type|key?|bucketlen|buckets + */ +static CPINLINE void seria_array_type(zend_array *ht, seriaString *buffer, size_t type_offset, size_t blen_offset) +{ + buffer->offset = blen_offset; + if (ht->nNumOfElements <= 0xff) + { + ((SBucketType*) (buffer->buffer + type_offset))->data_len = 1; + SERIA_SET_ENTRY_TYPE(buffer, ht->nNumOfElements) + } + else if (ht->nNumOfElements <= 0xffff) + { + ((SBucketType*) (buffer->buffer + type_offset))->data_len = 2; + SERIA_SET_ENTRY_SHORT(buffer, ht->nNumOfElements); + } + else + { + ((SBucketType*) (buffer->buffer + type_offset))->data_len = 0; + swoole_string_cpy(buffer, &ht->nNumOfElements, sizeof (uint32_t)); + } +} + +/* + * buffer is bucket len addr + */ +static CPINLINE void* get_array_real_len(void *buffer, zend_uchar data_len, uint32_t *nNumOfElements) +{ + if (data_len == 1) + { + *nNumOfElements = *((zend_uchar*) buffer); + return buffer + sizeof (zend_uchar); + } + else if (data_len == 2) + { + *nNumOfElements = *((unsigned short*) buffer); + return buffer + sizeof (short); + } + else + { + *nNumOfElements = *((uint32_t*) buffer); + return buffer + sizeof (uint32_t); + } +} + +static CPINLINE void * get_pack_string_len_addr(void ** buffer, size_t *strlen) +{ + + uint8_t overhead = (*(uint8_t*) * buffer); + uint32_t real_offset; + uint8_t len_byte; + + if (overhead & 4) + { + real_offset = (*(uint32_t*) * buffer) >> 3; + len_byte = overhead & 3; + (*buffer) += 4; + } + else + { + real_offset = (*(uint16_t*) * buffer) >> 3; + len_byte = overhead & 3; + (*buffer) += 2; + } + void *str_pool_addr = unser_start + real_offset; + if (len_byte == 1) + { + *strlen = *((zend_uchar*) str_pool_addr); + str_pool_addr = str_pool_addr + sizeof (zend_uchar); + } + else if (len_byte == 2) + { + *strlen = *((unsigned short*) str_pool_addr); + str_pool_addr = str_pool_addr + sizeof (unsigned short); + } + else + { + *strlen = *((size_t*) str_pool_addr); + str_pool_addr = str_pool_addr + sizeof (size_t); + } + // size_t tmp = *strlen; + return str_pool_addr; +} + +/* + * array + */ + +static void* swoole_unserialize_arr(void *buffer, zval *zvalue, uint32_t nNumOfElements, long flag) +{ + //Initialize zend array + zend_ulong h, nIndex, max_index = 0; + uint32_t size = cp_zend_hash_check_size(nNumOfElements); + if (!size) + { + return NULL; + } + if (!buffer) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "illegal unserialize data"); + return NULL; + } + ZVAL_NEW_ARR(zvalue); + //Initialize buckets + zend_array *ht = Z_ARR_P(zvalue); + ht->nTableSize = size; + ht->nNumUsed = nNumOfElements; + ht->nNumOfElements = nNumOfElements; + ht->nNextFreeElement = 0; +#ifdef HASH_FLAG_APPLY_PROTECTION + ht->u.flags = HASH_FLAG_APPLY_PROTECTION; +#endif + ht->nTableMask = -(ht->nTableSize); + ht->pDestructor = ZVAL_PTR_DTOR; + + GC_SET_REFCOUNT(ht, 1); + GC_TYPE_INFO(ht) = IS_ARRAY; + // if (ht->nNumUsed) + //{ + // void *arData = ecalloc(1, len); + HT_SET_DATA_ADDR(ht, emalloc(HT_SIZE(ht))); + ht->u.flags |= HASH_FLAG_INITIALIZED; + int ht_hash_size = HT_HASH_SIZE((ht)->nTableMask); + if (ht_hash_size <= 0) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "illegal unserialize data"); + return NULL; + } + HT_HASH_RESET(ht); + //} + + + int idx; + Bucket *p; + for(idx = 0; idx < nNumOfElements; idx++) + { + if (!buffer) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "illegal array unserialize data"); + return NULL; + } + SBucketType type = *((SBucketType*) buffer); + buffer += sizeof (SBucketType); + p = ht->arData + idx; + /* Initialize key */ + if (type.key_type == KEY_TYPE_STRING) + { + size_t key_len; + if (type.key_len == 3) + {//read the same mem + void *str_pool_addr = get_pack_string_len_addr(&buffer, &key_len); + p->key = zend_string_init((char*) str_pool_addr, key_len, 0); + h = zend_inline_hash_func((char*) str_pool_addr, key_len); + p->key->h = p->h = h; + } + else + {//move step + if (type.key_len == 1) + { + key_len = *((zend_uchar*) buffer); + buffer += sizeof (zend_uchar); + } + else if (type.key_len == 2) + { + key_len = *((unsigned short*) buffer); + buffer += sizeof (unsigned short); + } + else + { + key_len = *((size_t*) buffer); + buffer += sizeof (size_t); + } + p->key = zend_string_init((char*) buffer, key_len, 0); + // h = zend_inline_hash_func((char*) buffer, key_len); + h = zend_inline_hash_func((char*) buffer, key_len); + buffer += key_len; + p->key->h = p->h = h; + } + } + else + { + if (type.key_len == 0) + { + //means pack + h = p->h = idx; + p->key = NULL; + max_index = p->h + 1; + // ht->u.flags |= HASH_FLAG_PACKED; + } + else + { + if (type.key_len == 1) + { + h = *((zend_uchar*) buffer); + buffer += sizeof (zend_uchar); + } + else if (type.key_len == 2) + { + h = *((unsigned short*) buffer); + buffer += sizeof (unsigned short); + } + else + { + h = *((zend_ulong*) buffer); + buffer += sizeof (zend_ulong); + } + p->h = h; + p->key = NULL; + if (h >= max_index) + { + max_index = h + 1; + } + } + } + /* Initialize hash */ + nIndex = h | ht->nTableMask; + Z_NEXT(p->val) = HT_HASH(ht, nIndex); + HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); + + /* Initialize data type */ + p->val.u1.v.type = type.data_type; + Z_TYPE_FLAGS(p->val) = 0; + + /* Initialize data */ + if (type.data_type == IS_STRING) + { + size_t data_len; + if (type.data_len == 3) + {//read the same mem + void *str_pool_addr = get_pack_string_len_addr(&buffer, &data_len); + p->val.value.str = zend_string_init((char*) str_pool_addr, data_len, 0); + } + else + { + if (type.data_len == 1) + { + data_len = *((zend_uchar*) buffer); + buffer += sizeof (zend_uchar); + } + else if (type.data_len == 2) + { + data_len = *((unsigned short*) buffer); + buffer += sizeof (unsigned short); + } + else + { + data_len = *((size_t*) buffer); + buffer += sizeof (size_t); + } + p->val.value.str = zend_string_init((char*) buffer, data_len, 0); + buffer += data_len; + } + Z_TYPE_INFO(p->val) = IS_STRING_EX; + } + else if (type.data_type == IS_ARRAY) + { + uint32_t num = 0; + buffer = get_array_real_len(buffer, type.data_len, &num); + buffer = swoole_unserialize_arr(buffer, &p->val, num, flag); + } + else if (type.data_type == IS_LONG) + { + buffer = swoole_unserialize_long(buffer, &p->val, type); + } + else if (type.data_type == IS_DOUBLE) + { + p->val.value = *((zend_value*) buffer); + buffer += sizeof (zend_value); + } + else if (type.data_type == IS_UNDEF) + { + buffer = swoole_unserialize_object(buffer, &p->val, type.data_len, NULL, flag); + Z_TYPE_INFO(p->val) = IS_OBJECT_EX; + } + + } + ht->nNextFreeElement = max_index; + + return buffer; + +} + +/* + * arr layout + * type|key?|bucketlen|buckets + */ +static void swoole_serialize_arr(seriaString *buffer, zend_array *zvalue) +{ + zval *data; + zend_string *key; + zend_ulong index; + swPoolstr *swStr = NULL; + zend_uchar is_pack = zvalue->u.flags & HASH_FLAG_PACKED; + + ZEND_HASH_FOREACH_KEY_VAL(zvalue, index, key, data) + { + SBucketType type = {0}; + type.data_type = Z_TYPE_P(data); + //start point + size_t p = buffer->offset; + + if (is_pack && zvalue->nNextFreeElement == zvalue->nNumOfElements) + { + type.key_type = KEY_TYPE_INDEX; + type.key_len = 0; + SERIA_SET_ENTRY_TYPE(buffer, type); + } + else + { + //seria key + if (key) + { + type.key_type = KEY_TYPE_STRING; + if ((swStr = swoole_mini_filter_find(key))) + { + type.key_len = 3; //means use same string + SERIA_SET_ENTRY_TYPE(buffer, type); + if (swStr->offset & 4) + { + SERIA_SET_ENTRY_SIZE4(buffer, swStr->offset); + } + else + { + SERIA_SET_ENTRY_SHORT(buffer, swStr->offset); + } + } + else + { + if (key->len <= 0xff) + { + type.key_len = 1; + SERIA_SET_ENTRY_TYPE(buffer, type); + swoole_mini_filter_add(key, buffer->offset, 1); + SERIA_SET_ENTRY_TYPE(buffer, key->len); + swoole_string_cpy(buffer, key->val, key->len); + } + else if (key->len <= 0xffff) + {//if more than this don't need optimize + type.key_len = 2; + SERIA_SET_ENTRY_TYPE(buffer, type); + swoole_mini_filter_add(key, buffer->offset, 2); + SERIA_SET_ENTRY_SHORT(buffer, key->len); + swoole_string_cpy(buffer, key->val, key->len); + } + else + { + type.key_len = 0; + SERIA_SET_ENTRY_TYPE(buffer, type); + swoole_mini_filter_add(key, buffer->offset, 3); + swoole_string_cpy(buffer, key + XtOffsetOf(zend_string, len), sizeof (size_t) + key->len); + } + } + } + else + { + type.key_type = KEY_TYPE_INDEX; + if (index <= 0xff) + { + type.key_len = 1; + SERIA_SET_ENTRY_TYPE(buffer, type); + SERIA_SET_ENTRY_TYPE(buffer, index); + } + else if (index <= 0xffff) + { + type.key_len = 2; + SERIA_SET_ENTRY_TYPE(buffer, type); + SERIA_SET_ENTRY_SHORT(buffer, index); + } + else + { + type.key_len = 3; + SERIA_SET_ENTRY_TYPE(buffer, type); + SERIA_SET_ENTRY_ULONG(buffer, index); + } + + } + } + //seria data +try_again: + switch (Z_TYPE_P(data)) + { + case IS_STRING: + { + if ((swStr = swoole_mini_filter_find(Z_STR_P(data)))) + { + ((SBucketType*) (buffer->buffer + p))->data_len = 3; //means use same string + if (swStr->offset & 4) + { + SERIA_SET_ENTRY_SIZE4(buffer, swStr->offset); + } + else + { + SERIA_SET_ENTRY_SHORT(buffer, swStr->offset); + } + } + else + { + if (Z_STRLEN_P(data) <= 0xff) + { + ((SBucketType*) (buffer->buffer + p))->data_len = 1; + swoole_mini_filter_add(Z_STR_P(data), buffer->offset, 1); + SERIA_SET_ENTRY_TYPE(buffer, Z_STRLEN_P(data)); + swoole_string_cpy(buffer, Z_STRVAL_P(data), Z_STRLEN_P(data)); + } + else if (Z_STRLEN_P(data) <= 0xffff) + { + ((SBucketType*) (buffer->buffer + p))->data_len = 2; + swoole_mini_filter_add(Z_STR_P(data), buffer->offset, 2); + SERIA_SET_ENTRY_SHORT(buffer, Z_STRLEN_P(data)); + swoole_string_cpy(buffer, Z_STRVAL_P(data), Z_STRLEN_P(data)); + } + else + {//if more than this don't need optimize + ((SBucketType*) (buffer->buffer + p))->data_len = 0; + swoole_mini_filter_add(Z_STR_P(data), buffer->offset, 3); + swoole_string_cpy(buffer, (char*) Z_STR_P(data) + XtOffsetOf(zend_string, len), sizeof (size_t) + Z_STRLEN_P(data)); + } + } + break; + } + case IS_LONG: + { + SBucketType* long_type = (SBucketType*) (buffer->buffer + p); + swoole_serialize_long(buffer, data, long_type); + break; + } + case IS_DOUBLE: + swoole_set_zend_value(buffer, &(data->value)); + break; + case IS_REFERENCE: + data = Z_REFVAL_P(data); + ((SBucketType*) (buffer->buffer + p))->data_type = Z_TYPE_P(data); + goto try_again; + break; + case IS_ARRAY: + { + zend_array *ht = Z_ARRVAL_P(data); + + if (GC_IS_RECURSIVE(ht)) + { + ((SBucketType*) (buffer->buffer + p))->data_type = IS_NULL;//reset type null + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "the array has cycle ref"); + } + else + { + seria_array_type(ht, buffer, p, buffer->offset); + if (ZEND_HASH_APPLY_PROTECTION(ht)) + { + GC_PROTECT_RECURSION(ht); + swoole_serialize_arr(buffer, ht); + GC_UNPROTECT_RECURSION(ht); + } + else + { + swoole_serialize_arr(buffer, ht); + } + + } + break; + } + //object propterty table is this type + case IS_INDIRECT: + data = Z_INDIRECT_P(data); + zend_uchar type = Z_TYPE_P(data); + ((SBucketType*) (buffer->buffer + p))->data_type = (type == IS_UNDEF ? IS_NULL : type); + goto try_again; + break; + case IS_OBJECT: + { + /* + * layout + * type | key | namelen | name | bucket len |buckets + */ + ((SBucketType*) (buffer->buffer + p))->data_type = IS_UNDEF; + + if (ZEND_HASH_APPLY_PROTECTION(Z_OBJPROP_P(data))) + { + GC_PROTECT_RECURSION(Z_OBJPROP_P(data)); + swoole_serialize_object(buffer, data, p); + GC_UNPROTECT_RECURSION(Z_OBJPROP_P(data)); + } + else + { + swoole_serialize_object(buffer, data, p); + } + + break; + } + default:// + break; + + } + + } + ZEND_HASH_FOREACH_END(); +} + +/* + * string + */ +static CPINLINE void swoole_serialize_string(seriaString *buffer, zval *zvalue) +{ + + swoole_string_cpy(buffer, Z_STRVAL_P(zvalue), Z_STRLEN_P(zvalue)); +} + +static CPINLINE zend_string* swoole_unserialize_string(void *buffer, size_t len) +{ + + return zend_string_init(buffer, len, 0); +} + +/* + * raw + */ +static CPINLINE void swoole_unserialize_raw(void *buffer, zval *zvalue) +{ + + memcpy(&zvalue->value, buffer, sizeof (zend_value)); +} + +#if 0 +/* + * null + */ +static CPINLINE void swoole_unserialize_null(void *buffer, zval *zvalue) +{ + + memcpy(&zvalue->value, buffer, sizeof (zend_value)); +} +#endif + +static CPINLINE void swoole_serialize_raw(seriaString *buffer, zval *zvalue) +{ + + swoole_string_cpy(buffer, &zvalue->value, sizeof (zend_value)); +} + +/* + * obj layout + * type|bucket key|name len| name| buket len |buckets + */ +static void swoole_serialize_object(seriaString *buffer, zval *obj, size_t start) +{ + zend_string *name = Z_OBJCE_P(obj)->name; + if (GC_IS_RECURSIVE(Z_OBJPROP_P(obj))) + { + zend_throw_exception_ex(NULL, 0, "the object %s has cycle ref.", name->val); + return; + } + if (name->len > 0xffff) + {//so long? + zend_throw_exception_ex(NULL, 0, "the object name is too long."); + } + else + { + SERIA_SET_ENTRY_SHORT(buffer, name->len); + swoole_string_cpy(buffer, name->val, name->len); + } + + zend_class_entry *ce = Z_OBJ_P(obj)->ce; + if (ce && zend_hash_exists(&ce->function_table, Z_STR(swSeriaG.sleep_fname))) + { + zval retval; + if (call_user_function_ex(NULL, obj, &swSeriaG.sleep_fname, &retval, 0, 0, 1, NULL) == SUCCESS) + { + if (EG(exception)) + { + zval_dtor(&retval); + return; + } + if (Z_TYPE(retval) == IS_ARRAY) + { + zend_string *prop_key; + zval *prop_value, *sleep_value; + const char *prop_name, *class_name; + size_t prop_key_len; + int got_num = 0; + + //for the zero malloc + zend_array tmp_arr; + zend_array *ht = (zend_array *) & tmp_arr; +#if PHP_VERSION_ID >= 70300 + _zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL(retval)), ZVAL_PTR_DTOR, 0); +#else + _zend_hash_init(ht, zend_hash_num_elements(Z_ARRVAL(retval)), ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_CC); +#endif + ht->nTableMask = -(ht)->nTableSize; + ALLOCA_FLAG(use_heap); + void *ht_addr = do_alloca(HT_SIZE(ht), use_heap); + HT_SET_DATA_ADDR(ht, ht_addr); + ht->u.flags |= HASH_FLAG_INITIALIZED; + HT_HASH_RESET(ht); + + //just clean property do not add null when does not exist + //we double for each, cause we do not malloc and release it + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_OBJPROP_P(obj), prop_key, prop_value) + { + //get origin property name + zend_unmangle_property_name_ex(prop_key, &class_name, &prop_name, &prop_key_len); + + ZEND_HASH_FOREACH_VAL(Z_ARRVAL(retval), sleep_value) + { + if (Z_TYPE_P(sleep_value) == IS_STRING && + Z_STRLEN_P(sleep_value) == prop_key_len && + memcmp(Z_STRVAL_P(sleep_value), prop_name, prop_key_len) == 0) + { + got_num++; + //add mangle key,unmangle in unseria + _zend_hash_add_or_update(ht, prop_key, prop_value, HASH_UPDATE ZEND_FILE_LINE_CC); + + break; + } + + } + ZEND_HASH_FOREACH_END(); + + } + ZEND_HASH_FOREACH_END(); + + //there some member not in property + if (zend_hash_num_elements(Z_ARRVAL(retval)) > got_num) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep() retrun a member but does not exist in property"); + + } + seria_array_type(ht, buffer, start, buffer->offset); + swoole_serialize_arr(buffer, ht); + ZSTR_ALLOCA_FREE(ht_addr, use_heap); + zval_dtor(&retval); + return; + + } + else + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, " __sleep should return an array only containing the " + "names of instance-variables to serialize"); + zval_dtor(&retval); + } + + } + } + seria_array_type(Z_OBJPROP_P(obj), buffer, start, buffer->offset); + swoole_serialize_arr(buffer, Z_OBJPROP_P(obj)); + // printf("hash2 %u\n",ce->properties_info.arData[0].key->h); +} + +/* + * for the zero malloc + */ +static CPINLINE zend_string * swoole_string_init(const char *str, size_t len) +{ +#ifdef ZEND_DEBUG + return zend_string_init(str, len, 0); +#else + ALLOCA_FLAG(use_heap); + zend_string *ret; + ZSTR_ALLOCA_INIT(ret, str, len, use_heap); + + return ret; +#endif +} + +/* + * for the zero malloc + */ +static CPINLINE void swoole_string_release(zend_string *str) +{ +#ifdef ZEND_DEBUG + zend_string_release(str); +#else + //if dont support alloc 0 will ignore + //if support alloc size is definitely < ZEND_ALLOCA_MAX_SIZE + ZSTR_ALLOCA_FREE(str, 0); +#endif +} + +static CPINLINE zend_class_entry* swoole_try_get_ce(zend_string *class_name) +{ + //user class , do not support incomplete class now + zend_class_entry *ce = zend_lookup_class(class_name); + if (ce) + { + return ce; + } + // try call unserialize callback and retry lookup + zval user_func, args[1], retval; + + /* Check for unserialize callback */ + if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) + { + zend_throw_exception_ex(NULL, 0, "can not find class %s", class_name->val TSRMLS_CC); + return NULL; + } + + zend_string *fname = swoole_string_init(ZEND_STRL(PG(unserialize_callback_func))); + Z_STR(user_func) = fname; + Z_TYPE_INFO(user_func) = IS_STRING_EX; + ZVAL_STR(&args[0], class_name); + + call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL); + + swoole_string_release(fname); + + //user class , do not support incomplete class now + ce = zend_lookup_class(class_name); + if (!ce) + { + zend_throw_exception_ex(NULL, 0, "can not find class %s", class_name->val TSRMLS_CC); + return NULL; + } + else + { + return ce; + } +} + +/* + * obj layout + * type| key[0|1] |name len| name| buket len |buckets + */ +static void* swoole_unserialize_object(void *buffer, zval *return_value, zend_uchar bucket_len, zval *args, long flag) +{ + zval property; + uint32_t arr_num = 0; + size_t name_len = *((unsigned short*) buffer); + if (!name_len) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "illegal unserialize data"); + return NULL; + } + buffer += 2; + zend_string *class_name; + if (flag == UNSERIALIZE_OBJECT_TO_STDCLASS) + { + class_name = swoole_string_init(ZEND_STRL("StdClass")); + } + else + { + class_name = swoole_string_init((char*) buffer, name_len); + } + buffer += name_len; + zend_class_entry *ce = swoole_try_get_ce(class_name); + swoole_string_release(class_name); + + if (!ce) + { + return NULL; + } + + buffer = get_array_real_len(buffer, bucket_len, &arr_num); + buffer = swoole_unserialize_arr(buffer, &property, arr_num, flag); + + object_init_ex(return_value, ce); + + zval *data,*d; + zend_string *key; + zend_ulong index; + + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(property), index, key, data) + { + const char *prop_name, *tmp; + size_t prop_len; + if (key) + { + + if ((d = zend_hash_find(Z_OBJPROP_P(return_value), key)) != NULL) + { + if (Z_TYPE_P(d) == IS_INDIRECT) + { + d = Z_INDIRECT_P(d); + } + ZVAL_COPY(d, data); + } + else + { + zend_unmangle_property_name_ex(key, &tmp, &prop_name, &prop_len); + zend_update_property(ce, return_value, prop_name, prop_len, data); + } +// zend_hash_update(Z_OBJPROP_P(return_value),key,data); +// zend_update_property(ce, return_value, ZSTR_VAL(key), ZSTR_LEN(key), data); + } + else + { + zend_hash_next_index_insert(Z_OBJPROP_P(return_value), data); + } + } + ZEND_HASH_FOREACH_END(); + zval_dtor(&property); + + if (ce->constructor) + { + // zend_fcall_info fci = {0}; + // zend_fcall_info_cache fcc = {0}; + // fci.size = sizeof (zend_fcall_info); + // zval retval; + // ZVAL_UNDEF(&fci.function_name); + // fci.retval = &retval; + // fci.param_count = 0; + // fci.params = NULL; + // fci.no_separation = 1; + // fci.object = Z_OBJ_P(return_value); + // + // zend_fcall_info_args_ex(&fci, ce->constructor, args); + // + // fcc.initialized = 1; + // fcc.function_handler = ce->constructor; + // // fcc.calling_scope = EG(scope); + // fcc.called_scope = Z_OBJCE_P(return_value); + // fcc.object = Z_OBJ_P(return_value); + // + // if (zend_call_function(&fci, &fcc) == FAILURE) + // { + // zend_throw_exception_ex(NULL, 0, "could not call class constructor"); + // } + // zend_fcall_info_args_clear(&fci, 1); + } + + + //call object __wakeup + if (zend_hash_str_exists(&ce->function_table, ZEND_STRL("__wakeup"))) + { + zval ret, wakeup; + zend_string *fname = swoole_string_init(ZEND_STRL("__wakeup")); + Z_STR(wakeup) = fname; + Z_TYPE_INFO(wakeup) = IS_STRING_EX; + call_user_function_ex(CG(function_table), return_value, &wakeup, &ret, 0, NULL, 1, NULL); + swoole_string_release(fname); + zval_ptr_dtor(&ret); + } + + return buffer; + +} + +/* + * dispatch + */ + +static CPINLINE void swoole_seria_dispatch(seriaString *buffer, zval *zvalue) +{ +again: + switch (Z_TYPE_P(zvalue)) + { + case IS_NULL: + case IS_TRUE: + case IS_FALSE: + break; + case IS_LONG: + { + SBucketType* type = (SBucketType*) (buffer->buffer + _STR_HEADER_SIZE); + swoole_serialize_long(buffer, zvalue, type); + break; + } + case IS_DOUBLE: + swoole_serialize_raw(buffer, zvalue); + break; + case IS_STRING: + swoole_serialize_string(buffer, zvalue); + break; + case IS_ARRAY: + { + seria_array_type(Z_ARRVAL_P(zvalue), buffer, _STR_HEADER_SIZE, _STR_HEADER_SIZE + 1); + swoole_serialize_arr(buffer, Z_ARRVAL_P(zvalue)); + swoole_string_cpy(buffer, SWOOLE_SERI_EOF, 3); + swoole_mini_filter_clear(); + break; + } + case IS_REFERENCE: + zvalue = Z_REFVAL_P(zvalue); + goto again; + break; + case IS_OBJECT: + { + SBucketType* type = (SBucketType*) (buffer->buffer + _STR_HEADER_SIZE); + type->data_type = IS_UNDEF; + swoole_serialize_object(buffer, zvalue, _STR_HEADER_SIZE); + swoole_string_cpy(buffer, SWOOLE_SERI_EOF, 3); + swoole_mini_filter_clear(); + break; + } + default: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "the type is not supported by swoole serialize."); + + break; + } +} + +PHPAPI zend_string* php_swoole_serialize(zval *zvalue) +{ + + seriaString str; + swoole_string_new(SERIA_SIZE, &str, Z_TYPE_P(zvalue)); + swoole_seria_dispatch(&str, zvalue); //serialize into a string + zend_string *z_str = (zend_string *) str.buffer; + + z_str->val[str.offset] = '\0'; + z_str->len = str.offset - _STR_HEADER_SIZE; + z_str->h = 0; + GC_SET_REFCOUNT(z_str, 1); + GC_TYPE_INFO(z_str) = IS_STRING_EX; + + return z_str; +} + +static CPINLINE int swoole_seria_check_eof(void *buffer, size_t len) +{ + void *eof_str = buffer - sizeof (SBucketType) + len - 3; + if (memcmp(eof_str, SWOOLE_SERI_EOF, 3) == 0) + { + return 0; + } + else + { + return -1; + } +} + +/* + * buffer is seria string buffer + * len is string len + * return_value is unseria bucket + * args is for the object ctor (can be NULL) + */ +PHPAPI int php_swoole_unserialize(void *buffer, size_t len, zval *return_value, zval *object_args, long flag) +{ + SBucketType type = *(SBucketType*) (buffer); + zend_uchar real_type = type.data_type; + buffer += sizeof (SBucketType); + switch (real_type) + { + case IS_NULL: + case IS_TRUE: + case IS_FALSE: + Z_TYPE_INFO_P(return_value) = real_type; + break; + case IS_LONG: + swoole_unserialize_long(buffer, return_value, type); + Z_TYPE_INFO_P(return_value) = real_type; + break; + case IS_DOUBLE: + swoole_unserialize_raw(buffer, return_value); + Z_TYPE_INFO_P(return_value) = real_type; + break; + case IS_STRING: + len -= sizeof (SBucketType); + zend_string *str = swoole_unserialize_string(buffer, len); + ZVAL_STR(return_value, str); + break; + case IS_ARRAY: + { + if (swoole_seria_check_eof(buffer, len) < 0) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "detect the error eof"); + return SW_FALSE; + } + unser_start = buffer - sizeof (SBucketType); + uint32_t num = 0; + buffer = get_array_real_len(buffer, type.data_len, &num); + if (!swoole_unserialize_arr(buffer, return_value, num, flag)) + { + return SW_FALSE; + } + break; + } + case IS_UNDEF: + if (swoole_seria_check_eof(buffer, len) < 0) + { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "detect the error eof"); + return SW_FALSE; + } + unser_start = buffer - sizeof (SBucketType); + if (!swoole_unserialize_object(buffer, return_value, type.data_len, object_args, flag)) + { + return SW_FALSE; + } + break; + default: + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "the type is not supported by swoole serialize."); + return SW_FALSE; + } + + return SW_TRUE; +} + +static PHP_METHOD(swoole_serialize, pack) +{ + zval *zvalue; + zend_size_t is_fast = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &zvalue, &is_fast) == FAILURE) + { + RETURN_FALSE; + } + swSeriaG.pack_string = !is_fast; + zend_string *z_str = php_swoole_serialize(zvalue); + + RETURN_STR(z_str); +} + +static PHP_METHOD(swoole_serialize, unpack) +{ + char *buffer = NULL; + size_t arg_len; + zval *args = NULL; //for object + long flag = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|la", &buffer, &arg_len, &flag, &args) == FAILURE) + { + RETURN_FALSE; + } + if (!php_swoole_unserialize(buffer, arg_len, return_value, args, flag)) + { + RETURN_FALSE; + } +} + +#endif diff --git a/vendor/swoole/swoole_serialize.h b/vendor/swoole/swoole_serialize.h new file mode 100755 index 0000000..be4f7ba --- /dev/null +++ b/vendor/swoole/swoole_serialize.h @@ -0,0 +1,120 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: xinhua.guo <woshiguo35@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#ifndef SERIALIZE_H +#define SERIALIZE_H + +#ifdef __cplusplus +extern "C" +{ +#endif +#if PHP_MAJOR_VERSION >= 7 + +#define SERIA_SIZE 4096 +#define FILTER_SIZE 1024 + +typedef struct _seriaString +{ + size_t offset; + size_t total; + void * buffer; //zend_string +} seriaString; + +typedef struct _SBucketType +{ + zend_uchar key_type : 1; + zend_uchar key_len : 2; + zend_uchar data_len : 2; + zend_uchar data_type : 3; //IS_UNDEF means object now +} SBucketType; + +struct _swMinFilter +{ + uint32_t mini_fillter_find_cnt; + uint32_t mini_fillter_miss_cnt; + uint32_t bigger_fillter_size; +}; + +struct _swSeriaG +{ + zval sleep_fname; + zval weekup_fname; + zend_uchar pack_string; + struct _swMinFilter filter; +}; + +#pragma pack (4) + +typedef struct _swPoolstr +{ + zend_string *str; + uint32_t offset; +} swPoolstr; + +#pragma pack () + + +static void *unser_start = 0; +static swPoolstr mini_filter[FILTER_SIZE]; +static swPoolstr *bigger_filter = NULL; + +#define SERIA_SET_ENTRY_TYPE_WITH_MINUS(buffer,type) swoole_check_size(buffer, 1);\ + *(char*) (buffer->buffer + buffer->offset) = *((char*) & type);\ + buffer->offset += 1; + +#define SERIA_SET_ENTRY_SHORT_WITH_MINUS(buffer,data) swoole_check_size(buffer, 2);\ + *(short*) (buffer->buffer + buffer->offset) = data;\ + buffer->offset += 2; + +#define SERIA_SET_ENTRY_SIZE4_WITH_MINUS(buffer,data) swoole_check_size(buffer, 4);\ + *(int32_t*) (buffer->buffer + buffer->offset) = data;\ + buffer->offset += 4; + +#define SERIA_SET_ENTRY_TYPE(buffer,type) swoole_check_size(buffer, 1);\ + *(zend_uchar*) (buffer->buffer + buffer->offset) = *((zend_uchar*) & type);\ + buffer->offset += 1; + +#define SERIA_GET_ENTRY_TYPE(buffer) *(zend_uchar*) (buffer->buffer + buffer->offset) = *((zend_uchar*) & type);\ + buffer->offset += 1; + +#define SERIA_SET_ENTRY_SHORT(buffer,data) swoole_check_size(buffer, 2);\ + *(unsigned short*) (buffer->buffer + buffer->offset) = data;\ + buffer->offset += 2; + +#define SERIA_SET_ENTRY_SIZE4(buffer,data) swoole_check_size(buffer, 4);\ + *(uint32_t*) (buffer->buffer + buffer->offset) = data;\ + buffer->offset += 4; + +#define SERIA_SET_ENTRY_ULONG(buffer,data) swoole_check_size(buffer, sizeof(zend_ulong));\ + *(zend_ulong *) (buffer->buffer + buffer->offset) = data;\ + buffer->offset += sizeof(zend_ulong); + +#define KEY_TYPE_STRING 1 +#define KEY_TYPE_INDEX 0 + +#define SW_FAST_PACK 1 + +#define UNSERIALIZE_OBJECT_TO_ARRAY 1 +#define UNSERIALIZE_OBJECT_TO_STDCLASS 2 + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SERIALIZE_H */ + diff --git a/vendor/swoole/swoole_server.c b/vendor/swoole/swoole_server.c new file mode 100755 index 0000000..c2365ca --- /dev/null +++ b/vendor/swoole/swoole_server.c @@ -0,0 +1,4210 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#include "Connection.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif +#include "ext/standard/php_var.h" +#if PHP_MAJOR_VERSION < 7 +#include "ext/standard/php_smart_str.h" +#else +#include "zend_smart_str.h" +#endif + +#ifdef HAVE_PCRE + +typedef struct +{ + int current_fd; + int max_fd; + uint32_t session_id; + swServer *serv; + swListenPort *port; + int end; + int index; +} swConnectionIterator; + +#endif + +static int php_swoole_task_id = 0; +static int udp_server_socket; +static int dgram_server_socket; + +static struct +{ + zval *zobjects[SW_MAX_LISTEN_PORT]; + zval *zports; + uint8_t num; +} server_port_list; + +zval *php_sw_server_callbacks[PHP_SERVER_CALLBACK_NUM]; +zend_fcall_info_cache *php_sw_server_caches[PHP_SERVER_CALLBACK_NUM]; + +static swHashMap *task_callbacks = NULL; +#ifdef SW_COROUTINE +static swHashMap *task_coroutine_map = NULL; +static swHashMap *send_coroutine_map = NULL; +#endif + +#ifdef SW_COROUTINE +typedef struct +{ + php_context context; + int *list; + int count; + zval *result; + swTimer_node *timer; +} swTaskCo; +#endif + +#if PHP_MAJOR_VERSION >= 7 +zval _php_sw_server_callbacks[PHP_SERVER_CALLBACK_NUM]; +#endif + +static int php_swoole_task_finish(swServer *serv, zval *data TSRMLS_DC); +static void php_swoole_onPipeMessage(swServer *serv, swEventData *req); +static void php_swoole_onStart(swServer *); +static void php_swoole_onShutdown(swServer *); +static void php_swoole_onWorkerStart(swServer *, int worker_id); +static void php_swoole_onWorkerStop(swServer *, int worker_id); +static void php_swoole_onWorkerExit(swServer *serv, int worker_id); +static void php_swoole_onUserWorkerStart(swServer *serv, swWorker *worker); +static int php_swoole_onTask(swServer *, swEventData *task); +static int php_swoole_onFinish(swServer *, swEventData *task); +static void php_swoole_onWorkerError(swServer *serv, int worker_id, pid_t worker_pid, int exit_code, int signo); +static void php_swoole_onManagerStart(swServer *serv); +static void php_swoole_onManagerStop(swServer *serv); + +#ifdef SW_COROUTINE +static void php_swoole_onConnect_finish(void *param); +static void php_swoole_onSendTimeout(swTimer *timer, swTimer_node *tnode); +static void php_swoole_server_send_resume(swServer *serv, php_context *context, int fd); +#endif + +static zval* php_swoole_server_add_port(swServer *serv, swListenPort *port TSRMLS_DC); + +static int php_swoole_create_dir(const char* path, size_t length TSRMLS_DC) +{ + if (access(path, F_OK) == 0) + { + return 0; + } +#if 1 + return php_stream_mkdir(path, 0777, PHP_STREAM_MKDIR_RECURSIVE | REPORT_ERRORS, NULL) ? 0 : -1; +#else + int startpath; + int endpath; + int i = 0; + int pathlen = length; + char curpath[128] = {0}; + if ('/' != path[0]) + { + if (getcwd(curpath, sizeof(curpath)) == NULL) + { + swoole_php_sys_error(E_WARNING, "getcwd() failed."); + return -1; + } + strcat(curpath, "/"); + startpath = strlen(curpath); + strcat(curpath, path); + if (path[pathlen] != '/') + { + strcat(curpath, "/"); + } + endpath = strlen(curpath); + } + else + { + strcpy(curpath, path); + if (path[pathlen] != '/') + { + strcat(curpath, "/"); + } + startpath = 1; + endpath = strlen(curpath); + } + for (i = startpath; i < endpath ; i++ ) + { + if ('/' == curpath[i]) + { + curpath[i] = '\0'; + if (access(curpath, F_OK) != 0) + { + if (mkdir(curpath, 0755) == -1) + { + swoole_php_sys_error(E_WARNING, "mkdir(%s, 0755).", path); + return -1; + } + } + curpath[i] = '/'; + } + } + return 0; +#endif +} + +int php_swoole_task_pack(swEventData *task, zval *data TSRMLS_DC) +{ + smart_str serialized_data = { 0 }; + php_serialize_data_t var_hash; +#if PHP_MAJOR_VERSION >= 7 + zend_string *serialized_string = NULL; +#endif + + task->info.type = SW_EVENT_TASK; + //field fd save task_id + task->info.fd = php_swoole_task_id++; + if (unlikely(php_swoole_task_id >= SW_MAX_INT)) + { + php_swoole_task_id = 0; + } + //field from_id save the worker_id + task->info.from_id = SwooleWG.id; + swTask_type(task) = 0; + + char *task_data_str; + int task_data_len = 0; + //need serialize + if (SW_Z_TYPE_P(data) != IS_STRING) + { + //serialize + swTask_type(task) |= SW_TASK_SERIALIZE; + +#if PHP_MAJOR_VERSION >= 7 + if (SWOOLE_G(fast_serialize)) + { + serialized_string = php_swoole_serialize(data); + task_data_str = serialized_string->val; + task_data_len = serialized_string->len; + } + else +#endif + { + PHP_VAR_SERIALIZE_INIT(var_hash); + sw_php_var_serialize(&serialized_data, data, &var_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(var_hash); + +#if PHP_MAJOR_VERSION < 7 + task_data_str = serialized_data.c; + task_data_len = serialized_data.len; +#else + if (!serialized_data.s) + { + return -1; + } + task_data_str = serialized_data.s->val; + task_data_len = serialized_data.s->len; +#endif + } + } + else + { + task_data_str = Z_STRVAL_P(data); + task_data_len = Z_STRLEN_P(data); + } + + if (task_data_len >= SW_IPC_MAX_SIZE - sizeof(task->info)) + { + if (swTaskWorker_large_pack(task, task_data_str, task_data_len) < 0) + { + swoole_php_fatal_error(E_WARNING, "large task pack failed."); + task->info.fd = SW_ERR; + task->info.len = 0; + } + } + else + { + memcpy(task->data, task_data_str, task_data_len); + task->info.len = task_data_len; + } + +#if PHP_MAJOR_VERSION >= 7 + if (SWOOLE_G(fast_serialize) && serialized_string) + { + zend_string_release(serialized_string); + } + else +#endif + { + smart_str_free(&serialized_data); + } + return task->info.fd; +} + +void php_swoole_get_recv_data(zval *zdata, swEventData *req, char *header, uint32_t header_length) +{ + char *data_ptr = NULL; + int data_len; + +#ifdef SW_USE_RINGBUFFER + swPackage package; + if (req->info.type == SW_EVENT_PACKAGE) + { + memcpy(&package, req->data, sizeof (package)); + + data_ptr = package.data; + data_len = package.length; + } +#else + if (req->info.type == SW_EVENT_PACKAGE_END) + { + swString *worker_buffer = swWorker_get_buffer(SwooleG.serv, req->info.from_id); + data_ptr = worker_buffer->str; + data_len = worker_buffer->length; + } +#endif + else + { + data_ptr = req->data; + data_len = req->info.len; + } + + if (header_length >= data_len) + { + SW_ZVAL_STRING(zdata, "", 1); + } + else + { + SW_ZVAL_STRINGL(zdata, data_ptr + header_length, data_len - header_length, 1); + } + + if (header_length > 0) + { + memcpy(header, data_ptr, header_length); + } + +#ifdef SW_USE_RINGBUFFER + if (req->info.type == SW_EVENT_PACKAGE) + { + swReactorThread *thread = swServer_get_thread(SwooleG.serv, req->info.from_id); + thread->buffer_input->free(thread->buffer_input, data_ptr); + } +#endif +} + +int php_swoole_get_send_data(zval *zdata, char **str TSRMLS_DC) +{ + int length; + + if (SW_Z_TYPE_P(zdata) == IS_OBJECT) + { + if (!instanceof_function(Z_OBJCE_P(zdata), swoole_buffer_class_entry_ptr TSRMLS_CC)) + { + goto convert; + } + swString *str_buffer = swoole_get_object(zdata); + if (!str_buffer->str) + { + swoole_php_fatal_error(E_WARNING, "swoole_buffer object is empty."); + return SW_ERR; + } + length = str_buffer->length - str_buffer->offset; + *str = str_buffer->str + str_buffer->offset; + } + else + { + convert: + convert_to_string(zdata); + length = Z_STRLEN_P(zdata); + *str = Z_STRVAL_P(zdata); + } + + return length; +} + +static sw_inline int php_swoole_check_task_param(swServer *serv, int dst_worker_id TSRMLS_DC) +{ + if (serv->task_worker_num < 1) + { + swoole_php_fatal_error(E_WARNING, "task method can't be executed, please set 'task_worker_num' > 0."); + return SW_ERR; + } + + if (dst_worker_id >= serv->task_worker_num) + { + swoole_php_fatal_error(E_WARNING, "worker_id must be less than serv->task_worker_num."); + return SW_ERR; + } + + if (!swIsWorker()) + { + swoole_php_fatal_error(E_WARNING, "task method can only be used in the worker process."); + return SW_ERR; + } + + return SW_OK; +} + +zval* php_swoole_task_unpack(swEventData *task_result TSRMLS_DC) +{ + zval *result_data, *result_unserialized_data; + char *result_data_str; + int result_data_len = 0; + php_unserialize_data_t var_hash; + swString *large_packet; + + /** + * Large result package + */ + if (swTask_type(task_result) & SW_TASK_TMPFILE) + { + large_packet = swTaskWorker_large_unpack(task_result); + /** + * unpack failed + */ + if (large_packet == NULL) + { + return NULL; + } + result_data_str = large_packet->str; + result_data_len = large_packet->length; + } + else + { + result_data_str = task_result->data; + result_data_len = task_result->info.len; + } + + if (swTask_type(task_result) & SW_TASK_SERIALIZE) + { + SW_ALLOC_INIT_ZVAL(result_unserialized_data); + +#if PHP_MAJOR_VERSION >= 7 + if (SWOOLE_G(fast_serialize)) + { + if (php_swoole_unserialize(result_data_str, result_data_len, result_unserialized_data, NULL, 0)) + { + result_data = result_unserialized_data; + } + else + { + SW_ALLOC_INIT_ZVAL(result_data); + SW_ZVAL_STRINGL(result_data, result_data_str, result_data_len, 1); + } + } + else +#endif + { + PHP_VAR_UNSERIALIZE_INIT(var_hash); + //unserialize success + if (sw_php_var_unserialize(&result_unserialized_data, (const unsigned char ** ) &result_data_str, + (const unsigned char * ) (result_data_str + result_data_len), &var_hash TSRMLS_CC)) + { + result_data = result_unserialized_data; + } + //failed + else + { + SW_ALLOC_INIT_ZVAL(result_data); + SW_ZVAL_STRINGL(result_data, result_data_str, result_data_len, 1); + } + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + } + } + else + { + SW_ALLOC_INIT_ZVAL(result_data); + SW_ZVAL_STRINGL(result_data, result_data_str, result_data_len, 1); + } + return result_data; +} + +#ifdef SW_COROUTINE +static void php_swoole_task_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + swTaskCo *task_co = (swTaskCo *) tnode->data; + int i; + zval *retval = NULL; + zval *result = task_co->result; + + for (i = 0; i < task_co->count; i++) + { + if (!zend_hash_index_exists(Z_ARRVAL_P(result), i)) + { + add_index_bool(result, i, 0); + swHashMap_del_int(task_coroutine_map, task_co->list[i]); + } + } + + php_context *context = &task_co->context; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_free(result); + efree(task_co); +} +#endif + +static zval* php_swoole_server_add_port(swServer *serv, swListenPort *port TSRMLS_DC) +{ + zval *port_object; + SW_ALLOC_INIT_ZVAL(port_object); + object_init_ex(port_object, swoole_server_port_class_entry_ptr); + server_port_list.zobjects[server_port_list.num++] = port_object; + + swoole_server_port_property *property = emalloc(sizeof(swoole_server_port_property)); + bzero(property, sizeof(swoole_server_port_property)); + swoole_set_property(port_object, 0, property); + swoole_set_object(port_object, port); + property->serv = serv; + + zend_update_property_string(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("host"), port->host TSRMLS_CC); + zend_update_property_long(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("port"), port->port TSRMLS_CC); + zend_update_property_long(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("type"), port->type TSRMLS_CC); + zend_update_property_long(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("sock"), port->sock TSRMLS_CC); + +#ifdef HAVE_PCRE + zval *connection_iterator; + SW_MAKE_STD_ZVAL(connection_iterator); + object_init_ex(connection_iterator, swoole_connection_iterator_class_entry_ptr); + zend_update_property(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("connections"), connection_iterator TSRMLS_CC); + + swConnectionIterator *i = emalloc(sizeof(swConnectionIterator)); + bzero(i, sizeof(swConnectionIterator)); + i->port = port; + i->serv = serv; + swoole_set_object(connection_iterator, i); +#endif + + add_next_index_zval(server_port_list.zports, port_object); + + return port_object; +} + +void php_swoole_server_before_start(swServer *serv, zval *zobject TSRMLS_DC) +{ + /** + * create swoole server + */ + if (swServer_create(serv) < 0) + { + swoole_php_fatal_error(E_ERROR, "failed to create the server. Error: %s", sw_error); + return; + } + + swTrace("Create swoole_server host=%s, port=%d, mode=%d, type=%d", serv->listen_list->host, (int) serv->listen_list->port, serv->factory_mode, (int) serv->listen_list->type); + + sw_zval_add_ref(&zobject); + serv->ptr2 = sw_zval_dup(zobject); + +#ifdef SW_COROUTINE + coro_init(TSRMLS_C); + if (serv->send_yield) + { + send_coroutine_map = swHashMap_new(SW_HASHMAP_INIT_BUCKET_N, NULL); + if (send_coroutine_map == NULL) + { + swoole_php_fatal_error(E_ERROR, "failed to create send_coroutine_map. Error: %s", sw_error); + } + if (serv->onClose == NULL) + { + serv->onClose = php_swoole_onClose; + } + } +#endif + + /** + * Master Process ID + */ + zend_update_property_long(swoole_server_class_entry_ptr, zobject, ZEND_STRL("master_pid"), getpid() TSRMLS_CC); + + zval *zsetting = sw_zend_read_property(swoole_server_class_entry_ptr, zobject, ZEND_STRL("setting"), 1 TSRMLS_CC); + if (zsetting == NULL || ZVAL_IS_NULL(zsetting)) + { + SW_ALLOC_INIT_ZVAL(zsetting); + array_init(zsetting); +#ifdef HT_ALLOW_COW_VIOLATION + HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(zsetting)); +#endif + zend_update_property(swoole_server_class_entry_ptr, zobject, ZEND_STRL("setting"), zsetting TSRMLS_CC); + } + + if (!zend_hash_str_exists(Z_ARRVAL_P(zsetting), ZEND_STRL("worker_num"))) + { + add_assoc_long(zsetting, "worker_num", serv->worker_num); + } + if (!zend_hash_str_exists(Z_ARRVAL_P(zsetting), ZEND_STRL("task_worker_num"))) + { + add_assoc_long(zsetting, "task_worker_num", serv->task_worker_num); + } + if (!zend_hash_str_exists(Z_ARRVAL_P(zsetting), ZEND_STRL("buffer_output_size"))) + { + add_assoc_long(zsetting, "buffer_output_size", serv->buffer_output_size); + } + if (!zend_hash_str_exists(Z_ARRVAL_P(zsetting), ZEND_STRL("max_connection"))) + { + add_assoc_long(zsetting, "max_connection", serv->max_connection); + } +#ifdef HAVE_PTRACE + //trace request + if (serv->request_slowlog_file && (serv->trace_event_worker || serv->task_worker_num > 0)) + { + serv->manager_alarm = serv->request_slowlog_timeout; + if (swServer_add_hook(serv, SW_SERVER_HOOK_MANAGER_TIMER, php_swoole_trace_check, 1) < 0) + { + swoole_php_fatal_error(E_ERROR, "Unable to add server hook."); + return; + } + } +#endif + + int i; + zval *retval = NULL; + zval *port_object; + zval *port_setting; + + for (i = 1; i < server_port_list.num; i++) + { + port_object = server_port_list.zobjects[i]; + port_setting = sw_zend_read_property(swoole_server_port_class_entry_ptr, port_object, ZEND_STRL("setting"), 1 TSRMLS_CC); + //use swoole_server->setting + if (port_setting == NULL || ZVAL_IS_NULL(port_setting)) + { + sw_zval_add_ref(&port_setting); + sw_zval_add_ref(&port_object); + sw_zend_call_method_with_1_params(&port_object, swoole_server_port_class_entry_ptr, NULL, "set", &retval, zsetting); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + } + } +} + +void php_swoole_register_callback(swServer *serv) +{ + /* + * optional callback + */ + if (php_sw_server_callbacks[SW_SERVER_CB_onStart] != NULL) + { + serv->onStart = php_swoole_onStart; + } + serv->onShutdown = php_swoole_onShutdown; + /** + * require callback, set the master/manager/worker PID + */ + serv->onWorkerStart = php_swoole_onWorkerStart; + + if (php_sw_server_callbacks[SW_SERVER_CB_onWorkerStop] != NULL) + { + serv->onWorkerStop = php_swoole_onWorkerStop; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onWorkerExit] != NULL) + { + serv->onWorkerExit = php_swoole_onWorkerExit; + } + /** + * UDP Packet + */ + if (php_sw_server_callbacks[SW_SERVER_CB_onPacket] != NULL) + { + serv->onPacket = php_swoole_onPacket; + } + /** + * Task Worker + */ + if (php_sw_server_callbacks[SW_SERVER_CB_onTask] != NULL) + { + serv->onTask = php_swoole_onTask; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onFinish] != NULL) + { + serv->onFinish = php_swoole_onFinish; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onWorkerError] != NULL) + { + serv->onWorkerError = php_swoole_onWorkerError; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onManagerStart] != NULL) + { + serv->onManagerStart = php_swoole_onManagerStart; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onManagerStop] != NULL) + { + serv->onManagerStop = php_swoole_onManagerStop; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onPipeMessage] != NULL) + { + serv->onPipeMessage = php_swoole_onPipeMessage; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onBufferFull] != NULL) + { + serv->onBufferFull = php_swoole_onBufferFull; + } + if (php_sw_server_callbacks[SW_SERVER_CB_onBufferEmpty] != NULL || serv->send_yield) + { + serv->onBufferEmpty = php_swoole_onBufferEmpty; + } +} + +static int php_swoole_task_finish(swServer *serv, zval *data TSRMLS_DC) +{ + int flags = 0; + smart_str serialized_data = {0}; + php_serialize_data_t var_hash; + char *data_str; + int data_len = 0; + int ret; + +#if PHP_MAJOR_VERSION >= 7 + zend_string *serialized_string = NULL; +#endif + + //need serialize + if (SW_Z_TYPE_P(data) != IS_STRING) + { + //serialize + flags |= SW_TASK_SERIALIZE; +#if PHP_MAJOR_VERSION >= 7 + if (SWOOLE_G(fast_serialize)) + { + serialized_string = php_swoole_serialize(data); + data_str = serialized_string->val; + data_len = serialized_string->len; + } + else +#endif + { + PHP_VAR_SERIALIZE_INIT(var_hash); + sw_php_var_serialize(&serialized_data, data, &var_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(var_hash); +#if PHP_MAJOR_VERSION<7 + data_str = serialized_data.c; + data_len = serialized_data.len; +#else + data_str = serialized_data.s->val; + data_len = serialized_data.s->len; +#endif + } + } + else + { + data_str = Z_STRVAL_P(data); + data_len = Z_STRLEN_P(data); + } + + ret = swTaskWorker_finish(serv, data_str, data_len, flags); +#if PHP_MAJOR_VERSION >= 7 + if (SWOOLE_G(fast_serialize) && serialized_string) + { + zend_string_release(serialized_string); + } + else +#endif + { + smart_str_free(&serialized_data); + } + return ret; +} + +static void php_swoole_onPipeMessage(swServer *serv, swEventData *req) +{ + SWOOLE_GET_TSRMLS; + + zval *zserv = (zval *) serv->ptr2; + zval *zworker_id; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, (long) req->info.from_id); + + zval *zdata = php_swoole_task_unpack(req TSRMLS_CC); + if (zdata == NULL) + { + return; + } + + if (SwooleG.enable_coroutine) + { + zval *args[3]; + args[0] = zserv; + args[1] = zworker_id; + args[2] = zdata; + + zend_fcall_info_cache *cache = php_sw_server_caches[SW_SERVER_CB_onPipeMessage]; + int ret = coro_create(cache, args, 3, &retval, NULL, NULL); + if (ret < 0) + { + sw_zval_ptr_dtor(&zworker_id); + sw_zval_free(zdata); + if (ret == CORO_LIMIT) + { + swWarn("Failed to handle onPipeMessage. Coroutine limited"); + } + return; + } + } + else + { + zval **args[3]; + args[0] = &zserv; + args[1] = &zworker_id; + args[2] = &zdata; + + swTrace("PipeMessage: fd=%d|len=%d|from_id=%d|data=%s\n", req->info.fd, req->info.len, req->info.from_id, req->data); + + if (sw_call_user_function_fast(php_sw_server_callbacks[SW_SERVER_CB_onPipeMessage], php_sw_server_caches[SW_SERVER_CB_onPipeMessage], &retval, 3, args TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onPipeMessage handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + + sw_zval_ptr_dtor(&zworker_id); + sw_zval_free(zdata); + + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +int php_swoole_onReceive(swServer *serv, swEventData *req) +{ + swFactory *factory = &serv->factory; + zval *zserv = (zval *) serv->ptr2; + + zval *zfd; + zval *zfrom_id; + zval *zdata; + zval *retval = NULL; + + SWOOLE_GET_TSRMLS; + + php_swoole_udp_t udp_info; + swDgramPacket *packet; + + SW_MAKE_STD_ZVAL(zfd); + SW_MAKE_STD_ZVAL(zfrom_id); + SW_MAKE_STD_ZVAL(zdata); + + //dgram + if (swEventData_is_dgram(req->info.type)) + { + swoole_php_error(E_DEPRECATED, "The udp onReceive callback is deprecated, use onPacket instead."); + + swString *buffer = swWorker_get_buffer(serv, req->info.from_id); + packet = (swDgramPacket*) buffer->str; + + //udp ipv4 + if (req->info.type == SW_EVENT_UDP) + { + udp_info.from_fd = req->info.from_fd; + udp_info.port = packet->port; + memcpy(&udp_server_socket, &udp_info, sizeof(udp_server_socket)); + factory->last_from_id = udp_server_socket; + swTrace("SendTo: from_id=%d|from_fd=%d", (uint16_t) req->info.from_id, req->info.from_fd); + SW_ZVAL_STRINGL(zdata, packet->data, packet->length, 1); + ZVAL_LONG(zfrom_id, (long ) udp_server_socket); + ZVAL_LONG(zfd, (long ) packet->addr.v4.s_addr); + } + //udp ipv6 + else if (req->info.type == SW_EVENT_UDP6) + { + udp_info.from_fd = req->info.from_fd; + udp_info.port = packet->port; + memcpy(&dgram_server_socket, &udp_info, sizeof(udp_server_socket)); + factory->last_from_id = dgram_server_socket; + + swTrace("SendTo: from_id=%d|from_fd=%d", (uint16_t) req->info.from_id, req->info.from_fd); + + ZVAL_LONG(zfrom_id, (long ) dgram_server_socket); + char tmp[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &packet->addr.v6, tmp, sizeof(tmp)); + SW_ZVAL_STRING(zfd, tmp, 1); + SW_ZVAL_STRINGL(zdata, packet->data, packet->length, 1); + } + //unix dgram + else + { + SW_ZVAL_STRINGL(zfd, packet->data, packet->addr.un.path_length, 1); + SW_ZVAL_STRINGL(zdata, packet->data + packet->addr.un.path_length, packet->length - packet->addr.un.path_length, 1); + ZVAL_LONG(zfrom_id, (long ) req->info.from_fd); + dgram_server_socket = req->info.from_fd; + } + } + //stream + else + { + ZVAL_LONG(zfrom_id, (long ) req->info.from_id); + ZVAL_LONG(zfd, (long ) req->info.fd); + php_swoole_get_recv_data(zdata, req, NULL, 0); + } + + if (SwooleG.enable_coroutine) + { + zval *args[4]; + args[0] = zserv; + args[1] = zfd; + args[2] = zfrom_id; + args[3] = zdata; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onReceive); + int ret = coro_create(cache, args, 4, &retval, NULL, NULL); + if (ret < 0) + { + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + sw_zval_ptr_dtor(&zdata); + if (ret == CORO_LIMIT) + { + serv->factory.end(&SwooleG.serv->factory, req->info.fd); + } + return SW_OK; + } + } + else + { + zval **args[4]; + zval *callback = php_swoole_server_get_callback(serv, req->info.from_fd, SW_SERVER_CB_onReceive); + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + swoole_php_fatal_error(E_WARNING, "onReceive callback is null."); + return SW_OK; + } + + args[0] = &zserv; + args[1] = &zfd; + args[2] = &zfrom_id; + args[3] = &zdata; + + zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onReceive); + if (sw_call_user_function_fast(callback, fci_cache, &retval, 4, args TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onReceive handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + sw_zval_ptr_dtor(&zdata); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; +} + +int php_swoole_onPacket(swServer *serv, swEventData *req) +{ + zval *zserv = (zval *) serv->ptr2; + zval *zdata; + zval *zaddr; + zval *retval = NULL; + swDgramPacket *packet; + + SWOOLE_GET_TSRMLS; + + SW_MAKE_STD_ZVAL(zdata); + SW_MAKE_STD_ZVAL(zaddr); + array_init(zaddr); + + swString *buffer = swWorker_get_buffer(serv, req->info.from_id); + packet = (swDgramPacket*) buffer->str; + + add_assoc_long(zaddr, "server_socket", req->info.from_fd); + swConnection *from_sock = swServer_connection_get(serv, req->info.from_fd); + if (from_sock) + { + add_assoc_long(zaddr, "server_port", swConnection_get_port(from_sock)); + } + + char address[INET6_ADDRSTRLEN]; + + //udp ipv4 + if (req->info.type == SW_EVENT_UDP) + { + inet_ntop(AF_INET, &packet->addr.v4, address, sizeof(address)); + sw_add_assoc_string(zaddr, "address", address, 1); + add_assoc_long(zaddr, "port", packet->port); + SW_ZVAL_STRINGL(zdata, packet->data, packet->length, 1); + } + //udp ipv6 + else if (req->info.type == SW_EVENT_UDP6) + { + inet_ntop(AF_INET6, &packet->addr.v6, address, sizeof(address)); + sw_add_assoc_string(zaddr, "address", address, 1); + add_assoc_long(zaddr, "port", packet->port); + SW_ZVAL_STRINGL(zdata, packet->data, packet->length, 1); + } + //unix dgram + else if (req->info.type == SW_EVENT_UNIX_DGRAM) + { + sw_add_assoc_stringl(zaddr, "address", packet->data, packet->addr.un.path_length, 1); + SW_ZVAL_STRINGL(zdata, packet->data + packet->addr.un.path_length, packet->length - packet->addr.un.path_length, 1); + dgram_server_socket = req->info.from_fd; + } + + if (SwooleG.enable_coroutine) + { + zval *args[3]; + args[0] = zserv; + args[1] = zdata; + args[2] = zaddr; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onPacket); + int ret = coro_create(cache, args, 3, &retval, NULL, NULL); + if (ret < 0) + { + sw_zval_ptr_dtor(&zaddr); + sw_zval_ptr_dtor(&zdata); + return SW_OK; + } + } + else + { + zval **args[3]; + args[0] = &zserv; + args[1] = &zdata; + args[2] = &zaddr; + + zval *callback = php_swoole_server_get_callback(serv, req->info.from_fd, SW_SERVER_CB_onPacket); + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + swoole_php_fatal_error(E_WARNING, "onPacket callback is null."); + return SW_OK; + } + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 3, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onPacket handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zaddr); + sw_zval_ptr_dtor(&zdata); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + return SW_OK; +} + +static int php_swoole_onTask(swServer *serv, swEventData *req) +{ + zval *zserv = (zval *) serv->ptr2; + zval **args[4]; + + zval *zfd; + zval *zfrom_id; + + sw_atomic_fetch_sub(&serv->stats->tasking_num, 1); + + zval *retval = NULL; + + SWOOLE_GET_TSRMLS; + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, (long) req->info.fd); + + SW_MAKE_STD_ZVAL(zfrom_id); + ZVAL_LONG(zfrom_id, (long) req->info.from_id); + + zval *zdata = php_swoole_task_unpack(req TSRMLS_CC); + if (zdata == NULL) + { + return SW_ERR; + } + + args[0] = &zserv; + args[1] = &zfd; + args[2] = &zfrom_id; + args[3] = &zdata; + + zend_fcall_info_cache *fci_cache = php_sw_server_caches[SW_SERVER_CB_onTask]; + if (sw_call_user_function_fast(php_sw_server_callbacks[SW_SERVER_CB_onTask], fci_cache, &retval, 4, args TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onTask handler error."); + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + sw_zval_free(zdata); + + if (retval) + { + if (SW_Z_TYPE_P(retval) != IS_NULL) + { + php_swoole_task_finish(serv, retval TSRMLS_CC); + } + sw_zval_ptr_dtor(&retval); + } + + return SW_OK; +} + +static int php_swoole_onFinish(swServer *serv, swEventData *req) +{ + zval *zserv = (zval *) serv->ptr2; + zval **args[3]; + + zval *ztask_id; + zval *zdata; + zval *retval = NULL; + + SWOOLE_GET_TSRMLS; + + SW_MAKE_STD_ZVAL(ztask_id); + ZVAL_LONG(ztask_id, (long) req->info.fd); + + zdata = php_swoole_task_unpack(req TSRMLS_CC); + if (zdata == NULL) + { + return SW_ERR; + } + +#ifdef SW_COROUTINE + if (swTask_type(req) & SW_TASK_COROUTINE) + { + int task_id = req->info.fd; + swTaskCo *task_co = swHashMap_find_int(task_coroutine_map, task_id); + if (task_co == NULL) + { + swoole_php_fatal_error(E_WARNING, "task[%d] has expired.", task_id); + fail: sw_zval_free(zdata); + return SW_OK; + } + int i, task_index = -1; + zval *result = task_co->result; + for (i = 0; i < task_co->count; i++) + { + if (task_co->list[i] == task_id) + { + task_index = i; + break; + } + } + if (task_index < 0) + { + swoole_php_fatal_error(E_WARNING, "task[%d] is invalid.", task_id); + goto fail; + } + add_index_zval(result, task_index, zdata); +#if PHP_MAJOR_VERSION >= 7 + efree(zdata); +#endif + swHashMap_del_int(task_coroutine_map, task_id); + + if (php_swoole_array_length(result) == task_co->count) + { + if (task_co->timer) + { + swTimer_del(&SwooleG.timer, task_co->timer); + task_co->timer = NULL; + } + php_context *context = &task_co->context; + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_free(result); + efree(task_co); + } + return SW_OK; + } +#endif + + args[0] = &zserv; + args[1] = &ztask_id; + args[2] = &zdata; + + zval *callback = NULL; + if (swTask_type(req) & SW_TASK_CALLBACK) + { + callback = swHashMap_find_int(task_callbacks, req->info.fd); + if (callback == NULL) + { + swTask_type(req) = swTask_type(req) & (~SW_TASK_CALLBACK); + } + } + if (callback == NULL) + { + callback = php_sw_server_callbacks[SW_SERVER_CB_onFinish]; + } + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 3, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onFinish handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&ztask_id); + sw_zval_free(zdata); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + if (swTask_type(req) & SW_TASK_CALLBACK) + { + swHashMap_del_int(task_callbacks, req->info.fd); + sw_zval_free(callback); + } + return SW_OK; +} + +static void php_swoole_onStart(swServer *serv) +{ + SwooleG.lock.lock(&SwooleG.lock); + SWOOLE_GET_TSRMLS; + + zval *zserv = (zval *) serv->ptr2; + zval **args[1]; + zval *retval = NULL; + + pid_t manager_pid = serv->factory_mode == SW_MODE_PROCESS ? serv->gs->manager_pid : 0; + + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("master_pid"), serv->gs->master_pid TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("manager_pid"), manager_pid TSRMLS_CC); + + args[0] = &zserv; + + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onStart], &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onStart handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + SwooleG.lock.unlock(&SwooleG.lock); +} + +static void php_swoole_onManagerStart(swServer *serv) +{ + SWOOLE_GET_TSRMLS; + + zval *zserv = (zval *) serv->ptr2; + zval **args[1]; + zval *retval = NULL; + + pid_t manager_pid = serv->factory_mode == SW_MODE_PROCESS ? serv->gs->manager_pid : 0; + + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("master_pid"), serv->gs->master_pid TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("manager_pid"), manager_pid TSRMLS_CC); + + args[0] = &zserv; + + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onManagerStart], &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onManagerStart handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onManagerStop(swServer *serv) +{ + SWOOLE_GET_TSRMLS; + zval *zserv = (zval *) serv->ptr2; + zval **args[1]; + zval *retval = NULL; + + args[0] = &zserv; + + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onManagerStop], &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onManagerStop handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onShutdown(swServer *serv) +{ + SwooleG.lock.lock(&SwooleG.lock); + zval *zserv = (zval *) serv->ptr2; + zval **args[1]; + zval *retval = NULL; + + args[0] = &zserv; + + SWOOLE_GET_TSRMLS; + + if (php_sw_server_callbacks[SW_SERVER_CB_onShutdown] != NULL) + { + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onShutdown], &retval, 1, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onShutdown handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + } + SwooleG.lock.unlock(&SwooleG.lock); +} + +static void php_swoole_onWorkerStart_coroutine(zval *zserv, zval *zworker_id) +{ + zval *retval = NULL; + zval *args[2]; + args[0] = zserv; + args[1] = zworker_id; + + zend_fcall_info_cache *cache = php_sw_server_caches[SW_SERVER_CB_onWorkerStart]; + int ret = coro_create(cache, args, 2, &retval, NULL, NULL); + if (ret < 0) + { + sw_zval_ptr_dtor(&zworker_id); + if (ret == CORO_LIMIT) + { + swWarn("Failed to handle onWorkerStart. Coroutine limited."); + } + return; + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onWorkerStart_callback(zval *zserv, zval *zworker_id) +{ + zval *retval = NULL; + zval **args[2]; + args[0] = &zserv; + args[1] = &zworker_id; + + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onWorkerStart], &retval, + 2, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStart handler error."); + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onWorkerStart(swServer *serv, int worker_id) +{ + zval *zserv = (zval *) serv->ptr2; + zval *zworker_id; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + /** + * Master Process ID + */ + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("master_pid"), serv->gs->master_pid TSRMLS_CC); + + /** + * Manager Process ID + */ + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("manager_pid"), serv->gs->manager_pid TSRMLS_CC); + + /** + * Worker ID + */ + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("worker_id"), worker_id TSRMLS_CC); + + /** + * Is a task worker? + */ + if (worker_id >= serv->worker_num) + { + zend_update_property_bool(swoole_server_class_entry_ptr, zserv, ZEND_STRL("taskworker"), 1 TSRMLS_CC); + } + else + { + zend_update_property_bool(swoole_server_class_entry_ptr, zserv, ZEND_STRL("taskworker"), 0 TSRMLS_CC); + } + + /** + * Worker Process ID + */ + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("worker_pid"), getpid() TSRMLS_CC); + + /** + * Have not set the event callback + */ + if (php_sw_server_callbacks[SW_SERVER_CB_onWorkerStart] == NULL) + { + return; + } + + if (SwooleG.enable_coroutine && worker_id < serv->worker_num) + { + php_swoole_onWorkerStart_coroutine(zserv, zworker_id); + } + else + { + php_swoole_onWorkerStart_callback(zserv, zworker_id); + } +} + +static void php_swoole_onWorkerStop(swServer *serv, int worker_id) +{ + if (SwooleWG.shutdown) + { + return; + } + SwooleWG.shutdown = 1; + + zval *zobject = (zval *) serv->ptr2; + zval *zworker_id; + zval **args[2]; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + SWOOLE_GET_TSRMLS; + + args[0] = &zobject; + args[1] = &zworker_id; + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onWorkerStop], &retval, 2, args, 0, + NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStop handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zworker_id); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onWorkerExit(swServer *serv, int worker_id) +{ + zval *zobject = (zval *) serv->ptr2; + zval *zworker_id; + zval **args[2]; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + SWOOLE_GET_TSRMLS; + + args[0] = &zobject; + args[1] = &zworker_id; + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onWorkerExit], &retval, 2, args, 0, + NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerStop handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zworker_id); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +static void php_swoole_onUserWorkerStart(swServer *serv, swWorker *worker) +{ + SWOOLE_GET_TSRMLS; + + zval *object = worker->ptr; + zend_update_property_long(swoole_process_class_entry_ptr, object, ZEND_STRL("id"), SwooleWG.id TSRMLS_CC); + + zval *zserv = (zval *) serv->ptr2; + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("master_pid"), serv->gs->master_pid TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, zserv, ZEND_STRL("manager_pid"), serv->gs->manager_pid TSRMLS_CC); + + php_swoole_process_start(worker, object TSRMLS_CC); +} + +static void php_swoole_onWorkerError(swServer *serv, int worker_id, pid_t worker_pid, int exit_code, int signo) +{ + zval *zobject = (zval *) serv->ptr2; + zval *zworker_id, *zworker_pid, *zexit_code, *zsigno; + zval **args[5]; + zval *retval = NULL; + + SW_MAKE_STD_ZVAL(zworker_id); + ZVAL_LONG(zworker_id, worker_id); + + SW_MAKE_STD_ZVAL(zworker_pid); + ZVAL_LONG(zworker_pid, worker_pid); + + SW_MAKE_STD_ZVAL(zexit_code); + ZVAL_LONG(zexit_code, exit_code); + + SW_MAKE_STD_ZVAL(zsigno); + ZVAL_LONG(zsigno, signo); + + SWOOLE_GET_TSRMLS; + + args[0] = &zobject; + args[1] = &zworker_id; + args[2] = &zworker_pid; + args[3] = &zexit_code; + args[4] = &zsigno; + + if (sw_call_user_function_ex(EG(function_table), NULL, php_sw_server_callbacks[SW_SERVER_CB_onWorkerError], &retval, 5, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "onWorkerError handler error."); + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + + sw_zval_ptr_dtor(&zworker_id); + sw_zval_ptr_dtor(&zworker_pid); + sw_zval_ptr_dtor(&zexit_code); + sw_zval_ptr_dtor(&zsigno); + + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +#ifdef SW_COROUTINE +static void php_swoole_onConnect_finish(void *param) +{ + swServer *serv = SwooleG.serv; + swTrace("onConnect finish and send confirm"); + swServer_tcp_feedback(serv, (uint32_t) (long) param, SW_EVENT_CONFIRM); +} +#endif + +void php_swoole_onConnect(swServer *serv, swDataHead *info) +{ + zval *zserv = (zval *) serv->ptr2; + zval *zfd; + zval *zfrom_id; + zval *retval = NULL; + + SWOOLE_GET_TSRMLS; + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, info->fd); + + SW_MAKE_STD_ZVAL(zfrom_id); + ZVAL_LONG(zfrom_id, info->from_id); + + if (SwooleG.enable_coroutine) + { + zval *args[3]; + args[0] = zserv; + args[1] = zfd; + args[2] = zfrom_id; + + int ret; + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, info->from_fd, SW_SERVER_CB_onConnect); + if (cache == NULL) { + return; + } + if (serv->enable_delay_receive) + { + ret = coro_create(cache, args, 3, &retval, php_swoole_onConnect_finish, (void*) (long) info->fd); + } + else + { + ret = coro_create(cache, args, 3, &retval, NULL, NULL); + } + + if (ret < 0) + { + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + return; + } + } + else + { + zval **args[3]; + args[0] = &zserv; + args[1] = &zfd; + args[2] = &zfrom_id; + + zval *callback = php_swoole_server_get_callback(serv, info->from_fd, SW_SERVER_CB_onConnect); + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + return; + } + + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 3, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onConnect handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +void php_swoole_onClose(swServer *serv, swDataHead *info) +{ + zval *zserv = (zval *) serv->ptr2; + zval *zfd; + zval *zfrom_id; + zval *retval = NULL; + + SWOOLE_GET_TSRMLS; + + if (SwooleG.enable_coroutine && serv->send_yield) + { + swLinkedList *coros_list = swHashMap_find_int(send_coroutine_map, info->fd); + if (coros_list) + { + php_context *context = swLinkedList_shift(coros_list); + if (context == NULL) + { + swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); + } + else + { + SwooleG.error = ECONNRESET; + zval_ptr_dtor(&context->coro_params); + ZVAL_NULL(&context->coro_params); + //resume coroutine + php_swoole_server_send_resume(serv, context, info->fd); + //free memory + swLinkedList_free(coros_list); + swHashMap_del_int(send_coroutine_map, info->fd); + } + } + } + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, info->fd); + + SW_MAKE_STD_ZVAL(zfrom_id); + ZVAL_LONG(zfrom_id, info->from_id); + + if (SwooleG.enable_coroutine) + { + zval *args[3]; + args[0] = zserv; + args[1] = zfd; + args[2] = zfrom_id; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, info->from_fd, SW_SERVER_CB_onClose); + if (cache == NULL) + { + return; + } + + int ret = coro_create(cache, args, 3, &retval, NULL, NULL); + sw_zval_ptr_dtor(&zfd); + sw_zval_ptr_dtor(&zfrom_id); + + if (ret < 0) + { + return; + } + } + else + { + zval **args[3]; + args[0] = &zserv; + args[1] = &zfd; + args[2] = &zfrom_id; + + zval *callback = php_swoole_server_get_callback(serv, info->from_fd, SW_SERVER_CB_onClose); + if (callback == NULL || ZVAL_IS_NULL(callback)) + { + return; + } + if (sw_call_user_function_ex(EG(function_table), NULL, callback, &retval, 3, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onClose handler error."); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +void php_swoole_onBufferFull(swServer *serv, swDataHead *info) +{ + zval *zserv = (zval *) serv->ptr2; + zval *zfd; + zval **args[2]; + zval *retval = NULL; + + zval *callback = php_swoole_server_get_callback(serv, info->from_fd, SW_SERVER_CB_onBufferFull); + if (!callback) + { + return; + } + + SWOOLE_GET_TSRMLS; + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, info->fd); + + args[0] = &zserv; + args[1] = &zfd; + + zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, info->from_fd, SW_SERVER_CB_onBufferFull); + if (sw_call_user_function_fast(callback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onBufferFull handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zfd); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +#ifdef SW_COROUTINE +static void php_swoole_onSendTimeout(swTimer *timer, swTimer_node *tnode) +{ + php_context *context = (php_context *) tnode->data; + zval *zdata = &context->coro_params; + zval *result; + zval *retval = NULL; + SW_MAKE_STD_ZVAL(result); + + SwooleG.error = EAGAIN; + ZVAL_BOOL(result, 0); + + context->private_data = NULL; + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + sw_zval_ptr_dtor(&zdata); + efree(context); +} + +static void php_swoole_server_send_resume(swServer *serv, php_context *context, int fd) +{ + char *data; + zval *zdata = &context->coro_params; + zval *result; + zval *retval = NULL; + SW_MAKE_STD_ZVAL(result); + + if (context->private_data) + { + swTimer_del(&SwooleG.timer, (swTimer_node *) context->private_data); + context->private_data = NULL; + } + + if (ZVAL_IS_NULL(zdata)) + { + _fail: ZVAL_BOOL(result, 0); + } + else + { + int length = php_swoole_get_send_data(zdata, &data TSRMLS_CC); + if (length <= 0) + { + goto _fail; + } + ZVAL_BOOL(result, swServer_tcp_send(serv, fd, data, length) == SW_OK); + } + + int ret = coro_resume(context, result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&result); + sw_zval_ptr_dtor(&zdata); + efree(context); +} + +void php_swoole_server_send_yield(swServer *serv, int fd, zval *zdata, zval *return_value) +{ + swLinkedList *coros_list = swHashMap_find_int(send_coroutine_map, fd); + if (coros_list == NULL) + { + coros_list = swLinkedList_new(2, NULL); + if (coros_list == NULL) + { + RETURN_FALSE; + } + if (swHashMap_add_int(send_coroutine_map, fd, (void*) coros_list) == SW_ERR) + { + swLinkedList_free(coros_list); + RETURN_FALSE; + } + } + + php_context *context = emalloc(sizeof(php_context)); + if (swLinkedList_append(coros_list, (void *) context) == SW_ERR) + { + efree(context); + RETURN_FALSE; + } + if (serv->send_timeout > 0) + { + php_swoole_check_timer((int) (serv->send_timeout * 1000)); + context->private_data = SwooleG.timer.add(&SwooleG.timer, (int) (serv->send_timeout * 1000), 0, context, php_swoole_onSendTimeout); + } + else + { + context->private_data = NULL; + } + context->coro_params = *zdata; + coro_save(context); + coro_yield(); +} +#endif + +void php_swoole_onBufferEmpty(swServer *serv, swDataHead *info) +{ + SWOOLE_GET_TSRMLS; + + zval *zserv = (zval *) serv->ptr2; + zval *zfd; + zval **args[2]; + zval *retval = NULL; + zval *callback; + +#ifdef SW_COROUTINE + if (serv->send_yield == 0) + { + goto _callback; + } + + swLinkedList *coros_list = swHashMap_find_int(send_coroutine_map, info->fd); + if (coros_list) + { + php_context *context = swLinkedList_shift(coros_list); + if (context == NULL) + { + swoole_php_fatal_error(E_WARNING, "Nothing can coroResume."); + goto _callback; + } + //resume coroutine + php_swoole_server_send_resume(serv, context, info->fd); + //free memory + if (coros_list->num == 0) + { + swLinkedList_free(coros_list); + swHashMap_del_int(send_coroutine_map, info->fd); + } + } +#endif + +#ifdef SW_COROUTINE + _callback: +#endif + callback = php_swoole_server_get_callback(serv, info->from_fd, SW_SERVER_CB_onBufferEmpty); + if (!callback) + { + return; + } + + SW_MAKE_STD_ZVAL(zfd); + ZVAL_LONG(zfd, info->fd); + + args[0] = &zserv; + args[1] = &zfd; + + zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, info->from_fd, SW_SERVER_CB_onBufferEmpty); + if (sw_call_user_function_fast(callback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onBufferEmpty handler error."); + } + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + sw_zval_ptr_dtor(&zfd); + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } +} + +PHP_METHOD(swoole_server, __construct) +{ + zend_size_t host_len = 0; + char *serv_host; + long sock_type = SW_SOCK_TCP; + long serv_port = 0; + long serv_mode = SW_MODE_PROCESS; + + //only cli env + if (strcasecmp("cli", sapi_module.name) != 0) + { + swoole_php_fatal_error(E_ERROR, "swoole_server only can be used in PHP CLI mode."); + RETURN_FALSE; + } + + if (SwooleG.main_reactor != NULL) + { + swoole_php_fatal_error(E_ERROR, "eventLoop has already been created. unable to create swoole_server."); + RETURN_FALSE; + } + + if (SwooleG.serv != NULL) + { + swoole_php_fatal_error(E_WARNING, "server is running. unable to create swoole_server."); + RETURN_FALSE; + } + + swServer *serv = sw_malloc(sizeof (swServer)); + swServer_init(serv); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lll", &serv_host, &host_len, &serv_port, &serv_mode, &sock_type) == FAILURE) + { + swoole_php_fatal_error(E_ERROR, "invalid swoole_server parameters."); + return; + } + +#ifdef __CYGWIN__ + serv_mode = SW_MODE_SINGLE; +#elif !defined(SW_USE_THREAD) + if (serv_mode == SW_MODE_THREAD || serv_mode == SW_MODE_BASE) + { + serv_mode = SW_MODE_SINGLE; + swoole_php_fatal_error(E_WARNING, "can't use multi-threading in PHP. reset server mode to be SWOOLE_MODE_BASE"); + } +#endif + serv->factory_mode = serv_mode; + + if (serv->factory_mode == SW_MODE_SINGLE) + { + serv->worker_num = 1; + serv->max_request = 0; + } + + bzero(php_sw_server_callbacks, sizeof (zval*) * PHP_SERVER_CALLBACK_NUM); + + if (serv_port == 0 && strcasecmp(serv_host, "SYSTEMD") == 0) + { + if (swserver_add_systemd_socket(serv) <= 0) + { + swoole_php_fatal_error(E_ERROR, "failed to add systemd socket."); + return; + } + } + else + { + swListenPort *port = swServer_add_port(serv, sock_type, serv_host, serv_port); + if (!port) + { + zend_throw_exception_ex(swoole_exception_class_entry_ptr, errno TSRMLS_CC, "failed to listen server port[%s:%d]. Error: %s[%d].", + serv_host, serv_port, strerror(errno), errno); + return; + } + } + + zval *server_object = getThis(); + +#ifdef HAVE_PCRE + zval *connection_iterator_object; + SW_MAKE_STD_ZVAL(connection_iterator_object); + object_init_ex(connection_iterator_object, swoole_connection_iterator_class_entry_ptr); + zend_update_property(swoole_server_class_entry_ptr, server_object, ZEND_STRL("connections"), connection_iterator_object TSRMLS_CC); + + swConnectionIterator *i = emalloc(sizeof(swConnectionIterator)); + bzero(i, sizeof(swConnectionIterator)); + i->serv = serv; + swoole_set_object(connection_iterator_object, i); +#endif + + zend_update_property_stringl(swoole_server_class_entry_ptr, server_object, ZEND_STRL("host"), serv_host, host_len TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("port"), (long) serv->listen_list->port TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("mode"), serv->factory_mode TSRMLS_CC); + zend_update_property_long(swoole_server_class_entry_ptr, server_object, ZEND_STRL("type"), sock_type TSRMLS_CC); + swoole_set_object(server_object, serv); + + zval *ports; + SW_ALLOC_INIT_ZVAL(ports); + array_init(ports); + server_port_list.zports = ports; + +#ifdef HT_ALLOW_COW_VIOLATION + HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(ports)); +#endif + + swListenPort *ls; + LL_FOREACH(serv->listen_list, ls) + { + php_swoole_server_add_port(serv, ls TSRMLS_CC); + } + + zend_update_property(swoole_server_class_entry_ptr, server_object, ZEND_STRL("ports"), ports TSRMLS_CC); +} + +PHP_METHOD(swoole_server, __destruct) +{ +#if SW_DEBUG_SERVER_DESTRUCT + int i; + for (i = 0; i < PHP_SERVER_CALLBACK_NUM; i++) + { +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + if (php_sw_server_caches[i]) + { + efree(php_sw_server_caches[i]); + php_sw_server_caches[i] = NULL; + } +#endif + } + + zval *port_object; + for (i = 0; i < server_port_list.num; i++) + { + port_object = server_port_list.zobjects[i]; + efree(port_object); + server_port_list.zobjects[i] = NULL; + } + + efree(server_port_list.zports); + server_port_list.zports = NULL; +#endif +} + +PHP_METHOD(swoole_server, set) +{ + zval *zset = NULL; + zval *zobject = getThis(); + HashTable *vht; + + zval *v; + + swServer *serv = swoole_get_object(zobject); + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "server is running. unable to execute function 'swoole_server_set'."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + + php_swoole_array_separate(zset); + vht = Z_ARRVAL_P(zset); + + //chroot + if (php_swoole_array_get_value(vht, "chroot", v)) + { + convert_to_string(v); + if (SwooleG.chroot) + { + sw_free(SwooleG.chroot); + } + SwooleG.chroot = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //user + if (php_swoole_array_get_value(vht, "user", v)) + { + convert_to_string(v); + if (SwooleG.user) + { + sw_free(SwooleG.user); + } + SwooleG.user = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //group + if (php_swoole_array_get_value(vht, "group", v)) + { + convert_to_string(v); + if (SwooleG.group) + { + sw_free(SwooleG.group); + } + SwooleG.group = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //daemonize + if (php_swoole_array_get_value(vht, "daemonize", v)) + { + convert_to_boolean(v); + serv->daemonize = Z_BVAL_P(v); + } +#ifdef SW_DEBUG + //debug + if (php_swoole_array_get_value(vht, "debug_mode", v)) + { + convert_to_boolean(v); + if (Z_BVAL_P(v)) + { + SwooleG.log_level = 0; + } + } +#endif + if (php_swoole_array_get_value(vht, "trace_flags", v)) + { + convert_to_long(v); + SwooleG.trace_flags = (int32_t) Z_LVAL_P(v); + } + //pid file + if (php_swoole_array_get_value(vht, "pid_file", v)) + { + convert_to_string(v); + if (serv->pid_file) + { + sw_free(serv->pid_file); + } + serv->pid_file = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //reactor thread num + if (php_swoole_array_get_value(vht, "reactor_num", v)) + { + convert_to_long(v); + serv->reactor_num = (int) Z_LVAL_P(v); + if (serv->reactor_num <= 0) + { + serv->reactor_num = SwooleG.cpu_num; + } + } + //worker_num + if (php_swoole_array_get_value(vht, "worker_num", v)) + { + convert_to_long(v); + serv->worker_num = (int) Z_LVAL_P(v); + if (serv->worker_num <= 0) + { + serv->worker_num = SwooleG.cpu_num; + } + } + //max wait time + if (php_swoole_array_get_value(vht, "max_wait_time", v)) + { + convert_to_long(v); + serv->max_wait_time = (uint32_t) Z_LVAL_P(v); + } +#ifdef SW_COROUTINE + if (php_swoole_array_get_value(vht, "enable_coroutine", v)) + { + convert_to_double(v); + SwooleG.enable_coroutine = Z_DVAL_P(v); + } + if (php_swoole_array_get_value(vht, "max_coro_num", v) || php_swoole_array_get_value(vht, "max_coroutine", v)) + { + convert_to_long(v); + COROG.max_coro_num = (int) Z_LVAL_P(v); + if (COROG.max_coro_num <= 0) + { + COROG.max_coro_num = SW_DEFAULT_MAX_CORO_NUM; + } + else if (COROG.max_coro_num >= SW_MAX_CORO_NUM_LIMIT) + { + COROG.max_coro_num = SW_MAX_CORO_NUM_LIMIT; + } + } + if (php_swoole_array_get_value(vht, "send_yield", v)) + { + convert_to_boolean(v); + serv->send_yield = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "send_timeout", v)) + { + convert_to_double(v); + serv->send_timeout = Z_DVAL_P(v); + } +#endif + //dispatch_mode + if (php_swoole_array_get_value(vht, "dispatch_mode", v)) + { + convert_to_long(v); + serv->dispatch_mode = (int) Z_LVAL_P(v); + } + //dispatch function + if (php_swoole_array_get_value(vht, "dispatch_func", v)) + { + swServer_dispatch_function func = NULL; + while(1) + { + if (Z_TYPE_P(v) == IS_STRING) + { + func = swoole_get_function(Z_STRVAL_P(v), Z_STRLEN_P(v)); + break; + } + + char *func_name = NULL; + if (!sw_zend_is_callable(v, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + sw_zval_add_ref(&v); + serv->private_data_3 = sw_zval_dup(v); + func = php_swoole_dispatch_func; + break; + } + if (func) + { + serv->dispatch_mode = SW_DISPATCH_USERFUNC; + serv->dispatch_func = func; + } + } + //log_file + if (php_swoole_array_get_value(vht, "log_file", v)) + { + convert_to_string(v); + if (SwooleG.log_file) + { + sw_free(SwooleG.log_file); + } + SwooleG.log_file = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //log_level + if (php_swoole_array_get_value(vht, "log_level", v)) + { + convert_to_long(v); + SwooleG.log_level = (int) Z_LVAL_P(v); + } + /** + * for dispatch_mode = 1/3 + */ + if (php_swoole_array_get_value(vht, "discard_timeout_request", v)) + { + convert_to_boolean(v); + serv->discard_timeout_request = Z_BVAL_P(v); + } + //onConnect/onClose event + if (php_swoole_array_get_value(vht, "enable_unsafe_event", v)) + { + convert_to_boolean(v); + serv->enable_unsafe_event = Z_BVAL_P(v); + } + //delay receive + if (php_swoole_array_get_value(vht, "enable_delay_receive", v)) + { + convert_to_boolean(v); + serv->enable_delay_receive = Z_BVAL_P(v); + } + //task_worker_num + if (php_swoole_array_get_value(vht, "task_worker_num", v)) + { + convert_to_long(v); + serv->task_worker_num = (int) Z_LVAL_P(v); + if (task_callbacks == NULL) + { + task_callbacks = swHashMap_new(1024, NULL); + } +#ifdef SW_COROUTINE + if (task_coroutine_map == NULL) + { + task_coroutine_map = swHashMap_new(1024, NULL); + } +#endif + } + //slowlog + if (php_swoole_array_get_value(vht, "trace_event_worker", v)) + { + convert_to_boolean(v); + serv->trace_event_worker = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "request_slowlog_timeout", v)) + { + convert_to_long(v); + serv->request_slowlog_timeout = (uint8_t) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "request_slowlog_file", v)) + { + convert_to_string(v); + serv->request_slowlog_file = fopen(Z_STRVAL_P(v), "a+"); + if (serv->request_slowlog_file == NULL) + { + swoole_php_fatal_error(E_ERROR, "Unable to open request_slowlog_file[%s].", Z_STRVAL_P(v)); + return; + } + if (serv->request_slowlog_timeout == 0) + { + serv->request_slowlog_timeout = 1; + } + } + //task ipc mode, 1,2,3 + if (php_swoole_array_get_value(vht, "task_ipc_mode", v)) + { + convert_to_long(v); + serv->task_ipc_mode = (int) Z_LVAL_P(v); + } + /** + * Temporary file directory for task_worker + */ + if (php_swoole_array_get_value(vht, "task_tmpdir", v)) + { + convert_to_string(v); + if (php_swoole_create_dir(Z_STRVAL_P(v), Z_STRLEN_P(v) TSRMLS_CC) < 0) + { + swoole_php_fatal_error(E_ERROR, "Unable to create task_tmpdir[%s].", Z_STRVAL_P(v)); + return; + } + if (SwooleG.task_tmpdir) + { + sw_free(SwooleG.task_tmpdir); + } + SwooleG.task_tmpdir = sw_malloc(Z_STRLEN_P(v) + sizeof(SW_TASK_TMP_FILE) + 1); + SwooleG.task_tmpdir_len = snprintf(SwooleG.task_tmpdir, SW_TASK_TMPDIR_SIZE, "%s/swoole.task.XXXXXX", Z_STRVAL_P(v)) + 1; + } + //task_max_request + if (php_swoole_array_get_value(vht, "task_max_request", v)) + { + convert_to_long(v); + serv->task_max_request = (int) Z_LVAL_P(v); + } + //max_connection + if (php_swoole_array_get_value(vht, "max_connection", v) || php_swoole_array_get_value(vht, "max_conn", v)) + { + convert_to_long(v); + serv->max_connection = (int) Z_LVAL_P(v); + } + //heartbeat_check_interval + if (php_swoole_array_get_value(vht, "heartbeat_check_interval", v)) + { + convert_to_long(v); + serv->heartbeat_check_interval = (int) Z_LVAL_P(v); + } + //heartbeat idle time + if (php_swoole_array_get_value(vht, "heartbeat_idle_time", v)) + { + convert_to_long(v); + serv->heartbeat_idle_time = (int) Z_LVAL_P(v); + + if (serv->heartbeat_check_interval > serv->heartbeat_idle_time) + { + swoole_php_fatal_error(E_WARNING, "heartbeat_idle_time must be greater than heartbeat_check_interval."); + serv->heartbeat_check_interval = serv->heartbeat_idle_time / 2; + } + } + else if (serv->heartbeat_check_interval > 0) + { + serv->heartbeat_idle_time = serv->heartbeat_check_interval * 2; + } + //max_request + if (php_swoole_array_get_value(vht, "max_request", v)) + { + convert_to_long(v); + serv->max_request = (int) Z_LVAL_P(v); + } + //reload async + if (php_swoole_array_get_value(vht, "reload_async", v)) + { + convert_to_boolean(v); + serv->reload_async = Z_BVAL_P(v); + } + //cpu affinity + if (php_swoole_array_get_value(vht, "open_cpu_affinity", v)) + { + convert_to_boolean(v); + serv->open_cpu_affinity = Z_BVAL_P(v); + } + //cpu affinity set + if (php_swoole_array_get_value(vht, "cpu_affinity_ignore", v)) + { + int ignore_num = zend_hash_num_elements(Z_ARRVAL_P(v)); + if (ignore_num >= SW_CPU_NUM) + { + swoole_php_fatal_error(E_ERROR, "cpu_affinity_ignore num must be less than cpu num (%d)", SW_CPU_NUM); + RETURN_FALSE; + } + int available_num = SW_CPU_NUM - ignore_num; + int *available_cpu = (int *) sw_malloc(sizeof(int) * available_num); + int flag, i, available_i = 0; + + zval *zval_core = NULL; + for (i = 0; i < SW_CPU_NUM; i++) + { + flag = 1; + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(v), zval_core) + int core = (int) Z_LVAL_P(zval_core); + if (i == core) + { + flag = 0; + break; + } + SW_HASHTABLE_FOREACH_END(); + if (flag) + { + available_cpu[available_i] = i; + available_i++; + } + } + serv->cpu_affinity_available_num = available_num; + serv->cpu_affinity_available = available_cpu; + } + //paser x-www-form-urlencoded form data + if (php_swoole_array_get_value(vht, "http_parse_post", v)) + { + convert_to_boolean(v); + serv->http_parse_post = Z_BVAL_P(v); + } + //temporary directory for HTTP uploaded file. + if (php_swoole_array_get_value(vht, "upload_tmp_dir", v)) + { + convert_to_string(v); + if (php_swoole_create_dir(Z_STRVAL_P(v), Z_STRLEN_P(v) TSRMLS_CC) < 0) + { + swoole_php_fatal_error(E_ERROR, "Unable to create upload_tmp_dir[%s].", Z_STRVAL_P(v)); + return; + } + if (serv->upload_tmp_dir) + { + sw_free(serv->upload_tmp_dir); + } + serv->upload_tmp_dir = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + /** + * http static file handler + */ + if (php_swoole_array_get_value(vht, "enable_static_handler", v)) + { + convert_to_boolean(v); + serv->enable_static_handler = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "document_root", v)) + { + convert_to_string(v); + if (serv->document_root) + { + sw_free(serv->document_root); + } + serv->document_root = sw_strndup(Z_STRVAL_P(v), Z_STRLEN_P(v)); + if (serv->document_root[Z_STRLEN_P(v) - 1] == '/') + { + serv->document_root[Z_STRLEN_P(v) - 1] = 0; + serv->document_root_len = Z_STRLEN_P(v) - 1; + } + else + { + serv->document_root_len = Z_STRLEN_P(v); + } + } + /** + * buffer input size + */ + if (php_swoole_array_get_value(vht, "buffer_input_size", v)) + { + convert_to_long(v); + serv->buffer_input_size = (int) Z_LVAL_P(v); + } + /** + * buffer output size + */ + if (php_swoole_array_get_value(vht, "buffer_output_size", v)) + { + convert_to_long(v); + serv->buffer_output_size = (int) Z_LVAL_P(v); + } + //message queue key + if (php_swoole_array_get_value(vht, "message_queue_key", v)) + { + convert_to_long(v); + serv->message_queue_key = (int) Z_LVAL_P(v); + } + + zval *retval = NULL; + zval *port_object = server_port_list.zobjects[0]; + + sw_zval_add_ref(&port_object); + sw_zval_add_ref(&zset); + + sw_zend_call_method_with_1_params(&port_object, swoole_server_port_class_entry_ptr, NULL, "set", &retval, zset); + + zval *zsetting = php_swoole_read_init_property(swoole_server_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + sw_zval_ptr_dtor(&zset); + + RETURN_TRUE; +} + +PHP_METHOD(swoole_server, on) +{ + zval *name; + zval *cb; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "server is running. unable to register event callback function."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "zz", &name, &cb) == FAILURE) + { + return; + } + + char *func_name = NULL; + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(cb, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + + convert_to_string(name); + + char *callback_name[PHP_SERVER_CALLBACK_NUM] = { + "Connect", + "Receive", + "Close", + "Packet", + "Start", + "Shutdown", + "WorkerStart", + "WorkerStop", + "Task", + "Finish", + "WorkerExit", + "WorkerError", + "ManagerStart", + "ManagerStop", + "PipeMessage", + NULL, + NULL, + NULL, + NULL, + "BufferFull", + "BufferEmpty", + }; + + int i; + char property_name[128]; + int l_property_name = 0; + memcpy(property_name, "on", 2); + + for (i = 0; i < PHP_SERVER_CALLBACK_NUM; i++) + { + if (callback_name[i] == NULL) + { + continue; + } + if (strncasecmp(callback_name[i], Z_STRVAL_P(name), Z_STRLEN_P(name)) == 0) + { + memcpy(property_name + 2, callback_name[i], Z_STRLEN_P(name)); + l_property_name = Z_STRLEN_P(name) + 2; + property_name[l_property_name] = '\0'; + zend_update_property(swoole_server_class_entry_ptr, getThis(), property_name, l_property_name, cb TSRMLS_CC); + php_sw_server_callbacks[i] = sw_zend_read_property(swoole_server_class_entry_ptr, getThis(), property_name, l_property_name, 0 TSRMLS_CC); + php_sw_server_caches[i] = func_cache; + sw_copy_to_stack(php_sw_server_callbacks[i], _php_sw_server_callbacks[i]); + break; + } + } + + if (l_property_name == 0) + { + swoole_php_error(E_WARNING, "unknown event types[%s]", Z_STRVAL_P(name)); + efree(func_cache); + RETURN_FALSE; + } + + if (i < SW_SERVER_CB_onStart) + { + zval *port_object = server_port_list.zobjects[0]; + zval *retval = NULL; + sw_zval_add_ref(&port_object); + sw_zend_call_method_with_2_params(&port_object, swoole_server_port_class_entry_ptr, NULL, "on", &retval, name, cb); + } + else + { + RETURN_TRUE; + } +} + +PHP_METHOD(swoole_server, listen) +{ + char *host; + zend_size_t host_len; + long sock_type; + long port; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "server is running. can't add listener."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &host, &host_len, &port, &sock_type) == FAILURE) + { + return; + } + + swListenPort *ls = swServer_add_port(serv, (int) sock_type, host, (int) port); + if (!ls) + { + RETURN_FALSE; + } + + zval *port_object = php_swoole_server_add_port(serv, ls TSRMLS_CC); + RETURN_ZVAL(port_object, 1, NULL); +} + +PHP_METHOD(swoole_server, addProcess) +{ + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "server is running. can't add process."); + RETURN_FALSE; + } + + zval *process = NULL; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &process) == FAILURE) + { + return; + } + + if (ZVAL_IS_NULL(process)) + { + swoole_php_fatal_error(E_WARNING, "the first parameter can't be empty."); + RETURN_FALSE; + } + + if (!instanceof_function(Z_OBJCE_P(process), swoole_process_class_entry_ptr TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "object is not instanceof swoole_process."); + RETURN_FALSE; + } + + if (serv->onUserWorkerStart == NULL) + { + serv->onUserWorkerStart = php_swoole_onUserWorkerStart; + } + +#if PHP_MAJOR_VERSION >= 7 + zval *tmp_process = emalloc(sizeof(zval)); + memcpy(tmp_process, process, sizeof(zval)); + process = tmp_process; +#endif + + sw_zval_add_ref(&process); + + swWorker *worker = swoole_get_object(process); + worker->ptr = process; + + int id = swServer_add_worker(serv, worker); + if (id < 0) + { + swoole_php_fatal_error(E_WARNING, "swServer_add_worker failed."); + RETURN_FALSE; + } + zend_update_property_long(swoole_process_class_entry_ptr, getThis(), ZEND_STRL("id"), id TSRMLS_CC); + RETURN_LONG(id); +} + +PHP_METHOD(swoole_server, start) +{ + zval *zobject = getThis(); + int ret; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "server is running. unable to execute swoole_server->start."); + RETURN_FALSE; + } + + php_swoole_register_callback(serv); + + if (php_sw_server_callbacks[SW_SERVER_CB_onReceive] == NULL && php_sw_server_callbacks[SW_SERVER_CB_onPacket] == NULL) + { + swoole_php_fatal_error(E_ERROR, "require onReceive/onPacket callback"); + RETURN_FALSE; + } + //------------------------------------------------------------- + serv->onReceive = php_swoole_onReceive; + + php_swoole_server_before_start(serv, zobject TSRMLS_CC); + + ret = swServer_start(serv); + if (ret < 0) + { + swoole_php_fatal_error(E_ERROR, "failed to start server. Error: %s", sw_error); + RETURN_LONG(ret); + } + RETURN_TRUE; +} + +PHP_METHOD(swoole_server, send) +{ + int ret; + + zval *zfd; + zval *zdata; + zend_long server_socket = -1; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "can't send data to the connections in master process."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_ZVAL(zfd) + Z_PARAM_ZVAL(zdata) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(server_socket) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|l", &zfd, &zdata, &server_socket) == FAILURE) + { + return; + } +#endif + + char *data; + int length = php_swoole_get_send_data(zdata, &data TSRMLS_CC); + + if (length < 0) + { + RETURN_FALSE; + } + else if (length == 0) + { + swoole_php_fatal_error(E_WARNING, "data is empty."); + RETURN_FALSE; + } + + if (serv->have_udp_sock && SW_Z_TYPE_P(zfd) == IS_STRING) + { + if (server_socket == -1) + { + server_socket = dgram_server_socket; + } + //UDP IPv6 + if (strchr(Z_STRVAL_P(zfd), ':')) + { + php_swoole_udp_t udp_info; + memcpy(&udp_info, &server_socket, sizeof(udp_info)); + ret = swSocket_udp_sendto6(udp_info.from_fd, Z_STRVAL_P(zfd), udp_info.port, data, length); + } + //UNIX DGRAM + else if (Z_STRVAL_P(zfd)[0] == '/') + { + struct sockaddr_un addr_un; + memcpy(addr_un.sun_path, Z_STRVAL_P(zfd), Z_STRLEN_P(zfd)); + addr_un.sun_family = AF_UNIX; + addr_un.sun_path[Z_STRLEN_P(zfd)] = 0; + ret = swSocket_sendto_blocking(server_socket, data, length, 0, (struct sockaddr *) &addr_un, sizeof(addr_un)); + } + else + { + goto convert; + } + SW_CHECK_RETURN(ret); + } + + convert: convert_to_long(zfd); + uint32_t fd = (uint32_t) Z_LVAL_P(zfd); + //UDP + if (swServer_is_udp(fd)) + { + if (server_socket == -1) + { + server_socket = udp_server_socket; + } + + php_swoole_udp_t udp_info; + memcpy(&udp_info, &server_socket, sizeof(udp_info)); + + struct sockaddr_in addr_in; + addr_in.sin_family = AF_INET; + addr_in.sin_port = htons(udp_info.port); + addr_in.sin_addr.s_addr = fd; + ret = swSocket_sendto_blocking(udp_info.from_fd, data, length, 0, (struct sockaddr *) &addr_in, sizeof(addr_in)); + SW_CHECK_RETURN(ret); + } + //TCP + else + { + ret = swServer_tcp_send(serv, fd, data, length); +#ifdef SW_COROUTINE + if (ret < 0 && SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW && serv->send_yield) + { + zval_add_ref(zdata); + php_swoole_server_send_yield(serv, fd, zdata, return_value); + } + else +#endif + { + SW_CHECK_RETURN(ret); + } + } +} + +PHP_METHOD(swoole_server, sendto) +{ + char *ip; + char *data; + zend_size_t len, ip_len; + + zend_long port; + zend_long server_socket = -1; + zend_bool ipv6 = 0; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STRING(ip, ip_len) + Z_PARAM_LONG(port) + Z_PARAM_STRING(data, len) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(server_socket) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sls|l", &ip, &ip_len, &port, &data, &len, &server_socket) == FAILURE) + { + return; + } +#endif + + if (len <= 0) + { + swoole_php_fatal_error(E_WARNING, "data is empty."); + RETURN_FALSE; + } + + if (strchr(ip, ':')) + { + ipv6 = 1; + } + + if (ipv6 == 0 && serv->udp_socket_ipv4 <= 0) + { + swoole_php_fatal_error(E_WARNING, "UDP listener has to be added before executing sendto."); + RETURN_FALSE; + } + else if (ipv6 == 1 && serv->udp_socket_ipv6 <= 0) + { + swoole_php_fatal_error(E_WARNING, "UDP6 listener has to be added before executing sendto."); + RETURN_FALSE; + } + + if (server_socket < 0) + { + server_socket = ipv6 ? serv->udp_socket_ipv6 : serv->udp_socket_ipv4; + } + + int ret; + if (ipv6) + { + ret = swSocket_udp_sendto6(server_socket, ip, port, data, len); + } + else + { + ret = swSocket_udp_sendto(server_socket, ip, port, data, len); + } + SW_CHECK_RETURN(ret); +} + +PHP_METHOD(swoole_server, sendfile) +{ + zend_size_t len; + + char *filename; + long fd; + long offset = 0; + long length = 0; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls|ll", &fd, &filename, &len, &offset, &length) == FAILURE) + { + return; + } + + if (swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "can't sendfile[%s] to the connections in master process.", filename); + RETURN_FALSE; + } + + SW_CHECK_RETURN(swServer_tcp_sendfile(serv, (int) fd, filename, len, offset, length)); +} + +PHP_METHOD(swoole_server, close) +{ + zend_bool reset = SW_FALSE; + zend_long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "can't close the connections in master process."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_LONG(fd) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(reset) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &fd, &reset) == FAILURE) + { + return; + } +#endif + + SW_CHECK_RETURN(serv->close(serv, (int )fd, (int )reset)); +} + +PHP_METHOD(swoole_server, confirm) +{ + long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "can't confirm the connections in master process."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } + + SW_CHECK_RETURN(swServer_tcp_feedback(serv, fd, SW_EVENT_CONFIRM)); +} + +PHP_METHOD(swoole_server, pause) +{ + long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } + + SW_CHECK_RETURN(swServer_tcp_feedback(serv, fd, SW_EVENT_PAUSE_RECV)); +} + +PHP_METHOD(swoole_server, resume) +{ + long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } + + SW_CHECK_RETURN(swServer_tcp_feedback(serv, fd, SW_EVENT_RESUME_RECV)); +} + +PHP_METHOD(swoole_server, stats) +{ + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + array_init(return_value); + sw_add_assoc_long_ex(return_value, ZEND_STRS("start_time"), serv->stats->start_time); + sw_add_assoc_long_ex(return_value, ZEND_STRS("connection_num"), serv->stats->connection_num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("accept_count"), serv->stats->accept_count); + sw_add_assoc_long_ex(return_value, ZEND_STRS("close_count"), serv->stats->close_count); + sw_add_assoc_long_ex(return_value, ZEND_STRS("tasking_num"), serv->stats->tasking_num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("request_count"), serv->stats->request_count); + if (SwooleWG.worker) + { + sw_add_assoc_long_ex(return_value, ZEND_STRS("worker_request_count"), SwooleWG.worker->request_count); + } + + if (serv->task_ipc_mode > SW_TASK_IPC_UNIXSOCK && serv->gs->task_workers.queue) + { + int queue_num = -1; + int queue_bytes = -1; + if (swMsgQueue_stat(serv->gs->task_workers.queue, &queue_num, &queue_bytes) == 0) + { + sw_add_assoc_long_ex(return_value, ZEND_STRS("task_queue_num"), queue_num); + sw_add_assoc_long_ex(return_value, ZEND_STRS("task_queue_bytes"), queue_bytes); + } + } + +#ifdef SW_COROUTINE + sw_add_assoc_long_ex(return_value, ZEND_STRS("coroutine_num"), COROG.coro_num); +#endif +} + +PHP_METHOD(swoole_server, reload) +{ + zend_bool only_reload_taskworker = 0; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &only_reload_taskworker) == FAILURE) + { + return; + } + + int sig = only_reload_taskworker ? SIGUSR2 : SIGUSR1; + if (kill(serv->gs->manager_pid, sig) < 0) + { + swoole_php_fatal_error(E_WARNING, "failed to send the reload signal. Error: %s[%d]", strerror(errno), errno); + RETURN_FALSE; + } + RETURN_TRUE; +} + +PHP_METHOD(swoole_server, heartbeat) +{ + zend_bool close_connection = 0; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &close_connection) == FAILURE) + { + return; + } + + if (serv->heartbeat_idle_time < 1) + { + RETURN_FALSE; + } + + int serv_max_fd = swServer_get_maxfd(serv); + int serv_min_fd = swServer_get_minfd(serv); + + array_init(return_value); + + int fd; + int checktime = (int) serv->gs->now - serv->heartbeat_idle_time; + swConnection *conn; + + for (fd = serv_min_fd; fd <= serv_max_fd; fd++) + { + swTrace("heartbeat check fd=%d", fd); + conn = &serv->connection_list[fd]; + + if (1 == conn->active && conn->last_time < checktime) + { + conn->close_force = 1; + /** + * Close the connection + */ + if (close_connection) + { + serv->factory.end(&serv->factory, fd); + } +#ifdef SW_REACTOR_USE_SESSION + add_next_index_long(return_value, conn->session_id); +#else + add_next_index_long(return_value, fd); +#endif + } + } +} + +PHP_METHOD(swoole_server, taskwait) +{ + swEventData buf; + zval *data; + + double timeout = SW_TASKWAIT_TIMEOUT; + long dst_worker_id = -1; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|dl", &data, &timeout, &dst_worker_id) == FAILURE) + { + return; + } + + if (php_swoole_check_task_param(serv, dst_worker_id TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + if (php_swoole_task_pack(&buf, data TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + int task_id = buf.info.fd; + + uint64_t notify; + swEventData *task_result = &(serv->task_result[SwooleWG.id]); + bzero(task_result, sizeof(swEventData)); + swPipe *task_notify_pipe = &serv->task_notify[SwooleWG.id]; + int efd = task_notify_pipe->getFd(task_notify_pipe, 0); + + //clear history task + while (read(efd, &notify, sizeof(notify)) > 0); + + int _dst_worker_id = (int) dst_worker_id; + if (swProcessPool_dispatch_blocking(&serv->gs->task_workers, &buf, &_dst_worker_id) >= 0) + { + sw_atomic_fetch_add(&serv->stats->tasking_num, 1); + task_notify_pipe->timeout = timeout; + while(1) + { + if (task_notify_pipe->read(task_notify_pipe, &notify, sizeof(notify)) > 0) + { + if (task_result->info.fd != task_id) + { + continue; + } + zval *task_notify_data = php_swoole_task_unpack(task_result TSRMLS_CC); + if (task_notify_data == NULL) + { + RETURN_FALSE; + } + else + { + RETVAL_ZVAL(task_notify_data, 0, 0); + efree(task_notify_data); + return; + } + break; + } + else + { + swoole_php_error(E_WARNING, "taskwait failed. Error: %s[%d]", strerror(errno), errno); + break; + } + } + } + RETURN_FALSE; +} + +PHP_METHOD(swoole_server, taskWaitMulti) +{ + swEventData buf; + zval *tasks; + zval *task; + double timeout = SW_TASKWAIT_TIMEOUT; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|d", &tasks, &timeout) == FAILURE) + { + return; + } + + array_init(return_value); + + int dst_worker_id; + int task_id; + int i = 0; + int n_task = Z_ARRVAL_P(tasks)->nNumOfElements; + + if (n_task >= SW_MAX_CONCURRENT_TASK) + { + swoole_php_fatal_error(E_WARNING, "too many concurrent tasks."); + RETURN_FALSE; + } + + int list_of_id[SW_MAX_CONCURRENT_TASK]; + + uint64_t notify; + swEventData *task_result = &(serv->task_result[SwooleWG.id]); + bzero(task_result, sizeof(swEventData)); + swPipe *task_notify_pipe = &serv->task_notify[SwooleWG.id]; + swWorker *worker = swServer_get_worker(serv, SwooleWG.id); + + char _tmpfile[sizeof(SW_TASK_TMP_FILE)] = SW_TASK_TMP_FILE; + int _tmpfile_fd = swoole_tmpfile(_tmpfile); + if (_tmpfile_fd < 0) + { + RETURN_FALSE; + } + close(_tmpfile_fd); + int *finish_count = (int *) task_result->data; + + worker->lock.lock(&worker->lock); + *finish_count = 0; + memcpy(task_result->data + 4, _tmpfile, sizeof(_tmpfile)); + worker->lock.unlock(&worker->lock); + + //clear history task + int efd = task_notify_pipe->getFd(task_notify_pipe, 0); + while (read(efd, &notify, sizeof(notify)) > 0); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(tasks), task) + task_id = php_swoole_task_pack(&buf, task TSRMLS_CC); + if (task_id < 0) + { + swoole_php_fatal_error(E_WARNING, "task pack failed."); + goto fail; + } + swTask_type(&buf) |= SW_TASK_WAITALL; + dst_worker_id = -1; + if (swProcessPool_dispatch_blocking(&serv->gs->task_workers, &buf, &dst_worker_id) < 0) + { + swoole_php_fatal_error(E_WARNING, "taskwait failed. Error: %s[%d]", strerror(errno), errno); + task_id = -1; + fail: + add_index_bool(return_value, i, 0); + n_task --; + } + sw_atomic_fetch_add(&serv->stats->tasking_num, 1); + list_of_id[i] = task_id; + i++; + SW_HASHTABLE_FOREACH_END(); + + if (n_task == 0) + { + SwooleG.error = SW_ERROR_TASK_DISPATCH_FAIL; + RETURN_FALSE; + } + + double _now = swoole_microtime(); + while (n_task > 0) + { + task_notify_pipe->timeout = timeout; + int ret = task_notify_pipe->read(task_notify_pipe, &notify, sizeof(notify)); + if (ret > 0 && *finish_count < n_task) + { + if (swoole_microtime() - _now < timeout) + { + continue; + } + } + break; + } + + worker->lock.lock(&worker->lock); + swString *content = swoole_file_get_contents(_tmpfile); + worker->lock.unlock(&worker->lock); + + if (content == NULL) + { + RETURN_FALSE; + } + + swEventData *result; + zval *zdata; + int j; + + do + { + result = (swEventData *) (content->str + content->offset); + task_id = result->info.fd; + zdata = php_swoole_task_unpack(result TSRMLS_CC); + if (zdata == NULL) + { + goto next; + } + for (j = 0; j < Z_ARRVAL_P(tasks)->nNumOfElements; j++) + { + if (list_of_id[j] == task_id) + { + break; + } + } + add_index_zval(return_value, j, zdata); + efree(zdata); + next: content->offset += sizeof(swDataHead) + result->info.len; + } + while(content->offset < content->length); + //free memory + swString_free(content); + //delete tmp file + unlink(_tmpfile); +} + +#ifdef SW_COROUTINE +PHP_METHOD(swoole_server, taskCo) +{ + swEventData buf; + zval *tasks; + zval *task; + double timeout = SW_TASKWAIT_TIMEOUT; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|d", &tasks, &timeout) == FAILURE) + { + return; + } + + int dst_worker_id = -1; + int task_id; + int i = 0; + int n_task = Z_ARRVAL_P(tasks)->nNumOfElements; + + if (n_task >= SW_MAX_CONCURRENT_TASK) + { + swoole_php_fatal_error(E_WARNING, "too many concurrent tasks."); + RETURN_FALSE; + } + + if (php_swoole_check_task_param(serv, dst_worker_id TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + int *list = ecalloc(n_task, sizeof(int)); + if (list == NULL) + { + RETURN_FALSE; + } + + swTaskCo *task_co = emalloc(sizeof(swTaskCo)); + if (task_co == NULL) + { + efree(list); + RETURN_FALSE; + } + + zval *result; + SW_ALLOC_INIT_ZVAL(result); + array_init(result); + + SW_HASHTABLE_FOREACH_START(Z_ARRVAL_P(tasks), task) + task_id = php_swoole_task_pack(&buf, task TSRMLS_CC); + if (task_id < 0) + { + swoole_php_fatal_error(E_WARNING, "failed to pack task."); + goto fail; + } + swTask_type(&buf) |= (SW_TASK_NONBLOCK | SW_TASK_COROUTINE); + dst_worker_id = -1; + sw_atomic_fetch_add(&serv->stats->tasking_num, 1); + if (swProcessPool_dispatch(&serv->gs->task_workers, &buf, &dst_worker_id) < 0) + { + sw_atomic_fetch_sub(&serv->stats->tasking_num, 1); + task_id = -1; + fail: + add_index_bool(result, i, 0); + n_task --; + } + else + { + swHashMap_add_int(task_coroutine_map, buf.info.fd, task_co); + } + list[i] = task_id; + i++; + SW_HASHTABLE_FOREACH_END(); + + if (n_task == 0) + { + SwooleG.error = SW_ERROR_TASK_DISPATCH_FAIL; + RETURN_FALSE; + } + + int ms = (int) (timeout * 1000); + + task_co->result = result; + task_co->list = list; + task_co->count = n_task; + task_co->context.onTimeout = NULL; + task_co->context.state = SW_CORO_CONTEXT_RUNNING; + + php_swoole_check_timer(ms); + swTimer_node *timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, task_co, php_swoole_task_onTimeout); + if (timer) + { + task_co->timer = timer; + } + coro_save(&task_co->context); + coro_yield(); +} +#endif + +PHP_METHOD(swoole_server, task) +{ + swEventData buf; + zval *data; + zval *callback = NULL; + + zend_long dst_worker_id = -1; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ZVAL(data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(dst_worker_id) + Z_PARAM_ZVAL(callback) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|lz", &data, &dst_worker_id, &callback) == FAILURE) + { + return; + } +#endif + + if (php_swoole_check_task_param(serv, dst_worker_id TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + if (php_swoole_task_pack(&buf, data TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + if (callback && !ZVAL_IS_NULL(callback)) + { +#ifdef PHP_SWOOLE_CHECK_CALLBACK + char *func_name = NULL; + if (!sw_zend_is_callable(callback, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_WARNING, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); +#endif + swTask_type(&buf) |= SW_TASK_CALLBACK; + sw_zval_add_ref(&callback); + swHashMap_add_int(task_callbacks, buf.info.fd, sw_zval_dup(callback)); + } + + swTask_type(&buf) |= SW_TASK_NONBLOCK; + + int _dst_worker_id = (int) dst_worker_id; + if (swProcessPool_dispatch(&serv->gs->task_workers, &buf, &_dst_worker_id) >= 0) + { + sw_atomic_fetch_add(&serv->stats->tasking_num, 1); + RETURN_LONG(buf.info.fd); + } + else + { + RETURN_FALSE; + } +} + +PHP_METHOD(swoole_server, sendMessage) +{ + swEventData buf; + + zval *message; + long worker_id = -1; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &message, &worker_id) == FAILURE) + { + return; + } + + if (worker_id == SwooleWG.id) + { + swoole_php_fatal_error(E_WARNING, "can't send messages to self."); + RETURN_FALSE; + } + + if (worker_id >= serv->worker_num + serv->task_worker_num) + { + swoole_php_fatal_error(E_WARNING, "worker_id[%d] is invalid.", (int) worker_id); + RETURN_FALSE; + } + + if (!serv->onPipeMessage) + { + swoole_php_fatal_error(E_WARNING, "onPipeMessage is null, can't use sendMessage."); + RETURN_FALSE; + } + + if (php_swoole_task_pack(&buf, message TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + + buf.info.type = SW_EVENT_PIPE_MESSAGE; + buf.info.from_id = SwooleWG.id; + + swWorker *to_worker = swServer_get_worker(serv, worker_id); + SW_CHECK_RETURN(swWorker_send2worker(to_worker, &buf, sizeof(buf.info) + buf.info.len, SW_PIPE_MASTER | SW_PIPE_NONBLOCK)); +} + +PHP_METHOD(swoole_server, finish) +{ + zval *data; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ZVAL(data) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &data) == FAILURE) + { + return; + } +#endif + + SW_CHECK_RETURN(php_swoole_task_finish(serv, data TSRMLS_CC)); +} + +PHP_METHOD(swoole_server, bind) +{ + long fd = 0; + long uid = 0; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &fd, &uid) == FAILURE) + { + return; + } + + swConnection *conn = swWorker_get_connection(serv, fd); + if (conn == NULL || conn->active == 0) + { + RETURN_FALSE; + } + + sw_spinlock(&conn->lock); + if (conn->uid != 0) + { + RETVAL_FALSE; + } + else + { + conn->uid = (uint32_t) uid; + RETVAL_TRUE; + } + sw_spinlock_release(&conn->lock); +} + +#ifdef SWOOLE_SOCKETS_SUPPORT +PHP_METHOD(swoole_server, getSocket) +{ + long port = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &port) == FAILURE) + { + return; + } + + zval *zobject = getThis(); + swServer *serv = swoole_get_object(zobject); + + int sock = swServer_get_socket(serv, port); + php_socket *socket_object = swoole_convert_to_socket(sock); + + if (!socket_object) + { + RETURN_FALSE; + } + SW_ZEND_REGISTER_RESOURCE(return_value, (void *) socket_object, php_sockets_le_socket()); + zval *zsocket = sw_zval_dup(return_value); + sw_zval_add_ref(&zsocket); +} +#endif + +PHP_METHOD(swoole_server, connection_info) +{ + zval *zobject = getThis(); + + zend_bool noCheckConnection = 0; + zval *zfd; + long from_id = -1; + + swServer *serv = swoole_get_object(zobject); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|lb", &zfd, &from_id, &noCheckConnection) == FAILURE) + { + return; + } + + zend_long fd = 0; + zend_bool ipv6_udp = 0; + + //ipv6 udp + if (SW_Z_TYPE_P(zfd) == IS_STRING) + { + if (is_numeric_string(Z_STRVAL_P(zfd), Z_STRLEN_P(zfd), &fd, NULL, 0)) + { + ipv6_udp = 0; + } + else + { + fd = 0; + ipv6_udp = 1; + } + } + else + { + convert_to_long(zfd); + fd = Z_LVAL_P(zfd); + } + + //udp + if (ipv6_udp || swServer_is_udp(fd)) + { + array_init(return_value); + + swoole_php_error(E_DEPRECATED, "The UDP connection_info is deprecated, use onPacket instead."); + + if (ipv6_udp) + { + add_assoc_zval(return_value, "remote_ip", zfd); + } + else + { + struct in_addr sin_addr; + sin_addr.s_addr = fd; + sw_add_assoc_string(return_value, "remote_ip", inet_ntoa(sin_addr), 1); + } + + if (from_id == 0) + { + return; + } + + php_swoole_udp_t udp_info; + memcpy(&udp_info, &from_id, sizeof(udp_info)); + //server socket + swConnection *from_sock = swServer_connection_get(serv, udp_info.from_fd); + if (from_sock) + { + add_assoc_long(return_value, "server_fd", from_sock->fd); + add_assoc_long(return_value, "socket_type", from_sock->socket_type); + add_assoc_long(return_value, "server_port", swConnection_get_port(from_sock)); + } + add_assoc_long(return_value, "remote_port", udp_info.port); + return; + } + + swConnection *conn = swServer_connection_verify(serv, fd); + if (!conn) + { + RETURN_FALSE; + } + //connection is closed + if (conn->active == 0 && !noCheckConnection) + { + RETURN_FALSE; + } + else + { + array_init(return_value); + + if (conn->uid > 0 || serv->dispatch_mode == SW_DISPATCH_UIDMOD) + { + add_assoc_long(return_value, "uid", conn->uid); + } + + swListenPort *port = swServer_get_port(serv, conn->fd); + if (port && port->open_websocket_protocol) + { + add_assoc_long(return_value, "websocket_status", conn->websocket_status); + } + +#ifdef SW_USE_OPENSSL + if (conn->ssl_client_cert.length > 0) + { + sw_add_assoc_stringl(return_value, "ssl_client_cert", conn->ssl_client_cert.str, conn->ssl_client_cert.length - 1, 1); + } +#endif + //server socket + swConnection *from_sock = swServer_connection_get(serv, conn->from_fd); + if (from_sock) + { + add_assoc_long(return_value, "server_port", swConnection_get_port(from_sock)); + } + add_assoc_long(return_value, "server_fd", conn->from_fd); + add_assoc_long(return_value, "socket_fd", conn->fd); + add_assoc_long(return_value, "socket_type", conn->socket_type); + add_assoc_long(return_value, "remote_port", swConnection_get_port(conn)); + sw_add_assoc_string(return_value, "remote_ip", swConnection_get_ip(conn), 1); + add_assoc_long(return_value, "reactor_id", conn->from_id); + add_assoc_long(return_value, "connect_time", conn->connect_time); + add_assoc_long(return_value, "last_time", conn->last_time); + add_assoc_long(return_value, "close_errno", conn->close_errno); + } +} + +PHP_METHOD(swoole_server, connection_list) +{ + long start_fd = 0; + long find_count = 10; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ll", &start_fd, &find_count) == FAILURE) + { + return; + } + + //超过最大查找数量 + if (find_count > SW_MAX_FIND_COUNT) + { + swoole_php_fatal_error(E_WARNING, "swoole_connection_list max_find_count=%d", SW_MAX_FIND_COUNT); + RETURN_FALSE; + } + + //复制出来避免被其他进程改写 + int serv_max_fd = swServer_get_maxfd(serv); + + if (start_fd == 0) + { + start_fd = swServer_get_minfd(serv); + } +#ifdef SW_REACTOR_USE_SESSION + else + { + swConnection *conn = swWorker_get_connection(serv, start_fd); + if (!conn) + { + RETURN_FALSE; + } + start_fd = conn->fd; + } +#endif + + //达到最大,表示已经取完了 + if ((int) start_fd >= serv_max_fd) + { + RETURN_FALSE; + } + + array_init(return_value); + int fd = start_fd + 1; + swConnection *conn; + + for (; fd <= serv_max_fd; fd++) + { + swTrace("maxfd=%d, fd=%d, find_count=%ld, start_fd=%ld", serv_max_fd, fd, find_count, start_fd); + conn = &serv->connection_list[fd]; + + if (conn->active && !conn->closed) + { +#ifdef SW_USE_OPENSSL + if (conn->ssl && conn->ssl_state != SW_SSL_STATE_READY) + { + continue; + } +#endif +#ifdef SW_REACTOR_USE_SESSION + add_next_index_long(return_value, conn->session_id); +#else + add_next_index_long(return_value, fd); +#endif + find_count--; + } + //finish fetch + if (find_count <= 0) + { + break; + } + } +} + +PHP_METHOD(swoole_server, sendwait) +{ + long fd; + zval *zdata; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &fd, &zdata) == FAILURE) + { + return; + } + + char *data; + int length = php_swoole_get_send_data(zdata, &data TSRMLS_CC); + + if (length < 0) + { + RETURN_FALSE; + } + else if (length == 0) + { + swoole_php_fatal_error(E_WARNING, "data is empty."); + RETURN_FALSE; + } + + if (serv->factory_mode != SW_MODE_SINGLE || swIsTaskWorker()) + { + swoole_php_fatal_error(E_WARNING, "can't sendwait."); + RETURN_FALSE; + } + + //UDP + if (swServer_is_udp(fd)) + { + swoole_php_fatal_error(E_WARNING, "can't sendwait."); + RETURN_FALSE; + } + //TCP + else + { + SW_CHECK_RETURN(swServer_tcp_sendwait(serv, fd, data, length)); + } +} + +PHP_METHOD(swoole_server, exist) +{ + zend_long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + +#ifdef FAST_ZPP + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(fd) + ZEND_PARSE_PARAMETERS_END(); +#else + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } +#endif + + swConnection *conn = swWorker_get_connection(serv, fd); + if (!conn) + { + RETURN_FALSE; + } + //connection is closed + if (conn->active == 0 || conn->closed) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +PHP_METHOD(swoole_server, protect) +{ + long fd; + zend_bool value = 1; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &fd, &value) == FAILURE) + { + return; + } + + swConnection *conn = swWorker_get_connection(serv, fd); + if (!conn) + { + RETURN_FALSE; + } + //connection is closed + if (conn->active == 0 || conn->closed) + { + RETURN_FALSE; + } + else + { + conn->protect = value; + RETURN_TRUE; + } +} + +#ifdef SW_BUFFER_RECV_TIME +PHP_METHOD(swoole_server, getReceivedTime) +{ + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + if (serv->last_receive_usec > 0) + { + RETURN_DOUBLE(serv->last_receive_usec); + } + else + { + RETURN_FALSE; + } +} +#endif + +PHP_METHOD(swoole_server, shutdown) +{ + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + if (kill(serv->gs->master_pid, SIGTERM) < 0) + { + swoole_php_sys_error(E_WARNING, "failed to shutdown. kill(%d, SIGTERM) failed.", serv->gs->master_pid); + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +PHP_METHOD(swoole_server, stop) +{ + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + swoole_php_fatal_error(E_WARNING, "server is not running."); + RETURN_FALSE; + } + + zend_bool wait_reactor = 0; + long worker_id = SwooleWG.id; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &worker_id, &wait_reactor) == FAILURE) + { + return; + } + + if (worker_id == SwooleWG.id && wait_reactor == 0) + { + SwooleG.main_reactor->running = 0; + SwooleG.running = 0; + } + else + { + swWorker *worker = swServer_get_worker(SwooleG.serv, worker_id); + if (worker == NULL) + { + RETURN_FALSE; + } + else if (kill(worker->pid, SIGTERM) < 0) + { + swoole_php_sys_error(E_WARNING, "kill(%d, SIGTERM) failed.", worker->pid); + RETURN_FALSE; + } + } + RETURN_TRUE; +} + +#ifdef HAVE_PCRE + +PHP_METHOD(swoole_connection_iterator, rewind) +{ + swConnectionIterator *itearator = swoole_get_object(getThis()); + itearator->current_fd = swServer_get_minfd(SwooleG.serv); +} + +PHP_METHOD(swoole_connection_iterator, valid) +{ + swConnectionIterator *itearator = swoole_get_object(getThis()); + int fd = itearator->current_fd; + swConnection *conn; + + int max_fd = swServer_get_maxfd(itearator->serv); + for (; fd <= max_fd; fd++) + { + conn = &SwooleG.serv->connection_list[fd]; + + if (conn->active && !conn->closed) + { +#ifdef SW_USE_OPENSSL + if (conn->ssl && conn->ssl_state != SW_SSL_STATE_READY) + { + continue; + } +#endif + if (itearator->port && conn->from_fd != itearator->port->sock) + { + continue; + } + itearator->session_id = conn->session_id; + itearator->current_fd = fd; + itearator->index++; + RETURN_TRUE; + } + } + + RETURN_FALSE; +} + +PHP_METHOD(swoole_connection_iterator, current) +{ + swConnectionIterator *itearator = swoole_get_object(getThis()); + RETURN_LONG(itearator->session_id); +} + +PHP_METHOD(swoole_connection_iterator, next) +{ + swConnectionIterator *itearator = swoole_get_object(getThis()); + itearator->current_fd++; +} + +PHP_METHOD(swoole_connection_iterator, key) +{ + swConnectionIterator *itearator = swoole_get_object(getThis()); + RETURN_LONG(itearator->index); +} + +PHP_METHOD(swoole_connection_iterator, count) +{ + swConnectionIterator *i = swoole_get_object(getThis()); + if (i->port) + { + RETURN_LONG(i->port->connection_num); + } + else + { + RETURN_LONG(i->serv->stats->connection_num); + } +} + +PHP_METHOD(swoole_connection_iterator, offsetExists) +{ + zval *zobject = (zval *) SwooleG.serv->ptr2; + zval *retval = NULL; + zval *zfd; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfd) == FAILURE) + { + return; + } + sw_zend_call_method_with_1_params(&zobject, swoole_server_class_entry_ptr, NULL, "exist", &retval, zfd); + if (retval) + { + RETVAL_BOOL(Z_BVAL_P(retval)); + sw_zval_ptr_dtor(&retval); + } +} + +PHP_METHOD(swoole_connection_iterator, offsetGet) +{ + zval *zobject = (zval *) SwooleG.serv->ptr2; + zval *retval = NULL; + zval *zfd; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zfd) == FAILURE) + { + return; + } + sw_zend_call_method_with_1_params(&zobject, swoole_server_class_entry_ptr, NULL, "connection_info", &retval, zfd); + if (retval) + { + RETVAL_ZVAL(retval, 0, 0); + } +} + +PHP_METHOD(swoole_connection_iterator, offsetSet) +{ + return; +} + +PHP_METHOD(swoole_connection_iterator, offsetUnset) +{ + return; +} + +PHP_METHOD(swoole_connection_iterator, __destruct) +{ + swConnectionIterator *i = swoole_get_object(getThis()); + efree(i); + swoole_set_object(getThis(), NULL); +} + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/vendor/swoole/swoole_server_port.c b/vendor/swoole/swoole_server_port.c new file mode 100755 index 0000000..0dd8af0 --- /dev/null +++ b/vendor/swoole/swoole_server_port.c @@ -0,0 +1,639 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +zend_class_entry swoole_server_port_ce; +zend_class_entry *swoole_server_port_class_entry_ptr; + +static PHP_METHOD(swoole_server_port, __construct); +static PHP_METHOD(swoole_server_port, __destruct); +static PHP_METHOD(swoole_server_port, on); +static PHP_METHOD(swoole_server_port, set); + +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_server_port, getSocket); +#endif + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_port_set, 0, 0, 1) + ZEND_ARG_ARRAY_INFO(0, settings, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_server_port_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +const zend_function_entry swoole_server_port_methods[] = +{ + PHP_ME(swoole_server_port, __construct, arginfo_swoole_void, ZEND_ACC_PRIVATE | ZEND_ACC_CTOR) + PHP_ME(swoole_server_port, __destruct, arginfo_swoole_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_ME(swoole_server_port, set, arginfo_swoole_server_port_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_server_port, on, arginfo_swoole_server_port_on, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) +#ifdef SWOOLE_SOCKETS_SUPPORT + PHP_ME(swoole_server_port, getSocket, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#endif + PHP_FE_END +}; + +void swoole_server_port_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_server_port_ce, "swoole_server_port", "Swoole\\Server\\Port", swoole_server_port_methods); + swoole_server_port_class_entry_ptr = zend_register_internal_class(&swoole_server_port_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_server_port, "Swoole\\Server\\Port"); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Server\\Port", swoole_server_port_class_entry_ptr); + } + + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onConnect"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onReceive"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onClose"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onPacket"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onBufferFull"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onBufferEmpty"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onRequest"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onHandShake"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onMessage"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("onOpen"), ZEND_ACC_PUBLIC TSRMLS_CC); + + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_port_class_entry_ptr, ZEND_STRL("port"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_port_class_entry_ptr, ZEND_STRL("type"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_long(swoole_server_port_class_entry_ptr, ZEND_STRL("sock"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("setting"), ZEND_ACC_PUBLIC TSRMLS_CC); + +#ifdef HAVE_PCRE + zend_declare_property_null(swoole_server_port_class_entry_ptr, ZEND_STRL("connections"), ZEND_ACC_PUBLIC TSRMLS_CC); +#endif +} + +static PHP_METHOD(swoole_server_port, __construct) +{ + swoole_php_fatal_error(E_ERROR, "please use the swoole_server->listen method."); + return; +} + +static PHP_METHOD(swoole_server_port, __destruct) +{ + swoole_server_port_property *property = swoole_get_property(getThis(), 0); + +#ifdef PHP_SWOOLE_ENABLE_FASTCALL + int j; + for (j = 0; j < PHP_SERVER_CALLBACK_NUM; j++) + { + if (property->caches[j]) + { + efree(property->caches[j]); + property->caches[j] = NULL; + } + } +#endif + + efree(property); + swoole_set_property(getThis(), 0, NULL); + swoole_set_object(getThis(), NULL); +} + +static PHP_METHOD(swoole_server_port, set) +{ + zval *zset = NULL; + HashTable *vht; + zval *v; + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "z", &zset) == FAILURE) + { + return; + } + if (Z_TYPE_P(zset) != IS_ARRAY) + { + RETURN_FALSE; + } + + php_swoole_array_separate(zset); + vht = Z_ARRVAL_P(zset); + + swListenPort *port = swoole_get_object(getThis()); + swoole_server_port_property *property = swoole_get_property(getThis(), 0); + + if (port == NULL || property == NULL) + { + swoole_php_fatal_error(E_ERROR, "please use the swoole_server->listen method."); + return; + } + + property->setting = zset; + + //backlog + if (php_swoole_array_get_value(vht, "backlog", v)) + { + convert_to_long(v); + port->backlog = (int) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "socket_buffer_size", v)) + { + convert_to_long(v); + port->socket_buffer_size = (int) Z_LVAL_P(v); + if (port->socket_buffer_size <= 0) + { + port->socket_buffer_size = SW_MAX_INT; + } + } + /** + * !!! Don't set this option, for tests only. + */ + if (php_swoole_array_get_value(vht, "kernel_socket_recv_buffer_size", v)) + { + convert_to_long(v); + port->kernel_socket_recv_buffer_size = (int) Z_LVAL_P(v); + if (port->kernel_socket_recv_buffer_size <= 0) + { + port->kernel_socket_recv_buffer_size = SW_MAX_INT; + } + } + /** + * !!! Don't set this option, for tests only. + */ + if (php_swoole_array_get_value(vht, "kernel_socket_send_buffer_size", v)) + { + convert_to_long(v); + port->kernel_socket_send_buffer_size = (int) Z_LVAL_P(v); + if (port->kernel_socket_send_buffer_size <= 0) + { + port->kernel_socket_send_buffer_size = SW_MAX_INT; + } + } + if (php_swoole_array_get_value(vht, "buffer_high_watermark", v)) + { + convert_to_long(v); + port->buffer_high_watermark = (int) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "buffer_low_watermark", v)) + { + convert_to_long(v); + port->buffer_low_watermark = (int) Z_LVAL_P(v); + } + //tcp_nodelay + if (php_swoole_array_get_value(vht, "open_tcp_nodelay", v)) + { + convert_to_boolean(v); + port->open_tcp_nodelay = Z_BVAL_P(v); + } + //tcp_defer_accept + if (php_swoole_array_get_value(vht, "tcp_defer_accept", v)) + { + convert_to_long(v); + port->tcp_defer_accept = (uint8_t) Z_LVAL_P(v); + } + //tcp_keepalive + if (php_swoole_array_get_value(vht, "open_tcp_keepalive", v)) + { + convert_to_boolean(v); + port->open_tcp_keepalive = Z_BVAL_P(v); + } + //buffer: eof check + if (php_swoole_array_get_value(vht, "open_eof_check", v)) + { + convert_to_boolean(v); + port->open_eof_check = Z_BVAL_P(v); + } + //buffer: split package with eof + if (php_swoole_array_get_value(vht, "open_eof_split", v)) + { + convert_to_boolean(v); + port->protocol.split_by_eof = Z_BVAL_P(v); + if (port->protocol.split_by_eof) + { + port->open_eof_check = 1; + } + } + //package eof + if (php_swoole_array_get_value(vht, "package_eof", v)) + { + convert_to_string(v); + port->protocol.package_eof_len = Z_STRLEN_P(v); + if (port->protocol.package_eof_len > SW_DATA_EOF_MAXLEN) + { + swoole_php_fatal_error(E_ERROR, "pacakge_eof max length is %d", SW_DATA_EOF_MAXLEN); + RETURN_FALSE; + } + bzero(port->protocol.package_eof, SW_DATA_EOF_MAXLEN); + memcpy(port->protocol.package_eof, Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + //http_protocol + if (php_swoole_array_get_value(vht, "open_http_protocol", v)) + { + convert_to_boolean(v); + port->open_http_protocol = Z_BVAL_P(v); + } + //websocket protocol + if (php_swoole_array_get_value(vht, "open_websocket_protocol", v)) + { + convert_to_boolean(v); + port->open_websocket_protocol = Z_BVAL_P(v); + } + if (php_swoole_array_get_value(vht, "websocket_subprotocol", v)) + { + convert_to_string(v); + if (port->websocket_subprotocol) + { + sw_free(port->websocket_subprotocol); + } + port->websocket_subprotocol = sw_strdup(Z_STRVAL_P(v)); + port->websocket_subprotocol_length = Z_STRLEN_P(v); + } +#ifdef SW_USE_HTTP2 + //http2 protocol + if (php_swoole_array_get_value(vht, "open_http2_protocol", v)) + { + convert_to_boolean(v); + port->open_http2_protocol = Z_BVAL_P(v); + } +#endif + //buffer: mqtt protocol + if (php_swoole_array_get_value(vht, "open_mqtt_protocol", v)) + { + convert_to_boolean(v); + port->open_mqtt_protocol = Z_BVAL_P(v); + } + //redis protocol + if (php_swoole_array_get_value(vht, "open_redis_protocol", v)) + { + convert_to_boolean(v); + port->open_redis_protocol = Z_BVAL_P(v); + } + //tcp_keepidle + if (php_swoole_array_get_value(vht, "tcp_keepidle", v)) + { + convert_to_long(v); + port->tcp_keepidle = (uint16_t) Z_LVAL_P(v); + } + //tcp_keepinterval + if (php_swoole_array_get_value(vht, "tcp_keepinterval", v)) + { + convert_to_long(v); + port->tcp_keepinterval = (uint16_t) Z_LVAL_P(v); + } + //tcp_keepcount + if (sw_zend_hash_find(vht, ZEND_STRS("tcp_keepcount"), (void **) &v) == SUCCESS) + { + convert_to_long(v); + port->tcp_keepcount = (uint16_t) Z_LVAL_P(v); + } + //tcp_fastopen + if (sw_zend_hash_find(vht, ZEND_STRS("tcp_fastopen"), (void **) &v) == SUCCESS) + { + convert_to_boolean(v); + port->tcp_fastopen = Z_BVAL_P(v); + } + //open length check + if (php_swoole_array_get_value(vht, "open_length_check", v)) + { + convert_to_boolean(v); + port->open_length_check = Z_BVAL_P(v); + } + //package length size + if (php_swoole_array_get_value(vht, "package_length_type", v)) + { + convert_to_string(v); + port->protocol.package_length_type = Z_STRVAL_P(v)[0]; + port->protocol.package_length_size = swoole_type_size(port->protocol.package_length_type); + if (port->protocol.package_length_size == 0) + { + swoole_php_fatal_error(E_ERROR, "unknow package_length_type, see pack(). Link: http://php.net/pack"); + RETURN_FALSE; + } + } + //length function + if (php_swoole_array_get_value(vht, "package_length_func", v)) + { + while(1) + { + if (Z_TYPE_P(v) == IS_STRING) + { + swProtocol_length_function func = swoole_get_function(Z_STRVAL_P(v), Z_STRLEN_P(v)); + if (func != NULL) + { + port->protocol.get_package_length = func; + break; + } + } + + char *func_name = NULL; + if (!sw_zend_is_callable(v, 0, &func_name TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + port->protocol.get_package_length = php_swoole_length_func; + sw_zval_add_ref(&v); + port->protocol.private_data = sw_zval_dup(v); + break; + } + + port->protocol.package_length_size = 0; + port->protocol.package_length_type = '\0'; + port->protocol.package_length_offset = SW_BUFFER_SIZE; + } + //package length offset + if (php_swoole_array_get_value(vht, "package_length_offset", v)) + { + convert_to_long(v); + port->protocol.package_length_offset = (int) Z_LVAL_P(v); + if (port->protocol.package_length_offset > SW_BUFFER_SIZE) + { + swoole_php_fatal_error(E_ERROR, "'package_length_offset' value is too large."); + } + } + //package body start + if (php_swoole_array_get_value(vht, "package_body_offset", v) || php_swoole_array_get_value(vht, "package_body_start", v)) + { + convert_to_long(v); + port->protocol.package_body_offset = (int) Z_LVAL_P(v); + if (port->protocol.package_body_offset > SW_BUFFER_SIZE) + { + swoole_php_fatal_error(E_ERROR, "'package_body_offset' value is too large."); + } + } + /** + * package max length + */ + if (php_swoole_array_get_value(vht, "package_max_length", v)) + { + convert_to_long(v); + port->protocol.package_max_length = (int) Z_LVAL_P(v); + } + +#ifdef SW_USE_OPENSSL + if (port->ssl) + { + if (php_swoole_array_get_value(vht, "ssl_cert_file", v)) + { + convert_to_string(v); + if (access(Z_STRVAL_P(v), R_OK) < 0) + { + swoole_php_fatal_error(E_ERROR, "ssl cert file[%s] not found.", Z_STRVAL_P(v)); + return; + } + if (port->ssl_option.cert_file) + { + sw_free(port->ssl_option.cert_file); + } + port->ssl_option.cert_file = sw_strdup(Z_STRVAL_P(v)); + port->open_ssl_encrypt = 1; + } + if (php_swoole_array_get_value(vht, "ssl_key_file", v)) + { + convert_to_string(v); + if (access(Z_STRVAL_P(v), R_OK) < 0) + { + swoole_php_fatal_error(E_ERROR, "ssl key file[%s] not found.", Z_STRVAL_P(v)); + return; + } + if (port->ssl_option.key_file) + { + sw_free(port->ssl_option.key_file); + } + port->ssl_option.key_file = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_method", v)) + { + convert_to_long(v); + port->ssl_option.method = (int) Z_LVAL_P(v); + } + //verify client cert + if (php_swoole_array_get_value(vht, "ssl_client_cert_file", v)) + { + convert_to_string(v); + if (access(Z_STRVAL_P(v), R_OK) < 0) + { + swoole_php_fatal_error(E_ERROR, "ssl cert file[%s] not found.", port->ssl_option.cert_file); + return; + } + if (port->ssl_option.client_cert_file) + { + sw_free(port->ssl_option.client_cert_file); + } + port->ssl_option.client_cert_file = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_verify_depth", v)) + { + convert_to_long(v); + port->ssl_option.verify_depth = (int) Z_LVAL_P(v); + } + if (php_swoole_array_get_value(vht, "ssl_prefer_server_ciphers", v)) + { + convert_to_boolean(v); + port->ssl_config.prefer_server_ciphers = Z_BVAL_P(v); + } + // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_session_tickets"), (void **) &v) == SUCCESS) + // { + // convert_to_boolean(v); + // port->ssl_config.session_tickets = Z_BVAL_P(v); + // } + // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_stapling"), (void **) &v) == SUCCESS) + // { + // convert_to_boolean(v); + // port->ssl_config.stapling = Z_BVAL_P(v); + // } + // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_stapling_verify"), (void **) &v) == SUCCESS) + // { + // convert_to_boolean(v); + // port->ssl_config.stapling_verify = Z_BVAL_P(v); + // } + if (php_swoole_array_get_value(vht, "ssl_ciphers", v)) + { + convert_to_string(v); + if (port->ssl_config.ciphers) + { + sw_free(port->ssl_config.ciphers); + } + port->ssl_config.ciphers = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_ecdh_curve", v)) + { + convert_to_string(v); + if (port->ssl_config.ecdh_curve) + { + sw_free(port->ssl_config.ecdh_curve); + } + port->ssl_config.ecdh_curve = sw_strdup(Z_STRVAL_P(v)); + } + if (php_swoole_array_get_value(vht, "ssl_dhparam", v)) + { + convert_to_string(v); + if (port->ssl_config.dhparam) + { + sw_free(port->ssl_config.dhparam); + } + port->ssl_config.dhparam = sw_strdup(Z_STRVAL_P(v)); + } + // if (sw_zend_hash_find(vht, ZEND_STRS("ssl_session_cache"), (void **) &v) == SUCCESS) + // { + // convert_to_string(v); + // port->ssl_config.session_cache = strdup(Z_STRVAL_P(v)); + // } + if (swPort_enable_ssl_encrypt(port) < 0) + { + swoole_php_fatal_error(E_ERROR, "swPort_enable_ssl_encrypt() failed."); + RETURN_FALSE; + } + } +#endif + + zval *zsetting = php_swoole_read_init_property(swoole_server_port_class_entry_ptr, getThis(), ZEND_STRL("setting") TSRMLS_CC); + sw_php_array_merge(Z_ARRVAL_P(zsetting), Z_ARRVAL_P(zset)); + sw_zval_ptr_dtor(&zset); +} + +static PHP_METHOD(swoole_server_port, on) +{ + char *name = NULL; + zend_size_t len, i; + zval *cb; + + swoole_server_port_property *property = swoole_get_property(getThis(), 0); + swServer *serv = property->serv; + if (serv->gs->start > 0) + { + swoole_php_fatal_error(E_WARNING, "can't register event callback function after server started."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS()TSRMLS_CC, "sz", &name, &len, &cb) == FAILURE) + { + return; + } + + char *func_name = NULL; + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(cb, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + return; + } + efree(func_name); + + swListenPort *port = swoole_get_object(getThis()); + if (!port->ptr) + { + port->ptr = property; + } + + char *callback_name[PHP_SERVER_CALLBACK_NUM] = { + "Connect", + "Receive", + "Close", + "Packet", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Request", + "HandShake", + "Open", + "Message", + "BufferFull", + "BufferEmpty", + }; + + char property_name[128]; + int l_property_name = 0; + memcpy(property_name, "on", 2); + + for (i = 0; i < PHP_SERVER_CALLBACK_NUM; i++) + { + if (callback_name[i] == NULL) + { + continue; + } + if (strncasecmp(callback_name[i], name, len) == 0) + { + memcpy(property_name + 2, callback_name[i], len); + l_property_name = len + 2; + property_name[l_property_name] = '\0'; + zend_update_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, cb TSRMLS_CC); + property->callbacks[i] = sw_zend_read_property(swoole_server_port_class_entry_ptr, getThis(), property_name, l_property_name, 0 TSRMLS_CC); + sw_copy_to_stack(property->callbacks[i], property->_callbacks[i]); + + if (i == SW_SERVER_CB_onConnect && serv->onConnect == NULL) + { + serv->onConnect = php_swoole_onConnect; + } + else if (i == SW_SERVER_CB_onPacket && serv->onPacket == NULL) + { + serv->onPacket = php_swoole_onPacket; + } + else if (i == SW_SERVER_CB_onClose && serv->onClose == NULL) + { + serv->onClose = php_swoole_onClose; + } + else if (i == SW_SERVER_CB_onBufferFull && serv->onBufferFull == NULL) + { + serv->onBufferFull = php_swoole_onBufferFull; + } + else if (i == SW_SERVER_CB_onBufferEmpty && serv->onBufferEmpty == NULL) + { + serv->onBufferEmpty = php_swoole_onBufferEmpty; + } + property->caches[i] = func_cache; + break; + } + } + + if (l_property_name == 0) + { + swoole_php_error(E_WARNING, "unknown event types[%s]", name); + efree(func_cache); + RETURN_FALSE; + } + RETURN_TRUE; +} + +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_server_port, getSocket) +{ + swListenPort *port = swoole_get_object(getThis()); + php_socket *socket_object = swoole_convert_to_socket(port->sock); + if (!socket_object) + { + RETURN_FALSE; + } + SW_ZEND_REGISTER_RESOURCE(return_value, (void *) socket_object, php_sockets_le_socket()); + zval *zsocket = sw_zval_dup(return_value); + sw_zval_add_ref(&zsocket); +} +#endif diff --git a/vendor/swoole/swoole_socket_coro.c b/vendor/swoole/swoole_socket_coro.c new file mode 100755 index 0000000..6b2c498 --- /dev/null +++ b/vendor/swoole/swoole_socket_coro.c @@ -0,0 +1,1183 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2018 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" + +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" + +static zend_class_entry swoole_socket_coro_ce; +static zend_class_entry *swoole_socket_coro_class_entry_ptr; +static zend_object_handlers swoole_socket_coro_handlers; + +static zend_class_entry swoole_socket_coro_exception_ce; +static zend_class_entry *swoole_socket_coro_exception_class_entry_ptr; + +enum socket_opcode +{ + SW_SOCKET_OPCODE_ACCEPT, + SW_SOCKET_OPCODE_CONNECT, + SW_SOCKET_OPCODE_RECV, + SW_SOCKET_OPCODE_RECVFROM, + SW_SOCKET_OPCODE_SEND, +}; + +typedef struct +{ + zval object; + int fd; + int domain; + int type; + int cid; + enum socket_opcode opcode; + php_context context; + swTimer_node *timer; +#ifdef SWOOLE_SOCKETS_SUPPORT + zval *resource; +#endif + zend_object std; +} socket_coro; + +static PHP_METHOD(swoole_socket_coro, __construct); +static PHP_METHOD(swoole_socket_coro, bind); +static PHP_METHOD(swoole_socket_coro, listen); +static PHP_METHOD(swoole_socket_coro, accept); +static PHP_METHOD(swoole_socket_coro, connect); +static PHP_METHOD(swoole_socket_coro, recv); +static PHP_METHOD(swoole_socket_coro, send); +static PHP_METHOD(swoole_socket_coro, recvfrom); +static PHP_METHOD(swoole_socket_coro, sendto); +static PHP_METHOD(swoole_socket_coro, getpeername); +static PHP_METHOD(swoole_socket_coro, getsockname); +static PHP_METHOD(swoole_socket_coro, close); +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_socket_coro, getSocket); +#endif + +static int swoole_socket_connect(socket_coro *sock, char *host, size_t l_host, int port); +static void socket_onTimeout(swTimer *timer, swTimer_node *tnode); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_construct, 0, 0, 3) + ZEND_ARG_INFO(0, domain) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, protocol) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_bind, 0, 0, 1) + ZEND_ARG_INFO(0, address) + ZEND_ARG_INFO(0, port) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_listen, 0, 0, 0) + ZEND_ARG_INFO(0, backlog) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_accept, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_recv, 0, 0, 0) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_send, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_recvfrom, 0, 0, 1) + ZEND_ARG_INFO(1, peername) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_sendto, 0, 0, 3) + ZEND_ARG_INFO(0, addr) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_socket_coro_connect, 0, 0, 1) + ZEND_ARG_INFO(0, host) + ZEND_ARG_INFO(0, port) + ZEND_ARG_INFO(0, timeout) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +static const zend_function_entry swoole_socket_coro_methods[] = +{ + PHP_ME(swoole_socket_coro, __construct, arginfo_swoole_socket_coro_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_socket_coro, bind, arginfo_swoole_socket_coro_bind, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, listen, arginfo_swoole_socket_coro_listen, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, accept, arginfo_swoole_socket_coro_accept, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, connect, arginfo_swoole_socket_coro_connect, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, recv, arginfo_swoole_socket_coro_recv, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, send, arginfo_swoole_socket_coro_send, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, recvfrom, arginfo_swoole_socket_coro_recvfrom, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, sendto, arginfo_swoole_socket_coro_sendto, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, getpeername, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_socket_coro, getsockname, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#ifdef SWOOLE_SOCKETS_SUPPORT + PHP_ME(swoole_socket_coro, getSocket, arginfo_swoole_void, ZEND_ACC_PUBLIC) +#endif + PHP_ME(swoole_socket_coro, close, arginfo_swoole_void, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static inline socket_coro * sw_socket_coro_fetch_object(zend_object *obj) +{ + return (socket_coro *) ((char *) obj - XtOffsetOf(socket_coro, std)); +} + +#define Z_SOCKET_CORO_OBJ_P(zv) sw_socket_coro_fetch_object(Z_OBJ_P(zv)); + + +static void swoole_socket_coro_free_storage(zend_object *object) +{ + socket_coro *sock = (socket_coro *) sw_socket_coro_fetch_object(object); + if (sock->fd >= 0) + { + SwooleG.main_reactor->close(SwooleG.main_reactor, sock->fd); + } + zend_object_std_dtor(&sock->std); +} + +static zend_object *swoole_socket_coro_create(zend_class_entry *ce TSRMLS_DC) +{ + socket_coro *sock = ecalloc(1, sizeof(socket_coro) + zend_object_properties_size(ce)); + zend_object_std_init(&sock->std, ce TSRMLS_CC); + object_properties_init(&sock->std, ce); + sock->std.handlers = &swoole_socket_coro_handlers; + + return &sock->std; +} + +void swoole_socket_coro_init(int module_number TSRMLS_DC) +{ + INIT_CLASS_ENTRY(swoole_socket_coro_ce, "Swoole\\Coroutine\\Socket", swoole_socket_coro_methods); + + swoole_socket_coro_class_entry_ptr = zend_register_internal_class(&swoole_socket_coro_ce TSRMLS_CC); + swoole_socket_coro_class_entry_ptr->ce_flags |= ZEND_ACC_FINAL; + swoole_socket_coro_class_entry_ptr->create_object = swoole_socket_coro_create; + swoole_socket_coro_class_entry_ptr->serialize = zend_class_serialize_deny; + swoole_socket_coro_class_entry_ptr->unserialize = zend_class_unserialize_deny; + zend_declare_property_long(swoole_socket_coro_class_entry_ptr, SW_STRL("errCode") - 1, 0, ZEND_ACC_PUBLIC TSRMLS_CC); + + memcpy(&swoole_socket_coro_handlers, zend_get_std_object_handlers(), sizeof(swoole_socket_coro_handlers)); + swoole_socket_coro_handlers.free_obj = swoole_socket_coro_free_storage; + swoole_socket_coro_handlers.clone_obj = NULL; + swoole_socket_coro_handlers.offset = XtOffsetOf(socket_coro, std); + + INIT_CLASS_ENTRY(swoole_socket_coro_exception_ce, "Swoole\\Coroutine\\Socket\\Exception", NULL); + swoole_socket_coro_exception_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_socket_coro_exception_ce, + zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\Socket", swoole_socket_coro_class_entry_ptr); + sw_zend_register_class_alias("Co\\Socket\\Exception", swoole_socket_coro_exception_class_entry_ptr); + } +} + +static int socket_onReadable(swReactor *reactor, swEvent *event) +{ + socket_coro *sock = (socket_coro *) event->socket->object; + php_context *context = &sock->context; + + zval *retval = NULL; + zval result; + + swSocketAddress client_addr; + socklen_t client_addrlen = sizeof(client_addr); + + reactor->del(reactor, sock->fd); + + if (sock->timer) + { + swTimer_del(&SwooleG.timer, sock->timer); + sock->timer = NULL; + } + + switch (sock->opcode) + { + case SW_SOCKET_OPCODE_ACCEPT: + { + int conn; +#ifdef HAVE_ACCEPT4 + conn = accept4(sock->fd, (struct sockaddr *) &client_addr, &client_addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC); +#else + conn = accept(event->fd, (struct sockaddr *) &client_addr, &client_addrlen); + if (conn >= 0) + { + swoole_fcntl_set_option(conn, 1, 1); + } +#endif + if (conn >= 0) + { + zend_object *client; + client = swoole_socket_coro_create(swoole_socket_coro_class_entry_ptr); + socket_coro *client_sock = (socket_coro *) sw_socket_coro_fetch_object(client); + ZVAL_OBJ(&result, &client_sock->std); + client_sock->fd = conn; + client_sock->domain = sock->domain; + client_sock->object = result; + // zend_object_std_dtor(&client_sock->std); + } + else + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), errno TSRMLS_CC); + ZVAL_FALSE(&result); + } + break; + } + case SW_SOCKET_OPCODE_RECV: + { + zend_string *buf = zend_string_alloc(SW_BUFFER_SIZE_BIG, 0); + int bytes = 0; + + while (1) + { + int n = recv(sock->fd, ZSTR_VAL(buf) + bytes, ZSTR_LEN(buf) - bytes - 1, MSG_DONTWAIT); + if (n < 0) + { + if (errno == EINTR) + { + continue; + } + else + { + if (bytes == 0) + { + bytes = -1; + } + break; + } + } + else if (n == 0) + { + break; + } + else + { + bytes += n; + if (sock->type != SOCK_STREAM) + { + break; + } + if (ZSTR_LEN(buf) - 1 == bytes) + { + zend_string_realloc(buf, ZSTR_LEN(buf) + SW_BUFFER_SIZE_BIG, 0); + } + continue; + } + } + if (bytes < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), errno TSRMLS_CC); + zend_string_free(buf); + ZVAL_FALSE(&result); + } + else if (bytes == 0) + { + zend_string_free(buf); + ZVAL_EMPTY_STRING(&result); + } + else + { + ZVAL_NEW_STR(&result, buf); + ZSTR_LEN(buf) = bytes; + ZSTR_VAL(buf)[bytes] = 0; + } + break; + } + case SW_SOCKET_OPCODE_RECVFROM: + { + zend_string *buf = zend_string_alloc(SW_BUFFER_SIZE_BIG, 0); + swSocketAddress info; + zval *peername = Z_REFVAL(context->coro_params); + info.len = sizeof(info.addr); + int bytes = recvfrom(sock->fd, ZSTR_VAL(buf), ZSTR_LEN(buf) - 1, 0, (struct sockaddr *) &info.addr, &info.len); + if (bytes < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), errno TSRMLS_CC); + zend_string_free(buf); + ZVAL_FALSE(&result); + } + else if (bytes == 0) + { + zend_string_free(buf); + ZVAL_EMPTY_STRING(&result); + } + else + { + array_init(peername); + if (sock->domain == AF_INET) + { + add_assoc_long(peername, "port", ntohs(info.addr.inet_v4.sin_port)); + add_assoc_string(peername, "address", inet_ntoa(info.addr.inet_v4.sin_addr)); + } + else if (sock->domain == AF_INET6) + { + add_assoc_long(peername, "port", ntohs(info.addr.inet_v6.sin6_port)); + char tmp[INET6_ADDRSTRLEN]; + if (inet_ntop(AF_INET6, &info.addr.inet_v6.sin6_addr, tmp, sizeof(tmp))) + { + sw_add_assoc_string(peername, "address", tmp, 1); + } + else + { + swoole_php_fatal_error(E_WARNING, "inet_ntop() failed."); + } + } + else if (sock->domain == AF_UNIX) + { + add_assoc_string(peername, "address", info.addr.un.sun_path); + } + ZVAL_NEW_STR(&result, buf); + ZSTR_LEN(buf) = bytes; + ZSTR_VAL(buf)[bytes] = 0; + } + break; + } + default: + break; + } + + //unbind coroutine + sock->cid = 0; + int ret = coro_resume(context, &result, &retval); + zval_ptr_dtor(&result); + if (ret == CORO_END && retval) + { + zval_ptr_dtor(retval); + } + return SW_OK; +} + +static int socket_onWritable(swReactor *reactor, swEvent *event) +{ + socket_coro *sock = (socket_coro *) event->socket->object; + php_context *context = &sock->context; + + zval *retval = NULL; + zval result; + + reactor->del(reactor, sock->fd); + + if (sock->timer) + { + swTimer_del(&SwooleG.timer, sock->timer); + sock->timer = NULL; + } + + switch (sock->opcode) + { + case SW_SOCKET_OPCODE_SEND: + { + int n = send(sock->fd, Z_STRVAL(context->coro_params), Z_STRLEN(context->coro_params), MSG_DONTWAIT); + if (n < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + ZVAL_FALSE(&result); + break; + } + else + { + ZVAL_LONG(&result, n); + } + break; + } + case SW_SOCKET_OPCODE_CONNECT: + { + socklen_t len = sizeof(SwooleG.error); + if (getsockopt(event->fd, SOL_SOCKET, SO_ERROR, &SwooleG.error, &len) < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), errno TSRMLS_CC); + ZVAL_FALSE(&result); + break; + } + if (SwooleG.error == 0) + { + ZVAL_TRUE(&result); + } + else + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), SwooleG.error TSRMLS_CC); + ZVAL_FALSE(&result); + } + break; + } + default: + break; + } + + //unbind coroutine + sock->cid = 0; + int ret = coro_resume(context, &result, &retval); + zval_ptr_dtor(&result); + if (ret == CORO_END && retval) + { + zval_ptr_dtor(retval); + } + return SW_OK; +} + +static void socket_onResolveCompleted(swAio_event *event) +{ + socket_coro *sock = (socket_coro *) event->object; + php_context *context = &sock->context; + + zval *retval = NULL; + zval result; + + if (event->error == 0) + { + int ret = swoole_socket_connect(sock, event->buf, strlen(event->buf), Z_LVAL(context->coro_params)); + if (ret == -1 && errno == EINPROGRESS) + { + efree(event->buf); + if (context->private_data) + { + int ms = (int) (Z_DVAL_P((zval *) context->private_data) * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + efree(context->private_data); + context->private_data = NULL; + } + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_WRITE) < 0) + { + goto _error; + } + else + { + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + return; + } + } + else if (ret == 0) + { + ZVAL_TRUE(&result); + sock->cid = 0; + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + } + goto _error; + } + else + { + _error: + ZVAL_FALSE(&result); + //unbind coroutine + sock->cid = 0; + int ret = coro_resume(context, &result, &retval); + if (ret == CORO_END && retval) + { + sw_zval_ptr_dtor(&retval); + } + } +} + +static void socket_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + socket_coro *sock = (socket_coro *) tnode->data; + php_context *context = &sock->context; + sock->timer = NULL; + SwooleG.main_reactor->del(SwooleG.main_reactor, sock->fd); + + zval *retval = NULL; + zval result; + if (sock->opcode == SW_SOCKET_OPCODE_RECV) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), EAGAIN TSRMLS_CC); + } + else + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, &sock->object, ZEND_STRL("errCode"), ETIMEDOUT TSRMLS_CC); + } + ZVAL_FALSE(&result); + + //unbind coroutine + sock->cid = 0; + int ret = coro_resume(context, &result, &retval); + zval_ptr_dtor(&result); + if (ret == CORO_END && retval) + { + zval_ptr_dtor(retval); + } +} + +static int swoole_socket_connect(socket_coro *sock, char *host, size_t l_host, int port) +{ + switch (sock->domain) + { + case AF_INET: + { + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + socklen_t len = sizeof(addr); + + if (!inet_pton(AF_INET, host, &addr.sin_addr)) + { + return -2; + } + else + { + return connect(sock->fd, (struct sockaddr *) &addr, len); + } + } + case AF_INET6: + { + struct sockaddr_in6 addr; + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(port); + socklen_t len = sizeof(addr); + + if (!inet_pton(AF_INET6, host, &addr.sin6_addr)) + { + return -1; + } + else + { + return connect(sock->fd, (struct sockaddr *) &addr, len); + } + } + case AF_UNIX: + { + struct sockaddr_un s_un = { 0 }; + if (l_host >= sizeof(s_un.sun_path)) + { + return -1; + } + + s_un.sun_family = AF_UNIX; + memcpy(&s_un.sun_path, host, l_host); + return connect(sock->fd, (struct sockaddr *) &s_un, (socklen_t) (XtOffsetOf(struct sockaddr_un, sun_path) + l_host)); + } + + default: + break; + } + return -3; +} + +static PHP_METHOD(swoole_socket_coro, __construct) +{ + zend_long domain, type, protocol; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_LONG(domain); + Z_PARAM_LONG(type); + Z_PARAM_LONG(protocol); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + sock->fd = socket(domain, type, protocol); + sock->domain = domain; + sock->type = type; + sock->object = *getThis(); + + if (sock->fd < 0) + { + zend_throw_exception_ex(swoole_socket_coro_exception_class_entry_ptr, errno, "Unable to create socket [%d]: %s", + strerror(errno), errno TSRMLS_CC); + RETURN_FALSE; + } + + php_swoole_check_reactor(); + if (!swReactor_handle_isset(SwooleG.main_reactor, PHP_SWOOLE_FD_SOCKET)) + { + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_SOCKET | SW_EVENT_READ, socket_onReadable); + SwooleG.main_reactor->setHandle(SwooleG.main_reactor, PHP_SWOOLE_FD_SOCKET | SW_EVENT_WRITE, socket_onWritable); + } + + swSetNonBlock(sock->fd); +} + +static PHP_METHOD(swoole_socket_coro, bind) +{ + char *address; + size_t l_address; + zend_long port = 0; + + struct sockaddr_storage sa_storage = {0}; + struct sockaddr *sock_type = (struct sockaddr*) &sa_storage; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STRING(address, l_address); + Z_PARAM_OPTIONAL + Z_PARAM_LONG(port); + ZEND_PARSE_PARAMETERS_END(); + + int retval; + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + switch (sock->domain) + { + case AF_UNIX: + { struct sockaddr_un *sa = (struct sockaddr_un *) sock_type; + sa->sun_family = AF_UNIX; + + if (l_address >= sizeof(sa->sun_path)) + { + swoole_php_error(E_WARNING, "invalid path: too long (maximum size is %d)", (int )sizeof(sa->sun_path) - 1); + RETURN_FALSE; + } + memcpy(&sa->sun_path, address, l_address); + + retval = bind(sock->fd, (struct sockaddr *) sa, + offsetof(struct sockaddr_un, sun_path) + l_address); + break; + } + + case AF_INET: + { + struct sockaddr_in *sa = (struct sockaddr_in *) sock_type; + sa->sin_family = AF_INET; + sa->sin_port = htons((unsigned short) port); + if (!inet_aton(address, &sa->sin_addr)) + { + RETURN_FALSE; + } + retval = bind(sock->fd, (struct sockaddr *) sa, sizeof(struct sockaddr_in)); + break; + } + + case AF_INET6: + { + struct sockaddr_in6 *sa = (struct sockaddr_in6 *) sock_type; + sa->sin6_family = AF_INET6; + sa->sin6_port = htons((unsigned short) port); + + if (!inet_pton(AF_INET6, address, &sa->sin6_addr)) + { + RETURN_FALSE; + } + retval = bind(sock->fd, (struct sockaddr *)sa, sizeof(struct sockaddr_in6)); + break; + } + default: + RETURN_FALSE; + } + + if (retval != 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + RETURN_TRUE; +} + +static PHP_METHOD(swoole_socket_coro, listen) +{ + zend_long backlog = 0; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(backlog); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (listen(sock->fd, backlog) != 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_socket_coro, accept) +{ + coro_check(TSRMLS_C); + + double timeout = -1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_DOUBLE(timeout); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_READ) < 0) + { + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + + php_context *context = &sock->context; + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; + sock->opcode = SW_SOCKET_OPCODE_ACCEPT; + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + } + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_socket_coro, recv) +{ + coro_check(TSRMLS_C); + + double timeout = -1; + + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_DOUBLE(timeout); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_READ) < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + + php_context *context = &sock->context; + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; + sock->opcode = SW_SOCKET_OPCODE_RECV; + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + } + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_socket_coro, recvfrom) +{ + coro_check(TSRMLS_C); + + zval *peername; + double timeout = -1; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ZVAL(peername); + Z_PARAM_OPTIONAL + Z_PARAM_DOUBLE(timeout); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_READ) < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + + php_context *context = &sock->context; + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; + context->coro_params = *peername; + sock->opcode = SW_SOCKET_OPCODE_RECVFROM; + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + } + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_socket_coro, send) +{ + coro_check(TSRMLS_C); + + double timeout = -1; + zval *data; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ZVAL(data); + Z_PARAM_OPTIONAL + Z_PARAM_DOUBLE(timeout); + ZEND_PARSE_PARAMETERS_END(); + + if (Z_TYPE_P(data) != IS_STRING) + { + RETURN_FALSE; + } + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + int ret = send(sock->fd, Z_STRVAL_P(data), Z_STRLEN_P(data), MSG_DONTWAIT); + if (ret < 0) + { + if (errno == EAGAIN) + { + goto _yield; + } + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + else + { + RETURN_LONG(ret); + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + + _yield: + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_WRITE) < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + php_context *context = &sock->context; + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; + context->coro_params = *data; + sock->opcode = SW_SOCKET_OPCODE_SEND; + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + } + + coro_save(context); + coro_yield(); +} + +static PHP_METHOD(swoole_socket_coro, sendto) +{ + char *data; + size_t l_data; + char *addr; + size_t l_addr; + zend_long port = 0; + + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STRING(addr, l_addr); + Z_PARAM_LONG(port); + Z_PARAM_STRING(data, l_data); + ZEND_PARSE_PARAMETERS_END(); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + + int ret; + if (sock->domain == AF_INET) + { + ret = swSocket_udp_sendto(sock->fd, addr, port, data, l_data); + } + else if (sock->domain == AF_INET6) + { + ret = swSocket_udp_sendto6(sock->fd, addr, port, data, l_data); + } + else if (sock->domain == AF_UNIX) + { + ret = swSocket_unix_sendto(sock->fd, addr, data, l_data); + } + else + { + RETURN_FALSE; + } + + if (ret < 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + else + { + RETURN_LONG(ret); + } +} + +static PHP_METHOD(swoole_socket_coro, close) +{ + coro_check(TSRMLS_C); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (sock->fd < 0) + { + RETURN_FALSE; + } + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + int ret = SwooleG.main_reactor->close(SwooleG.main_reactor, sock->fd); + sock->fd = -1; + SW_CHECK_RETURN(ret); +} + +static PHP_METHOD(swoole_socket_coro, getsockname) +{ + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + array_init(return_value); + + swSocketAddress info; + char addr_str[INET6_ADDRSTRLEN + 1]; + + if (getsockname(sock->fd, (struct sockaddr *) &info.addr.inet_v4, &info.len) != 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + switch (sock->domain) + { + case AF_INET6: + inet_ntop(AF_INET6, &info.addr.inet_v6.sin6_addr, addr_str, INET6_ADDRSTRLEN); + add_assoc_string(return_value, "address", addr_str); + add_assoc_long(return_value, "port", htons(info.addr.inet_v6.sin6_port)); + break; + case AF_INET: + inet_ntop(AF_INET, &info.addr.inet_v4.sin_addr, addr_str, INET_ADDRSTRLEN); + add_assoc_string(return_value, "address", addr_str); + add_assoc_long(return_value, "port", htons(info.addr.inet_v4.sin_port)); + break; + case AF_UNIX: + add_assoc_string(return_value, "address", info.addr.un.sun_path); + break; + default: + swoole_php_error(E_WARNING, "Unsupported address family %d", sock->domain); + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_socket_coro, getpeername) +{ + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + array_init(return_value); + + swSocketAddress info; + char addr_str[INET6_ADDRSTRLEN + 1]; + + if (getpeername(sock->fd, (struct sockaddr *) &info.addr.inet_v4, &info.len) != 0) + { + zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), errno TSRMLS_CC); + RETURN_FALSE; + } + + switch (sock->domain) + { + case AF_INET6: + inet_ntop(AF_INET6, &info.addr.inet_v6.sin6_addr, addr_str, INET6_ADDRSTRLEN); + add_assoc_string(return_value, "address", addr_str); + add_assoc_long(return_value, "port", htons(info.addr.inet_v6.sin6_port)); + break; + case AF_INET: + inet_ntop(AF_INET, &info.addr.inet_v4.sin_addr, addr_str, INET_ADDRSTRLEN); + add_assoc_string(return_value, "address", addr_str); + add_assoc_long(return_value, "port", htons(info.addr.inet_v4.sin_port)); + break; + case AF_UNIX: + add_assoc_string(return_value, "address", info.addr.un.sun_path); + break; + default: + swoole_php_error(E_WARNING, "Unsupported address family %d", sock->domain); + RETURN_FALSE; + } +} + +static PHP_METHOD(swoole_socket_coro, connect) +{ + coro_check(TSRMLS_C); + + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + char *host; + size_t l_host; + zend_long port = 0; + double timeout = SW_CLIENT_DEFAULT_TIMEOUT; + + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STRING(host, l_host); + Z_PARAM_OPTIONAL + Z_PARAM_LONG(port); + Z_PARAM_DOUBLE(timeout); + ZEND_PARSE_PARAMETERS_END(); + + if (sock->domain == AF_INET6 || sock->domain == AF_INET) + { + if (ZEND_NUM_ARGS() == 1) + { + swoole_php_error(E_WARNING, "Socket of type AF_INET/AF_INET6 requires port argument"); + RETURN_FALSE; + } + else if (port == 0 || port >= 65536) + { + swoole_php_error(E_WARNING, "Invalid port argument[%d]", port); + RETURN_FALSE; + } + } + if (unlikely(sock->cid && sock->cid != sw_get_current_cid())) + { + swoole_php_fatal_error(E_WARNING, "socket has already been bound to another coroutine."); + RETURN_FALSE; + } + + int retval = swoole_socket_connect(sock, host, l_host, port); + if (retval == -2) + { + swAio_event ev; + bzero(&ev, sizeof(swAio_event)); + + ev.nbytes = l_host < SW_IP_MAX_LENGTH ? SW_IP_MAX_LENGTH : l_host + 1; + ev.buf = emalloc(ev.nbytes); + if (!ev.buf) + { + swWarn("malloc failed."); + RETURN_FALSE; + } + + memcpy(ev.buf, host, l_host); + ((char *) ev.buf)[l_host] = 0; + ev.flags = sock->domain; + ev.type = SW_AIO_GETHOSTBYNAME; + ev.object = sock; + ev.callback = socket_onResolveCompleted; + + php_swoole_check_aio(); + + if (swAio_dispatch(&ev) < 0) + { + efree(ev.buf); + RETURN_FALSE + } + else + { + ZVAL_LONG(&sock->context.coro_params, port); + zval *ztimeout; + if (timeout > 0) + { + ztimeout = emalloc(sizeof(zval)); + ZVAL_DOUBLE(ztimeout, timeout); + sock->context.private_data = ztimeout; + } + else + { + sock->context.private_data = NULL; + } + goto _yield; + } + } + else if (retval == -1) + { + if (errno == EINPROGRESS) + { + if (SwooleG.main_reactor->add(SwooleG.main_reactor, sock->fd, PHP_SWOOLE_FD_SOCKET | SW_EVENT_WRITE) < 0) + { + goto _error; + } + + swConnection *_socket = swReactor_get(SwooleG.main_reactor, sock->fd); + _socket->object = sock; + + if (timeout > 0) + { + int ms = (int) (timeout * 1000); + php_swoole_check_timer(ms); + sock->timer = SwooleG.timer.add(&SwooleG.timer, ms, 0, sock, socket_onTimeout); + } + + php_context *context; + _yield: context = &sock->context; + context->state = SW_CORO_CONTEXT_RUNNING; + context->onTimeout = NULL; + sock->opcode = SW_SOCKET_OPCODE_CONNECT; + + coro_save(context); + coro_yield(); + } + else + { + _error: zend_update_property_long(swoole_socket_coro_class_entry_ptr, getThis(), ZEND_STRL("errCode"), + errno TSRMLS_CC); + } + } + else if (retval == 0) + { + RETURN_TRUE; + } + else + { + RETURN_FALSE; + } +} + +#ifdef SWOOLE_SOCKETS_SUPPORT +static PHP_METHOD(swoole_socket_coro, getSocket) +{ + socket_coro *sock = (socket_coro *) Z_SOCKET_CORO_OBJ_P(getThis()); + if (sock->fd < 0) + { + RETURN_FALSE; + } + php_socket *socket_object = swoole_convert_to_socket(sock->fd); + if (!socket_object) + { + RETURN_FALSE; + } + SW_ZEND_REGISTER_RESOURCE(return_value, (void * ) socket_object, php_sockets_le_socket()); + zval *zsocket = sw_zval_dup(return_value); + sw_zval_add_ref(&zsocket); + sock->resource = zsocket; +} +#endif +#endif diff --git a/vendor/swoole/swoole_table.c b/vendor/swoole/swoole_table.c new file mode 100755 index 0000000..603519a --- /dev/null +++ b/vendor/swoole/swoole_table.c @@ -0,0 +1,935 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +#ifdef HAVE_PCRE +#include <ext/spl/spl_iterators.h> +#endif + +#include "include/table.h" + +static zend_class_entry swoole_table_ce; +static zend_class_entry *swoole_table_class_entry_ptr; + +static zend_class_entry swoole_table_row_ce; +static zend_class_entry *swoole_table_row_class_entry_ptr; + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_construct, 0, 0, 1) + ZEND_ARG_INFO(0, table_size) + ZEND_ARG_INFO(0, conflict_proportion) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_column, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_set, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_ARRAY_INFO(0, value, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_get, 0, 0, 1) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, field) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_exist, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_offsetExists, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, offset) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_offsetUnset, 0, 0, 1) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_del, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_incr, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, column) + ZEND_ARG_INFO(0, incrby) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_table_decr, 0, 0, 2) + ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(0, column) + ZEND_ARG_INFO(0, decrby) +ZEND_END_ARG_INFO() + +static PHP_METHOD(swoole_table, __construct); +static PHP_METHOD(swoole_table, column); +static PHP_METHOD(swoole_table, create); +static PHP_METHOD(swoole_table, set); +static PHP_METHOD(swoole_table, get); +static PHP_METHOD(swoole_table, del); +static PHP_METHOD(swoole_table, exist); +static PHP_METHOD(swoole_table, incr); +static PHP_METHOD(swoole_table, decr); +static PHP_METHOD(swoole_table, count); +static PHP_METHOD(swoole_table, destroy); +static PHP_METHOD(swoole_table, getMemorySize); +static PHP_METHOD(swoole_table, offsetExists); +static PHP_METHOD(swoole_table, offsetGet); +static PHP_METHOD(swoole_table, offsetSet); +static PHP_METHOD(swoole_table, offsetUnset); + +#ifdef HAVE_PCRE +static PHP_METHOD(swoole_table, rewind); +static PHP_METHOD(swoole_table, next); +static PHP_METHOD(swoole_table, current); +static PHP_METHOD(swoole_table, key); +static PHP_METHOD(swoole_table, valid); +#endif + +static PHP_METHOD(swoole_table_row, offsetExists); +static PHP_METHOD(swoole_table_row, offsetGet); +static PHP_METHOD(swoole_table_row, offsetSet); +static PHP_METHOD(swoole_table_row, offsetUnset); +static PHP_METHOD(swoole_table_row, __destruct); + +static const zend_function_entry swoole_table_methods[] = +{ + PHP_ME(swoole_table, __construct, arginfo_swoole_table_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(swoole_table, column, arginfo_swoole_table_column, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, create, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, destroy, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, set, arginfo_swoole_table_set, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, get, arginfo_swoole_table_get, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, count, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, del, arginfo_swoole_table_del, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, exist, arginfo_swoole_table_exist, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, incr, arginfo_swoole_table_incr, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, decr, arginfo_swoole_table_decr, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, getMemorySize, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, offsetExists, arginfo_swoole_table_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, offsetGet, arginfo_swoole_table_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, offsetSet, arginfo_swoole_table_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, offsetUnset, arginfo_swoole_table_offsetUnset, ZEND_ACC_PUBLIC) + PHP_FALIAS(__sleep, swoole_unsupport_serialize, NULL) + PHP_FALIAS(__wakeup, swoole_unsupport_serialize, NULL) +#ifdef HAVE_PCRE + PHP_ME(swoole_table, rewind, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, next, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, current, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, key, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table, valid, arginfo_swoole_table_void, ZEND_ACC_PUBLIC) +#endif + PHP_FE_END +}; + +static const zend_function_entry swoole_table_row_methods[] = +{ + PHP_ME(swoole_table_row, offsetExists, arginfo_swoole_table_offsetExists, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table_row, offsetGet, arginfo_swoole_table_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table_row, offsetSet, arginfo_swoole_table_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table_row, offsetUnset, arginfo_swoole_table_offsetUnset, ZEND_ACC_PUBLIC) + PHP_ME(swoole_table_row, __destruct, arginfo_swoole_table_void, ZEND_ACC_PUBLIC | ZEND_ACC_DTOR) + PHP_FE_END +}; + +static inline void php_swoole_table_row2array(swTable *table, swTableRow *row, zval *return_value) +{ + array_init(return_value); + + swTableColumn *col = NULL; + swTable_string_length_t vlen = 0; + double dval = 0; + int64_t lval = 0; + char *k; + + while(1) + { + col = swHashMap_each(table->columns, &k); + if (col == NULL) + { + break; + } + if (col->type == SW_TABLE_STRING) + { + memcpy(&vlen, row->data + col->index, sizeof(swTable_string_length_t)); + sw_add_assoc_stringl_ex(return_value, col->name->str, col->name->length + 1, row->data + col->index + sizeof(swTable_string_length_t), vlen, 1); + } + else if (col->type == SW_TABLE_FLOAT) + { + memcpy(&dval, row->data + col->index, sizeof(dval)); + sw_add_assoc_double_ex(return_value, col->name->str, col->name->length + 1, dval); + } + else + { + switch (col->type) + { + case SW_TABLE_INT8: + memcpy(&lval, row->data + col->index, 1); + sw_add_assoc_long_ex(return_value, col->name->str, col->name->length + 1, (int8_t) lval); + break; + case SW_TABLE_INT16: + memcpy(&lval, row->data + col->index, 2); + sw_add_assoc_long_ex(return_value, col->name->str, col->name->length + 1, (int16_t) lval); + break; + case SW_TABLE_INT32: + memcpy(&lval, row->data + col->index, 4); + sw_add_assoc_long_ex(return_value, col->name->str, col->name->length + 1, (int32_t) lval); + break; + default: + memcpy(&lval, row->data + col->index, 8); + sw_add_assoc_long_ex(return_value, col->name->str, col->name->length + 1, lval); + break; + } + } + } +} + +static inline void php_swoole_table_get_field_value(swTable *table, swTableRow *row, zval *return_value, char *field, uint16_t field_len) +{ + swTable_string_length_t vlen = 0; + double dval = 0; + int64_t lval = 0; + + swTableColumn *col = swHashMap_find(table->columns, field, field_len); + if (!col) + { + ZVAL_BOOL(return_value, 0); + return; + } + if (col->type == SW_TABLE_STRING) + { + memcpy(&vlen, row->data + col->index, sizeof(swTable_string_length_t)); + SW_ZVAL_STRINGL(return_value, row->data + col->index + sizeof(swTable_string_length_t), vlen, 1); + } + else if (col->type == SW_TABLE_FLOAT) + { + memcpy(&dval, row->data + col->index, sizeof(dval)); + ZVAL_DOUBLE(return_value, dval); + } + else + { + switch (col->type) + { + case SW_TABLE_INT8: + memcpy(&lval, row->data + col->index, 1); + ZVAL_LONG(return_value, (int8_t) lval); + break; + case SW_TABLE_INT16: + memcpy(&lval, row->data + col->index, 2); + ZVAL_LONG(return_value, (int16_t) lval); + break; + case SW_TABLE_INT32: + memcpy(&lval, row->data + col->index, 4); + ZVAL_LONG(return_value, (int32_t) lval); + break; + default: + memcpy(&lval, row->data + col->index, 8); + ZVAL_LONG(return_value, lval); + break; + } + } +} + +void swoole_table_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_table_ce, "swoole_table", "Swoole\\Table", swoole_table_methods); + swoole_table_class_entry_ptr = zend_register_internal_class(&swoole_table_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_table, "Swoole\\Table"); + zend_class_implements(swoole_table_class_entry_ptr TSRMLS_CC, 1, zend_ce_arrayaccess); + +#ifdef HAVE_PCRE + zend_class_implements(swoole_table_class_entry_ptr TSRMLS_CC, 2, spl_ce_Iterator, spl_ce_Countable); +#endif + + zend_declare_class_constant_long(swoole_table_class_entry_ptr, SW_STRL("TYPE_INT")-1, SW_TABLE_INT TSRMLS_CC); + zend_declare_class_constant_long(swoole_table_class_entry_ptr, SW_STRL("TYPE_STRING")-1, SW_TABLE_STRING TSRMLS_CC); + zend_declare_class_constant_long(swoole_table_class_entry_ptr, SW_STRL("TYPE_FLOAT")-1, SW_TABLE_FLOAT TSRMLS_CC); + + SWOOLE_INIT_CLASS_ENTRY(swoole_table_row_ce, "swoole_table_row", "Swoole\\Table\\Row", swoole_table_row_methods); + swoole_table_row_class_entry_ptr = zend_register_internal_class(&swoole_table_row_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_table_row, "Swoole\\Table\\Row"); + zend_class_implements(swoole_table_row_class_entry_ptr TSRMLS_CC, 1, zend_ce_arrayaccess); + + zend_declare_property_null(swoole_table_row_class_entry_ptr, ZEND_STRL("key"), ZEND_ACC_PUBLIC TSRMLS_CC); + zend_declare_property_null(swoole_table_row_class_entry_ptr, ZEND_STRL("value"), ZEND_ACC_PUBLIC TSRMLS_CC); +} + +void swoole_table_column_free(swTableColumn *col) +{ + swString_free(col->name); +} + +PHP_METHOD(swoole_table, __construct) +{ + long table_size; + double conflict_proportion = SW_TABLE_CONFLICT_PROPORTION; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|d", &table_size, &conflict_proportion) == FAILURE) + { + RETURN_FALSE; + } + + swTable *table = swTable_new(table_size, conflict_proportion); + if (table == NULL) + { + zend_throw_exception(swoole_exception_class_entry_ptr, "global memory allocation failure.", SW_ERROR_MALLOC_FAIL TSRMLS_CC); + RETURN_FALSE; + } + swoole_set_object(getThis(), table); +} + +PHP_METHOD(swoole_table, column) +{ + char *name; + zend_size_t len; + long type; + long size = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &name, &len, &type, &size) == FAILURE) + { + RETURN_FALSE; + } + if (type == SW_TABLE_STRING && size < 1) + { + swoole_php_fatal_error(E_WARNING, "the length of string type values has to be more than zero."); + RETURN_FALSE; + } + //default int32 + if (type == SW_TABLE_INT && size < 1) + { + size = 4; + } + swTable *table = swoole_get_object(getThis()); + if (table->memory) + { + swoole_php_fatal_error(E_WARNING, "can't add column after the creation of swoole table."); + RETURN_FALSE; + } + swTableColumn_add(table, name, len, type, size); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_table, create) +{ + swTable *table = swoole_get_object(getThis()); + if (table->memory) + { + swoole_php_fatal_error(E_WARNING, "the swoole table has been created already."); + RETURN_FALSE; + } + if (swTable_create(table) < 0) + { + swoole_php_fatal_error(E_ERROR, "unable to allocate memory."); + RETURN_FALSE; + } + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("size"), table->size TSRMLS_CC); + zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("memorySize"), table->memory_size TSRMLS_CC); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_table, destroy) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTable_free(table); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_table, set) +{ + zval *array; + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &key, &keylen, &array) == FAILURE) + { + RETURN_FALSE; + } + + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTableRow *row = swTableRow_set(table, key, keylen, &_rowlock); + if (!row) + { + swTableRow_unlock(_rowlock); + swoole_php_error(E_WARNING, "unable to allocate memory."); + RETURN_FALSE; + } + + swTableColumn *col; + zval *v; + char *k; + uint32_t klen; + int ktype; + HashTable *_ht = Z_ARRVAL_P(array); + + SW_HASHTABLE_FOREACH_START2(_ht, k, klen, ktype, v) + { + col = swTableColumn_get(table, k, klen); + if (k == NULL || col == NULL) + { + continue; + } + else if (col->type == SW_TABLE_STRING) + { + convert_to_string(v); + swTableRow_set_value(row, col, Z_STRVAL_P(v), Z_STRLEN_P(v)); + } + else if (col->type == SW_TABLE_FLOAT) + { + convert_to_double(v); + swTableRow_set_value(row, col, &Z_DVAL_P(v), 0); + } + else + { + convert_to_long(v); + swTableRow_set_value(row, col, &Z_LVAL_P(v), 0); + } + } + (void) ktype; + SW_HASHTABLE_FOREACH_END(); + swTableRow_unlock(_rowlock); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_table, offsetSet) +{ + ZEND_MN(swoole_table_set)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(swoole_table, incr) +{ + char *key; + zend_size_t key_len; + char *col; + zend_size_t col_len; + zval* incrby = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z", &key, &key_len, &col, &col_len, &incrby) == FAILURE) + { + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTableRow *row = swTableRow_set(table, key, key_len, &_rowlock); + if (!row) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "unable to allocate memory."); + RETURN_FALSE; + } + + swTableColumn *column; + column = swTableColumn_get(table, col, col_len); + if (column == NULL) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "column[%s] does not exist.", col); + RETURN_FALSE; + } + else if (column->type == SW_TABLE_STRING) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "can't execute 'incr' on a string type column."); + RETURN_FALSE; + } + else if (column->type == SW_TABLE_FLOAT) + { + double set_value = 0; + memcpy(&set_value, row->data + column->index, sizeof(set_value)); + if (incrby) + { + convert_to_double(incrby); + set_value += Z_DVAL_P(incrby); + } + else + { + set_value += 1; + } + swTableRow_set_value(row, column, &set_value, 0); + RETVAL_DOUBLE(set_value); + } + else + { + int64_t set_value = 0; + memcpy(&set_value, row->data + column->index, column->size); + if (incrby) + { + convert_to_long(incrby); + set_value += Z_LVAL_P(incrby); + } + else + { + set_value += 1; + } + swTableRow_set_value(row, column, &set_value, 0); + RETVAL_LONG(set_value); + } + swTableRow_unlock(_rowlock); +} + +static PHP_METHOD(swoole_table, decr) +{ + char *key; + zend_size_t key_len; + char *col; + zend_size_t col_len; + zval *decrby = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z", &key, &key_len, &col, &col_len, &decrby) == FAILURE) + { + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTableRow *row = swTableRow_set(table, key, key_len, &_rowlock); + if (!row) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "unable to allocate memory."); + RETURN_FALSE; + } + + swTableColumn *column; + column = swTableColumn_get(table, col, col_len); + if (column == NULL) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "column[%s] does not exist.", col); + RETURN_FALSE; + } + else if (column->type == SW_TABLE_STRING) + { + swTableRow_unlock(_rowlock); + swoole_php_fatal_error(E_WARNING, "can't execute 'decr' on a string type column."); + RETURN_FALSE; + } + else if (column->type == SW_TABLE_FLOAT) + { + double set_value = 0; + memcpy(&set_value, row->data + column->index, sizeof(set_value)); + if (decrby) + { + convert_to_double(decrby); + set_value -= Z_DVAL_P(decrby); + } + else + { + set_value -= 1; + } + swTableRow_set_value(row, column, &set_value, 0); + RETVAL_DOUBLE(set_value); + } + else + { + int64_t set_value = 0; + memcpy(&set_value, row->data + column->index, column->size); + if (decrby) + { + convert_to_long(decrby); + set_value -= Z_LVAL_P(decrby); + } + else + { + set_value -= 1; + } + swTableRow_set_value(row, column, &set_value, 0); + RETVAL_LONG(set_value); + } + swTableRow_unlock(_rowlock); +} + +static PHP_METHOD(swoole_table, get) +{ + char *key; + zend_size_t keylen; + + char *field = NULL; + zend_size_t field_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &key, &keylen, &field, &field_len) == FAILURE) + { + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTableRow *row = swTableRow_get(table, key, keylen, &_rowlock); + if (!row) + { + RETVAL_FALSE; + } + else if (field && field_len > 0) + { + php_swoole_table_get_field_value(table, row, return_value, field, (uint16_t) field_len); + } + else + { + php_swoole_table_row2array(table, row, return_value); + } + swTableRow_unlock(_rowlock); +} + +static PHP_METHOD(swoole_table, offsetGet) +{ + char *key; + zend_size_t keylen; + + char *field = NULL; + zend_size_t field_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &key, &keylen, &field, &field_len) == FAILURE) + { + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "Must create table first."); + RETURN_FALSE; + } + + zval *value; + SW_MAKE_STD_ZVAL(value); + + swTableRow *row = swTableRow_get(table, key, keylen, &_rowlock); + if (!row) + { + array_init(value); + } + else + { + php_swoole_table_row2array(table, row, value); + } + swTableRow_unlock(_rowlock); + + object_init_ex(return_value, swoole_table_row_class_entry_ptr); + zend_update_property(swoole_table_row_class_entry_ptr, return_value, ZEND_STRL("value"), value TSRMLS_CC); + zend_update_property_stringl(swoole_table_row_class_entry_ptr, return_value, ZEND_STRL("key"), key, keylen TSRMLS_CC); + sw_zval_ptr_dtor(&value); + swoole_set_object(return_value, table); +} + +static PHP_METHOD(swoole_table, exist) +{ + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &keylen) == FAILURE) + { + RETURN_FALSE; + } + + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + swTableRow *_rowlock = NULL; + swTableRow *row = swTableRow_get(table, key, keylen, &_rowlock); + swTableRow_unlock(_rowlock); + if (!row) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +static PHP_METHOD(swoole_table, offsetExists) +{ + ZEND_MN(swoole_table_exist)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(swoole_table, del) +{ + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &keylen) == FAILURE) + { + RETURN_FALSE; + } + + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + SW_CHECK_RETURN(swTableRow_del(table, key, keylen)); +} + +static PHP_METHOD(swoole_table, offsetUnset) +{ + ZEND_MN(swoole_table_del)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(swoole_table, count) +{ + #define COUNT_NORMAL 0 + #define COUNT_RECURSIVE 1 + + long mode = COUNT_NORMAL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) + { + return; + } + + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + + if (mode == COUNT_NORMAL) + { + RETURN_LONG(table->row_num); + } + else + { + RETURN_LONG(table->row_num * table->column_num); + } +} + +static PHP_METHOD(swoole_table, getMemorySize) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + RETURN_LONG(swTable_get_memory_size(table)); + } + else + { + RETURN_LONG(table->memory_size); + } +} + +#ifdef HAVE_PCRE +static PHP_METHOD(swoole_table, rewind) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + swTable_iterator_rewind(table); + swTable_iterator_forward(table); +} + +static PHP_METHOD(swoole_table, current) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + swTableRow *row = swTable_iterator_current(table); + swTableRow_lock(row); + php_swoole_table_row2array(table, row, return_value); + swTableRow_unlock(row); +} + +static PHP_METHOD(swoole_table, key) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + swTableRow *row = swTable_iterator_current(table); + swTableRow_lock(row); + SW_RETVAL_STRING(row->key, 1); + swTableRow_unlock(row); +} + +static PHP_METHOD(swoole_table, next) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + swTable_iterator_forward(table); +} + +static PHP_METHOD(swoole_table, valid) +{ + swTable *table = swoole_get_object(getThis()); + if (!table->memory) + { + swoole_php_fatal_error(E_ERROR, "the swoole table does not exist."); + RETURN_FALSE; + } + swTableRow *row = swTable_iterator_current(table); + RETURN_BOOL(row != NULL); +} +#endif + +static PHP_METHOD(swoole_table_row, offsetExists) +{ + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &keylen) == FAILURE) + { + RETURN_FALSE; + } + + zval *value = sw_zend_read_property(swoole_table_row_class_entry_ptr, getThis(), SW_STRL("value")-1, 0 TSRMLS_CC); + RETURN_BOOL(zend_hash_str_exists(Z_ARRVAL_P(value), key, keylen) == SUCCESS); +} + +static PHP_METHOD(swoole_table_row, offsetGet) +{ + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &key, &keylen) == FAILURE) + { + RETURN_FALSE; + } + + zval *value = sw_zend_read_property(swoole_table_row_class_entry_ptr, getThis(), SW_STRL("value")-1, 0 TSRMLS_CC); + zval *zvalue; + if (sw_zend_hash_find(Z_ARRVAL_P(value), key, keylen + 1, (void **) &zvalue) == FAILURE) + { + RETURN_FALSE; + } + RETURN_ZVAL(zvalue, 1, 0); +} + +static PHP_METHOD(swoole_table_row, offsetSet) +{ + zval *value; + char *key; + zend_size_t keylen; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &key, &keylen, &value) == FAILURE) + { + RETURN_FALSE; + } + + swTable *table = swoole_get_object(getThis()); + if (table == NULL || table->memory == NULL) + { + swoole_php_fatal_error(E_ERROR, "Must create table first."); + RETURN_FALSE; + } + + zval *prop_key = sw_zend_read_property(swoole_table_row_class_entry_ptr, getThis(), SW_STRL("key")-1, 0 TSRMLS_CC); + + swTableRow *_rowlock = NULL; + swTableRow *row = swTableRow_set(table, Z_STRVAL_P(prop_key), Z_STRLEN_P(prop_key), &_rowlock); + if (!row) + { + swTableRow_unlock(_rowlock); + swoole_php_error(E_WARNING, "Unable to allocate memory."); + RETURN_FALSE; + } + + swTableColumn *col; + col = swTableColumn_get(table, key, keylen); + if (col->type == SW_TABLE_STRING) + { + convert_to_string(value); + swTableRow_set_value(row, col, Z_STRVAL_P(value), Z_STRLEN_P(value)); + } + else if (col->type == SW_TABLE_FLOAT) + { + convert_to_double(value); + swTableRow_set_value(row, col, &Z_DVAL_P(value), 0); + } + else + { + convert_to_long(value); + swTableRow_set_value(row, col, &Z_LVAL_P(value), 0); + } + swTableRow_unlock(_rowlock); + + zval *prop_value = sw_zend_read_property(swoole_table_row_class_entry_ptr, getThis(), SW_STRL("value")-1, 0 TSRMLS_CC); + sw_zend_hash_update(Z_ARRVAL_P(prop_value), key, keylen, value, sizeof(zval *), NULL); + RETURN_TRUE; +} + +static PHP_METHOD(swoole_table_row, offsetUnset) +{ + swoole_php_fatal_error(E_WARNING, "not supported."); + RETURN_FALSE; +} + +static PHP_METHOD(swoole_table_row, __destruct) +{ + swoole_set_object(getThis(), NULL); +} diff --git a/vendor/swoole/swoole_timer.c b/vendor/swoole/swoole_timer.c new file mode 100755 index 0000000..b0cd852 --- /dev/null +++ b/vendor/swoole/swoole_timer.c @@ -0,0 +1,552 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2015 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ + +#include "php_swoole.h" +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +enum swoole_timer_type +{ + SW_TIMER_TICK, SW_TIMER_AFTER, +}; + +typedef struct _swTimer_callback +{ + zval* callback; + zval* data; +#if PHP_MAJOR_VERSION >= 7 + zval _callback; + zval _data; +#endif +#ifdef SW_COROUTINE + zend_fcall_info_cache *func_cache; +#endif + int interval; + int type; +} swTimer_callback; + +#ifdef SW_COROUTINE +int php_swoole_del_timer_coro(swTimer_node *tnode TSRMLS_DC); +#endif +static int php_swoole_del_timer(swTimer_node *tnode TSRMLS_DC); + +void php_swoole_clear_all_timer() +{ + if (!SwooleG.timer.map) + { + return; + } + SWOOLE_GET_TSRMLS; + uint64_t timer_id; + //kill user process + while (1) + { + swTimer_node *tnode = swHashMap_each_int(SwooleG.timer.map, &timer_id); + if (tnode == NULL) + { + break; + } + if (tnode->type != SW_TIMER_TYPE_PHP) + { + continue; + } + php_swoole_del_timer(tnode TSRMLS_CC); + swTimer_del(&SwooleG.timer, tnode); + } +} + +int php_swoole_add_timer_coro(int ms, int cli_fd, long *timeout_id, void* param, swLinkedList_node **node TSRMLS_DC) //void * +{ + if (SwooleG.serv && swIsMaster()) + { + swoole_php_fatal_error(E_WARNING, "cannot use timer in master process."); + return SW_ERR; + } + if (ms > SW_TIMER_MAX_VALUE) + { + swoole_php_fatal_error(E_WARNING, "The given parameters is too big."); + return SW_ERR; + } + if (ms <= 0) + { + swoole_php_fatal_error(E_WARNING, "Timer must be greater than 0"); + return SW_ERR; + } + + if (!swIsTaskWorker()) + { + php_swoole_check_reactor(); + } + + php_swoole_check_timer(ms); + + if (unlikely(SwooleWG.delayed_coro_timeout_list == NULL)) + { + SwooleWG.delayed_coro_timeout_list = swLinkedList_new(2, NULL); + if (SwooleWG.delayed_coro_timeout_list == NULL) + { + swoole_php_fatal_error(E_WARNING, "New swLinkedList failed."); + return SW_ERR; + } + } + + swTimer_coro_callback *scc = emalloc(sizeof(swTimer_coro_callback)); + scc->ms = ms; + scc->data = param; + scc->cli_fd = cli_fd; + scc->timeout_id = timeout_id; + + if (swLinkedList_append(SwooleWG.delayed_coro_timeout_list, (void *)scc) == SW_ERR) + { + efree(scc); + swoole_php_fatal_error(E_WARNING, "Append to swTimer_coro_callback_list failed."); + return SW_ERR; + } + if (node != NULL) + { + *node = SwooleWG.delayed_coro_timeout_list->tail; + } + return SW_OK; +} + +int php_swoole_clear_timer_coro(long id TSRMLS_DC) +{ + if (id < 0) + { + swoole_php_error(E_WARNING, "no timer id"); + return SW_ERR; + } + + if (!SwooleG.timer.set) + { + swoole_php_error(E_WARNING, "no timer"); + return SW_ERR; + } + + swTimer_node *tnode = swTimer_get(&SwooleG.timer, id); + if (tnode == NULL) + { + swoole_php_error(E_WARNING, "timer#%ld is not found.", id); + return SW_ERR; + } + + //current timer, cannot remove here. + if (tnode->id == SwooleG.timer._current_id) + { + tnode->remove = 1; + return SW_OK; + } + if (php_swoole_del_timer_coro(tnode TSRMLS_CC) < 0) + { + return SW_ERR; + } + if (swTimer_del(&SwooleG.timer, tnode) < 0) + { + return SW_ERR; + } + else + { + return SW_OK; + } +} + +int php_swoole_del_timer_coro(swTimer_node *tnode TSRMLS_DC) +{ + swTimer_coro_callback *scc = tnode->data; + if (!scc) + { + return SW_ERR; + } + efree(scc); + return SW_OK; +} + +long php_swoole_add_timer(int ms, zval *callback, zval *param, int persistent TSRMLS_DC) +{ + if (ms > SW_TIMER_MAX_VALUE) + { + swoole_php_fatal_error(E_WARNING, "The given parameters is too big."); + return SW_ERR; + } + if (ms <= 0) + { + swoole_php_fatal_error(E_WARNING, "Timer must be greater than 0"); + return SW_ERR; + } + + char *func_name = NULL; + + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) + { + efree(func_cache); + efree(func_name); + swoole_php_fatal_error(E_ERROR, "Function '%s' is not callable", func_name); + return SW_ERR; + } + efree(func_name); + + if (!swIsTaskWorker()) + { + php_swoole_check_reactor(); + } + + php_swoole_check_timer(ms); + swTimer_callback *cb = emalloc(sizeof(swTimer_callback)); + + cb->data = &cb->_data; + cb->callback = &cb->_callback; + memcpy(cb->callback, callback, sizeof(zval)); + if (param) + { + memcpy(cb->data, param, sizeof(zval)); + } + else + { + cb->data = NULL; + } + + + if (SwooleG.enable_coroutine) + { + cb->func_cache = func_cache; + } + else + { + efree(func_cache); + } + + swTimerCallback timer_func; + if (persistent) + { + cb->type = SW_TIMER_TICK; + timer_func = php_swoole_onInterval; + } + else + { + cb->type = SW_TIMER_AFTER; + timer_func = php_swoole_onTimeout; + } + + sw_zval_add_ref(&cb->callback); + if (cb->data) + { + sw_zval_add_ref(&cb->data); + } + + swTimer_node *tnode = SwooleG.timer.add(&SwooleG.timer, ms, persistent, cb, timer_func); + if (tnode == NULL) + { + swoole_php_fatal_error(E_WARNING, "add timer failed."); + return SW_ERR; + } + else + { + tnode->type = SW_TIMER_TYPE_PHP; + return tnode->id; + } +} + +static int php_swoole_del_timer(swTimer_node *tnode TSRMLS_DC) +{ + swTimer_callback *cb = tnode->data; + if (!cb) + { + return SW_ERR; + } + if (cb->callback) + { + sw_zval_ptr_dtor(&cb->callback); + } + if (cb->data) + { + sw_zval_ptr_dtor(&cb->data); + } + if (SwooleG.enable_coroutine && cb->func_cache) + { + efree(cb->func_cache); + } + efree(cb); + return SW_OK; +} + +void php_swoole_onTimeout(swTimer *timer, swTimer_node *tnode) +{ + if (tnode->type == SW_TIMER_TYPE_CORO) // coroutine timeout + { + swTimer_coro_callback *scc = tnode->data; + // del the reactor handle + if (swLinkedList_append(SwooleWG.coro_timeout_list, scc->data) == SW_OK) + { + if ((scc->cli_fd > 0) && (SwooleG.main_reactor->del(SwooleG.main_reactor, scc->cli_fd) == SW_ERR)) + { + swSysError("reactor->del(%d) failed.", scc->cli_fd); + } + } + + php_swoole_del_timer_coro(tnode TSRMLS_CC); + } + else // swoole_timer + { + swTimer_callback *cb = tnode->data; + zval *retval = NULL; + + if (SwooleG.enable_coroutine) + { + zval *args[2]; + int argc; + + if (NULL == cb->data) + { + argc = 0; + args[0] = NULL; + } + else + { + argc = 1; + args[0] = cb->data; + } + int ret = coro_create(cb->func_cache, args, argc, &retval, NULL, NULL); + if (CORO_LIMIT == ret) + { + swoole_php_fatal_error(E_WARNING, "swoole_timer: coroutine limit"); + return; + } + } + else + { + zval **args[2]; + int argc; + + if (NULL == cb->data) + { + argc = 0; + args[0] = NULL; + } + else + { + argc = 1; + args[0] = &cb->data; + } + + if (sw_call_user_function_ex(EG(function_table), NULL, cb->callback, &retval, argc, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_timer: onTimeout handler error"); + return; + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + php_swoole_del_timer(tnode TSRMLS_CC); + } +} + +void php_swoole_onInterval(swTimer *timer, swTimer_node *tnode) +{ + zval *retval = NULL; + int argc = 1; + + zval *ztimer_id; + + swTimer_callback *cb = tnode->data; + + SW_MAKE_STD_ZVAL(ztimer_id); + ZVAL_LONG(ztimer_id, tnode->id); + + if (SwooleG.enable_coroutine) + { + zval *args[2]; + if (cb->data) + { + argc = 2; + sw_zval_add_ref(&cb->data); + args[1] = cb->data; + } + args[0] = ztimer_id; + + int ret = coro_create(cb->func_cache, args, argc, &retval, NULL, NULL); + if (CORO_LIMIT == ret) + { + swoole_php_fatal_error(E_WARNING, "swoole_timer: coroutine limit"); + return; + } + } + else + { + zval **args[2]; + if (cb->data) + { + argc = 2; + sw_zval_add_ref(&cb->data); + args[1] = &cb->data; + } + args[0] = &ztimer_id; + + if (sw_call_user_function_ex(EG(function_table), NULL, cb->callback, &retval, argc, args, 0, NULL TSRMLS_CC) == FAILURE) + { + swoole_php_fatal_error(E_WARNING, "swoole_timer: onTimerCallback handler error"); + return; + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval != NULL) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&ztimer_id); + + if (tnode->remove) + { + php_swoole_del_timer(tnode TSRMLS_CC); + } +} + +void php_swoole_check_timer(int msec) +{ + if (SwooleG.timer.fd == 0) + { + swTimer_init(msec); + } +} + +PHP_FUNCTION(swoole_timer_tick) +{ + long after_ms; + zval *callback; + zval *param = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|z", &after_ms, &callback, &param) == FAILURE) + { + return; + } + + long timer_id = php_swoole_add_timer(after_ms, callback, param, 1 TSRMLS_CC); + if (timer_id < 0) + { + RETURN_FALSE; + } + else + { + RETURN_LONG(timer_id); + } +} + +PHP_FUNCTION(swoole_timer_after) +{ + long after_ms; + zval *callback; + zval *param = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|z", &after_ms, &callback, &param) == FAILURE) + { + return; + } + + long timer_id = php_swoole_add_timer(after_ms, callback, param, 0 TSRMLS_CC); + if (timer_id < 0) + { + RETURN_FALSE; + } + else + { + RETURN_LONG(timer_id); + } +} + +PHP_FUNCTION(swoole_timer_clear) +{ + if (!SwooleG.timer.set) + { + swoole_php_error(E_WARNING, "no timer"); + RETURN_FALSE; + } + + long id; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) + { + return; + } + + swTimer_node *tnode = swTimer_get(&SwooleG.timer, id); + if (tnode == NULL) + { + swoole_php_error(E_WARNING, "timer#%ld is not found.", id); + RETURN_FALSE; + } + if (tnode->remove) + { + RETURN_FALSE; + } + //current timer, cannot remove here. + if (SwooleG.timer._current_id > 0 && tnode->id == SwooleG.timer._current_id) + { + tnode->remove = 1; + RETURN_TRUE; + } + //remove timer + if (php_swoole_del_timer(tnode TSRMLS_CC) < 0) + { + RETURN_FALSE; + } + if (swTimer_del(&SwooleG.timer, tnode) == SW_FALSE) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} + +PHP_FUNCTION(swoole_timer_exists) +{ + if (!SwooleG.timer.set) + { + swoole_php_error(E_WARNING, "no timer"); + RETURN_FALSE; + } + + long id; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &id) == FAILURE) + { + return; + } + + swTimer_node *tnode = swTimer_get(&SwooleG.timer, id); + if (tnode == NULL) + { + RETURN_FALSE; + } + if (tnode->remove) + { + RETURN_FALSE; + } + RETURN_TRUE; +} diff --git a/vendor/swoole/swoole_trace.c b/vendor/swoole/swoole_trace.c new file mode 100755 index 0000000..26960a2 --- /dev/null +++ b/vendor/swoole/swoole_trace.c @@ -0,0 +1,539 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" + +#ifdef HAVE_PTRACE +#include <stddef.h> +#include <sys/ptrace.h> + +#if SIZEOF_LONG == 4 +#define PTR_FMT "08" +#elif SIZEOF_LONG == 8 +#define PTR_FMT "016" +#endif + +#if defined(PT_ATTACH) && !defined(PTRACE_ATTACH) +#if __APPLE__ +#define PTRACE_ATTACH PT_ATTACHEXC +#else +#define PTRACE_ATTACH PT_ATTACH +#endif +#endif + +#if defined(PT_DETACH) && !defined(PTRACE_DETACH) +#define PTRACE_DETACH PT_DETACH +#endif + +#if defined(PT_READ_D) && !defined(PTRACE_PEEKDATA) +#define PTRACE_PEEKDATA PT_READ_D +#endif + +#define valid_ptr(p) ((p) && 0 == ((p) & (sizeof(long) - 1))) + +static void trace_request(swWorker *worker); +static int trace_dump(swWorker *worker, FILE *slowlog); +static int trace_get_long(pid_t traced_pid, long addr, long *data); +static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr); + +static void trace_request(swWorker *worker) +{ + FILE *slowlog = SwooleG.serv->request_slowlog_file; + pid_t traced_pid = worker->pid; + int ret = trace_dump(worker, slowlog); + if (ret < 0) + { + swSysError("failed to trace worker %d, error lint =%d.", worker->pid, -ret); + } + if (0 > ptrace(PTRACE_DETACH, traced_pid, (void *) 1, 0)) + { + swSysError("failed to ptrace(DETACH) worker %d", worker->pid); + } + fflush(slowlog); +} + +void php_swoole_trace_check(void *arg) +{ + swServer *serv = (swServer *) arg; + uint8_t timeout = serv->request_slowlog_timeout; + int count = serv->worker_num + serv->task_worker_num; + int i = serv->trace_event_worker ? 0 : serv->worker_num; + swWorker *worker; + + for (; i < count; i++) + { + worker = swServer_get_worker(serv, i); + swTraceLog(SW_TRACE_SERVER, "trace request, worker#%d, pid=%d. request_time=%d.", i, worker->pid, worker->request_time); + if (!(worker->request_time > 0 && worker->traced == 0 && serv->gs->now - worker->request_time >= timeout)) + { + continue; + } + if (ptrace(PTRACE_ATTACH, worker->pid, 0, 0) < 0) + { + swSysError("failed to ptrace(ATTACH, %d) worker#%d,", worker->pid, worker->id); + continue; + } + worker->tracer = trace_request; + worker->traced = 1; + } +} + +static int trace_get_long(pid_t traced_pid, long addr, long *data) +{ + errno = 0; + *data = ptrace(PTRACE_PEEKDATA, traced_pid, (void *) addr, 0); + if (*data < 0) + { + return -1; + } + return 0; +} + +static int trace_get_strz(pid_t traced_pid, char *buf, size_t sz, long addr) +{ + int i; + long l = addr; + char *lc = (char *) &l; + + i = l % SIZEOF_LONG; + l -= i; + for (addr = l;; addr += SIZEOF_LONG) + { + if (0 > trace_get_long(traced_pid, addr, &l)) + { + return -1; + } + for (; i < SIZEOF_LONG; i++) + { + --sz; + if (sz && lc[i]) + { + *buf++ = lc[i]; + continue; + } + *buf = '\0'; + return 0; + } + i = 0; + } + return 0; +} + +size_t trace_print_time(struct timeval *tv, char *timebuf, size_t timebuf_len) +{ + struct tm t; + size_t len; + + len = strftime(timebuf, timebuf_len, "[%d-%b-%Y %H:%M:%S", localtime_r((const time_t *) &tv->tv_sec, &t)); + len += snprintf(timebuf + len, timebuf_len - len, "] "); + return len; +} + +static int trace_dump(swWorker *worker, FILE *slowlog) +{ + SWOOLE_GET_TSRMLS; + + pid_t traced_pid = worker->pid; + int callers_limit = 100; + struct timeval tv; + static const int buf_size = 1024; + char buf[buf_size]; + long execute_data; + long l; + + gettimeofday(&tv, 0); + + trace_print_time(&tv, buf, buf_size); + + fprintf(slowlog, "\n%s [worker#%d] pid %d\n", buf, worker->id, (int) traced_pid); + + if (0 > trace_get_long(traced_pid, (long) &EG(current_execute_data), &l)) + { + return -__LINE__; + } + + execute_data = l; + +#if PHP_VERSION_ID > 70100 + while (execute_data) + { + long function; + long function_name; + long file_name; + long prev; + uint32_t lineno = 0; + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, func), &l)) + { + return -__LINE__; + } + + function = l; + + if (valid_ptr(function)) + { + if (0 > trace_get_long(traced_pid, function + offsetof(zend_function, common.function_name), &l)) + { + return -1; + } + + function_name = l; + + if (function_name == 0) + { + uint32_t *call_info = (uint32_t *) &l; + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, This.u1.type_info), &l)) + { + return -__LINE__; + } + + if (ZEND_CALL_KIND_EX((*call_info) >> ZEND_CALL_INFO_SHIFT) == ZEND_CALL_TOP_CODE) + { + return 0; + } + else if (ZEND_CALL_KIND_EX(*(call_info) >> ZEND_CALL_INFO_SHIFT) == ZEND_CALL_NESTED_CODE) + { + memcpy(buf, "[INCLUDE_OR_EVAL]", sizeof("[INCLUDE_OR_EVAL]")); + } + else + { + ZEND_ASSERT(0); + } + } + else + { + if (0 > trace_get_strz(traced_pid, buf, buf_size, function_name + offsetof(zend_string, val))) + { + return -__LINE__; + } + + } + } + else + { + memcpy(buf, "???", sizeof("???")); + } + + fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data); + fprintf(slowlog, "%s()", buf); + + *buf = '\0'; + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) + { + return -__LINE__; + } + + execute_data = prev = l; + + while (prev) + { + zend_uchar *type; + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, func), &l)) + { + return -__LINE__; + } + + function = l; + + if (!valid_ptr(function)) + { + break; + } + + type = (zend_uchar *) &l; + if (0 > trace_get_long(traced_pid, function + offsetof(zend_function, type), &l)) + { + return -__LINE__; + } + + if (ZEND_USER_CODE(*type)) + { + if (0 > trace_get_long(traced_pid, function + offsetof(zend_op_array, filename), &l)) + { + return -__LINE__; + } + + file_name = l; + + if (0 > trace_get_strz(traced_pid, buf, buf_size, file_name + offsetof(zend_string, val))) + { + return -__LINE__; + } + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, opline), &l)) + { + return -__LINE__; + } + + if (valid_ptr(l)) + { + long opline = l; + uint32_t *lu = (uint32_t *) &l; + + if (0 > trace_get_long(traced_pid, opline + offsetof(struct _zend_op, lineno), &l)) + { + return -__LINE__; + } + + lineno = *lu; + } + break; + } + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, prev_execute_data), &l)) + { + return -__LINE__; + } + + prev = l; + } + + fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno); + + if (0 == --callers_limit) + { + break; + } + } +#elif PHP_VERSION_ID > 70000 + while (execute_data) + { + long function; + long function_name; + long file_name; + long prev; + uint lineno = 0; + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, func), &l)) + { + return -1; + } + + function = l; + + if (valid_ptr(function)) + { + if (0 > trace_get_long(traced_pid, function + offsetof(zend_function, common.function_name), &l)) + { + return -1; + } + + function_name = l; + + if (function_name == 0) + { + uint32_t *call_info = (uint32_t *)&l; + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, This.u1.type_info), &l)) + { + return -1; + } + + if (ZEND_CALL_KIND_EX((*call_info) >> 24) == ZEND_CALL_TOP_CODE) + { + return 0; + } + else if (ZEND_CALL_KIND_EX(*(call_info) >> 24) == ZEND_CALL_NESTED_CODE) + { + memcpy(buf, "[INCLUDE_OR_EVAL]", sizeof("[INCLUDE_OR_EVAL]")); + } + else + { + ZEND_ASSERT(0); + } + } + else + { + if (0 > trace_get_strz(traced_pid, buf, buf_size, function_name + offsetof(zend_string, val))) + { + return -1; + } + + } + } + else + { + memcpy(buf, "???", sizeof("???")); + } + + fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data); + + fprintf(slowlog, "%s()", buf); + + *buf = '\0'; + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) + { + return -1; + } + + execute_data = prev = l; + + while (prev) + { + zend_uchar *type; + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, func), &l)) + { + return -1; + } + + function = l; + + if (!valid_ptr(function)) + { + break; + } + + type = (zend_uchar *)&l; + if (0 > trace_get_long(traced_pid, function + offsetof(zend_function, type), &l)) + { + return -1; + } + + if (ZEND_USER_CODE(*type)) + { + if (0 > trace_get_long(traced_pid, function + offsetof(zend_op_array, filename), &l)) + { + return -1; + } + + file_name = l; + + if (0 > trace_get_strz(traced_pid, buf, buf_size, file_name + offsetof(zend_string, val))) + { + return -1; + } + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, opline), &l)) + { + return -1; + } + + if (valid_ptr(l)) + { + long opline = l; + uint32_t *lu = (uint32_t *) &l; + + if (0 > trace_get_long(traced_pid, opline + offsetof(struct _zend_op, lineno), &l)) + { + return -1; + } + + lineno = *lu; + } + break; + } + + if (0 > trace_get_long(traced_pid, prev + offsetof(zend_execute_data, prev_execute_data), &l)) + { + return -1; + } + + prev = l; + } + + fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno); + + if (0 == --callers_limit) + { + break; + } + } +#else + while (execute_data) + { + long function; + uint lineno = 0; + + fprintf(slowlog, "[0x%" PTR_FMT "lx] ", execute_data); + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, function_state.function), &l)) + { + return -1; + } + + function = l; + + if (valid_ptr(function)) + { + if (0 > trace_get_strz(traced_pid, buf, buf_size, function + offsetof(zend_function, common.function_name))) + { + return -1; + } + + fprintf(slowlog, "%s()", buf); + } + else + { + fprintf(slowlog, "???"); + } + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, op_array), &l)) + { + return -1; + } + + *buf = '\0'; + + if (valid_ptr(l)) + { + long op_array = l; + + if (0 > trace_get_strz(traced_pid, buf, buf_size, op_array + offsetof(zend_op_array, filename))) + { + return -1; + } + } + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, opline), &l)) + { + return -1; + } + + if (valid_ptr(l)) + { + long opline = l; + uint *lu = (uint *) &l; + + if (0 > trace_get_long(traced_pid, opline + offsetof(struct _zend_op, lineno), &l)) + { + return -1; + } + + lineno = *lu; + } + + fprintf(slowlog, " %s:%u\n", *buf ? buf : "unknown", lineno); + + if (0 > trace_get_long(traced_pid, execute_data + offsetof(zend_execute_data, prev_execute_data), &l)) + { + return -1; + } + + execute_data = l; + + if (0 == --callers_limit) + { + break; + } + } +#endif + + return 0; +} +#endif diff --git a/vendor/swoole/swoole_websocket_server.c b/vendor/swoole/swoole_websocket_server.c new file mode 100755 index 0000000..81aa74a --- /dev/null +++ b/vendor/swoole/swoole_websocket_server.c @@ -0,0 +1,605 @@ +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ +*/ + +#include "php_swoole.h" +#include "swoole_http.h" +#ifdef SW_COROUTINE +#include "swoole_coroutine.h" +#endif + +#include <ext/standard/url.h> +#include <ext/standard/sha1.h> +#include <ext/standard/php_var.h> +#include <ext/standard/php_string.h> +#include <ext/date/php_date.h> +#include <main/php_variables.h> + +#include "websocket.h" +#include "Connection.h" +#include "base64.h" +#include "thirdparty/php_http_parser.h" + +static zend_class_entry swoole_websocket_server_ce; +static zend_class_entry *swoole_websocket_server_class_entry_ptr; + +static zend_class_entry swoole_websocket_frame_ce; +static zend_class_entry *swoole_websocket_frame_class_entry_ptr; + +static int websocket_handshake(swListenPort *, http_context *); + +static PHP_METHOD(swoole_websocket_server, on); +static PHP_METHOD(swoole_websocket_server, push); +static PHP_METHOD(swoole_websocket_server, exist); +static PHP_METHOD(swoole_websocket_server, isEstablished); +static PHP_METHOD(swoole_websocket_server, pack); +static PHP_METHOD(swoole_websocket_server, unpack); + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_on, 0, 0, 2) + ZEND_ARG_INFO(0, event_name) + ZEND_ARG_INFO(0, callback) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_push, 0, 0, 2) + ZEND_ARG_INFO(0, fd) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, opcode) + ZEND_ARG_INFO(0, finish) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_pack, 0, 0, 1) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, opcode) + ZEND_ARG_INFO(0, finish) + ZEND_ARG_INFO(0, mask) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_unpack, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_exist, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_swoole_websocket_server_isEstablished, 0, 0, 1) + ZEND_ARG_INFO(0, fd) +ZEND_END_ARG_INFO() + +const zend_function_entry swoole_websocket_server_methods[] = +{ + PHP_ME(swoole_websocket_server, on, arginfo_swoole_websocket_server_on, ZEND_ACC_PUBLIC) + PHP_ME(swoole_websocket_server, push, arginfo_swoole_websocket_server_push, ZEND_ACC_PUBLIC) + PHP_ME(swoole_websocket_server, exist, arginfo_swoole_websocket_server_exist, ZEND_ACC_PUBLIC) + PHP_ME(swoole_websocket_server, isEstablished, arginfo_swoole_websocket_server_isEstablished, ZEND_ACC_PUBLIC) + PHP_ME(swoole_websocket_server, pack, arginfo_swoole_websocket_server_pack, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(swoole_websocket_server, unpack, arginfo_swoole_websocket_server_unpack, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; + +void swoole_websocket_onOpen(http_context *ctx) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + int fd = ctx->fd; + + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (!conn) + { + swoole_error_log(SW_LOG_NOTICE, SW_ERROR_SESSION_CLOSED, "session[%d] is closed.", fd); + return; + } + conn->websocket_status = WEBSOCKET_STATUS_ACTIVE; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen); + if (cache) + { + swServer *serv = SwooleG.serv; + zval *zserv = (zval *) serv->ptr2; + zval *zrequest_object = ctx->request.zobject; + zval *retval = NULL; + + if (SwooleG.enable_coroutine) + { + zval *args[2]; + args[0] = zserv; + args[1] = zrequest_object; + + int ret = coro_create(cache, args, 2, &retval, NULL, NULL); + if (ret == CORO_LIMIT) + { + SwooleG.serv->factory.end(&SwooleG.serv->factory, fd); + return; + } + } + else + { + zval **args[2]; + args[0] = &zserv; + args[1] = &zrequest_object; + + zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, conn->from_fd, SW_SERVER_CB_onOpen); + if (sw_call_user_function_fast(zcallback, cache, &retval, 2, args TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onOpen handler error"); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + } +} + +/** + * default onRequest callback + */ +void swoole_websocket_onRequest(http_context *ctx) +{ + SWOOLE_GET_TSRMLS; + char *content = "<html><body><h2>HTTP ERROR 400</h2><hr><i>Powered by "SW_HTTP_SERVER_SOFTWARE" ("PHP_SWOOLE_VERSION")</i></body></html>"; + char *bad_request = "HTTP/1.1 400 Bad Request\r\n"\ + "Content-Type: text/html; charset=UTF-8\r\n"\ + "Cache-Control: must-revalidate,no-cache,no-store\r\n"\ + "Content-Length: %d\r\n"\ + "Server: "SW_HTTP_SERVER_SOFTWARE"\r\n\r\n%s"; + + char buf[512]; + + int n = sprintf(buf, bad_request, strlen(content), content); + swServer_tcp_send(SwooleG.serv, ctx->fd, buf, n); + ctx->end = 1; + swServer_tcp_close(SwooleG.serv, ctx->fd, 0); + swoole_http_context_free(ctx TSRMLS_CC); +} + +void php_swoole_sha1(const char *str, int _len, unsigned char *digest) +{ + PHP_SHA1_CTX context; + PHP_SHA1Init(&context); + PHP_SHA1Update(&context, (unsigned char *) str, _len); + PHP_SHA1Final(digest, &context); +} + +static int websocket_handshake(swListenPort *port, http_context *ctx) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + zval *header = ctx->request.zheader; + HashTable *ht = Z_ARRVAL_P(header); + zval *pData; + + if (sw_zend_hash_find(ht, ZEND_STRS("sec-websocket-key"), (void **) &pData) == FAILURE) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "header no sec-websocket-key"); + return SW_ERR; + } + convert_to_string(pData); + + swString_clear(swoole_http_buffer); + swString_append_ptr(swoole_http_buffer, ZEND_STRL("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n")); + + int n; + char sec_websocket_accept[128]; + memcpy(sec_websocket_accept, Z_STRVAL_P(pData), Z_STRLEN_P(pData)); + memcpy(sec_websocket_accept + Z_STRLEN_P(pData), SW_WEBSOCKET_GUID, sizeof(SW_WEBSOCKET_GUID) - 1); + + char sha1_str[20]; + bzero(sha1_str, sizeof(sha1_str)); + php_swoole_sha1(sec_websocket_accept, Z_STRLEN_P(pData) + sizeof(SW_WEBSOCKET_GUID) - 1, (unsigned char *) sha1_str); + + char encoded_str[50]; + bzero(encoded_str, sizeof(encoded_str)); + n = swBase64_encode((unsigned char *) sha1_str, sizeof(sha1_str), encoded_str); + + char _buf[128]; + n = snprintf(_buf, sizeof(_buf), "Sec-WebSocket-Accept: %*s\r\n", n, encoded_str); + + swString_append_ptr(swoole_http_buffer, _buf, n); + swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Version: "SW_WEBSOCKET_VERSION"\r\n")); + if (port->websocket_subprotocol) + { + swString_append_ptr(swoole_http_buffer, ZEND_STRL("Sec-WebSocket-Protocol: ")); + swString_append_ptr(swoole_http_buffer, port->websocket_subprotocol, port->websocket_subprotocol_length); + swString_append_ptr(swoole_http_buffer, ZEND_STRL("\r\n")); + } + swString_append_ptr(swoole_http_buffer, ZEND_STRL("Server: "SW_WEBSOCKET_SERVER_SOFTWARE"\r\n\r\n")); + + swTrace("websocket header len:%ld\n%s \n", swoole_http_buffer->length, swoole_http_buffer->str); + + return swServer_tcp_send(SwooleG.serv, ctx->fd, swoole_http_buffer->str, swoole_http_buffer->length); +} + +int swoole_websocket_onMessage(swEventData *req) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + int fd = req->info.fd; + + zval *zdata; + SW_MAKE_STD_ZVAL(zdata); + + char frame_header[2]; + php_swoole_get_recv_data(zdata, req, frame_header, 2); + + long finish = frame_header[0] ? 1 : 0; + long opcode = frame_header[1]; + + zval *zframe; + SW_MAKE_STD_ZVAL(zframe); + object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr); + + zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("fd"), fd TSRMLS_CC); + zend_update_property_bool(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), finish TSRMLS_CC); + zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), opcode TSRMLS_CC); + zend_update_property(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), zdata TSRMLS_CC); + + swServer *serv = SwooleG.serv; + zval *zserv = (zval *) serv->ptr2; + zval *retval = NULL; + + if (SwooleG.enable_coroutine) + { + zval *args[2]; + args[0] = zserv; + args[1] = zframe; + + zend_fcall_info_cache *cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage); + int ret = coro_create(cache, args, 2, &retval, NULL, NULL); + if (ret == CORO_LIMIT) + { + sw_zval_ptr_dtor(&zdata); + sw_zval_ptr_dtor(&zframe); + SwooleG.serv->factory.end(&SwooleG.serv->factory, fd); + return SW_OK; + } + } + else + { + zval **args[2]; + args[0] = &zserv; + args[1] = &zframe; + + zend_fcall_info_cache *fci_cache = php_swoole_server_get_cache(serv, req->info.from_fd, SW_SERVER_CB_onMessage); + zval *zcallback = php_swoole_server_get_callback(SwooleG.serv, req->info.from_fd, SW_SERVER_CB_onMessage); + + if (sw_call_user_function_fast(zcallback, fci_cache, &retval, 2, args TSRMLS_CC) == FAILURE) + { + swoole_php_error(E_WARNING, "onMessage handler error"); + } + } + + if (EG(exception)) + { + zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); + } + if (retval) + { + sw_zval_ptr_dtor(&retval); + } + sw_zval_ptr_dtor(&zdata); + sw_zval_ptr_dtor(&zframe); + return SW_OK; +} + +int swoole_websocket_onHandshake(swListenPort *port, http_context *ctx) +{ +#if PHP_MAJOR_VERSION < 7 + TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); +#endif + + int fd = ctx->fd; + int ret = websocket_handshake(port, ctx); + if (ret == SW_ERR) + { + swServer_tcp_close(SwooleG.serv, fd, 1); + } + else + { + swoole_websocket_onOpen(ctx); + } + + //free client data + if (!ctx->end) + { + swoole_http_context_free(ctx TSRMLS_CC); + } + + return SW_OK; +} + +void swoole_websocket_init(int module_number TSRMLS_DC) +{ + SWOOLE_INIT_CLASS_ENTRY(swoole_websocket_server_ce, "swoole_websocket_server", "Swoole\\WebSocket\\Server", swoole_websocket_server_methods); + swoole_websocket_server_class_entry_ptr = sw_zend_register_internal_class_ex(&swoole_websocket_server_ce, swoole_http_server_class_entry_ptr, "swoole_http_server" TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_websocket_server, "Swoole\\WebSocket\\Server"); + + SWOOLE_INIT_CLASS_ENTRY(swoole_websocket_frame_ce, "swoole_websocket_frame", "Swoole\\WebSocket\\Frame", NULL); + swoole_websocket_frame_class_entry_ptr = zend_register_internal_class(&swoole_websocket_frame_ce TSRMLS_CC); + SWOOLE_CLASS_ALIAS(swoole_websocket_frame, "Swoole\\WebSocket\\Frame"); + + if (SWOOLE_G(use_shortname)) + { + sw_zend_register_class_alias("Co\\WebSocket\\Server", swoole_websocket_server_class_entry_ptr); + sw_zend_register_class_alias("Co\\WebSocket\\Frame", swoole_websocket_frame_class_entry_ptr); + } + + REGISTER_LONG_CONSTANT("WEBSOCKET_OPCODE_TEXT", WEBSOCKET_OPCODE_TEXT_FRAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("WEBSOCKET_OPCODE_BINARY", WEBSOCKET_OPCODE_BINARY_FRAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("WEBSOCKET_OPCODE_PING", WEBSOCKET_OPCODE_PING, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("WEBSOCKET_STATUS_CONNECTION", WEBSOCKET_STATUS_CONNECTION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("WEBSOCKET_STATUS_HANDSHAKE", WEBSOCKET_STATUS_HANDSHAKE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("WEBSOCKET_STATUS_FRAME", WEBSOCKET_STATUS_ACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("WEBSOCKET_STATUS_ACTIVE", WEBSOCKET_STATUS_ACTIVE, CONST_CS | CONST_PERSISTENT); +} + +void php_swoole_websocket_unpack(swString *data, zval *zframe TSRMLS_DC) +{ + swWebSocket_frame frame; + + if (data->length < sizeof(frame.header)) + { + ZVAL_BOOL(zframe, 0); + return; + } + + swWebSocket_decode(&frame, data); + + object_init_ex(zframe, swoole_websocket_frame_class_entry_ptr); + + zend_update_property_bool(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("finish"), frame.header.FIN TSRMLS_CC); + zend_update_property_long(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("opcode"), frame.header.OPCODE TSRMLS_CC); + zend_update_property_stringl(swoole_websocket_frame_class_entry_ptr, zframe, ZEND_STRL("data"), frame.payload, frame.payload_length TSRMLS_CC); +} + +static PHP_METHOD(swoole_websocket_server, on) +{ + zval *callback; + zval *event_name; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start > 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "can't register event callback function after server started."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &event_name, &callback) == FAILURE) + { + return; + } + + char *func_name = NULL; + zend_fcall_info_cache *func_cache = emalloc(sizeof(zend_fcall_info_cache)); + if (!sw_zend_is_callable_ex(callback, NULL, 0, &func_name, NULL, func_cache, NULL TSRMLS_CC)) + { + swoole_php_fatal_error(E_ERROR, "function '%s' is not callable", func_name); + efree(func_name); + RETURN_FALSE; + } + efree(func_name); + + serv->listen_list->open_websocket_protocol = 1; + + if (strncasecmp("open", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) + { + zend_update_property(swoole_websocket_server_class_entry_ptr, getThis(), ZEND_STRL("onOpen"), callback TSRMLS_CC); + php_sw_server_callbacks[SW_SERVER_CB_onOpen] = sw_zend_read_property(swoole_websocket_server_class_entry_ptr, getThis(), ZEND_STRL("onOpen"), 0 TSRMLS_CC); + sw_copy_to_stack(php_sw_server_callbacks[SW_SERVER_CB_onOpen], _php_sw_server_callbacks[SW_SERVER_CB_onOpen]); + php_sw_server_caches[SW_SERVER_CB_onOpen] = func_cache; + } + else if (strncasecmp("message", Z_STRVAL_P(event_name), Z_STRLEN_P(event_name)) == 0) + { + zend_update_property(swoole_websocket_server_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), callback TSRMLS_CC); + php_sw_server_callbacks[SW_SERVER_CB_onMessage] = sw_zend_read_property(swoole_websocket_server_class_entry_ptr, getThis(), ZEND_STRL("onMessage"), 0 TSRMLS_CC); + sw_copy_to_stack(php_sw_server_callbacks[SW_SERVER_CB_onMessage], _php_sw_server_callbacks[SW_SERVER_CB_onMessage]); + php_sw_server_caches[SW_SERVER_CB_onMessage] = func_cache; + } + else + { + efree(func_cache); + zval *obj = getThis(); + sw_zend_call_method_with_2_params(&obj, swoole_http_server_class_entry_ptr, NULL, "on", &return_value, event_name, callback); + } +} + +static PHP_METHOD(swoole_websocket_server, push) +{ + zval *zdata; + long fd = 0; + long opcode = WEBSOCKET_OPCODE_TEXT_FRAME; + zend_bool fin = 1; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz|lb", &fd, &zdata, &opcode, &fin) == FAILURE) + { + return; + } + + if (fd <= 0) + { + swoole_php_fatal_error(E_WARNING, "fd[%d] is invalid.", (int )fd); + RETURN_FALSE; + } + + if (opcode > WEBSOCKET_OPCODE_PONG) + { + swoole_php_fatal_error(E_WARNING, "the maximum value of opcode is 10."); + RETURN_FALSE; + } + + char *data; + int length = php_swoole_get_send_data(zdata, &data TSRMLS_CC); + + if (length < 0) + { + RETURN_FALSE; + } + + swConnection *conn = swWorker_get_connection(SwooleG.serv, fd); + if (!conn || conn->websocket_status < WEBSOCKET_STATUS_HANDSHAKE) + { + SwooleG.error = SW_ERROR_WEBSOCKET_BAD_CLIENT; + swoole_php_fatal_error(E_WARNING, "the connected client of connection[%d] is not a websocket client.", (int ) fd); + RETURN_FALSE; + } + swString_clear(swoole_http_buffer); + swWebSocket_encode(swoole_http_buffer, data, length, opcode, (int) fin, 0); + + int ret = swServer_tcp_send(SwooleG.serv, fd, swoole_http_buffer->str, swoole_http_buffer->length); +#ifdef SW_COROUTINE + swServer *serv = SwooleG.serv; + if (ret < 0 && SwooleG.error == SW_ERROR_OUTPUT_BUFFER_OVERFLOW && serv->send_yield) + { + zval _yield_data; + ZVAL_STRINGL(&_yield_data, swoole_http_buffer->str, swoole_http_buffer->length); + php_swoole_server_send_yield(serv, fd, &_yield_data, return_value); + } + else +#endif + { + SW_CHECK_RETURN(ret); + } +} + +static PHP_METHOD(swoole_websocket_server, pack) +{ + char *data; + zend_size_t length; + long opcode = WEBSOCKET_OPCODE_TEXT_FRAME; + zend_bool finish = 1; + zend_bool mask = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbb", &data, &length, &opcode, &finish, &mask) == FAILURE) + { + return; + } + + if (opcode > WEBSOCKET_OPCODE_PONG) + { + swoole_php_fatal_error(E_WARNING, "the maximum value of opcode is 10."); + RETURN_FALSE; + } + + if (swoole_http_buffer == NULL) + { + swoole_http_buffer = swString_new(SW_HTTP_RESPONSE_INIT_SIZE); + if (!swoole_http_buffer) + { + swoole_php_fatal_error(E_ERROR, "[1] swString_new(%d) failed.", SW_HTTP_RESPONSE_INIT_SIZE); + RETURN_FALSE; + } + } + + swString_clear(swoole_http_buffer); + swWebSocket_encode(swoole_http_buffer, data, length, opcode, (int) finish, mask); + SW_RETURN_STRINGL(swoole_http_buffer->str, swoole_http_buffer->length, 1); +} + +static PHP_METHOD(swoole_websocket_server, unpack) +{ + swString buffer; + bzero(&buffer, sizeof(buffer)); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer.str, &buffer.length) == FAILURE) + { + return; + } + + php_swoole_websocket_unpack(&buffer, return_value TSRMLS_CC); +} + +static PHP_METHOD(swoole_websocket_server, exist) +{ + zend_long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "the server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } + + swConnection *conn = swWorker_get_connection(serv, fd); + if (!conn) + { + RETURN_FALSE; + } + //connection is closed + if (conn->active == 0 || conn->closed) + { + RETURN_FALSE; + } + swConnection *server_sock = swServer_connection_get(serv, conn->from_fd); + if (server_sock) + { + swListenPort *port = server_sock->object; + //not websocket port + if (port && !port->open_websocket_protocol) + { + RETURN_TRUE; + } + } + //have not handshake + if (conn->websocket_status < WEBSOCKET_STATUS_ACTIVE) + { + RETURN_FALSE; + } + RETURN_TRUE; +} + +static PHP_METHOD(swoole_websocket_server, isEstablished) +{ + zend_long fd; + + swServer *serv = swoole_get_object(getThis()); + if (serv->gs->start == 0) + { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "the server is not running."); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fd) == FAILURE) + { + return; + } + + swConnection *conn = swWorker_get_connection(serv, fd); + //not isEstablished + if (!conn || conn->active == 0 || conn->closed || conn->websocket_status < WEBSOCKET_STATUS_ACTIVE) + { + RETURN_FALSE; + } + else + { + RETURN_TRUE; + } +} diff --git a/vendor/swoole/tests/CONTRIBUTION b/vendor/swoole/tests/CONTRIBUTION new file mode 100755 index 0000000..a2a45d3 --- /dev/null +++ b/vendor/swoole/tests/CONTRIBUTION @@ -0,0 +1,2 @@ +Tianfeng Han @ Swoole Group <https://github.com/swoole> +Xiaofeng Chu @ Zan Group <https://github.com/youzan> diff --git a/vendor/swoole/tests/README.md b/vendor/swoole/tests/README.md new file mode 100755 index 0000000..138c933 --- /dev/null +++ b/vendor/swoole/tests/README.md @@ -0,0 +1,31 @@ +# PHP Unit-test + +Run these tests to make certain that the swoole extension you installed can work well. + +## How to run +1. Run all of the test scripts on source root dir by `make test` +2. Or run `./strart.sh` +3. use`./start.sh ./swoole_*` command to run a part of the tests + +## Log files + +| suffix | intro | +| ------ | --------------------------------------------- | +| diff | show the differents between output and expect | +| out | script output | +| exp | expect output | +| log | all above | +| php | php temp script file | + + +## Clean +Run `./clean` to remove all of the tests log files. + +## Contribute the test script +Run `./new.sh [test-script-filename]` + +E.g. : `./new.sh ./swoole-coroutine/co_sleep.phpt` + +It will generate the test script file and auto open on your ide (MacOS only). + +![](https://ws1.sinaimg.cn/large/006DQdzWly1frvn56azn9g30rs0m8b29.gif) \ No newline at end of file diff --git a/vendor/swoole/tests/clean b/vendor/swoole/tests/clean new file mode 100755 index 0000000..cfef96e --- /dev/null +++ b/vendor/swoole/tests/clean @@ -0,0 +1,32 @@ +#!/usr/bin/env php +<?php +$dirs = scandir(__DIR__); +foreach ($dirs as $d) +{ + if (substr($d, 0, 6) == 'swoole') + { + clean(__DIR__ . '/' . $d); + } +} + +function clean($dir) +{ + $ignore_files = include __DIR__ . '/include/ignore_files.php'; + $files = scandir($dir); + foreach ($files as $f) + { + if ($f == '.' or $f == '..') + { + continue; + } + if (substr($f, -5) != '.phpt') + { + $file = $dir . '/' . $f; + if (is_file($file) and !in_array($dir . '/' . $f, $ignore_files)) + { + echo "DELETE: ", $file, "\n"; + unlink($file); + } + } + } +} diff --git a/vendor/swoole/tests/coro_test.sh b/vendor/swoole/tests/coro_test.sh new file mode 100755 index 0000000..0d0ce59 --- /dev/null +++ b/vendor/swoole/tests/coro_test.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +./start.sh swoole_client_coro/ swoole_coroutine/ swoole_coroutine_channel/ swoole_coroutine_util/ swoole_http_cilent_coro/ swoole_mysql_coro/ swoole_redis_coro/ swoole_socket_coro/ diff --git a/vendor/swoole/tests/include/api/http_server.php b/vendor/swoole/tests/include/api/http_server.php new file mode 100755 index 0000000..070aa10 --- /dev/null +++ b/vendor/swoole/tests/include/api/http_server.php @@ -0,0 +1,86 @@ +<?php +$http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); +$http->set(array( + 'log_file' => '/dev/null', + "http_parse_post" => 1, + "upload_tmp_dir" => "/tmp", +)); +$http->on("WorkerStart", function (\swoole_server $serv) +{ + /** + * @var $pm ProcessManager + */ + global $pm; + if ($pm) + { + $pm->wakeup(); + } +}); +$http->on('request', function ($request, swoole_http_response $response) +{ + $route = $request->server['request_uri']; + if ($route == '/info') + { + $response->end($request->header['user-agent']); + return; + } + elseif ($route == '/cookies') + { + $response->end(@json_encode($request->cookie)); + return; + } + elseif ($route == '/get') + { + $response->end(@json_encode($request->get)); + return; + } + elseif ($route == '/post') + { + $response->end(@json_encode($request->post)); + return; + } + elseif ($route == '/get_file') + { + $response->sendfile(TEST_IMAGE); + return; + } + elseif ($route == '/upload_file') + { + $response->end(json_encode([ + 'files' => $request->files, + 'md5' => md5_file($request->files['test_jpg']['tmp_name']), + 'post' => $request->post + ])); + return; + } + elseif ($route == '/gzip') + { + $response->gzip(5); + Swoole\Async::readFile(__DIR__ . '/../../../README.md', function ($file, $content) use ($response) { + $response->end($content); + }); + return; + } + else + { + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->set(array( + 'timeout' => 0.3, + )); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) use ($response) + { + }); + $cli->on('error', function ($cli) use ($response) + { + echo "error"; + $response->end("error"); + }); + $cli->get('/info', function ($cli) use ($response) + { + $response->end($cli->body . "\n"); + $cli->close(); + }); + } +}); +$http->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async/read_write.php b/vendor/swoole/tests/include/api/swoole_async/read_write.php new file mode 100755 index 0000000..9ef0245 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async/read_write.php @@ -0,0 +1,175 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +// TODO 线上版本 512k coredump +//$chunk = 1024 * 512; +//parallel_read_copy($chunk); + + + +//$chunk = 1024 * 1024; +//parallel_read_copy($chunk); + +//$chunk = 1024 * 1024 - 1; +//parallel_read_copy($chunk); + +//serial_read_copy(); + + +// DOC +// 读全部文件chunk = -1 或者 不传递 +// 不需要chunk参数,强制性一次读取1M数据 +// swoole_function swoole_async_read($file, callable $cb, $chunk, $offset) {} + + +// 新接口取消readfile与writefile + +function gen_rand_file($file, $m = 10) +{ + // !! linux 的bs不支持m作为单位 !!! + $bs = 1024 * 1024; + `dd if=/dev/urandom of=$file bs=$bs count=$m >/dev/null 2>&1`; + // 可能会失败 + // return filesize($file); + return $m * 1024 * 1024; +} + + +// 验证复制完整性并清理文件 +function valid_clean($from, $to) +{ +// echo "copy finished\n"; +// echo `ls -alh | grep $from`; + $diff = `diff $from $to`; // valid + if ($diff) { + echo $diff; + echo "FAIL\n"; + } else { + echo "SUCCESS\n"; + } + @unlink($from); + @unlink($to); +} + + +// 重构后swoole版本api +function serial_read_copy($size_m = 10) +{ + $start = microtime(true); + + $chunk = 1024 * 1024; + + $offset = 0; + $file = "bigfile"; + $origin_size = gen_rand_file($file, $size_m); + + $n = (int)ceil($origin_size / $chunk); + swoole_async_set([ "thread_num" => $n,]); + + $i = 0; + swoole_async_read($file, function($filename, $content) use($file, &$offset, &$n, &$i, $start) { + + $read_size = strlen($content); + //echo "<$i> read [offset=$offset, len=$read_size]\n"; + + $continue = $read_size !== 0; + if ($continue) { + swoole_async_write("$file.copy", $content, $offset, function($write_file, $write_size) use($file, $offset, $read_size, &$n, $i, $start) { + $n--; + + assert($read_size === $write_size); // 断言分块全部写入 + //echo "<$i> write [offset=$offset, len=$write_size]\n"; + + if ($n === 0) { + //echo "cost: ", microtime(true) - $start, "\n"; + valid_clean($file, $write_file); + } + }); + } + + $offset += $read_size; + $i++; + + return $continue; + + }, $chunk); +} + + +function parallel_read_copy($chunk, $size_m = 10) +{ + $start = microtime(true); + + $offset = 0; + $file = "bigfile"; + //生成一个10M大小的文件 + $origin_size = gen_rand_file($file, $size_m); + $n = (int)ceil($origin_size / $chunk); + //设置线程数 + swoole_async_set([ "thread_num" => $n,]); + + for ($i = 0; $i < $n; $i++) { + $offset = $i * $chunk; + + swoole_async_read($file, function($filename, $content) use($file, $offset, $i, &$n, $start) { + + $read_size = strlen($content); +// echo "<$i> read [offset=$offset, len=$read_size]\n"; + + swoole_async_write("$file.copy", $content, $offset, function($write_file, $write_size) use($file, $offset, $read_size, &$n, $i, $start) { + $n--; + + assert($read_size === $write_size); // 断言分块全部写入 +// echo "<$i> write [offset=$offset, len=$write_size]\n"; + + if ($n === 0) { +// echo "cost: ", microtime(true) - $start, "\n"; + valid_clean($file, $write_file); + } + }); + + // !!! 只读取单独chunk,停止继续读 + return false; + }, $chunk, $offset); + } +} + + + +// 旧的swoole版本api 使用 +function serial_copy_old($chunk) +{ + $offset = 0; + $file = "bigfile"; + $origin_size = gen_rand_file($file); + + $n = (int)ceil($origin_size / $chunk); + swoole_async_set([ "thread_num" => $n,]); + + $i = 0; + swoole_async_read($file, function($filename, $content) use($file, &$offset, &$n, &$i) { + + $read_size = strlen($content); + echo "<$i> read [offset=$offset, len=$read_size]\n"; + + $continue = $read_size !== 0; + if ($continue) { + swoole_async_write("$file.copy", $content, $offset, function($write_file, $write_size) use($file, $offset, $read_size, &$n, $i) { + $n--; + + assert($read_size === $write_size); // 断言分块全部写入 + echo "<$i> write [offset=$offset, len=$write_size]\n"; + + if ($n === 0) { + valid_clean($file, $write_file); + } + }); + } + + $offset += $read_size; + $i++; + return $continue; + + }, $chunk); +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async/recursive_write.php b/vendor/swoole/tests/include/api/swoole_async/recursive_write.php new file mode 100755 index 0000000..087e6bf --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async/recursive_write.php @@ -0,0 +1,54 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +//$file = __DIR__ . "/tmp.file"; +// 最大 限制1024M +// user set data swoole_buffer must between 0~1048576 +//$data = file_get_contents("/dev/urandom", null, null, null, 1024 * 1024 + 1); +//swoole_async_write($file, $data, -1, swoole_function($f, $l) { +// var_dump($l); +//}); +//@unlink($file); + + +/* +$recursiveWrite = swoole_function($dep = 0) use($data, &$recursiveWrite, $file, $size) { + swoole_async_write($file, $data, -1, swoole_function ($file, $len) use(&$recursiveWrite, $dep, $size) { + if ($dep > 100) { + echo "SUCCESS"; + unlink($file); + return false; + } + + assert($len === $size); + $recursiveWrite(++$dep); + return true; + }); +}; +*/ +// $recursiveWrite(); + +function recursiveWrite($dep = 0, $size = 1024 * 1024) +{ + static $data; + if ($data === null) { + $data = file_get_contents("/dev/urandom", null, null, null, $size); + } + + $file = "tmp.file"; + + swoole_async_write($file, $data, -1, function ($file, $len) use(&$recursiveWrite, $dep, $size) { + if ($dep > 100) { + echo "SUCCESS"; + unlink($file); + return false; + } + + assert($len === $size); + recursiveWrite(++$dep); + return true; + }); +} + diff --git a/vendor/swoole/tests/include/api/swoole_async/swoole_async_read.php b/vendor/swoole/tests/include/api/swoole_async/swoole_async_read.php new file mode 100755 index 0000000..b7c7d1b --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async/swoole_async_read.php @@ -0,0 +1,66 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_read($filename, $callback, $chunk_size = null, $offset = null) {} + +function read_dev_zero() +{ + $context = file_get_contents("/dev/zero", null, null, null, 8192); + assert(strlen($context) === 8192); + + // TODO WARNING zif_swoole_async_read: offset must be less than file_size[=0]. + swoole_async_read("/dev/zero", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + +function read_dev_null() +{ + $context = file_get_contents("/dev/null", null, null, null, 8192); + assert(strlen($context) === 0); + + // TODO WARNING zif_swoole_async_read: offset must be less than file_size[=0]. + swoole_async_read("/dev/null", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + + +function read_normal_file() +{ + $context = file_get_contents(__FILE__, null, null, null, 8192); + $len = strlen($context); + + swoole_async_read(__FILE__, function ($filename, $content) use($len) { + echo "read callback\n"; +// echo $len, "\n"; +// echo strlen($content), "\n"; +// assert($len === strlen($content)); + + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + +read_dev_zero(); +read_dev_null(); +read_normal_file(); + +// todo read 大文件 \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async/swoole_async_write.php b/vendor/swoole/tests/include/api/swoole_async/swoole_async_write.php new file mode 100755 index 0000000..9d692c3 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async/swoole_async_write.php @@ -0,0 +1,67 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_write($filename, $content, $offset = null, $callback = null) {} +//callback: return true: write contine. return false: close the file. + +function write_dev_zero() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/zero", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_write("/dev/zero", $data, -1, function ($file, $len) { + echo "write /dev/zero $len size\n"; + return true; + }); + } +} + +function write_dev_null() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/null", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_write("/dev/null", $data, -1, function ($file, $len) { + echo "write /dev/null $len size\n"; + return true; + }); + } +} + + +function write_normal_file() +{ + $file = __DIR__ . "/zero"; + + $data = str_repeat("\0", 8192); + $len = file_put_contents($file, $data); + assert($len === 8192); + unlink($file); + + /** @noinspection PhpUnusedLocalVariableInspection + * @param int $dep + */ + $recursiveWrite = function($dep = 0) use($data, &$recursiveWrite, $file) { + swoole_async_write($file, $data, -1, function ($file, $len) use(&$recursiveWrite, $dep) { + if ($dep > 100) { + unlink($file); + return false; + } + + echo "write $file $len size\n"; + $recursiveWrite(++$dep); + return true; + }); + }; + + $recursiveWrite(); + +} + +write_dev_zero(); +write_dev_null(); +write_normal_file(); diff --git a/vendor/swoole/tests/include/api/swoole_async/swoole_pipe_block.php b/vendor/swoole/tests/include/api/swoole_async/swoole_pipe_block.php new file mode 100755 index 0000000..4706a44 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async/swoole_pipe_block.php @@ -0,0 +1,19 @@ +<?php + + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +function block_test($n = 20000) +{ + for ($i = 0; $i < $n; $i++) { + $randStr = RandStr::gen(15); + $host = "www.i_$randStr.com"; + + swoole_async_dns_lookup($host, function($host, $ip) use($i) { + echo "FIN i -> $ip\n"; + }); + } +} + +block_test(); diff --git a/vendor/swoole/tests/include/api/swoole_async_old/read_write.php b/vendor/swoole/tests/include/api/swoole_async_old/read_write.php new file mode 100755 index 0000000..f6e2bc8 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/read_write.php @@ -0,0 +1,77 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +//swoole_function swoole_async_read($filename, $callback, $chunk_size = null, $offset = null) {} +//swoole_function swoole_async_write($filename, $content, $offset = null, $callback = null) {} +//swoole_function swoole_async_readfile($filename, $callback) {} +//swoole_function swoole_async_writefile($filename, $content, $callback = null) {} + +// WARNING zif_swoole_async_readfile: file_size[size=1073741824|max_size=4194304] is too big. Please use swoole_async_read. + +function rw_small_file() { + $file = __DIR__ . "/small_zero"; + + @unlink($file); + @unlink("$file.copy"); + $len = 1024 * 1024 * 4; // 4M + $put_len = file_put_contents($file, str_repeat("\0", $len), FILE_APPEND); + assert($put_len === $len); + + swoole_async_readfile($file, function($filename, $content) use($file) { + swoole_async_writefile("$file.copy", $content, function($write_file) use($file) { + // echo "copy small file finish\n"; + // echo `ls -alh | grep zero`; + assert(filesize($write_file) === filesize($file)); + unlink($write_file); + unlink($file); + echo "SUCCESS"; + }); + }); +} + +function rw_big_file() { + $file = __DIR__ . "/big_zero"; + + @unlink($file); + @unlink("$file.copy"); + // 生成1G文件 + for($i = 0; $i < 1024; $i++) { + $len = 1024 * 1024; + $put_len = file_put_contents($file, str_repeat("\0", $len), FILE_APPEND); + assert($put_len === $len); + } + + // chunk = 1M copy + $i = 0; + swoole_async_read($file, function($filename, $content) use($file, &$i) { + // echo "read " . strlen($content) . " size\n"; + $continue = true; + if (empty($content)) { + $continue = false; + } + + $offset = $i * 1024 * 1024; + // echo "write offset $offset\n"; + swoole_async_write("$file.copy", $content, $offset, function($write_file, $len) use($file, &$i, $continue) { + // echo "write $len size\n"; + $i++; + if ($continue === false) { + // echo "copy finished\n"; + // echo `ls -alh | grep zero`; + sleep(1); + assert(filesize($write_file) === filesize($file)); + unlink($file); + unlink($write_file); + echo "SUCCESS"; + } + }); + + return $continue; + + }, 1024 * 1024); +} + + +rw_small_file(); +rw_big_file(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_read.php b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_read.php new file mode 100755 index 0000000..b7c7d1b --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_read.php @@ -0,0 +1,66 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_read($filename, $callback, $chunk_size = null, $offset = null) {} + +function read_dev_zero() +{ + $context = file_get_contents("/dev/zero", null, null, null, 8192); + assert(strlen($context) === 8192); + + // TODO WARNING zif_swoole_async_read: offset must be less than file_size[=0]. + swoole_async_read("/dev/zero", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + +function read_dev_null() +{ + $context = file_get_contents("/dev/null", null, null, null, 8192); + assert(strlen($context) === 0); + + // TODO WARNING zif_swoole_async_read: offset must be less than file_size[=0]. + swoole_async_read("/dev/null", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + + +function read_normal_file() +{ + $context = file_get_contents(__FILE__, null, null, null, 8192); + $len = strlen($context); + + swoole_async_read(__FILE__, function ($filename, $content) use($len) { + echo "read callback\n"; +// echo $len, "\n"; +// echo strlen($content), "\n"; +// assert($len === strlen($content)); + + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }, 8192); +} + +read_dev_zero(); +read_dev_null(); +read_normal_file(); + +// todo read 大文件 \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_readfile.php b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_readfile.php new file mode 100755 index 0000000..d6068b6 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_readfile.php @@ -0,0 +1,62 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_readfile($filename, $callback) {} + + +function read_dev_zero() +{ + $context = file_get_contents("/dev/zero", null, null, null, 8192); + assert(strlen($context) === 8192); + + // TODO WARNING zif_swoole_async_readfile: file is empty. + swoole_async_readfile("/dev/zero", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }); +} + +function read_dev_null() +{ + $context = file_get_contents("/dev/null", null, null, null, 8192); + assert(strlen($context) === 0); + + // TODO WARNING zif_swoole_async_readfile: file is empty. + swoole_async_readfile("/dev/null", function ($filename, $content) { + echo "file: $filename\ncontent-length: " . strlen($content) . "\nContent: $content\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }); +} + + +function read_normal_file() +{ + $context = file_get_contents(__FILE__, null, null, null, 8192); + $len = strlen($context); + + swoole_async_readfile(__FILE__, function ($filename, $content) use($len) { + echo "read callback\n"; + if (empty($content)) { + echo "file is end.\n"; + return false; + } else { + return true; + } + }); +} + +read_dev_zero(); +read_dev_null(); +read_normal_file(); + +// todo read 大文件 \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_write.php b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_write.php new file mode 100755 index 0000000..9d692c3 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_write.php @@ -0,0 +1,67 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_write($filename, $content, $offset = null, $callback = null) {} +//callback: return true: write contine. return false: close the file. + +function write_dev_zero() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/zero", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_write("/dev/zero", $data, -1, function ($file, $len) { + echo "write /dev/zero $len size\n"; + return true; + }); + } +} + +function write_dev_null() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/null", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_write("/dev/null", $data, -1, function ($file, $len) { + echo "write /dev/null $len size\n"; + return true; + }); + } +} + + +function write_normal_file() +{ + $file = __DIR__ . "/zero"; + + $data = str_repeat("\0", 8192); + $len = file_put_contents($file, $data); + assert($len === 8192); + unlink($file); + + /** @noinspection PhpUnusedLocalVariableInspection + * @param int $dep + */ + $recursiveWrite = function($dep = 0) use($data, &$recursiveWrite, $file) { + swoole_async_write($file, $data, -1, function ($file, $len) use(&$recursiveWrite, $dep) { + if ($dep > 100) { + unlink($file); + return false; + } + + echo "write $file $len size\n"; + $recursiveWrite(++$dep); + return true; + }); + }; + + $recursiveWrite(); + +} + +write_dev_zero(); +write_dev_null(); +write_normal_file(); diff --git a/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_writefile.php b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_writefile.php new file mode 100755 index 0000000..fe3bb9f --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/swoole_async_writefile.php @@ -0,0 +1,63 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_async_writefile($filename, $content, $callback = null) {} + +function write_dev_zero() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/zero", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_writefile("/dev/zero", $data, function ($file, $len) { + echo "write /dev/zero $len size\n"; + }); + } +} + +function write_dev_null() +{ + $data = str_repeat("\0", 8192); + $len = file_put_contents("/dev/null", $data); + assert($len === 8192); + + for ($i = 0; $i < 100; $i++) { + swoole_async_writefile("/dev/null", $data, function ($file, $len) { + echo "write /dev/null $len size\n"; + }); + } +} + + +function write_normal_file() +{ + $file = __DIR__ . "/zero"; + + $data = str_repeat("\0", 8192); + $len = file_put_contents($file, $data); + assert($len === 8192); + unlink($file); + + /** @noinspection PhpUnusedLocalVariableInspection + * @param int $dep + */ + $recursiveWrite = function($dep = 0) use($data, &$recursiveWrite, $file) { + swoole_async_writefile($file, $data, function ($file, $len) use(&$recursiveWrite, $dep) { + if ($dep > 100) { + unlink($file); + return; + } + + echo "write $file $len size\n"; + $recursiveWrite(++$dep); + }); + }; + + $recursiveWrite(); +} + +write_dev_zero(); +write_dev_null(); +write_normal_file(); diff --git a/vendor/swoole/tests/include/api/swoole_async_old/swoole_pipe_block.php b/vendor/swoole/tests/include/api/swoole_async_old/swoole_pipe_block.php new file mode 100755 index 0000000..4706a44 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_async_old/swoole_pipe_block.php @@ -0,0 +1,19 @@ +<?php + + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +function block_test($n = 20000) +{ + for ($i = 0; $i < $n; $i++) { + $randStr = RandStr::gen(15); + $host = "www.i_$randStr.com"; + + swoole_async_dns_lookup($host, function($host, $ip) use($i) { + echo "FIN i -> $ip\n"; + }); + } +} + +block_test(); diff --git a/vendor/swoole/tests/include/api/swoole_callback/swoole_cannot_destroy_active_lambda_function.php b/vendor/swoole/tests/include/api/swoole_callback/swoole_cannot_destroy_active_lambda_function.php new file mode 100755 index 0000000..6eb9b80 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_callback/swoole_cannot_destroy_active_lambda_function.php @@ -0,0 +1,42 @@ +<?php + +// Cannot destroy active lambda swoole_function +// 先用nc起一个 swoole_server +// nc -4lk 9090 + +send("hello", function($cli, $data) { + var_dump($data); + send("hello", function($cli, $data) { + var_dump($data); + send("hello", function($cli, $data) { + var_dump($data); + }); + }); +}); + + + +function send($str, $onRecv) +{ + static $client; + + if ($client === null) { + $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $client->on("error", function($cli) { echo "error"; }); + $client->on("close", function($cli) { echo "close"; }); + + $client->on("connect", function($cli) use($str, $onRecv) { + send($str, $onRecv); + }); + } + + // !!! Fatal error: Cannot destroy active lambda swoole_function + $client->on("receive", $onRecv); + + if ($client->isConnected()) { + $client->send("PING"); + } else { + $client->connect("127.0.0.1", 9090); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_client/connect_timeout.php b/vendor/swoole/tests/include/api/swoole_client/connect_timeout.php new file mode 100755 index 0000000..824e83c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_client/connect_timeout.php @@ -0,0 +1,11 @@ +<?php +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("connect", function(swoole_client $cli) { + assert(false); +}); +$cli->on("receive", function(swoole_client $cli, $data) { + assert(false); +}); +$cli->on("error", function(swoole_client $cli) { echo "connect timeout\n"; }); +$cli->on("close", function(swoole_client $cli) { echo "close\n"; }); +$cli->connect("11.11.11.11", 9000, 0.5); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_client/connect_twice.php b/vendor/swoole/tests/include/api/swoole_client/connect_twice.php new file mode 100755 index 0000000..0650dab --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_client/connect_twice.php @@ -0,0 +1,34 @@ +<?php + +$start = microtime(true); + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("connect", function(swoole_client $cli) { + assert(false); +}); +$cli->on("receive", function(swoole_client $cli, $data) { + assert(false); +}); +$cli->on("error", function(swoole_client $cli) { + echo "error\n"; +}); +$cli->on("close", function(swoole_client $cli) { + echo "close\n"; +}); + +function refcount($var) +{ + ob_start(); + debug_zval_dump($var); + preg_match('/refcount\((?<refcount>\d)\)/', ob_get_clean(), $matches); + return intval($matches["refcount"]) - 3; +} + +@$cli->connect("11.11.11.11", 9000, 0.1); +@$cli->connect("11.11.11.11", 9000, 0.1); +@$cli->connect("11.11.11.11", 9000, 0.1); +@$cli->connect("11.11.11.11", 9000, 0.1); +@$cli->connect("11.11.11.11", 9000, 0.1); +Swoole\Event::wait(); +// xdebug_debug_zval("cli"); +// echo refcount($cli); // php7无效 \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_client/opcode_client.php b/vendor/swoole/tests/include/api/swoole_client/opcode_client.php new file mode 100755 index 0000000..5fa3473 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_client/opcode_client.php @@ -0,0 +1,48 @@ +<?php + + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + + +// suicide(5000); + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +/** @noinspection PhpVoidFunctionResultUsedInspection */ +assert($cli->set([ + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, +])); + +$cli->on("connect", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + assert($cli->isConnected() === true); + +}); + +$cli->on("receive", function(swoole_client $cli, $data){ + + $cli->close(); + assert($cli->isConnected() === false); +}); + +$cli->on("error", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + echo "ERROR"; +}); + +$cli->on("close", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + echo "CLOSE"; +}); + +$cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT); + +$cli->timeo_id = swoole_timer_after(1000, function() use($cli) { + debug_log("connect timeout"); + $cli->close(); + assert($cli->isConnected() === false); +}); diff --git a/vendor/swoole/tests/include/api/swoole_client/simple_client.php b/vendor/swoole/tests/include/api/swoole_client/simple_client.php new file mode 100755 index 0000000..7d4fa5a --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_client/simple_client.php @@ -0,0 +1,63 @@ +<?php + + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + + +suicide(5000); + + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +/** @noinspection PhpVoidFunctionResultUsedInspection */ +assert($cli->set([ + // TODO test + // 'open_eof_check' => true, + // 'package_eof' => "\r\n\r\n", + + // TODO + // "socket_buffer_size" => 1, +])); + +$cli->on("connect", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + + // TODO getSocket BUG + // assert(is_resource($cli->getSocket())); + /* + $cli->getSocket(); + // Warning: swoole_client_async::getSocket(): unable to obtain socket family Error: Bad file descriptor[9]. + $cli->getSocket(); + */ + + + assert($cli->isConnected() === true); + $cli->send(RandStr::gen(1024, RandStr::ALL)); + // $cli->sendfile(__DIR__.'/test.txt'); +}); + +$cli->on("receive", function(swoole_client $cli, $data){ + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $cli->send(RandStr::gen(1024, RandStr::ALL)); + $cli->close(); + assert($cli->isConnected() === false); +}); + +$cli->on("error", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("error"); +}); + +$cli->on("close", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("close"); +}); + +$cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT); +$cli->timeo_id = swoole_timer_after(1000, function() use($cli) { + debug_log("connect timeout"); + $cli->close(); + assert($cli->isConnected() === false); +}); diff --git a/vendor/swoole/tests/include/api/swoole_client/socket_free.php b/vendor/swoole/tests/include/api/swoole_client/socket_free.php new file mode 100755 index 0000000..da3c48e --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_client/socket_free.php @@ -0,0 +1,48 @@ +<?php + +// swoole socket 复用BUG + +function onClose(swoole_client $cli) { + $fd = \EventUtil::getSocketFd($cli->getSocket()); + echo "close fd <$fd>\n"; +} + +function onError(swoole_client $cli) { + $fd = \EventUtil::getSocketFd($cli->getSocket()); + echo "error fd <$fd>\n"; +} + +$host = "127.0.0.1"; +$port = 8050; + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("receive", function(swoole_client $cli, $data){ }); +$cli->on("error", "onError"); +$cli->on("close", "onClose"); + +$cli->on("connect", function(swoole_client $cli) use($host, $port) { + $fd = \EventUtil::getSocketFd($cli->getSocket()); + echo "connected fd <$fd>\n"; + $cli->close(); // close(fd) + + + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + $newCli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $newCli->on("receive", function(swoole_client $cli, $data){ }); + $newCli->on("error", "onError"); + $newCli->on("close", "onClose"); + $newCli->on("connect", function(swoole_client $newCli) use($cli) { + $fd = \EventUtil::getSocketFd($cli->getSocket()); + echo "connected fd <$fd>, reuse!!!\n"; + + echo "free socket\n"; + $cli->__destruct(); + echo "send\n"; + $r = $newCli->send("HELLO"); + }); + $newCli->connect($host, $port); + // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +}); + +$cli->connect($host, $port); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/connect_host_not_found.php b/vendor/swoole/tests/include/api/swoole_http_client/connect_host_not_found.php new file mode 100755 index 0000000..128aeb8 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/connect_host_not_found.php @@ -0,0 +1,16 @@ +<?php +function main() { +$cli = new \swoole_http_client("11.11.11.11", 9000); + +$cli->on('close', function($cli) { + assert(false); +}); + +$cli->on('error', function($cli) { + echo "error"; +}); + +$cli->get('/', function(swoole_http_client $cli) {}); +} + +main(); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/connect_port_not_listen.php b/vendor/swoole/tests/include/api/swoole_http_client/connect_port_not_listen.php new file mode 100755 index 0000000..3cbe9f9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/connect_port_not_listen.php @@ -0,0 +1,12 @@ +<?php +$cli = new swoole_http_client("127.0.0.1", 65535); + +$cli->on('close', function($cli) { + echo "close\n"; +}); + +$cli->on('error', function($cli) { + echo "error\n"; +}); + +$cli->get('/', function(swoole_http_client $cli) {}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/connect_timeout.php b/vendor/swoole/tests/include/api/swoole_http_client/connect_timeout.php new file mode 100755 index 0000000..493bda6 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/connect_timeout.php @@ -0,0 +1,19 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +$cli = new \swoole_http_client("127.0.0.1", 65535); + +$cli->on('close', function($cli) { + echo 'close\n'; +}); + +$cli->on('error', function($cli) { + echo "error\n"; +}); + +swoole_timer_after(500, function() { + swoole_event_exit(); + echo "time out\n"; +}); +$cli->get('/', function(swoole_http_client $cli) {}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/http_request_connect_timeout.php b/vendor/swoole/tests/include/api/swoole_http_client/http_request_connect_timeout.php new file mode 100755 index 0000000..9f1fa55 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/http_request_connect_timeout.php @@ -0,0 +1,10 @@ +<?php +$httpClient = new swoole_http_client("11.11.11.11", 9000); +$httpClient->set(['timeout' => 1]); + +$httpClient->get("/", function ($client) +{ + assert($client->errCode == 110); + assert($client->statusCode == -1); + assert(!$client->body); +}); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/meomry_leak.php b/vendor/swoole/tests/include/api/swoole_http_client/meomry_leak.php new file mode 100755 index 0000000..d281751 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/meomry_leak.php @@ -0,0 +1,38 @@ +<?php + +// swoole_server +$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); +socket_setopt($s, SOL_SOCKET, SO_REUSEADDR, 1); +socket_bind($s, "127.0.0.1", 9090); +socket_listen($s); + +$func = "hello"; + +while($conn = socket_accept($s)) { + socket_write($conn, "HTTP/1.1 200 OK\r\n\r\n"); + socket_write($conn, "HTTP/1.1 200 OK\r\nX-Func: {$func}\r\n\r\n"); + socket_close($conn); +} + + +// client +function hello() { + echo "\n\nhello world!\n\n"; + swoole_event_exit(); + exit(); +} + +function req() { + $cli = new swoole_http_client("127.0.0.1", 9090); + $cli->on("close", function() { + req(); + }); + $cli->get("/", function(swoole_http_client $cli) { + echo "receive:", $cli->body, "\n"; + }); +} + +req(); + + + diff --git a/vendor/swoole/tests/include/api/swoole_http_client/on_error_close.php b/vendor/swoole/tests/include/api/swoole_http_client/on_error_close.php new file mode 100755 index 0000000..94f44a2 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/on_error_close.php @@ -0,0 +1,27 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +// 旧版本因为没有做判断, 构造失败之后, 之后调用close会core + +function error_close_test($desc, $ip, $port) +{ + $cli = new swoole_http_client($ip, $port); + $cli->on("error", function() use($desc) { echo "$desc error\n"; }); + $cli->on("close", function() use($desc) { echo "$desc close\n"; }); + $cli->get("/", function($cli){ }); + swoole_timer_after(1000, function() use($cli) { $cli->close(); }); +} + +// 触发close 回调 +error_close_test("baidu", "115.239.211.112", 80); + +// 触发error回调 +error_close_test("localhost", "127.0.0.1", 9090); + +// TODO 此处行为不正确 +// 应该校验参数是否合法ip, 抛出异常(构造函数无法返回错误) +error_close_test("\\0", "\0", 9090); + +// TODO 同上 +error_close_test("", "null string", 9090); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/on_receive_core.php b/vendor/swoole/tests/include/api/swoole_http_client/on_receive_core.php new file mode 100755 index 0000000..4394e66 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/on_receive_core.php @@ -0,0 +1,27 @@ +<?php + +function create() +{ + $cli = new swoole_http_client("127.0.0.1", 80); + $cli->setHeaders([ + "Host" => "xxx.xxx.xxx", + ]); + $cli->on("error", function() { echo "error"; }); + $cli->on("close", function() { echo "close\n\n"; post(create()); }); + return $cli; +} +post(create()); +function post($cli) { + $cli->post("/xxx/xxx/xxx", [ + "ua" => "younipf", + "debug" => "json", + ], function($cli) { + echo $cli->statusCode, "\n"; + post($cli); + }); +} + + +$payload = <<<HTML +HTTP/1.1 400 Bad Request\r\nDate: Fri, 10 Mar 2017 10:47:07 GMT\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 242\r\nConnection: close\r\n\r\n<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html>\r\n<head><title>400 Bad Request</title></head>\r\n<body bgcolor=\"white\">\r\n<h1>400 Bad Request</h1>\r\n<p>Your browser sent a request that this swoole_server could not understand.</body>\r\n</html>\r\n +HTML; diff --git a/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client.php b/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client.php new file mode 100755 index 0000000..d59e92c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client.php @@ -0,0 +1,352 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +function makeHttpClient($host = HTTP_SERVER_HOST, $port = HTTP_SERVER_PORT, $ssl = false, $output = false, callable $done = null) +{ + $httpClient = new \swoole_http_client($host, $port, $ssl); + + $httpClient->set([ + "socket_buffer_size" => 1024 * 1024 * 2, + 'timeout' => 1.0, + ]); + if ($ssl) { + $httpClient->set([ + 'ssl_cert_file' => __DIR__ . '../swoole_http_server/localhost-ssl/swoole_server.crt', + 'ssl_key_file' => __DIR__ . '../swoole_http_server/localhost-ssl/swoole_server.key', + ]); + } + + $httpClient->on("connect", function(\swoole_http_client $httpClient) { + assert($httpClient->isConnected() === true); + // debug_log("connect"); + }); + + $httpClient->on("error", function(\swoole_http_client $httpClient) use($output, $done) { + if ($output) { + echo "error"; + } + if ($done) { + $done(); + } + // debug_log("error"); + }); + + $httpClient->on("close", function(\swoole_http_client $httpClient) use($output, $done) { + if ($output) { + echo "close"; + } + if ($done) { + $done(); + } + // debug_log("close"); + }); + + return $httpClient; +} + +function testUri($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + + $ok = $httpClient->get("/uri", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === "/uri"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testHttpGet($host, $port, array $query, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + + $queryStr = http_build_query($query); + $ok = $httpClient->get("/get?$queryStr", function (\swoole_http_client $httpClient) use ($query, $fin, $queryStr) + { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + if ($queryStr === "") + { + assert($httpClient->body === "null"); + } + else + { + $ret = json_decode($httpClient->body, true); + assert(arrayEqual($ret, $query, false)); + } + if ($fin) + { + $fin($httpClient); + } + }); + assert($ok); +} + + +function testPost($host, $port, array $query, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + + $ok = $httpClient->post("/post", $query, function(\swoole_http_client $httpClient) use($query, $fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + // $httpClient->headers; + $ret = json_decode($httpClient->body, true); + assert(arrayEqual($ret, $query, false)); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + + +function testMethod($host, $port, $method, $data = null, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + + $ok = $httpClient->setMethod($method); + assert($ok); + if ($data) { + $httpClient->setData($data); + } + $ok = $httpClient->execute("/method", function(\swoole_http_client $httpClient) use($method, $fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === $method); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testCookie($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + $ok = $httpClient->setCookies(["hello" => "world"]); + assert($ok); + + $ok = $httpClient->get("/cookie", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === "{\"hello\":\"world\"}"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +// setCookies 已经加入类型限制 +function testCookieCore($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + $ok = $httpClient->setCookies("hello=world; path=/;"); + assert($ok); + + $ok = $httpClient->get("/cookie", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === "null"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testHeader($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + $httpClient->setting += ["keep_alive" => true]; + // TODO 只要调用setHeaders 则会变为 connection close + $ok = $httpClient->setHeaders(["hello" => "world"]); + assert($ok); + + $ok = $httpClient->get("/header", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + $headers = json_decode($httpClient->body, true); + assert(isset($headers["hello"]) && $headers["hello"] === "world"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +// 已经修复 +function testHeaderCore($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + + // $httpClient->setting += ["keep_alive" => true]; + // COREDUMP + // 旧版传递字符串会发生coredump + // $httpClient->setHeaders("Hello: World\r\nHello: World\r\n"); + $r = $httpClient->setHeaders(["\0" => "\0"]); + + $ok = $httpClient->get("/header", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + $headers = json_decode($httpClient->body, true); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testSleep($host, $port) +{ + $httpClient = makeHttpClient($host, $port); + $ok = $httpClient->get("/sleep", function(\swoole_http_client $httpClient) { + assert(false); + }); + assert($ok); +} + +// http message 分多次接受有问题 (10k message) +function testBigBodyMethodNotSupport($host, $port, callable $fin = null) +{ + if ($fin) { + $httpClient = makeHttpClient($host, $port, false, true, $fin); + } else { + $httpClient = makeHttpClient($host, $port, false, true); + } + $body = str_repeat("\0", 10240); + $ok = $httpClient->post("/", $body, function(\swoole_http_client $httpClient) use($fin) { + echo "SUCCESS\n"; + }); + assert($ok); +} + +// http message 分多次接受有问题 (间隔1s发送) +function testBigBodyMethodNotSupport2($host, $port, callable $fin = null) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function(swoole_client $cli) { + $cli->send("POST / HTTP/1.0\r\nHost: 127.0.0.1\r\nConnection: close\r\nContent-Length: 1\r\n\r\n"); + swoole_timer_after(1, function() use($cli) { + $cli->send("\0"); + }); + }); + + $cli->on("receive", function(swoole_client $cli, $data){ + echo "SUCCESS"; + }); + + $cli->on("error", function(swoole_client $cli) use($fin) { + echo "error"; + if ($fin) { + $fin(); + } + }); + + $cli->on("close", function(swoole_client $cli) use($fin) { + echo "close"; + if ($fin) { + $fin(); + } + }); + + $cli->connect($host, $port); +} + +function testSendfile($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + $httpClient->setMethod("GET"); + $ok = $httpClient->execute("/file", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testRawCookie($host, $port, $cookie, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + $httpClient->setMethod("POST"); + $httpClient->setData($cookie); + $ok = $httpClient->execute("/rawcookie", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + + +function testRawcontent($host, $port, $data, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + if ($data !== false) { + $httpClient->setData($data); + } + + $httpClient->setMethod("POST"); + + $ok = $httpClient->execute("/rawcontent", function(\swoole_http_client $httpClient) use($fin, $data) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testExecute($host, $port, $method, $data, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port); + if ($data !== false) { + $httpClient->setData($data); + } + + if ($method) { + $httpClient->setMethod("POST"); + } + + $ok = $httpClient->execute("/content_length", function(\swoole_http_client $httpClient) use($fin, $data) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function request($host, $port, $method, $url, $body, array $header, array $cookie, callable $finish) +{ + $httpClient = makeHttpClient($host, $port); + $httpClient->setMethod($method); + + if ($cookie) { + $httpClient->setCookies($cookie); + } + if ($header) { + $httpClient->setCookies($header); + } + + if ($body) { + $httpClient->setData($body); + } + + $httpClient->setting += ["keep_alive" => false]; + $httpClient->execute($url, function(\swoole_http_client $httpClient) use($finish) { + $finish($httpClient); + $httpClient->close(); + }); +} diff --git a/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client_test.php b/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client_test.php new file mode 100755 index 0000000..a46e018 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/simple_http_client_test.php @@ -0,0 +1,75 @@ +<?php + +`pkill php-fpm`; +require __DIR__ . "/../../../include/bootstrap.php"; +require_once __DIR__ . "/simple_http_client.php"; + +$host = HTTP_SERVER_HOST; +$port = HTTP_SERVER_PORT; + + +$data = null; +testExecute($host, $port, null, $data, function($httpClient) use($data) { + assert(0 === intval($httpClient->body)); + echo "SUCCESS"; +}); + + +$data = null; +testExecute($host, $port, "POST", $data, function($httpClient) use($data) { + assert(0 === intval($httpClient->body)); + echo "SUCCESS"; +}); + + +$data = RandStr::gen(rand(0, 1024)); +testExecute($host, $port, "POST", $data, function($httpClient) use($data) { + assert(strlen($data) === intval($httpClient->body)); + echo "SUCCESS"; +}); + +exit; + + + +testHttpsHeaderCore($host, $port); +testUri($host, $port); + +testUri($host, $port); +testGet($host, $port, []); +testGet($host, $port, $_SERVER); +testPost($host, $port, $_SERVER); + +testMethod($host, $port, "GET"); +testMethod($host, $port, "DELETE"); + +testMethod($host, $port, "POST", "payload"); +testMethod($host, $port, "PUT", "payload"); +testMethod($host, $port, "PATCH", "payload"); + + +// TODO bug, 没有校验 +// testMethod($host, $port, "GET", "http_body"); +// testMethod($host, $port, "DELETE", "http_body"); +//testMethod($host, $port, "POST", null); +//testMethod($host, $port, "PUT", null); +//testMethod($host, $port, "PATCH", null); + + +testCookie($host, $port); +// TODO coredump +// testCookieCore($host, $port); + +testHttpsHeaderCore($host, $port); +testHeader($host, $port); + +testSleep($host, $port); + + + +//request($host, $port, "GET", "/", null, +// ["cookie_key" => "cookie_value"], +// ["header_key" => "header_value"], +// swoole_function(swoole_http_client $cli) { +// assert($cli->body === "Hello World!"); +// }); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client.php b/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client.php new file mode 100755 index 0000000..3d8e2f7 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client.php @@ -0,0 +1,280 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +/* +class swoole_http_client +{ + public swoole_function __construct() {} + public swoole_function __destruct() {} + public swoole_function set() {} + public swoole_function setMethod() {} + public swoole_function setHeaders() {} + public swoole_function setCookies() {} + public swoole_function setData() {} + public swoole_function execute() {} + public swoole_function push() {} + public swoole_function get() {} + public swoole_function post() {} + public swoole_function isConnected() {} + public swoole_function close() {} + public swoole_function on() {} +} +*/ + + +function addTimer(\swoole_http_client $httpClient) +{ + if (property_exists($httpClient, "timeo_id")) { + return false; + } + return $httpClient->timeo_id = swoole_timer_after(1000, function() use($httpClient) { + debug_log("http request timeout"); + + // TODO 超时强制关闭连接 server端: ERROR swFactoryProcess_finish (ERROR 1005): session#%d does not exist. + $httpClient->close(); + assert($httpClient->isConnected() === false); + }); +} + +function cancelTimer($httpClient) +{ + if (property_exists($httpClient, "timeo_id")) { + $ret = swoole_timer_clear($httpClient->timeo_id); + unset($httpClient->timeo_id); + return $ret; + } + return false; +} + + +function makeHttpClient($host = HTTP_SERVER_HOST, $port = HTTP_SERVER_PORT, $ssl = true) +{ + $httpClient = new \swoole_http_client($host, $port, $ssl); + + $httpClient->set([ + 'timeout' => 1, + "socket_buffer_size" => 1024 * 1024 * 2, + ]); + if ($ssl) { + $httpClient->set([ + 'ssl_cert_file' => __DIR__ . '/../swoole_http_server/localhost-ssl/server.crt', + 'ssl_key_file' => __DIR__ . '/../swoole_http_server/localhost-ssl/server.key', + ]); + } + + $httpClient->on("connect", function(\swoole_http_client $httpClient) { + assert($httpClient->isConnected() === true); + // debug_log("connect"); + }); + + $httpClient->on("error", function(\swoole_http_client $httpClient) { + // debug_log("error"); + }); + + $httpClient->on("close", function(\swoole_http_client $httpClient) { + // debug_log("close"); + }); + + return $httpClient; +} + +function testUri($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + + addTimer($httpClient); + $ok = $httpClient->get("/uri", function(\swoole_http_client $httpClient) use($fin) { + cancelTimer($httpClient); + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === "/uri"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testHttpsGet($host, $port, array $query, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + + $queryStr = http_build_query($query); + $ok = $httpClient->get("/get?$queryStr", function(\swoole_http_client $httpClient) use($query, $fin, $queryStr) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + // $httpClient->headers; + if ($queryStr === "") { + assert($httpClient->body === "null"); + } else { + $ret = json_decode($httpClient->body, true); + assert(arrayEqual($ret, $query, false)); + } + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + + +function testPost($host, $port, array $query, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + + $ok = $httpClient->post("/post", $query, function(\swoole_http_client $httpClient) use($query, $fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + // $httpClient->headers; + $ret = json_decode($httpClient->body, true); + assert(arrayEqual($ret, $query, false)); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + + +function testMethod($host, $port, $method, $data = null, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + + addTimer($httpClient); + $ok = $httpClient->setMethod($method); + assert($ok); + if ($data) { + $httpClient->setData($data); + } + $ok = $httpClient->execute("/method", function(\swoole_http_client $httpClient) use($method, $fin) { + cancelTimer($httpClient); + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === $method); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testCookie($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + addTimer($httpClient); + $ok = $httpClient->setCookies(["hello" => "world"]); + assert($ok); + + $ok = $httpClient->get("/cookie", function(\swoole_http_client $httpClient) use($fin) { + cancelTimer($httpClient); + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + assert($httpClient->body === "{\"hello\":\"world\"}"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testCookieCore($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + addTimer($httpClient); + $ok = $httpClient->setCookies("hello=world; path=/;"); + assert($ok); + + $ok = $httpClient->get("/cookie", function(\swoole_http_client $httpClient) use($fin) { + cancelTimer($httpClient); + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + var_dump($httpClient->body); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testHeader($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + addTimer($httpClient); + + $httpClient->setting += ["keep_alive" => true]; + // TODO 只要调用setHeaders 则会变为 connection close + $ok = $httpClient->setHeaders(["hello" => "world"]); + assert($ok); + + $ok = $httpClient->get("/header", function(\swoole_http_client $httpClient) use($fin) { + cancelTimer($httpClient); + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + $headers = json_decode($httpClient->body, true); + assert(isset($headers["hello"]) && $headers["hello"] === "world"); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +// 已经修复 +function testHttpsHeaderCore($host, $port, callable $fin = null) +{ + $httpClient = makeHttpClient($host, $port, true); + // $httpClient->setting += ["keep_alive" => true]; + // COREDUMP + // 旧版传递字符串会发生coredump + // $httpClient->setHeaders("Hello: World\r\nHello: World\r\n"); + $r = $httpClient->setHeaders(["\0" => "\0"]); + + $ok = $httpClient->get("/header", function(\swoole_http_client $httpClient) use($fin) { + assert($httpClient->statusCode === 200); + assert($httpClient->errCode === 0); + $headers = json_decode($httpClient->body, true); + if ($fin) { + $fin($httpClient); + } + }); + assert($ok); +} + +function testSleep($host, $port) +{ + $httpClient = makeHttpClient($host, $port, true); + addTimer($httpClient); + + $ok = $httpClient->get("/sleep", function(\swoole_http_client $httpClient) { + assert(false); + }); + assert($ok); +} + + +function request($host, $port, $method, $url, $body, array $header, array $cookie, callable $finish) +{ + $httpClient = makeHttpClient($host, $port, true); + addTimer($httpClient); + $httpClient->setMethod($method); + + if ($cookie) { + $httpClient->setCookies($cookie); + } + if ($header) { + $httpClient->setCookies($header); + } + + if ($body) { + $httpClient->setData($body); + } + + $httpClient->setting += ["keep_alive" => false]; + $httpClient->execute($url, function(\swoole_http_client $httpClient) use($finish) { + cancelTimer($httpClient); + $finish($httpClient); + $httpClient->close(); + }); +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client_test.php b/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client_test.php new file mode 100755 index 0000000..b33980a --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/simple_https_client_test.php @@ -0,0 +1,44 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; +require_once __DIR__ . "/simple_https_client.php"; + + +//request($host, $port, "GET", "/", null, +// ["cookie_key" => "cookie_value"], +// ["header_key" => "header_value"], +// swoole_function(swoole_http_client $cli) { +// assert($cli->body === "Hello World!"); +// }); + + + +testUri($host, $port); +testGet($host, $port, []); +testGet($host, $port, $_SERVER); +testPost($host, $port, $_SERVER); + +testMethod($host, $port, "GET"); +testMethod($host, $port, "DELETE"); + +testMethod($host, $port, "POST", "payload"); +testMethod($host, $port, "PUT", "payload"); +testMethod($host, $port, "PATCH", "payload"); + + +// TODO bug, 没有校验 +// testMethod($host, $port, "GET", "http_body"); +// testMethod($host, $port, "DELETE", "http_body"); +//testMethod($host, $port, "POST", null); +//testMethod($host, $port, "PUT", null); +//testMethod($host, $port, "PATCH", null); + + +testCookie($host, $port); +// TODO coredump +// testCookieCore(); + +testHttpsHeaderCore($host, $port); +testHeader($host, $port); + +testSleep($host, $port); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_RST.php b/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_RST.php new file mode 100755 index 0000000..6d509e8 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_RST.php @@ -0,0 +1,33 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +// 旧版本一个bug, 连接收到RST会coredump + +// 1. 对端发送RST +// 2. 对端不回任何segment +function test_connect_refused() +{ + static $clients = []; + $hosts = ["115.239.211.112", "127.0.0.1", "11.11.11.11"]; + + for ($i = 0; $i < 2000; $i++) { + $host = $hosts[$i % 3]; + $port = 8000 + $i; + echo "get $host:$port\n"; + $cli = new swoole_http_client($host, $port); + $cli->setHeaders(["Connection" => "close"]); + $cli->get("/", function(swoole_http_client $cli) { + echo "receive:", $cli->body, "\n"; + }); + swoole_timer_after(3000, function() use($cli, &$clients) { + $cli->close(); + unset($clients[spl_object_hash($cli)]); + }); + + $clients[spl_object_hash($cli)] = $cli; // 防止swoole 引用计数处理错误 + } +} + +test_connect_refused(); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_simple.php b/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_simple.php new file mode 100755 index 0000000..8e55874 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/swoole_http_client_simple.php @@ -0,0 +1,10 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +$cli = new swoole_http_client("115.239.211.112", 80); +$cli->setHeaders(["Connection" => "close"]); +$cli->get("/", function(swoole_http_client $cli) { + echo "receive:", $cli->body, "\n"; +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_client/uaf_client.php b/vendor/swoole/tests/include/api/swoole_http_client/uaf_client.php new file mode 100755 index 0000000..2897edf --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/uaf_client.php @@ -0,0 +1,41 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +/* +require('net').createServer(swoole_function(socket) { + socket.on('data', swoole_function(data) { + socket.write('HTTP/1.1 200 OK\r\n'); + socket.write('Transfer-Encoding: chunked\r\n'); + socket.write('\r\n'); + + var php_func = "hello" + // var php_func = "ReflectionClass::export" + + socket.write('4\r\n'); + socket.write('func\r\n'); + socket.write('0\r\n'); + socket.write('\r\n'); + socket.write('HTTP/1.1 200 OK\r\n'); + socket.write('Transfer-Encoding: ' + php_func + '\r\n'); + socket.write('\r\n'); + }); +}).listen(9090, '127.0.0.1'); + */ + + +// 旧版本会因为因为 use after free +// 回调的zval 指向 parser header的zval +// 最后 call hello + +function hello() { + echo "=======================================\n"; + echo "call hello\n"; + var_dump(func_get_args()); +} + + +$cli = new swoole_http_client("127.0.0.1", 9090); +$cli->get("/", function(swoole_http_client $cli) { + echo "receive:", $cli->body, "\n"; +}); diff --git a/vendor/swoole/tests/include/api/swoole_http_client/uaf_server.js b/vendor/swoole/tests/include/api/swoole_http_client/uaf_server.js new file mode 100755 index 0000000..9f44b5d --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_client/uaf_server.js @@ -0,0 +1,21 @@ +require('net').createServer(function(socket) { + socket.on('data', function(data) { + socket.write('HTTP/1.1 200 OK\r\n'); + socket.write('Transfer-Encoding: chunked\r\n'); + socket.write('\r\n'); + + var php_func = "hello" + // var php_func = "ReflectionClass::export" + + socket.write('4\r\n'); + socket.write('func\r\n'); + socket.write('0\r\n'); + socket.write('\r\n'); + + // 故意构造两条响应 + + socket.write('HTTP/1.1 200 OK\r\n'); + socket.write('Transfer-Encoding: ' + php_func + '\r\n'); + socket.write('\r\n'); + }); +}).listen(9090, '127.0.0.1'); diff --git a/vendor/swoole/tests/include/api/swoole_http_server/htf_swoole20_https_server.php b/vendor/swoole/tests/include/api/swoole_http_server/htf_swoole20_https_server.php new file mode 100755 index 0000000..2d7a6a2 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/htf_swoole20_https_server.php @@ -0,0 +1,11 @@ +<?php +$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); +$http->set([ + 'ssl_cert_file' => __DIR__ . '/localhost-ssl/swoole_server.crt', + 'ssl_key_file' => __DIR__ . '/localhost-ssl/swoole_server.key', +]); +$http->on('request', function ($request, $response) { + $response->header("Content-Type", "text/html; charset=utf-8"); + $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); +}); +$http->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_server/http_server.php b/vendor/swoole/tests/include/api/swoole_http_server/http_server.php new file mode 100755 index 0000000..36cc715 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/http_server.php @@ -0,0 +1,316 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +class HttpServer +{ + /** + * @var \swoole_http_server + */ + public $httpServ; + + public function __construct($host = HTTP_SERVER_HOST, $port = HTTP_SERVER_PORT, $ssl = false) + { + if ($ssl) { + $this->httpServ = new \swoole_http_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); + } else { + $this->httpServ = new \swoole_http_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + } + + $config = [ + // 输出限制 + "buffer_output_size" => 1024 * 1024 * 1024, + "max_connection" => 10240, + "pipe_buffer_size" => 1024 * 1024 * 1024, + // 'enable_port_reuse' => true, + 'user' => 'www-data', + 'group' => 'www-data', + 'log_file' => '/tmp/swoole.log', + 'dispatch_mode' => 3, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + 'daemonize' => 0, + 'reactor_num' => 1, + 'worker_num' => 2, + 'max_request' => 100000, + + /* + 'package_max_length' => 1024 * 1024 * 2 + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + 'open_nova_protocol' => 1, + */ + ]; + + if ($ssl) + { + $config['ssl_cert_file'] = __DIR__ . '/localhost-ssl/server.crt'; + $config['ssl_key_file'] = __DIR__ . '/localhost-ssl/server.key'; + } + $this->httpServ->set($config); + } + + public function start() + { + $this->httpServ->on('start', [$this, 'onStart']); + $this->httpServ->on('shutdown', [$this, 'onShutdown']); + + $this->httpServ->on('workerStart', [$this, 'onWorkerStart']); + $this->httpServ->on('workerStop', [$this, 'onWorkerStop']); + $this->httpServ->on('workerError', [$this, 'onWorkerError']); + + $this->httpServ->on('connect', [$this, 'onConnect']); + $this->httpServ->on('receive', [$this, 'onReceive']); + $this->httpServ->on('request', [$this, 'onRequest']); + + $this->httpServ->on('close', [$this, 'onClose']); + + $sock = $this->httpServ->getSocket(); + if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { + echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL; + } + $this->httpServ->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(\swoole_http_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(\swoole_http_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(\swoole_http_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(\swoole_http_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(\swoole_http_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(\swoole_http_server $swooleServer, $fd, $fromId, $data) + { + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $swooleServer->send($fd, RandStr::gen($recv_len, RandStr::ALL)); + } + + public function onRequest(\swoole_http_request $request, \swoole_http_response $response) + { + $uri = $request->server["request_uri"]; + if ($uri === "/favicon.ico") { + $response->status(404); + $response->end(); + return; + } + + testSetCookie: + { + $name = "name"; + $value = "value"; + // $expire = $request->swoole_server["request_time"] + 3600; + $expire = 0; + $path = "/"; + $domain = ""; + $secure = false; + $httpOnly = true; + // string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] + $response->cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly); + $expect = "name=value; path=/; httponly"; + assert(in_array($expect, $response->cookie, true)); + } + + + if ($uri === "/ping") { + $this->httpServ->send($request->fd, "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\npong\r\n"); + return; + } + + if ($uri === "/gzip") { + $level = 9; + $response->gzip($level); + $response->end(RandStr::gen(1024 * 1024 * 2, RandStr::ALL)); + return; + } + + if ($uri === "/info") { + ob_start(); + print("request_uri: {$uri}\n"); + print("request_method: {$request->server['request_method']}\n"); + + if (property_exists($request, "get")) { + print("get:" . var_export($request->get, true) . "\n"); + } + if (property_exists($request, "post")) { + print("post:" . var_export($request->post, true) . "\n"); + } + if (property_exists($request, "cookie")) { + print("cookie:" . var_export($request->cookie, true) . "\n"); + } + if (property_exists($request, "header")) { + print("header:" . var_export($request->header, true) . "\n"); + } + + $response->end(nl2br(ob_get_clean())); + return; + } + + + + if ($uri === "/uri") { + $response->end($request->server['request_uri']); + return; + } + + if ($uri === "/method") { + $response->end($request->server['request_method']); + return; + } + + if ($uri === "/get") { + if (!empty($request->get)) { + $response->end(json_encode($request->get)); + } else { + $response->end("null"); + } + return; + } + + if ($uri === "/post") { + if (property_exists($request, "post")) { + $response->end(json_encode($request->post)); + } else { + $response->end("{}"); + } + return; + } + + if ($uri === "/cookie") { + if (property_exists($request, "cookie")) { + $response->end(json_encode($request->cookie)); + } else { + $response->end("{}"); + } + return; + } + + if ($uri === "/header") { + if (property_exists($request, "header")) { + $response->end(json_encode($request->header)); + } else { + $response->end("{}"); + } + return; + } + + if ($uri === "/sleep") { + swoole_timer_after(1000, function() use($response) { + $response->end(); + }); + return; + } + + if ($uri === "/404") { + $response->status(404); + $response->end(); + return; + } + + if ($uri === "/302") { + $response->header("Location", "http://www.swoole.com/"); + $response->status(302); + $response->end(); + return; + } + + if ($uri === "/code") { + swoole_async_readfile(__FILE__, function($filename, $contents) use($response) { + $response->end(highlight_string($contents, true)); + }); + return; + } + + if ($uri === "/json") { + $response->header("Content-Type", "application/json"); + $response->end(json_encode($request->server, JSON_PRETTY_PRINT)); + return; + } + + if ($uri === "/chunked") { + $write = function($str) use($request) { return $this->httpServ->send($request->fd, $str); }; + + $write("HTTP/1.1 200 OK\r\n"); + $write("Content-Encoding: chunked\r\n"); + $write("Transfer-Encoding: chunked\r\n"); + $write("Content-Type: text/html\r\n"); + $write("Connection: keep-alive\r\n"); + $write("\r\n"); + + // "0\r\n\r\n" finish + $writeChunk = function($str = "") use($write) { + $hexLen = dechex(strlen($str)); + return $write("$hexLen\r\n$str\r\n"); + }; + $timer = swoole_timer_tick(200, function() use(&$timer, $writeChunk) { + static $i = 0; + $str = RandStr::gen($i++ % 40 + 1, RandStr::CHINESE) . "<br>"; + if ($writeChunk($str) === false) { + swoole_timer_clear($timer); + } + }); + return; + } + + if ($uri === "/content_length") { + // $body = $request->rawcontent(); + if (property_exists($request, "header")) { + if (isset($request->header['content-length'])) { + $response->end($request->header['content-length']); + } else { + $response->end(0); + } + return; + } + } + + if ($uri === "/rawcontent") { + $response->end($request->rawcontent()); + return; + } + + if ($uri === "/file") { + $response->header("Content-Type", "text"); + $response->header("Content-Disposition", "attachment; filename=\"test.php\""); + // TODO 这里会超时 + $response->sendfile(__FILE__); + } + + if ($uri === "/rawcookie") { + $response->cookie($name, $value, $expire, $path, $domain, $secure, $httpOnly); + $response->rawcookie("rawcontent", $request->rawcontent()); + } + + $response->end("Hello World!"); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_http_server/http_server_without_response.php b/vendor/swoole/tests/include/api/swoole_http_server/http_server_without_response.php new file mode 100755 index 0000000..668c3c9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/http_server_without_response.php @@ -0,0 +1,10 @@ +<?php + +$host = isset($argv[1]) ? $argv[1] : HTTP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : HTTP_SERVER_PORT; + +$httpServer = new swoole_http_server($host, $port); +$httpServer->on("request", function ($request, $response) { +}); + +$httpServer->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.crt b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.crt new file mode 100755 index 0000000..2dd2cdc --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICJTCCAY4CCQCyGHb21IPDXjANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJD +TjERMA8GA1UECBMIWmhlamlhbmcxETAPBgNVBAcTCEhhbmd6aG91MQ4wDAYDVQQK +EwVNeSBDQTESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE3MDIwOTA3NTExOVoXDTE3 +MDMxMTA3NTExOVowVzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTEOMAwGA1UEChMFTXkgQ0ExEjAQBgNVBAMTCWxvY2Fs +aG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAkkn6a1CZrX/cDofktWZT +GDMIwIVfMsSOCSTBGTeQoCc7i/Zn6minMyJsD5+s3W6ctpja0JlwKt53ZVgNgrm9 +H6NZyKNKqdWY8ElZwKE7nJ1LGlpS6nbY+M2VVedZLetU66+pi5/tAOsewRXkDemI +4xi6BRU4jIlvT84ovReklXUCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAvGGt+nFvc +sfV/5oqJ43/wZvrA/NfLjtH2hJfBCMB+64gVgzVU/7FF35lTQwgDhAEidzUrUHVP +eI3hxJlVBBAGF5UjLx7rGOAPqm3Vm4C3Xkso90DZzSUo/se/R6bdpO+Iv1icLhFR +uGmMwQb/2DFpiy2XQojkoNwBvI1V9cHGGQ== +-----END CERTIFICATE----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.csr b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.csr new file mode 100755 index 0000000..c2faca9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTEOMAwGA1UEChMFTXkgQ0ExEjAQBgNVBAMTCWxvY2Fs +aG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAkkn6a1CZrX/cDofktWZT +GDMIwIVfMsSOCSTBGTeQoCc7i/Zn6minMyJsD5+s3W6ctpja0JlwKt53ZVgNgrm9 +H6NZyKNKqdWY8ElZwKE7nJ1LGlpS6nbY+M2VVedZLetU66+pi5/tAOsewRXkDemI +4xi6BRU4jIlvT84ovReklXUCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAI+msopi +c6QIu0yYwPix0DyC8FEONih0kOQ//oe1bMLwbox/uxSoRmoJGiOdF7jqZceA0k8H +59SWMGzIUt5MRhDrye/7/LedXDVdCPacYLx7OzIlkBv9Dklk9o26jjT9u3Il7fQx +OfcCm2Lk+cwv3xXm6ZtEmklqKbnAnKd1oBfv +-----END CERTIFICATE REQUEST----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.key b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.key new file mode 100755 index 0000000..43c49e9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCSSfprUJmtf9wOh+S1ZlMYMwjAhV8yxI4JJMEZN5CgJzuL9mfq +aKczImwPn6zdbpy2mNrQmXAq3ndlWA2Cub0fo1nIo0qp1ZjwSVnAoTucnUsaWlLq +dtj4zZVV51kt61Trr6mLn+0A6x7BFeQN6YjjGLoFFTiMiW9Pzii9F6SVdQIDAQAB +AoGAb2J8lbFtEbnE6Bt4fNZIdqiFBXGHprQaIcQmcvjn2cmFgXBAdy7v//M5rDu7 +9239TNrd4O6zhTCWYEfHIb4izQlzj1WNwYm+9JCQ/ZLdD7B3e9IlYxcuw2QfmMJh +SLKITQSXLrCOlkRtRHCeKxC281p8jbpt7cwEPSZ9TNGP8QECQQDCvIXFUTKsb6Vc +UUcwCJBWucMlRA0njSqtcFU6G0LXSL8UspQMBM52T+fkQT1Hcx3rfUCPL9ywZvDG +7ECYDm6FAkEAwE+lhsuling0arIsI+IUT+N24iWYcC6Mq02MNa0A32KsOJs4oXxD +L50KFfsT3aW0V5KgaWipo/RwdQgkBHoWMQJACaauOok7qbAe0eR1UrwZ6zJpqX8l +57/nTZEzqB2Rwnmofq4bCD10vghXxcg18USTRwh+GpqUpWl0pWcwDFkqwQJATWaA +/4ytNtsEdcD6RQL0G+c37PMmtFf34+ZVPTFBPadQG4RVuaDyxZIWAhzItRfBStHH +4ETwqf1y2ZeKL4cXsQJAO0VLkDsUaepjfUMMYGw1cJeKm3ckdLb0+BKx9+Auxl2q +RgF3Nic7M09BbJxaRjjC47nyEA5wVg+G2DVgD4jI0A== +-----END RSA PRIVATE KEY----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.srl b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.srl new file mode 100755 index 0000000..fb21ab2 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/ca.srl @@ -0,0 +1 @@ +BC864F1DFA88521C diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.crt b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.crt new file mode 100755 index 0000000..3d24c6d --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKTCCAZICCQC8hk8d+ohSHDANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJD +TjERMA8GA1UECBMIWmhlamlhbmcxETAPBgNVBAcTCEhhbmd6aG91MQ4wDAYDVQQK +EwVNeSBDQTESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE3MDIwOTA3NTMxMloXDTE3 +MDMxMTA3NTMxMlowWzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEChMJTXkgQ2xpZW50MRIwEAYDVQQDEwls +b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJEUnBzXTTiyUmDb +yhkQoQ/yH1zTnuIk5Meg1Bp0fp1l4kwiizdPbZkk4YkTT/HXdTE6822Cqho+CwGE +VqWZyyd2AZmj87OGb4ZRCyyFzzjfEwdCTvyqZSUBoc1gvSGdEiaA4mXE87Y0XcMB +BasOrfmO76nuzyaXLT7xDjrB+Qw5AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAC09q +KOuSbAW4Zt4I3CZOh3j+bMax++6M37RWCpShCTdaapdm37y436QbtuB9K6ry7MLo +0HcqQksDm8tLmQqEenfhqZo10FiQj0v1ckvg3lzH4OIP5IM0zXkApnlX6aKuOBbC +XMkYSqdwK0A8QNrl051RCKE2CaYK3cnSN0z4+Vs= +-----END CERTIFICATE----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.csr b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.csr new file mode 100755 index 0000000..6b10ec9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBmzCCAQQCAQAwWzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEChMJTXkgQ2xpZW50MRIwEAYDVQQDEwls +b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJEUnBzXTTiyUmDb +yhkQoQ/yH1zTnuIk5Meg1Bp0fp1l4kwiizdPbZkk4YkTT/HXdTE6822Cqho+CwGE +VqWZyyd2AZmj87OGb4ZRCyyFzzjfEwdCTvyqZSUBoc1gvSGdEiaA4mXE87Y0XcMB +BasOrfmO76nuzyaXLT7xDjrB+Qw5AgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQAx +rsaWSV81/SCf+0af57Wr+BJfiGEutZpdmIe0ofPKfVfz7c8QKjqK+/xQb0INUaYd +MUPjuLfvp06iCWyDPsfhsBRZMSDfFZDp8bnoVloVbP+yLL2Gd+h/a5iYjKTJ2FEt +mDaoIXqbw7oHXXxfKKLP2iyUQCqbfJTC0XeJtFWJ3w== +-----END CERTIFICATE REQUEST----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.key b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.key new file mode 100755 index 0000000..71fbdb6 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCRFJwc1004slJg28oZEKEP8h9c057iJOTHoNQadH6dZeJMIos3 +T22ZJOGJE0/x13UxOvNtgqoaPgsBhFalmcsndgGZo/Ozhm+GUQsshc843xMHQk78 +qmUlAaHNYL0hnRImgOJlxPO2NF3DAQWrDq35ju+p7s8mly0+8Q46wfkMOQIDAQAB +AoGAarOFvZB7st8zxxjfImAglOG2P0dE633G5Stb07kqBgkQzn35dcxtBt0hIveZ +LH0SLAr3Tetzv6kx3wO91j2uM1QURztULIcFaDrQyrBbAYoka2WDoxJCSRoGvb9X +7JoyuYtYvbctT8dvYF9mVttq/YdAjFfs7RHwMGSZUc9xkCECQQDA1NNdmsupDZrG +e6sBToEcNuLd/ahB77AS19dWt9WLGSDhG+/wj2bx9l73RTnadenjIPoRaY0RZu4u +fDNlKYErAkEAwJtQn4PSLZe3Rx/FfrGn4pxLFvL/6EgaPKxY1nNd55JY3x15L9A9 +IjODD+CH+BYbYufHfI5n27QIVRDIpNAOKwJAb/2q3BxA1+fs0gWU5WdgmLBPxjnB +dLnt+qOcjuKphOWNMO/2xDGkyjYaJWXxGa2NrrnCQkaZBVhQUHMVrlUSjQJAeUhT ++F5VlwgWDN9gyWqtQPESB510r5vXiaUtO7zhwNRSygwRJ56FIGg3e2PzurCRBjLV +VwWFOL+hD4/GCKJKiQJAfQbp5pZ1Fni/YWo2gmuQi+9kMv3BKfpeHwNclPICY86c +JSAo2+e7Xwz+GHxW9Hqpuz4J1CKjFGS0VzZAFWBi2w== +-----END RSA PRIVATE KEY----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.pem b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.pem new file mode 100755 index 0000000..0d980cf --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/client.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRFJwc1004slJg28oZEKEP8h9c +057iJOTHoNQadH6dZeJMIos3T22ZJOGJE0/x13UxOvNtgqoaPgsBhFalmcsndgGZ +o/Ozhm+GUQsshc843xMHQk78qmUlAaHNYL0hnRImgOJlxPO2NF3DAQWrDq35ju+p +7s8mly0+8Q46wfkMOQIDAQAB +-----END PUBLIC KEY----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.crt b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.crt new file mode 100755 index 0000000..f5d9338 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.crt @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICKTCCAZICCQC8hk8d+ohSGzANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJD +TjERMA8GA1UECBMIWmhlamlhbmcxETAPBgNVBAcTCEhhbmd6aG91MQ4wDAYDVQQK +EwVNeSBDQTESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTE3MDIwOTA3NTIzNloXDTE3 +MDMxMTA3NTIzNlowWzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEChMJTXkgU2VydmVyMRIwEAYDVQQDEwls +b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKg4oNy7liSNUU1T +gZQEEKPJ1znNgbCzbEJ/QlsKhLMzIjiv+xaTvYFffUcZw++NwsCwQUYsdAsmDwQT +4wdTr6JBKwYuKRnyL/l5N/h4VEmNh2MGz2NSqo66QNOiJMOYhmuxmcr08WXPr6Hp +A+KtpQgNt2NFB0nSbb/EvyJgSx85AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAHnKB +iH4Yy7P9dfgJ7/KAB3U15pFYVonPgiqCjVZLgF6rG1F0PNjRBaH24QLg1r/pzbYV +BwsM7WVslRiAx2xh4O3A67GukhPOVerNGcfiFeadqM2e9RVVtcLkwMMfRaL/4oRx +NrkkscP5NrD9lzbVGq9b+heQMYT3fPxokseNngc= +-----END CERTIFICATE----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.csr b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.csr new file mode 100755 index 0000000..5af3eeb --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.csr @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBmzCCAQQCAQAwWzELMAkGA1UEBhMCQ04xETAPBgNVBAgTCFpoZWppYW5nMREw +DwYDVQQHEwhIYW5nemhvdTESMBAGA1UEChMJTXkgU2VydmVyMRIwEAYDVQQDEwls +b2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKg4oNy7liSNUU1T +gZQEEKPJ1znNgbCzbEJ/QlsKhLMzIjiv+xaTvYFffUcZw++NwsCwQUYsdAsmDwQT +4wdTr6JBKwYuKRnyL/l5N/h4VEmNh2MGz2NSqo66QNOiJMOYhmuxmcr08WXPr6Hp +A+KtpQgNt2NFB0nSbb/EvyJgSx85AgMBAAGgADANBgkqhkiG9w0BAQUFAAOBgQA6 +hlKHAfMWwwyqdqsMPd+Q4LetmER+ARnMZTOMSMp1iFXEdTIZwA+WHfxdN+KJ4gnp +3QWpoG+q4O2tyMZQDB9wSAY7LbFyHjzpqq1JJXL2Qpa71NqE0JRZEToAxuyrGf0n +NCpZp0vHFERhgntLkNSM9sMFCWuB6dB1YfeCkTWCeA== +-----END CERTIFICATE REQUEST----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.key b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.key new file mode 100755 index 0000000..86c694e --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQCoOKDcu5YkjVFNU4GUBBCjydc5zYGws2xCf0JbCoSzMyI4r/sW +k72BX31HGcPvjcLAsEFGLHQLJg8EE+MHU6+iQSsGLikZ8i/5eTf4eFRJjYdjBs9j +UqqOukDToiTDmIZrsZnK9PFlz6+h6QPiraUIDbdjRQdJ0m2/xL8iYEsfOQIDAQAB +AoGAPmbbTWaMuLxvd2bNv5GOdqOuIjQYsuqr8zLv84PAXBVQ0YR+eQ6PEsnQWCq3 +o0qL/xyi6hwdY/FXSqTx58rkcIsO7BRlmaQ7uqEgMd52UUej/xAka8mFVJbjAjPR +gB2mGaoO9IiPYFwrjoDA5v/lFq62SLZ81nvOOwbjZxXW3TECQQDS1yGKPuvxOV/w +BVCYwhSALMMXBxhAVi4bDtft6dMqXtOourBpUS9zvGx2GTct4hpzVFGkVt7VONbH +/oGUOKytAkEAzECW/LV5v9R7ufcTbAgbML4+Yh/38lvPg2Oh2f6k1RMerszRJ6nZ +K+wwRnmT+gmPCIiKmebhZ7OkmlUiz6ciPQJBAKijX/VWfJt127F8XsnAOmuG4ggS +KaiUBc6oobdu1fLG5B7KK/4g7IZyyIHxizwM5EEoySBcR2FeVBSlEXm/lwUCQQCC +eFO6MxYFQm6SONBwNrFfrnZc6bzRVHI2pILzpCSYcvEriWulIWq3EtU3f1vV4Rs7 +wTR/4KplOqxPZUiqSkGlAkAy5HpRgBjCG57vHpwIv8jZm3g0/8Kqle5dMp8o8IVI +2gh6YbBt2xIZCgGKKK6VUYz7PdGyEZ+I/41iIeLzftek +-----END RSA PRIVATE KEY----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.pem b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.pem new file mode 100755 index 0000000..8440a4c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/localhost-ssl/server.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoOKDcu5YkjVFNU4GUBBCjydc5 +zYGws2xCf0JbCoSzMyI4r/sWk72BX31HGcPvjcLAsEFGLHQLJg8EE+MHU6+iQSsG +LikZ8i/5eTf4eFRJjYdjBs9jUqqOukDToiTDmIZrsZnK9PFlz6+h6QPiraUIDbdj +RQdJ0m2/xL8iYEsfOQIDAQAB +-----END PUBLIC KEY----- diff --git a/vendor/swoole/tests/include/api/swoole_http_server/simple_http_server.php b/vendor/swoole/tests/include/api/swoole_http_server/simple_http_server.php new file mode 100755 index 0000000..54b46ae --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/simple_http_server.php @@ -0,0 +1,8 @@ +<?php + +require_once __DIR__ . "/http_server.php"; + +$host = isset($argv[1]) ? $argv[1] : HTTP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : HTTP_SERVER_PORT; + +(new HttpServer($host, $port, false))->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_http_server/simple_https_server.php b/vendor/swoole/tests/include/api/swoole_http_server/simple_https_server.php new file mode 100755 index 0000000..687d29c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_http_server/simple_https_server.php @@ -0,0 +1,30 @@ +<?php +require_once __DIR__ . "/http_server.php"; + + +/* +class swoole_http_server extends swoole_server +{ + public swoole_function on($name, $cb) {} // 与 tcp swoole_server 的on接受的eventname 不同 +} +class swoole_http_response +{ + public swoole_function cookie() {} + public swoole_function rawcookie() {} + public swoole_function status() {} + public swoole_function gzip() {} + public swoole_function header() {} + public swoole_function write() {} + public swoole_function end() {} + public swoole_function sendfile() {} +} +class swoole_http_request +{ +public swoole_function rawcontent() {} +} + */ + +$host = isset($argv[1]) ? $argv[1] : HTTP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : HTTP_SERVER_PORT; + +(new HttpServer($host, $port, true))->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/mysqli.php b/vendor/swoole/tests/include/api/swoole_mysql/mysqli.php new file mode 100755 index 0000000..a6b5fb0 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/mysqli.php @@ -0,0 +1,67 @@ +<?php + +$pdo = new \PDO('swoole_mysql:dbname=db_koudaitong;host=127.0.0.1;port=3007', 'user_koudaitong', 'ocfLsVO7l2B3TMOPmpSX'); + +// 1 +//$stmt = $pdo->prepare("select * from attachment where mp_id = :mp_id LIMIT 10"); +//$stmt->bindValue(":mp_id", 1, \PDO::PARAM_INT); + +// 2 +$stmt = $pdo->prepare("select * from attachment where mp_id = ? LIMIT 10"); +$stmt->bindValue(1, 1, \PDO::PARAM_INT); + +$stmt->execute(); +$r = $stmt->fetchAll(\PDO::FETCH_ASSOC); +var_dump($r); + + +$mysqli = new \mysqli(); +$mysqli->connect('127.0.0.1', 'user_koudaitong', 'ocfLsVO7l2B3TMOPmpSX', 'db_koudaitong', '3007'); + +if ($mysqli->connect_errno) { + printf("Connect failed: [errno=%d]%s\n", $mysqli->connect_errno, $mysqli->connect_error); + exit(); +} + +$stmt = $mysqli->prepare("select * from attachment where mp_id = ? LIMIT 10"); +if ($stmt) { + $kdt_id = 1; + $stmt->bind_param("i", $kdt_id); + $stmt->execute(); + $stmt->bind_result($r); + $stmt->fetch(); + + var_dump($r); + + $stmt->close(); +} else { + printf("Prepare failed: [errno=%d]%s\n", $mysqli->errno, $mysqli->error); +} + +$mysqli->close(); + + + + + +//require_once __DIR__ . "/swoole_mysql_init.php"; + +// sql syntax error +//$ret = $link->query("select"); +//echo $link->error, "\n"; // You have an error in your SQL syntax; check the manual that corresponds to your MySQL swoole_server version for the right syntax to use near '' at line 1 +//echo $link->errno; //1064 +//exit; + +// select +//$ret = $link->query("select 1, 1, 1"); +// var_dump(mysqli_fetch_field($ret)); +// var_dump(mysqli_fetch_assoc($ret)); +// var_dump(mysqli_fetch_all($ret)); +//exit; + + +// insert +//$ret = $link->query("insert into ad (`kdt_id`, `num`, `data`, `valid`, `created_time`, `update_time`) VALUES (99999, 1, 'data', 1, 0, 0)"); +//var_dump($ret); +//var_dump($link->insert_id); +//exit; \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/query_without_connect.php b/vendor/swoole/tests/include/api/swoole_mysql/query_without_connect.php new file mode 100755 index 0000000..1450be5 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/query_without_connect.php @@ -0,0 +1,50 @@ +<?php + +require_once __DIR__ . "/swoole_mysql_init.php"; + +$sql = "select 1"; +$bind = []; + +$onQuery = function($mysql_result, $result) { + var_dump($result); + swoole_event_exit(); + fprintf(STDERR, "SUCCESS"); +}; + +$swoole_mysql = new \swoole_mysql(); + +$swoole_mysql->on("connect", function(\swoole_mysql $swoole_mysql) use($sql, $bind, $onQuery, $swoole_mysql) { +// $swoole_mysql->query($sql, $bind, swoole_function(\swoole_mysql $swoole_mysql, $result) use($onQuery) { +// $onQuery($swoole_mysql, $result); +// $swoole_mysql->close(); +// }); +}); + +$swoole_mysql->on("error", function(\swoole_mysql $swoole_mysql) use($onQuery, $swoole_mysql) { + $onQuery($swoole_mysql, "connection error"); +}); + +$swoole_mysql->on("close", function() { + echo "closed\n"; +}); + + +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +]); + +// 未连上 直接 调用query +$r = $swoole_mysql->query($sql, $bind, function(\swoole_mysql $swoole_mysql, $result) use($onQuery) { + var_dump("query cb"); + // TODO error error_no + $onQuery($swoole_mysql, $result); + // $swoole_mysql->close(); +}); + +// 此处返回true 不符合预期 +var_dump($r); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_timeout.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_timeout.php new file mode 100755 index 0000000..8e54879 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_timeout.php @@ -0,0 +1,21 @@ +<?php +$swoole_mysql = new \swoole_mysql(); + +$swoole_mysql->on("close", function () +{ + echo "closed\n"; + swoole_event_exit(); +}); + +$r = $swoole_mysql->connect([ + "host" => "11.11.11.11", + "port" => 9000, + "user" => "root", + "password" => "admin", + "database" => "test", + "charset" => "utf8mb4", + 'timeout' => 1.0, +], function (\swoole_mysql $swoole_mysql, $result) +{ + assert($result === false); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_twice.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_twice.php new file mode 100755 index 0000000..efa0cf1 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_connect_twice.php @@ -0,0 +1,63 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +$onQuery = function ($swoole_mysql, $result) +{ + assert($swoole_mysql->errno === 0); + + $swoole_mysql->query("select 1", function ($swoole_mysql, $result) + { + assert($swoole_mysql->errno === 0); + echo "SUCCESS\n"; + swoole_event_exit(); + }); +}; + +$sql = "show tables"; +$swoole_mysql = new \swoole_mysql(); + +$swoole_mysql->on("close", function () +{ + echo "closed\n"; +}); + +$onConnect = function (\swoole_mysql $swoole_mysql, $result) use ($sql, $onQuery) +{ + if ($result) + { + $swoole_mysql->query_timeout = swoole_timer_after(1000, function () use ($onQuery, $swoole_mysql) + { + $onQuery($swoole_mysql, "query timeout"); + }); + + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) use ($onQuery) + { + swoole_timer_clear($swoole_mysql->query_timeout); + $onQuery($swoole_mysql, $result); + }); + } + else + { + echo "connect to swoole_mysql swoole_server[{$swoole_mysql->serverInfo['host']}:{$swoole_mysql->serverInfo['port']}] error [errno=$swoole_mysql->connect_errno, error=$swoole_mysql->connect_error]"; + } +}; + +$r = $swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], $onConnect); +assert($r); + +$r = @$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], $onConnect); +assert($r === false); diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_init.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_init.php new file mode 100755 index 0000000..389a90d --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_init.php @@ -0,0 +1,34 @@ +<?php +require_once __DIR__ . "/../../../include/bootstrap.php"; + +function swoole_mysql_query($sql, callable $onQuery) +{ + $mysql = new \swoole_mysql(); + + $mysql->on("close", function () + { + echo "closed\n"; + }); + + $mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", + ], function (\swoole_mysql $mysql, $result) use ($sql, $onQuery) + { + if ($result) + { + $mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) use ($onQuery) + { + $onQuery($swoole_mysql, $result); + }); + } + else + { + echo "connect error [errno=$mysql->connect_errno, error=$mysql->connect_error]"; + } + }); +} diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_memory_leak.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_memory_leak.php new file mode 100755 index 0000000..0fcaba8 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_memory_leak.php @@ -0,0 +1,57 @@ +<?php + +// 轻微内存泄漏 +//while (true) { +// echo memory_get_usage(), "\n"; +// $pdo = new \PDO('swoole_mysql:dbname=test;host=127.0.0.1;port=3306', 'root', '123456'); +// $stmt = $pdo->prepare("select * from test"); +// $stmt->execute(); +// $r = $stmt->fetchAll(\PDO::FETCH_ASSOC); +// // var_dump(count($r)); +//} + + +$sql = "select * from component_v2"; +define("MYSQL_SERVER_HOST", "127.0.0.1"); +define("MYSQL_SERVER_PORT", 3306); +define("MYSQL_SERVER_USER", "test_database"); +define("MYSQL_SERVER_PWD", "test_database"); +define("MYSQL_SERVER_DB", "test_database"); + + +//$sql = "select * from test"; +//define("MYSQL_SERVER_HOST", "127.0.0.1"); +//define("MYSQL_SERVER_PORT", 3306); +//define("MYSQL_SERVER_USER", "root"); +//define("MYSQL_SERVER_PWD", "123456"); +//define("MYSQL_SERVER_DB", "test"); + + +class Callback +{ + public $sql; + public $result; + public function __construct($sql) + { + $this->sql = $sql; + } + public function __invoke($mysql, $result) + { + echo memory_get_usage(), "\n"; + $this->result = $result; + $mysql->query($this->sql, new Callback($this->sql)); + } +} + +$swoole_mysql = new \swoole_mysql(); +$swoole_mysql->on("close", function() { echo "closed\n"; }); +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], function(\swoole_mysql $mysql) use($sql) { + $mysql->query($sql, new Callback($sql)); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_on_check.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_on_check.php new file mode 100755 index 0000000..55418f0 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_on_check.php @@ -0,0 +1,13 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +$swoole_mysql = new \swoole_mysql(); +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], null); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_multi_filed.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_multi_filed.php new file mode 100755 index 0000000..a5da134 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_multi_filed.php @@ -0,0 +1,16 @@ +<?php + +require_once __DIR__ . "/swoole_mysql_init.php"; + + +$n = 1024 * 1024; +$fields = implode(", ", range(0, $n - 1)); + +swoole_mysql_query("select $fields", function($swoole_mysql, $result) { + if ($swoole_mysql->errno === 0) { + fprintf(STDERR, "SUCCESS"); + } else { + fprintf(STDERR, "ERROR"); + } + swoole_event_exit(); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_same_filed.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_same_filed.php new file mode 100755 index 0000000..be716fb --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_query_same_filed.php @@ -0,0 +1,27 @@ +<?php + +require_once __DIR__ . "/swoole_mysql_init.php"; + +//$pdo = new \PDO("swoole_mysql:dbname=showcase;host=127.0.0.1", "test_database", "test_database"); +//$ret = $pdo->query("select 1, 1"); +//var_dump($ret->fetchAll()); +//exit; + +//$link = new \mysqli(); +//swoole_mysql_query(); +//$link->connect(MYSQL_SERVER_HOST, MYSQL_SERVER_USER, MYSQL_SERVER_PWD, MYSQL_SERVER_DB, MYSQL_SERVER_PORT); +//$ret = $link->query("select 1, 1"); +//$ret = $link->query("select * from ad"); +//var_dump($ret); +//var_dump(mysqli_fetch_assoc($ret)); +//var_dump(mysqli_fetch_field($ret)); +//var_dump(mysqli_fetch_all($ret)); +//exit; + + +swoole_mysql_query("select 1, 1", function($swoole_mysql, $result) { + assert($swoole_mysql->errno === 0); + var_dump($result); + assert(count($result[0]) === 2); + swoole_event_exit(); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_recursive_query.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_recursive_query.php new file mode 100755 index 0000000..7d34729 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_recursive_query.php @@ -0,0 +1,46 @@ +<?php + +require_once __DIR__ . "/swoole_mysql_init.php"; + +function query($swoole_mysql, $dep = 0) +{ + + $sql = "select 1"; + $swoole_mysql->query($sql, function(\swoole_mysql $swoole_mysql, $result) use($dep) { + // echo ".\n"; + if ($dep > 20) { + fprintf(STDERR, "SUCCESS\n"); + swoole_event_exit(); + } else { + if ($swoole_mysql->errno !== 0) { + fprintf(STDERR, "FAIL"); + swoole_event_exit(); + } else { + query($swoole_mysql, ++$dep); + } + } + }); +} + +$swoole_mysql = new \swoole_mysql(); +$swoole_mysql->on("close", function() { + echo "closed\n"; +}); + + +$swoole_mysql->conn_timeout = swoole_timer_after(1000, function() { + echo "connecte timeout\n\n\n"; +}); + +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], function(\swoole_mysql $swoole_mysql) { + assert($swoole_mysql->errno === 0); + swoole_timer_clear($swoole_mysql->conn_timeout); + query($swoole_mysql); +}); diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_refcout.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_refcout.php new file mode 100755 index 0000000..6b5aa0d --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_refcout.php @@ -0,0 +1,26 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +$i = 10000; +$start = $end = 0; +while($i--) { + if ($i == 99) { + $start = memory_get_usage(); + } + // 不应该在构造函数加引用计数 + $swoole_mysql = new \swoole_mysql(); + // xdebug_debug_zval("swoole_mysql"); // 2 + if ($i == 1) { + $end = memory_get_usage(); + } +} + + +if (($end - $start) < 1000) { + fprintf(STDERR, "SUCCESS"); +} else { + fprintf(STDERR, "FAIL"); +} +swoole_event_exit(); diff --git a/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_sql_syntax_error.php b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_sql_syntax_error.php new file mode 100755 index 0000000..97c8038 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_mysql/swoole_mysql_sql_syntax_error.php @@ -0,0 +1,12 @@ +<?php + +require_once __DIR__ . "/swoole_mysql_init.php"; + +swoole_mysql_query("select", function($mysql_result, $result) { + if ($mysql_result->errno === 1064) { + fprintf(STDERR, "SUCCESS"); + } else { + fprintf(STDERR, "FAIL"); + } + swoole_event_exit(); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_redis/connect_timeout.php b/vendor/swoole/tests/include/api/swoole_redis/connect_timeout.php new file mode 100755 index 0000000..940680e --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/connect_timeout.php @@ -0,0 +1,15 @@ +<?php +$redis = new swoole_redis(); +$redis->on("close", function (){ + echo "closed\n"; +}); + +$redis->on("message", function (){ + echo "message\n"; +}); + +$result = $redis->connect("192.1.1.1", 9000, function ($redis, $result) +{ + assert($redis->errCode == SOCKET_ETIMEDOUT); + assert($result === false); +}); diff --git a/vendor/swoole/tests/include/api/swoole_redis/doublefree_client.php b/vendor/swoole/tests/include/api/swoole_redis/doublefree_client.php new file mode 100755 index 0000000..efcce00 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/doublefree_client.php @@ -0,0 +1,61 @@ +<?php + +function get(\swoole_redis $redis) +{ + // TODO 为什么需要timer,否则call返回false TIMER ??? + swoole_timer_after(1, function() use($redis) { + $r = $redis->get("HELLO", function(\swoole_redis $redis, $result) { + var_dump($result); + get($redis); + }); + assert($r); + $redis->close(); + test(); + }); +} + +function test() +{ + $redis = new \swoole_redis(); + $redis->on("close", function(\swoole_redis $redis) { + echo "close\n\n"; + test(); + // 死循环 + // $swoole_redis->close(); + }); + + $redis->connect("127.0.0.1", 6379, function(\swoole_redis $redis, $connected) { + assert($connected); + // get($swoole_redis); + $redis->get("HELLO", function(\swoole_redis $redis, $result) {}); + }); +} + +test(); +return; + +function test1() { + $redis = new \swoole_redis(); + $redis->on("close", function() { echo "close"; }); + + $redis->connect("127.0.0.1", 6379, function(\swoole_redis $redis, $connected) { + assert($connected); + + swoole_timer_after(1, function() use($redis) { + $r = $redis->get("HELLO", function(\swoole_redis $redis, $result) { + var_dump($redis); + var_dump($result); + test(); + }); + assert($r); + swoole_timer_after(1, function() use($redis) { +// $r = $swoole_redis->close(); +// var_dump($r); +// $swoole_redis->close(); + }); + }); + }); +} + +test1(); + diff --git a/vendor/swoole/tests/include/api/swoole_redis/doublefree_server.php b/vendor/swoole/tests/include/api/swoole_redis/doublefree_server.php new file mode 100755 index 0000000..2599bf8 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/doublefree_server.php @@ -0,0 +1,54 @@ +<?php + +(new FakeRedisServer())->start(); + +class FakeRedisServer +{ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server("0.0.0.0", 6379, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set(["worker_num" => 1]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onClose() {} + public function onStart(swoole_server $swooleServer) {} + public function onShutdown(swoole_server $swooleServer) {} + public function onWorkerStart(swoole_server $swooleServer, $workerId) {} + public function onWorkerStop(swoole_server $swooleServer, $workerId) {} + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) {} + + public function onConnect(swoole_server $swooleServer, $fd) { + // $swooleServer->close($fd); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + $swooleServer->send($fd, "\0"); + return; + + $swooleServer->send($fd, "$-1\r\n"); + echo $data; + swoole_timer_after(1000, function() use($swooleServer, $fd) { + $swooleServer->close($fd); + }); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_redis/redis_server_without_response.php b/vendor/swoole/tests/include/api/swoole_redis/redis_server_without_response.php new file mode 100755 index 0000000..f4d16ef --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/redis_server_without_response.php @@ -0,0 +1,13 @@ +<?php +$host = isset($argv[1]) ? $argv[1] : HTTP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : HTTP_SERVER_PORT; + +$swoole = new swoole_server($host, $port); + +$swoole->on("connect", function ($server, $fd) { +}); + +$swoole->on("receive", function ($server, $fd, $from_id, $data) { +}); + +$swoole->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_redis/redis_test.php b/vendor/swoole/tests/include/api/swoole_redis/redis_test.php new file mode 100755 index 0000000..0d33753 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/redis_test.php @@ -0,0 +1,67 @@ +<?php + +define("REDIS_SERVER_HOST", "127.0.0.1"); +define("REDIS_SERVER_PORT", 6379); + +$redis = new \swoole_redis(); +$redis->on("close", function() { echo "close"; }); + +// !!!! For SUBSCRIBE +$redis->on("message", function() { var_dump(func_get_args()); }); + +$redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT, function(\swoole_redis $redis, $connected) { + if ($connected === false) { + fputs(STDERR, "ERROR:$redis->errMsg($redis->errCode)\n"); + echo "connected fail"; + return; + } + echo "connected\n"; + +$luaScript = <<<LUA +error scripr +LUA; +$redis->eval($luaScript, 0, function(\swoole_redis $redis, $result) { + if ($result === false) { + // TODO WTF ? 错误信息呢?! + // 这里的errMsg 与 errCode是socket的 + // 那redis原生的呢?! + // 抓包可以看到错误返回信息 + fputs(STDERR, "ERROR:$redis->errMsg($redis->errCode)\n"); + } else { + var_dump($result); + } + $redis->close(); +}); + return; + + + + /** + * evalsha + * SCRIPT FLUSH :清除所有脚本缓存 + * SCRIPT EXISTS :根据给定的脚本校验和,检查指定的脚本是否存在于脚本缓存 + * SCRIPT LOAD :将一个脚本装入脚本缓存,但并不立即运行它 + * SCRIPT KILL :杀死当前正在运行的脚本 + */ + + $luaScript = <<<LUA +return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]} +LUA; + $keyNum = 2; + $key1 = "key1"; + $key2 = "key2"; + $val1 = "first"; + $val2 = "second"; + $r = $redis->eval($luaScript, $keyNum, $key1, $key2, $val1, $val2, function(\swoole_redis $redis, $result) { + if ($result === false) { + var_dump($redis); + redis_error($redis); + // WTF + // -ERR Error compiling script (new swoole_function): user_script:1: unfinished string near '<eof>' + } else { + var_dump($result); + } + $redis->close(); + }); + assert($r === true); +}); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_redis/simple_redis.php b/vendor/swoole/tests/include/api/swoole_redis/simple_redis.php new file mode 100755 index 0000000..9c40eaf --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_redis/simple_redis.php @@ -0,0 +1,43 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +class Obj +{ +} + +$redis = new swoole_redis(); +$redis->on("close", function () +{ + echo "close"; +}); +$redis->on("message", function () +{ + var_dump(func_get_args()); +}); + +define('REDIS_TEST_KEY', "swoole:test:key_" . md5(microtime())); +define('REDIS_TEST_VALUE', RandStr::gen(128, RandStr::ALPHA | RandStr::NUM | RandStr::CHINESE)); + +// $swoole_redis->connect(REDIS_SERVER_PATH, false, swoole_function() {}); TODO +$redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT, function (\swoole_redis $redis) +{ + $redis->get(REDIS_TEST_KEY, function (\swoole_redis $redis, $result) + { + assert($result === null); + $redis->set(REDIS_TEST_KEY, REDIS_TEST_VALUE, function (\swoole_redis $redis, $result) + { + assert($result === 'OK'); + $redis->get(REDIS_TEST_KEY, function (\swoole_redis $redis, $result) + { + assert($result === REDIS_TEST_VALUE); + $redis->del(REDIS_TEST_KEY, function (\swoole_redis $redis, $result) + { + assert($result === 1); + $redis->close(); + }); + }); + }); + }); +}); diff --git a/vendor/swoole/tests/include/api/swoole_server/TestServer.php b/vendor/swoole/tests/include/api/swoole_server/TestServer.php new file mode 100755 index 0000000..78e589f --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/TestServer.php @@ -0,0 +1,101 @@ +<?php +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +abstract class TestServer +{ + protected $index = array(); + protected $recv_bytes = 0; + protected $count = 0; + protected $show_lost_package = false; + + const PKG_NUM = 100000; + const LEN_MIN = 0; + const LEN_MAX = 200; + + /** + * @var swoole_server + */ + protected $serv; + + abstract function onReceive($serv, $fd, $reactor_id, $data); + + function __construct($base = false) + { + $mode = $base ? SWOOLE_BASE : SWOOLE_PROCESS; + $serv = new swoole_server("127.0.0.1", 9501, $mode); + $serv->on('Connect', [$this, 'onConnect']); + $serv->on('receive', [$this, '_receive']); + $serv->on('workerStart', [$this, 'onWorkerStart']); + $serv->on('Close', [$this, 'onClose']); + $this->serv = $serv; + } + + function onConnect($serv, $fd, $from_id) + { + + } + + function _receive($serv, $fd, $from_id, $data) + { + $this->count++; + $this->recv_bytes += strlen($data); + $this->onReceive($serv, $fd, $from_id, $data); + if ($this->count == self::PKG_NUM) + { + $serv->send($fd, "end\n"); + } + } + + function onClose($serv, $fd, $from_id) + { + echo "Total count={$this->count}, bytes={$this->recv_bytes}\n"; + if ($this->show_lost_package) + { + for ($i = 0; $i < self::PKG_NUM; $i++) + { + if (!isset($this->index[$i])) + { + echo "lost package#$i\n"; + } + } + } + $this->count = $this->recv_bytes = 0; + unset($this->index); + $this->index = array(); + } + + function set($conf) + { + $this->serv->set($conf); + } + + function start() + { + $this->serv->start(); + } + + function onWorkerStart($serv, $id) + { + //sleep(1); + } + + static function random() + { + return rand(self::LEN_MIN, self::LEN_MAX); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/manager_process_exit.log b/vendor/swoole/tests/include/api/swoole_server/manager_process_exit.log new file mode 100755 index 0000000..6926a49 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/manager_process_exit.log @@ -0,0 +1,16 @@ +[2017-01-09 20:48:45 *7139.0] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:48:45 *7140.1] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:48:45 #7136.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=0] +[2017-01-09 20:48:45 #7136.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=1] +[2017-01-09 20:48:48 #7136.0] WARNING swServer_signal_hanlder: Fatal Error: manager process exit. status=1, signal=23. +[2017-01-09 20:48:48 *7140.1] ERROR swFactoryProcess_finish (ERROR 1004): send 1024 byte failed, because session#1 is closed. +[2017-01-09 20:49:14 *7149.0] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:49:14 @7146.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=0] +[2017-01-09 20:49:14 *7150.1] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:49:14 #7146.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=1] +[2017-01-09 20:49:16 #7146.0] WARNING swServer_signal_hanlder: Fatal Error: manager process exit. status=24, signal=38. +[2017-01-09 20:50:23 *7158.1] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:50:23 *7157.0] WARNING swServer_tcp_deny_exit: swServer_tcp_deny_exit +[2017-01-09 20:50:23 #7154.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=1] +[2017-01-09 20:50:23 #7154.0] WARNING swReactorThread_onPipeReceive: [Master] set worker idle.[work_id=0] +[2017-01-09 20:50:24 #7154.0] WARNING swServer_signal_hanlder: Fatal Error: manager process exit. status=49, signal=82. diff --git a/vendor/swoole/tests/include/api/swoole_server/multi_protocol_server.php b/vendor/swoole/tests/include/api/swoole_server/multi_protocol_server.php new file mode 100755 index 0000000..106935c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/multi_protocol_server.php @@ -0,0 +1,110 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//(new OpcodeServer("127.0.0.1", 9999, 9998, 9997))->start(PHP_INT_MAX); + +$host = isset($argv[1]) ? $argv[1] : null; +$port = isset($argv[2]) ? $argv[2] : null; +$port1 = isset($argv[3]) ? $argv[3] : null; +$port2 = isset($argv[4]) ? $argv[4] : null; + +(new OpcodeServer($host, $port, $port1, $port2))->start(); + +class OpcodeServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct($host, $port, $port1, $port2) + { + $this->swooleServer = new \swoole_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + 'dispatch_mode' => 3, + 'worker_num' => 2, + + 'open_eof_split' => true, + 'package_eof' => "\r\n", + ]); + + $this->swooleServer->on("receive", function(\swoole_server $server, $fd, $fromReactorId, $recv) use($port) { + assert(intval($recv) === $port); + $r = $server->send($fd, opcode_encode("return", $port)); + assert($r !== false); + }); + + $serv1 = $this->swooleServer->listen(TCP_SERVER_HOST, $port1, SWOOLE_SOCK_TCP); + assert($serv1 !== false); + + + $serv1->set([ + 'open_eof_split' => true, + 'package_eof' => "\r", + ]); + + $serv1->on("receive", function(\swoole_server $server, $fd, $fromReactorId, $recv) use($port1) { + assert(intval($recv) === $port1); + $r = $server->send($fd, opcode_encode("return", $port1)); + assert($r !== false); + }); + + + $serv2 = $this->swooleServer->listen(TCP_SERVER_HOST, $port2, SWOOLE_SOCK_TCP); + assert($serv2 !== false); + + $serv2->set([ + 'open_eof_split' => true, + 'package_eof' => "\n", + ]); + + + $serv2->on("receive", function(\swoole_server $server, $fd, $fromReactorId, $recv) use($port2) { + assert(intval($recv) === $port2); + $r = $server->send($fd, opcode_encode("return", $port2)); + assert($r !== false); + }); + + } + + public function start($lifetime = 1000) + { + $this->lifetime = $lifetime; + + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() { } + public function onClose() { } + public function onStart(\swoole_server $swooleServer) { } + public function onShutdown(\swoole_server $swooleServer) { } + public function onWorkerStart(\swoole_server $swooleServer, $workerId) + { + if ($workerId === 0) { + swoole_timer_after($this->lifetime, function() { + $this->swooleServer->shutdown(); + kill_self_and_descendant(getmypid()); + /* + \swoole_process::signal(SIGTERM, swoole_function() { + $this->swooleServer->shutdown(); + }); + \swoole_process::kill(0, SIGTERM); + */ + }); + } + } + public function onWorkerStop(\swoole_server $swooleServer, $workerId) { } + public function onWorkerError(\swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) { } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/opcode_server.php b/vendor/swoole/tests/include/api/swoole_server/opcode_server.php new file mode 100755 index 0000000..6f09f14 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/opcode_server.php @@ -0,0 +1,183 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +// (new OpcodeServer("127.0.0.1", 9999))->start(PHP_INT_MAX); + +$host = isset($argv[1]) ? $argv[1] : HTTP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : HTTP_SERVER_PORT; +$port1 = isset($argv[3]) ? $argv[3] : null; +$port2 = isset($argv[4]) ? $argv[4] : null; + +(new OpcodeServer($host, $port, $port1, $port2))->start(); + +class OpcodeServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct($host, $port, $port1 = null, $port2 = null) + { + $this->swooleServer = new \swoole_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + 'dispatch_mode' => 3, + 'worker_num' => 2, + 'task_worker_num' => 2, + + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + "heartbeat_idle_time"=> 20 + ]); + + if ($port1) { + $serv1 = $this->swooleServer->addListener(TCP_SERVER_HOST, $port1, SWOOLE_SOCK_TCP); + assert($serv1 !== false); + } + if ($port2) { + $serv2 = $this->swooleServer->addListener(TCP_SERVER_HOST, $port2, SWOOLE_SOCK_TCP); + assert($serv2 !== false); + } + } + + public function start($lifetime = 1000) + { + $this->lifetime = $lifetime; + + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->on('task', [$this, 'onTask']); + $this->swooleServer->on('finish', [$this, 'onFinish']); + $this->swooleServer->on('pipeMessage', [$this, 'onPipeMessage']); + $this->swooleServer->on('packet', [$this, 'onPacket']); + + /* + $proc = new \swoole_process(swoole_function(\swoole_process $proc) use($i) { + var_dump($this->swooleServer->id); + sleep(10000); + $r = $this->swooleServer->addProcess($proc); + var_dump($r); + $proc->freeQueue(); + }); + $proc->useQueue(); + // $proc->start(); + + $proc1 = new \swoole_process(swoole_function(\swoole_process $proc) use($i) { + var_dump($this->swooleServer->id); + sleep(1000); + }); + + $proc2 = new \swoole_process(swoole_function(\swoole_process $proc) { + var_dump($this->swooleServer->id); + sleep(1000); + }); + + + $r = $this->swooleServer->addProcess($proc); + $r = $this->swooleServer->addProcess($proc1); + $r = $this->swooleServer->addProcess($proc2); + var_dump($this->swooleServer->id); + */ + + $this->swooleServer->start(); + } + + public function onConnect() { } + public function onClose() { } + public function onStart(\swoole_server $swooleServer) { } + public function onShutdown(\swoole_server $swooleServer) { } + public function onWorkerStart(\swoole_server $swooleServer, $workerId) + { + if ($workerId === 0) { + swoole_timer_after($this->lifetime, function() { + $this->swooleServer->shutdown(); + kill_self_and_descendant(getmypid()); + /* + \swoole_process::signal(SIGTERM, swoole_function() { + $this->swooleServer->shutdown(); + }); + \swoole_process::kill(0, SIGTERM); + */ + }); + } + } + public function onWorkerStop(\swoole_server $swooleServer, $workerId) { } + public function onWorkerError(\swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) { } + public function onReceive(\swoole_server $swooleServer, $fd, $fromReactorId, $recv) + { + list($op, $args) = opcode_decode($recv); + + switch($op) { + case "sendMessage": + list($msg, $toWorkerId) = $args; + $r = $swooleServer->sendMessage(json_encode([ + "fd" => $fd, + "msg" => $msg, + ]), $toWorkerId); + assert($r); + return; + + case "sendfile": + $len = filesize(__FILE__); + $r = $swooleServer->send($fd, pack("N", $len + 4)); + assert($r !== false); + $r =$swooleServer->sendfile($fd, __FILE__); + assert($r !== false); + return; + + default: + if (method_exists($swooleServer, $op)) { + $r = call_user_func_array([$swooleServer, $op], $args); + if (is_resource($r)) { + $r = true; + } + $r = $swooleServer->send($fd, opcode_encode("return", $r)); + assert($r !== false); + return; + } else { + + } + } + } + + public function onTask(\swoole_server $swooleServer, $taskId, $fromWorkerId, $recv) + { + $recv = json_decode($recv); + assert(json_last_error() === JSON_ERROR_NONE); + return json_encode($recv); + } + + public function onFinish(\swoole_server $swooleServer, $taskId, $recv) + { + $recv = json_decode($recv); + assert(json_last_error() === JSON_ERROR_NONE); + assert(isset($recv["fd"]) && isset($recv["data"])); + $this->swooleServer->send($recv["fd"], opcode_encode("return", $recv["data"])); + } + + public function onPipeMessage(\swoole_server $swooleServer, $fromWorkerId, $recv) + { + $recv = json_decode($recv, true); + assert(json_last_error() === JSON_ERROR_NONE); + assert(isset($recv["fd"]) && isset($recv["msg"])); + $this->swooleServer->send($recv["fd"], opcode_encode("return", $recv["msg"])); + } + + public function onPacket(\swoole_server $swooleServer, $data, array $clientInfo) + { + + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_client.php b/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_client.php new file mode 100755 index 0000000..3bb6867 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_client.php @@ -0,0 +1,19 @@ +<?php +ini_set("memory_limit", "1024m"); + +function reconn() { + echo "Reconnect\n"; + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $cli->on("connect", function(swoole_client $cli) { + // client 发送 大包数据 + $cli->send(str_repeat("\0", 1024 * 1024 * 1.9)); + }); + $cli->on("receive", function(swoole_client $cli, $data) { + $cli->send($data); + }); + $cli->on("error", function(swoole_client $cli) { echo "error\n"; }); + $cli->on("close", function(swoole_client $cli) { echo "close\n"; reconn(); }); + $cli->connect("127.0.0.1", 9001); +} + +reconn(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_serv.php b/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_serv.php new file mode 100755 index 0000000..db97394 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/reconnect_fail/tcp_serv.php @@ -0,0 +1,106 @@ +<?php + +function debug_log($str, $handle = STDERR) +{ + if ($handle === STDERR) { + $tpl = "\033[31m[%d %s] %s\033[0m\n"; + } else { + $tpl = "[%d %s] %s\n"; + } + if (is_resource($handle)) { + fprintf($handle, $tpl, posix_getpid(), date("Y-m-d H:i:s", time()), $str); + } else { + printf($tpl, posix_getpid(), date("Y-m-d H:i:s", time()), $str); + } +} + +(new TcpServer())->start(); + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server("127.0.0.1", 9001, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + // "buffer_output_size" => 1024 * 1024 * 1024, // 输出限制 + + 'max_connection' => 10240, + 'pipe_buffer_size' => 1024 * 1024 * 2, +// 'pipe_buffer_size' => 1024, + + 'dispatch_mode' => 3, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + 'daemonize' => 0, + 'reactor_num' => 1, + 'worker_num' => 2, + 'max_request' => 100000, + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + echo "close $fd\n"; +// var_dump($swooleServer->shutdown()); + // swoole_server 接受数据之后立马关闭连接 + var_dump($swooleServer->close($fd)); + // $swooleServer->send($fd, $data); + } +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_server/server_manager_process_exit.php b/vendor/swoole/tests/include/api/swoole_server/server_manager_process_exit.php new file mode 100755 index 0000000..85312f0 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/server_manager_process_exit.php @@ -0,0 +1,142 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +if (pcntl_fork() === 0) { + suicide(1000); + exit(); +} + + +if (pcntl_fork() === 0) { + suicide(1000); + exit(); +} + + +if (pcntl_fork() === 0) { + suicide(1000); + + + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + /** @noinspection PhpVoidFunctionResultUsedInspection */ + assert($cli->set([ + "socket_buffer_size" => 1024, + ])); + + $cli->on("connect", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + assert($cli->isConnected() === true); + $cli->send(str_repeat("\0", 1024)); + }); + + $cli->on("receive", function(swoole_client $cli, $data){ + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $cli->send(str_repeat("\0", $recv_len)); + }); + + $cli->on("error", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("error"); + }); + + $cli->on("close", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("close"); + }); + + $cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT); + $cli->timeo_id = swoole_timer_after(1000, function() use($cli) { + debug_log("connect timeout"); + $cli->close(); + assert($cli->isConnected() === false); + }); + exit(); +} + +(new TcpServer())->start(); + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server(TCP_SERVER_HOST, TCP_SERVER_PORT, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + "buffer_output_size" => 1024 * 1024 * 1024, // 输出限制 + "max_connection" => 10240, + "pipe_buffer_size" => 1024 * 1024 * 1024, + 'daemonize' => 0, + 'worker_num' => 2, + 'max_request' => 100000, + 'reactor_num' => 1, + // 'package_max_length' => 1024 * 1024 * 2 + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $swooleServer->send($fd, str_repeat("\0", $recv_len)); + } +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_server/server_send_fast_recv_slow.php b/vendor/swoole/tests/include/api/swoole_server/server_send_fast_recv_slow.php new file mode 100755 index 0000000..ce1bda0 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/server_send_fast_recv_slow.php @@ -0,0 +1,145 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +if (pcntl_fork() === 0) { + suicide(3000); + + + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + /** @noinspection PhpVoidFunctionResultUsedInspection */ + assert($cli->set([ + "socket_buffer_size" => 1, + ])); + + $cli->on("connect", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + + // TODO getSocket BUG + // assert(is_resource($cli->getSocket())); + /* + $cli->getSocket(); + // Warning: swoole_client_async::getSocket(): unable to obtain socket family Error: Bad file descriptor[9]. + $cli->getSocket(); + */ + + + assert($cli->isConnected() === true); + $cli->send(str_repeat("\0", 1024)); + // $cli->sendfile(__DIR__.'/test.txt'); + }); + + $cli->on("receive", function(swoole_client $cli, $data){ + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $cli->send(str_repeat("\0", 1024)); + }); + + $cli->on("error", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("error"); + }); + + $cli->on("close", function(swoole_client $cli) { + swoole_timer_clear($cli->timeo_id); + debug_log("close"); + }); + + $cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT); + $cli->timeo_id = swoole_timer_after(1000, function() use($cli) { + debug_log("connect timeout"); + $cli->close(); + assert($cli->isConnected() === false); + }); + + exit(); +} + + +(new TcpServer())->start(); + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server(TCP_SERVER_HOST, TCP_SERVER_PORT, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + "buffer_output_size" => 1024 * 1024 * 1024, // 输出限制 + "max_connection" => 10240, + "pipe_buffer_size" => 1024 * 1024 * 1024, + + // 'log_file' => __DIR__ . '/send_fast_recv_slow.log', + 'daemonize' => 0, + 'worker_num' => 2, + 'max_request' => 100000, + 'reactor_num' => 1, + // 'package_max_length' => 1024 * 1024 * 2 + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $swooleServer->send($fd, str_repeat("\0", $recv_len)); + } +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_server/simple_server.php b/vendor/swoole/tests/include/api/swoole_server/simple_server.php new file mode 100755 index 0000000..bad1911 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/simple_server.php @@ -0,0 +1,114 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; +/* +if (pcntl_fork() === 0) { + require_once __DIR__ . "/../swoole_client_async/simple_client.php"; + exit(); +}*/ + +(new TcpServer())->start(); + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server(TCP_SERVER_HOST, TCP_SERVER_PORT, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + // "buffer_output_size" => 1024 * 1024 * 1024, // 输出限制 + "max_connection" => 10240, + "pipe_buffer_size" => 1024 * 1024 * 1024, + + // 'enable_port_reuse' => true, + // 'user' => 'www-data', + // 'group' => 'www-data', + +// 'log_file' => __DIR__ . '/simple_server.log', + 'dispatch_mode' => 2, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + 'daemonize' => 0, + 'reactor_num' => 1, + 'worker_num' => 1, + 'max_request' => 100000, + // 'package_max_length' => 1024 * 1024 * 2 + /* + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + 'open_nova_protocol' => 1, + */ + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + if (trim($data) == 'shutdown') + { + $swooleServer->shutdown(); + return; + } + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + $swooleServer->send($fd, RandStr::gen($recv_len, RandStr::ALL)); + // $swooleServer->close($fd); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/simple_tcp_server.php b/vendor/swoole/tests/include/api/swoole_server/simple_tcp_server.php new file mode 100755 index 0000000..e9bdbbd --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/simple_tcp_server.php @@ -0,0 +1,103 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//(new TcpServer($argv[1], $argv[2]))->start(); +$host = isset($argv[1]) ? $argv[1] : TCP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : TCP_SERVER_PORT; + +$server = new TcpServer($host, $port); +$server->start(); + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct($host, $port) + { + echo "swoole_server host:$host, port:$port\n"; + $this->swooleServer = new \swoole_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + "pipe_buffer_size" => 1024 * 1024 * 1024, + 'dispatch_mode' => 3, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + //'daemonize' => 1, + 'reactor_num' => 2, + 'worker_num' => 4, + 'max_request' => 100000, + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + if ($workerId == 0) { + swoole_timer_after(5000, function () { + $this->swooleServer->shutdown(); + }); + } + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + //echo "swoole_server receive data: $data\n"; + $recv_len = strlen($data); + debug_log("receive: len $recv_len"); + + //$swooleServer->send($fd, RandStr::gen($recv_len, RandStr::ALL)); + + $filename = __DIR__ . "/testsendfile.txt"; + $swooleServer->sendfile($fd, $filename); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/simple_udp_server.php b/vendor/swoole/tests/include/api/swoole_server/simple_udp_server.php new file mode 100755 index 0000000..89db793 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/simple_udp_server.php @@ -0,0 +1,89 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +(new UdpServer())->start(); + +class UdpServer +{ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server(UDP_SERVER_HOST, UDP_SERVER_PORT, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); + $this->swooleServer->set([ + "max_connection" => 1000, + 'dispatch_mode' => 3, + 'daemonize' => 0, + 'reactor_num' => 4, + 'worker_num' => 8, + 'max_request' => 1000, + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('Packet', [$this, 'onPacket']); + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + swoole_timer_after(3000, function() { + $this->swooleServer->shutdown(); + }); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + //UDP: 收到数据帧事件 + public function onPacket(swoole_server $swooleServer, $data, $clientInfo) + { + if (trim($data) == 'shutdown') + { + $swooleServer->shutdown(); + return; + } + //echo "clientInfo: $clientInfo, receive: $data\n"; + $swooleServer->sendto($clientInfo['address'], $clientInfo['port'], $data); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/tcp_task_server.php b/vendor/swoole/tests/include/api/swoole_server/tcp_task_server.php new file mode 100755 index 0000000..c5ff808 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/tcp_task_server.php @@ -0,0 +1,111 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; +$host = isset($argv[1]) ? $argv[1] : TCP_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : TCP_SERVER_PORT; +$server = new TcpServer($host, $port); +$server->start(); + +class TcpServer +{ + public $swooleServer; + + public function __construct($host, $port) + { + echo "swoole_server host:$host, port:$port\n"; + $this->swooleServer = new \swoole_server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + "pipe_buffer_size" => 1024 * 1024 * 1024, + 'dispatch_mode' => 3, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + //'daemonize' => 1, + 'reactor_num' => 2, + 'worker_num' => 4, + 'task_worker_num' => 8, + 'max_request' => 100000, + 'log_file' => '/tmp/swoole_server.log', + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + $this->swooleServer->on('task', [$this, 'onTask']); + $this->swooleServer->on('finish', [$this, 'onFinish']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + if ($workerId == 0) { + //swoole_timer_after(5000, function () { + // $this->swooleServer->shutdown(); + //}); + } + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + //echo "swoole_server receive data: $data\n"; + $param = array( + 'fd' => $fd, + 'data' => $data, + ); + $swooleServer->task(json_encode($param)); + //echo "send data to task worker.\n"; + } + + public function onTask(swoole_server $swooleServer, $task_id, $fromId, $data) + { + $task_data = json_decode($data, true); + $swooleServer->finish($task_data); + } + + public function onFinish(swoole_server $swooleServer, $worker_task_id, $task_data) + { + $swooleServer->send($task_data['fd'], "OK"); + } +} diff --git a/vendor/swoole/tests/include/api/swoole_server/testsendfile.txt b/vendor/swoole/tests/include/api/swoole_server/testsendfile.txt new file mode 100755 index 0000000..7e40a7e --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_server/testsendfile.txt @@ -0,0 +1 @@ +testsendfile.txt diff --git a/vendor/swoole/tests/include/api/swoole_timer/accurate_test.php b/vendor/swoole/tests/include/api/swoole_timer/accurate_test.php new file mode 100755 index 0000000..5a971a9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_timer/accurate_test.php @@ -0,0 +1,21 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_timer_after($ms, $callback, $param = null) {} +//swoole_function swoole_timer_tick($ms, $callback) {} +//swoole_function swoole_timer_clear($timer_id) {} + + +function after() +{ + $start = microtime(true); + swoole_timer_after(1000, function() use($start) { + echo microtime(true) - $start, "\n"; + after(); + }); +} + +//for ($i = 0; $i < 10000; $i++) { + after(); +//} diff --git a/vendor/swoole/tests/include/api/swoole_timer/fixRate_vs_fixDelay.php b/vendor/swoole/tests/include/api/swoole_timer/fixRate_vs_fixDelay.php new file mode 100755 index 0000000..7568dc2 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_timer/fixRate_vs_fixDelay.php @@ -0,0 +1,79 @@ +<?php + +function fixRate(callable $callable, $interval) +{ + return swoole_timer_tick($interval, $callable); +} + +function fixDelay(callable $callable, $interval) +{ + return swoole_timer_after($interval, function() use($callable, $interval) { + call_user_func($callable); + fixDelay($callable, $interval); + }); +} + +function randBlock() +{ + $n = mt_rand(0, 10); + for ($i = 0; $i < 1000000 * $n; $i++) {} +} + +/* +$t = microtime(true); +fixDelay(swoole_function() use(&$t) { + echo number_format(microtime(true) - $t, 3), PHP_EOL; + randBlock(); + $t = microtime(true); +}, 1000); +//*/ +/* +1.007 +1.005 +1.005 +1.004 +1.003 +1.004 +1.002 +1.006 +1.006 +1.005 +1.004 +1.002 +1.006 +1.004 +1.002 +*/ + + +/* +$t = microtime(true); +fixRate(swoole_function() use(&$t) { + echo number_format(microtime(true) - $t, 3), PHP_EOL; + randBlock(); + $t = microtime(true); +}, 1000); +*/ +/* +1.003 +0.759 +1.005 +0.538 +1.002 +1.003 +0.763 +1.005 +0.247 +1.004 +1.004 +0.270 +1.005 +0.199 +1.000 +0.335 +1.005 +1.006 +0.239 +1.004 +0.119 +*/ \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_timer/invalid_args.php b/vendor/swoole/tests/include/api/swoole_timer/invalid_args.php new file mode 100755 index 0000000..c7b213f --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_timer/invalid_args.php @@ -0,0 +1,26 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +//swoole_function swoole_timer_after($ms, $callback, $param = null) {} +//swoole_function swoole_timer_tick($ms, $callback) {} +//swoole_function swoole_timer_clear($timer_id) {} + +swoole_timer_after(-1, function(){ }); +swoole_timer_tick(-1, function() { }); +swoole_timer_after(86400001, function(){ }); +swoole_timer_tick(86400001, function() { }); +swoole_timer_clear(-1); + +for ($i = 0; $i < 1000; $i++) { + swoole_timer_clear(swoole_timer_after(1, function() {})); +} + +//swoole_timer_after(1, null); +//swoole_timer_after(1, "strlen"); + +function sw_timer_pass_ref(&$ref_func) { + swoole_timer_after(1, $ref_func); +} +$func = function() {}; +sw_timer_pass_ref($func); diff --git a/vendor/swoole/tests/include/api/swoole_timer/multi_timer.php b/vendor/swoole/tests/include/api/swoole_timer/multi_timer.php new file mode 100755 index 0000000..1695701 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_timer/multi_timer.php @@ -0,0 +1,9 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +for ($j = 0; $j < 100; $j++) { + swoole_timer_after(1, function() use($j){ + echo $j, "\n"; + }); +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_timer/register_shutdown_priority.php b/vendor/swoole/tests/include/api/swoole_timer/register_shutdown_priority.php new file mode 100755 index 0000000..e0be4df --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_timer/register_shutdown_priority.php @@ -0,0 +1,86 @@ +<?php + +// first shutdown func +// timer after +function func1() +{ + register_shutdown_function(function() { + echo "first shutdown func\n"; + }); + +// $start = microtime(true); + swoole_timer_after(1, function() /*use($start)*/ { + echo "timer after\n"; +// echo (microtime(true) - $start) * 1000 - 1; + }); +} + +// first shutdown func +// timer after +function func1_2() +{ + $order4 = function() { echo "first shutdown func\n"; }; + $order5 = function() { swoole_event_wait(); }; + $order6 = function() { echo "timer after\n";}; + + // order 1 + register_shutdown_function($order4); + // order 2 + register_shutdown_function($order5); + // order 3 + swoole_timer_after(1, $order6); +} + + +// timer after +// first shutdown func +function func2() +{ + register_shutdown_function(function() { + echo "first shutdown func\n"; + }); + + swoole_timer_after(1, function() { + echo "timer after\n"; + }); + + swoole_event_wait(); +} + + +// first shutdown func +// timer after +// second shutdown func +function func3() +{ + register_shutdown_function(function() { + echo "first shutdown func\n"; + }); + + swoole_timer_after(1, function() { + echo "timer after\n"; + register_shutdown_function(function() { + echo "second shutdown func\n"; + }); + }); + +} + + +function recv_shutdow() +{ + register_shutdown_function(function() { + echo "shutdown\n"; + recv_shutdow(); + }); +} + + + +//recv_shutdow(); +//func1(); +func1_2(); +//func2(); +//func3(); + + diff --git a/vendor/swoole/tests/include/api/swoole_utils/swoole_utils.php b/vendor/swoole/tests/include/api/swoole_utils/swoole_utils.php new file mode 100755 index 0000000..d640208 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_utils/swoole_utils.php @@ -0,0 +1,15 @@ +<?php + +//swoole_function swoole_get_local_ip() {} +//swoole_function swoole_strerror($errno) {} +//swoole_function swoole_errno() {} + +require_once __DIR__ . "/../../../include/bootstrap.php"; + + +$ip_list = swoole_get_local_ip(); +print_r($ip_list); + + +echo swoole_errno(), "\n"; +echo swoole_strerror(swoole_errno()); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_websocket_server/send_large_request_data.php b/vendor/swoole/tests/include/api/swoole_websocket_server/send_large_request_data.php new file mode 100755 index 0000000..5bfdd4c --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_websocket_server/send_large_request_data.php @@ -0,0 +1,27 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; +require "websocket_client.php"; + +function send_large_request_data($host, $port) +{ + $client = new WebSocketClient($host, $port); + if (!$client->connect()) + { + echo "send failed, errCode={$client->errCode}\n"; + return false; + } + + $data = str_repeat("data", 40000); + for ($i = 0; $i < 100; $i++) + { + if (!$client->send($data)) + { + echo "send failed, errCode={$client->errCode}\n"; + return false; + } + $response = $client->recv(); + assert($response == "SUCCESS", "response failed"); + } + return true; +} diff --git a/vendor/swoole/tests/include/api/swoole_websocket_server/send_small_request_data.php b/vendor/swoole/tests/include/api/swoole_websocket_server/send_small_request_data.php new file mode 100755 index 0000000..78a4e56 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_websocket_server/send_small_request_data.php @@ -0,0 +1,18 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; +require "websocket_client.php"; + +function send_small_request_data($host, $port) +{ + $client = new WebSocketClient($host, $port); + $client->connect(); + + $data = ""; + for ($i = 0; $i < 100; $i++) + { + $client->send($data); + $response = $client->recv(); + assert($response == "SUCCESS", "response failed"); + } +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_websocket_server/swoole_websocket_server.php b/vendor/swoole/tests/include/api/swoole_websocket_server/swoole_websocket_server.php new file mode 100755 index 0000000..5147c45 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_websocket_server/swoole_websocket_server.php @@ -0,0 +1,118 @@ +<?php + +require_once __DIR__ . "/../../../include/bootstrap.php"; + +class WebSocketServer +{ + /** + * @var \swoole_websocket_server + */ + public $webSocketServ; + + public function __construct($host = WEBSOCKET_SERVER_HOST, $port = WEBSOCKET_SERVER_PORT) + { + $this->webSocketServ = new \swoole_websocket_server($host, $port); + + $this->webSocketServ->set([ + // 输出限制 + "buffer_output_size" => 1024 * 1024 * 1024, + + "max_connection" => 10240, + "pipe_buffer_size" => 1024 * 1024 * 1024, + + // 'enable_port_reuse' => true, + 'user' => 'www-data', + 'group' => 'www-data', + + // 'log_file' => __DIR__.'/swoole.log', + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + 'daemonize' => 0, + 'reactor_num' => 1, + 'worker_num' => 2, + 'max_request' => 100000, + ]); + + } + + public function start() + { + $this->webSocketServ->on('start', [$this, 'onStart']); + $this->webSocketServ->on('shutdown', [$this, 'onShutdown']); + + $this->webSocketServ->on('workerStart', [$this, 'onWorkerStart']); + $this->webSocketServ->on('workerStop', [$this, 'onWorkerStop']); + $this->webSocketServ->on('workerError', [$this, 'onWorkerError']); + + $this->webSocketServ->on('connect', [$this, 'onConnect']); + $this->webSocketServ->on('request', [$this, 'onRequest']); + + $this->webSocketServ->on('open', [$this, 'onOpen']); + $this->webSocketServ->on('message', [$this, 'onMessage']); + + $this->webSocketServ->on('close', [$this, 'onClose']); + + $sock = $this->webSocketServ->getSocket(); + if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) { + echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL; + } + + $this->webSocketServ->start(); + } + + public function onConnect() + { + debug_log("connecting ......"); + } + + public function onClose() + { + debug_log("closing ....."); + } + + public function onStart(\swoole_websocket_server $swooleServer) + { + debug_log("swoole_server starting ....."); + } + + public function onShutdown(\swoole_websocket_server $swooleServer) + { + debug_log("swoole_server shutdown ....."); + } + + public function onWorkerStart(\swoole_websocket_server $swooleServer, $workerId) + { + debug_log("worker #$workerId starting ....."); + } + + public function onWorkerStop(\swoole_websocket_server $swooleServer, $workerId) + { + debug_log("worker #$workerId stopping ...."); + } + + public function onWorkerError(\swoole_websocket_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { + debug_log("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onRequest(\swoole_http_request $request, \swoole_http_response $response) + { + $response->end("Hello World!"); + } + + public function onOpen(swoole_websocket_server $server, $request) + { + debug_log("{$request->fd} opened"); + } + + public function onMessage(swoole_websocket_server $server, $frame) + { + $server->push($frame->fd, "SUCCESS"); + } +} + +$host = isset($argv[1]) ? $argv[1] : WEBSOCKET_SERVER_HOST; +$port = isset($argv[2]) ? $argv[2] : WEBSOCKET_SERVER_PORT; + +$wsServer = new WebSocketServer($host, $port); +$wsServer->start(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/api/swoole_websocket_server/websocket_client.php b/vendor/swoole/tests/include/api/swoole_websocket_server/websocket_client.php new file mode 100755 index 0000000..5af8cb9 --- /dev/null +++ b/vendor/swoole/tests/include/api/swoole_websocket_server/websocket_client.php @@ -0,0 +1,391 @@ +<?php + +class WebSocketClient +{ + const VERSION = '0.1.4'; + const TOKEN_LENGHT = 16; + const TYPE_ID_WELCOME = 0; + const TYPE_ID_PREFIX = 1; + const TYPE_ID_CALL = 2; + const TYPE_ID_CALLRESULT = 3; + const TYPE_ID_ERROR = 4; + const TYPE_ID_SUBSCRIBE = 5; + const TYPE_ID_UNSUBSCRIBE = 6; + const TYPE_ID_PUBLISH = 7; + const TYPE_ID_EVENT = 8; + private $key; + private $host; + private $port; + private $path; + /** + * @var swoole_client + */ + private $socket; + private $buffer = ''; + private $origin = null; + /** + * @var bool + */ + private $connected = false; + + /** + * @param string $host + * @param int $port + * @param string $path + */ + function __construct($host = '127.0.0.1', $port = 8080, $path = '/', $origin = null) + { + $this->host = $host; + $this->port = $port; + $this->path = $path; + $this->origin = $origin; + $this->key = $this->generateToken(self::TOKEN_LENGHT); + } + + /** + * Disconnect on destruct + */ + function __destruct() + { + $this->disconnect(); + } + + /** + * Connect client to swoole_server + * + * @return $this + */ + public function connect() + { + $this->socket = new \swoole_client(SWOOLE_SOCK_TCP); + if (!$this->socket->connect($this->host, $this->port)) + { + return false; + } + $this->socket->send($this->createHeader()); + return $this->recv(); + } + + public function getSocket() + { + return $this->socket; + } + + /** + * Disconnect from swoole_server + */ + public function disconnect() + { + $this->connected = false; + $this->socket->close(); + } + + public function recv() + { + $data = $this->socket->recv(); + if ($data === false) + { + echo "Error: {$this->socket->errMsg}"; + return false; + } + $this->buffer .= $data; + $recv_data = $this->parseData($this->buffer); + if ($recv_data) + { + $this->buffer = ''; + return $recv_data; + } + else + { + return false; + } + } + + /** + * @param $data + * @param string $type + * @param bool $masked + */ + public function send($data, $type = 'text', $masked = true) + { + return $this->socket->send($this->hybi10Encode($data, $type, $masked)); + } + + /** + * Parse received data + * + * @param $response + */ + private function parseData($response) + { + if (!$this->connected && isset($response['Sec-Websocket-Accept'])) + { + if (base64_encode(pack('H*', sha1($this->key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))) + === $response['Sec-Websocket-Accept'] + ) + { + $this->connected = true; + } + else + { + throw new \Exception("error response key."); + } + } + return $this->hybi10Decode($response); + } + + /** + * Create header for websocket client + * + * @return string + */ + private function createHeader() + { + $host = $this->host; + if ($host === '127.0.0.1' || $host === '0.0.0.0') + { + $host = 'localhost'; + } + return "GET {$this->path} HTTP/1.1" . "\r\n" . + "Origin: {$this->origin}" . "\r\n" . + "Host: {$host}:{$this->port}" . "\r\n" . + "Sec-WebSocket-Key: {$this->key}" . "\r\n" . + "User-Agent: PHPWebSocketClient/" . self::VERSION . "\r\n" . + "Upgrade: websocket" . "\r\n" . + "Connection: Upgrade" . "\r\n" . + "Sec-WebSocket-Protocol: wamp" . "\r\n" . + "Sec-WebSocket-Version: 13" . "\r\n" . "\r\n"; + } + + /** + * Parse raw incoming data + * + * @param $header + * + * @return array + */ + private function parseIncomingRaw($header) + { + $retval = array(); + $content = ""; + $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header)); + foreach ($fields as $field) + { + if (preg_match('/([^:]+): (.+)/m', $field, $match)) + { + $match[1] = preg_replace_callback('/(?<=^|[\x09\x20\x2D])./', + function ($matches) + { + return strtoupper($matches[0]); + }, + strtolower(trim($match[1]))); + if (isset($retval[$match[1]])) + { + $retval[$match[1]] = array($retval[$match[1]], $match[2]); + } + else + { + $retval[$match[1]] = trim($match[2]); + } + } + else + { + if (preg_match('!HTTP/1\.\d (\d)* .!', $field)) + { + $retval["status"] = $field; + } + else + { + $content .= $field . "\r\n"; + } + } + } + $retval['content'] = $content; + return $retval; + } + + /** + * Generate token + * + * @param int $length + * + * @return string + */ + private function generateToken($length) + { + $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"§$%&/()=[]{}'; + $useChars = array(); + // select some random chars: + for ($i = 0; $i < $length; $i++) + { + $useChars[] = $characters[mt_rand(0, strlen($characters) - 1)]; + } + // Add numbers + array_push($useChars, rand(0, 9), rand(0, 9), rand(0, 9)); + shuffle($useChars); + $randomString = trim(implode('', $useChars)); + $randomString = substr($randomString, 0, self::TOKEN_LENGHT); + return base64_encode($randomString); + } + + /** + * Generate token + * + * @param int $length + * + * @return string + */ + public function generateAlphaNumToken($length) + { + $characters = str_split('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); + srand((float)microtime() * 1000000); + $token = ''; + do + { + shuffle($characters); + $token .= $characters[mt_rand(0, (count($characters) - 1))]; + } while (strlen($token) < $length); + return $token; + } + + /** + * @param $payload + * @param string $type + * @param bool $masked + * + * @return bool|string + */ + private function hybi10Encode($payload, $type = 'text', $masked = true) + { + $frameHead = array(); + $frame = ''; + $payloadLength = strlen($payload); + switch ($type) + { + case 'text': + // first byte indicates FIN, Text-Frame (10000001): + $frameHead[0] = 129; + break; + case 'close': + // first byte indicates FIN, Close Frame(10001000): + $frameHead[0] = 136; + break; + case 'ping': + // first byte indicates FIN, Ping frame (10001001): + $frameHead[0] = 137; + break; + case 'pong': + // first byte indicates FIN, Pong frame (10001010): + $frameHead[0] = 138; + break; + } + // set mask and payload length (using 1, 3 or 9 bytes) + if ($payloadLength > 65535) + { + $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8); + $frameHead[1] = ($masked === true) ? 255 : 127; + for ($i = 0; $i < 8; $i++) + { + $frameHead[$i + 2] = bindec($payloadLengthBin[$i]); + } + // most significant bit MUST be 0 (close connection if frame too big) + if ($frameHead[2] > 127) + { + $this->close(1004); + return false; + } + } + elseif ($payloadLength > 125) + { + $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8); + $frameHead[1] = ($masked === true) ? 254 : 126; + $frameHead[2] = bindec($payloadLengthBin[0]); + $frameHead[3] = bindec($payloadLengthBin[1]); + } + else + { + $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength; + } + // convert frame-head to string: + foreach (array_keys($frameHead) as $i) + { + $frameHead[$i] = chr($frameHead[$i]); + } + if ($masked === true) + { + // generate a random mask: + $mask = array(); + for ($i = 0; $i < 4; $i++) + { + $mask[$i] = chr(rand(0, 255)); + } + $frameHead = array_merge($frameHead, $mask); + } + $frame = implode('', $frameHead); + // append payload to frame: + for ($i = 0; $i < $payloadLength; $i++) + { + $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i]; + } + return $frame; + } + + /** + * @param $data + * + * @return null|string + */ + private function hybi10Decode($data) + { + if (empty($data)) + { + return null; + } + $bytes = $data; + $dataLength = ''; + $mask = ''; + $coded_data = ''; + $decodedData = ''; + $secondByte = sprintf('%08b', ord($bytes[1])); + $masked = ($secondByte[0] == '1') ? true : false; + $dataLength = ($masked === true) ? ord($bytes[1]) & 127 : ord($bytes[1]); + if ($masked === true) + { + if ($dataLength === 126) + { + $mask = substr($bytes, 4, 4); + $coded_data = substr($bytes, 8); + } + elseif ($dataLength === 127) + { + $mask = substr($bytes, 10, 4); + $coded_data = substr($bytes, 14); + } + else + { + $mask = substr($bytes, 2, 4); + $coded_data = substr($bytes, 6); + } + for ($i = 0; $i < strlen($coded_data); $i++) + { + $decodedData .= $coded_data[$i] ^ $mask[$i % 4]; + } + } + else + { + if ($dataLength === 126) + { + $decodedData = substr($bytes, 4); + } + elseif ($dataLength === 127) + { + $decodedData = substr($bytes, 10); + } + else + { + $decodedData = substr($bytes, 2); + } + } + return $decodedData; + } +} diff --git a/vendor/swoole/tests/include/api/tcp_server.php b/vendor/swoole/tests/include/api/tcp_server.php new file mode 100755 index 0000000..e74990a --- /dev/null +++ b/vendor/swoole/tests/include/api/tcp_server.php @@ -0,0 +1,30 @@ +<?php +$serv = new \swoole_server('127.0.0.1', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP); +$serv->set([ +// 'log_file' => __DIR__ . '/simple_server.log', + 'dispatch_mode' => 2, + 'daemonize' => 0, + 'worker_num' => 1, +]); + +$serv->on('workerStart', function (\swoole_server $serv) +{ + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); +}); + +$serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) +{ + if (trim($data) == 'shutdown') + { + $serv->shutdown(); + return; + } + $recv_len = strlen($data); + $serv->send($fd, RandStr::gen($recv_len, RandStr::ALL)); +}); + +$serv->start(); diff --git a/vendor/swoole/tests/include/lib/class.websocket_client.php b/vendor/swoole/tests/include/lib/class.websocket_client.php new file mode 100755 index 0000000..0a7eb18 --- /dev/null +++ b/vendor/swoole/tests/include/lib/class.websocket_client.php @@ -0,0 +1,338 @@ +<?php +ini_set('display_errors', 1); +error_reporting(E_ALL); + +/** + * Very basic websocket client. + * Supporting draft hybi-10. + * + * @author Simon Samtleben <web@lemmingzshadow.net> + * @version 2011-10-18 + */ + +class WebsocketClient +{ + private $_host; + private $_port; + private $_path; + private $_origin; + private $_Socket = null; + private $_connected = false; + + public function __construct() { } + + public function __destruct() + { + $this->disconnect(); + } + + public function sendRecv($data, $type = 'text', $masked = true) + { + if($this->_connected === false) + { + trigger_error("Not connected", E_USER_WARNING); + return false; + } + if( !is_string($data)) { + trigger_error("Not a string data was given.", E_USER_WARNING); + return false; + } + if (strlen($data) == 0) + { + return false; + } + $res = $this->_Socket->send($this->_hybi10Encode($data, $type, $masked)); + + if($res === 0 || $res === false) + { + return false; + } + + $buf = $this->_Socket->recv(512); + + $out = $this->_hybi10Decode($buf); + return $out['payload']; + } + + public function recvData() { + $buf = $this->_Socket->recv(512); + $out = $this->_hybi10Decode($buf); + return $out['payload']; + } + + public function connect($host, $port, $path, $origin = false) + { + $this->_host = $host; + $this->_port = $port; + $this->_path = $path; + $this->_origin = $origin; + + $key = base64_encode($this->_generateRandomString(16, false, true)); + $header = "GET " . $path . " HTTP/1.1\r\n"; + $header.= "Host: ".$host.":".$port."\r\n"; + $header.= "Upgrade: websocket\r\n"; + $header.= "Connection: Upgrade\r\n"; + $header.= "Sec-WebSocket-Key: " . $key . "\r\n"; + if($origin !== false) + { + $header.= "Sec-WebSocket-Origin: " . $origin . "\r\n"; + } + $header.= "Sec-WebSocket-Version: 13\r\n"; + + $this->_Socket = new swoole_client(SWOOLE_TCP, SWOOLE_SOCK_SYNC); + $this->_Socket->connect($host, $port, 1); + $this->_Socket->send($header."\r\n"); + $response = $this->_Socket->recv(1500); + + preg_match('#Sec-WebSocket-Accept:\s(.*)$#mU', $response, $matches); + + if ($matches) { + $keyAccept = trim($matches[1]); + $expectedResonse = base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); + $this->_connected = ($keyAccept === $expectedResonse) ? true : false; + } + + return $this->_connected; + } + + public function checkConnection() + { + $this->_connected = false; + + // send ping: + $data = 'ping?'; + $this->_Socket->send($this->_hybi10Encode($data, 'ping', true)); + + $response = $this->_Socket->recv(300); + if(empty($response)) + { + return false; + } + $response = $this->_hybi10Decode($response); + if(!is_array($response)) + { + return false; + } + if(!isset($response['type']) || $response['type'] !== 'pong') + { + return false; + } + $this->_connected = true; + return true; + } + + + public function disconnect() + { + $this->_connected = false; + $this->_Socket->close(); + } + + public function reconnect() + { + sleep(10); + $this->_connected = false; + fclose($this->_Socket); + $this->connect($this->_host, $this->_port, $this->_path, $this->_origin); + } + + private function _generateRandomString($length = 10, $addSpaces = true, $addNumbers = true) + { + $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"§$%&/()=[]{}'; + $useChars = array(); + // select some random chars: + for($i = 0; $i < $length; $i++) + { + $useChars[] = $characters[mt_rand(0, strlen($characters)-1)]; + } + // add spaces and numbers: + if($addSpaces === true) + { + array_push($useChars, ' ', ' ', ' ', ' ', ' ', ' '); + } + if($addNumbers === true) + { + array_push($useChars, rand(0,9), rand(0,9), rand(0,9)); + } + shuffle($useChars); + $randomString = trim(implode('', $useChars)); + $randomString = substr($randomString, 0, $length); + return $randomString; + } + + private function _hybi10Encode($payload, $type = 'text', $masked = true) + { + $frameHead = array(); + $frame = ''; + $payloadLength = strlen($payload); + + switch($type) + { + case 'text': + // first byte indicates FIN, Text-Frame (10000001): + $frameHead[0] = 129; + break; + + case 'close': + // first byte indicates FIN, Close Frame(10001000): + $frameHead[0] = 136; + break; + + case 'ping': + // first byte indicates FIN, Ping frame (10001001): + $frameHead[0] = 137; + break; + + case 'pong': + // first byte indicates FIN, Pong frame (10001010): + $frameHead[0] = 138; + break; + } + + // set mask and payload length (using 1, 3 or 9 bytes) + if($payloadLength > 65535) + { + $payloadLengthBin = str_split(sprintf('%064b', $payloadLength), 8); + $frameHead[1] = ($masked === true) ? 255 : 127; + for($i = 0; $i < 8; $i++) + { + $frameHead[$i+2] = bindec($payloadLengthBin[$i]); + } + // most significant bit MUST be 0 (close connection if frame too big) + if($frameHead[2] > 127) + { + $this->close(1004); + return false; + } + } + elseif($payloadLength > 125) + { + $payloadLengthBin = str_split(sprintf('%016b', $payloadLength), 8); + $frameHead[1] = ($masked === true) ? 254 : 126; + $frameHead[2] = bindec($payloadLengthBin[0]); + $frameHead[3] = bindec($payloadLengthBin[1]); + } + else + { + $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength; + } + + // convert frame-head to string: + foreach(array_keys($frameHead) as $i) + { + $frameHead[$i] = chr($frameHead[$i]); + } + if($masked === true) + { + // generate a random mask: + $mask = array(); + for($i = 0; $i < 4; $i++) + { + $mask[$i] = chr(rand(0, 255)); + } + + $frameHead = array_merge($frameHead, $mask); + } + $frame = implode('', $frameHead); + + // append payload to frame: + $framePayload = array(); + for($i = 0; $i < $payloadLength; $i++) + { + $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i]; + } + + return $frame; + } + + private function _hybi10Decode($data) + { + $payloadLength = ''; + $mask = ''; + $unmaskedPayload = ''; + $decodedData = array(); + + // estimate frame type: + $firstByteBinary = sprintf('%08b', ord($data[0])); + $secondByteBinary = sprintf('%08b', ord($data[1])); + $opcode = bindec(substr($firstByteBinary, 4, 4)); + $isMasked = ($secondByteBinary[0] == '1') ? true : false; + $payloadLength = ord($data[1]) & 127; + + switch($opcode) + { + // text frame: + case 1: + $decodedData['type'] = 'text'; + break; + + case 2: + $decodedData['type'] = 'binary'; + break; + + // connection close frame: + case 8: + $decodedData['type'] = 'close'; + break; + + // ping frame: + case 9: + $decodedData['type'] = 'ping'; + break; + + // pong frame: + case 10: + $decodedData['type'] = 'pong'; + break; + + default: + return false; + break; + } + + if($payloadLength === 126) + { + $mask = substr($data, 4, 4); + $payloadOffset = 8; + $dataLength = bindec(sprintf('%08b', ord($data[2])) . sprintf('%08b', ord($data[3]))) + $payloadOffset; + } + elseif($payloadLength === 127) + { + $mask = substr($data, 10, 4); + $payloadOffset = 14; + $tmp = ''; + for($i = 0; $i < 8; $i++) + { + $tmp .= sprintf('%08b', ord($data[$i+2])); + } + $dataLength = bindec($tmp) + $payloadOffset; + unset($tmp); + } + else + { + $mask = substr($data, 2, 4); + $payloadOffset = 6; + $dataLength = $payloadLength + $payloadOffset; + } + + if($isMasked === true) + { + for($i = $payloadOffset; $i < $dataLength; $i++) + { + $j = $i - $payloadOffset; + if(isset($data[$i])) + { + $unmaskedPayload .= $data[$i] ^ $mask[$j % 4]; + } + } + $decodedData['payload'] = $unmaskedPayload; + } + else + { + $payloadOffset = $payloadOffset - 4; + $decodedData['payload'] = substr($data, $payloadOffset); + } + + return $decodedData; + } +} diff --git a/vendor/swoole/tests/include/lib/curl.php b/vendor/swoole/tests/include/lib/curl.php new file mode 100755 index 0000000..f367805 --- /dev/null +++ b/vendor/swoole/tests/include/lib/curl.php @@ -0,0 +1,17 @@ +<?php +function curlGet($url) +{ + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + //在http 请求头加入 gzip压缩 + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept-Encoding: gzip')); + //curl返回的结果,采用gzip解压 + curl_setopt($ch, CURLOPT_ENCODING, "gzip"); + $output = curl_exec($ch); + curl_close($ch); + return $output; +} diff --git a/vendor/swoole/tests/include/macos/phpstorm.py b/vendor/swoole/tests/include/macos/phpstorm.py new file mode 100755 index 0000000..0a7ac1e --- /dev/null +++ b/vendor/swoole/tests/include/macos/phpstorm.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import socket +import struct +import sys +import os +import time + +# see com.intellij.idea.SocketLock for the server side of this interface + +RUN_PATH = u'/Applications/PhpStorm.app' +CONFIG_PATH = u'/Users/twosee/Library/Preferences/PhpStorm2017.3' +SYSTEM_PATH = u'/Users/twosee/Library/Caches/PhpStorm2017.3' + + +def print_usage(cmd): + print(('Usage:\n' + + ' {0} -h | -? | --help\n' + + ' {0} [project_dir]\n' + + ' {0} [-l|--line line] [project_dir|--temp-project] file[:line]\n' + + ' {0} diff <left> <right>\n' + + ' {0} merge <local> <remote> [base] <merged>').format(cmd)) + + +def process_args(argv): + args = [] + + skip_next = False + for i, arg in enumerate(argv[1:]): + if arg == '-h' or arg == '-?' or arg == '--help': + print_usage(argv[0]) + exit(0) + elif i == 0 and (arg == 'diff' or arg == 'merge' or arg == '--temp-project'): + args.append(arg) + elif arg == '-l' or arg == '--line': + args.append(arg) + skip_next = True + elif skip_next: + args.append(arg) + skip_next = False + else: + path = arg + if ':' in arg: + file_path, line_number = arg.rsplit(':', 1) + if line_number.isdigit(): + args.append('-l') + args.append(line_number) + path = file_path + args.append(os.path.abspath(path)) + + return args + + +def try_activate_instance(args): + port_path = os.path.join(CONFIG_PATH, 'port') + token_path = os.path.join(SYSTEM_PATH, 'token') + if not (os.path.exists(port_path) and os.path.exists(token_path)): + return False + + with open(port_path) as pf: + port = int(pf.read()) + with open(token_path) as tf: + token = tf.read() + + s = socket.socket() + s.settimeout(0.3) + try: + s.connect(('127.0.0.1', port)) + except (socket.error, IOError): + return False + + found = False + while True: + try: + path_len = struct.unpack('>h', s.recv(2))[0] + path = s.recv(path_len).decode('utf-8') + if os.path.abspath(path) == os.path.abspath(CONFIG_PATH): + found = True + break + except (socket.error, IOError): + return False + + if found: + cmd = 'activate ' + token + '\0' + os.getcwd() + '\0' + '\0'.join(args) + if sys.version_info.major >= 3: cmd = cmd.encode('utf-8') + encoded = struct.pack('>h', len(cmd)) + cmd + s.send(encoded) + time.sleep(0.5) # don't close the socket immediately + return True + + return False + + +def start_new_instance(args): + if sys.platform == 'darwin': + if len(args) > 0: + args.insert(0, '--args') + os.execvp('open', ['-a', RUN_PATH] + args) + else: + bin_file = os.path.split(RUN_PATH)[1] + os.execv(RUN_PATH, [bin_file] + args) + + +ide_args = process_args(sys.argv) +if not try_activate_instance(ide_args): + start_new_instance(ide_args) \ No newline at end of file diff --git a/vendor/swoole/tests/include/memoryleak/connect_host_not_found.php b/vendor/swoole/tests/include/memoryleak/connect_host_not_found.php new file mode 100755 index 0000000..b7ddd28 --- /dev/null +++ b/vendor/swoole/tests/include/memoryleak/connect_host_not_found.php @@ -0,0 +1,52 @@ +<?php + +class BigSizeMemory +{ + private $host; + private $port; + private $data; + private $tcpClient; + private $httpClient; + + public function __construct($host = "11.11.11.11", $port = 9000) + { + $this->data = str_repeat("\0", 1024 * 1024); // 1M + $this->host = $host; + $this->port = $port; + } + + function swoole_client_memory_leak() + { + $obj = new BigSizeMemory(); + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $obj->cli = $cli; + $cli->on("connect", function(swoole_client $cli) { + assert(false); + }); + $cli->on("receive", function(swoole_client $cli, $data) { + assert(false); + }); + $cli->on("error", function(swoole_client $cli) { echo "error\n"; unset($this->data); }); + $cli->on("close", function(swoole_client $cli) { echo "close\n"; unset($this->data); }); + + $cli->connect($this->host, $this->port); + $this->tcpClient = $cli; + } + + function swoole_http_client_memory_leak() + { + $cli = new swoole_http_client($this->host, $this->port); + $cli->on('close', function($cli) { echo "error\n"; unset($this->data); }); + $cli->on('error', function($cli) { echo "close\n"; unset($this->data); }); + $cli->get('/', function(swoole_http_client $cli) {}); + $this->httpClient = $cli; + } +} + + + + + +// 回调不触发, 对象不析构, 内存泄漏 +(new BigSizeMemory())->swoole_http_client_memory_leak(); +(new BigSizeMemory())->swoole_client_memory_leak(); \ No newline at end of file diff --git a/vendor/swoole/tests/include/memoryleak/tcp_client_memory_leak/tcp_serv.php b/vendor/swoole/tests/include/memoryleak/tcp_client_memory_leak/tcp_serv.php new file mode 100755 index 0000000..883369b --- /dev/null +++ b/vendor/swoole/tests/include/memoryleak/tcp_client_memory_leak/tcp_serv.php @@ -0,0 +1,100 @@ +<?php + + +class TcpServer +{ + /** + * @var \swoole_server + */ + public $swooleServer; + + public function __construct() + { + $this->swooleServer = new \swoole_server("127.0.0.1", 9001, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); + $this->swooleServer->set([ + // "buffer_output_size" => 1024 * 1024 * 1024, // 输出限制 + + 'log_file' => __DIR__ . '/swoole.log', + 'max_connection' => 10240, + 'pipe_buffer_size' => 1024 * 1024 * 1024, + + 'dispatch_mode' => 3, + 'open_tcp_nodelay' => 1, + 'open_cpu_affinity' => 1, + 'daemonize' => 0, + 'reactor_num' => 1, + 'worker_num' => 2, + 'max_request' => 100000, + ]); + } + + public function start() + { + $this->swooleServer->on('start', [$this, 'onStart']); + $this->swooleServer->on('shutdown', [$this, 'onShutdown']); + + $this->swooleServer->on('workerStart', [$this, 'onWorkerStart']); + $this->swooleServer->on('workerStop', [$this, 'onWorkerStop']); + $this->swooleServer->on('workerError', [$this, 'onWorkerError']); + + $this->swooleServer->on('connect', [$this, 'onConnect']); + $this->swooleServer->on('receive', [$this, 'onReceive']); + + $this->swooleServer->on('close', [$this, 'onClose']); + + $this->swooleServer->start(); + } + + public function onConnect() + { +// print("connecting ......"); + } + + public function onClose() + { +// print("closing ....."); + } + + public function onStart(swoole_server $swooleServer) + { +// print("swoole_server starting ....."); + } + + public function onShutdown(swoole_server $swooleServer) + { +// print("swoole_server shutdown ....."); + } + + public function onWorkerStart(swoole_server $swooleServer, $workerId) + { +// print("worker #$workerId starting ....."); + } + + public function onWorkerStop(swoole_server $swooleServer, $workerId) + { +// print("worker #$workerId stopping ...."); + } + + public function onWorkerError(swoole_server $swooleServer, $workerId, $workerPid, $exitCode, $sigNo) + { +// print("worker error happening [workerId=$workerId, workerPid=$workerPid, exitCode=$exitCode, signalNo=$sigNo]..."); + } + + public function onReceive(swoole_server $swooleServer, $fd, $fromId, $data) + { + static $i; + if ($i > 20000) + { + $swooleServer->close($fd); + $swooleServer->shutdown(); + @unlink(__DIR__ . '/swoole.log'); + } + else + { + $swooleServer->send($fd, $data); + } + $i++; + } +} + +(new TcpServer())->start(); diff --git a/vendor/swoole/tests/include/redis/bug_01.php b/vendor/swoole/tests/include/redis/bug_01.php new file mode 100755 index 0000000..26796cc --- /dev/null +++ b/vendor/swoole/tests/include/redis/bug_01.php @@ -0,0 +1,13 @@ +<?php +go(function () { + $redis = new co\Redis(); + $redis->connect('127.0.0.1', 6379); + while (true) + { + $val = $redis->subscribe(['test']); + var_dump($val); + if (!$val) { + break; + } + } +}); diff --git a/vendor/swoole/tests/include/redis/bug_02.php b/vendor/swoole/tests/include/redis/bug_02.php new file mode 100755 index 0000000..1b7501c --- /dev/null +++ b/vendor/swoole/tests/include/redis/bug_02.php @@ -0,0 +1,20 @@ +<?php +go(function () { + $redis = new co\Redis(); + $redis->connect('127.0.0.1', 6379); + echo "connectd: "; + var_dump($redis->connected); + co::sleep(10); + + $rt = $redis->get("key"); + var_dump($rt, $redis->errCode, $redis->errMsg); + + echo "connectd: ";var_dump($redis->connected); + + swoole_timer_after(1000, function () use ($redis) { + echo "connectd: ";var_dump($redis->connected); + $rt = $redis->get("key"); + var_dump($rt); + }); +}); + diff --git a/vendor/swoole/tests/include/redis/bug_03.php b/vendor/swoole/tests/include/redis/bug_03.php new file mode 100755 index 0000000..bbf2269 --- /dev/null +++ b/vendor/swoole/tests/include/redis/bug_03.php @@ -0,0 +1,21 @@ +<?php + + +go(function () use ($redis) { + + $redis = new co\Redis(); + $redis->connect('127.0.0.1', 6379); + + + go(function () use ($redis) { + var_dump($redis->get("key")); + }); + + go(function() use ($redis) { + + co::sleep(1); + var_dump($redis->get("key")); + }); + +}); + diff --git a/vendor/swoole/tests/include/skipif.inc b/vendor/swoole/tests/include/skipif.inc new file mode 100755 index 0000000..b8637ac --- /dev/null +++ b/vendor/swoole/tests/include/skipif.inc @@ -0,0 +1,9 @@ +<?php +if (substr(PHP_OS, 0, 3) == 'WIN') +{ + exit("skip for Windows"); +} +if (!extension_loaded("swoole")) +{ + exit("swoole extension is required"); +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/skipifDarwin.inc b/vendor/swoole/tests/include/skipifDarwin.inc new file mode 100755 index 0000000..3fec344 --- /dev/null +++ b/vendor/swoole/tests/include/skipifDarwin.inc @@ -0,0 +1,5 @@ +<?php +if (PHP_OS === "Darwin") +{ + exit("skip for Darwin"); +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/swoole.inc b/vendor/swoole/tests/include/swoole.inc new file mode 100755 index 0000000..68c1698 --- /dev/null +++ b/vendor/swoole/tests/include/swoole.inc @@ -0,0 +1,16 @@ +<?php +require_once __DIR__ . "/config.php"; +require_once __DIR__ . "/toolkit/RandStr.php"; +require_once __DIR__ . "/toolkit/functions.php"; +require_once __DIR__ . '/../include/lib/curl.php'; + +ini_set("memory_limit", "1024M"); +ini_set("swoole.aio_mode", SWOOLE_AIO_BASE); // SWOOLE_AIO_BASE, SWOOLE_AIO_LINUX + +swoole_async_set([ + "socket_dontwait" => 1, + "aio_mode" => SWOOLE_AIO_BASE, + "thread_num" => 1, + 'disable_dns_cache' => true, + 'dns_lookup_random' => true, +]); \ No newline at end of file diff --git a/vendor/swoole/tests/include/toolkit/RandStr.php b/vendor/swoole/tests/include/toolkit/RandStr.php new file mode 100755 index 0000000..642ead8 --- /dev/null +++ b/vendor/swoole/tests/include/toolkit/RandStr.php @@ -0,0 +1,72 @@ +<?php + + +class RandStr +{ + const ALPHA = 1; + const NUM = 2; + const CHINESE = 4; + const ALL = self::ALPHA | self::NUM | self::CHINESE; + + const __ALPHA = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const __NUM = "0123456789"; + const __CHINESE2000 = "五于天末开下理事画现玫珠表珍列玉平不来与屯妻到互寺城霜载直进吉协南才垢圾夫无坟增示赤过志地雪支三夺大厅左丰百右历面帮原胡春克太磁砂灰达成顾肆友龙本村枯林械相查可机格析极检构术样档杰棕杨李要权楷七革基苛式牙划或功贡攻匠菜共区芳燕东芝世节切芭药睛睦盯虎止旧占卤贞睡肯具餐眩瞳步眯瞎卢眼皮此量时晨果虹早昌蝇曙遇昨蝗明蛤晚景暗晃显晕电最归紧昆呈叶顺呆呀中虽吕另员呼听吸只史嘛啼吵喧叫啊哪吧哟车轩因困四辊加男轴力斩胃办罗罚较边思轨轻累同财央朵曲由则崭册几贩骨内风凡赠峭迪岂邮凤生行知条长处得各务向笔物秀答称入科秒秋管秘季委么第后持拓打找年提扣押抽手折扔失换扩拉朱搂近所报扫反批且肝采肛胆肿肋肌用遥朋脸胸及胶膛爱甩妥肥脂全会估休代个介保佃仙作伯仍从你信们偿伙亿他分公化钱针然钉氏外旬名甸负儿铁角欠多久匀乐炙锭包凶争色主计庆订度让刘训为高放诉衣认义方说就变这记离良充率闰半关亲并站间部曾商产瓣前闪交六立冰普帝决闻妆冯北汪法尖洒江小浊澡渐没少泊肖兴光注洋水淡学沁池当汉涨业灶类灯煤粘烛炽烟灿烽煌粗粉炮米料炒炎迷断籽娄宽寂审宫军宙客宾家空宛社实宵灾之官字安它怀导居民收慢避惭届必怕愉懈心习悄屡忱忆敢恨怪尼卫际承阿陈耻阳职阵出降孤阴队防联孙耿辽也子限取陛姨寻姑杂毁旭如舅九奶婚妨嫌录灵巡刀好妇妈姆对参戏台劝观矣牟能难允驻驼马邓艰双线结顷红引旨强细纲张绵级给约纺弱纱继综纪弛绿经比烃定守害一在工上是国和的有人我了发以瑟斑晴语伍残封都动什杆舍鞍伏邦悲韭源善着羚磊矿剧页万尤跋森棵酒宁歌臣茹哎莽酣谨甘黄腊垂道植申卡叔趾足虚玻晶暮临象坚界肃梨刊章朝蚕品喊带雷恩闸鸭轰曼黑柬温盆苯苦某荆匡芋棋柑奎霸震积余叙者复怎炸笺简数赣彻覆碧凰皑易肠派汽拿攀势抛看拜哲岳兵肢县甫拥解穆受貌豺豪橡毅衰畏丧众输夷份雁谷苏癸蹬察镜跑软鸟鸣岛印狈逛鲁渔免见杀便誓辩尺州亢亡丹亥孩俯肪激唯截颜冲头均壮兽敝幸夹旁辞滓疗嫉泵永函兆泰康否杯系党灭庶兼播凯撰挖巨启眉媚声蕊恭舔翌翻熟屈齿龄亨蒸滁椰服矛仓她施媳案淄巢扭那丸津食霓骚令通私云爸骤蕴雍幻慈每沸曳王土木目日口田山禾白月金言火已女又干士二十寸雨古犬石厂丁西戈卜曰虫川甲皿竹斤乃八夕文广辛门贝己巳乙尸羽耳臼巴弓阶而种自深农体路正论些资形重战使等合图新还想点其起性斗把里两应制育去气问展意接情油题利压组期毛群次但孔流席运质治位器指建活教统别更真将识先专常造修病老回验很特根团转总任调热改完集毫研尔求精层清确低再证劳被号装单据设场花传判究须青越轮做整即速织书状海斯议般千影推今德差始响觉液维破消试布需胜济效选话片牧备续标存身板述底规走除置配养敌华测准许技床端感非磨往圆照搞族神容亚段算适讲按值美态彪班麦削排该击素密候草何树属市径螺英快坏移材省武培著河京助升抓含苗副谈围射例致酸却短剂宣环落首波践府考刻靠够满住枝局菌周护岩师举元超模贫减扬亩球医校呢稻滑鼓刚写微略范供块套项倒卷创律远初优死毒圈伟控跟裂粮母练塞钢顶策留误粒础故丝焊株院冷弹错散盾视艺版烈零室血缺厘绝富喷柱望盘雄似巩益洲脱投送侧润盖挥距触星松获独混座依未突架冬湿偏纹执寨责阀吃稳硬价努奇预评读背损棉侵厚泥辟卵箱掌氧停溶营终孟待尽俄缩沙退讨奋胞幼迫旋征槽殖握担鲜钻逐脚盐编蜂急伤飞域露核缘游振操甚迅辉异序纸夜乡隶缸念兰映沟吗儒磷插埃燃欢补咱芽瓦倾碳演附耪裔斜灌欧献猪腐请透司危括靛脉囤若尾束暴企穗愈拖牛染既遍锻夏井费访吹荣铜沿替滚旱悟脑措贯藏隙濮徐吴赵陆沈蒋曹唐潘袁郭蔡戴薛姚宋韩谢姜严陶董郑程倪秦邵汤葛俞杜殷龚魏梁崔邹邱彭尹庄卞贾洪盛樊侯邢郁凌仇韦童翟付祁仲宗梅鲍祝谭钟庞乔虞郝傅焦熊浦柏狄裴柳戚房毕翁储聂莫贺茅屠杭尚诸芦鞠廖骆靳詹阮惠桑柯刁柴丛齐喻桂侍舒戎阎宦巫黎涂符厉糜冒钮郎霍甄姬祖卓晓祥萍忠俊斌宏玲勇峰宝霞丽娟敏琴健静福贵勤锦艳莉涛瑞跃仁泉连喜银亮宇慧鹏茂淑芹坤剑君翠彬恒礼侠智浩菊香蓉炳寿圣贤洁耀延翔芬绍琳颖栋巧铭敬淮登鸿宜莲庭孝泽政彩诚崇彦佩宪锡钧劲锋殿希迎堂裕鹤欣汝妹岭沛莹雅佳纯靖蕾俭蔚彤湘绪尧廷锁勋庚嘉伦娥详钦寅冠骏滨威捷亭巍楼呜娜旺晋悦咏焕昭枫琼慎杏仕仪珊桃谦航舜猛卿鼎咸陵镇召敦佐熙遵桥网闽挺菲禄耘锐潮鉴婉塔蚜描粤粱惮慨乌矩疾徊碍戒买笛痛锈锌匆矢溪荤惟陪掩耸棠祭槐憨狙忙辑奉忧飘沫怖悬厌欲谱瘤货蛊赴垣嚎履闯藩遁雀渠探涸滇钡诡弟秩渗痊捏茸诬枪狠弃摇倘贬庙汇肩捎怒帽寄岸搐饼违汕蝎炔擅掖傀闹蜡裸碱奠秉丑倍萧瞒萌歧勒煎谐梳携蛇箕臂皖坍奸胎赌魁患凿傣栈唁晤碑匪翅瘫烤汛狰捍袄瞩碘嗜绰毖瓶疤俺倦冉递葬骇伶擒谴搬睬盎丈粳袋暇颈屉阜邻篓拆脊镭趣鼠疹寐鼻澎椿倔蝴酿辈钨盂购釉逆诛粹凄桅娇菏瑶父抢浮晦拂葫揉壕弊冻笼箩氛舵凹型默闲菩驰啦篡孪瑚蜗午宴驯镶砚怠粥躁豁靡拴睁丘傈腋碟懂皆淤矗浸隘挛咬帛揩瘩妖荡斟疼哥撬铣拨味哇挞迹哈孺桓蚀萄命惫幂渤稗迂瞧菱躺礁贸赶尝郡咖笆扎裤卉割炕砸潦俏饥羹锗赦博衙摆漱畅码砍钎渡绒牢捡痪棍喂辨璃澳饮洼抿窟咯辰隋憋酋绅狱悔厄"; + // const __CHINESE3000 = "啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱碱拣捡简俭剪减荐槛鉴践贱见键箭件健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸尽劲荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵觉决诀绝均菌钧军君峻俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利僳例俐痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃汀廷停亭庭艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座"; + + private static $strCache = []; + + public static function gen($len = 10, $type = self::NUM | self::ALPHA) { + $str = self::getChars($type); + $strLen = mb_strlen($str); + + $ret = ""; + for ($i = 0; $i < $len; $i++) { + // non safe rand + $ret .= mb_substr($str, rand(0, $strLen - 1), 1); + } + return $ret; + } + + static function getBytes($n) + { + if (function_exists('openssl_random_pseudo_bytes')) + { + return openssl_random_pseudo_bytes($n); + } + elseif (function_exists('random_bytes')) + { + return random_bytes($n); + } + else + { + return self::gen($n); + } + } + + private static function getChars($mask) + { + if (isset(static::$strCache[$mask])) { + return static::$strCache[$mask]; + } + + $str = ""; + if ($mask & self::NUM) { + $str .= self::__NUM; + } + + if ($mask & self::ALPHA) { + $str .= self::__ALPHA; + } + + if ($mask & self::CHINESE) { + $str .= self::__CHINESE2000; + } + + if ($str === "") { + $str .= self::NUM . self::ALPHA; + } + + static::$strCache[$mask] = $str; + return $str; + } +} \ No newline at end of file diff --git a/vendor/swoole/tests/include/toolkit/TcpStat.php b/vendor/swoole/tests/include/toolkit/TcpStat.php new file mode 100755 index 0000000..380476b --- /dev/null +++ b/vendor/swoole/tests/include/toolkit/TcpStat.php @@ -0,0 +1,87 @@ +<?php + + +class TcpStat +{ + const SS_NETSTAT_TCP_STATE_MAP = [ + "established" => "ESTABLISHED", + "syn-sent" => "SYN_SENT", + "syn-recv" => "SYN_RCVD", + "fin-wait-1" => "FIN_WAIT_1", + "fin-wait-2" => "FIN_WAIT_2", + "time-wait" => "TIME_WAIT", + "closed" => "CLOSED", + "close-wait" => "CLOSE_WAIT", + "last-ack" => "LAST_ACK", + "listen" => "LISTEN", + "closing" => "CLOSING", + ]; + + public static function xCount($path) + { + if (PHP_OS === "Darwin") { + $n = `netstat -x | grep $path | wc -l`; + return intval(trim($n)); + } else { + $n = `ss -x src $path | wc -l`; + return intval(trim($n)) - 1; + } + } + + public static function count($host, $port, $states = ["established", "time-wait", "close-wait"]) { + if (!ip2long($host)) { + $host = gethostbyname($host); + } + + $pipe = "wc -l"; + $func = PHP_OS === "Darwin" ? "netstat" : "ss"; + $states = static::fmtTcpState($states, $func); + + $info = []; + foreach ($states as $state) { + $ret = call_user_func([static::class, $func], $host, $port, $state, $pipe); + $info[$state] = intval(trim($ret)) - 1; + } + + return $info; + } + + private static function netstat($host, $port, $state, $pipe = "") + { + if ($pipe) { + $pipe = " | $pipe"; + } + // $4 src $5 dst $6 stats + return `netstat -an | awk '(\$5 == "$host.$port" && \$6 == "$state") || NR==2 {print \$0}' $pipe`; + } + + private static function ss($host, $port, $state, $pipe = "") + { + if ($pipe) { + $pipe = " | $pipe"; + } + return `ss state $state dst $host:$port $pipe`; + } + + private static function fmtTcpState(array $states, $type) + { + $from = $to = []; + if ($type === "ss") { + $to = static::SS_NETSTAT_TCP_STATE_MAP; + $from = array_flip($to); + } else if ($type === "netstat") { + $from = static::SS_NETSTAT_TCP_STATE_MAP; + $to = array_flip($from); + } + + $ret = []; + foreach ($states as $state) { + if (isset($to[$state])) { + $ret[] = $state; + } else if (isset($from[$state])) { + $ret[] = $from[$state]; + } + } + return $ret; + } +} diff --git a/vendor/swoole/tests/include/toolkit/functions.php b/vendor/swoole/tests/include/toolkit/functions.php new file mode 100755 index 0000000..d4d5af4 --- /dev/null +++ b/vendor/swoole/tests/include/toolkit/functions.php @@ -0,0 +1,626 @@ +<?php +function swoole_php_fork($func, $out = false) { + $process = new swoole_process($func, $out); + $pid = $process->start(); + + register_shutdown_function( + function ($pid, $process) + { + swoole_process::kill($pid); + $process->wait(); + }, + $pid, $process + ); + + return $process; +} + +function swoole_unittest_fork($func) +{ + $process = new swoole_process($func, false, false); + $process->start(); + + return $process; +} + +function swoole_unittest_wait() +{ + return swoole_process::wait(); +} + +function makeTcpClient($host, $port, callable $onConnect = null, callable $onReceive = null) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + assert($cli->set([ + 'open_length_check' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + ])); + $cli->on("connect", function (\swoole_client $cli) use ($onConnect) + { + assert($cli->isConnected() === true); + if ($onConnect) + { + $onConnect($cli); + } + }); + $cli->on("receive", function (\swoole_client $cli, $recv) use ($onReceive) + { + if ($onReceive) + { + $onReceive($cli, $recv); + } + }); + $cli->on("error", function (\swoole_client $cli) + { + swoole_event_exit(); + }); + $cli->on("close", function (\swoole_client $cli) + { + swoole_event_exit(); + }); + $cli->connect($host, $port); +} + + +function opcode_encode($op, $data) +{ + $r = json_encode([$op, $data]); + assert(json_last_error() === JSON_ERROR_NONE); + return pack("N", strlen($r) + 4) . $r; +} +function opcode_decode($raw) +{ + $json = substr($raw, 4); + $r = json_decode($json, true); + assert(json_last_error() === JSON_ERROR_NONE); + assert(is_array($r) && count($r) === 2); + return $r; +} +function kill_self_and_descendant($pid) +{ + if (PHP_OS === "Darwin") { + return; + } + $pids = findDescendantPids($pid); + foreach($pids as $pid) { + posix_kill($pid, SIGKILL); + } + posix_kill($pid, SIGKILL); +} +/** + * fork 一个进程把父进程pid通过消息队列传给子进程,延时把父进程干掉 + * @param int $after + * @param int $sig + */ +function killself_in_syncmode($lifetime = 1000, $sig = SIGKILL) { + $proc = new \swoole_process(function(\swoole_process $proc) use($lifetime, $sig) { + $pid = $proc->pop(); + $proc->freeQueue(); + usleep($lifetime * 1000); + \swoole_process::kill($pid, $sig); + $proc->exit(); + }, true); + $proc->useQueue(); + $proc->push(posix_getpid()); + $proc->start(); +} +/** + * 异步模式用定时器干掉自己 + * @param int $lifetime + * @param int $sig + * @param callable $cb + */ +function suicide($lifetime, $sig = SIGKILL, callable $cb = null) +{ + swoole_timer_after($lifetime, function() use($lifetime, $sig, $cb) { + if ($cb) { + $cb(); + } + echo "suicide after $lifetime ms\n"; + posix_kill(posix_getpid(), $sig); + }); +} +// 查找某pid的所有子孙pid +function findDescendantPids($pid) +{ + list($pinfo, ) = pstree(); + $y = function($pid) use(&$y, $pinfo) { + if (isset($pinfo[$pid])) { + list(, $childs) = $pinfo[$pid]; + $pids = $childs; + foreach($childs as $child) { + $pids = array_merge($pids, $y($child)); + } + return $pids; + } else { + return []; + } + }; + return $y($pid); +} +/** + * @return array [pinfo, tree] + * tree [ + * ppid + * [...child pids] + * ] + * list(ppid, array childs) = tree[pid] + */ +function pstree() +{ + $pinfo = []; + $iter = new DirectoryIterator("/proc"); + foreach($iter as $item) { + $pid = $item->getFilename(); + if ($item->isDir() && ctype_digit($pid)) { + $stat = file_get_contents("/proc/$pid/stat"); + $info = explode(" ", $stat); + $pinfo[$pid] = [intval($info[3]), []/*, $info*/]; + } + } + foreach($pinfo as $pid => $info) { + list($ppid, ) = $info; + $ppid = intval($ppid); + $pinfo[$ppid][1][] = $pid; + } + $y = function($pid, $path = []) use(&$y, $pinfo) { + if (isset($pinfo[$pid])) { + list($ppid, ) = $pinfo[$pid]; + $ppid = $ppid; + $path[] = $pid; + return $y($ppid, $path); + } else { + return array_reverse($path); + } + }; + $tree = []; + foreach($pinfo as $pid => $info) { + $path = $y($pid); + $node = &$tree; + foreach($path as $id) { + if (!isset($node[$id])) { + $node[$id] = []; + } + $node = &$node[$id]; + } + } + return [$pinfo, $tree]; +} +function debug_log($str, $handle = STDERR) +{ + if ($handle === STDERR) { + $tpl = "\033[31m[%d %s] %s\033[0m\n"; + } else { + $tpl = "[%d %s] %s\n"; + } + if (is_resource($handle)) { + fprintf($handle, $tpl, posix_getpid(), date("Y-m-d H:i:s", time()), $str); + } else { + printf($tpl, posix_getpid(), date("Y-m-d H:i:s", time()), $str); + } +} +function arrayEqual(array $a, array $b, $strict = true) +{ + if (($a && !$b) || (!$a && $b)) { + return false; + } + if ($strict) { + foreach ($a as $k => $v) { + if (!array_key_exists($k, $b)) { + return false; + } + if (gettype($v) !== gettype($b[$k])) { + return false; + } + if (is_array($v) && arrayEqual($v, $b[$k]) === false) { + return false; + } + } + return true; + } else { + $aks = array_keys($a); + $bks = array_keys($b); + sort($aks); + sort($bks); + return $aks === $bks; + } +} +function get_one_free_port() +{ + $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + $ok = socket_bind($socket, "0.0.0.0", 0); + if (!$ok) { + return false; + } + $ok = socket_listen($socket); + if (!$ok) { + return false; + } + $ok = socket_getsockname($socket, $addr, $port); + if (!$ok) { + return false; + } + socket_close($socket); + return $port; +} +function start_server($file, $host, $port, $redirect_file = "/dev/null", $ext1 = null, $ext2 = null, $debug = false) +{ + $php_executable = getenv('TEST_PHP_EXECUTABLE') ?: PHP_BINARY; + $cmd_args = getenv('TEST_PHP_ARGS'); + $fdSpec = [ + 0 => STDIN, + 1 => STDOUT, + 2 => STDERR, + ]; + /*if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = "$php_executable $cmd_args $file"; + $opts = ["bypass_shell" => true, "suppress_errors" => true]; + $handle = proc_open(addslashes($cmd), $fdSpec, $pipes, null, null, $opts); + } else { + $cmd = "exec $php_executable $file > $redirect_file 2>&1"; + $handle = proc_open($cmd, $fdSpec, $pipes); + }*/ + // 必须加exec, 否咋proc_terminate结束不了server进程 !!!!!! + if ($debug) { + $cmd = "exec $php_executable $file $host $port $ext1 $ext2"; + echo "[SHELL_EXEC]".$cmd."\n"; + } else { + $cmd = "exec $php_executable $file $host $port $ext1 $ext2 > $redirect_file 2>&1"; + } + // $cmd = "exec $php_executable $file $host $port"; + $handle = proc_open($cmd, $fdSpec, $pipes); + if ($handle === false) { + exit(__FUNCTION__ . " fail"); + } + make_sure_server_listen_success: + { + $i = 0; + $fp = null; + while (($i++ < 30) && !($fp = @fsockopen($host, $port))) { + usleep(10000); + } + if ($fp) { + fclose($fp); + } + } +// linux上有问题,client端事件循环还没起起来就会先调用这个shutdown回调, 结束了子进程 +// 第二个shutdown_function swoole才会把子进程的事件循环起来 +// register_shutdown_function(function() use($handle, $redirect_file) { +// proc_terminate($handle, SIGTERM); +// @unlink($redirect_file); +// }); + return function() use($handle, $redirect_file) { + // @unlink($redirect_file); + proc_terminate($handle, SIGTERM); + swoole_event_exit(); + exit(); + }; +} +function fork_exec(callable $fn, $f_stdout = "/dev/null", $f_stderr = null) +{ + $pid = pcntl_fork(); + if ($pid < 0) { + exit("fork fail"); + } + if ($pid === 0) { + fclose(STDOUT); + $STDOUT = fopen($f_stdout, "w"); + if ($f_stderr !== null) { + fclose(STDERR); + $STDERR = fopen($f_stderr, "w"); + } + $fn(); + exit; + } + pcntl_waitpid($pid, $status); +} +/** + * spawn_exec + * @param null|string $cmd command + * @param null|string $input code + * @param null|int $tv_sec timeout sec + * @param null|int $tv_usec timeout usec + * @param null|string $cwd change work dir + * @param array|null $env env + * @return array [out, err] + */ +function spawn_exec($cmd, $input = null, $tv_sec = null, $tv_usec = null, $cwd = null, array $env = null) +{ + $out = $err = null; + $winOpt = ['suppress_errors' => true, 'binary_pipes' => true]; + $proc = proc_open($cmd, [ + 0 => ["pipe", "r"], + 1 => ["pipe", "w"], + 2 => ["pipe", "w"], + ], $pipes, $cwd, $env, $winOpt); + assert($proc !== false); + if ($input !== null) { + $n = fwrite($pipes[0], $input); + if (strlen($input) !== $n) { + goto closePipes; + } + } + // 必须关闭 + assert(fclose($pipes[0])); + unset($pipes[0]); + // 防止select立即返回, 消耗cpu + assert(!($tv_sec === 0 && $tv_usec === 0)); + while (true) { + $r = $pipes; + $w = null; + $e = null; + /* 隐藏被信号或者其他系统调用打断 产生的错误*/ + set_error_handler(function() {}); + $n = @stream_select($r, $w, $e, $tv_sec, $tv_usec); + restore_error_handler(); + if ($n === false) { + break; + } else if ($n === 0) { + // 超时kill -9 + assert(proc_terminate($proc, SIGKILL)); + throw new \RuntimeException("exec $cmd time out"); + } else if ($n > 0) { + foreach ($r as $handle) { + if ($handle === $pipes[1]) { + $_ = &$out; + } else if ($handle === $pipes[2]) { + $_ = &$err; + } else { + $_ = ""; + } + $line = fread($handle, 8192); + $isEOF = $line === ""; + if ($isEOF) { + break 2; + } else { + $_ .= $line; + } + } + } + } + closePipes: + foreach ($pipes as $fd => $pipe) { + if (is_resource($pipe)) { + @fclose($pipe); + } + unset($pipes[$fd]); + } + return [$out, $err]; +} + +function parent_child($parentFunc, $childFunc) +{ + $pid = pcntl_fork(); + if ($pid < 0) + { + echo "ERROR"; + exit; + } + if ($pid === 0) + { + $childFunc(); + exit; + } + else + { + $parentFunc($pid); + } +} + +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +class ProcessManager +{ + /** + * @var swoole_atomic + */ + protected $atomic; + protected $alone = false; + + public $parentFunc; + public $childFunc; + public $async = false; + + protected $childPid; + + protected $parentFirst = false; + + function __construct() + { + $this->atomic = new swoole_atomic(0); + } + + function setParent(callable $func) + { + $this->parentFunc = $func; + } + + function parentFirst() + { + $this->parentFirst = true; + } + + function childFirst() + { + $this->parentFirst = false; + } + + function setChild(callable $func) + { + $this->childFunc = $func; + } + + //等待信息 + function wait() + { + $this->atomic->wait(); + } + + //唤醒等待的进程 + function wakeup() + { + $this->atomic->wakeup(); + } + + function runParentFunc($pid = 0) + { + return call_user_func($this->parentFunc, $pid); + } + + function runChildFunc() + { + return call_user_func($this->childFunc); + } + + function fork($func) + { + $pid = pcntl_fork(); + if ($pid > 0) + { + return $pid; + } + elseif ($pid < 0) + { + return false; + } + else + { + call_user_func($func); + exit; + } + } + + /** + * 杀死子进程 + */ + function kill() + { + if (!$this->alone) + { + swoole_process::kill($this->childPid); + } + } + + function run() + { + global $argv, $argc; + if ($argc > 1) + { + if ($argv[1] == 'child') + { + $this->alone = true; + return $this->runChildFunc(); + } + elseif ($argv[1] == 'parent') + { + $this->alone = true; + return $this->runParentFunc(); + } + } + $pid = pcntl_fork(); + if ($this->parentFirst) + { + $this->atomic->set(0); + } + if ($pid < 0) + { + echo "ERROR"; + exit; + } + //子进程 + elseif ($pid === 0) + { + //等待父进程 + if ($this->parentFirst) + { + $this->wait(); + } + $this->runChildFunc(); + exit; + } + //父进程 + else + { + $this->childPid = $pid; + //子进程优先运行,父进程进入等待状态 + if (!$this->parentFirst) + { + $this->wait(); + } + $this->runParentFunc($pid); + if ($this->async) + { + swoole_event::wait(); + } + pcntl_waitpid($pid, $status); + } + } +} + + +/* + +----------------------------------------------------------------------+ + | Swoole | + +----------------------------------------------------------------------+ + | Copyright (c) 2012-2017 The Swoole Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.0 of the Apache license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.apache.org/licenses/LICENSE-2.0.html | + | If you did not receive a copy of the Apache2.0 license and are unable| + | to obtain it through the world-wide-web, please send a note to | + | license@swoole.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Tianfeng Han <mikan.tenny@gmail.com> | + +----------------------------------------------------------------------+ + */ +class ServerManager +{ + protected $host; + protected $file; + public $port; + + function __construct($file) + { + if (!is_file($file)) + { + throw new \Exception("server file [$file] not exists."); + } + $this->file = $file; + } + + function listen($host = '127.0.0.1', $port = 0) + { + $this->port = $port == 0 ? get_one_free_port() : $port; + $this->host = $host; + } + + function run($debug = false) + { + return start_server($this->file, $this->host, $this->port, "/dev/null", null, null, $debug); + } +} + +function debug($var) +{ + var_dump($var); + exit; +} \ No newline at end of file diff --git a/vendor/swoole/tests/new.sh b/vendor/swoole/tests/new.sh new file mode 100755 index 0000000..e8c710e --- /dev/null +++ b/vendor/swoole/tests/new.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env php +<?php +define('SWOOLE_COLOR_RED', 1); +define('SWOOLE_COLOR_GREEN', 2); +define('SWOOLE_COLOR_YELLOW', 3); +define('SWOOLE_COLOR_BLUE', 4); +define('SWOOLE_COLOR_MAGENTA', 5); +define('SWOOLE_COLOR_CYAN', 6); +define('SWOOLE_COLOR_WHITE', 7); +function swoole_color(string $content, int $color): string +{ + return "\033[3{$color}m{$content}\033[0m"; +} + +function fgetsin(string $tip = '', bool $accept_empty = true): string +{ + do { + if ($tip) { + echo "$tip: "; + } + $in = trim(fgets(STDIN)); + } while (!$accept_empty && $in === ''); + + return $in; +} + +function yes(string $content = ''): bool +{ + echo $content; + return fgetsin() === 'y'; +} + +if (empty($argv[1])) { + error_filename: + exit( + swoole_color("Please enter the correct file name or path! e.g.:", SWOOLE_COLOR_RED) . + swoole_color("\n\"./new.sh ./swoole_coroutine\"\n", SWOOLE_COLOR_MAGENTA) + ); +} + +$filename = $argv[1]; +if (!pathinfo($filename, PATHINFO_EXTENSION)) { + $path = ['dirname' => $filename]; +} else { + $path = pathinfo($filename); +} +$path['dirname'] = trim($path['dirname'], './'); // i know arg2 is a list but it's no problem + +$replacement = []; +$tip = swoole_color("[Test name]: ", SWOOLE_COLOR_BLUE); +$replacement['test_name'] = fgetsin($tip, false); +$tip = swoole_color("[Test intro]: ", SWOOLE_COLOR_BLUE); +$replacement['test_intro'] = fgetsin($tip); + +if (empty($path['filename'])) { + $path['filename'] = $replacement['test_name']; // use test name to be filename +} +$filename = "{$path['dirname']}/{$path['filename']}.phpt"; + +//if dir not exist, create it +if (!is_dir(__DIR__ . "/{$path['dirname']}")) { + echo swoole_color( + "The dir [{$path['dirname']}] is not exist, if you want to create it? [y/n]: ", + SWOOLE_COLOR_YELLOW + ); + if (yes()) { + mkdir($path['dirname'], 0755, true); + } else { + exit(swoole_color('Can\'t generate the test file in nonexistent dir!', SWOOLE_COLOR_RED)); + } +} elseif (file_exists($filename)) { + echo swoole_color("The file [{$path['filename']}] is exist, if you want to overwrite it? [y/n]: ", SWOOLE_COLOR_YELLOW); + if (!yes()) { + exit(swoole_color('You should rename your test filename.', SWOOLE_COLOR_RED)); + } +} + +//calc dir deep +$deep = 0; +$temp = $filename; +while (($temp = dirname($temp)) !== '.') { + $deep++; +} +if ($deep < 1) { + goto error_filename; +} + +$template = file_get_contents(__DIR__ . '/template.phpt'); +$replacement['dir_deep'] = str_repeat('/..', $deep); +foreach ($replacement as $key => $value) { + $template = str_replace("{{{$key}}}", $value, $template); +} + +if (file_put_contents($filename, $template)) { + echo swoole_color("Generate the test file successfully!\n", SWOOLE_COLOR_GREEN) . + "[" . __DIR__ . "/$filename]"; + @shell_exec('/usr/bin/env git add ' . __DIR__ . "/$filename"); + if (\stripos(PHP_OS, 'Darwin') !== false) { + //MacOS + $pstorm = '/usr/local/bin/pstorm'; + if (file_exists($pstorm) || ( + file_exists('/Applications/PhpStorm.app') && + file_put_contents($pstorm, file_get_contents(__DIR__ . '/include/macos/phpstorm.py')) && + chmod($pstorm, 0744) + ) + ) { + @shell_exec("/usr/local/bin/phpstorm {$filename}"); + } + } +} else { + exit("\nGenerate the test file failed!"); +} diff --git a/vendor/swoole/tests/run-tests b/vendor/swoole/tests/run-tests new file mode 100755 index 0000000..cc1e9ea --- /dev/null +++ b/vendor/swoole/tests/run-tests @@ -0,0 +1,2912 @@ +#!/usr/bin/env php +<?php +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2017 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Ilia Alshanetsky <iliaa@php.net> | + | Preston L. Bannister <pbannister@php.net> | + | Marcus Boerger <helly@php.net> | + | Derick Rethans <derick@php.net> | + | Sander Roobol <sander@php.net> | + | (based on version by: Stig Bakken <ssb@php.net>) | + | (based on the PHP 3 test framework by Rasmus Lerdorf) | + +----------------------------------------------------------------------+ + */ + +/* $Id: 1991b56a087a4b6df1d9a65676d24112078512a1 $ */ + +/* Sanity check to ensure that pcre extension needed by this script is available. + * In the event it is not, print a nice error message indicating that this script will + * not run without it. + */ + +if (!extension_loaded('pcre')) { + echo <<<NO_PCRE_ERROR + ++-----------------------------------------------------------+ +| ! ERROR ! | +| The test-suite requires that you have pcre extension | +| enabled. To enable this extension either compile your PHP | +| with --with-pcre-regex or if you've compiled pcre as a | +| shared module load it via php.ini. | ++-----------------------------------------------------------+ + +NO_PCRE_ERROR; +exit; +} + +if (!function_exists('proc_open')) { + echo <<<NO_PROC_OPEN_ERROR + ++-----------------------------------------------------------+ +| ! ERROR ! | +| The test-suite requires that proc_open() is available. | +| Please check if you disabled it in php.ini. | ++-----------------------------------------------------------+ + +NO_PROC_OPEN_ERROR; +exit; +} + +// If timezone is not set, use UTC. +if (ini_get('date.timezone') == '') { + date_default_timezone_set('UTC'); +} + +// store current directory +$CUR_DIR = getcwd(); + +// change into the PHP source directory. + +if (getenv('TEST_PHP_SRCDIR')) { + @chdir(getenv('TEST_PHP_SRCDIR')); +} + +// Delete some security related environment variables +putenv('SSH_CLIENT=deleted'); +putenv('SSH_AUTH_SOCK=deleted'); +putenv('SSH_TTY=deleted'); +putenv('SSH_CONNECTION=deleted'); + +$cwd = getcwd(); +set_time_limit(0); + +ini_set('pcre.backtrack_limit', PHP_INT_MAX); + +$valgrind_version = 0; +$valgrind_header = ''; + +// delete as much output buffers as possible +while(@ob_end_clean()); +if (ob_get_level()) echo "Not all buffers were deleted.\n"; + +error_reporting(E_ALL); + +$environment = isset($_ENV) ? $_ENV : array(); +if ((substr(PHP_OS, 0, 3) == "WIN") && empty($environment["SystemRoot"])) { + $environment["SystemRoot"] = getenv("SystemRoot"); +} + +// Don't ever guess at the PHP executable location. +// Require the explicit specification. +// Otherwise we could end up testing the wrong file! + +$php = null; +$php_cgi = null; +$phpdbg = null; + +if (getenv('TEST_PHP_EXECUTABLE')) { + $php = getenv('TEST_PHP_EXECUTABLE'); + + if ($php=='auto') { + $php = $cwd . '/sapi/cli/php'; + putenv("TEST_PHP_EXECUTABLE=$php"); + + if (!getenv('TEST_PHP_CGI_EXECUTABLE')) { + $php_cgi = $cwd . '/sapi/cgi/php-cgi'; + + if (file_exists($php_cgi)) { + putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi"); + } else { + $php_cgi = null; + } + } + } + $environment['TEST_PHP_EXECUTABLE'] = $php; +} + +if (getenv('TEST_PHP_CGI_EXECUTABLE')) { + $php_cgi = getenv('TEST_PHP_CGI_EXECUTABLE'); + + if ($php_cgi=='auto') { + $php_cgi = $cwd . '/sapi/cgi/php-cgi'; + putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi"); + } + + $environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi; +} + +if (!getenv('TEST_PHPDBG_EXECUTABLE')) { + if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/phpdbg.exe")) { + $phpdbg = realpath(dirname($php) . "/phpdbg.exe"); + } elseif (file_exists(dirname($php) . "/../../sapi/phpdbg/phpdbg")) { + $phpdbg = realpath(dirname($php) . "/../../sapi/phpdbg/phpdbg"); + } elseif (file_exists("./sapi/phpdbg/phpdbg")) { + $phpdbg = realpath("./sapi/phpdbg/phpdbg"); + } elseif (file_exists(dirname($php) . "/phpdbg")) { + $phpdbg = realpath(dirname($php) . "/phpdbg"); + } else { + $phpdbg = null; + } + if ($phpdbg) { + putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg"); + } +} + +if (getenv('TEST_PHPDBG_EXECUTABLE')) { + $phpdbg = getenv('TEST_PHPDBG_EXECUTABLE'); + + if ($phpdbg=='auto') { + $phpdbg = $cwd . '/sapi/phpdbg/phpdbg'; + putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg"); + } + + $environment['TEST_PHPDBG_EXECUTABLE'] = $phpdbg; +} + +function verify_config() +{ + global $php; + + if (empty($php) || !file_exists($php)) { + error('environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!'); + } + + if (function_exists('is_executable') && !is_executable($php)) { + error("invalid PHP executable specified by TEST_PHP_EXECUTABLE = $php"); + } +} + +if (getenv('TEST_PHP_LOG_FORMAT')) { + $log_format = strtoupper(getenv('TEST_PHP_LOG_FORMAT')); +} else { + $log_format = 'LEODS'; +} + +// Check whether a detailed log is wanted. +if (getenv('TEST_PHP_DETAILED')) { + $DETAILED = getenv('TEST_PHP_DETAILED'); +} else { + $DETAILED = 0; +} + +junit_init(); + +if (getenv('SHOW_ONLY_GROUPS')) { + $SHOW_ONLY_GROUPS = explode(",", getenv('SHOW_ONLY_GROUPS')); +} else { + $SHOW_ONLY_GROUPS = array(); +} + +// Check whether user test dirs are requested. +if (getenv('TEST_PHP_USER')) { + $user_tests = explode (',', getenv('TEST_PHP_USER')); +} else { + $user_tests = array(); +} + +$exts_to_test = array(); +$ini_overwrites = array( + 'output_handler=', + 'open_basedir=', + 'disable_functions=', + 'output_buffering=Off', + 'error_reporting=' . (E_ALL | E_STRICT), + 'display_errors=1', + 'display_startup_errors=1', + 'log_errors=0', + 'html_errors=0', + 'report_memleaks=1', + 'report_zend_debug=0', + 'docref_root=', + 'docref_ext=.html', + 'error_prepend_string=', + 'error_append_string=', + 'auto_prepend_file=', + 'auto_append_file=', + 'ignore_repeated_errors=0', + 'precision=14', + 'memory_limit=128M', + 'log_errors_max_len=0', + 'opcache.fast_shutdown=0', + 'opcache.file_update_protection=0', + ); + +$no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0'; + +function write_information($show_html) +{ + global $cwd, $php, $php_cgi, $phpdbg, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $leak_check, $valgrind_header, $no_file_cache; + + // Get info from php + $info_file = __DIR__ . '/run-test-info.php'; + @unlink($info_file); + $php_info = '<?php echo " +PHP_SAPI : " , PHP_SAPI , " +PHP_VERSION : " , phpversion() , " +ZEND_VERSION: " , zend_version() , " +PHP_OS : " , PHP_OS , " - " , php_uname() , " +INI actual : " , realpath(get_cfg_var("cfg_file_path")) , " +More .INIs : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n","", php_ini_scanned_files()) : "** not determined **"); ?>'; + save_text($info_file, $php_info); + $info_params = array(); + settings2array($ini_overwrites, $info_params); + settings2params($info_params); + $php_info = `$php $pass_options $info_params $no_file_cache "$info_file"`; + define('TESTED_PHP_VERSION', `$php -n -r "echo PHP_VERSION;"`); + + if ($php_cgi && $php != $php_cgi) { + $php_info_cgi = `$php_cgi $pass_options $info_params $no_file_cache -q "$info_file"`; + $php_info_sep = "\n---------------------------------------------------------------------"; + $php_cgi_info = "$php_info_sep\nPHP : $php_cgi $php_info_cgi$php_info_sep"; + } else { + $php_cgi_info = ''; + } + + if ($phpdbg) { + $phpdbg_info = `$phpdbg $pass_options $info_params $no_file_cache -qrr "$info_file"`; + $php_info_sep = "\n---------------------------------------------------------------------"; + $phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep"; + } else { + $phpdbg_info = ''; + } + + if (function_exists('opcache_invalidate')) { + opcache_invalidate($info_file, true); + } + @unlink($info_file); + + // load list of enabled extensions + save_text($info_file, '<?php echo str_replace("Zend OPcache", "opcache", join(",", get_loaded_extensions())); ?>'); + $exts_to_test = explode(',',`$php $pass_options $info_params $no_file_cache "$info_file"`); + // check for extensions that need special handling and regenerate + $info_params_ex = array( + 'session' => array('session.auto_start=0'), + 'tidy' => array('tidy.clean_output=0'), + 'zlib' => array('zlib.output_compression=Off'), + 'xdebug' => array('xdebug.default_enable=0'), + 'mbstring' => array('mbstring.func_overload=0'), + ); + + foreach($info_params_ex as $ext => $ini_overwrites_ex) { + if (in_array($ext, $exts_to_test)) { + $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex); + } + } + + if (function_exists('opcache_invalidate')) { + opcache_invalidate($info_file, true); + } + @unlink($info_file); + + // Write test context information. + echo " +===================================================================== +PHP : $php $php_info $php_cgi_info $phpdbg_info +CWD : $cwd +Extra dirs : "; + foreach ($user_tests as $test_dir) { + echo "{$test_dir}\n "; + } + echo " +VALGRIND : " . ($leak_check ? $valgrind_header : 'Not used') . " +===================================================================== +"; +} + +define('PHP_QA_EMAIL', 'qa-reports@lists.php.net'); +define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php'); +define('QA_REPORTS_PAGE', 'http://qa.php.net/reports'); +define('TRAVIS_CI' , (bool) getenv('TRAVIS')); + +function save_or_mail_results() +{ + global $sum_results, $just_save_results, $failed_test_summary, + $PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file, $compression; + + /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */ + if (!getenv('NO_INTERACTION') && !TRAVIS_CI) { + $fp = fopen("php://stdin", "r+"); + if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED']) { + echo "\nYou may have found a problem in PHP."; + } + echo "\nThis report can be automatically sent to the PHP QA team at\n"; + echo QA_REPORTS_PAGE . " and http://news.php.net/php.qa.reports\n"; + echo "This gives us a better understanding of PHP's behavior.\n"; + echo "If you don't want to send the report immediately you can choose\n"; + echo "option \"s\" to save it. You can then email it to ". PHP_QA_EMAIL . " later.\n"; + echo "Do you want to send this report now? [Yns]: "; + flush(); + + $user_input = fgets($fp, 10); + $just_save_results = (strtolower($user_input[0]) == 's'); + } + + if ($just_save_results || !getenv('NO_INTERACTION') || TRAVIS_CI) { + if ($just_save_results || TRAVIS_CI || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') { + /* + * Collect information about the host system for our report + * Fetch phpinfo() output so that we can see the PHP environment + * Make an archive of all the failed tests + * Send an email + */ + if ($just_save_results) { + $user_input = 's'; + } + + /* Ask the user to provide an email address, so that QA team can contact the user */ + if (TRAVIS_CI) { + $user_email = 'travis at php dot net'; + } elseif (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) { + echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): "; + flush(); + $user_email = trim(fgets($fp, 1024)); + $user_email = str_replace("@", " at ", str_replace(".", " dot ", $user_email)); + } + + $failed_tests_data = ''; + $sep = "\n" . str_repeat('=', 80) . "\n"; + $failed_tests_data .= $failed_test_summary . "\n"; + $failed_tests_data .= get_summary(true, false) . "\n"; + + if ($sum_results['FAILED']) { + foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) { + $failed_tests_data .= $sep . $test_info['name'] . $test_info['info']; + $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output']), FILE_BINARY); + $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff']), FILE_BINARY); + $failed_tests_data .= $sep . "\n\n"; + } + $status = "failed"; + } else { + $status = "success"; + } + + $failed_tests_data .= "\n" . $sep . 'BUILD ENVIRONMENT' . $sep; + $failed_tests_data .= "OS:\n" . PHP_OS . " - " . php_uname() . "\n\n"; + $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A'; + + if (substr(PHP_OS, 0, 3) != "WIN") { + /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */ + if (getenv('PHP_AUTOCONF')) { + $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version'); + } else { + $autoconf = shell_exec('autoconf --version'); + } + + /* Always use the generated libtool - Mac OSX uses 'glibtool' */ + $libtool = shell_exec($CUR_DIR . '/libtool --version'); + + /* Use shtool to find out if there is glibtool present (MacOSX) */ + $sys_libtool_path = shell_exec(__DIR__ . '/build/shtool path glibtool libtool'); + + if ($sys_libtool_path) { + $sys_libtool = shell_exec(str_replace("\n", "", $sys_libtool_path) . ' --version'); + } + + /* Try the most common flags for 'version' */ + $flags = array('-v', '-V', '--version'); + $cc_status = 0; + + foreach($flags AS $flag) { + system(getenv('CC') . " $flag >/dev/null 2>&1", $cc_status); + if ($cc_status == 0) { + $compiler = shell_exec(getenv('CC') . " $flag 2>&1"); + break; + } + } + + $ldd = shell_exec("ldd $php 2>/dev/null"); + } + + $failed_tests_data .= "Autoconf:\n$autoconf\n"; + $failed_tests_data .= "Bundled Libtool:\n$libtool\n"; + $failed_tests_data .= "System Libtool:\n$sys_libtool\n"; + $failed_tests_data .= "Compiler:\n$compiler\n"; + $failed_tests_data .= "Bison:\n". shell_exec('bison --version 2>/dev/null') . "\n"; + $failed_tests_data .= "Libraries:\n$ldd\n"; + $failed_tests_data .= "\n"; + + if (isset($user_email)) { + $failed_tests_data .= "User's E-mail: " . $user_email . "\n\n"; + } + + $failed_tests_data .= $sep . "PHPINFO" . $sep; + $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null'); + + if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status) && !TRAVIS_CI) { + file_put_contents($output_file, $failed_tests_data); + + if (!$just_save_results) { + echo "\nThe test script was unable to automatically send the report to PHP's QA Team\n"; + } + + echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n"; + } elseif (!getenv('NO_INTERACTION') && !TRAVIS_CI) { + fwrite($fp, "\nThank you for helping to make PHP better.\n"); + fclose($fp); + } + } + } +} + +// Determine the tests to be run. + +$test_files = array(); +$redir_tests = array(); +$test_results = array(); +$PHP_FAILED_TESTS = array('BORKED' => array(), 'FAILED' => array(), 'WARNED' => array(), 'LEAKED' => array(), 'XFAILED' => array()); + +// If parameters given assume they represent selected tests to run. +$failed_tests_file= false; +$pass_option_n = false; +$pass_options = ''; + +$compression = 0; +$output_file = $CUR_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt'; + +if ($compression && in_array("compress.zlib", stream_get_filters())) { + $output_file = 'compress.zlib://' . $output_file . '.gz'; +} + +$just_save_results = false; +$leak_check = false; +$html_output = false; +$html_file = null; +$temp_source = null; +$temp_target = null; +$temp_urlbase = null; +$conf_passed = null; +$no_clean = false; + +$cfgtypes = array('show', 'keep'); +$cfgfiles = array('skip', 'php', 'clean', 'out', 'diff', 'exp'); +$cfg = array(); + +foreach($cfgtypes as $type) { + $cfg[$type] = array(); + + foreach($cfgfiles as $file) { + $cfg[$type][$file] = false; + } +} + +if (getenv('TEST_PHP_ARGS')) { + + if (!isset($argc) || !$argc || !isset($argv)) { + $argv = array(__FILE__); + } + + $argv = array_merge($argv, explode(' ', getenv('TEST_PHP_ARGS'))); + $argc = count($argv); +} + +if (isset($argc) && $argc > 1) { + + for ($i=1; $i<$argc; $i++) { + $is_switch = false; + $switch = substr($argv[$i],1,1); + $repeat = substr($argv[$i],0,1) == '-'; + + while ($repeat) { + + if (!$is_switch) { + $switch = substr($argv[$i],1,1); + } + + $is_switch = true; + + if ($repeat) { + foreach($cfgtypes as $type) { + if (strpos($switch, '--' . $type) === 0) { + foreach($cfgfiles as $file) { + if ($switch == '--' . $type . '-' . $file) { + $cfg[$type][$file] = true; + $is_switch = false; + break; + } + } + } + } + } + + if (!$is_switch) { + $is_switch = true; + break; + } + + $repeat = false; + + switch($switch) { + case 'r': + case 'l': + $test_list = file($argv[++$i]); + if ($test_list) { + foreach($test_list as $test) { + $matches = array(); + if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) { + $redir_tests[] = array($matches[1], $matches[2]); + } else if (strlen($test)) { + $test_files[] = trim($test); + } + } + } + if ($switch != 'l') { + break; + } + $i--; + // break left intentionally + case 'w': + $failed_tests_file = fopen($argv[++$i], 'w+t'); + break; + case 'a': + $failed_tests_file = fopen($argv[++$i], 'a+t'); + break; + case 'c': + $conf_passed = $argv[++$i]; + break; + case 'd': + $ini_overwrites[] = $argv[++$i]; + break; + case 'g': + $SHOW_ONLY_GROUPS = explode(",", $argv[++$i]); + break; + //case 'h' + case '--keep-all': + foreach($cfgfiles as $file) { + $cfg['keep'][$file] = true; + } + break; + //case 'l' + case 'm': + $leak_check = true; + $valgrind_cmd = "valgrind --version"; + $valgrind_header = system_with_timeout($valgrind_cmd, $environment); + $replace_count = 0; + if (!$valgrind_header) { + error("Valgrind returned no version info, cannot proceed.\nPlease check if Valgrind is installed."); + } else { + $valgrind_version = preg_replace("/valgrind-(\d+)\.(\d+)\.(\d+)([.\w_-]+)?(\s+)/", '$1.$2.$3', $valgrind_header, 1, $replace_count); + if ($replace_count != 1) { + error("Valgrind returned invalid version info (\"$valgrind_header\"), cannot proceed."); + } + $valgrind_header = trim($valgrind_header); + } + break; + case 'n': + if (!$pass_option_n) { + $pass_options .= ' -n'; + } + $pass_option_n = true; + break; + case 'e': + $pass_options .= ' -e'; + break; + case '--no-clean': + $no_clean = true; + break; + case 'p': + $php = $argv[++$i]; + putenv("TEST_PHP_EXECUTABLE=$php"); + $environment['TEST_PHP_EXECUTABLE'] = $php; + break; + case 'P': + if(constant('PHP_BINARY')) { + $php = PHP_BINARY; + } else { + break; + } + putenv("TEST_PHP_EXECUTABLE=$php"); + $environment['TEST_PHP_EXECUTABLE'] = $php; + break; + case 'q': + putenv('NO_INTERACTION=1'); + break; + //case 'r' + case 's': + $output_file = $argv[++$i]; + $just_save_results = true; + break; + case '--set-timeout': + $environment['TEST_TIMEOUT'] = $argv[++$i]; + break; + case '--show-all': + foreach($cfgfiles as $file) { + $cfg['show'][$file] = true; + } + break; + case '--temp-source': + $temp_source = $argv[++$i]; + break; + case '--temp-target': + $temp_target = $argv[++$i]; + if ($temp_urlbase) { + $temp_urlbase = $temp_target; + } + break; + case '--temp-urlbase': + $temp_urlbase = $argv[++$i]; + break; + case 'v': + case '--verbose': + $DETAILED = true; + break; + case 'x': + $environment['SKIP_SLOW_TESTS'] = 1; + break; + case '--offline': + $environment['SKIP_ONLINE_TESTS'] = 1; + break; + //case 'w' + case '-': + // repeat check with full switch + $switch = $argv[$i]; + if ($switch != '-') { + $repeat = true; + } + break; + case '--html': + $html_file = fopen($argv[++$i], 'wt'); + $html_output = is_resource($html_file); + break; + case '--version': + echo '$Id: 1991b56a087a4b6df1d9a65676d24112078512a1 $' . "\n"; + exit(1); + + default: + echo "Illegal switch '$switch' specified!\n"; + case 'h': + case '-help': + case '--help': + echo <<<HELP +Synopsis: + php run-tests.php [options] [files] [directories] + +Options: + -l <file> Read the testfiles to be executed from <file>. After the test + has finished all failed tests are written to the same <file>. + If the list is empty and no further test is specified then + all tests are executed (same as: -r <file> -w <file>). + + -r <file> Read the testfiles to be executed from <file>. + + -w <file> Write a list of all failed tests to <file>. + + -a <file> Same as -w but append rather then truncating <file>. + + -c <file> Look for php.ini in directory <file> or use <file> as ini. + + -n Pass -n option to the php binary (Do not use a php.ini). + + -d foo=bar Pass -d option to the php binary (Define INI entry foo + with value 'bar'). + + -g Comma separated list of groups to show during test run + (possible values: PASS, FAIL, XFAIL, SKIP, BORK, WARN, LEAK, REDIRECT). + + -m Test for memory leaks with Valgrind. + + -p <php> Specify PHP executable to run. + + -P Use PHP_BINARY as PHP executable to run. + + -q Quiet, no user interaction (same as environment NO_INTERACTION). + + -s <file> Write output to <file>. + + -x Sets 'SKIP_SLOW_TESTS' environmental variable. + + --offline Sets 'SKIP_ONLINE_TESTS' environmental variable. + + --verbose + -v Verbose mode. + + --help + -h This Help. + + --html <file> Generate HTML output. + + --temp-source <sdir> --temp-target <tdir> [--temp-urlbase <url>] + Write temporary files to <tdir> by replacing <sdir> from the + filenames to generate with <tdir>. If --html is being used and + <url> given then the generated links are relative and prefixed + with the given url. In general you want to make <sdir> the path + to your source files and <tdir> some pach in your web page + hierarchy with <url> pointing to <tdir>. + + --keep-[all|php|skip|clean] + Do not delete 'all' files, 'php' test file, 'skip' or 'clean' + file. + + --set-timeout [n] + Set timeout for individual tests, where [n] is the number of + seconds. The default value is 60 seconds, or 300 seconds when + testing for memory leaks. + + --show-[all|php|skip|clean|exp|diff|out] + Show 'all' files, 'php' test file, 'skip' or 'clean' file. You + can also use this to show the output 'out', the expected result + 'exp' or the difference between them 'diff'. The result types + get written independent of the log format, however 'diff' only + exists when a test fails. + + --no-clean Do not execute clean section if any. + +HELP; + exit(1); + } + } + + if (!$is_switch) { + $testfile = realpath($argv[$i]); + + if (!$testfile && strpos($argv[$i], '*') !== false && function_exists('glob')) { + + if (preg_match("/\.phpt$/", $argv[$i])) { + $pattern_match = glob($argv[$i]); + } else if (preg_match("/\*$/", $argv[$i])) { + $pattern_match = glob($argv[$i] . '.phpt'); + } else { + die("bogus test name " . $argv[$i] . "\n"); + } + + if (is_array($pattern_match)) { + $test_files = array_merge($test_files, $pattern_match); + } + + } else if (is_dir($testfile)) { + find_files($testfile); + } else if (preg_match("/\.phpt$/", $testfile)) { + $test_files[] = $testfile; + } else { + die("bogus test name " . $argv[$i] . "\n"); + } + } + } + + if (strlen($conf_passed)) { + if (substr(PHP_OS, 0, 3) == "WIN") { + $pass_options .= " -c " . escapeshellarg($conf_passed); + } else { + $pass_options .= " -c '$conf_passed'"; + } + } + + $test_files = array_unique($test_files); + $test_files = array_merge($test_files, $redir_tests); + + // Run selected tests. + $test_cnt = count($test_files); + + if ($test_cnt) { + putenv('NO_INTERACTION=1'); + verify_config(); + write_information($html_output); + usort($test_files, "test_sort"); + $start_time = time(); + + if (!$html_output) { + echo "Running selected tests.\n"; + } else { + show_start($start_time); + } + + $test_idx = 0; + run_all_tests($test_files, $environment); + $end_time = time(); + + if ($html_output) { + show_end($end_time); + } + + if ($failed_tests_file) { + fclose($failed_tests_file); + } + + compute_summary(); + if ($html_output) { + fwrite($html_file, "<hr/>\n" . get_summary(false, true)); + } + echo "====================================================================="; + echo get_summary(false, false); + + if ($html_output) { + fclose($html_file); + } + + if ($output_file != '' && $just_save_results) { + save_or_mail_results(); + } + + junit_save_xml(); + + if (getenv('REPORT_EXIT_STATUS') == 1 && ($sum_results['FAILED'] || $sum_results['BORKED'])) { + exit(1); + } + + exit(0); + } +} + +verify_config(); +write_information($html_output); + +// Compile a list of all test files (*.phpt). +$test_files = array(); +$exts_tested = count($exts_to_test); +$exts_skipped = 0; +$ignored_by_ext = 0; +sort($exts_to_test); +$test_dirs = array(); +$optionals = array('tests', 'ext', 'Zend', 'sapi'); + +foreach($optionals as $dir) { + if (@filetype($dir) == 'dir') { + $test_dirs[] = $dir; + } +} + +// Convert extension names to lowercase +foreach ($exts_to_test as $key => $val) { + $exts_to_test[$key] = strtolower($val); +} + +foreach ($test_dirs as $dir) { + find_files("{$cwd}/{$dir}", ($dir == 'ext')); +} + +foreach ($user_tests as $dir) { + find_files($dir, ($dir == 'ext')); +} + +function find_files($dir, $is_ext_dir = false, $ignore = false) +{ + global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped, $exts_tested; + + $o = opendir($dir) or error("cannot open directory: $dir"); + + while (($name = readdir($o)) !== false) { + + if (is_dir("{$dir}/{$name}") && !in_array($name, array('.', '..', '.svn'))) { + $skip_ext = ($is_ext_dir && !in_array(strtolower($name), $exts_to_test)); + if ($skip_ext) { + $exts_skipped++; + } + find_files("{$dir}/{$name}", false, $ignore || $skip_ext); + } + + // Cleanup any left-over tmp files from last run. + if (substr($name, -4) == '.tmp') { + @unlink("$dir/$name"); + continue; + } + + // Otherwise we're only interested in *.phpt files. + if (substr($name, -5) == '.phpt') { + if ($ignore) { + $ignored_by_ext++; + } else { + $testfile = realpath("{$dir}/{$name}"); + $test_files[] = $testfile; + } + } + } + + closedir($o); +} + +function test_name($name) +{ + if (is_array($name)) { + return $name[0] . ':' . $name[1]; + } else { + return $name; + } +} + +function test_sort($a, $b) +{ + global $cwd; + + $a = test_name($a); + $b = test_name($b); + + $ta = strpos($a, "{$cwd}/tests") === 0 ? 1 + (strpos($a, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0; + $tb = strpos($b, "{$cwd}/tests") === 0 ? 1 + (strpos($b, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0; + + if ($ta == $tb) { + return strcmp($a, $b); + } else { + return $tb - $ta; + } +} + +$test_files = array_unique($test_files); +usort($test_files, "test_sort"); + +$start_time = time(); +show_start($start_time); + +$test_cnt = count($test_files); +$test_idx = 0; +run_all_tests($test_files, $environment); +$end_time = time(); + +if ($failed_tests_file) { + fclose($failed_tests_file); +} + +// Summarize results + +if (0 == count($test_results)) { + echo "No tests were run.\n"; + return; +} + +compute_summary(); + +show_end($end_time); +show_summary(); + +if ($html_output) { + fclose($html_file); +} + +save_or_mail_results(); + +junit_save_xml(); + +if (getenv('REPORT_EXIT_STATUS') == 1 && ($sum_results['FAILED'] || $sum_results['BORKED'])) { + exit(1); +} +exit(0); + +// +// Send Email to QA Team +// + +function mail_qa_team($data, $compression, $status = false) +{ + $url_bits = parse_url(QA_SUBMISSION_PAGE); + + if (($proxy = getenv('http_proxy'))) { + $proxy = parse_url($proxy); + $path = $url_bits['host'].$url_bits['path']; + $host = $proxy['host']; + if (empty($proxy['port'])) { + $proxy['port'] = 80; + } + $port = $proxy['port']; + } else { + $path = $url_bits['path']; + $host = $url_bits['host']; + $port = empty($url_bits['port']) ? 80 : $port = $url_bits['port']; + } + + $data = "php_test_data=" . urlencode(base64_encode(str_replace("\00", '[0x0]', $data))); + $data_length = strlen($data); + + $fs = fsockopen($host, $port, $errno, $errstr, 10); + + if (!$fs) { + return false; + } + + $php_version = urlencode(TESTED_PHP_VERSION); + + echo "\nPosting to ". QA_SUBMISSION_PAGE . "\n"; + fwrite($fs, "POST " . $path . "?status=$status&version=$php_version HTTP/1.1\r\n"); + fwrite($fs, "Host: " . $host . "\r\n"); + fwrite($fs, "User-Agent: QA Browser 0.1\r\n"); + fwrite($fs, "Content-Type: application/x-www-form-urlencoded\r\n"); + fwrite($fs, "Content-Length: " . $data_length . "\r\n\r\n"); + fwrite($fs, $data); + fwrite($fs, "\r\n\r\n"); + fclose($fs); + + return 1; +} + + +// +// Write the given text to a temporary file, and return the filename. +// + +function save_text($filename, $text, $filename_copy = null) +{ + global $DETAILED; + + if ($filename_copy && $filename_copy != $filename) { + if (file_put_contents($filename_copy, $text, FILE_BINARY) === false) { + error("Cannot open file '" . $filename_copy . "' (save_text)"); + } + } + + if (file_put_contents($filename, $text, FILE_BINARY) === false) { + error("Cannot open file '" . $filename . "' (save_text)"); + } + + if (1 < $DETAILED) echo " +FILE $filename {{{ +$text +}}} +"; +} + +// +// Write an error in a format recognizable to Emacs or MSVC. +// + +function error_report($testname, $logname, $tested) +{ + $testname = realpath($testname); + $logname = realpath($logname); + + switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) { + case 'MSVC': + echo $testname . "(1) : $tested\n"; + echo $logname . "(1) : $tested\n"; + break; + case 'EMACS': + echo $testname . ":1: $tested\n"; + echo $logname . ":1: $tested\n"; + break; + } +} + +function system_with_timeout($commandline, $env = null, $stdin = null) +{ + global $leak_check, $cwd; + + $data = ''; + + $bin_env = array(); + foreach((array)$env as $key => $value) { + $bin_env[$key] = $value; + } + + $proc = proc_open($commandline, array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ), $pipes, $cwd, $bin_env, array('suppress_errors' => true, 'binary_pipes' => true)); + + if (!$proc) { + return false; + } + + if (!is_null($stdin)) { + fwrite($pipes[0], $stdin); + } + fclose($pipes[0]); + unset($pipes[0]); + + $timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60); + + while (true) { + /* hide errors from interrupted syscalls */ + $r = $pipes; + $w = null; + $e = null; + + $n = @stream_select($r, $w, $e, $timeout); + + if ($n === false) { + break; + } else if ($n === 0) { + /* timed out */ + $data .= "\n ** ERROR: process timed out **\n"; + proc_terminate($proc, 9); + return $data; + } else if ($n > 0) { + $line = fread($pipes[1], 8192); + if (strlen($line) == 0) { + /* EOF */ + break; + } + $data .= $line; + } + } + + $stat = proc_get_status($proc); + + if ($stat['signaled']) { + $data .= "\nTermsig=" . $stat['stopsig'] . "\n"; + } + if ($stat["exitcode"] > 128 && $stat["exitcode"] < 160) { + $data .= "\nTermsig=" . ($stat["exitcode"] - 128) . "\n"; + } + + $code = proc_close($proc); + return $data; +} + +function run_all_tests($test_files, $env, $redir_tested = null) +{ + global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx; + + foreach($test_files as $name) { + + if (is_array($name)) { + $index = "# $name[1]: $name[0]"; + + if ($redir_tested) { + $name = $name[0]; + } + } else if ($redir_tested) { + $index = "# $redir_tested: $name"; + } else { + $index = $name; + } + $test_idx++; + $result = run_test($php, $name, $env); + + if (!is_array($name) && $result != 'REDIR') { + $test_results[$index] = $result; + if ($failed_tests_file && ($result == 'XFAILED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) { + fwrite($failed_tests_file, "$index\n"); + } + } + } +} + +// +// Show file or result block +// +function show_file_block($file, $block, $section = null) +{ + global $cfg; + + if ($cfg['show'][$file]) { + + if (is_null($section)) { + $section = strtoupper($file); + } + + echo "\n========" . $section . "========\n"; + echo rtrim($block); + echo "\n========DONE========\n"; + } +} + +// +// Run an individual test case. +// +function run_test($php, $file, $env) +{ + global $log_format, $info_params, $ini_overwrites, $cwd, $PHP_FAILED_TESTS; + global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx; + global $leak_check, $temp_source, $temp_target, $cfg, $environment; + global $no_clean; + global $valgrind_version; + global $JUNIT; + global $SHOW_ONLY_GROUPS; + global $no_file_cache; + $temp_filenames = null; + $org_file = $file; + + if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) { + $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE']; + } + + if (isset($env['TEST_PHPDBG_EXECUTABLE'])) { + $phpdbg = $env['TEST_PHPDBG_EXECUTABLE']; + } + + if (is_array($file)) { + $file = $file[0]; + } + + if ($DETAILED) echo " +================= +TEST $file +"; + + // Load the sections of the test file. + $section_text = array('TEST' => ''); + + $fp = fopen($file, "rb") or error("Cannot open test file: $file"); + + $borked = false; + $bork_info = ''; + + if (!feof($fp)) { + $line = fgets($fp); + + if ($line === false) { + $bork_info = "cannot read test"; + $borked = true; + } + } else { + $bork_info = "empty test [$file]"; + $borked = true; + } + if (!$borked && strncmp('--TEST--', $line, 8)) { + $bork_info = "tests must start with --TEST-- [$file]"; + $borked = true; + } + + $section = 'TEST'; + $secfile = false; + $secdone = false; + + while (!feof($fp)) { + $line = fgets($fp); + + if ($line === false) { + break; + } + + // Match the beginning of a section. + if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { + $section = $r[1]; + settype($section, 'string'); + + if (isset($section_text[$section])) { + $bork_info = "duplicated $section section"; + $borked = true; + } + + $section_text[$section] = ''; + $secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL'; + $secdone = false; + continue; + } + + // Add to the section text. + if (!$secdone) { + $section_text[$section] .= $line; + } + + // End of actual test? + if ($secfile && preg_match('/^===DONE===\s*$/', $line)) { + $secdone = true; + } + } + + // the redirect section allows a set of tests to be reused outside of + // a given test dir + if (!$borked) { + if (@count($section_text['REDIRECTTEST']) == 1) { + + if ($IN_REDIRECT) { + $borked = true; + $bork_info = "Can't redirect a test from within a redirected test"; + } else { + $borked = false; + } + + } else { + + if (!isset($section_text['PHPDBG']) && @count($section_text['FILE']) + @count($section_text['FILEEOF']) + @count($section_text['FILE_EXTERNAL']) != 1) { + $bork_info = "missing section --FILE--"; + $borked = true; + } + + if (@count($section_text['FILEEOF']) == 1) { + $section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']); + unset($section_text['FILEEOF']); + } + + foreach (array( 'FILE', 'EXPECT', 'EXPECTF', 'EXPECTREGEX' ) as $prefix) { + $key = $prefix . '_EXTERNAL'; + + if (@count($section_text[$key]) == 1) { + // don't allow tests to retrieve files from anywhere but this subdirectory + $section_text[$key] = dirname($file) . '/' . trim(str_replace('..', '', $section_text[$key])); + + if (file_exists($section_text[$key])) { + $section_text[$prefix] = file_get_contents($section_text[$key], FILE_BINARY); + unset($section_text[$key]); + } else { + $bork_info = "could not load --" . $key . "-- " . dirname($file) . '/' . trim($section_text[$key]); + $borked = true; + } + } + } + + if ((@count($section_text['EXPECT']) + @count($section_text['EXPECTF']) + @count($section_text['EXPECTREGEX'])) != 1) { + $bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--"; + $borked = true; + } + } + } + fclose($fp); + + $shortname = str_replace($cwd . '/', '', $file); + $tested_file = $shortname; + + if ($borked) { + show_result("BORK", $bork_info, $tested_file); + $PHP_FAILED_TESTS['BORKED'][] = array ( + 'name' => $file, + 'test_name' => '', + 'output' => '', + 'diff' => '', + 'info' => "$bork_info [$file]", + ); + + junit_mark_test_as('BORK', $shortname, $tested_file, 0, $bork_info); + return 'BORKED'; + } + + $tested = trim($section_text['TEST']); + + /* For GET/POST/PUT tests, check if cgi sapi is available and if it is, use it. */ + if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['GZIP_POST']) || !empty($section_text['DEFLATE_POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['PUT']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { + if (isset($php_cgi)) { + $old_php = $php; + $php = $php_cgi . ' -C '; + } else if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/php-cgi.exe")) { + $old_php = $php; + $php = realpath(dirname($php) . "/php-cgi.exe") . ' -C '; + } else { + if (file_exists(dirname($php) . "/../../sapi/cgi/php-cgi")) { + $old_php = $php; + $php = realpath(dirname($php) . "/../../sapi/cgi/php-cgi") . ' -C '; + } else if (file_exists("./sapi/cgi/php-cgi")) { + $old_php = $php; + $php = realpath("./sapi/cgi/php-cgi") . ' -C '; + } else if (file_exists(dirname($php) . "/php-cgi")) { + $old_php = $php; + $php = realpath(dirname($php) . "/php-cgi") . ' -C '; + } else { + show_result('SKIP', $tested, $tested_file, "reason: CGI not available"); + + junit_init_suite(junit_get_suitename_for($shortname)); + junit_mark_test_as('SKIP', $shortname, $tested, 0, 'CGI not available'); + return 'SKIPPED'; + } + } + $uses_cgi = true; + } + + /* For phpdbg tests, check if phpdbg sapi is available and if it is, use it. */ + if (array_key_exists('PHPDBG', $section_text)) { + if (!isset($section_text['STDIN'])) { + $section_text['STDIN'] = $section_text['PHPDBG']."\n"; + } + + if (isset($phpdbg)) { + $old_php = $php; + $php = $phpdbg . ' -qIb'; + } else { + show_result('SKIP', $tested, $tested_file, "reason: phpdbg not available"); + + junit_init_suite(junit_get_suitename_for($shortname)); + junit_mark_test_as('SKIP', $shortname, $tested, 0, 'phpdbg not available'); + return 'SKIPPED'; + } + } + + if (!$SHOW_ONLY_GROUPS) { + show_test($test_idx, $shortname); + } + + if (is_array($IN_REDIRECT)) { + $temp_dir = $test_dir = $IN_REDIRECT['dir']; + } else { + $temp_dir = $test_dir = realpath(dirname($file)); + } + + if ($temp_source && $temp_target) { + $temp_dir = str_replace($temp_source, $temp_target, $temp_dir); + } + + $main_file_name = basename($file,'phpt'); + + $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'diff'; + $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'log'; + $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'exp'; + $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'out'; + $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'mem'; + $sh_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'sh'; + $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php'; + $test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php'; + $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php'; + $test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php'; + $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php'; + $test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php'; + $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('/phpt.'); + $tmp_relative_file = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $test_file) . 't'; + + if ($temp_source && $temp_target) { + $temp_skipif .= 's'; + $temp_file .= 's'; + $temp_clean .= 's'; + $copy_file = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file) . '.phps'; + + if (!is_dir(dirname($copy_file))) { + mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file)); + } + + if (isset($section_text['FILE'])) { + save_text($copy_file, $section_text['FILE']); + } + + $temp_filenames = array( + 'file' => $copy_file, + 'diff' => $diff_filename, + 'log' => $log_filename, + 'exp' => $exp_filename, + 'out' => $output_filename, + 'mem' => $memcheck_filename, + 'sh' => $sh_filename, + 'php' => $temp_file, + 'skip' => $temp_skipif, + 'clean'=> $temp_clean); + } + + if (is_array($IN_REDIRECT)) { + $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']); + $tested_file = $tmp_relative_file; + } + + // unlink old test results + @unlink($diff_filename); + @unlink($log_filename); + @unlink($exp_filename); + @unlink($output_filename); + @unlink($memcheck_filename); + @unlink($sh_filename); + @unlink($temp_file); + @unlink($test_file); + @unlink($temp_skipif); + @unlink($test_skipif); + @unlink($tmp_post); + @unlink($temp_clean); + @unlink($test_clean); + + // Reset environment from any previous test. + $env['REDIRECT_STATUS'] = ''; + $env['QUERY_STRING'] = ''; + $env['PATH_TRANSLATED'] = ''; + $env['SCRIPT_FILENAME'] = ''; + $env['REQUEST_METHOD'] = ''; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + $env['TZ'] = ''; + + if (!empty($section_text['ENV'])) { + + foreach(explode("\n", trim($section_text['ENV'])) as $e) { + $e = explode('=', trim($e), 2); + + if (!empty($e[0]) && isset($e[1])) { + $env[$e[0]] = $e[1]; + } + } + } + + // Default ini settings + $ini_settings = array(); + + // Additional required extensions + if (array_key_exists('EXTENSIONS', $section_text)) { + $ext_dir=`$php -r 'echo ini_get("extension_dir");'`; + $extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS'])); + $loaded = explode(",", `$php -n -r 'echo join(",", get_loaded_extensions());'`); + foreach ($extensions as $req_ext) { + if (!in_array($req_ext, $loaded)) { + if ($req_ext == 'opcache') { + $ini_settings['zend_extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $req_ext . '.' . PHP_SHLIB_SUFFIX; + } else { + $ini_settings['extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $req_ext . '.' . PHP_SHLIB_SUFFIX; + } + } + } + } + + // additional ini overwrites + //$ini_overwrites[] = 'setting=value'; + settings2array($ini_overwrites, $ini_settings); + + // Any special ini settings + // these may overwrite the test defaults... + if (array_key_exists('INI', $section_text)) { + if (strpos($section_text['INI'], '{PWD}') !== false) { + $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); + } + settings2array(preg_split( "/[\n\r]+/", $section_text['INI']), $ini_settings); + } + + settings2params($ini_settings); + + // Check if test should be skipped. + $info = ''; + $warn = false; + + if (array_key_exists('SKIPIF', $section_text)) { + + if (trim($section_text['SKIPIF'])) { + show_file_block('skip', $section_text['SKIPIF']); + save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif); + $extra = substr(PHP_OS, 0, 3) !== "WIN" ? + "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": ""; + + if ($leak_check) { + $env['USE_ZEND_ALLOC'] = '0'; + $env['ZEND_DONT_UNLOAD_MODULES'] = 1; + } else { + $env['USE_ZEND_ALLOC'] = '1'; + $env['ZEND_DONT_UNLOAD_MODULES'] = 0; + } + + junit_start_timer($shortname); + + $output = system_with_timeout("$extra $php $pass_options -q $ini_settings $no_file_cache -d display_errors=0 \"$test_skipif\"", $env); + + junit_finish_timer($shortname); + + if (!$cfg['keep']['skip']) { + @unlink($test_skipif); + } + + if (!strncasecmp('skip', ltrim($output), 4)) { + + if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { + show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames); + } else { + show_result('SKIP', $tested, $tested_file, '', $temp_filenames); + } + + if (isset($old_php)) { + $php = $old_php; + } + + if (!$cfg['keep']['skip']) { + @unlink($test_skipif); + } + + $message = !empty($m[1]) ? $m[1] : ''; + junit_mark_test_as('SKIP', $shortname, $tested, null, $message); + return 'SKIPPED'; + } + + if (!strncasecmp('info', ltrim($output), 4)) { + if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { + $info = " (info: $m[1])"; + } + } + + if (!strncasecmp('warn', ltrim($output), 4)) { + if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { + $warn = true; /* only if there is a reason */ + $info = " (warn: $m[1])"; + } + } + + if (!strncasecmp('xfail', ltrim($output), 5)) { + // Pretend we have an XFAIL section + $section_text['XFAIL'] = trim(substr(ltrim($output), 5)); + } + } + } + + if (!extension_loaded("zlib") + && ( array_key_exists("GZIP_POST", $section_text) + || array_key_exists("DEFLATE_POST", $section_text)) + ) { + $message = "ext/zlib required"; + show_result('SKIP', $tested, $tested_file, "reason: $message", $temp_filenames); + junit_mark_test_as('SKIP', $shortname, $tested, null, $message); + return 'SKIPPED'; + } + + if (@count($section_text['REDIRECTTEST']) == 1) { + $test_files = array(); + + $IN_REDIRECT = eval($section_text['REDIRECTTEST']); + $IN_REDIRECT['via'] = "via [$shortname]\n\t"; + $IN_REDIRECT['dir'] = realpath(dirname($file)); + $IN_REDIRECT['prefix'] = trim($section_text['TEST']); + + if (count($IN_REDIRECT['TESTS']) == 1) { + + if (is_array($org_file)) { + $test_files[] = $org_file[1]; + } else { + $GLOBALS['test_files'] = $test_files; + find_files($IN_REDIRECT['TESTS']); + + foreach($GLOBALS['test_files'] as $f) { + $test_files[] = array($f, $file); + } + } + $test_cnt += @count($test_files) - 1; + $test_idx--; + + show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file); + + // set up environment + $redirenv = array_merge($environment, $IN_REDIRECT['ENV']); + $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR; + + usort($test_files, "test_sort"); + run_all_tests($test_files, $redirenv, $tested); + + show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file); + + // a redirected test never fails + $IN_REDIRECT = false; + + junit_mark_test_as('PASS', $shortname, $tested); + return 'REDIR'; + + } else { + + $bork_info = "Redirect info must contain exactly one TEST string to be used as redirect directory."; + show_result("BORK", $bork_info, '', $temp_filenames); + $PHP_FAILED_TESTS['BORKED'][] = array ( + 'name' => $file, + 'test_name' => '', + 'output' => '', + 'diff' => '', + 'info' => "$bork_info [$file]", + ); + } + } + + if (is_array($org_file) || @count($section_text['REDIRECTTEST']) == 1) { + + if (is_array($org_file)) { + $file = $org_file[0]; + } + + $bork_info = "Redirected test did not contain redirection info"; + show_result("BORK", $bork_info, '', $temp_filenames); + $PHP_FAILED_TESTS['BORKED'][] = array ( + 'name' => $file, + 'test_name' => '', + 'output' => '', + 'diff' => '', + 'info' => "$bork_info [$file]", + ); + + junit_mark_test_as('BORK', $shortname, $tested, null, $bork_info); + + return 'BORKED'; + } + + // We've satisfied the preconditions - run the test! + if (isset($section_text['FILE'])) { + show_file_block('php', $section_text['FILE'], 'TEST'); + save_text($test_file, $section_text['FILE'], $temp_file); + } else { + $test_file = $temp_file = ""; + } + + if (array_key_exists('GET', $section_text)) { + $query_string = trim($section_text['GET']); + } else { + $query_string = ''; + } + + $env['REDIRECT_STATUS'] = '1'; + if (empty($env['QUERY_STRING'])) { + $env['QUERY_STRING'] = $query_string; + } + if (empty($env['PATH_TRANSLATED'])) { + $env['PATH_TRANSLATED'] = $test_file; + } + if (empty($env['SCRIPT_FILENAME'])) { + $env['SCRIPT_FILENAME'] = $test_file; + } + + if (array_key_exists('COOKIE', $section_text)) { + $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); + } else { + $env['HTTP_COOKIE'] = ''; + } + + $args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : ''; + + if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { + + $post = trim($section_text['POST_RAW']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + + foreach ($raw_lines as $line) { + + if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + + if ($started) { + $request .= "\n"; + } + + $started = true; + $request .= $line; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'POST'; + + if (empty($request)) { + junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request'); + return 'BORKED'; + } + + save_text($tmp_post, $request); + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } elseif (array_key_exists('PUT', $section_text) && !empty($section_text['PUT'])) { + + $post = trim($section_text['PUT']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + + foreach ($raw_lines as $line) { + + if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + + if ($started) { + $request .= "\n"; + } + + $started = true; + $request .= $line; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'PUT'; + + if (empty($request)) { + junit_mark_test_as('BORK', $shortname, $tested, null, 'empty $request'); + return 'BORKED'; + } + + save_text($tmp_post, $request); + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { + + $post = trim($section_text['POST']); + $content_length = strlen($post); + save_text($tmp_post, $post); + + $env['REQUEST_METHOD'] = 'POST'; + if (empty($env['CONTENT_TYPE'])) { + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + } + + if (empty($env['CONTENT_LENGTH'])) { + $env['CONTENT_LENGTH'] = $content_length; + } + + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } else if (array_key_exists('GZIP_POST', $section_text) && !empty($section_text['GZIP_POST'])) { + + $post = trim($section_text['GZIP_POST']); + $post = gzencode($post, 9, FORCE_GZIP); + $env['HTTP_CONTENT_ENCODING'] = 'gzip'; + + save_text($tmp_post, $post); + $content_length = strlen($post); + + $env['REQUEST_METHOD'] = 'POST'; + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + $env['CONTENT_LENGTH'] = $content_length; + + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } else if (array_key_exists('DEFLATE_POST', $section_text) && !empty($section_text['DEFLATE_POST'])) { + $post = trim($section_text['DEFLATE_POST']); + $post = gzcompress($post, 9); + $env['HTTP_CONTENT_ENCODING'] = 'deflate'; + save_text($tmp_post, $post); + $content_length = strlen($post); + + $env['REQUEST_METHOD'] = 'POST'; + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + $env['CONTENT_LENGTH'] = $content_length; + + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < \"$tmp_post\""; + + } else { + + $env['REQUEST_METHOD'] = 'GET'; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + + $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args 2>&1"; + } + + if ($leak_check) { + $env['USE_ZEND_ALLOC'] = '0'; + $env['ZEND_DONT_UNLOAD_MODULES'] = 1; + + /* --vex-iropt-register-updates=allregs-at-mem-access is necessary for phpdbg watchpoint tests */ + if (version_compare($valgrind_version, '3.8.0', '>=')) { + /* valgrind 3.3.0+ doesn't have --log-file-exactly option */ + $cmd = "valgrind -q --tool=memcheck --trace-children=yes --vex-iropt-register-updates=allregs-at-mem-access --log-file=$memcheck_filename $cmd"; + } elseif (version_compare($valgrind_version, '3.3.0', '>=')) { + $cmd = "valgrind -q --tool=memcheck --trace-children=yes --vex-iropt-precise-memory-exns=yes --log-file=$memcheck_filename $cmd"; + } else { + $cmd = "valgrind -q --tool=memcheck --trace-children=yes --vex-iropt-precise-memory-exns=yes --log-file-exactly=$memcheck_filename $cmd"; + } + + } else { + $env['USE_ZEND_ALLOC'] = '1'; + $env['ZEND_DONT_UNLOAD_MODULES'] = 0; + } + + if ($DETAILED) echo " +CONTENT_LENGTH = " . $env['CONTENT_LENGTH'] . " +CONTENT_TYPE = " . $env['CONTENT_TYPE'] . " +PATH_TRANSLATED = " . $env['PATH_TRANSLATED'] . " +QUERY_STRING = " . $env['QUERY_STRING'] . " +REDIRECT_STATUS = " . $env['REDIRECT_STATUS'] . " +REQUEST_METHOD = " . $env['REQUEST_METHOD'] . " +SCRIPT_FILENAME = " . $env['SCRIPT_FILENAME'] . " +HTTP_COOKIE = " . $env['HTTP_COOKIE'] . " +COMMAND $cmd +"; + + junit_start_timer($shortname); + + $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null); + + junit_finish_timer($shortname); + + if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) { + + if (trim($section_text['CLEAN'])) { + show_file_block('clean', $section_text['CLEAN']); + save_text($test_clean, trim($section_text['CLEAN']), $temp_clean); + + if (!$no_clean) { + $clean_params = array(); + settings2array($ini_overwrites, $clean_params); + settings2params($clean_params); + $extra = substr(PHP_OS, 0, 3) !== "WIN" ? + "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": ""; + system_with_timeout("$extra $php $pass_options -q $clean_params $no_file_cache \"$test_clean\"", $env); + } + + if (!$cfg['keep']['clean']) { + @unlink($test_clean); + } + } + } + + @unlink($tmp_post); + + $leaked = false; + $passed = false; + + if ($leak_check) { // leak check + $leaked = filesize($memcheck_filename) > 0; + + if (!$leaked) { + @unlink($memcheck_filename); + } + } + + // Does the output match what is expected? + $output = preg_replace("/\r\n/", "\n", trim($out)); + + /* when using CGI, strip the headers from the output */ + $headers = ""; + + if (!empty($uses_cgi) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) { + $output = trim($match[2]); + $rh = preg_split("/[\n\r]+/", $match[1]); + $headers = array(); + + foreach ($rh as $line) { + if (strpos($line, ':') !== false) { + $line = explode(':', $line, 2); + $headers[trim($line[0])] = trim($line[1]); + } + } + } + + $failed_headers = false; + + if (isset($section_text['EXPECTHEADERS'])) { + $want = array(); + $wanted_headers = array(); + $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']); + + foreach($lines as $line) { + if (strpos($line, ':') !== false) { + $line = explode(':', $line, 2); + $want[trim($line[0])] = trim($line[1]); + $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]); + } + } + + $org_headers = $headers; + $headers = array(); + $output_headers = array(); + + foreach($want as $k => $v) { + + if (isset($org_headers[$k])) { + $headers = $org_headers[$k]; + $output_headers[] = $k . ': ' . $org_headers[$k]; + } + + if (!isset($org_headers[$k]) || $org_headers[$k] != $v) { + $failed_headers = true; + } + } + + ksort($wanted_headers); + $wanted_headers = join("\n", $wanted_headers); + ksort($output_headers); + $output_headers = join("\n", $output_headers); + } + + show_file_block('out', $output); + + if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { + + if (isset($section_text['EXPECTF'])) { + $wanted = trim($section_text['EXPECTF']); + } else { + $wanted = trim($section_text['EXPECTREGEX']); + } + + show_file_block('exp', $wanted); + $wanted_re = preg_replace('/\r\n/', "\n", $wanted); + + if (isset($section_text['EXPECTF'])) { + + // do preg_quote, but miss out any %r delimited sections + $temp = ""; + $r = "%r"; + $startOffset = 0; + $length = strlen($wanted_re); + while($startOffset < $length) { + $start = strpos($wanted_re, $r, $startOffset); + if ($start !== false) { + // we have found a start tag + $end = strpos($wanted_re, $r, $start+2); + if ($end === false) { + // unbalanced tag, ignore it. + $end = $start = $length; + } + } else { + // no more %r sections + $start = $end = $length; + } + // quote a non re portion of the string + $temp = $temp . preg_quote(substr($wanted_re, $startOffset, ($start - $startOffset)), '/'); + // add the re unquoted. + if ($end > $start) { + $temp = $temp . '(' . substr($wanted_re, $start+2, ($end - $start-2)). ')'; + } + $startOffset = $end + 2; + } + $wanted_re = $temp; + + $wanted_re = str_replace( + array('%binary_string_optional%'), + 'string', + $wanted_re + ); + $wanted_re = str_replace( + array('%unicode_string_optional%'), + 'string', + $wanted_re + ); + $wanted_re = str_replace( + array('%unicode\|string%', '%string\|unicode%'), + 'string', + $wanted_re + ); + $wanted_re = str_replace( + array('%u\|b%', '%b\|u%'), + '', + $wanted_re + ); + // Stick to basics + $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re); + $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re); + $wanted_re = str_replace('%S', '[^\r\n]*', $wanted_re); + $wanted_re = str_replace('%a', '.+', $wanted_re); + $wanted_re = str_replace('%A', '.*', $wanted_re); + $wanted_re = str_replace('%w', '\s*', $wanted_re); + $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re); + $wanted_re = str_replace('%d', '\d+', $wanted_re); + $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re); + $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re); + $wanted_re = str_replace('%c', '.', $wanted_re); + // %f allows two points "-.0.0" but that is the best *simple* expression + } +/* DEBUG YOUR REGEX HERE + var_dump($wanted_re); + print(str_repeat('=', 80) . "\n"); + var_dump($output); +*/ + if (preg_match("/^$wanted_re\$/s", $output)) { + $passed = true; + if (!$cfg['keep']['php']) { + @unlink($test_file); + } + if (isset($old_php)) { + $php = $old_php; + } + + if (!$leaked && !$failed_headers) { + if (isset($section_text['XFAIL'] )) { + $warn = true; + $info = " (warn: XFAIL section but test passes)"; + }else { + show_result("PASS", $tested, $tested_file, '', $temp_filenames); + junit_mark_test_as('PASS', $shortname, $tested); + return 'PASSED'; + } + } + } + + } else { + + $wanted = trim($section_text['EXPECT']); + $wanted = preg_replace('/\r\n/',"\n", $wanted); + show_file_block('exp', $wanted); + + // compare and leave on success + if (!strcmp($output, $wanted)) { + $passed = true; + + if (!$cfg['keep']['php']) { + @unlink($test_file); + } + + if (isset($old_php)) { + $php = $old_php; + } + + if (!$leaked && !$failed_headers) { + if (isset($section_text['XFAIL'] )) { + $warn = true; + $info = " (warn: XFAIL section but test passes)"; + }else { + show_result("PASS", $tested, $tested_file, '', $temp_filenames); + junit_mark_test_as('PASS', $shortname, $tested); + return 'PASSED'; + } + } + } + + $wanted_re = null; + } + + // Test failed so we need to report details. + if ($failed_headers) { + $passed = false; + $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted; + $output = $output_headers . "\n--HEADERS--\n" . $output; + + if (isset($wanted_re)) { + $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re; + } + } + + if ($leaked) { + $restype[] = 'LEAK'; + } + + if ($warn) { + $restype[] = 'WARN'; + } + + if (!$passed) { + if (isset($section_text['XFAIL'])) { + $restype[] = 'XFAIL'; + $info = ' XFAIL REASON: ' . rtrim($section_text['XFAIL']); + } else { + $restype[] = 'FAIL'; + } + } + + if (!$passed) { + + // write .exp + if (strpos($log_format, 'E') !== false && file_put_contents($exp_filename, $wanted, FILE_BINARY) === false) { + error("Cannot create expected test output - $exp_filename"); + } + + // write .out + if (strpos($log_format, 'O') !== false && file_put_contents($output_filename, $output, FILE_BINARY) === false) { + error("Cannot create test output - $output_filename"); + } + + // write .diff + $diff = generate_diff($wanted, $wanted_re, $output); + if (is_array($IN_REDIRECT)) { + $diff = "# original source file: $shortname\n" . $diff; + } + show_file_block('diff', $diff); + if (strpos($log_format, 'D') !== false && file_put_contents($diff_filename, $diff, FILE_BINARY) === false) { + error("Cannot create test diff - $diff_filename"); + } + + // write .sh + if (strpos($log_format, 'S') !== false && file_put_contents($sh_filename, "#!/bin/sh + +{$cmd} +", FILE_BINARY) === false) { + error("Cannot create test shell script - $sh_filename"); + } + chmod($sh_filename, 0755); + + // write .log + if (strpos($log_format, 'L') !== false && file_put_contents($log_filename, " +---- EXPECTED OUTPUT +$wanted +---- ACTUAL OUTPUT +$output +---- FAILED +", FILE_BINARY) === false) { + error("Cannot create test log - $log_filename"); + error_report($file, $log_filename, $tested); + } + } + + show_result(implode('&', $restype), $tested, $tested_file, $info, $temp_filenames); + + foreach ($restype as $type) { + $PHP_FAILED_TESTS[$type.'ED'][] = array ( + 'name' => $file, + 'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]", + 'output' => $output_filename, + 'diff' => $diff_filename, + 'info' => $info, + ); + } + + if (isset($old_php)) { + $php = $old_php; + } + + $diff = empty($diff) ? '' : preg_replace('/\e/', '<esc>', $diff); + + junit_mark_test_as($restype, str_replace($cwd . '/', '', $tested_file), $tested, null, $info, $diff); + + return $restype[0] . 'ED'; +} + +function comp_line($l1, $l2, $is_reg) +{ + if ($is_reg) { + return preg_match('/^'. $l1 . '$/s', $l2); + } else { + return !strcmp($l1, $l2); + } +} + +function count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2, $cnt1, $cnt2, $steps) +{ + $equal = 0; + + while ($idx1 < $cnt1 && $idx2 < $cnt2 && comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) { + $idx1++; + $idx2++; + $equal++; + $steps--; + } + if (--$steps > 0) { + $eq1 = 0; + $st = $steps / 2; + + for ($ofs1 = $idx1 + 1; $ofs1 < $cnt1 && $st-- > 0; $ofs1++) { + $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $ofs1, $idx2, $cnt1, $cnt2, $st); + + if ($eq > $eq1) { + $eq1 = $eq; + } + } + + $eq2 = 0; + $st = $steps; + + for ($ofs2 = $idx2 + 1; $ofs2 < $cnt2 && $st-- > 0; $ofs2++) { + $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $ofs2, $cnt1, $cnt2, $st); + if ($eq > $eq2) { + $eq2 = $eq; + } + } + + if ($eq1 > $eq2) { + $equal += $eq1; + } else if ($eq2 > 0) { + $equal += $eq2; + } + } + + return $equal; +} + +function generate_array_diff($ar1, $ar2, $is_reg, $w) +{ + $idx1 = 0; $ofs1 = 0; $cnt1 = @count($ar1); + $idx2 = 0; $ofs2 = 0; $cnt2 = @count($ar2); + $diff = array(); + $old1 = array(); + $old2 = array(); + + while ($idx1 < $cnt1 && $idx2 < $cnt2) { + + if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) { + $idx1++; + $idx2++; + continue; + } else { + + $c1 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1+1, $idx2, $cnt1, $cnt2, 10); + $c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2+1, $cnt1, $cnt2, 10); + + if ($c1 > $c2) { + $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++]; + $last = 1; + } else if ($c2 > 0) { + $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; + $last = 2; + } else { + $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++]; + $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++]; + } + } + } + + reset($old1); $k1 = key($old1); $l1 = -2; + reset($old2); $k2 = key($old2); $l2 = -2; + + while ($k1 !== null || $k2 !== null) { + + if ($k1 == $l1 + 1 || $k2 === null) { + $l1 = $k1; + $diff[] = current($old1); + $k1 = next($old1) ? key($old1) : null; + } else if ($k2 == $l2 + 1 || $k1 === null) { + $l2 = $k2; + $diff[] = current($old2); + $k2 = next($old2) ? key($old2) : null; + } else if ($k1 < $k2) { + $l1 = $k1; + $diff[] = current($old1); + $k1 = next($old1) ? key($old1) : null; + } else { + $l2 = $k2; + $diff[] = current($old2); + $k2 = next($old2) ? key($old2) : null; + } + } + + while ($idx1 < $cnt1) { + $diff[] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++]; + } + + while ($idx2 < $cnt2) { + $diff[] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++]; + } + + return $diff; +} + +function generate_diff($wanted, $wanted_re, $output) +{ + $w = explode("\n", $wanted); + $o = explode("\n", $output); + $r = is_null($wanted_re) ? $w : explode("\n", $wanted_re); + $diff = generate_array_diff($r, $o, !is_null($wanted_re), $w); + + return implode("\r\n", $diff); +} + +function error($message) +{ + echo "ERROR: {$message}\n"; + exit(1); +} + +function settings2array($settings, &$ini_settings) +{ + foreach($settings as $setting) { + + if (strpos($setting, '=') !== false) { + $setting = explode("=", $setting, 2); + $name = trim($setting[0]); + $value = trim($setting[1]); + + if ($name == 'extension' || $name == 'zend_extension') { + + if (!isset($ini_settings[$name])) { + $ini_settings[$name] = array(); + } + + $ini_settings[$name][] = $value; + + } else { + $ini_settings[$name] = $value; + } + } + } +} + +function settings2params(&$ini_settings) +{ + $settings = ''; + + foreach($ini_settings as $name => $value) { + + if (is_array($value)) { + foreach($value as $val) { + $val = addslashes($val); + $settings .= " -d \"$name=$val\""; + } + } else { + if (substr(PHP_OS, 0, 3) == "WIN" && !empty($value) && $value{0} == '"') { + $len = strlen($value); + + if ($value{$len - 1} == '"') { + $value{0} = "'"; + $value{$len - 1} = "'"; + } + } else { + $value = addslashes($value); + } + + $settings .= " -d \"$name=$value\""; + } + } + + $ini_settings = $settings; +} + +function compute_summary() +{ + global $n_total, $test_results, $ignored_by_ext, $sum_results, $percent_results; + + $n_total = count($test_results); + $n_total += $ignored_by_ext; + $sum_results = array( + 'PASSED' => 0, + 'WARNED' => 0, + 'SKIPPED' => 0, + 'FAILED' => 0, + 'BORKED' => 0, + 'LEAKED' => 0, + 'XFAILED' => 0 + ); + + foreach ($test_results as $v) { + $sum_results[$v]++; + } + + $sum_results['SKIPPED'] += $ignored_by_ext; + $percent_results = array(); + + foreach($sum_results as $v => $n) { + $percent_results[$v] = (100.0 * $n) / $n_total; + } +} + +function get_summary($show_ext_summary, $show_html) +{ + global $exts_skipped, $exts_tested, $n_total, $sum_results, $percent_results, $end_time, $start_time, $failed_test_summary, $PHP_FAILED_TESTS, $leak_check; + + $x_total = $n_total - $sum_results['SKIPPED'] - $sum_results['BORKED']; + + if ($x_total) { + $x_warned = (100.0 * $sum_results['WARNED']) / $x_total; + $x_failed = (100.0 * $sum_results['FAILED']) / $x_total; + $x_xfailed = (100.0 * $sum_results['XFAILED']) / $x_total; + $x_leaked = (100.0 * $sum_results['LEAKED']) / $x_total; + $x_passed = (100.0 * $sum_results['PASSED']) / $x_total; + } else { + $x_warned = $x_failed = $x_passed = $x_leaked = $x_xfailed = 0; + } + + $summary = ''; + + if ($show_html) { + $summary .= "<pre>\n"; + } + + if ($show_ext_summary) { + $summary .= ' +===================================================================== +TEST RESULT SUMMARY +--------------------------------------------------------------------- +Exts skipped : ' . sprintf('%4d', $exts_skipped) . ' +Exts tested : ' . sprintf('%4d', $exts_tested) . ' +--------------------------------------------------------------------- +'; + } + + $summary .= ' +Number of tests : ' . sprintf('%4d', $n_total) . ' ' . sprintf('%8d', $x_total); + + if ($sum_results['BORKED']) { + $summary .= ' +Tests borked : ' . sprintf('%4d (%5.1f%%)', $sum_results['BORKED'], $percent_results['BORKED']) . ' --------'; + } + + $summary .= ' +Tests skipped : ' . sprintf('%4d (%5.1f%%)', $sum_results['SKIPPED'], $percent_results['SKIPPED']) . ' -------- +Tests warned : ' . sprintf('%4d (%5.1f%%)', $sum_results['WARNED'], $percent_results['WARNED']) . ' ' . sprintf('(%5.1f%%)', $x_warned) . ' +Tests failed : ' . sprintf('%4d (%5.1f%%)', $sum_results['FAILED'], $percent_results['FAILED']) . ' ' . sprintf('(%5.1f%%)', $x_failed) . ' +Expected fail : ' . sprintf('%4d (%5.1f%%)', $sum_results['XFAILED'], $percent_results['XFAILED']) . ' ' . sprintf('(%5.1f%%)', $x_xfailed); + + if ($leak_check) { + $summary .= ' +Tests leaked : ' . sprintf('%4d (%5.1f%%)', $sum_results['LEAKED'], $percent_results['LEAKED']) . ' ' . sprintf('(%5.1f%%)', $x_leaked); + } + + $summary .= ' +Tests passed : ' . sprintf('%4d (%5.1f%%)', $sum_results['PASSED'], $percent_results['PASSED']) . ' ' . sprintf('(%5.1f%%)', $x_passed) . ' +--------------------------------------------------------------------- +Time taken : ' . sprintf('%4d seconds', $end_time - $start_time) . ' +===================================================================== +'; + $failed_test_summary = ''; + + if (count($PHP_FAILED_TESTS['XFAILED'])) { + $failed_test_summary .= ' +===================================================================== +EXPECTED FAILED TEST SUMMARY +--------------------------------------------------------------------- +'; + foreach ($PHP_FAILED_TESTS['XFAILED'] as $failed_test_data) { + $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n"; + } + $failed_test_summary .= "=====================================================================\n"; + } + + if (count($PHP_FAILED_TESTS['BORKED'])) { + $failed_test_summary .= ' +===================================================================== +BORKED TEST SUMMARY +--------------------------------------------------------------------- +'; + foreach ($PHP_FAILED_TESTS['BORKED'] as $failed_test_data) { + $failed_test_summary .= $failed_test_data['info'] . "\n"; + } + + $failed_test_summary .= "=====================================================================\n"; + } + + if (count($PHP_FAILED_TESTS['FAILED'])) { + $failed_test_summary .= ' +===================================================================== +FAILED TEST SUMMARY +--------------------------------------------------------------------- +'; + foreach ($PHP_FAILED_TESTS['FAILED'] as $failed_test_data) { + $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n"; + } + $failed_test_summary .= "=====================================================================\n"; + } + if (count($PHP_FAILED_TESTS['WARNED'])) { + $failed_test_summary .= ' +===================================================================== +WARNED TEST SUMMARY +--------------------------------------------------------------------- +'; + foreach ($PHP_FAILED_TESTS['WARNED'] as $failed_test_data) { + $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n"; + } + + $failed_test_summary .= "=====================================================================\n"; + } + + if (count($PHP_FAILED_TESTS['LEAKED'])) { + $failed_test_summary .= ' +===================================================================== +LEAKED TEST SUMMARY +--------------------------------------------------------------------- +'; + foreach ($PHP_FAILED_TESTS['LEAKED'] as $failed_test_data) { + $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n"; + } + + $failed_test_summary .= "=====================================================================\n"; + } + + if ($failed_test_summary && !getenv('NO_PHPTEST_SUMMARY')) { + $summary .= $failed_test_summary; + } + + if ($show_html) { + $summary .= "</pre>"; + } + + return $summary; +} + +function show_start($start_time) +{ + global $html_output, $html_file; + + if ($html_output) { + fwrite($html_file, "<h2>Time Start: " . date('Y-m-d H:i:s', $start_time) . "</h2>\n"); + fwrite($html_file, "<table>\n"); + } + + echo "TIME START " . date('Y-m-d H:i:s', $start_time) . "\n=====================================================================\n"; +} + +function show_end($end_time) +{ + global $html_output, $html_file; + + if ($html_output) { + fwrite($html_file, "</table>\n"); + fwrite($html_file, "<h2>Time End: " . date('Y-m-d H:i:s', $end_time) . "</h2>\n"); + } + + echo "=====================================================================\nTIME END " . date('Y-m-d H:i:s', $end_time) . "\n"; +} + +function show_summary() +{ + global $html_output, $html_file; + + if ($html_output) { + fwrite($html_file, "<hr/>\n" . get_summary(true, true)); + } + + echo get_summary(true, false); +} + +function show_redirect_start($tests, $tested, $tested_file) +{ + global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS; + + if ($html_output) { + fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) begin</td></tr>\n"); + } + + if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) { + echo "REDIRECT $tests ($tested [$tested_file]) begin\n"; + } else { + // Write over the last line to avoid random trailing chars on next echo + echo str_repeat(" ", $line_length), "\r"; + } +} + +function show_redirect_ends($tests, $tested, $tested_file) +{ + global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS; + + if ($html_output) { + fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) done</td></tr>\n"); + } + + if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) { + echo "REDIRECT $tests ($tested [$tested_file]) done\n"; + } else { + // Write over the last line to avoid random trailing chars on next echo + echo str_repeat(" ", $line_length), "\r"; + } +} + +function show_test($test_idx, $shortname) +{ + global $test_cnt; + global $line_length; + + $str = "TEST $test_idx/$test_cnt [$shortname]\r"; + $line_length = strlen($str); + echo $str; + flush(); +} + +function show_result($result, $tested, $tested_file, $extra = '', $temp_filenames = null) +{ + global $html_output, $html_file, $temp_target, $temp_urlbase, $line_length, $SHOW_ONLY_GROUPS; + + //color + if ($result == 'FAIL') { + $result = "\033[31m[$result]\033[0m"; + } elseif($result == 'SKIP') { + $result = "\033[33m[$result]\033[0m"; + } elseif($result == 'BORK') { + $result = "\033[35m[$result]\033[0m"; + } else { + $result = "\033[32m[$result]\033[0m"; + } + + if (!$SHOW_ONLY_GROUPS || in_array($result, $SHOW_ONLY_GROUPS)) { + echo "$result $tested [$tested_file] $extra\n"; + } else if (!$SHOW_ONLY_GROUPS) { + // Write over the last line to avoid random trailing chars on next echo + echo str_repeat(" ", $line_length), "\r"; + } + + if ($html_output) { + + if (isset($temp_filenames['file']) && file_exists($temp_filenames['file'])) { + $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['file']); + $tested = "<a href='$url'>$tested</a>"; + } + + if (isset($temp_filenames['skip']) && file_exists($temp_filenames['skip'])) { + + if (empty($extra)) { + $extra = "skipif"; + } + + $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['skip']); + $extra = "<a href='$url'>$extra</a>"; + + } else if (empty($extra)) { + $extra = "&nbsp;"; + } + + if (isset($temp_filenames['diff']) && file_exists($temp_filenames['diff'])) { + $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['diff']); + $diff = "<a href='$url'>diff</a>"; + } else { + $diff = "&nbsp;"; + } + + if (isset($temp_filenames['mem']) && file_exists($temp_filenames['mem'])) { + $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['mem']); + $mem = "<a href='$url'>leaks</a>"; + } else { + $mem = "&nbsp;"; + } + + fwrite($html_file, + "<tr>" . + "<td>$result</td>" . + "<td>$tested</td>" . + "<td>$extra</td>" . + "<td>$diff</td>" . + "<td>$mem</td>" . + "</tr>\n"); + } +} + +function junit_init() { + // Check whether a junit log is wanted. + $JUNIT = getenv('TEST_PHP_JUNIT'); + if (empty($JUNIT)) { + $JUNIT = FALSE; + } elseif (!$fp = fopen($JUNIT, 'w')) { + error("Failed to open $JUNIT for writing."); + } else { + $JUNIT = array( + 'fp' => $fp, + 'name' => 'php-src', + 'test_total' => 0, + 'test_pass' => 0, + 'test_fail' => 0, + 'test_error' => 0, + 'test_skip' => 0, + 'test_warn' => 0, + 'execution_time'=> 0, + 'suites' => array(), + 'files' => array() + ); + } + + $GLOBALS['JUNIT'] = $JUNIT; +} + +function junit_save_xml() { + global $JUNIT; + if (!junit_enabled()) return; + + $xml = '<?xml version="1.0" encoding="UTF-8"?>'. PHP_EOL . + '<testsuites>' . PHP_EOL; + $xml .= junit_get_suite_xml(); + $xml .= '</testsuites>'; + fwrite($JUNIT['fp'], $xml); +} + +function junit_get_suite_xml($suite_name = '') { + global $JUNIT; + + $suite = $suite_name ? $JUNIT['suites'][$suite_name] : $JUNIT; + + $result = sprintf( + '<testsuite name="%s" tests="%s" failures="%d" errors="%d" skip="%d" time="%s">' . PHP_EOL, + $suite['name'], $suite['test_total'], $suite['test_fail'], $suite['test_error'], $suite['test_skip'], + $suite['execution_time'] + ); + + foreach($suite['suites'] as $sub_suite) { + $result .= junit_get_suite_xml($sub_suite['name']); + } + + // Output files only in subsuites + if (!empty($suite_name)) { + foreach($suite['files'] as $file) { + $result .= $JUNIT['files'][$file]['xml']; + } + } + + $result .= '</testsuite>' . PHP_EOL; + + return $result; +} + +function junit_enabled() { + global $JUNIT; + return !empty($JUNIT); +} + +/** + * @param array|string $type + * @param string $file_name + * @param string $test_name + * @param int|string $time + * @param string $message + * @param string $details + * @return void + */ +function junit_mark_test_as($type, $file_name, $test_name, $time = null, $message = '', $details = '') { + global $JUNIT; + if (!junit_enabled()) return; + + $suite = junit_get_suitename_for($file_name); + + junit_suite_record($suite, 'test_total'); + + $time = null !== $time ? $time : junit_get_timer($file_name); + junit_suite_record($suite, 'execution_time', $time); + + $escaped_details = htmlspecialchars($details, ENT_QUOTES, 'UTF-8'); + $escaped_details = preg_replace_callback('/[\0-\x08\x0B\x0C\x0E-\x1F]/', function ($c) { + return sprintf('[[0x%02x]]', ord($c[0])); + }, $escaped_details); + $escaped_message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); + + $escaped_test_name = basename($file_name) . ' - ' . htmlspecialchars($test_name, ENT_QUOTES); + $JUNIT['files'][$file_name]['xml'] = "<testcase classname='$suite' name='$escaped_test_name' time='$time'>\n"; + + if (is_array($type)) { + $output_type = $type[0] . 'ED'; + $temp = array_intersect(array('XFAIL', 'FAIL', 'WARN'), $type); + $type = reset($temp); + } else { + $output_type = $type . 'ED'; + } + + if ('PASS' == $type || 'XFAIL' == $type) { + junit_suite_record($suite, 'test_pass'); + } elseif ('BORK' == $type) { + junit_suite_record($suite, 'test_error'); + $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'/>\n"; + } elseif ('SKIP' == $type) { + junit_suite_record($suite, 'test_skip'); + $JUNIT['files'][$file_name]['xml'] .= "<skipped>$escaped_message</skipped>\n"; + } elseif ('WARN' == $type) { + junit_suite_record($suite, 'test_warn'); + $JUNIT['files'][$file_name]['xml'] .= "<warning>$escaped_message</warning>\n"; + } elseif ('FAIL' == $type) { + junit_suite_record($suite, 'test_fail'); + $JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$escaped_message'>$escaped_details</failure>\n"; + } else { + junit_suite_record($suite, 'test_error'); + $JUNIT['files'][$file_name]['xml'] .= "<error type='$output_type' message='$escaped_message'>$escaped_details</error>\n"; + } + + $JUNIT['files'][$file_name]['xml'] .= "</testcase>\n"; + +} + +function junit_suite_record($suite, $param, $value = 1) { + global $JUNIT; + + $JUNIT[$param] += $value; + $JUNIT['suites'][$suite][$param] += $value; +} + +function junit_get_timer($file_name) { + global $JUNIT; + if (!junit_enabled()) return 0; + + if (isset($JUNIT['files'][$file_name]['total'])) { + return number_format($JUNIT['files'][$file_name]['total'], 4); + } + + return 0; +} + +function junit_start_timer($file_name) { + global $JUNIT; + if (!junit_enabled()) return; + + if (!isset($JUNIT['files'][$file_name]['start'])) { + $JUNIT['files'][$file_name]['start'] = microtime(true); + + $suite = junit_get_suitename_for($file_name); + junit_init_suite($suite); + $JUNIT['suites'][$suite]['files'][$file_name] = $file_name; + } +} + +function junit_get_suitename_for($file_name) { + return junit_path_to_classname(dirname($file_name)); +} + +function junit_path_to_classname($file_name) { + global $JUNIT; + return $JUNIT['name'] . '.' . str_replace(DIRECTORY_SEPARATOR, '.', $file_name); +} + +function junit_init_suite($suite_name) { + global $JUNIT; + if (!junit_enabled()) return; + + if (!empty($JUNIT['suites'][$suite_name])) { + return; + } + + $JUNIT['suites'][$suite_name] = array( + 'name' => $suite_name, + 'test_total' => 0, + 'test_pass' => 0, + 'test_fail' => 0, + 'test_error' => 0, + 'test_skip' => 0, + 'suites' => array(), + 'files' => array(), + 'execution_time'=> 0, + ); +} + +function junit_finish_timer($file_name) { + global $JUNIT; + if (!junit_enabled()) return; + + if (!isset($JUNIT['files'][$file_name]['start'])) { + error("Timer for $file_name was not started!"); + } + + if (!isset($JUNIT['files'][$file_name]['total'])) { + $JUNIT['files'][$file_name]['total'] = 0; + } + + $start = $JUNIT['files'][$file_name]['start']; + $JUNIT['files'][$file_name]['total'] += microtime(true) - $start; + unset($JUNIT['files'][$file_name]['start']); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim: noet sw=4 ts=4 + */ +?> diff --git a/vendor/swoole/tests/start.sh b/vendor/swoole/tests/start.sh new file mode 100755 index 0000000..5e63564 --- /dev/null +++ b/vendor/swoole/tests/start.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +pidof_php() +{ + echo `ps -A | grep -m1 php | grep -v phpstorm | awk '{print $1}'` +} + +`pidof_php | xargs kill > /dev/null 2>&1` +export TEST_PHP_EXECUTABLE=`which php` +BASEDIR=$(dirname "$0") +glob='swoole_*' +[ -z "$1" ] || glob="$@" +${TEST_PHP_EXECUTABLE} -d "memory_limit=1024m" ${BASEDIR}/run-tests ${glob} +`pidof_php | xargs kill > /dev/null 2>&1` + +rm /tmp/swoole.log diff --git a/vendor/swoole/tests/swoole_async/aio1.phpt b/vendor/swoole/tests/swoole_async/aio1.phpt new file mode 100755 index 0000000..29bb852 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/aio1.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_async: linux native aio readfile & writefile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +swoole_async::set(array('aio_mode' => SWOOLE_AIO_LINUX)); + +swoole_async_readfile(TEST_IMAGE, function ($filename, $content) +{ + assert(md5_file($filename) == md5($content)); + $wFile = __DIR__ . '/tmp'; + $wData = str_repeat('A', 8192 * 128); + swoole_async::writeFile($wFile, $wData, function ($file) use ($wData) + { + assert(md5_file($file) == md5($wData)); + echo "SUCCESS\n"; + swoole_event::defer(function() use ($file) { + unlink($file); + }); + }); + echo "SUCCESS\n"; +}); + +swoole_event::wait(); +?> +--EXPECT-- +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_async/aio2.phpt b/vendor/swoole/tests/swoole_async/aio2.phpt new file mode 100755 index 0000000..aae87b9 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/aio2.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_async: linux native aio read + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +swoole_async::set(array('aio_mode' => SWOOLE_AIO_LINUX)); + +$data = ''; +swoole_async_read(TEST_IMAGE, function ($filename, $content) use (&$data) +{ + if ($content) + { + $data .= $content; + } + else + { + assert(md5($data) == md5_file(TEST_IMAGE)); + } + return true; +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_async/aio3.phpt b/vendor/swoole/tests/swoole_async/aio3.phpt new file mode 100755 index 0000000..08c4670 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/aio3.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_async: linux native aio write + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const N = 10; +swoole_async::set(array('aio_mode' => SWOOLE_AIO_LINUX)); + +$data = ''; +$count = 0; +$sets = 'ABCDEFGHIJK'; +for ($i = 0; $i < N; $i++) +{ + $wData = str_repeat($sets[$i], 1023) . "\n"; + $data .= $wData; + swoole_async_write(__DIR__ . '/tmp', $wData, $i * 1024, function ($filename, $length) use ($data, &$count) + { + $count ++; + if ($count == N) { + swoole_event::defer(function() use ($data) { + assert(md5_file(__DIR__. '/tmp') == md5($data)); + echo "SUCCESS\n"; + unlink(__DIR__. '/tmp'); + }); + + } + }); +} + +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_1m_chunk.phpt b/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_1m_chunk.phpt new file mode 100755 index 0000000..47f0de5 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_1m_chunk.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_async: parallel_read_copy_10m_file + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_async/read_write.php'; + + +$chunk = 1024 * 1024; +parallel_read_copy($chunk, 10); +?> + +--EXPECT-- +SUCCESS + +--CLEAN-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_512k_chunk.phpt b/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_512k_chunk.phpt new file mode 100755 index 0000000..9e5ee9c --- /dev/null +++ b/vendor/swoole/tests/swoole_async/parallel_read_copy_10m_file_with_512k_chunk.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_async: parallel_read_copy_10m_file + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_async/read_write.php'; + + +$chunk = 1024 * 512; +parallel_read_copy($chunk, 10); +?> + +--EXPECT-- +SUCCESS + +--CLEAN-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/readfile.phpt b/vendor/swoole/tests/swoole_async/readfile.phpt new file mode 100755 index 0000000..70f6206 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/readfile.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_async: swoole_async_read + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +swoole_async_readfile(TEST_IMAGE, function ($filename, $content) { + assert(md5_file($filename) == md5($content)); + echo "SUCCESS\n"; +}); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_async/recursive_write.phpt b/vendor/swoole/tests/swoole_async/recursive_write.phpt new file mode 100755 index 0000000..009cf06 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/recursive_write.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_async: recursive write file + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_async/recursive_write.php'; + +recursiveWrite(); +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/serial_read_copy_10m_file.phpt b/vendor/swoole/tests/swoole_async/serial_read_copy_10m_file.phpt new file mode 100755 index 0000000..feec46d --- /dev/null +++ b/vendor/swoole/tests/swoole_async/serial_read_copy_10m_file.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_async: sequence copy 10m file + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_async/read_write.php'; + + +serial_read_copy(10); +?> + +--EXPECT-- +SUCCESS + +--CLEAN-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/swoole_async_dns_lookup.phpt b/vendor/swoole/tests/swoole_async/swoole_async_dns_lookup.phpt new file mode 100755 index 0000000..84aea05 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/swoole_async_dns_lookup.phpt @@ -0,0 +1,25 @@ +--TEST-- +swoole_async: swoole_async_dns_lookup + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +swoole_async_dns_lookup("www.baidu.com", function($host, $ip) { + assert(ip2long($ip)); + echo "SUCCESS"; +}); + +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/swoole_async_read.phpt b/vendor/swoole/tests/swoole_async/swoole_async_read.phpt new file mode 100755 index 0000000..1962eb2 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/swoole_async_read.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_async: swoole_async_read + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +swoole_async_read(__FILE__, function ($filename, $content) { + $size = strlen($content); + if ($size === 0) { + echo "SUCCESS"; + return false; + } else { + assert(filesize(__FILE__) === $size); + return true; + } +}, 8192); +?> + +--EXPECT-- +SUCCESS + + +--CLEAN-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_async/swoole_async_set.phpt b/vendor/swoole/tests/swoole_async/swoole_async_set.phpt new file mode 100755 index 0000000..ac35d70 --- /dev/null +++ b/vendor/swoole/tests/swoole_async/swoole_async_set.phpt @@ -0,0 +1,58 @@ +--TEST-- +swoole_async: swoole_async_set + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + + +swoole_async_set([ + "aio_mode" => 1, + "thread_num" => 1, + "enable_signalfd" => true, + "socket_buffer_size" => 0, + "socket_dontwait" => true, + "aio_max_buffer" => 0, + "disable_dns_cache" => true, + "dns_lookup_random" => true, + "enable_reuse_port" => true, +]); + + +// 一个线程 进行dns查询, 结果有序 +$r = []; + +$tokens = array_fill(0, 10, 0); + +for($i = 0; $i < 10; $i++) { + swoole_async_dns_lookup("www.youtube.com", function($domain, $ip) use($i, &$r, &$tokens) { + //echo $domain, $ip, "\n"; + array_pop($tokens); + $r[] = $i; + if (empty($tokens)) { + foreach($r as $i => $_i) { + assert($i === $_i); + } + echo "SUCCESS"; + } + + }); +} + + + + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_async/swoole_async_write.phpt b/vendor/swoole/tests/swoole_async/swoole_async_write.phpt new file mode 100755 index 0000000..736f0ef --- /dev/null +++ b/vendor/swoole/tests/swoole_async/swoole_async_write.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_async: swoole_async_write + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$tmpFile = __DIR__.'/tmpFile'; + +$data = ''; +$offset = 0; + +for ($i = 0; $i < 10; $i++) +{ + $size = rand(1000, 8192); + $chunk = RandStr::gen($size); + swoole_async_write($tmpFile, $chunk, $offset); + + $data .= $chunk; + $offset += $size; +} + + +for ($i = 0; $i < 5; $i++) +{ + $size = rand(1000, 8192); + $chunk = RandStr::gen($size); + swoole_async_write($tmpFile, $chunk, $offset, function () use ($i) { + echo "SUCCESS\n"; + if ($i == 4) { + swoole_event_exit(); + } + }); + + $data .= $chunk; + $offset += $size; +} +swoole_event::wait(); + +assert(md5($data) == md5_file($tmpFile)); +unlink($tmpFile); +?> + +--EXPECT-- +SUCCESS +SUCCESS +SUCCESS +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_async/writefile.phpt b/vendor/swoole/tests/swoole_async/writefile.phpt new file mode 100755 index 0000000..ecfe96e --- /dev/null +++ b/vendor/swoole/tests/swoole_async/writefile.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_async: swoole_async_read + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$content = file_get_contents(TEST_IMAGE); +$filename = __DIR__ . '/tmp_file.jpg'; + +swoole_async_writefile($filename, $content, function ($filename) +{ + assert(md5_file($filename) == md5_file(TEST_IMAGE)); + echo "SUCCESS\n"; + unlink($filename); + swoole_event_exit(); +}); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_atomic/atomic.phpt b/vendor/swoole/tests/swoole_atomic/atomic.phpt new file mode 100755 index 0000000..8e9baa3 --- /dev/null +++ b/vendor/swoole/tests/swoole_atomic/atomic.phpt @@ -0,0 +1,25 @@ +--TEST-- +swoole_atomic: add/sub/get/cmpset +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$atomic = new swoole_atomic(1); + +assert($atomic->add(199) == 200); +assert($atomic->sub(35) == 165); +assert($atomic->get() == 165); +assert($atomic->cmpset(165, 1)); +assert(!$atomic->cmpset(1555, 0)); +?> + +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_atomic/wait.phpt b/vendor/swoole/tests/swoole_atomic/wait.phpt new file mode 100755 index 0000000..165ffce --- /dev/null +++ b/vendor/swoole/tests/swoole_atomic/wait.phpt @@ -0,0 +1,46 @@ +--TEST-- +swoole_atomic: wakeup & wait +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$atomic = new swoole_atomic; +const N = 4; + +$workers = []; + +for ($i = 0; $i < 4; $i++) +{ + $p = new swoole_process(function () use ($atomic) + { + $atomic->wait(); + echo "Child OK\n"; + }); + $p->start(); + $workers[$i] = $p; +} + +usleep(200000); +echo "Master OK\n"; +$atomic->wakeup(N); + +for ($i = 0; $i < 4; $i++) +{ + $status = swoole_process::wait(); +} +?> + +--EXPECT-- +Master OK +Child OK +Child OK +Child OK +Child OK diff --git a/vendor/swoole/tests/swoole_buffer/buffer_append.phpt b/vendor/swoole/tests/swoole_buffer/buffer_append.phpt new file mode 100755 index 0000000..c590ce2 --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_append.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$data = "Test: write to swoole_buffer something."; +$data_len = strlen($data); + +#write to swoole_buffer +$write_len = $buffer->append($data); +assert($data_len === $write_len); + +#read some byte +$read_str = $buffer->read(0, $data_len); +if (strcmp($read_str, $data) == 0) { + echo "SUCCESS"; +} + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_buffer/buffer_clear.phpt b/vendor/swoole/tests/swoole_buffer/buffer_clear.phpt new file mode 100755 index 0000000..f529a87 --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_clear.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$data = "Test:write swoole_buffer something."; +$ret = $buffer->write(0, $data); +assert($buffer->length == strlen($data)); + +$buffer->clear(); +if($buffer->length == 0) { + echo "SUCCESS"; +} + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_buffer/buffer_expand.phpt b/vendor/swoole/tests/swoole_buffer/buffer_expand.phpt new file mode 100755 index 0000000..b5f62ab --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_expand.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$new_size = 256; +$expand_ret = $buffer->expand($new_size); +assert($new_size == $expand_ret); + +echo "buffer size = $buffer->capacity"; + +?> + +--EXPECTF-- +buffer size = %d diff --git a/vendor/swoole/tests/swoole_buffer/buffer_read_write.phpt b/vendor/swoole/tests/swoole_buffer/buffer_read_write.phpt new file mode 100755 index 0000000..755816c --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_read_write.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$data = "Test: write to swoole_buffer something."; +$data_len = strlen($data); + +#write to swoole_buffer +$write_len = $buffer->write(0, $data); +assert($data_len === $write_len); + +#read some byte +$read_str = $buffer->read(0, $data_len); +if (strcmp($read_str, $data) == 0) { + echo "SUCCESS"; +} + + ?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_buffer/buffer_recycle.phpt b/vendor/swoole/tests/swoole_buffer/buffer_recycle.phpt new file mode 100755 index 0000000..47ba0b0 --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_recycle.phpt @@ -0,0 +1,35 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$data = "Test: write to swoole_buffer something."; +$data_len = strlen($data); + +#写入数据 +$write_len = $buffer->write(0, $data); +assert($data_len === $write_len); + +//获得数据 +$str = $buffer->substr(0, $data_len, true); +$buffer->recycle(); +assert($buffer->length == 0); + +echo "SUCCESS"; + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_buffer/buffer_substr.phpt b/vendor/swoole/tests/swoole_buffer/buffer_substr.phpt new file mode 100755 index 0000000..99f3154 --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/buffer_substr.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_buffer: read and write swoole_buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); +assert($buffer instanceof swoole_buffer); + +$data = "Test: write to swoole_buffer something."; +$data_len = strlen($data); + +#write to swoole_buffer +$write_len = $buffer->write(0, $data); +assert($data_len === $write_len); + +$str = $buffer->substr(0); +if (strcmp($data, $str) == 0) { + echo "SUCCESS"; +} + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_buffer/construct_buffer.phpt b/vendor/swoole/tests/swoole_buffer/construct_buffer.phpt new file mode 100755 index 0000000..6492b4c --- /dev/null +++ b/vendor/swoole/tests/swoole_buffer/construct_buffer.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_buffer: default contruct buffer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$buffer = new swoole_buffer(); + +assert($buffer instanceof swoole_buffer); + +echo "capacity:" . $buffer->capacity . "\n"; +echo "length:" . $buffer->length . "\n"; + +$ret = $buffer->read(0, 10); +assert($ret == false); + + ?> + +--EXPECT-- +capacity:128 +length:0 diff --git a/vendor/swoole/tests/swoole_channel/basic.phpt b/vendor/swoole/tests/swoole_channel/basic.phpt new file mode 100755 index 0000000..f62996c --- /dev/null +++ b/vendor/swoole/tests/swoole_channel/basic.phpt @@ -0,0 +1,50 @@ +--TEST-- +swoole_coroutine: coro channel +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $ch = new \Swoole\Channel(1); + $out = new \Swoole\Channel(1); + Swoole\Coroutine::create(function() use ($ch, $out) { + $tmp = $ch->pop(); + $out->push("OK"); + }); + $ch->push("test"); + $ret = $out->pop(); + $response->end("$ret\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_channel/pusu_pop_stats.phpt b/vendor/swoole/tests/swoole_channel/pusu_pop_stats.phpt new file mode 100755 index 0000000..b060d82 --- /dev/null +++ b/vendor/swoole/tests/swoole_channel/pusu_pop_stats.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_channel: push & pop & stats + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +use Swoole\Channel; + +const N = 100; +$chan = new Channel(1024 * 256); + +$worker_num = 4; +$workers = array(); + +for ($i = 0; $i < N; $i++) +{ + $n = rand(100, 200); + $chan->push(['value' => str_repeat('A', $n), 'len' => $n]); +} + +$stats = $chan->stats(); +assert($stats['queue_num'] == N); + +for ($i = 0; $i < N; $i++) +{ + $ret = $chan->pop(); + assert(is_array($ret)); +} +?> + +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/big_package_memory_leak.phpt b/vendor/swoole/tests/swoole_client_async/big_package_memory_leak.phpt new file mode 100755 index 0000000..459989e --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/big_package_memory_leak.phpt @@ -0,0 +1,49 @@ +--TEST-- +swoole_client: big_package_memory_leak + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$tcp_server = __DIR__ . "/../include/memoryleak/tcp_client_memory_leak/tcp_serv.php"; +$closeServer = start_server($tcp_server, "127.0.0.1", 9001); + +$mem = memory_get_usage(true); +fclose(STDOUT); +ini_set("memory_limit", "100m"); +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("connect", function (swoole_client $cli) +{ + $cli->send(str_repeat("\0", 1024 * 1024 * 1.9)); +}); +$cli->on("receive", function (swoole_client $cli, $data) +{ + $cli->send($data); +}); +$cli->on("error", function (swoole_client $cli) +{ + echo "error"; +}); +$cli->on("close", function (swoole_client $cli) use ($closeServer) +{ + echo "closed\n"; + $closeServer(); +}); +$cli->connect("127.0.0.1", 9001); +assert(memory_get_usage(true) == $mem); +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS +closed diff --git a/vendor/swoole/tests/swoole_client_async/buffer_full.php.phpt b/vendor/swoole/tests/swoole_client_async/buffer_full.php.phpt new file mode 100755 index 0000000..a37224d --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/buffer_full.php.phpt @@ -0,0 +1,114 @@ +--TEST-- +swoole_client: onBufferFull & onBufferEmpty + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + Swoole\Async::set(['log_level' => 5, 'display_errors' => false]); + $client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->set(['socket_buffer_size' => 1 * 1024 * 1024,]); + $client->buffer = array(); + + $client->on("connect", function (Swoole\Client $cli) + { + for ($i = 0; $i < 1024; $i++) + { + $data = str_repeat('A', 8192); + if ($cli->send($data) === false and $cli->errCode == 1008) { + $cli->buffer[] = $data; + } + } + }); + + $client->on("receive", function (Swoole\Client $cli, $data) + { + $cli->send(pack('N', 8) . 'shutdown'); + $cli->close(); + assert($data === md5_file(TEST_IMAGE)); + }); + + $client->on("error", function($cli){ + echo "Connect failed\n"; + }); + + $client->on("close", function($cli){ + + }); + + $client->on("bufferEmpty", function (Swoole\Client $cli) + { + echo "bufferEmpty\n"; + foreach ($cli->buffer as $k => $data) + { + if ($cli->send($data) === false and $cli->errCode == 1008) + { + break; + } + else + { + unset($cli->buffer[$k]); + } + } + if (count($cli->buffer) == 0) + { + $cli->close(); + } + }); + + $client->on("bufferFull", function (Swoole\Client $cli) + { + echo "bufferFull\n"; + }); + + $client->connect(TCP_SERVER_HOST, $port, 0.5); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $socket = stream_socket_server("tcp://0.0.0.0:{$port}", $errno, $errstr) or die("$errstr ($errno)<br />\n"); + $pm->wakeup(); + while ($conn = stream_socket_accept($socket)) + { + for ($i = 0; $i < 4; $i++) + { + usleep(500000); + for ($j = 0; $j < 256; $j++) + { + $data = fread($conn, 8192); + } + } + fclose($conn); + break; + } + fclose($socket); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +bufferFull +bufferEmpty +bufferFull +bufferEmpty +bufferFull +bufferEmpty +bufferFull +bufferEmpty diff --git a/vendor/swoole/tests/swoole_client_async/connect_dns.phpt b/vendor/swoole/tests/swoole_client_async/connect_dns.phpt new file mode 100755 index 0000000..8164e81 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/connect_dns.phpt @@ -0,0 +1,45 @@ +--TEST-- +swoole_client: connect & dns + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$cli->on("connect", function (swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("GET / HTTP/1.1\r\nHost: www.baidu.com\r\nUser-Agent: curl/7.50.1-DEV\r\nAccept: */*\r\n\r\n"); +}); + +$cli->on("receive", function (swoole_client $cli, $data) { + assert(strlen($data) > 0); + $cli->close(); + assert($cli->isConnected() === false); +}); + +$cli->on("error", function (swoole_client $cli) { + echo "ERROR"; +}); + +$cli->on("close", function (swoole_client $cli) { + echo "SUCCESS"; +}); + +$cli->connect("www.baidu.com", 80, 2.0); + +swoole_event::wait(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_async/connect_refuse.phpt b/vendor/swoole/tests/swoole_client_async/connect_refuse.phpt new file mode 100755 index 0000000..66e6aee --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/connect_refuse.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_client: connect refuse + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("connect", function(swoole_client $cli) { + assert(false); +}); +$cli->on("receive", function(swoole_client $cli, $data) { + assert(false); +}); +$cli->on("error", function(swoole_client $cli) { echo "error\n"; }); +$cli->on("close", function(swoole_client $cli) { echo "close\n"; }); + +$cli->connect("127.0.0.1", 65535); +?> + +--EXPECT-- +error \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/connect_timeout.phpt b/vendor/swoole/tests/swoole_client_async/connect_timeout.phpt new file mode 100755 index 0000000..c5c2617 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/connect_timeout.phpt @@ -0,0 +1,38 @@ +--TEST-- +swoole_client: connect_host_not_found + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$start = microtime(true); + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); +$cli->on("connect", function(swoole_client $cli) { + assert(false); +}); +$cli->on("receive", function(swoole_client $cli, $data) { + assert(false); +}); +$cli->on("error", function(swoole_client $cli) { + echo "error\n"; +}); +$cli->on("close", function(swoole_client $cli) { + echo "close\n"; +}); + +$cli->connect("192.0.0.1", 9000, 0.1); +?> + +--EXPECT-- +error \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/connect_twice.phpt b/vendor/swoole/tests/swoole_client_async/connect_twice.phpt new file mode 100755 index 0000000..461d138 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/connect_twice.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_client: connect twice + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_client/connect_twice.php'; +?> + +--EXPECT-- +error \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/eof.phpt b/vendor/swoole/tests/swoole_client_async/eof.phpt new file mode 100755 index 0000000..2c51169 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/eof.phpt @@ -0,0 +1,131 @@ +--TEST-- +swoole_client: eof protocol [async] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$port = get_one_free_port(); +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->set(['open_eof_check' => true, 'open_eof_split' => true, "package_eof" => "\r\n\r\n"]); + + $client->on("connect", function (swoole_client $cli) + { + $cli->send("recv\r\n\r\n"); + }); + + $client->on("receive", function(swoole_client $cli, $pkg) use ($pid) { + static $i = 0; + $i++; + + //小包 + if ($i <= 1000) + { + assert($pkg and strlen($pkg) <= 2048); + if ($i == 1000) + { + echo "SUCCESS\n"; + } + return; + } + //慢速发送 + elseif ($i <= 1100) + { + assert($pkg and strlen($pkg) <= 8192); + if ($i == 1100) + { + echo "SUCCESS\n"; + } + return; + } + //大包 + else + { + assert($pkg != false); + $_pkg = unserialize($pkg); + assert(is_array($_pkg)); + assert($_pkg['i'] == $i - 1100 - 1); + assert($_pkg['data'] <= 256 * 1024); + if ($i == 2100) { + echo "SUCCESS\n"; + $cli->close(); + swoole_process::kill($pid); + } + } + }); + + $client->on("error", function(swoole_client $cli) { + print("error"); + }); + + $client->on("close", function(swoole_client $cli) { + swoole_event_exit(); + }); + + if (!$client->connect('127.0.0.1', $port, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE); + $serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M + 'socket_buffer_size' => 128 * 1024 * 1024, + "worker_num" => 1, + 'send_yield' => true, + 'log_file' => '/data/logs/swoole.log', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + //小包 + for ($i = 0; $i < 1000; $i++) + { + $serv->send($fd, str_repeat('A', rand(100, 2000)) . "\r\n\r\n"); + } + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $serv->send($fd, str_repeat('A', rand(1000, 2000))); + usleep(rand(10000, 50000)); + $serv->send($fd, str_repeat('A', rand(2000, 4000)) . "\r\n\r\n"); + } + //大包 + for ($i = 0; $i < 1000; $i++) + { + $serv->send($fd, serialize(['i' => $i, 'data' => str_repeat('A', rand(20000, 256 * 1024))]) . "\r\n\r\n"); + } + }); + $serv->start(); +}; +$pm->async = true; +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_async/eof_close.phpt b/vendor/swoole/tests/swoole_client_async/eof_close.phpt new file mode 100755 index 0000000..db8abe6 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/eof_close.phpt @@ -0,0 +1,76 @@ +--TEST-- +swoole_client: eof protocol [async] [close] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->set(['open_eof_check' => true, 'open_eof_split' => true, "package_eof" => "\r\n\r\n"]); + + $client->on("connect", function (swoole_client $cli) + { + $cli->send("recv\r\n\r\n"); + }); + + $client->on("receive", function (swoole_client $cli, $pkg) use ($pid, $pm) { + echo "RECEIVED\n"; + $cli->close(); + $pm->kill(); + }); + + $client->on("error", function(swoole_client $cli) { + print("error"); + }); + + $client->on("close", function(swoole_client $cli) { + echo "CLOSED\n"; + }); + + if (!$client->connect('127.0.0.1', 9501, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M + 'socket_buffer_size' => 128 * 1024 * 1024, + "worker_num" => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) { + $serv->send($fd, str_repeat('A', rand(100, 2000)) . "\r\n\r\n"); + }); + $serv->start(); +}; +$pm->async = true; +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +RECEIVED +CLOSED diff --git a/vendor/swoole/tests/swoole_client_async/getSocket_bug.phpt b/vendor/swoole/tests/swoole_client_async/getSocket_bug.phpt new file mode 100755 index 0000000..a14a8c6 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/getSocket_bug.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_client: getSocket debug + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (method_exists('swoole_client', 'getSocket') === false) { + exit("require sockets supports."); +} +?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/simple_server.php"; +start_server($simple_tcp_server, TCP_SERVER_HOST, TCP_SERVER_PORT); + +suicide(1000); + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$cli->on("connect", function(swoole_client $cli) { + // getSocket BUG + $cli->getSocket(); + $cli->getSocket(); + + echo "SUCCESS"; + /* + @$cli->getSocket(); + $err = error_get_last(); + assert($err["message"] === "swoole_client_async::getSocket(): unable to obtain socket family Error: Bad file descriptor[9]."); + */ + swoole_event_exit(); +}); + +$cli->on("receive", function(swoole_client $cli, $data){}); +$cli->on("error", function(swoole_client $cli) {echo "error\n";}); +$cli->on("close", function(swoole_client $cli) {}); + +$cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT, 1); +Swoole\Event::wait(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_async/getpeername.phpt b/vendor/swoole/tests/swoole_client_async/getpeername.phpt new file mode 100755 index 0000000..311eea5 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/getpeername.phpt @@ -0,0 +1,68 @@ +--TEST-- +swoole_client: getsockpeername + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new \swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (\swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("test"); + }); + + $cli->on("receive", function(\swoole_client $cli, $data){ + $i = $cli->getpeername(); + assert($i !== false); + $cli->send('shutdown'); + $cli->close(); + }); + + $cli->on("close", function(\swoole_client $cli) { + echo "SUCCESS\n"; + }); + + $r = $cli->connect(UDP_SERVER_HOST, UDP_SERVER_PORT, 1); + assert($r); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server(UDP_SERVER_HOST, UDP_SERVER_PORT, SWOOLE_BASE, SWOOLE_SOCK_UDP); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null']); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Packet", function (\swoole_server $serv, $data, $clientInfo) + { + if (trim($data) == 'shutdown') + { + $serv->shutdown(); + return; + } + $serv->sendto($clientInfo['address'], $clientInfo['port'], $data); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_async/getsockname.phpt b/vendor/swoole/tests/swoole_client_async/getsockname.phpt new file mode 100755 index 0000000..1011934 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/getsockname.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_client: swoole_client getsockname + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/simple_server.php"; +start_server($simple_tcp_server, TCP_SERVER_HOST, TCP_SERVER_PORT); + +suicide(5000); + + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$cli->on("connect", function(swoole_client $cli) { + assert($cli->isConnected() === true); + + $i = $cli->getsockname(); + assert($i !== false); + assert($i["host"] === "127.0.0.1"); + + $cli->close(); +}); + +$cli->on("receive", function(swoole_client $cli, $data){ +}); + +$cli->on("error", function(swoole_client $cli) { + echo "error"; +}); + +$cli->on("close", function(swoole_client $cli) { + echo "SUCCESS"; + swoole_event_exit(); +}); + +$cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT, 1); +Swoole\Event::wait(); +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/length_protocol.phpt b/vendor/swoole/tests/swoole_client_async/length_protocol.phpt new file mode 100755 index 0000000..ad5dc2d --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/length_protocol.phpt @@ -0,0 +1,135 @@ +--TEST-- +swoole_client: length protocol [async] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->set([ + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + + $client->on("connect", function (swoole_client $cli) + { + $cli->send("recv\r\n\r\n"); + }); + + $client->on("receive", function(swoole_client $cli, $pkg) use ($pid) { + static $i = 0; + $i++; + + //小包 + if ($i <= 1000) + { + assert($pkg and strlen($pkg) <= 2048); + if ($i == 1000) + { + echo "SUCCESS\n"; + } + return; + } + //慢速发送 + elseif ($i <= 1100) + { + assert($pkg and strlen($pkg) <= 8192); + if ($i == 1100) + { + echo "SUCCESS\n"; + } + return; + } + //大包 + else + { + assert($pkg != false); + $_pkg = unserialize(substr($pkg, 4)); + assert(is_array($_pkg)); + assert($_pkg['i'] == $i - 1100 - 1); + assert($_pkg['data'] <= 256 * 1024); + if ($i == 2100) { + echo "SUCCESS\n"; + $cli->close(); + swoole_process::kill($pid); + } + } + }); + + $client->on("error", function(swoole_client $cli) { + print("error"); + }); + + $client->on("close", function(swoole_client $cli) { + swoole_event_exit(); + }); + + if (!$client->connect('127.0.0.1', 9501, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + "worker_num" => 1, + 'send_yield' => true, + 'log_file' => '/tmp/swoole.log', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + //小包 + for ($i = 0; $i < 1000; $i++) + { + $data = str_repeat('A', rand(100, 2000)); + $serv->send($fd, pack('N', strlen($data)) . $data); + } + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $data = str_repeat('A', rand(3000, 6000)); + $n = rand(1000, 2000); + $serv->send($fd, pack('N', strlen($data)). substr($data, 0, $n)); + usleep(rand(10000, 50000)); + $serv->send($fd, substr($data, $n)); + } + //大包 + for ($i = 0; $i < 1000; $i++) + { + $data = serialize(['i' => $i, 'data' => str_repeat('A', rand(20000, 256 * 1024))]); + $serv->send($fd, pack('N', strlen($data)) . $data); + } + }); + $serv->start(); +}; + +$pm->async = true; +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_async/sendfile.phpt b/vendor/swoole/tests/swoole_client_async/sendfile.phpt new file mode 100755 index 0000000..01c35b1 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/sendfile.phpt @@ -0,0 +1,78 @@ +--TEST-- +swoole_client: async sendfile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $client->on("connect", function (Swoole\Client $cli) + { + $cli->send(pack('N', filesize(TEST_IMAGE))); + $ret = $cli->sendfile(TEST_IMAGE); + assert($ret); + }); + $client->on("receive", function (Swoole\Client $cli, $data) + { + $cli->send(pack('N', 8) . 'shutdown'); + $cli->close(); + assert($data === md5_file(TEST_IMAGE)); + }); + $client->on("error", function($cli){ + echo "Connect failed\n"; + }); + $client->on("close", function($cli){ + + }); + $client->connect(TCP_SERVER_HOST, $port, 0.5); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, $port, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'dispatch_mode' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + 'package_max_length' => 2000000, + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) + { + if (substr($data, 4, 8) == 'shutdown') + { + $serv->shutdown(); + return; + } + $serv->send($fd, md5(substr($data, 4))); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_client_async/sleep_wake.phpt b/vendor/swoole/tests/swoole_client_async/sleep_wake.phpt new file mode 100755 index 0000000..1ba3ffc --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/sleep_wake.phpt @@ -0,0 +1,66 @@ +--TEST-- +swoole_client: swoole_client sleep & sleep + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (swoole_client $cli) + { + assert($cli->isConnected() === true); + $r = $cli->sleep(); + assert($r); + swoole_timer_after(200, function () use ($cli) + { + $r = $cli->wakeup(); + assert($r); + }); + $cli->send(RandStr::gen(1024, RandStr::ALL)); + }); + + $cli->on("receive", function(swoole_client $cli, $data){ + $recv_len = strlen($data); + $cli->send(RandStr::gen(1024, RandStr::ALL)); + $cli->close(); + assert($cli->isConnected() === false); + }); + + $cli->on("error", function(swoole_client $cli) { + echo "error"; + }); + + $cli->on("close", function(swoole_client $cli) { + echo "SUCCESS"; + }); + + $cli->connect('127.0.0.1', 9501, 0.1); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/tcp_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_client_async/swoole_client.phpt b/vendor/swoole/tests/swoole_client_async/swoole_client.phpt new file mode 100755 index 0000000..099686a --- /dev/null +++ b/vendor/swoole/tests/swoole_client_async/swoole_client.phpt @@ -0,0 +1,57 @@ +--TEST-- +swoole_client: swoole_client connect & send & close + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/simple_server.php"; +start_server($simple_tcp_server, TCP_SERVER_HOST, TCP_SERVER_PORT); + + +suicide(5000); + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$cli->on("connect", function(swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send(RandStr::gen(1024, RandStr::ALL)); +}); + +$cli->on("receive", function(swoole_client $cli, $data){ + $recv_len = strlen($data); + // print("receive: len $recv_len"); + $cli->send(RandStr::gen(1024, RandStr::ALL)); + $cli->close(); + assert($cli->isConnected() === false); +}); + +$cli->on("error", function(swoole_client $cli) { + // swoole_timer_clear($cli->timeo_id); + print("error"); +}); + +$cli->on("close", function(swoole_client $cli) { + // swoole_timer_clear($cli->timeo_id); + // print("close"); + swoole_event_exit(); + echo "SUCCESS"; +}); + +$cli->connect(TCP_SERVER_HOST, TCP_SERVER_PORT, 0.2); + + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_coro/close_resume.phpt b/vendor/swoole/tests/swoole_client_coro/close_resume.phpt new file mode 100755 index 0000000..b5940da --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/close_resume.phpt @@ -0,0 +1,71 @@ +--TEST-- +swoole_server: (length protocol) resume in onClose callback + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/api/swoole_server/TestServer.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) +{ + go(function () { + $cli = new Co\Client(SWOOLE_SOCK_TCP); + $cli->set([ + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + $cli->connect('127.0.0.1', 9501); + $data = str_repeat('A', 1025); + $cli->send(pack('N', strlen($data)).$data); + co::sleep(0.2); + $retData = $cli->recv(); + assert(is_string($retData) and strlen($retData) > 0); + $retData = $cli->recv(); + assert($retData == false); + assert($cli->errCode == SWOOLE_ERROR_CLIENT_NO_CONNECTION); + }); + swoole_event_wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set([ + 'worker_num' => 1, + //'dispatch_mode' => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $data = str_repeat('B', 1025); + $serv->send($fd, pack('N', strlen($data)) . $data); + $serv->close($fd); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECTF-- diff --git a/vendor/swoole/tests/swoole_client_coro/eof.phpt b/vendor/swoole/tests/swoole_client_coro/eof.phpt new file mode 100755 index 0000000..3d5e50a --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/eof.phpt @@ -0,0 +1,71 @@ +--TEST-- +swoole_coroutine: tcp client with eof +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $port2 = $http->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); + $port2->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + + $port2->on('Receive', function ($serv, $fd, $rid, $data) + { + $serv->send($fd, "Swoole: $data\r\n\r\n"); + }); + + $http->set(array( + //'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + $cli->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + if (!$cli->connect('127.0.0.1', 9502)) + { + fail: + $response->end("ERROR\n"); + return; + } + if (!$cli->send("hello\r\n\r\n")) + { + goto fail; + } + $ret = $cli->recv(); + if (!$ret) + { + goto fail; + } + $response->end("OK\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_client_coro/eof_02.phpt b/vendor/swoole/tests/swoole_client_coro/eof_02.phpt new file mode 100755 index 0000000..deacade --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/eof_02.phpt @@ -0,0 +1,97 @@ +--TEST-- +swoole_coroutine: tcp client with eof [02] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +class MyPool +{ + protected $pool; + + public function __construct() + { + $this->pool = new SplQueue(); + } + + public function put($mysql) + { + $this->pool->push($mysql); + } + + public function get() + { + //有空闲连接 + if (count($this->pool) > 0) { + return $this->pool->pop(); + } + + $client = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP | SWOOLE_KEEP); + $client->set(array( + 'open_eof_split' => true, //打开EOF_SPLIT检测 + 'package_eof' => "\r\n", + )); + $res = $client->connect('127.0.0.1', 8000, 3); + if ($res == false) { + echo "create connect failed, errCode=".$client->errCode."\n"; + return false; + } else { + return $client; + } + } +} + +$pm->parentFunc = function ($pid) use ($pm) { + go(function () { + $pool = new MyPool(); + for ($j = 0; $j < 2; $j++) + { + $con = []; + for ($i = 0; $i < 4; $i++) + { + $client = $pool->get(); + $client->send('hello' . $i . "\r\n"); + $con[] = $client; + } + co::sleep(0.1); + foreach ($con as $key => $value) + { + echo "recv:" . trim($value->recv()) . "\n"; + $pool->put($value); + } + } + }); + swoole_event_wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new swoole_server('0.0.0.0', 8000, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set(array( + 'open_eof_split' => true, + 'package_eof' => "\r\n", + )); + $serv->on('receive', function ($serv, $fd, $rid, $data) { + $ret = "server reply {" . trim($data) . "} \r\n"; + $serv->send($fd, $ret); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +recv:server reply {hello0} +recv:server reply {hello1} +recv:server reply {hello2} +recv:server reply {hello3} +recv:server reply {hello0} +recv:server reply {hello1} +recv:server reply {hello2} +recv:server reply {hello3} diff --git a/vendor/swoole/tests/swoole_client_coro/length_02.phpt b/vendor/swoole/tests/swoole_client_coro/length_02.phpt new file mode 100755 index 0000000..3bc30a1 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/length_02.phpt @@ -0,0 +1,67 @@ +--TEST-- +swoole_server: (length protocol) wrong packet + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/api/swoole_server/TestServer.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) +{ + go(function () { + $cli = new Co\Client(SWOOLE_SOCK_TCP); + $cli->set([ + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + $cli->connect('127.0.0.1', 9501); + $data = str_repeat('A', 1025); + $cli->send(pack('N', strlen($data)).$data); + $retData = $cli->recv(); + assert($retData == false); + assert($cli->errCode == SOCKET_ECONNRESET); + }); + swoole_event_wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set([ + 'worker_num' => 1, + //'dispatch_mode' => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $serv->send($fd, pack('N', 1223)); + $serv->close($fd); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECTF-- diff --git a/vendor/swoole/tests/swoole_client_coro/tcp_client.phpt b/vendor/swoole/tests/swoole_client_coro/tcp_client.phpt new file mode 100755 index 0000000..b55c6e4 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/tcp_client.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_coroutine: tcp client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $port2 = $http->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); + $port2->set([]); + $port2->on('Receive', function ($serv, $fd, $rid, $data) + { + $serv->send($fd, "Swoole: $data"); + }); + + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP); + if (!$cli->connect('127.0.0.1', 9502)) + { + fail: + $response->end("ERROR\n"); + return; + } + if (!$cli->send("hello")) + { + goto fail; + } + $ret = $cli->recv(); + if (!$ret) + { + goto fail; + } + $response->end("OK\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_client_coro/timeout.phpt b/vendor/swoole/tests/swoole_client_coro/timeout.phpt new file mode 100755 index 0000000..f2706b0 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/timeout.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_coroutine: timeout of udp client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + $begin = time(); + if (!$cli->connect('127.0.0.1', 9502, 3)) + { + fail: + $response->end("ERROR\n"); + return; + } + if (!$cli->send("hello")) + { + goto fail; + } + $ret = $cli->recv(); + $interval = time() - $begin; + if ($ret !== false) + { + goto fail; + } + if ($interval < 3) + { + goto fail; + } + $cli->close(); + $response->end("TIMEOUT\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +TIMEOUT diff --git a/vendor/swoole/tests/swoole_client_coro/udp_client.phpt b/vendor/swoole/tests/swoole_client_coro/udp_client.phpt new file mode 100755 index 0000000..35aafa6 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_coro/udp_client.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_coroutine: udp client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $port2 = $http->listen('127.0.0.1', 9502, SWOOLE_SOCK_UDP); + $port2->set([]); + $port2->on('Packet', function ($serv, $data, $client) + { + $serv->sendto($client['address'], $client['port'], "Swoole: $data"); + }); + + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP); + if (!$cli->connect('127.0.0.1', 9502)) + { + fail: + $response->end("ERROR\n"); + return; + } + if (!$cli->send("hello")) + { + goto fail; + } + $ret = $cli->recv(); + if (!$ret) + { + goto fail; + } + $response->end("OK\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_client_sync/eof.phpt b/vendor/swoole/tests/swoole_client_sync/eof.phpt new file mode 100755 index 0000000..ef0bc0c --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/eof.phpt @@ -0,0 +1,108 @@ +--TEST-- +swoole_client: eof protocol [sync] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$port = get_one_free_port(); +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + if (!$client->connect('127.0.0.1', $port, 5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + + $client->send("recv\r\n\r\n"); + + //小包 + for ($i = 0; $i < 1000; $i++) + { + $pkg = $client->recv(); + assert($pkg and strlen($pkg) <= 2048); + } + echo "SUCCESS\n"; + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $pkg = $client->recv(); + assert($pkg and strlen($pkg) <= 8192); + } + echo "SUCCESS\n"; + //大包 + for ($i = 0; $i < 1000; $i++) + { + $pkg = $client->recv(); + assert($pkg != false); + $_pkg = unserialize($pkg); + assert(is_array($_pkg)); + assert($_pkg['i'] == $i); + assert($_pkg['data'] <= 256 * 1024); + } + echo "SUCCESS\n"; + $client->close(); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE); + $serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M + 'socket_buffer_size' => 256 * 1024 * 1024, + 'send_yield' => true, + "worker_num" => 1, + 'log_file' => '/tmp/swoole.log', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + //小包 + for ($i = 0; $i < 1000; $i++) + { + $serv->send($fd, str_repeat('A', rand(100, 2000)) . "\r\n\r\n"); + } + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $serv->send($fd, str_repeat('A', rand(1000, 2000))); + usleep(rand(10000, 50000)); + $serv->send($fd, str_repeat('A', rand(2000, 4000)) . "\r\n\r\n"); + } + //大包 + for ($i = 0; $i < 1000; $i++) + { + $serv->send($fd, serialize(['i' => $i, 'data' => str_repeat('A', rand(20000, 256 * 1024))]) . "\r\n\r\n"); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/eof_timeout.phpt b/vendor/swoole/tests/swoole_client_sync/eof_timeout.phpt new file mode 100755 index 0000000..31cbf42 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/eof_timeout.phpt @@ -0,0 +1,74 @@ +--TEST-- +swoole_client_sync: eof timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +ini_set("swoole.display_errors", "Off"); + +$pm->parentFunc = function ($pid) +{ + $cli = new Swoole\Client(SWOOLE_SOCK_TCP); + $cli->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + if (!$cli->connect('127.0.0.1', 9502, 0.5)) + { + fail: + echo "ERROR\n"; + swoole_process::kill($pid); + return; + } + //no eof, should be timeout here + if (!$cli->send("hello")) + { + goto fail; + } + $ret = $cli->recv(); + if (!$ret) + { + goto fail; + } + echo "OK\n"; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $port2 = $http->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); + $port2->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + + $port2->on('Receive', function ($serv, $fd, $rid, $data) + { + $serv->send($fd, "Swoole: $data\r\n\r\n"); + }); + + $http->set(array( + //'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $response->end("OK\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +ERROR diff --git a/vendor/swoole/tests/swoole_client_sync/length_protocol.phpt b/vendor/swoole/tests/swoole_client_sync/length_protocol.phpt new file mode 100755 index 0000000..fe3be6a --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/length_protocol.phpt @@ -0,0 +1,112 @@ +--TEST-- +swoole_client: length protocol [sync] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set([ + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + ]); + if (!$client->connect('127.0.0.1', $port, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + + $client->send("recv\r\n\r\n"); + + //小包 + for ($i = 0; $i < 1000; $i++) + { + $pkg = $client->recv(); + assert($pkg and strlen($pkg) <= 2048); + } + echo "SUCCESS\n"; + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $pkg = $client->recv(); + assert($pkg and strlen($pkg) <= 8192); + } + echo "SUCCESS\n"; + //大包 + for ($i = 0; $i < 1000; $i++) + { + $pkg = $client->recv(); + assert($pkg != false); + $_pkg = unserialize(substr($pkg, 4)); + assert(is_array($_pkg)); + assert($_pkg['i'] == $i); + assert($_pkg['data'] <= 256 * 1024); + } + echo "SUCCESS\n"; + $client->close(); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE); + $serv->set(array( + 'package_max_length' => 1024 * 1024 * 2, //2M + 'socket_buffer_size' => 256 * 1024 * 1024, + "worker_num" => 1, + 'log_file' => '/tmp/swoole.log', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + //小包 + for ($i = 0; $i < 1000; $i++) + { + $data = str_repeat('A', rand(100, 2000)); + $serv->send($fd, pack('N', strlen($data)) . $data); + } + //慢速发送 + for ($i = 0; $i < 100; $i++) + { + $data = str_repeat('A', rand(3000, 6000)); + $n = rand(1000, 2000); + $serv->send($fd, pack('N', strlen($data)). substr($data, 0, $n)); + usleep(rand(10000, 50000)); + $serv->send($fd, substr($data, $n)); + } + //大包 + for ($i = 0; $i < 1000; $i++) + { + $data = serialize(['i' => $i, 'data' => str_repeat('A', rand(20000, 256 * 1024))]); + $serv->send($fd, pack('N', strlen($data)) . $data); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/length_protocol_02.phpt b/vendor/swoole/tests/swoole_client_sync/length_protocol_02.phpt new file mode 100755 index 0000000..421b0c8 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/length_protocol_02.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_client: length protocol 02 [sync] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set([ + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + ]); + if (!$client->connect('127.0.0.1', 9501, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + + $int = rand(1000, 5000); + $data = json_encode(['data' => RandStr::gen($int), 'index' => 2, 'len' => $int]); + $client->send(pack('N', strlen($data) + 4) . $data); + $pkg = $client->recv(); + assert($pkg != false and strlen($pkg) > 100); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_PROCESS); + $serv->set(array( + "worker_num" => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 0, + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $data = str_repeat('A', rand(100, 2000)); + $serv->send($fd, pack('N', strlen($data) + 4) . $data); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_client_sync/recv_timeout.phpt b/vendor/swoole/tests/swoole_client_sync/recv_timeout.phpt new file mode 100755 index 0000000..6d8a2bb --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/recv_timeout.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_client: recv timeout + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) +{ + $client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $r = $client->connect(TCP_SERVER_HOST, 9501, 0.5); + assert($r); + $client->send(pack('N', filesize(TEST_IMAGE))); + $data = @$client->recv(); + assert($data == false); + assert($client->errCode == SOCKET_EAGAIN); + $pm->kill(); + $client->close(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) + { + //do nothing + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_client_sync/sendfile.phpt b/vendor/swoole/tests/swoole_client_sync/sendfile.phpt new file mode 100755 index 0000000..ba7a512 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/sendfile.phpt @@ -0,0 +1,66 @@ +--TEST-- +swoole_client: sync sendfile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $r = $client->connect(TCP_SERVER_HOST, $port, 0.5); + assert($r); + $client->send(pack('N', filesize(TEST_IMAGE))); + $ret = $client->sendfile(TEST_IMAGE); + assert($ret); + + $data = $client->recv(); + $client->send(pack('N', 8) . 'shutdown'); + $client->close(); + assert($data === md5_file(TEST_IMAGE)); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, $port, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'dispatch_mode' => 1, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + 'package_max_length' => 2000000, + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) + { + if (substr($data, 4, 8) == 'shutdown') + { + $serv->shutdown(); + return; + } + $serv->send($fd, md5(substr($data, 4))); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-1.phpt b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-1.phpt new file mode 100755 index 0000000..1b257fd --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-1.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_client sync: connect 1 - 1 + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + * Time: 上午10:06 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); +$r = @$cli->connect("11.11.11.11", 80, 0.5); +echo intval($r); +?> + +--EXPECT-- +0 diff --git a/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-2.phpt b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-2.phpt new file mode 100755 index 0000000..d3d7c16 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-2.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_client sync: connect 1 - 2 + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 上午10:06 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +killself_in_syncmode(1000, SIGTERM); + + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); +$r = $cli->connect(IP_BAIDU, 80); +assert($r); +$cli->close(); +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-3.phpt b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-3.phpt new file mode 100755 index 0000000..1b32564 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/swoole_client_connect1-3.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_client sync: connect 1 - 3 nonblocking connect & select + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 上午10:06 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +killself_in_syncmode(1000, SIGTERM); + + +$cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); +$r = $cli->connect(IP_BAIDU, 80, 1); +assert($r); +$r = $w = $e = [$cli]; +$n = swoole_client_select($r, $w, $e, 0); +assert($n === 1); +assert(count($w) === 1); +assert(count($e) === 0); +assert(count($r) === 0); +$cli->close(); +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/swoole_client_send_recv.phpt b/vendor/swoole/tests/swoole_client_sync/swoole_client_send_recv.phpt new file mode 100755 index 0000000..8672aa6 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/swoole_client_send_recv.phpt @@ -0,0 +1,39 @@ +--TEST-- +swoole_client sync: send & recv + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 上午10:06 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +killself_in_syncmode(1000); + + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); +$r = $cli->connect(IP_BAIDU, 80); +assert($r); +$r = $cli->send("GET / HTTP/1.1\r\n\r\n"); +assert($r === 18); +$r = $cli->recv(); +assert($r !== false); +assert(substr($r, 0, 4) === "HTTP"); +echo "SUCCESS"; + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/swoole_client_sync_send_recv.phpt b/vendor/swoole/tests/swoole_client_sync/swoole_client_sync_send_recv.phpt new file mode 100755 index 0000000..ee9bb60 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/swoole_client_sync_send_recv.phpt @@ -0,0 +1,35 @@ +--TEST-- +swoole_client: udp sync client send & recv + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/simple_udp_server.php"; +start_server($simple_tcp_server, UDP_SERVER_HOST, UDP_SERVER_PORT); + +$client = new swoole_client(SWOOLE_SOCK_UDP); +$client->connect(UDP_SERVER_HOST, UDP_SERVER_PORT); + +$data = "UdpSendto"; +$client->send($data); + +$message = $client->recv(); +echo "FromServer:$message\n"; +echo "SUCCESS"; + +?> + +--EXPECTF-- +FromServer:UdpSendto +SUCCESS diff --git a/vendor/swoole/tests/swoole_client_sync/udp_client_sendto.phpt b/vendor/swoole/tests/swoole_client_sync/udp_client_sendto.phpt new file mode 100755 index 0000000..f8328b0 --- /dev/null +++ b/vendor/swoole/tests/swoole_client_sync/udp_client_sendto.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_client: udp sync client sendto + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/simple_udp_server.php"; +start_server($simple_tcp_server, UDP_SERVER_HOST, UDP_SERVER_PORT); + +$client = new swoole_client(SWOOLE_SOCK_UDP); +$client->connect(UDP_SERVER_HOST, UDP_SERVER_PORT); + +$ret = $client->sendto(UDP_SERVER_HOST, UDP_SERVER_PORT, "TestUdpClientSendto"); +$message = $client->recv(); +echo "FromServer:{$message}\n"; +echo "SUCCESS"; + +?> + +--EXPECT-- +FromServer:TestUdpClientSendto +SUCCESS diff --git a/vendor/swoole/tests/swoole_coroutine/call_user_func_array.phpt b/vendor/swoole/tests/swoole_coroutine/call_user_func_array.phpt new file mode 100755 index 0000000..9fd10d4 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/call_user_func_array.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_coroutine: call_user_func_array +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +class A { + public function foo() { + call_user_func_array([$this, "bar"], []); + echo "foo\n"; + } + protected function bar() { + echo "bar\n"; + } +} +$a = new A; +call_user_func_array([$a, "foo"], []); +?> +--EXPECT-- +bar +foo diff --git a/vendor/swoole/tests/swoole_coroutine/coro_stats.phpt b/vendor/swoole/tests/swoole_coroutine/coro_stats.phpt new file mode 100755 index 0000000..29ea3c6 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/coro_stats.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_coroutine: current stats +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +assert(Co::stats()['coroutine_num'] === 0); + +go(function () { + assert(Co::stats()['coroutine_num'] === 1); + Co::sleep(0.5); + assert(Co::stats()['coroutine_num'] === 2); +}); +go(function () { + assert(Co::stats()['coroutine_num'] === 2); + Co::sleep(0.5); + assert(Co::stats()['coroutine_num'] === 1); +}); +assert(Co::stats()['coroutine_num'] === 2); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine/current.phpt b/vendor/swoole/tests/swoole_coroutine/current.phpt new file mode 100755 index 0000000..a3bf50f --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/current.phpt @@ -0,0 +1,20 @@ +--TEST-- +swoole_coroutine: current cid +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +assert(Co::getuid() === -1); +go(function () { + assert(Co::getuid() === 1); + Co::sleep(1); + assert(Co::getuid() === 1); +}); +go(function () { + assert(Co::getuid() === 2); +}); +assert(Co::getuid() === -1); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine/destruct/destruct1.phpt b/vendor/swoole/tests/swoole_coroutine/destruct/destruct1.phpt new file mode 100755 index 0000000..26e30d4 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/destruct/destruct1.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_coroutine: destruct1 +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +class T +{ + function __construct() + { + + } + function test() + { + echo "call function \n"; + } + + function __destruct() + { + go(function () { + echo "coro start\n"; + co::sleep(1.0); + echo "coro exit\n"; + }); + } +} + +$t = new T(); +$t->test(); +unset($t); +echo "end\n"; +?> +--EXPECT-- +call function +coro start +end +coro exit \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine/destruct/destruct2.phpt b/vendor/swoole/tests/swoole_coroutine/destruct/destruct2.phpt new file mode 100755 index 0000000..5658220 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/destruct/destruct2.phpt @@ -0,0 +1,39 @@ +--TEST-- +swoole_coroutine: destruct2 +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +class T +{ + function __construct() + { + + } + function test() + { + echo "call function \n"; + } + + function __destruct() + { + go(function () { + echo "coro start\n"; + co::sleep(1.0); + echo "coro exit\n"; + }); + } +} + +$t = new T(); +$t->test(); +echo "end\n"; +?> +--EXPECTF-- +call function +end + +Fatal error: go(): can not use coroutine in __destruct after php_request_shutdown %s diff --git a/vendor/swoole/tests/swoole_coroutine/empty.phpt b/vendor/swoole/tests/swoole_coroutine/empty.phpt new file mode 100755 index 0000000..8cf0e16 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/empty.phpt @@ -0,0 +1,16 @@ +--TEST-- +swoole_coroutine: coro empty +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + echo "co[1] exit\n"; +}); +?> +--EXPECT-- +co[1] start +co[1] exit diff --git a/vendor/swoole/tests/swoole_coroutine/exception/empty.phpt b/vendor/swoole/tests/swoole_coroutine/exception/empty.phpt new file mode 100755 index 0000000..3727114 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/exception/empty.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: IO empty Exception +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +go(function () { + try { + echo "start\n"; + throw new Exception('coro Exception'); + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "finally.\n"; + } +}); + echo "end\n"; + +?> +--EXPECT-- +start +Caught exception: coro Exception +finally. +end diff --git a/vendor/swoole/tests/swoole_coroutine/exception/nested.phpt b/vendor/swoole/tests/swoole_coroutine/exception/nested.phpt new file mode 100755 index 0000000..8328b7b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/exception/nested.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_coroutine: exception before yield +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +go(function () { + try { + echo "start\n"; + go(function(){ + try { + echo "sub start\n"; + throw new Exception('sub coro Exception'); + co::sleep(0.5); + echo "after go2 sleep\n"; + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "finally 2\n"; + } + }); + echo "after go1 sleep\n"; + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "finally 1\n"; + } +}); + echo "end\n"; + +?> +--EXPECT-- +start +sub start +Caught exception: sub coro Exception +finally 2 +after go1 sleep +finally 1 +end diff --git a/vendor/swoole/tests/swoole_coroutine/exception/yield.phpt b/vendor/swoole/tests/swoole_coroutine/exception/yield.phpt new file mode 100755 index 0000000..cc99f73 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/exception/yield.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_coroutine: exception after yield +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +go(function () { + try { + echo "start\n"; + co::sleep(0.5); + echo "after sleep\n"; + throw new Exception('coro Exception'); + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "finally.\n"; + } +}); + echo "end\n"; + +?> +--EXPECT-- +start +end +after sleep +Caught exception: coro Exception +finally. diff --git a/vendor/swoole/tests/swoole_coroutine/exception/yield1.phpt b/vendor/swoole/tests/swoole_coroutine/exception/yield1.phpt new file mode 100755 index 0000000..a3c4606 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/exception/yield1.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_coroutine: exception before yield +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +go(function () { + try { + echo "start\n"; + throw new Exception('coro Exception'); + co::sleep(0.5); + echo "after sleep\n"; + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + } finally { + echo "finally.\n"; + } +}); + echo "end\n"; + +?> +--EXPECT-- +start +Caught exception: coro Exception +finally. +end diff --git a/vendor/swoole/tests/swoole_coroutine/forbidden_case/array_map.phpt b/vendor/swoole/tests/swoole_coroutine/forbidden_case/array_map.phpt new file mode 100755 index 0000000..e765dcc --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/forbidden_case/array_map.phpt @@ -0,0 +1,25 @@ +--TEST-- +swoole_coroutine: coro array map +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +co::create(function() { + array_map("test",array("func start\n")); + echo "co end\n"; +}); +function test($p) { + echo $p; + co::sleep(1); + echo "func end \n"; +} +echo "main end\n"; +?> +--EXPECT-- +func start +main end +func end +co end diff --git a/vendor/swoole/tests/swoole_coroutine/forbidden_case/call_user.phpt b/vendor/swoole/tests/swoole_coroutine/forbidden_case/call_user.phpt new file mode 100755 index 0000000..b1dc83a --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/forbidden_case/call_user.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_coroutine: coro call user func +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +co::create(function() { + $name = "call_user_func"; + $return = $name("test"); + echo "co end\n"; +}); + +function test() { + echo "func start\n"; + co::sleep(0.5); + echo "func end\n"; +} +echo "main end\n"; +?> +--EXPECT-- +func start +main end +func end +co end diff --git a/vendor/swoole/tests/swoole_coroutine/forbidden_case/invoke.phpt b/vendor/swoole/tests/swoole_coroutine/forbidden_case/invoke.phpt new file mode 100755 index 0000000..04fbea8 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/forbidden_case/invoke.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: coro invoke +--SKIPIF-- +<?php require __DIR__ . '/../../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../../include/bootstrap.php'; + +use Swoole\Coroutine as co; +co::create(function() { + $function = new ReflectionFunction('foo'); + $function->invoke(); + echo "co end\n"; +}); +function foo() { + echo "func start\n"; + co::sleep(0.5); + echo "func end\n"; +} +echo "main end\n"; +?> +--EXPECT-- +func start +main end +func end +co end diff --git a/vendor/swoole/tests/swoole_coroutine/nested1.phpt b/vendor/swoole/tests/swoole_coroutine/nested1.phpt new file mode 100755 index 0000000..7aa5c0b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/nested1.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: coro channel +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + co::sleep(1.0); + go(function () { + echo "co[2] start\n"; + co::sleep(1.0); + echo "co[2] exit\n"; + }); + echo "co[1] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +end +co[2] start +co[1] exit +co[2] exit diff --git a/vendor/swoole/tests/swoole_coroutine/nested2.phpt b/vendor/swoole/tests/swoole_coroutine/nested2.phpt new file mode 100755 index 0000000..9f3d543 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/nested2.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: coro nested2 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + go(function () { + echo "co[2] start\n"; + co::sleep(2.0); + echo "co[2] exit\n"; + }); + co::sleep(1.0); + echo "co[1] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +co[2] start +end +co[1] exit +co[2] exit diff --git a/vendor/swoole/tests/swoole_coroutine/nested3.phpt b/vendor/swoole/tests/swoole_coroutine/nested3.phpt new file mode 100755 index 0000000..fbd63cf --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/nested3.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: coro nested3 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + go(function () { + echo "co[2] start\n"; + co::sleep(1.0); + echo "co[2] exit\n"; + }); + co::sleep(2.0); + echo "co[1] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +co[2] start +end +co[2] exit +co[1] exit diff --git a/vendor/swoole/tests/swoole_coroutine/nested_empty.phpt b/vendor/swoole/tests/swoole_coroutine/nested_empty.phpt new file mode 100755 index 0000000..a347cd7 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/nested_empty.phpt @@ -0,0 +1,22 @@ +--TEST-- +swoole_coroutine: coro nested empty +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + go(function () { + echo "co[2] start\n"; + echo "co[2] exit\n"; + }); + echo "co[1] exit\n"; +}); +?> +--EXPECT-- +co[1] start +co[2] start +co[2] exit +co[1] exit diff --git a/vendor/swoole/tests/swoole_coroutine/nested_uid.phpt b/vendor/swoole/tests/swoole_coroutine/nested_uid.phpt new file mode 100755 index 0000000..dc2a49b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/nested_uid.phpt @@ -0,0 +1,36 @@ +--TEST-- +swoole_coroutine: coro nested strict +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +assert(Co::getuid() === -1); +go(function () { + assert(Co::getuid() === 1); + Co::sleep(0.01); + assert(Co::getuid() === 1); +}); +assert(Co::getuid() === -1); +go(function () { + assert(Co::getuid() === 2); + + go(function () { + assert(Co::getuid() === 3); + go(function () { + assert(Co::getuid() === 4); + go(function () { + assert(Co::getuid() === 5); + Co::sleep(0.01); + assert(Co::getuid() === 5); + }); + assert(Co::getuid() === 4); + }); + assert(Co::getuid() === 3); + }); + assert(Co::getuid() === 2); +}); +assert(Co::getuid() === -1); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine/no_inline_func.phpt b/vendor/swoole/tests/swoole_coroutine/no_inline_func.phpt new file mode 100755 index 0000000..2255d61 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/no_inline_func.phpt @@ -0,0 +1,31 @@ +--TEST-- +swoole_coroutine: coro not inline function +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +echo "start\n"; +co::create(function () { + $ret = test(); + echo $ret; +}); +function test() +{ + echo "start func\n"; + co::sleep(0.5); + echo "end func\n"; + return "return func params\n"; +} +echo "end\n"; +?> +--EXPECT-- +start +start func +end +end func +return func params diff --git a/vendor/swoole/tests/swoole_coroutine/parallel1.phpt b/vendor/swoole/tests/swoole_coroutine/parallel1.phpt new file mode 100755 index 0000000..236e510 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/parallel1.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_coroutine: coro parallel1 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + co::sleep(1.0); + echo "co[1] exit\n"; +}); + +go(function () { + echo "co[2] start\n"; + co::sleep(2.0); + echo "co[2] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +co[2] start +end +co[1] exit +co[2] exit + diff --git a/vendor/swoole/tests/swoole_coroutine/parallel2.phpt b/vendor/swoole/tests/swoole_coroutine/parallel2.phpt new file mode 100755 index 0000000..c64f497 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/parallel2.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_coroutine: coro parallel2 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + co::sleep(2.0); + echo "co[1] exit\n"; +}); + +go(function () { + echo "co[2] start\n"; + co::sleep(1.0); + echo "co[2] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +co[2] start +end +co[2] exit +co[1] exit diff --git a/vendor/swoole/tests/swoole_coroutine/parallel3.phpt b/vendor/swoole/tests/swoole_coroutine/parallel3.phpt new file mode 100755 index 0000000..1d4299b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/parallel3.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_coroutine: coro parallel3 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +go(function () { + echo "co[1] start\n"; + co::sleep(2.0); + echo "co[1] exit\n"; +}); + +go(function () { + echo "co[2] start\n"; + go(function () { + echo "co[3] start\n"; + co::sleep(3.0); + echo "co[3] exit\n"; + }); + co::sleep(1.0); + echo "co[2] exit\n"; +}); +echo "end\n"; +?> +--EXPECT-- +co[1] start +co[2] start +co[3] start +end +co[2] exit +co[1] exit +co[3] exit diff --git a/vendor/swoole/tests/swoole_coroutine/use_process.phpt b/vendor/swoole/tests/swoole_coroutine/use_process.phpt new file mode 100755 index 0000000..1001d84 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/use_process.phpt @@ -0,0 +1,85 @@ +--TEST-- +swoole_server: user process + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager(); + +const SIZE = 8192 * 5; +const TIMES = 10; +$pm->parentFunc = function ($pid) { + $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set([ + "open_eof_check" => true, + "package_eof" => "\r\n\r\n" + ]); + $r = $client->connect("127.0.0.1", 9503, - 1); + if ($r === false) { + echo "ERROR"; + exit(); + } + $client->send("SUCCESS"); + for ($i = 0; $i < TIMES; $i ++) { + $ret = $client->recv(); + assert(strlen($ret) == SIZE + 4); + } + $client->close(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new \swoole_server("127.0.0.1", 9503); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null' + ]); + + $proc = new swoole\process(function ($process) use ($serv) { + $data = json_decode($process->read(), true); + for ($i = 0; $i < TIMES/2; $i ++) { + go (function() use ($serv,$data, $i){ + //echo "user sleep start\n"; + co::sleep(0.01); + //echo "user sleep end\n"; + $serv->send($data['fd'], str_repeat('A', SIZE) . "\r\n\r\n"); + //echo "user process $i send ok\n"; + }); + } + }, false, true); + + $serv->addProcess($proc); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) use ($proc) { + $proc->write(json_encode([ + 'fd' => $fd + ])); + for ($i = 0; $i < TIMES/2; $i ++) { + go (function() use ($serv,$fd, $i){ + //echo "worker sleep start\n"; + co::sleep(0.01); + //echo "worker sleep end\n"; + $serv->send($fd, str_repeat('A', SIZE) . "\r\n\r\n"); + //echo "worker send $i ok\n"; + }); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine/user_coroutine.phpt b/vendor/swoole/tests/swoole_coroutine/user_coroutine.phpt new file mode 100755 index 0000000..345c3dd --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/user_coroutine.phpt @@ -0,0 +1,70 @@ +--TEST-- +swoole_coroutine: user coroutine +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +use Swoole\Coroutine\Http\Client as HttpClient; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + assert(strlen($data) > 1024); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + Swoole\Coroutine::create(function () use ($response) + { + $url = 'http://news.bitauto.com/xinche/'; + $components = parse_url($url); + + if (!isset($components['host'])) + { + throw new \Exception("{$url} parse no host"); + } + + $host = $components['host']; + + $ip = swoole_async_dns_lookup_coro($host); + $port = isset($components['port']) ? $components['port'] : 80; + $client = new HttpClient($ip, $port); + + $client->setHeaders([ + 'Host' => $host, + 'User-Agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0', + ]); + $client->set(['timeout' => 10]); + $client->get(isset($components['path']) ? $components['path'] : '/'); + $response->end($client->body); + }); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_coroutine/user_coroutine_2.phpt b/vendor/swoole/tests/swoole_coroutine/user_coroutine_2.phpt new file mode 100755 index 0000000..926daf8 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine/user_coroutine_2.phpt @@ -0,0 +1,16 @@ +--TEST-- +swoole_coroutine: user coroutine +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +Swoole\Coroutine::create(function () +{ + echo "OK\n"; +}); + +?> +--EXPECT-- +OK \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_channel/1.phpt b/vendor/swoole/tests/swoole_coroutine_channel/1.phpt new file mode 100755 index 0000000..b052c2a --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/1.phpt @@ -0,0 +1,66 @@ +--TEST-- +swoole_coroutine: consumer first with select mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(); +//consumer first with select mode +$num = 10; +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; +?> +--EXPECT-- +select yield +push start +main end +select resume res: true +pop [#0] ret:'data-0' +push [#0] ret:true +pop [#1] ret:'data-1' +push [#1] ret:true +pop [#2] ret:'data-2' +push [#2] ret:true +pop [#3] ret:'data-3' +push [#3] ret:true +pop [#4] ret:'data-4' +push [#4] ret:true +pop [#5] ret:'data-5' +push [#5] ret:true +pop [#6] ret:'data-6' +push [#6] ret:true +pop [#7] ret:'data-7' +push [#7] ret:true +pop [#8] ret:'data-8' +push [#8] ret:true +pop [#9] ret:'data-9' +push [#9] ret:true diff --git a/vendor/swoole/tests/swoole_coroutine_channel/2.phpt b/vendor/swoole/tests/swoole_coroutine_channel/2.phpt new file mode 100755 index 0000000..2b8a071 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/2.phpt @@ -0,0 +1,56 @@ +--TEST-- +swoole_coroutine: consumer first without select mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(); +//consumer first without select mode +$num = 10; +go(function () use ($c1, $num) { + echo "pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; +?> +--EXPECT-- +pop start +push start +main end +pop [#0] ret:'data-0' +push [#0] ret:true +pop [#1] ret:'data-1' +push [#1] ret:true +pop [#2] ret:'data-2' +push [#2] ret:true +pop [#3] ret:'data-3' +push [#3] ret:true +pop [#4] ret:'data-4' +push [#4] ret:true +pop [#5] ret:'data-5' +push [#5] ret:true +pop [#6] ret:'data-6' +push [#6] ret:true +pop [#7] ret:'data-7' +push [#7] ret:true +pop [#8] ret:'data-8' +push [#8] ret:true +pop [#9] ret:'data-9' +push [#9] ret:true + diff --git a/vendor/swoole/tests/swoole_coroutine_channel/3.phpt b/vendor/swoole/tests/swoole_coroutine_channel/3.phpt new file mode 100755 index 0000000..74a743d --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/3.phpt @@ -0,0 +1,65 @@ +--TEST-- +swoole_coroutine: product first with select mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(1); +//product first with select mode +$num = 10; +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); +echo "main end\n"; +?> +--EXPECT-- +push start +push [#0] ret:true +select yield +select resume res: true +pop [#0] ret:'data-0' +main end +pop [#1] ret:'data-1' +push [#1] ret:true +pop [#2] ret:'data-2' +push [#2] ret:true +pop [#3] ret:'data-3' +push [#3] ret:true +pop [#4] ret:'data-4' +push [#4] ret:true +pop [#5] ret:'data-5' +push [#5] ret:true +pop [#6] ret:'data-6' +push [#6] ret:true +pop [#7] ret:'data-7' +push [#7] ret:true +pop [#8] ret:'data-8' +push [#8] ret:true +pop [#9] ret:'data-9' +push [#9] ret:true diff --git a/vendor/swoole/tests/swoole_coroutine_channel/4.phpt b/vendor/swoole/tests/swoole_coroutine_channel/4.phpt new file mode 100755 index 0000000..6c84c5b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/4.phpt @@ -0,0 +1,54 @@ +--TEST-- +swoole_coroutine: product first without select mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(2); +//product first without select mode +$num = 10; +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1, $num) { + echo "pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c1->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); +echo "main end\n"; +?> +--EXPECT-- +push start +push [#0] ret:true +push [#1] ret:true +pop start +pop [#0] ret:'data-0' +pop [#1] ret:'data-1' +main end +pop [#2] ret:'data-2' +push [#2] ret:true +pop [#3] ret:'data-3' +push [#3] ret:true +pop [#4] ret:'data-4' +push [#4] ret:true +pop [#5] ret:'data-5' +push [#5] ret:true +pop [#6] ret:'data-6' +push [#6] ret:true +pop [#7] ret:'data-7' +push [#7] ret:true +pop [#8] ret:'data-8' +push [#8] ret:true +pop [#9] ret:'data-9' +push [#9] ret:true diff --git a/vendor/swoole/tests/swoole_coroutine_channel/5.phpt b/vendor/swoole/tests/swoole_coroutine_channel/5.phpt new file mode 100755 index 0000000..a5eb968 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/5.phpt @@ -0,0 +1,73 @@ +--TEST-- +swoole_coroutine: push with sleep +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(); + +$num = 10; +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + echo "select yield\n"; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("data-$i"); + echo "push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; +?> +--EXPECT-- +select yield +push start +main end +select resume res: true +pop [#0] ret:'data-0' +push [#0] ret:true +pop [#1] ret:'data-1' +push [#1] ret:true +start sleep +end sleep +pop [#2] ret:'data-2' +push [#2] ret:true +pop [#3] ret:'data-3' +push [#3] ret:true +pop [#4] ret:'data-4' +push [#4] ret:true +pop [#5] ret:'data-5' +push [#5] ret:true +pop [#6] ret:'data-6' +push [#6] ret:true +pop [#7] ret:'data-7' +push [#7] ret:true +pop [#8] ret:'data-8' +push [#8] ret:true +pop [#9] ret:'data-9' +push [#9] ret:true diff --git a/vendor/swoole/tests/swoole_coroutine_channel/basic.phpt b/vendor/swoole/tests/swoole_coroutine_channel/basic.phpt new file mode 100755 index 0000000..cd0ebcd --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +swoole_coroutine: coro channel +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +use Swoole\Coroutine as co; +$chan = new co\Channel(1); +co::create(function () use ($chan) { + for($i=1; $i<=10; $i++) { + co::sleep(0.01); + $chan->push(['rand' => rand(1000, 9999), 'index' => $i]); + echo "$i\n"; + } +}); + +co::create(function () use ($chan) { + for($i=0; $i<10; $i++) { + $data = $chan->pop(); + assert(!empty($data)); + } +}); + +swoole_event::wait(); + +?> +--EXPECT-- +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/vendor/swoole/tests/swoole_coroutine_channel/chan_select_timeout.phpt b/vendor/swoole/tests/swoole_coroutine_channel/chan_select_timeout.phpt new file mode 100755 index 0000000..84d5ddf --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/chan_select_timeout.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_coroutine: coro channel select timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +$chan = new co\Channel(1); + +go(function () use ($chan) { + $read_list = [$chan]; + $write_list = null; + $result = chan::select($read_list, $write_list, 0.1); + assert($result == false); +}); + +swoole_event::wait(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine_channel/chan_stats.phpt b/vendor/swoole/tests/swoole_coroutine_channel/chan_stats.phpt new file mode 100755 index 0000000..f824f8d --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/chan_stats.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_coroutine: coro channel stats +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$chan = new chan(10); + +go(function () use ($chan) { + $chan->push(1); + $chan->push(2); + $chan->push("hello world"); + $chan->push([1, 3, 4, 4, 6]); + assert($chan->stats()['queue_num'] == 4); + + $chan->pop(); + $chan->pop(); + $chan->pop(); + $chan->pop(); + assert($chan->stats()['queue_num'] == 0); +}); + +swoole_event::wait(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine_channel/coro_wait.phpt b/vendor/swoole/tests/swoole_coroutine_channel/coro_wait.phpt new file mode 100755 index 0000000..ca608a9 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/coro_wait.phpt @@ -0,0 +1,85 @@ +--TEST-- +swoole_coroutine: coroutine wait +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + $data = curlGet('http://127.0.0.1:9503/'); + assert(!empty($data)); + $json = json_decode($data, true); + assert(is_array($json)); + assert(isset($json['www.qq.com']) and $json['www.qq.com'] > 1024); + assert(isset($json['www.163.com']) and $json['www.163.com'] > 1024); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_http_server("127.0.0.1", 9503, SWOOLE_BASE); +// $serv->set(["worker_num" => 1, 'log_file' => '/dev/null',]); + $serv->on("WorkerStart", function (\swoole_server $serv, $worker_id) use ($pm) { + $pm->wakeup(); + }); + $serv->on('request', function ($req, $resp) { + + $chan = new chan(2); + go(function () use ($chan) { + $cli = new Swoole\Coroutine\Http\Client('www.qq.com', 80); + $cli->set(['timeout' => 10]); + $cli->setHeaders([ + 'Host' => "www.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $ret = $cli->get('/'); + if ($ret) + { + $chan->push(['www.qq.com' => strlen($cli->body)]); + } + else + { + $chan->push(['www.qq.com' => 0]); + } + }); + + go(function () use ($chan) { + $cli = new Swoole\Coroutine\Http\Client('www.163.com', 80); + $cli->set(['timeout' => 10]); + $cli->setHeaders([ + 'Host' => "www.163.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $ret = $cli->get('/'); + if ($ret) + { + $chan->push(['www.163.com' => strlen($cli->body)]); + } + else + { + $chan->push(['www.163.com' => 0]); + } + }); + + $result = []; + for ($i = 0; $i < 2; $i++) + { + $result += $chan->pop(); + } + $resp->end(json_encode($result)); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_coroutine_channel/fibonacci.phpt b/vendor/swoole/tests/swoole_coroutine_channel/fibonacci.phpt new file mode 100755 index 0000000..c05ff5a --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/fibonacci.phpt @@ -0,0 +1,55 @@ +--TEST-- +swoole_coroutine: fibonacci +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$c1 = new chan(); +$c2 = new chan(); +function fibonacci($c1, $c2) +{ + go(function () use ($c1, $c2) { + $a = 0; + $b = 1; + while(1) { + $read_list = [$c2]; + $write_list = [$c1]; + $result = chan::select($read_list, $write_list, 2); + if ($write_list) { + $t = $a + $b; + $a = $b; + $b = $t; + $c1->push($a); + } + if ($read_list) { + $ret = $c2->pop(); + if ($ret === 1) { + return 1; + } + } + } + }); +} +$num = 10; +go(function () use ($c1, $c2, $num) { + for ($i = 0; $i < $num; $i ++) { + $ret = $c1->pop(); + echo "fibonacci @$i $ret\n"; + } + $c2->push(1); +}); +fibonacci($c1, $c2); +?> +--EXPECT-- +fibonacci @0 1 +fibonacci @1 1 +fibonacci @2 2 +fibonacci @3 3 +fibonacci @4 5 +fibonacci @5 8 +fibonacci @6 13 +fibonacci @7 21 +fibonacci @8 34 +fibonacci @9 55 diff --git a/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan.phpt b/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan.phpt new file mode 100755 index 0000000..3d8dae5 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan.phpt @@ -0,0 +1,110 @@ +--TEST-- +swoole_coroutine: hybird channel +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$c1 = new chan(); +$c2 = new chan(10); +$num = 10; +go(function () use ($c2,$num) { + for ($i=0;$i<$num;$i++) + { + $ret = $c2->push("chan2-$i"); + echo "chan 2 push [#$i] ret:".var_export($ret,1)."\n"; + } +}); +go(function () use ($c1,$num) { + $read_list = [$c1]; + $write_list = null; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + if ($read_list) + { + foreach($read_list as $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + echo "chan1 pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "chan1 push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("chan1-$i"); + echo "chan1 push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); + +go(function () use ($c2,$num) { + echo "chan2 pop start\n"; + for ($i=0;$i<$num;$i++) + { + $ret = $c2->pop(); + echo "chan2 pop [#$i] ret:".var_export($ret,1)."\n"; + } +}); +echo "main end\n"; +?> +--EXPECT-- +chan 2 push [#0] ret:true +chan 2 push [#1] ret:true +chan 2 push [#2] ret:true +chan 2 push [#3] ret:true +chan 2 push [#4] ret:true +chan 2 push [#5] ret:true +chan 2 push [#6] ret:true +chan 2 push [#7] ret:true +chan 2 push [#8] ret:true +chan 2 push [#9] ret:true +chan1 push start +chan2 pop start +chan2 pop [#0] ret:'chan2-0' +chan2 pop [#1] ret:'chan2-1' +chan2 pop [#2] ret:'chan2-2' +chan2 pop [#3] ret:'chan2-3' +chan2 pop [#4] ret:'chan2-4' +chan2 pop [#5] ret:'chan2-5' +chan2 pop [#6] ret:'chan2-6' +chan2 pop [#7] ret:'chan2-7' +chan2 pop [#8] ret:'chan2-8' +chan2 pop [#9] ret:'chan2-9' +main end +select resume res: true +chan1 pop [#0] ret:'chan1-0' +chan1 push [#0] ret:true +chan1 pop [#1] ret:'chan1-1' +chan1 push [#1] ret:true +start sleep +end sleep +chan1 pop [#2] ret:'chan1-2' +chan1 push [#2] ret:true +chan1 pop [#3] ret:'chan1-3' +chan1 push [#3] ret:true +chan1 pop [#4] ret:'chan1-4' +chan1 push [#4] ret:true +chan1 pop [#5] ret:'chan1-5' +chan1 push [#5] ret:true +chan1 pop [#6] ret:'chan1-6' +chan1 push [#6] ret:true +chan1 pop [#7] ret:'chan1-7' +chan1 push [#7] ret:true +chan1 pop [#8] ret:'chan1-8' +chan1 push [#8] ret:true +chan1 pop [#9] ret:'chan1-9' +chan1 push [#9] ret:true + diff --git a/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan2.phpt b/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan2.phpt new file mode 100755 index 0000000..e0a215f --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_channel/hybird_chan2.phpt @@ -0,0 +1,102 @@ +--TEST-- +swoole_coroutine: hybird channel select +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$c1 = new chan(); +$c2 = new chan(10); +$num = 10; +go(function () use ($c2,$num) { + for ($i=0;$i<$num;$i++) + { + $ret = $c2->push("chan2-$i"); + echo "chan 2 push [#$i] ret:".var_export($ret,1)."\n"; + } +}); + +go(function () use ($c1,$c2,$num) { + $ori_list = $read_list = [$c1,$c2]; + $write_list = null; + $result = chan::select($read_list, $write_list, 2); + echo "select resume res: ".var_export($result,1)."\n"; + + if ($ori_list) + { + foreach ($ori_list as $chan => $ch) + { + for ($i=0;$i<$num;$i++) + { + $ret = $ch->pop(); + $chan_id = $chan + 1; + echo "chan{$chan_id} pop [#$i] ret:".var_export($ret,1)."\n"; + } + } + } +}); + +go(function () use ($c1,$num) { + echo "chan1 push start\n"; + for ($i=0;$i<$num;$i++) + { + if ($i == 2) { + echo "start sleep\n"; + co:sleep(1); + echo "end sleep\n"; + } + $ret = $c1->push("chan1-$i"); + echo "chan1 push [#$i] ret:".var_export($ret,1)."\n"; + } + +}); +echo "main end\n"; +?> +--EXPECT-- +chan 2 push [#0] ret:true +chan 2 push [#1] ret:true +chan 2 push [#2] ret:true +chan 2 push [#3] ret:true +chan 2 push [#4] ret:true +chan 2 push [#5] ret:true +chan 2 push [#6] ret:true +chan 2 push [#7] ret:true +chan 2 push [#8] ret:true +chan 2 push [#9] ret:true +select resume res: true +chan1 push start +main end +chan1 pop [#0] ret:'chan1-0' +chan1 push [#0] ret:true +chan1 pop [#1] ret:'chan1-1' +chan1 push [#1] ret:true +start sleep +end sleep +chan1 pop [#2] ret:'chan1-2' +chan1 push [#2] ret:true +chan1 pop [#3] ret:'chan1-3' +chan1 push [#3] ret:true +chan1 pop [#4] ret:'chan1-4' +chan1 push [#4] ret:true +chan1 pop [#5] ret:'chan1-5' +chan1 push [#5] ret:true +chan1 pop [#6] ret:'chan1-6' +chan1 push [#6] ret:true +chan1 pop [#7] ret:'chan1-7' +chan1 push [#7] ret:true +chan1 pop [#8] ret:'chan1-8' +chan1 push [#8] ret:true +chan1 pop [#9] ret:'chan1-9' +chan2 pop [#0] ret:'chan2-0' +chan2 pop [#1] ret:'chan2-1' +chan2 pop [#2] ret:'chan2-2' +chan2 pop [#3] ret:'chan2-3' +chan2 pop [#4] ret:'chan2-4' +chan2 pop [#5] ret:'chan2-5' +chan2 pop [#6] ret:'chan2-6' +chan2 pop [#7] ret:'chan2-7' +chan2 pop [#8] ret:'chan2-8' +chan2 pop [#9] ret:'chan2-9' +chan1 push [#9] ret:true diff --git a/vendor/swoole/tests/swoole_coroutine_util/dns_lookup.phpt b/vendor/swoole/tests/swoole_coroutine_util/dns_lookup.phpt new file mode 100755 index 0000000..a2afe2f --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/dns_lookup.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_coroutine: dns lookup +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $host = swoole_async_dns_lookup_coro('www.baidu.com'); + if ($host) + { + $response->end("OK\n"); + } + else + { + $response->end("ERROR\n"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_coroutine_util/exec.phpt b/vendor/swoole/tests/swoole_coroutine_util/exec.phpt new file mode 100755 index 0000000..76407a6 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/exec.phpt @@ -0,0 +1,18 @@ +--TEST-- +swoole_coroutine: exec +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +go(function () { + $data = co::exec('md5sum ' . TEST_IMAGE); + assert($data['code'] == 0); + assert($data['signal'] == 0); + assert(strstr($data['output'], ' ', true) === md5_file(TEST_IMAGE)); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/fgets.phpt b/vendor/swoole/tests/swoole_coroutine_util/fgets.phpt new file mode 100755 index 0000000..80829f9 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/fgets.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_coroutine: fgets +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +go(function () { + $file = __DIR__ . '/fgets.phpt'; + $fp = fopen($file, 'r'); + if (!$fp) + { + echo "ERROR\n"; + return; + } + + $data = ''; + while (1) + { + $line = co::fgets($fp); + if (empty($line) and feof($fp)) + { + break; + } + $data .= $line; +// echo $line; + } + assert(md5($data) == md5_file($file)); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/fread.phpt b/vendor/swoole/tests/swoole_coroutine_util/fread.phpt new file mode 100755 index 0000000..a9d62f2 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/fread.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_coroutine: fread +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $fp = fopen(TEST_IMAGE, 'r'); + if ($fp) + { + $data = co::fread($fp); + assert(md5($data) == md5_file(TEST_IMAGE)); + } + else + { + echo "ERROR\n"; + } +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/fwrite.phpt b/vendor/swoole/tests/swoole_coroutine_util/fwrite.phpt new file mode 100755 index 0000000..b7236a8 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/fwrite.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_coroutine: fwrite +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $file = __DIR__ . '/tmp'; + $fp = fopen($file, 'w+'); + $data = RandStr::gen(8192 * 8); + if ($fp) + { + $ret = co::fwrite($fp, $data); + if ($ret) + { + assert(md5($data) == md5_file($file)); + unlink($file); + + return; + } + } + unlink($file); + echo "ERROR\n"; +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/getaddrinfo.phpt b/vendor/swoole/tests/swoole_coroutine_util/getaddrinfo.phpt new file mode 100755 index 0000000..078f172 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/getaddrinfo.phpt @@ -0,0 +1,17 @@ +--TEST-- +swoole_coroutine: getaddrinfo +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $ip = co::getaddrinfo('www.baidu.com'); + assert(!empty($ip) and is_array($ip)); +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine_util/gethostbyname.phpt b/vendor/swoole/tests/swoole_coroutine_util/gethostbyname.phpt new file mode 100755 index 0000000..3018bea --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/gethostbyname.phpt @@ -0,0 +1,18 @@ +--TEST-- +swoole_coroutine: gethostbyname +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $ip = co::gethostbyname('www.baidu.com'); + assert($ip != false); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/gethostbyname_ipv6.phpt b/vendor/swoole/tests/swoole_coroutine_util/gethostbyname_ipv6.phpt new file mode 100755 index 0000000..ebb5561 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/gethostbyname_ipv6.phpt @@ -0,0 +1,18 @@ +--TEST-- +swoole_coroutine: gethostbyname for IPv6 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $ip = co::gethostbyname('ipv6.baidu.com', AF_INET6); + assert(!empty($ip)); +}); + +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine_util/readfile.phpt b/vendor/swoole/tests/swoole_coroutine_util/readfile.phpt new file mode 100755 index 0000000..78bf86b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/readfile.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_coroutine: Co::readFile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +go(function () { + $content = Co::readFile(TEST_IMAGE); + assert(md5_file(TEST_IMAGE) == md5($content)); +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_coroutine_util/resume1.phpt b/vendor/swoole/tests/swoole_coroutine_util/resume1.phpt new file mode 100755 index 0000000..b5f0c8b --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/resume1.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_coroutine: user suspend and resume1 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +$id = go(function(){ + $id = co::getUid(); + echo "start coro $id\n"; + co::suspend(); + echo "resume coro $id @1\n"; + co::suspend(); + echo "resume coro $id @2\n"; +}); +echo "start to resume $id @1\n"; +co::resume($id); +echo "start to resume $id @2\n"; +co::resume($id); +echo "main\n"; + +?> +--EXPECT-- +start coro 1 +start to resume 1 @1 +resume coro 1 @1 +start to resume 1 @2 +resume coro 1 @2 +main diff --git a/vendor/swoole/tests/swoole_coroutine_util/resume2.phpt b/vendor/swoole/tests/swoole_coroutine_util/resume2.phpt new file mode 100755 index 0000000..9f4a861 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/resume2.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_coroutine: user suspend and resume2 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +$map = []; +$id = go(function() use (&$map){ + $id = co::getUid(); + echo "start coro $id\n"; + $id2 = go(function(){ + $id2 = co::getUid(); + echo "start coro $id2\n"; + co::suspend(); + echo "resume coro $id2\n"; + }); + $map[2] = $id2; + co::suspend(); + echo "resume coro $id\n"; +}); +$map[1] = $id; +echo "start to resume {$map[2]}\n"; +co::resume($map[2]); +echo "start to resume {$map[1]}\n"; +co::resume($map[1]); +echo "main\n"; + +?> +--EXPECT-- +start coro 1 +start coro 2 +start to resume 2 +resume coro 2 +start to resume 1 +resume coro 1 +main diff --git a/vendor/swoole/tests/swoole_coroutine_util/resume3.phpt b/vendor/swoole/tests/swoole_coroutine_util/resume3.phpt new file mode 100755 index 0000000..1e03d30 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/resume3.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_coroutine: user suspend and resume3 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +$map = []; +$id = go(function() use (&$map){ + $id = co::getUid(); + echo "start coro $id\n"; + $id2 = go(function(){ + $id2 = co::getUid(); + echo "start coro $id2\n"; + co::suspend(); + echo "resume coro $id2\n"; + }); + $map[2] = $id2; + co::suspend(); + echo "resume coro $id\n"; +}); +$map[1] = $id; +echo "start to resume {$map[1]}\n"; +co::resume($map[1]); +echo "start to resume {$map[2]}\n"; +co::resume($map[2]); +echo "main\n"; + +?> +--EXPECT-- +start coro 1 +start coro 2 +start to resume 1 +resume coro 1 +start to resume 2 +resume coro 2 +main diff --git a/vendor/swoole/tests/swoole_coroutine_util/resume4.phpt b/vendor/swoole/tests/swoole_coroutine_util/resume4.phpt new file mode 100755 index 0000000..53ed547 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/resume4.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_coroutine: user suspend and resume4 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; +co::suspend(); +$id = go(function(){ + $id = co::getUid(); + echo "start coro $id\n"; + co::suspend(); + echo "resume coro $id\n"; +}); +echo "start to resume $id\n"; +co::resume($id); +echo "main\n"; + +?> +--EXPECTF-- +Fatal error: Swoole\Coroutine::suspend(): can not suspend outside coroutine %s diff --git a/vendor/swoole/tests/swoole_coroutine_util/sleep.phpt b/vendor/swoole/tests/swoole_coroutine_util/sleep.phpt new file mode 100755 index 0000000..69cb9b1 --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/sleep.phpt @@ -0,0 +1,19 @@ +--TEST-- +swoole_coroutine: sleep +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + co::sleep(0.5); + echo "OK"; +}); + +?> +--EXPECT-- +OK \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_coroutine_util/writefile.phpt b/vendor/swoole/tests/swoole_coroutine_util/writefile.phpt new file mode 100755 index 0000000..6d6ca5c --- /dev/null +++ b/vendor/swoole/tests/swoole_coroutine_util/writefile.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_coroutine: Co::writeFile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$content = file_get_contents(TEST_IMAGE); +$filename = __DIR__ . '/tmp_file.jpg'; +go(function () use ($filename, $content) { + $n = Co::writeFile($filename, $content); + assert(md5_file($filename) == md5_file(TEST_IMAGE)); + assert($n === filesize($filename)); + unlink($filename); +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_event/defer.phpt b/vendor/swoole/tests/swoole_event/defer.phpt new file mode 100755 index 0000000..49e5e10 --- /dev/null +++ b/vendor/swoole/tests/swoole_event/defer.phpt @@ -0,0 +1,27 @@ +--TEST-- +global_function: swoole_event_write + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +swoole_event_defer(function () { + echo "defer [1]\n"; +}); +swoole_timer_after(100, function () { + echo "timer [1]\n"; + swoole_timer_after(100, function () { + echo "timer [2]\n"; + }); + swoole_event_defer(function () { + echo "defer [2]\n"; + }); +}); +swoole_event_wait(); +?> + +--EXPECT-- +defer [1] +timer [1] +defer [2] +timer [2] diff --git a/vendor/swoole/tests/swoole_event/swoole_event.phpt b/vendor/swoole/tests/swoole_event/swoole_event.phpt new file mode 100755 index 0000000..6390e74 --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_event: swoole_event_exit + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- + +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +swoole_timer_tick(1, function() { + echo "tick\n"; + swoole_event_exit(); +}); +Swoole\Event::wait(); +?> +--EXPECT-- +tick + + diff --git a/vendor/swoole/tests/swoole_event/swoole_event_core.phpt b/vendor/swoole/tests/swoole_event/swoole_event_core.phpt new file mode 100755 index 0000000..f7f986d --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event_core.phpt @@ -0,0 +1,54 @@ +--TEST-- +swoole_event: swoole_event_exit coredump + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- + +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function dnsLookup() { + swoole_async_dns_lookup("www.qq.com", function($host, $ip) { + swoole_event_exit(); + exit(); + }); +} + +$i = 200; +while (--$i) { + $pid = pcntl_fork(); + if ($pid < 0) { + exit; + } + + if ($pid === 0) { + dnsLookup(); + exit(); + } + + pcntl_waitpid($pid, $status); + if (!pcntl_wifexited($status)) { + fprintf(STDERR, "$pid %s exit [exit_status=%d, stop_sig=%d, term_sig=%d]\n", + pcntl_wifexited($status) ? "normal": "abnormal", + pcntl_wexitstatus($status), + pcntl_wstopsig($status), + pcntl_wtermsig($status) + ); + exit(1); + } +} +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS + + diff --git a/vendor/swoole/tests/swoole_event/swoole_event_del.phpt b/vendor/swoole/tests/swoole_event/swoole_event_del.phpt new file mode 100755 index 0000000..0fe7dc4 --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event_del.phpt @@ -0,0 +1,27 @@ +--TEST-- +global_function: swoole_event_del +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30); +fwrite($fp, "GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n"); + +swoole_event_add($fp, function($fp) { + $resp = fread($fp, 8192); + //socket处理完成后,从epoll事件中移除socket + swoole_event_del($fp); + fclose($fp); +}); +Swoole\Event::wait(); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_event/swoole_event_isset.phpt b/vendor/swoole/tests/swoole_event/swoole_event_isset.phpt new file mode 100755 index 0000000..6061aff --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event_isset.phpt @@ -0,0 +1,30 @@ +--TEST-- +global_function: swoole_event_isset +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30); +fwrite($fp, "GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n"); + +swoole_event_add($fp, function ($fp) { + $resp = fread($fp, 8192); + //socket处理完成后,从epoll事件中移除socket + swoole_event_del($fp); + fclose($fp); +}); + +assert(swoole_event_isset($fp, SWOOLE_EVENT_READ) == true); +assert(swoole_event_isset($fp, SWOOLE_EVENT_WRITE) == false); +Swoole\Event::wait(); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_event/swoole_event_set.phpt b/vendor/swoole/tests/swoole_event/swoole_event_set.phpt new file mode 100755 index 0000000..d14d157 --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event_set.phpt @@ -0,0 +1,48 @@ +--TEST-- +global_function: swoole_event_set +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30); + +function write_callback($fp) { + $resp = fread($fp, 8192); + + //socket处理完成后,从epoll事件中移除socket + swoole_event_del($fp); + fclose($fp); + + echo "read_callback:SUCCESS\n"; +} + +swoole_event_add($fp, function($fp) { + $resp = fread($fp, 8192); + + //socket处理完成后,从epoll事件中移除socket + swoole_event_del($fp); + fclose($fp); + + echo "SUCCESS\n"; +}); + +#设置写事件回调函数,这会替换掉原有的写事件回调函数 +swoole_event_set($fp, null, 'write_callback', SWOOLE_EVENT_WRITE); + +swoole_event_write($fp, "GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n"); +echo "Finish"; +?> + + +--EXPECT-- +Finish + +read_callback:SUCCESS diff --git a/vendor/swoole/tests/swoole_event/swoole_event_write.phpt b/vendor/swoole/tests/swoole_event/swoole_event_write.phpt new file mode 100755 index 0000000..323facf --- /dev/null +++ b/vendor/swoole/tests/swoole_event/swoole_event_write.phpt @@ -0,0 +1,28 @@ +--TEST-- +global_function: swoole_event_write + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30); + +swoole_event_add($fp, function($fp) { + $resp = fread($fp, 8192); + + //socket处理完成后,从epoll事件中移除socket + swoole_event_del($fp); + fclose($fp); + + echo "SUCCESS\n"; +}); + +swoole_event_write($fp, "GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n"); + +echo "Finish\n"; +?> + +--EXPECT-- +Finish + +SUCCESS diff --git a/vendor/swoole/tests/swoole_function/swoole_cpu_num.phpt b/vendor/swoole/tests/swoole_function/swoole_cpu_num.phpt new file mode 100755 index 0000000..b41416d --- /dev/null +++ b/vendor/swoole/tests/swoole_function/swoole_cpu_num.phpt @@ -0,0 +1,21 @@ +--TEST-- +global_function: swoole_cpu_num +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$cpu_num = swoole_cpu_num(); +echo "cpu_num: $cpu_num"; + +?> + +--EXPECTF-- +cpu_num: %d diff --git a/vendor/swoole/tests/swoole_function/swoole_get_local_ip.phpt b/vendor/swoole/tests/swoole_function/swoole_get_local_ip.phpt new file mode 100755 index 0000000..a0e0f29 --- /dev/null +++ b/vendor/swoole/tests/swoole_function/swoole_get_local_ip.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_get_local_ip + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$ips = swoole_get_local_ip(); +foreach ($ips as $ip) { + assert(filter_var($ip, FILTER_VALIDATE_IP) === $ip); + assert(strstr($ip, ".", true) !== "127"); +} + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_function/swoole_set_process_name.phpt b/vendor/swoole/tests/swoole_function/swoole_set_process_name.phpt new file mode 100755 index 0000000..30c9448 --- /dev/null +++ b/vendor/swoole/tests/swoole_function/swoole_set_process_name.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_set_process_name + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +<?php require __DIR__ . '/../inc/skipifDarwin.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$name = "SWOOLE_PROCESS_TEST_" . rand(1, 100); +swoole_set_process_name($name); +$count = trim(`ps aux|grep $name|grep -v grep|wc -l`); +assert($count == 1); +echo "SUCCESS"; + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_function/swoole_version.phpt b/vendor/swoole/tests/swoole_function/swoole_version.phpt new file mode 100755 index 0000000..1d79202 --- /dev/null +++ b/vendor/swoole/tests/swoole_function/swoole_version.phpt @@ -0,0 +1,21 @@ +--TEST-- +global_function: swoole_version +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$version = swoole_version(); +echo "swoole_version: $version"; + +?> + +--EXPECTF-- +swoole_version: %s diff --git a/vendor/swoole/tests/swoole_http2_client/get.phpt b/vendor/swoole/tests/swoole_http2_client/get.phpt new file mode 100755 index 0000000..b42ffb0 --- /dev/null +++ b/vendor/swoole/tests/swoole_http2_client/get.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_http2_client: get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +swoole_async_dns_lookup("www.jd.com", function ($domain, $ip) +{ + $client = new Swoole\Http2\Client($ip, 443, true); + $array = array( + "host" => "www.jd.com", + "accept-encoding" => "gzip, deflate", + 'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'accept-language' => 'zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4,ja;q=0.2', + 'user-agent' => 'Mozilla/5.0 (X11; Linux x86_64) Chrome/58.0.3026.3 Safari/537.36', + ); + $client->setHeaders($array); + $client->get("/", function ($o) use ($client) + { + assert($o->statusCode == 200); + assert(strlen($o->body) > 1024); + $client->close(); + }); +}); +swoole_event::wait(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http2_client/headers.phpt b/vendor/swoole/tests/swoole_http2_client/headers.phpt new file mode 100755 index 0000000..83abb1b --- /dev/null +++ b/vendor/swoole/tests/swoole_http2_client/headers.phpt @@ -0,0 +1,28 @@ +--TEST-- +headers: http2 auto to lower +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +$domain = 'www.swoole.com'; +$client = new Swoole\Http2\Client($domain, 443, true); +$client->set([ + 'timeout' => 5, + 'ssl_host_name' => $domain +]); +// auto to-lower +$client->setHeaders([ + 'Host' => $domain, + 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip' +]); +$client->get('/', function (Swoole\Http2\Response $response) use ($client) { + echo $response->statusCode; + $client->close(); +}); +swoole_event_wait(); +?> +--EXPECT-- +200 \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http2_client_coro/headers.phpt b/vendor/swoole/tests/swoole_http2_client_coro/headers.phpt new file mode 100755 index 0000000..12991e5 --- /dev/null +++ b/vendor/swoole/tests/swoole_http2_client_coro/headers.phpt @@ -0,0 +1,32 @@ +--TEST-- +headers: http2 headers auto to lower +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +go(function () { + $domain = 'www.swoole.com'; + $cli = new Swoole\Coroutine\Http2\Client($domain, 443, true); + $cli->set([ + 'timeout' => 10, + 'ssl_host_name' => $domain + ]); + $cli->connect(); + + $req = new Swoole\Coroutine\Http2\Request; + $req->path = "/"; + // auto to-lower + $req->headers = [ + 'Host' => $domain, + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-encoding' => 'gzip', + ]; + assert($cli->send($req)); + $response = $cli->recv(); + echo $response->statusCode; +}); +?> +--EXPECT-- +200 \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/get.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/get.phpt new file mode 100755 index 0000000..e32e495 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/get.phpt @@ -0,0 +1,62 @@ +--TEST-- +swoole_coroutine: http client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Http\Client('www.qq.com', 80); + $cli->set(['timeout' => 10]); + $cli->setHeaders([ + 'Host' => "www.qq.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $ret = ($cli->get('/')); + if (!$ret) + { + $response->end("ERROR\n"); + return; + } + else + { + $response->end("OK\n"); + $cli->close(); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/get_without_content_length.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/get_without_content_length.phpt new file mode 100755 index 0000000..5690432 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/get_without_content_length.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_coroutine: http GET without Content-Length header +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +use Swoole\Coroutine as co; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) { + co::create(function () use ($pm) { + $cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 9501); + $cli->set([ + 'timeout' => 10 + ]); + $cli->setHeaders([ + 'Connection' => 'close', + 'Accept' => '*/*' + ]); + $ret = $cli->get('/'); + assert($ret == true); + assert($cli->statusCode == 200); + $pm->kill(); + echo "OK\n"; + }); + swoole_event::wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + 'log_file' => '/dev/null' + )); + $serv->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $serv->on('receive', function ($serv, $fd, $threadId, $data) + { + $serv->send($fd, "HTTP/1.1 200 OK\r\nServer: nginx\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"); + $serv->close($fd); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/head_method.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/head_method.phpt new file mode 100755 index 0000000..765fa69 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/head_method.phpt @@ -0,0 +1,22 @@ +--TEST-- +swoole_coroutine: http client with HEAD method +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +Swoole\Coroutine::create(function () +{ + $cli = new \Swoole\Coroutine\Http\Client('www.baidu.com', 80); + $cli->set(['timeout' => 10]); + $cli->setMethod("HEAD"); + $cli->get('/'); + assert($cli->statusCode == 200); + assert(count($cli->headers) > 0); +}); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/http_proxy.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/http_proxy.phpt new file mode 100755 index 0000000..cf677af --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/http_proxy.phpt @@ -0,0 +1,37 @@ +--TEST-- +swoole_coroutine: httpclient with http_proxy +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + co::create(function () { + $cli = new co\http\client('127.0.0.1', 9501); + $cli->setHeaders(['Host' => 'localhost']); + $cli->set(['http_proxy_host' => HTTP_PROXY_HOST, 'http_proxy_port' => HTTP_PROXY_PORT]); + $result = $cli->get('/get?json=true'); + assert($result); + $ret = json_decode($cli->body, true); + assert(is_array($ret) and $ret['json'] == 'true'); + }); + + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/https.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/https.phpt new file mode 100755 index 0000000..b4055d2 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/https.phpt @@ -0,0 +1,62 @@ +--TEST-- +swoole_coroutine: https client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli = new Swoole\Coroutine\Http\Client('www.baidu.com', 443, true); + $cli->set(['timeout' => 10]); + $cli->setHeaders([ + 'Host' => "www.baidu.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $ret = ($cli->get('/')); + if (!$ret) + { + $response->end("ERROR\n"); + return; + } + else + { + $response->end("OK\n"); + $cli->close(); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/multi.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/multi.phpt new file mode 100755 index 0000000..b7a525a --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/multi.phpt @@ -0,0 +1,76 @@ +--TEST-- +swoole_coroutine: multi http client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $cli1 = new Swoole\Coroutine\Http\Client('www.baidu.com', 443, true); + $cli1->set(['timeout' => 10]); + $cli1->setHeaders([ + 'Host' => "www.baidu.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $cli1->setDefer(1); + + $cli2 = new Swoole\Coroutine\Http\Client('www.baidu.com', 443, true); + $cli2->set(['timeout' => 10]); + $cli2->setHeaders([ + 'Host' => "www.baidu.com", + "User-Agent" => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', + ]); + $cli2->setDefer(1); + + $ret1 = ($cli1->get('/')); + $ret2 = ($cli2->get('/')); + if (!$ret1 or !$ret2) + { + $response->end("ERROR\n"); + return; + } + else + { + $cli1->close(); + $cli2->close(); + $response->end("OK\n"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/websocket.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/websocket.phpt new file mode 100755 index 0000000..39188e4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/websocket.phpt @@ -0,0 +1,75 @@ +--TEST-- +swoole_coroutine: websocket client & server +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + go(function () { + $cli = new Co\http\Client("127.0.0.1", 9501); + $cli->set(['timeout' => -1]); + $ret = $cli->upgrade("/"); + + if (!$ret) + { + echo "ERROR\n"; + return; + } + echo $cli->recv()->data; + for ($i = 0; $i < 5; $i++) + { + $cli->push("hello server"); + echo ($cli->recv())->data; + co::sleep(0.1); + } + }); + swoole_event::wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $ws = new swoole_websocket_server("127.0.0.1", 9501, SWOOLE_BASE); + $ws->set(array( + 'log_file' => '/dev/null' + )); + $ws->on("WorkerStart", function (\swoole_server $serv) { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + + $ws->on('open', function ($serv, swoole_http_request $request) { + $ip = co::gethostbyname('www.baidu.com'); + if ($ip) + { + $serv->push($request->fd, "start\n"); + } + }); + + $ws->on('message', function ($serv, $frame) { + co::sleep(0.1); + $serv->push($frame->fd, "hello client\n"); + }); + + $ws->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +start +hello client +hello client +hello client +hello client +hello client diff --git a/vendor/swoole/tests/swoole_http_cilent_coro/websocket_bug_01.phpt b/vendor/swoole/tests/swoole_http_cilent_coro/websocket_bug_01.phpt new file mode 100755 index 0000000..401e5ae --- /dev/null +++ b/vendor/swoole/tests/swoole_http_cilent_coro/websocket_bug_01.phpt @@ -0,0 +1,60 @@ +--TEST-- +swoole_coroutine: websocket handshake + frame +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +Co::set(['log_level' => SWOOLE_LOG_WARNING]); + +$pm->parentFunc = function ($pid) use ($pm) { + go(function () { + $cli = new Co\http\Client("127.0.0.1", 9501); + $ret = $cli->upgrade("/"); + if (!$ret) + { + echo "ERROR\n"; + return; + } + echo "CONNECTED\n"; + echo $cli->recv()->data; + }); + swoole_event::wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $ws = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $ws->set(array( + 'log_file' => '/dev/null' + )); + $ws->on("WorkerStart", function (\swoole_server $serv) { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + + $ws->on('receive', function ($serv, $fd, $threadId, $data) { + $sendData = "HTTP/1.1 101 Switching Protocols\r\n"; + $sendData .= "Upgrade: websocket\r\nConnection: Upgrade\r\nSec-Websocket-Accept: IFpdKwYy9wdo4gTldFLHFh3xQE0=\r\n"; + $sendData .= "Sec-Websocket-Version: 13\r\nServer: swoole-http-server\r\n\r\n"; + $sendData .= swoole_websocket_server::pack("hello world\n"); + $serv->send($fd, $sendData); + }); + + $ws->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +CONNECTED +hello world diff --git a/vendor/swoole/tests/swoole_http_client/connect_host_not_found.phpt b/vendor/swoole/tests/swoole_http_client/connect_host_not_found.phpt new file mode 100755 index 0000000..a029d1f --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/connect_host_not_found.phpt @@ -0,0 +1,22 @@ +--TEST-- +swoole_http_client: connect_host_not_found + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/connect_host_not_found.php'; +// 实际期望输出error +?> + +--EXPECT-- +error \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_client/connect_port_not_listen.phpt b/vendor/swoole/tests/swoole_http_client/connect_port_not_listen.phpt new file mode 100755 index 0000000..3e118c4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/connect_port_not_listen.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_http_client: connect_port_not_listen + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/connect_port_not_listen.php'; +?> + +--EXPECT-- +error \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_client/content_length.phpt b/vendor/swoole/tests/swoole_http_client/content_length.phpt new file mode 100755 index 0000000..9535143 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/content_length.phpt @@ -0,0 +1,48 @@ +--TEST-- +swoole_http_client: content length + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +$makeDone = function($n, $f) { + return function() use(&$n, $f) { + $n--; + if ($n === 0) { + $f(); + } + }; +}; +$done = $makeDone(2, $closeServer); + +$data = ['value' => RandStr::gen(rand(0, 1024))]; +testExecute(HTTP_SERVER_HOST, $port, null, $data, function ($httpClient) use ($data, $done) +{ + echo "SUCCESS\n"; + $done(); +}); + +testExecute(HTTP_SERVER_HOST, $port, "POST", $data, function ($httpClient) use ($data, $done) +{ + echo "SUCCESS\n"; + $done(); +}); +?> + +--EXPECT-- +SUCCESS +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_client/cookie.phpt b/vendor/swoole/tests/swoole_http_client/cookie.phpt new file mode 100755 index 0000000..aaf87c4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/cookie.phpt @@ -0,0 +1,47 @@ +--TEST-- +swoole_http_client: setCookies +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cookies = array('a' => 1, 'b' => '++'); + $cli->setCookies($cookies); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->get('/cookies', function ($cli) use ($cookies) + { + assert($cli->statusCode == 200); + $ret = json_decode($cli->body, true); + assert($ret); + assert(is_array($ret)); + assert(arrayEqual($ret, $cookies, false)); + $cli->close(); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close diff --git a/vendor/swoole/tests/swoole_http_client/download.phpt b/vendor/swoole/tests/swoole_http_client/download.phpt new file mode 100755 index 0000000..640671c --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/download.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_http_client: download file +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->download('/get_file', __DIR__.'/tmpfile', function ($cli) + { + assert($cli->statusCode == 200); + assert(md5_file($cli->downloadFile) == md5_file(TEST_IMAGE)); + $cli->close(); + unlink(__DIR__ . '/tmpfile'); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close diff --git a/vendor/swoole/tests/swoole_http_client/execute_without_method_and_content.phpt b/vendor/swoole/tests/swoole_http_client/execute_without_method_and_content.phpt new file mode 100755 index 0000000..7a8a1e0 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/execute_without_method_and_content.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_http_client: execute without method and content + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + + +$httpClient = new \swoole_http_client("115.239.210.27", "80"); +$httpClient->setData("null"); +$r = $httpClient->execute("/", function(\swoole_http_client $httpClient) { + echo "SUCCESS"; + $httpClient->close(); +}); + +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_client/get.phpt b/vendor/swoole/tests/swoole_http_client/get.phpt new file mode 100755 index 0000000..d6f1f26 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/get.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_http_client: get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + echo file_get_contents("http://127.0.0.1:9501/"); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +Done +--EXPECTREGEX-- +swoole +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_http_client/get_with_query_string.phpt b/vendor/swoole/tests/swoole_http_client/get_with_query_string.phpt new file mode 100755 index 0000000..c2edc72 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/get_with_query_string.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: get_with_query +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testHttpGet(HTTP_SERVER_HOST, $port, $_SERVER, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGKILL, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/get_without_query_string.phpt b/vendor/swoole/tests/swoole_http_client/get_without_query_string.phpt new file mode 100755 index 0000000..bce2cb9 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/get_without_query_string.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_http_client: get_without_query_string +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testHttpGet(HTTP_SERVER_HOST, $port, [], function () use ($closeServer) +{ + echo "SUCCESS"; + $closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/http_proxy.phpt b/vendor/swoole/tests/swoole_http_client/http_proxy.phpt new file mode 100755 index 0000000..25e4e49 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/http_proxy.phpt @@ -0,0 +1,35 @@ +--TEST-- +swoole_http_client: get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->setHeaders(['Host' => 'localhost']); + $cli->set(['http_proxy_host' => HTTP_PROXY_HOST, 'http_proxy_port' => HTTP_PROXY_PORT]); + $cli->get('/get?json=true', function ($cli) + { + assert($cli->statusCode == 200); + $ret = json_decode($cli->body, true); + assert(is_array($ret) and $ret['json'] == 'true'); + $cli->close(); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_client/http_request_connect_timeout.phpt b/vendor/swoole/tests/swoole_http_client/http_request_connect_timeout.phpt new file mode 100755 index 0000000..cde5558 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/http_request_connect_timeout.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_http_client: connect timeout + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_client/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +require_once __DIR__ . '/../include/api/swoole_http_client/http_request_connect_timeout.php'; +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_client/keepalive.phpt b/vendor/swoole/tests/swoole_http_client/keepalive.phpt new file mode 100755 index 0000000..f2f1de7 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/keepalive.phpt @@ -0,0 +1,98 @@ +--TEST-- +swoole_http_client: keepalive +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + echo file_get_contents("http://127.0.0.1:9501/keep"); + echo file_get_contents("http://127.0.0.1:9501/notkeep"); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'worker_num' => 1, + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + if ($pm) + { + $pm->wakeup(); + } + }); + $http->on('request', function ($request, swoole_http_response $response) use ($http) + { + $route = $request->server['request_uri']; + if ($route == '/info') + { + $response->end($request->header['connection']); + return; + } + elseif ($route == '/keep') + { + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->set(array( + 'keep_alive' => 1, + )); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) use ($response) + { + }); + $cli->on('error', function ($cli) use ($response) + { + echo "error"; + $response->end("error"); + }); + $cli->get('/info', function ($cli) use ($response) + { + $response->end($cli->body . "\n"); + $cli->close(); + }); + $http->cli = $cli; + } + elseif ($route == '/notkeep') + { + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->set(array( + 'keep_alive' => 0, + )); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) use ($response) + { + }); + $cli->on('error', function ($cli) use ($response) + { + echo "error"; + $response->end("error"); + }); + $cli->get('/info', function ($cli) use ($response) + { + $response->end($cli->body . "\n"); + }); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +Done +--EXPECTREGEX-- +keep-alive +closed +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_http_client/method_delete.phpt b/vendor/swoole/tests/swoole_http_client/method_delete.phpt new file mode 100755 index 0000000..263e8f3 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_delete.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_http_client: method_get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "DELETE", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_delete_with_payload.phpt b/vendor/swoole/tests/swoole_http_client/method_delete_with_payload.phpt new file mode 100755 index 0000000..a7c8d17 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_delete_with_payload.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_http_client: method_delete_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "DELETE", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_get.phpt b/vendor/swoole/tests/swoole_http_client/method_get.phpt new file mode 100755 index 0000000..951fec9 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_get.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_http_client: method_get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "GET", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_get_with_payload.phpt b/vendor/swoole/tests/swoole_http_client/method_get_with_payload.phpt new file mode 100755 index 0000000..e169815 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_get_with_payload.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_http_client: method_get_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "GET", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_head.phpt b/vendor/swoole/tests/swoole_http_client/method_head.phpt new file mode 100755 index 0000000..f220e47 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_head.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_http_client: HEAD method +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$cli = new swoole_http_client('jd.com'); +$cli->set(array( + 'timeout' => 3, +)); + +$cli->on('close', function ($cli) +{ + +}); +$cli->on('error', function ($cli) +{ + echo "error\n"; +}); + +$cli->setMethod('HEAD'); + +$cli->get('/', function ($cli) +{ + assert($cli->statusCode == 302); + $cli->close(); +}); +swoole_event::wait(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_http_client/method_patch.phpt b/vendor/swoole/tests/swoole_http_client/method_patch.phpt new file mode 100755 index 0000000..e95331d --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_patch.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_patch +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_patch_with_payload.phpt b/vendor/swoole/tests/swoole_http_client/method_patch_with_payload.phpt new file mode 100755 index 0000000..564ffa5 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_patch_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_patch_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_post.phpt b/vendor/swoole/tests/swoole_http_client/method_post.phpt new file mode 100755 index 0000000..39aeb1d --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_post.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_post +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "POST", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_post_with_payload.phpt b/vendor/swoole/tests/swoole_http_client/method_post_with_payload.phpt new file mode 100755 index 0000000..4af961f --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_post_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_post_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "POST", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_put.phpt b/vendor/swoole/tests/swoole_http_client/method_put.phpt new file mode 100755 index 0000000..f6e7418 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_put.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_put +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/method_put_with_payload.phpt b/vendor/swoole/tests/swoole_http_client/method_put_with_payload.phpt new file mode 100755 index 0000000..681e631 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/method_put_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: method_put_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", "put", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/post.phpt b/vendor/swoole/tests/swoole_http_client/post.phpt new file mode 100755 index 0000000..ea74537 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/post.phpt @@ -0,0 +1,49 @@ +--TEST-- +swoole_http_client: post +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->set(array( + 'timeout' => 0.3, + )); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $data = array('name' => "rango"); + $cli->post('/post', $data, function ($cli) use ($data) + { + assert($cli->statusCode == 200); + $ret = json_decode($cli->body, true); + assert($ret); + assert(is_array($ret)); + assert(arrayEqual($ret, $data, false)); + $cli->close(); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close diff --git a/vendor/swoole/tests/swoole_http_client/post_with_body.phpt b/vendor/swoole/tests/swoole_http_client/post_with_body.phpt new file mode 100755 index 0000000..73b3d18 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/post_with_body.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: post_with_body +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testPost(HTTP_SERVER_HOST, $port, $_SERVER, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/post_with_empty_content.phpt b/vendor/swoole/tests/swoole_http_client/post_with_empty_content.phpt new file mode 100755 index 0000000..e9ff41d --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/post_with_empty_content.phpt @@ -0,0 +1,49 @@ +--TEST-- +swoole_http_client: post with empty content + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + @$cli->post('/post', '', function ($cli) + { + assert($cli->statusCode == 200); + assert($cli->body == 'null'); + $cli->close(); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close + diff --git a/vendor/swoole/tests/swoole_http_client/post_without_content_length.phpt b/vendor/swoole/tests/swoole_http_client/post_without_content_length.phpt new file mode 100755 index 0000000..214bbf7 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/post_without_content_length.phpt @@ -0,0 +1,62 @@ +--TEST-- +swoole_http_client: post without content-length + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->post('/post', '{}', function ($cli) + { + assert($cli->statusCode == 200); + assert(strlen($cli->body) > 0); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server('127.0.0.1', 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set(['open_http_protocol' => true]); + $serv->on('workerStart', function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $serv->send($fd, + "HTTP/1.1 200 OK\r\nContent-Type: application/json; charset=UTF-8\r\nConnection: close\r\n\r\n{\"msg\":\"对不起,错误的请求数据.\",\"result\":2}"); + $serv->close($fd); + }); + + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close + diff --git a/vendor/swoole/tests/swoole_http_client/recursive_get.phpt b/vendor/swoole/tests/swoole_http_client/recursive_get.phpt new file mode 100755 index 0000000..635b6de --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/recursive_get.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_http_client: recursive_get + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +$cli = new \swoole_http_client("127.0.0.1", 80); +$cli->on("error", function() { /*echo "ERROR";*/ swoole_event_exit(); }); +$cli->on("close", function() { /*echo "CLOSE";*/ swoole_event_exit(); }); +$i = 0; +function get() +{ + global $cli, $i, $closeServer; + ++$i; + if ($i > 10) + { + echo "SUCCESS\n"; + $cli->close(); + $closeServer(); + } + else + { + $cli->get("/", __FUNCTION__); + } +} +get(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/request_timeout.phpt b/vendor/swoole/tests/swoole_http_client/request_timeout.phpt new file mode 100755 index 0000000..48be680 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/request_timeout.phpt @@ -0,0 +1,57 @@ +--TEST-- +swoole_http_client: request timeout + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client("127.0.0.1", 9502); + $cli->get('/', function ($c) { + assert($c->statusCode == -2); + assert($c->body == ""); + }); + swoole\event::wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new Swoole\Server("127.0.0.1", 9502, SWOOLE_BASE); + $serv->set(array( + 'worker_num' => 1, + 'log_file' => '/dev/null', + )); + $serv->on('connect', function ($serv, $fd){ + //echo "Client: Connect.\n"; + }); + $serv->on('receive', function ($serv, $fd, $rid, $data) { + sleep(1); + $serv->shutdown(); + }); + $serv->on('close', function ($serv, $fd) { +// echo "Client: Close.\n"; + }); + $serv->on('WorkerStart', function ($server) use ($pm) { + $pm->wakeup(); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_client/set_cookie_zval.phpt b/vendor/swoole/tests/swoole_http_client/set_cookie_zval.phpt new file mode 100755 index 0000000..7988806 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/set_cookie_zval.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_http_client: setHeaders & setCookies + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +$cli = new \swoole_http_client(HTTP_SERVER_HOST, $port); +$cli->on("error", function() { /*echo "ERROR";*/ swoole_event_exit(); }); +$cli->on("close", function() { /*echo "CLOSE";*/ swoole_event_exit(); }); + +function get() { + static $i = 0; + global $cli; + static $zval = [ + "headers" => ["Connection" => "keep-alive"], + "cookies" => ['name' => 'rango', 'value' => 1234], + ]; + + assert($cli->setCookies($zval["cookies"])); + + if ($i++ > 10) + { + echo "SUCCESS\n"; + $cli->close(); + } + else + { + assert($zval["cookies"]['name'] == 'rango'); + assert($zval["cookies"]['value'] == '1234'); + $cli->get("/test", __FUNCTION__); + } +} +get(); +suicide(1000, SIGKILL, $closeServer); +swoole_event_wait(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/set_headers_core1.phpt b/vendor/swoole/tests/swoole_http_client/set_headers_core1.phpt new file mode 100755 index 0000000..888e83f --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/set_headers_core1.phpt @@ -0,0 +1,76 @@ +--TEST-- +swoole_http_client: set headers core 1 + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + global $cli; + $cli = new \swoole_http_client("127.0.0.1", 9990); + $cli->on("error", function() { /*echo "ERROR";*/ swoole_event_exit(); }); + $cli->on("close", function() { /*echo "CLOSE";*/ swoole_event_exit(); }); + + function get() { + static $i = 0; + global $cli; + $cli->setHeaders([]); + if ($i > 10) { + echo "SUCCESS"; + $cli->get('/shutdown', function($cli){ + $cli->close(); + }); + } else { + $i++; + $cli->get("/lookup?topic=worker_test", __FUNCTION__); + } + } + swoole_timer_after(5000, function() { swoole_event_exit(); }); + get(); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_http_server(TCP_SERVER_HOST, 9990, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Request", function (\swoole_http_request $request, \swoole_http_response $response) use ($serv) + { + $uri = $request->server["request_uri"]; + if ($uri == '/shutdown') + { + $response->end("on"); + $serv->shutdown(); + return; + } else { + $response->end("SUCCESS"); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/set_headers_core2.phpt b/vendor/swoole/tests/swoole_http_client/set_headers_core2.phpt new file mode 100755 index 0000000..669fed9 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/set_headers_core2.phpt @@ -0,0 +1,82 @@ +--TEST-- +swoole_http_client: set headers core 2 + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + global $cli; + $cli = new \swoole_http_client("127.0.0.1", 9990); + $cli->on("error", function() { /*echo "ERROR";*/ swoole_event_exit(); }); + $cli->on("close", function() { /*echo "CLOSE";*/ swoole_event_exit(); }); + + function get() { + static $i; + global $cli; + static $zval = [ + "headers" => ["Connection" => "keep-alive"], + "cookies" => [], + ]; + + $cli->setHeaders($zval["headers"]); + + if ($i > 10) { + echo "SUCCESS"; + $cli->get('/shutdown', function($cli){ + $cli->close(); + }); + } else { + $i++; + $cli->get("/lookup?topic=worker_test", __FUNCTION__); + } + } + swoole_timer_after(5000, function() { swoole_event_exit(); }); + get(); + swoole_event_wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_http_server(TCP_SERVER_HOST, 9990, SWOOLE_BASE, SWOOLE_SOCK_TCP); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Request", function (\swoole_http_request $request, \swoole_http_response $response) use ($serv) + { + $uri = $request->server["request_uri"]; + if ($uri == '/shutdown') + { + $response->end("on"); + $serv->shutdown(); + return; + } else { + $response->end("SUCCESS"); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/test_big_body.phpt b/vendor/swoole/tests/swoole_http_client/test_big_body.phpt new file mode 100755 index 0000000..e1d6d95 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_big_body.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: post big body +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testBigBodyMethodNotSupport(HTTP_SERVER_HOST, $port, function() use($closeServer) { + $closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS +close diff --git a/vendor/swoole/tests/swoole_http_client/test_cookie.phpt b/vendor/swoole/tests/swoole_http_client/test_cookie.phpt new file mode 100755 index 0000000..2a5f9f4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_cookie.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: test cookie +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testCookie(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/test_header.phpt b/vendor/swoole/tests/swoole_http_client/test_header.phpt new file mode 100755 index 0000000..180afb4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_header.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: test header +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testHeader(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/test_header_core.phpt b/vendor/swoole/tests/swoole_http_client/test_header_core.phpt new file mode 100755 index 0000000..d189a0b --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_header_core.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_http_client: test header coredump +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +set_error_handler(function($errno) { + assert($errno === 4096); + echo "ERROR"; +}); + +testHeaderCore(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/test_request.phpt b/vendor/swoole/tests/swoole_http_client/test_request.phpt new file mode 100755 index 0000000..84b687f --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_request.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_http_client: test request +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +request(HTTP_SERVER_HOST, $port, "GET", "/", null, + ["cookie_key" => "cookie_value"], + ["header_key" => "header_value"], + function(swoole_http_client $cli) use($closeServer) { + assert($cli->body === "Hello World!"); + echo "SUCCESS";$closeServer(); + }); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/test_twice_send.phpt b/vendor/swoole/tests/swoole_http_client/test_twice_send.phpt new file mode 100755 index 0000000..c13cdda --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_twice_send.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_http_client: test twice send +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testBigBodyMethodNotSupport2(HTTP_SERVER_HOST, $port, function() use($closeServer) { + $closeServer(); +}); + +suicide(2500, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESSclose diff --git a/vendor/swoole/tests/swoole_http_client/test_uri.phpt b/vendor/swoole/tests/swoole_http_client/test_uri.phpt new file mode 100755 index 0000000..9ccde1d --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/test_uri.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_client: test server[uri] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testUri(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_http_client/timeout.phpt b/vendor/swoole/tests/swoole_http_client/timeout.phpt new file mode 100755 index 0000000..ee5cea9 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/timeout.phpt @@ -0,0 +1,89 @@ +--TEST-- +swoole_http_client: timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + echo file_get_contents("http://127.0.0.1:9501/"); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'worker_num' => 2, + 'task_worker_num' => 2, + 'log_file' => '/dev/null', + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + if ($pm) + { + $pm->wakeup(); + } + }); + $http->on('request', function ($request, swoole_http_response $response) + { + $route = $request->server['request_uri']; + if ($route == '/info') + { + $response->end("111"); + return; + } + else + { + $cli = new swoole_http_client('192.0.0.1', 9502); + $cli->setHeaders(array('User-Agent' => "swoole")); + $cli->on('close', function ($cli) use ($response) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) use ($response) + { + echo "error\n"; + $response->end("error\n"); + }); + $cli->post('/info', array('bat' => "man"), function ($cli) use ($response) + { + if ($cli->statusCode == 200) + { + $response->end($cli->body . "\n"); + } + $cli->close(); + }); + } + }); + + $http->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + + }); + + $http->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +Done +--EXPECTREGEX-- +error +error +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_http_client/upload.phpt b/vendor/swoole/tests/swoole_http_client/upload.phpt new file mode 100755 index 0000000..7550bdc --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/upload.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_http_client: upload file +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->addFile(TEST_IMAGE, 'test.jpg'); + $cli->post('/upload_file', array('name' => 'rango'), function ($cli) + { + assert($cli->statusCode == 200); + $ret = json_decode($cli->body, true); + assert($ret and is_array($ret)); + assert(md5_file(TEST_IMAGE) == $ret['md5']); + $cli->close(); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close diff --git a/vendor/swoole/tests/swoole_http_client/websocket.phpt b/vendor/swoole/tests/swoole_http_client/websocket.phpt new file mode 100755 index 0000000..9ce4fde --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/websocket.phpt @@ -0,0 +1,81 @@ +--TEST-- +swoole_http_client: websocket client send 128 messages +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const N = 128; +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->count = 0; + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->on('Message', function ($cli, $frame) + { + $cli->count++; + if ($cli->count == N) + { + echo "OK\n"; + $cli->close(); + } + }); + $cli->upgrade('/websocket', function ($cli) + { + for ($i = 0; $i < N; $i++) + { + $cli->push(str_repeat('A', rand(8192, 65536))); + } + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_websocket_server("127.0.0.1", 9501); + $serv->set(['log_file' => '/dev/null']); + $serv->count = 0; + $serv->on('Open', function ($swoole_server, $req) + { + }); + $serv->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $serv->on('Message', function ($serv, $frame) + { + $serv->count++; + if ($serv->count == N) + { + for ($i = 0; $i < N; $i++) + { + $serv->push($frame->fd, str_repeat('B', rand(8192, 65536))); + } + } + }); + $serv->on('Close', function ($swoole_server, $fd) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK +close diff --git a/vendor/swoole/tests/swoole_http_client/websocket_bad_protocol.phpt b/vendor/swoole/tests/swoole_http_client/websocket_bad_protocol.phpt new file mode 100755 index 0000000..e0cce40 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/websocket_bad_protocol.phpt @@ -0,0 +1,51 @@ +--TEST-- +swoole_http_client: websocket client with bad protocol +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const N = 128; +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->count = 0; + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->on('Message', function ($cli, $frame) + { + }); + $cli->upgrade('/websocket', function ($cli) + { + @$cli->push(str_repeat('A', rand(8192, 65536))); + assert(swoole_last_error() == 8504); + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501); + $serv->set(['log_file' => '/dev/null']); + $serv->on('Receive', function ($serv, $fd, $rid, $data) + { + $serv->send($fd, "data"); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +close + diff --git a/vendor/swoole/tests/swoole_http_client/websocket_bug_18031401.phpt b/vendor/swoole/tests/swoole_http_client/websocket_bug_18031401.phpt new file mode 100755 index 0000000..8d6e869 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/websocket_bug_18031401.phpt @@ -0,0 +1,63 @@ +--TEST-- +swoole_http_client: websocket client bug 1015 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new swoole_http_client('127.0.0.1', 9501); + $cli->on('close', function ($cli) + { + echo "close\n"; + }); + $cli->on('error', function ($cli) + { + echo "error\n"; + }); + $cli->on('Message', function ($cli, $frame) + { + echo $frame->data; + $cli->close(); + }); + $cli->upgrade('/', function ($cli) + { + echo "CONNECTED\n"; + }); + swoole_event::wait(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $ws = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $ws->set(array( + 'log_file' => '/dev/null' + )); + $ws->on("WorkerStart", function (\swoole_server $serv) { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $ws->on('receive', function ($serv, $fd, $threadId, $data) { + $sendData = "HTTP/1.1 101 Switching Protocols\r\n"; + $sendData .= "Upgrade: websocket\r\nConnection: Upgrade\r\nSec-Websocket-Accept: IFpdKwYy9wdo4gTldFLHFh3xQE0=\r\n"; + $sendData .= "Sec-Websocket-Version: 13\r\nServer: swoole-http-server\r\n\r\n"; + $sendData .= swoole_websocket_server::pack("hello world\n"); + $serv->send($fd, $sendData); + }); + $ws->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +CONNECTED +hello world +close diff --git a/vendor/swoole/tests/swoole_http_client/websocket_port_not_listen.phpt b/vendor/swoole/tests/swoole_http_client/websocket_port_not_listen.phpt new file mode 100755 index 0000000..c15fbd4 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_client/websocket_port_not_listen.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_http_client: failure of websocket client handshake +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$cli = new swoole_http_client('127.0.0.1', 9999); +$cli->count = 0; +$cli->on('close', function ($cli) +{ + echo "close\n"; +}); +$cli->on('error', function ($cli) +{ + echo "error\n"; +}); +$cli->on('Message', function ($cli, $frame) +{ + $cli->count++; +}); +$cli->upgrade('/websocket', function ($cli) +{ + @$cli->push(str_repeat('A', rand(8192, 65536))); + assert(swoole_last_error() == 8503); +}); +swoole_event::wait(); +?> +--EXPECT-- +error diff --git a/vendor/swoole/tests/swoole_http_server/chunk.phpt b/vendor/swoole/tests/swoole_http_server/chunk.phpt new file mode 100755 index 0000000..fdaf32d --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/chunk.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_http_server: http chunk +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + $data = curlGet('http://127.0.0.1:9501/'); + assert(!empty($data)); + assert(md5($data) === md5_file(TEST_IMAGE)); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set([ + //'log_file' => '/dev/null', + ]); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, $response) { + $data = str_split(file_get_contents(TEST_IMAGE), 8192); + foreach ($data as $chunk) + { + $response->write($chunk); + } + $response->end(); + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_server/cookies.phpt b/vendor/swoole/tests/swoole_http_server/cookies.phpt new file mode 100755 index 0000000..6ed30e8 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/cookies.phpt @@ -0,0 +1,97 @@ +--TEST-- +swoole_http_server: cookies +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$cookies = array ( + '8MLP_5753_saltkey' => 'RSU8HYED', + '8MLP_5753_lastvisit' => '1426120671', + 'attentiondomain' => '2z.cn,chinaz.com,kuaishang.cn,cxpcms.com', + '8MLP_5753_security_cookiereport' => 'c014Hgufskpv55xgM9UaB/ZZdMrcN0QqBYdcGomTu8OlTDWzTA0z', + '8MLP_5753_ulastactivity' => 'e4a1aRIbgdzoRDd8NlT5CMIwLnWjyjr2hWyfn6T5g82RitUOdf3o', + 'mytool_user' => 'uSHVgCUFWf5Sv2Y8tKytQRUJW3wMVT3rw5xQLNGQFIsod4C6vYWeGA==', + 'PHPSESSID' => 't3hp9h4o8rb3956t5pajnsfab1', + '8MLP_5753_st_p' => '1024432|1428040399|f7599ba9053aa27e12e9e597a4c372ce', + '8MLP_5753_st_t' => '1024432|1428040402|46d40e02d899b10b431822eb1d39f6a1', + '8MLP_5753_forum_lastvisit' => 'D_140_1427103032D_165_1427427405D_168_1427870172D_167_1427870173D_166_1428021390D_163_1428040402', + '8MLP_5753_sid' => 'k25gxK', + 'cmstop_page-view-mode' => 'view', + 'cmstop_rememberusername' => 'error', + 'cmstop_auth' => 'Jcn2qzVn9nsjqtodER9OphcW3PURDWNx6mO7j0Zbb9k=', + 'cmstop_username' => 'error', + 'Hm_lvt_aecc9715b0f5d5f7f34fba48a3c511d6' => '1427967317,1428021376,1428036617,1428040224', + 'Hm_lpvt_aecc9715b0f5d5f7f34fba48a3c511d6' => '1428050417', + 'YjVmNm_timeout' => '0', +); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($cookies) { + $client = new swoole_client(SWOOLE_SOCK_TCP); + if (!$client->connect('127.0.0.1', 9501, 1)) + { + exit("connect failed. Error: {$client->errCode}\n"); + } + $header = "GET /index.php HTTP/1.1\r\n"; + $header .= "Host: 127.0.0.1\r\n"; + $header .= "Connection: keep-alive\r\n"; + $header .= "Cache-Control: max-age=0\r\n"; + + $cookieStr = ''; + foreach($cookies as $k => $v) + { + $cookieStr .= "$k=$v; "; + } + $cookieStr .= "end=1"; + $cookies['end'] = "1"; + + $header .= "Cookie: $cookieStr\r\n"; + $header .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"; + $header .= "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36\r\n"; + $header .= "\r\n"; + $_sendStr = $header; + + $client->send($_sendStr); + $data = $client->recv(); + $client->close(); + + list(, $_respCookieStr) = explode("\r\n\r\n", $data); + + $respCookie = json_decode($_respCookieStr, true); + assert($respCookie == $cookies); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set(['log_file' => '/dev/null']); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, $response) { + $response->end(json_encode($request->cookie)); + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_http_server/enable_coroutine.phpt b/vendor/swoole/tests/swoole_http_server/enable_coroutine.phpt new file mode 100755 index 0000000..96893c9 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/enable_coroutine.phpt @@ -0,0 +1,44 @@ +--TEST-- +enable_coroutine: enable_coroutine setting in server +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/lib/curl.php'; +use Swoole\Http\Request; +use Swoole\Http\Response; +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + echo curlGet('http://127.0.0.1:9501/') . "\n"; + echo curlGet('http://127.0.0.1:9501/co') . "\n"; + echo curlGet('http://127.0.0.1:9501/co') . "\n"; + echo curlGet('http://127.0.0.1:9501/co') . "\n"; + swoole_process::kill($pid); +}; +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server('127.0.0.1', 9501); + $http->set([ + 'enable_coroutine' => false, // close build-in coroutine + 'log_level' => -1 + ]); + $http->on("request", function (Request $request, Response $response) { + $response->header("Content-Type", "text/plain"); + if ($request->server['request_uri'] == '/co') { + go(function () use ($response) { + $response->end(Co::getuid()); + }); + } else { + $response->end(Co::getuid()); + } + }); + $http->start(); +}; +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +-1 +1 +2 +3 \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_server/gzip.phpt b/vendor/swoole/tests/swoole_http_server/gzip.phpt new file mode 100755 index 0000000..7a4e528 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/gzip.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_http_server: gzip +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/gzip"); + assert(md5_file(__DIR__ . '/../../README.md') == md5($data)); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + include __DIR__ . "/../include/api/http_server.php"; +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECTREGEX-- + diff --git a/vendor/swoole/tests/swoole_http_server/large_url.phpt b/vendor/swoole/tests/swoole_http_server/large_url.phpt new file mode 100755 index 0000000..7f560c1 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/large_url.phpt @@ -0,0 +1,75 @@ +--TEST-- +swoole_http_server: large url + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + $client = new swoole_client(SWOOLE_SOCK_TCP); + $client->set(array( + 'open_tcp_nodelay' => true, + )); + if (!$client->connect('127.0.0.1', 9501, 1)) + { + exit("connect failed. Error: {$client->errCode}\n"); + } + + $len = rand(1024, 2048); + $header = "GET /home/explore/?a=".str_repeat('A', $len)." HTTP/1.1\r\n"; + $header .= "Host: 127.0.0.1\r\n"; + $header .= "Connection: keep-alive\r\n"; + $header .= "Cache-Control: max-age=0\r\n"; + $cookie = "8MLP_5753_saltkey=RSU8HYED; 8MLP_5753_lastvisit=1426120671; pgv_pvi=1454765056; CNZZDATA1000008050=684878078-1426123263-http%253A%252F%252Fcznews-team.chinaz.com%252F%7C1426485386; attentiondomain=2z.cn%2cchinaz.com%2ckuaishang.cn%2ccxpcms.com; CNZZDATA33217=cnzz_eid%3D1036784254-1426122273-http%253A%252F%252Fcznews-team.chinaz.com%252F%26ntime%3D1427414208; CNZZDATA433095=cnzz_eid%3D1613871160-1426123273-http%253A%252F%252Fcznews-team.chinaz.com%252F%26ntime%3D1427848205; CNZZDATA1254679775=309722566-1427851758-http%253A%252F%252Fcznews-team.chinaz.com%252F%7C1427851758; 8MLP_5753_security_cookiereport=c014Hgufskpv55xgM9UaB%2FZZdMrcN0QqBYdcGomTu8OlTDWzTA0z; 8MLP_5753_ulastactivity=e4a1aRIbgdzoRDd8NlT5CMIwLnWjyjr2hWyfn6T5g82RitUOdf3o; 8MLP_5753_auth=9351LJpv7Xa%2FPUylJDQgRiAONZ5HysOaj%2BqRGb6jYmpqZpRkVc2ibPXm7LAfArC%2FpIpY2Fx%2B59AHqzr843qozZWxWNZi; mytool_user=uSHVgCUFWf5Sv2Y8tKytQRUJW3wMVT3rw5xQLNGQFIsod4C6vYWeGA==; 8MLP_5753_lip=220.160.111.22%2C1428036585; pgv_si=s4245709824; PHPSESSID=t3hp9h4o8rb3956t5pajnsfab1; 8MLP_5753_st_p=1024432%7C1428040399%7Cf7599ba9053aa27e12e9e597a4c372ce; 8MLP_5753_viewid=tid_7701248; 8MLP_5753_smile=5D1; 8MLP_5753_st_t=1024432%7C1428040402%7C46d40e02d899b10b431822eb1d39f6a1; 8MLP_5753_forum_lastvisit=D_140_1427103032D_165_1427427405D_168_1427870172D_167_1427870173D_166_1428021390D_163_1428040402; 8MLP_5753_sid=k25gxK; 8MLP_5753_lastact=1428040403%09misc.php%09patch; cmstop_page-view-mode=view; cmstop_rememberusername=error; cmstop_auth=Jcn2qzVn9nsjqtodER9OphcW3PURDWNx6mO7j0Zbb9k%3D; cmstop_userid=6; cmstop_username=error; Hm_lvt_aecc9715b0f5d5f7f34fba48a3c511d6=1427967317,1428021376,1428036617,1428040224; Hm_lpvt_aecc9715b0f5d5f7f34fba48a3c511d6=1428050417; YjVmNm_timeout=0"; + $header .= "Cookie: $cookie\r\n"; + $header .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"; + $header .= "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36\r\n"; + $header .= "\r\n"; + $_sendStr = $header; + + $client->send(substr($_sendStr, 0, 512)); + usleep(200000); + $client->send(substr($_sendStr, 512, 512)); + usleep(200000); + $client->send(substr($_sendStr, 1024)); + $data = $client->recv(); + $client->close(); + + assert(!empty($data) and $data = 4096); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set(['log_file' => '/dev/null']); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, $response) { + $response->header("Content-Type", "text/plain"); + $response->end(strlen($request->get['a'])); + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_http_server/rawContent.phpt b/vendor/swoole/tests/swoole_http_server/rawContent.phpt new file mode 100755 index 0000000..7d99fc7 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/rawContent.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_http_response: rawcontent + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +$payload = RandStr::gen(1024 * 1024); +testRawcontent(HTTP_SERVER_HOST, $port, $payload, function(\swoole_http_client $cli) use($closeServer, $payload) { + assert($cli->body === $payload); + echo "SUCCESS\n"; + $closeServer(); +}); +swoole_event::wait(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_server/rawCookie.phpt b/vendor/swoole/tests/swoole_http_server/rawCookie.phpt new file mode 100755 index 0000000..9a78488 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/rawCookie.phpt @@ -0,0 +1,31 @@ +--TEST-- +swoole_http_response: rawcooki + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +$rawcontent = "HELLO"; +testRawCookie(HTTP_SERVER_HOST, $port, $rawcontent, function(\swoole_http_client $cli) use($closeServer, $rawcontent) { + assert($cli->headers["set-cookie"] === "rawcontent=$rawcontent"); + echo "SUCCESS"; + $closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_server/redirect.phpt b/vendor/swoole/tests/swoole_http_server/redirect.phpt new file mode 100755 index 0000000..b656dc7 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/redirect.phpt @@ -0,0 +1,51 @@ +--TEST-- +swoole_http_server: http redirect +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + $data = curlGet('http://127.0.0.1:9501/'); + assert(!empty($data)); + assert(md5($data) === md5_file(TEST_IMAGE)); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set([ + 'log_file' => '/dev/null', + 'enable_static_handler' => true, + 'document_root' => dirname(dirname(__DIR__)) . '/examples/', + ]); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, swoole_http_response $response) { + if ($request->server['path_info'] == '/') { + $response->redirect('/test.jpg'); + } + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_server/sendfile.phpt b/vendor/swoole/tests/swoole_http_server/sendfile.phpt new file mode 100755 index 0000000..ffdebf7 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/sendfile.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_http_server: sendfile + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_http_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_http_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testSendfile(HTTP_SERVER_HOST, $port, function(\swoole_http_client $cli) use($closeServer) { + // TODO: !!!! swoole_server send file block + //var_dump($cli); + + echo "SUCCESS"; + $closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_http_server/static_handler.phpt b/vendor/swoole/tests/swoole_http_server/static_handler.phpt new file mode 100755 index 0000000..0daecad --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/static_handler.phpt @@ -0,0 +1,49 @@ +--TEST-- +swoole_http_server: cookies +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + $data = curlGet('http://127.0.0.1:9501/test.jpg'); + assert(!empty($data)); + assert(md5($data) === md5_file(TEST_IMAGE)); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set([ + 'log_file' => '/dev/null', + 'enable_static_handler' => true, + 'document_root' => dirname(dirname(__DIR__)) . '/examples/', + ]); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, $response) { + $response->end(TEST_IMAGE); + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_server/upload.phpt b/vendor/swoole/tests/swoole_http_server/upload.phpt new file mode 100755 index 0000000..e9b56c8 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/upload.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_http_server: cookies +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1:9501"); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_POST, 1); //设置为POST方式 + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); + + $file = TEST_IMAGE; + + $post_data = array('test' => str_repeat('a', 80)); + + if (function_exists("curl_file_create")) + { + $cfile = curl_file_create($file); + $post_data['file'] = $cfile; + } + else + { + $post_data['file'] = '@' . $file; + } + + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //POST数据 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $res = curl_exec($ch); + assert(!empty($res)); + assert($res === md5_file($file)); + curl_close($ch); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $http->set(['log_file' => '/dev/null']); + + $http->on("WorkerStart", function ($serv, $wid) { + global $pm; + $pm->wakeup(); + }); + + $http->on("request", function ($request, $response) { + $response->end(md5_file($request->files['file']['tmp_name'])); + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_http_server/uploadFile.phpt b/vendor/swoole/tests/swoole_http_server/uploadFile.phpt new file mode 100755 index 0000000..d9151c2 --- /dev/null +++ b/vendor/swoole/tests/swoole_http_server/uploadFile.phpt @@ -0,0 +1,63 @@ +--TEST-- +swoole_http_server: upload file +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) +{ + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1:9501"); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); + + $post_data = array('test' => str_repeat('a', 80)); + + if (function_exists("curl_file_create")) + { + $cfile = curl_file_create(TEST_IMAGE); + $post_data['upfile'] = $cfile; + } + else + { + $post_data['upfile'] = '@' . TEST_IMAGE; + } + + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); //POST数据 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + echo curl_exec($ch); + curl_close($ch); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501); + $http->set(['log_file' => '/dev/null']); + $http->on('workerStart', function() use ($pm) { + $pm->wakeup(); + }); + $http->on('request', function ($request, $response) { + if (empty($request->files['upfile']) or md5_file(TEST_IMAGE) != md5_file($request->files['upfile']['tmp_name'])) + { + $response->end("ERROR"); + } + else + { + $response->end("OK"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_https_client/get_with_query_string.phpt b/vendor/swoole/tests/swoole_https_client/get_with_query_string.phpt new file mode 100755 index 0000000..661c517 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/get_with_query_string.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_https_client: get_with_query +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$sm = new ServerManager(__DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"); +$sm->listen(HTTP_SERVER_HOST); +$closeServer = $sm->run(); + +testHttpsGet(HTTP_SERVER_HOST, $sm->port, $_SERVER, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGKILL, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/get_without_query_string.phpt b/vendor/swoole/tests/swoole_https_client/get_without_query_string.phpt new file mode 100755 index 0000000..7a4371d --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/get_without_query_string.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: get_without_query_string +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testHttpsGet(HTTP_SERVER_HOST, $port, [], function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/http_proxy.phpt b/vendor/swoole/tests/swoole_https_client/http_proxy.phpt new file mode 100755 index 0000000..26bc430 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/http_proxy.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_https_client: get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$cli = new swoole_http_client('www.baidu.com', 443, true); +$cli->setHeaders([ + 'Host' => 'www.baidu.com', + 'User-Agent' => 'Chrome/49.0.2587.3', + 'Accept' => 'text/html,application/xhtml+xml,application/xml', + 'Accept-Encoding' => 'gzip', +]); +$cli->set(['http_proxy_host' => HTTP_PROXY_HOST, 'http_proxy_port' => HTTP_PROXY_PORT]); +$cli->get('/', function ($cli) +{ + assert($cli->statusCode == 200); + echo "SUCCESS\n"; + $cli->close(); +}); +swoole_event::wait(); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_delete.phpt b/vendor/swoole/tests/swoole_https_client/method_delete.phpt new file mode 100755 index 0000000..2b8c246 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_delete.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_https_client: method_get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "DELETE", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_delete_with_payload.phpt b/vendor/swoole/tests/swoole_https_client/method_delete_with_payload.phpt new file mode 100755 index 0000000..f91eca0 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_delete_with_payload.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_https_client: method_delete_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "DELETE", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_get.phpt b/vendor/swoole/tests/swoole_https_client/method_get.phpt new file mode 100755 index 0000000..87e8b70 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_get.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_https_client: method_get +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "GET", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_get_with_payload.phpt b/vendor/swoole/tests/swoole_https_client/method_get_with_payload.phpt new file mode 100755 index 0000000..8106ec7 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_get_with_payload.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_https_client: method_get_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "GET", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_patch.phpt b/vendor/swoole/tests/swoole_https_client/method_patch.phpt new file mode 100755 index 0000000..a75660e --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_patch.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_patch +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_patch_with_payload.phpt b/vendor/swoole/tests/swoole_https_client/method_patch_with_payload.phpt new file mode 100755 index 0000000..8b5d6ad --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_patch_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_patch_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_post.phpt b/vendor/swoole/tests/swoole_https_client/method_post.phpt new file mode 100755 index 0000000..1a3b083 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_post.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_post +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "POST", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_post_with_payload.phpt b/vendor/swoole/tests/swoole_https_client/method_post_with_payload.phpt new file mode 100755 index 0000000..99cd0b7 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_post_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_post_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "POST", "payload", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_put.phpt b/vendor/swoole/tests/swoole_https_client/method_put.phpt new file mode 100755 index 0000000..29b5fe1 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_put.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_put +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", null, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/method_put_with_payload.phpt b/vendor/swoole/tests/swoole_https_client/method_put_with_payload.phpt new file mode 100755 index 0000000..1bbd2ed --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/method_put_with_payload.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: method_put_with_payload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testMethod(HTTP_SERVER_HOST, $port, "PATCH", "put", function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/post_with_body.phpt b/vendor/swoole/tests/swoole_https_client/post_with_body.phpt new file mode 100755 index 0000000..899eab6 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/post_with_body.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: post_with_body +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testPost(HTTP_SERVER_HOST, $port, $_SERVER, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/test_cookie.phpt b/vendor/swoole/tests/swoole_https_client/test_cookie.phpt new file mode 100755 index 0000000..8db2f3b --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/test_cookie.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: test cookie +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testCookie(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/test_header.phpt b/vendor/swoole/tests/swoole_https_client/test_header.phpt new file mode 100755 index 0000000..fc8ba66 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/test_header.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: test header +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testHeader(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/test_header_core.phpt b/vendor/swoole/tests/swoole_https_client/test_header_core.phpt new file mode 100755 index 0000000..6b8f650 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/test_header_core.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_https_client: test header coredump +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +//set_error_handler(function($errno) { +// assert($errno === 4096); +// echo "ERROR"; +//}); + +testHttpsHeaderCore(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/test_request.phpt b/vendor/swoole/tests/swoole_https_client/test_request.phpt new file mode 100755 index 0000000..12d9092 --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/test_request.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_https_client: test request +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +request(HTTP_SERVER_HOST, $port, "GET", "/", null, + ["cookie_key" => "cookie_value"], + ["header_key" => "header_value"], + function(swoole_http_client $cli) use($closeServer) { + assert($cli->body === "Hello World!"); + echo "SUCCESS";$closeServer(); + }); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_https_client/test_uri.phpt b/vendor/swoole/tests/swoole_https_client/test_uri.phpt new file mode 100755 index 0000000..59ceb9f --- /dev/null +++ b/vendor/swoole/tests/swoole_https_client/test_uri.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_https_client: test server[uri] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_http_client/simple_https_client.php'; + +$simple_http_server = __DIR__ . "/../include/api/swoole_http_server/simple_https_server.php"; +$closeServer = start_server($simple_http_server, HTTP_SERVER_HOST, $port = get_one_free_port()); + +testUri(HTTP_SERVER_HOST, $port, function() use($closeServer) { + echo "SUCCESS";$closeServer(); +}); + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_lock/mutex.phpt b/vendor/swoole/tests/swoole_lock/mutex.phpt new file mode 100755 index 0000000..7c7eb63 --- /dev/null +++ b/vendor/swoole/tests/swoole_lock/mutex.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_lock: mutex + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +use Swoole\Lock; + +$lock = new Lock(LOCK::MUTEX); +assert($lock->lock()); + +if (pcntl_fork() > 0) +{ + sleep(1); + assert($lock->unlock()); + echo "[Parent] exit\n"; + pcntl_wait($status); +} +else +{ + echo "[Child] Wait Lock\n"; + assert($lock->lock()); + echo "[Child] Get Lock\n"; + assert($lock->unlock()); + exit("[Child] exit\n"); +} +?> +--EXPECT-- +[Child] Wait Lock +[Parent] exit +[Child] Get Lock +[Child] exit diff --git a/vendor/swoole/tests/swoole_lock/trylock.phpt b/vendor/swoole/tests/swoole_lock/trylock.phpt new file mode 100755 index 0000000..e2025bf --- /dev/null +++ b/vendor/swoole/tests/swoole_lock/trylock.phpt @@ -0,0 +1,35 @@ +--TEST-- +swoole_lock: trylock + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +use Swoole\Lock; + +$lock = new Lock(LOCK::MUTEX); +assert($lock->lock()); + +if (pcntl_fork() > 0) +{ + sleep(1); + assert($lock->unlock()); + assert($lock->lock()); + pcntl_wait($status); +} +else +{ + assert($lock->trylock() == false); + assert($lock->unlock()); +} +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_memory_pool/free_1.phpt b/vendor/swoole/tests/swoole_memory_pool/free_1.phpt new file mode 100755 index 0000000..7deee5a --- /dev/null +++ b/vendor/swoole/tests/swoole_memory_pool/free_1.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_memory_pool: fixed pool free [01] + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +use Swoole\Memory\Pool; +$pool = new Pool(128 * 1024, Pool::TYPE_FIXED, 1024); +$slices = array(); + +for ($i = 0; $i < 125; $i++) +{ + /** + * @var $p1 Swoole\Memory\Pool\Slice + */ + $p1 = $pool->alloc(); + if ($p1 == false) + { + echo "index=$i\n"; + break; + } + $p1->write("hello world-" . $i); + $slices[] = $p1; +} + +$p1 = $pool->alloc(); +assert($p1 == false); + +//free lasest +unset($slices[count($slices) - 1]); +$p1 = $pool->alloc(); +assert($p1 != false); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_mysql/connect_timeout.phpt b/vendor/swoole/tests/swoole_mysql/connect_timeout.phpt new file mode 100755 index 0000000..2c35e02 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/connect_timeout.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_mysql: connect timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_connect_timeout.php'; + +?> + +--EXPECT-- +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/connect_twice.phpt b/vendor/swoole/tests/swoole_mysql/connect_twice.phpt new file mode 100755 index 0000000..d9b54b5 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/connect_twice.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_mysql: connect_twice +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +fork_exec(function() { + require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_connect_twice.php'; +}); +?> +--EXPECT-- +SUCCESS +closed diff --git a/vendor/swoole/tests/swoole_mysql/query_coredump.phpt b/vendor/swoole/tests/swoole_mysql/query_coredump.phpt new file mode 100755 index 0000000..56db9cd --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/query_coredump.phpt @@ -0,0 +1,25 @@ +--TEST-- +swoole_mysql: query coredump +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +swoole_mysql_query("select 1", function($swoole_mysql, $result) { + fprintf(STDERR, "SUCCESS\n"); + $swoole_mysql->close(); +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/query_multifield.phpt b/vendor/swoole/tests/swoole_mysql/query_multifield.phpt new file mode 100755 index 0000000..2efd645 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/query_multifield.phpt @@ -0,0 +1,37 @@ +--TEST-- +swoole_mysql: query multifield +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +define('FIELD_NUM', 8192); + +$n = range(0, FIELD_NUM - 1); +$fields = implode(", ", $n); + +swoole_mysql_query("select $fields", function ($swoole_mysql, $result) +{ + global $fields; + assert(count($result[0]) == FIELD_NUM); + assert($swoole_mysql->errno === 0); + $swoole_mysql->query("select $fields", function ($swoole_mysql, $result) + { + assert(count($result[0]) == FIELD_NUM); + $swoole_mysql->close(); + }); +}); +Swoole\Event::wait(); +?> +--EXPECT-- +closed diff --git a/vendor/swoole/tests/swoole_mysql/recursive_query.phpt b/vendor/swoole/tests/swoole_mysql/recursive_query.phpt new file mode 100755 index 0000000..81f1b51 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/recursive_query.phpt @@ -0,0 +1,23 @@ +--TEST-- +swoole_mysql: recursive query +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +fork_exec(function() { + require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_recursive_query.php'; +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/refcount_test.phpt b/vendor/swoole/tests/swoole_mysql/refcount_test.phpt new file mode 100755 index 0000000..23d009c --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/refcount_test.phpt @@ -0,0 +1,22 @@ +--TEST-- +swoole_mysql: test refcount +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; +fork_exec(function() { + require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_refcout.php'; +}); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_mysql/select1.phpt b/vendor/swoole/tests/swoole_mysql/select1.phpt new file mode 100755 index 0000000..e336480 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/select1.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_mysql: select 1 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +fork_exec(function() { + swoole_mysql_query("select 1", function($mysql_result, $result) { + swoole_event_exit(); + fprintf(STDERR, "SUCCESS\n"); + }); +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/simple_insert.phpt b/vendor/swoole/tests/swoole_mysql/simple_insert.phpt new file mode 100755 index 0000000..50efc48 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/simple_insert.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_mysql: simple insert +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +fork_exec(function () { + $sql = <<<SQL +INSERT INTO `test`.`userinfo` +(`name`, `level`, `passwd`, `regtime`, `big_n`, `data`, `lastlogin_ip`, `price`, `mdate`, `mtime`, `mdatetime`, `year`, `int8_t`, `mshort`, `mtext`) +VALUES +('jack', 199, 'xuyou', '2015-01-01 18:00:00', 999000, 'null', 1270, 0.22, '1997-06-04', '21:52:33', '2018-04-17 04:16:20', 1989, 127, 32767, ''); +SQL; + swoole_mysql_query($sql, function ($swoole_mysql, $result) { + ob_start(); + assert($result === true); + assert($swoole_mysql->errno === 0); + if ($buf = ob_get_clean()) + { + fprintf(STDERR, $buf); + } + assert($swoole_mysql->insert_id > 0); + swoole_event_exit(); + fprintf(STDERR, "SUCCESS\n"); + }); +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/simple_query.phpt b/vendor/swoole/tests/swoole_mysql/simple_query.phpt new file mode 100755 index 0000000..d2dbb02 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/simple_query.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_mysql: simple query +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +swoole_mysql_query("select * from userinfo limit 2", function($mysql, $result) { + assert($mysql->errno === 0); + assert(is_array($result) and count($result) == 2); + echo "SUCCESS\n"; + $mysql->close(); +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/sql_syntax_error.phpt b/vendor/swoole/tests/swoole_mysql/sql_syntax_error.phpt new file mode 100755 index 0000000..54e17bf --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/sql_syntax_error.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_mysql: sql syntax error +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_mysql/swoole_mysql_init.php'; + +swoole_mysql_query("select", function($mysql, $result) { + if ($mysql->errno === 1064) { + fprintf(STDERR, "SUCCESS\n"); + } else { + fprintf(STDERR, "FAIL\n"); + } + $mysql->close(); +}); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/transaction.phpt b/vendor/swoole/tests/swoole_mysql/transaction.phpt new file mode 100755 index 0000000..5b32a9f --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/transaction.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_mysql: transaction begin & commit +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$swoole_mysql = new \swoole_mysql(); + +$swoole_mysql->on("close", function () +{ + echo "closed\n"; +}); + +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], function (\swoole_mysql $swoole_mysql, $result) +{ + if ($result) + { + $swoole_mysql->begin(function (\swoole_mysql $swoole_mysql) + { + assert($swoole_mysql->errno === 0); + $sql = "SELECT COUNT(*) AS cnt FROM userinfo"; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + assert($swoole_mysql->errno === 0); + $sql = "UPDATE `userinfo` SET `level` = '11' WHERE `id` = 4; "; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + $swoole_mysql->commit(function (\swoole_mysql $swoole_mysql) + { + $sql = "SELECT * FROM `userinfo` where `id` = 4;"; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + assert($swoole_mysql->errno === 0); + assert(intval($result[0]['level']) === 11); + echo "SUCCESS\n"; + $swoole_mysql->close(); + }); + }); + }); + }); + }); + } + else + { + echo "connect error [errno=$swoole_mysql->connect_errno, error=$swoole_mysql->connect_error]"; + } +}); +Swoole\Event::wait(); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql/transaction_rollback.phpt b/vendor/swoole/tests/swoole_mysql/transaction_rollback.phpt new file mode 100755 index 0000000..0a0e357 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql/transaction_rollback.phpt @@ -0,0 +1,69 @@ +--TEST-- +swoole_mysql: transaction +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$swoole_mysql = new \swoole_mysql(); + +$swoole_mysql->on("close", function () +{ + echo "closed\n"; +}); + +$swoole_mysql->connect([ + "host" => MYSQL_SERVER_HOST, + "port" => MYSQL_SERVER_PORT, + "user" => MYSQL_SERVER_USER, + "password" => MYSQL_SERVER_PWD, + "database" => MYSQL_SERVER_DB, + "charset" => "utf8mb4", +], function (\swoole_mysql $swoole_mysql, $result) +{ + if ($result) + { + $swoole_mysql->begin(function (\swoole_mysql $swoole_mysql) + { + assert($swoole_mysql->errno === 0); + $sql = "SELECT COUNT(*) AS cnt FROM userinfo"; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + assert($swoole_mysql->errno === 0); + $sql = "UPDATE `userinfo` SET `level` = '19' WHERE `id` = 4; "; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + $swoole_mysql->rollback(function (\swoole_mysql $swoole_mysql) + { + $sql = "SELECT * FROM `userinfo` where `id` = 4;"; + $swoole_mysql->query($sql, function (\swoole_mysql $swoole_mysql, $result) + { + assert($swoole_mysql->errno === 0); + assert(intval($result[0]['level']) != 19); + echo "SUCCESS\n"; + $swoole_mysql->close(); + }); + }); + }); + }); + }); + } + else + { + echo "connect error [errno=$swoole_mysql->connect_errno, error=$swoole_mysql->connect_error]"; + } +}); +Swoole\Event::wait(); +?> +--EXPECT-- +SUCCESS +closed \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/aborted_clients.phpt b/vendor/swoole/tests/swoole_mysql_coro/aborted_clients.phpt new file mode 100755 index 0000000..072f972 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/aborted_clients.phpt @@ -0,0 +1,25 @@ +--TEST-- +aborted_clients: mysql-close/reconnect/aborted-client-num +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB + ]; + assert($db->connect($server) === true); + $before_num = (int)$db->query('show status like "Aborted_clients"')[0]["Value"]; + assert($db->close() === true); + assert($db->connect($server) === true); + $after_num = (int)$db->query('show status like "Aborted_clients"')[0]["Value"]; + assert($after_num - $before_num === 0); +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/fetch.phpt b/vendor/swoole/tests/swoole_mysql_coro/fetch.phpt new file mode 100755 index 0000000..e7d8302 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/fetch.phpt @@ -0,0 +1,30 @@ +--TEST-- +fetch: use fetch to get data +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + 'fetch_mode' => true + ]; + + $db->connect($server); + + // now we can make the responses independent + $stmt = $db->prepare('SELECT `id` FROM `userinfo` LIMIT 2'); + assert($stmt->execute() === true); + assert(is_array($stmt->fetch())); + assert(is_array($stmt->fetch())); + assert($stmt->fetch() === null); + assert($stmt->fetchAll() === null); +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/fetch_mode.phpt b/vendor/swoole/tests/swoole_mysql_coro/fetch_mode.phpt new file mode 100755 index 0000000..3a138c2 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/fetch_mode.phpt @@ -0,0 +1,30 @@ +--TEST-- +fetch_mode: use fetch to get data +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + 'fetch_mode' => true + ]; + + $db->connect($server); + + // now we can make the responses independent + $stmt1 = $db->prepare('SELECT * FROM ckl LIMIT 1'); + assert($stmt1->execute() === true); + $stmt2 = $db->prepare('SELECT * FROM ckl LIMIT 2'); + assert($stmt2->execute() === true); + assert(count($stmt1->fetchAll()) === 1); + assert(count($stmt2->fetchAll()) === 2); +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/fetch_mode_twice.phpt b/vendor/swoole/tests/swoole_mysql_coro/fetch_mode_twice.phpt new file mode 100755 index 0000000..648568b --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/fetch_mode_twice.phpt @@ -0,0 +1,29 @@ +--TEST-- +fetch_mode_twice: call fetch twice +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + 'fetch_mode' => true + ]; + + $db->connect($server); + + assert($db->query("INSERT INTO ckl (`domain`,`path`,`name`) VALUES ('www.baidu.com', '/search', 'baidu')") === true); + // now we can make the responses independent + $stmt = $db->prepare('SELECT * FROM ckl LIMIT 1'); + assert($stmt->execute() === true); + assert(($ret = $stmt->fetchAll()) && is_array($ret) && count($ret) === 1); + assert($stmt->fetchAll() === null); +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/prepare_insert.phpt b/vendor/swoole/tests/swoole_mysql_coro/prepare_insert.phpt new file mode 100755 index 0000000..1a8f686 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/prepare_insert.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_coroutine: mysql prepare (insert) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $db = new co\MySQL(); + $server = array( + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + ); + + $ret1 = $db->connect($server); + if (!$ret1) { + echo "CONNECT ERROR\n"; + return; + } + + $stmt = $db->prepare('INSERT INTO ckl (`domain`,`path`,`name`) VALUES (?,?,?)'); + if (!$stmt) { + echo "PREPARE ERROR\n"; + return; + } + + $ret3 = $stmt->execute(array('www.baidu.com', '/search', 'baidu')); + if (!$ret3) { + echo "EXECUTE ERROR\n"; + return; + } + assert($stmt->insert_id > 0); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/prepare_select.phpt b/vendor/swoole/tests/swoole_mysql_coro/prepare_select.phpt new file mode 100755 index 0000000..4ced688 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/prepare_select.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_coroutine: mysql prepare (select) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $db = new co\MySQL(); + $server = array( + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + ); + + $ret1 = $db->connect($server); + if (!$ret1) { + echo "CONNECT ERROR\n"; + return; + } + + $stmt = $db->prepare('SELECT * FROM userinfo WHERE id=?'); + if (!$stmt) { + echo "PREPARE ERROR\n"; + return; + } + + $ret3 = $stmt->execute(array(10)); + if (!$ret3) { + echo "EXECUTE ERROR\n"; + return; + } + assert(count($ret3) > 0); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/procedure.phpt b/vendor/swoole/tests/swoole_mysql_coro/procedure.phpt new file mode 100755 index 0000000..9b772b9 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/procedure.phpt @@ -0,0 +1,54 @@ +--TEST-- +procedure: procedure without fetch mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB + ]; + + $clear = <<<SQL + DROP PROCEDURE IF EXISTS `reply` +SQL; + $map = [ + 'You said: "hello mysql!"', + 'Hey swoole!', + 'foo', + 'bar', + 'PHP is really the best programming language!' + ]; + $procedure = <<<SQL + CREATE DEFINER=`root`@`localhost` PROCEDURE `reply`(content varchar(255)) + BEGIN + SELECT concat('You said: \"', content, '\"'); + SELECT '$map[1]'; + SELECT '$map[2]'; + SELECT '$map[3]'; + SELECT '$map[4]'; + INSERT INTO ckl (`domain`,`path`,`name`) VALUES ('www.baidu.com', '/search', 'baidu'); + END +SQL; + + $db->connect($server); + if ($db->query($clear) && $db->query($procedure)) { + //SWOOLE + $_map = $map; + $stmt = $db->prepare('CALL reply(?)'); + $res = $stmt->execute(['hello mysql!']); + do { + assert(current($res[0]) === array_shift($_map)); + } while ($res = $stmt->nextResult()); + assert($stmt->affected_rows === 1, 'get the affected rows failed!'); + assert(empty($_map), 'there are some results lost!'); + } +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/procedure_in_fetch.phpt b/vendor/swoole/tests/swoole_mysql_coro/procedure_in_fetch.phpt new file mode 100755 index 0000000..798ed04 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/procedure_in_fetch.phpt @@ -0,0 +1,78 @@ +--TEST-- +procedure: procedure in fetch mode +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB, + 'fetch_mode' => true + ]; + + $clear = <<<SQL + DROP PROCEDURE IF EXISTS `reply` +SQL; + $map = [ + 'You said: "hello mysql!"', + 'Hey swoole!', + 'foo', + 'bar', + 'PHP is really the best programming language!' + ]; + $procedure = <<<SQL + CREATE DEFINER=`root`@`localhost` PROCEDURE `reply`(content varchar(255)) + BEGIN + SELECT concat('You said: \"', content, '\"'); + SELECT '$map[1]'; + SELECT '$map[2]'; + SELECT '$map[3]'; + SELECT '$map[4]'; + INSERT INTO ckl (`domain`,`path`,`name`) VALUES ('www.baidu.com', '/search', 'baidu'); + END +SQL; + + $db->connect($server); + if ($db->query($clear) && $db->query($procedure)) { + + //SWOOLE + $_map = $map; + $stmt = $db->prepare('CALL reply(?)'); + assert($stmt->execute(['hello mysql!']) === true); + do { + $res = $stmt->fetchAll(); + assert(current($res[0]) === array_shift($_map)); + } while ($stmt->nextResult()); + assert($stmt->affected_rows === 1, 'get the affected rows failed!'); + assert(empty($_map), 'there are some results lost!'); + + //PDO + !extension_loaded('PDO') && exit; + $_map = $map; + try { + $pdo = new PDO( + "mysql:host=" . MYSQL_SERVER_HOST . ";dbname=" . MYSQL_SERVER_DB . ";charset=utf8", + MYSQL_SERVER_USER, MYSQL_SERVER_PWD + ); + $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + $stmt = $pdo->prepare("CALL reply(?)"); + assert($stmt->execute(['hello mysql!']) === true); + do { + $res = $stmt->fetchAll(); + assert(current($res[0]) === array_shift($_map)); + } while ($ret = $stmt->nextRowset()); + assert($stmt->rowCount() === 1, 'get the affected rows failed!'); + assert(empty($_map), 'there are some results lost!'); + } catch (\PDOException $e) { + assert($e->getCode() === 2054); // not support auth plugin + } + } +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/procedure_single.phpt b/vendor/swoole/tests/swoole_mysql_coro/procedure_single.phpt new file mode 100755 index 0000000..b20b8d8 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/procedure_single.phpt @@ -0,0 +1,38 @@ +--TEST-- +swoole_coroutine: mysql procedure single +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; + +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1 + ]; + + $clear = <<<SQL + DROP PROCEDURE IF EXISTS `say` +SQL; + $procedure = <<<SQL + CREATE DEFINER=`root`@`localhost` PROCEDURE `say`(content varchar(255)) + BEGIN + SELECT concat('You said: \"', content, '\"'); + END +SQL; + + $db->connect($server); + if ($db->query($clear) && $db->query($procedure)) { + $stmt = $db->prepare('CALL say(?)'); + $ret = $stmt->execute(['hello mysql!']); + echo current($ret[0]); // You said: "hello mysql!" + } +}); +?> +--EXPECT-- +You said: "hello mysql!" \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/query.phpt b/vendor/swoole/tests/swoole_mysql_coro/query.phpt new file mode 100755 index 0000000..91c5e87 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/query.phpt @@ -0,0 +1,63 @@ +--TEST-- +swoole_coroutine: mysql client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $mysql = new Swoole\Coroutine\MySQL(); + $res = $mysql->connect([ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB + ]); + if (!$res) + { + fail: + $response->end("ERROR\n"); + return; + } + $ret = $mysql->query('show tables', 2); + if (!$ret) { + goto fail; + } + if (count($ret) > 0) { + $response->end("OK\n"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_mysql_coro/query_timeout.phpt b/vendor/swoole/tests/swoole_mysql_coro/query_timeout.phpt new file mode 100755 index 0000000..72ed11c --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/query_timeout.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_coroutine: mysql query timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +go(function (){ + $mysql = new Swoole\Coroutine\MySQL(); + $res = $mysql->connect([ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB + ]); + if (!$res) + { + fail : echo "CONNECT ERROR\n"; + + return; + } + $ret = $mysql->query('select sleep(1)', 0.2); + if (!$ret) + { + echo $mysql->errno ."\n"; + echo $mysql->error."\n"; + } + else + { + var_dump($ret); + } +}); +swoole_event::wait(); +?> +--EXPECT-- +110 +query timeout diff --git a/vendor/swoole/tests/swoole_mysql_coro/simple_query.phpt b/vendor/swoole/tests/swoole_mysql_coro/simple_query.phpt new file mode 100755 index 0000000..6e3f18b --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/simple_query.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_coroutine: mysql simple query + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +go(function () { + $mysql = new Swoole\Coroutine\MySQL(); + $res = $mysql->connect([ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB + ]); + assert($res); + $ret = $mysql->query('show tables', 2); + assert(is_array($ret)); + assert(count($ret) > 0); +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_mysql_coro/statement_destruct.phpt b/vendor/swoole/tests/swoole_mysql_coro/statement_destruct.phpt new file mode 100755 index 0000000..e66e4e0 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/statement_destruct.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_coroutine: mysql prepare (destruct) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +use Swoole\Coroutine as co; + +co::create(function () { + $db = new co\MySQL(); + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + ]; + + $ret1 = $db->connect($server); + + $start_prepared_num = (int)(($db->query('show status like \'Prepared_stmt_count\''))[0]['Value']); + if (!$ret1) { + echo "CONNECT ERROR\n"; + return; + } + $stmt1 = $db->prepare('SELECT * FROM userinfo WHERE id=?'); + if (!$stmt1) { + echo "PREPARE1 ERROR\n"; + return; + } + $stmt2 = $db->prepare('SELECT * FROM `userinfo`'); + if (!$stmt2) { + echo "PREPARE2 ERROR\n"; + return; + } + $stmt3 = $db->prepare('SELECT `id` FROM `userinfo`'); + if (!$stmt3) { + echo "PREPARE3 ERROR\n"; + return; + } + + $prepared_num1 = (int)(($db->query('show status like \'Prepared_stmt_count\''))[0]['Value']); + assert($prepared_num1 - $start_prepared_num === 3); + $stmt1 = null; //destruct + unset($stmt2); //destruct + $prepared_num2 = (int)(($db->query('show status like \'Prepared_stmt_count\''))[0]['Value']); + assert($prepared_num1 - $prepared_num2 === 2); +}); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_mysql_coro/without_fetch.phpt b/vendor/swoole/tests/swoole_mysql_coro/without_fetch.phpt new file mode 100755 index 0000000..55b5fb2 --- /dev/null +++ b/vendor/swoole/tests/swoole_mysql_coro/without_fetch.phpt @@ -0,0 +1,27 @@ +--TEST-- +without_fetch: just execute (test memory leak) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/config.php'; +go(function () { + $db = new Swoole\Coroutine\Mysql; + $server = [ + 'host' => MYSQL_SERVER_HOST, + 'user' => MYSQL_SERVER_USER1, + 'password' => MYSQL_SERVER_PWD, + 'database' => MYSQL_SERVER_DB1, + 'fetch_mode' => true + ]; + + $db->connect($server); + $stmt = $db->prepare('SELECT * FROM `userinfo` LIMIT 1'); + assert($stmt->execute() === true); + assert($stmt->execute() === true); + assert($stmt->execute() === true); + assert(is_array($stmt->fetchAll())); +}); +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/echo.py b/vendor/swoole/tests/swoole_process/echo.py new file mode 100755 index 0000000..a261ea0 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/echo.py @@ -0,0 +1,7 @@ +import sys + +def main(): + s = raw_input() + print "Python: " + s + +main() diff --git a/vendor/swoole/tests/swoole_process/process_exec.phpt b/vendor/swoole/tests/swoole_process/process_exec.phpt new file mode 100755 index 0000000..5c09c8b --- /dev/null +++ b/vendor/swoole/tests/swoole_process/process_exec.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_process: exec +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$process = new swoole_process('python_process', true); +$pid = $process->start(); + +function python_process(swoole_process $worker) +{ + $worker->exec('/usr/bin/python', array(__DIR__ . "/echo.py")); +} + +$process->write("Hello World\n"); +echo $process->read(); +?> +Done +--EXPECTREGEX-- +Python: Hello World +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_process/process_msgqueue.phpt b/vendor/swoole/tests/swoole_process/process_msgqueue.phpt new file mode 100755 index 0000000..860e673 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/process_msgqueue.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_process: sysv msgqueue +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function callback_function(swoole_process $worker){} + +$process = new swoole_process('callback_function', false, false); +$process->useQueue(); + +$bytes = 0; +foreach(range(1, 10) as $i) +{ + $data = "hello worker[$i]"; + $bytes += strlen($data); + $process->push($data); +} + +$queue = $process->statQueue(); +($queue['queue_num'] == 10 && $queue['queue_bytes'] == $bytes) + && $output = "Success\n"; + +echo $output; +$process->freeQueue(); +?> +Done +--EXPECTREGEX-- +Success +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_process/process_push.phpt b/vendor/swoole/tests/swoole_process/process_push.phpt new file mode 100755 index 0000000..88cb38c --- /dev/null +++ b/vendor/swoole/tests/swoole_process/process_push.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_process: push +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$process = new swoole_process(function(swoole_process $worker) { + + $recv = $worker->pop(); + + echo "$recv"; + sleep(2); + + $worker->exit(0); +}, false, false); + +$process->useQueue(); +$pid = $process->start(); + +$process->push("hello worker\n"); +?> +--EXPECTREGEX-- +hello worker +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_process/process_select.phpt b/vendor/swoole/tests/swoole_process/process_select.phpt new file mode 100755 index 0000000..8cd4dcf --- /dev/null +++ b/vendor/swoole/tests/swoole_process/process_select.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_process: select +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$process = new swoole_process(function (swoole_process $worker) +{ + $worker->write("hello master\n"); + $worker->exit(0); +}, false); + +$pid = $process->start(); +$r = array($process); +$w = array(); +$e = array(); +$ret = swoole_select($r, $w, $e, 1.0); +echo $process->read(); +?> +Done +--EXPECTREGEX-- +hello master +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_process/signal.phpt b/vendor/swoole/tests/swoole_process/signal.phpt new file mode 100755 index 0000000..5106a28 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/signal.phpt @@ -0,0 +1,57 @@ +--TEST-- +swoole_process: signal +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +//父进程中先设置信号 +swoole_process::signal(SIGCHLD, function () +{ + swoole_process::signal(SIGCHLD, null); + swoole_process::signal(SIGTERM, null); + echo "PARENT WAIT\n"; + swoole_event_exit(); +}); + +//测试被子进程覆盖信号 +swoole_process::signal(SIGTERM, function () { + //释放信号,否则底层会报内存泄漏 + swoole_process::signal(SIGTERM, null); + echo "PARENT SIGTERM\n"; + swoole_event_exit(); +}); + + +$pid = (new \swoole_process(function () +{ + swoole_process::signal(SIGTERM, function ($sig) { + echo "CHILD SIGTERM\n"; + swoole_process::signal(SIGTERM, function ($sig) { + echo "CHILD EXIT\n"; + swoole_event_exit(); + }); + }); +}))->start(); + +swoole_timer_after(500, function() use ($pid) { + swoole_process::kill($pid, SIGTERM); + swoole_timer_after(500, function() use ($pid) { + swoole_process::kill($pid, SIGTERM); + }); +}); +swoole_event_wait(); +?> +--EXPECT-- +CHILD SIGTERM +CHILD EXIT +PARENT WAIT + diff --git a/vendor/swoole/tests/swoole_process/swoole_process_close.phpt b/vendor/swoole/tests/swoole_process/swoole_process_close.phpt new file mode 100755 index 0000000..9cf131d --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_close.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_process: close +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +//$proc = new \swoole_process(swoole_function(\swoole_process $proc) { +// $proc->close(); +//}); +//$proc->start(); +// +//$proc = new \swoole_process(swoole_function(\swoole_process $proc) { +// usleep(200000); +// // assert(false); +//}); +//$proc->start(); +//$proc->close(); +// +// +//\swoole_process::wait(true); +//\swoole_process::wait(true); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_ctor.phpt b/vendor/swoole/tests/swoole_process/swoole_process_ctor.phpt new file mode 100755 index 0000000..e759048 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_ctor.phpt @@ -0,0 +1,25 @@ +--TEST-- +swoole_process: ctor +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function() { + assert(false); +}); +unset($proc); +echo "SUCCESS"; + + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_deamon.phpt b/vendor/swoole/tests/swoole_process/swoole_process_deamon.phpt new file mode 100755 index 0000000..465bb48 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_deamon.phpt @@ -0,0 +1,35 @@ +--TEST-- +swoole_process: deamon +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $proc) { + $r = \swoole_process::daemon(); + assert($r); + + $proc->push(posix_getpid()); +}); +$proc->useQueue(); +$forkPid = $proc->start(); +$demonPid = intval($proc->pop()); + +assert($forkPid !== $demonPid); + +\swoole_process::kill($demonPid, SIGKILL); + +\swoole_process::wait(true); +\swoole_process::wait(true); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_exec.phpt b/vendor/swoole/tests/swoole_process/swoole_process_exec.phpt new file mode 100755 index 0000000..53d4999 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_exec.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_process: exec +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $proc) { + $proc->exec("/usr/bin/printf", ["HELLO"]); +}, true); +$proc->start(); +echo $proc->read(); +$proc->exec("/usr/bin/printf", [" WORLD"]); + + +\swoole_process::wait(true); +?> +--EXPECT-- +HELLO WORLD \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_exit.phpt b/vendor/swoole/tests/swoole_process/swoole_process_exit.phpt new file mode 100755 index 0000000..4b830f6 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_exit.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_process: exit +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $proc) { + $proc->exit(9); +}); +$pid = $proc->start(); + + +$i = \swoole_process::wait(true); +assert($i["code"] === 9); + +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_freeQueue.phpt b/vendor/swoole/tests/swoole_process/swoole_process_freeQueue.phpt new file mode 100755 index 0000000..9badf3f --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_freeQueue.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_process: freeQueue +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function() {}); +$r = $proc->useQueue(); +assert($r); + +$proc->start(); +$r = $proc->freeQueue(); +assert($r); + +\swoole_process::wait(); + +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_kill.phpt b/vendor/swoole/tests/swoole_process/swoole_process_kill.phpt new file mode 100755 index 0000000..622d8c0 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_kill.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_process: kill +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function() { + sleep(PHP_INT_MAX); +}); +$pid = $proc->start(); +swoole_process::kill($pid, SIGKILL); +$i = \swoole_process::wait(true); +assert($i["signal"] === SIGKILL); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_name.phpt b/vendor/swoole/tests/swoole_process/swoole_process_name.phpt new file mode 100755 index 0000000..6c2540c --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_name.phpt @@ -0,0 +1,36 @@ +--TEST-- +swoole_process: name +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +require __DIR__ . '/../inc/skipifDarwin.inc'; +?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$name = "SWOOLE_PROCESS_TEST_" . rand(1, 100); + +$proc = new \swoole_process(function($childProc) { + global $name; + $childProc->name($name); + sleep(PHP_INT_MAX); +}); + +$pid = $proc->start(); +$count = trim(`ps aux|grep $name|grep -v grep|wc -l`); +assert($count == 1); +\swoole_process::kill($pid, SIGKILL); + +\swoole_process::wait(true); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_pop.phpt b/vendor/swoole/tests/swoole_process/swoole_process_pop.phpt new file mode 100755 index 0000000..ecc237d --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_pop.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_process: pop +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +// TODO 难道 queue不应该做成一个独立的组件,放在proc对象上啥意思 +$proc = new \swoole_process(function() { }); +$proc->useQueue(); +$proc->push("SUCCESS"); +echo $proc->pop(); +$proc->freeQueue(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_push.phpt b/vendor/swoole/tests/swoole_process/swoole_process_push.phpt new file mode 100755 index 0000000..aed3d2a --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_push.phpt @@ -0,0 +1,36 @@ +--TEST-- +swoole_process: push +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +//$proc = new \swoole_process(swoole_function() {}); +//$proc->useQueue(); +//$r = $proc->push("\0"); +// assert($r === false); +// TODO max data ? +// $r = $proc->push(str_repeat("\0", 1024 * 1024 * 8)); +// assert($r === false); +//$proc->freeQueue(); + + +$proc = new \swoole_process(function() {}); +$proc->useQueue(); +$proc->start(); +$r = $proc->push("\0"); +assert($r === true); +$proc->freeQueue(); +\swoole_process::wait(true); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_read.phpt b/vendor/swoole/tests/swoole_process/swoole_process_read.phpt new file mode 100755 index 0000000..273b244 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_read.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_process: read +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $process) { + $r = $process->write("SUCCESS"); + assert($r === 7); +}); +$r = $proc->start(); +assert($r > 0); + + +swoole_timer_after(10, function() use($proc) { + echo $proc->read(); + // swoole_event_exit(); +}); + + +\swoole_process::wait(true); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_redirect.phpt b/vendor/swoole/tests/swoole_process/swoole_process_redirect.phpt new file mode 100755 index 0000000..8712969 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_redirect.phpt @@ -0,0 +1,28 @@ +--TEST-- +swoole_process: redirect +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $proc) { + echo "SUCCESS"; +}, true); + +$proc->start(); +$r = $proc->read(); +echo "READ: $r~"; + + +\swoole_process::wait(true); +?> +--EXPECT-- +READ: SUCCESS~ \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_setaffinity.phpt b/vendor/swoole/tests/swoole_process/swoole_process_setaffinity.phpt new file mode 100755 index 0000000..5683643 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_setaffinity.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_process: setaffinity +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$r = \swoole_process::setaffinity([0]); +assert($r); + +$r = \swoole_process::setaffinity([0, 1]); +assert($r); +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_start.phpt b/vendor/swoole/tests/swoole_process/swoole_process_start.phpt new file mode 100755 index 0000000..3c00659 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_start.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_process: start +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function() { + echo "SUCCESS"; +}); +$r = $proc->start(); +assert($r > 0); +$proc->close(); + +\swoole_process::wait(true); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_useQueue.phpt b/vendor/swoole/tests/swoole_process/swoole_process_useQueue.phpt new file mode 100755 index 0000000..a18a16b --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_useQueue.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_process: useQueue +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $proc) { + echo $proc->pop(); +}); +$proc->useQueue(); +$proc->start(); +$proc->push("SUCCESS"); + +\swoole_process::wait(true); +$proc->freeQueue(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_wait.phpt b/vendor/swoole/tests/swoole_process/swoole_process_wait.phpt new file mode 100755 index 0000000..511fb3b --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_wait.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_process: wait +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function() {}); +$pid = $proc->start(); +$info = \swoole_process::wait(true); +assert($pid === $info["pid"]); +assert($info["code"] === 0); +assert($info["signal"] === 0); + +$proc = new \swoole_process(function() { exit(1); }); +$pid = $proc->start(); +$info = \swoole_process::wait(true); +assert($pid === $info["pid"]); +assert($info["code"] === 1); +assert($info["signal"] === 0); + +$proc = new \swoole_process(function() { \swoole_process::kill(posix_getpid(), SIGTERM); }); +$pid = $proc->start(); +$info = \swoole_process::wait(true); +assert($pid === $info["pid"]); +assert($info["code"] === 0); +assert($info["signal"] === SIGTERM); + +echo "SUCCESS"; +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/swoole_process_write.phpt b/vendor/swoole/tests/swoole_process/swoole_process_write.phpt new file mode 100755 index 0000000..1406b46 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/swoole_process_write.phpt @@ -0,0 +1,31 @@ +--TEST-- +swoole_process: write +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $process) { + $r = $process->write("SUCCESS"); + assert($r === 7); +}); +$r = $proc->start(); +assert($r > 0); + + +swoole_timer_after(10, function() use($proc) { + echo $proc->read(); +}); + +\swoole_process::wait(true); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_process/timeout.phpt b/vendor/swoole/tests/swoole_process/timeout.phpt new file mode 100755 index 0000000..c05e5a8 --- /dev/null +++ b/vendor/swoole/tests/swoole_process/timeout.phpt @@ -0,0 +1,26 @@ +--TEST-- +swoole_process: pipe read timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$proc = new \swoole_process(function(\swoole_process $process) { + sleep(5); +}); +$r = $proc->start(); +assert($r > 0); +ini_set("swoole.display_errors", "off"); +$proc->setTimeout(0.5); +$ret = $proc->read(); +assert($ret === false); +swoole_process::kill($proc->pid, SIGKILL); +\swoole_process::wait(true); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_process/write_in_worker.phpt b/vendor/swoole/tests/swoole_process/write_in_worker.phpt new file mode 100755 index 0000000..46df4bf --- /dev/null +++ b/vendor/swoole/tests/swoole_process/write_in_worker.phpt @@ -0,0 +1,47 @@ +--TEST-- +swoole_process: write in worker +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$serv = new \swoole_server('127.0.0.1', 9501); +$process = new \Swoole\Process(function ($process) use ($serv) { + sleep(1); + echo "process start\n"; + for ($i = 0; $i < 1024; $i++) + { + $data = $process->read(); + assert(strlen($data) == 8192); + } + echo "process end\n"; + $serv->shutdown(); +}); +$serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', +]); +$serv->on("WorkerStart", function (\swoole_server $serv) use ($process) { + for ($i = 0; $i < 1024; $i++) + { + $process->write(str_repeat('A', 8192)); + assert($process==true); + } + echo "worker end\n"; +}); +$serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) use ($process) { + +}); +$serv->addProcess($process); +$serv->start(); +?> +--EXPECT-- +worker end +process start +process end diff --git a/vendor/swoole/tests/swoole_redis/connect_refuse.phpt b/vendor/swoole/tests/swoole_redis/connect_refuse.phpt new file mode 100755 index 0000000..4d038e3 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis/connect_refuse.phpt @@ -0,0 +1,37 @@ +--TEST-- +swoole_redis: connect refuse + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_redis", false)) +{ + exit("SKIP"); +} +?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$redis = new swoole_redis(); + +$redis->on("close", function (){ + echo "closed\n"; +}); + +$result = $redis->connect("127.0.0.1", 19009, function ($redis, $result) +{ + assert($redis->errCode == SOCKET_ECONNREFUSED); + assert($result === false); +}); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_redis/connect_timeout.phpt b/vendor/swoole/tests/swoole_redis/connect_timeout.phpt new file mode 100755 index 0000000..1bde815 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis/connect_timeout.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_redis: connect timeout + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_redis", false)) +{ + exit("SKIP"); +} +?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_redis/connect_timeout.php'; + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_redis/get_set.phpt b/vendor/swoole/tests/swoole_redis/get_set.phpt new file mode 100755 index 0000000..2602274 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis/get_set.phpt @@ -0,0 +1,24 @@ +--TEST-- +swoole_redis: get & set +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_redis", false)) +{ + exit("required redis."); +} +?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_redis/simple_redis.php'; +?> +--EXPECT-- +close \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_redis/subscribe.phpt b/vendor/swoole/tests/swoole_redis/subscribe.phpt new file mode 100755 index 0000000..e899d8c --- /dev/null +++ b/vendor/swoole/tests/swoole_redis/subscribe.phpt @@ -0,0 +1,62 @@ +--TEST-- +swoole_redis: subscribe & publish +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_redis", false)) +{ + exit("required redis."); +} +?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +parent_child(function ($pid) +{ + //父进程 + suicide(3000); + $redis = new \swoole_redis(); + $redis->on("message", function (\swoole_redis $redis, $message) use ($pid) + { + if ($message[0] == 'subscribe') + { + return; + } + assert($message !== false); + assert($message[2] === "payload!!!"); + + pcntl_waitpid($pid, $status); + swoole_event_exit(); + }); + + $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT, function (\swoole_redis $redis, $r) + { + assert($r); + $redis->subscribe("test_on_message"); + }); +}, function () +{ + //子进程 + suicide(2000); + $redis = new \swoole_redis(); + $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT, function (\swoole_redis $redis, $r) + { + assert($r); + $r = $redis->publish("test_on_message", "payload!!!", function (\swoole_redis $redis, $r) + { + assert($r); + swoole_event_exit(); + }); + assert($r); + }); +}); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_redis_coro/basic.phpt b/vendor/swoole/tests/swoole_redis_coro/basic.phpt new file mode 100755 index 0000000..146d71a --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/basic.phpt @@ -0,0 +1,64 @@ +--TEST-- +swoole_coroutine: redis client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + if (!$res) + { + fail: + $response->end("ERROR\n"); + return; + } + + $ret = $redis->set('key', 'value'); + if (!$ret) { + goto fail; + } + $ret = $redis->get('key'); + if (!$ret) { + goto fail; + } + assert($ret == "value"); + if (strlen($ret) > 0) { + $response->end("OK\n"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_redis_coro/connect_timeout.phpt b/vendor/swoole/tests/swoole_redis_coro/connect_timeout.phpt new file mode 100755 index 0000000..c0706f2 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/connect_timeout.phpt @@ -0,0 +1,31 @@ +--TEST-- +swoole_redis_coro: connect twice +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("Swoole\\Coroutine\\Redis", false)) +{ + exit("SKIP"); +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +//Co::set(['log_level' => SWOOLE_LOG_TRACE, 'trace_flags' => SWOOLE_TRACE_ALL]); + +go(function () { + $redis = new Swoole\Coroutine\Redis(['timeout' => 0.5]); + echo "connect [1]\n"; + $redis->connect('192.0.0.1', 6379); + echo "close [1]\n"; + assert($redis->connected === false); + $redis->close(); +}); + +swoole_event::wait(); +?> +--EXPECT-- +connect [1] +close [1] diff --git a/vendor/swoole/tests/swoole_redis_coro/connect_twice-2.phpt b/vendor/swoole/tests/swoole_redis_coro/connect_twice-2.phpt new file mode 100755 index 0000000..86ff91a --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/connect_twice-2.phpt @@ -0,0 +1,65 @@ +--TEST-- +swoole_coroutine: redis client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $data = curlGet("http://127.0.0.1:9501/"); + echo $data; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + $res2 = @$redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + assert($res2 == false); + if (!$res) + { + fail: + $response->end("ERROR\n"); + return; + } + $ret = $redis->set('key', 'value'); + if (!$ret) { + goto fail; + } + $ret = $redis->get('key'); + if (!$ret) { + goto fail; + } + assert($ret == "value"); + if (strlen($ret) > 0) { + $response->end("OK\n"); + } + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_redis_coro/connect_twice.phpt b/vendor/swoole/tests/swoole_redis_coro/connect_twice.phpt new file mode 100755 index 0000000..bbeb70f --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/connect_twice.phpt @@ -0,0 +1,40 @@ +--TEST-- +swoole_redis_coro: connect twice +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("Swoole\\Coroutine\\Redis", false)) +{ + exit("SKIP"); +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +//Co::set(['log_level' => SWOOLE_LOG_TRACE, 'trace_flags' => SWOOLE_TRACE_ALL]); + +go(function () { + $redis = new Swoole\Coroutine\Redis(); + echo "connect [1]\n"; + $redis->connect('127.0.0.1', 6379); + assert($redis->connected === true); + echo "close [1]\n"; + $redis->close(); + assert($redis->connected === false); + echo "connect [2]\n"; + $redis->connect('127.0.0.1', 6379); + assert($redis->connected === true); + echo "close [2]\n"; + $redis->close(); + assert($redis->connected === false); +}); + +swoole_event::wait(); +?> +--EXPECT-- +connect [1] +close [1] +connect [2] +close [2] diff --git a/vendor/swoole/tests/swoole_redis_coro/defer.phpt b/vendor/swoole/tests/swoole_redis_coro/defer.phpt new file mode 100755 index 0000000..21ae89a --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/defer.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_redis_coro: defer +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("Swoole\\Coroutine\\Redis", false)) +{ + exit("SKIP"); +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +//Co::set(['log_level' => SWOOLE_LOG_TRACE, 'trace_flags' => SWOOLE_TRACE_ALL]); + +go(function () { + $redis = new Swoole\Coroutine\Redis(); + echo "CONNECT [1]\n"; + $redis->connect('127.0.0.1', 6379); + $redis->setDefer(); + echo "SET [1]\n"; + $redis->set('key1', 'value'); + + $redis2 = new Swoole\Coroutine\Redis(); + echo "CONNECT [2]\n"; + $redis2->connect('127.0.0.1', 6379); + $redis2->setDefer(); + echo "GET [2]\n"; + $redis2->get('key1'); + + echo "RECV [1]\n"; + $result1 = $redis->recv(); + var_dump($result1); + + echo "RECV [2]\n"; + $result2 = $redis2->recv(); + var_dump($result2); +}); + +swoole_event::wait(); +?> +--EXPECT-- +CONNECT [1] +SET [1] +CONNECT [2] +GET [2] +RECV [1] +bool(true) +RECV [2] +string(5) "value" diff --git a/vendor/swoole/tests/swoole_redis_coro/multi_exec.phpt b/vendor/swoole/tests/swoole_redis_coro/multi_exec.phpt new file mode 100755 index 0000000..4fe0874 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/multi_exec.phpt @@ -0,0 +1,32 @@ +--TEST-- +swoole_coroutine: redis multi and exec +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +go(function () { + $redis = new \Swoole\Coroutine\Redis(); + $result = $redis->connect('127.0.0.1', 6379, false); + assert($result); + + assert($redis->hmset('u:i:1', ['a' => 'hello', 'b' => 'world'])); + assert($redis->hmset('u:i:2', ['a' => 'rango', 'b' => 'swoole'])); + assert($redis->multi(SWOOLE_REDIS_MODE_PIPELINE)); + //$redis->multi(SWOOLE_REDIS_MODE_PIPELINE); + $redis->hmget('u:i:1', array('a', 'b')); + $redis->hmget('u:i:2', array('a', 'b')); + + $rs = $redis->exec(); + assert($rs and is_array($rs)); + assert($rs[0][0] == 'hello'); + assert($rs[0][1] == 'world'); + assert($rs[1][0] == 'rango'); + assert($rs[1][1] == 'swoole'); +}); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_redis_coro/pool.phpt b/vendor/swoole/tests/swoole_redis_coro/pool.phpt new file mode 100755 index 0000000..10769c7 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/pool.phpt @@ -0,0 +1,79 @@ +--TEST-- +swoole_coroutine: redis client +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + echo curlGet("http://127.0.0.1:9501/"); + echo curlGet("http://127.0.0.1:9501/"); + echo curlGet("http://127.0.0.1:9501/"); + swoole_process::kill($pid); +}; + +$count = 0; +$pool = new SplQueue(); + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + $http->set(array( + 'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + global $count, $pool; + if (count($pool) == 0) + { + $redis = new Swoole\Coroutine\Redis(); + $redis->id = $count; + $res = $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + if ($res == false) + { + fail: + $response->end("ERROR\n"); + return; + } + $count++; + $pool->push($redis); + } + + $redis = $pool->pop(); + $ret = $redis->set('key', 'value'); + if ($ret) + { + $response->end("OK[$count]\n"); + } + else + { + goto fail; + } + $pool->push($redis); + + }); + + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK[1] +OK[1] +OK[1] diff --git a/vendor/swoole/tests/swoole_redis_coro/reconnect.phpt b/vendor/swoole/tests/swoole_redis_coro/reconnect.phpt new file mode 100755 index 0000000..9aea76d --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/reconnect.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_coroutine: redis reconnect +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +go(function () { + $redis = new Swoole\Coroutine\Redis(); + $res = $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + assert($res); + $redis->close(); + $res2 = $redis->connect(REDIS_SERVER_HOST, REDIS_SERVER_PORT); + assert($res2); +}); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_redis_coro/subscribe.phpt b/vendor/swoole/tests/swoole_redis_coro/subscribe.phpt new file mode 100755 index 0000000..a0247de --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_coro/subscribe.phpt @@ -0,0 +1,39 @@ +--TEST-- +swoole_coroutine: redis subscribe +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +use Swoole\Coroutine as co; + +const N = 100; + +co::create(function () { + $redis = new co\Redis(); + $redis->connect('127.0.0.1', 6379); + for ($i = 0; $i < N; $i++) + { + $val = $redis->subscribe(['test']); + assert($val and count($val) > 1); + } + $redis->close(); +}); + +co::create(function () { + $redis = new co\redis; + $redis->connect('127.0.0.1', 6379); + for ($i = 0; $i < N; $i++) + { + $ret = $redis->publish('test', 'hello-' . $i); + assert($ret); + } +}); + +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_redis_server/big_packet.phpt b/vendor/swoole/tests/swoole_redis_server/big_packet.phpt new file mode 100755 index 0000000..0699879 --- /dev/null +++ b/vendor/swoole/tests/swoole_redis_server/big_packet.phpt @@ -0,0 +1,79 @@ +--TEST-- +swoole_redis_server: test big packet + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("redis", false)) +{ + exit("skip"); +} +?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +use Swoole\Redis\Server; + +define('VALUE_LEN', 8192 * 128); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $redis = new redis; + $redis->connect('127.0.0.1', 9501); + $redis->set('big_value', str_repeat('A', VALUE_LEN)); + $ret = $redis->get('big_value'); + assert($ret and strlen($ret) == VALUE_LEN); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $server = new Server("127.0.0.1", 9501, SWOOLE_BASE); + $server->data = array(); + + $server->setHandler('GET', function ($fd, $data) use ($server) { + if (count($data) == 0) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'GET' command"); + } + $key = $data[0]; + if (empty($server->data[$key])) + { + $server->send($fd, Server::format(Server::NIL)); + } + else + { + $server->send($fd, Server::format(Server::STRING, $server->data[$key])); + } + }); + + $server->setHandler('SET', function ($fd, $data) use ($server) { + if (count($data) < 2) + { + return Server::format(Server::ERROR, "ERR wrong number of arguments for 'SET' command"); + } + $key = $data[0]; + $server->data[$key] = $data[1]; + $server->send($fd, Server::format(Server::STATUS, 'OK')); + }); + + $server->on('WorkerStart', function ($server) use ($pm) { + $pm->wakeup(); + }); + + $server->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_serialize/001.phpt b/vendor/swoole/tests/swoole_serialize/001.phpt new file mode 100755 index 0000000..c6e633f --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/001.phpt @@ -0,0 +1,30 @@ +--TEST-- +swoole_serialize: Check for null serialisation +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + + class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + }; + $f = new Obj(1,2); + $unserialized = swoole_serialize::pack($f); + file_put_contents("/tmp/swoole_seria_test", $unserialized); +echo "OK" +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_serialize/002.phpt b/vendor/swoole/tests/swoole_serialize/002.phpt new file mode 100755 index 0000000..0407cf2 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/002.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_serialize: Check for null serialisation +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('null', null); +?> +--EXPECT-- +null +NULL +OK diff --git a/vendor/swoole/tests/swoole_serialize/003.phpt b/vendor/swoole/tests/swoole_serialize/003.phpt new file mode 100755 index 0000000..e96db63 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/003.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_serialize: Check for bool serialisation +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('bool true', true); +test('bool false', false); +?> +--EXPECT-- +bool true +bool(true) +OK +bool false +bool(false) +OK diff --git a/vendor/swoole/tests/swoole_serialize/004.phpt b/vendor/swoole/tests/swoole_serialize/004.phpt new file mode 100755 index 0000000..687fe82 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/004.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_serialize: Check for integer serialisation +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); +?> +--EXPECT-- +zero: 0 +int(0) +OK +small: 1 +int(1) +OK +small: -1 +int(-1) +OK +medium: 1000 +int(1000) +OK +medium: -1000 +int(-1000) +OK +large: 100000 +int(100000) +OK +large: -100000 +int(-100000) +OK diff --git a/vendor/swoole/tests/swoole_serialize/005.phpt b/vendor/swoole/tests/swoole_serialize/005.phpt new file mode 100755 index 0000000..c05340e --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/005.phpt @@ -0,0 +1,29 @@ +--TEST-- +swoole_serialize: Check for double serialisation +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('double: 123.456', 123.456); +?> +--EXPECT-- +double: 123.456 +float(123.456) +OK diff --git a/vendor/swoole/tests/swoole_serialize/006.phpt b/vendor/swoole/tests/swoole_serialize/006.phpt new file mode 100755 index 0000000..20ef25b --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/006.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_serialize: Check for simple string serialization +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); +?> +--EXPECT-- +empty: "" +string(0) "" +OK +string: "foobar" +string(6) "foobar" +OK diff --git a/vendor/swoole/tests/swoole_serialize/007.phpt b/vendor/swoole/tests/swoole_serialize/007.phpt new file mode 100755 index 0000000..8b97c1c --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/007.phpt @@ -0,0 +1,73 @@ +--TEST-- +swoole_serialize: Check for simple array serialization +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('empty array:', array()); +test('array(1, 2, 3)', array(1, 2, 3)); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9))); +?> +--EXPECT-- +empty array: +array(0) { +} +OK +array(1, 2, 3) +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(array(1, 2, 3), arr... +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/008.phpt b/vendor/swoole/tests/swoole_serialize/008.phpt new file mode 100755 index 0000000..827a734 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/008.phpt @@ -0,0 +1,61 @@ +--TEST-- +swoole_serialize: Check for array+string serialization +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo")); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2)); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek")); +test('array("" => "empty")', array("" => "empty")); +?> +--EXPECT-- +array("foo", "foo", "foo") +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array("one" => 1, "two" => 2)) +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array("kek" => "lol", "lol" => "kek") +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array("" => "empty") +array(1) { + [""]=> + string(5) "empty" +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/009.phpt b/vendor/swoole/tests/swoole_serialize/009.phpt new file mode 100755 index 0000000..c09bb9b --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/009.phpt @@ -0,0 +1,85 @@ +--TEST-- +swoole_serialize: Check for reference serialization +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +ini_set("display_errors", "Off"); + +function test($type, $variable, $test) { + // $serialized = serialize($variable); +// $unserialized = unserialize($serialized); + + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + echo $type, PHP_EOL; + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +$a = array('foo'); + +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = []; +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); +?> +--EXPECT-- +array($a, $a) +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(&$a, &$a) +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +cyclic +array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + array(1) { + [0]=> + NULL + } + } + } + } +} +OK \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_serialize/010.phpt b/vendor/swoole/tests/swoole_serialize/010.phpt new file mode 100755 index 0000000..9ea1ecc --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/010.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_serialize: Array test +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) +); + +test('array', $a, false); +?> +--EXPECT-- +array +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/012.phpt b/vendor/swoole/tests/swoole_serialize/012.phpt new file mode 100755 index 0000000..a11aaf1 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/012.phpt @@ -0,0 +1,51 @@ +--TEST-- +swoole_serialize: Object test +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +$o = new Obj(1, 2, 3); + + +test('object', $o, false); +?> +--EXPECTF-- +object +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/013.phpt b/vendor/swoole/tests/swoole_serialize/013.phpt new file mode 100755 index 0000000..cf71324 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/013.phpt @@ -0,0 +1,58 @@ +--TEST-- +swoole_serialize: Object-Array test +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } +} + +$o = array(new Obj(1, 2), new Obj(3, 4)); + + +test('object', $o, false); +?> +--EXPECTF-- +object +array(2) { + [0]=> + object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } + [1]=> + object(Obj)#%d (2) { + ["a"]=> + int(3) + ["b"]=> + int(4) + } +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/014.phpt b/vendor/swoole/tests/swoole_serialize/014.phpt new file mode 100755 index 0000000..cb497a5 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/014.phpt @@ -0,0 +1,58 @@ +--TEST-- +swoole_serialize: Object-Reference test +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } +} + +$o = new Obj(1, 2); +$a = array(&$o, &$o); + +test('object', $a, false); +?> +--EXPECTF-- +object +array(2) { + [0]=> + object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } + [1]=> + object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) + } +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/016.phpt b/vendor/swoole/tests/swoole_serialize/016.phpt new file mode 100755 index 0000000..82ffb1e --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/016.phpt @@ -0,0 +1,64 @@ +--TEST-- +swoole_serialize: Object test, __sleep +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + + var_dump($unserialized); + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + public $a; + protected $b; + private $c; + var $d; + + function __construct($a, $b, $c, $d) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + $this->d = $d; + } + + function __sleep() { + return array('a', 'b', 'c'); + } + +# function __wakeup() { +# $this->d = $this->a + $this->b + $this->c; +# } +} + +$o = new Obj(1, 2, 3, 4); + + +test('object', $o, true); +?> +--EXPECTF-- +object +object(Obj)#%d (4) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + ["d"]=> + NULL +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/017.phpt b/vendor/swoole/tests/swoole_serialize/017.phpt new file mode 100755 index 0000000..526b753 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/017.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_serialize: Object test, __wakeup +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +function test($type, $variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + + var_dump($unserialized); + echo $test || $unserialized->b == 3 ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + + function __wakeup() { + $this->b = $this->a * 3; + } +} + +$o = new Obj(1, 2); + + +test('object', $o, false); +?> +--EXPECTF-- +object +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(3) +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/019.phpt b/vendor/swoole/tests/swoole_serialize/019.phpt new file mode 100755 index 0000000..dcaba3f --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/019.phpt @@ -0,0 +1,48 @@ +--TEST-- +swoole_serialize: Object test, __autoload +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + + +function test($type, $test) { + $serialized = file_get_contents("/tmp/swoole_seria_test"); + $unserialized = swoole_serialize::unpack($serialized); + + echo $type, PHP_EOL; + + var_dump($unserialized); + echo $test || $unserialized->b == 2 ? 'OK' : 'ERROR', PHP_EOL; +} + +spl_autoload_register(function ($classname) { + class Obj { + var $a; + var $b; + + function __construct($a, $b) { + $this->a = $a; + $this->b = $b; + } + } +}); + +test('autoload', false); +?> +--EXPECTF-- +autoload +object(Obj)#%d (2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/020.phpt b/vendor/swoole/tests/swoole_serialize/020.phpt new file mode 100755 index 0000000..0b21e9a --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/020.phpt @@ -0,0 +1,48 @@ +--TEST-- +swoole_serialize: Object test, stdclass +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +ini_set("display_errors", "Off"); +function test($variable, $test) { + $serialized = swoole_serialize::pack($variable); + $unserialized = swoole_serialize::unpack($serialized, UNSERIALIZE_OBJECT_TO_STDCLASS); + + echo UNSERIALIZE_OBJECT_TO_STDCLASS, PHP_EOL; + + var_dump($unserialized); + echo get_class($unserialized->sub) == "stdClass" ? 'OK' : 'ERROR', PHP_EOL; +} + +class Obj { + var $sub; +} + +class subObj { + var $b = "sub"; +} + +$o = new Obj(); +$o->sub = new subObj(); + +test($o, true); +?> +--EXPECTF-- +2 +object(stdClass)#4 (1) { + ["sub"]=> + object(stdClass)#3 (1) { + ["b"]=> + string(3) "sub" + } +} +OK diff --git a/vendor/swoole/tests/swoole_serialize/021.phpt b/vendor/swoole/tests/swoole_serialize/021.phpt new file mode 100755 index 0000000..2fa8838 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/021.phpt @@ -0,0 +1,33 @@ +--TEST-- +swoole_serialize: Object test, type undef +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +ini_set("display_errors", "Off"); +class Foo +{ + public $a = 'a'; +} + +$foo = new Foo(); +$foo->a = 'b'; +unset($foo->a); +$ser = swoole_serialize::pack($foo); +$bar = swoole_serialize::unpack($ser); +var_dump($bar); + +?> +--EXPECTF-- +object(Foo)#2 (1) { + ["a"]=> + NULL +} diff --git a/vendor/swoole/tests/swoole_serialize/022.phpt b/vendor/swoole/tests/swoole_serialize/022.phpt new file mode 100755 index 0000000..a31a084 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/022.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_serialize: Object test, extends private +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +ini_set("display_errors", "Off"); + +abstract class AbstractAsyncTask +{ + private $data = null; + + public function __construct($data = null) + { + $this->data = $data; + } + + public function getData() + { + return $this->data; + } +} + +class test extends AbstractAsyncTask +{ + +} + + +$data = swoole_serialize::pack(new test('aaa')); + + +$a = swoole_serialize::unpack($data); + +var_dump($a); + +var_dump($a->getData()); + +?> +--EXPECTF-- +object(test)#1 (1) { + ["data":"AbstractAsyncTask":private]=> + string(3) "aaa" +} +string(3) "aaa" diff --git a/vendor/swoole/tests/swoole_serialize/023.phpt b/vendor/swoole/tests/swoole_serialize/023.phpt new file mode 100755 index 0000000..e8e12e1 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/023.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_serialize: Object test, extends protect +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +ini_set("display_errors", "Off"); + +abstract class AbstractAsyncTask +{ + protected $data = null; + + public function __construct($data = null) + { + $this->data = $data; + } + + public function getData() + { + return $this->data; + } +} + +class test extends AbstractAsyncTask +{ + +} + + +$data = swoole_serialize::pack(new test('aaa')); + + +$a = swoole_serialize::unpack($data); + +var_dump($a); + +var_dump($a->getData()); + +?> +--EXPECTF-- +object(test)#1 (1) { + ["data":protected]=> + string(3) "aaa" +} +string(3) "aaa" diff --git a/vendor/swoole/tests/swoole_serialize/packunpack.phpt b/vendor/swoole/tests/swoole_serialize/packunpack.phpt new file mode 100755 index 0000000..bbdda16 --- /dev/null +++ b/vendor/swoole/tests/swoole_serialize/packunpack.phpt @@ -0,0 +1,58 @@ +--TEST-- +swoole_serialize: pack & unpack +--SKIPIF-- +<?php +require __DIR__ . '/../include/skipif.inc'; +if (!class_exists("swoole_serialize", false)) +{ + echo "skip"; +} +?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +// int +$int_data = mt_rand(100, 999); +$data = swoole_serialize::pack($int_data); +$un_data = swoole_serialize::unpack($data); +assert($int_data == $un_data); + +// long +$long_data = mt_rand(100000000000, 999999999999); +$data = swoole_serialize::pack($long_data); +$un_data = swoole_serialize::unpack($data); +assert($long_data == $un_data); + +// string +$str_data = str_repeat('bcy', 10); +$data = swoole_serialize::pack($str_data); +$un_data = swoole_serialize::unpack($data); +assert($str_data == $un_data); + +// array +$arr_data = array_pad([], 32, '0123456789abcdefghijklmnopqrstuvwxyz'); +$data = swoole_serialize::pack($arr_data); +$un_data = swoole_serialize::unpack($data); +assert($arr_data == $un_data); + +// large array +$large_arr_data = array_pad([], 4096, '0123456789abcdefghijklmnopqrstuvwxyz'); +$data = swoole_serialize::pack($large_arr_data); +$un_data = swoole_serialize::unpack($data); +assert($large_arr_data == $un_data); + +// error array data +$data_out = substr($data, 0, 8192); +$err_data = @swoole_serialize::unpack($data_out); +assert($err_data == false); +?> +DONE +--EXPECTF-- +DONE diff --git a/vendor/swoole/tests/swoole_server/addListener.phpt b/vendor/swoole/tests/swoole_server/addListener.phpt new file mode 100755 index 0000000..01ec6af --- /dev/null +++ b/vendor/swoole/tests/swoole_server/addListener.phpt @@ -0,0 +1,71 @@ +--TEST-- +swoole_server: +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; + +$port1 = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $cli = new \swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (\swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("test"); + }); + + $cli->on("receive", function(\swoole_client $cli, $data){ + $i = $cli->getpeername(); + assert($i !== false); + $cli->send('shutdown'); + $cli->close(); + }); + + $cli->on("close", function(\swoole_client $cli) { + echo "SUCCESS\n"; + }); + + $r = $cli->connect(UDP_SERVER_HOST, UDP_SERVER_PORT, 1); + assert($r); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server(UDP_SERVER_HOST, UDP_SERVER_PORT, SWOOLE_BASE, SWOOLE_SOCK_UDP); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null']); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Packet", function (\swoole_server $serv, $data, $clientInfo) + { + if (trim($data) == 'shutdown') + { + $serv->shutdown(); + return; + } + $serv->sendto($clientInfo['address'], $clientInfo['port'], $data); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/addProcess.phpt b/vendor/swoole/tests/swoole_server/addProcess.phpt new file mode 100755 index 0000000..8fead98 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/addProcess.phpt @@ -0,0 +1,86 @@ +--TEST-- +swoole_server: addProcess +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (\swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("test"); + }); + + $cli->on("receive", function(\swoole_client $cli, $data){ + assert($data == 'test'); + $cli->send('shutdown'); + $cli->close(); + }); + + $cli->on("close", function(\swoole_client $cli) { + echo "SUCCESS\n"; + }); + + $cli->on("error", function(\swoole_client $cli) { + echo "error\n"; + }); + + $r = $cli->connect(TCP_SERVER_HOST, $port, 1); + assert($r); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, $port); + $process = new \Swoole\Process(function ($process) use ($serv) + { + while (1) + { + $msg = json_decode($process->read(), true); + $serv->send($msg['fd'], $msg['data']); + } + }); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) use ($process) + { + if (trim($data) == 'shutdown') + { + $serv->shutdown(); + return; + } + else { + $process->write(json_encode(['fd' => $fd, 'data' => $data])); + } + }); + $serv->addProcess($process); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/bigPipeMessage.phpt b/vendor/swoole/tests/swoole_server/bigPipeMessage.phpt new file mode 100755 index 0000000..fe88f90 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/bigPipeMessage.phpt @@ -0,0 +1,77 @@ +--TEST-- +swoole_server: send big pipe message +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); + +const N = 800000; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (\swoole_client $cli) { + $cli->send("test"); + }); + + $cli->on("receive", function(\swoole_client $cli, $data){ + echo $data; + $cli->close(); + }); + + $cli->on("close", function(\swoole_client $cli) { + + }); + + $cli->on("error", function(\swoole_client $cli) { + + }); + + $cli->connect(TCP_SERVER_HOST, $port, 1); + Swoole\Event::wait(); + Swoole\Process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, $port); + $serv->set([ + "worker_num" => 2, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("pipeMessage", function ($serv, $worker_id, $data) + { + if (is_array($data) and strlen($data['data']) == N) + { + $serv->send($data['fd'], "OK\n"); + } + }); + $serv->on("receive", function ($serv, $fd, $rid, $data) + { + $data = str_repeat("A", N); + $serv->sendMessage(array('data' => $data, 'fd' => $fd), 1 - $serv->worker_id); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_server/big_udp_packet.phpt b/vendor/swoole/tests/swoole_server/big_udp_packet.phpt new file mode 100755 index 0000000..f059067 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/big_udp_packet.phpt @@ -0,0 +1,55 @@ +--TEST-- +swoole_server: send big udp packet to server +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +//最大长度:65535 - UDP包头 8字节 + IP包头 20字节 = 65507 +const N = 65507; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC); + if (!$client->connect('127.0.0.1', $port)) + { + exit("connect failed\n"); + } + $client->send(str_repeat('A', N)); + $data = $client->recv(); + assert(strlen($data) == N); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE, SWOOLE_SOCK_UDP); + $serv->set(['worker_num' => 1, 'log_file' => '/dev/null']); + $serv->on("workerStart", function ($serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('packet', function ($serv, $data, $client) + { + $serv->sendto($client['address'], $client['port'], str_repeat('B', strlen($data))); + }); + $serv->start(); +}; + + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/bind.phpt b/vendor/swoole/tests/swoole_server/bind.phpt new file mode 100755 index 0000000..3a8749e --- /dev/null +++ b/vendor/swoole/tests/swoole_server/bind.phpt @@ -0,0 +1,37 @@ +--TEST-- +swoole_server: bind +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) use($port) { + $r = $cli->send(opcode_encode("bind", [2, 42])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $binded) = opcode_decode($recv); + assert($binded); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/bug_11000_01.phpt b/vendor/swoole/tests/swoole_server/bug_11000_01.phpt new file mode 100755 index 0000000..4dcab1e --- /dev/null +++ b/vendor/swoole/tests/swoole_server/bug_11000_01.phpt @@ -0,0 +1,38 @@ +--TEST-- +swoole_server: bug_11000_01 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$serv = new \swoole_server(TCP_SERVER_HOST, $port); +$process = new \Swoole\Process(function ($process) use ($serv) { + $s = $serv->stats(); + assert($s and is_array($s) and count($s) > 1); + $serv->shutdown(); +}); + +$serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', +]); + +$serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) use ($process) { + +}); + +$serv->addProcess($process); +$serv->start(); + +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/connections.phpt b/vendor/swoole/tests/swoole_server/connections.phpt new file mode 100755 index 0000000..490b356 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/connections.phpt @@ -0,0 +1,91 @@ +--TEST-- +swoole_server: connection iterator +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const N = 10; + +global $count; +$count = 0; +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + global $count; + for ($i = 0; $i < N; $i++) + { + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $cli->on("connect", function (swoole_client $cli) + { + + }); + $cli->on("receive", function (swoole_client $cli, $data) + { + assert($data == "OK"); + global $count; + $count ++; + $cli->close(); + }); + $cli->on("error", function (swoole_client $cli) + { + echo "error\n"; + }); + $cli->on("close", function (swoole_client $cli) + { + + }); + $cli->connect("127.0.0.1", $port, 0.1); + } + swoole_event::wait(); + assert($count == N); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE); + $serv->set(array( + "worker_num" => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('connect', function (swoole_server $serv, $fd, $rid) + { + global $count; + $count++; + if ($count == N) + { + $serv->defer(function () use ($serv) + { + foreach ($serv->connections as $fd) + { + $serv->send($fd, "OK"); + } + }); + } + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/dispatch_by_stream.phpt b/vendor/swoole/tests/swoole_server/dispatch_by_stream.phpt new file mode 100755 index 0000000..9b63cc5 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/dispatch_by_stream.phpt @@ -0,0 +1,93 @@ +--TEST-- +swoole_server: dispatch_mode = 7 [stream] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + if (!$client->connect('127.0.0.1', 9501, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + + $data = array( + 'name' => __FILE__, + 'sid' => 1000236, + 'content' => str_repeat('A', 8192 * rand(1, 3)), + ); + + $_serialize_data = serialize($data). "\r\n\r\n";; + + $chunk_size = 2048; + $len = strlen($_serialize_data); + $chunk_num = intval($len / $chunk_size) + 1; + for ($i = 0; $i < $chunk_num; $i++) + { + if ($len < ($i + 1) * $chunk_size) + { + $sendn = $len - ($i * $chunk_size); + } + else + { + $sendn = $chunk_size; + } + $client->send(substr($_serialize_data, $i * $chunk_size, $sendn)); + usleep(10000); + } + echo $client->recv(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M + "worker_num" => 1, + 'log_file' => '/dev/null', + "reload_async" => true, + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $_data = unserialize(rtrim($data)); + if ($_data and is_array($_data) and $_data['sid'] == 1000236) + { + $serv->send($fd, "SUCCESS"); + } + else + { + $serv->send($fd, "ERROR"); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/dispatch_mode_1.phpt b/vendor/swoole/tests/swoole_server/dispatch_mode_1.phpt new file mode 100755 index 0000000..ff9d0d5 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/dispatch_mode_1.phpt @@ -0,0 +1,103 @@ +--TEST-- +swoole_server: dispatch_mode = 1 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const REQ_N = 10000; +const CLIENT_N = 16; +const WORKER_N = 4; + +global $stats; +$stats = array(); +$count = 0; +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + global $count, $stats; + for ($i = 0; $i < CLIENT_N; $i++) + { + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $cli->set([ + 'package_eof' => "\r\n\r\n", + 'open_eof_split' => true, + ]); + $cli->count = 0; + $cli->on("connect", function (swoole_client $cli) + { + for ($i = 0; $i < REQ_N; $i++) + { + $cli->send("hello world\r\n\r\n"); + } + }); + $cli->on("receive", function (swoole_client $cli, $data) + { + global $stats; + $wid = trim($data); + if (isset($stats[$wid])) + { + $stats[$wid]++; + } + else + { + $stats[$wid] = 1; + } + $cli->count++; + if ($cli->count == REQ_N) + { + $cli->close(); + } + }); + $cli->on("error", function (swoole_client $cli) + { + echo "error\n"; + }); + $cli->on("close", function (swoole_client $cli) + { + + }); + $cli->connect("127.0.0.1", $port, 0.1); + } + swoole_event::wait(); + swoole_process::kill($pid); + foreach ($stats as $s) + { + assert($s == REQ_N * CLIENT_N / WORKER_N); + } +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_PROCESS); + $serv->set(array( + "worker_num" => WORKER_N, + 'dispatch_mode' => 1, + 'package_eof' => "\r\n\r\n", + 'open_eof_split' => true, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $serv->send($fd, $serv->worker_id . "\r\n\r\n"); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/dispatch_mode_3.phpt b/vendor/swoole/tests/swoole_server/dispatch_mode_3.phpt new file mode 100755 index 0000000..4b53164 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/dispatch_mode_3.phpt @@ -0,0 +1,105 @@ +--TEST-- +swoole_server: dispatch_mode = 3 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const REQ_N = 10000; +const CLIENT_N = 16; +const WORKER_N = 16; + +global $stats; +$stats = array(); +$count = 0; +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + global $count, $stats; + for ($i = 0; $i < CLIENT_N; $i++) + { + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + $cli->set([ + 'package_eof' => "\r\n\r\n", + 'open_eof_split' => true, + ]); + $cli->count = 0; + $cli->on("connect", function (swoole_client $cli) + { + for ($i = 0; $i < REQ_N; $i++) + { + $cli->send("hello world\r\n\r\n"); + } + }); + $cli->on("receive", function (swoole_client $cli, $data) + { + global $stats; + $wid = trim($data); + if (isset($stats[$wid])) + { + $stats[$wid]++; + } + else + { + $stats[$wid] = 1; + } + $cli->count++; + if ($cli->count == REQ_N) + { + $cli->close(); + } + }); + $cli->on("error", function (swoole_client $cli) + { + echo "error\n"; + }); + $cli->on("close", function (swoole_client $cli) + { + + }); + $cli->connect("127.0.0.1", $port, 0.1); + } + swoole_event::wait(); + swoole_process::kill($pid); + assert($stats[10] < 500); + assert($stats[5] < 500); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_PROCESS); + $serv->set(array( + "worker_num" => WORKER_N, + 'dispatch_mode' => 3, + 'package_eof' => "\r\n\r\n", + 'open_eof_split' => true, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + if ($serv->worker_id == 10 or $serv->worker_id == 5) + { + usleep(5000); + } + $serv->send($fd, $serv->worker_id . "\r\n\r\n"); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/eof_protocol.phpt b/vendor/swoole/tests/swoole_server/eof_protocol.phpt new file mode 100755 index 0000000..47969f2 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/eof_protocol.phpt @@ -0,0 +1,105 @@ +--TEST-- +swoole_server: (eof protocol) recv 100k packet + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_server/TestServer.php'; + +class EofServer extends TestServer +{ + protected $show_lost_package = true; + function onReceive($serv, $fd, $reactor_id, $data) + { + $pkg = unserialize(rtrim($data)); + if ($pkg['index'] % 1000 == 0) + { + //echo "#{$pkg['index']} recv package. sid={$pkg['sid']}, length=" . strlen($data) . ", md5=".md5($data)."\n"; + } + if (!isset($pkg['index'])) + { + exit("error packet"); + } + if ($pkg['index'] > self::PKG_NUM) + { + echo "invalid index #{$pkg['index']}\n"; + } + $this->index[$pkg['index']] = true; + } + function onWorkerStart($serv, $wid) + { + global $pm; + $pm->wakeup(); + } +} + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP); + if (!$client->connect('127.0.0.1', 9501, 2.0)) + { + exit("connect failed\n"); + } + $bytes = 0; + $pkg_bytes = 0; + + for ($i = 0; $i < TestServer::PKG_NUM; $i++) + { + $len = rand(1000, 1024 * 128 - 8); + $sid = rand(10000, 99999); + + $array['index'] = $i; + $array['sid'] = $sid; + $array['len'] = $len; + $array['data'] = str_repeat('A', $len); + $pkt = serialize($array) . "\r\n\r\n"; + $pkg_bytes += strlen($pkt); + +// if ($i % 1000 == 0 or $i > 99000) +// { +// echo "#{$i} send package. sid={$sid}, length=" . ($len + 10) . ", total bytes={$pkg_bytes}\n"; +// } + if (!$client->send($pkt)) + { + break; + } + $bytes += strlen($pkt); + } + $recv = $client->recv(); + echo $recv; + +// echo "send ".TestServer::PKG_NUM." packet sucess, send $bytes bytes\n"; + $client->close(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new EofServer(); + $serv->set([ + 'log_file' => '/dev/null', + 'package_eof' => "\r\n\r\n", + 'open_eof_split' => true, + 'worker_num' => 1, + 'package_max_length' => 1024 * 1024 * 2, + ]); + $serv->start(); +}; + +$pm->childFirst(); +//$pm->runParentFunc(); +$pm->run(); +?> +--EXPECTF-- +end +Total count=100000, bytes=%d diff --git a/vendor/swoole/tests/swoole_server/eof_server.phpt b/vendor/swoole/tests/swoole_server/eof_server.phpt new file mode 100755 index 0000000..f66c193 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/eof_server.phpt @@ -0,0 +1,92 @@ +--TEST-- +swoole_server: eof server +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + if (!$client->connect('127.0.0.1', 9501, 0.5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + + $data = array( + 'name' => __FILE__, + 'sid' => 1000236, + 'content' => str_repeat('A', 8192 * rand(1, 3)), + ); + + $_serialize_data = serialize($data). "\r\n\r\n";; + + $chunk_size = 2048; + $len = strlen($_serialize_data); + $chunk_num = intval($len / $chunk_size) + 1; + for ($i = 0; $i < $chunk_num; $i++) + { + if ($len < ($i + 1) * $chunk_size) + { + $sendn = $len - ($i * $chunk_size); + } + else + { + $sendn = $chunk_size; + } + $client->send(substr($_serialize_data, $i * $chunk_size, $sendn)); + usleep(10000); + } + echo $client->recv(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + 'package_eof' => "\r\n\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + 'dispatch_mode' => 3, + 'package_max_length' => 1024 * 1024 * 2, //2M + "worker_num" => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $_data = unserialize(rtrim($data)); + if ($_data and is_array($_data) and $_data['sid'] == 1000236) + { + $serv->send($fd, "SUCCESS"); + } + else + { + $serv->send($fd, "ERROR"); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/exist.phpt b/vendor/swoole/tests/swoole_server/exist.phpt new file mode 100755 index 0000000..752198a --- /dev/null +++ b/vendor/swoole/tests/swoole_server/exist.phpt @@ -0,0 +1,43 @@ +--TEST-- +swoole_server: exist +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("exist", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/getClientInfo.phpt b/vendor/swoole/tests/swoole_server/getClientInfo.phpt new file mode 100755 index 0000000..c5d2cbb --- /dev/null +++ b/vendor/swoole/tests/swoole_server/getClientInfo.phpt @@ -0,0 +1,63 @@ +--TEST-- +swoole_server: get client info +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("getClientInfo", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert(is_array($data) && $data); + /** + * + array(8) { + ["server_fd"]=> + int(3) + ["socket_type"]=> + int(1) + ["server_port"]=> + int(49749) + ["remote_port"]=> + int(49758) + ["remote_ip"]=> + string(9) "127.0.0.1" + ["from_id"]=> + int(1) + ["connect_time"]=> + int(1496842883) + ["last_time"]=> + int(1496842884) + } + */ + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/getClientList.phpt b/vendor/swoole/tests/swoole_server/getClientList.phpt new file mode 100755 index 0000000..addd16f --- /dev/null +++ b/vendor/swoole/tests/swoole_server/getClientList.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: get client list +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("getClientList", [])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert(is_array($data) && count($data) === 1); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/getLastError.phpt b/vendor/swoole/tests/swoole_server/getLastError.phpt new file mode 100755 index 0000000..82e5e69 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/getLastError.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: get last error +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("getLastError", [])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === 0); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/getSocket.phpt b/vendor/swoole/tests/swoole_server/getSocket.phpt new file mode 100755 index 0000000..a0e9126 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/getSocket.phpt @@ -0,0 +1,78 @@ +--TEST-- +swoole_server: +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + + $cli->on("connect", function (\swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("test"); + }); + + $cli->on("receive", function(\swoole_client $cli, $data){ + assert($data == 'Socket'); + $cli->send('shutdown'); + $cli->close(); + }); + + $cli->on("close", function(\swoole_client $cli) { + echo "SUCCESS\n"; + }); + + $cli->on("error", function(\swoole_client $cli) { + echo "error\n"; + }); + + $r = $cli->connect(TCP_SERVER_HOST, $port, 1); + assert($r); + Swoole\Event::wait(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new \swoole_server(TCP_SERVER_HOST, $port); + $socket = $serv->getSocket(); + $serv->set([ + "worker_num" => 1, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $rid, $data) use ($socket) + { + if (trim($data) == 'shutdown') + { + $serv->shutdown(); + return; + } + else { + $serv->send($fd, get_resource_type($socket)); + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/heartbeat.phpt b/vendor/swoole/tests/swoole_server/heartbeat.phpt new file mode 100755 index 0000000..9f1d214 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/heartbeat.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_server: heart beat false +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("heartbeat", [false])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + // TODO +// var_dump($data); + + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/heartbeat_true.phpt b/vendor/swoole/tests/swoole_server/heartbeat_true.phpt new file mode 100755 index 0000000..c2ee66c --- /dev/null +++ b/vendor/swoole/tests/swoole_server/heartbeat_true.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_server: heart beat (true) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("heartbeat", [true])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + // TODO +// var_dump($data); + + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/heartbeat_with_base.phpt b/vendor/swoole/tests/swoole_server/heartbeat_with_base.phpt new file mode 100755 index 0000000..2e8c7f0 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/heartbeat_with_base.phpt @@ -0,0 +1,55 @@ +--TEST-- +swoole_server: heart beat with SWOOLE_BASE +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + if (!$client->connect('127.0.0.1', 9501, 5, 0)) + { + echo "Over flow. errno=" . $client->errCode; + die("\n"); + } + $s1 = time(); + assert($client->recv() === ''); + $s2 = time(); + assert($s2 - $s1 > 1); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE); + $serv->set(array( + 'heartbeat_check_interval' => 1, + 'heartbeat_idle_time' => 2, + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_server/kill_task_worker_01.phpt b/vendor/swoole/tests/swoole_server/kill_task_worker_01.phpt new file mode 100755 index 0000000..c63be95 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/kill_task_worker_01.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_server: kill task worker [SWOOLE_BASE] + +--SKIPIF-- +<?php require __DIR__ . "/../include/skipif.inc"; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . "/../include/swoole.inc"; + +const PROC_NAME = 'swoole_unittest_server_task_worker'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + for ($i = 0; $i < 5; $i++) + { + //杀死进程 + shell_exec("ps aux | grep \"" . PROC_NAME . "\" |grep -v grep| awk '{ print $2}' | xargs kill"); + //判断进程是否存在 + assert(intval(shell_exec("ps aux | grep \"" . PROC_NAME . "\" |grep -v grep| awk '{ print $2}'")) > 0); + } + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503, SWOOLE_BASE); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null', 'task_worker_num' => 1,]); + $serv->on("WorkerStart", function (\swoole_server $serv, $worker_id) use ($pm) { + if ($worker_id = 1) + { + swoole_set_process_name(PROC_NAME); + $pm->wakeup(); + } + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + }); + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + return array("code" => 0, 'message' => 'hello world', 'sid' => uniqid()); + }); + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/kill_task_worker_02.phpt b/vendor/swoole/tests/swoole_server/kill_task_worker_02.phpt new file mode 100755 index 0000000..5e765e8 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/kill_task_worker_02.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_server: kill task worker [SWOOLE_PROCESS] + +--SKIPIF-- +<?php require __DIR__ . "/../include/skipif.inc"; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . "/../include/swoole.inc"; + +const PROC_NAME = 'swoole_unittest_server_task_worker'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + for ($i = 0; $i < 5; $i++) + { + //杀死进程 + shell_exec("ps aux | grep \"" . PROC_NAME . "\" |grep -v grep| awk '{ print $2}' | xargs kill"); + //判断进程是否存在 + assert(intval(shell_exec("ps aux | grep \"" . PROC_NAME . "\" |grep -v grep| awk '{ print $2}'")) > 0); + } + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503, SWOOLE_PROCESS); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null', 'task_worker_num' => 1,]); + $serv->on("WorkerStart", function (\swoole_server $serv, $worker_id) use ($pm) { + if ($worker_id = 1) + { + swoole_set_process_name(PROC_NAME); + $pm->wakeup(); + } + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + }); + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + return array("code" => 0, 'message' => 'hello world', 'sid' => uniqid()); + }); + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/kill_worker_01.phpt b/vendor/swoole/tests/swoole_server/kill_worker_01.phpt new file mode 100755 index 0000000..f68ff04 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/kill_worker_01.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_server: kill worker [SWOOLE_BASE] + +--SKIPIF-- +<?php require __DIR__ . "/../include/skipif.inc"; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . "/../include/bootstrap.php"; + +const WORKER_PROC_NAME = 'swoole_unittest_server_event_worker'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + for ($i = 0; $i < 1; $i++) + { + //杀死进程 + shell_exec("ps aux | grep \"" . WORKER_PROC_NAME . "\" |grep -v grep| awk '{ print $2}' | xargs kill"); + //判断进程是否存在 + assert(intval(shell_exec("ps aux | grep \"" . WORKER_PROC_NAME . "\" |grep -v grep| awk '{ print $2}'")) > 0); + } + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503, SWOOLE_BASE); + $serv->set(["worker_num" => 2, 'log_file' => '/dev/null',]); + $serv->on("WorkerStart", function (\swoole_server $serv, $worker_id) use ($pm) { + if ($worker_id == 0) + { + swoole_set_process_name(WORKER_PROC_NAME); + $pm->wakeup(); + } + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/kill_worker_02.phpt b/vendor/swoole/tests/swoole_server/kill_worker_02.phpt new file mode 100755 index 0000000..8d60192 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/kill_worker_02.phpt @@ -0,0 +1,52 @@ +--TEST-- +swoole_server: kill worker [SWOOLE_PROCESS] + +--SKIPIF-- +<?php require __DIR__ . "/../include/skipif.inc"; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . "/../include/swoole.inc"; + +const WORKER_PROC_NAME = 'swoole_unittest_server_event_worker'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + for ($i = 0; $i < 5; $i++) + { + //杀死进程 + shell_exec("ps aux | grep \"" . WORKER_PROC_NAME . "\" |grep -v grep| awk '{ print $2}' | xargs kill"); + //判断进程是否存在 + assert(intval(shell_exec("ps aux | grep \"" . WORKER_PROC_NAME . "\" |grep -v grep| awk '{ print $2}'")) > 0); + } + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503, SWOOLE_PROCESS); + $serv->set(["worker_num" => 2, 'log_file' => '/dev/null',]); + $serv->on("WorkerStart", function (\swoole_server $serv, $worker_id) use ($pm) { + if ($worker_id == 0) + { + swoole_set_process_name(WORKER_PROC_NAME); + $pm->wakeup(); + } + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/length_protocol.phpt b/vendor/swoole/tests/swoole_server/length_protocol.phpt new file mode 100755 index 0000000..172c2bb --- /dev/null +++ b/vendor/swoole/tests/swoole_server/length_protocol.phpt @@ -0,0 +1,104 @@ +--TEST-- +swoole_server: (length protocol) recv 100k packet + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_server/TestServer.php'; + +class PkgServer extends TestServer +{ + protected $show_lost_package = true; + function onReceive($serv, $fd, $reactor_id, $data) + { + $header = unpack('Nlen/Nindex/Nsid', substr($data, 0, 12)); + if ($header['index'] % 1000 == 0) + { + //echo "#{$header['index']} recv package. sid={$header['sid']}, length=" . strlen($data) . ", bytes={$this->recv_bytes}\n"; + } + if ($header['index'] > self::PKG_NUM) + { + echo "invalid index #{$header['index']}\n"; + } + $this->index[$header['index']] = true; + } + + function onWorkerStart($serv, $wid) + { + global $pm; + $pm->wakeup(); + } +} + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP); + if (!$client->connect('127.0.0.1', 9501)) + { + exit("connect failed\n"); + } + + $bytes = 0; + $pkg_bytes = 0; + + for ($i = 0; $i < TestServer::PKG_NUM; $i++) + { + $len = rand(1000, 1024 * 128 - 8); + $sid = rand(10000, 99999); + + $pkt = pack('NNN', $len + 8, $i, $sid); + $pkt .= str_repeat('A', $len); + + $pkg_bytes += strlen($pkt); + +// if ($i % 1000 == 0) +// { +// echo "#{$i} send package. sid={$sid}, length=" . ($len + 10) . ", total bytes={$pkg_bytes}\n"; +// } + if (!$client->send($pkt)) + { + break; + } + $bytes += strlen($pkt); + } + + $recv = $client->recv(); + echo $recv; + //echo "send ".TestServer::PKG_NUM." packet sucess, send $bytes bytes\n"; + $client->close(); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new PkgServer(true); + $serv->set([ + 'worker_num' => 1, + //'dispatch_mode' => 1, + 'log_file' => '/dev/null', + 'open_length_check' => true, + 'package_max_length' => 1024 * 1024, + 'package_length_type' => 'N', + 'package_length_offset' => 0, + 'package_body_offset' => 4, + 'task_worker_num' => 0 + ]); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECTF-- +end +Total count=100000, bytes=%d diff --git a/vendor/swoole/tests/swoole_server/listen_fail.phpt b/vendor/swoole/tests/swoole_server/listen_fail.phpt new file mode 100755 index 0000000..34f2b69 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/listen_fail.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_server: +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +//调高log_level +Swoole\Async::set(['log_level' => 8]); +try +{ + $serv = new swoole_server('192.0.0.1', 80); +} +catch(swoole_exception $e) +{ + assert($e->getCode() == 99); +} +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/max_request.phpt b/vendor/swoole/tests/swoole_server/max_request.phpt new file mode 100755 index 0000000..7c69ba1 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/max_request.phpt @@ -0,0 +1,72 @@ +--TEST-- +swoole_server: max_request + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; +$counter = new swoole_atomic(); + +$pm->parentFunc = function ($pid) +{ + $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set(["open_eof_check" => true, "package_eof" => "\r\n\r\n"]); + $r = $client->connect("127.0.0.1", 9503, -1); + if ($r === false) + { + echo "ERROR"; + exit; + } + for ($i = 0; $i < 4000; $i++) + { + $data = "PKG-$i" . str_repeat('A', rand(100, 20000)) . "\r\n\r\n"; + $client->send($data); + $ret = $client->recv(); + assert($ret and strlen($ret) == strlen($data) + 8); + } + $client->close(); + global $counter; + assert($counter->get() > 10); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503); + $serv->set([ + "worker_num" => 4, + 'dispatch_mode' => 1, + "open_eof_split" => true, + "package_eof" => "\r\n\r\n", + 'max_request' => 200, + 'log_file' => '/dev/null', + ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + global $counter; + $counter->add(1); + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + $serv->send($fd, "Server: $data"); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/pid_file.phpt b/vendor/swoole/tests/swoole_server/pid_file.phpt new file mode 100755 index 0000000..de9bbff --- /dev/null +++ b/vendor/swoole/tests/swoole_server/pid_file.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_server: pid_file +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +const PID_FILE = __DIR__.'/test.pid'; +$port = 9508; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + assert(is_file(PID_FILE)); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port); + $serv->set(array( + "worker_num" => 1, + 'pid_file' => PID_FILE, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +clearstatcache(); +assert(!is_file(PID_FILE)); +?> + +--EXPECT-- + diff --git a/vendor/swoole/tests/swoole_server/protect.phpt b/vendor/swoole/tests/swoole_server/protect.phpt new file mode 100755 index 0000000..c48f610 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/protect.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: protect +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("protect", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/protect_false.phpt b/vendor/swoole/tests/swoole_server/protect_false.phpt new file mode 100755 index 0000000..3f19a29 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/protect_false.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: protect($fd, false) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("protect", [2, false])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/reload.phpt b/vendor/swoole/tests/swoole_server/reload.phpt new file mode 100755 index 0000000..3bf760e --- /dev/null +++ b/vendor/swoole/tests/swoole_server/reload.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: reload +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("reload", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/request_slowlog.phpt b/vendor/swoole/tests/swoole_server/request_slowlog.phpt new file mode 100755 index 0000000..7636300 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/request_slowlog.phpt @@ -0,0 +1,78 @@ +--TEST-- +swoole_server: slowlog +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +//$port = get_one_free_port(); + +$port = 9501; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($port, $pm) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 + if (!$client->connect('127.0.0.1', $port, 3)) + { + exit("connect failed\n"); + } + echo $client->recv(); + assert($client->send("Request\n")); + echo $client->recv(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port); + $serv->set([ + 'worker_num' => 1, + 'task_worker_num' => 1, + 'request_slowlog_file' => __DIR__ . '/slow.log', + 'trace_event_worker' => true, + 'request_slowlog_timeout' => 1, + 'trace_flags' => SWOOLE_TRACE_ALL, + 'log_level' => SWOOLE_LOG_WARNING, +// 'log_file' => '/dev/null', + ]); + $serv->on("workerStart", function ($serv, $wid) use ($pm) { + $pm->wakeup(); + global $argv; + if ($serv->taskworker) { + swoole_set_process_name('php '.$argv[0].': task worker #'.$wid); + } else { + swoole_set_process_name('php '.$argv[0].': event worker #'.$wid); + } + }); + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) { + sleep(2); + $serv->send($data[2], "Task Finish\n"); + }); + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) { + + }); + $serv->on('connect', function (swoole_server $serv, $fd) { + $serv->task([str_repeat("A", 1024 * 1024 * 2), 'task', $fd]); + }); + $serv->on('receive', function ($serv, $fd, $from_id, $data) { + sleep(2); + $serv->send($fd, "Hello World\n"); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +Task Finish +Hello World diff --git a/vendor/swoole/tests/swoole_server/sendMessage.phpt b/vendor/swoole/tests/swoole_server/sendMessage.phpt new file mode 100755 index 0000000..209de3a --- /dev/null +++ b/vendor/swoole/tests/swoole_server/sendMessage.phpt @@ -0,0 +1,41 @@ +--TEST-- +swoole_server: send message +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) use($port) { + $r = $cli->send(opcode_encode("sendMessage", ["SUCCESS", 1])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $msg) = opcode_decode($recv); + echo $msg; + swoole_event_exit(); +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/sendMessage_02.phpt b/vendor/swoole/tests/swoole_server/sendMessage_02.phpt new file mode 100755 index 0000000..08da600 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/sendMessage_02.phpt @@ -0,0 +1,107 @@ +--TEST-- +swoole_server: send message [02] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set([ + 'package_eof' => "\r\n", + 'open_eof_check' => true, + 'open_eof_split' => true, + ]); + if (!$client->connect('127.0.0.1', 9501)) + { + exit("connect failed\n"); + } + $list = []; + for ($i = 0; $i < 7; $i++) + { + $data = $client->recv(); + if ($data === false or $data === '') + { + echo "ERROR\n"; + break; + } + $list[] = intval($data); + } + sort($list); + assert($list == range(0, 6)); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP ); + $serv->set([ + 'log_file' => '/dev/null', + 'worker_num' => 4, + 'task_worker_num' => 3, + ]); + + $lock = new swoole\lock(); + + $process = new \Swoole\Process(function ($process) use ($serv) { + while (true) + { + $r = $process->read(); + if (!$r) + { + continue; + } + $cmd = json_decode($r, true); + for ($i = 0; $i < ($serv->setting['worker_num'] + $serv->setting['task_worker_num']); $i++) + { + $serv->sendMessage(['worker_id' => $i, 'fd' => $cmd['fd']], $i); + } + } + }); + + $serv->addProcess($process); + $serv->on("workerStart", function ($serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('connect', function (swoole_server $serv, $fd) use ($process) { + $process->write(json_encode(["fd" => $fd])); + }); + $serv->on('receive', function ($serv, $fd, $from_id, $data) { + + }); + + $serv->on('pipeMessage', function (swoole_server $serv, $worker_id, $data) use ($lock) { + //$lock->lock(); + $serv->send($data['fd'], $data['worker_id']."\r\n"); + //$lock->unlock(); + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + + $serv->start(); +}; + + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/sendfile.phpt b/vendor/swoole/tests/swoole_server/sendfile.phpt new file mode 100755 index 0000000..a039f25 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/sendfile.phpt @@ -0,0 +1,43 @@ +--TEST-- +swoole_server: sendfile +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("sendfile", [2, __FILE__])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + $len = unpack("N", substr($recv, 0, 4))[1]; + assert($len - 4 === strlen(substr($recv, 4))); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/sendfile_02.phpt b/vendor/swoole/tests/swoole_server/sendfile_02.phpt new file mode 100755 index 0000000..2a277b8 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/sendfile_02.phpt @@ -0,0 +1,72 @@ +--TEST-- +swoole_server: sendfile [02] +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($pm) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP , SWOOLE_SOCK_SYNC); //同步阻塞 + if (!$client->connect('127.0.0.1', 9501)) + { + exit("connect failed\n"); + } + + $socket = $client->getSocket(); + socket_set_option($socket, SOL_SOCKET, SO_SNDBUF, 65536); + socket_set_option($socket, SOL_SOCKET, SO_RCVBUF, 65536); + + $N = filesize(TEST_IMAGE); + $bytes = 0; + while($bytes < $N) + { + $n = rand(8192, 65536); + $r = $client->recv($n); + if (!$r) + { + break; + } + usleep(10000); + $bytes += strlen($r); + } + assert($bytes == $N); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP ); + $serv->set([ + 'log_file' => '/dev/null', + 'kernel_socket_send_buffer_size' => 65536, + ]); + $serv->on("workerStart", function ($serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('connect', function (swoole_server $serv, $fd) + { + $serv->sendfile($fd, TEST_IMAGE); + }); + $serv->on('receive', function ($serv, $fd, $from_id, $data) + { + + }); + $serv->start(); +}; + + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/sendfile_ssl.phpt b/vendor/swoole/tests/swoole_server/sendfile_ssl.phpt new file mode 100755 index 0000000..91c3e2a --- /dev/null +++ b/vendor/swoole/tests/swoole_server/sendfile_ssl.phpt @@ -0,0 +1,74 @@ +--TEST-- +swoole_server: sendfile with SSL +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + $client = new swoole_client(SWOOLE_SOCK_TCP | SWOOLE_SSL, SWOOLE_SOCK_SYNC); //同步阻塞 + if (!$client->connect('127.0.0.1', 9501)) + { + exit("connect failed\n"); + } + + $socket = $client->getSocket(); + socket_set_option($socket, SOL_SOCKET, SO_SNDBUF, 65536); + socket_set_option($socket, SOL_SOCKET, SO_RCVBUF, 65536); + + $N = filesize(TEST_IMAGE); + $bytes = 0; + $data = ''; + while ($bytes < $N) + { + $n = rand(8192, 65536); + $r = $client->recv($n); + if (!$r) + { + break; + } + usleep(10000); + $bytes += strlen($r); + $data .= $r; + } + assert($bytes == $N); + assert(md5_file(TEST_IMAGE) == md5($data)); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) { + $serv = new swoole_server("127.0.0.1", 9501, SWOOLE_BASE, SWOOLE_SOCK_TCP | SWOOLE_SSL); + $serv->set([ + //'log_file' => '/dev/null', + 'kernel_socket_send_buffer_size' => 65536, + 'ssl_cert_file' => dirname(__DIR__) . '/include/api/swoole_http_server/localhost-ssl/server.crt', + 'ssl_key_file' => dirname(__DIR__) . '/include/api/swoole_http_server/localhost-ssl/server.key', + ]); + $serv->on("workerStart", function ($serv) use ($pm) { + $pm->wakeup(); + }); + $serv->on('connect', function (swoole_server $serv, $fd) { + $serv->sendfile($fd, TEST_IMAGE); + }); + $serv->on('receive', function ($serv, $fd, $from_id, $data) { + + }); + $serv->start(); +}; + + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/shutdown.phpt b/vendor/swoole/tests/swoole_server/shutdown.phpt new file mode 100755 index 0000000..5e61086 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/shutdown.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: shutdown +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("shutdown", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/slow_client.phpt b/vendor/swoole/tests/swoole_server/slow_client.phpt new file mode 100755 index 0000000..cdfd419 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/slow_client.phpt @@ -0,0 +1,78 @@ +--TEST-- +swoole_server: send big pipe message +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); + +const N = 1024 * 1024 * 1; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($port) +{ + $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); //同步阻塞 + if (!$client->connect('127.0.0.1', $port)) + { + exit("connect failed\n"); + } + + $socket = $client->getSocket(); + socket_set_option($socket, SOL_SOCKET, SO_SNDBUF, 65536); + socket_set_option($socket, SOL_SOCKET, SO_RCVBUF, 65536); + + $bytes = 0; + while($bytes < N) + { + $n = rand(8192, 65536); + $r = $client->recv($n); + if (!$r) + { + break; + } + usleep(10000); + $bytes += strlen($r); + } + assert($bytes == N); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + $serv = new swoole_server("127.0.0.1", $port); + $serv->set([ + 'worker_num' => 1, + 'log_file' => '/dev/null', + 'kernel_socket_send_buffer_size' => 65536, + ]); + $serv->on("workerStart", function ($serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('connect', function (swoole_server $serv, $fd) + { + $_send_data = str_repeat("A", N); + $serv->send($fd, $_send_data); + }); + $serv->on('receive', function ($serv, $fd, $from_id, $data) + { + + }); + $serv->start(); +}; + + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/stats.phpt b/vendor/swoole/tests/swoole_server/stats.phpt new file mode 100755 index 0000000..1486496 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/stats.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_server: +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("stats", [])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + /** + * array(7) { + ["start_time"]=> + int(1496842485) + ["connection_num"]=> + int(1) + ["accept_count"]=> + int(2) + ["close_count"]=> + int(1) + ["tasking_num"]=> + int(0) + ["request_count"]=> + int(0) + ["worker_request_count"]=> + int(0) + } + */ + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/stop.phpt b/vendor/swoole/tests/swoole_server/stop.phpt new file mode 100755 index 0000000..29f7186 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/stop.phpt @@ -0,0 +1,42 @@ +--TEST-- +swoole_server: stop +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/opcode_server.php"; +$port = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +suicide(2000); +usleep(500 * 1000); + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) { + $r = $cli->send(opcode_encode("stop", [2])); + assert($r !== false); +}, function(\swoole_client $cli, $recv) { + list($op, $data) = opcode_decode($recv); + assert($data === true); + swoole_event_exit(); + echo "SUCCESS"; +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server/task.phpt b/vendor/swoole/tests/swoole_server/task.phpt new file mode 100755 index 0000000..8623f69 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/task.phpt @@ -0,0 +1,47 @@ +--TEST-- +swoole_server: task & finish +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/tcp_task_server.php"; +$port = get_one_free_port(); +$closeServer = start_server($simple_tcp_server, TCP_SERVER_HOST, $port); + +$cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); + +$cli->on("connect", function(swoole_client $cli) { + assert($cli->isConnected() === true); + $cli->send("Test swoole_server::task Interface."); +}); + +$cli->on("receive", function(swoole_client $cli, $data){ + //echo "RECEIVE: $data\n"; + assert($data == "OK"); + $cli->close(); + assert($cli->isConnected() === false); +}); + +$cli->on("error", function(swoole_client $cli) { + echo "ERROR\n"; +}); + +$cli->on("close", function(swoole_client $cli) use($closeServer) { + echo "SUCCESS"; + $closeServer(); +}); + +$cli->connect(TCP_SERVER_HOST, $port); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/taskWaitMulti.phpt b/vendor/swoole/tests/swoole_server/taskWaitMulti.phpt new file mode 100755 index 0000000..33b1b8d --- /dev/null +++ b/vendor/swoole/tests/swoole_server/taskWaitMulti.phpt @@ -0,0 +1,93 @@ +--TEST-- +swoole_server: taskWaitMulti +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $cli->connect("127.0.0.1", $port, 0.5) or die("ERROR"); + + $cli->send("task-01") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->send("task-02") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->close(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port); + $serv->set(array( + "worker_num" => 1, + 'task_worker_num' => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + if ($data == 'task-01') + { + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $results = $serv->taskWaitMulti($tasks, 2); + } + else + { + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = mt_rand(1000, 9999); + $tasks[] = 0; + $results = $serv->taskWaitMulti($tasks, 0.2); + } + if (count($results) == 4) + { + $serv->send($fd, 'OK'); + } + else + { + $serv->send($fd, 'ERR'); + } + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + if ($data == 0) + { + usleep(300000); + } + return $data; + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/task_callback.phpt b/vendor/swoole/tests/swoole_server/task_callback.phpt new file mode 100755 index 0000000..7708078 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/task_callback.phpt @@ -0,0 +1,83 @@ +--TEST-- +swoole_server: task callback +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = 9508; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $cli->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); +// $cli->set(['open_eof_split' => true, 'package_eof' => "\r\n\r\n"]); + $cli->connect("127.0.0.1", $port, 0.5) or die("ERROR"); + + $cli->send("task-01") or die("ERROR"); + + $res = json_decode(trim($cli->recv()), true); + assert($res['code'] == 0); + assert($res['message'] == 'hello world'); + + echo "SUCCESS\n"; + + $res = json_decode(trim($cli->recv()), true); + assert($res['code'] == 0); + assert($res['message'] == 'hello world'); + echo "SUCCESS\n"; + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port); + $serv->set(array( + "worker_num" => 1, + 'task_worker_num' => 2, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + $serv->task(['type' => 'array', 'value' => $data], -1, function ($serv, $taskId, $data) use ($fd) { + $serv->send($fd, json_encode($data)."\r\n\r\n"); + }); + $serv->task(['type' => 'array', 'value' => $data, 'worker_id' => 0], 0, function ($serv, $taskId, $data) use ($fd) { + $serv->send($fd, json_encode($data)."\r\n\r\n"); + }); + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + return array("code" => 0, 'message' => 'hello world', 'sid' => uniqid()); + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +SUCCESS +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/task_max_request.phpt b/vendor/swoole/tests/swoole_server/task_max_request.phpt new file mode 100755 index 0000000..1dbcdc0 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/task_max_request.phpt @@ -0,0 +1,76 @@ +--TEST-- +swoole_server: task_max_request + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +const N = 4000; + +$counter1 = new swoole_atomic(); +$counter2 = new swoole_atomic(); +$counter3 = new swoole_atomic(); + +swoole_unittest_fork(function() { + + $serv = new \swoole_server("127.0.0.1", 9503); + $serv->set([ + "worker_num" => 1, + 'task_max_request' => 200, + 'task_worker_num' => 4, + 'log_file' => '/dev/null', + ]); + + $serv->on("WorkerStart", function (\swoole_server $serv) + { + if (!$serv->taskworker) { + for($i = 0; $i< N; $i++) { + $serv->task(array('type' => 'php', 'data' => RandStr::gen(100))); + } + } else { + //Task 进程启动数量 + global $counter3; + $counter3->add(1); + } + }); + + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + $serv->send($fd, "Server: $data"); + }); + + $serv->on('Task', function ($swooleServer, $task_id, $workerId, $data) + { + global $counter1; + $counter1->add(1); + return json_encode($data); + }); + + $serv->on('Finish', function (swoole_server $swooleServer, $workerId, $task_data) + { + global $counter2; + $counter2->add(1); + if ($counter2->get() == N) { + $swooleServer->shutdown(); + } + }); + + $serv->start(); +}); + +swoole_unittest_wait(); +assert($counter1->get() == 4000); +assert($counter2->get() == 4000); +assert($counter2->get() > 15); +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/task_queue.phpt b/vendor/swoole/tests/swoole_server/task_queue.phpt new file mode 100755 index 0000000..2d7be1f --- /dev/null +++ b/vendor/swoole/tests/swoole_server/task_queue.phpt @@ -0,0 +1,84 @@ +--TEST-- +swoole_server: task queue +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = 9508; +const N = 2048; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port, $pm) +{ + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $cli->connect("127.0.0.1", $port, 10) or die("ERROR"); + $cli->send("task-01") or die("ERROR"); + echo $cli->recv(); + $cli->close(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port, SWOOLE_BASE); + $serv->set(array( + "worker_num" => 1, + 'task_worker_num' => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + for ($i = 0; $i < 2048; $i++) + { + $data = array('id' => $i, 'fd' => $fd, 'data' => RandStr::getBytes(rand(2048, 4096))); + if ($serv->task($data) === false) + { + $serv->send($fd, "ERROR\n"); + return; + } + } + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + if ($task_id == 0) + { + sleep(1); + } + if ($task_id != $data['id']) + { + echo "ERROR, $task_id, {$data['id']}\n"; + } + if ($data['id'] == N - 1) + { + $serv->send($data['fd'], "OK"); + } + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_server/taskwait.phpt b/vendor/swoole/tests/swoole_server/taskwait.phpt new file mode 100755 index 0000000..c6578d1 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/taskwait.phpt @@ -0,0 +1,158 @@ +--TEST-- +swoole_server: taskwait +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = get_one_free_port(); + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port) +{ + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $cli->connect("127.0.0.1", $port, 0.5) or die("ERROR"); + + $cli->send("array-01") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->send("array-02") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->send("string-01") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->send("string-02") or die("ERROR"); + assert($cli->recv() == 'OK'); + $cli->send("timeout") or die("ERROR"); + assert($cli->recv() == 'OK'); + + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port); + $serv->set(array( + "worker_num" => 1, + 'task_worker_num' => 1, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) + { + if ($data == 'array-01') + { + $res = $serv->taskwait(['type' => 'array', 'value' => $data]); + if (!empty($res['name'])) + { + $serv->send($fd, 'OK'); + } + else + { + $serv->send($fd, 'ERR'); + } + } + elseif ($data == 'array-02') + { + $res = $serv->taskwait(['type' => 'string', 'value' => $data]); + if ($res == "hello world\n") + { + $serv->send($fd, 'OK'); + } + else + { + $serv->send($fd, 'ERR'); + } + } + elseif ($data == 'string-01') + { + $res = $serv->taskwait('array'); + if (!empty($res['name'])) + { + $serv->send($fd, 'OK'); + } + else + { + $serv->send($fd, 'ERR'); + } + } + elseif ($data == 'string-02') + { + $res = $serv->taskwait('string'); + if ($res == "hello world\n") + { + $serv->send($fd, 'OK'); + } + else + { + $serv->send($fd, 'ERR'); + } + } + elseif ($data == 'timeout') + { + $res = $serv->taskwait('timeout', 0.2); + if ($res === false) + { + $res = $serv->taskwait('string', 0.2); + if ($res === "hello world\n") + { + $serv->send($fd, 'OK'); + return; + } + } + $serv->send($fd, 'ERR'); + } + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) + { + if (is_array($data)) + { + if ($data['type'] == 'array') + { + return array('name' => 'rango', 'year' => 1987); + } + else + { + return "hello world\n"; + } + } + else + { + if ($data == 'array') + { + return array('name' => 'rango', 'year' => 1987); + } + elseif ($data == 'string') + { + return "hello world\n"; + } + elseif ($data == 'timeout') + { + usleep(300000); + return "task timeout\n"; + } + } + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server/unsock_dgram.phpt b/vendor/swoole/tests/swoole_server/unsock_dgram.phpt new file mode 100755 index 0000000..c8214b8 --- /dev/null +++ b/vendor/swoole/tests/swoole_server/unsock_dgram.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_server: unix socket dgram server + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +parent_child(function ($pid) +{ + usleep(100000); + $client = new \swoole_client(SWOOLE_SOCK_UNIX_DGRAM, SWOOLE_SOCK_SYNC); + $r = $client->connect(UNIXSOCK_SERVER_PATH, 0, -1); + if ($r === false) + { + echo "ERROR"; + exit; + } + $client->send("SUCCESS"); + echo $client->recv(); + $client->close(); +}, function () +{ + $serv = new \swoole_server(UNIXSOCK_SERVER_PATH, 0, SWOOLE_PROCESS, SWOOLE_UNIX_DGRAM); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null', 'daemonize' => true]); + $serv->on("WorkerStart", function (\swoole_server $serv) + { + swoole_timer_after(1000, function () use ($serv) + { + @unlink(UNIXSOCK_SERVER_PATH); + $serv->shutdown(); + }); + }); + $serv->on("packet", function (\swoole_server $serv, $data, $addr) + { + $serv->send($addr['address'], 'SUCCESS'); + }); + $serv->start(); +}); +?> + +--EXPECT-- +SUCCESS + + diff --git a/vendor/swoole/tests/swoole_server/unsock_stream.phpt b/vendor/swoole/tests/swoole_server/unsock_stream.phpt new file mode 100755 index 0000000..2572b1c --- /dev/null +++ b/vendor/swoole/tests/swoole_server/unsock_stream.phpt @@ -0,0 +1,59 @@ +--TEST-- +swoole_server: unix socket dgram server + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) +{ + $client = new \swoole_client(SWOOLE_SOCK_UNIX_STREAM, SWOOLE_SOCK_SYNC); + $r = $client->connect(UNIXSOCK_SERVER_PATH, 0, -1); + if ($r === false) + { + echo "ERROR"; + exit; + } + $client->send("SUCCESS"); + echo $client->recv(); + $client->close(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server(UNIXSOCK_SERVER_PATH, 0, SWOOLE_BASE, SWOOLE_SOCK_UNIX_STREAM); + $serv->set(["worker_num" => 1, ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + swoole_timer_after(1000, function () use ($serv) + { + @unlink(UNIXSOCK_SERVER_PATH); + $serv->shutdown(); + }); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + $serv->send($fd, 'SUCCESS'); + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_server/use_process.phpt b/vendor/swoole/tests/swoole_server/use_process.phpt new file mode 100755 index 0000000..f2cda8e --- /dev/null +++ b/vendor/swoole/tests/swoole_server/use_process.phpt @@ -0,0 +1,78 @@ +--TEST-- +swoole_server: user process + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; + +const SIZE = 8192* 5; + +$pm->parentFunc = function ($pid) +{ + $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $client->set(["open_eof_check" => true, "package_eof" => "\r\n\r\n"]); + $r = $client->connect("127.0.0.1", 9503, -1); + if ($r === false) + { + echo "ERROR"; + exit; + } + $client->send("SUCCESS"); + for($i=0; $i < 20; $i++) { + $ret = $client->recv(); + assert(strlen($ret) == SIZE +4); + } + $client->close(); + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server("127.0.0.1", 9503); + $serv->set(["worker_num" => 1, 'log_file' => '/dev/null']); + + $proc = new swoole\process(function ($process) use ($serv){ + //echo posix_getpid()."\n"; + while(true) { + $data = json_decode($process->read(), true); + //var_dump(SIZE); + for($i=0; $i < 10; $i++) { + $serv->send($data['fd'], str_repeat('A', SIZE)."\r\n\r\n"); + //echo "user process send ok\n"; + } + } + }, false, true); + + $serv->addProcess($proc); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) use ($proc) + { + $proc->write(json_encode(['fd' => $fd])); + for($i=0; $i < 10; $i++) { + $serv->send($fd, str_repeat('A', SIZE)."\r\n\r\n"); + //echo "worker send ok\n"; + } + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); + +?> + +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_server_port/swoole_server_port.phpt b/vendor/swoole/tests/swoole_server_port/swoole_server_port.phpt new file mode 100755 index 0000000..5477876 --- /dev/null +++ b/vendor/swoole/tests/swoole_server_port/swoole_server_port.phpt @@ -0,0 +1,75 @@ +--TEST-- +swoole_server: swoole server port +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +/** + + * Time: 下午4:34 + */ +require_once __DIR__ . '/../include/swoole.inc'; + +$simple_tcp_server = __DIR__ . "/../include/api/swoole_server/multi_protocol_server.php"; + +$port = get_one_free_port(); +$port1 = get_one_free_port(); +$port2 = get_one_free_port(); + +start_server($simple_tcp_server, TCP_SERVER_HOST, $port, "/dev/null", $port1, $port2); + +suicide(2000); +usleep(500 * 1000); + + +$tokens = [1,1,1]; +function checkDone() +{ + global $tokens; + array_pop($tokens); + + if (empty($tokens)) { + echo "SUCCESS"; + swoole_event_exit(); + } +} + +makeTcpClient(TCP_SERVER_HOST, $port, function(\swoole_client $cli) use($port) { + $r = $cli->send("$port\r\n"); + assert($r !== false); +}, function(\swoole_client $cli, $recv) use($port) { + list($op, $data) = opcode_decode($recv); + assert(intval($data) === $port); + checkDone(); +}); + +makeTcpClient(TCP_SERVER_HOST, $port1, function(\swoole_client $cli) use($port1) { + $r = $cli->send("$port1\r"); + assert($r !== false); +}, function(\swoole_client $cli, $recv) use($port1) { + list($op, $data) = opcode_decode($recv); + assert(intval($data) === $port1); + checkDone(); +}); + +makeTcpClient(TCP_SERVER_HOST, $port2, function(\swoole_client $cli) use($port2) { + $r = $cli->send("$port2\n"); + assert($r !== false); +}, function(\swoole_client $cli, $recv) use($port2) { + list($op, $data) = opcode_decode($recv); + assert(intval($data) === $port2); + checkDone(); +}); + +?> +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_server_port/tcp_eof.phpt b/vendor/swoole/tests/swoole_server_port/tcp_eof.phpt new file mode 100755 index 0000000..97d5450 --- /dev/null +++ b/vendor/swoole/tests/swoole_server_port/tcp_eof.phpt @@ -0,0 +1,71 @@ +--TEST-- +swoole_server_port: tcp port with eof +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +$pm = new ProcessManager; +ini_set("swoole.display_errors", "Off"); +$pm->parentFunc = function ($pid) +{ + $cli = new Swoole\Client(SWOOLE_SOCK_TCP); + $cli->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + if (!$cli->connect('127.0.0.1', 9502, 0.5)) + { + fail: + echo "ERROR\n"; + return; + } + //no eof, should be timeout here + if (!$cli->send("hello\r\n\r\n")) + { + goto fail; + } + $ret = $cli->recv(); + if (!$ret) + { + goto fail; + } + echo "OK\n"; + swoole_process::kill($pid); +}; + +$pm->childFunc = function () use ($pm) +{ + $http = new swoole_http_server("127.0.0.1", 9501, SWOOLE_BASE); + + $port2 = $http->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP); + $port2->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + + $port2->on('Receive', function ($serv, $fd, $rid, $data) + { + $serv->send($fd, "Swoole: $data\r\n\r\n"); + }); + + $http->set(array( + //'log_file' => '/dev/null' + )); + $http->on("WorkerStart", function (\swoole_server $serv) + { + /** + * @var $pm ProcessManager + */ + global $pm; + $pm->wakeup(); + }); + $http->on('request', function (swoole_http_request $request, swoole_http_response $response) + { + $response->end("OK\n"); + }); + $http->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +OK diff --git a/vendor/swoole/tests/swoole_socket_coro/accept.phpt b/vendor/swoole/tests/swoole_socket_coro/accept.phpt new file mode 100755 index 0000000..fa2a321 --- /dev/null +++ b/vendor/swoole/tests/swoole_socket_coro/accept.phpt @@ -0,0 +1,34 @@ +--TEST-- +swoole_coroutine_socket: accept +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +go(function () { + $sock = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + assert($sock->bind('127.0.0.1', 9601)); + assert($sock->listen(512)); + $conn = $sock->accept(); + assert($conn); + assert($conn instanceof Swoole\Coroutine\Socket); + + $data = $conn->recv(); + $json = json_decode($data, true); + assert(is_array($json), $json['data'] == 'hello'); + $conn->send("world\n"); + $conn->close(); +}); + +go(function () { + $conn = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + assert($conn->connect('127.0.0.1', 9601)); + $conn->send(json_encode(['data' => 'hello'])); + echo $conn->recv(); +}); +?> +--EXPECT-- +world diff --git a/vendor/swoole/tests/swoole_socket_coro/complete_test.phpt b/vendor/swoole/tests/swoole_socket_coro/complete_test.phpt new file mode 100755 index 0000000..3dab20c --- /dev/null +++ b/vendor/swoole/tests/swoole_socket_coro/complete_test.phpt @@ -0,0 +1,66 @@ +--TEST-- +complete test: server&&client&&timeout(millisecond) +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) { + $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, 0); + assert($socket instanceof Swoole\Coroutine\Socket); + assert($socket->errCode === 0); + go(function () use ($socket) { + assert($socket->connect('localhost', 9501)); + $i = 0.000; + while (true) { + $socket->send("hello"); + $server_reply = $socket->recv(.01); + assert($server_reply === 'swoole'); + co::sleep($i += .001); // after 10 times we sleep 0.01s to trigger server timeout + if ($i > .01) { + break; + } + } + co::sleep(0.5); + echo("client exit\n"); + $socket->close(); + }); + swoole_event_wait(); +}; + +$pm->childFunc = function () use ($pm) { + $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, 0); + assert($socket->bind('127.0.0.1', 9501)); + assert($socket->listen(128)); + go(function () use ($socket, $pm) { + $client = $socket->accept(); + assert($client instanceof Swoole\Coroutine\Socket); + $i = 0; + while (true) { + $client_data = $client->recv(.01); + if ($client->errCode > 0) { + assert($client->errCode === SOCKET_EAGAIN); //EAGAIN + break; + } else { + $i++; + assert($client_data === 'hello'); + $client->send('swoole'); + } + } + echo "$i\n"; + echo("sever exit\n"); + $client->close(); + $socket->close(); + }); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- +10 +sever exit +client exit diff --git a/vendor/swoole/tests/swoole_socket_coro/recv_timeout.phpt b/vendor/swoole/tests/swoole_socket_coro/recv_timeout.phpt new file mode 100755 index 0000000..b1bb77f --- /dev/null +++ b/vendor/swoole/tests/swoole_socket_coro/recv_timeout.phpt @@ -0,0 +1,44 @@ +--TEST-- +swoole_socket_coro: recv timeout +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; + +$pm = new ProcessManager; + +$pm->parentFunc = function ($pid) use ($pm) +{ + go(function () use ($pm) { + $conn = new Swoole\Coroutine\Socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + assert($conn->connect('127.0.0.1', 9501)); + $conn->send(json_encode(['data' => 'hello'])); + $ret = $conn->recv(0.2); + assert($ret === false); + assert($conn->errCode == SOCKET_EAGAIN); + }); + swoole_event_wait(); + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm) +{ + $serv = new \swoole_server('127.0.0.1', 9501, SWOOLE_BASE); + $serv->set(["worker_num" => 1, ]); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on("Receive", function (\swoole_server $serv, $fd, $reactorId, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> +--EXPECT-- diff --git a/vendor/swoole/tests/swoole_socket_coro/sendto.phpt b/vendor/swoole/tests/swoole_socket_coro/sendto.phpt new file mode 100755 index 0000000..c71b05e --- /dev/null +++ b/vendor/swoole/tests/swoole_socket_coro/sendto.phpt @@ -0,0 +1,48 @@ +--TEST-- +swoole_coroutine_socket: accept +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/lib/curl.php'; + +const N = 5; +//Server +go(function () { + $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_DGRAM, 0); + $socket->bind('127.0.0.1', 9601); + for ($i = 0; $i < N; $i++) + { + $peer = null; + $data = $socket->recvfrom($peer); + echo "[Server] recvfrom[{$peer['address']}:{$peer['port']}] : $data\n"; + $socket->sendto($peer['address'], $peer['port'], "Swoole: $data"); + } +}); + +//Client +go(function () { + $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_DGRAM, 0); + for ($i = 0; $i < N; $i++) + { + $socket->sendto('127.0.0.1', 9601, "hello-".$i); + $peer = null; + $data = $socket->recvfrom($peer); + echo "[Client] recvfrom[{$peer['address']}:{$peer['port']}] : $data\n"; + } +}); +swoole_event_wait(); +?> +--EXPECTF-- +[Server] recvfrom[127.0.0.1:%d] : hello-0 +[Client] recvfrom[127.0.0.1:9601] : Swoole: hello-0 +[Server] recvfrom[127.0.0.1:%d] : hello-1 +[Client] recvfrom[127.0.0.1:9601] : Swoole: hello-1 +[Server] recvfrom[127.0.0.1:%d] : hello-2 +[Client] recvfrom[127.0.0.1:9601] : Swoole: hello-2 +[Server] recvfrom[127.0.0.1:%d] : hello-3 +[Client] recvfrom[127.0.0.1:9601] : Swoole: hello-3 +[Server] recvfrom[127.0.0.1:%d] : hello-4 +[Client] recvfrom[127.0.0.1:9601] : Swoole: hello-4 diff --git a/vendor/swoole/tests/swoole_table/foreach.phpt b/vendor/swoole/tests/swoole_table/foreach.phpt new file mode 100755 index 0000000..429a204 --- /dev/null +++ b/vendor/swoole/tests/swoole_table/foreach.phpt @@ -0,0 +1,47 @@ +--TEST-- +swoole_table: iterator + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$table = new swoole_table(65536); + +$table->column('id', swoole_table::TYPE_INT); +$table->column('name', swoole_table::TYPE_STRING, 128); +$table->column('num', swoole_table::TYPE_FLOAT); + +if (!$table->create()) +{ + echo __LINE__." error"; +} +$table->set('test_key', array('id' => 1, 'name' => 'rango', 'num' => 3.1415926)); +$table->set('hello_world', array('id' => 100, 'name' => 'xinhua', 'num' => 399.66)); + +$_key = array(); +$_num = array(); +foreach ($table as $key => $value) +{ + $_key [] = $key; + $_num [] = $value['num']; +} +sort($_key); +sort($_num); +if (implode('', $_key) == 'hello_worldtest_key' and array_sum($_num) == 399.66 + 3.1415926) +{ + echo 'SUCCESS'; +} + +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_table/int.phpt b/vendor/swoole/tests/swoole_table/int.phpt new file mode 100755 index 0000000..cde638e --- /dev/null +++ b/vendor/swoole/tests/swoole_table/int.phpt @@ -0,0 +1,106 @@ +--TEST-- +swoole_table: int + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$table = new swoole_table(65536); + +$table->column('i8', swoole_table::TYPE_INT, 1); +$table->column('i16', swoole_table::TYPE_INT, 2); +$table->column('i32', swoole_table::TYPE_INT, 4); +$table->column('i64', swoole_table::TYPE_INT, 8); + +if (!$table->create()) +{ + echo __LINE__." error"; +} + +$ret = $table->set('test_key', array( + 'i8' => -120, + 'i16' => -30000, + 'i32' => -1247483648, + 'i64' => -9023372036854775808, +)); +if (!$ret) +{ + echo __LINE__." error"; +} + +$ret = $table->get('test_key'); +if (!$ret) +{ + echo __LINE__." error"; +} + +assert($ret['i8'] == -120); +assert($ret['i16'] == -30000); +assert($ret['i32'] == -1247483648); +assert($ret['i64'] == -9023372036854775808); + +$ret = $table->incr('test_key', 'i8', 8); +if (!$ret) +{ + echo __LINE__." error"; +} +assert($table->get('test_key', 'i8') == -120 + 8); + +$ret = $table->decr('test_key', 'i32', 8); +if (!$ret) +{ + echo __LINE__." error"; +} +assert($table->get('test_key', 'i32') == -1247483648 - 8); + + +$ret = $table->set('test_key', array( + 'i8' => 120, + 'i16' => 30000, + 'i32' => 1247483648, + 'i64' => 9023372036854775808, +)); +if (!$ret) +{ + echo __LINE__." error"; +} + +$ret = $table->get('test_key'); +if (!$ret) +{ + echo __LINE__." error"; +} + +assert($ret['i8'] == 120); +assert($ret['i16'] == 30000); +assert($ret['i32'] == 1247483648); +assert($ret['i64'] == 9023372036854775808); + +$ret = $table->incr('test_key', 'i8', 4); +if (!$ret) +{ + echo __LINE__." error"; +} +assert($table->get('test_key', 'i8') == 120 + 4); + +$ret = $table->decr('test_key', 'i32', 8); +if (!$ret) +{ + echo __LINE__." error"; +} +assert($table->get('test_key', 'i32') == 1247483648 - 8); + +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_table/key_value.phpt b/vendor/swoole/tests/swoole_table/key_value.phpt new file mode 100755 index 0000000..c805fe3 --- /dev/null +++ b/vendor/swoole/tests/swoole_table/key_value.phpt @@ -0,0 +1,97 @@ +--TEST-- +swoole_table key-value operate + +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +$table = new swoole_table(65536); + +$table->column('id', swoole_table::TYPE_INT); +$table->column('name', swoole_table::TYPE_STRING, 128); +$table->column('num', swoole_table::TYPE_FLOAT); + +if (!$table->create()) +{ + echo __LINE__." error"; +} +if (!$table->set('test_key', array('id' => 1, 'name' => 'rango', 'num' => 3.1415926))) +{ + echo __LINE__." error"; +} + +$ret = $table->get('test_key'); +if (!($ret and is_array($ret) and $ret['id'] == 1)) +{ + echo __LINE__." error"; +} + +$ret = $table->get('test_key', 'id'); +if (!($ret and $ret == 1)) +{ + echo __LINE__." error"; +} + +$ret = $table->exist('test_key'); +if (!($ret)) +{ + echo __LINE__." error"; +} + +$ret = $table->exist('test_key_not_exists'); +if ($ret) +{ + echo __LINE__." error"; +} + +$ret = $table->incr('test_key','id', 2); +if (!$ret) +{ + echo __LINE__." error"; +} +$_value = $table->get('test_key', 'id'); +if ($_value != 3) +{ + echo __LINE__." error"; +} + +$ret = $table->decr('test_key', 'id', 2); +if (!$ret) +{ + echo __LINE__ . " error"; +} +$_value = $table->get('test_key', 'id'); +if ($_value != 1) +{ + echo __LINE__ . " error"; +} + +$table->set('hello_world', array('id' => 100, 'name' => 'xinhua', 'num' => 399.66)); +if (count($table) != 2) +{ + echo __LINE__." error"; +} + +$ret = $table->del('test_key'); +if (!$ret) +{ + echo __LINE__." error"; +} +if ($table->exist('test_key')) +{ + echo __LINE__." error"; +} +echo "SUCCESS"; +?> + +--EXPECT-- +SUCCESS \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_timer/enable_coroutine.phpt b/vendor/swoole/tests/swoole_timer/enable_coroutine.phpt new file mode 100755 index 0000000..f0faf68 --- /dev/null +++ b/vendor/swoole/tests/swoole_timer/enable_coroutine.phpt @@ -0,0 +1,17 @@ +--TEST-- +enable_coroutine: enable_coroutine setting +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +swoole_async_set([ + 'enable_coroutine' => false +]); +swoole_timer_after(1, function () { + $uid = Co::getuid(); + echo "#{$uid}\n"; +}); +?> +--EXPECT-- +#-1 \ No newline at end of file diff --git a/vendor/swoole/tests/swoole_timer/greater_than_0.phpt b/vendor/swoole/tests/swoole_timer/greater_than_0.phpt new file mode 100755 index 0000000..054b98a --- /dev/null +++ b/vendor/swoole/tests/swoole_timer/greater_than_0.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_timer: Timer must be greater than 0 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +assert(@swoole_timer_after(0, function() {}) === false); +assert(@swoole_timer_after(-1, function() {}) === false); +assert(@swoole_timer_tick(0, function() {}) === false); +assert(@swoole_timer_tick(-1, function() {}) === false); +?> +--EXPECTF-- diff --git a/vendor/swoole/tests/swoole_timer/parameters_is_too_big.phpt b/vendor/swoole/tests/swoole_timer/parameters_is_too_big.phpt new file mode 100755 index 0000000..661c51f --- /dev/null +++ b/vendor/swoole/tests/swoole_timer/parameters_is_too_big.phpt @@ -0,0 +1,21 @@ +--TEST-- +swoole_timer: The given parameters is too big. +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +assert(@swoole_timer_after(86400001, function() {}) === false); +assert(@swoole_timer_after(86400001, function() {}) === false); +assert(@swoole_timer_tick(86400001, function() {}) === false); +assert(@swoole_timer_tick(86400001, function() {}) === false); +?> +--EXPECTF-- diff --git a/vendor/swoole/tests/swoole_timer/swoole_timer_after.phpt b/vendor/swoole/tests/swoole_timer/swoole_timer_after.phpt new file mode 100755 index 0000000..6f269ca --- /dev/null +++ b/vendor/swoole/tests/swoole_timer/swoole_timer_after.phpt @@ -0,0 +1,53 @@ +--TEST-- +swoole_timer: swoole_timer_after,swoole_timer_exists,swoole_timer_clear +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; + +class TimerTest { + public static $count = 0; + private $timer_id = null; + + protected function resetTimer($ms) { + if ($this->timer_id && swoole_timer_exists($this->timer_id)) { + swoole_timer_clear($this->timer_id); + $this->timer_id = null; + } + if (self::$count == 10) { + return; + } + $this->timer_id = swoole_timer_after($ms, array($this, 'onTimerTick')); + assert($this->timer_id > 0); + } + + public function onTimerTick() { + self::$count++; + echo "onTimerTick:" . self::$count . "\n"; + $this->resetTimer(10); + } +} + +$timer_test = new TimerTest(); +$timer_test->onTimerTick(); + +?> +--EXPECT-- +onTimerTick:1 +onTimerTick:2 +onTimerTick:3 +onTimerTick:4 +onTimerTick:5 +onTimerTick:6 +onTimerTick:7 +onTimerTick:8 +onTimerTick:9 +onTimerTick:10 diff --git a/vendor/swoole/tests/swoole_timer/task_worker.phpt b/vendor/swoole/tests/swoole_timer/task_worker.phpt new file mode 100755 index 0000000..b5488bb --- /dev/null +++ b/vendor/swoole/tests/swoole_timer/task_worker.phpt @@ -0,0 +1,81 @@ +--TEST-- +swoole_timer: call after in Task-Worker +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +$port = 9508; + +$pm = new ProcessManager; +$pm->parentFunc = function ($pid) use ($port, $pm) +{ + $cli = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); + $cli->set(['open_eof_check' => true, "package_eof" => "\r\n\r\n"]); + $cli->connect("127.0.0.1", $port, 5) or die("ERROR"); + + $cli->send("task-01") or die("ERROR"); + for ($i = 0; $i < 4; $i++) + { + echo trim($cli->recv())."\n"; + } + $pm->kill(); +}; + +$pm->childFunc = function () use ($pm, $port) +{ + ini_set('swoole.display_errors', 'Off'); + $serv = new swoole_server("127.0.0.1", $port); + $serv->set(array( + "worker_num" => 1, + 'task_worker_num' => 2, + 'log_file' => '/dev/null', + )); + $serv->on("WorkerStart", function (\swoole_server $serv) use ($pm) + { + $pm->wakeup(); + }); + $serv->on('receive', function (swoole_server $serv, $fd, $rid, $data) { + $serv->task([$fd, 'timer']); + }); + + $serv->on('task', function (swoole_server $serv, $task_id, $worker_id, $data) { + list($fd) = $data; + swoole_timer::after(500, function () use ($serv, $fd) { + $serv->send($fd, "500\r\n\r\n"); + swoole_timer::after(300, function () use ($serv, $fd) { + $serv->send($fd, "800\r\n\r\n"); + }); + }); + swoole_timer::after(1000, function () use ($serv, $fd) { + $serv->send($fd, "1000\r\n\r\n"); + }); + swoole_timer::after(2000, function () use ($serv, $fd) { + $serv->send($fd, "2000\r\n\r\n"); + }); + }); + + $serv->on('finish', function (swoole_server $serv, $fd, $rid, $data) + { + + }); + $serv->start(); +}; + +$pm->childFirst(); +$pm->run(); +?> + +--EXPECT-- +500 +800 +1000 +2000 diff --git a/vendor/swoole/tests/swoole_websocket_server/test_send_large_request_data.phpt b/vendor/swoole/tests/swoole_websocket_server/test_send_large_request_data.phpt new file mode 100755 index 0000000..19a0cdf --- /dev/null +++ b/vendor/swoole/tests/swoole_websocket_server/test_send_large_request_data.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_websocket_server: test server with large data +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_websocket_server/send_large_request_data.php'; + +$swoole_websocket_server = __DIR__ . "/../include/api/swoole_websocket_server/swoole_websocket_server.php"; +$closeServer = start_server($swoole_websocket_server, WEBSOCKET_SERVER_HOST, $port = get_one_free_port()); + +send_large_request_data(WEBSOCKET_SERVER_HOST, $port); +echo "SUCCESS"; + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_websocket_server/test_send_small_request_data.phpt b/vendor/swoole/tests/swoole_websocket_server/test_send_small_request_data.phpt new file mode 100755 index 0000000..db45638 --- /dev/null +++ b/vendor/swoole/tests/swoole_websocket_server/test_send_small_request_data.phpt @@ -0,0 +1,27 @@ +--TEST-- +swoole_websocket_server: test server with small data +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +require_once __DIR__ . '/../include/api/swoole_websocket_server/send_small_request_data.php'; + +$swoole_websocket_server = __DIR__ . "/../include/api/swoole_websocket_server/swoole_websocket_server.php"; +$closeServer = start_server($swoole_websocket_server, WEBSOCKET_SERVER_HOST, $port = get_one_free_port()); + +send_small_request_data(WEBSOCKET_SERVER_HOST, $port); +echo "SUCCESS"; + +suicide(1000, SIGTERM, $closeServer); +?> +--EXPECT-- +SUCCESS diff --git a/vendor/swoole/tests/swoole_websocket_server/websocket_message.phpt b/vendor/swoole/tests/swoole_websocket_server/websocket_message.phpt new file mode 100755 index 0000000..727f861 --- /dev/null +++ b/vendor/swoole/tests/swoole_websocket_server/websocket_message.phpt @@ -0,0 +1,55 @@ +--TEST-- +swoole_http_client: websocket message +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> + +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require_once __DIR__ . '/../include/swoole.inc'; +include __DIR__ . "/../include/lib/class.websocket_client.php"; + +function start_swoole_ws_server() +{ + swoole_php_fork(function () + { + $serv = new swoole_websocket_server("127.0.0.1", 9501); + $serv->set(['log_file' => '/dev/null']); + $serv->on('Open', function ($swoole_server, $req) + { + }); + $serv->on('Message', function ($swoole_server, $frame) + { + $swoole_server->push($frame->fd, "hello " . $frame->data); + if ($frame->data == "shutdown") + { + $swoole_server->shutdown(); + } + }); + $serv->on('Close', function ($swoole_server, $fd) + { + }); + $serv->start(); + }); +} + +sleep(1); //wait the release of port 9501 +start_swoole_ws_server(); +sleep(1); + +$cli = new WebsocketClient; +$connected = $cli->connect('127.0.0.1', 9501, '/'); +assert($connected); +assert($cli->sendRecv("batman") == 'hello batman'); +assert($cli->sendRecv("spiderman") == 'hello spiderman'); +?> + +--EXPECT-- + +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_websocket_server/websocket_pingpong.phpt b/vendor/swoole/tests/swoole_websocket_server/websocket_pingpong.phpt new file mode 100755 index 0000000..c66ebd1 --- /dev/null +++ b/vendor/swoole/tests/swoole_websocket_server/websocket_pingpong.phpt @@ -0,0 +1,51 @@ +--TEST-- +swoole_http_client: websocket push 2 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require __DIR__ . '/../include/swoole.inc'; +require __DIR__ . '/../include/lib/class.websocket_client.php'; + +function start_swoole_ws_server() +{ + swoole_php_fork(function () + { + $serv = new swoole_websocket_server("127.0.0.1", 9501); + $serv->set(['log_file' => '/dev/null']); + $serv->on('Open', function ($swoole_server, $req) + { + }); + + $serv->on('Message', function ($swoole_server, $frame) + { + $swoole_server->push($frame->fd, "hello " . $frame->data); + }); + + $serv->on('Close', function ($swoole_server, $fd) + { + }); + + $serv->start(); + }); +} +sleep(1); //wait the release of port 9501 +start_swoole_ws_server(); +sleep(1); + +$cli = new WebsocketClient; +$connected = $cli->connect('127.0.0.1', 9501, '/'); +echo $cli->checkConnection(),"\n"; +?> +Done +--EXPECTREGEX-- +1 +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/swoole_websocket_server/websocket_push.phpt b/vendor/swoole/tests/swoole_websocket_server/websocket_push.phpt new file mode 100755 index 0000000..5bb0fba --- /dev/null +++ b/vendor/swoole/tests/swoole_websocket_server/websocket_push.phpt @@ -0,0 +1,55 @@ +--TEST-- +swoole_http_client: websocket push 3 +--SKIPIF-- +<?php require __DIR__ . '/../include/skipif.inc'; ?> +--INI-- +assert.active=1 +assert.warning=1 +assert.bail=0 +assert.quiet_eval=0 + +--FILE-- +<?php +require_once __DIR__ . '/../include/bootstrap.php'; +require __DIR__ . '/../include/swoole.inc'; +require __DIR__ . '/../include/lib/class.websocket_client.php'; + +function start_swoole_ws_server() { + swoole_php_fork(function () + { + $serv = new swoole_websocket_server("127.0.0.1", 9501); + $serv->set(['log_file' => '/dev/null']); + $serv->on('Open', function ($swoole_server, $req) + { + }); + + $serv->on('Message', function ($swoole_server, $frame) + { + $swoole_server->push($frame->fd, "hello " . $frame->data); + sleep(1); + $swoole_server->push($frame->fd, "hello " . $frame->data . " again"); + }); + + $serv->on('Close', function ($swoole_server, $fd) + { + }); + + $serv->start(); + }); +} +sleep(1); //wait the release of port 9501 +start_swoole_ws_server(); +sleep(1); + +$cli = new WebsocketClient; +$connected = $cli->connect('127.0.0.1', 9501, '/'); +echo $cli->sendRecv("batman"), "\r\n"; +sleep(2); +echo $cli->recvData(), "\r\n"; +?> +Done +--EXPECTREGEX-- +hello batman +hello batman again +Done.* +--CLEAN-- diff --git a/vendor/swoole/tests/template.phpt b/vendor/swoole/tests/template.phpt new file mode 100755 index 0000000..3b9a0fb --- /dev/null +++ b/vendor/swoole/tests/template.phpt @@ -0,0 +1,9 @@ +--TEST-- +{{test_name}}: {{test_intro}} +--SKIPIF-- +<?php require __DIR__ . '{{dir_deep}}/include/skipif.inc'; ?> +--FILE-- +<?php +require_once __DIR__ . '{{dir_deep}}/include/bootstrap.php'; +?> +--EXPECT-- \ No newline at end of file diff --git a/vendor/swoole/tests/test-all-version.sh b/vendor/swoole/tests/test-all-version.sh new file mode 100755 index 0000000..d6a6929 --- /dev/null +++ b/vendor/swoole/tests/test-all-version.sh @@ -0,0 +1,14 @@ +to_php7.sh +cd ../ +./make.sh +cd tests/ +./start.sh +cd ../ +./make.sh +cd tests/ +to_php72.sh +cd ../ +./make.sh +cd tests/ +./start.sh + diff --git a/vendor/swoole/tests/test.sql b/vendor/swoole/tests/test.sql new file mode 100755 index 0000000..7e50789 --- /dev/null +++ b/vendor/swoole/tests/test.sql @@ -0,0 +1,216 @@ +-- phpMyAdmin SQL Dump +-- version 4.0.10 +-- http://www.phpmyadmin.net +-- +-- 主机: 127.0.0.1 +-- 生成日期: 2018-04-19 06:46:07 +-- 服务器版本: 5.7.16 +-- PHP 版本: 7.2.0 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; + +-- +-- 数据库: `test` +-- + +-- -------------------------------------------------------- + +-- +-- 表的结构 `ckl` +-- + +CREATE TABLE IF NOT EXISTS `ckl` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain` varchar(128) NOT NULL, + `path` varchar(128) NOT NULL, + `name` varchar(32) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `userinfo` +-- + +CREATE TABLE IF NOT EXISTS `userinfo` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(40) NOT NULL, + `level` int(11) NOT NULL, + `passwd` varchar(40) NOT NULL, + `regtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `big_n` bigint(20) NOT NULL, + `data` json NOT NULL, + `lastlogin_ip` int(11) NOT NULL, + `price` double NOT NULL, + `mdate` date NOT NULL, + `mtime` time NOT NULL, + `mdatetime` datetime NOT NULL, + `year` year(4) NOT NULL, + `int8_t` tinyint(11) NOT NULL, + `mshort` smallint(6) NOT NULL, + `mtext` text NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=144 ; + +-- +-- 转存表中的数据 `userinfo` +-- + +INSERT INTO `userinfo` (`id`, `name`, `level`, `passwd`, `regtime`, `big_n`, `data`, `lastlogin_ip`, `price`, `mdate`, `mtime`, `mdatetime`, `year`, `int8_t`, `mshort`, `mtext`) VALUES +(1, 'jack', 199, 'xuyou', '2015-01-01 18:00:00', 999000, 'null', 1270, 0.22, '0000-00-00', '21:52:33', '2018-04-17 04:16:20', 1989, 127, 32767, ''), +(2, 'jack', 0, 'xuyou', '2016-05-19 16:00:00', 0, '{"a": 123}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 01:03:00', 1999, 0, 0, ''), +(3, '韩天峰', 0, 'xuyou', '2016-05-20 11:08:47', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(4, 'jack', 11, 'xuyou', '2016-05-20 11:17:33', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(5, 'jack', 0, 'xuyou', '2016-05-24 10:47:58', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(6, 'jack', 0, 'xuyou', '2016-05-24 10:49:04', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(7, 'rango22', 0, '123456', '2016-07-19 05:31:37', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(8, 'rango22', 0, '123456', '2016-07-19 05:37:03', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(9, 'hello', 99, '123456', '2017-07-03 11:32:01', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(10, 'hello', 99, '123456', '2017-07-03 11:37:37', 19999991, 'null', 7775533, 256.33, '2017-12-13', '09:51:29', '0000-00-00 00:00:00', 2015, 127, 32321, '我们都是中国人,你很好吗?'), +(11, 'hello', 0, '123456', '2017-07-03 11:37:49', 99999999, '{"exam": [{"hash": "690c8834", "mark": 70, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 80, "level": 1, "point": 2, "credit": 5, "remarks": "", "raw_mark": "70.00", "required": "必修"}, {"hash": "cfa8d530", "mark": 90, "name": "工程制图与CAD", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 4, "credit": 2.5, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cb20e313", "mark": 78, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 2.8, "credit": 2, "remarks": "", "raw_mark": "78.00", "required": "必修"}, {"hash": "b5acc996", "mark": 71, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 39, "level": 1, "point": 2.1, "credit": 3, "remarks": "", "raw_mark": "71.00", "required": "必修"}, {"hash": "408f80cf", "mark": 81, "name": "思想道德修养与法律基础", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 85, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "必修"}, {"hash": "49335642", "mark": 93, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "efba9f7e", "mark": 85, "name": "大学生就业指导", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "限选"}, {"hash": "ae282f8b", "mark": 80, "name": "军训", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3, "credit": 3, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "0eab47c9", "mark": 67, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 112, "level": 2, "point": 1.7, "credit": 7, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 83, "name": "大学物理Ⅱ", "pass": "通过", "type": "正常", "hours": 64, "level": 2, "point": 3.3, "credit": 4, "remarks": "", "raw_mark": "83.00", "required": "必修"}, {"hash": "60a3b855", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 0.7, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c13b6ed1", "mark": 80, "name": "公益劳动", "pass": "通过", "type": "正常", "hours": 8, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "dcb1fed5", "mark": 79, "name": "工程训练", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 2.9, "credit": 2, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 52, "name": "电路分析", "pass": "未通过", "type": "正常", "hours": 56, "level": 2, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "52.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 60, "name": "电路分析", "pass": "通过", "type": "补考1", "hours": 56, "level": 2, "point": 1, "credit": 3.5, "remarks": "", "raw_mark": "60.00", "required": "必修"}, {"hash": "86a4a2ec", "mark": 80, "name": "电路分析实验", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "893b0788", "mark": 81, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "faa9dd23", "mark": 80, "name": "计算机实验Ⅰ", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 66, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 1.6, "credit": 4, "remarks": "", "raw_mark": "66.00", "required": "必修"}, {"hash": "4dff4e51", "mark": 81, "name": "大学语文", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3.1, "credit": 1, "remarks": "", "raw_mark": "81.00", "required": "限选"}, {"hash": "9e8161b2", "mark": 90, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 4, "level": 2, "point": 4, "credit": 1, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 93, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "1ad047dd", "mark": 76, "name": "大学生心理健康", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 2.6, "credit": 2, "remarks": "", "raw_mark": "76.00", "required": "选修"}, {"hash": "d9dfb118", "mark": 67, "name": "线性代数", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.7, "credit": 3, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 37, "name": "大学物理Ⅱ", "pass": "未通过", "type": "正常", "hours": 64, "level": 3, "point": 0, "credit": 4, "remarks": "", "raw_mark": "37.00", "required": "必修"}, {"hash": "53e14717", "mark": 64, "name": "大学物理Ⅱ", "pass": "通过", "type": "补考1", "hours": 64, "level": 3, "point": 1.4, "credit": 4, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "f6ec9881", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 0.8, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "9324ee0c", "mark": 64, "name": "复变函数和积分变换", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.4, "credit": 3, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "fa73a644", "mark": 77, "name": "低频电子线路", "pass": "通过", "type": "正常", "hours": 56, "level": 3, "point": 2.7, "credit": 3.5, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "e55b42ed", "mark": 80, "name": "低频电子线路实验", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "89187582", "mark": 80, "name": "电工电子实习Ⅰ", "pass": "通过", "type": "正常", "hours": 2, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 61, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.1, "credit": 4, "remarks": "", "raw_mark": "61.00", "required": "必修"}, {"hash": "e947f801", "mark": 75, "name": "知识产权法", "pass": "通过", "type": "正常", "hours": 16, "level": 3, "point": 2.5, "credit": 1, "remarks": "", "raw_mark": "合格", "required": "限选"}, {"hash": "c0b656a6", "mark": 80, "name": "中国近现代史纲要", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "80.00", "required": "必修"}, {"hash": "8c09367f", "mark": 88, "name": "世界美术作品欣赏", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.8, "credit": 2, "remarks": "", "raw_mark": "88.00", "required": "选修"}, {"hash": "8789c756", "mark": 86, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.6, "credit": 1, "remarks": "", "raw_mark": "86.00", "required": "必修"}, {"hash": "663d3874", "mark": 80, "name": "数学实验", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3, "credit": 0.5, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "a1930834", "mark": 77, "name": "概率论与数理统计Ⅰ", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 2.7, "credit": 3, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 22, "name": "信号与系统", "pass": "未通过", "type": "正常", "hours": 56, "level": 4, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "22.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 82, "name": "信号与系统", "pass": "通过", "type": "补考1", "hours": 56, "level": 4, "point": 3.2, "credit": 3.5, "remarks": "", "raw_mark": "82.00", "required": "必修"}, {"hash": "9285a3b0", "mark": 80, "name": "信号与系统实验", "pass": "通过", "type": "正常", "hours": 24, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "529677fa", "mark": 89, "name": "数字逻辑电路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 3.9, "credit": 3.5, "remarks": "", "raw_mark": "89.00", "required": "必修"}, {"hash": "c6a3a4a2", "mark": 80, "name": "电子线路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "76a12616", "mark": 90, "name": "数字电路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 4, "credit": 1, "remarks": "", "raw_mark": "优秀", "required": "必修"}, {"hash": "8e83e66b", "mark": 93, "name": "高频电子线路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 4.3, "credit": 3.5, "remarks": "", "raw_mark": "93.00", "required": "选修"}, {"hash": "5567f82f", "mark": 65, "name": "电机及拖动基础", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.5, "credit": 3.5, "remarks": "", "raw_mark": "65.00", "required": "必修"}, {"hash": "cb1aafd4", "mark": 85, "name": "自动化学科概论", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "选修"}, {"hash": "90a15fa0", "mark": 94, "name": "中国传统哲学", "pass": "", "type": "正常", "hours": 16, "level": 4, "point": 4.4, "credit": 1, "remarks": "", "raw_mark": "94.00", "required": "限选"}, {"hash": "1cb70c8a", "mark": 79, "name": "马克思主义基本原理", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 2.9, "credit": 3, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "34e5264c", "mark": 62, "name": "读写译", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.2, "credit": 4, "remarks": "", "raw_mark": "62.00", "required": "必修"}, {"hash": "43f8c3b3", "mark": 95, "name": "化学与人类", "pass": "通过", "type": "正常", "hours": 25, "level": 4, "point": 4.5, "credit": 2, "remarks": "", "raw_mark": "95.00", "required": "选修"}, {"hash": "8789c756", "mark": 88, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 3.8, "credit": 1, "remarks": "", "raw_mark": "88.00", "required": "必修"}, {"hash": "fa229571", "mark": -1, "name": "电磁场与电磁波", "pass": "", "type": "", "hours": 48, "level": 5, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "未提交", "required": "选修"}, {"hash": "5f26647a", "mark": 69, "name": "通信原理", "pass": "通过", "type": "正常", "hours": 48, "level": 5, "point": 1.9, "credit": 3.5, "remarks": "", "raw_mark": "69.00", "required": "选修"}], "year": {"1": 2.594, "2": 2.656, "3": 2.85}, "level": {"1": {"point": 2.86, "credit": 21.5, "all_num": 9, "calc_point": 2.86046511627907, "powerpoint": 61.5, "required_num": 8, "required_point": 2.8292682926829267, "required_credit": 20.5, "required_powerpoint": 58}, "2": {"point": 2.416, "credit": 32.2, "all_num": 14, "calc_point": 2.416149068322981, "powerpoint": 77.8, "required_num": 12, "required_point": 2.3801369863013693, "required_credit": 29.2, "required_powerpoint": 69.49999999999999}, "3": {"point": 2.192, "credit": 27.3, "all_num": 12, "calc_point": 2.1923076923076925, "powerpoint": 59.85, "required_num": 10, "required_point": 2.0473251028806585, "required_credit": 24.3, "required_powerpoint": 49.75}, "4": {"point": 3.045, "credit": 32.5, "all_num": 15, "calc_point": 3.0446153846153847, "powerpoint": 98.95, "required_num": 11, "required_point": 2.68, "required_credit": 25, "required_powerpoint": 67}, "5": {"point": 2.85, "credit": 7, "all_num": 2, "calc_point": 0.95, "powerpoint": 6.6499999999999995, "required_num": 0, "required_point": 0, "required_credit": 0, "required_powerpoint": 0}}, "total": {"all": 52, "nop": 0, "pass": 51, "point": 2.639, "credit": 117}, "version": "1.0", "timestamp": 1515067986.502983, "personal_info": {"major": "自动化", "realname": "俞美玲", "class_num": "1504312", "student_id": "150431227"}}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(12, 'hello', 99, '123456', '2017-07-03 11:37:52', 99999999, '{"a": 1234}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(13, 'hello-1', 100, '123456', '2017-07-04 02:05:48', 99999999, '{}', 0, 12.369, '0000-00-00', '00:19:31', '0000-00-00 00:00:00', 0000, 0, 11, 'none'), +(14, 'hello', 99, '123456', '2017-07-04 03:13:46', 99999999, '{"a": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(15, 'hello-2', 990, '123456', '2017-07-04 04:45:31', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 95, 2563, ''), +(16, 'hello', 99, '123456', '2017-07-04 04:46:02', 99999999, '{"exam": [{"hash": "690c8834", "mark": 70, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 80, "level": 1, "point": 2, "credit": 5, "remarks": "", "raw_mark": "70.00", "required": "必修"}, {"hash": "cfa8d530", "mark": 90, "name": "工程制图与CAD", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 4, "credit": 2.5, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cb20e313", "mark": 78, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 2.8, "credit": 2, "remarks": "", "raw_mark": "78.00", "required": "必修"}, {"hash": "b5acc996", "mark": 71, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 39, "level": 1, "point": 2.1, "credit": 3, "remarks": "", "raw_mark": "71.00", "required": "必修"}, {"hash": "408f80cf", "mark": 81, "name": "思想道德修养与法律基础", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 85, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "必修"}, {"hash": "49335642", "mark": 93, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "efba9f7e", "mark": 85, "name": "大学生就业指导", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "限选"}, {"hash": "ae282f8b", "mark": 80, "name": "军训", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3, "credit": 3, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "0eab47c9", "mark": 67, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 112, "level": 2, "point": 1.7, "credit": 7, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 83, "name": "大学物理Ⅱ", "pass": "通过", "type": "正常", "hours": 64, "level": 2, "point": 3.3, "credit": 4, "remarks": "", "raw_mark": "83.00", "required": "必修"}, {"hash": "60a3b855", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 0.7, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c13b6ed1", "mark": 80, "name": "公益劳动", "pass": "通过", "type": "正常", "hours": 8, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "dcb1fed5", "mark": 79, "name": "工程训练", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 2.9, "credit": 2, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 52, "name": "电路分析", "pass": "未通过", "type": "正常", "hours": 56, "level": 2, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "52.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 60, "name": "电路分析", "pass": "通过", "type": "补考1", "hours": 56, "level": 2, "point": 1, "credit": 3.5, "remarks": "", "raw_mark": "60.00", "required": "必修"}, {"hash": "86a4a2ec", "mark": 80, "name": "电路分析实验", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "893b0788", "mark": 81, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "faa9dd23", "mark": 80, "name": "计算机实验Ⅰ", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 66, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 1.6, "credit": 4, "remarks": "", "raw_mark": "66.00", "required": "必修"}, {"hash": "4dff4e51", "mark": 81, "name": "大学语文", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3.1, "credit": 1, "remarks": "", "raw_mark": "81.00", "required": "限选"}, {"hash": "9e8161b2", "mark": 90, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 4, "level": 2, "point": 4, "credit": 1, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 93, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "1ad047dd", "mark": 76, "name": "大学生心理健康", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 2.6, "credit": 2, "remarks": "", "raw_mark": "76.00", "required": "选修"}, {"hash": "d9dfb118", "mark": 67, "name": "线性代数", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.7, "credit": 3, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 37, "name": "大学物理Ⅱ", "pass": "未通过", "type": "正常", "hours": 64, "level": 3, "point": 0, "credit": 4, "remarks": "", "raw_mark": "37.00", "required": "必修"}, {"hash": "53e14717", "mark": 64, "name": "大学物理Ⅱ", "pass": "通过", "type": "补考1", "hours": 64, "level": 3, "point": 1.4, "credit": 4, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "f6ec9881", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 0.8, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "9324ee0c", "mark": 64, "name": "复变函数和积分变换", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.4, "credit": 3, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "fa73a644", "mark": 77, "name": "低频电子线路", "pass": "通过", "type": "正常", "hours": 56, "level": 3, "point": 2.7, "credit": 3.5, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "e55b42ed", "mark": 80, "name": "低频电子线路实验", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "89187582", "mark": 80, "name": "电工电子实习Ⅰ", "pass": "通过", "type": "正常", "hours": 2, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 61, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.1, "credit": 4, "remarks": "", "raw_mark": "61.00", "required": "必修"}, {"hash": "e947f801", "mark": 75, "name": "知识产权法", "pass": "通过", "type": "正常", "hours": 16, "level": 3, "point": 2.5, "credit": 1, "remarks": "", "raw_mark": "合格", "required": "限选"}, {"hash": "c0b656a6", "mark": 80, "name": "中国近现代史纲要", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "80.00", "required": "必修"}, {"hash": "8c09367f", "mark": 88, "name": "世界美术作品欣赏", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.8, "credit": 2, "remarks": "", "raw_mark": "88.00", "required": "选修"}, {"hash": "8789c756", "mark": 86, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.6, "credit": 1, "remarks": "", "raw_mark": "86.00", "required": "必修"}, {"hash": "663d3874", "mark": 80, "name": "数学实验", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3, "credit": 0.5, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "a1930834", "mark": 77, "name": "概率论与数理统计Ⅰ", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 2.7, "credit": 3, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 22, "name": "信号与系统", "pass": "未通过", "type": "正常", "hours": 56, "level": 4, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "22.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 82, "name": "信号与系统", "pass": "通过", "type": "补考1", "hours": 56, "level": 4, "point": 3.2, "credit": 3.5, "remarks": "", "raw_mark": "82.00", "required": "必修"}, {"hash": "9285a3b0", "mark": 80, "name": "信号与系统实验", "pass": "通过", "type": "正常", "hours": 24, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "529677fa", "mark": 89, "name": "数字逻辑电路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 3.9, "credit": 3.5, "remarks": "", "raw_mark": "89.00", "required": "必修"}, {"hash": "c6a3a4a2", "mark": 80, "name": "电子线路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "76a12616", "mark": 90, "name": "数字电路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 4, "credit": 1, "remarks": "", "raw_mark": "优秀", "required": "必修"}, {"hash": "8e83e66b", "mark": 93, "name": "高频电子线路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 4.3, "credit": 3.5, "remarks": "", "raw_mark": "93.00", "required": "选修"}, {"hash": "5567f82f", "mark": 65, "name": "电机及拖动基础", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.5, "credit": 3.5, "remarks": "", "raw_mark": "65.00", "required": "必修"}, {"hash": "cb1aafd4", "mark": 85, "name": "自动化学科概论", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "选修"}, {"hash": "90a15fa0", "mark": 94, "name": "中国传统哲学", "pass": "", "type": "正常", "hours": 16, "level": 4, "point": 4.4, "credit": 1, "remarks": "", "raw_mark": "94.00", "required": "限选"}, {"hash": "1cb70c8a", "mark": 79, "name": "马克思主义基本原理", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 2.9, "credit": 3, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "34e5264c", "mark": 62, "name": "读写译", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.2, "credit": 4, "remarks": "", "raw_mark": "62.00", "required": "必修"}, {"hash": "43f8c3b3", "mark": 95, "name": "化学与人类", "pass": "通过", "type": "正常", "hours": 25, "level": 4, "point": 4.5, "credit": 2, "remarks": "", "raw_mark": "95.00", "required": "选修"}, {"hash": "8789c756", "mark": 88, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 3.8, "credit": 1, "remarks": "", "raw_mark": "88.00", "required": "必修"}, {"hash": "fa229571", "mark": -1, "name": "电磁场与电磁波", "pass": "", "type": "", "hours": 48, "level": 5, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "未提交", "required": "选修"}, {"hash": "5f26647a", "mark": 69, "name": "通信原理", "pass": "通过", "type": "正常", "hours": 48, "level": 5, "point": 1.9, "credit": 3.5, "remarks": "", "raw_mark": "69.00", "required": "选修"}], "year": {"1": 2.594, "2": 2.656, "3": 2.85}, "level": {"1": {"point": 2.86, "credit": 21.5, "all_num": 9, "calc_point": 2.86046511627907, "powerpoint": 61.5, "required_num": 8, "required_point": 2.8292682926829267, "required_credit": 20.5, "required_powerpoint": 58}, "2": {"point": 2.416, "credit": 32.2, "all_num": 14, "calc_point": 2.416149068322981, "powerpoint": 77.8, "required_num": 12, "required_point": 2.3801369863013693, "required_credit": 29.2, "required_powerpoint": 69.49999999999999}, "3": {"point": 2.192, "credit": 27.3, "all_num": 12, "calc_point": 2.1923076923076925, "powerpoint": 59.85, "required_num": 10, "required_point": 2.0473251028806585, "required_credit": 24.3, "required_powerpoint": 49.75}, "4": {"point": 3.045, "credit": 32.5, "all_num": 15, "calc_point": 3.0446153846153847, "powerpoint": 98.95, "required_num": 11, "required_point": 2.68, "required_credit": 25, "required_powerpoint": 67}, "5": {"point": 2.85, "credit": 7, "all_num": 2, "calc_point": 0.95, "powerpoint": 6.6499999999999995, "required_num": 0, "required_point": 0, "required_credit": 0, "required_powerpoint": 0}}, "total": {"all": 52, "nop": 0, "pass": 51, "point": 2.639, "credit": 117}, "version": "1.0", "timestamp": 1515067986.502983, "personal_info": {"major": "自动化", "realname": "俞美玲", "class_num": "1504312", "student_id": "150431227"}}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''); +INSERT INTO `userinfo` (`id`, `name`, `level`, `passwd`, `regtime`, `big_n`, `data`, `lastlogin_ip`, `price`, `mdate`, `mtime`, `mdatetime`, `year`, `int8_t`, `mshort`, `mtext`) VALUES +(17, 'hello', 99, '123456', '2017-07-04 05:17:48', 99999999, '{"a": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''); +INSERT INTO `userinfo` (`id`, `name`, `level`, `passwd`, `regtime`, `big_n`, `data`, `lastlogin_ip`, `price`, `mdate`, `mtime`, `mdatetime`, `year`, `int8_t`, `mshort`, `mtext`) VALUES +(18, 'hello', 99, '123456', '2017-07-04 06:04:23', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(19, 'hello', 99, '123456', '2017-07-04 06:08:14', 99999999, '{"exam": [{"hash": "690c8834", "mark": 70, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 80, "level": 1, "point": 2, "credit": 5, "remarks": "", "raw_mark": "70.00", "required": "必修"}, {"hash": "cfa8d530", "mark": 90, "name": "工程制图与CAD", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 4, "credit": 2.5, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cb20e313", "mark": 78, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 2.8, "credit": 2, "remarks": "", "raw_mark": "78.00", "required": "必修"}, {"hash": "b5acc996", "mark": 71, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 39, "level": 1, "point": 2.1, "credit": 3, "remarks": "", "raw_mark": "71.00", "required": "必修"}, {"hash": "408f80cf", "mark": 81, "name": "思想道德修养与法律基础", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 85, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "必修"}, {"hash": "49335642", "mark": 93, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "efba9f7e", "mark": 85, "name": "大学生就业指导", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "限选"}, {"hash": "ae282f8b", "mark": 80, "name": "军训", "pass": "通过", "type": "正常", "hours": 16, "level": 1, "point": 3, "credit": 3, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "0eab47c9", "mark": 67, "name": "高等数学Ⅱ", "pass": "通过", "type": "正常", "hours": 112, "level": 2, "point": 1.7, "credit": 7, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 83, "name": "大学物理Ⅱ", "pass": "通过", "type": "正常", "hours": 64, "level": 2, "point": 3.3, "credit": 4, "remarks": "", "raw_mark": "83.00", "required": "必修"}, {"hash": "60a3b855", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 0.7, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c13b6ed1", "mark": 80, "name": "公益劳动", "pass": "通过", "type": "正常", "hours": 8, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "dcb1fed5", "mark": 79, "name": "工程训练", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 2.9, "credit": 2, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 52, "name": "电路分析", "pass": "未通过", "type": "正常", "hours": 56, "level": 2, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "52.00", "required": "必修"}, {"hash": "dec6dd65", "mark": 60, "name": "电路分析", "pass": "通过", "type": "补考1", "hours": 56, "level": 2, "point": 1, "credit": 3.5, "remarks": "", "raw_mark": "60.00", "required": "必修"}, {"hash": "86a4a2ec", "mark": 80, "name": "电路分析实验", "pass": "通过", "type": "正常", "hours": 24, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "893b0788", "mark": 81, "name": "计算机基础与程序设计", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 3.1, "credit": 3, "remarks": "", "raw_mark": "81.00", "required": "必修"}, {"hash": "faa9dd23", "mark": 80, "name": "计算机实验Ⅰ", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 66, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 2, "point": 1.6, "credit": 4, "remarks": "", "raw_mark": "66.00", "required": "必修"}, {"hash": "4dff4e51", "mark": 81, "name": "大学语文", "pass": "通过", "type": "正常", "hours": 16, "level": 2, "point": 3.1, "credit": 1, "remarks": "", "raw_mark": "81.00", "required": "限选"}, {"hash": "9e8161b2", "mark": 90, "name": "军事理论", "pass": "通过", "type": "正常", "hours": 4, "level": 2, "point": 4, "credit": 1, "remarks": "", "raw_mark": "90.00", "required": "必修"}, {"hash": "cfc19fbd", "mark": 93, "name": "体育", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 4.3, "credit": 1, "remarks": "", "raw_mark": "93.00", "required": "必修"}, {"hash": "1ad047dd", "mark": 76, "name": "大学生心理健康", "pass": "通过", "type": "正常", "hours": 32, "level": 2, "point": 2.6, "credit": 2, "remarks": "", "raw_mark": "76.00", "required": "选修"}, {"hash": "d9dfb118", "mark": 67, "name": "线性代数", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.7, "credit": 3, "remarks": "", "raw_mark": "67.00", "required": "必修"}, {"hash": "53e14717", "mark": 37, "name": "大学物理Ⅱ", "pass": "未通过", "type": "正常", "hours": 64, "level": 3, "point": 0, "credit": 4, "remarks": "", "raw_mark": "37.00", "required": "必修"}, {"hash": "53e14717", "mark": 64, "name": "大学物理Ⅱ", "pass": "通过", "type": "补考1", "hours": 64, "level": 3, "point": 1.4, "credit": 4, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "f6ec9881", "mark": 80, "name": "大学物理实验Ⅱ", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 0.8, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "9324ee0c", "mark": 64, "name": "复变函数和积分变换", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.4, "credit": 3, "remarks": "", "raw_mark": "64.00", "required": "必修"}, {"hash": "fa73a644", "mark": 77, "name": "低频电子线路", "pass": "通过", "type": "正常", "hours": 56, "level": 3, "point": 2.7, "credit": 3.5, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "e55b42ed", "mark": 80, "name": "低频电子线路实验", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "89187582", "mark": 80, "name": "电工电子实习Ⅰ", "pass": "通过", "type": "正常", "hours": 2, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "c397a560", "mark": 61, "name": "大学外语", "pass": "通过", "type": "正常", "hours": 48, "level": 3, "point": 1.1, "credit": 4, "remarks": "", "raw_mark": "61.00", "required": "必修"}, {"hash": "e947f801", "mark": 75, "name": "知识产权法", "pass": "通过", "type": "正常", "hours": 16, "level": 3, "point": 2.5, "credit": 1, "remarks": "", "raw_mark": "合格", "required": "限选"}, {"hash": "c0b656a6", "mark": 80, "name": "中国近现代史纲要", "pass": "通过", "type": "正常", "hours": 24, "level": 3, "point": 3, "credit": 2, "remarks": "", "raw_mark": "80.00", "required": "必修"}, {"hash": "8c09367f", "mark": 88, "name": "世界美术作品欣赏", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.8, "credit": 2, "remarks": "", "raw_mark": "88.00", "required": "选修"}, {"hash": "8789c756", "mark": 86, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 3, "point": 3.6, "credit": 1, "remarks": "", "raw_mark": "86.00", "required": "必修"}, {"hash": "663d3874", "mark": 80, "name": "数学实验", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3, "credit": 0.5, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "a1930834", "mark": 77, "name": "概率论与数理统计Ⅰ", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 2.7, "credit": 3, "remarks": "", "raw_mark": "77.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 22, "name": "信号与系统", "pass": "未通过", "type": "正常", "hours": 56, "level": 4, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "22.00", "required": "必修"}, {"hash": "ea7ee677", "mark": 82, "name": "信号与系统", "pass": "通过", "type": "补考1", "hours": 56, "level": 4, "point": 3.2, "credit": 3.5, "remarks": "", "raw_mark": "82.00", "required": "必修"}, {"hash": "9285a3b0", "mark": 80, "name": "信号与系统实验", "pass": "通过", "type": "正常", "hours": 24, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "529677fa", "mark": 89, "name": "数字逻辑电路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 3.9, "credit": 3.5, "remarks": "", "raw_mark": "89.00", "required": "必修"}, {"hash": "c6a3a4a2", "mark": 80, "name": "电子线路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 3, "credit": 1, "remarks": "", "raw_mark": "良好", "required": "必修"}, {"hash": "76a12616", "mark": 90, "name": "数字电路课程设计", "pass": "通过", "type": "正常", "hours": 8, "level": 4, "point": 4, "credit": 1, "remarks": "", "raw_mark": "优秀", "required": "必修"}, {"hash": "8e83e66b", "mark": 93, "name": "高频电子线路", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 4.3, "credit": 3.5, "remarks": "", "raw_mark": "93.00", "required": "选修"}, {"hash": "5567f82f", "mark": 65, "name": "电机及拖动基础", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.5, "credit": 3.5, "remarks": "", "raw_mark": "65.00", "required": "必修"}, {"hash": "cb1aafd4", "mark": 85, "name": "自动化学科概论", "pass": "通过", "type": "正常", "hours": 16, "level": 4, "point": 3.5, "credit": 1, "remarks": "", "raw_mark": "85.00", "required": "选修"}, {"hash": "90a15fa0", "mark": 94, "name": "中国传统哲学", "pass": "", "type": "正常", "hours": 16, "level": 4, "point": 4.4, "credit": 1, "remarks": "", "raw_mark": "94.00", "required": "限选"}, {"hash": "1cb70c8a", "mark": 79, "name": "马克思主义基本原理", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 2.9, "credit": 3, "remarks": "", "raw_mark": "79.00", "required": "必修"}, {"hash": "34e5264c", "mark": 62, "name": "读写译", "pass": "通过", "type": "正常", "hours": 48, "level": 4, "point": 1.2, "credit": 4, "remarks": "", "raw_mark": "62.00", "required": "必修"}, {"hash": "43f8c3b3", "mark": 95, "name": "化学与人类", "pass": "通过", "type": "正常", "hours": 25, "level": 4, "point": 4.5, "credit": 2, "remarks": "", "raw_mark": "95.00", "required": "选修"}, {"hash": "8789c756", "mark": 88, "name": "羽毛球", "pass": "通过", "type": "正常", "hours": 32, "level": 4, "point": 3.8, "credit": 1, "remarks": "", "raw_mark": "88.00", "required": "必修"}, {"hash": "fa229571", "mark": -1, "name": "电磁场与电磁波", "pass": "", "type": "", "hours": 48, "level": 5, "point": 0, "credit": 3.5, "remarks": "", "raw_mark": "未提交", "required": "选修"}, {"hash": "5f26647a", "mark": 69, "name": "通信原理", "pass": "通过", "type": "正常", "hours": 48, "level": 5, "point": 1.9, "credit": 3.5, "remarks": "", "raw_mark": "69.00", "required": "选修"}], "year": {"1": 2.594, "2": 2.656, "3": 2.85}, "level": {"1": {"point": 2.86, "credit": 21.5, "all_num": 9, "calc_point": 2.86046511627907, "powerpoint": 61.5, "required_num": 8, "required_point": 2.8292682926829267, "required_credit": 20.5, "required_powerpoint": 58}, "2": {"point": 2.416, "credit": 32.2, "all_num": 14, "calc_point": 2.416149068322981, "powerpoint": 77.8, "required_num": 12, "required_point": 2.3801369863013693, "required_credit": 29.2, "required_powerpoint": 69.49999999999999}, "3": {"point": 2.192, "credit": 27.3, "all_num": 12, "calc_point": 2.1923076923076925, "powerpoint": 59.85, "required_num": 10, "required_point": 2.0473251028806585, "required_credit": 24.3, "required_powerpoint": 49.75}, "4": {"point": 3.045, "credit": 32.5, "all_num": 15, "calc_point": 3.0446153846153847, "powerpoint": 98.95, "required_num": 11, "required_point": 2.68, "required_credit": 25, "required_powerpoint": 67}, "5": {"point": 2.85, "credit": 7, "all_num": 2, "calc_point": 0.95, "powerpoint": 6.6499999999999995, "required_num": 0, "required_point": 0, "required_credit": 0, "required_powerpoint": 0}}, "total": {"all": 52, "nop": 0, "pass": 51, "point": 2.639, "credit": 117}, "version": "1.0", "timestamp": 1515067986.502983, "personal_info": {"major": "自动化", "realname": "俞美玲", "class_num": "1504312", "student_id": "150431227"}}', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(20, 'hello', 99, '123456', '2017-07-04 07:01:51', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(21, 'hello', 99, '123456', '2017-07-04 07:15:59', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(22, 'hello', 99, '123456', '2017-07-04 07:28:26', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(23, 'hello', 99, '123456', '2017-07-04 07:38:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(24, 'hello', 99, '123456', '2017-07-04 08:17:44', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(25, 'jack2', 0, 'xuyou', '2017-07-05 09:11:28', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(26, 'jack2', 0, 'xuyou', '2017-07-05 09:12:29', 0, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(27, 'hello', 99, '123456', '2017-07-11 06:25:44', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(28, 'hello', 99, '123456', '2017-07-11 06:45:23', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(29, 'hello', 99, '123456', '2017-07-11 08:00:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(30, 'hello', 99, '123456', '2017-07-11 08:17:26', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(31, 'hello', 99, '123456', '2017-07-12 09:31:45', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(32, 'hello', 99, '123456', '2017-07-12 09:33:41', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(33, 'hello', 99, '123456', '2017-07-12 11:41:38', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(34, 'hello', 99, '123456', '2017-07-12 11:42:53', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(35, 'hello', 99, '123456', '2017-07-17 03:54:06', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(36, 'hello', 99, '123456', '2017-07-17 09:44:19', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(37, 'hello', 99, '123456', '2017-07-18 03:14:12', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(38, 'hello', 99, '123456', '2017-07-18 05:47:02', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(39, 'hello', 99, '123456', '2017-07-21 09:38:17', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(40, 'hello', 99, '123456', '2017-07-21 09:52:04', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(41, 'hello', 99, '123456', '2017-07-21 10:14:29', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(42, 'hello', 99, '123456', '2017-07-24 03:19:44', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(43, 'hello', 99, '123456', '2017-07-26 02:18:34', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(44, 'hello', 99, '123456', '2017-07-26 07:22:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(45, 'hello', 99, '123456', '2017-07-26 08:13:04', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(46, 'hello', 99, '123456', '2017-07-28 07:09:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(47, 'hello', 99, '123456', '2017-08-01 03:32:01', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(48, 'hello', 99, '123456', '2017-08-01 05:14:46', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(49, 'hello', 99, '123456', '2017-08-01 10:18:54', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(50, 'hello', 99, '123456', '2017-08-01 10:22:01', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(51, 'hello', 99, '123456', '2017-08-01 10:24:46', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(52, 'hello', 99, '123456', '2017-08-01 10:47:33', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(53, 'hello', 99, '123456', '2017-08-01 11:16:02', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(54, 'hello', 99, '123456', '2017-08-03 03:45:41', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(55, 'hello', 99, '123456', '2017-08-04 06:40:32', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(56, 'hello', 99, '123456', '2017-08-04 11:04:03', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(57, 'hello', 99, '123456', '2017-08-04 11:13:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(58, 'hello', 99, '123456', '2017-08-07 10:04:58', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(59, 'hello', 99, '123456', '2017-08-09 07:15:12', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(60, 'hello', 99, '123456', '2017-08-09 08:27:46', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(61, 'hello', 99, '123456', '2017-08-11 03:08:51', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(62, 'hello', 99, '123456', '2017-08-11 08:34:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(63, 'hello', 99, '123456', '2017-08-11 08:44:17', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(64, 'hello', 99, '123456', '2017-08-11 08:51:29', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(65, 'hello', 99, '123456', '2017-08-11 08:55:53', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(66, 'hello', 99, '123456', '2017-08-11 09:00:10', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(67, 'hello', 99, '123456', '2017-08-11 09:18:48', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(68, 'hello', 99, '123456', '2017-08-11 09:21:00', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(69, 'hello', 99, '123456', '2017-08-25 10:56:13', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(70, 'hello', 99, '123456', '2017-08-25 11:09:53', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(71, 'hello', 99, '123456', '2017-08-25 11:10:03', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(72, 'hello', 99, '123456', '2017-08-25 11:11:09', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(73, 'hello', 99, '123456', '2017-08-28 08:31:07', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(74, 'hello', 99, '123456', '2017-08-28 09:34:51', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(75, 'hello', 99, '123456', '2017-08-28 10:42:24', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(76, 'hello', 99, '123456', '2017-08-29 08:32:22', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(77, 'hello', 99, '123456', '2017-08-29 08:48:17', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(78, 'hello', 99, '123456', '2017-08-29 08:55:39', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(79, 'hello', 99, '123456', '2017-08-29 09:37:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(80, 'hello', 99, '123456', '2017-08-29 10:12:40', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(81, 'hello', 99, '123456', '2017-08-31 02:27:16', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(82, 'hello', 99, '123456', '2017-08-31 02:34:13', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(83, 'hello', 99, '123456', '2017-08-31 02:47:56', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(84, 'hello', 99, '123456', '2017-08-31 02:57:32', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(85, 'hello', 99, '123456', '2017-08-31 03:02:33', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(86, 'hello', 99, '123456', '2017-09-15 10:07:50', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(87, 'hello', 99, '123456', '2017-09-15 10:11:16', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(88, 'hello', 99, '123456', '2017-09-15 11:02:13', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(89, 'hello', 99, '123456', '2017-09-20 08:34:24', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(90, 'hello', 99, '123456', '2017-09-20 09:07:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(91, 'hello', 99, '123456', '2017-09-20 12:13:06', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(92, 'hello', 99, '123456', '2017-09-21 10:09:12', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(93, 'hello', 99, '123456', '2017-09-21 12:01:52', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(94, 'hello', 99, '123456', '2017-09-21 12:09:19', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(95, 'hello', 99, '123456', '2017-10-20 09:16:57', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(96, 'hello', 99, '123456', '2017-10-20 09:34:40', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(97, 'hello', 99, '123456', '2017-10-20 09:47:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(98, 'hello', 99, '123456', '2017-10-20 10:35:23', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(99, 'hello', 99, '123456', '2017-11-01 11:25:55', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(100, 'hello', 99, '123456', '2017-11-02 02:12:17', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(101, 'hello', 99, '123456', '2017-11-22 02:00:20', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(102, 'hello', 99, '123456', '2017-11-22 06:59:13', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(103, 'hello', 99, '123456', '2017-12-04 09:26:42', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(104, 'hello', 99, '123456', '2017-12-05 06:47:43', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(105, 'hello', 99, '123456', '2017-12-05 07:00:56', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(106, 'hello', 99, '123456', '2017-12-26 09:07:35', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(107, 'hello', 99, '123456', '2017-12-26 09:15:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(108, 'hello', 99, '123456', '2017-12-26 09:17:36', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(109, 'hello', 99, '123456', '2017-12-28 10:33:28', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(110, 'hello', 99, '123456', '2017-12-28 11:03:53', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(111, 'hello', 99, '123456', '2017-12-28 11:06:07', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(112, 'hello', 99, '123456', '2017-12-29 09:40:14', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(113, 'hello', 99, '123456', '2017-12-29 09:42:12', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(114, 'hello', 99, '123456', '2017-12-29 11:22:35', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(115, 'hello', 99, '123456', '2017-12-29 11:24:43', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(116, 'hello', 99, '123456', '2018-01-04 08:10:13', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(117, 'hello', 99, '123456', '2018-01-04 08:18:22', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(118, 'hello', 99, '123456', '2018-01-04 08:27:45', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(119, 'hello', 99, '123456', '2018-01-04 10:34:21', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(120, 'hello', 99, '123456', '2018-01-06 10:03:02', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(121, 'hello', 99, '123456', '2018-01-12 05:01:04', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(122, 'hello', 99, '123456', '2018-01-31 09:26:07', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(123, 'hello', 99, '123456', '2018-02-09 08:04:25', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(124, 'hello', 99, '123456', '2018-02-09 08:11:39', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(125, 'hello', 99, '123456', '2018-03-06 02:10:49', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(126, 'hello', 99, '123456', '2018-03-06 05:23:31', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(127, 'hello', 99, '123456', '2018-03-06 10:40:31', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(128, 'hello', 99, '123456', '2018-03-07 07:09:56', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(129, 'hello', 99, '123456', '2018-03-07 07:14:26', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(130, 'hello', 99, '123456', '2018-03-07 07:24:50', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(131, 'hello', 99, '123456', '2018-03-12 11:03:18', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(132, 'hello', 99, '123456', '2018-03-14 10:05:20', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(133, 'hello', 99, '123456', '2018-03-14 10:06:16', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(134, 'hello', 99, '123456', '2018-03-27 08:44:22', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(135, 'hello', 99, '123456', '2018-03-27 09:26:56', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(136, 'hello', 99, '123456', '2018-03-27 10:56:56', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(137, 'hello', 99, '123456', '2018-03-27 11:53:30', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(138, 'hello', 99, '123456', '2018-03-27 11:58:47', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(139, 'hello', 99, '123456', '2018-03-27 12:07:07', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(140, 'hello', 99, '123456', '2018-03-28 03:28:03', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(141, 'hello', 99, '123456', '2018-03-28 03:34:24', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(142, 'hello', 99, '123456', '2018-04-09 07:25:27', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''), +(143, 'hello', 99, '123456', '2018-04-09 07:48:00', 99999999, 'null', 0, 0, '0000-00-00', '00:00:00', '0000-00-00 00:00:00', 0000, 0, 0, ''); + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_elf_gas.S new file mode 100755 index 0000000..09bd7b5 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_elf_gas.S @@ -0,0 +1,131 @@ +/* + Copyright Edward Nevill 2015 + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.cpu generic+fp+simd +.text +.align 2 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack for GP + FPU + sub sp, sp, #0xb0 + +# Because gcc may save integer registers in fp registers across a +# function call we cannot skip saving the fp registers. +# +# Do not reinstate this test unless you fully understand what you +# are doing. +# +# # test if fpu env should be preserved +# cmp w3, #0 +# b.eq 1f + + # save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + +1: + # save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp x29, x30, [sp, #0x90] + + # save LR as PC + str x30, [sp, #0xa0] + + # store RSP (pointing to context-data) in first argument (x0). + # STR cannot have sp as a target register + mov x4, sp + str x4, [x0] + + # restore RSP (pointing to context-data) from A2 (x1) + mov sp, x1 + +# # test if fpu env should be preserved +# cmp w3, #0 +# b.eq 2f + + # load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + +2: + # load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp x29, x30, [sp, #0x90] + + # use third arg as return value after jump + # and as first arg in context function + mov x0, x2 + + # load pc + ldr x4, [sp, #0xa0] + + # restore stack from GP + FPU + add sp, sp, #0xb0 + + ret x4 +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_macho_gas.S new file mode 100755 index 0000000..958178e --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_arm64_aapcs_macho_gas.S @@ -0,0 +1,120 @@ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl _jump_fcontext +.balign 16 +_jump_fcontext: + ; prepare stack for GP + FPU + sub sp, sp, #0xb0 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + ; test if fpu env should be preserved + cmp w3, #0 + b.eq 1f + + ; save d8 - d15 + stp d8, d9, [sp, #0x00] + stp d10, d11, [sp, #0x10] + stp d12, d13, [sp, #0x20] + stp d14, d15, [sp, #0x30] + +1: +#endif + + ; save x19-x30 + stp x19, x20, [sp, #0x40] + stp x21, x22, [sp, #0x50] + stp x23, x24, [sp, #0x60] + stp x25, x26, [sp, #0x70] + stp x27, x28, [sp, #0x80] + stp fp, lr, [sp, #0x90] + + ; save LR as PC + str lr, [sp, #0xa0] + + ; store RSP (pointing to context-data) in first argument (x0). + ; STR cannot have sp as a target register + mov x4, sp + str x4, [x0] + + ; restore RSP (pointing to context-data) from A2 (x1) + mov sp, x1 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + ; test if fpu env should be preserved + cmp w3, #0 + b.eq 2f + + ; load d8 - d15 + ldp d8, d9, [sp, #0x00] + ldp d10, d11, [sp, #0x10] + ldp d12, d13, [sp, #0x20] + ldp d14, d15, [sp, #0x30] + +2: +#endif + + ; load x19-x30 + ldp x19, x20, [sp, #0x40] + ldp x21, x22, [sp, #0x50] + ldp x23, x24, [sp, #0x60] + ldp x25, x26, [sp, #0x70] + ldp x27, x28, [sp, #0x80] + ldp fp, lr, [sp, #0x90] + + ; use third arg as return value after jump + ; and as first arg in context function + mov x0, x2 + + ; load pc + ldr x4, [sp, #0xa0] + + ; restore stack from GP + FPU + add sp, sp, #0xb0 + + ret x4 diff --git a/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S new file mode 100755 index 0000000..3019aeb --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_elf_gas.S @@ -0,0 +1,93 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | | * + * ------------------------------------------------- * + * | 0x60| 0x64| | * + * ------------------------------------------------- * + * | lr | pc | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,%function +jump_fcontext: + @ save LR as PC + push {lr} + @ save V1-V8,LR + push {v1-v8,lr} + + @ prepare stack for FPU + sub sp, sp, #64 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ test if fpu env should be preserved + cmp a4, #0 + beq 1f + + @ save S16-S31 + vstmia sp, {d8-d15} + +1: +#endif + + @ store RSP (pointing to context-data) in A1 + str sp, [a1] + + @ restore RSP (pointing to context-data) from A2 + mov sp, a2 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ test if fpu env should be preserved + cmp a4, #0 + beq 2f + + @ restore S16-S31 + vldmia sp, {d8-d15} +2: +#endif + + @ prepare stack for FPU + add sp, sp, #64 + + @ use third arg as return value after jump + @ and as first arg in context function + mov a1, a3 + + @ restore v1-V8,LR,PC + pop {v1-v8,lr,pc} +.size jump_fcontext,.-jump_fcontext + +@ Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_macho_gas.S new file mode 100755 index 0000000..7593534 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_macho_gas.S @@ -0,0 +1,103 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | sjlj| v1 | v2 | v3 | v4 | v5 | v6 | v7 | + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| | * + * ------------------------------------------------- * + * | v8 | lr | pc | | * + * ------------------------------------------------- * + * * + * *****************************************************/ + +.text +.globl _jump_fcontext +.align 2 +_jump_fcontext: + @ save LR as PC + push {lr} + @ save V1-V8,LR + push {v1-v8,lr} + + @ locate TLS to save/restore SjLj handler + mrc p15, 0, v2, c13, c0, #3 + bic v2, v2, #3 + + @ load TLS[__PTK_LIBC_DYLD_Unwind_SjLj_Key] + ldr v1, [v2, #72] + @ save SjLj handler + push {v1} + + @ prepare stack for FPU + sub sp, sp, #64 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ test if fpu env should be preserved + cmp a4, #0 + beq 1f + + @ save S16-S31 + vstmia sp, {d8-d15} + +1: +#endif + + @ store RSP (pointing to context-data) in A1 + str sp, [a1] + + @ restore RSP (pointing to context-data) from A2 + mov sp, a2 + +#if (defined(__VFP_FP__) && !defined(__SOFTFP__)) + @ test if fpu env should be preserved + cmp a4, #0 + beq 2f + + @ restore S16-S31 + vldmia sp, {d8-d15} + +2: +#endif + + @ prepare stack for FPU + add sp, sp, #64 + + @ restore SjLj handler + pop {v1} + @ store SjLj handler in TLS + str v1, [v2, #72] + + @ use third arg as return value after jump + @ and as first arg in context function + mov a1, a3 + + @ restore v1-V8,LR,PC + pop {v1-v8,lr,pc} diff --git a/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_pe_armasm.asm b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_pe_armasm.asm new file mode 100755 index 0000000..4e145df --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_arm_aapcs_pe_armasm.asm @@ -0,0 +1,112 @@ +;/* +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +;*/ + +; ******************************************************* +; * * +; * ------------------------------------------------- * +; * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * +; * ------------------------------------------------- * +; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * +; * ------------------------------------------------- * +; * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * +; * ------------------------------------------------- * +; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * +; * ------------------------------------------------- * +; * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * +; * ------------------------------------------------- * +; * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * +; * ------------------------------------------------- * +; * |deall|limit| base| v1 | v2 | v3 | v4 | v5 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 24 | 25 | 26 | 27 | 28 | | * +; * ------------------------------------------------- * +; * | 0x60| 0x64| 0x68| 0x6c| 0x70| | * +; * ------------------------------------------------- * +; * | v6 | v7 | v8 | lr | pc | | * +; * ------------------------------------------------- * +; * * +; ******************************************************* + + AREA |.text|, CODE + ALIGN 4 + EXPORT jump_fcontext + +jump_fcontext PROC + @ save LR as PC + push {lr} + @ save V1-V8,LR + push {v1-v8,lr} + + @ prepare stack for FPU + sub sp, sp, #0x4c + + @ test if fpu env should be preserved + cmp a4, #0 + beq 1f + + @ save S16-S31 + vstmia sp, {d8-d15} + +1: + ; load TIB to save/restore thread size and limit. + ; we do not need preserve CPU flag and can use it's arg register + mrc p15, #0, v1, c13, c0, #2 + + ; save current stack base + ldr a5, [v1,#0x04] + str a5, [sp,#0x48] + ; save current stack limit + ldr a5, [v1,#0x08] + str a5, [sp,#0x44] + ; save current deallocation stack + ldr a5, [v1,#0xe0c] + str a5, [sp,#0x40] + + @ store RSP (pointing to context-data) in A1 + str sp, [a1] + + @ restore RSP (pointing to context-data) from A2 + mov sp, a2 + + @ test if fpu env should be preserved + cmp a4, #0 + beq 2f + + @ restore S16-S31 + vldmia sp, {d8-d15} + +2: + ; restore stack base + ldr a5, [sp,#0x48] + str a5, [v1,#0x04] + ; restore stack limit + ldr a5, [sp,#0x44] + str a5, [v1,#0x08] + ; restore deallocation stack + ldr a5, [sp,#0x40] + str a5, [v1,#0xe0c] + + @ prepare stack for FPU + add sp, sp, #0x4c + + ; use third arg as return value after jump + ; and as first arg in context function + mov a1, a3 + + @ restore v1-V8,LR + pop {v1-v8,lr} + pop {pc} + + ENDP + END diff --git a/vendor/swoole/thirdparty/boost/asm/jump_combined_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_combined_sysv_macho_gas.S new file mode 100755 index 0000000..1d27afa --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_combined_sysv_macho_gas.S @@ -0,0 +1,20 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__i386__) + #include "jump_i386_sysv_macho_gas.S" +#elif defined(__x86_64__) + #include "jump_x86_64_sysv_macho_gas.S" +#elif defined(__ppc__) + #include "jump_ppc32_sysv_macho_gas.S" +#elif defined(__ppc64__) + #include "jump_ppc64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_gas.asm b/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_gas.asm new file mode 100755 index 0000000..b55b772 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_gas.asm @@ -0,0 +1,140 @@ +/* + Copyright Oliver Kowalke 2009. + Copyright Thomas Sailer 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************** + --------------------------------------------------------------------------------- + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + --------------------------------------------------------------------------------- + | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | + --------------------------------------------------------------------------------- + | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | + --------------------------------------------------------------------------------- + --------------------------------------------------------------------------------- + | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | + --------------------------------------------------------------------------------- + | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | + --------------------------------------------------------------------------------- + | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR| + --------------------------------------------------------------------------------- +* *****************************************************************/ + +.file "jump_i386_ms_pe_gas.asm" +.text +.p2align 4,,15 +.globl _jump_fcontext +.def _jump_fcontext; .scl 2; .type 32; .endef +_jump_fcontext: + /* fourth arg of jump_fcontext() == flag indicating preserving FPU */ + movl 0x10(%esp), %ecx + + pushl %ebp /* save EBP */ + pushl %ebx /* save EBX */ + pushl %esi /* save ESI */ + pushl %edi /* save EDI */ + + /* load NT_TIB */ + movl %fs:(0x18), %edx + + /* load current SEH exception list */ + movl (%edx), %eax + push %eax + + /* load current stack base */ + movl 0x04(%edx), %eax + push %eax + + /* load current stack limit */ + movl 0x08(%edx), %eax + push %eax + + /* load current dealloction stack */ + movl 0xe0c(%edx), %eax + push %eax + + /* load fiber local storage */ + movl 0x10(%edx), %eax + push %eax + + /* prepare stack for FPU */ + leal -0x08(%esp), %esp + + /* test for flag preserve_fpu */ + testl %ecx, %ecx + je 1f + + /* save MMX control word */ + stmxcsr (%esp) + /* save x87 control word */ + fnstcw 0x04(%esp) + +1: + /* first arg of jump_fcontext() == context jumping from */ + movl 0x30(%esp), %eax + + /* store ESP (pointing to context-data) in EAX */ + movl %esp, (%eax) + + /* second arg of jump_fcontext() == context jumping to */ + movl 0x34(%esp), %edx + + /* third arg of jump_fcontext() == value to be returned after jump */ + movl 0x38(%esp), %eax + + /* restore ESP (pointing to context-data) from EDX */ + movl %edx, %esp + + /* test for flag preserve_fpu */ + testl %ecx, %ecx + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr (%esp) + /* restore x87 control-word */ + fldcw 0x04(%esp) + +2: + /* prepare stack for FPU */ + leal 0x08(%esp), %esp + + /* load NT_TIB into ECX */ + movl %fs:(0x18), %edx + + /* restore fiber local storage */ + popl %ecx + movl %ecx, 0x10(%edx) + + /* restore current deallocation stack */ + popl %ecx + movl %ecx, 0xe0c(%edx) + + /* restore current stack limit */ + popl %ecx + movl %ecx, 0x08(%edx) + + /* restore current stack base */ + popl %ecx + movl %ecx, 0x04(%edx) + + /* restore current SEH exception list */ + popl %ecx + movl %ecx, (%edx) + + popl %edi /* save EDI */ + popl %esi /* save ESI */ + popl %ebx /* save EBX */ + popl %ebp /* save EBP */ + + /* restore return-address */ + popl %edx + + /* use value in EAX as return-value after jump */ + /* use value in EAX as first arg in context function */ + movl %eax, 0x04(%esp) + + /* indirect jump to context */ + jmp *%edx diff --git a/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_masm.asm b/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_masm.asm new file mode 100755 index 0000000..d12f710 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_i386_ms_pe_masm.asm @@ -0,0 +1,142 @@ + +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +; --------------------------------------------------------------------------------- +; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | +; --------------------------------------------------------------------------------- +; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | +; --------------------------------------------------------------------------------- +; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | +; --------------------------------------------------------------------------------- +; --------------------------------------------------------------------------------- +; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | +; --------------------------------------------------------------------------------- +; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | +; --------------------------------------------------------------------------------- +; | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR| +; --------------------------------------------------------------------------------- + +.386 +.XMM +.model flat, c +.code + +jump_fcontext PROC BOOST_CONTEXT_EXPORT + ; fourth arg of jump_fcontext() == flag indicating preserving FPU + mov ecx, [esp+010h] + + push ebp ; save EBP + push ebx ; save EBX + push esi ; save ESI + push edi ; save EDI + + assume fs:nothing + ; load NT_TIB into ECX + mov edx, fs:[018h] + assume fs:error + + ; load current SEH exception list + mov eax, [edx] + push eax + + ; load current stack base + mov eax, [edx+04h] + push eax + + ; load current stack limit + mov eax, [edx+08h] + push eax + + ; load current deallocation stack + mov eax, [edx+0e0ch] + push eax + + ; load fiber local storage + mov eax, [edx+010h] + push eax + + ; prepare stack for FPU + lea esp, [esp-08h] + + ; test for flag preserve_fpu + test ecx, ecx + je nxt1 + + ; save MMX control- and status-word + stmxcsr [esp] + ; save x87 control-word + fnstcw [esp+04h] + +nxt1: + ; first arg of jump_fcontext() == context jumping from + mov eax, [esp+030h] + + ; store ESP (pointing to context-data) in EAX + mov [eax], esp + + ; second arg of jump_fcontext() == context jumping to + mov edx, [esp+034h] + + ; third arg of jump_fcontext() == value to be returned after jump + mov eax, [esp+038h] + + ; restore ESP (pointing to context-data) from EDX + mov esp, edx + + ; test for flag preserve_fpu + test ecx, ecx + je nxt2 + + ; restore MMX control- and status-word + ldmxcsr [esp] + ; restore x87 control-word + fldcw [esp+04h] + +nxt2: + ; prepare stack for FPU + lea esp, [esp+08h] + + assume fs:nothing + ; load NT_TIB into ECX + mov edx, fs:[018h] + assume fs:error + + ; restore fiber local storage + pop ecx + mov [edx+010h], ecx + + ; restore current deallocation stack + pop ecx + mov [edx+0e0ch], ecx + + ; restore current stack limit + pop ecx + mov [edx+08h], ecx + + ; restore current stack base + pop ecx + mov [edx+04h], ecx + + ; restore current SEH exception list + pop ecx + mov [edx], ecx + + pop edi ; save EDI + pop esi ; save ESI + pop ebx ; save EBX + pop ebp ; save EBP + + ; restore return-address + pop edx + + ; use value in EAX as return-value after jump + ; use value in EAX as first arg in context function + mov [esp+04h], eax + + ; indirect jump to context + jmp edx +jump_fcontext ENDP +END diff --git a/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_elf_gas.S new file mode 100755 index 0000000..aa47b0f --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_elf_gas.S @@ -0,0 +1,90 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,@function +jump_fcontext: + /* fourth arg of jump_fcontext() == flag indicating preserving FPU */ + movl 0x10(%esp), %ecx + + pushl %ebp /* save EBP */ + pushl %ebx /* save EBX */ + pushl %esi /* save ESI */ + pushl %edi /* save EDI */ + + /* prepare stack for FPU */ + leal -0x8(%esp), %esp + + /* test for flag preserve_fpu */ + test %ecx, %ecx + je 1f + + /* save MMX control- and status-word */ + stmxcsr (%esp) + /* save x87 control-word */ + fnstcw 0x4(%esp) + +1: + /* first arg of jump_fcontext() == context jumping from */ + movl 0x1c(%esp), %eax + + /* store ESP (pointing to context-data) in EAX */ + movl %esp, (%eax) + + /* second arg of jump_fcontext() == context jumping to */ + movl 0x20(%esp), %edx + + /* third arg of jump_fcontext() == value to be returned after jump */ + movl 0x24(%esp), %eax + + /* restore ESP (pointing to context-data) from EDX */ + movl %edx, %esp + + /* test for flag preserve_fpu */ + test %ecx, %ecx + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr (%esp) + /* restore x87 control-word */ + fldcw 0x4(%esp) +2: + /* prepare stack for FPU */ + leal 0x8(%esp), %esp + + popl %edi /* restore EDI */ + popl %esi /* restore ESI */ + popl %ebx /* restore EBX */ + popl %ebp /* restore EBP */ + + /* restore return-address */ + popl %edx + + /* use value in EAX as return-value after jump */ + /* use value in EAX as first arg in context function */ + movl %eax, 0x4(%esp) + + /* indirect jump to context */ + jmp *%edx +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_macho_gas.S new file mode 100755 index 0000000..05d669f --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_i386_sysv_macho_gas.S @@ -0,0 +1,85 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl _jump_fcontext +.align 2 +_jump_fcontext: + /* fourth arg of jump_fcontext() == flag indicating preserving FPU */ + movl 0x10(%esp), %ecx + + pushl %ebp /* save EBP */ + pushl %ebx /* save EBX */ + pushl %esi /* save ESI */ + pushl %edi /* save EDI */ + + /* prepare stack for FPU */ + leal -0x8(%esp), %esp + + /* test for flag preserve_fpu */ + test %ecx, %ecx + je 1f + + /* save MMX control- and status-word */ + stmxcsr (%esp) + /* save x87 control-word */ + fnstcw 0x4(%esp) + +1: + /* first arg of jump_fcontext() == context jumping from */ + movl 0x1c(%esp), %eax + + /* store ESP (pointing to context-data) in EAX */ + movl %esp, (%eax) + + /* second arg of jump_fcontext() == context jumping to */ + movl 0x20(%esp), %edx + + /* third arg of jump_fcontext() == value to be returned after jump */ + movl 0x24(%esp), %eax + + /* restore ESP (pointing to context-data) from EDX */ + movl %edx, %esp + + /* test for flag preserve_fpu */ + test %ecx, %ecx + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr (%esp) + /* restore x87 control-word */ + fldcw 0x4(%esp) +2: + /* prepare stack for FPU */ + leal 0x8(%esp), %esp + + popl %edi /* restore EDI */ + popl %esi /* restore ESI */ + popl %ebx /* restore EBX */ + popl %ebp /* restore EBP */ + + /* restore return-address */ + popl %edx + + /* use value in EAX as return-value after jump */ + /* use value in EAX as first arg in context function */ + movl %eax, 0x4(%esp) + + /* indirect jump to context */ + jmp *%edx diff --git a/vendor/swoole/thirdparty/boost/asm/jump_i386_x86_64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_i386_x86_64_sysv_macho_gas.S new file mode 100755 index 0000000..959ddac --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_i386_x86_64_sysv_macho_gas.S @@ -0,0 +1,16 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__i386__) + #include "jump_i386_sysv_macho_gas.S" +#elif defined(__x86_64__) + #include "jump_x86_64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/jump_mips32_o32_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_mips32_o32_elf_gas.S new file mode 100755 index 0000000..67cc079 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_mips32_o32_elf_gas.S @@ -0,0 +1,118 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F20 | F22 | F24 | F26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F28 | F30 | S0 | S1 | S2 | S3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | | * + * ------------------------------------------------- * + * | S4 | S5 | S6 | S7 | FP | RA | PC | | * + * ------------------------------------------------- * + * * + * *****************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,@function +.ent jump_fcontext +jump_fcontext: + # reserve space on stack + addiu $sp, $sp, -92 + + sw $s0, 48($sp) # save S0 + sw $s1, 52($sp) # save S1 + sw $s2, 56($sp) # save S2 + sw $s3, 60($sp) # save S3 + sw $s4, 64($sp) # save S4 + sw $s5, 68($sp) # save S5 + sw $s6, 72($sp) # save S6 + sw $s7, 76($sp) # save S7 + sw $fp, 80($sp) # save FP + sw $ra, 84($sp) # save RA + sw $ra, 88($sp) # save RA as PC + +#if defined(__mips_hard_float) + # test if fpu env should be preserved + beqz $a3, 1f + + s.d $f20, ($sp) # save F20 + s.d $f22, 8($sp) # save F22 + s.d $f24, 16($sp) # save F24 + s.d $f26, 24($sp) # save F26 + s.d $f28, 32($sp) # save F28 + s.d $f30, 40($sp) # save F30 + +1: +#endif + + # store SP (pointing to context-data) in A0 + sw $sp, ($a0) + + # restore SP (pointing to context-data) from A1 + move $sp, $a1 + + +#if defined(__mips_hard_float) + # test if fpu env should be preserved + beqz $a3, 2f + + l.d $f20, ($sp) # restore F20 + l.d $f22, 8($sp) # restore F22 + l.d $f24, 16($sp) # restore F24 + l.d $f26, 24($sp) # restore F26 + l.d $f28, 32($sp) # restore F28 + l.d $f30, 40($sp) # restore F30 + +2: +#endif + + lw $s0, 48($sp) # restore S0 + lw $s1, 52($sp) # restore S1 + lw $s2, 56($sp) # restore S2 + lw $s3, 60($sp) # restore S3 + lw $s4, 64($sp) # restore S4 + lw $s5, 68($sp) # restore S5 + lw $s6, 72($sp) # restore S6 + lw $s7, 76($sp) # restore S7 + lw $fp, 80($sp) # restore FP + lw $ra, 84($sp) # restore RA + + # load PC + lw $t9, 88($sp) + + # adjust stack + addiu $sp, $sp, 92 + + # use third arg as return value after jump + move $v0, $a2 + # use third arg as first arg in context function + move $a0, $a2 + + # jump to context + jr $t9 +.end jump_fcontext +.size jump_fcontext, .-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc32_ppc64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_ppc64_sysv_macho_gas.S new file mode 100755 index 0000000..f175e31 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_ppc64_sysv_macho_gas.S @@ -0,0 +1,16 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__ppc__) + #include "jump_ppc32_sysv_macho_gas.S" +#elif defined(__ppc64__) + #include "jump_ppc64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_elf_gas.S new file mode 100755 index 0000000..d5380d5 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_elf_gas.S @@ -0,0 +1,208 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | R14 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | | * + * ------------------------------------------------- * + * | R31 | CR | LR | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl jump_fcontext +.align 2 +.type jump_fcontext,@function +jump_fcontext: + # reserve space on stack + subi %r1, %r1, 240 + + stw %r13, 152(%r1) # save R13 + stw %r14, 156(%r1) # save R14 + stw %r15, 160(%r1) # save R15 + stw %r16, 164(%r1) # save R16 + stw %r17, 168(%r1) # save R17 + stw %r18, 172(%r1) # save R18 + stw %r19, 176(%r1) # save R19 + stw %r20, 180(%r1) # save R20 + stw %r21, 184(%r1) # save R21 + stw %r22, 188(%r1) # save R22 + stw %r23, 192(%r1) # save R23 + stw %r24, 196(%r1) # save R24 + stw %r25, 200(%r1) # save R25 + stw %r26, 204(%r1) # save R26 + stw %r27, 208(%r1) # save R27 + stw %r28, 212(%r1) # save R28 + stw %r29, 216(%r1) # save R29 + stw %r30, 220(%r1) # save R30 + stw %r31, 224(%r1) # save R31 + + # save CR + mfcr %r0 + stw %r0, 228(%r1) + # save LR + mflr %r0 + stw %r0, 232(%r1) + # save LR as PC + stw %r0, 236(%r1) + + # test if fpu env should be preserved + cmpwi cr7, %r6, 0 + beq cr7, 1f + + stfd %f14, 0(%r1) # save F14 + stfd %f15, 8(%r1) # save F15 + stfd %f16, 16(%r1) # save F16 + stfd %f17, 24(%r1) # save F17 + stfd %f18, 32(%r1) # save F18 + stfd %f19, 40(%r1) # save F19 + stfd %f20, 48(%r1) # save F20 + stfd %f21, 56(%r1) # save F21 + stfd %f22, 64(%r1) # save F22 + stfd %f23, 72(%r1) # save F23 + stfd %f24, 80(%r1) # save F24 + stfd %f25, 88(%r1) # save F25 + stfd %f26, 96(%r1) # save F26 + stfd %f27, 104(%r1) # save F27 + stfd %f28, 112(%r1) # save F28 + stfd %f29, 120(%r1) # save F29 + stfd %f30, 128(%r1) # save F30 + stfd %f31, 136(%r1) # save F31 + mffs %f0 # load FPSCR + stfd %f0, 144(%r1) # save FPSCR + +1: + # store RSP (pointing to context-data) in R3 + stw %r1, 0(%r3) + + # restore RSP (pointing to context-data) from R4 + mr %r1, %r4 + + # test if fpu env should be preserved + cmpwi cr7, %r6, 0 + beq cr7, 2f + + lfd %f14, 0(%r1) # restore F14 + lfd %f15, 8(%r1) # restore F15 + lfd %f16, 16(%r1) # restore F16 + lfd %f17, 24(%r1) # restore F17 + lfd %f18, 32(%r1) # restore F18 + lfd %f19, 40(%r1) # restore F19 + lfd %f20, 48(%r1) # restore F20 + lfd %f21, 56(%r1) # restore F21 + lfd %f22, 64(%r1) # restore F22 + lfd %f23, 72(%r1) # restore F23 + lfd %f24, 80(%r1) # restore F24 + lfd %f25, 88(%r1) # restore F25 + lfd %f26, 96(%r1) # restore F26 + lfd %f27, 104(%r1) # restore F27 + lfd %f28, 112(%r1) # restore F28 + lfd %f29, 120(%r1) # restore F29 + lfd %f30, 128(%r1) # restore F30 + lfd %f31, 136(%r1) # restore F31 + lfd %f0, 144(%r1) # load FPSCR + mtfsf 0xff, %f0 # restore FPSCR + +2: + lwz %r13, 152(%r1) # restore R13 + lwz %r14, 156(%r1) # restore R14 + lwz %r15, 160(%r1) # restore R15 + lwz %r16, 164(%r1) # restore R16 + lwz %r17, 168(%r1) # restore R17 + lwz %r18, 172(%r1) # restore R18 + lwz %r19, 176(%r1) # restore R19 + lwz %r20, 180(%r1) # restore R20 + lwz %r21, 184(%r1) # restore R21 + lwz %r22, 188(%r1) # restore R22 + lwz %r23, 192(%r1) # restore R23 + lwz %r24, 196(%r1) # restore R24 + lwz %r25, 200(%r1) # restore R25 + lwz %r26, 204(%r1) # restore R26 + lwz %r27, 208(%r1) # restore R27 + lwz %r28, 212(%r1) # restore R28 + lwz %r29, 216(%r1) # restore R29 + lwz %r30, 220(%r1) # restore R30 + lwz %r31, 224(%r1) # restore R31 + + # restore CR + lwz %r0, 228(%r1) + mtcr %r0 + # restore LR + lwz %r0, 232(%r1) + mtlr %r0 + + # load PC + lwz %r0, 236(%r1) + # restore CTR + mtctr %r0 + + # adjust stack + addi %r1, %r1, 240 + + # use third arg as return value after jump + # use third arg as first arg in context function + mr %r3, %r5 + + # jump to context + bctr +.size jump_fcontext, .-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_macho_gas.S new file mode 100755 index 0000000..59d8f49 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_macho_gas.S @@ -0,0 +1,203 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | R14 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | | * + * ------------------------------------------------- * + * | R31 | CR | LR | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl _jump_fcontext +.align 2 +_jump_fcontext: + ; reserve space on stack + subi r1, r1, 240 + + stw r13, 152(r1) ; save R13 + stw r14, 156(r1) ; save R14 + stw r15, 160(r1) ; save R15 + stw r16, 164(r1) ; save R16 + stw r17, 168(r1) ; save R17 + stw r18, 172(r1) ; save R18 + stw r19, 176(r1) ; save R19 + stw r20, 180(r1) ; save R20 + stw r21, 184(r1) ; save R21 + stw r22, 188(r1) ; save R22 + stw r23, 192(r1) ; save R23 + stw r24, 196(r1) ; save R24 + stw r25, 200(r1) ; save R25 + stw r26, 204(r1) ; save R26 + stw r27, 208(r1) ; save R27 + stw r28, 212(r1) ; save R28 + stw r29, 216(r1) ; save R29 + stw r30, 220(r1) ; save R30 + stw r31, 224(r1) ; save R31 + + ; save CR + mfcr r0 + stw r0, 228(r1) + ; save LR + mflr r0 + stw r0, 232(r1) + ; save LR as PC + stw r0, 236(r1) + + ; test if fpu env should be preserved + cmpwi cr7, r6, 0 + beq cr7, l1 + + stfd f14, 0(r1) ; save F14 + stfd f15, 8(r1) ; save F15 + stfd f16, 16(r1) ; save F16 + stfd f17, 24(r1) ; save F17 + stfd f18, 32(r1) ; save F18 + stfd f19, 40(r1) ; save F19 + stfd f20, 48(r1) ; save F20 + stfd f21, 56(r1) ; save F21 + stfd f22, 64(r1) ; save F22 + stfd f23, 72(r1) ; save F23 + stfd f24, 80(r1) ; save F24 + stfd f25, 88(r1) ; save F25 + stfd f26, 96(r1) ; save F26 + stfd f27, 104(r1) ; save F27 + stfd f28, 112(r1) ; save F28 + stfd f29, 120(r1) ; save F29 + stfd f30, 128(r1) ; save F30 + stfd f31, 136(r1) ; save F31 + mffs f0 ; load FPSCR + stfd f0, 144(r1) ; save FPSCR + +l1: + ; store RSP (pointing to context-data) in R3 + stw r1, 0(r3) + + ; restore RSP (pointing to context-data) from R4 + mr r1, r4 + + ; test if fpu env should be preserved + cmpwi cr7, r6, 0 + beq cr7, l2 + + lfd f14, 0(r1) ; restore F14 + lfd f15, 8(r1) ; restore F15 + lfd f16, 16(r1) ; restore F16 + lfd f17, 24(r1) ; restore F17 + lfd f18, 32(r1) ; restore F18 + lfd f19, 40(r1) ; restore F19 + lfd f20, 48(r1) ; restore F20 + lfd f21, 56(r1) ; restore F21 + lfd f22, 64(r1) ; restore F22 + lfd f23, 72(r1) ; restore F23 + lfd f24, 80(r1) ; restore F24 + lfd f25, 88(r1) ; restore F25 + lfd f26, 96(r1) ; restore F26 + lfd f27, 104(r1) ; restore F27 + lfd f28, 112(r1) ; restore F28 + lfd f29, 120(r1) ; restore F29 + lfd f30, 128(r1) ; restore F30 + lfd f31, 136(r1) ; restore F31 + lfd f0, 144(r1) ; load FPSCR + mtfsf 0xff, f0 ; restore FPSCR + +l2: + lwz r13, 152(r1) ; restore R13 + lwz r14, 156(r1) ; restore R14 + lwz r15, 160(r1) ; restore R15 + lwz r16, 164(r1) ; restore R16 + lwz r17, 168(r1) ; restore R17 + lwz r18, 172(r1) ; restore R18 + lwz r19, 176(r1) ; restore R19 + lwz r20, 180(r1) ; restore R20 + lwz r21, 184(r1) ; restore R21 + lwz r22, 188(r1) ; restore R22 + lwz r23, 192(r1) ; restore R23 + lwz r24, 196(r1) ; restore R24 + lwz r25, 200(r1) ; restore R25 + lwz r26, 204(r1) ; restore R26 + lwz r27, 208(r1) ; restore R27 + lwz r28, 212(r1) ; restore R28 + lwz r29, 216(r1) ; restore R29 + lwz r30, 220(r1) ; restore R30 + lwz r31, 224(r1) ; restore R31 + + ; restore CR + lwz r0, 228(r1) + mtcr r0 + ; restore LR + lwz r0, 232(r1) + mtlr r0 + + ; load PC + lwz r0, 236(r1) + ; restore CTR + mtctr r0 + + ; adjust stack + addi r1, r1, 240 + + ; use third arg as return value after jump + ; use third arg as first arg in context function + mr r3, r5 + + ; jump to context + bctr diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_xcoff_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_xcoff_gas.S new file mode 100755 index 0000000..7cdf8a9 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc32_sysv_xcoff_gas.S @@ -0,0 +1,138 @@ +.globl .jump_fcontext +.globl jump_fcontext[DS] +.align 2 +.csect jump_fcontext[DS] +jump_fcontext: + .long .jump_fcontext +.jump_fcontext: + # reserve space on stack + subi 1, 1, 240 + + stw 13, 152(1) # save R13 + stw 14, 156(1) # save R14 + stw 15, 160(1) # save R15 + stw 16, 164(1) # save R16 + stw 17, 168(1) # save R17 + stw 18, 172(1) # save R18 + stw 19, 176(1) # save R19 + stw 20, 180(1) # save R20 + stw 21, 184(1) # save R21 + stw 22, 188(1) # save R22 + stw 23, 192(1) # save R23 + stw 24, 196(1) # save R24 + stw 25, 200(1) # save R25 + stw 26, 204(1) # save R26 + stw 27, 208(1) # save R27 + stw 28, 212(1) # save R28 + stw 29, 216(1) # save R29 + stw 30, 220(1) # save R30 + stw 31, 224(1) # save R31 + + # save CR + mfcr 0 + stw 0, 228(1) + # save LR + mflr 0 + stw 0, 232(1) + # save LR as PC + stw 0, 236(1) + + # test if fpu env should be preserved + cmpwi 7, 6, 0 + beq 7, label1 + + stfd 14, 0(1) # save F14 + stfd 15, 8(1) # save F15 + stfd 16, 16(1) # save F16 + stfd 17, 24(1) # save F17 + stfd 18, 32(1) # save F18 + stfd 19, 40(1) # save F19 + stfd 20, 48(1) # save F20 + stfd 21, 56(1) # save F21 + stfd 22, 64(1) # save F22 + stfd 23, 72(1) # save F23 + stfd 24, 80(1) # save F24 + stfd 25, 88(1) # save F25 + stfd 26, 96(1) # save F26 + stfd 27, 104(1) # save F27 + stfd 28, 112(1) # save F28 + stfd 29, 120(1) # save F29 + stfd 30, 128(1) # save F30 + stfd 31, 136(1) # save F31 + mffs 0 # load FPSCR + stfd 0, 144(1) # save FPSCR + +label1: + # store RSP (pointing to context-data) in R3 + stw 1, 0(3) + + # restore RSP (pointing to context-data) from R4 + mr 1, 4 + + # test if fpu env should be preserved + cmpwi 7, 6, 0 + beq 7, label2 + + lfd 14, 0(1) # restore F14 + lfd 15, 8(1) # restore F15 + lfd 16, 16(1) # restore F16 + lfd 17, 24(1) # restore F17 + lfd 18, 32(1) # restore F18 + lfd 19, 40(1) # restore F19 + lfd 20, 48(1) # restore F20 + lfd 21, 56(1) # restore F21 + lfd 22, 64(1) # restore F22 + lfd 23, 72(1) # restore F23 + lfd 24, 80(1) # restore F24 + lfd 25, 88(1) # restore F25 + lfd 26, 96(1) # restore F26 + lfd 27, 104(1) # restore F27 + lfd 28, 112(1) # restore F28 + lfd 29, 120(1) # restore F29 + lfd 30, 128(1) # restore F30 + lfd 31, 136(1) # restore F31 + lfd 0, 144(1) # load FPSCR + mtfsf 0xff, 0 # restore FPSCR + +label2: + lwz 13, 152(1) # restore R13 + lwz 14, 156(1) # restore R14 + lwz 15, 160(1) # restore R15 + lwz 16, 164(1) # restore R16 + lwz 17, 168(1) # restore R17 + lwz 18, 172(1) # restore R18 + lwz 19, 176(1) # restore R19 + lwz 20, 180(1) # restore R20 + lwz 21, 184(1) # restore R21 + lwz 22, 188(1) # restore R22 + lwz 23, 192(1) # restore R23 + lwz 24, 196(1) # restore R24 + lwz 25, 200(1) # restore R25 + lwz 26, 204(1) # restore R26 + lwz 27, 208(1) # restore R27 + lwz 28, 212(1) # restore R28 + lwz 29, 216(1) # restore R29 + lwz 30, 220(1) # restore R30 + lwz 31, 224(1) # restore R31 + + # restore CR + lwz 0, 228(1) + mtcr 0 + # restore LR + lwz 0, 232(1) + mtlr 0 + + # load PC + lwz 0, 236(1) + # restore CTR + mtctr 0 + + # adjust stack + addi 1, 1, 240 + + # use third arg as return value after jump + # use third arg as first arg in context function + mr 3, 5 + + # jump to context + bctr diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_elf_gas.S new file mode 100755 index 0000000..46bc3cc --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_elf_gas.S @@ -0,0 +1,267 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | TOC | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R14 | R15 | R16 | R17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R18 | R19 | R20 | R21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * + * ------------------------------------------------- * + * | R22 | R23 | R24 | R25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * + * ------------------------------------------------- * + * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * + * ------------------------------------------------- * + * | R26 | R27 | R28 | R29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * + * ------------------------------------------------- * + * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | R30 | R31 | CR | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 80 | 81 | | * + * ------------------------------------------------- * + * | 320 | 324 | | * + * ------------------------------------------------- * + * | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.globl jump_fcontext +#if _CALL_ELF == 2 + .text + .align 2 +jump_fcontext: + addis %r2, %r12, .TOC.-jump_fcontext@ha + addi %r2, %r2, .TOC.-jump_fcontext@l + .localentry jump_fcontext, . - jump_fcontext +#else + .section ".opd","aw" + .align 3 +jump_fcontext: +# ifdef _CALL_LINUX + .quad .L.jump_fcontext,.TOC.@tocbase,0 + .type jump_fcontext,@function + .text + .align 2 +.L.jump_fcontext: +# else + .hidden .jump_fcontext + .globl .jump_fcontext + .quad .jump_fcontext,.TOC.@tocbase,0 + .size jump_fcontext,24 + .type .jump_fcontext,@function + .text + .align 2 +.jump_fcontext: +# endif +#endif + # reserve space on stack + subi %r1, %r1, 328 + +#if _CALL_ELF != 2 + std %r2, 152(%r1) # save TOC +#endif + std %r14, 160(%r1) # save R14 + std %r15, 168(%r1) # save R15 + std %r16, 176(%r1) # save R16 + std %r17, 184(%r1) # save R17 + std %r18, 192(%r1) # save R18 + std %r19, 200(%r1) # save R19 + std %r20, 208(%r1) # save R20 + std %r21, 216(%r1) # save R21 + std %r22, 224(%r1) # save R22 + std %r23, 232(%r1) # save R23 + std %r24, 240(%r1) # save R24 + std %r25, 248(%r1) # save R25 + std %r26, 256(%r1) # save R26 + std %r27, 264(%r1) # save R27 + std %r28, 272(%r1) # save R28 + std %r29, 280(%r1) # save R29 + std %r30, 288(%r1) # save R30 + std %r31, 296(%r1) # save R31 + + # save CR + mfcr %r0 + std %r0, 304(%r1) + # save LR + mflr %r0 + std %r0, 312(%r1) + # save LR as PC + std %r0, 320(%r1) + + # test if fpu env should be preserved + cmpwi cr7, %r6, 0 + beq cr7, 1f + + stfd %f14, 0(%r1) # save F14 + stfd %f15, 8(%r1) # save F15 + stfd %f16, 16(%r1) # save F16 + stfd %f17, 24(%r1) # save F17 + stfd %f18, 32(%r1) # save F18 + stfd %f19, 40(%r1) # save F19 + stfd %f20, 48(%r1) # save F20 + stfd %f21, 56(%r1) # save F21 + stfd %f22, 64(%r1) # save F22 + stfd %f23, 72(%r1) # save F23 + stfd %f24, 80(%r1) # save F24 + stfd %f25, 88(%r1) # save F25 + stfd %f26, 96(%r1) # save F26 + stfd %f27, 104(%r1) # save F27 + stfd %f28, 112(%r1) # save F28 + stfd %f29, 120(%r1) # save F29 + stfd %f30, 128(%r1) # save F30 + stfd %f31, 136(%r1) # save F31 + mffs %f0 # load FPSCR + stfd %f0, 144(%r1) # save FPSCR + +1: + # store RSP (pointing to context-data) in R3 + std %r1, 0(%r3) + + # restore RSP (pointing to context-data) from R4 + mr %r1, %r4 + + # test if fpu env should be preserved + cmpwi cr7, %r6, 0 + beq cr7, 2f + + lfd %f14, 0(%r1) # restore F14 + lfd %f15, 8(%r1) # restore F15 + lfd %f16, 16(%r1) # restore F16 + lfd %f17, 24(%r1) # restore F17 + lfd %f18, 32(%r1) # restore F18 + lfd %f19, 40(%r1) # restore F19 + lfd %f20, 48(%r1) # restore F20 + lfd %f21, 56(%r1) # restore F21 + lfd %f22, 64(%r1) # restore F22 + lfd %f23, 72(%r1) # restore F23 + lfd %f24, 80(%r1) # restore F24 + lfd %f25, 88(%r1) # restore F25 + lfd %f26, 96(%r1) # restore F26 + lfd %f27, 104(%r1) # restore F27 + lfd %f28, 112(%r1) # restore F28 + lfd %f29, 120(%r1) # restore F29 + lfd %f30, 128(%r1) # restore F30 + lfd %f31, 136(%r1) # restore F31 + lfd %f0, 144(%r1) # load FPSCR + mtfsf 0xff, %f0 # restore FPSCR + +2: +#if _CALL_ELF != 2 + ld %r2, 152(%r1) # restore TOC +#endif + ld %r14, 160(%r1) # restore R14 + ld %r15, 168(%r1) # restore R15 + ld %r16, 176(%r1) # restore R16 + ld %r17, 184(%r1) # restore R17 + ld %r18, 192(%r1) # restore R18 + ld %r19, 200(%r1) # restore R19 + ld %r20, 208(%r1) # restore R20 + ld %r21, 216(%r1) # restore R21 + ld %r22, 224(%r1) # restore R22 + ld %r23, 232(%r1) # restore R23 + ld %r24, 240(%r1) # restore R24 + ld %r25, 248(%r1) # restore R25 + ld %r26, 256(%r1) # restore R26 + ld %r27, 264(%r1) # restore R27 + ld %r28, 272(%r1) # restore R28 + ld %r29, 280(%r1) # restore R29 + ld %r30, 288(%r1) # restore R30 + ld %r31, 296(%r1) # restore R31 + + # restore CR + ld %r0, 304(%r1) + mtcr %r0 + # restore LR + ld %r0, 312(%r1) + mtlr %r0 + + # load PC + ld %r12, 320(%r1) + # restore CTR + mtctr %r12 + + # adjust stack + addi %r1, %r1, 328 + + # use third arg as return value after jump + # use third arg as first arg in context function + mr %r3, %r5 + + # jump to context + bctr +#if _CALL_ELF == 2 + .size jump_fcontext, .-jump_fcontext +#else +# ifdef _CALL_LINUX + .size .jump_fcontext, .-.L.jump_fcontext +# else + .size .jump_fcontext, .-.jump_fcontext +# endif +#endif + + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_macho_gas.S new file mode 100755 index 0000000..d94b7f6 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_macho_gas.S @@ -0,0 +1,226 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R14 | R15 | R16 | R17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R18 | R19 | R20 | R21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * + * ------------------------------------------------- * + * | R22 | R23 | R24 | R25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * + * ------------------------------------------------- * + * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * + * ------------------------------------------------- * + * | R26 | R27 | R28 | R29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * + * ------------------------------------------------- * + * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | R30 | R31 | CR | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 80 | 81 | | * + * ------------------------------------------------- * + * | 320 | 324 | | * + * ------------------------------------------------- * + * | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.align 2 +.globl jump_fcontext + +_jump_fcontext: + ; reserve space on stack + subi r1, r1, 328 + + std r13, 152(r1) ; save R13 + std r14, 160(r1) ; save R14 + std r15, 168(r1) ; save R15 + std r16, 176(r1) ; save R16 + std r17, 184(r1) ; save R17 + std r18, 192(r1) ; save R18 + std r19, 200(r1) ; save R19 + std r20, 208(r1) ; save R20 + std r21, 216(r1) ; save R21 + std r22, 224(r1) ; save R22 + std r23, 232(r1) ; save R23 + std r24, 240(r1) ; save R24 + std r25, 248(r1) ; save R25 + std r26, 256(r1) ; save R26 + std r27, 264(r1) ; save R27 + std r28, 272(r1) ; save R28 + std r29, 280(r1) ; save R29 + std r30, 288(r1) ; save R30 + std r31, 296(r1) ; save R31 + + ; save CR + mfcr r0 + std r0, 304(r1) + ; save LR + mflr r0 + std r0, 312(r1) + ; save LR as PC + std r0, 320(r1) + + ; test if fpu env should be preserved + cmpwi cr7, r6, 0 + beq cr7, l1 + + stfd f14, 0(r1) ; save F14 + stfd f15, 8(r1) ; save F15 + stfd f16, 16(r1) ; save F16 + stfd f17, 24(r1) ; save F17 + stfd f18, 32(r1) ; save F18 + stfd f19, 40(r1) ; save F19 + stfd f20, 48(r1) ; save F20 + stfd f21, 56(r1) ; save F21 + stfd f22, 64(r1) ; save F22 + stfd f23, 72(r1) ; save F23 + stfd f24, 80(r1) ; save F24 + stfd f25, 88(r1) ; save F25 + stfd f26, 96(r1) ; save F26 + stfd f27, 104(r1) ; save F27 + stfd f28, 112(r1) ; save F28 + stfd f29, 120(r1) ; save F29 + stfd f30, 128(r1) ; save F30 + stfd f31, 136(r1) ; save F31 + mffs f0 ; load FPSCR + stfd f0, 144(r1) ; save FPSCR + +l1: + ; store RSP (pointing to context-data) in R3 + stw r1, 0(r3) + + ; restore RSP (pointing to context-data) from R4 + mr r1, r4 + + ; test if fpu env should be preserved + cmpwi cr7, r6, 0 + beq cr7, l2 + + lfd f14, 0(r1) ; restore F14 + lfd f15, 8(r1) ; restore F15 + lfd f16, 16(r1) ; restore F16 + lfd f17, 24(r1) ; restore F17 + lfd f18, 32(r1) ; restore F18 + lfd f19, 40(r1) ; restore F19 + lfd f20, 48(r1) ; restore F20 + lfd f21, 56(r1) ; restore F21 + lfd f22, 64(r1) ; restore F22 + lfd f23, 72(r1) ; restore F23 + lfd f24, 80(r1) ; restore F24 + lfd f25, 88(r1) ; restore F25 + lfd f26, 96(r1) ; restore F26 + lfd f27, 104(r1) ; restore F27 + lfd f28, 112(r1) ; restore F28 + lfd f29, 120(r1) ; restore F29 + lfd f30, 128(r1) ; restore F30 + lfd f31, 136(r1) ; restore F31 + lfd f0, 144(r1) ; load FPSCR + mtfsf 0xff, f0 ; restore FPSCR + +2: + ld r13, 152(r1) ; restore R13 + ld r14, 160(r1) ; restore R14 + ld r15, 168(r1) ; restore R15 + ld r16, 176(r1) ; restore R16 + ld r17, 184(r1) ; restore R17 + ld r18, 192(r1) ; restore R18 + ld r19, 200(r1) ; restore R19 + ld r20, 208(r1) ; restore R20 + ld r21, 216(r1) ; restore R21 + ld r22, 224(r1) ; restore R22 + ld r23, 232(r1) ; restore R23 + ld r24, 240(r1) ; restore R24 + ld r25, 248(r1) ; restore R25 + ld r26, 256(r1) ; restore R26 + ld r27, 264(r1) ; restore R27 + ld r28, 272(r1) ; restore R28 + ld r29, 280(r1) ; restore R29 + ld r30, 288(r1) ; restore R30 + ld r31, 296(r1) ; restore R31 + + ; restore CR + ld r0, 304(r1) + mtcr r0 + ; restore LR + ld r0, 312(r1) + mtlr r0 + + ; load PC + ld r0, 320(r1) + ; restore CTR + mtctr r0 + + ; adjust stack + addi r1, r1, 328 + + ; use third arg as return value after jump + ; use third arg as first arg in context function + mr r3, r5 + + ; jump to context + bctr diff --git a/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_xcoff_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_xcoff_gas.S new file mode 100755 index 0000000..65d60d4 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_ppc64_sysv_xcoff_gas.S @@ -0,0 +1,134 @@ +.align 2 +.globl .jump_fcontext +.jump_fcontext: + # reserve space on stack + subi 1, 1, 328 + + std 13, 152(1) # save R13 + std 14, 160(1) # save R14 + std 15, 168(1) # save R15 + std 16, 176(1) # save R16 + std 17, 184(1) # save R17 + std 18, 192(1) # save R18 + std 19, 200(1) # save R19 + std 20, 208(1) # save R20 + std 21, 216(1) # save R21 + std 22, 224(1) # save R22 + std 23, 232(1) # save R23 + std 24, 240(1) # save R24 + std 25, 248(1) # save R25 + std 26, 256(1) # save R26 + std 27, 264(1) # save R27 + std 28, 272(1) # save R28 + std 29, 280(1) # save R29 + std 30, 288(1) # save R30 + std 31, 296(1) # save R31 + + # save CR + mfcr 0 + std 0, 304(1) + # save LR + mflr 0 + std 0, 312(1) + # save LR as PC + std 0, 320(1) + + # test if fpu env should be preserved + cmpwi 7, 6, 0 + beq 7, label1 + + stfd 14, 0(1) # save F14 + stfd 15, 8(1) # save F15 + stfd 16, 16(1) # save F16 + stfd 17, 24(1) # save F17 + stfd 18, 32(1) # save F18 + stfd 19, 40(1) # save F19 + stfd 20, 48(1) # save F20 + stfd 21, 56(1) # save F21 + stfd 22, 64(1) # save F22 + stfd 23, 72(1) # save F23 + stfd 24, 80(1) # save F24 + stfd 25, 88(1) # save F25 + stfd 26, 96(1) # save F26 + stfd 27, 104(1) # save F27 + stfd 28, 112(1) # save F28 + stfd 29, 120(1) # save F29 + stfd 30, 128(1) # save F30 + stfd 31, 136(1) # save F31 + mffs 0 # load FPSCR + stfd 0, 144(1) # save FPSCR + +label1: + # store RSP (pointing to context-data) in R3 + stw 1, 0(3) + + # restore RSP (pointing to context-data) from R4 + mr 1, 4 + + # test if fpu env should be preserved + cmpwi 7, 6, 0 + beq 7, label2 + + lfd 14, 0(1) # restore F14 + lfd 15, 8(1) # restore F15 + lfd 16, 16(1) # restore F16 + lfd 17, 24(1) # restore F17 + lfd 18, 32(1) # restore F18 + lfd 19, 40(1) # restore F19 + lfd 20, 48(1) # restore F20 + lfd 21, 56(1) # restore F21 + lfd 22, 64(1) # restore F22 + lfd 23, 72(1) # restore F23 + lfd 24, 80(1) # restore F24 + lfd 25, 88(1) # restore F25 + lfd 26, 96(1) # restore F26 + lfd 27, 104(1) # restore F27 + lfd 28, 112(1) # restore F28 + lfd 29, 120(1) # restore F29 + lfd 30, 128(1) # restore F30 + lfd 31, 136(1) # restore F31 + lfd 0, 144(1) # load FPSCR + mtfsf 0xff, 0 # restore FPSCR + +label2: + ld 13, 152(1) # restore R13 + ld 14, 160(1) # restore R14 + ld 15, 168(1) # restore R15 + ld 16, 176(1) # restore R16 + ld 17, 184(1) # restore R17 + ld 18, 192(1) # restore R18 + ld 19, 200(1) # restore R19 + ld 20, 208(1) # restore R20 + ld 21, 216(1) # restore R21 + ld 22, 224(1) # restore R22 + ld 23, 232(1) # restore R23 + ld 24, 240(1) # restore R24 + ld 25, 248(1) # restore R25 + ld 26, 256(1) # restore R26 + ld 27, 264(1) # restore R27 + ld 28, 272(1) # restore R28 + ld 29, 280(1) # restore R29 + ld 30, 288(1) # restore R30 + ld 31, 296(1) # restore R31 + + # restore CR + ld 0, 304(1) + mtcr 0 + # restore LR + ld 0, 312(1) + mtlr 0 + + # load PC + ld 0, 320(1) + # restore CTR + mtctr 0 + + # adjust stack + addi 1, 1, 328 + + # use third arg as return value after jump + # use third arg as first arg in context function + mr 3, 5 + + # jump to context + bctr diff --git a/vendor/swoole/thirdparty/boost/asm/jump_sparc64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_sparc64_sysv_elf_gas.S new file mode 100755 index 0000000..ec01de8 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_sparc64_sysv_elf_gas.S @@ -0,0 +1,139 @@ +/* + Copyright Martin Husemann 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************* + * * + * ------------------------------------------------------------- * + * | Offset (in 4 or 8 byte units) | Content | * + * ------------------------------------------------------------- * + * | 0 | %sp | * + * ------------------------------------------------------------- * + * | 1 | %pc | * + * ------------------------------------------------------------- * + * | 2 | %i7 (return address) | * + * ------------------------------------------------------------- * + * | 3 | %g1 | * + * ------------------------------------------------------------- * + * | 4 | %g2 | * + * ------------------------------------------------------------- * + * | 5 | %g3 | * + * ------------------------------------------------------------- * + * | 6 | %g6 | * + * ------------------------------------------------------------- * + * | 7 | %g7 | * + * ------------------------------------------------------------- * + * The local and in registers are stored on the stack. * + *******************************************************************/ + +#define OFF(N) (8*(N)) +#define CCFSZ 176 // C Compiler Frame Size +#define BIAS (2048-1) // Stack offset for 64 bit programs +#define FC_SZ 448 // sizeof(fcontext_t) +#define FC_STK 384 // offsetof(fcontext_t, fc_stack) +#define FC_FPU 0 // offsetof(fcontext_t, fc_fp) +#define FC_FSR 264 // offsetof(fcontext_t, fc_fp.fp_fsr) +#define FC_FPRS 256 // offsetof(fcontext_t, fc_fp.fp_fprs) +#define FC_GREG 320 // offsetof(fcontext_t, fc_greg) +#define BLOCK_SIZE 64 + + .register %g2,#ignore + .register %g3,#ignore + .register %g6,#ignore + +.text +.globl jump_fcontext +.align 4 +.type jump_fcontext,@function +// intptr_t +// jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, +// bool preserve_fpu = true); +jump_fcontext: + // %o0 = pointer to old fcontext, save current state here + // %o1 = new context to jump to + // %o2 = new return value in context %o0 + // %o3 = preserve fpu registers + // Save current state in %o0 fcontext, then activate %o1. + // If %o3, include fpu registers. + + flushw // make sure all shadow registers are up to date in the current stack + + // save current state to fcontext_t at %o0 + stx %sp, [%o0 + FC_GREG + OFF(0)] // current stack pointer + add %o7, 8, %o4 // calculate next instruction past call + stx %o4, [%o0 + FC_GREG + OFF(1)] // and store it as %pc in save context + stx %o7, [%o0 + FC_GREG + OFF(2)] + stx %g1, [%o0 + FC_GREG + OFF(3)] + stx %g2, [%o0 + FC_GREG + OFF(4)] + stx %g3, [%o0 + FC_GREG + OFF(5)] + stx %g6, [%o0 + FC_GREG + OFF(6)] + stx %g7, [%o0 + FC_GREG + OFF(7)] + + // do we need to handle fpu? + brz %o3, Lno_fpu + nop + + add %o0, FC_FPU, %o5 + stda %f0, [%o5] 0xf0 /* ASI_BLOCK_PRIMARY */ + add %o5, BLOCK_SIZE, %o5 + stda %f16, [%o5] 0xf0 + add %o5, BLOCK_SIZE, %o5 + stda %f32, [%o5] 0xf0 + add %o5, BLOCK_SIZE, %o5 + stda %f48, [%o5] 0xf0 + stx %fsr, [%o0+FC_FSR] + rd %fprs, %o4 + stx %o4, [%o0+FC_FPRS] + + add %o1, FC_FPU, %o5 + ldda [%o5] 0xf0 /* ASI_BLOCK_PRIMARY */, %f0 + add %o5, BLOCK_SIZE, %o5 + ldda [%o5] 0xf0, %f16 + add %o5, BLOCK_SIZE, %o5 + ldda [%o5] 0xf0, %f32 + add %o5, BLOCK_SIZE, %o5 + ldda [%o5] 0xf0, %f48 + ldx [%o1+FC_FSR], %fsr + ldx [%o1+FC_FPRS], %o4 + wr %o4,0,%fprs + +Lno_fpu: + // load new state from %o1 + ldx [%o1 + FC_GREG + OFF(1)], %o4 + ldx [%o1 + FC_GREG + OFF(2)], %o7 + ldx [%o1 + FC_GREG + OFF(3)], %g1 + ldx [%o1 + FC_GREG + OFF(4)], %g2 + ldx [%o1 + FC_GREG + OFF(5)], %g3 + ldx [%o1 + FC_GREG + OFF(6)], %g6 + ldx [%o1 + FC_GREG + OFF(7)], %g7 + // switch to new stack + ldx [%o1 + FC_GREG + OFF(0)], %sp + // and now reload from this stack the shadow regist bank contents + ldx [%sp + BIAS + OFF(0)], %l0 + ldx [%sp + BIAS + OFF(1)], %l1 + ldx [%sp + BIAS + OFF(2)], %l2 + ldx [%sp + BIAS + OFF(3)], %l3 + ldx [%sp + BIAS + OFF(4)], %l4 + ldx [%sp + BIAS + OFF(5)], %l5 + ldx [%sp + BIAS + OFF(6)], %l6 + ldx [%sp + BIAS + OFF(7)], %l7 + ldx [%sp + BIAS + OFF(8)], %i0 + ldx [%sp + BIAS + OFF(9)], %i1 + ldx [%sp + BIAS + OFF(10)], %i2 + ldx [%sp + BIAS + OFF(11)], %i3 + ldx [%sp + BIAS + OFF(12)], %i4 + ldx [%sp + BIAS + OFF(13)], %i5 + ldx [%sp + BIAS + OFF(14)], %i6 + ldx [%sp + BIAS + OFF(15)], %i7 + + // finally continue execution in new context + jmp %o4 + mov %o2, %o0 // return arg as result + +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_sparc_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_sparc_sysv_elf_gas.S new file mode 100755 index 0000000..5f85c3e --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_sparc_sysv_elf_gas.S @@ -0,0 +1,135 @@ +/* + Copyright Martin Husemann 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************* + * * + * ------------------------------------------------------------- * + * | Offset (in 4 or 8 byte units) | Content | * + * ------------------------------------------------------------- * + * | 0 | %sp | * + * ------------------------------------------------------------- * + * | 1 | %pc | * + * ------------------------------------------------------------- * + * | 2 | %i7 (return address) | * + * ------------------------------------------------------------- * + * | 3 | %g1 | * + * ------------------------------------------------------------- * + * | 4 | %g2 | * + * ------------------------------------------------------------- * + * | 5 | %g3 | * + * ------------------------------------------------------------- * + * | 6 | %g6 | * + * ------------------------------------------------------------- * + * | 7 | %g7 | * + * ------------------------------------------------------------- * + * The local and in registers are stored on the stack. * + *******************************************************************/ + +#define OFF(N) (4*(N)) +#define CCFSZ 96 +#define FC_SZ 176 +#define FC_stK 168 // offsetof(fcontext_t, fc_stack) +#define FC_FPU 0 // offsetof(fcontext_t, fc_fp) +#define FC_FSR 128 // offsetof(fcontext_t, fc_fp.fp_fsr) +#define FC_GREG 136 // offsetof(fcontext_t, fc_greg) +#define BLOCK_SIZE 8 +#ifdef __NetBSD__ +#define FLUSHW t 0x83; nop // T_FLUSHWIN +#endif + +.text +.globl jump_fcontext +.align 4 +.type jump_fcontext,@function +// intptr_t +// jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, +// bool preserve_fpu = true); +jump_fcontext: + // %o0 = pointer to old fcontext, save current state here + // %o1 = new context to jump to + // %o2 = new return value in context %o0 + // %o3 = preserve fpu registers + // Save current state in %o0 fcontext, then activate %o1. + // If %o3, include fpu registers. + + FLUSHW // make sure all shadow registers are up to date in the current stack + + // save current state to fcontext_t at %o0 + st %sp, [%o0 + FC_GREG + OFF(0)] // current stack pointer + add %o7, 8, %o4 // calculate next instruction past call + st %o4, [%o0 + FC_GREG + OFF(1)] // and store it as %pc in save context + st %o7, [%o0 + FC_GREG + OFF(2)] + st %g1, [%o0 + FC_GREG + OFF(3)] + st %g2, [%o0 + FC_GREG + OFF(4)] + st %g3, [%o0 + FC_GREG + OFF(5)] + st %g6, [%o0 + FC_GREG + OFF(6)] + st %g7, [%o0 + FC_GREG + OFF(7)] + + // do we need to handle fpu? + cmp %o3, 0 + bz Lno_fpu + nop + + add %o0, FC_FPU, %o5 + std %f0, [%o5] + std %f2, [%o5+0x08] + std %f4, [%o5+0x10] + std %f6, [%o5+0x18] + std %f8, [%o5+0x20] + std %f10, [%o5+0x28] + std %f12, [%o5+0x30] + std %f14, [%o5+0x38] + st %fsr, [%o0+FC_FSR] + + add %o1, FC_FPU, %o5 + ldd [%o5], %f0 + ldd [%o5+0x08], %f2 + ldd [%o5+0x10], %f4 + ldd [%o5+0x18], %f6 + ldd [%o5+0x20], %f8 + ldd [%o5+0x28], %f10 + ldd [%o5+0x30], %f12 + ldd [%o5+0x38], %f14 + ld [%o1+FC_FSR], %fsr + +Lno_fpu: + // load new state from %o1 + ld [%o1 + FC_GREG + OFF(1)], %o4 + ld [%o1 + FC_GREG + OFF(2)], %o7 + ld [%o1 + FC_GREG + OFF(3)], %g1 + ld [%o1 + FC_GREG + OFF(4)], %g2 + ld [%o1 + FC_GREG + OFF(5)], %g3 + ld [%o1 + FC_GREG + OFF(6)], %g6 + ld [%o1 + FC_GREG + OFF(7)], %g7 + // switch to new stack + ld [%o1 + FC_GREG + OFF(0)], %sp + // and now reload from this stack the shadow regist bank contents + ld [%sp + OFF(0)], %l0 + ld [%sp + OFF(1)], %l1 + ld [%sp + OFF(2)], %l2 + ld [%sp + OFF(3)], %l3 + ld [%sp + OFF(4)], %l4 + ld [%sp + OFF(5)], %l5 + ld [%sp + OFF(6)], %l6 + ld [%sp + OFF(7)], %l7 + ld [%sp + OFF(8)], %i0 + ld [%sp + OFF(9)], %i1 + ld [%sp + OFF(10)], %i2 + ld [%sp + OFF(11)], %i3 + ld [%sp + OFF(12)], %i4 + ld [%sp + OFF(13)], %i5 + ld [%sp + OFF(14)], %i6 + ld [%sp + OFF(15)], %i7 + + // finally continue execution in new context + jmp %o4 + mov %o2, %o0 // return arg as result + +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_gas.asm b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_gas.asm new file mode 100755 index 0000000..c4706ef --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_gas.asm @@ -0,0 +1,225 @@ +/* + Copyright Oliver Kowalke 2009. + Copyright Thomas Sailer 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- + * | 0 | 1 | | + * ---------------------------------------------------------------------------------- + * | 0x0 | 0x4 | | + * ---------------------------------------------------------------------------------- + * | <indicator> | | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | + * ---------------------------------------------------------------------------------- + * | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | + * ---------------------------------------------------------------------------------- + * | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | + * ---------------------------------------------------------------------------------- + * | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | + * ---------------------------------------------------------------------------------- + * | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | + * ---------------------------------------------------------------------------------- + * | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | + * ---------------------------------------------------------------------------------- + * | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 | + * ---------------------------------------------------------------------------------- + * | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | + * ---------------------------------------------------------------------------------- + * | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 | + * ---------------------------------------------------------------------------------- + * | limit | base | R12 | R13 | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | + * ---------------------------------------------------------------------------------- + * | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 | + * ---------------------------------------------------------------------------------- + * | R14 | R15 | RDI | RSI | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | + * ---------------------------------------------------------------------------------- + * | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | + * ---------------------------------------------------------------------------------- + * | RBX | RBP | RIP | EXIT | + * ---------------------------------------------------------------------------------- + * * + * *************************************************************************************/ + +.file "jump_x86_64_ms_pe_gas.asm" +.text +.p2align 4,,15 +.globl jump_fcontext +.def jump_fcontext; .scl 2; .type 32; .endef +.seh_proc jump_fcontext +jump_fcontext: +.seh_endprologue + + pushq %rbp /* save RBP */ + pushq %rbx /* save RBX */ + pushq %rsi /* save RSI */ + pushq %rdi /* save RDI */ + pushq %r15 /* save R15 */ + pushq %r14 /* save R14 */ + pushq %r13 /* save R13 */ + pushq %r12 /* save R12 */ + + /* load NT_TIB */ + movq %gs:(0x30), %r10 + /* save current stack base */ + movq 0x08(%r10), %rax + pushq %rax + /* save current stack limit */ + movq 0x10(%r10), %rax + pushq %rax + /* save current deallocation stack */ + movq 0x1478(%r10), %rax + pushq %rax + /* save fiber local storage */ + movq 0x18(%r10), %rax + pushq %rax + + /* prepare stack for FPU */ + leaq -0xa8(%rsp), %rsp + + /* test for flag preserve_fpu */ + testq %r9, %r9 + je 1f + + /* save MMX control- and status-word */ + stmxcsr 0xa0(%rsp) + /* save x87 control-word */ + fnstcw 0xa4(%rsp) + + /* save XMM storage */ + movaps %xmm6, (%rsp) + movaps %xmm7, 0x10(%rsp) + movaps %xmm8, 0x20(%rsp) + movaps %xmm9, 0x30(%rsp) + movaps %xmm10, 0x40(%rsp) + movaps %xmm11, 0x50(%rsp) + movaps %xmm12, 0x60(%rsp) + movaps %xmm13, 0x70(%rsp) + movaps %xmm14, 0x80(%rsp) + movaps %xmm15, 0x90(%rsp) + +1: + /* set R10 to zero */ + xorq %r10, %r10 + /* set indicator */ + pushq %r10 + + /* store RSP (pointing to context-data) in RCX */ + movq %rsp, (%rcx) + + /* restore RSP (pointing to context-data) from RDX */ + movq %rdx, %rsp + + /* load indicator */ + popq %r10 + + /* test for flag preserve_fpu */ + testq %r9, %r9 + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr 0xa0(%rsp) + /* save x87 control-word */ + fldcw 0xa4(%rsp) + + /* restore XMM storage */ + movaps (%rsp), %xmm6 + movaps 0x10(%rsp), %xmm7 + movaps 0x20(%rsp), %xmm8 + movaps 0x30(%rsp), %xmm9 + movaps 0x40(%rsp), %xmm10 + movaps 0x50(%rsp), %xmm11 + movaps 0x60(%rsp), %xmm12 + movaps 0x70(%rsp), %xmm13 + movaps 0x80(%rsp), %xmm14 + movaps 0x90(%rsp), %xmm15 + +2: + /* set offset of stack */ + movq 0xa8, %rcx + + /* test for indicator */ + testq %r10, %r10 + je 3f + + addq 0x8, %rcx + +3: + /* prepare stack for FPU */ + leaq (%rsp,%rcx), %rsp + + /* load NT_TIB */ + movq %gs:(0x30), %r10 + /* restore fiber local storage */ + popq %rax + movq %rax, 0x18(%r10) + /* restore deallocation stack */ + popq %rax + movq %rax, 0x1478(%r10) + /* restore stack limit */ + popq %rax + movq %rax, 0x10(%r10) + /* restore stack base */ + popq %rax + movq %rax, 0x8(%r10) + + popq %r12 /* restore R12 */ + popq %r13 /* restore R13 */ + popq %r14 /* restore R14 */ + popq %r15 /* restore R15 */ + popq %rdi /* restore RDI */ + popq %rsi /* restore RSI */ + popq %rbx /* restore RBX */ + popq %rbp /* restore RBP */ + + /* restore return-address */ + popq %r10 + + /* use third arg as return-value after jump */ + movq %r8, %rax + /* use third arg as first arg in context function */ + movq %r8, %rcx + + /* indirect jump to context */ + jmp *%r10 +.seh_endproc diff --git a/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_masm.asm b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_masm.asm new file mode 100755 index 0000000..6950ee7 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_ms_pe_masm.asm @@ -0,0 +1,216 @@ + +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +; ---------------------------------------------------------------------------------- +; | 0 | 1 | | +; ---------------------------------------------------------------------------------- +; | 0x0 | 0x4 | | +; ---------------------------------------------------------------------------------- +; | <indicator> | | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +; ---------------------------------------------------------------------------------- +; | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | +; ---------------------------------------------------------------------------------- +; | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | +; ---------------------------------------------------------------------------------- +; | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | +; ---------------------------------------------------------------------------------- +; | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | +; ---------------------------------------------------------------------------------- +; | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | +; ---------------------------------------------------------------------------------- +; | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 | +; ---------------------------------------------------------------------------------- +; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | +; ---------------------------------------------------------------------------------- +; | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 | +; ---------------------------------------------------------------------------------- +; | limit | base | R12 | R13 | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | +; ---------------------------------------------------------------------------------- +; | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 | +; ---------------------------------------------------------------------------------- +; | R14 | R15 | RDI | RSI | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | +; ---------------------------------------------------------------------------------- +; | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | +; ---------------------------------------------------------------------------------- +; | RBX | RBP | RIP | EXIT | +; ---------------------------------------------------------------------------------- + +.code + +jump_fcontext PROC BOOST_CONTEXT_EXPORT FRAME + .endprolog + + push rbp ; save RBP + push rbx ; save RBX + push rsi ; save RSI + push rdi ; save RDI + push r15 ; save R15 + push r14 ; save R14 + push r13 ; save R13 + push r12 ; save R12 + + ; load NT_TIB + mov r10, gs:[030h] + ; save current stack base + mov rax, [r10+08h] + push rax + ; save current stack limit + mov rax, [r10+010h] + push rax + ; save current deallocation stack + mov rax, [r10+01478h] + push rax + ; save fiber local storage + mov rax, [r10+018h] + push rax + + ; prepare stack for FPU + lea rsp, [rsp-0a8h] + + ; test for flag preserve_fpu + test r9, r9 + je nxt1 + + ; save MMX control- and status-word + stmxcsr [rsp+0a0h] + ; save x87 control-word + fnstcw [rsp+0a4h] + + ; save XMM storage + movaps [rsp], xmm6 + movaps [rsp+010h], xmm7 + movaps [rsp+020h], xmm8 + movaps [rsp+030h], xmm9 + movaps [rsp+040h], xmm10 + movaps [rsp+050h], xmm11 + movaps [rsp+060h], xmm12 + movaps [rsp+070h], xmm13 + movaps [rsp+080h], xmm14 + movaps [rsp+090h], xmm15 + +nxt1: + ; set R10 to zero + xor r10, r10 + ; set indicator + push r10 + + ; store RSP (pointing to context-data) in RCX + mov [rcx], rsp + + ; restore RSP (pointing to context-data) from RDX + mov rsp, rdx + + ; load indicator + pop r10 + + ; test for flag preserve_fpu + test r9, r9 + je nxt2 + + ; restore MMX control- and status-word + ldmxcsr [rsp+0a0h] + ; save x87 control-word + fldcw [rsp+0a4h] + + ; restore XMM storage + movaps xmm6, [rsp] + movaps xmm7, [rsp+010h] + movaps xmm8, [rsp+020h] + movaps xmm9, [rsp+030h] + movaps xmm10, [rsp+040h] + movaps xmm11, [rsp+050h] + movaps xmm12, [rsp+060h] + movaps xmm13, [rsp+070h] + movaps xmm14, [rsp+080h] + movaps xmm15, [rsp+090h] + +nxt2: + ; set offset of stack + mov rcx, 0a8h + + ; test for indicator + test r10, r10 + je nxt3 + + add rcx, 08h + +nxt3: + ; prepare stack for FPU + lea rsp, [rsp+rcx] + + ; load NT_TIB + mov r10, gs:[030h] + ; restore fiber local storage + pop rax + mov [r10+018h], rax + ; restore deallocation stack + pop rax + mov [r10+01478h], rax + ; restore stack limit + pop rax + mov [r10+010h], rax + ; restore stack base + pop rax + mov [r10+08h], rax + + pop r12 ; restore R12 + pop r13 ; restore R13 + pop r14 ; restore R14 + pop r15 ; restore R15 + pop rdi ; restore RDI + pop rsi ; restore RSI + pop rbx ; restore RBX + pop rbp ; restore RBP + + ; restore return-address + pop r10 + + ; use third arg as return-value after jump + mov rax, r8 + ; use third arg as first arg in context function + mov rcx, r8 + + ; indirect jump to context + jmp r10 +jump_fcontext ENDP +END diff --git a/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_elf_gas.S new file mode 100755 index 0000000..ac55531 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_elf_gas.S @@ -0,0 +1,98 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | EXIT | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl jump_fcontext +.type jump_fcontext,@function +.align 16 +jump_fcontext: + pushq %rbp /* save RBP */ + pushq %rbx /* save RBX */ + pushq %r15 /* save R15 */ + pushq %r14 /* save R14 */ + pushq %r13 /* save R13 */ + pushq %r12 /* save R12 */ + + /* prepare stack for FPU */ + leaq -0x8(%rsp), %rsp + + /* test for flag preserve_fpu */ + cmp $0, %rcx + je 1f + + /* save MMX control- and status-word */ + stmxcsr (%rsp) + /* save x87 control-word */ + fnstcw 0x4(%rsp) + +1: + /* store RSP (pointing to context-data) in RDI */ + movq %rsp, (%rdi) + + /* restore RSP (pointing to context-data) from RSI */ + movq %rsi, %rsp + + /* test for flag preserve_fpu */ + cmp $0, %rcx + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr (%rsp) + /* restore x87 control-word */ + fldcw 0x4(%rsp) + +2: + /* prepare stack for FPU */ + leaq 0x8(%rsp), %rsp + + popq %r12 /* restrore R12 */ + popq %r13 /* restrore R13 */ + popq %r14 /* restrore R14 */ + popq %r15 /* restrore R15 */ + popq %rbx /* restrore RBX */ + popq %rbp /* restrore RBP */ + + /* restore return-address */ + popq %r8 + + /* use third arg as return-value after jump */ + movq %rdx, %rax + /* use third arg as first arg in context function */ + movq %rdx, %rdi + + /* indirect jump to context */ + jmp *%r8 +.size jump_fcontext,.-jump_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_macho_gas.S new file mode 100755 index 0000000..50563c3 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/jump_x86_64_sysv_macho_gas.S @@ -0,0 +1,93 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | EXIT | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl _jump_fcontext +.align 8 +_jump_fcontext: + pushq %rbp /* save RBP */ + pushq %rbx /* save RBX */ + pushq %r15 /* save R15 */ + pushq %r14 /* save R14 */ + pushq %r13 /* save R13 */ + pushq %r12 /* save R12 */ + + /* prepare stack for FPU */ + leaq -0x8(%rsp), %rsp + + /* test for flag preserve_fpu */ + cmp $0, %rcx + je 1f + + /* save MMX control- and status-word */ + stmxcsr (%rsp) + /* save x87 control-word */ + fnstcw 0x4(%rsp) + +1: + /* store RSP (pointing to context-data) in RDI */ + movq %rsp, (%rdi) + + /* restore RSP (pointing to context-data) from RSI */ + movq %rsi, %rsp + + /* test for flag preserve_fpu */ + cmp $0, %rcx + je 2f + + /* restore MMX control- and status-word */ + ldmxcsr (%rsp) + /* restore x87 control-word */ + fldcw 0x4(%rsp) + +2: + /* prepare stack for FPU */ + leaq 0x8(%rsp), %rsp + + popq %r12 /* restrore R12 */ + popq %r13 /* restrore R13 */ + popq %r14 /* restrore R14 */ + popq %r15 /* restrore R15 */ + popq %rbx /* restrore RBX */ + popq %rbp /* restrore RBP */ + + /* restore return-address */ + popq %r8 + + /* use third arg as return-value after jump */ + movq %rdx, %rax + /* use third arg as first arg in context function */ + movq %rdx, %rdi + + /* indirect jump to context */ + jmp *%r8 diff --git a/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_elf_gas.S new file mode 100755 index 0000000..b208ab7 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_elf_gas.S @@ -0,0 +1,85 @@ +/* + Copyright Edward Nevill 2015 + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.cpu generic+fp+simd +.text +.align 2 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + # shift address in x0 (allocated stack) to lower 16 byte boundary + and x0, x0, ~0xF + + # reserve space for context-data on context-stack + sub x0, x0, #0xb0 + + # third arg of make_fcontext() == address of context-function + # store address as a PC to jump in + str x2, [x0, #0xa0] + + # save address of finish as return-address for context-function + # will be entered after context-function returns (LR register) + adr x1, finish + str x1, [x0, #0x98] + + ret x30 // return pointer to context-data (x0) + +finish: + # exit code is zero + mov x0, #0 + # exit application + bl _exit + +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_macho_gas.S new file mode 100755 index 0000000..6b55a08 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_arm64_aapcs_macho_gas.S @@ -0,0 +1,83 @@ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | d8 | d9 | d10 | d11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | d12 | d13 | d14 | d15 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | x19 | x20 | x21 | x22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | x23 | x24 | x25 | x26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | x27 | x28 | FP | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | | | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| | | * + * ------------------------------------------------- * + * | PC | align | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + + +.text +.globl _make_fcontext +.balign 16 + +_make_fcontext: + ; shift address in x0 (allocated stack) to lower 16 byte boundary + and x0, x0, ~0xF + + ; reserve space for context-data on context-stack + sub x0, x0, #0xb0 + + ; third arg of make_fcontext() == address of context-function + ; store address as a PC to jump in + str x2, [x0, #0xa0] + + ; compute abs address of label finish + ; 0x0c = 3 instructions * size (4) before label 'finish' + + ; TODO: Numeric offset since llvm still does not support labels in ADR. Fix: + ; http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140407/212336.html + adr x1, 0x0c + + ; save address of finish as return-address for context-function + ; will be entered after context-function returns (LR register) + str x1, [x0, #0x98] + + ret lr ; return pointer to context-data (x0) + +finish: + ; exit code is zero + mov x0, #0 + ; exit application + bl __exit + + diff --git a/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_elf_gas.S new file mode 100755 index 0000000..9877655 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_elf_gas.S @@ -0,0 +1,71 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | | * + * ------------------------------------------------- * + * | 0x60| 0x64| | * + * ------------------------------------------------- * + * | lr | pc | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,%function +make_fcontext: + @ shift address in A1 to lower 16 byte boundary + bic a1, a1, #15 + + @ reserve space for context-data on context-stack + sub a1, a1, #104 + + @ third arg of make_fcontext() == address of context-function + str a3, [a1,#100] + + @ compute abs address of label finish + adr a2, finish + @ save address of finish as return-address for context-function + @ will be entered after context-function returns + str a2, [a1,#96] + + bx lr @ return pointer to context-data + +finish: + @ exit code is zero + mov a1, #0 + @ exit application + bl _exit@PLT +.size make_fcontext,.-make_fcontext + +@ Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_macho_gas.S new file mode 100755 index 0000000..039726f --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_macho_gas.S @@ -0,0 +1,66 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | sjlj| v1 | v2 | v3 | v4 | v5 | v6 | v7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| | * + * ------------------------------------------------- * + * | v8 | lr | pc | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl _make_fcontext +.align 2 +_make_fcontext: + @ shift address in A1 to lower 16 byte boundary + bic a1, a1, #15 + + @ reserve space for context-data on context-stack + sub a1, a1, #108 + + @ third arg of make_fcontext() == address of context-function + str a3, [a1,#104] + + @ compute abs address of label finish + adr a2, finish + @ save address of finish as return-address for context-function + @ will be entered after context-function returns + str a2, [a1,#100] + + bx lr @ return pointer to context-data + +finish: + @ exit code is zero + mov a1, #0 + @ exit application + bl __exit diff --git a/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_pe_armasm.asm b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_pe_armasm.asm new file mode 100755 index 0000000..5c3d6df --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_arm_aapcs_pe_armasm.asm @@ -0,0 +1,86 @@ +;/* +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) +;*/ + +; ******************************************************* +; * * +; * ------------------------------------------------- * +; * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * +; * ------------------------------------------------- * +; * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * +; * ------------------------------------------------- * +; * | s16 | s17 | s18 | s19 | s20 | s21 | s22 | s23 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * +; * ------------------------------------------------- * +; * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * +; * ------------------------------------------------- * +; * | s24 | s25 | s26 | s27 | s28 | s29 | s30 | s31 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * +; * ------------------------------------------------- * +; * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * +; * ------------------------------------------------- * +; * |deall|limit| base| v1 | v2 | v3 | v4 | v5 | * +; * ------------------------------------------------- * +; * ------------------------------------------------- * +; * | 24 | 25 | 26 | 27 | 28 | | * +; * ------------------------------------------------- * +; * | 0x60| 0x64| 0x68| 0x6c| 0x70| | * +; * ------------------------------------------------- * +; * | v6 | v7 | v8 | lr | pc | | * +; * ------------------------------------------------- * +; * * +; ******************************************************* + + + AREA |.text|, CODE + ALIGN 4 + EXPORT make_fcontext + IMPORT _exit + +make_fcontext PROC + ; first arg of make_fcontext() == top of context-stack + ; save top of context-stack (base) A4 + mov a4, a1 + + ; shift address in A1 to lower 16 byte boundary + bic a1, a1, #0x0f + + ; reserve space for context-data on context-stack + sub a1, a1, #0x74 + + ; save top address of context_stack as 'base' + str a4, [a1,#0x48] + ; second arg of make_fcontext() == size of context-stack + ; compute bottom address of context-stack (limit) + sub a4, a4, a2 + ; save bottom address of context-stack as 'limit' + str a4, [a1,#0x44] + ; save bottom address of context-stack as 'dealloction stack' + str a4, [a1,#0x40] + + ; third arg of make_fcontext() == address of context-function + str a3, [a1,#0x70] + + ; compute abs address of label finish + adr a2, finish + ; save address of finish as return-address for context-function + ; will be entered after context-function returns + str a2, [a1,#0x6c] + + bx lr ; return pointer to context-data + +finish + ; exit code is zero + mov a1, #0 + ; exit application + bl _exit + + ENDP + END diff --git a/vendor/swoole/thirdparty/boost/asm/make_combined_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_combined_sysv_macho_gas.S new file mode 100755 index 0000000..727e904 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_combined_sysv_macho_gas.S @@ -0,0 +1,20 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__i386__) + #include "make_i386_sysv_macho_gas.S" +#elif defined(__x86_64__) + #include "make_x86_64_sysv_macho_gas.S" +#elif defined(__ppc__) + #include "make_ppc32_sysv_macho_gas.S" +#elif defined(__ppc64__) + #include "make_ppc64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_gas.asm b/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_gas.asm new file mode 100755 index 0000000..881b3c8 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_gas.asm @@ -0,0 +1,124 @@ +/* + Copyright Oliver Kowalke 2009. + Copyright Thomas Sailer 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************** + --------------------------------------------------------------------------------- + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + --------------------------------------------------------------------------------- + | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | + --------------------------------------------------------------------------------- + | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | + --------------------------------------------------------------------------------- + --------------------------------------------------------------------------------- + | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | + --------------------------------------------------------------------------------- + | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | + --------------------------------------------------------------------------------- + | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR| + --------------------------------------------------------------------------------- +*******************************************************************/ + +.file "make_i386_ms_pe_gas.asm" +.text +.p2align 4,,15 +.globl _make_fcontext +.def _make_fcontext; .scl 2; .type 32; .endef +_make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movl 0x04(%esp), %eax + + /* reserve space for first argument of context-function */ + /* EAX might already point to a 16byte border */ + leal -0x08(%eax), %eax + + /* shift address in EAX to lower 16 byte boundary */ + andl $-16, %eax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. EIP + return-address for context-function */ + /* on context-function entry: (ESP -0x4) % 8 == 0 */ + /* additional space is required for SEH */ + leal -0x3c(%eax), %eax + + /* first arg of make_fcontext() == top of context-stack */ + movl 0x04(%esp), %ecx + /* save top address of context stack as 'base' */ + movl %ecx, 0x14(%eax) + /* second arg of make_fcontext() == size of context-stack */ + movl 0x08(%esp), %edx + /* negate stack size for LEA instruction (== substraction) */ + negl %edx + /* compute bottom address of context stack (limit) */ + leal (%ecx,%edx), %ecx + /* save bottom address of context-stack as 'limit' */ + movl %ecx, 0x10(%eax) + /* save bottom address of context-stack as 'dealloction stack' */ + movl %ecx, 0xc(%eax) + + /* third arg of make_fcontext() == address of context-function */ + movl 0xc(%esp), %ecx + movl %ecx, 0x2c(%eax) + + /* save MMX control- and status-word */ + stmxcsr (%eax) + /* save x87 control-word */ + fnstcw 0x04(%eax) + + /* compute abs address of label finish */ + movl $finish, %ecx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movl %ecx, 0x30(%eax) + + /* traverse current seh chain to get the last exception handler installed by Windows */ + /* note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default */ + /* the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler */ + /* at its end by RaiseException all seh andlers are disregarded if not present and the */ + /* program is aborted */ + /* load NT_TIB into ECX */ + movl %fs:(0x0), %ecx + +walk: + /* load 'next' member of current SEH into EDX */ + movl (%ecx), %edx + /* test if 'next' of current SEH is last (== 0xffffffff) */ + incl %edx + jz found + decl %edx + /* exchange content; ECX contains address of next SEH */ + xchgl %ecx, %edx + /* inspect next SEH */ + jmp walk + +found: + /* load 'handler' member of SEH == address of last SEH handler installed by Windows */ + movl 0x04(%ecx), %ecx + /* save address in ECX as SEH handler for context */ + movl %ecx, 0x3c(%eax) + /* set ECX to -1 */ + movl $0xffffffff, %ecx + /* save ECX as next SEH item */ + movl %ecx, 0x38(%eax) + /* load address of next SEH item */ + leal 0x38(%eax), %ecx + /* save next SEH */ + movl %ecx, 0x18(%eax) + + /* return pointer to context-data */ + ret + +finish: + /* ESP points to same address as ESP on entry of context function + 0x4 */ + xorl %eax, %eax + /* exit code is zero */ + movl %eax, (%esp) + /* exit application */ + call __exit + hlt + +.def __exit; .scl 2; .type 32; .endef /* standard C library function */ diff --git a/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_masm.asm b/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_masm.asm new file mode 100755 index 0000000..35c8b1c --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_i386_ms_pe_masm.asm @@ -0,0 +1,122 @@ + +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +; --------------------------------------------------------------------------------- +; | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | +; --------------------------------------------------------------------------------- +; | 0h | 04h | 08h | 0ch | 010h | 014h | 018h | 01ch | +; --------------------------------------------------------------------------------- +; | fc_mxcsr|fc_x87_cw| fc_strg |fc_deallo| limit | base | fc_seh | EDI | +; --------------------------------------------------------------------------------- +; --------------------------------------------------------------------------------- +; | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | +; --------------------------------------------------------------------------------- +; | 020h | 024h | 028h | 02ch | 030h | 034h | 038h | 03ch | +; --------------------------------------------------------------------------------- +; | ESI | EBX | EBP | EIP | EXIT | | SEH NXT |SEH HNDLR| +; --------------------------------------------------------------------------------- + +.386 +.XMM +.model flat, c +; standard C library function +_exit PROTO, value:SDWORD +.code + +make_fcontext PROC BOOST_CONTEXT_EXPORT + ; first arg of make_fcontext() == top of context-stack + mov eax, [esp+04h] + + ; reserve space for first argument of context-function + ; EAX might already point to a 16byte border + lea eax, [eax-08h] + + ; shift address in EAX to lower 16 byte boundary + and eax, -16 + + ; reserve space for context-data on context-stack + ; size for fc_mxcsr .. EIP + return-address for context-function + ; on context-function entry: (ESP -0x4) % 8 == 0 + ; additional space is required for SEH + lea eax, [eax-03ch] + + ; first arg of make_fcontext() == top of context-stack + mov ecx, [esp+04h] + ; save top address of context stack as 'base' + mov [eax+014h], ecx + ; second arg of make_fcontext() == size of context-stack + mov edx, [esp+08h] + ; negate stack size for LEA instruction (== substraction) + neg edx + ; compute bottom address of context stack (limit) + lea ecx, [ecx+edx] + ; save bottom address of context-stack as 'limit' + mov [eax+010h], ecx + ; save bottom address of context-stack as 'dealloction stack' + mov [eax+0ch], ecx + + ; third arg of make_fcontext() == address of context-function + mov ecx, [esp+0ch] + mov [eax+02ch], ecx + + ; save MMX control- and status-word + stmxcsr [eax] + ; save x87 control-word + fnstcw [eax+04h] + + ; compute abs address of label finish + mov ecx, finish + ; save address of finish as return-address for context-function + ; will be entered after context-function returns + mov [eax+030h], ecx + + ; traverse current seh chain to get the last exception handler installed by Windows + ; note that on Windows Server 2008 and 2008 R2, SEHOP is activated by default + ; the exception handler chain is tested for the presence of ntdll.dll!FinalExceptionHandler + ; at its end by RaiseException all seh-handlers are disregarded if not present and the + ; program is aborted + assume fs:nothing + ; load NT_TIB into ECX + mov ecx, fs:[0h] + assume fs:error + +walk: + ; load 'next' member of current SEH into EDX + mov edx, [ecx] + ; test if 'next' of current SEH is last (== 0xffffffff) + inc edx + jz found + dec edx + ; exchange content; ECX contains address of next SEH + xchg edx, ecx + ; inspect next SEH + jmp walk + +found: + ; load 'handler' member of SEH == address of last SEH handler installed by Windows + mov ecx, [ecx+04h] + ; save address in ECX as SEH handler for context + mov [eax+03ch], ecx + ; set ECX to -1 + mov ecx, 0ffffffffh + ; save ECX as next SEH item + mov [eax+038h], ecx + ; load address of next SEH item + lea ecx, [eax+038h] + ; save next SEH + mov [eax+018h], ecx + + ret ; return pointer to context-data + +finish: + ; exit code is zero + xor eax, eax + mov [esp], eax + ; exit application + call _exit + hlt +make_fcontext ENDP +END diff --git a/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_elf_gas.S new file mode 100755 index 0000000..26c9451 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_elf_gas.S @@ -0,0 +1,77 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,@function +make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movl 0x4(%esp), %eax + + /* reserve space for first argument of context-function + rax might already point to a 16byte border */ + leal -0x8(%eax), %eax + + /* shift address in EAX to lower 16 byte boundary */ + andl $-16, %eax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. EIP + return-address for context-function */ + /* on context-function entry: (ESP -0x4) % 8 == 0 */ + leal -0x20(%eax), %eax + + /* third arg of make_fcontext() == address of context-function */ + movl 0xc(%esp), %edx + movl %edx, 0x18(%eax) + + /* save MMX control- and status-word */ + stmxcsr (%eax) + /* save x87 control-word */ + fnstcw 0x4(%eax) + + /* compute abs address of label finish */ + call 1f + /* address of label 1 */ +1: popl %ecx + /* compute abs address of label finish */ + addl $finish-1b, %ecx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movl %ecx, 0x1c(%eax) + + ret /* return pointer to context-data */ + +finish: + call 2f + /* address of label 2 */ +2: popl %ebx + /* compute address of GOT and store it in EBX */ + addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx + + /* exit code is zero */ + xorl %eax, %eax + movl %eax, (%esp) + /* exit application */ + call _exit@PLT + hlt +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_macho_gas.S new file mode 100755 index 0000000..02ae223 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_i386_sysv_macho_gas.S @@ -0,0 +1,66 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| EDI | ESI | EBX | EBP | EIP | EXIT | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl _make_fcontext +.align 2 +_make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movl 0x4(%esp), %eax + + /* reserve space for first argument of context-function + rax might already point to a 16byte border */ + leal -0x8(%eax), %eax + + /* shift address in EAX to lower 16 byte boundary */ + andl $-16, %eax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. EIP + return-address for context-function */ + /* on context-function entry: (ESP -0x4) % 8 == 0 */ + leal -0x20(%eax), %eax + + /* thrid arg of make_fcontext() == address of context-function */ + movl 0xc(%esp), %edx + movl %edx, 0x18(%eax) + + /* save MMX control- and status-word */ + stmxcsr (%eax) + /* save x87 control-word */ + fnstcw 0x4(%eax) + + /* compute abs address of label finish */ + call 1f + /* address of label 1 */ +1: popl %ecx + /* compute abs address of label finish */ + addl $finish-1b, %ecx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movl %ecx, 0x1c(%eax) + + ret /* return pointer to context-data */ + +finish: + /* exit code is zero */ + xorl %eax, %eax + movl %eax, (%esp) + /* exit application */ + call __exit + hlt diff --git a/vendor/swoole/thirdparty/boost/asm/make_i386_x86_64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_i386_x86_64_sysv_macho_gas.S new file mode 100755 index 0000000..e364b2d --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_i386_x86_64_sysv_macho_gas.S @@ -0,0 +1,16 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__i386__) + #include "make_i386_sysv_macho_gas.S" +#elif defined(__x86_64__) + #include "make_x86_64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/make_mips32_o32_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_mips32_o32_elf_gas.S new file mode 100755 index 0000000..c71ad05 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_mips32_o32_elf_gas.S @@ -0,0 +1,89 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F20 | F22 | F24 | F26 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F28 | F30 | S0 | S1 | S2 | S3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | | * + * ------------------------------------------------- * + * | S4 | S5 | S6 | S7 | FP | RA | PC | | * + * ------------------------------------------------- * + * * + * *****************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,@function +.ent make_fcontext +make_fcontext: +#ifdef __PIC__ +.set noreorder +.cpload $t9 +.set reorder +#endif + # first arg of make_fcontext() == top address of context-stack + move $v0, $a0 + + # shift address in A0 to lower 16 byte boundary + move $v1, $v0 + li $v0, -16 # 0xfffffffffffffff0 + and $v0, $v1, $v0 + + # reserve space for context-data on context-stack + # including 48 byte of shadow space (sp % 16 == 0) + addiu $v0, $v0, -140 + + # third arg of make_fcontext() == address of context-function + sw $a2, 88($v0) + # save global pointer in context-data + # S0 will contain address of global pointer + sw $gp, 48($v0) + + # compute abs address of label finish + la $t9, finish + # save address of finish as return-address for context-function + # will be entered after context-function returns + sw $t9, 84($v0) + + jr $ra # return pointer to context-data + +finish: + # allocate stack space (contains shadow space for subroutines) + addiu $sp, $sp, -32 + # save return address + sw $ra, 28($sp) + + # restore GP (global pointer) + move $gp, $s0 + # exit code is zero + move $a0, $zero + # address of exit + lw $t9, %call16(_exit)($gp) + # exit application + jalr $t9 +.end make_fcontext +.size make_fcontext, .-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc32_ppc64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc32_ppc64_sysv_macho_gas.S new file mode 100755 index 0000000..52e7220 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc32_ppc64_sysv_macho_gas.S @@ -0,0 +1,16 @@ +/* + Copyright Sergue E. Leontiev 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Stub file for universal binary + +#if defined(__ppc__) + #include "make_ppc32_sysv_macho_gas.S" +#elif defined(__ppc64__) + #include "make_ppc64_sysv_macho_gas.S" +#else + #error "No arch's" +#endif diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_elf_gas.S new file mode 100755 index 0000000..30ce473 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_elf_gas.S @@ -0,0 +1,123 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | R14 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | | * + * ------------------------------------------------- * + * | R31 | CR | LR | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl make_fcontext +.align 2 +.type make_fcontext,@function +make_fcontext: + # save return address into R6 + mflr %r6 + + # first arg of make_fcontext() == top address of context-function + # shift address in R3 to lower 16 byte boundary + clrrwi %r3, %r3, 4 + + # reserve space for context-data on context-stack + # including 64 byte of linkage + parameter area (R1 % 16 == 0) + subi %r3, %r3, 304 + + # third arg of make_fcontext() == address of context-function + stw %r5, 236(%r3) + + # load LR + mflr %r0 + # jump to label 1 + bl 1f +1: + # load LR into R4 + mflr %r4 + # compute abs address of label finish + addi %r4, %r4, finish - 1b + # restore LR + mtlr %r0 + # save address of finish as return-address for context-function + # will be entered after context-function returns + stw %r4, 232(%r3) + + # restore return address from R6 + mtlr %r6 + + blr # return pointer to context-data + +finish: + # save return address into R0 + mflr %r0 + # save return address on stack, set up stack frame + stw %r0, 4(%r1) + # allocate stack space, R1 % 16 == 0 + stwu %r1, -16(%r1) + + # exit code is zero + li %r3, 0 + # exit application + bl _exit@plt +.size make_fcontext, .-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_macho_gas.S new file mode 100755 index 0000000..f99b883 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_macho_gas.S @@ -0,0 +1,118 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | R14 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R15 | R16 | R17 | R18 | R19 | R20 | R21 | R22 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R23 | R24 | R25 | R26 | R27 | R28 | R29 | R30 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | | * + * ------------------------------------------------- * + * | R31 | CR | LR | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl _make_fcontext +.align 2 +_make_fcontext: + ; save return address into R6 + mflr r6 + + ; first arg of make_fcontext() == top address of context-function + ; shift address in R3 to lower 16 byte boundary + clrrwi r3, r3, 4 + + ; reserve space for context-data on context-stack + ; including 64 byte of linkage + parameter area (R1 % 16 == 0) + subi r3, r3, 304 + + ; third arg of make_fcontext() == address of context-function + stw r5, 236(r3) + + ; load LR + mflr r0 + ; jump to label 1 + bl l1 +l1: + ; load LR into R4 + mflr r4 + ; compute abs address of label finish + addi r4, r4, lo16((finish - .)+4) + # restore LR + mtlr r0 + ; save address of finish as return-address for context-function + ; will be entered after context-function returns + stw r4, 232(r3) + + ; restore return address from R6 + mtlr r6 + + blr ; return pointer to context-data + +finish: + ; save return address into R0 + mflr r0 + ; save return address on stack, set up stack frame + stw r0, 4(r1) + ; allocate stack space, R1 % 16 == 0 + stwu r1, -16(r1) + + ; exit code is zero + li r3, 0 + ; exit application + bl __exit diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_xcoff_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_xcoff_gas.S new file mode 100755 index 0000000..5298d49 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc32_sysv_xcoff_gas.S @@ -0,0 +1,55 @@ + .globl make_fcontext[DS] + .globl .make_fcontext[PR] + .align 2 + .csect make_fcontext[DS] +make_fcontext: + .long .make_fcontext[PR] + .csect .make_fcontext[PR], 3 +#.make_fcontext: + # save return address into R6 + mflr 6 + + # first arg of make_fcontext() == top address of context-function + # shift address in R3 to lower 16 byte boundary + clrrwi 3, 3, 4 + + # reserve space for context-data on context-stack + # including 64 byte of linkage + parameter area (R1 % 16 == 0) + subi 3, 3, 304 + + # third arg of make_fcontext() == address of context-function + stw 5, 236(3) + + # load LR + mflr 0 + # jump to label 1 + bl .Label +.Label: + # load LR into R4 + mflr 4 + # compute abs address of label .L_finish + addi 4, 4, .L_finish - .Label + # restore LR + mtlr 0 + # save address of finish as return-address for context-function + # will be entered after context-function returns + stw 4, 232(3) + + # restore return address from R6 + mtlr 6 + + blr # return pointer to context-data + +.L_finish: + # save return address into R0 + mflr 0 + # save return address on stack, set up stack frame + stw 0, 4(1) + # allocate stack space, R1 % 16 == 0 + stwu 1, -16(1) + + # exit code is zero + li 3, 0 + # exit application + bl ._exit + nop diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_elf_gas.S new file mode 100755 index 0000000..b777fe6 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_elf_gas.S @@ -0,0 +1,189 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | TOC | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R14 | R15 | R16 | R17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R18 | R19 | R20 | R21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * + * ------------------------------------------------- * + * | R22 | R23 | R24 | R25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * + * ------------------------------------------------- * + * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * + * ------------------------------------------------- * + * | R26 | R27 | R28 | R29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * + * ------------------------------------------------- * + * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | R30 | R31 | CR | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 80 | 81 | | * + * ------------------------------------------------- * + * | 320 | 324 | | * + * ------------------------------------------------- * + * | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.globl make_fcontext +#if _CALL_ELF == 2 + .text + .align 2 +make_fcontext: + addis %r2, %r12, .TOC.-make_fcontext@ha + addi %r2, %r2, .TOC.-make_fcontext@l + .localentry make_fcontext, . - make_fcontext +#else + .section ".opd","aw" + .align 3 +make_fcontext: +# ifdef _CALL_LINUX + .quad .L.make_fcontext,.TOC.@tocbase,0 + .type make_fcontext,@function + .text + .align 2 +.L.make_fcontext: +# else + .hidden .make_fcontext + .globl .make_fcontext + .quad .make_fcontext,.TOC.@tocbase,0 + .size make_fcontext,24 + .type .make_fcontext,@function + .text + .align 2 +.make_fcontext: +# endif +#endif + # save return address into R6 + mflr %r6 + + # first arg of make_fcontext() == top address of context-stack + # shift address in R3 to lower 16 byte boundary + clrrdi %r3, %r3, 4 + + # reserve space for context-data on context-stack + # including 64 byte of linkage + parameter area (R1 % 16 == 0) + subi %r3, %r3, 392 + + # third arg of make_fcontext() == address of context-function + # entry point (ELFv2) or descriptor (ELFv1) +#if _CALL_ELF == 2 + # save address of context-function entry point + std %r5, 320(%r3) +#else + # save address of context-function entry point + ld %r4, 0(%r5) + std %r4, 320(%r3) + # save TOC of context-function + ld %r4, 8(%r5) + std %r4, 152(%r3) +#endif + + # load LR + mflr %r0 + # jump to label 1 + bl 1f +1: + # load LR into R4 + mflr %r4 + # compute abs address of label finish + addi %r4, %r4, finish - 1b + # restore LR + mtlr %r0 + # save address of finish as return-address for context-function + # will be entered after context-function returns + std %r4, 312(%r3) + + # restore return address from R6 + mtlr %r6 + + blr # return pointer to context-data + +finish: + # save return address into R0 + mflr %r0 + # save return address on stack, set up stack frame + std %r0, 8(%r1) + # allocate stack space, R1 % 16 == 0 + stdu %r1, -32(%r1) + + # exit code is zero + li %r3, 0 + # exit application + bl _exit + nop +#if _CALL_ELF == 2 + .size make_fcontext, .-make_fcontext +#else +# ifdef _CALL_LINUX + .size .make_fcontext, .-.L.make_fcontext +# else + .size .make_fcontext, .-.make_fcontext +# endif +#endif + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_macho_gas.S new file mode 100755 index 0000000..c4208c5 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_macho_gas.S @@ -0,0 +1,140 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 | * + * ------------------------------------------------- * + * | F14 | F15 | F16 | F17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | * + * ------------------------------------------------- * + * | F18 | F19 | F20 | F21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 64 | 68 | 72 | 76 | 80 | 84 | 88 | 92 | * + * ------------------------------------------------- * + * | F22 | F23 | F24 | F25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | * + * ------------------------------------------------- * + * | F26 | F27 | F28 | F29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | * + * ------------------------------------------------- * + * | F30 | F31 | fpscr | R13 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 160 | 164 | 168 | 172 | 176 | 180 | 184 | 188 | * + * ------------------------------------------------- * + * | R14 | R15 | R16 | R17 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * + * ------------------------------------------------- * + * | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * + * ------------------------------------------------- * + * | R18 | R19 | R20 | R21 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | * + * ------------------------------------------------- * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | * + * ------------------------------------------------- * + * | R22 | R23 | R24 | R25 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | * + * ------------------------------------------------- * + * | 256 | 260 | 264 | 268 | 272 | 276 | 280 | 284 | * + * ------------------------------------------------- * + * | R26 | R27 | R28 | R29 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | * + * ------------------------------------------------- * + * | 288 | 292 | 296 | 300 | 304 | 308 | 312 | 316 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | R30 | R31 | CR | LR | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 80 | 81 | | * + * ------------------------------------------------- * + * | 320 | 324 | | * + * ------------------------------------------------- * + * | PC | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.text +.globl _make_fcontext +_make_fcontext: + ; save return address into R6 + mflr r6 + + ; first arg of make_fcontext() == top address of context-function + ; shift address in R3 to lower 16 byte boundary + clrrwi r3, r3, 4 + + ; reserve space for context-data on context-stack + ; including 64 byte of linkage + parameter area (R1 16 == 0) + subi r3, r3, 392 + + ; third arg of make_fcontext() == address of context-function + stw r5, 320(r3) + + ; load LR + mflr r0 + ; jump to label 1 + bl l1 +l1: + ; load LR into R4 + mflr r4 + ; compute abs address of label finish + addi r4, r4, lo16((finish - .) + 4) + ; restore LR + mtlr r0 + ; save address of finish as return-address for context-function + ; will be entered after context-function returns + std r4, 312(r3) + + ; restore return address from R6 + mtlr r6 + + blr ; return pointer to context-data + +finish: + ; save return address into R0 + mflr r0 + ; save return address on stack, set up stack frame + stw r0, 8(r1) + ; allocate stack space, R1 16 == 0 + stwu r1, -32(r1) + + ; set return value to zero + li r3, 0 + ; exit application + bl __exit + nop diff --git a/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_xcoff_gas.S b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_xcoff_gas.S new file mode 100755 index 0000000..8de630c --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_ppc64_sysv_xcoff_gas.S @@ -0,0 +1,53 @@ + .globl make_fcontext[DS] + .globl .make_fcontext[PR] + .align 2 + .csect .make_fcontext[PR], 3 + .globl _make_fcontext +#._make_fcontext: + # save return address into R6 + mflr 6 + + # first arg of make_fcontext() == top address of context-function + # shift address in R3 to lower 16 byte boundary + clrrwi 3, 3, 4 + + # reserve space for context-data on context-stack + # including 64 byte of linkage + parameter area (R1 % 16 == 0) + subi 3, 3, 392 + + # third arg of make_fcontext() == address of context-function + stw 5, 320(3) + + # load LR + mflr 0 + # jump to label 1 + bl .Label +.Label: + # load LR into R4 + mflr 4 + # compute abs address of label .L_finish + addi 4, 4, .L_finish - .Label + # restore LR + mtlr 0 + # save address of finish as return-address for context-function + # will be entered after context-function returns + stw 4, 312(3) + + # restore return address from R6 + mtlr 6 + + blr # return pointer to context-data + +.L_finish: + # save return address into R0 + mflr 0 + # save return address on stack, set up stack frame + stw 0, 8(1) + # allocate stack space, R1 % 16 == 0 + stwu 1, -32(1) + + # exit code is zero + li 3, 0 + # exit application + bl ._exit + nop diff --git a/vendor/swoole/thirdparty/boost/asm/make_sparc64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_sparc64_sysv_elf_gas.S new file mode 100755 index 0000000..113e0f5 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_sparc64_sysv_elf_gas.S @@ -0,0 +1,89 @@ +/* + Copyright Martin Husemann 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************* + * * + * ------------------------------------------------------------- * + * | Offset (in 4 or 8 byte units) | Content | * + * ------------------------------------------------------------- * + * | 0 | %sp | * + * ------------------------------------------------------------- * + * | 1 | %pc | * + * ------------------------------------------------------------- * + * | 2 | %i7 (return address) | * + * ------------------------------------------------------------- * + * | 3 | %g1 | * + * ------------------------------------------------------------- * + * | 4 | %g2 | * + * ------------------------------------------------------------- * + * | 5 | %g3 | * + * ------------------------------------------------------------- * + * | 6 | %g6 | * + * ------------------------------------------------------------- * + * | 7 | %g7 | * + * ------------------------------------------------------------- * + * The local and in registers are stored on the stack. * + *******************************************************************/ + +#define OFF(N) (8*(N)) +#define CCFSZ 176 // C Compiler Frame Size +#define BIAS (2048-1) // Stack offset for 64 bit programs +#define FC_SZ 448 // sizeof(fcontext_t) +#define FC_STK 384 // offsetof(fcontext_t, fc_stack) +#define FC_FPU 0 // offsetof(fcontext_t, fc_fp) +#define FC_FSR 264 // offsetof(fcontext_t, fc_fp.fp_fsr) +#define FC_FPRS 256 // offsetof(fcontext_t, fc_fp.fp_fprs) +#define FC_GREG 320 // offsetof(fcontext_t, fc_greg) +#define BLOCK_SIZE 64 + + .register %g2,#ignore + .register %g3,#ignore + .register %g6,#ignore + +.text +.globl make_fcontext +.align 4 +.type make_fcontext,@function +// fcontext_t * +// make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ) +make_fcontext: + save %sp, -CCFSZ, %sp + // %i0 initial stack pointer + // %i1 stack size limit + // %i2 function pointer for context start function + + sub %i0, FC_SZ, %i4 // allocate fcontext_t at on the new stack and keep pointer as return value + andn %i4, BLOCK_SIZE-1, %i5 // force block ops usable alignement and keep pointer to fcontext in %i5 + + stx %i0, [%i5+FC_STK+OFF(0)] // save fs_stack.sp + stx %i1, [%i5+FC_STK+OFF(1)] // save fs_stack.size + sub %i5, CCFSZ+BIAS, %o1 // leave space for one register window (and offset stack for 64bit) + stx %o1, [%i5+FC_GREG+OFF(0)] // save new stack pointer + stx %i2, [%i5+FC_GREG+OFF(1)] // save new %pc (function pointer) + stx %g1, [%i5+FC_GREG+OFF(3)] + stx %g2, [%i5+FC_GREG+OFF(4)] + stx %g3, [%i5+FC_GREG+OFF(5)] + stx %g6, [%i5+FC_GREG+OFF(6)] + stx %g7, [%i5+FC_GREG+OFF(7)] + + // synthesize "return address": jump to finish +1: rd %pc, %i4 + add %i4, finish-1b-8, %i4 + stx %i4, [%i5+FC_GREG+OFF(2)] + + ret + restore %g0, %i5, %o0 // return fcontext_t + +finish: + mov %g0, %o0 + call _exit + nop + +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_sparc_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_sparc_sysv_elf_gas.S new file mode 100755 index 0000000..2633471 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_sparc_sysv_elf_gas.S @@ -0,0 +1,85 @@ +/* + Copyright Martin Husemann 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/******************************************************************* + * * + * ------------------------------------------------------------- * + * | Offset (in 4 or 8 byte units) | Content | * + * ------------------------------------------------------------- * + * | 0 | %sp | * + * ------------------------------------------------------------- * + * | 1 | %pc | * + * ------------------------------------------------------------- * + * | 2 | %i7 (return address) | * + * ------------------------------------------------------------- * + * | 3 | %g1 | * + * ------------------------------------------------------------- * + * | 4 | %g2 | * + * ------------------------------------------------------------- * + * | 5 | %g3 | * + * ------------------------------------------------------------- * + * | 6 | %g6 | * + * ------------------------------------------------------------- * + * | 7 | %g7 | * + * ------------------------------------------------------------- * + * The local and in registers are stored on the stack. * + *******************************************************************/ + +#define OFF(N) (4*(N)) +#define CCFSZ 96 +#define FC_SZ 176 +#define FC_stK 168 // offsetof(fcontext_t, fc_stack) +#define FC_FPU 0 // offsetof(fcontext_t, fc_fp) +#define FC_FSR 128 // offsetof(fcontext_t, fc_fp.fp_fsr) +#define FC_GREG 136 // offsetof(fcontext_t, fc_greg) +#define BLOCK_SIZE 8 + +.text +.globl make_fcontext +.align 4 +.type make_fcontext,@function +// fcontext_t * +// make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) ) +make_fcontext: + save %sp, -CCFSZ, %sp + // %i0 initial stack pointer + // %i1 stack size limit + // %i2 function pointer for context start function + + sub %i0, FC_SZ, %i4 // allocate fcontext_t at on the new stack and keep pointer as return value + andn %i4, BLOCK_SIZE-1, %i5 // force block ops usable alignement and keep pointer to fcontext in %i5 + + st %i0, [%i5+FC_stK+OFF(0)] // save fs_stack.sp + st %i1, [%i5+FC_stK+OFF(1)] // save fs_stack.size + sub %i5, CCFSZ, %o1 // leave space for one register window + st %o1, [%i5+FC_GREG+OFF(0)] // save new stack pointer + st %i2, [%i5+FC_GREG+OFF(1)] // save new %pc (function pointer) + st %g1, [%i5+FC_GREG+OFF(3)] + st %g2, [%i5+FC_GREG+OFF(4)] + st %g3, [%i5+FC_GREG+OFF(5)] + st %g6, [%i5+FC_GREG+OFF(6)] + st %g7, [%i5+FC_GREG+OFF(7)] + + // synthesize "return address": jump to finish + mov %i7, %l0 +2: call 3f + nop +3: add finish-2b-8, %o7, %i4 + st %i4, [%i5+FC_GREG+OFF(2)] + + ret + restore %g0, %i5, %o0 // return fcontext_t + +finish: + mov %g0, %o0 + call _exit + nop + +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_gas.asm b/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_gas.asm new file mode 100755 index 0000000..31dd566 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_gas.asm @@ -0,0 +1,151 @@ +/* + Copyright Oliver Kowalke 2009. + Copyright Thomas Sailer 2013. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- + * | 0 | 1 | | + * ---------------------------------------------------------------------------------- + * | 0x0 | 0x4 | | + * ---------------------------------------------------------------------------------- + * | <indicator> | | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | + * ---------------------------------------------------------------------------------- + * | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | + * ---------------------------------------------------------------------------------- + * | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | + * ---------------------------------------------------------------------------------- + * | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | + * ---------------------------------------------------------------------------------- + * | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | + * ---------------------------------------------------------------------------------- + * | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 | + * ---------------------------------------------------------------------------------- + * | SEE registers (XMM6-XMM15) | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | + * ---------------------------------------------------------------------------------- + * | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 | + * ---------------------------------------------------------------------------------- + * | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | + * ---------------------------------------------------------------------------------- + * | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 | + * ---------------------------------------------------------------------------------- + * | limit | base | R12 | R13 | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | + * ---------------------------------------------------------------------------------- + * | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 | + * ---------------------------------------------------------------------------------- + * | R14 | R15 | RDI | RSI | + * ---------------------------------------------------------------------------------- + * ---------------------------------------------------------------------------------- + * | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | + * ---------------------------------------------------------------------------------- + * | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | + * ---------------------------------------------------------------------------------- + * | RBX | RBP | RIP | EXIT | + * ---------------------------------------------------------------------------------- + * * + * *************************************************************************************/ + +.file "make_x86_64_ms_pe_gas.asm" +.text +.p2align 4,,15 +.globl make_fcontext +.def make_fcontext; .scl 2; .type 32; .endef +.seh_proc make_fcontext +make_fcontext: +.seh_endprologue + + /* first arg of make_fcontext() == top of context-stack */ + movq %rcx, %rax + + /* reserve 32byte shadow-space for context-function */ + leaq -0x28(%rax), %rax + + /* shift address in RAX to lower 16 byte boundary */ + /* == pointer to fcontext_t and address of context stack */ + andq $-16, %rax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. RIP + return-address for context-function */ + /* on context-function entry: (RSP -0x8) % 16 == 0 */ + leaq -0x128(%rax), %rax + + /* third arg of make_fcontext() == address of context-function */ + movq %r8, 0x118(%rax) + + /* first arg of make_fcontext() == top of context-stack */ + /* save top address of context stack as 'base' */ + movq %rcx, 0xd0(%rax) + /* second arg of make_fcontext() == size of context-stack */ + /* negate stack size for LEA instruction (== substraction) */ + negq %rdx + /* compute bottom address of context stack (limit) */ + leaq (%rcx,%rdx), %rcx + /* save bottom address of context stack as 'limit' */ + movq %rcx, 0xc8(%rax) + /* save address of context stack limit as 'dealloction stack' */ + movq %rcx, 0xc0(%rax) + + /* save MMX control- and status-word */ + stmxcsr 0xa8(%rax) + /* save x87 control-word */ + fnstcw 0xac(%rax) + + /* compute abs address of label finish */ + leaq finish(%rip), %rcx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movq %rcx, 0x120(%rax) + + /* set indicator */ + movq 1, %rcx + movq %rcx, (%rax) + + ret /* return pointer to context-data */ + +finish: + /* 32byte shadow-space for _exit() are */ + /* already reserved by make_fcontext() */ + /* exit code is zero */ + xorq %rcx, %rcx + /* exit application */ + call _exit + hlt +.seh_endproc + +.def _exit; .scl 2; .type 32; .endef /* standard C library function */ diff --git a/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_masm.asm b/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_masm.asm new file mode 100755 index 0000000..a4eb58c --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_x86_64_ms_pe_masm.asm @@ -0,0 +1,144 @@ + +; Copyright Oliver Kowalke 2009. +; Distributed under the Boost Software License, Version 1.0. +; (See accompanying file LICENSE_1_0.txt or copy at +; http://www.boost.org/LICENSE_1_0.txt) + +; ---------------------------------------------------------------------------------- +; | 0 | 1 | | +; ---------------------------------------------------------------------------------- +; | 0x0 | 0x4 | | +; ---------------------------------------------------------------------------------- +; | <indicator> | | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +; ---------------------------------------------------------------------------------- +; | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | 0x20 | 0x24 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | +; ---------------------------------------------------------------------------------- +; | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | 0x40 | 0x44 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | +; ---------------------------------------------------------------------------------- +; | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | 0x60 | 0x64 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | +; ---------------------------------------------------------------------------------- +; | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | +; ---------------------------------------------------------------------------------- +; | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | 0xa0 | 0xa4 | +; ---------------------------------------------------------------------------------- +; | SEE registers (XMM6-XMM15) | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | +; ---------------------------------------------------------------------------------- +; | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | 0xc0 | 0xc4 | +; ---------------------------------------------------------------------------------- +; | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | +; ---------------------------------------------------------------------------------- +; | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | 0xe0 | 0xe4 | +; ---------------------------------------------------------------------------------- +; | limit | base | R12 | R13 | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | +; ---------------------------------------------------------------------------------- +; | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | 0x100 | 0x104 | +; ---------------------------------------------------------------------------------- +; | R14 | R15 | RDI | RSI | +; ---------------------------------------------------------------------------------- +; ---------------------------------------------------------------------------------- +; | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | +; ---------------------------------------------------------------------------------- +; | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | +; ---------------------------------------------------------------------------------- +; | RBX | RBP | RIP | EXIT | +; ---------------------------------------------------------------------------------- + +; standard C library function +EXTERN _exit:PROC +.code + +; generate function table entry in .pdata and unwind information in +make_fcontext PROC BOOST_CONTEXT_EXPORT FRAME + ; .xdata for a function's structured exception handling unwind behavior + .endprolog + + ; first arg of make_fcontext() == top of context-stack + mov rax, rcx + + ; reserve 32byte shadow-space for context-function + sub rax, 028h + + ; shift address in RAX to lower 16 byte boundary + ; == pointer to fcontext_t and address of context stack + and rax, -16 + + ; reserve space for context-data on context-stack + ; size for fc_mxcsr .. RIP + return-address for context-function + ; on context-function entry: (RSP -0x8) % 16 == 0 + sub rax, 0128h + + ; third arg of make_fcontext() == address of context-function + mov [rax+0118h], r8 + + ; first arg of make_fcontext() == top of context-stack + ; save top address of context stack as 'base' + mov [rax+0d0h], rcx + ; second arg of make_fcontext() == size of context-stack + ; negate stack size for LEA instruction (== substraction) + neg rdx + ; compute bottom address of context stack (limit) + lea rcx, [rcx+rdx] + ; save bottom address of context stack as 'limit' + mov [rax+0c8h], rcx + ; save address of context stack limit as 'dealloction stack' + mov [rax+0c0h], rcx + + ; save MMX control- and status-word + stmxcsr [rax+0a8h] + ; save x87 control-word + fnstcw [rax+0ach] + + ; compute abs address of label finish + lea rcx, finish + ; save address of finish as return-address for context-function + ; will be entered after context-function returns + mov [rax+0120h], rcx + + ; set indicator + mov rcx, 1 + mov [rax], rcx + + ret ; return pointer to context-data + +finish: + ; 32byte shadow-space for _exit() are + ; already reserved by make_fcontext() + ; exit code is zero + xor rcx, rcx + ; exit application + call _exit + hlt +make_fcontext ENDP +END diff --git a/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_elf_gas.S b/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_elf_gas.S new file mode 100755 index 0000000..b687879 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_elf_gas.S @@ -0,0 +1,75 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | EXIT | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl make_fcontext +.type make_fcontext,@function +.align 16 +make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movq %rdi, %rax + + /* shift address in RAX to lower 16 byte boundary */ + andq $-16, %rax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. RIP + return-address for context-function */ + /* on context-function entry: (RSP -0x8) % 16 == 0 */ + leaq -0x48(%rax), %rax + + /* third arg of make_fcontext() == address of context-function */ + movq %rdx, 0x38(%rax) + + /* save MMX control- and status-word */ + stmxcsr (%rax) + /* save x87 control-word */ + fnstcw 0x4(%rax) + + /* compute abs address of label finish */ + leaq finish(%rip), %rcx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movq %rcx, 0x40(%rax) + + ret /* return pointer to context-data */ + +finish: + /* exit code is zero */ + xorq %rdi, %rdi + /* exit application */ + call _exit@PLT + hlt +.size make_fcontext,.-make_fcontext + +/* Mark that we don't need executable stack. */ +.section .note.GNU-stack,"",%progbits diff --git a/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_macho_gas.S b/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_macho_gas.S new file mode 100755 index 0000000..3a030f8 --- /dev/null +++ b/vendor/swoole/thirdparty/boost/asm/make_x86_64_sysv_macho_gas.S @@ -0,0 +1,71 @@ +/* + Copyright Oliver Kowalke 2009. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ + +/**************************************************************************************** + * * + * ---------------------------------------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ---------------------------------------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | * + * ---------------------------------------------------------------------------------- * + * | fc_mxcsr|fc_x87_cw| R12 | R13 | R14 | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ---------------------------------------------------------------------------------- * + * | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | * + * ---------------------------------------------------------------------------------- * + * | R15 | RBX | RBP | RIP | * + * ---------------------------------------------------------------------------------- * + * ---------------------------------------------------------------------------------- * + * | 16 | 17 | | * + * ---------------------------------------------------------------------------------- * + * | 0x40 | 0x44 | | * + * ---------------------------------------------------------------------------------- * + * | EXIT | | * + * ---------------------------------------------------------------------------------- * + * * + ****************************************************************************************/ + +.text +.globl _make_fcontext +.align 8 +_make_fcontext: + /* first arg of make_fcontext() == top of context-stack */ + movq %rdi, %rax + + /* shift address in RAX to lower 16 byte boundary */ + movabs $-16, %r8 + andq %r8, %rax + + /* reserve space for context-data on context-stack */ + /* size for fc_mxcsr .. RIP + return-address for context-function */ + /* on context-function entry: (RSP -0x8) % 16 == 0 */ + leaq -0x48(%rax), %rax + + /* third arg of make_fcontext() == address of context-function */ + movq %rdx, 0x38(%rax) + + /* save MMX control- and status-word */ + stmxcsr (%rax) + /* save x87 control-word */ + fnstcw 0x4(%rax) + + /* compute abs address of label finish */ + leaq finish(%rip), %rcx + /* save address of finish as return-address for context-function */ + /* will be entered after context-function returns */ + movq %rcx, 0x40(%rax) + + ret /* return pointer to context-data */ + +finish: + /* exit code is zero */ + xorq %rdi, %rdi + /* exit application */ + call __exit + hlt diff --git a/vendor/swoole/thirdparty/multipart_parser.c b/vendor/swoole/thirdparty/multipart_parser.c new file mode 100755 index 0000000..b98d8d2 --- /dev/null +++ b/vendor/swoole/thirdparty/multipart_parser.c @@ -0,0 +1,289 @@ +/* Based on node-formidable by Felix Geisendörfer + * Igor Afonov - afonov@gmail.com - 2012 + * MIT License - http://www.opensource.org/licenses/mit-license.php + */ + +#include "multipart_parser.h" + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +static void multipart_log(const char * format, ...) +{ +#ifdef DEBUG_MULTIPART + va_list args; + va_start(args, format); + + fprintf(stderr, "[HTTP_MULTIPART_PARSER] %s:%d: ", __FILE__, __LINE__); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); +#endif +} + +#define NOTIFY_CB(FOR) \ +do { \ + if (p->settings->on_##FOR) { \ + if (p->settings->on_##FOR(p) != 0) { \ + return i; \ + } \ + } \ +} while (0) + +#define EMIT_DATA_CB(FOR, ptr, len) \ +do { \ + if (p->settings->on_##FOR) { \ + if (p->settings->on_##FOR(p, ptr, len) != 0) { \ + return i; \ + } \ + } \ +} while (0) + + +#define LF 10 +#define CR 13 + +enum state { + s_uninitialized = 1, + s_start, + s_start_boundary, + s_header_field_start, + s_header_field, + s_headers_almost_done, + s_header_value_start, + s_header_value, + s_header_value_almost_done, + s_part_data_start, + s_part_data, + s_part_data_almost_boundary, + s_part_data_boundary, + s_part_data_almost_end, + s_part_data_end, + s_part_data_final_hyphen, + s_end +}; + +multipart_parser* multipart_parser_init(const char *boundary, size_t boundary_length, + const multipart_parser_settings* settings) +{ + multipart_parser* p = calloc(sizeof(multipart_parser) + boundary_length + boundary_length + 9 + 4, sizeof(char)); + memcpy(p->multipart_boundary, "--", 2); + memcpy(p->multipart_boundary + 2, boundary, boundary_length); + p->multipart_boundary[2 + boundary_length] = 0; + +#if 0 + printf("boundary: %s\r\n\r\n", p->multipart_boundary); +#endif + + p->boundary_length = boundary_length + 2; + p->lookbehind = (p->multipart_boundary + p->boundary_length + 1); + p->index = 0; + p->state = s_start; + p->settings = settings; + + return p; +} + +void multipart_parser_free(multipart_parser* p) { + free(p); +} + +size_t multipart_parser_execute(multipart_parser* p, const char *buf, size_t len) { + size_t i = 0; + size_t mark = 0; + char c, cl; + int is_last = 0; + + while(i < len) { + c = buf[i]; + is_last = (i == (len - 1)); + switch (p->state) { + case s_start: + multipart_log("s_start"); + p->index = 0; + p->state = s_start_boundary; + + /* fallthrough */ + case s_start_boundary: + multipart_log("s_start_boundary"); + if (p->index == p->boundary_length) { + if (c != CR) { + return i; + } + p->index++; + break; + } else if (p->index == (p->boundary_length + 1)) { + if (c != LF) { + return i; + } + p->index = 0; + NOTIFY_CB(part_data_begin); + p->state = s_header_field_start; + break; + } + if (c != p->multipart_boundary[p->index]) { + return i; + } + p->index++; + break; + + case s_header_field_start: + multipart_log("s_header_field_start"); + mark = i; + p->state = s_header_field; + + /* fallthrough */ + case s_header_field: + multipart_log("s_header_field"); + if (c == CR) { + p->state = s_headers_almost_done; + break; + } + + if (c == '-') { + break; + } + + if (c == ':') { + EMIT_DATA_CB(header_field, buf + mark, i - mark); + p->state = s_header_value_start; + break; + } + + cl = tolower(c); + if (cl < 'a' || cl > 'z') { + multipart_log("invalid character in header name"); + return i; + } + if (is_last) + EMIT_DATA_CB(header_field, buf + mark, (i - mark) + 1); + break; + + case s_headers_almost_done: + multipart_log("s_headers_almost_done"); + if (c != LF) { + return i; + } + + p->state = s_part_data_start; + break; + + case s_header_value_start: + multipart_log("s_header_value_start"); + if (c == ' ') { + break; + } + + mark = i; + p->state = s_header_value; + + /* fallthrough */ + case s_header_value: + multipart_log("s_header_value"); + if (c == CR) { + EMIT_DATA_CB(header_value, buf + mark, i - mark); + p->state = s_header_value_almost_done; + } + if (is_last) + EMIT_DATA_CB(header_value, buf + mark, (i - mark) + 1); + break; + + case s_header_value_almost_done: + multipart_log("s_header_value_almost_done"); + if (c != LF) { + return i; + } + p->state = s_header_field_start; + break; + + case s_part_data_start: + multipart_log("s_part_data_start"); + NOTIFY_CB(headers_complete); + mark = i; + p->state = s_part_data; + + /* fallthrough */ + case s_part_data: + multipart_log("s_part_data"); + if (c == CR) { + EMIT_DATA_CB(part_data, buf + mark, i - mark); + mark = i; + p->state = s_part_data_almost_boundary; + p->lookbehind[0] = CR; + break; + } + if (is_last) + EMIT_DATA_CB(part_data, buf + mark, (i - mark) + 1); + break; + + case s_part_data_almost_boundary: + multipart_log("s_part_data_almost_boundary"); + if (c == LF) { + p->state = s_part_data_boundary; + p->lookbehind[1] = LF; + p->index = 0; + break; + } + EMIT_DATA_CB(part_data, p->lookbehind, 1); + p->state = s_part_data; + mark = i --; + break; + + case s_part_data_boundary: + multipart_log("s_part_data_boundary"); + if (p->multipart_boundary[p->index] != c) { + EMIT_DATA_CB(part_data, p->lookbehind, 2 + p->index); + p->state = s_part_data; + mark = i --; + break; + } + p->lookbehind[2 + p->index] = c; + if ((++ p->index) == p->boundary_length) { + NOTIFY_CB(part_data_end); + p->state = s_part_data_almost_end; + } + break; + + case s_part_data_almost_end: + multipart_log("s_part_data_almost_end"); + if (c == '-') { + p->state = s_part_data_final_hyphen; + break; + } + if (c == CR) { + p->state = s_part_data_end; + break; + } + return i; + + case s_part_data_final_hyphen: + multipart_log("s_part_data_final_hyphen"); + if (c == '-') { + NOTIFY_CB(body_end); + p->state = s_end; + break; + } + return i; + + case s_part_data_end: + multipart_log("s_part_data_end"); + if (c == LF) { + p->state = s_header_field_start; + NOTIFY_CB(part_data_begin); + break; + } + return i; + + case s_end: + multipart_log("s_end: %02X", (int) c); + break; + + default: + multipart_log("Multipart parser unrecoverable error"); + return 0; + } + ++ i; + } + + return len; +} diff --git a/vendor/swoole/thirdparty/multipart_parser.h b/vendor/swoole/thirdparty/multipart_parser.h new file mode 100755 index 0000000..e3ab7bf --- /dev/null +++ b/vendor/swoole/thirdparty/multipart_parser.h @@ -0,0 +1,60 @@ +/* Based on node-formidable by Felix Geisendörfer + * Igor Afonov - afonov@gmail.com - 2012 + * MIT License - http://www.opensource.org/licenses/mit-license.php + */ +#ifndef _multipart_parser_h +#define _multipart_parser_h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include <stdlib.h> +#include <ctype.h> + +typedef struct multipart_parser multipart_parser; +typedef struct multipart_parser_settings multipart_parser_settings; +typedef struct multipart_parser_state multipart_parser_state; + +typedef int (*multipart_data_cb) (multipart_parser*, const char *at, size_t length); +typedef int (*multipart_notify_cb) (multipart_parser*); + +struct multipart_parser { + void * data; + void * fp; + + size_t index; + size_t boundary_length; + + unsigned char state; + + const multipart_parser_settings* settings; + + char* lookbehind; + char multipart_boundary[1]; +}; + +struct multipart_parser_settings { + multipart_data_cb on_header_field; + multipart_data_cb on_header_value; + multipart_data_cb on_part_data; + + multipart_notify_cb on_part_data_begin; + multipart_notify_cb on_headers_complete; + multipart_notify_cb on_part_data_end; + multipart_notify_cb on_body_end; +}; + +multipart_parser* multipart_parser_init + (const char *boundary, size_t boundary_length, const multipart_parser_settings* settings); + +void multipart_parser_free(multipart_parser* p); + +size_t multipart_parser_execute(multipart_parser* p, const char *buf, size_t len); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/vendor/swoole/thirdparty/php_http_parser.c b/vendor/swoole/thirdparty/php_http_parser.c new file mode 100755 index 0000000..d3bc496 --- /dev/null +++ b/vendor/swoole/thirdparty/php_http_parser.c @@ -0,0 +1,1608 @@ +/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include <assert.h> +#include <stddef.h> +#include "php_http_parser.h" + + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + + +#define CALLBACK2(FOR) \ +do { \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser)) return (p - data); \ + } \ +} while (0) + + +#define MARK(FOR) \ +do { \ + FOR##_mark = p; \ +} while (0) + +#define CALLBACK_NOCLEAR(FOR) \ +do { \ + if (FOR##_mark) { \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser, \ + FOR##_mark, \ + p - FOR##_mark)) \ + { \ + return (p - data); \ + } \ + } \ + } \ +} while (0) + +#ifdef PHP_WIN32 +# undef CALLBACK +#endif +#define CALLBACK(FOR) \ +do { \ + CALLBACK_NOCLEAR(FOR); \ + FOR##_mark = NULL; \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { "DELETE" + , "GET" + , "HEAD" + , "POST" + , "PUT" + , "PATCH" + , "CONNECT" + , "OPTIONS" + , "TRACE" + , "COPY" + , "LOCK" + , "MKCOL" + , "MOVE" + , "PROPFIND" + , "PROPPATCH" + , "UNLOCK" + , "REPORT" + , "MKACTIVITY" + , "CHECKOUT" + , "MERGE" + , "M-SEARCH" + , "NOTIFY" + , "SUBSCRIBE" + , "UNSUBSCRIBE" + , "NOTIMPLEMENTED" + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1*<any CHAR except CTLs or separators> + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + ' ', '!', '"', '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', '/', +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', '}', '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +static const uint8_t normal_url_char[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, 1, 1, 0, 1, 1, 1, 1, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1, 1, 1, 1, 1, 1, 1, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1, 1, 1, 1, 1, 1, 1, 1, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1, 1, 1, 1, 1, 1, 1, 0 }; + + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_host + , s_req_port + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_start + , s_header_value + + , s_header_almost_done + + , s_headers_almost_done + /* Important: 's_headers_almost_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + , s_chunk_size_start + , s_chunk_size + , s_chunk_size_almost_done + , s_chunk_parameters + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + }; + + +#define PARSING_HEADER(state) (state <= s_headers_almost_done && 0 == (parser->flags & F_TRAILING)) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_keep_alive + , h_matching_connection_close + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + }; + + +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_TRAILING = 1 << 3 + , F_UPGRADE = 1 << 4 + , F_SKIPBODY = 1 << 5 + }; + + +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define TOKEN(c) tokens[(unsigned char)c] + + +#define start_state (parser->type == PHP_HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) if (cond) goto error +# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +size_t php_http_parser_execute (php_http_parser *parser, + const php_http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + const char *p = data, *pe; + size_t to_read; + + enum state state = (enum state) parser->state; + enum header_states header_state = (enum header_states) parser->header_state; + uint32_t index = parser->index; + uint32_t nread = parser->nread; + + /* technically we could combine all of these (except for url_mark) into one + variable, saving stack space, but it seems more clear to have them + separated. */ + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *fragment_mark = 0; + const char *query_string_mark = 0; + const char *path_mark = 0; + const char *url_mark = 0; + + if (len == 0) { + if (state == s_body_identity_eof) { + CALLBACK2(message_complete); + } + return 0; + } + + if (state == s_header_field) + header_field_mark = data; + if (state == s_header_value) + header_value_mark = data; + if (state == s_req_fragment) + fragment_mark = data; + if (state == s_req_query_string) + query_string_mark = data; + if (state == s_req_path) + path_mark = data; + if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash + || state == s_req_schema_slash_slash || state == s_req_port + || state == s_req_query_string_start || state == s_req_query_string + || state == s_req_host + || state == s_req_fragment_start || state == s_req_fragment) + url_mark = data; + + for (p=data, pe=data+len; p != pe; p++) { + ch = *p; + + if (PARSING_HEADER(state)) { + ++nread; + /* Buffer overflow attack */ + if (nread > PHP_HTTP_MAX_HEADER_SIZE) goto error; + } + + switch (state) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = -1; + + CALLBACK2(message_begin); + + if (ch == 'H') + state = s_res_or_resp_H; + else { + parser->type = PHP_HTTP_REQUEST; + goto start_req_method_assign; + } + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = PHP_HTTP_RESPONSE; + state = s_res_HT; + } else { + if (ch != 'E') goto error; + parser->type = PHP_HTTP_REQUEST; + parser->method = PHP_HTTP_HEAD; + index = 2; + state = s_req_method; + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = -1; + + CALLBACK2(message_begin); + + switch (ch) { + case 'H': + state = s_res_H; + break; + + case CR: + case LF: + break; + + default: + goto error; + } + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + state = s_res_HT; + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + state = s_res_HTT; + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + state = s_res_HTTP; + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + state = s_res_first_http_major; + break; + + case s_res_first_http_major: + if (ch < '1' || ch > '9') goto error; + parser->http_major = ch - '0'; + state = s_res_http_major; + break; + + /* major HTTP version or dot */ + case s_res_http_major: + { + if (ch == '.') { + state = s_res_first_http_minor; + break; + } + + if (ch < '0' || ch > '9') goto error; + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) goto error; + break; + } + + /* first digit of minor HTTP version */ + case s_res_first_http_minor: + if (ch < '0' || ch > '9') goto error; + parser->http_minor = ch - '0'; + state = s_res_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_res_http_minor: + { + if (ch == ' ') { + state = s_res_first_status_code; + break; + } + + if (ch < '0' || ch > '9') goto error; + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) goto error; + break; + } + + case s_res_first_status_code: + { + if (ch < '0' || ch > '9') { + if (ch == ' ') { + break; + } + goto error; + } + parser->status_code = ch - '0'; + state = s_res_status_code; + break; + } + + case s_res_status_code: + { + if (ch < '0' || ch > '9') { + switch (ch) { + case ' ': + state = s_res_status; + break; + case CR: + state = s_res_line_almost_done; + break; + case LF: + state = s_header_field_start; + break; + default: + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (parser->status_code > 999) goto error; + break; + } + + case s_res_status: + /* the human readable status. e.g. "NOT FOUND" + * we are not humans so just ignore this */ + if (ch == CR) { + state = s_res_line_almost_done; + break; + } + + if (ch == LF) { + state = s_header_field_start; + break; + } + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + state = s_header_field_start; + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = -1; + + CALLBACK2(message_begin); + + if (ch < 'A' || 'Z' < ch) goto error; + + start_req_method_assign: + parser->method = (enum php_http_method) 0; + index = 1; + switch (ch) { + case 'C': parser->method = PHP_HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = PHP_HTTP_DELETE; break; + case 'G': parser->method = PHP_HTTP_GET; break; + case 'H': parser->method = PHP_HTTP_HEAD; break; + case 'L': parser->method = PHP_HTTP_LOCK; break; + case 'M': parser->method = PHP_HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; + case 'N': parser->method = PHP_HTTP_NOTIFY; break; + case 'O': parser->method = PHP_HTTP_OPTIONS; break; + case 'P': parser->method = PHP_HTTP_POST; /* or PROPFIND or PROPPATCH or PUT */ break; + case 'R': parser->method = PHP_HTTP_REPORT; break; + case 'S': parser->method = PHP_HTTP_SUBSCRIBE; break; + case 'T': parser->method = PHP_HTTP_TRACE; break; + case 'U': parser->method = PHP_HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; + default: parser->method = PHP_HTTP_NOT_IMPLEMENTED; break; + } + state = s_req_method; + break; + } + + case s_req_method: + { + const char *matcher; + if (ch == '\0') + goto error; + + matcher = method_strings[parser->method]; + if (ch == ' ' && (matcher[index] == '\0' || parser->method == PHP_HTTP_NOT_IMPLEMENTED)) { + state = s_req_spaces_before_url; + } else if (ch == matcher[index]) { + ; /* nada */ + } else if (parser->method == PHP_HTTP_CONNECT) { + if (index == 1 && ch == 'H') { + parser->method = PHP_HTTP_CHECKOUT; + } else if (index == 2 && ch == 'P') { + parser->method = PHP_HTTP_COPY; + } + } else if (parser->method == PHP_HTTP_MKCOL) { + if (index == 1 && ch == 'O') { + parser->method = PHP_HTTP_MOVE; + } else if (index == 1 && ch == 'E') { + parser->method = PHP_HTTP_MERGE; + } else if (index == 1 && ch == '-') { + parser->method = PHP_HTTP_MSEARCH; + } else if (index == 2 && ch == 'A') { + parser->method = PHP_HTTP_MKACTIVITY; + } + } else if (index == 1 && parser->method == PHP_HTTP_POST && ch == 'R') { + parser->method = PHP_HTTP_PROPFIND; /* or HTTP_PROPPATCH */ + } else if (index == 1 && parser->method == PHP_HTTP_POST && ch == 'U') { + parser->method = PHP_HTTP_PUT; + } else if (index == 1 && parser->method == PHP_HTTP_POST && ch == 'A') { + parser->method = PHP_HTTP_PATCH; + } else if (index == 2 && parser->method == PHP_HTTP_UNLOCK && ch == 'S') { + parser->method = PHP_HTTP_UNSUBSCRIBE; + } else if (index == 4 && parser->method == PHP_HTTP_PROPFIND && ch == 'P') { + parser->method = PHP_HTTP_PROPPATCH; + } else { + parser->method = PHP_HTTP_NOT_IMPLEMENTED; + } + + ++index; + break; + } + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + if (ch == '/' || ch == '*') { + MARK(url); + MARK(path); + state = s_req_path; + break; + } + + c = LOWER(ch); + + if (c >= 'a' && c <= 'z') { + MARK(url); + state = s_req_schema; + break; + } + + goto error; + } + + case s_req_schema: + { + c = LOWER(ch); + + if (c >= 'a' && c <= 'z') break; + + if (ch == ':') { + state = s_req_schema_slash; + break; + } else if (ch == '.') { + state = s_req_host; + break; + } else if ('0' <= ch && ch <= '9') { + state = s_req_host; + break; + } + + goto error; + } + + case s_req_schema_slash: + STRICT_CHECK(ch != '/'); + state = s_req_schema_slash_slash; + break; + + case s_req_schema_slash_slash: + STRICT_CHECK(ch != '/'); + state = s_req_host; + break; + + case s_req_host: + { + c = LOWER(ch); + if (c >= 'a' && c <= 'z') break; + if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') break; + switch (ch) { + case ':': + state = s_req_port; + break; + case '/': + MARK(path); + state = s_req_path; + break; + case ' ': + /* The request line looks like: + * "GET http://foo.bar.com HTTP/1.1" + * That is, there is no path. + */ + CALLBACK(url); + state = s_req_http_start; + break; + default: + goto error; + } + break; + } + + case s_req_port: + { + if (ch >= '0' && ch <= '9') break; + switch (ch) { + case '/': + MARK(path); + state = s_req_path; + break; + case ' ': + /* The request line looks like: + * "GET http://foo.bar.com:1234 HTTP/1.1" + * That is, there is no path. + */ + CALLBACK(url); + state = s_req_http_start; + break; + default: + goto error; + } + break; + } + + case s_req_path: + { + if (normal_url_char[(unsigned char)ch]) break; + + switch (ch) { + case ' ': + CALLBACK(url); + CALLBACK(path); + state = s_req_http_start; + break; + case CR: + CALLBACK(url); + CALLBACK(path); + parser->http_major = 0; + parser->http_minor = 9; + state = s_req_line_almost_done; + break; + case LF: + CALLBACK(url); + CALLBACK(path); + parser->http_major = 0; + parser->http_minor = 9; + state = s_header_field_start; + break; + case '?': + CALLBACK(path); + state = s_req_query_string_start; + break; + case '#': + CALLBACK(path); + state = s_req_fragment_start; + break; + default: + goto error; + } + break; + } + + case s_req_query_string_start: + { + if (normal_url_char[(unsigned char)ch]) { + MARK(query_string); + state = s_req_query_string; + break; + } + + switch (ch) { + case '?': + break; /* XXX ignore extra '?' ... is this right? */ + case ' ': + CALLBACK(url); + state = s_req_http_start; + break; + case CR: + CALLBACK(url); + parser->http_major = 0; + parser->http_minor = 9; + state = s_req_line_almost_done; + break; + case LF: + CALLBACK(url); + parser->http_major = 0; + parser->http_minor = 9; + state = s_header_field_start; + break; + case '#': + state = s_req_fragment_start; + break; + default: + goto error; + } + break; + } + + case s_req_query_string: + { + if (normal_url_char[(unsigned char)ch]) break; + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + break; + case ' ': + CALLBACK(url); + CALLBACK(query_string); + state = s_req_http_start; + break; + case CR: + CALLBACK(url); + CALLBACK(query_string); + parser->http_major = 0; + parser->http_minor = 9; + state = s_req_line_almost_done; + break; + case LF: + CALLBACK(url); + CALLBACK(query_string); + parser->http_major = 0; + parser->http_minor = 9; + state = s_header_field_start; + break; + case '#': + CALLBACK(query_string); + state = s_req_fragment_start; + break; + default: + goto error; + } + break; + } + + case s_req_fragment_start: + { + if (normal_url_char[(unsigned char)ch]) { + MARK(fragment); + state = s_req_fragment; + break; + } + + switch (ch) { + case ' ': + CALLBACK(url); + state = s_req_http_start; + break; + case CR: + CALLBACK(url); + parser->http_major = 0; + parser->http_minor = 9; + state = s_req_line_almost_done; + break; + case LF: + CALLBACK(url); + parser->http_major = 0; + parser->http_minor = 9; + state = s_header_field_start; + break; + case '?': + MARK(fragment); + state = s_req_fragment; + break; + case '#': + break; + default: + goto error; + } + break; + } + + case s_req_fragment: + { + if (normal_url_char[(unsigned char)ch]) break; + + switch (ch) { + case ' ': + CALLBACK(url); + CALLBACK(fragment); + state = s_req_http_start; + break; + case CR: + CALLBACK(url); + CALLBACK(fragment); + parser->http_major = 0; + parser->http_minor = 9; + state = s_req_line_almost_done; + break; + case LF: + CALLBACK(url); + CALLBACK(fragment); + parser->http_major = 0; + parser->http_minor = 9; + state = s_header_field_start; + break; + case '?': + case '#': + break; + default: + goto error; + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + state = s_req_http_H; + break; + case ' ': + break; + default: + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + state = s_req_http_HT; + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + state = s_req_http_HTT; + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + state = s_req_http_HTTP; + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + state = s_req_first_http_major; + break; + + /* first digit of major HTTP version */ + case s_req_first_http_major: + if (ch < '1' || ch > '9') goto error; + parser->http_major = ch - '0'; + state = s_req_http_major; + break; + + /* major HTTP version or dot */ + case s_req_http_major: + { + if (ch == '.') { + state = s_req_first_http_minor; + break; + } + + if (ch < '0' || ch > '9') goto error; + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) goto error; + break; + } + + /* first digit of minor HTTP version */ + case s_req_first_http_minor: + if (ch < '0' || ch > '9') goto error; + parser->http_minor = ch - '0'; + state = s_req_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_req_http_minor: + { + if (ch == CR) { + state = s_req_line_almost_done; + break; + } + + if (ch == LF) { + state = s_header_field_start; + break; + } + + /* XXX allow spaces after digit? */ + + if (ch < '0' || ch > '9') goto error; + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) goto error; + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (ch != LF) goto error; + state = s_header_field_start; + break; + } + + case s_header_field_start: + { + if (ch == CR) { + state = s_headers_almost_done; + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + state = s_headers_almost_done; + goto headers_almost_done; + } + + c = TOKEN(ch); + + if (!c) goto error; + + MARK(header_field); + + index = 0; + state = s_header_field; + + switch (c) { + case 'c': + header_state = h_C; + break; + + case 'p': + header_state = h_matching_proxy_connection; + break; + + case 't': + header_state = h_matching_transfer_encoding; + break; + + case 'u': + header_state = h_matching_upgrade; + break; + + default: + header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + c = TOKEN(ch); + + if (c) { + switch (header_state) { + case h_general: + break; + + case h_C: + index++; + header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + index++; + header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + index++; + switch (c) { + case 'n': + header_state = h_matching_connection; + break; + case 't': + header_state = h_matching_content_length; + break; + default: + header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + index++; + if (index > sizeof(CONNECTION)-1 + || c != CONNECTION[index]) { + header_state = h_general; + } else if (index == sizeof(CONNECTION)-2) { + header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + index++; + if (index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[index]) { + header_state = h_general; + } else if (index == sizeof(PROXY_CONNECTION)-2) { + header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + index++; + if (index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[index]) { + header_state = h_general; + } else if (index == sizeof(CONTENT_LENGTH)-2) { + header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + index++; + if (index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[index]) { + header_state = h_general; + } else if (index == sizeof(TRANSFER_ENCODING)-2) { + header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + index++; + if (index > sizeof(UPGRADE)-1 + || c != UPGRADE[index]) { + header_state = h_general; + } else if (index == sizeof(UPGRADE)-2) { + header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + break; + } + + if (ch == ':') { + CALLBACK(header_field); + state = s_header_value_start; + break; + } + + if (ch == CR) { + state = s_header_almost_done; + CALLBACK(header_field); + break; + } + + if (ch == LF) { + CALLBACK(header_field); + state = s_header_field_start; + break; + } + + goto error; + } + + case s_header_value_start: + { + if (ch == ' ') break; + + MARK(header_value); + + state = s_header_value; + index = 0; + + c = LOWER(ch); + + if (ch == CR) { + CALLBACK(header_value); + header_state = h_general; + state = s_header_almost_done; + break; + } + + if (ch == LF) { + CALLBACK(header_value); + state = s_header_field_start; + break; + } + + switch (header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + header_state = h_matching_transfer_encoding_chunked; + } else { + header_state = h_general; + } + break; + + case h_content_length: + if (ch < '0' || ch > '9') goto error; + parser->content_length = ch - '0'; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + header_state = h_matching_connection_close; + } else { + header_state = h_general; + } + break; + + default: + header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + c = LOWER(ch); + + if (ch == CR) { + CALLBACK(header_value); + state = s_header_almost_done; + break; + } + + if (ch == LF) { + CALLBACK(header_value); + goto header_almost_done; + } + + switch (header_state) { + case h_general: + break; + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + if (ch == ' ') break; + if (ch < '0' || ch > '9') goto error; + parser->content_length *= 10; + parser->content_length += ch - '0'; + break; + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + index++; + if (index > sizeof(CHUNKED)-1 + || c != CHUNKED[index]) { + header_state = h_general; + } else if (index == sizeof(CHUNKED)-2) { + header_state = h_transfer_encoding_chunked; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + index++; + if (index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[index]) { + header_state = h_general; + } else if (index == sizeof(KEEP_ALIVE)-2) { + header_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + index++; + if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { + header_state = h_general; + } else if (index == sizeof(CLOSE)-2) { + header_state = h_connection_close; + } + break; + + case h_transfer_encoding_chunked: + case h_connection_keep_alive: + case h_connection_close: + if (ch != ' ') header_state = h_general; + break; + + default: + state = s_header_value; + header_state = h_general; + break; + } + break; + } + + case s_header_almost_done: + header_almost_done: + { + STRICT_CHECK(ch != LF); + + state = s_header_field_start; + + switch (header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + break; + } + + case s_headers_almost_done: + headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + CALLBACK2(message_complete); + state = NEW_MESSAGE(); + break; + } + + nread = 0; + + if (parser->flags & F_UPGRADE || parser->method == PHP_HTTP_CONNECT) { + parser->upgrade = 1; + } + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + return p - data; /* Error */ + } + } + + /* Exit, the rest of the connect is in a different protocol. */ + if (parser->upgrade) { + CALLBACK2(message_complete); + return (p - data); + } + + if (parser->flags & F_SKIPBODY) { + CALLBACK2(message_complete); + state = NEW_MESSAGE(); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + state = s_chunk_size_start; + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + CALLBACK2(message_complete); + state = NEW_MESSAGE(); + } else if (parser->content_length > 0) { + /* Content-Length header given and non-zero */ + state = s_body_identity; + } else { + if (parser->type == PHP_HTTP_REQUEST || php_http_should_keep_alive(parser)) { + /* Assume content-length 0 - read the next */ + CALLBACK2(message_complete); + state = NEW_MESSAGE(); + } else { + /* Read body until EOF */ + state = s_body_identity_eof; + } + } + } + + break; + } + + case s_body_identity: + to_read = MIN(pe - p, (size_t)parser->content_length); + if (to_read > 0) { + if (settings->on_body) settings->on_body(parser, p, to_read); + p += to_read - 1; + parser->content_length -= to_read; + if (parser->content_length == 0) { + CALLBACK2(message_complete); + state = NEW_MESSAGE(); + } + } + break; + + /* read until EOF */ + case s_body_identity_eof: + to_read = pe - p; + if (to_read > 0) { + if (settings->on_body) settings->on_body(parser, p, to_read); + p += to_read - 1; + } + break; + + case s_chunk_size_start: + { + assert(parser->flags & F_CHUNKED); + + c = unhex[(unsigned char)ch]; + if (c == -1) goto error; + parser->content_length = c; + state = s_chunk_size; + break; + } + + case s_chunk_size: + { + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + state = s_chunk_size_almost_done; + break; + } + + c = unhex[(unsigned char)ch]; + + if (c == -1) { + if (ch == ';' || ch == ' ') { + state = s_chunk_parameters; + break; + } + goto error; + } + + parser->content_length *= 16; + parser->content_length += c; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + state = s_chunk_size_almost_done; + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + state = s_header_field_start; + } else { + state = s_chunk_data; + } + break; + } + + case s_chunk_data: + { + assert(parser->flags & F_CHUNKED); + + to_read = MIN(pe - p, (size_t)(parser->content_length)); + + if (to_read > 0) { + if (settings->on_body) settings->on_body(parser, p, to_read); + p += to_read - 1; + } + + if (to_read == parser->content_length) { + state = s_chunk_data_almost_done; + } + + parser->content_length -= to_read; + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != CR); + state = s_chunk_data_done; + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + state = s_chunk_size_start; + break; + + default: + assert(0 && "unhandled state"); + goto error; + } + } + + CALLBACK_NOCLEAR(header_field); + CALLBACK_NOCLEAR(header_value); + CALLBACK_NOCLEAR(fragment); + CALLBACK_NOCLEAR(query_string); + CALLBACK_NOCLEAR(path); + CALLBACK_NOCLEAR(url); + + parser->state = state; + parser->header_state = header_state; + parser->index = index; + parser->nread = nread; + + return len; + +error: + parser->state = s_dead; + return (p - data); +} + + +int +php_http_should_keep_alive (php_http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } else { + return 1; + } + } else { + /* HTTP/1.0 or earlier */ + if (parser->flags & F_CONNECTION_KEEP_ALIVE) { + return 1; + } else { + return 0; + } + } +} + + +const char * php_http_method_str (enum php_http_method m) +{ + return method_strings[m]; +} + + +void +php_http_parser_init (php_http_parser *parser, enum php_http_parser_type t) +{ + parser->type = t; + parser->state = (t == PHP_HTTP_REQUEST ? s_start_req : (t == PHP_HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->nread = 0; + parser->upgrade = 0; + parser->flags = 0; + parser->method = 0; +} diff --git a/vendor/swoole/thirdparty/php_http_parser.h b/vendor/swoole/thirdparty/php_http_parser.h new file mode 100755 index 0000000..2bf2356 --- /dev/null +++ b/vendor/swoole/thirdparty/php_http_parser.h @@ -0,0 +1,180 @@ +/* Copyright 2009,2010 Ryan Dahl <ry@tinyclouds.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +/* modified by Moriyoshi Koizumi <moriyoshi@php.net> to make it fit to PHP source tree. */ +#ifndef php_http_parser_h +#define php_http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + + +#include <sys/types.h> +#if defined(_WIN32) && !defined(__MINGW32__) +# include <windows.h> +# include "win32/php_stdint.h" +# include "config.w32.h" +#else +# include "php_config.h" +# ifdef HAVE_STDINT_H +# include <stdint.h> +# endif +#endif + +/* Compile with -DPHP_HTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef PHP_HTTP_PARSER_STRICT +# define PHP_HTTP_PARSER_STRICT 1 +#else +# define PHP_HTTP_PARSER_STRICT 0 +#endif + + +/* Maximium header size allowed */ +#define PHP_HTTP_MAX_HEADER_SIZE (80*1024) + + +typedef struct php_http_parser php_http_parser; +typedef struct php_http_parser_settings php_http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a PHP_HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * http_data_cb does not return data chunks. It will be call arbitrarally + * many times for each string. E.G. you might get 10 callbacks for "on_path" + * each providing just a few characters more data. + */ +typedef int (*php_http_data_cb) (php_http_parser*, const char *at, size_t length); +typedef int (*php_http_cb) (php_http_parser*); + + +/* Request Methods */ +enum php_http_method + { PHP_HTTP_DELETE = 0 + , PHP_HTTP_GET + , PHP_HTTP_HEAD + , PHP_HTTP_POST + , PHP_HTTP_PUT + , PHP_HTTP_PATCH + /* pathological */ + , PHP_HTTP_CONNECT + , PHP_HTTP_OPTIONS + , PHP_HTTP_TRACE + /* webdav */ + , PHP_HTTP_COPY + , PHP_HTTP_LOCK + , PHP_HTTP_MKCOL + , PHP_HTTP_MOVE + , PHP_HTTP_PROPFIND + , PHP_HTTP_PROPPATCH + , PHP_HTTP_UNLOCK + /* subversion */ + , PHP_HTTP_REPORT + , PHP_HTTP_MKACTIVITY + , PHP_HTTP_CHECKOUT + , PHP_HTTP_MERGE + /* upnp */ + , PHP_HTTP_MSEARCH + , PHP_HTTP_NOTIFY + , PHP_HTTP_SUBSCRIBE + , PHP_HTTP_UNSUBSCRIBE + /* unknown, not implemented */ + , PHP_HTTP_NOT_IMPLEMENTED + }; + + +enum php_http_parser_type { PHP_HTTP_REQUEST, PHP_HTTP_RESPONSE, PHP_HTTP_BOTH }; + + +struct php_http_parser { + /** PRIVATE **/ + unsigned char type : 2; + unsigned char flags : 6; + unsigned char state; + unsigned char header_state; + unsigned char index; + + uint32_t nread; + ssize_t content_length; + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned short status_code; /* responses only */ + unsigned char method; /* requests only */ + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + char upgrade; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct php_http_parser_settings { + php_http_cb on_message_begin; + php_http_data_cb on_path; + php_http_data_cb on_query_string; + php_http_data_cb on_url; + php_http_data_cb on_fragment; + php_http_data_cb on_header_field; + php_http_data_cb on_header_value; + php_http_cb on_headers_complete; + php_http_data_cb on_body; + php_http_cb on_message_complete; +}; + + +void php_http_parser_init(php_http_parser *parser, enum php_http_parser_type type); + + +size_t php_http_parser_execute(php_http_parser *parser, + const php_http_parser_settings *settings, + const char *data, + size_t len); + + +/* If php_http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns true, then this will be should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int php_http_should_keep_alive(php_http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *php_http_method_str(enum php_http_method); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/vendor/swoole/tools/arginfo_check.php b/vendor/swoole/tools/arginfo_check.php new file mode 100755 index 0000000..694aef5 --- /dev/null +++ b/vendor/swoole/tools/arginfo_check.php @@ -0,0 +1,19 @@ +<?php +// if no output, it means there is no mistake. +$list = array_filter(scandir(__DIR__.'/../'), function (string $name) { + return substr($name, -2, 2) === '.c'; +}); +array_walk($list, function (string $filename) { + $content = file_get_contents(__DIR__."/../{$filename}"); + preg_match_all( + '/ZEND_BEGIN_ARG_INFO_EX\(.+, (\d+?)\)\n([\s\S]*?)ZEND_END_ARG_INFO\(\)/', + $content, $arg_info_matches, PREG_SET_ORDER + ); + array_walk($arg_info_matches, function (array $arg_info) { + [$_, $arg_num, $arg_lines] = $arg_info; + $total_num = substr_count($arg_lines, "ZEND_ARG_"); + if ((int)$arg_num > $total_num) { + var_dump($_); + } + }); +}); \ No newline at end of file diff --git a/vendor/swoole/tools/check-package.php b/vendor/swoole/tools/check-package.php new file mode 100755 index 0000000..d382c54 --- /dev/null +++ b/vendor/swoole/tools/check-package.php @@ -0,0 +1,77 @@ +#!/usr/bin/env php +<?php +define('BASE_DIR', dirname(__DIR__)); +if (empty($argv[1])) +{ + $DIR = BASE_DIR . '/tests'; +} +else +{ + $DIR = BASE_DIR . '/' . $argv[1]; +} + +$role = empty($argv[2]) ? 'test' : 'src'; +$cmd = empty($argv[3]) ? 'list' : 'check'; + +$_files = []; +search($DIR, $_files); + +foreach ($_files as $f) +{ + $filename = str_replace($DIR . '/', '', $f); + if ($cmd == 'list') + { + echo '<file name="' . $filename . '" role="' . $role . '" />' . "\n"; + } + elseif ($cmd == 'check') + { + if (!inPackage($filename)) + { + echo "$filename\n"; + } + } +} + +function search($path, &$_files) +{ + $dirs = _scandir($path); + foreach ($dirs as $d) + { + $_path = $path . '/' . $d; + if (!is_dir($_path)) + { + $_files[] = $_path; + continue; + } + else + { + search($_path, $_files); + } + } +} + +function _scandir($dir) +{ + $list = scandir($dir); + return array_filter($list, function ($f) + { + return $f[0] !== '.'; + }); +} + +function inPackage($file) +{ + static $content = null; + if (!$content) + { + $content = file_get_contents(BASE_DIR . '/package.xml'); + } + if (strpos($content, $file) === false) + { + return false; + } + else + { + return true; + } +} diff --git a/vendor/swoole/tools/export.php b/vendor/swoole/tools/export.php new file mode 100755 index 0000000..ad084b1 --- /dev/null +++ b/vendor/swoole/tools/export.php @@ -0,0 +1,5 @@ +<?php +if ($argc == 1) { + die("Usage: php export.php [class_name]\n"); +} +ReflectionClass::export($argv[1]); diff --git a/vendor/swoole/tools/gen-data.php b/vendor/swoole/tools/gen-data.php new file mode 100755 index 0000000..1d33730 --- /dev/null +++ b/vendor/swoole/tools/gen-data.php @@ -0,0 +1,6 @@ +<?php +$fp = fopen(__DIR__ . "/a.txt", "w"); +ftruncate($fp, filesize(__DIR__ . "/a.txt")); +fwrite($fp, str_repeat('A', 1024)); +fwrite($fp, str_repeat('B', 1024)); +fwrite($fp, str_repeat('C', 256)."\n"); diff --git a/vendor/swoole/tools/ip.php b/vendor/swoole/tools/ip.php new file mode 100755 index 0000000..1b02247 --- /dev/null +++ b/vendor/swoole/tools/ip.php @@ -0,0 +1,10 @@ +<?php +if (empty($argv[1])) { + die("php ip.php sin_addr\n"); +} +$v = $argv[1]; +$n = unpack('Nip', $v); +$ip = long2ip($n['ip']); +$results = `curl http://freeapi.ipip.net/$ip`; +echo "IP: $ip, LOCATION: $results\n"; + diff --git a/vendor/swoole/travis/compile.sh b/vendor/swoole/travis/compile.sh new file mode 100755 index 0000000..fcc7d8c --- /dev/null +++ b/vendor/swoole/travis/compile.sh @@ -0,0 +1,3 @@ +#!/bin/sh +phpize && ./configure && make clean && make + diff --git a/vendor/wechat/composer.json b/vendor/wechat/composer.json new file mode 100755 index 0000000..c370e23 --- /dev/null +++ b/vendor/wechat/composer.json @@ -0,0 +1,36 @@ +{ + "name": "china-wangyu/wechat", + "description": "wechat PHP 微信 微信授权 微信用户信息 微信token 微信模板 微信自定义菜单生产 微信JDK 微信关键字回复 微信模板消息发送", + "keywords": [ + "wechat", + "performance", + "php" + ], + "homepage": "https://gitee.com/china_wangyu/wechat", + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "china-wangyu", + "email": "china-wangyu@aliyun.com", + "homepage": "https://gitee.com/china_wangyu/wechat", + "role": "Developer" + } + ], + "require":{ + "PHP" : ">= 7.0.0" + }, + "minimum-stability": "dev", + "autoload": { + "psr-4": { + "WeChat\\Core\\": "src/WeChat/Core", + "WeChat\\Extend\\": "src/WeChat/Extend" + } + }, + "repositories": { + "packagist": { + "type": "composer", + "url": "https://packagist.phpcomposer.com" + } + } +} diff --git a/vendor/wechat/composer.lock b/vendor/wechat/composer.lock new file mode 100755 index 0000000..c357147 --- /dev/null +++ b/vendor/wechat/composer.lock @@ -0,0 +1,19 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "eea659f6db5dde1a19624f61a5c833cc", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 7.0.0" + }, + "platform-dev": [] +} diff --git a/vendor/wechat/src/WeChat/Core/Authorize.php b/vendor/wechat/src/WeChat/Core/Authorize.php new file mode 100755 index 0000000..e30f7bc --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Authorize.php @@ -0,0 +1,321 @@ +<?php +namespace WeChat\Core; + + +/** + * Class Authorize 微信授权认证类 + * @package WeChat\Core + */ +abstract class Authorize extends Base implements \WeChat\Extend\Authorize +{ + + /** + * @var string $token 设置微信的认证字符 + */ + protected $token = 'dyjj'; + + /** + * @var string $appID 公众号appid + */ + protected $appid = static::$appid; + + /** + * @var string $appScret 公众号appSecret + */ + protected $appSecret = static::$appSecret; + + /** + * @var array $config 微信的数据集合 + */ + protected $config = []; + + /** + * @var array $userInfo 微信的数据集合 + */ + protected $userInfo = []; + + /** + * @var array $returnData 回复用户的消息数据 + */ + protected $returnData = array( + 'MsgType' => 'text', // 可选类型[text: 文本|image: 图片|voice: 语音|video: 视频|music: 音乐|news: 图文] + 'Title' => '', // 标题 + 'Content' => '', // 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示) + 'PicUrl' => '', // 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 + 'Url' => '', // 点击图文消息跳转链接 + 'MediaId' => '', // 通过素材管理中的接口上传多媒体文件,得到的id。 + 'Description' => '', // 视频消息的描述 + 'MusicURL' => '', // 音乐链接 + 'HQMusicUrl' => '', // 高质量音乐链接,WIFI环境优先使用该链接播放音乐 + 'ThumbMediaId' => '', // 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id + 'ArticleCount' => '', // 图文消息个数;当用户发送文本、图片、视频、图文、地理位置这五种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息 + 'Articles' => '', // 图文消息信息,注意,如果图文数超过限制,则将只发限制内的条数 + ); + + /** + * 设置与微信对接的TOKEN凭证字符 + * Authorize constructor. + * @param string $token 微信开发模式TOKEN字符串 + * @param string $appID 微信appid + * @param string $appScret 微信appScret + * @inheritdoc 详细文档:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=1833550478&lang=zh_CN + */ + public function __construct(string $token,string $appID,string $appScret) + { + // 这里填写的是你在微信上设置的TOKEN,但是必须保证与微信公众平台-接口配置信息一致 + if (!empty($token)) $this->token = $token; + if (!empty($appID)) $this->appid = $appID; + if (!empty($appScret)) $this->appSecret = $appScret; + } + + /** + * 微信授权 + */ + final public function index() + { + // 验证数据或回复用户 + (!isset($_REQUEST['echostr'])) ? $this->responseMsg() : $this->valid(); + } + + /** + * 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败。 + */ + final protected function valid() + { + $echoStr = $_REQUEST['echostr']; + if ($this->checkSignature()) { + echo $echoStr; + exit; + } + } + + /** + * 开发者通过检验signature对请求进行校验 + * @return bool + */ + final protected function checkSignature() + { + $tmpArr = array($this->token, $_REQUEST['timestamp'], $_REQUEST['nonce']); + sort($tmpArr); + $tmpStr = sha1(implode($tmpArr)); + return ($tmpStr == $_REQUEST['signature']) ? true: false; + } + + /** + * 公众号的消息推送,回复 + */ + final protected function responseMsg() + { + try{ + $postStr = file_get_contents("php://input"); + if (!empty($postStr)) { + $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); + + // 微信提醒数组 + $this->config = json_decode(json_encode($postObj), true); + + // 普通授权token + $resToken = Token::gain($this->appid, $this->appSecret); + + $this->userInfo = []; + if (isset($resToken['access_token'])){ + // 微信用户信息 + $this->userInfo = User::newUserInfo($resToken['access_token'], $this->config['FromUserName']); + } + + // 逻辑操作,需要更改逻辑的就在这个方法咯~ + $this->handle(); + + // 被动发送消息 + Send::trigger($this->config,$this->returnData); + } + }catch (\Exception $exception){ + $this->text($exception->getMessage()); + } + echo ''; + exit; + } + + /** + * 首次关注事件 + * @return mixed|void + */ + public function follow() + { + // TODO: Implement follow() method. + $sendMsg = '您好,感谢您关注,爱你么么哒~'; + $this->text($sendMsg); + } + + /** + * 扫码关注事件 + * @return mixed|void + */ + public function scanFollow() + { + // TODO: Implement scanFollow() method. + $this->text('扫码关注' . json_encode($this->config)); + } + + /** + * 点击事件 + * @return mixed|void + */ + public function click() + { + // TODO: Implement click() method. + $this->text('这个是用户点击事件~'. json_encode($this->config)); + } + + /** + * 扫码商品事件 + * @return mixed|void + */ + public function scanProduct() + { + // TODO: Implement scanProduct() method. + $this->text('用户商品扫码' . json_encode($this->config)); + } + + /** + * 扫码事件 + * @return mixed|void + */ + public function scan() + { + // TODO: Implement scan() method. + $this->text('扫码进入' . json_encode($this->config)); + } + + /** + * 用户输入 + * @return mixed|void + */ + public function input() + { + // TODO: Implement input() method. + $this->text('用户输入' . json_encode($this->config)); + } + + + /** + * 用户操作方法 + * @param \WeChat\Core\Authorize->returnData 返回数据数组 + * @param \WeChat\Core\Authorize->config 微信数据包 + * @return mixed + */ + final public function handle() + { + // TODO: Implement handle() method. + switch ($this->config['MsgType']){ + case $this->config['MsgType'] =='text': + $this->input(); + break; + case $this->config['Event'] == 'subscribe' : + $params = explode('_', trim($this->config['EventKey'])); // 扫码参数 + !isset($params[1]) ? + $this->follow() : // 搜索公众号或推荐公众号关注 + $this->scanFollow(); // 扫码关注 + break; + case $this->config['Event'] == 'user_scan_product_enter_session': // 用户商品扫码 + $this->scanProduct(); + break; + case $this->config['Event'] == 'CLICK': // 用户点击事件 + $this->click(); + break; + case $this->config['Event'] == 'SCAN': // 扫码进入 + $this->scan(); + break; + } + } + + /** + * 发送文本消息 + * @param string $content 回复的文本内容 + */ + final protected function text(string $content = '这是个友好的回复~') + { + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['Content'] = $content; + } + + /** + * 发送图片消息 + * @param string $mediaId 素材ID + */ + final protected function image(string $mediaId) + { + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['MediaId'] = $mediaId; + } + + /** + * 发送语音消息 + * @param string $mediaId 素材ID + */ + final protected function voice(string $mediaId) + { + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['MediaId'] = $mediaId; + } + + /** + * 发送视频消息 + * @param string $mediaId 素材ID + * @param string $title 视频标题 + * @param string $description 视频消息的描述 + */ + final protected function video(string $mediaId,string $title = '这是一个标题',string $description = '消息的描述') + { + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['MediaId'] = $mediaId; + $this->returnData['Title'] = $title; + $this->returnData['Description'] = $description; + } + + /** + * 发送音乐消息 + * @param string $title 消息标题 + * @param string $description 描述 + * @param string $musicURL 音乐链接 + * @param string $HQMusicUrl 高清音乐URL + * @param string $ThumbMediaId 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id + */ + final protected function music(string $title = '这是一个标题',string $description = '消息的描述', + string $musicURL = '', string $HQMusicUrl = '', string $ThumbMediaId = '') + { + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['Title'] = $title; + $this->returnData['Description'] = $description; + $this->returnData['MusicURL'] = $musicURL; + $this->returnData['HQMusicUrl'] = $HQMusicUrl; + $this->returnData['ThumbMediaId'] = $ThumbMediaId; + } + + + /** + * 发送图文消息 + * @param array $Articles 图文数组 + * @format 格式 $Articles = array( + array( + 'Title'=>'标题', + 'Description'=>'注释', + 'PicUrl'=>'图片地主(含域名的全路径:图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200)', + 'Url'=>'点击图文消息跳转链接' + ), + ); + */ + final protected function news(array $Articles = []) + { + if (!isset($Articles[0]['Title'])) { + echo ''; + die; + } + $this->returnData['MsgType'] = __FUNCTION__; + $this->returnData['ArticleCount'] = count($Articles); + $this->returnData['Articles'] = $Articles; + } + + + +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Core/Base.php b/vendor/wechat/src/WeChat/Core/Base.php new file mode 100755 index 0000000..3c7c9a1 --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Base.php @@ -0,0 +1,14 @@ +<?php +namespace WeChat\Core; + +/** + * Class WxBase 抽象公用静态方法类 + * @package wechat + */ +abstract class Base +{ + use \WeChat\Extend\Tool; + + protected static $appid = 'wx2b29f5846b8d00fa'; + protected static $appSecret = 'd8b93b7e2b175b904c435cb493b66ff8'; +} diff --git a/vendor/wechat/src/WeChat/Core/Menu.php b/vendor/wechat/src/WeChat/Core/Menu.php new file mode 100755 index 0000000..b7eb569 --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Menu.php @@ -0,0 +1,147 @@ +<?php +namespace WeChat\Core; + + +/** + * Class Menu 微信菜单类 + * @package WeChat\Core + */ +class Menu extends Base +{ + // 获取菜单 + private static $getMenuUrl = 'https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=ACCESS_TOKEN'; + + // 设置菜单 + private static $setMenuUrl = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN'; + + /** + * 获取菜单 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141014 + * @param string $accessToken + * @return array|bool + */ + public static function gain(string $accessToken) + { + // 拼装获取菜单链接 + $getMenuUrl = str_replace('ACCESS_TOKEN', $accessToken, static::$getMenuUrl); + + // 发送获取菜单,获取结果 + return self::get($getMenuUrl); + } + + /** + * 删除菜单 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141015 + * @param string $accessToken + * @return array|bool + */ + public static function delete(string $accessToken) + { + // 拼装获取菜单链接 + $getMenuUrl = str_replace('ACCESS_TOKEN', $accessToken, static::$getMenuUrl); + + // 发送获取菜单,获取结果 + return self::get($getMenuUrl); + } + + + /** + * 设置菜单 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013 + * @param string $accessToken + * @param array $menu + 例如:$menu =[ + [ + 'type'=> 'click', // + 'name'=> '这是第一级button', + 'list' => [ + [ + 'type'=> 'view', + 'name'=> '百度', + 'url' => 'http://www.baidu.com', + ] + ], + ], + [ + 'type'=> 'miniprogram', + 'name'=> 'xx小程序', + 'url' => 'http://www.baidu.com', + 'appid' => 'asdasdas', 小程序APPID + 'pagepath' => '/page/index/index', // 小程序页面链接 + ] + ]; + + * @return array + */ + public static function set(string $accessToken, array $menu) + { + (!is_array($menu) or count($menu) < 1) && self::error('请设置正确的参数 $menu ~ !'); + + // 组装参数 + $format_param['button'] = self::format($menu); + + // 替换token + $setMenuUrl = str_replace('ACCESS_TOKEN', $accessToken, static::$setMenuUrl); + + // 生成菜单 + return self::post($setMenuUrl, json_encode($format_param, JSON_UNESCAPED_UNICODE)); + } + + + /** + * 格式化菜单数组 + * @param array $menu 菜单数组 + * @return array + */ + public static function format(array $menu) + { + $button =[]; + foreach ($menu as $key => $val) { + + if (!isset($val['list'])) { + $button[$key] = static::getTypeParam($val['type'],$val); + } else { + $button[$key]['name'] = $val['name']; + $button[$key]['sub_button'] = static::format($val['list']); + } + } + return $button; + } + + + /** + * 获取自定义菜单参数 + * @param string $type 类型 + * @param array $item 数组 + * @return array + */ + private static function getTypeParam(string $type,array $item) + { + switch (strtolower($type)) + { + case 'click': + return array( + 'type' => 'click', + 'name' => $item['name'], + 'key' => $item['name'], // 关键词 + ); + break; + case 'view': + return array( + 'type' => 'view', + 'name' => $item['name'], + 'url' => $item['url'], // 原文链接 + ); + break; + case 'miniprogram': // 小程序 + return array( + 'type' => 'miniprogram', + 'name' => $item['name'], // 菜单名称 + 'url' => $item['url'], // 小程序链接 + 'appid' => $item['appid'], // 小程序APPID + 'pagepath' => $item['pagepath'], // 小程序页面路径 + ); + break; + } + } +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Core/QrCode.php b/vendor/wechat/src/WeChat/Core/QrCode.php new file mode 100755 index 0000000..9e3ee86 --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/QrCode.php @@ -0,0 +1,94 @@ +<?php +namespace WeChat\Core; + +include(__DIR__.'/../Lib/phpqrcode.php'); + +/** + * Class Qrcode 二维码类 + * @package wechat + */ +class QrCode extends Base +{ + // 获取微信公众二维码(永久/有效时长) + private static $setQrCodeUrl = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN'; + + + // 显示微信公众号二维码 + private static $showqrcodeUrl = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=JSAPI_TICKET'; + + + /** + * 生成二维码 + * @inheritdoc 文档说明:http://phpqrcode.sourceforge.net/ + * @param string $text 二维码内容 + * @param bool $filePath 二维码储存路径 + * @param string $level 二维码容错机制 + * @param int $size 点大小 + * @param int $margin 点间距 + * @param bool $saveandprint 保存或打印 + * @return string|void + */ + public static function create(string $text = '', + bool $filePath = false, + string $level = QR_ECLEVEL_L, + int $size = 6, + int $margin = 2, + bool $saveandprint=false) + { + try { + if ($filePath !== false) { + // Save it to a file + if (!is_dir(dirname($filePath))) { + mkdir(dirname($filePath), 755); + } + } + return \QRcode::png($text,$filePath,$level,$size,$margin,$saveandprint); + } catch (\WeChat\Extend\Json $exception) { + return $exception->getMessage(); + } + + } + + /** + * 创建微信带参二维码生成 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542 + * @param string $accessToken 授权TOKEN + * @param string $scene_str 字符串 + * @param string $scene_str_prefix 字符串前缀 + * @param int $type 二维码类型:(小于等于1) = 有效时长30天 (大于等于2) = 永久 + * @return array|bool|mixed + */ + public static function wechat(string $accessToken,string $scene_str, string $scene_str_prefix = 'wene_', int $type = 1) + { + $result = false; + // 验证微信普通token + empty($accessToken) && $accessToken = Token::gain(); + + //创建加密字符 + $strLen = strlen($scene_str) + strlen($scene_str_prefix); + + // 验证字符长度 + if ($strLen <= 64 and $strLen > 1) { + // 准备参数 + $setQrCodeUrl = str_replace('TOKEN', $accessToken, static::$setQrCodeUrl); + + $qrCodeParam['action_name'] = "QR_LIMIT_STR_SCENE"; + if(intval($type) <= 1){ + $qrCodeParam['action_name'] = "QR_STR_SCENE"; + $qrCodeParam['expire_seconds'] = 604800; + } + $qrCodeParam['action_info'] = [ + 'scene'=> ['scene_str'=> $scene_str_prefix . $scene_str], + ]; + $qrCodeParam = json_encode($qrCodeParam,JSON_UNESCAPED_UNICODE); + + // 获取对应数据 + $result = self::post($setQrCodeUrl, $qrCodeParam); + if (isset($result['ticket'])) { + $result['showUrl'] = str_replace('JSAPI_TICKET',$result['ticket'],static::$showqrcodeUrl); + } + } + // 返回结果 + return $result; + } +} diff --git a/vendor/wechat/src/WeChat/Core/Send.php b/vendor/wechat/src/WeChat/Core/Send.php new file mode 100755 index 0000000..dfb6e0d --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Send.php @@ -0,0 +1,214 @@ +<?php +namespace WeChat\Core; + + +/** + * Class WxSend 微信推送类 + * @package wechat + */ +class Send extends Base +{ + // 微信发送模板消息API + private static $setMsgUrl = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN'; + + // 被动回复微信数据 + protected static $triggerConfig; + + // 被动回复用户数据 + protected static $triggerData; + + // 被动回复消息模板 + protected static $triggerTemplate; + + // 被动回复消息模板公共部分 + protected static $triggerTemplateStart = '<ToUserName><![CDATA[%s]]></ToUserName> + <FromUserName><![CDATA[%s]]></FromUserName> + <CreateTime>%s</CreateTime> + <MsgType><![CDATA[%s]]></MsgType>'; + + /** + * 被动回复消息 + * @param array $triggerConfig 微信消息对象 + * @param array $triggerData 用户数据 + * @throws \Exception + */ + public static function trigger(array $triggerConfig = [], array $triggerData = []) + { + static::$triggerConfig = $triggerConfig; + static::$triggerData = $triggerData; + + try { + static::$triggerTemplateStart = sprintf(static::$triggerTemplateStart, static::$triggerConfig['FromUserName'], static::$triggerConfig['ToUserName'], + time(), static::$triggerData['MsgType']); + static::setTriggerMsgTemplate(); + echo static::$triggerTemplate; + die; + } catch (\Exception $exception) { + static::$triggerTemplateStart = sprintf(static::$triggerTemplateStart, static::$triggerConfig['FromUserName'], static::$triggerConfig['ToUserName'], + time(), 'text'); + static::$triggerData['Content'] = $exception->getMessage(); + static::setTriggerMsgTemplate(); + echo static::$triggerTemplate; + die; + } + } + + + /** + * 主动发送模板消息 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277 + * @param string $accessToken + * @param string $pushTemplateId 模板ID + * @param string $openid 用户openid + * @param array $pushData 模板参数 + * @param string $url 模板消息链接 + * @param string $topColor 微信top颜色 + * @return array + */ + public static function push(string $accessToken, string $pushTemplateId, string $openid, array $pushData = [], + string $url = '', string $topColor = '#FF0000') + { + // 检测参数 + if (empty($pushData) or empty($openid) or empty($pushTemplateId)) { + self::error('请设置正确的参数 $triggerTemplate or $value~ !'); + } + + // 准备数据 + $pushTemplate['template_id'] = $pushTemplateId; + $pushTemplate['touser'] = $openid; + $pushTemplate['url'] = empty($url) ? '' : $url; + $pushTemplate['topcolor'] = empty($topColor) ? '' : $topColor; + $pushTemplate['data'] = $pushData; + $send_url = str_replace('ACCESS_TOKEN', $accessToken, static::$setMsgUrl); + + // 发送请求,并返回 + return self::post($send_url, json_encode($pushTemplate, JSON_UNESCAPED_UNICODE)); + } + + + /** + * 设置被动消息模板 + * @param string $type 属性,可选类型[text: 文本|image: 图片|voice: 语音|video: 视频|music: 音乐|news: 图文] + * @inheritdoc 微信消息文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543 + * @throws \Exception + */ + protected static function setTriggerMsgTemplate() + { + $msgType = static::$triggerData['MsgType']; + switch ($msgType) { + case 'text': + self::setTriggerTextMsgTemplate(); + break; + case 'image': + self::setTriggerImageMsgTemplate(); + break; + case 'voice': + self::setTriggerVoiceMsgTemplate(); + break; + case 'video': + self::setTriggerVideoMsgTemplate(); + break; + case 'music': + static::setTriggerMusicMsgTemplate(); + break; + case 'news': + static::setTriggerNewsMsgTemplate(); + break; + default : + self::setTriggerTextMsgTemplate(); + break; + } + } + + /** + * 设置文本消息 + * @throws \Exception + */ + private static function setTriggerTextMsgTemplate() + { + $msgTemplate = '<Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + static::$triggerTemplate = sprintf(static::$triggerTemplate, static::$triggerData['Content']); + } + + /** + * 设置图片消息 + * @throws \Exception + */ + private static function setTriggerImageMsgTemplate() + { + $msgTemplate = '<Image><MediaId><![CDATA[%s]]></MediaId></Image>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + static::$triggerTemplate = sprintf(static::$triggerTemplate, static::$triggerData['MediaId']); + } + + /** + * 设置语音消息 + * @throws \Exception + */ + private static function setTriggerVoiceMsgTemplate() + { + $msgTemplate = '<Voice><MediaId>< ![CDATA[%s]]></MediaId></Voice>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + static::$triggerTemplate = sprintf(static::$triggerTemplate, static::$triggerData['MediaId']); + } + + /** + * 设置视频消息 + * @throws \Exception + */ + private static function setTriggerVideoMsgTemplate() + { + $msgTemplate = '<Video><MediaId><![CDATA[%s]]></MediaId><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description></Video>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + static::$triggerTemplate = sprintf(static::$triggerTemplate, static::$triggerData['MediaId'], static::$triggerData['Title'], static::$triggerData['Description']); + } + + /** + * 设置音乐消息 + * @throws \Exception + */ + private static function setTriggerMusicMsgTemplate() + { + $msgTemplate = '<Music> + <Title><![CDATA[%s]]></Title> + <Description><![CDATA[%s]]></Description> + <MusicUrl><![CDATA[%s]]></MusicUrl> + <HQMusicUrl><![CDATA[%s]]></HQMusicUrl> + <ThumbMediaId><![CDATA[%s]]></ThumbMediaId> + </Music>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + static::$triggerTemplate = sprintf(static::$triggerTemplate, static::$triggerData['Title'], static::$triggerData['Description'], + static::$triggerData['MusicUrl'], static::$triggerData['HQMusicUrl'], static::$triggerData['ThumbMediaId']); + } + + /** + * 设置图文消息 + * @throws \Exception + */ + private static function setTriggerNewsMsgTemplate() + { + $newCount = count(static::$triggerData['Articles']); + if ($newCount < 1) throw new \Exception('图文消息发送失败,请检查数据结构~'); + try { + $msgTemplate = "<ArticleCount>'.$newCount.'</ArticleCount>"; + $msgTemplate .= "<Articles>"; + foreach (static::$triggerData['Articles'] as $article) { + $msgTemplate .= '<item> + <Title><![CDATA[%s]]></Title> + <Description><![CDATA[%s]]></Description> + <PicUrl><![CDATA[%s]]></PicUrl> + <Url><![CDATA[%s]]></Url> + </item>'; + $msgTemplate = sprintf($msgTemplate, $article['Title'], $article['Description'], + $article['PicUrl'], $article['Url']); + } + + $msgTemplate .= '</Articles>'; + static::$triggerTemplate = '<xml>' . static::$triggerTemplateStart . $msgTemplate . '</xml>'; + } catch (\Exception $exception) { + throw new \Exception('图文消息发送失败,错误信息:' . $exception->getMessage()); + } + + } +} diff --git a/vendor/wechat/src/WeChat/Core/Template.php b/vendor/wechat/src/WeChat/Core/Template.php new file mode 100755 index 0000000..11fba3c --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Template.php @@ -0,0 +1,57 @@ +<?php +namespace WeChat\Core; + +/** + * Class WxTemplate 微信模板类 + * @package wechat + */ +class Template extends Base +{ + // 微信获取所有模板api + private static $getTemplateUrl = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=TOKEN'; + + /** + * 格式化消息模板内容 + * @param array $template 模板内容 + * @return array 消息模板内容 + */ + public static function format($template = []) + { + $param = self::trim_template($template['content']); + $template['param'] = [ + 'touser' => '', // 用户OPENID + 'template_id' => $template['template_id'], //模板ID + 'url' => '', // 跳转的url地址 + 'topcolor' => '', + 'data' => $param, //模板必须参数 + ]; + return $template; + } + + /** + * 获取所有消息模板内容 + * @inheritdoc 详细文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277 + * @param string $accessToken 微信token + * @return array + */ + public static function gain(string $accessToken) + { + static::$getTemplateUrl = str_replace('TOKEN',$accessToken,static::$getTemplateUrl); + return self::get(static::$getTemplateUrl); + } + + /** + * 获取模板需要的参数name + * @param string $string 过滤包含参数的字符串 + * @return array 不带其它字符的参数数组 + */ + private static function trim_template(string $string) + { + $string = preg_replace('/([\x80-\xff]*)/i', '', $string); + $trim = array(" ", " ", "\t", "\n", "\r", '.DATA', '}}'); + $arr = explode('{{', str_replace($trim, '', $string)); + unset($arr[0]); + return array_values($arr); + } + +} diff --git a/vendor/wechat/src/WeChat/Core/Ticket.php b/vendor/wechat/src/WeChat/Core/Ticket.php new file mode 100755 index 0000000..9db037b --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Ticket.php @@ -0,0 +1,71 @@ +<?php +namespace WeChat\Core; + +/** + * Class WxTicket 微信ticket类 含签名生成 + * @package wechat + */ +class Ticket extends Base +{ + // 微信ticket (jsapi) + private static $getTicketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi'; + + /** + * 设置微信ticket + * @param string $accessToken 微信普通token + * @return bool 微信 ticket|false + */ + public static function gain(string $accessToken) + { + $param = \WeChat\Extend\File::param('ticket'); + if ($param === null or empty($param)) { + + // 准备数据 + static::$getTicketUrl = str_replace('ACCESS_TOKEN',$accessToken,static::$getTicketUrl); + $result = self::get(static::$getTicketUrl); + + // 返回数据 + isset($result['ticket']) && \WeChat\Extend\File::param('ticket', $result); + return $result; + } else { + return $param['ticket']; + } + } + + + /** + * 获取微信JSDK + * @param string $ticket 获取微信JSDK签名 + * @param string $redirect_url 微信JSDK + * @return mixed + */ + public static function sign(string $ticket, string $redirect_url = '') + { + $url = empty($redirect_url) ? $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] : $redirect_url; + $timestamp = time(); + $nonceStr = self::createNonceStr(); + $string = 'jsapi_ticket=' . $ticket . '&noncestr=' . $nonceStr . '&timestamp=' . $timestamp . '&url=' . $url; + $param['rawString'] = $string; + $param['signature'] = sha1($param['rawString']); + $param['nonceStr'] = $nonceStr; + $param['timestamp'] = $timestamp; + $param['url'] = $url; + return $param; + } + + + /** + * 创建随机字符微信版本 + * @param int $length + * @return string + */ + private static function createNonceStr($length = 16) + { + $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + $str = ""; + for ($i = 0; $i < $length; $i++) { + $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); + } + return $str; + } +} diff --git a/vendor/wechat/src/WeChat/Core/Token.php b/vendor/wechat/src/WeChat/Core/Token.php new file mode 100755 index 0000000..157c735 --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/Token.php @@ -0,0 +1,49 @@ +<?php +namespace WeChat\Core; + +/** + * Class WxToken 微信Token类 + * @package wechat + */ +class Token extends Base +{ + // 获取token API地址 + private static $getTokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET'; + + /** + * [gain 获取微信access_token] + * @param string $appid [微信AppID] + * @param string $appSecret [微信AppSecret] + * @return [string] [微信access_token] + */ + public static function gain() + { + $appid = static::$appid; + $appSecret = static::$appSecret; + $param = \WeChat\Extend\File::param('access_token'); + if ($param === null or (isset($param['time']) and time() - $param['time'] > 7150)) { + // 进行微信AppID 和 AppSecret的验证 + if(empty($appid) or empty($appSecret)){ + self::error('请设置管理端微信公众号开发者APPID 和 APPSECRET~ !'); + } + + // 获取参数验证规则 + if (strlen(trim($appid)) != 18 or strlen(trim($appSecret)) != 32) { + self::error('请设置正确格式的微信公众号开发者APPID 和 APPSECRET~ !'); + } + + // 准备数据 + static::$getTokenUrl = str_replace('APPID', $appid, static::$getTokenUrl); + static::$getTokenUrl = str_replace('APPSECRET', $appSecret, static::$getTokenUrl); + + // 返回结果 + $result = self::get(static::$getTokenUrl); + isset($result['access_token']) && \WeChat\Extend\File::param('access_token', $result); + return $result; + } else { + return $param['access_token']; + } + self::error('扩展文件夹权限不足~ !'); + } + +} diff --git a/vendor/wechat/src/WeChat/Core/User.php b/vendor/wechat/src/WeChat/Core/User.php new file mode 100755 index 0000000..3fd6128 --- /dev/null +++ b/vendor/wechat/src/WeChat/Core/User.php @@ -0,0 +1,98 @@ +<?php +namespace WeChat\Core; + +/** + * Class WxUser 微信用户类 + * @package wechat + */ +class User extends Base +{ + // 第一步:用户同意授权,获取code + private static $getCodeUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=state&connect_redirect=1#wechat_redirect'; + + // 第二步:通过code换取网页授权access_token + private static $getOpenIdUrl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code'; + + // 第三步:拉取用户信息(需scope为 snsapi_userinfo) + private static $getUserInfoUrl = 'https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN'; + + // 第四步:拉取用户信息(普通access_token版) + private static $getUserInfoUrlByToken = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN'; + + /** + * [] + * @param string $appid [] + * + */ + + /** + * code 重载http,获取微信授权 * + * @header 重载链接获取code + */ + public static function code() + { + + empty(static::$appid) && self::error('请设置管理端微信公众号开发者APPID ~ !'); + //当前域名 + $service_url = urlencode($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + + static::$getCodeUrl = str_replace('APPID',static::$appid,static::$getCodeUrl); + static::$getCodeUrl = str_replace('REDIRECT_URI',$service_url,static::$getCodeUrl); + self::header(static::$getCodeUrl); + } + + /** + * 获取用户 OPENID + * @param string $code 微信授权CODE + * @param bool $type true:获取用户信息 | false:用户openid + * @return array 用户信息|用户openid + */ + public static function openid(string $code, bool $type = false) + { + //验证参数 + (empty(static::$appid) or empty(static::$appSecret)) && self::error('请设置管理端微信公众号开发者APPID 和 APPSECRET~ !'); + empty($code) && self::error('请验证是否传了正确的参数 code ~ !'); + + //获取用户数据 + static::$getOpenIdUrl = str_replace('APPID',static::$appid,static::$getOpenIdUrl); + static::$getOpenIdUrl = str_replace('SECRET',static::$appSecret,static::$getOpenIdUrl); + static::$getOpenIdUrl = str_replace('CODE',$code,static::$getOpenIdUrl); + + $result = self::get(static::$getOpenIdUrl); + + return $type == false ? $result : self::userinfo($result['access_token'], $result['openid']); + } + + + /** + * 获取用户信息(通过code换取网页授权access_token版) + * @param string $access_token 授权获取用户关键参数:access_token + * @param string $openid 用户openid + * @return array + */ + public static function userInfo(string $access_token, string $openid) + { + (empty($access_token) or empty($openid)) && self::error('getOpenid()方法设置参数~ !'); + + static::$getUserInfoUrl = str_replace('ACCESS_TOKEN',$access_token,static::$getUserInfoUrl); + static::$getUserInfoUrl = str_replace('OPENID',$openid,static::$getUserInfoUrl); + + return self::get(static::$getUserInfoUrl); + } + + /** + * 获取用户信息(普通ACCESS_TOKEN获取版) + * @param string $access_token 普通access_token + * @param string $openid 用户openid + * @return array + */ + public static function newUserInfo(string $openid) + { + (empty(static::$access_token) or empty($openid)) && self::error('getOpenid()方法设置参数~ !'); + + static::$getUserInfoUrlByToken = str_replace('ACCESS_TOKEN',static::$access_token,static::$getUserInfoUrlByToken); + static::$getUserInfoUrlByToken = str_replace('OPENID',$openid,static::$getUserInfoUrlByToken); + + return self::get(static::$getUserInfoUrlByToken); + } +} diff --git a/vendor/wechat/src/WeChat/Extend/Authorize.php b/vendor/wechat/src/WeChat/Extend/Authorize.php new file mode 100755 index 0000000..439f25e --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/Authorize.php @@ -0,0 +1,57 @@ +<?php +namespace WeChat\Extend; + + +/** + * 微信授权接口 + * Interface Authorize + * @package WeChat\Extend + */ +interface Authorize +{ + + /** + * 首次关注 + * @param \WeChat\Core\Authorize->returnData 返回数据数组 + * @param \WeChat\Core\Authorize->config 微信数据包 + * @return mixed + */ + public function follow(); + + /** + * 扫码关注 + * @param \WeChat\Core\Authorize->returnData 返回数据数组 + * @param \WeChat\Core\Authorize->config 微信数据包 + * @return mixed + */ + public function scanFollow(); + + /** + * 点击事件 + * @param \WeChat\Core\Authorize->returnData 返回数据数组 + * @param \WeChat\Core\Authorize->config 微信数据包 + * @return mixed + */ + public function click(); + + /** + * 扫描商品 + * @param \WeChat\Core\Authorize->returnData 返回数据数组 + * @param \WeChat\Core\Authorize->config 微信数据包 + * @return mixed + */ + public function scanProduct(); + + /** + * 扫码事件 + * @return mixed + */ + public function scan(); + + + /** + * 用户输入 + * @return mixed + */ + public function input(); +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Extend/File.php b/vendor/wechat/src/WeChat/Extend/File.php new file mode 100755 index 0000000..ba714d0 --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/File.php @@ -0,0 +1,81 @@ +<?php +namespace WeChat\Extend; + +/** + * Class File 微信存储类 + * @package wechat\lib + */ +class File +{ + + /** + * 定义常量 / 路径连接符 + */ + private static $ext = '/'; + + /** + * 存储对象文件,可扩展 + * @param string $var + * @param array $val + * @return null + */ + public static function param(string $var, array $val = []) + { + $file_path = self::mkdir('param'); + $fileCont = json_decode(file_get_contents($file_path), true); + if(empty($fileCont) and empty($val)) return null; + if(!empty($val) and !empty($var)){ + $val['time'] = time(); + $fileCont[$var] = $val; + file_put_contents($file_path,json_encode($fileCont)); + } + if(!empty($val) and empty($var)){ + if ($fileCont[$var]['time'] - time() <= 7100){ + unset($fileCont[$var]['time']); + if (!empty($fileCont[$var])) return $fileCont[$var]; + } + return null; + } + } + + /** + * 支付日志 + * @param string $type + * @param array $param + * @return mixed + */ + public static function paylog(string $type = 'wechat', array $param = []) + { + $file_path = self::mkdir('wechat'); + if (!empty($type) and empty($param)) { + return json_decode(file_get_contents($file_path), true); + } + $data = '['.date('Y-m-d H:i:s').'] => '.json_encode($param) . PHP_EOL; + file_put_contents($file_path, $data, FILE_APPEND); + } + + + + /** + * 创建日志类型文件 + * @param string $type + * @return string + */ + private static function mkdir(string $type = 'param') + { + $file_dir = dirname(__FILE__) . static::$ext . 'log' ; + (!is_dir($file_dir)) && mkdir($file_dir, 0755); + $file_dir .= static::$ext . date('Y-m-d-H') . static::$ext; + if ($type == 'param') { + $file_dir = dirname(__FILE__) . static::$ext . 'log' . static::$ext . 'param' . static::$ext; + } + + $file_name = $type . '.log'; + (!is_dir($file_dir)) && mkdir($file_dir, 0755); + + if (!is_file($file_dir . $file_name)) { + file_put_contents($file_dir . $file_name, ''); + } + return $file_dir . $file_name; + } +} diff --git a/vendor/wechat/src/WeChat/Extend/Json.php b/vendor/wechat/src/WeChat/Extend/Json.php new file mode 100755 index 0000000..a6da583 --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/Json.php @@ -0,0 +1,59 @@ +<?php +namespace WeChat\Extend; + +use Throwable; + +/** + * Class Json json输出类 + * @package wechat\lib + */ +class Json extends \Exception +{ + public function __construct(string $message = "", int $code = 0, Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + } + + /** + * 请求失败 + * @param string $msg + */ + public static function error(string $msg = '请求失败') + { + self::return_abnormal(400, $msg); + } + + /** + * 请求成功 + * @param string $msg 返回消息 + * @param array $data 返回data数据 + */ + public static function success(string $msg = '请求成功', array $data = []) + { + self::return_abnormal(200, $msg, $data); + } + + + /** + * 输出JSON + * @param int $code 状态码 + * @param string $msg 原因 + * @param array $data 输出数据 + */ + public static function return_abnormal(int $code,string $msg,array $data = []) + { + $code_state = $code == 200 ? 'OK' : 'Bad Request'; + $param = [ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + ]; + + header("HTTP/1.1 " . $code . " " . $code_state); + header('Content-Type:application/json;charset=utf-8'); + if ($param !== null) { + echo json_encode($param, JSON_UNESCAPED_UNICODE); + } + exit(); + } +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Extend/Request.php b/vendor/wechat/src/WeChat/Extend/Request.php new file mode 100755 index 0000000..8701b8b --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/Request.php @@ -0,0 +1,119 @@ +<?php +namespace WeChat\Extend; + +/** + * Class Request 请求类 + * @package wechat\lib + */ +class Request +{ + /** + * 支持请求类型 + * @var array $methods + */ + private static $methods = ['get','post']; + + /** + * 发送 header 请求 + * @param string $url 请求链接 + * @param array $params 请求参数 + */ + public static function header(string $url,array $params = []):void + { + if (!empty($params)) $url .= static::ToUrlParams($params); + header('Location: ' . $url); + exit(); + } + + /** + * 发送 <script>window.top.location.href</script> 请求 + * @param string $url + * @param array $params + */ + public static function jump(string $url,array $params = []) + { + if (!empty($params)) $url .= static::ToUrlParams($params); + exit( '<script>window.top.location.href='.$url.'</script>'); + } + + /** + * 发送curl请求 + * @param string $method 【类型 : get | post】 + * @param string $url 请求链接 + * @param array $params 请求参数 + * @return array + */ + public static function request(string $method,string $url, $params = []):array + { + $method = strtolower($method); + $isHttp = stristr($url,'https') ? true : false; + if (!in_array($method,static::$methods)) Json::error('请求类型错误~'); + if ($method === 'get' and !empty($params)) $url .= static::ToUrlParams($params); + return static::curl_request($url,$isHttp,$method,$params); + } + + /** + * [curl_request 发送http请求] + * @param [url] $url [请求地址] + * @param boolean $https [是否使用HTTPS] + * @param string $method [请求方式:GET / POST] + * @param [array] $data [post 数据] + * @return [result] [成功返回对方返回的结果,是非返回false] + */ + public static function curl_request($url, $https = false, $method = 'get', $data = null) + { + /**************** 初始化curl ******************/ + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //结果为字符串且输出到屏幕上 + /**************** 发送 https请求 ******************/ + if ($https === true) { + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + } + /******** 发送 POST 请求 类型为:application/x-www-form-urlencoded **********/ + if ($method == 'post') { + curl_setopt($ch, CURLOPT_POST, 1); //post提交方式 + curl_setopt($ch, CURLOPT_HEADER, 0); //设置header + // 所需传的数组用 http_build_query() 函数处理一下,就可以传递二维数组了 + if (is_array($data) and count($data) > 0) $data = http_build_query($data); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + } else { + curl_setopt($ch, CURLOPT_TIMEOUT, 500); + } + /**************** 发送请求 ******************/ + curl_setopt($ch, CURLOPT_URL, $url); + $result = curl_exec($ch); + $url_status = curl_getinfo($ch); + /**************** 关闭连接 并 返回数据 ******************/ + curl_close($ch); + + if (intval($url_status["http_code"]) == 200){ + if (json_decode($result,true) != false){ + return json_decode($result,true); + } + return $result; + } + return false; + } + + + + /** + * + * 拼接签名字符串 + * @param array $urlObj + * + * @return 返回已经拼接好的字符串 + */ + public static function ToUrlParams($urlObj) + { + $buff = "?"; + foreach ($urlObj as $k => $v) { + if ($k != "sign") { + $buff .= $k . "=" . $v . "&"; + } + } + $buff = trim($buff, "&"); + return $buff; + } +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Extend/Tool.php b/vendor/wechat/src/WeChat/Extend/Tool.php new file mode 100755 index 0000000..3eab558 --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/Tool.php @@ -0,0 +1,179 @@ +<?php +namespace WeChat\Extend; + +/** + * Trait Tool 工具类 + * @package wechat\lib + */ +trait Tool +{ + /** + * 接口 json 成功输出 + * @param string $msg 输出内容,输出参数~ + * @param array $data + */ + + public static function success($msg = '操作成功', array $data = []) + { + if (is_array($msg)){ + Json::success('操作成功~', $data); + } + Json::success($msg, $data); + } + + /** + * 接口 json 失败输出 + * @param string $msg + */ + public static function error(string $msg = '操作失败') + { + Json::error($msg); + } + + /** + * 重载路由 + * @param string $url + * @param array $params + */ + public static function header(string $url, array $params = []): void + { + Request::header($url, $params); + } + + /** + * curl 发送 POST 请求 + * @param string $url + * @param array $params + * @return array + */ + public static function post(string $url,$params = []) + { + return Request::request('POST',$url,$params); + } + + /** + * curl 发送 GET 请求 + * @param string $url + * @param array $params + * @return array + */ + public static function get(string $url,array $params = []) + { + return Request::request('GET',$url,$params); + } + + /** + * url拼接数组 + * @param array $params + * @return string + */ + public static function url_splice_array(array $params = []) + { + $buff = ""; + foreach ($params as $k => $v) { + if ($k != "sign") { + $buff .= $k . "=" . $v . "&"; + } + } + $buff = trim($buff, "&"); + return $buff; + } + + /** + * 创建唯一字符 + * @param string $strBlur 原字符 + * @param string $strType 加密方式 :[w所有|s字符|d数字] + * @param int $strLen 返回字符长度,建议大于16位 + * @return string 字符串 + */ + public static function randOnlyStr(string $strBlur = '',string $strType = 'w',int $strLen = 18):string + { + $dStr = '0123456789'; + $sStr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $wStr = '!$&()*,/:;=?@-._~'; + $strBlurLen = (strlen(static::uniqueString($strBlur)) + 1) == 1 ? 0 : strlen(static::uniqueString($strBlur)) + 1; + $strSuffix = $strBlurLen > 0 ? '#'.static::uniqueString($strBlur) : ''; + switch ($strType) + { + case 's': # 字符串 + return static::getGapStrByStr($sStr,$strLen - $strBlurLen).$strSuffix; + break; + case 'd': # 数字 + return static::getGapStrByStr($dStr,$strLen - $strBlurLen).$strSuffix; + break; + case 'w': # 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。 + return static::getGapStrByStr($dStr.$sStr.$wStr,$strLen - $strBlurLen).$strSuffix; + break; + default : # 默认大小写字母 + return static::getGapStrByStr($sStr,$strLen - $strBlurLen).$strSuffix; + break; + } + } + + /** + * 获取对应字符 + * @param string $str 字符串 + * @param int $strLen 长度 + * @return string 随机字符串 + */ + public static function getGapStrByStr(string $str = '', int $strLen = 18) + { + static $newStr = ''; + static $i = 0; + if ($i < $strLen) + { + $newStr .= $str[rand(0,strlen($str))]; + $i ++; + static::getGapStrByStr($str,$strLen); + } + return $newStr; + } + + + + /** + * 生成唯一字符串 + * @param $type $type 类型 + * @return string 字符串 + */ + public static function uniqueString(string $type) + { + return bin2hex($type); + } + + /** + * 获取唯一字符串类型 + * @param $string $string 唯一字符串 + * @return bool|string 返回结果:字符串或者false + */ + public static function uniqueType(string $string) + { + return hex2bin($string); + } + + + /** + * 小程序检验数据的真实性,并且获取解密后的明文. + * @param string $appID 加密的用户数据 + * @param string $sessionKey 与用户数据一同返回的初始向量 + * @param string $encryptedData 解密后的原文 + * @param string $iv 成功0,失败返回对应的错误码 + * @return string + */ + public static function decryptData(string $appID, string $sessionKey, string $encryptedData, string $iv ) + { + if (strlen($sessionKey) != 24) return '4'; + if (strlen($iv) != 24) return '3'; + + $aesKey = base64_decode($sessionKey); + $aesIV = base64_decode($iv); + $aesCipher = base64_decode($encryptedData); + + $result = openssl_decrypt($aesCipher,"AES-128-CBC",$aesKey,1,$aesIV); + $dataObj = json_decode($result,true); + if( $dataObj == NULL ) return '2'; + if( $dataObj['watermark']['appid'] != $appID ) return '1'; + return $result; + } + +} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Extend/log/param/param.log b/vendor/wechat/src/WeChat/Extend/log/param/param.log new file mode 100755 index 0000000..7ec1684 --- /dev/null +++ b/vendor/wechat/src/WeChat/Extend/log/param/param.log @@ -0,0 +1 @@ +{"access_token":{"access_token":"22_TkrZweCYc9K1gZtrP7YjI-rKHTeaWhEfWS6XWVd1MbGHdPXLd72rFNx3ziElXYKoFKwYVUOiAzHrUQPvlEvxdRCElu03JlDSJWkdF6U3z6AsPq44YQLVFinkSewiRd6h74TKo6Y_Xjn_Bo3sUJCcAGAZOH","expires_in":7200,"time":1561616075}} \ No newline at end of file diff --git a/vendor/wechat/src/WeChat/Lib/phpqrcode.php b/vendor/wechat/src/WeChat/Lib/phpqrcode.php new file mode 100755 index 0000000..48efc9a --- /dev/null +++ b/vendor/wechat/src/WeChat/Lib/phpqrcode.php @@ -0,0 +1,3310 @@ +<?php + +/* + * PHP QR Code encoder + * + * This file contains MERGED version of PHP QR Code library. + * It was auto-generated from full version for your convenience. + * + * This merged version was configured to not requre any external files, + * with disabled cache, error loging and weker but faster mask matching. + * If you need tune it up please use non-merged version. + * + * For full version, documentation, examples of use please visit: + * + * http://phpqrcode.sourceforge.net/ + * https://sourceforge.net/projects/phpqrcode/ + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +/* + * Version: 1.1.4 + * Build: 2010100721 + */ + + + +//---- qrconst.php ----------------------------- + + + + + +/* + * PHP QR Code encoder + * + * Common constants + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + // Encoding modes + + define('QR_MODE_NUL', -1); + define('QR_MODE_NUM', 0); + define('QR_MODE_AN', 1); + define('QR_MODE_8', 2); + define('QR_MODE_KANJI', 3); + define('QR_MODE_STRUCTURE', 4); + + // Levels of error correction. + + define('QR_ECLEVEL_L', 0); + define('QR_ECLEVEL_M', 1); + define('QR_ECLEVEL_Q', 2); + define('QR_ECLEVEL_H', 3); + + // Supported output formats + + define('QR_FORMAT_TEXT', 0); + define('QR_FORMAT_PNG', 1); + + class qrstr { + public static function set(&$srctab, $x, $y, $repl, $replLen = false) { + $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); + } + } + + + +//---- merged_config.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Config file, tuned-up for merged verion + */ + + define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there + define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true + define('QR_LOG_DIR', false); // default error logs dir + + define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code + define('QR_FIND_FROM_RANDOM', 2); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly + define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false + + define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images + + + + +//---- qrtools.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Toolset, handy and debug utilites. + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + class QRtools { + + //---------------------------------------------------------------------- + public static function binarize($frame) + { + $len = count($frame); + foreach ($frame as &$frameLine) { + + for($i=0; $i<$len; $i++) { + $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; + } + } + + return $frame; + } + + //---------------------------------------------------------------------- + public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037') + { + $barcode_array = array(); + + if (!is_array($mode)) + $mode = explode(',', $mode); + + $eccLevel = 'L'; + + if (count($mode) > 1) { + $eccLevel = $mode[1]; + } + + $qrTab = QRcode::text($code, false, $eccLevel); + $size = count($qrTab); + + $barcode_array['num_rows'] = $size; + $barcode_array['num_cols'] = $size; + $barcode_array['bcode'] = array(); + + foreach ($qrTab as $line) { + $arrAdd = array(); + foreach(str_split($line) as $char) + $arrAdd[] = ($char=='1')?1:0; + $barcode_array['bcode'][] = $arrAdd; + } + + return $barcode_array; + } + + //---------------------------------------------------------------------- + public static function clearCache() + { + self::$frames = array(); + } + + //---------------------------------------------------------------------- + public static function buildCache() + { + QRtools::markTime('before_build_cache'); + + $mask = new QRmask(); + for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) { + $frame = QRspec::newFrame($a); + if (QR_IMAGE) { + $fileName = QR_CACHE_DIR.'frame_'.$a.'.png'; + QRimage::png(self::binarize($frame), $fileName, 1, 0); + } + + $width = count($frame); + $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); + for ($maskNo=0; $maskNo<8; $maskNo++) + $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); + } + + QRtools::markTime('after_build_cache'); + } + + //---------------------------------------------------------------------- + public static function log($outfile, $err) + { + if (QR_LOG_DIR !== false) { + if ($err != '') { + if ($outfile !== false) { + file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); + } else { + file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); + } + } + } + } + + //---------------------------------------------------------------------- + public static function dumpMask($frame) + { + $width = count($frame); + for($y=0;$y<$width;$y++) { + for($x=0;$x<$width;$x++) { + echo ord($frame[$y][$x]).','; + } + } + } + + //---------------------------------------------------------------------- + public static function markTime($markerId) + { + list($usec, $sec) = explode(" ", microtime()); + $time = ((float)$usec + (float)$sec); + + if (!isset($GLOBALS['qr_time_bench'])) + $GLOBALS['qr_time_bench'] = array(); + + $GLOBALS['qr_time_bench'][$markerId] = $time; + } + + //---------------------------------------------------------------------- + public static function timeBenchmark() + { + self::markTime('finish'); + + $lastTime = 0; + $startTime = 0; + $p = 0; + + echo '<table cellpadding="3" cellspacing="1"> + <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead> + <tbody>'; + + foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) { + if ($p > 0) { + echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>'; + } else { + $startTime = $thisTime; + } + + $p++; + $lastTime = $thisTime; + } + + echo '</tbody><tfoot> + <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr> + </tfoot> + </table>'; + } + + } + + //########################################################################## + + QRtools::markTime('start'); + + + + +//---- qrspec.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * QR Code specifications + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + define('QRSPEC_VERSION_MAX', 40); + define('QRSPEC_WIDTH_MAX', 177); + + define('QRCAP_WIDTH', 0); + define('QRCAP_WORDS', 1); + define('QRCAP_REMINDER', 2); + define('QRCAP_EC', 3); + + class QRspec { + + public static $capacity = array( + array( 0, 0, 0, array( 0, 0, 0, 0)), + array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 + array( 25, 44, 7, array( 10, 16, 22, 28)), + array( 29, 70, 7, array( 15, 26, 36, 44)), + array( 33, 100, 7, array( 20, 36, 52, 64)), + array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 + array( 41, 172, 7, array( 36, 64, 96, 112)), + array( 45, 196, 0, array( 40, 72, 108, 130)), + array( 49, 242, 0, array( 48, 88, 132, 156)), + array( 53, 292, 0, array( 60, 110, 160, 192)), + array( 57, 346, 0, array( 72, 130, 192, 224)), //10 + array( 61, 404, 0, array( 80, 150, 224, 264)), + array( 65, 466, 0, array( 96, 176, 260, 308)), + array( 69, 532, 0, array( 104, 198, 288, 352)), + array( 73, 581, 3, array( 120, 216, 320, 384)), + array( 77, 655, 3, array( 132, 240, 360, 432)), //15 + array( 81, 733, 3, array( 144, 280, 408, 480)), + array( 85, 815, 3, array( 168, 308, 448, 532)), + array( 89, 901, 3, array( 180, 338, 504, 588)), + array( 93, 991, 3, array( 196, 364, 546, 650)), + array( 97, 1085, 3, array( 224, 416, 600, 700)), //20 + array(101, 1156, 4, array( 224, 442, 644, 750)), + array(105, 1258, 4, array( 252, 476, 690, 816)), + array(109, 1364, 4, array( 270, 504, 750, 900)), + array(113, 1474, 4, array( 300, 560, 810, 960)), + array(117, 1588, 4, array( 312, 588, 870, 1050)), //25 + array(121, 1706, 4, array( 336, 644, 952, 1110)), + array(125, 1828, 4, array( 360, 700, 1020, 1200)), + array(129, 1921, 3, array( 390, 728, 1050, 1260)), + array(133, 2051, 3, array( 420, 784, 1140, 1350)), + array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30 + array(141, 2323, 3, array( 480, 868, 1290, 1530)), + array(145, 2465, 3, array( 510, 924, 1350, 1620)), + array(149, 2611, 3, array( 540, 980, 1440, 1710)), + array(153, 2761, 3, array( 570, 1036, 1530, 1800)), + array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35 + array(161, 3034, 0, array( 600, 1120, 1680, 1980)), + array(165, 3196, 0, array( 630, 1204, 1770, 2100)), + array(169, 3362, 0, array( 660, 1260, 1860, 2220)), + array(173, 3532, 0, array( 720, 1316, 1950, 2310)), + array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40 + ); + + //---------------------------------------------------------------------- + public static function getDataLength($version, $level) + { + return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level]; + } + + //---------------------------------------------------------------------- + public static function getECCLength($version, $level) + { + return self::$capacity[$version][QRCAP_EC][$level]; + } + + //---------------------------------------------------------------------- + public static function getWidth($version) + { + return self::$capacity[$version][QRCAP_WIDTH]; + } + + //---------------------------------------------------------------------- + public static function getRemainder($version) + { + return self::$capacity[$version][QRCAP_REMINDER]; + } + + //---------------------------------------------------------------------- + public static function getMinimumVersion($size, $level) + { + + for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) { + $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level]; + if($words >= $size) + return $i; + } + + return -1; + } + + //###################################################################### + + public static $lengthTableBits = array( + array(10, 12, 14), + array( 9, 11, 13), + array( 8, 16, 16), + array( 8, 10, 12) + ); + + //---------------------------------------------------------------------- + public static function lengthIndicator($mode, $version) + { + if ($mode == QR_MODE_STRUCTURE) + return 0; + + if ($version <= 9) { + $l = 0; + } else if ($version <= 26) { + $l = 1; + } else { + $l = 2; + } + + return self::$lengthTableBits[$mode][$l]; + } + + //---------------------------------------------------------------------- + public static function maximumWords($mode, $version) + { + if($mode == QR_MODE_STRUCTURE) + return 3; + + if($version <= 9) { + $l = 0; + } else if($version <= 26) { + $l = 1; + } else { + $l = 2; + } + + $bits = self::$lengthTableBits[$mode][$l]; + $words = (1 << $bits) - 1; + + if($mode == QR_MODE_KANJI) { + $words *= 2; // the number of bytes is required + } + + return $words; + } + + // Error correction code ----------------------------------------------- + // Table of the error correction code (Reed-Solomon block) + // See Table 12-16 (pp.30-36), JIS X0510:2004. + + public static $eccTable = array( + array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), + array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 + array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), + array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), + array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), + array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 + array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), + array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), + array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), + array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), + array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10 + array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), + array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), + array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), + array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), + array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15 + array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), + array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), + array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), + array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), + array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20 + array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), + array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), + array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), + array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), + array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25 + array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), + array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), + array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), + array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), + array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30 + array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), + array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), + array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), + array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), + array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35 + array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), + array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), + array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), + array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), + array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40 + ); + + //---------------------------------------------------------------------- + // CACHEABLE!!! + + public static function getEccSpec($version, $level, array &$spec) + { + if (count($spec) < 5) { + $spec = array(0,0,0,0,0); + } + + $b1 = self::$eccTable[$version][$level][0]; + $b2 = self::$eccTable[$version][$level][1]; + $data = self::getDataLength($version, $level); + $ecc = self::getECCLength($version, $level); + + if($b2 == 0) { + $spec[0] = $b1; + $spec[1] = (int)($data / $b1); + $spec[2] = (int)($ecc / $b1); + $spec[3] = 0; + $spec[4] = 0; + } else { + $spec[0] = $b1; + $spec[1] = (int)($data / ($b1 + $b2)); + $spec[2] = (int)($ecc / ($b1 + $b2)); + $spec[3] = $b2; + $spec[4] = $spec[1] + 1; + } + } + + // Alignment pattern --------------------------------------------------- + + // Positions of alignment patterns. + // This array includes only the second and the third position of the + // alignment patterns. Rest of them can be calculated from the distance + // between them. + + // See Table 1 in Appendix E (pp.71) of JIS X0510:2004. + + public static $alignmentPattern = array( + array( 0, 0), + array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 + array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 + array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15 + array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20 + array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25 + array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30 + array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35 + array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40 + ); + + + /** -------------------------------------------------------------------- + * Put an alignment marker. + * @param frame + * @param width + * @param ox,oy center coordinate of the pattern + */ + public static function putAlignmentMarker(array &$frame, $ox, $oy) + { + $finder = array( + "\xa1\xa1\xa1\xa1\xa1", + "\xa1\xa0\xa0\xa0\xa1", + "\xa1\xa0\xa1\xa0\xa1", + "\xa1\xa0\xa0\xa0\xa1", + "\xa1\xa1\xa1\xa1\xa1" + ); + + $yStart = $oy-2; + $xStart = $ox-2; + + for($y=0; $y<5; $y++) { + QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]); + } + } + + //---------------------------------------------------------------------- + public static function putAlignmentPattern($version, &$frame, $width) + { + if($version < 2) + return; + + $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0]; + if($d < 0) { + $w = 2; + } else { + $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2); + } + + if($w * $w - 3 == 1) { + $x = self::$alignmentPattern[$version][0]; + $y = self::$alignmentPattern[$version][0]; + self::putAlignmentMarker($frame, $x, $y); + return; + } + + $cx = self::$alignmentPattern[$version][0]; + for($x=1; $x<$w - 1; $x++) { + self::putAlignmentMarker($frame, 6, $cx); + self::putAlignmentMarker($frame, $cx, 6); + $cx += $d; + } + + $cy = self::$alignmentPattern[$version][0]; + for($y=0; $y<$w-1; $y++) { + $cx = self::$alignmentPattern[$version][0]; + for($x=0; $x<$w-1; $x++) { + self::putAlignmentMarker($frame, $cx, $cy); + $cx += $d; + } + $cy += $d; + } + } + + // Version information pattern ----------------------------------------- + + // Version information pattern (BCH coded). + // See Table 1 in Appendix D (pp.68) of JIS X0510:2004. + + // size: [QRSPEC_VERSION_MAX - 6] + + public static $versionPattern = array( + 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, + 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, + 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, + 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, + 0x27541, 0x28c69 + ); + + //---------------------------------------------------------------------- + public static function getVersionPattern($version) + { + if($version < 7 || $version > QRSPEC_VERSION_MAX) + return 0; + + return self::$versionPattern[$version -7]; + } + + // Format information -------------------------------------------------- + // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib) + + public static $formatInfo = array( + array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), + array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), + array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), + array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) + ); + + public static function getFormatInfo($mask, $level) + { + if($mask < 0 || $mask > 7) + return 0; + + if($level < 0 || $level > 3) + return 0; + + return self::$formatInfo[$level][$mask]; + } + + // Frame --------------------------------------------------------------- + // Cache of initial frames. + + public static $frames = array(); + + /** -------------------------------------------------------------------- + * Put a finder pattern. + * @param frame + * @param width + * @param ox,oy upper-left coordinate of the pattern + */ + public static function putFinderPattern(&$frame, $ox, $oy) + { + $finder = array( + "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", + "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", + "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", + "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", + "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", + "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", + "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" + ); + + for($y=0; $y<7; $y++) { + QRstr::set($frame, $ox, $oy+$y, $finder[$y]); + } + } + + //---------------------------------------------------------------------- + public static function createFrame($version) + { + $width = self::$capacity[$version][QRCAP_WIDTH]; + $frameLine = str_repeat ("\0", $width); + $frame = array_fill(0, $width, $frameLine); + + // Finder pattern + self::putFinderPattern($frame, 0, 0); + self::putFinderPattern($frame, $width - 7, 0); + self::putFinderPattern($frame, 0, $width - 7); + + // Separator + $yOffset = $width - 7; + + for($y=0; $y<7; $y++) { + $frame[$y][7] = "\xc0"; + $frame[$y][$width - 8] = "\xc0"; + $frame[$yOffset][7] = "\xc0"; + $yOffset++; + } + + $setPattern = str_repeat("\xc0", 8); + + QRstr::set($frame, 0, 7, $setPattern); + QRstr::set($frame, $width-8, 7, $setPattern); + QRstr::set($frame, 0, $width - 8, $setPattern); + + // Format info + $setPattern = str_repeat("\x84", 9); + QRstr::set($frame, 0, 8, $setPattern); + QRstr::set($frame, $width - 8, 8, $setPattern, 8); + + $yOffset = $width - 8; + + for($y=0; $y<8; $y++,$yOffset++) { + $frame[$y][8] = "\x84"; + $frame[$yOffset][8] = "\x84"; + } + + // Timing pattern + + for($i=1; $i<$width-15; $i++) { + $frame[6][7+$i] = chr(0x90 | ($i & 1)); + $frame[7+$i][6] = chr(0x90 | ($i & 1)); + } + + // Alignment pattern + self::putAlignmentPattern($version, $frame, $width); + + // Version information + if($version >= 7) { + $vinf = self::getVersionPattern($version); + + $v = $vinf; + + for($x=0; $x<6; $x++) { + for($y=0; $y<3; $y++) { + $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); + $v = $v >> 1; + } + } + + $v = $vinf; + for($y=0; $y<6; $y++) { + for($x=0; $x<3; $x++) { + $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); + $v = $v >> 1; + } + } + } + + // and a little bit... + $frame[$width - 8][8] = "\x81"; + + return $frame; + } + + //---------------------------------------------------------------------- + public static function debug($frame, $binary_mode = false) + { + if ($binary_mode) { + + foreach ($frame as &$frameLine) { + $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine)); + $frameLine = join('&#9608;&#9608;', explode('1', $frameLine)); + } + + ?> + <style> + .m { background-color: white; } + </style> + <?php + echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'; + echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame); + echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >'; + + } else { + + foreach ($frame as &$frameLine) { + $frameLine = join('<span class="m">&nbsp;</span>', explode("\xc0", $frameLine)); + $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine)); + $frameLine = join('<span class="p">&nbsp;</span>', explode("\xa0", $frameLine)); + $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine)); + $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0 + $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1 + $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit + $frameLine = join('<span class="c">&nbsp;</span>', explode("\x90", $frameLine)); //clock 0 + $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1 + $frameLine = join('<span class="f">&nbsp;</span>', explode("\x88", $frameLine)); //version + $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version + $frameLine = join('&#9830;', explode("\x01", $frameLine)); + $frameLine = join('&#8901;', explode("\0", $frameLine)); + } + + ?> + <style> + .p { background-color: yellow; } + .m { background-color: #00FF00; } + .s { background-color: #FF0000; } + .c { background-color: aqua; } + .x { background-color: pink; } + .f { background-color: gold; } + </style> + <?php + echo "<pre><tt>"; + echo join("<br/ >", $frame); + echo "</tt></pre>"; + + } + } + + //---------------------------------------------------------------------- + public static function serial($frame) + { + return gzcompress(join("\n", $frame), 9); + } + + //---------------------------------------------------------------------- + public static function unserial($code) + { + return explode("\n", gzuncompress($code)); + } + + //---------------------------------------------------------------------- + public static function newFrame($version) + { + if($version < 1 || $version > QRSPEC_VERSION_MAX) + return null; + + if(!isset(self::$frames[$version])) { + + $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat'; + + if (QR_CACHEABLE) { + if (file_exists($fileName)) { + self::$frames[$version] = self::unserial(file_get_contents($fileName)); + } else { + self::$frames[$version] = self::createFrame($version); + file_put_contents($fileName, self::serial(self::$frames[$version])); + } + } else { + self::$frames[$version] = self::createFrame($version); + } + } + + if(is_null(self::$frames[$version])) + return null; + + return self::$frames[$version]; + } + + //---------------------------------------------------------------------- + public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; } + public static function rsBlockNum1($spec) { return $spec[0]; } + public static function rsDataCodes1($spec) { return $spec[1]; } + public static function rsEccCodes1($spec) { return $spec[2]; } + public static function rsBlockNum2($spec) { return $spec[3]; } + public static function rsDataCodes2($spec) { return $spec[4]; } + public static function rsEccCodes2($spec) { return $spec[2]; } + public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } + public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } + + } + + + +//---- qrimage.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Image output of code using GD2 + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + define('QR_IMAGE', true); + + class QRimage { + + //---------------------------------------------------------------------- + public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=TRUE) + { + $image = self::image($frame, $pixelPerPoint, $outerFrame); + if ($filename === false) { + Header("Content-type: image/png"); + ImagePng($image); + } else { + if($saveandprint===TRUE){ + ImagePng($image, $filename); + header("Content-type: image/png"); + ImagePng($image); + }else{ + ImagePng($image, $filename); + } + } + ImageDestroy($image); + } + + //---------------------------------------------------------------------- + public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) + { + $image = self::image($frame, $pixelPerPoint, $outerFrame); + + if ($filename === false) { + Header("Content-type: image/jpeg"); + ImageJpeg($image, null, $q); + } else { + ImageJpeg($image, $filename, $q); + } + + ImageDestroy($image); + } + + //---------------------------------------------------------------------- + private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) + { + $h = count($frame); + $w = strlen($frame[0]); + + $imgW = $w + 2*$outerFrame; + $imgH = $h + 2*$outerFrame; + + $base_image =ImageCreate($imgW, $imgH); + + $col[0] = ImageColorAllocate($base_image,255,255,255); + $col[1] = ImageColorAllocate($base_image,0,0,0); + + imagefill($base_image, 0, 0, $col[0]); + + for($y=0; $y<$h; $y++) { + for($x=0; $x<$w; $x++) { + if ($frame[$y][$x] == '1') { + ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); + } + } + } + + $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint); + ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH); + ImageDestroy($base_image); + + return $target_image; + } + } + + + +//---- qrinput.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Input encoding class + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + define('STRUCTURE_HEADER_BITS', 20); + define('MAX_STRUCTURED_SYMBOLS', 16); + + class QRinputItem { + + public $mode; + public $size; + public $data; + public $bstream; + + public function __construct($mode, $size, $data, $bstream = null) + { + $setData = array_slice($data, 0, $size); + + if (count($setData) < $size) { + $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); + } + + if(!QRinput::check($mode, $size, $setData)) { + throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); + return null; + } + + $this->mode = $mode; + $this->size = $size; + $this->data = $setData; + $this->bstream = $bstream; + } + + //---------------------------------------------------------------------- + public function encodeModeNum($version) + { + try { + + $words = (int)($this->size / 3); + $bs = new QRbitstream(); + + $val = 0x1; + $bs->appendNum(4, $val); + $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size); + + for($i=0; $i<$words; $i++) { + $val = (ord($this->data[$i*3 ]) - ord('0')) * 100; + $val += (ord($this->data[$i*3+1]) - ord('0')) * 10; + $val += (ord($this->data[$i*3+2]) - ord('0')); + $bs->appendNum(10, $val); + } + + if($this->size - $words * 3 == 1) { + $val = ord($this->data[$words*3]) - ord('0'); + $bs->appendNum(4, $val); + } else if($this->size - $words * 3 == 2) { + $val = (ord($this->data[$words*3 ]) - ord('0')) * 10; + $val += (ord($this->data[$words*3+1]) - ord('0')); + $bs->appendNum(7, $val); + } + + $this->bstream = $bs; + return 0; + + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function encodeModeAn($version) + { + try { + $words = (int)($this->size / 2); + $bs = new QRbitstream(); + + $bs->appendNum(4, 0x02); + $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size); + + for($i=0; $i<$words; $i++) { + $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45; + $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1])); + + $bs->appendNum(11, $val); + } + + if($this->size & 1) { + $val = QRinput::lookAnTable(ord($this->data[$words * 2])); + $bs->appendNum(6, $val); + } + + $this->bstream = $bs; + return 0; + + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function encodeMode8($version) + { + try { + $bs = new QRbitstream(); + + $bs->appendNum(4, 0x4); + $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size); + + for($i=0; $i<$this->size; $i++) { + $bs->appendNum(8, ord($this->data[$i])); + } + + $this->bstream = $bs; + return 0; + + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function encodeModeKanji($version) + { + try { + + $bs = new QRbitrtream(); + + $bs->appendNum(4, 0x8); + $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2)); + + for($i=0; $i<$this->size; $i+=2) { + $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]); + if($val <= 0x9ffc) { + $val -= 0x8140; + } else { + $val -= 0xc140; + } + + $h = ($val >> 8) * 0xc0; + $val = ($val & 0xff) + $h; + + $bs->appendNum(13, $val); + } + + $this->bstream = $bs; + return 0; + + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function encodeModeStructure() + { + try { + $bs = new QRbitstream(); + + $bs->appendNum(4, 0x03); + $bs->appendNum(4, ord($this->data[1]) - 1); + $bs->appendNum(4, ord($this->data[0]) - 1); + $bs->appendNum(8, ord($this->data[2])); + + $this->bstream = $bs; + return 0; + + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function estimateBitStreamSizeOfEntry($version) + { + $bits = 0; + + if($version == 0) + $version = 1; + + switch($this->mode) { + case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break; + case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break; + case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break; + case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break; + case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS; + default: + return 0; + } + + $l = QRspec::lengthIndicator($this->mode, $version); + $m = 1 << $l; + $num = (int)(($this->size + $m - 1) / $m); + + $bits += $num * (4 + $l); + + return $bits; + } + + //---------------------------------------------------------------------- + public function encodeBitStream($version) + { + try { + + unset($this->bstream); + $words = QRspec::maximumWords($this->mode, $version); + + if($this->size > $words) { + + $st1 = new QRinputItem($this->mode, $words, $this->data); + $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); + + $st1->encodeBitStream($version); + $st2->encodeBitStream($version); + + $this->bstream = new QRbitstream(); + $this->bstream->append($st1->bstream); + $this->bstream->append($st2->bstream); + + unset($st1); + unset($st2); + + } else { + + $ret = 0; + + switch($this->mode) { + case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; + case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; + case QR_MODE_8: $ret = $this->encodeMode8($version); break; + case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break; + case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; + + default: + break; + } + + if($ret < 0) + return -1; + } + + return $this->bstream->size(); + + } catch (Exception $e) { + return -1; + } + } + }; + + //########################################################################## + + class QRinput { + + public $items; + + private $version; + private $level; + + //---------------------------------------------------------------------- + public function __construct($version = 0, $level = QR_ECLEVEL_L) + { + if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) { + throw new Exception('Invalid version no'); + return NULL; + } + + $this->version = $version; + $this->level = $level; + } + + //---------------------------------------------------------------------- + public function getVersion() + { + return $this->version; + } + + //---------------------------------------------------------------------- + public function setVersion($version) + { + if($version < 0 || $version > QRSPEC_VERSION_MAX) { + throw new Exception('Invalid version no'); + return -1; + } + + $this->version = $version; + + return 0; + } + + //---------------------------------------------------------------------- + public function getErrorCorrectionLevel() + { + return $this->level; + } + + //---------------------------------------------------------------------- + public function setErrorCorrectionLevel($level) + { + if($level > QR_ECLEVEL_H) { + throw new Exception('Invalid ECLEVEL'); + return -1; + } + + $this->level = $level; + + return 0; + } + + //---------------------------------------------------------------------- + public function appendEntry(QRinputItem $entry) + { + $this->items[] = $entry; + } + + //---------------------------------------------------------------------- + public function append($mode, $size, $data) + { + try { + $entry = new QRinputItem($mode, $size, $data); + $this->items[] = $entry; + return 0; + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + + public function insertStructuredAppendHeader($size, $index, $parity) + { + if( $size > MAX_STRUCTURED_SYMBOLS ) { + throw new Exception('insertStructuredAppendHeader wrong size'); + } + + if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) { + throw new Exception('insertStructuredAppendHeader wrong index'); + } + + $buf = array($size, $index, $parity); + + try { + $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf); + array_unshift($this->items, $entry); + return 0; + } catch (Exception $e) { + return -1; + } + } + + //---------------------------------------------------------------------- + public function calcParity() + { + $parity = 0; + + foreach($this->items as $item) { + if($item->mode != QR_MODE_STRUCTURE) { + for($i=$item->size-1; $i>=0; $i--) { + $parity ^= $item->data[$i]; + } + } + } + + return $parity; + } + + //---------------------------------------------------------------------- + public static function checkModeNum($size, $data) + { + for($i=0; $i<$size; $i++) { + if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ + return false; + } + } + + return true; + } + + //---------------------------------------------------------------------- + public static function estimateBitsModeNum($size) + { + $w = (int)$size / 3; + $bits = $w * 10; + + switch($size - $w * 3) { + case 1: + $bits += 4; + break; + case 2: + $bits += 7; + break; + default: + break; + } + + return $bits; + } + + //---------------------------------------------------------------------- + public static $anTable = array( + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + ); + + //---------------------------------------------------------------------- + public static function lookAnTable($c) + { + return (($c > 127)?-1:self::$anTable[$c]); + } + + //---------------------------------------------------------------------- + public static function checkModeAn($size, $data) + { + for($i=0; $i<$size; $i++) { + if (self::lookAnTable(ord($data[$i])) == -1) { + return false; + } + } + + return true; + } + + //---------------------------------------------------------------------- + public static function estimateBitsModeAn($size) + { + $w = (int)($size / 2); + $bits = $w * 11; + + if($size & 1) { + $bits += 6; + } + + return $bits; + } + + //---------------------------------------------------------------------- + public static function estimateBitsMode8($size) + { + return $size * 8; + } + + //---------------------------------------------------------------------- + public function estimateBitsModeKanji($size) + { + return (int)(($size / 2) * 13); + } + + //---------------------------------------------------------------------- + public static function checkModeKanji($size, $data) + { + if($size & 1) + return false; + + for($i=0; $i<$size; $i+=2) { + $val = (ord($data[$i]) << 8) | ord($data[$i+1]); + if( $val < 0x8140 + || ($val > 0x9ffc && $val < 0xe040) + || $val > 0xebbf) { + return false; + } + } + + return true; + } + + /*********************************************************************** + * Validation + **********************************************************************/ + + public static function check($mode, $size, $data) + { + if($size <= 0) + return false; + + switch($mode) { + case QR_MODE_NUM: return self::checkModeNum($size, $data); break; + case QR_MODE_AN: return self::checkModeAn($size, $data); break; + case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break; + case QR_MODE_8: return true; break; + case QR_MODE_STRUCTURE: return true; break; + + default: + break; + } + + return false; + } + + + //---------------------------------------------------------------------- + public function estimateBitStreamSize($version) + { + $bits = 0; + + foreach($this->items as $item) { + $bits += $item->estimateBitStreamSizeOfEntry($version); + } + + return $bits; + } + + //---------------------------------------------------------------------- + public function estimateVersion() + { + $version = 0; + $prev = 0; + do { + $prev = $version; + $bits = $this->estimateBitStreamSize($prev); + $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); + if ($version < 0) { + return -1; + } + } while ($version > $prev); + + return $version; + } + + //---------------------------------------------------------------------- + public static function lengthOfCode($mode, $version, $bits) + { + $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version); + switch($mode) { + case QR_MODE_NUM: + $chunks = (int)($payload / 10); + $remain = $payload - $chunks * 10; + $size = $chunks * 3; + if($remain >= 7) { + $size += 2; + } else if($remain >= 4) { + $size += 1; + } + break; + case QR_MODE_AN: + $chunks = (int)($payload / 11); + $remain = $payload - $chunks * 11; + $size = $chunks * 2; + if($remain >= 6) + $size++; + break; + case QR_MODE_8: + $size = (int)($payload / 8); + break; + case QR_MODE_KANJI: + $size = (int)(($payload / 13) * 2); + break; + case QR_MODE_STRUCTURE: + $size = (int)($payload / 8); + break; + default: + $size = 0; + break; + } + + $maxsize = QRspec::maximumWords($mode, $version); + if($size < 0) $size = 0; + if($size > $maxsize) $size = $maxsize; + + return $size; + } + + //---------------------------------------------------------------------- + public function createBitStream() + { + $total = 0; + + foreach($this->items as $item) { + $bits = $item->encodeBitStream($this->version); + + if($bits < 0) + return -1; + + $total += $bits; + } + + return $total; + } + + //---------------------------------------------------------------------- + public function convertData() + { + $ver = $this->estimateVersion(); + if($ver > $this->getVersion()) { + $this->setVersion($ver); + } + + for(;;) { + $bits = $this->createBitStream(); + + if($bits < 0) + return -1; + + $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); + if($ver < 0) { + throw new Exception('WRONG VERSION'); + return -1; + } else if($ver > $this->getVersion()) { + $this->setVersion($ver); + } else { + break; + } + } + + return 0; + } + + //---------------------------------------------------------------------- + public function appendPaddingBit(&$bstream) + { + $bits = $bstream->size(); + $maxwords = QRspec::getDataLength($this->version, $this->level); + $maxbits = $maxwords * 8; + + if ($maxbits == $bits) { + return 0; + } + + if ($maxbits - $bits < 5) { + return $bstream->appendNum($maxbits - $bits, 0); + } + + $bits += 4; + $words = (int)(($bits + 7) / 8); + + $padding = new QRbitstream(); + $ret = $padding->appendNum($words * 8 - $bits + 4, 0); + + if($ret < 0) + return $ret; + + $padlen = $maxwords - $words; + + if($padlen > 0) { + + $padbuf = array(); + for($i=0; $i<$padlen; $i++) { + $padbuf[$i] = ($i&1)?0x11:0xec; + } + + $ret = $padding->appendBytes($padlen, $padbuf); + + if($ret < 0) + return $ret; + + } + + $ret = $bstream->append($padding); + + return $ret; + } + + //---------------------------------------------------------------------- + public function mergeBitStream() + { + if($this->convertData() < 0) { + return null; + } + + $bstream = new QRbitstream(); + + foreach($this->items as $item) { + $ret = $bstream->append($item->bstream); + if($ret < 0) { + return null; + } + } + + return $bstream; + } + + //---------------------------------------------------------------------- + public function getBitStream() + { + + $bstream = $this->mergeBitStream(); + + if($bstream == null) { + return null; + } + + $ret = $this->appendPaddingBit($bstream); + if($ret < 0) { + return null; + } + + return $bstream; + } + + //---------------------------------------------------------------------- + public function getByteStream() + { + $bstream = $this->getBitStream(); + if($bstream == null) { + return null; + } + + return $bstream->toByte(); + } + } + + + + + + +//---- qrbitstream.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Bitstream class + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + class QRbitstream { + + public $data = array(); + + //---------------------------------------------------------------------- + public function size() + { + return count($this->data); + } + + //---------------------------------------------------------------------- + public function allocate($setLength) + { + $this->data = array_fill(0, $setLength, 0); + return 0; + } + + //---------------------------------------------------------------------- + public static function newFromNum($bits, $num) + { + $bstream = new QRbitstream(); + $bstream->allocate($bits); + + $mask = 1 << ($bits - 1); + for($i=0; $i<$bits; $i++) { + if($num & $mask) { + $bstream->data[$i] = 1; + } else { + $bstream->data[$i] = 0; + } + $mask = $mask >> 1; + } + + return $bstream; + } + + //---------------------------------------------------------------------- + public static function newFromBytes($size, $data) + { + $bstream = new QRbitstream(); + $bstream->allocate($size * 8); + $p=0; + + for($i=0; $i<$size; $i++) { + $mask = 0x80; + for($j=0; $j<8; $j++) { + if($data[$i] & $mask) { + $bstream->data[$p] = 1; + } else { + $bstream->data[$p] = 0; + } + $p++; + $mask = $mask >> 1; + } + } + + return $bstream; + } + + //---------------------------------------------------------------------- + public function append(QRbitstream $arg) + { + if (is_null($arg)) { + return -1; + } + + if($arg->size() == 0) { + return 0; + } + + if($this->size() == 0) { + $this->data = $arg->data; + return 0; + } + + $this->data = array_values(array_merge($this->data, $arg->data)); + + return 0; + } + + //---------------------------------------------------------------------- + public function appendNum($bits, $num) + { + if ($bits == 0) + return 0; + + $b = QRbitstream::newFromNum($bits, $num); + + if(is_null($b)) + return -1; + + $ret = $this->append($b); + unset($b); + + return $ret; + } + + //---------------------------------------------------------------------- + public function appendBytes($size, $data) + { + if ($size == 0) + return 0; + + $b = QRbitstream::newFromBytes($size, $data); + + if(is_null($b)) + return -1; + + $ret = $this->append($b); + unset($b); + + return $ret; + } + + //---------------------------------------------------------------------- + public function toByte() + { + + $size = $this->size(); + + if($size == 0) { + return array(); + } + + $data = array_fill(0, (int)(($size + 7) / 8), 0); + $bytes = (int)($size / 8); + + $p = 0; + + for($i=0; $i<$bytes; $i++) { + $v = 0; + for($j=0; $j<8; $j++) { + $v = $v << 1; + $v |= $this->data[$p]; + $p++; + } + $data[$i] = $v; + } + + if($size & 7) { + $v = 0; + for($j=0; $j<($size & 7); $j++) { + $v = $v << 1; + $v |= $this->data[$p]; + $p++; + } + $data[$bytes] = $v; + } + + return $data; + } + + } + + + + +//---- qrsplit.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Input splitting classes + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * The following data / specifications are taken from + * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) + * or + * "Automatic identification and data capture techniques -- + * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + class QRsplit { + + public $dataStr = ''; + public $input; + public $modeHint; + + //---------------------------------------------------------------------- + public function __construct($dataStr, $input, $modeHint) + { + $this->dataStr = $dataStr; + $this->input = $input; + $this->modeHint = $modeHint; + } + + //---------------------------------------------------------------------- + public static function isdigitat($str, $pos) + { + if ($pos >= strlen($str)) + return false; + + return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); + } + + //---------------------------------------------------------------------- + public static function isalnumat($str, $pos) + { + if ($pos >= strlen($str)) + return false; + + return (QRinput::lookAnTable(ord($str[$pos])) >= 0); + } + + //---------------------------------------------------------------------- + public function identifyMode($pos) + { + if ($pos >= strlen($this->dataStr)) + return QR_MODE_NUL; + + $c = $this->dataStr[$pos]; + + if(self::isdigitat($this->dataStr, $pos)) { + return QR_MODE_NUM; + } else if(self::isalnumat($this->dataStr, $pos)) { + return QR_MODE_AN; + } else if($this->modeHint == QR_MODE_KANJI) { + + if ($pos+1 < strlen($this->dataStr)) + { + $d = $this->dataStr[$pos+1]; + $word = (ord($c) << 8) | ord($d); + if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) { + return QR_MODE_KANJI; + } + } + } + + return QR_MODE_8; + } + + //---------------------------------------------------------------------- + public function eatNum() + { + $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); + + $p = 0; + while(self::isdigitat($this->dataStr, $p)) { + $p++; + } + + $run = $p; + $mode = $this->identifyMode($p); + + if($mode == QR_MODE_8) { + $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + + QRinput::estimateBitsMode8(1) // + 4 + l8 + - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 + if($dif > 0) { + return $this->eat8(); + } + } + if($mode == QR_MODE_AN) { + $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln + + QRinput::estimateBitsModeAn(1) // + 4 + la + - QRinput::estimateBitsModeAn($run + 1);// - 4 - la + if($dif > 0) { + return $this->eatAn(); + } + } + + $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr)); + if($ret < 0) + return -1; + + return $run; + } + + //---------------------------------------------------------------------- + public function eatAn() + { + $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); + $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); + + $p = 0; + + while(self::isalnumat($this->dataStr, $p)) { + if(self::isdigitat($this->dataStr, $p)) { + $q = $p; + while(self::isdigitat($this->dataStr, $q)) { + $q++; + } + + $dif = QRinput::estimateBitsModeAn($p) // + 4 + la + + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln + - QRinput::estimateBitsModeAn($q); // - 4 - la + + if($dif < 0) { + break; + } else { + $p = $q; + } + } else { + $p++; + } + } + + $run = $p; + + if(!self::isalnumat($this->dataStr, $p)) { + $dif = QRinput::estimateBitsModeAn($run) + 4 + $la + + QRinput::estimateBitsMode8(1) // + 4 + l8 + - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 + if($dif > 0) { + return $this->eat8(); + } + } + + $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr)); + if($ret < 0) + return -1; + + return $run; + } + + //---------------------------------------------------------------------- + public function eatKanji() + { + $p = 0; + + while($this->identifyMode($p) == QR_MODE_KANJI) { + $p += 2; + } + + $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr)); + if($ret < 0) + return -1; + + return $run; + } + + //---------------------------------------------------------------------- + public function eat8() + { + $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); + $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); + + $p = 1; + $dataStrLen = strlen($this->dataStr); + + while($p < $dataStrLen) { + + $mode = $this->identifyMode($p); + if($mode == QR_MODE_KANJI) { + break; + } + if($mode == QR_MODE_NUM) { + $q = $p; + while(self::isdigitat($this->dataStr, $q)) { + $q++; + } + $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln + - QRinput::estimateBitsMode8($q); // - 4 - l8 + if($dif < 0) { + break; + } else { + $p = $q; + } + } else if($mode == QR_MODE_AN) { + $q = $p; + while(self::isalnumat($this->dataStr, $q)) { + $q++; + } + $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 + + QRinput::estimateBitsModeAn($q - $p) + 4 + $la + - QRinput::estimateBitsMode8($q); // - 4 - l8 + if($dif < 0) { + break; + } else { + $p = $q; + } + } else { + $p++; + } + } + + $run = $p; + $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); + + if($ret < 0) + return -1; + + return $run; + } + + //---------------------------------------------------------------------- + public function splitString() + { + while (strlen($this->dataStr) > 0) + { + if($this->dataStr == '') + return 0; + + $mode = $this->identifyMode(0); + + switch ($mode) { + case QR_MODE_NUM: $length = $this->eatNum(); break; + case QR_MODE_AN: $length = $this->eatAn(); break; + case QR_MODE_KANJI: + if ($hint == QR_MODE_KANJI) + $length = $this->eatKanji(); + else $length = $this->eat8(); + break; + default: $length = $this->eat8(); break; + + } + + if($length == 0) return 0; + if($length < 0) return -1; + + $this->dataStr = substr($this->dataStr, $length); + } + } + + //---------------------------------------------------------------------- + public function toUpper() + { + $stringLen = strlen($this->dataStr); + $p = 0; + + while ($p<$stringLen) { + $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint); + if($mode == QR_MODE_KANJI) { + $p += 2; + } else { + if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) { + $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); + } + $p++; + } + } + + return $this->dataStr; + } + + //---------------------------------------------------------------------- + public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true) + { + if(is_null($string) || $string == '\0' || $string == '') { + throw new Exception('empty string!!!'); + } + + $split = new QRsplit($string, $input, $modeHint); + + if(!$casesensitive) + $split->toUpper(); + + return $split->splitString(); + } + } + + + +//---- qrrscode.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Reed-Solomon error correction support + * + * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q + * (libfec is released under the GNU Lesser General Public License.) + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + class QRrsItem { + + public $mm; // Bits per symbol + public $nn; // Symbols per block (= (1<<mm)-1) + public $alpha_to = array(); // log lookup table + public $index_of = array(); // Antilog lookup table + public $genpoly = array(); // Generator polynomial + public $nroots; // Number of generator roots = number of parity symbols + public $fcr; // First consecutive root, index form + public $prim; // Primitive element, index form + public $iprim; // prim-th root of 1, index form + public $pad; // Padding bytes in shortened block + public $gfpoly; + + //---------------------------------------------------------------------- + public function modnn($x) + { + while ($x >= $this->nn) { + $x -= $this->nn; + $x = ($x >> $this->mm) + ($x & $this->nn); + } + + return $x; + } + + //---------------------------------------------------------------------- + public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) + { + // Common code for intializing a Reed-Solomon control block (char or int symbols) + // Copyright 2004 Phil Karn, KA9Q + // May be used under the terms of the GNU Lesser General Public License (LGPL) + + $rs = null; + + // Check parameter ranges + if($symsize < 0 || $symsize > 8) return $rs; + if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs; + if($prim <= 0 || $prim >= (1<<$symsize)) return $rs; + if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values! + if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding + + $rs = new QRrsItem(); + $rs->mm = $symsize; + $rs->nn = (1<<$symsize)-1; + $rs->pad = $pad; + + $rs->alpha_to = array_fill(0, $rs->nn+1, 0); + $rs->index_of = array_fill(0, $rs->nn+1, 0); + + // PHP style macro replacement ;) + $NN =& $rs->nn; + $A0 =& $NN; + + // Generate Galois field lookup tables + $rs->index_of[0] = $A0; // log(zero) = -inf + $rs->alpha_to[$A0] = 0; // alpha**-inf = 0 + $sr = 1; + + for($i=0; $i<$rs->nn; $i++) { + $rs->index_of[$sr] = $i; + $rs->alpha_to[$i] = $sr; + $sr <<= 1; + if($sr & (1<<$symsize)) { + $sr ^= $gfpoly; + } + $sr &= $rs->nn; + } + + if($sr != 1){ + // field generator polynomial is not primitive! + $rs = NULL; + return $rs; + } + + /* Form RS code generator polynomial from its roots */ + $rs->genpoly = array_fill(0, $nroots+1, 0); + + $rs->fcr = $fcr; + $rs->prim = $prim; + $rs->nroots = $nroots; + $rs->gfpoly = $gfpoly; + + /* Find prim-th root of 1, used in decoding */ + for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn) + ; // intentional empty-body loop! + + $rs->iprim = (int)($iprim / $prim); + $rs->genpoly[0] = 1; + + for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { + $rs->genpoly[$i+1] = 1; + + // Multiply rs->genpoly[] by @**(root + x) + for ($j = $i; $j > 0; $j--) { + if ($rs->genpoly[$j] != 0) { + $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)]; + } else { + $rs->genpoly[$j] = $rs->genpoly[$j-1]; + } + } + // rs->genpoly[0] can never be zero + $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)]; + } + + // convert rs->genpoly[] to index form for quicker encoding + for ($i = 0; $i <= $nroots; $i++) + $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]]; + + return $rs; + } + + //---------------------------------------------------------------------- + public function encode_rs_char($data, &$parity) + { + $MM =& $this->mm; + $NN =& $this->nn; + $ALPHA_TO =& $this->alpha_to; + $INDEX_OF =& $this->index_of; + $GENPOLY =& $this->genpoly; + $NROOTS =& $this->nroots; + $FCR =& $this->fcr; + $PRIM =& $this->prim; + $IPRIM =& $this->iprim; + $PAD =& $this->pad; + $A0 =& $NN; + + $parity = array_fill(0, $NROOTS, 0); + + for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) { + + $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; + if($feedback != $A0) { + // feedback term is non-zero + + // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must + // always be for the polynomials constructed by init_rs() + $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback); + + for($j=1;$j<$NROOTS;$j++) { + $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])]; + } + } + + // Shift + array_shift($parity); + if($feedback != $A0) { + array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]); + } else { + array_push($parity, 0); + } + } + } + } + + //########################################################################## + + class QRrs { + + public static $items = array(); + + //---------------------------------------------------------------------- + public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) + { + foreach(self::$items as $rs) { + if($rs->pad != $pad) continue; + if($rs->nroots != $nroots) continue; + if($rs->mm != $symsize) continue; + if($rs->gfpoly != $gfpoly) continue; + if($rs->fcr != $fcr) continue; + if($rs->prim != $prim) continue; + + return $rs; + } + + $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); + array_unshift(self::$items, $rs); + + return $rs; + } + } + + + +//---- qrmask.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Masking + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + define('N1', 3); + define('N2', 3); + define('N3', 40); + define('N4', 10); + + class QRmask { + + public $runLength = array(); + + //---------------------------------------------------------------------- + public function __construct() + { + $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); + } + + //---------------------------------------------------------------------- + public function writeFormatInformation($width, &$frame, $mask, $level) + { + $blacks = 0; + $format = QRspec::getFormatInfo($mask, $level); + + for($i=0; $i<8; $i++) { + if($format & 1) { + $blacks += 2; + $v = 0x85; + } else { + $v = 0x84; + } + + $frame[8][$width - 1 - $i] = chr($v); + if($i < 6) { + $frame[$i][8] = chr($v); + } else { + $frame[$i + 1][8] = chr($v); + } + $format = $format >> 1; + } + + for($i=0; $i<7; $i++) { + if($format & 1) { + $blacks += 2; + $v = 0x85; + } else { + $v = 0x84; + } + + $frame[$width - 7 + $i][8] = chr($v); + if($i == 0) { + $frame[8][7] = chr($v); + } else { + $frame[8][6 - $i] = chr($v); + } + + $format = $format >> 1; + } + + return $blacks; + } + + //---------------------------------------------------------------------- + public function mask0($x, $y) { return ($x+$y)&1; } + public function mask1($x, $y) { return ($y&1); } + public function mask2($x, $y) { return ($x%3); } + public function mask3($x, $y) { return ($x+$y)%3; } + public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; } + public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; } + public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; } + public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; } + + //---------------------------------------------------------------------- + private function generateMaskNo($maskNo, $width, $frame) + { + $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); + + for($y=0; $y<$width; $y++) { + for($x=0; $x<$width; $x++) { + if(ord($frame[$y][$x]) & 0x80) { + $bitMask[$y][$x] = 0; + } else { + $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); + $bitMask[$y][$x] = ($maskFunc == 0)?1:0; + } + + } + } + + return $bitMask; + } + + //---------------------------------------------------------------------- + public static function serial($bitFrame) + { + $codeArr = array(); + + foreach ($bitFrame as $line) + $codeArr[] = join('', $line); + + return gzcompress(join("\n", $codeArr), 9); + } + + //---------------------------------------------------------------------- + public static function unserial($code) + { + $codeArr = array(); + + $codeLines = explode("\n", gzuncompress($code)); + foreach ($codeLines as $line) + $codeArr[] = str_split($line); + + return $codeArr; + } + + //---------------------------------------------------------------------- + public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) + { + $b = 0; + $bitMask = array(); + + $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; + + if (QR_CACHEABLE) { + if (file_exists($fileName)) { + $bitMask = self::unserial(file_get_contents($fileName)); + } else { + $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); + if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) + mkdir(QR_CACHE_DIR.'mask_'.$maskNo); + file_put_contents($fileName, self::serial($bitMask)); + } + } else { + $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); + } + + if ($maskGenOnly) + return; + + $d = $s; + + for($y=0; $y<$width; $y++) { + for($x=0; $x<$width; $x++) { + if($bitMask[$y][$x] == 1) { + $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); + } + $b += (int)(ord($d[$y][$x]) & 1); + } + } + + return $b; + } + + //---------------------------------------------------------------------- + public function makeMask($width, $frame, $maskNo, $level) + { + $masked = array_fill(0, $width, str_repeat("\0", $width)); + $this->makeMaskNo($maskNo, $width, $frame, $masked); + $this->writeFormatInformation($width, $masked, $maskNo, $level); + + return $masked; + } + + //---------------------------------------------------------------------- + public function calcN1N3($length) + { + $demerit = 0; + + for($i=0; $i<$length; $i++) { + + if($this->runLength[$i] >= 5) { + $demerit += (N1 + ($this->runLength[$i] - 5)); + } + if($i & 1) { + if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { + $fact = (int)($this->runLength[$i] / 3); + if(($this->runLength[$i-2] == $fact) && + ($this->runLength[$i-1] == $fact) && + ($this->runLength[$i+1] == $fact) && + ($this->runLength[$i+2] == $fact)) { + if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { + $demerit += N3; + } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { + $demerit += N3; + } + } + } + } + } + return $demerit; + } + + //---------------------------------------------------------------------- + public function evaluateSymbol($width, $frame) + { + $head = 0; + $demerit = 0; + + for($y=0; $y<$width; $y++) { + $head = 0; + $this->runLength[0] = 1; + + $frameY = $frame[$y]; + + if ($y>0) + $frameYM = $frame[$y-1]; + + for($x=0; $x<$width; $x++) { + if(($x > 0) && ($y > 0)) { + $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); + $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); + + if(($b22 | ($w22 ^ 1))&1) { + $demerit += N2; + } + } + if(($x == 0) && (ord($frameY[$x]) & 1)) { + $this->runLength[0] = -1; + $head = 1; + $this->runLength[$head] = 1; + } else if($x > 0) { + if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { + $head++; + $this->runLength[$head] = 1; + } else { + $this->runLength[$head]++; + } + } + } + + $demerit += $this->calcN1N3($head+1); + } + + for($x=0; $x<$width; $x++) { + $head = 0; + $this->runLength[0] = 1; + + for($y=0; $y<$width; $y++) { + if($y == 0 && (ord($frame[$y][$x]) & 1)) { + $this->runLength[0] = -1; + $head = 1; + $this->runLength[$head] = 1; + } else if($y > 0) { + if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { + $head++; + $this->runLength[$head] = 1; + } else { + $this->runLength[$head]++; + } + } + } + + $demerit += $this->calcN1N3($head+1); + } + + return $demerit; + } + + + //---------------------------------------------------------------------- + public function mask($width, $frame, $level) + { + $minDemerit = PHP_INT_MAX; + $bestMaskNum = 0; + $bestMask = array(); + + $checked_masks = array(0,1,2,3,4,5,6,7); + + if (QR_FIND_FROM_RANDOM !== false) { + + $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9); + for ($i = 0; $i < $howManuOut; $i++) { + $remPos = rand (0, count($checked_masks)-1); + unset($checked_masks[$remPos]); + $checked_masks = array_values($checked_masks); + } + + } + + $bestMask = $frame; + + foreach($checked_masks as $i) { + $mask = array_fill(0, $width, str_repeat("\0", $width)); + + $demerit = 0; + $blacks = 0; + $blacks = $this->makeMaskNo($i, $width, $frame, $mask); + $blacks += $this->writeFormatInformation($width, $mask, $i, $level); + $blacks = (int)(100 * $blacks / ($width * $width)); + $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); + $demerit += $this->evaluateSymbol($width, $mask); + + if($demerit < $minDemerit) { + $minDemerit = $demerit; + $bestMask = $mask; + $bestMaskNum = $i; + } + } + + return $bestMask; + } + + //---------------------------------------------------------------------- + } + + + + +//---- qrencode.php ----------------------------- + + + + +/* + * PHP QR Code encoder + * + * Main encoder classes. + * + * Based on libqrencode C library distributed under LGPL 2.1 + * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> + * + * PHP QR Code is distributed under LGPL 3 + * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + class QRrsblock { + public $dataLength; + public $data = array(); + public $eccLength; + public $ecc = array(); + + public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs) + { + $rs->encode_rs_char($data, $ecc); + + $this->dataLength = $dl; + $this->data = $data; + $this->eccLength = $el; + $this->ecc = $ecc; + } + }; + + //########################################################################## + + class QRrawcode { + public $version; + public $datacode = array(); + public $ecccode = array(); + public $blocks; + public $rsblocks = array(); //of RSblock + public $count; + public $dataLength; + public $eccLength; + public $b1; + + //---------------------------------------------------------------------- + public function __construct(QRinput $input) + { + $spec = array(0,0,0,0,0); + + $this->datacode = $input->getByteStream(); + if(is_null($this->datacode)) { + throw new Exception('null imput string'); + } + + QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec); + + $this->version = $input->getVersion(); + $this->b1 = QRspec::rsBlockNum1($spec); + $this->dataLength = QRspec::rsDataLength($spec); + $this->eccLength = QRspec::rsEccLength($spec); + $this->ecccode = array_fill(0, $this->eccLength, 0); + $this->blocks = QRspec::rsBlockNum($spec); + + $ret = $this->init($spec); + if($ret < 0) { + throw new Exception('block alloc error'); + return null; + } + + $this->count = 0; + } + + //---------------------------------------------------------------------- + public function init(array $spec) + { + $dl = QRspec::rsDataCodes1($spec); + $el = QRspec::rsEccCodes1($spec); + $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); + + + $blockNo = 0; + $dataPos = 0; + $eccPos = 0; + for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) { + $ecc = array_slice($this->ecccode,$eccPos); + $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); + $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); + + $dataPos += $dl; + $eccPos += $el; + $blockNo++; + } + + if(QRspec::rsBlockNum2($spec) == 0) + return 0; + + $dl = QRspec::rsDataCodes2($spec); + $el = QRspec::rsEccCodes2($spec); + $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); + + if($rs == NULL) return -1; + + for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) { + $ecc = array_slice($this->ecccode,$eccPos); + $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); + $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); + + $dataPos += $dl; + $eccPos += $el; + $blockNo++; + } + + return 0; + } + + //---------------------------------------------------------------------- + public function getCode() + { + $ret; + + if($this->count < $this->dataLength) { + $row = $this->count % $this->blocks; + $col = $this->count / $this->blocks; + if($col >= $this->rsblocks[0]->dataLength) { + $row += $this->b1; + } + $ret = $this->rsblocks[$row]->data[$col]; + } else if($this->count < $this->dataLength + $this->eccLength) { + $row = ($this->count - $this->dataLength) % $this->blocks; + $col = ($this->count - $this->dataLength) / $this->blocks; + $ret = $this->rsblocks[$row]->ecc[$col]; + } else { + return 0; + } + $this->count++; + + return $ret; + } + } + + //########################################################################## + + class QRcode { + + public $version; + public $width; + public $data; + + //---------------------------------------------------------------------- + public function encodeMask(QRinput $input, $mask) + { + if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { + throw new Exception('wrong version'); + } + if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { + throw new Exception('wrong level'); + } + + $raw = new QRrawcode($input); + + QRtools::markTime('after_raw'); + + $version = $raw->version; + $width = QRspec::getWidth($version); + $frame = QRspec::newFrame($version); + + $filler = new FrameFiller($width, $frame); + if(is_null($filler)) { + return NULL; + } + + // inteleaved data and ecc codes + for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { + $code = $raw->getCode(); + $bit = 0x80; + for($j=0; $j<8; $j++) { + $addr = $filler->next(); + $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); + $bit = $bit >> 1; + } + } + + QRtools::markTime('after_filler'); + + unset($raw); + + // remainder bits + $j = QRspec::getRemainder($version); + for($i=0; $i<$j; $i++) { + $addr = $filler->next(); + $filler->setFrameAt($addr, 0x02); + } + + $frame = $filler->frame; + unset($filler); + + + // masking + $maskObj = new QRmask(); + if($mask < 0) { + + if (QR_FIND_BEST_MASK) { + $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); + } else { + $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); + } + } else { + $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); + } + + if($masked == NULL) { + return NULL; + } + + QRtools::markTime('after_mask'); + + $this->version = $version; + $this->width = $width; + $this->data = $masked; + + return $this; + } + + //---------------------------------------------------------------------- + public function encodeInput(QRinput $input) + { + return $this->encodeMask($input, -1); + } + + //---------------------------------------------------------------------- + public function encodeString8bit($string, $version, $level) + { + if(string == NULL) { + throw new Exception('empty string!'); + return NULL; + } + + $input = new QRinput($version, $level); + if($input == NULL) return NULL; + + $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); + if($ret < 0) { + unset($input); + return NULL; + } + return $this->encodeInput($input); + } + + //---------------------------------------------------------------------- + public function encodeString($string, $version, $level, $hint, $casesensitive) + { + + if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { + throw new Exception('bad hint'); + return NULL; + } + + $input = new QRinput($version, $level); + if($input == NULL) return NULL; + + $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); + if($ret < 0) { + return NULL; + } + + return $this->encodeInput($input); + } + + //---------------------------------------------------------------------- + public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) + { + $enc = QRencode::factory($level, $size, $margin); + $enc->encodePNG($text, $outfile, $saveandprint=false); + } + + //---------------------------------------------------------------------- + public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) + { + $enc = QRencode::factory($level, $size, $margin); + return $enc->encode($text, $outfile); + } + + //---------------------------------------------------------------------- + public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) + { + $enc = QRencode::factory($level, $size, $margin); + return $enc->encodeRAW($text, $outfile); + } + } + + //########################################################################## + + class FrameFiller { + + public $width; + public $frame; + public $x; + public $y; + public $dir; + public $bit; + + //---------------------------------------------------------------------- + public function __construct($width, &$frame) + { + $this->width = $width; + $this->frame = $frame; + $this->x = $width - 1; + $this->y = $width - 1; + $this->dir = -1; + $this->bit = -1; + } + + //---------------------------------------------------------------------- + public function setFrameAt($at, $val) + { + $this->frame[$at['y']][$at['x']] = chr($val); + } + + //---------------------------------------------------------------------- + public function getFrameAt($at) + { + return ord($this->frame[$at['y']][$at['x']]); + } + + //---------------------------------------------------------------------- + public function next() + { + do { + + if($this->bit == -1) { + $this->bit = 0; + return array('x'=>$this->x, 'y'=>$this->y); + } + + $x = $this->x; + $y = $this->y; + $w = $this->width; + + if($this->bit == 0) { + $x--; + $this->bit++; + } else { + $x++; + $y += $this->dir; + $this->bit--; + } + + if($this->dir < 0) { + if($y < 0) { + $y = 0; + $x -= 2; + $this->dir = 1; + if($x == 6) { + $x--; + $y = 9; + } + } + } else { + if($y == $w) { + $y = $w - 1; + $x -= 2; + $this->dir = -1; + if($x == 6) { + $x--; + $y -= 8; + } + } + } + if($x < 0 || $y < 0) return null; + + $this->x = $x; + $this->y = $y; + + } while(ord($this->frame[$y][$x]) & 0x80); + + return array('x'=>$x, 'y'=>$y); + } + + } ; + + //########################################################################## + + class QRencode { + + public $casesensitive = true; + public $eightbit = false; + + public $version = 0; + public $size = 3; + public $margin = 4; + + public $structured = 0; // not supported yet + + public $level = QR_ECLEVEL_L; + public $hint = QR_MODE_8; + + //---------------------------------------------------------------------- + public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4) + { + $enc = new QRencode(); + $enc->size = $size; + $enc->margin = $margin; + + switch ($level.'') { + case '0': + case '1': + case '2': + case '3': + $enc->level = $level; + break; + case 'l': + case 'L': + $enc->level = QR_ECLEVEL_L; + break; + case 'm': + case 'M': + $enc->level = QR_ECLEVEL_M; + break; + case 'q': + case 'Q': + $enc->level = QR_ECLEVEL_Q; + break; + case 'h': + case 'H': + $enc->level = QR_ECLEVEL_H; + break; + } + + return $enc; + } + + //---------------------------------------------------------------------- + public function encodeRAW($intext, $outfile = false) + { + $code = new QRcode(); + + if($this->eightbit) { + $code->encodeString8bit($intext, $this->version, $this->level); + } else { + $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); + } + + return $code->data; + } + + //---------------------------------------------------------------------- + public function encode($intext, $outfile = false) + { + $code = new QRcode(); + + if($this->eightbit) { + $code->encodeString8bit($intext, $this->version, $this->level); + } else { + $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); + } + + QRtools::markTime('after_encode'); + + if ($outfile!== false) { + file_put_contents($outfile, join("\n", QRtools::binarize($code->data))); + } else { + return QRtools::binarize($code->data); + } + } + + //---------------------------------------------------------------------- + public function encodePNG($intext, $outfile = false,$saveandprint=false) + { + try { + + ob_start(); + $tab = $this->encode($intext); + $err = ob_get_contents(); + ob_end_clean(); + + if ($err != '') + QRtools::log($outfile, $err); + + $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin)); + + QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint); + + } catch (Exception $e) { + + QRtools::log($outfile, $e->getMessage()); + + } + } + } + + diff --git a/vendor/wechat/vendor/autoload.php b/vendor/wechat/vendor/autoload.php new file mode 100755 index 0000000..7521aab --- /dev/null +++ b/vendor/wechat/vendor/autoload.php @@ -0,0 +1,7 @@ +<?php + +// autoload.php @generated by Composer + +require_once __DIR__ . '/composer/autoload_real.php'; + +return ComposerAutoloaderInit22bf7f20d9e49a6971dcc77918fb2a17::getLoader(); diff --git a/vendor/wechat/vendor/composer/ClassLoader.php b/vendor/wechat/vendor/composer/ClassLoader.php new file mode 100755 index 0000000..fce8549 --- /dev/null +++ b/vendor/wechat/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ +<?php + +/* + * This file is part of Composer. + * + * (c) Nils Adermann <naderman@naderman.de> + * Jordi Boggiano <j.boggiano@seld.be> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier <fabien@symfony.com> + * @author Jordi Boggiano <j.boggiano@seld.be> + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/wechat/vendor/composer/LICENSE b/vendor/wechat/vendor/composer/LICENSE new file mode 100755 index 0000000..f27399a --- /dev/null +++ b/vendor/wechat/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/vendor/wechat/vendor/composer/autoload_classmap.php b/vendor/wechat/vendor/composer/autoload_classmap.php new file mode 100755 index 0000000..7a91153 --- /dev/null +++ b/vendor/wechat/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ +<?php + +// autoload_classmap.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/vendor/wechat/vendor/composer/autoload_namespaces.php b/vendor/wechat/vendor/composer/autoload_namespaces.php new file mode 100755 index 0000000..b7fc012 --- /dev/null +++ b/vendor/wechat/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ +<?php + +// autoload_namespaces.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( +); diff --git a/vendor/wechat/vendor/composer/autoload_psr4.php b/vendor/wechat/vendor/composer/autoload_psr4.php new file mode 100755 index 0000000..be5cd7b --- /dev/null +++ b/vendor/wechat/vendor/composer/autoload_psr4.php @@ -0,0 +1,11 @@ +<?php + +// autoload_psr4.php @generated by Composer + +$vendorDir = dirname(dirname(__FILE__)); +$baseDir = dirname($vendorDir); + +return array( + 'WeChat\\Extend\\' => array($baseDir . '/src/WeChat/Extend'), + 'WeChat\\Core\\' => array($baseDir . '/src/WeChat/Core'), +); diff --git a/vendor/wechat/vendor/composer/autoload_real.php b/vendor/wechat/vendor/composer/autoload_real.php new file mode 100755 index 0000000..ca8bf57 --- /dev/null +++ b/vendor/wechat/vendor/composer/autoload_real.php @@ -0,0 +1,52 @@ +<?php + +// autoload_real.php @generated by Composer + +class ComposerAutoloaderInit22bf7f20d9e49a6971dcc77918fb2a17 +{ + private static $loader; + + public static function loadClassLoader($class) + { + if ('Composer\Autoload\ClassLoader' === $class) { + require __DIR__ . '/ClassLoader.php'; + } + } + + public static function getLoader() + { + if (null !== self::$loader) { + return self::$loader; + } + + spl_autoload_register(array('ComposerAutoloaderInit22bf7f20d9e49a6971dcc77918fb2a17', 'loadClassLoader'), true, true); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + spl_autoload_unregister(array('ComposerAutoloaderInit22bf7f20d9e49a6971dcc77918fb2a17', 'loadClassLoader')); + + $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit22bf7f20d9e49a6971dcc77918fb2a17::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/wechat/vendor/composer/autoload_static.php b/vendor/wechat/vendor/composer/autoload_static.php new file mode 100755 index 0000000..6e34199 --- /dev/null +++ b/vendor/wechat/vendor/composer/autoload_static.php @@ -0,0 +1,36 @@ +<?php + +// autoload_static.php @generated by Composer + +namespace Composer\Autoload; + +class ComposerStaticInit22bf7f20d9e49a6971dcc77918fb2a17 +{ + public static $prefixLengthsPsr4 = array ( + 'W' => + array ( + 'WeChat\\Extend\\' => 14, + 'WeChat\\Core\\' => 12, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'WeChat\\Extend\\' => + array ( + 0 => __DIR__ . '/../..' . '/src/WeChat/Extend', + ), + 'WeChat\\Core\\' => + array ( + 0 => __DIR__ . '/../..' . '/src/WeChat/Core', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit22bf7f20d9e49a6971dcc77918fb2a17::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit22bf7f20d9e49a6971dcc77918fb2a17::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/wechat/vendor/composer/installed.json b/vendor/wechat/vendor/composer/installed.json new file mode 100755 index 0000000..fe51488 --- /dev/null +++ b/vendor/wechat/vendor/composer/installed.json @@ -0,0 +1 @@ +[] diff --git a/wxtmp/Message.php b/wxtmp/Message.php new file mode 100755 index 0000000..f7c7ac7 --- /dev/null +++ b/wxtmp/Message.php @@ -0,0 +1,5 @@ +<?php + public class Message(){ + $appid = ''; + $appsecret = ''; + } \ No newline at end of file diff --git a/wxtmp/index.php b/wxtmp/index.php new file mode 100755 index 0000000..37ff41d --- /dev/null +++ b/wxtmp/index.php @@ -0,0 +1,75 @@ +<?php +$appid = 'wx2b29f5846b8d00fa'; +$appsecret = 'd8b93b7e2b175b904c435cb493b66ff8' ; +$tenpalate_id = 'ObkTv-txyqsv8Toie4HC8PnBFJmwygw9zPJbx8h0FcM'; +var_dump(send_notice($appid,$appsecret,$tenpalate_id )); +/** +* 发送模板消息 +*/ + function send_notice($appid,$appsecret,$tenpalate_id ){ + //获取access_token + if (isset($_COOKIE['access_token'])){ + $access_token = $_COOKIE['access_token']; + }else{ + $json_token=curl_post('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret); + $access_token=json_decode($json_token,true); + $access_token=$access_token['access_token']; + setcookie('access_token',$access_token,7200); + } + //模板消息 + $json_template = json_tempalte('objYQuHNqKTi2sjSTzLTc7C7PjDo',$tenpalate_id,'http://t.ect99.com'); + $url="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=".$access_token; + + $res=curl_post($url,urldecode($json_template)); + $res = json_decode($res); + var_dump($res); + if ($res['errcode']==0){ + return '发送成功'; + }else{ + return '发送失败'; + } + } + + /** + * 将模板消息json格式化 + */ + function json_tempalte($openid,$tenpalate_id ,$url){ + //模板消息 + $template=array( + 'touser'=>$openid, //用户openid + 'template_id'=>$tenpalate_id, //在公众号下配置的模板id + 'url'=>$url, //点击模板消息会跳转的链接 + 'topcolor'=>"#7B68EE", + 'data'=>array( + 'first'=>array('value'=>urlencode("您的活动已通过"),'color'=>"#FF0000"), + 'keyword1'=>array('value'=>urlencode('测试文章标题'),'color'=>'#FF0000'), //keyword需要与配置的模板消息对应 + 'keyword2'=>array('value'=>urlencode(date("Y-m-d H:i:s")),'color'=>'#FF0000'), + 'keyword3'=>array('value'=>urlencode('测试发布人'),'color'=>'#FF0000'), + 'keyword4'=>array('value'=>urlencode('测试状态'),'color'=>'#FF0000'), + 'remark' =>array('value'=>urlencode('备注:这是测试'),'color'=>'#FF0000'), ) + ); + $json_template=json_encode($template); + return $json_template; + } + + + /** + * @param $url + * @param array $data + * @return mixed + * curl请求 + */ + function curl_post($url , $data=array()){ + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + // POST数据 + curl_setopt($ch, CURLOPT_POST, 1); + // 把post的变量加上 + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + $output = curl_exec($ch); + curl_close($ch); + return $output; + } \ No newline at end of file diff --git a/wxtmp/pptWX.php b/wxtmp/pptWX.php new file mode 100755 index 0000000..92cbe9c --- /dev/null +++ b/wxtmp/pptWX.php @@ -0,0 +1,28 @@ +<?php + require 'pptWXBase.php'; + class pptWX extends pptWXBase + { + public function index(){ + $abc='11111'; + return $abc; + } + public function getList(){ + $abc=[1,2,3,4,5]; + return $abc; + } + + } + //获取数据,通过路由信息,如***.com/passport/wx.php/pptWX/getList,即调用pptWX类,getList方法 + function getData(){ + $uri = explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); + foreach ($uri as $k=>$v) { + if('pptWX' == $v){ + $class = $uri[$k]; + $object = new $class(); + $action = $uri[($k+1)]; + return $object->$action(); + } + } + + } + \ No newline at end of file diff --git a/wxtmp/pptWXBase.php b/wxtmp/pptWXBase.php new file mode 100755 index 0000000..6ab0d64 --- /dev/null +++ b/wxtmp/pptWXBase.php @@ -0,0 +1,214 @@ +<?php + require '../vendor/wechat/vendor/autoload.php'; + class pptWXBase + { + protected $openid; + public function __construct(){ + session_start(); + //$_SESSION['openid'] = null; + if(!isset($_SESSION['openid'])){ + $openid = $this->getHeaderValue('openid'); + if(empty($openid)){ + //去登录 + $code = isset($_GET['code']) ? $_GET['code'] : ''; + $this->wxLogin($code); + exit(); + }else{ + //已经有openid了,不用登录 + $_SESSION['openid'] = $openid; + } + } + $this->openid = $_SESSION['openid']; + } + /** + * 获取请求头 + * @param [string] $keyName [头名] + * @return [string] [头值] + */ + public function getHeaderValue($keyName){ + $headerValue = ''; + if (function_exists('apache_request_headers') && $result = apache_request_headers()) { + $headerValue = $result[$keyName]; + } else { + foreach ($_SERVER as $key => $val) { + if (0 === strpos($key, 'HTTP_')) { + $key = str_replace('_', '-', strtolower(substr($key, 5))); + if($key == $keyName){ + $headerValue = $val; + break; + } + } + } + } + return $headerValue; + } + /** + * 调用微信登录 + * @return [type] [description] + */ + public function wxLogin($code){ + //登录过程 + if(!$code){ + //调取授权 + $this->getAuth(); + }else{ + //获取openid,同时获取用户信息 + $authInfo = $this->getOpenid($code,true); + if(isset($authInfo['openid'])){ + $_SESSION['openid'] = $authInfo['openid']; + $this->openid = $_SESSION['openid']; + echo "<script>document.location.reload()</script>";exit(); + } + } + } + /** + *第一步:用户同意授权,获取code + *getAuth(); + *第二步:通过code换取网页授权access_token + *getOpenid($code,$type=false){ + *第三步:拉取用户信息(需scope为 snsapi_userinfo) + *微信用户信息 + *第一种,直接在第二步获取openid时获取 + *getOpenid($code,$type=true); + *第二种 通过用户授权accress_token获取 + *getUserInfo($userAuthAccessToken, $openid); + *第三种 通过公众号accressToken获取 + *getUserInfoByToken($accessToken, $openid) + * + * + */ + + /** + * 获取用户授权CODE,回调为当前地址,需要判断Code + * + */ + public function getAuth(){ + \WeChat\Core\User::code(); # 重载微信授权 + } + /** + * 通过code获取openid,access_token或用户信息 + * @param [string] $code [用户授权code] + * @param [string] $type [true:同时获取用户信息 | false:只获取用户openid] + * @return [string] [openid] + */ + public function getOpenid($code, $type=false){ + return \WeChat\Core\User::openid($code, $type); + } + /** + * 通过用户授权access_token获取用户信息 + * @param [string] $userAuthAaccessToken [用户授权access_token] + * @param [string] $openid [用户openid] + * @return [array] [] + */ + public function getUserInfo($userAuthAccessToken, $openid){ + return \WeChat\Core\User::userInfo($userAuthAccessToken, $openid); + } + /** + * 通过公众号accessToken获取用户信息 + * @param [string] $accessToken [公众号access_token] + * @param [string] $openid [用户openid] + * @return [array] [] + */ + public function getUserInfoByToken($openid){ + return \WeChat\Core\User::newUserInfo($openid); + } + /** + * 获取公众号下所有模板信息 + * @return [array] [模板列表] + */ + public function getAllTemplateMsg(){ + $accessToken = $this->getAccessToken(); + return \WeChat\Core\Template::gain($accessToken); + } + /** + * 获取用户accessToken + * @return [string] accessToken + */ + public function getAccessToken(){ + $accessToken = \WeChat\Core\Token::gain(); # 获取微信access_token + $accessToken = $accessToken['access_token']; + return $accessToken; + } + /** + * 发送模板消息 + * @param [string] $templateId [模板ID] + * @param [string] $openid [用户openid] + * @param [array] $data [消息数据] + * @param [string] $url [点击跳转地址] + * @param string $color [标题颜色] + * @return [array] 消息是否成功发送 + * errcode: 0成功,其他失败 + * errmsg: 错误信息,ok成功,其他失败 + * msgid: 消息id + * + */ + public function sendTemplateMsg($templateId, $openid, $data, $url, $color = '#7B68EE'){ + //\WeChat\Core\User::code($appID); # 重载微信授权 + $accessToken = $this->getAccessToken(); + return \WeChat\Core\Send::push($accessToken, $templateId, $openid, $data, $url, $color); + } + } + // $templateId = 'ObkTv-txyqsv8Toie4HC8PnBFJmwygw9zPJbx8h0FcM'; + // $openid = 'objYQuHNqKTi2sjSTzLTc7C7PjDo'; + // $url = 'http://t.ect99.com'; + // //模板消息 + // $data = [ + // 'first'=>['value'=>'您的活动已通过','color'=>"#FF0000"], + // 'keyword1'=>['value'=>'测试文章标题'], //keyword需要与配置的模板消息对应 + // 'keyword2'=>['value'=>date("Y-m-d H:i:s")], + // 'keyword3'=>['value'=>'测试发布人'], + // 'keyword4'=>['value'=>'测试状态'], + // 'remark' =>['value'=>'备注:这是测试'] + // ]; + // var_dump(pptWX->sendTemplateMsg($templateId, $openid, $data, $url)); + // //登录过程 + // $code = isset($_GET['code']) ? $_GET['code'] : ''; + // if(!$code){ + // //调取授权 + // pptWXBase::getAuth(); + // }else{ + // //获取授权信息,只获取openid + // //$authInfo = pptWXBase::getOpenid($code); + // // 返回代码示例 + // // array(5) { + // // ["access_token"]=> + // // string(89) "22_HQ4kM7_gbUZ-fGP1TnFLeh-wxk-jWyjc_PzrbYpICXyuGCNKWEi_Yz5_qnStDGP56I8OD4xJvNRVS98U1TC6Zw" + // // ["expires_in"]=> + // // int(7200) + // // ["refresh_token"]=> + // // string(89) "22_bdxpWwS0wADfSNO1y6Sq7txoWBK3hG4x3vvx_WOe-sovDig-yWZ43MsBtzJlY2svcxmlvLxKwBughKbJL14b8A" + // // ["openid"]=> + // // string(28) "objYQuHNqKTi2sjSTzLTc7C7PjDo" + // // ["scope"]=> + // // string(15) "snsapi_userinfo" + // // } + // //获取用户信息 + // //通过授权token,获取用户信息 + // //$userInfo = pptWXBase::getUserInfo($authInfo['access_token'], $authInfo['openid']); + // //获取openid,同时获取用户信息 + // $authInfo = pptWXBase::getOpenid($code,true); + // // 返回代码示例 + // // array(9) { + // // ["openid"]=> + // // string(28) "objYQuHNqKTi2sjSTzLTc7C7PjDo" + // // ["nickname"]=> + // // string(12) "网事悠悠" + // // ["sex"]=> + // // int(1) + // // ["language"]=> + // // string(5) "zh_CN" + // // ["city"]=> + // // string(6) "枣庄" + // // ["province"]=> + // // string(6) "山东" + // // ["country"]=> + // // string(6) "中国" + // // ["headimgurl"]=> + // // string(130) "http://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJW7ghRsPm6dJReYJ97lUMicgjQLVdSaPr3SKBZ29riaZ3KOFaw1nmKyt4LtibvN2FkzFTTESgetm9QQ/132" + // // ["privilege"]=> + // // array(0) { + // // } + // // } + + // var_dump($authInfo); + // } diff --git a/wxtmp/url.php b/wxtmp/url.php new file mode 100755 index 0000000..8634761 --- /dev/null +++ b/wxtmp/url.php @@ -0,0 +1,6 @@ +<?php + $current_url = 'http://t.ect99.com/wxtmp/wx.php'; + $appid = 'wx2b29f5846b8d00fa'; + + +header('Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.urlencode($current_url).'&response_type=code&scope=snsapi_base&state=123#wechat_redirect'); \ No newline at end of file diff --git a/wxtmp/wx.php b/wxtmp/wx.php new file mode 100755 index 0000000..9cfb119 --- /dev/null +++ b/wxtmp/wx.php @@ -0,0 +1,15 @@ +<?php + require 'pptWX.php'; + $data = getData(); +?> + <html> + <head> + + </head> + <body> + <?php foreach($data as $item): ?> + <?=$item?> + <?php endforeach ?> + aaaaaaaaaaaaaaaaaaaaa + </body> + </html>